diff --git a/.gitattributes b/.gitattributes index 57ef0daea0e3..f9868677fa2e 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,6 +13,7 @@ README.* conflict-marker-size=32 *.data -whitespace contrib/pgcrypto/sql/pgp-armor.sql whitespace=-blank-at-eol src/backend/catalog/sql_features.txt whitespace=space-before-tab,blank-at-eof,-blank-at-eol +src/backend/utils/Gen_dummy_probes.pl.prolog whitespace=-blank-at-eof # Test output files that contain extra whitespace *.out -whitespace diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000000..adc97026b6e0 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,107 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project overview + +This is **ArenaDatabaseDB (ADB)** — an MPP (Massively Parallel Processing) database fork of Greenplum Database (GPDB), itself built on PostgreSQL. The repo tracks upstream PostgreSQL and periodically merges new major PostgreSQL versions into GPDB-specific branches. + +**Key branches:** +- `adb-6.x` — production ADB 6.x line (main branch for PRs) +- `ai-merge-stage1` — staging branch for the current PG 8.0.0-alpha.0 → GPDB merge +- `gg_upgrade` — tracks upstream PostgreSQL code + +## Build + +Requires: GNU make, autoconf 2.69, Bison, Flex, Perl, and standard C toolchain. + +```bash +# Configure (first time or after configure.in changes) +./configure --prefix=/usr/local/pgsql + +# Build everything +make world + +# Install +make install + +# Clean +make distclean +``` + +`make world` builds `src/` and `contrib/`. Plain `make` builds `src/` only. + +## Running tests + +```bash +# Run regression tests against a temporary installation (no running server needed) +make check + +# Run against an already-running server +make installcheck + +# Run all test suites (regress, isolation, pl, contrib, bin) +make check-world +make installcheck-world + +# Run parallel regression tests +make installcheck-parallel + +# Run a specific test file by name against a running server +cd src/test/regress && ./pg_regress --inputdir=. --schedule=serial_schedule + +# Run isolation (concurrent transaction) tests +cd src/test/isolation && make installcheck +# Or a specific spec: ./pg_isolation_regress +``` + +Set `MAX_CONNECTIONS=N` to cap parallelism: `make check MAX_CONNECTIONS=4`. + +## Code style + +- **C/Perl**: tabs, 4-space indent. Run `pgindent` (see `src/tools/pgindent/README.gpdb`) before submitting. +- **Python**: spaces, 4-space indent. Must pass `pylint`. +- **Go**: formatted with `gofmt`. +- Formatting config is in `.editorconfig`. +- Follow [PostgreSQL Coding Conventions](https://www.postgresql.org/docs/current/source.html). + +## Architecture + +``` +src/backend/ Main server process + access/ Table and index access methods (heap, nbtree, gin, gist, brin, hash, spgist) + catalog/ System catalog management + commands/ SQL command execution (DDL) + executor/ Query execution engine + nodes/ Node type definitions, copy/equal/out functions + optimizer/ Query planner (geqo, path, plan, prep, util) + parser/ SQL parser + replication/ WAL streaming, logical replication + storage/ Buffer manager, file I/O, lock manager, page layout + utils/ Memory management, error handling, type system, caching + +src/include/ Header files (mirrors backend/ structure) +src/bin/ Client utilities: psql, pg_dump, pg_ctl, pg_basebackup, pg_upgrade, etc. +src/pl/ Procedural languages: plpgsql, plperl, plpython, tcl +src/test/ Test suites: regress, isolation, authentication, subscription, ssl +contrib/ Optional extensions (pg_stat_statements, pageinspect, postgres_fdw, etc.) +``` + +GPDB/ADB-specific distributed execution concepts used throughout the codebase: +- **Motion nodes** — data movement operators between MPP segments +- **Slices** — independent units of parallel execution +- **ORCA** — the Greenplum cost-based optimizer (referenced in optimizer/ and JIT-related code) +- **arenadata_toolkit** — ADB-specific monitoring extension (tested in isolation2 tests) + +## PostgreSQL major-version merge workflow + +The primary ongoing task on `ai-merge-stage1` is merging upstream PostgreSQL into GPDB. The full decision matrix and workflow are documented in [`GG_PG_MERGE_SKILL.md`](./GG_PG_MERGE_SKILL.md). Key points: + +1. `git merge --no-commit --no-ff ` +2. Record conflicts: `git diff --name-only --diff-filter=U` +3. Resolve semantically — never blindly take `ours` or `theirs` +4. Adopt upstream API shapes first; re-graft GPDB-specific logic into the new shape +5. Verify: `rg "^(<<<<<<<|=======|>>>>>>>)"` must return nothing +6. Build and run targeted regression tests before finalizing + +Reference commits for resolution style: `1e11aaff762`, `f2b03841`, `1fa092913d2`, `3e9744465db`, `ed7a5095716ee`, `4dbcb3f844ec`, `a91e2fa94180`, `55a1954da16`, `80831bcdbe`, `eb57bd9c1`. diff --git a/COPYRIGHT b/COPYRIGHT index a73a89266ba5..fdc0260f583b 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -14,7 +14,7 @@ the PostgreSQL License is provided below: PostgreSQL Database Management System (formerly known as Postgres, then as Postgres95) -Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of California diff --git a/GG_PG_13_14_MERGE_CONFLICTS.md b/GG_PG_13_14_MERGE_CONFLICTS.md new file mode 100644 index 000000000000..9cf92d742dbb --- /dev/null +++ b/GG_PG_13_14_MERGE_CONFLICTS.md @@ -0,0 +1,325 @@ +# GreengageDB — PG13→14 Merge: Conflicts Requiring Deep Analysis + +Conflict sites in the PG13→14 merge (`d259afa736..e1c1c30f635`, 2022 commits, +701 conflict files on `claude-merge-2` based on `adb-8.x` tip `0f7c5267a2c`) +that cannot be resolved mechanically and require analysis of PG or Greengage +git history. + +For resolution rules, see `GG_PG_13_14_MERGE_RULES.md`. + +--- + +## CONFLICT-01: `procarray.c` — PGXACT elimination + GPDB distributed snapshot + +**File**: `src/backend/storage/ipc/procarray.c` +**Conflict count**: 4 markers + +### What happened + +PG14 eliminated `PGXACT` (commits `dc7420c`–`623a9ba`). XID state previously +accessed via `allPgXact[i]` is now in dense arrays in `PROC_HDR`: + +```c +/* PG13 */ +allPgXact[i].xid +allPgXact[i].overflowed + +/* PG14 */ +ProcGlobal->xids[proc->pgxactoff] +ProcGlobal->subxidStates[proc->pgxactoff].overflowed +``` + +GPDB's `GetDistributedSnapshotMaxInProgressXids()` and `GetLocalOldestXmin()` +access XID state via the old `PGXACT` form. + +### Analysis required + +```bash +# Find how adb-8.x resolved these functions +git show origin/adb-8.x:src/backend/storage/ipc/procarray.c \ + | grep -A30 "GetDistributedSnapshotMaxInProgressXids" + +git show origin/adb-8.x:src/backend/storage/ipc/procarray.c \ + | grep -A20 "GetLocalOldestXmin" +``` + +Expected: replace `allPgXact[i].xid` with `ProcGlobal->xids[proc->pgxactoff]` +inside all GPDB-specific loops over `arrayP->pgprocnos[]`. + +### Reference + +PG commits: `dc7420c`, `1f51c17`, `941697c`, `5788e25`, `73487a6`, `623a9ba`. + +--- + +## CONFLICT-02: `xact.c` — GPDB reader-writer XID sharing + streaming abort + +**File**: `src/backend/access/transam/xact.c` + +### What happened + +Two changes landed in the same region of `AbortTransaction()`: + +- **PG14**: Added `ResetLogicalStreamingState()` in `AbortTransaction()` and + `AbortSubTransaction()`; new global `CheckXidAlive`/`bsysscan`. +- **GPDB**: `SharedLocalSnapshotSlot->writer_xact` (pointing into removed + `allPgXact[]`) must be replaced. `IsCurrentTransactionIdForReader()` + accesses writer XID state through the slot. + +### Analysis required + +```bash +# Check what replaced writer_xact in the slot struct +git show origin/adb-8.x:src/include/storage/lock.h \ + | grep -A5 "writer_xact\|writer_proc" + +# Check resolved IsCurrentTransactionIdForReader +git show origin/adb-8.x:src/backend/access/transam/xact.c \ + | grep -A20 "IsCurrentTransactionIdForReader" +``` + +Expected field mapping: +```c +writer_xact->xid → writer_proc->xid +writer_xact->overflowed → writer_proc->subxidStatus.overflowed +writer_xact->nxids → writer_proc->subxidStatus.count +``` + +--- + +## CONFLICT-03: `gram.y` — `relkind`→`objtype` rename + GPDB grammar + +**File**: `src/backend/parser/gram.y` +**Conflict count**: 21 markers + +### What happened + +PG14 renamed `.relkind` to `.objtype` in `CreateTableAsStmt` and related +parse nodes. GPDB has substantial grammar additions (SCATTER BY, external +tables, resource queues, ENCODING, etc.) that conflict with the same regions. + +21 markers in a grammar file is high risk — a single malformed rule causes +parse errors on all SQL. + +### Analysis required + +```bash +# List all conflict positions +git diff HEAD -- src/backend/parser/gram.y | grep -n "<<<<<<" | head -25 + +# After resolution, verify grammar parses +make -C src/backend/parser gram.tab.c 2>&1 | grep "error\|conflict" + +# Check GPDB grammar additions in adb-8.x +git show origin/adb-8.x:src/backend/parser/gram.y \ + | grep -n "SCATTER\|ENCODING\|DISTRIBUTED\|EXTERNAL" | head -20 +``` + +For each conflict: if it is a `.relkind`/`.objtype` rename, update GPDB code +in the same rule to use `.objtype`. If it is a GPDB-only grammar rule that PG +also touched, merge both sets of changes. + +--- + +## CONFLICT-04: `guc.c` / `guc_gp.c` — `wal_keep_size` + `hashagg` removal + +**Files**: `src/backend/utils/misc/guc.c`, `src/include/utils/guc.h`, +`src/include/utils/guc_tables.h` + +### What happened + +- `wal_keep_segments` (integer, segment count) → `wal_keep_size` (integer, MB): + semantic change, not just rename. Existing configuration values differ. +- `hashagg_avoid_disk_plan` (GPDB-added, `GPDB_13_MERGE_FIXME`) must be deleted. +- PG14 reorganized `guc.c` struct types (`GucContext`, `GucFlags`). + +### Analysis required + +```bash +# Verify hashagg_avoid_disk_plan is gone in adb-8.x +git show origin/adb-8.x:src/backend/utils/misc/guc_gp.c \ + | grep "hashagg_avoid_disk" +# Expected: no output + +# Check wal_keep_size variable name and unit +git show origin/adb-8.x:src/backend/utils/misc/guc.c \ + | grep -A15 "wal_keep" + +# Verify GucFlags type usage in GPDB GUC table entries +git show origin/adb-8.x:src/include/utils/guc_tables.h | head -50 +``` + +--- + +## CONFLICT-05: `toasting.c` — OID preassignment removal + `attcompression` + +**File**: `src/backend/catalog/toasting.c` + +### What happened + +PG14 (commit `f3faf35`) stopped creating `pg_type` entries for toast tables, +removing the need for `toast_typid`. PG14 also requires that toast attribute +descriptors set `attcompression = InvalidCompressionMethod`. + +### Analysis required + +```bash +# Check how adb-8.x resolved this +git show origin/adb-8.x:src/backend/catalog/toasting.c \ + | grep -n "GetPreassigned\|toast_typid\|attcompression" + +# Check pg_type.c for related changes +git show origin/adb-8.x:src/backend/catalog/pg_type.c \ + | grep -n "GetPreassigned\|sequence\|toast" | head -15 +``` + +Expected: remove the `if (IsBinaryUpgrade) toast_typid = GetPreassigned...` +block; pass `InvalidOid` to `heap_create()`; add `attcompression = +InvalidCompressionMethod` for all three toast attrs. + +--- + +## CONFLICT-06: `heapam.c` — HOT updates + AO table dispatch + +**File**: `src/backend/access/heap/heapam.c` + +### What happened + +PG14 made significant changes to HOT update logic and added `attcompression` +handling. GPDB has `CdbDispatch*` hooks and AO-table bypass paths in the same +file. + +### Analysis required + +```bash +# Find all GPDB-specific additions in heapam.c on adb-8.x +git show origin/adb-8.x:src/backend/access/heap/heapam.c \ + | grep -n "CdbDispatch\|AO_\|AppendOnly\|gp_" | head -20 + +# For each conflict region, determine: dispatch hook, AO bypass, or comment +git diff HEAD -- src/backend/access/heap/heapam.c \ + | grep -n "<<<<<<" | head -20 +``` + +--- + +## CONFLICT-07: `copy.c` — binary COPY optimization + external table dispatch + +**File**: `src/backend/commands/copy.c` + +### What happened + +PG14 (commit `cd22d3c`) avoided redundant buffer allocations in binary COPY +FROM. PG14 also later splits `copy.c` into `copyfrom.c` / `copyto.c`, but +verify whether that split falls within `e1c1c30f635`: + +```bash +git log --oneline e1c1c30f635 -- src/backend/commands/copyfrom.c 2>/dev/null \ + | head -3 +# If no output, the split has not happened at our target +``` + +GPDB has extensive external-table dispatch in `copy.c`. + +### Analysis required + +```bash +git show origin/adb-8.x:src/backend/commands/copy.c \ + | grep -n "CdbDispatch\|external\|ExtTable\|url_" | head -20 +``` + +Position the binary-COPY optimization (avoiding allocations) correctly relative +to GPDB's external-table dispatch path. + +--- + +## CONFLICT-08: `vacuumlazy.c` — GlobalVis horizon + GPDB AO vacuum + +**File**: `src/backend/access/heap/vacuumlazy.c` + +### What happened + +PG14's snapshot-scalability series replaced `GetOldestXmin()` with the +`GlobalVis*` horizon API in vacuum: + +```c +/* PG13 */ +OldestXmin = GetOldestXmin(rel, PROCARRAY_FLAGS_VACUUM); +/* PG14 */ +vacrel->vistest = GlobalVisTestFor(rel); +/* then: */ +GlobalVisTestIsRemovable(vistest, xid) +``` + +GPDB has AO-table vacuum dispatch in the same file. + +### Analysis required + +```bash +git show origin/adb-8.x:src/backend/access/heap/vacuumlazy.c \ + | grep -n "AO\|AppendOnly\|OldestXmin\|GlobalVis" | head -20 +``` + +Verify `GetLocalOldestXmin()` in `procarray.c` is updated or removed — if it +returns `RecentGlobalXmin` (deleted in PG14), it must be rewritten. + +--- + +## CONFLICT-09: `pg_aggregate.c` / `aggregatecmds.c` — new aggregate options + +**Files**: `src/backend/catalog/pg_aggregate.c`, +`src/backend/commands/aggregatecmds.c` + +### What happened + +PG14 added `MFINALFUNC_EXTRA` and other aggregate definition options, changing +the `AggregateCreate()` signature. GPDB has custom ordered-aggregate handling +and distributed aggregate dispatch. + +### Analysis required + +```bash +git diff d259afa736..e1c1c30f635 -- src/backend/catalog/pg_aggregate.c \ + | grep "^[+-].*AggregateCreate\|mfinalfunc_extra" | head -10 + +# Find all GPDB callers of AggregateCreate +grep -rn "AggregateCreate(" src/ --include="*.c" | head -10 +``` + +--- + +## CONFLICT-10: `src/tools/pgindent/typedefs.list` — additive merge + +**File**: `src/tools/pgindent/typedefs.list` + +### What happened + +Both PG14 and GPDB added new typedef names in the same alphabetically-sorted +regions. This is a pure additive conflict. + +### Resolution + +Keep **all** entries from both sides, maintaining alphabetical order. Do not +remove GPDB-specific typedef names (e.g., `MotionNode`, `CdbVisitOpt`, etc.). + +--- + +## Template for new entries + +When a conflict requires reading commit history to resolve, add an entry: + +```markdown +## CONFLICT-NN: `file` — brief description + +**File**: `path/to/file` +**Conflict count**: N markers + +### What happened +[PG14 change + GPDB content in same area] + +### Analysis required +[Specific git commands to run] + +### Reference +[PG commit hashes or GPDB PR numbers] +``` diff --git a/GG_PG_13_14_MERGE_RULES.md b/GG_PG_13_14_MERGE_RULES.md new file mode 100644 index 000000000000..31c42090247b --- /dev/null +++ b/GG_PG_13_14_MERGE_RULES.md @@ -0,0 +1,880 @@ +# GreengageDB — PostgreSQL 13→14 Major-Version Merge Rules + +This document supplements `GG_PG_MERGE_RULES.md` (PG12→13 rules) with patterns +specific to the PG13→14 merge. Ground truth sources: + +1. **PR #2545** ("Sync 14x b12 merge") — the production batch-12 merge into + `arenadata/gpdb/adb-8.x`, approved by four reviewers, merged 2026-05-20. +2. **PR #2439 / #2490** — exploratory and staging variants of the same batch. +3. **`claude-merge-2` exercise** — merge of PG commits + `d259afa736..e1c1c30f635` (2022 commits, 701 conflict files) onto + `adb-8.x` tip `0f7c5267a2c`. + +--- + +## 1. Key structural changes in PG14 and their resolution strategy + +### 1.1 `configure.in` → `configure.ac` rename (commit `25244b8`) + +PG14 renamed `configure.in` to `configure.ac` to conform with Autoconf +conventions. GreengageDB already tracks `configure.ac` on `adb-8.x`; this +conflict is a pure **take ours** for the file name. The content conflict inside +`configure.ac` follows the same rules as §3.1 of `GG_PG_MERGE_RULES.md`: + +``` +Resolution: + Keep GPDB's AC_INIT name + contact, update PG_PACKAGE_VERSION to PG14 + version string from upstream AC_INIT (e.g. "14beta2"). + Keep all GPDB --with-* options. + Take upstream copyright year update (2020 → 2021). +``` + +### 1.2 PGXACT elimination — snapshot scalability (commits `dc7420c`–`623a9ba`) + +This is the dominant structural change in PG14. The `PGXACT` struct and the +`allPgXact[]` array in `PROC_HDR` were abolished. Transaction XID state is now +stored in dense per-field arrays directly in `PROC_HDR`: + +| Old (`PGXACT` field) | New (`PROC_HDR` / `PGPROC` field) | +|---|---| +| `allPgXact[i].xid` | `ProcGlobal->xids[proc->pgxactoff]` | +| `allPgXact[i].nxids` | `ProcGlobal->subxidStates[proc->pgxactoff].count` | +| `allPgXact[i].overflowed` | `ProcGlobal->subxidStates[proc->pgxactoff].overflowed` | +| `allPgXact[i].vacuumFlags` | `ProcGlobal->statusFlags[proc->pgxactoff]` | +| `MyPgXact` pointer | `proc->pgxactoff` index into the dense arrays | + +**Resolution strategy** (adopted in PR #2545): + +1. **Take upstream shape entirely.** Remove `PGXACT` struct references, remove + `allPgXact` array, replace with `pgxactoff` index-based access. +2. **Re-graft GPDB-specific `IsCurrentTransactionIdForReader()`** in `xact.c` + onto the new `PGPROC` fields: + ```c + /* OLD (PG13 / GPDB) */ + writer_xact->xid + writer_xact->overflowed + writer_xact->nxids + /* NEW (PG14) */ + writer_proc->xid + writer_proc->subxidStatus.overflowed + writer_proc->subxidStatus.count + ``` +3. Remove `SharedLocalSnapshotSlot->writer_xact` pointer — it pointed into + `allPgXact[]` which no longer exists. The slot now holds the writer + `PGPROC *` directly. +4. In `procarray.c`, update all GPDB-specific distributed-snapshot logic + (`GetDistributedSnapshotMaxInProgressXids()`, `GetLocalOldestXmin()`) + to use `ProcGlobal->xids[pgxactoff]` instead of `MyPgXact->xid`. + +**Files most affected**: `src/backend/storage/ipc/procarray.c`, +`src/backend/access/transam/xact.c`, `src/include/storage/proc.h`, +`src/backend/postmaster/autovacuum.c`. + +### 1.3 `RecentGlobalXmin` / `GetFullRecentGlobalXmin()` removal + +PG14 removed `RecentGlobalXmin` and `RecentGlobalDataXmin` globals from +`snapmgr.c`, replacing them with the `GlobalVis*` horizon mechanism. + +The GPDB-specific `GetFullRecentGlobalXmin()` function (which wrapped +`RecentGlobalXmin`) must also be **deleted**. Update its callers to use +`GetOldestNonRemovableTransactionId()` or the `GlobalVis*` API. + +### 1.4 `relkind` → `objtype` field rename in parse nodes (commit `cc35d89`) + +Upstream renamed the `relkind` field to `objtype` in: +- `CreateTableAsStmt` +- `RefreshMatViewStmt` +- `IntoClause` +- Various `AlterTableCmd` subtypes + +**Resolution**: Mechanical rename — take upstream form. The field type changes +from `char` to an enum (`ObjectType`), so comparisons like +`stmt->relkind == RELKIND_RELATION` become `stmt->objtype == OBJECT_TABLE`. + +Grep to find all sites in GPDB code: +```bash +grep -rn "->relkind\b\|\.relkind\b" src/backend/ src/include/ \ + --include="*.c" --include="*.h" \ + | grep -v "rd_rel->relkind\|Form_pg_class\|RELKIND_" +``` + +### 1.5 `InsertPgAttributeTuple` → `InsertPgAttributeTuples` (bulk insert) + +PG14 refactored `heap.c` to bulk-insert `pg_attribute` rows using +`TupleTableSlot[]` instead of one row at a time. + +- Function renamed: `InsertPgAttributeTuple` → `InsertPgAttributeTuples` (plural). +- New `pg_attribute` column: `attcompression` (column-level compression method). +- Constant renamed: `MAX_PGATTRIBUTE_INSERT_BYTES` → `MAX_CATALOG_MULTI_INSERT_BYTES`. + +**Resolution**: Take upstream bulk-insert implementation. Add the +`attcompression` slot value in GPDB-specific catalog-insert paths. GPDB's +`MetaTrackAddUpdInternal` call in the same file is preserved in place. + +### 1.6 No `pg_type` entries for sequences and toast tables (commit `f3faf35`) + +Upstream stopped pre-allocating a `toast_typid` via `GetPreassignedOidForType()` +in `toasting.c`. The GPDB OID-preassignment block for `toast_typid` must be +**removed** — `toast_typid` is now passed as `InvalidOid` to `heap_create()`. + +```c +/* REMOVE this GPDB block: */ +if (IsBinaryUpgrade) + toast_typid = GetPreassignedOidForType(...); +/* Change the call to: */ +heap_create(..., InvalidOid, ...); +``` + +PG14 also adds `attcompression = InvalidCompressionMethod` for all three toast +attribute descriptors (chunk_id, chunk_seq, chunk_data) — keep these additions. + +### 1.7 MinimalTuple for tuple queues (`tqueue.c`, commit `cdc7169`) + +`TupleQueueReaderNext()` return type changed from `HeapTuple` to `MinimalTuple`. +**Resolution**: Take upstream shape entirely — no GPDB-specific logic in `tqueue.c`. + +### 1.8 Long-lived `WaitEventSet` for `WaitLatch()` (commit `3347c98`) + +`WaitLatch()` no longer delegates to `WaitLatchOrSocket()`. A module-static +`LatchWaitSet` is used, initialized by new `InitializeLatchWaitSet()`. + +**Resolution**: Take upstream. Thread `InitializeLatchWaitSet()` into GPDB's +process startup paths (postmaster, bgworker initialization). + +### 1.9 GUC renames and removals + +| Old GUC | New GUC | Change type | +|---|---|---| +| `wal_keep_segments` (count) | `wal_keep_size` (MB) | **Semantic change** — values are numerically different | +| `hashagg_avoid_disk_plan` | *(removed)* | Explicitly delete; GPDB-added GUC with a `GPDB_13_MERGE_FIXME` tag | +| `enable_incrementalsort` | `enable_incremental_sort` | Rename (upstream naming convention) | +| `REPLICATION_MASTER` group | `REPLICATION_PRIMARY` | Rename | + +For `hashagg_avoid_disk_plan`: **delete the GUC entry** from `guc_gp.c` +and its backing variable. Any GPDB code that tested this flag should have +its condition removed or hardcoded. + +### 1.10 `StrNCpy` → `strlcpy` global rename (commit `1784f27`) + +PG14 replaced all `StrNCpy()` calls with `strlcpy()` across the tree. +`StrNCpy` is still present in `c.h` but deprecated. Take upstream `strlcpy` +form everywhere. Not a compile error but clean up GPDB-specific files too. + +### 1.11 Logical decoding — in-memory streaming for large transactions + +`reorderbuffer.c` gained in-memory streaming support. `worker.c` gained binary +replication column support. `xact.c` gained `ResetLogicalStreamingState()` in +both `AbortTransaction` and `AbortSubTransaction`. + +**Resolution**: All upstream shape. Update `src/test/isolation2` expected +outputs where replication output format changes. + +### 1.12 `pg_type` catalog — new `typsubscript` column + +PG14 added `typsubscript` to `pg_type` for custom subscript handlers. +After resolving `pg_type.dat`, run the duplicate-OID scan (§3.6 of +`GG_PG_MERGE_RULES.md`) to ensure no collisions. + +--- + +## 2. Conflict classification matrix (PG13→14 specific) + +### 2.1 Build / config identity + +Same rules as §3.1 of `GG_PG_MERGE_RULES.md`. `configure.ac` replaces +`configure.in` — conflicts on this file follow the same strategy. + +### 2.2 Additive conflicts in `xact.c` + +PG14 adds `ResetLogicalStreamingState()` in `AbortTransaction`. GPDB updates +`IsCurrentTransactionIdForReader()` with new writer-proc field names. Keep +**both**. + +### 2.3 GPDB FIXME tag cleanup + +Search for `GPDB_13_MERGE_FIXME` after resolution: +```bash +grep -rn "GPDB_13_MERGE_FIXME" src/ --include="*.c" --include="*.h" +``` +Each hit must be evaluated: if PG14 subsumes the workaround, remove the GPDB +code and the tag. Otherwise, re-tag as `GPDB_14_MERGE_FIXME`. + +### 2.4 Test and translation files + +- `src/test/regress/expected/*.out` — always take GPDB version. +- `src/test/isolation2/expected/*.out` — always take GPDB version. +- `*.po` translation files — always take GPDB version (GPDB does not maintain + localization; take ours to avoid regressing GPDB-added strings). + +--- + +## 3. Verification checklist (PG13→14 additions) + +Run the full checklist from §5 of `GG_PG_MERGE_RULES.md`, plus: + +```bash +# 1. No PGXACT references (struct removed in PG14) +grep -rn "PGXACT\|allPgXact\|MyPgXact" src/ --include="*.c" --include="*.h" \ + | grep -v "^Binary\|/\*" +# Every non-comment hit is a missed migration + +# 2. No old relkind field accesses in parse nodes +grep -rn "->relkind\b\|\.relkind\b" src/backend/ src/include/ \ + --include="*.c" --include="*.h" \ + | grep -v "rd_rel->relkind\|Form_pg_class\|RELKIND_" + +# 3. wal_keep_segments must be gone +grep -rn "wal_keep_segments" src/ --include="*.c" --include="*.h" +# Expected: zero hits + +# 4. hashagg_avoid_disk_plan must be gone +grep -rn "hashagg_avoid_disk_plan" src/ +# Expected: zero hits + +# 5. InsertPgAttributeTuple (singular) must be gone +grep -rn "InsertPgAttributeTuple[^s]" src/ --include="*.c" --include="*.h" +# Expected: zero hits + +# 6. Evaluate all GPDB_13_MERGE_FIXME tags +grep -rn "GPDB_13_MERGE_FIXME" src/ --include="*.c" --include="*.h" + +# 7. Standard checks (from GG_PG_MERGE_RULES.md §5) +git diff --name-only --diff-filter=U # must be empty +rg "^<<<<<<<" src/ doc/ # must be empty +``` + +--- + +## 4. File-by-file quick reference (PG13→14 specific) + +| File | Resolution strategy | +|---|---| +| `configure.ac` | GPDB AC_INIT + update PG_PACKAGE_VERSION to PG14 version | +| `src/include/catalog/catversion.h` | Take higher value | +| `src/backend/storage/ipc/procarray.c` | Take upstream PGXACT-elimination; re-graft GPDB distributed-snapshot logic onto `ProcGlobal->xids[pgxactoff]` | +| `src/backend/access/transam/xact.c` | Keep both: upstream `ResetLogicalStreamingState()` + GPDB `IsCurrentTransactionIdForReader()` migration to writer_proc | +| `src/include/storage/proc.h` | Take upstream (adds `pgxactoff`, `statusFlags`; removes `PGXACT`) | +| `src/backend/catalog/heap.c` | Take upstream bulk-insert + `attcompression`; keep `MetaTrackAddUpdInternal` | +| `src/backend/catalog/toasting.c` | Remove GPDB's `GetPreassignedOidForType` for toast type; pass `InvalidOid`; add `attcompression = InvalidCompressionMethod` for toast attrs | +| `src/backend/catalog/pg_type.c` | Take upstream (adds `typsubscript`); update GPDB OID-dispatch paths | +| `src/backend/utils/misc/guc.c` | Delete `wal_keep_segments`, add `wal_keep_size`; delete `hashagg_avoid_disk_plan` | +| `src/backend/utils/misc/guc_gp.c` | Remove `hashagg_avoid_disk_plan`; update `enable_incremental_sort` name | +| `src/backend/parser/gram.y` | Take upstream (`.relkind` → `.objtype`); keep GPDB dispatch grammar | +| `src/backend/commands/copy.c` | Take upstream binary COPY optimization; preserve GPDB external-table dispatch | +| `src/backend/replication/logical/reorderbuffer.c` | Take upstream streaming additions; no GPDB-specific logic | +| `src/backend/storage/ipc/latch.c` | Take upstream long-lived `WaitEventSet`; thread `InitializeLatchWaitSet()` into GPDB startup | +| `src/test/regress/expected/*.out` | Always take GPDB version | +| `src/backend/po/*.po` / `src/bin/*/po/*.po` | Always take GPDB version | + +--- + +## 5. Common compile errors after PG13→14 merge + +| Error | Cause | Fix | +|---|---|---| +| `'PGXACT' undeclared` | PGXACT struct removed | Replace `allPgXact[i].field` with `ProcGlobal->field[proc->pgxactoff]` | +| `'PROC_HDR' has no member 'allPgXact'` | Dense array removed | Use `ProcGlobal->xids`, `->subxidStates`, `->statusFlags` | +| `'MyPgXact' undeclared` | Pointer removed | Use `MyProc->pgxactoff` to index into `ProcGlobal` arrays | +| `'CreateTableAsStmt' has no member 'relkind'` | Field renamed to `objtype` | Replace `.relkind` with `.objtype`; type is now `ObjectType` enum | +| `implicit declaration of 'InsertPgAttributeTuple'` | Renamed to plural form | Update call sites to `InsertPgAttributeTuples` | +| `'MAX_PGATTRIBUTE_INSERT_BYTES' undeclared` | Renamed | Replace with `MAX_CATALOG_MULTI_INSERT_BYTES` | +| `implicit declaration of 'GetFullRecentGlobalXmin'` | Function deleted | Use `GetOldestNonRemovableTransactionId()` | +| `'wal_keep_segments' undeclared` | GUC renamed to `wal_keep_size` | Update variable name and unit (`GUC_UNIT_MB`) | +| `implicit declaration of 'InitializeLatchWaitSet'` | New function not added to startup | Add call in postmaster/bgworker init | + +--- + +## 6. Use `cloudberrydb/cloudberrydb` as a reference branch + +Apache Cloudberry already completed a PG14 merge of the Greenplum codebase +and is the closest public reference for "how should a working GPDB-on-PG14 +look." When resolving a difficult merge conflict, fetch the cloudberry +remote and diff the file against `cloudberry/main`: + +```bash +git remote add cloudberry https://github.com/cloudberrydb/cloudberrydb.git +git fetch cloudberry --depth=1 +git show cloudberry/main:src/path/to/file.c | diff -u - src/path/to/file.c +``` + +Cloudberry diverges from Greengage in some areas (different optimizer +hooks, different resource-group implementation, etc.), so the diff is a +**reference, not a patch** — use it to confirm the *shape* of a PG14 +declaration, the *parameter signature* of a renamed function, the +*split* of a header that PG14 broke up, and which GPDB-specific +additions can be deleted because they were superseded upstream. + +Cases where cloudberry was decisive in `claude-merge-2`: + +| Question | Cloudberry-resolved finding | +|---|---| +| Does PG14 still need GPDB's `a_expr ColLabelNoAs` target_el rule? | No — `BareColLabel` covers all cases once GPDB keywords are added to `bare_label_keyword` | +| Did `create_append_path` keep `List *partitioned_rels`? | No — removed; the new signature has nine args, not ten | +| Where did `cost_material`, `exprType`, `is_opclause` etc. live? | `optimizer/cost.h` and `nodes/nodeFuncs.h` — no change from PG13 | +| Should `pgstat.h` still declare `BackendState`/`WaitEvent*`? | No — moved to `utils/backend_status.h` and `utils/wait_event.h`; pgstat.h just `#include`s them | + +## 7. Merge-artifact patterns we kept hitting (`claude-merge-2`) + +The recursive merge driver leaves three kinds of garbage that the build +later trips over. Recognize them on sight; the fix is mechanical. + +### 7.1 Duplicate-and-truncate in function signatures + +When upstream changes a signature and GPDB had local edits in the same +area, git often keeps **both** signatures and **truncates** one of them. +Result: a valid PG13 prototype, then an orphan tail of the PG14 one (or +vice versa). Cascades as "storage class specified for parameter X" on +every following extern in the same header. + +```c +extern void ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot); // ← PG13 +extern void ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, // ← truncated +extern void ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo, // ← PG14 (correct) + EState *estate, TupleTableSlot *slot); +``` + +Fix: delete the older signature (and the truncated tail) — keep PG14. +Cross-check against `cloudberry/main` if unsure. + +### 7.2 Lost opening `/*` or `#ifdef` + +The merge sometimes eats the leading line of a comment block or `#ifdef` +arm, leaving an orphan `* foo` or `#else /* WIN32 */` with no opener. +Compile error is "missing terminating ' character", "expected +specifier-qualifier-list before ..." or "#endif without #if". Symptom on +include-guarded headers: every consumer sees the file double-included, +producing redeclaration spam for every top-level decl. + +Hit in `claude-merge-2`: + - `src/include/postgres.h` — lost `#ifdef WORDS_BIGENDIAN` + - `src/include/miscadmin.h` — lost `#ifndef WIN32` + - `src/include/nodes/pathnodes.h` — lost `/*` before `VolatileFunctionStatus` comment and before `TidRangePath` comment + +### 7.3 PG14 split of `pgstat.h` + +PG14 broke `pgstat.h` into three headers and made the old `pgstat.h` +`#include` them for backward compatibility: + +| Type | New home | +|---|---| +| `BackendState`, `PgBackendStatus`, `PgBackendSSLStatus`, `PgBackendGSSStatus`, `LocalPgBackendStatus` | `utils/backend_status.h` | +| `WaitEventActivity`/`Client`/`IPC`/`Timeout`/`IO`, `PG_WAIT_*` macros, `pgstat_report_wait_start`/`end` | `utils/wait_event.h` | +| `ProgressCommandType`, `PGSTAT_NUM_PROGRESS_PARAM` | `utils/backend_progress.h` | + +GPDB extensions to those groups (the `PG_WAIT_RESOURCE_GROUP`, +`PG_WAIT_RESOURCE_QUEUE`, `PG_WAIT_REPLICATION`, +`PG_WAIT_PARALLEL_RETRIEVE_CURSOR` macros) must be **moved** into the +new home, not left in `pgstat.h` — otherwise they'll get dropped the +next time someone tidies `pgstat.h`. + +Resolution: in `pgstat.h`, delete the duplicated blocks (`BackendState`, +the `PG_WAIT_*` and `WaitEvent*` block, `ProgressCommandType` / +`PGSTAT_NUM_PROGRESS_PARAM`, the `PgBackend*Status` structs, and the +inline `pgstat_report_wait_start`/`end` helpers). Add the GPDB +`PG_WAIT_*` macros to `wait_event.h`. + +## 8. Catalog/`genbki.pl` rules tightened in PG14 + +### 8.1 `oid_symbol` is rejected for `pg_proc` and `pg_type` + +`genbki.pl` (line ~651) now *errors out* with "custom OID symbols are +not allowed for pg_proc entries" / "for pg_type entries". The fmgr +table (`Gen_fmgrtab.pl`) auto-generates `F_` for every pg_proc +row; `form_pg_type_symbol()` auto-generates `OID` / +`ARRAYOID` for every pg_type row. + +Resolution: +- Drop the `oid_symbol => '...'` field from every `pg_proc.dat` and + `pg_type.dat` entry. +- For pg_proc symbols that C/C++ code still references by name + (`COUNT_ANY_OID`, `MEDIAN_*_OID`, etc.), add explicit `#define`s in + `pg_proc.h` near the related `IS_MEDIAN_OID` macro. +- For pg_type symbols already matching the auto-generated form + (`COMPLEXOID` from `typname 'complex'`, `ANYTABLEOID` from + `typname 'anytable'`), no `#define` is needed — `form_pg_type_symbol` + produces the same name. + +### 8.2 `assign_next_oid()` replaced `$GenbkiNextOid` + +PG14 replaced the file-global `$GenbkiNextOid` scalar with a per-catalog +`assign_next_oid($catname)` call. Any GPDB-local `genbki.pl` patch that +uses `$GenbkiNextOid++` must be updated to call `assign_next_oid()` on +the appropriate catalog (e.g. `assign_next_oid('pg_opfamily')`). + +### 8.3 `DECLARE_TOAST` / `DECLARE_UNIQUE_INDEX` moved into per-catalog headers + +PG14 moved index and toast declarations from `catalog/indexing.h` and +`catalog/toasting.h` into the individual `pg_*.h` headers. The merge +must **not** keep both copies — any duplicated `DECLARE_*` lines in the +per-catalog headers (when the central headers still have them too) will +fail with "found N duplicate OID(s) in catalog data". + +Resolution: strip the duplicated `DECLARE_TOAST`, `DECLARE_INDEX`, +`DECLARE_UNIQUE_INDEX`, `DECLARE_UNIQUE_INDEX_PKEY` lines from the +**per-catalog headers** (taking PG14's central-header form). Leave the +central `indexing.h` / `toasting.h` declarations in place. + +### 8.4 GPDB-OID conflicts with PG14 multirange/sort-support OIDs + +PG14 grabbed OIDs in the 3000s, 4000s and 6150-6171 range for new +multirange types/operators, GiST sort_support, and `pg_stat_get_- +replication_slot` / `bit_count` functions. GPDB-specific entries that +landed there (notably the legacy `cdbhash_*` family and the AO_* +table/handler OIDs) collide. + +Resolution: renumber the GPDB entries to a confirmed-unused range. Run +`src/include/catalog/unused_oids` for an authoritative gap list — at +the time of `claude-merge-2` the script's first suggestion was 9446. +The renumbering used **9446–9469** (24 OIDs): + + - 3435 (AO_COLUMN_TABLE_AM_OID) → 9446 + - 4161/4162 (pg_collation toast) → 9447/9448 + - 4198 (AO_ROW_TABLE_AM_HANDLER_OID) → 9449 + - 4199 (AO_COLUMN_TABLE_AM_HANDLER_OID) → 9450 + - 6150–6158 (cdbhash) → 9451–9459 + - 6162–6171 (cdbhash) → 9460–9469 + +cdbhash 6140–6149 do **not** clash with PG14 and were left alone. + +## 9. Parser/grammar rules added in PG14 + +### 9.1 New `bare_label_keyword` rule + `check_keywords.pl` enforcement + +PG14 added a separate `bare_label_keyword` rule in `gram.y` that +enumerates the keywords usable as a column label *without* `AS`. The +`check_keywords.pl` script run by `Makefile` now enforces three +invariants: + + 1. Every keyword tagged `BARE_LABEL` in `kwlist.h` must appear in + `bare_label_keyword`. + 2. Conversely, every keyword in `bare_label_keyword` must be tagged + `BARE_LABEL` (or `AS_LABEL`) in `kwlist.h`. + 3. The `bare_label_keyword` rule must be alphabetically sorted + (with the `_P` suffix stripped for comparison, matching + `check_alphabetical_order` in `check_keywords.pl`). + +Resolution: when merging, append every GPDB-specific keyword that +`kwlist.h` marks as `BARE_LABEL` to `bare_label_keyword` and re-sort +the whole rule. In `claude-merge-2` this was 62 GPDB keywords. + +Exception: clause-introducing keywords (`PARTITION`, `DISTRIBUTED`, +`SCATTER`) **cannot** be `BARE_LABEL` because they create +shift/reduce conflicts with their clause syntax (e.g. `SELECT x +SCATTER` is ambiguous with `SELECT x [AS] alias FROM ... SCATTER`). +Mark these `AS_LABEL` in `kwlist.h` and omit from +`bare_label_keyword`. Forgetting this produces ~7000 reduce/reduce +conflicts and the build fails at the bison stage. + +### 9.2 New `BareColLabel` non-terminal supersedes GPDB's `ColLabelNoAs` + +PG14's `BareColLabel: IDENT | bare_label_keyword` covers the GPDB +extension that previously needed a separate `ColLabelNoAs` / +`keywords_ok_in_alias_no_as` rule. Once GPDB keywords are added to +`bare_label_keyword`, the `target_el: a_expr ColLabelNoAs { ... }` +alternative becomes redundant — and in fact **must** be removed +because keeping both produces hundreds of reduce/reduce conflicts. + +The `PartitionIdentKeyword` rule itself stays — it's still referenced +by `PartitionColId` in the ALTER TABLE partition syntax. + +### 9.3 New `opt_routine_body` / `opt_createfunc_opt_list` (commit `e717a9a18b2`) + +PG14 collapsed the four `CreateFunctionStmt` alternatives to a single +shape using `opt_createfunc_opt_list opt_routine_body` for SQL-standard +function bodies. The merge frequently mis-resolves these, leaving +truncated action blocks. The correct PG14 form is: + +```c +CreateFunctionStmt: + CREATE opt_or_replace FUNCTION func_name func_args_with_defaults + RETURNS func_return opt_createfunc_opt_list opt_routine_body { ... } + | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults + RETURNS TABLE '(' table_func_column_list ')' opt_createfunc_opt_list opt_routine_body { ... } + | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults + opt_createfunc_opt_list opt_routine_body { ... } + | CREATE opt_or_replace PROCEDURE func_name func_args_with_defaults + opt_createfunc_opt_list opt_routine_body { ... } +; +``` + +When the merge leaves multiple half-merged variants, just delete +everything and paste this block back. + +--- + +## 10. Batch-by-batch process for PG14 merge + +The adb-8.x history shows PG14 was merged in named batches (b1–b12). For +each batch: + +```bash +BATCH_END= +PREV_END= # last commit already merged + +git merge --no-commit --no-ff $BATCH_END +git diff --name-only --diff-filter=U | tee /tmp/conflicts_batch.txt +wc -l /tmp/conflicts_batch.txt + +# Resolve per this document and GG_PG_MERGE_RULES.md +# ... + +# Verify +git diff --name-only --diff-filter=U +rg "^<<<<<<<" src/ doc/ +grep -rn "PGXACT\|allPgXact" src/ --include="*.c" --include="*.h" + +# Build test +sudo docker build -t gpdb8_u22:test -f arenadata/Dockerfile.ubuntu . 2>&1 \ + | grep -E "\.c:[0-9]+: error|\.cpp:[0-9]+: error" | head -20 + +git commit -m "Merge PG14 commits $PREV_END..$BATCH_END + +Batch: +Conflicts resolved: " +``` + +--- + +## 11. Unit-test (mock/cmockery) phase — PG13→14 + +Once the tree compiles **and links**, a separate class of PG14 breakage +shows up only when running the backend mock tests: + +```bash +# CI form (serial — see §11.6); recurses src/backend then src/bin and +# runs every cmockery-based *_test.c program. +make -s unittest-check +``` + +Ground truth: the `claude-merge-2` unit-test fix commits (`185a312bb2a`, +`55eb9df9af6`, `a38fa247d9e`, `3237b4bff21`, `e1216380a35` … +`f3d3b9e9f5c`, plus the `mock.mk` and `ftsmessagehandler_test.c` fixes +made while resolving the test run). At the end of `claude-merge-2` all +53 mock test suites (backend + `src/bin`) pass. + +### 11.1 `errstart` split into `errstart` / `errstart_cold` (the dominant test break) + +PG14 split `errstart()` into a warm path and a cold path. The +`ereport`/`elog` macros now call **`errstart_cold()`** when the elevel is +a compile-time constant `>= ERROR`, and `errstart()` otherwise. Mock +tests that drive an ERROR/FATAL path set their `expect_*`/`will_return` +on the wrong symbol, so cmockery aborts with a "no expectations" error +on `errstart`. + +Fix each affected test's local `EXPECT_EREPORT()` helper to branch on the +level (note: the exact `will_return*` form differs per file — preserve +the file's own side-effect callback): + +```c +#define EXPECT_EREPORT(LOG_LEVEL) \ + if (LOG_LEVEL < ERROR) { \ + expect_value(errstart, elevel, (LOG_LEVEL)); \ + expect_any(errstart, domain); \ + will_return(errstart, false); \ + } else { \ + expect_value(errstart_cold, elevel, (LOG_LEVEL)); \ + expect_any(errstart_cold, domain); \ + will_return_with_sideeffect(errstart_cold, false, &_errfinish_impl, NULL); \ + } +``` + +Files fixed: `tcop/test/postgres_test.c`, `utils/fmgr/test/dfmgr_test.c`, +`utils/init/test/postinit_test.c`, `utils/test/session_state_test.c`, +`utils/mmgr/test/runaway_cleaner_test.c`, +`replication/test/gp_replication_test.c`. +**Do not** blindly edit every test that names `errstart`: +`utils/mmgr/test/redzone_handler_test.c` and `libpq/test/pqcomm_test.c` +only exercise sub-ERROR levels and must keep plain `errstart`. + +### 11.2 GUC coverage test — every new PG14 GUC must be listed + +`utils/misc/test/guc_test.c` (and `guc_gp_test.c`) assert that **every** +GUC in `ConfigureNamesBool/Int/Real/String/Enum` appears in exactly one +of `src/include/utils/sync_guc_name.h` or `unsync_guc_name.h`. A new PG14 +GUC trips `test_*_guc_coverage`: + +``` +GUC: '' does not exist in both list. +``` + +Resolution: add each new upstream PG14 GUC to **`unsync_guc_name.h`**, +**alphabetically** (it is not distributed/synced to segments), and keep +the two lists mutually exclusive (`test_guc_name_list_mutual_exclusion`). +The 14 GUCs added in `claude-merge-2`: + +``` +compute_query_id, debug_invalidate_system_caches_always, +default_toast_compression, enable_async_append, enable_resultcache, +idle_session_timeout, in_hot_standby, log_recovery_conflict_waits, +recovery_init_sync_method, remove_temp_files_after_crash, ssl_crl_dir, +track_wal_io_timing, vacuum_failsafe_age, vacuum_multixact_failsafe_age +``` + +### 11.3 mock-link breakage: PG14 widened what the test programs pull in + +Two `src/backend/mock.mk` changes were needed: + +1. **`uuid_le` / `brin_minmax_multi`.** PG14's new `brin_minmax_multi.c` + calls `uuid_le()`. Remove `src/backend/utils/adt/uuid.o` from + `EXCL_OBJS` and add `$(UUID_LIBS)` to `MOCK_LIBS`, or every test + program fails to link with `undefined reference to 'uuid_le'`. + +2. **`get_dirent_type` pulls in the FRONTEND `libpgcommon`.** PG14's + `fd.c` (`walkdir`) calls the new `get_dirent_type()`, which lives in + `src/common/file_utils.c` (outside its `#ifdef FRONTEND`, so it is in + *both* `libpgcommon_srv.a` and the frontend `libpgcommon.a`). The one + test that mocks `fd` — `cdb/test/cdbappendonlyxlog` — then has + `fd_mock.o` referencing `get_dirent_type` **after** the linker has + already scanned the server `libpgcommon_srv.a` (it sits in + `objfiles.txt`, ahead of the mock objects). The reference is resolved + from the FRONTEND `libpgcommon.a` carried in `$(LIBS)`, dragging in + frontend `file_utils.o` + `fe_memutils.o` and detonating with: + + ``` + multiple definition of `fsync_fname' / `durable_rename' (vs fd_mock.o) + multiple definition of `palloc' / `pfree' / `pstrdup' ... (vs mcxt.o) + ``` + + Fix: re-list the **server** archives *after* the mock objects in the + `%.t` link rule, so late `src/common` references resolve against the + server variant (which omits the FRONTEND-only `fsync_fname` / + `durable_rename` / `palloc`): + + ```make + MOCK_SRV_LIBS := $(top_builddir)/src/common/libpgcommon_srv.a \ + $(top_builddir)/src/port/libpgport_srv.a + # ... in the %.t recipe, between the mock objects and $(MOCK_LIBS): + ... $(filter-out %/objfiles.txt, $^) $(MOCK_SRV_LIBS) $(MOCK_LIBS) -o $@ + ``` + + This is the correct fix (server `file_utils_srv.o` defines only + `get_dirent_type`, references `palloc` which `mcxt.o` already + satisfies) — prefer it over `-Wl,--allow-multiple-definition`. + +### 11.4 Mock expectations must cover new PG14 function parameters + +When PG14 adds a parameter to a function a test mocks, the +auto-generated mock checks the new parameter and the test fails with: + +``` +Could not get value to check parameter of function +``` + +Add the matching `expect_value()`/`expect_any()` with the value from the +real call site. Concrete case: PG14 added `bool two_phase` to +`ReplicationSlotCreate()`; `fts/test/ftsmessagehandler_test.c` needed +`expect_value(ReplicationSlotCreate, two_phase, false);` to match the +`ReplicationSlotCreate(name, false, RS_PERSISTENT, false)` call in +`ftsmessagehandler.c`. Post-merge grep: `Could not get value to check parameter`. + +### 11.5 Verification + +```bash +# Run the whole suite the way CI does (serial): +make -s unittest-check 2>&1 | tee /tmp/ut.log +grep -E "\[ FAILED" /tmp/ut.log # must be empty +echo "exit=$?" # make must exit 0 + +# Targeted re-run of one directory while iterating: +make -C src/backend//test check +``` + +### 11.6 Caveat: `make -j unittest-check` races (do not mistake for regressions) + +The mock build generates shared objects (`cmockery.o`, the per-file +`*_mock.o`) on demand; under `-j`, multiple test directories build the +same shared object concurrently and intermittently fail with +`cannot find .../cmockery.o`, spurious `undefined reference`, or +truncated-object link errors. CI runs the target **serially**. When +triaging a `-j` failure, **re-run the offending directory serially** +before assuming a real break — in `claude-merge-2`, 3 of the 5 initial +`-j` failures (`catalog/storage_tablespace`, `utils/datumstream`, +`utils/hash/dynahash`) were only this race; the two genuine failures were +§11.3.2 (`cdbappendonlyxlog`) and §11.4 (`ftsmessagehandler`). + +--- + +## 12. Other PG14 API-shape changes hit during `claude-merge-2` + +These are mechanical "adopt the new signature, re-graft GPDB args" fixes +not covered above. Each row is a real commit from the fix history. + +| Symbol / area | PG14 change | Resolution | +|---|---|---| +| `commands/copy.c` | `copy.c` split into `copyfrom.c`/`copyto.c`; `CopyState`→`CopyFromState`/`CopyToState`; protocol-v2 removed | **GPDB keeps the monolithic `copy.c` + unified `CopyStateData`** (it heavily extends it for external tables / distribution). Map upstream `Copy{From,To}State` back to `CopyState`; re-graft only the protocol change: drop v2 branches, collapse `COPY_OLD_FE`/`COPY_NEW_FE`→`COPY_FRONTEND` (keep old names as compat macros), use direct `pq_beginmessage`/`pq_endmessage`. | +| `BeginCopyFrom()` | upstream gained a `whereClause` arg | GPDB's signature differs — when fixing callers (`file_fdw`) match **GPDB's** arg list; the merge tends to insert a spurious extra `NULL`. | +| `src/bin/scripts` connect API | `connectDatabase`/`connectMaintenanceDatabase` now take a `ConnParams *` (`fe_utils/connect_utils.h`) | Take **cloudberry's `scripts/common.c`/`.h` wholesale**; revert any transient `*_cparams` wrapper shims. | +| `simple_prompt()` | returns the string (no caller buffer); moved `src/port`→`src/common` | Update `initdb.c`, `pgbench.c`, `scripts/common.c`; add `sprompt.o` to link where needed. | +| `output_completion_banner()` | now 1 arg (was 2) | `pg_upgrade` caller. | +| `fmtQualifiedId()` | GPDB form takes no encoding arg | Drop cloudberry's `fmtQualifiedIdEnc`; use `fmtQualifiedId`. | +| `ReindexIndex`/`ReindexTable` | unified into `ExecReindex()` | Replace the GPDB Reindex dispatch in `utility.c` with `ExecReindex`. | +| `ProcedureCreate()` | upstream arg list changed | Re-add the two **GPDB-specific trailing args** `prodataaccess`, `proexeclocation` (e.g. the four multirange-constructor calls in `typecmds.c`). | +| `cluster_rel()` | return type `bool`→`void` | Drop the return-value use. | +| `pg_hex_encode()`/`pg_hex_decode()` | gained a `dstlen` arg | Thread the destination length through callers. | +| `errcontext_msg()` / `set_errcontext_domain()` | return `int` (was `void`), for the new `ereport` | Fix the return types in GPDB copies. | +| `pqPutMsgStart()` | dropped the `force` parameter | Update `cdbdisp_async.c`. | +| `nodeModifyTable` | single subplan: `mt_whichplan`/`mt_nplans`/`mt_plans` gone; `TransitionCaptureState.tcs_map` gone; `jf_junkAttNo`→`ri_RowIdAttNo`; `ri_PartitionCheck`→`rd_rel->relispartition` | Remove the dead multi-subplan logic; fix `ExecInsert`/`ExecUpdate`/`ExecDelete` and `ExecCrossPartitionUpdate` (new `segid`) call sites. | +| `ReadNewTransactionId()` | renamed `ReadNextTransactionId()` | Mechanical rename (also in `test/regress`). | +| `doputenv()` | use `setenv()` | `pg_regress.c` / regress driver. | +| backend `libpq` protocol v2 | `fe-protocol2.c` removed | Drop `fe-protocol2` from the backend libpq `Makefile`. | + +--- + +## 13. `initdb` / cluster-bootstrap phase — PG13→14 + +After the tree compiles **and** the mock unit tests pass, the next gate is +`initdb` (creating the demo cluster). The merge left a whole class of +catalog / BKI / planner regressions that **neither the compiler nor the +cmockery tests can catch** — they only fire when `initdb` actually builds +and populates `template1`. In `claude-merge-2`, `initdb` was completely +broken and took **7 distinct fixes** (commit `770bc1f1fb2`) to get through +bootstrap and most of post-bootstrap; one larger item (the PG14 UPDATE +rework, §13.5) remained. + +### 13.1 How to run and diagnose + +Fast dev loop (don't rebuild the Docker image per fix — see +[[build-test-docker-workflow]]): run a container with the **mounted** source +plus `--sysctl kernel.sem=...`, build once with +`--prefix=/usr/local/greenplum-db-devel` (ORCA on), install, create the +gpadmin user + demo cluster, then iterate: + +```bash +# after editing a source file, reinstall only what changed and re-run initdb +make -j20 -C src/backend install # backend (.c) or BKI/genbki/catalog headers +make -C src/backend/catalog install # *.sql data files (system_views.sql etc.) +su gpadmin -c '.../bin/initdb -E UNICODE -D /tmp/idbtest' # or make_cluster +``` + +`initdb` errors arrive as a backend `FATAL`/`PANIC` (the `PANIC: cannot +abort transaction 1, it was already committed` is just fallout — look at +the `FATAL` line just above it) followed by +`initdb: error: ... cdb_init.d directory: Broken pipe`. + +**The decisive diagnostic for every one of these:** diff the suspect file +against the merge's **PG14 parent**, not `gg_upgrade` (which is PG13): + +```bash +git show ^2:src/path/to/file # authoritative "what PG14 does" +git show :src/path/to/file # what GPDB had before (first parent) +``` + +Bootstrap and post-bootstrap are two distinct sub-phases: + +### 13.2 Bootstrap (`postgres.bki`) failures + +These happen during `running bootstrap script ...` — the backend reads the +generated `postgres.bki`. All are catalog/genbki resolution errors. + +- **Catalog header ordering.** PG14's `pg_statistic_ext_data.stxdexpr` is + `pg_statistic[]` (`_pg_statistic`), so `pg_statistic.h` must precede + `pg_statistic_ext*.h` in `CATALOG_HEADERS` (`src/backend/catalog/Makefile`) + — the BKI creates a catalog's array type only when the catalog itself is + created. Symptom: `FATAL: unrecognized type "_pg_statistic"` in + `bootstrap.c gettype`. (See also §8; the comment in that Makefile warns of + "undocumented ordering dependencies".) + +- **BKI string-literal quoting must be self-consistent.** PG14 switched the + BKI to **single-quoted** strings, inverted by `DeescapeQuotedString()`. + Four files must agree, and the merge is prone to taking some from PG14 and + some from GPDB-PG13: + - `genbki.pl` — emit `sprintf("'%s'", …)`, escape `''`; + - `bootscanner.l` — `sid \'([^']|\'\')*\'`, action `DeescapeQuotedString(yytext)` + (PG14 dropped `scanstr()` and `parser/scansup.h`'s use here); + - `initdb.c` `escape_quotes_bki()` — wrap in **single** quotes (not the old + double-quote / `\042`-octal form); + - `guc-file.l` `DeescapeQuotedString()` — single-quote (shared with + `postgresql.conf`, so leave it single-quote). + Symptom: `FATAL: syntax error at line N: unexpected character """` (a `"` + from the old `initdb.c`) or `... "'"` (a `'` reaching a double-quote + scanner). Fix all four to the PG14 single-quote convention. + +- **GPDB-only genbki substitutions get dropped.** PG14's `genbki.pl` has no + `PGUID` handling (it's GPDB-specific, for `pg_compression.compowner`'s + `BKI_DEFAULT(PGUID)`). When the merge adopts upstream `genbki.pl` shape it + loses GPDB's `s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g` (and the + `$BOOTSTRAP_SUPERUSERID` definition). Symptom: `FATAL: invalid input + syntax for type oid: "PGUID"` in `InsertOneValue`. Re-add the substitution. + +- **Missing per-catalog index `DECLARE`s.** PG14 added the `pg_range` + multirange index `pg_range_rngmultitypid_index` (oid 2228). GPDB keeps + index declarations in central `indexing.h` (§8.3); the merge moved + `pg_range`'s `rngtypid` index but dropped the new `rngmultitypid` one. + Symptom: `FATAL: could not open relation with OID 2228` in post-bootstrap. + Cross-check every `#define IndexId` against a matching + `DECLARE_UNIQUE_INDEX(...)`. + +### 13.3 Post-bootstrap (SQL) failures + +These happen during `performing post-bootstrap initialization ...`, while +`initdb` feeds `system_views.sql`, `information_schema.sql`, snowball, and +GPDB's `cdb_init.d/*.sql`. **Note GPDB installs only `system_views.sql` +(plus information_schema/snowball) — there is no `system_functions.sql` in +the install**, so functions PG14 placed in `system_functions.sql` must +instead live in `pg_proc.dat` or `system_views.sql`. + +- **Duplicate keys in a `pg_proc.dat` entry (Perl last-wins).** When both the + GPDB and the upstream PG14 versions of `proallargtypes` / `proargmodes` / + `proargnames` survive in one entry, Perl keeps the **last**, silently + dropping the other. Hit on `pg_stat_get_activity`: the GPDB set + (`…leader_pid,sess_id,rsgid,rsgname`, with `sslcompression`) and the PG14 + set (`…leader_pid,query_id`, no `sslcompression`) were both present, so the + GPDB columns vanished and `CREATE VIEW pg_stat_activity` failed with + `column s.sess_id does not exist`. Fix: collapse to **one** set that + matches the C function (`pgstatfuncs.c`, `PG_STAT_GET_ACTIVITY_COLS`) + exactly — here PG14's columns *plus* GPDB's `sess_id`/`rsgid`/`rsgname`. + `.dat` files can't be opened by some editors as text (binary heuristic on + the extension) — edit with a verified `python3`/`perl` script and assert + the three token-counts are equal. + +- **A function PG14 relocated between `pg_proc.dat` and `system_views.sql`.** + PG14 moved `ts_debug` *into* `pg_proc.dat` (as `prolang => 'sql'` entries) + and removed it from `system_views.sql`. The merge took the new `pg_proc.dat` + entries but kept GPDB's old `system_views.sql` copy → `FATAL: function + "ts_debug" already exists`. Remove the stale `system_views.sql` definition. + +- **PG14 row-identity wiring missing for UPDATE/DELETE.** The whole PG14 + lazy row-identity machinery (`add_row_identity_columns`, + `add_row_identity_var`, `distribute_row_identity_vars`, `row_identity_vars`) + was merged into `appendinfo.c`/`inherit.c`/`planmain.c`, but + `preprocess_targetlist()` (`preptlist.c`) was left as GPDB's old version + that never calls `add_row_identity_columns()` for the base result relation. + So a simple `DELETE` gets no `ctid` junk column → `FATAL: could not find + junk ctid column` in `ExecInitModifyTable`. Fix: add the upstream block to + `preprocess_targetlist`: + ```c + if ((command_type == CMD_UPDATE || command_type == CMD_DELETE) && + !target_rte->inh) + { + root->processed_tlist = tlist; + add_row_identity_columns(root, result_relation, target_rte, target_relation); + tlist = root->processed_tlist; + } + ``` + +### 13.4 Error → cause → fix quick table + +| `initdb` FATAL | Phase | Cause | Fix | +|---|---|---|---| +| `unrecognized type "_pg_statistic"` | bootstrap | catalog header order | `pg_statistic.h` before `pg_statistic_ext*.h` | +| `syntax error … unexpected character "…"` | bootstrap | BKI quote convention split across files | single-quote everywhere (§13.2) | +| `invalid input syntax for type oid: "PGUID"` | bootstrap | genbki lost GPDB `PGUID` sub | restore `s/\bPGUID\b/.../` + `$BOOTSTRAP_SUPERUSERID` | +| `could not open relation with OID 2228` | post | missing index `DECLARE` | add `pg_range_rngmultitypid_index` to `indexing.h` | +| `could not find junk ctid column` | post | `preprocess_targetlist` missing row-identity call | add `add_row_identity_columns` block | +| `column s.sess_id does not exist` | post | duplicate `.dat` keys, last-wins | one merged `pg_stat_get_activity` col set | +| `function "ts_debug" already exists` | post | function in both `pg_proc.dat` and `system_views.sql` | drop the `system_views.sql` copy | +| `targetColnos does not match subplan target list` | post | PG14 UPDATE rework not adopted | §13.5 (open) | + +### 13.5 Open: PG14 UPDATE planning rework (`update_colnos`) + +PG14 commit `86dc90056d` reworked UPDATE/DELETE planning. The **DELETE** half +is handled by §13.3's row-identity wiring. The **UPDATE** half is larger and +was *not* adopted: PG14 `preprocess_targetlist` does +`root->update_colnos = extract_update_targetlist_colnos(tlist)` (it does +**not** expand the UPDATE tlist), threads `updateColnos` through +`ModifyTable`, and `ExecBuildUpdateProjection` uses it. GPDB's merged +`preprocess_targetlist` still calls the old `expand_targetlist()` for +`CMD_UPDATE`, so the executor trips on `targetColnos does not match subplan +target list`. Re-grafting this is entangled with GPDB's MPP **split-update** +(distribution-key updates), so it's a substantial, higher-risk change — +use Apache Cloudberry (which already did PG14 + GPDB) as the reference (§6). diff --git a/GNUmakefile.in b/GNUmakefile.in index 8ff92755ace7..d1429e13ce74 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -26,7 +26,7 @@ all: $(MAKE) -C contrib/pgcrypto all $(MAKE) -C contrib/btree_gin all $(MAKE) -C contrib/pg_trgm all -ifeq ($(with_openssl), yes) +ifeq ($(with_ssl), openssl) $(MAKE) -C contrib/sslinfo all endif ifneq ($(with_uuid),no) @@ -65,7 +65,7 @@ install: $(MAKE) -C contrib/pgcrypto $@ $(MAKE) -C contrib/btree_gin $@ $(MAKE) -C contrib/pg_trgm $@ -ifeq ($(with_openssl), yes) +ifeq ($(with_ssl), openssl) $(MAKE) -C contrib/sslinfo $@ endif ifneq ($(with_uuid),no) @@ -162,7 +162,7 @@ ICW_TARGETS += contrib/file_fdw contrib/formatter_fixedwidth ICW_TARGETS += contrib/extprotocol contrib/dblink contrib/pg_trgm ICW_TARGETS += contrib/indexscan contrib/hstore contrib/ltree contrib/pgcrypto # sslinfo depends on openssl -ifeq ($(with_openssl), yes) +ifeq ($(with_ssl), openssl) ICW_TARGETS += contrib/sslinfo endif ifneq ($(with_uuid),no) diff --git a/README.docker.md b/README.docker.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/config/config.guess b/config/config.guess index 11fda528bc7b..1972fda8eb05 100644 --- a/config/config.guess +++ b/config/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2020 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2020-04-26' +timestamp='2021-01-25' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -27,12 +27,12 @@ timestamp='2020-04-26' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2020 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -103,7 +103,7 @@ set_cc_for_build() { test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039 - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } @@ -131,16 +131,14 @@ if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown +UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown +UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown +UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu + LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" @@ -149,17 +147,29 @@ Linux|GNU|GNU/*) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc - #else + #elif defined(__GLIBC__) LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')" - # If ldd exists, use it to detect musl libc. - if command -v ldd >/dev/null && \ - ldd --version 2>&1 | grep -q ^musl - then - LIBC=musl + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu fi ;; esac @@ -178,20 +188,20 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - "/sbin/$sysctl" 2>/dev/null || \ - "/usr/sbin/$sysctl" 2>/dev/null || \ - echo unknown)` + UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)) case "$UNAME_MACHINE_ARCH" in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,') + endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p') machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; @@ -222,7 +232,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr") ;; esac # The OS release @@ -235,7 +245,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in release='-gnu' ;; *) - release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2) ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: @@ -244,15 +254,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//') echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//') echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//') echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) @@ -288,17 +298,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}') ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}') ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1) case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; @@ -336,7 +346,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + echo "$UNAME_MACHINE"-dec-osf"$(echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 @@ -370,7 +380,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then + if test "$( (/bin/universe) 2>/dev/null)" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd @@ -383,17 +393,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in + case $(/usr/bin/uname -p) in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" @@ -404,7 +414,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null @@ -412,30 +422,30 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in SUN_ARCH=x86_64 fi fi - echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case "$(/usr/bin/arch -k)" in Series*|S4*) - UNAME_RELEASE=`uname -v` + UNAME_RELEASE=$(uname -v) ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null) test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 - case "`/bin/arch`" in + case "$(/bin/arch)" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; @@ -515,8 +525,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && - dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`"$dummy" "$dummyarg"` && + dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') && + SYSTEM_NAME=$("$dummy" "$dummyarg") && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; @@ -543,11 +553,11 @@ EOF exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + UNAME_PROCESSOR=$(/usr/bin/uname -p) + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ - [ "$TARGET_BINARY_INTERFACE"x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then echo m88k-dg-dgux"$UNAME_RELEASE" else @@ -571,17 +581,17 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if test -x /usr/bin/oslevel ; then + IBM_REV=$(/usr/bin/oslevel) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -601,7 +611,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") then echo "$SYSTEM_NAME" else @@ -614,15 +624,15 @@ EOF fi exit ;; *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + IBM_CPU_ID=$(/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }') if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/lslpp ] ; then - IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | - awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + if test -x /usr/bin/lslpp ; then + IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/) else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi @@ -650,14 +660,14 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + if test -x /usr/bin/getconf; then + sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null) + sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null) case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 @@ -669,7 +679,7 @@ EOF esac ;; esac fi - if [ "$HP_ARCH" = "" ]; then + if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" @@ -704,11 +714,11 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy") test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ "$HP_ARCH" = hppa2.0w ] + if test "$HP_ARCH" = hppa2.0w then set_cc_for_build @@ -732,7 +742,7 @@ EOF echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//') echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) @@ -762,7 +772,7 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; @@ -782,7 +792,7 @@ EOF echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then + if test -x /usr/sbin/sysversion ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 @@ -831,14 +841,14 @@ EOF echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz) + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/') echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///') + FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/') echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) @@ -851,25 +861,25 @@ EOF echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; arm:FreeBSD:*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi else - echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf fi exit ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=$(/usr/bin/uname -p) case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin @@ -905,15 +915,15 @@ EOF echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')" exit ;; *:GNU:*:*) # the GNU system - echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + echo "$(echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,')-unknown-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC" exit ;; *:Minix:*:*) echo "$UNAME_MACHINE"-unknown-minix @@ -926,7 +936,7 @@ EOF echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -985,6 +995,9 @@ EOF k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; @@ -1035,7 +1048,7 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) @@ -1055,7 +1068,7 @@ EOF exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; @@ -1073,7 +1086,7 @@ EOF ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; - riscv32:Linux:*:* | riscv64:Linux:*:*) + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) @@ -1095,7 +1108,17 @@ EOF echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + set_cc_for_build + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_X32 >/dev/null + then + LIBCABI="$LIBC"x32 + fi + fi + echo "$UNAME_MACHINE"-pc-linux-"$LIBCABI" exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" @@ -1135,7 +1158,7 @@ EOF echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) - UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//') if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else @@ -1144,7 +1167,7 @@ EOF exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in + case $(/bin/uname -X | grep "^Machine") in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; @@ -1153,10 +1176,10 @@ EOF exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //')) (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 @@ -1206,7 +1229,7 @@ EOF 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1217,7 +1240,7 @@ EOF NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + && OS_REL=.$(sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ @@ -1250,7 +1273,7 @@ EOF exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=$( (uname -p) 2>/dev/null) echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv @@ -1284,7 +1307,7 @@ EOF echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then + if test -d /usr/nec; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" @@ -1332,8 +1355,11 @@ EOF *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; + arm64:Darwin:*:*) + echo aarch64-apple-darwin"$UNAME_RELEASE" + exit ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac @@ -1346,7 +1372,7 @@ EOF else set_cc_for_build fi - if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null @@ -1370,7 +1396,7 @@ EOF echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` + UNAME_PROCESSOR=$(uname -p) if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc @@ -1438,10 +1464,10 @@ EOF echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')" exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=$( (uname -p) 2>/dev/null) case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1451,13 +1477,13 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; - i*86:AROS:*:*) - echo "$UNAME_MACHINE"-pc-aros + *:AROS:*:*) + echo "$UNAME_MACHINE"-unknown-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx @@ -1509,7 +1535,7 @@ main () #define __ARCHITECTURE__ "m68k" #endif int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null); if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else @@ -1601,7 +1627,7 @@ main () } EOF -$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. @@ -1626,14 +1652,14 @@ This script (version $timestamp), has failed to recognize the operating system you are using. If your script is old, overwrite *all* copies of config.guess and config.sub with the latest versions from: - https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess + https://git.savannah.gnu.org/cgit/config.git/plain/config.guess and - https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + https://git.savannah.gnu.org/cgit/config.git/plain/config.sub EOF -year=`echo $timestamp | sed 's,-.*,,'` +year=$(echo $timestamp | sed 's,-.*,,') # shellcheck disable=SC2003 -if test "`expr "\`date +%Y\`" - "$year"`" -lt 3 ; then +if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then cat >&2 </dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` +uname -m = $( (uname -m) 2>/dev/null || echo unknown) +uname -r = $( (uname -r) 2>/dev/null || echo unknown) +uname -s = $( (uname -s) 2>/dev/null || echo unknown) +uname -v = $( (uname -v) 2>/dev/null || echo unknown) -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` +/usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null) +/bin/uname -X = $( (/bin/uname -X) 2>/dev/null) -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` +hostinfo = $( (hostinfo) 2>/dev/null) +/bin/universe = $( (/bin/universe) 2>/dev/null) +/usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null) +/bin/arch = $( (/bin/arch) 2>/dev/null) +/usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null) +/usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null) UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" diff --git a/config/config.sub b/config/config.sub index a0d12275ac5f..7f7d0b055ac5 100644 --- a/config/config.sub +++ b/config/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2020 Free Software Foundation, Inc. +# Copyright 1992-2021 Free Software Foundation, Inc. -timestamp='2020-04-24' +timestamp='2021-03-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -33,7 +33,7 @@ timestamp='2020-04-24' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -50,7 +50,7 @@ timestamp='2020-04-24' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. -me=`echo "$0" | sed -e 's,.*/,,'` +me=$(echo "$0" | sed -e 's,.*/,,') usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2020 Free Software Foundation, Inc. +Copyright 1992-2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -124,28 +124,27 @@ case $1 in ;; *-*-*-*) basic_machine=$field1-$field2 - os=$field3-$field4 + basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ - | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ + nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova*) basic_machine=$field1 - os=$maybe_os + basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown - os=linux-android + basic_os=linux-android ;; *) basic_machine=$field1-$field2 - os=$field3 + basic_os=$field3 ;; esac ;; @@ -154,7 +153,7 @@ case $1 in case $field1-$field2 in decstation-3100) basic_machine=mips-dec - os= + basic_os= ;; *-*) # Second component is usually, but not always the OS @@ -162,7 +161,7 @@ case $1 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 - os=$field2 + basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ @@ -175,11 +174,11 @@ case $1 in | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 - os= + basic_os= ;; *) basic_machine=$field1 - os=$field2 + basic_os=$field2 ;; esac ;; @@ -191,447 +190,451 @@ case $1 in case $field1 in 386bsd) basic_machine=i386-pc - os=bsd + basic_os=bsd ;; a29khif) basic_machine=a29k-amd - os=udi + basic_os=udi ;; adobe68k) basic_machine=m68010-adobe - os=scout + basic_os=scout ;; alliant) basic_machine=fx80-alliant - os= + basic_os= ;; altos | altos3068) basic_machine=m68k-altos - os= + basic_os= ;; am29k) basic_machine=a29k-none - os=bsd + basic_os=bsd ;; amdahl) basic_machine=580-amdahl - os=sysv + basic_os=sysv ;; amiga) basic_machine=m68k-unknown - os= + basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown - os=amigaos + basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown - os=sysv4 + basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo - os=sysv + basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo - os=bsd + basic_os=bsd ;; aros) basic_machine=i386-pc - os=aros + basic_os=aros ;; aux) basic_machine=m68k-apple - os=aux + basic_os=aux ;; balance) basic_machine=ns32k-sequent - os=dynix + basic_os=dynix ;; blackfin) basic_machine=bfin-unknown - os=linux + basic_os=linux ;; cegcc) basic_machine=arm-unknown - os=cegcc + basic_os=cegcc ;; convex-c1) basic_machine=c1-convex - os=bsd + basic_os=bsd ;; convex-c2) basic_machine=c2-convex - os=bsd + basic_os=bsd ;; convex-c32) basic_machine=c32-convex - os=bsd + basic_os=bsd ;; convex-c34) basic_machine=c34-convex - os=bsd + basic_os=bsd ;; convex-c38) basic_machine=c38-convex - os=bsd + basic_os=bsd ;; cray) basic_machine=j90-cray - os=unicos + basic_os=unicos ;; crds | unos) basic_machine=m68k-crds - os= + basic_os= ;; da30) basic_machine=m68k-da30 - os= + basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec - os= + basic_os= ;; delta88) basic_machine=m88k-motorola - os=sysv3 + basic_os=sysv3 ;; dicos) basic_machine=i686-pc - os=dicos + basic_os=dicos ;; djgpp) basic_machine=i586-pc - os=msdosdjgpp + basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd - os=ebmon + basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson - os=ose + basic_os=ose ;; gmicro) basic_machine=tron-gmicro - os=sysv + basic_os=sysv ;; go32) basic_machine=i386-pc - os=go32 + basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi - os=hms + basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi - os=xray + basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi - os=hms + basic_os=hms ;; harris) basic_machine=m88k-harris - os=sysv3 + basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp - os=hpux + basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp - os=bsd + basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp - os=osf + basic_os=osf ;; hppro) basic_machine=hppa1.1-hp - os=proelf + basic_os=proelf ;; i386mach) basic_machine=i386-mach - os=mach + basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi - os=sysv + basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown - os=linux + basic_os=linux ;; magnum | m3230) basic_machine=mips-mips - os=sysv + basic_os=sysv ;; merlin) basic_machine=ns32k-utek - os=sysv + basic_os=sysv ;; mingw64) basic_machine=x86_64-pc - os=mingw64 + basic_os=mingw64 ;; mingw32) basic_machine=i686-pc - os=mingw32 + basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown - os=mingw32ce + basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k - os=coff + basic_os=coff ;; morphos) basic_machine=powerpc-unknown - os=morphos + basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown - os=moxiebox + basic_os=moxiebox ;; msdos) basic_machine=i386-pc - os=msdos + basic_os=msdos ;; msys) basic_machine=i686-pc - os=msys + basic_os=msys ;; mvs) basic_machine=i370-ibm - os=mvs + basic_os=mvs ;; nacl) basic_machine=le32-unknown - os=nacl + basic_os=nacl ;; ncr3000) basic_machine=i486-ncr - os=sysv4 + basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc - os=netbsd + basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel - os=linux + basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony - os=newsos + basic_os=newsos ;; news1000) basic_machine=m68030-sony - os=newsos + basic_os=newsos ;; necv70) basic_machine=v70-nec - os=sysv + basic_os=sysv ;; nh3000) basic_machine=m68k-harris - os=cxux + basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris - os=cxux + basic_os=cxux ;; nindy960) basic_machine=i960-intel - os=nindy + basic_os=nindy ;; mon960) basic_machine=i960-intel - os=mon960 + basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq - os=nonstopux + basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm - os=os400 + basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson - os=ose + basic_os=ose ;; os68k) basic_machine=m68k-none - os=os68k + basic_os=os68k ;; paragon) basic_machine=i860-intel - os=osf + basic_os=osf ;; parisc) basic_machine=hppa-unknown - os=linux + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp ;; pw32) basic_machine=i586-unknown - os=pw32 + basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc - os=rdos + basic_os=rdos ;; rdos32) basic_machine=i386-pc - os=rdos + basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k - os=coff + basic_os=coff ;; sa29200) basic_machine=a29k-amd - os=udi + basic_os=udi ;; sei) basic_machine=mips-sei - os=seiux + basic_os=seiux ;; sequent) basic_machine=i386-sequent - os= + basic_os= ;; sps7) basic_machine=m68k-bull - os=sysv2 + basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem - os= + basic_os= ;; stratus) basic_machine=i860-stratus - os=sysv4 + basic_os=sysv4 ;; sun2) basic_machine=m68000-sun - os= + basic_os= ;; sun2os3) basic_machine=m68000-sun - os=sunos3 + basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun - os=sunos4 + basic_os=sunos4 ;; sun3) basic_machine=m68k-sun - os= + basic_os= ;; sun3os3) basic_machine=m68k-sun - os=sunos3 + basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun - os=sunos4 + basic_os=sunos4 ;; sun4) basic_machine=sparc-sun - os= + basic_os= ;; sun4os3) basic_machine=sparc-sun - os=sunos3 + basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun - os=sunos4 + basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun - os=solaris2 + basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun - os= + basic_os= ;; sv1) basic_machine=sv1-cray - os=unicos + basic_os=unicos ;; symmetry) basic_machine=i386-sequent - os=dynix + basic_os=dynix ;; t3e) basic_machine=alphaev5-cray - os=unicos + basic_os=unicos ;; t90) basic_machine=t90-cray - os=unicos + basic_os=unicos ;; toad1) basic_machine=pdp10-xkl - os=tops20 + basic_os=tops20 ;; tpf) basic_machine=s390x-ibm - os=tpf + basic_os=tpf ;; udi29k) basic_machine=a29k-amd - os=udi + basic_os=udi ;; ultra3) basic_machine=a29k-nyu - os=sym1 + basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec - os=none + basic_os=none ;; vaxv) basic_machine=vax-dec - os=sysv + basic_os=sysv ;; vms) basic_machine=vax-dec - os=vms + basic_os=vms ;; vsta) basic_machine=i386-pc - os=vsta + basic_os=vsta ;; vxworks960) basic_machine=i960-wrs - os=vxworks + basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs - os=vxworks + basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs - os=vxworks + basic_os=vxworks ;; xbox) basic_machine=i686-pc - os=mingw32 + basic_os=mingw32 ;; ymp) basic_machine=ymp-cray - os=unicos + basic_os=unicos ;; *) basic_machine=$1 - os= + basic_os= ;; esac ;; @@ -683,17 +686,17 @@ case $basic_machine in bluegene*) cpu=powerpc vendor=ibm - os=cnk + basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec - os=tops10 + basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec - os=tops20 + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) @@ -703,7 +706,7 @@ case $basic_machine in dpx2*) cpu=m68k vendor=bull - os=sysv3 + basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k @@ -712,7 +715,7 @@ case $basic_machine in elxsi) cpu=elxsi vendor=elxsi - os=${os:-bsd} + basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 @@ -725,7 +728,7 @@ case $basic_machine in h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi - os=hiuxwe2 + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 @@ -766,38 +769,38 @@ case $basic_machine in vendor=hp ;; i*86v32) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv32 + basic_os=sysv32 ;; i*86v4*) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv4 + basic_os=sysv4 ;; i*86v) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=sysv + basic_os=sysv ;; i*86sol2) - cpu=`echo "$1" | sed -e 's/86.*/86/'` + cpu=$(echo "$1" | sed -e 's/86.*/86/') vendor=pc - os=solaris2 + basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray - os=${os:-unicos} + basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi - case $os in + case $basic_os in irix*) ;; *) - os=irix4 + basic_os=irix4 ;; esac ;; @@ -808,26 +811,26 @@ case $basic_machine in *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari - os=mint + basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony - os=newsos + basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next - case $os in + case $basic_os in openstep*) ;; nextstep*) ;; ns2*) - os=nextstep2 + basic_os=nextstep2 ;; *) - os=nextstep3 + basic_os=nextstep3 ;; esac ;; @@ -838,12 +841,12 @@ case $basic_machine in op50n-* | op60c-*) cpu=hppa1.1 vendor=oki - os=proelf + basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi - os=hiuxwe2 + basic_os=hiuxwe2 ;; pbd) cpu=sparc @@ -880,12 +883,12 @@ case $basic_machine in sde) cpu=mipsisa32 vendor=sde - os=${os:-elf} + basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs - os=vxworks + basic_os=vxworks ;; tower | tower-32) cpu=m68k @@ -902,7 +905,7 @@ case $basic_machine in w89k-*) cpu=hppa1.1 vendor=winbond - os=proelf + basic_os=proelf ;; none) cpu=none @@ -914,7 +917,7 @@ case $basic_machine in ;; leon-*|leon[3-9]-*) cpu=sparc - vendor=`echo "$basic_machine" | sed 's/-.*//'` + vendor=$(echo "$basic_machine" | sed 's/-.*//') ;; *-*) @@ -955,11 +958,11 @@ case $cpu-$vendor in # some cases the only manufacturer, in others, it is the most popular. craynv-unknown) vendor=cray - os=${os:-unicosmp} + basic_os=${basic_os:-unicosmp} ;; c90-unknown | c90-cray) vendor=cray - os=${os:-unicos} + basic_os=${Basic_os:-unicos} ;; fx80-unknown) vendor=alliant @@ -1003,7 +1006,7 @@ case $cpu-$vendor in dpx20-unknown | dpx20-bull) cpu=rs6000 vendor=bull - os=${os:-bosx} + basic_os=${basic_os:-bosx} ;; # Here we normalize CPU types irrespective of the vendor @@ -1012,7 +1015,7 @@ case $cpu-$vendor in ;; blackfin-*) cpu=bfin - os=linux + basic_os=linux ;; c54x-*) cpu=tic54x @@ -1025,7 +1028,7 @@ case $cpu-$vendor in ;; e500v[12]-*) cpu=powerpc - os=$os"spe" + basic_os=${basic_os}"spe" ;; mips3*-*) cpu=mips64 @@ -1035,7 +1038,7 @@ case $cpu-$vendor in ;; m68knommu-*) cpu=m68k - os=linux + basic_os=linux ;; m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*) cpu=s12z @@ -1045,7 +1048,7 @@ case $cpu-$vendor in ;; parisc-*) cpu=hppa - os=linux + basic_os=linux ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) cpu=i586 @@ -1081,7 +1084,7 @@ case $cpu-$vendor in cpu=mipsisa64sb1el ;; sh5e[lb]-*) - cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` + cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/') ;; spur-*) cpu=spur @@ -1099,13 +1102,16 @@ case $cpu-$vendor in cpu=x86_64 ;; xscale-* | xscalee[bl]-*) - cpu=`echo "$cpu" | sed 's/^xscale/arm/'` + cpu=$(echo "$cpu" | sed 's/^xscale/arm/') + ;; + arm64-*) + cpu=aarch64 ;; # Recognize the canonical CPU Types that limit and/or modify the # company names they are paired with. cr16-*) - os=${os:-elf} + basic_os=${basic_os:-elf} ;; crisv32-* | etraxfs*-*) cpu=crisv32 @@ -1116,7 +1122,7 @@ case $cpu-$vendor in vendor=axis ;; crx-*) - os=${os:-elf} + basic_os=${basic_os:-elf} ;; neo-tandem) cpu=neo @@ -1138,16 +1144,12 @@ case $cpu-$vendor in cpu=nsx vendor=tandem ;; - s390-*) - cpu=s390 - vendor=ibm - ;; - s390x-*) - cpu=s390x - vendor=ibm + mipsallegrexel-sony) + cpu=mipsallegrexel + vendor=sony ;; tile*-*) - os=${os:-linux-gnu} + basic_os=${basic_os:-linux-gnu} ;; *) @@ -1164,7 +1166,7 @@ case $cpu-$vendor in | am33_2.0 \ | amdgcn \ | arc | arceb \ - | arm | arm[lb]e | arme[lb] | armv* \ + | arm | arm[lb]e | arme[lb] | armv* \ | avr | avr32 \ | asmjs \ | ba \ @@ -1183,6 +1185,7 @@ case $cpu-$vendor in | k1om \ | le32 | le64 \ | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ | m32c | m32r | m32rle \ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ @@ -1227,8 +1230,9 @@ case $cpu-$vendor in | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ | pru \ | pyramid \ - | riscv | riscv32 | riscv64 \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ | score \ | sh | shl \ | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ @@ -1238,6 +1242,7 @@ case $cpu-$vendor in | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ | spu \ | tahoe \ + | thumbv7* \ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ | tron \ | ubicom32 \ @@ -1275,8 +1280,47 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x$os != x ] +if test x$basic_os != x then + +# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|') + ;; + os2-emx) + kernel=os2 + os=$(echo $basic_os | sed -e 's|os2-emx|emx|') + ;; + nto-qnx*) + kernel=nto + os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|') + ;; + *-*) + # shellcheck disable=SC2162 + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1528,6 +1499,7 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. +kernel= case $cpu-$vendor in score-*) os=elf @@ -1539,7 +1511,8 @@ case $cpu-$vendor in os=riscix1.2 ;; arm*-rebel) - os=linux + kernel=linux + os=gnu ;; arm*-semi) os=aout @@ -1705,84 +1678,178 @@ case $cpu-$vendor in os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + musl* | newlib* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) - case $os in - riscix*) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - sunos*) + *-sunos*) vendor=sun ;; - cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - beos*) + *-beos*) vendor=be ;; - hpux*) + *-hpux*) vendor=hp ;; - mpeix*) + *-mpeix*) vendor=hp ;; - hiux*) + *-hiux*) vendor=hitachi ;; - unos*) + *-unos*) vendor=crds ;; - dgux*) + *-dgux*) vendor=dg ;; - luna*) + *-luna*) vendor=omron ;; - genix*) + *-genix*) vendor=ns ;; - clix*) + *-clix*) vendor=intergraph ;; - mvs* | opened*) + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - os400*) + s390-* | s390x-*) vendor=ibm ;; - ptx*) + *-ptx*) vendor=sequent ;; - tpf*) + *-tpf*) vendor=ibm ;; - vxsim* | vxworks* | windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - aux*) + *-aux*) vendor=apple ;; - hms*) + *-hms*) vendor=hitachi ;; - mpw* | macos*) + *-mpw* | *-macos*) vendor=apple ;; - *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - vos*) + *-vos*) vendor=stratus ;; esac ;; esac -echo "$cpu-$vendor-$os" +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: diff --git a/src/test/thread/thread_test.c b/config/thread_test.c similarity index 92% rename from src/test/thread/thread_test.c rename to config/thread_test.c index e1bec01b81ad..784f4fe8ce3c 100644 --- a/src/test/thread/thread_test.c +++ b/config/thread_test.c @@ -1,12 +1,12 @@ /*------------------------------------------------------------------------- * * thread_test.c - * libc thread test program + * libc threading test program * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * src/test/thread/thread_test.c + * config/thread_test.c * * This program tests to see if your standard libc functions use * pthread_setspecific()/pthread_getspecific() to be thread-safe. @@ -20,12 +20,7 @@ *------------------------------------------------------------------------- */ -#if !defined(IN_CONFIGURE) && !defined(WIN32) -#include "postgres.h" - -/* we want to know what the native strerror does, not pg_strerror */ -#undef strerror -#endif +/* We cannot use c.h, as port.h will not exist yet */ #include #include @@ -36,6 +31,7 @@ #include #include #include +#include /* CYGWIN requires this for MAXHOSTNAMELEN */ #ifdef __CYGWIN__ @@ -47,25 +43,11 @@ #include #endif - /* Test for POSIX.1c 2-arg sigwait() and fail on single-arg version */ #include int sigwait(const sigset_t *set, int *sig); -#if !defined(ENABLE_THREAD_SAFETY) && !defined(IN_CONFIGURE) && !defined(WIN32) -int -main(int argc, char *argv[]) -{ - fprintf(stderr, "This PostgreSQL build does not support threads.\n"); - fprintf(stderr, "Perhaps rerun 'configure' using '--enable-thread-safety'.\n"); - return 1; -} -#else - -/* This must be down here because this is the code that uses threads. */ -#include - #define TEMP_FILENAME_1 "thread_test.1" #define TEMP_FILENAME_2 "thread_test.2" @@ -119,14 +101,12 @@ main(int argc, char *argv[]) return 1; } -#ifdef IN_CONFIGURE /* Send stdout to 'config.log' */ close(1); dup(5); -#endif #ifdef WIN32 - err = WSAStartup(MAKEWORD(1, 1), &wsaData); + err = WSAStartup(MAKEWORD(2, 2), &wsaData); if (err != 0) { fprintf(stderr, "Cannot start the network subsystem - %d**\nexiting\n", err); @@ -455,5 +435,3 @@ func_call_2(void) pthread_mutex_lock(&init_mutex); /* wait for parent to test */ pthread_mutex_unlock(&init_mutex); } - -#endif /* !ENABLE_THREAD_SAFETY && !IN_CONFIGURE */ diff --git a/configure b/configure index 7f538ec7421d..6a8f19058e7b 100755 --- a/configure +++ b/configure @@ -652,6 +652,8 @@ MSGFMT enable_largefile PG_CRC32C_OBJS CFLAGS_ARMV8_CRC32C +CFLAGS_VECTORIZE +CFLAGS_UNROLL_LOOPS CFLAGS_SSE42 have_win32_dbghelp LIBOBJS @@ -734,6 +736,7 @@ with_uuid with_readline with_systemd with_selinux +with_ssl with_openssl with_ldap with_krb_srvnam @@ -5437,6 +5440,14 @@ if test "$ac_env_CFLAGS_VECTOR_set" = set; then CFLAGS_VECTOR=$ac_env_CFLAGS_VECTOR_value fi +# set CFLAGS_UNROLL_LOOPS and CFLAGS_VECTORIZE from the environment, if present +if test "$ac_env_CFLAGS_UNROLL_LOOPS_set" = set; then + CFLAGS_UNROLL_LOOPS=$ac_env_CFLAGS_UNROLL_LOOPS_value +fi +if test "$ac_env_CFLAGS_VECTORIZE_set" = set; then + CFLAGS_VECTORIZE=$ac_env_CFLAGS_VECTORIZE_value +fi + # Some versions of GCC support some additional useful warning flags. # Check whether they are supported, and add them to CFLAGS if so. # ICC pretends to be GCC but it's lying; it doesn't support these flags, @@ -6445,6 +6456,14 @@ if test x"$pgac_cv_prog_CC_cflags__ftree_vectorize" = x"yes"; then CFLAGS_VECTOR="${CFLAGS_VECTOR} -ftree-vectorize" fi + # Set CFLAGS_UNROLL_LOOPS and CFLAGS_VECTORIZE for PG14 compatibility + if test x"$pgac_cv_prog_CC_cflags__funroll_loops" = x"yes"; then + CFLAGS_UNROLL_LOOPS="-funroll-loops" + fi + if test x"$pgac_cv_prog_CC_cflags__ftree_vectorize" = x"yes"; then + CFLAGS_VECTORIZE="-ftree-vectorize" + fi + # We want to suppress clang's unhelpful unused-command-line-argument warnings # but gcc won't complain about unrecognized -Wno-foo switches, so we have to @@ -13877,6 +13896,7 @@ fi fi if test "$with_openssl" = yes ; then + with_ssl=openssl # Minimum required OpenSSL version is 1.0.1 $as_echo "#define OPENSSL_API_COMPAT 0x10001000L" >>confdefs.h @@ -14111,7 +14131,7 @@ done # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it # doesn't have these OpenSSL 1.1.0 functions. So check for individual # functions. - for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data + for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -20217,7 +20237,7 @@ fi -if test $ac_cv_func_fseeko = yes; then +if test "$ac_cv_func_fseeko" = yes; then # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; @@ -21549,7 +21569,7 @@ $as_echo "$as_me: WARNING: else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include "$srcdir/src/test/thread/thread_test.c" +#include "$srcdir/config/thread_test.c" _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 diff --git a/configure.ac b/configure.ac index c545328648ac..8ca92e4881a1 100644 --- a/configure.ac +++ b/configure.ac @@ -21,14 +21,14 @@ dnl The PACKAGE_VERSION from upstream PostgreSQL is maintained in the dnl PG_PACKAGE_VERSION variable, when merging make sure to update this dnl variable with the merge conflict from the AC_INIT() statement. AC_INIT([Greenplum Database], [8.0.0-alpha.0], [support@greenplum.org], [], [https://greengagedb.org/]) -[PG_PACKAGE_VERSION=14alpha0] +[PG_PACKAGE_VERSION=14beta2] AC_SUBST(PG_PACKAGE_VERSION) -dnl m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required. -dnl Untested combinations of 'autoconf' and PostgreSQL versions are not -dnl recommended. You can remove the check from 'configure.ac' but it is then -dnl your responsibility whether the result works or not.])]) -AC_COPYRIGHT([Copyright (c) 1996-2020, PostgreSQL Global Development Group]) +m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required. +Untested combinations of 'autoconf' and PostgreSQL versions are not +recommended. You can remove the check from 'configure.ac' but it is then +your responsibility whether the result works or not.])]) +AC_COPYRIGHT([Copyright (c) 1996-2021, PostgreSQL Global Development Group]) AC_CONFIG_SRCDIR([src/backend/access/common/heaptuple.c]) AC_CONFIG_AUX_DIR(config) AC_PREFIX_DEFAULT(/usr/local/gpdb) @@ -508,9 +508,12 @@ BITCODE_CFLAGS="" user_BITCODE_CXXFLAGS=$BITCODE_CXXFLAGS BITCODE_CXXFLAGS="" -# set CFLAGS_VECTOR from the environment, if available -if test "$ac_env_CFLAGS_VECTOR_set" = set; then - CFLAGS_VECTOR=$ac_env_CFLAGS_VECTOR_value +# set CFLAGS_UNROLL_LOOPS and CFLAGS_VECTORIZE from the environment, if present +if test "$ac_env_CFLAGS_UNROLL_LOOPS_set" = set; then + CFLAGS_UNROLL_LOOPS=$ac_env_CFLAGS_UNROLL_LOOPS_value +fi +if test "$ac_env_CFLAGS_VECTORIZE_set" = set; then + CFLAGS_VECTORIZE=$ac_env_CFLAGS_VECTORIZE_value fi # Some versions of GCC support some additional useful warning flags. @@ -568,9 +571,10 @@ if test "$GCC" = yes -a "$ICC" = no; then # implicit-fallthrough level 3 (GCC's default). PGAC_PROG_CC_CFLAGS_OPT([-Werror=implicit-fallthrough=3]) PGAC_PROG_CXX_CFLAGS_OPT([-fexcess-precision=standard]) + # Optimization flags for specific files that benefit from loop unrolling + PGAC_PROG_CC_VAR_OPT(CFLAGS_UNROLL_LOOPS, [-funroll-loops]) # Optimization flags for specific files that benefit from vectorization - PGAC_PROG_CC_VAR_OPT(CFLAGS_VECTOR, [-funroll-loops]) - PGAC_PROG_CC_VAR_OPT(CFLAGS_VECTOR, [-ftree-vectorize]) + PGAC_PROG_CC_VAR_OPT(CFLAGS_VECTORIZE, [-ftree-vectorize]) # We want to suppress clang's unhelpful unused-command-line-argument warnings # but gcc won't complain about unrecognized -Wno-foo switches, so we have to # test for the positive form and if that works, add the negative form @@ -623,7 +627,8 @@ elif test "$PORTNAME" = "hpux"; then PGAC_PROG_CXX_CFLAGS_OPT([+Olibmerrno]) fi -AC_SUBST(CFLAGS_VECTOR) +AC_SUBST(CFLAGS_UNROLL_LOOPS) +AC_SUBST(CFLAGS_VECTORIZE) # Determine flags used to emit bitcode for JIT inlining. Need to test # for behaviour changing compiler flags, to keep compatibility with @@ -977,15 +982,6 @@ PGAC_ARG_BOOL(with, bonjour, no, AC_MSG_RESULT([$with_bonjour]) -# -# OpenSSL -# -AC_MSG_CHECKING([whether to build with OpenSSL support]) -PGAC_ARG_BOOL(with, openssl, no, [build with OpenSSL support], - [AC_DEFINE([USE_OPENSSL], 1, [Define to build with OpenSSL support. (--with-openssl)])]) -AC_MSG_RESULT([$with_openssl]) -AC_SUBST(with_openssl) - # # SELinux # @@ -1044,22 +1040,18 @@ if test "$with_ossp_uuid" = yes ; then with_uuid=ossp fi -if test "$with_uuid" = bsd ; then - AC_DEFINE([HAVE_UUID_BSD], 1, [Define to 1 if you have BSD UUID support.]) - UUID_EXTRA_OBJS="md5.o sha1.o" -elif test "$with_uuid" = e2fs ; then - AC_DEFINE([HAVE_UUID_E2FS], 1, [Define to 1 if you have E2FS UUID support.]) - UUID_EXTRA_OBJS="md5.o sha1.o" -elif test "$with_uuid" = ossp ; then - AC_DEFINE([HAVE_UUID_OSSP], 1, [Define to 1 if you have OSSP UUID support.]) - UUID_EXTRA_OBJS="" -elif test "$with_uuid" = no ; then - UUID_EXTRA_OBJS="" -else - AC_MSG_ERROR([--with-uuid must specify one of bsd, e2fs, or ossp]) +if test "$with_uuid" != no ; then + if test "$with_uuid" = bsd ; then + AC_DEFINE([HAVE_UUID_BSD], 1, [Define to 1 if you have BSD UUID support.]) + elif test "$with_uuid" = e2fs ; then + AC_DEFINE([HAVE_UUID_E2FS], 1, [Define to 1 if you have E2FS UUID support.]) + elif test "$with_uuid" = ossp ; then + AC_DEFINE([HAVE_UUID_OSSP], 1, [Define to 1 if you have OSSP UUID support.]) + else + AC_MSG_ERROR([--with-uuid must specify one of bsd, e2fs, or ossp]) + fi fi AC_SUBST(with_uuid) -AC_SUBST(UUID_EXTRA_OBJS) # @@ -1124,6 +1116,31 @@ PGAC_ARG_BOOL(with, zlib, yes, [do not use Zlib]) AC_SUBST(with_zlib) +# +# LZ4 +# +AC_MSG_CHECKING([whether to build with LZ4 support]) +PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], + [AC_DEFINE([USE_LZ4], 1, [Define to 1 to build with LZ4 support. (--with-lz4)])]) +AC_MSG_RESULT([$with_lz4]) +AC_SUBST(with_lz4) + +if test "$with_lz4" = yes; then + PKG_CHECK_MODULES(LZ4, liblz4) + # We only care about -I, -D, and -L switches; + # note that -llz4 will be added by AC_CHECK_LIB below. + for pgac_option in $LZ4_CFLAGS; do + case $pgac_option in + -I*|-D*) CPPFLAGS="$CPPFLAGS $pgac_option";; + esac + done + for pgac_option in $LZ4_LIBS; do + case $pgac_option in + -L*) LDFLAGS="$LDFLAGS $pgac_option";; + esac + done +fi + # # bzip2 # @@ -1353,6 +1370,10 @@ AC_SEARCH_LIBS(shmget, cygipc) # *BSD: AC_SEARCH_LIBS(backtrace_symbols, execinfo) +if test "$enable_thread_safety" = yes; then + AC_SEARCH_LIBS(pthread_barrier_wait, pthread) +fi + if test "$with_readline" = yes; then PGAC_CHECK_READLINE if test x"$pgac_cv_check_readline" = x"no"; then @@ -1437,7 +1458,21 @@ if test "$enable_mapreduce" = yes ; then LIBS="$_LIBS" fi +# +# SSL Library +# +# There is currently only one supported SSL/TLS library: OpenSSL. +# +PGAC_ARG_REQ(with, ssl, [LIB], [use LIB for SSL/TLS support (openssl)]) +if test x"$with_ssl" = x"" ; then + with_ssl=no +fi +PGAC_ARG_BOOL(with, openssl, no, [obsolete spelling of --with-ssl=openssl]) if test "$with_openssl" = yes ; then + with_ssl=openssl +fi + +if test "$with_ssl" = openssl ; then dnl Order matters! # Minimum required OpenSSL version is 1.0.1 AC_DEFINE(OPENSSL_API_COMPAT, [0x10001000L], @@ -1456,12 +1491,16 @@ if test "$with_openssl" = yes ; then # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it # doesn't have these OpenSSL 1.1.0 functions. So check for individual # functions. - AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data]) + AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data HMAC_CTX_new HMAC_CTX_free]) # OpenSSL versions before 1.1.0 required setting callback functions, for # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock() # function was removed. AC_CHECK_FUNCS([CRYPTO_lock]) + AC_DEFINE([USE_OPENSSL], 1, [Define to 1 to build with OpenSSL support. (--with-ssl=openssl)]) +elif test "$with_ssl" != no ; then + AC_MSG_ERROR([--with-ssl must specify openssl]) fi +AC_SUBST(with_ssl) if test "$with_rt" = yes ; then AC_CHECK_LIB(rt, clock_gettime, [], @@ -1494,6 +1533,10 @@ if test "$with_libxslt" = yes ; then AC_CHECK_LIB(xslt, xsltCleanupGlobals, [], [AC_MSG_ERROR([library 'xslt' is required for XSLT support])]) fi +if test "$with_lz4" = yes ; then + AC_CHECK_LIB(lz4, LZ4_compress_default, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) +fi + # Note: We can test for libldap_r only after we know PTHREAD_LIBS if test "$with_ldap" = yes ; then _LIBS="$LIBS" @@ -1587,6 +1630,7 @@ AC_CHECK_HEADERS(m4_normalize([ sys/shm.h sys/sockio.h sys/tas.h + sys/uio.h sys/un.h termios.h ucred.h @@ -1673,6 +1717,10 @@ failure. It is possible the compiler isn't looking in the proper directory. Use --without-zlib to disable zlib support.])]) fi +if test "$with_lz4" = yes; then + AC_CHECK_HEADERS(lz4.h, [], [AC_MSG_ERROR([lz4.h header file is required for LZ4])]) +fi + # Check for bzlib.h if test "$with_libbz2" = yes ; then AC_CHECK_HEADER(bzlib.h, [], [AC_MSG_ERROR([header file is required for bzip2 support])], []) @@ -1688,7 +1736,7 @@ if test "$with_gssapi" = yes ; then [AC_CHECK_HEADERS(gssapi.h, [], [AC_MSG_ERROR([gssapi.h header file is required for GSSAPI])])]) fi -if test "$with_openssl" = yes ; then +if test "$with_ssl" = openssl ; then AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([header file is required for OpenSSL])]) AC_CHECK_HEADER(openssl/err.h, [], [AC_MSG_ERROR([header file is required for OpenSSL])]) fi @@ -2011,6 +2059,7 @@ AC_CHECK_FUNCS(m4_normalize([ pstat pthread_is_threaded_np readlink + readv setproctitle setproctitle_fast setsid @@ -2018,9 +2067,11 @@ AC_CHECK_FUNCS(m4_normalize([ strchrnul strsignal symlink + syncfs sync_file_range uselocale wcstombs_l + writev ])) # For upstream Postgres, the getifaddrs() symbol is optional, but the GPDB @@ -2093,7 +2144,9 @@ AC_REPLACE_FUNCS(m4_normalize([ link mkdtemp pread + preadv pwrite + pwritev random srandom strlcat @@ -2102,6 +2155,10 @@ AC_REPLACE_FUNCS(m4_normalize([ strtof ])) +if test "$enable_thread_safety" = yes; then + AC_REPLACE_FUNCS(pthread_barrier_wait) +fi + if test "$PORTNAME" = "win32" -o "$PORTNAME" = "cygwin"; then # Cygwin and (apparently, based on test results) Mingw both # have a broken strtof(), so substitute the same replacement @@ -2116,11 +2173,13 @@ fi case $host_os in # Windows uses a specialised env handler mingw*) + AC_DEFINE(HAVE_SETENV, 1, [Define to 1 because replacement version used.]) AC_DEFINE(HAVE_UNSETENV, 1, [Define to 1 because replacement version used.]) + ac_cv_func_setenv=yes ac_cv_func_unsetenv=yes ;; *) - AC_REPLACE_FUNCS([unsetenv]) + AC_REPLACE_FUNCS([setenv unsetenv]) ;; esac @@ -2166,6 +2225,7 @@ if test "$PORTNAME" = "win32"; then AC_LIBOBJ(win32error) AC_LIBOBJ(win32security) AC_LIBOBJ(win32setlocale) + AC_LIBOBJ(win32stat) AC_DEFINE([HAVE_SYMLINK], 1, [Define to 1 if you have the `symlink' function.]) AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [ @@ -2539,40 +2599,23 @@ else SHMEM_IMPLEMENTATION="src/backend/port/win32_shmem.c" fi -# Select random number source -# -# You can override this logic by setting the appropriate USE_*RANDOM flag to 1 -# in the template or configure command line. - -# If not selected manually, try to select a source automatically. -if test x"$USE_OPENSSL_RANDOM" = x"" && test x"$USE_WIN32_RANDOM" = x"" && test x"$USE_DEV_URANDOM" = x"" ; then - if test x"$with_openssl" = x"yes" ; then - USE_OPENSSL_RANDOM=1 - elif test "$PORTNAME" = "win32" ; then - USE_WIN32_RANDOM=1 - else - AC_CHECK_FILE([/dev/urandom], [], []) - - if test x"$ac_cv_file__dev_urandom" = x"yes" ; then - USE_DEV_URANDOM=1 - fi - fi -fi - +# Select random number source. If a TLS library is used then it will be the +# first choice, else the native platform sources (Windows API or /dev/urandom) +# will be used. AC_MSG_CHECKING([which random number source to use]) -if test x"$USE_OPENSSL_RANDOM" = x"1" ; then - AC_DEFINE(USE_OPENSSL_RANDOM, 1, [Define to use OpenSSL for random number generation]) +if test x"$with_ssl" = x"openssl" ; then AC_MSG_RESULT([OpenSSL]) -elif test x"$USE_WIN32_RANDOM" = x"1" ; then - AC_DEFINE(USE_WIN32_RANDOM, 1, [Define to use native Windows API for random number generation]) +elif test x"$PORTNAME" = x"win32" ; then AC_MSG_RESULT([Windows native]) -elif test x"$USE_DEV_URANDOM" = x"1" ; then - AC_DEFINE(USE_DEV_URANDOM, 1, [Define to use /dev/urandom for random number generation]) - AC_MSG_RESULT([/dev/urandom]) else - AC_MSG_ERROR([ + AC_MSG_RESULT([/dev/urandom]) + AC_CHECK_FILE([/dev/urandom], [], []) + + if test x"$ac_cv_file__dev_urandom" = x"no" ; then + AC_MSG_ERROR([ no source of strong random numbers was found -PostgreSQL can use OpenSSL or /dev/urandom as a source of random numbers.]) +PostgreSQL can use OpenSSL, native Windows API or /dev/urandom as a source of random numbers.]) + fi fi # If not set in template file, set bytes to use libc memset() @@ -2681,20 +2724,18 @@ AC_MSG_CHECKING([thread safety of required library functions]) _CFLAGS="$CFLAGS" _LIBS="$LIBS" -CFLAGS="$CFLAGS $PTHREAD_CFLAGS -DIN_CONFIGURE" +CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$LIBS $PTHREAD_LIBS" AC_RUN_IFELSE( - [AC_LANG_SOURCE([[#include "$srcdir/src/test/thread/thread_test.c"]])], + [AC_LANG_SOURCE([[#include "$srcdir/config/thread_test.c"]])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) AC_MSG_ERROR([thread test program failed -This platform is not thread-safe. Check the file 'config.log' or compile -and run src/test/thread/thread_test for the exact reason. -Use --disable-thread-safety to disable thread safety.])], +This platform is not thread-safe. Check the file 'config.log' for the +exact reason, or use --disable-thread-safety to disable thread safety.])], [AC_MSG_RESULT(maybe) AC_MSG_WARN([ *** Skipping thread test program because of cross-compile build. -*** Run the program in src/test/thread on the target machine. ])]) CFLAGS="$_CFLAGS" LIBS="$_LIBS" @@ -2794,8 +2835,10 @@ AC_SUBST(PG_VERSION_NUM) # literally, so that it's possible to override it at build time using # a command like "make ... PG_SYSROOT=path". This has to be done after # we've finished all configure checks that depend on CPPFLAGS. +# The same for LDFLAGS, too. if test x"$PG_SYSROOT" != x; then CPPFLAGS=`echo "$CPPFLAGS" | sed -e "s| $PG_SYSROOT | \\\$(PG_SYSROOT) |"` + LDFLAGS=`echo "$LDFLAGS" | sed -e "s| $PG_SYSROOT | \\\$(PG_SYSROOT) |"` fi AC_SUBST(PG_SYSROOT) diff --git a/contrib/Makefile b/contrib/Makefile index 7780482a4932..35968f945f62 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -59,7 +59,7 @@ SUBDIRS += \ extprotocol \ indexscan -ifeq ($(with_openssl),yes) +ifeq ($(with_ssl),openssl) SUBDIRS += sslinfo else ALWAYS_SUBDIRS += sslinfo diff --git a/contrib/adminpack/Makefile b/contrib/adminpack/Makefile index 630fea7726c7..851504f4aefb 100644 --- a/contrib/adminpack/Makefile +++ b/contrib/adminpack/Makefile @@ -4,7 +4,6 @@ MODULE_big = adminpack OBJS = \ $(WIN32RES) \ adminpack.o -PG_CPPFLAGS = -I$(libpq_srcdir) EXTENSION = adminpack DATA = adminpack--1.0.sql adminpack--1.0--1.1.sql adminpack--1.1--2.0.sql\ diff --git a/contrib/adminpack/adminpack.c b/contrib/adminpack/adminpack.c index d064b5a0806d..48c174691047 100644 --- a/contrib/adminpack/adminpack.c +++ b/contrib/adminpack/adminpack.c @@ -3,7 +3,7 @@ * adminpack.c * * - * Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Copyright (c) 2002-2021, PostgreSQL Global Development Group * * Author: Andreas Pflug * @@ -79,10 +79,13 @@ convert_and_check_filename(text *arg) * files on the server as the PG user, so no need to do any further checks * here. */ - if (is_member_of_role(GetUserId(), DEFAULT_ROLE_WRITE_SERVER_FILES)) + if (is_member_of_role(GetUserId(), ROLE_PG_WRITE_SERVER_FILES)) return filename; - /* User isn't a member of the default role, so check if it's allowable */ + /* + * User isn't a member of the pg_write_server_files role, so check if it's + * allowable + */ if (is_absolute_path(filename)) { /* Disallow '/a/b/data/..' */ diff --git a/contrib/amcheck/Makefile b/contrib/amcheck/Makefile index a2b1b1036b3e..b82f221e50bb 100644 --- a/contrib/amcheck/Makefile +++ b/contrib/amcheck/Makefile @@ -3,13 +3,16 @@ MODULE_big = amcheck OBJS = \ $(WIN32RES) \ + verify_heapam.o \ verify_nbtree.o EXTENSION = amcheck -DATA = amcheck--1.1--1.2.sql amcheck--1.0--1.1.sql amcheck--1.0.sql +DATA = amcheck--1.2--1.3.sql amcheck--1.1--1.2.sql amcheck--1.0--1.1.sql amcheck--1.0.sql PGFILEDESC = "amcheck - function for verifying relation integrity" -REGRESS = check check_btree +REGRESS = check check_btree check_heap + +TAP_TESTS = 1 ifdef USE_PGXS PG_CONFIG = pg_config diff --git a/contrib/amcheck/amcheck--1.2--1.3.sql b/contrib/amcheck/amcheck--1.2--1.3.sql new file mode 100644 index 000000000000..7237ab738ce7 --- /dev/null +++ b/contrib/amcheck/amcheck--1.2--1.3.sql @@ -0,0 +1,30 @@ +/* contrib/amcheck/amcheck--1.2--1.3.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "ALTER EXTENSION amcheck UPDATE TO '1.3'" to load this file. \quit + +-- +-- verify_heapam() +-- +CREATE FUNCTION verify_heapam(relation regclass, + on_error_stop boolean default false, + check_toast boolean default false, + skip text default 'none', + startblock bigint default null, + endblock bigint default null, + blkno OUT bigint, + offnum OUT integer, + attnum OUT integer, + msg OUT text) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'verify_heapam' +LANGUAGE C; + +-- Don't want this to be available to public +REVOKE ALL ON FUNCTION verify_heapam(regclass, + boolean, + boolean, + text, + bigint, + bigint) +FROM PUBLIC; diff --git a/contrib/amcheck/amcheck.control b/contrib/amcheck/amcheck.control index c6e310046d4e..ab50931f754a 100644 --- a/contrib/amcheck/amcheck.control +++ b/contrib/amcheck/amcheck.control @@ -1,5 +1,5 @@ # amcheck extension comment = 'functions for verifying relation integrity' -default_version = '1.2' +default_version = '1.3' module_pathname = '$libdir/amcheck' relocatable = true diff --git a/contrib/amcheck/expected/check_btree.out b/contrib/amcheck/expected/check_btree.out index 13848b7449b7..5a3f1ef737cf 100644 --- a/contrib/amcheck/expected/check_btree.out +++ b/contrib/amcheck/expected/check_btree.out @@ -97,8 +97,8 @@ SELECT bt_index_parent_check('bttest_b_idx'); SELECT * FROM pg_locks WHERE relation = ANY(ARRAY['bttest_a', 'bttest_a_idx', 'bttest_b', 'bttest_b_idx']::regclass[]) AND pid = pg_backend_pid(); - locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | granted | fastpath -----------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+-----+------+---------+---------- + locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | granted | fastpath | waitstart +----------+----------+----------+------+-------+------------+---------------+---------+-------+----------+--------------------+-----+------+---------+----------+----------- (0 rows) COMMIT; diff --git a/contrib/amcheck/expected/check_heap.out b/contrib/amcheck/expected/check_heap.out new file mode 100644 index 000000000000..1fb382314290 --- /dev/null +++ b/contrib/amcheck/expected/check_heap.out @@ -0,0 +1,194 @@ +CREATE TABLE heaptest (a integer, b text); +REVOKE ALL ON heaptest FROM PUBLIC; +-- Check that invalid skip option is rejected +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'rope'); +ERROR: invalid skip option +HINT: Valid skip options are "all-visible", "all-frozen", and "none". +-- Check specifying invalid block ranges when verifying an empty table +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 5, endblock := 8); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +-- Check that valid options are not rejected nor corruption reported +-- for an empty table, and that skip enum-like parameter is case-insensitive +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'None'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'All-Frozen'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'All-Visible'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'NONE'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'ALL-FROZEN'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'ALL-VISIBLE'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +-- Add some data so subsequent tests are not entirely trivial +INSERT INTO heaptest (a, b) + (SELECT gs, repeat('x', gs) + FROM generate_series(1,50) gs); +-- Check that valid options are not rejected nor corruption reported +-- for a non-empty table +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +CREATE ROLE regress_heaptest_role; +-- verify permissions are checked (error due to function not callable) +SET ROLE regress_heaptest_role; +SELECT * FROM verify_heapam(relation := 'heaptest'); +ERROR: permission denied for function verify_heapam +RESET ROLE; +GRANT EXECUTE ON FUNCTION verify_heapam(regclass, boolean, boolean, text, bigint, bigint) TO regress_heaptest_role; +-- verify permissions are now sufficient +SET ROLE regress_heaptest_role; +SELECT * FROM verify_heapam(relation := 'heaptest'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +RESET ROLE; +-- Check specifying invalid block ranges when verifying a non-empty table. +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 10000); +ERROR: ending block number must be between 0 and 0 +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 10000, endblock := 11000); +ERROR: starting block number must be between 0 and 0 +-- Vacuum freeze to change the xids encountered in subsequent tests +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) heaptest; +-- Check that valid options are not rejected nor corruption reported +-- for a non-empty frozen table +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible'); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +-- Check that partitioned tables (the parent ones) which don't have visibility +-- maps are rejected +CREATE TABLE test_partitioned (a int, b text default repeat('x', 5000)) + PARTITION BY list (a); +SELECT * FROM verify_heapam('test_partitioned', + startblock := NULL, + endblock := NULL); +ERROR: "test_partitioned" is not a table, materialized view, or TOAST table +-- Check that valid options are not rejected nor corruption reported +-- for an empty partition table (the child one) +CREATE TABLE test_partition partition OF test_partitioned FOR VALUES IN (1); +SELECT * FROM verify_heapam('test_partition', + startblock := NULL, + endblock := NULL); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +-- Check that valid options are not rejected nor corruption reported +-- for a non-empty partition table (the child one) +INSERT INTO test_partitioned (a) (SELECT 1 FROM generate_series(1,1000) gs); +SELECT * FROM verify_heapam('test_partition', + startblock := NULL, + endblock := NULL); + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + +-- Check that indexes are rejected +CREATE INDEX test_index ON test_partition (a); +SELECT * FROM verify_heapam('test_index', + startblock := NULL, + endblock := NULL); +ERROR: "test_index" is not a table, materialized view, or TOAST table +-- Check that views are rejected +CREATE VIEW test_view AS SELECT 1; +SELECT * FROM verify_heapam('test_view', + startblock := NULL, + endblock := NULL); +ERROR: "test_view" is not a table, materialized view, or TOAST table +-- Check that sequences are rejected +CREATE SEQUENCE test_sequence; +SELECT * FROM verify_heapam('test_sequence', + startblock := NULL, + endblock := NULL); +ERROR: "test_sequence" is not a table, materialized view, or TOAST table +-- Check that foreign tables are rejected +CREATE FOREIGN DATA WRAPPER dummy; +CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy; +CREATE FOREIGN TABLE test_foreign_table () SERVER dummy_server; +SELECT * FROM verify_heapam('test_foreign_table', + startblock := NULL, + endblock := NULL); +ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table +-- cleanup +DROP TABLE heaptest; +DROP TABLE test_partition; +DROP TABLE test_partitioned; +DROP OWNED BY regress_heaptest_role; -- permissions +DROP ROLE regress_heaptest_role; diff --git a/contrib/amcheck/sql/check_heap.sql b/contrib/amcheck/sql/check_heap.sql new file mode 100644 index 000000000000..298de6886afd --- /dev/null +++ b/contrib/amcheck/sql/check_heap.sql @@ -0,0 +1,116 @@ +CREATE TABLE heaptest (a integer, b text); +REVOKE ALL ON heaptest FROM PUBLIC; + +-- Check that invalid skip option is rejected +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'rope'); + +-- Check specifying invalid block ranges when verifying an empty table +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0); +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 5, endblock := 8); + +-- Check that valid options are not rejected nor corruption reported +-- for an empty table, and that skip enum-like parameter is case-insensitive +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'None'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'All-Frozen'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'All-Visible'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'NONE'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'ALL-FROZEN'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'ALL-VISIBLE'); + +-- Add some data so subsequent tests are not entirely trivial +INSERT INTO heaptest (a, b) + (SELECT gs, repeat('x', gs) + FROM generate_series(1,50) gs); + +-- Check that valid options are not rejected nor corruption reported +-- for a non-empty table +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible'); +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0); + +CREATE ROLE regress_heaptest_role; + +-- verify permissions are checked (error due to function not callable) +SET ROLE regress_heaptest_role; +SELECT * FROM verify_heapam(relation := 'heaptest'); +RESET ROLE; + +GRANT EXECUTE ON FUNCTION verify_heapam(regclass, boolean, boolean, text, bigint, bigint) TO regress_heaptest_role; + +-- verify permissions are now sufficient +SET ROLE regress_heaptest_role; +SELECT * FROM verify_heapam(relation := 'heaptest'); +RESET ROLE; + +-- Check specifying invalid block ranges when verifying a non-empty table. +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 10000); +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 10000, endblock := 11000); + +-- Vacuum freeze to change the xids encountered in subsequent tests +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) heaptest; + +-- Check that valid options are not rejected nor corruption reported +-- for a non-empty frozen table +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'none'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-frozen'); +SELECT * FROM verify_heapam(relation := 'heaptest', skip := 'all-visible'); +SELECT * FROM verify_heapam(relation := 'heaptest', startblock := 0, endblock := 0); + +-- Check that partitioned tables (the parent ones) which don't have visibility +-- maps are rejected +CREATE TABLE test_partitioned (a int, b text default repeat('x', 5000)) + PARTITION BY list (a); +SELECT * FROM verify_heapam('test_partitioned', + startblock := NULL, + endblock := NULL); + +-- Check that valid options are not rejected nor corruption reported +-- for an empty partition table (the child one) +CREATE TABLE test_partition partition OF test_partitioned FOR VALUES IN (1); +SELECT * FROM verify_heapam('test_partition', + startblock := NULL, + endblock := NULL); + +-- Check that valid options are not rejected nor corruption reported +-- for a non-empty partition table (the child one) +INSERT INTO test_partitioned (a) (SELECT 1 FROM generate_series(1,1000) gs); +SELECT * FROM verify_heapam('test_partition', + startblock := NULL, + endblock := NULL); + +-- Check that indexes are rejected +CREATE INDEX test_index ON test_partition (a); +SELECT * FROM verify_heapam('test_index', + startblock := NULL, + endblock := NULL); + +-- Check that views are rejected +CREATE VIEW test_view AS SELECT 1; +SELECT * FROM verify_heapam('test_view', + startblock := NULL, + endblock := NULL); + +-- Check that sequences are rejected +CREATE SEQUENCE test_sequence; +SELECT * FROM verify_heapam('test_sequence', + startblock := NULL, + endblock := NULL); + +-- Check that foreign tables are rejected +CREATE FOREIGN DATA WRAPPER dummy; +CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy; +CREATE FOREIGN TABLE test_foreign_table () SERVER dummy_server; +SELECT * FROM verify_heapam('test_foreign_table', + startblock := NULL, + endblock := NULL); + +-- cleanup +DROP TABLE heaptest; +DROP TABLE test_partition; +DROP TABLE test_partitioned; +DROP OWNED BY regress_heaptest_role; -- permissions +DROP ROLE regress_heaptest_role; diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl new file mode 100644 index 000000000000..9bd66c07f46f --- /dev/null +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -0,0 +1,211 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgresNode; +use TestLib; + +use Fcntl qw(:seek); +use Test::More tests => 80; + +my ($node, $result); + +# +# Test set-up +# +$node = get_new_node('test'); +$node->init; +$node->append_conf('postgresql.conf', 'autovacuum=off'); +$node->start; +$node->safe_psql('postgres', q(CREATE EXTENSION amcheck)); + +# +# Check a table with data loaded but no corruption, freezing, etc. +# +fresh_test_table('test'); +check_all_options_uncorrupted('test', 'plain'); + +# +# Check a corrupt table +# +fresh_test_table('test'); +corrupt_first_page('test'); +detects_heap_corruption("verify_heapam('test')", "plain corrupted table"); +detects_heap_corruption( + "verify_heapam('test', skip := 'all-visible')", + "plain corrupted table skipping all-visible"); +detects_heap_corruption( + "verify_heapam('test', skip := 'all-frozen')", + "plain corrupted table skipping all-frozen"); +detects_heap_corruption( + "verify_heapam('test', check_toast := false)", + "plain corrupted table skipping toast"); +detects_heap_corruption( + "verify_heapam('test', startblock := 0, endblock := 0)", + "plain corrupted table checking only block zero"); + +# +# Check a corrupt table with all-frozen data +# +fresh_test_table('test'); +$node->safe_psql('postgres', q(VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test)); +detects_no_corruption("verify_heapam('test')", + "all-frozen not corrupted table"); +corrupt_first_page('test'); +detects_heap_corruption("verify_heapam('test')", + "all-frozen corrupted table"); +detects_no_corruption( + "verify_heapam('test', skip := 'all-frozen')", + "all-frozen corrupted table skipping all-frozen"); + +# Returns the filesystem path for the named relation. +sub relation_filepath +{ + my ($relname) = @_; + + my $pgdata = $node->data_dir; + my $rel = $node->safe_psql('postgres', + qq(SELECT pg_relation_filepath('$relname'))); + die "path not found for relation $relname" unless defined $rel; + return "$pgdata/$rel"; +} + +# Returns the fully qualified name of the toast table for the named relation +sub get_toast_for +{ + my ($relname) = @_; + + return $node->safe_psql( + 'postgres', qq( + SELECT 'pg_toast.' || t.relname + FROM pg_catalog.pg_class c, pg_catalog.pg_class t + WHERE c.relname = '$relname' + AND c.reltoastrelid = t.oid)); +} + +# (Re)create and populate a test table of the given name. +sub fresh_test_table +{ + my ($relname) = @_; + + return $node->safe_psql( + 'postgres', qq( + DROP TABLE IF EXISTS $relname CASCADE; + CREATE TABLE $relname (a integer, b text); + ALTER TABLE $relname SET (autovacuum_enabled=false); + ALTER TABLE $relname ALTER b SET STORAGE external; + INSERT INTO $relname (a, b) + (SELECT gs, repeat('b',gs*10) FROM generate_series(1,1000) gs); + BEGIN; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + RELEASE s1; + SAVEPOINT s1; + SELECT 1 FROM $relname WHERE a = 42 FOR UPDATE; + UPDATE $relname SET b = b WHERE a = 42; + COMMIT; + )); +} + +# Stops the test node, corrupts the first page of the named relation, and +# restarts the node. +sub corrupt_first_page +{ + my ($relname) = @_; + my $relpath = relation_filepath($relname); + + $node->stop; + + my $fh; + open($fh, '+<', $relpath) + or BAIL_OUT("open failed: $!"); + binmode $fh; + + # Corrupt some line pointers. The values are chosen to hit the + # various line-pointer-corruption checks in verify_heapam.c + # on both little-endian and big-endian architectures. + seek($fh, 32, SEEK_SET) + or BAIL_OUT("seek failed: $!"); + syswrite( + $fh, + pack("L*", + 0xAAA15550, 0xAAA0D550, 0x00010000, + 0x00008000, 0x0000800F, 0x001e8000) + ) or BAIL_OUT("syswrite failed: $!"); + close($fh) + or BAIL_OUT("close failed: $!"); + + $node->start; +} + +sub detects_heap_corruption +{ + my ($function, $testname) = @_; + + detects_corruption( + $function, + $testname, + qr/line pointer redirection to item at offset \d+ precedes minimum offset \d+/, + qr/line pointer redirection to item at offset \d+ exceeds maximum offset \d+/, + qr/line pointer to page offset \d+ is not maximally aligned/, + qr/line pointer length \d+ is less than the minimum tuple header size \d+/, + qr/line pointer to page offset \d+ with length \d+ ends beyond maximum page offset \d+/, + ); +} + +sub detects_corruption +{ + my ($function, $testname, @re) = @_; + + my $result = $node->safe_psql('postgres', qq(SELECT * FROM $function)); + like($result, $_, $testname) for (@re); +} + +sub detects_no_corruption +{ + my ($function, $testname) = @_; + + my $result = $node->safe_psql('postgres', qq(SELECT * FROM $function)); + is($result, '', $testname); +} + +# Check various options are stable (don't abort) and do not report corruption +# when running verify_heapam on an uncorrupted test table. +# +# The relname *must* be an uncorrupted table, or this will fail. +# +# The prefix is used to identify the test, along with the options, +# and should be unique. +sub check_all_options_uncorrupted +{ + my ($relname, $prefix) = @_; + + for my $stop (qw(true false)) + { + for my $check_toast (qw(true false)) + { + for my $skip ("'none'", "'all-frozen'", "'all-visible'") + { + for my $startblock (qw(NULL 0)) + { + for my $endblock (qw(NULL 0)) + { + my $opts = + "on_error_stop := $stop, " + . "check_toast := $check_toast, " + . "skip := $skip, " + . "startblock := $startblock, " + . "endblock := $endblock"; + + detects_no_corruption( + "verify_heapam('$relname', $opts)", + "$prefix: $opts"); + } + } + } + } + } +} diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c new file mode 100644 index 000000000000..a3caee7cdd38 --- /dev/null +++ b/contrib/amcheck/verify_heapam.c @@ -0,0 +1,1734 @@ +/*------------------------------------------------------------------------- + * + * verify_heapam.c + * Functions to check postgresql heap relations for corruption + * + * Copyright (c) 2016-2021, PostgreSQL Global Development Group + * + * contrib/amcheck/verify_heapam.c + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/detoast.h" +#include "access/genam.h" +#include "access/heapam.h" +#include "access/heaptoast.h" +#include "access/multixact.h" +#include "access/toast_internals.h" +#include "access/visibilitymap.h" +#include "catalog/pg_am.h" +#include "funcapi.h" +#include "miscadmin.h" +#include "storage/bufmgr.h" +#include "storage/procarray.h" +#include "utils/builtins.h" +#include "utils/fmgroids.h" + +PG_FUNCTION_INFO_V1(verify_heapam); + +/* The number of columns in tuples returned by verify_heapam */ +#define HEAPCHECK_RELATION_COLS 4 + +/* + * Despite the name, we use this for reporting problems with both XIDs and + * MXIDs. + */ +typedef enum XidBoundsViolation +{ + XID_INVALID, + XID_IN_FUTURE, + XID_PRECEDES_CLUSTERMIN, + XID_PRECEDES_RELMIN, + XID_BOUNDS_OK +} XidBoundsViolation; + +typedef enum XidCommitStatus +{ + XID_COMMITTED, + XID_IS_CURRENT_XID, + XID_IN_PROGRESS, + XID_ABORTED +} XidCommitStatus; + +typedef enum SkipPages +{ + SKIP_PAGES_ALL_FROZEN, + SKIP_PAGES_ALL_VISIBLE, + SKIP_PAGES_NONE +} SkipPages; + +/* + * Struct holding information about a toasted attribute sufficient to both + * check the toasted attribute and, if found to be corrupt, to report where it + * was encountered in the main table. + */ +typedef struct ToastedAttribute +{ + struct varatt_external toast_pointer; + BlockNumber blkno; /* block in main table */ + OffsetNumber offnum; /* offset in main table */ + AttrNumber attnum; /* attribute in main table */ +} ToastedAttribute; + +/* + * Struct holding the running context information during + * a lifetime of a verify_heapam execution. + */ +typedef struct HeapCheckContext +{ + /* + * Cached copies of values from ShmemVariableCache and computed values + * from them. + */ + FullTransactionId next_fxid; /* ShmemVariableCache->nextXid */ + TransactionId next_xid; /* 32-bit version of next_fxid */ + TransactionId oldest_xid; /* ShmemVariableCache->oldestXid */ + FullTransactionId oldest_fxid; /* 64-bit version of oldest_xid, computed + * relative to next_fxid */ + TransactionId safe_xmin; /* this XID and newer ones can't become + * all-visible while we're running */ + + /* + * Cached copy of value from MultiXactState + */ + MultiXactId next_mxact; /* MultiXactState->nextMXact */ + MultiXactId oldest_mxact; /* MultiXactState->oldestMultiXactId */ + + /* + * Cached copies of the most recently checked xid and its status. + */ + TransactionId cached_xid; + XidCommitStatus cached_status; + + /* Values concerning the heap relation being checked */ + Relation rel; + TransactionId relfrozenxid; + FullTransactionId relfrozenfxid; + TransactionId relminmxid; + Relation toast_rel; + Relation *toast_indexes; + Relation valid_toast_index; + int num_toast_indexes; + + /* Values for iterating over pages in the relation */ + BlockNumber blkno; + BufferAccessStrategy bstrategy; + Buffer buffer; + Page page; + + /* Values for iterating over tuples within a page */ + OffsetNumber offnum; + ItemId itemid; + uint16 lp_len; + uint16 lp_off; + HeapTupleHeader tuphdr; + int natts; + + /* Values for iterating over attributes within the tuple */ + uint32 offset; /* offset in tuple data */ + AttrNumber attnum; + + /* True if tuple's xmax makes it eligible for pruning */ + bool tuple_could_be_pruned; + + /* + * List of ToastedAttribute structs for toasted attributes which are not + * eligible for pruning and should be checked + */ + List *toasted_attributes; + + /* Whether verify_heapam has yet encountered any corrupt tuples */ + bool is_corrupt; + + /* The descriptor and tuplestore for verify_heapam's result tuples */ + TupleDesc tupdesc; + Tuplestorestate *tupstore; +} HeapCheckContext; + +/* Internal implementation */ +static void sanity_check_relation(Relation rel); +static void check_tuple(HeapCheckContext *ctx); +static void check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx, + ToastedAttribute *ta, int32 *expected_chunk_seq, + uint32 extsize); + +static bool check_tuple_attribute(HeapCheckContext *ctx); +static void check_toasted_attribute(HeapCheckContext *ctx, + ToastedAttribute *ta); + +static bool check_tuple_header(HeapCheckContext *ctx); +static bool check_tuple_visibility(HeapCheckContext *ctx); + +static void report_corruption(HeapCheckContext *ctx, char *msg); +static void report_toast_corruption(HeapCheckContext *ctx, + ToastedAttribute *ta, char *msg); +static TupleDesc verify_heapam_tupdesc(void); +static FullTransactionId FullTransactionIdFromXidAndCtx(TransactionId xid, + const HeapCheckContext *ctx); +static void update_cached_xid_range(HeapCheckContext *ctx); +static void update_cached_mxid_range(HeapCheckContext *ctx); +static XidBoundsViolation check_mxid_in_range(MultiXactId mxid, + HeapCheckContext *ctx); +static XidBoundsViolation check_mxid_valid_in_rel(MultiXactId mxid, + HeapCheckContext *ctx); +static XidBoundsViolation get_xid_status(TransactionId xid, + HeapCheckContext *ctx, + XidCommitStatus *status); + +/* + * Scan and report corruption in heap pages, optionally reconciling toasted + * attributes with entries in the associated toast table. Intended to be + * called from SQL with the following parameters: + * + * relation: + * The Oid of the heap relation to be checked. + * + * on_error_stop: + * Whether to stop at the end of the first page for which errors are + * detected. Note that multiple rows may be returned. + * + * check_toast: + * Whether to check each toasted attribute against the toast table to + * verify that it can be found there. + * + * skip: + * What kinds of pages in the heap relation should be skipped. Valid + * options are "all-visible", "all-frozen", and "none". + * + * Returns to the SQL caller a set of tuples, each containing the location + * and a description of a corruption found in the heap. + * + * This code goes to some trouble to avoid crashing the server even if the + * table pages are badly corrupted, but it's probably not perfect. If + * check_toast is true, we'll use regular index lookups to try to fetch TOAST + * tuples, which can certainly cause crashes if the right kind of corruption + * exists in the toast table or index. No matter what parameters you pass, + * we can't protect against crashes that might occur trying to look up the + * commit status of transaction IDs (though we avoid trying to do such lookups + * for transaction IDs that can't legally appear in the table). + */ +Datum +verify_heapam(PG_FUNCTION_ARGS) +{ + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + MemoryContext old_context; + bool random_access; + HeapCheckContext ctx; + Buffer vmbuffer = InvalidBuffer; + Oid relid; + bool on_error_stop; + bool check_toast; + SkipPages skip_option = SKIP_PAGES_NONE; + BlockNumber first_block; + BlockNumber last_block; + BlockNumber nblocks; + const char *skip; + + /* Check to see if caller supports us returning a tuplestore */ + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("materialize mode required, but it is not allowed in this context"))); + + /* Check supplied arguments */ + if (PG_ARGISNULL(0)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("relation cannot be null"))); + relid = PG_GETARG_OID(0); + + if (PG_ARGISNULL(1)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("on_error_stop cannot be null"))); + on_error_stop = PG_GETARG_BOOL(1); + + if (PG_ARGISNULL(2)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("check_toast cannot be null"))); + check_toast = PG_GETARG_BOOL(2); + + if (PG_ARGISNULL(3)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("skip cannot be null"))); + skip = text_to_cstring(PG_GETARG_TEXT_PP(3)); + if (pg_strcasecmp(skip, "all-visible") == 0) + skip_option = SKIP_PAGES_ALL_VISIBLE; + else if (pg_strcasecmp(skip, "all-frozen") == 0) + skip_option = SKIP_PAGES_ALL_FROZEN; + else if (pg_strcasecmp(skip, "none") == 0) + skip_option = SKIP_PAGES_NONE; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid skip option"), + errhint("Valid skip options are \"all-visible\", \"all-frozen\", and \"none\"."))); + + memset(&ctx, 0, sizeof(HeapCheckContext)); + ctx.cached_xid = InvalidTransactionId; + ctx.toasted_attributes = NIL; + + /* + * Any xmin newer than the xmin of our snapshot can't become all-visible + * while we're running. + */ + ctx.safe_xmin = GetTransactionSnapshot()->xmin; + + /* + * If we report corruption when not examining some individual attribute, + * we need attnum to be reported as NULL. Set that up before any + * corruption reporting might happen. + */ + ctx.attnum = -1; + + /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */ + old_context = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory); + random_access = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0; + ctx.tupdesc = verify_heapam_tupdesc(); + ctx.tupstore = tuplestore_begin_heap(random_access, false, work_mem); + rsinfo->returnMode = SFRM_Materialize; + rsinfo->setResult = ctx.tupstore; + rsinfo->setDesc = ctx.tupdesc; + MemoryContextSwitchTo(old_context); + + /* Open relation, check relkind and access method */ + ctx.rel = relation_open(relid, AccessShareLock); + sanity_check_relation(ctx.rel); + + /* Early exit if the relation is empty */ + nblocks = RelationGetNumberOfBlocks(ctx.rel); + if (!nblocks) + { + relation_close(ctx.rel, AccessShareLock); + PG_RETURN_NULL(); + } + + ctx.bstrategy = GetAccessStrategy(BAS_BULKREAD); + ctx.buffer = InvalidBuffer; + ctx.page = NULL; + + /* Validate block numbers, or handle nulls. */ + if (PG_ARGISNULL(4)) + first_block = 0; + else + { + int64 fb = PG_GETARG_INT64(4); + + if (fb < 0 || fb >= nblocks) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("starting block number must be between 0 and %u", + nblocks - 1))); + first_block = (BlockNumber) fb; + } + if (PG_ARGISNULL(5)) + last_block = nblocks - 1; + else + { + int64 lb = PG_GETARG_INT64(5); + + if (lb < 0 || lb >= nblocks) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("ending block number must be between 0 and %u", + nblocks - 1))); + last_block = (BlockNumber) lb; + } + + /* Optionally open the toast relation, if any. */ + if (ctx.rel->rd_rel->reltoastrelid && check_toast) + { + int offset; + + /* Main relation has associated toast relation */ + ctx.toast_rel = table_open(ctx.rel->rd_rel->reltoastrelid, + AccessShareLock); + offset = toast_open_indexes(ctx.toast_rel, + AccessShareLock, + &(ctx.toast_indexes), + &(ctx.num_toast_indexes)); + ctx.valid_toast_index = ctx.toast_indexes[offset]; + } + else + { + /* + * Main relation has no associated toast relation, or we're + * intentionally skipping it. + */ + ctx.toast_rel = NULL; + ctx.toast_indexes = NULL; + ctx.num_toast_indexes = 0; + } + + update_cached_xid_range(&ctx); + update_cached_mxid_range(&ctx); + ctx.relfrozenxid = ctx.rel->rd_rel->relfrozenxid; + ctx.relfrozenfxid = FullTransactionIdFromXidAndCtx(ctx.relfrozenxid, &ctx); + ctx.relminmxid = ctx.rel->rd_rel->relminmxid; + + if (TransactionIdIsNormal(ctx.relfrozenxid)) + ctx.oldest_xid = ctx.relfrozenxid; + + for (ctx.blkno = first_block; ctx.blkno <= last_block; ctx.blkno++) + { + OffsetNumber maxoff; + + /* Optionally skip over all-frozen or all-visible blocks */ + if (skip_option != SKIP_PAGES_NONE) + { + int32 mapbits; + + mapbits = (int32) visibilitymap_get_status(ctx.rel, ctx.blkno, + &vmbuffer); + if (skip_option == SKIP_PAGES_ALL_FROZEN) + { + if ((mapbits & VISIBILITYMAP_ALL_FROZEN) != 0) + continue; + } + + if (skip_option == SKIP_PAGES_ALL_VISIBLE) + { + if ((mapbits & VISIBILITYMAP_ALL_VISIBLE) != 0) + continue; + } + } + + /* Read and lock the next page. */ + ctx.buffer = ReadBufferExtended(ctx.rel, MAIN_FORKNUM, ctx.blkno, + RBM_NORMAL, ctx.bstrategy); + LockBuffer(ctx.buffer, BUFFER_LOCK_SHARE); + ctx.page = BufferGetPage(ctx.buffer); + + /* Perform tuple checks */ + maxoff = PageGetMaxOffsetNumber(ctx.page); + for (ctx.offnum = FirstOffsetNumber; ctx.offnum <= maxoff; + ctx.offnum = OffsetNumberNext(ctx.offnum)) + { + ctx.itemid = PageGetItemId(ctx.page, ctx.offnum); + + /* Skip over unused/dead line pointers */ + if (!ItemIdIsUsed(ctx.itemid) || ItemIdIsDead(ctx.itemid)) + continue; + + /* + * If this line pointer has been redirected, check that it + * redirects to a valid offset within the line pointer array + */ + if (ItemIdIsRedirected(ctx.itemid)) + { + OffsetNumber rdoffnum = ItemIdGetRedirect(ctx.itemid); + ItemId rditem; + + if (rdoffnum < FirstOffsetNumber) + { + report_corruption(&ctx, + psprintf("line pointer redirection to item at offset %u precedes minimum offset %u", + (unsigned) rdoffnum, + (unsigned) FirstOffsetNumber)); + continue; + } + if (rdoffnum > maxoff) + { + report_corruption(&ctx, + psprintf("line pointer redirection to item at offset %u exceeds maximum offset %u", + (unsigned) rdoffnum, + (unsigned) maxoff)); + continue; + } + rditem = PageGetItemId(ctx.page, rdoffnum); + if (!ItemIdIsUsed(rditem)) + report_corruption(&ctx, + psprintf("line pointer redirection to unused item at offset %u", + (unsigned) rdoffnum)); + continue; + } + + /* Sanity-check the line pointer's offset and length values */ + ctx.lp_len = ItemIdGetLength(ctx.itemid); + ctx.lp_off = ItemIdGetOffset(ctx.itemid); + + if (ctx.lp_off != MAXALIGN(ctx.lp_off)) + { + report_corruption(&ctx, + psprintf("line pointer to page offset %u is not maximally aligned", + ctx.lp_off)); + continue; + } + if (ctx.lp_len < MAXALIGN(SizeofHeapTupleHeader)) + { + report_corruption(&ctx, + psprintf("line pointer length %u is less than the minimum tuple header size %u", + ctx.lp_len, + (unsigned) MAXALIGN(SizeofHeapTupleHeader))); + continue; + } + if (ctx.lp_off + ctx.lp_len > BLCKSZ) + { + report_corruption(&ctx, + psprintf("line pointer to page offset %u with length %u ends beyond maximum page offset %u", + ctx.lp_off, + ctx.lp_len, + (unsigned) BLCKSZ)); + continue; + } + + /* It should be safe to examine the tuple's header, at least */ + ctx.tuphdr = (HeapTupleHeader) PageGetItem(ctx.page, ctx.itemid); + ctx.natts = HeapTupleHeaderGetNatts(ctx.tuphdr); + + /* Ok, ready to check this next tuple */ + check_tuple(&ctx); + } + + /* clean up */ + UnlockReleaseBuffer(ctx.buffer); + + /* + * Check any toast pointers from the page whose lock we just released + */ + if (ctx.toasted_attributes != NIL) + { + ListCell *cell; + + foreach(cell, ctx.toasted_attributes) + check_toasted_attribute(&ctx, lfirst(cell)); + list_free_deep(ctx.toasted_attributes); + ctx.toasted_attributes = NIL; + } + + if (on_error_stop && ctx.is_corrupt) + break; + } + + if (vmbuffer != InvalidBuffer) + ReleaseBuffer(vmbuffer); + + /* Close the associated toast table and indexes, if any. */ + if (ctx.toast_indexes) + toast_close_indexes(ctx.toast_indexes, ctx.num_toast_indexes, + AccessShareLock); + if (ctx.toast_rel) + table_close(ctx.toast_rel, AccessShareLock); + + /* Close the main relation */ + relation_close(ctx.rel, AccessShareLock); + + PG_RETURN_NULL(); +} + +/* + * Check that a relation's relkind and access method are both supported. + */ +static void +sanity_check_relation(Relation rel) +{ + if (rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_MATVIEW && + rel->rd_rel->relkind != RELKIND_TOASTVALUE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a table, materialized view, or TOAST table", + RelationGetRelationName(rel)))); + if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only heap AM is supported"))); +} + +/* + * Shared internal implementation for report_corruption and + * report_toast_corruption. + */ +static void +report_corruption_internal(Tuplestorestate *tupstore, TupleDesc tupdesc, + BlockNumber blkno, OffsetNumber offnum, + AttrNumber attnum, char *msg) +{ + Datum values[HEAPCHECK_RELATION_COLS]; + bool nulls[HEAPCHECK_RELATION_COLS]; + HeapTuple tuple; + + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); + values[0] = Int64GetDatum(blkno); + values[1] = Int32GetDatum(offnum); + values[2] = Int32GetDatum(attnum); + nulls[2] = (attnum < 0); + values[3] = CStringGetTextDatum(msg); + + /* + * In principle, there is nothing to prevent a scan over a large, highly + * corrupted table from using work_mem worth of memory building up the + * tuplestore. That's ok, but if we also leak the msg argument memory + * until the end of the query, we could exceed work_mem by more than a + * trivial amount. Therefore, free the msg argument each time we are + * called rather than waiting for our current memory context to be freed. + */ + pfree(msg); + + tuple = heap_form_tuple(tupdesc, values, nulls); + tuplestore_puttuple(tupstore, tuple); +} + +/* + * Record a single corruption found in the main table. The values in ctx should + * indicate the location of the corruption, and the msg argument should contain + * a human-readable description of the corruption. + * + * The msg argument is pfree'd by this function. + */ +static void +report_corruption(HeapCheckContext *ctx, char *msg) +{ + report_corruption_internal(ctx->tupstore, ctx->tupdesc, ctx->blkno, + ctx->offnum, ctx->attnum, msg); + ctx->is_corrupt = true; +} + +/* + * Record corruption found in the toast table. The values in ta should + * indicate the location in the main table where the toast pointer was + * encountered, and the msg argument should contain a human-readable + * description of the toast table corruption. + * + * As above, the msg argument is pfree'd by this function. + */ +static void +report_toast_corruption(HeapCheckContext *ctx, ToastedAttribute *ta, + char *msg) +{ + report_corruption_internal(ctx->tupstore, ctx->tupdesc, ta->blkno, + ta->offnum, ta->attnum, msg); + ctx->is_corrupt = true; +} + +/* + * Construct the TupleDesc used to report messages about corruptions found + * while scanning the heap. + */ +static TupleDesc +verify_heapam_tupdesc(void) +{ + TupleDesc tupdesc; + AttrNumber a = 0; + + tupdesc = CreateTemplateTupleDesc(HEAPCHECK_RELATION_COLS); + TupleDescInitEntry(tupdesc, ++a, "blkno", INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, ++a, "offnum", INT4OID, -1, 0); + TupleDescInitEntry(tupdesc, ++a, "attnum", INT4OID, -1, 0); + TupleDescInitEntry(tupdesc, ++a, "msg", TEXTOID, -1, 0); + Assert(a == HEAPCHECK_RELATION_COLS); + + return BlessTupleDesc(tupdesc); +} + +/* + * Check for tuple header corruption. + * + * Some kinds of corruption make it unsafe to check the tuple attributes, for + * example when the line pointer refers to a range of bytes outside the page. + * In such cases, we return false (not checkable) after recording appropriate + * corruption messages. + * + * Some other kinds of tuple header corruption confuse the question of where + * the tuple attributes begin, or how long the nulls bitmap is, etc., making it + * unreasonable to attempt to check attributes, even if all candidate answers + * to those questions would not result in reading past the end of the line + * pointer or page. In such cases, like above, we record corruption messages + * about the header and then return false. + * + * Other kinds of tuple header corruption do not bear on the question of + * whether the tuple attributes can be checked, so we record corruption + * messages for them but we do not return false merely because we detected + * them. + * + * Returns whether the tuple is sufficiently sensible to undergo visibility and + * attribute checks. + */ +static bool +check_tuple_header(HeapCheckContext *ctx) +{ + HeapTupleHeader tuphdr = ctx->tuphdr; + uint16 infomask = tuphdr->t_infomask; + bool result = true; + unsigned expected_hoff; + + if (ctx->tuphdr->t_hoff > ctx->lp_len) + { + report_corruption(ctx, + psprintf("data begins at offset %u beyond the tuple length %u", + ctx->tuphdr->t_hoff, ctx->lp_len)); + result = false; + } + + if ((ctx->tuphdr->t_infomask & HEAP_XMAX_COMMITTED) && + (ctx->tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)) + { + report_corruption(ctx, + pstrdup("multixact should not be marked committed")); + + /* + * This condition is clearly wrong, but it's not enough to justify + * skipping further checks, because we don't rely on this to determine + * whether the tuple is visible or to interpret other relevant header + * fields. + */ + } + + if (infomask & HEAP_HASNULL) + expected_hoff = MAXALIGN(SizeofHeapTupleHeader + BITMAPLEN(ctx->natts)); + else + expected_hoff = MAXALIGN(SizeofHeapTupleHeader); + if (ctx->tuphdr->t_hoff != expected_hoff) + { + if ((infomask & HEAP_HASNULL) && ctx->natts == 1) + report_corruption(ctx, + psprintf("tuple data should begin at byte %u, but actually begins at byte %u (1 attribute, has nulls)", + expected_hoff, ctx->tuphdr->t_hoff)); + else if ((infomask & HEAP_HASNULL)) + report_corruption(ctx, + psprintf("tuple data should begin at byte %u, but actually begins at byte %u (%u attributes, has nulls)", + expected_hoff, ctx->tuphdr->t_hoff, ctx->natts)); + else if (ctx->natts == 1) + report_corruption(ctx, + psprintf("tuple data should begin at byte %u, but actually begins at byte %u (1 attribute, no nulls)", + expected_hoff, ctx->tuphdr->t_hoff)); + else + report_corruption(ctx, + psprintf("tuple data should begin at byte %u, but actually begins at byte %u (%u attributes, no nulls)", + expected_hoff, ctx->tuphdr->t_hoff, ctx->natts)); + result = false; + } + + return result; +} + +/* + * Checks tuple visibility so we know which further checks are safe to + * perform. + * + * If a tuple could have been inserted by a transaction that also added a + * column to the table, but which ultimately did not commit, or which has not + * yet committed, then the table's current TupleDesc might differ from the one + * used to construct this tuple, so we must not check it. + * + * As a special case, if our own transaction inserted the tuple, even if we + * added a column to the table, our TupleDesc should match. We could check the + * tuple, but choose not to do so. + * + * If a tuple has been updated or deleted, we can still read the old tuple for + * corruption checking purposes, as long as we are careful about concurrent + * vacuums. The main table tuple itself cannot be vacuumed away because we + * hold a buffer lock on the page, but if the deleting transaction is older + * than our transaction snapshot's xmin, then vacuum could remove the toast at + * any time, so we must not try to follow TOAST pointers. + * + * If xmin or xmax values are older than can be checked against clog, or appear + * to be in the future (possibly due to wrap-around), then we cannot make a + * determination about the visibility of the tuple, so we skip further checks. + * + * Returns true if the tuple itself should be checked, false otherwise. Sets + * ctx->tuple_could_be_pruned if the tuple -- and thus also any associated + * TOAST tuples -- are eligible for pruning. + */ +static bool +check_tuple_visibility(HeapCheckContext *ctx) +{ + TransactionId xmin; + TransactionId xvac; + TransactionId xmax; + XidCommitStatus xmin_status; + XidCommitStatus xvac_status; + XidCommitStatus xmax_status; + HeapTupleHeader tuphdr = ctx->tuphdr; + + ctx->tuple_could_be_pruned = true; /* have not yet proven otherwise */ + + /* If xmin is normal, it should be within valid range */ + xmin = HeapTupleHeaderGetXmin(tuphdr); + switch (get_xid_status(xmin, ctx, &xmin_status)) + { + case XID_INVALID: + case XID_BOUNDS_OK: + break; + case XID_IN_FUTURE: + report_corruption(ctx, + psprintf("xmin %u equals or exceeds next valid transaction ID %u:%u", + xmin, + EpochFromFullTransactionId(ctx->next_fxid), + XidFromFullTransactionId(ctx->next_fxid))); + return false; + case XID_PRECEDES_CLUSTERMIN: + report_corruption(ctx, + psprintf("xmin %u precedes oldest valid transaction ID %u:%u", + xmin, + EpochFromFullTransactionId(ctx->oldest_fxid), + XidFromFullTransactionId(ctx->oldest_fxid))); + return false; + case XID_PRECEDES_RELMIN: + report_corruption(ctx, + psprintf("xmin %u precedes relation freeze threshold %u:%u", + xmin, + EpochFromFullTransactionId(ctx->relfrozenfxid), + XidFromFullTransactionId(ctx->relfrozenfxid))); + return false; + } + + /* + * Has inserting transaction committed? + */ + if (!HeapTupleHeaderXminCommitted(tuphdr)) + { + if (HeapTupleHeaderXminInvalid(tuphdr)) + return false; /* inserter aborted, don't check */ + /* Used by pre-9.0 binary upgrades */ + else if (tuphdr->t_infomask & HEAP_MOVED_OFF) + { + xvac = HeapTupleHeaderGetXvac(tuphdr); + + switch (get_xid_status(xvac, ctx, &xvac_status)) + { + case XID_INVALID: + report_corruption(ctx, + pstrdup("old-style VACUUM FULL transaction ID for moved off tuple is invalid")); + return false; + case XID_IN_FUTURE: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved off tuple equals or exceeds next valid transaction ID %u:%u", + xvac, + EpochFromFullTransactionId(ctx->next_fxid), + XidFromFullTransactionId(ctx->next_fxid))); + return false; + case XID_PRECEDES_RELMIN: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved off tuple precedes relation freeze threshold %u:%u", + xvac, + EpochFromFullTransactionId(ctx->relfrozenfxid), + XidFromFullTransactionId(ctx->relfrozenfxid))); + return false; + case XID_PRECEDES_CLUSTERMIN: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved off tuple precedes oldest valid transaction ID %u:%u", + xvac, + EpochFromFullTransactionId(ctx->oldest_fxid), + XidFromFullTransactionId(ctx->oldest_fxid))); + return false; + case XID_BOUNDS_OK: + break; + } + + switch (xvac_status) + { + case XID_IS_CURRENT_XID: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved off tuple matches our current transaction ID", + xvac)); + return false; + case XID_IN_PROGRESS: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved off tuple appears to be in progress", + xvac)); + return false; + + case XID_COMMITTED: + + /* + * The tuple is dead, because the xvac transaction moved + * it off and committed. It's checkable, but also + * prunable. + */ + return true; + + case XID_ABORTED: + + /* + * The original xmin must have committed, because the xvac + * transaction tried to move it later. Since xvac is + * aborted, whether it's still alive now depends on the + * status of xmax. + */ + break; + } + } + /* Used by pre-9.0 binary upgrades */ + else if (tuphdr->t_infomask & HEAP_MOVED_IN) + { + xvac = HeapTupleHeaderGetXvac(tuphdr); + + switch (get_xid_status(xvac, ctx, &xvac_status)) + { + case XID_INVALID: + report_corruption(ctx, + pstrdup("old-style VACUUM FULL transaction ID for moved in tuple is invalid")); + return false; + case XID_IN_FUTURE: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved in tuple equals or exceeds next valid transaction ID %u:%u", + xvac, + EpochFromFullTransactionId(ctx->next_fxid), + XidFromFullTransactionId(ctx->next_fxid))); + return false; + case XID_PRECEDES_RELMIN: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved in tuple precedes relation freeze threshold %u:%u", + xvac, + EpochFromFullTransactionId(ctx->relfrozenfxid), + XidFromFullTransactionId(ctx->relfrozenfxid))); + return false; + case XID_PRECEDES_CLUSTERMIN: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved in tuple precedes oldest valid transaction ID %u:%u", + xvac, + EpochFromFullTransactionId(ctx->oldest_fxid), + XidFromFullTransactionId(ctx->oldest_fxid))); + return false; + case XID_BOUNDS_OK: + break; + } + + switch (xvac_status) + { + case XID_IS_CURRENT_XID: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved in tuple matches our current transaction ID", + xvac)); + return false; + case XID_IN_PROGRESS: + report_corruption(ctx, + psprintf("old-style VACUUM FULL transaction ID %u for moved in tuple appears to be in progress", + xvac)); + return false; + + case XID_COMMITTED: + + /* + * The original xmin must have committed, because the xvac + * transaction moved it later. Whether it's still alive + * now depends on the status of xmax. + */ + break; + + case XID_ABORTED: + + /* + * The tuple is dead, because the xvac transaction moved + * it off and committed. It's checkable, but also + * prunable. + */ + return true; + } + } + else if (xmin_status != XID_COMMITTED) + { + /* + * Inserting transaction is not in progress, and not committed, so + * it might have changed the TupleDesc in ways we don't know + * about. Thus, don't try to check the tuple structure. + * + * If xmin_status happens to be XID_IS_CURRENT_XID, then in theory + * any such DDL changes ought to be visible to us, so perhaps we + * could check anyway in that case. But, for now, let's be + * conservative and treat this like any other uncommitted insert. + */ + return false; + } + } + + /* + * Okay, the inserter committed, so it was good at some point. Now what + * about the deleting transaction? + */ + + if (tuphdr->t_infomask & HEAP_XMAX_IS_MULTI) + { + /* + * xmax is a multixact, so sanity-check the MXID. Note that we do this + * prior to checking for HEAP_XMAX_INVALID or + * HEAP_XMAX_IS_LOCKED_ONLY. This might therefore complain about + * things that wouldn't actually be a problem during a normal scan, + * but eventually we're going to have to freeze, and that process will + * ignore hint bits. + * + * Even if the MXID is out of range, we still know that the original + * insert committed, so we can check the tuple itself. However, we + * can't rule out the possibility that this tuple is dead, so don't + * clear ctx->tuple_could_be_pruned. Possibly we should go ahead and + * clear that flag anyway if HEAP_XMAX_INVALID is set or if + * HEAP_XMAX_IS_LOCKED_ONLY is true, but for now we err on the side of + * avoiding possibly-bogus complaints about missing TOAST entries. + */ + xmax = HeapTupleHeaderGetRawXmax(tuphdr); + switch (check_mxid_valid_in_rel(xmax, ctx)) + { + case XID_INVALID: + report_corruption(ctx, + pstrdup("multitransaction ID is invalid")); + return true; + case XID_PRECEDES_RELMIN: + report_corruption(ctx, + psprintf("multitransaction ID %u precedes relation minimum multitransaction ID threshold %u", + xmax, ctx->relminmxid)); + return true; + case XID_PRECEDES_CLUSTERMIN: + report_corruption(ctx, + psprintf("multitransaction ID %u precedes oldest valid multitransaction ID threshold %u", + xmax, ctx->oldest_mxact)); + return true; + case XID_IN_FUTURE: + report_corruption(ctx, + psprintf("multitransaction ID %u equals or exceeds next valid multitransaction ID %u", + xmax, + ctx->next_mxact)); + return true; + case XID_BOUNDS_OK: + break; + } + } + + if (tuphdr->t_infomask & HEAP_XMAX_INVALID) + { + /* + * This tuple is live. A concurrently running transaction could + * delete it before we get around to checking the toast, but any such + * running transaction is surely not less than our safe_xmin, so the + * toast cannot be vacuumed out from under us. + */ + ctx->tuple_could_be_pruned = false; + return true; + } + + if (HEAP_XMAX_IS_LOCKED_ONLY(tuphdr->t_infomask)) + { + /* + * "Deleting" xact really only locked it, so the tuple is live in any + * case. As above, a concurrently running transaction could delete + * it, but it cannot be vacuumed out from under us. + */ + ctx->tuple_could_be_pruned = false; + return true; + } + + if (tuphdr->t_infomask & HEAP_XMAX_IS_MULTI) + { + /* + * We already checked above that this multixact is within limits for + * this table. Now check the update xid from this multixact. + */ + xmax = HeapTupleGetUpdateXid(tuphdr); + switch (get_xid_status(xmax, ctx, &xmax_status)) + { + case XID_INVALID: + /* not LOCKED_ONLY, so it has to have an xmax */ + report_corruption(ctx, + pstrdup("update xid is invalid")); + return true; + case XID_IN_FUTURE: + report_corruption(ctx, + psprintf("update xid %u equals or exceeds next valid transaction ID %u:%u", + xmax, + EpochFromFullTransactionId(ctx->next_fxid), + XidFromFullTransactionId(ctx->next_fxid))); + return true; + case XID_PRECEDES_RELMIN: + report_corruption(ctx, + psprintf("update xid %u precedes relation freeze threshold %u:%u", + xmax, + EpochFromFullTransactionId(ctx->relfrozenfxid), + XidFromFullTransactionId(ctx->relfrozenfxid))); + return true; + case XID_PRECEDES_CLUSTERMIN: + report_corruption(ctx, + psprintf("update xid %u precedes oldest valid transaction ID %u:%u", + xmax, + EpochFromFullTransactionId(ctx->oldest_fxid), + XidFromFullTransactionId(ctx->oldest_fxid))); + return true; + case XID_BOUNDS_OK: + break; + } + + switch (xmax_status) + { + case XID_IS_CURRENT_XID: + case XID_IN_PROGRESS: + + /* + * The delete is in progress, so it cannot be visible to our + * snapshot. + */ + ctx->tuple_could_be_pruned = false; + break; + case XID_COMMITTED: + + /* + * The delete committed. Whether the toast can be vacuumed + * away depends on how old the deleting transaction is. + */ + ctx->tuple_could_be_pruned = TransactionIdPrecedes(xmax, + ctx->safe_xmin); + break; + case XID_ABORTED: + + /* + * The delete aborted or crashed. The tuple is still live. + */ + ctx->tuple_could_be_pruned = false; + break; + } + + /* Tuple itself is checkable even if it's dead. */ + return true; + } + + /* xmax is an XID, not a MXID. Sanity check it. */ + xmax = HeapTupleHeaderGetRawXmax(tuphdr); + switch (get_xid_status(xmax, ctx, &xmax_status)) + { + case XID_IN_FUTURE: + report_corruption(ctx, + psprintf("xmax %u equals or exceeds next valid transaction ID %u:%u", + xmax, + EpochFromFullTransactionId(ctx->next_fxid), + XidFromFullTransactionId(ctx->next_fxid))); + return false; /* corrupt */ + case XID_PRECEDES_RELMIN: + report_corruption(ctx, + psprintf("xmax %u precedes relation freeze threshold %u:%u", + xmax, + EpochFromFullTransactionId(ctx->relfrozenfxid), + XidFromFullTransactionId(ctx->relfrozenfxid))); + return false; /* corrupt */ + case XID_PRECEDES_CLUSTERMIN: + report_corruption(ctx, + psprintf("xmax %u precedes oldest valid transaction ID %u:%u", + xmax, + EpochFromFullTransactionId(ctx->oldest_fxid), + XidFromFullTransactionId(ctx->oldest_fxid))); + return false; /* corrupt */ + case XID_BOUNDS_OK: + case XID_INVALID: + break; + } + + /* + * Whether the toast can be vacuumed away depends on how old the deleting + * transaction is. + */ + switch (xmax_status) + { + case XID_IS_CURRENT_XID: + case XID_IN_PROGRESS: + + /* + * The delete is in progress, so it cannot be visible to our + * snapshot. + */ + ctx->tuple_could_be_pruned = false; + break; + + case XID_COMMITTED: + + /* + * The delete committed. Whether the toast can be vacuumed away + * depends on how old the deleting transaction is. + */ + ctx->tuple_could_be_pruned = TransactionIdPrecedes(xmax, + ctx->safe_xmin); + break; + + case XID_ABORTED: + + /* + * The delete aborted or crashed. The tuple is still live. + */ + ctx->tuple_could_be_pruned = false; + break; + } + + /* Tuple itself is checkable even if it's dead. */ + return true; +} + + +/* + * Check the current toast tuple against the state tracked in ctx, recording + * any corruption found in ctx->tupstore. + * + * This is not equivalent to running verify_heapam on the toast table itself, + * and is not hardened against corruption of the toast table. Rather, when + * validating a toasted attribute in the main table, the sequence of toast + * tuples that store the toasted value are retrieved and checked in order, with + * each toast tuple being checked against where we are in the sequence, as well + * as each toast tuple having its varlena structure sanity checked. + * + * On entry, *expected_chunk_seq should be the chunk_seq value that we expect + * to find in toasttup. On exit, it will be updated to the value the next call + * to this function should expect to see. + */ +static void +check_toast_tuple(HeapTuple toasttup, HeapCheckContext *ctx, + ToastedAttribute *ta, int32 *expected_chunk_seq, + uint32 extsize) +{ + int32 chunk_seq; + int32 last_chunk_seq = (extsize - 1) / TOAST_MAX_CHUNK_SIZE; + Pointer chunk; + bool isnull; + int32 chunksize; + int32 expected_size; + + /* Sanity-check the sequence number. */ + chunk_seq = DatumGetInt32(fastgetattr(toasttup, 2, + ctx->toast_rel->rd_att, &isnull)); + if (isnull) + { + report_toast_corruption(ctx, ta, + psprintf("toast value %u has toast chunk with null sequence number", + ta->toast_pointer.va_valueid)); + return; + } + if (chunk_seq != *expected_chunk_seq) + { + /* Either the TOAST index is corrupt, or we don't have all chunks. */ + report_toast_corruption(ctx, ta, + psprintf("toast value %u index scan returned chunk %d when expecting chunk %d", + ta->toast_pointer.va_valueid, + chunk_seq, *expected_chunk_seq)); + } + *expected_chunk_seq = chunk_seq + 1; + + /* Sanity-check the chunk data. */ + chunk = DatumGetPointer(fastgetattr(toasttup, 3, + ctx->toast_rel->rd_att, &isnull)); + if (isnull) + { + report_toast_corruption(ctx, ta, + psprintf("toast value %u chunk %d has null data", + ta->toast_pointer.va_valueid, + chunk_seq)); + return; + } + if (!VARATT_IS_EXTENDED(chunk)) + chunksize = VARSIZE(chunk) - VARHDRSZ; + else if (VARATT_IS_SHORT(chunk)) + { + /* + * could happen due to heap_form_tuple doing its thing + */ + chunksize = VARSIZE_SHORT(chunk) - VARHDRSZ_SHORT; + } + else + { + /* should never happen */ + uint32 header = ((varattrib_4b *) chunk)->va_4byte.va_header; + + report_toast_corruption(ctx, ta, + psprintf("toast value %u chunk %d has invalid varlena header %0x", + ta->toast_pointer.va_valueid, + chunk_seq, header)); + return; + } + + /* + * Some checks on the data we've found + */ + if (chunk_seq > last_chunk_seq) + { + report_toast_corruption(ctx, ta, + psprintf("toast value %u chunk %d follows last expected chunk %d", + ta->toast_pointer.va_valueid, + chunk_seq, last_chunk_seq)); + return; + } + + expected_size = chunk_seq < last_chunk_seq ? TOAST_MAX_CHUNK_SIZE + : extsize - (last_chunk_seq * TOAST_MAX_CHUNK_SIZE); + + if (chunksize != expected_size) + report_toast_corruption(ctx, ta, + psprintf("toast value %u chunk %d has size %u, but expected size %u", + ta->toast_pointer.va_valueid, + chunk_seq, chunksize, expected_size)); +} + +/* + * Check the current attribute as tracked in ctx, recording any corruption + * found in ctx->tupstore. + * + * This function follows the logic performed by heap_deform_tuple(), and in the + * case of a toasted value, optionally stores the toast pointer so later it can + * be checked following the logic of detoast_external_attr(), checking for any + * conditions that would result in either of those functions Asserting or + * crashing the backend. The checks performed by Asserts present in those two + * functions are also performed here and in check_toasted_attribute. In cases + * where those two functions are a bit cavalier in their assumptions about data + * being correct, we perform additional checks not present in either of those + * two functions. Where some condition is checked in both of those functions, + * we perform it here twice, as we parallel the logical flow of those two + * functions. The presence of duplicate checks seems a reasonable price to pay + * for keeping this code tightly coupled with the code it protects. + * + * Returns true if the tuple attribute is sane enough for processing to + * continue on to the next attribute, false otherwise. + */ +static bool +check_tuple_attribute(HeapCheckContext *ctx) +{ + Datum attdatum; + struct varlena *attr; + char *tp; /* pointer to the tuple data */ + uint16 infomask; + Form_pg_attribute thisatt; + struct varatt_external toast_pointer; + + infomask = ctx->tuphdr->t_infomask; + thisatt = TupleDescAttr(RelationGetDescr(ctx->rel), ctx->attnum); + + tp = (char *) ctx->tuphdr + ctx->tuphdr->t_hoff; + + if (ctx->tuphdr->t_hoff + ctx->offset > ctx->lp_len) + { + report_corruption(ctx, + psprintf("attribute with length %u starts at offset %u beyond total tuple length %u", + thisatt->attlen, + ctx->tuphdr->t_hoff + ctx->offset, + ctx->lp_len)); + return false; + } + + /* Skip null values */ + if (infomask & HEAP_HASNULL && att_isnull(ctx->attnum, ctx->tuphdr->t_bits)) + return true; + + /* Skip non-varlena values, but update offset first */ + if (thisatt->attlen != -1) + { + ctx->offset = att_align_nominal(ctx->offset, thisatt->attalign); + ctx->offset = att_addlength_pointer(ctx->offset, thisatt->attlen, + tp + ctx->offset); + if (ctx->tuphdr->t_hoff + ctx->offset > ctx->lp_len) + { + report_corruption(ctx, + psprintf("attribute with length %u ends at offset %u beyond total tuple length %u", + thisatt->attlen, + ctx->tuphdr->t_hoff + ctx->offset, + ctx->lp_len)); + return false; + } + return true; + } + + /* Ok, we're looking at a varlena attribute. */ + ctx->offset = att_align_pointer(ctx->offset, thisatt->attalign, -1, + tp + ctx->offset); + + /* Get the (possibly corrupt) varlena datum */ + attdatum = fetchatt(thisatt, tp + ctx->offset); + + /* + * We have the datum, but we cannot decode it carelessly, as it may still + * be corrupt. + */ + + /* + * Check that VARTAG_SIZE won't hit a TrapMacro on a corrupt va_tag before + * risking a call into att_addlength_pointer + */ + if (VARATT_IS_EXTERNAL(tp + ctx->offset)) + { + uint8 va_tag = VARTAG_EXTERNAL(tp + ctx->offset); + + if (va_tag != VARTAG_ONDISK) + { + report_corruption(ctx, + psprintf("toasted attribute has unexpected TOAST tag %u", + va_tag)); + /* We can't know where the next attribute begins */ + return false; + } + } + + /* Ok, should be safe now */ + ctx->offset = att_addlength_pointer(ctx->offset, thisatt->attlen, + tp + ctx->offset); + + if (ctx->tuphdr->t_hoff + ctx->offset > ctx->lp_len) + { + report_corruption(ctx, + psprintf("attribute with length %u ends at offset %u beyond total tuple length %u", + thisatt->attlen, + ctx->tuphdr->t_hoff + ctx->offset, + ctx->lp_len)); + + return false; + } + + /* + * heap_deform_tuple would be done with this attribute at this point, + * having stored it in values[], and would continue to the next attribute. + * We go further, because we need to check if the toast datum is corrupt. + */ + + attr = (struct varlena *) DatumGetPointer(attdatum); + + /* + * Now we follow the logic of detoast_external_attr(), with the same + * caveats about being paranoid about corruption. + */ + + /* Skip values that are not external */ + if (!VARATT_IS_EXTERNAL(attr)) + return true; + + /* It is external, and we're looking at a page on disk */ + + /* + * Must copy attr into toast_pointer for alignment considerations + */ + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + /* The tuple header better claim to contain toasted values */ + if (!(infomask & HEAP_HASEXTERNAL)) + { + report_corruption(ctx, + psprintf("toast value %u is external but tuple header flag HEAP_HASEXTERNAL not set", + toast_pointer.va_valueid)); + return true; + } + + /* The relation better have a toast table */ + if (!ctx->rel->rd_rel->reltoastrelid) + { + report_corruption(ctx, + psprintf("toast value %u is external but relation has no toast relation", + toast_pointer.va_valueid)); + return true; + } + + /* If we were told to skip toast checking, then we're done. */ + if (ctx->toast_rel == NULL) + return true; + + /* + * If this tuple is eligible to be pruned, we cannot check the toast. + * Otherwise, we push a copy of the toast tuple so we can check it after + * releasing the main table buffer lock. + */ + if (!ctx->tuple_could_be_pruned) + { + ToastedAttribute *ta; + + ta = (ToastedAttribute *) palloc0(sizeof(ToastedAttribute)); + + VARATT_EXTERNAL_GET_POINTER(ta->toast_pointer, attr); + ta->blkno = ctx->blkno; + ta->offnum = ctx->offnum; + ta->attnum = ctx->attnum; + ctx->toasted_attributes = lappend(ctx->toasted_attributes, ta); + } + + return true; +} + +/* + * For each attribute collected in ctx->toasted_attributes, look up the value + * in the toast table and perform checks on it. This function should only be + * called on toast pointers which cannot be vacuumed away during our + * processing. + */ +static void +check_toasted_attribute(HeapCheckContext *ctx, ToastedAttribute *ta) +{ + SnapshotData SnapshotToast; + ScanKeyData toastkey; + SysScanDesc toastscan; + bool found_toasttup; + HeapTuple toasttup; + uint32 extsize; + int32 expected_chunk_seq = 0; + int32 last_chunk_seq; + + extsize = VARATT_EXTERNAL_GET_EXTSIZE(ta->toast_pointer); + last_chunk_seq = (extsize - 1) / TOAST_MAX_CHUNK_SIZE; + + /* + * Setup a scan key to find chunks in toast table with matching va_valueid + */ + ScanKeyInit(&toastkey, + (AttrNumber) 1, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(ta->toast_pointer.va_valueid)); + + /* + * Check if any chunks for this toasted object exist in the toast table, + * accessible via the index. + */ + init_toast_snapshot(&SnapshotToast); + toastscan = systable_beginscan_ordered(ctx->toast_rel, + ctx->valid_toast_index, + &SnapshotToast, 1, + &toastkey); + found_toasttup = false; + while ((toasttup = + systable_getnext_ordered(toastscan, + ForwardScanDirection)) != NULL) + { + found_toasttup = true; + check_toast_tuple(toasttup, ctx, ta, &expected_chunk_seq, extsize); + } + systable_endscan_ordered(toastscan); + + if (!found_toasttup) + report_toast_corruption(ctx, ta, + psprintf("toast value %u not found in toast table", + ta->toast_pointer.va_valueid)); + else if (expected_chunk_seq <= last_chunk_seq) + report_toast_corruption(ctx, ta, + psprintf("toast value %u was expected to end at chunk %d, but ended while expecting chunk %d", + ta->toast_pointer.va_valueid, + last_chunk_seq, expected_chunk_seq)); +} + +/* + * Check the current tuple as tracked in ctx, recording any corruption found in + * ctx->tupstore. + */ +static void +check_tuple(HeapCheckContext *ctx) +{ + /* + * Check various forms of tuple header corruption, and if the header is + * too corrupt, do not continue with other checks. + */ + if (!check_tuple_header(ctx)) + return; + + /* + * Check tuple visibility. If the inserting transaction aborted, we + * cannot assume our relation description matches the tuple structure, and + * therefore cannot check it. + */ + if (!check_tuple_visibility(ctx)) + return; + + /* + * The tuple is visible, so it must be compatible with the current version + * of the relation descriptor. It might have fewer columns than are + * present in the relation descriptor, but it cannot have more. + */ + if (RelationGetDescr(ctx->rel)->natts < ctx->natts) + { + report_corruption(ctx, + psprintf("number of attributes %u exceeds maximum expected for table %u", + ctx->natts, + RelationGetDescr(ctx->rel)->natts)); + return; + } + + /* + * Check each attribute unless we hit corruption that confuses what to do + * next, at which point we abort further attribute checks for this tuple. + * Note that we don't abort for all types of corruption, only for those + * types where we don't know how to continue. We also don't abort the + * checking of toasted attributes collected from the tuple prior to + * aborting. Those will still be checked later along with other toasted + * attributes collected from the page. + */ + ctx->offset = 0; + for (ctx->attnum = 0; ctx->attnum < ctx->natts; ctx->attnum++) + if (!check_tuple_attribute(ctx)) + break; /* cannot continue */ + + /* revert attnum to -1 until we again examine individual attributes */ + ctx->attnum = -1; +} + +/* + * Convert a TransactionId into a FullTransactionId using our cached values of + * the valid transaction ID range. It is the caller's responsibility to have + * already updated the cached values, if necessary. + */ +static FullTransactionId +FullTransactionIdFromXidAndCtx(TransactionId xid, const HeapCheckContext *ctx) +{ + uint32 epoch; + + if (!TransactionIdIsNormal(xid)) + return FullTransactionIdFromEpochAndXid(0, xid); + epoch = EpochFromFullTransactionId(ctx->next_fxid); + if (xid > ctx->next_xid) + epoch--; + return FullTransactionIdFromEpochAndXid(epoch, xid); +} + +/* + * Update our cached range of valid transaction IDs. + */ +static void +update_cached_xid_range(HeapCheckContext *ctx) +{ + /* Make cached copies */ + LWLockAcquire(XidGenLock, LW_SHARED); + ctx->next_fxid = ShmemVariableCache->nextXid; + ctx->oldest_xid = ShmemVariableCache->oldestXid; + LWLockRelease(XidGenLock); + + /* And compute alternate versions of the same */ + ctx->oldest_fxid = FullTransactionIdFromXidAndCtx(ctx->oldest_xid, ctx); + ctx->next_xid = XidFromFullTransactionId(ctx->next_fxid); +} + +/* + * Update our cached range of valid multitransaction IDs. + */ +static void +update_cached_mxid_range(HeapCheckContext *ctx) +{ + ReadMultiXactIdRange(&ctx->oldest_mxact, &ctx->next_mxact); +} + +/* + * Return whether the given FullTransactionId is within our cached valid + * transaction ID range. + */ +static inline bool +fxid_in_cached_range(FullTransactionId fxid, const HeapCheckContext *ctx) +{ + return (FullTransactionIdPrecedesOrEquals(ctx->oldest_fxid, fxid) && + FullTransactionIdPrecedes(fxid, ctx->next_fxid)); +} + +/* + * Checks whether a multitransaction ID is in the cached valid range, returning + * the nature of the range violation, if any. + */ +static XidBoundsViolation +check_mxid_in_range(MultiXactId mxid, HeapCheckContext *ctx) +{ + if (!TransactionIdIsValid(mxid)) + return XID_INVALID; + if (MultiXactIdPrecedes(mxid, ctx->relminmxid)) + return XID_PRECEDES_RELMIN; + if (MultiXactIdPrecedes(mxid, ctx->oldest_mxact)) + return XID_PRECEDES_CLUSTERMIN; + if (MultiXactIdPrecedesOrEquals(ctx->next_mxact, mxid)) + return XID_IN_FUTURE; + return XID_BOUNDS_OK; +} + +/* + * Checks whether the given mxid is valid to appear in the heap being checked, + * returning the nature of the range violation, if any. + * + * This function attempts to return quickly by caching the known valid mxid + * range in ctx. Callers should already have performed the initial setup of + * the cache prior to the first call to this function. + */ +static XidBoundsViolation +check_mxid_valid_in_rel(MultiXactId mxid, HeapCheckContext *ctx) +{ + XidBoundsViolation result; + + result = check_mxid_in_range(mxid, ctx); + if (result == XID_BOUNDS_OK) + return XID_BOUNDS_OK; + + /* The range may have advanced. Recheck. */ + update_cached_mxid_range(ctx); + return check_mxid_in_range(mxid, ctx); +} + +/* + * Checks whether the given transaction ID is (or was recently) valid to appear + * in the heap being checked, or whether it is too old or too new to appear in + * the relation, returning information about the nature of the bounds violation. + * + * We cache the range of valid transaction IDs. If xid is in that range, we + * conclude that it is valid, even though concurrent changes to the table might + * invalidate it under certain corrupt conditions. (For example, if the table + * contains corrupt all-frozen bits, a concurrent vacuum might skip the page(s) + * containing the xid and then truncate clog and advance the relfrozenxid + * beyond xid.) Reporting the xid as valid under such conditions seems + * acceptable, since if we had checked it earlier in our scan it would have + * truly been valid at that time. + * + * If the status argument is not NULL, and if and only if the transaction ID + * appears to be valid in this relation, the status argument will be set with + * the commit status of the transaction ID. + */ +static XidBoundsViolation +get_xid_status(TransactionId xid, HeapCheckContext *ctx, + XidCommitStatus *status) +{ + FullTransactionId fxid; + FullTransactionId clog_horizon; + + /* Quick check for special xids */ + if (!TransactionIdIsValid(xid)) + return XID_INVALID; + else if (xid == BootstrapTransactionId || xid == FrozenTransactionId) + { + if (status != NULL) + *status = XID_COMMITTED; + return XID_BOUNDS_OK; + } + + /* Check if the xid is within bounds */ + fxid = FullTransactionIdFromXidAndCtx(xid, ctx); + if (!fxid_in_cached_range(fxid, ctx)) + { + /* + * We may have been checking against stale values. Update the cached + * range to be sure, and since we relied on the cached range when we + * performed the full xid conversion, reconvert. + */ + update_cached_xid_range(ctx); + fxid = FullTransactionIdFromXidAndCtx(xid, ctx); + } + + if (FullTransactionIdPrecedesOrEquals(ctx->next_fxid, fxid)) + return XID_IN_FUTURE; + if (FullTransactionIdPrecedes(fxid, ctx->oldest_fxid)) + return XID_PRECEDES_CLUSTERMIN; + if (FullTransactionIdPrecedes(fxid, ctx->relfrozenfxid)) + return XID_PRECEDES_RELMIN; + + /* Early return if the caller does not request clog checking */ + if (status == NULL) + return XID_BOUNDS_OK; + + /* Early return if we just checked this xid in a prior call */ + if (xid == ctx->cached_xid) + { + *status = ctx->cached_status; + return XID_BOUNDS_OK; + } + + *status = XID_COMMITTED; + LWLockAcquire(XactTruncationLock, LW_SHARED); + clog_horizon = + FullTransactionIdFromXidAndCtx(ShmemVariableCache->oldestClogXid, + ctx); + if (FullTransactionIdPrecedesOrEquals(clog_horizon, fxid)) + { + if (TransactionIdIsCurrentTransactionId(xid)) + *status = XID_IS_CURRENT_XID; + else if (TransactionIdIsInProgress(xid)) + *status = XID_IN_PROGRESS; + else if (TransactionIdDidCommit(xid)) + *status = XID_COMMITTED; + else + *status = XID_ABORTED; + } + LWLockRelease(XactTruncationLock); + ctx->cached_xid = xid; + ctx->cached_status = *status; + return XID_BOUNDS_OK; +} diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index 5f3de3c0b7f6..fdfc320e84f9 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -14,7 +14,7 @@ * that every visible heap tuple has a matching index tuple. * * - * Copyright (c) 2017-2020, PostgreSQL Global Development Group + * Copyright (c) 2017-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/amcheck/verify_nbtree.c @@ -290,7 +290,7 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, if (heaprel == NULL || heapid != IndexGetRelation(indrelid, false)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("could not open parent table of index %s", + errmsg("could not open parent table of index \"%s\"", RelationGetRelationName(indrel)))); /* Relation suitable for checking as B-Tree? */ @@ -535,8 +535,8 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace, if (metad->btm_fastroot != metad->btm_root) ereport(DEBUG1, (errcode(ERRCODE_NO_DATA), - errmsg("harmless fast root mismatch in index %s", - RelationGetRelationName(rel)), + errmsg_internal("harmless fast root mismatch in index \"%s\"", + RelationGetRelationName(rel)), errdetail_internal("Fast root block %u (level %u) differs from true root block %u (level %u).", metad->btm_fastroot, metad->btm_fastlevel, metad->btm_root, metad->btm_level))); @@ -721,8 +721,8 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) else ereport(DEBUG1, (errcode(ERRCODE_NO_DATA), - errmsg("block %u of index \"%s\" ignored", - current, RelationGetRelationName(state->rel)))); + errmsg_internal("block %u of index \"%s\" concurrently deleted", + current, RelationGetRelationName(state->rel)))); goto nextpage; } else if (nextleveldown.leftmost == InvalidBlockNumber) @@ -769,7 +769,7 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) P_FIRSTDATAKEY(opaque)); itup = (IndexTuple) PageGetItem(state->target, itemid); nextleveldown.leftmost = BTreeTupleGetDownLink(itup); - nextleveldown.level = opaque->btpo.level - 1; + nextleveldown.level = opaque->btpo_level - 1; } else { @@ -794,14 +794,14 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) if (opaque->btpo_prev != leftcurrent) bt_recheck_sibling_links(state, opaque->btpo_prev, leftcurrent); - /* Check level, which must be valid for non-ignorable page */ - if (level.level != opaque->btpo.level) + /* Check level */ + if (level.level != opaque->btpo_level) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg("leftmost down link for level points to block in index \"%s\" whose level is not one level down", RelationGetRelationName(state->rel)), errdetail_internal("Block pointed to=%u expected level=%u level in pointed to block=%u.", - current, level.level, opaque->btpo.level))); + current, level.level, opaque->btpo_level))); /* Verify invariants for page */ bt_target_page_check(state); @@ -918,7 +918,7 @@ bt_recheck_sibling_links(BtreeCheckState *state, Buffer newtargetbuf; Page page; BTPageOpaque opaque; - BlockNumber newtargetblock; + BlockNumber newtargetblock; /* Couple locks in the usual order for nbtree: Left to right */ lbuf = ReadBufferExtended(state->rel, MAIN_FORKNUM, leftcurrent, @@ -979,8 +979,8 @@ bt_recheck_sibling_links(BtreeCheckState *state, /* Report split in left sibling, not target (or new target) */ ereport(DEBUG1, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("harmless concurrent page split detected in index \"%s\"", - RelationGetRelationName(state->rel)), + errmsg_internal("harmless concurrent page split detected in index \"%s\"", + RelationGetRelationName(state->rel)), errdetail_internal("Block=%u new right sibling=%u original right sibling=%u.", leftcurrent, newtargetblock, state->targetblock))); @@ -1078,8 +1078,7 @@ bt_target_page_check(BtreeCheckState *state) state->targetblock, BTreeTupleGetNAtts(itup, state->rel), P_ISLEAF(topaque) ? "heap" : "index", - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } } @@ -1120,8 +1119,7 @@ bt_target_page_check(BtreeCheckState *state) errdetail_internal("Index tid=(%u,%u) tuple size=%zu lp_len=%u page lsn=%X/%X.", state->targetblock, offset, tupsize, ItemIdGetLength(itemid), - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn), + LSN_FORMAT_ARGS(state->targetlsn)), errhint("This could be a torn page problem."))); /* Check the number of index tuple attributes */ @@ -1147,8 +1145,7 @@ bt_target_page_check(BtreeCheckState *state) BTreeTupleGetNAtts(itup, state->rel), P_ISLEAF(topaque) ? "heap" : "index", htid, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } /* @@ -1167,7 +1164,7 @@ bt_target_page_check(BtreeCheckState *state) bt_child_highkey_check(state, offset, NULL, - topaque->btpo.level); + topaque->btpo_level); } continue; } @@ -1195,8 +1192,7 @@ bt_target_page_check(BtreeCheckState *state) RelationGetRelationName(state->rel)), errdetail_internal("Index tid=%s points to heap tid=%s page lsn=%X/%X.", itid, htid, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } /* @@ -1225,8 +1221,7 @@ bt_target_page_check(BtreeCheckState *state) RelationGetRelationName(state->rel)), errdetail_internal("Index tid=%s posting list offset=%d page lsn=%X/%X.", itid, i, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } ItemPointerCopy(current, &last); @@ -1282,8 +1277,7 @@ bt_target_page_check(BtreeCheckState *state) itid, P_ISLEAF(topaque) ? "heap" : "index", htid, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } /* Fingerprint leaf page tuples (those that point to the heap) */ @@ -1390,8 +1384,7 @@ bt_target_page_check(BtreeCheckState *state) itid, P_ISLEAF(topaque) ? "heap" : "index", htid, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } /* Reset, in case scantid was set to (itup) posting tuple's max TID */ skey->scantid = scantid; @@ -1442,8 +1435,7 @@ bt_target_page_check(BtreeCheckState *state) nitid, P_ISLEAF(topaque) ? "heap" : "index", nhtid, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } /* @@ -1500,8 +1492,7 @@ bt_target_page_check(BtreeCheckState *state) RelationGetRelationName(state->rel)), errdetail_internal("Last item on page tid=(%u,%u) page lsn=%X/%X.", state->targetblock, offset, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } } @@ -1529,7 +1520,7 @@ bt_target_page_check(BtreeCheckState *state) if (!P_ISLEAF(topaque) && P_RIGHTMOST(topaque) && state->readonly) { bt_child_highkey_check(state, InvalidOffsetNumber, - NULL, topaque->btpo.level); + NULL, topaque->btpo_level); } } @@ -1601,14 +1592,18 @@ bt_right_page_check_scankey(BtreeCheckState *state) if (!P_IGNORE(opaque) || P_RIGHTMOST(opaque)) break; - /* We landed on a deleted page, so step right to find a live page */ - targetnext = opaque->btpo_next; - ereport(DEBUG1, + /* + * We landed on a deleted or half-dead sibling page. Step right until + * we locate a live sibling page. + */ + ereport(DEBUG2, (errcode(ERRCODE_NO_DATA), - errmsg("level %u leftmost page of index \"%s\" was found deleted or half dead", - opaque->btpo.level, RelationGetRelationName(state->rel)), + errmsg_internal("level %u sibling page in block %u of index \"%s\" was found deleted or half dead", + opaque->btpo_level, targetnext, RelationGetRelationName(state->rel)), errdetail_internal("Deleted page found when building scankey from right sibling."))); + targetnext = opaque->btpo_next; + /* Be slightly more pro-active in freeing this memory, just in case */ pfree(rightpage); } @@ -1731,11 +1726,11 @@ bt_right_page_check_scankey(BtreeCheckState *state) * possible that it's an internal page with only a negative infinity * item. */ - ereport(DEBUG1, + ereport(DEBUG2, (errcode(ERRCODE_NO_DATA), - errmsg("%s block %u of index \"%s\" has no first data item", - P_ISLEAF(opaque) ? "leaf" : "internal", targetnext, - RelationGetRelationName(state->rel)))); + errmsg_internal("%s block %u of index \"%s\" has no first data item", + P_ISLEAF(opaque) ? "leaf" : "internal", targetnext, + RelationGetRelationName(state->rel)))); return NULL; } @@ -1752,14 +1747,36 @@ bt_right_page_check_scankey(BtreeCheckState *state) * this function is capable to compare pivot keys on different levels. */ static bool -bt_pivot_tuple_identical(IndexTuple itup1, IndexTuple itup2) +bt_pivot_tuple_identical(bool heapkeyspace, IndexTuple itup1, IndexTuple itup2) { if (IndexTupleSize(itup1) != IndexTupleSize(itup2)) return false; - if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid, - IndexTupleSize(itup1) - offsetof(ItemPointerData, ip_posid)) != 0) - return false; + if (heapkeyspace) + { + /* + * Offset number will contain important information in heapkeyspace + * indexes: the number of attributes left in the pivot tuple following + * suffix truncation. Don't skip over it (compare it too). + */ + if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid, + IndexTupleSize(itup1) - + offsetof(ItemPointerData, ip_posid)) != 0) + return false; + } + else + { + /* + * Cannot rely on offset number field having consistent value across + * levels on pg_upgrade'd !heapkeyspace indexes. Compare contents of + * tuple starting from just after item pointer (i.e. after block + * number and offset number). + */ + if (memcmp(&itup1->t_info, &itup2->t_info, + IndexTupleSize(itup1) - + offsetof(IndexTupleData, t_info)) != 0) + return false; + } return true; } @@ -1885,17 +1902,17 @@ bt_child_highkey_check(BtreeCheckState *state, RelationGetRelationName(state->rel)), errdetail_internal("Target block=%u child block=%u target page lsn=%X/%X.", state->targetblock, blkno, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); - /* Check level for non-ignorable page */ - if (!P_IGNORE(opaque) && opaque->btpo.level != target_level - 1) + /* Do level sanity check */ + if ((!P_ISDELETED(opaque) || P_HAS_FULLXID(opaque)) && + opaque->btpo_level != target_level - 1) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg("block found while following rightlinks from child of index \"%s\" has invalid level", RelationGetRelationName(state->rel)), errdetail_internal("Block pointed to=%u expected level=%u level in pointed to block=%u.", - blkno, target_level - 1, opaque->btpo.level))); + blkno, target_level - 1, opaque->btpo_level))); /* Try to detect circular links */ if ((!first && blkno == state->prevrightlink) || blkno == opaque->btpo_prev) @@ -1913,7 +1930,7 @@ bt_child_highkey_check(BtreeCheckState *state, rightsplit = P_INCOMPLETE_SPLIT(opaque); /* - * If we visit page with high key, check that it is be equal to the + * If we visit page with high key, check that it is equal to the * target key next to corresponding downlink. */ if (!rightsplit && !P_RIGHTMOST(opaque)) @@ -1971,8 +1988,7 @@ bt_child_highkey_check(BtreeCheckState *state, RelationGetRelationName(state->rel)), errdetail_internal("Target block=%u child block=%u target page lsn=%X/%X.", state->targetblock, blkno, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); pivotkey_offset = P_HIKEY; } itemid = PageGetItemIdCareful(state, state->targetblock, @@ -2002,12 +2018,11 @@ bt_child_highkey_check(BtreeCheckState *state, RelationGetRelationName(state->rel)), errdetail_internal("Target block=%u child block=%u target page lsn=%X/%X.", state->targetblock, blkno, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); itup = state->lowkey; } - if (!bt_pivot_tuple_identical(highkey, itup)) + if (!bt_pivot_tuple_identical(state->heapkeyspace, highkey, itup)) { ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), @@ -2015,8 +2030,7 @@ bt_child_highkey_check(BtreeCheckState *state, RelationGetRelationName(state->rel)), errdetail_internal("Target block=%u child block=%u target page lsn=%X/%X.", state->targetblock, blkno, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } } @@ -2123,7 +2137,7 @@ bt_child_check(BtreeCheckState *state, BTScanInsert targetkey, * check for downlink connectivity. */ bt_child_highkey_check(state, downlinkoffnum, - child, topaque->btpo.level); + child, topaque->btpo_level); /* * Since there cannot be a concurrent VACUUM operation in readonly mode, @@ -2156,8 +2170,7 @@ bt_child_check(BtreeCheckState *state, BTScanInsert targetkey, RelationGetRelationName(state->rel)), errdetail_internal("Parent block=%u child block=%u parent page lsn=%X/%X.", state->targetblock, childblock, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); for (offset = P_FIRSTDATAKEY(copaque); offset <= maxoffset; @@ -2198,8 +2211,7 @@ bt_child_check(BtreeCheckState *state, BTScanInsert targetkey, RelationGetRelationName(state->rel)), errdetail_internal("Parent block=%u child index tid=(%u,%u) parent page lsn=%X/%X.", state->targetblock, childblock, offset, - (uint32) (state->targetlsn >> 32), - (uint32) state->targetlsn))); + LSN_FORMAT_ARGS(state->targetlsn)))); } pfree(child); @@ -2265,13 +2277,12 @@ bt_downlink_missing_check(BtreeCheckState *state, bool rightsplit, { ereport(DEBUG1, (errcode(ERRCODE_NO_DATA), - errmsg("harmless interrupted page split detected in index %s", - RelationGetRelationName(state->rel)), + errmsg_internal("harmless interrupted page split detected in index \"%s\"", + RelationGetRelationName(state->rel)), errdetail_internal("Block=%u level=%u left sibling=%u page lsn=%X/%X.", - blkno, opaque->btpo.level, + blkno, opaque->btpo_level, opaque->btpo_prev, - (uint32) (pagelsn >> 32), - (uint32) pagelsn))); + LSN_FORMAT_ARGS(pagelsn)))); return; } @@ -2292,14 +2303,13 @@ bt_downlink_missing_check(BtreeCheckState *state, bool rightsplit, RelationGetRelationName(state->rel)), errdetail_internal("Block=%u page lsn=%X/%X.", blkno, - (uint32) (pagelsn >> 32), - (uint32) pagelsn))); + LSN_FORMAT_ARGS(pagelsn)))); /* Descend from the given page, which is an internal page */ elog(DEBUG1, "checking for interrupted multi-level deletion due to missing downlink in index \"%s\"", RelationGetRelationName(state->rel)); - level = opaque->btpo.level; + level = opaque->btpo_level; itemid = PageGetItemIdCareful(state, blkno, page, P_FIRSTDATAKEY(opaque)); itup = (IndexTuple) PageGetItem(page, itemid); childblk = BTreeTupleGetDownLink(itup); @@ -2314,16 +2324,16 @@ bt_downlink_missing_check(BtreeCheckState *state, bool rightsplit, break; /* Do an extra sanity check in passing on internal pages */ - if (copaque->btpo.level != level - 1) + if (copaque->btpo_level != level - 1) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg_internal("downlink points to block in index \"%s\" whose level is not one level down", RelationGetRelationName(state->rel)), errdetail_internal("Top parent/under check block=%u block pointed to=%u expected level=%u level in pointed to block=%u.", blkno, childblk, - level - 1, copaque->btpo.level))); + level - 1, copaque->btpo_level))); - level = copaque->btpo.level; + level = copaque->btpo_level; itemid = PageGetItemIdCareful(state, childblk, child, P_FIRSTDATAKEY(copaque)); itup = (IndexTuple) PageGetItem(child, itemid); @@ -2359,8 +2369,7 @@ bt_downlink_missing_check(BtreeCheckState *state, bool rightsplit, RelationGetRelationName(state->rel)), errdetail_internal("Top parent/target block=%u leaf block=%u top parent/under check lsn=%X/%X.", blkno, childblk, - (uint32) (pagelsn >> 32), - (uint32) pagelsn))); + LSN_FORMAT_ARGS(pagelsn)))); /* * Iff leaf page is half-dead, its high key top parent link should point @@ -2385,9 +2394,8 @@ bt_downlink_missing_check(BtreeCheckState *state, bool rightsplit, errmsg("internal index block lacks downlink in index \"%s\"", RelationGetRelationName(state->rel)), errdetail_internal("Block=%u level=%u page lsn=%X/%X.", - blkno, opaque->btpo.level, - (uint32) (pagelsn >> 32), - (uint32) pagelsn))); + blkno, opaque->btpo_level, + LSN_FORMAT_ARGS(pagelsn)))); } /* @@ -2980,21 +2988,28 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) } /* - * Deleted pages have no sane "level" field, so can only check non-deleted - * page level + * Deleted pages that still use the old 32-bit XID representation have no + * sane "level" field because they type pun the field, but all other pages + * (including pages deleted on Postgres 14+) have a valid value. */ - if (P_ISLEAF(opaque) && !P_ISDELETED(opaque) && opaque->btpo.level != 0) - ereport(ERROR, - (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("invalid leaf page level %u for block %u in index \"%s\"", - opaque->btpo.level, blocknum, RelationGetRelationName(state->rel)))); + if (!P_ISDELETED(opaque) || P_HAS_FULLXID(opaque)) + { + /* Okay, no reason not to trust btpo_level field from page */ - if (!P_ISLEAF(opaque) && !P_ISDELETED(opaque) && - opaque->btpo.level == 0) - ereport(ERROR, - (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("invalid internal page level 0 for block %u in index \"%s\"", - blocknum, RelationGetRelationName(state->rel)))); + if (P_ISLEAF(opaque) && opaque->btpo_level != 0) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("invalid leaf page level %u for block %u in index \"%s\"", + opaque->btpo_level, blocknum, + RelationGetRelationName(state->rel)))); + + if (!P_ISLEAF(opaque) && opaque->btpo_level == 0) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("invalid internal page level 0 for block %u in index \"%s\"", + blocknum, + RelationGetRelationName(state->rel)))); + } /* * Sanity checks for number of items on page. @@ -3041,8 +3056,6 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) * state. This state is nonetheless treated as corruption by VACUUM on * from version 9.4 on, so do the same here. See _bt_pagedel() for full * details. - * - * Internal pages should never have garbage items, either. */ if (!P_ISLEAF(opaque) && P_ISHALFDEAD(opaque)) ereport(ERROR, @@ -3051,11 +3064,27 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) blocknum, RelationGetRelationName(state->rel)), errhint("This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it."))); + /* + * Check that internal pages have no garbage items, and that no page has + * an invalid combination of deletion-related page level flags + */ if (!P_ISLEAF(opaque) && P_HAS_GARBAGE(opaque)) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("internal page block %u in index \"%s\" has garbage items", - blocknum, RelationGetRelationName(state->rel)))); + errmsg_internal("internal page block %u in index \"%s\" has garbage items", + blocknum, RelationGetRelationName(state->rel)))); + + if (P_HAS_FULLXID(opaque) && !P_ISDELETED(opaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("full transaction id page flag appears in non-deleted block %u in index \"%s\"", + blocknum, RelationGetRelationName(state->rel)))); + + if (P_ISDELETED(opaque) && P_ISHALFDEAD(opaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("deleted page block %u in index \"%s\" is half-dead", + blocknum, RelationGetRelationName(state->rel)))); return page; } @@ -3105,7 +3134,7 @@ PageGetItemIdCareful(BtreeCheckState *state, BlockNumber block, Page page, ItemId itemid = PageGetItemId(page, offset); if (ItemIdGetOffset(itemid) + ItemIdGetLength(itemid) > - BLCKSZ - sizeof(BTPageOpaqueData)) + BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg("line pointer points past end of tuple space in index \"%s\"", diff --git a/contrib/auth_delay/auth_delay.c b/contrib/auth_delay/auth_delay.c index 11c2f059e4c5..5820ac328db1 100644 --- a/contrib/auth_delay/auth_delay.c +++ b/contrib/auth_delay/auth_delay.c @@ -2,7 +2,7 @@ * * auth_delay.c * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/auth_delay/auth_delay.c diff --git a/contrib/auto_explain/auto_explain.c b/contrib/auto_explain/auto_explain.c index cd717b144e0d..4dfc2bf3a216 100644 --- a/contrib/auto_explain/auto_explain.c +++ b/contrib/auto_explain/auto_explain.c @@ -3,7 +3,7 @@ * auto_explain.c * * - * Copyright (c) 2008-2020, PostgreSQL Global Development Group + * Copyright (c) 2008-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/auto_explain/auto_explain.c @@ -335,7 +335,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags) MemoryContext oldcxt; oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt); - queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL); + queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL, false); MemoryContextSwitchTo(oldcxt); } } @@ -392,12 +392,19 @@ explain_ExecutorEnd(QueryDesc *queryDesc) { if (queryDesc->totaltime && auto_explain_enabled()) { + MemoryContext oldcxt; double msec; /* Wait for completion of all qExec processes. */ if (queryDesc->estate->dispatcherState && queryDesc->estate->dispatcherState->primaryResults) cdbdisp_checkDispatchResult(queryDesc->estate->dispatcherState, DISPATCH_WAIT_NONE); + /* + * Make sure we operate in the per-query context, so any cruft will be + * discarded later during ExecutorEnd. + */ + oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt); + /* * Make sure stats accumulation is done. (Note: it's okay if several * levels of hook all do this.) @@ -451,9 +458,9 @@ explain_ExecutorEnd(QueryDesc *queryDesc) (errmsg("duration: %.3f ms plan:\n%s", msec, es->str->data), errhidestmt(true))); - - pfree(es->str->data); } + + MemoryContextSwitchTo(oldcxt); } if (prev_ExecutorEnd) diff --git a/contrib/auto_explain/t/001_auto_explain.pl b/contrib/auto_explain/t/001_auto_explain.pl new file mode 100644 index 000000000000..9c4f1d057135 --- /dev/null +++ b/contrib/auto_explain/t/001_auto_explain.pl @@ -0,0 +1,55 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgresNode; +use TestLib; +use Test::More tests => 4; + +my $node = get_new_node('main'); +$node->init; +$node->append_conf('postgresql.conf', + "shared_preload_libraries = 'auto_explain'"); +$node->append_conf('postgresql.conf', "auto_explain.log_min_duration = 0"); +$node->append_conf('postgresql.conf', "auto_explain.log_analyze = on"); +$node->start; + +# run a couple of queries +$node->safe_psql("postgres", "SELECT * FROM pg_class;"); +$node->safe_psql("postgres", + "SELECT * FROM pg_proc WHERE proname = 'int4pl';"); + +# emit some json too +$node->append_conf('postgresql.conf', "auto_explain.log_format = json"); +$node->reload; +$node->safe_psql("postgres", "SELECT * FROM pg_proc;"); +$node->safe_psql("postgres", + "SELECT * FROM pg_class WHERE relname = 'pg_class';"); + +$node->stop('fast'); + +my $log = $node->logfile(); + +my $log_contents = slurp_file($log); + +like( + $log_contents, + qr/Seq Scan on pg_class/, + "sequential scan logged, text mode"); + +like( + $log_contents, + qr/Index Scan using pg_proc_proname_args_nsp_index on pg_proc/, + "index scan logged, text mode"); + +like( + $log_contents, + qr/"Node Type": "Seq Scan"[^}]*"Relation Name": "pg_proc"/s, + "sequential scan logged, json mode"); + +like( + $log_contents, + qr/"Node Type": "Index Scan"[^}]*"Index Name": "pg_class_relname_nsp_index"/s, + "index scan logged, json mode"); diff --git a/contrib/bloom/blcost.c b/contrib/bloom/blcost.c index 54f954dce8c9..4af1fc9e1cc0 100644 --- a/contrib/bloom/blcost.c +++ b/contrib/bloom/blcost.c @@ -3,7 +3,7 @@ * blcost.c * Cost estimate function for bloom indexes. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blcost.c diff --git a/contrib/bloom/blinsert.c b/contrib/bloom/blinsert.c index 6d3fd5c432cd..c34a640d1c44 100644 --- a/contrib/bloom/blinsert.c +++ b/contrib/bloom/blinsert.c @@ -3,7 +3,7 @@ * blinsert.c * Bloom index build and insert functions. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blinsert.c @@ -63,7 +63,6 @@ flushCachedPage(Relation index, BloomBuildState *buildstate) static void initCachedPage(BloomBuildState *buildstate) { - memset(buildstate->data.data, 0, BLCKSZ); BloomInitPage(buildstate->data.data, 0); buildstate->count = 0; } @@ -198,6 +197,7 @@ bool blinsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { BloomState blstate; diff --git a/contrib/bloom/bloom.h b/contrib/bloom/bloom.h index d1382b13c4b8..4c92e1a77100 100644 --- a/contrib/bloom/bloom.h +++ b/contrib/bloom/bloom.h @@ -3,7 +3,7 @@ * bloom.h * Header for bloom index. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/bloom.h @@ -192,6 +192,7 @@ extern bool blvalidate(Oid opclassoid); extern bool blinsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, struct IndexInfo *indexInfo); extern IndexScanDesc blbeginscan(Relation r, int nkeys, int norderbys); extern int64 blgetbitmap(IndexScanDesc scan, Node **bmNodeP); diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c index bd3c12ea594c..569f1503e581 100644 --- a/contrib/bloom/blscan.c +++ b/contrib/bloom/blscan.c @@ -3,7 +3,7 @@ * blscan.c * Bloom index scan functions. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blscan.c diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index 26b9927c3aaf..754de008d43f 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -3,7 +3,7 @@ * blutils.c * Bloom index utilities. * - * Portions Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1990-1993, Regents of the University of California * * IDENTIFICATION @@ -411,7 +411,6 @@ BloomInitPage(Page page, uint16 flags) PageInit(page, BLCKSZ, sizeof(BloomPageOpaqueData)); opaque = BloomPageGetOpaque(page); - memset(opaque, 0, sizeof(BloomPageOpaqueData)); opaque->flags = flags; opaque->bloom_page_id = BLOOM_PAGE_ID; } diff --git a/contrib/bloom/blvacuum.c b/contrib/bloom/blvacuum.c index 3282adde03b1..88b0a6d29002 100644 --- a/contrib/bloom/blvacuum.c +++ b/contrib/bloom/blvacuum.c @@ -3,7 +3,7 @@ * blvacuum.c * Bloom VACUUM functions. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blvacuum.c diff --git a/contrib/bloom/blvalidate.c b/contrib/bloom/blvalidate.c index 3c05e5b01c99..aa8c87c07727 100644 --- a/contrib/bloom/blvalidate.c +++ b/contrib/bloom/blvalidate.c @@ -3,7 +3,7 @@ * blvalidate.c * Opclass validator for bloom. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blvalidate.c diff --git a/contrib/bloom/t/001_wal.pl b/contrib/bloom/t/001_wal.pl index 7f6398f57129..9310af5c3dd8 100644 --- a/contrib/bloom/t/001_wal.pl +++ b/contrib/bloom/t/001_wal.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Test generic xlog record work for bloom index replication. use strict; use warnings; diff --git a/contrib/bool_plperl/expected/bool_plperl.out b/contrib/bool_plperl/expected/bool_plperl.out index 84c25acdb4f8..187df8db96f9 100644 --- a/contrib/bool_plperl/expected/bool_plperl.out +++ b/contrib/bool_plperl/expected/bool_plperl.out @@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p; --- test transforming to perl CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void LANGUAGE plperl -TRANSFORM FOR TYPE bool +TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils AS $$ my ($x, $y, $z) = @_; @@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL); (1 row) +--- test ruleutils +\sf bool2perl +CREATE OR REPLACE FUNCTION public.bool2perl(boolean, boolean, boolean) + RETURNS void + TRANSFORM FOR TYPE boolean, FOR TYPE boolean + LANGUAGE plperl +AS $function$ +my ($x, $y, $z) = @_; + +die("NULL mistransformed") if (defined($z)); +die("TRUE mistransformed to UNDEF") if (!defined($x)); +die("FALSE mistransformed to UNDEF") if (!defined($y)); +die("TRUE mistransformed") if (!$x); +die("FALSE mistransformed") if ($y); +$function$ --- test selecting bool through SPI CREATE FUNCTION spi_test() RETURNS void LANGUAGE plperl diff --git a/contrib/bool_plperl/expected/bool_plperlu.out b/contrib/bool_plperl/expected/bool_plperlu.out index 745ba9893386..8337d337e992 100644 --- a/contrib/bool_plperl/expected/bool_plperlu.out +++ b/contrib/bool_plperl/expected/bool_plperlu.out @@ -52,7 +52,7 @@ SELECT perl2undef() IS NULL AS p; --- test transforming to perl CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void LANGUAGE plperlu -TRANSFORM FOR TYPE bool +TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils AS $$ my ($x, $y, $z) = @_; @@ -68,6 +68,21 @@ SELECT bool2perl (true, false, NULL); (1 row) +--- test ruleutils +\sf bool2perl +CREATE OR REPLACE FUNCTION public.bool2perl(boolean, boolean, boolean) + RETURNS void + TRANSFORM FOR TYPE boolean, FOR TYPE boolean + LANGUAGE plperlu +AS $function$ +my ($x, $y, $z) = @_; + +die("NULL mistransformed") if (defined($z)); +die("TRUE mistransformed to UNDEF") if (!defined($x)); +die("FALSE mistransformed to UNDEF") if (!defined($y)); +die("TRUE mistransformed") if (!$x); +die("FALSE mistransformed") if ($y); +$function$ --- test selecting bool through SPI CREATE FUNCTION spi_test() RETURNS void LANGUAGE plperlu diff --git a/contrib/bool_plperl/sql/bool_plperl.sql b/contrib/bool_plperl/sql/bool_plperl.sql index dd99f545ea98..b7f570862cee 100644 --- a/contrib/bool_plperl/sql/bool_plperl.sql +++ b/contrib/bool_plperl/sql/bool_plperl.sql @@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p; CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void LANGUAGE plperl -TRANSFORM FOR TYPE bool +TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils AS $$ my ($x, $y, $z) = @_; @@ -46,6 +46,10 @@ $$; SELECT bool2perl (true, false, NULL); +--- test ruleutils + +\sf bool2perl + --- test selecting bool through SPI CREATE FUNCTION spi_test() RETURNS void diff --git a/contrib/bool_plperl/sql/bool_plperlu.sql b/contrib/bool_plperl/sql/bool_plperlu.sql index b756b0be6768..1480a0433067 100644 --- a/contrib/bool_plperl/sql/bool_plperlu.sql +++ b/contrib/bool_plperl/sql/bool_plperlu.sql @@ -33,7 +33,7 @@ SELECT perl2undef() IS NULL AS p; CREATE FUNCTION bool2perl(bool, bool, bool) RETURNS void LANGUAGE plperlu -TRANSFORM FOR TYPE bool +TRANSFORM FOR TYPE bool, for type boolean -- duplicate to test ruleutils AS $$ my ($x, $y, $z) = @_; @@ -46,6 +46,10 @@ $$; SELECT bool2perl (true, false, NULL); +--- test ruleutils + +\sf bool2perl + --- test selecting bool through SPI CREATE FUNCTION spi_test() RETURNS void diff --git a/contrib/btree_gist/btree_numeric.c b/contrib/btree_gist/btree_numeric.c index d66901680e33..35e466cdd942 100644 --- a/contrib/btree_gist/btree_numeric.c +++ b/contrib/btree_gist/btree_numeric.c @@ -195,7 +195,7 @@ gbt_numeric_penalty(PG_FUNCTION_ARGS) } else { - Numeric nul = DatumGetNumeric(DirectFunctionCall1(int4_numeric, Int32GetDatum(0))); + Numeric nul = int64_to_numeric(0); *result = 0.0; diff --git a/contrib/cube/Makefile b/contrib/cube/Makefile index 54f609db1715..cf195506c717 100644 --- a/contrib/cube/Makefile +++ b/contrib/cube/Makefile @@ -7,7 +7,7 @@ OBJS = \ cubeparse.o EXTENSION = cube -DATA = cube--1.2.sql cube--1.2--1.3.sql cube--1.3--1.4.sql \ +DATA = cube--1.2.sql cube--1.2--1.3.sql cube--1.3--1.4.sql cube--1.4--1.5.sql \ cube--1.1--1.2.sql cube--1.0--1.1.sql PGFILEDESC = "cube - multidimensional cube data type" diff --git a/contrib/cube/cube--1.4--1.5.sql b/contrib/cube/cube--1.4--1.5.sql new file mode 100644 index 000000000000..4b5bf8d205e9 --- /dev/null +++ b/contrib/cube/cube--1.4--1.5.sql @@ -0,0 +1,21 @@ +/* contrib/cube/cube--1.4--1.5.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION cube UPDATE TO '1.5'" to load this file. \quit + +-- Remove @ and ~ +DROP OPERATOR @ (cube, cube); +DROP OPERATOR ~ (cube, cube); + +-- Add binary input/output handlers +CREATE FUNCTION cube_recv(internal) +RETURNS cube +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +CREATE FUNCTION cube_send(cube) +RETURNS bytea +AS 'MODULE_PATHNAME' +LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; + +ALTER TYPE cube SET ( RECEIVE = cube_recv, SEND = cube_send ); diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c index 6f810b26c5d6..a5d1ba673352 100644 --- a/contrib/cube/cube.c +++ b/contrib/cube/cube.c @@ -13,6 +13,7 @@ #include "access/gist.h" #include "access/stratnum.h" #include "cubedata.h" +#include "libpq/pqformat.h" #include "utils/array.h" #include "utils/float.h" @@ -31,6 +32,8 @@ PG_FUNCTION_INFO_V1(cube_in); PG_FUNCTION_INFO_V1(cube_a_f8_f8); PG_FUNCTION_INFO_V1(cube_a_f8); PG_FUNCTION_INFO_V1(cube_out); +PG_FUNCTION_INFO_V1(cube_send); +PG_FUNCTION_INFO_V1(cube_recv); PG_FUNCTION_INFO_V1(cube_f8); PG_FUNCTION_INFO_V1(cube_f8_f8); PG_FUNCTION_INFO_V1(cube_c_f8); @@ -319,6 +322,59 @@ cube_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(buf.data); } +/* + * cube_send - a binary output handler for cube type + */ +Datum +cube_send(PG_FUNCTION_ARGS) +{ + NDBOX *cube = PG_GETARG_NDBOX_P(0); + StringInfoData buf; + int32 i, + nitems = DIM(cube); + + pq_begintypsend(&buf); + pq_sendint32(&buf, cube->header); + if (!IS_POINT(cube)) + nitems += nitems; + /* for symmetry with cube_recv, we don't use LL_COORD/UR_COORD here */ + for (i = 0; i < nitems; i++) + pq_sendfloat8(&buf, cube->x[i]); + + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} + +/* + * cube_recv - a binary input handler for cube type + */ +Datum +cube_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int32 header; + int32 i, + nitems; + NDBOX *cube; + + header = pq_getmsgint(buf, sizeof(int32)); + nitems = (header & DIM_MASK); + if (nitems > CUBE_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("cube dimension is too large"), + errdetail("A cube cannot have more than %d dimensions.", + CUBE_MAX_DIM))); + if ((header & POINT_BIT) == 0) + nitems += nitems; + cube = palloc(offsetof(NDBOX, x) + sizeof(double) * nitems); + SET_VARSIZE(cube, offsetof(NDBOX, x) + sizeof(double) * nitems); + cube->header = header; + for (i = 0; i < nitems; i++) + cube->x[i] = pq_getmsgfloat8(buf); + + PG_RETURN_NDBOX_P(cube); +} + /***************************************************************************** * GiST functions diff --git a/contrib/cube/cube.control b/contrib/cube/cube.control index 3e238fc9374a..50427ec1170f 100644 --- a/contrib/cube/cube.control +++ b/contrib/cube/cube.control @@ -1,6 +1,6 @@ # cube extension comment = 'data type for multidimensional cubes' -default_version = '1.4' +default_version = '1.5' module_pathname = '$libdir/cube' relocatable = true trusted = true diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index cbf9eddd8f46..11b95ccff9f6 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -9,7 +9,7 @@ * Shridhar Daithankar * * contrib/dblink/dblink.c - * Copyright (c) 2001-2020, PostgreSQL Global Development Group + * Copyright (c) 2001-2021, PostgreSQL Global Development Group * ALL RIGHTS RESERVED; * * Permission to use, copy, modify, and distribute this software and its @@ -38,7 +38,6 @@ #include "access/relation.h" #include "access/reloptions.h" #include "access/table.h" -#include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_foreign_data_wrapper.h" #include "catalog/pg_foreign_server.h" @@ -2608,7 +2607,8 @@ createConnHash(void) ctl.keysize = NAMEDATALEN; ctl.entrysize = sizeof(remoteConnHashEnt); - return hash_create("Remote Con hash", NUMCONN, &ctl, HASH_ELEM); + return hash_create("Remote Con hash", NUMCONN, &ctl, + HASH_ELEM | HASH_STRINGS); } static void diff --git a/contrib/dblink/input/paths.source b/contrib/dblink/input/paths.source index aab3a3b2bfb4..881a65314f34 100644 --- a/contrib/dblink/input/paths.source +++ b/contrib/dblink/input/paths.source @@ -1,8 +1,8 @@ -- Initialization that requires path substitution. -CREATE FUNCTION putenv(text) +CREATE FUNCTION setenv(text, text) RETURNS void - AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv' + AS '@libdir@/regress@DLSUFFIX@', 'regress_setenv' LANGUAGE C STRICT; CREATE FUNCTION wait_pid(int) @@ -11,4 +11,4 @@ CREATE FUNCTION wait_pid(int) LANGUAGE C STRICT; CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL - AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$; + AS $$SELECT setenv('PGSERVICEFILE', '@abs_srcdir@/' || $1)$$; diff --git a/contrib/dblink/output/paths.source b/contrib/dblink/output/paths.source index e1097f0996fe..8ed95e1f7825 100644 --- a/contrib/dblink/output/paths.source +++ b/contrib/dblink/output/paths.source @@ -1,11 +1,11 @@ -- Initialization that requires path substitution. -CREATE FUNCTION putenv(text) +CREATE FUNCTION setenv(text, text) RETURNS void - AS '@libdir@/regress@DLSUFFIX@', 'regress_putenv' + AS '@libdir@/regress@DLSUFFIX@', 'regress_setenv' LANGUAGE C STRICT; CREATE FUNCTION wait_pid(int) RETURNS void AS '@libdir@/regress@DLSUFFIX@' LANGUAGE C STRICT; CREATE FUNCTION set_pgservicefile(text) RETURNS void LANGUAGE SQL - AS $$SELECT putenv('PGSERVICEFILE=@abs_srcdir@/' || $1)$$; + AS $$SELECT setenv('PGSERVICEFILE', '@abs_srcdir@/' || $1)$$; diff --git a/contrib/dict_int/dict_int.c b/contrib/dict_int/dict_int.c index a7e9890fcc4f..3c84208b11e3 100644 --- a/contrib/dict_int/dict_int.c +++ b/contrib/dict_int/dict_int.c @@ -3,7 +3,7 @@ * dict_int.c * Text search dictionary for integers * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/dict_int/dict_int.c diff --git a/contrib/dict_xsyn/dict_xsyn.c b/contrib/dict_xsyn/dict_xsyn.c index 1065d64ccb0a..79c4f18f409c 100644 --- a/contrib/dict_xsyn/dict_xsyn.c +++ b/contrib/dict_xsyn/dict_xsyn.c @@ -3,7 +3,7 @@ * dict_xsyn.c * Extended synonym dictionary * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/dict_xsyn/dict_xsyn.c diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c index cf5c53cb94bd..4534777ab3c2 100644 --- a/contrib/file_fdw/file_fdw.c +++ b/contrib/file_fdw/file_fdw.c @@ -3,7 +3,7 @@ * file_fdw.c * foreign-data wrapper for server-side flat files (or programs). * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/file_fdw/file_fdw.c @@ -106,7 +106,7 @@ typedef struct FileFdwExecutionState bool is_program; /* true if filename represents an OS command */ List *options; /* merged COPY options, excluding filename and * is_program */ - CopyState cstate; /* COPY execution state */ + CopyFromState cstate; /* COPY execution state */ } FileFdwExecutionState; /* @@ -270,13 +270,13 @@ file_fdw_validator(PG_FUNCTION_ARGS) * otherwise there'd still be a security hole. */ if (strcmp(def->defname, "filename") == 0 && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_SERVER_FILES)) + !is_member_of_role(GetUserId(), ROLE_PG_READ_SERVER_FILES)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("only superuser or a member of the pg_read_server_files role may specify the filename option of a file_fdw foreign table"))); if (strcmp(def->defname, "program") == 0 && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_EXECUTE_SERVER_PROGRAM)) + !is_member_of_role(GetUserId(), ROLE_PG_EXECUTE_SERVER_PROGRAM)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("only superuser or a member of the pg_execute_server_program role may specify the program option of a file_fdw foreign table"))); @@ -672,7 +672,7 @@ fileBeginForeignScan(ForeignScanState *node, int eflags) char *filename; bool is_program; List *options; - CopyState cstate; + CopyFromState cstate; FileFdwExecutionState *festate; /* @@ -741,9 +741,6 @@ fileIterateForeignScan(ForeignScanState *node) * * We can pass ExprContext = NULL because we read all columns from the * file, so no need to evaluate default expressions. - * - * We can also pass tupleOid = NULL because we don't allow oids for - * foreign tables. */ ExecClearTuple(slot); found = NextCopyFrom(festate->cstate, NULL, @@ -1015,7 +1012,7 @@ estimate_size(PlannerInfo *root, RelOptInfo *baserel, /* * Estimate the number of tuples in the file. */ - if (baserel->pages > 0) + if (baserel->tuples >= 0 && baserel->pages > 0) { /* * We have # of pages and # of tuples from pg_class (that is, from a @@ -1127,7 +1124,7 @@ file_acquire_sample_rows(Relation onerel, int elevel, char *filename; bool is_program; List *options; - CopyState cstate; + CopyFromState cstate; ErrorContextCallback errcallback; MemoryContext oldcontext = CurrentMemoryContext; MemoryContext tupcontext; diff --git a/contrib/fuzzystrmatch/fuzzystrmatch.c b/contrib/fuzzystrmatch/fuzzystrmatch.c index ccbb84b481ba..d237772a3b21 100644 --- a/contrib/fuzzystrmatch/fuzzystrmatch.c +++ b/contrib/fuzzystrmatch/fuzzystrmatch.c @@ -6,7 +6,7 @@ * Joe Conway * * contrib/fuzzystrmatch/fuzzystrmatch.c - * Copyright (c) 2001-2020, PostgreSQL Global Development Group + * Copyright (c) 2001-2021, PostgreSQL Global Development Group * ALL RIGHTS RESERVED; * * metaphone() diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile index 72376d900763..c4e339b57c1c 100644 --- a/contrib/hstore/Makefile +++ b/contrib/hstore/Makefile @@ -7,10 +7,12 @@ OBJS = \ hstore_gin.o \ hstore_gist.o \ hstore_io.o \ - hstore_op.o + hstore_op.o \ + hstore_subs.o EXTENSION = hstore DATA = hstore--1.4.sql \ + hstore--1.7--1.8.sql \ hstore--1.6--1.7.sql \ hstore--1.5--1.6.sql \ hstore--1.4--1.5.sql \ diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out index e596d77043a6..bc22588df9bb 100644 --- a/contrib/hstore/expected/hstore.out +++ b/contrib/hstore/expected/hstore.out @@ -1571,6 +1571,33 @@ select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_jso {"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}] (1 row) +-- Test subscripting +insert into test_json_agg default values; +select f2['d'], f2['x'] is null as x_isnull from test_json_agg; + f2 | x_isnull +--------+---------- + 12345 | t + -12345 | t + | t +(3 rows) + +select f2['d']['e'] from test_json_agg; -- error +ERROR: hstore allows only one subscript +select f2['d':'e'] from test_json_agg; -- error +ERROR: hstore allows only one subscript +update test_json_agg set f2['d'] = f2['e'], f2['x'] = 'xyzzy'; +select f2 from test_json_agg; + f2 +--------------------------------------------------------------------------------------------------------------------- + "b"=>"t", "c"=>NULL, "d"=>"012345", "e"=>"012345", "f"=>"1.234", "g"=>"2.345e+4", "x"=>"xyzzy", "a key"=>"1" + "b"=>"f", "c"=>"null", "d"=>"012345.6", "e"=>"012345.6", "f"=>"-1.234", "g"=>"0.345e-4", "x"=>"xyzzy", "a key"=>"2" + "d"=>NULL, "x"=>"xyzzy" +(3 rows) + +-- Test subscripting in plpgsql +do $$ declare h hstore; +begin h['a'] := 'b'; raise notice 'h = %, h[a] = %', h, h['a']; end $$; +NOTICE: h = "a"=>"b", h[a] = b -- Check the hstore_hash() and hstore_hash_extended() function explicitly. SELECT v as value, hstore_hash(v)::bit(32) as standard, hstore_hash_extended(v, 0)::bit(32) as extended0, diff --git a/contrib/hstore/hstore--1.7--1.8.sql b/contrib/hstore/hstore--1.7--1.8.sql new file mode 100644 index 000000000000..fb450a9d6ab1 --- /dev/null +++ b/contrib/hstore/hstore--1.7--1.8.sql @@ -0,0 +1,17 @@ +/* contrib/hstore/hstore--1.7--1.8.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION hstore UPDATE TO '1.8'" to load this file. \quit + +CREATE FUNCTION hstore_subscript_handler(internal) +RETURNS internal +AS 'MODULE_PATHNAME', 'hstore_subscript_handler' +LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; + +ALTER TYPE hstore SET ( + SUBSCRIPT = hstore_subscript_handler +); + +-- Remove @ and ~ +DROP OPERATOR @ (hstore, hstore); +DROP OPERATOR ~ (hstore, hstore); diff --git a/contrib/hstore/hstore.control b/contrib/hstore/hstore.control index f0da7724295c..89e3c746c461 100644 --- a/contrib/hstore/hstore.control +++ b/contrib/hstore/hstore.control @@ -1,6 +1,6 @@ # hstore extension comment = 'data type for storing sets of (key, value) pairs' -default_version = '1.7' +default_version = '1.8' module_pathname = '$libdir/hstore' relocatable = true trusted = true diff --git a/contrib/hstore/hstore_subs.c b/contrib/hstore/hstore_subs.c new file mode 100644 index 000000000000..ca4c174a5150 --- /dev/null +++ b/contrib/hstore/hstore_subs.c @@ -0,0 +1,297 @@ +/*------------------------------------------------------------------------- + * + * hstore_subs.c + * Subscripting support functions for hstore. + * + * This is a great deal simpler than array_subs.c, because the result of + * subscripting an hstore is just a text string (the value for the key). + * We do not need to support array slicing notation, nor multiple subscripts. + * Less obviously, because the subscript result is never a SQL container + * type, there will never be any nested-assignment scenarios, so we do not + * need a fetch_old function. In turn, that means we can drop the + * check_subscripts function and just let the fetch and assign functions + * do everything. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * contrib/hstore/hstore_subs.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "executor/execExpr.h" +#include "hstore.h" +#include "nodes/nodeFuncs.h" +#include "nodes/subscripting.h" +#include "parser/parse_coerce.h" +#include "parser/parse_expr.h" +#include "utils/builtins.h" + + +/* + * Finish parse analysis of a SubscriptingRef expression for hstore. + * + * Verify there's just one subscript, coerce it to text, + * and set the result type of the SubscriptingRef node. + */ +static void +hstore_subscript_transform(SubscriptingRef *sbsref, + List *indirection, + ParseState *pstate, + bool isSlice, + bool isAssignment) +{ + A_Indices *ai; + Node *subexpr; + + /* We support only single-subscript, non-slice cases */ + if (isSlice || list_length(indirection) != 1) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("hstore allows only one subscript"), + parser_errposition(pstate, + exprLocation((Node *) indirection)))); + + /* Transform the subscript expression to type text */ + ai = linitial_node(A_Indices, indirection); + Assert(ai->uidx != NULL && ai->lidx == NULL && !ai->is_slice); + + subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind); + /* If it's not text already, try to coerce */ + subexpr = coerce_to_target_type(pstate, + subexpr, exprType(subexpr), + TEXTOID, -1, + COERCION_ASSIGNMENT, + COERCE_IMPLICIT_CAST, + -1); + if (subexpr == NULL) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("hstore subscript must have type text"), + parser_errposition(pstate, exprLocation(ai->uidx)))); + + /* ... and store the transformed subscript into the SubscriptRef node */ + sbsref->refupperindexpr = list_make1(subexpr); + sbsref->reflowerindexpr = NIL; + + /* Determine the result type of the subscripting operation; always text */ + sbsref->refrestype = TEXTOID; + sbsref->reftypmod = -1; +} + +/* + * Evaluate SubscriptingRef fetch for hstore. + * + * Source container is in step's result variable (it's known not NULL, since + * we set fetch_strict to true), and the subscript expression is in the + * upperindex[] array. + */ +static void +hstore_subscript_fetch(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + HStore *hs; + text *key; + HEntry *entries; + int idx; + text *out; + + /* Should not get here if source hstore is null */ + Assert(!(*op->resnull)); + + /* Check for null subscript */ + if (sbsrefstate->upperindexnull[0]) + { + *op->resnull = true; + return; + } + + /* OK, fetch/detoast the hstore and subscript */ + hs = DatumGetHStoreP(*op->resvalue); + key = DatumGetTextPP(sbsrefstate->upperindex[0]); + + /* The rest is basically the same as hstore_fetchval() */ + entries = ARRPTR(hs); + idx = hstoreFindKey(hs, NULL, + VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key)); + + if (idx < 0 || HSTORE_VALISNULL(entries, idx)) + { + *op->resnull = true; + return; + } + + out = cstring_to_text_with_len(HSTORE_VAL(entries, STRPTR(hs), idx), + HSTORE_VALLEN(entries, idx)); + + *op->resvalue = PointerGetDatum(out); +} + +/* + * Evaluate SubscriptingRef assignment for hstore. + * + * Input container (possibly null) is in result area, replacement value is in + * SubscriptingRefState's replacevalue/replacenull. + */ +static void +hstore_subscript_assign(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + text *key; + Pairs p; + HStore *out; + + /* Check for null subscript */ + if (sbsrefstate->upperindexnull[0]) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("hstore subscript in assignment must not be null"))); + + /* OK, fetch/detoast the subscript */ + key = DatumGetTextPP(sbsrefstate->upperindex[0]); + + /* Create a Pairs entry for subscript + replacement value */ + p.needfree = false; + p.key = VARDATA_ANY(key); + p.keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(key)); + + if (sbsrefstate->replacenull) + { + p.vallen = 0; + p.isnull = true; + } + else + { + text *val = DatumGetTextPP(sbsrefstate->replacevalue); + + p.val = VARDATA_ANY(val); + p.vallen = hstoreCheckValLen(VARSIZE_ANY_EXHDR(val)); + p.isnull = false; + } + + if (*op->resnull) + { + /* Just build a one-element hstore (cf. hstore_from_text) */ + out = hstorePairs(&p, 1, p.keylen + p.vallen); + } + else + { + /* + * Otherwise, merge the new key into the hstore. Based on + * hstore_concat. + */ + HStore *hs = DatumGetHStoreP(*op->resvalue); + int s1count = HS_COUNT(hs); + int outcount = 0; + int vsize; + char *ps1, + *bufd, + *pd; + HEntry *es1, + *ed; + int s1idx; + int s2idx; + + /* Allocate result without considering possibility of duplicate */ + vsize = CALCDATASIZE(s1count + 1, VARSIZE(hs) + p.keylen + p.vallen); + out = palloc(vsize); + SET_VARSIZE(out, vsize); + HS_SETCOUNT(out, s1count + 1); + + ps1 = STRPTR(hs); + bufd = pd = STRPTR(out); + es1 = ARRPTR(hs); + ed = ARRPTR(out); + + for (s1idx = s2idx = 0; s1idx < s1count || s2idx < 1; ++outcount) + { + int difference; + + if (s1idx >= s1count) + difference = 1; + else if (s2idx >= 1) + difference = -1; + else + { + int s1keylen = HSTORE_KEYLEN(es1, s1idx); + int s2keylen = p.keylen; + + if (s1keylen == s2keylen) + difference = memcmp(HSTORE_KEY(es1, ps1, s1idx), + p.key, + s1keylen); + else + difference = (s1keylen > s2keylen) ? 1 : -1; + } + + if (difference >= 0) + { + HS_ADDITEM(ed, bufd, pd, p); + ++s2idx; + if (difference == 0) + ++s1idx; + } + else + { + HS_COPYITEM(ed, bufd, pd, + HSTORE_KEY(es1, ps1, s1idx), + HSTORE_KEYLEN(es1, s1idx), + HSTORE_VALLEN(es1, s1idx), + HSTORE_VALISNULL(es1, s1idx)); + ++s1idx; + } + } + + HS_FINALIZE(out, outcount, bufd, pd); + } + + *op->resvalue = PointerGetDatum(out); + *op->resnull = false; +} + +/* + * Set up execution state for an hstore subscript operation. + */ +static void +hstore_exec_setup(const SubscriptingRef *sbsref, + SubscriptingRefState *sbsrefstate, + SubscriptExecSteps *methods) +{ + /* Assert we are dealing with one subscript */ + Assert(sbsrefstate->numlower == 0); + Assert(sbsrefstate->numupper == 1); + /* We can't check upperprovided[0] here, but it must be true */ + + /* Pass back pointers to appropriate step execution functions */ + methods->sbs_check_subscripts = NULL; + methods->sbs_fetch = hstore_subscript_fetch; + methods->sbs_assign = hstore_subscript_assign; + methods->sbs_fetch_old = NULL; +} + +/* + * hstore_subscript_handler + * Subscripting handler for hstore. + */ +PG_FUNCTION_INFO_V1(hstore_subscript_handler); +Datum +hstore_subscript_handler(PG_FUNCTION_ARGS) +{ + static const SubscriptRoutines sbsroutines = { + .transform = hstore_subscript_transform, + .exec_setup = hstore_exec_setup, + .fetch_strict = true, /* fetch returns NULL for NULL inputs */ + .fetch_leakproof = true, /* fetch returns NULL for bad subscript */ + .store_leakproof = false /* ... but assignment throws error */ + }; + + PG_RETURN_POINTER(&sbsroutines); +} diff --git a/contrib/hstore/sql/hstore.sql b/contrib/hstore/sql/hstore.sql index 1143de010447..c7cea188bc29 100644 --- a/contrib/hstore/sql/hstore.sql +++ b/contrib/hstore/sql/hstore.sql @@ -369,6 +369,18 @@ insert into test_json_agg values ('rec1','"a key" =>1, b => t, c => null, d=> 12 select json_agg(q) from test_json_agg q; select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q; +-- Test subscripting +insert into test_json_agg default values; +select f2['d'], f2['x'] is null as x_isnull from test_json_agg; +select f2['d']['e'] from test_json_agg; -- error +select f2['d':'e'] from test_json_agg; -- error +update test_json_agg set f2['d'] = f2['e'], f2['x'] = 'xyzzy'; +select f2 from test_json_agg; + +-- Test subscripting in plpgsql +do $$ declare h hstore; +begin h['a'] := 'b'; raise notice 'h = %, h[a] = %', h, h['a']; end $$; + -- Check the hstore_hash() and hstore_hash_extended() function explicitly. SELECT v as value, hstore_hash(v)::bit(32) as standard, hstore_hash_extended(v, 0)::bit(32) as extended0, diff --git a/contrib/hstore_plpython/expected/hstore_plpython.out b/contrib/hstore_plpython/expected/hstore_plpython.out index 1ab5feea93d7..ecf1dd61bc17 100644 --- a/contrib/hstore_plpython/expected/hstore_plpython.out +++ b/contrib/hstore_plpython/expected/hstore_plpython.out @@ -47,19 +47,29 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']); (1 row) -- test python -> hstore -CREATE FUNCTION test2() RETURNS hstore +CREATE FUNCTION test2(a int, b text) RETURNS hstore LANGUAGE plpythonu TRANSFORM FOR TYPE hstore AS $$ -val = {'a': 1, 'b': 'boo', 'c': None} +val = {'a': a, 'b': b, 'c': None} return val $$; -SELECT test2(); +SELECT test2(1, 'boo'); test2 --------------------------------- "a"=>"1", "b"=>"boo", "c"=>NULL (1 row) +--- test ruleutils +\sf test2 +CREATE OR REPLACE FUNCTION public.test2(a integer, b text) + RETURNS hstore + TRANSFORM FOR TYPE hstore + LANGUAGE plpythonu +AS $function$ +val = {'a': a, 'b': b, 'c': None} +return val +$function$ -- test python -> hstore[] CREATE FUNCTION test2arr() RETURNS hstore[] LANGUAGE plpythonu diff --git a/contrib/hstore_plpython/sql/hstore_plpython.sql b/contrib/hstore_plpython/sql/hstore_plpython.sql index 2c54ee6aaad2..b6d98b7dd537 100644 --- a/contrib/hstore_plpython/sql/hstore_plpython.sql +++ b/contrib/hstore_plpython/sql/hstore_plpython.sql @@ -40,15 +40,18 @@ SELECT test1arr(array['aa=>bb, cc=>NULL'::hstore, 'dd=>ee']); -- test python -> hstore -CREATE FUNCTION test2() RETURNS hstore +CREATE FUNCTION test2(a int, b text) RETURNS hstore LANGUAGE plpythonu TRANSFORM FOR TYPE hstore AS $$ -val = {'a': 1, 'b': 'boo', 'c': None} +val = {'a': a, 'b': b, 'c': None} return val $$; -SELECT test2(); +SELECT test2(1, 'boo'); + +--- test ruleutils +\sf test2 -- test python -> hstore[] diff --git a/contrib/intarray/Makefile b/contrib/intarray/Makefile index 01faa36b1073..3817c1669ab9 100644 --- a/contrib/intarray/Makefile +++ b/contrib/intarray/Makefile @@ -12,7 +12,7 @@ OBJS = \ _intbig_gist.o EXTENSION = intarray -DATA = intarray--1.3--1.4.sql intarray--1.2--1.3.sql \ +DATA = intarray--1.4--1.5.sql intarray--1.3--1.4.sql intarray--1.2--1.3.sql \ intarray--1.2.sql intarray--1.1--1.2.sql \ intarray--1.0--1.1.sql PGFILEDESC = "intarray - functions and operators for arrays of integers" diff --git a/contrib/intarray/_int_selfuncs.c b/contrib/intarray/_int_selfuncs.c index e9519536a109..a90c46793d10 100644 --- a/contrib/intarray/_int_selfuncs.c +++ b/contrib/intarray/_int_selfuncs.c @@ -3,7 +3,7 @@ * _int_selfuncs.c * Functions for selectivity estimation of intarray operators * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/contrib/intarray/bench/bench.pl b/contrib/intarray/bench/bench.pl index daf3febc804a..a4341d12cc2b 100755 --- a/contrib/intarray/bench/bench.pl +++ b/contrib/intarray/bench/bench.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/contrib/intarray/bench/create_test.pl b/contrib/intarray/bench/create_test.pl index 3f2a6e4da2a1..993a4572f416 100755 --- a/contrib/intarray/bench/create_test.pl +++ b/contrib/intarray/bench/create_test.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl +# Copyright (c) 2021, PostgreSQL Global Development Group + # contrib/intarray/bench/create_test.pl use strict; diff --git a/contrib/intarray/intarray--1.4--1.5.sql b/contrib/intarray/intarray--1.4--1.5.sql new file mode 100644 index 000000000000..2454ebcddc22 --- /dev/null +++ b/contrib/intarray/intarray--1.4--1.5.sql @@ -0,0 +1,8 @@ +/* contrib/intarray/intarray--1.4--1.5.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION intarray UPDATE TO '1.5'" to load this file. \quit + +-- Remove @ and ~ +DROP OPERATOR @ (_int4, _int4); +DROP OPERATOR ~ (_int4, _int4); diff --git a/contrib/intarray/intarray.control b/contrib/intarray/intarray.control index bbc837c5732e..c3ff753e2cfd 100644 --- a/contrib/intarray/intarray.control +++ b/contrib/intarray/intarray.control @@ -1,6 +1,6 @@ # intarray extension comment = 'functions, operators, and index support for 1-D arrays of integers' -default_version = '1.4' +default_version = '1.5' module_pathname = '$libdir/_int' relocatable = true trusted = true diff --git a/contrib/isn/isn.c b/contrib/isn/isn.c index cf36bb69d4d5..1cf1669f25ca 100644 --- a/contrib/isn/isn.c +++ b/contrib/isn/isn.c @@ -4,7 +4,7 @@ * PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC) * * Author: German Mendez Bravo (Kronuz) - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/isn/isn.c diff --git a/contrib/isn/isn.h b/contrib/isn/isn.h index 017f5974db56..4f4935f80d85 100644 --- a/contrib/isn/isn.h +++ b/contrib/isn/isn.h @@ -4,7 +4,7 @@ * PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC) * * Author: German Mendez Bravo (Kronuz) - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/isn/isn.h diff --git a/contrib/jsonb_plperl/jsonb_plperl.c b/contrib/jsonb_plperl/jsonb_plperl.c index b81ba54b809d..22e90afe1b6e 100644 --- a/contrib/jsonb_plperl/jsonb_plperl.c +++ b/contrib/jsonb_plperl/jsonb_plperl.c @@ -216,9 +216,7 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem) IV ival = SvIV(in); out.type = jbvNumeric; - out.val.numeric = - DatumGetNumeric(DirectFunctionCall1(int8_numeric, - Int64GetDatum((int64) ival))); + out.val.numeric = int64_to_numeric(ival); } else if (SvNOK(in)) { diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c index 91b7958c48ef..65cce4999366 100644 --- a/contrib/oid2name/oid2name.c +++ b/contrib/oid2name/oid2name.c @@ -12,6 +12,7 @@ #include "catalog/pg_class_d.h" #include "common/connect.h" #include "common/logging.h" +#include "common/string.h" #include "getopt_long.h" #include "libpq-fe.h" #include "pg_getopt.h" @@ -293,8 +294,7 @@ PGconn * sql_conn(struct options *my_opts) { PGconn *conn; - bool have_password = false; - char password[100]; + char *password = NULL; bool new_pass; PGresult *res; @@ -316,7 +316,7 @@ sql_conn(struct options *my_opts) keywords[2] = "user"; values[2] = my_opts->username; keywords[3] = "password"; - values[3] = have_password ? password : NULL; + values[3] = password; keywords[4] = "dbname"; values[4] = my_opts->dbname; keywords[5] = "fallback_application_name"; @@ -336,11 +336,10 @@ sql_conn(struct options *my_opts) if (PQstatus(conn) == CONNECTION_BAD && PQconnectionNeedsPassword(conn) && - !have_password) + !password) { PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; + password = simple_prompt("Password: ", false); new_pass = true; } } while (new_pass); @@ -348,8 +347,7 @@ sql_conn(struct options *my_opts) /* check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { - pg_log_error("could not connect to database %s: %s", - my_opts->dbname, PQerrorMessage(conn)); + pg_log_error("%s", PQerrorMessage(conn)); PQfinish(conn); exit(1); } diff --git a/contrib/oid2name/t/001_basic.pl b/contrib/oid2name/t/001_basic.pl index fa2c5743f63a..8f0d4349a077 100644 --- a/contrib/oid2name/t/001_basic.pl +++ b/contrib/oid2name/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/contrib/pg_standby/Makefile b/contrib/old_snapshot/Makefile similarity index 50% rename from contrib/pg_standby/Makefile rename to contrib/old_snapshot/Makefile index 87732bedf185..adb557532fc1 100644 --- a/contrib/pg_standby/Makefile +++ b/contrib/old_snapshot/Makefile @@ -1,19 +1,20 @@ -# contrib/pg_standby/Makefile +# contrib/old_snapshot/Makefile -PGFILEDESC = "pg_standby - supports creation of a warm standby" -PGAPPICON = win32 - -PROGRAM = pg_standby +MODULE_big = old_snapshot OBJS = \ $(WIN32RES) \ - pg_standby.o + time_mapping.o + +EXTENSION = old_snapshot +DATA = old_snapshot--1.0.sql +PGFILEDESC = "old_snapshot - utilities in support of old_snapshot_threshold" ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else -subdir = contrib/pg_standby +subdir = contrib/old_snapshot top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/old_snapshot/old_snapshot--1.0.sql b/contrib/old_snapshot/old_snapshot--1.0.sql new file mode 100644 index 000000000000..9ebb8829e372 --- /dev/null +++ b/contrib/old_snapshot/old_snapshot--1.0.sql @@ -0,0 +1,14 @@ +/* contrib/old_snapshot/old_snapshot--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION old_snapshot" to load this file. \quit + +-- Show visibility map and page-level visibility information for each block. +CREATE FUNCTION pg_old_snapshot_time_mapping(array_offset OUT int4, + end_timestamp OUT timestamptz, + newest_xmin OUT xid) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'pg_old_snapshot_time_mapping' +LANGUAGE C STRICT; + +-- XXX. Do we want REVOKE commands here? diff --git a/contrib/old_snapshot/old_snapshot.control b/contrib/old_snapshot/old_snapshot.control new file mode 100644 index 000000000000..491eec536cd6 --- /dev/null +++ b/contrib/old_snapshot/old_snapshot.control @@ -0,0 +1,5 @@ +# old_snapshot extension +comment = 'utilities in support of old_snapshot_threshold' +default_version = '1.0' +module_pathname = '$libdir/old_snapshot' +relocatable = true diff --git a/contrib/old_snapshot/time_mapping.c b/contrib/old_snapshot/time_mapping.c new file mode 100644 index 000000000000..02acf77b1ad0 --- /dev/null +++ b/contrib/old_snapshot/time_mapping.c @@ -0,0 +1,160 @@ +/*------------------------------------------------------------------------- + * + * time_mapping.c + * time to XID mapping information + * + * Copyright (c) 2020-2021, PostgreSQL Global Development Group + * + * contrib/old_snapshot/time_mapping.c + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "funcapi.h" +#include "storage/lwlock.h" +#include "utils/old_snapshot.h" +#include "utils/snapmgr.h" +#include "utils/timestamp.h" + +/* + * Backend-private copy of the information from oldSnapshotControl which relates + * to the time to XID mapping, plus an index so that we can iterate. + * + * Note that the length of the xid_by_minute array is given by + * OLD_SNAPSHOT_TIME_MAP_ENTRIES (which is not a compile-time constant). + */ +typedef struct +{ + int current_index; + int head_offset; + TimestampTz head_timestamp; + int count_used; + TransactionId xid_by_minute[FLEXIBLE_ARRAY_MEMBER]; +} OldSnapshotTimeMapping; + +#define NUM_TIME_MAPPING_COLUMNS 3 + +PG_MODULE_MAGIC; +PG_FUNCTION_INFO_V1(pg_old_snapshot_time_mapping); + +static OldSnapshotTimeMapping *GetOldSnapshotTimeMapping(void); +static TupleDesc MakeOldSnapshotTimeMappingTupleDesc(void); +static HeapTuple MakeOldSnapshotTimeMappingTuple(TupleDesc tupdesc, + OldSnapshotTimeMapping *mapping); + +/* + * SQL-callable set-returning function. + */ +Datum +pg_old_snapshot_time_mapping(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + OldSnapshotTimeMapping *mapping; + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + mapping = GetOldSnapshotTimeMapping(); + funcctx->user_fctx = mapping; + funcctx->tuple_desc = MakeOldSnapshotTimeMappingTupleDesc(); + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + mapping = (OldSnapshotTimeMapping *) funcctx->user_fctx; + + while (mapping->current_index < mapping->count_used) + { + HeapTuple tuple; + + tuple = MakeOldSnapshotTimeMappingTuple(funcctx->tuple_desc, mapping); + ++mapping->current_index; + SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); + } + + SRF_RETURN_DONE(funcctx); +} + +/* + * Get the old snapshot time mapping data from shared memory. + */ +static OldSnapshotTimeMapping * +GetOldSnapshotTimeMapping(void) +{ + OldSnapshotTimeMapping *mapping; + + mapping = palloc(offsetof(OldSnapshotTimeMapping, xid_by_minute) + + sizeof(TransactionId) * OLD_SNAPSHOT_TIME_MAP_ENTRIES); + mapping->current_index = 0; + + LWLockAcquire(OldSnapshotTimeMapLock, LW_SHARED); + mapping->head_offset = oldSnapshotControl->head_offset; + mapping->head_timestamp = oldSnapshotControl->head_timestamp; + mapping->count_used = oldSnapshotControl->count_used; + for (int i = 0; i < OLD_SNAPSHOT_TIME_MAP_ENTRIES; ++i) + mapping->xid_by_minute[i] = oldSnapshotControl->xid_by_minute[i]; + LWLockRelease(OldSnapshotTimeMapLock); + + return mapping; +} + +/* + * Build a tuple descriptor for the pg_old_snapshot_time_mapping() SRF. + */ +static TupleDesc +MakeOldSnapshotTimeMappingTupleDesc(void) +{ + TupleDesc tupdesc; + + tupdesc = CreateTemplateTupleDesc(NUM_TIME_MAPPING_COLUMNS); + + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "array_offset", + INT4OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "end_timestamp", + TIMESTAMPTZOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "newest_xmin", + XIDOID, -1, 0); + + return BlessTupleDesc(tupdesc); +} + +/* + * Convert one entry from the old snapshot time mapping to a HeapTuple. + */ +static HeapTuple +MakeOldSnapshotTimeMappingTuple(TupleDesc tupdesc, OldSnapshotTimeMapping *mapping) +{ + Datum values[NUM_TIME_MAPPING_COLUMNS]; + bool nulls[NUM_TIME_MAPPING_COLUMNS]; + int array_position; + TimestampTz timestamp; + + /* + * Figure out the array position corresponding to the current index. + * + * Index 0 means the oldest entry in the mapping, which is stored at + * mapping->head_offset. Index 1 means the next-oldest entry, which is a + * the following index, and so on. We wrap around when we reach the end of + * the array. + */ + array_position = (mapping->head_offset + mapping->current_index) + % OLD_SNAPSHOT_TIME_MAP_ENTRIES; + + /* + * No explicit timestamp is stored for any entry other than the oldest + * one, but each entry corresponds to 1-minute period, so we can just add. + */ + timestamp = TimestampTzPlusMilliseconds(mapping->head_timestamp, + mapping->current_index * 60000); + + /* Initialize nulls and values arrays. */ + memset(nulls, 0, sizeof(nulls)); + values[0] = Int32GetDatum(array_position); + values[1] = TimestampTzGetDatum(timestamp); + values[2] = TransactionIdGetDatum(mapping->xid_by_minute[array_position]); + + return heap_form_tuple(tupdesc, values, nulls); +} diff --git a/contrib/pageinspect/Makefile b/contrib/pageinspect/Makefile index 447262f8d027..ab64c8d1fdab 100644 --- a/contrib/pageinspect/Makefile +++ b/contrib/pageinspect/Makefile @@ -8,12 +8,14 @@ OBJS = \ btreefuncs.o \ fsmfuncs.o \ ginfuncs.o \ + gistfuncs.o \ hashfuncs.o \ heapfuncs.o \ rawpage.o EXTENSION = pageinspect -DATA = pageinspect--1.7--1.8.sql pageinspect--1.6--1.7.sql \ +DATA = pageinspect--1.8--1.9.sql pageinspect--1.7--1.8.sql \ + pageinspect--1.6--1.7.sql \ pageinspect--1.5.sql pageinspect--1.5--1.6.sql \ pageinspect--1.4--1.5.sql pageinspect--1.3--1.4.sql \ pageinspect--1.2--1.3.sql pageinspect--1.1--1.2.sql \ diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c index 0bc7fc64dda8..5484c0392828 100644 --- a/contrib/pageinspect/brinfuncs.c +++ b/contrib/pageinspect/brinfuncs.c @@ -2,7 +2,7 @@ * brinfuncs.c * Functions to investigate BRIN indexes * - * Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Copyright (c) 2014-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/brinfuncs.c @@ -256,7 +256,18 @@ brin_page_items(PG_FUNCTION_ARGS) int att = attno - 1; values[0] = UInt16GetDatum(offset); - values[1] = UInt32GetDatum(dtup->bt_blkno); + switch (TupleDescAttr(tupdesc, 1)->atttypid) + { + case INT8OID: + values[1] = Int64GetDatum((int64) dtup->bt_blkno); + break; + case INT4OID: + /* support for old extension version */ + values[1] = UInt32GetDatum(dtup->bt_blkno); + break; + default: + elog(ERROR, "incorrect output types"); + } values[2] = UInt16GetDatum(attno); values[3] = BoolGetDatum(dtup->bt_columns[att].bv_allnulls); values[4] = BoolGetDatum(dtup->bt_columns[att].bv_hasnulls); diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c index e7a323044bf9..b7725b572f0d 100644 --- a/contrib/pageinspect/btreefuncs.c +++ b/contrib/pageinspect/btreefuncs.c @@ -41,8 +41,10 @@ #include "utils/varlena.h" PG_FUNCTION_INFO_V1(bt_metap); +PG_FUNCTION_INFO_V1(bt_page_items_1_9); PG_FUNCTION_INFO_V1(bt_page_items); PG_FUNCTION_INFO_V1(bt_page_items_bytea); +PG_FUNCTION_INFO_V1(bt_page_stats_1_9); PG_FUNCTION_INFO_V1(bt_page_stats); #define IS_INDEX(r) ((r)->rd_rel->relkind == RELKIND_INDEX) @@ -73,11 +75,7 @@ typedef struct BTPageStat /* opaque data */ BlockNumber btpo_prev; BlockNumber btpo_next; - union - { - uint32 level; - TransactionId xact; - } btpo; + uint32 btpo_level; uint16 btpo_flags; BTCycleId btpo_cycleid; } BTPageStat; @@ -110,9 +108,33 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat) /* page type (flags) */ if (P_ISDELETED(opaque)) { - stat->type = 'd'; - stat->btpo.xact = opaque->btpo.xact; - return; + /* We divide deleted pages into leaf ('d') or internal ('D') */ + if (P_ISLEAF(opaque) || !P_HAS_FULLXID(opaque)) + stat->type = 'd'; + else + stat->type = 'D'; + + /* + * Report safexid in a deleted page. + * + * Handle pg_upgrade'd deleted pages that used the previous safexid + * representation in btpo_level field (this used to be a union type + * called "bpto"). + */ + if (P_HAS_FULLXID(opaque)) + { + FullTransactionId safexid = BTPageGetDeleteXid(page); + + elog(NOTICE, "deleted page from block %u has safexid %u:%u", + blkno, EpochFromFullTransactionId(safexid), + XidFromFullTransactionId(safexid)); + } + else + elog(NOTICE, "deleted page from block %u has safexid %u", + blkno, opaque->btpo_level); + + /* Don't interpret BTDeletedPageData as index tuples */ + maxoff = InvalidOffsetNumber; } else if (P_IGNORE(opaque)) stat->type = 'e'; @@ -126,7 +148,7 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat) /* btpage opaque data */ stat->btpo_prev = opaque->btpo_prev; stat->btpo_next = opaque->btpo_next; - stat->btpo.level = opaque->btpo.level; + stat->btpo_level = opaque->btpo_level; stat->btpo_flags = opaque->btpo_flags; stat->btpo_cycleid = opaque->btpo_cycleid; @@ -160,11 +182,11 @@ GetBTPageStatistics(BlockNumber blkno, Buffer buffer, BTPageStat *stat) * Usage: SELECT * FROM bt_page_stats('t1_pkey', 1); * ----------------------------------------------- */ -Datum -bt_page_stats(PG_FUNCTION_ARGS) +static Datum +bt_page_stats_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version) { text *relname = PG_GETARG_TEXT_PP(0); - uint32 blkno = PG_GETARG_UINT32(1); + int64 blkno = (ext_version == PAGEINSPECT_V1_8 ? PG_GETARG_UINT32(1) : PG_GETARG_INT64(1)); Buffer buffer; Relation rel; RangeVar *relrv; @@ -197,8 +219,15 @@ bt_page_stats(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary tables of other sessions"))); + if (blkno < 0 || blkno > MaxBlockNumber) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid block number"))); + if (blkno == 0) - elog(ERROR, "block 0 is a meta page"); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("block 0 is a meta page"))); CHECK_RELATION_BLOCK_RANGE(rel, blkno); @@ -219,16 +248,16 @@ bt_page_stats(PG_FUNCTION_ARGS) elog(ERROR, "return type must be a row type"); j = 0; - values[j++] = psprintf("%d", stat.blkno); + values[j++] = psprintf("%u", stat.blkno); values[j++] = psprintf("%c", stat.type); - values[j++] = psprintf("%d", stat.live_items); - values[j++] = psprintf("%d", stat.dead_items); - values[j++] = psprintf("%d", stat.avg_item_size); - values[j++] = psprintf("%d", stat.page_size); - values[j++] = psprintf("%d", stat.free_size); - values[j++] = psprintf("%d", stat.btpo_prev); - values[j++] = psprintf("%d", stat.btpo_next); - values[j++] = psprintf("%d", (stat.type == 'd') ? stat.btpo.xact : stat.btpo.level); + values[j++] = psprintf("%u", stat.live_items); + values[j++] = psprintf("%u", stat.dead_items); + values[j++] = psprintf("%u", stat.avg_item_size); + values[j++] = psprintf("%u", stat.page_size); + values[j++] = psprintf("%u", stat.free_size); + values[j++] = psprintf("%u", stat.btpo_prev); + values[j++] = psprintf("%u", stat.btpo_next); + values[j++] = psprintf("%u", stat.btpo_level); values[j++] = psprintf("%d", stat.btpo_flags); tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc), @@ -239,6 +268,19 @@ bt_page_stats(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } +Datum +bt_page_stats_1_9(PG_FUNCTION_ARGS) +{ + return bt_page_stats_internal(fcinfo, PAGEINSPECT_V1_9); +} + +/* entry point for old extension version */ +Datum +bt_page_stats(PG_FUNCTION_ARGS) +{ + return bt_page_stats_internal(fcinfo, PAGEINSPECT_V1_8); +} + /* * cross-call data structure for SRF @@ -259,7 +301,7 @@ struct user_args * ------------------------------------------------------ */ static Datum -bt_page_print_tuples(FuncCallContext *fctx, struct user_args *uargs) +bt_page_print_tuples(struct user_args *uargs) { Page page = uargs->page; OffsetNumber offset = uargs->offset; @@ -405,11 +447,11 @@ bt_page_print_tuples(FuncCallContext *fctx, struct user_args *uargs) * Usage: SELECT * FROM bt_page_items('t1_pkey', 1); *------------------------------------------------------- */ -Datum -bt_page_items(PG_FUNCTION_ARGS) +static Datum +bt_page_items_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version) { text *relname = PG_GETARG_TEXT_PP(0); - uint32 blkno = PG_GETARG_UINT32(1); + int64 blkno = (ext_version == PAGEINSPECT_V1_8 ? PG_GETARG_UINT32(1) : PG_GETARG_INT64(1)); Datum result; FuncCallContext *fctx; MemoryContext mctx; @@ -447,8 +489,15 @@ bt_page_items(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary tables of other sessions"))); + if (blkno < 0 || blkno > MaxBlockNumber) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid block number"))); + if (blkno == 0) - elog(ERROR, "block 0 is a meta page"); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("block 0 is a meta page"))); CHECK_RELATION_BLOCK_RANGE(rel, blkno); @@ -474,10 +523,14 @@ bt_page_items(PG_FUNCTION_ARGS) opaque = (BTPageOpaque) PageGetSpecialPointer(uargs->page); - if (P_ISDELETED(opaque)) - elog(NOTICE, "page is deleted"); - - fctx->max_calls = PageGetMaxOffsetNumber(uargs->page); + if (!P_ISDELETED(opaque)) + fctx->max_calls = PageGetMaxOffsetNumber(uargs->page); + else + { + /* Don't interpret BTDeletedPageData as index tuples */ + elog(NOTICE, "page from block " INT64_FORMAT " is deleted", blkno); + fctx->max_calls = 0; + } uargs->leafpage = P_ISLEAF(opaque); uargs->rightmost = P_RIGHTMOST(opaque); @@ -498,7 +551,7 @@ bt_page_items(PG_FUNCTION_ARGS) if (fctx->call_cntr < fctx->max_calls) { - result = bt_page_print_tuples(fctx, uargs); + result = bt_page_print_tuples(uargs); uargs->offset++; SRF_RETURN_NEXT(fctx, result); } @@ -506,6 +559,19 @@ bt_page_items(PG_FUNCTION_ARGS) SRF_RETURN_DONE(fctx); } +Datum +bt_page_items_1_9(PG_FUNCTION_ARGS) +{ + return bt_page_items_internal(fcinfo, PAGEINSPECT_V1_9); +} + +/* entry point for old extension version */ +Datum +bt_page_items(PG_FUNCTION_ARGS) +{ + return bt_page_items_internal(fcinfo, PAGEINSPECT_V1_8); +} + /*------------------------------------------------------- * bt_page_items_bytea() * @@ -561,7 +627,14 @@ bt_page_items_bytea(PG_FUNCTION_ARGS) if (P_ISDELETED(opaque)) elog(NOTICE, "page is deleted"); - fctx->max_calls = PageGetMaxOffsetNumber(uargs->page); + if (!P_ISDELETED(opaque)) + fctx->max_calls = PageGetMaxOffsetNumber(uargs->page); + else + { + /* Don't interpret BTDeletedPageData as index tuples */ + elog(NOTICE, "page from block is deleted"); + fctx->max_calls = 0; + } uargs->leafpage = P_ISLEAF(opaque); uargs->rightmost = P_RIGHTMOST(opaque); @@ -582,7 +655,7 @@ bt_page_items_bytea(PG_FUNCTION_ARGS) if (fctx->call_cntr < fctx->max_calls) { - result = bt_page_print_tuples(fctx, uargs); + result = bt_page_print_tuples(uargs); uargs->offset++; SRF_RETURN_NEXT(fctx, result); } @@ -650,10 +723,7 @@ bt_metap(PG_FUNCTION_ARGS) /* * We need a kluge here to detect API versions prior to 1.8. Earlier - * versions incorrectly used int4 for certain columns. This caused - * various problems. For example, an int4 version of the "oldest_xact" - * column would not work with TransactionId values that happened to exceed - * PG_INT32_MAX. + * versions incorrectly used int4 for certain columns. * * There is no way to reliably avoid the problems created by the old * function definition at this point, so insist that the user update the @@ -681,7 +751,8 @@ bt_metap(PG_FUNCTION_ARGS) */ if (metad->btm_version >= BTREE_NOVAC_VERSION) { - values[j++] = psprintf("%u", metad->btm_oldest_btpo_xact); + values[j++] = psprintf(INT64_FORMAT, + (int64) metad->btm_last_cleanup_num_delpages); values[j++] = psprintf("%f", metad->btm_last_cleanup_num_heap_tuples); values[j++] = metad->btm_allequalimage ? "t" : "f"; } diff --git a/contrib/pageinspect/expected/btree.out b/contrib/pageinspect/expected/btree.out index 17bf0c547082..c60bc88560cc 100644 --- a/contrib/pageinspect/expected/btree.out +++ b/contrib/pageinspect/expected/btree.out @@ -3,17 +3,19 @@ INSERT INTO test1 VALUES (72057594037927937, 'text'); CREATE INDEX test1_a_idx ON test1 USING btree (a); \x SELECT * FROM bt_metap('test1_a_idx'); --[ RECORD 1 ]-----------+------- -magic | 340322 -version | 4 -root | 1 -level | 0 -fastroot | 1 -fastlevel | 0 -oldest_xact | 0 -last_cleanup_num_tuples | -1 -allequalimage | t +-[ RECORD 1 ]-------------+------- +magic | 340322 +version | 4 +root | 1 +level | 0 +fastroot | 1 +fastlevel | 0 +last_cleanup_num_delpages | 0 +last_cleanup_num_tuples | -1 +allequalimage | t +SELECT * FROM bt_page_stats('test1_a_idx', -1); +ERROR: invalid block number SELECT * FROM bt_page_stats('test1_a_idx', 0); ERROR: block 0 is a meta page SELECT * FROM bt_page_stats('test1_a_idx', 1); @@ -27,11 +29,13 @@ page_size | 8192 free_size | 8128 btpo_prev | 0 btpo_next | 0 -btpo | 0 +btpo_level | 0 btpo_flags | 3 SELECT * FROM bt_page_stats('test1_a_idx', 2); ERROR: block number out of range +SELECT * FROM bt_page_items('test1_a_idx', -1); +ERROR: invalid block number SELECT * FROM bt_page_items('test1_a_idx', 0); ERROR: block 0 is a meta page SELECT * FROM bt_page_items('test1_a_idx', 1); @@ -48,6 +52,8 @@ tids | SELECT * FROM bt_page_items('test1_a_idx', 2); ERROR: block number out of range +SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', -1)); +ERROR: invalid block number SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 0)); ERROR: block is a meta page SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 1)); diff --git a/contrib/pageinspect/expected/gin.out b/contrib/pageinspect/expected/gin.out index 82f63b23b19d..ef7570b9723b 100644 --- a/contrib/pageinspect/expected/gin.out +++ b/contrib/pageinspect/expected/gin.out @@ -35,3 +35,4 @@ FROM gin_leafpage_items(get_raw_page('test1_y_idx', -[ RECORD 1 ] ?column? | t +DROP TABLE test1; diff --git a/contrib/pageinspect/expected/gist.out b/contrib/pageinspect/expected/gist.out new file mode 100644 index 000000000000..86c9e9caa9dc --- /dev/null +++ b/contrib/pageinspect/expected/gist.out @@ -0,0 +1,69 @@ +-- The gist_page_opaque_info() function prints the page's LSN. Normally, +-- that's constant 1 (GistBuildLSN) on every page of a freshly built GiST +-- index. But with wal_level=minimal, the whole relation is dumped to WAL at +-- the end of the transaction if it's smaller than wal_skip_threshold, which +-- updates the LSNs. Wrap the tests on gist_page_opaque_info() in the +-- same transaction with the CREATE INDEX so that we see the LSNs before +-- they are possibly overwritten at end of transaction. +BEGIN; +-- Create a test table and GiST index. +CREATE TABLE test_gist AS SELECT point(i,i) p, i::text t FROM + generate_series(1,1000) i; +CREATE INDEX test_gist_idx ON test_gist USING gist (p); +-- Page 0 is the root, the rest are leaf pages +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 0)); + lsn | nsn | rightlink | flags +-----+-----+------------+------- + 0/1 | 0/0 | 4294967295 | {} +(1 row) + +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 1)); + lsn | nsn | rightlink | flags +-----+-----+------------+-------- + 0/1 | 0/0 | 4294967295 | {leaf} +(1 row) + +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 2)); + lsn | nsn | rightlink | flags +-----+-----+-----------+-------- + 0/1 | 0/0 | 1 | {leaf} +(1 row) + +COMMIT; +SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 0), 'test_gist_idx'); + itemoffset | ctid | itemlen | dead | keys +------------+-----------+---------+------+------------------- + 1 | (1,65535) | 40 | f | (p)=((166,166)) + 2 | (2,65535) | 40 | f | (p)=((332,332)) + 3 | (3,65535) | 40 | f | (p)=((498,498)) + 4 | (4,65535) | 40 | f | (p)=((664,664)) + 5 | (5,65535) | 40 | f | (p)=((830,830)) + 6 | (6,65535) | 40 | f | (p)=((996,996)) + 7 | (7,65535) | 40 | f | (p)=((1000,1000)) +(7 rows) + +SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 1), 'test_gist_idx') LIMIT 5; + itemoffset | ctid | itemlen | dead | keys +------------+-------+---------+------+------------- + 1 | (0,1) | 40 | f | (p)=((1,1)) + 2 | (0,2) | 40 | f | (p)=((2,2)) + 3 | (0,3) | 40 | f | (p)=((3,3)) + 4 | (0,4) | 40 | f | (p)=((4,4)) + 5 | (0,5) | 40 | f | (p)=((5,5)) +(5 rows) + +-- gist_page_items_bytea prints the raw key data as a bytea. The output of that is +-- platform-dependent (endianess), so omit the actual key data from the output. +SELECT itemoffset, ctid, itemlen FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0)); + itemoffset | ctid | itemlen +------------+-----------+--------- + 1 | (1,65535) | 40 + 2 | (2,65535) | 40 + 3 | (3,65535) | 40 + 4 | (4,65535) | 40 + 5 | (5,65535) | 40 + 6 | (6,65535) | 40 + 7 | (7,65535) | 40 +(7 rows) + +DROP TABLE test_gist; diff --git a/contrib/pageinspect/expected/hash.out b/contrib/pageinspect/expected/hash.out index 75d7bcfad5f7..bd0628d01369 100644 --- a/contrib/pageinspect/expected/hash.out +++ b/contrib/pageinspect/expected/hash.out @@ -28,6 +28,8 @@ hash_page_type | bitmap SELECT hash_page_type(get_raw_page('test_hash_a_idx', 6)); ERROR: block number 6 is out of range for relation "test_hash_a_idx" +SELECT * FROM hash_bitmap_info('test_hash_a_idx', -1); +ERROR: invalid block number SELECT * FROM hash_bitmap_info('test_hash_a_idx', 0); ERROR: invalid overflow block number 0 SELECT * FROM hash_bitmap_info('test_hash_a_idx', 1); @@ -40,6 +42,8 @@ SELECT * FROM hash_bitmap_info('test_hash_a_idx', 4); ERROR: invalid overflow block number 4 SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5); ERROR: invalid overflow block number 5 +SELECT * FROM hash_bitmap_info('test_hash_a_idx', 6); +ERROR: block number 6 is out of range for relation "test_hash_a_idx" SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM hash_metapage_info(get_raw_page('test_hash_a_idx', 0)); diff --git a/contrib/pageinspect/expected/oldextversions.out b/contrib/pageinspect/expected/oldextversions.out new file mode 100644 index 000000000000..04dc7f8640eb --- /dev/null +++ b/contrib/pageinspect/expected/oldextversions.out @@ -0,0 +1,40 @@ +-- test old extension version entry points +DROP EXTENSION pageinspect; +CREATE EXTENSION pageinspect VERSION '1.8'; +CREATE TABLE test1 (a int8, b text); +INSERT INTO test1 VALUES (72057594037927937, 'text'); +CREATE INDEX test1_a_idx ON test1 USING btree (a); +-- from page.sql +SELECT octet_length(get_raw_page('test1', 0)) AS main_0; + main_0 +-------- + 8192 +(1 row) + +SELECT octet_length(get_raw_page('test1', 'main', 0)) AS main_0; + main_0 +-------- + 8192 +(1 row) + +SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_test; + silly_checksum_test +--------------------- + t +(1 row) + +-- from btree.sql +SELECT * FROM bt_page_stats('test1_a_idx', 1); + blkno | type | live_items | dead_items | avg_item_size | page_size | free_size | btpo_prev | btpo_next | btpo | btpo_flags +-------+------+------------+------------+---------------+-----------+-----------+-----------+-----------+------+------------ + 1 | l | 1 | 0 | 16 | 8192 | 8128 | 0 | 0 | 0 | 3 +(1 row) + +SELECT * FROM bt_page_items('test1_a_idx', 1); + itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | tids +------------+-------+---------+-------+------+-------------------------+------+-------+------ + 1 | (0,1) | 16 | f | f | 01 00 00 00 00 00 00 01 | f | (0,1) | +(1 row) + +DROP TABLE test1; +DROP EXTENSION pageinspect; diff --git a/contrib/pageinspect/expected/page.out b/contrib/pageinspect/expected/page.out index b6aea0124bbc..4da28f0a1db5 100644 --- a/contrib/pageinspect/expected/page.out +++ b/contrib/pageinspect/expected/page.out @@ -1,7 +1,7 @@ CREATE EXTENSION pageinspect; CREATE TABLE test1 (a int, b int); INSERT INTO test1 VALUES (16777217, 131584); -VACUUM test1; -- set up FSM +VACUUM (DISABLE_PAGE_SKIPPING) test1; -- set up FSM -- The page contents can vary, so just test that it can be read -- successfully, but don't keep the output. SELECT octet_length(get_raw_page('test1', 'main', 0)) AS main_0; @@ -32,6 +32,8 @@ SELECT octet_length(get_raw_page('test1', 'vm', 0)) AS vm_0; SELECT octet_length(get_raw_page('test1', 'vm', 1)) AS vm_1; ERROR: block number 1 is out of range for relation "test1" +SELECT octet_length(get_raw_page('test1', 'main', -1)); +ERROR: invalid block number SELECT octet_length(get_raw_page('xxx', 'main', 0)); ERROR: relation "xxx" does not exist SELECT octet_length(get_raw_page('test1', 'xxx', 0)); @@ -55,6 +57,8 @@ SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_ t (1 row) +SELECT page_checksum(get_raw_page('test1', 0), -1); +ERROR: invalid block number SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bits) FROM heap_page_items(get_raw_page('test1', 0)); tuple_data_split @@ -83,18 +87,8 @@ SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); (1 row) -- If we freeze the only tuple on test1, the infomask should --- always be the same in all test runs. we show raw flags by --- default: HEAP_XMIN_COMMITTED and HEAP_XMIN_INVALID. -VACUUM FREEZE test1; -SELECT t_infomask, t_infomask2, raw_flags, combined_flags -FROM heap_page_items(get_raw_page('test1', 0)), - LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); - t_infomask | t_infomask2 | raw_flags | combined_flags -------------+-------------+-----------------------------------------------------------+-------------------- - 2816 | 2 | {HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID,HEAP_XMAX_INVALID} | {HEAP_XMIN_FROZEN} -(1 row) - --- output the decoded flag HEAP_XMIN_FROZEN instead +-- always be the same in all test runs. +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test1; SELECT t_infomask, t_infomask2, raw_flags, combined_flags FROM heap_page_items(get_raw_page('test1', 0)), LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); diff --git a/contrib/pageinspect/fsmfuncs.c b/contrib/pageinspect/fsmfuncs.c index 099acbb2fe4b..930f1df33900 100644 --- a/contrib/pageinspect/fsmfuncs.c +++ b/contrib/pageinspect/fsmfuncs.c @@ -9,7 +9,7 @@ * there's hardly any use case for using these without superuser-rights * anyway. * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/fsmfuncs.c diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c index 711473579a86..e425cbcdb8e1 100644 --- a/contrib/pageinspect/ginfuncs.c +++ b/contrib/pageinspect/ginfuncs.c @@ -2,7 +2,7 @@ * ginfuncs.c * Functions to investigate the content of GIN indexes * - * Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Copyright (c) 2014-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/ginfuncs.c diff --git a/contrib/pageinspect/gistfuncs.c b/contrib/pageinspect/gistfuncs.c new file mode 100644 index 000000000000..7c9b9be3efad --- /dev/null +++ b/contrib/pageinspect/gistfuncs.c @@ -0,0 +1,281 @@ +/* + * gistfuncs.c + * Functions to investigate the content of GiST indexes + * + * Copyright (c) 2014-2021, PostgreSQL Global Development Group + * + * IDENTIFICATION + * contrib/pageinspect/gistfuncs.c + */ +#include "postgres.h" + +#include "access/gist.h" +#include "access/gist_private.h" +#include "access/htup.h" +#include "access/relation.h" +#include "catalog/namespace.h" +#include "funcapi.h" +#include "miscadmin.h" +#include "pageinspect.h" +#include "storage/itemptr.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "utils/rel.h" +#include "utils/pg_lsn.h" +#include "utils/varlena.h" + +PG_FUNCTION_INFO_V1(gist_page_opaque_info); +PG_FUNCTION_INFO_V1(gist_page_items); +PG_FUNCTION_INFO_V1(gist_page_items_bytea); + +#define ItemPointerGetDatum(X) PointerGetDatum(X) + + +Datum +gist_page_opaque_info(PG_FUNCTION_ARGS) +{ + bytea *raw_page = PG_GETARG_BYTEA_P(0); + TupleDesc tupdesc; + Page page; + GISTPageOpaque opaq; + HeapTuple resultTuple; + Datum values[4]; + bool nulls[4]; + Datum flags[16]; + int nflags = 0; + uint16 flagbits; + + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to use raw page functions"))); + + page = get_page_from_raw(raw_page); + + opaq = (GISTPageOpaque) PageGetSpecialPointer(page); + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + /* Convert the flags bitmask to an array of human-readable names */ + flagbits = opaq->flags; + if (flagbits & F_LEAF) + flags[nflags++] = CStringGetTextDatum("leaf"); + if (flagbits & F_DELETED) + flags[nflags++] = CStringGetTextDatum("deleted"); + if (flagbits & F_TUPLES_DELETED) + flags[nflags++] = CStringGetTextDatum("tuples_deleted"); + if (flagbits & F_FOLLOW_RIGHT) + flags[nflags++] = CStringGetTextDatum("follow_right"); + if (flagbits & F_HAS_GARBAGE) + flags[nflags++] = CStringGetTextDatum("has_garbage"); + flagbits &= ~(F_LEAF | F_DELETED | F_TUPLES_DELETED | F_FOLLOW_RIGHT | F_HAS_GARBAGE); + if (flagbits) + { + /* any flags we don't recognize are printed in hex */ + flags[nflags++] = DirectFunctionCall1(to_hex32, Int32GetDatum(flagbits)); + } + + memset(nulls, 0, sizeof(nulls)); + + values[0] = LSNGetDatum(PageGetLSN(page)); + values[1] = LSNGetDatum(GistPageGetNSN(page)); + values[2] = Int64GetDatum(opaq->rightlink); + values[3] = PointerGetDatum(construct_array(flags, nflags, + TEXTOID, + -1, false, TYPALIGN_INT)); + + /* Build and return the result tuple. */ + resultTuple = heap_form_tuple(tupdesc, values, nulls); + + return HeapTupleGetDatum(resultTuple); +} + +Datum +gist_page_items_bytea(PG_FUNCTION_ARGS) +{ + bytea *raw_page = PG_GETARG_BYTEA_P(0); + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + bool randomAccess; + TupleDesc tupdesc; + Tuplestorestate *tupstore; + MemoryContext oldcontext; + Page page; + OffsetNumber offset; + OffsetNumber maxoff = InvalidOffsetNumber; + + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to use raw page functions"))); + + /* check to see if caller supports us returning a tuplestore */ + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("materialize mode required, but it is not allowed in this context"))); + + /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */ + oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory); + + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0; + tupstore = tuplestore_begin_heap(randomAccess, false, work_mem); + rsinfo->returnMode = SFRM_Materialize; + rsinfo->setResult = tupstore; + rsinfo->setDesc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + + page = get_page_from_raw(raw_page); + + /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */ + if (GistPageIsDeleted(page)) + elog(NOTICE, "page is deleted"); + else + maxoff = PageGetMaxOffsetNumber(page); + + for (offset = FirstOffsetNumber; + offset <= maxoff; + offset++) + { + Datum values[5]; + bool nulls[5]; + ItemId id; + IndexTuple itup; + bytea *tuple_bytea; + int tuple_len; + + id = PageGetItemId(page, offset); + + if (!ItemIdIsValid(id)) + elog(ERROR, "invalid ItemId"); + + itup = (IndexTuple) PageGetItem(page, id); + tuple_len = IndexTupleSize(itup); + + memset(nulls, 0, sizeof(nulls)); + + values[0] = DatumGetInt16(offset); + values[1] = ItemPointerGetDatum(&itup->t_tid); + values[2] = Int32GetDatum((int) IndexTupleSize(itup)); + + tuple_bytea = (bytea *) palloc(tuple_len + VARHDRSZ); + SET_VARSIZE(tuple_bytea, tuple_len + VARHDRSZ); + memcpy(VARDATA(tuple_bytea), itup, tuple_len); + values[3] = BoolGetDatum(ItemIdIsDead(id)); + values[4] = PointerGetDatum(tuple_bytea); + + tuplestore_putvalues(tupstore, tupdesc, values, nulls); + } + + return (Datum) 0; +} + +Datum +gist_page_items(PG_FUNCTION_ARGS) +{ + bytea *raw_page = PG_GETARG_BYTEA_P(0); + Oid indexRelid = PG_GETARG_OID(1); + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + bool randomAccess; + Relation indexRel; + TupleDesc tupdesc; + Tuplestorestate *tupstore; + MemoryContext oldcontext; + Page page; + OffsetNumber offset; + OffsetNumber maxoff = InvalidOffsetNumber; + + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to use raw page functions"))); + + /* check to see if caller supports us returning a tuplestore */ + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("materialize mode required, but it is not allowed in this context"))); + + /* The tupdesc and tuplestore must be created in ecxt_per_query_memory */ + oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory); + + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0; + tupstore = tuplestore_begin_heap(randomAccess, false, work_mem); + rsinfo->returnMode = SFRM_Materialize; + rsinfo->setResult = tupstore; + rsinfo->setDesc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + + /* Open the relation */ + indexRel = index_open(indexRelid, AccessShareLock); + + page = get_page_from_raw(raw_page); + + /* Avoid bogus PageGetMaxOffsetNumber() call with deleted pages */ + if (GistPageIsDeleted(page)) + elog(NOTICE, "page is deleted"); + else + maxoff = PageGetMaxOffsetNumber(page); + + for (offset = FirstOffsetNumber; + offset <= maxoff; + offset++) + { + Datum values[5]; + bool nulls[5]; + ItemId id; + IndexTuple itup; + Datum itup_values[INDEX_MAX_KEYS]; + bool itup_isnull[INDEX_MAX_KEYS]; + char *key_desc; + + id = PageGetItemId(page, offset); + + if (!ItemIdIsValid(id)) + elog(ERROR, "invalid ItemId"); + + itup = (IndexTuple) PageGetItem(page, id); + + index_deform_tuple(itup, RelationGetDescr(indexRel), + itup_values, itup_isnull); + + memset(nulls, 0, sizeof(nulls)); + + values[0] = DatumGetInt16(offset); + values[1] = ItemPointerGetDatum(&itup->t_tid); + values[2] = Int32GetDatum((int) IndexTupleSize(itup)); + values[3] = BoolGetDatum(ItemIdIsDead(id)); + + key_desc = BuildIndexValueDescription(indexRel, itup_values, itup_isnull); + if (key_desc) + values[4] = CStringGetTextDatum(key_desc); + else + { + values[4] = (Datum) 0; + nulls[4] = true; + } + + tuplestore_putvalues(tupstore, tupdesc, values, nulls); + } + + relation_close(indexRel, AccessShareLock); + + return (Datum) 0; +} diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c index 3b2f0339cfe0..ff01119474a4 100644 --- a/contrib/pageinspect/hashfuncs.c +++ b/contrib/pageinspect/hashfuncs.c @@ -2,7 +2,7 @@ * hashfuncs.c * Functions to investigate the content of HASH indexes * - * Copyright (c) 2017-2020, PostgreSQL Global Development Group + * Copyright (c) 2017-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/hashfuncs.c @@ -390,7 +390,7 @@ Datum hash_bitmap_info(PG_FUNCTION_ARGS) { Oid indexRelid = PG_GETARG_OID(0); - uint64 ovflblkno = PG_GETARG_INT64(1); + int64 ovflblkno = PG_GETARG_INT64(1); HashMetaPage metap; Buffer metabuf, mapbuf; @@ -425,11 +425,16 @@ hash_bitmap_info(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary tables of other sessions"))); + if (ovflblkno < 0 || ovflblkno > MaxBlockNumber) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid block number"))); + if (ovflblkno >= RelationGetNumberOfBlocks(indexRel)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("block number " UINT64_FORMAT " is out of range for relation \"%s\"", - ovflblkno, RelationGetRelationName(indexRel)))); + errmsg("block number %lld is out of range for relation \"%s\"", + (long long int) ovflblkno, RelationGetRelationName(indexRel)))); /* Read the metapage so we can determine which bitmap page to use */ metabuf = _hash_getbuf(indexRel, HASH_METAPAGE, HASH_READ, LH_META_PAGE); diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c index f04455da127c..f6760eb31e79 100644 --- a/contrib/pageinspect/heapfuncs.c +++ b/contrib/pageinspect/heapfuncs.c @@ -15,7 +15,7 @@ * there's hardly any use case for using these without superuser-rights * anyway. * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/heapfuncs.c @@ -338,7 +338,7 @@ tuple_data_split_internal(Oid relid, char *tupdata, attr = TupleDescAttr(tupdesc, i); /* - * Tuple header can specify less attributes than tuple descriptor as + * Tuple header can specify fewer attributes than tuple descriptor as * ALTER TABLE ADD COLUMN without DEFAULT keyword does not actually * change tuples in pages, so attributes with numbers greater than * (t_infomask2 & HEAP_NATTS_MASK) should be treated as NULL. diff --git a/contrib/pageinspect/pageinspect--1.8--1.9.sql b/contrib/pageinspect/pageinspect--1.8--1.9.sql new file mode 100644 index 000000000000..be89a64ca140 --- /dev/null +++ b/contrib/pageinspect/pageinspect--1.8--1.9.sql @@ -0,0 +1,137 @@ +/* contrib/pageinspect/pageinspect--1.8--1.9.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pageinspect UPDATE TO '1.9'" to load this file. \quit + +-- +-- gist_page_opaque_info() +-- +CREATE FUNCTION gist_page_opaque_info(IN page bytea, + OUT lsn pg_lsn, + OUT nsn pg_lsn, + OUT rightlink bigint, + OUT flags text[]) +AS 'MODULE_PATHNAME', 'gist_page_opaque_info' +LANGUAGE C STRICT PARALLEL SAFE; + + +-- +-- gist_page_items_bytea() +-- +CREATE FUNCTION gist_page_items_bytea(IN page bytea, + OUT itemoffset smallint, + OUT ctid tid, + OUT itemlen smallint, + OUT dead boolean, + OUT key_data bytea) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'gist_page_items_bytea' +LANGUAGE C STRICT PARALLEL SAFE; + +-- +-- gist_page_items() +-- +CREATE FUNCTION gist_page_items(IN page bytea, + IN index_oid regclass, + OUT itemoffset smallint, + OUT ctid tid, + OUT itemlen smallint, + OUT dead boolean, + OUT keys text) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'gist_page_items' +LANGUAGE C STRICT PARALLEL SAFE; + +-- +-- get_raw_page() +-- +DROP FUNCTION get_raw_page(text, int4); +CREATE FUNCTION get_raw_page(text, int8) +RETURNS bytea +AS 'MODULE_PATHNAME', 'get_raw_page_1_9' +LANGUAGE C STRICT PARALLEL SAFE; + +DROP FUNCTION get_raw_page(text, text, int4); +CREATE FUNCTION get_raw_page(text, text, int8) +RETURNS bytea +AS 'MODULE_PATHNAME', 'get_raw_page_fork_1_9' +LANGUAGE C STRICT PARALLEL SAFE; + +-- +-- page_checksum() +-- +DROP FUNCTION page_checksum(IN page bytea, IN blkno int4); +CREATE FUNCTION page_checksum(IN page bytea, IN blkno int8) +RETURNS smallint +AS 'MODULE_PATHNAME', 'page_checksum_1_9' +LANGUAGE C STRICT PARALLEL SAFE; + +-- +-- bt_metap() +-- +DROP FUNCTION bt_metap(text); +CREATE FUNCTION bt_metap(IN relname text, + OUT magic int4, + OUT version int4, + OUT root int8, + OUT level int8, + OUT fastroot int8, + OUT fastlevel int8, + OUT last_cleanup_num_delpages int8, + OUT last_cleanup_num_tuples float8, + OUT allequalimage boolean) +AS 'MODULE_PATHNAME', 'bt_metap' +LANGUAGE C STRICT PARALLEL SAFE; + +-- +-- bt_page_stats() +-- +DROP FUNCTION bt_page_stats(text, int4); +CREATE FUNCTION bt_page_stats(IN relname text, IN blkno int8, + OUT blkno int8, + OUT type "char", + OUT live_items int4, + OUT dead_items int4, + OUT avg_item_size int4, + OUT page_size int4, + OUT free_size int4, + OUT btpo_prev int8, + OUT btpo_next int8, + OUT btpo_level int8, + OUT btpo_flags int4) +AS 'MODULE_PATHNAME', 'bt_page_stats_1_9' +LANGUAGE C STRICT PARALLEL SAFE; + +-- +-- bt_page_items() +-- +DROP FUNCTION bt_page_items(text, int4); +CREATE FUNCTION bt_page_items(IN relname text, IN blkno int8, + OUT itemoffset smallint, + OUT ctid tid, + OUT itemlen smallint, + OUT nulls bool, + OUT vars bool, + OUT data text, + OUT dead boolean, + OUT htid tid, + OUT tids tid[]) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'bt_page_items_1_9' +LANGUAGE C STRICT PARALLEL SAFE; + +-- +-- brin_page_items() +-- +DROP FUNCTION brin_page_items(IN page bytea, IN index_oid regclass); +CREATE FUNCTION brin_page_items(IN page bytea, IN index_oid regclass, + OUT itemoffset int, + OUT blknum int8, + OUT attnum int, + OUT allnulls bool, + OUT hasnulls bool, + OUT placeholder bool, + OUT value text) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'brin_page_items' +LANGUAGE C STRICT PARALLEL SAFE; diff --git a/contrib/pageinspect/pageinspect.control b/contrib/pageinspect/pageinspect.control index f8cdf526c651..bd716769a174 100644 --- a/contrib/pageinspect/pageinspect.control +++ b/contrib/pageinspect/pageinspect.control @@ -1,5 +1,5 @@ # pageinspect extension comment = 'inspect the contents of database pages at a low level' -default_version = '1.8' +default_version = '1.9' module_pathname = '$libdir/pageinspect' relocatable = true diff --git a/contrib/pageinspect/pageinspect.h b/contrib/pageinspect/pageinspect.h index 478e0d2d20d8..3812a3c23397 100644 --- a/contrib/pageinspect/pageinspect.h +++ b/contrib/pageinspect/pageinspect.h @@ -3,7 +3,7 @@ * pageinspect.h * Common functions for pageinspect. * - * Copyright (c) 2017-2020, PostgreSQL Global Development Group + * Copyright (c) 2017-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/pageinspect.h @@ -15,6 +15,15 @@ #include "storage/bufpage.h" +/* + * Extension version number, for supporting older extension versions' objects + */ +enum pageinspect_version +{ + PAGEINSPECT_V1_8, + PAGEINSPECT_V1_9, +}; + /* in rawpage.c */ extern Page get_page_from_raw(bytea *raw_page); diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index d2b851fa32c3..6cfc0a924695 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -5,7 +5,7 @@ * * Access-method specific inspection functions are in separate files. * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/rawpage.c @@ -40,6 +40,28 @@ static bytea *get_raw_page_internal(text *relname, ForkNumber forknum, * * Returns a copy of a page from shared buffers as a bytea */ +PG_FUNCTION_INFO_V1(get_raw_page_1_9); + +Datum +get_raw_page_1_9(PG_FUNCTION_ARGS) +{ + text *relname = PG_GETARG_TEXT_PP(0); + int64 blkno = PG_GETARG_INT64(1); + bytea *raw_page; + + if (blkno < 0 || blkno > MaxBlockNumber) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid block number"))); + + raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno); + + PG_RETURN_BYTEA_P(raw_page); +} + +/* + * entry point for old extension version + */ PG_FUNCTION_INFO_V1(get_raw_page); Datum @@ -69,6 +91,32 @@ get_raw_page(PG_FUNCTION_ARGS) * * Same, for any fork */ +PG_FUNCTION_INFO_V1(get_raw_page_fork_1_9); + +Datum +get_raw_page_fork_1_9(PG_FUNCTION_ARGS) +{ + text *relname = PG_GETARG_TEXT_PP(0); + text *forkname = PG_GETARG_TEXT_PP(1); + int64 blkno = PG_GETARG_INT64(2); + bytea *raw_page; + ForkNumber forknum; + + forknum = forkname_to_number(text_to_cstring(forkname)); + + if (blkno < 0 || blkno > MaxBlockNumber) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid block number"))); + + raw_page = get_raw_page_internal(relname, forknum, blkno); + + PG_RETURN_BYTEA_P(raw_page); +} + +/* + * Entry point for old extension version + */ PG_FUNCTION_INFO_V1(get_raw_page_fork); Datum @@ -268,8 +316,7 @@ page_header(PG_FUNCTION_ARGS) { char lsnchar[64]; - snprintf(lsnchar, sizeof(lsnchar), "%X/%X", - (uint32) (lsn >> 32), (uint32) lsn); + snprintf(lsnchar, sizeof(lsnchar), "%X/%X", LSN_FORMAT_ARGS(lsn)); values[0] = CStringGetTextDatum(lsnchar); } else @@ -299,13 +346,14 @@ page_header(PG_FUNCTION_ARGS) * Compute checksum of a raw page */ +PG_FUNCTION_INFO_V1(page_checksum_1_9); PG_FUNCTION_INFO_V1(page_checksum); -Datum -page_checksum(PG_FUNCTION_ARGS) +static Datum +page_checksum_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version) { bytea *raw_page = PG_GETARG_BYTEA_P(0); - uint32 blkno = PG_GETARG_INT32(1); + int64 blkno = (ext_version == PAGEINSPECT_V1_8 ? PG_GETARG_UINT32(1) : PG_GETARG_INT64(1)); int raw_page_size; PageHeader page; @@ -314,6 +362,11 @@ page_checksum(PG_FUNCTION_ARGS) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to use raw page functions"))); + if (blkno < 0 || blkno > MaxBlockNumber) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid block number"))); + raw_page_size = VARSIZE(raw_page) - VARHDRSZ; /* @@ -328,3 +381,18 @@ page_checksum(PG_FUNCTION_ARGS) PG_RETURN_INT16(pg_checksum_page((char *) page, blkno)); } + +Datum +page_checksum_1_9(PG_FUNCTION_ARGS) +{ + return page_checksum_internal(fcinfo, PAGEINSPECT_V1_9); +} + +/* + * Entry point for old extension version + */ +Datum +page_checksum(PG_FUNCTION_ARGS) +{ + return page_checksum_internal(fcinfo, PAGEINSPECT_V1_8); +} diff --git a/contrib/pageinspect/sql/btree.sql b/contrib/pageinspect/sql/btree.sql index 8eac64c7b3cb..963591795973 100644 --- a/contrib/pageinspect/sql/btree.sql +++ b/contrib/pageinspect/sql/btree.sql @@ -6,14 +6,17 @@ CREATE INDEX test1_a_idx ON test1 USING btree (a); SELECT * FROM bt_metap('test1_a_idx'); +SELECT * FROM bt_page_stats('test1_a_idx', -1); SELECT * FROM bt_page_stats('test1_a_idx', 0); SELECT * FROM bt_page_stats('test1_a_idx', 1); SELECT * FROM bt_page_stats('test1_a_idx', 2); +SELECT * FROM bt_page_items('test1_a_idx', -1); SELECT * FROM bt_page_items('test1_a_idx', 0); SELECT * FROM bt_page_items('test1_a_idx', 1); SELECT * FROM bt_page_items('test1_a_idx', 2); +SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', -1)); SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 0)); SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 1)); SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 2)); diff --git a/contrib/pageinspect/sql/gin.sql b/contrib/pageinspect/sql/gin.sql index d516ed3cbd44..423f5c574999 100644 --- a/contrib/pageinspect/sql/gin.sql +++ b/contrib/pageinspect/sql/gin.sql @@ -17,3 +17,5 @@ SELECT COUNT(*) > 0 FROM gin_leafpage_items(get_raw_page('test1_y_idx', (pg_relation_size('test1_y_idx') / current_setting('block_size')::bigint)::int - 1)); + +DROP TABLE test1; diff --git a/contrib/pageinspect/sql/gist.sql b/contrib/pageinspect/sql/gist.sql new file mode 100644 index 000000000000..1560d1e15c31 --- /dev/null +++ b/contrib/pageinspect/sql/gist.sql @@ -0,0 +1,29 @@ +-- The gist_page_opaque_info() function prints the page's LSN. Normally, +-- that's constant 1 (GistBuildLSN) on every page of a freshly built GiST +-- index. But with wal_level=minimal, the whole relation is dumped to WAL at +-- the end of the transaction if it's smaller than wal_skip_threshold, which +-- updates the LSNs. Wrap the tests on gist_page_opaque_info() in the +-- same transaction with the CREATE INDEX so that we see the LSNs before +-- they are possibly overwritten at end of transaction. +BEGIN; + +-- Create a test table and GiST index. +CREATE TABLE test_gist AS SELECT point(i,i) p, i::text t FROM + generate_series(1,1000) i; +CREATE INDEX test_gist_idx ON test_gist USING gist (p); + +-- Page 0 is the root, the rest are leaf pages +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 0)); +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 1)); +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 2)); + +COMMIT; + +SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 0), 'test_gist_idx'); +SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 1), 'test_gist_idx') LIMIT 5; + +-- gist_page_items_bytea prints the raw key data as a bytea. The output of that is +-- platform-dependent (endianess), so omit the actual key data from the output. +SELECT itemoffset, ctid, itemlen FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0)); + +DROP TABLE test_gist; diff --git a/contrib/pageinspect/sql/hash.sql b/contrib/pageinspect/sql/hash.sql index 87ee549a7b4f..64f33f1d52fd 100644 --- a/contrib/pageinspect/sql/hash.sql +++ b/contrib/pageinspect/sql/hash.sql @@ -13,12 +13,14 @@ SELECT hash_page_type(get_raw_page('test_hash_a_idx', 5)); SELECT hash_page_type(get_raw_page('test_hash_a_idx', 6)); +SELECT * FROM hash_bitmap_info('test_hash_a_idx', -1); SELECT * FROM hash_bitmap_info('test_hash_a_idx', 0); SELECT * FROM hash_bitmap_info('test_hash_a_idx', 1); SELECT * FROM hash_bitmap_info('test_hash_a_idx', 2); SELECT * FROM hash_bitmap_info('test_hash_a_idx', 3); SELECT * FROM hash_bitmap_info('test_hash_a_idx', 4); SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5); +SELECT * FROM hash_bitmap_info('test_hash_a_idx', 6); SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, diff --git a/contrib/pageinspect/sql/oldextversions.sql b/contrib/pageinspect/sql/oldextversions.sql new file mode 100644 index 000000000000..78e08f40e824 --- /dev/null +++ b/contrib/pageinspect/sql/oldextversions.sql @@ -0,0 +1,20 @@ +-- test old extension version entry points + +DROP EXTENSION pageinspect; +CREATE EXTENSION pageinspect VERSION '1.8'; + +CREATE TABLE test1 (a int8, b text); +INSERT INTO test1 VALUES (72057594037927937, 'text'); +CREATE INDEX test1_a_idx ON test1 USING btree (a); + +-- from page.sql +SELECT octet_length(get_raw_page('test1', 0)) AS main_0; +SELECT octet_length(get_raw_page('test1', 'main', 0)) AS main_0; +SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_test; + +-- from btree.sql +SELECT * FROM bt_page_stats('test1_a_idx', 1); +SELECT * FROM bt_page_items('test1_a_idx', 1); + +DROP TABLE test1; +DROP EXTENSION pageinspect; diff --git a/contrib/pageinspect/sql/page.sql b/contrib/pageinspect/sql/page.sql index bd049aeb247f..d333b763d709 100644 --- a/contrib/pageinspect/sql/page.sql +++ b/contrib/pageinspect/sql/page.sql @@ -3,7 +3,7 @@ CREATE EXTENSION pageinspect; CREATE TABLE test1 (a int, b int); INSERT INTO test1 VALUES (16777217, 131584); -VACUUM test1; -- set up FSM +VACUUM (DISABLE_PAGE_SKIPPING) test1; -- set up FSM -- The page contents can vary, so just test that it can be read -- successfully, but don't keep the output. @@ -17,6 +17,7 @@ SELECT octet_length(get_raw_page('test1', 'fsm', 1)) AS fsm_1; SELECT octet_length(get_raw_page('test1', 'vm', 0)) AS vm_0; SELECT octet_length(get_raw_page('test1', 'vm', 1)) AS vm_1; +SELECT octet_length(get_raw_page('test1', 'main', -1)); SELECT octet_length(get_raw_page('xxx', 'main', 0)); SELECT octet_length(get_raw_page('test1', 'xxx', 0)); @@ -25,6 +26,7 @@ SELECT get_raw_page('test1', 0) = get_raw_page('test1', 'main', 0); SELECT pagesize, version FROM page_header(get_raw_page('test1', 0)); SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_test; +SELECT page_checksum(get_raw_page('test1', 0), -1); SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bits) FROM heap_page_items(get_raw_page('test1', 0)); @@ -32,15 +34,9 @@ SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bi SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); -- If we freeze the only tuple on test1, the infomask should --- always be the same in all test runs. we show raw flags by --- default: HEAP_XMIN_COMMITTED and HEAP_XMIN_INVALID. -VACUUM FREEZE test1; +-- always be the same in all test runs. +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test1; -SELECT t_infomask, t_infomask2, raw_flags, combined_flags -FROM heap_page_items(get_raw_page('test1', 0)), - LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); - --- output the decoded flag HEAP_XMIN_FROZEN instead SELECT t_infomask, t_infomask2, raw_flags, combined_flags FROM heap_page_items(get_raw_page('test1', 0)), LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c index d5f9d14b0109..3d644be8dd55 100644 --- a/contrib/passwordcheck/passwordcheck.c +++ b/contrib/passwordcheck/passwordcheck.c @@ -3,7 +3,7 @@ * passwordcheck.c * * - * Copyright (c) 2009-2020, PostgreSQL Global Development Group + * Copyright (c) 2009-2021, PostgreSQL Global Development Group * * Author: Laurenz Albe * @@ -91,6 +91,9 @@ check_password(const char *username, int i; bool pwd_has_letter, pwd_has_nonletter; +#ifdef USE_CRACKLIB + const char *reason; +#endif /* enforce minimum length */ if (pwdlen < MIN_PWD_LENGTH) @@ -125,10 +128,11 @@ check_password(const char *username, #ifdef USE_CRACKLIB /* call cracklib to check password */ - if (FascistCheck(password, CRACKLIB_DICTPATH)) + if ((reason = FascistCheck(password, CRACKLIB_DICTPATH))) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("password is easily cracked"))); + errmsg("password is easily cracked"), + errdetail_log("cracklib diagnostic: %s", reason))); #endif } diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index c202756d2f6a..1265a8f632ad 100644 --- a/contrib/pg_prewarm/autoprewarm.c +++ b/contrib/pg_prewarm/autoprewarm.c @@ -16,7 +16,7 @@ * relevant database in turn. The former keeps running after the * initial prewarm is complete to update the dump file periodically. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pg_prewarm/autoprewarm.c @@ -35,6 +35,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "postmaster/bgworker.h" +#include "postmaster/interrupt.h" #include "storage/buf_internals.h" #include "storage/dsm.h" #include "storage/ipc.h" @@ -94,12 +95,6 @@ static void apw_start_database_worker(void); static bool apw_init_shmem(void); static void apw_detach_shmem(int code, Datum arg); static int apw_compare_blockinfo(const void *p, const void *q); -static void apw_sigterm_handler(SIGNAL_ARGS); -static void apw_sighup_handler(SIGNAL_ARGS); - -/* Flags set by signal handlers */ -static volatile sig_atomic_t got_sigterm = false; -static volatile sig_atomic_t got_sighup = false; /* Pointer to shared-memory state. */ static AutoPrewarmSharedState *apw_state = NULL; @@ -158,11 +153,12 @@ void autoprewarm_main(Datum main_arg) { bool first_time = true; + bool final_dump_allowed = true; TimestampTz last_dump_time = 0; /* Establish signal handlers; once that's done, unblock signals. */ - pqsignal(SIGTERM, apw_sigterm_handler); - pqsignal(SIGHUP, apw_sighup_handler); + pqsignal(SIGTERM, SignalHandlerForShutdownRequest); + pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGUSR1, procsignal_sigusr1_handler); BackgroundWorkerUnblockSignals(); @@ -198,45 +194,48 @@ autoprewarm_main(Datum main_arg) * There's not much point in performing a dump immediately after we finish * preloading; so, if we do end up preloading, consider the last dump time * to be equal to the current time. + * + * If apw_load_buffers() is terminated early by a shutdown request, + * prevent dumping out our state below the loop, because we'd effectively + * just truncate the saved state to however much we'd managed to preload. */ if (first_time) { apw_load_buffers(); + final_dump_allowed = !ShutdownRequestPending; last_dump_time = GetCurrentTimestamp(); } /* Periodically dump buffers until terminated. */ - while (!got_sigterm) + while (!ShutdownRequestPending) { /* In case of a SIGHUP, just reload the configuration. */ - if (got_sighup) + if (ConfigReloadPending) { - got_sighup = false; + ConfigReloadPending = false; ProcessConfigFile(PGC_SIGHUP); } if (autoprewarm_interval <= 0) { /* We're only dumping at shutdown, so just wait forever. */ - (void) WaitLatch(&MyProc->procLatch, + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, -1L, PG_WAIT_EXTENSION); } else { - long delay_in_ms = 0; - TimestampTz next_dump_time = 0; - long secs = 0; - int usecs = 0; + TimestampTz next_dump_time; + long delay_in_ms; /* Compute the next dump time. */ next_dump_time = TimestampTzPlusMilliseconds(last_dump_time, autoprewarm_interval * 1000); - TimestampDifference(GetCurrentTimestamp(), next_dump_time, - &secs, &usecs); - delay_in_ms = secs + (usecs / 1000); + delay_in_ms = + TimestampDifferenceMilliseconds(GetCurrentTimestamp(), + next_dump_time); /* Perform a dump if it's time. */ if (delay_in_ms <= 0) @@ -247,21 +246,22 @@ autoprewarm_main(Datum main_arg) } /* Sleep until the next dump time. */ - (void) WaitLatch(&MyProc->procLatch, + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, delay_in_ms, PG_WAIT_EXTENSION); } /* Reset the latch, loop. */ - ResetLatch(&MyProc->procLatch); + ResetLatch(MyLatch); } /* * Dump one last time. We assume this is probably the result of a system * shutdown, although it's possible that we've merely been terminated. */ - apw_dump_now(true, true); + if (final_dump_allowed) + apw_dump_now(true, true); } /* @@ -394,6 +394,13 @@ apw_load_buffers(void) if (!have_free_buffer()) break; + /* + * Likewise, don't launch if we've already been told to shut down. + * (The launch would fail anyway, but we might as well skip it.) + */ + if (ShutdownRequestPending) + break; + /* * Start a per-database worker to load blocks for this database; this * function will return once the per-database worker exits. @@ -411,10 +418,11 @@ apw_load_buffers(void) apw_state->pid_using_dumpfile = InvalidPid; LWLockRelease(&apw_state->lock); - /* Report our success. */ - ereport(LOG, - (errmsg("autoprewarm successfully prewarmed %d of %d previously-loaded blocks", - apw_state->prewarmed_blocks, num_elements))); + /* Report our success, if we were able to finish. */ + if (!ShutdownRequestPending) + ereport(LOG, + (errmsg("autoprewarm successfully prewarmed %d of %d previously-loaded blocks", + apw_state->prewarmed_blocks, num_elements))); } /* @@ -689,7 +697,7 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged) apw_state->pid_using_dumpfile = InvalidPid; ereport(DEBUG1, - (errmsg("wrote block details for %d blocks", num_blocks))); + (errmsg_internal("wrote block details for %d blocks", num_blocks))); return num_blocks; } @@ -895,35 +903,3 @@ apw_compare_blockinfo(const void *p, const void *q) return 0; } - -/* - * Signal handler for SIGTERM - */ -static void -apw_sigterm_handler(SIGNAL_ARGS) -{ - int save_errno = errno; - - got_sigterm = true; - - if (MyProc) - SetLatch(&MyProc->procLatch); - - errno = save_errno; -} - -/* - * Signal handler for SIGHUP - */ -static void -apw_sighup_handler(SIGNAL_ARGS) -{ - int save_errno = errno; - - got_sighup = true; - - if (MyProc) - SetLatch(&MyProc->procLatch); - - errno = save_errno; -} diff --git a/contrib/pg_prewarm/pg_prewarm.c b/contrib/pg_prewarm/pg_prewarm.c index 33e2d28b2767..48d0132a0d0e 100644 --- a/contrib/pg_prewarm/pg_prewarm.c +++ b/contrib/pg_prewarm/pg_prewarm.c @@ -3,7 +3,7 @@ * pg_prewarm.c * prewarming utilities * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pg_prewarm/pg_prewarm.c @@ -126,8 +126,8 @@ pg_prewarm(PG_FUNCTION_ARGS) if (first_block < 0 || first_block >= nblocks) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("starting block number must be between 0 and " INT64_FORMAT, - nblocks - 1))); + errmsg("starting block number must be between 0 and %lld", + (long long) (nblocks - 1)))); } if (PG_ARGISNULL(4)) last_block = nblocks - 1; @@ -137,8 +137,8 @@ pg_prewarm(PG_FUNCTION_ARGS) if (last_block < 0 || last_block >= nblocks) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("ending block number must be between 0 and " INT64_FORMAT, - nblocks - 1))); + errmsg("ending block number must be between 0 and %lld", + (long long) (nblocks - 1)))); } /* Now we're ready to do the real work. */ diff --git a/contrib/pg_standby/.gitignore b/contrib/pg_standby/.gitignore deleted file mode 100644 index a401b085a895..000000000000 --- a/contrib/pg_standby/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/pg_standby diff --git a/contrib/pg_stat_statements/Makefile b/contrib/pg_stat_statements/Makefile index 081f997d703f..3ec627b95618 100644 --- a/contrib/pg_stat_statements/Makefile +++ b/contrib/pg_stat_statements/Makefile @@ -6,7 +6,7 @@ OBJS = \ pg_stat_statements.o EXTENSION = pg_stat_statements -DATA = pg_stat_statements--1.4.sql \ +DATA = pg_stat_statements--1.4.sql pg_stat_statements--1.8--1.9.sql \ pg_stat_statements--1.7--1.8.sql pg_stat_statements--1.6--1.7.sql \ pg_stat_statements--1.5--1.6.sql pg_stat_statements--1.4--1.5.sql \ pg_stat_statements--1.3--1.4.sql pg_stat_statements--1.2--1.3.sql \ diff --git a/contrib/pg_stat_statements/expected/pg_stat_statements.out b/contrib/pg_stat_statements/expected/pg_stat_statements.out index e0edb134f3dc..40b5109b5596 100644 --- a/contrib/pg_stat_statements/expected/pg_stat_statements.out +++ b/contrib/pg_stat_statements/expected/pg_stat_statements.out @@ -530,8 +530,8 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; -- -- Track the total number of rows retrieved or affected by the utility --- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW --- and SELECT INTO +-- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW, +-- REFRESH MATERIALIZED VIEW and SELECT INTO -- SELECT pg_stat_statements_reset(); pg_stat_statements_reset @@ -543,6 +543,7 @@ CREATE TABLE pgss_ctas AS SELECT a, 'ctas' b FROM generate_series(1, 10) a; SELECT generate_series(1, 10) c INTO pgss_select_into; COPY pgss_ctas (a, b) FROM STDIN; CREATE MATERIALIZED VIEW pgss_matv AS SELECT * FROM pgss_ctas; +REFRESH MATERIALIZED VIEW pgss_matv; BEGIN; DECLARE pgss_cursor CURSOR FOR SELECT * FROM pgss_matv; FETCH NEXT pgss_cursor; @@ -586,10 +587,11 @@ SELECT query, plans, calls, rows FROM pg_stat_statements ORDER BY query COLLATE FETCH FORWARD 5 pgss_cursor | 0 | 1 | 5 FETCH FORWARD ALL pgss_cursor | 0 | 1 | 7 FETCH NEXT pgss_cursor | 0 | 1 | 1 + REFRESH MATERIALIZED VIEW pgss_matv | 0 | 1 | 13 SELECT generate_series(1, 10) c INTO pgss_select_into | 0 | 1 | 10 SELECT pg_stat_statements_reset() | 0 | 1 | 1 SELECT query, plans, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 1 | 0 | 0 -(12 rows) +(13 rows) -- -- Track user activity and reset them @@ -859,4 +861,210 @@ SELECT query, plans, calls, rows FROM pg_stat_statements ORDER BY query COLLATE SELECT query, plans, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 1 | 0 | 0 (6 rows) +-- +-- access to pg_stat_statements_info view +-- +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +SELECT dealloc FROM pg_stat_statements_info; + dealloc +--------- + 0 +(1 row) + +-- +-- top level handling +-- +SET pg_stat_statements.track = 'top'; +DELETE FROM test; +DO $$ +BEGIN + DELETE FROM test; +END; +$$ LANGUAGE plpgsql; +SELECT query, toplevel, plans, calls FROM pg_stat_statements WHERE query LIKE '%DELETE%' ORDER BY query COLLATE "C", toplevel; + query | toplevel | plans | calls +-----------------------+----------+-------+------- + DELETE FROM test | t | 1 | 1 + DO $$ +| t | 0 | 1 + BEGIN +| | | + DELETE FROM test;+| | | + END; +| | | + $$ LANGUAGE plpgsql | | | +(2 rows) + +SET pg_stat_statements.track = 'all'; +DELETE FROM test; +DO $$ +BEGIN + DELETE FROM test; +END; +$$ LANGUAGE plpgsql; +SELECT query, toplevel, plans, calls FROM pg_stat_statements WHERE query LIKE '%DELETE%' ORDER BY query COLLATE "C", toplevel; + query | toplevel | plans | calls +-----------------------+----------+-------+------- + DELETE FROM test | f | 1 | 1 + DELETE FROM test | t | 2 | 2 + DO $$ +| t | 0 | 2 + BEGIN +| | | + DELETE FROM test;+| | | + END; +| | | + $$ LANGUAGE plpgsql | | | +(3 rows) + +-- FROM [ONLY] +CREATE TABLE tbl_inh(id integer); +CREATE TABLE tbl_inh_1() INHERITS (tbl_inh); +INSERT INTO tbl_inh_1 SELECT 1; +SELECT * FROM tbl_inh; + id +---- + 1 +(1 row) + +SELECT * FROM ONLY tbl_inh; + id +---- +(0 rows) + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%FROM%tbl_inh%'; + count +------- + 2 +(1 row) + +-- WITH TIES +CREATE TABLE limitoption AS SELECT 0 AS val FROM generate_series(1, 10); +SELECT * +FROM limitoption +WHERE val < 2 +ORDER BY val +FETCH FIRST 2 ROWS WITH TIES; + val +----- + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +(10 rows) + +SELECT * +FROM limitoption +WHERE val < 2 +ORDER BY val +FETCH FIRST 2 ROW ONLY; + val +----- + 0 + 0 +(2 rows) + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%FETCH FIRST%'; + count +------- + 2 +(1 row) + +-- GROUP BY [DISTINCT] +SELECT a, b, c +FROM (VALUES (1, 2, 3), (4, NULL, 6), (7, 8, 9)) AS t (a, b, c) +GROUP BY ROLLUP(a, b), rollup(a, c) +ORDER BY a, b, c; + a | b | c +---+---+--- + 1 | 2 | 3 + 1 | 2 | + 1 | 2 | + 1 | | 3 + 1 | | 3 + 1 | | + 1 | | + 1 | | + 4 | | 6 + 4 | | 6 + 4 | | 6 + 4 | | + 4 | | + 4 | | + 4 | | + 4 | | + 7 | 8 | 9 + 7 | 8 | + 7 | 8 | + 7 | | 9 + 7 | | 9 + 7 | | + 7 | | + 7 | | + | | +(25 rows) + +SELECT a, b, c +FROM (VALUES (1, 2, 3), (4, NULL, 6), (7, 8, 9)) AS t (a, b, c) +GROUP BY DISTINCT ROLLUP(a, b), rollup(a, c) +ORDER BY a, b, c; + a | b | c +---+---+--- + 1 | 2 | 3 + 1 | 2 | + 1 | | 3 + 1 | | + 4 | | 6 + 4 | | 6 + 4 | | + 4 | | + 7 | 8 | 9 + 7 | 8 | + 7 | | 9 + 7 | | + | | +(13 rows) + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%GROUP BY%ROLLUP%'; + count +------- + 2 +(1 row) + +-- GROUPING SET agglevelsup +SELECT ( + SELECT ( + SELECT GROUPING(a,b) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + grouping +---------- + 0 + 0 + 0 +(3 rows) + +SELECT ( + SELECT ( + SELECT GROUPING(e,f) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + grouping +---------- + 3 + 0 + 1 +(3 rows) + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%SELECT GROUPING%'; + count +------- + 2 +(1 row) + DROP EXTENSION pg_stat_statements; diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql b/contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql new file mode 100644 index 000000000000..c45223f888e9 --- /dev/null +++ b/contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql @@ -0,0 +1,71 @@ +/* contrib/pg_stat_statements/pg_stat_statements--1.8--1.9.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.9'" to load this file. \quit + +--- Define pg_stat_statements_info +CREATE FUNCTION pg_stat_statements_info( + OUT dealloc bigint, + OUT stats_reset timestamp with time zone +) +RETURNS record +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT VOLATILE PARALLEL SAFE; + +CREATE VIEW pg_stat_statements_info AS + SELECT * FROM pg_stat_statements_info(); + +GRANT SELECT ON pg_stat_statements_info TO PUBLIC; + +/* First we have to remove them from the extension */ +ALTER EXTENSION pg_stat_statements DROP VIEW pg_stat_statements; +ALTER EXTENSION pg_stat_statements DROP FUNCTION pg_stat_statements(boolean); + +/* Then we can drop them */ +DROP VIEW pg_stat_statements; +DROP FUNCTION pg_stat_statements(boolean); + +/* Now redefine */ +CREATE FUNCTION pg_stat_statements(IN showtext boolean, + OUT userid oid, + OUT dbid oid, + OUT toplevel bool, + OUT queryid bigint, + OUT query text, + OUT plans int8, + OUT total_plan_time float8, + OUT min_plan_time float8, + OUT max_plan_time float8, + OUT mean_plan_time float8, + OUT stddev_plan_time float8, + OUT calls int8, + OUT total_exec_time float8, + OUT min_exec_time float8, + OUT max_exec_time float8, + OUT mean_exec_time float8, + OUT stddev_exec_time float8, + OUT rows int8, + OUT shared_blks_hit int8, + OUT shared_blks_read int8, + OUT shared_blks_dirtied int8, + OUT shared_blks_written int8, + OUT local_blks_hit int8, + OUT local_blks_read int8, + OUT local_blks_dirtied int8, + OUT local_blks_written int8, + OUT temp_blks_read int8, + OUT temp_blks_written int8, + OUT blk_read_time float8, + OUT blk_write_time float8, + OUT wal_records int8, + OUT wal_fpi int8, + OUT wal_bytes numeric +) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'pg_stat_statements_1_9' +LANGUAGE C STRICT VOLATILE PARALLEL SAFE; + +CREATE VIEW pg_stat_statements AS + SELECT * FROM pg_stat_statements(true); + +GRANT SELECT ON pg_stat_statements TO PUBLIC; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 6b91c62c31a8..07fe0e7cdad2 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -8,24 +8,9 @@ * a shared hashtable. (We track only as many distinct queries as will fit * in the designated amount of shared memory.) * - * As of Postgres 9.2, this module normalizes query entries. Normalization - * is a process whereby similar queries, typically differing only in their - * constants (though the exact rules are somewhat more subtle than that) are - * recognized as equivalent, and are tracked as a single entry. This is - * particularly useful for non-prepared queries. - * - * Normalization is implemented by fingerprinting queries, selectively - * serializing those fields of each query tree's nodes that are judged to be - * essential to the query. This is referred to as a query jumble. This is - * distinct from a regular serialization in that various extraneous - * information is ignored as irrelevant or not essential to the query, such - * as the collations of Vars and, most notably, the values of constants. - * - * This jumble is acquired at the end of parse analysis of each query, and - * a 64-bit hash of it is stored into the query's Query.queryId field. - * The server then copies this value around, making it available in plan - * tree(s) generated from the query. The executor can then use this value - * to blame query costs on the proper queryId. + * Starting in Postgres 9.2, this module normalized query entries. As of + * Postgres 14, the normalization is done by the core if compute_query_id is + * enabled, or optionally by third-party modules. * * To facilitate presenting entries to users, we create "representative" query * strings in which constants are replaced with parameter symbols ($n), to @@ -49,7 +34,7 @@ * in the file to be read or written while holding only shared lock. * * - * Copyright (c) 2008-2020, PostgreSQL Global Development Group + * Copyright (c) 2008-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pg_stat_statements/pg_stat_statements.c @@ -62,6 +47,7 @@ #include #include +#include "access/parallel.h" #include "catalog/pg_authid.h" #include "common/hashfn.h" #include "executor/instrument.h" @@ -76,11 +62,15 @@ #include "pgstat.h" #include "storage/fd.h" #include "storage/ipc.h" +#include "storage/lwlock.h" +#include "storage/shmem.h" #include "storage/spin.h" #include "tcop/utility.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/queryjumble.h" #include "utils/memutils.h" +#include "utils/timestamp.h" PG_MODULE_MAGIC; @@ -98,7 +88,7 @@ PG_MODULE_MAGIC; #define PGSS_TEXT_FILE PG_STAT_TMP_DIR "/pgss_query_texts.stat" /* Magic number identifying the stats file format */ -static const uint32 PGSS_FILE_HEADER = 0x20171004; +static const uint32 PGSS_FILE_HEADER = 0x20201227; /* PostgreSQL major version number, changes in which invalidate all entries */ static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100; @@ -113,7 +103,13 @@ static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100; #define USAGE_DEALLOC_PERCENT 5 /* free this % of entries at once */ #define IS_STICKY(c) ((c.calls[PGSS_PLAN] + c.calls[PGSS_EXEC]) == 0) -#define JUMBLE_SIZE 1024 /* query serialization buffer size */ +/* + * Utility statements that pgss_ProcessUtility and pgss_post_parse_analyze + * ignores. + */ +#define PGSS_HANDLED_UTILITY(n) (!IsA(n, ExecuteStmt) && \ + !IsA(n, PrepareStmt) && \ + !IsA(n, DeallocateStmt)) /* * Extension version number, for supporting older extension versions' objects @@ -124,7 +120,8 @@ typedef enum pgssVersion PGSS_V1_1, PGSS_V1_2, PGSS_V1_3, - PGSS_V1_8 + PGSS_V1_8, + PGSS_V1_9 } pgssVersion; typedef enum pgssStoreKind @@ -146,16 +143,17 @@ typedef enum pgssStoreKind * Hashtable key that defines the identity of a hashtable entry. We separate * queries by user and by database even if they are otherwise identical. * - * Right now, this structure contains no padding. If you add any, make sure - * to teach pgss_store() to zero the padding bytes. Otherwise, things will - * break, because pgss_hash is created using HASH_BLOBS, and thus tag_hash - * is used to hash this. + * If you add a new key to this struct, make sure to teach pgss_store() to + * zero the padding bytes. Otherwise, things will break, because pgss_hash is + * created using HASH_BLOBS, and thus tag_hash is used to hash this. + */ typedef struct pgssHashKey { Oid userid; /* user OID */ Oid dbid; /* database OID */ uint64 queryid; /* query identifier */ + bool toplevel; /* query executed at top level */ } pgssHashKey; /* @@ -190,9 +188,18 @@ typedef struct Counters double usage; /* usage factor */ int64 wal_records; /* # of WAL records generated */ int64 wal_fpi; /* # of WAL full page images generated */ - uint64 wal_bytes; /* total amount of WAL bytes generated */ + uint64 wal_bytes; /* total amount of WAL generated in bytes */ } Counters; +/* + * Global statistics for pg_stat_statements + */ +typedef struct pgssGlobalStats +{ + int64 dealloc; /* # of times entries were deallocated */ + TimestampTz stats_reset; /* timestamp with all stats reset */ +} pgssGlobalStats; + /* * Statistics per statement * @@ -222,42 +229,9 @@ typedef struct pgssSharedState Size extent; /* current extent of query file */ int n_writers; /* number of active writers to query file */ int gc_count; /* query file garbage collection cycle count */ + pgssGlobalStats stats; /* global statistics for pgss */ } pgssSharedState; -/* - * Struct for tracking locations/lengths of constants during normalization - */ -typedef struct pgssLocationLen -{ - int location; /* start offset in query text */ - int length; /* length in bytes, or -1 to ignore */ -} pgssLocationLen; - -/* - * Working state for computing a query jumble and producing a normalized - * query string - */ -typedef struct pgssJumbleState -{ - /* Jumble of current query tree */ - unsigned char *jumble; - - /* Number of bytes used in jumble[] */ - Size jumble_len; - - /* Array of locations of constants that should be removed */ - pgssLocationLen *clocations; - - /* Allocated length of clocations array */ - int clocations_buf_size; - - /* Current number of valid entries in clocations array */ - int clocations_count; - - /* highest Param id we've seen, in order to start normalization correctly */ - int highest_extern_param_id; -} pgssJumbleState; - /*---- Local variables ----*/ /* Current nesting depth of ExecutorRun+ProcessUtility calls */ @@ -305,8 +279,9 @@ static bool pgss_save; /* whether to save stats across shutdown */ #define pgss_enabled(level) \ + (!IsParallelWorker() && \ (pgss_track == PGSS_TRACK_ALL || \ - (pgss_track == PGSS_TRACK_TOP && (level) == 0)) + (pgss_track == PGSS_TRACK_TOP && (level) == 0))) #define record_gc_qtexts() \ do { \ @@ -326,11 +301,14 @@ PG_FUNCTION_INFO_V1(pg_stat_statements_reset_1_7); PG_FUNCTION_INFO_V1(pg_stat_statements_1_2); PG_FUNCTION_INFO_V1(pg_stat_statements_1_3); PG_FUNCTION_INFO_V1(pg_stat_statements_1_8); +PG_FUNCTION_INFO_V1(pg_stat_statements_1_9); PG_FUNCTION_INFO_V1(pg_stat_statements); +PG_FUNCTION_INFO_V1(pg_stat_statements_info); static void pgss_shmem_startup(void); static void pgss_shmem_shutdown(int code, Datum arg); -static void pgss_post_parse_analyze(ParseState *pstate, Query *query); +static void pgss_post_parse_analyze(ParseState *pstate, Query *query, + JumbleState *jstate); static PlannedStmt *pgss_planner(Query *parse, const char *query_string, int cursorOptions, @@ -342,17 +320,17 @@ static void pgss_ExecutorRun(QueryDesc *queryDesc, static void pgss_ExecutorFinish(QueryDesc *queryDesc); static void pgss_ExecutorEnd(QueryDesc *queryDesc); static void pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); -static uint64 pgss_hash_string(const char *str, int len); static void pgss_store(const char *query, uint64 queryId, int query_location, int query_len, pgssStoreKind kind, double total_time, uint64 rows, const BufferUsage *bufusage, const WalUsage *walusage, - pgssJumbleState *jstate); + JumbleState *jstate); static void pg_stat_statements_internal(FunctionCallInfo fcinfo, pgssVersion api_version, bool showtext); @@ -368,16 +346,9 @@ static char *qtext_fetch(Size query_offset, int query_len, static bool need_gc_qtexts(void); static void gc_qtexts(void); static void entry_reset(Oid userid, Oid dbid, uint64 queryid); -static void AppendJumble(pgssJumbleState *jstate, - const unsigned char *item, Size size); -static void JumbleQuery(pgssJumbleState *jstate, Query *query); -static void JumbleRangeTable(pgssJumbleState *jstate, List *rtable); -static void JumbleRowMarks(pgssJumbleState *jstate, List *rowMarks); -static void JumbleExpr(pgssJumbleState *jstate, Node *node); -static void RecordConstLocation(pgssJumbleState *jstate, int location); -static char *generate_normalized_query(pgssJumbleState *jstate, const char *query, - int query_loc, int *query_len_p, int encoding); -static void fill_in_constant_lengths(pgssJumbleState *jstate, const char *query, +static char *generate_normalized_query(JumbleState *jstate, const char *query, + int query_loc, int *query_len_p); +static void fill_in_constant_lengths(JumbleState *jstate, const char *query, int query_loc); static int comp_location(const void *a, const void *b); @@ -399,6 +370,12 @@ _PG_init(void) if (!process_shared_preload_libraries_in_progress) return; + /* + * Inform the postmaster that we want to enable query_id calculation if + * compute_query_id is set to auto. + */ + EnableQueryId(); + /* * Define (or redefine) custom GUC variables. */ @@ -554,9 +531,10 @@ pgss_shmem_startup(void) pgss->extent = 0; pgss->n_writers = 0; pgss->gc_count = 0; + pgss->stats.dealloc = 0; + pgss->stats.stats_reset = GetCurrentTimestamp(); } - memset(&info, 0, sizeof(info)); info.keysize = sizeof(pgssHashKey); info.entrysize = sizeof(pgssEntry); pgss_hash = ShmemInitHash("pg_stat_statements hash", @@ -673,6 +651,10 @@ pgss_shmem_startup(void) entry->counters = temp.counters; } + /* Read global statistics for pg_stat_statements */ + if (fread(&pgss->stats, sizeof(pgssGlobalStats), 1, file) != 1) + goto read_error; + pfree(buffer); FreeFile(file); FreeFile(qfile); @@ -794,6 +776,10 @@ pgss_shmem_shutdown(int code, Datum arg) } } + /* Dump global statistics for pg_stat_statements */ + if (fwrite(&pgss->stats, sizeof(pgssGlobalStats), 1, file) != 1) + goto error; + free(qbuffer); qbuffer = NULL; @@ -830,63 +816,35 @@ pgss_shmem_shutdown(int code, Datum arg) * Post-parse-analysis hook: mark query with a queryId */ static void -pgss_post_parse_analyze(ParseState *pstate, Query *query) +pgss_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate) { - pgssJumbleState jstate; - if (prev_post_parse_analyze_hook) - prev_post_parse_analyze_hook(pstate, query); - - /* Assert we didn't do this already */ - Assert(query->queryId == UINT64CONST(0)); + prev_post_parse_analyze_hook(pstate, query, jstate); /* Safety check... */ if (!pgss || !pgss_hash || !pgss_enabled(exec_nested_level)) return; /* - * Utility statements get queryId zero. We do this even in cases where - * the statement contains an optimizable statement for which a queryId - * could be derived (such as EXPLAIN or DECLARE CURSOR). For such cases, - * runtime control will first go through ProcessUtility and then the - * executor, and we don't want the executor hooks to do anything, since we - * are already measuring the statement's costs at the utility level. + * Clear queryId for prepared statements related utility, as those will + * inherit from the underlying statement's one (except DEALLOCATE which is + * entirely untracked). */ if (query->utilityStmt) { - query->queryId = UINT64CONST(0); + if (pgss_track_utility && !PGSS_HANDLED_UTILITY(query->utilityStmt)) + query->queryId = UINT64CONST(0); return; } - /* Set up workspace for query jumbling */ - jstate.jumble = (unsigned char *) palloc(JUMBLE_SIZE); - jstate.jumble_len = 0; - jstate.clocations_buf_size = 32; - jstate.clocations = (pgssLocationLen *) - palloc(jstate.clocations_buf_size * sizeof(pgssLocationLen)); - jstate.clocations_count = 0; - jstate.highest_extern_param_id = 0; - - /* Compute query ID and mark the Query node with it */ - JumbleQuery(&jstate, query); - query->queryId = - DatumGetUInt64(hash_any_extended(jstate.jumble, jstate.jumble_len, 0)); - - /* - * If we are unlucky enough to get a hash of zero, use 1 instead, to - * prevent confusion with the utility-statement case. - */ - if (query->queryId == UINT64CONST(0)) - query->queryId = UINT64CONST(1); - /* - * If we were able to identify any ignorable constants, we immediately - * create a hash table entry for the query, so that we can record the - * normalized form of the query string. If there were no such constants, - * the normalized string would be the same as the query text anyway, so - * there's no need for an early entry. + * If query jumbling were able to identify any ignorable constants, we + * immediately create a hash table entry for the query, so that we can + * record the normalized form of the query string. If there were no such + * constants, the normalized string would be the same as the query text + * anyway, so there's no need for an early entry. */ - if (jstate.clocations_count > 0) + if (jstate && jstate->clocations_count > 0) pgss_store(pstate->p_sourcetext, query->queryId, query->stmt_location, @@ -896,7 +854,7 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query) 0, NULL, NULL, - &jstate); + jstate); } /* @@ -1023,7 +981,7 @@ pgss_ExecutorStart(QueryDesc *queryDesc, int eflags) MemoryContext oldcxt; oldcxt = MemoryContextSwitchTo(queryDesc->estate->es_query_cxt); - queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL); + queryDesc->totaltime = InstrAlloc(1, INSTRUMENT_ALL, false); MemoryContextSwitchTo(oldcxt); } } @@ -1112,11 +1070,30 @@ pgss_ExecutorEnd(QueryDesc *queryDesc) */ static void pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) { Node *parsetree = pstmt->utilityStmt; + uint64 saved_queryId = pstmt->queryId; + + /* + * Force utility statements to get queryId zero. We do this even in cases + * where the statement contains an optimizable statement for which a + * queryId could be derived (such as EXPLAIN or DECLARE CURSOR). For such + * cases, runtime control will first go through ProcessUtility and then + * the executor, and we don't want the executor hooks to do anything, + * since we are already measuring the statement's costs at the utility + * level. + * + * Note that this is only done if pg_stat_statements is enabled and + * configured to track utility statements, in the unlikely possibility + * that user configured another extension to handle utility statements + * only. + */ + if (pgss_enabled(exec_nested_level) && pgss_track_utility) + pstmt->queryId = UINT64CONST(0); /* * If it's an EXECUTE statement, we don't track it and don't increment the @@ -1133,9 +1110,7 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, * Likewise, we don't track execution of DEALLOCATE. */ if (pgss_track_utility && pgss_enabled(exec_nested_level) && - !IsA(parsetree, ExecuteStmt) && - !IsA(parsetree, PrepareStmt) && - !IsA(parsetree, DeallocateStmt)) + PGSS_HANDLED_UTILITY(parsetree)) { instr_time start; instr_time duration; @@ -1153,11 +1128,11 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, PG_TRY(); { if (prev_ProcessUtility) - prev_ProcessUtility(pstmt, queryString, + prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); else - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } @@ -1171,13 +1146,14 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, INSTR_TIME_SUBTRACT(duration, start); /* - * Track the total number of rows retrieved or affected by - * the utility statements of COPY, FETCH, CREATE TABLE AS, - * CREATE MATERIALIZED VIEW and SELECT INTO. + * Track the total number of rows retrieved or affected by the utility + * statements of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED + * VIEW, REFRESH MATERIALIZED VIEW and SELECT INTO. */ rows = (qc && (qc->commandTag == CMDTAG_COPY || qc->commandTag == CMDTAG_FETCH || - qc->commandTag == CMDTAG_SELECT)) ? + qc->commandTag == CMDTAG_SELECT || + qc->commandTag == CMDTAG_REFRESH_MATERIALIZED_VIEW)) ? qc->nprocessed : 0; /* calc differences of buffer counters. */ @@ -1189,7 +1165,7 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, WalUsageAccumDiff(&walusage, &pgWalUsage, &walusage_start); pgss_store(queryString, - 0, /* signal that it's a utility stmt */ + saved_queryId, pstmt->stmt_location, pstmt->stmt_len, PGSS_EXEC, @@ -1202,33 +1178,22 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, else { if (prev_ProcessUtility) - prev_ProcessUtility(pstmt, queryString, + prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); else - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } } -/* - * Given an arbitrarily long query string, produce a hash for the purposes of - * identifying the query, without normalizing constants. Used when hashing - * utility statements. - */ -static uint64 -pgss_hash_string(const char *str, int len) -{ - return DatumGetUInt64(hash_any_extended((const unsigned char *) str, - len, 0)); -} - /* * Store some statistics for a statement. * - * If queryId is 0 then this is a utility statement and we should compute - * a suitable queryId internally. + * If queryId is 0 then this is a utility statement for which we couldn't + * compute a queryId during parse analysis, and we should compute a suitable + * queryId internally. * * If jstate is not NULL then we're trying to create an entry for which * we have no statistics as yet; we just want to record the normalized @@ -1245,7 +1210,7 @@ pgss_store(const char *query, uint64 queryId, double total_time, uint64 rows, const BufferUsage *bufusage, const WalUsage *walusage, - pgssJumbleState *jstate) + JumbleState *jstate) { pgssHashKey key; pgssEntry *entry; @@ -1259,57 +1224,28 @@ pgss_store(const char *query, uint64 queryId, return; /* - * Confine our attention to the relevant part of the string, if the query - * is a portion of a multi-statement source string. - * - * First apply starting offset, unless it's -1 (unknown). + * Nothing to do if compute_query_id isn't enabled and no other module + * computed a query identifier. */ - if (query_location >= 0) - { - Assert(query_location <= strlen(query)); - query += query_location; - /* Length of 0 (or -1) means "rest of string" */ - if (query_len <= 0) - query_len = strlen(query); - else - Assert(query_len <= strlen(query)); - } - else - { - /* If query location is unknown, distrust query_len as well */ - query_location = 0; - query_len = strlen(query); - } + if (queryId == UINT64CONST(0)) + return; /* - * Discard leading and trailing whitespace, too. Use scanner_isspace() - * not libc's isspace(), because we want to match the lexer's behavior. + * Confine our attention to the relevant part of the string, if the query + * is a portion of a multi-statement source string, and update query + * location and length if needed. */ - while (query_len > 0 && scanner_isspace(query[0])) - query++, query_location++, query_len--; - while (query_len > 0 && scanner_isspace(query[query_len - 1])) - query_len--; + query = CleanQuerytext(query, &query_location, &query_len); - /* - * For utility statements, we just hash the query string to get an ID. - */ - if (queryId == UINT64CONST(0)) - { - queryId = pgss_hash_string(query, query_len); + /* Set up key for hashtable search */ - /* - * If we are unlucky enough to get a hash of zero(invalid), use - * queryID as 2 instead, queryID 1 is already in use for normal - * statements. - */ - if (queryId == UINT64CONST(0)) - queryId = UINT64CONST(2); - } + /* memset() is required when pgssHashKey is without padding only */ + memset(&key, 0, sizeof(pgssHashKey)); - /* Set up key for hashtable search */ key.userid = GetUserId(); key.dbid = MyDatabaseId; key.queryid = queryId; + key.toplevel = (exec_nested_level == 0); /* Lookup the hash table entry with shared lock. */ LWLockAcquire(pgss->lock, LW_SHARED); @@ -1336,8 +1272,7 @@ pgss_store(const char *query, uint64 queryId, LWLockRelease(pgss->lock); norm_query = generate_normalized_query(jstate, query, query_location, - &query_len, - encoding); + &query_len); LWLockAcquire(pgss->lock, LW_SHARED); } @@ -1490,7 +1425,8 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS) #define PG_STAT_STATEMENTS_COLS_V1_2 19 #define PG_STAT_STATEMENTS_COLS_V1_3 23 #define PG_STAT_STATEMENTS_COLS_V1_8 32 -#define PG_STAT_STATEMENTS_COLS 32 /* maximum of above */ +#define PG_STAT_STATEMENTS_COLS_V1_9 33 +#define PG_STAT_STATEMENTS_COLS 33 /* maximum of above */ /* * Retrieve statement statistics. @@ -1502,6 +1438,16 @@ pg_stat_statements_reset(PG_FUNCTION_ARGS) * expected API version is identified by embedding it in the C name of the * function. Unfortunately we weren't bright enough to do that for 1.1. */ +Datum +pg_stat_statements_1_9(PG_FUNCTION_ARGS) +{ + bool showtext = PG_GETARG_BOOL(0); + + pg_stat_statements_internal(fcinfo, PGSS_V1_9, showtext); + + return (Datum) 0; +} + Datum pg_stat_statements_1_8(PG_FUNCTION_ARGS) { @@ -1566,7 +1512,7 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, pgssEntry *entry; /* Superusers or members of pg_read_all_stats members are allowed */ - is_allowed_role = is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS); + is_allowed_role = is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS); /* hash table must exist already */ if (!pgss || !pgss_hash) @@ -1621,6 +1567,10 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, if (api_version != PGSS_V1_8) elog(ERROR, "incorrect number of output arguments"); break; + case PG_STAT_STATEMENTS_COLS_V1_9: + if (api_version != PGSS_V1_9) + elog(ERROR, "incorrect number of output arguments"); + break; default: elog(ERROR, "incorrect number of output arguments"); } @@ -1712,6 +1662,8 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, values[i++] = ObjectIdGetDatum(entry->key.userid); values[i++] = ObjectIdGetDatum(entry->key.dbid); + if (api_version >= PGSS_V1_9) + values[i++] = BoolGetDatum(entry->key.toplevel); if (is_allowed_role || entry->key.userid == userid) { @@ -1849,6 +1801,7 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, api_version == PGSS_V1_2 ? PG_STAT_STATEMENTS_COLS_V1_2 : api_version == PGSS_V1_3 ? PG_STAT_STATEMENTS_COLS_V1_3 : api_version == PGSS_V1_8 ? PG_STAT_STATEMENTS_COLS_V1_8 : + api_version == PGSS_V1_9 ? PG_STAT_STATEMENTS_COLS_V1_9 : -1 /* fail if you forget to update this assert */ )); tuplestore_putvalues(tupstore, tupdesc, values, nulls); @@ -1863,6 +1816,47 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo, tuplestore_donestoring(tupstore); } +/* Number of output arguments (columns) for pg_stat_statements_info */ +#define PG_STAT_STATEMENTS_INFO_COLS 2 + +/* + * Return statistics of pg_stat_statements. + */ +Datum +pg_stat_statements_info(PG_FUNCTION_ARGS) +{ + pgssGlobalStats stats; + TupleDesc tupdesc; + Datum values[PG_STAT_STATEMENTS_INFO_COLS]; + bool nulls[PG_STAT_STATEMENTS_INFO_COLS]; + + if (!pgss || !pgss_hash) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("pg_stat_statements must be loaded via shared_preload_libraries"))); + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); + + /* Read global statistics for pg_stat_statements */ + { + volatile pgssSharedState *s = (volatile pgssSharedState *) pgss; + + SpinLockAcquire(&s->mutex); + stats = s->stats; + SpinLockRelease(&s->mutex); + } + + values[0] = Int64GetDatum(stats.dealloc); + values[1] = TimestampTzGetDatum(stats.stats_reset); + + PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); +} + /* * Estimate shared memory space needed. */ @@ -2018,6 +2012,15 @@ entry_dealloc(void) } pfree(entries); + + /* Increment the number of times entries are deallocated */ + { + volatile pgssSharedState *s = (volatile pgssSharedState *) pgss; + + SpinLockAcquire(&s->mutex); + s->stats.dealloc += 1; + SpinLockRelease(&s->mutex); + } } /* @@ -2471,10 +2474,20 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid) if (userid != 0 && dbid != 0 && queryid != UINT64CONST(0)) { /* If all the parameters are available, use the fast path. */ + memset(&key, 0, sizeof(pgssHashKey)); key.userid = userid; key.dbid = dbid; key.queryid = queryid; + /* Remove the key if it exists, starting with the top-level entry */ + key.toplevel = false; + entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_REMOVE, NULL); + if (entry) /* found */ + num_remove++; + + /* Also remove entries for top level statements */ + key.toplevel = true; + /* Remove the key if exists */ entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_REMOVE, NULL); if (entry) /* found */ @@ -2510,6 +2523,20 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid) if (num_entries != num_remove) goto release_lock; + /* + * Reset global statistics for pg_stat_statements since all entries are + * removed. + */ + { + volatile pgssSharedState *s = (volatile pgssSharedState *) pgss; + TimestampTz stats_reset = GetCurrentTimestamp(); + + SpinLockAcquire(&s->mutex); + s->stats.dealloc = 0; + s->stats.stats_reset = stats_reset; + SpinLockRelease(&s->mutex); + } + /* * Write new empty query file, perhaps even creating a new one to recover * if the file was missing. @@ -2542,678 +2569,6 @@ entry_reset(Oid userid, Oid dbid, uint64 queryid) LWLockRelease(pgss->lock); } -/* - * AppendJumble: Append a value that is substantive in a given query to - * the current jumble. - */ -static void -AppendJumble(pgssJumbleState *jstate, const unsigned char *item, Size size) -{ - unsigned char *jumble = jstate->jumble; - Size jumble_len = jstate->jumble_len; - - /* - * Whenever the jumble buffer is full, we hash the current contents and - * reset the buffer to contain just that hash value, thus relying on the - * hash to summarize everything so far. - */ - while (size > 0) - { - Size part_size; - - if (jumble_len >= JUMBLE_SIZE) - { - uint64 start_hash; - - start_hash = DatumGetUInt64(hash_any_extended(jumble, - JUMBLE_SIZE, 0)); - memcpy(jumble, &start_hash, sizeof(start_hash)); - jumble_len = sizeof(start_hash); - } - part_size = Min(size, JUMBLE_SIZE - jumble_len); - memcpy(jumble + jumble_len, item, part_size); - jumble_len += part_size; - item += part_size; - size -= part_size; - } - jstate->jumble_len = jumble_len; -} - -/* - * Wrappers around AppendJumble to encapsulate details of serialization - * of individual local variable elements. - */ -#define APP_JUMB(item) \ - AppendJumble(jstate, (const unsigned char *) &(item), sizeof(item)) -#define APP_JUMB_STRING(str) \ - AppendJumble(jstate, (const unsigned char *) (str), strlen(str) + 1) - -/* - * JumbleQuery: Selectively serialize the query tree, appending significant - * data to the "query jumble" while ignoring nonsignificant data. - * - * Rule of thumb for what to include is that we should ignore anything not - * semantically significant (such as alias names) as well as anything that can - * be deduced from child nodes (else we'd just be double-hashing that piece - * of information). - */ -static void -JumbleQuery(pgssJumbleState *jstate, Query *query) -{ - Assert(IsA(query, Query)); - Assert(query->utilityStmt == NULL); - - APP_JUMB(query->commandType); - /* resultRelation is usually predictable from commandType */ - JumbleExpr(jstate, (Node *) query->cteList); - JumbleRangeTable(jstate, query->rtable); - JumbleExpr(jstate, (Node *) query->jointree); - JumbleExpr(jstate, (Node *) query->targetList); - JumbleExpr(jstate, (Node *) query->onConflict); - JumbleExpr(jstate, (Node *) query->returningList); - JumbleExpr(jstate, (Node *) query->groupClause); - JumbleExpr(jstate, (Node *) query->groupingSets); - JumbleExpr(jstate, query->havingQual); - JumbleExpr(jstate, (Node *) query->windowClause); - JumbleExpr(jstate, (Node *) query->distinctClause); - JumbleExpr(jstate, (Node *) query->sortClause); - JumbleExpr(jstate, query->limitOffset); - JumbleExpr(jstate, query->limitCount); - JumbleRowMarks(jstate, query->rowMarks); - JumbleExpr(jstate, query->setOperations); -} - -/* - * Jumble a range table - */ -static void -JumbleRangeTable(pgssJumbleState *jstate, List *rtable) -{ - ListCell *lc; - - foreach(lc, rtable) - { - RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); - - APP_JUMB(rte->rtekind); - switch (rte->rtekind) - { - case RTE_RELATION: - APP_JUMB(rte->relid); - JumbleExpr(jstate, (Node *) rte->tablesample); - break; - case RTE_SUBQUERY: - JumbleQuery(jstate, rte->subquery); - break; - case RTE_JOIN: - APP_JUMB(rte->jointype); - break; - case RTE_FUNCTION: - JumbleExpr(jstate, (Node *) rte->functions); - break; - case RTE_TABLEFUNC: - JumbleExpr(jstate, (Node *) rte->tablefunc); - break; - case RTE_VALUES: - JumbleExpr(jstate, (Node *) rte->values_lists); - break; - case RTE_CTE: - - /* - * Depending on the CTE name here isn't ideal, but it's the - * only info we have to identify the referenced WITH item. - */ - APP_JUMB_STRING(rte->ctename); - APP_JUMB(rte->ctelevelsup); - break; - case RTE_NAMEDTUPLESTORE: - APP_JUMB_STRING(rte->enrname); - break; - case RTE_RESULT: - break; - default: - elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); - break; - } - } -} - -/* - * Jumble a rowMarks list - */ -static void -JumbleRowMarks(pgssJumbleState *jstate, List *rowMarks) -{ - ListCell *lc; - - foreach(lc, rowMarks) - { - RowMarkClause *rowmark = lfirst_node(RowMarkClause, lc); - - if (!rowmark->pushedDown) - { - APP_JUMB(rowmark->rti); - APP_JUMB(rowmark->strength); - APP_JUMB(rowmark->waitPolicy); - } - } -} - -/* - * Jumble an expression tree - * - * In general this function should handle all the same node types that - * expression_tree_walker() does, and therefore it's coded to be as parallel - * to that function as possible. However, since we are only invoked on - * queries immediately post-parse-analysis, we need not handle node types - * that only appear in planning. - * - * Note: the reason we don't simply use expression_tree_walker() is that the - * point of that function is to support tree walkers that don't care about - * most tree node types, but here we care about all types. We should complain - * about any unrecognized node type. - */ -static void -JumbleExpr(pgssJumbleState *jstate, Node *node) -{ - ListCell *temp; - - if (node == NULL) - return; - - /* Guard against stack overflow due to overly complex expressions */ - check_stack_depth(); - - /* - * We always emit the node's NodeTag, then any additional fields that are - * considered significant, and then we recurse to any child nodes. - */ - APP_JUMB(node->type); - - switch (nodeTag(node)) - { - case T_Var: - { - Var *var = (Var *) node; - - APP_JUMB(var->varno); - APP_JUMB(var->varattno); - APP_JUMB(var->varlevelsup); - } - break; - case T_Const: - { - Const *c = (Const *) node; - - /* We jumble only the constant's type, not its value */ - APP_JUMB(c->consttype); - /* Also, record its parse location for query normalization */ - RecordConstLocation(jstate, c->location); - } - break; - case T_Param: - { - Param *p = (Param *) node; - - APP_JUMB(p->paramkind); - APP_JUMB(p->paramid); - APP_JUMB(p->paramtype); - /* Also, track the highest external Param id */ - if (p->paramkind == PARAM_EXTERN && - p->paramid > jstate->highest_extern_param_id) - jstate->highest_extern_param_id = p->paramid; - } - break; - case T_Aggref: - { - Aggref *expr = (Aggref *) node; - - APP_JUMB(expr->aggfnoid); - JumbleExpr(jstate, (Node *) expr->aggdirectargs); - JumbleExpr(jstate, (Node *) expr->args); - JumbleExpr(jstate, (Node *) expr->aggorder); - JumbleExpr(jstate, (Node *) expr->aggdistinct); - JumbleExpr(jstate, (Node *) expr->aggfilter); - } - break; - case T_GroupingFunc: - { - GroupingFunc *grpnode = (GroupingFunc *) node; - - JumbleExpr(jstate, (Node *) grpnode->refs); - } - break; - case T_WindowFunc: - { - WindowFunc *expr = (WindowFunc *) node; - - APP_JUMB(expr->winfnoid); - APP_JUMB(expr->winref); - JumbleExpr(jstate, (Node *) expr->args); - JumbleExpr(jstate, (Node *) expr->aggfilter); - } - break; - case T_SubscriptingRef: - { - SubscriptingRef *sbsref = (SubscriptingRef *) node; - - JumbleExpr(jstate, (Node *) sbsref->refupperindexpr); - JumbleExpr(jstate, (Node *) sbsref->reflowerindexpr); - JumbleExpr(jstate, (Node *) sbsref->refexpr); - JumbleExpr(jstate, (Node *) sbsref->refassgnexpr); - } - break; - case T_FuncExpr: - { - FuncExpr *expr = (FuncExpr *) node; - - APP_JUMB(expr->funcid); - JumbleExpr(jstate, (Node *) expr->args); - } - break; - case T_NamedArgExpr: - { - NamedArgExpr *nae = (NamedArgExpr *) node; - - APP_JUMB(nae->argnumber); - JumbleExpr(jstate, (Node *) nae->arg); - } - break; - case T_OpExpr: - case T_DistinctExpr: /* struct-equivalent to OpExpr */ - case T_NullIfExpr: /* struct-equivalent to OpExpr */ - { - OpExpr *expr = (OpExpr *) node; - - APP_JUMB(expr->opno); - JumbleExpr(jstate, (Node *) expr->args); - } - break; - case T_ScalarArrayOpExpr: - { - ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; - - APP_JUMB(expr->opno); - APP_JUMB(expr->useOr); - JumbleExpr(jstate, (Node *) expr->args); - } - break; - case T_BoolExpr: - { - BoolExpr *expr = (BoolExpr *) node; - - APP_JUMB(expr->boolop); - JumbleExpr(jstate, (Node *) expr->args); - } - break; - case T_SubLink: - { - SubLink *sublink = (SubLink *) node; - - APP_JUMB(sublink->subLinkType); - APP_JUMB(sublink->subLinkId); - JumbleExpr(jstate, (Node *) sublink->testexpr); - JumbleQuery(jstate, castNode(Query, sublink->subselect)); - } - break; - case T_FieldSelect: - { - FieldSelect *fs = (FieldSelect *) node; - - APP_JUMB(fs->fieldnum); - JumbleExpr(jstate, (Node *) fs->arg); - } - break; - case T_FieldStore: - { - FieldStore *fstore = (FieldStore *) node; - - JumbleExpr(jstate, (Node *) fstore->arg); - JumbleExpr(jstate, (Node *) fstore->newvals); - } - break; - case T_RelabelType: - { - RelabelType *rt = (RelabelType *) node; - - APP_JUMB(rt->resulttype); - JumbleExpr(jstate, (Node *) rt->arg); - } - break; - case T_CoerceViaIO: - { - CoerceViaIO *cio = (CoerceViaIO *) node; - - APP_JUMB(cio->resulttype); - JumbleExpr(jstate, (Node *) cio->arg); - } - break; - case T_ArrayCoerceExpr: - { - ArrayCoerceExpr *acexpr = (ArrayCoerceExpr *) node; - - APP_JUMB(acexpr->resulttype); - JumbleExpr(jstate, (Node *) acexpr->arg); - JumbleExpr(jstate, (Node *) acexpr->elemexpr); - } - break; - case T_ConvertRowtypeExpr: - { - ConvertRowtypeExpr *crexpr = (ConvertRowtypeExpr *) node; - - APP_JUMB(crexpr->resulttype); - JumbleExpr(jstate, (Node *) crexpr->arg); - } - break; - case T_CollateExpr: - { - CollateExpr *ce = (CollateExpr *) node; - - APP_JUMB(ce->collOid); - JumbleExpr(jstate, (Node *) ce->arg); - } - break; - case T_CaseExpr: - { - CaseExpr *caseexpr = (CaseExpr *) node; - - JumbleExpr(jstate, (Node *) caseexpr->arg); - foreach(temp, caseexpr->args) - { - CaseWhen *when = lfirst_node(CaseWhen, temp); - - JumbleExpr(jstate, (Node *) when->expr); - JumbleExpr(jstate, (Node *) when->result); - } - JumbleExpr(jstate, (Node *) caseexpr->defresult); - } - break; - case T_CaseTestExpr: - { - CaseTestExpr *ct = (CaseTestExpr *) node; - - APP_JUMB(ct->typeId); - } - break; - case T_ArrayExpr: - JumbleExpr(jstate, (Node *) ((ArrayExpr *) node)->elements); - break; - case T_RowExpr: - JumbleExpr(jstate, (Node *) ((RowExpr *) node)->args); - break; - case T_RowCompareExpr: - { - RowCompareExpr *rcexpr = (RowCompareExpr *) node; - - APP_JUMB(rcexpr->rctype); - JumbleExpr(jstate, (Node *) rcexpr->largs); - JumbleExpr(jstate, (Node *) rcexpr->rargs); - } - break; - case T_CoalesceExpr: - JumbleExpr(jstate, (Node *) ((CoalesceExpr *) node)->args); - break; - case T_MinMaxExpr: - { - MinMaxExpr *mmexpr = (MinMaxExpr *) node; - - APP_JUMB(mmexpr->op); - JumbleExpr(jstate, (Node *) mmexpr->args); - } - break; - case T_SQLValueFunction: - { - SQLValueFunction *svf = (SQLValueFunction *) node; - - APP_JUMB(svf->op); - /* type is fully determined by op */ - APP_JUMB(svf->typmod); - } - break; - case T_XmlExpr: - { - XmlExpr *xexpr = (XmlExpr *) node; - - APP_JUMB(xexpr->op); - JumbleExpr(jstate, (Node *) xexpr->named_args); - JumbleExpr(jstate, (Node *) xexpr->args); - } - break; - case T_NullTest: - { - NullTest *nt = (NullTest *) node; - - APP_JUMB(nt->nulltesttype); - JumbleExpr(jstate, (Node *) nt->arg); - } - break; - case T_BooleanTest: - { - BooleanTest *bt = (BooleanTest *) node; - - APP_JUMB(bt->booltesttype); - JumbleExpr(jstate, (Node *) bt->arg); - } - break; - case T_CoerceToDomain: - { - CoerceToDomain *cd = (CoerceToDomain *) node; - - APP_JUMB(cd->resulttype); - JumbleExpr(jstate, (Node *) cd->arg); - } - break; - case T_CoerceToDomainValue: - { - CoerceToDomainValue *cdv = (CoerceToDomainValue *) node; - - APP_JUMB(cdv->typeId); - } - break; - case T_SetToDefault: - { - SetToDefault *sd = (SetToDefault *) node; - - APP_JUMB(sd->typeId); - } - break; - case T_CurrentOfExpr: - { - CurrentOfExpr *ce = (CurrentOfExpr *) node; - - APP_JUMB(ce->cvarno); - if (ce->cursor_name) - APP_JUMB_STRING(ce->cursor_name); - APP_JUMB(ce->cursor_param); - } - break; - case T_NextValueExpr: - { - NextValueExpr *nve = (NextValueExpr *) node; - - APP_JUMB(nve->seqid); - APP_JUMB(nve->typeId); - } - break; - case T_InferenceElem: - { - InferenceElem *ie = (InferenceElem *) node; - - APP_JUMB(ie->infercollid); - APP_JUMB(ie->inferopclass); - JumbleExpr(jstate, ie->expr); - } - break; - case T_TargetEntry: - { - TargetEntry *tle = (TargetEntry *) node; - - APP_JUMB(tle->resno); - APP_JUMB(tle->ressortgroupref); - JumbleExpr(jstate, (Node *) tle->expr); - } - break; - case T_RangeTblRef: - { - RangeTblRef *rtr = (RangeTblRef *) node; - - APP_JUMB(rtr->rtindex); - } - break; - case T_JoinExpr: - { - JoinExpr *join = (JoinExpr *) node; - - APP_JUMB(join->jointype); - APP_JUMB(join->isNatural); - APP_JUMB(join->rtindex); - JumbleExpr(jstate, join->larg); - JumbleExpr(jstate, join->rarg); - JumbleExpr(jstate, join->quals); - } - break; - case T_FromExpr: - { - FromExpr *from = (FromExpr *) node; - - JumbleExpr(jstate, (Node *) from->fromlist); - JumbleExpr(jstate, from->quals); - } - break; - case T_OnConflictExpr: - { - OnConflictExpr *conf = (OnConflictExpr *) node; - - APP_JUMB(conf->action); - JumbleExpr(jstate, (Node *) conf->arbiterElems); - JumbleExpr(jstate, conf->arbiterWhere); - JumbleExpr(jstate, (Node *) conf->onConflictSet); - JumbleExpr(jstate, conf->onConflictWhere); - APP_JUMB(conf->constraint); - APP_JUMB(conf->exclRelIndex); - JumbleExpr(jstate, (Node *) conf->exclRelTlist); - } - break; - case T_List: - foreach(temp, (List *) node) - { - JumbleExpr(jstate, (Node *) lfirst(temp)); - } - break; - case T_IntList: - foreach(temp, (List *) node) - { - APP_JUMB(lfirst_int(temp)); - } - break; - case T_SortGroupClause: - { - SortGroupClause *sgc = (SortGroupClause *) node; - - APP_JUMB(sgc->tleSortGroupRef); - APP_JUMB(sgc->eqop); - APP_JUMB(sgc->sortop); - APP_JUMB(sgc->nulls_first); - } - break; - case T_GroupingSet: - { - GroupingSet *gsnode = (GroupingSet *) node; - - JumbleExpr(jstate, (Node *) gsnode->content); - } - break; - case T_WindowClause: - { - WindowClause *wc = (WindowClause *) node; - - APP_JUMB(wc->winref); - APP_JUMB(wc->frameOptions); - JumbleExpr(jstate, (Node *) wc->partitionClause); - JumbleExpr(jstate, (Node *) wc->orderClause); - JumbleExpr(jstate, wc->startOffset); - JumbleExpr(jstate, wc->endOffset); - } - break; - case T_CommonTableExpr: - { - CommonTableExpr *cte = (CommonTableExpr *) node; - - /* we store the string name because RTE_CTE RTEs need it */ - APP_JUMB_STRING(cte->ctename); - APP_JUMB(cte->ctematerialized); - JumbleQuery(jstate, castNode(Query, cte->ctequery)); - } - break; - case T_SetOperationStmt: - { - SetOperationStmt *setop = (SetOperationStmt *) node; - - APP_JUMB(setop->op); - APP_JUMB(setop->all); - JumbleExpr(jstate, setop->larg); - JumbleExpr(jstate, setop->rarg); - } - break; - case T_RangeTblFunction: - { - RangeTblFunction *rtfunc = (RangeTblFunction *) node; - - JumbleExpr(jstate, rtfunc->funcexpr); - } - break; - case T_TableFunc: - { - TableFunc *tablefunc = (TableFunc *) node; - - JumbleExpr(jstate, tablefunc->docexpr); - JumbleExpr(jstate, tablefunc->rowexpr); - JumbleExpr(jstate, (Node *) tablefunc->colexprs); - } - break; - case T_TableSampleClause: - { - TableSampleClause *tsc = (TableSampleClause *) node; - - APP_JUMB(tsc->tsmhandler); - JumbleExpr(jstate, (Node *) tsc->args); - JumbleExpr(jstate, (Node *) tsc->repeatable); - } - break; - default: - /* Only a warning, since we can stumble along anyway */ - elog(WARNING, "unrecognized node type: %d", - (int) nodeTag(node)); - break; - } -} - -/* - * Record location of constant within query string of query tree - * that is currently being walked. - */ -static void -RecordConstLocation(pgssJumbleState *jstate, int location) -{ - /* -1 indicates unknown or undefined location */ - if (location >= 0) - { - /* enlarge array if needed */ - if (jstate->clocations_count >= jstate->clocations_buf_size) - { - jstate->clocations_buf_size *= 2; - jstate->clocations = (pgssLocationLen *) - repalloc(jstate->clocations, - jstate->clocations_buf_size * - sizeof(pgssLocationLen)); - } - jstate->clocations[jstate->clocations_count].location = location; - /* initialize lengths to -1 to simplify fill_in_constant_lengths */ - jstate->clocations[jstate->clocations_count].length = -1; - jstate->clocations_count++; - } -} - /* * Generate a normalized version of the query string that will be used to * represent all similar queries. @@ -3234,8 +2589,8 @@ RecordConstLocation(pgssJumbleState *jstate, int location) * Returns a palloc'd string. */ static char * -generate_normalized_query(pgssJumbleState *jstate, const char *query, - int query_loc, int *query_len_p, int encoding) +generate_normalized_query(JumbleState *jstate, const char *query, + int query_loc, int *query_len_p) { char *norm_query; int query_len = *query_len_p; @@ -3341,10 +2696,10 @@ generate_normalized_query(pgssJumbleState *jstate, const char *query, * reason for a constant to start with a '-'. */ static void -fill_in_constant_lengths(pgssJumbleState *jstate, const char *query, +fill_in_constant_lengths(JumbleState *jstate, const char *query, int query_loc) { - pgssLocationLen *locs; + LocationLen *locs; core_yyscan_t yyscanner; core_yy_extra_type yyextra; core_YYSTYPE yylval; @@ -3358,7 +2713,7 @@ fill_in_constant_lengths(pgssJumbleState *jstate, const char *query, */ if (jstate->clocations_count > 1) qsort(jstate->clocations, jstate->clocations_count, - sizeof(pgssLocationLen), comp_location); + sizeof(LocationLen), comp_location); locs = jstate->clocations; /* initialize the flex scanner --- should match raw_parser() */ @@ -3438,13 +2793,13 @@ fill_in_constant_lengths(pgssJumbleState *jstate, const char *query, } /* - * comp_location: comparator for qsorting pgssLocationLen structs by location + * comp_location: comparator for qsorting LocationLen structs by location */ static int comp_location(const void *a, const void *b) { - int l = ((const pgssLocationLen *) a)->location; - int r = ((const pgssLocationLen *) b)->location; + int l = ((const LocationLen *) a)->location; + int r = ((const LocationLen *) b)->location; if (l < r) return -1; diff --git a/contrib/pg_stat_statements/pg_stat_statements.control b/contrib/pg_stat_statements/pg_stat_statements.control index 65b18b11d258..2f1ce6ed5070 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.control +++ b/contrib/pg_stat_statements/pg_stat_statements.control @@ -1,5 +1,5 @@ # pg_stat_statements extension comment = 'track planning and execution statistics of all SQL statements executed' -default_version = '1.8' +default_version = '1.9' module_pathname = '$libdir/pg_stat_statements' relocatable = true diff --git a/contrib/pg_stat_statements/sql/pg_stat_statements.sql b/contrib/pg_stat_statements/sql/pg_stat_statements.sql index 996a24a293c5..bc3b6493e6bc 100644 --- a/contrib/pg_stat_statements/sql/pg_stat_statements.sql +++ b/contrib/pg_stat_statements/sql/pg_stat_statements.sql @@ -252,8 +252,8 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; -- -- Track the total number of rows retrieved or affected by the utility --- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW --- and SELECT INTO +-- commands of COPY, FETCH, CREATE TABLE AS, CREATE MATERIALIZED VIEW, +-- REFRESH MATERIALIZED VIEW and SELECT INTO -- SELECT pg_stat_statements_reset(); @@ -265,6 +265,7 @@ COPY pgss_ctas (a, b) FROM STDIN; 13 copy \. CREATE MATERIALIZED VIEW pgss_matv AS SELECT * FROM pgss_ctas; +REFRESH MATERIALIZED VIEW pgss_matv; BEGIN; DECLARE pgss_cursor CURSOR FOR SELECT * FROM pgss_matv; FETCH NEXT pgss_cursor; @@ -357,4 +358,83 @@ SELECT 42; SELECT 42; SELECT query, plans, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; +-- +-- access to pg_stat_statements_info view +-- +SELECT pg_stat_statements_reset(); +SELECT dealloc FROM pg_stat_statements_info; + +-- +-- top level handling +-- +SET pg_stat_statements.track = 'top'; +DELETE FROM test; +DO $$ +BEGIN + DELETE FROM test; +END; +$$ LANGUAGE plpgsql; +SELECT query, toplevel, plans, calls FROM pg_stat_statements WHERE query LIKE '%DELETE%' ORDER BY query COLLATE "C", toplevel; + +SET pg_stat_statements.track = 'all'; +DELETE FROM test; +DO $$ +BEGIN + DELETE FROM test; +END; +$$ LANGUAGE plpgsql; +SELECT query, toplevel, plans, calls FROM pg_stat_statements WHERE query LIKE '%DELETE%' ORDER BY query COLLATE "C", toplevel; + +-- FROM [ONLY] +CREATE TABLE tbl_inh(id integer); +CREATE TABLE tbl_inh_1() INHERITS (tbl_inh); +INSERT INTO tbl_inh_1 SELECT 1; + +SELECT * FROM tbl_inh; +SELECT * FROM ONLY tbl_inh; + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%FROM%tbl_inh%'; + +-- WITH TIES +CREATE TABLE limitoption AS SELECT 0 AS val FROM generate_series(1, 10); +SELECT * +FROM limitoption +WHERE val < 2 +ORDER BY val +FETCH FIRST 2 ROWS WITH TIES; + +SELECT * +FROM limitoption +WHERE val < 2 +ORDER BY val +FETCH FIRST 2 ROW ONLY; + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%FETCH FIRST%'; + +-- GROUP BY [DISTINCT] +SELECT a, b, c +FROM (VALUES (1, 2, 3), (4, NULL, 6), (7, 8, 9)) AS t (a, b, c) +GROUP BY ROLLUP(a, b), rollup(a, c) +ORDER BY a, b, c; +SELECT a, b, c +FROM (VALUES (1, 2, 3), (4, NULL, 6), (7, 8, 9)) AS t (a, b, c) +GROUP BY DISTINCT ROLLUP(a, b), rollup(a, c) +ORDER BY a, b, c; + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%GROUP BY%ROLLUP%'; + +-- GROUPING SET agglevelsup +SELECT ( + SELECT ( + SELECT GROUPING(a,b) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); +SELECT ( + SELECT ( + SELECT GROUPING(e,f) FROM (VALUES (1)) v2(c) + ) FROM (VALUES (1,2)) v1(a,b) GROUP BY (a,b) +) FROM (VALUES(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); + +SELECT COUNT(*) FROM pg_stat_statements WHERE query LIKE '%SELECT GROUPING%'; + DROP EXTENSION pg_stat_statements; diff --git a/contrib/pg_surgery/.gitignore b/contrib/pg_surgery/.gitignore new file mode 100644 index 000000000000..5dcb3ff97235 --- /dev/null +++ b/contrib/pg_surgery/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/contrib/pg_surgery/Makefile b/contrib/pg_surgery/Makefile new file mode 100644 index 000000000000..a66776c4c413 --- /dev/null +++ b/contrib/pg_surgery/Makefile @@ -0,0 +1,23 @@ +# contrib/pg_surgery/Makefile + +MODULE_big = pg_surgery +OBJS = \ + $(WIN32RES) \ + heap_surgery.o + +EXTENSION = pg_surgery +DATA = pg_surgery--1.0.sql +PGFILEDESC = "pg_surgery - perform surgery on a damaged relation" + +REGRESS = heap_surgery + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = contrib/pg_surgery +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/contrib/pg_surgery/expected/heap_surgery.out b/contrib/pg_surgery/expected/heap_surgery.out new file mode 100644 index 000000000000..d4a757ffa014 --- /dev/null +++ b/contrib/pg_surgery/expected/heap_surgery.out @@ -0,0 +1,178 @@ +create extension pg_surgery; +-- create a normal heap table and insert some rows. +-- use a temp table so that vacuum behavior doesn't depend on global xmin +create temp table htab (a int); +insert into htab values (100), (200), (300), (400), (500); +-- test empty TID array +select heap_force_freeze('htab'::regclass, ARRAY[]::tid[]); + heap_force_freeze +------------------- + +(1 row) + +-- nothing should be frozen yet +select * from htab where xmin = 2; + a +--- +(0 rows) + +-- freeze forcibly +select heap_force_freeze('htab'::regclass, ARRAY['(0, 4)']::tid[]); + heap_force_freeze +------------------- + +(1 row) + +-- now we should have one frozen tuple +select ctid, xmax from htab where xmin = 2; + ctid | xmax +-------+------ + (0,4) | 0 +(1 row) + +-- kill forcibly +select heap_force_kill('htab'::regclass, ARRAY['(0, 4)']::tid[]); + heap_force_kill +----------------- + +(1 row) + +-- should be gone now +select * from htab where ctid = '(0, 4)'; + a +--- +(0 rows) + +-- should now be skipped because it's already dead +select heap_force_kill('htab'::regclass, ARRAY['(0, 4)']::tid[]); +NOTICE: skipping tid (0, 4) for relation "htab" because it is marked dead + heap_force_kill +----------------- + +(1 row) + +select heap_force_freeze('htab'::regclass, ARRAY['(0, 4)']::tid[]); +NOTICE: skipping tid (0, 4) for relation "htab" because it is marked dead + heap_force_freeze +------------------- + +(1 row) + +-- freeze two TIDs at once while skipping an out-of-range block number +select heap_force_freeze('htab'::regclass, + ARRAY['(0, 1)', '(0, 3)', '(1, 1)']::tid[]); +NOTICE: skipping block 1 for relation "htab" because the block number is out of range + heap_force_freeze +------------------- + +(1 row) + +-- we should now have two frozen tuples +select ctid, xmax from htab where xmin = 2; + ctid | xmax +-------+------ + (0,1) | 0 + (0,3) | 0 +(2 rows) + +-- out-of-range TIDs should be skipped +select heap_force_freeze('htab'::regclass, ARRAY['(0, 0)', '(0, 6)']::tid[]); +NOTICE: skipping tid (0, 0) for relation "htab" because the item number is out of range +NOTICE: skipping tid (0, 6) for relation "htab" because the item number is out of range + heap_force_freeze +------------------- + +(1 row) + +-- set up a new table with a redirected line pointer +-- use a temp table so that vacuum behavior doesn't depend on global xmin +create temp table htab2(a int); +insert into htab2 values (100); +update htab2 set a = 200; +vacuum htab2; +-- redirected TIDs should be skipped +select heap_force_kill('htab2'::regclass, ARRAY['(0, 1)']::tid[]); +NOTICE: skipping tid (0, 1) for relation "htab2" because it redirects to item 2 + heap_force_kill +----------------- + +(1 row) + +-- now create an unused line pointer +select ctid from htab2; + ctid +------- + (0,2) +(1 row) + +update htab2 set a = 300; +select ctid from htab2; + ctid +------- + (0,3) +(1 row) + +vacuum freeze htab2; +-- unused TIDs should be skipped +select heap_force_kill('htab2'::regclass, ARRAY['(0, 2)']::tid[]); +NOTICE: skipping tid (0, 2) for relation "htab2" because it is marked unused + heap_force_kill +----------------- + +(1 row) + +-- multidimensional TID array should be rejected +select heap_force_kill('htab2'::regclass, ARRAY[['(0, 2)']]::tid[]); +ERROR: argument must be empty or one-dimensional array +-- TID array with nulls should be rejected +select heap_force_kill('htab2'::regclass, ARRAY[NULL]::tid[]); +ERROR: array must not contain nulls +-- but we should be able to kill the one tuple we have +select heap_force_kill('htab2'::regclass, ARRAY['(0, 3)']::tid[]); + heap_force_kill +----------------- + +(1 row) + +-- materialized view. +-- note that we don't commit the transaction, so autovacuum can't interfere. +begin; +create materialized view mvw as select a from generate_series(1, 3) a; +select * from mvw where xmin = 2; + a +--- +(0 rows) + +select heap_force_freeze('mvw'::regclass, ARRAY['(0, 3)']::tid[]); + heap_force_freeze +------------------- + +(1 row) + +select * from mvw where xmin = 2; + a +--- + 3 +(1 row) + +select heap_force_kill('mvw'::regclass, ARRAY['(0, 3)']::tid[]); + heap_force_kill +----------------- + +(1 row) + +select * from mvw where ctid = '(0, 3)'; + a +--- +(0 rows) + +rollback; +-- check that it fails on an unsupported relkind +create view vw as select 1; +select heap_force_kill('vw'::regclass, ARRAY['(0, 1)']::tid[]); +ERROR: "vw" is not a table, materialized view, or TOAST table +select heap_force_freeze('vw'::regclass, ARRAY['(0, 1)']::tid[]); +ERROR: "vw" is not a table, materialized view, or TOAST table +-- cleanup. +drop view vw; +drop extension pg_surgery; diff --git a/contrib/pg_surgery/heap_surgery.c b/contrib/pg_surgery/heap_surgery.c new file mode 100644 index 000000000000..d31e5f31fd42 --- /dev/null +++ b/contrib/pg_surgery/heap_surgery.c @@ -0,0 +1,428 @@ +/*------------------------------------------------------------------------- + * + * heap_surgery.c + * Functions to perform surgery on the damaged heap table. + * + * Copyright (c) 2020-2021, PostgreSQL Global Development Group + * + * IDENTIFICATION + * contrib/pg_surgery/heap_surgery.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/heapam.h" +#include "access/visibilitymap.h" +#include "catalog/pg_am_d.h" +#include "catalog/pg_proc_d.h" +#include "miscadmin.h" +#include "storage/bufmgr.h" +#include "utils/acl.h" +#include "utils/rel.h" + +PG_MODULE_MAGIC; + +/* Options to forcefully change the state of a heap tuple. */ +typedef enum HeapTupleForceOption +{ + HEAP_FORCE_KILL, + HEAP_FORCE_FREEZE +} HeapTupleForceOption; + +PG_FUNCTION_INFO_V1(heap_force_kill); +PG_FUNCTION_INFO_V1(heap_force_freeze); + +static int32 tidcmp(const void *a, const void *b); +static Datum heap_force_common(FunctionCallInfo fcinfo, + HeapTupleForceOption heap_force_opt); +static void sanity_check_tid_array(ArrayType *ta, int *ntids); +static void sanity_check_relation(Relation rel); +static BlockNumber find_tids_one_page(ItemPointer tids, int ntids, + OffsetNumber *next_start_ptr); + +/*------------------------------------------------------------------------- + * heap_force_kill() + * + * Force kill the tuple(s) pointed to by the item pointer(s) stored in the + * given TID array. + * + * Usage: SELECT heap_force_kill(regclass, tid[]); + *------------------------------------------------------------------------- + */ +Datum +heap_force_kill(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(heap_force_common(fcinfo, HEAP_FORCE_KILL)); +} + +/*------------------------------------------------------------------------- + * heap_force_freeze() + * + * Force freeze the tuple(s) pointed to by the item pointer(s) stored in the + * given TID array. + * + * Usage: SELECT heap_force_freeze(regclass, tid[]); + *------------------------------------------------------------------------- + */ +Datum +heap_force_freeze(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(heap_force_common(fcinfo, HEAP_FORCE_FREEZE)); +} + +/*------------------------------------------------------------------------- + * heap_force_common() + * + * Common code for heap_force_kill and heap_force_freeze + *------------------------------------------------------------------------- + */ +static Datum +heap_force_common(FunctionCallInfo fcinfo, HeapTupleForceOption heap_force_opt) +{ + Oid relid = PG_GETARG_OID(0); + ArrayType *ta = PG_GETARG_ARRAYTYPE_P_COPY(1); + ItemPointer tids; + int ntids, + nblocks; + Relation rel; + OffsetNumber curr_start_ptr, + next_start_ptr; + bool include_this_tid[MaxHeapTuplesPerPage]; + + if (RecoveryInProgress()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("recovery is in progress"), + errhint("heap surgery functions cannot be executed during recovery."))); + + /* Check inputs. */ + sanity_check_tid_array(ta, &ntids); + + rel = relation_open(relid, RowExclusiveLock); + + /* Check target relation. */ + sanity_check_relation(rel); + + tids = ((ItemPointer) ARR_DATA_PTR(ta)); + + /* + * If there is more than one TID in the array, sort them so that we can + * easily fetch all the TIDs belonging to one particular page from the + * array. + */ + if (ntids > 1) + qsort((void *) tids, ntids, sizeof(ItemPointerData), tidcmp); + + curr_start_ptr = next_start_ptr = 0; + nblocks = RelationGetNumberOfBlocks(rel); + + /* + * Loop, performing the necessary actions for each block. + */ + while (next_start_ptr != ntids) + { + Buffer buf; + Buffer vmbuf = InvalidBuffer; + Page page; + BlockNumber blkno; + OffsetNumber curoff; + OffsetNumber maxoffset; + int i; + bool did_modify_page = false; + bool did_modify_vm = false; + + CHECK_FOR_INTERRUPTS(); + + /* + * Find all the TIDs belonging to one particular page starting from + * next_start_ptr and process them one by one. + */ + blkno = find_tids_one_page(tids, ntids, &next_start_ptr); + + /* Check whether the block number is valid. */ + if (blkno >= nblocks) + { + /* Update the current_start_ptr before moving to the next page. */ + curr_start_ptr = next_start_ptr; + + ereport(NOTICE, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("skipping block %u for relation \"%s\" because the block number is out of range", + blkno, RelationGetRelationName(rel)))); + continue; + } + + buf = ReadBuffer(rel, blkno); + LockBufferForCleanup(buf); + + page = BufferGetPage(buf); + + maxoffset = PageGetMaxOffsetNumber(page); + + /* + * Figure out which TIDs we are going to process and which ones we are + * going to skip. + */ + memset(include_this_tid, 0, sizeof(include_this_tid)); + for (i = curr_start_ptr; i < next_start_ptr; i++) + { + OffsetNumber offno = ItemPointerGetOffsetNumberNoCheck(&tids[i]); + ItemId itemid; + + /* Check whether the offset number is valid. */ + if (offno == InvalidOffsetNumber || offno > maxoffset) + { + ereport(NOTICE, + errmsg("skipping tid (%u, %u) for relation \"%s\" because the item number is out of range", + blkno, offno, RelationGetRelationName(rel))); + continue; + } + + itemid = PageGetItemId(page, offno); + + /* Only accept an item ID that is used. */ + if (ItemIdIsRedirected(itemid)) + { + ereport(NOTICE, + errmsg("skipping tid (%u, %u) for relation \"%s\" because it redirects to item %u", + blkno, offno, RelationGetRelationName(rel), + ItemIdGetRedirect(itemid))); + continue; + } + else if (ItemIdIsDead(itemid)) + { + ereport(NOTICE, + (errmsg("skipping tid (%u, %u) for relation \"%s\" because it is marked dead", + blkno, offno, RelationGetRelationName(rel)))); + continue; + } + else if (!ItemIdIsUsed(itemid)) + { + ereport(NOTICE, + (errmsg("skipping tid (%u, %u) for relation \"%s\" because it is marked unused", + blkno, offno, RelationGetRelationName(rel)))); + continue; + } + + /* Mark it for processing. */ + Assert(offno < MaxHeapTuplesPerPage); + include_this_tid[offno] = true; + } + + /* + * Before entering the critical section, pin the visibility map page + * if it appears to be necessary. + */ + if (heap_force_opt == HEAP_FORCE_KILL && PageIsAllVisible(page)) + visibilitymap_pin(rel, blkno, &vmbuf); + + /* No ereport(ERROR) from here until all the changes are logged. */ + START_CRIT_SECTION(); + + for (curoff = FirstOffsetNumber; curoff <= maxoffset; + curoff = OffsetNumberNext(curoff)) + { + ItemId itemid; + + if (!include_this_tid[curoff]) + continue; + + itemid = PageGetItemId(page, curoff); + Assert(ItemIdIsNormal(itemid)); + + did_modify_page = true; + + if (heap_force_opt == HEAP_FORCE_KILL) + { + ItemIdSetDead(itemid); + + /* + * If the page is marked all-visible, we must clear + * PD_ALL_VISIBLE flag on the page header and an all-visible + * bit on the visibility map corresponding to the page. + */ + if (PageIsAllVisible(page)) + { + PageClearAllVisible(page); + visibilitymap_clear(rel, blkno, vmbuf, + VISIBILITYMAP_VALID_BITS); + did_modify_vm = true; + } + } + else + { + HeapTupleHeader htup; + + Assert(heap_force_opt == HEAP_FORCE_FREEZE); + + htup = (HeapTupleHeader) PageGetItem(page, itemid); + + /* + * Reset all visibility-related fields of the tuple. This + * logic should mimic heap_execute_freeze_tuple(), but we + * choose to reset xmin and ctid just to be sure that no + * potentially-garbled data is left behind. + */ + ItemPointerSet(&htup->t_ctid, blkno, curoff); + HeapTupleHeaderSetXmin(htup, FrozenTransactionId); + HeapTupleHeaderSetXmax(htup, InvalidTransactionId); + if (htup->t_infomask & HEAP_MOVED) + { + if (htup->t_infomask & HEAP_MOVED_OFF) + HeapTupleHeaderSetXvac(htup, InvalidTransactionId); + else + HeapTupleHeaderSetXvac(htup, FrozenTransactionId); + } + + /* + * Clear all the visibility-related bits of this tuple and + * mark it as frozen. Also, get rid of HOT_UPDATED and + * KEYS_UPDATES bits. + */ + htup->t_infomask &= ~HEAP_XACT_MASK; + htup->t_infomask |= (HEAP_XMIN_FROZEN | HEAP_XMAX_INVALID); + htup->t_infomask2 &= ~HEAP_HOT_UPDATED; + htup->t_infomask2 &= ~HEAP_KEYS_UPDATED; + } + } + + /* + * If the page was modified, only then, we mark the buffer dirty or do + * the WAL logging. + */ + if (did_modify_page) + { + /* Mark buffer dirty before we write WAL. */ + MarkBufferDirty(buf); + + /* XLOG stuff */ + if (RelationNeedsWAL(rel)) + log_newpage_buffer(buf, true); + } + + /* WAL log the VM page if it was modified. */ + if (did_modify_vm && RelationNeedsWAL(rel)) + log_newpage_buffer(vmbuf, false); + + END_CRIT_SECTION(); + + UnlockReleaseBuffer(buf); + + if (vmbuf != InvalidBuffer) + ReleaseBuffer(vmbuf); + + /* Update the current_start_ptr before moving to the next page. */ + curr_start_ptr = next_start_ptr; + } + + relation_close(rel, RowExclusiveLock); + + pfree(ta); + + PG_RETURN_VOID(); +} + +/*------------------------------------------------------------------------- + * tidcmp() + * + * Compare two item pointers, return -1, 0, or +1. + * + * See ItemPointerCompare for details. + * ------------------------------------------------------------------------ + */ +static int32 +tidcmp(const void *a, const void *b) +{ + ItemPointer iptr1 = ((const ItemPointer) a); + ItemPointer iptr2 = ((const ItemPointer) b); + + return ItemPointerCompare(iptr1, iptr2); +} + +/*------------------------------------------------------------------------- + * sanity_check_tid_array() + * + * Perform sanity checks on the given tid array, and set *ntids to the + * number of items in the array. + * ------------------------------------------------------------------------ + */ +static void +sanity_check_tid_array(ArrayType *ta, int *ntids) +{ + if (ARR_HASNULL(ta) && array_contains_nulls(ta)) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("array must not contain nulls"))); + + if (ARR_NDIM(ta) > 1) + ereport(ERROR, + (errcode(ERRCODE_DATA_EXCEPTION), + errmsg("argument must be empty or one-dimensional array"))); + + *ntids = ArrayGetNItems(ARR_NDIM(ta), ARR_DIMS(ta)); +} + +/*------------------------------------------------------------------------- + * sanity_check_relation() + * + * Perform sanity checks on the given relation. + * ------------------------------------------------------------------------ + */ +static void +sanity_check_relation(Relation rel) +{ + if (rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_MATVIEW && + rel->rd_rel->relkind != RELKIND_TOASTVALUE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a table, materialized view, or TOAST table", + RelationGetRelationName(rel)))); + + if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only heap AM is supported"))); + + /* Must be owner of the table or superuser. */ + if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, + get_relkind_objtype(rel->rd_rel->relkind), + RelationGetRelationName(rel)); +} + +/*------------------------------------------------------------------------- + * find_tids_one_page() + * + * Find all the tids residing in the same page as tids[next_start_ptr], and + * update next_start_ptr so that it points to the first tid in the next page. + * + * NOTE: The input tids[] array must be sorted. + * ------------------------------------------------------------------------ + */ +static BlockNumber +find_tids_one_page(ItemPointer tids, int ntids, OffsetNumber *next_start_ptr) +{ + int i; + BlockNumber prev_blkno, + blkno; + + prev_blkno = blkno = InvalidBlockNumber; + + for (i = *next_start_ptr; i < ntids; i++) + { + ItemPointerData tid = tids[i]; + + blkno = ItemPointerGetBlockNumberNoCheck(&tid); + + if (i == *next_start_ptr) + prev_blkno = blkno; + + if (prev_blkno != blkno) + break; + } + + *next_start_ptr = i; + return prev_blkno; +} diff --git a/contrib/pg_surgery/pg_surgery--1.0.sql b/contrib/pg_surgery/pg_surgery--1.0.sql new file mode 100644 index 000000000000..d1e53a07bc9d --- /dev/null +++ b/contrib/pg_surgery/pg_surgery--1.0.sql @@ -0,0 +1,18 @@ +/* contrib/pg_surgery/pg_surgery--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION pg_surgery" to load this file. \quit + +CREATE FUNCTION heap_force_kill(reloid regclass, tids tid[]) +RETURNS VOID +AS 'MODULE_PATHNAME', 'heap_force_kill' +LANGUAGE C STRICT; + +REVOKE EXECUTE ON FUNCTION heap_force_kill(regclass, tid[]) FROM PUBLIC; + +CREATE FUNCTION heap_force_freeze(reloid regclass, tids tid[]) +RETURNS VOID +AS 'MODULE_PATHNAME', 'heap_force_freeze' +LANGUAGE C STRICT; + +REVOKE EXECUTE ON FUNCTION heap_force_freeze(regclass, tid[]) FROM PUBLIC; diff --git a/contrib/pg_surgery/pg_surgery.control b/contrib/pg_surgery/pg_surgery.control new file mode 100644 index 000000000000..2bcdad1e3f7f --- /dev/null +++ b/contrib/pg_surgery/pg_surgery.control @@ -0,0 +1,5 @@ +# pg_surgery extension +comment = 'extension to perform surgery on a damaged relation' +default_version = '1.0' +module_pathname = '$libdir/pg_surgery' +relocatable = true diff --git a/contrib/pg_surgery/sql/heap_surgery.sql b/contrib/pg_surgery/sql/heap_surgery.sql new file mode 100644 index 000000000000..6526b27535de --- /dev/null +++ b/contrib/pg_surgery/sql/heap_surgery.sql @@ -0,0 +1,88 @@ +create extension pg_surgery; + +-- create a normal heap table and insert some rows. +-- use a temp table so that vacuum behavior doesn't depend on global xmin +create temp table htab (a int); +insert into htab values (100), (200), (300), (400), (500); + +-- test empty TID array +select heap_force_freeze('htab'::regclass, ARRAY[]::tid[]); + +-- nothing should be frozen yet +select * from htab where xmin = 2; + +-- freeze forcibly +select heap_force_freeze('htab'::regclass, ARRAY['(0, 4)']::tid[]); + +-- now we should have one frozen tuple +select ctid, xmax from htab where xmin = 2; + +-- kill forcibly +select heap_force_kill('htab'::regclass, ARRAY['(0, 4)']::tid[]); + +-- should be gone now +select * from htab where ctid = '(0, 4)'; + +-- should now be skipped because it's already dead +select heap_force_kill('htab'::regclass, ARRAY['(0, 4)']::tid[]); +select heap_force_freeze('htab'::regclass, ARRAY['(0, 4)']::tid[]); + +-- freeze two TIDs at once while skipping an out-of-range block number +select heap_force_freeze('htab'::regclass, + ARRAY['(0, 1)', '(0, 3)', '(1, 1)']::tid[]); + +-- we should now have two frozen tuples +select ctid, xmax from htab where xmin = 2; + +-- out-of-range TIDs should be skipped +select heap_force_freeze('htab'::regclass, ARRAY['(0, 0)', '(0, 6)']::tid[]); + +-- set up a new table with a redirected line pointer +-- use a temp table so that vacuum behavior doesn't depend on global xmin +create temp table htab2(a int); +insert into htab2 values (100); +update htab2 set a = 200; +vacuum htab2; + +-- redirected TIDs should be skipped +select heap_force_kill('htab2'::regclass, ARRAY['(0, 1)']::tid[]); + +-- now create an unused line pointer +select ctid from htab2; +update htab2 set a = 300; +select ctid from htab2; +vacuum freeze htab2; + +-- unused TIDs should be skipped +select heap_force_kill('htab2'::regclass, ARRAY['(0, 2)']::tid[]); + +-- multidimensional TID array should be rejected +select heap_force_kill('htab2'::regclass, ARRAY[['(0, 2)']]::tid[]); + +-- TID array with nulls should be rejected +select heap_force_kill('htab2'::regclass, ARRAY[NULL]::tid[]); + +-- but we should be able to kill the one tuple we have +select heap_force_kill('htab2'::regclass, ARRAY['(0, 3)']::tid[]); + +-- materialized view. +-- note that we don't commit the transaction, so autovacuum can't interfere. +begin; +create materialized view mvw as select a from generate_series(1, 3) a; + +select * from mvw where xmin = 2; +select heap_force_freeze('mvw'::regclass, ARRAY['(0, 3)']::tid[]); +select * from mvw where xmin = 2; + +select heap_force_kill('mvw'::regclass, ARRAY['(0, 3)']::tid[]); +select * from mvw where ctid = '(0, 3)'; +rollback; + +-- check that it fails on an unsupported relkind +create view vw as select 1; +select heap_force_kill('vw'::regclass, ARRAY['(0, 1)']::tid[]); +select heap_force_freeze('vw'::regclass, ARRAY['(0, 1)']::tid[]); + +-- cleanup. +drop view vw; +drop extension pg_surgery; diff --git a/contrib/pg_trgm/Makefile b/contrib/pg_trgm/Makefile index 1963eea79aac..f8ecb34a2d23 100644 --- a/contrib/pg_trgm/Makefile +++ b/contrib/pg_trgm/Makefile @@ -9,7 +9,7 @@ OBJS = \ trgm_regexp.o EXTENSION = pg_trgm -DATA = pg_trgm--1.4--1.5.sql pg_trgm--1.3--1.4.sql \ +DATA = pg_trgm--1.5--1.6.sql pg_trgm--1.4--1.5.sql pg_trgm--1.3--1.4.sql \ pg_trgm--1.3.sql pg_trgm--1.2--1.3.sql pg_trgm--1.1--1.2.sql \ pg_trgm--1.0--1.1.sql PGFILEDESC = "pg_trgm - trigram matching" diff --git a/contrib/pg_trgm/expected/pg_trgm.out b/contrib/pg_trgm/expected/pg_trgm.out index 5cd47b1a3bb5..cc7412d689e6 100644 --- a/contrib/pg_trgm/expected/pg_trgm.out +++ b/contrib/pg_trgm/expected/pg_trgm.out @@ -4780,6 +4780,12 @@ insert into test2 values ('abcdef'); insert into test2 values ('quark'); insert into test2 values (' z foo bar'); insert into test2 values ('/123/-45/'); +insert into test2 values ('line 1'); +insert into test2 values ('%line 2'); +insert into test2 values ('line 3%'); +insert into test2 values ('%line 4%'); +insert into test2 values ('%li%ne 5%'); +insert into test2 values ('li_e 6'); create index test2_idx_gin on test2 using gin (t gin_trgm_ops); set enable_seqscan=off; explain (costs off) @@ -4886,7 +4892,13 @@ select * from test2 where t ~ '(abc)*$'; quark z foo bar /123/-45/ -(4 rows) + line 1 + %line 2 + line 3% + %line 4% + %li%ne 5% + li_e 6 +(10 rows) select * from test2 where t ~* 'DEF'; t @@ -4941,7 +4953,11 @@ select * from test2 where t ~ '[a-z]{3}'; abcdef quark z foo bar -(3 rows) + line 1 + %line 2 + line 3% + %line 4% +(7 rows) select * from test2 where t ~* '(a{10}|b{10}|c{10}){10}'; t @@ -4984,6 +5000,93 @@ select * from test2 where t ~ '/\d+/-\d'; /123/-45/ (1 row) +-- test = operator +explain (costs off) + select * from test2 where t = 'abcdef'; + QUERY PLAN +------------------------------------------ + Bitmap Heap Scan on test2 + Recheck Cond: (t = 'abcdef'::text) + -> Bitmap Index Scan on test2_idx_gin + Index Cond: (t = 'abcdef'::text) +(4 rows) + +select * from test2 where t = 'abcdef'; + t +-------- + abcdef +(1 row) + +explain (costs off) + select * from test2 where t = '%line%'; + QUERY PLAN +------------------------------------------ + Bitmap Heap Scan on test2 + Recheck Cond: (t = '%line%'::text) + -> Bitmap Index Scan on test2_idx_gin + Index Cond: (t = '%line%'::text) +(4 rows) + +select * from test2 where t = '%line%'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 1'; + t +--- +(0 rows) + +select * from test2 where t = '%line 2'; + t +--------- + %line 2 +(1 row) + +select * from test2 where t = 'line 3%'; + t +--------- + line 3% +(1 row) + +select * from test2 where t = '%line 3%'; + t +--- +(0 rows) + +select * from test2 where t = '%line 4%'; + t +---------- + %line 4% +(1 row) + +select * from test2 where t = '%line 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li_ne 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li%ne 5%'; + t +----------- + %li%ne 5% +(1 row) + +select * from test2 where t = 'line 6'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 6'; + t +-------- + li_e 6 +(1 row) + drop index test2_idx_gin; create index test2_idx_gist on test2 using gist (t gist_trgm_ops); set enable_seqscan=off; @@ -5095,7 +5198,13 @@ select * from test2 where t ~ '(abc)*$'; quark z foo bar /123/-45/ -(4 rows) + line 1 + %line 2 + line 3% + %line 4% + %li%ne 5% + li_e 6 +(10 rows) select * from test2 where t ~* 'DEF'; t @@ -5150,7 +5259,11 @@ select * from test2 where t ~ '[a-z]{3}'; abcdef quark z foo bar -(3 rows) + line 1 + %line 2 + line 3% + %line 4% +(7 rows) select * from test2 where t ~* '(a{10}|b{10}|c{10}){10}'; t @@ -5193,6 +5306,89 @@ select * from test2 where t ~ '/\d+/-\d'; /123/-45/ (1 row) +-- test = operator +explain (costs off) + select * from test2 where t = 'abcdef'; + QUERY PLAN +------------------------------------------ + Index Scan using test2_idx_gist on test2 + Index Cond: (t = 'abcdef'::text) +(2 rows) + +select * from test2 where t = 'abcdef'; + t +-------- + abcdef +(1 row) + +explain (costs off) + select * from test2 where t = '%line%'; + QUERY PLAN +------------------------------------------ + Index Scan using test2_idx_gist on test2 + Index Cond: (t = '%line%'::text) +(2 rows) + +select * from test2 where t = '%line%'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 1'; + t +--- +(0 rows) + +select * from test2 where t = '%line 2'; + t +--------- + %line 2 +(1 row) + +select * from test2 where t = 'line 3%'; + t +--------- + line 3% +(1 row) + +select * from test2 where t = '%line 3%'; + t +--- +(0 rows) + +select * from test2 where t = '%line 4%'; + t +---------- + %line 4% +(1 row) + +select * from test2 where t = '%line 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li_ne 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li%ne 5%'; + t +----------- + %li%ne 5% +(1 row) + +select * from test2 where t = 'line 6'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 6'; + t +-------- + li_e 6 +(1 row) + -- Check similarity threshold (bug #14202) CREATE TEMP TABLE restaurants (city text); INSERT INTO restaurants SELECT 'Warsaw' FROM generate_series(1, 10000); diff --git a/contrib/pg_trgm/expected/pg_trgm_optimizer.out b/contrib/pg_trgm/expected/pg_trgm_optimizer.out index 0dc53f5137ad..278d5462f9a1 100644 --- a/contrib/pg_trgm/expected/pg_trgm_optimizer.out +++ b/contrib/pg_trgm/expected/pg_trgm_optimizer.out @@ -4787,6 +4787,12 @@ insert into test2 values ('abcdef'); insert into test2 values ('quark'); insert into test2 values (' z foo bar'); insert into test2 values ('/123/-45/'); +insert into test2 values ('line 1'); +insert into test2 values ('%line 2'); +insert into test2 values ('line 3%'); +insert into test2 values ('%line 4%'); +insert into test2 values ('%li%ne 5%'); +insert into test2 values ('li_e 6'); create index test2_idx_gin on test2 using gin (t gin_trgm_ops); set enable_seqscan=off; explain (costs off) @@ -4894,10 +4900,16 @@ select * from test2 where t ~ '(abc)*$'; t ------------- abcdef + line 1 + %line 4% quark + line 3% + li_e 6 z foo bar /123/-45/ -(4 rows) + %line 2 + %li%ne 5% +(10 rows) select * from test2 where t ~* 'DEF'; t @@ -4949,10 +4961,14 @@ select * from test2 where t ~ 'q'; select * from test2 where t ~ '[a-z]{3}'; t ------------- - z foo bar - quark abcdef -(3 rows) + line 1 + %line 4% + quark + line 3% + z foo bar + %line 2 +(7 rows) select * from test2 where t ~* '(a{10}|b{10}|c{10}){10}'; t @@ -4995,6 +5011,97 @@ select * from test2 where t ~ '/\d+/-\d'; /123/-45/ (1 row) +-- test = operator +explain (costs off) + select * from test2 where t = 'abcdef'; + QUERY PLAN +------------------------------------------------ + Gather Motion 1:1 (slice1; segments: 1) + -> Bitmap Heap Scan on test2 + Recheck Cond: (t = 'abcdef'::text) + -> Bitmap Index Scan on test2_idx_gin + Index Cond: (t = 'abcdef'::text) + Optimizer: Postgres query optimizer +(6 rows) + +select * from test2 where t = 'abcdef'; + t +-------- + abcdef +(1 row) + +explain (costs off) + select * from test2 where t = '%line%'; + QUERY PLAN +------------------------------------------------ + Gather Motion 1:1 (slice1; segments: 1) + -> Bitmap Heap Scan on test2 + Recheck Cond: (t = '%line%'::text) + -> Bitmap Index Scan on test2_idx_gin + Index Cond: (t = '%line%'::text) + Optimizer: Postgres query optimizer +(6 rows) + +select * from test2 where t = '%line%'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 1'; + t +--- +(0 rows) + +select * from test2 where t = '%line 2'; + t +--------- + %line 2 +(1 row) + +select * from test2 where t = 'line 3%'; + t +--------- + line 3% +(1 row) + +select * from test2 where t = '%line 3%'; + t +--- +(0 rows) + +select * from test2 where t = '%line 4%'; + t +---------- + %line 4% +(1 row) + +select * from test2 where t = '%line 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li_ne 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li%ne 5%'; + t +----------- + %li%ne 5% +(1 row) + +select * from test2 where t = 'line 6'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 6'; + t +-------- + li_e 6 +(1 row) + drop index test2_idx_gin; create index test2_idx_gist on test2 using gist (t gist_trgm_ops); set enable_seqscan=off; @@ -5102,11 +5209,17 @@ select * from test2 where t ~ 'a[bc]+d'; select * from test2 where t ~ '(abc)*$'; t ------------- - quark - abcdef z foo bar /123/-45/ -(4 rows) + %line 2 + %li%ne 5% + abcdef + line 1 + %line 4% + quark + line 3% + li_e 6 +(10 rows) select * from test2 where t ~* 'DEF'; t @@ -5158,10 +5271,14 @@ select * from test2 where t ~ 'q'; select * from test2 where t ~ '[a-z]{3}'; t ------------- - abcdef - quark z foo bar -(3 rows) + %line 2 + quark + line 3% + abcdef + line 1 + %line 4% +(7 rows) select * from test2 where t ~* '(a{10}|b{10}|c{10}){10}'; t @@ -5204,6 +5321,97 @@ select * from test2 where t ~ '/\d+/-\d'; /123/-45/ (1 row) +-- test = operator +explain (costs off) + select * from test2 where t = 'abcdef'; + QUERY PLAN +------------------------------------------------- + Gather Motion 1:1 (slice1; segments: 1) + -> Bitmap Heap Scan on test2 + Recheck Cond: (t = 'abcdef'::text) + -> Bitmap Index Scan on test2_idx_gist + Index Cond: (t = 'abcdef'::text) + Optimizer: Postgres query optimizer +(6 rows) + +select * from test2 where t = 'abcdef'; + t +-------- + abcdef +(1 row) + +explain (costs off) + select * from test2 where t = '%line%'; + QUERY PLAN +------------------------------------------------- + Gather Motion 1:1 (slice1; segments: 1) + -> Bitmap Heap Scan on test2 + Recheck Cond: (t = '%line%'::text) + -> Bitmap Index Scan on test2_idx_gist + Index Cond: (t = '%line%'::text) + Optimizer: Postgres query optimizer +(6 rows) + +select * from test2 where t = '%line%'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 1'; + t +--- +(0 rows) + +select * from test2 where t = '%line 2'; + t +--------- + %line 2 +(1 row) + +select * from test2 where t = 'line 3%'; + t +--------- + line 3% +(1 row) + +select * from test2 where t = '%line 3%'; + t +--- +(0 rows) + +select * from test2 where t = '%line 4%'; + t +---------- + %line 4% +(1 row) + +select * from test2 where t = '%line 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li_ne 5%'; + t +--- +(0 rows) + +select * from test2 where t = '%li%ne 5%'; + t +----------- + %li%ne 5% +(1 row) + +select * from test2 where t = 'line 6'; + t +--- +(0 rows) + +select * from test2 where t = 'li_e 6'; + t +-------- + li_e 6 +(1 row) + -- Check similarity threshold (bug #14202) CREATE TEMP TABLE restaurants (city text); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'city' as the Greenplum Database data distribution key for this table. diff --git a/contrib/pg_trgm/pg_trgm--1.4--1.5.sql b/contrib/pg_trgm/pg_trgm--1.4--1.5.sql index 284f88d32521..db122fce0ffc 100644 --- a/contrib/pg_trgm/pg_trgm--1.4--1.5.sql +++ b/contrib/pg_trgm/pg_trgm--1.4--1.5.sql @@ -1,4 +1,4 @@ -/* contrib/pg_trgm/pg_trgm--1.5--1.5.sql */ +/* contrib/pg_trgm/pg_trgm--1.4--1.5.sql */ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.5'" to load this file. \quit diff --git a/contrib/pg_trgm/pg_trgm--1.5--1.6.sql b/contrib/pg_trgm/pg_trgm--1.5--1.6.sql new file mode 100644 index 000000000000..9e74684eaddb --- /dev/null +++ b/contrib/pg_trgm/pg_trgm--1.5--1.6.sql @@ -0,0 +1,10 @@ +/* contrib/pg_trgm/pg_trgm--1.5--1.6.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pg_trgm UPDATE TO '1.6'" to load this file. \quit + +ALTER OPERATOR FAMILY gin_trgm_ops USING gin ADD + OPERATOR 11 pg_catalog.= (text, text); + +ALTER OPERATOR FAMILY gist_trgm_ops USING gist ADD + OPERATOR 11 pg_catalog.= (text, text); diff --git a/contrib/pg_trgm/pg_trgm.control b/contrib/pg_trgm/pg_trgm.control index ed4487e96b27..1d6a9ddf2599 100644 --- a/contrib/pg_trgm/pg_trgm.control +++ b/contrib/pg_trgm/pg_trgm.control @@ -1,6 +1,6 @@ # pg_trgm extension comment = 'text similarity measurement and index searching based on trigrams' -default_version = '1.5' +default_version = '1.6' module_pathname = '$libdir/pg_trgm' relocatable = true trusted = true diff --git a/contrib/pg_trgm/sql/pg_trgm.sql b/contrib/pg_trgm/sql/pg_trgm.sql index 6b9e37993442..d39fdfc6669b 100644 --- a/contrib/pg_trgm/sql/pg_trgm.sql +++ b/contrib/pg_trgm/sql/pg_trgm.sql @@ -101,6 +101,12 @@ insert into test2 values ('abcdef'); insert into test2 values ('quark'); insert into test2 values (' z foo bar'); insert into test2 values ('/123/-45/'); +insert into test2 values ('line 1'); +insert into test2 values ('%line 2'); +insert into test2 values ('line 3%'); +insert into test2 values ('%line 4%'); +insert into test2 values ('%li%ne 5%'); +insert into test2 values ('li_e 6'); create index test2_idx_gin on test2 using gin (t gin_trgm_ops); set enable_seqscan=off; explain (costs off) @@ -137,6 +143,23 @@ select * from test2 where t ~ ' z foo bar'; select * from test2 where t ~ ' z foo'; select * from test2 where t ~ 'qua(?!foo)'; select * from test2 where t ~ '/\d+/-\d'; +-- test = operator +explain (costs off) + select * from test2 where t = 'abcdef'; +select * from test2 where t = 'abcdef'; +explain (costs off) + select * from test2 where t = '%line%'; +select * from test2 where t = '%line%'; +select * from test2 where t = 'li_e 1'; +select * from test2 where t = '%line 2'; +select * from test2 where t = 'line 3%'; +select * from test2 where t = '%line 3%'; +select * from test2 where t = '%line 4%'; +select * from test2 where t = '%line 5%'; +select * from test2 where t = '%li_ne 5%'; +select * from test2 where t = '%li%ne 5%'; +select * from test2 where t = 'line 6'; +select * from test2 where t = 'li_e 6'; drop index test2_idx_gin; create index test2_idx_gist on test2 using gist (t gist_trgm_ops); @@ -175,6 +198,23 @@ select * from test2 where t ~ ' z foo bar'; select * from test2 where t ~ ' z foo'; select * from test2 where t ~ 'qua(?!foo)'; select * from test2 where t ~ '/\d+/-\d'; +-- test = operator +explain (costs off) + select * from test2 where t = 'abcdef'; +select * from test2 where t = 'abcdef'; +explain (costs off) + select * from test2 where t = '%line%'; +select * from test2 where t = '%line%'; +select * from test2 where t = 'li_e 1'; +select * from test2 where t = '%line 2'; +select * from test2 where t = 'line 3%'; +select * from test2 where t = '%line 3%'; +select * from test2 where t = '%line 4%'; +select * from test2 where t = '%line 5%'; +select * from test2 where t = '%li_ne 5%'; +select * from test2 where t = '%li%ne 5%'; +select * from test2 where t = 'line 6'; +select * from test2 where t = 'li_e 6'; -- Check similarity threshold (bug #14202) diff --git a/contrib/pg_trgm/trgm.h b/contrib/pg_trgm/trgm.h index b616953462e6..405a1d95528d 100644 --- a/contrib/pg_trgm/trgm.h +++ b/contrib/pg_trgm/trgm.h @@ -37,6 +37,7 @@ #define WordDistanceStrategyNumber 8 #define StrictWordSimilarityStrategyNumber 9 #define StrictWordDistanceStrategyNumber 10 +#define EqualStrategyNumber 11 typedef char trgm[3]; diff --git a/contrib/pg_trgm/trgm_gin.c b/contrib/pg_trgm/trgm_gin.c index 4dbf0ffb68ad..32fafef203f5 100644 --- a/contrib/pg_trgm/trgm_gin.c +++ b/contrib/pg_trgm/trgm_gin.c @@ -89,6 +89,7 @@ gin_extract_query_trgm(PG_FUNCTION_ARGS) case SimilarityStrategyNumber: case WordSimilarityStrategyNumber: case StrictWordSimilarityStrategyNumber: + case EqualStrategyNumber: trg = generate_trgm(VARDATA_ANY(val), VARSIZE_ANY_EXHDR(val)); break; case ILikeStrategyNumber: @@ -221,6 +222,7 @@ gin_trgm_consistent(PG_FUNCTION_ARGS) #endif /* FALL THRU */ case LikeStrategyNumber: + case EqualStrategyNumber: /* Check if all extracted trigrams are presented. */ res = true; for (i = 0; i < nkeys; i++) @@ -306,6 +308,7 @@ gin_trgm_triconsistent(PG_FUNCTION_ARGS) #endif /* FALL THRU */ case LikeStrategyNumber: + case EqualStrategyNumber: /* Check if all extracted trigrams are presented. */ res = GIN_MAYBE; for (i = 0; i < nkeys; i++) diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c index 9937ef925311..6f28db7d1edb 100644 --- a/contrib/pg_trgm/trgm_gist.c +++ b/contrib/pg_trgm/trgm_gist.c @@ -16,7 +16,7 @@ typedef struct int siglen; /* signature length in bytes */ } TrgmGistOptions; -#define LTREE_GET_ASIGLEN() (PG_HAS_OPCLASS_OPTIONS() ? \ +#define GET_SIGLEN() (PG_HAS_OPCLASS_OPTIONS() ? \ ((TrgmGistOptions *) PG_GET_OPCLASS_OPTIONS())->siglen : \ SIGLEN_DEFAULT) @@ -108,7 +108,7 @@ Datum gtrgm_compress(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - int siglen = LTREE_GET_ASIGLEN(); + int siglen = GET_SIGLEN(); GISTENTRY *retval = entry; if (entry->leafkey) @@ -195,7 +195,7 @@ gtrgm_consistent(PG_FUNCTION_ARGS) /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); - int siglen = LTREE_GET_ASIGLEN(); + int siglen = GET_SIGLEN(); TRGM *key = (TRGM *) DatumGetPointer(entry->key); TRGM *qtrg; bool res; @@ -232,6 +232,7 @@ gtrgm_consistent(PG_FUNCTION_ARGS) case SimilarityStrategyNumber: case WordSimilarityStrategyNumber: case StrictWordSimilarityStrategyNumber: + case EqualStrategyNumber: qtrg = generate_trgm(VARDATA(query), querysize - VARHDRSZ); break; @@ -338,7 +339,8 @@ gtrgm_consistent(PG_FUNCTION_ARGS) #endif /* FALL THRU */ case LikeStrategyNumber: - /* Wildcard search is inexact */ + case EqualStrategyNumber: + /* Wildcard and equal search are inexact */ *recheck = true; /* @@ -448,7 +450,7 @@ gtrgm_distance(PG_FUNCTION_ARGS) /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); - int siglen = LTREE_GET_ASIGLEN(); + int siglen = GET_SIGLEN(); TRGM *key = (TRGM *) DatumGetPointer(entry->key); TRGM *qtrg; float8 res; @@ -557,7 +559,7 @@ gtrgm_union(PG_FUNCTION_ARGS) GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); int32 len = entryvec->n; int *size = (int *) PG_GETARG_POINTER(1); - int siglen = LTREE_GET_ASIGLEN(); + int siglen = GET_SIGLEN(); int32 i; TRGM *result = gtrgm_alloc(false, siglen, NULL); BITVECP base = GETSIGN(result); @@ -583,7 +585,7 @@ gtrgm_same(PG_FUNCTION_ARGS) TRGM *a = (TRGM *) PG_GETARG_POINTER(0); TRGM *b = (TRGM *) PG_GETARG_POINTER(1); bool *result = (bool *) PG_GETARG_POINTER(2); - int siglen = LTREE_GET_ASIGLEN(); + int siglen = GET_SIGLEN(); if (ISSIGNKEY(a)) { /* then b also ISSIGNKEY */ @@ -680,7 +682,7 @@ gtrgm_penalty(PG_FUNCTION_ARGS) GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); /* always ISSIGNKEY */ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); float *penalty = (float *) PG_GETARG_POINTER(2); - int siglen = LTREE_GET_ASIGLEN(); + int siglen = GET_SIGLEN(); TRGM *origval = (TRGM *) DatumGetPointer(origentry->key); TRGM *newval = (TRGM *) DatumGetPointer(newentry->key); BITVECP orig = GETSIGN(origval); @@ -786,9 +788,9 @@ Datum gtrgm_picksplit(PG_FUNCTION_ARGS) { GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - OffsetNumber maxoff = entryvec->n - 2; + OffsetNumber maxoff = entryvec->n - 1; GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - int siglen = LTREE_GET_ASIGLEN(); + int siglen = GET_SIGLEN(); OffsetNumber k, j; TRGM *datum_l, @@ -811,8 +813,8 @@ gtrgm_picksplit(PG_FUNCTION_ARGS) SPLITCOST *costvector; /* cache the sign data for each existing item */ - cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 2)); - cache_sign = palloc(siglen * (maxoff + 2)); + cache = (CACHESIGN *) palloc(sizeof(CACHESIGN) * (maxoff + 1)); + cache_sign = palloc(siglen * (maxoff + 1)); for (k = FirstOffsetNumber; k <= maxoff; k = OffsetNumberNext(k)) fillcache(&cache[k], GETENTRY(entryvec, k), &cache_sign[siglen * k], @@ -841,7 +843,7 @@ gtrgm_picksplit(PG_FUNCTION_ARGS) } /* initialize the result vectors */ - nbytes = (maxoff + 2) * sizeof(OffsetNumber); + nbytes = maxoff * sizeof(OffsetNumber); v->spl_left = left = (OffsetNumber *) palloc(nbytes); v->spl_right = right = (OffsetNumber *) palloc(nbytes); v->spl_nleft = 0; @@ -853,9 +855,6 @@ gtrgm_picksplit(PG_FUNCTION_ARGS) union_l = GETSIGN(datum_l); union_r = GETSIGN(datum_r); - maxoff = OffsetNumberNext(maxoff); - fillcache(&cache[maxoff], GETENTRY(entryvec, maxoff), - &cache_sign[siglen * maxoff], siglen); /* sort before ... */ costvector = (SPLITCOST *) palloc(sizeof(SPLITCOST) * maxoff); @@ -944,7 +943,6 @@ gtrgm_picksplit(PG_FUNCTION_ARGS) } } - *right = *left = FirstOffsetNumber; v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); diff --git a/contrib/pg_trgm/trgm_regexp.c b/contrib/pg_trgm/trgm_regexp.c index 21e8a9f34351..bf1dea6352e0 100644 --- a/contrib/pg_trgm/trgm_regexp.c +++ b/contrib/pg_trgm/trgm_regexp.c @@ -181,7 +181,7 @@ * 7) Mark state 3 final because state 5 of source NFA is marked as final. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -282,8 +282,8 @@ typedef struct typedef int TrgmColor; /* We assume that colors returned by the regexp engine cannot be these: */ -#define COLOR_UNKNOWN (-1) -#define COLOR_BLANK (-2) +#define COLOR_UNKNOWN (-3) +#define COLOR_BLANK (-4) typedef struct { @@ -780,7 +780,8 @@ getColorInfo(regex_t *regex, TrgmNFA *trgmNFA) palloc0(colorsCount * sizeof(TrgmColorInfo)); /* - * Loop over colors, filling TrgmColorInfo about each. + * Loop over colors, filling TrgmColorInfo about each. Note we include + * WHITE (0) even though we know it'll be reported as non-expandable. */ for (i = 0; i < colorsCount; i++) { @@ -1098,9 +1099,9 @@ addKey(TrgmNFA *trgmNFA, TrgmState *state, TrgmStateKey *key) /* Add enter key to this state */ addKeyToQueue(trgmNFA, &destKey); } - else + else if (arc->co >= 0) { - /* Regular color */ + /* Regular color (including WHITE) */ TrgmColorInfo *colorInfo = &trgmNFA->colorInfo[arc->co]; if (colorInfo->expandable) @@ -1156,6 +1157,14 @@ addKey(TrgmNFA *trgmNFA, TrgmState *state, TrgmStateKey *key) addKeyToQueue(trgmNFA, &destKey); } } + else + { + /* RAINBOW: treat as unexpandable color */ + destKey.prefix.colors[0] = COLOR_UNKNOWN; + destKey.prefix.colors[1] = COLOR_UNKNOWN; + destKey.nstate = arc->to; + addKeyToQueue(trgmNFA, &destKey); + } } pfree(arcs); @@ -1211,16 +1220,22 @@ addArcs(TrgmNFA *trgmNFA, TrgmState *state) for (i = 0; i < arcsCount; i++) { regex_arc_t *arc = &arcs[i]; - TrgmColorInfo *colorInfo = &trgmNFA->colorInfo[arc->co]; + TrgmColorInfo *colorInfo; /* * Ignore non-expandable colors; addKey already handled the case. * - * We need no special check for begin/end pseudocolors here. We - * don't need to do any processing for them, and they will be - * marked non-expandable since the regex engine will have reported - * them that way. + * We need no special check for WHITE or begin/end pseudocolors + * here. We don't need to do any processing for them, and they + * will be marked non-expandable since the regex engine will have + * reported them that way. We do have to watch out for RAINBOW, + * which has a negative color number. */ + if (arc->co < 0) + continue; + Assert(arc->co < trgmNFA->ncolors); + + colorInfo = &trgmNFA->colorInfo[arc->co]; if (!colorInfo->expandable) continue; diff --git a/contrib/pg_visibility/expected/pg_visibility.out b/contrib/pg_visibility/expected/pg_visibility.out index ca4b6e186bca..315633bfea66 100644 --- a/contrib/pg_visibility/expected/pg_visibility.out +++ b/contrib/pg_visibility/expected/pg_visibility.out @@ -105,7 +105,7 @@ ERROR: "test_foreign_table" is not a table, materialized view, or TOAST table create table regular_table (a int, b text); alter table regular_table alter column b set storage external; insert into regular_table values (1, repeat('one', 1000)), (2, repeat('two', 1000)); -vacuum regular_table; +vacuum (disable_page_skipping) regular_table; select count(*) > 0 from pg_visibility('regular_table'); ?column? ---------- @@ -132,7 +132,7 @@ select count(*) > 0 from pg_visibility((select reltoastrelid from pg_class where (1 row) create materialized view matview_visibility_test as select * from regular_table; -vacuum matview_visibility_test; +vacuum (disable_page_skipping) matview_visibility_test; select count(*) > 0 from pg_visibility('matview_visibility_test'); ?column? ---------- @@ -149,7 +149,7 @@ select count(*) > 0 from pg_visibility('matview_visibility_test'); -- regular tables which are part of a partition *do* have visibility maps insert into test_partition values (1); -vacuum test_partition; +vacuum (disable_page_skipping) test_partition; select count(*) > 0 from pg_visibility('test_partition', 0); ?column? ---------- @@ -179,6 +179,69 @@ select pg_truncate_visibility_map('test_partition'); (1 row) +-- test copy freeze +create table copyfreeze (a int, b char(1500)); +-- load all rows via COPY FREEZE and ensure that all pages are set all-visible +-- and all-frozen. +begin; +truncate copyfreeze; +copy copyfreeze from stdin freeze; +commit; +select * from pg_visibility_map('copyfreeze'); + blkno | all_visible | all_frozen +-------+-------------+------------ + 0 | t | t + 1 | t | t + 2 | t | t +(3 rows) + +select * from pg_check_frozen('copyfreeze'); + t_ctid +-------- +(0 rows) + +-- load half the rows via regular COPY and rest via COPY FREEZE. The pages +-- which are touched by regular COPY must not be set all-visible/all-frozen. On +-- the other hand, pages allocated by COPY FREEZE should be marked +-- all-frozen/all-visible. +begin; +truncate copyfreeze; +copy copyfreeze from stdin; +copy copyfreeze from stdin freeze; +commit; +select * from pg_visibility_map('copyfreeze'); + blkno | all_visible | all_frozen +-------+-------------+------------ + 0 | f | f + 1 | f | f + 2 | t | t +(3 rows) + +select * from pg_check_frozen('copyfreeze'); + t_ctid +-------- +(0 rows) + +-- Try a mix of regular COPY and COPY FREEZE. +begin; +truncate copyfreeze; +copy copyfreeze from stdin freeze; +copy copyfreeze from stdin; +copy copyfreeze from stdin freeze; +commit; +select * from pg_visibility_map('copyfreeze'); + blkno | all_visible | all_frozen +-------+-------------+------------ + 0 | t | t + 1 | f | f + 2 | t | t +(3 rows) + +select * from pg_check_frozen('copyfreeze'); + t_ctid +-------- +(0 rows) + -- cleanup drop table test_partitioned; drop view test_view; @@ -188,3 +251,4 @@ drop server dummy_server; drop foreign data wrapper dummy; drop materialized view matview_visibility_test; drop table regular_table; +drop table copyfreeze; diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c index a56d446d0e27..7d384d3e2ce4 100644 --- a/contrib/pg_visibility/pg_visibility.c +++ b/contrib/pg_visibility/pg_visibility.c @@ -3,7 +3,7 @@ * pg_visibility.c * display visibility map information and page-level visibility bits * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * contrib/pg_visibility/pg_visibility.c *------------------------------------------------------------------------- diff --git a/contrib/pg_visibility/sql/pg_visibility.sql b/contrib/pg_visibility/sql/pg_visibility.sql index f79b54480b70..ff3538f9964a 100644 --- a/contrib/pg_visibility/sql/pg_visibility.sql +++ b/contrib/pg_visibility/sql/pg_visibility.sql @@ -71,7 +71,7 @@ select pg_truncate_visibility_map('test_foreign_table'); create table regular_table (a int, b text); alter table regular_table alter column b set storage external; insert into regular_table values (1, repeat('one', 1000)), (2, repeat('two', 1000)); -vacuum regular_table; +vacuum (disable_page_skipping) regular_table; select count(*) > 0 from pg_visibility('regular_table'); select count(*) > 0 from pg_visibility((select reltoastrelid from pg_class where relname = 'regular_table')); truncate regular_table; @@ -79,7 +79,7 @@ select count(*) > 0 from pg_visibility('regular_table'); select count(*) > 0 from pg_visibility((select reltoastrelid from pg_class where relname = 'regular_table')); create materialized view matview_visibility_test as select * from regular_table; -vacuum matview_visibility_test; +vacuum (disable_page_skipping) matview_visibility_test; select count(*) > 0 from pg_visibility('matview_visibility_test'); insert into regular_table values (1), (2); refresh materialized view matview_visibility_test; @@ -87,13 +87,89 @@ select count(*) > 0 from pg_visibility('matview_visibility_test'); -- regular tables which are part of a partition *do* have visibility maps insert into test_partition values (1); -vacuum test_partition; +vacuum (disable_page_skipping) test_partition; select count(*) > 0 from pg_visibility('test_partition', 0); select count(*) > 0 from pg_visibility_map('test_partition'); select count(*) > 0 from pg_visibility_map_summary('test_partition'); select * from pg_check_frozen('test_partition'); -- hopefully none select pg_truncate_visibility_map('test_partition'); +-- test copy freeze +create table copyfreeze (a int, b char(1500)); + +-- load all rows via COPY FREEZE and ensure that all pages are set all-visible +-- and all-frozen. +begin; +truncate copyfreeze; +copy copyfreeze from stdin freeze; +1 '1' +2 '2' +3 '3' +4 '4' +5 '5' +6 '6' +7 '7' +8 '8' +9 '9' +10 '10' +11 '11' +12 '12' +\. +commit; +select * from pg_visibility_map('copyfreeze'); +select * from pg_check_frozen('copyfreeze'); + +-- load half the rows via regular COPY and rest via COPY FREEZE. The pages +-- which are touched by regular COPY must not be set all-visible/all-frozen. On +-- the other hand, pages allocated by COPY FREEZE should be marked +-- all-frozen/all-visible. +begin; +truncate copyfreeze; +copy copyfreeze from stdin; +1 '1' +2 '2' +3 '3' +4 '4' +5 '5' +6 '6' +\. +copy copyfreeze from stdin freeze; +7 '7' +8 '8' +9 '9' +10 '10' +11 '11' +12 '12' +\. +commit; +select * from pg_visibility_map('copyfreeze'); +select * from pg_check_frozen('copyfreeze'); + +-- Try a mix of regular COPY and COPY FREEZE. +begin; +truncate copyfreeze; +copy copyfreeze from stdin freeze; +1 '1' +2 '2' +3 '3' +4 '4' +5 '5' +\. +copy copyfreeze from stdin; +6 '6' +\. +copy copyfreeze from stdin freeze; +7 '7' +8 '8' +9 '9' +10 '10' +11 '11' +12 '12' +\. +commit; +select * from pg_visibility_map('copyfreeze'); +select * from pg_check_frozen('copyfreeze'); + -- cleanup drop table test_partitioned; drop view test_view; @@ -103,3 +179,4 @@ drop server dummy_server; drop foreign data wrapper dummy; drop materialized view matview_visibility_test; drop table regular_table; +drop table copyfreeze; diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile index 04637385780f..c0c5f582206b 100644 --- a/contrib/pgcrypto/Makefile +++ b/contrib/pgcrypto/Makefile @@ -1,6 +1,6 @@ # contrib/pgcrypto/Makefile -INT_SRCS = md5.c sha1.c internal.c internal-sha2.c blf.c rijndael.c \ +INT_SRCS = internal.c internal-sha2.c blf.c rijndael.c \ pgp-mpi-internal.c imath.c INT_TESTS = sha2 @@ -10,8 +10,8 @@ OSSL_TESTS = sha2 des 3des cast5 ZLIB_TST = pgp-compression ZLIB_OFF_TST = pgp-zlib-DISABLED -CF_SRCS = $(if $(subst no,,$(with_openssl)), $(OSSL_SRCS), $(INT_SRCS)) -CF_TESTS = $(if $(subst no,,$(with_openssl)), $(OSSL_TESTS), $(INT_TESTS)) +CF_SRCS = $(if $(subst openssl,,$(with_ssl)), $(INT_SRCS), $(OSSL_SRCS)) +CF_TESTS = $(if $(subst openssl,,$(with_ssl)), $(INT_TESTS), $(OSSL_TESTS)) CF_PGP_TESTS = $(if $(subst no,,$(with_zlib)), $(ZLIB_TST), $(ZLIB_OFF_TST)) SRCS = \ diff --git a/contrib/pgcrypto/crypt-md5.c b/contrib/pgcrypto/crypt-md5.c index b6466d3e3178..d38721a1010a 100644 --- a/contrib/pgcrypto/crypt-md5.c +++ b/contrib/pgcrypto/crypt-md5.c @@ -65,11 +65,17 @@ px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen) /* get the length of the true salt */ sl = ep - sp; - /* */ + /* we need two PX_MD objects */ err = px_find_digest("md5", &ctx); if (err) return NULL; err = px_find_digest("md5", &ctx1); + if (err) + { + /* this path is possible under low-memory circumstances */ + px_md_free(ctx); + return NULL; + } /* The password first, since that is what is most unknown */ px_md_update(ctx, (const uint8 *) pw, strlen(pw)); diff --git a/contrib/pgcrypto/imath.c b/contrib/pgcrypto/imath.c index bc1a5659a913..8f3ed577b7c7 100644 --- a/contrib/pgcrypto/imath.c +++ b/contrib/pgcrypto/imath.c @@ -29,7 +29,7 @@ * * 4. Update this header comment. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pgcrypto/imath.c @@ -478,7 +478,7 @@ mp_int_init(mp_int z) mp_int mp_int_alloc(void) { - mp_int out = px_alloc(sizeof(mpz_t)); + mp_int out = palloc(sizeof(mpz_t)); if (out != NULL) mp_int_init(out); @@ -604,7 +604,7 @@ mp_int_free(mp_int z) assert(z != NULL); mp_int_clear(z); - px_free(z); /* note: NOT s_free() */ + pfree(z); /* note: NOT s_free() */ } mp_result @@ -2205,7 +2205,7 @@ static const mp_digit fill = (mp_digit) 0xdeadbeefabad1dea; static mp_digit * s_alloc(mp_size num) { - mp_digit *out = px_alloc(num * sizeof(mp_digit)); + mp_digit *out = palloc(num * sizeof(mp_digit)); assert(out != NULL); @@ -2228,7 +2228,7 @@ s_realloc(mp_digit *old, mp_size osize, mp_size nsize) new[ix] = fill; memcpy(new, old, osize * sizeof(mp_digit)); #else - mp_digit *new = px_realloc(old, nsize * sizeof(mp_digit)); + mp_digit *new = repalloc(old, nsize * sizeof(mp_digit)); assert(new != NULL); #endif @@ -2239,7 +2239,7 @@ s_realloc(mp_digit *old, mp_size osize, mp_size nsize) static void s_free(void *ptr) { - px_free(ptr); + pfree(ptr); } static bool diff --git a/contrib/pgcrypto/internal-sha2.c b/contrib/pgcrypto/internal-sha2.c index e06f55445eff..ecf3004e95b9 100644 --- a/contrib/pgcrypto/internal-sha2.c +++ b/contrib/pgcrypto/internal-sha2.c @@ -33,6 +33,7 @@ #include +#include "common/cryptohash.h" #include "common/sha2.h" #include "px.h" @@ -42,7 +43,6 @@ void init_sha384(PX_MD *h); void init_sha512(PX_MD *h); /* SHA224 */ - static unsigned int_sha224_len(PX_MD *h) { @@ -55,42 +55,7 @@ int_sha224_block_len(PX_MD *h) return PG_SHA224_BLOCK_LENGTH; } -static void -int_sha224_update(PX_MD *h, const uint8 *data, unsigned dlen) -{ - pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; - - pg_sha224_update(ctx, data, dlen); -} - -static void -int_sha224_reset(PX_MD *h) -{ - pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; - - pg_sha224_init(ctx); -} - -static void -int_sha224_finish(PX_MD *h, uint8 *dst) -{ - pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; - - pg_sha224_final(ctx, dst); -} - -static void -int_sha224_free(PX_MD *h) -{ - pg_sha224_ctx *ctx = (pg_sha224_ctx *) h->p.ptr; - - px_memset(ctx, 0, sizeof(*ctx)); - px_free(ctx); - px_free(h); -} - /* SHA256 */ - static unsigned int_sha256_len(PX_MD *h) { @@ -103,42 +68,7 @@ int_sha256_block_len(PX_MD *h) return PG_SHA256_BLOCK_LENGTH; } -static void -int_sha256_update(PX_MD *h, const uint8 *data, unsigned dlen) -{ - pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; - - pg_sha256_update(ctx, data, dlen); -} - -static void -int_sha256_reset(PX_MD *h) -{ - pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; - - pg_sha256_init(ctx); -} - -static void -int_sha256_finish(PX_MD *h, uint8 *dst) -{ - pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; - - pg_sha256_final(ctx, dst); -} - -static void -int_sha256_free(PX_MD *h) -{ - pg_sha256_ctx *ctx = (pg_sha256_ctx *) h->p.ptr; - - px_memset(ctx, 0, sizeof(*ctx)); - px_free(ctx); - px_free(h); -} - /* SHA384 */ - static unsigned int_sha384_len(PX_MD *h) { @@ -151,42 +81,7 @@ int_sha384_block_len(PX_MD *h) return PG_SHA384_BLOCK_LENGTH; } -static void -int_sha384_update(PX_MD *h, const uint8 *data, unsigned dlen) -{ - pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; - - pg_sha384_update(ctx, data, dlen); -} - -static void -int_sha384_reset(PX_MD *h) -{ - pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; - - pg_sha384_init(ctx); -} - -static void -int_sha384_finish(PX_MD *h, uint8 *dst) -{ - pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; - - pg_sha384_final(ctx, dst); -} - -static void -int_sha384_free(PX_MD *h) -{ - pg_sha384_ctx *ctx = (pg_sha384_ctx *) h->p.ptr; - - px_memset(ctx, 0, sizeof(*ctx)); - px_free(ctx); - px_free(h); -} - /* SHA512 */ - static unsigned int_sha512_len(PX_MD *h) { @@ -199,38 +94,41 @@ int_sha512_block_len(PX_MD *h) return PG_SHA512_BLOCK_LENGTH; } +/* Generic interface for all SHA2 methods */ static void -int_sha512_update(PX_MD *h, const uint8 *data, unsigned dlen) +int_sha2_update(PX_MD *h, const uint8 *data, unsigned dlen) { - pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - pg_sha512_update(ctx, data, dlen); + if (pg_cryptohash_update(ctx, data, dlen) < 0) + elog(ERROR, "could not update %s context", "SHA2"); } static void -int_sha512_reset(PX_MD *h) +int_sha2_reset(PX_MD *h) { - pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - pg_sha512_init(ctx); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "SHA2"); } static void -int_sha512_finish(PX_MD *h, uint8 *dst) +int_sha2_finish(PX_MD *h, uint8 *dst) { - pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - pg_sha512_final(ctx, dst); + if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0) + elog(ERROR, "could not finalize %s context", "SHA2"); } static void -int_sha512_free(PX_MD *h) +int_sha2_free(PX_MD *h) { - pg_sha512_ctx *ctx = (pg_sha512_ctx *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - px_memset(ctx, 0, sizeof(*ctx)); - px_free(ctx); - px_free(h); + pg_cryptohash_free(ctx); + pfree(h); } /* init functions */ @@ -238,19 +136,17 @@ int_sha512_free(PX_MD *h) void init_sha224(PX_MD *md) { - pg_sha224_ctx *ctx; - - ctx = px_alloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + pg_cryptohash_ctx *ctx; + ctx = pg_cryptohash_create(PG_SHA224); md->p.ptr = ctx; md->result_size = int_sha224_len; md->block_size = int_sha224_block_len; - md->reset = int_sha224_reset; - md->update = int_sha224_update; - md->finish = int_sha224_finish; - md->free = int_sha224_free; + md->reset = int_sha2_reset; + md->update = int_sha2_update; + md->finish = int_sha2_finish; + md->free = int_sha2_free; md->reset(md); } @@ -258,19 +154,17 @@ init_sha224(PX_MD *md) void init_sha256(PX_MD *md) { - pg_sha256_ctx *ctx; - - ctx = px_alloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + pg_cryptohash_ctx *ctx; + ctx = pg_cryptohash_create(PG_SHA256); md->p.ptr = ctx; md->result_size = int_sha256_len; md->block_size = int_sha256_block_len; - md->reset = int_sha256_reset; - md->update = int_sha256_update; - md->finish = int_sha256_finish; - md->free = int_sha256_free; + md->reset = int_sha2_reset; + md->update = int_sha2_update; + md->finish = int_sha2_finish; + md->free = int_sha2_free; md->reset(md); } @@ -278,19 +172,17 @@ init_sha256(PX_MD *md) void init_sha384(PX_MD *md) { - pg_sha384_ctx *ctx; - - ctx = px_alloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + pg_cryptohash_ctx *ctx; + ctx = pg_cryptohash_create(PG_SHA384); md->p.ptr = ctx; md->result_size = int_sha384_len; md->block_size = int_sha384_block_len; - md->reset = int_sha384_reset; - md->update = int_sha384_update; - md->finish = int_sha384_finish; - md->free = int_sha384_free; + md->reset = int_sha2_reset; + md->update = int_sha2_update; + md->finish = int_sha2_finish; + md->free = int_sha2_free; md->reset(md); } @@ -298,19 +190,17 @@ init_sha384(PX_MD *md) void init_sha512(PX_MD *md) { - pg_sha512_ctx *ctx; - - ctx = px_alloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + pg_cryptohash_ctx *ctx; + ctx = pg_cryptohash_create(PG_SHA512); md->p.ptr = ctx; md->result_size = int_sha512_len; md->block_size = int_sha512_block_len; - md->reset = int_sha512_reset; - md->update = int_sha512_update; - md->finish = int_sha512_finish; - md->free = int_sha512_free; + md->reset = int_sha2_reset; + md->update = int_sha2_update; + md->finish = int_sha2_finish; + md->free = int_sha2_free; md->reset(md); } diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c index f56984d5e226..39627d052749 100644 --- a/contrib/pgcrypto/internal.c +++ b/contrib/pgcrypto/internal.c @@ -34,22 +34,12 @@ #include #include "blf.h" -#include "md5.h" #include "px.h" #include "rijndael.h" -#include "sha1.h" -#ifndef MD5_DIGEST_LENGTH -#define MD5_DIGEST_LENGTH 16 -#endif - -#ifndef SHA1_DIGEST_LENGTH -#ifdef SHA1_RESULTLEN -#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN -#else -#define SHA1_DIGEST_LENGTH 20 -#endif -#endif +#include "common/cryptohash.h" +#include "common/md5.h" +#include "common/sha1.h" #define SHA1_BLOCK_SIZE 64 #define MD5_BLOCK_SIZE 64 @@ -96,35 +86,37 @@ int_md5_block_len(PX_MD *h) static void int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen) { - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - MD5Update(ctx, data, dlen); + if (pg_cryptohash_update(ctx, data, dlen) < 0) + elog(ERROR, "could not update %s context", "MD5"); } static void int_md5_reset(PX_MD *h) { - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - MD5Init(ctx); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "MD5"); } static void int_md5_finish(PX_MD *h, uint8 *dst) { - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - MD5Final(dst, ctx); + if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0) + elog(ERROR, "could not finalize %s context", "MD5"); } static void int_md5_free(PX_MD *h) { - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - px_memset(ctx, 0, sizeof(*ctx)); - px_free(ctx); - px_free(h); + pg_cryptohash_free(ctx); + pfree(h); } /* SHA1 */ @@ -144,35 +136,37 @@ int_sha1_block_len(PX_MD *h) static void int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - SHA1Update(ctx, data, dlen); + if (pg_cryptohash_update(ctx, data, dlen) < 0) + elog(ERROR, "could not update %s context", "SHA1"); } static void int_sha1_reset(PX_MD *h) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - SHA1Init(ctx); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "SHA1"); } static void int_sha1_finish(PX_MD *h, uint8 *dst) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - SHA1Final(dst, ctx); + if (pg_cryptohash_final(ctx, dst, h->result_size(h)) < 0) + elog(ERROR, "could not finalize %s context", "SHA1"); } static void int_sha1_free(PX_MD *h) { - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; + pg_cryptohash_ctx *ctx = (pg_cryptohash_ctx *) h->p.ptr; - px_memset(ctx, 0, sizeof(*ctx)); - px_free(ctx); - px_free(h); + pg_cryptohash_free(ctx); + pfree(h); } /* init functions */ @@ -180,10 +174,9 @@ int_sha1_free(PX_MD *h) static void init_md5(PX_MD *md) { - MD5_CTX *ctx; + pg_cryptohash_ctx *ctx; - ctx = px_alloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + ctx = pg_cryptohash_create(PG_MD5); md->p.ptr = ctx; @@ -200,10 +193,9 @@ init_md5(PX_MD *md) static void init_sha1(PX_MD *md) { - SHA1_CTX *ctx; + pg_cryptohash_ctx *ctx; - ctx = px_alloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + ctx = pg_cryptohash_create(PG_SHA1); md->p.ptr = ctx; @@ -246,9 +238,9 @@ intctx_free(PX_Cipher *c) if (cx) { px_memset(cx, 0, sizeof *cx); - px_free(cx); + pfree(cx); } - px_free(c); + pfree(c); } /* @@ -373,8 +365,7 @@ rj_load(int mode) PX_Cipher *c; struct int_ctx *cx; - c = px_alloc(sizeof *c); - memset(c, 0, sizeof *c); + c = palloc0(sizeof *c); c->block_size = rj_block_size; c->key_size = rj_key_size; @@ -384,8 +375,7 @@ rj_load(int mode) c->decrypt = rj_decrypt; c->free = intctx_free; - cx = px_alloc(sizeof *cx); - memset(cx, 0, sizeof *cx); + cx = palloc0(sizeof *cx); cx->mode = mode; c->ptr = cx; @@ -482,8 +472,7 @@ bf_load(int mode) PX_Cipher *c; struct int_ctx *cx; - c = px_alloc(sizeof *c); - memset(c, 0, sizeof *c); + c = palloc0(sizeof *c); c->block_size = bf_block_size; c->key_size = bf_key_size; @@ -493,8 +482,7 @@ bf_load(int mode) c->decrypt = bf_decrypt; c->free = intctx_free; - cx = px_alloc(sizeof *cx); - memset(cx, 0, sizeof *cx); + cx = palloc0(sizeof *cx); cx->mode = mode; c->ptr = cx; return c; @@ -564,7 +552,7 @@ px_find_digest(const char *name, PX_MD **res) for (p = int_digest_list; p->name; p++) if (pg_strcasecmp(p->name, name) == 0) { - h = px_alloc(sizeof(*h)); + h = palloc(sizeof(*h)); p->init(h); *res = h; diff --git a/contrib/pgcrypto/mbuf.c b/contrib/pgcrypto/mbuf.c index 548ef6209745..bc668a0e802f 100644 --- a/contrib/pgcrypto/mbuf.c +++ b/contrib/pgcrypto/mbuf.c @@ -70,9 +70,9 @@ mbuf_free(MBuf *mbuf) if (mbuf->own_data) { px_memset(mbuf->data, 0, mbuf->buf_end - mbuf->data); - px_free(mbuf->data); + pfree(mbuf->data); } - px_free(mbuf); + pfree(mbuf); return 0; } @@ -88,7 +88,7 @@ prepare_room(MBuf *mbuf, int block_len) newlen = (mbuf->buf_end - mbuf->data) + ((block_len + STEP + STEP - 1) & -STEP); - newbuf = px_realloc(mbuf->data, newlen); + newbuf = repalloc(mbuf->data, newlen); mbuf->buf_end = newbuf + newlen; mbuf->data_end = newbuf + (mbuf->data_end - mbuf->data); @@ -121,8 +121,8 @@ mbuf_create(int len) if (!len) len = 8192; - mbuf = px_alloc(sizeof *mbuf); - mbuf->data = px_alloc(len); + mbuf = palloc(sizeof *mbuf); + mbuf->data = palloc(len); mbuf->buf_end = mbuf->data + len; mbuf->data_end = mbuf->data; mbuf->read_pos = mbuf->data; @@ -138,7 +138,7 @@ mbuf_create_from_data(uint8 *data, int len) { MBuf *mbuf; - mbuf = px_alloc(sizeof *mbuf); + mbuf = palloc(sizeof *mbuf); mbuf->data = (uint8 *) data; mbuf->buf_end = mbuf->data + len; mbuf->data_end = mbuf->data + len; @@ -219,15 +219,14 @@ pullf_create(PullFilter **pf_p, const PullFilterOps *op, void *init_arg, PullFil res = 0; } - pf = px_alloc(sizeof(*pf)); - memset(pf, 0, sizeof(*pf)); + pf = palloc0(sizeof(*pf)); pf->buflen = res; pf->op = op; pf->priv = priv; pf->src = src; if (pf->buflen > 0) { - pf->buf = px_alloc(pf->buflen); + pf->buf = palloc(pf->buflen); pf->pos = 0; } else @@ -248,11 +247,11 @@ pullf_free(PullFilter *pf) if (pf->buf) { px_memset(pf->buf, 0, pf->buflen); - px_free(pf->buf); + pfree(pf->buf); } px_memset(pf, 0, sizeof(*pf)); - px_free(pf); + pfree(pf); } /* may return less data than asked, 0 means eof */ @@ -386,15 +385,14 @@ pushf_create(PushFilter **mp_p, const PushFilterOps *op, void *init_arg, PushFil res = 0; } - mp = px_alloc(sizeof(*mp)); - memset(mp, 0, sizeof(*mp)); + mp = palloc0(sizeof(*mp)); mp->block_size = res; mp->op = op; mp->priv = priv; mp->next = next; if (mp->block_size > 0) { - mp->buf = px_alloc(mp->block_size); + mp->buf = palloc(mp->block_size); mp->pos = 0; } else @@ -415,11 +413,11 @@ pushf_free(PushFilter *mp) if (mp->buf) { px_memset(mp->buf, 0, mp->block_size); - px_free(mp->buf); + pfree(mp->buf); } px_memset(mp, 0, sizeof(*mp)); - px_free(mp); + pfree(mp); } void diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c deleted file mode 100644 index 15d7c9bcdc58..000000000000 --- a/contrib/pgcrypto/md5.c +++ /dev/null @@ -1,397 +0,0 @@ -/* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * contrib/pgcrypto/md5.c - */ - -#include "postgres.h" - -#include - -#include "md5.h" - -#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s)))) - -#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z))) -#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z))) -#define H(X, Y, Z) ((X) ^ (Y) ^ (Z)) -#define I(X, Y, Z) ((Y) ^ ((X) | (~Z))) - -#define ROUND1(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define ROUND2(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define ROUND3(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define ROUND4(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define Sa 7 -#define Sb 12 -#define Sc 17 -#define Sd 22 - -#define Se 5 -#define Sf 9 -#define Sg 14 -#define Sh 20 - -#define Si 4 -#define Sj 11 -#define Sk 16 -#define Sl 23 - -#define Sm 6 -#define Sn 10 -#define So 15 -#define Sp 21 - -#define MD5_A0 0x67452301 -#define MD5_B0 0xefcdab89 -#define MD5_C0 0x98badcfe -#define MD5_D0 0x10325476 - -/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */ -static const uint32 T[65] = { - 0, - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, -}; - -static const uint8 md5_paddat[MD5_BUFLEN] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static void md5_calc(const uint8 *, md5_ctxt *); - -void -md5_init(md5_ctxt *ctxt) -{ - ctxt->md5_n = 0; - ctxt->md5_i = 0; - ctxt->md5_sta = MD5_A0; - ctxt->md5_stb = MD5_B0; - ctxt->md5_stc = MD5_C0; - ctxt->md5_std = MD5_D0; - memset(ctxt->md5_buf, 0, sizeof(ctxt->md5_buf)); -} - -void -md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len) -{ - unsigned int gap, - i; - - ctxt->md5_n += len * 8; /* byte to bit */ - gap = MD5_BUFLEN - ctxt->md5_i; - - if (len >= gap) - { - memmove(ctxt->md5_buf + ctxt->md5_i, input, gap); - md5_calc(ctxt->md5_buf, ctxt); - - for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) - md5_calc(input + i, ctxt); - - ctxt->md5_i = len - i; - memmove(ctxt->md5_buf, input + i, ctxt->md5_i); - } - else - { - memmove(ctxt->md5_buf + ctxt->md5_i, input, len); - ctxt->md5_i += len; - } -} - -void -md5_pad(md5_ctxt *ctxt) -{ - unsigned int gap; - - /* Don't count up padding. Keep md5_n. */ - gap = MD5_BUFLEN - ctxt->md5_i; - if (gap > 8) - { - memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, - gap - sizeof(ctxt->md5_n)); - } - else - { - /* including gap == 8 */ - memmove(ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap); - md5_calc(ctxt->md5_buf, ctxt); - memmove(ctxt->md5_buf, md5_paddat + gap, - MD5_BUFLEN - sizeof(ctxt->md5_n)); - } - - /* 8 byte word */ -#ifndef WORDS_BIGENDIAN - memmove(&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8); -#else - ctxt->md5_buf[56] = ctxt->md5_n8[7]; - ctxt->md5_buf[57] = ctxt->md5_n8[6]; - ctxt->md5_buf[58] = ctxt->md5_n8[5]; - ctxt->md5_buf[59] = ctxt->md5_n8[4]; - ctxt->md5_buf[60] = ctxt->md5_n8[3]; - ctxt->md5_buf[61] = ctxt->md5_n8[2]; - ctxt->md5_buf[62] = ctxt->md5_n8[1]; - ctxt->md5_buf[63] = ctxt->md5_n8[0]; -#endif - - md5_calc(ctxt->md5_buf, ctxt); -} - -void -md5_result(uint8 *digest, md5_ctxt *ctxt) -{ - /* 4 byte words */ -#ifndef WORDS_BIGENDIAN - memmove(digest, &ctxt->md5_st8[0], 16); -#else - digest[0] = ctxt->md5_st8[3]; - digest[1] = ctxt->md5_st8[2]; - digest[2] = ctxt->md5_st8[1]; - digest[3] = ctxt->md5_st8[0]; - digest[4] = ctxt->md5_st8[7]; - digest[5] = ctxt->md5_st8[6]; - digest[6] = ctxt->md5_st8[5]; - digest[7] = ctxt->md5_st8[4]; - digest[8] = ctxt->md5_st8[11]; - digest[9] = ctxt->md5_st8[10]; - digest[10] = ctxt->md5_st8[9]; - digest[11] = ctxt->md5_st8[8]; - digest[12] = ctxt->md5_st8[15]; - digest[13] = ctxt->md5_st8[14]; - digest[14] = ctxt->md5_st8[13]; - digest[15] = ctxt->md5_st8[12]; -#endif -} - -#ifdef WORDS_BIGENDIAN -static uint32 X[16]; -#endif - -static void -md5_calc(const uint8 *b64, md5_ctxt *ctxt) -{ - uint32 A = ctxt->md5_sta; - uint32 B = ctxt->md5_stb; - uint32 C = ctxt->md5_stc; - uint32 D = ctxt->md5_std; - -#ifndef WORDS_BIGENDIAN - const uint32 *X = (const uint32 *) b64; -#else - /* 4 byte words */ - /* what a brute force but fast! */ - uint8 *y = (uint8 *) X; - - y[0] = b64[3]; - y[1] = b64[2]; - y[2] = b64[1]; - y[3] = b64[0]; - y[4] = b64[7]; - y[5] = b64[6]; - y[6] = b64[5]; - y[7] = b64[4]; - y[8] = b64[11]; - y[9] = b64[10]; - y[10] = b64[9]; - y[11] = b64[8]; - y[12] = b64[15]; - y[13] = b64[14]; - y[14] = b64[13]; - y[15] = b64[12]; - y[16] = b64[19]; - y[17] = b64[18]; - y[18] = b64[17]; - y[19] = b64[16]; - y[20] = b64[23]; - y[21] = b64[22]; - y[22] = b64[21]; - y[23] = b64[20]; - y[24] = b64[27]; - y[25] = b64[26]; - y[26] = b64[25]; - y[27] = b64[24]; - y[28] = b64[31]; - y[29] = b64[30]; - y[30] = b64[29]; - y[31] = b64[28]; - y[32] = b64[35]; - y[33] = b64[34]; - y[34] = b64[33]; - y[35] = b64[32]; - y[36] = b64[39]; - y[37] = b64[38]; - y[38] = b64[37]; - y[39] = b64[36]; - y[40] = b64[43]; - y[41] = b64[42]; - y[42] = b64[41]; - y[43] = b64[40]; - y[44] = b64[47]; - y[45] = b64[46]; - y[46] = b64[45]; - y[47] = b64[44]; - y[48] = b64[51]; - y[49] = b64[50]; - y[50] = b64[49]; - y[51] = b64[48]; - y[52] = b64[55]; - y[53] = b64[54]; - y[54] = b64[53]; - y[55] = b64[52]; - y[56] = b64[59]; - y[57] = b64[58]; - y[58] = b64[57]; - y[59] = b64[56]; - y[60] = b64[63]; - y[61] = b64[62]; - y[62] = b64[61]; - y[63] = b64[60]; -#endif - - ROUND1(A, B, C, D, 0, Sa, 1); - ROUND1(D, A, B, C, 1, Sb, 2); - ROUND1(C, D, A, B, 2, Sc, 3); - ROUND1(B, C, D, A, 3, Sd, 4); - ROUND1(A, B, C, D, 4, Sa, 5); - ROUND1(D, A, B, C, 5, Sb, 6); - ROUND1(C, D, A, B, 6, Sc, 7); - ROUND1(B, C, D, A, 7, Sd, 8); - ROUND1(A, B, C, D, 8, Sa, 9); - ROUND1(D, A, B, C, 9, Sb, 10); - ROUND1(C, D, A, B, 10, Sc, 11); - ROUND1(B, C, D, A, 11, Sd, 12); - ROUND1(A, B, C, D, 12, Sa, 13); - ROUND1(D, A, B, C, 13, Sb, 14); - ROUND1(C, D, A, B, 14, Sc, 15); - ROUND1(B, C, D, A, 15, Sd, 16); - - ROUND2(A, B, C, D, 1, Se, 17); - ROUND2(D, A, B, C, 6, Sf, 18); - ROUND2(C, D, A, B, 11, Sg, 19); - ROUND2(B, C, D, A, 0, Sh, 20); - ROUND2(A, B, C, D, 5, Se, 21); - ROUND2(D, A, B, C, 10, Sf, 22); - ROUND2(C, D, A, B, 15, Sg, 23); - ROUND2(B, C, D, A, 4, Sh, 24); - ROUND2(A, B, C, D, 9, Se, 25); - ROUND2(D, A, B, C, 14, Sf, 26); - ROUND2(C, D, A, B, 3, Sg, 27); - ROUND2(B, C, D, A, 8, Sh, 28); - ROUND2(A, B, C, D, 13, Se, 29); - ROUND2(D, A, B, C, 2, Sf, 30); - ROUND2(C, D, A, B, 7, Sg, 31); - ROUND2(B, C, D, A, 12, Sh, 32); - - ROUND3(A, B, C, D, 5, Si, 33); - ROUND3(D, A, B, C, 8, Sj, 34); - ROUND3(C, D, A, B, 11, Sk, 35); - ROUND3(B, C, D, A, 14, Sl, 36); - ROUND3(A, B, C, D, 1, Si, 37); - ROUND3(D, A, B, C, 4, Sj, 38); - ROUND3(C, D, A, B, 7, Sk, 39); - ROUND3(B, C, D, A, 10, Sl, 40); - ROUND3(A, B, C, D, 13, Si, 41); - ROUND3(D, A, B, C, 0, Sj, 42); - ROUND3(C, D, A, B, 3, Sk, 43); - ROUND3(B, C, D, A, 6, Sl, 44); - ROUND3(A, B, C, D, 9, Si, 45); - ROUND3(D, A, B, C, 12, Sj, 46); - ROUND3(C, D, A, B, 15, Sk, 47); - ROUND3(B, C, D, A, 2, Sl, 48); - - ROUND4(A, B, C, D, 0, Sm, 49); - ROUND4(D, A, B, C, 7, Sn, 50); - ROUND4(C, D, A, B, 14, So, 51); - ROUND4(B, C, D, A, 5, Sp, 52); - ROUND4(A, B, C, D, 12, Sm, 53); - ROUND4(D, A, B, C, 3, Sn, 54); - ROUND4(C, D, A, B, 10, So, 55); - ROUND4(B, C, D, A, 1, Sp, 56); - ROUND4(A, B, C, D, 8, Sm, 57); - ROUND4(D, A, B, C, 15, Sn, 58); - ROUND4(C, D, A, B, 6, So, 59); - ROUND4(B, C, D, A, 13, Sp, 60); - ROUND4(A, B, C, D, 4, Sm, 61); - ROUND4(D, A, B, C, 11, Sn, 62); - ROUND4(C, D, A, B, 2, So, 63); - ROUND4(B, C, D, A, 9, Sp, 64); - - ctxt->md5_sta += A; - ctxt->md5_stb += B; - ctxt->md5_stc += C; - ctxt->md5_std += D; -} diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index 023d78d5c07e..d66a00cdcc35 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -180,7 +180,7 @@ digest_free(PX_MD *h) OSSLDigest *digest = (OSSLDigest *) h->p.ptr; free_openssl_digest(digest); - px_free(h); + pfree(h); } static int px_openssl_initialized = 0; @@ -226,6 +226,7 @@ px_find_digest(const char *name, PX_MD **res) } if (EVP_DigestInit_ex(ctx, md, NULL) == 0) { + EVP_MD_CTX_destroy(ctx); pfree(digest); return -1; } @@ -238,7 +239,7 @@ px_find_digest(const char *name, PX_MD **res) open_digests = digest; /* The PX_MD object is allocated in the current memory context. */ - h = px_alloc(sizeof(*h)); + h = palloc(sizeof(*h)); h->result_size = digest_result_size; h->block_size = digest_block_size; h->reset = digest_reset; @@ -377,7 +378,7 @@ gen_ossl_free(PX_Cipher *c) OSSLCipher *od = (OSSLCipher *) c->ptr; free_openssl_cipher(od); - px_free(c); + pfree(c); } static int @@ -427,7 +428,7 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, } if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen)) - return PXE_ERR_GENERIC; + return PXE_ENCRYPT_FAILED; return 0; } @@ -824,7 +825,7 @@ px_find_cipher(const char *name, PX_Cipher **res) od->evp_ciph = i->ciph->cipher_func(); /* The PX_Cipher is allocated in current memory context */ - c = px_alloc(sizeof(*c)); + c = palloc(sizeof(*c)); c->block_size = gen_ossl_block_size; c->key_size = gen_ossl_key_size; c->iv_size = gen_ossl_iv_size; diff --git a/contrib/pgcrypto/pgp-cfb.c b/contrib/pgcrypto/pgp-cfb.c index 8ae7c8608fb5..dafa562daa12 100644 --- a/contrib/pgcrypto/pgp-cfb.c +++ b/contrib/pgcrypto/pgp-cfb.c @@ -67,8 +67,7 @@ pgp_cfb_create(PGP_CFB **ctx_p, int algo, const uint8 *key, int key_len, return res; } - ctx = px_alloc(sizeof(*ctx)); - memset(ctx, 0, sizeof(*ctx)); + ctx = palloc0(sizeof(*ctx)); ctx->ciph = ciph; ctx->block_size = px_cipher_block_size(ciph); ctx->resync = resync; @@ -85,7 +84,7 @@ pgp_cfb_free(PGP_CFB *ctx) { px_cipher_free(ctx->ciph); px_memset(ctx, 0, sizeof(*ctx)); - px_free(ctx); + pfree(ctx); } /* diff --git a/contrib/pgcrypto/pgp-compress.c b/contrib/pgcrypto/pgp-compress.c index 3636a662b076..086bec31ae2c 100644 --- a/contrib/pgcrypto/pgp-compress.c +++ b/contrib/pgcrypto/pgp-compress.c @@ -57,13 +57,13 @@ struct ZipStat static void * z_alloc(void *priv, unsigned n_items, unsigned item_len) { - return px_alloc(n_items * item_len); + return palloc(n_items * item_len); } static void z_free(void *priv, void *addr) { - px_free(addr); + pfree(addr); } static int @@ -80,8 +80,7 @@ compress_init(PushFilter *next, void *init_arg, void **priv_p) /* * init */ - st = px_alloc(sizeof(*st)); - memset(st, 0, sizeof(*st)); + st = palloc0(sizeof(*st)); st->buf_len = ZIP_OUT_BUF; st->stream.zalloc = z_alloc; st->stream.zfree = z_free; @@ -93,7 +92,7 @@ compress_init(PushFilter *next, void *init_arg, void **priv_p) res = deflateInit(&st->stream, ctx->compress_level); if (res != Z_OK) { - px_free(st); + pfree(st); return PXE_PGP_COMPRESSION_ERROR; } *priv_p = st; @@ -174,7 +173,7 @@ compress_free(void *priv) deflateEnd(&st->stream); px_memset(st, 0, sizeof(*st)); - px_free(st); + pfree(st); } static const PushFilterOps @@ -212,8 +211,7 @@ decompress_init(void **priv_p, void *arg, PullFilter *src) && ctx->compress_algo != PGP_COMPR_ZIP) return PXE_PGP_UNSUPPORTED_COMPR; - dec = px_alloc(sizeof(*dec)); - memset(dec, 0, sizeof(*dec)); + dec = palloc0(sizeof(*dec)); dec->buf_len = ZIP_OUT_BUF; *priv_p = dec; @@ -226,7 +224,7 @@ decompress_init(void **priv_p, void *arg, PullFilter *src) res = inflateInit(&dec->stream); if (res != Z_OK) { - px_free(dec); + pfree(dec); px_debug("decompress_init: inflateInit error"); return PXE_PGP_COMPRESSION_ERROR; } @@ -293,7 +291,7 @@ decompress_read(void *priv, PullFilter *src, int len, * A stream must be terminated by a normal packet. If the last stream * packet in the source stream is a full packet, a normal empty packet * must follow. Since the underlying packet reader doesn't know that - * the compressed stream has been ended, we need to to consume the + * the compressed stream has been ended, we need to consume the * terminating packet here. This read does not harm even if the * stream has already ended. */ @@ -318,7 +316,7 @@ decompress_free(void *priv) inflateEnd(&dec->stream); px_memset(dec, 0, sizeof(*dec)); - px_free(dec); + pfree(dec); } static const PullFilterOps diff --git a/contrib/pgcrypto/pgp-decrypt.c b/contrib/pgcrypto/pgp-decrypt.c index 3ecbf9c0c259..d12dcad19452 100644 --- a/contrib/pgcrypto/pgp-decrypt.c +++ b/contrib/pgcrypto/pgp-decrypt.c @@ -211,7 +211,7 @@ pktreader_free(void *priv) struct PktData *pkt = priv; px_memset(pkt, 0, sizeof(*pkt)); - px_free(pkt); + pfree(pkt); } static struct PullFilterOps pktreader_filter = { @@ -224,13 +224,13 @@ pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, int pkttype, PGP_Context *ctx) { int res; - struct PktData *pkt = px_alloc(sizeof(*pkt)); + struct PktData *pkt = palloc(sizeof(*pkt)); pkt->type = pkttype; pkt->len = len; res = pullf_create(pf_p, &pktreader_filter, pkt, src); if (res < 0) - px_free(pkt); + pfree(pkt); return res; } @@ -447,8 +447,7 @@ mdcbuf_init(void **priv_p, void *arg, PullFilter *src) PGP_Context *ctx = arg; struct MDCBufData *st; - st = px_alloc(sizeof(*st)); - memset(st, 0, sizeof(*st)); + st = palloc0(sizeof(*st)); st->buflen = sizeof(st->buf); st->ctx = ctx; *priv_p = st; @@ -576,7 +575,7 @@ mdcbuf_free(void *priv) px_md_free(st->ctx->mdc_ctx); st->ctx->mdc_ctx = NULL; px_memset(st, 0, sizeof(*st)); - px_free(st); + pfree(st); } static struct PullFilterOps mdcbuf_filter = { diff --git a/contrib/pgcrypto/pgp-encrypt.c b/contrib/pgcrypto/pgp-encrypt.c index 46518942ac2a..f7467c9b1cb1 100644 --- a/contrib/pgcrypto/pgp-encrypt.c +++ b/contrib/pgcrypto/pgp-encrypt.c @@ -178,8 +178,7 @@ encrypt_init(PushFilter *next, void *init_arg, void **priv_p) if (res < 0) return res; - st = px_alloc(sizeof(*st)); - memset(st, 0, sizeof(*st)); + st = palloc0(sizeof(*st)); st->ciph = ciph; *priv_p = st; @@ -219,7 +218,7 @@ encrypt_free(void *priv) if (st->ciph) pgp_cfb_free(st->ciph); px_memset(st, 0, sizeof(*st)); - px_free(st); + pfree(st); } static const PushFilterOps encrypt_filter = { @@ -241,7 +240,7 @@ pkt_stream_init(PushFilter *next, void *init_arg, void **priv_p) { struct PktStreamStat *st; - st = px_alloc(sizeof(*st)); + st = palloc(sizeof(*st)); st->final_done = 0; st->pkt_block = 1 << STREAM_BLOCK_SHIFT; *priv_p = st; @@ -301,7 +300,7 @@ pkt_stream_free(void *priv) struct PktStreamStat *st = priv; px_memset(st, 0, sizeof(*st)); - px_free(st); + pfree(st); } static const PushFilterOps pkt_stream_filter = { diff --git a/contrib/pgcrypto/pgp-mpi-internal.c b/contrib/pgcrypto/pgp-mpi-internal.c index 0cea51418058..5b94e654521b 100644 --- a/contrib/pgcrypto/pgp-mpi-internal.c +++ b/contrib/pgcrypto/pgp-mpi-internal.c @@ -60,10 +60,10 @@ mp_px_rand(uint32 bits, mpz_t *res) int last_bits = bits & 7; uint8 *buf; - buf = px_alloc(bytes); + buf = palloc(bytes); if (!pg_strong_random(buf, bytes)) { - px_free(buf); + pfree(buf); return PXE_NO_RANDOM; } @@ -78,7 +78,7 @@ mp_px_rand(uint32 bits, mpz_t *res) mp_int_read_unsigned(res, buf, bytes); - px_free(buf); + pfree(buf); return 0; } diff --git a/contrib/pgcrypto/pgp-mpi.c b/contrib/pgcrypto/pgp-mpi.c index 36a6d361ab31..03be27973bec 100644 --- a/contrib/pgcrypto/pgp-mpi.c +++ b/contrib/pgcrypto/pgp-mpi.c @@ -44,7 +44,7 @@ pgp_mpi_alloc(int bits, PGP_MPI **mpi) px_debug("pgp_mpi_alloc: unreasonable request: bits=%d", bits); return PXE_PGP_CORRUPT_DATA; } - n = px_alloc(sizeof(*n) + len); + n = palloc(sizeof(*n) + len); n->bits = bits; n->bytes = len; n->data = (uint8 *) (n) + sizeof(*n); @@ -72,7 +72,7 @@ pgp_mpi_free(PGP_MPI *mpi) if (mpi == NULL) return 0; px_memset(mpi, 0, sizeof(*mpi) + mpi->bytes); - px_free(mpi); + pfree(mpi); return 0; } diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c index 62a2f351e43b..0536bfb8921c 100644 --- a/contrib/pgcrypto/pgp-pgsql.c +++ b/contrib/pgcrypto/pgp-pgsql.c @@ -32,6 +32,7 @@ #include "postgres.h" #include "catalog/pg_type.h" +#include "common/string.h" #include "funcapi.h" #include "lib/stringinfo.h" #include "mb/pg_wchar.h" @@ -92,19 +93,6 @@ convert_to_utf8(text *src) return convert_charset(src, GetDatabaseEncoding(), PG_UTF8); } -static bool -string_is_ascii(const char *str) -{ - const char *p; - - for (p = str; *p; p++) - { - if (IS_HIGHBIT_SET(*p)) - return false; - } - return true; -} - static void clear_and_pfree(text *p) { @@ -814,7 +802,7 @@ parse_key_value_arrays(ArrayType *key_array, ArrayType *val_array, v = TextDatumGetCString(key_datums[i]); - if (!string_is_ascii(v)) + if (!pg_is_ascii(v)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("header key must not contain non-ASCII characters"))); @@ -836,7 +824,7 @@ parse_key_value_arrays(ArrayType *key_array, ArrayType *val_array, v = TextDatumGetCString(val_datums[i]); - if (!string_is_ascii(v)) + if (!pg_is_ascii(v)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("header value must not contain non-ASCII characters"))); diff --git a/contrib/pgcrypto/pgp-pubenc.c b/contrib/pgcrypto/pgp-pubenc.c index 9fdcf7c31c77..c254a3727506 100644 --- a/contrib/pgcrypto/pgp-pubenc.c +++ b/contrib/pgcrypto/pgp-pubenc.c @@ -46,12 +46,12 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p) if (pad_len < 8) return PXE_BUG; - buf = px_alloc(res_len); + buf = palloc(res_len); buf[0] = 0x02; if (!pg_strong_random(buf + 1, pad_len)) { - px_free(buf); + pfree(buf); return PXE_NO_RANDOM; } @@ -64,7 +64,7 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p) if (!pg_strong_random(p, 1)) { px_memset(buf, 0, res_len); - px_free(buf); + pfree(buf); return PXE_NO_RANDOM; } } @@ -97,7 +97,7 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes) /* * create "secret message" */ - secmsg = px_alloc(klen + 3); + secmsg = palloc(klen + 3); secmsg[0] = ctx->cipher_algo; memcpy(secmsg + 1, ctx->sess_key, klen); secmsg[klen + 1] = (cksum >> 8) & 0xFF; @@ -118,10 +118,10 @@ create_secmsg(PGP_Context *ctx, PGP_MPI **msg_p, int full_bytes) if (padded) { px_memset(padded, 0, full_bytes); - px_free(padded); + pfree(padded); } px_memset(secmsg, 0, klen + 3); - px_free(secmsg); + pfree(secmsg); if (res >= 0) *msg_p = m; diff --git a/contrib/pgcrypto/pgp-pubkey.c b/contrib/pgcrypto/pgp-pubkey.c index d447e5fd4fed..9a6561caf9dd 100644 --- a/contrib/pgcrypto/pgp-pubkey.c +++ b/contrib/pgcrypto/pgp-pubkey.c @@ -39,8 +39,7 @@ pgp_key_alloc(PGP_PubKey **pk_p) { PGP_PubKey *pk; - pk = px_alloc(sizeof(*pk)); - memset(pk, 0, sizeof(*pk)); + pk = palloc0(sizeof(*pk)); *pk_p = pk; return 0; } @@ -78,7 +77,7 @@ pgp_key_free(PGP_PubKey *pk) break; } px_memset(pk, 0, sizeof(*pk)); - px_free(pk); + pfree(pk); } static int diff --git a/contrib/pgcrypto/pgp.c b/contrib/pgcrypto/pgp.c index a1f76335ab4d..64292a915b6c 100644 --- a/contrib/pgcrypto/pgp.c +++ b/contrib/pgcrypto/pgp.c @@ -222,8 +222,7 @@ pgp_init(PGP_Context **ctx_p) { PGP_Context *ctx; - ctx = px_alloc(sizeof *ctx); - memset(ctx, 0, sizeof *ctx); + ctx = palloc0(sizeof *ctx); ctx->cipher_algo = def_cipher_algo; ctx->s2k_cipher_algo = def_s2k_cipher_algo; @@ -248,7 +247,7 @@ pgp_free(PGP_Context *ctx) if (ctx->pub_key) pgp_key_free(ctx->pub_key); px_memset(ctx, 0, sizeof *ctx); - px_free(ctx); + pfree(ctx); return 0; } diff --git a/contrib/pgcrypto/px-hmac.c b/contrib/pgcrypto/px-hmac.c index 06e5148f1b42..99174d265517 100644 --- a/contrib/pgcrypto/px-hmac.c +++ b/contrib/pgcrypto/px-hmac.c @@ -57,8 +57,7 @@ hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen) PX_MD *md = h->md; bs = px_md_block_size(md); - keybuf = px_alloc(bs); - memset(keybuf, 0, bs); + keybuf = palloc0(bs); if (klen > bs) { @@ -76,7 +75,7 @@ hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen) } px_memset(keybuf, 0, bs); - px_free(keybuf); + pfree(keybuf); px_md_update(md, h->p.ipad, bs); } @@ -108,7 +107,7 @@ hmac_finish(PX_HMAC *h, uint8 *dst) bs = px_md_block_size(md); hlen = px_md_result_size(md); - buf = px_alloc(hlen); + buf = palloc(hlen); px_md_finish(md, buf); @@ -118,7 +117,7 @@ hmac_finish(PX_HMAC *h, uint8 *dst) px_md_finish(md, dst); px_memset(buf, 0, hlen); - px_free(buf); + pfree(buf); } static void @@ -131,9 +130,9 @@ hmac_free(PX_HMAC *h) px_memset(h->p.ipad, 0, bs); px_memset(h->p.opad, 0, bs); - px_free(h->p.ipad); - px_free(h->p.opad); - px_free(h); + pfree(h->p.ipad); + pfree(h->p.opad); + pfree(h); } @@ -158,9 +157,9 @@ px_find_hmac(const char *name, PX_HMAC **res) return PXE_HASH_UNUSABLE_FOR_HMAC; } - h = px_alloc(sizeof(*h)); - h->p.ipad = px_alloc(bs); - h->p.opad = px_alloc(bs); + h = palloc(sizeof(*h)); + h->p.ipad = palloc(bs); + h->p.opad = palloc(bs); h->md = md; h->result_size = hmac_result_size; diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c index 2c6704e25777..4205e9c3effe 100644 --- a/contrib/pgcrypto/px.c +++ b/contrib/pgcrypto/px.c @@ -58,6 +58,7 @@ static const struct error_desc px_err_list[] = { {PXE_MCRYPT_INTERNAL, "mcrypt internal error"}, {PXE_NO_RANDOM, "Failed to generate strong random bits"}, {PXE_DECRYPT_FAILED, "Decryption failed"}, + {PXE_ENCRYPT_FAILED, "Encryption failed"}, {PXE_PGP_CORRUPT_DATA, "Wrong key or corrupt data"}, {PXE_PGP_CORRUPT_ARMOR, "Corrupt ascii-armor"}, {PXE_PGP_UNSUPPORTED_COMPR, "Unsupported compression algorithm"}, @@ -196,8 +197,7 @@ combo_init(PX_Combo *cx, const uint8 *key, unsigned klen, ivs = px_cipher_iv_size(c); if (ivs > 0) { - ivbuf = px_alloc(ivs); - memset(ivbuf, 0, ivs); + ivbuf = palloc0(ivs); if (ivlen > ivs) memcpy(ivbuf, iv, ivs); else @@ -206,15 +206,15 @@ combo_init(PX_Combo *cx, const uint8 *key, unsigned klen, if (klen > ks) klen = ks; - keybuf = px_alloc(ks); + keybuf = palloc0(ks); memset(keybuf, 0, ks); memcpy(keybuf, key, klen); err = px_cipher_init(c, keybuf, klen, ivbuf); if (ivbuf) - px_free(ivbuf); - px_free(keybuf); + pfree(ivbuf); + pfree(keybuf); return err; } @@ -238,7 +238,7 @@ combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen, /* encrypt */ if (bs > 1) { - bbuf = px_alloc(bs * 4); + bbuf = palloc(bs * 4); bpos = dlen % bs; *rlen = dlen - bpos; memcpy(bbuf, data + *rlen, bpos); @@ -283,7 +283,7 @@ combo_encrypt(PX_Combo *cx, const uint8 *data, unsigned dlen, } out: if (bbuf) - px_free(bbuf); + pfree(bbuf); return err; } @@ -354,7 +354,7 @@ combo_free(PX_Combo *cx) if (cx->cipher) px_cipher_free(cx->cipher); px_memset(cx, 0, sizeof(*cx)); - px_free(cx); + pfree(cx); } /* PARSER */ @@ -411,17 +411,14 @@ px_find_combo(const char *name, PX_Combo **res) PX_Combo *cx; - cx = px_alloc(sizeof(*cx)); - memset(cx, 0, sizeof(*cx)); - - buf = px_alloc(strlen(name) + 1); - strcpy(buf, name); + cx = palloc0(sizeof(*cx)); + buf = pstrdup(name); err = parse_cipher_name(buf, &s_cipher, &s_pad); if (err) { - px_free(buf); - px_free(cx); + pfree(buf); + pfree(cx); return err; } @@ -448,7 +445,7 @@ px_find_combo(const char *name, PX_Combo **res) cx->decrypt_len = combo_decrypt_len; cx->free = combo_free; - px_free(buf); + pfree(buf); *res = cx; @@ -457,7 +454,7 @@ px_find_combo(const char *name, PX_Combo **res) err1: if (cx->cipher) px_cipher_free(cx->cipher); - px_free(cx); - px_free(buf); + pfree(cx); + pfree(buf); return PXE_NO_CIPHER; } diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h index 0212ee8af61c..335d00eb1767 100644 --- a/contrib/pgcrypto/px.h +++ b/contrib/pgcrypto/px.h @@ -37,19 +37,6 @@ /* keep debug messages? */ #define PX_DEBUG -/* a way to disable palloc - * - useful if compiled into standalone - */ -#ifndef PX_OWN_ALLOC -#define px_alloc(s) palloc(s) -#define px_realloc(p, s) repalloc(p, s) -#define px_free(p) pfree(p) -#else -void *px_alloc(size_t s); -void *px_realloc(void *p, size_t s); -void px_free(void *p); -#endif - /* max salt returned */ #define PX_MAX_SALT_LEN 128 @@ -74,6 +61,7 @@ void px_free(void *p); #define PXE_MCRYPT_INTERNAL -16 #define PXE_NO_RANDOM -17 #define PXE_DECRYPT_FAILED -18 +#define PXE_ENCRYPT_FAILED -19 #define PXE_PGP_CORRUPT_DATA -100 #define PXE_PGP_CORRUPT_ARMOR -101 diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c deleted file mode 100644 index 64671ac64d9a..000000000000 --- a/contrib/pgcrypto/sha1.c +++ /dev/null @@ -1,331 +0,0 @@ -/* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * contrib/pgcrypto/sha1.c - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://www.itl.nist.gov/fipspubs/fip180-1.htm - * implemented by Jun-ichiro itojun Itoh - */ - -#include "postgres.h" - -#include - -#include "sha1.h" - -/* constant table */ -static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6}; - -#define K(t) _K[(t) / 20] - -#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) -#define F1(b, c, d) (((b) ^ (c)) ^ (d)) -#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) -#define F3(b, c, d) (((b) ^ (c)) ^ (d)) - -#define S(n, x) (((x) << (n)) | ((x) >> (32 - (n)))) - -#define H(n) (ctxt->h.b32[(n)]) -#define COUNT (ctxt->count) -#define BCOUNT (ctxt->c.b64[0] / 8) -#define W(n) (ctxt->m.b32[(n)]) - -#define PUTPAD(x) \ -do { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ -} while (0) - -static void sha1_step(struct sha1_ctxt *); - -static void -sha1_step(struct sha1_ctxt *ctxt) -{ - uint32 a, - b, - c, - d, - e; - size_t t, - s; - uint32 tmp; - -#ifndef WORDS_BIGENDIAN - struct sha1_ctxt tctxt; - - memmove(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); - ctxt->m.b8[0] = tctxt.m.b8[3]; - ctxt->m.b8[1] = tctxt.m.b8[2]; - ctxt->m.b8[2] = tctxt.m.b8[1]; - ctxt->m.b8[3] = tctxt.m.b8[0]; - ctxt->m.b8[4] = tctxt.m.b8[7]; - ctxt->m.b8[5] = tctxt.m.b8[6]; - ctxt->m.b8[6] = tctxt.m.b8[5]; - ctxt->m.b8[7] = tctxt.m.b8[4]; - ctxt->m.b8[8] = tctxt.m.b8[11]; - ctxt->m.b8[9] = tctxt.m.b8[10]; - ctxt->m.b8[10] = tctxt.m.b8[9]; - ctxt->m.b8[11] = tctxt.m.b8[8]; - ctxt->m.b8[12] = tctxt.m.b8[15]; - ctxt->m.b8[13] = tctxt.m.b8[14]; - ctxt->m.b8[14] = tctxt.m.b8[13]; - ctxt->m.b8[15] = tctxt.m.b8[12]; - ctxt->m.b8[16] = tctxt.m.b8[19]; - ctxt->m.b8[17] = tctxt.m.b8[18]; - ctxt->m.b8[18] = tctxt.m.b8[17]; - ctxt->m.b8[19] = tctxt.m.b8[16]; - ctxt->m.b8[20] = tctxt.m.b8[23]; - ctxt->m.b8[21] = tctxt.m.b8[22]; - ctxt->m.b8[22] = tctxt.m.b8[21]; - ctxt->m.b8[23] = tctxt.m.b8[20]; - ctxt->m.b8[24] = tctxt.m.b8[27]; - ctxt->m.b8[25] = tctxt.m.b8[26]; - ctxt->m.b8[26] = tctxt.m.b8[25]; - ctxt->m.b8[27] = tctxt.m.b8[24]; - ctxt->m.b8[28] = tctxt.m.b8[31]; - ctxt->m.b8[29] = tctxt.m.b8[30]; - ctxt->m.b8[30] = tctxt.m.b8[29]; - ctxt->m.b8[31] = tctxt.m.b8[28]; - ctxt->m.b8[32] = tctxt.m.b8[35]; - ctxt->m.b8[33] = tctxt.m.b8[34]; - ctxt->m.b8[34] = tctxt.m.b8[33]; - ctxt->m.b8[35] = tctxt.m.b8[32]; - ctxt->m.b8[36] = tctxt.m.b8[39]; - ctxt->m.b8[37] = tctxt.m.b8[38]; - ctxt->m.b8[38] = tctxt.m.b8[37]; - ctxt->m.b8[39] = tctxt.m.b8[36]; - ctxt->m.b8[40] = tctxt.m.b8[43]; - ctxt->m.b8[41] = tctxt.m.b8[42]; - ctxt->m.b8[42] = tctxt.m.b8[41]; - ctxt->m.b8[43] = tctxt.m.b8[40]; - ctxt->m.b8[44] = tctxt.m.b8[47]; - ctxt->m.b8[45] = tctxt.m.b8[46]; - ctxt->m.b8[46] = tctxt.m.b8[45]; - ctxt->m.b8[47] = tctxt.m.b8[44]; - ctxt->m.b8[48] = tctxt.m.b8[51]; - ctxt->m.b8[49] = tctxt.m.b8[50]; - ctxt->m.b8[50] = tctxt.m.b8[49]; - ctxt->m.b8[51] = tctxt.m.b8[48]; - ctxt->m.b8[52] = tctxt.m.b8[55]; - ctxt->m.b8[53] = tctxt.m.b8[54]; - ctxt->m.b8[54] = tctxt.m.b8[53]; - ctxt->m.b8[55] = tctxt.m.b8[52]; - ctxt->m.b8[56] = tctxt.m.b8[59]; - ctxt->m.b8[57] = tctxt.m.b8[58]; - ctxt->m.b8[58] = tctxt.m.b8[57]; - ctxt->m.b8[59] = tctxt.m.b8[56]; - ctxt->m.b8[60] = tctxt.m.b8[63]; - ctxt->m.b8[61] = tctxt.m.b8[62]; - ctxt->m.b8[62] = tctxt.m.b8[61]; - ctxt->m.b8[63] = tctxt.m.b8[60]; -#endif - - a = H(0); - b = H(1); - c = H(2); - d = H(3); - e = H(4); - - for (t = 0; t < 20; t++) - { - s = t & 0x0f; - if (t >= 16) - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 20; t < 40; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 40; t < 60; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 60; t < 80; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - - H(0) = H(0) + a; - H(1) = H(1) + b; - H(2) = H(2) + c; - H(3) = H(3) + d; - H(4) = H(4) + e; - - memset(&ctxt->m.b8[0], 0, 64); -} - -/*------------------------------------------------------------*/ - -void -sha1_init(struct sha1_ctxt *ctxt) -{ - memset(ctxt, 0, sizeof(struct sha1_ctxt)); - H(0) = 0x67452301; - H(1) = 0xefcdab89; - H(2) = 0x98badcfe; - H(3) = 0x10325476; - H(4) = 0xc3d2e1f0; -} - -void -sha1_pad(struct sha1_ctxt *ctxt) -{ - size_t padlen; /* pad length in bytes */ - size_t padstart; - - PUTPAD(0x80); - - padstart = COUNT % 64; - padlen = 64 - padstart; - if (padlen < 8) - { - memset(&ctxt->m.b8[padstart], 0, padlen); - COUNT += padlen; - COUNT %= 64; - sha1_step(ctxt); - padstart = COUNT % 64; /* should be 0 */ - padlen = 64 - padstart; /* should be 64 */ - } - memset(&ctxt->m.b8[padstart], 0, padlen - 8); - COUNT += (padlen - 8); - COUNT %= 64; -#ifdef WORDS_BIGENDIAN - PUTPAD(ctxt->c.b8[0]); - PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[7]); -#else - PUTPAD(ctxt->c.b8[7]); - PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[0]); -#endif -} - -void -sha1_loop(struct sha1_ctxt *ctxt, const uint8 *input0, size_t len) -{ - const uint8 *input; - size_t gaplen; - size_t gapstart; - size_t off; - size_t copysiz; - - input = (const uint8 *) input0; - off = 0; - - while (off < len) - { - gapstart = COUNT % 64; - gaplen = 64 - gapstart; - - copysiz = (gaplen < len - off) ? gaplen : len - off; - memmove(&ctxt->m.b8[gapstart], &input[off], copysiz); - COUNT += copysiz; - COUNT %= 64; - ctxt->c.b64[0] += copysiz * 8; - if (COUNT % 64 == 0) - sha1_step(ctxt); - off += copysiz; - } -} - -void -sha1_result(struct sha1_ctxt *ctxt, uint8 *digest0) -{ - uint8 *digest; - - digest = (uint8 *) digest0; - sha1_pad(ctxt); -#ifdef WORDS_BIGENDIAN - memmove(digest, &ctxt->h.b8[0], 20); -#else - digest[0] = ctxt->h.b8[3]; - digest[1] = ctxt->h.b8[2]; - digest[2] = ctxt->h.b8[1]; - digest[3] = ctxt->h.b8[0]; - digest[4] = ctxt->h.b8[7]; - digest[5] = ctxt->h.b8[6]; - digest[6] = ctxt->h.b8[5]; - digest[7] = ctxt->h.b8[4]; - digest[8] = ctxt->h.b8[11]; - digest[9] = ctxt->h.b8[10]; - digest[10] = ctxt->h.b8[9]; - digest[11] = ctxt->h.b8[8]; - digest[12] = ctxt->h.b8[15]; - digest[13] = ctxt->h.b8[14]; - digest[14] = ctxt->h.b8[13]; - digest[15] = ctxt->h.b8[12]; - digest[16] = ctxt->h.b8[19]; - digest[17] = ctxt->h.b8[18]; - digest[18] = ctxt->h.b8[17]; - digest[19] = ctxt->h.b8[16]; -#endif -} diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c index c2514a69ed39..4497d444ac7a 100644 --- a/contrib/pgrowlocks/pgrowlocks.c +++ b/contrib/pgrowlocks/pgrowlocks.c @@ -130,7 +130,7 @@ pgrowlocks(PG_FUNCTION_ARGS) aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_SELECT); if (aclresult != ACLCHECK_OK) - aclresult = is_member_of_role(GetUserId(), DEFAULT_ROLE_STAT_SCAN_TABLES) ? ACLCHECK_OK : ACLCHECK_NO_PRIV; + aclresult = is_member_of_role(GetUserId(), ROLE_PG_STAT_SCAN_TABLES) ? ACLCHECK_OK : ACLCHECK_NO_PRIV; if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c index 868a635ef9bc..cf71af7a0ce4 100644 --- a/contrib/pgstattuple/pgstatapprox.c +++ b/contrib/pgstattuple/pgstatapprox.c @@ -3,7 +3,7 @@ * pgstatapprox.c * Bloat estimation functions * - * Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Copyright (c) 2014-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pgstattuple/pgstatapprox.c @@ -195,6 +195,9 @@ statapprox_heap(Relation rel, output_type *stat) stat->tuple_count = vac_estimate_reltuples(rel, nblocks, scanned, stat->tuple_count); + /* It's not clear if we could get -1 here, but be safe. */ + stat->tuple_count = Max(stat->tuple_count, 0); + /* * Calculate percentages if the relation has one or more pages. */ diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c index b1ce0d77d737..5368bb30f0c5 100644 --- a/contrib/pgstattuple/pgstatindex.c +++ b/contrib/pgstattuple/pgstatindex.c @@ -283,8 +283,12 @@ pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo) page = BufferGetPage(buffer); opaque = (BTPageOpaque) PageGetSpecialPointer(page); - /* Determine page type, and update totals */ - + /* + * Determine page type, and update totals. + * + * Note that we arbitrarily bucket deleted pages together without + * considering if they're leaf pages or internal pages. + */ if (P_ISDELETED(opaque)) indexStat.deleted_pages++; else if (P_IGNORE(opaque)) diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c index f1458a32a756..9226e459a84a 100644 --- a/contrib/pgstattuple/pgstattuple.c +++ b/contrib/pgstattuple/pgstattuple.c @@ -433,7 +433,7 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, opaque = (BTPageOpaque) PageGetSpecialPointer(page); if (P_IGNORE(opaque)) { - /* recyclable page */ + /* deleted or half-dead page */ stat->free_space += BLCKSZ; } else if (P_ISLEAF(opaque)) @@ -443,7 +443,7 @@ pgstat_btree_page(pgstattuple_type *stat, Relation rel, BlockNumber blkno, } else { - /* root or node */ + /* internal page */ } } diff --git a/contrib/postgres_fdw/Makefile b/contrib/postgres_fdw/Makefile index 57873631c7ee..d3495e0db90c 100644 --- a/contrib/postgres_fdw/Makefile +++ b/contrib/postgres_fdw/Makefile @@ -14,7 +14,7 @@ PG_CPPFLAGS = -I$(libpq_srcdir) SHLIB_LINK_INTERNAL = $(libpq) EXTENSION = postgres_fdw -DATA = postgres_fdw--1.0.sql +DATA = postgres_fdw--1.0.sql postgres_fdw--1.0--1.1.sql REGRESS = postgres_fdw gp_postgres_fdw diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index ce6e07fb565f..33ac0fd1c974 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -3,7 +3,7 @@ * connection.c * Connection management functions for postgres_fdw * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/connection.c @@ -16,12 +16,14 @@ #include "access/xact.h" #include "catalog/pg_user_mapping.h" #include "commands/defrem.h" +#include "funcapi.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "pgstat.h" #include "postgres_fdw.h" #include "storage/fd.h" #include "storage/latch.h" +#include "utils/builtins.h" #include "utils/datetime.h" #include "utils/hsearch.h" #include "utils/inval.h" @@ -57,8 +59,12 @@ typedef struct ConnCacheEntry bool have_error; /* have any subxacts aborted in this xact? */ bool changing_xact_state; /* xact state change in process */ bool invalidated; /* true if reconnect is pending */ + bool keep_connections; /* setting value of keep_connections + * server option */ + Oid serverid; /* foreign server OID used to get server name */ uint32 server_hashvalue; /* hash value of foreign server OID */ uint32 mapping_hashvalue; /* hash value of user mapping OID */ + PgFdwConnState state; /* extra per-connection state */ } ConnCacheEntry; /* @@ -73,12 +79,19 @@ static unsigned int prep_stmt_number = 0; /* tracks whether any work is needed in callback functions */ static bool xact_got_connection = false; +/* + * SQL functions + */ +PG_FUNCTION_INFO_V1(postgres_fdw_get_connections); +PG_FUNCTION_INFO_V1(postgres_fdw_disconnect); +PG_FUNCTION_INFO_V1(postgres_fdw_disconnect_all); + /* prototypes of private functions */ +static void make_new_connection(ConnCacheEntry *entry, UserMapping *user); static PGconn *connect_pg_server(ForeignServer *server, UserMapping *user); static void disconnect_pg_server(ConnCacheEntry *entry); static void check_conn_params(const char **keywords, const char **values, UserMapping *user); static void configure_remote_session(PGconn *conn); -static void do_sql_command(PGconn *conn, const char *sql); static void begin_remote_xact(ConnCacheEntry *entry); static void pgfdw_xact_callback(XactEvent event, void *arg); static void pgfdw_subxact_callback(SubXactEvent event, @@ -93,6 +106,7 @@ static bool pgfdw_exec_cleanup_query(PGconn *conn, const char *query, static bool pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result); static bool UserMappingPasswordRequired(UserMapping *user); +static bool disconnect_cached_connections(Oid serverid); /* * Get a PGconn which can be used to execute queries on the remote PostgreSQL @@ -103,27 +117,29 @@ static bool UserMappingPasswordRequired(UserMapping *user); * will_prep_stmt must be true if caller intends to create any prepared * statements. Since those don't go away automatically at transaction end * (not even on error), we need this flag to cue manual cleanup. + * + * If state is not NULL, *state receives the per-connection state associated + * with the PGconn. */ PGconn * -GetConnection(UserMapping *user, bool will_prep_stmt) +GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state) { bool found; + bool retry = false; ConnCacheEntry *entry; ConnCacheKey key; + MemoryContext ccxt = CurrentMemoryContext; /* First time through, initialize connection cache hashtable */ if (ConnectionHash == NULL) { HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(ConnCacheKey); ctl.entrysize = sizeof(ConnCacheEntry); - /* allocate ConnectionHash in the cache context */ - ctl.hcxt = CacheMemoryContext; ConnectionHash = hash_create("postgres_fdw connections", 8, &ctl, - HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + HASH_ELEM | HASH_BLOBS); /* * Register some callback functions that manage connection cleanup. @@ -170,52 +186,153 @@ GetConnection(UserMapping *user, bool will_prep_stmt) disconnect_pg_server(entry); } - /* - * We don't check the health of cached connection here, because it would - * require some overhead. Broken connection will be detected when the - * connection is actually used. - */ - /* * If cache entry doesn't have a connection, we have to establish a new * connection. (If connect_pg_server throws an error, the cache entry * will remain in a valid empty state, ie conn == NULL.) */ if (entry->conn == NULL) + make_new_connection(entry, user); + + /* + * We check the health of the cached connection here when starting a new + * remote transaction. If a broken connection is detected, we try to + * reestablish a new connection later. + */ + PG_TRY(); { - ForeignServer *server = GetForeignServer(user->serverid); + /* Process a pending asynchronous request if any. */ + if (entry->state.pendingAreq) + process_pending_request(entry->state.pendingAreq); + /* Start a new transaction or subtransaction if needed. */ + begin_remote_xact(entry); + } + PG_CATCH(); + { + MemoryContext ecxt = MemoryContextSwitchTo(ccxt); + ErrorData *errdata = CopyErrorData(); - /* Reset all transient state fields, to be sure all are clean */ - entry->xact_depth = 0; - entry->have_prep_stmt = false; - entry->have_error = false; - entry->changing_xact_state = false; - entry->invalidated = false; - entry->server_hashvalue = - GetSysCacheHashValue1(FOREIGNSERVEROID, - ObjectIdGetDatum(server->serverid)); - entry->mapping_hashvalue = - GetSysCacheHashValue1(USERMAPPINGOID, - ObjectIdGetDatum(user->umid)); - - /* Now try to make the connection */ - entry->conn = connect_pg_server(server, user); - - elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\" (user mapping oid %u, userid %u)", - entry->conn, server->servername, user->umid, user->userid); + /* + * If connection failure is reported when starting a new remote + * transaction (not subtransaction), new connection will be + * reestablished later. + * + * After a broken connection is detected in libpq, any error other + * than connection failure (e.g., out-of-memory) can be thrown + * somewhere between return from libpq and the expected ereport() call + * in pgfdw_report_error(). In this case, since PQstatus() indicates + * CONNECTION_BAD, checking only PQstatus() causes the false detection + * of connection failure. To avoid this, we also verify that the + * error's sqlstate is ERRCODE_CONNECTION_FAILURE. Note that also + * checking only the sqlstate can cause another false detection + * because pgfdw_report_error() may report ERRCODE_CONNECTION_FAILURE + * for any libpq-originated error condition. + */ + if (errdata->sqlerrcode != ERRCODE_CONNECTION_FAILURE || + PQstatus(entry->conn) != CONNECTION_BAD || + entry->xact_depth > 0) + { + MemoryContextSwitchTo(ecxt); + PG_RE_THROW(); + } + + /* Clean up the error state */ + FlushErrorState(); + FreeErrorData(errdata); + errdata = NULL; + + retry = true; } + PG_END_TRY(); /* - * Start a new transaction or subtransaction if needed. + * If a broken connection is detected, disconnect it, reestablish a new + * connection and retry a new remote transaction. If connection failure is + * reported again, we give up getting a connection. */ - begin_remote_xact(entry); + if (retry) + { + Assert(entry->xact_depth == 0); + + ereport(DEBUG3, + (errmsg_internal("could not start remote transaction on connection %p", + entry->conn)), + errdetail_internal("%s", pchomp(PQerrorMessage(entry->conn)))); + + elog(DEBUG3, "closing connection %p to reestablish a new one", + entry->conn); + disconnect_pg_server(entry); + + if (entry->conn == NULL) + make_new_connection(entry, user); + + begin_remote_xact(entry); + } /* Remember if caller will prepare statements */ entry->have_prep_stmt |= will_prep_stmt; + /* If caller needs access to the per-connection state, return it. */ + if (state) + *state = &entry->state; + return entry->conn; } +/* + * Reset all transient state fields in the cached connection entry and + * establish new connection to the remote server. + */ +static void +make_new_connection(ConnCacheEntry *entry, UserMapping *user) +{ + ForeignServer *server = GetForeignServer(user->serverid); + ListCell *lc; + + Assert(entry->conn == NULL); + + /* Reset all transient state fields, to be sure all are clean */ + entry->xact_depth = 0; + entry->have_prep_stmt = false; + entry->have_error = false; + entry->changing_xact_state = false; + entry->invalidated = false; + entry->serverid = server->serverid; + entry->server_hashvalue = + GetSysCacheHashValue1(FOREIGNSERVEROID, + ObjectIdGetDatum(server->serverid)); + entry->mapping_hashvalue = + GetSysCacheHashValue1(USERMAPPINGOID, + ObjectIdGetDatum(user->umid)); + memset(&entry->state, 0, sizeof(entry->state)); + + /* + * Determine whether to keep the connection that we're about to make here + * open even after the transaction using it ends, so that the subsequent + * transactions can re-use it. + * + * It's enough to determine this only when making new connection because + * all the connections to the foreign server whose keep_connections option + * is changed will be closed and re-made later. + * + * By default, all the connections to any foreign servers are kept open. + */ + entry->keep_connections = true; + foreach(lc, server->options) + { + DefElem *def = (DefElem *) lfirst(lc); + + if (strcmp(def->defname, "keep_connections") == 0) + entry->keep_connections = defGetBoolean(def); + } + + /* Now try to make the connection */ + entry->conn = connect_pg_server(server, user); + + elog(DEBUG3, "new postgres_fdw connection %p for server \"%s\" (user mapping oid %u, userid %u)", + entry->conn, server->servername, user->umid, user->userid); +} + /* * Connect to remote server using specified server and user mapping properties. */ @@ -450,7 +567,7 @@ configure_remote_session(PGconn *conn) /* * Convenience subroutine to issue a non-data-returning SQL command to remote */ -static void +void do_sql_command(PGconn *conn, const char *sql) { PGresult *res; @@ -565,8 +682,12 @@ GetPrepStmtNumber(PGconn *conn) * Caller is responsible for the error handling on the result. */ PGresult * -pgfdw_exec_query(PGconn *conn, const char *query) +pgfdw_exec_query(PGconn *conn, const char *query, PgFdwConnState *state) { + /* First, process a pending asynchronous request, if any. */ + if (state && state->pendingAreq) + process_pending_request(state->pendingAreq); + /* * Submit a query. Since we don't use non-blocking mode, this also can * block. But its risk is relatively small, so we ignore that for now. @@ -852,6 +973,8 @@ pgfdw_xact_callback(XactEvent event, void *arg) { entry->have_prep_stmt = false; entry->have_error = false; + /* Also reset per-connection state */ + memset(&entry->state, 0, sizeof(entry->state)); } /* Disarm changing_xact_state if it all worked. */ @@ -864,12 +987,16 @@ pgfdw_xact_callback(XactEvent event, void *arg) entry->xact_depth = 0; /* - * If the connection isn't in a good idle state, discard it to - * recover. Next GetConnection will open a new connection. + * If the connection isn't in a good idle state, it is marked as + * invalid or keep_connections option of its server is disabled, then + * discard it to recover. Next GetConnection will open a new + * connection. */ if (PQstatus(entry->conn) != CONNECTION_OK || PQtransactionStatus(entry->conn) != PQTRANS_IDLE || - entry->changing_xact_state) + entry->changing_xact_state || + entry->invalidated || + !entry->keep_connections) { elog(DEBUG3, "discarding connection %p", entry->conn); disconnect_pg_server(entry); @@ -993,9 +1120,12 @@ pgfdw_subxact_callback(SubXactEvent event, SubTransactionId mySubid, * Connection invalidation callback function * * After a change to a pg_foreign_server or pg_user_mapping catalog entry, - * mark connections depending on that entry as needing to be remade. - * We can't immediately destroy them, since they might be in the midst of - * a transaction, but we'll remake them at the next opportunity. + * close connections depending on that entry immediately if current transaction + * has not used those connections yet. Otherwise, mark those connections as + * invalid and then make pgfdw_xact_callback() close them at the end of current + * transaction, since they cannot be closed in the midst of the transaction + * using them. Closed connections will be remade at the next opportunity if + * necessary. * * Although most cache invalidation callbacks blow away all the related stuff * regardless of the given hashvalue, connections are expensive enough that @@ -1026,7 +1156,21 @@ pgfdw_inval_callback(Datum arg, int cacheid, uint32 hashvalue) entry->server_hashvalue == hashvalue) || (cacheid == USERMAPPINGOID && entry->mapping_hashvalue == hashvalue)) - entry->invalidated = true; + { + /* + * Close the connection immediately if it's not used yet in this + * transaction. Otherwise mark it as invalid so that + * pgfdw_xact_callback() can close it at the end of this + * transaction. + */ + if (entry->xact_depth == 0) + { + elog(DEBUG3, "discarding connection %p", entry->conn); + disconnect_pg_server(entry); + } + else + entry->invalidated = true; + } } } @@ -1043,8 +1187,6 @@ pgfdw_inval_callback(Datum arg, int cacheid, uint32 hashvalue) static void pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry) { - HeapTuple tup; - Form_pg_user_mapping umform; ForeignServer *server; /* nothing to do for inactive entries and entries of sane state */ @@ -1055,13 +1197,7 @@ pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry) disconnect_pg_server(entry); /* find server name to be shown in the message below */ - tup = SearchSysCache1(USERMAPPINGOID, - ObjectIdGetDatum(entry->key)); - if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for user mapping %u", entry->key); - umform = (Form_pg_user_mapping) GETSTRUCT(tup); - server = GetForeignServer(umform->umserver); - ReleaseSysCache(tup); + server = GetForeignServer(entry->serverid); ereport(ERROR, (errcode(ERRCODE_CONNECTION_EXCEPTION), @@ -1073,6 +1209,10 @@ pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry) * Cancel the currently-in-progress query (whose query text we do not have) * and ignore the result. Returns true if we successfully cancel the query * and discard any pending result, and false if not. + * + * XXX: if the query was one sent by fetch_more_data_begin(), we could get the + * query text from the pendingAreq saved in the per-connection state, then + * report the query using it. */ static bool pgfdw_cancel_query(PGconn *conn) @@ -1192,20 +1332,15 @@ pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result) { int wc; TimestampTz now = GetCurrentTimestamp(); - long secs; - int microsecs; long cur_timeout; /* If timeout has expired, give up, else get sleep time. */ - if (now >= endtime) + cur_timeout = TimestampDifferenceMilliseconds(now, endtime); + if (cur_timeout <= 0) { timed_out = true; goto exit; } - TimestampDifference(now, endtime, &secs, µsecs); - - /* To protect against clock skew, limit sleep to one minute. */ - cur_timeout = Min(60000, secs * USECS_PER_SEC + microsecs); /* Sleep until there's something to do */ wc = WaitLatchOrSocket(MyLatch, @@ -1251,3 +1386,257 @@ exit: ; *result = last_res; return timed_out; } + +/* + * List active foreign server connections. + * + * This function takes no input parameter and returns setof record made of + * following values: + * - server_name - server name of active connection. In case the foreign server + * is dropped but still the connection is active, then the server name will + * be NULL in output. + * - valid - true/false representing whether the connection is valid or not. + * Note that the connections can get invalidated in pgfdw_inval_callback. + * + * No records are returned when there are no cached connections at all. + */ +Datum +postgres_fdw_get_connections(PG_FUNCTION_ARGS) +{ +#define POSTGRES_FDW_GET_CONNECTIONS_COLS 2 + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + TupleDesc tupdesc; + Tuplestorestate *tupstore; + MemoryContext per_query_ctx; + MemoryContext oldcontext; + HASH_SEQ_STATUS scan; + ConnCacheEntry *entry; + + /* check to see if caller supports us returning a tuplestore */ + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("materialize mode required, but it is not allowed in this context"))); + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + /* Build tuplestore to hold the result rows */ + per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; + oldcontext = MemoryContextSwitchTo(per_query_ctx); + + tupstore = tuplestore_begin_heap(true, false, work_mem); + rsinfo->returnMode = SFRM_Materialize; + rsinfo->setResult = tupstore; + rsinfo->setDesc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + + /* If cache doesn't exist, we return no records */ + if (!ConnectionHash) + { + /* clean up and return the tuplestore */ + tuplestore_donestoring(tupstore); + + PG_RETURN_VOID(); + } + + hash_seq_init(&scan, ConnectionHash); + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) + { + ForeignServer *server; + Datum values[POSTGRES_FDW_GET_CONNECTIONS_COLS]; + bool nulls[POSTGRES_FDW_GET_CONNECTIONS_COLS]; + + /* We only look for open remote connections */ + if (!entry->conn) + continue; + + server = GetForeignServerExtended(entry->serverid, FSV_MISSING_OK); + + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); + + /* + * The foreign server may have been dropped in current explicit + * transaction. It is not possible to drop the server from another + * session when the connection associated with it is in use in the + * current transaction, if tried so, the drop query in another session + * blocks until the current transaction finishes. + * + * Even though the server is dropped in the current transaction, the + * cache can still have associated active connection entry, say we + * call such connections dangling. Since we can not fetch the server + * name from system catalogs for dangling connections, instead we show + * NULL value for server name in output. + * + * We could have done better by storing the server name in the cache + * entry instead of server oid so that it could be used in the output. + * But the server name in each cache entry requires 64 bytes of + * memory, which is huge, when there are many cached connections and + * the use case i.e. dropping the foreign server within the explicit + * current transaction seems rare. So, we chose to show NULL value for + * server name in output. + * + * Such dangling connections get closed either in next use or at the + * end of current explicit transaction in pgfdw_xact_callback. + */ + if (!server) + { + /* + * If the server has been dropped in the current explicit + * transaction, then this entry would have been invalidated in + * pgfdw_inval_callback at the end of drop server command. Note + * that this connection would not have been closed in + * pgfdw_inval_callback because it is still being used in the + * current explicit transaction. So, assert that here. + */ + Assert(entry->conn && entry->xact_depth > 0 && entry->invalidated); + + /* Show null, if no server name was found */ + nulls[0] = true; + } + else + values[0] = CStringGetTextDatum(server->servername); + + values[1] = BoolGetDatum(!entry->invalidated); + + tuplestore_putvalues(tupstore, tupdesc, values, nulls); + } + + /* clean up and return the tuplestore */ + tuplestore_donestoring(tupstore); + + PG_RETURN_VOID(); +} + +/* + * Disconnect the specified cached connections. + * + * This function discards the open connections that are established by + * postgres_fdw from the local session to the foreign server with + * the given name. Note that there can be multiple connections to + * the given server using different user mappings. If the connections + * are used in the current local transaction, they are not disconnected + * and warning messages are reported. This function returns true + * if it disconnects at least one connection, otherwise false. If no + * foreign server with the given name is found, an error is reported. + */ +Datum +postgres_fdw_disconnect(PG_FUNCTION_ARGS) +{ + ForeignServer *server; + char *servername; + + servername = text_to_cstring(PG_GETARG_TEXT_PP(0)); + server = GetForeignServerByName(servername, false); + + PG_RETURN_BOOL(disconnect_cached_connections(server->serverid)); +} + +/* + * Disconnect all the cached connections. + * + * This function discards all the open connections that are established by + * postgres_fdw from the local session to the foreign servers. + * If the connections are used in the current local transaction, they are + * not disconnected and warning messages are reported. This function + * returns true if it disconnects at least one connection, otherwise false. + */ +Datum +postgres_fdw_disconnect_all(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(disconnect_cached_connections(InvalidOid)); +} + +/* + * Workhorse to disconnect cached connections. + * + * This function scans all the connection cache entries and disconnects + * the open connections whose foreign server OID matches with + * the specified one. If InvalidOid is specified, it disconnects all + * the cached connections. + * + * This function emits a warning for each connection that's used in + * the current transaction and doesn't close it. It returns true if + * it disconnects at least one connection, otherwise false. + * + * Note that this function disconnects even the connections that are + * established by other users in the same local session using different + * user mappings. This leads even non-superuser to be able to close + * the connections established by superusers in the same local session. + * + * XXX As of now we don't see any security risk doing this. But we should + * set some restrictions on that, for example, prevent non-superuser + * from closing the connections established by superusers even + * in the same session? + */ +static bool +disconnect_cached_connections(Oid serverid) +{ + HASH_SEQ_STATUS scan; + ConnCacheEntry *entry; + bool all = !OidIsValid(serverid); + bool result = false; + + /* + * Connection cache hashtable has not been initialized yet in this + * session, so return false. + */ + if (!ConnectionHash) + return false; + + hash_seq_init(&scan, ConnectionHash); + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) + { + /* Ignore cache entry if no open connection right now. */ + if (!entry->conn) + continue; + + if (all || entry->serverid == serverid) + { + /* + * Emit a warning because the connection to close is used in the + * current transaction and cannot be disconnected right now. + */ + if (entry->xact_depth > 0) + { + ForeignServer *server; + + server = GetForeignServerExtended(entry->serverid, + FSV_MISSING_OK); + + if (!server) + { + /* + * If the foreign server was dropped while its connection + * was used in the current transaction, the connection + * must have been marked as invalid by + * pgfdw_inval_callback at the end of DROP SERVER command. + */ + Assert(entry->invalidated); + + ereport(WARNING, + (errmsg("cannot close dropped server connection because it is still in use"))); + } + else + ereport(WARNING, + (errmsg("cannot close connection for server \"%s\" because it is still in use", + server->servername))); + } + else + { + elog(DEBUG3, "discarding connection %p", entry->conn); + disconnect_pg_server(entry); + result = true; + } + } + } + + return result; +} diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index ad37a7422133..31919fda8c61 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -24,7 +24,7 @@ * with collations that match the remote table's columns, which we can * consider to be user error. * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/deparse.c @@ -56,6 +56,7 @@ #include "utils/rel.h" #include "utils/syscache.h" #include "utils/typcache.h" +#include "commands/tablecmds.h" /* * Global context for foreign_expr_walker's search of an expression tree. @@ -426,23 +427,28 @@ foreign_expr_walker(Node *node, return false; /* - * Recurse to remaining subexpressions. Since the container - * subscripts must yield (noncollatable) integers, they won't - * affect the inner_cxt state. + * Recurse into the remaining subexpressions. The container + * subscripts will not affect collation of the SubscriptingRef + * result, so do those first and reset inner_cxt afterwards. */ if (!foreign_expr_walker((Node *) sr->refupperindexpr, glob_cxt, &inner_cxt)) return false; + inner_cxt.collation = InvalidOid; + inner_cxt.state = FDW_COLLATE_NONE; if (!foreign_expr_walker((Node *) sr->reflowerindexpr, glob_cxt, &inner_cxt)) return false; + inner_cxt.collation = InvalidOid; + inner_cxt.state = FDW_COLLATE_NONE; if (!foreign_expr_walker((Node *) sr->refexpr, glob_cxt, &inner_cxt)) return false; /* - * Container subscripting should yield same collation as - * input, but for safety use same logic as for function nodes. + * Container subscripting typically yields same collation as + * refexpr's, but in case it doesn't, use same logic as for + * function nodes. */ collation = sr->refcollid; if (collation == InvalidOid) @@ -1270,7 +1276,7 @@ deparseLockingClause(deparse_expr_cxt *context) * that DECLARE CURSOR ... FOR UPDATE is supported, which it isn't * before 8.3. */ - if (relid == root->parse->resultRelation && + if (bms_is_member(relid, root->all_result_relids) && (root->parse->commandType == CMD_UPDATE || root->parse->commandType == CMD_DELETE)) { @@ -1700,13 +1706,16 @@ deparseRangeTblRef(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, * The statement text is appended to buf, and we also create an integer List * of the columns being retrieved by WITH CHECK OPTION or RETURNING (if any), * which is returned to *retrieved_attrs. + * + * This also stores end position of the VALUES clause, so that we can rebuild + * an INSERT for a batch of rows later. */ void deparseInsertSql(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, List *targetAttrs, bool doNothing, List *withCheckOptionList, List *returningList, - List **retrieved_attrs) + List **retrieved_attrs, int *values_end_len) { AttrNumber pindex; bool first; @@ -1749,6 +1758,7 @@ deparseInsertSql(StringInfo buf, RangeTblEntry *rte, } else appendStringInfoString(buf, " DEFAULT VALUES"); + *values_end_len = buf->len; if (doNothing) appendStringInfoString(buf, " ON CONFLICT DO NOTHING"); @@ -1758,6 +1768,55 @@ deparseInsertSql(StringInfo buf, RangeTblEntry *rte, withCheckOptionList, returningList, retrieved_attrs); } +/* + * rebuild remote INSERT statement + * + * Provided a number of rows in a batch, builds INSERT statement with the + * right number of parameters. + */ +void +rebuildInsertSql(StringInfo buf, char *orig_query, + int values_end_len, int num_cols, + int num_rows) +{ + int i, + j; + int pindex; + bool first; + + /* Make sure the values_end_len is sensible */ + Assert((values_end_len > 0) && (values_end_len <= strlen(orig_query))); + + /* Copy up to the end of the first record from the original query */ + appendBinaryStringInfo(buf, orig_query, values_end_len); + + /* + * Add records to VALUES clause (we already have parameters for the first + * row, so start at the right offset). + */ + pindex = num_cols + 1; + for (i = 0; i < num_rows; i++) + { + appendStringInfoString(buf, ", ("); + + first = true; + for (j = 0; j < num_cols; j++) + { + if (!first) + appendStringInfoString(buf, ", "); + first = false; + + appendStringInfo(buf, "$%d", pindex); + pindex++; + } + + appendStringInfoChar(buf, ')'); + } + + /* Copy stuff after VALUES clause from the original query */ + appendStringInfoString(buf, orig_query + values_end_len); +} + /* * deparse remote UPDATE statement * @@ -1810,6 +1869,7 @@ deparseUpdateSql(StringInfo buf, RangeTblEntry *rte, * 'foreignrel' is the RelOptInfo for the target relation or the join relation * containing all base relations in the query * 'targetlist' is the tlist of the underlying foreign-scan plan node + * (note that this only contains new-value expressions and junk attrs) * 'targetAttrs' is the target columns of the UPDATE * 'remote_conds' is the qual clauses that must be evaluated remotely * '*params_list' is an output list of exprs that will become remote Params @@ -1831,8 +1891,9 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, deparse_expr_cxt context; int nestlevel; bool first; - ListCell *lc; RangeTblEntry *rte = planner_rt_fetch(rtindex, root); + ListCell *lc, + *lc2; /* Set up context struct for recursion */ context.root = root; @@ -1851,14 +1912,13 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, nestlevel = set_transmission_modes(); first = true; - foreach(lc, targetAttrs) + forboth(lc, targetlist, lc2, targetAttrs) { - int attnum = lfirst_int(lc); - TargetEntry *tle = get_tle_by_resno(targetlist, attnum); + TargetEntry *tle = lfirst_node(TargetEntry, lc); + int attnum = lfirst_int(lc2); - if (!tle) - elog(ERROR, "attribute number %d not found in UPDATE targetlist", - attnum); + /* update's new-value expressions shouldn't be resjunk */ + Assert(!tle->resjunk); if (!first) appendStringInfoString(buf, ", "); @@ -2114,6 +2174,38 @@ deparseAnalyzeSql(StringInfo buf, Relation rel, List **retrieved_attrs) deparseRelation(buf, rel); } +/* + * Construct a simple "TRUNCATE rel" statement + */ +void +deparseTruncateSql(StringInfo buf, + List *rels, + DropBehavior behavior, + bool restart_seqs) +{ + ListCell *cell; + + appendStringInfoString(buf, "TRUNCATE "); + + foreach(cell, rels) + { + Relation rel = lfirst(cell); + + if (cell != list_head(rels)) + appendStringInfoString(buf, ", "); + + deparseRelation(buf, rel); + } + + appendStringInfo(buf, " %s IDENTITY", + restart_seqs ? "RESTART" : "CONTINUE"); + + if (behavior == DROP_RESTRICT) + appendStringInfoString(buf, " RESTRICT"); + else if (behavior == DROP_CASCADE) + appendStringInfoString(buf, " CASCADE"); +} + /* * Construct name to use for given column, and emit it into buf. * If it has a column_name FDW option, use that instead of attribute name. @@ -2706,7 +2798,6 @@ deparseOpExpr(OpExpr *node, deparse_expr_cxt *context) HeapTuple tuple; Form_pg_operator form; char oprkind; - ListCell *arg; /* Retrieve information about the operator from system catalog. */ tuple = SearchSysCache1(OPEROID, ObjectIdGetDatum(node->opno)); @@ -2716,18 +2807,16 @@ deparseOpExpr(OpExpr *node, deparse_expr_cxt *context) oprkind = form->oprkind; /* Sanity check. */ - Assert((oprkind == 'r' && list_length(node->args) == 1) || - (oprkind == 'l' && list_length(node->args) == 1) || + Assert((oprkind == 'l' && list_length(node->args) == 1) || (oprkind == 'b' && list_length(node->args) == 2)); /* Always parenthesize the expression. */ appendStringInfoChar(buf, '('); - /* Deparse left operand. */ - if (oprkind == 'r' || oprkind == 'b') + /* Deparse left operand, if any. */ + if (oprkind == 'b') { - arg = list_head(node->args); - deparseExpr(lfirst(arg), context); + deparseExpr(linitial(node->args), context); appendStringInfoChar(buf, ' '); } @@ -2735,12 +2824,8 @@ deparseOpExpr(OpExpr *node, deparse_expr_cxt *context) deparseOperatorName(buf, form); /* Deparse right operand. */ - if (oprkind == 'l' || oprkind == 'b') - { - arg = list_tail(node->args); - appendStringInfoChar(buf, ' '); - deparseExpr(lfirst(arg), context); - } + appendStringInfoChar(buf, ' '); + deparseExpr(llast(node->args), context); appendStringInfoChar(buf, ')'); diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index 84bc0ee38171..31b5de91adde 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -13,12 +13,17 @@ DO $d$ OPTIONS (dbname '$$||current_database()||$$', port '$$||current_setting('port')||$$' )$$; + EXECUTE $$CREATE SERVER loopback3 FOREIGN DATA WRAPPER postgres_fdw + OPTIONS (dbname '$$||current_database()||$$', + port '$$||current_setting('port')||$$' + )$$; END; $d$; CREATE USER MAPPING FOR public SERVER testserver1 OPTIONS (user 'value', password 'value'); CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; CREATE USER MAPPING FOR CURRENT_USER SERVER loopback2; +CREATE USER MAPPING FOR public SERVER loopback3; -- =================================================================== -- create objects used through FDW loopback server -- =================================================================== @@ -129,6 +134,11 @@ CREATE FOREIGN TABLE ft6 ( c2 int NOT NULL, c3 text ) SERVER loopback2 OPTIONS (schema_name 'S 1', table_name 'T 4'); +CREATE FOREIGN TABLE ft7 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback3 OPTIONS (schema_name 'S 1', table_name 'T 4'); -- =================================================================== -- tests for validator -- =================================================================== @@ -199,7 +209,8 @@ ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); public | ft4 | loopback | (schema_name 'S 1', table_name 'T 3') | public | ft5 | loopback | (schema_name 'S 1', table_name 'T 4') | public | ft6 | loopback2 | (schema_name 'S 1', table_name 'T 4') | -(5 rows) + public | ft7 | loopback3 | (schema_name 'S 1', table_name 'T 4') | +(6 rows) -- Test that alteration of server options causes reconnection -- Remote's errors might be non-English, so hide them to ensure stable results @@ -602,6 +613,24 @@ SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 RESET enable_hashjoin; RESET enable_nestloop; +-- Test executing assertion in estimate_path_cost_size() that makes sure that +-- retrieved_rows for foreign rel re-used to cost pre-sorted foreign paths is +-- a sensible value even when the rel has tuples=0 +CREATE TABLE loct_empty (c1 int NOT NULL, c2 text); +CREATE FOREIGN TABLE ft_empty (c1 int NOT NULL, c2 text) + SERVER loopback OPTIONS (table_name 'loct_empty'); +INSERT INTO loct_empty + SELECT id, 'AAA' || to_char(id, 'FM000') FROM generate_series(1, 100) id; +DELETE FROM loct_empty; +ANALYZE ft_empty; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1; + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft_empty + Output: c1, c2 + Remote SQL: SELECT c1, c2 FROM public.loct_empty ORDER BY c1 ASC NULLS LAST +(3 rows) + -- =================================================================== -- WHERE with remotely-executable conditions -- =================================================================== @@ -653,14 +682,6 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- Op Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = (- "C 1"))) (3 rows) -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r) - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((1::numeric = ("C 1" !))) -(3 rows) - EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- @@ -1581,6 +1602,7 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL 20 | 0 | AAA020 (10 rows) +SET enable_resultcache TO off; -- right outer join + left outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; @@ -1607,6 +1629,7 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT 20 | 0 | AAA020 (10 rows) +RESET enable_resultcache; -- left outer join + right outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; @@ -2118,22 +2141,25 @@ SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 -- join with lateral reference EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Limit Output: t1."C 1" -> Nested Loop Output: t1."C 1" -> Index Scan using t1_pkey on "S 1"."T 1" t1 Output: t1."C 1", t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 - -> HashAggregate - Output: t2.c1, t3.c1 - Group Key: t2.c1, t3.c1 - -> Foreign Scan - Output: t2.c1, t3.c1 - Relations: (public.ft1 t2) INNER JOIN (public.ft2 t3) - Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r1.c2 = $1::integer)))) -(13 rows) + -> Result Cache + Cache Key: t1.c2 + -> Subquery Scan on q + -> HashAggregate + Output: t2.c1, t3.c1 + Group Key: t2.c1, t3.c1 + -> Foreign Scan + Output: t2.c1, t3.c1 + Relations: (public.ft1 t2) INNER JOIN (public.ft2 t3) + Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r1.c2 = $1::integer)))) +(16 rows) SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; C 1 @@ -3883,9 +3909,10 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + Batch Size: 1 -> Result Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::user_enum -(4 rows) +(5 rows) ALTER TABLE "S 1"."T 1" RENAME TO "T 0"; ALTER FOREIGN TABLE ft1 OPTIONS (SET table_name 'T 0'); @@ -3916,9 +3943,10 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 Remote SQL: INSERT INTO "S 1"."T 0"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + Batch Size: 1 -> Result Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::user_enum -(4 rows) +(5 rows) ALTER TABLE "S 1"."T 0" RENAME TO "T 1"; ALTER FOREIGN TABLE ft1 OPTIONS (SET table_name 'T 1'); @@ -4240,12 +4268,13 @@ INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20; -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + Batch Size: 1 -> Subquery Scan on "*SELECT*" Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum -> Foreign Scan on public.ft2 ft2_1 Output: (ft2_1.c1 + 1000), (ft2_1.c2 + 100), (ft2_1.c3 || ft2_1.c3) Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" LIMIT 20::bigint -(7 rows) +(8 rows) INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20; INSERT INTO ft2 (c1,c2,c3) @@ -5356,9 +5385,10 @@ INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo') RETURNING tableoid::regclass; Insert on public.ft2 Output: (ft2.tableoid)::regclass Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + Batch Size: 1 -> Result Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum -(5 rows) +(6 rows) INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo') RETURNING tableoid::regclass; tableoid @@ -5478,13 +5508,13 @@ UPDATE ft2 AS target SET (c2, c7) = ( FROM ft2 AS src WHERE target.c1 = src.c1 ) WHERE c1 > 1100; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- Update on public.ft2 target Remote SQL: UPDATE "S 1"."T 1" SET c2 = $2, c7 = $3 WHERE ctid = $1 -> Foreign Scan on public.ft2 target - Output: target.c1, $1, NULL::integer, target.c3, target.c4, target.c5, target.c6, $2, target.c8, (SubPlan 1 (returns $1,$2)), target.ctid - Remote SQL: SELECT "C 1", c3, c4, c5, c6, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" > 1100)) FOR UPDATE + Output: $1, $2, (SubPlan 1 (returns $1,$2)), target.ctid, target.* + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" > 1100)) FOR UPDATE SubPlan 1 (returns $1,$2) -> Foreign Scan on public.ft2 src Output: (src.c2 * 10), src.c7 @@ -5501,6 +5531,34 @@ UPDATE ft2 AS target SET (c2) = ( FROM ft2 AS src WHERE target.c1 = src.c1 ) WHERE c1 > 1100; +-- Test UPDATE involving a join that can be pushed down, +-- but a SET clause that can't be +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END + FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Update on public.ft2 d + Remote SQL: UPDATE "S 1"."T 1" SET c2 = $2 WHERE ctid = $1 + -> Foreign Scan + Output: CASE WHEN (random() >= '0'::double precision) THEN d.c2 ELSE 0 END, d.ctid, d.*, t.* + Relations: (public.ft2 d) INNER JOIN (public.ft2 t) + Remote SQL: SELECT r1.c2, r1.ctid, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r1."C 1" > 1000)))) FOR UPDATE OF r1 + -> Hash Join + Output: d.c2, d.ctid, d.*, t.* + Hash Cond: (d.c1 = t.c1) + -> Foreign Scan on public.ft2 d + Output: d.c2, d.ctid, d.*, d.c1 + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" > 1000)) ORDER BY "C 1" ASC NULLS LAST FOR UPDATE + -> Hash + Output: t.*, t.c1 + -> Foreign Scan on public.ft2 t + Output: t.*, t.c1 + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" +(17 rows) + +UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END + FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; -- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing -- user-defined operators/functions ALTER SERVER loopback OPTIONS (DROP extensions); @@ -5514,9 +5572,9 @@ UPDATE ft2 SET c3 = 'bar' WHERE postgres_fdw_abs(c1) > 2000 RETURNING *; Output: c1, c2, c3, c4, c5, c6, c7, c8 Remote SQL: UPDATE "S 1"."T 1" SET c3 = $2 WHERE ctid = $1 RETURNING "C 1", c2, c3, c4, c5, c6, c7, c8 -> Foreign Scan on public.ft2 - Output: c1, c2, NULL::integer, 'bar'::text, c4, c5, c6, c7, c8, ctid + Output: 'bar'::text, ctid, ft2.* Filter: (postgres_fdw_abs(ft2.c1) > 2000) - Remote SQL: SELECT "C 1", c2, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" FOR UPDATE + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" FOR UPDATE (7 rows) UPDATE ft2 SET c3 = 'bar' WHERE postgres_fdw_abs(c1) > 2000 RETURNING *; @@ -5545,11 +5603,11 @@ UPDATE ft2 SET c3 = 'baz' Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3 Remote SQL: UPDATE "S 1"."T 1" SET c3 = $2 WHERE ctid = $1 RETURNING "C 1", c2, c3, c4, c5, c6, c7, c8 -> Nested Loop - Output: ft2.c1, ft2.c2, NULL::integer, 'baz'::text, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.ctid, ft4.*, ft5.*, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3 + Output: 'baz'::text, ft2.ctid, ft2.*, ft4.*, ft5.*, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3 Join Filter: (ft2.c2 === ft4.c1) -> Foreign Scan on public.ft2 - Output: ft2.c1, ft2.c2, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.ctid - Remote SQL: SELECT "C 1", c2, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" > 2000)) FOR UPDATE + Output: ft2.ctid, ft2.*, ft2.c2 + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" > 2000)) FOR UPDATE -> Foreign Scan Output: ft4.*, ft4.c1, ft4.c2, ft4.c3, ft5.*, ft5.c1, ft5.c2, ft5.c3 Relations: (public.ft4) INNER JOIN (public.ft5) @@ -6208,9 +6266,10 @@ INSERT INTO rw_view VALUES (0, 5); -------------------------------------------------------------------------------- Insert on public.foreign_tbl Remote SQL: INSERT INTO public.base_tbl(a, b) VALUES ($1, $2) RETURNING a, b + Batch Size: 1 -> Result Output: 0, 5 -(4 rows) +(5 rows) INSERT INTO rw_view VALUES (0, 5); -- should fail ERROR: new row violates check option for view "rw_view" @@ -6221,9 +6280,10 @@ INSERT INTO rw_view VALUES (0, 15); -------------------------------------------------------------------------------- Insert on public.foreign_tbl Remote SQL: INSERT INTO public.base_tbl(a, b) VALUES ($1, $2) RETURNING a, b + Batch Size: 1 -> Result Output: 0, 15 -(4 rows) +(5 rows) INSERT INTO rw_view VALUES (0, 15); -- ok SELECT * FROM foreign_tbl; @@ -6239,7 +6299,7 @@ UPDATE rw_view SET b = b + 5; Update on public.foreign_tbl Remote SQL: UPDATE public.base_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b -> Foreign Scan on public.foreign_tbl - Output: foreign_tbl.a, (foreign_tbl.b + 5), foreign_tbl.ctid + Output: (foreign_tbl.b + 5), foreign_tbl.ctid, foreign_tbl.* Remote SQL: SELECT a, b, ctid FROM public.base_tbl WHERE ((a < b)) FOR UPDATE (5 rows) @@ -6253,7 +6313,7 @@ UPDATE rw_view SET b = b + 15; Update on public.foreign_tbl Remote SQL: UPDATE public.base_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b -> Foreign Scan on public.foreign_tbl - Output: foreign_tbl.a, (foreign_tbl.b + 15), foreign_tbl.ctid + Output: (foreign_tbl.b + 15), foreign_tbl.ctid, foreign_tbl.* Remote SQL: SELECT a, b, ctid FROM public.base_tbl WHERE ((a < b)) FOR UPDATE (5 rows) @@ -6321,13 +6381,13 @@ SELECT * FROM foreign_tbl; EXPLAIN (VERBOSE, COSTS OFF) UPDATE rw_view SET b = b + 5; - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Update on public.parent_tbl Foreign Update on public.foreign_tbl parent_tbl_1 Remote SQL: UPDATE public.child_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b -> Foreign Scan on public.foreign_tbl parent_tbl_1 - Output: parent_tbl_1.a, (parent_tbl_1.b + 5), parent_tbl_1.ctid + Output: (parent_tbl_1.b + 5), parent_tbl_1.tableoid, parent_tbl_1.ctid, parent_tbl_1.* Remote SQL: SELECT a, b, ctid FROM public.child_tbl WHERE ((a < b)) FOR UPDATE (6 rows) @@ -6336,13 +6396,13 @@ ERROR: new row violates check option for view "rw_view" DETAIL: Failing row contains (20, 20). EXPLAIN (VERBOSE, COSTS OFF) UPDATE rw_view SET b = b + 15; - QUERY PLAN ----------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Update on public.parent_tbl Foreign Update on public.foreign_tbl parent_tbl_1 Remote SQL: UPDATE public.child_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b -> Foreign Scan on public.foreign_tbl parent_tbl_1 - Output: parent_tbl_1.a, (parent_tbl_1.b + 15), parent_tbl_1.ctid + Output: (parent_tbl_1.b + 15), parent_tbl_1.tableoid, parent_tbl_1.ctid, parent_tbl_1.* Remote SQL: SELECT a, b, ctid FROM public.child_tbl WHERE ((a < b)) FOR UPDATE (6 rows) @@ -6659,7 +6719,7 @@ UPDATE rem1 set f1 = 10; -- all columns should be transmitted Update on public.rem1 Remote SQL: UPDATE public.loc1 SET f1 = $2, f2 = $3 WHERE ctid = $1 -> Foreign Scan on public.rem1 - Output: 10, f2, ctid, rem1.* + Output: 10, ctid, rem1.* Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE (5 rows) @@ -6892,7 +6952,7 @@ UPDATE rem1 set f2 = ''; -- can't be pushed down Update on public.rem1 Remote SQL: UPDATE public.loc1 SET f1 = $2, f2 = $3 WHERE ctid = $1 -> Foreign Scan on public.rem1 - Output: f1, ''::text, ctid, rem1.* + Output: ''::text, ctid, rem1.* Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE (5 rows) @@ -6916,7 +6976,7 @@ UPDATE rem1 set f2 = ''; -- can't be pushed down Update on public.rem1 Remote SQL: UPDATE public.loc1 SET f2 = $2 WHERE ctid = $1 RETURNING f1, f2 -> Foreign Scan on public.rem1 - Output: f1, ''::text, ctid, rem1.* + Output: ''::text, ctid, rem1.* Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE (5 rows) @@ -7223,39 +7283,111 @@ select * from bar where f1 in (select f1 from foo) for share; 4 | 44 (4 rows) --- Check UPDATE with inherited target and an inherited source table +-- Now check SELECT FOR UPDATE/SHARE with an inherited source table, +-- where the parent is itself a foreign table +create table loct4 (f1 int, f2 int, f3 int); +create foreign table foo2child (f3 int) inherits (foo2) + server loopback options (table_name 'loct4'); +NOTICE: moving and merging column "f3" with inherited definition +DETAIL: User-specified column moved to the position of the inherited column. explain (verbose, costs off) -update bar set f2 = f2 + 100 where f1 in (select f1 from foo); +select * from bar where f1 in (select f1 from foo2) for share; + QUERY PLAN +-------------------------------------------------------------------------------------- + LockRows + Output: bar.f1, bar.f2, bar.ctid, foo2.*, bar.*, bar.tableoid, foo2.tableoid + -> Hash Join + Output: bar.f1, bar.f2, bar.ctid, foo2.*, bar.*, bar.tableoid, foo2.tableoid + Inner Unique: true + Hash Cond: (bar.f1 = foo2.f1) + -> Append + -> Seq Scan on public.bar bar_1 + Output: bar_1.f1, bar_1.f2, bar_1.ctid, bar_1.*, bar_1.tableoid + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f1, bar_2.f2, bar_2.ctid, bar_2.*, bar_2.tableoid + Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR SHARE + -> Hash + Output: foo2.*, foo2.f1, foo2.tableoid + -> HashAggregate + Output: foo2.*, foo2.f1, foo2.tableoid + Group Key: foo2.f1 + -> Append + -> Foreign Scan on public.foo2 foo2_1 + Output: foo2_1.*, foo2_1.f1, foo2_1.tableoid + Remote SQL: SELECT f1, f2, f3 FROM public.loct1 + -> Foreign Scan on public.foo2child foo2_2 + Output: foo2_2.*, foo2_2.f1, foo2_2.tableoid + Remote SQL: SELECT f1, f2, f3 FROM public.loct4 +(24 rows) + +select * from bar where f1 in (select f1 from foo2) for share; + f1 | f2 +----+---- + 2 | 22 + 4 | 44 +(2 rows) + +drop foreign table foo2child; +-- And with a local child relation of the foreign table parent +create table foo2child (f3 int) inherits (foo2); +NOTICE: moving and merging column "f3" with inherited definition +DETAIL: User-specified column moved to the position of the inherited column. +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo2) for share; QUERY PLAN ------------------------------------------------------------------------------------------------- - Update on public.bar - Update on public.bar - Foreign Update on public.bar2 bar_1 - Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1 + LockRows + Output: bar.f1, bar.f2, bar.ctid, foo2.*, bar.*, bar.tableoid, foo2.ctid, foo2.tableoid -> Hash Join - Output: bar.f1, (bar.f2 + 100), bar.ctid, foo.ctid, foo.*, foo.tableoid + Output: bar.f1, bar.f2, bar.ctid, foo2.*, bar.*, bar.tableoid, foo2.ctid, foo2.tableoid Inner Unique: true - Hash Cond: (bar.f1 = foo.f1) - -> Seq Scan on public.bar - Output: bar.f1, bar.f2, bar.ctid + Hash Cond: (bar.f1 = foo2.f1) + -> Append + -> Seq Scan on public.bar bar_1 + Output: bar_1.f1, bar_1.f2, bar_1.ctid, bar_1.*, bar_1.tableoid + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f1, bar_2.f2, bar_2.ctid, bar_2.*, bar_2.tableoid + Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR SHARE -> Hash - Output: foo.ctid, foo.f1, foo.*, foo.tableoid + Output: foo2.*, foo2.f1, foo2.ctid, foo2.tableoid -> HashAggregate - Output: foo.ctid, foo.f1, foo.*, foo.tableoid - Group Key: foo.f1 + Output: foo2.*, foo2.f1, foo2.ctid, foo2.tableoid + Group Key: foo2.f1 -> Append - -> Seq Scan on public.foo foo_1 - Output: foo_1.ctid, foo_1.f1, foo_1.*, foo_1.tableoid - -> Foreign Scan on public.foo2 foo_2 - Output: foo_2.ctid, foo_2.f1, foo_2.*, foo_2.tableoid + -> Foreign Scan on public.foo2 foo2_1 + Output: foo2_1.*, foo2_1.f1, foo2_1.ctid, foo2_1.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 + -> Seq Scan on public.foo2child foo2_2 + Output: foo2_2.*, foo2_2.f1, foo2_2.ctid, foo2_2.tableoid +(23 rows) + +select * from bar where f1 in (select f1 from foo2) for share; + f1 | f2 +----+---- + 2 | 22 + 4 | 44 +(2 rows) + +drop table foo2child; +-- Check UPDATE with inherited target and an inherited source table +explain (verbose, costs off) +update bar set f2 = f2 + 100 where f1 in (select f1 from foo); + QUERY PLAN +------------------------------------------------------------------------------------------------------- + Update on public.bar + Update on public.bar bar_1 + Foreign Update on public.bar2 bar_2 + Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1 -> Hash Join - Output: bar_1.f1, (bar_1.f2 + 100), bar_1.f3, bar_1.ctid, foo.ctid, foo.*, foo.tableoid + Output: (bar.f2 + 100), foo.ctid, bar.tableoid, bar.ctid, (NULL::record), foo.*, foo.tableoid Inner Unique: true - Hash Cond: (bar_1.f1 = foo.f1) - -> Foreign Scan on public.bar2 bar_1 - Output: bar_1.f1, bar_1.f2, bar_1.f3, bar_1.ctid - Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE + Hash Cond: (bar.f1 = foo.f1) + -> Append + -> Seq Scan on public.bar bar_1 + Output: bar_1.f2, bar_1.f1, bar_1.tableoid, bar_1.ctid, NULL::record + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f2, bar_2.f1, bar_2.tableoid, bar_2.ctid, bar_2.* + Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE -> Hash Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> HashAggregate @@ -7267,7 +7399,7 @@ update bar set f2 = f2 + 100 where f1 in (select f1 from foo); -> Foreign Scan on public.foo2 foo_2 Output: foo_2.ctid, foo_2.f1, foo_2.*, foo_2.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 -(39 rows) +(25 rows) update bar set f2 = f2 + 100 where f1 in (select f1 from foo); select tableoid::regclass, * from bar order by 1,2; @@ -7287,39 +7419,24 @@ update bar set f2 = f2 + 100 from ( select f1 from foo union all select f1+3 from foo ) ss where bar.f1 = ss.f1; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Update on public.bar - Update on public.bar - Foreign Update on public.bar2 bar_1 + Update on public.bar bar_1 + Foreign Update on public.bar2 bar_2 Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1 - -> Hash Join - Output: bar.f1, (bar.f2 + 100), bar.ctid, (ROW(foo.f1)) - Hash Cond: (foo.f1 = bar.f1) - -> Append - -> Seq Scan on public.foo - Output: ROW(foo.f1), foo.f1 - -> Foreign Scan on public.foo2 foo_1 - Output: ROW(foo_1.f1), foo_1.f1 - Remote SQL: SELECT f1 FROM public.loct1 - -> Seq Scan on public.foo foo_2 - Output: ROW((foo_2.f1 + 3)), (foo_2.f1 + 3) - -> Foreign Scan on public.foo2 foo_3 - Output: ROW((foo_3.f1 + 3)), (foo_3.f1 + 3) - Remote SQL: SELECT f1 FROM public.loct1 - -> Hash - Output: bar.f1, bar.f2, bar.ctid - -> Seq Scan on public.bar - Output: bar.f1, bar.f2, bar.ctid -> Merge Join - Output: bar_1.f1, (bar_1.f2 + 100), bar_1.f3, bar_1.ctid, (ROW(foo.f1)) - Merge Cond: (bar_1.f1 = foo.f1) + Output: (bar.f2 + 100), (ROW(foo.f1)), bar.tableoid, bar.ctid, (NULL::record) + Merge Cond: (bar.f1 = foo.f1) -> Sort - Output: bar_1.f1, bar_1.f2, bar_1.f3, bar_1.ctid - Sort Key: bar_1.f1 - -> Foreign Scan on public.bar2 bar_1 - Output: bar_1.f1, bar_1.f2, bar_1.f3, bar_1.ctid - Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE + Output: bar.f2, bar.f1, bar.tableoid, bar.ctid, (NULL::record) + Sort Key: bar.f1 + -> Append + -> Seq Scan on public.bar bar_1 + Output: bar_1.f2, bar_1.f1, bar_1.tableoid, bar_1.ctid, NULL::record + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f2, bar_2.f1, bar_2.tableoid, bar_2.ctid, bar_2.* + Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE -> Sort Output: (ROW(foo.f1)), foo.f1 Sort Key: foo.f1 @@ -7334,7 +7451,7 @@ where bar.f1 = ss.f1; -> Foreign Scan on public.foo2 foo_3 Output: ROW((foo_3.f1 + 3)), (foo_3.f1 + 3) Remote SQL: SELECT f1 FROM public.loct1 -(45 rows) +(30 rows) update bar set f2 = f2 + 100 from @@ -7460,18 +7577,19 @@ ERROR: WHERE CURRENT OF is not supported for this table type rollback; explain (verbose, costs off) delete from foo where f1 < 5 returning *; - QUERY PLAN --------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------- Delete on public.foo - Output: foo.f1, foo.f2 - Delete on public.foo - Foreign Delete on public.foo2 foo_1 - -> Index Scan using i_foo_f1 on public.foo - Output: foo.ctid - Index Cond: (foo.f1 < 5) - -> Foreign Delete on public.foo2 foo_1 - Remote SQL: DELETE FROM public.loct1 WHERE ((f1 < 5)) RETURNING f1, f2 -(9 rows) + Output: foo_1.f1, foo_1.f2 + Delete on public.foo foo_1 + Foreign Delete on public.foo2 foo_2 + -> Append + -> Index Scan using i_foo_f1 on public.foo foo_1 + Output: foo_1.tableoid, foo_1.ctid + Index Cond: (foo_1.f1 < 5) + -> Foreign Delete on public.foo2 foo_2 + Remote SQL: DELETE FROM public.loct1 WHERE ((f1 < 5)) RETURNING f1, f2 +(10 rows) delete from foo where f1 < 5 returning *; f1 | f2 @@ -7485,17 +7603,20 @@ delete from foo where f1 < 5 returning *; explain (verbose, costs off) update bar set f2 = f2 + 100 returning *; - QUERY PLAN ------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------ Update on public.bar - Output: bar.f1, bar.f2 - Update on public.bar - Foreign Update on public.bar2 bar_1 - -> Seq Scan on public.bar - Output: bar.f1, (bar.f2 + 100), bar.ctid - -> Foreign Update on public.bar2 bar_1 - Remote SQL: UPDATE public.loct2 SET f2 = (f2 + 100) RETURNING f1, f2 -(8 rows) + Output: bar_1.f1, bar_1.f2 + Update on public.bar bar_1 + Foreign Update on public.bar2 bar_2 + -> Result + Output: (bar.f2 + 100), bar.tableoid, bar.ctid, (NULL::record) + -> Append + -> Seq Scan on public.bar bar_1 + Output: bar_1.f2, bar_1.tableoid, bar_1.ctid, NULL::record + -> Foreign Update on public.bar2 bar_2 + Remote SQL: UPDATE public.loct2 SET f2 = (f2 + 100) RETURNING f1, f2 +(11 rows) update bar set f2 = f2 + 100 returning *; f1 | f2 @@ -7520,15 +7641,18 @@ update bar set f2 = f2 + 100; QUERY PLAN -------------------------------------------------------------------------------------------------------- Update on public.bar - Update on public.bar - Foreign Update on public.bar2 bar_1 + Update on public.bar bar_1 + Foreign Update on public.bar2 bar_2 Remote SQL: UPDATE public.loct2 SET f1 = $2, f2 = $3, f3 = $4 WHERE ctid = $1 RETURNING f1, f2, f3 - -> Seq Scan on public.bar - Output: bar.f1, (bar.f2 + 100), bar.ctid - -> Foreign Scan on public.bar2 bar_1 - Output: bar_1.f1, (bar_1.f2 + 100), bar_1.f3, bar_1.ctid, bar_1.* - Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE -(9 rows) + -> Result + Output: (bar.f2 + 100), bar.tableoid, bar.ctid, (NULL::record) + -> Append + -> Seq Scan on public.bar bar_1 + Output: bar_1.f2, bar_1.tableoid, bar_1.ctid, NULL::record + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f2, bar_2.tableoid, bar_2.ctid, bar_2.* + Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE +(12 rows) update bar set f2 = f2 + 100; NOTICE: trig_row_before(23, skidoo) BEFORE ROW UPDATE ON bar2 @@ -7545,19 +7669,20 @@ NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON bar2 NOTICE: OLD: (7,277,77),NEW: (7,377,77) explain (verbose, costs off) delete from bar where f2 < 400; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------- Delete on public.bar - Delete on public.bar - Foreign Delete on public.bar2 bar_1 + Delete on public.bar bar_1 + Foreign Delete on public.bar2 bar_2 Remote SQL: DELETE FROM public.loct2 WHERE ctid = $1 RETURNING f1, f2, f3 - -> Seq Scan on public.bar - Output: bar.ctid - Filter: (bar.f2 < 400) - -> Foreign Scan on public.bar2 bar_1 - Output: bar_1.ctid, bar_1.* - Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 WHERE ((f2 < 400)) FOR UPDATE -(10 rows) + -> Append + -> Seq Scan on public.bar bar_1 + Output: bar_1.tableoid, bar_1.ctid, NULL::record + Filter: (bar_1.f2 < 400) + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.tableoid, bar_2.ctid, bar_2.* + Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 WHERE ((f2 < 400)) FOR UPDATE +(11 rows) delete from bar where f2 < 400; NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON bar2 @@ -7588,23 +7713,28 @@ analyze remt1; analyze remt2; explain (verbose, costs off) update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- Update on public.parent - Output: parent.a, parent.b, remt2.a, remt2.b - Update on public.parent - Foreign Update on public.remt1 parent_1 + Output: parent_1.a, parent_1.b, remt2.a, remt2.b + Update on public.parent parent_1 + Foreign Update on public.remt1 parent_2 + Remote SQL: UPDATE public.loct1 SET b = $2 WHERE ctid = $1 RETURNING a, b -> Nested Loop - Output: parent.a, (parent.b || remt2.b), parent.ctid, remt2.*, remt2.a, remt2.b + Output: (parent.b || remt2.b), remt2.*, remt2.a, remt2.b, parent.tableoid, parent.ctid, (NULL::record) Join Filter: (parent.a = remt2.a) - -> Seq Scan on public.parent - Output: parent.a, parent.b, parent.ctid - -> Foreign Scan on public.remt2 + -> Append + -> Seq Scan on public.parent parent_1 + Output: parent_1.b, parent_1.a, parent_1.tableoid, parent_1.ctid, NULL::record + -> Foreign Scan on public.remt1 parent_2 + Output: parent_2.b, parent_2.a, parent_2.tableoid, parent_2.ctid, parent_2.* + Remote SQL: SELECT a, b, ctid FROM public.loct1 FOR UPDATE + -> Materialize Output: remt2.b, remt2.*, remt2.a - Remote SQL: SELECT a, b FROM public.loct2 - -> Foreign Update - Remote SQL: UPDATE public.loct1 r4 SET b = (r4.b || r2.b) FROM public.loct2 r2 WHERE ((r4.a = r2.a)) RETURNING r4.a, r4.b, r2.a, r2.b -(14 rows) + -> Foreign Scan on public.remt2 + Output: remt2.b, remt2.*, remt2.a + Remote SQL: SELECT a, b FROM public.loct2 +(19 rows) update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; a | b | a | b @@ -7615,23 +7745,28 @@ update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a re explain (verbose, costs off) delete from parent using remt2 where parent.a = remt2.a returning parent; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------- Delete on public.parent - Output: parent.* - Delete on public.parent - Foreign Delete on public.remt1 parent_1 + Output: parent_1.* + Delete on public.parent parent_1 + Foreign Delete on public.remt1 parent_2 + Remote SQL: DELETE FROM public.loct1 WHERE ctid = $1 RETURNING a, b -> Nested Loop - Output: parent.ctid, remt2.* + Output: remt2.*, parent.tableoid, parent.ctid Join Filter: (parent.a = remt2.a) - -> Seq Scan on public.parent - Output: parent.ctid, parent.a - -> Foreign Scan on public.remt2 + -> Append + -> Seq Scan on public.parent parent_1 + Output: parent_1.a, parent_1.tableoid, parent_1.ctid + -> Foreign Scan on public.remt1 parent_2 + Output: parent_2.a, parent_2.tableoid, parent_2.ctid + Remote SQL: SELECT a, ctid FROM public.loct1 FOR UPDATE + -> Materialize Output: remt2.*, remt2.a - Remote SQL: SELECT a, b FROM public.loct2 - -> Foreign Delete - Remote SQL: DELETE FROM public.loct1 r4 USING public.loct2 r2 WHERE ((r4.a = r2.a)) RETURNING r4.a, r4.b -(14 rows) + -> Foreign Scan on public.remt2 + Output: remt2.*, remt2.a + Remote SQL: SELECT a, b FROM public.loct2 +(19 rows) delete from parent using remt2 where parent.a = remt2.a returning parent; parent @@ -7810,29 +7945,25 @@ DETAIL: Failing row contains (2, foo). CONTEXT: remote SQL command: UPDATE public.loct SET a = 2 WHERE ((b = 'foo'::text)) RETURNING a, b -- But the reverse is allowed update utrtest set a = 1 where b = 'qux' returning *; - a | b ----+----- - 1 | qux -(1 row) - +ERROR: cannot route tuples into foreign table to be updated "remp" select tableoid::regclass, * FROM utrtest; tableoid | a | b ----------+---+----- remp | 1 | foo - remp | 1 | qux + locp | 2 | qux (2 rows) select tableoid::regclass, * FROM remp; tableoid | a | b ----------+---+----- remp | 1 | foo - remp | 1 | qux -(2 rows) +(1 row) select tableoid::regclass, * FROM locp; - tableoid | a | b -----------+---+--- -(0 rows) + tableoid | a | b +----------+---+----- + locp | 2 | qux +(1 row) -- The executor should not let unexercised FDWs shut down update utrtest set a = 1 where b = 'foo'; @@ -7844,38 +7975,35 @@ insert into utrtest values (2, 'qux'); -- Check case where the foreign partition is a subplan target rel explain (verbose, costs off) update utrtest set a = 1 where a = 1 or a = 2 returning *; - QUERY PLAN ----------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------- Update on public.utrtest Output: utrtest_1.a, utrtest_1.b Foreign Update on public.remp utrtest_1 Update on public.locp utrtest_2 - -> Foreign Update on public.remp utrtest_1 - Remote SQL: UPDATE public.loct SET a = 1 WHERE (((a = 1) OR (a = 2))) RETURNING a, b - -> Seq Scan on public.locp utrtest_2 - Output: 1, utrtest_2.b, utrtest_2.ctid - Filter: ((utrtest_2.a = 1) OR (utrtest_2.a = 2)) -(9 rows) + -> Append + -> Foreign Update on public.remp utrtest_1 + Remote SQL: UPDATE public.loct SET a = 1 WHERE (((a = 1) OR (a = 2))) RETURNING a, b + -> Seq Scan on public.locp utrtest_2 + Output: 1, utrtest_2.tableoid, utrtest_2.ctid, NULL::record + Filter: ((utrtest_2.a = 1) OR (utrtest_2.a = 2)) +(10 rows) -- The new values are concatenated with ' triggered !' update utrtest set a = 1 where a = 1 or a = 2 returning *; - a | b ----+----------------- - 1 | qux triggered ! -(1 row) - +ERROR: cannot route tuples into foreign table to be updated "remp" delete from utrtest; insert into utrtest values (2, 'qux'); -- Check case where the foreign partition isn't a subplan target rel explain (verbose, costs off) update utrtest set a = 1 where a = 2 returning *; - QUERY PLAN ------------------------------------------------- + QUERY PLAN +------------------------------------------------------- Update on public.utrtest Output: utrtest_1.a, utrtest_1.b Update on public.locp utrtest_1 -> Seq Scan on public.locp utrtest_1 - Output: 1, utrtest_1.b, utrtest_1.ctid + Output: 1, utrtest_1.tableoid, utrtest_1.ctid Filter: (utrtest_1.a = 2) (6 rows) @@ -7896,66 +8024,51 @@ insert into utrtest values (2, 'qux'); -- with a direct modification plan explain (verbose, costs off) update utrtest set a = 1 returning *; - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------- Update on public.utrtest Output: utrtest_1.a, utrtest_1.b Foreign Update on public.remp utrtest_1 Update on public.locp utrtest_2 - -> Foreign Update on public.remp utrtest_1 - Remote SQL: UPDATE public.loct SET a = 1 RETURNING a, b - -> Seq Scan on public.locp utrtest_2 - Output: 1, utrtest_2.b, utrtest_2.ctid -(8 rows) + -> Append + -> Foreign Update on public.remp utrtest_1 + Remote SQL: UPDATE public.loct SET a = 1 RETURNING a, b + -> Seq Scan on public.locp utrtest_2 + Output: 1, utrtest_2.tableoid, utrtest_2.ctid, NULL::record +(9 rows) update utrtest set a = 1 returning *; - a | b ----+----- - 1 | foo - 1 | qux -(2 rows) - +ERROR: cannot route tuples into foreign table to be updated "remp" delete from utrtest; insert into utrtest values (1, 'foo'); insert into utrtest values (2, 'qux'); -- with a non-direct modification plan explain (verbose, costs off) update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; - QUERY PLAN ----------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------ Update on public.utrtest Output: utrtest_1.a, utrtest_1.b, "*VALUES*".column1 Foreign Update on public.remp utrtest_1 Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b Update on public.locp utrtest_2 -> Hash Join - Output: 1, utrtest_1.b, utrtest_1.ctid, "*VALUES*".*, "*VALUES*".column1 - Hash Cond: (utrtest_1.a = "*VALUES*".column1) - -> Foreign Scan on public.remp utrtest_1 - Output: utrtest_1.b, utrtest_1.ctid, utrtest_1.a - Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE - -> Hash - Output: "*VALUES*".*, "*VALUES*".column1 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".*, "*VALUES*".column1 - -> Hash Join - Output: 1, utrtest_2.b, utrtest_2.ctid, "*VALUES*".*, "*VALUES*".column1 - Hash Cond: (utrtest_2.a = "*VALUES*".column1) - -> Seq Scan on public.locp utrtest_2 - Output: utrtest_2.b, utrtest_2.ctid, utrtest_2.a + Output: 1, "*VALUES*".*, "*VALUES*".column1, utrtest.tableoid, utrtest.ctid, utrtest.* + Hash Cond: (utrtest.a = "*VALUES*".column1) + -> Append + -> Foreign Scan on public.remp utrtest_1 + Output: utrtest_1.a, utrtest_1.tableoid, utrtest_1.ctid, utrtest_1.* + Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE + -> Seq Scan on public.locp utrtest_2 + Output: utrtest_2.a, utrtest_2.tableoid, utrtest_2.ctid, NULL::record -> Hash Output: "*VALUES*".*, "*VALUES*".column1 -> Values Scan on "*VALUES*" Output: "*VALUES*".*, "*VALUES*".column1 -(24 rows) +(18 rows) update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; - a | b | x ----+-----+--- - 1 | foo | 1 - 1 | qux | 2 -(2 rows) - +ERROR: cannot route tuples into foreign table to be updated "remp" -- Change the definition of utrtest so that the foreign partition get updated -- after the local partition delete from utrtest; @@ -7971,50 +8084,45 @@ insert into utrtest values (3, 'xyzzy'); -- with a direct modification plan explain (verbose, costs off) update utrtest set a = 3 returning *; - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------- Update on public.utrtest Output: utrtest_1.a, utrtest_1.b Update on public.locp utrtest_1 Foreign Update on public.remp utrtest_2 - -> Seq Scan on public.locp utrtest_1 - Output: 3, utrtest_1.b, utrtest_1.ctid - -> Foreign Update on public.remp utrtest_2 - Remote SQL: UPDATE public.loct SET a = 3 RETURNING a, b -(8 rows) + -> Append + -> Seq Scan on public.locp utrtest_1 + Output: 3, utrtest_1.tableoid, utrtest_1.ctid, NULL::record + -> Foreign Update on public.remp utrtest_2 + Remote SQL: UPDATE public.loct SET a = 3 RETURNING a, b +(9 rows) update utrtest set a = 3 returning *; -- ERROR ERROR: cannot route tuples into foreign table to be updated "remp" -- with a non-direct modification plan explain (verbose, costs off) update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; - QUERY PLAN ----------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------- Update on public.utrtest Output: utrtest_1.a, utrtest_1.b, "*VALUES*".column1 Update on public.locp utrtest_1 Foreign Update on public.remp utrtest_2 Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b -> Hash Join - Output: 3, utrtest_1.b, utrtest_1.ctid, "*VALUES*".*, "*VALUES*".column1 - Hash Cond: (utrtest_1.a = "*VALUES*".column1) - -> Seq Scan on public.locp utrtest_1 - Output: utrtest_1.b, utrtest_1.ctid, utrtest_1.a - -> Hash - Output: "*VALUES*".*, "*VALUES*".column1 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".*, "*VALUES*".column1 - -> Hash Join - Output: 3, utrtest_2.b, utrtest_2.ctid, "*VALUES*".*, "*VALUES*".column1 - Hash Cond: (utrtest_2.a = "*VALUES*".column1) - -> Foreign Scan on public.remp utrtest_2 - Output: utrtest_2.b, utrtest_2.ctid, utrtest_2.a - Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE + Output: 3, "*VALUES*".*, "*VALUES*".column1, utrtest.tableoid, utrtest.ctid, (NULL::record) + Hash Cond: (utrtest.a = "*VALUES*".column1) + -> Append + -> Seq Scan on public.locp utrtest_1 + Output: utrtest_1.a, utrtest_1.tableoid, utrtest_1.ctid, NULL::record + -> Foreign Scan on public.remp utrtest_2 + Output: utrtest_2.a, utrtest_2.tableoid, utrtest_2.ctid, utrtest_2.* + Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE -> Hash Output: "*VALUES*".*, "*VALUES*".column1 -> Values Scan on "*VALUES*" Output: "*VALUES*".*, "*VALUES*".column1 -(24 rows) +(18 rows) update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR ERROR: cannot route tuples into foreign table to be updated "remp" @@ -8221,27 +8329,234 @@ select * from rem3; drop foreign table rem3; drop table loc3; -- =================================================================== --- test IMPORT FOREIGN SCHEMA +-- test for TRUNCATE -- =================================================================== -CREATE SCHEMA import_source; -CREATE TABLE import_source.t1 (c1 int, c2 varchar NOT NULL); -CREATE TABLE import_source.t2 (c1 int default 42, c2 varchar NULL, c3 text collate "POSIX"); -CREATE TYPE typ1 AS (m1 int, m2 varchar); -CREATE TABLE import_source.t3 (c1 timestamptz default now(), c2 typ1); -CREATE TABLE import_source."x 4" (c1 float8, "C 2" text, c3 varchar(42)); -CREATE TABLE import_source."x 5" (c1 float8); -ALTER TABLE import_source."x 5" DROP COLUMN c1; -CREATE TABLE import_source.t4 (c1 int) PARTITION BY RANGE (c1); -CREATE TABLE import_source.t4_part PARTITION OF import_source.t4 - FOR VALUES FROM (1) TO (100); -CREATE SCHEMA import_dest1; -IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; -\det+ import_dest1.* - List of foreign tables - Schema | Table | Server | FDW options | Description ---------------+-------+----------+-------------------------------------------------+------------- - import_dest1 | t1 | loopback | (schema_name 'import_source', table_name 't1') | - import_dest1 | t2 | loopback | (schema_name 'import_source', table_name 't2') | +CREATE TABLE tru_rtable0 (id int primary key); +CREATE FOREIGN TABLE tru_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable0'); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(1,10) x); +CREATE TABLE tru_ptable (id int) PARTITION BY HASH(id); +CREATE TABLE tru_ptable__p0 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE tru_rtable1 (id int primary key); +CREATE FOREIGN TABLE tru_ftable__p1 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback OPTIONS (table_name 'tru_rtable1'); +INSERT INTO tru_ptable (SELECT x FROM generate_series(11,20) x); +CREATE TABLE tru_pk_table(id int primary key); +CREATE TABLE tru_fk_table(fkey int references tru_pk_table(id)); +INSERT INTO tru_pk_table (SELECT x FROM generate_series(1,10) x); +INSERT INTO tru_fk_table (SELECT x % 10 + 1 FROM generate_series(5,25) x); +CREATE FOREIGN TABLE tru_pk_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_pk_table'); +CREATE TABLE tru_rtable_parent (id int); +CREATE TABLE tru_rtable_child (id int); +CREATE FOREIGN TABLE tru_ftable_parent (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable_parent'); +CREATE FOREIGN TABLE tru_ftable_child () INHERITS (tru_ftable_parent) + SERVER loopback OPTIONS (table_name 'tru_rtable_child'); +INSERT INTO tru_rtable_parent (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_rtable_child (SELECT x FROM generate_series(10, 18) x); +-- normal truncate +SELECT sum(id) FROM tru_ftable; -- 55 + sum +----- + 55 +(1 row) + +TRUNCATE tru_ftable; +SELECT count(*) FROM tru_rtable0; -- 0 + count +------- + 0 +(1 row) + +SELECT count(*) FROM tru_ftable; -- 0 + count +------- + 0 +(1 row) + +-- 'truncatable' option +ALTER SERVER loopback OPTIONS (ADD truncatable 'false'); +TRUNCATE tru_ftable; -- error +ERROR: foreign table "tru_ftable" does not allow truncates +ALTER FOREIGN TABLE tru_ftable OPTIONS (ADD truncatable 'true'); +TRUNCATE tru_ftable; -- accepted +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ERROR: foreign table "tru_ftable" does not allow truncates +ALTER SERVER loopback OPTIONS (DROP truncatable); +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ERROR: foreign table "tru_ftable" does not allow truncates +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'true'); +TRUNCATE tru_ftable; -- accepted +-- partitioned table with both local and foreign tables as partitions +SELECT sum(id) FROM tru_ptable; -- 155 + sum +----- + 155 +(1 row) + +TRUNCATE tru_ptable; +SELECT count(*) FROM tru_ptable; -- 0 + count +------- + 0 +(1 row) + +SELECT count(*) FROM tru_ptable__p0; -- 0 + count +------- + 0 +(1 row) + +SELECT count(*) FROM tru_ftable__p1; -- 0 + count +------- + 0 +(1 row) + +SELECT count(*) FROM tru_rtable1; -- 0 + count +------- + 0 +(1 row) + +-- 'CASCADE' option +SELECT sum(id) FROM tru_pk_ftable; -- 55 + sum +----- + 55 +(1 row) + +TRUNCATE tru_pk_ftable; -- failed by FK reference +ERROR: cannot truncate a table referenced in a foreign key constraint +DETAIL: Table "tru_fk_table" references "tru_pk_table". +HINT: Truncate table "tru_fk_table" at the same time, or use TRUNCATE ... CASCADE. +CONTEXT: remote SQL command: TRUNCATE public.tru_pk_table CONTINUE IDENTITY RESTRICT +TRUNCATE tru_pk_ftable CASCADE; +SELECT count(*) FROM tru_pk_ftable; -- 0 + count +------- + 0 +(1 row) + +SELECT count(*) FROM tru_fk_table; -- also truncated,0 + count +------- + 0 +(1 row) + +-- truncate two tables at a command +INSERT INTO tru_ftable (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_pk_ftable (SELECT x FROM generate_series(3,10) x); +SELECT count(*) from tru_ftable; -- 8 + count +------- + 8 +(1 row) + +SELECT count(*) from tru_pk_ftable; -- 8 + count +------- + 8 +(1 row) + +TRUNCATE tru_ftable, tru_pk_ftable CASCADE; +SELECT count(*) from tru_ftable; -- 0 + count +------- + 0 +(1 row) + +SELECT count(*) from tru_pk_ftable; -- 0 + count +------- + 0 +(1 row) + +-- truncate with ONLY clause +-- Since ONLY is specified, the table tru_ftable_child that inherits +-- tru_ftable_parent locally is not truncated. +TRUNCATE ONLY tru_ftable_parent; +SELECT sum(id) FROM tru_ftable_parent; -- 126 + sum +----- + 126 +(1 row) + +TRUNCATE tru_ftable_parent; +SELECT count(*) FROM tru_ftable_parent; -- 0 + count +------- + 0 +(1 row) + +-- in case when remote table has inherited children +CREATE TABLE tru_rtable0_child () INHERITS (tru_rtable0); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(5,9) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(10,14) x); +SELECT sum(id) FROM tru_ftable; -- 95 + sum +----- + 95 +(1 row) + +-- Both parent and child tables in the foreign server are truncated +-- even though ONLY is specified because ONLY has no effect +-- when truncating a foreign table. +TRUNCATE ONLY tru_ftable; +SELECT count(*) FROM tru_ftable; -- 0 + count +------- + 0 +(1 row) + +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(21,25) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(26,30) x); +SELECT sum(id) FROM tru_ftable; -- 255 + sum +----- + 255 +(1 row) + +TRUNCATE tru_ftable; -- truncate both of parent and child +SELECT count(*) FROM tru_ftable; -- 0 + count +------- + 0 +(1 row) + +-- cleanup +DROP FOREIGN TABLE tru_ftable_parent, tru_ftable_child, tru_pk_ftable,tru_ftable__p1,tru_ftable; +DROP TABLE tru_rtable0, tru_rtable1, tru_ptable, tru_ptable__p0, tru_pk_table, tru_fk_table, +tru_rtable_parent,tru_rtable_child, tru_rtable0_child; +-- =================================================================== +-- test IMPORT FOREIGN SCHEMA +-- =================================================================== +CREATE SCHEMA import_source; +CREATE TABLE import_source.t1 (c1 int, c2 varchar NOT NULL); +CREATE TABLE import_source.t2 (c1 int default 42, c2 varchar NULL, c3 text collate "POSIX"); +CREATE TYPE typ1 AS (m1 int, m2 varchar); +CREATE TABLE import_source.t3 (c1 timestamptz default now(), c2 typ1); +CREATE TABLE import_source."x 4" (c1 float8, "C 2" text, c3 varchar(42)); +CREATE TABLE import_source."x 5" (c1 float8); +ALTER TABLE import_source."x 5" DROP COLUMN c1; +CREATE TABLE import_source.t4 (c1 int) PARTITION BY RANGE (c1); +CREATE TABLE import_source.t4_part PARTITION OF import_source.t4 + FOR VALUES FROM (1) TO (100); +CREATE TABLE import_source.t4_part2 PARTITION OF import_source.t4 + FOR VALUES FROM (100) TO (200); +CREATE SCHEMA import_dest1; +IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; +\det+ import_dest1.* + List of foreign tables + Schema | Table | Server | FDW options | Description +--------------+-------+----------+-------------------------------------------------+------------- + import_dest1 | t1 | loopback | (schema_name 'import_source', table_name 't1') | + import_dest1 | t2 | loopback | (schema_name 'import_source', table_name 't2') | import_dest1 | t3 | loopback | (schema_name 'import_source', table_name 't3') | import_dest1 | t4 | loopback | (schema_name 'import_source', table_name 't4') | import_dest1 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') | @@ -8425,27 +8740,29 @@ FDW options: (schema_name 'import_source', table_name 'x 5') -- Check LIMIT TO and EXCEPT CREATE SCHEMA import_dest4; -IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch) +IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch, t4_part) FROM SERVER loopback INTO import_dest4; \det+ import_dest4.* - List of foreign tables - Schema | Table | Server | FDW options | Description ---------------+-------+----------+------------------------------------------------+------------- - import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | -(1 row) + List of foreign tables + Schema | Table | Server | FDW options | Description +--------------+---------+----------+-----------------------------------------------------+------------- + import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | + import_dest4 | t4_part | loopback | (schema_name 'import_source', table_name 't4_part') | +(2 rows) -IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch) +IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch, t4_part) FROM SERVER loopback INTO import_dest4; \det+ import_dest4.* - List of foreign tables - Schema | Table | Server | FDW options | Description ---------------+-------+----------+-------------------------------------------------+------------- - import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | - import_dest4 | t2 | loopback | (schema_name 'import_source', table_name 't2') | - import_dest4 | t3 | loopback | (schema_name 'import_source', table_name 't3') | - import_dest4 | t4 | loopback | (schema_name 'import_source', table_name 't4') | - import_dest4 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | -(5 rows) + List of foreign tables + Schema | Table | Server | FDW options | Description +--------------+---------+----------+-----------------------------------------------------+------------- + import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | + import_dest4 | t2 | loopback | (schema_name 'import_source', table_name 't2') | + import_dest4 | t3 | loopback | (schema_name 'import_source', table_name 't3') | + import_dest4 | t4 | loopback | (schema_name 'import_source', table_name 't4') | + import_dest4 | t4_part | loopback | (schema_name 'import_source', table_name 't4_part') | + import_dest4 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | +(6 rows) -- Assorted error cases IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest4; @@ -8755,8 +9072,8 @@ INSERT INTO pagg_tab_p2 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM gene INSERT INTO pagg_tab_p3 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 30 and (i % 30) >= 20; -- Create foreign partitions CREATE FOREIGN TABLE fpagg_tab_p1 PARTITION OF pagg_tab FOR VALUES FROM (0) TO (10) SERVER loopback OPTIONS (table_name 'pagg_tab_p1'); -CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2');; -CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3');; +CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2'); +CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3'); ANALYZE pagg_tab; ANALYZE fpagg_tab_p1; ANALYZE fpagg_tab_p2; @@ -8908,7 +9225,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c7 char(10) default 'ft1', c8 user_enum ) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; ERROR: password is required DETAIL: Non-superusers must provide a password in the user mapping. -- If we add a password to the connstr it'll fail, because we don't allow passwords @@ -8919,7 +9236,7 @@ DO $d$ END; $d$; ERROR: invalid option "password" -HINT: Valid options in this context are: service, passfile, channel_binding, connect_timeout, dbname, host, hostaddr, port, options, application_name, keepalives, keepalives_idle, keepalives_interval, keepalives_count, tcp_user_timeout, sslmode, sslcompression, sslcert, sslkey, sslrootcert, sslcrl, requirepeer, ssl_min_protocol_version, ssl_max_protocol_version, gssencmode, krbsrvname, gsslib, target_session_attrs, use_remote_estimate, fdw_startup_cost, fdw_tuple_cost, extensions, updatable, fetch_size +HINT: Valid options in this context are: service, passfile, channel_binding, connect_timeout, dbname, host, hostaddr, port, options, application_name, keepalives, keepalives_idle, keepalives_interval, keepalives_count, tcp_user_timeout, sslmode, sslcompression, sslcert, sslkey, sslrootcert, sslcrl, sslcrldir, sslsni, requirepeer, ssl_min_protocol_version, ssl_max_protocol_version, gssencmode, krbsrvname, gsslib, target_session_attrs, use_remote_estimate, fdw_startup_cost, fdw_tuple_cost, extensions, updatable, truncatable, fetch_size, batch_size, async_capable, keep_connections CONTEXT: SQL statement "ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw')" PL/pgSQL function inline_code_block line 3 at EXECUTE -- If we add a password for our user mapping instead, we should get a different @@ -8927,7 +9244,7 @@ PL/pgSQL function inline_code_block line 3 at EXECUTE -- -- This won't work with installcheck, but neither will most of the FDW checks. ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; ERROR: password is required DETAIL: Non-superuser cannot connect if the server does not request a password. HINT: Target server's authentication method must be changed or password_required=false set in the user mapping attributes. @@ -8935,7 +9252,7 @@ HINT: Target server's authentication method must be changed or password_require ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); ERROR: password_required=false is superuser-only HINT: User mappings with the password_required option set to false may only be created or modified by the superuser -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; ERROR: password is required DETAIL: Non-superuser cannot connect if the server does not request a password. HINT: Target server's authentication method must be changed or password_required=false set in the user mapping attributes. @@ -8944,10 +9261,10 @@ RESET ROLE; ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD password_required 'false'); SET ROLE regress_nosuper; -- Should finally work now -SELECT * FROM ft1_nopw LIMIT 1; - c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 -------+----+----+----+----+----+------------+---- - 1111 | 2 | | | | | ft1 | +SELECT 1 FROM ft1_nopw LIMIT 1; + ?column? +---------- + 1 (1 row) -- unpriv user also cannot set sslcert / sslkey on the user mapping @@ -8964,16 +9281,16 @@ HINT: User mappings with the sslcert or sslkey options set may only be created DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; -- This will fail again as it'll resolve the user mapping for public, which -- lacks password_required=false -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; ERROR: password is required DETAIL: Non-superusers must provide a password in the user mapping. RESET ROLE; -- The user mapping for public is passwordless and lacks the password_required=false -- mapping option, but will work because the current user is a superuser. -SELECT * FROM ft1_nopw LIMIT 1; - c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 -------+----+----+----+----+----+------------+---- - 1111 | 2 | | | | | ft1 | +SELECT 1 FROM ft1_nopw LIMIT 1; + ?column? +---------- + 1 (1 row) -- cleanup @@ -8995,3 +9312,1169 @@ PREPARE TRANSACTION 'fdw_tpc'; ERROR: cannot PREPARE a transaction that has operated on postgres_fdw foreign tables ROLLBACK; WARNING: there is no transaction in progress +-- =================================================================== +-- reestablish new connection +-- =================================================================== +-- Change application_name of remote connection to special one +-- so that we can easily terminate the connection later. +ALTER SERVER loopback OPTIONS (application_name 'fdw_retry_check'); +-- If debug_invalidate_system_caches_always is active, it results in +-- dropping remote connections after every transaction, making it +-- impossible to test termination meaningfully. So turn that off +-- for this test. +SET debug_invalidate_system_caches_always = 0; +-- Make sure we have a remote connection. +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +-- Terminate the remote connection and wait for the termination to complete. +SELECT pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; + pg_terminate_backend +---------------------- + t +(1 row) + +-- This query should detect the broken connection when starting new remote +-- transaction, reestablish new connection, and then succeed. +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +-- If we detect the broken connection when starting a new remote +-- subtransaction, we should fail instead of establishing a new connection. +-- Terminate the remote connection and wait for the termination to complete. +SELECT pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; + pg_terminate_backend +---------------------- + t +(1 row) + +SAVEPOINT s; +-- The text of the error might vary across platforms, so only show SQLSTATE. +\set VERBOSITY sqlstate +SELECT 1 FROM ft1 LIMIT 1; -- should fail +ERROR: 08006 +\set VERBOSITY default +COMMIT; +RESET debug_invalidate_system_caches_always; +-- ============================================================================= +-- test connection invalidation cases and postgres_fdw_get_connections function +-- ============================================================================= +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); + ?column? +---------- + 1 +(1 row) + +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- +(0 rows) + +-- This test case is for closing the connection in pgfdw_xact_callback +BEGIN; +-- Connection xact depth becomes 1 i.e. the connection is in midst of the xact. +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +SELECT 1 FROM ft7 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +-- List all the existing cached connections. loopback and loopback3 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- + loopback + loopback3 +(2 rows) + +-- Connections are not closed at the end of the alter and drop statements. +-- That's because the connections are in midst of this xact, +-- they are just marked as invalid in pgfdw_inval_callback. +ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); +DROP SERVER loopback3 CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to user mapping for public on server loopback3 +drop cascades to foreign table ft7 +-- List all the existing cached connections. loopback and loopback3 +-- should be output as invalid connections. Also the server name for +-- loopback3 should be NULL because the server was dropped. +SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; + server_name | valid +-------------+------- + loopback | f + | f +(2 rows) + +-- The invalid connections get closed in pgfdw_xact_callback during commit. +COMMIT; +-- All cached connections were closed while committing above xact, so no +-- records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- +(0 rows) + +-- ======================================================================= +-- test postgres_fdw_disconnect and postgres_fdw_disconnect_all functions +-- ======================================================================= +BEGIN; +-- Ensure to cache loopback connection. +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +-- Ensure to cache loopback2 connection. +SELECT 1 FROM ft6 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- + loopback + loopback2 +(2 rows) + +-- Issue a warning and return false as loopback connection is still in use and +-- can not be closed. +SELECT postgres_fdw_disconnect('loopback'); +WARNING: cannot close connection for server "loopback" because it is still in use + postgres_fdw_disconnect +------------------------- + f +(1 row) + +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- + loopback + loopback2 +(2 rows) + +-- Return false as connections are still in use, warnings are issued. +-- But disable warnings temporarily because the order of them is not stable. +SET client_min_messages = 'ERROR'; +SELECT postgres_fdw_disconnect_all(); + postgres_fdw_disconnect_all +----------------------------- + f +(1 row) + +RESET client_min_messages; +COMMIT; +-- Ensure that loopback2 connection is closed. +SELECT 1 FROM postgres_fdw_disconnect('loopback2'); + ?column? +---------- + 1 +(1 row) + +SELECT server_name FROM postgres_fdw_get_connections() WHERE server_name = 'loopback2'; + server_name +------------- +(0 rows) + +-- Return false as loopback2 connection is closed already. +SELECT postgres_fdw_disconnect('loopback2'); + postgres_fdw_disconnect +------------------------- + f +(1 row) + +-- Return an error as there is no foreign server with given name. +SELECT postgres_fdw_disconnect('unknownserver'); +ERROR: server "unknownserver" does not exist +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); + ?column? +---------- + 1 +(1 row) + +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- +(0 rows) + +-- ============================================================================= +-- test case for having multiple cached connections for a foreign server +-- ============================================================================= +CREATE ROLE regress_multi_conn_user1 SUPERUSER; +CREATE ROLE regress_multi_conn_user2 SUPERUSER; +CREATE USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +CREATE USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; +BEGIN; +-- Will cache loopback connection with user mapping for regress_multi_conn_user1 +SET ROLE regress_multi_conn_user1; +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +RESET ROLE; +-- Will cache loopback connection with user mapping for regress_multi_conn_user2 +SET ROLE regress_multi_conn_user2; +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +RESET ROLE; +-- Should output two connections for loopback server +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- + loopback + loopback +(2 rows) + +COMMIT; +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); + ?column? +---------- + 1 +(1 row) + +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- +(0 rows) + +-- Clean up +DROP USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +DROP USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; +DROP ROLE regress_multi_conn_user1; +DROP ROLE regress_multi_conn_user2; +-- =================================================================== +-- Test foreign server level option keep_connections +-- =================================================================== +-- By default, the connections associated with foreign server are cached i.e. +-- keep_connections option is on. Set it to off. +ALTER SERVER loopback OPTIONS (keep_connections 'off'); +-- connection to loopback server is closed at the end of xact +-- as keep_connections was set to off. +SELECT 1 FROM ft1 LIMIT 1; + ?column? +---------- + 1 +(1 row) + +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + server_name +------------- +(0 rows) + +ALTER SERVER loopback OPTIONS (SET keep_connections 'on'); +-- =================================================================== +-- batch insert +-- =================================================================== +BEGIN; +CREATE SERVER batch10 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( batch_size '10' ); +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + count +------- + 1 +(1 row) + +ALTER SERVER batch10 OPTIONS( SET batch_size '20' ); +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + count +------- + 0 +(1 row) + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=20']; + count +------- + 1 +(1 row) + +CREATE FOREIGN TABLE table30 ( x int ) SERVER batch10 OPTIONS ( batch_size '30' ); +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + count +------- + 1 +(1 row) + +ALTER FOREIGN TABLE table30 OPTIONS ( SET batch_size '40'); +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + count +------- + 0 +(1 row) + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=40']; + count +------- + 1 +(1 row) + +ROLLBACK; +CREATE TABLE batch_table ( x int ); +CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '10' ); +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; + QUERY PLAN +------------------------------------------------------------- + Insert on public.ftable + Remote SQL: INSERT INTO public.batch_table(x) VALUES ($1) + Batch Size: 10 + -> Function Scan on pg_catalog.generate_series i + Output: i.i + Function Call: generate_series(1, 10) +(6 rows) + +INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; +INSERT INTO ftable SELECT * FROM generate_series(11, 31) i; +INSERT INTO ftable VALUES (32); +INSERT INTO ftable VALUES (33), (34); +SELECT COUNT(*) FROM ftable; + count +------- + 34 +(1 row) + +TRUNCATE batch_table; +DROP FOREIGN TABLE ftable; +-- try if large batches exceed max number of bind parameters +CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '100000' ); +INSERT INTO ftable SELECT * FROM generate_series(1, 70000) i; +SELECT COUNT(*) FROM ftable; + count +------- + 70000 +(1 row) + +TRUNCATE batch_table; +DROP FOREIGN TABLE ftable; +-- Disable batch insert +CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '1' ); +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable VALUES (1), (2); + QUERY PLAN +------------------------------------------------------------- + Insert on public.ftable + Remote SQL: INSERT INTO public.batch_table(x) VALUES ($1) + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 +(5 rows) + +INSERT INTO ftable VALUES (1), (2); +SELECT COUNT(*) FROM ftable; + count +------- + 2 +(1 row) + +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +-- Use partitioning +CREATE TABLE batch_table ( x int ) PARTITION BY HASH (x); +CREATE TABLE batch_table_p0 (LIKE batch_table); +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 0) + SERVER loopback + OPTIONS (table_name 'batch_table_p0', batch_size '10'); +CREATE TABLE batch_table_p1 (LIKE batch_table); +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 1) + SERVER loopback + OPTIONS (table_name 'batch_table_p1', batch_size '1'); +CREATE TABLE batch_table_p2 + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 2); +INSERT INTO batch_table SELECT * FROM generate_series(1, 66) i; +SELECT COUNT(*) FROM batch_table; + count +------- + 66 +(1 row) + +-- Check that enabling batched inserts doesn't interfere with cross-partition +-- updates +CREATE TABLE batch_cp_upd_test (a int) PARTITION BY LIST (a); +CREATE TABLE batch_cp_upd_test1 (LIKE batch_cp_upd_test); +CREATE FOREIGN TABLE batch_cp_upd_test1_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (1) + SERVER loopback + OPTIONS (table_name 'batch_cp_upd_test1', batch_size '10'); +CREATE TABLE batch_cp_up_test1 PARTITION OF batch_cp_upd_test + FOR VALUES IN (2); +INSERT INTO batch_cp_upd_test VALUES (1), (2); +-- The following moves a row from the local partition to the foreign one +UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a; +ERROR: cannot route tuples into foreign table to be updated "batch_cp_upd_test1_f" +SELECT tableoid::regclass, * FROM batch_cp_upd_test; + tableoid | a +----------------------+--- + batch_cp_upd_test1_f | 1 + batch_cp_up_test1 | 2 +(2 rows) + +-- Clean up +DROP TABLE batch_table, batch_cp_upd_test, batch_table_p0, batch_table_p1 CASCADE; +-- Use partitioning +ALTER SERVER loopback OPTIONS (ADD batch_size '10'); +CREATE TABLE batch_table ( x int, field1 text, field2 text) PARTITION BY HASH (x); +CREATE TABLE batch_table_p0 (LIKE batch_table); +ALTER TABLE batch_table_p0 ADD CONSTRAINT p0_pkey PRIMARY KEY (x); +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 0) + SERVER loopback + OPTIONS (table_name 'batch_table_p0'); +CREATE TABLE batch_table_p1 (LIKE batch_table); +ALTER TABLE batch_table_p1 ADD CONSTRAINT p1_pkey PRIMARY KEY (x); +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback + OPTIONS (table_name 'batch_table_p1'); +INSERT INTO batch_table SELECT i, 'test'||i, 'test'|| i FROM generate_series(1, 50) i; +SELECT COUNT(*) FROM batch_table; + count +------- + 50 +(1 row) + +SELECT * FROM batch_table ORDER BY x; + x | field1 | field2 +----+--------+-------- + 1 | test1 | test1 + 2 | test2 | test2 + 3 | test3 | test3 + 4 | test4 | test4 + 5 | test5 | test5 + 6 | test6 | test6 + 7 | test7 | test7 + 8 | test8 | test8 + 9 | test9 | test9 + 10 | test10 | test10 + 11 | test11 | test11 + 12 | test12 | test12 + 13 | test13 | test13 + 14 | test14 | test14 + 15 | test15 | test15 + 16 | test16 | test16 + 17 | test17 | test17 + 18 | test18 | test18 + 19 | test19 | test19 + 20 | test20 | test20 + 21 | test21 | test21 + 22 | test22 | test22 + 23 | test23 | test23 + 24 | test24 | test24 + 25 | test25 | test25 + 26 | test26 | test26 + 27 | test27 | test27 + 28 | test28 | test28 + 29 | test29 | test29 + 30 | test30 | test30 + 31 | test31 | test31 + 32 | test32 | test32 + 33 | test33 | test33 + 34 | test34 | test34 + 35 | test35 | test35 + 36 | test36 | test36 + 37 | test37 | test37 + 38 | test38 | test38 + 39 | test39 | test39 + 40 | test40 | test40 + 41 | test41 | test41 + 42 | test42 | test42 + 43 | test43 | test43 + 44 | test44 | test44 + 45 | test45 | test45 + 46 | test46 | test46 + 47 | test47 | test47 + 48 | test48 | test48 + 49 | test49 | test49 + 50 | test50 | test50 +(50 rows) + +ALTER SERVER loopback OPTIONS (DROP batch_size); +-- =================================================================== +-- test asynchronous execution +-- =================================================================== +ALTER SERVER loopback OPTIONS (DROP extensions); +ALTER SERVER loopback OPTIONS (ADD async_capable 'true'); +ALTER SERVER loopback2 OPTIONS (ADD async_capable 'true'); +CREATE TABLE async_pt (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE base_tbl1 (a int, b int, c text); +CREATE TABLE base_tbl2 (a int, b int, c text); +CREATE FOREIGN TABLE async_p1 PARTITION OF async_pt FOR VALUES FROM (1000) TO (2000) + SERVER loopback OPTIONS (table_name 'base_tbl1'); +CREATE FOREIGN TABLE async_p2 PARTITION OF async_pt FOR VALUES FROM (2000) TO (3000) + SERVER loopback2 OPTIONS (table_name 'base_tbl2'); +INSERT INTO async_p1 SELECT 1000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +INSERT INTO async_p2 SELECT 2000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; +-- simple queries +CREATE TABLE result_tbl (a int, b int, c text); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; + QUERY PLAN +---------------------------------------------------------------------------------------- + Insert on public.result_tbl + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Remote SQL: SELECT a, b, c FROM public.base_tbl1 WHERE (((b % 100) = 0)) + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Remote SQL: SELECT a, b, c FROM public.base_tbl2 WHERE (((b % 100) = 0)) +(8 rows) + +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; +SELECT * FROM result_tbl ORDER BY a; + a | b | c +------+-----+------ + 1000 | 0 | 0000 + 1100 | 100 | 0100 + 1200 | 200 | 0200 + 1300 | 300 | 0300 + 1400 | 400 | 0400 + 1500 | 500 | 0500 + 1600 | 600 | 0600 + 1700 | 700 | 0700 + 1800 | 800 | 0800 + 1900 | 900 | 0900 + 2000 | 0 | 0000 + 2100 | 100 | 0100 + 2200 | 200 | 0200 + 2300 | 300 | 0300 + 2400 | 400 | 0400 + 2500 | 500 | 0500 + 2600 | 600 | 0600 + 2700 | 700 | 0700 + 2800 | 800 | 0800 + 2900 | 900 | 0900 +(20 rows) + +DELETE FROM result_tbl; +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + QUERY PLAN +---------------------------------------------------------------- + Insert on public.result_tbl + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Filter: (async_pt_1.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Filter: (async_pt_2.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl2 +(10 rows) + +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +SELECT * FROM result_tbl ORDER BY a; + a | b | c +------+-----+------ + 1505 | 505 | 0505 + 2505 | 505 | 0505 +(2 rows) + +DELETE FROM result_tbl; +-- Check case where multiple partitions use the same connection +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000) + SERVER loopback2 OPTIONS (table_name 'base_tbl3'); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + QUERY PLAN +---------------------------------------------------------------- + Insert on public.result_tbl + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Filter: (async_pt_1.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Filter: (async_pt_2.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl2 + -> Async Foreign Scan on public.async_p3 async_pt_3 + Output: async_pt_3.a, async_pt_3.b, async_pt_3.c + Filter: (async_pt_3.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl3 +(14 rows) + +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +SELECT * FROM result_tbl ORDER BY a; + a | b | c +------+-----+------ + 1505 | 505 | 0505 + 2505 | 505 | 0505 + 3505 | 505 | 0505 +(3 rows) + +DELETE FROM result_tbl; +DROP FOREIGN TABLE async_p3; +DROP TABLE base_tbl3; +-- Check case where the partitioned table has local/remote partitions +CREATE TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + QUERY PLAN +---------------------------------------------------------------- + Insert on public.result_tbl + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Filter: (async_pt_1.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Filter: (async_pt_2.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl2 + -> Seq Scan on public.async_p3 async_pt_3 + Output: async_pt_3.a, async_pt_3.b, async_pt_3.c + Filter: (async_pt_3.b === 505) +(13 rows) + +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +SELECT * FROM result_tbl ORDER BY a; + a | b | c +------+-----+------ + 1505 | 505 | 0505 + 2505 | 505 | 0505 + 3505 | 505 | 0505 +(3 rows) + +DELETE FROM result_tbl; +-- partitionwise joins +SET enable_partitionwise_join TO true; +CREATE TABLE join_tbl (a1 int, b1 int, c1 text, a2 int, b2 int, c2 text); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.join_tbl + -> Append + -> Async Foreign Scan + Output: t1_1.a, t1_1.b, t1_1.c, t2_1.a, t2_1.b, t2_1.c + Relations: (public.async_p1 t1_1) INNER JOIN (public.async_p1 t2_1) + Remote SQL: SELECT r5.a, r5.b, r5.c, r8.a, r8.b, r8.c FROM (public.base_tbl1 r5 INNER JOIN public.base_tbl1 r8 ON (((r5.a = r8.a)) AND ((r5.b = r8.b)) AND (((r5.b % 100) = 0)))) + -> Async Foreign Scan + Output: t1_2.a, t1_2.b, t1_2.c, t2_2.a, t2_2.b, t2_2.c + Relations: (public.async_p2 t1_2) INNER JOIN (public.async_p2 t2_2) + Remote SQL: SELECT r6.a, r6.b, r6.c, r9.a, r9.b, r9.c FROM (public.base_tbl2 r6 INNER JOIN public.base_tbl2 r9 ON (((r6.a = r9.a)) AND ((r6.b = r9.b)) AND (((r6.b % 100) = 0)))) + -> Hash Join + Output: t1_3.a, t1_3.b, t1_3.c, t2_3.a, t2_3.b, t2_3.c + Hash Cond: ((t2_3.a = t1_3.a) AND (t2_3.b = t1_3.b)) + -> Seq Scan on public.async_p3 t2_3 + Output: t2_3.a, t2_3.b, t2_3.c + -> Hash + Output: t1_3.a, t1_3.b, t1_3.c + -> Seq Scan on public.async_p3 t1_3 + Output: t1_3.a, t1_3.b, t1_3.c + Filter: ((t1_3.b % 100) = 0) +(20 rows) + +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +SELECT * FROM join_tbl ORDER BY a1; + a1 | b1 | c1 | a2 | b2 | c2 +------+-----+------+------+-----+------ + 1000 | 0 | 0000 | 1000 | 0 | 0000 + 1100 | 100 | 0100 | 1100 | 100 | 0100 + 1200 | 200 | 0200 | 1200 | 200 | 0200 + 1300 | 300 | 0300 | 1300 | 300 | 0300 + 1400 | 400 | 0400 | 1400 | 400 | 0400 + 1500 | 500 | 0500 | 1500 | 500 | 0500 + 1600 | 600 | 0600 | 1600 | 600 | 0600 + 1700 | 700 | 0700 | 1700 | 700 | 0700 + 1800 | 800 | 0800 | 1800 | 800 | 0800 + 1900 | 900 | 0900 | 1900 | 900 | 0900 + 2000 | 0 | 0000 | 2000 | 0 | 0000 + 2100 | 100 | 0100 | 2100 | 100 | 0100 + 2200 | 200 | 0200 | 2200 | 200 | 0200 + 2300 | 300 | 0300 | 2300 | 300 | 0300 + 2400 | 400 | 0400 | 2400 | 400 | 0400 + 2500 | 500 | 0500 | 2500 | 500 | 0500 + 2600 | 600 | 0600 | 2600 | 600 | 0600 + 2700 | 700 | 0700 | 2700 | 700 | 0700 + 2800 | 800 | 0800 | 2800 | 800 | 0800 + 2900 | 900 | 0900 | 2900 | 900 | 0900 + 3000 | 0 | 0000 | 3000 | 0 | 0000 + 3100 | 100 | 0100 | 3100 | 100 | 0100 + 3200 | 200 | 0200 | 3200 | 200 | 0200 + 3300 | 300 | 0300 | 3300 | 300 | 0300 + 3400 | 400 | 0400 | 3400 | 400 | 0400 + 3500 | 500 | 0500 | 3500 | 500 | 0500 + 3600 | 600 | 0600 | 3600 | 600 | 0600 + 3700 | 700 | 0700 | 3700 | 700 | 0700 + 3800 | 800 | 0800 | 3800 | 800 | 0800 + 3900 | 900 | 0900 | 3900 | 900 | 0900 +(30 rows) + +DELETE FROM join_tbl; +RESET enable_partitionwise_join; +-- Test rescan of an async Append node with do_exec_prune=false +SET enable_hashjoin TO false; +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + QUERY PLAN +---------------------------------------------------------------------------------------- + Insert on public.join_tbl + -> Nested Loop + Output: t1.a, t1.b, t1.c, t2.a, t2.b, t2.c + Join Filter: ((t1.a = t2.a) AND (t1.b = t2.b)) + -> Foreign Scan on public.async_p1 t1 + Output: t1.a, t1.b, t1.c + Remote SQL: SELECT a, b, c FROM public.base_tbl1 WHERE (((b % 100) = 0)) + -> Append + -> Async Foreign Scan on public.async_p1 t2_1 + Output: t2_1.a, t2_1.b, t2_1.c + Remote SQL: SELECT a, b, c FROM public.base_tbl1 + -> Async Foreign Scan on public.async_p2 t2_2 + Output: t2_2.a, t2_2.b, t2_2.c + Remote SQL: SELECT a, b, c FROM public.base_tbl2 + -> Seq Scan on public.async_p3 t2_3 + Output: t2_3.a, t2_3.b, t2_3.c +(16 rows) + +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +SELECT * FROM join_tbl ORDER BY a1; + a1 | b1 | c1 | a2 | b2 | c2 +------+-----+------+------+-----+------ + 1000 | 0 | 0000 | 1000 | 0 | 0000 + 1100 | 100 | 0100 | 1100 | 100 | 0100 + 1200 | 200 | 0200 | 1200 | 200 | 0200 + 1300 | 300 | 0300 | 1300 | 300 | 0300 + 1400 | 400 | 0400 | 1400 | 400 | 0400 + 1500 | 500 | 0500 | 1500 | 500 | 0500 + 1600 | 600 | 0600 | 1600 | 600 | 0600 + 1700 | 700 | 0700 | 1700 | 700 | 0700 + 1800 | 800 | 0800 | 1800 | 800 | 0800 + 1900 | 900 | 0900 | 1900 | 900 | 0900 +(10 rows) + +DELETE FROM join_tbl; +RESET enable_hashjoin; +-- Test interaction of async execution with plan-time partition pruning +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 3000; + QUERY PLAN +----------------------------------------------------------------------------- + Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Remote SQL: SELECT a, b, c FROM public.base_tbl1 WHERE ((a < 3000)) + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Remote SQL: SELECT a, b, c FROM public.base_tbl2 WHERE ((a < 3000)) +(7 rows) + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 2000; + QUERY PLAN +----------------------------------------------------------------------- + Foreign Scan on public.async_p1 async_pt + Output: async_pt.a, async_pt.b, async_pt.c + Remote SQL: SELECT a, b, c FROM public.base_tbl1 WHERE ((a < 2000)) +(3 rows) + +-- Test interaction of async execution with run-time partition pruning +SET plan_cache_mode TO force_generic_plan; +PREPARE async_pt_query (int, int) AS + INSERT INTO result_tbl SELECT * FROM async_pt WHERE a < $1 AND b === $2; +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (3000, 505); + QUERY PLAN +------------------------------------------------------------------------------------------ + Insert on public.result_tbl + -> Append + Subplans Removed: 1 + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Filter: (async_pt_1.b === $2) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 WHERE ((a < $1::integer)) + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Filter: (async_pt_2.b === $2) + Remote SQL: SELECT a, b, c FROM public.base_tbl2 WHERE ((a < $1::integer)) +(11 rows) + +EXECUTE async_pt_query (3000, 505); +SELECT * FROM result_tbl ORDER BY a; + a | b | c +------+-----+------ + 1505 | 505 | 0505 + 2505 | 505 | 0505 +(2 rows) + +DELETE FROM result_tbl; +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (2000, 505); + QUERY PLAN +------------------------------------------------------------------------------------------ + Insert on public.result_tbl + -> Append + Subplans Removed: 2 + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Filter: (async_pt_1.b === $2) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 WHERE ((a < $1::integer)) +(7 rows) + +EXECUTE async_pt_query (2000, 505); +SELECT * FROM result_tbl ORDER BY a; + a | b | c +------+-----+------ + 1505 | 505 | 0505 +(1 row) + +DELETE FROM result_tbl; +RESET plan_cache_mode; +CREATE TABLE local_tbl(a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'), (2505, 505, 'bar'); +ANALYZE local_tbl; +CREATE INDEX base_tbl1_idx ON base_tbl1 (a); +CREATE INDEX base_tbl2_idx ON base_tbl2 (a); +CREATE INDEX async_p3_idx ON async_p3 (a); +ANALYZE base_tbl1; +ANALYZE base_tbl2; +ANALYZE async_p3; +ALTER FOREIGN TABLE async_p1 OPTIONS (use_remote_estimate 'true'); +ALTER FOREIGN TABLE async_p2 OPTIONS (use_remote_estimate 'true'); +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + QUERY PLAN +------------------------------------------------------------------------------------------ + Nested Loop + Output: local_tbl.a, local_tbl.b, local_tbl.c, async_pt.a, async_pt.b, async_pt.c + -> Seq Scan on public.local_tbl + Output: local_tbl.a, local_tbl.b, local_tbl.c + Filter: (local_tbl.c = 'bar'::text) + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Remote SQL: SELECT a, b, c FROM public.base_tbl1 WHERE (($1::integer = a)) + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Remote SQL: SELECT a, b, c FROM public.base_tbl2 WHERE (($1::integer = a)) + -> Seq Scan on public.async_p3 async_pt_3 + Output: async_pt_3.a, async_pt_3.b, async_pt_3.c + Filter: (local_tbl.a = async_pt_3.a) +(15 rows) + +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + QUERY PLAN +------------------------------------------------------------------------------- + Nested Loop (actual rows=1 loops=1) + -> Seq Scan on local_tbl (actual rows=1 loops=1) + Filter: (c = 'bar'::text) + Rows Removed by Filter: 1 + -> Append (actual rows=1 loops=1) + -> Async Foreign Scan on async_p1 async_pt_1 (never executed) + -> Async Foreign Scan on async_p2 async_pt_2 (actual rows=1 loops=1) + -> Seq Scan on async_p3 async_pt_3 (never executed) + Filter: (local_tbl.a = a) +(9 rows) + +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + a | b | c | a | b | c +------+-----+-----+------+-----+------ + 2505 | 505 | bar | 2505 | 505 | 0505 +(1 row) + +ALTER FOREIGN TABLE async_p1 OPTIONS (DROP use_remote_estimate); +ALTER FOREIGN TABLE async_p2 OPTIONS (DROP use_remote_estimate); +DROP TABLE local_tbl; +DROP INDEX base_tbl1_idx; +DROP INDEX base_tbl2_idx; +DROP INDEX async_p3_idx; +-- Test that pending requests are processed properly +SET enable_mergejoin TO false; +SET enable_hashjoin TO false; +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; + QUERY PLAN +---------------------------------------------------------------- + Nested Loop + Output: t1.a, t1.b, t1.c, t2.a, t2.b, t2.c + Join Filter: (t1.a = t2.a) + -> Append + -> Async Foreign Scan on public.async_p1 t1_1 + Output: t1_1.a, t1_1.b, t1_1.c + Filter: (t1_1.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 + -> Async Foreign Scan on public.async_p2 t1_2 + Output: t1_2.a, t1_2.b, t1_2.c + Filter: (t1_2.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl2 + -> Seq Scan on public.async_p3 t1_3 + Output: t1_3.a, t1_3.b, t1_3.c + Filter: (t1_3.b === 505) + -> Materialize + Output: t2.a, t2.b, t2.c + -> Foreign Scan on public.async_p2 t2 + Output: t2.a, t2.b, t2.c + Remote SQL: SELECT a, b, c FROM public.base_tbl2 +(20 rows) + +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; + a | b | c | a | b | c +------+-----+------+------+-----+------ + 2505 | 505 | 0505 | 2505 | 505 | 0505 +(1 row) + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + QUERY PLAN +---------------------------------------------------------------- + Limit + Output: t1.a, t1.b, t1.c + -> Append + -> Async Foreign Scan on public.async_p1 t1_1 + Output: t1_1.a, t1_1.b, t1_1.c + Filter: (t1_1.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 + -> Async Foreign Scan on public.async_p2 t1_2 + Output: t1_2.a, t1_2.b, t1_2.c + Filter: (t1_2.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl2 + -> Seq Scan on public.async_p3 t1_3 + Output: t1_3.a, t1_3.b, t1_3.c + Filter: (t1_3.b === 505) +(14 rows) + +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------- + Limit (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Async Foreign Scan on async_p1 t1_1 (actual rows=0 loops=1) + Filter: (b === 505) + -> Async Foreign Scan on async_p2 t1_2 (actual rows=0 loops=1) + Filter: (b === 505) + -> Seq Scan on async_p3 t1_3 (actual rows=1 loops=1) + Filter: (b === 505) + Rows Removed by Filter: 101 +(9 rows) + +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + a | b | c +------+-----+------ + 3505 | 505 | 0505 +(1 row) + +-- Check with foreign modify +CREATE TABLE local_tbl (a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'); +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE remote_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl3'); +INSERT INTO remote_tbl VALUES (2505, 505, 'bar'); +CREATE TABLE base_tbl4 (a int, b int, c text); +CREATE FOREIGN TABLE insert_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl4'); +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); + QUERY PLAN +------------------------------------------------------------------------- + Insert on public.insert_tbl + Remote SQL: INSERT INTO public.base_tbl4(a, b, c) VALUES ($1, $2, $3) + Batch Size: 1 + -> Append + -> Seq Scan on public.local_tbl + Output: local_tbl.a, local_tbl.b, local_tbl.c + -> Async Foreign Scan on public.remote_tbl + Output: remote_tbl.a, remote_tbl.b, remote_tbl.c + Remote SQL: SELECT a, b, c FROM public.base_tbl3 +(9 rows) + +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); +SELECT * FROM insert_tbl ORDER BY a; + a | b | c +------+-----+----- + 1505 | 505 | foo + 2505 | 505 | bar +(2 rows) + +-- Check with direct modify +EXPLAIN (VERBOSE, COSTS OFF) +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; + QUERY PLAN +---------------------------------------------------------------------------------------- + Insert on public.join_tbl + CTE t + -> Update on public.remote_tbl + Output: remote_tbl.a, remote_tbl.b, remote_tbl.c + -> Foreign Update on public.remote_tbl + Remote SQL: UPDATE public.base_tbl3 SET c = (c || c) RETURNING a, b, c + -> Nested Loop Left Join + Output: async_pt.a, async_pt.b, async_pt.c, t.a, t.b, t.c + Join Filter: ((async_pt.a = t.a) AND (async_pt.b = t.b)) + -> Append + -> Async Foreign Scan on public.async_p1 async_pt_1 + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Filter: (async_pt_1.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl1 + -> Async Foreign Scan on public.async_p2 async_pt_2 + Output: async_pt_2.a, async_pt_2.b, async_pt_2.c + Filter: (async_pt_2.b === 505) + Remote SQL: SELECT a, b, c FROM public.base_tbl2 + -> Seq Scan on public.async_p3 async_pt_3 + Output: async_pt_3.a, async_pt_3.b, async_pt_3.c + Filter: (async_pt_3.b === 505) + -> CTE Scan on t + Output: t.a, t.b, t.c +(23 rows) + +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; +SELECT * FROM join_tbl ORDER BY a1; + a1 | b1 | c1 | a2 | b2 | c2 +------+-----+------+------+-----+-------- + 1505 | 505 | 0505 | | | + 2505 | 505 | 0505 | 2505 | 505 | barbar + 3505 | 505 | 0505 | | | +(3 rows) + +DELETE FROM join_tbl; +DROP TABLE local_tbl; +DROP FOREIGN TABLE remote_tbl; +DROP FOREIGN TABLE insert_tbl; +DROP TABLE base_tbl3; +DROP TABLE base_tbl4; +RESET enable_mergejoin; +RESET enable_hashjoin; +-- Test that UPDATE/DELETE with inherited target works with async_capable enabled +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Update on public.async_pt + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Foreign Update on public.async_p1 async_pt_1 + Foreign Update on public.async_p2 async_pt_2 + Update on public.async_p3 async_pt_3 + -> Append + -> Foreign Update on public.async_p1 async_pt_1 + Remote SQL: UPDATE public.base_tbl1 SET c = (c || c) WHERE ((b = 0)) RETURNING a, b, c + -> Foreign Update on public.async_p2 async_pt_2 + Remote SQL: UPDATE public.base_tbl2 SET c = (c || c) WHERE ((b = 0)) RETURNING a, b, c + -> Seq Scan on public.async_p3 async_pt_3 + Output: (async_pt_3.c || async_pt_3.c), async_pt_3.tableoid, async_pt_3.ctid, NULL::record + Filter: (async_pt_3.b = 0) +(13 rows) + +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; + a | b | c +------+---+---------- + 1000 | 0 | 00000000 + 2000 | 0 | 00000000 + 3000 | 0 | 00000000 +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM async_pt WHERE b = 0 RETURNING *; + QUERY PLAN +------------------------------------------------------------------------------------------ + Delete on public.async_pt + Output: async_pt_1.a, async_pt_1.b, async_pt_1.c + Foreign Delete on public.async_p1 async_pt_1 + Foreign Delete on public.async_p2 async_pt_2 + Delete on public.async_p3 async_pt_3 + -> Append + -> Foreign Delete on public.async_p1 async_pt_1 + Remote SQL: DELETE FROM public.base_tbl1 WHERE ((b = 0)) RETURNING a, b, c + -> Foreign Delete on public.async_p2 async_pt_2 + Remote SQL: DELETE FROM public.base_tbl2 WHERE ((b = 0)) RETURNING a, b, c + -> Seq Scan on public.async_p3 async_pt_3 + Output: async_pt_3.tableoid, async_pt_3.ctid + Filter: (async_pt_3.b = 0) +(13 rows) + +DELETE FROM async_pt WHERE b = 0 RETURNING *; + a | b | c +------+---+---------- + 1000 | 0 | 00000000 + 2000 | 0 | 00000000 + 3000 | 0 | 00000000 +(3 rows) + +-- Check EXPLAIN ANALYZE for a query that scans empty partitions asynchronously +DELETE FROM async_p1; +DELETE FROM async_p2; +DELETE FROM async_p3; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt; + QUERY PLAN +------------------------------------------------------------------------- + Append (actual rows=0 loops=1) + -> Async Foreign Scan on async_p1 async_pt_1 (actual rows=0 loops=1) + -> Async Foreign Scan on async_p2 async_pt_2 (actual rows=0 loops=1) + -> Seq Scan on async_p3 async_pt_3 (actual rows=0 loops=1) +(4 rows) + +-- Clean up +DROP TABLE async_pt; +DROP TABLE base_tbl1; +DROP TABLE base_tbl2; +DROP TABLE result_tbl; +DROP TABLE join_tbl; +ALTER SERVER loopback OPTIONS (DROP async_capable); +ALTER SERVER loopback2 OPTIONS (DROP async_capable); diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c index 1a03e02263ee..672b55a808f4 100644 --- a/contrib/postgres_fdw/option.c +++ b/contrib/postgres_fdw/option.c @@ -3,7 +3,7 @@ * option.c * FDW option handling for postgres_fdw * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/option.c @@ -107,7 +107,10 @@ postgres_fdw_validator(PG_FUNCTION_ARGS) * Validate option value, when we can do so without any context. */ if (strcmp(def->defname, "use_remote_estimate") == 0 || - strcmp(def->defname, "updatable") == 0) + strcmp(def->defname, "updatable") == 0 || + strcmp(def->defname, "truncatable") == 0 || + strcmp(def->defname, "async_capable") == 0 || + strcmp(def->defname, "keep_connections") == 0) { /* these accept only boolean values */ (void) defGetBoolean(def); @@ -142,6 +145,17 @@ postgres_fdw_validator(PG_FUNCTION_ARGS) errmsg("%s requires a non-negative integer value", def->defname))); } + else if (strcmp(def->defname, "batch_size") == 0) + { + int batch_size; + + batch_size = strtol(defGetString(def), NULL, 10); + if (batch_size <= 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("%s requires a non-negative integer value", + def->defname))); + } else if (strcmp(def->defname, "password_required") == 0) { bool pw_required = defGetBoolean(def); @@ -200,9 +214,19 @@ InitPgFdwOptions(void) /* updatable is available on both server and table */ {"updatable", ForeignServerRelationId, false}, {"updatable", ForeignTableRelationId, false}, + /* truncatable is available on both server and table */ + {"truncatable", ForeignServerRelationId, false}, + {"truncatable", ForeignTableRelationId, false}, /* fetch_size is available on both server and table */ {"fetch_size", ForeignServerRelationId, false}, {"fetch_size", ForeignTableRelationId, false}, + /* batch_size is available on both server and table */ + {"batch_size", ForeignServerRelationId, false}, + {"batch_size", ForeignTableRelationId, false}, + /* async_capable is available on both server and table */ + {"async_capable", ForeignServerRelationId, false}, + {"async_capable", ForeignTableRelationId, false}, + {"keep_connections", ForeignServerRelationId, false}, {"password_required", UserMappingRelationId, false}, /* diff --git a/contrib/postgres_fdw/postgres_fdw--1.0--1.1.sql b/contrib/postgres_fdw/postgres_fdw--1.0--1.1.sql new file mode 100644 index 000000000000..ed4ca378d4ab --- /dev/null +++ b/contrib/postgres_fdw/postgres_fdw--1.0--1.1.sql @@ -0,0 +1,20 @@ +/* contrib/postgres_fdw/postgres_fdw--1.0--1.1.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION postgres_fdw UPDATE TO '1.1'" to load this file. \quit + +CREATE FUNCTION postgres_fdw_get_connections (OUT server_name text, + OUT valid boolean) +RETURNS SETOF record +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT PARALLEL RESTRICTED; + +CREATE FUNCTION postgres_fdw_disconnect (text) +RETURNS bool +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT PARALLEL RESTRICTED; + +CREATE FUNCTION postgres_fdw_disconnect_all () +RETURNS bool +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT PARALLEL RESTRICTED; diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 560fa5602224..3622fac93cbb 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -3,7 +3,7 @@ * postgres_fdw.c * Foreign-data wrapper for remote PostgreSQL servers * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/postgres_fdw.c @@ -21,21 +21,25 @@ #include "commands/defrem.h" #include "commands/explain.h" #include "commands/vacuum.h" +#include "executor/execAsync.h" #include "foreign/fdwapi.h" #include "funcapi.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "optimizer/appendinfo.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" +#include "optimizer/prep.h" #include "optimizer/restrictinfo.h" #include "optimizer/tlist.h" #include "parser/parsetree.h" #include "postgres_fdw.h" +#include "storage/latch.h" #include "utils/builtins.h" #include "utils/float.h" #include "utils/guc.h" @@ -86,8 +90,10 @@ enum FdwScanPrivateIndex * 1) INSERT/UPDATE/DELETE statement text to be sent to the remote server * 2) Integer list of target attribute numbers for INSERT/UPDATE * (NIL for a DELETE) - * 3) Boolean flag showing if the remote query has a RETURNING clause - * 4) Integer list of attribute numbers retrieved by RETURNING, if any + * 3) Length till the end of VALUES clause for INSERT + * (-1 for a DELETE/UPDATE) + * 4) Boolean flag showing if the remote query has a RETURNING clause + * 5) Integer list of attribute numbers retrieved by RETURNING, if any */ enum FdwModifyPrivateIndex { @@ -95,6 +101,8 @@ enum FdwModifyPrivateIndex FdwModifyPrivateUpdateSql, /* Integer list of target attribute numbers for INSERT/UPDATE */ FdwModifyPrivateTargetAttnums, + /* Length till the end of VALUES clause (as an integer Value node) */ + FdwModifyPrivateLen, /* has-returning flag (as an integer Value node) */ FdwModifyPrivateHasReturning, /* Integer list of attribute numbers retrieved by RETURNING */ @@ -138,6 +146,7 @@ typedef struct PgFdwScanState /* for remote query execution */ PGconn *conn; /* connection for the scan */ + PgFdwConnState *conn_state; /* extra per-connection state */ unsigned int cursor_number; /* quasi-unique ID for my cursor */ bool cursor_exists; /* have we created the cursor? */ int numParams; /* number of parameters passed to query */ @@ -154,6 +163,9 @@ typedef struct PgFdwScanState int fetch_ct_2; /* Min(# of fetches done, 2) */ bool eof_reached; /* true if last fetch reached EOF */ + /* for asynchronous execution */ + bool async_capable; /* engage asynchronous-capable logic? */ + /* working memory contexts */ MemoryContext batch_cxt; /* context holding current batch of tuples */ MemoryContext temp_cxt; /* context for per-tuple temporary data */ @@ -171,11 +183,15 @@ typedef struct PgFdwModifyState /* for remote query execution */ PGconn *conn; /* connection for the scan */ + PgFdwConnState *conn_state; /* extra per-connection state */ char *p_name; /* name of prepared statement, if created */ /* extracted fdw_private data */ char *query; /* text of INSERT/UPDATE/DELETE command */ + char *orig_query; /* original text of INSERT command */ List *target_attrs; /* list of target attribute numbers */ + int values_end; /* length up to the end of VALUES */ + int batch_size; /* value of FDW option "batch_size" */ bool has_returning; /* is there a RETURNING clause? */ List *retrieved_attrs; /* attr numbers retrieved by RETURNING */ @@ -184,6 +200,9 @@ typedef struct PgFdwModifyState int p_nums; /* number of parameters to transmit */ FmgrInfo *p_flinfo; /* output conversion functions for them */ + /* batch operation stuff */ + int num_slots; /* number of slots to insert */ + /* working memory context */ MemoryContext temp_cxt; /* context for per-tuple temporary data */ @@ -208,6 +227,7 @@ typedef struct PgFdwDirectModifyState /* for remote query execution */ PGconn *conn; /* connection for the update */ + PgFdwConnState *conn_state; /* extra per-connection state */ int numParams; /* number of parameters passed to query */ FmgrInfo *param_flinfo; /* output conversion functions for them */ List *param_exprs; /* executable expressions for param values */ @@ -326,7 +346,8 @@ static void postgresBeginForeignScan(ForeignScanState *node, int eflags); static TupleTableSlot *postgresIterateForeignScan(ForeignScanState *node); static void postgresReScanForeignScan(ForeignScanState *node); static void postgresEndForeignScan(ForeignScanState *node); -static void postgresAddForeignUpdateTargets(Query *parsetree, +static void postgresAddForeignUpdateTargets(PlannerInfo *root, + Index rtindex, RangeTblEntry *target_rte, Relation target_relation); static List *postgresPlanForeignModify(PlannerInfo *root, @@ -342,6 +363,12 @@ static TupleTableSlot *postgresExecForeignInsert(EState *estate, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, TupleTableSlot *planSlot); +static TupleTableSlot **postgresExecForeignBatchInsert(EState *estate, + ResultRelInfo *resultRelInfo, + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int *numSlots); +static int postgresGetForeignModifyBatchSize(ResultRelInfo *resultRelInfo); static TupleTableSlot *postgresExecForeignUpdate(EState *estate, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, @@ -373,6 +400,9 @@ static void postgresExplainForeignModify(ModifyTableState *mtstate, ExplainState *es); static void postgresExplainDirectModify(ForeignScanState *node, ExplainState *es); +static void postgresExecForeignTruncate(List *rels, + DropBehavior behavior, + bool restart_seqs); static bool postgresAnalyzeForeignTable(Relation relation, AcquireSampleRowsFunc *func, BlockNumber *totalpages); @@ -392,6 +422,10 @@ static void postgresGetForeignUpperPaths(PlannerInfo *root, RelOptInfo *output_rel, void *extra); static int greenplumCheckIsGreenplum(UserMapping *user); +static bool postgresIsForeignPathAsyncCapable(ForeignPath *path); +static void postgresForeignAsyncRequest(AsyncRequest *areq); +static void postgresForeignAsyncConfigureWait(AsyncRequest *areq); +static void postgresForeignAsyncNotify(AsyncRequest *areq); /* * Helper functions @@ -421,7 +455,8 @@ static bool ec_member_matches_foreign(PlannerInfo *root, RelOptInfo *rel, void *arg); static void create_cursor(ForeignScanState *node); static void fetch_more_data(ForeignScanState *node); -static void close_cursor(PGconn *conn, unsigned int cursor_number); +static void close_cursor(PGconn *conn, unsigned int cursor_number, + PgFdwConnState *conn_state); static PgFdwModifyState *create_foreign_modify(EState *estate, RangeTblEntry *rte, ResultRelInfo *resultRelInfo, @@ -429,20 +464,24 @@ static PgFdwModifyState *create_foreign_modify(EState *estate, Plan *subplan, char *query, List *target_attrs, + int len, bool has_returning, List *retrieved_attrs); -static TupleTableSlot *execute_foreign_modify(EState *estate, - ResultRelInfo *resultRelInfo, - CmdType operation, - TupleTableSlot *slot, - TupleTableSlot *planSlot); +static TupleTableSlot **execute_foreign_modify(EState *estate, + ResultRelInfo *resultRelInfo, + CmdType operation, + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int *numSlots); static void prepare_foreign_modify(PgFdwModifyState *fmstate); static const char **convert_prep_stmt_params(PgFdwModifyState *fmstate, ItemPointer tupleid, - TupleTableSlot *slot); + TupleTableSlot **slots, + int numSlots); static void store_returning_result(PgFdwModifyState *fmstate, TupleTableSlot *slot, PGresult *res); static void finish_foreign_modify(PgFdwModifyState *fmstate); +static void deallocate_query(PgFdwModifyState *fmstate); static List *build_remote_returning(Index rtindex, Relation rel, List *returningList); static void rebuild_fdw_scan_tlist(ForeignScan *fscan, List *tlist); @@ -452,6 +491,7 @@ static void init_returning_filter(PgFdwDirectModifyState *dmstate, List *fdw_scan_tlist, Index rtindex); static TupleTableSlot *apply_returning_filter(PgFdwDirectModifyState *dmstate, + ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate); static void prepare_query_params(PlanState *node, @@ -470,6 +510,8 @@ static int postgresAcquireSampleRowsFunc(Relation relation, int elevel, double *totaldeadrows); static void analyze_row_processor(PGresult *res, int row, PgFdwAnalyzeState *astate); +static void produce_tuple_asynchronously(AsyncRequest *areq, bool fetch); +static void fetch_more_data_begin(AsyncRequest *areq); static HeapTuple make_tuple_from_result_row(PGresult *res, int row, Relation rel, @@ -504,6 +546,7 @@ static void apply_table_options(PgFdwRelationInfo *fpinfo); static void merge_fdw_options(PgFdwRelationInfo *fpinfo, const PgFdwRelationInfo *fpinfo_o, const PgFdwRelationInfo *fpinfo_i); +static int get_batch_size_option(Relation rel); /* @@ -529,6 +572,8 @@ postgres_fdw_handler(PG_FUNCTION_ARGS) routine->PlanForeignModify = postgresPlanForeignModify; routine->BeginForeignModify = postgresBeginForeignModify; routine->ExecForeignInsert = postgresExecForeignInsert; + routine->ExecForeignBatchInsert = postgresExecForeignBatchInsert; + routine->GetForeignModifyBatchSize = postgresGetForeignModifyBatchSize; routine->ExecForeignUpdate = postgresExecForeignUpdate; routine->ExecForeignDelete = postgresExecForeignDelete; routine->EndForeignModify = postgresEndForeignModify; @@ -547,6 +592,9 @@ postgres_fdw_handler(PG_FUNCTION_ARGS) routine->ExplainForeignModify = postgresExplainForeignModify; routine->ExplainDirectModify = postgresExplainDirectModify; + /* Support function for TRUNCATE */ + routine->ExecForeignTruncate = postgresExecForeignTruncate; + /* Support functions for ANALYZE */ routine->AnalyzeForeignTable = postgresAnalyzeForeignTable; @@ -559,6 +607,12 @@ postgres_fdw_handler(PG_FUNCTION_ARGS) /* Support functions for upper relation push-down */ routine->GetForeignUpperPaths = postgresGetForeignUpperPaths; + /* Support functions for asynchronous execution */ + routine->IsForeignPathAsyncCapable = postgresIsForeignPathAsyncCapable; + routine->ForeignAsyncRequest = postgresForeignAsyncRequest; + routine->ForeignAsyncConfigureWait = postgresForeignAsyncConfigureWait; + routine->ForeignAsyncNotify = postgresForeignAsyncNotify; + PG_RETURN_POINTER(routine); } @@ -593,14 +647,16 @@ postgresGetForeignRelSize(PlannerInfo *root, fpinfo->server = GetForeignServer(fpinfo->table->serverid); /* - * Extract user-settable option values. Note that per-table setting of - * use_remote_estimate overrides per-server setting. + * Extract user-settable option values. Note that per-table settings of + * use_remote_estimate, fetch_size and async_capable override per-server + * settings of them, respectively. */ fpinfo->use_remote_estimate = false; fpinfo->fdw_startup_cost = DEFAULT_FDW_STARTUP_COST; fpinfo->fdw_tuple_cost = DEFAULT_FDW_TUPLE_COST; fpinfo->shippable_extensions = NIL; fpinfo->fetch_size = 100; + fpinfo->async_capable = false; apply_server_options(fpinfo); apply_table_options(fpinfo); @@ -694,15 +750,14 @@ postgresGetForeignRelSize(PlannerInfo *root, else { /* - * If the foreign table has never been ANALYZEd, it will have relpages - * and reltuples equal to zero, which most likely has nothing to do - * with reality. We can't do a whole lot about that if we're not + * If the foreign table has never been ANALYZEd, it will have + * reltuples < 0, meaning "unknown". We can't do much if we're not * allowed to consult the remote server, but we can use a hack similar * to plancat.c's treatment of empty relations: use a minimum size * estimate of 10 pages, and divide by the column-datatype-based width * estimate to get the corresponding number of tuples. */ - if (baserel->pages == 0 && baserel->tuples == 0) + if (baserel->tuples < 0) { baserel->pages = 10; baserel->tuples = @@ -1386,6 +1441,57 @@ postgresGetForeignPlan(PlannerInfo *root, outer_plan); } +/* + * Construct a tuple descriptor for the scan tuples handled by a foreign join. + */ +static TupleDesc +get_tupdesc_for_join_scan_tuples(ForeignScanState *node) +{ + ForeignScan *fsplan = (ForeignScan *) node->ss.ps.plan; + EState *estate = node->ss.ps.state; + TupleDesc tupdesc; + + /* + * The core code has already set up a scan tuple slot based on + * fsplan->fdw_scan_tlist, and this slot's tupdesc is mostly good enough, + * but there's one case where it isn't. If we have any whole-row row + * identifier Vars, they may have vartype RECORD, and we need to replace + * that with the associated table's actual composite type. This ensures + * that when we read those ROW() expression values from the remote server, + * we can convert them to a composite type the local server knows. + */ + tupdesc = CreateTupleDescCopy(node->ss.ss_ScanTupleSlot->tts_tupleDescriptor); + for (int i = 0; i < tupdesc->natts; i++) + { + Form_pg_attribute att = TupleDescAttr(tupdesc, i); + Var *var; + RangeTblEntry *rte; + Oid reltype; + + /* Nothing to do if it's not a generic RECORD attribute */ + if (att->atttypid != RECORDOID || att->atttypmod >= 0) + continue; + + /* + * If we can't identify the referenced table, do nothing. This'll + * likely lead to failure later, but perhaps we can muddle through. + */ + var = (Var *) list_nth_node(TargetEntry, fsplan->fdw_scan_tlist, + i)->expr; + if (!IsA(var, Var) || var->varattno != 0) + continue; + rte = list_nth(estate->es_range_table, var->varno - 1); + if (rte->rtekind != RTE_RELATION) + continue; + reltype = get_rel_type_id(rte->relid); + if (!OidIsValid(reltype)) + continue; + att->atttypid = reltype; + /* shouldn't need to change anything else */ + } + return tupdesc; +} + /* * postgresBeginForeignScan * Initiate an executor scan of a foreign PostgreSQL table. @@ -1436,7 +1542,7 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags) * Get connection to the foreign server. Connection manager will * establish new connection if necessary. */ - fsstate->conn = GetConnection(user, false); + fsstate->conn = GetConnection(user, false, &fsstate->conn_state); /* Assign a unique ID for my cursor */ fsstate->cursor_number = GetCursorNumber(fsstate->conn); @@ -1470,7 +1576,7 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags) else { fsstate->rel = NULL; - fsstate->tupdesc = node->ss.ss_ScanTupleSlot->tts_tupleDescriptor; + fsstate->tupdesc = get_tupdesc_for_join_scan_tuples(node); } fsstate->attinmeta = TupleDescGetAttInMetadata(fsstate->tupdesc); @@ -1487,6 +1593,9 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags) &fsstate->param_flinfo, &fsstate->param_exprs, &fsstate->param_values); + + /* Set the async-capable flag */ + fsstate->async_capable = node->ss.ps.async_capable; } /* @@ -1501,8 +1610,10 @@ postgresIterateForeignScan(ForeignScanState *node) TupleTableSlot *slot = node->ss.ss_ScanTupleSlot; /* - * If this is the first call after Begin or ReScan, we need to create the - * cursor on the remote side. + * In sync mode, if this is the first call after Begin or ReScan, we need + * to create the cursor on the remote side. In async mode, we would have + * already created the cursor before we get here, even if this is the + * first call after Begin or ReScan. */ if (!fsstate->cursor_exists) create_cursor(node); @@ -1512,6 +1623,9 @@ postgresIterateForeignScan(ForeignScanState *node) */ if (fsstate->next_tuple >= fsstate->num_tuples) { + /* In async mode, just clear tuple slot. */ + if (fsstate->async_capable) + return ExecClearTuple(slot); /* No point in another fetch if we already detected EOF, though. */ if (!fsstate->eof_reached) fetch_more_data(node); @@ -1573,7 +1687,7 @@ postgresReScanForeignScan(ForeignScanState *node) * We don't use a PG_TRY block here, so be careful not to throw error * without releasing the PGresult. */ - res = pgfdw_exec_query(fsstate->conn, sql); + res = pgfdw_exec_query(fsstate->conn, sql, fsstate->conn_state); if (PQresultStatus(res) != PGRES_COMMAND_OK) pgfdw_report_error(ERROR, res, fsstate->conn, true, sql); PQclear(res); @@ -1601,7 +1715,8 @@ postgresEndForeignScan(ForeignScanState *node) /* Close the cursor if open, to prevent accumulation of cursors */ if (fsstate->cursor_exists) - close_cursor(fsstate->conn, fsstate->cursor_number); + close_cursor(fsstate->conn, fsstate->cursor_number, + fsstate->conn_state); /* Release remote connection */ ReleaseConnection(fsstate->conn); @@ -1615,36 +1730,27 @@ postgresEndForeignScan(ForeignScanState *node) * Add resjunk column(s) needed for update/delete on a foreign table */ static void -postgresAddForeignUpdateTargets(Query *parsetree, +postgresAddForeignUpdateTargets(PlannerInfo *root, + Index rtindex, RangeTblEntry *target_rte, Relation target_relation) { Var *var; - const char *attrname; - TargetEntry *tle; /* * In postgres_fdw, what we need is the ctid, same as for a regular table. */ /* Make a Var representing the desired value */ - var = makeVar(parsetree->resultRelation, + var = makeVar(rtindex, SelfItemPointerAttributeNumber, TIDOID, -1, InvalidOid, 0); - /* Wrap it in a resjunk TLE with the right name ... */ - attrname = "ctid"; - - tle = makeTargetEntry((Expr *) var, - list_length(parsetree->targetList) + 1, - pstrdup(attrname), - true); - - /* ... and add it to the query's targetlist */ - parsetree->targetList = lappend(parsetree->targetList, tle); + /* Register it as a row-identity column needed by this target rel */ + add_row_identity_var(root, var, rtindex, "ctid"); } /* @@ -1666,6 +1772,7 @@ postgresPlanForeignModify(PlannerInfo *root, List *returningList = NIL; List *retrieved_attrs = NIL; bool doNothing = false; + int values_end_len = -1; initStringInfo(&sql); @@ -1753,7 +1860,7 @@ postgresPlanForeignModify(PlannerInfo *root, deparseInsertSql(&sql, rte, resultRelation, rel, targetAttrs, doNothing, withCheckOptionList, returningList, - &retrieved_attrs); + &retrieved_attrs, &values_end_len); break; case CMD_UPDATE: deparseUpdateSql(&sql, rte, resultRelation, rel, @@ -1777,8 +1884,9 @@ postgresPlanForeignModify(PlannerInfo *root, * Build the fdw_private list that will be available to the executor. * Items in the list must match enum FdwModifyPrivateIndex, above. */ - return list_make4(makeString(sql.data), + return list_make5(makeString(sql.data), targetAttrs, + makeInteger(values_end_len), makeInteger((retrieved_attrs != NIL)), retrieved_attrs); } @@ -1798,6 +1906,7 @@ postgresBeginForeignModify(ModifyTableState *mtstate, char *query; List *target_attrs; bool has_returning; + int values_end_len; List *retrieved_attrs; RangeTblEntry *rte; @@ -1813,6 +1922,8 @@ postgresBeginForeignModify(ModifyTableState *mtstate, FdwModifyPrivateUpdateSql)); target_attrs = (List *) list_nth(fdw_private, FdwModifyPrivateTargetAttnums); + values_end_len = intVal(list_nth(fdw_private, + FdwModifyPrivateLen)); has_returning = intVal(list_nth(fdw_private, FdwModifyPrivateHasReturning)); retrieved_attrs = (List *) list_nth(fdw_private, @@ -1827,9 +1938,10 @@ postgresBeginForeignModify(ModifyTableState *mtstate, rte, resultRelInfo, mtstate->operation, - mtstate->mt_plans[subplan_index]->plan, + outerPlanState(mtstate)->plan, query, target_attrs, + values_end_len, has_returning, retrieved_attrs); @@ -1847,7 +1959,8 @@ postgresExecForeignInsert(EState *estate, TupleTableSlot *planSlot) { PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; - TupleTableSlot *rslot; + TupleTableSlot **rslot; + int numSlots = 1; /* * If the fmstate has aux_fmstate set, use the aux_fmstate (see @@ -1856,7 +1969,36 @@ postgresExecForeignInsert(EState *estate, if (fmstate->aux_fmstate) resultRelInfo->ri_FdwState = fmstate->aux_fmstate; rslot = execute_foreign_modify(estate, resultRelInfo, CMD_INSERT, - slot, planSlot); + &slot, &planSlot, &numSlots); + /* Revert that change */ + if (fmstate->aux_fmstate) + resultRelInfo->ri_FdwState = fmstate; + + return rslot ? *rslot : NULL; +} + +/* + * postgresExecForeignBatchInsert + * Insert multiple rows into a foreign table + */ +static TupleTableSlot ** +postgresExecForeignBatchInsert(EState *estate, + ResultRelInfo *resultRelInfo, + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int *numSlots) +{ + PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; + TupleTableSlot **rslot; + + /* + * If the fmstate has aux_fmstate set, use the aux_fmstate (see + * postgresBeginForeignInsert()) + */ + if (fmstate->aux_fmstate) + resultRelInfo->ri_FdwState = fmstate->aux_fmstate; + rslot = execute_foreign_modify(estate, resultRelInfo, CMD_INSERT, + slots, planSlots, numSlots); /* Revert that change */ if (fmstate->aux_fmstate) resultRelInfo->ri_FdwState = fmstate; @@ -1864,6 +2006,58 @@ postgresExecForeignInsert(EState *estate, return rslot; } +/* + * postgresGetForeignModifyBatchSize + * Determine the maximum number of tuples that can be inserted in bulk + * + * Returns the batch size specified for server or table. When batching is not + * allowed (e.g. for tables with AFTER ROW triggers or with RETURNING clause), + * returns 1. + */ +static int +postgresGetForeignModifyBatchSize(ResultRelInfo *resultRelInfo) +{ + int batch_size; + PgFdwModifyState *fmstate = resultRelInfo->ri_FdwState ? + (PgFdwModifyState *) resultRelInfo->ri_FdwState : + NULL; + + /* should be called only once */ + Assert(resultRelInfo->ri_BatchSize == 0); + + /* + * Should never get called when the insert is being performed as part of a + * row movement operation. + */ + Assert(fmstate == NULL || fmstate->aux_fmstate == NULL); + + /* + * In EXPLAIN without ANALYZE, ri_FdwState is NULL, so we have to lookup + * the option directly in server/table options. Otherwise just use the + * value we determined earlier. + */ + if (fmstate) + batch_size = fmstate->batch_size; + else + batch_size = get_batch_size_option(resultRelInfo->ri_RelationDesc); + + /* Disable batching when we have to use RETURNING. */ + if (resultRelInfo->ri_projectReturning != NULL || + (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_after_row)) + return 1; + + /* + * Otherwise use the batch size specified for server/table. The number of + * parameters in a batch is limited to 65535 (uint16), so make sure we + * don't exceed this limit by using the maximum batch_size possible. + */ + if (fmstate && fmstate->p_nums > 0) + batch_size = Min(batch_size, PQ_QUERY_PARAM_MAX_LIMIT / fmstate->p_nums); + + return batch_size; +} + /* * postgresExecForeignUpdate * Update one row in a foreign table @@ -1874,8 +2068,13 @@ postgresExecForeignUpdate(EState *estate, TupleTableSlot *slot, TupleTableSlot *planSlot) { - return execute_foreign_modify(estate, resultRelInfo, CMD_UPDATE, - slot, planSlot); + TupleTableSlot **rslot; + int numSlots = 1; + + rslot = execute_foreign_modify(estate, resultRelInfo, CMD_UPDATE, + &slot, &planSlot, &numSlots); + + return rslot ? rslot[0] : NULL; } /* @@ -1888,8 +2087,13 @@ postgresExecForeignDelete(EState *estate, TupleTableSlot *slot, TupleTableSlot *planSlot) { - return execute_foreign_modify(estate, resultRelInfo, CMD_DELETE, - slot, planSlot); + TupleTableSlot **rslot; + int numSlots = 1; + + rslot = execute_foreign_modify(estate, resultRelInfo, CMD_DELETE, + &slot, &planSlot, &numSlots); + + return rslot ? rslot[0] : NULL; } /* @@ -1921,11 +2125,12 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, PgFdwModifyState *fmstate; ModifyTable *plan = castNode(ModifyTable, mtstate->ps.plan); EState *estate = mtstate->ps.state; - Index resultRelation = resultRelInfo->ri_RangeTableIndex; + Index resultRelation; Relation rel = resultRelInfo->ri_RelationDesc; RangeTblEntry *rte; TupleDesc tupdesc = RelationGetDescr(rel); int attnum; + int values_end_len; StringInfoData sql; List *targetAttrs = NIL; List *retrieved_attrs = NIL; @@ -1940,8 +2145,7 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, */ if (plan && plan->operation == CMD_UPDATE && (resultRelInfo->ri_usesFdwDirectModify || - resultRelInfo->ri_FdwState) && - resultRelInfo > mtstate->resultRelInfo + mtstate->mt_whichplan) + resultRelInfo->ri_FdwState)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot route tuples into foreign table to be updated \"%s\"", @@ -1972,17 +2176,20 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, } /* - * If the foreign table is a partition, we need to create a new RTE - * describing the foreign table for use by deparseInsertSql and - * create_foreign_modify() below, after first copying the parent's RTE and - * modifying some fields to describe the foreign partition to work on. - * However, if this is invoked by UPDATE, the existing RTE may already - * correspond to this partition if it is one of the UPDATE subplan target - * rels; in that case, we can just use the existing RTE as-is. + * If the foreign table is a partition that doesn't have a corresponding + * RTE entry, we need to create a new RTE describing the foreign table for + * use by deparseInsertSql and create_foreign_modify() below, after first + * copying the parent's RTE and modifying some fields to describe the + * foreign partition to work on. However, if this is invoked by UPDATE, + * the existing RTE may already correspond to this partition if it is one + * of the UPDATE subplan target rels; in that case, we can just use the + * existing RTE as-is. */ - rte = exec_rt_fetch(resultRelation, estate); - if (rte->relid != RelationGetRelid(rel)) + if (resultRelInfo->ri_RangeTableIndex == 0) { + ResultRelInfo *rootResultRelInfo = resultRelInfo->ri_RootResultRelInfo; + + rte = exec_rt_fetch(rootResultRelInfo->ri_RangeTableIndex, estate); rte = copyObject(rte); rte->relid = RelationGetRelid(rel); rte->relkind = RELKIND_FOREIGN_TABLE; @@ -1994,15 +2201,22 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, * Vars contained in those expressions. */ if (plan && plan->operation == CMD_UPDATE && - resultRelation == plan->rootRelation) + rootResultRelInfo->ri_RangeTableIndex == plan->rootRelation) resultRelation = mtstate->resultRelInfo[0].ri_RangeTableIndex; + else + resultRelation = rootResultRelInfo->ri_RangeTableIndex; + } + else + { + resultRelation = resultRelInfo->ri_RangeTableIndex; + rte = exec_rt_fetch(resultRelation, estate); } /* Construct the SQL command string. */ deparseInsertSql(&sql, rte, resultRelation, rel, targetAttrs, doNothing, resultRelInfo->ri_WithCheckOptions, resultRelInfo->ri_returningList, - &retrieved_attrs); + &retrieved_attrs, &values_end_len); /* Construct an execution state. */ fmstate = create_foreign_modify(mtstate->ps.state, @@ -2012,6 +2226,7 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, NULL, sql.data, targetAttrs, + values_end_len, retrieved_attrs != NIL, retrieved_attrs); @@ -2137,6 +2352,65 @@ postgresRecheckForeignScan(ForeignScanState *node, TupleTableSlot *slot) return true; } +/* + * find_modifytable_subplan + * Helper routine for postgresPlanDirectModify to find the + * ModifyTable subplan node that scans the specified RTI. + * + * Returns NULL if the subplan couldn't be identified. That's not a fatal + * error condition, we just abandon trying to do the update directly. + */ +static ForeignScan * +find_modifytable_subplan(PlannerInfo *root, + ModifyTable *plan, + Index rtindex, + int subplan_index) +{ + Plan *subplan = outerPlan(plan); + + /* + * The cases we support are (1) the desired ForeignScan is the immediate + * child of ModifyTable, or (2) it is the subplan_index'th child of an + * Append node that is the immediate child of ModifyTable. There is no + * point in looking further down, as that would mean that local joins are + * involved, so we can't do the update directly. + * + * There could be a Result atop the Append too, acting to compute the + * UPDATE targetlist values. We ignore that here; the tlist will be + * checked by our caller. + * + * In principle we could examine all the children of the Append, but it's + * currently unlikely that the core planner would generate such a plan + * with the children out-of-order. Moreover, such a search risks costing + * O(N^2) time when there are a lot of children. + */ + if (IsA(subplan, Append)) + { + Append *appendplan = (Append *) subplan; + + if (subplan_index < list_length(appendplan->appendplans)) + subplan = (Plan *) list_nth(appendplan->appendplans, subplan_index); + } + else if (IsA(subplan, Result) && IsA(outerPlan(subplan), Append)) + { + Append *appendplan = (Append *) outerPlan(subplan); + + if (subplan_index < list_length(appendplan->appendplans)) + subplan = (Plan *) list_nth(appendplan->appendplans, subplan_index); + } + + /* Now, have we got a ForeignScan on the desired rel? */ + if (IsA(subplan, ForeignScan)) + { + ForeignScan *fscan = (ForeignScan *) subplan; + + if (bms_is_member(rtindex, fscan->fs_relids)) + return fscan; + } + + return NULL; +} + /* * postgresPlanDirectModify * Consider a direct foreign table modification @@ -2151,13 +2425,13 @@ postgresPlanDirectModify(PlannerInfo *root, int subplan_index) { CmdType operation = plan->operation; - Plan *subplan; RelOptInfo *foreignrel; RangeTblEntry *rte; PgFdwRelationInfo *fpinfo; Relation rel; StringInfoData sql; ForeignScan *fscan; + List *processed_tlist = NIL; List *targetAttrs = NIL; List *remote_exprs; List *params_list = NIL; @@ -2175,19 +2449,17 @@ postgresPlanDirectModify(PlannerInfo *root, return false; /* - * It's unsafe to modify a foreign table directly if there are any local - * joins needed. + * Try to locate the ForeignScan subplan that's scanning resultRelation. */ - subplan = (Plan *) list_nth(plan->plans, subplan_index); - if (!IsA(subplan, ForeignScan)) + fscan = find_modifytable_subplan(root, plan, resultRelation, subplan_index); + if (!fscan) return false; - fscan = (ForeignScan *) subplan; /* * It's unsafe to modify a foreign table directly if there are any quals * that should be evaluated locally. */ - if (subplan->qual != NIL) + if (fscan->scan.plan.qual != NIL) return false; /* Safe to fetch data about the target foreign rel */ @@ -2208,32 +2480,28 @@ postgresPlanDirectModify(PlannerInfo *root, */ if (operation == CMD_UPDATE) { - int col; + ListCell *lc, + *lc2; /* - * We transmit only columns that were explicitly targets of the - * UPDATE, so as to avoid unnecessary data transmission. + * The expressions of concern are the first N columns of the processed + * targetlist, where N is the length of the rel's update_colnos. */ - col = -1; - while ((col = bms_next_member(rte->updatedCols, col)) >= 0) + get_translated_update_targetlist(root, resultRelation, + &processed_tlist, &targetAttrs); + forboth(lc, processed_tlist, lc2, targetAttrs) { - /* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */ - AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber; - TargetEntry *tle; + TargetEntry *tle = lfirst_node(TargetEntry, lc); + AttrNumber attno = lfirst_int(lc2); + + /* update's new-value expressions shouldn't be resjunk */ + Assert(!tle->resjunk); if (attno <= InvalidAttrNumber) /* shouldn't happen */ elog(ERROR, "system-column update is not supported"); - tle = get_tle_by_resno(subplan->targetlist, attno); - - if (!tle) - elog(ERROR, "attribute number %d not found in subplan targetlist", - attno); - if (!is_foreign_expr(root, foreignrel, (Expr *) tle->expr)) return false; - - targetAttrs = lappend_int(targetAttrs, attno); } } @@ -2284,7 +2552,7 @@ postgresPlanDirectModify(PlannerInfo *root, case CMD_UPDATE: deparseDirectUpdateSql(&sql, root, resultRelation, rel, foreignrel, - ((Plan *) fscan)->targetlist, + processed_tlist, targetAttrs, remote_exprs, ¶ms_list, returningList, &retrieved_attrs); @@ -2301,9 +2569,10 @@ postgresPlanDirectModify(PlannerInfo *root, } /* - * Update the operation info. + * Update the operation and target relation info. */ fscan->operation = operation; + fscan->resultRelation = resultRelation; /* * Update the fdw_exprs list that will be available to the executor. @@ -2332,6 +2601,13 @@ postgresPlanDirectModify(PlannerInfo *root, rebuild_fdw_scan_tlist(fscan, returningList); } + /* + * Finally, unset the async-capable flag if it is set, as we currently + * don't support asynchronous execution of direct modifications. + */ + if (fscan->scan.plan.async_capable) + fscan->scan.plan.async_capable = false; + table_close(rel, NoLock); return true; } @@ -2369,7 +2645,7 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags) * Identify which user to do the remote access as. This should match what * ExecCheckRTEPerms() does. */ - rtindex = estate->es_result_relation_info->ri_RangeTableIndex; + rtindex = node->resultRelInfo->ri_RangeTableIndex; rte = exec_rt_fetch(rtindex, estate); userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); @@ -2385,7 +2661,7 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags) * Get connection to the foreign server. Connection manager will * establish new connection if necessary. */ - dmstate->conn = GetConnection(user, false); + dmstate->conn = GetConnection(user, false, &dmstate->conn_state); /* Update the foreign-join-related fields. */ if (fsplan->scan.scanrelid == 0) @@ -2426,7 +2702,7 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags) TupleDesc tupdesc; if (fsplan->scan.scanrelid == 0) - tupdesc = node->ss.ss_ScanTupleSlot->tts_tupleDescriptor; + tupdesc = get_tupdesc_for_join_scan_tuples(node); else tupdesc = RelationGetDescr(dmstate->rel); @@ -2464,7 +2740,7 @@ postgresIterateDirectModify(ForeignScanState *node) { PgFdwDirectModifyState *dmstate = (PgFdwDirectModifyState *) node->fdw_state; EState *estate = node->ss.ps.state; - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; + ResultRelInfo *resultRelInfo = node->resultRelInfo; /* * If this is the first call after Begin, execute the statement. @@ -2603,8 +2879,8 @@ postgresExplainForeignScan(ForeignScanState *node, ExplainState *es) quote_identifier(relname)); } else - appendStringInfo(relations, "%s", - quote_identifier(relname)); + appendStringInfoString(relations, + quote_identifier(relname)); refname = (char *) list_nth(es->rtable_names, rti - 1); if (refname == NULL) refname = rte->eref->aliasname; @@ -2647,6 +2923,13 @@ postgresExplainForeignModify(ModifyTableState *mtstate, FdwModifyPrivateUpdateSql)); ExplainPropertyText("Remote SQL", sql, es); + + /* + * For INSERT we should always have batch size >= 1, but UPDATE and + * DELETE don't support batching so don't show the property. + */ + if (rinfo->ri_BatchSize > 0) + ExplainPropertyInteger("Batch Size", NULL, rinfo->ri_BatchSize, es); } } @@ -2669,6 +2952,101 @@ postgresExplainDirectModify(ForeignScanState *node, ExplainState *es) } } +/* + * postgresExecForeignTruncate + * Truncate one or more foreign tables + */ +static void +postgresExecForeignTruncate(List *rels, + DropBehavior behavior, + bool restart_seqs) +{ + Oid serverid = InvalidOid; + UserMapping *user = NULL; + PGconn *conn = NULL; + StringInfoData sql; + ListCell *lc; + bool server_truncatable = true; + + /* + * By default, all postgres_fdw foreign tables are assumed truncatable. + * This can be overridden by a per-server setting, which in turn can be + * overridden by a per-table setting. + */ + foreach(lc, rels) + { + ForeignServer *server = NULL; + Relation rel = lfirst(lc); + ForeignTable *table = GetForeignTable(RelationGetRelid(rel)); + ListCell *cell; + bool truncatable; + + /* + * First time through, determine whether the foreign server allows + * truncates. Since all specified foreign tables are assumed to belong + * to the same foreign server, this result can be used for other + * foreign tables. + */ + if (!OidIsValid(serverid)) + { + serverid = table->serverid; + server = GetForeignServer(serverid); + + foreach(cell, server->options) + { + DefElem *defel = (DefElem *) lfirst(cell); + + if (strcmp(defel->defname, "truncatable") == 0) + { + server_truncatable = defGetBoolean(defel); + break; + } + } + } + + /* + * Confirm that all specified foreign tables belong to the same + * foreign server. + */ + Assert(table->serverid == serverid); + + /* Determine whether this foreign table allows truncations */ + truncatable = server_truncatable; + foreach(cell, table->options) + { + DefElem *defel = (DefElem *) lfirst(cell); + + if (strcmp(defel->defname, "truncatable") == 0) + { + truncatable = defGetBoolean(defel); + break; + } + } + + if (!truncatable) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("foreign table \"%s\" does not allow truncates", + RelationGetRelationName(rel)))); + } + Assert(OidIsValid(serverid)); + + /* + * Get connection to the foreign server. Connection manager will + * establish new connection if necessary. + */ + user = GetUserMapping(GetUserId(), serverid); + conn = GetConnection(user, false, NULL); + + /* Construct the TRUNCATE command string */ + initStringInfo(&sql); + deparseTruncateSql(&sql, rels, behavior, restart_seqs); + + /* Issue the TRUNCATE command to remote server */ + do_sql_command(conn, sql.data); + + pfree(sql.data); +} /* * estimate_path_cost_size @@ -2759,7 +3137,7 @@ estimate_path_cost_size(PlannerInfo *root, false, &retrieved_attrs, NULL); /* Get the remote estimate */ - conn = GetConnection(fpinfo->user, false); + conn = GetConnection(fpinfo->user, false, NULL); get_remote_estimate(sql.data, conn, &rows, &width, &startup_cost, &total_cost); ReleaseConnection(conn); @@ -2821,7 +3199,7 @@ estimate_path_cost_size(PlannerInfo *root, */ if (fpinfo->rel_startup_cost >= 0 && fpinfo->rel_total_cost >= 0) { - Assert(fpinfo->retrieved_rows >= 1); + Assert(fpinfo->retrieved_rows >= 0); rows = fpinfo->rows; retrieved_rows = fpinfo->retrieved_rows; @@ -2957,16 +3335,7 @@ estimate_path_cost_size(PlannerInfo *root, MemSet(&aggcosts, 0, sizeof(AggClauseCosts)); if (root->parse->hasAggs) { - get_agg_clause_costs(root, (Node *) fpinfo->grouped_tlist, - AGGSPLIT_SIMPLE, &aggcosts); - - /* - * The cost of aggregates in the HAVING qual will be the same - * for each child as it is for the parent, so there's no need - * to use a translated version of havingQual. - */ - get_agg_clause_costs(root, (Node *) root->parse->havingQual, - AGGSPLIT_SIMPLE, &aggcosts); + get_agg_clause_costs(root, AGGSPLIT_SIMPLE, &aggcosts); } /* Get number of grouping columns and possible number of groups */ @@ -2974,7 +3343,7 @@ estimate_path_cost_size(PlannerInfo *root, numGroups = estimate_num_groups(root, get_sortgrouplist_exprs(root->parse->groupClause, fpinfo->grouped_tlist), - input_rows, NULL); + input_rows, NULL, NULL); /* * Get the retrieved_rows and rows estimates. If there are HAVING @@ -3216,7 +3585,7 @@ get_remote_estimate(const char *sql, PGconn *conn, /* * Execute EXPLAIN remotely. */ - res = pgfdw_exec_query(conn, sql); + res = pgfdw_exec_query(conn, sql, NULL); if (PQresultStatus(res) != PGRES_TUPLES_OK) pgfdw_report_error(ERROR, res, conn, false, sql); @@ -3340,6 +3709,10 @@ create_cursor(ForeignScanState *node) StringInfoData buf; PGresult *res; + /* First, process a pending asynchronous request, if any. */ + if (fsstate->conn_state->pendingAreq) + process_pending_request(fsstate->conn_state->pendingAreq); + /* * Construct array of query parameter values in text format. We do the * conversions in the short-lived per-tuple context, so as not to cause a @@ -3420,17 +3793,38 @@ fetch_more_data(ForeignScanState *node) PG_TRY(); { PGconn *conn = fsstate->conn; - char sql[64]; int numrows; int i; - snprintf(sql, sizeof(sql), "FETCH %d FROM c%u", - fsstate->fetch_size, fsstate->cursor_number); + if (fsstate->async_capable) + { + Assert(fsstate->conn_state->pendingAreq); - res = pgfdw_exec_query(conn, sql); - /* On error, report the original query, not the FETCH. */ - if (PQresultStatus(res) != PGRES_TUPLES_OK) - pgfdw_report_error(ERROR, res, conn, false, fsstate->query); + /* + * The query was already sent by an earlier call to + * fetch_more_data_begin. So now we just fetch the result. + */ + res = pgfdw_get_result(conn, fsstate->query); + /* On error, report the original query, not the FETCH. */ + if (PQresultStatus(res) != PGRES_TUPLES_OK) + pgfdw_report_error(ERROR, res, conn, false, fsstate->query); + + /* Reset per-connection state */ + fsstate->conn_state->pendingAreq = NULL; + } + else + { + char sql[64]; + + /* This is a regular synchronous fetch. */ + snprintf(sql, sizeof(sql), "FETCH %d FROM c%u", + fsstate->fetch_size, fsstate->cursor_number); + + res = pgfdw_exec_query(conn, sql, fsstate->conn_state); + /* On error, report the original query, not the FETCH. */ + if (PQresultStatus(res) != PGRES_TUPLES_OK) + pgfdw_report_error(ERROR, res, conn, false, fsstate->query); + } /* Convert the data into HeapTuples */ numrows = PQntuples(res); @@ -3522,7 +3916,8 @@ reset_transmission_modes(int nestlevel) * Utility routine to close a cursor. */ static void -close_cursor(PGconn *conn, unsigned int cursor_number) +close_cursor(PGconn *conn, unsigned int cursor_number, + PgFdwConnState *conn_state) { char sql[64]; PGresult *res; @@ -3533,7 +3928,7 @@ close_cursor(PGconn *conn, unsigned int cursor_number) * We don't use a PG_TRY block here, so be careful not to throw error * without releasing the PGresult. */ - res = pgfdw_exec_query(conn, sql); + res = pgfdw_exec_query(conn, sql, conn_state); if (PQresultStatus(res) != PGRES_COMMAND_OK) pgfdw_report_error(ERROR, res, conn, true, sql); PQclear(res); @@ -3552,6 +3947,7 @@ create_foreign_modify(EState *estate, Plan *subplan, char *query, List *target_attrs, + int values_end, bool has_returning, List *retrieved_attrs) { @@ -3581,12 +3977,18 @@ create_foreign_modify(EState *estate, user = GetUserMapping(userid, table->serverid); /* Open connection; report that we'll create a prepared statement. */ - fmstate->conn = GetConnection(user, true); + fmstate->conn = GetConnection(user, true, &fmstate->conn_state); fmstate->p_name = NULL; /* prepared statement not made yet */ /* Set up remote query information. */ fmstate->query = query; + if (operation == CMD_INSERT) + { + fmstate->query = pstrdup(fmstate->query); + fmstate->orig_query = pstrdup(fmstate->query); + } fmstate->target_attrs = target_attrs; + fmstate->values_end = values_end; fmstate->has_returning = has_returning; fmstate->retrieved_attrs = retrieved_attrs; @@ -3638,6 +4040,12 @@ create_foreign_modify(EState *estate, Assert(fmstate->p_nums <= n_params); + /* Set batch_size from foreign server/table options. */ + if (operation == CMD_INSERT) + fmstate->batch_size = get_batch_size_option(rel); + + fmstate->num_slots = 1; + /* Initialize auxiliary state */ fmstate->aux_fmstate = NULL; @@ -3648,26 +4056,52 @@ create_foreign_modify(EState *estate, * execute_foreign_modify * Perform foreign-table modification as required, and fetch RETURNING * result if any. (This is the shared guts of postgresExecForeignInsert, - * postgresExecForeignUpdate, and postgresExecForeignDelete.) + * postgresExecForeignBatchInsert, postgresExecForeignUpdate, and + * postgresExecForeignDelete.) */ -static TupleTableSlot * +static TupleTableSlot ** execute_foreign_modify(EState *estate, ResultRelInfo *resultRelInfo, CmdType operation, - TupleTableSlot *slot, - TupleTableSlot *planSlot) + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int *numSlots) { PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; ItemPointer ctid = NULL; const char **p_values; PGresult *res; int n_rows; + StringInfoData sql; /* The operation should be INSERT, UPDATE, or DELETE */ Assert(operation == CMD_INSERT || operation == CMD_UPDATE || operation == CMD_DELETE); + /* First, process a pending asynchronous request, if any. */ + if (fmstate->conn_state->pendingAreq) + process_pending_request(fmstate->conn_state->pendingAreq); + + /* + * If the existing query was deparsed and prepared for a different number + * of rows, rebuild it for the proper number. + */ + if (operation == CMD_INSERT && fmstate->num_slots != *numSlots) + { + /* Destroy the prepared statement created previously */ + if (fmstate->p_name) + deallocate_query(fmstate); + + /* Build INSERT string with numSlots records in its VALUES clause. */ + initStringInfo(&sql); + rebuildInsertSql(&sql, fmstate->orig_query, fmstate->values_end, + fmstate->p_nums, *numSlots - 1); + pfree(fmstate->query); + fmstate->query = sql.data; + fmstate->num_slots = *numSlots; + } + /* Set up the prepared statement on the remote server, if we didn't yet */ if (!fmstate->p_name) prepare_foreign_modify(fmstate); @@ -3680,7 +4114,7 @@ execute_foreign_modify(EState *estate, Datum datum; bool isNull; - datum = ExecGetJunkAttribute(planSlot, + datum = ExecGetJunkAttribute(planSlots[0], fmstate->ctidAttno, &isNull); /* shouldn't ever get a null result... */ @@ -3690,14 +4124,14 @@ execute_foreign_modify(EState *estate, } /* Convert parameters needed by prepared statement to text form */ - p_values = convert_prep_stmt_params(fmstate, ctid, slot); + p_values = convert_prep_stmt_params(fmstate, ctid, slots, *numSlots); /* * Execute the prepared statement. */ if (!PQsendQueryPrepared(fmstate->conn, fmstate->p_name, - fmstate->p_nums, + fmstate->p_nums * (*numSlots), p_values, NULL, NULL, @@ -3718,9 +4152,10 @@ execute_foreign_modify(EState *estate, /* Check number of rows affected, and fetch RETURNING tuple if any */ if (fmstate->has_returning) { + Assert(*numSlots == 1); n_rows = PQntuples(res); if (n_rows > 0) - store_returning_result(fmstate, slot, res); + store_returning_result(fmstate, slots[0], res); } else n_rows = atoi(PQcmdTuples(res)); @@ -3730,10 +4165,12 @@ execute_foreign_modify(EState *estate, MemoryContextReset(fmstate->temp_cxt); + *numSlots = n_rows; + /* * Return NULL if nothing was inserted/updated/deleted on the remote end */ - return (n_rows > 0) ? slot : NULL; + return (n_rows > 0) ? slots : NULL; } /* @@ -3747,6 +4184,11 @@ prepare_foreign_modify(PgFdwModifyState *fmstate) char *p_name; PGresult *res; + /* + * The caller would already have processed a pending asynchronous request + * if any, so no need to do it here. + */ + /* Construct name we'll use for the prepared statement. */ snprintf(prep_name, sizeof(prep_name), "pgsql_fdw_prep_%u", GetPrepStmtNumber(fmstate->conn)); @@ -3793,52 +4235,64 @@ prepare_foreign_modify(PgFdwModifyState *fmstate) static const char ** convert_prep_stmt_params(PgFdwModifyState *fmstate, ItemPointer tupleid, - TupleTableSlot *slot) + TupleTableSlot **slots, + int numSlots) { const char **p_values; + int i; + int j; int pindex = 0; MemoryContext oldcontext; oldcontext = MemoryContextSwitchTo(fmstate->temp_cxt); - p_values = (const char **) palloc(sizeof(char *) * fmstate->p_nums); + p_values = (const char **) palloc(sizeof(char *) * fmstate->p_nums * numSlots); + + /* ctid is provided only for UPDATE/DELETE, which don't allow batching */ + Assert(!(tupleid != NULL && numSlots > 1)); /* 1st parameter should be ctid, if it's in use */ if (tupleid != NULL) { + Assert(numSlots == 1); /* don't need set_transmission_modes for TID output */ p_values[pindex] = OutputFunctionCall(&fmstate->p_flinfo[pindex], PointerGetDatum(tupleid)); pindex++; } - /* get following parameters from slot */ - if (slot != NULL && fmstate->target_attrs != NIL) + /* get following parameters from slots */ + if (slots != NULL && fmstate->target_attrs != NIL) { int nestlevel; ListCell *lc; nestlevel = set_transmission_modes(); - foreach(lc, fmstate->target_attrs) + for (i = 0; i < numSlots; i++) { - int attnum = lfirst_int(lc); - Datum value; - bool isnull; + j = (tupleid != NULL) ? 1 : 0; + foreach(lc, fmstate->target_attrs) + { + int attnum = lfirst_int(lc); + Datum value; + bool isnull; - value = slot_getattr(slot, attnum, &isnull); - if (isnull) - p_values[pindex] = NULL; - else - p_values[pindex] = OutputFunctionCall(&fmstate->p_flinfo[pindex], - value); - pindex++; + value = slot_getattr(slots[i], attnum, &isnull); + if (isnull) + p_values[pindex] = NULL; + else + p_values[pindex] = OutputFunctionCall(&fmstate->p_flinfo[j], + value); + pindex++; + j++; + } } reset_transmission_modes(nestlevel); } - Assert(pindex == fmstate->p_nums); + Assert(pindex == fmstate->p_nums * numSlots); MemoryContextSwitchTo(oldcontext); @@ -3892,29 +4346,42 @@ finish_foreign_modify(PgFdwModifyState *fmstate) Assert(fmstate != NULL); /* If we created a prepared statement, destroy it */ - if (fmstate->p_name) - { - char sql[64]; - PGresult *res; - - snprintf(sql, sizeof(sql), "DEALLOCATE %s", fmstate->p_name); - - /* - * We don't use a PG_TRY block here, so be careful not to throw error - * without releasing the PGresult. - */ - res = pgfdw_exec_query(fmstate->conn, sql); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - pgfdw_report_error(ERROR, res, fmstate->conn, true, sql); - PQclear(res); - fmstate->p_name = NULL; - } + deallocate_query(fmstate); /* Release remote connection */ ReleaseConnection(fmstate->conn); fmstate->conn = NULL; } +/* + * deallocate_query + * Deallocate a prepared statement for a foreign insert/update/delete + * operation + */ +static void +deallocate_query(PgFdwModifyState *fmstate) +{ + char sql[64]; + PGresult *res; + + /* do nothing if the query is not allocated */ + if (!fmstate->p_name) + return; + + snprintf(sql, sizeof(sql), "DEALLOCATE %s", fmstate->p_name); + + /* + * We don't use a PG_TRY block here, so be careful not to throw error + * without releasing the PGresult. + */ + res = pgfdw_exec_query(fmstate->conn, sql, fmstate->conn_state); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + pgfdw_report_error(ERROR, res, fmstate->conn, true, sql); + PQclear(res); + pfree(fmstate->p_name); + fmstate->p_name = NULL; +} + /* * build_remote_returning * Build a RETURNING targetlist of a remote query for performing an @@ -4055,6 +4522,10 @@ execute_dml_stmt(ForeignScanState *node) int numParams = dmstate->numParams; const char **values = dmstate->param_values; + /* First, process a pending asynchronous request, if any. */ + if (dmstate->conn_state->pendingAreq) + process_pending_request(dmstate->conn_state->pendingAreq); + /* * Construct array of query parameter values in text format. */ @@ -4102,7 +4573,7 @@ get_returning_data(ForeignScanState *node) { PgFdwDirectModifyState *dmstate = (PgFdwDirectModifyState *) node->fdw_state; EState *estate = node->ss.ps.state; - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; + ResultRelInfo *resultRelInfo = node->resultRelInfo; TupleTableSlot *slot = node->ss.ss_ScanTupleSlot; TupleTableSlot *resultSlot; @@ -4157,7 +4628,7 @@ get_returning_data(ForeignScanState *node) if (dmstate->rel) resultSlot = slot; else - resultSlot = apply_returning_filter(dmstate, slot, estate); + resultSlot = apply_returning_filter(dmstate, resultRelInfo, slot, estate); } dmstate->next_tuple++; @@ -4246,10 +4717,10 @@ init_returning_filter(PgFdwDirectModifyState *dmstate, */ static TupleTableSlot * apply_returning_filter(PgFdwDirectModifyState *dmstate, + ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate) { - ResultRelInfo *relInfo = estate->es_result_relation_info; TupleDesc resultTupType = RelationGetDescr(dmstate->resultRel); TupleTableSlot *resultSlot; Datum *values; @@ -4261,7 +4732,7 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate, /* * Use the return tuple slot as a place to store the result tuple. */ - resultSlot = ExecGetReturningSlot(estate, relInfo); + resultSlot = ExecGetReturningSlot(estate, resultRelInfo); /* * Extract all the values of the scan tuple. @@ -4456,7 +4927,7 @@ postgresAnalyzeForeignTable(Relation relation, */ table = GetForeignTable(RelationGetRelid(relation)); user = GetUserMapping(relation->rd_rel->relowner, table->serverid); - conn = GetConnection(user, false); + conn = GetConnection(user, false, NULL); /* * Construct command to get page count for relation. @@ -4467,7 +4938,7 @@ postgresAnalyzeForeignTable(Relation relation, /* In what follows, do not risk leaking any PGresults. */ PG_TRY(); { - res = pgfdw_exec_query(conn, sql.data); + res = pgfdw_exec_query(conn, sql.data, NULL); if (PQresultStatus(res) != PGRES_TUPLES_OK) pgfdw_report_error(ERROR, res, conn, false, sql.data); @@ -4542,7 +5013,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel, table = GetForeignTable(RelationGetRelid(relation)); server = GetForeignServer(table->serverid); user = GetUserMapping(relation->rd_rel->relowner, table->serverid); - conn = GetConnection(user, false); + conn = GetConnection(user, false, NULL); /* * Construct cursor that retrieves whole rows from remote. @@ -4559,7 +5030,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel, int fetch_size; ListCell *lc; - res = pgfdw_exec_query(conn, sql.data); + res = pgfdw_exec_query(conn, sql.data, NULL); if (PQresultStatus(res) != PGRES_COMMAND_OK) pgfdw_report_error(ERROR, res, conn, false, sql.data); PQclear(res); @@ -4611,7 +5082,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel, */ /* Fetch some rows */ - res = pgfdw_exec_query(conn, fetch_sql); + res = pgfdw_exec_query(conn, fetch_sql, NULL); /* On error, report the original query, not the FETCH. */ if (PQresultStatus(res) != PGRES_TUPLES_OK) pgfdw_report_error(ERROR, res, conn, false, sql.data); @@ -4630,7 +5101,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel, } /* Close the cursor, just to be tidy. */ - close_cursor(conn, cursor_number); + close_cursor(conn, cursor_number, NULL); } PG_CATCH(); { @@ -4770,7 +5241,7 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) */ server = GetForeignServer(serverOid); mapping = GetUserMapping(GetUserId(), server->serverid); - conn = GetConnection(mapping, false); + conn = GetConnection(mapping, false, NULL); /* Don't attempt to import collation if remote server hasn't got it */ if (PQserverVersion(conn) < 90100) @@ -4786,7 +5257,7 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) appendStringInfoString(&buf, "SELECT 1 FROM pg_catalog.pg_namespace WHERE nspname = "); deparseStringLiteral(&buf, stmt->remote_schema); - res = pgfdw_exec_query(conn, buf.data); + res = pgfdw_exec_query(conn, buf.data, NULL); if (PQresultStatus(res) != PGRES_TUPLES_OK) pgfdw_report_error(ERROR, res, conn, false, buf.data); @@ -4808,9 +5279,11 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) * should save a few cycles to not process excluded tables in the * first place.) * - * Ignore table data for partitions and only include the definitions - * of the root partitioned tables to allow access to the complete - * remote data set locally in the schema imported. + * Import table data for partitions only when they are explicitly + * specified in LIMIT TO clause. Otherwise ignore them and only + * include the definitions of the root partitioned tables to allow + * access to the complete remote data set locally in the schema + * imported. * * Note: because we run the connection with search_path restricted to * pg_catalog, the format_type() and pg_get_expr() outputs will always @@ -4866,7 +5339,8 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) deparseStringLiteral(&buf, stmt->remote_schema); /* Partitions are supported since Postgres 10 */ - if (PQserverVersion(conn) >= 100000) + if (PQserverVersion(conn) >= 100000 && + stmt->list_type != FDW_IMPORT_SCHEMA_LIMIT_TO) appendStringInfoString(&buf, " AND NOT c.relispartition "); /* Apply restrictions for LIMIT TO and EXCEPT */ @@ -4898,7 +5372,7 @@ postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid) appendStringInfoString(&buf, " ORDER BY c.relname, a.attnum"); /* Fetch the data */ - res = pgfdw_exec_query(conn, buf.data); + res = pgfdw_exec_query(conn, buf.data, NULL); if (PQresultStatus(res) != PGRES_TUPLES_OK) pgfdw_report_error(ERROR, res, conn, false, buf.data); @@ -5358,6 +5832,8 @@ apply_server_options(PgFdwRelationInfo *fpinfo) ExtractExtensionList(defGetString(def), false); else if (strcmp(def->defname, "fetch_size") == 0) fpinfo->fetch_size = strtol(defGetString(def), NULL, 10); + else if (strcmp(def->defname, "async_capable") == 0) + fpinfo->async_capable = defGetBoolean(def); } } @@ -5379,6 +5855,8 @@ apply_table_options(PgFdwRelationInfo *fpinfo) fpinfo->use_remote_estimate = defGetBoolean(def); else if (strcmp(def->defname, "fetch_size") == 0) fpinfo->fetch_size = strtol(defGetString(def), NULL, 10); + else if (strcmp(def->defname, "async_capable") == 0) + fpinfo->async_capable = defGetBoolean(def); } } @@ -5413,6 +5891,7 @@ merge_fdw_options(PgFdwRelationInfo *fpinfo, fpinfo->shippable_extensions = fpinfo_o->shippable_extensions; fpinfo->use_remote_estimate = fpinfo_o->use_remote_estimate; fpinfo->fetch_size = fpinfo_o->fetch_size; + fpinfo->async_capable = fpinfo_o->async_capable; /* Merge the table level options from either side of the join. */ if (fpinfo_i) @@ -5434,6 +5913,16 @@ merge_fdw_options(PgFdwRelationInfo *fpinfo, * relation sizes. */ fpinfo->fetch_size = Max(fpinfo_o->fetch_size, fpinfo_i->fetch_size); + + /* + * We'll prefer to consider this join async-capable if any table from + * either side of the join is considered async-capable. This would be + * reasonable because in that case the foreign server would have its + * own resources to scan that table asynchronously, and the join could + * also be computed asynchronously using the resources. + */ + fpinfo->async_capable = fpinfo_o->async_capable || + fpinfo_i->async_capable; } } @@ -5733,7 +6222,8 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, * RestrictInfos, so we must make our own. */ Assert(!IsA(expr, RestrictInfo)); - rinfo = make_restrictinfo(expr, + rinfo = make_restrictinfo(root, + expr, true, false, false, @@ -6319,6 +6809,244 @@ add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel, add_path(final_rel, (Path *) final_path); } +/* + * postgresIsForeignPathAsyncCapable + * Check whether a given ForeignPath node is async-capable. + */ +static bool +postgresIsForeignPathAsyncCapable(ForeignPath *path) +{ + RelOptInfo *rel = ((Path *) path)->parent; + PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private; + + return fpinfo->async_capable; +} + +/* + * postgresForeignAsyncRequest + * Asynchronously request next tuple from a foreign PostgreSQL table. + */ +static void +postgresForeignAsyncRequest(AsyncRequest *areq) +{ + produce_tuple_asynchronously(areq, true); +} + +/* + * postgresForeignAsyncConfigureWait + * Configure a file descriptor event for which we wish to wait. + */ +static void +postgresForeignAsyncConfigureWait(AsyncRequest *areq) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state; + AsyncRequest *pendingAreq = fsstate->conn_state->pendingAreq; + AppendState *requestor = (AppendState *) areq->requestor; + WaitEventSet *set = requestor->as_eventset; + + /* This should not be called unless callback_pending */ + Assert(areq->callback_pending); + + /* The core code would have registered postmaster death event */ + Assert(GetNumRegisteredWaitEvents(set) >= 1); + + /* Begin an asynchronous data fetch if not already done */ + if (!pendingAreq) + fetch_more_data_begin(areq); + else if (pendingAreq->requestor != areq->requestor) + { + /* + * This is the case when the in-process request was made by another + * Append. Note that it might be useless to process the request, + * because the query might not need tuples from that Append anymore. + * Skip the given request if there are any configured events other + * than the postmaster death event; otherwise process the request, + * then begin a fetch to configure the event below, because otherwise + * we might end up with no configured events other than the postmaster + * death event. + */ + if (GetNumRegisteredWaitEvents(set) > 1) + return; + process_pending_request(pendingAreq); + fetch_more_data_begin(areq); + } + else if (pendingAreq->requestee != areq->requestee) + { + /* + * This is the case when the in-process request was made by the same + * parent but for a different child. Since we configure only the + * event for the request made for that child, skip the given request. + */ + return; + } + else + Assert(pendingAreq == areq); + + AddWaitEventToSet(set, WL_SOCKET_READABLE, PQsocket(fsstate->conn), + NULL, areq); +} + +/* + * postgresForeignAsyncNotify + * Fetch some more tuples from a file descriptor that becomes ready, + * requesting next tuple. + */ +static void +postgresForeignAsyncNotify(AsyncRequest *areq) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state; + + /* The request should be currently in-process */ + Assert(fsstate->conn_state->pendingAreq == areq); + + /* The core code would have initialized the callback_pending flag */ + Assert(!areq->callback_pending); + + /* On error, report the original query, not the FETCH. */ + if (!PQconsumeInput(fsstate->conn)) + pgfdw_report_error(ERROR, NULL, fsstate->conn, false, fsstate->query); + + fetch_more_data(node); + + produce_tuple_asynchronously(areq, true); +} + +/* + * Asynchronously produce next tuple from a foreign PostgreSQL table. + */ +static void +produce_tuple_asynchronously(AsyncRequest *areq, bool fetch) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state; + AsyncRequest *pendingAreq = fsstate->conn_state->pendingAreq; + TupleTableSlot *result; + + /* This should not be called if the request is currently in-process */ + Assert(areq != pendingAreq); + + /* Fetch some more tuples, if we've run out */ + if (fsstate->next_tuple >= fsstate->num_tuples) + { + /* No point in another fetch if we already detected EOF, though */ + if (!fsstate->eof_reached) + { + /* Mark the request as pending for a callback */ + ExecAsyncRequestPending(areq); + /* Begin another fetch if requested and if no pending request */ + if (fetch && !pendingAreq) + fetch_more_data_begin(areq); + } + else + { + /* There's nothing more to do; just return a NULL pointer */ + result = NULL; + /* Mark the request as complete */ + ExecAsyncRequestDone(areq, result); + } + return; + } + + /* Get a tuple from the ForeignScan node */ + result = areq->requestee->ExecProcNodeReal(areq->requestee); + if (!TupIsNull(result)) + { + /* Mark the request as complete */ + ExecAsyncRequestDone(areq, result); + return; + } + Assert(fsstate->next_tuple >= fsstate->num_tuples); + + /* Fetch some more tuples, if we've not detected EOF yet */ + if (!fsstate->eof_reached) + { + /* Mark the request as pending for a callback */ + ExecAsyncRequestPending(areq); + /* Begin another fetch if requested and if no pending request */ + if (fetch && !pendingAreq) + fetch_more_data_begin(areq); + } + else + { + /* There's nothing more to do; just return a NULL pointer */ + result = NULL; + /* Mark the request as complete */ + ExecAsyncRequestDone(areq, result); + } +} + +/* + * Begin an asynchronous data fetch. + * + * Note: this function assumes there is no currently-in-progress asynchronous + * data fetch. + * + * Note: fetch_more_data must be called to fetch the result. + */ +static void +fetch_more_data_begin(AsyncRequest *areq) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + PgFdwScanState *fsstate = (PgFdwScanState *) node->fdw_state; + char sql[64]; + + Assert(!fsstate->conn_state->pendingAreq); + + /* Create the cursor synchronously. */ + if (!fsstate->cursor_exists) + create_cursor(node); + + /* We will send this query, but not wait for the response. */ + snprintf(sql, sizeof(sql), "FETCH %d FROM c%u", + fsstate->fetch_size, fsstate->cursor_number); + + if (PQsendQuery(fsstate->conn, sql) < 0) + pgfdw_report_error(ERROR, NULL, fsstate->conn, false, fsstate->query); + + /* Remember that the request is in process */ + fsstate->conn_state->pendingAreq = areq; +} + +/* + * Process a pending asynchronous request. + */ +void +process_pending_request(AsyncRequest *areq) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + PgFdwScanState *fsstate PG_USED_FOR_ASSERTS_ONLY = (PgFdwScanState *) node->fdw_state; + EState *estate = node->ss.ps.state; + MemoryContext oldcontext; + + /* The request should be currently in-process */ + Assert(fsstate->conn_state->pendingAreq == areq); + + oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + + /* The request would have been pending for a callback */ + Assert(areq->callback_pending); + + /* Unlike AsyncNotify, we unset callback_pending ourselves */ + areq->callback_pending = false; + + fetch_more_data(node); + + /* We need to send a new query afterwards; don't fetch */ + produce_tuple_asynchronously(areq, false); + + /* Unlike AsyncNotify, we call ExecAsyncResponse ourselves */ + ExecAsyncResponse(areq); + + /* Also, we do instrumentation ourselves, if required */ + if (areq->requestee->instrument) + InstrUpdateTupleCount(areq->requestee->instrument, + TupIsNull(areq->result) ? 0.0 : 1.0); + + MemoryContextSwitchTo(oldcontext); +} + /* * Create a tuple from the specified row of the PGresult. * @@ -6627,4 +7355,44 @@ greenplumCheckIsGreenplum(UserMapping *user) ReleaseConnection(conn); return ret; +/* + * Determine batch size for a given foreign table. The option specified for + * a table has precedence. + */ +static int +get_batch_size_option(Relation rel) +{ + Oid foreigntableid = RelationGetRelid(rel); + ForeignTable *table; + ForeignServer *server; + List *options; + ListCell *lc; + + /* we use 1 by default, which means "no batching" */ + int batch_size = 1; + + /* + * Load options for table and server. We append server options after table + * options, because table options take precedence. + */ + table = GetForeignTable(foreigntableid); + server = GetForeignServer(table->serverid); + + options = NIL; + options = list_concat(options, table->options); + options = list_concat(options, server->options); + + /* See if either table or server specifies batch_size. */ + foreach(lc, options) + { + DefElem *def = (DefElem *) lfirst(lc); + + if (strcmp(def->defname, "batch_size") == 0) + { + batch_size = strtol(defGetString(def), NULL, 10); + break; + } + } + + return batch_size; } diff --git a/contrib/postgres_fdw/postgres_fdw.control b/contrib/postgres_fdw/postgres_fdw.control index f9ed490752b0..d489382064cf 100644 --- a/contrib/postgres_fdw/postgres_fdw.control +++ b/contrib/postgres_fdw/postgres_fdw.control @@ -1,5 +1,5 @@ # postgres_fdw extension comment = 'foreign-data wrapper for remote PostgreSQL servers' -default_version = '1.0' +default_version = '1.1' module_pathname = '$libdir/postgres_fdw' relocatable = true diff --git a/contrib/postgres_fdw/postgres_fdw.h b/contrib/postgres_fdw/postgres_fdw.h index eef410db3921..9591c0f6c26d 100644 --- a/contrib/postgres_fdw/postgres_fdw.h +++ b/contrib/postgres_fdw/postgres_fdw.h @@ -3,7 +3,7 @@ * postgres_fdw.h * Foreign-data wrapper for remote PostgreSQL servers * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/postgres_fdw.h @@ -16,6 +16,7 @@ #include "foreign/foreign.h" #include "lib/stringinfo.h" #include "libpq-fe.h" +#include "nodes/execnodes.h" #include "nodes/pathnodes.h" #include "utils/relcache.h" @@ -77,7 +78,8 @@ typedef struct PgFdwRelationInfo bool use_remote_estimate; Cost fdw_startup_cost; Cost fdw_tuple_cost; - List *shippable_extensions; /* OIDs of whitelisted extensions */ + List *shippable_extensions; /* OIDs of shippable extensions */ + bool async_capable; /* Cached catalog information. */ ForeignTable *table; @@ -124,17 +126,29 @@ typedef struct PgFdwRelationInfo int relation_index; } PgFdwRelationInfo; +/* + * Extra control information relating to a connection. + */ +typedef struct PgFdwConnState +{ + AsyncRequest *pendingAreq; /* pending async request */ +} PgFdwConnState; + /* in postgres_fdw.c */ extern int set_transmission_modes(void); extern void reset_transmission_modes(int nestlevel); +extern void process_pending_request(AsyncRequest *areq); /* in connection.c */ -extern PGconn *GetConnection(UserMapping *user, bool will_prep_stmt); +extern PGconn *GetConnection(UserMapping *user, bool will_prep_stmt, + PgFdwConnState **state); extern void ReleaseConnection(PGconn *conn); extern unsigned int GetCursorNumber(PGconn *conn); extern unsigned int GetPrepStmtNumber(PGconn *conn); +extern void do_sql_command(PGconn *conn, const char *sql); extern PGresult *pgfdw_get_result(PGconn *conn, const char *query); -extern PGresult *pgfdw_exec_query(PGconn *conn, const char *query); +extern PGresult *pgfdw_exec_query(PGconn *conn, const char *query, + PgFdwConnState *state); extern void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn, bool clear, const char *sql); @@ -161,7 +175,10 @@ extern void deparseInsertSql(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, List *targetAttrs, bool doNothing, List *withCheckOptionList, List *returningList, - List **retrieved_attrs); + List **retrieved_attrs, int *values_end_len); +extern void rebuildInsertSql(StringInfo buf, char *orig_query, + int values_end_len, int num_cols, + int num_rows); extern void deparseUpdateSql(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, List *targetAttrs, @@ -190,6 +207,10 @@ extern void deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root, extern void deparseAnalyzeSizeSql(StringInfo buf, Relation rel); extern void deparseAnalyzeSql(StringInfo buf, Relation rel, List **retrieved_attrs); +extern void deparseTruncateSql(StringInfo buf, + List *rels, + DropBehavior behavior, + bool restart_seqs); extern void deparseStringLiteral(StringInfo buf, const char *val); extern Expr *find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel); extern Expr *find_em_expr_for_input_target(PlannerInfo *root, diff --git a/contrib/postgres_fdw/shippable.c b/contrib/postgres_fdw/shippable.c index 3433c1971233..b27f82e01559 100644 --- a/contrib/postgres_fdw/shippable.c +++ b/contrib/postgres_fdw/shippable.c @@ -7,13 +7,13 @@ * data types are shippable to a remote server for execution --- that is, * do they exist and have the same behavior remotely as they do locally? * Built-in objects are generally considered shippable. Other objects can - * be shipped if they are white-listed by the user. + * be shipped if they are declared as such by the user. * * Note: there are additional filter rules that prevent shipping mutable * functions or functions using nonportable collations. Those considerations * need not be accounted for here. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/shippable.c @@ -93,7 +93,6 @@ InitializeShippableCache(void) HASHCTL ctl; /* Create the hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(ShippableCacheKey); ctl.entrysize = sizeof(ShippableCacheEntry); ShippableCacheHash = @@ -111,7 +110,7 @@ InitializeShippableCache(void) * * Right now "shippability" is exclusively a function of whether the object * belongs to an extension declared by the user. In the future we could - * additionally have a whitelist of functions/operators declared one at a time. + * additionally have a list of functions/operators declared one at a time. */ static bool lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo) diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index d452d063430a..286dd99573eb 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -15,6 +15,10 @@ DO $d$ OPTIONS (dbname '$$||current_database()||$$', port '$$||current_setting('port')||$$' )$$; + EXECUTE $$CREATE SERVER loopback3 FOREIGN DATA WRAPPER postgres_fdw + OPTIONS (dbname '$$||current_database()||$$', + port '$$||current_setting('port')||$$' + )$$; END; $d$; @@ -22,6 +26,7 @@ CREATE USER MAPPING FOR public SERVER testserver1 OPTIONS (user 'value', password 'value'); CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; CREATE USER MAPPING FOR CURRENT_USER SERVER loopback2; +CREATE USER MAPPING FOR public SERVER loopback3; -- =================================================================== -- create objects used through FDW loopback server @@ -142,6 +147,12 @@ CREATE FOREIGN TABLE ft6 ( c3 text ) SERVER loopback2 OPTIONS (schema_name 'S 1', table_name 'T 4'); +CREATE FOREIGN TABLE ft7 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER loopback3 OPTIONS (schema_name 'S 1', table_name 'T 4'); + -- =================================================================== -- tests for validator -- =================================================================== @@ -298,6 +309,18 @@ SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 RESET enable_hashjoin; RESET enable_nestloop; +-- Test executing assertion in estimate_path_cost_size() that makes sure that +-- retrieved_rows for foreign rel re-used to cost pre-sorted foreign paths is +-- a sensible value even when the rel has tuples=0 +CREATE TABLE loct_empty (c1 int NOT NULL, c2 text); +CREATE FOREIGN TABLE ft_empty (c1 int NOT NULL, c2 text) + SERVER loopback OPTIONS (table_name 'loct_empty'); +INSERT INTO loct_empty + SELECT id, 'AAA' || to_char(id, 'FM000') FROM generate_series(1, 100) id; +DELETE FROM loct_empty; +ANALYZE ft_empty; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1; + -- =================================================================== -- WHERE with remotely-executable conditions -- =================================================================== @@ -307,7 +330,6 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- Nu EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l) -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r) EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- SubscriptingRef @@ -480,10 +502,12 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; +SET enable_resultcache TO off; -- right outer join + left outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; +RESET enable_resultcache; -- left outer join + right outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; @@ -1231,6 +1255,14 @@ UPDATE ft2 AS target SET (c2) = ( WHERE target.c1 = src.c1 ) WHERE c1 > 1100; +-- Test UPDATE involving a join that can be pushed down, +-- but a SET clause that can't be +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END + FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; +UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END + FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; + -- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing -- user-defined operators/functions ALTER SERVER loopback OPTIONS (DROP extensions); @@ -1867,6 +1899,27 @@ explain (verbose, costs off) select * from bar where f1 in (select f1 from foo) for share; select * from bar where f1 in (select f1 from foo) for share; +-- Now check SELECT FOR UPDATE/SHARE with an inherited source table, +-- where the parent is itself a foreign table +create table loct4 (f1 int, f2 int, f3 int); +create foreign table foo2child (f3 int) inherits (foo2) + server loopback options (table_name 'loct4'); + +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo2) for share; +select * from bar where f1 in (select f1 from foo2) for share; + +drop foreign table foo2child; + +-- And with a local child relation of the foreign table parent +create table foo2child (f3 int) inherits (foo2); + +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo2) for share; +select * from bar where f1 in (select f1 from foo2) for share; + +drop table foo2child; + -- Check UPDATE with inherited target and an inherited source table explain (verbose, costs off) update bar set f2 = f2 + 100 where f1 in (select f1 from foo); @@ -2327,6 +2380,113 @@ select * from rem3; drop foreign table rem3; drop table loc3; +-- =================================================================== +-- test for TRUNCATE +-- =================================================================== +CREATE TABLE tru_rtable0 (id int primary key); +CREATE FOREIGN TABLE tru_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable0'); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(1,10) x); + +CREATE TABLE tru_ptable (id int) PARTITION BY HASH(id); +CREATE TABLE tru_ptable__p0 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE tru_rtable1 (id int primary key); +CREATE FOREIGN TABLE tru_ftable__p1 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback OPTIONS (table_name 'tru_rtable1'); +INSERT INTO tru_ptable (SELECT x FROM generate_series(11,20) x); + +CREATE TABLE tru_pk_table(id int primary key); +CREATE TABLE tru_fk_table(fkey int references tru_pk_table(id)); +INSERT INTO tru_pk_table (SELECT x FROM generate_series(1,10) x); +INSERT INTO tru_fk_table (SELECT x % 10 + 1 FROM generate_series(5,25) x); +CREATE FOREIGN TABLE tru_pk_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_pk_table'); + +CREATE TABLE tru_rtable_parent (id int); +CREATE TABLE tru_rtable_child (id int); +CREATE FOREIGN TABLE tru_ftable_parent (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable_parent'); +CREATE FOREIGN TABLE tru_ftable_child () INHERITS (tru_ftable_parent) + SERVER loopback OPTIONS (table_name 'tru_rtable_child'); +INSERT INTO tru_rtable_parent (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_rtable_child (SELECT x FROM generate_series(10, 18) x); + +-- normal truncate +SELECT sum(id) FROM tru_ftable; -- 55 +TRUNCATE tru_ftable; +SELECT count(*) FROM tru_rtable0; -- 0 +SELECT count(*) FROM tru_ftable; -- 0 + +-- 'truncatable' option +ALTER SERVER loopback OPTIONS (ADD truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (ADD truncatable 'true'); +TRUNCATE tru_ftable; -- accepted +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER SERVER loopback OPTIONS (DROP truncatable); +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'true'); +TRUNCATE tru_ftable; -- accepted + +-- partitioned table with both local and foreign tables as partitions +SELECT sum(id) FROM tru_ptable; -- 155 +TRUNCATE tru_ptable; +SELECT count(*) FROM tru_ptable; -- 0 +SELECT count(*) FROM tru_ptable__p0; -- 0 +SELECT count(*) FROM tru_ftable__p1; -- 0 +SELECT count(*) FROM tru_rtable1; -- 0 + +-- 'CASCADE' option +SELECT sum(id) FROM tru_pk_ftable; -- 55 +TRUNCATE tru_pk_ftable; -- failed by FK reference +TRUNCATE tru_pk_ftable CASCADE; +SELECT count(*) FROM tru_pk_ftable; -- 0 +SELECT count(*) FROM tru_fk_table; -- also truncated,0 + +-- truncate two tables at a command +INSERT INTO tru_ftable (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_pk_ftable (SELECT x FROM generate_series(3,10) x); +SELECT count(*) from tru_ftable; -- 8 +SELECT count(*) from tru_pk_ftable; -- 8 +TRUNCATE tru_ftable, tru_pk_ftable CASCADE; +SELECT count(*) from tru_ftable; -- 0 +SELECT count(*) from tru_pk_ftable; -- 0 + +-- truncate with ONLY clause +-- Since ONLY is specified, the table tru_ftable_child that inherits +-- tru_ftable_parent locally is not truncated. +TRUNCATE ONLY tru_ftable_parent; +SELECT sum(id) FROM tru_ftable_parent; -- 126 +TRUNCATE tru_ftable_parent; +SELECT count(*) FROM tru_ftable_parent; -- 0 + +-- in case when remote table has inherited children +CREATE TABLE tru_rtable0_child () INHERITS (tru_rtable0); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(5,9) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(10,14) x); +SELECT sum(id) FROM tru_ftable; -- 95 + +-- Both parent and child tables in the foreign server are truncated +-- even though ONLY is specified because ONLY has no effect +-- when truncating a foreign table. +TRUNCATE ONLY tru_ftable; +SELECT count(*) FROM tru_ftable; -- 0 + +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(21,25) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(26,30) x); +SELECT sum(id) FROM tru_ftable; -- 255 +TRUNCATE tru_ftable; -- truncate both of parent and child +SELECT count(*) FROM tru_ftable; -- 0 + +-- cleanup +DROP FOREIGN TABLE tru_ftable_parent, tru_ftable_child, tru_pk_ftable,tru_ftable__p1,tru_ftable; +DROP TABLE tru_rtable0, tru_rtable1, tru_ptable, tru_ptable__p0, tru_pk_table, tru_fk_table, +tru_rtable_parent,tru_rtable_child, tru_rtable0_child; + -- =================================================================== -- test IMPORT FOREIGN SCHEMA -- =================================================================== @@ -2342,6 +2502,8 @@ ALTER TABLE import_source."x 5" DROP COLUMN c1; CREATE TABLE import_source.t4 (c1 int) PARTITION BY RANGE (c1); CREATE TABLE import_source.t4_part PARTITION OF import_source.t4 FOR VALUES FROM (1) TO (100); +CREATE TABLE import_source.t4_part2 PARTITION OF import_source.t4 + FOR VALUES FROM (100) TO (200); CREATE SCHEMA import_dest1; IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; @@ -2362,10 +2524,10 @@ IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest3 -- Check LIMIT TO and EXCEPT CREATE SCHEMA import_dest4; -IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch) +IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch, t4_part) FROM SERVER loopback INTO import_dest4; \det+ import_dest4.* -IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch) +IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch, t4_part) FROM SERVER loopback INTO import_dest4; \det+ import_dest4.* @@ -2516,8 +2678,8 @@ INSERT INTO pagg_tab_p3 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM gene -- Create foreign partitions CREATE FOREIGN TABLE fpagg_tab_p1 PARTITION OF pagg_tab FOR VALUES FROM (0) TO (10) SERVER loopback OPTIONS (table_name 'pagg_tab_p1'); -CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2');; -CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3');; +CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2'); +CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3'); ANALYZE pagg_tab; ANALYZE fpagg_tab_p1; @@ -2584,7 +2746,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c8 user_enum ) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- If we add a password to the connstr it'll fail, because we don't allow passwords -- in connstrs only in user mappings. @@ -2602,13 +2764,13 @@ $d$; ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- Unpriv user cannot make the mapping passwordless ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; RESET ROLE; @@ -2618,7 +2780,7 @@ ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD passwor SET ROLE regress_nosuper; -- Should finally work now -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- unpriv user also cannot set sslcert / sslkey on the user mapping -- first set password_required so we see the right error messages @@ -2632,13 +2794,13 @@ DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; -- This will fail again as it'll resolve the user mapping for public, which -- lacks password_required=false -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; RESET ROLE; -- The user mapping for public is passwordless and lacks the password_required=false -- mapping option, but will work because the current user is a superuser. -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- cleanup DROP USER MAPPING FOR public SERVER loopback_nopw; @@ -2654,3 +2816,524 @@ SELECT count(*) FROM ft1; -- error here PREPARE TRANSACTION 'fdw_tpc'; ROLLBACK; + +-- =================================================================== +-- reestablish new connection +-- =================================================================== + +-- Change application_name of remote connection to special one +-- so that we can easily terminate the connection later. +ALTER SERVER loopback OPTIONS (application_name 'fdw_retry_check'); + +-- If debug_invalidate_system_caches_always is active, it results in +-- dropping remote connections after every transaction, making it +-- impossible to test termination meaningfully. So turn that off +-- for this test. +SET debug_invalidate_system_caches_always = 0; + +-- Make sure we have a remote connection. +SELECT 1 FROM ft1 LIMIT 1; + +-- Terminate the remote connection and wait for the termination to complete. +SELECT pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; + +-- This query should detect the broken connection when starting new remote +-- transaction, reestablish new connection, and then succeed. +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; + +-- If we detect the broken connection when starting a new remote +-- subtransaction, we should fail instead of establishing a new connection. +-- Terminate the remote connection and wait for the termination to complete. +SELECT pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +SAVEPOINT s; +-- The text of the error might vary across platforms, so only show SQLSTATE. +\set VERBOSITY sqlstate +SELECT 1 FROM ft1 LIMIT 1; -- should fail +\set VERBOSITY default +COMMIT; + +RESET debug_invalidate_system_caches_always; + +-- ============================================================================= +-- test connection invalidation cases and postgres_fdw_get_connections function +-- ============================================================================= +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- This test case is for closing the connection in pgfdw_xact_callback +BEGIN; +-- Connection xact depth becomes 1 i.e. the connection is in midst of the xact. +SELECT 1 FROM ft1 LIMIT 1; +SELECT 1 FROM ft7 LIMIT 1; +-- List all the existing cached connections. loopback and loopback3 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Connections are not closed at the end of the alter and drop statements. +-- That's because the connections are in midst of this xact, +-- they are just marked as invalid in pgfdw_inval_callback. +ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); +DROP SERVER loopback3 CASCADE; +-- List all the existing cached connections. loopback and loopback3 +-- should be output as invalid connections. Also the server name for +-- loopback3 should be NULL because the server was dropped. +SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; +-- The invalid connections get closed in pgfdw_xact_callback during commit. +COMMIT; +-- All cached connections were closed while committing above xact, so no +-- records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ======================================================================= +-- test postgres_fdw_disconnect and postgres_fdw_disconnect_all functions +-- ======================================================================= +BEGIN; +-- Ensure to cache loopback connection. +SELECT 1 FROM ft1 LIMIT 1; +-- Ensure to cache loopback2 connection. +SELECT 1 FROM ft6 LIMIT 1; +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Issue a warning and return false as loopback connection is still in use and +-- can not be closed. +SELECT postgres_fdw_disconnect('loopback'); +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Return false as connections are still in use, warnings are issued. +-- But disable warnings temporarily because the order of them is not stable. +SET client_min_messages = 'ERROR'; +SELECT postgres_fdw_disconnect_all(); +RESET client_min_messages; +COMMIT; +-- Ensure that loopback2 connection is closed. +SELECT 1 FROM postgres_fdw_disconnect('loopback2'); +SELECT server_name FROM postgres_fdw_get_connections() WHERE server_name = 'loopback2'; +-- Return false as loopback2 connection is closed already. +SELECT postgres_fdw_disconnect('loopback2'); +-- Return an error as there is no foreign server with given name. +SELECT postgres_fdw_disconnect('unknownserver'); +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ============================================================================= +-- test case for having multiple cached connections for a foreign server +-- ============================================================================= +CREATE ROLE regress_multi_conn_user1 SUPERUSER; +CREATE ROLE regress_multi_conn_user2 SUPERUSER; +CREATE USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +CREATE USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; + +BEGIN; +-- Will cache loopback connection with user mapping for regress_multi_conn_user1 +SET ROLE regress_multi_conn_user1; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Will cache loopback connection with user mapping for regress_multi_conn_user2 +SET ROLE regress_multi_conn_user2; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Should output two connections for loopback server +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +COMMIT; +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- Clean up +DROP USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +DROP USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; +DROP ROLE regress_multi_conn_user1; +DROP ROLE regress_multi_conn_user2; + +-- =================================================================== +-- Test foreign server level option keep_connections +-- =================================================================== +-- By default, the connections associated with foreign server are cached i.e. +-- keep_connections option is on. Set it to off. +ALTER SERVER loopback OPTIONS (keep_connections 'off'); +-- connection to loopback server is closed at the end of xact +-- as keep_connections was set to off. +SELECT 1 FROM ft1 LIMIT 1; +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +ALTER SERVER loopback OPTIONS (SET keep_connections 'on'); + +-- =================================================================== +-- batch insert +-- =================================================================== + +BEGIN; + +CREATE SERVER batch10 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( batch_size '10' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + +ALTER SERVER batch10 OPTIONS( SET batch_size '20' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=20']; + +CREATE FOREIGN TABLE table30 ( x int ) SERVER batch10 OPTIONS ( batch_size '30' ); + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + +ALTER FOREIGN TABLE table30 OPTIONS ( SET batch_size '40'); + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=40']; + +ROLLBACK; + +CREATE TABLE batch_table ( x int ); + +CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '10' ); +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; +INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; +INSERT INTO ftable SELECT * FROM generate_series(11, 31) i; +INSERT INTO ftable VALUES (32); +INSERT INTO ftable VALUES (33), (34); +SELECT COUNT(*) FROM ftable; +TRUNCATE batch_table; +DROP FOREIGN TABLE ftable; + +-- try if large batches exceed max number of bind parameters +CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '100000' ); +INSERT INTO ftable SELECT * FROM generate_series(1, 70000) i; +SELECT COUNT(*) FROM ftable; +TRUNCATE batch_table; +DROP FOREIGN TABLE ftable; + +-- Disable batch insert +CREATE FOREIGN TABLE ftable ( x int ) SERVER loopback OPTIONS ( table_name 'batch_table', batch_size '1' ); +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable VALUES (1), (2); +INSERT INTO ftable VALUES (1), (2); +SELECT COUNT(*) FROM ftable; +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; + +-- Use partitioning +CREATE TABLE batch_table ( x int ) PARTITION BY HASH (x); + +CREATE TABLE batch_table_p0 (LIKE batch_table); +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 0) + SERVER loopback + OPTIONS (table_name 'batch_table_p0', batch_size '10'); + +CREATE TABLE batch_table_p1 (LIKE batch_table); +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 1) + SERVER loopback + OPTIONS (table_name 'batch_table_p1', batch_size '1'); + +CREATE TABLE batch_table_p2 + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +INSERT INTO batch_table SELECT * FROM generate_series(1, 66) i; +SELECT COUNT(*) FROM batch_table; + +-- Check that enabling batched inserts doesn't interfere with cross-partition +-- updates +CREATE TABLE batch_cp_upd_test (a int) PARTITION BY LIST (a); +CREATE TABLE batch_cp_upd_test1 (LIKE batch_cp_upd_test); +CREATE FOREIGN TABLE batch_cp_upd_test1_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (1) + SERVER loopback + OPTIONS (table_name 'batch_cp_upd_test1', batch_size '10'); +CREATE TABLE batch_cp_up_test1 PARTITION OF batch_cp_upd_test + FOR VALUES IN (2); +INSERT INTO batch_cp_upd_test VALUES (1), (2); + +-- The following moves a row from the local partition to the foreign one +UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a; +SELECT tableoid::regclass, * FROM batch_cp_upd_test; + +-- Clean up +DROP TABLE batch_table, batch_cp_upd_test, batch_table_p0, batch_table_p1 CASCADE; + +-- Use partitioning +ALTER SERVER loopback OPTIONS (ADD batch_size '10'); + +CREATE TABLE batch_table ( x int, field1 text, field2 text) PARTITION BY HASH (x); + +CREATE TABLE batch_table_p0 (LIKE batch_table); +ALTER TABLE batch_table_p0 ADD CONSTRAINT p0_pkey PRIMARY KEY (x); +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 0) + SERVER loopback + OPTIONS (table_name 'batch_table_p0'); + +CREATE TABLE batch_table_p1 (LIKE batch_table); +ALTER TABLE batch_table_p1 ADD CONSTRAINT p1_pkey PRIMARY KEY (x); +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback + OPTIONS (table_name 'batch_table_p1'); + +INSERT INTO batch_table SELECT i, 'test'||i, 'test'|| i FROM generate_series(1, 50) i; +SELECT COUNT(*) FROM batch_table; +SELECT * FROM batch_table ORDER BY x; + +ALTER SERVER loopback OPTIONS (DROP batch_size); + +-- =================================================================== +-- test asynchronous execution +-- =================================================================== + +ALTER SERVER loopback OPTIONS (DROP extensions); +ALTER SERVER loopback OPTIONS (ADD async_capable 'true'); +ALTER SERVER loopback2 OPTIONS (ADD async_capable 'true'); + +CREATE TABLE async_pt (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE base_tbl1 (a int, b int, c text); +CREATE TABLE base_tbl2 (a int, b int, c text); +CREATE FOREIGN TABLE async_p1 PARTITION OF async_pt FOR VALUES FROM (1000) TO (2000) + SERVER loopback OPTIONS (table_name 'base_tbl1'); +CREATE FOREIGN TABLE async_p2 PARTITION OF async_pt FOR VALUES FROM (2000) TO (3000) + SERVER loopback2 OPTIONS (table_name 'base_tbl2'); +INSERT INTO async_p1 SELECT 1000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +INSERT INTO async_p2 SELECT 2000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +-- simple queries +CREATE TABLE result_tbl (a int, b int, c text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Check case where multiple partitions use the same connection +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000) + SERVER loopback2 OPTIONS (table_name 'base_tbl3'); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +DROP FOREIGN TABLE async_p3; +DROP TABLE base_tbl3; + +-- Check case where the partitioned table has local/remote partitions +CREATE TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- partitionwise joins +SET enable_partitionwise_join TO true; + +CREATE TABLE join_tbl (a1 int, b1 int, c1 text, a2 int, b2 int, c2 text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_partitionwise_join; + +-- Test rescan of an async Append node with do_exec_prune=false +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_hashjoin; + +-- Test interaction of async execution with plan-time partition pruning +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 3000; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 2000; + +-- Test interaction of async execution with run-time partition pruning +SET plan_cache_mode TO force_generic_plan; + +PREPARE async_pt_query (int, int) AS + INSERT INTO result_tbl SELECT * FROM async_pt WHERE a < $1 AND b === $2; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (3000, 505); +EXECUTE async_pt_query (3000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (2000, 505); +EXECUTE async_pt_query (2000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +RESET plan_cache_mode; + +CREATE TABLE local_tbl(a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'), (2505, 505, 'bar'); +ANALYZE local_tbl; + +CREATE INDEX base_tbl1_idx ON base_tbl1 (a); +CREATE INDEX base_tbl2_idx ON base_tbl2 (a); +CREATE INDEX async_p3_idx ON async_p3 (a); +ANALYZE base_tbl1; +ANALYZE base_tbl2; +ANALYZE async_p3; + +ALTER FOREIGN TABLE async_p1 OPTIONS (use_remote_estimate 'true'); +ALTER FOREIGN TABLE async_p2 OPTIONS (use_remote_estimate 'true'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + +ALTER FOREIGN TABLE async_p1 OPTIONS (DROP use_remote_estimate); +ALTER FOREIGN TABLE async_p2 OPTIONS (DROP use_remote_estimate); + +DROP TABLE local_tbl; +DROP INDEX base_tbl1_idx; +DROP INDEX base_tbl2_idx; +DROP INDEX async_p3_idx; + +-- Test that pending requests are processed properly +SET enable_mergejoin TO false; +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + +-- Check with foreign modify +CREATE TABLE local_tbl (a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'); + +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE remote_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl3'); +INSERT INTO remote_tbl VALUES (2505, 505, 'bar'); + +CREATE TABLE base_tbl4 (a int, b int, c text); +CREATE FOREIGN TABLE insert_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl4'); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); + +SELECT * FROM insert_tbl ORDER BY a; + +-- Check with direct modify +EXPLAIN (VERBOSE, COSTS OFF) +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +DROP TABLE local_tbl; +DROP FOREIGN TABLE remote_tbl; +DROP FOREIGN TABLE insert_tbl; +DROP TABLE base_tbl3; +DROP TABLE base_tbl4; + +RESET enable_mergejoin; +RESET enable_hashjoin; + +-- Test that UPDATE/DELETE with inherited target works with async_capable enabled +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM async_pt WHERE b = 0 RETURNING *; +DELETE FROM async_pt WHERE b = 0 RETURNING *; + +-- Check EXPLAIN ANALYZE for a query that scans empty partitions asynchronously +DELETE FROM async_p1; +DELETE FROM async_p2; +DELETE FROM async_p3; + +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt; + +-- Clean up +DROP TABLE async_pt; +DROP TABLE base_tbl1; +DROP TABLE base_tbl2; +DROP TABLE result_tbl; +DROP TABLE join_tbl; + +ALTER SERVER loopback OPTIONS (DROP async_capable); +ALTER SERVER loopback2 OPTIONS (DROP async_capable); diff --git a/contrib/seg/Makefile b/contrib/seg/Makefile index f3578a86340d..bb63e835067f 100644 --- a/contrib/seg/Makefile +++ b/contrib/seg/Makefile @@ -7,7 +7,7 @@ OBJS = \ segparse.o EXTENSION = seg -DATA = seg--1.1.sql seg--1.1--1.2.sql seg--1.2--1.3.sql \ +DATA = seg--1.1.sql seg--1.1--1.2.sql seg--1.2--1.3.sql seg--1.3--1.4.sql \ seg--1.0--1.1.sql PGFILEDESC = "seg - line segment data type" diff --git a/contrib/seg/expected/seg.out b/contrib/seg/expected/seg.out index d7a937434adc..d20b7d60e152 100644 --- a/contrib/seg/expected/seg.out +++ b/contrib/seg/expected/seg.out @@ -931,6 +931,7 @@ CREATE TABLE test_seg (s seg); NOTICE: Table doesn't have 'DISTRIBUTED BY' clause, and no column type is suitable for a distribution key. Creating a NULL policy entry. \copy test_seg from 'data/test_seg.data' CREATE INDEX test_seg_ix ON test_seg USING gist (s); +SET enable_indexscan = false; EXPLAIN (COSTS OFF) SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; QUERY PLAN @@ -948,6 +949,7 @@ SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; 143 (1 row) +RESET enable_indexscan; SET enable_bitmapscan = false; EXPLAIN (COSTS OFF) SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; diff --git a/contrib/seg/seg--1.3--1.4.sql b/contrib/seg/seg--1.3--1.4.sql new file mode 100644 index 000000000000..13babddba4e9 --- /dev/null +++ b/contrib/seg/seg--1.3--1.4.sql @@ -0,0 +1,8 @@ +/* contrib/seg/seg--1.3--1.4.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION seg UPDATE TO '1.4'" to load this file. \quit + +-- Remove @ and ~ +DROP OPERATOR @ (seg, seg); +DROP OPERATOR ~ (seg, seg); diff --git a/contrib/seg/seg-validate.pl b/contrib/seg/seg-validate.pl index 9fa0887e7102..eee27056338b 100755 --- a/contrib/seg/seg-validate.pl +++ b/contrib/seg/seg-validate.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/contrib/seg/seg.control b/contrib/seg/seg.control index 9ac308084813..e2c6a4750fcc 100644 --- a/contrib/seg/seg.control +++ b/contrib/seg/seg.control @@ -1,6 +1,6 @@ # seg extension comment = 'data type for representing line segments or floating-point intervals' -default_version = '1.3' +default_version = '1.4' module_pathname = '$libdir/seg' relocatable = true trusted = true diff --git a/contrib/seg/sort-segments.pl b/contrib/seg/sort-segments.pl index 2e3c9734a94d..ec0d0a569977 100755 --- a/contrib/seg/sort-segments.pl +++ b/contrib/seg/sort-segments.pl @@ -1,5 +1,7 @@ #!/usr/bin/perl +# Copyright (c) 2021, PostgreSQL Global Development Group + # this script will sort any table with the segment data type in its last column use strict; diff --git a/contrib/seg/sql/seg.sql b/contrib/seg/sql/seg.sql index 40181ba35019..eb7c7138f821 100644 --- a/contrib/seg/sql/seg.sql +++ b/contrib/seg/sql/seg.sql @@ -217,9 +217,11 @@ CREATE TABLE test_seg (s seg); CREATE INDEX test_seg_ix ON test_seg USING gist (s); +SET enable_indexscan = false; EXPLAIN (COSTS OFF) SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; +RESET enable_indexscan; SET enable_bitmapscan = false; EXPLAIN (COSTS OFF) diff --git a/contrib/sepgsql/database.c b/contrib/sepgsql/database.c index ec2037859379..14a74fb29503 100644 --- a/contrib/sepgsql/database.c +++ b/contrib/sepgsql/database.c @@ -4,7 +4,7 @@ * * Routines corresponding to database objects * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -15,7 +15,6 @@ #include "access/sysattr.h" #include "access/table.h" #include "catalog/dependency.h" -#include "catalog/indexing.h" #include "catalog/pg_database.h" #include "commands/dbcommands.h" #include "commands/seclabel.h" diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c index 75ee612bcdae..1f96e8b507a4 100644 --- a/contrib/sepgsql/dml.c +++ b/contrib/sepgsql/dml.c @@ -4,7 +4,7 @@ * * Routines to handle DML permission checks * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ diff --git a/contrib/sepgsql/expected/label.out b/contrib/sepgsql/expected/label.out index 0300bc6fb45e..b1b7db55f67a 100644 --- a/contrib/sepgsql/expected/label.out +++ b/contrib/sepgsql/expected/label.out @@ -6,7 +6,7 @@ -- CREATE TABLE t1 (a int, b text); INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); -SELECT * INTO t2 FROM t1 WHERE a % 2 = 0; +CREATE TABLE t2 AS SELECT * FROM t1 WHERE a % 2 = 0; CREATE FUNCTION f1 () RETURNS text AS 'SELECT sepgsql_getcon()' LANGUAGE sql; diff --git a/contrib/sepgsql/expected/misc.out b/contrib/sepgsql/expected/misc.out index b2c01e03dedf..be52b86e00fe 100644 --- a/contrib/sepgsql/expected/misc.out +++ b/contrib/sepgsql/expected/misc.out @@ -84,8 +84,8 @@ LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_reg LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" min | avg -----+--------------------- 1 | 50.5000000000000000 @@ -101,8 +101,8 @@ LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_reg LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" min | avg -----+--------------------- 0 | 49.5000000000000000 @@ -114,8 +114,8 @@ LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_reg LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" min | avg -----+-------------------- 0 | 4.5000000000000000 @@ -127,8 +127,8 @@ LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_reg LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" min | avg -----+--------------------- 10 | 54.5000000000000000 diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c index 853b5b04ab8b..19a3ffb7ffae 100644 --- a/contrib/sepgsql/hooks.c +++ b/contrib/sepgsql/hooks.c @@ -4,7 +4,7 @@ * * Entrypoints of the hooks in PostgreSQL, and dispatches the callbacks. * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -313,6 +313,7 @@ sepgsql_exec_check_perms(List *rangeTabls, bool abort) static void sepgsql_utility_command(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, @@ -378,11 +379,11 @@ sepgsql_utility_command(PlannedStmt *pstmt, } if (next_ProcessUtility_hook) - (*next_ProcessUtility_hook) (pstmt, queryString, + (*next_ProcessUtility_hook) (pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); else - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c index b00b91df5aa3..7f23124009d5 100644 --- a/contrib/sepgsql/label.c +++ b/contrib/sepgsql/label.c @@ -4,7 +4,7 @@ * * Routines to support SELinux labels (security context) * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -18,7 +18,6 @@ #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/dependency.h" -#include "catalog/indexing.h" #include "catalog/pg_attribute.h" #include "catalog/pg_class.h" #include "catalog/pg_database.h" diff --git a/contrib/sepgsql/launcher b/contrib/sepgsql/launcher index 0fddaf59634d..6574eb9ea9e1 100755 --- a/contrib/sepgsql/launcher +++ b/contrib/sepgsql/launcher @@ -2,7 +2,7 @@ # # A wrapper script to launch psql command in regression test # -# Copyright (c) 2010-2020, PostgreSQL Global Development Group +# Copyright (c) 2010-2021, PostgreSQL Global Development Group # # ------------------------------------------------------------------------- diff --git a/contrib/sepgsql/proc.c b/contrib/sepgsql/proc.c index d5d7dbe103ba..e0ff3f03701a 100644 --- a/contrib/sepgsql/proc.c +++ b/contrib/sepgsql/proc.c @@ -4,7 +4,7 @@ * * Routines corresponding to procedure objects * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -15,7 +15,6 @@ #include "access/sysattr.h" #include "access/table.h" #include "catalog/dependency.h" -#include "catalog/indexing.h" #include "catalog/pg_namespace.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c index 96c57854a21a..31e2ed5b1431 100644 --- a/contrib/sepgsql/relation.c +++ b/contrib/sepgsql/relation.c @@ -4,7 +4,7 @@ * * Routines corresponding to relation/attribute objects * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -15,7 +15,6 @@ #include "access/sysattr.h" #include "access/table.h" #include "catalog/dependency.h" -#include "catalog/indexing.h" #include "catalog/pg_attribute.h" #include "catalog/pg_class.h" #include "catalog/pg_namespace.h" diff --git a/contrib/sepgsql/schema.c b/contrib/sepgsql/schema.c index 3b2b80be831e..0285c57114c1 100644 --- a/contrib/sepgsql/schema.c +++ b/contrib/sepgsql/schema.c @@ -4,7 +4,7 @@ * * Routines corresponding to schema objects * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -15,7 +15,6 @@ #include "access/sysattr.h" #include "access/table.h" #include "catalog/dependency.h" -#include "catalog/indexing.h" #include "catalog/pg_database.h" #include "catalog/pg_namespace.h" #include "commands/seclabel.h" diff --git a/contrib/sepgsql/selinux.c b/contrib/sepgsql/selinux.c index 2695e88f23c9..f11968bcaa29 100644 --- a/contrib/sepgsql/selinux.c +++ b/contrib/sepgsql/selinux.c @@ -5,7 +5,7 @@ * Interactions between userspace and selinux in kernelspace, * using libselinux api. * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -892,7 +892,7 @@ sepgsql_compute_create(const char *scontext, * tcontext: security label of the object being referenced * tclass: class code (SEPG_CLASS_*) of the object being referenced * required: a mask of required permissions (SEPG___) - * audit_name: a human readable object name for audit logs, or NULL. + * audit_name: a human-readable object name for audit logs, or NULL. * abort_on_violation: true, if error shall be raised on access violation */ bool diff --git a/contrib/sepgsql/sepgsql.h b/contrib/sepgsql/sepgsql.h index 38302b530b13..219373426730 100644 --- a/contrib/sepgsql/sepgsql.h +++ b/contrib/sepgsql/sepgsql.h @@ -4,7 +4,7 @@ * * Definitions corresponding to SE-PostgreSQL * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ diff --git a/contrib/sepgsql/sql/label.sql b/contrib/sepgsql/sql/label.sql index d19c6edb4ca8..76e261bee803 100644 --- a/contrib/sepgsql/sql/label.sql +++ b/contrib/sepgsql/sql/label.sql @@ -7,7 +7,7 @@ -- CREATE TABLE t1 (a int, b text); INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); -SELECT * INTO t2 FROM t1 WHERE a % 2 = 0; +CREATE TABLE t2 AS SELECT * FROM t1 WHERE a % 2 = 0; CREATE FUNCTION f1 () RETURNS text AS 'SELECT sepgsql_getcon()' diff --git a/contrib/sepgsql/uavc.c b/contrib/sepgsql/uavc.c index 97189b7c46f0..4cc48d5f82eb 100644 --- a/contrib/sepgsql/uavc.c +++ b/contrib/sepgsql/uavc.c @@ -6,7 +6,7 @@ * access control decisions recently used, and reduce number of kernel * invocations to avoid unnecessary performance hit. * - * Copyright (c) 2011-2020, PostgreSQL Global Development Group + * Copyright (c) 2011-2021, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ diff --git a/contrib/sslinfo/expected/sslinfo.out b/contrib/sslinfo/expected/sslinfo.out index ef0dc43a3c74..a2b4f1392503 100644 --- a/contrib/sslinfo/expected/sslinfo.out +++ b/contrib/sslinfo/expected/sslinfo.out @@ -2,6 +2,32 @@ Enable SSL in postgresql.conf with master only... preparing CRTs and KEYs -- start_ignore +\! gpstop -arf +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Starting gpstop with args: -arf +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Gathering information and validating the environment... +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Obtaining Greenplum Coordinator catalog information +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Obtaining Segment details from coordinator... +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Greenplum Version: 'postgres (Greenplum Database) 8.0.0-alpha.0 build dev' +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Commencing Coordinator instance shutdown with mode='fast' +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Coordinator segment instance directory=/home/gpadmin/gpdb_src/gpAux/gpdemo/datadirs/qddir/demoDataDir-1 +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Attempting forceful termination of any leftover coordinator process +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Terminating processes for segment /home/gpadmin/gpdb_src/gpAux/gpdemo/datadirs/qddir/demoDataDir-1 +20260612:00:33:37:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Stopping coordinator standby host 3a76691f25e1 mode=fast +20260612:00:33:38:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Successfully shutdown standby process on 3a76691f25e1 +20260612:00:33:38:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Targeting dbid [2, 5, 3, 6, 4, 7] for shutdown +20260612:00:33:38:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Commencing parallel primary segment instance shutdown, please wait... +20260612:00:33:38:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-0.00% of jobs completed +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-100.00% of jobs completed +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Commencing parallel mirror segment instance shutdown, please wait... +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-0.00% of jobs completed +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-100.00% of jobs completed +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:----------------------------------------------------- +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:- Segments stopped successfully = 6 +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:- Segments with errors during stop = 0 +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:----------------------------------------------------- +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Successfully shutdown 6 of 6 segment instances +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Database successfully shutdown with no errors reported +20260612:00:33:39:3615113 gpstop:3a76691f25e1:gpadmin-[INFO]:-Restarting System... -- end_ignore \! echo "gpstop begin ret = $?" gpstop begin ret = 0 @@ -38,15 +64,15 @@ SELECT ssl_client_serial(); (1 row) SELECT ssl_client_dn(); - ssl_client_dn ------------------------------------------------------------------------------------- - /CN=client.example.com/C=CN/ST=Qingdao/L=ClientLocality/O=SSLINFO-Client/OU=Client + ssl_client_dn +----------------------------------------------------------------- + /CN=client.example.com/C=CN/ST=Qingdao/L=ClientLocality/O=SSLIN (1 row) SELECT ssl_issuer_dn(); - ssl_issuer_dn ---------------------------------------------------------------------------- - /CN=root.example.com/C=CN/ST=Beijing/L=RootLocality/O=SSLINFO-dev/OU=Test + ssl_issuer_dn +----------------------------------------------------------------- + /CN=root.example.com/C=CN/ST=Beijing/L=RootLocality/O=SSLINFO-d (1 row) SELECT ssl_client_dn_field('CN') AS client_dn_CN; @@ -125,6 +151,32 @@ DROP EXTENSION sslinfo; \! bash config.bash clean restore SSL in postgresql.conf with master only -- start_ignore +\! gpstop -arf +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Starting gpstop with args: -arf +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Gathering information and validating the environment... +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Obtaining Greenplum Coordinator catalog information +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Obtaining Segment details from coordinator... +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Greenplum Version: 'postgres (Greenplum Database) 8.0.0-alpha.0 build dev' +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Commencing Coordinator instance shutdown with mode='fast' +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Coordinator segment instance directory=/home/gpadmin/gpdb_src/gpAux/gpdemo/datadirs/qddir/demoDataDir-1 +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Attempting forceful termination of any leftover coordinator process +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Terminating processes for segment /home/gpadmin/gpdb_src/gpAux/gpdemo/datadirs/qddir/demoDataDir-1 +20260612:00:33:47:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Stopping coordinator standby host 3a76691f25e1 mode=fast +20260612:00:33:48:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Successfully shutdown standby process on 3a76691f25e1 +20260612:00:33:48:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Targeting dbid [2, 5, 3, 6, 4, 7] for shutdown +20260612:00:33:48:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Commencing parallel primary segment instance shutdown, please wait... +20260612:00:33:48:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-0.00% of jobs completed +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-100.00% of jobs completed +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Commencing parallel mirror segment instance shutdown, please wait... +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-0.00% of jobs completed +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-100.00% of jobs completed +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:----------------------------------------------------- +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:- Segments stopped successfully = 6 +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:- Segments with errors during stop = 0 +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:----------------------------------------------------- +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Successfully shutdown 6 of 6 segment instances +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Database successfully shutdown with no errors reported +20260612:00:33:49:3615639 gpstop:3a76691f25e1:gpadmin-[INFO]:-Restarting System... -- end_ignore \! echo "gpstop end ret = $?" gpstop end ret = 0 diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c index 5ba3988e2704..30cae0bb985e 100644 --- a/contrib/sslinfo/sslinfo.c +++ b/contrib/sslinfo/sslinfo.c @@ -22,7 +22,6 @@ PG_MODULE_MAGIC; static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName); -static Datum X509_NAME_to_text(X509_NAME *name); static Datum ASN1_STRING_to_text(ASN1_STRING *str); /* @@ -54,9 +53,16 @@ PG_FUNCTION_INFO_V1(ssl_version); Datum ssl_version(PG_FUNCTION_ARGS) { - if (MyProcPort->ssl == NULL) + const char *version; + + if (!MyProcPort->ssl_in_use) + PG_RETURN_NULL(); + + version = be_tls_get_version(MyProcPort); + if (version == NULL) PG_RETURN_NULL(); - PG_RETURN_TEXT_P(cstring_to_text(SSL_get_version(MyProcPort->ssl))); + + PG_RETURN_TEXT_P(cstring_to_text(version)); } @@ -67,9 +73,16 @@ PG_FUNCTION_INFO_V1(ssl_cipher); Datum ssl_cipher(PG_FUNCTION_ARGS) { - if (MyProcPort->ssl == NULL) + const char *cipher; + + if (!MyProcPort->ssl_in_use) + PG_RETURN_NULL(); + + cipher = be_tls_get_cipher(MyProcPort); + if (cipher == NULL) PG_RETURN_NULL(); - PG_RETURN_TEXT_P(cstring_to_text(SSL_get_cipher(MyProcPort->ssl))); + + PG_RETURN_TEXT_P(cstring_to_text(cipher)); } @@ -83,7 +96,7 @@ PG_FUNCTION_INFO_V1(ssl_client_cert_present); Datum ssl_client_cert_present(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL(MyProcPort->peer != NULL); + PG_RETURN_BOOL(MyProcPort->peer_cert_valid); } @@ -99,25 +112,21 @@ PG_FUNCTION_INFO_V1(ssl_client_serial); Datum ssl_client_serial(PG_FUNCTION_ARGS) { + char decimal[NAMEDATALEN]; Datum result; - Port *port = MyProcPort; - X509 *peer = port->peer; - ASN1_INTEGER *serial = NULL; - BIGNUM *b; - char *decimal; - if (!peer) + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) + PG_RETURN_NULL(); + + be_tls_get_peer_serial(MyProcPort, decimal, NAMEDATALEN); + + if (!*decimal) PG_RETURN_NULL(); - serial = X509_get_serialNumber(peer); - b = ASN1_INTEGER_to_BN(serial, NULL); - decimal = BN_bn2dec(b); - BN_free(b); result = DirectFunctionCall3(numeric_in, CStringGetDatum(decimal), ObjectIdGetDatum(0), Int32GetDatum(-1)); - OPENSSL_free(decimal); return result; } @@ -228,7 +237,7 @@ ssl_client_dn_field(PG_FUNCTION_ARGS) text *fieldname = PG_GETARG_TEXT_PP(0); Datum result; - if (!(MyProcPort->peer)) + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) PG_RETURN_NULL(); result = X509_NAME_field_to_text(X509_get_subject_name(MyProcPort->peer), fieldname); @@ -275,76 +284,6 @@ ssl_issuer_field(PG_FUNCTION_ARGS) } -/* - * Equivalent of X509_NAME_oneline that respects encoding - * - * This function converts X509_NAME structure to the text variable - * converting all textual data into current database encoding. - * - * Parameter: X509_NAME *name X509_NAME structure to be converted - * - * Returns: text datum which contains string representation of - * X509_NAME - */ -static Datum -X509_NAME_to_text(X509_NAME *name) -{ - BIO *membuf = BIO_new(BIO_s_mem()); - int i, - nid, - count = X509_NAME_entry_count(name); - X509_NAME_ENTRY *e; - ASN1_STRING *v; - const char *field_name; - size_t size; - char nullterm; - char *sp; - char *dp; - text *result; - - if (membuf == NULL) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("could not create OpenSSL BIO structure"))); - - (void) BIO_set_close(membuf, BIO_CLOSE); - for (i = 0; i < count; i++) - { - e = X509_NAME_get_entry(name, i); - nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e)); - if (nid == NID_undef) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not get NID for ASN1_OBJECT object"))); - v = X509_NAME_ENTRY_get_data(e); - field_name = OBJ_nid2sn(nid); - if (field_name == NULL) - field_name = OBJ_nid2ln(nid); - if (field_name == NULL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid))); - BIO_printf(membuf, "/%s=", field_name); - ASN1_STRING_print_ex(membuf, v, - ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB) - | ASN1_STRFLGS_UTF8_CONVERT)); - } - - /* ensure null termination of the BIO's content */ - nullterm = '\0'; - BIO_write(membuf, &nullterm, 1); - size = BIO_get_mem_data(membuf, &sp); - dp = pg_any_to_server(sp, size - 1, PG_UTF8); - result = cstring_to_text(dp); - if (dp != sp) - pfree(dp); - if (BIO_free(membuf) != 1) - elog(ERROR, "could not free OpenSSL BIO structure"); - - PG_RETURN_TEXT_P(result); -} - - /* * Returns current client certificate subject as one string * @@ -358,9 +297,17 @@ PG_FUNCTION_INFO_V1(ssl_client_dn); Datum ssl_client_dn(PG_FUNCTION_ARGS) { - if (!(MyProcPort->peer)) + char subject[NAMEDATALEN]; + + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) + PG_RETURN_NULL(); + + be_tls_get_peer_subject_name(MyProcPort, subject, NAMEDATALEN); + + if (!*subject) PG_RETURN_NULL(); - return X509_NAME_to_text(X509_get_subject_name(MyProcPort->peer)); + + PG_RETURN_TEXT_P(cstring_to_text(subject)); } @@ -377,9 +324,17 @@ PG_FUNCTION_INFO_V1(ssl_issuer_dn); Datum ssl_issuer_dn(PG_FUNCTION_ARGS) { - if (!(MyProcPort->peer)) + char issuer[NAMEDATALEN]; + + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) PG_RETURN_NULL(); - return X509_NAME_to_text(X509_get_issuer_name(MyProcPort->peer)); + + be_tls_get_peer_issuer_name(MyProcPort, issuer, NAMEDATALEN); + + if (!*issuer) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(cstring_to_text(issuer)); } diff --git a/contrib/tablefunc/expected/tablefunc.out b/contrib/tablefunc/expected/tablefunc.out index fffadc6e1b40..464c210f42fd 100644 --- a/contrib/tablefunc/expected/tablefunc.out +++ b/contrib/tablefunc/expected/tablefunc.out @@ -3,12 +3,15 @@ CREATE EXTENSION tablefunc; -- normal_rand() -- no easy way to do this for regression testing -- -SELECT avg(normal_rand)::int FROM normal_rand(100, 250, 0.2); - avg ------ - 250 +SELECT avg(normal_rand)::int, count(*) FROM normal_rand(100, 250, 0.2); + avg | count +-----+------- + 250 | 100 (1 row) +-- negative number of tuples +SELECT avg(normal_rand)::int, count(*) FROM normal_rand(-1, 250, 0.2); +ERROR: number of rows cannot be negative -- -- crosstab() -- diff --git a/contrib/tablefunc/sql/tablefunc.sql b/contrib/tablefunc/sql/tablefunc.sql index ec375b05c63c..02e8a98c73e0 100644 --- a/contrib/tablefunc/sql/tablefunc.sql +++ b/contrib/tablefunc/sql/tablefunc.sql @@ -4,7 +4,9 @@ CREATE EXTENSION tablefunc; -- normal_rand() -- no easy way to do this for regression testing -- -SELECT avg(normal_rand)::int FROM normal_rand(100, 250, 0.2); +SELECT avg(normal_rand)::int, count(*) FROM normal_rand(100, 250, 0.2); +-- negative number of tuples +SELECT avg(normal_rand)::int, count(*) FROM normal_rand(-1, 250, 0.2); -- -- crosstab() diff --git a/contrib/tablefunc/tablefunc.c b/contrib/tablefunc/tablefunc.c index 3802ae905e8f..779bd4415e6a 100644 --- a/contrib/tablefunc/tablefunc.c +++ b/contrib/tablefunc/tablefunc.c @@ -10,7 +10,7 @@ * And contributors: * Nabil Sayegh * - * Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Copyright (c) 2002-2021, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without a written agreement @@ -49,7 +49,6 @@ static HTAB *load_categories_hash(char *cats_sql, MemoryContext per_query_ctx); static Tuplestorestate *get_crosstab_tuplestore(char *sql, HTAB *crosstab_hash, TupleDesc tupdesc, - MemoryContext per_query_ctx, bool randomAccess); static void validateConnectbyTupleDesc(TupleDesc tupdesc, bool show_branch, bool show_serial); static bool compatCrosstabTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2); @@ -185,6 +184,8 @@ normal_rand(PG_FUNCTION_ARGS) /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) { + int32 num_tuples; + /* create a function context for cross-call persistence */ funcctx = SRF_FIRSTCALL_INIT(); @@ -194,7 +195,12 @@ normal_rand(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* total number of tuples to be returned */ - funcctx->max_calls = PG_GETARG_UINT32(0); + num_tuples = PG_GETARG_INT32(0); + if (num_tuples < 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("number of rows cannot be negative"))); + funcctx->max_calls = num_tuples; /* allocate memory for user context */ fctx = (normal_rand_fctx *) palloc(sizeof(normal_rand_fctx)); @@ -680,7 +686,6 @@ crosstab_hash(PG_FUNCTION_ARGS) rsinfo->setResult = get_crosstab_tuplestore(sql, crosstab_hash, tupdesc, - per_query_ctx, rsinfo->allowedModes & SFRM_Materialize_Random); /* @@ -709,7 +714,6 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx) MemoryContext SPIcontext; /* initialize the category hash table */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = MAX_CATNAME_LEN; ctl.entrysize = sizeof(crosstab_HashEnt); ctl.hcxt = per_query_ctx; @@ -721,7 +725,7 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx) crosstab_hash = hash_create("crosstab hash", INIT_CATS, &ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_STRINGS | HASH_CONTEXT); /* Connect to SPI manager */ if ((ret = SPI_connect()) < 0) @@ -793,7 +797,6 @@ static Tuplestorestate * get_crosstab_tuplestore(char *sql, HTAB *crosstab_hash, TupleDesc tupdesc, - MemoryContext per_query_ctx, bool randomAccess) { Tuplestorestate *tupstore; diff --git a/contrib/tablefunc/tablefunc.h b/contrib/tablefunc/tablefunc.h index 794957ca2191..918518223d26 100644 --- a/contrib/tablefunc/tablefunc.h +++ b/contrib/tablefunc/tablefunc.h @@ -10,7 +10,7 @@ * And contributors: * Nabil Sayegh * - * Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Copyright (c) 2002-2021, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without a written agreement diff --git a/contrib/tcn/tcn.c b/contrib/tcn/tcn.c index 552f107bf6b0..06847024a31b 100644 --- a/contrib/tcn/tcn.c +++ b/contrib/tcn/tcn.c @@ -3,7 +3,7 @@ * tcn.c * triggered change notification support for PostgreSQL * - * Portions Copyright (c) 2011-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2011-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile index ed9a3d6c0ede..9a31e0b87958 100644 --- a/contrib/test_decoding/Makefile +++ b/contrib/test_decoding/Makefile @@ -5,9 +5,10 @@ PGFILEDESC = "test_decoding - example of a logical decoding output plugin" REGRESS = ddl xact rewrite toast permissions decoding_in_xact \ decoding_into_rel binary prepared replorigin time messages \ - spill slot truncate stream + spill slot truncate stream stats twophase twophase_stream ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \ - oldest_xmin snapshot_transfer subxact_without_top + oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \ + twophase_snapshot REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf @@ -16,6 +17,8 @@ ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf # typical installcheck users do not have (e.g. buildfarm clients). NO_INSTALLCHECK = 1 +TAP_TESTS = 1 + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/contrib/test_decoding/expected/concurrent_ddl_dml.out b/contrib/test_decoding/expected/concurrent_ddl_dml.out index 53578c8ed60f..3742a2a2474f 100644 --- a/contrib/test_decoding/expected/concurrent_ddl_dml.out +++ b/contrib/test_decoding/expected/concurrent_ddl_dml.out @@ -2,30 +2,38 @@ Parsed test spec with 2 sessions starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_float s1_insert_tbl2 s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_float: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE float; step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[double precision]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl1_float s1_insert_tbl2 s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl1_float: ALTER TABLE tbl1 ALTER COLUMN val2 TYPE float; @@ -33,42 +41,54 @@ step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s1_commit: COMMIT; step s2_alter_tbl1_float: <... completed> step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_char s1_insert_tbl2 s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_char: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE character varying; step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +---------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[character varying]:'1' -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl1_char s1_insert_tbl2 s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl1_char: ALTER TABLE tbl1 ALTER COLUMN val2 TYPE character varying; @@ -76,21 +96,27 @@ step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s1_commit: COMMIT; step s2_alter_tbl1_char: <... completed> step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s1_insert_tbl2 s2_alter_tbl1_float s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); @@ -98,21 +124,27 @@ step s2_alter_tbl1_float: ALTER TABLE tbl1 ALTER COLUMN val2 TYPE float; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s1_insert_tbl2 s2_alter_tbl1_char s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); @@ -120,21 +152,27 @@ step s2_alter_tbl1_char: ALTER TABLE tbl1 ALTER COLUMN val2 TYPE character varyi step s1_commit: COMMIT; step s2_alter_tbl1_char: <... completed> step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_float s1_insert_tbl2 s2_alter_tbl1_float s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_float: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE float; @@ -143,21 +181,27 @@ step s2_alter_tbl1_float: ALTER TABLE tbl1 ALTER COLUMN val2 TYPE float; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[double precision]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_char s1_insert_tbl2 s2_alter_tbl1_char s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_char: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE character varying; @@ -166,21 +210,27 @@ step s2_alter_tbl1_char: ALTER TABLE tbl1 ALTER COLUMN val2 TYPE character varyi step s1_commit: COMMIT; step s2_alter_tbl1_char: <... completed> step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +---------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[character varying]:'1' -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_char s1_begin s1_insert_tbl1 s2_alter_tbl2_text s1_insert_tbl2 s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_char: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE character varying; step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); @@ -188,21 +238,27 @@ step s2_alter_tbl2_text: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE text; step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 -table public.tbl2: INSERT: val1[integer]:1 val2[text]:'1' -COMMIT -?column? +table public.tbl2: INSERT: val1[integer]:1 val2[text]:'1' +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_char s1_begin s1_insert_tbl1 s2_alter_tbl2_text s1_insert_tbl2 s2_alter_tbl1_char s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_char: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE character varying; step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); @@ -212,21 +268,27 @@ step s2_alter_tbl1_char: ALTER TABLE tbl1 ALTER COLUMN val2 TYPE character varyi step s1_commit: COMMIT; step s2_alter_tbl1_char: <... completed> step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 -table public.tbl2: INSERT: val1[integer]:1 val2[text]:'1' -COMMIT -?column? +table public.tbl2: INSERT: val1[integer]:1 val2[text]:'1' +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_boolean s1_insert_tbl2 s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_boolean: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE boolean; @@ -234,21 +296,27 @@ ERROR: column "val2" cannot be cast automatically to type boolean step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_boolean s1_insert_tbl2 s2_alter_tbl1_boolean s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_boolean: ALTER TABLE tbl2 ALTER COLUMN val2 TYPE boolean; @@ -259,42 +327,54 @@ step s1_commit: COMMIT; step s2_alter_tbl1_boolean: <... completed> ERROR: column "val2" cannot be cast automatically to type boolean step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_add_int s1_insert_tbl2_3col s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_add_int: ALTER TABLE tbl2 ADD COLUMN val3 INTEGER; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +-------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s1_insert_tbl2 s1_commit s1_begin s2_alter_tbl2_add_int s1_insert_tbl2_3col s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); @@ -304,45 +384,57 @@ step s2_alter_tbl2_add_int: ALTER TABLE tbl2 ADD COLUMN val3 INTEGER; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -BEGIN +data +-------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 +COMMIT +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:1 -COMMIT -?column? +COMMIT +(7 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_add_float s1_insert_tbl2_3col s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_add_float: ALTER TABLE tbl2 ADD COLUMN val3 FLOAT; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +----------------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[double precision]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s1_insert_tbl2 s1_commit s1_begin s2_alter_tbl2_add_float s1_insert_tbl2_3col s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); @@ -352,45 +444,57 @@ step s2_alter_tbl2_add_float: ALTER TABLE tbl2 ADD COLUMN val3 FLOAT; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -BEGIN +data +----------------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 +COMMIT +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[double precision]:1 -COMMIT -?column? +COMMIT +(7 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s2_alter_tbl2_add_char s1_insert_tbl2_3col s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s2_alter_tbl2_add_char: ALTER TABLE tbl2 ADD COLUMN val3 character varying; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +-------------------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[character varying]:'1' -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s1_begin s1_insert_tbl1 s1_insert_tbl2 s1_commit s1_begin s2_alter_tbl2_add_char s1_insert_tbl2_3col s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); @@ -400,24 +504,30 @@ step s2_alter_tbl2_add_char: ALTER TABLE tbl2 ADD COLUMN val3 character varying; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -BEGIN +data +-------------------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 +COMMIT +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[character varying]:'1' -COMMIT -?column? +COMMIT +(7 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_int s1_begin s1_insert_tbl2_3col s2_alter_tbl2_drop_3rd_col s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_int: ALTER TABLE tbl2 ADD COLUMN val3 INTEGER; step s1_begin: BEGIN; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); @@ -425,20 +535,26 @@ step s2_alter_tbl2_drop_3rd_col: ALTER TABLE tbl2 DROP COLUMN val3; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +-------------------------------------------------------------------------- +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:1 -COMMIT -?column? +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_int s1_begin s1_insert_tbl2_3col s2_alter_tbl2_drop_3rd_col s1_insert_tbl2 s1_commit s1_insert_tbl2 s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_int: ALTER TABLE tbl2 ADD COLUMN val3 INTEGER; step s1_begin: BEGIN; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); @@ -448,24 +564,30 @@ step s1_commit: COMMIT; step s2_alter_tbl2_drop_3rd_col: <... completed> step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:1 +data +----------------------------------------------------------------------------- +BEGIN +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:null -COMMIT -BEGIN -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +BEGIN +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 +COMMIT +(7 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_int s1_begin s1_insert_tbl2_3col s2_alter_tbl2_drop_3rd_col s1_commit s2_get_changes s2_alter_tbl2_add_text s1_begin s1_insert_tbl2_3col s2_alter_tbl2_3rd_char s1_insert_tbl2_3col s1_commit s2_get_changes s2_alter_tbl2_3rd_int s1_insert_tbl2_3col s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_int: ALTER TABLE tbl2 ADD COLUMN val3 INTEGER; step s1_begin: BEGIN; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); @@ -473,11 +595,13 @@ step s2_alter_tbl2_drop_3rd_col: ALTER TABLE tbl2 DROP COLUMN val3; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +-------------------------------------------------------------------------- +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:1 -COMMIT +COMMIT +(3 rows) + step s2_alter_tbl2_add_text: ALTER TABLE tbl2 ADD COLUMN val3 TEXT; step s1_begin: BEGIN; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); @@ -486,29 +610,37 @@ step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s1_commit: COMMIT; step s2_alter_tbl2_3rd_char: <... completed> step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +------------------------------------------------------------------------- +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' -COMMIT +COMMIT +(4 rows) + step s2_alter_tbl2_3rd_int: ALTER TABLE tbl2 ALTER COLUMN val3 TYPE int USING val3::integer; step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +-------------------------------------------------------------------------- +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[integer]:1 -COMMIT -?column? +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_char s1_begin s1_insert_tbl1 s1_insert_tbl2_3col s2_alter_tbl2_3rd_text s1_insert_tbl2_3col s1_commit s1_insert_tbl2_3col s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_char: ALTER TABLE tbl2 ADD COLUMN val3 character varying; step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); @@ -519,25 +651,31 @@ step s1_commit: COMMIT; step s2_alter_tbl2_3rd_text: <... completed> step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +-------------------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[character varying]:'1' table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[character varying]:'1' -COMMIT -BEGIN -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' -COMMIT -?column? +COMMIT +BEGIN +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' +COMMIT +(8 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_text s1_begin s1_insert_tbl1 s1_insert_tbl2_3col s2_alter_tbl2_3rd_char s1_insert_tbl2_3col s1_commit s1_insert_tbl2_3col s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_text: ALTER TABLE tbl2 ADD COLUMN val3 TEXT; step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); @@ -548,25 +686,31 @@ step s1_commit: COMMIT; step s2_alter_tbl2_3rd_char: <... completed> step s1_insert_tbl2_3col: INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' -COMMIT -BEGIN +data +-------------------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' +COMMIT +BEGIN table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[character varying]:'1' -COMMIT -?column? +COMMIT +(8 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_char s1_begin s1_insert_tbl1 s2_alter_tbl2_3rd_text s1_insert_tbl2_3col s1_commit s2_alter_tbl2_drop_3rd_col s1_insert_tbl2 s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_char: ALTER TABLE tbl2 ADD COLUMN val3 character varying; step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); @@ -576,24 +720,30 @@ step s1_commit: COMMIT; step s2_alter_tbl2_drop_3rd_col: ALTER TABLE tbl2 DROP COLUMN val3; step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[text]:'1' -COMMIT -BEGIN -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +BEGIN +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 +COMMIT +(7 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_text s1_begin s1_insert_tbl1 s2_alter_tbl2_3rd_char s1_insert_tbl2_3col s1_commit s2_alter_tbl2_drop_3rd_col s1_insert_tbl2 s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_text: ALTER TABLE tbl2 ADD COLUMN val3 TEXT; step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); @@ -603,24 +753,30 @@ step s1_commit: COMMIT; step s2_alter_tbl2_drop_3rd_col: ALTER TABLE tbl2 DROP COLUMN val3; step s1_insert_tbl2: INSERT INTO tbl2 (val1, val2) VALUES (1, 1); step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 +data +-------------------------------------------------------------------------------------- +BEGIN +table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 val3[character varying]:'1' -COMMIT -BEGIN -table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +BEGIN +table public.tbl2: INSERT: val1[integer]:1 val2[integer]:1 +COMMIT +(7 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s1_init s2_alter_tbl2_add_char s1_begin s1_insert_tbl1 s2_alter_tbl2_drop_3rd_col s1_insert_tbl1 s1_commit s2_get_changes step s1_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s2_alter_tbl2_add_char: ALTER TABLE tbl2 ADD COLUMN val3 character varying; step s1_begin: BEGIN; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); @@ -628,12 +784,16 @@ step s2_alter_tbl2_drop_3rd_col: ALTER TABLE tbl2 DROP COLUMN val3; step s1_insert_tbl1: INSERT INTO tbl1 (val1, val2) VALUES (1, 1); step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +---------------------------------------------------------- +BEGIN table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 table public.tbl1: INSERT: val1[integer]:1 val2[integer]:1 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop diff --git a/contrib/test_decoding/expected/concurrent_stream.out b/contrib/test_decoding/expected/concurrent_stream.out new file mode 100644 index 000000000000..bf1e1326c619 --- /dev/null +++ b/contrib/test_decoding/expected/concurrent_stream.out @@ -0,0 +1,24 @@ +Parsed test spec with 3 sessions + +starting permutation: s0_begin s0_ddl s1_ddl s1_begin s1_toast_insert s2_ddl s1_commit s1_get_stream_changes +step s0_begin: BEGIN; +step s0_ddl: CREATE TABLE stream_test1(data text); +step s1_ddl: CREATE TABLE stream_test(data text); +step s1_begin: BEGIN; +step s1_toast_insert: INSERT INTO stream_test SELECT large_val(); +step s2_ddl: CREATE TABLE stream_test2(data text); +step s1_commit: COMMIT; +step s1_get_stream_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); +data +---------------------------------------- +opening a streamed block for transaction +streaming change for transaction +closing a streamed block for transaction +committing streamed transaction +(4 rows) + +?column? +-------- +stop +(1 row) + diff --git a/contrib/test_decoding/expected/ddl.out b/contrib/test_decoding/expected/ddl.out index d79cd316b79f..4ff0044c7879 100644 --- a/contrib/test_decoding/expected/ddl.out +++ b/contrib/test_decoding/expected/ddl.out @@ -565,6 +565,35 @@ UPDATE table_with_unique_not_null SET data = 3 WHERE data = 2; UPDATE table_with_unique_not_null SET id = -id; UPDATE table_with_unique_not_null SET id = -id; DELETE FROM table_with_unique_not_null WHERE data = 3; +-- check tables with dropped indexes used in REPLICA IDENTITY +-- table with primary key +CREATE TABLE table_dropped_index_with_pk (a int PRIMARY KEY, b int, c int); +CREATE UNIQUE INDEX table_dropped_index_with_pk_idx + ON table_dropped_index_with_pk(a); +ALTER TABLE table_dropped_index_with_pk REPLICA IDENTITY + USING INDEX table_dropped_index_with_pk_idx; +DROP INDEX table_dropped_index_with_pk_idx; +INSERT INTO table_dropped_index_with_pk VALUES (1,1,1), (2,2,2), (3,3,3); +UPDATE table_dropped_index_with_pk SET a = 4 WHERE a = 1; +UPDATE table_dropped_index_with_pk SET b = 5 WHERE a = 2; +UPDATE table_dropped_index_with_pk SET b = 6, c = 7 WHERE a = 3; +DELETE FROM table_dropped_index_with_pk WHERE b = 1; +DELETE FROM table_dropped_index_with_pk WHERE a = 3; +DROP TABLE table_dropped_index_with_pk; +-- table without primary key +CREATE TABLE table_dropped_index_no_pk (a int NOT NULL, b int, c int); +CREATE UNIQUE INDEX table_dropped_index_no_pk_idx + ON table_dropped_index_no_pk(a); +ALTER TABLE table_dropped_index_no_pk REPLICA IDENTITY + USING INDEX table_dropped_index_no_pk_idx; +DROP INDEX table_dropped_index_no_pk_idx; +INSERT INTO table_dropped_index_no_pk VALUES (1,1,1), (2,2,2), (3,3,3); +UPDATE table_dropped_index_no_pk SET a = 4 WHERE a = 1; +UPDATE table_dropped_index_no_pk SET b = 5 WHERE a = 2; +UPDATE table_dropped_index_no_pk SET b = 6, c = 7 WHERE a = 3; +DELETE FROM table_dropped_index_no_pk WHERE b = 1; +DELETE FROM table_dropped_index_no_pk WHERE a = 3; +DROP TABLE table_dropped_index_no_pk; -- check toast support BEGIN; CREATE SEQUENCE toasttable_rand_seq START 79 INCREMENT 1499; -- portable "random" @@ -682,6 +711,46 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc table public.table_with_unique_not_null: DELETE: id[integer]:4 COMMIT BEGIN + table public.table_dropped_index_with_pk: INSERT: a[integer]:1 b[integer]:1 c[integer]:1 + table public.table_dropped_index_with_pk: INSERT: a[integer]:2 b[integer]:2 c[integer]:2 + table public.table_dropped_index_with_pk: INSERT: a[integer]:3 b[integer]:3 c[integer]:3 + COMMIT + BEGIN + table public.table_dropped_index_with_pk: UPDATE: a[integer]:4 b[integer]:1 c[integer]:1 + COMMIT + BEGIN + table public.table_dropped_index_with_pk: UPDATE: a[integer]:2 b[integer]:5 c[integer]:2 + COMMIT + BEGIN + table public.table_dropped_index_with_pk: UPDATE: a[integer]:3 b[integer]:6 c[integer]:7 + COMMIT + BEGIN + table public.table_dropped_index_with_pk: DELETE: (no-tuple-data) + COMMIT + BEGIN + table public.table_dropped_index_with_pk: DELETE: (no-tuple-data) + COMMIT + BEGIN + table public.table_dropped_index_no_pk: INSERT: a[integer]:1 b[integer]:1 c[integer]:1 + table public.table_dropped_index_no_pk: INSERT: a[integer]:2 b[integer]:2 c[integer]:2 + table public.table_dropped_index_no_pk: INSERT: a[integer]:3 b[integer]:3 c[integer]:3 + COMMIT + BEGIN + table public.table_dropped_index_no_pk: UPDATE: a[integer]:4 b[integer]:1 c[integer]:1 + COMMIT + BEGIN + table public.table_dropped_index_no_pk: UPDATE: a[integer]:2 b[integer]:5 c[integer]:2 + COMMIT + BEGIN + table public.table_dropped_index_no_pk: UPDATE: a[integer]:3 b[integer]:6 c[integer]:7 + COMMIT + BEGIN + table public.table_dropped_index_no_pk: DELETE: (no-tuple-data) + COMMIT + BEGIN + table public.table_dropped_index_no_pk: DELETE: (no-tuple-data) + COMMIT + BEGIN table public.toasttable: INSERT: id[integer]:1 toasted_col1[text]:'12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000' rand1[double precision]:79 toasted_col2[text]:null rand2[double precision]:1578 COMMIT BEGIN @@ -690,7 +759,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc BEGIN table public.toasttable: UPDATE: id[integer]:1 toasted_col1[text]:'12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000' rand1[double precision]:79 toasted_col2[text]:null rand2[double precision]:1578 COMMIT -(103 rows) +(143 rows) INSERT INTO toasttable(toasted_col1) SELECT string_agg(g.i::text, '') FROM generate_series(1, 2000) g(i); -- update of second column, first column unchanged diff --git a/contrib/test_decoding/expected/delayed_startup.out b/contrib/test_decoding/expected/delayed_startup.out index db8c525ac408..d10de3658acc 100644 --- a/contrib/test_decoding/expected/delayed_startup.out +++ b/contrib/test_decoding/expected/delayed_startup.out @@ -6,33 +6,45 @@ step s1w: INSERT INTO do_write DEFAULT VALUES; step s2init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); step s1c: COMMIT; step s2init: <... completed> -?column? +?column? +-------- +init +(1 row) -init step s2start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data +data +---- +(0 rows) step s1b: BEGIN ISOLATION LEVEL SERIALIZABLE; step s1w: INSERT INTO do_write DEFAULT VALUES; step s1c: COMMIT; step s2start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data - -BEGIN +data +-------------------------------------------- +BEGIN table public.do_write: INSERT: id[integer]:2 -COMMIT +COMMIT +(3 rows) + step s1b: BEGIN ISOLATION LEVEL SERIALIZABLE; step s1w: INSERT INTO do_write DEFAULT VALUES; step s2start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data +data +---- +(0 rows) step s1c: COMMIT; step s2start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data - -BEGIN +data +-------------------------------------------- +BEGIN table public.do_write: INSERT: id[integer]:3 -COMMIT -?column? +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) -stop diff --git a/contrib/test_decoding/expected/mxact.out b/contrib/test_decoding/expected/mxact.out index f0d96cc67d0b..03ad3df09996 100644 --- a/contrib/test_decoding/expected/mxact.out +++ b/contrib/test_decoding/expected/mxact.out @@ -2,65 +2,89 @@ Parsed test spec with 3 sessions starting permutation: s0init s0start s1begin s1sharepgclass s2begin s2sharepgclass s0w s0start s2commit s1commit step s0init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data +data +---- +(0 rows) step s1begin: BEGIN; step s1sharepgclass: SELECT count(*) > 1 FROM (SELECT * FROM pg_class FOR SHARE) s; -?column? +?column? +-------- +t +(1 row) -t step s2begin: BEGIN; step s2sharepgclass: SELECT count(*) > 1 FROM (SELECT * FROM pg_class FOR SHARE) s; -?column? +?column? +-------- +t +(1 row) -t step s0w: INSERT INTO do_write DEFAULT VALUES; step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data - -BEGIN +data +-------------------------------------------- +BEGIN table public.do_write: INSERT: id[integer]:1 -COMMIT +COMMIT +(3 rows) + step s2commit: COMMIT; step s1commit: COMMIT; -?column? +?column? +-------- +stop +(1 row) -stop starting permutation: s0init s0start s1begin s1keysharepgclass s2begin s2keysharepgclass s0alter s0w s0start s2commit s1commit step s0init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -?column? +?column? +-------- +init +(1 row) -init step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data +data +---- +(0 rows) step s1begin: BEGIN; step s1keysharepgclass: SELECT count(*) > 1 FROM (SELECT * FROM pg_class FOR KEY SHARE) s; -?column? +?column? +-------- +t +(1 row) -t step s2begin: BEGIN; step s2keysharepgclass: SELECT count(*) > 1 FROM (SELECT * FROM pg_class FOR KEY SHARE) s; -?column? +?column? +-------- +t +(1 row) -t step s0alter: ALTER TABLE do_write ADD column ts timestamptz; step s0w: INSERT INTO do_write DEFAULT VALUES; step s0start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data - -BEGIN -COMMIT -BEGIN +data +------------------------------------------------------------------------------ +BEGIN +COMMIT +BEGIN table public.do_write: INSERT: id[integer]:1 ts[timestamp with time zone]:null -COMMIT +COMMIT +(5 rows) + step s2commit: COMMIT; step s1commit: COMMIT; -?column? +?column? +-------- +stop +(1 row) -stop diff --git a/contrib/test_decoding/expected/oldest_xmin.out b/contrib/test_decoding/expected/oldest_xmin.out index 02a091398fc1..dd6053f9c1f4 100644 --- a/contrib/test_decoding/expected/oldest_xmin.out +++ b/contrib/test_decoding/expected/oldest_xmin.out @@ -3,28 +3,38 @@ Parsed test spec with 2 sessions starting permutation: s0_begin s0_getxid s1_begin s1_insert s0_alter s0_commit s0_checkpoint s0_get_changes s0_get_changes s1_commit s0_vacuum s0_get_changes step s0_begin: BEGIN; step s0_getxid: SELECT pg_current_xact_id() IS NULL; -?column? +?column? +-------- +f +(1 row) -f step s1_begin: BEGIN; step s1_insert: INSERT INTO harvest VALUES ((1, 2, 3)); step s0_alter: ALTER TYPE basket DROP ATTRIBUTE mangos; step s0_commit: COMMIT; step s0_checkpoint: CHECKPOINT; step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data +data +---- +(0 rows) step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data +data +---- +(0 rows) step s1_commit: COMMIT; step s0_vacuum: VACUUM pg_attribute; step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +------------------------------------------------------ +BEGIN table public.harvest: INSERT: fruits[basket]:'(1,2,3)' -COMMIT -?column? +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) -stop diff --git a/contrib/test_decoding/expected/ondisk_startup.out b/contrib/test_decoding/expected/ondisk_startup.out index 586b03d75dbb..bc7ff0716487 100644 --- a/contrib/test_decoding/expected/ondisk_startup.out +++ b/contrib/test_decoding/expected/ondisk_startup.out @@ -3,50 +3,64 @@ Parsed test spec with 3 sessions starting permutation: s2b s2txid s1init s3b s3txid s2alter s2c s2b s2txid s3c s2c s1insert s1checkpoint s1start s1insert s1alter s1insert s1start step s2b: BEGIN; step s2txid: SELECT pg_current_xact_id() IS NULL; -?column? +?column? +-------- +f +(1 row) -f step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); step s3b: BEGIN; step s3txid: SELECT pg_current_xact_id() IS NULL; -?column? +?column? +-------- +f +(1 row) -f step s2alter: ALTER TABLE do_write ADD COLUMN addedbys2 int; step s2c: COMMIT; step s2b: BEGIN; step s2txid: SELECT pg_current_xact_id() IS NULL; -?column? +?column? +-------- +f +(1 row) -f step s3c: COMMIT; step s1init: <... completed> -?column? +?column? +-------- +init +(1 row) -init step s2c: COMMIT; step s1insert: INSERT INTO do_write DEFAULT VALUES; step s1checkpoint: CHECKPOINT; step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data - -BEGIN +data +-------------------------------------------------------------------- +BEGIN table public.do_write: INSERT: id[integer]:1 addedbys2[integer]:null -COMMIT +COMMIT +(3 rows) + step s1insert: INSERT INTO do_write DEFAULT VALUES; step s1alter: ALTER TABLE do_write ADD COLUMN addedbys1 int; step s1insert: INSERT INTO do_write DEFAULT VALUES; step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false'); -data - -BEGIN -table public.do_write: INSERT: id[integer]:2 addedbys2[integer]:null -COMMIT -BEGIN -COMMIT -BEGIN +data +-------------------------------------------------------------------------------------------- +BEGIN +table public.do_write: INSERT: id[integer]:2 addedbys2[integer]:null +COMMIT +BEGIN +COMMIT +BEGIN table public.do_write: INSERT: id[integer]:3 addedbys2[integer]:null addedbys1[integer]:null -COMMIT -?column? +COMMIT +(8 rows) + +?column? +-------- +stop +(1 row) -stop diff --git a/contrib/test_decoding/expected/slot.out b/contrib/test_decoding/expected/slot.out index ea72bf9f1573..75b4b5cc6257 100644 --- a/contrib/test_decoding/expected/slot.out +++ b/contrib/test_decoding/expected/slot.out @@ -144,7 +144,7 @@ SELECT pg_replication_slot_advance('regression_slot3', '0/0'); -- invalid LSN ERROR: invalid target WAL LSN SELECT pg_replication_slot_advance('regression_slot3', '0/1'); -- error ERROR: replication slot "regression_slot3" cannot be advanced -DETAIL: This slot has never previously reserved WAL, or has been invalidated. +DETAIL: This slot has never previously reserved WAL, or it has been invalidated. SELECT pg_drop_replication_slot('regression_slot3'); pg_drop_replication_slot -------------------------- diff --git a/contrib/test_decoding/expected/snapshot_transfer.out b/contrib/test_decoding/expected/snapshot_transfer.out index c3a00009946b..833f47874cbc 100644 --- a/contrib/test_decoding/expected/snapshot_transfer.out +++ b/contrib/test_decoding/expected/snapshot_transfer.out @@ -4,32 +4,40 @@ starting permutation: s0_begin s0_begin_sub0 s0_log_assignment s0_sub_get_base_s step s0_begin: BEGIN; step s0_begin_sub0: SAVEPOINT s0; step s0_log_assignment: SELECT pg_current_xact_id() IS NULL; -?column? +?column? +-------- +f +(1 row) -f step s0_sub_get_base_snap: INSERT INTO dummy VALUES (0); step s1_produce_new_snap: ALTER TABLE harvest ADD COLUMN mangos int; step s0_insert: INSERT INTO harvest VALUES (1, 2, 3); step s0_end_sub0: RELEASE SAVEPOINT s0; step s0_commit: COMMIT; step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.dummy: INSERT: i[integer]:0 +data +---------------------------------------------------------------------------------- +BEGIN +table public.dummy: INSERT: i[integer]:0 table public.harvest: INSERT: apples[integer]:1 pears[integer]:2 mangos[integer]:3 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop starting permutation: s0_begin s0_begin_sub0 s0_log_assignment s0_begin_sub1 s0_sub_get_base_snap s1_produce_new_snap s0_insert s0_end_sub1 s0_end_sub0 s0_commit s0_get_changes step s0_begin: BEGIN; step s0_begin_sub0: SAVEPOINT s0; step s0_log_assignment: SELECT pg_current_xact_id() IS NULL; -?column? +?column? +-------- +f +(1 row) -f step s0_begin_sub1: SAVEPOINT s1; step s0_sub_get_base_snap: INSERT INTO dummy VALUES (0); step s1_produce_new_snap: ALTER TABLE harvest ADD COLUMN mangos int; @@ -38,12 +46,16 @@ step s0_end_sub1: RELEASE SAVEPOINT s1; step s0_end_sub0: RELEASE SAVEPOINT s0; step s0_commit: COMMIT; step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN -table public.dummy: INSERT: i[integer]:0 +data +---------------------------------------------------------------------------------- +BEGIN +table public.dummy: INSERT: i[integer]:0 table public.harvest: INSERT: apples[integer]:1 pears[integer]:2 mangos[integer]:3 -COMMIT -?column? +COMMIT +(4 rows) + +?column? +-------- +stop +(1 row) -stop diff --git a/contrib/test_decoding/expected/stats.out b/contrib/test_decoding/expected/stats.out new file mode 100644 index 000000000000..206c0a126e55 --- /dev/null +++ b/contrib/test_decoding/expected/stats.out @@ -0,0 +1,143 @@ +-- predictability +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_stats', 'test_decoding'); + ?column? +---------- + init +(1 row) + +CREATE TABLE stats_test(data text); +-- function to wait for counters to advance +CREATE FUNCTION wait_for_decode_stats(check_reset bool, check_spill_txns bool) RETURNS void AS $$ +DECLARE + start_time timestamptz := clock_timestamp(); + updated bool; +BEGIN + -- we don't want to wait forever; loop will exit after 30 seconds + FOR i IN 1 .. 300 LOOP + + IF check_spill_txns THEN + + -- check to see if all updates have been reset/updated + SELECT CASE WHEN check_reset THEN (spill_txns = 0) + ELSE (spill_txns > 0) + END + INTO updated + FROM pg_stat_replication_slots WHERE slot_name='regression_slot_stats'; + + ELSE + + -- check to see if all updates have been reset/updated + SELECT CASE WHEN check_reset THEN (total_txns = 0) + ELSE (total_txns > 0) + END + INTO updated + FROM pg_stat_replication_slots WHERE slot_name='regression_slot_stats'; + + END IF; + + exit WHEN updated; + + -- wait a little + perform pg_sleep_for('100 milliseconds'); + + -- reset stats snapshot so we can test again + perform pg_stat_clear_snapshot(); + + END LOOP; + + -- report time waited in postmaster log (where it won't change test output) + RAISE LOG 'wait_for_decode_stats delayed % seconds', + extract(epoch from clock_timestamp() - start_time); +END +$$ LANGUAGE plpgsql; +-- non-spilled xact +SET logical_decoding_work_mem to '64MB'; +INSERT INTO stats_test values(1); +SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1'); + count +------- + 3 +(1 row) + +SELECT wait_for_decode_stats(false, false); + wait_for_decode_stats +----------------------- + +(1 row) + +SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots; + slot_name | spill_txns | spill_count | total_txns | total_bytes +-----------------------+------------+-------------+------------+------------- + regression_slot_stats | t | t | t | t +(1 row) + +RESET logical_decoding_work_mem; +-- reset the slot stats, and wait for stats collector's total txn to reset +SELECT pg_stat_reset_replication_slot('regression_slot_stats'); + pg_stat_reset_replication_slot +-------------------------------- + +(1 row) + +SELECT wait_for_decode_stats(true, false); + wait_for_decode_stats +----------------------- + +(1 row) + +SELECT slot_name, spill_txns, spill_count, total_txns, total_bytes FROM pg_stat_replication_slots; + slot_name | spill_txns | spill_count | total_txns | total_bytes +-----------------------+------------+-------------+------------+------------- + regression_slot_stats | 0 | 0 | 0 | 0 +(1 row) + +-- spilling the xact +BEGIN; +INSERT INTO stats_test SELECT 'serialize-topbig--1:'||g.i FROM generate_series(1, 5000) g(i); +COMMIT; +SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1'); + count +------- + 5002 +(1 row) + +-- Check stats, wait for the stats collector to update. We can't test the +-- exact stats count as that can vary if any background transaction (say by +-- autovacuum) happens in parallel to the main transaction. +SELECT wait_for_decode_stats(false, true); + wait_for_decode_stats +----------------------- + +(1 row) + +SELECT slot_name, spill_txns > 0 AS spill_txns, spill_count > 0 AS spill_count FROM pg_stat_replication_slots; + slot_name | spill_txns | spill_count +-----------------------+------------+------------- + regression_slot_stats | t | t +(1 row) + +-- Ensure stats can be repeatedly accessed using the same stats snapshot. See +-- https://postgr.es/m/20210317230447.c7uc4g3vbs4wi32i%40alap3.anarazel.de +BEGIN; +SELECT slot_name FROM pg_stat_replication_slots; + slot_name +----------------------- + regression_slot_stats +(1 row) + +SELECT slot_name FROM pg_stat_replication_slots; + slot_name +----------------------- + regression_slot_stats +(1 row) + +COMMIT; +DROP FUNCTION wait_for_decode_stats(bool, bool); +DROP TABLE stats_test; +SELECT pg_drop_replication_slot('regression_slot_stats'); + pg_drop_replication_slot +-------------------------- + +(1 row) + diff --git a/contrib/test_decoding/expected/stream.out b/contrib/test_decoding/expected/stream.out index d7e32f818546..0f21dcb8e0e4 100644 --- a/contrib/test_decoding/expected/stream.out +++ b/contrib/test_decoding/expected/stream.out @@ -29,10 +29,7 @@ COMMIT; SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); data ---------------------------------------------------------- - opening a streamed block for transaction streaming message: transactional: 1 prefix: test, sz: 50 - closing a streamed block for transaction - aborting streamed (sub)transaction opening a streamed block for transaction streaming change for transaction streaming change for transaction @@ -56,7 +53,7 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'incl streaming change for transaction closing a streamed block for transaction committing streamed transaction -(27 rows) +(24 rows) -- streaming test for toast changes ALTER TABLE stream_test ALTER COLUMN data set storage external; @@ -85,6 +82,30 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'incl committing streamed transaction (13 rows) +-- streaming test for toast with multi-insert +\COPY stream_test FROM STDIN +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + data +------------------------------------------ + opening a streamed block for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + closing a streamed block for transaction + opening a streamed block for transaction + streaming change for transaction + closing a streamed block for transaction + committing streamed transaction +(17 rows) + DROP TABLE stream_test; SELECT pg_drop_replication_slot('regression_slot'); pg_drop_replication_slot diff --git a/contrib/test_decoding/expected/subxact_without_top.out b/contrib/test_decoding/expected/subxact_without_top.out index 99ce99882257..4241b0015bd6 100644 --- a/contrib/test_decoding/expected/subxact_without_top.out +++ b/contrib/test_decoding/expected/subxact_without_top.out @@ -15,25 +15,35 @@ step s2_checkpoint: CHECKPOINT; step s1_begin: BEGIN; step s1_dml: INSERT INTO harvest VALUES (43); step s0_many_subxacts: select subxacts(); -subxacts +subxacts +-------- + +(1 row) - step s0_commit: COMMIT; step s2_checkpoint: CHECKPOINT; step s2_get_changes_suppress_output: SELECT null n FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1') GROUP BY n; -n +n +- + +(1 row) - step s2_get_changes_suppress_output: SELECT null n FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1') GROUP BY n; -n +n +- +(0 rows) step s1_commit: COMMIT; step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -data - -BEGIN +data +------------------------------------------------ +BEGIN table public.harvest: INSERT: apples[integer]:43 -COMMIT -?column? +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) -stop diff --git a/contrib/test_decoding/expected/twophase.out b/contrib/test_decoding/expected/twophase.out new file mode 100644 index 000000000000..e5e0f9689617 --- /dev/null +++ b/contrib/test_decoding/expected/twophase.out @@ -0,0 +1,220 @@ +-- Test prepared transactions. When two-phase-commit is enabled, transactions are +-- decoded at PREPARE time rather than at COMMIT PREPARED time. +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true); + ?column? +---------- + init +(1 row) + +CREATE TABLE test_prepared1(id integer primary key); +CREATE TABLE test_prepared2(id integer primary key); +-- Test that decoding happens at PREPARE time when two-phase-commit is enabled. +-- Decoding after COMMIT PREPARED must have all the commands in the transaction. +BEGIN; +INSERT INTO test_prepared1 VALUES (1); +INSERT INTO test_prepared1 VALUES (2); +-- should show nothing because the xact has not been prepared yet. +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------ +(0 rows) + +PREPARE TRANSACTION 'test_prepared#1'; +-- should show both the above inserts and the PREPARE TRANSACTION. +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +---------------------------------------------------- + BEGIN + table public.test_prepared1: INSERT: id[integer]:1 + table public.test_prepared1: INSERT: id[integer]:2 + PREPARE TRANSACTION 'test_prepared#1' +(4 rows) + +COMMIT PREPARED 'test_prepared#1'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +----------------------------------- + COMMIT PREPARED 'test_prepared#1' +(1 row) + +-- Test that rollback of a prepared xact is decoded. +BEGIN; +INSERT INTO test_prepared1 VALUES (3); +PREPARE TRANSACTION 'test_prepared#2'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +---------------------------------------------------- + BEGIN + table public.test_prepared1: INSERT: id[integer]:3 + PREPARE TRANSACTION 'test_prepared#2' +(3 rows) + +ROLLBACK PREPARED 'test_prepared#2'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------------------------------------- + ROLLBACK PREPARED 'test_prepared#2' +(1 row) + +-- Test prepare of a xact containing ddl. Leaving xact uncommitted for next test. +BEGIN; +ALTER TABLE test_prepared1 ADD COLUMN data text; +INSERT INTO test_prepared1 VALUES (4, 'frakbar'); +PREPARE TRANSACTION 'test_prepared#3'; +-- confirm that exclusive lock from the ALTER command is held on test_prepared1 table +SELECT 'test_prepared_1' AS relation, locktype, mode +FROM pg_locks +WHERE locktype = 'relation' + AND relation = 'test_prepared1'::regclass; + relation | locktype | mode +-----------------+----------+--------------------- + test_prepared_1 | relation | RowExclusiveLock + test_prepared_1 | relation | AccessExclusiveLock +(2 rows) + +-- The insert should show the newly altered column but not the DDL. +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------------------------------------------------------------------------- + BEGIN + table public.test_prepared1: INSERT: id[integer]:4 data[text]:'frakbar' + PREPARE TRANSACTION 'test_prepared#3' +(3 rows) + +-- Test that we decode correctly while an uncommitted prepared xact +-- with ddl exists. +-- +-- Use a separate table for the concurrent transaction because the lock from +-- the ALTER will stop us inserting into the other one. +-- +INSERT INTO test_prepared2 VALUES (5); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +---------------------------------------------------- + BEGIN + table public.test_prepared2: INSERT: id[integer]:5 + COMMIT +(3 rows) + +COMMIT PREPARED 'test_prepared#3'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +----------------------------------- + COMMIT PREPARED 'test_prepared#3' +(1 row) + +-- make sure stuff still works +INSERT INTO test_prepared1 VALUES (6); +INSERT INTO test_prepared2 VALUES (7); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +-------------------------------------------------------------------- + BEGIN + table public.test_prepared1: INSERT: id[integer]:6 data[text]:null + COMMIT + BEGIN + table public.test_prepared2: INSERT: id[integer]:7 + COMMIT +(6 rows) + +-- Check 'CLUSTER' (as operation that hold exclusive lock) doesn't block +-- logical decoding. +BEGIN; +INSERT INTO test_prepared1 VALUES (8, 'othercol'); +CLUSTER test_prepared1 USING test_prepared1_pkey; +INSERT INTO test_prepared1 VALUES (9, 'othercol2'); +PREPARE TRANSACTION 'test_prepared_lock'; +SELECT 'test_prepared1' AS relation, locktype, mode +FROM pg_locks +WHERE locktype = 'relation' + AND relation = 'test_prepared1'::regclass; + relation | locktype | mode +----------------+----------+--------------------- + test_prepared1 | relation | RowExclusiveLock + test_prepared1 | relation | ShareLock + test_prepared1 | relation | AccessExclusiveLock +(3 rows) + +-- The above CLUSTER command shouldn't cause a timeout on 2pc decoding. +SET statement_timeout = '180s'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +--------------------------------------------------------------------------- + BEGIN + table public.test_prepared1: INSERT: id[integer]:8 data[text]:'othercol' + table public.test_prepared1: INSERT: id[integer]:9 data[text]:'othercol2' + PREPARE TRANSACTION 'test_prepared_lock' +(4 rows) + +RESET statement_timeout; +COMMIT PREPARED 'test_prepared_lock'; +-- consume the commit +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +-------------------------------------- + COMMIT PREPARED 'test_prepared_lock' +(1 row) + +-- Test savepoints and sub-xacts. Creating savepoints will create +-- sub-xacts implicitly. +BEGIN; +CREATE TABLE test_prepared_savepoint (a int); +INSERT INTO test_prepared_savepoint VALUES (1); +SAVEPOINT test_savepoint; +INSERT INTO test_prepared_savepoint VALUES (2); +ROLLBACK TO SAVEPOINT test_savepoint; +PREPARE TRANSACTION 'test_prepared_savepoint'; +-- should show only 1, not 2 +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------------------------------------------------------------ + BEGIN + table public.test_prepared_savepoint: INSERT: a[integer]:1 + PREPARE TRANSACTION 'test_prepared_savepoint' +(3 rows) + +COMMIT PREPARED 'test_prepared_savepoint'; +-- consume the commit +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------------------------------------------- + COMMIT PREPARED 'test_prepared_savepoint' +(1 row) + +-- Test that a GID containing "_nodecode" gets decoded at commit prepared time. +BEGIN; +INSERT INTO test_prepared1 VALUES (20); +PREPARE TRANSACTION 'test_prepared_nodecode'; +-- should show nothing +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------ +(0 rows) + +COMMIT PREPARED 'test_prepared_nodecode'; +-- should be decoded now +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +--------------------------------------------------------------------- + BEGIN + table public.test_prepared1: INSERT: id[integer]:20 data[text]:null + COMMIT +(3 rows) + +-- Test 8: +-- cleanup and make sure results are also empty +DROP TABLE test_prepared1; +DROP TABLE test_prepared2; +-- show results. There should be nothing to show +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------ +(0 rows) + +SELECT pg_drop_replication_slot('regression_slot'); + pg_drop_replication_slot +-------------------------- + +(1 row) + diff --git a/contrib/test_decoding/expected/twophase_snapshot.out b/contrib/test_decoding/expected/twophase_snapshot.out new file mode 100644 index 000000000000..f555ffddf74f --- /dev/null +++ b/contrib/test_decoding/expected/twophase_snapshot.out @@ -0,0 +1,53 @@ +Parsed test spec with 3 sessions + +starting permutation: s2b s2txid s1init s3b s3txid s2c s2b s2insert s2p s3c s1insert s1start s2cp s1start +step s2b: BEGIN; +step s2txid: SELECT pg_current_xact_id() IS NULL; +?column? +-------- +f +(1 row) + +step s1init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true); +step s3b: BEGIN; +step s3txid: SELECT pg_current_xact_id() IS NULL; +?column? +-------- +f +(1 row) + +step s2c: COMMIT; +step s2b: BEGIN; +step s2insert: INSERT INTO do_write DEFAULT VALUES; +step s2p: PREPARE TRANSACTION 'test1'; +step s3c: COMMIT; +step s1init: <... completed> +?column? +-------- +init +(1 row) + +step s1insert: INSERT INTO do_write DEFAULT VALUES; +step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1'); +data +-------------------------------------------- +BEGIN +table public.do_write: INSERT: id[integer]:2 +COMMIT +(3 rows) + +step s2cp: COMMIT PREPARED 'test1'; +step s1start: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1'); +data +-------------------------------------------- +BEGIN +table public.do_write: INSERT: id[integer]:1 +PREPARE TRANSACTION 'test1' +COMMIT PREPARED 'test1' +(4 rows) + +?column? +-------- +stop +(1 row) + diff --git a/contrib/test_decoding/expected/twophase_stream.out b/contrib/test_decoding/expected/twophase_stream.out new file mode 100644 index 000000000000..b08bb0e5730b --- /dev/null +++ b/contrib/test_decoding/expected/twophase_stream.out @@ -0,0 +1,125 @@ +-- Test streaming of two-phase commits +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true); + ?column? +---------- + init +(1 row) + +CREATE TABLE stream_test(data text); +-- consume DDL +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +------ +(0 rows) + +-- streaming test with sub-transaction and PREPARE/COMMIT PREPARED +BEGIN; +SAVEPOINT s1; +SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', repeat('a', 50)); + ?column? +---------- + msg5 +(1 row) + +INSERT INTO stream_test SELECT repeat('a', 2000) || g.i FROM generate_series(1, 35) g(i); +TRUNCATE table stream_test; +ROLLBACK TO s1; +INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i); +PREPARE TRANSACTION 'test1'; +-- should show the inserts after a ROLLBACK +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + data +---------------------------------------------------------- + streaming message: transactional: 1 prefix: test, sz: 50 + opening a streamed block for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + streaming change for transaction + closing a streamed block for transaction + preparing streamed transaction 'test1' +(24 rows) + +COMMIT PREPARED 'test1'; +--should show the COMMIT PREPARED and the other changes in the transaction +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + data +------------------------- + COMMIT PREPARED 'test1' +(1 row) + +-- streaming test with sub-transaction and PREPARE/COMMIT PREPARED but with +-- filtered gid. gids with '_nodecode' will not be decoded at prepare time. +BEGIN; +SAVEPOINT s1; +SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', repeat('a', 50)); + ?column? +---------- + msg5 +(1 row) + +INSERT INTO stream_test SELECT repeat('a', 2000) || g.i FROM generate_series(1, 35) g(i); +TRUNCATE table stream_test; +ROLLBACK to s1; +INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i); +PREPARE TRANSACTION 'test1_nodecode'; +-- should NOT show inserts after a ROLLBACK +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + data +---------------------------------------------------------- + streaming message: transactional: 1 prefix: test, sz: 50 +(1 row) + +COMMIT PREPARED 'test1_nodecode'; +-- should show the inserts but not show a COMMIT PREPARED but a COMMIT +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + data +------------------------------------------------------------- + BEGIN + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa1' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa2' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa3' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa4' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa5' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa6' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa7' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa8' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa9' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa10' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa11' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa12' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa13' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa14' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa15' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa16' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa17' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa18' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa19' + table public.stream_test: INSERT: data[text]:'aaaaaaaaaa20' + COMMIT +(22 rows) + +DROP TABLE stream_test; +SELECT pg_drop_replication_slot('regression_slot'); + pg_drop_replication_slot +-------------------------- + +(1 row) + diff --git a/contrib/test_decoding/specs/concurrent_stream.spec b/contrib/test_decoding/specs/concurrent_stream.spec new file mode 100644 index 000000000000..54218a4b3f65 --- /dev/null +++ b/contrib/test_decoding/specs/concurrent_stream.spec @@ -0,0 +1,43 @@ +# Test decoding of in-progress transaction containing dml and a concurrent +# transaction with ddl operation. The transaction containing ddl operation +# should not get streamed as it doesn't have any changes. + +setup +{ + SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); + + -- consume DDL + SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + CREATE OR REPLACE FUNCTION large_val() RETURNS TEXT LANGUAGE SQL AS 'select array_agg(md5(g::text))::text from generate_series(1, 80000) g'; +} + +teardown +{ + DROP TABLE IF EXISTS stream_test; + DROP TABLE IF EXISTS stream_test1; + SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot'); +} + +session "s0" +setup { SET synchronous_commit=on; } +step "s0_begin" { BEGIN; } +step "s0_ddl" {CREATE TABLE stream_test1(data text);} + +session "s2" +setup { SET synchronous_commit=on; } +step "s2_ddl" {CREATE TABLE stream_test2(data text);} + +# The transaction commit for s1_ddl will add the INTERNAL_SNAPSHOT change to +# the currently running s0_ddl and we want to test that s0_ddl should not get +# streamed when user asked to skip-empty-xacts. Similarly, the +# INTERNAL_SNAPSHOT change added by s2_ddl should not change the results for +# what gets streamed. +session "s1" +setup { SET synchronous_commit=on; } +step "s1_ddl" { CREATE TABLE stream_test(data text); } +step "s1_begin" { BEGIN; } +step "s1_toast_insert" {INSERT INTO stream_test SELECT large_val();} +step "s1_commit" { COMMIT; } +step "s1_get_stream_changes" { SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1');} + +permutation "s0_begin" "s0_ddl" "s1_ddl" "s1_begin" "s1_toast_insert" "s2_ddl" "s1_commit" "s1_get_stream_changes" diff --git a/contrib/test_decoding/specs/oldest_xmin.spec b/contrib/test_decoding/specs/oldest_xmin.spec index da3a8cd512db..88bd30f5ff76 100644 --- a/contrib/test_decoding/specs/oldest_xmin.spec +++ b/contrib/test_decoding/specs/oldest_xmin.spec @@ -39,4 +39,4 @@ step "s1_commit" { COMMIT; } # composite type is a rare form of DDL which allows T1 to see the tuple which # will be removed (xmax set) before T1 commits. That is, interlocking doesn't # forbid modifying catalog after someone read it (and didn't commit yet). -permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes""s1_commit" "s0_vacuum" "s0_get_changes" +permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes" "s1_commit" "s0_vacuum" "s0_get_changes" diff --git a/contrib/test_decoding/specs/twophase_snapshot.spec b/contrib/test_decoding/specs/twophase_snapshot.spec new file mode 100644 index 000000000000..e8d9567fb9a2 --- /dev/null +++ b/contrib/test_decoding/specs/twophase_snapshot.spec @@ -0,0 +1,53 @@ +# Test decoding of two-phase transactions during the build of a consistent snapshot. +setup +{ + DROP TABLE IF EXISTS do_write; + CREATE TABLE do_write(id serial primary key); +} + +teardown +{ + DROP TABLE do_write; + SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot'); +} + + +session "s1" +setup { SET synchronous_commit=on; } + +step "s1init" {SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding', false, true);} +step "s1start" {SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', 'false', 'skip-empty-xacts', '1');} +step "s1insert" { INSERT INTO do_write DEFAULT VALUES; } + +session "s2" +setup { SET synchronous_commit=on; } + +step "s2b" { BEGIN; } +step "s2txid" { SELECT pg_current_xact_id() IS NULL; } +step "s2c" { COMMIT; } +step "s2insert" { INSERT INTO do_write DEFAULT VALUES; } +step "s2p" { PREPARE TRANSACTION 'test1'; } +step "s2cp" { COMMIT PREPARED 'test1'; } + + +session "s3" +setup { SET synchronous_commit=on; } + +step "s3b" { BEGIN; } +step "s3txid" { SELECT pg_current_xact_id() IS NULL; } +step "s3c" { COMMIT; } + +# Force building of a consistent snapshot between a PREPARE and COMMIT PREPARED +# and ensure that the whole transaction is decoded at the time of COMMIT +# PREPARED. +# +# 's1init' step will initialize the replication slot and cause logical decoding +# to wait in initial starting point till the in-progress transaction in s2 is +# committed. 's2c' step will cause logical decoding to go to initial consistent +# point and wait for in-progress transaction s3 to commit. 's3c' step will cause +# logical decoding to find a consistent point while the transaction s2 is +# prepared and not yet committed. This will cause the first s1start to skip +# prepared transaction s2 as that will be before consistent point. The second +# s1start will allow decoding of skipped prepare along with commit prepared done +# as part of s2cp. +permutation "s2b" "s2txid" "s1init" "s3b" "s3txid" "s2c" "s2b" "s2insert" "s2p" "s3c" "s1insert" "s1start" "s2cp" "s1start" diff --git a/contrib/test_decoding/sql/ddl.sql b/contrib/test_decoding/sql/ddl.sql index 2c4823e57805..1b3866d01530 100644 --- a/contrib/test_decoding/sql/ddl.sql +++ b/contrib/test_decoding/sql/ddl.sql @@ -345,6 +345,37 @@ UPDATE table_with_unique_not_null SET id = -id; UPDATE table_with_unique_not_null SET id = -id; DELETE FROM table_with_unique_not_null WHERE data = 3; +-- check tables with dropped indexes used in REPLICA IDENTITY +-- table with primary key +CREATE TABLE table_dropped_index_with_pk (a int PRIMARY KEY, b int, c int); +CREATE UNIQUE INDEX table_dropped_index_with_pk_idx + ON table_dropped_index_with_pk(a); +ALTER TABLE table_dropped_index_with_pk REPLICA IDENTITY + USING INDEX table_dropped_index_with_pk_idx; +DROP INDEX table_dropped_index_with_pk_idx; +INSERT INTO table_dropped_index_with_pk VALUES (1,1,1), (2,2,2), (3,3,3); +UPDATE table_dropped_index_with_pk SET a = 4 WHERE a = 1; +UPDATE table_dropped_index_with_pk SET b = 5 WHERE a = 2; +UPDATE table_dropped_index_with_pk SET b = 6, c = 7 WHERE a = 3; +DELETE FROM table_dropped_index_with_pk WHERE b = 1; +DELETE FROM table_dropped_index_with_pk WHERE a = 3; +DROP TABLE table_dropped_index_with_pk; + +-- table without primary key +CREATE TABLE table_dropped_index_no_pk (a int NOT NULL, b int, c int); +CREATE UNIQUE INDEX table_dropped_index_no_pk_idx + ON table_dropped_index_no_pk(a); +ALTER TABLE table_dropped_index_no_pk REPLICA IDENTITY + USING INDEX table_dropped_index_no_pk_idx; +DROP INDEX table_dropped_index_no_pk_idx; +INSERT INTO table_dropped_index_no_pk VALUES (1,1,1), (2,2,2), (3,3,3); +UPDATE table_dropped_index_no_pk SET a = 4 WHERE a = 1; +UPDATE table_dropped_index_no_pk SET b = 5 WHERE a = 2; +UPDATE table_dropped_index_no_pk SET b = 6, c = 7 WHERE a = 3; +DELETE FROM table_dropped_index_no_pk WHERE b = 1; +DELETE FROM table_dropped_index_no_pk WHERE a = 3; +DROP TABLE table_dropped_index_no_pk; + -- check toast support BEGIN; CREATE SEQUENCE toasttable_rand_seq START 79 INCREMENT 1499; -- portable "random" diff --git a/contrib/test_decoding/sql/stats.sql b/contrib/test_decoding/sql/stats.sql new file mode 100644 index 000000000000..67462ca27f70 --- /dev/null +++ b/contrib/test_decoding/sql/stats.sql @@ -0,0 +1,87 @@ +-- predictability +SET synchronous_commit = on; + +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_stats', 'test_decoding'); + +CREATE TABLE stats_test(data text); + +-- function to wait for counters to advance +CREATE FUNCTION wait_for_decode_stats(check_reset bool, check_spill_txns bool) RETURNS void AS $$ +DECLARE + start_time timestamptz := clock_timestamp(); + updated bool; +BEGIN + -- we don't want to wait forever; loop will exit after 30 seconds + FOR i IN 1 .. 300 LOOP + + IF check_spill_txns THEN + + -- check to see if all updates have been reset/updated + SELECT CASE WHEN check_reset THEN (spill_txns = 0) + ELSE (spill_txns > 0) + END + INTO updated + FROM pg_stat_replication_slots WHERE slot_name='regression_slot_stats'; + + ELSE + + -- check to see if all updates have been reset/updated + SELECT CASE WHEN check_reset THEN (total_txns = 0) + ELSE (total_txns > 0) + END + INTO updated + FROM pg_stat_replication_slots WHERE slot_name='regression_slot_stats'; + + END IF; + + exit WHEN updated; + + -- wait a little + perform pg_sleep_for('100 milliseconds'); + + -- reset stats snapshot so we can test again + perform pg_stat_clear_snapshot(); + + END LOOP; + + -- report time waited in postmaster log (where it won't change test output) + RAISE LOG 'wait_for_decode_stats delayed % seconds', + extract(epoch from clock_timestamp() - start_time); +END +$$ LANGUAGE plpgsql; + +-- non-spilled xact +SET logical_decoding_work_mem to '64MB'; +INSERT INTO stats_test values(1); +SELECT count(*) FROM pg_logical_slot_get_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1'); +SELECT wait_for_decode_stats(false, false); +SELECT slot_name, spill_txns = 0 AS spill_txns, spill_count = 0 AS spill_count, total_txns > 0 AS total_txns, total_bytes > 0 AS total_bytes FROM pg_stat_replication_slots; +RESET logical_decoding_work_mem; + +-- reset the slot stats, and wait for stats collector's total txn to reset +SELECT pg_stat_reset_replication_slot('regression_slot_stats'); +SELECT wait_for_decode_stats(true, false); +SELECT slot_name, spill_txns, spill_count, total_txns, total_bytes FROM pg_stat_replication_slots; + +-- spilling the xact +BEGIN; +INSERT INTO stats_test SELECT 'serialize-topbig--1:'||g.i FROM generate_series(1, 5000) g(i); +COMMIT; +SELECT count(*) FROM pg_logical_slot_peek_changes('regression_slot_stats', NULL, NULL, 'skip-empty-xacts', '1'); + +-- Check stats, wait for the stats collector to update. We can't test the +-- exact stats count as that can vary if any background transaction (say by +-- autovacuum) happens in parallel to the main transaction. +SELECT wait_for_decode_stats(false, true); +SELECT slot_name, spill_txns > 0 AS spill_txns, spill_count > 0 AS spill_count FROM pg_stat_replication_slots; + +-- Ensure stats can be repeatedly accessed using the same stats snapshot. See +-- https://postgr.es/m/20210317230447.c7uc4g3vbs4wi32i%40alap3.anarazel.de +BEGIN; +SELECT slot_name FROM pg_stat_replication_slots; +SELECT slot_name FROM pg_stat_replication_slots; +COMMIT; + +DROP FUNCTION wait_for_decode_stats(bool, bool); +DROP TABLE stats_test; +SELECT pg_drop_replication_slot('regression_slot_stats'); diff --git a/contrib/test_decoding/sql/stream.sql b/contrib/test_decoding/sql/stream.sql index ce86c816d11f..4feec62972a5 100644 --- a/contrib/test_decoding/sql/stream.sql +++ b/contrib/test_decoding/sql/stream.sql @@ -26,5 +26,23 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc INSERT INTO stream_test SELECT repeat('a', 6000) || g.i FROM generate_series(1, 10) g(i); SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); +-- streaming test for toast with multi-insert +\COPY stream_test FROM STDIN +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +toasted-123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +\. + +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + DROP TABLE stream_test; SELECT pg_drop_replication_slot('regression_slot'); diff --git a/contrib/test_decoding/sql/twophase.sql b/contrib/test_decoding/sql/twophase.sql new file mode 100644 index 000000000000..05f18e84948b --- /dev/null +++ b/contrib/test_decoding/sql/twophase.sql @@ -0,0 +1,111 @@ +-- Test prepared transactions. When two-phase-commit is enabled, transactions are +-- decoded at PREPARE time rather than at COMMIT PREPARED time. +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true); + +CREATE TABLE test_prepared1(id integer primary key); +CREATE TABLE test_prepared2(id integer primary key); + +-- Test that decoding happens at PREPARE time when two-phase-commit is enabled. +-- Decoding after COMMIT PREPARED must have all the commands in the transaction. +BEGIN; +INSERT INTO test_prepared1 VALUES (1); +INSERT INTO test_prepared1 VALUES (2); +-- should show nothing because the xact has not been prepared yet. +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +PREPARE TRANSACTION 'test_prepared#1'; +-- should show both the above inserts and the PREPARE TRANSACTION. +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +COMMIT PREPARED 'test_prepared#1'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- Test that rollback of a prepared xact is decoded. +BEGIN; +INSERT INTO test_prepared1 VALUES (3); +PREPARE TRANSACTION 'test_prepared#2'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +ROLLBACK PREPARED 'test_prepared#2'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- Test prepare of a xact containing ddl. Leaving xact uncommitted for next test. +BEGIN; +ALTER TABLE test_prepared1 ADD COLUMN data text; +INSERT INTO test_prepared1 VALUES (4, 'frakbar'); +PREPARE TRANSACTION 'test_prepared#3'; +-- confirm that exclusive lock from the ALTER command is held on test_prepared1 table +SELECT 'test_prepared_1' AS relation, locktype, mode +FROM pg_locks +WHERE locktype = 'relation' + AND relation = 'test_prepared1'::regclass; +-- The insert should show the newly altered column but not the DDL. +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- Test that we decode correctly while an uncommitted prepared xact +-- with ddl exists. +-- +-- Use a separate table for the concurrent transaction because the lock from +-- the ALTER will stop us inserting into the other one. +-- +INSERT INTO test_prepared2 VALUES (5); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +COMMIT PREPARED 'test_prepared#3'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +-- make sure stuff still works +INSERT INTO test_prepared1 VALUES (6); +INSERT INTO test_prepared2 VALUES (7); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- Check 'CLUSTER' (as operation that hold exclusive lock) doesn't block +-- logical decoding. +BEGIN; +INSERT INTO test_prepared1 VALUES (8, 'othercol'); +CLUSTER test_prepared1 USING test_prepared1_pkey; +INSERT INTO test_prepared1 VALUES (9, 'othercol2'); +PREPARE TRANSACTION 'test_prepared_lock'; + +SELECT 'test_prepared1' AS relation, locktype, mode +FROM pg_locks +WHERE locktype = 'relation' + AND relation = 'test_prepared1'::regclass; +-- The above CLUSTER command shouldn't cause a timeout on 2pc decoding. +SET statement_timeout = '180s'; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +RESET statement_timeout; +COMMIT PREPARED 'test_prepared_lock'; +-- consume the commit +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- Test savepoints and sub-xacts. Creating savepoints will create +-- sub-xacts implicitly. +BEGIN; +CREATE TABLE test_prepared_savepoint (a int); +INSERT INTO test_prepared_savepoint VALUES (1); +SAVEPOINT test_savepoint; +INSERT INTO test_prepared_savepoint VALUES (2); +ROLLBACK TO SAVEPOINT test_savepoint; +PREPARE TRANSACTION 'test_prepared_savepoint'; +-- should show only 1, not 2 +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +COMMIT PREPARED 'test_prepared_savepoint'; +-- consume the commit +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- Test that a GID containing "_nodecode" gets decoded at commit prepared time. +BEGIN; +INSERT INTO test_prepared1 VALUES (20); +PREPARE TRANSACTION 'test_prepared_nodecode'; +-- should show nothing +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +COMMIT PREPARED 'test_prepared_nodecode'; +-- should be decoded now +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- Test 8: +-- cleanup and make sure results are also empty +DROP TABLE test_prepared1; +DROP TABLE test_prepared2; +-- show results. There should be nothing to show +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +SELECT pg_drop_replication_slot('regression_slot'); diff --git a/contrib/test_decoding/sql/twophase_stream.sql b/contrib/test_decoding/sql/twophase_stream.sql new file mode 100644 index 000000000000..646076da2074 --- /dev/null +++ b/contrib/test_decoding/sql/twophase_stream.sql @@ -0,0 +1,45 @@ +-- Test streaming of two-phase commits + +SET synchronous_commit = on; +SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true); + +CREATE TABLE stream_test(data text); + +-- consume DDL +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- streaming test with sub-transaction and PREPARE/COMMIT PREPARED +BEGIN; +SAVEPOINT s1; +SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', repeat('a', 50)); +INSERT INTO stream_test SELECT repeat('a', 2000) || g.i FROM generate_series(1, 35) g(i); +TRUNCATE table stream_test; +ROLLBACK TO s1; +INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i); +PREPARE TRANSACTION 'test1'; +-- should show the inserts after a ROLLBACK +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + +COMMIT PREPARED 'test1'; +--should show the COMMIT PREPARED and the other changes in the transaction +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + +-- streaming test with sub-transaction and PREPARE/COMMIT PREPARED but with +-- filtered gid. gids with '_nodecode' will not be decoded at prepare time. +BEGIN; +SAVEPOINT s1; +SELECT 'msg5' FROM pg_logical_emit_message(true, 'test', repeat('a', 50)); +INSERT INTO stream_test SELECT repeat('a', 2000) || g.i FROM generate_series(1, 35) g(i); +TRUNCATE table stream_test; +ROLLBACK to s1; +INSERT INTO stream_test SELECT repeat('a', 10) || g.i FROM generate_series(1, 20) g(i); +PREPARE TRANSACTION 'test1_nodecode'; +-- should NOT show inserts after a ROLLBACK +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + +COMMIT PREPARED 'test1_nodecode'; +-- should show the inserts but not show a COMMIT PREPARED but a COMMIT +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL,NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'stream-changes', '1'); + +DROP TABLE stream_test; +SELECT pg_drop_replication_slot('regression_slot'); diff --git a/contrib/test_decoding/t/001_repl_stats.pl b/contrib/test_decoding/t/001_repl_stats.pl new file mode 100644 index 000000000000..2dc5ef5f0796 --- /dev/null +++ b/contrib/test_decoding/t/001_repl_stats.pl @@ -0,0 +1,118 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +# Test replication statistics data in pg_stat_replication_slots is sane after +# drop replication slot and restart. +use strict; +use warnings; +use File::Path qw(rmtree); +use PostgresNode; +use TestLib; +use Test::More tests => 2; + +# Test set-up +my $node = get_new_node('test'); +$node->init(allows_streaming => 'logical'); +$node->append_conf('postgresql.conf', 'synchronous_commit = on'); +$node->start; + +# Check that replication slot stats are expected. +sub test_slot_stats +{ + my ($node, $expected, $msg) = @_; + + my $result = $node->safe_psql( + 'postgres', qq[ + SELECT slot_name, total_txns > 0 AS total_txn, + total_bytes > 0 AS total_bytes + FROM pg_stat_replication_slots + ORDER BY slot_name]); + is($result, $expected, $msg); +} + +# Create table. +$node->safe_psql('postgres', "CREATE TABLE test_repl_stat(col1 int)"); + +# Create replication slots. +$node->safe_psql( + 'postgres', qq[ + SELECT pg_create_logical_replication_slot('regression_slot1', 'test_decoding'); + SELECT pg_create_logical_replication_slot('regression_slot2', 'test_decoding'); + SELECT pg_create_logical_replication_slot('regression_slot3', 'test_decoding'); + SELECT pg_create_logical_replication_slot('regression_slot4', 'test_decoding'); +]); + +# Insert some data. +$node->safe_psql('postgres', + "INSERT INTO test_repl_stat values(generate_series(1, 5));"); + +$node->safe_psql( + 'postgres', qq[ + SELECT data FROM pg_logical_slot_get_changes('regression_slot1', NULL, + NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + SELECT data FROM pg_logical_slot_get_changes('regression_slot2', NULL, + NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + SELECT data FROM pg_logical_slot_get_changes('regression_slot3', NULL, + NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + SELECT data FROM pg_logical_slot_get_changes('regression_slot4', NULL, + NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +]); + +# Wait for the statistics to be updated. +$node->poll_query_until( + 'postgres', qq[ + SELECT count(slot_name) >= 4 FROM pg_stat_replication_slots + WHERE slot_name ~ 'regression_slot' + AND total_txns > 0 AND total_bytes > 0; +]) or die "Timed out while waiting for statistics to be updated"; + +# Test to drop one of the replication slot and verify replication statistics data is +# fine after restart. +$node->safe_psql('postgres', + "SELECT pg_drop_replication_slot('regression_slot4')"); + +$node->stop; +$node->start; + +# Verify statistics data present in pg_stat_replication_slots are sane after +# restart. +test_slot_stats( + $node, + qq(regression_slot1|t|t +regression_slot2|t|t +regression_slot3|t|t), + 'check replication statistics are updated'); + +# Test to remove one of the replication slots and adjust +# max_replication_slots accordingly to the number of slots. This leads +# to a mismatch between the number of slots present in the stats file and the +# number of stats present in the shared memory, simulating the scenario for +# drop slot message lost by the statistics collector process. We verify +# replication statistics data is fine after restart. + +$node->stop; +my $datadir = $node->data_dir; +my $slot3_replslotdir = "$datadir/pg_replslot/regression_slot3"; + +rmtree($slot3_replslotdir); + +$node->append_conf('postgresql.conf', 'max_replication_slots = 2'); +$node->start; + +# Verify statistics data present in pg_stat_replication_slots are sane after +# restart. +test_slot_stats( + $node, + qq(regression_slot1|t|t +regression_slot2|t|t), + 'check replication statistics after removing the slot file'); + +# cleanup +$node->safe_psql('postgres', "DROP TABLE test_repl_stat"); +$node->safe_psql('postgres', + "SELECT pg_drop_replication_slot('regression_slot1')"); +$node->safe_psql('postgres', + "SELECT pg_drop_replication_slot('regression_slot2')"); + +# shutdown +$node->stop; diff --git a/contrib/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c index 34745150e9ba..de1b69265811 100644 --- a/contrib/test_decoding/test_decoding.c +++ b/contrib/test_decoding/test_decoding.c @@ -3,7 +3,7 @@ * test_decoding.c * example logical decoding output plugin * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/test_decoding/test_decoding.c @@ -34,10 +34,24 @@ typedef struct bool include_xids; bool include_timestamp; bool skip_empty_xacts; - bool xact_wrote_changes; bool only_local; } TestDecodingData; +/* + * Maintain the per-transaction level variables to track whether the + * transaction and or streams have written any changes. In streaming mode the + * transaction can be decoded in streams so along with maintaining whether the + * transaction has written any changes, we also need to track whether the + * current stream has written any changes. This is required so that if user + * has requested to skip the empty transactions we can skip the empty streams + * even though the transaction has written some changes. + */ +typedef struct +{ + bool xact_wrote_changes; + bool stream_wrote_changes; +} TestDecodingTxnData; + static void pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is_init); static void pg_decode_shutdown(LogicalDecodingContext *ctx); @@ -62,13 +76,35 @@ static void pg_decode_message(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr message_lsn, bool transactional, const char *prefix, Size sz, const char *message); +static bool pg_decode_filter_prepare(LogicalDecodingContext *ctx, + TransactionId xid, + const char *gid); +static void pg_decode_begin_prepare_txn(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +static void pg_decode_prepare_txn(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); +static void pg_decode_commit_prepared_txn(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +static void pg_decode_rollback_prepared_txn(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time); static void pg_decode_stream_start(LogicalDecodingContext *ctx, ReorderBufferTXN *txn); +static void pg_output_stream_start(LogicalDecodingContext *ctx, + TestDecodingData *data, + ReorderBufferTXN *txn, + bool last_write); static void pg_decode_stream_stop(LogicalDecodingContext *ctx, ReorderBufferTXN *txn); static void pg_decode_stream_abort(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr abort_lsn); +static void pg_decode_stream_prepare(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); static void pg_decode_stream_commit(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr commit_lsn); @@ -105,9 +141,15 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb) cb->filter_by_origin_cb = pg_decode_filter; cb->shutdown_cb = pg_decode_shutdown; cb->message_cb = pg_decode_message; + cb->filter_prepare_cb = pg_decode_filter_prepare; + cb->begin_prepare_cb = pg_decode_begin_prepare_txn; + cb->prepare_cb = pg_decode_prepare_txn; + cb->commit_prepared_cb = pg_decode_commit_prepared_txn; + cb->rollback_prepared_cb = pg_decode_rollback_prepared_txn; cb->stream_start_cb = pg_decode_stream_start; cb->stream_stop_cb = pg_decode_stream_stop; cb->stream_abort_cb = pg_decode_stream_abort; + cb->stream_prepare_cb = pg_decode_stream_prepare; cb->stream_commit_cb = pg_decode_stream_commit; cb->stream_change_cb = pg_decode_stream_change; cb->stream_message_cb = pg_decode_stream_message; @@ -251,8 +293,12 @@ static void pg_decode_begin_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) { TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = + MemoryContextAllocZero(ctx->context, sizeof(TestDecodingTxnData)); + + txndata->xact_wrote_changes = false; + txn->output_plugin_private = txndata; - data->xact_wrote_changes = false; if (data->skip_empty_xacts) return; @@ -276,8 +322,13 @@ pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr commit_lsn) { TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; + bool xact_wrote_changes = txndata->xact_wrote_changes; - if (data->skip_empty_xacts && !data->xact_wrote_changes) + pfree(txndata); + txn->output_plugin_private = NULL; + + if (data->skip_empty_xacts && !xact_wrote_changes) return; OutputPluginPrepareWrite(ctx, true); @@ -293,6 +344,112 @@ pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, OutputPluginWrite(ctx, true); } +/* BEGIN PREPARE callback */ +static void +pg_decode_begin_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) +{ + TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = + MemoryContextAllocZero(ctx->context, sizeof(TestDecodingTxnData)); + + txndata->xact_wrote_changes = false; + txn->output_plugin_private = txndata; + + if (data->skip_empty_xacts) + return; + + pg_output_begin(ctx, data, txn, true); +} + +/* PREPARE callback */ +static void +pg_decode_prepare_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn) +{ + TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; + + if (data->skip_empty_xacts && !txndata->xact_wrote_changes) + return; + + OutputPluginPrepareWrite(ctx, true); + + appendStringInfo(ctx->out, "PREPARE TRANSACTION %s", + quote_literal_cstr(txn->gid)); + + if (data->include_xids) + appendStringInfo(ctx->out, ", txid %u", txn->xid); + + if (data->include_timestamp) + appendStringInfo(ctx->out, " (at %s)", + timestamptz_to_str(txn->commit_time)); + + OutputPluginWrite(ctx, true); +} + +/* COMMIT PREPARED callback */ +static void +pg_decode_commit_prepared_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn) +{ + TestDecodingData *data = ctx->output_plugin_private; + + OutputPluginPrepareWrite(ctx, true); + + appendStringInfo(ctx->out, "COMMIT PREPARED %s", + quote_literal_cstr(txn->gid)); + + if (data->include_xids) + appendStringInfo(ctx->out, ", txid %u", txn->xid); + + if (data->include_timestamp) + appendStringInfo(ctx->out, " (at %s)", + timestamptz_to_str(txn->commit_time)); + + OutputPluginWrite(ctx, true); +} + +/* ROLLBACK PREPARED callback */ +static void +pg_decode_rollback_prepared_txn(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time) +{ + TestDecodingData *data = ctx->output_plugin_private; + + OutputPluginPrepareWrite(ctx, true); + + appendStringInfo(ctx->out, "ROLLBACK PREPARED %s", + quote_literal_cstr(txn->gid)); + + if (data->include_xids) + appendStringInfo(ctx->out, ", txid %u", txn->xid); + + if (data->include_timestamp) + appendStringInfo(ctx->out, " (at %s)", + timestamptz_to_str(txn->commit_time)); + + OutputPluginWrite(ctx, true); +} + +/* + * Filter out two-phase transactions. + * + * Each plugin can implement its own filtering logic. Here we demonstrate a + * simple logic by checking the GID. If the GID contains the "_nodecode" + * substring, then we filter it out. + */ +static bool +pg_decode_filter_prepare(LogicalDecodingContext *ctx, TransactionId xid, + const char *gid) +{ + if (strstr(gid, "_nodecode") != NULL) + return true; + + return false; +} + static bool pg_decode_filter(LogicalDecodingContext *ctx, RepOriginId origin_id) @@ -438,18 +595,20 @@ pg_decode_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change) { TestDecodingData *data; + TestDecodingTxnData *txndata; Form_pg_class class_form; TupleDesc tupdesc; MemoryContext old; data = ctx->output_plugin_private; + txndata = txn->output_plugin_private; /* output BEGIN if we haven't yet */ - if (data->skip_empty_xacts && !data->xact_wrote_changes) + if (data->skip_empty_xacts && !txndata->xact_wrote_changes) { pg_output_begin(ctx, data, txn, false); } - data->xact_wrote_changes = true; + txndata->xact_wrote_changes = true; class_form = RelationGetForm(relation); tupdesc = RelationGetDescr(relation); @@ -523,17 +682,19 @@ pg_decode_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, int nrelations, Relation relations[], ReorderBufferChange *change) { TestDecodingData *data; + TestDecodingTxnData *txndata; MemoryContext old; int i; data = ctx->output_plugin_private; + txndata = txn->output_plugin_private; /* output BEGIN if we haven't yet */ - if (data->skip_empty_xacts && !data->xact_wrote_changes) + if (data->skip_empty_xacts && !txndata->xact_wrote_changes) { pg_output_begin(ctx, data, txn, false); } - data->xact_wrote_changes = true; + txndata->xact_wrote_changes = true; /* Avoid leaking memory by using and resetting our own context */ old = MemoryContextSwitchTo(data->context); @@ -583,46 +744,59 @@ pg_decode_message(LogicalDecodingContext *ctx, OutputPluginWrite(ctx, true); } -/* - * We never try to stream any empty xact so we don't need any special handling - * for skip_empty_xacts in streaming mode APIs. - */ static void pg_decode_stream_start(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) { TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; - OutputPluginPrepareWrite(ctx, true); + /* + * Allocate the txn plugin data for the first stream in the transaction. + */ + if (txndata == NULL) + { + txndata = + MemoryContextAllocZero(ctx->context, sizeof(TestDecodingTxnData)); + txndata->xact_wrote_changes = false; + txn->output_plugin_private = txndata; + } + + txndata->stream_wrote_changes = false; + if (data->skip_empty_xacts) + return; + pg_output_stream_start(ctx, data, txn, true); +} + +static void +pg_output_stream_start(LogicalDecodingContext *ctx, TestDecodingData *data, ReorderBufferTXN *txn, bool last_write) +{ + OutputPluginPrepareWrite(ctx, last_write); if (data->include_xids) appendStringInfo(ctx->out, "opening a streamed block for transaction TXN %u", txn->xid); else - appendStringInfo(ctx->out, "opening a streamed block for transaction"); - OutputPluginWrite(ctx, true); + appendStringInfoString(ctx->out, "opening a streamed block for transaction"); + OutputPluginWrite(ctx, last_write); } -/* - * We never try to stream any empty xact so we don't need any special handling - * for skip_empty_xacts in streaming mode APIs. - */ static void pg_decode_stream_stop(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) { TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; + + if (data->skip_empty_xacts && !txndata->stream_wrote_changes) + return; OutputPluginPrepareWrite(ctx, true); if (data->include_xids) appendStringInfo(ctx->out, "closing a streamed block for transaction TXN %u", txn->xid); else - appendStringInfo(ctx->out, "closing a streamed block for transaction"); + appendStringInfoString(ctx->out, "closing a streamed block for transaction"); OutputPluginWrite(ctx, true); } -/* - * We never try to stream any empty xact so we don't need any special handling - * for skip_empty_xacts in streaming mode APIs. - */ static void pg_decode_stream_abort(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, @@ -630,31 +804,81 @@ pg_decode_stream_abort(LogicalDecodingContext *ctx, { TestDecodingData *data = ctx->output_plugin_private; + /* + * stream abort can be sent for an individual subtransaction but we + * maintain the output_plugin_private only under the toptxn so if this is + * not the toptxn then fetch the toptxn. + */ + ReorderBufferTXN *toptxn = txn->toptxn ? txn->toptxn : txn; + TestDecodingTxnData *txndata = toptxn->output_plugin_private; + bool xact_wrote_changes = txndata->xact_wrote_changes; + + if (txn->toptxn == NULL) + { + Assert(txn->output_plugin_private != NULL); + pfree(txndata); + txn->output_plugin_private = NULL; + } + + if (data->skip_empty_xacts && !xact_wrote_changes) + return; + OutputPluginPrepareWrite(ctx, true); if (data->include_xids) appendStringInfo(ctx->out, "aborting streamed (sub)transaction TXN %u", txn->xid); else - appendStringInfo(ctx->out, "aborting streamed (sub)transaction"); + appendStringInfoString(ctx->out, "aborting streamed (sub)transaction"); + OutputPluginWrite(ctx, true); +} + +static void +pg_decode_stream_prepare(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn) +{ + TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; + + if (data->skip_empty_xacts && !txndata->xact_wrote_changes) + return; + + OutputPluginPrepareWrite(ctx, true); + + if (data->include_xids) + appendStringInfo(ctx->out, "preparing streamed transaction TXN %s, txid %u", + quote_literal_cstr(txn->gid), txn->xid); + else + appendStringInfo(ctx->out, "preparing streamed transaction %s", + quote_literal_cstr(txn->gid)); + + if (data->include_timestamp) + appendStringInfo(ctx->out, " (at %s)", + timestamptz_to_str(txn->commit_time)); + OutputPluginWrite(ctx, true); } -/* - * We never try to stream any empty xact so we don't need any special handling - * for skip_empty_xacts in streaming mode APIs. - */ static void pg_decode_stream_commit(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr commit_lsn) { TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; + bool xact_wrote_changes = txndata->xact_wrote_changes; + + pfree(txndata); + txn->output_plugin_private = NULL; + + if (data->skip_empty_xacts && !xact_wrote_changes) + return; OutputPluginPrepareWrite(ctx, true); if (data->include_xids) appendStringInfo(ctx->out, "committing streamed transaction TXN %u", txn->xid); else - appendStringInfo(ctx->out, "committing streamed transaction"); + appendStringInfoString(ctx->out, "committing streamed transaction"); if (data->include_timestamp) appendStringInfo(ctx->out, " (at %s)", @@ -675,12 +899,20 @@ pg_decode_stream_change(LogicalDecodingContext *ctx, ReorderBufferChange *change) { TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; + + /* output stream start if we haven't yet */ + if (data->skip_empty_xacts && !txndata->stream_wrote_changes) + { + pg_output_stream_start(ctx, data, txn, false); + } + txndata->xact_wrote_changes = txndata->stream_wrote_changes = true; OutputPluginPrepareWrite(ctx, true); if (data->include_xids) appendStringInfo(ctx->out, "streaming change for TXN %u", txn->xid); else - appendStringInfo(ctx->out, "streaming change for transaction"); + appendStringInfoString(ctx->out, "streaming change for transaction"); OutputPluginWrite(ctx, true); } @@ -721,11 +953,18 @@ pg_decode_stream_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, ReorderBufferChange *change) { TestDecodingData *data = ctx->output_plugin_private; + TestDecodingTxnData *txndata = txn->output_plugin_private; + + if (data->skip_empty_xacts && !txndata->stream_wrote_changes) + { + pg_output_stream_start(ctx, data, txn, false); + } + txndata->xact_wrote_changes = txndata->stream_wrote_changes = true; OutputPluginPrepareWrite(ctx, true); if (data->include_xids) appendStringInfo(ctx->out, "streaming truncate for TXN %u", txn->xid); else - appendStringInfo(ctx->out, "streaming truncate for transaction"); + appendStringInfoString(ctx->out, "streaming truncate for transaction"); OutputPluginWrite(ctx, true); } diff --git a/contrib/tsm_system_rows/tsm_system_rows.c b/contrib/tsm_system_rows/tsm_system_rows.c index 5ab4dd2eca07..8e43cdc1c5b5 100644 --- a/contrib/tsm_system_rows/tsm_system_rows.c +++ b/contrib/tsm_system_rows/tsm_system_rows.c @@ -17,7 +17,7 @@ * won't visit blocks added after the first scan, but that is fine since * such blocks shouldn't contain any visible tuples anyway. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/contrib/tsm_system_time/tsm_system_time.c b/contrib/tsm_system_time/tsm_system_time.c index 0fd65f91ebb5..20debba28945 100644 --- a/contrib/tsm_system_time/tsm_system_time.c +++ b/contrib/tsm_system_time/tsm_system_time.c @@ -13,7 +13,7 @@ * However, we do what we can to reduce surprising behavior by selecting * the sampling pattern just once per query, much as in tsm_system_rows. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c index 0047efc075f3..2b3819fb2e82 100644 --- a/contrib/unaccent/unaccent.c +++ b/contrib/unaccent/unaccent.c @@ -3,7 +3,7 @@ * unaccent.c * Text search unaccent dictionary * - * Copyright (c) 2009-2020, PostgreSQL Global Development Group + * Copyright (c) 2009-2021, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/unaccent/unaccent.c diff --git a/contrib/unaccent/unaccent.rules b/contrib/unaccent/unaccent.rules index bf4c1bd19741..1b5eb1b16c87 100644 --- a/contrib/unaccent/unaccent.rules +++ b/contrib/unaccent/unaccent.rules @@ -1,11 +1,14 @@ +¡ ! © (C) « << ­ - ® (R) +± +/- » >> ¼ 1/4 ½ 1/2 ¾ 3/4 +¿ ? À A Á A Â A @@ -1131,6 +1134,9 @@ ⅇ e ⅈ i ⅉ j +⅐ 1/7 +⅑ 1/9 +⅒ 1/10 ⅓ 1/3 ⅔ 2/3 ⅕ 1/5 @@ -1176,6 +1182,7 @@ ⅽ c ⅾ d ⅿ m +↉ 0/3 − - ∕ / ∖ \ @@ -1602,3 +1609,5 @@ ⦆ )) 。 . 、 , +← <- +→ -> diff --git a/contrib/uuid-ossp/.gitignore b/contrib/uuid-ossp/.gitignore index 6c989c787297..5dcb3ff97235 100644 --- a/contrib/uuid-ossp/.gitignore +++ b/contrib/uuid-ossp/.gitignore @@ -1,5 +1,3 @@ -/md5.c -/sha1.c # Generated subdirectories /log/ /results/ diff --git a/contrib/uuid-ossp/Makefile b/contrib/uuid-ossp/Makefile index c00ea82eab86..81db921831b2 100644 --- a/contrib/uuid-ossp/Makefile +++ b/contrib/uuid-ossp/Makefile @@ -2,7 +2,6 @@ MODULE_big = uuid-ossp OBJS = \ - $(UUID_EXTRA_OBJS) \ $(WIN32RES) \ uuid-ossp.o @@ -20,8 +19,6 @@ pgcrypto_src = $(top_srcdir)/contrib/pgcrypto PG_CPPFLAGS = -I$(pgcrypto_src) -EXTRA_CLEAN = md5.c sha1.c - ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) @@ -32,6 +29,3 @@ top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif - -md5.c sha1.c: % : $(pgcrypto_src)/% - rm -f $@ && $(LN_S) $< . diff --git a/contrib/uuid-ossp/uuid-ossp.c b/contrib/uuid-ossp/uuid-ossp.c index 87db4d7b55b6..5eda81506592 100644 --- a/contrib/uuid-ossp/uuid-ossp.c +++ b/contrib/uuid-ossp/uuid-ossp.c @@ -2,7 +2,7 @@ * * UUID generation functions using the BSD, E2FS or OSSP UUID library * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * Portions Copyright (c) 2009 Andrew Gierth * @@ -14,6 +14,8 @@ #include "postgres.h" #include "fmgr.h" +#include "common/cryptohash.h" +#include "common/sha1.h" #include "port/pg_bswap.h" #include "utils/builtins.h" #include "utils/uuid.h" @@ -43,16 +45,6 @@ #undef uuid_hash -/* - * Some BSD variants offer md5 and sha1 implementations but Linux does not, - * so we use a copy of the ones from pgcrypto. Not needed with OSSP, though. - */ -#ifndef HAVE_UUID_OSSP -#include "md5.h" -#include "sha1.h" -#endif - - /* Check our UUID length against OSSP's; better both be 16 */ #if defined(HAVE_UUID_OSSP) && (UUID_LEN != UUID_LEN_BIN) #error UUID length mismatch @@ -328,23 +320,33 @@ uuid_generate_internal(int v, unsigned char *ns, const char *ptr, int len) if (v == 3) { - MD5_CTX ctx; + pg_cryptohash_ctx *ctx = pg_cryptohash_create(PG_MD5); - MD5Init(&ctx); - MD5Update(&ctx, ns, sizeof(uu)); - MD5Update(&ctx, (unsigned char *) ptr, len); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "MD5"); + if (pg_cryptohash_update(ctx, ns, sizeof(uu)) < 0 || + pg_cryptohash_update(ctx, (unsigned char *) ptr, len) < 0) + elog(ERROR, "could not update %s context", "MD5"); /* we assume sizeof MD5 result is 16, same as UUID size */ - MD5Final((unsigned char *) &uu, &ctx); + if (pg_cryptohash_final(ctx, (unsigned char *) &uu, + sizeof(uu)) < 0) + elog(ERROR, "could not finalize %s context", "MD5"); + pg_cryptohash_free(ctx); } else { - SHA1_CTX ctx; - unsigned char sha1result[SHA1_RESULTLEN]; + pg_cryptohash_ctx *ctx = pg_cryptohash_create(PG_SHA1); + unsigned char sha1result[SHA1_DIGEST_LENGTH]; + + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", "SHA1"); + if (pg_cryptohash_update(ctx, ns, sizeof(uu)) < 0 || + pg_cryptohash_update(ctx, (unsigned char *) ptr, len) < 0) + elog(ERROR, "could not update %s context", "SHA1"); + if (pg_cryptohash_final(ctx, sha1result, sizeof(sha1result)) < 0) + elog(ERROR, "could not finalize %s context", "SHA1"); + pg_cryptohash_free(ctx); - SHA1Init(&ctx); - SHA1Update(&ctx, ns, sizeof(uu)); - SHA1Update(&ctx, (unsigned char *) ptr, len); - SHA1Final(sha1result, &ctx); memcpy(&uu, sha1result, sizeof(uu)); } diff --git a/contrib/vacuumlo/t/001_basic.pl b/contrib/vacuumlo/t/001_basic.pl index 2bfb6ce17d96..2121f454e026 100644 --- a/contrib/vacuumlo/t/001_basic.pl +++ b/contrib/vacuumlo/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c index e4019fafaa9e..dcb95c432047 100644 --- a/contrib/vacuumlo/vacuumlo.c +++ b/contrib/vacuumlo/vacuumlo.c @@ -3,7 +3,7 @@ * vacuumlo.c * This removes orphaned large objects from a database. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,6 +24,7 @@ #include "catalog/pg_class_d.h" #include "common/connect.h" #include "common/logging.h" +#include "common/string.h" #include "getopt_long.h" #include "libpq-fe.h" #include "pg_getopt.h" @@ -69,15 +70,11 @@ vacuumlo(const char *database, const struct _param *param) int i; bool new_pass; bool success = true; - static bool have_password = false; - static char password[100]; + static char *password = NULL; /* Note: password can be carried over from a previous call */ - if (param->pg_prompt == TRI_YES && !have_password) - { - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; - } + if (param->pg_prompt == TRI_YES && !password) + password = simple_prompt("Password: ", false); /* * Start the connection. Loop until we have a password if requested by @@ -97,7 +94,7 @@ vacuumlo(const char *database, const struct _param *param) keywords[2] = "user"; values[2] = param->pg_user; keywords[3] = "password"; - values[3] = have_password ? password : NULL; + values[3] = password; keywords[4] = "dbname"; values[4] = database; keywords[5] = "fallback_application_name"; @@ -115,12 +112,11 @@ vacuumlo(const char *database, const struct _param *param) if (PQstatus(conn) == CONNECTION_BAD && PQconnectionNeedsPassword(conn) && - !have_password && + !password && param->pg_prompt != TRI_NO) { PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; + password = simple_prompt("Password: ", false); new_pass = true; } } while (new_pass); @@ -128,8 +124,7 @@ vacuumlo(const char *database, const struct _param *param) /* check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { - pg_log_error("connection to database \"%s\" failed: %s", - database, PQerrorMessage(conn)); + pg_log_error("%s", PQerrorMessage(conn)); PQfinish(conn); return -1; } diff --git a/doc/src/sgml/README.links b/doc/src/sgml/README.links new file mode 100644 index 000000000000..65df9c111f3b --- /dev/null +++ b/doc/src/sgml/README.links @@ -0,0 +1,54 @@ + + +Linking within DocBook documents can be confusing, so here is a summary: + + +Intra-document Linking +---------------------- + + + use to get chapter/section number from the title of the target + link, or xreflabel if defined at the target, or refentrytitle if target + is a refentry; has no close tag + http://www.oasis-open.org/docbook/documentation/reference/html/xref.html + +linkend= + controls the target of the link/xref, required + +endterm= + for , allows the text of the link/xref to be taken from a + different link target title + + + use to supply text for the link, only uses linkend, requires + http://www.oasis-open.org/docbook/documentation/reference/html/link.html + can be embedded inside of , unlike + + +External Linking +---------------- + + + like , but uses a URL (not a document target); requires + ; if no text is specified, the URL appears as the link + text + http://www.oasis-open.org/docbook/documentation/reference/html/ulink.html + +url= + used by to specify the URL, required + + +Guidelines +---------- + +- For an internal link, if you want to supply text, use , else + . + +- Specific nouns like GUC variables, SQL commands, and contrib modules + usually have xreflabels. + +- For an external link, use , with or without link text. + +- xreflabels added to tags prevent the chapter/section for id's from being + referenced; only the xreflabel is accessible. Therefore, use xreflabels + only when linking is common, and chapter/section information is unneeded. diff --git a/doc/src/sgml/acronyms.sgml b/doc/src/sgml/acronyms.sgml new file mode 100644 index 000000000000..9ed148ab8420 --- /dev/null +++ b/doc/src/sgml/acronyms.sgml @@ -0,0 +1,820 @@ + + + + Acronyms + + + This is a list of acronyms commonly used in the PostgreSQL + documentation and in discussions about PostgreSQL. + + + + + ANSI + + + + American National Standards Institute + + + + + + API + + + Application Programming Interface + + + + + + ASCII + + + American Standard + Code for Information Interchange + + + + + + BKI + + + Backend Interface + + + + + + CA + + + Certificate Authority + + + + + + CIDR + + + Classless + Inter-Domain Routing + + + + + + CPAN + + + Comprehensive Perl Archive Network + + + + + + CRL + + + Certificate + Revocation List + + + + + + CSV + + + Comma + Separated Values + + + + + + CTE + + + Common Table Expression + + + + + + CVE + + + Common Vulnerabilities and Exposures + + + + + + DBA + + + Database + Administrator + + + + + + DBI + + + Database Interface (Perl) + + + + + + DBMS + + + Database Management + System + + + + + + DDL + + + Data + Definition Language, SQL commands such as CREATE + TABLE, ALTER USER + + + + + + DML + + + Data + Manipulation Language, SQL commands such as INSERT, + UPDATE, DELETE + + + + + + DST + + + Daylight + Saving Time + + + + + + ECPG + + + Embedded C for PostgreSQL + + + + + + ESQL + + + Embedded + SQL + + + + + + FAQ + + + Frequently Asked + Questions + + + + + + FSM + + + Free Space Map + + + + + + GEQO + + + Genetic Query Optimizer + + + + + + GIN + + + Generalized Inverted Index + + + + + + GiST + + + Generalized Search Tree + + + + + + Git + + + Git + + + + + + GMT + + + Greenwich Mean Time + + + + + + GSSAPI + + + Generic + Security Services Application Programming Interface + + + + + + GUC + + + Grand Unified Configuration, + the PostgreSQL subsystem that handles server configuration + + + + + + HBA + + + Host-Based Authentication + + + + + + HOT + + + Heap-Only + Tuples + + + + + + IEC + + + International + Electrotechnical Commission + + + + + + IEEE + + + Institute of Electrical and + Electronics Engineers + + + + + + IPC + + + Inter-Process + Communication + + + + + + ISO + + + International Organization for + Standardization + + + + + + ISSN + + + International Standard + Serial Number + + + + + + JDBC + + + Java + Database Connectivity + + + + + + JIT + + + Just-in-Time + compilation + + + + + + JSON + + + JavaScript Object Notation + + + + + + LDAP + + + Lightweight + Directory Access Protocol + + + + + + LSN + + + Log Sequence Number, see pg_lsn + and WAL Internals. + + + + + + MITM + + + + Man-in-the-middle attack + + + + + + MSVC + + + Microsoft + Visual C + + + + + + MVCC + + + Multi-Version Concurrency Control + + + + + + NLS + + + National + Language Support + + + + + + ODBC + + + Open + Database Connectivity + + + + + + OID + + + Object Identifier + + + + + + OLAP + + + Online Analytical + Processing + + + + + + OLTP + + + Online Transaction + Processing + + + + + + ORDBMS + + + Object-Relational + Database Management System + + + + + + PAM + + + Pluggable + Authentication Modules + + + + + + PGSQL + + + PostgreSQL + + + + + + PGXS + + + PostgreSQL Extension System + + + + + + PID + + + Process Identifier + + + + + + PITR + + + Point-In-Time + Recovery (Continuous Archiving) + + + + + + PL + + + Procedural Languages (server-side) + + + + + + POSIX + + + Portable Operating + System Interface + + + + + + RDBMS + + + Relational + Database Management System + + + + + + RFC + + + Request For + Comments + + + + + + SGML + + + Standard Generalized + Markup Language + + + + + + SNI + + + + Server Name Indication, + RFC 6066 + + + + + + SPI + + + Server Programming Interface + + + + + + SP-GiST + + + Space-Partitioned Generalized Search Tree + + + + + + SQL + + + Structured Query Language + + + + + + SRF + + + Set-Returning Function + + + + + + SSH + + + Secure + Shell + + + + + + SSL + + + Secure Sockets Layer + + + + + + SSPI + + + Security + Support Provider Interface + + + + + + SYSV + + + Unix System V + + + + + + TCP/IP + + + Transmission + Control Protocol (TCP) / Internet Protocol (IP) + + + + + + TID + + + Tuple Identifier + + + + + + TLS + + + + Transport Layer Security + + + + + + TOAST + + + The Oversized-Attribute Storage Technique + + + + + + TPC + + + Transaction Processing + Performance Council + + + + + + URL + + + Uniform Resource + Locator + + + + + + UTC + + + Coordinated + Universal Time + + + + + + UTF + + + Unicode Transformation + Format + + + + + + UTF8 + + + Eight-Bit Unicode + Transformation Format + + + + + + UUID + + + Universally Unique Identifier + + + + + + WAL + + + Write-Ahead Log + + + + + + XID + + + Transaction Identifier + + + + + + XML + + + Extensible Markup + Language + + + + + + + + diff --git a/doc/src/sgml/advanced.sgml b/doc/src/sgml/advanced.sgml new file mode 100644 index 000000000000..2d4ab85d450c --- /dev/null +++ b/doc/src/sgml/advanced.sgml @@ -0,0 +1,720 @@ + + + + Advanced Features + + + Introduction + + + In the previous chapter we have covered the basics of using + SQL to store and access your data in + PostgreSQL. We will now discuss some + more advanced features of SQL that simplify + management and prevent loss or corruption of your data. Finally, + we will look at some PostgreSQL + extensions. + + + + This chapter will on occasion refer to examples found in to change or improve them, so it will be + useful to have read that chapter. Some examples from + this chapter can also be found in + advanced.sql in the tutorial directory. This + file also contains some sample data to load, which is not + repeated here. (Refer to for + how to use the file.) + + + + + + Views + + + view + + + + Refer back to the queries in . + Suppose the combined listing of weather records and city location + is of particular interest to your application, but you do not want + to type the query each time you need it. You can create a + view over the query, which gives a name to + the query that you can refer to like an ordinary table: + + +CREATE VIEW myview AS + SELECT city, temp_lo, temp_hi, prcp, date, location + FROM weather, cities + WHERE city = name; + +SELECT * FROM myview; + + + + + Making liberal use of views is a key aspect of good SQL database + design. Views allow you to encapsulate the details of the + structure of your tables, which might change as your application + evolves, behind consistent interfaces. + + + + Views can be used in almost any place a real table can be used. + Building views upon other views is not uncommon. + + + + + + Foreign Keys + + + foreign key + + + + referential integrity + + + + Recall the weather and + cities tables from . Consider the following problem: You + want to make sure that no one can insert rows in the + weather table that do not have a matching + entry in the cities table. This is called + maintaining the referential integrity of + your data. In simplistic database systems this would be + implemented (if at all) by first looking at the + cities table to check if a matching record + exists, and then inserting or rejecting the new + weather records. This approach has a + number of problems and is very inconvenient, so + PostgreSQL can do this for you. + + + + The new declaration of the tables would look like this: + + +CREATE TABLE cities ( + city varchar(80) primary key, + location point +); + +CREATE TABLE weather ( + city varchar(80) references cities(city), + temp_lo int, + temp_hi int, + prcp real, + date date +); + + + Now try inserting an invalid record: + + +INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28'); + + + +ERROR: insert or update on table "weather" violates foreign key constraint "weather_city_fkey" +DETAIL: Key (city)=(Berkeley) is not present in table "cities". + + + + + The behavior of foreign keys can be finely tuned to your + application. We will not go beyond this simple example in this + tutorial, but just refer you to + for more information. Making correct use of + foreign keys will definitely improve the quality of your database + applications, so you are strongly encouraged to learn about them. + + + + + + Transactions + + + transaction + + + + Transactions are a fundamental concept of all database + systems. The essential point of a transaction is that it bundles + multiple steps into a single, all-or-nothing operation. The intermediate + states between the steps are not visible to other concurrent transactions, + and if some failure occurs that prevents the transaction from completing, + then none of the steps affect the database at all. + + + + For example, consider a bank database that contains balances for various + customer accounts, as well as total deposit balances for branches. + Suppose that we want to record a payment of $100.00 from Alice's account + to Bob's account. Simplifying outrageously, the SQL commands for this + might look like: + + +UPDATE accounts SET balance = balance - 100.00 + WHERE name = 'Alice'; +UPDATE branches SET balance = balance - 100.00 + WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice'); +UPDATE accounts SET balance = balance + 100.00 + WHERE name = 'Bob'; +UPDATE branches SET balance = balance + 100.00 + WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob'); + + + + + The details of these commands are not important here; the important + point is that there are several separate updates involved to accomplish + this rather simple operation. Our bank's officers will want to be + assured that either all these updates happen, or none of them happen. + It would certainly not do for a system failure to result in Bob + receiving $100.00 that was not debited from Alice. Nor would Alice long + remain a happy customer if she was debited without Bob being credited. + We need a guarantee that if something goes wrong partway through the + operation, none of the steps executed so far will take effect. Grouping + the updates into a transaction gives us this guarantee. + A transaction is said to be atomic: from the point of + view of other transactions, it either happens completely or not at all. + + + + We also want a + guarantee that once a transaction is completed and acknowledged by + the database system, it has indeed been permanently recorded + and won't be lost even if a crash ensues shortly thereafter. + For example, if we are recording a cash withdrawal by Bob, + we do not want any chance that the debit to his account will + disappear in a crash just after he walks out the bank door. + A transactional database guarantees that all the updates made by + a transaction are logged in permanent storage (i.e., on disk) before + the transaction is reported complete. + + + + Another important property of transactional databases is closely + related to the notion of atomic updates: when multiple transactions + are running concurrently, each one should not be able to see the + incomplete changes made by others. For example, if one transaction + is busy totalling all the branch balances, it would not do for it + to include the debit from Alice's branch but not the credit to + Bob's branch, nor vice versa. So transactions must be all-or-nothing + not only in terms of their permanent effect on the database, but + also in terms of their visibility as they happen. The updates made + so far by an open transaction are invisible to other transactions + until the transaction completes, whereupon all the updates become + visible simultaneously. + + + + In PostgreSQL, a transaction is set up by surrounding + the SQL commands of the transaction with + BEGIN and COMMIT commands. So our banking + transaction would actually look like: + + +BEGIN; +UPDATE accounts SET balance = balance - 100.00 + WHERE name = 'Alice'; +-- etc etc +COMMIT; + + + + + If, partway through the transaction, we decide we do not want to + commit (perhaps we just noticed that Alice's balance went negative), + we can issue the command ROLLBACK instead of + COMMIT, and all our updates so far will be canceled. + + + + PostgreSQL actually treats every SQL statement as being + executed within a transaction. If you do not issue a BEGIN + command, + then each individual statement has an implicit BEGIN and + (if successful) COMMIT wrapped around it. A group of + statements surrounded by BEGIN and COMMIT + is sometimes called a transaction block. + + + + + Some client libraries issue BEGIN and COMMIT + commands automatically, so that you might get the effect of transaction + blocks without asking. Check the documentation for the interface + you are using. + + + + + It's possible to control the statements in a transaction in a more + granular fashion through the use of savepoints. Savepoints + allow you to selectively discard parts of the transaction, while + committing the rest. After defining a savepoint with + SAVEPOINT, you can if needed roll back to the savepoint + with ROLLBACK TO. All the transaction's database changes + between defining the savepoint and rolling back to it are discarded, but + changes earlier than the savepoint are kept. + + + + After rolling back to a savepoint, it continues to be defined, so you can + roll back to it several times. Conversely, if you are sure you won't need + to roll back to a particular savepoint again, it can be released, so the + system can free some resources. Keep in mind that either releasing or + rolling back to a savepoint + will automatically release all savepoints that were defined after it. + + + + All this is happening within the transaction block, so none of it + is visible to other database sessions. When and if you commit the + transaction block, the committed actions become visible as a unit + to other sessions, while the rolled-back actions never become visible + at all. + + + + Remembering the bank database, suppose we debit $100.00 from Alice's + account, and credit Bob's account, only to find later that we should + have credited Wally's account. We could do it using savepoints like + this: + + +BEGIN; +UPDATE accounts SET balance = balance - 100.00 + WHERE name = 'Alice'; +SAVEPOINT my_savepoint; +UPDATE accounts SET balance = balance + 100.00 + WHERE name = 'Bob'; +-- oops ... forget that and use Wally's account +ROLLBACK TO my_savepoint; +UPDATE accounts SET balance = balance + 100.00 + WHERE name = 'Wally'; +COMMIT; + + + + + This example is, of course, oversimplified, but there's a lot of control + possible in a transaction block through the use of savepoints. + Moreover, ROLLBACK TO is the only way to regain control of a + transaction block that was put in aborted state by the + system due to an error, short of rolling it back completely and starting + again. + + + + + + + Window Functions + + + window function + + + + A window function performs a calculation across a set of + table rows that are somehow related to the current row. This is comparable + to the type of calculation that can be done with an aggregate function. + However, window functions do not cause rows to become grouped into a single + output row like non-window aggregate calls would. Instead, the + rows retain their separate identities. Behind the scenes, the window + function is able to access more than just the current row of the query + result. + + + + Here is an example that shows how to compare each employee's salary + with the average salary in his or her department: + + +SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary; + + + + depname | empno | salary | avg +-----------+-------+--------+----------------------- + develop | 11 | 5200 | 5020.0000000000000000 + develop | 7 | 4200 | 5020.0000000000000000 + develop | 9 | 4500 | 5020.0000000000000000 + develop | 8 | 6000 | 5020.0000000000000000 + develop | 10 | 5200 | 5020.0000000000000000 + personnel | 5 | 3500 | 3700.0000000000000000 + personnel | 2 | 3900 | 3700.0000000000000000 + sales | 3 | 4800 | 4866.6666666666666667 + sales | 1 | 5000 | 4866.6666666666666667 + sales | 4 | 4800 | 4866.6666666666666667 +(10 rows) + + + The first three output columns come directly from the table + empsalary, and there is one output row for each row in the + table. The fourth column represents an average taken across all the table + rows that have the same depname value as the current row. + (This actually is the same function as the non-window avg + aggregate, but the OVER clause causes it to be + treated as a window function and computed across the window frame.) + + + + A window function call always contains an OVER clause + directly following the window function's name and argument(s). This is what + syntactically distinguishes it from a normal function or non-window + aggregate. The OVER clause determines exactly how the + rows of the query are split up for processing by the window function. + The PARTITION BY clause within OVER + divides the rows into groups, or partitions, that share the same + values of the PARTITION BY expression(s). For each row, + the window function is computed across the rows that fall into the + same partition as the current row. + + + + You can also control the order in which rows are processed by + window functions using ORDER BY within OVER. + (The window ORDER BY does not even have to match the + order in which the rows are output.) Here is an example: + + +SELECT depname, empno, salary, + rank() OVER (PARTITION BY depname ORDER BY salary DESC) +FROM empsalary; + + + + depname | empno | salary | rank +-----------+-------+--------+------ + develop | 8 | 6000 | 1 + develop | 10 | 5200 | 2 + develop | 11 | 5200 | 2 + develop | 9 | 4500 | 4 + develop | 7 | 4200 | 5 + personnel | 2 | 3900 | 1 + personnel | 5 | 3500 | 2 + sales | 1 | 5000 | 1 + sales | 4 | 4800 | 2 + sales | 3 | 4800 | 2 +(10 rows) + + + As shown here, the rank function produces a numerical rank + for each distinct ORDER BY value in the current row's + partition, using the order defined by the ORDER BY clause. + rank needs no explicit parameter, because its behavior + is entirely determined by the OVER clause. + + + + The rows considered by a window function are those of the virtual + table produced by the query's FROM clause as filtered by its + WHERE, GROUP BY, and HAVING clauses + if any. For example, a row removed because it does not meet the + WHERE condition is not seen by any window function. + A query can contain multiple window functions that slice up the data + in different ways using different OVER clauses, but + they all act on the same collection of rows defined by this virtual table. + + + + We already saw that ORDER BY can be omitted if the ordering + of rows is not important. It is also possible to omit PARTITION + BY, in which case there is a single partition containing all rows. + + + + There is another important concept associated with window functions: + for each row, there is a set of rows within its partition called its + window frame. Some window functions act only + on the rows of the window frame, rather than of the whole partition. + By default, if ORDER BY is supplied then the frame consists of + all rows from the start of the partition up through the current row, plus + any following rows that are equal to the current row according to the + ORDER BY clause. When ORDER BY is omitted the + default frame consists of all rows in the partition. + + + There are options to define the window frame in other ways, but + this tutorial does not cover them. See + for details. + + + Here is an example using sum: + + + +SELECT salary, sum(salary) OVER () FROM empsalary; + + + + salary | sum +--------+------- + 5200 | 47100 + 5000 | 47100 + 3500 | 47100 + 4800 | 47100 + 3900 | 47100 + 4200 | 47100 + 4500 | 47100 + 4800 | 47100 + 6000 | 47100 + 5200 | 47100 +(10 rows) + + + + Above, since there is no ORDER BY in the OVER + clause, the window frame is the same as the partition, which for lack of + PARTITION BY is the whole table; in other words each sum is + taken over the whole table and so we get the same result for each output + row. But if we add an ORDER BY clause, we get very different + results: + + + +SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary; + + + + salary | sum +--------+------- + 3500 | 3500 + 3900 | 7400 + 4200 | 11600 + 4500 | 16100 + 4800 | 25700 + 4800 | 25700 + 5000 | 30700 + 5200 | 41100 + 5200 | 41100 + 6000 | 47100 +(10 rows) + + + + Here the sum is taken from the first (lowest) salary up through the + current one, including any duplicates of the current one (notice the + results for the duplicated salaries). + + + + Window functions are permitted only in the SELECT list + and the ORDER BY clause of the query. They are forbidden + elsewhere, such as in GROUP BY, HAVING + and WHERE clauses. This is because they logically + execute after the processing of those clauses. Also, window functions + execute after non-window aggregate functions. This means it is valid to + include an aggregate function call in the arguments of a window function, + but not vice versa. + + + + If there is a need to filter or group rows after the window calculations + are performed, you can use a sub-select. For example: + + +SELECT depname, empno, salary, enroll_date +FROM + (SELECT depname, empno, salary, enroll_date, + rank() OVER (PARTITION BY depname ORDER BY salary DESC, empno) AS pos + FROM empsalary + ) AS ss +WHERE pos < 3; + + + The above query only shows the rows from the inner query having + rank less than 3. + + + + When a query involves multiple window functions, it is possible to write + out each one with a separate OVER clause, but this is + duplicative and error-prone if the same windowing behavior is wanted + for several functions. Instead, each windowing behavior can be named + in a WINDOW clause and then referenced in OVER. + For example: + + +SELECT sum(salary) OVER w, avg(salary) OVER w + FROM empsalary + WINDOW w AS (PARTITION BY depname ORDER BY salary DESC); + + + + + More details about window functions can be found in + , + , + , and the + reference page. + + + + + + Inheritance + + + inheritance + + + + Inheritance is a concept from object-oriented databases. It opens + up interesting new possibilities of database design. + + + + Let's create two tables: A table cities + and a table capitals. Naturally, capitals + are also cities, so you want some way to show the capitals + implicitly when you list all cities. If you're really clever you + might invent some scheme like this: + + +CREATE TABLE capitals ( + name text, + population real, + elevation int, -- (in ft) + state char(2) +); + +CREATE TABLE non_capitals ( + name text, + population real, + elevation int -- (in ft) +); + +CREATE VIEW cities AS + SELECT name, population, elevation FROM capitals + UNION + SELECT name, population, elevation FROM non_capitals; + + + This works OK as far as querying goes, but it gets ugly when you + need to update several rows, for one thing. + + + + A better solution is this: + + +CREATE TABLE cities ( + name text, + population real, + elevation int -- (in ft) +); + +CREATE TABLE capitals ( + state char(2) UNIQUE NOT NULL +) INHERITS (cities); + + + + + In this case, a row of capitals + inherits all columns (name, + population, and elevation) from its + parent, cities. The + type of the column name is + text, a native PostgreSQL + type for variable length character strings. The + capitals table has + an additional column, state, which shows its + state abbreviation. In + PostgreSQL, a table can inherit from + zero or more other tables. + + + + For example, the following query finds the names of all cities, + including state capitals, that are located at an elevation + over 500 feet: + + +SELECT name, elevation + FROM cities + WHERE elevation > 500; + + + which returns: + + + name | elevation +-----------+----------- + Las Vegas | 2174 + Mariposa | 1953 + Madison | 845 +(3 rows) + + + + + On the other hand, the following query finds + all the cities that are not state capitals and + are situated at an elevation over 500 feet: + + +SELECT name, elevation + FROM ONLY cities + WHERE elevation > 500; + + + + name | elevation +-----------+----------- + Las Vegas | 2174 + Mariposa | 1953 +(2 rows) + + + + + Here the ONLY before cities + indicates that the query should be run over only the + cities table, and not tables below + cities in the inheritance hierarchy. Many + of the commands that we have already discussed — + SELECT, UPDATE, and + DELETE — support this ONLY + notation. + + + + + Although inheritance is frequently useful, it has not been integrated + with unique constraints or foreign keys, which limits its usefulness. + See for more detail. + + + + + + + Conclusion + + + PostgreSQL has many features not + touched upon in this tutorial introduction, which has been + oriented toward newer users of SQL. These + features are discussed in more detail in the remainder of this + book. + + + + If you feel you need more introductory material, please visit the PostgreSQL + web site + for links to more resources. + + + diff --git a/doc/src/sgml/amcheck.sgml b/doc/src/sgml/amcheck.sgml new file mode 100644 index 000000000000..a2571d33ae67 --- /dev/null +++ b/doc/src/sgml/amcheck.sgml @@ -0,0 +1,558 @@ + + + + amcheck + + + amcheck + + + + The amcheck module provides functions that allow you to + verify the logical consistency of the structure of relations. + + + + The B-Tree checking functions verify various invariants in the + structure of the representation of particular relations. The + correctness of the access method functions behind index scans and + other important operations relies on these invariants always + holding. For example, certain functions verify, among other things, + that all B-Tree pages have items in logical order (e.g., + for B-Tree indexes on text, index tuples should be in + collated lexical order). If that particular invariant somehow fails + to hold, we can expect binary searches on the affected page to + incorrectly guide index scans, resulting in wrong answers to SQL + queries. If the structure appears to be valid, no error is raised. + + + Verification is performed using the same procedures as those used by + index scans themselves, which may be user-defined operator class + code. For example, B-Tree index verification relies on comparisons + made with one or more B-Tree support function 1 routines. See for details of operator class support + functions. + + + Unlike the B-Tree checking functions which report corruption by raising + errors, the heap checking function verify_heapam checks + a table and attempts to return a set of rows, one row per corruption + detected. Despite this, if facilities that + verify_heapam relies upon are themselves corrupted, the + function may be unable to continue and may instead raise an error. + + + Permission to execute amcheck functions may be granted + to non-superusers, but before granting such permissions careful consideration + should be given to data security and privacy concerns. Although the + corruption reports generated by these functions do not focus on the contents + of the corrupted data so much as on the structure of that data and the nature + of the corruptions found, an attacker who gains permission to execute these + functions, particularly if the attacker can also induce corruption, might be + able to infer something of the data itself from such messages. + + + + Functions + + + + + bt_index_check(index regclass, heapallindexed boolean) returns void + + bt_index_check + + + + + + bt_index_check tests that its target, a + B-Tree index, respects a variety of invariants. Example usage: + +test=# SELECT bt_index_check(index => c.oid, heapallindexed => i.indisunique), + c.relname, + c.relpages +FROM pg_index i +JOIN pg_opclass op ON i.indclass[0] = op.oid +JOIN pg_am am ON op.opcmethod = am.oid +JOIN pg_class c ON i.indexrelid = c.oid +JOIN pg_namespace n ON c.relnamespace = n.oid +WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog' +-- Don't check temp tables, which may be from another session: +AND c.relpersistence != 't' +-- Function may throw an error when this is omitted: +AND c.relkind = 'i' AND i.indisready AND i.indisvalid +ORDER BY c.relpages DESC LIMIT 10; + bt_index_check | relname | relpages +----------------+---------------------------------+---------- + | pg_depend_reference_index | 43 + | pg_depend_depender_index | 40 + | pg_proc_proname_args_nsp_index | 31 + | pg_description_o_c_o_index | 21 + | pg_attribute_relid_attnam_index | 14 + | pg_proc_oid_index | 10 + | pg_attribute_relid_attnum_index | 9 + | pg_amproc_fam_proc_index | 5 + | pg_amop_opr_fam_index | 5 + | pg_amop_fam_strat_index | 5 +(10 rows) + + This example shows a session that performs verification of the + 10 largest catalog indexes in the database test. + Verification of the presence of heap tuples as index tuples is + requested for the subset that are unique indexes. Since no + error is raised, all indexes tested appear to be logically + consistent. Naturally, this query could easily be changed to + call bt_index_check for every index in the + database where verification is supported. + + + bt_index_check acquires an AccessShareLock + on the target index and the heap relation it belongs to. This lock mode + is the same lock mode acquired on relations by simple + SELECT statements. + bt_index_check does not verify invariants + that span child/parent relationships, but will verify the + presence of all heap tuples as index tuples within the index + when heapallindexed is + true. When a routine, lightweight test for + corruption is required in a live production environment, using + bt_index_check often provides the best + trade-off between thoroughness of verification and limiting the + impact on application performance and availability. + + + + + + + bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void + + bt_index_parent_check + + + + + + bt_index_parent_check tests that its + target, a B-Tree index, respects a variety of invariants. + Optionally, when the heapallindexed + argument is true, the function verifies the + presence of all heap tuples that should be found within the + index. When the optional rootdescend + argument is true, verification re-finds + tuples on the leaf level by performing a new search from the + root page for each tuple. The checks that can be performed by + bt_index_parent_check are a superset of the + checks that can be performed by bt_index_check. + bt_index_parent_check can be thought of as + a more thorough variant of bt_index_check: + unlike bt_index_check, + bt_index_parent_check also checks + invariants that span parent/child relationships, including checking + that there are no missing downlinks in the index structure. + bt_index_parent_check follows the general + convention of raising an error if it finds a logical + inconsistency or other problem. + + + A ShareLock is required on the target index by + bt_index_parent_check (a + ShareLock is also acquired on the heap relation). + These locks prevent concurrent data modification from + INSERT, UPDATE, and DELETE + commands. The locks also prevent the underlying relation from + being concurrently processed by VACUUM, as well as + all other utility commands. Note that the function holds locks + only while running, not for the entire transaction. + + + bt_index_parent_check's additional + verification is more likely to detect various pathological + cases. These cases may involve an incorrectly implemented + B-Tree operator class used by the index that is checked, or, + hypothetically, undiscovered bugs in the underlying B-Tree index + access method code. Note that + bt_index_parent_check cannot be used when + Hot Standby mode is enabled (i.e., on read-only physical + replicas), unlike bt_index_check. + + + + + + + bt_index_check and + bt_index_parent_check both output log + messages about the verification process at + DEBUG1 and DEBUG2 severity + levels. These messages provide detailed information about the + verification process that may be of interest to + PostgreSQL developers. Advanced users + may also find this information helpful, since it provides + additional context should verification actually detect an + inconsistency. Running: + +SET client_min_messages = DEBUG1; + + in an interactive psql session before + running a verification query will display messages about the + progress of verification with a manageable level of detail. + + + + + + + + verify_heapam(relation regclass, + on_error_stop boolean, + check_toast boolean, + skip text, + startblock bigint, + endblock bigint, + blkno OUT bigint, + offnum OUT integer, + attnum OUT integer, + msg OUT text) + returns setof record + + + + + Checks a table for structural corruption, where pages in the relation + contain data that is invalidly formatted, and for logical corruption, + where pages are structurally valid but inconsistent with the rest of the + database cluster. + + + The following optional arguments are recognized: + + + + on_error_stop + + + If true, corruption checking stops at the end of the first block in + which any corruptions are found. + + + Defaults to false. + + + + + check_toast + + + If true, toasted values are checked against the target relation's + TOAST table. + + + This option is known to be slow. Also, if the toast table or its + index is corrupt, checking it against toast values could conceivably + crash the server, although in many cases this would just produce an + error. + + + Defaults to false. + + + + + skip + + + If not none, corruption checking skips blocks that + are marked as all-visible or all-frozen, as specified. + Valid options are all-visible, + all-frozen and none. + + + Defaults to none. + + + + + startblock + + + If specified, corruption checking begins at the specified block, + skipping all previous blocks. It is an error to specify a + startblock outside the range of blocks in the + target table. + + + By default, checking begins at the first block. + + + + + endblock + + + If specified, corruption checking ends at the specified block, + skipping all remaining blocks. It is an error to specify an + endblock outside the range of blocks in the target + table. + + + By default, all blocks are checked. + + + + + + For each corruption detected, verify_heapam returns + a row with the following columns: + + + + blkno + + + The number of the block containing the corrupt page. + + + + + offnum + + + The OffsetNumber of the corrupt tuple. + + + + + attnum + + + The attribute number of the corrupt column in the tuple, if the + corruption is specific to a column and not the tuple as a whole. + + + + + msg + + + A message describing the problem detected. + + + + + + + + + + + Optional <parameter>heapallindexed</parameter> Verification + + When the heapallindexed argument to B-Tree + verification functions is true, an additional + phase of verification is performed against the table associated with + the target index relation. This consists of a dummy + CREATE INDEX operation, which checks for the + presence of all hypothetical new index tuples against a temporary, + in-memory summarizing structure (this is built when needed during + the basic first phase of verification). The summarizing structure + fingerprints every tuple found within the target + index. The high level principle behind + heapallindexed verification is that a new + index that is equivalent to the existing, target index must only + have entries that can be found in the existing structure. + + + The additional heapallindexed phase adds + significant overhead: verification will typically take several times + longer. However, there is no change to the relation-level locks + acquired when heapallindexed verification is + performed. + + + The summarizing structure is bound in size by + maintenance_work_mem. In order to ensure that + there is no more than a 2% probability of failure to detect an + inconsistency for each heap tuple that should be represented in the + index, approximately 2 bytes of memory are needed per tuple. As + less memory is made available per tuple, the probability of missing + an inconsistency slowly increases. This approach limits the + overhead of verification significantly, while only slightly reducing + the probability of detecting a problem, especially for installations + where verification is treated as a routine maintenance task. Any + single absent or malformed tuple has a new opportunity to be + detected with each new verification attempt. + + + + + + Using <filename>amcheck</filename> Effectively + + + amcheck can be effective at detecting various types of + failure modes that data + checksums will fail to catch. These include: + + + + + Structural inconsistencies caused by incorrect operator class + implementations. + + + This includes issues caused by the comparison rules of operating + system collations changing. Comparisons of datums of a collatable + type like text must be immutable (just as all + comparisons used for B-Tree index scans must be immutable), which + implies that operating system collation rules must never change. + Though rare, updates to operating system collation rules can + cause these issues. More commonly, an inconsistency in the + collation order between a primary server and a standby server is + implicated, possibly because the major operating + system version in use is inconsistent. Such inconsistencies will + generally only arise on standby servers, and so can generally + only be detected on standby servers. + + + If a problem like this arises, it may not affect each individual + index that is ordered using an affected collation, simply because + indexed values might happen to have the same + absolute ordering regardless of the behavioral inconsistency. See + and for + further details about how PostgreSQL uses + operating system locales and collations. + + + + + Structural inconsistencies between indexes and the heap relations + that are indexed (when heapallindexed + verification is performed). + + + There is no cross-checking of indexes against their heap relation + during normal operation. Symptoms of heap corruption can be subtle. + + + + + Corruption caused by hypothetical undiscovered bugs in the + underlying PostgreSQL access method + code, sort code, or transaction management code. + + + Automatic verification of the structural integrity of indexes + plays a role in the general testing of new or proposed + PostgreSQL features that could plausibly allow a + logical inconsistency to be introduced. Verification of table + structure and associated visibility and transaction status + information plays a similar role. One obvious testing strategy + is to call amcheck functions continuously + when running the standard regression tests. See for details on running the tests. + + + + + File system or storage subsystem faults where checksums happen to + simply not be enabled. + + + Note that amcheck examines a page as represented in some + shared memory buffer at the time of verification if there is only a + shared buffer hit when accessing the block. Consequently, + amcheck does not necessarily examine data read from the + file system at the time of verification. Note that when checksums are + enabled, amcheck may raise an error due to a checksum + failure when a corrupt block is read into a buffer. + + + + + Corruption caused by faulty RAM, or the broader memory subsystem. + + + PostgreSQL does not protect against correctable + memory errors and it is assumed you will operate using RAM that + uses industry standard Error Correcting Codes (ECC) or better + protection. However, ECC memory is typically only immune to + single-bit errors, and should not be assumed to provide + absolute protection against failures that + result in memory corruption. + + + When heapallindexed verification is + performed, there is generally a greatly increased chance of + detecting single-bit errors, since strict binary equality is + tested, and the indexed attributes within the heap are tested. + + + + + + + Structural corruption can happen due to faulty storage hardware, or + relation files being overwritten or modified by unrelated software. + This kind of corruption can also be detected with + data page + checksums. + + + + Relation pages which are correctly formatted, internally consistent, and + correct relative to their own internal checksums may still contain + logical corruption. As such, this kind of corruption cannot be detected + with checksums. Examples include toasted + values in the main table which lack a corresponding entry in the toast + table, and tuples in the main table with a Transaction ID that is older + than the oldest valid Transaction ID in the database or cluster. + + + + Multiple causes of logical corruption have been observed in production + systems, including bugs in the PostgreSQL + server software, faulty and ill-conceived backup and restore tools, and + user error. + + + + Corrupt relations are most concerning in live production environments, + precisely the same environments where high risk activities are least + welcome. For this reason, verify_heapam has been + designed to diagnose corruption without undue risk. It cannot guard + against all causes of backend crashes, as even executing the calling + query could be unsafe on a badly corrupted system. Access to catalog tables is performed and could + be problematic if the catalogs themselves are corrupted. + + + + In general, amcheck can only prove the presence of + corruption; it cannot prove its absence. + + + + + Repairing Corruption + + No error concerning corruption raised by amcheck should + ever be a false positive. amcheck raises + errors in the event of conditions that, by definition, should never + happen, and so careful analysis of amcheck + errors is often required. + + + There is no general method of repairing problems that + amcheck detects. An explanation for the root cause of + an invariant violation should be sought. may play a useful role in diagnosing + corruption that amcheck detects. A REINDEX + may not be effective in repairing corruption. + + + + + diff --git a/doc/src/sgml/appendix-obsolete-default-roles.sgml b/doc/src/sgml/appendix-obsolete-default-roles.sgml new file mode 100644 index 000000000000..dec3c50e581a --- /dev/null +++ b/doc/src/sgml/appendix-obsolete-default-roles.sgml @@ -0,0 +1,22 @@ + + + + + Default Roles renamed to Predefined Roles + + + default-roles + + + + PostgreSQL 13 and below used the term 'Default Roles', however, as these + roles are not able to actually be changed and are installed as part of the + system at initialization time, the more appropriate term to use is "Predefined Roles". + See for current documentation regarding + Predefined Roles, and the release notes for + PostgreSQL 14 for details on this change. + + + diff --git a/doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml b/doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml new file mode 100644 index 000000000000..f74d0ae832e4 --- /dev/null +++ b/doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml @@ -0,0 +1,24 @@ + + + + + <command>pg_receivexlog</command> renamed to <command>pg_receivewal</command> + + + pg_receivexlog + pg_receivewal + + + + PostgreSQL 9.6 and below provided a command named + pg_receivexlog + pg_receivexlog + to fetch write-ahead-log (WAL) files. This command was renamed to pg_receivewal, see + for documentation of pg_receivewal and see + the release notes for PostgreSQL 10 for details + on this change. + + + diff --git a/doc/src/sgml/appendix-obsolete-pgresetxlog.sgml b/doc/src/sgml/appendix-obsolete-pgresetxlog.sgml new file mode 100644 index 000000000000..7d999301f15c --- /dev/null +++ b/doc/src/sgml/appendix-obsolete-pgresetxlog.sgml @@ -0,0 +1,24 @@ + + + + + <command>pg_resetxlog</command> renamed to <command>pg_resetwal</command> + + + pg_resetxlog + pg_resetwal + + + + PostgreSQL 9.6 and below provided a command named + pg_resetxlog + pg_resetxlog + to reset the write-ahead-log (WAL) files. This command was renamed to pg_resetwal, see + for documentation of pg_resetwal and see + the release notes for PostgreSQL 10 for details + on this change. + + + diff --git a/doc/src/sgml/appendix-obsolete-pgxlogdump.sgml b/doc/src/sgml/appendix-obsolete-pgxlogdump.sgml new file mode 100644 index 000000000000..4173fee04141 --- /dev/null +++ b/doc/src/sgml/appendix-obsolete-pgxlogdump.sgml @@ -0,0 +1,24 @@ + + + + + <command>pg_xlogdump</command> renamed to <command>pg_waldump</command> + + + pg_xlogdump + pg_waldump + + + + PostgreSQL 9.6 and below provided a command named + pg_xlogdump + pg_xlogdump + to read write-ahead-log (WAL) files. This command was renamed to pg_waldump, see + for documentation of pg_waldump and see + the release notes for PostgreSQL 10 for details + on this change. + + + diff --git a/doc/src/sgml/appendix-obsolete-recovery-config.sgml b/doc/src/sgml/appendix-obsolete-recovery-config.sgml new file mode 100644 index 000000000000..77c4289531bf --- /dev/null +++ b/doc/src/sgml/appendix-obsolete-recovery-config.sgml @@ -0,0 +1,58 @@ + + + + + <filename>recovery.conf</filename> file merged into <filename>postgresql.conf</filename> + + + recovery.conf + + + + PostgreSQL 11 and below used a configuration file named + recovery.conf + recovery.conf + to manage replicas and standbys. Support for this file was removed in PostgreSQL 12. See + the release notes for PostgreSQL 12 for details + on this change. + + + + On PostgreSQL 12 and above, + archive recovery, streaming replication, and PITR + are configured using + normal server configuration parameters. + These are set in postgresql.conf or via + ALTER SYSTEM + like any other parameter. + + + + The server will not start if a recovery.conf exists. + + + + The + trigger_file + + trigger_file + promote_trigger_file + + setting has been renamed to + . + + + + The + standby_mode + + standby_mode + standby.signal + + setting has been removed. A standby.signal file in the data directory + is used instead. See for details. + + + diff --git a/doc/src/sgml/appendix-obsolete.sgml b/doc/src/sgml/appendix-obsolete.sgml new file mode 100644 index 000000000000..d218de6c0986 --- /dev/null +++ b/doc/src/sgml/appendix-obsolete.sgml @@ -0,0 +1,42 @@ + + + + Obsolete or Renamed Features + + + Functionality is sometimes removed from PostgreSQL, feature, setting + and file names sometimes change, or documentation moves to different + places. This section directs users coming from old versions of the + documentation or from external links to the appropriate new location + for the information they need. + + + + + &obsolete-recovery-config; + &obsolete-default-roles; + &obsolete-pgxlogdump; + &obsolete-pgresetxlog; + &obsolete-pgreceivexlog; + + diff --git a/doc/src/sgml/arch-dev.sgml b/doc/src/sgml/arch-dev.sgml new file mode 100644 index 000000000000..7aff059e8248 --- /dev/null +++ b/doc/src/sgml/arch-dev.sgml @@ -0,0 +1,567 @@ + + + + Overview of PostgreSQL Internals + + + Author + + This chapter originated as part of + Stefan Simkovics' + Master's Thesis prepared at Vienna University of Technology under the direction + of O.Univ.Prof.Dr. Georg Gottlob and Univ.Ass. Mag. Katrin Seyr. + + + + + This chapter gives an overview of the internal structure of the + backend of PostgreSQL. After having + read the following sections you should have an idea of how a query + is processed. This chapter is intended to help the reader + understand the general sequence of operations that occur within the + backend from the point at which a query is received, to the point + at which the results are returned to the client. + + + + The Path of a Query + + + Here we give a short overview of the stages a query has to pass + to obtain a result. + + + + + + A connection from an application program to the PostgreSQL + server has to be established. The application program transmits a + query to the server and waits to receive the results sent back by the + server. + + + + + + The parser stage checks the query + transmitted by the application + program for correct syntax and creates + a query tree. + + + + + + The rewrite system takes + the query tree created by the parser stage and looks for + any rules (stored in the + system catalogs) to apply to + the query tree. It performs the + transformations given in the rule bodies. + + + + One application of the rewrite system is in the realization of + views. + Whenever a query against a view + (i.e., a virtual table) is made, + the rewrite system rewrites the user's query to + a query that accesses the base tables given in + the view definition instead. + + + + + + The planner/optimizer takes + the (rewritten) query tree and creates a + query plan that will be the input to the + executor. + + + + It does so by first creating all possible paths + leading to the same result. For example if there is an index on a + relation to be scanned, there are two paths for the + scan. One possibility is a simple sequential scan and the other + possibility is to use the index. Next the cost for the execution of + each path is estimated and the cheapest path is chosen. The cheapest + path is expanded into a complete plan that the executor can use. + + + + + + The executor recursively steps through + the plan tree and + retrieves rows in the way represented by the plan. + The executor makes use of the + storage system while scanning + relations, performs sorts and joins, + evaluates qualifications and finally hands back the rows derived. + + + + + + In the following sections we will cover each of the above listed items + in more detail to give a better understanding of PostgreSQL's internal + control and data structures. + + + + + How Connections Are Established + + + PostgreSQL implements a + process per user client/server model. + In this model, every + client process + connects to exactly one + backend process. + As we do not know ahead of time how many connections will be made, + we have to use a supervisor process that spawns a new + backend process every time a connection is requested. This supervisor + process is called + postmaster + and listens at a specified TCP/IP port for incoming connections. + Whenever it detects a request for a connection, it spawns a new + backend process. Those backend processes communicate with each + other and with other processes of the + instance + using semaphores and + shared memory + to ensure data integrity throughout concurrent data access. + + + + The client process can be any program that understands the + PostgreSQL protocol described in + . Many clients are based on the + C-language library libpq, but several independent + implementations of the protocol exist, such as the Java + JDBC driver. + + + + Once a connection is established, the client process can send a query + to the backend process it's connected to. The query is transmitted using + plain text, i.e., there is no parsing done in the client. The backend + process parses the query, creates an execution plan, + executes the plan, and returns the retrieved rows to the client + by transmitting them over the established connection. + + + + + The Parser Stage + + + The parser stage consists of two parts: + + + + + The parser defined in + gram.y and scan.l is + built using the Unix tools bison + and flex. + + + + + The transformation process does + modifications and augmentations to the data structures returned by the parser. + + + + + + + Parser + + + The parser has to check the query string (which arrives as plain + text) for valid syntax. If the syntax is correct a + parse tree is built up and handed back; + otherwise an error is returned. The parser and lexer are + implemented using the well-known Unix tools bison + and flex. + + + + The lexer is defined in the file + scan.l and is responsible + for recognizing identifiers, + the SQL key words etc. For + every key word or identifier that is found, a token + is generated and handed to the parser. + + + + The parser is defined in the file gram.y and + consists of a set of grammar rules and + actions that are executed whenever a rule + is fired. The code of the actions (which is actually C code) is + used to build up the parse tree. + + + + The file scan.l is transformed to the C + source file scan.c using the program + flex and gram.y is + transformed to gram.c using + bison. After these transformations + have taken place a normal C compiler can be used to create the + parser. Never make any changes to the generated C files as they + will be overwritten the next time flex + or bison is called. + + + + The mentioned transformations and compilations are normally done + automatically using the makefiles + shipped with the PostgreSQL + source distribution. + + + + + + A detailed description of bison or + the grammar rules given in gram.y would be + beyond the scope of this manual. There are many books and + documents dealing with flex and + bison. You should be familiar with + bison before you start to study the + grammar given in gram.y otherwise you won't + understand what happens there. + + + + + + Transformation Process + + + The parser stage creates a parse tree using only fixed rules about + the syntactic structure of SQL. It does not make any lookups in the + system catalogs, so there is no possibility to understand the detailed + semantics of the requested operations. After the parser completes, + the transformation process takes the tree handed + back by the parser as input and does the semantic interpretation needed + to understand which tables, functions, and operators are referenced by + the query. The data structure that is built to represent this + information is called the query tree. + + + + The reason for separating raw parsing from semantic analysis is that + system catalog lookups can only be done within a transaction, and we + do not wish to start a transaction immediately upon receiving a query + string. The raw parsing stage is sufficient to identify the transaction + control commands (BEGIN, ROLLBACK, etc), and + these can then be correctly executed without any further analysis. + Once we know that we are dealing with an actual query (such as + SELECT or UPDATE), it is okay to + start a transaction if we're not already in one. Only then can the + transformation process be invoked. + + + + The query tree created by the transformation process is structurally + similar to the raw parse tree in most places, but it has many differences + in detail. For example, a FuncCall node in the + parse tree represents something that looks syntactically like a function + call. This might be transformed to either a FuncExpr + or Aggref node depending on whether the referenced + name turns out to be an ordinary function or an aggregate function. + Also, information about the actual data types of columns and expression + results is added to the query tree. + + + + + + The <productname>PostgreSQL</productname> Rule System + + + PostgreSQL supports a powerful + rule system for the specification + of views and ambiguous view updates. + Originally the PostgreSQL + rule system consisted of two implementations: + + + + + The first one worked using row level processing and was + implemented deep in the executor. The rule system was + called whenever an individual row had been accessed. This + implementation was removed in 1995 when the last official release + of the Berkeley Postgres project was + transformed into Postgres95. + + + + + + The second implementation of the rule system is a technique + called query rewriting. + The rewrite system is a module + that exists between the parser stage and the + planner/optimizer. This technique is still implemented. + + + + + + + The query rewriter is discussed in some detail in + , so there is no need to cover it here. + We will only point out that both the input and the output of the + rewriter are query trees, that is, there is no change in the + representation or level of semantic detail in the trees. Rewriting + can be thought of as a form of macro expansion. + + + + + + Planner/Optimizer + + + The task of the planner/optimizer is to + create an optimal execution plan. A given SQL query (and hence, a + query tree) can be actually executed in a wide variety of + different ways, each of which will produce the same set of + results. If it is computationally feasible, the query optimizer + will examine each of these possible execution plans, ultimately + selecting the execution plan that is expected to run the fastest. + + + + + In some situations, examining each possible way in which a query + can be executed would take an excessive amount of time and memory. + In particular, this occurs when executing queries + involving large numbers of join operations. In order to determine + a reasonable (not necessarily optimal) query plan in a reasonable amount + of time, PostgreSQL uses a Genetic + Query Optimizer (see ) when the number of joins + exceeds a threshold (see ). + + + + + The planner's search procedure actually works with data structures + called paths, which are simply cut-down representations of + plans containing only as much information as the planner needs to make + its decisions. After the cheapest path is determined, a full-fledged + plan tree is built to pass to the executor. This represents + the desired execution plan in sufficient detail for the executor to run it. + In the rest of this section we'll ignore the distinction between paths + and plans. + + + + Generating Possible Plans + + + The planner/optimizer starts by generating plans for scanning each + individual relation (table) used in the query. The possible plans + are determined by the available indexes on each relation. + There is always the possibility of performing a + sequential scan on a relation, so a sequential scan plan is always + created. Assume an index is defined on a + relation (for example a B-tree index) and a query contains the + restriction + relation.attribute OPR constant. If + relation.attribute happens to match the key of the B-tree + index and OPR is one of the operators listed in + the index's operator class, another plan is created using + the B-tree index to scan the relation. If there are further indexes + present and the restrictions in the query happen to match a key of an + index, further plans will be considered. Index scan plans are also + generated for indexes that have a sort ordering that can match the + query's ORDER BY clause (if any), or a sort ordering that + might be useful for merge joining (see below). + + + + If the query requires joining two or more relations, + plans for joining relations are considered + after all feasible plans have been found for scanning single relations. + The three available join strategies are: + + + + + nested loop join: The right relation is scanned + once for every row found in the left relation. This strategy + is easy to implement but can be very time consuming. (However, + if the right relation can be scanned with an index scan, this can + be a good strategy. It is possible to use values from the current + row of the left relation as keys for the index scan of the right.) + + + + + + merge join: Each relation is sorted on the join + attributes before the join starts. Then the two relations are + scanned in parallel, and matching rows are combined to form + join rows. This kind of join is + attractive because each relation has to be scanned only once. + The required sorting might be achieved either by an explicit sort + step, or by scanning the relation in the proper order using an + index on the join key. + + + + + + hash join: the right relation is first scanned + and loaded into a hash table, using its join attributes as hash keys. + Next the left relation is scanned and the + appropriate values of every row found are used as hash keys to + locate the matching rows in the table. + + + + + + + When the query involves more than two relations, the final result + must be built up by a tree of join steps, each with two inputs. + The planner examines different possible join sequences to find the + cheapest one. + + + + If the query uses fewer than + relations, a near-exhaustive search is conducted to find the best + join sequence. The planner preferentially considers joins between any + two relations for which there exists a corresponding join clause in the + WHERE qualification (i.e., for + which a restriction like where rel1.attr1=rel2.attr2 + exists). Join pairs with no join clause are considered only when there + is no other choice, that is, a particular relation has no available + join clauses to any other relation. All possible plans are generated for + every join pair considered by the planner, and the one that is + (estimated to be) the cheapest is chosen. + + + + When geqo_threshold is exceeded, the join + sequences considered are determined by heuristics, as described + in . Otherwise the process is the same. + + + + The finished plan tree consists of sequential or index scans of + the base relations, plus nested-loop, merge, or hash join nodes as + needed, plus any auxiliary steps needed, such as sort nodes or + aggregate-function calculation nodes. Most of these plan node + types have the additional ability to do selection + (discarding rows that do not meet a specified Boolean condition) + and projection (computation of a derived column set + based on given column values, that is, evaluation of scalar + expressions where needed). One of the responsibilities of the + planner is to attach selection conditions from the + WHERE clause and computation of required + output expressions to the most appropriate nodes of the plan + tree. + + + + + + Executor + + + The executor takes the plan created by the + planner/optimizer and recursively processes it to extract the required set + of rows. This is essentially a demand-pull pipeline mechanism. + Each time a plan node is called, it must deliver one more row, or + report that it is done delivering rows. + + + + To provide a concrete example, assume that the top + node is a MergeJoin node. + Before any merge can be done two rows have to be fetched (one from + each subplan). So the executor recursively calls itself to + process the subplans (it starts with the subplan attached to + lefttree). The new top node (the top node of the left + subplan) is, let's say, a + Sort node and again recursion is needed to obtain + an input row. The child node of the Sort might + be a SeqScan node, representing actual reading of a table. + Execution of this node causes the executor to fetch a row from the + table and return it up to the calling node. The Sort + node will repeatedly call its child to obtain all the rows to be sorted. + When the input is exhausted (as indicated by the child node returning + a NULL instead of a row), the Sort code performs + the sort, and finally is able to return its first output row, namely + the first one in sorted order. It keeps the remaining rows stored so + that it can deliver them in sorted order in response to later demands. + + + + The MergeJoin node similarly demands the first row + from its right subplan. Then it compares the two rows to see if they + can be joined; if so, it returns a join row to its caller. On the next + call, or immediately if it cannot join the current pair of inputs, + it advances to the next row of one table + or the other (depending on how the comparison came out), and again + checks for a match. Eventually, one subplan or the other is exhausted, + and the MergeJoin node returns NULL to indicate that + no more join rows can be formed. + + + + Complex queries can involve many levels of plan nodes, but the general + approach is the same: each node computes and returns its next output + row each time it is called. Each node is also responsible for applying + any selection or projection expressions that were assigned to it by + the planner. + + + + The executor mechanism is used to evaluate all four basic SQL query + types: SELECT, INSERT, + UPDATE, and DELETE. + For SELECT, the top-level executor code + only needs to send each row returned by the query plan tree + off to the client. INSERT ... SELECT, + UPDATE, and DELETE + are effectively SELECTs under a special + top-level plan node called ModifyTable. + + + + INSERT ... SELECT feeds the rows up + to ModifyTable for insertion. For + UPDATE, the planner arranges that each + computed row includes all the updated column values, plus the + TID (tuple ID, or row ID) of the original + target row; this data is fed up to the ModifyTable + node, which uses the information to create a new updated row and + mark the old row deleted. For DELETE, the only + column that is actually returned by the plan is the TID, and the + ModifyTable node simply uses the TID to visit each + target row and mark it deleted. + + + + A simple INSERT ... VALUES command creates a + trivial plan tree consisting of a single Result + node, which computes just one result row, feeding that up + toModifyTable to perform the insertion. + + + + + diff --git a/doc/src/sgml/auto-explain.sgml b/doc/src/sgml/auto-explain.sgml new file mode 100644 index 000000000000..30e35a714a5f --- /dev/null +++ b/doc/src/sgml/auto-explain.sgml @@ -0,0 +1,340 @@ + + + + auto_explain + + + auto_explain + + + + The auto_explain module provides a means for + logging execution plans of slow statements automatically, without + having to run + by hand. This is especially helpful for tracking down un-optimized queries + in large applications. + + + + The module provides no SQL-accessible functions. To use it, simply + load it into the server. You can load it into an individual session: + + +LOAD 'auto_explain'; + + + (You must be superuser to do that.) More typical usage is to preload + it into some or all sessions by including auto_explain in + or + in + postgresql.conf. Then you can track unexpectedly slow queries + no matter when they happen. Of course there is a price in overhead for + that. + + + + Configuration Parameters + + + There are several configuration parameters that control the behavior of + auto_explain. Note that the default behavior is + to do nothing, so you must set at least + auto_explain.log_min_duration if you want any results. + + + + + + auto_explain.log_min_duration (integer) + + auto_explain.log_min_duration configuration parameter + + + + + auto_explain.log_min_duration is the minimum statement + execution time, in milliseconds, that will cause the statement's plan to + be logged. Setting this to 0 logs all plans. + -1 (the default) disables logging of plans. For + example, if you set it to 250ms then all statements + that run 250ms or longer will be logged. Only superusers can change this + setting. + + + + + + + auto_explain.log_analyze (boolean) + + auto_explain.log_analyze configuration parameter + + + + + auto_explain.log_analyze causes EXPLAIN ANALYZE + output, rather than just EXPLAIN output, to be printed + when an execution plan is logged. This parameter is off by default. + Only superusers can change this setting. + + + + When this parameter is on, per-plan-node timing occurs for all + statements executed, whether or not they run long enough to actually + get logged. This can have an extremely negative impact on performance. + Turning off auto_explain.log_timing ameliorates the + performance cost, at the price of obtaining less information. + + + + + + + + auto_explain.log_buffers (boolean) + + auto_explain.log_buffers configuration parameter + + + + + auto_explain.log_buffers controls whether buffer + usage statistics are printed when an execution plan is logged; it's + equivalent to the BUFFERS option of EXPLAIN. + This parameter has no effect + unless auto_explain.log_analyze is enabled. + This parameter is off by default. + Only superusers can change this setting. + + + + + + + auto_explain.log_wal (boolean) + + auto_explain.log_wal configuration parameter + + + + + auto_explain.log_wal controls whether WAL + usage statistics are printed when an execution plan is logged; it's + equivalent to the WAL option of EXPLAIN. + This parameter has no effect + unless auto_explain.log_analyze is enabled. + This parameter is off by default. + Only superusers can change this setting. + + + + + + + auto_explain.log_timing (boolean) + + auto_explain.log_timing configuration parameter + + + + + auto_explain.log_timing controls whether per-node + timing information is printed when an execution plan is logged; it's + equivalent to the TIMING option of EXPLAIN. + The overhead of repeatedly reading the system clock can slow down + queries significantly on some systems, so it may be useful to set this + parameter to off when only actual row counts, and not exact times, are + needed. + This parameter has no effect + unless auto_explain.log_analyze is enabled. + This parameter is on by default. + Only superusers can change this setting. + + + + + + + auto_explain.log_triggers (boolean) + + auto_explain.log_triggers configuration parameter + + + + + auto_explain.log_triggers causes trigger + execution statistics to be included when an execution plan is logged. + This parameter has no effect + unless auto_explain.log_analyze is enabled. + This parameter is off by default. + Only superusers can change this setting. + + + + + + + auto_explain.log_verbose (boolean) + + auto_explain.log_verbose configuration parameter + + + + + auto_explain.log_verbose controls whether verbose + details are printed when an execution plan is logged; it's + equivalent to the VERBOSE option of EXPLAIN. + This parameter is off by default. + Only superusers can change this setting. + + + + + + + auto_explain.log_settings (boolean) + + auto_explain.log_settings configuration parameter + + + + + auto_explain.log_settings controls whether information + about modified configuration options is printed when an execution plan is logged. + Only options affecting query planning with value different from the built-in + default value are included in the output. This parameter is off by default. + Only superusers can change this setting. + + + + + + + auto_explain.log_format (enum) + + auto_explain.log_format configuration parameter + + + + + auto_explain.log_format selects the + EXPLAIN output format to be used. + The allowed values are text, xml, + json, and yaml. The default is text. + Only superusers can change this setting. + + + + + + + auto_explain.log_level (enum) + + auto_explain.log_level configuration parameter + + + + + auto_explain.log_level selects the log level at which + auto_explain will log the query plan. + Valid values are DEBUG5, DEBUG4, + DEBUG3, DEBUG2, + DEBUG1, INFO, + NOTICE, WARNING, + and LOG. The default is LOG. + Only superusers can change this setting. + + + + + + + auto_explain.log_nested_statements (boolean) + + auto_explain.log_nested_statements configuration parameter + + + + + auto_explain.log_nested_statements causes nested + statements (statements executed inside a function) to be considered + for logging. When it is off, only top-level query plans are logged. This + parameter is off by default. Only superusers can change this setting. + + + + + + + auto_explain.sample_rate (real) + + auto_explain.sample_rate configuration parameter + + + + + auto_explain.sample_rate causes auto_explain to only + explain a fraction of the statements in each session. The default is 1, + meaning explain all the queries. In case of nested statements, either all + will be explained or none. Only superusers can change this setting. + + + + + + + In ordinary usage, these parameters are set + in postgresql.conf, although superusers can alter them + on-the-fly within their own sessions. + Typical usage might be: + + + +# postgresql.conf +session_preload_libraries = 'auto_explain' + +auto_explain.log_min_duration = '3s' + + + + + Example + + +postgres=# LOAD 'auto_explain'; +postgres=# SET auto_explain.log_min_duration = 0; +postgres=# SET auto_explain.log_analyze = true; +postgres=# SELECT count(*) + FROM pg_class, pg_index + WHERE oid = indrelid AND indisunique; + + + + This might produce log output such as: + + + Hash Join (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92 loops=1) + Hash Cond: (pg_class.oid = pg_index.indrelid) + -> Seq Scan on pg_class (cost=0.00..9.55 rows=255 width=4) (actual time=0.016..0.140 rows=255 loops=1) + -> Hash (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92 loops=1) + Buckets: 1024 Batches: 1 Memory Usage: 4kB + -> Seq Scan on pg_index (cost=0.00..3.02 rows=92 width=4) (actual time=0.008..3.187 rows=92 loops=1) + Filter: indisunique +]]> + + + + Author + + + Takahiro Itagaki itagaki.takahiro@oss.ntt.co.jp + + + + diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml new file mode 100644 index 000000000000..8c9186d277fd --- /dev/null +++ b/doc/src/sgml/backup.sgml @@ -0,0 +1,1657 @@ + + + + Backup and Restore + + backup + + + As with everything that contains valuable data, PostgreSQL + databases should be backed up regularly. While the procedure is + essentially simple, it is important to have a clear understanding of + the underlying techniques and assumptions. + + + + There are three fundamentally different approaches to backing up + PostgreSQL data: + + SQL dump + File system level backup + Continuous archiving + + Each has its own strengths and weaknesses; each is discussed in turn + in the following sections. + + + + <acronym>SQL</acronym> Dump + + + The idea behind this dump method is to generate a file with SQL + commands that, when fed back to the server, will recreate the + database in the same state as it was at the time of the dump. + PostgreSQL provides the utility program + for this purpose. The basic usage of this + command is: + +pg_dump dbname > dumpfile + + As you see, pg_dump writes its result to the + standard output. We will see below how this can be useful. + While the above command creates a text file, pg_dump + can create files in other formats that allow for parallelism and more + fine-grained control of object restoration. + + + + pg_dump is a regular PostgreSQL + client application (albeit a particularly clever one). This means + that you can perform this backup procedure from any remote host that has + access to the database. But remember that pg_dump + does not operate with special permissions. In particular, it must + have read access to all tables that you want to back up, so in order + to back up the entire database you almost always have to run it as a + database superuser. (If you do not have sufficient privileges to back up + the entire database, you can still back up portions of the database to which + you do have access using options such as + + or .) + + + + To specify which database server pg_dump should + contact, use the command line options and . The + default host is the local host or whatever your + PGHOST environment variable specifies. Similarly, + the default port is indicated by the PGPORT + environment variable or, failing that, by the compiled-in default. + (Conveniently, the server will normally have the same compiled-in + default.) + + + + Like any other PostgreSQL client application, + pg_dump will by default connect with the database + user name that is equal to the current operating system user name. To override + this, either specify the option or set the + environment variable PGUSER. Remember that + pg_dump connections are subject to the normal + client authentication mechanisms (which are described in ). + + + + An important advantage of pg_dump over the other backup + methods described later is that pg_dump's output can + generally be re-loaded into newer versions of PostgreSQL, + whereas file-level backups and continuous archiving are both extremely + server-version-specific. pg_dump is also the only method + that will work when transferring a database to a different machine + architecture, such as going from a 32-bit to a 64-bit server. + + + + Dumps created by pg_dump are internally consistent, + meaning, the dump represents a snapshot of the database at the time + pg_dump began running. pg_dump does not + block other operations on the database while it is working. + (Exceptions are those operations that need to operate with an + exclusive lock, such as most forms of ALTER TABLE.) + + + + Restoring the Dump + + + Text files created by pg_dump are intended to + be read in by the psql program. The + general command form to restore a dump is + +psql dbname < dumpfile + + where dumpfile is the + file output by the pg_dump command. The database dbname will not be created by this + command, so you must create it yourself from template0 + before executing psql (e.g., with + createdb -T template0 dbname). psql + supports options similar to pg_dump for specifying + the database server to connect to and the user name to use. See + the reference page for more information. + Non-text file dumps are restored using the utility. + + + + Before restoring an SQL dump, all the users who own objects or were + granted permissions on objects in the dumped database must already + exist. If they do not, the restore will fail to recreate the + objects with the original ownership and/or permissions. + (Sometimes this is what you want, but usually it is not.) + + + + By default, the psql script will continue to + execute after an SQL error is encountered. You might wish to run + psql with + the ON_ERROR_STOP variable set to alter that + behavior and have psql exit with an + exit status of 3 if an SQL error occurs: + +psql --set ON_ERROR_STOP=on dbname < dumpfile + + Either way, you will only have a partially restored database. + Alternatively, you can specify that the whole dump should be + restored as a single transaction, so the restore is either fully + completed or fully rolled back. This mode can be specified by + passing the or + command-line options to psql. When using this + mode, be aware that even a minor error can rollback a + restore that has already run for many hours. However, that might + still be preferable to manually cleaning up a complex database + after a partially restored dump. + + + + The ability of pg_dump and psql to + write to or read from pipes makes it possible to dump a database + directly from one server to another, for example: + +pg_dump -h host1 dbname | psql -h host2 dbname + + + + + + The dumps produced by pg_dump are relative to + template0. This means that any languages, procedures, + etc. added via template1 will also be dumped by + pg_dump. As a result, when restoring, if you are + using a customized template1, you must create the + empty database from template0, as in the example + above. + + + + + After restoring a backup, it is wise to run ANALYZE on each + database so the query optimizer has useful statistics; + see + and for more information. + For more advice on how to load large amounts of data + into PostgreSQL efficiently, refer to . + + + + + Using <application>pg_dumpall</application> + + + pg_dump dumps only a single database at a time, + and it does not dump information about roles or tablespaces + (because those are cluster-wide rather than per-database). + To support convenient dumping of the entire contents of a database + cluster, the program is provided. + pg_dumpall backs up each database in a given + cluster, and also preserves cluster-wide data such as role and + tablespace definitions. The basic usage of this command is: + +pg_dumpall > dumpfile + + The resulting dump can be restored with psql: + +psql -f dumpfile postgres + + (Actually, you can specify any existing database name to start from, + but if you are loading into an empty cluster then postgres + should usually be used.) It is always necessary to have + database superuser access when restoring a pg_dumpall + dump, as that is required to restore the role and tablespace information. + If you use tablespaces, make sure that the tablespace paths in the + dump are appropriate for the new installation. + + + + pg_dumpall works by emitting commands to re-create + roles, tablespaces, and empty databases, then invoking + pg_dump for each database. This means that while + each database will be internally consistent, the snapshots of + different databases are not synchronized. + + + + Cluster-wide data can be dumped alone using the + pg_dumpall option. + This is necessary to fully backup the cluster if running the + pg_dump command on individual databases. + + + + + Handling Large Databases + + + Some operating systems have maximum file size limits that cause + problems when creating large pg_dump output files. + Fortunately, pg_dump can write to the standard + output, so you can use standard Unix tools to work around this + potential problem. There are several possible methods: + + + + Use compressed dumps. + + You can use your favorite compression program, for example + gzip: + + +pg_dump dbname | gzip > filename.gz + + + Reload with: + + +gunzip -c filename.gz | psql dbname + + + or: + + +cat filename.gz | gunzip | psql dbname + + + + + + Use <command>split</command>. + + The split command + allows you to split the output into smaller files that are + acceptable in size to the underlying file system. For example, to + make chunks of 1 megabyte: + + +pg_dump dbname | split -b 1m - filename + + + Reload with: + + +cat filename* | psql dbname + + + + + + Use <application>pg_dump</application>'s custom dump format. + + If PostgreSQL was built on a system with the + zlib compression library installed, the custom dump + format will compress data as it writes it to the output file. This will + produce dump file sizes similar to using gzip, but it + has the added advantage that tables can be restored selectively. The + following command dumps a database using the custom dump format: + + +pg_dump -Fc dbname > filename + + + A custom-format dump is not a script for psql, but + instead must be restored with pg_restore, for example: + + +pg_restore -d dbname filename + + + See the and reference pages for details. + + + + + For very large databases, you might need to combine split + with one of the other two approaches. + + + + Use <application>pg_dump</application>'s parallel dump feature. + + To speed up the dump of a large database, you can use + pg_dump's parallel mode. This will dump + multiple tables at the same time. You can control the degree of + parallelism with the -j parameter. Parallel dumps + are only supported for the "directory" archive format. + + +pg_dump -j num -F d -f out.dir dbname + + + You can use pg_restore -j to restore a dump in parallel. + This will work for any archive of either the "custom" or the "directory" + archive mode, whether or not it has been created with pg_dump -j. + + + + + + + File System Level Backup + + + An alternative backup strategy is to directly copy the files that + PostgreSQL uses to store the data in the database; + explains where these files + are located. You can use whatever method you prefer + for doing file system backups; for example: + + +tar -cf backup.tar /usr/local/pgsql/data + + + + + There are two restrictions, however, which make this method + impractical, or at least inferior to the pg_dump + method: + + + + + The database server must be shut down in order to + get a usable backup. Half-way measures such as disallowing all + connections will not work + (in part because tar and similar tools do not take + an atomic snapshot of the state of the file system, + but also because of internal buffering within the server). + Information about stopping the server can be found in + . Needless to say, you + also need to shut down the server before restoring the data. + + + + + + If you have dug into the details of the file system layout of the + database, you might be tempted to try to back up or restore only certain + individual tables or databases from their respective files or + directories. This will not work because the + information contained in these files is not usable without + the commit log files, + pg_xact/*, which contain the commit status of + all transactions. A table file is only usable with this + information. Of course it is also impossible to restore only a + table and the associated pg_xact data + because that would render all other tables in the database + cluster useless. So file system backups only work for complete + backup and restoration of an entire database cluster. + + + + + + + An alternative file-system backup approach is to make a + consistent snapshot of the data directory, if the + file system supports that functionality (and you are willing to + trust that it is implemented correctly). The typical procedure is + to make a frozen snapshot of the volume containing the + database, then copy the whole data directory (not just parts, see + above) from the snapshot to a backup device, then release the frozen + snapshot. This will work even while the database server is running. + However, a backup created in this way saves + the database files in a state as if the database server was not + properly shut down; therefore, when you start the database server + on the backed-up data, it will think the previous server instance + crashed and will replay the WAL log. This is not a problem; just + be aware of it (and be sure to include the WAL files in your backup). + You can perform a CHECKPOINT before taking the + snapshot to reduce recovery time. + + + + If your database is spread across multiple file systems, there might not + be any way to obtain exactly-simultaneous frozen snapshots of all + the volumes. For example, if your data files and WAL log are on different + disks, or if tablespaces are on different file systems, it might + not be possible to use snapshot backup because the snapshots + must be simultaneous. + Read your file system documentation very carefully before trusting + the consistent-snapshot technique in such situations. + + + + If simultaneous snapshots are not possible, one option is to shut down + the database server long enough to establish all the frozen snapshots. + Another option is to perform a continuous archiving base backup () because such backups are immune to file + system changes during the backup. This requires enabling continuous + archiving just during the backup process; restore is done using + continuous archive recovery (). + + + + Another option is to use rsync to perform a file + system backup. This is done by first running rsync + while the database server is running, then shutting down the database + server long enough to do an rsync --checksum. + ( is necessary because rsync only + has file modification-time granularity of one second.) The + second rsync will be quicker than the first, + because it has relatively little data to transfer, and the end result + will be consistent because the server was down. This method + allows a file system backup to be performed with minimal downtime. + + + + Note that a file system backup will typically be larger + than an SQL dump. (pg_dump does not need to dump + the contents of indexes for example, just the commands to recreate + them.) However, taking a file system backup might be faster. + + + + + Continuous Archiving and Point-in-Time Recovery (PITR) + + + continuous archiving + + + + point-in-time recovery + + + + PITR + + + + At all times, PostgreSQL maintains a + write ahead log (WAL) in the pg_wal/ + subdirectory of the cluster's data directory. The log records + every change made to the database's data files. This log exists + primarily for crash-safety purposes: if the system crashes, the + database can be restored to consistency by replaying the + log entries made since the last checkpoint. However, the existence + of the log makes it possible to use a third strategy for backing up + databases: we can combine a file-system-level backup with backup of + the WAL files. If recovery is needed, we restore the file system backup and + then replay from the backed-up WAL files to bring the system to a + current state. This approach is more complex to administer than + either of the previous approaches, but it has some significant + benefits: + + + + We do not need a perfectly consistent file system backup as the starting point. + Any internal inconsistency in the backup will be corrected by log + replay (this is not significantly different from what happens during + crash recovery). So we do not need a file system snapshot capability, + just tar or a similar archiving tool. + + + + + Since we can combine an indefinitely long sequence of WAL files + for replay, continuous backup can be achieved simply by continuing to archive + the WAL files. This is particularly valuable for large databases, where + it might not be convenient to take a full backup frequently. + + + + + It is not necessary to replay the WAL entries all the + way to the end. We could stop the replay at any point and have a + consistent snapshot of the database as it was at that time. Thus, + this technique supports point-in-time recovery: it is + possible to restore the database to its state at any time since your base + backup was taken. + + + + + If we continuously feed the series of WAL files to another + machine that has been loaded with the same base backup file, we + have a warm standby system: at any point we can bring up + the second machine and it will have a nearly-current copy of the + database. + + + + + + + + pg_dump and + pg_dumpall do not produce file-system-level + backups and cannot be used as part of a continuous-archiving solution. + Such dumps are logical and do not contain enough + information to be used by WAL replay. + + + + + As with the plain file-system-backup technique, this method can only + support restoration of an entire database cluster, not a subset. + Also, it requires a lot of archival storage: the base backup might be bulky, + and a busy system will generate many megabytes of WAL traffic that + have to be archived. Still, it is the preferred backup technique in + many situations where high reliability is needed. + + + + To recover successfully using continuous archiving (also called + online backup by many database vendors), you need a continuous + sequence of archived WAL files that extends back at least as far as the + start time of your backup. So to get started, you should set up and test + your procedure for archiving WAL files before you take your + first base backup. Accordingly, we first discuss the mechanics of + archiving WAL files. + + + + Setting Up WAL Archiving + + + In an abstract sense, a running PostgreSQL system + produces an indefinitely long sequence of WAL records. The system + physically divides this sequence into WAL segment + files, which are normally 16MB apiece (although the segment size + can be altered during initdb). The segment + files are given numeric names that reflect their position in the + abstract WAL sequence. When not using WAL archiving, the system + normally creates just a few segment files and then + recycles them by renaming no-longer-needed segment files + to higher segment numbers. It's assumed that segment files whose + contents precede the last checkpoint are no longer of + interest and can be recycled. + + + + When archiving WAL data, we need to capture the contents of each segment + file once it is filled, and save that data somewhere before the segment + file is recycled for reuse. Depending on the application and the + available hardware, there could be many different ways of saving + the data somewhere: we could copy the segment files to an NFS-mounted + directory on another machine, write them onto a tape drive (ensuring that + you have a way of identifying the original name of each file), or batch + them together and burn them onto CDs, or something else entirely. To + provide the database administrator with flexibility, + PostgreSQL tries not to make any assumptions about how + the archiving will be done. Instead, PostgreSQL lets + the administrator specify a shell command to be executed to copy a + completed segment file to wherever it needs to go. The command could be + as simple as a cp, or it could invoke a complex shell + script — it's all up to you. + + + + To enable WAL archiving, set the + configuration parameter to replica or higher, + to on, + and specify the shell command to use in the configuration parameter. In practice + these settings will always be placed in the + postgresql.conf file. + In archive_command, + %p is replaced by the path name of the file to + archive, while %f is replaced by only the file name. + (The path name is relative to the current working directory, + i.e., the cluster's data directory.) + Use %% if you need to embed an actual % + character in the command. The simplest useful command is something + like: + +archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' # Unix +archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows + + which will copy archivable WAL segments to the directory + /mnt/server/archivedir. (This is an example, not a + recommendation, and might not work on all platforms.) After the + %p and %f parameters have been replaced, + the actual command executed might look like this: + +test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065 + + A similar command will be generated for each new file to be archived. + + + + The archive command will be executed under the ownership of the same + user that the PostgreSQL server is running as. Since + the series of WAL files being archived contains effectively everything + in your database, you will want to be sure that the archived data is + protected from prying eyes; for example, archive into a directory that + does not have group or world read access. + + + + It is important that the archive command return zero exit status if and + only if it succeeds. Upon getting a zero result, + PostgreSQL will assume that the file has been + successfully archived, and will remove or recycle it. However, a nonzero + status tells PostgreSQL that the file was not archived; + it will try again periodically until it succeeds. + + + + When the archive command is terminated by a signal (other than + SIGTERM that is used as part of a server + shutdown) or an error by the shell with an exit status greater than + 125 (such as command not found), the archiver process aborts and gets + restarted by the postmaster. In such cases, the failure is + not reported in . + + + + The archive command should generally be designed to refuse to overwrite + any pre-existing archive file. This is an important safety feature to + preserve the integrity of your archive in case of administrator error + (such as sending the output of two different servers to the same archive + directory). + + + + It is advisable to test your proposed archive command to ensure that it + indeed does not overwrite an existing file, and that it returns + nonzero status in this case. + The example command above for Unix ensures this by including a separate + test step. On some Unix platforms, cp has + switches such as that can be used to do the same thing + less verbosely, but you should not rely on these without verifying that + the right exit status is returned. (In particular, GNU cp + will return status zero when is used and the target file + already exists, which is not the desired behavior.) + + + + While designing your archiving setup, consider what will happen if + the archive command fails repeatedly because some aspect requires + operator intervention or the archive runs out of space. For example, this + could occur if you write to tape without an autochanger; when the tape + fills, nothing further can be archived until the tape is swapped. + You should ensure that any error condition or request to a human operator + is reported appropriately so that the situation can be + resolved reasonably quickly. The pg_wal/ directory will + continue to fill with WAL segment files until the situation is resolved. + (If the file system containing pg_wal/ fills up, + PostgreSQL will do a PANIC shutdown. No committed + transactions will be lost, but the database will remain offline until + you free some space.) + + + + The speed of the archiving command is unimportant as long as it can keep up + with the average rate at which your server generates WAL data. Normal + operation continues even if the archiving process falls a little behind. + If archiving falls significantly behind, this will increase the amount of + data that would be lost in the event of a disaster. It will also mean that + the pg_wal/ directory will contain large numbers of + not-yet-archived segment files, which could eventually exceed available + disk space. You are advised to monitor the archiving process to ensure that + it is working as you intend. + + + + In writing your archive command, you should assume that the file names to + be archived can be up to 64 characters long and can contain any + combination of ASCII letters, digits, and dots. It is not necessary to + preserve the original relative path (%p) but it is necessary to + preserve the file name (%f). + + + + Note that although WAL archiving will allow you to restore any + modifications made to the data in your PostgreSQL database, + it will not restore changes made to configuration files (that is, + postgresql.conf, pg_hba.conf and + pg_ident.conf), since those are edited manually rather + than through SQL operations. + You might wish to keep the configuration files in a location that will + be backed up by your regular file system backup procedures. See + for how to relocate the + configuration files. + + + + The archive command is only invoked on completed WAL segments. Hence, + if your server generates only little WAL traffic (or has slack periods + where it does so), there could be a long delay between the completion + of a transaction and its safe recording in archive storage. To put + a limit on how old unarchived data can be, you can set + to force the server to switch + to a new WAL segment file at least that often. Note that archived + files that are archived early due to a forced switch are still the same + length as completely full files. It is therefore unwise to set a very + short archive_timeout — it will bloat your archive + storage. archive_timeout settings of a minute or so are + usually reasonable. + + + + Also, you can force a segment switch manually with + pg_switch_wal if you want to ensure that a + just-finished transaction is archived as soon as possible. Other utility + functions related to WAL management are listed in . + + + + When wal_level is minimal some SQL commands + are optimized to avoid WAL logging, as described in . If archiving or streaming replication were + turned on during execution of one of these statements, WAL would not + contain enough information for archive recovery. (Crash recovery is + unaffected.) For this reason, wal_level can only be changed at + server start. However, archive_command can be changed with a + configuration file reload. If you wish to temporarily stop archiving, + one way to do it is to set archive_command to the empty + string (''). + This will cause WAL files to accumulate in pg_wal/ until a + working archive_command is re-established. + + + + + Making a Base Backup + + + The easiest way to perform a base backup is to use the + tool. It can create + a base backup either as regular files or as a tar archive. If more + flexibility than can provide is + required, you can also make a base backup using the low level API + (see ). + + + + It is not necessary to be concerned about the amount of time it takes + to make a base backup. However, if you normally run the + server with full_page_writes disabled, you might notice a drop + in performance while the backup runs since full_page_writes is + effectively forced on during backup mode. + + + + To make use of the backup, you will need to keep all the WAL + segment files generated during and after the file system backup. + To aid you in doing this, the base backup process + creates a backup history file that is immediately + stored into the WAL archive area. This file is named after the first + WAL segment file that you need for the file system backup. + For example, if the starting WAL file is + 0000000100001234000055CD the backup history file will be + named something like + 0000000100001234000055CD.007C9330.backup. (The second + part of the file name stands for an exact position within the WAL + file, and can ordinarily be ignored.) Once you have safely archived + the file system backup and the WAL segment files used during the + backup (as specified in the backup history file), all archived WAL + segments with names numerically less are no longer needed to recover + the file system backup and can be deleted. However, you should + consider keeping several backup sets to be absolutely certain that + you can recover your data. + + + + The backup history file is just a small text file. It contains the + label string you gave to , as well as + the starting and ending times and WAL segments of the backup. + If you used the label to identify the associated dump file, + then the archived history file is enough to tell you which dump file to + restore. + + + + Since you have to keep around all the archived WAL files back to your + last base backup, the interval between base backups should usually be + chosen based on how much storage you want to expend on archived WAL + files. You should also consider how long you are prepared to spend + recovering, if recovery should be necessary — the system will have to + replay all those WAL segments, and that could take awhile if it has + been a long time since the last base backup. + + + + + Making a Base Backup Using the Low Level API + + The procedure for making a base backup using the low level + APIs contains a few more steps than + the method, but is relatively + simple. It is very important that these steps are executed in + sequence, and that the success of a step is verified before + proceeding to the next step. + + + Low level base backups can be made in a non-exclusive or an exclusive + way. The non-exclusive method is recommended and the exclusive one is + deprecated and will eventually be removed. + + + + Making a Non-Exclusive Low-Level Backup + + A non-exclusive low level backup is one that allows other + concurrent backups to be running (both those started using + the same backup API and those started using + ). + + + + + + Ensure that WAL archiving is enabled and working. + + + + + Connect to the server (it does not matter which database) as a user with + rights to run pg_start_backup (superuser, or a user who has been granted + EXECUTE on the function) and issue the command: + +SELECT pg_start_backup('label', false, false); + + where label is any string you want to use to uniquely + identify this backup operation. The connection + calling pg_start_backup must be maintained until the end of + the backup, or the backup will be automatically aborted. + + + + By default, pg_start_backup can take a long time to finish. + This is because it performs a checkpoint, and the I/O + required for the checkpoint will be spread out over a significant + period of time, by default half your inter-checkpoint interval + (see the configuration parameter + ). This is + usually what you want, because it minimizes the impact on query + processing. If you want to start the backup as soon as + possible, change the second parameter to true, which will + issue an immediate checkpoint using as much I/O as available. + + + + The third parameter being false tells + pg_start_backup to initiate a non-exclusive base backup. + + + + + Perform the backup, using any convenient file-system-backup tool + such as tar or cpio (not + pg_dump or + pg_dumpall). It is neither + necessary nor desirable to stop normal operation of the database + while you do this. See + for things to + consider during this backup. + + + + + In the same connection as before, issue the command: + +SELECT * FROM pg_stop_backup(false, true); + + This terminates backup mode. On a primary, it also performs an automatic + switch to the next WAL segment. On a standby, it is not possible to + automatically switch WAL segments, so you may wish to run + pg_switch_wal on the primary to perform a manual + switch. The reason for the switch is to arrange for + the last WAL segment file written during the backup interval to be + ready to archive. + + + The pg_stop_backup will return one row with three + values. The second of these fields should be written to a file named + backup_label in the root directory of the backup. The + third field should be written to a file named + tablespace_map unless the field is empty. These files are + vital to the backup working and must be written byte for byte without + modification, which may require opening the file in binary mode. + + + + + Once the WAL segment files active during the backup are archived, you are + done. The file identified by pg_stop_backup's first return + value is the last segment that is required to form a complete set of + backup files. On a primary, if archive_mode is enabled and the + wait_for_archive parameter is true, + pg_stop_backup does not return until the last segment has + been archived. + On a standby, archive_mode must be always in order + for pg_stop_backup to wait. + Archiving of these files happens automatically since you have + already configured archive_command. In most cases this + happens quickly, but you are advised to monitor your archive + system to ensure there are no delays. + If the archive process has fallen behind + because of failures of the archive command, it will keep retrying + until the archive succeeds and the backup is complete. + If you wish to place a time limit on the execution of + pg_stop_backup, set an appropriate + statement_timeout value, but make note that if + pg_stop_backup terminates because of this your backup + may not be valid. + + + If the backup process monitors and ensures that all WAL segment files + required for the backup are successfully archived then the + wait_for_archive parameter (which defaults to true) can be set + to false to have + pg_stop_backup return as soon as the stop backup record is + written to the WAL. By default, pg_stop_backup will wait + until all WAL has been archived, which can take some time. This option + must be used with caution: if WAL archiving is not monitored correctly + then the backup might not include all of the WAL files and will + therefore be incomplete and not able to be restored. + + + + + + + Making an Exclusive Low-Level Backup + + + + The exclusive backup method is deprecated and should be avoided. + Prior to PostgreSQL 9.6, this was the only + low-level method available, but it is now recommended that all users + upgrade their scripts to use non-exclusive backups. + + + + + The process for an exclusive backup is mostly the same as for a + non-exclusive one, but it differs in a few key steps. This type of + backup can only be taken on a primary and does not allow concurrent + backups. Moreover, because it creates a backup label file, as + described below, it can block automatic restart of the primary server + after a crash. On the other hand, the erroneous removal of this + file from a backup or standby is a common mistake, which can result + in serious data corruption. If it is necessary to use this method, + the following steps may be used. + + + + + + Ensure that WAL archiving is enabled and working. + + + + + Connect to the server (it does not matter which database) as a user with + rights to run pg_start_backup (superuser, or a user who has been granted + EXECUTE on the function) and issue the command: + +SELECT pg_start_backup('label'); + + where label is any string you want to use to uniquely + identify this backup operation. + pg_start_backup creates a backup label file, + called backup_label, in the cluster directory with + information about your backup, including the start time and label string. + The function also creates a tablespace map file, + called tablespace_map, in the cluster directory with + information about tablespace symbolic links in pg_tblspc/ if + one or more such link is present. Both files are critical to the + integrity of the backup, should you need to restore from it. + + + + By default, pg_start_backup can take a long time to finish. + This is because it performs a checkpoint, and the I/O + required for the checkpoint will be spread out over a significant + period of time, by default half your inter-checkpoint interval + (see the configuration parameter + ). This is + usually what you want, because it minimizes the impact on query + processing. If you want to start the backup as soon as + possible, use: + +SELECT pg_start_backup('label', true); + + This forces the checkpoint to be done as quickly as possible. + + + + + Perform the backup, using any convenient file-system-backup tool + such as tar or cpio (not + pg_dump or + pg_dumpall). It is neither + necessary nor desirable to stop normal operation of the database + while you do this. See + for things to + consider during this backup. + + + As noted above, if the server crashes during the backup it may not be + possible to restart until the backup_label file has + been manually deleted from the PGDATA directory. Note + that it is very important to never remove the + backup_label file when restoring a backup, because + this will result in corruption. Confusion about when it is appropriate + to remove this file is a common cause of data corruption when using this + method; be very certain that you remove the file only on an existing + primary and never when building a standby or restoring a backup, even if + you are building a standby that will subsequently be promoted to a new + primary. + + + + + Again connect to the database as a user with rights to run + pg_stop_backup (superuser, or a user who has been granted EXECUTE on + the function), and issue the command: + +SELECT pg_stop_backup(); + + This function terminates backup mode and + performs an automatic switch to the next WAL segment. The reason for the + switch is to arrange for the last WAL segment written during the backup + interval to be ready to archive. + + + + + Once the WAL segment files active during the backup are archived, you are + done. The file identified by pg_stop_backup's result is + the last segment that is required to form a complete set of backup files. + If archive_mode is enabled, + pg_stop_backup does not return until the last segment has + been archived. + Archiving of these files happens automatically since you have + already configured archive_command. In most cases this + happens quickly, but you are advised to monitor your archive + system to ensure there are no delays. + If the archive process has fallen behind + because of failures of the archive command, it will keep retrying + until the archive succeeds and the backup is complete. + + + + When using exclusive backup mode, it is absolutely imperative to ensure + that pg_stop_backup completes successfully at the + end of the backup. Even if the backup itself fails, for example due to + lack of disk space, failure to call pg_stop_backup + will leave the server in backup mode indefinitely, causing future backups + to fail and increasing the risk of a restart failure during the time that + backup_label exists. + + + + + + + Backing Up the Data Directory + + Some file system backup tools emit warnings or errors + if the files they are trying to copy change while the copy proceeds. + When taking a base backup of an active database, this situation is normal + and not an error. However, you need to ensure that you can distinguish + complaints of this sort from real errors. For example, some versions + of rsync return a separate exit code for + vanished source files, and you can write a driver script to + accept this exit code as a non-error case. Also, some versions of + GNU tar return an error code indistinguishable from + a fatal error if a file was truncated while tar was + copying it. Fortunately, GNU tar versions 1.16 and + later exit with 1 if a file was changed during the backup, + and 2 for other errors. With GNU tar version 1.23 and + later, you can use the warning options --warning=no-file-changed + --warning=no-file-removed to hide the related warning messages. + + + + Be certain that your backup includes all of the files under + the database cluster directory (e.g., /usr/local/pgsql/data). + If you are using tablespaces that do not reside underneath this directory, + be careful to include them as well (and be sure that your backup + archives symbolic links as links, otherwise the restore will corrupt + your tablespaces). + + + + You should, however, omit from the backup the files within the + cluster's pg_wal/ subdirectory. This + slight adjustment is worthwhile because it reduces the risk + of mistakes when restoring. This is easy to arrange if + pg_wal/ is a symbolic link pointing to someplace outside + the cluster directory, which is a common setup anyway for performance + reasons. You might also want to exclude postmaster.pid + and postmaster.opts, which record information + about the running postmaster, not about the + postmaster which will eventually use this backup. + (These files can confuse pg_ctl.) + + + + It is often a good idea to also omit from the backup the files + within the cluster's pg_replslot/ directory, so that + replication slots that exist on the primary do not become part of the + backup. Otherwise, the subsequent use of the backup to create a standby + may result in indefinite retention of WAL files on the standby, and + possibly bloat on the primary if hot standby feedback is enabled, because + the clients that are using those replication slots will still be connecting + to and updating the slots on the primary, not the standby. Even if the + backup is only intended for use in creating a new primary, copying the + replication slots isn't expected to be particularly useful, since the + contents of those slots will likely be badly out of date by the time + the new primary comes on line. + + + + The contents of the directories pg_dynshmem/, + pg_notify/, pg_serial/, + pg_snapshots/, pg_stat_tmp/, + and pg_subtrans/ (but not the directories themselves) can be + omitted from the backup as they will be initialized on postmaster startup. + If is set and is under the data + directory then the contents of that directory can also be omitted. + + + + Any file or directory beginning with pgsql_tmp can be + omitted from the backup. These files are removed on postmaster start and + the directories will be recreated as needed. + + + + pg_internal.init files can be omitted from the + backup whenever a file of that name is found. These files contain + relation cache data that is always rebuilt when recovering. + + + + The backup label + file includes the label string you gave to pg_start_backup, + as well as the time at which pg_start_backup was run, and + the name of the starting WAL file. In case of confusion it is therefore + possible to look inside a backup file and determine exactly which + backup session the dump file came from. The tablespace map file includes + the symbolic link names as they exist in the directory + pg_tblspc/ and the full path of each symbolic link. + These files are not merely for your information; their presence and + contents are critical to the proper operation of the system's recovery + process. + + + + It is also possible to make a backup while the server is + stopped. In this case, you obviously cannot use + pg_start_backup or pg_stop_backup, and + you will therefore be left to your own devices to keep track of which + backup is which and how far back the associated WAL files go. + It is generally better to follow the continuous archiving procedure above. + + + + + + Recovering Using a Continuous Archive Backup + + + Okay, the worst has happened and you need to recover from your backup. + Here is the procedure: + + + + Stop the server, if it's running. + + + + + If you have the space to do so, + copy the whole cluster data directory and any tablespaces to a temporary + location in case you need them later. Note that this precaution will + require that you have enough free space on your system to hold two + copies of your existing database. If you do not have enough space, + you should at least save the contents of the cluster's pg_wal + subdirectory, as it might contain logs which + were not archived before the system went down. + + + + + Remove all existing files and subdirectories under the cluster data + directory and under the root directories of any tablespaces you are using. + + + + + Restore the database files from your file system backup. Be sure that they + are restored with the right ownership (the database system user, not + root!) and with the right permissions. If you are using + tablespaces, + you should verify that the symbolic links in pg_tblspc/ + were correctly restored. + + + + + Remove any files present in pg_wal/; these came from the + file system backup and are therefore probably obsolete rather than current. + If you didn't archive pg_wal/ at all, then recreate + it with proper permissions, + being careful to ensure that you re-establish it as a symbolic link + if you had it set up that way before. + + + + + If you have unarchived WAL segment files that you saved in step 2, + copy them into pg_wal/. (It is best to copy them, + not move them, so you still have the unmodified files if a + problem occurs and you have to start over.) + + + + + Set recovery configuration settings in + postgresql.conf (see ) and create a file + recovery.signal in the cluster + data directory. You might + also want to temporarily modify pg_hba.conf to prevent + ordinary users from connecting until you are sure the recovery was successful. + + + + + Start the server. The server will go into recovery mode and + proceed to read through the archived WAL files it needs. Should the + recovery be terminated because of an external error, the server can + simply be restarted and it will continue recovery. Upon completion + of the recovery process, the server will remove + recovery.signal (to prevent + accidentally re-entering recovery mode later) and then + commence normal database operations. + + + + + Inspect the contents of the database to ensure you have recovered to + the desired state. If not, return to step 1. If all is well, + allow your users to connect by restoring pg_hba.conf to normal. + + + + + + + The key part of all this is to set up a recovery configuration that + describes how you want to recover and how far the recovery should + run. The one thing that you absolutely must specify is the restore_command, + which tells PostgreSQL how to retrieve archived + WAL file segments. Like the archive_command, this is + a shell command string. It can contain %f, which is + replaced by the name of the desired log file, and %p, + which is replaced by the path name to copy the log file to. + (The path name is relative to the current working directory, + i.e., the cluster's data directory.) + Write %% if you need to embed an actual % + character in the command. The simplest useful command is + something like: + +restore_command = 'cp /mnt/server/archivedir/%f %p' + + which will copy previously archived WAL segments from the directory + /mnt/server/archivedir. Of course, you can use something + much more complicated, perhaps even a shell script that requests the + operator to mount an appropriate tape. + + + + It is important that the command return nonzero exit status on failure. + The command will be called requesting files that are not + present in the archive; it must return nonzero when so asked. This is not + an error condition. An exception is that if the command was terminated by + a signal (other than SIGTERM, which is used as + part of a database server shutdown) or an error by the shell (such as + command not found), then recovery will abort and the server will not start + up. + + + + Not all of the requested files will be WAL segment + files; you should also expect requests for files with a suffix of + .history. Also be aware that + the base name of the %p path will be different from + %f; do not expect them to be interchangeable. + + + + WAL segments that cannot be found in the archive will be sought in + pg_wal/; this allows use of recent un-archived segments. + However, segments that are available from the archive will be used in + preference to files in pg_wal/. + + + + Normally, recovery will proceed through all available WAL segments, + thereby restoring the database to the current point in time (or as + close as possible given the available WAL segments). Therefore, a normal + recovery will end with a file not found message, the exact text + of the error message depending upon your choice of + restore_command. You may also see an error message + at the start of recovery for a file named something like + 00000001.history. This is also normal and does not + indicate a problem in simple recovery situations; see + for discussion. + + + + If you want to recover to some previous point in time (say, right before + the junior DBA dropped your main transaction table), just specify the + required stopping point. You can specify + the stop point, known as the recovery target, either by + date/time, named restore point or by completion of a specific transaction + ID. As of this writing only the date/time and named restore point options + are very usable, since there are no tools to help you identify with any + accuracy which transaction ID to use. + + + + + The stop point must be after the ending time of the base backup, i.e., + the end time of pg_stop_backup. You cannot use a base backup + to recover to a time when that backup was in progress. (To + recover to such a time, you must go back to your previous base backup + and roll forward from there.) + + + + + If recovery finds corrupted WAL data, recovery will + halt at that point and the server will not start. In such a case the + recovery process could be re-run from the beginning, specifying a + recovery target before the point of corruption so that recovery + can complete normally. + If recovery fails for an external reason, such as a system crash or + if the WAL archive has become inaccessible, then the recovery can simply + be restarted and it will restart almost from where it failed. + Recovery restart works much like checkpointing in normal operation: + the server periodically forces all its state to disk, and then updates + the pg_control file to indicate that the already-processed + WAL data need not be scanned again. + + + + + + Timelines + + + timelines + + + + The ability to restore the database to a previous point in time creates + some complexities that are akin to science-fiction stories about time + travel and parallel universes. For example, in the original history of the database, + suppose you dropped a critical table at 5:15PM on Tuesday evening, but + didn't realize your mistake until Wednesday noon. + Unfazed, you get out your backup, restore to the point-in-time 5:14PM + Tuesday evening, and are up and running. In this history of + the database universe, you never dropped the table. But suppose + you later realize this wasn't such a great idea, and would like + to return to sometime Wednesday morning in the original history. + You won't be able + to if, while your database was up-and-running, it overwrote some of the + WAL segment files that led up to the time you now wish you + could get back to. Thus, to avoid this, you need to distinguish the series of + WAL records generated after you've done a point-in-time recovery from + those that were generated in the original database history. + + + + To deal with this problem, PostgreSQL has a notion + of timelines. Whenever an archive recovery completes, + a new timeline is created to identify the series of WAL records + generated after that recovery. The timeline + ID number is part of WAL segment file names so a new timeline does + not overwrite the WAL data generated by previous timelines. It is + in fact possible to archive many different timelines. While that might + seem like a useless feature, it's often a lifesaver. Consider the + situation where you aren't quite sure what point-in-time to recover to, + and so have to do several point-in-time recoveries by trial and error + until you find the best place to branch off from the old history. Without + timelines this process would soon generate an unmanageable mess. With + timelines, you can recover to any prior state, including + states in timeline branches that you abandoned earlier. + + + + Every time a new timeline is created, PostgreSQL creates + a timeline history file that shows which timeline it branched + off from and when. These history files are necessary to allow the system + to pick the right WAL segment files when recovering from an archive that + contains multiple timelines. Therefore, they are archived into the WAL + archive area just like WAL segment files. The history files are just + small text files, so it's cheap and appropriate to keep them around + indefinitely (unlike the segment files which are large). You can, if + you like, add comments to a history file to record your own notes about + how and why this particular timeline was created. Such comments will be + especially valuable when you have a thicket of different timelines as + a result of experimentation. + + + + The default behavior of recovery is to recover to the latest timeline found + in the archive. If you wish to recover to the timeline that was current + when the base backup was taken or into a specific child timeline (that + is, you want to return to some state that was itself generated after a + recovery attempt), you need to specify current or the + target timeline ID in . You + cannot recover into timelines that branched off earlier than the base backup. + + + + + Tips and Examples + + + Some tips for configuring continuous archiving are given here. + + + + Standalone Hot Backups + + + It is possible to use PostgreSQL's backup facilities to + produce standalone hot backups. These are backups that cannot be used + for point-in-time recovery, yet are typically much faster to backup and + restore than pg_dump dumps. (They are also much larger + than pg_dump dumps, so in some cases the speed advantage + might be negated.) + + + + As with base backups, the easiest way to produce a standalone + hot backup is to use the + tool. If you include the -X parameter when calling + it, all the write-ahead log required to use the backup will be + included in the backup automatically, and no special action is + required to restore the backup. + + + + If more flexibility in copying the backup files is needed, a lower + level process can be used for standalone hot backups as well. + To prepare for low level standalone hot backups, make sure + wal_level is set to + replica or higher, archive_mode to + on, and set up an archive_command that performs + archiving only when a switch file exists. For example: + +archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress || (test ! -f /var/lib/pgsql/archive/%f && cp %p /var/lib/pgsql/archive/%f)' + + This command will perform archiving when + /var/lib/pgsql/backup_in_progress exists, and otherwise + silently return zero exit status (allowing PostgreSQL + to recycle the unwanted WAL file). + + + + With this preparation, a backup can be taken using a script like the + following: + +touch /var/lib/pgsql/backup_in_progress +psql -c "select pg_start_backup('hot_backup');" +tar -cf /var/lib/pgsql/backup.tar /var/lib/pgsql/data/ +psql -c "select pg_stop_backup();" +rm /var/lib/pgsql/backup_in_progress +tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/ + + The switch file /var/lib/pgsql/backup_in_progress is + created first, enabling archiving of completed WAL files to occur. + After the backup the switch file is removed. Archived WAL files are + then added to the backup so that both base backup and all required + WAL files are part of the same tar file. + Please remember to add error handling to your backup scripts. + + + + + + Compressed Archive Logs + + + If archive storage size is a concern, you can use + gzip to compress the archive files: + +archive_command = 'gzip < %p > /mnt/server/archivedir/%f.gz' + + You will then need to use gunzip during recovery: + +restore_command = 'gunzip < /mnt/server/archivedir/%f.gz > %p' + + + + + + <varname>archive_command</varname> Scripts + + + Many people choose to use scripts to define their + archive_command, so that their + postgresql.conf entry looks very simple: + +archive_command = 'local_backup_script.sh "%p" "%f"' + + Using a separate script file is advisable any time you want to use + more than a single command in the archiving process. + This allows all complexity to be managed within the script, which + can be written in a popular scripting language such as + bash or perl. + + + + Examples of requirements that might be solved within a script include: + + + + Copying data to secure off-site data storage + + + + + Batching WAL files so that they are transferred every three hours, + rather than one at a time + + + + + Interfacing with other backup and recovery software + + + + + Interfacing with monitoring software to report errors + + + + + + + + When using an archive_command script, it's desirable + to enable . + Any messages written to stderr from the script will then + appear in the database server log, allowing complex configurations to + be diagnosed easily if they fail. + + + + + + + Caveats + + + At this writing, there are several limitations of the continuous archiving + technique. These will probably be fixed in future releases: + + + + + If a CREATE DATABASE + command is executed while a base backup is being taken, and then + the template database that the CREATE DATABASE copied + is modified while the base backup is still in progress, it is + possible that recovery will cause those modifications to be + propagated into the created database as well. This is of course + undesirable. To avoid this risk, it is best not to modify any + template databases while taking a base backup. + + + + + + CREATE TABLESPACE + commands are WAL-logged with the literal absolute path, and will + therefore be replayed as tablespace creations with the same + absolute path. This might be undesirable if the log is being + replayed on a different machine. It can be dangerous even if the + log is being replayed on the same machine, but into a new data + directory: the replay will still overwrite the contents of the + original tablespace. To avoid potential gotchas of this sort, + the best practice is to take a new base backup after creating or + dropping tablespaces. + + + + + + + It should also be noted that the default WAL + format is fairly bulky since it includes many disk page snapshots. + These page snapshots are designed to support crash recovery, since + we might need to fix partially-written disk pages. Depending on + your system hardware and software, the risk of partial writes might + be small enough to ignore, in which case you can significantly + reduce the total volume of archived logs by turning off page + snapshots using the + parameter. (Read the notes and warnings in + before you do so.) Turning off page snapshots does not prevent + use of the logs for PITR operations. An area for future + development is to compress archived WAL data by removing + unnecessary page copies even when full_page_writes is + on. In the meantime, administrators might wish to reduce the number + of page snapshots included in WAL by increasing the checkpoint + interval parameters as much as feasible. + + + + + diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml new file mode 100644 index 000000000000..7fd673ab54ee --- /dev/null +++ b/doc/src/sgml/bgworker.sgml @@ -0,0 +1,308 @@ + + + + Background Worker Processes + + + Background workers + + + + PostgreSQL can be extended to run user-supplied code in separate processes. + Such processes are started, stopped and monitored by postgres, + which permits them to have a lifetime closely linked to the server's status. + These processes have the option to attach to PostgreSQL's + shared memory area and to connect to databases internally; they can also run + multiple transactions serially, just like a regular client-connected server + process. Also, by linking to libpq they can connect to the + server and behave like a regular client application. + + + + + There are considerable robustness and security risks in using background + worker processes because, being written in the C language, + they have unrestricted access to data. Administrators wishing to enable + modules that include background worker processes should exercise extreme + caution. Only carefully audited modules should be permitted to run + background worker processes. + + + + + Background workers can be initialized at the time that + PostgreSQL is started by including the module name in + shared_preload_libraries. A module wishing to run a background + worker can register it by calling + RegisterBackgroundWorker(BackgroundWorker + *worker) + from its _PG_init() function. + Background workers can also be started + after the system is up and running by calling + RegisterDynamicBackgroundWorker(BackgroundWorker + *worker, BackgroundWorkerHandle + **handle). Unlike + RegisterBackgroundWorker, which can only be called from + within the postmaster process, + RegisterDynamicBackgroundWorker must be called + from a regular backend or another background worker. + + + + The structure BackgroundWorker is defined thus: + +typedef void (*bgworker_main_type)(Datum main_arg); +typedef struct BackgroundWorker +{ + char bgw_name[BGW_MAXLEN]; + char bgw_type[BGW_MAXLEN]; + int bgw_flags; + BgWorkerStartTime bgw_start_time; + int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */ + char bgw_library_name[BGW_MAXLEN]; + char bgw_function_name[BGW_MAXLEN]; + Datum bgw_main_arg; + char bgw_extra[BGW_EXTRALEN]; + int bgw_notify_pid; +} BackgroundWorker; + + + + + bgw_name and bgw_type are + strings to be used in log messages, process listings and similar contexts. + bgw_type should be the same for all background + workers of the same type, so that it is possible to group such workers in a + process listing, for example. bgw_name on the + other hand can contain additional information about the specific process. + (Typically, the string for bgw_name will contain + the type somehow, but that is not strictly required.) + + + + bgw_flags is a bitwise-or'd bit mask indicating the + capabilities that the module wants. Possible values are: + + + + BGWORKER_SHMEM_ACCESS + + + BGWORKER_SHMEM_ACCESS + Requests shared memory access. Workers without shared memory access + cannot access any of PostgreSQL's shared + data structures, such as heavyweight or lightweight locks, shared + buffers, or any custom data structures which the worker itself may + wish to create and use. + + + + + + BGWORKER_BACKEND_DATABASE_CONNECTION + + + BGWORKER_BACKEND_&zwsp;DATABASE_CONNECTION + Requests the ability to establish a database connection through which it + can later run transactions and queries. A background worker using + BGWORKER_BACKEND_DATABASE_CONNECTION to connect to a + database must also attach shared memory using + BGWORKER_SHMEM_ACCESS, or worker start-up will fail. + + + + + + + + + + bgw_start_time is the server state during which + postgres should start the process; it can be one of + BgWorkerStart_PostmasterStart (start as soon as + postgres itself has finished its own initialization; processes + requesting this are not eligible for database connections), + BgWorkerStart_ConsistentState (start as soon as a consistent state + has been reached in a hot standby, allowing processes to connect to + databases and run read-only queries), and + BgWorkerStart_RecoveryFinished (start as soon as the system has + entered normal read-write state). Note the last two values are equivalent + in a server that's not a hot standby. Note that this setting only indicates + when the processes are to be started; they do not stop when a different state + is reached. + + + + bgw_restart_time is the interval, in seconds, that + postgres should wait before restarting the process, in + case it crashes. It can be any positive value, + or BGW_NEVER_RESTART, indicating not to restart the + process in case of a crash. + + + + bgw_library_name is the name of a library in + which the initial entry point for the background worker should be sought. + The named library will be dynamically loaded by the worker process and + bgw_function_name will be used to identify the + function to be called. If loading a function from the core code, this must + be set to "postgres". + + + + bgw_function_name is the name of a function in + a dynamically loaded library which should be used as the initial entry point + for a new background worker. + + + + bgw_main_arg is the Datum argument + to the background worker main function. This main function should take a + single argument of type Datum and return void. + bgw_main_arg will be passed as the argument. + In addition, the global variable MyBgworkerEntry + points to a copy of the BackgroundWorker structure + passed at registration time; the worker may find it helpful to examine + this structure. + + + + On Windows (and anywhere else where EXEC_BACKEND is + defined) or in dynamic background workers it is not safe to pass a + Datum by reference, only by value. If an argument is required, it + is safest to pass an int32 or other small value and use that as an index + into an array allocated in shared memory. If a value like a cstring + or text is passed then the pointer won't be valid from the + new background worker process. + + + + bgw_extra can contain extra data to be passed + to the background worker. Unlike bgw_main_arg, this data + is not passed as an argument to the worker's main function, but it can be + accessed via MyBgworkerEntry, as discussed above. + + + + bgw_notify_pid is the PID of a PostgreSQL + backend process to which the postmaster should send SIGUSR1 + when the process is started or exits. It should be 0 for workers registered + at postmaster startup time, or when the backend registering the worker does + not wish to wait for the worker to start up. Otherwise, it should be + initialized to MyProcPid. + + + Once running, the process can connect to a database by calling + BackgroundWorkerInitializeConnection(char *dbname, char *username, uint32 flags) or + BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags). + This allows the process to run transactions and queries using the + SPI interface. If dbname is NULL or + dboid is InvalidOid, the session is not connected + to any particular database, but shared catalogs can be accessed. + If username is NULL or useroid is + InvalidOid, the process will run as the superuser created + during initdb. If BGWORKER_BYPASS_ALLOWCONN + is specified as flags it is possible to bypass the restriction + to connect to databases not allowing user connections. + A background worker can only call one of these two functions, and only + once. It is not possible to switch databases. + + + + Signals are initially blocked when control reaches the + background worker's main function, and must be unblocked by it; this is to + allow the process to customize its signal handlers, if necessary. + Signals can be unblocked in the new process by calling + BackgroundWorkerUnblockSignals and blocked by calling + BackgroundWorkerBlockSignals. + + + + If bgw_restart_time for a background worker is + configured as BGW_NEVER_RESTART, or if it exits with an exit + code of 0 or is terminated by TerminateBackgroundWorker, + it will be automatically unregistered by the postmaster on exit. + Otherwise, it will be restarted after the time period configured via + bgw_restart_time, or immediately if the postmaster + reinitializes the cluster due to a backend failure. Backends which need + to suspend execution only temporarily should use an interruptible sleep + rather than exiting; this can be achieved by calling + WaitLatch(). Make sure the + WL_POSTMASTER_DEATH flag is set when calling that function, and + verify the return code for a prompt exit in the emergency case that + postgres itself has terminated. + + + + When a background worker is registered using the + RegisterDynamicBackgroundWorker function, it is + possible for the backend performing the registration to obtain information + regarding the status of the worker. Backends wishing to do this should + pass the address of a BackgroundWorkerHandle * as the second + argument to RegisterDynamicBackgroundWorker. If the + worker is successfully registered, this pointer will be initialized with an + opaque handle that can subsequently be passed to + GetBackgroundWorkerPid(BackgroundWorkerHandle *, pid_t *) or + TerminateBackgroundWorker(BackgroundWorkerHandle *). + GetBackgroundWorkerPid can be used to poll the status of the + worker: a return value of BGWH_NOT_YET_STARTED indicates that + the worker has not yet been started by the postmaster; + BGWH_STOPPED indicates that it has been started but is + no longer running; and BGWH_STARTED indicates that it is + currently running. In this last case, the PID will also be returned via the + second argument. + TerminateBackgroundWorker causes the postmaster to send + SIGTERM to the worker if it is running, and to unregister it + as soon as it is not. + + + + In some cases, a process which registers a background worker may wish to + wait for the worker to start up. This can be accomplished by initializing + bgw_notify_pid to MyProcPid and + then passing the BackgroundWorkerHandle * obtained at + registration time to + WaitForBackgroundWorkerStartup(BackgroundWorkerHandle + *handle, pid_t *) function. + This function will block until the postmaster has attempted to start the + background worker, or until the postmaster dies. If the background worker + is running, the return value will be BGWH_STARTED, and + the PID will be written to the provided address. Otherwise, the return + value will be BGWH_STOPPED or + BGWH_POSTMASTER_DIED. + + + + A process can also wait for a background worker to shut down, by using the + WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle + *handle) function and passing the + BackgroundWorkerHandle * obtained at registration. This + function will block until the background worker exits, or postmaster dies. + When the background worker exits, the return value is + BGWH_STOPPED, if postmaster dies it will return + BGWH_POSTMASTER_DIED. + + + + If a background worker sends asynchronous notifications with the + NOTIFY command via the Server Programming Interface + (SPI), it should call + ProcessCompletedNotifies explicitly after committing + the enclosing transaction so that any notifications can be delivered. If a + background worker registers to receive asynchronous notifications with + the LISTEN through SPI, the worker + will log those notifications, but there is no programmatic way for the + worker to intercept and respond to those notifications. + + + + The src/test/modules/worker_spi module + contains a working example, + which demonstrates some useful techniques. + + + + The maximum number of registered background workers is limited by + . + + diff --git a/doc/src/sgml/biblio.sgml b/doc/src/sgml/biblio.sgml new file mode 100644 index 000000000000..73a21b6add1b --- /dev/null +++ b/doc/src/sgml/biblio.sgml @@ -0,0 +1,550 @@ + + + + Bibliography + + + Selected references and readings for SQL + and PostgreSQL. + + + + Some white papers and technical reports from the original + POSTGRES development team + are available at the University of California, Berkeley, Computer Science + Department web site. + + + + <acronym>SQL</acronym> Reference Books + + + The Practical <acronym>SQL</acronym> Handbook + Using SQL Variants + Fourth Edition + + + Judith + Bowman + + + Sandra + Emerson + + + Marcy + Darnovsky + + + 0-201-70309-2 + + Addison-Wesley Professional + + 2001 + + + + A Guide to the <acronym>SQL</acronym> Standard + A user's guide to the standard database language SQL + Fourth Edition + + + C. J. + Date + + + Hugh + Darwen + + + 0-201-96426-0 + + Addison-Wesley + + 1997 + + + + An Introduction to Database Systems + Eighth Edition + + + C. J. + Date + + + 0-321-19784-4 + + Addison-Wesley + + 2003 + + + + Fundamentals of Database Systems + Fourth Edition + + + Ramez + Elmasri + + + Shamkant + Navathe + + + 0-321-12226-7 + + Addison-Wesley + + 2003 + + + + Understanding the New <acronym>SQL</acronym> + A complete guide + + + Jim + Melton + + + Alan R. + Simon + + + 1-55860-245-3 + + Morgan Kaufmann + + 1993 + + + + Principles of Database and Knowledge-Base Systems + Classical Database Systems + + + Jeffrey D. + Ullman + + + Volume 1 + + Computer Science Press + + 1988 + + + + <ulink url="https://standards.iso.org/ittf/PubliclyAvailableStandards/c067367_ISO_IEC_TR_19075-6_2017.zip">SQL Technical Report</ulink> + Part 6: SQL support for JavaScript Object + Notation (JSON) + First Edition + 2017 + + + + + + PostgreSQL-specific Documentation + + + Enhancement of the ANSI SQL Implementation of PostgreSQL + + + Stefan + Simkovics + + + + + + + Discusses SQL history and syntax, and describes the addition of + INTERSECT and EXCEPT constructs into + PostgreSQL. Prepared as a Master's + Thesis with the support of O. Univ. Prof. Dr. Georg Gottlob and + Univ. Ass. Mag. Katrin Seyr at Vienna University of Technology. + + + + + Department of Information Systems, Vienna University of Technology +
Vienna, Austria
+
+ November 29, 1998 +
+ + + The <productname>Postgres95</productname> User Manual + + + A. + Yu + + + J. + Chen + + + + University of California +
Berkeley, California
+
+ Sept. 5, 1995 +
+ + + <ulink url="https://dsf.berkeley.edu/papers/UCB-MS-zfong.pdf">The + design and implementation of the <productname>POSTGRES</productname> query + optimizer</ulink> + + Zelaine + Fong + + + University of California, Berkeley, Computer Science Department + + + +
+ + + Proceedings and Articles + + + + <ulink url="https://arxiv.org/pdf/1208.4179">Serializable Snapshot Isolation in PostgreSQL</ulink> + + + D. + Ports + + + K. + Grittner + + + + + VLDB Conference + August 2012 +
Istanbul, Turkey
+
+
+ + + + <ulink url="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-95-51.pdf">A Critique of ANSI SQL Isolation Levels</ulink> + + + H. + Berenson + + + P. + Bernstein + + + J. + Gray + + + J. + Melton + + + E. + O'Neil + + + P. + O'Neil + + + + + ACM-SIGMOD Conference on Management of Data + June 1995 +
San Jose, California
+
+
+ + + Partial indexing in POSTGRES: research project + + + Nels + Olson + + + UCB Engin T7.49.1993 O676 + + University of California +
Berkeley, California
+
+ 1993 +
+ + + + A Unified Framework for Version Modeling Using Production Rules in a Database System + + + L. + Ong + + + J. + Goh + + + + + ERL Technical Memorandum M90/33 + + University of California +
Berkeley, California
+
+ April, 1990 +
+
+ + + + <ulink url="https://dsf.berkeley.edu/papers/ERL-M87-13.pdf">The <productname>POSTGRES</productname> + data model</ulink> + + + L. + Rowe + + + M. + Stonebraker + + + + + VLDB Conference + Sept. 1987 +
Brighton, England
+
+
+ + + + <ulink url="https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.40.5740">Generalized + Partial Indexes</ulink> + + + P. + Seshadri + + + A. + Swami + + + + + Eleventh International Conference on Data Engineering + 6–10 March 1995 +
Taipeh, Taiwan
+
+ Cat. No.95CH35724 + + IEEE Computer Society Press +
Los Alamitos, California
+
+ 1995 + 420–7 +
+ + + + <ulink url="https://dsf.berkeley.edu/papers/ERL-M85-95.pdf">The + design of <productname>POSTGRES</productname></ulink> + + + M. + Stonebraker + + + L. + Rowe + + + + + ACM-SIGMOD Conference on Management of Data + May 1986 +
Washington, DC
+
+
+ + + + The design of the <productname>POSTGRES</productname> rules system + + + M. + Stonebraker + + + E. + Hanson + + + C. H. + Hong + + + + + IEEE Conference on Data Engineering + Feb. 1987 +
Los Angeles, California
+
+
+ + + + <ulink url="https://dsf.berkeley.edu/papers/ERL-M87-06.pdf">The + design of the <productname>POSTGRES</productname> storage + system</ulink> + + + M. + Stonebraker + + + + + VLDB Conference + Sept. 1987 +
Brighton, England
+
+
+ + + + <ulink url="https://dsf.berkeley.edu/papers/ERL-M89-82.pdf">A + commentary on the <productname>POSTGRES</productname> rules + system</ulink> + + + M. + Stonebraker + + + M. + Hearst + + + S. + Potamianos + + + + + SIGMOD Record 18(3) + Sept. 1989 + + + + + + <ulink url="https://dsf.berkeley.edu/papers/ERL-M89-17.pdf">The + case for partial indexes</ulink> + + + M. + Stonebraker + + + + + SIGMOD Record 18(4) + Dec. 1989 + 4–11 + + + + + + <ulink url="https://dsf.berkeley.edu/papers/ERL-M90-34.pdf">The + implementation of <productname>POSTGRES</productname></ulink> + + + M. + Stonebraker + + + L. A. + Rowe + + + M. + Hirohama + + + + + Transactions on Knowledge and Data Engineering 2(1) + + IEEE + + March 1990 + + + + + + <ulink url="https://dsf.berkeley.edu/papers/ERL-M90-36.pdf">On + Rules, Procedures, Caching and Views in Database Systems</ulink> + + + M. + Stonebraker + + + A. + Jhingran + + + J. + Goh + + + S. + Potamianos + + + + + ACM-SIGMOD Conference on Management of Data + June 1990 + + + +
+
diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml new file mode 100644 index 000000000000..db1b3d5e9a02 --- /dev/null +++ b/doc/src/sgml/bki.sgml @@ -0,0 +1,1063 @@ + + + + System Catalog Declarations and Initial Contents + + + PostgreSQL uses many different system catalogs + to keep track of the existence and properties of database objects, such as + tables and functions. Physically there is no difference between a system + catalog and a plain user table, but the backend C code knows the structure + and properties of each catalog, and can manipulate it directly at a low + level. Thus, for example, it is inadvisable to attempt to alter the + structure of a catalog on-the-fly; that would break assumptions built into + the C code about how rows of the catalog are laid out. But the structure + of the catalogs can change between major versions. + + + + The structures of the catalogs are declared in specially formatted C + header files in the src/include/catalog/ directory of + the source tree. For each catalog there is a header file + named after the catalog (e.g., pg_class.h + for pg_class), which defines the set of columns + the catalog has, as well as some other basic properties such as its OID. + + + + Many of the catalogs have initial data that must be loaded into them + during the bootstrap phase + of initdb, to bring the system up to a point + where it is capable of executing SQL commands. (For + example, pg_class.h must contain an entry for itself, + as well as one for each other system catalog and index.) This + initial data is kept in editable form in data files that are also stored + in the src/include/catalog/ directory. For example, + pg_proc.dat describes all the initial rows that must + be inserted into the pg_proc catalog. + + + + To create the catalog files and load this initial data into them, a + backend running in bootstrap mode reads a BKI + (Backend Interface) file containing commands and initial data. + The postgres.bki file used in this mode is prepared + from the aforementioned header and data files, while building + a PostgreSQL distribution, by a Perl script + named genbki.pl. + Although it's specific to a particular PostgreSQL + release, postgres.bki is platform-independent and is + installed in the share subdirectory of the + installation tree. + + + + genbki.pl also produces a derived header file for + each catalog, for example pg_class_d.h for + the pg_class catalog. This file contains + automatically-generated macro definitions, and may contain other macros, + enum declarations, and so on that can be useful for client C code that + reads a particular catalog. + + + + Most PostgreSQL developers don't need to be directly concerned with + the BKI file, but almost any nontrivial feature + addition in the backend will require modifying the catalog header files + and/or initial data files. The rest of this chapter gives some + information about that, and for completeness describes + the BKI file format. + + + + System Catalog Declaration Rules + + + The key part of a catalog header file is a C structure definition + describing the layout of each row of the catalog. This begins with + a CATALOG macro, which so far as the C compiler is + concerned is just shorthand for typedef struct + FormData_catalogname. + Each field in the struct gives rise to a catalog column. + Fields can be annotated using the BKI property macros described + in genbki.h, for example to define a default value + for a field or mark it as nullable or not nullable. + The CATALOG line can also be annotated, with some + other BKI property macros described in genbki.h, to + define other properties of the catalog as a whole, such as whether + it is a shared relation. + + + + The system catalog cache code (and most catalog-munging code in general) + assumes that the fixed-length portions of all system catalog tuples are + in fact present, because it maps this C struct declaration onto them. + Thus, all variable-length fields and nullable fields must be placed at + the end, and they cannot be accessed as struct fields. + For example, if you tried to + set pg_type.typrelid + to be NULL, it would fail when some piece of code tried to reference + typetup->typrelid (or worse, + typetup->typelem, because that follows + typrelid). This would result in + random errors or even segmentation violations. + + + + As a partial guard against this type of error, variable-length or + nullable fields should not be made directly visible to the C compiler. + This is accomplished by wrapping them in #ifdef + CATALOG_VARLEN ... #endif (where + CATALOG_VARLEN is a symbol that is never defined). + This prevents C code from carelessly trying to access fields that might + not be there or might be at some other offset. + As an independent guard against creating incorrect rows, we + require all columns that should be non-nullable to be marked so + in pg_attribute. The bootstrap code will + automatically mark catalog columns as NOT NULL + if they are fixed-width and are not preceded by any nullable or + variable-width column. + Where this rule is inadequate, you can force correct marking by using + BKI_FORCE_NOT_NULL + and BKI_FORCE_NULL annotations as needed. + + + + Frontend code should not include any pg_xxx.h + catalog header file, as these files may contain C code that won't compile + outside the backend. (Typically, that happens because these files also + contain declarations for functions + in src/backend/catalog/ files.) + Instead, frontend code may include the corresponding + generated pg_xxx_d.h header, which will contain + OID #defines and any other data that might be of use + on the client side. If you want macros or other code in a catalog header + to be visible to frontend code, write #ifdef + EXPOSE_TO_CLIENT_CODE ... #endif around that + section to instruct genbki.pl to copy that section + to the pg_xxx_d.h header. + + + + A few of the catalogs are so fundamental that they can't even be created + by the BKI create command that's + used for most catalogs, because that command needs to write information + into these catalogs to describe the new catalog. These are + called bootstrap catalogs, and defining one takes + a lot of extra work: you have to manually prepare appropriate entries for + them in the pre-loaded contents of pg_class + and pg_type, and those entries will need to be + updated for subsequent changes to the catalog's structure. + (Bootstrap catalogs also need pre-loaded entries + in pg_attribute, but + fortunately genbki.pl handles that chore nowadays.) + Avoid making new catalogs be bootstrap catalogs if at all possible. + + + + + System Catalog Initial Data + + + Each catalog that has any manually-created initial data (some do not) + has a corresponding .dat file that contains its + initial data in an editable format. + + + + Data File Format + + + Each .dat file contains Perl data structure literals + that are simply eval'd to produce an in-memory data structure consisting + of an array of hash references, one per catalog row. + A slightly modified excerpt from pg_database.dat + will demonstrate the key features: + + + +[ + +# A comment could appear here. +{ oid => '1', oid_symbol => 'TemplateDbOid', + descr => 'database\'s default template', + datname => 'template1', encoding => 'ENCODING', datcollate => 'LC_COLLATE', + datctype => 'LC_CTYPE', datistemplate => 't', datallowconn => 't', + datconnlimit => '-1', datlastsysoid => '0', datfrozenxid => '0', + datminmxid => '1', dattablespace => 'pg_default', datacl => '_null_' }, + +] + + + + Points to note: + + + + + + + The overall file layout is: open square bracket, one or more sets of + curly braces each of which represents a catalog row, close square + bracket. Write a comma after each closing curly brace. + + + + + + Within each catalog row, write comma-separated + key => + value pairs. The + allowed keys are the names of the catalog's + columns, plus the metadata keys oid, + oid_symbol, + array_type_oid, and descr. + (The use of oid and oid_symbol + is described in below, + while array_type_oid is described in + . + descr supplies a description string for the object, + which will be inserted into pg_description + or pg_shdescription as appropriate.) + While the metadata keys are optional, the catalog's defined columns + must all be provided, except when the catalog's .h + file specifies a default value for the column. + (In the example above, the datdba field has + been omitted because pg_database.h supplies a + suitable default value for it.) + + + + + + All values must be single-quoted. Escape single quotes used within a + value with a backslash. Backslashes meant as data can, but need not, + be doubled; this follows Perl's rules for simple quoted literals. + Note that backslashes appearing as data will be treated as escapes by + the bootstrap scanner, according to the same rules as for escape string + constants (see ); for + example \t converts to a tab character. If you + actually want a backslash in the final value, you will need to write + four of them: Perl strips two, leaving \\ for the + bootstrap scanner to see. + + + + + + Null values are represented by _null_. + (Note that there is no way to create a value that is just that + string.) + + + + + + Comments are preceded by #, and must be on their + own lines. + + + + + + Field values that are OIDs of other catalog entries should be + represented by symbolic names rather than actual numeric OIDs. + (In the example above, dattablespace + contains such a reference.) + This is described in + below. + + + + + + Since hashes are unordered data structures, field order and line + layout aren't semantically significant. However, to maintain a + consistent appearance, we set a few rules that are applied by the + formatting script reformat_dat_file.pl: + + + + + + Within each pair of curly braces, the metadata + fields oid, oid_symbol, + array_type_oid, and descr + (if present) come first, in that order, then the catalog's own + fields appear in their defined order. + + + + + + Newlines are inserted between fields as needed to limit line length + to 80 characters, if possible. A newline is also inserted between + the metadata fields and the regular fields. + + + + + + If the catalog's .h file specifies a default + value for a column, and a data entry has that same + value, reformat_dat_file.pl will omit it from + the data file. This keeps the data representation compact. + + + + + + reformat_dat_file.pl preserves blank lines + and comment lines as-is. + + + + + + It's recommended to run reformat_dat_file.pl + before submitting catalog data patches. For convenience, you can + simply change to src/include/catalog/ and + run make reformat-dat-files. + + + + + + If you want to add a new method of making the data representation + smaller, you must implement it + in reformat_dat_file.pl and also + teach Catalog::ParseData() how to expand the + data back into the full representation. + + + + + + + + OID Assignment + + + A catalog row appearing in the initial data can be given a + manually-assigned OID by writing an oid + => nnnn metadata field. + Furthermore, if an OID is assigned, a C macro for that OID can be + created by writing an oid_symbol + => name metadata field. + + + + Pre-loaded catalog rows must have preassigned OIDs if there are OID + references to them in other pre-loaded rows. A preassigned OID is + also needed if the row's OID must be referenced from C code. + If neither case applies, the oid metadata field can + be omitted, in which case the bootstrap code assigns an OID + automatically. + In practice we usually preassign OIDs for all or none of the pre-loaded + rows in a given catalog, even if only some of them are actually + cross-referenced. + + + + Writing the actual numeric value of any OID in C code is considered + very bad form; always use a macro, instead. Direct references + to pg_proc OIDs are common enough that there's + a special mechanism to create the necessary macros automatically; + see src/backend/utils/Gen_fmgrtab.pl. Similarly + — but, for historical reasons, not done the same way — + there's an automatic method for creating macros + for pg_type + OIDs. oid_symbol entries are therefore not + necessary in those two catalogs. Likewise, macros for + the pg_class OIDs of system catalogs and + indexes are set up automatically. For all other system catalogs, you + have to manually specify any macros you need + via oid_symbol entries. + + + + To find an available OID for a new pre-loaded row, run the + script src/include/catalog/unused_oids. + It prints inclusive ranges of unused OIDs (e.g., the output + line 45-900 means OIDs 45 through 900 have not been + allocated yet). Currently, OIDs 1–9999 are reserved for manual + assignment; the unused_oids script simply looks + through the catalog headers and .dat files + to see which ones do not appear. You can also use + the duplicate_oids script to check for mistakes. + (genbki.pl will assign OIDs for any rows that + didn't get one hand-assigned to them, and it will also detect duplicate + OIDs at compile time.) + + + + When choosing OIDs for a patch that is not expected to be committed + immediately, best practice is to use a group of more-or-less + consecutive OIDs starting with some random choice in the range + 8000—9999. This minimizes the risk of OID collisions with other + patches being developed concurrently. To keep the 8000—9999 + range free for development purposes, after a patch has been committed + to the master git repository its OIDs should be renumbered into + available space below that range. Typically, this will be done + near the end of each development cycle, moving all OIDs consumed by + patches committed in that cycle at the same time. The script + renumber_oids.pl can be used for this purpose. + If an uncommitted patch is found to have OID conflicts with some + recently-committed patch, renumber_oids.pl may + also be useful for recovering from that situation. + + + + Because of this convention of possibly renumbering OIDs assigned by + patches, the OIDs assigned by a patch should not be considered stable + until the patch has been included in an official release. We do not + change manually-assigned object OIDs once released, however, as that + would create assorted compatibility problems. + + + + If genbki.pl needs to assign an OID to a catalog + entry that does not have a manually-assigned OID, it will use a value in + the range 10000—11999. The server's OID counter is set to 12000 + at the start of a bootstrap run. Thus objects created by regular SQL + commands during the later phases of bootstrap, such as objects created + while running the information_schema.sql script, + receive OIDs of 12000 or above. + + + + OIDs assigned during normal database operation are constrained to be + 16384 or higher. This ensures that the range 10000—16383 is free + for OIDs assigned automatically by genbki.pl or + during bootstrap. These automatically-assigned OIDs are not considered + stable, and may change from one installation to another. + + + + + OID Reference Lookup + + + In principle, cross-references from one initial catalog row to another + could be written just by writing the preassigned OID of the referenced + row in the referencing field. However, that is against project + policy, because it is error-prone, hard to read, and subject to + breakage if a newly-assigned OID is renumbered. Therefore + genbki.pl provides mechanisms to write + symbolic references instead. + The rules are as follows: + + + + + + + Use of symbolic references is enabled in a particular catalog column + by attaching BKI_LOOKUP(lookuprule) + to the column's definition, where lookuprule + is the name of the referenced catalog, e.g., pg_proc. + BKI_LOOKUP can be attached to columns of + type Oid, regproc, oidvector, + or Oid[]; in the latter two cases it implies performing a + lookup on each element of the array. + + + + + + It's also permissible to attach BKI_LOOKUP(encoding) + to integer columns to reference character set encodings, which are + not currently represented as catalog OIDs, but have a set of values + known to genbki.pl. + + + + + + In some catalog columns, it's allowed for entries to be zero instead + of a valid reference. If this is allowed, write + BKI_LOOKUP_OPT instead + of BKI_LOOKUP. Then you can + write 0 for an entry. (If the column is + declared regproc, you can optionally + write - instead of 0.) + Except for this special case, all entries in + a BKI_LOOKUP column must be symbolic references. + genbki.pl will warn about unrecognized names. + + + + + + Most kinds of catalog objects are simply referenced by their names. + Note that type names must exactly match the + referenced pg_type + entry's typname; you do not get to use + any aliases such as integer + for int4. + + + + + + A function can be represented by + its proname, if that is unique among + the pg_proc.dat entries (this works like regproc + input). Otherwise, write it + as proname(argtypename,argtypename,...), + like regprocedure. The argument type names must be spelled exactly as + they are in the pg_proc.dat entry's + proargtypes field. Do not insert any + spaces. + + + + + + Operators are represented + by oprname(lefttype,righttype), + writing the type names exactly as they appear in + the pg_operator.dat + entry's oprleft + and oprright fields. + (Write 0 for the omitted operand of a unary + operator.) + + + + + + The names of opclasses and opfamilies are only unique within an + access method, so they are represented + by access_method_name/object_name. + + + + + + In none of these cases is there any provision for + schema-qualification; all objects created during bootstrap are + expected to be in the pg_catalog schema. + + + + + + genbki.pl resolves all symbolic references while it + runs, and puts simple numeric OIDs into the emitted BKI file. There is + therefore no need for the bootstrap backend to deal with symbolic + references. + + + + It's desirable to mark OID reference columns + with BKI_LOOKUP or BKI_LOOKUP_OPT + even if the catalog has no initial data that requires lookup. This + allows genbki.pl to record the foreign key + relationships that exist in the system catalogs. That information is + used in the regression tests to check for incorrect entries. See also + the macros DECLARE_FOREIGN_KEY, + DECLARE_FOREIGN_KEY_OPT, + DECLARE_ARRAY_FOREIGN_KEY, + and DECLARE_ARRAY_FOREIGN_KEY_OPT, which are + used to declare foreign key relationships that are too complex + for BKI_LOOKUP (typically, multi-column foreign + keys). + + + + + Automatic Creation of Array Types + + + Most scalar data types should have a corresponding array type (that is, + a standard varlena array type whose element type is the scalar type, and + which is referenced by the typarray field of + the scalar type's pg_type + entry). genbki.pl is able to generate + the pg_type entry for the array type + automatically in most cases. + + + + To use this facility, just write an array_type_oid + => nnnn metadata field in the + scalar type's pg_type entry, specifying the OID + to use for the array type. You may then omit + the typarray field, since it will be filled + automatically with that OID. + + + + The generated array type's name is the scalar type's name with an + underscore prepended. The array entry's other fields are filled from + BKI_ARRAY_DEFAULT(value) + annotations in pg_type.h, or if there isn't one, + copied from the scalar type. (There's also a special case + for typalign.) Then + the typelem + and typarray fields of the two entries are + set to cross-reference each other. + + + + + Recipes for Editing Data Files + + + Here are some suggestions about the easiest ways to perform common tasks + when updating catalog data files. + + + + Add a new column with a default to a catalog: + + Add the column to the header file with + a BKI_DEFAULT(value) + annotation. The data file need only be adjusted by adding the field + in existing rows where a non-default value is needed. + + + + + Add a default value to an existing column that doesn't have + one: + + Add a BKI_DEFAULT annotation to the header file, + then run make reformat-dat-files to remove + now-redundant field entries. + + + + + Remove a column, whether it has a default or not: + + Remove the column from the header, then run make + reformat-dat-files to remove now-useless field entries. + + + + + Change or remove an existing default value: + + You cannot simply change the header file, since that will cause the + current data to be interpreted incorrectly. First run make + expand-dat-files to rewrite the data files with all + default values inserted explicitly, then change or remove + the BKI_DEFAULT annotation, then run make + reformat-dat-files to remove superfluous fields again. + + + + + Ad-hoc bulk editing: + + reformat_dat_file.pl can be adapted to perform + many kinds of bulk changes. Look for its block comments showing where + one-off code can be inserted. In the following example, we are going + to consolidate two boolean fields in pg_proc + into a char field: + + + + + Add the new column, with a default, + to pg_proc.h: + ++ /* see PROKIND_ categories below */ ++ char prokind BKI_DEFAULT(f); + + + + + + + Create a new script based on reformat_dat_file.pl + to insert appropriate values on-the-fly: + +- # At this point we have the full row in memory as a hash +- # and can do any operations we want. As written, it only +- # removes default values, but this script can be adapted to +- # do one-off bulk-editing. ++ # One-off change to migrate to prokind ++ # Default has already been filled in by now, so change to other ++ # values as appropriate ++ if ($values{proisagg} eq 't') ++ { ++ $values{prokind} = 'a'; ++ } ++ elsif ($values{proiswindow} eq 't') ++ { ++ $values{prokind} = 'w'; ++ } + + + + + + + Run the new script: + +$ cd src/include/catalog +$ perl rewrite_dat_with_prokind.pl pg_proc.dat + + At this point pg_proc.dat has all three + columns, prokind, + proisagg, + and proiswindow, though they will appear + only in rows where they have non-default values. + + + + + + Remove the old columns from pg_proc.h: + +- /* is it an aggregate? */ +- bool proisagg BKI_DEFAULT(f); +- +- /* is it a window function? */ +- bool proiswindow BKI_DEFAULT(f); + + + + + + + Finally, run make reformat-dat-files to remove + the useless old entries from pg_proc.dat. + + + + + For further examples of scripts used for bulk editing, see + convert_oid2name.pl + and remove_pg_type_oid_symbols.pl attached to this + message: + + + + + + + + <acronym>BKI</acronym> File Format + + + This section describes how the PostgreSQL + backend interprets BKI files. This description + will be easier to understand if the postgres.bki + file is at hand as an example. + + + + BKI input consists of a sequence of commands. Commands are made up + of a number of tokens, depending on the syntax of the command. + Tokens are usually separated by whitespace, but need not be if + there is no ambiguity. There is no special command separator; the + next token that syntactically cannot belong to the preceding + command starts a new one. (Usually you would put a new command on + a new line, for clarity.) Tokens can be certain key words, special + characters (parentheses, commas, etc.), identifiers, numbers, or + single-quoted strings. Everything is case sensitive. + + + + Lines starting with # are ignored. + + + + + + <acronym>BKI</acronym> Commands + + + + + create + tablename + tableoid + bootstrap + shared_relation + rowtype_oid oid + (name1 = + type1 + FORCE NOT NULL | FORCE NULL , + name2 = + type2 + FORCE NOT NULL | FORCE NULL , + ...) + + + + + Create a table named tablename, and having the OID + tableoid, + with the columns given in parentheses. + + + + The following column types are supported directly by + bootstrap.c: bool, + bytea, char (1 byte), + name, int2, + int4, regproc, regclass, + regtype, text, + oid, tid, xid, + cid, int2vector, oidvector, + _int4 (array), _text (array), + _oid (array), _char (array), + _aclitem (array). Although it is possible to create + tables containing columns of other types, this cannot be done until + after pg_type has been created and filled with + appropriate entries. (That effectively means that only these + column types can be used in bootstrap catalogs, but non-bootstrap + catalogs can contain any built-in type.) + + + + When bootstrap is specified, + the table will only be created on disk; nothing is entered into + pg_class, + pg_attribute, etc, for it. Thus the + table will not be accessible by ordinary SQL operations until + such entries are made the hard way (with insert + commands). This option is used for creating + pg_class etc themselves. + + + + The table is created as shared if shared_relation is + specified. + The table's row type OID (pg_type OID) can optionally + be specified via the rowtype_oid clause; if not specified, + an OID is automatically generated for it. (The rowtype_oid + clause is useless if bootstrap is specified, but it can be + provided anyway for documentation.) + + + + + + + open tablename + + + + + Open the table named + tablename + for insertion of data. Any currently open table is closed. + + + + + + + close tablename + + + + + Close the open table. The name of the table must be given as a + cross-check. + + + + + + + insert ( oid_value value1 value2 ... ) + + + + + Insert a new row into the open table using value1, value2, etc., for its column + values. + + + + NULL values can be specified using the special key word + _null_. Values that do not look like + identifiers or digit strings must be single-quoted. + (To include a single quote in a value, write it twice. + Escape-string-style backslash escapes are allowed in the string, too.) + + + + + + + declare unique + index indexname + indexoid + on tablename + using amname + ( opclass1 + name1 + , ... ) + + + + + Create an index named indexname, having OID + indexoid, + on the table named + tablename, using the + amname access + method. The fields to index are called name1, name2 etc., and the operator + classes to use are opclass1, opclass2 etc., respectively. + The index file is created and appropriate catalog entries are + made for it, but the index contents are not initialized by this command. + + + + + + + declare toast + toasttableoid + toastindexoid + on tablename + + + + + Create a TOAST table for the table named + tablename. + The TOAST table is assigned OID + toasttableoid + and its index is assigned OID + toastindexoid. + As with declare index, filling of the index + is postponed. + + + + + + build indices + + + + Fill in the indices that have previously been declared. + + + + + + + + + Structure of the Bootstrap <acronym>BKI</acronym> File + + + The open command cannot be used until the tables it uses + exist and have entries for the table that is to be opened. + (These minimum tables are pg_class, + pg_attribute, pg_proc, and + pg_type.) To allow those tables themselves to be filled, + create with the bootstrap option implicitly opens + the created table for data insertion. + + + + Also, the declare index and declare toast + commands cannot be used until the system catalogs they need have been + created and filled in. + + + + Thus, the structure of the postgres.bki file has to + be: + + + + create bootstrap one of the critical tables + + + + + insert data describing at least the critical tables + + + + + close + + + + + Repeat for the other critical tables. + + + + + create (without bootstrap) a noncritical table + + + + + open + + + + + insert desired data + + + + + close + + + + + Repeat for the other noncritical tables. + + + + + Define indexes and toast tables. + + + + + build indices + + + + + + + There are doubtless other, undocumented ordering dependencies. + + + + + BKI Example + + + The following sequence of commands will create the table + test_table with OID 420, having three columns + oid, cola and colb + of type oid, int4 and text, + respectively, and insert two rows into the table: + +create test_table 420 (oid = oid, cola = int4, colb = text) +open test_table +insert ( 421 1 'value 1' ) +insert ( 422 2 _null_ ) +close test_table + + + + diff --git a/doc/src/sgml/bloom.sgml b/doc/src/sgml/bloom.sgml new file mode 100644 index 000000000000..d1cf9ac24a75 --- /dev/null +++ b/doc/src/sgml/bloom.sgml @@ -0,0 +1,290 @@ + + + + bloom + + + bloom + + + + bloom provides an index access method based on + Bloom filters. + + + + A Bloom filter is a space-efficient data structure that is used to test + whether an element is a member of a set. In the case of an index access + method, it allows fast exclusion of non-matching tuples via signatures + whose size is determined at index creation. + + + + A signature is a lossy representation of the indexed attribute(s), and as + such is prone to reporting false positives; that is, it may be reported + that an element is in the set, when it is not. So index search results + must always be rechecked using the actual attribute values from the heap + entry. Larger signatures reduce the odds of a false positive and thus + reduce the number of useless heap visits, but of course also make the index + larger and hence slower to scan. + + + + This type of index is most useful when a table has many attributes and + queries test arbitrary combinations of them. A traditional btree index is + faster than a bloom index, but it can require many btree indexes to support + all possible queries where one needs only a single bloom index. Note + however that bloom indexes only support equality queries, whereas btree + indexes can also perform inequality and range searches. + + + + Parameters + + + A bloom index accepts the following parameters in its + WITH clause: + + + + + length + + + Length of each signature (index entry) in bits. It is rounded up to the + nearest multiple of 16. The default is + 80 bits and the maximum is 4096. + + + + + + + col1 — col32 + + + Number of bits generated for each index column. Each parameter's name + refers to the number of the index column that it controls. The default + is 2 bits and the maximum is 4095. + Parameters for index columns not actually used are ignored. + + + + + + + + Examples + + + This is an example of creating a bloom index: + + + +CREATE INDEX bloomidx ON tbloom USING bloom (i1,i2,i3) + WITH (length=80, col1=2, col2=2, col3=4); + + + + The index is created with a signature length of 80 bits, with attributes + i1 and i2 mapped to 2 bits, and attribute i3 mapped to 4 bits. We could + have omitted the length, col1, + and col2 specifications since those have the default values. + + + + Here is a more complete example of bloom index definition and usage, as + well as a comparison with equivalent btree indexes. The bloom index is + considerably smaller than the btree index, and can perform better. + + + +=# CREATE TABLE tbloom AS + SELECT + (random() * 1000000)::int as i1, + (random() * 1000000)::int as i2, + (random() * 1000000)::int as i3, + (random() * 1000000)::int as i4, + (random() * 1000000)::int as i5, + (random() * 1000000)::int as i6 + FROM + generate_series(1,10000000); +SELECT 10000000 + + + + A sequential scan over this large table takes a long time: + +=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451; + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------------------- + Seq Scan on tbloom (cost=0.00..2137.14 rows=3 width=24) (actual time=16.971..16.971 rows=0 loops=1) + Filter: ((i2 = 898732) AND (i5 = 123451)) + Rows Removed by Filter: 100000 + Planning Time: 0.346 ms + Execution Time: 16.988 ms +(5 rows) + + + + + Even with the btree index defined the result will still be a + sequential scan: + +=# CREATE INDEX btreeidx ON tbloom (i1, i2, i3, i4, i5, i6); +CREATE INDEX +=# SELECT pg_size_pretty(pg_relation_size('btreeidx')); + pg_size_pretty +---------------- + 3976 kB +(1 row) +=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451; + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------------------- + Seq Scan on tbloom (cost=0.00..2137.00 rows=2 width=24) (actual time=12.805..12.805 rows=0 loops=1) + Filter: ((i2 = 898732) AND (i5 = 123451)) + Rows Removed by Filter: 100000 + Planning Time: 0.138 ms + Execution Time: 12.817 ms +(5 rows) + + + + + Having the bloom index defined on the table is better than btree in + handling this type of search: + +=# CREATE INDEX bloomidx ON tbloom USING bloom (i1, i2, i3, i4, i5, i6); +CREATE INDEX +=# SELECT pg_size_pretty(pg_relation_size('bloomidx')); + pg_size_pretty +---------------- + 1584 kB +(1 row) +=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451; + QUERY PLAN +-------------------------------------------------------------------&zwsp;-------------------------------------------------- + Bitmap Heap Scan on tbloom (cost=1792.00..1799.69 rows=2 width=24) (actual time=0.388..0.388 rows=0 loops=1) + Recheck Cond: ((i2 = 898732) AND (i5 = 123451)) + Rows Removed by Index Recheck: 29 + Heap Blocks: exact=28 + -> Bitmap Index Scan on bloomidx (cost=0.00..1792.00 rows=2 width=0) (actual time=0.356..0.356 rows=29 loops=1) + Index Cond: ((i2 = 898732) AND (i5 = 123451)) + Planning Time: 0.099 ms + Execution Time: 0.408 ms +(8 rows) + + + + + Now, the main problem with the btree search is that btree is inefficient + when the search conditions do not constrain the leading index column(s). + A better strategy for btree is to create a separate index on each column. + Then the planner will choose something like this: + +=# CREATE INDEX btreeidx1 ON tbloom (i1); +CREATE INDEX +=# CREATE INDEX btreeidx2 ON tbloom (i2); +CREATE INDEX +=# CREATE INDEX btreeidx3 ON tbloom (i3); +CREATE INDEX +=# CREATE INDEX btreeidx4 ON tbloom (i4); +CREATE INDEX +=# CREATE INDEX btreeidx5 ON tbloom (i5); +CREATE INDEX +=# CREATE INDEX btreeidx6 ON tbloom (i6); +CREATE INDEX +=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451; + QUERY PLAN +-------------------------------------------------------------------&zwsp;-------------------------------------------------------- + Bitmap Heap Scan on tbloom (cost=24.34..32.03 rows=2 width=24) (actual time=0.028..0.029 rows=0 loops=1) + Recheck Cond: ((i5 = 123451) AND (i2 = 898732)) + -> BitmapAnd (cost=24.34..24.34 rows=2 width=0) (actual time=0.027..0.027 rows=0 loops=1) + -> Bitmap Index Scan on btreeidx5 (cost=0.00..12.04 rows=500 width=0) (actual time=0.026..0.026 rows=0 loops=1) + Index Cond: (i5 = 123451) + -> Bitmap Index Scan on btreeidx2 (cost=0.00..12.04 rows=500 width=0) (never executed) + Index Cond: (i2 = 898732) + Planning Time: 0.491 ms + Execution Time: 0.055 ms +(9 rows) + + Although this query runs much faster than with either of the single + indexes, we pay a penalty in index size. Each of the single-column + btree indexes occupies 2 MB, so the total space needed is 12 MB, + eight times the space used by the bloom index. + + + + + Operator Class Interface + + + An operator class for bloom indexes requires only a hash function for the + indexed data type and an equality operator for searching. This example + shows the operator class definition for the text data type: + + + +CREATE OPERATOR CLASS text_ops +DEFAULT FOR TYPE text USING bloom AS + OPERATOR 1 =(text, text), + FUNCTION 1 hashtext(text); + + + + + Limitations + + + + + Only operator classes for int4 and text are + included with the module. + + + + + + Only the = operator is supported for search. But + it is possible to add support for arrays with union and intersection + operations in the future. + + + + + + bloom access method doesn't support + UNIQUE indexes. + + + + + + bloom access method doesn't support searching for + NULL values. + + + + + + + + Authors + + + Teodor Sigaev teodor@postgrespro.ru, + Postgres Professional, Moscow, Russia + + + + Alexander Korotkov a.korotkov@postgrespro.ru, + Postgres Professional, Moscow, Russia + + + + Oleg Bartunov obartunov@postgrespro.ru, + Postgres Professional, Moscow, Russia + + + + diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml new file mode 100644 index 000000000000..ce7c2105755d --- /dev/null +++ b/doc/src/sgml/brin.sgml @@ -0,0 +1,1298 @@ + + + +BRIN Indexes + + + index + BRIN + + + + Introduction + + + BRIN stands for Block Range Index. + BRIN is designed for handling very large tables + in which certain columns have some natural correlation with their + physical location within the table. + A block range is a group of pages that are physically + adjacent in the table; for each block range, some summary info is stored + by the index. + For example, a table storing a store's sale orders might have + a date column on which each order was placed, and most of the time + the entries for earlier orders will appear earlier in the table as well; + a table storing a ZIP code column might have all codes for a city + grouped together naturally. + + + + BRIN indexes can satisfy queries via regular bitmap + index scans, and will return all tuples in all pages within each range if + the summary info stored by the index is consistent with the + query conditions. + The query executor is in charge of rechecking these tuples and discarding + those that do not match the query conditions — in other words, these + indexes are lossy. + Because a BRIN index is very small, scanning the index + adds little overhead compared to a sequential scan, but may avoid scanning + large parts of the table that are known not to contain matching tuples. + + + + The specific data that a BRIN index will store, + as well as the specific queries that the index will be able to satisfy, + depend on the operator class selected for each column of the index. + Data types having a linear sort order can have operator classes that + store the minimum and maximum value within each block range, for instance; + geometrical types might store the bounding box for all the objects + in the block range. + + + + The size of the block range is determined at index creation time by + the pages_per_range storage parameter. The number of index + entries will be equal to the size of the relation in pages divided by + the selected value for pages_per_range. Therefore, the smaller + the number, the larger the index becomes (because of the need to + store more index entries), but at the same time the summary data stored can + be more precise and more data blocks can be skipped during an index scan. + + + + Index Maintenance + + + At the time of creation, all existing heap pages are scanned and a + summary index tuple is created for each range, including the + possibly-incomplete range at the end. + As new pages are filled with data, page ranges that are already + summarized will cause the summary information to be updated with data + from the new tuples. + When a new page is created that does not fall within the last + summarized range, that range does not automatically acquire a summary + tuple; those tuples remain unsummarized until a summarization run is + invoked later, creating initial summaries. + This process can be invoked manually using the + brin_summarize_range(regclass, bigint) or + brin_summarize_new_values(regclass) functions; + automatically when VACUUM processes the table; + or by automatic summarization executed by autovacuum, as insertions + occur. (This last trigger is disabled by default and can be enabled + with the autosummarize parameter.) + Conversely, a range can be de-summarized using the + brin_desummarize_range(regclass, bigint) function, + which is useful when the index tuple is no longer a very good + representation because the existing values have changed. + + + + When autosummarization is enabled, each time a page range is filled a + request is sent to autovacuum for it to execute a targeted summarization + for that range, to be fulfilled at the end of the next worker run on the + same database. If the request queue is full, the request is not recorded + and a message is sent to the server log: + +LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was not recorded + + When this happens, the range will be summarized normally during the next + regular vacuum of the table. + + + + + + Built-in Operator Classes + + + The core PostgreSQL distribution + includes the BRIN operator classes shown in + . + + + + The minmax + operator classes store the minimum and the maximum values appearing + in the indexed column within the range. The inclusion + operator classes store a value which includes the values in the indexed + column within the range. The bloom operator + classes build a Bloom filter for all values in the range. The + minmax-multi operator classes store multiple + minimum and maximum values, representing values appearing in the indexed + column within the range. + + + + Built-in <acronym>BRIN</acronym> Operator Classes + + + + Name + Indexable Operators + + + + + bit_minmax_ops + = (bit,bit) + + < (bit,bit) + > (bit,bit) + <= (bit,bit) + >= (bit,bit) + + + box_inclusion_ops + @> (box,point) + + << (box,box) + &< (box,box) + &> (box,box) + >> (box,box) + <@ (box,box) + @> (box,box) + ~= (box,box) + && (box,box) + <<| (box,box) + &<| (box,box) + |&> (box,box) + |>> (box,box) + + + bpchar_bloom_ops + = (character,character) + + + + bpchar_minmax_ops + = (character,character) + + < (character,character) + <= (character,character) + > (character,character) + >= (character,character) + + + bytea_bloom_ops + = (bytea,bytea) + + + + bytea_minmax_ops + = (bytea,bytea) + + < (bytea,bytea) + <= (bytea,bytea) + > (bytea,bytea) + >= (bytea,bytea) + + + char_bloom_ops + = ("char","char") + + + + char_minmax_ops + = ("char","char") + + < ("char","char") + <= ("char","char") + > ("char","char") + >= ("char","char") + + + date_bloom_ops + = (date,date) + + + + date_minmax_ops + = (date,date) + + < (date,date) + <= (date,date) + > (date,date) + >= (date,date) + + + date_minmax_multi_ops + = (date,date) + + < (date,date) + <= (date,date) + > (date,date) + >= (date,date) + + + float4_bloom_ops + = (float4,float4) + + + + float4_minmax_ops + = (float4,float4) + + < (float4,float4) + > (float4,float4) + <= (float4,float4) + >= (float4,float4) + + + float4_minmax_multi_ops + = (float4,float4) + + < (float4,float4) + > (float4,float4) + <= (float4,float4) + >= (float4,float4) + + + float8_bloom_ops + = (float8,float8) + + + + float8_minmax_ops + = (float8,float8) + + < (float8,float8) + <= (float8,float8) + > (float8,float8) + >= (float8,float8) + + + float8_minmax_multi_ops + = (float8,float8) + + < (float8,float8) + <= (float8,float8) + > (float8,float8) + >= (float8,float8) + + + inet_inclusion_ops + << (inet,inet) + + <<= (inet,inet) + >> (inet,inet) + >>= (inet,inet) + = (inet,inet) + && (inet,inet) + + + inet_bloom_ops + = (inet,inet) + + + + inet_minmax_ops + = (inet,inet) + + < (inet,inet) + <= (inet,inet) + > (inet,inet) + >= (inet,inet) + + + inet_minmax_multi_ops + = (inet,inet) + + < (inet,inet) + <= (inet,inet) + > (inet,inet) + >= (inet,inet) + + + int2_bloom_ops + = (int2,int2) + + + + int2_minmax_ops + = (int2,int2) + + < (int2,int2) + > (int2,int2) + <= (int2,int2) + >= (int2,int2) + + + int2_minmax_multi_ops + = (int2,int2) + + < (int2,int2) + > (int2,int2) + <= (int2,int2) + >= (int2,int2) + + + int4_bloom_ops + = (int4,int4) + + + + int4_minmax_ops + = (int4,int4) + + < (int4,int4) + > (int4,int4) + <= (int4,int4) + >= (int4,int4) + + + int4_minmax_multi_ops + = (int4,int4) + + < (int4,int4) + > (int4,int4) + <= (int4,int4) + >= (int4,int4) + + + int8_bloom_ops + = (bigint,bigint) + + + + int8_minmax_ops + = (bigint,bigint) + + < (bigint,bigint) + > (bigint,bigint) + <= (bigint,bigint) + >= (bigint,bigint) + + + int8_minmax_multi_ops + = (bigint,bigint) + + < (bigint,bigint) + > (bigint,bigint) + <= (bigint,bigint) + >= (bigint,bigint) + + + interval_bloom_ops + = (interval,interval) + + + + interval_minmax_ops + = (interval,interval) + + < (interval,interval) + <= (interval,interval) + > (interval,interval) + >= (interval,interval) + + + interval_minmax_multi_ops + = (interval,interval) + + < (interval,interval) + <= (interval,interval) + > (interval,interval) + >= (interval,interval) + + + macaddr_bloom_ops + = (macaddr,macaddr) + + + + macaddr_minmax_ops + = (macaddr,macaddr) + + < (macaddr,macaddr) + <= (macaddr,macaddr) + > (macaddr,macaddr) + >= (macaddr,macaddr) + + + macaddr_minmax_multi_ops + = (macaddr,macaddr) + + < (macaddr,macaddr) + <= (macaddr,macaddr) + > (macaddr,macaddr) + >= (macaddr,macaddr) + + + macaddr8_bloom_ops + = (macaddr8,macaddr8) + + + + macaddr8_minmax_ops + = (macaddr8,macaddr8) + + < (macaddr8,macaddr8) + <= (macaddr8,macaddr8) + > (macaddr8,macaddr8) + >= (macaddr8,macaddr8) + + + macaddr8_minmax_multi_ops + = (macaddr8,macaddr8) + + < (macaddr8,macaddr8) + <= (macaddr8,macaddr8) + > (macaddr8,macaddr8) + >= (macaddr8,macaddr8) + + + name_bloom_ops + = (name,name) + + + + name_minmax_ops + = (name,name) + + < (name,name) + <= (name,name) + > (name,name) + >= (name,name) + + + numeric_bloom_ops + = (numeric,numeric) + + + + numeric_minmax_ops + = (numeric,numeric) + + < (numeric,numeric) + <= (numeric,numeric) + > (numeric,numeric) + >= (numeric,numeric) + + + numeric_minmax_multi_ops + = (numeric,numeric) + + < (numeric,numeric) + <= (numeric,numeric) + > (numeric,numeric) + >= (numeric,numeric) + + + oid_bloom_ops + = (oid,oid) + + + + oid_minmax_ops + = (oid,oid) + + < (oid,oid) + > (oid,oid) + <= (oid,oid) + >= (oid,oid) + + + oid_minmax_multi_ops + = (oid,oid) + + < (oid,oid) + > (oid,oid) + <= (oid,oid) + >= (oid,oid) + + + pg_lsn_bloom_ops + = (pg_lsn,pg_lsn) + + + + pg_lsn_minmax_ops + = (pg_lsn,pg_lsn) + + < (pg_lsn,pg_lsn) + > (pg_lsn,pg_lsn) + <= (pg_lsn,pg_lsn) + >= (pg_lsn,pg_lsn) + + + pg_lsn_minmax_multi_ops + = (pg_lsn,pg_lsn) + + < (pg_lsn,pg_lsn) + > (pg_lsn,pg_lsn) + <= (pg_lsn,pg_lsn) + >= (pg_lsn,pg_lsn) + + + range_inclusion_ops + = (anyrange,anyrange) + + < (anyrange,anyrange) + <= (anyrange,anyrange) + >= (anyrange,anyrange) + > (anyrange,anyrange) + && (anyrange,anyrange) + @> (anyrange,anyelement) + @> (anyrange,anyrange) + <@ (anyrange,anyrange) + << (anyrange,anyrange) + >> (anyrange,anyrange) + &< (anyrange,anyrange) + &> (anyrange,anyrange) + -|- (anyrange,anyrange) + + + text_bloom_ops + = (text,text) + + + + text_minmax_ops + = (text,text) + + < (text,text) + <= (text,text) + > (text,text) + >= (text,text) + + + tid_bloom_ops + = (tid,tid) + + + + tid_minmax_ops + = (tid,tid) + + < (tid,tid) + > (tid,tid) + <= (tid,tid) + >= (tid,tid) + + + tid_minmax_multi_ops + = (tid,tid) + + < (tid,tid) + > (tid,tid) + <= (tid,tid) + >= (tid,tid) + + + timestamp_bloom_ops + = (timestamp,timestamp) + + + + timestamp_minmax_ops + = (timestamp,timestamp) + + < (timestamp,timestamp) + <= (timestamp,timestamp) + > (timestamp,timestamp) + >= (timestamp,timestamp) + + + timestamp_minmax_multi_ops + = (timestamp,timestamp) + + < (timestamp,timestamp) + <= (timestamp,timestamp) + > (timestamp,timestamp) + >= (timestamp,timestamp) + + + timestamptz_bloom_ops + = (timestamptz,timestamptz) + + + + timestamptz_minmax_ops + = (timestamptz,timestamptz) + + < (timestamptz,timestamptz) + <= (timestamptz,timestamptz) + > (timestamptz,timestamptz) + >= (timestamptz,timestamptz) + + + timestamptz_minmax_multi_ops + = (timestamptz,timestamptz) + + < (timestamptz,timestamptz) + <= (timestamptz,timestamptz) + > (timestamptz,timestamptz) + >= (timestamptz,timestamptz) + + + time_bloom_ops + = (time,time) + + + + time_minmax_ops + = (time,time) + + < (time,time) + <= (time,time) + > (time,time) + >= (time,time) + + + time_minmax_multi_ops + = (time,time) + + < (time,time) + <= (time,time) + > (time,time) + >= (time,time) + + + timetz_bloom_ops + = (timetz,timetz) + + + + timetz_minmax_ops + = (timetz,timetz) + + < (timetz,timetz) + <= (timetz,timetz) + > (timetz,timetz) + >= (timetz,timetz) + + + timetz_minmax_multi_ops + = (timetz,timetz) + + < (timetz,timetz) + <= (timetz,timetz) + > (timetz,timetz) + >= (timetz,timetz) + + + uuid_bloom_ops + = (uuid,uuid) + + + + uuid_minmax_ops + = (uuid,uuid) + + < (uuid,uuid) + > (uuid,uuid) + <= (uuid,uuid) + >= (uuid,uuid) + + + uuid_minmax_multi_ops + = (uuid,uuid) + + < (uuid,uuid) + > (uuid,uuid) + <= (uuid,uuid) + >= (uuid,uuid) + + + varbit_minmax_ops + = (varbit,varbit) + + < (varbit,varbit) + > (varbit,varbit) + <= (varbit,varbit) + >= (varbit,varbit) + + +
+ + + Operator Class Parameters + + + Some of the built-in operator classes allow specifying parameters affecting + behavior of the operator class. Each operator class has its own set of + allowed parameters. Only the bloom and minmax-multi + operator classes allow specifying parameters: + + + + bloom operator classes accept these parameters: + + + + + n_distinct_per_range + + + Defines the estimated number of distinct non-null values in the block + range, used by BRIN bloom indexes for sizing of the + Bloom filter. It behaves similarly to n_distinct option + for . When set to a positive value, + each block range is assumed to contain this number of distinct non-null + values. When set to a negative value, which must be greater than or + equal to -1, the number of distinct non-null values is assumed to grow linearly with + the maximum possible number of tuples in the block range (about 290 + rows per block). The default value is -0.1, and + the minimum number of distinct non-null values is 16. + + + + + + false_positive_rate + + + Defines the desired false positive rate used by BRIN + bloom indexes for sizing of the Bloom filter. The values must be + between 0.0001 and 0.25. The default value is 0.01, which is 1% false + positive rate. + + + + + + + + minmax-multi operator classes accept these parameters: + + + + + values_per_range + + + Defines the maximum number of values stored by BRIN + minmax indexes to summarize a block range. Each value may represent + either a point, or a boundary of an interval. Values must be between + 8 and 256, and the default value is 32. + + + + + + + +
+ + + Extensibility + + + The BRIN interface has a high level of abstraction, + requiring the access method implementer only to implement the semantics + of the data type being accessed. The BRIN layer + itself takes care of concurrency, logging and searching the index structure. + + + + All it takes to get a BRIN access method working is to + implement a few user-defined methods, which define the behavior of + summary values stored in the index and the way they interact with + scan keys. + In short, BRIN combines + extensibility with generality, code reuse, and a clean interface. + + + + There are four methods that an operator class for BRIN + must provide: + + + + BrinOpcInfo *opcInfo(Oid type_oid) + + + Returns internal information about the indexed columns' summary data. + The return value must point to a palloc'd BrinOpcInfo, + which has this definition: + +typedef struct BrinOpcInfo +{ + /* Number of columns stored in an index column of this opclass */ + uint16 oi_nstored; + + /* Opaque pointer for the opclass' private use */ + void *oi_opaque; + + /* Type cache entries of the stored columns */ + TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER]; +} BrinOpcInfo; + + BrinOpcInfo.oi_opaque can be used by the + operator class routines to pass information between support functions + during an index scan. + + + + + + bool consistent(BrinDesc *bdesc, BrinValues *column, + ScanKey *keys, int nkeys) + + + Returns whether all the ScanKey entries are consistent with the given + indexed values for a range. + The attribute number to use is passed as part of the scan key. + Multiple scan keys for the same attribute may be passed at once; the + number of entries is determined by the nkeys parameter. + + + + + + bool consistent(BrinDesc *bdesc, BrinValues *column, + ScanKey key) + + + Returns whether the ScanKey is consistent with the given indexed + values for a range. + The attribute number to use is passed as part of the scan key. + This is an older backward-compatible variant of the consistent function. + + + + + + bool addValue(BrinDesc *bdesc, BrinValues *column, + Datum newval, bool isnull) + + + Given an index tuple and an indexed value, modifies the indicated + attribute of the tuple so that it additionally represents the new value. + If any modification was done to the tuple, true is + returned. + + + + + + bool unionTuples(BrinDesc *bdesc, BrinValues *a, + BrinValues *b) + + + Consolidates two index tuples. Given two index tuples, modifies the + indicated attribute of the first of them so that it represents both tuples. + The second tuple is not modified. + + + + + + An operator class for BRIN can optionally specify the + following method: + + + + void options(local_relopts *relopts) + + + Defines a set of user-visible parameters that control operator class + behavior. + + + + The options function is passed a pointer to a + local_relopts struct, which needs to be + filled with a set of operator class specific options. The options + can be accessed from other support functions using the + PG_HAS_OPCLASS_OPTIONS() and + PG_GET_OPCLASS_OPTIONS() macros. + + + + Since both key extraction of indexed values and representation of the + key in BRIN are flexible, they may depend on + user-specified parameters. + + + + + + The core distribution includes support for four types of operator classes: + minmax, minmax-multi, inclusion and bloom. Operator class definitions + using them are shipped for in-core data types as appropriate. Additional + operator classes can be defined by the user for other data types using + equivalent definitions, without having to write any source code; + appropriate catalog entries being declared is enough. Note that + assumptions about the semantics of operator strategies are embedded in the + support functions' source code. + + + + Operator classes that implement completely different semantics are also + possible, provided implementations of the four main support functions + described above are written. Note that backwards compatibility across major + releases is not guaranteed: for example, additional support functions might + be required in later releases. + + + + To write an operator class for a data type that implements a totally + ordered set, it is possible to use the minmax support functions + alongside the corresponding operators, as shown in + . + All operator class members (functions and operators) are mandatory. + + + + Function and Support Numbers for Minmax Operator Classes + + + + + + Operator class member + Object + + + + + Support Function 1 + internal function brin_minmax_opcinfo() + + + Support Function 2 + internal function brin_minmax_add_value() + + + Support Function 3 + internal function brin_minmax_consistent() + + + Support Function 4 + internal function brin_minmax_union() + + + Operator Strategy 1 + operator less-than + + + Operator Strategy 2 + operator less-than-or-equal-to + + + Operator Strategy 3 + operator equal-to + + + Operator Strategy 4 + operator greater-than-or-equal-to + + + Operator Strategy 5 + operator greater-than + + + +
+ + + To write an operator class for a complex data type which has values + included within another type, it's possible to use the inclusion support + functions alongside the corresponding operators, as shown + in . It requires + only a single additional function, which can be written in any language. + More functions can be defined for additional functionality. All operators + are optional. Some operators require other operators, as shown as + dependencies on the table. + + + + Function and Support Numbers for Inclusion Operator Classes + + + + + + + Operator class member + Object + Dependency + + + + + Support Function 1 + internal function brin_inclusion_opcinfo() + + + + Support Function 2 + internal function brin_inclusion_add_value() + + + + Support Function 3 + internal function brin_inclusion_consistent() + + + + Support Function 4 + internal function brin_inclusion_union() + + + + Support Function 11 + function to merge two elements + + + + Support Function 12 + optional function to check whether two elements are mergeable + + + + Support Function 13 + optional function to check if an element is contained within another + + + + Support Function 14 + optional function to check whether an element is empty + + + + Operator Strategy 1 + operator left-of + Operator Strategy 4 + + + Operator Strategy 2 + operator does-not-extend-to-the-right-of + Operator Strategy 5 + + + Operator Strategy 3 + operator overlaps + + + + Operator Strategy 4 + operator does-not-extend-to-the-left-of + Operator Strategy 1 + + + Operator Strategy 5 + operator right-of + Operator Strategy 2 + + + Operator Strategy 6, 18 + operator same-as-or-equal-to + Operator Strategy 7 + + + Operator Strategy 7, 16, 24, 25 + operator contains-or-equal-to + + + + Operator Strategy 8, 26, 27 + operator is-contained-by-or-equal-to + Operator Strategy 3 + + + Operator Strategy 9 + operator does-not-extend-above + Operator Strategy 11 + + + Operator Strategy 10 + operator is-below + Operator Strategy 12 + + + Operator Strategy 11 + operator is-above + Operator Strategy 9 + + + Operator Strategy 12 + operator does-not-extend-below + Operator Strategy 10 + + + Operator Strategy 20 + operator less-than + Operator Strategy 5 + + + Operator Strategy 21 + operator less-than-or-equal-to + Operator Strategy 5 + + + Operator Strategy 22 + operator greater-than + Operator Strategy 1 + + + Operator Strategy 23 + operator greater-than-or-equal-to + Operator Strategy 1 + + + +
+ + + Support function numbers 1 through 10 are reserved for the BRIN internal + functions, so the SQL level functions start with number 11. Support + function number 11 is the main function required to build the index. + It should accept two arguments with the same data type as the operator class, + and return the union of them. The inclusion operator class can store union + values with different data types if it is defined with the + STORAGE parameter. The return value of the union + function should match the STORAGE data type. + + + + Support function numbers 12 and 14 are provided to support + irregularities of built-in data types. Function number 12 + is used to support network addresses from different families which + are not mergeable. Function number 14 is used to support + empty ranges. Function number 13 is an optional but + recommended one, which allows the new value to be checked before + it is passed to the union function. As the BRIN framework can shortcut + some operations when the union is not changed, using this + function can improve index performance. + + + + To write an operator class for a data type that implements only an equality + operator and supports hashing, it is possible to use the bloom support procedures + alongside the corresponding operators, as shown in + . + All operator class members (procedures and operators) are mandatory. + + + + Procedure and Support Numbers for Bloom Operator Classes + + + + Operator class member + Object + + + + + Support Procedure 1 + internal function brin_bloom_opcinfo() + + + Support Procedure 2 + internal function brin_bloom_add_value() + + + Support Procedure 3 + internal function brin_bloom_consistent() + + + Support Procedure 4 + internal function brin_bloom_union() + + + Support Procedure 11 + function to compute hash of an element + + + Operator Strategy 1 + operator equal-to + + + +
+ + + Support procedure numbers 1-10 are reserved for the BRIN internal + functions, so the SQL level functions start with number 11. Support + function number 11 is the main function required to build the index. + It should accept one argument with the same data type as the operator class, + and return a hash of the value. + + + + The minmax-multi operator class is also intended for data types implementing + a totally ordered set, and may be seen as a simple extension of the minmax + operator class. While minmax operator class summarizes values from each block + range into a single contiguous interval, minmax-multi allows summarization + into multiple smaller intervals to improve handling of outlier values. + It is possible to use the minmax-multi support procedures alongside the + corresponding operators, as shown in + . + All operator class members (procedures and operators) are mandatory. + + + + Procedure and Support Numbers for minmax-multi Operator Classes + + + + Operator class member + Object + + + + + Support Procedure 1 + internal function brin_minmax_multi_opcinfo() + + + Support Procedure 2 + internal function brin_minmax_multi_add_value() + + + Support Procedure 3 + internal function brin_minmax_multi_consistent() + + + Support Procedure 4 + internal function brin_minmax_multi_union() + + + Support Procedure 11 + function to compute distance between two values (length of a range) + + + Operator Strategy 1 + operator less-than + + + Operator Strategy 2 + operator less-than-or-equal-to + + + Operator Strategy 3 + operator equal-to + + + Operator Strategy 4 + operator greater-than-or-equal-to + + + Operator Strategy 5 + operator greater-than + + + +
+ + + Both minmax and inclusion operator classes support cross-data-type + operators, though with these the dependencies become more complicated. + The minmax operator class requires a full set of operators to be + defined with both arguments having the same data type. It allows + additional data types to be supported by defining extra sets + of operators. Inclusion operator class operator strategies are dependent + on another operator strategy as shown in + , or the same + operator strategy as themselves. They require the dependency + operator to be defined with the STORAGE data type as the + left-hand-side argument and the other supported data type to be the + right-hand-side argument of the supported operator. See + float4_minmax_ops as an example of minmax, and + box_inclusion_ops as an example of inclusion. + +
+
diff --git a/doc/src/sgml/btree.sgml b/doc/src/sgml/btree.sgml new file mode 100644 index 000000000000..2b716c644398 --- /dev/null +++ b/doc/src/sgml/btree.sgml @@ -0,0 +1,913 @@ + + + +B-Tree Indexes + + + index + B-Tree + + + + Introduction + + + PostgreSQL includes an implementation of the + standard btree (multi-way balanced tree) index data + structure. Any data type that can be sorted into a well-defined linear + order can be indexed by a btree index. The only limitation is that an + index entry cannot exceed approximately one-third of a page (after TOAST + compression, if applicable). + + + + Because each btree operator class imposes a sort order on its data type, + btree operator classes (or, really, operator families) have come to be + used as PostgreSQL's general representation + and understanding of sorting semantics. Therefore, they've acquired + some features that go beyond what would be needed just to support btree + indexes, and parts of the system that are quite distant from the + btree AM make use of them. + + + + + + Behavior of B-Tree Operator Classes + + + As shown in , a btree operator + class must provide five comparison operators, + <, + <=, + =, + >= and + >. + One might expect that <> should also be part of + the operator class, but it is not, because it would almost never be + useful to use a <> WHERE clause in an index + search. (For some purposes, the planner treats <> + as associated with a btree operator class; but it finds that operator via + the = operator's negator link, rather than + from pg_amop.) + + + + When several data types share near-identical sorting semantics, their + operator classes can be grouped into an operator family. Doing so is + advantageous because it allows the planner to make deductions about + cross-type comparisons. Each operator class within the family should + contain the single-type operators (and associated support functions) + for its input data type, while cross-type comparison operators and + support functions are loose in the family. It is + recommendable that a complete set of cross-type operators be included + in the family, thus ensuring that the planner can represent any + comparison conditions that it deduces from transitivity. + + + + There are some basic assumptions that a btree operator family must + satisfy: + + + + + + An = operator must be an equivalence relation; that + is, for all non-null values A, + B, C of the + data type: + + + + + A = + A is true + (reflexive law) + + + + + if A = + B, + then B = + A + (symmetric law) + + + + + if A = + B and B + = C, + then A = + C + (transitive law) + + + + + + + + + A < operator must be a strong ordering relation; + that is, for all non-null values A, + B, C: + + + + + A < + A is false + (irreflexive law) + + + + + if A < + B + and B < + C, + then A < + C + (transitive law) + + + + + + + + + Furthermore, the ordering is total; that is, for all non-null + values A, B: + + + + + exactly one of A < + B, A + = B, and + B < + A is true + (trichotomy law) + + + + + (The trichotomy law justifies the definition of the comparison support + function, of course.) + + + + + + The other three operators are defined in terms of = + and < in the obvious way, and must act consistently + with them. + + + + For an operator family supporting multiple data types, the above laws must + hold when A, B, + C are taken from any data types in the family. + The transitive laws are the trickiest to ensure, as in cross-type + situations they represent statements that the behaviors of two or three + different operators are consistent. + As an example, it would not work to put float8 + and numeric into the same operator family, at least not with + the current semantics that numeric values are converted + to float8 for comparison to a float8. Because + of the limited accuracy of float8, this means there are + distinct numeric values that will compare equal to the + same float8 value, and thus the transitive law would fail. + + + + Another requirement for a multiple-data-type family is that any implicit + or binary-coercion casts that are defined between data types included in + the operator family must not change the associated sort ordering. + + + + It should be fairly clear why a btree index requires these laws to hold + within a single data type: without them there is no ordering to arrange + the keys with. Also, index searches using a comparison key of a + different data type require comparisons to behave sanely across two + data types. The extensions to three or more data types within a family + are not strictly required by the btree index mechanism itself, but the + planner relies on them for optimization purposes. + + + + + + B-Tree Support Functions + + + As shown in , btree defines + one required and four optional support functions. The five + user-defined methods are: + + + + order + + + For each combination of data types that a btree operator family + provides comparison operators for, it must provide a comparison + support function, registered in + pg_amproc with support function number 1 + and + amproclefttype/amprocrighttype + equal to the left and right data types for the comparison (i.e., + the same data types that the matching operators are registered + with in pg_amop). The comparison + function must take two non-null values + A and B and + return an int32 value that is + < 0, + 0, or > + 0 when A + < B, + A = + B, or A + > B, + respectively. A null result is disallowed: all values of the + data type must be comparable. See + src/backend/access/nbtree/nbtcompare.c for + examples. + + + + If the compared values are of a collatable data type, the + appropriate collation OID will be passed to the comparison + support function, using the standard + PG_GET_COLLATION() mechanism. + + + + + sortsupport + + + Optionally, a btree operator family may provide sort + support function(s), registered under support + function number 2. These functions allow implementing + comparisons for sorting purposes in a more efficient way than + naively calling the comparison support function. The APIs + involved in this are defined in + src/include/utils/sortsupport.h. + + + + + in_range + + + in_range support functions + + + + support functions + in_range + + + Optionally, a btree operator family may provide + in_range support function(s), registered + under support function number 3. These are not used during btree + index operations; rather, they extend the semantics of the + operator family so that it can support window clauses containing + the RANGE offset + PRECEDING and RANGE + offset FOLLOWING + frame bound types (see ). Fundamentally, the extra + information provided is how to add or subtract an + offset value in a way that is + compatible with the family's data ordering. + + + + An in_range function must have the signature + +in_range(val type1, base type1, offset type2, sub bool, less bool) +returns bool + + val and + base must be of the same type, which + is one of the types supported by the operator family (i.e., a + type for which it provides an ordering). However, + offset could be of a different type, + which might be one otherwise unsupported by the family. An + example is that the built-in time_ops family + provides an in_range function that has + offset of type interval. + A family can provide in_range functions for + any of its supported types and one or more + offset types. Each + in_range function should be entered in + pg_amproc with + amproclefttype equal to + type1 and amprocrighttype + equal to type2. + + + + The essential semantics of an in_range + function depend on the two Boolean flag parameters. It should + add or subtract base and + offset, then compare + val to the result, as follows: + + + + if !sub and + !less, return + val >= + (base + + offset) + + + + + if !sub and + less, return + val <= + (base + + offset) + + + + + if sub and + !less, return + val >= + (base - + offset) + + + + + if sub and + less, return + val <= + (base - + offset) + + + + Before doing so, the function should check the sign of + offset: if it is less than zero, raise + error + ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE + (22013) with error text like invalid preceding or + following size in window function. (This is required by + the SQL standard, although nonstandard operator families might + perhaps choose to ignore this restriction, since there seems to + be little semantic necessity for it.) This requirement is + delegated to the in_range function so that + the core code needn't understand what less than + zero means for a particular data type. + + + + An additional expectation is that in_range + functions should, if practical, avoid throwing an error if + base + + offset or + base - + offset would overflow. The correct + comparison result can be determined even if that value would be + out of the data type's range. Note that if the data type + includes concepts such as infinity or + NaN, extra care may be needed to ensure that + in_range's results agree with the normal + sort order of the operator family. + + + + The results of the in_range function must be + consistent with the sort ordering imposed by the operator family. + To be precise, given any fixed values of + offset and + sub, then: + + + + If in_range with + less = true is true for some + val1 and + base, it must be true for every + val2 <= + val1 with the same + base. + + + + + If in_range with + less = true is false for some + val1 and + base, it must be false for every + val2 >= + val1 with the same + base. + + + + + If in_range with + less = true is true for some + val and + base1, it must be true for every + base2 >= + base1 with the same + val. + + + + + If in_range with + less = true is false for some + val and + base1, it must be false for every + base2 <= + base1 with the same + val. + + + + Analogous statements with inverted conditions hold when + less = false. + + + + If the type being ordered (type1) is collatable, the + appropriate collation OID will be passed to the + in_range function, using the standard + PG_GET_COLLATION() mechanism. + + + + in_range functions need not handle NULL + inputs, and typically will be marked strict. + + + + + equalimage + + + Optionally, a btree operator family may provide + equalimage (equality implies image + equality) support functions, registered under support + function number 4. These functions allow the core code to + determine when it is safe to apply the btree deduplication + optimization. Currently, equalimage + functions are only called when building or rebuilding an index. + + + An equalimage function must have the + signature + +equalimage(opcintype oid) returns bool + + The return value is static information about an operator class + and collation. Returning true indicates that + the order function for the operator class is + guaranteed to only return 0 (arguments + are equal) when its A and + B arguments are also interchangeable + without any loss of semantic information. Not registering an + equalimage function or returning + false indicates that this condition cannot be + assumed to hold. + + + The opcintype argument is the + pg_type.oid of the + data type that the operator class indexes. This is a convenience + that allows reuse of the same underlying + equalimage function across operator classes. + If opcintype is a collatable data + type, the appropriate collation OID will be passed to the + equalimage function, using the standard + PG_GET_COLLATION() mechanism. + + + As far as the operator class is concerned, returning + true indicates that deduplication is safe (or + safe for the collation whose OID was passed to its + equalimage function). However, the core + code will only deem deduplication safe for an index when + every indexed column uses an operator class + that registers an equalimage function, and + each function actually returns true when + called. + + + Image equality is almost the same condition + as simple bitwise equality. There is one subtle difference: When + indexing a varlena data type, the on-disk representation of two + image equal datums may not be bitwise equal due to inconsistent + application of TOAST compression on input. + Formally, when an operator class's + equalimage function returns + true, it is safe to assume that the + datum_image_eq() C function will always agree + with the operator class's order function + (provided that the same collation OID is passed to both the + equalimage and order + functions). + + + The core code is fundamentally unable to deduce anything about + the equality implies image equality status of an + operator class within a multiple-data-type family based on + details from other operator classes in the same family. Also, it + is not sensible for an operator family to register a cross-type + equalimage function, and attempting to do so + will result in an error. This is because equality implies + image equality status does not just depend on + sorting/equality semantics, which are more or less defined at the + operator family level. In general, the semantics that one + particular data type implements must be considered separately. + + + The convention followed by the operator classes included with the + core PostgreSQL distribution is to + register a stock, generic equalimage + function. Most operator classes register + btequalimage(), which indicates that + deduplication is safe unconditionally. Operator classes for + collatable data types such as text register + btvarstrequalimage(), which indicates that + deduplication is safe with deterministic collations. Best + practice for third-party extensions is to register their own + custom function to retain control. + + + + + options + + + Optionally, a B-tree operator family may provide + options (operator class specific + options) support functions, registered under support + function number 5. These functions define a set of user-visible + parameters that control operator class behavior. + + + An options support function must have the + signature + +options(relopts local_relopts *) returns void + + The function is passed a pointer to a local_relopts + struct, which needs to be filled with a set of operator class + specific options. The options can be accessed from other support + functions using the PG_HAS_OPCLASS_OPTIONS() and + PG_GET_OPCLASS_OPTIONS() macros. + + + Currently, no B-Tree operator class has an options + support function. B-tree doesn't allow flexible representation of keys + like GiST, SP-GiST, GIN and BRIN do. So, options + probably doesn't have much application in the current B-tree index + access method. Nevertheless, this support function was added to B-tree + for uniformity, and will probably find uses during further + evolution of B-tree in PostgreSQL. + + + + + + + + + Implementation + + + This section covers B-Tree index implementation details that may be + of use to advanced users. See + src/backend/access/nbtree/README in the source + distribution for a much more detailed, internals-focused description + of the B-Tree implementation. + + + B-Tree Structure + + PostgreSQL B-Tree indexes are + multi-level tree structures, where each level of the tree can be + used as a doubly-linked list of pages. A single metapage is stored + in a fixed position at the start of the first segment file of the + index. All other pages are either leaf pages or internal pages. + Leaf pages are the pages on the lowest level of the tree. All + other levels consist of internal pages. Each leaf page contains + tuples that point to table rows. Each internal page contains + tuples that point to the next level down in the tree. Typically, + over 99% of all pages are leaf pages. Both internal pages and leaf + pages use the standard page format described in . + + + New leaf pages are added to a B-Tree index when an existing leaf + page cannot fit an incoming tuple. A page + split operation makes room for items that originally + belonged on the overflowing page by moving a portion of the items + to a new page. Page splits must also insert a new + downlink to the new page in the parent page, + which may cause the parent to split in turn. Page splits + cascade upwards in a recursive fashion. When the + root page finally cannot fit a new downlink, a root page + split operation takes place. This adds a new level to + the tree structure by creating a new root page that is one level + above the original root page. + + + + + Bottom-up index deletion + + B-Tree indexes are not directly aware that under MVCC, there might + be multiple extant versions of the same logical table row; to an + index, each tuple is an independent object that needs its own index + entry. Version churn tuples may sometimes + accumulate and adversely affect query latency and throughput. This + typically occurs with UPDATE-heavy workloads + where most individual updates cannot apply the + HOT optimization. Changing the value of only + one column covered by one index during an UPDATE + always necessitates a new set of index tuples + — one for each and every index on the + table. Note in particular that this includes indexes that were not + logically modified by the UPDATE. + All indexes will need a successor physical index tuple that points + to the latest version in the table. Each new tuple within each + index will generally need to coexist with the original + updated tuple for a short period of time (typically + until shortly after the UPDATE transaction + commits). + + + B-Tree indexes incrementally delete version churn index tuples by + performing bottom-up index deletion passes. + Each deletion pass is triggered in reaction to an anticipated + version churn page split. This only happens with + indexes that are not logically modified by + UPDATE statements, where concentrated build up + of obsolete versions in particular pages would occur otherwise. A + page split will usually be avoided, though it's possible that + certain implementation-level heuristics will fail to identify and + delete even one garbage index tuple (in which case a page split or + deduplication pass resolves the issue of an incoming new tuple not + fitting on a leaf page). The worst case number of versions that + any index scan must traverse (for any single logical row) is an + important contributor to overall system responsiveness and + throughput. A bottom-up index deletion pass targets suspected + garbage tuples in a single leaf page based on + qualitative distinctions involving logical + rows and versions. This contrasts with the top-down + index cleanup performed by autovacuum workers, which is triggered + when certain quantitative table-level + thresholds are exceeded (see ). + + + + Not all deletion operations that are performed within B-Tree + indexes are bottom-up deletion operations. There is a distinct + category of index tuple deletion: simple index tuple + deletion. This is a deferred maintenance operation + that deletes index tuples that are known to be safe to delete + (those whose item identifier's LP_DEAD bit is + already set). Like bottom-up index deletion, simple index + deletion takes place at the point that a page split is anticipated + as a way of avoiding the split. + + + Simple deletion is opportunistic in the sense that it can only + take place when recent index scans set the + LP_DEAD bits of affected items in passing. + Prior to PostgreSQL 14, the only + category of B-Tree deletion was simple deletion. The main + differences between it and bottom-up deletion are that only the + former is opportunistically driven by the activity of passing + index scans, while only the latter specifically targets version + churn from UPDATEs that do not logically modify + indexed columns. + + + + Bottom-up index deletion performs the vast majority of all garbage + index tuple cleanup for particular indexes with certain workloads. + This is expected with any B-Tree index that is subject to + significant version churn from UPDATEs that + rarely or never logically modify the columns that the index covers. + The average and worst case number of versions per logical row can + be kept low purely through targeted incremental deletion passes. + It's quite possible that the on-disk size of certain indexes will + never increase by even one single page/block despite + constant version churn from + UPDATEs. Even then, an exhaustive clean + sweep by a VACUUM operation (typically + run in an autovacuum worker process) will eventually be required as + a part of collective cleanup of the table and + each of its indexes. + + + Unlike VACUUM, bottom-up index deletion does not + provide any strong guarantees about how old the oldest garbage + index tuple may be. No index can be permitted to retain + floating garbage index tuples that became dead prior + to a conservative cutoff point shared by the table and all of its + indexes collectively. This fundamental table-level invariant makes + it safe to recycle table TIDs. This is how it + is possible for distinct logical rows to reuse the same table + TID over time (though this can never happen with + two logical rows whose lifetimes span the same + VACUUM cycle). + + + + + Deduplication + + A duplicate is a leaf page tuple (a tuple that points to a table + row) where all indexed key columns have values + that match corresponding column values from at least one other leaf + page tuple in the same index. Duplicate tuples are quite common in + practice. B-Tree indexes can use a special, space-efficient + representation for duplicates when an optional technique is + enabled: deduplication. + + + Deduplication works by periodically merging groups of duplicate + tuples together, forming a single posting list tuple for each + group. The column key value(s) only appear once in this + representation. This is followed by a sorted array of + TIDs that point to rows in the table. This + significantly reduces the storage size of indexes where each value + (or each distinct combination of column values) appears several + times on average. The latency of queries can be reduced + significantly. Overall query throughput may increase + significantly. The overhead of routine index vacuuming may also be + reduced significantly. + + + + B-Tree deduplication is just as effective with + duplicates that contain a NULL value, even though + NULL values are never equal to each other according to the + = member of any B-Tree operator class. As far + as any part of the implementation that understands the on-disk + B-Tree structure is concerned, NULL is just another value from the + domain of indexed values. + + + + The deduplication process occurs lazily, when a new item is + inserted that cannot fit on an existing leaf page, though only when + index tuple deletion could not free sufficient space for the new + item (typically deletion is briefly considered and then skipped + over). Unlike GIN posting list tuples, B-Tree posting list tuples + do not need to expand every time a new duplicate is inserted; they + are merely an alternative physical representation of the original + logical contents of the leaf page. This design prioritizes + consistent performance with mixed read-write workloads. Most + client applications will at least see a moderate performance + benefit from using deduplication. Deduplication is enabled by + default. + + + CREATE INDEX and REINDEX + apply deduplication to create posting list tuples, though the + strategy they use is slightly different. Each group of duplicate + ordinary tuples encountered in the sorted input taken from the + table is merged into a posting list tuple + before being added to the current pending leaf + page. Individual posting list tuples are packed with as many + TIDs as possible. Leaf pages are written out in + the usual way, without any separate deduplication pass. This + strategy is well-suited to CREATE INDEX and + REINDEX because they are once-off batch + operations. + + + Write-heavy workloads that don't benefit from deduplication due to + having few or no duplicate values in indexes will incur a small, + fixed performance penalty (unless deduplication is explicitly + disabled). The deduplicate_items storage + parameter can be used to disable deduplication within individual + indexes. There is never any performance penalty with read-only + workloads, since reading posting list tuples is at least as + efficient as reading the standard tuple representation. Disabling + deduplication isn't usually helpful. + + + It is sometimes possible for unique indexes (as well as unique + constraints) to use deduplication. This allows leaf pages to + temporarily absorb extra version churn duplicates. + Deduplication in unique indexes augments bottom-up index deletion, + especially in cases where a long-running transactions holds a + snapshot that blocks garbage collection. The goal is to buy time + for the bottom-up index deletion strategy to become effective + again. Delaying page splits until a single long-running + transaction naturally goes away can allow a bottom-up deletion pass + to succeed where an earlier deletion pass failed. + + + + A special heuristic is applied to determine whether a + deduplication pass in a unique index should take place. It can + often skip straight to splitting a leaf page, avoiding a + performance penalty from wasting cycles on unhelpful deduplication + passes. If you're concerned about the overhead of deduplication, + consider setting deduplicate_items = off + selectively. Leaving deduplication enabled in unique indexes has + little downside. + + + + Deduplication cannot be used in all cases due to + implementation-level restrictions. Deduplication safety is + determined when CREATE INDEX or + REINDEX is run. + + + Note that deduplication is deemed unsafe and cannot be used in the + following cases involving semantically significant differences + among equal datums: + + + + + + text, varchar, and char + cannot use deduplication when a + nondeterministic collation is used. Case + and accent differences must be preserved among equal datums. + + + + + + numeric cannot use deduplication. Numeric display + scale must be preserved among equal datums. + + + + + + jsonb cannot use deduplication, since the + jsonb B-Tree operator class uses + numeric internally. + + + + + + float4 and float8 cannot use + deduplication. These types have distinct representations for + -0 and 0, which are + nevertheless considered equal. This difference must be + preserved. + + + + + + There is one further implementation-level restriction that may be + lifted in a future version of + PostgreSQL: + + + + + + Container types (such as composite types, arrays, or range + types) cannot use deduplication. + + + + + + There is one further implementation-level restriction that applies + regardless of the operator class or collation used: + + + + + + INCLUDE indexes can never use deduplication. + + + + + + + + + diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml new file mode 100644 index 000000000000..f517a7d4aff2 --- /dev/null +++ b/doc/src/sgml/catalogs.sgml @@ -0,0 +1,13890 @@ + + + + + System Catalogs + + + The system catalogs are the place where a relational database + management system stores schema metadata, such as information about + tables and columns, and internal bookkeeping information. + PostgreSQL's system catalogs are regular + tables. You can drop and recreate the tables, add columns, insert + and update values, and severely mess up your system that way. + Normally, one should not change the system catalogs by hand, there + are normally SQL commands to do that. (For example, CREATE + DATABASE inserts a row into the + pg_database catalog — and actually + creates the database on disk.) There are some exceptions for + particularly esoteric operations, but many of those have been made + available as SQL commands over time, and so the need for direct manipulation + of the system catalogs is ever decreasing. + + + + Overview + + + lists the system catalogs. + More detailed documentation of each catalog follows below. + + + + Most system catalogs are copied from the template database during + database creation and are thereafter database-specific. A few + catalogs are physically shared across all databases in a cluster; + these are noted in the descriptions of the individual catalogs. + + + + System Catalogs + + + + + Catalog Name + Purpose + + + + + + pg_aggregate + aggregate functions + + + + pg_am + relation access methods + + + + pg_amop + access method operators + + + + pg_amproc + access method support functions + + + + pg_attrdef + column default values + + + + pg_attribute + table columns (attributes) + + + + pg_authid + authorization identifiers (roles) + + + + pg_auth_members + authorization identifier membership relationships + + + + pg_cast + casts (data type conversions) + + + + pg_class + tables, indexes, sequences, views (relations) + + + + pg_collation + collations (locale information) + + + + pg_constraint + check constraints, unique constraints, primary key constraints, foreign key constraints + + + + pg_conversion + encoding conversion information + + + + pg_database + databases within this database cluster + + + + pg_db_role_setting + per-role and per-database settings + + + + pg_default_acl + default privileges for object types + + + + pg_depend + dependencies between database objects + + + + pg_description + descriptions or comments on database objects + + + + pg_enum + enum label and value definitions + + + + pg_event_trigger + event triggers + + + + pg_extension + installed extensions + + + + pg_foreign_data_wrapper + foreign-data wrapper definitions + + + + pg_foreign_server + foreign server definitions + + + + pg_foreign_table + additional foreign table information + + + + pg_index + additional index information + + + + pg_inherits + table inheritance hierarchy + + + + pg_init_privs + object initial privileges + + + + pg_language + languages for writing functions + + + + pg_largeobject + data pages for large objects + + + + pg_largeobject_metadata + metadata for large objects + + + + pg_namespace + schemas + + + + pg_opclass + access method operator classes + + + + pg_operator + operators + + + + pg_opfamily + access method operator families + + + + pg_partitioned_table + information about partition key of tables + + + + pg_policy + row-security policies + + + + pg_proc + functions and procedures + + + + pg_publication + publications for logical replication + + + + pg_publication_rel + relation to publication mapping + + + + pg_range + information about range types + + + + pg_replication_origin + registered replication origins + + + + pg_rewrite + query rewrite rules + + + + pg_seclabel + security labels on database objects + + + + pg_sequence + information about sequences + + + + pg_shdepend + dependencies on shared objects + + + + pg_shdescription + comments on shared objects + + + + pg_shseclabel + security labels on shared database objects + + + + pg_statistic + planner statistics + + + + pg_statistic_ext + extended planner statistics (definition) + + + + pg_statistic_ext_data + extended planner statistics (built statistics) + + + + pg_subscription + logical replication subscriptions + + + + pg_subscription_rel + relation state for subscriptions + + + + pg_tablespace + tablespaces within this database cluster + + + + pg_transform + transforms (data type to procedural language conversions) + + + + pg_trigger + triggers + + + + pg_ts_config + text search configurations + + + + pg_ts_config_map + text search configurations' token mappings + + + + pg_ts_dict + text search dictionaries + + + + pg_ts_parser + text search parsers + + + + pg_ts_template + text search templates + + + + pg_type + data types + + + + pg_user_mapping + mappings of users to foreign servers + + + +
+
+ + + + <structname>pg_aggregate</structname> + + + pg_aggregate + + + + The catalog pg_aggregate stores information about + aggregate functions. An aggregate function is a function that + operates on a set of values (typically one column from each row + that matches a query condition) and returns a single value computed + from all these values. Typical aggregate functions are + sum, count, and + max. Each entry in + pg_aggregate is an extension of an entry + in pg_proc. + The pg_proc entry carries the aggregate's name, + input and output data types, and other information that is similar to + ordinary functions. + + + + <structname>pg_aggregate</structname> Columns + + + + + Column Type + + + Description + + + + + + + + aggfnoid regproc + (references pg_proc.oid) + + + pg_proc OID of the aggregate function + + + + + + aggkind char + + + Aggregate kind: + n for normal aggregates, + o for ordered-set aggregates, or + h for hypothetical-set aggregates + + + + + + aggnumdirectargs int2 + + + Number of direct (non-aggregated) arguments of an ordered-set or + hypothetical-set aggregate, counting a variadic array as one argument. + If equal to pronargs, the aggregate must be variadic + and the variadic array describes the aggregated arguments as well as + the final direct arguments. + Always zero for normal aggregates. + + + + + + aggtransfn regproc + (references pg_proc.oid) + + + Transition function + + + + + + aggfinalfn regproc + (references pg_proc.oid) + + + Final function (zero if none) + + + + + + aggcombinefn regproc + (references pg_proc.oid) + + + Combine function (zero if none) + + + + + + aggserialfn regproc + (references pg_proc.oid) + + + Serialization function (zero if none) + + + + + + aggdeserialfn regproc + (references pg_proc.oid) + + + Deserialization function (zero if none) + + + + + + aggmtransfn regproc + (references pg_proc.oid) + + + Forward transition function for moving-aggregate mode (zero if none) + + + + + + aggminvtransfn regproc + (references pg_proc.oid) + + + Inverse transition function for moving-aggregate mode (zero if none) + + + + + + aggmfinalfn regproc + (references pg_proc.oid) + + + Final function for moving-aggregate mode (zero if none) + + + + + + aggfinalextra bool + + + True to pass extra dummy arguments to aggfinalfn + + + + + + aggmfinalextra bool + + + True to pass extra dummy arguments to aggmfinalfn + + + + + + aggfinalmodify char + + + Whether aggfinalfn modifies the + transition state value: + r if it is read-only, + s if the aggtransfn + cannot be applied after the aggfinalfn, or + w if it writes on the value + + + + + + aggmfinalmodify char + + + Like aggfinalmodify, but for + the aggmfinalfn + + + + + + aggsortop oid + (references pg_operator.oid) + + + Associated sort operator (zero if none) + + + + + + aggtranstype oid + (references pg_type.oid) + + + Data type of the aggregate function's internal transition (state) data + + + + + + aggtransspace int4 + + + Approximate average size (in bytes) of the transition state + data, or zero to use a default estimate + + + + + + aggmtranstype oid + (references pg_type.oid) + + + Data type of the aggregate function's internal transition (state) + data for moving-aggregate mode (zero if none) + + + + + + aggmtransspace int4 + + + Approximate average size (in bytes) of the transition state data + for moving-aggregate mode, or zero to use a default estimate + + + + + + agginitval text + + + The initial value of the transition state. This is a text + field containing the initial value in its external string + representation. If this field is null, the transition state + value starts out null. + + + + + + aggminitval text + + + The initial value of the transition state for moving-aggregate mode. + This is a text field containing the initial value in its external + string representation. If this field is null, the transition state + value starts out null. + + + + +
+ + + New aggregate functions are registered with the CREATE AGGREGATE + command. See for more information about + writing aggregate functions and the meaning of the transition + functions, etc. + + +
+ + + + <structname>pg_am</structname> + + + pg_am + + + + The catalog pg_am stores information about + relation access methods. There is one row for each access method supported + by the system. + Currently, only tables and indexes have access methods. The requirements for table + and index access methods are discussed in detail in and + respectively. + + + + <structname>pg_am</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + amname name + + + Name of the access method + + + + + + amhandler regproc + (references pg_proc.oid) + + + OID of a handler function that is responsible for supplying information + about the access method + + + + + + amtype char + + + t = table (including materialized views), + i = index. + + + + +
+ + + + Before PostgreSQL 9.6, pg_am + contained many additional columns representing properties of index access + methods. That data is now only directly visible at the C code level. + However, pg_index_column_has_property() and related + functions have been added to allow SQL queries to inspect index access + method properties; see . + + + +
+ + + + <structname>pg_amop</structname> + + + pg_amop + + + + The catalog pg_amop stores information about + operators associated with access method operator families. There is one + row for each operator that is a member of an operator family. A family + member can be either a search operator or an + ordering operator. An operator + can appear in more than one family, but cannot appear in more than one + search position nor more than one ordering position within a family. + (It is allowed, though unlikely, for an operator to be used for both + search and ordering purposes.) + + + + <structname>pg_amop</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + amopfamily oid + (references pg_opfamily.oid) + + + The operator family this entry is for + + + + + + amoplefttype oid + (references pg_type.oid) + + + Left-hand input data type of operator + + + + + + amoprighttype oid + (references pg_type.oid) + + + Right-hand input data type of operator + + + + + + amopstrategy int2 + + + Operator strategy number + + + + + + amoppurpose char + + + Operator purpose, either s for search or + o for ordering + + + + + + amopopr oid + (references pg_operator.oid) + + + OID of the operator + + + + + + amopmethod oid + (references pg_am.oid) + + + Index access method operator family is for + + + + + + amopsortfamily oid + (references pg_opfamily.oid) + + + The B-tree operator family this entry sorts according to, if an + ordering operator; zero if a search operator + + + + +
+ + + A search operator entry indicates that an index of this operator + family can be searched to find all rows satisfying + WHERE + indexed_column + operator + constant. + Obviously, such an operator must return boolean, and its left-hand input + type must match the index's column data type. + + + + An ordering operator entry indicates that an index of this + operator family can be scanned to return rows in the order represented by + ORDER BY + indexed_column + operator + constant. + Such an operator could return any sortable data type, though again + its left-hand input type must match the index's column data type. + The exact semantics of the ORDER BY are specified by the + amopsortfamily column, which must reference + a B-tree operator family for the operator's result type. + + + + + At present, it's assumed that the sort order for an ordering operator + is the default for the referenced operator family, i.e., ASC NULLS + LAST. This might someday be relaxed by adding additional columns + to specify sort options explicitly. + + + + + An entry's amopmethod must match the + opfmethod of its containing operator family (including + amopmethod here is an intentional denormalization of the + catalog structure for performance reasons). Also, + amoplefttype and amoprighttype must match + the oprleft and oprright fields of the + referenced pg_operator entry. + + +
+ + + + <structname>pg_amproc</structname> + + + pg_amproc + + + + The catalog pg_amproc stores information about + support functions associated with access method operator families. There + is one row for each support function belonging to an operator family. + + + + <structname>pg_amproc</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + amprocfamily oid + (references pg_opfamily.oid) + + + The operator family this entry is for + + + + + + amproclefttype oid + (references pg_type.oid) + + + Left-hand input data type of associated operator + + + + + + amprocrighttype oid + (references pg_type.oid) + + + Right-hand input data type of associated operator + + + + + + amprocnum int2 + + + Support function number + + + + + + amproc regproc + (references pg_proc.oid) + + + OID of the function + + + + +
+ + + The usual interpretation of the + amproclefttype and amprocrighttype fields + is that they identify the left and right input types of the operator(s) + that a particular support function supports. For some access methods + these match the input data type(s) of the support function itself, for + others not. There is a notion of default support functions for + an index, which are those with amproclefttype and + amprocrighttype both equal to the index operator class's + opcintype. + + +
+ + + + <structname>pg_attrdef</structname> + + + pg_attrdef + + + + The catalog pg_attrdef stores column default + values. The main information about columns is stored in + pg_attribute. + Only columns for which a default value has been explicitly set will have + an entry here. + + + + <structname>pg_attrdef</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + adrelid oid + (references pg_class.oid) + + + The table this column belongs to + + + + + + adnum int2 + (references pg_attribute.attnum) + + + The number of the column + + + + + + adbin pg_node_tree + + + The column default value, in nodeToString() + representation. Use pg_get_expr(adbin, adrelid) to + convert it to an SQL expression. + + + + +
+
+ + + + <structname>pg_attribute</structname> + + + pg_attribute + + + + The catalog pg_attribute stores information about + table columns. There will be exactly one + pg_attribute row for every column in every + table in the database. (There will also be attribute entries for + indexes, and indeed all objects that have + pg_class + entries.) + + + + The term attribute is equivalent to column and is used for + historical reasons. + + + + <structname>pg_attribute</structname> Columns + + + + + Column Type + + + Description + + + + + + + + attrelid oid + (references pg_class.oid) + + + The table this column belongs to + + + + + + attname name + + + The column name + + + + + + atttypid oid + (references pg_type.oid) + + + The data type of this column (zero for a dropped column) + + + + + + attstattarget int4 + + + attstattarget controls the level of detail + of statistics accumulated for this column by + ANALYZE. + A zero value indicates that no statistics should be collected. + A negative value says to use the system default statistics target. + The exact meaning of positive values is data type-dependent. + For scalar data types, attstattarget + is both the target number of most common values + to collect, and the target number of histogram bins to create. + + + + + + attlen int2 + + + A copy of pg_type.typlen of this column's + type + + + + + + attnum int2 + + + The number of the column. Ordinary columns are numbered from 1 + up. System columns, such as ctid, + have (arbitrary) negative numbers. + + + + + + attndims int4 + + + Number of dimensions, if the column is an array type; otherwise 0. + (Presently, the number of dimensions of an array is not enforced, + so any nonzero value effectively means it's an array.) + + + + + + attcacheoff int4 + + + Always -1 in storage, but when loaded into a row descriptor + in memory this might be updated to cache the offset of the attribute + within the row + + + + + + atttypmod int4 + + + atttypmod records type-specific data + supplied at table creation time (for example, the maximum + length of a varchar column). It is passed to + type-specific input functions and length coercion functions. + The value will generally be -1 for types that do not need atttypmod. + + + + + + attbyval bool + + + A copy of pg_type.typbyval of this column's type + + + + + + attalign char + + + A copy of pg_type.typalign of this column's type + + + + + + attstorage char + + + Normally a copy of pg_type.typstorage of this + column's type. For TOAST-able data types, this can be altered + after column creation to control storage policy. + + + + + + attcompression char + + + The current compression method of the column. Typically this is + '\0' to specify use of the current default setting + (see ). Otherwise, + 'p' selects pglz compression, while + 'l' selects LZ4 + compression. However, this field is ignored + whenever attstorage does not allow + compression. + + + + + + attnotnull bool + + + This represents a not-null constraint. + + + + + + atthasdef bool + + + This column has a default expression or generation expression, in which + case there will be a corresponding entry in the + pg_attrdef catalog that actually defines the + expression. (Check attgenerated to + determine whether this is a default or a generation expression.) + + + + + + atthasmissing bool + + + This column has a value which is used where the column is entirely + missing from the row, as happens when a column is added with a + non-volatile DEFAULT value after the row is created. + The actual value used is stored in the + attmissingval column. + + + + + + attidentity char + + + If a zero byte (''), then not an identity column. + Otherwise, a = generated + always, d = generated by default. + + + + + + attgenerated char + + + If a zero byte (''), then not a generated column. + Otherwise, s = stored. (Other values might be added + in the future.) + + + + + + attisdropped bool + + + This column has been dropped and is no longer valid. A dropped + column is still physically present in the table, but is + ignored by the parser and so cannot be accessed via SQL. + + + + + + attislocal bool + + + This column is defined locally in the relation. Note that a column can + be locally defined and inherited simultaneously. + + + + + + attinhcount int4 + + + The number of direct ancestors this column has. A column with a + nonzero number of ancestors cannot be dropped nor renamed. + + + + + + attcollation oid + (references pg_collation.oid) + + + The defined collation of the column, or zero if the column is + not of a collatable data type + + + + + + attacl aclitem[] + + + Column-level access privileges, if any have been granted specifically + on this column + + + + + + attoptions text[] + + + Attribute-level options, as keyword=value strings + + + + + + attfdwoptions text[] + + + Attribute-level foreign data wrapper options, as keyword=value strings + + + + + + attmissingval anyarray + + + This column has a one element array containing the value used when the + column is entirely missing from the row, as happens when the column is + added with a non-volatile DEFAULT value after the + row is created. The value is only used when + atthasmissing is true. If there is no value + the column is null. + + + + +
+ + + In a dropped column's pg_attribute entry, + atttypid is reset to zero, but + attlen and the other fields copied from + pg_type are still valid. This arrangement is needed + to cope with the situation where the dropped column's data type was + later dropped, and so there is no pg_type row anymore. + attlen and the other fields can be used + to interpret the contents of a row of the table. + +
+ + + + <structname>pg_authid</structname> + + + pg_authid + + + + The catalog pg_authid contains information about + database authorization identifiers (roles). A role subsumes the concepts + of users and groups. A user is essentially just a + role with the rolcanlogin flag set. Any role (with or + without rolcanlogin) can have other roles as members; see + pg_auth_members. + + + + Since this catalog contains passwords, it must not be publicly readable. + pg_roles + is a publicly readable view on + pg_authid that blanks out the password field. + + + + contains detailed information about user and + privilege management. + + + + Because user identities are cluster-wide, + pg_authid + is shared across all databases of a cluster: there is only one + copy of pg_authid per cluster, not + one per database. + + + + <structname>pg_authid</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + rolname name + + + Role name + + + + + + rolsuper bool + + + Role has superuser privileges + + + + + + rolinherit bool + + + Role automatically inherits privileges of roles it is a + member of + + + + + + rolcreaterole bool + + + Role can create more roles + + + + + + rolcreatedb bool + + + Role can create databases + + + + + + rolcanlogin bool + + + Role can log in. That is, this role can be given as the initial + session authorization identifier. + + + + + + rolreplication bool + + + Role is a replication role. A replication role can initiate replication + connections and create and drop replication slots. + + + + + + rolbypassrls bool + + + Role bypasses every row-level security policy, see + for more information. + + + + + + rolconnlimit int4 + + + For roles that can log in, this sets maximum number of concurrent + connections this role can make. -1 means no limit. + + + + + + rolpassword text + + + Password (possibly encrypted); null if none. The format depends + on the form of encryption used. + + + + + + rolvaliduntil timestamptz + + + Password expiry time (only used for password authentication); + null if no expiration + + + + +
+ + + For an MD5 encrypted password, rolpassword + column will begin with the string md5 followed by a + 32-character hexadecimal MD5 hash. The MD5 hash will be of the user's + password concatenated to their user name. For example, if user + joe has password xyzzy, PostgreSQL + will store the md5 hash of xyzzyjoe. + + + + If the password is encrypted with SCRAM-SHA-256, it has the format: + +SCRAM-SHA-256$<iteration count>:<salt>$<StoredKey>:<ServerKey> + + where salt, StoredKey and + ServerKey are in Base64 encoded format. This format is + the same as that specified by RFC 5803. + + + + A password that does not follow either of those formats is assumed to be + unencrypted. + +
+ + + + <structname>pg_auth_members</structname> + + + pg_auth_members + + + + The catalog pg_auth_members shows the membership + relations between roles. Any non-circular set of relationships is allowed. + + + + Because user identities are cluster-wide, + pg_auth_members + is shared across all databases of a cluster: there is only one + copy of pg_auth_members per cluster, not + one per database. + + + + <structname>pg_auth_members</structname> Columns + + + + + Column Type + + + Description + + + + + + + + roleid oid + (references pg_authid.oid) + + + ID of a role that has a member + + + + + + member oid + (references pg_authid.oid) + + + ID of a role that is a member of roleid + + + + + + grantor oid + (references pg_authid.oid) + + + ID of the role that granted this membership + + + + + + admin_option bool + + + True if member can grant membership in + roleid to others + + + + +
+ +
+ + + + <structname>pg_cast</structname> + + + pg_cast + + + + The catalog pg_cast stores data type conversion + paths, both built-in and user-defined. + + + + It should be noted that pg_cast does not represent + every type conversion that the system knows how to perform; only those that + cannot be deduced from some generic rule. For example, casting between a + domain and its base type is not explicitly represented in + pg_cast. Another important exception is that + automatic I/O conversion casts, those performed using a data + type's own I/O functions to convert to or from text or other + string types, are not explicitly represented in + pg_cast. + + + + <structname>pg_cast</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + castsource oid + (references pg_type.oid) + + + OID of the source data type + + + + + + casttarget oid + (references pg_type.oid) + + + OID of the target data type + + + + + + castfunc oid + (references pg_proc.oid) + + + The OID of the function to use to perform this cast. Zero is + stored if the cast method doesn't require a function. + + + + + + castcontext char + + + Indicates what contexts the cast can be invoked in. + e means only as an explicit cast (using + CAST or :: syntax). + a means implicitly in assignment + to a target column, as well as explicitly. + i means implicitly in expressions, as well as the + other cases. + + + + + + castmethod char + + + Indicates how the cast is performed. + f means that the function specified in the castfunc field is used. + i means that the input/output functions are used. + b means that the types are binary-coercible, thus no conversion is required. + + + + +
+ + + The cast functions listed in pg_cast must + always take the cast source type as their first argument type, and + return the cast destination type as their result type. A cast + function can have up to three arguments. The second argument, + if present, must be type integer; it receives the type + modifier associated with the destination type, or -1 + if there is none. The third argument, + if present, must be type boolean; it receives true + if the cast is an explicit cast, false otherwise. + + + + It is legitimate to create a pg_cast entry + in which the source and target types are the same, if the associated + function takes more than one argument. Such entries represent + length coercion functions that coerce values of the type + to be legal for a particular type modifier value. + + + + When a pg_cast entry has different source and + target types and a function that takes more than one argument, it + represents converting from one type to another and applying a length + coercion in a single step. When no such entry is available, coercion + to a type that uses a type modifier involves two steps, one to + convert between data types and a second to apply the modifier. + +
+ + + <structname>pg_class</structname> + + + pg_class + + + + The catalog pg_class catalogs tables and most + everything else that has columns or is otherwise similar to a + table. This includes indexes (but see also pg_index), + sequences (but see also pg_sequence), + views, materialized views, composite types, and TOAST tables; + see relkind. + Below, when we mean all of these kinds of objects we speak of + relations. Not all columns are meaningful for all relation + types. + + + + <structname>pg_class</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + relname name + + + Name of the table, index, view, etc. + + + + + + relnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this relation + + + + + + reltype oid + (references pg_type.oid) + + + The OID of the data type that corresponds to this table's row type, + if any; zero for indexes, sequences, and toast tables, which have + no pg_type entry + + + + + + reloftype oid + (references pg_type.oid) + + + For typed tables, the OID of the underlying composite type; + zero for all other relations + + + + + + relowner oid + (references pg_authid.oid) + + + Owner of the relation + + + + + + relam oid + (references pg_am.oid) + + + If this is a table or an index, the access method used (heap, + B-tree, hash, etc.); otherwise zero (zero occurs for sequences, + as well as relations without storage, such as views) + + + + + + relfilenode oid + + + Name of the on-disk file of this relation; zero means this + is a mapped relation whose disk file name is determined + by low-level state + + + + + + reltablespace oid + (references pg_tablespace.oid) + + + The tablespace in which this relation is stored. If zero, + the database's default tablespace is implied. (Not meaningful + if the relation has no on-disk file.) + + + + + + relpages int4 + + + Size of the on-disk representation of this table in pages (of size + BLCKSZ). This is only an estimate used by the + planner. It is updated by VACUUM, + ANALYZE, and a few DDL commands such as + CREATE INDEX. + + + + + + reltuples float4 + + + Number of live rows in the table. This is only an estimate used by + the planner. It is updated by VACUUM, + ANALYZE, and a few DDL commands such as + CREATE INDEX. + If the table has never yet been vacuumed or + analyzed, reltuples + contains -1 indicating that the row count is + unknown. + + + + + + relallvisible int4 + + + Number of pages that are marked all-visible in the table's + visibility map. This is only an estimate used by the + planner. It is updated by VACUUM, + ANALYZE, and a few DDL commands such as + CREATE INDEX. + + + + + + reltoastrelid oid + (references pg_class.oid) + + + OID of the TOAST table associated with this table, zero if none. The + TOAST table stores large attributes out of line in a + secondary table. + + + + + + relhasindex bool + + + True if this is a table and it has (or recently had) any indexes + + + + + + relisshared bool + + + True if this table is shared across all databases in the cluster. Only + certain system catalogs (such as pg_database) + are shared. + + + + + + relpersistence char + + + p = permanent table, u = unlogged table, + t = temporary table + + + + + + relkind char + + + r = ordinary table, + i = index, + S = sequence, + t = TOAST table, + v = view, + m = materialized view, + c = composite type, + f = foreign table, + p = partitioned table, + I = partitioned index + + + + + + relnatts int2 + + + Number of user columns in the relation (system columns not + counted). There must be this many corresponding entries in + pg_attribute. See also + pg_attribute.attnum. + + + + + + relchecks int2 + + + Number of CHECK constraints on the table; see + pg_constraint catalog + + + + + + relhasrules bool + + + True if table has (or once had) rules; see + pg_rewrite catalog + + + + + + relhastriggers bool + + + True if table has (or once had) triggers; see + pg_trigger catalog + + + + + + relhassubclass bool + + + True if table or index has (or once had) any inheritance children + + + + + + relrowsecurity bool + + + True if table has row-level security enabled; see + pg_policy catalog + + + + + + relforcerowsecurity bool + + + True if row-level security (when enabled) will also apply to table owner; see + pg_policy catalog + + + + + + relispopulated bool + + + True if relation is populated (this is true for all + relations other than some materialized views) + + + + + + relreplident char + + + Columns used to form replica identity for rows: + d = default (primary key, if any), + n = nothing, + f = all columns, + i = index with + indisreplident set (same as nothing if the + index used has been dropped) + + + + + + relispartition bool + + + True if table or index is a partition + + + + + + relrewrite oid + (references pg_class.oid) + + + For new relations being written during a DDL operation that requires a + table rewrite, this contains the OID of the original relation; + otherwise zero. That state is only visible internally; this field should + never contain anything other than zero for a user-visible relation. + + + + + + relfrozenxid xid + + + All transaction IDs before this one have been replaced with a permanent + (frozen) transaction ID in this table. This is used to track + whether the table needs to be vacuumed in order to prevent transaction + ID wraparound or to allow pg_xact to be shrunk. Zero + (InvalidTransactionId) if the relation is not a table. + + + + + + relminmxid xid + + + All multixact IDs before this one have been replaced by a + transaction ID in this table. This is used to track + whether the table needs to be vacuumed in order to prevent multixact ID + wraparound or to allow pg_multixact to be shrunk. Zero + (InvalidMultiXactId) if the relation is not a table. + + + + + + relacl aclitem[] + + + Access privileges; see for details + + + + + + reloptions text[] + + + Access-method-specific options, as keyword=value strings + + + + + + relpartbound pg_node_tree + + + If table is a partition (see relispartition), + internal representation of the partition bound + + + + +
+ + + Several of the Boolean flags in pg_class are maintained + lazily: they are guaranteed to be true if that's the correct state, but + may not be reset to false immediately when the condition is no longer + true. For example, relhasindex is set by + CREATE INDEX, but it is never cleared by + DROP INDEX. Instead, VACUUM clears + relhasindex if it finds the table has no indexes. This + arrangement avoids race conditions and improves concurrency. + +
+ + + <structname>pg_collation</structname> + + + pg_collation + + + + The catalog pg_collation describes the + available collations, which are essentially mappings from an SQL + name to operating system locale categories. + See for more information. + + + + <structname>pg_collation</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + collname name + + + Collation name (unique per namespace and encoding) + + + + + + collnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this collation + + + + + + collowner oid + (references pg_authid.oid) + + + Owner of the collation + + + + + + collprovider char + + + Provider of the collation: d = database + default, c = libc, i = icu + + + + + + collisdeterministic bool + + + Is the collation deterministic? + + + + + + collencoding int4 + + + Encoding in which the collation is applicable, or -1 if it + works for any encoding + + + + + + collcollate name + + + LC_COLLATE for this collation object + + + + + + collctype name + + + LC_CTYPE for this collation object + + + + + + collversion text + + + Provider-specific version of the collation. This is recorded when the + collation is created and then checked when it is used, to detect + changes in the collation definition that could lead to data corruption. + + + + +
+ + + Note that the unique key on this catalog is (collname, + collencoding, collnamespace) not just + (collname, collnamespace). + PostgreSQL generally ignores all + collations that do not have collencoding equal to + either the current database's encoding or -1, and creation of new entries + with the same name as an entry with collencoding = -1 + is forbidden. Therefore it is sufficient to use a qualified SQL name + (schema.name) to identify a collation, + even though this is not unique according to the catalog definition. + The reason for defining the catalog this way is that + initdb fills it in at cluster initialization time with + entries for all locales available on the system, so it must be able to + hold entries for all encodings that might ever be used in the cluster. + + + + In the template0 database, it could be useful to create + collations whose encoding does not match the database encoding, + since they could match the encodings of databases later cloned from + template0. This would currently have to be done manually. + +
+ + + <structname>pg_constraint</structname> + + + pg_constraint + + + + The catalog pg_constraint stores check, primary + key, unique, foreign key, and exclusion constraints on tables. + (Column constraints are not treated specially. Every column constraint is + equivalent to some table constraint.) + Not-null constraints are represented in the + pg_attribute + catalog, not here. + + + + User-defined constraint triggers (created with + CREATE CONSTRAINT TRIGGER) also give rise to an entry in this table. + + + + Check constraints on domains are stored here, too. + + + + <structname>pg_constraint</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + conname name + + + Constraint name (not necessarily unique!) + + + + + + connamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this constraint + + + + + + contype char + + + c = check constraint, + f = foreign key constraint, + p = primary key constraint, + u = unique constraint, + t = constraint trigger, + x = exclusion constraint + + + + + + condeferrable bool + + + Is the constraint deferrable? + + + + + + condeferred bool + + + Is the constraint deferred by default? + + + + + + convalidated bool + + + Has the constraint been validated? + Currently, can be false only for foreign keys and CHECK constraints + + + + + + conrelid oid + (references pg_class.oid) + + + The table this constraint is on; zero if not a table constraint + + + + + + contypid oid + (references pg_type.oid) + + + The domain this constraint is on; zero if not a domain constraint + + + + + + conindid oid + (references pg_class.oid) + + + The index supporting this constraint, if it's a unique, primary + key, foreign key, or exclusion constraint; else zero + + + + + + conparentid oid + (references pg_constraint.oid) + + + The corresponding constraint of the parent partitioned table, + if this is a constraint on a partition; else zero + + + + + + confrelid oid + (references pg_class.oid) + + + If a foreign key, the referenced table; else zero + + + + + + confupdtype char + + + Foreign key update action code: + a = no action, + r = restrict, + c = cascade, + n = set null, + d = set default + + + + + + confdeltype char + + + Foreign key deletion action code: + a = no action, + r = restrict, + c = cascade, + n = set null, + d = set default + + + + + + confmatchtype char + + + Foreign key match type: + f = full, + p = partial, + s = simple + + + + + + conislocal bool + + + This constraint is defined locally for the relation. Note that a + constraint can be locally defined and inherited simultaneously. + + + + + + coninhcount int4 + + + The number of direct inheritance ancestors this constraint has. + A constraint with + a nonzero number of ancestors cannot be dropped nor renamed. + + + + + + connoinherit bool + + + This constraint is defined locally for the relation. It is a + non-inheritable constraint. + + + + + + conkey int2[] + (references pg_attribute.attnum) + + + If a table constraint (including foreign keys, but not constraint + triggers), list of the constrained columns + + + + + + confkey int2[] + (references pg_attribute.attnum) + + + If a foreign key, list of the referenced columns + + + + + + conpfeqop oid[] + (references pg_operator.oid) + + + If a foreign key, list of the equality operators for PK = FK comparisons + + + + + + conppeqop oid[] + (references pg_operator.oid) + + + If a foreign key, list of the equality operators for PK = PK comparisons + + + + + + conffeqop oid[] + (references pg_operator.oid) + + + If a foreign key, list of the equality operators for FK = FK comparisons + + + + + + conexclop oid[] + (references pg_operator.oid) + + + If an exclusion constraint, list of the per-column exclusion operators + + + + + + conbin pg_node_tree + + + If a check constraint, an internal representation of the + expression. (It's recommended to use + pg_get_constraintdef() to extract the definition of + a check constraint.) + + + + +
+ + + In the case of an exclusion constraint, conkey + is only useful for constraint elements that are simple column references. + For other cases, a zero appears in conkey + and the associated index must be consulted to discover the expression + that is constrained. (conkey thus has the + same contents as pg_index.indkey for the + index.) + + + + + pg_class.relchecks needs to agree with the + number of check-constraint entries found in this table for each + relation. + + +
+ + + + <structname>pg_conversion</structname> + + + pg_conversion + + + + The catalog pg_conversion describes + encoding conversion functions. See + for more information. + + + + <structname>pg_conversion</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + conname name + + + Conversion name (unique within a namespace) + + + + + + connamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this conversion + + + + + + conowner oid + (references pg_authid.oid) + + + Owner of the conversion + + + + + + conforencoding int4 + + + Source encoding ID + + + + + + contoencoding int4 + + + Destination encoding ID + + + + + + conproc regproc + (references pg_proc.oid) + + + Conversion function + + + + + + condefault bool + + + True if this is the default conversion + + + + +
+ +
+ + + <structname>pg_database</structname> + + + pg_database + + + + The catalog pg_database stores information about + the available databases. Databases are created with the CREATE DATABASE command. + Consult for details about the meaning + of some of the parameters. + + + + Unlike most system catalogs, pg_database + is shared across all databases of a cluster: there is only one + copy of pg_database per cluster, not + one per database. + + + + <structname>pg_database</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + datname name + + + Database name + + + + + + datdba oid + (references pg_authid.oid) + + + Owner of the database, usually the user who created it + + + + + + encoding int4 + + + Character encoding for this database + (pg_encoding_to_char() can translate + this number to the encoding name) + + + + + + datcollate name + + + LC_COLLATE for this database + + + + + + datctype name + + + LC_CTYPE for this database + + + + + + datistemplate bool + + + If true, then this database can be cloned by + any user with CREATEDB privileges; + if false, then only superusers or the owner of + the database can clone it. + + + + + + datallowconn bool + + + If false then no one can connect to this database. This is + used to protect the template0 database from being altered. + + + + + + datconnlimit int4 + + + Sets maximum number of concurrent connections that can be made + to this database. -1 means no limit. + + + + + + datlastsysoid oid + + + Last system OID in the database; useful + particularly to pg_dump + + + + + + datfrozenxid xid + + + All transaction IDs before this one have been replaced with a permanent + (frozen) transaction ID in this database. This is used to + track whether the database needs to be vacuumed in order to prevent + transaction ID wraparound or to allow pg_xact to be shrunk. + It is the minimum of the per-table + pg_class.relfrozenxid values. + + + + + + datminmxid xid + + + All multixact IDs before this one have been replaced with a + transaction ID in this database. This is used to + track whether the database needs to be vacuumed in order to prevent + multixact ID wraparound or to allow pg_multixact to be shrunk. + It is the minimum of the per-table + pg_class.relminmxid values. + + + + + + dattablespace oid + (references pg_tablespace.oid) + + + The default tablespace for the database. + Within this database, all tables for which + pg_class.reltablespace is zero + will be stored in this tablespace; in particular, all the non-shared + system catalogs will be there. + + + + + + datacl aclitem[] + + + Access privileges; see for details + + + + +
+
+ + + + <structname>pg_db_role_setting</structname> + + + pg_db_role_setting + + + + The catalog pg_db_role_setting records the default + values that have been set for run-time configuration variables, + for each role and database combination. + + + + Unlike most system catalogs, pg_db_role_setting + is shared across all databases of a cluster: there is only one + copy of pg_db_role_setting per cluster, not + one per database. + + + + <structname>pg_db_role_setting</structname> Columns + + + + + Column Type + + + Description + + + + + + + + setdatabase oid + (references pg_database.oid) + + + The OID of the database the setting is applicable to, or zero if not database-specific + + + + + + setrole oid + (references pg_authid.oid) + + + The OID of the role the setting is applicable to, or zero if not role-specific + + + + + + setconfig text[] + + + Defaults for run-time configuration variables + + + + +
+
+ + + + <structname>pg_default_acl</structname> + + + pg_default_acl + + + + The catalog pg_default_acl stores initial + privileges to be assigned to newly created objects. + + + + <structname>pg_default_acl</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + defaclrole oid + (references pg_authid.oid) + + + The OID of the role associated with this entry + + + + + + defaclnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace associated with this entry, + or zero if none + + + + + + defaclobjtype char + + + Type of object this entry is for: + r = relation (table, view), + S = sequence, + f = function, + T = type, + n = schema + + + + + + defaclacl aclitem[] + + + Access privileges that this type of object should have on creation + + + + +
+ + + A pg_default_acl entry shows the initial privileges to + be assigned to an object belonging to the indicated user. There are + currently two types of entry: global entries with + defaclnamespace = zero, and per-schema entries + that reference a particular schema. If a global entry is present then + it overrides the normal hard-wired default privileges + for the object type. A per-schema entry, if present, represents privileges + to be added to the global or hard-wired default privileges. + + + + Note that when an ACL entry in another catalog is null, it is taken + to represent the hard-wired default privileges for its object, + not whatever might be in pg_default_acl + at the moment. pg_default_acl is only consulted during + object creation. + + +
+ + + + <structname>pg_depend</structname> + + + pg_depend + + + + The catalog pg_depend records the dependency + relationships between database objects. This information allows + DROP commands to find which other objects must be dropped + by DROP CASCADE or prevent dropping in the DROP + RESTRICT case. + + + + See also pg_shdepend, + which performs a similar function for dependencies involving objects + that are shared across a database cluster. + + + + <structname>pg_depend</structname> Columns + + + + + Column Type + + + Description + + + + + + + + classid oid + (references pg_class.oid) + + + The OID of the system catalog the dependent object is in, + or zero for a DEPENDENCY_PIN entry + + + + + + objid oid + (references any OID column) + + + The OID of the specific dependent object, + or zero for a DEPENDENCY_PIN entry + + + + + + objsubid int4 + + + For a table column, this is the column number (the + objid and classid refer to the + table itself). For all other object types, this column is + zero. + + + + + + refclassid oid + (references pg_class.oid) + + + The OID of the system catalog the referenced object is in + + + + + + refobjid oid + (references any OID column) + + + The OID of the specific referenced object + + + + + + refobjsubid int4 + + + For a table column, this is the column number (the + refobjid and refclassid refer + to the table itself). For all other object types, this column + is zero. + + + + + + deptype char + + + A code defining the specific semantics of this dependency relationship; see text + + + + +
+ + + In all cases, a pg_depend entry indicates that the + referenced object cannot be dropped without also dropping the dependent + object. However, there are several subflavors identified by + deptype: + + + + DEPENDENCY_NORMAL (n) + + + A normal relationship between separately-created objects. The + dependent object can be dropped without affecting the + referenced object. The referenced object can only be dropped + by specifying CASCADE, in which case the dependent + object is dropped, too. Example: a table column has a normal + dependency on its data type. + + + + + + DEPENDENCY_AUTO (a) + + + The dependent object can be dropped separately from the + referenced object, and should be automatically dropped + (regardless of RESTRICT or CASCADE + mode) if the referenced object is dropped. Example: a named + constraint on a table is made auto-dependent on the table, so + that it will go away if the table is dropped. + + + + + + DEPENDENCY_INTERNAL (i) + + + The dependent object was created as part of creation of the + referenced object, and is really just a part of its internal + implementation. A direct DROP of the dependent + object will be disallowed outright (we'll tell the user to issue + a DROP against the referenced object, instead). + A DROP of the referenced object will result in + automatically dropping the dependent object + whether CASCADE is specified or not. If the + dependent object has to be dropped due to a dependency on some other + object being removed, its drop is converted to a drop of the referenced + object, so that NORMAL and AUTO + dependencies of the dependent object behave much like they were + dependencies of the referenced object. + Example: a view's ON SELECT rule is made + internally dependent on the view, preventing it from being dropped + while the view remains. Dependencies of the rule (such as tables it + refers to) act as if they were dependencies of the view. + + + + + + DEPENDENCY_PARTITION_PRI (P) + DEPENDENCY_PARTITION_SEC (S) + + + The dependent object was created as part of creation of the + referenced object, and is really just a part of its internal + implementation; however, unlike INTERNAL, + there is more than one such referenced object. The dependent object + must not be dropped unless at least one of these referenced objects + is dropped; if any one is, the dependent object should be dropped + whether or not CASCADE is specified. Also + unlike INTERNAL, a drop of some other object + that the dependent object depends on does not result in automatic + deletion of any partition-referenced object. Hence, if the drop + does not cascade to at least one of these objects via some other + path, it will be refused. (In most cases, the dependent object + shares all its non-partition dependencies with at least one + partition-referenced object, so that this restriction does not + result in blocking any cascaded delete.) + Primary and secondary partition dependencies behave identically + except that the primary dependency is preferred for use in error + messages; hence, a partition-dependent object should have one + primary partition dependency and one or more secondary partition + dependencies. + Note that partition dependencies are made in addition to, not + instead of, any dependencies the object would normally have. This + simplifies ATTACH/DETACH PARTITION operations: + the partition dependencies need only be added or removed. + Example: a child partitioned index is made partition-dependent + on both the partition table it is on and the parent partitioned + index, so that it goes away if either of those is dropped, but + not otherwise. The dependency on the parent index is primary, + so that if the user tries to drop the child partitioned index, + the error message will suggest dropping the parent index instead + (not the table). + + + + + + DEPENDENCY_EXTENSION (e) + + + The dependent object is a member of the extension that is + the referenced object (see + pg_extension). + The dependent object can be dropped only via + DROP EXTENSION on the referenced object. + Functionally this dependency type acts the same as + an INTERNAL dependency, but it's kept separate for + clarity and to simplify pg_dump. + + + + + + DEPENDENCY_AUTO_EXTENSION (x) + + + The dependent object is not a member of the extension that is the + referenced object (and so it should not be ignored + by pg_dump), but it cannot function + without the extension and should be auto-dropped if the extension is. + The dependent object may be dropped on its own as well. + Functionally this dependency type acts the same as + an AUTO dependency, but it's kept separate for + clarity and to simplify pg_dump. + + + + + + DEPENDENCY_PIN (p) + + + There is no dependent object; this type of entry is a signal + that the system itself depends on the referenced object, and so + that object must never be deleted. Entries of this type are + created only by initdb. The columns for the + dependent object contain zeroes. + + + + + + Other dependency flavors might be needed in future. + + + + Note that it's quite possible for two objects to be linked by more than + one pg_depend entry. For example, a child + partitioned index would have both a partition-type dependency on its + associated partition table, and an auto dependency on each column of + that table that it indexes. This sort of situation expresses the union + of multiple dependency semantics. A dependent object can be dropped + without CASCADE if any of its dependencies satisfies + its condition for automatic dropping. Conversely, all the + dependencies' restrictions about which objects must be dropped together + must be satisfied. + + +
+ + + + <structname>pg_description</structname> + + + pg_description + + + + The catalog pg_description stores optional descriptions + (comments) for each database object. Descriptions can be manipulated + with the COMMENT command and viewed with + psql's \d commands. + Descriptions of many built-in system objects are provided in the initial + contents of pg_description. + + + + See also pg_shdescription, + which performs a similar function for descriptions involving objects that + are shared across a database cluster. + + + + <structname>pg_description</structname> Columns + + + + + Column Type + + + Description + + + + + + + + objoid oid + (references any OID column) + + + The OID of the object this description pertains to + + + + + + classoid oid + (references pg_class.oid) + + + The OID of the system catalog this object appears in + + + + + + objsubid int4 + + + For a comment on a table column, this is the column number (the + objoid and classoid refer to + the table itself). For all other object types, this column is + zero. + + + + + + description text + + + Arbitrary text that serves as the description of this object + + + + +
+ +
+ + + + <structname>pg_enum</structname> + + + pg_enum + + + + The pg_enum catalog contains entries + showing the values and labels for each enum type. The + internal representation of a given enum value is actually the OID + of its associated row in pg_enum. + + + + <structname>pg_enum</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + enumtypid oid + (references pg_type.oid) + + + The OID of the pg_type entry owning this enum value + + + + + + enumsortorder float4 + + + The sort position of this enum value within its enum type + + + + + + enumlabel name + + + The textual label for this enum value + + + + +
+ + + The OIDs for pg_enum rows follow a special + rule: even-numbered OIDs are guaranteed to be ordered in the same way + as the sort ordering of their enum type. That is, if two even OIDs + belong to the same enum type, the smaller OID must have the smaller + enumsortorder value. Odd-numbered OID values + need bear no relationship to the sort order. This rule allows the + enum comparison routines to avoid catalog lookups in many common cases. + The routines that create and alter enum types attempt to assign even + OIDs to enum values whenever possible. + + + + When an enum type is created, its members are assigned sort-order + positions 1..n. But members added later might be given + negative or fractional values of enumsortorder. + The only requirement on these values is that they be correctly + ordered and unique within each enum type. + +
+ + + + <structname>pg_event_trigger</structname> + + + pg_event_trigger + + + + The catalog pg_event_trigger stores event triggers. + See for more information. + + + + <structname>pg_event_trigger</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + evtname name + + + Trigger name (must be unique) + + + + + + evtevent name + + + Identifies the event for which this trigger fires + + + + + + evtowner oid + (references pg_authid.oid) + + + Owner of the event trigger + + + + + + evtfoid oid + (references pg_proc.oid) + + + The function to be called + + + + + + evtenabled char + + + Controls in which modes + the event trigger fires. + O = trigger fires in origin and local modes, + D = trigger is disabled, + R = trigger fires in replica mode, + A = trigger fires always. + + + + + + evttags text[] + + + Command tags for which this trigger will fire. If NULL, the firing + of this trigger is not restricted on the basis of the command tag. + + + + +
+
+ + + + <structname>pg_extension</structname> + + + pg_extension + + + + The catalog pg_extension stores information + about the installed extensions. See + for details about extensions. + + + + <structname>pg_extension</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + extname name + + + Name of the extension + + + + + + extowner oid + (references pg_authid.oid) + + + Owner of the extension + + + + + + extnamespace oid + (references pg_namespace.oid) + + + Schema containing the extension's exported objects + + + + + + extrelocatable bool + + + True if extension can be relocated to another schema + + + + + + extversion text + + + Version name for the extension + + + + + + extconfig oid[] + (references pg_class.oid) + + + Array of regclass OIDs for the extension's configuration + table(s), or NULL if none + + + + + + extcondition text[] + + + Array of WHERE-clause filter conditions for the + extension's configuration table(s), or NULL if none + + + + +
+ + + Note that unlike most catalogs with a namespace column, + extnamespace is not meant to imply + that the extension belongs to that schema. Extension names are never + schema-qualified. Rather, extnamespace + indicates the schema that contains most or all of the extension's + objects. If extrelocatable is true, then + this schema must in fact contain all schema-qualifiable objects + belonging to the extension. + +
+ + + + <structname>pg_foreign_data_wrapper</structname> + + + pg_foreign_data_wrapper + + + + The catalog pg_foreign_data_wrapper stores + foreign-data wrapper definitions. A foreign-data wrapper is the + mechanism by which external data, residing on foreign servers, is + accessed. + + + + <structname>pg_foreign_data_wrapper</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + fdwname name + + + Name of the foreign-data wrapper + + + + + + fdwowner oid + (references pg_authid.oid) + + + Owner of the foreign-data wrapper + + + + + + fdwhandler oid + (references pg_proc.oid) + + + References a handler function that is responsible for + supplying execution routines for the foreign-data wrapper. + Zero if no handler is provided + + + + + + fdwvalidator oid + (references pg_proc.oid) + + + References a validator function that is responsible for + checking the validity of the options given to the + foreign-data wrapper, as well as options for foreign servers and user + mappings using the foreign-data wrapper. Zero if no validator + is provided + + + + + + fdwacl aclitem[] + + + Access privileges; see for details + + + + + + fdwoptions text[] + + + Foreign-data wrapper specific options, as keyword=value strings + + + + +
+
+ + + + <structname>pg_foreign_server</structname> + + + pg_foreign_server + + + + The catalog pg_foreign_server stores + foreign server definitions. A foreign server describes a source + of external data, such as a remote server. Foreign + servers are accessed via foreign-data wrappers. + + + + <structname>pg_foreign_server</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + srvname name + + + Name of the foreign server + + + + + + srvowner oid + (references pg_authid.oid) + + + Owner of the foreign server + + + + + + srvfdw oid + (references pg_foreign_data_wrapper.oid) + + + OID of the foreign-data wrapper of this foreign server + + + + + + srvtype text + + + Type of the server (optional) + + + + + + srvversion text + + + Version of the server (optional) + + + + + + srvacl aclitem[] + + + Access privileges; see for details + + + + + + srvoptions text[] + + + Foreign server specific options, as keyword=value strings + + + + +
+
+ + + + <structname>pg_foreign_table</structname> + + + pg_foreign_table + + + + The catalog pg_foreign_table contains + auxiliary information about foreign tables. A foreign table is + primarily represented by a + pg_class + entry, just like a regular table. Its pg_foreign_table + entry contains the information that is pertinent only to foreign tables + and not any other kind of relation. + + + + <structname>pg_foreign_table</structname> Columns + + + + + Column Type + + + Description + + + + + + + + ftrelid oid + (references pg_class.oid) + + + The OID of the pg_class entry for this foreign table + + + + + + ftserver oid + (references pg_foreign_server.oid) + + + OID of the foreign server for this foreign table + + + + + + ftoptions text[] + + + Foreign table options, as keyword=value strings + + + + +
+
+ + + + <structname>pg_index</structname> + + + pg_index + + + + The catalog pg_index contains part of the information + about indexes. The rest is mostly in + pg_class. + + + + <structname>pg_index</structname> Columns + + + + + Column Type + + + Description + + + + + + + + indexrelid oid + (references pg_class.oid) + + + The OID of the pg_class entry for this index + + + + + + indrelid oid + (references pg_class.oid) + + + The OID of the pg_class entry for the table this index is for + + + + + + indnatts int2 + + + The total number of columns in the index (duplicates + pg_class.relnatts); this number includes both key and included attributes + + + + + + indnkeyatts int2 + + + The number of key columns in the index, + not counting any included columns, which are + merely stored and do not participate in the index semantics + + + + + + indisunique bool + + + If true, this is a unique index + + + + + + indisprimary bool + + + If true, this index represents the primary key of the table + (indisunique should always be true when this is true) + + + + + + indisexclusion bool + + + If true, this index supports an exclusion constraint + + + + + + indimmediate bool + + + If true, the uniqueness check is enforced immediately on + insertion + (irrelevant if indisunique is not true) + + + + + + indisclustered bool + + + If true, the table was last clustered on this index + + + + + + indisvalid bool + + + If true, the index is currently valid for queries. False means the + index is possibly incomplete: it must still be modified by + INSERT/UPDATE operations, but it cannot safely + be used for queries. If it is unique, the uniqueness property is not + guaranteed true either. + + + + + + indcheckxmin bool + + + If true, queries must not use the index until the xmin + of this pg_index row is below their TransactionXmin + event horizon, because the table may contain broken HOT chains with + incompatible rows that they can see + + + + + + indisready bool + + + If true, the index is currently ready for inserts. False means the + index must be ignored by INSERT/UPDATE + operations. + + + + + + indislive bool + + + If false, the index is in process of being dropped, and should be + ignored for all purposes (including HOT-safety decisions) + + + + + + indisreplident bool + + + If true this index has been chosen as replica identity + using ALTER TABLE ... + REPLICA IDENTITY USING INDEX ... + + + + + + indkey int2vector + (references pg_attribute.attnum) + + + This is an array of indnatts values that + indicate which table columns this index indexes. For example a value + of 1 3 would mean that the first and the third table + columns make up the index entries. Key columns come before non-key + (included) columns. A zero in this array indicates that the + corresponding index attribute is an expression over the table columns, + rather than a simple column reference. + + + + + + indcollation oidvector + (references pg_collation.oid) + + + For each column in the index key + (indnkeyatts values), this contains the OID + of the collation to use for the index, or zero if the column is not of + a collatable data type. + + + + + + indclass oidvector + (references pg_opclass.oid) + + + For each column in the index key + (indnkeyatts values), this contains the OID + of the operator class to use. See + pg_opclass for details. + + + + + + indoption int2vector + + + This is an array of indnkeyatts values that + store per-column flag bits. The meaning of the bits is defined by + the index's access method. + + + + + + indexprs pg_node_tree + + + Expression trees (in nodeToString() + representation) for index attributes that are not simple column + references. This is a list with one element for each zero + entry in indkey. Null if all index attributes + are simple references. + + + + + + indpred pg_node_tree + + + Expression tree (in nodeToString() + representation) for partial index predicate. Null if not a + partial index. + + + + +
+ +
+ + + + <structname>pg_inherits</structname> + + + pg_inherits + + + + The catalog pg_inherits records information about + table and index inheritance hierarchies. There is one entry for each direct + parent-child table or index relationship in the database. (Indirect + inheritance can be determined by following chains of entries.) + + + + <structname>pg_inherits</structname> Columns + + + + + Column Type + + + Description + + + + + + + + inhrelid oid + (references pg_class.oid) + + + The OID of the child table or index + + + + + + inhparent oid + (references pg_class.oid) + + + The OID of the parent table or index + + + + + + inhseqno int4 + + + If there is more than one direct parent for a child table (multiple + inheritance), this number tells the order in which the + inherited columns are to be arranged. The count starts at 1. + + + Indexes cannot have multiple inheritance, since they can only inherit + when using declarative partitioning. + + + + + + inhdetachpending bool + + + true for a partition that is in the process of + being detached; false otherwise. + + + + +
+ +
+ + + <structname>pg_init_privs</structname> + + + pg_init_privs + + + + The catalog pg_init_privs records information about + the initial privileges of objects in the system. There is one entry + for each object in the database which has a non-default (non-NULL) + initial set of privileges. + + + + Objects can have initial privileges either by having those privileges set + when the system is initialized (by initdb) or when the + object is created during a CREATE EXTENSION and the + extension script sets initial privileges using the GRANT + system. Note that the system will automatically handle recording of the + privileges during the extension script and that extension authors need + only use the GRANT and REVOKE + statements in their script to have the privileges recorded. The + privtype column indicates if the initial privilege was + set by initdb or during a + CREATE EXTENSION command. + + + + Objects which have initial privileges set by initdb will + have entries where privtype is + 'i', while objects which have initial privileges set + by CREATE EXTENSION will have entries where + privtype is 'e'. + + + + <structname>pg_init_privs</structname> Columns + + + + + Column Type + + + Description + + + + + + + + objoid oid + (references any OID column) + + + The OID of the specific object + + + + + + classoid oid + (references pg_class.oid) + + + The OID of the system catalog the object is in + + + + + + objsubid int4 + + + For a table column, this is the column number (the + objoid and classoid refer to the + table itself). For all other object types, this column is + zero. + + + + + + privtype char + + + A code defining the type of initial privilege of this object; see text + + + + + + initprivs aclitem[] + + + The initial access privileges; see + for details + + + + +
+ +
+ + + + <structname>pg_language</structname> + + + pg_language + + + + The catalog pg_language registers + languages in which you can write functions or stored procedures. + See + and for more information about language handlers. + + + + <structname>pg_language</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + lanname name + + + Name of the language + + + + + + lanowner oid + (references pg_authid.oid) + + + Owner of the language + + + + + + lanispl bool + + + This is false for internal languages (such as + SQL) and true for user-defined languages. + Currently, pg_dump still uses this + to determine which languages need to be dumped, but this might be + replaced by a different mechanism in the future. + + + + + + lanpltrusted bool + + + True if this is a trusted language, which means that it is believed + not to grant access to anything outside the normal SQL execution + environment. Only superusers can create functions in untrusted + languages. + + + + + + lanplcallfoid oid + (references pg_proc.oid) + + + For noninternal languages this references the language + handler, which is a special function that is responsible for + executing all functions that are written in the particular + language. Zero for internal languages. + + + + + + laninline oid + (references pg_proc.oid) + + + This references a function that is responsible for executing + inline anonymous code blocks + ( blocks). + Zero if inline blocks are not supported. + + + + + + lanvalidator oid + (references pg_proc.oid) + + + This references a language validator function that is responsible + for checking the syntax and validity of new functions when they + are created. Zero if no validator is provided. + + + + + + lanacl aclitem[] + + + Access privileges; see for details + + + + +
+ +
+ + + + <structname>pg_largeobject</structname> + + + pg_largeobject + + + + The catalog pg_largeobject holds the data making up + large objects. A large object is identified by an OID + assigned when it is created. Each large object is broken into + segments or pages small enough to be conveniently stored as rows + in pg_largeobject. + The amount of data per page is defined to be LOBLKSIZE (which is currently + BLCKSZ/4, or typically 2 kB). + + + + Prior to PostgreSQL 9.0, there was no permission structure + associated with large objects. As a result, + pg_largeobject was publicly readable and could be + used to obtain the OIDs (and contents) of all large objects in the system. + This is no longer the case; use + pg_largeobject_metadata + to obtain a list of large object OIDs. + + + + <structname>pg_largeobject</structname> Columns + + + + + Column Type + + + Description + + + + + + + + loid oid + (references pg_largeobject_metadata.oid) + + + Identifier of the large object that includes this page + + + + + + pageno int4 + + + Page number of this page within its large object + (counting from zero) + + + + + + data bytea + + + Actual data stored in the large object. + This will never be more than LOBLKSIZE bytes and might be less. + + + + +
+ + + Each row of pg_largeobject holds data + for one page of a large object, beginning at + byte offset (pageno * LOBLKSIZE) within the object. The implementation + allows sparse storage: pages might be missing, and might be shorter than + LOBLKSIZE bytes even if they are not the last page of the object. + Missing regions within a large object read as zeroes. + + +
+ + + <structname>pg_largeobject_metadata</structname> + + + pg_largeobject_metadata + + + + The catalog pg_largeobject_metadata + holds metadata associated with large objects. The actual large object + data is stored in + pg_largeobject. + + + + <structname>pg_largeobject_metadata</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + lomowner oid + (references pg_authid.oid) + + + Owner of the large object + + + + + + lomacl aclitem[] + + + Access privileges; see for details + + + + +
+
+ + + + <structname>pg_namespace</structname> + + + pg_namespace + + + + The catalog pg_namespace stores namespaces. + A namespace is the structure underlying SQL schemas: each namespace + can have a separate collection of relations, types, etc. without name + conflicts. + + + + <structname>pg_namespace</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + nspname name + + + Name of the namespace + + + + + + nspowner oid + (references pg_authid.oid) + + + Owner of the namespace + + + + + + nspacl aclitem[] + + + Access privileges; see for details + + + + +
+ +
+ + + + <structname>pg_opclass</structname> + + + pg_opclass + + + + The catalog pg_opclass defines + index access method operator classes. Each operator class defines + semantics for index columns of a particular data type and a particular + index access method. An operator class essentially specifies that a + particular operator family is applicable to a particular indexable column + data type. The set of operators from the family that are actually usable + with the indexed column are whichever ones accept the column's data type + as their left-hand input. + + + + Operator classes are described at length in . + + + + <structname>pg_opclass</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + opcmethod oid + (references pg_am.oid) + + + Index access method operator class is for + + + + + + opcname name + + + Name of this operator class + + + + + + opcnamespace oid + (references pg_namespace.oid) + + + Namespace of this operator class + + + + + + opcowner oid + (references pg_authid.oid) + + + Owner of the operator class + + + + + + opcfamily oid + (references pg_opfamily.oid) + + + Operator family containing the operator class + + + + + + opcintype oid + (references pg_type.oid) + + + Data type that the operator class indexes + + + + + + opcdefault bool + + + True if this operator class is the default for opcintype + + + + + + opckeytype oid + (references pg_type.oid) + + + Type of data stored in index, or zero if same as opcintype + + + + +
+ + + An operator class's opcmethod must match the + opfmethod of its containing operator family. + Also, there must be no more than one pg_opclass + row having opcdefault true for any given combination of + opcmethod and opcintype. + + +
+ + + + <structname>pg_operator</structname> + + + pg_operator + + + + The catalog pg_operator stores information about operators. + See + and for more information. + + + + <structname>pg_operator</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + oprname name + + + Name of the operator + + + + + + oprnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this operator + + + + + + oprowner oid + (references pg_authid.oid) + + + Owner of the operator + + + + + + oprkind char + + + b = infix operator (both), + or l = prefix operator (left) + + + + + + oprcanmerge bool + + + This operator supports merge joins + + + + + + oprcanhash bool + + + This operator supports hash joins + + + + + + oprleft oid + (references pg_type.oid) + + + Type of the left operand (zero for a prefix operator) + + + + + + oprright oid + (references pg_type.oid) + + + Type of the right operand + + + + + + oprresult oid + (references pg_type.oid) + + + Type of the result + (zero for a not-yet-defined shell operator) + + + + + + oprcom oid + (references pg_operator.oid) + + + Commutator of this operator (zero if none) + + + + + + oprnegate oid + (references pg_operator.oid) + + + Negator of this operator (zero if none) + + + + + + oprcode regproc + (references pg_proc.oid) + + + Function that implements this operator + (zero for a not-yet-defined shell operator) + + + + + + oprrest regproc + (references pg_proc.oid) + + + Restriction selectivity estimation function for this operator + (zero if none) + + + + + + oprjoin regproc + (references pg_proc.oid) + + + Join selectivity estimation function for this operator + (zero if none) + + + + +
+ +
+ + + + <structname>pg_opfamily</structname> + + + pg_opfamily + + + + The catalog pg_opfamily defines operator families. + Each operator family is a collection of operators and associated + support routines that implement the semantics specified for a particular + index access method. Furthermore, the operators in a family are all + compatible, in a way that is specified by the access method. + The operator family concept allows cross-data-type operators to be used + with indexes and to be reasoned about using knowledge of access method + semantics. + + + + Operator families are described at length in . + + + + <structname>pg_opfamily</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + opfmethod oid + (references pg_am.oid) + + + Index access method operator family is for + + + + + + opfname name + + + Name of this operator family + + + + + + opfnamespace oid + (references pg_namespace.oid) + + + Namespace of this operator family + + + + + + opfowner oid + (references pg_authid.oid) + + + Owner of the operator family + + + + +
+ + + The majority of the information defining an operator family is not in its + pg_opfamily row, but in the associated rows in + pg_amop, + pg_amproc, + and + pg_opclass. + + +
+ + + + <structname>pg_partitioned_table</structname> + + + pg_partitioned_table + + + + The catalog pg_partitioned_table stores + information about how tables are partitioned. + + + + <structname>pg_partitioned_table</structname> Columns + + + + + Column Type + + + Description + + + + + + + + partrelid oid + (references pg_class.oid) + + + The OID of the pg_class entry for this partitioned table + + + + + + partstrat char + + + Partitioning strategy; h = hash partitioned table, + l = list partitioned table, r = range partitioned table + + + + + + partnatts int2 + + + The number of columns in the partition key + + + + + + partdefid oid + (references pg_class.oid) + + + The OID of the pg_class entry for the default partition + of this partitioned table, or zero if this partitioned table does not + have a default partition + + + + + + partattrs int2vector + (references pg_attribute.attnum) + + + This is an array of partnatts values that + indicate which table columns are part of the partition key. For + example, a value of 1 3 would mean that the first + and the third table columns make up the partition key. A zero in this + array indicates that the corresponding partition key column is an + expression, rather than a simple column reference. + + + + + + partclass oidvector + (references pg_opclass.oid) + + + For each column in the partition key, this contains the OID of the + operator class to use. See + pg_opclass for details. + + + + + + partcollation oidvector + (references pg_collation.oid) + + + For each column in the partition key, this contains the OID of the + collation to use for partitioning, or zero if the column is not + of a collatable data type. + + + + + + partexprs pg_node_tree + + + Expression trees (in nodeToString() + representation) for partition key columns that are not simple column + references. This is a list with one element for each zero + entry in partattrs. Null if all partition key columns + are simple references. + + + + +
+
+ + + + <structname>pg_policy</structname> + + + pg_policy + + + + The catalog pg_policy stores row-level + security policies for tables. A policy includes the kind of + command that it applies to (possibly all commands), the roles that it + applies to, the expression to be added as a security-barrier + qualification to queries that include the table, and the expression + to be added as a WITH CHECK option for queries that attempt to + add new records to the table. + + + + <structname>pg_policy</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + polname name + + + The name of the policy + + + + + + polrelid oid + (references pg_class.oid) + + + The table to which the policy applies + + + + + + polcmd char + + + The command type to which the policy is applied: + r for , + a for , + w for , + d for , + or * for all + + + + + + polpermissive bool + + + Is the policy permissive or restrictive? + + + + + + polroles oid[] + (references pg_authid.oid) + + + The roles to which the policy is applied; + zero means PUBLIC + (and normally appears alone in the array) + + + + + + polqual pg_node_tree + + + The expression tree to be added to the security barrier qualifications for queries that use the table + + + + + + polwithcheck pg_node_tree + + + The expression tree to be added to the WITH CHECK qualifications for queries that attempt to add rows to the table + + + + +
+ + + + Policies stored in pg_policy are applied only when + pg_class.relrowsecurity is set for + their table. + + + +
+ + + <structname>pg_proc</structname> + + + pg_proc + + + + The catalog pg_proc stores information about + functions, procedures, aggregate functions, and window functions + (collectively also known as routines). See , , and + for more information. + + + + If prokind indicates that the entry is for an + aggregate function, there should be a matching row in + pg_aggregate. + + + + <structname>pg_proc</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + proname name + + + Name of the function + + + + + + pronamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this function + + + + + + proowner oid + (references pg_authid.oid) + + + Owner of the function + + + + + + prolang oid + (references pg_language.oid) + + + Implementation language or call interface of this function + + + + + + procost float4 + + + Estimated execution cost (in units of + ); if proretset, + this is cost per row returned + + + + + + prorows float4 + + + Estimated number of result rows (zero if not proretset) + + + + + + provariadic oid + (references pg_type.oid) + + + Data type of the variadic array parameter's elements, + or zero if the function does not have a variadic parameter + + + + + + prosupport regproc + (references pg_proc.oid) + + + Planner support function for this function + (see ), or zero if none + + + + + + prokind char + + + f for a normal function, p + for a procedure, a for an aggregate function, or + w for a window function + + + + + + prosecdef bool + + + Function is a security definer (i.e., a setuid + function) + + + + + + proleakproof bool + + + The function has no side effects. No information about the + arguments is conveyed except via the return value. Any function + that might throw an error depending on the values of its arguments + is not leak-proof. + + + + + + proisstrict bool + + + Function returns null if any call argument is null. In that + case the function won't actually be called at all. Functions + that are not strict must be prepared to handle + null inputs. + + + + + + proretset bool + + + Function returns a set (i.e., multiple values of the specified + data type) + + + + + + provolatile char + + + provolatile tells whether the function's + result depends only on its input arguments, or is affected by outside + factors. + It is i for immutable functions, + which always deliver the same result for the same inputs. + It is s for stable functions, + whose results (for fixed inputs) do not change within a scan. + It is v for volatile functions, + whose results might change at any time. (Use v also + for functions with side-effects, so that calls to them cannot get + optimized away.) + + + + + + proparallel char + + + proparallel tells whether the function + can be safely run in parallel mode. + It is s for functions which are safe to run in + parallel mode without restriction. + It is r for functions which can be run in parallel + mode, but their execution is restricted to the parallel group leader; + parallel worker processes cannot invoke these functions. + It is u for functions which are unsafe in parallel + mode; the presence of such a function forces a serial execution plan. + + + + + + pronargs int2 + + + Number of input arguments + + + + + + pronargdefaults int2 + + + Number of arguments that have defaults + + + + + + prorettype oid + (references pg_type.oid) + + + Data type of the return value + + + + + + proargtypes oidvector + (references pg_type.oid) + + + An array of the data types of the function arguments. This includes + only input arguments (including INOUT and + VARIADIC arguments), and thus represents + the call signature of the function. + + + + + + proallargtypes oid[] + (references pg_type.oid) + + + An array of the data types of the function arguments. This includes + all arguments (including OUT and + INOUT arguments); however, if all the + arguments are IN arguments, this field will be null. + Note that subscripting is 1-based, whereas for historical reasons + proargtypes is subscripted from 0. + + + + + + proargmodes char[] + + + An array of the modes of the function arguments, encoded as + i for IN arguments, + o for OUT arguments, + b for INOUT arguments, + v for VARIADIC arguments, + t for TABLE arguments. + If all the arguments are IN arguments, + this field will be null. + Note that subscripts correspond to positions of + proallargtypes not proargtypes. + + + + + + proargnames text[] + + + An array of the names of the function arguments. + Arguments without a name are set to empty strings in the array. + If none of the arguments have a name, this field will be null. + Note that subscripts correspond to positions of + proallargtypes not proargtypes. + + + + + + proargdefaults pg_node_tree + + + Expression trees (in nodeToString() representation) + for default values. This is a list with + pronargdefaults elements, corresponding to the last + N input arguments (i.e., the last + N proargtypes positions). + If none of the arguments have defaults, this field will be null. + + + + + + protrftypes oid[] + (references pg_type.oid) + + + An array of the argument/result data type(s) for which to apply + transforms (from the function's TRANSFORM + clause). Null if none. + + + + + + prosrc text + + + This tells the function handler how to invoke the function. It + might be the actual source code of the function for interpreted + languages, a link symbol, a file name, or just about anything + else, depending on the implementation language/call convention. + + + + + + probin text + + + Additional information about how to invoke the function. + Again, the interpretation is language-specific. + + + + + + prosqlbody pg_node_tree + + + Pre-parsed SQL function body. This is used for SQL-language + functions when the body is given in SQL-standard notation + rather than as a string literal. It's null in other cases. + + + + + + proconfig text[] + + + Function's local settings for run-time configuration variables + + + + + + proacl aclitem[] + + + Access privileges; see for details + + + + +
+ + + For compiled functions, both built-in and dynamically loaded, + prosrc contains the function's C-language + name (link symbol). + For SQL-language functions, prosrc contains + the function's source text if that is specified as a string literal; + but if the function body is specified in SQL-standard style, + prosrc is unused (typically it's an empty + string) and prosqlbody contains the + pre-parsed definition. + For all other currently-known language types, + prosrc contains the function's source + text. probin is null except for + dynamically-loaded C functions, for which it gives the name of the + shared library file containing the function. + + +
+ + + <structname>pg_publication</structname> + + + pg_publication + + + + The catalog pg_publication contains all + publications created in the database. For more on publications see + . + + + + <structname>pg_publication</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + pubname name + + + Name of the publication + + + + + + pubowner oid + (references pg_authid.oid) + + + Owner of the publication + + + + + + puballtables bool + + + If true, this publication automatically includes all tables + in the database, including any that will be created in the future. + + + + + + pubinsert bool + + + If true, operations are replicated for + tables in the publication. + + + + + + pubupdate bool + + + If true, operations are replicated for + tables in the publication. + + + + + + pubdelete bool + + + If true, operations are replicated for + tables in the publication. + + + + + + pubtruncate bool + + + If true, operations are replicated for + tables in the publication. + + + + + + pubviaroot bool + + + If true, operations on a leaf partition are replicated using the + identity and schema of its topmost partitioned ancestor mentioned in the + publication instead of its own. + + + + +
+
+ + + <structname>pg_publication_rel</structname> + + + pg_publication_rel + + + + The catalog pg_publication_rel contains the + mapping between relations and publications in the database. This is a + many-to-many mapping. See also + for a more user-friendly view of this information. + + + + <structname>pg_publication_rel</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + prpubid oid + (references pg_publication.oid) + + + Reference to publication + + + + + + prrelid oid + (references pg_class.oid) + + + Reference to relation + + + + +
+
+ + + <structname>pg_range</structname> + + + pg_range + + + + The catalog pg_range stores information about + range types. This is in addition to the types' entries in + pg_type. + + + + <structname>pg_range</structname> Columns + + + + + Column Type + + + Description + + + + + + + + rngtypid oid + (references pg_type.oid) + + + OID of the range type + + + + + + rngsubtype oid + (references pg_type.oid) + + + OID of the element type (subtype) of this range type + + + + + + rngmultitypid oid + (references pg_type.oid) + + + OID of the multirange type for this range type + + + + + + rngcollation oid + (references pg_collation.oid) + + + OID of the collation used for range comparisons, or zero if none + + + + + + rngsubopc oid + (references pg_opclass.oid) + + + OID of the subtype's operator class used for range comparisons + + + + + + rngcanonical regproc + (references pg_proc.oid) + + + OID of the function to convert a range value into canonical form, + or zero if none + + + + + + rngsubdiff regproc + (references pg_proc.oid) + + + OID of the function to return the difference between two element + values as double precision, or zero if none + + + + +
+ + + rngsubopc (plus rngcollation, if the + element type is collatable) determines the sort ordering used by the range + type. rngcanonical is used when the element type is + discrete. rngsubdiff is optional but should be supplied to + improve performance of GiST indexes on the range type. + + +
+ + + <structname>pg_replication_origin</structname> + + + pg_replication_origin + + + + The pg_replication_origin catalog contains + all replication origins created. For more on replication origins + see . + + + + Unlike most system catalogs, pg_replication_origin + is shared across all databases of a cluster: there is only one copy + of pg_replication_origin per cluster, not one per + database. + + + + <structname>pg_replication_origin</structname> Columns + + + + + Column Type + + + Description + + + + + + + + roident oid + + + A unique, cluster-wide identifier for the replication + origin. Should never leave the system. + + + + + + roname text + + + The external, user defined, name of a replication + origin. + + + + +
+
+ + + <structname>pg_rewrite</structname> + + + pg_rewrite + + + + The catalog pg_rewrite stores rewrite rules for tables and views. + + + + <structname>pg_rewrite</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + rulename name + + + Rule name + + + + + + ev_class oid + (references pg_class.oid) + + + The table this rule is for + + + + + + ev_type char + + + Event type that the rule is for: 1 = , 2 = + , 3 = , 4 = + + + + + + + ev_enabled char + + + Controls in which modes + the rule fires. + O = rule fires in origin and local modes, + D = rule is disabled, + R = rule fires in replica mode, + A = rule fires always. + + + + + + is_instead bool + + + True if the rule is an INSTEAD rule + + + + + + ev_qual pg_node_tree + + + Expression tree (in the form of a + nodeToString() representation) for the + rule's qualifying condition + + + + + + ev_action pg_node_tree + + + Query tree (in the form of a + nodeToString() representation) for the + rule's action + + + + +
+ + + + pg_class.relhasrules + must be true if a table has any rules in this catalog. + + + +
+ + + <structname>pg_seclabel</structname> + + + pg_seclabel + + + + The catalog pg_seclabel stores security + labels on database objects. Security labels can be manipulated + with the SECURITY LABEL command. For an easier + way to view security labels, see . + + + + See also pg_shseclabel, + which performs a similar function for security labels of database objects + that are shared across a database cluster. + + + + <structname>pg_seclabel</structname> Columns + + + + + Column Type + + + Description + + + + + + + + objoid oid + (references any OID column) + + + The OID of the object this security label pertains to + + + + + + classoid oid + (references pg_class.oid) + + + The OID of the system catalog this object appears in + + + + + + objsubid int4 + + + For a security label on a table column, this is the column number (the + objoid and classoid refer to + the table itself). For all other object types, this column is + zero. + + + + + + provider text + + + The label provider associated with this label. + + + + + + label text + + + The security label applied to this object. + + + + +
+
+ + + <structname>pg_sequence</structname> + + + pg_sequence + + + + The catalog pg_sequence contains information about + sequences. Some of the information about sequences, such as the name and + the schema, is in + pg_class + + + + <structname>pg_sequence</structname> Columns + + + + + Column Type + + + Description + + + + + + + + seqrelid oid + (references pg_class.oid) + + + The OID of the pg_class entry for this sequence + + + + + + seqtypid oid + (references pg_type.oid) + + + Data type of the sequence + + + + + + seqstart int8 + + + Start value of the sequence + + + + + + seqincrement int8 + + + Increment value of the sequence + + + + + + seqmax int8 + + + Maximum value of the sequence + + + + + + seqmin int8 + + + Minimum value of the sequence + + + + + + seqcache int8 + + + Cache size of the sequence + + + + + + seqcycle bool + + + Whether the sequence cycles + + + + +
+
+ + + <structname>pg_shdepend</structname> + + + pg_shdepend + + + + The catalog pg_shdepend records the + dependency relationships between database objects and shared objects, + such as roles. This information allows + PostgreSQL to ensure that those objects are + unreferenced before attempting to delete them. + + + + See also pg_depend, + which performs a similar function for dependencies involving objects + within a single database. + + + + Unlike most system catalogs, pg_shdepend + is shared across all databases of a cluster: there is only one + copy of pg_shdepend per cluster, not + one per database. + + + + <structname>pg_shdepend</structname> Columns + + + + + Column Type + + + Description + + + + + + + + dbid oid + (references pg_database.oid) + + + The OID of the database the dependent object is in, + or zero for a shared object + or a SHARED_DEPENDENCY_PIN entry + + + + + + classid oid + (references pg_class.oid) + + + The OID of the system catalog the dependent object is in, + or zero for a SHARED_DEPENDENCY_PIN entry + + + + + + objid oid + (references any OID column) + + + The OID of the specific dependent object, + or zero for a SHARED_DEPENDENCY_PIN entry + + + + + + objsubid int4 + + + For a table column, this is the column number (the + objid and classid refer to the + table itself). For all other object types, this column is zero. + + + + + + refclassid oid + (references pg_class.oid) + + + The OID of the system catalog the referenced object is in + (must be a shared catalog) + + + + + + refobjid oid + (references any OID column) + + + The OID of the specific referenced object + + + + + + deptype char + + + A code defining the specific semantics of this dependency relationship; see text + + + + +
+ + + In all cases, a pg_shdepend entry indicates that + the referenced object cannot be dropped without also dropping the dependent + object. However, there are several subflavors identified by + deptype: + + + + SHARED_DEPENDENCY_OWNER (o) + + + The referenced object (which must be a role) is the owner of the + dependent object. + + + + + + SHARED_DEPENDENCY_ACL (a) + + + The referenced object (which must be a role) is mentioned in the + ACL (access control list, i.e., privileges list) of the + dependent object. (A SHARED_DEPENDENCY_ACL entry is + not made for the owner of the object, since the owner will have + a SHARED_DEPENDENCY_OWNER entry anyway.) + + + + + + SHARED_DEPENDENCY_POLICY (r) + + + The referenced object (which must be a role) is mentioned as the + target of a dependent policy object. + + + + + + SHARED_DEPENDENCY_PIN (p) + + + There is no dependent object; this type of entry is a signal + that the system itself depends on the referenced object, and so + that object must never be deleted. Entries of this type are + created only by initdb. The columns for the + dependent object contain zeroes. + + + + + + SHARED_DEPENDENCY_TABLESPACE (t) + + + The referenced object (which must be a tablespace) is mentioned as + the tablespace for a relation that doesn't have storage. + + + + + + Other dependency flavors might be needed in future. Note in particular + that the current definition only supports roles and tablespaces as referenced + objects. + + +
+ + + <structname>pg_shdescription</structname> + + + pg_shdescription + + + + The catalog pg_shdescription stores optional + descriptions (comments) for shared database objects. Descriptions can be + manipulated with the COMMENT command and viewed with + psql's \d commands. + + + + See also pg_description, + which performs a similar function for descriptions involving objects + within a single database. + + + + Unlike most system catalogs, pg_shdescription + is shared across all databases of a cluster: there is only one + copy of pg_shdescription per cluster, not + one per database. + + + + <structname>pg_shdescription</structname> Columns + + + + + Column Type + + + Description + + + + + + + + objoid oid + (references any OID column) + + + The OID of the object this description pertains to + + + + + + classoid oid + (references pg_class.oid) + + + The OID of the system catalog this object appears in + + + + + + description text + + + Arbitrary text that serves as the description of this object + + + + +
+ +
+ + + <structname>pg_shseclabel</structname> + + + pg_shseclabel + + + + The catalog pg_shseclabel stores security + labels on shared database objects. Security labels can be manipulated + with the SECURITY LABEL command. For an easier + way to view security labels, see . + + + + See also pg_seclabel, + which performs a similar function for security labels involving objects + within a single database. + + + + Unlike most system catalogs, pg_shseclabel + is shared across all databases of a cluster: there is only one + copy of pg_shseclabel per cluster, not + one per database. + + + + <structname>pg_shseclabel</structname> Columns + + + + + Column Type + + + Description + + + + + + + + objoid oid + (references any OID column) + + + The OID of the object this security label pertains to + + + + + + classoid oid + (references pg_class.oid) + + + The OID of the system catalog this object appears in + + + + + + provider text + + + The label provider associated with this label. + + + + + + label text + + + The security label applied to this object. + + + + +
+
+ + + <structname>pg_statistic</structname> + + + pg_statistic + + + + The catalog pg_statistic stores + statistical data about the contents of the database. Entries are + created by ANALYZE + and subsequently used by the query planner. Note that all the + statistical data is inherently approximate, even assuming that it + is up-to-date. + + + + Normally there is one entry, with stainherit = + false, for each table column that has been analyzed. + If the table has inheritance children, a second entry with + stainherit = true is also created. This row + represents the column's statistics over the inheritance tree, i.e., + statistics for the data you'd see with + SELECT column FROM table*, + whereas the stainherit = false row represents + the results of + SELECT column FROM ONLY table. + + + + pg_statistic also stores statistical data about + the values of index expressions. These are described as if they were + actual data columns; in particular, starelid + references the index. No entry is made for an ordinary non-expression + index column, however, since it would be redundant with the entry + for the underlying table column. Currently, entries for index expressions + always have stainherit = false. + + + + Since different kinds of statistics might be appropriate for different + kinds of data, pg_statistic is designed not + to assume very much about what sort of statistics it stores. Only + extremely general statistics (such as nullness) are given dedicated + columns in pg_statistic. Everything else + is stored in slots, which are groups of associated columns + whose content is identified by a code number in one of the slot's columns. + For more information see + src/include/catalog/pg_statistic.h. + + + + pg_statistic should not be readable by the + public, since even statistical information about a table's contents + might be considered sensitive. (Example: minimum and maximum values + of a salary column might be quite interesting.) + pg_stats + is a publicly readable view on + pg_statistic that only exposes information + about those tables that are readable by the current user. + + + + <structname>pg_statistic</structname> Columns + + + + + Column Type + + + Description + + + + + + + + starelid oid + (references pg_class.oid) + + + The table or index that the described column belongs to + + + + + + staattnum int2 + (references pg_attribute.attnum) + + + The number of the described column + + + + + + stainherit bool + + + If true, the stats include inheritance child columns, not just the + values in the specified relation + + + + + + stanullfrac float4 + + + The fraction of the column's entries that are null + + + + + + stawidth int4 + + + The average stored width, in bytes, of nonnull entries + + + + + + stadistinct float4 + + + The number of distinct nonnull data values in the column. + A value greater than zero is the actual number of distinct values. + A value less than zero is the negative of a multiplier for the number + of rows in the table; for example, a column in which about 80% of the + values are nonnull and each nonnull value appears about twice on + average could be represented by stadistinct = -0.4. + A zero value means the number of distinct values is unknown. + + + + + + stakindN int2 + + + A code number indicating the kind of statistics stored in the + Nth slot of the + pg_statistic row. + + + + + + staopN oid + (references pg_operator.oid) + + + An operator used to derive the statistics stored in the + Nth slot. For example, a + histogram slot would show the < operator + that defines the sort order of the data. + Zero if the statistics kind does not require an operator. + + + + + + stacollN oid + (references pg_collation.oid) + + + The collation used to derive the statistics stored in the + Nth slot. For example, a + histogram slot for a collatable column would show the collation that + defines the sort order of the data. Zero for noncollatable data. + + + + + + stanumbersN float4[] + + + Numerical statistics of the appropriate kind for the + Nth slot, or null if the slot + kind does not involve numerical values + + + + + + stavaluesN anyarray + + + Column data values of the appropriate kind for the + Nth slot, or null if the slot + kind does not store any data values. Each array's element + values are actually of the specific column's data type, or a related + type such as an array's element type, so there is no way to define + these columns' type more specifically than anyarray. + + + + +
+ +
+ + + <structname>pg_statistic_ext</structname> + + + pg_statistic_ext + + + + The catalog pg_statistic_ext + holds definitions of extended planner statistics. + Each row in this catalog corresponds to a statistics object + created with CREATE STATISTICS. + + + + <structname>pg_statistic_ext</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + stxrelid oid + (references pg_class.oid) + + + Table containing the columns described by this object + + + + + + stxname name + + + Name of the statistics object + + + + + + stxnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this statistics object + + + + + + stxowner oid + (references pg_authid.oid) + + + Owner of the statistics object + + + + + + stxstattarget int4 + + + stxstattarget controls the level of detail + of statistics accumulated for this statistics object by + ANALYZE. + A zero value indicates that no statistics should be collected. + A negative value says to use the maximum of the statistics targets of + the referenced columns, if set, or the system default statistics target. + Positive values of stxstattarget + determine the target number of most common values + to collect. + + + + + + stxkeys int2vector + (references pg_attribute.attnum) + + + An array of attribute numbers, indicating which table columns are + covered by this statistics object; + for example a value of 1 3 would + mean that the first and the third table columns are covered + + + + + + stxkind char[] + + + An array containing codes for the enabled statistics kinds; + valid values are: + d for n-distinct statistics, + f for functional dependency statistics, and + m for most common values (MCV) list statistics + e for expression statistics + + + + + + stxexprs pg_node_tree + + + Expression trees (in nodeToString() + representation) for statistics object attributes that are not simple + column references. This is a list with one element per expression. + Null if all statistics object attributes are simple references. + + + + + +
+ + + The pg_statistic_ext entry is filled in + completely during CREATE STATISTICS, but the actual + statistical values are not computed then. + Subsequent ANALYZE commands compute the desired values + and populate an entry in the + pg_statistic_ext_data + catalog. + +
+ + + <structname>pg_statistic_ext_data</structname> + + + pg_statistic_ext_data + + + + The catalog pg_statistic_ext_data + holds data for extended planner statistics defined in + pg_statistic_ext. + Each row in this catalog corresponds to a statistics object + created with CREATE STATISTICS. + + + + Like pg_statistic, + pg_statistic_ext_data should not be + readable by the public, since the contents might be considered sensitive. + (Example: most common combinations of values in columns might be quite + interesting.) + pg_stats_ext + is a publicly readable view + on pg_statistic_ext_data (after joining + with pg_statistic_ext) that only exposes + information about those tables and columns that are readable by the + current user. + + + + <structname>pg_statistic_ext_data</structname> Columns + + + + + Column Type + + + Description + + + + + + + + stxoid oid + (references pg_statistic_ext.oid) + + + Extended statistics object containing the definition for this data + + + + + + stxdndistinct pg_ndistinct + + + N-distinct counts, serialized as pg_ndistinct type + + + + + + stxddependencies pg_dependencies + + + Functional dependency statistics, serialized + as pg_dependencies type + + + + + + stxdmcv pg_mcv_list + + + MCV (most-common values) list statistics, serialized as + pg_mcv_list type + + + + + + stxdexpr pg_statistic[] + + + Per-expression statistics, serialized as an array of + pg_statistic type + + + + +
+ +
+ + + <structname>pg_subscription</structname> + + + pg_subscription + + + + The catalog pg_subscription contains all existing + logical replication subscriptions. For more information about logical + replication see . + + + + Unlike most system catalogs, pg_subscription is + shared across all databases of a cluster: there is only one copy + of pg_subscription per cluster, not one per + database. + + + + Access to the column subconninfo is revoked from + normal users, because it could contain plain-text passwords. + + + + <structname>pg_subscription</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + subdbid oid + (references pg_database.oid) + + + OID of the database that the subscription resides in + + + + + + subname name + + + Name of the subscription + + + + + + subowner oid + (references pg_authid.oid) + + + Owner of the subscription + + + + + + subenabled bool + + + If true, the subscription is enabled and should be replicating + + + + + + subbinary bool + + + If true, the subscription will request that the publisher send data + in binary format + + + + + + substream bool + + + If true, the subscription will allow streaming of in-progress + transactions + + + + + + subconninfo text + + + Connection string to the upstream database + + + + + + subslotname name + + + Name of the replication slot in the upstream database (also used + for the local replication origin name); + null represents NONE + + + + + + subsynccommit text + + + The synchronous_commit + setting for the subscription's workers to use + + + + + + subpublications text[] + + + Array of subscribed publication names. These reference + publications defined in the upstream database. For more on publications + see . + + + + +
+
+ + + <structname>pg_subscription_rel</structname> + + + pg_subscription_rel + + + + The catalog pg_subscription_rel contains the + state for each replicated relation in each subscription. This is a + many-to-many mapping. + + + + This catalog only contains tables known to the subscription after running + either CREATE SUBSCRIPTION or + ALTER SUBSCRIPTION ... REFRESH + PUBLICATION. + + + + <structname>pg_subscription_rel</structname> Columns + + + + + Column Type + + + Description + + + + + + + + srsubid oid + (references pg_subscription.oid) + + + Reference to subscription + + + + + + srrelid oid + (references pg_class.oid) + + + Reference to relation + + + + + + srsubstate char + + + State code: + i = initialize, + d = data is being copied, + f = finished table copy, + s = synchronized, + r = ready (normal replication) + + + + + + srsublsn pg_lsn + + + Remote LSN of the state change used for synchronization coordination + when in s or r states, + otherwise null + + + + +
+
+ + + <structname>pg_tablespace</structname> + + + pg_tablespace + + + + The catalog pg_tablespace stores information + about the available tablespaces. Tables can be placed in particular + tablespaces to aid administration of disk layout. + + + + Unlike most system catalogs, pg_tablespace + is shared across all databases of a cluster: there is only one + copy of pg_tablespace per cluster, not + one per database. + + + + <structname>pg_tablespace</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + spcname name + + + Tablespace name + + + + + + spcowner oid + (references pg_authid.oid) + + + Owner of the tablespace, usually the user who created it + + + + + + spcacl aclitem[] + + + Access privileges; see for details + + + + + + spcoptions text[] + + + Tablespace-level options, as keyword=value strings + + + + +
+
+ + + + <structname>pg_transform</structname> + + + pg_transform + + + + The catalog pg_transform stores information about + transforms, which are a mechanism to adapt data types to procedural + languages. See for more information. + + + + <structname>pg_transform</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + trftype oid + (references pg_type.oid) + + + OID of the data type this transform is for + + + + + + trflang oid + (references pg_language.oid) + + + OID of the language this transform is for + + + + + + trffromsql regproc + (references pg_proc.oid) + + + The OID of the function to use when converting the data type for input + to the procedural language (e.g., function parameters). Zero is stored + if the default behavior should be used. + + + + + + trftosql regproc + (references pg_proc.oid) + + + The OID of the function to use when converting output from the + procedural language (e.g., return values) to the data type. Zero is + stored if the default behavior should be used. + + + + +
+
+ + + + <structname>pg_trigger</structname> + + + pg_trigger + + + + The catalog pg_trigger stores triggers on tables + and views. + See + for more information. + + + + <structname>pg_trigger</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + tgrelid oid + (references pg_class.oid) + + + The table this trigger is on + + + + + + tgparentid oid + (references pg_trigger.oid) + + + Parent trigger that this trigger is cloned from (this happens when + partitions are created or attached to a partitioned table); + zero if not a clone + + + + + + tgname name + + + Trigger name (must be unique among triggers of same table) + + + + + + tgfoid oid + (references pg_proc.oid) + + + The function to be called + + + + + + tgtype int2 + + + Bit mask identifying trigger firing conditions + + + + + + tgenabled char + + + Controls in which modes + the trigger fires. + O = trigger fires in origin and local modes, + D = trigger is disabled, + R = trigger fires in replica mode, + A = trigger fires always. + + + + + + tgisinternal bool + + + True if trigger is internally generated (usually, to enforce + the constraint identified by tgconstraint) + + + + + + tgconstrrelid oid + (references pg_class.oid) + + + The table referenced by a referential integrity constraint + (zero if trigger is not for a referential integrity constraint) + + + + + + tgconstrindid oid + (references pg_class.oid) + + + The index supporting a unique, primary key, referential integrity, + or exclusion constraint + (zero if trigger is not for one of these types of constraint) + + + + + + tgconstraint oid + (references pg_constraint.oid) + + + The pg_constraint entry associated with the trigger + (zero if trigger is not for a constraint) + + + + + + tgdeferrable bool + + + True if constraint trigger is deferrable + + + + + + tginitdeferred bool + + + True if constraint trigger is initially deferred + + + + + + tgnargs int2 + + + Number of argument strings passed to trigger function + + + + + + tgattr int2vector + (references pg_attribute.attnum) + + + Column numbers, if trigger is column-specific; otherwise an + empty array + + + + + + tgargs bytea + + + Argument strings to pass to trigger, each NULL-terminated + + + + + + tgqual pg_node_tree + + + Expression tree (in nodeToString() + representation) for the trigger's WHEN condition, or null + if none + + + + + + tgoldtable name + + + REFERENCING clause name for OLD TABLE, + or null if none + + + + + + tgnewtable name + + + REFERENCING clause name for NEW TABLE, + or null if none + + + + +
+ + + Currently, column-specific triggering is supported only for + UPDATE events, and so tgattr is relevant + only for that event type. tgtype might + contain bits for other event types as well, but those are presumed + to be table-wide regardless of what is in tgattr. + + + + + When tgconstraint is nonzero, + tgconstrrelid, tgconstrindid, + tgdeferrable, and tginitdeferred are + largely redundant with the referenced pg_constraint entry. + However, it is possible for a non-deferrable trigger to be associated + with a deferrable constraint: foreign key constraints can have some + deferrable and some non-deferrable triggers. + + + + + + pg_class.relhastriggers + must be true if a relation has any triggers in this catalog. + + + +
+ + + + <structname>pg_ts_config</structname> + + + pg_ts_config + + + + The pg_ts_config catalog contains entries + representing text search configurations. A configuration specifies + a particular text search parser and a list of dictionaries to use + for each of the parser's output token types. The parser is shown + in the pg_ts_config entry, but the + token-to-dictionary mapping is defined by subsidiary entries in pg_ts_config_map. + + + + PostgreSQL's text search features are + described at length in . + + + + <structname>pg_ts_config</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + cfgname name + + + Text search configuration name + + + + + + cfgnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this configuration + + + + + + cfgowner oid + (references pg_authid.oid) + + + Owner of the configuration + + + + + + cfgparser oid + (references pg_ts_parser.oid) + + + The OID of the text search parser for this configuration + + + + +
+
+ + + + <structname>pg_ts_config_map</structname> + + + pg_ts_config_map + + + + The pg_ts_config_map catalog contains entries + showing which text search dictionaries should be consulted, and in + what order, for each output token type of each text search configuration's + parser. + + + + PostgreSQL's text search features are + described at length in . + + + + <structname>pg_ts_config_map</structname> Columns + + + + + Column Type + + + Description + + + + + + + + mapcfg oid + (references pg_ts_config.oid) + + + The OID of the pg_ts_config entry owning this map entry + + + + + + maptokentype int4 + + + A token type emitted by the configuration's parser + + + + + + mapseqno int4 + + + Order in which to consult this entry (lower + mapseqnos first) + + + + + + mapdict oid + (references pg_ts_dict.oid) + + + The OID of the text search dictionary to consult + + + + +
+
+ + + + <structname>pg_ts_dict</structname> + + + pg_ts_dict + + + + The pg_ts_dict catalog contains entries + defining text search dictionaries. A dictionary depends on a text + search template, which specifies all the implementation functions + needed; the dictionary itself provides values for the user-settable + parameters supported by the template. This division of labor allows + dictionaries to be created by unprivileged users. The parameters + are specified by a text string dictinitoption, + whose format and meaning vary depending on the template. + + + + PostgreSQL's text search features are + described at length in . + + + + <structname>pg_ts_dict</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + dictname name + + + Text search dictionary name + + + + + + dictnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this dictionary + + + + + + dictowner oid + (references pg_authid.oid) + + + Owner of the dictionary + + + + + + dicttemplate oid + (references pg_ts_template.oid) + + + The OID of the text search template for this dictionary + + + + + + dictinitoption text + + + Initialization option string for the template + + + + +
+
+ + + + <structname>pg_ts_parser</structname> + + + pg_ts_parser + + + + The pg_ts_parser catalog contains entries + defining text search parsers. A parser is responsible for splitting + input text into lexemes and assigning a token type to each lexeme. + Since a parser must be implemented by C-language-level functions, + creation of new parsers is restricted to database superusers. + + + + PostgreSQL's text search features are + described at length in . + + + + <structname>pg_ts_parser</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + prsname name + + + Text search parser name + + + + + + prsnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this parser + + + + + + prsstart regproc + (references pg_proc.oid) + + + OID of the parser's startup function + + + + + + prstoken regproc + (references pg_proc.oid) + + + OID of the parser's next-token function + + + + + + prsend regproc + (references pg_proc.oid) + + + OID of the parser's shutdown function + + + + + + prsheadline regproc + (references pg_proc.oid) + + + OID of the parser's headline function (zero if none) + + + + + + prslextype regproc + (references pg_proc.oid) + + + OID of the parser's lextype function + + + + +
+
+ + + + <structname>pg_ts_template</structname> + + + pg_ts_template + + + + The pg_ts_template catalog contains entries + defining text search templates. A template is the implementation + skeleton for a class of text search dictionaries. + Since a template must be implemented by C-language-level functions, + creation of new templates is restricted to database superusers. + + + + PostgreSQL's text search features are + described at length in . + + + + <structname>pg_ts_template</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + tmplname name + + + Text search template name + + + + + + tmplnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this template + + + + + + tmplinit regproc + (references pg_proc.oid) + + + OID of the template's initialization function (zero if none) + + + + + + tmpllexize regproc + (references pg_proc.oid) + + + OID of the template's lexize function + + + + +
+
+ + + + <structname>pg_type</structname> + + + pg_type + + + + The catalog pg_type stores information about data + types. Base types and enum types (scalar types) are created with + CREATE TYPE, and + domains with + CREATE DOMAIN. + A composite type is automatically created for each table in the database, to + represent the row structure of the table. It is also possible to create + composite types with CREATE TYPE AS. + + + + <structname>pg_type</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + typname name + + + Data type name + + + + + + typnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace that contains this type + + + + + + typowner oid + (references pg_authid.oid) + + + Owner of the type + + + + + + typlen int2 + + + For a fixed-size type, typlen is the number + of bytes in the internal representation of the type. But for a + variable-length type, typlen is negative. + -1 indicates a varlena type (one that has a length word), + -2 indicates a null-terminated C string. + + + + + + typbyval bool + + + typbyval determines whether internal + routines pass a value of this type by value or by reference. + typbyval had better be false if + typlen is not 1, 2, or 4 (or 8 on machines + where Datum is 8 bytes). + Variable-length types are always passed by reference. Note that + typbyval can be false even if the + length would allow pass-by-value. + + + + + + typtype char + + + typtype is + b for a base type, + c for a composite type (e.g., a table's row type), + d for a domain, + e for an enum type, + p for a pseudo-type, + r for a range type, or + m for a multirange type. + See also typrelid and + typbasetype. + + + + + + typcategory char + + + typcategory is an arbitrary classification + of data types that is used by the parser to determine which implicit + casts should be preferred. + See . + + + + + + typispreferred bool + + + True if the type is a preferred cast target within its + typcategory + + + + + + typisdefined bool + + + True if the type is defined, false if this is a placeholder + entry for a not-yet-defined type. When + typisdefined is false, nothing + except the type name, namespace, and OID can be relied on. + + + + + + typdelim char + + + Character that separates two values of this type when parsing + array input. Note that the delimiter is associated with the array + element data type, not the array data type. + + + + + + typrelid oid + (references pg_class.oid) + + + If this is a composite type (see + typtype), then this column points to + the pg_class entry that defines the + corresponding table. (For a free-standing composite type, the + pg_class entry doesn't really represent + a table, but it is needed anyway for the type's + pg_attribute entries to link to.) + Zero for non-composite types. + + + + + + typsubscript regproc + (references pg_proc.oid) + + + Subscripting handler function's OID, or zero if this type doesn't + support subscripting. Types that are true array + types have typsubscript + = array_subscript_handler, but other types may + have other handler functions to implement specialized subscripting + behavior. + + + + + + typelem oid + (references pg_type.oid) + + + If typelem is not zero then it + identifies another row in pg_type, + defining the type yielded by subscripting. This should be zero + if typsubscript is zero. However, it can + be zero when typsubscript isn't zero, if the + handler doesn't need typelem to + determine the subscripting result type. + Note that a typelem dependency is + considered to imply physical containment of the element type in + this type; so DDL changes on the element type might be restricted + by the presence of this type. + + + + + + typarray oid + (references pg_type.oid) + + + If typarray is not zero then it + identifies another row in pg_type, which + is the true array type having this type as element + + + + + + typinput regproc + (references pg_proc.oid) + + + Input conversion function (text format) + + + + + + typoutput regproc + (references pg_proc.oid) + + + Output conversion function (text format) + + + + + + typreceive regproc + (references pg_proc.oid) + + + Input conversion function (binary format), or zero if none + + + + + + typsend regproc + (references pg_proc.oid) + + + Output conversion function (binary format), or zero if none + + + + + + typmodin regproc + (references pg_proc.oid) + + + Type modifier input function, or zero if type does not support modifiers + + + + + + typmodout regproc + (references pg_proc.oid) + + + Type modifier output function, or zero to use the standard format + + + + + + typanalyze regproc + (references pg_proc.oid) + + + Custom function, + or zero to use the standard function + + + + + + typalign char + + + typalign is the alignment required + when storing a value of this type. It applies to storage on + disk as well as most representations of the value inside + PostgreSQL. + When multiple values are stored consecutively, such + as in the representation of a complete row on disk, padding is + inserted before a datum of this type so that it begins on the + specified boundary. The alignment reference is the beginning + of the first datum in the sequence. + Possible values are: + + + c = char alignment, i.e., no alignment needed. + + + s = short alignment (2 bytes on most machines). + + + i = int alignment (4 bytes on most machines). + + + d = double alignment (8 bytes on many machines, but by no means all). + + + + + + + + typstorage char + + + typstorage tells for varlena + types (those with typlen = -1) if + the type is prepared for toasting and what the default strategy + for attributes of this type should be. + Possible values are: + + + + p (plain): Values must always be stored plain + (non-varlena types always use this value). + + + + + e (external): Values can be stored in a + secondary TOAST relation (if relation has one, see + pg_class.reltoastrelid). + + + + + m (main): Values can be compressed and stored + inline. + + + + + x (extended): Values can be compressed and/or + moved to a secondary relation. + + + + x is the usual choice for toast-able types. + Note that m values can also be moved out to + secondary storage, but only as a last resort (e + and x values are moved first). + + + + + + typnotnull bool + + + typnotnull represents a not-null + constraint on a type. Used for domains only. + + + + + + typbasetype oid + (references pg_type.oid) + + + If this is a domain (see typtype), then + typbasetype identifies the type that this + one is based on. Zero if this type is not a domain. + + + + + + typtypmod int4 + + + Domains use typtypmod to record the typmod + to be applied to their base type (-1 if base type does not use a + typmod). -1 if this type is not a domain. + + + + + + typndims int4 + + + typndims is the number of array dimensions + for a domain over an array (that is, typbasetype is + an array type). + Zero for types other than domains over array types. + + + + + + typcollation oid + (references pg_collation.oid) + + + typcollation specifies the collation + of the type. If the type does not support collations, this will + be zero. A base type that supports collations will have a nonzero + value here, typically DEFAULT_COLLATION_OID. + A domain over a collatable type can have a collation OID different + from its base type's, if one was specified for the domain. + + + + + + typdefaultbin pg_node_tree + + + If typdefaultbin is not null, it is the + nodeToString() + representation of a default expression for the type. This is + only used for domains. + + + + + + typdefault text + + + typdefault is null if the type has no associated + default value. If typdefaultbin is not null, + typdefault must contain a human-readable version of the + default expression represented by typdefaultbin. If + typdefaultbin is null and typdefault is + not, then typdefault is the external representation of + the type's default value, which can be fed to the type's input + converter to produce a constant. + + + + + + typacl aclitem[] + + + Access privileges; see for details + + + + +
+ + + + For fixed-width types used in system tables, it is critical that the size + and alignment defined in pg_type + agree with the way that the compiler will lay out the column in + a structure representing a table row. + + + + + lists the system-defined values + of typcategory. Any future additions to this list will + also be upper-case ASCII letters. All other ASCII characters are reserved + for user-defined categories. + + + + <structfield>typcategory</structfield> Codes + + + + + Code + Category + + + + + + A + Array types + + + B + Boolean types + + + C + Composite types + + + D + Date/time types + + + E + Enum types + + + G + Geometric types + + + I + Network address types + + + N + Numeric types + + + P + Pseudo-types + + + R + Range types + + + S + String types + + + T + Timespan types + + + U + User-defined types + + + V + Bit-string types + + + X + unknown type + + + +
+ +
+ + + + <structname>pg_user_mapping</structname> + + + pg_user_mapping + + + + The catalog pg_user_mapping stores + the mappings from local user to remote. Access to this catalog is + restricted from normal users, use the view + pg_user_mappings + instead. + + + + <structname>pg_user_mapping</structname> Columns + + + + + Column Type + + + Description + + + + + + + + oid oid + + + Row identifier + + + + + + umuser oid + (references pg_authid.oid) + + + OID of the local role being mapped, or zero if the user mapping is public + + + + + + umserver oid + (references pg_foreign_server.oid) + + + The OID of the foreign server that contains this mapping + + + + + + umoptions text[] + + + User mapping specific options, as keyword=value strings + + + + +
+
+ + + + System Views + + + In addition to the system catalogs, PostgreSQL + provides a number of built-in views. Some system views provide convenient + access to some commonly used queries on the system catalogs. Other views + provide access to internal server state. + + + + The information schema () provides + an alternative set of views which overlap the functionality of the system + views. Since the information schema is SQL-standard whereas the views + described here are PostgreSQL-specific, + it's usually better to use the information schema if it provides all + the information you need. + + + + lists the system views described here. + More detailed documentation of each view follows below. + There are some additional views that provide access to the results of + the statistics collector; they are described in . + + + + Except where noted, all the views described here are read-only. + + + + System Views + + + + + View Name + Purpose + + + + + + pg_available_extensions + available extensions + + + + pg_available_extension_versions + available versions of extensions + + + + pg_backend_memory_contexts + backend memory contexts + + + + pg_config + compile-time configuration parameters + + + + pg_cursors + open cursors + + + + pg_file_settings + summary of configuration file contents + + + + pg_group + groups of database users + + + + pg_hba_file_rules + summary of client authentication configuration file contents + + + + pg_indexes + indexes + + + + pg_locks + locks currently held or awaited + + + + pg_matviews + materialized views + + + + pg_policies + policies + + + + pg_prepared_statements + prepared statements + + + + pg_prepared_xacts + prepared transactions + + + + pg_publication_tables + publications and their associated tables + + + + pg_replication_origin_status + information about replication origins, including replication progress + + + + pg_replication_slots + replication slot information + + + + pg_roles + database roles + + + + pg_rules + rules + + + + pg_seclabels + security labels + + + + pg_sequences + sequences + + + + pg_settings + parameter settings + + + + pg_shadow + database users + + + + pg_shmem_allocations + shared memory allocations + + + + pg_stats + planner statistics + + + + pg_stats_ext + extended planner statistics + + + + pg_stats_ext_exprs + extended planner statistics for expressions + + + + pg_tables + tables + + + + pg_timezone_abbrevs + time zone abbreviations + + + + pg_timezone_names + time zone names + + + + pg_user + database users + + + + pg_user_mappings + user mappings + + + + pg_views + views + + + + +
+
+ + + <structname>pg_available_extensions</structname> + + + pg_available_extensions + + + + The pg_available_extensions view lists the + extensions that are available for installation. + See also the + pg_extension + catalog, which shows the extensions currently installed. + + + + <structname>pg_available_extensions</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name name + + + Extension name + + + + + + default_version text + + + Name of default version, or NULL if none is + specified + + + + + + installed_version text + + + Currently installed version of the extension, + or NULL if not installed + + + + + + comment text + + + Comment string from the extension's control file + + + + +
+ + + The pg_available_extensions view is read only. + +
+ + + <structname>pg_available_extension_versions</structname> + + + pg_available_extension_versions + + + + The pg_available_extension_versions view lists the + specific extension versions that are available for installation. + See also the pg_extension + catalog, which shows the extensions currently installed. + + + + <structname>pg_available_extension_versions</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name name + + + Extension name + + + + + + version text + + + Version name + + + + + + installed bool + + + True if this version of this extension is currently + installed + + + + + + superuser bool + + + True if only superusers are allowed to install this extension + (but see trusted) + + + + + + trusted bool + + + True if the extension can be installed by non-superusers + with appropriate privileges + + + + + + relocatable bool + + + True if extension can be relocated to another schema + + + + + + schema name + + + Name of the schema that the extension must be installed into, + or NULL if partially or fully relocatable + + + + + + requires name[] + + + Names of prerequisite extensions, + or NULL if none + + + + + + comment text + + + Comment string from the extension's control file + + + + +
+ + + The pg_available_extension_versions view is read + only. + +
+ + + <structname>pg_backend_memory_contexts</structname> + + + pg_backend_memory_contexts + + + + The view pg_backend_memory_contexts displays all + the memory contexts of the server process attached to the current session. + + + pg_backend_memory_contexts contains one row + for each memory context. + + + + <structname>pg_backend_memory_contexts</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name text + + + Name of the memory context + + + + + + ident text + + + Identification information of the memory context. This field is truncated at 1024 bytes + + + + + + parent text + + + Name of the parent of this memory context + + + + + + level int4 + + + Distance from TopMemoryContext in context tree + + + + + + total_bytes int8 + + + Total bytes allocated for this memory context + + + + + + total_nblocks int8 + + + Total number of blocks allocated for this memory context + + + + + + free_bytes int8 + + + Free space in bytes + + + + + + free_chunks int8 + + + Total number of free chunks + + + + + + used_bytes int8 + + + Used space in bytes + + + + +
+ + + By default, the pg_backend_memory_contexts view can be + read only by superusers. + +
+ + + <structname>pg_config</structname> + + + pg_config + + + + The view pg_config describes the + compile-time configuration parameters of the currently installed + version of PostgreSQL. It is intended, for example, to + be used by software packages that want to interface to + PostgreSQL to facilitate finding the required header + files and libraries. It provides the same basic information as the + PostgreSQL client + application. + + + + By default, the pg_config view can be read + only by superusers. + + + + <structname>pg_config</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name text + + + The parameter name + + + + + + setting text + + + The parameter value + + + + +
+ +
+ + + <structname>pg_cursors</structname> + + + pg_cursors + + + + The pg_cursors view lists the cursors that + are currently available. Cursors can be defined in several ways: + + + + via the DECLARE + statement in SQL + + + + + + via the Bind message in the frontend/backend protocol, as + described in + + + + + + via the Server Programming Interface (SPI), as described in + + + + + + The pg_cursors view displays cursors + created by any of these means. Cursors only exist for the duration + of the transaction that defines them, unless they have been + declared WITH HOLD. Therefore non-holdable + cursors are only present in the view until the end of their + creating transaction. + + + + Cursors are used internally to implement some of the components + of PostgreSQL, such as procedural languages. + Therefore, the pg_cursors view might include cursors + that have not been explicitly created by the user. + + + + + + <structname>pg_cursors</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name text + + + The name of the cursor + + + + + + statement text + + + The verbatim query string submitted to declare this cursor + + + + + + is_holdable bool + + + true if the cursor is holdable (that is, it + can be accessed after the transaction that declared the cursor + has committed); false otherwise + + + + + + is_binary bool + + + true if the cursor was declared + BINARY; false + otherwise + + + + + + is_scrollable bool + + + true if the cursor is scrollable (that is, it + allows rows to be retrieved in a nonsequential manner); + false otherwise + + + + + + creation_time timestamptz + + + The time at which the cursor was declared + + + + +
+ + + The pg_cursors view is read only. + + +
+ + + <structname>pg_file_settings</structname> + + + pg_file_settings + + + + The view pg_file_settings provides a summary of + the contents of the server's configuration file(s). A row appears in + this view for each name = value entry appearing in the files, + with annotations indicating whether the value could be applied + successfully. Additional row(s) may appear for problems not linked to + a name = value entry, such as syntax errors in the files. + + + + This view is helpful for checking whether planned changes in the + configuration files will work, or for diagnosing a previous failure. + Note that this view reports on the current contents of the + files, not on what was last applied by the server. (The + pg_settings + view is usually sufficient to determine that.) + + + + By default, the pg_file_settings view can be read + only by superusers. + + + + <structname>pg_file_settings</structname> Columns + + + + + Column Type + + + Description + + + + + + + + sourcefile text + + + Full path name of the configuration file + + + + + + sourceline int4 + + + Line number within the configuration file where the entry appears + + + + + + seqno int4 + + + Order in which the entries are processed (1..n) + + + + + + name text + + + Configuration parameter name + + + + + + setting text + + + Value to be assigned to the parameter + + + + + + applied bool + + + True if the value can be applied successfully + + + + + + error text + + + If not null, an error message indicating why this entry could + not be applied + + + + +
+ + + If the configuration file contains syntax errors or invalid parameter + names, the server will not attempt to apply any settings from it, and + therefore all the applied fields will read as false. + In such a case there will be one or more rows with + non-null error fields indicating the + problem(s). Otherwise, individual settings will be applied if possible. + If an individual setting cannot be applied (e.g., invalid value, or the + setting cannot be changed after server start) it will have an appropriate + message in the error field. Another way that + an entry might have applied = false is that it is + overridden by a later entry for the same parameter name; this case is not + considered an error so nothing appears in + the error field. + + + + See for more information about the various + ways to change run-time parameters. + + +
+ + + <structname>pg_group</structname> + + + pg_group + + + + + The view pg_group exists for backwards + compatibility: it emulates a catalog that existed in + PostgreSQL before version 8.1. + It shows the names and members of all roles that are marked as not + rolcanlogin, which is an approximation to the set + of roles that are being used as groups. + + + + <structname>pg_group</structname> Columns + + + + + Column Type + + + Description + + + + + + + + groname name + (references pg_authid.rolname) + + + Name of the group + + + + + + grosysid oid + (references pg_authid.oid) + + + ID of this group + + + + + + grolist oid[] + (references pg_authid.oid) + + + An array containing the IDs of the roles in this group + + + + +
+ +
+ + + <structname>pg_hba_file_rules</structname> + + + pg_hba_file_rules + + + + The view pg_hba_file_rules provides a summary of + the contents of the client authentication configuration file, + pg_hba.conf. + A row appears in this view for each + non-empty, non-comment line in the file, with annotations indicating + whether the rule could be applied successfully. + + + + This view can be helpful for checking whether planned changes in the + authentication configuration file will work, or for diagnosing a previous + failure. Note that this view reports on the current contents + of the file, not on what was last loaded by the server. + + + + By default, the pg_hba_file_rules view can be read + only by superusers. + + + + <structname>pg_hba_file_rules</structname> Columns + + + + + Column Type + + + Description + + + + + + + + line_number int4 + + + Line number of this rule in pg_hba.conf + + + + + + type text + + + Type of connection + + + + + + database text[] + + + List of database name(s) to which this rule applies + + + + + + user_name text[] + + + List of user and group name(s) to which this rule applies + + + + + + address text + + + Host name or IP address, or one + of all, samehost, + or samenet, or null for local connections + + + + + + netmask text + + + IP address mask, or null if not applicable + + + + + + auth_method text + + + Authentication method + + + + + + options text[] + + + Options specified for authentication method, if any + + + + + + error text + + + If not null, an error message indicating why this + line could not be processed + + + + +
+ + + Usually, a row reflecting an incorrect entry will have values for only + the line_number and error fields. + + + + See for more information about + client authentication configuration. + +
+ + + <structname>pg_indexes</structname> + + + pg_indexes + + + + The view pg_indexes provides access to + useful information about each index in the database. + + + + <structname>pg_indexes</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table and index + + + + + + tablename name + (references pg_class.relname) + + + Name of table the index is for + + + + + + indexname name + (references pg_class.relname) + + + Name of index + + + + + + tablespace name + (references pg_tablespace.spcname) + + + Name of tablespace containing index (null if default for database) + + + + + + indexdef text + + + Index definition (a reconstructed + command) + + + + +
+ +
+ + + <structname>pg_locks</structname> + + + pg_locks + + + + The view pg_locks provides access to + information about the locks held by active processes within the + database server. See for more discussion + of locking. + + + + pg_locks contains one row per active lockable + object, requested lock mode, and relevant process. Thus, the same + lockable object might + appear many times, if multiple processes are holding or waiting + for locks on it. However, an object that currently has no locks on it + will not appear at all. + + + + There are several distinct types of lockable objects: + whole relations (e.g., tables), individual pages of relations, + individual tuples of relations, + transaction IDs (both virtual and permanent IDs), + and general database objects (identified by class OID and object OID, + in the same way as in pg_description or + pg_depend). Also, the right to extend a + relation is represented as a separate lockable object, as is the right to + update pg_database.datfrozenxid. + Also, advisory locks can be taken on numbers that have + user-defined meanings. + + + + <structname>pg_locks</structname> Columns + + + + + Column Type + + + Description + + + + + + + + locktype text + + + Type of the lockable object: + relation, + extend, + frozenid, + page, + tuple, + transactionid, + virtualxid, + spectoken, + object, + userlock, or + advisory. + (See also .) + + + + + + database oid + (references pg_database.oid) + + + OID of the database in which the lock target exists, or + zero if the target is a shared object, or + null if the target is a transaction ID + + + + + + relation oid + (references pg_class.oid) + + + OID of the relation targeted by the lock, or null if the target is not + a relation or part of a relation + + + + + + page int4 + + + Page number targeted by the lock within the relation, + or null if the target is not a relation page or tuple + + + + + + tuple int2 + + + Tuple number targeted by the lock within the page, + or null if the target is not a tuple + + + + + + virtualxid text + + + Virtual ID of the transaction targeted by the lock, + or null if the target is not a virtual transaction ID + + + + + + transactionid xid + + + ID of the transaction targeted by the lock, + or null if the target is not a transaction ID + + + + + + classid oid + (references pg_class.oid) + + + OID of the system catalog containing the lock target, or null if the + target is not a general database object + + + + + + objid oid + (references any OID column) + + + OID of the lock target within its system catalog, or null if the + target is not a general database object + + + + + + objsubid int2 + + + Column number targeted by the lock (the + classid and objid refer to the + table itself), + or zero if the target is some other general database object, + or null if the target is not a general database object + + + + + + virtualtransaction text + + + Virtual ID of the transaction that is holding or awaiting this lock + + + + + + pid int4 + + + Process ID of the server process holding or awaiting this + lock, or null if the lock is held by a prepared transaction + + + + + + mode text + + + Name of the lock mode held or desired by this process (see and ) + + + + + + granted bool + + + True if lock is held, false if lock is awaited + + + + + + fastpath bool + + + True if lock was taken via fast path, false if taken via main + lock table + + + + + + waitstart timestamptz + + + Time when the server process started waiting for this lock, + or null if the lock is held. + Note that this can be null for a very short period of time after + the wait started even though granted + is false. + + + + +
+ + + granted is true in a row representing a lock + held by the indicated process. False indicates that this process is + currently waiting to acquire this lock, which implies that at least one + other process is holding or waiting for a conflicting lock mode on the same + lockable object. The waiting process will sleep until the other lock is + released (or a deadlock situation is detected). A single process can be + waiting to acquire at most one lock at a time. + + + + Throughout running a transaction, a server process holds an exclusive lock + on the transaction's virtual transaction ID. If a permanent ID is assigned + to the transaction (which normally happens only if the transaction changes + the state of the database), it also holds an exclusive lock on the + transaction's permanent transaction ID until it ends. When a process finds + it necessary to wait specifically for another transaction to end, it does + so by attempting to acquire share lock on the other transaction's ID + (either virtual or permanent ID depending on the situation). That will + succeed only when the other transaction terminates and releases its locks. + + + + Although tuples are a lockable type of object, + information about row-level locks is stored on disk, not in memory, + and therefore row-level locks normally do not appear in this view. + If a process is waiting for a + row-level lock, it will usually appear in the view as waiting for the + permanent transaction ID of the current holder of that row lock. + + + + Advisory locks can be acquired on keys consisting of either a single + bigint value or two integer values. + A bigint key is displayed with its + high-order half in the classid column, its low-order half + in the objid column, and objsubid equal + to 1. The original bigint value can be reassembled with the + expression (classid::bigint << 32) | + objid::bigint. Integer keys are displayed with the + first key in the + classid column, the second key in the objid + column, and objsubid equal to 2. The actual meaning of + the keys is up to the user. Advisory locks are local to each database, + so the database column is meaningful for an advisory lock. + + + + pg_locks provides a global view of all locks + in the database cluster, not only those relevant to the current database. + Although its relation column can be joined + against pg_class.oid to identify locked + relations, this will only work correctly for relations in the current + database (those for which the database column + is either the current database's OID or zero). + + + + The pid column can be joined to the + pid column of the + + pg_stat_activity + view to get more + information on the session holding or awaiting each lock, + for example + +SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa + ON pl.pid = psa.pid; + + Also, if you are using prepared transactions, the + virtualtransaction column can be joined to the + transaction column of the pg_prepared_xacts + view to get more information on prepared transactions that hold locks. + (A prepared transaction can never be waiting for a lock, + but it continues to hold the locks it acquired while running.) + For example: + +SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx + ON pl.virtualtransaction = '-1/' || ppx.transaction; + + + + + While it is possible to obtain information about which processes block + which other processes by joining pg_locks against + itself, this is very difficult to get right in detail. Such a query would + have to encode knowledge about which lock modes conflict with which + others. Worse, the pg_locks view does not expose + information about which processes are ahead of which others in lock wait + queues, nor information about which processes are parallel workers running + on behalf of which other client sessions. It is better to use + the pg_blocking_pids() function + (see ) to identify which + process(es) a waiting process is blocked behind. + + + + The pg_locks view displays data from both the + regular lock manager and the predicate lock manager, which are + separate systems; in addition, the regular lock manager subdivides its + locks into regular and fast-path locks. + This data is not guaranteed to be entirely consistent. + When the view is queried, + data on fast-path locks (with fastpath = true) + is gathered from each backend one at a time, without freezing the state of + the entire lock manager, so it is possible for locks to be taken or + released while information is gathered. Note, however, that these locks are + known not to conflict with any other lock currently in place. After + all backends have been queried for fast-path locks, the remainder of the + regular lock manager is locked as a unit, and a consistent snapshot of all + remaining locks is collected as an atomic action. After unlocking the + regular lock manager, the predicate lock manager is similarly locked and all + predicate locks are collected as an atomic action. Thus, with the exception + of fast-path locks, each lock manager will deliver a consistent set of + results, but as we do not lock both lock managers simultaneously, it is + possible for locks to be taken or released after we interrogate the regular + lock manager and before we interrogate the predicate lock manager. + + + + Locking the regular and/or predicate lock manager could have some + impact on database performance if this view is very frequently accessed. + The locks are held only for the minimum amount of time necessary to + obtain data from the lock managers, but this does not completely eliminate + the possibility of a performance impact. + + +
+ + + <structname>pg_matviews</structname> + + + pg_matviews + + + + materialized views + + + + The view pg_matviews provides access to + useful information about each materialized view in the database. + + + + <structname>pg_matviews</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing materialized view + + + + + + matviewname name + (references pg_class.relname) + + + Name of materialized view + + + + + + matviewowner name + (references pg_authid.rolname) + + + Name of materialized view's owner + + + + + + tablespace name + (references pg_tablespace.spcname) + + + Name of tablespace containing materialized view (null if default for database) + + + + + + hasindexes bool + + + True if materialized view has (or recently had) any indexes + + + + + + ispopulated bool + + + True if materialized view is currently populated + + + + + + definition text + + + Materialized view definition (a reconstructed query) + + + + +
+ +
+ + + <structname>pg_policies</structname> + + + pg_policies + + + + The view pg_policies provides access to + useful information about each row-level security policy in the database. + + + + <structname>pg_policies</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table policy is on + + + + + + tablename name + (references pg_class.relname) + + + Name of table policy is on + + + + + + policyname name + (references pg_policy.polname) + + + Name of policy + + + + + + permissive text + + + Is the policy permissive or restrictive? + + + + + + roles name[] + + + The roles to which this policy applies + + + + + + cmd text + + + The command type to which the policy is applied + + + + + + qual text + + + The expression added to the security barrier qualifications for + queries that this policy applies to + + + + + + with_check text + + + The expression added to the WITH CHECK qualifications for + queries that attempt to add rows to this table + + + + +
+ +
+ + + <structname>pg_prepared_statements</structname> + + + pg_prepared_statements + + + + The pg_prepared_statements view displays + all the prepared statements that are available in the current + session. See for more information about prepared + statements. + + + + pg_prepared_statements contains one row + for each prepared statement. Rows are added to the view when a new + prepared statement is created and removed when a prepared statement + is released (for example, via the DEALLOCATE command). + + + + <structname>pg_prepared_statements</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name text + + + The identifier of the prepared statement + + + + + + statement text + + + The query string submitted by the client to create this + prepared statement. For prepared statements created via SQL, + this is the PREPARE statement submitted by + the client. For prepared statements created via the + frontend/backend protocol, this is the text of the prepared + statement itself. + + + + + + prepare_time timestamptz + + + The time at which the prepared statement was created + + + + + + parameter_types regtype[] + + + The expected parameter types for the prepared statement in the + form of an array of regtype. The OID corresponding + to an element of this array can be obtained by casting the + regtype value to oid. + + + + + + from_sql bool + + + true if the prepared statement was created + via the PREPARE SQL command; + false if the statement was prepared via the + frontend/backend protocol + + + + + + generic_plans int8 + + + Number of times generic plan was chosen + + + + + + custom_plans int8 + + + Number of times custom plan was chosen + + + + +
+ + + The pg_prepared_statements view is read only. + +
+ + + <structname>pg_prepared_xacts</structname> + + + pg_prepared_xacts + + + + The view pg_prepared_xacts displays + information about transactions that are currently prepared for two-phase + commit (see for details). + + + + pg_prepared_xacts contains one row per prepared + transaction. An entry is removed when the transaction is committed or + rolled back. + + + + <structname>pg_prepared_xacts</structname> Columns + + + + + Column Type + + + Description + + + + + + + + transaction xid + + + Numeric transaction identifier of the prepared transaction + + + + + + gid text + + + Global transaction identifier that was assigned to the transaction + + + + + + prepared timestamptz + + + Time at which the transaction was prepared for commit + + + + + + owner name + (references pg_authid.rolname) + + + Name of the user that executed the transaction + + + + + + database name + (references pg_database.datname) + + + Name of the database in which the transaction was executed + + + + +
+ + + When the pg_prepared_xacts view is accessed, the + internal transaction manager data structures are momentarily locked, and + a copy is made for the view to display. This ensures that the + view produces a consistent set of results, while not blocking + normal operations longer than necessary. Nonetheless + there could be some impact on database performance if this view is + frequently accessed. + + +
+ + + <structname>pg_publication_tables</structname> + + + pg_publication_tables + + + + The view pg_publication_tables provides + information about the mapping between publications and the tables they + contain. Unlike the underlying catalog + pg_publication_rel, + this view expands + publications defined as FOR ALL TABLES, so for such + publications there will be a row for each eligible table. + + + + <structname>pg_publication_tables</structname> Columns + + + + + Column Type + + + Description + + + + + + + + pubname name + (references pg_publication.pubname) + + + Name of publication + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table + + + + + + tablename name + (references pg_class.relname) + + + Name of table + + + + +
+
+ + + <structname>pg_replication_origin_status</structname> + + + pg_replication_origin_status + + + + The pg_replication_origin_status view + contains information about how far replay for a certain origin has + progressed. For more on replication origins + see . + + + + <structname>pg_replication_origin_status</structname> Columns + + + + + Column Type + + + Description + + + + + + + + local_id oid + (references pg_replication_origin.roident) + + + internal node identifier + + + + + + external_id text + (references pg_replication_origin.roname) + + + external node identifier + + + + + + remote_lsn pg_lsn + + + The origin node's LSN up to which data has been replicated. + + + + + + local_lsn pg_lsn + + + This node's LSN at which remote_lsn has + been replicated. Used to flush commit records before persisting + data to disk when using asynchronous commits. + + + + +
+
+ + + <structname>pg_replication_slots</structname> + + + pg_replication_slots + + + + The pg_replication_slots view provides a listing + of all replication slots that currently exist on the database cluster, + along with their current state. + + + + For more on replication slots, + see and . + + + + <structname>pg_replication_slots</structname> Columns + + + + + Column Type + + + Description + + + + + + + + slot_name name + + + A unique, cluster-wide identifier for the replication slot + + + + + + plugin name + + + The base name of the shared object containing the output plugin this logical slot is using, or null for physical slots. + + + + + + slot_type text + + + The slot type: physical or logical + + + + + + datoid oid + (references pg_database.oid) + + + The OID of the database this slot is associated with, or + null. Only logical slots have an associated database. + + + + + + database name + (references pg_database.datname) + + + The name of the database this slot is associated with, or + null. Only logical slots have an associated database. + + + + + + temporary bool + + + True if this is a temporary replication slot. Temporary slots are + not saved to disk and are automatically dropped on error or when + the session has finished. + + + + + + active bool + + + True if this slot is currently actively being used + + + + + + active_pid int4 + + + The process ID of the session using this slot if the slot + is currently actively being used. NULL if + inactive. + + + + + + xmin xid + + + The oldest transaction that this slot needs the database to + retain. VACUUM cannot remove tuples deleted + by any later transaction. + + + + + + catalog_xmin xid + + + The oldest transaction affecting the system catalogs that this + slot needs the database to retain. VACUUM cannot + remove catalog tuples deleted by any later transaction. + + + + + + restart_lsn pg_lsn + + + The address (LSN) of oldest WAL which still + might be required by the consumer of this slot and thus won't be + automatically removed during checkpoints unless this LSN + gets behind more than + from the current LSN. NULL + if the LSN of this slot has never been reserved. + + + + + + confirmed_flush_lsn pg_lsn + + + The address (LSN) up to which the logical + slot's consumer has confirmed receiving data. Data older than this is + not available anymore. NULL for physical slots. + + + + + + wal_status text + + + Availability of WAL files claimed by this slot. + Possible values are: + + + reserved means that the claimed files + are within max_wal_size. + + + extended means + that max_wal_size is exceeded but the files are + still retained, either by the replication slot or + by wal_keep_size. + + + + + unreserved means that the slot no longer + retains the required WAL files and some of them are to be removed at + the next checkpoint. This state can return + to reserved or extended. + + + + + lost means that some required WAL files have + been removed and this slot is no longer usable. + + + + The last two states are seen only when + is + non-negative. If restart_lsn is NULL, this + field is null. + + + + + + safe_wal_size int8 + + + The number of bytes that can be written to WAL such that this slot + is not in danger of getting in state "lost". It is NULL for lost + slots, as well as if max_slot_wal_keep_size + is -1. + + + + + + two_phase bool + + + True if the slot is enabled for decoding prepared transactions. Always + false for physical slots. + + + + +
+
+ + + <structname>pg_roles</structname> + + + pg_roles + + + + The view pg_roles provides access to + information about database roles. This is simply a publicly + readable view of + pg_authid + that blanks out the password field. + + + + <structname>pg_roles</structname> Columns + + + + + Column Type + + + Description + + + + + + + + rolname name + + + Role name + + + + + + rolsuper bool + + + Role has superuser privileges + + + + + + rolinherit bool + + + Role automatically inherits privileges of roles it is a + member of + + + + + + rolcreaterole bool + + + Role can create more roles + + + + + + rolcreatedb bool + + + Role can create databases + + + + + + rolcanlogin bool + + + Role can log in. That is, this role can be given as the initial + session authorization identifier + + + + + + rolreplication bool + + + Role is a replication role. A replication role can initiate replication + connections and create and drop replication slots. + + + + + + rolconnlimit int4 + + + For roles that can log in, this sets maximum number of concurrent + connections this role can make. -1 means no limit. + + + + + + rolpassword text + + + Not the password (always reads as ********) + + + + + + rolvaliduntil timestamptz + + + Password expiry time (only used for password authentication); + null if no expiration + + + + + + rolbypassrls bool + + + Role bypasses every row-level security policy, see + for more information. + + + + + + rolconfig text[] + + + Role-specific defaults for run-time configuration variables + + + + + + oid oid + (references pg_authid.oid) + + + ID of role + + + + +
+ +
+ + + <structname>pg_rules</structname> + + + pg_rules + + + + The view pg_rules provides access to + useful information about query rewrite rules. + + + + <structname>pg_rules</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table + + + + + + tablename name + (references pg_class.relname) + + + Name of table the rule is for + + + + + + rulename name + (references pg_rewrite.rulename) + + + Name of rule + + + + + + definition text + + + Rule definition (a reconstructed creation command) + + + + +
+ + + The pg_rules view excludes the ON SELECT rules + of views and materialized views; those can be seen in + pg_views and pg_matviews. + + +
+ + + <structname>pg_seclabels</structname> + + + pg_seclabels + + + + The view pg_seclabels provides information about + security labels. It as an easier-to-query version of the + pg_seclabel catalog. + + + + <structname>pg_seclabels</structname> Columns + + + + + Column Type + + + Description + + + + + + + + objoid oid + (references any OID column) + + + The OID of the object this security label pertains to + + + + + + classoid oid + (references pg_class.oid) + + + The OID of the system catalog this object appears in + + + + + + objsubid int4 + + + For a security label on a table column, this is the column number (the + objoid and classoid refer to + the table itself). For all other object types, this column is + zero. + + + + + + objtype text + + + The type of object to which this label applies, as text. + + + + + + objnamespace oid + (references pg_namespace.oid) + + + The OID of the namespace for this object, if applicable; + otherwise NULL. + + + + + + objname text + + + The name of the object to which this label applies, as text. + + + + + + provider text + (references pg_seclabel.provider) + + + The label provider associated with this label. + + + + + + label text + (references pg_seclabel.label) + + + The security label applied to this object. + + + + +
+
+ + + <structname>pg_sequences</structname> + + + pg_sequences + + + + The view pg_sequences provides access to + useful information about each sequence in the database. + + + + <structname>pg_sequences</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing sequence + + + + + + sequencename name + (references pg_class.relname) + + + Name of sequence + + + + + + sequenceowner name + (references pg_authid.rolname) + + + Name of sequence's owner + + + + + + data_type regtype + (references pg_type.oid) + + + Data type of the sequence + + + + + + start_value int8 + + + Start value of the sequence + + + + + + min_value int8 + + + Minimum value of the sequence + + + + + + max_value int8 + + + Maximum value of the sequence + + + + + + increment_by int8 + + + Increment value of the sequence + + + + + + cycle bool + + + Whether the sequence cycles + + + + + + cache_size int8 + + + Cache size of the sequence + + + + + + last_value int8 + + + The last sequence value written to disk. If caching is used, + this value can be greater than the last value handed out from the + sequence. Null if the sequence has not been read from yet. Also, if + the current user does not have USAGE + or SELECT privilege on the sequence, the value is + null. + + + + +
+
+ + + <structname>pg_settings</structname> + + + pg_settings + + + + The view pg_settings provides access to + run-time parameters of the server. It is essentially an alternative + interface to the SHOW + and SET commands. + It also provides access to some facts about each parameter that are + not directly available from SHOW, such as minimum and + maximum values. + + + + <structname>pg_settings</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name text + + + Run-time configuration parameter name + + + + + + setting text + + + Current value of the parameter + + + + + + unit text + + + Implicit unit of the parameter + + + + + + category text + + + Logical group of the parameter + + + + + + short_desc text + + + A brief description of the parameter + + + + + + extra_desc text + + + Additional, more detailed, description of the parameter + + + + + + context text + + + Context required to set the parameter's value (see below) + + + + + + vartype text + + + Parameter type (bool, enum, + integer, real, or string) + + + + + + source text + + + Source of the current parameter value + + + + + + min_val text + + + Minimum allowed value of the parameter (null for non-numeric + values) + + + + + + max_val text + + + Maximum allowed value of the parameter (null for non-numeric + values) + + + + + + enumvals text[] + + + Allowed values of an enum parameter (null for non-enum + values) + + + + + + boot_val text + + + Parameter value assumed at server startup if the parameter is + not otherwise set + + + + + + reset_val text + + + Value that RESET would reset the parameter to + in the current session + + + + + + sourcefile text + + + Configuration file the current value was set in (null for + values set from sources other than configuration files, or when + examined by a user who is neither a superuser or a member of + pg_read_all_settings); helpful when using + include directives in configuration files + + + + + + sourceline int4 + + + Line number within the configuration file the current value was + set at (null for values set from sources other than configuration files, + or when examined by a user who is neither a superuser or a member of + pg_read_all_settings). + + + + + + pending_restart bool + + + true if the value has been changed in the + configuration file but needs a restart; or false + otherwise. + + + + +
+ + + There are several possible values of context. + In order of decreasing difficulty of changing the setting, they are: + + + + + + internal + + + These settings cannot be changed directly; they reflect internally + determined values. Some of them may be adjustable by rebuilding the + server with different configuration options, or by changing options + supplied to initdb. + + + + + + postmaster + + + These settings can only be applied when the server starts, so any change + requires restarting the server. Values for these settings are typically + stored in the postgresql.conf file, or passed on + the command line when starting the server. Of course, settings with any + of the lower context types can also be + set at server start time. + + + + + + sighup + + + Changes to these settings can be made in + postgresql.conf without restarting the server. + Send a SIGHUP signal to the postmaster to + cause it to re-read postgresql.conf and apply + the changes. The postmaster will also forward the + SIGHUP signal to its child processes so that + they all pick up the new value. + + + + + + superuser-backend + + + Changes to these settings can be made in + postgresql.conf without restarting the server. + They can also be set for a particular session in the connection request + packet (for example, via libpq's PGOPTIONS + environment variable), but only if the connecting user is a superuser. + However, these settings never change in a session after it is started. + If you change them in postgresql.conf, send a + SIGHUP signal to the postmaster to cause it to + re-read postgresql.conf. The new values will only + affect subsequently-launched sessions. + + + + + + backend + + + Changes to these settings can be made in + postgresql.conf without restarting the server. + They can also be set for a particular session in the connection request + packet (for example, via libpq's PGOPTIONS + environment variable); any user can make such a change for their session. + However, these settings never change in a session after it is started. + If you change them in postgresql.conf, send a + SIGHUP signal to the postmaster to cause it to + re-read postgresql.conf. The new values will only + affect subsequently-launched sessions. + + + + + + superuser + + + These settings can be set from postgresql.conf, + or within a session via the SET command; but only superusers + can change them via SET. Changes in + postgresql.conf will affect existing sessions + only if no session-local value has been established with SET. + + + + + + user + + + These settings can be set from postgresql.conf, + or within a session via the SET command. Any user is + allowed to change their session-local value. Changes in + postgresql.conf will affect existing sessions + only if no session-local value has been established with SET. + + + + + + + See for more information about the various + ways to change these parameters. + + + + This view does not display customized options + until the extension module that defines them has been loaded. + + + + This view cannot be inserted into or deleted from, but it can be updated. An + UPDATE applied to a row of pg_settings + is equivalent to executing the SET command on that named + parameter. The change only affects the value used by the current + session. If an UPDATE is issued within a transaction + that is later aborted, the effects of the UPDATE command + disappear when the transaction is rolled back. Once the surrounding + transaction is committed, the effects will persist until the end of the + session, unless overridden by another UPDATE or + SET. + + +
+ + + <structname>pg_shadow</structname> + + + pg_shadow + + + + The view pg_shadow exists for backwards + compatibility: it emulates a catalog that existed in + PostgreSQL before version 8.1. + It shows properties of all roles that are marked as + rolcanlogin in + pg_authid. + + + + The name stems from the fact that this table + should not be readable by the public since it contains passwords. + pg_user + is a publicly readable view on + pg_shadow that blanks out the password field. + + + + <structname>pg_shadow</structname> Columns + + + + + Column Type + + + Description + + + + + + + + usename name + (references pg_authid.rolname) + + + User name + + + + + + usesysid oid + (references pg_authid.oid) + + + ID of this user + + + + + + usecreatedb bool + + + User can create databases + + + + + + usesuper bool + + + User is a superuser + + + + + + userepl bool + + + User can initiate streaming replication and put the system in and + out of backup mode. + + + + + + usebypassrls bool + + + User bypasses every row-level security policy, see + for more information. + + + + + + passwd text + + + Password (possibly encrypted); null if none. See + pg_authid + for details of how encrypted passwords are stored. + + + + + + valuntil timestamptz + + + Password expiry time (only used for password authentication) + + + + + + useconfig text[] + + + Session defaults for run-time configuration variables + + + + +
+ +
+ + + <structname>pg_shmem_allocations</structname> + + + pg_shmem_allocations + + + + The pg_shmem_allocations view shows allocations + made from the server's main shared memory segment. This includes both + memory allocated by postgres itself and memory + allocated by extensions using the mechanisms detailed in + . + + + + Note that this view does not include memory allocated using the dynamic + shared memory infrastructure. + + + + <structname>pg_shmem_allocations</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name text + + + The name of the shared memory allocation. NULL for unused memory + and <anonymous> for anonymous + allocations. + + + + + + off int8 + + + The offset at which the allocation starts. NULL for anonymous + allocations, since details related to them are not known. + + + + + + size int8 + + + Size of the allocation + + + + + + allocated_size int8 + + + Size of the allocation including padding. For anonymous + allocations, no information about padding is available, so the + size and allocated_size columns + will always be equal. Padding is not meaningful for free memory, so + the columns will be equal in that case also. + + + + +
+ + + Anonymous allocations are allocations that have been made + with ShmemAlloc() directly, rather than via + ShmemInitStruct() or + ShmemInitHash(). + + + + By default, the pg_shmem_allocations view can be + read only by superusers. + +
+ + + <structname>pg_stats</structname> + + + pg_stats + + + + The view pg_stats provides access to + the information stored in the pg_statistic + catalog. This view allows access only to rows of + pg_statistic that correspond to tables the + user has permission to read, and therefore it is safe to allow public + read access to this view. + + + + pg_stats is also designed to present the + information in a more readable format than the underlying catalog + — at the cost that its schema must be extended whenever new slot types + are defined for pg_statistic. + + + + <structname>pg_stats</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table + + + + + + tablename name + (references pg_class.relname) + + + Name of table + + + + + + attname name + (references pg_attribute.attname) + + + Name of column described by this row + + + + + + inherited bool + + + If true, this row includes inheritance child columns, not just the + values in the specified table + + + + + + null_frac float4 + + + Fraction of column entries that are null + + + + + + avg_width int4 + + + Average width in bytes of column's entries + + + + + + n_distinct float4 + + + If greater than zero, the estimated number of distinct values in the + column. If less than zero, the negative of the number of distinct + values divided by the number of rows. (The negated form is used when + ANALYZE believes that the number of distinct values is + likely to increase as the table grows; the positive form is used when + the column seems to have a fixed number of possible values.) For + example, -1 indicates a unique column in which the number of distinct + values is the same as the number of rows. + + + + + + most_common_vals anyarray + + + A list of the most common values in the column. (Null if + no values seem to be more common than any others.) + + + + + + most_common_freqs float4[] + + + A list of the frequencies of the most common values, + i.e., number of occurrences of each divided by total number of rows. + (Null when most_common_vals is.) + + + + + + histogram_bounds anyarray + + + A list of values that divide the column's values into groups of + approximately equal population. The values in + most_common_vals, if present, are omitted from this + histogram calculation. (This column is null if the column data type + does not have a < operator or if the + most_common_vals list accounts for the entire + population.) + + + + + + correlation float4 + + + Statistical correlation between physical row ordering and + logical ordering of the column values. This ranges from -1 to +1. + When the value is near -1 or +1, an index scan on the column will + be estimated to be cheaper than when it is near zero, due to reduction + of random access to the disk. (This column is null if the column data + type does not have a < operator.) + + + + + + most_common_elems anyarray + + + A list of non-null element values most often appearing within values of + the column. (Null for scalar types.) + + + + + + most_common_elem_freqs float4[] + + + A list of the frequencies of the most common element values, i.e., the + fraction of rows containing at least one instance of the given value. + Two or three additional values follow the per-element frequencies; + these are the minimum and maximum of the preceding per-element + frequencies, and optionally the frequency of null elements. + (Null when most_common_elems is.) + + + + + + elem_count_histogram float4[] + + + A histogram of the counts of distinct non-null element values within the + values of the column, followed by the average number of distinct + non-null elements. (Null for scalar types.) + + + + +
+ + + The maximum number of entries in the array fields can be controlled on a + column-by-column basis using the ALTER + TABLE SET STATISTICS + command, or globally by setting the + run-time parameter. + + +
+ + + <structname>pg_stats_ext</structname> + + + pg_stats_ext + + + + The view pg_stats_ext provides access to + information about each extended statistics object in the database, + combining information stored in the pg_statistic_ext + and pg_statistic_ext_data + catalogs. This view allows access only to rows of + pg_statistic_ext and pg_statistic_ext_data + that correspond to tables the user has permission to read, and therefore + it is safe to allow public read access to this view. + + + + pg_stats_ext is also designed to present the + information in a more readable format than the underlying catalogs + — at the cost that its schema must be extended whenever new types + of extended statistics are added to pg_statistic_ext. + + + + <structname>pg_stats_ext</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table + + + + + + tablename name + (references pg_class.relname) + + + Name of table + + + + + + statistics_schemaname name + (references pg_namespace.nspname) + + + Name of schema containing extended statistics object + + + + + + statistics_name name + (references pg_statistic_ext.stxname) + + + Name of extended statistics object + + + + + + statistics_owner name + (references pg_authid.rolname) + + + Owner of the extended statistics object + + + + + + attnames name[] + (references pg_attribute.attname) + + + Names of the columns included in the extended statistics object + + + + + + exprs text[] + + + Expressions included in the extended statistics object + + + + + + kinds char[] + + + Types of extended statistics object enabled for this record + + + + + + n_distinct pg_ndistinct + + + N-distinct counts for combinations of column values. If greater + than zero, the estimated number of distinct values in the combination. + If less than zero, the negative of the number of distinct values divided + by the number of rows. + (The negated form is used when ANALYZE believes that + the number of distinct values is likely to increase as the table grows; + the positive form is used when the column seems to have a fixed number + of possible values.) For example, -1 indicates a unique combination of + columns in which the number of distinct combinations is the same as the + number of rows. + + + + + + dependencies pg_dependencies + + + Functional dependency statistics + + + + + + most_common_vals text[] + + + A list of the most common combinations of values in the columns. + (Null if no combinations seem to be more common than any others.) + + + + + + most_common_val_nulls bool[] + + + A list of NULL flags for the most common combinations of values. + (Null when most_common_vals is.) + + + + + + most_common_freqs float8[] + + + A list of the frequencies of the most common combinations, + i.e., number of occurrences of each divided by total number of rows. + (Null when most_common_vals is.) + + + + + + most_common_base_freqs float8[] + + + A list of the base frequencies of the most common combinations, + i.e., product of per-value frequencies. + (Null when most_common_vals is.) + + + + +
+ + + The maximum number of entries in the array fields can be controlled on a + column-by-column basis using the ALTER + TABLE SET STATISTICS command, or globally by setting the + run-time parameter. + + +
+ + + <structname>pg_stats_ext_exprs</structname> + + + pg_stats_ext_exprs + + + + The view pg_stats_ext_exprs provides access to + information about all expressions included in extended statistics objects, + combining information stored in the pg_statistic_ext + and pg_statistic_ext_data + catalogs. This view allows access only to rows of + pg_statistic_ext and pg_statistic_ext_data + that correspond to tables the user has permission to read, and therefore + it is safe to allow public read access to this view. + + + + pg_stats_ext_exprs is also designed to present + the information in a more readable format than the underlying catalogs + — at the cost that its schema must be extended whenever the structure + of statistics in pg_statistic changes. + + + + <structname>pg_stats_ext_exprs</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table + + + + + + tablename name + (references pg_class.relname) + + + Name of table the statistics object is defined on + + + + + + statistics_schemaname name + (references pg_namespace.nspname) + + + Name of schema containing extended statistics object + + + + + + statistics_name name + (references pg_statistic_ext.stxname) + + + Name of extended statistics object + + + + + + statistics_owner name + (references pg_authid.rolname) + + + Owner of the extended statistics object + + + + + + expr text + + + Expression included in the extended statistics object + + + + + + null_frac float4 + + + Fraction of expression entries that are null + + + + + + avg_width int4 + + + Average width in bytes of expression's entries + + + + + + n_distinct float4 + + + If greater than zero, the estimated number of distinct values in the + expression. If less than zero, the negative of the number of distinct + values divided by the number of rows. (The negated form is used when + ANALYZE believes that the number of distinct values is + likely to increase as the table grows; the positive form is used when + the expression seems to have a fixed number of possible values.) For + example, -1 indicates a unique expression in which the number of distinct + values is the same as the number of rows. + + + + + + most_common_vals anyarray + + + A list of the most common values in the expression. (Null if + no values seem to be more common than any others.) + + + + + + most_common_freqs float4[] + + + A list of the frequencies of the most common values, + i.e., number of occurrences of each divided by total number of rows. + (Null when most_common_vals is.) + + + + + + histogram_bounds anyarray + + + A list of values that divide the expression's values into groups of + approximately equal population. The values in + most_common_vals, if present, are omitted from this + histogram calculation. (This expression is null if the expression data type + does not have a < operator or if the + most_common_vals list accounts for the entire + population.) + + + + + + correlation float4 + + + Statistical correlation between physical row ordering and + logical ordering of the expression values. This ranges from -1 to +1. + When the value is near -1 or +1, an index scan on the expression will + be estimated to be cheaper than when it is near zero, due to reduction + of random access to the disk. (This expression is null if the expression's + data type does not have a < operator.) + + + + + + most_common_elems anyarray + + + A list of non-null element values most often appearing within values of + the expression. (Null for scalar types.) + + + + + + most_common_elem_freqs float4[] + + + A list of the frequencies of the most common element values, i.e., the + fraction of rows containing at least one instance of the given value. + Two or three additional values follow the per-element frequencies; + these are the minimum and maximum of the preceding per-element + frequencies, and optionally the frequency of null elements. + (Null when most_common_elems is.) + + + + + + elem_count_histogram float4[] + + + A histogram of the counts of distinct non-null element values within the + values of the expression, followed by the average number of distinct + non-null elements. (Null for scalar types.) + + + + +
+ + + The maximum number of entries in the array fields can be controlled on a + column-by-column basis using the ALTER + TABLE SET STATISTICS command, or globally by setting the + run-time parameter. + + +
+ + + <structname>pg_tables</structname> + + + pg_tables + + + + The view pg_tables provides access to + useful information about each table in the database. + + + + <structname>pg_tables</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing table + + + + + + tablename name + (references pg_class.relname) + + + Name of table + + + + + + tableowner name + (references pg_authid.rolname) + + + Name of table's owner + + + + + + tablespace name + (references pg_tablespace.spcname) + + + Name of tablespace containing table (null if default for database) + + + + + + hasindexes bool + (references pg_class.relhasindex) + + + True if table has (or recently had) any indexes + + + + + + hasrules bool + (references pg_class.relhasrules) + + + True if table has (or once had) rules + + + + + + hastriggers bool + (references pg_class.relhastriggers) + + + True if table has (or once had) triggers + + + + + + rowsecurity bool + (references pg_class.relrowsecurity) + + + True if row security is enabled on the table + + + + +
+ +
+ + + <structname>pg_timezone_abbrevs</structname> + + + pg_timezone_abbrevs + + + + The view pg_timezone_abbrevs provides a list + of time zone abbreviations that are currently recognized by the datetime + input routines. The contents of this view change when the + run-time parameter is modified. + + + + <structname>pg_timezone_abbrevs</structname> Columns + + + + + Column Type + + + Description + + + + + + + + abbrev text + + + Time zone abbreviation + + + + + + utc_offset interval + + + Offset from UTC (positive means east of Greenwich) + + + + + + is_dst bool + + + True if this is a daylight-savings abbreviation + + + + +
+ + + While most timezone abbreviations represent fixed offsets from UTC, + there are some that have historically varied in value + (see for more information). + In such cases this view presents their current meaning. + + +
+ + + <structname>pg_timezone_names</structname> + + + pg_timezone_names + + + + The view pg_timezone_names provides a list + of time zone names that are recognized by SET TIMEZONE, + along with their associated abbreviations, UTC offsets, + and daylight-savings status. (Technically, + PostgreSQL does not use UTC because leap + seconds are not handled.) + Unlike the abbreviations shown in pg_timezone_abbrevs, many of these names imply a set of daylight-savings transition + date rules. Therefore, the associated information changes across local DST + boundaries. The displayed information is computed based on the current + value of CURRENT_TIMESTAMP. + + + + <structname>pg_timezone_names</structname> Columns + + + + + Column Type + + + Description + + + + + + + + name text + + + Time zone name + + + + + + abbrev text + + + Time zone abbreviation + + + + + + utc_offset interval + + + Offset from UTC (positive means east of Greenwich) + + + + + + is_dst bool + + + True if currently observing daylight savings + + + + +
+ +
+ + + <structname>pg_user</structname> + + + pg_user + + + + The view pg_user provides access to + information about database users. This is simply a publicly + readable view of + pg_shadow + that blanks out the password field. + + + + <structname>pg_user</structname> Columns + + + + + Column Type + + + Description + + + + + + + + usename name + + + User name + + + + + + usesysid oid + + + ID of this user + + + + + + usecreatedb bool + + + User can create databases + + + + + + usesuper bool + + + User is a superuser + + + + + + userepl bool + + + User can initiate streaming replication and put the system in and + out of backup mode. + + + + + + usebypassrls bool + + + User bypasses every row-level security policy, see + for more information. + + + + + + passwd text + + + Not the password (always reads as ********) + + + + + + valuntil timestamptz + + + Password expiry time (only used for password authentication) + + + + + + useconfig text[] + + + Session defaults for run-time configuration variables + + + + +
+ +
+ + + <structname>pg_user_mappings</structname> + + + pg_user_mappings + + + + The view pg_user_mappings provides access + to information about user mappings. This is essentially a publicly + readable view of + pg_user_mapping + that leaves out the options field if the user has no rights to use + it. + + + + <structname>pg_user_mappings</structname> Columns + + + + + Column Type + + + Description + + + + + + + + umid oid + (references pg_user_mapping.oid) + + + OID of the user mapping + + + + + + srvid oid + (references pg_foreign_server.oid) + + + The OID of the foreign server that contains this mapping + + + + + + srvname name + (references pg_foreign_server.srvname) + + + Name of the foreign server + + + + + + umuser oid + (references pg_authid.oid) + + + OID of the local role being mapped, or zero if the user mapping is public + + + + + + usename name + + + Name of the local user to be mapped + + + + + + umoptions text[] + + + User mapping specific options, as keyword=value strings + + + + +
+ + + To protect password information stored as a user mapping option, + the umoptions column will read as null + unless one of the following applies: + + + + current user is the user being mapped, and owns the server or + holds USAGE privilege on it + + + + + current user is the server owner and mapping is for PUBLIC + + + + + current user is a superuser + + + + + +
+ + + + <structname>pg_views</structname> + + + pg_views + + + + The view pg_views provides access to + useful information about each view in the database. + + + + <structname>pg_views</structname> Columns + + + + + Column Type + + + Description + + + + + + + + schemaname name + (references pg_namespace.nspname) + + + Name of schema containing view + + + + + + viewname name + (references pg_class.relname) + + + Name of view + + + + + + viewowner name + (references pg_authid.rolname) + + + Name of view's owner + + + + + + definition text + + + View definition (a reconstructed query) + + + + +
+ +
+ +
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml new file mode 100644 index 000000000000..98df74d0e101 --- /dev/null +++ b/doc/src/sgml/charset.sgml @@ -0,0 +1,2642 @@ + + + + Localization + + + This chapter describes the available localization features from the + point of view of the administrator. + PostgreSQL supports two localization + facilities: + + + + + Using the locale features of the operating system to provide + locale-specific collation order, number formatting, translated + messages, and other aspects. + This is covered in and + . + + + + + + Providing a number of different character sets to support storing text + in all kinds of languages, and providing character set translation + between client and server. + This is covered in . + + + + + + + + Locale Support + + locale + + + Locale support refers to an application respecting + cultural preferences regarding alphabets, sorting, number + formatting, etc. PostgreSQL uses the standard ISO + C and POSIX locale facilities provided by the server operating + system. For additional information refer to the documentation of your + system. + + + + Overview + + + Locale support is automatically initialized when a database + cluster is created using initdb. + initdb will initialize the database cluster + with the locale setting of its execution environment by default, + so if your system is already set to use the locale that you want + in your database cluster then there is nothing else you need to + do. If you want to use a different locale (or you are not sure + which locale your system is set to), you can instruct + initdb exactly which locale to use by + specifying the option. For example: + +initdb --locale=sv_SE + + + + + This example for Unix systems sets the locale to Swedish + (sv) as spoken + in Sweden (SE). Other possibilities might include + en_US (U.S. English) and fr_CA (French + Canadian). If more than one character set can be used for a + locale then the specifications can take the form + language_territory.codeset. For example, + fr_BE.UTF-8 represents the French language (fr) as + spoken in Belgium (BE), with a UTF-8 character set + encoding. + + + + What locales are available on your + system under what names depends on what was provided by the operating + system vendor and what was installed. On most Unix systems, the command + locale -a will provide a list of available locales. + Windows uses more verbose locale names, such as German_Germany + or Swedish_Sweden.1252, but the principles are the same. + + + + Occasionally it is useful to mix rules from several locales, e.g., + use English collation rules but Spanish messages. To support that, a + set of locale subcategories exist that control only certain + aspects of the localization rules: + + + + + + + + LC_COLLATE + String sort order + + + LC_CTYPE + Character classification (What is a letter? Its upper-case equivalent?) + + + LC_MESSAGES + Language of messages + + + LC_MONETARY + Formatting of currency amounts + + + LC_NUMERIC + Formatting of numbers + + + LC_TIME + Formatting of dates and times + + + + + + The category names translate into names of + initdb options to override the locale choice + for a specific category. For instance, to set the locale to + French Canadian, but use U.S. rules for formatting currency, use + initdb --locale=fr_CA --lc-monetary=en_US. + + + + If you want the system to behave as if it had no locale support, + use the special locale name C, or equivalently + POSIX. + + + + Some locale categories must have their values + fixed when the database is created. You can use different settings + for different databases, but once a database is created, you cannot + change them for that database anymore. LC_COLLATE + and LC_CTYPE are these categories. They affect + the sort order of indexes, so they must be kept fixed, or indexes on + text columns would become corrupt. + (But you can alleviate this restriction using collations, as discussed + in .) + The default values for these + categories are determined when initdb is run, and + those values are used when new databases are created, unless + specified otherwise in the CREATE DATABASE command. + + + + The other locale categories can be changed whenever desired + by setting the server configuration parameters + that have the same name as the locale categories (see for details). The values + that are chosen by initdb are actually only written + into the configuration file postgresql.conf to + serve as defaults when the server is started. If you remove these + assignments from postgresql.conf then the + server will inherit the settings from its execution environment. + + + + Note that the locale behavior of the server is determined by the + environment variables seen by the server, not by the environment + of any client. Therefore, be careful to configure the correct locale settings + before starting the server. A consequence of this is that if + client and server are set up in different locales, messages might + appear in different languages depending on where they originated. + + + + + When we speak of inheriting the locale from the execution + environment, this means the following on most operating systems: + For a given locale category, say the collation, the following + environment variables are consulted in this order until one is + found to be set: LC_ALL, LC_COLLATE + (or the variable corresponding to the respective category), + LANG. If none of these environment variables are + set then the locale defaults to C. + + + + Some message localization libraries also look at the environment + variable LANGUAGE which overrides all other locale + settings for the purpose of setting the language of messages. If + in doubt, please refer to the documentation of your operating + system, in particular the documentation about + gettext. + + + + + To enable messages to be translated to the user's preferred language, + NLS must have been selected at build time + (configure --enable-nls). All other locale support is + built in automatically. + + + + + Behavior + + + The locale settings influence the following SQL features: + + + + + Sort order in queries using ORDER BY or the standard + comparison operators on textual data + ORDER BYand locales + + + + + + The upper, lower, and initcap + functions + upperand locales + lowerand locales + + + + + + Pattern matching operators (LIKE, SIMILAR TO, + and POSIX-style regular expressions); locales affect both case + insensitive matching and the classification of characters by + character-class regular expressions + LIKEand locales + regular expressionsand locales + + + + + + The to_char family of functions + to_charand locales + + + + + + The ability to use indexes with LIKE clauses + + + + + + + The drawback of using locales other than C or + POSIX in PostgreSQL is its performance + impact. It slows character handling and prevents ordinary indexes + from being used by LIKE. For this reason use locales + only if you actually need them. + + + + As a workaround to allow PostgreSQL to use indexes + with LIKE clauses under a non-C locale, several custom + operator classes exist. These allow the creation of an index that + performs a strict character-by-character comparison, ignoring + locale comparison rules. Refer to + for more information. Another approach is to create indexes using + the C collation, as discussed in + . + + + + + Problems + + + If locale support doesn't work according to the explanation above, + check that the locale support in your operating system is + correctly configured. To check what locales are installed on your + system, you can use the command locale -a if + your operating system provides it. + + + + Check that PostgreSQL is actually using the locale + that you think it is. The LC_COLLATE and LC_CTYPE + settings are determined when a database is created, and cannot be + changed except by creating a new database. Other locale + settings including LC_MESSAGES and LC_MONETARY + are initially determined by the environment the server is started + in, but can be changed on-the-fly. You can check the active locale + settings using the SHOW command. + + + + The directory src/test/locale in the source + distribution contains a test suite for + PostgreSQL's locale support. + + + + Client applications that handle server-side errors by parsing the + text of the error message will obviously have problems when the + server's messages are in a different language. Authors of such + applications are advised to make use of the error code scheme + instead. + + + + Maintaining catalogs of message translations requires the on-going + efforts of many volunteers that want to see + PostgreSQL speak their preferred language well. + If messages in your language are currently not available or not fully + translated, your assistance would be appreciated. If you want to + help, refer to or write to the developers' + mailing list. + + + + + + + Collation Support + + collation + + + The collation feature allows specifying the sort order and character + classification behavior of data per-column, or even per-operation. + This alleviates the restriction that the + LC_COLLATE and LC_CTYPE settings + of a database cannot be changed after its creation. + + + + Concepts + + + Conceptually, every expression of a collatable data type has a + collation. (The built-in collatable data types are + text, varchar, and char. + User-defined base types can also be marked collatable, and of course + a domain over a collatable data type is collatable.) If the + expression is a column reference, the collation of the expression is the + defined collation of the column. If the expression is a constant, the + collation is the default collation of the data type of the + constant. The collation of a more complex expression is derived + from the collations of its inputs, as described below. + + + + The collation of an expression can be the default + collation, which means the locale settings defined for the + database. It is also possible for an expression's collation to be + indeterminate. In such cases, ordering operations and other + operations that need to know the collation will fail. + + + + When the database system has to perform an ordering or a character + classification, it uses the collation of the input expression. This + happens, for example, with ORDER BY clauses + and function or operator calls such as <. + The collation to apply for an ORDER BY clause + is simply the collation of the sort key. The collation to apply for a + function or operator call is derived from the arguments, as described + below. In addition to comparison operators, collations are taken into + account by functions that convert between lower and upper case + letters, such as lower, upper, and + initcap; by pattern matching operators; and by + to_char and related functions. + + + + For a function or operator call, the collation that is derived by + examining the argument collations is used at run time for performing + the specified operation. If the result of the function or operator + call is of a collatable data type, the collation is also used at parse + time as the defined collation of the function or operator expression, + in case there is a surrounding expression that requires knowledge of + its collation. + + + + The collation derivation of an expression can be + implicit or explicit. This distinction affects how collations are + combined when multiple different collations appear in an + expression. An explicit collation derivation occurs when a + COLLATE clause is used; all other collation + derivations are implicit. When multiple collations need to be + combined, for example in a function call, the following rules are + used: + + + + + If any input expression has an explicit collation derivation, then + all explicitly derived collations among the input expressions must be + the same, otherwise an error is raised. If any explicitly + derived collation is present, that is the result of the + collation combination. + + + + + + Otherwise, all input expressions must have the same implicit + collation derivation or the default collation. If any non-default + collation is present, that is the result of the collation combination. + Otherwise, the result is the default collation. + + + + + + If there are conflicting non-default implicit collations among the + input expressions, then the combination is deemed to have indeterminate + collation. This is not an error condition unless the particular + function being invoked requires knowledge of the collation it should + apply. If it does, an error will be raised at run-time. + + + + + For example, consider this table definition: + +CREATE TABLE test1 ( + a text COLLATE "de_DE", + b text COLLATE "es_ES", + ... +); + + + Then in + +SELECT a < 'foo' FROM test1; + + the < comparison is performed according to + de_DE rules, because the expression combines an + implicitly derived collation with the default collation. But in + +SELECT a < ('foo' COLLATE "fr_FR") FROM test1; + + the comparison is performed using fr_FR rules, + because the explicit collation derivation overrides the implicit one. + Furthermore, given + +SELECT a < b FROM test1; + + the parser cannot determine which collation to apply, since the + a and b columns have conflicting + implicit collations. Since the < operator + does need to know which collation to use, this will result in an + error. The error can be resolved by attaching an explicit collation + specifier to either input expression, thus: + +SELECT a < b COLLATE "de_DE" FROM test1; + + or equivalently + +SELECT a COLLATE "de_DE" < b FROM test1; + + On the other hand, the structurally similar case + +SELECT a || b FROM test1; + + does not result in an error, because the || operator + does not care about collations: its result is the same regardless + of the collation. + + + + The collation assigned to a function or operator's combined input + expressions is also considered to apply to the function or operator's + result, if the function or operator delivers a result of a collatable + data type. So, in + +SELECT * FROM test1 ORDER BY a || 'foo'; + + the ordering will be done according to de_DE rules. + But this query: + +SELECT * FROM test1 ORDER BY a || b; + + results in an error, because even though the || operator + doesn't need to know a collation, the ORDER BY clause does. + As before, the conflict can be resolved with an explicit collation + specifier: + +SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; + + + + + + Managing Collations + + + A collation is an SQL schema object that maps an SQL name to locales + provided by libraries installed in the operating system. A collation + definition has a provider that specifies which + library supplies the locale data. One standard provider name + is libc, which uses the locales provided by the + operating system C library. These are the locales that most tools + provided by the operating system use. Another provider + is icu, which uses the external + ICUICU library. ICU locales can only be + used if support for ICU was configured when PostgreSQL was built. + + + + A collation object provided by libc maps to a + combination of LC_COLLATE and LC_CTYPE + settings, as accepted by the setlocale() system library call. (As + the name would suggest, the main purpose of a collation is to set + LC_COLLATE, which controls the sort order. But + it is rarely necessary in practice to have an + LC_CTYPE setting that is different from + LC_COLLATE, so it is more convenient to collect + these under one concept than to create another infrastructure for + setting LC_CTYPE per expression.) Also, + a libc collation + is tied to a character set encoding (see ). + The same collation name may exist for different encodings. + + + + A collation object provided by icu maps to a named + collator provided by the ICU library. ICU does not support + separate collate and ctype settings, so + they are always the same. Also, ICU collations are independent of the + encoding, so there is always only one ICU collation of a given name in + a database. + + + + Standard Collations + + + On all platforms, the collations named default, + C, and POSIX are available. Additional + collations may be available depending on operating system support. + The default collation selects the LC_COLLATE + and LC_CTYPE values specified at database creation time. + The C and POSIX collations both specify + traditional C behavior, in which only the ASCII letters + A through Z + are treated as letters, and sorting is done strictly by character + code byte values. + + + + Additionally, the SQL standard collation name ucs_basic + is available for encoding UTF8. It is equivalent + to C and sorts by Unicode code point. + + + + + Predefined Collations + + + If the operating system provides support for using multiple locales + within a single program (newlocale and related functions), + or if support for ICU is configured, + then when a database cluster is initialized, initdb + populates the system catalog pg_collation with + collations based on all the locales it finds in the operating + system at the time. + + + + To inspect the currently available locales, use the query SELECT + * FROM pg_collation, or the command \dOS+ + in psql. + + + + libc Collations + + + For example, the operating system might + provide a locale named de_DE.utf8. + initdb would then create a collation named + de_DE.utf8 for encoding UTF8 + that has both LC_COLLATE and + LC_CTYPE set to de_DE.utf8. + It will also create a collation with the .utf8 + tag stripped off the name. So you could also use the collation + under the name de_DE, which is less cumbersome + to write and makes the name less encoding-dependent. Note that, + nevertheless, the initial set of collation names is + platform-dependent. + + + + The default set of collations provided by libc map + directly to the locales installed in the operating system, which can be + listed using the command locale -a. In case + a libc collation is needed that has different values + for LC_COLLATE and LC_CTYPE, or if new + locales are installed in the operating system after the database system + was initialized, then a new collation may be created using + the command. + New operating system locales can also be imported en masse using + the pg_import_system_collations() function. + + + + Within any particular database, only collations that use that + database's encoding are of interest. Other entries in + pg_collation are ignored. Thus, a stripped collation + name such as de_DE can be considered unique + within a given database even though it would not be unique globally. + Use of the stripped collation names is recommended, since it will + make one fewer thing you need to change if you decide to change to + another database encoding. Note however that the default, + C, and POSIX collations can be used regardless of + the database encoding. + + + + PostgreSQL considers distinct collation + objects to be incompatible even when they have identical properties. + Thus for example, + +SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; + + will draw an error even though the C and POSIX + collations have identical behaviors. Mixing stripped and non-stripped + collation names is therefore not recommended. + + + + + ICU Collations + + + With ICU, it is not sensible to enumerate all possible locale names. ICU + uses a particular naming system for locales, but there are many more ways + to name a locale than there are actually distinct locales. + initdb uses the ICU APIs to extract a set of distinct + locales to populate the initial set of collations. Collations provided by + ICU are created in the SQL environment with names in BCP 47 language tag + format, with a private use + extension -x-icu appended, to distinguish them from + libc locales. + + + + Here are some example collations that might be created: + + + + de-x-icu + + German collation, default variant + + + + + de-AT-x-icu + + German collation for Austria, default variant + + (There are also, say, de-DE-x-icu + or de-CH-x-icu, but as of this writing, they are + equivalent to de-x-icu.) + + + + + + und-x-icu (for undefined) + + + ICU root collation. Use this to get a reasonable + language-agnostic sort order. + + + + + + + + Some (less frequently used) encodings are not supported by ICU. When the + database encoding is one of these, ICU collation entries + in pg_collation are ignored. Attempting to use one + will draw an error along the lines of collation "de-x-icu" for + encoding "WIN874" does not exist. + + + + + + Creating New Collation Objects + + + If the standard and predefined collations are not sufficient, users can + create their own collation objects using the SQL + command . + + + + The standard and predefined collations are in the + schema pg_catalog, like all predefined objects. + User-defined collations should be created in user schemas. This also + ensures that they are saved by pg_dump. + + + + libc Collations + + + New libc collations can be created like this: + +CREATE COLLATION german (provider = libc, locale = 'de_DE'); + + The exact values that are acceptable for the locale + clause in this command depend on the operating system. On Unix-like + systems, the command locale -a will show a list. + + + + Since the predefined libc collations already include all collations + defined in the operating system when the database instance is + initialized, it is not often necessary to manually create new ones. + Reasons might be if a different naming system is desired (in which case + see also ) or if the operating system has + been upgraded to provide new locale definitions (in which case see + also pg_import_system_collations()). + + + + + ICU Collations + + + ICU allows collations to be customized beyond the basic language+country + set that is preloaded by initdb. Users are encouraged + to define their own collation objects that make use of these facilities to + suit the sorting behavior to their requirements. + See + and for + information on ICU locale naming. The set of acceptable names and + attributes depends on the particular ICU version. + + + + Here are some examples: + + + + CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk'); + CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook'); + + German collation with phone book collation type + + The first example selects the ICU locale using a language + tag per BCP 47. The second example uses the traditional + ICU-specific locale syntax. The first style is preferred going + forward, but it is not supported by older ICU versions. + + + Note that you can name the collation objects in the SQL environment + anything you want. In this example, we follow the naming style that + the predefined collations use, which in turn also follow BCP 47, but + that is not required for user-defined collations. + + + + + + CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji'); + CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji'); + + + Root collation with Emoji collation type, per Unicode Technical Standard #51 + + + Observe how in the traditional ICU locale naming system, the root + locale is selected by an empty string. + + + + + + CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn'); + CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn'); + + + Sort Greek letters before Latin ones. (The default is Latin before Greek.) + + + + + + CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper'); + CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper'); + + + Sort upper-case letters before lower-case letters. (The default is + lower-case letters first.) + + + + + + CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn'); + CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn'); + + + Combines both of the above options. + + + + + + CREATE COLLATION numeric (provider = icu, locale = 'en-u-kn-true'); + CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes'); + + + Numeric ordering, sorts sequences of digits by their numeric value, + for example: A-21 < A-123 + (also known as natural sort). + + + + + + See Unicode + Technical Standard #35 + and BCP 47 for + details. The list of possible collation types (co + subtag) can be found in + the CLDR + repository. + The ICU Locale + Explorer can be used to check the details of a particular locale + definition. The examples using the k* subtags require + at least ICU version 54. + + + + Note that while this system allows creating collations that ignore + case or ignore accents or similar (using the + ks key), in order for such collations to act in a + truly case- or accent-insensitive manner, they also need to be declared as not + deterministic in CREATE COLLATION; + see . + Otherwise, any strings that compare equal according to the collation but + are not byte-wise equal will be sorted according to their byte values. + + + + + By design, ICU will accept almost any string as a locale name and match + it to the closest locale it can provide, using the fallback procedure + described in its documentation. Thus, there will be no direct feedback + if a collation specification is composed using features that the given + ICU installation does not actually support. It is therefore recommended + to create application-level test cases to check that the collation + definitions satisfy one's requirements. + + + + + + Copying Collations + + + The command can also be used to + create a new collation from an existing collation, which can be useful to + be able to use operating-system-independent collation names in + applications, create compatibility names, or use an ICU-provided collation + under a more readable name. For example: + +CREATE COLLATION german FROM "de_DE"; +CREATE COLLATION french FROM "fr-x-icu"; + + + + + + + Nondeterministic Collations + + + A collation is either deterministic or + nondeterministic. A deterministic collation uses + deterministic comparisons, which means that it considers strings to be + equal only if they consist of the same byte sequence. Nondeterministic + comparison may determine strings to be equal even if they consist of + different bytes. Typical situations include case-insensitive comparison, + accent-insensitive comparison, as well as comparison of strings in + different Unicode normal forms. It is up to the collation provider to + actually implement such insensitive comparisons; the deterministic flag + only determines whether ties are to be broken using bytewise comparison. + See also Unicode Technical + Standard 10 for more information on the terminology. + + + + To create a nondeterministic collation, specify the property + deterministic = false to CREATE + COLLATION, for example: + +CREATE COLLATION ndcoll (provider = icu, locale = 'und', deterministic = false); + + This example would use the standard Unicode collation in a + nondeterministic way. In particular, this would allow strings in + different normal forms to be compared correctly. More interesting + examples make use of the ICU customization facilities explained above. + For example: + +CREATE COLLATION case_insensitive (provider = icu, locale = 'und-u-ks-level2', deterministic = false); +CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-true', deterministic = false); + + + + + All standard and predefined collations are deterministic, all + user-defined collations are deterministic by default. While + nondeterministic collations give a more correct behavior, + especially when considering the full power of Unicode and its many + special cases, they also have some drawbacks. Foremost, their use leads + to a performance penalty. Note, in particular, that B-tree cannot use + deduplication with indexes that use a nondeterministic collation. Also, + certain operations are not possible with nondeterministic collations, + such as pattern matching operations. Therefore, they should be used + only in cases where they are specifically wanted. + + + + + To deal with text in different Unicode normalization forms, it is also + an option to use the functions/expressions + normalize and is normalized to + preprocess or check the strings, instead of using nondeterministic + collations. There are different trade-offs for each approach. + + + + + + + + Character Set Support + + character set + + + The character set support in PostgreSQL + allows you to store text in a variety of character sets (also called + encodings), including + single-byte character sets such as the ISO 8859 series and + multiple-byte character sets such as EUC (Extended Unix + Code), UTF-8, and Mule internal code. All supported character sets + can be used transparently by clients, but a few are not supported + for use within the server (that is, as a server-side encoding). + The default character set is selected while + initializing your PostgreSQL database + cluster using initdb. It can be overridden when you + create a database, so you can have multiple + databases each with a different character set. + + + + An important restriction, however, is that each database's character set + must be compatible with the database's LC_CTYPE (character + classification) and LC_COLLATE (string sort order) locale + settings. For C or + POSIX locale, any character set is allowed, but for other + libc-provided locales there is only one character set that will work + correctly. + (On Windows, however, UTF-8 encoding can be used with any locale.) + If you have ICU support configured, ICU-provided locales can be used + with most but not all server-side encodings. + + + + Supported Character Sets + + + shows the character sets available + for use in PostgreSQL. + + + + <productname>PostgreSQL</productname> Character Sets + + + + + + + + + + + Name + Description + Language + Server? + ICU? + + Bytes/&zwsp;Char + Aliases + + + + + BIG5 + Big Five + Traditional Chinese + No + No + 1–2 + WIN950, Windows950 + + + EUC_CN + Extended UNIX Code-CN + Simplified Chinese + Yes + Yes + 1–3 + + + + EUC_JP + Extended UNIX Code-JP + Japanese + Yes + Yes + 1–3 + + + + EUC_JIS_2004 + Extended UNIX Code-JP, JIS X 0213 + Japanese + Yes + No + 1–3 + + + + EUC_KR + Extended UNIX Code-KR + Korean + Yes + Yes + 1–3 + + + + EUC_TW + Extended UNIX Code-TW + Traditional Chinese, Taiwanese + Yes + Yes + 1–3 + + + + GB18030 + National Standard + Chinese + No + No + 1–4 + + + + GBK + Extended National Standard + Simplified Chinese + No + No + 1–2 + WIN936, Windows936 + + + ISO_8859_5 + ISO 8859-5, ECMA 113 + Latin/Cyrillic + Yes + Yes + 1 + + + + ISO_8859_6 + ISO 8859-6, ECMA 114 + Latin/Arabic + Yes + Yes + 1 + + + + ISO_8859_7 + ISO 8859-7, ECMA 118 + Latin/Greek + Yes + Yes + 1 + + + + ISO_8859_8 + ISO 8859-8, ECMA 121 + Latin/Hebrew + Yes + Yes + 1 + + + + JOHAB + JOHAB + Korean (Hangul) + No + No + 1–3 + + + + KOI8R + KOI8-R + Cyrillic (Russian) + Yes + Yes + 1 + KOI8 + + + KOI8U + KOI8-U + Cyrillic (Ukrainian) + Yes + Yes + 1 + + + + LATIN1 + ISO 8859-1, ECMA 94 + Western European + Yes + Yes + 1 + ISO88591 + + + LATIN2 + ISO 8859-2, ECMA 94 + Central European + Yes + Yes + 1 + ISO88592 + + + LATIN3 + ISO 8859-3, ECMA 94 + South European + Yes + Yes + 1 + ISO88593 + + + LATIN4 + ISO 8859-4, ECMA 94 + North European + Yes + Yes + 1 + ISO88594 + + + LATIN5 + ISO 8859-9, ECMA 128 + Turkish + Yes + Yes + 1 + ISO88599 + + + LATIN6 + ISO 8859-10, ECMA 144 + Nordic + Yes + Yes + 1 + ISO885910 + + + LATIN7 + ISO 8859-13 + Baltic + Yes + Yes + 1 + ISO885913 + + + LATIN8 + ISO 8859-14 + Celtic + Yes + Yes + 1 + ISO885914 + + + LATIN9 + ISO 8859-15 + LATIN1 with Euro and accents + Yes + Yes + 1 + ISO885915 + + + LATIN10 + ISO 8859-16, ASRO SR 14111 + Romanian + Yes + No + 1 + ISO885916 + + + MULE_INTERNAL + Mule internal code + Multilingual Emacs + Yes + No + 1–4 + + + + SJIS + Shift JIS + Japanese + No + No + 1–2 + Mskanji, ShiftJIS, WIN932, Windows932 + + + SHIFT_JIS_2004 + Shift JIS, JIS X 0213 + Japanese + No + No + 1–2 + + + + SQL_ASCII + unspecified (see text) + any + Yes + No + 1 + + + + UHC + Unified Hangul Code + Korean + No + No + 1–2 + WIN949, Windows949 + + + UTF8 + Unicode, 8-bit + all + Yes + Yes + 1–4 + Unicode + + + WIN866 + Windows CP866 + Cyrillic + Yes + Yes + 1 + ALT + + + WIN874 + Windows CP874 + Thai + Yes + No + 1 + + + + WIN1250 + Windows CP1250 + Central European + Yes + Yes + 1 + + + + WIN1251 + Windows CP1251 + Cyrillic + Yes + Yes + 1 + WIN + + + WIN1252 + Windows CP1252 + Western European + Yes + Yes + 1 + + + + WIN1253 + Windows CP1253 + Greek + Yes + Yes + 1 + + + + WIN1254 + Windows CP1254 + Turkish + Yes + Yes + 1 + + + + WIN1255 + Windows CP1255 + Hebrew + Yes + Yes + 1 + + + + WIN1256 + Windows CP1256 + Arabic + Yes + Yes + 1 + + + + WIN1257 + Windows CP1257 + Baltic + Yes + Yes + 1 + + + + WIN1258 + Windows CP1258 + Vietnamese + Yes + Yes + 1 + ABC, TCVN, TCVN5712, VSCII + + + +
+ + + Not all client APIs support all the listed character sets. For example, the + PostgreSQL + JDBC driver does not support MULE_INTERNAL, LATIN6, + LATIN8, and LATIN10. + + + + The SQL_ASCII setting behaves considerably differently + from the other settings. When the server character set is + SQL_ASCII, the server interprets byte values 0–127 + according to the ASCII standard, while byte values 128–255 are taken + as uninterpreted characters. No encoding conversion will be done when + the setting is SQL_ASCII. Thus, this setting is not so + much a declaration that a specific encoding is in use, as a declaration + of ignorance about the encoding. In most cases, if you are + working with any non-ASCII data, it is unwise to use the + SQL_ASCII setting because + PostgreSQL will be unable to help you by + converting or validating non-ASCII characters. + +
+ + + Setting the Character Set + + + initdb defines the default character set (encoding) + for a PostgreSQL cluster. For example, + + +initdb -E EUC_JP + + + sets the default character set to + EUC_JP (Extended Unix Code for Japanese). You + can use instead of + if you prefer longer option strings. + If no or option is + given, initdb attempts to determine the appropriate + encoding to use based on the specified or default locale. + + + + You can specify a non-default encoding at database creation time, + provided that the encoding is compatible with the selected locale: + + +createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean + + + This will create a database named korean that + uses the character set EUC_KR, and locale ko_KR. + Another way to accomplish this is to use this SQL command: + + +CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0; + + + Notice that the above commands specify copying the template0 + database. When copying any other database, the encoding and locale + settings cannot be changed from those of the source database, because + that might result in corrupt data. For more information see + . + + + + The encoding for a database is stored in the system catalog + pg_database. You can see it by using the + psql option or the + \l command. + + +$ psql -l + List of databases + Name | Owner | Encoding | Collation | Ctype | Access Privileges +-----------+----------+-----------+-------------+-------------+------------------------------------- + clocaledb | hlinnaka | SQL_ASCII | C | C | + englishdb | hlinnaka | UTF8 | en_GB.UTF8 | en_GB.UTF8 | + japanese | hlinnaka | UTF8 | ja_JP.UTF8 | ja_JP.UTF8 | + korean | hlinnaka | EUC_KR | ko_KR.euckr | ko_KR.euckr | + postgres | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 | + template0 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 | {=c/hlinnaka,hlinnaka=CTc/hlinnaka} + template1 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 | {=c/hlinnaka,hlinnaka=CTc/hlinnaka} +(7 rows) + + + + + + On most modern operating systems, PostgreSQL + can determine which character set is implied by the LC_CTYPE + setting, and it will enforce that only the matching database encoding is + used. On older systems it is your responsibility to ensure that you use + the encoding expected by the locale you have selected. A mistake in + this area is likely to lead to strange behavior of locale-dependent + operations such as sorting. + + + + PostgreSQL will allow superusers to create + databases with SQL_ASCII encoding even when + LC_CTYPE is not C or POSIX. As noted + above, SQL_ASCII does not enforce that the data stored in + the database has any particular encoding, and so this choice poses risks + of locale-dependent misbehavior. Using this combination of settings is + deprecated and may someday be forbidden altogether. + + + + + + Automatic Character Set Conversion Between Server and Client + + + PostgreSQL supports automatic character + set conversion between server and client for many combinations of + character sets ( + shows which ones). + + + + To enable automatic character set conversion, you have to + tell PostgreSQL the character set + (encoding) you would like to use in the client. There are several + ways to accomplish this: + + + + + Using the \encoding command in + psql. + \encoding allows you to change client + encoding on the fly. For + example, to change the encoding to SJIS, type: + + +\encoding SJIS + + + + + + + libpq () has functions to control the client encoding. + + + + + + Using SET client_encoding TO. + + Setting the client encoding can be done with this SQL command: + + +SET CLIENT_ENCODING TO 'value'; + + + Also you can use the standard SQL syntax SET NAMES + for this purpose: + + +SET NAMES 'value'; + + + To query the current client encoding: + + +SHOW client_encoding; + + + To return to the default encoding: + + +RESET client_encoding; + + + + + + + Using PGCLIENTENCODING. If the environment variable + PGCLIENTENCODING is defined in the client's + environment, that client encoding is automatically selected + when a connection to the server is made. (This can + subsequently be overridden using any of the other methods + mentioned above.) + + + + + + Using the configuration variable . If the + client_encoding variable is set, that client + encoding is automatically selected when a connection to the + server is made. (This can subsequently be overridden using any + of the other methods mentioned above.) + + + + + + + + If the conversion of a particular character is not possible + — suppose you chose EUC_JP for the + server and LATIN1 for the client, and some + Japanese characters are returned that do not have a representation in + LATIN1 — an error is reported. + + + + If the client character set is defined as SQL_ASCII, + encoding conversion is disabled, regardless of the server's character + set. (However, if the server's character set is + not SQL_ASCII, the server will still check that + incoming data is valid for that encoding; so the net effect is as + though the client character set were the same as the server's.) + Just as for the server, use of SQL_ASCII is unwise + unless you are working with all-ASCII data. + + + + + Available Character Set Conversions + + + PostgreSQL allows conversion between any + two character sets for which a conversion function is listed in the + pg_conversion + system catalog. PostgreSQL comes with + some predefined conversions, as summarized in + and shown in more + detail in . You can + create a new conversion using the SQL command + . (To be used for automatic + client/server conversions, a conversion must be marked + as default for its character set pair.) + + + + Built-in Client/Server Character Set Conversions + + + + + + Server Character Set + Available Client Character Sets + + + + + BIG5 + not supported as a server encoding + + + + EUC_CN + EUC_CN, + MULE_INTERNAL, + UTF8 + + + + EUC_JP + EUC_JP, + MULE_INTERNAL, + SJIS, + UTF8 + + + + EUC_JIS_2004 + EUC_JIS_2004, + SHIFT_JIS_2004, + UTF8 + + + + EUC_KR + EUC_KR, + MULE_INTERNAL, + UTF8 + + + + EUC_TW + EUC_TW, + BIG5, + MULE_INTERNAL, + UTF8 + + + + GB18030 + not supported as a server encoding + + + + GBK + not supported as a server encoding + + + + ISO_8859_5 + ISO_8859_5, + KOI8R, + MULE_INTERNAL, + UTF8, + WIN866, + WIN1251 + + + + ISO_8859_6 + ISO_8859_6, + UTF8 + + + + ISO_8859_7 + ISO_8859_7, + UTF8 + + + + ISO_8859_8 + ISO_8859_8, + UTF8 + + + + JOHAB + not supported as a server encoding + + + + KOI8R + KOI8R, + ISO_8859_5, + MULE_INTERNAL, + UTF8, + WIN866, + WIN1251 + + + + KOI8U + KOI8U, + UTF8 + + + + LATIN1 + LATIN1, + MULE_INTERNAL, + UTF8 + + + + LATIN2 + LATIN2, + MULE_INTERNAL, + UTF8, + WIN1250 + + + + LATIN3 + LATIN3, + MULE_INTERNAL, + UTF8 + + + + LATIN4 + LATIN4, + MULE_INTERNAL, + UTF8 + + + + LATIN5 + LATIN5, + UTF8 + + + + LATIN6 + LATIN6, + UTF8 + + + + LATIN7 + LATIN7, + UTF8 + + + + LATIN8 + LATIN8, + UTF8 + + + + LATIN9 + LATIN9, + UTF8 + + + + LATIN10 + LATIN10, + UTF8 + + + + MULE_INTERNAL + MULE_INTERNAL, + BIG5, + EUC_CN, + EUC_JP, + EUC_KR, + EUC_TW, + ISO_8859_5, + KOI8R, + LATIN1 to LATIN4, + SJIS, + WIN866, + WIN1250, + WIN1251 + + + + SJIS + not supported as a server encoding + + + + SHIFT_JIS_2004 + not supported as a server encoding + + + + SQL_ASCII + any (no conversion will be performed) + + + + UHC + not supported as a server encoding + + + + UTF8 + all supported encodings + + + + WIN866 + WIN866, + ISO_8859_5, + KOI8R, + MULE_INTERNAL, + UTF8, + WIN1251 + + + + WIN874 + WIN874, + UTF8 + + + + WIN1250 + WIN1250, + LATIN2, + MULE_INTERNAL, + UTF8 + + + + WIN1251 + WIN1251, + ISO_8859_5, + KOI8R, + MULE_INTERNAL, + UTF8, + WIN866 + + + + WIN1252 + WIN1252, + UTF8 + + + + WIN1253 + WIN1253, + UTF8 + + + + WIN1254 + WIN1254, + UTF8 + + + + WIN1255 + WIN1255, + UTF8 + + + + WIN1256 + WIN1256, + UTF8 + + + + WIN1257 + WIN1257, + UTF8 + + + + WIN1258 + WIN1258, + UTF8 + + + + +
+ + + All Built-in Character Set Conversions + + + + + + + Conversion Name + + + The conversion names follow a standard naming scheme: The + official name of the source encoding with all + non-alphanumeric characters replaced by underscores, followed + by _to_, followed by the similarly processed + destination encoding name. Therefore, these names sometimes + deviate from the customary encoding names shown in + . + + + + Source Encoding + Destination Encoding + + + + + + big5_to_euc_tw + BIG5 + EUC_TW + + + big5_to_mic + BIG5 + MULE_INTERNAL + + + big5_to_utf8 + BIG5 + UTF8 + + + euc_cn_to_mic + EUC_CN + MULE_INTERNAL + + + euc_cn_to_utf8 + EUC_CN + UTF8 + + + euc_jp_to_mic + EUC_JP + MULE_INTERNAL + + + euc_jp_to_sjis + EUC_JP + SJIS + + + euc_jp_to_utf8 + EUC_JP + UTF8 + + + euc_kr_to_mic + EUC_KR + MULE_INTERNAL + + + euc_kr_to_utf8 + EUC_KR + UTF8 + + + euc_tw_to_big5 + EUC_TW + BIG5 + + + euc_tw_to_mic + EUC_TW + MULE_INTERNAL + + + euc_tw_to_utf8 + EUC_TW + UTF8 + + + gb18030_to_utf8 + GB18030 + UTF8 + + + gbk_to_utf8 + GBK + UTF8 + + + iso_8859_10_to_utf8 + LATIN6 + UTF8 + + + iso_8859_13_to_utf8 + LATIN7 + UTF8 + + + iso_8859_14_to_utf8 + LATIN8 + UTF8 + + + iso_8859_15_to_utf8 + LATIN9 + UTF8 + + + iso_8859_16_to_utf8 + LATIN10 + UTF8 + + + iso_8859_1_to_mic + LATIN1 + MULE_INTERNAL + + + iso_8859_1_to_utf8 + LATIN1 + UTF8 + + + iso_8859_2_to_mic + LATIN2 + MULE_INTERNAL + + + iso_8859_2_to_utf8 + LATIN2 + UTF8 + + + iso_8859_2_to_windows_1250 + LATIN2 + WIN1250 + + + iso_8859_3_to_mic + LATIN3 + MULE_INTERNAL + + + iso_8859_3_to_utf8 + LATIN3 + UTF8 + + + iso_8859_4_to_mic + LATIN4 + MULE_INTERNAL + + + iso_8859_4_to_utf8 + LATIN4 + UTF8 + + + iso_8859_5_to_koi8_r + ISO_8859_5 + KOI8R + + + iso_8859_5_to_mic + ISO_8859_5 + MULE_INTERNAL + + + iso_8859_5_to_utf8 + ISO_8859_5 + UTF8 + + + iso_8859_5_to_windows_1251 + ISO_8859_5 + WIN1251 + + + iso_8859_5_to_windows_866 + ISO_8859_5 + WIN866 + + + iso_8859_6_to_utf8 + ISO_8859_6 + UTF8 + + + iso_8859_7_to_utf8 + ISO_8859_7 + UTF8 + + + iso_8859_8_to_utf8 + ISO_8859_8 + UTF8 + + + iso_8859_9_to_utf8 + LATIN5 + UTF8 + + + johab_to_utf8 + JOHAB + UTF8 + + + koi8_r_to_iso_8859_5 + KOI8R + ISO_8859_5 + + + koi8_r_to_mic + KOI8R + MULE_INTERNAL + + + koi8_r_to_utf8 + KOI8R + UTF8 + + + koi8_r_to_windows_1251 + KOI8R + WIN1251 + + + koi8_r_to_windows_866 + KOI8R + WIN866 + + + koi8_u_to_utf8 + KOI8U + UTF8 + + + mic_to_big5 + MULE_INTERNAL + BIG5 + + + mic_to_euc_cn + MULE_INTERNAL + EUC_CN + + + mic_to_euc_jp + MULE_INTERNAL + EUC_JP + + + mic_to_euc_kr + MULE_INTERNAL + EUC_KR + + + mic_to_euc_tw + MULE_INTERNAL + EUC_TW + + + mic_to_iso_8859_1 + MULE_INTERNAL + LATIN1 + + + mic_to_iso_8859_2 + MULE_INTERNAL + LATIN2 + + + mic_to_iso_8859_3 + MULE_INTERNAL + LATIN3 + + + mic_to_iso_8859_4 + MULE_INTERNAL + LATIN4 + + + mic_to_iso_8859_5 + MULE_INTERNAL + ISO_8859_5 + + + mic_to_koi8_r + MULE_INTERNAL + KOI8R + + + mic_to_sjis + MULE_INTERNAL + SJIS + + + mic_to_windows_1250 + MULE_INTERNAL + WIN1250 + + + mic_to_windows_1251 + MULE_INTERNAL + WIN1251 + + + mic_to_windows_866 + MULE_INTERNAL + WIN866 + + + sjis_to_euc_jp + SJIS + EUC_JP + + + sjis_to_mic + SJIS + MULE_INTERNAL + + + sjis_to_utf8 + SJIS + UTF8 + + + windows_1258_to_utf8 + WIN1258 + UTF8 + + + uhc_to_utf8 + UHC + UTF8 + + + utf8_to_big5 + UTF8 + BIG5 + + + utf8_to_euc_cn + UTF8 + EUC_CN + + + utf8_to_euc_jp + UTF8 + EUC_JP + + + utf8_to_euc_kr + UTF8 + EUC_KR + + + utf8_to_euc_tw + UTF8 + EUC_TW + + + utf8_to_gb18030 + UTF8 + GB18030 + + + utf8_to_gbk + UTF8 + GBK + + + utf8_to_iso_8859_1 + UTF8 + LATIN1 + + + utf8_to_iso_8859_10 + UTF8 + LATIN6 + + + utf8_to_iso_8859_13 + UTF8 + LATIN7 + + + utf8_to_iso_8859_14 + UTF8 + LATIN8 + + + utf8_to_iso_8859_15 + UTF8 + LATIN9 + + + utf8_to_iso_8859_16 + UTF8 + LATIN10 + + + utf8_to_iso_8859_2 + UTF8 + LATIN2 + + + utf8_to_iso_8859_3 + UTF8 + LATIN3 + + + utf8_to_iso_8859_4 + UTF8 + LATIN4 + + + utf8_to_iso_8859_5 + UTF8 + ISO_8859_5 + + + utf8_to_iso_8859_6 + UTF8 + ISO_8859_6 + + + utf8_to_iso_8859_7 + UTF8 + ISO_8859_7 + + + utf8_to_iso_8859_8 + UTF8 + ISO_8859_8 + + + utf8_to_iso_8859_9 + UTF8 + LATIN5 + + + utf8_to_johab + UTF8 + JOHAB + + + utf8_to_koi8_r + UTF8 + KOI8R + + + utf8_to_koi8_u + UTF8 + KOI8U + + + utf8_to_sjis + UTF8 + SJIS + + + utf8_to_windows_1258 + UTF8 + WIN1258 + + + utf8_to_uhc + UTF8 + UHC + + + utf8_to_windows_1250 + UTF8 + WIN1250 + + + utf8_to_windows_1251 + UTF8 + WIN1251 + + + utf8_to_windows_1252 + UTF8 + WIN1252 + + + utf8_to_windows_1253 + UTF8 + WIN1253 + + + utf8_to_windows_1254 + UTF8 + WIN1254 + + + utf8_to_windows_1255 + UTF8 + WIN1255 + + + utf8_to_windows_1256 + UTF8 + WIN1256 + + + utf8_to_windows_1257 + UTF8 + WIN1257 + + + utf8_to_windows_866 + UTF8 + WIN866 + + + utf8_to_windows_874 + UTF8 + WIN874 + + + windows_1250_to_iso_8859_2 + WIN1250 + LATIN2 + + + windows_1250_to_mic + WIN1250 + MULE_INTERNAL + + + windows_1250_to_utf8 + WIN1250 + UTF8 + + + windows_1251_to_iso_8859_5 + WIN1251 + ISO_8859_5 + + + windows_1251_to_koi8_r + WIN1251 + KOI8R + + + windows_1251_to_mic + WIN1251 + MULE_INTERNAL + + + windows_1251_to_utf8 + WIN1251 + UTF8 + + + windows_1251_to_windows_866 + WIN1251 + WIN866 + + + windows_1252_to_utf8 + WIN1252 + UTF8 + + + windows_1256_to_utf8 + WIN1256 + UTF8 + + + windows_866_to_iso_8859_5 + WIN866 + ISO_8859_5 + + + windows_866_to_koi8_r + WIN866 + KOI8R + + + windows_866_to_mic + WIN866 + MULE_INTERNAL + + + windows_866_to_utf8 + WIN866 + UTF8 + + + windows_866_to_windows_1251 + WIN866 + WIN + + + windows_874_to_utf8 + WIN874 + UTF8 + + + euc_jis_2004_to_utf8 + EUC_JIS_2004 + UTF8 + + + utf8_to_euc_jis_2004 + UTF8 + EUC_JIS_2004 + + + shift_jis_2004_to_utf8 + SHIFT_JIS_2004 + UTF8 + + + utf8_to_shift_jis_2004 + UTF8 + SHIFT_JIS_2004 + + + euc_jis_2004_to_shift_jis_2004 + EUC_JIS_2004 + SHIFT_JIS_2004 + + + shift_jis_2004_to_euc_jis_2004 + SHIFT_JIS_2004 + EUC_JIS_2004 + + + +
+
+ + + Further Reading + + + These are good sources to start learning about various kinds of encoding + systems. + + + + CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing + + + + Contains detailed explanations of EUC_JP, + EUC_CN, EUC_KR, + EUC_TW. + + + + + + + + + + The web site of the Unicode Consortium. + + + + + + RFC 3629 + + + + UTF-8 (8-bit UCS/Unicode Transformation + Format) is defined here. + + + + + + + +
+ +
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml new file mode 100644 index 000000000000..02f048911295 --- /dev/null +++ b/doc/src/sgml/client-auth.sgml @@ -0,0 +1,2232 @@ + + + + Client Authentication + + + client authentication + + + + When a client application connects to the database server, it + specifies which PostgreSQL database user name it + wants to connect as, much the same way one logs into a Unix computer + as a particular user. Within the SQL environment the active database + user name determines access privileges to database objects — see + for more information. Therefore, it is + essential to restrict which database users can connect. + + + + + As explained in , + PostgreSQL actually does privilege + management in terms of roles. In this chapter, we + consistently use database user to mean role with the + LOGIN privilege. + + + + + Authentication is the process by which the + database server establishes the identity of the client, and by + extension determines whether the client application (or the user + who runs the client application) is permitted to connect with the + database user name that was requested. + + + + PostgreSQL offers a number of different + client authentication methods. The method used to authenticate a + particular client connection can be selected on the basis of + (client) host address, database, and user. + + + + PostgreSQL database user names are logically + separate from user names of the operating system in which the server + runs. If all the users of a particular server also have accounts on + the server's machine, it makes sense to assign database user names + that match their operating system user names. However, a server that + accepts remote connections might have many database users who have no local + operating system + account, and in such cases there need be no connection between + database user names and OS user names. + + + + The <filename>pg_hba.conf</filename> File + + + pg_hba.conf + + + + Client authentication is controlled by a configuration file, + which traditionally is named + pg_hba.conf and is stored in the database + cluster's data directory. + (HBA stands for host-based authentication.) A default + pg_hba.conf file is installed when the data + directory is initialized by initdb. It is + possible to place the authentication configuration file elsewhere, + however; see the configuration parameter. + + + + The general format of the pg_hba.conf file is + a set of records, one per line. Blank lines are ignored, as is any + text after the # comment character. + A record can be continued onto the next line by ending the line with + a backslash. (Backslashes are not special except at the end of a line.) + A record is made + up of a number of fields which are separated by spaces and/or tabs. + Fields can contain white space if the field value is double-quoted. + Quoting one of the keywords in a database, user, or address field (e.g., + all or replication) makes the word lose its special + meaning, and just match a database, user, or host with that name. + Backslash line continuation applies even within quoted text or comments. + + + + Each record specifies a connection type, a client IP address range + (if relevant for the connection type), a database name, a user name, + and the authentication method to be used for connections matching + these parameters. The first record with a matching connection type, + client address, requested database, and user name is used to perform + authentication. There is no fall-through or + backup: if one record is chosen and the authentication + fails, subsequent records are not considered. If no record matches, + access is denied. + + + + A record can have several formats: + +local database user auth-method auth-options +host database user address auth-method auth-options +hostssl database user address auth-method auth-options +hostnossl database user address auth-method auth-options +hostgssenc database user address auth-method auth-options +hostnogssenc database user address auth-method auth-options +host database user IP-address IP-mask auth-method auth-options +hostssl database user IP-address IP-mask auth-method auth-options +hostnossl database user IP-address IP-mask auth-method auth-options +hostgssenc database user IP-address IP-mask auth-method auth-options +hostnogssenc database user IP-address IP-mask auth-method auth-options + + The meaning of the fields is as follows: + + + + local + + + This record matches connection attempts using Unix-domain + sockets. Without a record of this type, Unix-domain socket + connections are disallowed. + + + + + + host + + + This record matches connection attempts made using TCP/IP. + host records match + SSL or non-SSL connection + attempts as well as GSSAPI encrypted or + non-GSSAPI encrypted connection attempts. + + + + Remote TCP/IP connections will not be possible unless + the server is started with an appropriate value for the + configuration parameter, + since the default behavior is to listen for TCP/IP connections + only on the local loopback address localhost. + + + + + + + hostssl + + + This record matches connection attempts made using TCP/IP, + but only when the connection is made with SSL + encryption. + + + + To make use of this option the server must be built with + SSL support. Furthermore, + SSL must be enabled + by setting the configuration parameter (see + for more information). + Otherwise, the hostssl record is ignored except for + logging a warning that it cannot match any connections. + + + + + + hostnossl + + + This record type has the opposite behavior of hostssl; + it only matches connection attempts made over + TCP/IP that do not use SSL. + + + + + + hostgssenc + + + This record matches connection attempts made using TCP/IP, + but only when the connection is made with GSSAPI + encryption. + + + + To make use of this option the server must be built with + GSSAPI support. Otherwise, + the hostgssenc record is ignored except for logging + a warning that it cannot match any connections. + + + + + + hostnogssenc + + + This record type has the opposite behavior of hostgssenc; + it only matches connection attempts made over + TCP/IP that do not use GSSAPI encryption. + + + + + + database + + + Specifies which database name(s) this record matches. The value + all specifies that it matches all databases. + The value sameuser specifies that the record + matches if the requested database has the same name as the + requested user. The value samerole specifies that + the requested user must be a member of the role with the same + name as the requested database. (samegroup is an + obsolete but still accepted spelling of samerole.) + Superusers are not considered to be members of a role for the + purposes of samerole unless they are explicitly + members of the role, directly or indirectly, and not just by + virtue of being a superuser. + The value replication specifies that the record + matches if a physical replication connection is requested, however, it + doesn't match with logical replication connections. Note that physical + replication connections do not specify any particular database whereas + logical replication connections do specify it. + Otherwise, this is the name of + a specific PostgreSQL database. + Multiple database names can be supplied by separating them with + commas. A separate file containing database names can be specified by + preceding the file name with @. + + + + + + user + + + Specifies which database user name(s) this record + matches. The value all specifies that it + matches all users. Otherwise, this is either the name of a specific + database user, or a group name preceded by +. + (Recall that there is no real distinction between users and groups + in PostgreSQL; a + mark really means + match any of the roles that are directly or indirectly members + of this role, while a name without a + mark matches + only that specific role.) For this purpose, a superuser is only + considered to be a member of a role if they are explicitly a member + of the role, directly or indirectly, and not just by virtue of + being a superuser. + Multiple user names can be supplied by separating them with commas. + A separate file containing user names can be specified by preceding the + file name with @. + + + + + + address + + + Specifies the client machine address(es) that this record + matches. This field can contain either a host name, an IP + address range, or one of the special key words mentioned below. + + + + An IP address range is specified using standard numeric notation + for the range's starting address, then a slash (/) + and a CIDR mask length. The mask + length indicates the number of high-order bits of the client + IP address that must match. Bits to the right of this should + be zero in the given IP address. + There must not be any white space between the IP address, the + /, and the CIDR mask length. + + + + Typical examples of an IPv4 address range specified this way are + 172.20.143.89/32 for a single host, or + 172.20.143.0/24 for a small network, or + 10.6.0.0/16 for a larger one. + An IPv6 address range might look like ::1/128 + for a single host (in this case the IPv6 loopback address) or + fe80::7a31:c1ff:0000:0000/96 for a small + network. + 0.0.0.0/0 represents all + IPv4 addresses, and ::0/0 represents + all IPv6 addresses. + To specify a single host, use a mask length of 32 for IPv4 or + 128 for IPv6. In a network address, do not omit trailing zeroes. + + + + An entry given in IPv4 format will match only IPv4 connections, + and an entry given in IPv6 format will match only IPv6 connections, + even if the represented address is in the IPv4-in-IPv6 range. + Note that entries in IPv6 format will be rejected if the system's + C library does not have support for IPv6 addresses. + + + + You can also write all to match any IP address, + samehost to match any of the server's own IP + addresses, or samenet to match any address in any + subnet that the server is directly connected to. + + + + If a host name is specified (anything that is not an IP address + range or a special key word is treated as a host name), + that name is compared with the result of a reverse name + resolution of the client's IP address (e.g., reverse DNS + lookup, if DNS is used). Host name comparisons are case + insensitive. If there is a match, then a forward name + resolution (e.g., forward DNS lookup) is performed on the host + name to check whether any of the addresses it resolves to are + equal to the client's IP address. If both directions match, + then the entry is considered to match. (The host name that is + used in pg_hba.conf should be the one that + address-to-name resolution of the client's IP address returns, + otherwise the line won't be matched. Some host name databases + allow associating an IP address with multiple host names, but + the operating system will only return one host name when asked + to resolve an IP address.) + + + + A host name specification that starts with a dot + (.) matches a suffix of the actual host + name. So .example.com would match + foo.example.com (but not just + example.com). + + + + When host names are specified + in pg_hba.conf, you should make sure that + name resolution is reasonably fast. It can be of advantage to + set up a local name resolution cache such + as nscd. Also, you may wish to enable the + configuration parameter log_hostname to see + the client's host name instead of the IP address in the log. + + + + These fields do not apply to local records. + + + + + Users sometimes wonder why host names are handled + in this seemingly complicated way, with two name resolutions + including a reverse lookup of the client's IP address. This + complicates use of the feature in case the client's reverse DNS + entry is not set up or yields some undesirable host name. + It is done primarily for efficiency: this way, a connection attempt + requires at most two resolver lookups, one reverse and one forward. + If there is a resolver problem with some address, it becomes only + that client's problem. A hypothetical alternative + implementation that only did forward lookups would have to + resolve every host name mentioned in + pg_hba.conf during every connection attempt. + That could be quite slow if many names are listed. + And if there is a resolver problem with one of the host names, + it becomes everyone's problem. + + + + Also, a reverse lookup is necessary to implement the suffix + matching feature, because the actual client host name needs to + be known in order to match it against the pattern. + + + + Note that this behavior is consistent with other popular + implementations of host name-based access control, such as the + Apache HTTP Server and TCP Wrappers. + + + + + + + IP-address + IP-mask + + + These two fields can be used as an alternative to the + IP-address/mask-length + notation. Instead of + specifying the mask length, the actual mask is specified in a + separate column. For example, 255.0.0.0 represents an IPv4 + CIDR mask length of 8, and 255.255.255.255 represents a + CIDR mask length of 32. + + + + These fields do not apply to local records. + + + + + + auth-method + + + Specifies the authentication method to use when a connection matches + this record. The possible choices are summarized here; details + are in . + + + + trust + + + Allow the connection unconditionally. This method + allows anyone that can connect to the + PostgreSQL database server to login as + any PostgreSQL user they wish, + without the need for a password or any other authentication. See for details. + + + + + + reject + + + Reject the connection unconditionally. This is useful for + filtering out certain hosts from a group, for example a + reject line could block a specific host from connecting, + while a later line allows the remaining hosts in a specific + network to connect. + + + + + + scram-sha-256 + + + Perform SCRAM-SHA-256 authentication to verify the user's + password. See for details. + + + + + + md5 + + + Perform SCRAM-SHA-256 or MD5 authentication to verify the + user's password. See + for details. + + + + + + password + + + Require the client to supply an unencrypted password for + authentication. + Since the password is sent in clear text over the + network, this should not be used on untrusted networks. + See for details. + + + + + + gss + + + Use GSSAPI to authenticate the user. This is only + available for TCP/IP connections. See for details. It can be used in conjunction + with GSSAPI encryption. + + + + + + sspi + + + Use SSPI to authenticate the user. This is only + available on Windows. See for details. + + + + + + ident + + + Obtain the operating system user name of the client + by contacting the ident server on the client + and check if it matches the requested database user name. + Ident authentication can only be used on TCP/IP + connections. When specified for local connections, peer + authentication will be used instead. + See for details. + + + + + + peer + + + Obtain the client's operating system user name from the operating + system and check if it matches the requested database user name. + This is only available for local connections. + See for details. + + + + + + ldap + + + Authenticate using an LDAP server. See for details. + + + + + + radius + + + Authenticate using a RADIUS server. See for details. + + + + + + cert + + + Authenticate using SSL client certificates. See + for details. + + + + + + pam + + + Authenticate using the Pluggable Authentication Modules + (PAM) service provided by the operating system. See for details. + + + + + + bsd + + + Authenticate using the BSD Authentication service provided by the + operating system. See for details. + + + + + + + + + + + auth-options + + + After the auth-method field, there can be field(s) of + the form name=value that + specify options for the authentication method. Details about which + options are available for which authentication methods appear below. + + + + In addition to the method-specific options listed below, there is a + method-independent authentication option clientcert, which + can be specified in any hostssl record. + This option can be set to verify-ca or + verify-full. Both options require the client + to present a valid (trusted) SSL certificate, while + verify-full additionally enforces that the + cn (Common Name) in the certificate matches + the username or an applicable mapping. + This behavior is similar to the cert authentication + method (see ) but enables pairing + the verification of client certificates with any authentication + method that supports hostssl entries. + + + On any record using client certificate authentication (i.e. one + using the cert authentication method or one + using the clientcert option), you can specify + which part of the client certificate credentials to match using + the clientname option. This option can have one + of two values. If you specify clientname=CN, which + is the default, the username is matched against the certificate's + Common Name (CN). If instead you specify + clientname=DN the username is matched against the + entire Distinguished Name (DN) of the certificate. + This option is probably best used in conjunction with a username map. + The comparison is done with the DN in + RFC 2253 + format. To see the DN of a client certificate + in this format, do + +openssl x509 -in myclient.crt -noout --subject -nameopt RFC2253 | sed "s/^subject=//" + + Care needs to be taken when using this option, especially when using + regular expression matching against the DN. + + + + + + + + Files included by @ constructs are read as lists of names, + which can be separated by either whitespace or commas. Comments are + introduced by #, just as in + pg_hba.conf, and nested @ constructs are + allowed. Unless the file name following @ is an absolute + path, it is taken to be relative to the directory containing the + referencing file. + + + + Since the pg_hba.conf records are examined + sequentially for each connection attempt, the order of the records is + significant. Typically, earlier records will have tight connection + match parameters and weaker authentication methods, while later + records will have looser match parameters and stronger authentication + methods. For example, one might wish to use trust + authentication for local TCP/IP connections but require a password for + remote TCP/IP connections. In this case a record specifying + trust authentication for connections from 127.0.0.1 would + appear before a record specifying password authentication for a wider + range of allowed client IP addresses. + + + + The pg_hba.conf file is read on start-up and when + the main server process receives a + SIGHUPSIGHUP + signal. If you edit the file on an + active system, you will need to signal the postmaster + (using pg_ctl reload, calling the SQL function + pg_reload_conf(), or using kill + -HUP) to make it re-read the file. + + + + + The preceding statement is not true on Microsoft Windows: there, any + changes in the pg_hba.conf file are immediately + applied by subsequent new connections. + + + + + The system view + pg_hba_file_rules + can be helpful for pre-testing changes to the pg_hba.conf + file, or for diagnosing problems if loading of the file did not have the + desired effects. Rows in the view with + non-null error fields indicate problems in the + corresponding lines of the file. + + + + + To connect to a particular database, a user must not only pass the + pg_hba.conf checks, but must have the + CONNECT privilege for the database. If you wish to + restrict which users can connect to which databases, it's usually + easier to control this by granting/revoking CONNECT privilege + than to put the rules in pg_hba.conf entries. + + + + + Some examples of pg_hba.conf entries are shown in + . See the next section for details on the + different authentication methods. + + + + Example <filename>pg_hba.conf</filename> Entries + +# Allow any user on the local system to connect to any database with +# any database user name using Unix-domain sockets (the default for local +# connections). +# +# TYPE DATABASE USER ADDRESS METHOD +local all all trust + +# The same using local loopback TCP/IP connections. +# +# TYPE DATABASE USER ADDRESS METHOD +host all all 127.0.0.1/32 trust + +# The same as the previous line, but using a separate netmask column +# +# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD +host all all 127.0.0.1 255.255.255.255 trust + +# The same over IPv6. +# +# TYPE DATABASE USER ADDRESS METHOD +host all all ::1/128 trust + +# The same using a host name (would typically cover both IPv4 and IPv6). +# +# TYPE DATABASE USER ADDRESS METHOD +host all all localhost trust + +# Allow any user from any host with IP address 192.168.93.x to connect +# to database "postgres" as the same user name that ident reports for +# the connection (typically the operating system user name). +# +# TYPE DATABASE USER ADDRESS METHOD +host postgres all 192.168.93.0/24 ident + +# Allow any user from host 192.168.12.10 to connect to database +# "postgres" if the user's password is correctly supplied. +# +# TYPE DATABASE USER ADDRESS METHOD +host postgres all 192.168.12.10/32 scram-sha-256 + +# Allow any user from hosts in the example.com domain to connect to +# any database if the user's password is correctly supplied. +# +# Require SCRAM authentication for most users, but make an exception +# for user 'mike', who uses an older client that doesn't support SCRAM +# authentication. +# +# TYPE DATABASE USER ADDRESS METHOD +host all mike .example.com md5 +host all all .example.com scram-sha-256 + +# In the absence of preceding "host" lines, these three lines will +# reject all connections from 192.168.54.1 (since that entry will be +# matched first), but allow GSSAPI-encrypted connections from anywhere else +# on the Internet. The zero mask causes no bits of the host IP address to +# be considered, so it matches any host. Unencrypted GSSAPI connections +# (which "fall through" to the third line since "hostgssenc" only matches +# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10. +# +# TYPE DATABASE USER ADDRESS METHOD +host all all 192.168.54.1/32 reject +hostgssenc all all 0.0.0.0/0 gss +host all all 192.168.12.10/32 gss + +# Allow users from 192.168.x.x hosts to connect to any database, if +# they pass the ident check. If, for example, ident says the user is +# "bryanh" and he requests to connect as PostgreSQL user "guest1", the +# connection is allowed if there is an entry in pg_ident.conf for map +# "omicron" that says "bryanh" is allowed to connect as "guest1". +# +# TYPE DATABASE USER ADDRESS METHOD +host all all 192.168.0.0/16 ident map=omicron + +# If these are the only three lines for local connections, they will +# allow local users to connect only to their own databases (databases +# with the same name as their database user name) except for administrators +# and members of role "support", who can connect to all databases. The file +# $PGDATA/admins contains a list of names of administrators. Passwords +# are required in all cases. +# +# TYPE DATABASE USER ADDRESS METHOD +local sameuser all md5 +local all @admins md5 +local all +support md5 + +# The last two lines above can be combined into a single line: +local all @admins,+support md5 + +# The database column can also use lists and file names: +local db1,db2,@demodbs all md5 + + + + + + User Name Maps + + + User name maps + + + + When using an external authentication system such as Ident or GSSAPI, + the name of the operating system user that initiated the connection + might not be the same as the database user (role) that is to be used. + In this case, a user name map can be applied to map the operating system + user name to a database user. To use user name mapping, specify + map=map-name + in the options field in pg_hba.conf. This option is + supported for all authentication methods that receive external user names. + Since different mappings might be needed for different connections, + the name of the map to be used is specified in the + map-name parameter in pg_hba.conf + to indicate which map to use for each individual connection. + + + + User name maps are defined in the ident map file, which by default is named + pg_ident.confpg_ident.conf + and is stored in the + cluster's data directory. (It is possible to place the map file + elsewhere, however; see the + configuration parameter.) + The ident map file contains lines of the general form: + +map-name system-username database-username + + Comments, whitespace and line continuations are handled in the same way as in + pg_hba.conf. The + map-name is an arbitrary name that will be used to + refer to this mapping in pg_hba.conf. The other + two fields specify an operating system user name and a matching + database user name. The same map-name can be + used repeatedly to specify multiple user-mappings within a single map. + + + There is no restriction regarding how many database users a given + operating system user can correspond to, nor vice versa. Thus, entries + in a map should be thought of as meaning this operating system + user is allowed to connect as this database user, rather than + implying that they are equivalent. The connection will be allowed if + there is any map entry that pairs the user name obtained from the + external authentication system with the database user name that the + user has requested to connect as. + + + If the system-username field starts with a slash (/), + the remainder of the field is treated as a regular expression. + (See for details of + PostgreSQL's regular expression syntax.) The regular + expression can include a single capture, or parenthesized subexpression, + which can then be referenced in the database-username + field as \1 (backslash-one). This allows the mapping of + multiple user names in a single line, which is particularly useful for + simple syntax substitutions. For example, these entries + +mymap /^(.*)@mydomain\.com$ \1 +mymap /^(.*)@otherdomain\.com$ guest + + will remove the domain part for users with system user names that end with + @mydomain.com, and allow any user whose system name ends with + @otherdomain.com to log in as guest. + + + + + Keep in mind that by default, a regular expression can match just part of + a string. It's usually wise to use ^ and $, as + shown in the above example, to force the match to be to the entire + system user name. + + + + + The pg_ident.conf file is read on start-up and + when the main server process receives a + SIGHUPSIGHUP + signal. If you edit the file on an + active system, you will need to signal the postmaster + (using pg_ctl reload, calling the SQL function + pg_reload_conf(), or using kill + -HUP) to make it re-read the file. + + + + A pg_ident.conf file that could be used in + conjunction with the pg_hba.conf file in is shown in . In this example, anyone + logged in to a machine on the 192.168 network that does not have the + operating system user name bryanh, ann, or + robert would not be granted access. Unix user + robert would only be allowed access when he tries to + connect as PostgreSQL user bob, not + as robert or anyone else. ann would + only be allowed to connect as ann. User + bryanh would be allowed to connect as either + bryanh or as guest1. + + + + An Example <filename>pg_ident.conf</filename> File + +# MAPNAME SYSTEM-USERNAME PG-USERNAME + +omicron bryanh bryanh +omicron ann ann +# bob has user name robert on these machines +omicron robert bob +# bryanh can also connect as guest1 +omicron bryanh guest1 + + + + + + Authentication Methods + + + PostgreSQL provides various methods for + authenticating users: + + + + + Trust authentication, which + simply trusts that users are who they say they are. + + + + + Password authentication, which + requires that users send a password. + + + + + GSSAPI authentication, which + relies on a GSSAPI-compatible security library. Typically this is + used to access an authentication server such as a Kerberos or + Microsoft Active Directory server. + + + + + SSPI authentication, which + uses a Windows-specific protocol similar to GSSAPI. + + + + + Ident authentication, which + relies on an Identification Protocol + (RFC 1413) + service on the client's machine. (On local Unix-socket connections, + this is treated as peer authentication.) + + + + + Peer authentication, which + relies on operating system facilities to identify the process at the + other end of a local connection. This is not supported for remote + connections. + + + + + LDAP authentication, which + relies on an LDAP authentication server. + + + + + RADIUS authentication, which + relies on a RADIUS authentication server. + + + + + Certificate authentication, which + requires an SSL connection and authenticates users by checking the + SSL certificate they send. + + + + + PAM authentication, which + relies on a PAM (Pluggable Authentication Modules) library. + + + + + BSD authentication, which + relies on the BSD Authentication framework (currently available + only on OpenBSD). + + + + + + + Peer authentication is usually recommendable for local connections, + though trust authentication might be sufficient in some circumstances. + Password authentication is the easiest choice for remote connections. + All the other options require some kind of external security + infrastructure (usually an authentication server or a certificate + authority for issuing SSL certificates), or are platform-specific. + + + + The following sections describe each of these authentication methods + in more detail. + + + + + Trust Authentication + + + When trust authentication is specified, + PostgreSQL assumes that anyone who can + connect to the server is authorized to access the database with + whatever database user name they specify (even superuser names). + Of course, restrictions made in the database and + user columns still apply. + This method should only be used when there is adequate + operating-system-level protection on connections to the server. + + + + trust authentication is appropriate and very + convenient for local connections on a single-user workstation. It + is usually not appropriate by itself on a multiuser + machine. However, you might be able to use trust even + on a multiuser machine, if you restrict access to the server's + Unix-domain socket file using file-system permissions. To do this, set the + unix_socket_permissions (and possibly + unix_socket_group) configuration parameters as + described in . Or you + could set the unix_socket_directories + configuration parameter to place the socket file in a suitably + restricted directory. + + + + Setting file-system permissions only helps for Unix-socket connections. + Local TCP/IP connections are not restricted by file-system permissions. + Therefore, if you want to use file-system permissions for local security, + remove the host ... 127.0.0.1 ... line from + pg_hba.conf, or change it to a + non-trust authentication method. + + + + trust authentication is only suitable for TCP/IP connections + if you trust every user on every machine that is allowed to connect + to the server by the pg_hba.conf lines that specify + trust. It is seldom reasonable to use trust + for any TCP/IP connections other than those from localhost (127.0.0.1). + + + + + + Password Authentication + + + MD5 + + + SCRAM + + + password + authentication + + + + There are several password-based authentication methods. These methods + operate similarly but differ in how the users' passwords are stored on the + server and how the password provided by a client is sent across the + connection. + + + + + scram-sha-256 + + + The method scram-sha-256 performs SCRAM-SHA-256 + authentication, as described in + RFC 7677. It + is a challenge-response scheme that prevents password sniffing on + untrusted connections and supports storing passwords on the server in a + cryptographically hashed form that is thought to be secure. + + + + This is the most secure of the currently provided methods, but it is + not supported by older client libraries. + + + + + + md5 + + + The method md5 uses a custom less secure challenge-response + mechanism. It prevents password sniffing and avoids storing passwords + on the server in plain text but provides no protection if an attacker + manages to steal the password hash from the server. Also, the MD5 hash + algorithm is nowadays no longer considered secure against determined + attacks. + + + + The md5 method cannot be used with + the feature. + + + + To ease transition from the md5 method to the newer + SCRAM method, if md5 is specified as a method + in pg_hba.conf but the user's password on the + server is encrypted for SCRAM (see below), then SCRAM-based + authentication will automatically be chosen instead. + + + + + + password + + + The method password sends the password in clear-text and is + therefore vulnerable to password sniffing attacks. It should + always be avoided if possible. If the connection is protected by SSL + encryption then password can be used safely, though. + (Though SSL certificate authentication might be a better choice if one + is depending on using SSL). + + + + + + + PostgreSQL database passwords are + separate from operating system user passwords. The password for + each database user is stored in the pg_authid system + catalog. Passwords can be managed with the SQL commands + and + , + e.g., CREATE ROLE foo WITH LOGIN PASSWORD 'secret', + or the psql + command \password. + If no password has been set up for a user, the stored password + is null and password authentication will always fail for that user. + + + + The availability of the different password-based authentication methods + depends on how a user's password on the server is encrypted (or hashed, + more accurately). This is controlled by the configuration + parameter at the time the + password is set. If a password was encrypted using + the scram-sha-256 setting, then it can be used for the + authentication methods scram-sha-256 + and password (but password transmission will be in + plain text in the latter case). The authentication method + specification md5 will automatically switch to using + the scram-sha-256 method in this case, as explained + above, so it will also work. If a password was encrypted using + the md5 setting, then it can be used only for + the md5 and password authentication + method specifications (again, with the password transmitted in plain text + in the latter case). (Previous PostgreSQL releases supported storing the + password on the server in plain text. This is no longer possible.) To + check the currently stored password hashes, see the system + catalog pg_authid. + + + + To upgrade an existing installation from md5 + to scram-sha-256, after having ensured that all client + libraries in use are new enough to support SCRAM, + set password_encryption = 'scram-sha-256' + in postgresql.conf, make all users set new passwords, + and change the authentication method specifications + in pg_hba.conf to scram-sha-256. + + + + + GSSAPI Authentication + + + GSSAPI + + + + GSSAPI is an industry-standard protocol + for secure authentication defined in + RFC 2743. + PostgreSQL + supports GSSAPI for authentication, + communications encryption, or both. + GSSAPI provides automatic authentication + (single sign-on) for systems that support it. The authentication itself is + secure. If GSSAPI encryption + or SSL encryption is + used, the data sent along the database connection will be encrypted; + otherwise, it will not. + + + + GSSAPI support has to be enabled when PostgreSQL is built; + see for more information. + + + + When GSSAPI uses + Kerberos, it uses a standard service + principal (authentication identity) name in the format + servicename/hostname@realm. + The principal name used by a particular installation is not encoded in + the PostgreSQL server in any way; rather it + is specified in the keytab file that the server + reads to determine its identity. If multiple principals are listed in + the keytab file, the server will accept any one of them. + The server's realm name is the preferred realm specified in the Kerberos + configuration file(s) accessible to the server. + + + + When connecting, the client must know the principal name of the server + it intends to connect to. The servicename + part of the principal is ordinarily postgres, + but another value can be selected via libpq's + connection parameter. + The hostname part is the fully qualified + host name that libpq is told to connect to. + The realm name is the preferred realm specified in the Kerberos + configuration file(s) accessible to the client. + + + + The client will also have a principal name for its own identity + (and it must have a valid ticket for this principal). To + use GSSAPI for authentication, the client + principal must be associated with + a PostgreSQL database user name. + The pg_ident.conf configuration file can be used + to map principals to user names; for example, + pgusername@realm could be mapped to just pgusername. + Alternatively, you can use the full username@realm principal as + the role name in PostgreSQL without any mapping. + + + + PostgreSQL also supports mapping + client principals to user names by just stripping the realm from + the principal. This method is supported for backwards compatibility and is + strongly discouraged as it is then impossible to distinguish different users + with the same user name but coming from different realms. To enable this, + set include_realm to 0. For simple single-realm + installations, doing that combined with setting the + krb_realm parameter (which checks that the principal's realm + matches exactly what is in the krb_realm parameter) + is still secure; but this is a + less capable approach compared to specifying an explicit mapping in + pg_ident.conf. + + + + The location of the server's keytab file is specified by the configuration parameter. + For security reasons, it is recommended to use a separate keytab + just for the PostgreSQL server rather + than allowing the server to read the system keytab file. + Make sure that your server keytab file is readable (and preferably + only readable, not writable) by the PostgreSQL + server account. (See also .) + + + + The keytab file is generated using the Kerberos software; see the + Kerberos documentation for details. The following example shows + doing this using the kadmin tool of + MIT-compatible Kerberos 5 implementations: + +kadmin% addprinc -randkey postgres/server.my.domain.org +kadmin% ktadd -k krb5.keytab postgres/server.my.domain.org + + + + + The following authentication options are supported for + the GSSAPI authentication method: + + + include_realm + + + If set to 0, the realm name from the authenticated user principal is + stripped off before being passed through the user name mapping + (). This is discouraged and is + primarily available for backwards compatibility, as it is not secure + in multi-realm environments unless krb_realm is + also used. It is recommended to + leave include_realm set to the default (1) and to + provide an explicit mapping in pg_ident.conf to convert + principal names to PostgreSQL user names. + + + + + + map + + + Allows mapping from client principals to database user names. See + for details. For a GSSAPI/Kerberos + principal, such as username@EXAMPLE.COM (or, less + commonly, username/hostbased@EXAMPLE.COM), the + user name used for mapping is + username@EXAMPLE.COM (or + username/hostbased@EXAMPLE.COM, respectively), + unless include_realm has been set to 0, in which case + username (or username/hostbased) + is what is seen as the system user name when mapping. + + + + + + krb_realm + + + Sets the realm to match user principal names against. If this parameter + is set, only users of that realm will be accepted. If it is not set, + users of any realm can connect, subject to whatever user name mapping + is done. + + + + + + + + In addition to these settings, which can be different for + different pg_hba.conf entries, there is the + server-wide configuration + parameter. If that is set to true, client principals are matched to + user map entries case-insensitively. krb_realm, if + set, is also matched case-insensitively. + + + + + SSPI Authentication + + + SSPI + + + + SSPI is a Windows + technology for secure authentication with single sign-on. + PostgreSQL will use SSPI in + negotiate mode, which will use + Kerberos when possible and automatically + fall back to NTLM in other cases. + SSPI authentication only works when both + server and client are running Windows, + or, on non-Windows platforms, when GSSAPI + is available. + + + + When using Kerberos authentication, + SSPI works the same way + GSSAPI does; see + for details. + + + + The following configuration options are supported for SSPI: + + + + include_realm + + + If set to 0, the realm name from the authenticated user principal is + stripped off before being passed through the user name mapping + (). This is discouraged and is + primarily available for backwards compatibility, as it is not secure + in multi-realm environments unless krb_realm is + also used. It is recommended to + leave include_realm set to the default (1) and to + provide an explicit mapping in pg_ident.conf to convert + principal names to PostgreSQL user names. + + + + + + compat_realm + + + If set to 1, the domain's SAM-compatible name (also known as the + NetBIOS name) is used for the include_realm + option. This is the default. If set to 0, the true realm name from + the Kerberos user principal name is used. + + + Do not disable this option unless your server runs under a domain + account (this includes virtual service accounts on a domain member + system) and all clients authenticating through SSPI are also using + domain accounts, or authentication will fail. + + + + + + upn_username + + + If this option is enabled along with compat_realm, + the user name from the Kerberos UPN is used for authentication. If + it is disabled (the default), the SAM-compatible user name is used. + By default, these two names are identical for new user accounts. + + + Note that libpq uses the SAM-compatible name if no + explicit user name is specified. If you use + libpq or a driver based on it, you should + leave this option disabled or explicitly specify user name in the + connection string. + + + + + + map + + + Allows for mapping between system and database user names. See + for details. For an SSPI/Kerberos + principal, such as username@EXAMPLE.COM (or, less + commonly, username/hostbased@EXAMPLE.COM), the + user name used for mapping is + username@EXAMPLE.COM (or + username/hostbased@EXAMPLE.COM, respectively), + unless include_realm has been set to 0, in which case + username (or username/hostbased) + is what is seen as the system user name when mapping. + + + + + + krb_realm + + + Sets the realm to match user principal names against. If this parameter + is set, only users of that realm will be accepted. If it is not set, + users of any realm can connect, subject to whatever user name mapping + is done. + + + + + + + + + Ident Authentication + + + ident + + + + The ident authentication method works by obtaining the client's + operating system user name from an ident server and using it as + the allowed database user name (with an optional user name mapping). + This is only supported on TCP/IP connections. + + + + + When ident is specified for a local (non-TCP/IP) connection, + peer authentication (see ) will be + used instead. + + + + + The following configuration options are supported for ident: + + + map + + + Allows for mapping between system and database user names. See + for details. + + + + + + + + The Identification Protocol is described in + RFC 1413. + Virtually every Unix-like + operating system ships with an ident server that listens on TCP + port 113 by default. The basic functionality of an ident server + is to answer questions like What user initiated the + connection that goes out of your port X + and connects to my port Y?. + Since PostgreSQL knows both X and + Y when a physical connection is established, it + can interrogate the ident server on the host of the connecting + client and can theoretically determine the operating system user + for any given connection. + + + + The drawback of this procedure is that it depends on the integrity + of the client: if the client machine is untrusted or compromised, + an attacker could run just about any program on port 113 and + return any user name they choose. This authentication method is + therefore only appropriate for closed networks where each client + machine is under tight control and where the database and system + administrators operate in close contact. In other words, you must + trust the machine running the ident server. + Heed the warning: +
+ RFC 1413 + + The Identification Protocol is not intended as an authorization + or access control protocol. + +
+
+ + + Some ident servers have a nonstandard option that causes the returned + user name to be encrypted, using a key that only the originating + machine's administrator knows. This option must not be + used when using the ident server with PostgreSQL, + since PostgreSQL does not have any way to decrypt the + returned string to determine the actual user name. + +
+ + + Peer Authentication + + + peer + + + + The peer authentication method works by obtaining the client's + operating system user name from the kernel and using it as the + allowed database user name (with optional user name mapping). This + method is only supported on local connections. + + + + The following configuration options are supported for peer: + + + map + + + Allows for mapping between system and database user names. See + for details. + + + + + + + + Peer authentication is only available on operating systems providing + the getpeereid() function, the SO_PEERCRED + socket parameter, or similar mechanisms. Currently that includes + Linux, + most flavors of BSD including + macOS, + and Solaris. + + + + + + LDAP Authentication + + + LDAP + + + + This authentication method operates similarly to + password except that it uses LDAP + as the password verification method. LDAP is used only to validate + the user name/password pairs. Therefore the user must already + exist in the database before LDAP can be used for + authentication. + + + + LDAP authentication can operate in two modes. In the first mode, + which we will call the simple bind mode, + the server will bind to the distinguished name constructed as + prefix username suffix. + Typically, the prefix parameter is used to specify + cn=, or DOMAIN\ in an Active + Directory environment. suffix is used to specify the + remaining part of the DN in a non-Active Directory environment. + + + + In the second mode, which we will call the search+bind mode, + the server first binds to the LDAP directory with + a fixed user name and password, specified with ldapbinddn + and ldapbindpasswd, and performs a search for the user trying + to log in to the database. If no user and password is configured, an + anonymous bind will be attempted to the directory. The search will be + performed over the subtree at ldapbasedn, and will try to + do an exact match of the attribute specified in + ldapsearchattribute. + Once the user has been found in + this search, the server disconnects and re-binds to the directory as + this user, using the password specified by the client, to verify that the + login is correct. This mode is the same as that used by LDAP authentication + schemes in other software, such as Apache mod_authnz_ldap and pam_ldap. + This method allows for significantly more flexibility + in where the user objects are located in the directory, but will cause + two separate connections to the LDAP server to be made. + + + + The following configuration options are used in both modes: + + + ldapserver + + + Names or IP addresses of LDAP servers to connect to. Multiple + servers may be specified, separated by spaces. + + + + + ldapport + + + Port number on LDAP server to connect to. If no port is specified, + the LDAP library's default port setting will be used. + + + + + ldapscheme + + + Set to ldaps to use LDAPS. This is a non-standard + way of using LDAP over SSL, supported by some LDAP server + implementations. See also the ldaptls option for + an alternative. + + + + + ldaptls + + + Set to 1 to make the connection between PostgreSQL and the LDAP server + use TLS encryption. This uses the StartTLS + operation per RFC 4513. + See also the ldapscheme option for an alternative. + + + + + + + + Note that using ldapscheme or + ldaptls only encrypts the traffic between the + PostgreSQL server and the LDAP server. The connection between the + PostgreSQL server and the PostgreSQL client will still be unencrypted + unless SSL is used there as well. + + + + The following options are used in simple bind mode only: + + + ldapprefix + + + String to prepend to the user name when forming the DN to bind as, + when doing simple bind authentication. + + + + + ldapsuffix + + + String to append to the user name when forming the DN to bind as, + when doing simple bind authentication. + + + + + + + + The following options are used in search+bind mode only: + + + ldapbasedn + + + Root DN to begin the search for the user in, when doing search+bind + authentication. + + + + + ldapbinddn + + + DN of user to bind to the directory with to perform the search when + doing search+bind authentication. + + + + + ldapbindpasswd + + + Password for user to bind to the directory with to perform the search + when doing search+bind authentication. + + + + + ldapsearchattribute + + + Attribute to match against the user name in the search when doing + search+bind authentication. If no attribute is specified, the + uid attribute will be used. + + + + + ldapsearchfilter + + + The search filter to use when doing search+bind authentication. + Occurrences of $username will be replaced with the + user name. This allows for more flexible search filters than + ldapsearchattribute. + + + + + ldapurl + + + An RFC 4516 + LDAP URL. This is an alternative way to write some of the + other LDAP options in a more compact and standard form. The format is + +ldap[s]://host[:port]/basedn[?[attribute][?[scope][?[filter]]]] + + scope must be one + of base, one, sub, + typically the last. (The default is base, which + is normally not useful in this application.) attribute can + nominate a single attribute, in which case it is used as a value for + ldapsearchattribute. If + attribute is empty then + filter can be used as a value for + ldapsearchfilter. + + + + The URL scheme ldaps chooses the LDAPS method for + making LDAP connections over SSL, equivalent to using + ldapscheme=ldaps. To use encrypted LDAP + connections using the StartTLS operation, use the + normal URL scheme ldap and specify the + ldaptls option in addition to + ldapurl. + + + + For non-anonymous binds, ldapbinddn + and ldapbindpasswd must be specified as separate + options. + + + + LDAP URLs are currently only supported with + OpenLDAP, not on Windows. + + + + + + + + It is an error to mix configuration options for simple bind with options + for search+bind. + + + + When using search+bind mode, the search can be performed using a single + attribute specified with ldapsearchattribute, or using + a custom search filter specified with + ldapsearchfilter. + Specifying ldapsearchattribute=foo is equivalent to + specifying ldapsearchfilter="(foo=$username)". If neither + option is specified the default is + ldapsearchattribute=uid. + + + + If PostgreSQL was compiled with + OpenLDAP as the LDAP client library, the + ldapserver setting may be omitted. In that case, a + list of host names and ports is looked up via + RFC 2782 DNS SRV records. + The name _ldap._tcp.DOMAIN is looked up, where + DOMAIN is extracted from ldapbasedn. + + + + Here is an example for a simple-bind LDAP configuration: + +host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net" + + When a connection to the database server as database + user someuser is requested, PostgreSQL will attempt to + bind to the LDAP server using the DN cn=someuser, dc=example, + dc=net and the password provided by the client. If that connection + succeeds, the database access is granted. + + + + Here is an example for a search+bind configuration: + +host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid + + When a connection to the database server as database + user someuser is requested, PostgreSQL will attempt to + bind anonymously (since ldapbinddn was not specified) to + the LDAP server, perform a search for (uid=someuser) + under the specified base DN. If an entry is found, it will then attempt to + bind using that found information and the password supplied by the client. + If that second connection succeeds, the database access is granted. + + + + Here is the same search+bind configuration written as a URL: + +host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub" + + Some other software that supports authentication against LDAP uses the + same URL format, so it will be easier to share the configuration. + + + + Here is an example for a search+bind configuration that uses + ldapsearchfilter instead of + ldapsearchattribute to allow authentication by + user ID or email address: + +host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))" + + + + + Here is an example for a search+bind configuration that uses DNS SRV + discovery to find the host name(s) and port(s) for the LDAP service for the + domain name example.net: + +host ... ldap ldapbasedn="dc=example,dc=net" + + + + + + Since LDAP often uses commas and spaces to separate the different + parts of a DN, it is often necessary to use double-quoted parameter + values when configuring LDAP options, as shown in the examples. + + + + + + + RADIUS Authentication + + + RADIUS + + + + This authentication method operates similarly to + password except that it uses RADIUS + as the password verification method. RADIUS is used only to validate + the user name/password pairs. Therefore the user must already + exist in the database before RADIUS can be used for + authentication. + + + + When using RADIUS authentication, an Access Request message will be sent + to the configured RADIUS server. This request will be of type + Authenticate Only, and include parameters for + user name, password (encrypted) and + NAS Identifier. The request will be encrypted using + a secret shared with the server. The RADIUS server will respond to + this request with either Access Accept or + Access Reject. There is no support for RADIUS accounting. + + + + Multiple RADIUS servers can be specified, in which case they will + be tried sequentially. If a negative response is received from + a server, the authentication will fail. If no response is received, + the next server in the list will be tried. To specify multiple + servers, separate the server names with commas and surround the list + with double quotes. If multiple servers are specified, the other + RADIUS options can also be given as comma-separated lists, to provide + individual values for each server. They can also be specified as + a single value, in which case that value will apply to all servers. + + + + The following configuration options are supported for RADIUS: + + + radiusservers + + + The DNS names or IP addresses of the RADIUS servers to connect to. + This parameter is required. + + + + + + radiussecrets + + + The shared secrets used when talking securely to the RADIUS + servers. This must have exactly the same value on the PostgreSQL + and RADIUS servers. It is recommended that this be a string of + at least 16 characters. This parameter is required. + + + The encryption vector used will only be cryptographically + strong if PostgreSQL is built with support for + OpenSSL. In other cases, the transmission to the + RADIUS server should only be considered obfuscated, not secured, and + external security measures should be applied if necessary. + + + + + + + + radiusports + + + The port numbers to connect to on the RADIUS servers. If no port + is specified, the default RADIUS port (1812) + will be used. + + + + + + radiusidentifiers + + + The strings to be used as NAS Identifier in the + RADIUS requests. This parameter can be used, for example, to + identify which database cluster the user is attempting to connect + to, which can be useful for policy matching on + the RADIUS server. If no identifier is specified, the default + postgresql will be used. + + + + + + + + + If it is necessary to have a comma or whitespace in a RADIUS parameter + value, that can be done by putting double quotes around the value, but + it is tedious because two layers of double-quoting are now required. + An example of putting whitespace into RADIUS secret strings is: + +host ... radius radiusservers="server1,server2" radiussecrets="""secret one"",""secret two""" + + + + + + Certificate Authentication + + + Certificate + + + + This authentication method uses SSL client certificates to perform + authentication. It is therefore only available for SSL connections. + When using this authentication method, the server will require that + the client provide a valid, trusted certificate. No password prompt + will be sent to the client. The cn (Common Name) + attribute of the certificate + will be compared to the requested database user name, and if they match + the login will be allowed. User name mapping can be used to allow + cn to be different from the database user name. + + + + The following configuration options are supported for SSL certificate + authentication: + + + map + + + Allows for mapping between system and database user names. See + for details. + + + + + + + + It is redundant to use the clientcert option with + cert authentication because cert + authentication is effectively trust authentication + with clientcert=verify-full. + + + + + PAM Authentication + + + PAM + + + + This authentication method operates similarly to + password except that it uses PAM (Pluggable + Authentication Modules) as the authentication mechanism. The + default PAM service name is postgresql. + PAM is used only to validate user name/password pairs and optionally the + connected remote host name or IP address. Therefore the user must already + exist in the database before PAM can be used for authentication. For more + information about PAM, please read the + + Linux-PAM Page. + + + + The following configuration options are supported for PAM: + + + pamservice + + + PAM service name. + + + + + pam_use_hostname + + + Determines whether the remote IP address or the host name is provided + to PAM modules through the PAM_RHOST item. By + default, the IP address is used. Set this option to 1 to use the + resolved host name instead. Host name resolution can lead to login + delays. (Most PAM configurations don't use this information, so it is + only necessary to consider this setting if a PAM configuration was + specifically created to make use of it.) + + + + + + + + + If PAM is set up to read /etc/shadow, authentication + will fail because the PostgreSQL server is started by a non-root + user. However, this is not an issue when PAM is configured to use + LDAP or other authentication methods. + + + + + + BSD Authentication + + + BSD Authentication + + + + This authentication method operates similarly to + password except that it uses BSD Authentication + to verify the password. BSD Authentication is used only + to validate user name/password pairs. Therefore the user's role must + already exist in the database before BSD Authentication can be used + for authentication. The BSD Authentication framework is currently + only available on OpenBSD. + + + + BSD Authentication in PostgreSQL uses + the auth-postgresql login type and authenticates with + the postgresql login class if that's defined + in login.conf. By default that login class does not + exist, and PostgreSQL will use the default login class. + + + + + To use BSD Authentication, the PostgreSQL user account (that is, the + operating system user running the server) must first be added to + the auth group. The auth group + exists by default on OpenBSD systems. + + + + + + Authentication Problems + + + Authentication failures and related problems generally + manifest themselves through error messages like the following: + + + + +FATAL: no pg_hba.conf entry for host "123.123.123.123", user "andym", database "testdb" + + This is what you are most likely to get if you succeed in contacting + the server, but it does not want to talk to you. As the message + suggests, the server refused the connection request because it found + no matching entry in its pg_hba.conf + configuration file. + + + + +FATAL: password authentication failed for user "andym" + + Messages like this indicate that you contacted the server, and it is + willing to talk to you, but not until you pass the authorization + method specified in the pg_hba.conf file. Check + the password you are providing, or check your Kerberos or ident + software if the complaint mentions one of those authentication + types. + + + + +FATAL: user "andym" does not exist + + The indicated database user name was not found. + + + + +FATAL: database "testdb" does not exist + + The database you are trying to connect to does not exist. Note that + if you do not specify a database name, it defaults to the database + user name, which might or might not be the right thing. + + + + + The server log might contain more information about an + authentication failure than is reported to the client. If you are + confused about the reason for a failure, check the server log. + + + + +
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml new file mode 100644 index 000000000000..3eee9883595f --- /dev/null +++ b/doc/src/sgml/config.sgml @@ -0,0 +1,11028 @@ + + + + Server Configuration + + + configuration + of the server + + + + There are many configuration parameters that affect the behavior of + the database system. In the first section of this chapter we + describe how to interact with configuration parameters. The subsequent sections + discuss each parameter in detail. + + + + Setting Parameters + + + Parameter Names and Values + + + All parameter names are case-insensitive. Every parameter takes a + value of one of five types: boolean, string, integer, floating point, + or enumerated (enum). The type determines the syntax for setting the + parameter: + + + + + + Boolean: + Values can be written as + on, + off, + true, + false, + yes, + no, + 1, + 0 + (all case-insensitive) or any unambiguous prefix of one of these. + + + + + + String: + In general, enclose the value in single quotes, doubling any single + quotes within the value. Quotes can usually be omitted if the value + is a simple number or identifier, however. + (Values that match an SQL keyword require quoting in some contexts.) + + + + + + Numeric (integer and floating point): + Numeric parameters can be specified in the customary integer and + floating-point formats; fractional values are rounded to the nearest + integer if the parameter is of integer type. Integer parameters + additionally accept hexadecimal input (beginning + with 0x) and octal input (beginning + with 0), but these formats cannot have a fraction. + Do not use thousands separators. + Quotes are not required, except for hexadecimal input. + + + + + + Numeric with Unit: + Some numeric parameters have an implicit unit, because they describe + quantities of memory or time. The unit might be bytes, kilobytes, blocks + (typically eight kilobytes), milliseconds, seconds, or minutes. + An unadorned numeric value for one of these settings will use the + setting's default unit, which can be learned from + pg_settings.unit. + For convenience, settings can be given with a unit specified explicitly, + for example '120 ms' for a time value, and they will be + converted to whatever the parameter's actual unit is. Note that the + value must be written as a string (with quotes) to use this feature. + The unit name is case-sensitive, and there can be whitespace between + the numeric value and the unit. + + + + + Valid memory units are B (bytes), + kB (kilobytes), + MB (megabytes), GB + (gigabytes), and TB (terabytes). + The multiplier for memory units is 1024, not 1000. + + + + + + Valid time units are + us (microseconds), + ms (milliseconds), + s (seconds), min (minutes), + h (hours), and d (days). + + + + + If a fractional value is specified with a unit, it will be rounded + to a multiple of the next smaller unit if there is one. + For example, 30.1 GB will be converted + to 30822 MB not 32319628902 B. + If the parameter is of integer type, a final rounding to integer + occurs after any unit conversion. + + + + + + Enumerated: + Enumerated-type parameters are written in the same way as string + parameters, but are restricted to have one of a limited set of + values. The values allowable for such a parameter can be found from + pg_settings.enumvals. + Enum parameter values are case-insensitive. + + + + + + + Parameter Interaction via the Configuration File + + + The most fundamental way to set these parameters is to edit the file + postgresql.confpostgresql.conf, + which is normally kept in the data directory. A default copy is + installed when the database cluster directory is initialized. + An example of what this file might look like is: + +# This is a comment +log_connections = yes +log_destination = 'syslog' +search_path = '"$user", public' +shared_buffers = 128MB + + One parameter is specified per line. The equal sign between name and + value is optional. Whitespace is insignificant (except within a quoted + parameter value) and blank lines are + ignored. Hash marks (#) designate the remainder + of the line as a comment. Parameter values that are not simple + identifiers or numbers must be single-quoted. To embed a single + quote in a parameter value, write either two quotes (preferred) + or backslash-quote. + If the file contains multiple entries for the same parameter, + all but the last one are ignored. + + + + Parameters set in this way provide default values for the cluster. + The settings seen by active sessions will be these values unless they + are overridden. The following sections describe ways in which the + administrator or user can override these defaults. + + + + + SIGHUP + + The configuration file is reread whenever the main server process + receives a SIGHUP signal; this signal is most easily + sent by running pg_ctl reload from the command line or by + calling the SQL function pg_reload_conf(). The main + server process also propagates this signal to all currently running + server processes, so that existing sessions also adopt the new values + (this will happen after they complete any currently-executing client + command). Alternatively, you can + send the signal to a single server process directly. Some parameters + can only be set at server start; any changes to their entries in the + configuration file will be ignored until the server is restarted. + Invalid parameter settings in the configuration file are likewise + ignored (but logged) during SIGHUP processing. + + + + In addition to postgresql.conf, + a PostgreSQL data directory contains a file + postgresql.auto.confpostgresql.auto.conf, + which has the same format as postgresql.conf but + is intended to be edited automatically, not manually. This file holds + settings provided through the ALTER SYSTEM command. + This file is read whenever postgresql.conf is, + and its settings take effect in the same way. Settings + in postgresql.auto.conf override those + in postgresql.conf. + + + + External tools may also + modify postgresql.auto.conf. It is not + recommended to do this while the server is running, since a + concurrent ALTER SYSTEM command could overwrite + such changes. Such tools might simply append new settings to the end, + or they might choose to remove duplicate settings and/or comments + (as ALTER SYSTEM will). + + + + The system view + pg_file_settings + can be helpful for pre-testing changes to the configuration files, or for + diagnosing problems if a SIGHUP signal did not have the + desired effects. + + + + + Parameter Interaction via SQL + + + PostgreSQL provides three SQL + commands to establish configuration defaults. + The already-mentioned ALTER SYSTEM command + provides an SQL-accessible means of changing global defaults; it is + functionally equivalent to editing postgresql.conf. + In addition, there are two commands that allow setting of defaults + on a per-database or per-role basis: + + + + + + The ALTER DATABASE command allows global + settings to be overridden on a per-database basis. + + + + + + The ALTER ROLE command allows both global and + per-database settings to be overridden with user-specific values. + + + + + + Values set with ALTER DATABASE and ALTER ROLE + are applied only when starting a fresh database session. They + override values obtained from the configuration files or server + command line, and constitute defaults for the rest of the session. + Note that some settings cannot be changed after server start, and + so cannot be set with these commands (or the ones listed below). + + + + Once a client is connected to the database, PostgreSQL + provides two additional SQL commands (and equivalent functions) to + interact with session-local configuration settings: + + + + + + The SHOW command allows inspection of the + current value of any parameter. The corresponding SQL function is + current_setting(setting_name text) + (see ). + + + + + + The SET command allows modification of the + current value of those parameters that can be set locally to a + session; it has no effect on other sessions. + The corresponding SQL function is + set_config(setting_name, new_value, is_local) + (see ). + + + + + + In addition, the system view pg_settings can be + used to view and change session-local values: + + + + + + Querying this view is similar to using SHOW ALL but + provides more detail. It is also more flexible, since it's possible + to specify filter conditions or join against other relations. + + + + + + Using UPDATE on this view, specifically + updating the setting column, is the equivalent + of issuing SET commands. For example, the equivalent of + +SET configuration_parameter TO DEFAULT; + + is: + +UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter'; + + + + + + + + + Parameter Interaction via the Shell + + + In addition to setting global defaults or attaching + overrides at the database or role level, you can pass settings to + PostgreSQL via shell facilities. + Both the server and libpq client library + accept parameter values via the shell. + + + + + + During server startup, parameter settings can be + passed to the postgres command via the + command-line parameter. For example, + +postgres -c log_connections=yes -c log_destination='syslog' + + Settings provided in this way override those set via + postgresql.conf or ALTER SYSTEM, + so they cannot be changed globally without restarting the server. + + + + + + When starting a client session via libpq, + parameter settings can be + specified using the PGOPTIONS environment variable. + Settings established in this way constitute defaults for the life + of the session, but do not affect other sessions. + For historical reasons, the format of PGOPTIONS is + similar to that used when launching the postgres + command; specifically, the flag must be specified. + For example, + +env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql + + + + + Other clients and libraries might provide their own mechanisms, + via the shell or otherwise, that allow the user to alter session + settings without direct use of SQL commands. + + + + + + + + Managing Configuration File Contents + + + PostgreSQL provides several features for breaking + down complex postgresql.conf files into sub-files. + These features are especially useful when managing multiple servers + with related, but not identical, configurations. + + + + + include + in configuration file + + In addition to individual parameter settings, + the postgresql.conf file can contain include + directives, which specify another file to read and process as if + it were inserted into the configuration file at this point. This + feature allows a configuration file to be divided into physically + separate parts. Include directives simply look like: + +include 'filename' + + If the file name is not an absolute path, it is taken as relative to + the directory containing the referencing configuration file. + Inclusions can be nested. + + + + + include_if_exists + in configuration file + + There is also an include_if_exists directive, which acts + the same as the include directive, except + when the referenced file does not exist or cannot be read. A regular + include will consider this an error condition, but + include_if_exists merely logs a message and continues + processing the referencing configuration file. + + + + + include_dir + in configuration file + + The postgresql.conf file can also contain + include_dir directives, which specify an entire + directory of configuration files to include. These look like + +include_dir 'directory' + + Non-absolute directory names are taken as relative to the directory + containing the referencing configuration file. Within the specified + directory, only non-directory files whose names end with the + suffix .conf will be included. File names that + start with the . character are also ignored, to + prevent mistakes since such files are hidden on some platforms. Multiple + files within an include directory are processed in file name order + (according to C locale rules, i.e., numbers before letters, and + uppercase letters before lowercase ones). + + + + Include files or directories can be used to logically separate portions + of the database configuration, rather than having a single large + postgresql.conf file. Consider a company that has two + database servers, each with a different amount of memory. There are + likely elements of the configuration both will share, for things such + as logging. But memory-related parameters on the server will vary + between the two. And there might be server specific customizations, + too. One way to manage this situation is to break the custom + configuration changes for your site into three files. You could add + this to the end of your postgresql.conf file to include + them: + +include 'shared.conf' +include 'memory.conf' +include 'server.conf' + + All systems would have the same shared.conf. Each + server with a particular amount of memory could share the + same memory.conf; you might have one for all servers + with 8GB of RAM, another for those having 16GB. And + finally server.conf could have truly server-specific + configuration information in it. + + + + Another possibility is to create a configuration file directory and + put this information into files there. For example, a conf.d + directory could be referenced at the end of postgresql.conf: + +include_dir 'conf.d' + + Then you could name the files in the conf.d directory + like this: + +00shared.conf +01memory.conf +02server.conf + + This naming convention establishes a clear order in which these + files will be loaded. This is important because only the last + setting encountered for a particular parameter while the server is + reading configuration files will be used. In this example, + something set in conf.d/02server.conf would override a + value set in conf.d/01memory.conf. + + + + You might instead use this approach to naming the files + descriptively: + +00shared.conf +01memory-8GB.conf +02server-foo.conf + + This sort of arrangement gives a unique name for each configuration file + variation. This can help eliminate ambiguity when several servers have + their configurations all stored in one place, such as in a version + control repository. (Storing database configuration files under version + control is another good practice to consider.) + + + + + + File Locations + + + In addition to the postgresql.conf file + already mentioned, PostgreSQL uses + two other manually-edited configuration files, which control + client authentication (their use is discussed in ). By default, all three + configuration files are stored in the database cluster's data + directory. The parameters described in this section allow the + configuration files to be placed elsewhere. (Doing so can ease + administration. In particular it is often easier to ensure that + the configuration files are properly backed-up when they are + kept separate.) + + + + + data_directory (string) + + data_directory configuration parameter + + + + + Specifies the directory to use for data storage. + This parameter can only be set at server start. + + + + + + config_file (string) + + config_file configuration parameter + + + + + Specifies the main server configuration file + (customarily called postgresql.conf). + This parameter can only be set on the postgres command line. + + + + + + hba_file (string) + + hba_file configuration parameter + + + + + Specifies the configuration file for host-based authentication + (customarily called pg_hba.conf). + This parameter can only be set at server start. + + + + + + ident_file (string) + + ident_file configuration parameter + + + + + Specifies the configuration file for user name mapping + (customarily called pg_ident.conf). + This parameter can only be set at server start. + See also . + + + + + + external_pid_file (string) + + external_pid_file configuration parameter + + + + + Specifies the name of an additional process-ID (PID) file that the + server should create for use by server administration programs. + This parameter can only be set at server start. + + + + + + + In a default installation, none of the above parameters are set + explicitly. Instead, the + data directory is specified by the command-line + option or the PGDATA environment variable, and the + configuration files are all found within the data directory. + + + + If you wish to keep the configuration files elsewhere than the + data directory, the postgres + command-line option or PGDATA environment variable + must point to the directory containing the configuration files, + and the data_directory parameter must be set in + postgresql.conf (or on the command line) to show + where the data directory is actually located. Notice that + data_directory overrides and + PGDATA for the location + of the data directory, but not for the location of the configuration + files. + + + + If you wish, you can specify the configuration file names and locations + individually using the parameters config_file, + hba_file and/or ident_file. + config_file can only be specified on the + postgres command line, but the others can be + set within the main configuration file. If all three parameters plus + data_directory are explicitly set, then it is not necessary + to specify or PGDATA. + + + + When setting any of these parameters, a relative path will be interpreted + with respect to the directory in which postgres + is started. + + + + + Connections and Authentication + + + Connection Settings + + + + + listen_addresses (string) + + listen_addresses configuration parameter + + + + + Specifies the TCP/IP address(es) on which the server is + to listen for connections from client applications. + The value takes the form of a comma-separated list of host names + and/or numeric IP addresses. The special entry * + corresponds to all available IP interfaces. The entry + 0.0.0.0 allows listening for all IPv4 addresses and + :: allows listening for all IPv6 addresses. + If the list is empty, the server does not listen on any IP interface + at all, in which case only Unix-domain sockets can be used to connect + to it. + The default value is localhost, + which allows only local TCP/IP loopback connections to be + made. While client authentication () allows fine-grained control + over who can access the server, listen_addresses + controls which interfaces accept connection attempts, which + can help prevent repeated malicious connection requests on + insecure network interfaces. This parameter can only be set + at server start. + + + + + + port (integer) + + port configuration parameter + + + + + The TCP port the server listens on; 5432 by default. Note that the + same port number is used for all IP addresses the server listens on. + This parameter can only be set at server start. + + + + + + max_connections (integer) + + max_connections configuration parameter + + + + + Determines the maximum number of concurrent connections to the + database server. The default is typically 100 connections, but + might be less if your kernel settings will not support it (as + determined during initdb). This parameter can + only be set at server start. + + + + When running a standby server, you must set this parameter to the + same or higher value than on the primary server. Otherwise, queries + will not be allowed in the standby server. + + + + + + superuser_reserved_connections + (integer) + + superuser_reserved_connections configuration parameter + + + + + Determines the number of connection slots that + are reserved for connections by PostgreSQL + superusers. At most + connections can ever be active simultaneously. Whenever the + number of active concurrent connections is at least + max_connections minus + superuser_reserved_connections, new + connections will be accepted only for superusers, and no + new replication connections will be accepted. + + + + The default value is three connections. The value must be less + than max_connections. + This parameter can only be set at server start. + + + + + + unix_socket_directories (string) + + unix_socket_directories configuration parameter + + + + + Specifies the directory of the Unix-domain socket(s) on which the + server is to listen for connections from client applications. + Multiple sockets can be created by listing multiple directories + separated by commas. Whitespace between entries is + ignored; surround a directory name with double quotes if you need + to include whitespace or commas in the name. + An empty value + specifies not listening on any Unix-domain sockets, in which case + only TCP/IP sockets can be used to connect to the server. + + + + A value that starts with @ specifies that a + Unix-domain socket in the abstract namespace should be created + (currently supported on Linux and Windows). In that case, this value + does not specify a directory but a prefix from which + the actual socket name is computed in the same manner as for the + file-system namespace. While the abstract socket name prefix can be + chosen freely, since it is not a file-system location, the convention + is to nonetheless use file-system-like values such as + @/tmp. + + + + The default value is normally + /tmp, but that can be changed at build time. + On Windows, the default is empty, which means no Unix-domain socket is + created by default. + This parameter can only be set at server start. + + + + In addition to the socket file itself, which is named + .s.PGSQL.nnnn where + nnnn is the server's port number, an ordinary file + named .s.PGSQL.nnnn.lock will be + created in each of the unix_socket_directories directories. + Neither file should ever be removed manually. + For sockets in the abstract namespace, no lock file is created. + + + + + + unix_socket_group (string) + + unix_socket_group configuration parameter + + + + + Sets the owning group of the Unix-domain socket(s). (The owning + user of the sockets is always the user that starts the + server.) In combination with the parameter + unix_socket_permissions this can be used as + an additional access control mechanism for Unix-domain connections. + By default this is the empty string, which uses the default + group of the server user. This parameter can only be set at + server start. + + + + This parameter is not supported on Windows. Any setting will be + ignored. Also, sockets in the abstract namespace have no file owner, + so this setting is also ignored in that case. + + + + + + unix_socket_permissions (integer) + + unix_socket_permissions configuration parameter + + + + + Sets the access permissions of the Unix-domain socket(s). Unix-domain + sockets use the usual Unix file system permission set. + The parameter value is expected to be a numeric mode + specified in the format accepted by the + chmod and umask + system calls. (To use the customary octal format the number + must start with a 0 (zero).) + + + + The default permissions are 0777, meaning + anyone can connect. Reasonable alternatives are + 0770 (only user and group, see also + unix_socket_group) and 0700 + (only user). (Note that for a Unix-domain socket, only write + permission matters, so there is no point in setting or revoking + read or execute permissions.) + + + + This access control mechanism is independent of the one + described in . + + + + This parameter can only be set at server start. + + + + This parameter is irrelevant on systems, notably Solaris as of Solaris + 10, that ignore socket permissions entirely. There, one can achieve a + similar effect by pointing unix_socket_directories to a + directory having search permission limited to the desired audience. + + + + Sockets in the abstract namespace have no file permissions, so this + setting is also ignored in that case. + + + + + + bonjour (boolean) + + bonjour configuration parameter + + + + + Enables advertising the server's existence via + Bonjour. The default is off. + This parameter can only be set at server start. + + + + + + bonjour_name (string) + + bonjour_name configuration parameter + + + + + Specifies the Bonjour service + name. The computer name is used if this parameter is set to the + empty string '' (which is the default). This parameter is + ignored if the server was not compiled with + Bonjour support. + This parameter can only be set at server start. + + + + + + tcp_keepalives_idle (integer) + + tcp_keepalives_idle configuration parameter + + + + + Specifies the amount of time with no network activity after which + the operating system should send a TCP keepalive message to the client. + If this value is specified without units, it is taken as seconds. + A value of 0 (the default) selects the operating system's default. + This parameter is supported only on systems that support + TCP_KEEPIDLE or an equivalent socket option, and on + Windows; on other systems, it must be zero. + In sessions connected via a Unix-domain socket, this parameter is + ignored and always reads as zero. + + + + On Windows, setting a value of 0 will set this parameter to 2 hours, + since Windows does not provide a way to read the system default value. + + + + + + + tcp_keepalives_interval (integer) + + tcp_keepalives_interval configuration parameter + + + + + Specifies the amount of time after which a TCP keepalive message + that has not been acknowledged by the client should be retransmitted. + If this value is specified without units, it is taken as seconds. + A value of 0 (the default) selects the operating system's default. + This parameter is supported only on systems that support + TCP_KEEPINTVL or an equivalent socket option, and on + Windows; on other systems, it must be zero. + In sessions connected via a Unix-domain socket, this parameter is + ignored and always reads as zero. + + + + On Windows, setting a value of 0 will set this parameter to 1 second, + since Windows does not provide a way to read the system default value. + + + + + + + tcp_keepalives_count (integer) + + tcp_keepalives_count configuration parameter + + + + + Specifies the number of TCP keepalive messages that can be lost before + the server's connection to the client is considered dead. + A value of 0 (the default) selects the operating system's default. + This parameter is supported only on systems that support + TCP_KEEPCNT or an equivalent socket option; + on other systems, it must be zero. + In sessions connected via a Unix-domain socket, this parameter is + ignored and always reads as zero. + + + + This parameter is not supported on Windows, and must be zero. + + + + + + + tcp_user_timeout (integer) + + tcp_user_timeout configuration parameter + + + + + Specifies the amount of time that transmitted data may + remain unacknowledged before the TCP connection is forcibly closed. + If this value is specified without units, it is taken as milliseconds. + A value of 0 (the default) selects the operating system's default. + This parameter is supported only on systems that support + TCP_USER_TIMEOUT; on other systems, it must be zero. + In sessions connected via a Unix-domain socket, this parameter is + ignored and always reads as zero. + + + + This parameter is not supported on Windows, and must be zero. + + + + + + + client_connection_check_interval (integer) + + client_connection_check_interval configuration parameter + + + + + Sets the time interval between optional checks that the client is still + connected, while running queries. The check is performed by polling + the socket, and allows long running queries to be aborted sooner if + the kernel reports that the connection is closed. + + + This option is currently available only on systems that support the + non-standard POLLRDHUP extension to the + poll system call, including Linux. + + + If the value is specified without units, it is taken as milliseconds. + The default value is 0, which disables connection + checks. Without connection checks, the server will detect the loss of + the connection only at the next interaction with the socket, when it + waits for, receives or sends data. + + + For the kernel itself to detect lost TCP connections reliably and within + a known timeframe in all scenarios including network failure, it may + also be necessary to adjust the TCP keepalive settings of the operating + system, or the , + and + settings of + PostgreSQL. + + + + + + + + + Authentication + + + + authentication_timeout (integer) + timeoutclient authentication + client authenticationtimeout during + + authentication_timeout configuration parameter + + + + + + Maximum amount of time allowed to complete client authentication. If a + would-be client has not completed the authentication protocol in + this much time, the server closes the connection. This prevents + hung clients from occupying a connection indefinitely. + If this value is specified without units, it is taken as seconds. + The default is one minute (1m). + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + password_encryption (enum) + + password_encryption configuration parameter + + + + + When a password is specified in or + , this parameter determines the + algorithm to use to encrypt the password. Possible values are + scram-sha-256, which will encrypt the password with + SCRAM-SHA-256, and md5, which stores the password + as an MD5 hash. The default is scram-sha-256. + + + Note that older clients might lack support for the SCRAM authentication + mechanism, and hence not work with passwords encrypted with + SCRAM-SHA-256. See for more details. + + + + + + krb_server_keyfile (string) + + krb_server_keyfile configuration parameter + + + + + Sets the location of the server's Kerberos key file. The default is + FILE:/usr/local/pgsql/etc/krb5.keytab + (where the directory part is whatever was specified + as sysconfdir at build time; use + pg_config --sysconfdir to determine that). + If this parameter is set to an empty string, it is ignored and a + system-dependent default is used. + This parameter can only be set in the + postgresql.conf file or on the server command line. + See for more information. + + + + + + krb_caseins_users (boolean) + + krb_caseins_users configuration parameter + + + + + Sets whether GSSAPI user names should be treated + case-insensitively. + The default is off (case sensitive). This parameter can only be + set in the postgresql.conf file or on the server command line. + + + + + + db_user_namespace (boolean) + + db_user_namespace configuration parameter + + + + + This parameter enables per-database user names. It is off by default. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + If this is on, you should create users as username@dbname. + When username is passed by a connecting client, + @ and the database name are appended to the user + name and that database-specific user name is looked up by the + server. Note that when you create users with names containing + @ within the SQL environment, you will need to + quote the user name. + + + + With this parameter enabled, you can still create ordinary global + users. Simply append @ when specifying the user + name in the client, e.g., joe@. The @ + will be stripped off before the user name is looked up by the + server. + + + + db_user_namespace causes the client's and + server's user name representation to differ. + Authentication checks are always done with the server's user name + so authentication methods must be configured for the + server's user name, not the client's. Because + md5 uses the user name as salt on both the + client and server, md5 cannot be used with + db_user_namespace. + + + + + This feature is intended as a temporary measure until a + complete solution is found. At that time, this option will + be removed. + + + + + + + + + SSL + + + See for more information about setting up SSL. + + + + + ssl (boolean) + + ssl configuration parameter + + + + + Enables SSL connections. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is off. + + + + + + ssl_ca_file (string) + + ssl_ca_file configuration parameter + + + + + Specifies the name of the file containing the SSL server certificate + authority (CA). + Relative paths are relative to the data directory. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is empty, meaning no CA file is loaded, + and client certificate verification is not performed. + + + + + + ssl_cert_file (string) + + ssl_cert_file configuration parameter + + + + + Specifies the name of the file containing the SSL server certificate. + Relative paths are relative to the data directory. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is server.crt. + + + + + + ssl_crl_file (string) + + ssl_crl_file configuration parameter + + + + + Specifies the name of the file containing the SSL server certificate + revocation list (CRL). + Relative paths are relative to the data directory. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is empty, meaning no CRL file is loaded (unless + is set). + + + + + + ssl_crl_dir (string) + + ssl_crl_dir configuration parameter + + + + + Specifies the name of the directory containing the SSL server + certificate revocation list (CRL). Relative paths are relative to the + data directory. This parameter can only be set in + the postgresql.conf file or on the server command + line. The default is empty, meaning no CRLs are used (unless + is set). + + + + The directory needs to be prepared with the + OpenSSL command + openssl rehash or c_rehash. See + its documentation for details. + + + + When using this setting, CRLs in the specified directory are loaded + on-demand at connection time. New CRLs can be added to the directory + and will be used immediately. This is unlike , which causes the CRL in the file to be + loaded at server start time or when the configuration is reloaded. + Both settings can be used together. + + + + + + ssl_key_file (string) + + ssl_key_file configuration parameter + + + + + Specifies the name of the file containing the SSL server private key. + Relative paths are relative to the data directory. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is server.key. + + + + + + ssl_ciphers (string) + + ssl_ciphers configuration parameter + + + + + Specifies a list of SSL cipher suites that are + allowed to be used by SSL connections. See the + ciphers + manual page in the OpenSSL package for the + syntax of this setting and a list of supported values. Only + connections using TLS version 1.2 and lower are affected. There is + currently no setting that controls the cipher choices used by TLS + version 1.3 connections. The default value is + HIGH:MEDIUM:+3DES:!aNULL. The default is usually a + reasonable choice unless you have specific security requirements. + + + + This parameter can only be set in the + postgresql.conf file or on the server command + line. + + + + Explanation of the default value: + + + HIGH + + + Cipher suites that use ciphers from HIGH group (e.g., + AES, Camellia, 3DES) + + + + + + MEDIUM + + + Cipher suites that use ciphers from MEDIUM group + (e.g., RC4, SEED) + + + + + + +3DES + + + The OpenSSL default order for + HIGH is problematic because it orders 3DES + higher than AES128. This is wrong because 3DES offers less + security than AES128, and it is also much slower. + +3DES reorders it after all other + HIGH and MEDIUM ciphers. + + + + + + !aNULL + + + Disables anonymous cipher suites that do no authentication. Such + cipher suites are vulnerable to MITM attacks and + therefore should not be used. + + + + + + + + Available cipher suite details will vary across + OpenSSL versions. Use the command + openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL' to + see actual details for the currently installed + OpenSSL version. Note that this list is + filtered at run time based on the server key type. + + + + + + ssl_prefer_server_ciphers (boolean) + + ssl_prefer_server_ciphers configuration parameter + + + + + Specifies whether to use the server's SSL cipher preferences, rather + than the client's. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is on. + + + + Older PostgreSQL versions do not have this setting and always use the + client's preferences. This setting is mainly for backward + compatibility with those versions. Using the server's preferences is + usually better because it is more likely that the server is appropriately + configured. + + + + + + ssl_ecdh_curve (string) + + ssl_ecdh_curve configuration parameter + + + + + Specifies the name of the curve to use in ECDH key + exchange. It needs to be supported by all clients that connect. + It does not need to be the same curve used by the server's Elliptic + Curve key. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is prime256v1. + + + + OpenSSL names for the most common curves + are: + prime256v1 (NIST P-256), + secp384r1 (NIST P-384), + secp521r1 (NIST P-521). + The full list of available curves can be shown with the command + openssl ecparam -list_curves. Not all of them + are usable in TLS though. + + + + + + ssl_min_protocol_version (enum) + + ssl_min_protocol_version configuration parameter + + + + + Sets the minimum SSL/TLS protocol version to use. Valid values are + currently: TLSv1, TLSv1.1, + TLSv1.2, TLSv1.3. Older + versions of the OpenSSL library do not + support all values; an error will be raised if an unsupported setting + is chosen. Protocol versions before TLS 1.0, namely SSL version 2 and + 3, are always disabled. + + + + The default is TLSv1.2, which satisfies industry + best practices as of this writing. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + ssl_max_protocol_version (enum) + + ssl_max_protocol_version configuration parameter + + + + + Sets the maximum SSL/TLS protocol version to use. Valid values are as + for , with addition of + an empty string, which allows any protocol version. The default is to + allow any version. Setting the maximum protocol version is mainly + useful for testing or if some component has issues working with a + newer protocol. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + ssl_dh_params_file (string) + + ssl_dh_params_file configuration parameter + + + + + Specifies the name of the file containing Diffie-Hellman parameters + used for so-called ephemeral DH family of SSL ciphers. The default is + empty, in which case compiled-in default DH parameters used. Using + custom DH parameters reduces the exposure if an attacker manages to + crack the well-known compiled-in DH parameters. You can create your own + DH parameters file with the command + openssl dhparam -out dhparams.pem 2048. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + ssl_passphrase_command (string) + + ssl_passphrase_command configuration parameter + + + + + Sets an external command to be invoked when a passphrase for + decrypting an SSL file such as a private key needs to be obtained. By + default, this parameter is empty, which means the built-in prompting + mechanism is used. + + + The command must print the passphrase to the standard output and exit + with code 0. In the parameter value, %p is + replaced by a prompt string. (Write %% for a + literal %.) Note that the prompt string will + probably contain whitespace, so be sure to quote adequately. A single + newline is stripped from the end of the output if present. + + + The command does not actually have to prompt the user for a + passphrase. It can read it from a file, obtain it from a keychain + facility, or similar. It is up to the user to make sure the chosen + mechanism is adequately secure. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + ssl_passphrase_command_supports_reload (boolean) + + ssl_passphrase_command_supports_reload configuration parameter + + + + + This parameter determines whether the passphrase command set by + ssl_passphrase_command will also be called during a + configuration reload if a key file needs a passphrase. If this + parameter is off (the default), then + ssl_passphrase_command will be ignored during a + reload and the SSL configuration will not be reloaded if a passphrase + is needed. That setting is appropriate for a command that requires a + TTY for prompting, which might not be available when the server is + running. Setting this parameter to on might be appropriate if the + passphrase is obtained from a file, for example. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + + Resource Consumption + + + Memory + + + + shared_buffers (integer) + + shared_buffers configuration parameter + + + + + Sets the amount of memory the database server uses for shared + memory buffers. The default is typically 128 megabytes + (128MB), but might be less if your kernel settings will + not support it (as determined during initdb). + This setting must be at least 128 kilobytes. However, + settings significantly higher than the minimum are usually needed + for good performance. + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + (Non-default values of BLCKSZ change the minimum + value.) + This parameter can only be set at server start. + + + + If you have a dedicated database server with 1GB or more of RAM, a + reasonable starting value for shared_buffers is 25% + of the memory in your system. There are some workloads where even + larger settings for shared_buffers are effective, but + because PostgreSQL also relies on the + operating system cache, it is unlikely that an allocation of more than + 40% of RAM to shared_buffers will work better than a + smaller amount. Larger settings for shared_buffers + usually require a corresponding increase in + max_wal_size, in order to spread out the + process of writing large quantities of new or changed data over a + longer period of time. + + + + On systems with less than 1GB of RAM, a smaller percentage of RAM is + appropriate, so as to leave adequate space for the operating system. + + + + + + + huge_pages (enum) + + huge_pages configuration parameter + + + + + Controls whether huge pages are requested for the main shared memory + area. Valid values are try (the default), + on, and off. With + huge_pages set to try, the + server will try to request huge pages, but fall back to the default if + that fails. With on, failure to request huge pages + will prevent the server from starting up. With off, + huge pages will not be requested. + + + + At present, this setting is supported only on Linux and Windows. The + setting is ignored on other systems when set to + try. + + + + The use of huge pages results in smaller page tables and less CPU time + spent on memory management, increasing performance. For more details about + using huge pages on Linux, see . + + + + Huge pages are known as large pages on Windows. To use them, you need to + assign the user right Lock pages in memory to the Windows user account + that runs PostgreSQL. + You can use Windows Group Policy tool (gpedit.msc) to assign the user right + Lock pages in memory. + To start the database server on the command prompt as a standalone process, + not as a Windows service, the command prompt must be run as an administrator or + User Access Control (UAC) must be disabled. When the UAC is enabled, the normal + command prompt revokes the user right Lock pages in memory when started. + + + + Note that this setting only affects the main shared memory area. + Operating systems such as Linux, FreeBSD, and Illumos can also use + huge pages (also known as super pages or + large pages) automatically for normal memory + allocation, without an explicit request from + PostgreSQL. On Linux, this is called + transparent huge pagestransparent + huge pages (THP). That feature has been known to + cause performance degradation with + PostgreSQL for some users on some Linux + versions, so its use is currently discouraged (unlike explicit use of + huge_pages). + + + + + + huge_page_size (integer) + + huge_page_size configuration parameter + + + + + Controls the size of huge pages, when they are enabled with + . + The default is zero (0). + When set to 0, the default huge page size on the + system will be used. This parameter can only be set at server start. + + + Some commonly available page sizes on modern 64 bit server architectures include: + 2MB and 1GB (Intel and AMD), 16MB and + 16GB (IBM POWER), and 64kB, 2MB, + 32MB and 1GB (ARM). For more information + about usage and support, see . + + + Non-default settings are currently supported only on Linux. + + + + + + temp_buffers (integer) + + temp_buffers configuration parameter + + + + + Sets the maximum amount of memory used for temporary buffers within + each database session. These are session-local buffers used only + for access to temporary tables. + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + The default is eight megabytes (8MB). + (If BLCKSZ is not 8kB, the default value scales + proportionally to it.) + This setting can be changed within individual + sessions, but only before the first use of temporary tables + within the session; subsequent attempts to change the value will + have no effect on that session. + + + + A session will allocate temporary buffers as needed up to the limit + given by temp_buffers. The cost of setting a large + value in sessions that do not actually need many temporary + buffers is only a buffer descriptor, or about 64 bytes, per + increment in temp_buffers. However if a buffer is + actually used an additional 8192 bytes will be consumed for it + (or in general, BLCKSZ bytes). + + + + + + max_prepared_transactions (integer) + + max_prepared_transactions configuration parameter + + + + + Sets the maximum number of transactions that can be in the + prepared state simultaneously (see ). + Setting this parameter to zero (which is the default) + disables the prepared-transaction feature. + This parameter can only be set at server start. + + + + If you are not planning to use prepared transactions, this parameter + should be set to zero to prevent accidental creation of prepared + transactions. If you are using prepared transactions, you will + probably want max_prepared_transactions to be at + least as large as , so that every + session can have a prepared transaction pending. + + + + When running a standby server, you must set this parameter to the + same or higher value than on the primary server. Otherwise, queries + will not be allowed in the standby server. + + + + + + work_mem (integer) + + work_mem configuration parameter + + + + + Sets the base maximum amount of memory to be used by a query operation + (such as a sort or hash table) before writing to temporary disk files. + If this value is specified without units, it is taken as kilobytes. + The default value is four megabytes (4MB). + Note that for a complex query, several sort or hash operations might be + running in parallel; each operation will generally be allowed + to use as much memory as this value specifies before it starts + to write data into temporary files. Also, several running + sessions could be doing such operations concurrently. + Therefore, the total memory used could be many times the value + of work_mem; it is necessary to keep this + fact in mind when choosing the value. Sort operations are used + for ORDER BY, DISTINCT, + and merge joins. + Hash tables are used in hash joins, hash-based aggregation, result + cache nodes and hash-based processing of IN + subqueries. + + + Hash-based operations are generally more sensitive to memory + availability than equivalent sort-based operations. The + memory available for hash tables is computed by multiplying + work_mem by + hash_mem_multiplier. This makes it + possible for hash-based operations to use an amount of memory + that exceeds the usual work_mem base + amount. + + + + + + hash_mem_multiplier (floating point) + + hash_mem_multiplier configuration parameter + + + + + Used to compute the maximum amount of memory that hash-based + operations can use. The final limit is determined by + multiplying work_mem by + hash_mem_multiplier. The default value is + 1.0, which makes hash-based operations subject to the same + simple work_mem maximum as sort-based + operations. + + + Consider increasing hash_mem_multiplier in + environments where spilling by query operations is a regular + occurrence, especially when simply increasing + work_mem results in memory pressure (memory + pressure typically takes the form of intermittent out of + memory errors). A setting of 1.5 or 2.0 may be effective with + mixed workloads. Higher settings in the range of 2.0 - 8.0 or + more may be effective in environments where + work_mem has already been increased to 40MB + or more. + + + + + + maintenance_work_mem (integer) + + maintenance_work_mem configuration parameter + + + + + Specifies the maximum amount of memory to be used by maintenance + operations, such as VACUUM, CREATE + INDEX, and ALTER TABLE ADD FOREIGN KEY. + If this value is specified without units, it is taken as kilobytes. + It defaults + to 64 megabytes (64MB). Since only one of these + operations can be executed at a time by a database session, and + an installation normally doesn't have many of them running + concurrently, it's safe to set this value significantly larger + than work_mem. Larger settings might improve + performance for vacuuming and for restoring database dumps. + + + Note that when autovacuum runs, up to + times this memory + may be allocated, so be careful not to set the default value + too high. It may be useful to control for this by separately + setting . + + + + + + autovacuum_work_mem (integer) + + autovacuum_work_mem configuration parameter + + + + + Specifies the maximum amount of memory to be used by each + autovacuum worker process. + If this value is specified without units, it is taken as kilobytes. + It defaults to -1, indicating that + the value of should + be used instead. The setting has no effect on the behavior of + VACUUM when run in other contexts. + This parameter can only be set in the + postgresql.conf file or on the server command + line. + + + + + + logical_decoding_work_mem (integer) + + logical_decoding_work_mem configuration parameter + + + + + Specifies the maximum amount of memory to be used by logical decoding, + before some of the decoded changes are written to local disk. This + limits the amount of memory used by logical streaming replication + connections. It defaults to 64 megabytes (64MB). + Since each replication connection only uses a single buffer of this size, + and an installation normally doesn't have many such connections + concurrently (as limited by max_wal_senders), it's + safe to set this value significantly higher than work_mem, + reducing the amount of decoded changes written to disk. + + + + + + max_stack_depth (integer) + + max_stack_depth configuration parameter + + + + + Specifies the maximum safe depth of the server's execution stack. + The ideal setting for this parameter is the actual stack size limit + enforced by the kernel (as set by ulimit -s or local + equivalent), less a safety margin of a megabyte or so. The safety + margin is needed because the stack depth is not checked in every + routine in the server, but only in key potentially-recursive routines. + If this value is specified without units, it is taken as kilobytes. + The default setting is two megabytes (2MB), which + is conservatively small and unlikely to risk crashes. However, + it might be too small to allow execution of complex functions. + Only superusers can change this setting. + + + + Setting max_stack_depth higher than + the actual kernel limit will mean that a runaway recursive function + can crash an individual backend process. On platforms where + PostgreSQL can determine the kernel limit, + the server will not allow this variable to be set to an unsafe + value. However, not all platforms provide the information, + so caution is recommended in selecting a value. + + + + + + shared_memory_type (enum) + + shared_memory_type configuration parameter + + + + + Specifies the shared memory implementation that the server + should use for the main shared memory region that holds + PostgreSQL's shared buffers and other + shared data. Possible values are mmap (for + anonymous shared memory allocated using mmap), + sysv (for System V shared memory allocated via + shmget) and windows (for Windows + shared memory). Not all values are supported on all platforms; the + first supported option is the default for that platform. The use of + the sysv option, which is not the default on any + platform, is generally discouraged because it typically requires + non-default kernel settings to allow for large allocations (see ). + + + + + + dynamic_shared_memory_type (enum) + + dynamic_shared_memory_type configuration parameter + + + + + Specifies the dynamic shared memory implementation that the server + should use. Possible values are posix (for POSIX shared + memory allocated using shm_open), sysv + (for System V shared memory allocated via shmget), + windows (for Windows shared memory), + and mmap (to simulate shared memory using + memory-mapped files stored in the data directory). + Not all values are supported on all platforms; the first supported + option is the default for that platform. The use of the + mmap option, which is not the default on any platform, + is generally discouraged because the operating system may write + modified pages back to disk repeatedly, increasing system I/O load; + however, it may be useful for debugging, when the + pg_dynshmem directory is stored on a RAM disk, or when + other shared memory facilities are not available. + + + + + + min_dynamic_shared_memory (integer) + + min_dynamic_shared_memory configuration parameter + + + + + Specifies the amount of memory that should be allocated at server + startup for use by parallel queries. When this memory region is + insufficient or exhausted by concurrent queries, new parallel queries + try to allocate extra shared memory temporarily from the operating + system using the method configured with + dynamic_shared_memory_type, which may be slower due + to memory management overheads. Memory that is allocated at startup + with min_dynamic_shared_memory is affected by + the huge_pages setting on operating systems where + that is supported, and may be more likely to benefit from larger pages + on operating systems where that is managed automatically. + The default value is 0 (none). This parameter can + only be set at server start. + + + + + + + + + Disk + + + + temp_file_limit (integer) + + temp_file_limit configuration parameter + + + + + Specifies the maximum amount of disk space that a process can use + for temporary files, such as sort and hash temporary files, or the + storage file for a held cursor. A transaction attempting to exceed + this limit will be canceled. + If this value is specified without units, it is taken as kilobytes. + -1 (the default) means no limit. + Only superusers can change this setting. + + + This setting constrains the total space used at any instant by all + temporary files used by a given PostgreSQL process. + It should be noted that disk space used for explicit temporary + tables, as opposed to temporary files used behind-the-scenes in query + execution, does not count against this limit. + + + + + + + + + Kernel Resource Usage + + + + max_files_per_process (integer) + + max_files_per_process configuration parameter + + + + + Sets the maximum number of simultaneously open files allowed to each + server subprocess. The default is one thousand files. If the kernel is enforcing + a safe per-process limit, you don't need to worry about this setting. + But on some platforms (notably, most BSD systems), the kernel will + allow individual processes to open many more files than the system + can actually support if many processes all try to open + that many files. If you find yourself seeing Too many open + files failures, try reducing this setting. + This parameter can only be set at server start. + + + + + + + + Cost-based Vacuum Delay + + + During the execution of + and + commands, the system maintains an + internal counter that keeps track of the estimated cost of the + various I/O operations that are performed. When the accumulated + cost reaches a limit (specified by + vacuum_cost_limit), the process performing + the operation will sleep for a short period of time, as specified by + vacuum_cost_delay. Then it will reset the + counter and continue execution. + + + + The intent of this feature is to allow administrators to reduce + the I/O impact of these commands on concurrent database + activity. There are many situations where it is not + important that maintenance commands like + VACUUM and ANALYZE finish + quickly; however, it is usually very important that these + commands do not significantly interfere with the ability of the + system to perform other database operations. Cost-based vacuum + delay provides a way for administrators to achieve this. + + + + This feature is disabled by default for manually issued + VACUUM commands. To enable it, set the + vacuum_cost_delay variable to a nonzero + value. + + + + + vacuum_cost_delay (floating point) + + vacuum_cost_delay configuration parameter + + + + + The amount of time that the process will sleep + when the cost limit has been exceeded. + If this value is specified without units, it is taken as milliseconds. + The default value is zero, which disables the cost-based vacuum + delay feature. Positive values enable cost-based vacuuming. + + + + When using cost-based vacuuming, appropriate values for + vacuum_cost_delay are usually quite small, perhaps + less than 1 millisecond. While vacuum_cost_delay + can be set to fractional-millisecond values, such delays may not be + measured accurately on older platforms. On such platforms, + increasing VACUUM's throttled resource consumption + above what you get at 1ms will require changing the other vacuum cost + parameters. You should, nonetheless, + keep vacuum_cost_delay as small as your platform + will consistently measure; large delays are not helpful. + + + + + + vacuum_cost_page_hit (integer) + + vacuum_cost_page_hit configuration parameter + + + + + The estimated cost for vacuuming a buffer found in the shared buffer + cache. It represents the cost to lock the buffer pool, lookup + the shared hash table and scan the content of the page. The + default value is one. + + + + + + vacuum_cost_page_miss (integer) + + vacuum_cost_page_miss configuration parameter + + + + + The estimated cost for vacuuming a buffer that has to be read from + disk. This represents the effort to lock the buffer pool, + lookup the shared hash table, read the desired block in from + the disk and scan its content. The default value is 2. + + + + + + vacuum_cost_page_dirty (integer) + + vacuum_cost_page_dirty configuration parameter + + + + + The estimated cost charged when vacuum modifies a block that was + previously clean. It represents the extra I/O required to + flush the dirty block out to disk again. The default value is + 20. + + + + + + vacuum_cost_limit (integer) + + vacuum_cost_limit configuration parameter + + + + + The accumulated cost that will cause the vacuuming process to sleep. + The default value is 200. + + + + + + + + There are certain operations that hold critical locks and should + therefore complete as quickly as possible. Cost-based vacuum + delays do not occur during such operations. Therefore it is + possible that the cost accumulates far higher than the specified + limit. To avoid uselessly long delays in such cases, the actual + delay is calculated as vacuum_cost_delay * + accumulated_balance / + vacuum_cost_limit with a maximum of + vacuum_cost_delay * 4. + + + + + + Background Writer + + + There is a separate server + process called the background writer, whose function + is to issue writes of dirty (new or modified) shared + buffers. When the number of clean shared buffers appears to be + insufficient, the background writer writes some dirty buffers to the + file system and marks them as clean. This reduces the likelihood + that server processes handling user queries will be unable to find + clean buffers and have to write dirty buffers themselves. + However, the background writer does cause a net overall + increase in I/O load, because while a repeatedly-dirtied page might + otherwise be written only once per checkpoint interval, the + background writer might write it several times as it is dirtied + in the same interval. The parameters discussed in this subsection + can be used to tune the behavior for local needs. + + + + + bgwriter_delay (integer) + + bgwriter_delay configuration parameter + + + + + Specifies the delay between activity rounds for the + background writer. In each round the writer issues writes + for some number of dirty buffers (controllable by the + following parameters). It then sleeps for + the length of bgwriter_delay, and repeats. + When there are no dirty buffers in the + buffer pool, though, it goes into a longer sleep regardless of + bgwriter_delay. + If this value is specified without units, it is taken as milliseconds. + The default value is 200 + milliseconds (200ms). Note that on many systems, the + effective resolution of sleep delays is 10 milliseconds; setting + bgwriter_delay to a value that is not a multiple of 10 + might have the same results as setting it to the next higher multiple + of 10. This parameter can only be set in the + postgresql.conf file or on the server command line. + + + + + + bgwriter_lru_maxpages (integer) + + bgwriter_lru_maxpages configuration parameter + + + + + In each round, no more than this many buffers will be written + by the background writer. Setting this to zero disables + background writing. (Note that checkpoints, which are managed by + a separate, dedicated auxiliary process, are unaffected.) + The default value is 100 buffers. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + bgwriter_lru_multiplier (floating point) + + bgwriter_lru_multiplier configuration parameter + + + + + The number of dirty buffers written in each round is based on the + number of new buffers that have been needed by server processes + during recent rounds. The average recent need is multiplied by + bgwriter_lru_multiplier to arrive at an estimate of the + number of buffers that will be needed during the next round. Dirty + buffers are written until there are that many clean, reusable buffers + available. (However, no more than bgwriter_lru_maxpages + buffers will be written per round.) + Thus, a setting of 1.0 represents a just in time policy + of writing exactly the number of buffers predicted to be needed. + Larger values provide some cushion against spikes in demand, + while smaller values intentionally leave writes to be done by + server processes. + The default is 2.0. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + bgwriter_flush_after (integer) + + bgwriter_flush_after configuration parameter + + + + + Whenever more than this amount of data has + been written by the background writer, attempt to force the OS to issue these + writes to the underlying storage. Doing so will limit the amount of + dirty data in the kernel's page cache, reducing the likelihood of + stalls when an fsync is issued at the end of a checkpoint, or when + the OS writes data back in larger batches in the background. Often + that will result in greatly reduced transaction latency, but there + also are some cases, especially with workloads that are bigger than + , but smaller than the OS's page + cache, where performance might degrade. This setting may have no + effect on some platforms. + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + The valid range is between + 0, which disables forced writeback, and + 2MB. The default is 512kB on Linux, + 0 elsewhere. (If BLCKSZ is not 8kB, + the default and maximum values scale proportionally to it.) + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + Smaller values of bgwriter_lru_maxpages and + bgwriter_lru_multiplier reduce the extra I/O load + caused by the background writer, but make it more likely that server + processes will have to issue writes for themselves, delaying interactive + queries. + + + + + Asynchronous Behavior + + + + backend_flush_after (integer) + + backend_flush_after configuration parameter + + + + + Whenever more than this amount of data has + been written by a single backend, attempt to force the OS to issue + these writes to the underlying storage. Doing so will limit the + amount of dirty data in the kernel's page cache, reducing the + likelihood of stalls when an fsync is issued at the end of a + checkpoint, or when the OS writes data back in larger batches in the + background. Often that will result in greatly reduced transaction + latency, but there also are some cases, especially with workloads + that are bigger than , but smaller + than the OS's page cache, where performance might degrade. This + setting may have no effect on some platforms. + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + The valid range is + between 0, which disables forced writeback, + and 2MB. The default is 0, i.e., no + forced writeback. (If BLCKSZ is not 8kB, + the maximum value scales proportionally to it.) + + + + + + effective_io_concurrency (integer) + + effective_io_concurrency configuration parameter + + + + + Sets the number of concurrent disk I/O operations that + PostgreSQL expects can be executed + simultaneously. Raising this value will increase the number of I/O + operations that any individual PostgreSQL session + attempts to initiate in parallel. The allowed range is 1 to 1000, + or zero to disable issuance of asynchronous I/O requests. Currently, + this setting only affects bitmap heap scans. + + + + For magnetic drives, a good starting point for this setting is the + number of separate + drives comprising a RAID 0 stripe or RAID 1 mirror being used for the + database. (For RAID 5 the parity drive should not be counted.) + However, if the database is often busy with multiple queries issued in + concurrent sessions, lower values may be sufficient to keep the disk + array busy. A value higher than needed to keep the disks busy will + only result in extra CPU overhead. + SSDs and other memory-based storage can often process many + concurrent requests, so the best value might be in the hundreds. + + + + Asynchronous I/O depends on an effective posix_fadvise + function, which some operating systems lack. If the function is not + present then setting this parameter to anything but zero will result + in an error. On some operating systems (e.g., Solaris), the function + is present but does not actually do anything. + + + + The default is 1 on supported systems, otherwise 0. This value can + be overridden for tables in a particular tablespace by setting the + tablespace parameter of the same name (see + ). + + + + + + maintenance_io_concurrency (integer) + + maintenance_io_concurrency configuration parameter + + + + + Similar to effective_io_concurrency, but used + for maintenance work that is done on behalf of many client sessions. + + + The default is 10 on supported systems, otherwise 0. This value can + be overridden for tables in a particular tablespace by setting the + tablespace parameter of the same name (see + ). + + + + + + max_worker_processes (integer) + + max_worker_processes configuration parameter + + + + + Sets the maximum number of background processes that the system + can support. This parameter can only be set at server start. The + default is 8. + + + + When running a standby server, you must set this parameter to the + same or higher value than on the primary server. Otherwise, queries + will not be allowed in the standby server. + + + + When changing this value, consider also adjusting + , + , and + . + + + + + + max_parallel_workers_per_gather (integer) + + max_parallel_workers_per_gather configuration parameter + + + + + Sets the maximum number of workers that can be started by a single + Gather or Gather Merge node. + Parallel workers are taken from the pool of processes established by + , limited by + . Note that the requested + number of workers may not actually be available at run time. If this + occurs, the plan will run with fewer workers than expected, which may + be inefficient. The default value is 2. Setting this value to 0 + disables parallel query execution. + + + + Note that parallel queries may consume very substantially more + resources than non-parallel queries, because each worker process is + a completely separate process which has roughly the same impact on the + system as an additional user session. This should be taken into + account when choosing a value for this setting, as well as when + configuring other settings that control resource utilization, such + as . Resource limits such as + work_mem are applied individually to each worker, + which means the total utilization may be much higher across all + processes than it would normally be for any single process. + For example, a parallel query using 4 workers may use up to 5 times + as much CPU time, memory, I/O bandwidth, and so forth as a query which + uses no workers at all. + + + + For more information on parallel query, see + . + + + + + + max_parallel_maintenance_workers (integer) + + max_parallel_maintenance_workers configuration parameter + + + + + Sets the maximum number of parallel workers that can be + started by a single utility command. Currently, the parallel + utility commands that support the use of parallel workers are + CREATE INDEX only when building a B-tree index, + and VACUUM without FULL + option. Parallel workers are taken from the pool of processes + established by , limited + by . Note that the requested + number of workers may not actually be available at run time. + If this occurs, the utility operation will run with fewer + workers than expected. The default value is 2. Setting this + value to 0 disables the use of parallel workers by utility + commands. + + + + Note that parallel utility commands should not consume + substantially more memory than equivalent non-parallel + operations. This strategy differs from that of parallel + query, where resource limits generally apply per worker + process. Parallel utility commands treat the resource limit + maintenance_work_mem as a limit to be applied to + the entire utility command, regardless of the number of + parallel worker processes. However, parallel utility + commands may still consume substantially more CPU resources + and I/O bandwidth. + + + + + + max_parallel_workers (integer) + + max_parallel_workers configuration parameter + + + + + Sets the maximum number of workers that the system can support for + parallel operations. The default value is 8. When increasing or + decreasing this value, consider also adjusting + and + . + Also, note that a setting for this value which is higher than + will have no effect, + since parallel workers are taken from the pool of worker processes + established by that setting. + + + + + + + parallel_leader_participation (boolean) + + parallel_leader_participation configuration parameter + + + + + Allows the leader process to execute the query plan under + Gather and Gather Merge nodes + instead of waiting for worker processes. The default is + on. Setting this value to off + reduces the likelihood that workers will become blocked because the + leader is not reading tuples fast enough, but requires the leader + process to wait for worker processes to start up before the first + tuples can be produced. The degree to which the leader can help or + hinder performance depends on the plan type, number of workers and + query duration. + + + + + + old_snapshot_threshold (integer) + + old_snapshot_threshold configuration parameter + + + + + Sets the minimum amount of time that a query snapshot can be used + without risk of a snapshot too old error occurring + when using the snapshot. Data that has been dead for longer than + this threshold is allowed to be vacuumed away. This can help + prevent bloat in the face of snapshots which remain in use for a + long time. To prevent incorrect results due to cleanup of data which + would otherwise be visible to the snapshot, an error is generated + when the snapshot is older than this threshold and the snapshot is + used to read a page which has been modified since the snapshot was + built. + + + + If this value is specified without units, it is taken as minutes. + A value of -1 (the default) disables this feature, + effectively setting the snapshot age limit to infinity. + This parameter can only be set at server start. + + + + Useful values for production work probably range from a small number + of hours to a few days. Small values (such as 0 or + 1min) are only allowed because they may sometimes be + useful for testing. While a setting as high as 60d is + allowed, please note that in many workloads extreme bloat or + transaction ID wraparound may occur in much shorter time frames. + + + + When this feature is enabled, freed space at the end of a relation + cannot be released to the operating system, since that could remove + information needed to detect the snapshot too old + condition. All space allocated to a relation remains associated with + that relation for reuse only within that relation unless explicitly + freed (for example, with VACUUM FULL). + + + + This setting does not attempt to guarantee that an error will be + generated under any particular circumstances. In fact, if the + correct results can be generated from (for example) a cursor which + has materialized a result set, no error will be generated even if the + underlying rows in the referenced table have been vacuumed away. + Some tables cannot safely be vacuumed early, and so will not be + affected by this setting, such as system catalogs. For such tables + this setting will neither reduce bloat nor create a possibility + of a snapshot too old error on scanning. + + + + + + + + + Write Ahead Log + + + For additional information on tuning these settings, + see . + + + + Settings + + + + wal_level (enum) + + wal_level configuration parameter + + + + + wal_level determines how much information is written to + the WAL. The default value is replica, which writes enough + data to support WAL archiving and replication, including running + read-only queries on a standby server. minimal removes all + logging except the information required to recover from a crash or + immediate shutdown. Finally, + logical adds information necessary to support logical + decoding. Each level includes the information logged at all lower + levels. This parameter can only be set at server start. + + + In minimal level, no information is logged for + permanent relations for the remainder of a transaction that creates or + rewrites them. This can make operations much faster (see + ). Operations that initiate this + optimization include: + + ALTER ... SET TABLESPACE + CLUSTER + CREATE TABLE + REFRESH MATERIALIZED VIEW + (without ) + REINDEX + TRUNCATE + + But minimal WAL does not contain enough information to reconstruct the + data from a base backup and the WAL logs, so replica or + higher must be used to enable WAL archiving + () and streaming replication. + Note that changing wal_level to + minimal makes any base backups taken before + unavailable for archive recovery and standby server, which may + lead to data loss. + + + In logical level, the same information is logged as + with replica, plus information needed to allow + extracting logical change sets from the WAL. Using a level of + logical will increase the WAL volume, particularly if many + tables are configured for REPLICA IDENTITY FULL and + many UPDATE and DELETE statements are + executed. + + + In releases prior to 9.6, this parameter also allowed the + values archive and hot_standby. + These are still accepted but mapped to replica. + + + + + + fsync (boolean) + + fsync configuration parameter + + + + + If this parameter is on, the PostgreSQL server + will try to make sure that updates are physically written to + disk, by issuing fsync() system calls or various + equivalent methods (see ). + This ensures that the database cluster can recover to a + consistent state after an operating system or hardware crash. + + + + While turning off fsync is often a performance + benefit, this can result in unrecoverable data corruption in + the event of a power failure or system crash. Thus it + is only advisable to turn off fsync if + you can easily recreate your entire database from external + data. + + + + Examples of safe circumstances for turning off + fsync include the initial loading of a new + database cluster from a backup file, using a database cluster + for processing a batch of data after which the database + will be thrown away and recreated, + or for a read-only database clone which + gets recreated frequently and is not used for failover. High + quality hardware alone is not a sufficient justification for + turning off fsync. + + + + For reliable recovery when changing fsync + off to on, it is necessary to force all modified buffers in the + kernel to durable storage. This can be done while the cluster + is shutdown or while fsync is on by running initdb + --sync-only, running sync, unmounting the + file system, or rebooting the server. + + + + In many situations, turning off + for noncritical transactions can provide much of the potential + performance benefit of turning off fsync, without + the attendant risks of data corruption. + + + + fsync can only be set in the postgresql.conf + file or on the server command line. + If you turn this parameter off, also consider turning off + . + + + + + + synchronous_commit (enum) + + synchronous_commit configuration parameter + + + + + Specifies how much WAL processing must complete before + the database server returns a success + indication to the client. Valid values are + remote_apply, on + (the default), remote_write, + local, and off. + + + + If synchronous_standby_names is empty, + the only meaningful settings are on and + off; remote_apply, + remote_write and local + all provide the same local synchronization level + as on. The local behavior of all + non-off modes is to wait for local flush of WAL + to disk. In off mode, there is no waiting, + so there can be a delay between when success is reported to the + client and when the transaction is later guaranteed to be safe + against a server crash. (The maximum + delay is three times .) Unlike + , setting this parameter to off + does not create any risk of database inconsistency: an operating + system or database crash might + result in some recent allegedly-committed transactions being lost, but + the database state will be just the same as if those transactions had + been aborted cleanly. So, turning synchronous_commit off + can be a useful alternative when performance is more important than + exact certainty about the durability of a transaction. For more + discussion see . + + + + If is non-empty, + synchronous_commit also controls whether + transaction commits will wait for their WAL records to be + processed on the standby server(s). + + + + When set to remote_apply, commits will wait + until replies from the current synchronous standby(s) indicate they + have received the commit record of the transaction and applied + it, so that it has become visible to queries on the standby(s), + and also written to durable storage on the standbys. This will + cause much larger commit delays than previous settings since + it waits for WAL replay. When set to on, + commits wait until replies + from the current synchronous standby(s) indicate they have received + the commit record of the transaction and flushed it to durable storage. This + ensures the transaction will not be lost unless both the primary and + all synchronous standbys suffer corruption of their database storage. + When set to remote_write, commits will wait until replies + from the current synchronous standby(s) indicate they have + received the commit record of the transaction and written it to + their file systems. This setting ensures data preservation if a standby instance of + PostgreSQL crashes, but not if the standby + suffers an operating-system-level crash because the data has not + necessarily reached durable storage on the standby. + The setting local causes commits to wait for + local flush to disk, but not for replication. This is usually not + desirable when synchronous replication is in use, but is provided for + completeness. + + + + This parameter can be changed at any time; the behavior for any + one transaction is determined by the setting in effect when it + commits. It is therefore possible, and useful, to have some + transactions commit synchronously and others asynchronously. + For example, to make a single multistatement transaction commit + asynchronously when the default is the opposite, issue SET + LOCAL synchronous_commit TO OFF within the transaction. + + + + summarizes the + capabilities of the synchronous_commit settings. + + + + synchronous_commit Modes + + + + + + + + + synchronous_commit setting + local durable commit + standby durable commit after PG crash + standby durable commit after OS crash + standby query consistency + + + + + + + remote_apply + + + + + + + + on + + + + + + + + remote_write + + + + + + + + local + + + + + + + + off + + + + + + + + +
+ +
+
+ + + wal_sync_method (enum) + + wal_sync_method configuration parameter + + + + + Method used for forcing WAL updates out to disk. + If fsync is off then this setting is irrelevant, + since WAL file updates will not be forced out at all. + Possible values are: + + + + + open_datasync (write WAL files with open() option O_DSYNC) + + + + + fdatasync (call fdatasync() at each commit) + + + + + fsync (call fsync() at each commit) + + + + + fsync_writethrough (call fsync() at each commit, forcing write-through of any disk write cache) + + + + + open_sync (write WAL files with open() option O_SYNC) + + + + + The open_* options also use O_DIRECT if available. + Not all of these choices are available on all platforms. + The default is the first method in the above list that is supported + by the platform, except that fdatasync is the default on + Linux and FreeBSD. The default is not necessarily ideal; it might be + necessary to change this setting or other aspects of your system + configuration in order to create a crash-safe configuration or + achieve optimal performance. + These aspects are discussed in . + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + full_page_writes (boolean) + + full_page_writes configuration parameter + + + + + When this parameter is on, the PostgreSQL server + writes the entire content of each disk page to WAL during the + first modification of that page after a checkpoint. + This is needed because + a page write that is in process during an operating system crash might + be only partially completed, leading to an on-disk page + that contains a mix of old and new data. The row-level change data + normally stored in WAL will not be enough to completely restore + such a page during post-crash recovery. Storing the full page image + guarantees that the page can be correctly restored, but at the price + of increasing the amount of data that must be written to WAL. + (Because WAL replay always starts from a checkpoint, it is sufficient + to do this during the first change of each page after a checkpoint. + Therefore, one way to reduce the cost of full-page writes is to + increase the checkpoint interval parameters.) + + + + Turning this parameter off speeds normal operation, but + might lead to either unrecoverable data corruption, or silent + data corruption, after a system failure. The risks are similar to turning off + fsync, though smaller, and it should be turned off + only based on the same circumstances recommended for that parameter. + + + + Turning off this parameter does not affect use of + WAL archiving for point-in-time recovery (PITR) + (see ). + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is on. + + + + + + wal_log_hints (boolean) + + wal_log_hints configuration parameter + + + + + When this parameter is on, the PostgreSQL + server writes the entire content of each disk page to WAL during the + first modification of that page after a checkpoint, even for + non-critical modifications of so-called hint bits. + + + + If data checksums are enabled, hint bit updates are always WAL-logged + and this setting is ignored. You can use this setting to test how much + extra WAL-logging would occur if your database had data checksums + enabled. + + + + This parameter can only be set at server start. The default value is off. + + + + + + wal_compression (boolean) + + wal_compression configuration parameter + + + + + When this parameter is on, the PostgreSQL + server compresses full page images written to WAL when + is on or during a base backup. + A compressed page image will be decompressed during WAL replay. + The default value is off. + Only superusers can change this setting. + + + + Turning this parameter on can reduce the WAL volume without + increasing the risk of unrecoverable data corruption, + but at the cost of some extra CPU spent on the compression during + WAL logging and on the decompression during WAL replay. + + + + + + wal_init_zero (boolean) + + wal_init_zero configuration parameter + + + + + If set to on (the default), this option causes new + WAL files to be filled with zeroes. On some file systems, this ensures + that space is allocated before we need to write WAL records. However, + Copy-On-Write (COW) file systems may not benefit + from this technique, so the option is given to skip the unnecessary + work. If set to off, only the final byte is written + when the file is created so that it has the expected size. + + + + + + wal_recycle (boolean) + + wal_recycle configuration parameter + + + + + If set to on (the default), this option causes WAL + files to be recycled by renaming them, avoiding the need to create new + ones. On COW file systems, it may be faster to create new ones, so the + option is given to disable this behavior. + + + + + + wal_buffers (integer) + + wal_buffers configuration parameter + + + + + The amount of shared memory used for WAL data that has not yet been + written to disk. The default setting of -1 selects a size equal to + 1/32nd (about 3%) of , but not less + than 64kB nor more than the size of one WAL + segment, typically 16MB. This value can be set + manually if the automatic choice is too large or too small, + but any positive value less than 32kB will be + treated as 32kB. + If this value is specified without units, it is taken as WAL blocks, + that is XLOG_BLCKSZ bytes, typically 8kB. + This parameter can only be set at server start. + + + + The contents of the WAL buffers are written out to disk at every + transaction commit, so extremely large values are unlikely to + provide a significant benefit. However, setting this value to at + least a few megabytes can improve write performance on a busy + server where many clients are committing at once. The auto-tuning + selected by the default setting of -1 should give reasonable + results in most cases. + + + + + + + wal_writer_delay (integer) + + wal_writer_delay configuration parameter + + + + + Specifies how often the WAL writer flushes WAL, in time terms. + After flushing WAL the writer sleeps for the length of time given + by wal_writer_delay, unless woken up sooner + by an asynchronously committing transaction. If the last flush + happened less than wal_writer_delay ago and less + than wal_writer_flush_after worth of WAL has been + produced since, then WAL is only written to the operating system, not + flushed to disk. + If this value is specified without units, it is taken as milliseconds. + The default value is 200 milliseconds (200ms). Note that + on many systems, the effective resolution of sleep delays is 10 + milliseconds; setting wal_writer_delay to a value that is + not a multiple of 10 might have the same results as setting it to the + next higher multiple of 10. This parameter can only be set in the + postgresql.conf file or on the server command line. + + + + + + wal_writer_flush_after (integer) + + wal_writer_flush_after configuration parameter + + + + + Specifies how often the WAL writer flushes WAL, in volume terms. + If the last flush happened less + than wal_writer_delay ago and less + than wal_writer_flush_after worth of WAL has been + produced since, then WAL is only written to the operating system, not + flushed to disk. If wal_writer_flush_after is set + to 0 then WAL data is always flushed immediately. + If this value is specified without units, it is taken as WAL blocks, + that is XLOG_BLCKSZ bytes, typically 8kB. + The default is 1MB. + This parameter can only be set in the + postgresql.conf file or on the server command line. + + + + + + wal_skip_threshold (integer) + + wal_skip_threshold configuration parameter + + + + + When wal_level is minimal and a + transaction commits after creating or rewriting a permanent relation, + this setting determines how to persist the new data. If the data is + smaller than this setting, write it to the WAL log; otherwise, use an + fsync of affected files. Depending on the properties of your storage, + raising or lowering this value might help if such commits are slowing + concurrent transactions. If this value is specified without units, it + is taken as kilobytes. The default is two megabytes + (2MB). + + + + + + commit_delay (integer) + + commit_delay configuration parameter + + + + + Setting commit_delay adds a time delay + before a WAL flush is initiated. This can improve + group commit throughput by allowing a larger number of transactions + to commit via a single WAL flush, if system load is high enough + that additional transactions become ready to commit within the + given interval. However, it also increases latency by up to the + commit_delay for each WAL + flush. Because the delay is just wasted if no other transactions + become ready to commit, a delay is only performed if at least + commit_siblings other transactions are active + when a flush is about to be initiated. Also, no delays are + performed if fsync is disabled. + If this value is specified without units, it is taken as microseconds. + The default commit_delay is zero (no delay). + Only superusers can change this setting. + + + In PostgreSQL releases prior to 9.3, + commit_delay behaved differently and was much + less effective: it affected only commits, rather than all WAL flushes, + and waited for the entire configured delay even if the WAL flush + was completed sooner. Beginning in PostgreSQL 9.3, + the first process that becomes ready to flush waits for the configured + interval, while subsequent processes wait only until the leader + completes the flush operation. + + + + + + commit_siblings (integer) + + commit_siblings configuration parameter + + + + + Minimum number of concurrent open transactions to require + before performing the commit_delay delay. A larger + value makes it more probable that at least one other + transaction will become ready to commit during the delay + interval. The default is five transactions. + + + + +
+
+ + Checkpoints + + + + checkpoint_timeout (integer) + + checkpoint_timeout configuration parameter + + + + + Maximum time between automatic WAL checkpoints. + If this value is specified without units, it is taken as seconds. + The valid range is between 30 seconds and one day. + The default is five minutes (5min). + Increasing this parameter can increase the amount of time needed + for crash recovery. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + checkpoint_completion_target (floating point) + + checkpoint_completion_target configuration parameter + + + + + Specifies the target of checkpoint completion, as a fraction of + total time between checkpoints. The default is 0.9, which spreads the + checkpoint across almost all of the available interval, providing fairly + consistent I/O load while also leaving some time for checkpoint + completion overhead. Reducing this parameter is not recommended because + it causes the checkpoint to complete faster. This results in a higher + rate of I/O during the checkpoint followed by a period of less I/O between + the checkpoint completion and the next scheduled checkpoint. This + parameter can only be set in the postgresql.conf file + or on the server command line. + + + + + + checkpoint_flush_after (integer) + + checkpoint_flush_after configuration parameter + + + + + Whenever more than this amount of data has been + written while performing a checkpoint, attempt to force the + OS to issue these writes to the underlying storage. Doing so will + limit the amount of dirty data in the kernel's page cache, reducing + the likelihood of stalls when an fsync is issued at the end of the + checkpoint, or when the OS writes data back in larger batches in the + background. Often that will result in greatly reduced transaction + latency, but there also are some cases, especially with workloads + that are bigger than , but smaller + than the OS's page cache, where performance might degrade. This + setting may have no effect on some platforms. + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + The valid range is + between 0, which disables forced writeback, + and 2MB. The default is 256kB on + Linux, 0 elsewhere. (If BLCKSZ is not + 8kB, the default and maximum values scale proportionally to it.) + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + checkpoint_warning (integer) + + checkpoint_warning configuration parameter + + + + + Write a message to the server log if checkpoints caused by + the filling of WAL segment files happen closer together + than this amount of time (which suggests that + max_wal_size ought to be raised). + If this value is specified without units, it is taken as seconds. + The default is 30 seconds (30s). + Zero disables the warning. + No warnings will be generated if checkpoint_timeout + is less than checkpoint_warning. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + max_wal_size (integer) + + max_wal_size configuration parameter + + + + + Maximum size to let the WAL grow during automatic + checkpoints. This is a soft limit; WAL size can exceed + max_wal_size under special circumstances, such as + heavy load, a failing archive_command, or a high + wal_keep_size setting. + If this value is specified without units, it is taken as megabytes. + The default is 1 GB. + Increasing this parameter can increase the amount of time needed for + crash recovery. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + min_wal_size (integer) + + min_wal_size configuration parameter + + + + + As long as WAL disk usage stays below this setting, old WAL files are + always recycled for future use at a checkpoint, rather than removed. + This can be used to ensure that enough WAL space is reserved to + handle spikes in WAL usage, for example when running large batch + jobs. + If this value is specified without units, it is taken as megabytes. + The default is 80 MB. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + Archiving + + + + archive_mode (enum) + + archive_mode configuration parameter + + + + + When archive_mode is enabled, completed WAL segments + are sent to archive storage by setting + . In addition to off, + to disable, there are two modes: on, and + always. During normal operation, there is no + difference between the two modes, but when set to always + the WAL archiver is enabled also during archive recovery or standby + mode. In always mode, all files restored from the archive + or streamed with streaming replication will be archived (again). See + for details. + + + archive_mode and archive_command are + separate variables so that archive_command can be + changed without leaving archiving mode. + This parameter can only be set at server start. + archive_mode cannot be enabled when + wal_level is set to minimal. + + + + + + archive_command (string) + + archive_command configuration parameter + + + + + The local shell command to execute to archive a completed WAL file + segment. Any %p in the string is + replaced by the path name of the file to archive, and any + %f is replaced by only the file name. + (The path name is relative to the working directory of the server, + i.e., the cluster's data directory.) + Use %% to embed an actual % character in the + command. It is important for the command to return a zero + exit status only if it succeeds. For more information see + . + + + This parameter can only be set in the postgresql.conf + file or on the server command line. It is ignored unless + archive_mode was enabled at server start. + If archive_command is an empty string (the default) while + archive_mode is enabled, WAL archiving is temporarily + disabled, but the server continues to accumulate WAL segment files in + the expectation that a command will soon be provided. Setting + archive_command to a command that does nothing but + return true, e.g., /bin/true (REM on + Windows), effectively disables + archiving, but also breaks the chain of WAL files needed for + archive recovery, so it should only be used in unusual circumstances. + + + + + + archive_timeout (integer) + + archive_timeout configuration parameter + + + + + The is only invoked for + completed WAL segments. Hence, if your server generates little WAL + traffic (or has slack periods where it does so), there could be a + long delay between the completion of a transaction and its safe + recording in archive storage. To limit how old unarchived + data can be, you can set archive_timeout to force the + server to switch to a new WAL segment file periodically. When this + parameter is greater than zero, the server will switch to a new + segment file whenever this amount of time has elapsed since the last + segment file switch, and there has been any database activity, + including a single checkpoint (checkpoints are skipped if there is + no database activity). Note that archived files that are closed + early due to a forced switch are still the same length as completely + full files. Therefore, it is unwise to use a very short + archive_timeout — it will bloat your archive + storage. archive_timeout settings of a minute or so are + usually reasonable. You should consider using streaming replication, + instead of archiving, if you want data to be copied off the primary + server more quickly than that. + If this value is specified without units, it is taken as seconds. + This parameter can only be set in the + postgresql.conf file or on the server command line. + + + + + + + + + + Archive Recovery + + + configuration + of recovery + of a standby server + + + + This section describes the settings that apply only for the duration of + the recovery. They must be reset for any subsequent recovery you wish to + perform. + + + + Recovery covers using the server as a standby or for + executing a targeted recovery. Typically, standby mode would be used to + provide high availability and/or read scalability, whereas a targeted + recovery is used to recover from data loss. + + + + To start the server in standby mode, create a file called + standby.signalstandby.signal + in the data directory. The server will enter recovery and will not stop + recovery when the end of archived WAL is reached, but will keep trying to + continue recovery by connecting to the sending server as specified by the + primary_conninfo setting and/or by fetching new WAL + segments using restore_command. For this mode, the + parameters from this section and are of interest. + Parameters from will + also be applied but are typically not useful in this mode. + + + + To start the server in targeted recovery mode, create a file called + recovery.signalrecovery.signal + in the data directory. If both standby.signal and + recovery.signal files are created, standby mode + takes precedence. Targeted recovery mode ends when the archived WAL is + fully replayed, or when recovery_target is reached. + In this mode, the parameters from both this section and will be used. + + + + + restore_command (string) + + restore_command configuration parameter + + + + + The local shell command to execute to retrieve an archived segment of + the WAL file series. This parameter is required for archive recovery, + but optional for streaming replication. + Any %f in the string is + replaced by the name of the file to retrieve from the archive, + and any %p is replaced by the copy destination path name + on the server. + (The path name is relative to the current working directory, + i.e., the cluster's data directory.) + Any %r is replaced by the name of the file containing the + last valid restart point. That is the earliest file that must be kept + to allow a restore to be restartable, so this information can be used + to truncate the archive to just the minimum required to support + restarting from the current restore. %r is typically only + used by warm-standby configurations + (see ). + Write %% to embed an actual % character. + + + + It is important for the command to return a zero exit status + only if it succeeds. The command will be asked for file + names that are not present in the archive; it must return nonzero + when so asked. Examples: + +restore_command = 'cp /mnt/server/archivedir/%f "%p"' +restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows + + An exception is that if the command was terminated by a signal (other + than SIGTERM, which is used as part of a + database server shutdown) or an error by the shell (such as command + not found), then recovery will abort and the server will not start up. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + archive_cleanup_command (string) + + archive_cleanup_command configuration parameter + + + + + This optional parameter specifies a shell command that will be executed + at every restartpoint. The purpose of + archive_cleanup_command is to provide a mechanism for + cleaning up old archived WAL files that are no longer needed by the + standby server. + Any %r is replaced by the name of the file containing the + last valid restart point. + That is the earliest file that must be kept to allow a + restore to be restartable, and so all files earlier than %r + may be safely removed. + This information can be used to truncate the archive to just the + minimum required to support restart from the current restore. + The module + is often used in archive_cleanup_command for + single-standby configurations, for example: +archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' + Note however that if multiple standby servers are restoring from the + same archive directory, you will need to ensure that you do not delete + WAL files until they are no longer needed by any of the servers. + archive_cleanup_command would typically be used in a + warm-standby configuration (see ). + Write %% to embed an actual % character in the + command. + + + If the command returns a nonzero exit status then a warning log + message will be written. An exception is that if the command was + terminated by a signal or an error by the shell (such as command not + found), a fatal error will be raised. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + recovery_end_command (string) + + recovery_end_command configuration parameter + + + + + This parameter specifies a shell command that will be executed once only + at the end of recovery. This parameter is optional. The purpose of the + recovery_end_command is to provide a mechanism for cleanup + following replication or recovery. + Any %r is replaced by the name of the file containing the + last valid restart point, like in . + + + If the command returns a nonzero exit status then a warning log + message will be written and the database will proceed to start up + anyway. An exception is that if the command was terminated by a + signal or an error by the shell (such as command not found), the + database will not proceed with startup. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + + + + Recovery Target + + + By default, recovery will recover to the end of the WAL log. The + following parameters can be used to specify an earlier stopping point. + At most one of recovery_target, + recovery_target_lsn, recovery_target_name, + recovery_target_time, or recovery_target_xid + can be used; if more than one of these is specified in the configuration + file, an error will be raised. + These parameters can only be set at server start. + + + + + recovery_target = 'immediate' + + recovery_target configuration parameter + + + + + This parameter specifies that recovery should end as soon as a + consistent state is reached, i.e., as early as possible. When restoring + from an online backup, this means the point where taking the backup + ended. + + + Technically, this is a string parameter, but 'immediate' + is currently the only allowed value. + + + + + + recovery_target_name (string) + + recovery_target_name configuration parameter + + + + + This parameter specifies the named restore point (created with + pg_create_restore_point()) to which recovery will proceed. + + + + + + recovery_target_time (timestamp) + + recovery_target_time configuration parameter + + + + + This parameter specifies the time stamp up to which recovery + will proceed. + The precise stopping point is also influenced by + . + + + + The value of this parameter is a time stamp in the same format + accepted by the timestamp with time zone data type, + except that you cannot use a time zone abbreviation (unless the + variable has been set + earlier in the configuration file). Preferred style is to use a + numeric offset from UTC, or you can write a full time zone name, + e.g., Europe/Helsinki not EEST. + + + + + + recovery_target_xid (string) + + recovery_target_xid configuration parameter + + + + + This parameter specifies the transaction ID up to which recovery + will proceed. Keep in mind + that while transaction IDs are assigned sequentially at transaction + start, transactions can complete in a different numeric order. + The transactions that will be recovered are those that committed + before (and optionally including) the specified one. + The precise stopping point is also influenced by + . + + + + + + recovery_target_lsn (pg_lsn) + + recovery_target_lsn configuration parameter + + + + + This parameter specifies the LSN of the write-ahead log location up + to which recovery will proceed. The precise stopping point is also + influenced by . This + parameter is parsed using the system data type + pg_lsn. + + + + + + + The following options further specify the recovery target, and affect + what happens when the target is reached: + + + + + recovery_target_inclusive (boolean) + + recovery_target_inclusive configuration parameter + + + + + Specifies whether to stop just after the specified recovery target + (on), or just before the recovery target + (off). + Applies when , + , or + is specified. + This setting controls whether transactions + having exactly the target WAL location (LSN), commit time, or transaction ID, respectively, will + be included in the recovery. Default is on. + + + + + + recovery_target_timeline (string) + + recovery_target_timeline configuration parameter + + + + + Specifies recovering into a particular timeline. The value can be a + numeric timeline ID or a special value. The value + current recovers along the same timeline that was + current when the base backup was taken. The + value latest recovers + to the latest timeline found in the archive, which is useful in + a standby server. latest is the default. + + + + You usually only need to set this parameter + in complex re-recovery situations, where you need to return to + a state that itself was reached after a point-in-time recovery. + See for discussion. + + + + + + recovery_target_action (enum) + + recovery_target_action configuration parameter + + + + + Specifies what action the server should take once the recovery target is + reached. The default is pause, which means recovery will + be paused. promote means the recovery process will finish + and the server will start to accept connections. + Finally shutdown will stop the server after reaching the + recovery target. + + + The intended use of the pause setting is to allow queries + to be executed against the database to check if this recovery target + is the most desirable point for recovery. + The paused state can be resumed by + using pg_wal_replay_resume() (see + ), which then + causes recovery to end. If this recovery target is not the + desired stopping point, then shut down the server, change the + recovery target settings to a later target and restart to + continue recovery. + + + The shutdown setting is useful to have the instance ready + at the exact replay point desired. The instance will still be able to + replay more WAL records (and in fact will have to replay WAL records + since the last checkpoint next time it is started). + + + Note that because recovery.signal will not be + removed when recovery_target_action is set to shutdown, + any subsequent start will end with immediate shutdown unless the + configuration is changed or the recovery.signal + file is removed manually. + + + This setting has no effect if no recovery target is set. + If is not enabled, a setting of + pause will act the same as shutdown. + If the recovery target is reached while a promotion is ongoing, + a setting of pause will act the same as + promote. + + + In any case, if a recovery target is configured but the archive + recovery ends before the target is reached, the server will shut down + with a fatal error. + + + + + + + +
+ + + Replication + + + These settings control the behavior of the built-in + streaming replication feature (see + ). Servers will be either a + primary or a standby server. Primaries can send data, while standbys + are always receivers of replicated data. When cascading replication + (see ) is used, standby servers + can also be senders, as well as receivers. + Parameters are mainly for sending and standby servers, though some + parameters have meaning only on the primary server. Settings may vary + across the cluster without problems if that is required. + + + + Sending Servers + + + These parameters can be set on any server that is + to send replication data to one or more standby servers. + The primary is always a sending server, so these parameters must + always be set on the primary. + The role and meaning of these parameters does not change after a + standby becomes the primary. + + + + + max_wal_senders (integer) + + max_wal_senders configuration parameter + + + + + Specifies the maximum number of concurrent connections from standby + servers or streaming base backup clients (i.e., the maximum number of + simultaneously running WAL sender processes). The default is + 10. The value 0 means + replication is disabled. Abrupt disconnection of a streaming client might + leave an orphaned connection slot behind until a timeout is reached, + so this parameter should be set slightly higher than the maximum + number of expected clients so disconnected clients can immediately + reconnect. This parameter can only be set at server start. Also, + wal_level must be set to + replica or higher to allow connections from standby + servers. + + + + When running a standby server, you must set this parameter to the + same or higher value than on the primary server. Otherwise, queries + will not be allowed in the standby server. + + + + + + max_replication_slots (integer) + + max_replication_slots configuration parameter + + + + + Specifies the maximum number of replication slots + (see ) that the server + can support. The default is 10. This parameter can only be set at + server start. + Setting it to a lower value than the number of currently + existing replication slots will prevent the server from starting. + Also, wal_level must be set + to replica or higher to allow replication slots to + be used. + + + + On the subscriber side, specifies how many replication origins (see + ) can be tracked simultaneously, + effectively limiting how many logical replication subscriptions can + be created on the server. Setting it to a lower value than the current + number of tracked replication origins (reflected in + pg_replication_origin_status, + not pg_replication_origin) + will prevent the server from starting. + + + + + + wal_keep_size (integer) + + wal_keep_size configuration parameter + + + + + Specifies the minimum size of past log file segments kept in the + pg_wal + directory, in case a standby server needs to fetch them for streaming + replication. If a standby + server connected to the sending server falls behind by more than + wal_keep_size megabytes, the sending server might + remove a WAL segment still needed by the standby, in which case the + replication connection will be terminated. Downstream connections + will also eventually fail as a result. (However, the standby + server can recover by fetching the segment from archive, if WAL + archiving is in use.) + + + + This sets only the minimum size of segments retained in + pg_wal; the system might need to retain more segments + for WAL archival or to recover from a checkpoint. If + wal_keep_size is zero (the default), the system + doesn't keep any extra segments for standby purposes, so the number + of old WAL segments available to standby servers is a function of + the location of the previous checkpoint and status of WAL + archiving. + If this value is specified without units, it is taken as megabytes. + This parameter can only be set in the + postgresql.conf file or on the server command line. + + + + + + max_slot_wal_keep_size (integer) + + max_slot_wal_keep_size configuration parameter + + + + + Specify the maximum size of WAL files + that replication + slots are allowed to retain in the pg_wal + directory at checkpoint time. + If max_slot_wal_keep_size is -1 (the default), + replication slots may retain an unlimited amount of WAL files. Otherwise, if + restart_lsn of a replication slot falls behind the current LSN by more + than the given size, the standby using the slot may no longer be able + to continue replication due to removal of required WAL files. You + can see the WAL availability of replication slots + in pg_replication_slots. + + + + + + wal_sender_timeout (integer) + + wal_sender_timeout configuration parameter + + + + + Terminate replication connections that are inactive for longer + than this amount of time. This is useful for + the sending server to detect a standby crash or network outage. + If this value is specified without units, it is taken as milliseconds. + The default value is 60 seconds. + A value of zero disables the timeout mechanism. + + + With a cluster distributed across multiple geographic + locations, using different values per location brings more flexibility + in the cluster management. A smaller value is useful for faster + failure detection with a standby having a low-latency network + connection, and a larger value helps in judging better the health + of a standby if located on a remote location, with a high-latency + network connection. + + + + + + track_commit_timestamp (boolean) + + track_commit_timestamp configuration parameter + + + + + Record commit time of transactions. This parameter + can only be set in postgresql.conf file or on the server + command line. The default value is off. + + + + + + + + + Primary Server + + + These parameters can be set on the primary server that is + to send replication data to one or more standby servers. + Note that in addition to these parameters, + must be set appropriately on the primary + server, and optionally WAL archiving can be enabled as + well (see ). + The values of these parameters on standby servers are irrelevant, + although you may wish to set them there in preparation for the + possibility of a standby becoming the primary. + + + + + + synchronous_standby_names (string) + + synchronous_standby_names configuration parameter + + + + + Specifies a list of standby servers that can support + synchronous replication, as described in + . + There will be one or more active synchronous standbys; + transactions waiting for commit will be allowed to proceed after + these standby servers confirm receipt of their data. + The synchronous standbys will be those whose names appear + in this list, and + that are both currently connected and streaming data in real-time + (as shown by a state of streaming in the + + pg_stat_replication view). + Specifying more than one synchronous standby can allow for very high + availability and protection against data loss. + + + The name of a standby server for this purpose is the + application_name setting of the standby, as set in the + standby's connection information. In case of a physical replication + standby, this should be set in the primary_conninfo + setting; the default is the setting of + if set, else walreceiver. + For logical replication, this can be set in the connection + information of the subscription, and it defaults to the + subscription name. For other replication stream consumers, + consult their documentation. + + + This parameter specifies a list of standby servers using + either of the following syntaxes: + +[FIRST] num_sync ( standby_name [, ...] ) +ANY num_sync ( standby_name [, ...] ) +standby_name [, ...] + + where num_sync is + the number of synchronous standbys that transactions need to + wait for replies from, + and standby_name + is the name of a standby server. + FIRST and ANY specify the method to choose + synchronous standbys from the listed servers. + + + The keyword FIRST, coupled with + num_sync, specifies a + priority-based synchronous replication and makes transaction commits + wait until their WAL records are replicated to + num_sync synchronous + standbys chosen based on their priorities. For example, a setting of + FIRST 3 (s1, s2, s3, s4) will cause each commit to wait for + replies from three higher-priority standbys chosen from standby servers + s1, s2, s3 and s4. + The standbys whose names appear earlier in the list are given higher + priority and will be considered as synchronous. Other standby servers + appearing later in this list represent potential synchronous standbys. + If any of the current synchronous standbys disconnects for whatever + reason, it will be replaced immediately with the next-highest-priority + standby. The keyword FIRST is optional. + + + The keyword ANY, coupled with + num_sync, specifies a + quorum-based synchronous replication and makes transaction commits + wait until their WAL records are replicated to at least + num_sync listed standbys. + For example, a setting of ANY 3 (s1, s2, s3, s4) will cause + each commit to proceed as soon as at least any three standbys of + s1, s2, s3 and s4 + reply. + + + FIRST and ANY are case-insensitive. If these + keywords are used as the name of a standby server, + its standby_name must + be double-quoted. + + + The third syntax was used before PostgreSQL + version 9.6 and is still supported. It's the same as the first syntax + with FIRST and + num_sync equal to 1. + For example, FIRST 1 (s1, s2) and s1, s2 have + the same meaning: either s1 or s2 is chosen + as a synchronous standby. + + + The special entry * matches any standby name. + + + There is no mechanism to enforce uniqueness of standby names. In case + of duplicates one of the matching standbys will be considered as + higher priority, though exactly which one is indeterminate. + + + + Each standby_name + should have the form of a valid SQL identifier, unless it + is *. You can use double-quoting if necessary. But note + that standby_names are + compared to standby application names case-insensitively, whether + double-quoted or not. + + + + If no synchronous standby names are specified here, then synchronous + replication is not enabled and transaction commits will not wait for + replication. This is the default configuration. Even when + synchronous replication is enabled, individual transactions can be + configured not to wait for replication by setting the + parameter to + local or off. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + vacuum_defer_cleanup_age (integer) + + vacuum_defer_cleanup_age configuration parameter + + + + + Specifies the number of transactions by which VACUUM and + HOT updates will defer cleanup of dead row versions. The + default is zero transactions, meaning that dead row versions can be + removed as soon as possible, that is, as soon as they are no longer + visible to any open transaction. You may wish to set this to a + non-zero value on a primary server that is supporting hot standby + servers, as described in . This allows + more time for queries on the standby to complete without incurring + conflicts due to early cleanup of rows. However, since the value + is measured in terms of number of write transactions occurring on the + primary server, it is difficult to predict just how much additional + grace time will be made available to standby queries. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + You should also consider setting hot_standby_feedback + on standby server(s) as an alternative to using this parameter. + + + This does not prevent cleanup of dead rows which have reached the age + specified by old_snapshot_threshold. + + + + + + + + + Standby Servers + + + These settings control the behavior of a + standby server + that is + to receive replication data. Their values on the primary server + are irrelevant. + + + + + + primary_conninfo (string) + + primary_conninfo configuration parameter + + + + + Specifies a connection string to be used for the standby server + to connect with a sending server. This string is in the format + described in . If any option is + unspecified in this string, then the corresponding environment + variable (see ) is checked. If the + environment variable is not set either, then + defaults are used. + + + The connection string should specify the host name (or address) + of the sending server, as well as the port number if it is not + the same as the standby server's default. + Also specify a user name corresponding to a suitably-privileged role + on the sending server (see + ). + A password needs to be provided too, if the sender demands password + authentication. It can be provided in the + primary_conninfo string, or in a separate + ~/.pgpass file on the standby server (use + replication as the database name). + Do not specify a database name in the + primary_conninfo string. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + If this parameter is changed while the WAL receiver process is + running, that process is signaled to shut down and expected to + restart with the new setting (except if primary_conninfo + is an empty string). + This setting has no effect if the server is not in standby mode. + + + + + primary_slot_name (string) + + primary_slot_name configuration parameter + + + + + Optionally specifies an existing replication slot to be used when + connecting to the sending server via streaming replication to control + resource removal on the upstream node + (see ). + This parameter can only be set in the postgresql.conf + file or on the server command line. + If this parameter is changed while the WAL receiver process is running, + that process is signaled to shut down and expected to restart with the + new setting. + This setting has no effect if primary_conninfo is not + set or the server is not in standby mode. + + + + + + promote_trigger_file (string) + + promote_trigger_file configuration parameter + + + + + Specifies a trigger file whose presence ends recovery in the + standby. Even if this value is not set, you can still promote + the standby using pg_ctl promote or calling + pg_promote(). + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + hot_standby (boolean) + + hot_standby configuration parameter + + + + + Specifies whether or not you can connect and run queries during + recovery, as described in . + The default value is on. + This parameter can only be set at server start. It only has effect + during archive recovery or in standby mode. + + + + + + max_standby_archive_delay (integer) + + max_standby_archive_delay configuration parameter + + + + + When Hot Standby is active, this parameter determines how long the + standby server should wait before canceling standby queries that + conflict with about-to-be-applied WAL entries, as described in + . + max_standby_archive_delay applies when WAL data is + being read from WAL archive (and is therefore not current). + If this value is specified without units, it is taken as milliseconds. + The default is 30 seconds. + A value of -1 allows the standby to wait forever for conflicting + queries to complete. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + Note that max_standby_archive_delay is not the same as the + maximum length of time a query can run before cancellation; rather it + is the maximum total time allowed to apply any one WAL segment's data. + Thus, if one query has resulted in significant delay earlier in the + WAL segment, subsequent conflicting queries will have much less grace + time. + + + + + + max_standby_streaming_delay (integer) + + max_standby_streaming_delay configuration parameter + + + + + When Hot Standby is active, this parameter determines how long the + standby server should wait before canceling standby queries that + conflict with about-to-be-applied WAL entries, as described in + . + max_standby_streaming_delay applies when WAL data is + being received via streaming replication. + If this value is specified without units, it is taken as milliseconds. + The default is 30 seconds. + A value of -1 allows the standby to wait forever for conflicting + queries to complete. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + Note that max_standby_streaming_delay is not the same as + the maximum length of time a query can run before cancellation; rather + it is the maximum total time allowed to apply WAL data once it has + been received from the primary server. Thus, if one query has + resulted in significant delay, subsequent conflicting queries will + have much less grace time until the standby server has caught up + again. + + + + + + wal_receiver_create_temp_slot (boolean) + + wal_receiver_create_temp_slot configuration parameter + + + + + Specifies whether the WAL receiver process should create a temporary replication + slot on the remote instance when no permanent replication slot to use + has been configured (using ). + The default is off. This parameter can only be set in the + postgresql.conf file or on the server command line. + If this parameter is changed while the WAL receiver process is running, + that process is signaled to shut down and expected to restart with + the new setting. + + + + + + wal_receiver_status_interval (integer) + + wal_receiver_status_interval configuration parameter + + + + + Specifies the minimum frequency for the WAL receiver + process on the standby to send information about replication progress + to the primary or upstream standby, where it can be seen using the + + pg_stat_replication + view. The standby will report + the last write-ahead log location it has written, the last position it + has flushed to disk, and the last position it has applied. + This parameter's value is the maximum amount of time between reports. + Updates are sent each time the write or flush positions change, or as + often as specified by this parameter if set to a non-zero value. + There are additional cases where updates are sent while ignoring this + parameter; for example, when processing of the existing WAL completes + or when synchronous_commit is set to + remote_apply. + Thus, the apply position may lag slightly behind the true position. + If this value is specified without units, it is taken as seconds. + The default value is 10 seconds. This parameter can only be set in + the postgresql.conf file or on the server + command line. + + + + + + hot_standby_feedback (boolean) + + hot_standby_feedback configuration parameter + + + + + Specifies whether or not a hot standby will send feedback to the primary + or upstream standby + about queries currently executing on the standby. This parameter can + be used to eliminate query cancels caused by cleanup records, but + can cause database bloat on the primary for some workloads. + Feedback messages will not be sent more frequently than once per + wal_receiver_status_interval. The default value is + off. This parameter can only be set in the + postgresql.conf file or on the server command line. + + + If cascaded replication is in use the feedback is passed upstream + until it eventually reaches the primary. Standbys make no other use + of feedback they receive other than to pass upstream. + + + This setting does not override the behavior of + old_snapshot_threshold on the primary; a snapshot on the + standby which exceeds the primary's age threshold can become invalid, + resulting in cancellation of transactions on the standby. This is + because old_snapshot_threshold is intended to provide an + absolute limit on the time which dead rows can contribute to bloat, + which would otherwise be violated because of the configuration of a + standby. + + + + + + wal_receiver_timeout (integer) + + wal_receiver_timeout configuration parameter + + + + + Terminate replication connections that are inactive for longer + than this amount of time. This is useful for + the receiving standby server to detect a primary node crash or network + outage. + If this value is specified without units, it is taken as milliseconds. + The default value is 60 seconds. + A value of zero disables the timeout mechanism. + This parameter can only be set in + the postgresql.conf file or on the server + command line. + + + + + + wal_retrieve_retry_interval (integer) + + wal_retrieve_retry_interval configuration parameter + + + + + Specifies how long the standby server should wait when WAL data is not + available from any sources (streaming replication, + local pg_wal or WAL archive) before trying + again to retrieve WAL data. + If this value is specified without units, it is taken as milliseconds. + The default value is 5 seconds. + This parameter can only be set in + the postgresql.conf file or on the server + command line. + + + This parameter is useful in configurations where a node in recovery + needs to control the amount of time to wait for new WAL data to be + available. For example, in archive recovery, it is possible to + make the recovery more responsive in the detection of a new WAL + log file by reducing the value of this parameter. On a system with + low WAL activity, increasing it reduces the amount of requests necessary + to access WAL archives, something useful for example in cloud + environments where the amount of times an infrastructure is accessed + is taken into account. + + + + + + recovery_min_apply_delay (integer) + + recovery_min_apply_delay configuration parameter + + + + + By default, a standby server restores WAL records from the + sending server as soon as possible. It may be useful to have a time-delayed + copy of the data, offering opportunities to correct data loss errors. + This parameter allows you to delay recovery by a specified amount + of time. For example, if + you set this parameter to 5min, the standby will + replay each transaction commit only when the system time on the standby + is at least five minutes past the commit time reported by the primary. + If this value is specified without units, it is taken as milliseconds. + The default is zero, adding no delay. + + + It is possible that the replication delay between servers exceeds the + value of this parameter, in which case no delay is added. + Note that the delay is calculated between the WAL time stamp as written + on primary and the current time on the standby. Delays in transfer + because of network lag or cascading replication configurations + may reduce the actual wait time significantly. If the system + clocks on primary and standby are not synchronized, this may lead to + recovery applying records earlier than expected; but that is not a + major issue because useful settings of this parameter are much larger + than typical time deviations between servers. + + + The delay occurs only on WAL records for transaction commits. + Other records are replayed as quickly as possible, which + is not a problem because MVCC visibility rules ensure their effects + are not visible until the corresponding commit record is applied. + + + The delay occurs once the database in recovery has reached a consistent + state, until the standby is promoted or triggered. After that the standby + will end recovery without further waiting. + + + This parameter is intended for use with streaming replication deployments; + however, if the parameter is specified it will be honored in all cases + except crash recovery. + + hot_standby_feedback will be delayed by use of this feature + which could lead to bloat on the primary; use both together with care. + + + + Synchronous replication is affected by this setting when synchronous_commit + is set to remote_apply; every COMMIT + will need to wait to be applied. + + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + + Subscribers + + + These settings control the behavior of a logical replication subscriber. + Their values on the publisher are irrelevant. + + + + Note that wal_receiver_timeout, + wal_receiver_status_interval and + wal_retrieve_retry_interval configuration parameters + affect the logical replication workers as well. + + + + + + max_logical_replication_workers (int) + + max_logical_replication_workers configuration parameter + + + + + Specifies maximum number of logical replication workers. This includes + both apply workers and table synchronization workers. + + + Logical replication workers are taken from the pool defined by + max_worker_processes. + + + The default value is 4. This parameter can only be set at server + start. + + + + + + max_sync_workers_per_subscription (integer) + + max_sync_workers_per_subscription configuration parameter + + + + + Maximum number of synchronization workers per subscription. This + parameter controls the amount of parallelism of the initial data copy + during the subscription initialization or when new tables are added. + + + Currently, there can be only one synchronization worker per table. + + + The synchronization workers are taken from the pool defined by + max_logical_replication_workers. + + + The default value is 2. This parameter can only be set in the + postgresql.conf file or on the server command + line. + + + + + + + + + + + Query Planning + + + Planner Method Configuration + + + These configuration parameters provide a crude method of + influencing the query plans chosen by the query optimizer. If + the default plan chosen by the optimizer for a particular query + is not optimal, a temporary solution is to use one + of these configuration parameters to force the optimizer to + choose a different plan. + Better ways to improve the quality of the + plans chosen by the optimizer include adjusting the planner cost + constants (see ), + running ANALYZE manually, increasing + the value of the configuration parameter, + and increasing the amount of statistics collected for + specific columns using ALTER TABLE SET + STATISTICS. + + + + + enable_async_append (boolean) + + enable_async_append configuration parameter + + + + + Enables or disables the query planner's use of async-aware + append plan types. The default is on. + + + + + + enable_bitmapscan (boolean) + + bitmap scan + + + enable_bitmapscan configuration parameter + + + + + Enables or disables the query planner's use of bitmap-scan plan + types. The default is on. + + + + + + enable_gathermerge (boolean) + + enable_gathermerge configuration parameter + + + + + Enables or disables the query planner's use of gather + merge plan types. The default is on. + + + + + + enable_hashagg (boolean) + + enable_hashagg configuration parameter + + + + + Enables or disables the query planner's use of hashed + aggregation plan types. The default is on. + + + + + + enable_hashjoin (boolean) + + enable_hashjoin configuration parameter + + + + + Enables or disables the query planner's use of hash-join plan + types. The default is on. + + + + + + enable_incremental_sort (boolean) + + enable_incremental_sort configuration parameter + + + + + Enables or disables the query planner's use of incremental sort steps. + The default is on. + + + + + + enable_indexscan (boolean) + + index scan + + + enable_indexscan configuration parameter + + + + + Enables or disables the query planner's use of index-scan plan + types. The default is on. + + + + + + enable_indexonlyscan (boolean) + + enable_indexonlyscan configuration parameter + + + + + Enables or disables the query planner's use of index-only-scan plan + types (see ). + The default is on. + + + + + + enable_material (boolean) + + enable_material configuration parameter + + + + + Enables or disables the query planner's use of materialization. + It is impossible to suppress materialization entirely, + but turning this variable off prevents the planner from inserting + materialize nodes except in cases where it is required for correctness. + The default is on. + + + + + + enable_resultcache (boolean) + + enable_resultcache configuration parameter + + + + + Enables or disables the query planner's use of result cache plans for + caching results from parameterized scans inside nested-loop joins. + This plan type allows scans to the underlying plans to be skipped when + the results for the current parameters are already in the cache. Less + commonly looked up results may be evicted from the cache when more + space is required for new entries. The default is + on. + + + + + + enable_mergejoin (boolean) + + enable_mergejoin configuration parameter + + + + + Enables or disables the query planner's use of merge-join plan + types. The default is on. + + + + + + enable_nestloop (boolean) + + enable_nestloop configuration parameter + + + + + Enables or disables the query planner's use of nested-loop join + plans. It is impossible to suppress nested-loop joins entirely, + but turning this variable off discourages the planner from using + one if there are other methods available. The default is + on. + + + + + + enable_parallel_append (boolean) + + enable_parallel_append configuration parameter + + + + + Enables or disables the query planner's use of parallel-aware + append plan types. The default is on. + + + + + + enable_parallel_hash (boolean) + + enable_parallel_hash configuration parameter + + + + + Enables or disables the query planner's use of hash-join plan + types with parallel hash. Has no effect if hash-join plans are not + also enabled. The default is on. + + + + + + enable_partition_pruning (boolean) + + enable_partition_pruning configuration parameter + + + + + Enables or disables the query planner's ability to eliminate a + partitioned table's partitions from query plans. This also controls + the planner's ability to generate query plans which allow the query + executor to remove (ignore) partitions during query execution. The + default is on. + See for details. + + + + + + enable_partitionwise_join (boolean) + + enable_partitionwise_join configuration parameter + + + + + Enables or disables the query planner's use of partitionwise join, + which allows a join between partitioned tables to be performed by + joining the matching partitions. Partitionwise join currently applies + only when the join conditions include all the partition keys, which + must be of the same data type and have one-to-one matching sets of + child partitions. Because partitionwise join planning can use + significantly more CPU time and memory during planning, the default is + off. + + + + + + enable_partitionwise_aggregate (boolean) + + enable_partitionwise_aggregate configuration parameter + + + + + Enables or disables the query planner's use of partitionwise grouping + or aggregation, which allows grouping or aggregation on a partitioned + tables performed separately for each partition. If the GROUP + BY clause does not include the partition keys, only partial + aggregation can be performed on a per-partition basis, and + finalization must be performed later. Because partitionwise grouping + or aggregation can use significantly more CPU time and memory during + planning, the default is off. + + + + + + enable_seqscan (boolean) + + sequential scan + + + enable_seqscan configuration parameter + + + + + Enables or disables the query planner's use of sequential scan + plan types. It is impossible to suppress sequential scans + entirely, but turning this variable off discourages the planner + from using one if there are other methods available. The + default is on. + + + + + + enable_sort (boolean) + + enable_sort configuration parameter + + + + + Enables or disables the query planner's use of explicit sort + steps. It is impossible to suppress explicit sorts entirely, + but turning this variable off discourages the planner from + using one if there are other methods available. The default + is on. + + + + + + enable_tidscan (boolean) + + enable_tidscan configuration parameter + + + + + Enables or disables the query planner's use of TID + scan plan types. The default is on. + + + + + + + + Planner Cost Constants + + + The cost variables described in this section are measured + on an arbitrary scale. Only their relative values matter, hence + scaling them all up or down by the same factor will result in no change + in the planner's choices. By default, these cost variables are based on + the cost of sequential page fetches; that is, + seq_page_cost is conventionally set to 1.0 + and the other cost variables are set with reference to that. But + you can use a different scale if you prefer, such as actual execution + times in milliseconds on a particular machine. + + + + + Unfortunately, there is no well-defined method for determining ideal + values for the cost variables. They are best treated as averages over + the entire mix of queries that a particular installation will receive. This + means that changing them on the basis of just a few experiments is very + risky. + + + + + + + seq_page_cost (floating point) + + seq_page_cost configuration parameter + + + + + Sets the planner's estimate of the cost of a disk page fetch + that is part of a series of sequential fetches. The default is 1.0. + This value can be overridden for tables and indexes in a particular + tablespace by setting the tablespace parameter of the same name + (see ). + + + + + + random_page_cost (floating point) + + random_page_cost configuration parameter + + + + + Sets the planner's estimate of the cost of a + non-sequentially-fetched disk page. The default is 4.0. + This value can be overridden for tables and indexes in a particular + tablespace by setting the tablespace parameter of the same name + (see ). + + + + Reducing this value relative to seq_page_cost + will cause the system to prefer index scans; raising it will + make index scans look relatively more expensive. You can raise + or lower both values together to change the importance of disk I/O + costs relative to CPU costs, which are described by the following + parameters. + + + + Random access to mechanical disk storage is normally much more expensive + than four times sequential access. However, a lower default is used + (4.0) because the majority of random accesses to disk, such as indexed + reads, are assumed to be in cache. The default value can be thought of + as modeling random access as 40 times slower than sequential, while + expecting 90% of random reads to be cached. + + + + If you believe a 90% cache rate is an incorrect assumption + for your workload, you can increase random_page_cost to better + reflect the true cost of random storage reads. Correspondingly, + if your data is likely to be completely in cache, such as when + the database is smaller than the total server memory, decreasing + random_page_cost can be appropriate. Storage that has a low random + read cost relative to sequential, e.g., solid-state drives, might + also be better modeled with a lower value for random_page_cost, + e.g., 1.1. + + + + + Although the system will let you set random_page_cost to + less than seq_page_cost, it is not physically sensible + to do so. However, setting them equal makes sense if the database + is entirely cached in RAM, since in that case there is no penalty + for touching pages out of sequence. Also, in a heavily-cached + database you should lower both values relative to the CPU parameters, + since the cost of fetching a page already in RAM is much smaller + than it would normally be. + + + + + + + cpu_tuple_cost (floating point) + + cpu_tuple_cost configuration parameter + + + + + Sets the planner's estimate of the cost of processing + each row during a query. + The default is 0.01. + + + + + + cpu_index_tuple_cost (floating point) + + cpu_index_tuple_cost configuration parameter + + + + + Sets the planner's estimate of the cost of processing + each index entry during an index scan. + The default is 0.005. + + + + + + cpu_operator_cost (floating point) + + cpu_operator_cost configuration parameter + + + + + Sets the planner's estimate of the cost of processing each + operator or function executed during a query. + The default is 0.0025. + + + + + + parallel_setup_cost (floating point) + + parallel_setup_cost configuration parameter + + + + + Sets the planner's estimate of the cost of launching parallel worker + processes. + The default is 1000. + + + + + + parallel_tuple_cost (floating point) + + parallel_tuple_cost configuration parameter + + + + + Sets the planner's estimate of the cost of transferring one tuple + from a parallel worker process to another process. + The default is 0.1. + + + + + + min_parallel_table_scan_size (integer) + + min_parallel_table_scan_size configuration parameter + + + + + Sets the minimum amount of table data that must be scanned in order + for a parallel scan to be considered. For a parallel sequential scan, + the amount of table data scanned is always equal to the size of the + table, but when indexes are used the amount of table data + scanned will normally be less. + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + The default is 8 megabytes (8MB). + + + + + + min_parallel_index_scan_size (integer) + + min_parallel_index_scan_size configuration parameter + + + + + Sets the minimum amount of index data that must be scanned in order + for a parallel scan to be considered. Note that a parallel index scan + typically won't touch the entire index; it is the number of pages + which the planner believes will actually be touched by the scan which + is relevant. This parameter is also used to decide whether a + particular index can participate in a parallel vacuum. See + . + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + The default is 512 kilobytes (512kB). + + + + + + effective_cache_size (integer) + + effective_cache_size configuration parameter + + + + + Sets the planner's assumption about the effective size of the + disk cache that is available to a single query. This is + factored into estimates of the cost of using an index; a + higher value makes it more likely index scans will be used, a + lower value makes it more likely sequential scans will be + used. When setting this parameter you should consider both + PostgreSQL's shared buffers and the + portion of the kernel's disk cache that will be used for + PostgreSQL data files, though some + data might exist in both places. Also, take + into account the expected number of concurrent queries on different + tables, since they will have to share the available + space. This parameter has no effect on the size of shared + memory allocated by PostgreSQL, nor + does it reserve kernel disk cache; it is used only for estimation + purposes. The system also does not assume data remains in + the disk cache between queries. + If this value is specified without units, it is taken as blocks, + that is BLCKSZ bytes, typically 8kB. + The default is 4 gigabytes (4GB). + (If BLCKSZ is not 8kB, the default value scales + proportionally to it.) + + + + + + jit_above_cost (floating point) + + jit_above_cost configuration parameter + + + + + Sets the query cost above which JIT compilation is activated, if + enabled (see ). + Performing JIT costs planning time but can + accelerate query execution. + Setting this to -1 disables JIT compilation. + The default is 100000. + + + + + + jit_inline_above_cost (floating point) + + jit_inline_above_cost configuration parameter + + + + + Sets the query cost above which JIT compilation attempts to inline + functions and operators. Inlining adds planning time, but can + improve execution speed. It is not meaningful to set this to less + than jit_above_cost. + Setting this to -1 disables inlining. + The default is 500000. + + + + + + jit_optimize_above_cost (floating point) + + jit_optimize_above_cost configuration parameter + + + + + Sets the query cost above which JIT compilation applies expensive + optimizations. Such optimization adds planning time, but can improve + execution speed. It is not meaningful to set this to less + than jit_above_cost, and it is unlikely to be + beneficial to set it to more + than jit_inline_above_cost. + Setting this to -1 disables expensive optimizations. + The default is 500000. + + + + + + + + + Genetic Query Optimizer + + + The genetic query optimizer (GEQO) is an algorithm that does query + planning using heuristic searching. This reduces planning time for + complex queries (those joining many relations), at the cost of producing + plans that are sometimes inferior to those found by the normal + exhaustive-search algorithm. + For more information see . + + + + + + geqo (boolean) + + genetic query optimization + + + GEQO + genetic query optimization + + + geqo configuration parameter + + + + + Enables or disables genetic query optimization. + This is on by default. It is usually best not to turn it off in + production; the geqo_threshold variable provides + more granular control of GEQO. + + + + + + geqo_threshold (integer) + + geqo_threshold configuration parameter + + + + + Use genetic query optimization to plan queries with at least + this many FROM items involved. (Note that a + FULL OUTER JOIN construct counts as only one FROM + item.) The default is 12. For simpler queries it is usually best + to use the regular, exhaustive-search planner, but for queries with + many tables the exhaustive search takes too long, often + longer than the penalty of executing a suboptimal plan. Thus, + a threshold on the size of the query is a convenient way to manage + use of GEQO. + + + + + + geqo_effort (integer) + + geqo_effort configuration parameter + + + + + Controls the trade-off between planning time and query plan + quality in GEQO. This variable must be an integer in the + range from 1 to 10. The default value is five. Larger values + increase the time spent doing query planning, but also + increase the likelihood that an efficient query plan will be + chosen. + + + + geqo_effort doesn't actually do anything + directly; it is only used to compute the default values for + the other variables that influence GEQO behavior (described + below). If you prefer, you can set the other parameters by + hand instead. + + + + + + geqo_pool_size (integer) + + geqo_pool_size configuration parameter + + + + + Controls the pool size used by GEQO, that is the + number of individuals in the genetic population. It must be + at least two, and useful values are typically 100 to 1000. If + it is set to zero (the default setting) then a suitable + value is chosen based on geqo_effort and + the number of tables in the query. + + + + + + geqo_generations (integer) + + geqo_generations configuration parameter + + + + + Controls the number of generations used by GEQO, that is + the number of iterations of the algorithm. It must + be at least one, and useful values are in the same range as + the pool size. If it is set to zero (the default setting) + then a suitable value is chosen based on + geqo_pool_size. + + + + + + geqo_selection_bias (floating point) + + geqo_selection_bias configuration parameter + + + + + Controls the selection bias used by GEQO. The selection bias + is the selective pressure within the population. Values can be + from 1.50 to 2.00; the latter is the default. + + + + + + geqo_seed (floating point) + + geqo_seed configuration parameter + + + + + Controls the initial value of the random number generator used + by GEQO to select random paths through the join order search space. + The value can range from zero (the default) to one. Varying the + value changes the set of join paths explored, and may result in a + better or worse best path being found. + + + + + + + + Other Planner Options + + + + + default_statistics_target (integer) + + default_statistics_target configuration parameter + + + + + Sets the default statistics target for table columns without + a column-specific target set via ALTER TABLE + SET STATISTICS. Larger values increase the time needed to + do ANALYZE, but might improve the quality of the + planner's estimates. The default is 100. For more information + on the use of statistics by the PostgreSQL + query planner, refer to . + + + + + + constraint_exclusion (enum) + + constraint exclusion + + + constraint_exclusion configuration parameter + + + + + Controls the query planner's use of table constraints to + optimize queries. + The allowed values of constraint_exclusion are + on (examine constraints for all tables), + off (never examine constraints), and + partition (examine constraints only for inheritance + child tables and UNION ALL subqueries). + partition is the default setting. + It is often used with traditional inheritance trees to improve + performance. + + + + When this parameter allows it for a particular table, the planner + compares query conditions with the table's CHECK + constraints, and omits scanning tables for which the conditions + contradict the constraints. For example: + + +CREATE TABLE parent(key integer, ...); +CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent); +CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent); +... +SELECT * FROM parent WHERE key = 2400; + + + With constraint exclusion enabled, this SELECT + will not scan child1000 at all, improving performance. + + + + Currently, constraint exclusion is enabled by default + only for cases that are often used to implement table partitioning via + inheritance trees. Turning it on for all tables imposes extra + planning overhead that is quite noticeable on simple queries, and most + often will yield no benefit for simple queries. If you have no + tables that are partitioned using traditional inheritance, you might + prefer to turn it off entirely. (Note that the equivalent feature for + partitioned tables is controlled by a separate parameter, + .) + + + + Refer to for + more information on using constraint exclusion to implement + partitioning. + + + + + + cursor_tuple_fraction (floating point) + + cursor_tuple_fraction configuration parameter + + + + + Sets the planner's estimate of the fraction of a cursor's rows that + will be retrieved. The default is 0.1. Smaller values of this + setting bias the planner towards using fast start plans + for cursors, which will retrieve the first few rows quickly while + perhaps taking a long time to fetch all rows. Larger values + put more emphasis on the total estimated time. At the maximum + setting of 1.0, cursors are planned exactly like regular queries, + considering only the total estimated time and not how soon the + first rows might be delivered. + + + + + + from_collapse_limit (integer) + + from_collapse_limit configuration parameter + + + + + The planner will merge sub-queries into upper queries if the + resulting FROM list would have no more than + this many items. Smaller values reduce planning time but might + yield inferior query plans. The default is eight. + For more information see . + + + + Setting this value to or more + may trigger use of the GEQO planner, resulting in non-optimal + plans. See . + + + + + + jit (boolean) + + jit configuration parameter + + + + + Determines whether JIT compilation may be used by + PostgreSQL, if available (see ). + The default is on. + + + + + + join_collapse_limit (integer) + + join_collapse_limit configuration parameter + + + + + The planner will rewrite explicit JOIN + constructs (except FULL JOINs) into lists of + FROM items whenever a list of no more than this many items + would result. Smaller values reduce planning time but might + yield inferior query plans. + + + + By default, this variable is set the same as + from_collapse_limit, which is appropriate + for most uses. Setting it to 1 prevents any reordering of + explicit JOINs. Thus, the explicit join order + specified in the query will be the actual order in which the + relations are joined. Because the query planner does not always choose + the optimal join order, advanced users can elect to + temporarily set this variable to 1, and then specify the join + order they desire explicitly. + For more information see . + + + + Setting this value to or more + may trigger use of the GEQO planner, resulting in non-optimal + plans. See . + + + + + + plan_cache_mode (enum) + + plan_cache_mode configuration parameter + + + + + Prepared statements (either explicitly prepared or implicitly + generated, for example by PL/pgSQL) can be executed using custom or + generic plans. Custom plans are made afresh for each execution + using its specific set of parameter values, while generic plans do + not rely on the parameter values and can be re-used across + executions. Thus, use of a generic plan saves planning time, but if + the ideal plan depends strongly on the parameter values then a + generic plan may be inefficient. The choice between these options + is normally made automatically, but it can be overridden + with plan_cache_mode. + The allowed values are auto (the default), + force_custom_plan and + force_generic_plan. + This setting is considered when a cached plan is to be executed, + not when it is prepared. + For more information see . + + + + + + + + + + Error Reporting and Logging + + + server log + + + + Where to Log + + + where to log + + + + current_logfiles + and the log_destination configuration parameter + + + + + + log_destination (string) + + log_destination configuration parameter + + + + + PostgreSQL supports several methods + for logging server messages, including + stderr, csvlog and + syslog. On Windows, + eventlog is also supported. Set this + parameter to a list of desired log destinations separated by + commas. The default is to log to stderr + only. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + If csvlog is included in log_destination, + log entries are output in comma separated + value (CSV) format, which is convenient for + loading logs into programs. + See for details. + must be enabled to generate + CSV-format log output. + + + When either stderr or + csvlog are included, the file + current_logfiles is created to record the location + of the log file(s) currently in use by the logging collector and the + associated logging destination. This provides a convenient way to + find the logs currently in use by the instance. Here is an example of + this file's content: + +stderr log/postgresql.log +csvlog log/postgresql.csv + + + current_logfiles is recreated when a new log file + is created as an effect of rotation, and + when log_destination is reloaded. It is removed when + neither stderr + nor csvlog are included + in log_destination, and when the logging collector is + disabled. + + + + + On most Unix systems, you will need to alter the configuration of + your system's syslog daemon in order + to make use of the syslog option for + log_destination. PostgreSQL + can log to syslog facilities + LOCAL0 through LOCAL7 (see ), but the default + syslog configuration on most platforms + will discard all such messages. You will need to add something like: + +local0.* /var/log/postgresql + + to the syslog daemon's configuration file + to make it work. + + + On Windows, when you use the eventlog + option for log_destination, you should + register an event source and its library with the operating + system so that the Windows Event Viewer can display event + log messages cleanly. + See for details. + + + + + + + logging_collector (boolean) + + logging_collector configuration parameter + + + + + This parameter enables the logging collector, which + is a background process that captures log messages + sent to stderr and redirects them into log files. + This approach is often more useful than + logging to syslog, since some types of messages + might not appear in syslog output. (One common + example is dynamic-linker failure messages; another is error messages + produced by scripts such as archive_command.) + This parameter can only be set at server start. + + + + + It is possible to log to stderr without using the + logging collector; the log messages will just go to wherever the + server's stderr is directed. However, that method is + only suitable for low log volumes, since it provides no convenient + way to rotate log files. Also, on some platforms not using the + logging collector can result in lost or garbled log output, because + multiple processes writing concurrently to the same log file can + overwrite each other's output. + + + + + + The logging collector is designed to never lose messages. This means + that in case of extremely high load, server processes could be + blocked while trying to send additional log messages when the + collector has fallen behind. In contrast, syslog + prefers to drop messages if it cannot write them, which means it + may fail to log some messages in such cases but it will not block + the rest of the system. + + + + + + + + log_directory (string) + + log_directory configuration parameter + + + + + When logging_collector is enabled, + this parameter determines the directory in which log files will be created. + It can be specified as an absolute path, or relative to the + cluster data directory. + This parameter can only be set in the postgresql.conf + file or on the server command line. + The default is log. + + + + + + log_filename (string) + + log_filename configuration parameter + + + + + When logging_collector is enabled, + this parameter sets the file names of the created log files. The value + is treated as a strftime pattern, + so %-escapes can be used to specify time-varying + file names. (Note that if there are + any time-zone-dependent %-escapes, the computation + is done in the zone specified + by .) + The supported %-escapes are similar to those + listed in the Open Group's strftime + specification. + Note that the system's strftime is not used + directly, so platform-specific (nonstandard) extensions do not work. + The default is postgresql-%Y-%m-%d_%H%M%S.log. + + + If you specify a file name without escapes, you should plan to + use a log rotation utility to avoid eventually filling the + entire disk. In releases prior to 8.4, if + no % escapes were + present, PostgreSQL would append + the epoch of the new log file's creation time, but this is no + longer the case. + + + If CSV-format output is enabled in log_destination, + .csv will be appended to the timestamped + log file name to create the file name for CSV-format output. + (If log_filename ends in .log, the suffix is + replaced instead.) + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + log_file_mode (integer) + + log_file_mode configuration parameter + + + + + On Unix systems this parameter sets the permissions for log files + when logging_collector is enabled. (On Microsoft + Windows this parameter is ignored.) + The parameter value is expected to be a numeric mode + specified in the format accepted by the + chmod and umask + system calls. (To use the customary octal format the number + must start with a 0 (zero).) + + + The default permissions are 0600, meaning only the + server owner can read or write the log files. The other commonly + useful setting is 0640, allowing members of the owner's + group to read the files. Note however that to make use of such a + setting, you'll need to alter to + store the files somewhere outside the cluster data directory. In + any case, it's unwise to make the log files world-readable, since + they might contain sensitive data. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + log_rotation_age (integer) + + log_rotation_age configuration parameter + + + + + When logging_collector is enabled, + this parameter determines the maximum amount of time to use an + individual log file, after which a new log file will be created. + If this value is specified without units, it is taken as minutes. + The default is 24 hours. + Set to zero to disable time-based creation of new log files. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + log_rotation_size (integer) + + log_rotation_size configuration parameter + + + + + When logging_collector is enabled, + this parameter determines the maximum size of an individual log file. + After this amount of data has been emitted into a log file, + a new log file will be created. + If this value is specified without units, it is taken as kilobytes. + The default is 10 megabytes. + Set to zero to disable size-based creation of new log files. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + log_truncate_on_rotation (boolean) + + log_truncate_on_rotation configuration parameter + + + + + When logging_collector is enabled, + this parameter will cause PostgreSQL to truncate (overwrite), + rather than append to, any existing log file of the same name. + However, truncation will occur only when a new file is being opened + due to time-based rotation, not during server startup or size-based + rotation. When off, pre-existing files will be appended to in + all cases. For example, using this setting in combination with + a log_filename like postgresql-%H.log + would result in generating twenty-four hourly log files and then + cyclically overwriting them. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + Example: To keep 7 days of logs, one log file per day named + server_log.Mon, server_log.Tue, + etc, and automatically overwrite last week's log with this week's log, + set log_filename to server_log.%a, + log_truncate_on_rotation to on, and + log_rotation_age to 1440. + + + Example: To keep 24 hours of logs, one log file per hour, but + also rotate sooner if the log file size exceeds 1GB, set + log_filename to server_log.%H%M, + log_truncate_on_rotation to on, + log_rotation_age to 60, and + log_rotation_size to 1000000. + Including %M in log_filename allows + any size-driven rotations that might occur to select a file name + different from the hour's initial file name. + + + + + + syslog_facility (enum) + + syslog_facility configuration parameter + + + + + When logging to syslog is enabled, this parameter + determines the syslog + facility to be used. You can choose + from LOCAL0, LOCAL1, + LOCAL2, LOCAL3, LOCAL4, + LOCAL5, LOCAL6, LOCAL7; + the default is LOCAL0. See also the + documentation of your system's + syslog daemon. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + syslog_ident (string) + + syslog_ident configuration parameter + + + + + When logging to syslog is enabled, this parameter + determines the program name used to identify + PostgreSQL messages in + syslog logs. The default is + postgres. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + syslog_sequence_numbers (boolean) + + syslog_sequence_numbers configuration parameter + + + + + + When logging to syslog and this is on (the + default), then each message will be prefixed by an increasing + sequence number (such as [2]). This circumvents + the --- last message repeated N times --- suppression + that many syslog implementations perform by default. In more modern + syslog implementations, repeated message suppression can be configured + (for example, $RepeatedMsgReduction + in rsyslog), so this might not be + necessary. Also, you could turn this off if you actually want to + suppress repeated messages. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + syslog_split_messages (boolean) + + syslog_split_messages configuration parameter + + + + + When logging to syslog is enabled, this parameter + determines how messages are delivered to syslog. When on (the + default), messages are split by lines, and long lines are split so + that they will fit into 1024 bytes, which is a typical size limit for + traditional syslog implementations. When off, PostgreSQL server log + messages are delivered to the syslog service as is, and it is up to + the syslog service to cope with the potentially bulky messages. + + + + If syslog is ultimately logging to a text file, then the effect will + be the same either way, and it is best to leave the setting on, since + most syslog implementations either cannot handle large messages or + would need to be specially configured to handle them. But if syslog + is ultimately writing into some other medium, it might be necessary or + more useful to keep messages logically together. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + event_source (string) + + event_source configuration parameter + + + + + When logging to event log is enabled, this parameter + determines the program name used to identify + PostgreSQL messages in + the log. The default is PostgreSQL. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + When to Log + + + + + log_min_messages (enum) + + log_min_messages configuration parameter + + + + + Controls which message + levels are written to the server log. + Valid values are DEBUG5, DEBUG4, + DEBUG3, DEBUG2, DEBUG1, + INFO, NOTICE, WARNING, + ERROR, LOG, FATAL, and + PANIC. Each level includes all the levels that + follow it. The later the level, the fewer messages are sent + to the log. The default is WARNING. Note that + LOG has a different rank here than in + . + Only superusers can change this setting. + + + + + + log_min_error_statement (enum) + + log_min_error_statement configuration parameter + + + + + Controls which SQL statements that cause an error + condition are recorded in the server log. The current + SQL statement is included in the log entry for any message of + the specified + severity + or higher. + Valid values are DEBUG5, + DEBUG4, DEBUG3, + DEBUG2, DEBUG1, + INFO, NOTICE, + WARNING, ERROR, + LOG, + FATAL, and PANIC. + The default is ERROR, which means statements + causing errors, log messages, fatal errors, or panics will be logged. + To effectively turn off logging of failing statements, + set this parameter to PANIC. + Only superusers can change this setting. + + + + + + log_min_duration_statement (integer) + + log_min_duration_statement configuration parameter + + + + + Causes the duration of each completed statement to be logged + if the statement ran for at least the specified amount of time. + For example, if you set it to 250ms + then all SQL statements that run 250ms or longer will be + logged. Enabling this parameter can be helpful in tracking down + unoptimized queries in your applications. + If this value is specified without units, it is taken as milliseconds. + Setting this to zero prints all statement durations. + -1 (the default) disables logging statement + durations. Only superusers can change this setting. + + + + This overrides , + meaning that queries with duration exceeding this setting are not + subject to sampling and are always logged. + + + + For clients using extended query protocol, durations of the Parse, + Bind, and Execute steps are logged independently. + + + + + When using this option together with + , + the text of statements that are logged because of + log_statement will not be repeated in the + duration log message. + If you are not using syslog, it is recommended + that you log the PID or session ID using + + so that you can link the statement message to the later + duration message using the process ID or session ID. + + + + + + + log_min_duration_sample (integer) + + log_min_duration_sample configuration parameter + + + + + Allows sampling the duration of completed statements that ran for + at least the specified amount of time. This produces the same + kind of log entries as + , but only for a + subset of the executed statements, with sample rate controlled by + . + For example, if you set it to 100ms then all + SQL statements that run 100ms or longer will be considered for + sampling. Enabling this parameter can be helpful when the + traffic is too high to log all queries. + If this value is specified without units, it is taken as milliseconds. + Setting this to zero samples all statement durations. + -1 (the default) disables sampling statement + durations. Only superusers can change this setting. + + + + This setting has lower priority + than log_min_duration_statement, meaning that + statements with durations + exceeding log_min_duration_statement are not + subject to sampling and are always logged. + + + + Other notes for log_min_duration_statement + apply also to this setting. + + + + + + log_statement_sample_rate (floating point) + + log_statement_sample_rate configuration parameter + + + + + Determines the fraction of statements with duration exceeding + that will be logged. + Sampling is stochastic, for example 0.5 means + there is statistically one chance in two that any given statement + will be logged. + The default is 1.0, meaning to log all sampled + statements. + Setting this to zero disables sampled statement-duration logging, + the same as setting + log_min_duration_sample to + -1. + Only superusers can change this setting. + + + + + + log_transaction_sample_rate (floating point) + + log_transaction_sample_rate configuration parameter + + + + + Sets the fraction of transactions whose statements are all logged, + in addition to statements logged for other reasons. It applies to + each new transaction regardless of its statements' durations. + Sampling is stochastic, for example 0.1 means + there is statistically one chance in ten that any given transaction + will be logged. + log_transaction_sample_rate can be helpful to + construct a sample of transactions. + The default is 0, meaning not to log + statements from any additional transactions. Setting this + to 1 logs all statements of all transactions. + Only superusers can change this setting. + + + + Like all statement-logging options, this option can add significant + overhead. + + + + + + + + + explains the message + severity levels used by PostgreSQL. If logging output + is sent to syslog or Windows' + eventlog, the severity levels are translated + as shown in the table. + + + + Message Severity Levels + + + + + + + + Severity + Usage + syslog + eventlog + + + + + + DEBUG1 .. DEBUG5 + Provides successively-more-detailed information for use by + developers. + DEBUG + INFORMATION + + + + INFO + Provides information implicitly requested by the user, + e.g., output from VACUUM VERBOSE. + INFO + INFORMATION + + + + NOTICE + Provides information that might be helpful to users, e.g., + notice of truncation of long identifiers. + NOTICE + INFORMATION + + + + WARNING + Provides warnings of likely problems, e.g., COMMIT + outside a transaction block. + NOTICE + WARNING + + + + ERROR + Reports an error that caused the current command to + abort. + WARNING + ERROR + + + + LOG + Reports information of interest to administrators, e.g., + checkpoint activity. + INFO + INFORMATION + + + + FATAL + Reports an error that caused the current session to + abort. + ERR + ERROR + + + + PANIC + Reports an error that caused all database sessions to abort. + CRIT + ERROR + + + +
+ +
+ + What to Log + + + + + application_name (string) + + application_name configuration parameter + + + + + The application_name can be any string of less than + NAMEDATALEN characters (64 characters in a standard build). + It is typically set by an application upon connection to the server. + The name will be displayed in the pg_stat_activity view + and included in CSV log entries. It can also be included in regular + log entries via the parameter. + Only printable ASCII characters may be used in the + application_name value. Other characters will be + replaced with question marks (?). + + + + + + debug_print_parse (boolean) + + debug_print_parse configuration parameter + + + debug_print_rewritten (boolean) + + debug_print_rewritten configuration parameter + + + debug_print_plan (boolean) + + debug_print_plan configuration parameter + + + + + These parameters enable various debugging output to be emitted. + When set, they print the resulting parse tree, the query rewriter + output, or the execution plan for each executed query. + These messages are emitted at LOG message level, so by + default they will appear in the server log but will not be sent to the + client. You can change that by adjusting + and/or + . + These parameters are off by default. + + + + + + debug_pretty_print (boolean) + + debug_pretty_print configuration parameter + + + + + When set, debug_pretty_print indents the messages + produced by debug_print_parse, + debug_print_rewritten, or + debug_print_plan. This results in more readable + but much longer output than the compact format used when + it is off. It is on by default. + + + + + + log_autovacuum_min_duration (integer) + + log_autovacuum_min_duration + configuration parameter + + + + + Causes each action executed by autovacuum to be logged if it ran for at + least the specified amount of time. Setting this to zero logs + all autovacuum actions. -1 (the default) disables + logging autovacuum actions. + If this value is specified without units, it is taken as milliseconds. + For example, if you set this to + 250ms then all automatic vacuums and analyzes that run + 250ms or longer will be logged. In addition, when this parameter is + set to any value other than -1, a message will be + logged if an autovacuum action is skipped due to a conflicting lock or a + concurrently dropped relation. Enabling this parameter can be helpful + in tracking autovacuum activity. This parameter can only be set in + the postgresql.conf file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + log_checkpoints (boolean) + + log_checkpoints configuration parameter + + + + + Causes checkpoints and restartpoints to be logged in the server log. + Some statistics are included in the log messages, including the number + of buffers written and the time spent writing them. + This parameter can only be set in the postgresql.conf + file or on the server command line. The default is off. + + + + + + log_connections (boolean) + + log_connections configuration parameter + + + + + Causes each attempted connection to the server to be logged, + as well as successful completion of both client authentication (if + necessary) and authorization. + Only superusers can change this parameter at session start, + and it cannot be changed at all within a session. + The default is off. + + + + + Some client programs, like psql, attempt + to connect twice while determining if a password is required, so + duplicate connection received messages do not + necessarily indicate a problem. + + + + + + + log_disconnections (boolean) + + log_disconnections configuration parameter + + + + + Causes session terminations to be logged. The log output + provides information similar to log_connections, + plus the duration of the session. + Only superusers can change this parameter at session start, + and it cannot be changed at all within a session. + The default is off. + + + + + + + log_duration (boolean) + + log_duration configuration parameter + + + + + Causes the duration of every completed statement to be logged. + The default is off. + Only superusers can change this setting. + + + + For clients using extended query protocol, durations of the Parse, + Bind, and Execute steps are logged independently. + + + + + The difference between enabling log_duration and setting + to zero is that + exceeding log_min_duration_statement forces the text of + the query to be logged, but this option doesn't. Thus, if + log_duration is on and + log_min_duration_statement has a positive value, all + durations are logged but the query text is included only for + statements exceeding the threshold. This behavior can be useful for + gathering statistics in high-load installations. + + + + + + + log_error_verbosity (enum) + + log_error_verbosity configuration parameter + + + + + Controls the amount of detail written in the server log for each + message that is logged. Valid values are TERSE, + DEFAULT, and VERBOSE, each adding more + fields to displayed messages. TERSE excludes + the logging of DETAIL, HINT, + QUERY, and CONTEXT error information. + VERBOSE output includes the SQLSTATE error + code (see also ) and the source code file name, function name, + and line number that generated the error. + Only superusers can change this setting. + + + + + + log_hostname (boolean) + + log_hostname configuration parameter + + + + + By default, connection log messages only show the IP address of the + connecting host. Turning this parameter on causes logging of the + host name as well. Note that depending on your host name resolution + setup this might impose a non-negligible performance penalty. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + log_line_prefix (string) + + log_line_prefix configuration parameter + + + + + This is a printf-style string that is output at the + beginning of each log line. + % characters begin escape sequences + that are replaced with status information as outlined below. + Unrecognized escapes are ignored. Other + characters are copied straight to the log line. Some escapes are + only recognized by session processes, and will be treated as empty by + background processes such as the main server process. Status + information may be aligned either left or right by specifying a + numeric literal after the % and before the option. A negative + value will cause the status information to be padded on the + right with spaces to give it a minimum width, whereas a positive + value will pad on the left. Padding can be useful to aid human + readability in log files. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. The default is + '%m [%p] ' which logs a time stamp and the process ID. + + + + + + + Escape + Effect + Session only + + + + + %a + Application name + yes + + + %u + User name + yes + + + %d + Database name + yes + + + %r + Remote host name or IP address, and remote port + yes + + + %h + Remote host name or IP address + yes + + + %b + Backend type + no + + + %p + Process ID + no + + + %P + Process ID of the parallel group leader, if this process + is a parallel query worker + no + + + %t + Time stamp without milliseconds + no + + + %m + Time stamp with milliseconds + no + + + %n + Time stamp with milliseconds (as a Unix epoch) + no + + + %i + Command tag: type of session's current command + yes + + + %e + SQLSTATE error code + no + + + %c + Session ID: see below + no + + + %l + Number of the log line for each session or process, starting at 1 + no + + + %s + Process start time stamp + no + + + %v + Virtual transaction ID (backendID/localXID) + no + + + %x + Transaction ID (0 if none is assigned) + no + + + %q + Produces no output, but tells non-session + processes to stop at this point in the string; ignored by + session processes + no + + + %Q + query identifier of the current query. Query + identifiers are not computed by default, so this field + will be zero unless + parameter is enabled or a third-party module that computes + query identifiers is configured. + yes + + + %% + Literal % + no + + + + + + + The backend type corresponds to the column + backend_type in the view + + pg_stat_activity, + but additional types can appear + in the log that don't show in that view. + + + + The %c escape prints a quasi-unique session identifier, + consisting of two 4-byte hexadecimal numbers (without leading zeros) + separated by a dot. The numbers are the process start time and the + process ID, so %c can also be used as a space saving way + of printing those items. For example, to generate the session + identifier from pg_stat_activity, use this query: + +SELECT to_hex(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' || + to_hex(pid) +FROM pg_stat_activity; + + + + + + + If you set a nonempty value for log_line_prefix, + you should usually make its last character be a space, to provide + visual separation from the rest of the log line. A punctuation + character can be used too. + + + + + + Syslog produces its own + time stamp and process ID information, so you probably do not want to + include those escapes if you are logging to syslog. + + + + + + The %q escape is useful when including information that is + only available in session (backend) context like user or database + name. For example: + +log_line_prefix = '%m [%p] %q%u@%d/%a ' + + + + + + + The %Q escape always reports a zero identifier + for lines output by because + log_statement generates output before an + identifier can be calculated, including invalid statements for + which an identifier cannot be calculated. + + + + + + + log_lock_waits (boolean) + + log_lock_waits configuration parameter + + + + + Controls whether a log message is produced when a session waits + longer than to acquire a + lock. This is useful in determining if lock waits are causing + poor performance. The default is off. + Only superusers can change this setting. + + + + + + log_recovery_conflict_waits (boolean) + + log_recovery_conflict_waits configuration parameter + + + + + Controls whether a log message is produced when the startup process + waits longer than deadlock_timeout + for recovery conflicts. This is useful in determining if recovery + conflicts prevent the recovery from applying WAL. + + + + The default is off. This parameter can only be set + in the postgresql.conf file or on the server + command line. + + + + + + log_parameter_max_length (integer) + + log_parameter_max_length configuration parameter + + + + + If greater than zero, each bind parameter value logged with a + non-error statement-logging message is trimmed to this many bytes. + Zero disables logging of bind parameters for non-error statement logs. + -1 (the default) allows bind parameters to be + logged in full. + If this value is specified without units, it is taken as bytes. + Only superusers can change this setting. + + + + This setting only affects log messages printed as a result of + , + , and related settings. Non-zero + values of this setting add some overhead, particularly if parameters + are sent in binary form, since then conversion to text is required. + + + + + + log_parameter_max_length_on_error (integer) + + log_parameter_max_length_on_error configuration parameter + + + + + If greater than zero, each bind parameter value reported in error + messages is trimmed to this many bytes. + Zero (the default) disables including bind parameters in error + messages. + -1 allows bind parameters to be printed in full. + If this value is specified without units, it is taken as bytes. + + + + Non-zero values of this setting add overhead, as + PostgreSQL will need to store textual + representations of parameter values in memory at the start of each + statement, whether or not an error eventually occurs. The overhead + is greater when bind parameters are sent in binary form than when + they are sent as text, since the former case requires data + conversion while the latter only requires copying the string. + + + + + + log_statement (enum) + + log_statement configuration parameter + + + + + Controls which SQL statements are logged. Valid values are + none (off), ddl, mod, and + all (all statements). ddl logs all data definition + statements, such as CREATE, ALTER, and + DROP statements. mod logs all + ddl statements, plus data-modifying statements + such as INSERT, + UPDATE, DELETE, TRUNCATE, + and COPY FROM. + PREPARE, EXECUTE, and + EXPLAIN ANALYZE statements are also logged if their + contained command is of an appropriate type. For clients using + extended query protocol, logging occurs when an Execute message + is received, and values of the Bind parameters are included + (with any embedded single-quote marks doubled). + + + + The default is none. Only superusers can change this + setting. + + + + + Statements that contain simple syntax errors are not logged + even by the log_statement = all setting, + because the log message is emitted only after basic parsing has + been done to determine the statement type. In the case of extended + query protocol, this setting likewise does not log statements that + fail before the Execute phase (i.e., during parse analysis or + planning). Set log_min_error_statement to + ERROR (or lower) to log such statements. + + + + + + + log_replication_commands (boolean) + + log_replication_commands configuration parameter + + + + + Causes each replication command to be logged in the server log. + See for more information about + replication command. The default value is off. + Only superusers can change this setting. + + + + + + log_temp_files (integer) + + log_temp_files configuration parameter + + + + + Controls logging of temporary file names and sizes. + Temporary files can be + created for sorts, hashes, and temporary query results. + If enabled by this setting, a log entry is emitted for each + temporary file when it is deleted. + A value of zero logs all temporary file information, while positive + values log only files whose size is greater than or equal to + the specified amount of data. + If this value is specified without units, it is taken as kilobytes. + The default setting is -1, which disables such logging. + Only superusers can change this setting. + + + + + + log_timezone (string) + + log_timezone configuration parameter + + + + + Sets the time zone used for timestamps written in the server log. + Unlike , this value is cluster-wide, + so that all sessions will report timestamps consistently. + The built-in default is GMT, but that is typically + overridden in postgresql.conf; initdb + will install a setting there corresponding to its system environment. + See for more information. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + Using CSV-Format Log Output + + + Including csvlog in the log_destination list + provides a convenient way to import log files into a database table. + This option emits log lines in comma-separated-values + (CSV) format, + with these columns: + time stamp with milliseconds, + user name, + database name, + process ID, + client host:port number, + session ID, + per-session line number, + command tag, + session start time, + virtual transaction ID, + regular transaction ID, + error severity, + SQLSTATE code, + error message, + error message detail, + hint, + internal query that led to the error (if any), + character count of the error position therein, + error context, + user query that led to the error (if any and enabled by + log_min_error_statement), + character count of the error position therein, + location of the error in the PostgreSQL source code + (if log_error_verbosity is set to verbose), + application name, backend type, process ID of parallel group leader, + and query id. + Here is a sample table definition for storing CSV-format log output: + + +CREATE TABLE postgres_log +( + log_time timestamp(3) with time zone, + user_name text, + database_name text, + process_id integer, + connection_from text, + session_id text, + session_line_num bigint, + command_tag text, + session_start_time timestamp with time zone, + virtual_transaction_id text, + transaction_id bigint, + error_severity text, + sql_state_code text, + message text, + detail text, + hint text, + internal_query text, + internal_query_pos integer, + context text, + query text, + query_pos integer, + location text, + application_name text, + backend_type text, + leader_pid integer, + query_id bigint, + PRIMARY KEY (session_id, session_line_num) +); + + + + + To import a log file into this table, use the COPY FROM + command: + + +COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + It is also possible to access the file as a foreign table, using + the supplied module. + + + + There are a few things you need to do to simplify importing CSV log + files: + + + + + Set log_filename and + log_rotation_age to provide a consistent, + predictable naming scheme for your log files. This lets you + predict what the file name will be and know when an individual log + file is complete and therefore ready to be imported. + + + + + + Set log_rotation_size to 0 to disable + size-based log rotation, as it makes the log file name difficult + to predict. + + + + + + Set log_truncate_on_rotation to on so + that old log data isn't mixed with the new in the same file. + + + + + + The table definition above includes a primary key specification. + This is useful to protect against accidentally importing the same + information twice. The COPY command commits all of the + data it imports at one time, so any error will cause the entire + import to fail. If you import a partial log file and later import + the file again when it is complete, the primary key violation will + cause the import to fail. Wait until the log is complete and + closed before importing. This procedure will also protect against + accidentally importing a partial line that hasn't been completely + written, which would also cause COPY to fail. + + + + + + + + Process Title + + + These settings control how process titles of server processes are + modified. Process titles are typically viewed using programs like + ps or, on Windows, Process Explorer. + See for details. + + + + + cluster_name (string) + + cluster_name configuration parameter + + + + + Sets a name that identifies this database cluster (instance) for + various purposes. The cluster name appears in the process title for + all server processes in this cluster. Moreover, it is the default + application name for a standby connection (see .) + + + + The name can be any string of less + than NAMEDATALEN characters (64 characters in a standard + build). Only printable ASCII characters may be used in the + cluster_name value. Other characters will be + replaced with question marks (?). No name is shown + if this parameter is set to the empty string '' (which is + the default). This parameter can only be set at server start. + + + + + + update_process_title (boolean) + + update_process_title configuration parameter + + + + + Enables updating of the process title every time a new SQL command + is received by the server. + This setting defaults to on on most platforms, but it + defaults to off on Windows due to that platform's larger + overhead for updating the process title. + Only superusers can change this setting. + + + + + +
+ + + Run-time Statistics + + + Query and Index Statistics Collector + + + These parameters control server-wide statistics collection features. + When statistics collection is enabled, the data that is produced can be + accessed via the pg_stat and + pg_statio family of system views. + Refer to for more information. + + + + + + track_activities (boolean) + + track_activities configuration parameter + + + + + Enables the collection of information on the currently + executing command of each session, along with its identifier and the + time when that command began execution. This parameter is on by + default. Note that even when enabled, this information is not + visible to all users, only to superusers and the user owning + the session being reported on, so it should not represent a + security risk. + Only superusers can change this setting. + + + + + + track_activity_query_size (integer) + + track_activity_query_size configuration parameter + + + + + Specifies the amount of memory reserved to store the text of the + currently executing command for each active session, for the + pg_stat_activity.query field. + If this value is specified without units, it is taken as bytes. + The default value is 1024 bytes. + This parameter can only be set at server start. + + + + + + track_counts (boolean) + + track_counts configuration parameter + + + + + Enables collection of statistics on database activity. + This parameter is on by default, because the autovacuum + daemon needs the collected information. + Only superusers can change this setting. + + + + + + track_io_timing (boolean) + + track_io_timing configuration parameter + + + + + Enables timing of database I/O calls. This parameter is off by + default, as it will repeatedly query the operating system for + the current time, which may cause significant overhead on some + platforms. You can use the tool to + measure the overhead of timing on your system. + I/O timing information is + displayed in + pg_stat_database, in the output of + when the BUFFERS option + is used, by autovacuum for auto-vacuums and auto-analyzes, when + is set and by + . Only superusers can change this + setting. + + + + + + track_wal_io_timing (boolean) + + track_wal_io_timing configuration parameter + + + + + Enables timing of WAL I/O calls. This parameter is off by default, + as it will repeatedly query the operating system for the current time, + which may cause significant overhead on some platforms. + You can use the pg_test_timing tool to + measure the overhead of timing on your system. + I/O timing information is + displayed in + pg_stat_wal. Only superusers can + change this setting. + + + + + + track_functions (enum) + + track_functions configuration parameter + + + + + Enables tracking of function call counts and time used. Specify + pl to track only procedural-language functions, + all to also track SQL and C language functions. + The default is none, which disables function + statistics tracking. Only superusers can change this setting. + + + + + SQL-language functions that are simple enough to be inlined + into the calling query will not be tracked, regardless of this + setting. + + + + + + + stats_temp_directory (string) + + stats_temp_directory configuration parameter + + + + + Sets the directory to store temporary statistics data in. This can be + a path relative to the data directory or an absolute path. The default + is pg_stat_tmp. Pointing this at a RAM-based + file system will decrease physical I/O requirements and can lead to + improved performance. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + + Statistics Monitoring + + + + compute_query_id (enum) + + compute_query_id configuration parameter + + + + + Enables in-core computation of a query identifier. + Query identifiers can be displayed in the pg_stat_activity + view, using EXPLAIN, or emitted in the log if + configured via the parameter. + The extension also requires a query + identifier to be computed. Note that an external module can + alternatively be used if the in-core query identifier computation + method is not acceptable. In this case, in-core computation + must be always disabled. + Valid values are off (always disabled), + on (always enabled) and auto, + which lets modules such as + automatically enable it. + The default is auto. + + + + To ensure that only one query identifier is calculated and + displayed, extensions that calculate query identifiers should + throw an error if a query identifier has already been computed. + + + + + + + log_statement_stats (boolean) + + log_statement_stats configuration parameter + + + log_parser_stats (boolean) + + log_parser_stats configuration parameter + + + log_planner_stats (boolean) + + log_planner_stats configuration parameter + + + log_executor_stats (boolean) + + log_executor_stats configuration parameter + + + + + For each query, output performance statistics of the respective + module to the server log. This is a crude profiling + instrument, similar to the Unix getrusage() operating + system facility. log_statement_stats reports total + statement statistics, while the others report per-module statistics. + log_statement_stats cannot be enabled together with + any of the per-module options. All of these options are disabled by + default. Only superusers can change these settings. + + + + + + + + + + + Automatic Vacuuming + + + autovacuum + configuration parameters + + + + These settings control the behavior of the autovacuum + feature. Refer to for more information. + Note that many of these settings can be overridden on a per-table + basis; see . + + + + + + autovacuum (boolean) + + autovacuum configuration parameter + + + + + Controls whether the server should run the + autovacuum launcher daemon. This is on by default; however, + must also be enabled for + autovacuum to work. + This parameter can only be set in the postgresql.conf + file or on the server command line; however, autovacuuming can be + disabled for individual tables by changing table storage parameters. + + + Note that even when this parameter is disabled, the system + will launch autovacuum processes if necessary to + prevent transaction ID wraparound. See for more information. + + + + + + autovacuum_max_workers (integer) + + autovacuum_max_workers configuration parameter + + + + + Specifies the maximum number of autovacuum processes (other than the + autovacuum launcher) that may be running at any one time. The default + is three. This parameter can only be set at server start. + + + + + + autovacuum_naptime (integer) + + autovacuum_naptime configuration parameter + + + + + Specifies the minimum delay between autovacuum runs on any given + database. In each round the daemon examines the + database and issues VACUUM and ANALYZE commands + as needed for tables in that database. + If this value is specified without units, it is taken as seconds. + The default is one minute (1min). + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + autovacuum_vacuum_threshold (integer) + + autovacuum_vacuum_threshold + configuration parameter + + + + + Specifies the minimum number of updated or deleted tuples needed + to trigger a VACUUM in any one table. + The default is 50 tuples. + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + autovacuum_vacuum_insert_threshold (integer) + + autovacuum_vacuum_insert_threshold + configuration parameter + + + + + Specifies the number of inserted tuples needed to trigger a + VACUUM in any one table. + The default is 1000 tuples. If -1 is specified, autovacuum will not + trigger a VACUUM operation on any tables based on + the number of inserts. + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + autovacuum_analyze_threshold (integer) + + autovacuum_analyze_threshold + configuration parameter + + + + + Specifies the minimum number of inserted, updated or deleted tuples + needed to trigger an ANALYZE in any one table. + The default is 50 tuples. + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + autovacuum_vacuum_scale_factor (floating point) + + autovacuum_vacuum_scale_factor + configuration parameter + + + + + Specifies a fraction of the table size to add to + autovacuum_vacuum_threshold + when deciding whether to trigger a VACUUM. + The default is 0.2 (20% of table size). + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + autovacuum_vacuum_insert_scale_factor (floating point) + + autovacuum_vacuum_insert_scale_factor + configuration parameter + + + + + Specifies a fraction of the table size to add to + autovacuum_vacuum_insert_threshold + when deciding whether to trigger a VACUUM. + The default is 0.2 (20% of table size). + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + autovacuum_analyze_scale_factor (floating point) + + autovacuum_analyze_scale_factor + configuration parameter + + + + + Specifies a fraction of the table size to add to + autovacuum_analyze_threshold + when deciding whether to trigger an ANALYZE. + The default is 0.1 (10% of table size). + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + autovacuum_freeze_max_age (integer) + + autovacuum_freeze_max_age + configuration parameter + + + + + Specifies the maximum age (in transactions) that a table's + pg_class.relfrozenxid field can + attain before a VACUUM operation is forced + to prevent transaction ID wraparound within the table. + Note that the system will launch autovacuum processes to + prevent wraparound even when autovacuum is otherwise disabled. + + + + Vacuum also allows removal of old files from the + pg_xact subdirectory, which is why the default + is a relatively low 200 million transactions. + This parameter can only be set at server start, but the setting + can be reduced for individual tables by + changing table storage parameters. + For more information see . + + + + + + autovacuum_multixact_freeze_max_age (integer) + + autovacuum_multixact_freeze_max_age + configuration parameter + + + + + Specifies the maximum age (in multixacts) that a table's + pg_class.relminmxid field can + attain before a VACUUM operation is forced to + prevent multixact ID wraparound within the table. + Note that the system will launch autovacuum processes to + prevent wraparound even when autovacuum is otherwise disabled. + + + + Vacuuming multixacts also allows removal of old files from the + pg_multixact/members and pg_multixact/offsets + subdirectories, which is why the default is a relatively low + 400 million multixacts. + This parameter can only be set at server start, but the setting can + be reduced for individual tables by changing table storage parameters. + For more information see . + + + + + + autovacuum_vacuum_cost_delay (floating point) + + autovacuum_vacuum_cost_delay + configuration parameter + + + + + Specifies the cost delay value that will be used in automatic + VACUUM operations. If -1 is specified, the regular + value will be used. + If this value is specified without units, it is taken as milliseconds. + The default value is 2 milliseconds. + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + autovacuum_vacuum_cost_limit (integer) + + autovacuum_vacuum_cost_limit + configuration parameter + + + + + Specifies the cost limit value that will be used in automatic + VACUUM operations. If -1 is specified (which is the + default), the regular + value will be used. Note that + the value is distributed proportionally among the running autovacuum + workers, if there is more than one, so that the sum of the limits for + each worker does not exceed the value of this variable. + This parameter can only be set in the postgresql.conf + file or on the server command line; + but the setting can be overridden for individual tables by + changing table storage parameters. + + + + + + + + + Client Connection Defaults + + + Statement Behavior + + + + client_min_messages (enum) + + client_min_messages configuration parameter + + + + + Controls which + message levels + are sent to the client. + Valid values are DEBUG5, + DEBUG4, DEBUG3, DEBUG2, + DEBUG1, LOG, NOTICE, + WARNING, and ERROR. + Each level includes all the levels that follow it. The later the level, + the fewer messages are sent. The default is + NOTICE. Note that LOG has a different + rank here than in . + + + INFO level messages are always sent to the client. + + + + + + search_path (string) + + search_path configuration parameter + + pathfor schemas + + + + This variable specifies the order in which schemas are searched + when an object (table, data type, function, etc.) is referenced by a + simple name with no schema specified. When there are objects of + identical names in different schemas, the one found first + in the search path is used. An object that is not in any of the + schemas in the search path can only be referenced by specifying + its containing schema with a qualified (dotted) name. + + + + The value for search_path must be a comma-separated + list of schema names. Any name that is not an existing schema, or is + a schema for which the user does not have USAGE + permission, is silently ignored. + + + + If one of the list items is the special name + $user, then the schema having the name returned by + CURRENT_USER is substituted, if there is such a schema + and the user has USAGE permission for it. + (If not, $user is ignored.) + + + + The system catalog schema, pg_catalog, is always + searched, whether it is mentioned in the path or not. If it is + mentioned in the path then it will be searched in the specified + order. If pg_catalog is not in the path then it will + be searched before searching any of the path items. + + + + + Likewise, the current session's temporary-table schema, + pg_temp_nnn, is always searched if it + exists. It can be explicitly listed in the path by using the + alias pg_temppg_temp. If it is not listed in the path then + it is searched first (even before pg_catalog). However, + the temporary schema is only searched for relation (table, view, + sequence, etc) and data type names. It is never searched for + function or operator names. + + + + When objects are created without specifying a particular target + schema, they will be placed in the first valid schema named in + search_path. An error is reported if the search + path is empty. + + + + The default value for this parameter is + "$user", public. + This setting supports shared use of a database (where no users + have private schemas, and all share use of public), + private per-user schemas, and combinations of these. Other + effects can be obtained by altering the default search path + setting, either globally or per-user. + + + + For more information on schema handling, see + . In particular, the default + configuration is suitable only when the database has a single user or + a few mutually-trusting users. + + + + The current effective value of the search path can be examined + via the SQL function + current_schemas + (see ). + This is not quite the same as + examining the value of search_path, since + current_schemas shows how the items + appearing in search_path were resolved. + + + + + + + row_security (boolean) + + row_security configuration parameter + + + + + This variable controls whether to raise an error in lieu of applying a + row security policy. When set to on, policies apply + normally. When set to off, queries fail which would + otherwise apply at least one policy. The default is on. + Change to off where limited row visibility could cause + incorrect results; for example, pg_dump makes that + change by default. This variable has no effect on roles which bypass + every row security policy, to wit, superusers and roles with + the BYPASSRLS attribute. + + + + For more information on row security policies, + see . + + + + + + default_table_access_method (string) + + default_table_access_method configuration parameter + + + + + This parameter specifies the default table access method to use when + creating tables or materialized views if the CREATE + command does not explicitly specify an access method, or when + SELECT ... INTO is used, which does not allow to + specify a table access method. The default is heap. + + + + + + default_tablespace (string) + + default_tablespace configuration parameter + + tablespacedefault + + + + This variable specifies the default tablespace in which to create + objects (tables and indexes) when a CREATE command does + not explicitly specify a tablespace. + + + + The value is either the name of a tablespace, or an empty string + to specify using the default tablespace of the current database. + If the value does not match the name of any existing tablespace, + PostgreSQL will automatically use the default + tablespace of the current database. If a nondefault tablespace + is specified, the user must have CREATE privilege + for it, or creation attempts will fail. + + + + This variable is not used for temporary tables; for them, + is consulted instead. + + + + This variable is also not used when creating databases. + By default, a new database inherits its tablespace setting from + the template database it is copied from. + + + + If this parameter is set to a value other than the empty string + when a partitioned table is created, the partitioned table's + tablespace will be set to that value, which will be used as + the default tablespace for partitions created in the future, + even if default_tablespace has changed since then. + + + + For more information on tablespaces, + see . + + + + + + default_toast_compression (enum) + + default_toast_compression configuration parameter + + + + + This variable sets the default + TOAST + compression method for values of compressible columns. + (This can be overridden for individual columns by setting + the COMPRESSION column option in + CREATE TABLE or + ALTER TABLE.) + The supported compression methods are pglz and + (if PostgreSQL was compiled with + ) lz4. + The default is pglz. + + + + + + temp_tablespaces (string) + + temp_tablespaces configuration parameter + + tablespacetemporary + + + + This variable specifies tablespaces in which to create temporary + objects (temp tables and indexes on temp tables) when a + CREATE command does not explicitly specify a tablespace. + Temporary files for purposes such as sorting large data sets + are also created in these tablespaces. + + + + The value is a list of names of tablespaces. When there is more than + one name in the list, PostgreSQL chooses a random + member of the list each time a temporary object is to be created; + except that within a transaction, successively created temporary + objects are placed in successive tablespaces from the list. + If the selected element of the list is an empty string, + PostgreSQL will automatically use the default + tablespace of the current database instead. + + + + When temp_tablespaces is set interactively, specifying a + nonexistent tablespace is an error, as is specifying a tablespace for + which the user does not have CREATE privilege. However, + when using a previously set value, nonexistent tablespaces are + ignored, as are tablespaces for which the user lacks + CREATE privilege. In particular, this rule applies when + using a value set in postgresql.conf. + + + + The default value is an empty string, which results in all temporary + objects being created in the default tablespace of the current + database. + + + + See also . + + + + + + check_function_bodies (boolean) + + check_function_bodies configuration parameter + + + + + This parameter is normally on. When set to off, it + disables validation of the routine body string during and . Disabling validation avoids side + effects of the validation process, in particular preventing false + positives due to problems such as forward references. + Set this parameter + to off before loading functions on behalf of other + users; pg_dump does so automatically. + + + + + + default_transaction_isolation (enum) + + transaction isolation level + setting default + + + default_transaction_isolation configuration parameter + + + + + Each SQL transaction has an isolation level, which can be + either read uncommitted, read + committed, repeatable read, or + serializable. This parameter controls the + default isolation level of each new transaction. The default + is read committed. + + + + Consult and for more information. + + + + + + default_transaction_read_only (boolean) + + read-only transaction + setting default + + + default_transaction_read_only configuration parameter + + + + + A read-only SQL transaction cannot alter non-temporary tables. + This parameter controls the default read-only status of each new + transaction. The default is off (read/write). + + + + Consult for more information. + + + + + + default_transaction_deferrable (boolean) + + deferrable transaction + setting default + + + default_transaction_deferrable configuration parameter + + + + + When running at the serializable isolation level, + a deferrable read-only SQL transaction may be delayed before + it is allowed to proceed. However, once it begins executing + it does not incur any of the overhead required to ensure + serializability; so serialization code will have no reason to + force it to abort because of concurrent updates, making this + option suitable for long-running read-only transactions. + + + + This parameter controls the default deferrable status of each + new transaction. It currently has no effect on read-write + transactions or those operating at isolation levels lower + than serializable. The default is off. + + + + Consult for more information. + + + + + + + session_replication_role (enum) + + session_replication_role configuration parameter + + + + + Controls firing of replication-related triggers and rules for the + current session. Setting this variable requires + superuser privilege and results in discarding any previously cached + query plans. Possible values are origin (the default), + replica and local. + + + + The intended use of this setting is that logical replication systems + set it to replica when they are applying replicated + changes. The effect of that will be that triggers and rules (that + have not been altered from their default configuration) will not fire + on the replica. See the ALTER TABLE clauses + ENABLE TRIGGER and ENABLE RULE + for more information. + + + + PostgreSQL treats the settings origin and + local the same internally. Third-party replication + systems may use these two values for their internal purposes, for + example using local to designate a session whose + changes should not be replicated. + + + + Since foreign keys are implemented as triggers, setting this parameter + to replica also disables all foreign key checks, + which can leave data in an inconsistent state if improperly used. + + + + + + statement_timeout (integer) + + statement_timeout configuration parameter + + + + + Abort any statement that takes more than the specified amount of time. + If log_min_error_statement is set + to ERROR or lower, the statement that timed out + will also be logged. + If this value is specified without units, it is taken as milliseconds. + A value of zero (the default) disables the timeout. + + + + The timeout is measured from the time a command arrives at the + server until it is completed by the server. If multiple SQL + statements appear in a single simple-Query message, the timeout + is applied to each statement separately. + (PostgreSQL versions before 13 usually + treated the timeout as applying to the whole query string.) + In extended query protocol, the timeout starts running when any + query-related message (Parse, Bind, Execute, Describe) arrives, and + it is canceled by completion of an Execute or Sync message. + + + + Setting statement_timeout in + postgresql.conf is not recommended because it would + affect all sessions. + + + + + + lock_timeout (integer) + + lock_timeout configuration parameter + + + + + Abort any statement that waits longer than the specified amount of + time while attempting to acquire a lock on a table, index, + row, or other database object. The time limit applies separately to + each lock acquisition attempt. The limit applies both to explicit + locking requests (such as LOCK TABLE, or SELECT + FOR UPDATE without NOWAIT) and to implicitly-acquired + locks. + If this value is specified without units, it is taken as milliseconds. + A value of zero (the default) disables the timeout. + + + + Unlike statement_timeout, this timeout can only occur + while waiting for locks. Note that if statement_timeout + is nonzero, it is rather pointless to set lock_timeout to + the same or larger value, since the statement timeout would always + trigger first. If log_min_error_statement is set to + ERROR or lower, the statement that timed out will be + logged. + + + + Setting lock_timeout in + postgresql.conf is not recommended because it would + affect all sessions. + + + + + + idle_in_transaction_session_timeout (integer) + + idle_in_transaction_session_timeout configuration parameter + + + + + Terminate any session that has been idle (that is, waiting for a + client query) within an open transaction for longer than the + specified amount of time. + If this value is specified without units, it is taken as milliseconds. + A value of zero (the default) disables the timeout. + + + + This option can be used to ensure that idle sessions do not hold + locks for an unreasonable amount of time. Even when no significant + locks are held, an open transaction prevents vacuuming away + recently-dead tuples that may be visible only to this transaction; + so remaining idle for a long time can contribute to table bloat. + See for more details. + + + + + + idle_session_timeout (integer) + + idle_session_timeout configuration parameter + + + + + Terminate any session that has been idle (that is, waiting for a + client query), but not within an open transaction, for longer than + the specified amount of time. + If this value is specified without units, it is taken as milliseconds. + A value of zero (the default) disables the timeout. + + + + Unlike the case with an open transaction, an idle session without a + transaction imposes no large costs on the server, so there is less + need to enable this timeout + than idle_in_transaction_session_timeout. + + + + Be wary of enforcing this timeout on connections made through + connection-pooling software or other middleware, as such a layer + may not react well to unexpected connection closure. It may be + helpful to enable this timeout only for interactive sessions, + perhaps by applying it only to particular users. + + + + + + vacuum_freeze_table_age (integer) + + vacuum_freeze_table_age configuration parameter + + + + + VACUUM performs an aggressive scan if the table's + pg_class.relfrozenxid field has reached + the age specified by this setting. An aggressive scan differs from + a regular VACUUM in that it visits every page that might + contain unfrozen XIDs or MXIDs, not just those that might contain dead + tuples. The default is 150 million transactions. Although users can + set this value anywhere from zero to two billion, VACUUM + will silently limit the effective value to 95% of + , so that a + periodic manual VACUUM has a chance to run before an + anti-wraparound autovacuum is launched for the table. For more + information see + . + + + + + + vacuum_freeze_min_age (integer) + + vacuum_freeze_min_age configuration parameter + + + + + Specifies the cutoff age (in transactions) that VACUUM + should use to decide whether to freeze row versions + while scanning a table. + The default is 50 million transactions. Although + users can set this value anywhere from zero to one billion, + VACUUM will silently limit the effective value to half + the value of , so + that there is not an unreasonably short time between forced + autovacuums. For more information see . + + + + + + vacuum_failsafe_age (integer) + + vacuum_failsafe_age configuration parameter + + + + + Specifies the maximum age (in transactions) that a table's + pg_class.relfrozenxid + field can attain before VACUUM takes + extraordinary measures to avoid system-wide transaction ID + wraparound failure. This is VACUUM's + strategy of last resort. The failsafe typically triggers + when an autovacuum to prevent transaction ID wraparound has + already been running for some time, though it's possible for + the failsafe to trigger during any VACUUM. + + + When the failsafe is triggered, any cost-based delay that is + in effect will no longer be applied, and further non-essential + maintenance tasks (such as index vacuuming) are bypassed. + + + The default is 1.6 billion transactions. Although users can + set this value anywhere from zero to 2.1 billion, + VACUUM will silently adjust the effective + value to no less than 105% of . + + + + + + vacuum_multixact_freeze_table_age (integer) + + vacuum_multixact_freeze_table_age configuration parameter + + + + + VACUUM performs an aggressive scan if the table's + pg_class.relminmxid field has reached + the age specified by this setting. An aggressive scan differs from + a regular VACUUM in that it visits every page that might + contain unfrozen XIDs or MXIDs, not just those that might contain dead + tuples. The default is 150 million multixacts. + Although users can set this value anywhere from zero to two billion, + VACUUM will silently limit the effective value to 95% of + , so that a + periodic manual VACUUM has a chance to run before an + anti-wraparound is launched for the table. + For more information see . + + + + + + vacuum_multixact_freeze_min_age (integer) + + vacuum_multixact_freeze_min_age configuration parameter + + + + + Specifies the cutoff age (in multixacts) that VACUUM + should use to decide whether to replace multixact IDs with a newer + transaction ID or multixact ID while scanning a table. The default + is 5 million multixacts. + Although users can set this value anywhere from zero to one billion, + VACUUM will silently limit the effective value to half + the value of , + so that there is not an unreasonably short time between forced + autovacuums. + For more information see . + + + + + + vacuum_multixact_failsafe_age (integer) + + vacuum_multixact_failsafe_age configuration parameter + + + + + Specifies the maximum age (in transactions) that a table's + pg_class.relminmxid + field can attain before VACUUM takes + extraordinary measures to avoid system-wide multixact ID + wraparound failure. This is VACUUM's + strategy of last resort. The failsafe typically triggers when + an autovacuum to prevent transaction ID wraparound has already + been running for some time, though it's possible for the + failsafe to trigger during any VACUUM. + + + When the failsafe is triggered, any cost-based delay that is + in effect will no longer be applied, and further non-essential + maintenance tasks (such as index vacuuming) are bypassed. + + + The default is 1.6 billion multixacts. Although users can set + this value anywhere from zero to 2.1 billion, + VACUUM will silently adjust the effective + value to no less than 105% of . + + + + + + bytea_output (enum) + + bytea_output configuration parameter + + + + + Sets the output format for values of type bytea. + Valid values are hex (the default) + and escape (the traditional PostgreSQL + format). See for more + information. The bytea type always + accepts both formats on input, regardless of this setting. + + + + + + xmlbinary (enum) + + xmlbinary configuration parameter + + + + + Sets how binary values are to be encoded in XML. This applies + for example when bytea values are converted to + XML by the functions xmlelement or + xmlforest. Possible values are + base64 and hex, which + are both defined in the XML Schema standard. The default is + base64. For further information about + XML-related functions, see . + + + + The actual choice here is mostly a matter of taste, + constrained only by possible restrictions in client + applications. Both methods support all possible values, + although the hex encoding will be somewhat larger than the + base64 encoding. + + + + + + xmloption (enum) + + xmloption configuration parameter + + + SET XML OPTION + + + XML option + + + + + Sets whether DOCUMENT or + CONTENT is implicit when converting between + XML and character string values. See for a description of this. Valid + values are DOCUMENT and + CONTENT. The default is + CONTENT. + + + + According to the SQL standard, the command to set this option is + +SET XML OPTION { DOCUMENT | CONTENT }; + + This syntax is also available in PostgreSQL. + + + + + + gin_pending_list_limit (integer) + + gin_pending_list_limit + configuration parameter + + + + + Sets the maximum size of a GIN index's pending list, which is used + when fastupdate is enabled. If the list grows + larger than this maximum size, it is cleaned up by moving + the entries in it to the index's main GIN data structure in bulk. + If this value is specified without units, it is taken as kilobytes. + The default is four megabytes (4MB). This setting + can be overridden for individual GIN indexes by changing + index storage parameters. + See and + for more information. + + + + + + + + Locale and Formatting + + + + + DateStyle (string) + + DateStyle configuration parameter + + + + + Sets the display format for date and time values, as well as the + rules for interpreting ambiguous date input values. For + historical reasons, this variable contains two independent + components: the output format specification (ISO, + Postgres, SQL, or German) + and the input/output specification for year/month/day ordering + (DMY, MDY, or YMD). These + can be set separately or together. The keywords Euro + and European are synonyms for DMY; the + keywords US, NonEuro, and + NonEuropean are synonyms for MDY. See + for more information. The + built-in default is ISO, MDY, but + initdb will initialize the + configuration file with a setting that corresponds to the + behavior of the chosen lc_time locale. + + + + + + IntervalStyle (enum) + + IntervalStyle configuration parameter + + + + + Sets the display format for interval values. + The value sql_standard will produce + output matching SQL standard interval literals. + The value postgres (which is the default) will produce + output matching PostgreSQL releases prior to 8.4 + when the + parameter was set to ISO. + The value postgres_verbose will produce output + matching PostgreSQL releases prior to 8.4 + when the DateStyle + parameter was set to non-ISO output. + The value iso_8601 will produce output matching the time + interval format with designators defined in section + 4.4.3.2 of ISO 8601. + + + The IntervalStyle parameter also affects the + interpretation of ambiguous interval input. See + for more information. + + + + + + TimeZone (string) + + TimeZone configuration parameter + + time zone + + + + Sets the time zone for displaying and interpreting time stamps. + The built-in default is GMT, but that is typically + overridden in postgresql.conf; initdb + will install a setting there corresponding to its system environment. + See for more information. + + + + + + timezone_abbreviations (string) + + timezone_abbreviations configuration parameter + + time zone names + + + + Sets the collection of time zone abbreviations that will be accepted + by the server for datetime input. The default is 'Default', + which is a collection that works in most of the world; there are + also 'Australia' and 'India', + and other collections can be defined for a particular installation. + See for more information. + + + + + + extra_float_digits (integer) + + significant digits + + + floating-point + display + + + extra_float_digits configuration parameter + + + + + This parameter adjusts the number of digits used for textual output of + floating-point values, including float4, float8, + and geometric data types. + + + If the value is 1 (the default) or above, float values are output in + shortest-precise format; see . The + actual number of digits generated depends only on the value being + output, not on the value of this parameter. At most 17 digits are + required for float8 values, and 9 for float4 + values. This format is both fast and precise, preserving the original + binary float value exactly when correctly read. For historical + compatibility, values up to 3 are permitted. + + + If the value is zero or negative, then the output is rounded to a + given decimal precision. The precision used is the standard number of + digits for the type (FLT_DIG + or DBL_DIG as appropriate) reduced according to the + value of this parameter. (For example, specifying -1 will cause + float4 values to be output rounded to 5 significant + digits, and float8 values + rounded to 14 digits.) This format is slower and does not preserve all + the bits of the binary float value, but may be more human-readable. + + + + The meaning of this parameter, and its default value, changed + in PostgreSQL 12; + see for further discussion. + + + + + + + client_encoding (string) + + client_encoding configuration parameter + + character set + + + + Sets the client-side encoding (character set). + The default is to use the database encoding. + The character sets supported by the PostgreSQL + server are described in . + + + + + + lc_messages (string) + + lc_messages configuration parameter + + + + + Sets the language in which messages are displayed. Acceptable + values are system-dependent; see for + more information. If this variable is set to the empty string + (which is the default) then the value is inherited from the + execution environment of the server in a system-dependent way. + + + + On some systems, this locale category does not exist. Setting + this variable will still work, but there will be no effect. + Also, there is a chance that no translated messages for the + desired language exist. In that case you will continue to see + the English messages. + + + + Only superusers can change this setting, because it affects the + messages sent to the server log as well as to the client, and + an improper value might obscure the readability of the server + logs. + + + + + + lc_monetary (string) + + lc_monetary configuration parameter + + + + + Sets the locale to use for formatting monetary amounts, for + example with the to_char family of + functions. Acceptable values are system-dependent; see for more information. If this variable is + set to the empty string (which is the default) then the value + is inherited from the execution environment of the server in a + system-dependent way. + + + + + + lc_numeric (string) + + lc_numeric configuration parameter + + + + + Sets the locale to use for formatting numbers, for example + with the to_char family of + functions. Acceptable values are system-dependent; see for more information. If this variable is + set to the empty string (which is the default) then the value + is inherited from the execution environment of the server in a + system-dependent way. + + + + + + lc_time (string) + + lc_time configuration parameter + + + + + Sets the locale to use for formatting dates and times, for example + with the to_char family of + functions. Acceptable values are system-dependent; see for more information. If this variable is + set to the empty string (which is the default) then the value + is inherited from the execution environment of the server in a + system-dependent way. + + + + + + default_text_search_config (string) + + default_text_search_config configuration parameter + + + + + Selects the text search configuration that is used by those variants + of the text search functions that do not have an explicit argument + specifying the configuration. + See for further information. + The built-in default is pg_catalog.simple, but + initdb will initialize the + configuration file with a setting that corresponds to the + chosen lc_ctype locale, if a configuration + matching that locale can be identified. + + + + + + + + + + Shared Library Preloading + + + Several settings are available for preloading shared libraries into the + server, in order to load additional functionality or achieve performance + benefits. For example, a setting of + '$libdir/mylib' would cause + mylib.so (or on some platforms, + mylib.sl) to be preloaded from the installation's standard + library directory. The differences between the settings are when they + take effect and what privileges are required to change them. + + + + PostgreSQL procedural language libraries can + be preloaded in this way, typically by using the + syntax '$libdir/plXXX' where + XXX is pgsql, perl, + tcl, or python. + + + + Only shared libraries specifically intended to be used with PostgreSQL + can be loaded this way. Every PostgreSQL-supported library has + a magic block that is checked to guarantee compatibility. For + this reason, non-PostgreSQL libraries cannot be loaded in this way. You + might be able to use operating-system facilities such + as LD_PRELOAD for that. + + + + In general, refer to the documentation of a specific module for the + recommended way to load that module. + + + + + local_preload_libraries (string) + + local_preload_libraries configuration parameter + + + $libdir/plugins + + + + + This variable specifies one or more shared libraries that are to be + preloaded at connection start. + It contains a comma-separated list of library names, where each name + is interpreted as for the LOAD command. + Whitespace between entries is ignored; surround a library name with + double quotes if you need to include whitespace or commas in the name. + The parameter value only takes effect at the start of the connection. + Subsequent changes have no effect. If a specified library is not + found, the connection attempt will fail. + + + + This option can be set by any user. Because of that, the libraries + that can be loaded are restricted to those appearing in the + plugins subdirectory of the installation's + standard library directory. (It is the database administrator's + responsibility to ensure that only safe libraries + are installed there.) Entries in local_preload_libraries + can specify this directory explicitly, for example + $libdir/plugins/mylib, or just specify + the library name — mylib would have + the same effect as $libdir/plugins/mylib. + + + + The intent of this feature is to allow unprivileged users to load + debugging or performance-measurement libraries into specific sessions + without requiring an explicit LOAD command. To that end, + it would be typical to set this parameter using + the PGOPTIONS environment variable on the client or by + using + ALTER ROLE SET. + + + + However, unless a module is specifically designed to be used in this way by + non-superusers, this is usually not the right setting to use. Look + at instead. + + + + + + + session_preload_libraries (string) + + session_preload_libraries configuration parameter + + + + + This variable specifies one or more shared libraries that are to be + preloaded at connection start. + It contains a comma-separated list of library names, where each name + is interpreted as for the LOAD command. + Whitespace between entries is ignored; surround a library name with + double quotes if you need to include whitespace or commas in the name. + The parameter value only takes effect at the start of the connection. + Subsequent changes have no effect. If a specified library is not + found, the connection attempt will fail. + Only superusers can change this setting. + + + + The intent of this feature is to allow debugging or + performance-measurement libraries to be loaded into specific sessions + without an explicit + LOAD command being given. For + example, could be enabled for all + sessions under a given user name by setting this parameter + with ALTER ROLE SET. Also, this parameter can be changed + without restarting the server (but changes only take effect when a new + session is started), so it is easier to add new modules this way, even + if they should apply to all sessions. + + + + Unlike , there is no large + performance advantage to loading a library at session start rather than + when it is first used. There is some advantage, however, when + connection pooling is used. + + + + + + shared_preload_libraries (string) + + shared_preload_libraries configuration parameter + + + + + This variable specifies one or more shared libraries to be preloaded at + server start. + It contains a comma-separated list of library names, where each name + is interpreted as for the LOAD command. + Whitespace between entries is ignored; surround a library name with + double quotes if you need to include whitespace or commas in the name. + This parameter can only be set at server start. If a specified + library is not found, the server will fail to start. + + + + Some libraries need to perform certain operations that can only take + place at postmaster start, such as allocating shared memory, reserving + light-weight locks, or starting background workers. Those libraries + must be loaded at server start through this parameter. See the + documentation of each library for details. + + + + Other libraries can also be preloaded. By preloading a shared library, + the library startup time is avoided when the library is first used. + However, the time to start each new server process might increase + slightly, even if that process never uses the library. So this + parameter is recommended only for libraries that will be used in most + sessions. Also, changing this parameter requires a server restart, so + this is not the right setting to use for short-term debugging tasks, + say. Use for that + instead. + + + + + On Windows hosts, preloading a library at server start will not reduce + the time required to start each new server process; each server process + will re-load all preload libraries. However, shared_preload_libraries + is still useful on Windows hosts for libraries that need to + perform operations at postmaster start time. + + + + + + + jit_provider (string) + + jit_provider configuration parameter + + + + + This variable is the name of the JIT provider library to be used + (see ). + The default is llvmjit. + This parameter can only be set at server start. + + + + If set to a non-existent library, JIT will not be + available, but no error will be raised. This allows JIT support to be + installed separately from the main + PostgreSQL package. + + + + + + + + + Other Defaults + + + + + dynamic_library_path (string) + + dynamic_library_path configuration parameter + + dynamic loading + + + + If a dynamically loadable module needs to be opened and the + file name specified in the CREATE FUNCTION or + LOAD command + does not have a directory component (i.e., the + name does not contain a slash), the system will search this + path for the required file. + + + + The value for dynamic_library_path must be a + list of absolute directory paths separated by colons (or semi-colons + on Windows). If a list element starts + with the special string $libdir, the + compiled-in PostgreSQL package + library directory is substituted for $libdir; this + is where the modules provided by the standard + PostgreSQL distribution are installed. + (Use pg_config --pkglibdir to find out the name of + this directory.) For example: + +dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir' + + or, in a Windows environment: + +dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + + + + The default value for this parameter is + '$libdir'. If the value is set to an empty + string, the automatic path search is turned off. + + + + This parameter can be changed at run time by superusers, but a + setting done that way will only persist until the end of the + client connection, so this method should be reserved for + development purposes. The recommended way to set this parameter + is in the postgresql.conf configuration + file. + + + + + + gin_fuzzy_search_limit (integer) + + gin_fuzzy_search_limit configuration parameter + + + + + Soft upper limit of the size of the set returned by GIN index scans. For more + information see . + + + + + + + + + + Lock Management + + + + + deadlock_timeout (integer) + + deadlock + timeout during + + + timeout + deadlock + + + deadlock_timeout configuration parameter + + + + + This is the amount of time to wait on a lock + before checking to see if there is a deadlock condition. The + check for deadlock is relatively expensive, so the server doesn't run + it every time it waits for a lock. We optimistically assume + that deadlocks are not common in production applications and + just wait on the lock for a while before checking for a + deadlock. Increasing this value reduces the amount of time + wasted in needless deadlock checks, but slows down reporting of + real deadlock errors. + If this value is specified without units, it is taken as milliseconds. + The default is one second (1s), + which is probably about the smallest value you would want in + practice. On a heavily loaded server you might want to raise it. + Ideally the setting should exceed your typical transaction time, + so as to improve the odds that a lock will be released before + the waiter decides to check for deadlock. Only superusers can change + this setting. + + + + When is set, + this parameter also determines the amount of time to wait before + a log message is issued about the lock wait. If you are trying + to investigate locking delays you might want to set a shorter than + normal deadlock_timeout. + + + + + + max_locks_per_transaction (integer) + + max_locks_per_transaction configuration parameter + + + + + The shared lock table tracks locks on + max_locks_per_transaction * ( + ) objects (e.g., tables); + hence, no more than this many distinct objects can be locked at + any one time. This parameter controls the average number of object + locks allocated for each transaction; individual transactions + can lock more objects as long as the locks of all transactions + fit in the lock table. This is not the number of + rows that can be locked; that value is unlimited. The default, + 64, has historically proven sufficient, but you might need to + raise this value if you have queries that touch many different + tables in a single transaction, e.g., query of a parent table with + many children. This parameter can only be set at server start. + + + + When running a standby server, you must set this parameter to the + same or higher value than on the primary server. Otherwise, queries + will not be allowed in the standby server. + + + + + + max_pred_locks_per_transaction (integer) + + max_pred_locks_per_transaction configuration parameter + + + + + The shared predicate lock table tracks locks on + max_pred_locks_per_transaction * ( + ) objects (e.g., tables); + hence, no more than this many distinct objects can be locked at + any one time. This parameter controls the average number of object + locks allocated for each transaction; individual transactions + can lock more objects as long as the locks of all transactions + fit in the lock table. This is not the number of + rows that can be locked; that value is unlimited. The default, + 64, has generally been sufficient in testing, but you might need to + raise this value if you have clients that touch many different + tables in a single serializable transaction. This parameter can + only be set at server start. + + + + + + max_pred_locks_per_relation (integer) + + max_pred_locks_per_relation configuration parameter + + + + + This controls how many pages or tuples of a single relation can be + predicate-locked before the lock is promoted to covering the whole + relation. Values greater than or equal to zero mean an absolute + limit, while negative values + mean divided by + the absolute value of this setting. The default is -2, which keeps + the behavior from previous versions of PostgreSQL. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + max_pred_locks_per_page (integer) + + max_pred_locks_per_page configuration parameter + + + + + This controls how many rows on a single page can be predicate-locked + before the lock is promoted to covering the whole page. The default + is 2. This parameter can only be set in + the postgresql.conf file or on the server command line. + + + + + + + + + Version and Platform Compatibility + + + Previous PostgreSQL Versions + + + + + array_nulls (boolean) + + array_nulls configuration parameter + + + + + This controls whether the array input parser recognizes + unquoted NULL as specifying a null array element. + By default, this is on, allowing array values containing + null values to be entered. However, PostgreSQL versions + before 8.2 did not support null values in arrays, and therefore would + treat NULL as specifying a normal array element with + the string value NULL. For backward compatibility with + applications that require the old behavior, this variable can be + turned off. + + + + Note that it is possible to create array values containing null values + even when this variable is off. + + + + + + backslash_quote (enum) + stringsbackslash quotes + + backslash_quote configuration parameter + + + + + This controls whether a quote mark can be represented by + \' in a string literal. The preferred, SQL-standard way + to represent a quote mark is by doubling it ('') but + PostgreSQL has historically also accepted + \'. However, use of \' creates security risks + because in some client character set encodings, there are multibyte + characters in which the last byte is numerically equivalent to ASCII + \. If client-side code does escaping incorrectly then an + SQL-injection attack is possible. This risk can be prevented by + making the server reject queries in which a quote mark appears to be + escaped by a backslash. + The allowed values of backslash_quote are + on (allow \' always), + off (reject always), and + safe_encoding (allow only if client encoding does not + allow ASCII \ within a multibyte character). + safe_encoding is the default setting. + + + + Note that in a standard-conforming string literal, \ just + means \ anyway. This parameter only affects the handling of + non-standard-conforming literals, including + escape string syntax (E'...'). + + + + + + escape_string_warning (boolean) + stringsescape warning + + escape_string_warning configuration parameter + + + + + When on, a warning is issued if a backslash (\) + appears in an ordinary string literal ('...' + syntax) and standard_conforming_strings is off. + The default is on. + + + Applications that wish to use backslash as escape should be + modified to use escape string syntax (E'...'), + because the default behavior of ordinary strings is now to treat + backslash as an ordinary character, per SQL standard. This variable + can be enabled to help locate code that needs to be changed. + + + + + + lo_compat_privileges (boolean) + + lo_compat_privileges configuration parameter + + + + + In PostgreSQL releases prior to 9.0, large objects + did not have access privileges and were, therefore, always readable + and writable by all users. Setting this variable to on + disables the new privilege checks, for compatibility with prior + releases. The default is off. + Only superusers can change this setting. + + + Setting this variable does not disable all security checks related to + large objects — only those for which the default behavior has + changed in PostgreSQL 9.0. + + + + + + quote_all_identifiers (boolean) + + quote_all_identifiers configuration parameter + + + + + When the database generates SQL, force all identifiers to be quoted, + even if they are not (currently) keywords. This will affect the + output of EXPLAIN as well as the results of functions + like pg_get_viewdef. See also the + option of + and . + + + + + + standard_conforming_strings (boolean) + stringsstandard conforming + + standard_conforming_strings configuration parameter + + + + + This controls whether ordinary string literals + ('...') treat backslashes literally, as specified in + the SQL standard. + Beginning in PostgreSQL 9.1, the default is + on (prior releases defaulted to off). + Applications can check this + parameter to determine how string literals will be processed. + The presence of this parameter can also be taken as an indication + that the escape string syntax (E'...') is supported. + Escape string syntax () + should be used if an application desires + backslashes to be treated as escape characters. + + + + + + synchronize_seqscans (boolean) + + synchronize_seqscans configuration parameter + + + + + This allows sequential scans of large tables to synchronize with each + other, so that concurrent scans read the same block at about the + same time and hence share the I/O workload. When this is enabled, + a scan might start in the middle of the table and then wrap + around the end to cover all rows, so as to synchronize with the + activity of scans already in progress. This can result in + unpredictable changes in the row ordering returned by queries that + have no ORDER BY clause. Setting this parameter to + off ensures the pre-8.3 behavior in which a sequential + scan always starts from the beginning of the table. The default + is on. + + + + + + + + + Platform and Client Compatibility + + + + transform_null_equals (boolean) + IS NULL + + transform_null_equals configuration parameter + + + + + When on, expressions of the form expr = + NULL (or NULL = + expr) are treated as + expr IS NULL, that is, they + return true if expr evaluates to the null value, + and false otherwise. The correct SQL-spec-compliant behavior of + expr = NULL is to always + return null (unknown). Therefore this parameter defaults to + off. + + + + However, filtered forms in Microsoft + Access generate queries that appear to use + expr = NULL to test for + null values, so if you use that interface to access the database you + might want to turn this option on. Since expressions of the + form expr = NULL always + return the null value (using the SQL standard interpretation), they are not + very useful and do not appear often in normal applications so + this option does little harm in practice. But new users are + frequently confused about the semantics of expressions + involving null values, so this option is off by default. + + + + Note that this option only affects the exact form = NULL, + not other comparison operators or other expressions + that are computationally equivalent to some expression + involving the equals operator (such as IN). + Thus, this option is not a general fix for bad programming. + + + + Refer to for related information. + + + + + + + + + + Error Handling + + + + + exit_on_error (boolean) + + exit_on_error configuration parameter + + + + + If on, any error will terminate the current session. By default, + this is set to off, so that only FATAL errors will terminate the + session. + + + + + + restart_after_crash (boolean) + + restart_after_crash configuration parameter + + + + + When set to on, which is the default, PostgreSQL + will automatically reinitialize after a backend crash. Leaving this + value set to on is normally the best way to maximize the availability + of the database. However, in some circumstances, such as when + PostgreSQL is being invoked by clusterware, it may be + useful to disable the restart so that the clusterware can gain + control and take any actions it deems appropriate. + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + data_sync_retry (boolean) + + data_sync_retry configuration parameter + + + + + When set to off, which is the default, PostgreSQL + will raise a PANIC-level error on failure to flush modified data files + to the file system. This causes the database server to crash. This + parameter can only be set at server start. + + + On some operating systems, the status of data in the kernel's page + cache is unknown after a write-back failure. In some cases it might + have been entirely forgotten, making it unsafe to retry; the second + attempt may be reported as successful, when in fact the data has been + lost. In these circumstances, the only way to avoid data loss is to + recover from the WAL after any failure is reported, preferably + after investigating the root cause of the failure and replacing any + faulty hardware. + + + If set to on, PostgreSQL will instead + report an error but continue to run so that the data flushing + operation can be retried in a later checkpoint. Only set it to on + after investigating the operating system's treatment of buffered data + in case of write-back failure. + + + + + + recovery_init_sync_method (enum) + + recovery_init_sync_method configuration parameter + + + + + When set to fsync, which is the default, + PostgreSQL will recursively open and + synchronize all files in the data directory before crash recovery + begins. The search for files will follow symbolic links for the WAL + directory and each configured tablespace (but not any other symbolic + links). This is intended to make sure that all WAL and data files are + durably stored on disk before replaying changes. This applies whenever + starting a database cluster that did not shut down cleanly, including + copies created with pg_basebackup. + + + On Linux, syncfs may be used instead, to ask the + operating system to synchronize the whole file systems that contain the + data directory, the WAL files and each tablespace (but not any other + file systems that may be reachable through symbolic links). This may + be a lot faster than the fsync setting, because it + doesn't need to open each file one by one. On the other hand, it may + be slower if a file system is shared by other applications that + modify a lot of files, since those files will also be written to disk. + Furthermore, on versions of Linux before 5.8, I/O errors encountered + while writing data to disk may not be reported to + PostgreSQL, and relevant error messages may + appear only in kernel logs. + + + This parameter can only be set in the + postgresql.conf file or on the server command line. + + + + + + + + + + Preset Options + + + The following parameters are read-only. + As such, they have been excluded from the sample + postgresql.conf file. These options report + various aspects of PostgreSQL behavior + that might be of interest to certain applications, particularly + administrative front-ends. + Most of them are determined when PostgreSQL + is compiled or when it is installed. + + + + + + block_size (integer) + + block_size configuration parameter + + + + + Reports the size of a disk block. It is determined by the value + of BLCKSZ when building the server. The default + value is 8192 bytes. The meaning of some configuration + variables (such as ) is + influenced by block_size. See for information. + + + + + + data_checksums (boolean) + + data_checksums configuration parameter + + + + + Reports whether data checksums are enabled for this cluster. + See for more information. + + + + + + data_directory_mode (integer) + + data_directory_mode configuration parameter + + + + + On Unix systems this parameter reports the permissions the data + directory (defined by ) + had at server startup. + (On Microsoft Windows this parameter will always display + 0700.) See + for more information. + + + + + + debug_assertions (boolean) + + debug_assertions configuration parameter + + + + + Reports whether PostgreSQL has been built + with assertions enabled. That is the case if the + macro USE_ASSERT_CHECKING is defined + when PostgreSQL is built (accomplished + e.g., by the configure option + ). By + default PostgreSQL is built without + assertions. + + + + + + integer_datetimes (boolean) + + integer_datetimes configuration parameter + + + + + Reports whether PostgreSQL was built with support for + 64-bit-integer dates and times. As of PostgreSQL 10, + this is always on. + + + + + + in_hot_standby (boolean) + + in_hot_standby configuration parameter + + + + + Reports whether the server is currently in hot standby mode. When + this is on, all transactions are forced to be + read-only. Within a session, this can change only if the server is + promoted to be primary. See for more + information. + + + + + + lc_collate (string) + + lc_collate configuration parameter + + + + + Reports the locale in which sorting of textual data is done. + See for more information. + This value is determined when a database is created. + + + + + + lc_ctype (string) + + lc_ctype configuration parameter + + + + + Reports the locale that determines character classifications. + See for more information. + This value is determined when a database is created. + Ordinarily this will be the same as lc_collate, + but for special applications it might be set differently. + + + + + + max_function_args (integer) + + max_function_args configuration parameter + + + + + Reports the maximum number of function arguments. It is determined by + the value of FUNC_MAX_ARGS when building the server. The + default value is 100 arguments. + + + + + + max_identifier_length (integer) + + max_identifier_length configuration parameter + + + + + Reports the maximum identifier length. It is determined as one + less than the value of NAMEDATALEN when building + the server. The default value of NAMEDATALEN is + 64; therefore the default + max_identifier_length is 63 bytes, which + can be less than 63 characters when using multibyte encodings. + + + + + + max_index_keys (integer) + + max_index_keys configuration parameter + + + + + Reports the maximum number of index keys. It is determined by + the value of INDEX_MAX_KEYS when building the server. The + default value is 32 keys. + + + + + + segment_size (integer) + + segment_size configuration parameter + + + + + Reports the number of blocks (pages) that can be stored within a file + segment. It is determined by the value of RELSEG_SIZE + when building the server. The maximum size of a segment file in bytes + is equal to segment_size multiplied by + block_size; by default this is 1GB. + + + + + + server_encoding (string) + + server_encoding configuration parameter + + character set + + + + Reports the database encoding (character set). + It is determined when the database is created. Ordinarily, + clients need only be concerned with the value of . + + + + + + server_version (string) + + server_version configuration parameter + + + + + Reports the version number of the server. It is determined by the + value of PG_VERSION when building the server. + + + + + + server_version_num (integer) + + server_version_num configuration parameter + + + + + Reports the version number of the server as an integer. It is determined + by the value of PG_VERSION_NUM when building the server. + + + + + + ssl_library (string) + + ssl_library configuration parameter + + + + + Reports the name of the SSL library that this + PostgreSQL server was built with (even if + SSL is not currently configured or in use on this instance), for + example OpenSSL, or an empty string if none. + + + + + + wal_block_size (integer) + + wal_block_size configuration parameter + + + + + Reports the size of a WAL disk block. It is determined by the value + of XLOG_BLCKSZ when building the server. The default value + is 8192 bytes. + + + + + + wal_segment_size (integer) + + wal_segment_size configuration parameter + + + + + Reports the size of write ahead log segments. The default value is + 16MB. See for more information. + + + + + + + + + Customized Options + + + This feature was designed to allow parameters not normally known to + PostgreSQL to be added by add-on modules + (such as procedural languages). This allows extension modules to be + configured in the standard ways. + + + + Custom options have two-part names: an extension name, then a dot, then + the parameter name proper, much like qualified names in SQL. An example + is plpgsql.variable_conflict. + + + + Because custom options may need to be set in processes that have not + loaded the relevant extension module, PostgreSQL + will accept a setting for any two-part parameter name. Such variables + are treated as placeholders and have no function until the module that + defines them is loaded. When an extension module is loaded, it will add + its variable definitions, convert any placeholder values according to + those definitions, and issue warnings for any unrecognized placeholders + that begin with its extension name. + + + + + Developer Options + + + The following parameters are intended for developer testing, and + should never be used on a production database. However, some of + them can be used to assist with the recovery of severely damaged + databases. As such, they have been excluded from the sample + postgresql.conf file. Note that many of these + parameters require special source compilation flags to work at all. + + + + + allow_system_table_mods (boolean) + + allow_system_table_mods configuration parameter + + + + + Allows modification of the structure of system tables as well as + certain other risky actions on system tables. This is otherwise not + allowed even for superusers. Ill-advised use of this setting can + cause irretrievable data loss or seriously corrupt the database + system. Only superusers can change this setting. + + + + + + backtrace_functions (string) + + backtrace_functions configuration parameter + + + + + This parameter contains a comma-separated list of C function names. + If an error is raised and the name of the internal C function where + the error happens matches a value in the list, then a backtrace is + written to the server log together with the error message. This can + be used to debug specific areas of the source code. + + + + Backtrace support is not available on all platforms, and the quality + of the backtraces depends on compilation options. + + + + This parameter can only be set by superusers. + + + + + + debug_invalidate_system_caches_always (integer) + + debug_invalidate_system_caches_always configuration parameter + + + + + When set to 1, each system catalog cache entry is + invalidated at the first possible opportunity, whether or not + anything that would render it invalid really occurred. Caching of + system catalogs is effectively disabled as a result, so the server + will run extremely slowly. Higher values run the cache invalidation + recursively, which is even slower and only useful for testing + the caching logic itself. The default value of 0 + selects normal catalog caching behavior. + + + + This parameter can be very helpful when trying to trigger + hard-to-reproduce bugs involving concurrent catalog changes, but it + is otherwise rarely needed. See the source code files + inval.c and + pg_config_manual.h for details. + + + + This parameter is supported when + CLOBBER_CACHE_ENABLED was defined at compile time + (which happens automatically when using the + configure option + ). In production builds, its value + will always be 0 and attempts to set it to another + value will raise an error. + + + + + + force_parallel_mode (enum) + + force_parallel_mode configuration parameter + + + + + Allows the use of parallel queries for testing purposes even in cases + where no performance benefit is expected. + The allowed values of force_parallel_mode are + off (use parallel mode only when it is expected to improve + performance), on (force parallel query for all queries + for which it is thought to be safe), and regress (like + on, but with additional behavior changes as explained + below). + + + + More specifically, setting this value to on will add + a Gather node to the top of any query plan for which this + appears to be safe, so that the query runs inside of a parallel worker. + Even when a parallel worker is not available or cannot be used, + operations such as starting a subtransaction that would be prohibited + in a parallel query context will be prohibited unless the planner + believes that this will cause the query to fail. If failures or + unexpected results occur when this option is set, some functions used + by the query may need to be marked PARALLEL UNSAFE + (or, possibly, PARALLEL RESTRICTED). + + + + Setting this value to regress has all of the same effects + as setting it to on plus some additional effects that are + intended to facilitate automated regression testing. Normally, + messages from a parallel worker include a context line indicating that, + but a setting of regress suppresses this line so that the + output is the same as in non-parallel execution. Also, + the Gather nodes added to plans by this setting are hidden + in EXPLAIN output so that the output matches what + would be obtained if this setting were turned off. + + + + + + ignore_system_indexes (boolean) + + ignore_system_indexes configuration parameter + + + + + Ignore system indexes when reading system tables (but still + update the indexes when modifying the tables). This is useful + when recovering from damaged system indexes. + This parameter cannot be changed after session start. + + + + + + post_auth_delay (integer) + + post_auth_delay configuration parameter + + + + + The amount of time to delay when a new + server process is started, after it conducts the + authentication procedure. This is intended to give developers an + opportunity to attach to the server process with a debugger. + If this value is specified without units, it is taken as seconds. + A value of zero (the default) disables the delay. + This parameter cannot be changed after session start. + + + + + + pre_auth_delay (integer) + + pre_auth_delay configuration parameter + + + + + The amount of time to delay just after a + new server process is forked, before it conducts the + authentication procedure. This is intended to give developers an + opportunity to attach to the server process with a debugger to + trace down misbehavior in authentication. + If this value is specified without units, it is taken as seconds. + A value of zero (the default) disables the delay. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + trace_notify (boolean) + + trace_notify configuration parameter + + + + + Generates a great amount of debugging output for the + LISTEN and NOTIFY + commands. or + must be + DEBUG1 or lower to send this output to the + client or server logs, respectively. + + + + + + trace_recovery_messages (enum) + + trace_recovery_messages configuration parameter + + + + + Enables logging of recovery-related debugging output that otherwise + would not be logged. This parameter allows the user to override the + normal setting of , but only for + specific messages. This is intended for use in debugging Hot Standby. + Valid values are DEBUG5, DEBUG4, + DEBUG3, DEBUG2, DEBUG1, and + LOG. The default, LOG, does not affect + logging decisions at all. The other values cause recovery-related + debug messages of that priority or higher to be logged as though they + had LOG priority; for common settings of + log_min_messages this results in unconditionally sending + them to the server log. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + trace_sort (boolean) + + trace_sort configuration parameter + + + + + If on, emit information about resource usage during sort operations. + This parameter is only available if the TRACE_SORT macro + was defined when PostgreSQL was compiled. + (However, TRACE_SORT is currently defined by default.) + + + + + + trace_locks (boolean) + + trace_locks configuration parameter + + + + + If on, emit information about lock usage. Information dumped + includes the type of lock operation, the type of lock and the unique + identifier of the object being locked or unlocked. Also included + are bit masks for the lock types already granted on this object as + well as for the lock types awaited on this object. For each lock + type a count of the number of granted locks and waiting locks is + also dumped as well as the totals. An example of the log file output + is shown here: + +LOG: LockAcquire: new: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 + wait(0) type(AccessShareLock) +LOG: GrantLock: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(2) req(1,0,0,0,0,0,0)=1 grant(1,0,0,0,0,0,0)=1 + wait(0) type(AccessShareLock) +LOG: UnGrantLock: updated: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 + wait(0) type(AccessShareLock) +LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) + grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0 + wait(0) type(INVALID) + + Details of the structure being dumped may be found in + src/include/storage/lock.h. + + + This parameter is only available if the LOCK_DEBUG + macro was defined when PostgreSQL was + compiled. + + + + + + trace_lwlocks (boolean) + + trace_lwlocks configuration parameter + + + + + If on, emit information about lightweight lock usage. Lightweight + locks are intended primarily to provide mutual exclusion of access + to shared-memory data structures. + + + This parameter is only available if the LOCK_DEBUG + macro was defined when PostgreSQL was + compiled. + + + + + + trace_userlocks (boolean) + + trace_userlocks configuration parameter + + + + + If on, emit information about user lock usage. Output is the same + as for trace_locks, only for advisory locks. + + + This parameter is only available if the LOCK_DEBUG + macro was defined when PostgreSQL was + compiled. + + + + + + trace_lock_oidmin (integer) + + trace_lock_oidmin configuration parameter + + + + + If set, do not trace locks for tables below this OID (used to avoid + output on system tables). + + + This parameter is only available if the LOCK_DEBUG + macro was defined when PostgreSQL was + compiled. + + + + + + trace_lock_table (integer) + + trace_lock_table configuration parameter + + + + + Unconditionally trace locks on this table (OID). + + + This parameter is only available if the LOCK_DEBUG + macro was defined when PostgreSQL was + compiled. + + + + + + debug_deadlocks (boolean) + + debug_deadlocks configuration parameter + + + + + If set, dumps information about all current locks when a + deadlock timeout occurs. + + + This parameter is only available if the LOCK_DEBUG + macro was defined when PostgreSQL was + compiled. + + + + + + log_btree_build_stats (boolean) + + log_btree_build_stats configuration parameter + + + + + If set, logs system resource usage statistics (memory and CPU) on + various B-tree operations. + + + This parameter is only available if the BTREE_BUILD_STATS + macro was defined when PostgreSQL was + compiled. + + + + + + wal_consistency_checking (string) + + wal_consistency_checking configuration parameter + + + + + This parameter is intended to be used to check for bugs in the WAL + redo routines. When enabled, full-page images of any buffers modified + in conjunction with the WAL record are added to the record. + If the record is subsequently replayed, the system will first apply + each record and then test whether the buffers modified by the record + match the stored images. In certain cases (such as hint bits), minor + variations are acceptable, and will be ignored. Any unexpected + differences will result in a fatal error, terminating recovery. + + + + The default value of this setting is the empty string, which disables + the feature. It can be set to all to check all + records, or to a comma-separated list of resource managers to check + only records originating from those resource managers. Currently, + the supported resource managers are heap, + heap2, btree, hash, + gin, gist, sequence, + spgist, brin, and generic. Only + superusers can change this setting. + + + + + + wal_debug (boolean) + + wal_debug configuration parameter + + + + + If on, emit WAL-related debugging output. This parameter is + only available if the WAL_DEBUG macro was + defined when PostgreSQL was + compiled. + + + + + + ignore_checksum_failure (boolean) + + ignore_checksum_failure configuration parameter + + + + + Only has effect if are enabled. + + + Detection of a checksum failure during a read normally causes + PostgreSQL to report an error, aborting the current + transaction. Setting ignore_checksum_failure to on causes + the system to ignore the failure (but still report a warning), and + continue processing. This behavior may cause crashes, propagate + or hide corruption, or other serious problems. However, it may allow + you to get past the error and retrieve undamaged tuples that might still be + present in the table if the block header is still sane. If the header is + corrupt an error will be reported even if this option is enabled. The + default setting is off, and it can only be changed by a superuser. + + + + + + zero_damaged_pages (boolean) + + zero_damaged_pages configuration parameter + + + + + Detection of a damaged page header normally causes + PostgreSQL to report an error, aborting the current + transaction. Setting zero_damaged_pages to on causes + the system to instead report a warning, zero out the damaged + page in memory, and continue processing. This behavior will destroy data, + namely all the rows on the damaged page. However, it does allow you to get + past the error and retrieve rows from any undamaged pages that might + be present in the table. It is useful for recovering data if + corruption has occurred due to a hardware or software error. You should + generally not set this on until you have given up hope of recovering + data from the damaged pages of a table. Zeroed-out pages are not + forced to disk so it is recommended to recreate the table or + the index before turning this parameter off again. The + default setting is off, and it can only be changed + by a superuser. + + + + + + ignore_invalid_pages (boolean) + + ignore_invalid_pages configuration parameter + + + + + If set to off (the default), detection of + WAL records having references to invalid pages during + recovery causes PostgreSQL to + raise a PANIC-level error, aborting the recovery. Setting + ignore_invalid_pages to on + causes the system to ignore invalid page references in WAL records + (but still report a warning), and continue the recovery. + This behavior may cause crashes, data loss, + propagate or hide corruption, or other serious problems. + However, it may allow you to get past the PANIC-level error, + to finish the recovery, and to cause the server to start up. + The parameter can only be set at server start. It only has effect + during recovery or in standby mode. + + + + + + jit_debugging_support (boolean) + + jit_debugging_support configuration parameter + + + + + If LLVM has the required functionality, register generated functions + with GDB. This makes debugging easier. + The default setting is off. + This parameter can only be set at server start. + + + + + + jit_dump_bitcode (boolean) + + jit_dump_bitcode configuration parameter + + + + + Writes the generated LLVM IR out to the + file system, inside . This is only + useful for working on the internals of the JIT implementation. + The default setting is off. + This parameter can only be changed by a superuser. + + + + + + jit_expressions (boolean) + + jit_expressions configuration parameter + + + + + Determines whether expressions are JIT compiled, when JIT compilation + is activated (see ). The default is + on. + + + + + + jit_profiling_support (boolean) + + jit_profiling_support configuration parameter + + + + + If LLVM has the required functionality, emit the data needed to allow + perf to profile functions generated by JIT. + This writes out files to ~/.debug/jit/; the + user is responsible for performing cleanup when desired. + The default setting is off. + This parameter can only be set at server start. + + + + + + jit_tuple_deforming (boolean) + + jit_tuple_deforming configuration parameter + + + + + Determines whether tuple deforming is JIT compiled, when JIT + compilation is activated (see ). + The default is on. + + + + + + remove_temp_files_after_crash (boolean) + + remove_temp_files_after_crash configuration parameter + + + + + When set to on, which is the default, + PostgreSQL will automatically remove + temporary files after a backend crash. If disabled, the files will be + retained and may be used for debugging, for example. Repeated crashes + may however result in accumulation of useless files. This parameter + can only be set in the postgresql.conf file or on + the server command line. + + + + + + + + Short Options + + + For convenience there are also single letter command-line option + switches available for some parameters. They are described in + . Some of these + options exist for historical reasons, and their presence as a + single-letter option does not necessarily indicate an endorsement + to use the option heavily. + + + + Short Option Key + + + + + + Short Option + Equivalent + + + + + + + shared_buffers = x + + + + log_min_messages = DEBUGx + + + + datestyle = euro + + + + , , , + , , , + , + + + enable_bitmapscan = off, + enable_hashjoin = off, + enable_indexscan = off, + enable_mergejoin = off, + enable_nestloop = off, + enable_indexonlyscan = off, + enable_seqscan = off, + enable_tidscan = off + + + + + fsync = off + + + + listen_addresses = x + + + + listen_addresses = '*' + + + + unix_socket_directories = x + + + + ssl = on + + + + max_connections = x + + + + allow_system_table_mods = on + + + + port = x + + + + ignore_system_indexes = on + + + + log_statement_stats = on + + + + work_mem = x + + + , , + log_parser_stats = on, + log_planner_stats = on, + log_executor_stats = on + + + + post_auth_delay = x + + + +
+ +
+
diff --git a/doc/src/sgml/contrib.sgml b/doc/src/sgml/contrib.sgml new file mode 100644 index 000000000000..d3ca4b693200 --- /dev/null +++ b/doc/src/sgml/contrib.sgml @@ -0,0 +1,203 @@ + + + + Additional Supplied Modules + + + This appendix and the next one contain information regarding the modules that + can be found in the contrib directory of the + PostgreSQL distribution. + These include porting tools, analysis utilities, + and plug-in features that are not part of the core PostgreSQL system, + mainly because they address a limited audience or are too experimental + to be part of the main source tree. This does not preclude their + usefulness. + + + + This appendix covers extensions and other server plug-in modules found in + contrib. covers utility + programs. + + + + When building from the source distribution, these components are not built + automatically, unless you build the "world" target + (see ). + You can build and install all of them by running: + +make +make install + + in the contrib directory of a configured source tree; + or to build and install + just one selected module, do the same in that module's subdirectory. + Many of the modules have regression tests, which can be executed by + running: + +make check + + before installation or + +make installcheck + + once you have a PostgreSQL server running. + + + + If you are using a pre-packaged version of PostgreSQL, + these modules are typically made available as a separate subpackage, + such as postgresql-contrib. + + + + Many modules supply new user-defined functions, operators, or types. + To make use of one of these modules, after you have installed the code + you need to register the new SQL objects in the database system. + This is done by executing + a command. In a fresh database, + you can simply do + + +CREATE EXTENSION module_name; + + + This command registers the new SQL objects in the current database only, + so you need to run it in each database that you want + the module's facilities to be available in. Alternatively, run it in + database template1 so that the extension will be copied into + subsequently-created databases by default. + + + + For all these modules, CREATE EXTENSION must be run + by a database superuser, unless the module is + considered trusted, in which case it can be run by any + user who has CREATE privilege on the current + database. Modules that are trusted are identified as such in the + sections that follow. Generally, trusted modules are ones that cannot + provide access to outside-the-database functionality. + + + + Many modules allow you to install their objects in a schema of your + choice. To do that, add SCHEMA + schema_name to the CREATE EXTENSION + command. By default, the objects will be placed in your current creation + target schema, which in turn defaults to public. + + + + Note, however, that some of these modules are not extensions + in this sense, but are loaded into the server in some other way, for instance + by way of + . See the documentation of each + module for details. + + + &adminpack; + &amcheck; + &auth-delay; + &auto-explain; + &bloom; + &btree-gin; + &btree-gist; + &citext; + &cube; + &dblink; + &dict-int; + &dict-xsyn; + &earthdistance; + &file-fdw; + &fuzzystrmatch; + &hstore; + &intagg; + &intarray; + &isn; + &lo; + <ree; + &oldsnapshot; + &pageinspect; + &passwordcheck; + &pgbuffercache; + &pgcrypto; + &pgfreespacemap; + &pgprewarm; + &pgrowlocks; + &pgstatstatements; + &pgstattuple; + &pgsurgery; + &pgtrgm; + &pgvisibility; + &postgres-fdw; + &seg; + &sepgsql; + &contrib-spi; + &sslinfo; + &tablefunc; + &tcn; + &test-decoding; + &tsm-system-rows; + &tsm-system-time; + &unaccent; + &uuid-ossp; + &xml2; + + + + + + + Additional Supplied Programs + + + This appendix and the previous one contain information regarding the modules that + can be found in the contrib directory of the + PostgreSQL distribution. See for + more information about the contrib section in general and + server extensions and plug-ins found in contrib + specifically. + + + + This appendix covers utility programs found in contrib. + Once installed, either from source or a packaging system, they are found in + the bin directory of the + PostgreSQL installation and can be used like any + other program. + + + + Client Applications + + + This section covers PostgreSQL client + applications in contrib. They can be run from anywhere, + independent of where the database server resides. See + also for information about client + applications that are part of the core PostgreSQL + distribution. + + + &oid2name; + &vacuumlo; + + + + Server Applications + + + Some applications run on the PostgreSQL server + itself. Currently, no such applications are included in the + contrib directory. See also for information about server applications that + are part of the core PostgreSQL distribution. + + + + diff --git a/doc/src/sgml/cube.sgml b/doc/src/sgml/cube.sgml new file mode 100644 index 000000000000..adf8dbaa9172 --- /dev/null +++ b/doc/src/sgml/cube.sgml @@ -0,0 +1,639 @@ + + + + cube + + + cube (extension) + + + + This module implements a data type cube for + representing multidimensional cubes. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Syntax + + + shows the valid external + representations for the cube + type. x, y, etc. denote + floating-point numbers. + + + + Cube External Representations + + + + External Syntax + Meaning + + + + + + x + A one-dimensional point + (or, zero-length one-dimensional interval) + + + + (x) + Same as above + + + x1,x2,...,xn + A point in n-dimensional space, represented internally as a + zero-volume cube + + + + (x1,x2,...,xn) + Same as above + + + (x),(y) + A one-dimensional interval starting at x and ending at y or vice versa; the + order does not matter + + + + [(x),(y)] + Same as above + + + (x1,...,xn),(y1,...,yn) + An n-dimensional cube represented by a pair of its diagonally + opposite corners + + + + [(x1,...,xn),(y1,...,yn)] + Same as above + + + +
+ + + It does not matter which order the opposite corners of a cube are + entered in. The cube functions + automatically swap values if needed to create a uniform + lower left — upper right internal representation. + When the corners coincide, cube stores only one corner + along with an is point flag to avoid wasting space. + + + + White space is ignored on input, so + [(x),(y)] is the same as + [ ( x ), ( y ) ]. + +
+ + + Precision + + + Values are stored internally as 64-bit floating point numbers. This means + that numbers with more than about 16 significant digits will be truncated. + + + + + Usage + + + shows the specialized operators + provided for type cube. + + + + Cube Operators + + + + + Operator + + + Description + + + + + + + + cube && cube + boolean + + + Do the cubes overlap? + + + + + + cube @> cube + boolean + + + Does the first cube contain the second? + + + + + + cube <@ cube + boolean + + + Is the first cube contained in the second? + + + + + + cube -> integer + float8 + + + Extracts the n-th coordinate of the cube + (counting from 1). + + + + + + cube ~> integer + float8 + + + Extracts the n-th coordinate of the cube, + counting in the following way: n = 2 + * k - 1 means lower bound + of k-th dimension, n = 2 + * k means upper bound of + k-th dimension. Negative + n denotes the inverse value of the corresponding + positive coordinate. This operator is designed for KNN-GiST support. + + + + + + cube <-> cube + float8 + + + Computes the Euclidean distance between the two cubes. + + + + + + cube <#> cube + float8 + + + Computes the taxicab (L-1 metric) distance between the two cubes. + + + + + + cube <=> cube + float8 + + + Computes the Chebyshev (L-inf metric) distance between the two cubes. + + + + +
+ + + In addition to the above operators, the usual comparison + operators shown in are + available for type cube. These + operators first compare the first coordinates, and if those are equal, + compare the second coordinates, etc. They exist mainly to support the + b-tree index operator class for cube, which can be useful for + example if you would like a UNIQUE constraint on a cube column. + Otherwise, this ordering is not of much practical use. + + + + The cube module also provides a GiST index operator class for + cube values. + A cube GiST index can be used to search for values using the + =, &&, @>, and + <@ operators in WHERE clauses. + + + + In addition, a cube GiST index can be used to find nearest + neighbors using the metric operators + <->, <#>, and + <=> in ORDER BY clauses. + For example, the nearest neighbor of the 3-D point (0.5, 0.5, 0.5) + could be found efficiently with: + +SELECT c FROM test ORDER BY c <-> cube(array[0.5,0.5,0.5]) LIMIT 1; + + + + + The ~> operator can also be used in this way to + efficiently retrieve the first few values sorted by a selected coordinate. + For example, to get the first few cubes ordered by the first coordinate + (lower left corner) ascending one could use the following query: + +SELECT c FROM test ORDER BY c ~> 1 LIMIT 5; + + And to get 2-D cubes ordered by the first coordinate of the upper right + corner descending: + +SELECT c FROM test ORDER BY c ~> 3 DESC LIMIT 5; + + + + + shows the available functions. + + + + Cube Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + cube ( float8 ) + cube + + + Makes a one dimensional cube with both coordinates the same. + + + cube(1) + (1) + + + + + + cube ( float8, float8 ) + cube + + + Makes a one dimensional cube. + + + cube(1, 2) + (1),(2) + + + + + + cube ( float8[] ) + cube + + + Makes a zero-volume cube using the coordinates defined by the array. + + + cube(ARRAY[1,2,3]) + (1, 2, 3) + + + + + + cube ( float8[], float8[] ) + cube + + + Makes a cube with upper right and lower left coordinates as defined by + the two arrays, which must be of the same length. + + + cube(ARRAY[1,2], ARRAY[3,4]) + (1, 2),(3, 4) + + + + + + cube ( cube, float8 ) + cube + + + Makes a new cube by adding a dimension on to an existing cube, + with the same values for both endpoints of the new coordinate. This + is useful for building cubes piece by piece from calculated values. + + + cube('(1,2),(3,4)'::cube, 5) + (1, 2, 5),(3, 4, 5) + + + + + + cube ( cube, float8, float8 ) + cube + + + Makes a new cube by adding a dimension on to an existing cube. This is + useful for building cubes piece by piece from calculated values. + + + cube('(1,2),(3,4)'::cube, 5, 6) + (1, 2, 5),(3, 4, 6) + + + + + + cube_dim ( cube ) + integer + + + Returns the number of dimensions of the cube. + + + cube_dim('(1,2),(3,4)') + 2 + + + + + + cube_ll_coord ( cube, integer ) + float8 + + + Returns the n-th coordinate value for the lower + left corner of the cube. + + + cube_ll_coord('(1,2),(3,4)', 2) + 2 + + + + + + cube_ur_coord ( cube, integer ) + float8 + + + Returns the n-th coordinate value for the + upper right corner of the cube. + + + cube_ur_coord('(1,2),(3,4)', 2) + 4 + + + + + + cube_is_point ( cube ) + boolean + + + Returns true if the cube is a point, that is, + the two defining corners are the same. + + + cube_is_point(cube(1,1)) + t + + + + + + cube_distance ( cube, cube ) + float8 + + + Returns the distance between two cubes. If both + cubes are points, this is the normal distance function. + + + cube_distance('(1,2)', '(3,4)') + 2.8284271247461903 + + + + + + cube_subset ( cube, integer[] ) + cube + + + Makes a new cube from an existing cube, using a list of + dimension indexes from an array. Can be used to extract the endpoints + of a single dimension, or to drop dimensions, or to reorder them as + desired. + + + cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2]) + (3),(7) + + + cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]) + (5, 3, 1, 1),(8, 7, 6, 6) + + + + + + cube_union ( cube, cube ) + cube + + + Produces the union of two cubes. + + + cube_union('(1,2)', '(3,4)') + (1, 2),(3, 4) + + + + + + cube_inter ( cube, cube ) + cube + + + Produces the intersection of two cubes. + + + cube_inter('(1,2)', '(3,4)') + (3, 4),(1, 2) + + + + + + cube_enlarge ( c cube, r double, n integer ) + cube + + + Increases the size of the cube by the specified + radius r in at least n + dimensions. If the radius is negative the cube is shrunk instead. + All defined dimensions are changed by the + radius r. Lower-left coordinates are decreased + by r and upper-right coordinates are increased + by r. If a lower-left coordinate is increased + to more than the corresponding upper-right coordinate (this can only + happen when r < 0) than both coordinates are + set to their average. If n is greater than the + number of defined dimensions and the cube is being enlarged + (r > 0), then extra dimensions are added to + make n altogether; 0 is used as the initial + value for the extra coordinates. This function is useful for creating + bounding boxes around a point for searching for nearby points. + + + cube_enlarge('(1,2),(3,4)', 0.5, 3) + (0.5, 1.5, -0.5),(3.5, 4.5, 0.5) + + + + +
+
+ + + Defaults + + + I believe this union: + + +select cube_union('(0,5,2),(2,3,1)', '0'); +cube_union +------------------- +(0, 0, 0),(2, 5, 2) +(1 row) + + + + does not contradict common sense, neither does the intersection + + + +select cube_inter('(0,-1),(1,1)', '(-2),(2)'); +cube_inter +------------- +(0, 0),(1, 0) +(1 row) + + + + In all binary operations on differently-dimensioned cubes, I assume the + lower-dimensional one to be a Cartesian projection, i. e., having zeroes + in place of coordinates omitted in the string representation. The above + examples are equivalent to: + + + +cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)'); +cube_inter('(0,-1),(1,1)','(-2,0),(2,0)'); + + + + The following containment predicate uses the point syntax, + while in fact the second argument is internally represented by a box. + This syntax makes it unnecessary to define a separate point type + and functions for (box,point) predicates. + + + +select cube_contains('(0,0),(1,1)', '0.5,0.5'); +cube_contains +-------------- +t +(1 row) + + + + + Notes + + + For examples of usage, see the regression test sql/cube.sql. + + + + To make it harder for people to break things, there + is a limit of 100 on the number of dimensions of cubes. This is set + in cubedata.h if you need something bigger. + + + + + Credits + + + Original author: Gene Selkov, Jr. selkovjr@mcs.anl.gov, + Mathematics and Computer Science Division, Argonne National Laboratory. + + + + My thanks are primarily to Prof. Joe Hellerstein + () for elucidating the + gist of the GiST (), and + to his former student Andy Dong for his example written for Illustra. + I am also grateful to all Postgres developers, present and past, for + enabling myself to create my own world and live undisturbed in it. And I + would like to acknowledge my gratitude to Argonne Lab and to the + U.S. Department of Energy for the years of faithful support of my database + research. + + + + Minor updates to this package were made by Bruno Wolff III + bruno@wolff.to in August/September of 2002. These include + changing the precision from single precision to double precision and adding + some new functions. + + + + Additional updates were made by Joshua Reich josh@root.net in + July 2006. These include cube(float8[], float8[]) and + cleaning up the code to use the V1 call protocol instead of the deprecated + V0 protocol. + + + +
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml new file mode 100644 index 000000000000..de561cded1e9 --- /dev/null +++ b/doc/src/sgml/datatype.sgml @@ -0,0 +1,5271 @@ + + + + Data Types + + + data type + + + + type + data type + + + + PostgreSQL has a rich set of native data + types available to users. Users can add new types to + PostgreSQL using the command. + + + + shows all the built-in general-purpose data + types. Most of the alternative names listed in the + Aliases column are the names used internally by + PostgreSQL for historical reasons. In + addition, some internally used or deprecated types are available, + but are not listed here. + + + + Data Types + + + + + + + Name + Aliases + Description + + + + + + bigint + int8 + signed eight-byte integer + + + + bigserial + serial8 + autoincrementing eight-byte integer + + + + bit [ (n) ] + + fixed-length bit string + + + + bit varying [ (n) ] + varbit [ (n) ] + variable-length bit string + + + + boolean + bool + logical Boolean (true/false) + + + + box + + rectangular box on a plane + + + + bytea + + binary data (byte array) + + + + character [ (n) ] + char [ (n) ] + fixed-length character string + + + + character varying [ (n) ] + varchar [ (n) ] + variable-length character string + + + + cidr + + IPv4 or IPv6 network address + + + + circle + + circle on a plane + + + + date + + calendar date (year, month, day) + + + + double precision + float8 + double precision floating-point number (8 bytes) + + + + inet + + IPv4 or IPv6 host address + + + + integer + int, int4 + signed four-byte integer + + + + interval [ fields ] [ (p) ] + + time span + + + + json + + textual JSON data + + + + jsonb + + binary JSON data, decomposed + + + + line + + infinite line on a plane + + + + lseg + + line segment on a plane + + + + macaddr + + MAC (Media Access Control) address + + + + macaddr8 + + MAC (Media Access Control) address (EUI-64 format) + + + + money + + currency amount + + + + numeric [ (p, + s) ] + decimal [ (p, + s) ] + exact numeric of selectable precision + + + + path + + geometric path on a plane + + + + pg_lsn + + PostgreSQL Log Sequence Number + + + + pg_snapshot + + user-level transaction ID snapshot + + + + point + + geometric point on a plane + + + + polygon + + closed geometric path on a plane + + + + real + float4 + single precision floating-point number (4 bytes) + + + + smallint + int2 + signed two-byte integer + + + + smallserial + serial2 + autoincrementing two-byte integer + + + + serial + serial4 + autoincrementing four-byte integer + + + + text + + variable-length character string + + + + time [ (p) ] [ without time zone ] + + time of day (no time zone) + + + + time [ (p) ] with time zone + timetz + time of day, including time zone + + + + timestamp [ (p) ] [ without time zone ] + + date and time (no time zone) + + + + timestamp [ (p) ] with time zone + timestamptz + date and time, including time zone + + + + tsquery + + text search query + + + + tsvector + + text search document + + + + txid_snapshot + + user-level transaction ID snapshot (deprecated; see pg_snapshot) + + + + uuid + + universally unique identifier + + + + xml + + XML data + + + +
+ + + Compatibility + + The following types (or spellings thereof) are specified by + SQL: bigint, bit, bit + varying, boolean, char, + character varying, character, + varchar, date, double + precision, integer, interval, + numeric, decimal, real, + smallint, time (with or without time zone), + timestamp (with or without time zone), + xml. + + + + + Each data type has an external representation determined by its input + and output functions. Many of the built-in types have + obvious external formats. However, several types are either unique + to PostgreSQL, such as geometric + paths, or have several possible formats, such as the date + and time types. + Some of the input and output functions are not invertible, i.e., + the result of an output function might lose accuracy when compared to + the original input. + + + + Numeric Types + + + data type + numeric + + + + Numeric types consist of two-, four-, and eight-byte integers, + four- and eight-byte floating-point numbers, and selectable-precision + decimals. lists the + available types. + + + + Numeric Types + + + + + + + + Name + Storage Size + Description + Range + + + + + + smallint + 2 bytes + small-range integer + -32768 to +32767 + + + integer + 4 bytes + typical choice for integer + -2147483648 to +2147483647 + + + bigint + 8 bytes + large-range integer + -9223372036854775808 to +9223372036854775807 + + + + decimal + variable + user-specified precision, exact + up to 131072 digits before the decimal point; up to 16383 digits after the decimal point + + + numeric + variable + user-specified precision, exact + up to 131072 digits before the decimal point; up to 16383 digits after the decimal point + + + + real + 4 bytes + variable-precision, inexact + 6 decimal digits precision + + + double precision + 8 bytes + variable-precision, inexact + 15 decimal digits precision + + + + smallserial + 2 bytes + small autoincrementing integer + 1 to 32767 + + + + serial + 4 bytes + autoincrementing integer + 1 to 2147483647 + + + + bigserial + 8 bytes + large autoincrementing integer + 1 to 9223372036854775807 + + + +
+ + + The syntax of constants for the numeric types is described in + . The numeric types have a + full set of corresponding arithmetic operators and + functions. Refer to for more + information. The following sections describe the types in detail. + + + + Integer Types + + + integer + + + + smallint + + + + bigint + + + + int4 + integer + + + + int2 + smallint + + + + int8 + bigint + + + + The types smallint, integer, and + bigint store whole numbers, that is, numbers without + fractional components, of various ranges. Attempts to store + values outside of the allowed range will result in an error. + + + + The type integer is the common choice, as it offers + the best balance between range, storage size, and performance. + The smallint type is generally only used if disk + space is at a premium. The bigint type is designed to be + used when the range of the integer type is insufficient. + + + + SQL only specifies the integer types + integer (or int), + smallint, and bigint. The + type names int2, int4, and + int8 are extensions, which are also used by some + other SQL database systems. + + + + + + Arbitrary Precision Numbers + + + numeric (data type) + + + + arbitrary precision numbers + + + + decimal + numeric + + + + The type numeric can store numbers with a + very large number of digits. It is especially recommended for + storing monetary amounts and other quantities where exactness is + required. Calculations with numeric values yield exact + results where possible, e.g., addition, subtraction, multiplication. + However, calculations on numeric values are very slow + compared to the integer types, or to the floating-point types + described in the next section. + + + + We use the following terms below: The + precision of a numeric + is the total count of significant digits in the whole number, + that is, the number of digits to both sides of the decimal point. + The scale of a numeric is the + count of decimal digits in the fractional part, to the right of the + decimal point. So the number 23.5141 has a precision of 6 and a + scale of 4. Integers can be considered to have a scale of zero. + + + + Both the maximum precision and the maximum scale of a + numeric column can be + configured. To declare a column of type numeric use + the syntax: + +NUMERIC(precision, scale) + + The precision must be positive, the scale zero or positive. + Alternatively: + +NUMERIC(precision) + + selects a scale of 0. Specifying: + +NUMERIC + + without any precision or scale creates an unconstrained + numeric column in which numeric values of any length can be + stored, up to the implementation limits. A column of this kind will + not coerce input values to any particular scale, whereas + numeric columns with a declared scale will coerce + input values to that scale. (The SQL standard + requires a default scale of 0, i.e., coercion to integer + precision. We find this a bit useless. If you're concerned + about portability, always specify the precision and scale + explicitly.) + + + + + The maximum precision that can be explicitly specified in + a NUMERIC type declaration is 1000. An + unconstrained NUMERIC column is subject to the limits + described in . + + + + + If the scale of a value to be stored is greater than the declared + scale of the column, the system will round the value to the specified + number of fractional digits. Then, if the number of digits to the + left of the decimal point exceeds the declared precision minus the + declared scale, an error is raised. + + + + Numeric values are physically stored without any extra leading or + trailing zeroes. Thus, the declared precision and scale of a column + are maximums, not fixed allocations. (In this sense the numeric + type is more akin to varchar(n) + than to char(n).) The actual storage + requirement is two bytes for each group of four decimal digits, + plus three to eight bytes overhead. + + + + infinity + numeric (data type) + + + + NaN + not a number + + + + not a number + numeric (data type) + + + + In addition to ordinary numeric values, the numeric type + has several special values: + +Infinity +-Infinity +NaN + + These are adapted from the IEEE 754 standard, and represent + infinity, negative infinity, and + not-a-number, respectively. When writing these values + as constants in an SQL command, you must put quotes around them, + for example UPDATE table SET x = '-Infinity'. + On input, these strings are recognized in a case-insensitive manner. + The infinity values can alternatively be spelled inf + and -inf. + + + + The infinity values behave as per mathematical expectations. For + example, Infinity plus any finite value equals + Infinity, as does Infinity + plus Infinity; but Infinity + minus Infinity yields NaN (not a + number), because it has no well-defined interpretation. Note that an + infinity can only be stored in an unconstrained numeric + column, because it notionally exceeds any finite precision limit. + + + + The NaN (not a number) value is used to represent + undefined calculational results. In general, any operation with + a NaN input yields another NaN. + The only exception is when the operation's other inputs are such that + the same output would be obtained if the NaN were to + be replaced by any finite or infinite numeric value; then, that output + value is used for NaN too. (An example of this + principle is that NaN raised to the zero power + yields one.) + + + + + In most implementations of the not-a-number concept, + NaN is not considered equal to any other numeric + value (including NaN). In order to allow + numeric values to be sorted and used in tree-based + indexes, PostgreSQL treats NaN + values as equal, and greater than all non-NaN + values. + + + + + The types decimal and numeric are + equivalent. Both types are part of the SQL + standard. + + + + When rounding values, the numeric type rounds ties away + from zero, while (on most machines) the real + and double precision types round ties to the nearest even + number. For example: + + +SELECT x, + round(x::numeric) AS num_round, + round(x::double precision) AS dbl_round +FROM generate_series(-3.5, 3.5, 1) as x; + x | num_round | dbl_round +------+-----------+----------- + -3.5 | -4 | -4 + -2.5 | -3 | -2 + -1.5 | -2 | -2 + -0.5 | -1 | -0 + 0.5 | 1 | 0 + 1.5 | 2 | 2 + 2.5 | 3 | 2 + 3.5 | 4 | 4 +(8 rows) + + + + + + + Floating-Point Types + + + real + + + + double precision + + + + float4 + real + + + + float8 + double precision + + + + floating point + + + + The data types real and double precision are + inexact, variable-precision numeric types. On all currently supported + platforms, these types are implementations of IEEE + Standard 754 for Binary Floating-Point Arithmetic (single and double + precision, respectively), to the extent that the underlying processor, + operating system, and compiler support it. + + + + Inexact means that some values cannot be converted exactly to the + internal format and are stored as approximations, so that storing + and retrieving a value might show slight discrepancies. + Managing these errors and how they propagate through calculations + is the subject of an entire branch of mathematics and computer + science and will not be discussed here, except for the + following points: + + + + If you require exact storage and calculations (such as for + monetary amounts), use the numeric type instead. + + + + + + If you want to do complicated calculations with these types + for anything important, especially if you rely on certain + behavior in boundary cases (infinity, underflow), you should + evaluate the implementation carefully. + + + + + + Comparing two floating-point values for equality might not + always work as expected. + + + + + + + On all currently supported platforms, the real type has a + range of around 1E-37 to 1E+37 with a precision of at least 6 decimal + digits. The double precision type has a range of around + 1E-307 to 1E+308 with a precision of at least 15 digits. Values that are + too large or too small will cause an error. Rounding might take place if + the precision of an input number is too high. Numbers too close to zero + that are not representable as distinct from zero will cause an underflow + error. + + + + By default, floating point values are output in text form in their + shortest precise decimal representation; the decimal value produced is + closer to the true stored binary value than to any other value + representable in the same binary precision. (However, the output value is + currently never exactly midway between two + representable values, in order to avoid a widespread bug where input + routines do not properly respect the round-to-nearest-even rule.) This value will + use at most 17 significant decimal digits for float8 + values, and at most 9 digits for float4 values. + + + + + This shortest-precise output format is much faster to generate than the + historical rounded format. + + + + + For compatibility with output generated by older versions + of PostgreSQL, and to allow the output + precision to be reduced, the + parameter can be used to select rounded decimal output instead. Setting a + value of 0 restores the previous default of rounding the value to 6 + (for float4) or 15 (for float8) + significant decimal digits. Setting a negative value reduces the number + of digits further; for example -2 would round output to 4 or 13 digits + respectively. + + + + Any value of greater than 0 + selects the shortest-precise format. + + + + + Applications that wanted precise values have historically had to set + to 3 to obtain them. For + maximum compatibility between versions, they should continue to do so. + + + + + infinity + floating point + + + + not a number + floating point + + + + In addition to ordinary numeric values, the floating-point types + have several special values: + +Infinity +-Infinity +NaN + + These represent the IEEE 754 special values + infinity, negative infinity, and + not-a-number, respectively. When writing these values + as constants in an SQL command, you must put quotes around them, + for example UPDATE table SET x = '-Infinity'. On input, + these strings are recognized in a case-insensitive manner. + The infinity values can alternatively be spelled inf + and -inf. + + + + + IEEE 754 specifies that NaN should not compare equal + to any other floating-point value (including NaN). + In order to allow floating-point values to be sorted and used + in tree-based indexes, PostgreSQL treats + NaN values as equal, and greater than all + non-NaN values. + + + + + PostgreSQL also supports the SQL-standard + notations float and + float(p) for specifying + inexact numeric types. Here, p specifies + the minimum acceptable precision in binary digits. + PostgreSQL accepts + float(1) to float(24) as selecting the + real type, while + float(25) to float(53) select + double precision. Values of p + outside the allowed range draw an error. + float with no precision specified is taken to mean + double precision. + + + + + + Serial Types + + + smallserial + + + + serial + + + + bigserial + + + + serial2 + + + + serial4 + + + + serial8 + + + + auto-increment + serial + + + + sequence + and serial type + + + + + This section describes a PostgreSQL-specific way to create an + autoincrementing column. Another way is to use the SQL-standard + identity column feature, described at . + + + + + The data types smallserial, serial and + bigserial are not true types, but merely + a notational convenience for creating unique identifier columns + (similar to the AUTO_INCREMENT property + supported by some other databases). In the current + implementation, specifying: + + +CREATE TABLE tablename ( + colname SERIAL +); + + + is equivalent to specifying: + + +CREATE SEQUENCE tablename_colname_seq AS integer; +CREATE TABLE tablename ( + colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') +); +ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname; + + + Thus, we have created an integer column and arranged for its default + values to be assigned from a sequence generator. A NOT NULL + constraint is applied to ensure that a null value cannot be + inserted. (In most cases you would also want to attach a + UNIQUE or PRIMARY KEY constraint to prevent + duplicate values from being inserted by accident, but this is + not automatic.) Lastly, the sequence is marked as owned by + the column, so that it will be dropped if the column or table is dropped. + + + + + Because smallserial, serial and + bigserial are implemented using sequences, there may + be "holes" or gaps in the sequence of values which appears in the + column, even if no rows are ever deleted. A value allocated + from the sequence is still "used up" even if a row containing that + value is never successfully inserted into the table column. This + may happen, for example, if the inserting transaction rolls back. + See nextval() in + for details. + + + + + To insert the next value of the sequence into the serial + column, specify that the serial + column should be assigned its default value. This can be done + either by excluding the column from the list of columns in + the INSERT statement, or through the use of + the DEFAULT key word. + + + + The type names serial and serial4 are + equivalent: both create integer columns. The type + names bigserial and serial8 work + the same way, except that they create a bigint + column. bigserial should be used if you anticipate + the use of more than 231 identifiers over the + lifetime of the table. The type names smallserial and + serial2 also work the same way, except that they + create a smallint column. + + + + The sequence created for a serial column is + automatically dropped when the owning column is dropped. + You can drop the sequence without dropping the column, but this + will force removal of the column default expression. + + +
+ + + Monetary Types + + + The money type stores a currency amount with a fixed + fractional precision; see . The fractional precision is + determined by the database's setting. + The range shown in the table assumes there are two fractional digits. + Input is accepted in a variety of formats, including integer and + floating-point literals, as well as typical + currency formatting, such as '$1,000.00'. + Output is generally in the latter form but depends on the locale. + + + + Monetary Types + + + + + + + + Name + Storage Size + Description + Range + + + + + money + 8 bytes + currency amount + -92233720368547758.08 to +92233720368547758.07 + + + +
+ + + Since the output of this data type is locale-sensitive, it might not + work to load money data into a database that has a different + setting of lc_monetary. To avoid problems, before + restoring a dump into a new database make sure lc_monetary has + the same or equivalent value as in the database that was dumped. + + + + Values of the numeric, int, and + bigint data types can be cast to money. + Conversion from the real and double precision + data types can be done by casting to numeric first, for + example: + +SELECT '12.34'::float8::numeric::money; + + However, this is not recommended. Floating point numbers should not be + used to handle money due to the potential for rounding errors. + + + + A money value can be cast to numeric without + loss of precision. Conversion to other types could potentially lose + precision, and must also be done in two stages: + +SELECT '52093.89'::money::numeric::float8; + + + + + Division of a money value by an integer value is performed + with truncation of the fractional part towards zero. To get a rounded + result, divide by a floating-point value, or cast the money + value to numeric before dividing and back to money + afterwards. (The latter is preferable to avoid risking precision loss.) + When a money value is divided by another money + value, the result is double precision (i.e., a pure number, + not money); the currency units cancel each other out in the division. + +
+ + + + Character Types + + + character string + data types + + + + string + character string + + + + character + + + + character varying + + + + text + + + + char + + + + varchar + + + + Character Types + + + + Name + Description + + + + + character varying(n), varchar(n) + variable-length with limit + + + character(n), char(n) + fixed-length, blank padded + + + text + variable unlimited length + + + +
+ + + shows the + general-purpose character types available in + PostgreSQL. + + + + SQL defines two primary character types: + character varying(n) and + character(n), where n + is a positive integer. Both of these types can store strings up to + n characters (not bytes) in length. An attempt to store a + longer string into a column of these types will result in an + error, unless the excess characters are all spaces, in which case + the string will be truncated to the maximum length. (This somewhat + bizarre exception is required by the SQL + standard.) If the string to be stored is shorter than the declared + length, values of type character will be space-padded; + values of type character varying will simply store the + shorter + string. + + + + If one explicitly casts a value to character + varying(n) or + character(n), then an over-length + value will be truncated to n characters without + raising an error. (This too is required by the + SQL standard.) + + + + The notations varchar(n) and + char(n) are aliases for character + varying(n) and + character(n), respectively. + character without length specifier is equivalent to + character(1). If character varying is used + without length specifier, the type accepts strings of any size. The + latter is a PostgreSQL extension. + + + + In addition, PostgreSQL provides the + text type, which stores strings of any length. + Although the type text is not in the + SQL standard, several other SQL database + management systems have it as well. + + + + Values of type character are physically padded + with spaces to the specified width n, and are + stored and displayed that way. However, trailing spaces are treated as + semantically insignificant and disregarded when comparing two values + of type character. In collations where whitespace + is significant, this behavior can produce unexpected results; + for example SELECT 'a '::CHAR(2) collate "C" < + E'a\n'::CHAR(2) returns true, even though C + locale would consider a space to be greater than a newline. + Trailing spaces are removed when converting a character value + to one of the other string types. Note that trailing spaces + are semantically significant in + character varying and text values, and + when using pattern matching, that is LIKE and + regular expressions. + + + + The characters that can be stored in any of these data types are + determined by the database character set, which is selected when + the database is created. Regardless of the specific character set, + the character with code zero (sometimes called NUL) cannot be stored. + For more information refer to . + + + + The storage requirement for a short string (up to 126 bytes) is 1 byte + plus the actual string, which includes the space padding in the case of + character. Longer strings have 4 bytes of overhead instead + of 1. Long strings are compressed by the system automatically, so + the physical requirement on disk might be less. Very long values are also + stored in background tables so that they do not interfere with rapid + access to shorter column values. In any case, the longest + possible character string that can be stored is about 1 GB. (The + maximum value that will be allowed for n in the data + type declaration is less than that. It wouldn't be useful to + change this because with multibyte character encodings the number of + characters and bytes can be quite different. If you desire to + store long strings with no specific upper limit, use + text or character varying without a length + specifier, rather than making up an arbitrary length limit.) + + + + + There is no performance difference among these three types, + apart from increased storage space when using the blank-padded + type, and a few extra CPU cycles to check the length when storing into + a length-constrained column. While + character(n) has performance + advantages in some other database systems, there is no such advantage in + PostgreSQL; in fact + character(n) is usually the slowest of + the three because of its additional storage costs. In most situations + text or character varying should be used + instead. + + + + + Refer to for information about + the syntax of string literals, and to + for information about available operators and functions. + + + + Using the Character Types + + +CREATE TABLE test1 (a character(4)); +INSERT INTO test1 VALUES ('ok'); +SELECT a, char_length(a) FROM test1; -- + + a | char_length +------+------------- + ok | 2 + + +CREATE TABLE test2 (b varchar(5)); +INSERT INTO test2 VALUES ('ok'); +INSERT INTO test2 VALUES ('good '); +INSERT INTO test2 VALUES ('too long'); +ERROR: value too long for type character varying(5) +INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation +SELECT b, char_length(b) FROM test2; + + b | char_length +-------+------------- + ok | 2 + good | 5 + too l | 5 + + + + + + The char_length function is discussed in + . + + + + + + + There are two other fixed-length character types in + PostgreSQL, shown in . The name + type exists only for the storage of identifiers + in the internal system catalogs and is not intended for use by the general user. Its + length is currently defined as 64 bytes (63 usable characters plus + terminator) but should be referenced using the constant + NAMEDATALEN in C source code. + The length is set at compile time (and + is therefore adjustable for special uses); the default maximum + length might change in a future release. The type "char" + (note the quotes) is different from char(1) in that it + only uses one byte of storage. It is internally used in the system + catalogs as a simplistic enumeration type. + + + + Special Character Types + + + + Name + Storage Size + Description + + + + + "char" + 1 byte + single-byte internal type + + + name + 64 bytes + internal type for object names + + + +
+ +
+ + + Binary Data Types + + + binary data + + + + bytea + + + + The bytea data type allows storage of binary strings; + see . + + + + Binary Data Types + + + + + + + Name + Storage Size + Description + + + + + bytea + 1 or 4 bytes plus the actual binary string + variable-length binary string + + + +
+ + + A binary string is a sequence of octets (or bytes). Binary + strings are distinguished from character strings in two + ways. First, binary strings specifically allow storing + octets of value zero and other non-printable + octets (usually, octets outside the decimal range 32 to 126). + Character strings disallow zero octets, and also disallow any + other octet values and sequences of octet values that are invalid + according to the database's selected character set encoding. + Second, operations on binary strings process the actual bytes, + whereas the processing of character strings depends on locale settings. + In short, binary strings are appropriate for storing data that the + programmer thinks of as raw bytes, whereas character + strings are appropriate for storing text. + + + + The bytea type supports two + formats for input and output: hex format + and PostgreSQL's historical + escape format. Both + of these are always accepted on input. The output format depends + on the configuration parameter ; + the default is hex. (Note that the hex format was introduced in + PostgreSQL 9.0; earlier versions and some + tools don't understand it.) + + + + The SQL standard defines a different binary + string type, called BLOB or BINARY LARGE + OBJECT. The input format is different from + bytea, but the provided functions and operators are + mostly the same. + + + + <type>bytea</type> Hex Format + + + The hex format encodes binary data as 2 hexadecimal digits + per byte, most significant nibble first. The entire string is + preceded by the sequence \x (to distinguish it + from the escape format). In some contexts, the initial backslash may + need to be escaped by doubling it + (see ). + For input, the hexadecimal digits can + be either upper or lower case, and whitespace is permitted between + digit pairs (but not within a digit pair nor in the starting + \x sequence). + The hex format is compatible with a wide + range of external applications and protocols, and it tends to be + faster to convert than the escape format, so its use is preferred. + + + + Example: + +SELECT '\xDEADBEEF'; + + + + + + <type>bytea</type> Escape Format + + + The escape format is the traditional + PostgreSQL format for the bytea + type. It + takes the approach of representing a binary string as a sequence + of ASCII characters, while converting those bytes that cannot be + represented as an ASCII character into special escape sequences. + If, from the point of view of the application, representing bytes + as characters makes sense, then this representation can be + convenient. But in practice it is usually confusing because it + fuzzes up the distinction between binary strings and character + strings, and also the particular escape mechanism that was chosen is + somewhat unwieldy. Therefore, this format should probably be avoided + for most new applications. + + + + When entering bytea values in escape format, + octets of certain + values must be escaped, while all octet + values can be escaped. In + general, to escape an octet, convert it into its three-digit + octal value and precede it by a backslash. + Backslash itself (octet decimal value 92) can alternatively be represented by + double backslashes. + + shows the characters that must be escaped, and gives the alternative + escape sequences where applicable. + + + + <type>bytea</type> Literal Escaped Octets + + + + + + + + + Decimal Octet Value + Description + Escaped Input Representation + Example + Hex Representation + + + + + + 0 + zero octet + '\000' + '\000'::bytea + \x00 + + + + 39 + single quote + '''' or '\047' + ''''::bytea + \x27 + + + + 92 + backslash + '\\' or '\134' + '\\'::bytea + \x5c + + + + 0 to 31 and 127 to 255 + non-printable octets + '\xxx' (octal value) + '\001'::bytea + \x01 + + + + +
+ + + The requirement to escape non-printable octets + varies depending on locale settings. In some instances you can get away + with leaving them unescaped. + + + + The reason that single quotes must be doubled, as shown + in , is that this + is true for any string literal in an SQL command. The generic + string-literal parser consumes the outermost single quotes + and reduces any pair of single quotes to one data character. + What the bytea input function sees is just one + single quote, which it treats as a plain data character. + However, the bytea input function treats + backslashes as special, and the other behaviors shown in + are implemented by + that function. + + + + In some contexts, backslashes must be doubled compared to what is + shown above, because the generic string-literal parser will also + reduce pairs of backslashes to one data character; + see . + + + + Bytea octets are output in hex + format by default. If you change + to escape, + non-printable octets are converted to their + equivalent three-digit octal value and preceded by one backslash. + Most printable octets are output by their standard + representation in the client character set, e.g.: + + +SET bytea_output = 'escape'; + +SELECT 'abc \153\154\155 \052\251\124'::bytea; + bytea +---------------- + abc klm *\251T + + + The octet with decimal value 92 (backslash) is doubled in the output. + Details are in . + + + + <type>bytea</type> Output Escaped Octets + + + + + + + + + Decimal Octet Value + Description + Escaped Output Representation + Example + Output Result + + + + + + + 92 + backslash + \\ + '\134'::bytea + \\ + + + + 0 to 31 and 127 to 255 + non-printable octets + \xxx (octal value) + '\001'::bytea + \001 + + + + 32 to 126 + printable octets + client character set representation + '\176'::bytea + ~ + + + + +
+ + + Depending on the front end to PostgreSQL you use, + you might have additional work to do in terms of escaping and + unescaping bytea strings. For example, you might also + have to escape line feeds and carriage returns if your interface + automatically translates these. + +
+
+ + + + Date/Time Types + + + date + + + time + + + time without time zone + + + time with time zone + + + timestamp + + + timestamptz + + + timestamp with time zone + + + timestamp without time zone + + + interval + + + time span + + + + PostgreSQL supports the full set of + SQL date and time types, shown in . The operations available + on these data types are described in + . + Dates are counted according to the Gregorian calendar, even in + years before that calendar was introduced (see for more information). + + + + Date/Time Types + + + + Name + Storage Size + Description + Low Value + High Value + Resolution + + + + + timestamp [ (p) ] [ without time zone ] + 8 bytes + both date and time (no time zone) + 4713 BC + 294276 AD + 1 microsecond + + + timestamp [ (p) ] with time zone + 8 bytes + both date and time, with time zone + 4713 BC + 294276 AD + 1 microsecond + + + date + 4 bytes + date (no time of day) + 4713 BC + 5874897 AD + 1 day + + + time [ (p) ] [ without time zone ] + 8 bytes + time of day (no date) + 00:00:00 + 24:00:00 + 1 microsecond + + + time [ (p) ] with time zone + 12 bytes + time of day (no date), with time zone + + 00:00:00+1559 + 24:00:00-1559 + 1 microsecond + + + interval [ fields ] [ (p) ] + 16 bytes + time interval + -178000000 years + 178000000 years + 1 microsecond + + + +
+ + + + The SQL standard requires that writing just timestamp + be equivalent to timestamp without time + zone, and PostgreSQL honors that + behavior. timestamptz is accepted as an + abbreviation for timestamp with time zone; this is a + PostgreSQL extension. + + + + + time, timestamp, and + interval accept an optional precision value + p which specifies the number of + fractional digits retained in the seconds field. By default, there + is no explicit bound on precision. The allowed range of + p is from 0 to 6. + + + + The interval type has an additional option, which is + to restrict the set of stored fields by writing one of these phrases: + +YEAR +MONTH +DAY +HOUR +MINUTE +SECOND +YEAR TO MONTH +DAY TO HOUR +DAY TO MINUTE +DAY TO SECOND +HOUR TO MINUTE +HOUR TO SECOND +MINUTE TO SECOND + + Note that if both fields and + p are specified, the + fields must include SECOND, + since the precision applies only to the seconds. + + + + The type time with time zone is defined by the SQL + standard, but the definition exhibits properties which lead to + questionable usefulness. In most cases, a combination of + date, time, timestamp without time + zone, and timestamp with time zone should + provide a complete range of date/time functionality required by + any application. + + + + Date/Time Input + + + Date and time input is accepted in almost any reasonable format, including + ISO 8601, SQL-compatible, + traditional POSTGRES, and others. + For some formats, ordering of day, month, and year in date input is + ambiguous and there is support for specifying the expected + ordering of these fields. Set the parameter + to MDY to select month-day-year interpretation, + DMY to select day-month-year interpretation, or + YMD to select year-month-day interpretation. + + + + PostgreSQL is more flexible in + handling date/time input than the + SQL standard requires. + See + for the exact parsing rules of date/time input and for the + recognized text fields including months, days of the week, and + time zones. + + + + Remember that any date or time literal input needs to be enclosed + in single quotes, like text strings. Refer to + for more + information. + SQL requires the following syntax + +type [ (p) ] 'value' + + where p is an optional precision + specification giving the number of + fractional digits in the seconds field. Precision can be + specified for time, timestamp, and + interval types, and can range from 0 to 6. + If no precision is specified in a constant specification, + it defaults to the precision of the literal value (but not + more than 6 digits). + + + + Dates + + + date + + + + shows some possible + inputs for the date type. + + + + Date Input + + + + + + Example + Description + + + + + 1999-01-08 + ISO 8601; January 8 in any mode + (recommended format) + + + January 8, 1999 + unambiguous in any datestyle input mode + + + 1/8/1999 + January 8 in MDY mode; + August 1 in DMY mode + + + 1/18/1999 + January 18 in MDY mode; + rejected in other modes + + + 01/02/03 + January 2, 2003 in MDY mode; + February 1, 2003 in DMY mode; + February 3, 2001 in YMD mode + + + + 1999-Jan-08 + January 8 in any mode + + + Jan-08-1999 + January 8 in any mode + + + 08-Jan-1999 + January 8 in any mode + + + 99-Jan-08 + January 8 in YMD mode, else error + + + 08-Jan-99 + January 8, except error in YMD mode + + + Jan-08-99 + January 8, except error in YMD mode + + + 19990108 + ISO 8601; January 8, 1999 in any mode + + + 990108 + ISO 8601; January 8, 1999 in any mode + + + 1999.008 + year and day of year + + + J2451187 + Julian date + + + January 8, 99 BC + year 99 BC + + + +
+
+ + + Times + + + time + + + time without time zone + + + time with time zone + + + + The time-of-day types are time [ + (p) ] without time zone and + time [ (p) ] with time + zone. time alone is equivalent to + time without time zone. + + + + Valid input for these types consists of a time of day followed + by an optional time zone. (See + and .) If a time zone is + specified in the input for time without time zone, + it is silently ignored. You can also specify a date but it will + be ignored, except when you use a time zone name that involves a + daylight-savings rule, such as + America/New_York. In this case specifying the date + is required in order to determine whether standard or daylight-savings + time applies. The appropriate time zone offset is recorded in the + time with time zone value. + + + + Time Input + + + + + + Example + Description + + + + + 04:05:06.789 + ISO 8601 + + + 04:05:06 + ISO 8601 + + + 04:05 + ISO 8601 + + + 040506 + ISO 8601 + + + 04:05 AM + same as 04:05; AM does not affect value + + + 04:05 PM + same as 16:05; input hour must be <= 12 + + + 04:05:06.789-8 + ISO 8601 + + + 04:05:06-08:00 + ISO 8601 + + + 04:05-08:00 + ISO 8601 + + + 040506-08 + ISO 8601 + + + 04:05:06 PST + time zone specified by abbreviation + + + 2003-04-12 04:05:06 America/New_York + time zone specified by full name + + + +
+ + + Time Zone Input + + + + Example + Description + + + + + PST + Abbreviation (for Pacific Standard Time) + + + America/New_York + Full time zone name + + + PST8PDT + POSIX-style time zone specification + + + -8:00 + ISO-8601 offset for PST + + + -800 + ISO-8601 offset for PST + + + -8 + ISO-8601 offset for PST + + + zulu + Military abbreviation for UTC + + + z + Short form of zulu + + + +
+ + + Refer to for more information on how + to specify time zones. + +
+ + + Time Stamps + + + timestamp + + + + timestamp with time zone + + + + timestamp without time zone + + + + Valid input for the time stamp types consists of the concatenation + of a date and a time, followed by an optional time zone, + followed by an optional AD or BC. + (Alternatively, AD/BC can appear + before the time zone, but this is not the preferred ordering.) + Thus: + + +1999-01-08 04:05:06 + + and: + +1999-01-08 04:05:06 -8:00 + + + are valid values, which follow the ISO 8601 + standard. In addition, the common format: + +January 8 04:05:06 1999 PST + + is supported. + + + + The SQL standard differentiates + timestamp without time zone + and timestamp with time zone literals by the presence of a + + or - symbol and time zone offset after + the time. Hence, according to the standard, + + +TIMESTAMP '2004-10-19 10:23:54' + + + is a timestamp without time zone, while + + +TIMESTAMP '2004-10-19 10:23:54+02' + + + is a timestamp with time zone. + PostgreSQL never examines the content of a + literal string before determining its type, and therefore will treat + both of the above as timestamp without time zone. To + ensure that a literal is treated as timestamp with time + zone, give it the correct explicit type: + + +TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02' + + + In a literal that has been determined to be timestamp without time + zone, PostgreSQL will silently ignore + any time zone indication. + That is, the resulting value is derived from the date/time + fields in the input value, and is not adjusted for time zone. + + + + For timestamp with time zone, the internally stored + value is always in UTC (Universal + Coordinated Time, traditionally known as Greenwich Mean Time, + GMT). An input value that has an explicit + time zone specified is converted to UTC using the appropriate offset + for that time zone. If no time zone is stated in the input string, + then it is assumed to be in the time zone indicated by the system's + parameter, and is converted to UTC using the + offset for the timezone zone. + + + + When a timestamp with time + zone value is output, it is always converted from UTC to the + current timezone zone, and displayed as local time in that + zone. To see the time in another time zone, either change + timezone or use the AT TIME ZONE construct + (see ). + + + + Conversions between timestamp without time zone and + timestamp with time zone normally assume that the + timestamp without time zone value should be taken or given + as timezone local time. A different time zone can + be specified for the conversion using AT TIME ZONE. + + + + + Special Values + + + time + constants + + + + date + constants + + + + PostgreSQL supports several + special date/time input values for convenience, as shown in . The values + infinity and -infinity + are specially represented inside the system and will be displayed + unchanged; but the others are simply notational shorthands + that will be converted to ordinary date/time values when read. + (In particular, now and related strings are converted + to a specific time value as soon as they are read.) + All of these values need to be enclosed in single quotes when used + as constants in SQL commands. + + + + Special Date/Time Inputs + + + + Input String + Valid Types + Description + + + + + epoch + date, timestamp + 1970-01-01 00:00:00+00 (Unix system time zero) + + + infinity + date, timestamp + later than all other time stamps + + + -infinity + date, timestamp + earlier than all other time stamps + + + now + date, time, timestamp + current transaction's start time + + + today + date, timestamp + midnight (00:00) today + + + tomorrow + date, timestamp + midnight (00:00) tomorrow + + + yesterday + date, timestamp + midnight (00:00) yesterday + + + allballs + time + 00:00:00.00 UTC + + + +
+ + + The following SQL-compatible functions can also + be used to obtain the current time value for the corresponding data + type: + CURRENT_DATE, CURRENT_TIME, + CURRENT_TIMESTAMP, LOCALTIME, + LOCALTIMESTAMP. (See .) Note that these are + SQL functions and are not recognized in data input strings. + + + + + While the input strings now, + today, tomorrow, + and yesterday are fine to use in interactive SQL + commands, they can have surprising behavior when the command is + saved to be executed later, for example in prepared statements, + views, and function definitions. The string can be converted to a + specific time value that continues to be used long after it becomes + stale. Use one of the SQL functions instead in such contexts. + For example, CURRENT_DATE + 1 is safer than + 'tomorrow'::date. + + + +
+
+ + + Date/Time Output + + + date + output format + formatting + + + + time + output format + formatting + + + + The output format of the date/time types can be set to one of the four + styles ISO 8601, + SQL (Ingres), traditional POSTGRES + (Unix date format), or + German. The default + is the ISO format. (The + SQL standard requires the use of the ISO 8601 + format. The name of the SQL output format is a + historical accident.) shows examples of each + output style. The output of the date and + time types is generally only the date or time part + in accordance with the given examples. However, the + POSTGRES style outputs date-only values in + ISO format. + + + + Date/Time Output Styles + + + + + + + Style Specification + Description + Example + + + + + ISO + ISO 8601, SQL standard + 1997-12-17 07:37:16-08 + + + SQL + traditional style + 12/17/1997 07:37:16.00 PST + + + Postgres + original style + Wed Dec 17 07:37:16 1997 PST + + + German + regional style + 17.12.1997 07:37:16.00 PST + + + +
+ + + + ISO 8601 specifies the use of uppercase letter T to separate + the date and time. PostgreSQL accepts that format on + input, but on output it uses a space rather than T, as shown + above. This is for readability and for consistency with + RFC 3339 as + well as some other database systems. + + + + + In the SQL and POSTGRES styles, day appears before + month if DMY field ordering has been specified, otherwise month appears + before day. + (See + for how this setting also affects interpretation of input values.) + shows examples. + + + + Date Order Conventions + + + + + + + datestyle Setting + Input Ordering + Example Output + + + + + SQL, DMY + day/month/year + 17/12/1997 15:37:16.00 CET + + + SQL, MDY + month/day/year + 12/17/1997 07:37:16.00 PST + + + Postgres, DMY + day/month/year + Wed 17 Dec 07:37:16 1997 PST + + + +
+ + + The date/time style can be selected by the user using the + SET datestyle command, the parameter in the + postgresql.conf configuration file, or the + PGDATESTYLE environment variable on the server or + client. + + + + The formatting function to_char + (see ) is also available as + a more flexible way to format date/time output. + +
+ + + Time Zones + + + time zone + + + + Time zones, and time-zone conventions, are influenced by + political decisions, not just earth geometry. Time zones around the + world became somewhat standardized during the 1900s, + but continue to be prone to arbitrary changes, particularly with + respect to daylight-savings rules. + PostgreSQL uses the widely-used + IANA (Olson) time zone database for information about + historical time zone rules. For times in the future, the assumption + is that the latest known rules for a given time zone will + continue to be observed indefinitely far into the future. + + + + PostgreSQL endeavors to be compatible with + the SQL standard definitions for typical usage. + However, the SQL standard has an odd mix of date and + time types and capabilities. Two obvious problems are: + + + + + Although the date type + cannot have an associated time zone, the + time type can. + Time zones in the real world have little meaning unless + associated with a date as well as a time, + since the offset can vary through the year with daylight-saving + time boundaries. + + + + + + The default time zone is specified as a constant numeric offset + from UTC. It is therefore impossible to adapt to + daylight-saving time when doing date/time arithmetic across + DST boundaries. + + + + + + + + To address these difficulties, we recommend using date/time types + that contain both date and time when using time zones. We + do not recommend using the type time with + time zone (though it is supported by + PostgreSQL for legacy applications and + for compliance with the SQL standard). + PostgreSQL assumes + your local time zone for any type containing only date or time. + + + + All timezone-aware dates and times are stored internally in + UTC. They are converted to local time + in the zone specified by the configuration + parameter before being displayed to the client. + + + + PostgreSQL allows you to specify time zones in + three different forms: + + + + A full time zone name, for example America/New_York. + The recognized time zone names are listed in the + pg_timezone_names view (see ). + PostgreSQL uses the widely-used IANA + time zone data for this purpose, so the same time zone + names are also recognized by other software. + + + + + A time zone abbreviation, for example PST. Such a + specification merely defines a particular offset from UTC, in + contrast to full time zone names which can imply a set of daylight + savings transition rules as well. The recognized abbreviations + are listed in the pg_timezone_abbrevs view (see ). You cannot set the + configuration parameters or + to a time + zone abbreviation, but you can use abbreviations in + date/time input values and with the AT TIME ZONE + operator. + + + + + In addition to the timezone names and abbreviations, + PostgreSQL will accept POSIX-style time zone + specifications, as described in + . This option is not + normally preferable to using a named time zone, but it may be + necessary if no suitable IANA time zone entry is available. + + + + + In short, this is the difference between abbreviations + and full names: abbreviations represent a specific offset from UTC, + whereas many of the full names imply a local daylight-savings time + rule, and so have two possible UTC offsets. As an example, + 2014-06-04 12:00 America/New_York represents noon local + time in New York, which for this particular date was Eastern Daylight + Time (UTC-4). So 2014-06-04 12:00 EDT specifies that + same time instant. But 2014-06-04 12:00 EST specifies + noon Eastern Standard Time (UTC-5), regardless of whether daylight + savings was nominally in effect on that date. + + + + To complicate matters, some jurisdictions have used the same timezone + abbreviation to mean different UTC offsets at different times; for + example, in Moscow MSK has meant UTC+3 in some years and + UTC+4 in others. PostgreSQL interprets such + abbreviations according to whatever they meant (or had most recently + meant) on the specified date; but, as with the EST example + above, this is not necessarily the same as local civil time on that date. + + + + In all cases, timezone names and abbreviations are recognized + case-insensitively. (This is a change from PostgreSQL + versions prior to 8.2, which were case-sensitive in some contexts but + not others.) + + + + Neither timezone names nor abbreviations are hard-wired into the server; + they are obtained from configuration files stored under + .../share/timezone/ and .../share/timezonesets/ + of the installation directory + (see ). + + + + The configuration parameter can + be set in the file postgresql.conf, or in any of the + other standard ways described in . + There are also some special ways to set it: + + + + + The SQL command SET TIME ZONE + sets the time zone for the session. This is an alternative spelling + of SET TIMEZONE TO with a more SQL-spec-compatible syntax. + + + + + + The PGTZ environment variable is used by + libpq clients + to send a SET TIME ZONE + command to the server upon connection. + + + + + + + + Interval Input + + + interval + + + + interval values can be written using the following + verbose syntax: + + +@ quantity unit quantity unit... direction + + + where quantity is a number (possibly signed); + unit is microsecond, + millisecond, second, + minute, hour, day, + week, month, year, + decade, century, millennium, + or abbreviations or plurals of these units; + direction can be ago or + empty. The at sign (@) is optional noise. The amounts + of the different units are implicitly added with appropriate + sign accounting. ago negates all the fields. + This syntax is also used for interval output, if + is set to + postgres_verbose. + + + + Quantities of days, hours, minutes, and seconds can be specified without + explicit unit markings. For example, '1 12:59:10' is read + the same as '1 day 12 hours 59 min 10 sec'. Also, + a combination of years and months can be specified with a dash; + for example '200-10' is read the same as '200 years + 10 months'. (These shorter forms are in fact the only ones allowed + by the SQL standard, and are used for output when + IntervalStyle is set to sql_standard.) + + + + Interval values can also be written as ISO 8601 time intervals, using + either the format with designators of the standard's section + 4.4.3.2 or the alternative format of section 4.4.3.3. The + format with designators looks like this: + +P quantity unit quantity unit ... T quantity unit ... + + The string must start with a P, and may include a + T that introduces the time-of-day units. The + available unit abbreviations are given in . Units may be + omitted, and may be specified in any order, but units smaller than + a day must appear after T. In particular, the meaning of + M depends on whether it is before or after + T. + + + + ISO 8601 Interval Unit Abbreviations + + + + Abbreviation + Meaning + + + + + Y + Years + + + M + Months (in the date part) + + + W + Weeks + + + D + Days + + + H + Hours + + + M + Minutes (in the time part) + + + S + Seconds + + + +
+ + + In the alternative format: + +P years-months-days T hours:minutes:seconds + + the string must begin with P, and a + T separates the date and time parts of the interval. + The values are given as numbers similar to ISO 8601 dates. + + + + When writing an interval constant with a fields + specification, or when assigning a string to an interval column that was + defined with a fields specification, the interpretation of + unmarked quantities depends on the fields. For + example INTERVAL '1' YEAR is read as 1 year, whereas + INTERVAL '1' means 1 second. Also, field values + to the right of the least significant field allowed by the + fields specification are silently discarded. For + example, writing INTERVAL '1 day 2:03:04' HOUR TO MINUTE + results in dropping the seconds field, but not the day field. + + + + According to the SQL standard all fields of an interval + value must have the same sign, so a leading negative sign applies to all + fields; for example the negative sign in the interval literal + '-1 2:03:04' applies to both the days and hour/minute/second + parts. PostgreSQL allows the fields to have different + signs, and traditionally treats each field in the textual representation + as independently signed, so that the hour/minute/second part is + considered positive in this example. If IntervalStyle is + set to sql_standard then a leading sign is considered + to apply to all fields (but only if no additional signs appear). + Otherwise the traditional PostgreSQL interpretation is + used. To avoid ambiguity, it's recommended to attach an explicit sign + to each field if any field is negative. + + + + In the verbose input format, and in some fields of the more compact + input formats, field values can have fractional parts; for example + '1.5 week' or '01:02:03.45'. Such input is + converted to the appropriate number of months, days, and seconds + for storage. When this would result in a fractional number of + months or days, the fraction is added to the lower-order fields + using the conversion factors 1 month = 30 days and 1 day = 24 hours. + For example, '1.5 month' becomes 1 month and 15 days. + Only seconds will ever be shown as fractional on output. + + + + shows some examples + of valid interval input. + + + + Interval Input + + + + Example + Description + + + + + 1-2 + SQL standard format: 1 year 2 months + + + 3 4:05:06 + SQL standard format: 3 days 4 hours 5 minutes 6 seconds + + + 1 year 2 months 3 days 4 hours 5 minutes 6 seconds + Traditional Postgres format: 1 year 2 months 3 days 4 hours 5 minutes 6 seconds + + + P1Y2M3DT4H5M6S + ISO 8601 format with designators: same meaning as above + + + P0001-02-03T04:05:06 + ISO 8601 alternative format: same meaning as above + + + +
+ + + Internally interval values are stored as months, days, + and seconds. This is done because the number of days in a month + varies, and a day can have 23 or 25 hours if a daylight savings + time adjustment is involved. The months and days fields are integers + while the seconds field can store fractions. Because intervals are + usually created from constant strings or timestamp subtraction, + this storage method works well in most cases, but can cause unexpected + results: + + +SELECT EXTRACT(hours from '80 minutes'::interval); + date_part +----------- + 1 + +SELECT EXTRACT(days from '80 hours'::interval); + date_part +----------- + 0 + + + Functions justify_days and + justify_hours are available for adjusting days + and hours that overflow their normal ranges. + + +
+ + + Interval Output + + + interval + output format + formatting + + + + The output format of the interval type can be set to one of the + four styles sql_standard, postgres, + postgres_verbose, or iso_8601, + using the command SET intervalstyle. + The default is the postgres format. + shows examples of each + output style. + + + + The sql_standard style produces output that conforms to + the SQL standard's specification for interval literal strings, if + the interval value meets the standard's restrictions (either year-month + only or day-time only, with no mixing of positive + and negative components). Otherwise the output looks like a standard + year-month literal string followed by a day-time literal string, + with explicit signs added to disambiguate mixed-sign intervals. + + + + The output of the postgres style matches the output of + PostgreSQL releases prior to 8.4 when the + parameter was set to ISO. + + + + The output of the postgres_verbose style matches the output of + PostgreSQL releases prior to 8.4 when the + DateStyle parameter was set to non-ISO output. + + + + The output of the iso_8601 style matches the format + with designators described in section 4.4.3.2 of the + ISO 8601 standard. + + + + Interval Output Style Examples + + + + Style Specification + Year-Month Interval + Day-Time Interval + Mixed Interval + + + + + sql_standard + 1-2 + 3 4:05:06 + -1-2 +3 -4:05:06 + + + postgres + 1 year 2 mons + 3 days 04:05:06 + -1 year -2 mons +3 days -04:05:06 + + + postgres_verbose + @ 1 year 2 mons + @ 3 days 4 hours 5 mins 6 secs + @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago + + + iso_8601 + P1Y2M + P3DT4H5M6S + P-1Y-2M3D&zwsp;T-4H-5M-6S + + + +
+ +
+ +
+ + + Boolean Type + + + Boolean + data type + + + + true + + + + false + + + + PostgreSQL provides the + standard SQL type boolean; + see . + The boolean type can have several states: + true, false, and a third state, + unknown, which is represented by the + SQL null value. + + + + Boolean Data Type + + + + Name + Storage Size + Description + + + + + boolean + 1 byte + state of true or false + + + +
+ + + Boolean constants can be represented in SQL queries by the SQL + key words TRUE, FALSE, + and NULL. + + + + The datatype input function for type boolean accepts these + string representations for the true state: + + true + yes + on + 1 + + and these representations for the false state: + + false + no + off + 0 + + Unique prefixes of these strings are also accepted, for + example t or n. + Leading or trailing whitespace is ignored, and case does not matter. + + + + The datatype output function for type boolean always emits + either t or f, as shown in + . + + + + Using the <type>boolean</type> Type + + +CREATE TABLE test1 (a boolean, b text); +INSERT INTO test1 VALUES (TRUE, 'sic est'); +INSERT INTO test1 VALUES (FALSE, 'non est'); +SELECT * FROM test1; + a | b +---+--------- + t | sic est + f | non est + +SELECT * FROM test1 WHERE a; + a | b +---+--------- + t | sic est + + + + + The key words TRUE and FALSE are + the preferred (SQL-compliant) method for writing + Boolean constants in SQL queries. But you can also use the string + representations by following the generic string-literal constant syntax + described in , for + example 'yes'::boolean. + + + + Note that the parser automatically understands + that TRUE and FALSE are of + type boolean, but this is not so + for NULL because that can have any type. + So in some contexts you might have to cast NULL + to boolean explicitly, for + example NULL::boolean. Conversely, the cast can be + omitted from a string-literal Boolean value in contexts where the parser + can deduce that the literal must be of type boolean. + +
+ + + Enumerated Types + + + data type + enumerated (enum) + + + + enumerated types + + + + Enumerated (enum) types are data types that + comprise a static, ordered set of values. + They are equivalent to the enum + types supported in a number of programming languages. An example of an enum + type might be the days of the week, or a set of status values for + a piece of data. + + + + Declaration of Enumerated Types + + + Enum types are created using the command, + for example: + + +CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); + + + Once created, the enum type can be used in table and function + definitions much like any other type: + +CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); +CREATE TABLE person ( + name text, + current_mood mood +); +INSERT INTO person VALUES ('Moe', 'happy'); +SELECT * FROM person WHERE current_mood = 'happy'; + name | current_mood +------+-------------- + Moe | happy +(1 row) + + + + + + Ordering + + + The ordering of the values in an enum type is the + order in which the values were listed when the type was created. + All standard comparison operators and related + aggregate functions are supported for enums. For example: + + +INSERT INTO person VALUES ('Larry', 'sad'); +INSERT INTO person VALUES ('Curly', 'ok'); +SELECT * FROM person WHERE current_mood > 'sad'; + name | current_mood +-------+-------------- + Moe | happy + Curly | ok +(2 rows) + +SELECT * FROM person WHERE current_mood > 'sad' ORDER BY current_mood; + name | current_mood +-------+-------------- + Curly | ok + Moe | happy +(2 rows) + +SELECT name +FROM person +WHERE current_mood = (SELECT MIN(current_mood) FROM person); + name +------- + Larry +(1 row) + + + + + + Type Safety + + + Each enumerated data type is separate and cannot + be compared with other enumerated types. See this example: + + +CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic'); +CREATE TABLE holidays ( + num_weeks integer, + happiness happiness +); +INSERT INTO holidays(num_weeks,happiness) VALUES (4, 'happy'); +INSERT INTO holidays(num_weeks,happiness) VALUES (6, 'very happy'); +INSERT INTO holidays(num_weeks,happiness) VALUES (8, 'ecstatic'); +INSERT INTO holidays(num_weeks,happiness) VALUES (2, 'sad'); +ERROR: invalid input value for enum happiness: "sad" +SELECT person.name, holidays.num_weeks FROM person, holidays + WHERE person.current_mood = holidays.happiness; +ERROR: operator does not exist: mood = happiness + + + + + If you really need to do something like that, you can either + write a custom operator or add explicit casts to your query: + + +SELECT person.name, holidays.num_weeks FROM person, holidays + WHERE person.current_mood::text = holidays.happiness::text; + name | num_weeks +------+----------- + Moe | 4 +(1 row) + + + + + + + Implementation Details + + + Enum labels are case sensitive, so + 'happy' is not the same as 'HAPPY'. + White space in the labels is significant too. + + + + Although enum types are primarily intended for static sets of values, + there is support for adding new values to an existing enum type, and for + renaming values (see ). Existing values + cannot be removed from an enum type, nor can the sort ordering of such + values be changed, short of dropping and re-creating the enum type. + + + + An enum value occupies four bytes on disk. The length of an enum + value's textual label is limited by the NAMEDATALEN + setting compiled into PostgreSQL; in standard + builds this means at most 63 bytes. + + + + The translations from internal enum values to textual labels are + kept in the system catalog + pg_enum. + Querying this catalog directly can be useful. + + + + + + + Geometric Types + + + Geometric data types represent two-dimensional spatial + objects. shows the geometric + types available in PostgreSQL. + + + + Geometric Types + + + + + + + + Name + Storage Size + Description + Representation + + + + + point + 16 bytes + Point on a plane + (x,y) + + + line + 32 bytes + Infinite line + {A,B,C} + + + lseg + 32 bytes + Finite line segment + ((x1,y1),(x2,y2)) + + + box + 32 bytes + Rectangular box + ((x1,y1),(x2,y2)) + + + path + 16+16n bytes + Closed path (similar to polygon) + ((x1,y1),...) + + + path + 16+16n bytes + Open path + [(x1,y1),...] + + + polygon + 40+16n bytes + Polygon (similar to closed path) + ((x1,y1),...) + + + circle + 24 bytes + Circle + <(x,y),r> (center point and radius) + + + +
+ + + A rich set of functions and operators is available to perform various geometric + operations such as scaling, translation, rotation, and determining + intersections. They are explained in . + + + + Points + + + point + + + + Points are the fundamental two-dimensional building block for geometric + types. Values of type point are specified using either of + the following syntaxes: + + +( x , y ) + x , y + + + where x and y are the respective + coordinates, as floating-point numbers. + + + + Points are output using the first syntax. + + + + + Lines + + + line + + + + Lines are represented by the linear + equation Ax + By + C = 0, + where A and B are not both zero. Values + of type line are input and output in the following form: + +{ A, B, C } + + + Alternatively, any of the following forms can be used for input: + + +[ ( x1 , y1 ) , ( x2 , y2 ) ] +( ( x1 , y1 ) , ( x2 , y2 ) ) + ( x1 , y1 ) , ( x2 , y2 ) + x1 , y1 , x2 , y2 + + + where + (x1,y1) + and + (x2,y2) + are two different points on the line. + + + + + Line Segments + + + lseg + + + + line segment + + + + Line segments are represented by pairs of points that are the endpoints + of the segment. Values of type lseg are specified using any + of the following syntaxes: + + +[ ( x1 , y1 ) , ( x2 , y2 ) ] +( ( x1 , y1 ) , ( x2 , y2 ) ) + ( x1 , y1 ) , ( x2 , y2 ) + x1 , y1 , x2 , y2 + + + where + (x1,y1) + and + (x2,y2) + are the end points of the line segment. + + + + Line segments are output using the first syntax. + + + + + Boxes + + + box (data type) + + + + rectangle + + + + Boxes are represented by pairs of points that are opposite + corners of the box. + Values of type box are specified using any of the following + syntaxes: + + +( ( x1 , y1 ) , ( x2 , y2 ) ) + ( x1 , y1 ) , ( x2 , y2 ) + x1 , y1 , x2 , y2 + + + where + (x1,y1) + and + (x2,y2) + are any two opposite corners of the box. + + + + Boxes are output using the second syntax. + + + + Any two opposite corners can be supplied on input, but the values + will be reordered as needed to store the + upper right and lower left corners, in that order. + + + + + Paths + + + path (data type) + + + + Paths are represented by lists of connected points. Paths can be + open, where + the first and last points in the list are considered not connected, or + closed, + where the first and last points are considered connected. + + + + Values of type path are specified using any of the following + syntaxes: + + +[ ( x1 , y1 ) , ... , ( xn , yn ) ] +( ( x1 , y1 ) , ... , ( xn , yn ) ) + ( x1 , y1 ) , ... , ( xn , yn ) + ( x1 , y1 , ... , xn , yn ) + x1 , y1 , ... , xn , yn + + + where the points are the end points of the line segments + comprising the path. Square brackets ([]) indicate + an open path, while parentheses (()) indicate a + closed path. When the outermost parentheses are omitted, as + in the third through fifth syntaxes, a closed path is assumed. + + + + Paths are output using the first or second syntax, as appropriate. + + + + + Polygons + + + polygon + + + + Polygons are represented by lists of points (the vertexes of the + polygon). Polygons are very similar to closed paths, but are + stored differently and have their own set of support routines. + + + + Values of type polygon are specified using any of the + following syntaxes: + + +( ( x1 , y1 ) , ... , ( xn , yn ) ) + ( x1 , y1 ) , ... , ( xn , yn ) + ( x1 , y1 , ... , xn , yn ) + x1 , y1 , ... , xn , yn + + + where the points are the end points of the line segments + comprising the boundary of the polygon. + + + + Polygons are output using the first syntax. + + + + + Circles + + + circle + + + + Circles are represented by a center point and radius. + Values of type circle are specified using any of the + following syntaxes: + + +< ( x , y ) , r > +( ( x , y ) , r ) + ( x , y ) , r + x , y , r + + + where + (x,y) + is the center point and r is the radius of the + circle. + + + + Circles are output using the first syntax. + + + +
+ + + Network Address Types + + + network + data types + + + + PostgreSQL offers data types to store IPv4, IPv6, and MAC + addresses, as shown in . It + is better to use these types instead of plain text types to store + network addresses, because + these types offer input error checking and specialized + operators and functions (see ). + + + + Network Address Types + + + + + + + Name + Storage Size + Description + + + + + + cidr + 7 or 19 bytes + IPv4 and IPv6 networks + + + + inet + 7 or 19 bytes + IPv4 and IPv6 hosts and networks + + + + macaddr + 6 bytes + MAC addresses + + + + macaddr8 + 8 bytes + MAC addresses (EUI-64 format) + + + + +
+ + + When sorting inet or cidr data types, + IPv4 addresses will always sort before IPv6 addresses, including + IPv4 addresses encapsulated or mapped to IPv6 addresses, such as + ::10.2.3.4 or ::ffff:10.4.3.2. + + + + + <type>inet</type> + + + inet (data type) + + + + The inet type holds an IPv4 or IPv6 host address, and + optionally its subnet, all in one field. + The subnet is represented by the number of network address bits + present in the host address (the + netmask). If the netmask is 32 and the address is IPv4, + then the value does not indicate a subnet, only a single host. + In IPv6, the address length is 128 bits, so 128 bits specify a + unique host address. Note that if you + want to accept only networks, you should use the + cidr type rather than inet. + + + + The input format for this type is + address/y + where + address + is an IPv4 or IPv6 address and + y + is the number of bits in the netmask. If the + /y + portion is omitted, the + netmask is taken to be 32 for IPv4 or 128 for IPv6, + so the value represents + just a single host. On display, the + /y + portion is suppressed if the netmask specifies a single host. + + + + + <type>cidr</type> + + + cidr + + + + The cidr type holds an IPv4 or IPv6 network specification. + Input and output formats follow Classless Internet Domain Routing + conventions. + The format for specifying networks is address/y where address is the network's lowest + address represented as an + IPv4 or IPv6 address, and y is the number of bits in the netmask. If + y is omitted, it is calculated + using assumptions from the older classful network numbering system, except + it will be at least large enough to include all of the octets + written in the input. It is an error to specify a network address + that has bits set to the right of the specified netmask. + + + + shows some examples. + + + + <type>cidr</type> Type Input Examples + + + + cidr Input + cidr Output + abbrev(cidr) + + + + + 192.168.100.128/25 + 192.168.100.128/25 + 192.168.100.128/25 + + + 192.168/24 + 192.168.0.0/24 + 192.168.0/24 + + + 192.168/25 + 192.168.0.0/25 + 192.168.0.0/25 + + + 192.168.1 + 192.168.1.0/24 + 192.168.1/24 + + + 192.168 + 192.168.0.0/24 + 192.168.0/24 + + + 128.1 + 128.1.0.0/16 + 128.1/16 + + + 128 + 128.0.0.0/16 + 128.0/16 + + + 128.1.2 + 128.1.2.0/24 + 128.1.2/24 + + + 10.1.2 + 10.1.2.0/24 + 10.1.2/24 + + + 10.1 + 10.1.0.0/16 + 10.1/16 + + + 10 + 10.0.0.0/8 + 10/8 + + + 10.1.2.3/32 + 10.1.2.3/32 + 10.1.2.3/32 + + + 2001:4f8:3:ba::/64 + 2001:4f8:3:ba::/64 + 2001:4f8:3:ba/64 + + + 2001:4f8:3:ba:&zwsp;2e0:81ff:fe22:d1f1/128 + 2001:4f8:3:ba:&zwsp;2e0:81ff:fe22:d1f1/128 + 2001:4f8:3:ba:&zwsp;2e0:81ff:fe22:d1f1/128 + + + ::ffff:1.2.3.0/120 + ::ffff:1.2.3.0/120 + ::ffff:1.2.3/120 + + + ::ffff:1.2.3.0/128 + ::ffff:1.2.3.0/128 + ::ffff:1.2.3.0/128 + + + +
+
+ + + <type>inet</type> vs. <type>cidr</type> + + + The essential difference between inet and cidr + data types is that inet accepts values with nonzero bits to + the right of the netmask, whereas cidr does not. For + example, 192.168.0.1/24 is valid for inet + but not for cidr. + + + + + If you do not like the output format for inet or + cidr values, try the functions host, + text, and abbrev. + + + + + + <type>macaddr</type> + + + macaddr (data type) + + + + MAC address + macaddr + + + + The macaddr type stores MAC addresses, known for example + from Ethernet card hardware addresses (although MAC addresses are + used for other purposes as well). Input is accepted in the + following formats: + + + '08:00:2b:01:02:03' + '08-00-2b-01-02-03' + '08002b:010203' + '08002b-010203' + '0800.2b01.0203' + '0800-2b01-0203' + '08002b010203' + + + These examples all specify the same address. Upper and + lower case is accepted for the digits + a through f. Output is always in the + first of the forms shown. + + + + IEEE Std 802-2001 specifies the second shown form (with hyphens) + as the canonical form for MAC addresses, and specifies the first + form (with colons) as the bit-reversed notation, so that + 08-00-2b-01-02-03 = 01:00:4D:08:04:0C. This convention is widely + ignored nowadays, and it is relevant only for obsolete network + protocols (such as Token Ring). PostgreSQL makes no provisions + for bit reversal, and all accepted formats use the canonical LSB + order. + + + + The remaining five input formats are not part of any standard. + + + + + <type>macaddr8</type> + + + macaddr8 (data type) + + + + MAC address (EUI-64 format) + macaddr + + + + The macaddr8 type stores MAC addresses in EUI-64 + format, known for example from Ethernet card hardware addresses + (although MAC addresses are used for other purposes as well). + This type can accept both 6 and 8 byte length MAC addresses + and stores them in 8 byte length format. MAC addresses given + in 6 byte format will be stored in 8 byte length format with the + 4th and 5th bytes set to FF and FE, respectively. + + Note that IPv6 uses a modified EUI-64 format where the 7th bit + should be set to one after the conversion from EUI-48. The + function macaddr8_set7bit is provided to make this + change. + + Generally speaking, any input which is comprised of pairs of hex + digits (on byte boundaries), optionally separated consistently by + one of ':', '-' or '.', is + accepted. The number of hex digits must be either 16 (8 bytes) or + 12 (6 bytes). Leading and trailing whitespace is ignored. + + The following are examples of input formats that are accepted: + + + '08:00:2b:01:02:03:04:05' + '08-00-2b-01-02-03-04-05' + '08002b:0102030405' + '08002b-0102030405' + '0800.2b01.0203.0405' + '0800-2b01-0203-0405' + '08002b01:02030405' + '08002b0102030405' + + + These examples all specify the same address. Upper and + lower case is accepted for the digits + a through f. Output is always in the + first of the forms shown. + + + + The last six input formats shown above are not part of any standard. + + + + To convert a traditional 48 bit MAC address in EUI-48 format to + modified EUI-64 format to be included as the host portion of an + IPv6 address, use macaddr8_set7bit as shown: + + +SELECT macaddr8_set7bit('08:00:2b:01:02:03'); + + macaddr8_set7bit +------------------------- + 0a:00:2b:ff:fe:01:02:03 +(1 row) + + + + + + + +
+ + + Bit String Types + + + bit string + data type + + + + Bit strings are strings of 1's and 0's. They can be used to store + or visualize bit masks. There are two SQL bit types: + bit(n) and bit + varying(n), where + n is a positive integer. + + + + bit type data must match the length + n exactly; it is an error to attempt to + store shorter or longer bit strings. bit varying data is + of variable length up to the maximum length + n; longer strings will be rejected. + Writing bit without a length is equivalent to + bit(1), while bit varying without a length + specification means unlimited length. + + + + + If one explicitly casts a bit-string value to + bit(n), it will be truncated or + zero-padded on the right to be exactly n bits, + without raising an error. Similarly, + if one explicitly casts a bit-string value to + bit varying(n), it will be truncated + on the right if it is more than n bits. + + + + + Refer to for information about the syntax + of bit string constants. Bit-logical operators and string + manipulation functions are available; see . + + + + Using the Bit String Types + + +CREATE TABLE test (a BIT(3), b BIT VARYING(5)); +INSERT INTO test VALUES (B'101', B'00'); +INSERT INTO test VALUES (B'10', B'101'); + +ERROR: bit string length 2 does not match type bit(3) + +INSERT INTO test VALUES (B'10'::bit(3), B'101'); +SELECT * FROM test; + + a | b +-----+----- + 101 | 00 + 100 | 101 + + + + + + A bit string value requires 1 byte for each group of 8 bits, plus + 5 or 8 bytes overhead depending on the length of the string + (but long values may be compressed or moved out-of-line, as explained + in for character strings). + + + + + Text Search Types + + + full text search + data types + + + + text search + data types + + + + PostgreSQL provides two data types that + are designed to support full text search, which is the activity of + searching through a collection of natural-language documents + to locate those that best match a query. + The tsvector type represents a document in a form optimized + for text search; the tsquery type similarly represents + a text query. + provides a detailed explanation of this + facility, and summarizes the + related functions and operators. + + + + <type>tsvector</type> + + + tsvector (data type) + + + + A tsvector value is a sorted list of distinct + lexemes, which are words that have been + normalized to merge different variants of the same word + (see for details). Sorting and + duplicate-elimination are done automatically during input, as shown in + this example: + + +SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector; + tsvector +---------------------------------------------------- + 'a' 'and' 'ate' 'cat' 'fat' 'mat' 'on' 'rat' 'sat' + + + To represent + lexemes containing whitespace or punctuation, surround them with quotes: + + +SELECT $$the lexeme ' ' contains spaces$$::tsvector; + tsvector +------------------------------------------- + ' ' 'contains' 'lexeme' 'spaces' 'the' + + + (We use dollar-quoted string literals in this example and the next one + to avoid the confusion of having to double quote marks within the + literals.) Embedded quotes and backslashes must be doubled: + + +SELECT $$the lexeme 'Joe''s' contains a quote$$::tsvector; + tsvector +------------------------------------------------ + 'Joe''s' 'a' 'contains' 'lexeme' 'quote' 'the' + + + Optionally, integer positions + can be attached to lexemes: + + +SELECT 'a:1 fat:2 cat:3 sat:4 on:5 a:6 mat:7 and:8 ate:9 a:10 fat:11 rat:12'::tsvector; + tsvector +-------------------------------------------------------------------&zwsp;------------ + 'a':1,6,10 'and':8 'ate':9 'cat':3 'fat':2,11 'mat':7 'on':5 'rat':12 'sat':4 + + + A position normally indicates the source word's location in the + document. Positional information can be used for + proximity ranking. Position values can + range from 1 to 16383; larger numbers are silently set to 16383. + Duplicate positions for the same lexeme are discarded. + + + + Lexemes that have positions can further be labeled with a + weight, which can be A, + B, C, or D. + D is the default and hence is not shown on output: + + +SELECT 'a:1A fat:2B,4C cat:5D'::tsvector; + tsvector +---------------------------- + 'a':1A 'cat':5 'fat':2B,4C + + + Weights are typically used to reflect document structure, for example + by marking title words differently from body words. Text search + ranking functions can assign different priorities to the different + weight markers. + + + + It is important to understand that the + tsvector type itself does not perform any word + normalization; it assumes the words it is given are normalized + appropriately for the application. For example, + + +SELECT 'The Fat Rats'::tsvector; + tsvector +-------------------- + 'Fat' 'Rats' 'The' + + + For most English-text-searching applications the above words would + be considered non-normalized, but tsvector doesn't care. + Raw document text should usually be passed through + to_tsvector to normalize the words appropriately + for searching: + + +SELECT to_tsvector('english', 'The Fat Rats'); + to_tsvector +----------------- + 'fat':2 'rat':3 + + + Again, see for more detail. + + + + + + <type>tsquery</type> + + + tsquery (data type) + + + + A tsquery value stores lexemes that are to be + searched for, and can combine them using the Boolean operators + & (AND), | (OR), and + ! (NOT), as well as the phrase search operator + <-> (FOLLOWED BY). There is also a variant + <N> of the FOLLOWED BY + operator, where N is an integer constant that + specifies the distance between the two lexemes being searched + for. <-> is equivalent to <1>. + + + + Parentheses can be used to enforce grouping of these operators. + In the absence of parentheses, ! (NOT) binds most tightly, + <-> (FOLLOWED BY) next most tightly, then + & (AND), with | (OR) binding + the least tightly. + + + + Here are some examples: + + +SELECT 'fat & rat'::tsquery; + tsquery +--------------- + 'fat' & 'rat' + +SELECT 'fat & (rat | cat)'::tsquery; + tsquery +--------------------------- + 'fat' & ( 'rat' | 'cat' ) + +SELECT 'fat & rat & ! cat'::tsquery; + tsquery +------------------------ + 'fat' & 'rat' & !'cat' + + + + + Optionally, lexemes in a tsquery can be labeled with + one or more weight letters, which restricts them to match only + tsvector lexemes with one of those weights: + + +SELECT 'fat:ab & cat'::tsquery; + tsquery +------------------ + 'fat':AB & 'cat' + + + + + Also, lexemes in a tsquery can be labeled with * + to specify prefix matching: + +SELECT 'super:*'::tsquery; + tsquery +----------- + 'super':* + + This query will match any word in a tsvector that begins + with super. + + + + Quoting rules for lexemes are the same as described previously for + lexemes in tsvector; and, as with tsvector, + any required normalization of words must be done before converting + to the tsquery type. The to_tsquery + function is convenient for performing such normalization: + + +SELECT to_tsquery('Fat:ab & Cats'); + to_tsquery +------------------ + 'fat':AB & 'cat' + + + Note that to_tsquery will process prefixes in the same way + as other words, which means this comparison returns true: + + +SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' ); + ?column? +---------- + t + + because postgres gets stemmed to postgr: + +SELECT to_tsvector( 'postgraduate' ), to_tsquery( 'postgres:*' ); + to_tsvector | to_tsquery +---------------+------------ + 'postgradu':1 | 'postgr':* + + which will match the stemmed form of postgraduate. + + + + + + + + <acronym>UUID</acronym> Type + + + UUID + + + + The data type uuid stores Universally Unique Identifiers + (UUID) as defined by RFC 4122, + ISO/IEC 9834-8:2005, and related standards. + (Some systems refer to this data type as a globally unique identifier, or + GUID,GUID instead.) This + identifier is a 128-bit quantity that is generated by an algorithm chosen + to make it very unlikely that the same identifier will be generated by + anyone else in the known universe using the same algorithm. Therefore, + for distributed systems, these identifiers provide a better uniqueness + guarantee than sequence generators, which + are only unique within a single database. + + + + A UUID is written as a sequence of lower-case hexadecimal digits, + in several groups separated by hyphens, specifically a group of 8 + digits followed by three groups of 4 digits followed by a group of + 12 digits, for a total of 32 digits representing the 128 bits. An + example of a UUID in this standard form is: + +a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 + + PostgreSQL also accepts the following + alternative forms for input: + use of upper-case digits, the standard format surrounded by + braces, omitting some or all hyphens, adding a hyphen after any + group of four digits. Examples are: + +A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11 +{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11} +a0eebc999c0b4ef8bb6d6bb9bd380a11 +a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 +{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11} + + Output is always in the standard form. + + + + See for how to generate a UUID in + PostgreSQL. + + + + + <acronym>XML</acronym> Type + + + XML + + + + The xml data type can be used to store XML data. Its + advantage over storing XML data in a text field is that it + checks the input values for well-formedness, and there are support + functions to perform type-safe operations on it; see . Use of this data type requires the + installation to have been built with configure + --with-libxml. + + + + The xml type can store well-formed + documents, as defined by the XML standard, as well + as content fragments, which are defined by reference + to the more permissive + document node + of the XQuery and XPath data model. + Roughly, this means that content fragments can have + more than one top-level element or character node. The expression + xmlvalue IS DOCUMENT + can be used to evaluate whether a particular xml + value is a full document or only a content fragment. + + + + Limits and compatibility notes for the xml data type + can be found in . + + + + Creating XML Values + + To produce a value of type xml from character data, + use the function + xmlparse:xmlparse + +XMLPARSE ( { DOCUMENT | CONTENT } value) + + Examples: +Manual...') +XMLPARSE (CONTENT 'abcbarfoo') +]]> + While this is the only way to convert character strings into XML + values according to the SQL standard, the PostgreSQL-specific + syntaxes: +bar' +'bar'::xml +]]> + can also be used. + + + + The xml type does not validate input values + against a document type declaration + (DTD),DTD + even when the input value specifies a DTD. + There is also currently no built-in support for validating against + other XML schema languages such as XML Schema. + + + + The inverse operation, producing a character string value from + xml, uses the function + xmlserialize:xmlserialize + +XMLSERIALIZE ( { DOCUMENT | CONTENT } value AS type ) + + type can be + character, character varying, or + text (or an alias for one of those). Again, according + to the SQL standard, this is the only way to convert between type + xml and character types, but PostgreSQL also allows + you to simply cast the value. + + + + When a character string value is cast to or from type + xml without going through XMLPARSE or + XMLSERIALIZE, respectively, the choice of + DOCUMENT versus CONTENT is + determined by the XML option + XML option + session configuration parameter, which can be set using the + standard command: + +SET XML OPTION { DOCUMENT | CONTENT }; + + or the more PostgreSQL-like syntax + +SET xmloption TO { DOCUMENT | CONTENT }; + + The default is CONTENT, so all forms of XML + data are allowed. + + + + + + Encoding Handling + + Care must be taken when dealing with multiple character encodings + on the client, server, and in the XML data passed through them. + When using the text mode to pass queries to the server and query + results to the client (which is the normal mode), PostgreSQL + converts all character data passed between the client and the + server and vice versa to the character encoding of the respective + end; see . This includes string + representations of XML values, such as in the above examples. + This would ordinarily mean that encoding declarations contained in + XML data can become invalid as the character data is converted + to other encodings while traveling between client and server, + because the embedded encoding declaration is not changed. To cope + with this behavior, encoding declarations contained in + character strings presented for input to the xml type + are ignored, and content is assumed + to be in the current server encoding. Consequently, for correct + processing, character strings of XML data must be sent + from the client in the current client encoding. It is the + responsibility of the client to either convert documents to the + current client encoding before sending them to the server, or to + adjust the client encoding appropriately. On output, values of + type xml will not have an encoding declaration, and + clients should assume all data is in the current client + encoding. + + + + When using binary mode to pass query parameters to the server + and query results back to the client, no encoding conversion + is performed, so the situation is different. In this case, an + encoding declaration in the XML data will be observed, and if it + is absent, the data will be assumed to be in UTF-8 (as required by + the XML standard; note that PostgreSQL does not support UTF-16). + On output, data will have an encoding declaration + specifying the client encoding, unless the client encoding is + UTF-8, in which case it will be omitted. + + + + Needless to say, processing XML data with PostgreSQL will be less + error-prone and more efficient if the XML data encoding, client encoding, + and server encoding are the same. Since XML data is internally + processed in UTF-8, computations will be most efficient if the + server encoding is also UTF-8. + + + + + Some XML-related functions may not work at all on non-ASCII data + when the server encoding is not UTF-8. This is known to be an + issue for xmltable() and xpath() in particular. + + + + + + Accessing XML Values + + + The xml data type is unusual in that it does not + provide any comparison operators. This is because there is no + well-defined and universally useful comparison algorithm for XML + data. One consequence of this is that you cannot retrieve rows by + comparing an xml column against a search value. XML + values should therefore typically be accompanied by a separate key + field such as an ID. An alternative solution for comparing XML + values is to convert them to character strings first, but note + that character string comparison has little to do with a useful + XML comparison method. + + + + Since there are no comparison operators for the xml + data type, it is not possible to create an index directly on a + column of this type. If speedy searches in XML data are desired, + possible workarounds include casting the expression to a + character string type and indexing that, or indexing an XPath + expression. Of course, the actual query would have to be adjusted + to search by the indexed expression. + + + + The text-search functionality in PostgreSQL can also be used to speed + up full-document searches of XML data. The necessary + preprocessing support is, however, not yet available in the PostgreSQL + distribution. + + + + + &json; + + &array; + + &rowtypes; + + &rangetypes; + + + Domain Types + + + domain + + + + data type + domain + + + + A domain is a user-defined data type that is + based on another underlying type. Optionally, + it can have constraints that restrict its valid values to a subset of + what the underlying type would allow. Otherwise it behaves like the + underlying type — for example, any operator or function that + can be applied to the underlying type will work on the domain type. + The underlying type can be any built-in or user-defined base type, + enum type, array type, composite type, range type, or another domain. + + + + For example, we could create a domain over integers that accepts only + positive integers: + +CREATE DOMAIN posint AS integer CHECK (VALUE > 0); +CREATE TABLE mytable (id posint); +INSERT INTO mytable VALUES(1); -- works +INSERT INTO mytable VALUES(-1); -- fails + + + + + When an operator or function of the underlying type is applied to a + domain value, the domain is automatically down-cast to the underlying + type. Thus, for example, the result of mytable.id - 1 + is considered to be of type integer not posint. + We could write (mytable.id - 1)::posint to cast the + result back to posint, causing the domain's constraints + to be rechecked. In this case, that would result in an error if the + expression had been applied to an id value of + 1. Assigning a value of the underlying type to a field or variable of + the domain type is allowed without writing an explicit cast, but the + domain's constraints will be checked. + + + + For additional information see . + + + + + Object Identifier Types + + + object identifier + data type + + + + oid + + + + regclass + + + + regcollation + + + + regconfig + + + + regdictionary + + + + regnamespace + + + + regoper + + + + regoperator + + + + regproc + + + + regprocedure + + + + regrole + + + + regtype + + + + xid8 + + + + cid + + + + tid + + + + xid + + + + Object identifiers (OIDs) are used internally by + PostgreSQL as primary keys for various + system tables. + Type oid represents an object identifier. There are also + several alias types for oid, each + named regsomething. + shows an + overview. + + + + The oid type is currently implemented as an unsigned + four-byte integer. Therefore, it is not large enough to provide + database-wide uniqueness in large databases, or even in large + individual tables. + + + + The oid type itself has few operations beyond comparison. + It can be cast to integer, however, and then manipulated using the + standard integer operators. (Beware of possible + signed-versus-unsigned confusion if you do this.) + + + + The OID alias types have no operations of their own except + for specialized input and output routines. These routines are able + to accept and display symbolic names for system objects, rather than + the raw numeric value that type oid would use. The alias + types allow simplified lookup of OID values for objects. For example, + to examine the pg_attribute rows related to a table + mytable, one could write: + +SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass; + + rather than: + +SELECT * FROM pg_attribute + WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable'); + + While that doesn't look all that bad by itself, it's still oversimplified. + A far more complicated sub-select would be needed to + select the right OID if there are multiple tables named + mytable in different schemas. + The regclass input converter handles the table lookup according + to the schema path setting, and so it does the right thing + automatically. Similarly, casting a table's OID to + regclass is handy for symbolic display of a numeric OID. + + + + Object Identifier Types + + + + Name + References + Description + Value Example + + + + + + + oid + any + numeric object identifier + 564182 + + + + regclass + pg_class + relation name + pg_type + + + + regcollation + pg_collation + collation name + "POSIX" + + + + regconfig + pg_ts_config + text search configuration + english + + + + regdictionary + pg_ts_dict + text search dictionary + simple + + + + regnamespace + pg_namespace + namespace name + pg_catalog + + + + regoper + pg_operator + operator name + + + + + + regoperator + pg_operator + operator with argument types + *(integer,&zwsp;integer) + or -(NONE,&zwsp;integer) + + + + regproc + pg_proc + function name + sum + + + + regprocedure + pg_proc + function with argument types + sum(int4) + + + + regrole + pg_authid + role name + smithee + + + + regtype + pg_type + data type name + integer + + + +
+ + + All of the OID alias types for objects that are grouped by namespace + accept schema-qualified names, and will + display schema-qualified names on output if the object would not + be found in the current search path without being qualified. + For example, myschema.mytable is acceptable input + for regclass (if there is such a table). That value + might be output as myschema.mytable, or + just mytable, depending on the current search path. + The regproc and regoper alias types will only + accept input names that are unique (not overloaded), so they are + of limited use; for most uses regprocedure or + regoperator are more appropriate. For regoperator, + unary operators are identified by writing NONE for the unused + operand. + + + + The input functions for these types allow whitespace between tokens, + and will fold upper-case letters to lower case, except within double + quotes; this is done to make the syntax rules similar to the way + object names are written in SQL. Conversely, the output functions + will use double quotes if needed to make the output be a valid SQL + identifier. For example, the OID of a function + named Foo (with upper case F) + taking two integer arguments could be entered as + ' "Foo" ( int, integer ) '::regprocedure. The + output would look like "Foo"(integer,integer). + Both the function name and the argument type names could be + schema-qualified, too. + + + + Many built-in PostgreSQL functions accept + the OID of a table, or another kind of database object, and for + convenience are declared as taking regclass (or the + appropriate OID alias type). This means you do not have to look up + the object's OID by hand, but can just enter its name as a string + literal. For example, the nextval(regclass) function + takes a sequence relation's OID, so you could call it like this: + +nextval('foo') operates on sequence foo +nextval('FOO') same as above +nextval('"Foo"') operates on sequence Foo +nextval('myschema.foo') operates on myschema.foo +nextval('"myschema".foo') same as above +nextval('foo') searches search path for foo + + + + + + When you write the argument of such a function as an unadorned + literal string, it becomes a constant of type regclass + (or the appropriate type). + Since this is really just an OID, it will track the originally + identified object despite later renaming, schema reassignment, + etc. This early binding behavior is usually desirable for + object references in column defaults and views. But sometimes you might + want late binding where the object reference is resolved + at run time. To get late-binding behavior, force the constant to be + stored as a text constant instead of regclass: + +nextval('foo'::text) foo is looked up at runtime + + The to_regclass() function and its siblings + can also be used to perform run-time lookups. See + . + + + + + Another practical example of use of regclass + is to look up the OID of a table listed in + the information_schema views, which don't supply + such OIDs directly. One might for example wish to call + the pg_relation_size() function, which requires + the table OID. Taking the above rules into account, the correct way + to do that is + +SELECT table_schema, table_name, + pg_relation_size((quote_ident(table_schema) || '.' || + quote_ident(table_name))::regclass) +FROM information_schema.tables +WHERE ... + + The quote_ident() function will take care of + double-quoting the identifiers where needed. The seemingly easier + +SELECT pg_relation_size(table_name) +FROM information_schema.tables +WHERE ... + + is not recommended, because it will fail for + tables that are outside your search path or have names that require + quoting. + + + + An additional property of most of the OID alias types is the creation of + dependencies. If a + constant of one of these types appears in a stored expression + (such as a column default expression or view), it creates a dependency + on the referenced object. For example, if a column has a default + expression nextval('my_seq'::regclass), + PostgreSQL + understands that the default expression depends on the sequence + my_seq, so the system will not let the sequence + be dropped without first removing the default expression. The + alternative of nextval('my_seq'::text) does not + create a dependency. + (regrole is an exception to this property. Constants of this + type are not allowed in stored expressions.) + + + + Another identifier type used by the system is xid, or transaction + (abbreviated xact) identifier. This is the data type of the system columns + xmin and xmax. Transaction identifiers are 32-bit quantities. + In some contexts, a 64-bit variant xid8 is used. Unlike + xid values, xid8 values increase strictly + monotonically and cannot be reused in the lifetime of a database cluster. + + + + A third identifier type used by the system is cid, or + command identifier. This is the data type of the system columns + cmin and cmax. Command identifiers are also 32-bit quantities. + + + + A final identifier type used by the system is tid, or tuple + identifier (row identifier). This is the data type of the system column + ctid. A tuple ID is a pair + (block number, tuple index within block) that identifies the + physical location of the row within its table. + + + + (The system columns are further explained in .) + +
+ + + <acronym>pg_lsn Type</acronym> + + + pg_lsn + + + + The pg_lsn data type can be used to store LSN (Log Sequence + Number) data which is a pointer to a location in the WAL. This type is a + representation of XLogRecPtr and an internal system type of + PostgreSQL. + + + + Internally, an LSN is a 64-bit integer, representing a byte position in + the write-ahead log stream. It is printed as two hexadecimal numbers of + up to 8 digits each, separated by a slash; for example, + 16/B374D848. The pg_lsn type supports the + standard comparison operators, like = and + >. Two LSNs can be subtracted using the + - operator; the result is the number of bytes separating + those write-ahead log locations. Also the number of bytes can be + added into and subtracted from LSN using the + +(pg_lsn,numeric) and + -(pg_lsn,numeric) operators, respectively. Note that + the calculated LSN should be in the range of pg_lsn type, + i.e., between 0/0 and + FFFFFFFF/FFFFFFFF. + + + + + Pseudo-Types + + + record + + + + any + + + + anyelement + + + + anyarray + + + + anynonarray + + + + anyenum + + + + anyrange + + + + anymultirange + + + + anycompatible + + + + anycompatiblearray + + + + anycompatiblenonarray + + + + anycompatiblerange + + + + anycompatiblemultirange + + + + void + + + + trigger + + + + event_trigger + + + + pg_ddl_command + + + + language_handler + + + + fdw_handler + + + + table_am_handler + + + + index_am_handler + + + + tsm_handler + + + + cstring + + + + internal + + + + unknown + + + + The PostgreSQL type system contains a + number of special-purpose entries that are collectively called + pseudo-types. A pseudo-type cannot be used as a + column data type, but it can be used to declare a function's + argument or result type. Each of the available pseudo-types is + useful in situations where a function's behavior does not + correspond to simply taking or returning a value of a specific + SQL data type. lists the existing + pseudo-types. + + + + Pseudo-Types + + + + + + Name + Description + + + + + + any + Indicates that a function accepts any input data type. + + + + anyelement + Indicates that a function accepts any data type + (see ). + + + + anyarray + Indicates that a function accepts any array data type + (see ). + + + + anynonarray + Indicates that a function accepts any non-array data type + (see ). + + + + anyenum + Indicates that a function accepts any enum data type + (see and + ). + + + + anyrange + Indicates that a function accepts any range data type + (see and + ). + + + + anymultirange + Indicates that a function accepts any multirange data type + (see and + ). + + + + anycompatible + Indicates that a function accepts any data type, + with automatic promotion of multiple arguments to a common data type + (see ). + + + + anycompatiblearray + Indicates that a function accepts any array data type, + with automatic promotion of multiple arguments to a common data type + (see ). + + + + anycompatiblenonarray + Indicates that a function accepts any non-array data type, + with automatic promotion of multiple arguments to a common data type + (see ). + + + + anycompatiblerange + Indicates that a function accepts any range data type, + with automatic promotion of multiple arguments to a common data type + (see and + ). + + + + anycompatiblemultirange + Indicates that a function accepts any multirange data type, + with automatic promotion of multiple arguments to a common data type + (see and + ). + + + + cstring + Indicates that a function accepts or returns a null-terminated C string. + + + + internal + Indicates that a function accepts or returns a server-internal + data type. + + + + language_handler + A procedural language call handler is declared to return language_handler. + + + + fdw_handler + A foreign-data wrapper handler is declared to return fdw_handler. + + + + table_am_handler + A table access method handler is declared to return table_am_handler. + + + + index_am_handler + An index access method handler is declared to return index_am_handler. + + + + tsm_handler + A tablesample method handler is declared to return tsm_handler. + + + + record + Identifies a function taking or returning an unspecified row type. + + + + trigger + A trigger function is declared to return trigger. + + + + event_trigger + An event trigger function is declared to return event_trigger. + + + + pg_ddl_command + Identifies a representation of DDL commands that is available to event triggers. + + + + void + Indicates that a function returns no value. + + + + unknown + Identifies a not-yet-resolved type, e.g., of an undecorated + string literal. + + + +
+ + + Functions coded in C (whether built-in or dynamically loaded) can be + declared to accept or return any of these pseudo-types. It is up to + the function author to ensure that the function will behave safely + when a pseudo-type is used as an argument type. + + + + Functions coded in procedural languages can use pseudo-types only as + allowed by their implementation languages. At present most procedural + languages forbid use of a pseudo-type as an argument type, and allow + only void and record as a result type (plus + trigger or event_trigger when the function is used + as a trigger or event trigger). Some also support polymorphic functions + using the polymorphic pseudo-types, which are shown above and discussed + in detail in . + + + + The internal pseudo-type is used to declare functions + that are meant only to be called internally by the database + system, and not by direct invocation in an SQL + query. If a function has at least one internal-type + argument then it cannot be called from SQL. To + preserve the type safety of this restriction it is important to + follow this coding rule: do not create any function that is + declared to return internal unless it has at least one + internal argument. + + +
+ +
diff --git a/doc/src/sgml/datetime.sgml b/doc/src/sgml/datetime.sgml new file mode 100644 index 000000000000..c53bd2f379f4 --- /dev/null +++ b/doc/src/sgml/datetime.sgml @@ -0,0 +1,932 @@ + + + + Date/Time Support + + + PostgreSQL uses an internal heuristic + parser for all date/time input support. Dates and times are input as + strings, and are broken up into distinct fields with a preliminary + determination of what kind of information can be in the + field. Each field is interpreted and either assigned a numeric + value, ignored, or rejected. + The parser contains internal lookup tables for all textual fields, + including months, days of the week, and time zones. + + + + This appendix includes information on the content of these + lookup tables and describes the steps used by the parser to decode + dates and times. + + + + Date/Time Input Interpretation + + + Date/time input strings are decoded using the following procedure. + + + + + + Break the input string into tokens and categorize each token as + a string, time, time zone, or number. + + + + + + If the numeric token contains a colon (:), this is + a time string. Include all subsequent digits and colons. + + + + + + If the numeric token contains a dash (-), slash + (/), or two or more dots (.), this is + a date string which might have a text month. If a date token has + already been seen, it is instead interpreted as a time zone + name (e.g., America/New_York). + + + + + + If the token is numeric only, then it is either a single field + or an ISO 8601 concatenated date (e.g., + 19990113 for January 13, 1999) or time + (e.g., 141516 for 14:15:16). + + + + + + If the token starts with a plus (+) or minus + (-), then it is either a numeric time zone or a special + field. + + + + + + + + If the token is an alphabetic string, match up with possible strings: + + + + + + See if the token matches any known time zone abbreviation. + These abbreviations are supplied by the configuration file + described in . + + + + + + If not found, search an internal table to match + the token as either a special string (e.g., today), + day (e.g., Thursday), + month (e.g., January), + or noise word (e.g., at, on). + + + + + + If still not found, throw an error. + + + + + + + + When the token is a number or number field: + + + + + + If there are eight or six digits, + and if no other date fields have been previously read, then interpret + as a concatenated date (e.g., + 19990118 or 990118). + The interpretation is YYYYMMDD or YYMMDD. + + + + + + If the token is three digits + and a year has already been read, then interpret as day of year. + + + + + + If four or six digits and a year has already been read, then + interpret as a time (HHMM or HHMMSS). + + + + + + If three or more digits and no date fields have yet been found, + interpret as a year (this forces yy-mm-dd ordering of the remaining + date fields). + + + + + + Otherwise the date field ordering is assumed to follow the + DateStyle setting: mm-dd-yy, dd-mm-yy, or yy-mm-dd. + Throw an error if a month or day field is found to be out of range. + + + + + + + + If BC has been specified, negate the year and add one for + internal storage. (There is no year zero in the Gregorian + calendar, so numerically 1 BC becomes year zero.) + + + + + + If BC was not specified, and if the year field was two digits in length, + then adjust the year to four digits. If the field is less than 70, then + add 2000, otherwise add 1900. + + + + Gregorian years AD 1–99 can be entered by using 4 digits with leading + zeros (e.g., 0099 is AD 99). + + + + + + + + + + Handling of Invalid or Ambiguous Timestamps + + + Ordinarily, if a date/time string is syntactically valid but contains + out-of-range field values, an error will be thrown. For example, input + specifying the 31st of February will be rejected. + + + + During a daylight-savings-time transition, it is possible for a + seemingly valid timestamp string to represent a nonexistent or ambiguous + timestamp. Such cases are not rejected; the ambiguity is resolved by + determining which UTC offset to apply. For example, supposing that the + parameter is set + to America/New_York, consider + +=> SELECT '2018-03-11 02:30'::timestamptz; + timestamptz +------------------------ + 2018-03-11 03:30:00-04 +(1 row) + + Because that day was a spring-forward transition date in that time zone, + there was no civil time instant 2:30AM; clocks jumped forward from 2AM + EST to 3AM EDT. PostgreSQL interprets the + given time as if it were standard time (UTC-5), which then renders as + 3:30AM EDT (UTC-4). + + + + Conversely, consider the behavior during a fall-back transition: + +=> SELECT '2018-11-04 02:30'::timestamptz; + timestamptz +------------------------ + 2018-11-04 02:30:00-05 +(1 row) + + On that date, there were two possible interpretations of 2:30AM; there + was 2:30AM EDT, and then an hour later after the reversion to standard + time, there was 2:30AM EST. + Again, PostgreSQL interprets the given time + as if it were standard time (UTC-5). We can force the matter by + specifying daylight-savings time: + +=> SELECT '2018-11-04 02:30 EDT'::timestamptz; + timestamptz +------------------------ + 2018-11-04 01:30:00-05 +(1 row) + + This timestamp could validly be rendered as either 2:30 UTC-4 or + 1:30 UTC-5; the timestamp output code chooses the latter. + + + + The precise rule that is applied in such cases is that an invalid + timestamp that appears to fall within a jump-forward daylight savings + transition is assigned the UTC offset that prevailed in the time zone + just before the transition, while an ambiguous timestamp that could fall + on either side of a jump-back transition is assigned the UTC offset that + prevailed just after the transition. In most time zones this is + equivalent to saying that the standard-time interpretation is + preferred when in doubt. + + + + In all cases, the UTC offset associated with a timestamp can be + specified explicitly, using either a numeric UTC offset or a time zone + abbreviation that corresponds to a fixed UTC offset. The rule just + given applies only when it is necessary to infer a UTC offset for a time + zone in which the offset varies. + + + + + + Date/Time Key Words + + + shows the tokens that are + recognized as names of months. + + + + Month Names + + + + Month + Abbreviations + + + + + January + Jan + + + February + Feb + + + March + Mar + + + April + Apr + + + May + + + + June + Jun + + + July + Jul + + + August + Aug + + + September + Sep, Sept + + + October + Oct + + + November + Nov + + + December + Dec + + + +
+ + + shows the tokens that are + recognized as names of days of the week. + + + + Day of the Week Names + + + + Day + Abbreviations + + + + + Sunday + Sun + + + Monday + Mon + + + Tuesday + Tue, Tues + + + Wednesday + Wed, Weds + + + Thursday + Thu, Thur, Thurs + + + Friday + Fri + + + Saturday + Sat + + + +
+ + + shows the tokens that serve + various modifier purposes. + + + + Date/Time Field Modifiers + + + + Identifier + Description + + + + + AM + Time is before 12:00 + + + AT + Ignored + + + JULIAN, JD, J + Next field is Julian Date + + + ON + Ignored + + + PM + Time is on or after 12:00 + + + T + Next field is time + + + +
+
+ + + Date/Time Configuration Files + + + time zone + input abbreviations + + + + Since timezone abbreviations are not well standardized, + PostgreSQL provides a means to customize + the set of abbreviations accepted by the server. The + run-time parameter + determines the active set of abbreviations. While this parameter + can be altered by any database user, the possible values for it + are under the control of the database administrator — they + are in fact names of configuration files stored in + .../share/timezonesets/ of the installation directory. + By adding or altering files in that directory, the administrator + can set local policy for timezone abbreviations. + + + + timezone_abbreviations can be set to any file name + found in .../share/timezonesets/, if the file's name + is entirely alphabetic. (The prohibition against non-alphabetic + characters in timezone_abbreviations prevents reading + files outside the intended directory, as well as reading editor + backup files and other extraneous files.) + + + + A timezone abbreviation file can contain blank lines and comments + beginning with #. Non-comment lines must have one of + these formats: + + +zone_abbreviation offset +zone_abbreviation offset D +zone_abbreviation time_zone_name +@INCLUDE file_name +@OVERRIDE + + + + + A zone_abbreviation is just the abbreviation + being defined. An offset is an integer giving + the equivalent offset in seconds from UTC, positive being east from + Greenwich and negative being west. For example, -18000 would be five + hours west of Greenwich, or North American east coast standard time. + D indicates that the zone name represents local + daylight-savings time rather than standard time. + + + + Alternatively, a time_zone_name can be given, referencing + a zone name defined in the IANA timezone database. The zone's definition + is consulted to see whether the abbreviation is or has been in use in + that zone, and if so, the appropriate meaning is used — that is, + the meaning that was currently in use at the timestamp whose value is + being determined, or the meaning in use immediately before that if it + wasn't current at that time, or the oldest meaning if it was used only + after that time. This behavior is essential for dealing with + abbreviations whose meaning has historically varied. It is also allowed + to define an abbreviation in terms of a zone name in which that + abbreviation does not appear; then using the abbreviation is just + equivalent to writing out the zone name. + + + + + Using a simple integer offset is preferred + when defining an abbreviation whose offset from UTC has never changed, + as such abbreviations are much cheaper to process than those that + require consulting a time zone definition. + + + + + The @INCLUDE syntax allows inclusion of another file in the + .../share/timezonesets/ directory. Inclusion can be nested, + to a limited depth. + + + + The @OVERRIDE syntax indicates that subsequent entries in the + file can override previous entries (typically, entries obtained from + included files). Without this, conflicting definitions of the same + timezone abbreviation are considered an error. + + + + In an unmodified installation, the file Default contains + all the non-conflicting time zone abbreviations for most of the world. + Additional files Australia and India are + provided for those regions: these files first include the + Default file and then add or modify abbreviations as needed. + + + + For reference purposes, a standard installation also contains files + Africa.txt, America.txt, etc, containing + information about every time zone abbreviation known to be in use + according to the IANA timezone database. The zone name + definitions found in these files can be copied and pasted into a custom + configuration file as needed. Note that these files cannot be directly + referenced as timezone_abbreviations settings, because of + the dot embedded in their names. + + + + + If an error occurs while reading the time zone abbreviation set, no new + value is applied and the old set is kept. If the error occurs while + starting the database, startup fails. + + + + + + Time zone abbreviations defined in the configuration file override + non-timezone meanings built into PostgreSQL. + For example, the Australia configuration file defines + SAT (for South Australian Standard Time). When this + file is active, SAT will not be recognized as an abbreviation + for Saturday. + + + + + + If you modify files in .../share/timezonesets/, + it is up to you to make backups — a normal database dump + will not include this directory. + + + + + + + <acronym>POSIX</acronym> Time Zone Specifications + + + time zone + POSIX-style specification + + + + PostgreSQL can accept time zone specifications + that are written according to the POSIX standard's rules + for the TZ environment + variable. POSIX time zone specifications are + inadequate to deal with the complexity of real-world time zone history, + but there are sometimes reasons to use them. + + + + A POSIX time zone specification has the form + +STD offset DST dstoffset , rule + + (For readability, we show spaces between the fields, but spaces should + not be used in practice.) The fields are: + + + + STD is the zone abbreviation to be used + for standard time. + + + + + offset is the zone's standard-time offset + from UTC. + + + + + DST is the zone abbreviation to be used + for daylight-savings time. If this field and the following ones are + omitted, the zone uses a fixed UTC offset with no daylight-savings + rule. + + + + + dstoffset is the daylight-savings offset + from UTC. This field is typically omitted, since it defaults to one + hour less than the standard-time offset, + which is usually the right thing. + + + + + rule defines the rule for when daylight + savings is in effect, as described below. + + + + + + + In this syntax, a zone abbreviation can be a string of letters, such + as EST, or an arbitrary string surrounded by angle + brackets, such as <UTC-05>. + Note that the zone abbreviations given here are only used for output, + and even then only in some timestamp output formats. The zone + abbreviations recognized in timestamp input are determined as explained + in . + + + + The offset fields specify the hours, and optionally minutes and seconds, + difference from UTC. They have the format + hh:mm:ss + optionally with a leading sign (+ + or -). The positive sign is used for + zones west of Greenwich. (Note that this is the + opposite of the ISO-8601 sign convention used elsewhere in + PostgreSQL.) hh + can have one or two digits; mm + and ss (if used) must have two. + + + + The daylight-savings transition rule has the + format + +dstdate / dsttime , stddate / stdtime + + (As before, spaces should not be included in practice.) + The dstdate + and dsttime fields define when daylight-savings + time starts, while stddate + and stdtime define when standard time + starts. (In some cases, notably in zones south of the equator, the + former might be later in the year than the latter.) The date fields + have one of these formats: + + + n + + + A plain integer denotes a day of the year, counting from zero to + 364, or to 365 in leap years. + + + + + Jn + + + In this form, n counts from 1 to 365, + and February 29 is not counted even if it is present. (Thus, a + transition occurring on February 29 could not be specified this + way. However, days after February have the same numbers whether + it's a leap year or not, so that this form is usually more useful + than the plain-integer form for transitions on fixed dates.) + + + + + Mm.n.d + + + This form specifies a transition that always happens during the same + month and on the same day of the week. m + identifies the month, from 1 to 12. n + specifies the n'th occurrence of the + weekday identified by d. + n is a number between 1 and 4, or 5 + meaning the last occurrence of that weekday in the month (which + could be the fourth or the fifth). d is + a number between 0 and 6, with 0 indicating Sunday. + For example, M3.2.0 means the second + Sunday in March. + + + + + + + + + The M format is sufficient to describe many common + daylight-savings transition laws. But note that none of these variants + can deal with daylight-savings law changes, so in practice the + historical data stored for named time zones (in the IANA time zone + database) is necessary to interpret past time stamps correctly. + + + + + The time fields in a transition rule have the same format as the offset + fields described previously, except that they cannot contain signs. + They define the current local time at which the change to the other + time occurs. If omitted, they default to 02:00:00. + + + + If a daylight-savings abbreviation is given but the + transition rule field is omitted, + the fallback behavior is to use the + rule M3.2.0,M11.1.0, which corresponds to USA + practice as of 2020 (that is, spring forward on the second Sunday of + March, fall back on the first Sunday of November, both transitions + occurring at 2AM prevailing time). Note that this rule does not + give correct USA transition dates for years before 2007. + + + + As an example, CET-1CEST,M3.5.0,M10.5.0/3 describes + current (as of 2020) timekeeping practice in Paris. This specification + says that standard time has the abbreviation CET and + is one hour ahead (east) of UTC; daylight savings time has the + abbreviation CEST and is implicitly two hours ahead + of UTC; daylight savings time begins on the last Sunday in March at 2AM + CET and ends on the last Sunday in October at 3AM CEST. + + + + The four timezone names EST5EDT, + CST6CDT, MST7MDT, + and PST8PDT look like they are POSIX zone + specifications. However, they actually are treated as named time zones + because (for historical reasons) there are files by those names in the + IANA time zone database. The practical implication of this is that + these zone names will produce valid historical USA daylight-savings + transitions, even when a plain POSIX specification would not. + + + + One should be wary that it is easy to misspell a POSIX-style time zone + specification, since there is no check on the reasonableness of the + zone abbreviation(s). For example, SET TIMEZONE TO + FOOBAR0 will work, leaving the system effectively using a + rather peculiar abbreviation for UTC. + + + + + + History of Units + + + Gregorian calendar + + + + The SQL standard states that Within the definition of a + datetime literal, the datetime + values are constrained by the natural rules for dates and + times according to the Gregorian calendar. + PostgreSQL follows the SQL + standard's lead by counting dates exclusively in the Gregorian + calendar, even for years before that calendar was in use. + This rule is known as the proleptic Gregorian calendar. + + + + The Julian calendar was introduced by Julius Caesar in 45 BC. + It was in common use in the Western world + until the year 1582, when countries started changing to the Gregorian + calendar. In the Julian calendar, the tropical year is + approximated as 365 1/4 days = 365.25 days. This gives an error of + about 1 day in 128 years. + + + + The accumulating calendar error prompted + Pope Gregory XIII to reform the calendar in accordance with + instructions from the Council of Trent. + In the Gregorian calendar, the tropical year is approximated as + 365 + 97 / 400 days = 365.2425 days. Thus it takes approximately 3300 + years for the tropical year to shift one day with respect to the + Gregorian calendar. + + + + The approximation 365+97/400 is achieved by having 97 leap years + every 400 years, using the following rules: + + + + Every year divisible by 4 is a leap year. + + + However, every year divisible by 100 is not a leap year. + + + However, every year divisible by 400 is a leap year after all. + + + + So, 1700, 1800, 1900, 2100, and 2200 are not leap years. But 1600, + 2000, and 2400 are leap years. + + By contrast, in the older Julian calendar all years divisible by 4 are leap + years. + + + + The papal bull of February 1582 decreed that 10 days should be dropped + from October 1582 so that 15 October should follow immediately after + 4 October. + This was observed in Italy, Poland, Portugal, and Spain. Other Catholic + countries followed shortly after, but Protestant countries were + reluctant to change, and the Greek Orthodox countries didn't change + until the start of the 20th century. + + The reform was observed by Great Britain and its dominions (including what + is now the USA) in 1752. + Thus 2 September 1752 was followed by 14 September 1752. + + This is why Unix systems that have the cal program + produce the following: + + +$ cal 9 1752 + September 1752 + S M Tu W Th F S + 1 2 14 15 16 +17 18 19 20 21 22 23 +24 25 26 27 28 29 30 + + + But, of course, this calendar is only valid for Great Britain and + dominions, not other places. + Since it would be difficult and confusing to try to track the actual + calendars that were in use in various places at various times, + PostgreSQL does not try, but rather follows the Gregorian + calendar rules for all dates, even though this method is not historically + accurate. + + + + Different calendars have been developed in various parts of the + world, many predating the Gregorian system. + + For example, + the beginnings of the Chinese calendar can be traced back to the 14th + century BC. Legend has it that the Emperor Huangdi invented that + calendar in 2637 BC. + + The People's Republic of China uses the Gregorian calendar + for civil purposes. The Chinese calendar is used for determining + festivals. + + + + + + Julian Dates + + + Julian date + + + + The Julian Date system is a method for + numbering days. It is + unrelated to the Julian calendar, though it is confusingly + named similarly to that calendar. + The Julian Date system was invented by the French scholar + Joseph Justus Scaliger (1540–1609) + and probably takes its name from Scaliger's father, + the Italian scholar Julius Caesar Scaliger (1484–1558). + + + + In the Julian Date system, each day has a sequential number, starting + from JD 0 (which is sometimes called the Julian Date). + JD 0 corresponds to 1 January 4713 BC in the Julian calendar, or + 24 November 4714 BC in the Gregorian calendar. Julian Date counting + is most often used by astronomers for labeling their nightly observations, + and therefore a date runs from noon UTC to the next noon UTC, rather than + from midnight to midnight: JD 0 designates the 24 hours from noon UTC on + 24 November 4714 BC to noon UTC on 25 November 4714 BC. + + + + Although PostgreSQL supports Julian Date notation for + input and output of dates (and also uses Julian dates for some internal + datetime calculations), it does not observe the nicety of having dates + run from noon to noon. PostgreSQL treats a Julian Date + as running from local midnight to local midnight, the same as a normal + date. + + + + This definition does, however, provide a way to obtain the astronomical + definition when you need it: do the arithmetic in time + zone UTC+12. For example, + +=> SELECT extract(julian from '2021-06-23 7:00:00-04'::timestamptz at time zone 'UTC+12'); + extract +------------------------------ + 2459388.95833333333333333333 +(1 row) +=> SELECT extract(julian from '2021-06-23 8:00:00-04'::timestamptz at time zone 'UTC+12'); + extract +-------------------------------------- + 2459389.0000000000000000000000000000 +(1 row) +=> SELECT extract(julian from date '2021-06-23'); + extract +--------- + 2459389 +(1 row) + + + + +
diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml new file mode 100644 index 000000000000..4ab38bcc999b --- /dev/null +++ b/doc/src/sgml/dblink.sgml @@ -0,0 +1,2136 @@ + + + + dblink + + + dblink + + + + dblink is a module that supports connections to + other PostgreSQL databases from within a database + session. + + + + See also , which provides roughly the same + functionality using a more modern and standards-compliant infrastructure. + + + + + dblink_connect + + + + dblink_connect + 3 + + + + dblink_connect + opens a persistent connection to a remote database + + + + +dblink_connect(text connstr) returns text +dblink_connect(text connname, text connstr) returns text + + + + + Description + + + dblink_connect() establishes a connection to a remote + PostgreSQL database. The server and database to + be contacted are identified through a standard libpq + connection string. Optionally, a name can be assigned to the + connection. Multiple named connections can be open at once, but + only one unnamed connection is permitted at a time. The connection + will persist until closed or until the database session is ended. + + + + The connection string may also be the name of an existing foreign + server. It is recommended to use the foreign-data wrapper + dblink_fdw when defining the foreign + server. See the example below, as well as + and + . + + + + + + Arguments + + + + connname + + + The name to use for this connection; if omitted, an unnamed + connection is opened, replacing any existing unnamed connection. + + + + + + connstr + + libpq-style connection info string, for example + hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres + password=mypasswd options=-csearch_path=. + For details see . + Alternatively, the name of a foreign server. + + + + + + + + Return Value + + + Returns status, which is always OK (since any error + causes the function to throw an error instead of returning). + + + + + Notes + + + If untrusted users have access to a database that has not adopted a + secure schema usage pattern, + begin each session by removing publicly-writable schemas from + search_path. One could, for example, + add options=-csearch_path= to + connstr. This consideration is not specific + to dblink; it applies to every interface for + executing arbitrary SQL commands. + + + + Only superusers may use dblink_connect to create + non-password-authenticated connections. If non-superusers need this + capability, use dblink_connect_u instead. + + + + It is unwise to choose connection names that contain equal signs, + as this opens a risk of confusion with connection info strings + in other dblink functions. + + + + + Examples + + +SELECT dblink_connect('dbname=postgres options=-csearch_path='); + dblink_connect +---------------- + OK +(1 row) + +SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path='); + dblink_connect +---------------- + OK +(1 row) + +-- FOREIGN DATA WRAPPER functionality +-- Note: local connection must require password authentication for this to work properly +-- Otherwise, you will receive the following error from dblink_connect(): +-- ERROR: password is required +-- DETAIL: Non-superuser cannot connect if the server does not request a password. +-- HINT: Target server's authentication method must be changed. + +CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw OPTIONS (hostaddr '127.0.0.1', dbname 'contrib_regression'); + +CREATE USER regress_dblink_user WITH PASSWORD 'secret'; +CREATE USER MAPPING FOR regress_dblink_user SERVER fdtest OPTIONS (user 'regress_dblink_user', password 'secret'); +GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user; +GRANT SELECT ON TABLE foo TO regress_dblink_user; + +\set ORIGINAL_USER :USER +\c - regress_dblink_user +SELECT dblink_connect('myconn', 'fdtest'); + dblink_connect +---------------- + OK +(1 row) + +SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]); + a | b | c +----+---+--------------- + 0 | a | {a0,b0,c0} + 1 | b | {a1,b1,c1} + 2 | c | {a2,b2,c2} + 3 | d | {a3,b3,c3} + 4 | e | {a4,b4,c4} + 5 | f | {a5,b5,c5} + 6 | g | {a6,b6,c6} + 7 | h | {a7,b7,c7} + 8 | i | {a8,b8,c8} + 9 | j | {a9,b9,c9} + 10 | k | {a10,b10,c10} +(11 rows) + +\c - :ORIGINAL_USER +REVOKE USAGE ON FOREIGN SERVER fdtest FROM regress_dblink_user; +REVOKE SELECT ON TABLE foo FROM regress_dblink_user; +DROP USER MAPPING FOR regress_dblink_user SERVER fdtest; +DROP USER regress_dblink_user; +DROP SERVER fdtest; + + + + + + + dblink_connect_u + + + + dblink_connect_u + 3 + + + + dblink_connect_u + opens a persistent connection to a remote database, insecurely + + + + +dblink_connect_u(text connstr) returns text +dblink_connect_u(text connname, text connstr) returns text + + + + + Description + + + dblink_connect_u() is identical to + dblink_connect(), except that it will allow non-superusers + to connect using any authentication method. + + + + If the remote server selects an authentication method that does not + involve a password, then impersonation and subsequent escalation of + privileges can occur, because the session will appear to have + originated from the user as which the local PostgreSQL + server runs. Also, even if the remote server does demand a password, + it is possible for the password to be supplied from the server + environment, such as a ~/.pgpass file belonging to the + server's user. This opens not only a risk of impersonation, but the + possibility of exposing a password to an untrustworthy remote server. + Therefore, dblink_connect_u() is initially + installed with all privileges revoked from PUBLIC, + making it un-callable except by superusers. In some situations + it may be appropriate to grant EXECUTE permission for + dblink_connect_u() to specific users who are considered + trustworthy, but this should be done with care. It is also recommended + that any ~/.pgpass file belonging to the server's user + not contain any records specifying a wildcard host name. + + + + For further details see dblink_connect(). + + + + + + + dblink_disconnect + + + + dblink_disconnect + 3 + + + + dblink_disconnect + closes a persistent connection to a remote database + + + + +dblink_disconnect() returns text +dblink_disconnect(text connname) returns text + + + + + Description + + + dblink_disconnect() closes a connection previously opened + by dblink_connect(). The form with no arguments closes + an unnamed connection. + + + + + Arguments + + + + connname + + + The name of a named connection to be closed. + + + + + + + + Return Value + + + Returns status, which is always OK (since any error + causes the function to throw an error instead of returning). + + + + + Examples + + +SELECT dblink_disconnect(); + dblink_disconnect +------------------- + OK +(1 row) + +SELECT dblink_disconnect('myconn'); + dblink_disconnect +------------------- + OK +(1 row) + + + + + + + dblink + + + + dblink + 3 + + + + dblink + executes a query in a remote database + + + + +dblink(text connname, text sql [, bool fail_on_error]) returns setof record +dblink(text connstr, text sql [, bool fail_on_error]) returns setof record +dblink(text sql [, bool fail_on_error]) returns setof record + + + + + Description + + + dblink executes a query (usually a SELECT, + but it can be any SQL statement that returns rows) in a remote database. + + + + When two text arguments are given, the first one is first + looked up as a persistent connection's name; if found, the command + is executed on that connection. If not found, the first argument + is treated as a connection info string as for dblink_connect, + and the indicated connection is made just for the duration of this command. + + + + + Arguments + + + + connname + + + Name of the connection to use; omit this parameter to use the + unnamed connection. + + + + + + connstr + + + A connection info string, as previously described for + dblink_connect. + + + + + + sql + + + The SQL query that you wish to execute in the remote database, + for example select * from foo. + + + + + + fail_on_error + + + If true (the default when omitted) then an error thrown on the + remote side of the connection causes an error to also be thrown + locally. If false, the remote error is locally reported as a NOTICE, + and the function returns no rows. + + + + + + + + Return Value + + + The function returns the row(s) produced by the query. Since + dblink can be used with any query, it is declared + to return record, rather than specifying any particular + set of columns. This means that you must specify the expected + set of columns in the calling query — otherwise + PostgreSQL would not know what to expect. + Here is an example: + + +SELECT * + FROM dblink('dbname=mydb options=-csearch_path=', + 'select proname, prosrc from pg_proc') + AS t1(proname name, prosrc text) + WHERE proname LIKE 'bytea%'; + + + The alias part of the FROM clause must + specify the column names and types that the function will return. + (Specifying column names in an alias is actually standard SQL + syntax, but specifying column types is a PostgreSQL + extension.) This allows the system to understand what + * should expand to, and what proname + in the WHERE clause refers to, in advance of trying + to execute the function. At run time, an error will be thrown + if the actual query result from the remote database does not + have the same number of columns shown in the FROM clause. + The column names need not match, however, and dblink + does not insist on exact type matches either. It will succeed + so long as the returned data strings are valid input for the + column type declared in the FROM clause. + + + + + Notes + + + A convenient way to use dblink with predetermined + queries is to create a view. + This allows the column type information to be buried in the view, + instead of having to spell it out in every query. For example, + + +CREATE VIEW myremote_pg_proc AS + SELECT * + FROM dblink('dbname=postgres options=-csearch_path=', + 'select proname, prosrc from pg_proc') + AS t1(proname name, prosrc text); + +SELECT * FROM myremote_pg_proc WHERE proname LIKE 'bytea%'; + + + + + Examples + + +SELECT * FROM dblink('dbname=postgres options=-csearch_path=', + 'select proname, prosrc from pg_proc') + AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%'; + proname | prosrc +------------+------------ + byteacat | byteacat + byteaeq | byteaeq + bytealt | bytealt + byteale | byteale + byteagt | byteagt + byteage | byteage + byteane | byteane + byteacmp | byteacmp + bytealike | bytealike + byteanlike | byteanlike + byteain | byteain + byteaout | byteaout +(12 rows) + +SELECT dblink_connect('dbname=postgres options=-csearch_path='); + dblink_connect +---------------- + OK +(1 row) + +SELECT * FROM dblink('select proname, prosrc from pg_proc') + AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%'; + proname | prosrc +------------+------------ + byteacat | byteacat + byteaeq | byteaeq + bytealt | bytealt + byteale | byteale + byteagt | byteagt + byteage | byteage + byteane | byteane + byteacmp | byteacmp + bytealike | bytealike + byteanlike | byteanlike + byteain | byteain + byteaout | byteaout +(12 rows) + +SELECT dblink_connect('myconn', 'dbname=regression options=-csearch_path='); + dblink_connect +---------------- + OK +(1 row) + +SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc') + AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%'; + proname | prosrc +------------+------------ + bytearecv | bytearecv + byteasend | byteasend + byteale | byteale + byteagt | byteagt + byteage | byteage + byteane | byteane + byteacmp | byteacmp + bytealike | bytealike + byteanlike | byteanlike + byteacat | byteacat + byteaeq | byteaeq + bytealt | bytealt + byteain | byteain + byteaout | byteaout +(14 rows) + + + + + + + dblink_exec + + + + dblink_exec + 3 + + + + dblink_exec + executes a command in a remote database + + + + +dblink_exec(text connname, text sql [, bool fail_on_error]) returns text +dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text +dblink_exec(text sql [, bool fail_on_error]) returns text + + + + + Description + + + dblink_exec executes a command (that is, any SQL statement + that doesn't return rows) in a remote database. + + + + When two text arguments are given, the first one is first + looked up as a persistent connection's name; if found, the command + is executed on that connection. If not found, the first argument + is treated as a connection info string as for dblink_connect, + and the indicated connection is made just for the duration of this command. + + + + + Arguments + + + + connname + + + Name of the connection to use; omit this parameter to use the + unnamed connection. + + + + + + connstr + + + A connection info string, as previously described for + dblink_connect. + + + + + + sql + + + The SQL command that you wish to execute in the remote database, + for example + insert into foo values(0, 'a', '{"a0","b0","c0"}'). + + + + + + fail_on_error + + + If true (the default when omitted) then an error thrown on the + remote side of the connection causes an error to also be thrown + locally. If false, the remote error is locally reported as a NOTICE, + and the function's return value is set to ERROR. + + + + + + + + Return Value + + + Returns status, either the command's status string or ERROR. + + + + + Examples + + +SELECT dblink_connect('dbname=dblink_test_standby'); + dblink_connect +---------------- + OK +(1 row) + +SELECT dblink_exec('insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');'); + dblink_exec +----------------- + INSERT 943366 1 +(1 row) + +SELECT dblink_connect('myconn', 'dbname=regression'); + dblink_connect +---------------- + OK +(1 row) + +SELECT dblink_exec('myconn', 'insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');'); + dblink_exec +------------------ + INSERT 6432584 1 +(1 row) + +SELECT dblink_exec('myconn', 'insert into pg_class values (''foo'')',false); +NOTICE: sql error +DETAIL: ERROR: null value in column "relnamespace" violates not-null constraint + + dblink_exec +------------- + ERROR +(1 row) + + + + + + + dblink_open + + + + dblink_open + 3 + + + + dblink_open + opens a cursor in a remote database + + + + +dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text +dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text + + + + + Description + + + dblink_open() opens a cursor in a remote database. + The cursor can subsequently be manipulated with + dblink_fetch() and dblink_close(). + + + + + Arguments + + + + connname + + + Name of the connection to use; omit this parameter to use the + unnamed connection. + + + + + + cursorname + + + The name to assign to this cursor. + + + + + + sql + + + The SELECT statement that you wish to execute in the remote + database, for example select * from pg_class. + + + + + + fail_on_error + + + If true (the default when omitted) then an error thrown on the + remote side of the connection causes an error to also be thrown + locally. If false, the remote error is locally reported as a NOTICE, + and the function's return value is set to ERROR. + + + + + + + + Return Value + + + Returns status, either OK or ERROR. + + + + + Notes + + + Since a cursor can only persist within a transaction, + dblink_open starts an explicit transaction block + (BEGIN) on the remote side, if the remote side was + not already within a transaction. This transaction will be + closed again when the matching dblink_close is + executed. Note that if + you use dblink_exec to change data between + dblink_open and dblink_close, + and then an error occurs or you use dblink_disconnect before + dblink_close, your change will be + lost because the transaction will be aborted. + + + + + Examples + + +SELECT dblink_connect('dbname=postgres options=-csearch_path='); + dblink_connect +---------------- + OK +(1 row) + +SELECT dblink_open('foo', 'select proname, prosrc from pg_proc'); + dblink_open +------------- + OK +(1 row) + + + + + + + dblink_fetch + + + + dblink_fetch + 3 + + + + dblink_fetch + returns rows from an open cursor in a remote database + + + + +dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record +dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record + + + + + Description + + + dblink_fetch fetches rows from a cursor previously + established by dblink_open. + + + + + Arguments + + + + connname + + + Name of the connection to use; omit this parameter to use the + unnamed connection. + + + + + + cursorname + + + The name of the cursor to fetch from. + + + + + + howmany + + + The maximum number of rows to retrieve. The next howmany + rows are fetched, starting at the current cursor position, moving + forward. Once the cursor has reached its end, no more rows are produced. + + + + + + fail_on_error + + + If true (the default when omitted) then an error thrown on the + remote side of the connection causes an error to also be thrown + locally. If false, the remote error is locally reported as a NOTICE, + and the function returns no rows. + + + + + + + + Return Value + + + The function returns the row(s) fetched from the cursor. To use this + function, you will need to specify the expected set of columns, + as previously discussed for dblink. + + + + + Notes + + + On a mismatch between the number of return columns specified in the + FROM clause, and the actual number of columns returned by the + remote cursor, an error will be thrown. In this event, the remote cursor + is still advanced by as many rows as it would have been if the error had + not occurred. The same is true for any other error occurring in the local + query after the remote FETCH has been done. + + + + + Examples + + +SELECT dblink_connect('dbname=postgres options=-csearch_path='); + dblink_connect +---------------- + OK +(1 row) + +SELECT dblink_open('foo', 'select proname, prosrc from pg_proc where proname like ''bytea%'''); + dblink_open +------------- + OK +(1 row) + +SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); + funcname | source +----------+---------- + byteacat | byteacat + byteacmp | byteacmp + byteaeq | byteaeq + byteage | byteage + byteagt | byteagt +(5 rows) + +SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); + funcname | source +-----------+----------- + byteain | byteain + byteale | byteale + bytealike | bytealike + bytealt | bytealt + byteane | byteane +(5 rows) + +SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); + funcname | source +------------+------------ + byteanlike | byteanlike + byteaout | byteaout +(2 rows) + +SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text); + funcname | source +----------+-------- +(0 rows) + + + + + + + dblink_close + + + + dblink_close + 3 + + + + dblink_close + closes a cursor in a remote database + + + + +dblink_close(text cursorname [, bool fail_on_error]) returns text +dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text + + + + + Description + + + dblink_close closes a cursor previously opened with + dblink_open. + + + + + Arguments + + + + connname + + + Name of the connection to use; omit this parameter to use the + unnamed connection. + + + + + + cursorname + + + The name of the cursor to close. + + + + + + fail_on_error + + + If true (the default when omitted) then an error thrown on the + remote side of the connection causes an error to also be thrown + locally. If false, the remote error is locally reported as a NOTICE, + and the function's return value is set to ERROR. + + + + + + + + Return Value + + + Returns status, either OK or ERROR. + + + + + Notes + + + If dblink_open started an explicit transaction block, + and this is the last remaining open cursor in this connection, + dblink_close will issue the matching COMMIT. + + + + + Examples + + +SELECT dblink_connect('dbname=postgres options=-csearch_path='); + dblink_connect +---------------- + OK +(1 row) + +SELECT dblink_open('foo', 'select proname, prosrc from pg_proc'); + dblink_open +------------- + OK +(1 row) + +SELECT dblink_close('foo'); + dblink_close +-------------- + OK +(1 row) + + + + + + + dblink_get_connections + + + + dblink_get_connections + 3 + + + + dblink_get_connections + returns the names of all open named dblink connections + + + + +dblink_get_connections() returns text[] + + + + + Description + + + dblink_get_connections returns an array of the names + of all open named dblink connections. + + + + + Return Value + + Returns a text array of connection names, or NULL if none. + + + + Examples + + +SELECT dblink_get_connections(); + + + + + + + dblink_error_message + + + + dblink_error_message + 3 + + + + dblink_error_message + gets last error message on the named connection + + + + +dblink_error_message(text connname) returns text + + + + + Description + + + dblink_error_message fetches the most recent remote + error message for a given connection. + + + + + Arguments + + + + connname + + + Name of the connection to use. + + + + + + + + Return Value + + + Returns last error message, or OK if there has been + no error in this connection. + + + + + Notes + + + When asynchronous queries are initiated by + dblink_send_query, the error message associated with + the connection might not get updated until the server's response message + is consumed. This typically means that dblink_is_busy + or dblink_get_result should be called prior to + dblink_error_message, so that any error generated by + the asynchronous query will be visible. + + + + + Examples + + +SELECT dblink_error_message('dtest1'); + + + + + + + dblink_send_query + + + + dblink_send_query + 3 + + + + dblink_send_query + sends an async query to a remote database + + + + +dblink_send_query(text connname, text sql) returns int + + + + + Description + + + dblink_send_query sends a query to be executed + asynchronously, that is, without immediately waiting for the result. + There must not be an async query already in progress on the + connection. + + + + After successfully dispatching an async query, completion status + can be checked with dblink_is_busy, and the results + are ultimately collected with dblink_get_result. + It is also possible to attempt to cancel an active async query + using dblink_cancel_query. + + + + + Arguments + + + + connname + + + Name of the connection to use. + + + + + + sql + + + The SQL statement that you wish to execute in the remote database, + for example select * from pg_class. + + + + + + + + Return Value + + + Returns 1 if the query was successfully dispatched, 0 otherwise. + + + + + Examples + + +SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 < 3'); + + + + + + + dblink_is_busy + + + + dblink_is_busy + 3 + + + + dblink_is_busy + checks if connection is busy with an async query + + + + +dblink_is_busy(text connname) returns int + + + + + Description + + + dblink_is_busy tests whether an async query is in progress. + + + + + Arguments + + + + connname + + + Name of the connection to check. + + + + + + + + Return Value + + + Returns 1 if connection is busy, 0 if it is not busy. + If this function returns 0, it is guaranteed that + dblink_get_result will not block. + + + + + Examples + + +SELECT dblink_is_busy('dtest1'); + + + + + + + dblink_get_notify + + + + dblink_get_notify + 3 + + + + dblink_get_notify + retrieve async notifications on a connection + + + + +dblink_get_notify() returns setof (notify_name text, be_pid int, extra text) +dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text) + + + + + Description + + + dblink_get_notify retrieves notifications on either + the unnamed connection, or on a named connection if specified. + To receive notifications via dblink, LISTEN must + first be issued, using dblink_exec. + For details see and . + + + + + + Arguments + + + + connname + + + The name of a named connection to get notifications on. + + + + + + + + Return Value + Returns setof (notify_name text, be_pid int, extra text), or an empty set if none. + + + + Examples + + +SELECT dblink_exec('LISTEN virtual'); + dblink_exec +------------- + LISTEN +(1 row) + +SELECT * FROM dblink_get_notify(); + notify_name | be_pid | extra +-------------+--------+------- +(0 rows) + +NOTIFY virtual; +NOTIFY + +SELECT * FROM dblink_get_notify(); + notify_name | be_pid | extra +-------------+--------+------- + virtual | 1229 | +(1 row) + + + + + + + dblink_get_result + + + + dblink_get_result + 3 + + + + dblink_get_result + gets an async query result + + + + +dblink_get_result(text connname [, bool fail_on_error]) returns setof record + + + + + Description + + + dblink_get_result collects the results of an + asynchronous query previously sent with dblink_send_query. + If the query is not already completed, dblink_get_result + will wait until it is. + + + + + Arguments + + + + connname + + + Name of the connection to use. + + + + + + fail_on_error + + + If true (the default when omitted) then an error thrown on the + remote side of the connection causes an error to also be thrown + locally. If false, the remote error is locally reported as a NOTICE, + and the function returns no rows. + + + + + + + + Return Value + + + For an async query (that is, an SQL statement returning rows), + the function returns the row(s) produced by the query. To use this + function, you will need to specify the expected set of columns, + as previously discussed for dblink. + + + + For an async command (that is, an SQL statement not returning rows), + the function returns a single row with a single text column containing + the command's status string. It is still necessary to specify that + the result will have a single text column in the calling FROM + clause. + + + + + Notes + + + This function must be called if + dblink_send_query returned 1. + It must be called once for each query + sent, and one additional time to obtain an empty set result, + before the connection can be used again. + + + + When using dblink_send_query and + dblink_get_result, dblink fetches the entire + remote query result before returning any of it to the local query + processor. If the query returns a large number of rows, this can result + in transient memory bloat in the local session. It may be better to open + such a query as a cursor with dblink_open and then fetch a + manageable number of rows at a time. Alternatively, use plain + dblink(), which avoids memory bloat by spooling large result + sets to disk. + + + + + Examples + + +contrib_regression=# SELECT dblink_connect('dtest1', 'dbname=contrib_regression'); + dblink_connect +---------------- + OK +(1 row) + +contrib_regression=# SELECT * FROM +contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 < 3') AS t1; + t1 +---- + 1 +(1 row) + +contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]); + f1 | f2 | f3 +----+----+------------ + 0 | a | {a0,b0,c0} + 1 | b | {a1,b1,c1} + 2 | c | {a2,b2,c2} +(3 rows) + +contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]); + f1 | f2 | f3 +----+----+---- +(0 rows) + +contrib_regression=# SELECT * FROM +contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 < 3; select * from foo where f1 > 6') AS t1; + t1 +---- + 1 +(1 row) + +contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]); + f1 | f2 | f3 +----+----+------------ + 0 | a | {a0,b0,c0} + 1 | b | {a1,b1,c1} + 2 | c | {a2,b2,c2} +(3 rows) + +contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]); + f1 | f2 | f3 +----+----+--------------- + 7 | h | {a7,b7,c7} + 8 | i | {a8,b8,c8} + 9 | j | {a9,b9,c9} + 10 | k | {a10,b10,c10} +(4 rows) + +contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]); + f1 | f2 | f3 +----+----+---- +(0 rows) + + + + + + + dblink_cancel_query + + + + dblink_cancel_query + 3 + + + + dblink_cancel_query + cancels any active query on the named connection + + + + +dblink_cancel_query(text connname) returns text + + + + + Description + + + dblink_cancel_query attempts to cancel any query that + is in progress on the named connection. Note that this is not + certain to succeed (since, for example, the remote query might + already have finished). A cancel request simply improves the + odds that the query will fail soon. You must still complete the + normal query protocol, for example by calling + dblink_get_result. + + + + + Arguments + + + + connname + + + Name of the connection to use. + + + + + + + + Return Value + + + Returns OK if the cancel request has been sent, or + the text of an error message on failure. + + + + + Examples + + +SELECT dblink_cancel_query('dtest1'); + + + + + + + dblink_get_pkey + + + + dblink_get_pkey + 3 + + + + dblink_get_pkey + returns the positions and field names of a relation's + primary key fields + + + + + +dblink_get_pkey(text relname) returns setof dblink_pkey_results + + + + + Description + + + dblink_get_pkey provides information about the primary + key of a relation in the local database. This is sometimes useful + in generating queries to be sent to remote databases. + + + + + Arguments + + + + relname + + + Name of a local relation, for example foo or + myschema.mytab. Include double quotes if the + name is mixed-case or contains special characters, for + example "FooBar"; without quotes, the string + will be folded to lower case. + + + + + + + + Return Value + + + Returns one row for each primary key field, or no rows if the relation + has no primary key. The result row type is defined as + + +CREATE TYPE dblink_pkey_results AS (position int, colname text); + + + The position column simply runs from 1 to N; + it is the number of the field within the primary key, not the number + within the table's columns. + + + + + Examples + + +CREATE TABLE foobar ( + f1 int, + f2 int, + f3 int, + PRIMARY KEY (f1, f2, f3) +); +CREATE TABLE + +SELECT * FROM dblink_get_pkey('foobar'); + position | colname +----------+--------- + 1 | f1 + 2 | f2 + 3 | f3 +(3 rows) + + + + + + + dblink_build_sql_insert + + + + dblink_build_sql_insert + 3 + + + + dblink_build_sql_insert + + builds an INSERT statement using a local tuple, replacing the + primary key field values with alternative supplied values + + + + + +dblink_build_sql_insert(text relname, + int2vector primary_key_attnums, + integer num_primary_key_atts, + text[] src_pk_att_vals_array, + text[] tgt_pk_att_vals_array) returns text + + + + + Description + + + dblink_build_sql_insert can be useful in doing selective + replication of a local table to a remote database. It selects a row + from the local table based on primary key, and then builds an SQL + INSERT command that will duplicate that row, but with + the primary key values replaced by the values in the last argument. + (To make an exact copy of the row, just specify the same values for + the last two arguments.) + + + + + Arguments + + + + relname + + + Name of a local relation, for example foo or + myschema.mytab. Include double quotes if the + name is mixed-case or contains special characters, for + example "FooBar"; without quotes, the string + will be folded to lower case. + + + + + + primary_key_attnums + + + Attribute numbers (1-based) of the primary key fields, + for example 1 2. + + + + + + num_primary_key_atts + + + The number of primary key fields. + + + + + + src_pk_att_vals_array + + + Values of the primary key fields to be used to look up the + local tuple. Each field is represented in text form. + An error is thrown if there is no local row with these + primary key values. + + + + + + tgt_pk_att_vals_array + + + Values of the primary key fields to be placed in the resulting + INSERT command. Each field is represented in text form. + + + + + + + + Return Value + + Returns the requested SQL statement as text. + + + + Notes + + + As of PostgreSQL 9.0, the attribute numbers in + primary_key_attnums are interpreted as logical + column numbers, corresponding to the column's position in + SELECT * FROM relname. Previous versions interpreted the + numbers as physical column positions. There is a difference if any + column(s) to the left of the indicated column have been dropped during + the lifetime of the table. + + + + + Examples + + +SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}'); + dblink_build_sql_insert +-------------------------------------------------- + INSERT INTO foo(f1,f2,f3) VALUES('1','b''a','1') +(1 row) + + + + + + + dblink_build_sql_delete + + + + dblink_build_sql_delete + 3 + + + + dblink_build_sql_delete + builds a DELETE statement using supplied values for primary + key field values + + + + + +dblink_build_sql_delete(text relname, + int2vector primary_key_attnums, + integer num_primary_key_atts, + text[] tgt_pk_att_vals_array) returns text + + + + + Description + + + dblink_build_sql_delete can be useful in doing selective + replication of a local table to a remote database. It builds an SQL + DELETE command that will delete the row with the given + primary key values. + + + + + Arguments + + + + relname + + + Name of a local relation, for example foo or + myschema.mytab. Include double quotes if the + name is mixed-case or contains special characters, for + example "FooBar"; without quotes, the string + will be folded to lower case. + + + + + + primary_key_attnums + + + Attribute numbers (1-based) of the primary key fields, + for example 1 2. + + + + + + num_primary_key_atts + + + The number of primary key fields. + + + + + + tgt_pk_att_vals_array + + + Values of the primary key fields to be used in the resulting + DELETE command. Each field is represented in text form. + + + + + + + + Return Value + + Returns the requested SQL statement as text. + + + + Notes + + + As of PostgreSQL 9.0, the attribute numbers in + primary_key_attnums are interpreted as logical + column numbers, corresponding to the column's position in + SELECT * FROM relname. Previous versions interpreted the + numbers as physical column positions. There is a difference if any + column(s) to the left of the indicated column have been dropped during + the lifetime of the table. + + + + + Examples + + +SELECT dblink_build_sql_delete('"MyFoo"', '1 2', 2, '{"1", "b"}'); + dblink_build_sql_delete +--------------------------------------------- + DELETE FROM "MyFoo" WHERE f1='1' AND f2='b' +(1 row) + + + + + + + dblink_build_sql_update + + + + dblink_build_sql_update + 3 + + + + dblink_build_sql_update + builds an UPDATE statement using a local tuple, replacing + the primary key field values with alternative supplied values + + + + + +dblink_build_sql_update(text relname, + int2vector primary_key_attnums, + integer num_primary_key_atts, + text[] src_pk_att_vals_array, + text[] tgt_pk_att_vals_array) returns text + + + + + Description + + + dblink_build_sql_update can be useful in doing selective + replication of a local table to a remote database. It selects a row + from the local table based on primary key, and then builds an SQL + UPDATE command that will duplicate that row, but with + the primary key values replaced by the values in the last argument. + (To make an exact copy of the row, just specify the same values for + the last two arguments.) The UPDATE command always assigns + all fields of the row — the main difference between this and + dblink_build_sql_insert is that it's assumed that + the target row already exists in the remote table. + + + + + Arguments + + + + relname + + + Name of a local relation, for example foo or + myschema.mytab. Include double quotes if the + name is mixed-case or contains special characters, for + example "FooBar"; without quotes, the string + will be folded to lower case. + + + + + + primary_key_attnums + + + Attribute numbers (1-based) of the primary key fields, + for example 1 2. + + + + + + num_primary_key_atts + + + The number of primary key fields. + + + + + + src_pk_att_vals_array + + + Values of the primary key fields to be used to look up the + local tuple. Each field is represented in text form. + An error is thrown if there is no local row with these + primary key values. + + + + + + tgt_pk_att_vals_array + + + Values of the primary key fields to be placed in the resulting + UPDATE command. Each field is represented in text form. + + + + + + + + Return Value + + Returns the requested SQL statement as text. + + + + Notes + + + As of PostgreSQL 9.0, the attribute numbers in + primary_key_attnums are interpreted as logical + column numbers, corresponding to the column's position in + SELECT * FROM relname. Previous versions interpreted the + numbers as physical column positions. There is a difference if any + column(s) to the left of the indicated column have been dropped during + the lifetime of the table. + + + + + Examples + + +SELECT dblink_build_sql_update('foo', '1 2', 2, '{"1", "a"}', '{"1", "b"}'); + dblink_build_sql_update +------------------------------------------------------------- + UPDATE foo SET f1='1',f2='b',f3='1' WHERE f1='1' AND f2='b' +(1 row) + + + + + diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml new file mode 100644 index 000000000000..498654876fdc --- /dev/null +++ b/doc/src/sgml/ddl.sgml @@ -0,0 +1,5078 @@ + + + + Data Definition + + + This chapter covers how one creates the database structures that + will hold one's data. In a relational database, the raw data is + stored in tables, so the majority of this chapter is devoted to + explaining how tables are created and modified and what features are + available to control what data is stored in the tables. + Subsequently, we discuss how tables can be organized into + schemas, and how privileges can be assigned to tables. Finally, + we will briefly look at other features that affect the data storage, + such as inheritance, table partitioning, views, functions, and + triggers. + + + + Table Basics + + + table + + + + row + + + + column + + + + A table in a relational database is much like a table on paper: It + consists of rows and columns. The number and order of the columns + is fixed, and each column has a name. The number of rows is + variable — it reflects how much data is stored at a given moment. + SQL does not make any guarantees about the order of the rows in a + table. When a table is read, the rows will appear in an unspecified order, + unless sorting is explicitly requested. This is covered in . Furthermore, SQL does not assign unique + identifiers to rows, so it is possible to have several completely + identical rows in a table. This is a consequence of the + mathematical model that underlies SQL but is usually not desirable. + Later in this chapter we will see how to deal with this issue. + + + + Each column has a data type. The data type constrains the set of + possible values that can be assigned to a column and assigns + semantics to the data stored in the column so that it can be used + for computations. For instance, a column declared to be of a + numerical type will not accept arbitrary text strings, and the data + stored in such a column can be used for mathematical computations. + By contrast, a column declared to be of a character string type + will accept almost any kind of data but it does not lend itself to + mathematical calculations, although other operations such as string + concatenation are available. + + + + PostgreSQL includes a sizable set of + built-in data types that fit many applications. Users can also + define their own data types. Most built-in data types have obvious + names and semantics, so we defer a detailed explanation to . Some of the frequently used data types are + integer for whole numbers, numeric for + possibly fractional numbers, text for character + strings, date for dates, time for + time-of-day values, and timestamp for values + containing both date and time. + + + + table + creating + + + + To create a table, you use the aptly named command. + In this command you specify at least a name for the new table, the + names of the columns and the data type of each column. For + example: + +CREATE TABLE my_first_table ( + first_column text, + second_column integer +); + + This creates a table named my_first_table with + two columns. The first column is named + first_column and has a data type of + text; the second column has the name + second_column and the type integer. + The table and column names follow the identifier syntax explained + in . The type names are + usually also identifiers, but there are some exceptions. Note that the + column list is comma-separated and surrounded by parentheses. + + + + Of course, the previous example was heavily contrived. Normally, + you would give names to your tables and columns that convey what + kind of data they store. So let's look at a more realistic + example: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric +); + + (The numeric type can store fractional components, as + would be typical of monetary amounts.) + + + + + When you create many interrelated tables it is wise to choose a + consistent naming pattern for the tables and columns. For + instance, there is a choice of using singular or plural nouns for + table names, both of which are favored by some theorist or other. + + + + + There is a limit on how many columns a table can contain. + Depending on the column types, it is between 250 and 1600. + However, defining a table with anywhere near this many columns is + highly unusual and often a questionable design. + + + + table + removing + + + + If you no longer need a table, you can remove it using the command. + For example: + +DROP TABLE my_first_table; +DROP TABLE products; + + Attempting to drop a table that does not exist is an error. + Nevertheless, it is common in SQL script files to unconditionally + try to drop each table before creating it, ignoring any error + messages, so that the script works whether or not the table exists. + (If you like, you can use the DROP TABLE IF EXISTS variant + to avoid the error messages, but this is not standard SQL.) + + + + If you need to modify a table that already exists, see later in this chapter. + + + + With the tools discussed so far you can create fully functional + tables. The remainder of this chapter is concerned with adding + features to the table definition to ensure data integrity, + security, or convenience. If you are eager to fill your tables with + data now you can skip ahead to and read the + rest of this chapter later. + + + + + Default Values + + + default value + + + + A column can be assigned a default value. When a new row is + created and no values are specified for some of the columns, those + columns will be filled with their respective default values. A + data manipulation command can also request explicitly that a column + be set to its default value, without having to know what that value is. + (Details about data manipulation commands are in .) + + + + null valuedefault value + If no default value is declared explicitly, the default value is the + null value. This usually makes sense because a null value can + be considered to represent unknown data. + + + + In a table definition, default values are listed after the column + data type. For example: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric DEFAULT 9.99 +); + + + + + The default value can be an expression, which will be + evaluated whenever the default value is inserted + (not when the table is created). A common example + is for a timestamp column to have a default of CURRENT_TIMESTAMP, + so that it gets set to the time of row insertion. Another common + example is generating a serial number for each row. + In PostgreSQL this is typically done by + something like: + +CREATE TABLE products ( + product_no integer DEFAULT nextval('products_product_no_seq'), + ... +); + + where the nextval() function supplies successive values + from a sequence object (see ). This arrangement is sufficiently common + that there's a special shorthand for it: + +CREATE TABLE products ( + product_no SERIAL, + ... +); + + The SERIAL shorthand is discussed further in . + + + + + Generated Columns + + + generated column + + + + A generated column is a special column that is always computed from other + columns. Thus, it is for columns what a view is for tables. There are two + kinds of generated columns: stored and virtual. A stored generated column + is computed when it is written (inserted or updated) and occupies storage + as if it were a normal column. A virtual generated column occupies no + storage and is computed when it is read. Thus, a virtual generated column + is similar to a view and a stored generated column is similar to a + materialized view (except that it is always updated automatically). + PostgreSQL currently implements only stored generated columns. + + + + To create a generated column, use the GENERATED ALWAYS + AS clause in CREATE TABLE, for example: + +CREATE TABLE people ( + ..., + height_cm numeric, + height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED +); + + The keyword STORED must be specified to choose the + stored kind of generated column. See for + more details. + + + + A generated column cannot be written to directly. In + INSERT or UPDATE commands, a value + cannot be specified for a generated column, but the keyword + DEFAULT may be specified. + + + + Consider the differences between a column with a default and a generated + column. The column default is evaluated once when the row is first + inserted if no other value was provided; a generated column is updated + whenever the row changes and cannot be overridden. A column default may + not refer to other columns of the table; a generation expression would + normally do so. A column default can use volatile functions, for example + random() or functions referring to the current time; + this is not allowed for generated columns. + + + + Several restrictions apply to the definition of generated columns and + tables involving generated columns: + + + + + The generation expression can only use immutable functions and cannot + use subqueries or reference anything other than the current row in any + way. + + + + + A generation expression cannot reference another generated column. + + + + + A generation expression cannot reference a system column, except + tableoid. + + + + + A generated column cannot have a column default or an identity definition. + + + + + A generated column cannot be part of a partition key. + + + + + Foreign tables can have generated columns. See for details. + + + + For inheritance: + + + + If a parent column is a generated column, a child column must also be + a generated column using the same expression. In the definition of + the child column, leave off the GENERATED clause, + as it will be copied from the parent. + + + + + In case of multiple inheritance, if one parent column is a generated + column, then all parent columns must be generated columns and with the + same expression. + + + + + If a parent column is not a generated column, a child column may be + defined to be a generated column or not. + + + + + + + + + Additional considerations apply to the use of generated columns. + + + + Generated columns maintain access privileges separately from their + underlying base columns. So, it is possible to arrange it so that a + particular role can read from a generated column but not from the + underlying base columns. + + + + + Generated columns are, conceptually, updated after + BEFORE triggers have run. Therefore, changes made to + base columns in a BEFORE trigger will be reflected in + generated columns. But conversely, it is not allowed to access + generated columns in BEFORE triggers. + + + + + + + + Constraints + + + constraint + + + + Data types are a way to limit the kind of data that can be stored + in a table. For many applications, however, the constraint they + provide is too coarse. For example, a column containing a product + price should probably only accept positive values. But there is no + standard data type that accepts only positive numbers. Another issue is + that you might want to constrain column data with respect to other + columns or rows. For example, in a table containing product + information, there should be only one row for each product number. + + + + To that end, SQL allows you to define constraints on columns and + tables. Constraints give you as much control over the data in your + tables as you wish. If a user attempts to store data in a column + that would violate a constraint, an error is raised. This applies + even if the value came from the default value definition. + + + + Check Constraints + + + check constraint + + + + constraint + check + + + + A check constraint is the most generic constraint type. It allows + you to specify that the value in a certain column must satisfy a + Boolean (truth-value) expression. For instance, to require positive + product prices, you could use: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric CHECK (price > 0) +); + + + + + As you see, the constraint definition comes after the data type, + just like default value definitions. Default values and + constraints can be listed in any order. A check constraint + consists of the key word CHECK followed by an + expression in parentheses. The check constraint expression should + involve the column thus constrained, otherwise the constraint + would not make too much sense. + + + + constraint + name + + + + You can also give the constraint a separate name. This clarifies + error messages and allows you to refer to the constraint when you + need to change it. The syntax is: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric CONSTRAINT positive_price CHECK (price > 0) +); + + So, to specify a named constraint, use the key word + CONSTRAINT followed by an identifier followed + by the constraint definition. (If you don't specify a constraint + name in this way, the system chooses a name for you.) + + + + A check constraint can also refer to several columns. Say you + store a regular price and a discounted price, and you want to + ensure that the discounted price is lower than the regular price: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric CHECK (price > 0), + discounted_price numeric CHECK (discounted_price > 0), + CHECK (price > discounted_price) +); + + + + + The first two constraints should look familiar. The third one + uses a new syntax. It is not attached to a particular column, + instead it appears as a separate item in the comma-separated + column list. Column definitions and these constraint + definitions can be listed in mixed order. + + + + We say that the first two constraints are column constraints, whereas the + third one is a table constraint because it is written separately + from any one column definition. Column constraints can also be + written as table constraints, while the reverse is not necessarily + possible, since a column constraint is supposed to refer to only the + column it is attached to. (PostgreSQL doesn't + enforce that rule, but you should follow it if you want your table + definitions to work with other database systems.) The above example could + also be written as: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric, + CHECK (price > 0), + discounted_price numeric, + CHECK (discounted_price > 0), + CHECK (price > discounted_price) +); + + or even: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric CHECK (price > 0), + discounted_price numeric, + CHECK (discounted_price > 0 AND price > discounted_price) +); + + It's a matter of taste. + + + + Names can be assigned to table constraints in the same way as + column constraints: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric, + CHECK (price > 0), + discounted_price numeric, + CHECK (discounted_price > 0), + CONSTRAINT valid_discount CHECK (price > discounted_price) +); + + + + + null value + with check constraints + + + + It should be noted that a check constraint is satisfied if the + check expression evaluates to true or the null value. Since most + expressions will evaluate to the null value if any operand is null, + they will not prevent null values in the constrained columns. To + ensure that a column does not contain null values, the not-null + constraint described in the next section can be used. + + + + + PostgreSQL does not support + CHECK constraints that reference table data other than + the new or updated row being checked. While a CHECK + constraint that violates this rule may appear to work in simple + tests, it cannot guarantee that the database will not reach a state + in which the constraint condition is false (due to subsequent changes + of the other row(s) involved). This would cause a database dump and + reload to fail. The reload could fail even when the complete + database state is consistent with the constraint, due to rows not + being loaded in an order that will satisfy the constraint. If + possible, use UNIQUE, EXCLUDE, + or FOREIGN KEY constraints to express + cross-row and cross-table restrictions. + + + + If what you desire is a one-time check against other rows at row + insertion, rather than a continuously-maintained consistency + guarantee, a custom trigger can be used + to implement that. (This approach avoids the dump/reload problem because + pg_dump does not reinstall triggers until after + reloading data, so that the check will not be enforced during a + dump/reload.) + + + + + + PostgreSQL assumes that + CHECK constraints' conditions are immutable, that + is, they will always give the same result for the same input row. + This assumption is what justifies examining CHECK + constraints only when rows are inserted or updated, and not at other + times. (The warning above about not referencing other table data is + really a special case of this restriction.) + + + + An example of a common way to break this assumption is to reference a + user-defined function in a CHECK expression, and + then change the behavior of that + function. PostgreSQL does not disallow + that, but it will not notice if there are rows in the table that now + violate the CHECK constraint. That would cause a + subsequent database dump and reload to fail. + The recommended way to handle such a change is to drop the constraint + (using ALTER TABLE), adjust the function definition, + and re-add the constraint, thereby rechecking it against all table rows. + + + + + + Not-Null Constraints + + + not-null constraint + + + + constraint + NOT NULL + + + + A not-null constraint simply specifies that a column must not + assume the null value. A syntax example: + +CREATE TABLE products ( + product_no integer NOT NULL, + name text NOT NULL, + price numeric +); + + + + + A not-null constraint is always written as a column constraint. A + not-null constraint is functionally equivalent to creating a check + constraint CHECK (column_name + IS NOT NULL), but in + PostgreSQL creating an explicit + not-null constraint is more efficient. The drawback is that you + cannot give explicit names to not-null constraints created this + way. + + + + Of course, a column can have more than one constraint. Just write + the constraints one after another: + +CREATE TABLE products ( + product_no integer NOT NULL, + name text NOT NULL, + price numeric NOT NULL CHECK (price > 0) +); + + The order doesn't matter. It does not necessarily determine in which + order the constraints are checked. + + + + The NOT NULL constraint has an inverse: the + NULL constraint. This does not mean that the + column must be null, which would surely be useless. Instead, this + simply selects the default behavior that the column might be null. + The NULL constraint is not present in the SQL + standard and should not be used in portable applications. (It was + only added to PostgreSQL to be + compatible with some other database systems.) Some users, however, + like it because it makes it easy to toggle the constraint in a + script file. For example, you could start with: + +CREATE TABLE products ( + product_no integer NULL, + name text NULL, + price numeric NULL +); + + and then insert the NOT key word where desired. + + + + + In most database designs the majority of columns should be marked + not null. + + + + + + Unique Constraints + + + unique constraint + + + + constraint + unique + + + + Unique constraints ensure that the data contained in a column, or a + group of columns, is unique among all the rows in the + table. The syntax is: + +CREATE TABLE products ( + product_no integer UNIQUE, + name text, + price numeric +); + + when written as a column constraint, and: + +CREATE TABLE products ( + product_no integer, + name text, + price numeric, + UNIQUE (product_no) +); + + when written as a table constraint. + + + + To define a unique constraint for a group of columns, write it as a + table constraint with the column names separated by commas: + +CREATE TABLE example ( + a integer, + b integer, + c integer, + UNIQUE (a, c) +); + + This specifies that the combination of values in the indicated columns + is unique across the whole table, though any one of the columns + need not be (and ordinarily isn't) unique. + + + + You can assign your own name for a unique constraint, in the usual way: + +CREATE TABLE products ( + product_no integer CONSTRAINT must_be_different UNIQUE, + name text, + price numeric +); + + + + + Adding a unique constraint will automatically create a unique B-tree + index on the column or group of columns listed in the constraint. + A uniqueness restriction covering only some rows cannot be written as + a unique constraint, but it is possible to enforce such a restriction by + creating a unique partial index. + + + + null value + with unique constraints + + + + In general, a unique constraint is violated if there is more than + one row in the table where the values of all of the + columns included in the constraint are equal. + However, two null values are never considered equal in this + comparison. That means even in the presence of a + unique constraint it is possible to store duplicate + rows that contain a null value in at least one of the constrained + columns. This behavior conforms to the SQL standard, but we have + heard that other SQL databases might not follow this rule. So be + careful when developing applications that are intended to be + portable. + + + + + Primary Keys + + + primary key + + + + constraint + primary key + + + + A primary key constraint indicates that a column, or group of columns, + can be used as a unique identifier for rows in the table. This + requires that the values be both unique and not null. So, the following + two table definitions accept the same data: + +CREATE TABLE products ( + product_no integer UNIQUE NOT NULL, + name text, + price numeric +); + + + +CREATE TABLE products ( + product_no integer PRIMARY KEY, + name text, + price numeric +); + + + + + Primary keys can span more than one column; the syntax + is similar to unique constraints: + +CREATE TABLE example ( + a integer, + b integer, + c integer, + PRIMARY KEY (a, c) +); + + + + + Adding a primary key will automatically create a unique B-tree index + on the column or group of columns listed in the primary key, and will + force the column(s) to be marked NOT NULL. + + + + A table can have at most one primary key. (There can be any number + of unique and not-null constraints, which are functionally almost the + same thing, but only one can be identified as the primary key.) + Relational database theory + dictates that every table must have a primary key. This rule is + not enforced by PostgreSQL, but it is + usually best to follow it. + + + + Primary keys are useful both for + documentation purposes and for client applications. For example, + a GUI application that allows modifying row values probably needs + to know the primary key of a table to be able to identify rows + uniquely. There are also various ways in which the database system + makes use of a primary key if one has been declared; for example, + the primary key defines the default target column(s) for foreign keys + referencing its table. + + + + + Foreign Keys + + + foreign key + + + + constraint + foreign key + + + + referential integrity + + + + A foreign key constraint specifies that the values in a column (or + a group of columns) must match the values appearing in some row + of another table. + We say this maintains the referential + integrity between two related tables. + + + + Say you have the product table that we have used several times already: + +CREATE TABLE products ( + product_no integer PRIMARY KEY, + name text, + price numeric +); + + Let's also assume you have a table storing orders of those + products. We want to ensure that the orders table only contains + orders of products that actually exist. So we define a foreign + key constraint in the orders table that references the products + table: + +CREATE TABLE orders ( + order_id integer PRIMARY KEY, + product_no integer REFERENCES products (product_no), + quantity integer +); + + Now it is impossible to create orders with non-NULL + product_no entries that do not appear in the + products table. + + + + We say that in this situation the orders table is the + referencing table and the products table is + the referenced table. Similarly, there are + referencing and referenced columns. + + + + You can also shorten the above command to: + +CREATE TABLE orders ( + order_id integer PRIMARY KEY, + product_no integer REFERENCES products, + quantity integer +); + + because in absence of a column list the primary key of the + referenced table is used as the referenced column(s). + + + + You can assign your own name for a foreign key constraint, + in the usual way. + + + + A foreign key can also constrain and reference a group of columns. + As usual, it then needs to be written in table constraint form. + Here is a contrived syntax example: + +CREATE TABLE t1 ( + a integer PRIMARY KEY, + b integer, + c integer, + FOREIGN KEY (b, c) REFERENCES other_table (c1, c2) +); + + Of course, the number and type of the constrained columns need to + match the number and type of the referenced columns. + + + + foreign key + self-referential + + + + Sometimes it is useful for the other table of a + foreign key constraint to be the same table; this is called + a self-referential foreign key. For + example, if you want rows of a table to represent nodes of a tree + structure, you could write + +CREATE TABLE tree ( + node_id integer PRIMARY KEY, + parent_id integer REFERENCES tree, + name text, + ... +); + + A top-level node would have NULL parent_id, + while non-NULL parent_id entries would be + constrained to reference valid rows of the table. + + + + A table can have more than one foreign key constraint. This is + used to implement many-to-many relationships between tables. Say + you have tables about products and orders, but now you want to + allow one order to contain possibly many products (which the + structure above did not allow). You could use this table structure: + +CREATE TABLE products ( + product_no integer PRIMARY KEY, + name text, + price numeric +); + +CREATE TABLE orders ( + order_id integer PRIMARY KEY, + shipping_address text, + ... +); + +CREATE TABLE order_items ( + product_no integer REFERENCES products, + order_id integer REFERENCES orders, + quantity integer, + PRIMARY KEY (product_no, order_id) +); + + Notice that the primary key overlaps with the foreign keys in + the last table. + + + + CASCADE + foreign key action + + + + RESTRICT + foreign key action + + + + We know that the foreign keys disallow creation of orders that + do not relate to any products. But what if a product is removed + after an order is created that references it? SQL allows you to + handle that as well. Intuitively, we have a few options: + + Disallow deleting a referenced product + Delete the orders as well + Something else? + + + + + To illustrate this, let's implement the following policy on the + many-to-many relationship example above: when someone wants to + remove a product that is still referenced by an order (via + order_items), we disallow it. If someone + removes an order, the order items are removed as well: + +CREATE TABLE products ( + product_no integer PRIMARY KEY, + name text, + price numeric +); + +CREATE TABLE orders ( + order_id integer PRIMARY KEY, + shipping_address text, + ... +); + +CREATE TABLE order_items ( + product_no integer REFERENCES products ON DELETE RESTRICT, + order_id integer REFERENCES orders ON DELETE CASCADE, + quantity integer, + PRIMARY KEY (product_no, order_id) +); + + + + + Restricting and cascading deletes are the two most common options. + RESTRICT prevents deletion of a + referenced row. NO ACTION means that if any + referencing rows still exist when the constraint is checked, an error + is raised; this is the default behavior if you do not specify anything. + (The essential difference between these two choices is that + NO ACTION allows the check to be deferred until + later in the transaction, whereas RESTRICT does not.) + CASCADE specifies that when a referenced row is deleted, + row(s) referencing it should be automatically deleted as well. + There are two other options: + SET NULL and SET DEFAULT. + These cause the referencing column(s) in the referencing row(s) + to be set to nulls or their default + values, respectively, when the referenced row is deleted. + Note that these do not excuse you from observing any constraints. + For example, if an action specifies SET DEFAULT + but the default value would not satisfy the foreign key constraint, the + operation will fail. + + + + Analogous to ON DELETE there is also + ON UPDATE which is invoked when a referenced + column is changed (updated). The possible actions are the same. + In this case, CASCADE means that the updated values of the + referenced column(s) should be copied into the referencing row(s). + + + + Normally, a referencing row need not satisfy the foreign key constraint + if any of its referencing columns are null. If MATCH FULL + is added to the foreign key declaration, a referencing row escapes + satisfying the constraint only if all its referencing columns are null + (so a mix of null and non-null values is guaranteed to fail a + MATCH FULL constraint). If you don't want referencing rows + to be able to avoid satisfying the foreign key constraint, declare the + referencing column(s) as NOT NULL. + + + + A foreign key must reference columns that either are a primary key or + form a unique constraint. This means that the referenced columns always + have an index (the one underlying the primary key or unique constraint); + so checks on whether a referencing row has a match will be efficient. + Since a DELETE of a row from the referenced table + or an UPDATE of a referenced column will require + a scan of the referencing table for rows matching the old value, it + is often a good idea to index the referencing columns too. Because this + is not always needed, and there are many choices available on how + to index, declaration of a foreign key constraint does not + automatically create an index on the referencing columns. + + + + More information about updating and deleting data is in . Also see the description of foreign key constraint + syntax in the reference documentation for + . + + + + + Exclusion Constraints + + + exclusion constraint + + + + constraint + exclusion + + + + Exclusion constraints ensure that if any two rows are compared on + the specified columns or expressions using the specified operators, + at least one of these operator comparisons will return false or null. + The syntax is: + +CREATE TABLE circles ( + c circle, + EXCLUDE USING gist (c WITH &&) +); + + + + + See also CREATE + TABLE ... CONSTRAINT ... EXCLUDE for details. + + + + Adding an exclusion constraint will automatically create an index + of the type specified in the constraint declaration. + + + + + + System Columns + + + Every table has several system columns that are + implicitly defined by the system. Therefore, these names cannot be + used as names of user-defined columns. (Note that these + restrictions are separate from whether the name is a key word or + not; quoting a name will not allow you to escape these + restrictions.) You do not really need to be concerned about these + columns; just know they exist. + + + + column + system column + + + + + tableoid + + + tableoid + + + + The OID of the table containing this row. This column is + particularly handy for queries that select from partitioned + tables (see ) or inheritance + hierarchies (see ), since without it, + it's difficult to tell which individual table a row came from. The + tableoid can be joined against the + oid column of + pg_class to obtain the table name. + + + + + + xmin + + + xmin + + + + The identity (transaction ID) of the inserting transaction for + this row version. (A row version is an individual state of a + row; each update of a row creates a new row version for the same + logical row.) + + + + + + cmin + + + cmin + + + + The command identifier (starting at zero) within the inserting + transaction. + + + + + + xmax + + + xmax + + + + The identity (transaction ID) of the deleting transaction, or + zero for an undeleted row version. It is possible for this column to + be nonzero in a visible row version. That usually indicates that the + deleting transaction hasn't committed yet, or that an attempted + deletion was rolled back. + + + + + + cmax + + + cmax + + + + The command identifier within the deleting transaction, or zero. + + + + + + ctid + + + ctid + + + + The physical location of the row version within its table. Note that + although the ctid can be used to + locate the row version very quickly, a row's + ctid will change if it is + updated or moved by VACUUM FULL. Therefore + ctid is useless as a long-term row + identifier. A primary key should be used to identify logical rows. + + + + + + + Transaction identifiers are also 32-bit quantities. In a + long-lived database it is possible for transaction IDs to wrap + around. This is not a fatal problem given appropriate maintenance + procedures; see for details. It is + unwise, however, to depend on the uniqueness of transaction IDs + over the long term (more than one billion transactions). + + + + Command identifiers are also 32-bit quantities. This creates a hard limit + of 232 (4 billion) SQL commands + within a single transaction. In practice this limit is not a + problem — note that the limit is on the number of + SQL commands, not the number of rows processed. + Also, only commands that actually modify the database contents will + consume a command identifier. + + + + + Modifying Tables + + + table + modifying + + + + When you create a table and you realize that you made a mistake, or + the requirements of the application change, you can drop the + table and create it again. But this is not a convenient option if + the table is already filled with data, or if the table is + referenced by other database objects (for instance a foreign key + constraint). Therefore PostgreSQL + provides a family of commands to make modifications to existing + tables. Note that this is conceptually distinct from altering + the data contained in the table: here we are interested in altering + the definition, or structure, of the table. + + + + You can: + + + Add columns + + + Remove columns + + + Add constraints + + + Remove constraints + + + Change default values + + + Change column data types + + + Rename columns + + + Rename tables + + + + All these actions are performed using the + + command, whose reference page contains details beyond those given + here. + + + + Adding a Column + + + column + adding + + + + To add a column, use a command like: + +ALTER TABLE products ADD COLUMN description text; + + The new column is initially filled with whatever default + value is given (null if you don't specify a DEFAULT clause). + + + + + From PostgreSQL 11, adding a column with + a constant default value no longer means that each row of the table + needs to be updated when the ALTER TABLE statement + is executed. Instead, the default value will be returned the next time + the row is accessed, and applied when the table is rewritten, making + the ALTER TABLE very fast even on large tables. + + + + However, if the default value is volatile (e.g., + clock_timestamp()) + each row will need to be updated with the value calculated at the time + ALTER TABLE is executed. To avoid a potentially + lengthy update operation, particularly if you intend to fill the column + with mostly nondefault values anyway, it may be preferable to add the + column with no default, insert the correct values using + UPDATE, and then add any desired default as described + below. + + + + + You can also define constraints on the column at the same time, + using the usual syntax: + +ALTER TABLE products ADD COLUMN description text CHECK (description <> ''); + + In fact all the options that can be applied to a column description + in CREATE TABLE can be used here. Keep in mind however + that the default value must satisfy the given constraints, or the + ADD will fail. Alternatively, you can add + constraints later (see below) after you've filled in the new column + correctly. + + + + + + Removing a Column + + + column + removing + + + + To remove a column, use a command like: + +ALTER TABLE products DROP COLUMN description; + + Whatever data was in the column disappears. Table constraints involving + the column are dropped, too. However, if the column is referenced by a + foreign key constraint of another table, + PostgreSQL will not silently drop that + constraint. You can authorize dropping everything that depends on + the column by adding CASCADE: + +ALTER TABLE products DROP COLUMN description CASCADE; + + See for a description of the general + mechanism behind this. + + + + + Adding a Constraint + + + constraint + adding + + + + To add a constraint, the table constraint syntax is used. For example: + +ALTER TABLE products ADD CHECK (name <> ''); +ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no); +ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups; + + To add a not-null constraint, which cannot be written as a table + constraint, use this syntax: + +ALTER TABLE products ALTER COLUMN product_no SET NOT NULL; + + + + + The constraint will be checked immediately, so the table data must + satisfy the constraint before it can be added. + + + + + Removing a Constraint + + + constraint + removing + + + + To remove a constraint you need to know its name. If you gave it + a name then that's easy. Otherwise the system assigned a + generated name, which you need to find out. The + psql command \d + tablename can be helpful + here; other interfaces might also provide a way to inspect table + details. Then the command is: + +ALTER TABLE products DROP CONSTRAINT some_name; + + (If you are dealing with a generated constraint name like $2, + don't forget that you'll need to double-quote it to make it a valid + identifier.) + + + + As with dropping a column, you need to add CASCADE if you + want to drop a constraint that something else depends on. An example + is that a foreign key constraint depends on a unique or primary key + constraint on the referenced column(s). + + + + This works the same for all constraint types except not-null + constraints. To drop a not null constraint use: + +ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL; + + (Recall that not-null constraints do not have names.) + + + + + Changing a Column's Default Value + + + default value + changing + + + + To set a new default for a column, use a command like: + +ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77; + + Note that this doesn't affect any existing rows in the table, it + just changes the default for future INSERT commands. + + + + To remove any default value, use: + +ALTER TABLE products ALTER COLUMN price DROP DEFAULT; + + This is effectively the same as setting the default to null. + As a consequence, it is not an error + to drop a default where one hadn't been defined, because the + default is implicitly the null value. + + + + + Changing a Column's Data Type + + + column data type + changing + + + + To convert a column to a different data type, use a command like: + +ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2); + + This will succeed only if each existing entry in the column can be + converted to the new type by an implicit cast. If a more complex + conversion is needed, you can add a USING clause that + specifies how to compute the new values from the old. + + + + PostgreSQL will attempt to convert the column's + default value (if any) to the new type, as well as any constraints + that involve the column. But these conversions might fail, or might + produce surprising results. It's often best to drop any constraints + on the column before altering its type, and then add back suitably + modified constraints afterwards. + + + + + Renaming a Column + + + column + renaming + + + + To rename a column: + +ALTER TABLE products RENAME COLUMN product_no TO product_number; + + + + + + Renaming a Table + + + table + renaming + + + + To rename a table: + +ALTER TABLE products RENAME TO items; + + + + + + + Privileges + + + privilege + + + + permission + privilege + + + + owner + + + + GRANT + + + + REVOKE + + + + ACL + + + + When an object is created, it is assigned an owner. The + owner is normally the role that executed the creation statement. + For most kinds of objects, the initial state is that only the owner + (or a superuser) can do anything with the object. To allow + other roles to use it, privileges must be + granted. + + + + There are different kinds of privileges: SELECT, + INSERT, UPDATE, DELETE, + TRUNCATE, REFERENCES, TRIGGER, + CREATE, CONNECT, TEMPORARY, + EXECUTE, and USAGE. + The privileges applicable to a particular + object vary depending on the object's type (table, function, etc). + More detail about the meanings of these privileges appears below. + The following sections and chapters will also show you how + these privileges are used. + + + + The right to modify or destroy an object is inherent in being the + object's owner, and cannot be granted or revoked in itself. + (However, like all privileges, that right can be inherited by + members of the owning role; see .) + + + + An object can be assigned to a new owner with an ALTER + command of the appropriate kind for the object, for example + +ALTER TABLE table_name OWNER TO new_owner; + + Superusers can always do this; ordinary roles can only do it if they are + both the current owner of the object (or a member of the owning role) and + a member of the new owning role. + + + + To assign privileges, the command is + used. For example, if joe is an existing role, and + accounts is an existing table, the privilege to + update the table can be granted with: + +GRANT UPDATE ON accounts TO joe; + + Writing ALL in place of a specific privilege grants all + privileges that are relevant for the object type. + + + + The special role name PUBLIC can + be used to grant a privilege to every role on the system. Also, + group roles can be set up to help manage privileges when + there are many users of a database — for details see + . + + + + To revoke a previously-granted privilege, use the fittingly named + command: + +REVOKE ALL ON accounts FROM PUBLIC; + + + + + Ordinarily, only the object's owner (or a superuser) can grant or + revoke privileges on an object. However, it is possible to grant a + privilege with grant option, which gives the recipient + the right to grant it in turn to others. If the grant option is + subsequently revoked then all who received the privilege from that + recipient (directly or through a chain of grants) will lose the + privilege. For details see the and + reference pages. + + + + An object's owner can choose to revoke their own ordinary privileges, + for example to make a table read-only for themselves as well as others. + But owners are always treated as holding all grant options, so they + can always re-grant their own privileges. + + + + The available privileges are: + + + + SELECT + + + Allows SELECT from + any column, or specific column(s), of a table, view, materialized + view, or other table-like object. + Also allows use of COPY TO. + This privilege is also needed to reference existing column values in + UPDATE or DELETE. + For sequences, this privilege also allows use of the + currval function. + For large objects, this privilege allows the object to be read. + + + + + + INSERT + + + Allows INSERT of a new row into a table, view, + etc. Can be granted on specific column(s), in which case + only those columns may be assigned to in the INSERT + command (other columns will therefore receive default values). + Also allows use of COPY FROM. + + + + + + UPDATE + + + Allows UPDATE of any + column, or specific column(s), of a table, view, etc. + (In practice, any nontrivial UPDATE command will + require SELECT privilege as well, since it must + reference table columns to determine which rows to update, and/or to + compute new values for columns.) + SELECT ... FOR UPDATE + and SELECT ... FOR SHARE + also require this privilege on at least one column, in addition to the + SELECT privilege. For sequences, this + privilege allows use of the nextval and + setval functions. + For large objects, this privilege allows writing or truncating the + object. + + + + + + DELETE + + + Allows DELETE of a row from a table, view, etc. + (In practice, any nontrivial DELETE command will + require SELECT privilege as well, since it must + reference table columns to determine which rows to delete.) + + + + + + TRUNCATE + + + Allows TRUNCATE on a table. + + + + + + REFERENCES + + + Allows creation of a foreign key constraint referencing a + table, or specific column(s) of a table. + + + + + + TRIGGER + + + Allows creation of a trigger on a table, view, etc. + + + + + + CREATE + + + For databases, allows new schemas and publications to be created within + the database, and allows trusted extensions to be installed within + the database. + + + For schemas, allows new objects to be created within the schema. + To rename an existing object, you must own the + object and have this privilege for the containing + schema. + + + For tablespaces, allows tables, indexes, and temporary files to be + created within the tablespace, and allows databases to be created that + have the tablespace as their default tablespace. + + + Note that revoking this privilege will not alter the existence or + location of existing objects. + + + + + + CONNECT + + + Allows the grantee to connect to the database. This + privilege is checked at connection startup (in addition to checking + any restrictions imposed by pg_hba.conf). + + + + + + TEMPORARY + + + Allows temporary tables to be created while using the database. + + + + + + EXECUTE + + + Allows calling a function or procedure, including use of + any operators that are implemented on top of the function. This is the + only type of privilege that is applicable to functions and procedures. + + + + + + USAGE + + + For procedural languages, allows use of the language for + the creation of functions in that language. This is the only type + of privilege that is applicable to procedural languages. + + + For schemas, allows access to objects contained in the + schema (assuming that the objects' own privilege requirements are + also met). Essentially this allows the grantee to look up + objects within the schema. Without this permission, it is still + possible to see the object names, e.g., by querying system catalogs. + Also, after revoking this permission, existing sessions might have + statements that have previously performed this lookup, so this is not + a completely secure way to prevent object access. + + + For sequences, allows use of the + currval and nextval functions. + + + For types and domains, allows use of the type or domain in the + creation of tables, functions, and other schema objects. (Note that + this privilege does not control all usage of the + type, such as values of the type appearing in queries. It only + prevents objects from being created that depend on the type. The + main purpose of this privilege is controlling which users can create + dependencies on a type, which could prevent the owner from changing + the type later.) + + + For foreign-data wrappers, allows creation of new servers using the + foreign-data wrapper. + + + For foreign servers, allows creation of foreign tables using the + server. Grantees may also create, alter, or drop their own user + mappings associated with that server. + + + + + + The privileges required by other commands are listed on the + reference page of the respective command. + + + + PostgreSQL grants privileges on some types of objects to + PUBLIC by default when the objects are created. + No privileges are granted to PUBLIC by default on + tables, + table columns, + sequences, + foreign data wrappers, + foreign servers, + large objects, + schemas, + or tablespaces. + For other types of objects, the default privileges + granted to PUBLIC are as follows: + CONNECT and TEMPORARY (create + temporary tables) privileges for databases; + EXECUTE privilege for functions and procedures; and + USAGE privilege for languages and data types + (including domains). + The object owner can, of course, REVOKE + both default and expressly granted privileges. (For maximum + security, issue the REVOKE in the same transaction that + creates the object; then there is no window in which another user + can use the object.) + Also, these default privilege settings can be overridden using the + command. + + + + shows the one-letter + abbreviations that are used for these privilege types in + ACL (Access Control List) values. + You will see these letters in the output of the + commands listed below, or when looking at ACL columns of system catalogs. + + + + ACL Privilege Abbreviations + + + + + + + Privilege + Abbreviation + Applicable Object Types + + + + + SELECT + r (read) + + LARGE OBJECT, + SEQUENCE, + TABLE (and table-like objects), + table column + + + + INSERT + a (append) + TABLE, table column + + + UPDATE + w (write) + + LARGE OBJECT, + SEQUENCE, + TABLE, + table column + + + + DELETE + d + TABLE + + + TRUNCATE + D + TABLE + + + REFERENCES + x + TABLE, table column + + + TRIGGER + t + TABLE + + + CREATE + C + + DATABASE, + SCHEMA, + TABLESPACE + + + + CONNECT + c + DATABASE + + + TEMPORARY + T + DATABASE + + + EXECUTE + X + FUNCTION, PROCEDURE + + + USAGE + U + + DOMAIN, + FOREIGN DATA WRAPPER, + FOREIGN SERVER, + LANGUAGE, + SCHEMA, + SEQUENCE, + TYPE + + + + +
+ + + summarizes the privileges + available for each type of SQL object, using the abbreviations shown + above. + It also shows the psql command + that can be used to examine privilege settings for each object type. + + + + Summary of Access Privileges + + + + + + + + Object Type + All Privileges + Default PUBLIC Privileges + psql Command + + + + + DATABASE + CTc + Tc + \l + + + DOMAIN + U + U + \dD+ + + + FUNCTION or PROCEDURE + X + X + \df+ + + + FOREIGN DATA WRAPPER + U + none + \dew+ + + + FOREIGN SERVER + U + none + \des+ + + + LANGUAGE + U + U + \dL+ + + + LARGE OBJECT + rw + none + + + + SCHEMA + UC + none + \dn+ + + + SEQUENCE + rwU + none + \dp + + + TABLE (and table-like objects) + arwdDxt + none + \dp + + + Table column + arwx + none + \dp + + + TABLESPACE + C + none + \db+ + + + TYPE + U + U + \dT+ + + + +
+ + + + aclitem + + The privileges that have been granted for a particular object are + displayed as a list of aclitem entries, where each + aclitem describes the permissions of one grantee that + have been granted by a particular grantor. For example, + calvin=r*w/hobbes specifies that the role + calvin has the privilege + SELECT (r) with grant option + (*) as well as the non-grantable + privilege UPDATE (w), both granted + by the role hobbes. If calvin + also has some privileges on the same object granted by a different + grantor, those would appear as a separate aclitem entry. + An empty grantee field in an aclitem stands + for PUBLIC. + + + + As an example, suppose that user miriam creates + table mytable and does: + +GRANT SELECT ON mytable TO PUBLIC; +GRANT SELECT, UPDATE, INSERT ON mytable TO admin; +GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw; + + Then psql's \dp command + would show: + +=> \dp mytable + Access privileges + Schema | Name | Type | Access privileges | Column privileges | Policies +--------+---------+-------+-----------------------+-----------------------+---------- + public | mytable | table | miriam=arwdDxt/miriam+| col1: +| + | | | =r/miriam +| miriam_rw=rw/miriam | + | | | admin=arw/miriam | | +(1 row) + + + + + If the Access privileges column is empty for a given + object, it means the object has default privileges (that is, its + privileges entry in the relevant system catalog is null). Default + privileges always include all privileges for the owner, and can include + some privileges for PUBLIC depending on the object + type, as explained above. The first GRANT + or REVOKE on an object will instantiate the default + privileges (producing, for + example, miriam=arwdDxt/miriam) and then modify them + per the specified request. Similarly, entries are shown in Column + privileges only for columns with nondefault privileges. + (Note: for this purpose, default privileges always means + the built-in default privileges for the object's type. An object whose + privileges have been affected by an ALTER DEFAULT + PRIVILEGES command will always be shown with an explicit + privilege entry that includes the effects of + the ALTER.) + + + + Notice that the owner's implicit grant options are not marked in the + access privileges display. A * will appear only when + grant options have been explicitly granted to someone. + +
+ + + Row Security Policies + + + row-level security + + + + policy + + + + In addition to the SQL-standard privilege + system available through , + tables can have row security policies that restrict, + on a per-user basis, which rows can be returned by normal queries + or inserted, updated, or deleted by data modification commands. + This feature is also known as Row-Level Security. + By default, tables do not have any policies, so that if a user has + access privileges to a table according to the SQL privilege system, + all rows within it are equally available for querying or updating. + + + + When row security is enabled on a table (with + ALTER TABLE ... ENABLE ROW LEVEL + SECURITY), all normal access to the table for selecting rows or + modifying rows must be allowed by a row security policy. (However, the + table's owner is typically not subject to row security policies.) If no + policy exists for the table, a default-deny policy is used, meaning that + no rows are visible or can be modified. Operations that apply to the + whole table, such as TRUNCATE and REFERENCES, + are not subject to row security. + + + + Row security policies can be specific to commands, or to roles, or to + both. A policy can be specified to apply to ALL + commands, or to SELECT, INSERT, UPDATE, + or DELETE. Multiple roles can be assigned to a given + policy, and normal role membership and inheritance rules apply. + + + + To specify which rows are visible or modifiable according to a policy, + an expression is required that returns a Boolean result. This + expression will be evaluated for each row prior to any conditions or + functions coming from the user's query. (The only exceptions to this + rule are leakproof functions, which are guaranteed to + not leak information; the optimizer may choose to apply such functions + ahead of the row-security check.) Rows for which the expression does + not return true will not be processed. Separate expressions + may be specified to provide independent control over the rows which are + visible and the rows which are allowed to be modified. Policy + expressions are run as part of the query and with the privileges of the + user running the query, although security-definer functions can be used + to access data not available to the calling user. + + + + Superusers and roles with the BYPASSRLS attribute always + bypass the row security system when accessing a table. Table owners + normally bypass row security as well, though a table owner can choose to + be subject to row security with ALTER + TABLE ... FORCE ROW LEVEL SECURITY. + + + + Enabling and disabling row security, as well as adding policies to a + table, is always the privilege of the table owner only. + + + + Policies are created using the + command, altered using the command, + and dropped using the command. To + enable and disable row security for a given table, use the + command. + + + + Each policy has a name and multiple policies can be defined for a + table. As policies are table-specific, each policy for a table must + have a unique name. Different tables may have policies with the + same name. + + + + When multiple policies apply to a given query, they are combined using + either OR (for permissive policies, which are the + default) or using AND (for restrictive policies). + This is similar to the rule that a given role has the privileges + of all roles that they are a member of. Permissive vs. restrictive + policies are discussed further below. + + + + As a simple example, here is how to create a policy on + the account relation to allow only members of + the managers role to access rows, and only rows of their + accounts: + + + +CREATE TABLE accounts (manager text, company text, contact_email text); + +ALTER TABLE accounts ENABLE ROW LEVEL SECURITY; + +CREATE POLICY account_managers ON accounts TO managers + USING (manager = current_user); + + + + The policy above implicitly provides a WITH CHECK + clause identical to its USING clause, so that the + constraint applies both to rows selected by a command (so a manager + cannot SELECT, UPDATE, + or DELETE existing rows belonging to a different + manager) and to rows modified by a command (so rows belonging to a + different manager cannot be created via INSERT + or UPDATE). + + + + If no role is specified, or the special user name + PUBLIC is used, then the policy applies to all + users on the system. To allow all users to access only their own row in + a users table, a simple policy can be used: + + + +CREATE POLICY user_policy ON users + USING (user_name = current_user); + + + + This works similarly to the previous example. + + + + To use a different policy for rows that are being added to the table + compared to those rows that are visible, multiple policies can be + combined. This pair of policies would allow all users to view all rows + in the users table, but only modify their own: + + + +CREATE POLICY user_sel_policy ON users + FOR SELECT + USING (true); +CREATE POLICY user_mod_policy ON users + USING (user_name = current_user); + + + + In a SELECT command, these two policies are combined + using OR, with the net effect being that all rows + can be selected. In other command types, only the second policy applies, + so that the effects are the same as before. + + + + Row security can also be disabled with the ALTER TABLE + command. Disabling row security does not remove any policies that are + defined on the table; they are simply ignored. Then all rows in the + table are visible and modifiable, subject to the standard SQL privileges + system. + + + + Below is a larger example of how this feature can be used in production + environments. The table passwd emulates a Unix password + file: + + + +-- Simple passwd-file based example +CREATE TABLE passwd ( + user_name text UNIQUE NOT NULL, + pwhash text, + uid int PRIMARY KEY, + gid int NOT NULL, + real_name text NOT NULL, + home_phone text, + extra_info text, + home_dir text NOT NULL, + shell text NOT NULL +); + +CREATE ROLE admin; -- Administrator +CREATE ROLE bob; -- Normal user +CREATE ROLE alice; -- Normal user + +-- Populate the table +INSERT INTO passwd VALUES + ('admin','xxx',0,0,'Admin','111-222-3333',null,'/root','/bin/dash'); +INSERT INTO passwd VALUES + ('bob','xxx',1,1,'Bob','123-456-7890',null,'/home/bob','/bin/zsh'); +INSERT INTO passwd VALUES + ('alice','xxx',2,1,'Alice','098-765-4321',null,'/home/alice','/bin/zsh'); + +-- Be sure to enable row-level security on the table +ALTER TABLE passwd ENABLE ROW LEVEL SECURITY; + +-- Create policies +-- Administrator can see all rows and add any rows +CREATE POLICY admin_all ON passwd TO admin USING (true) WITH CHECK (true); +-- Normal users can view all rows +CREATE POLICY all_view ON passwd FOR SELECT USING (true); +-- Normal users can update their own records, but +-- limit which shells a normal user is allowed to set +CREATE POLICY user_mod ON passwd FOR UPDATE + USING (current_user = user_name) + WITH CHECK ( + current_user = user_name AND + shell IN ('/bin/bash','/bin/sh','/bin/dash','/bin/zsh','/bin/tcsh') + ); + +-- Allow admin all normal rights +GRANT SELECT, INSERT, UPDATE, DELETE ON passwd TO admin; +-- Users only get select access on public columns +GRANT SELECT + (user_name, uid, gid, real_name, home_phone, extra_info, home_dir, shell) + ON passwd TO public; +-- Allow users to update certain columns +GRANT UPDATE + (pwhash, real_name, home_phone, extra_info, shell) + ON passwd TO public; + + + + As with any security settings, it's important to test and ensure that + the system is behaving as expected. Using the example above, this + demonstrates that the permission system is working properly. + + + +-- admin can view all rows and fields +postgres=> set role admin; +SET +postgres=> table passwd; + user_name | pwhash | uid | gid | real_name | home_phone | extra_info | home_dir | shell +-----------+--------+-----+-----+-----------+--------------+------------+-------------+----------- + admin | xxx | 0 | 0 | Admin | 111-222-3333 | | /root | /bin/dash + bob | xxx | 1 | 1 | Bob | 123-456-7890 | | /home/bob | /bin/zsh + alice | xxx | 2 | 1 | Alice | 098-765-4321 | | /home/alice | /bin/zsh +(3 rows) + +-- Test what Alice is able to do +postgres=> set role alice; +SET +postgres=> table passwd; +ERROR: permission denied for relation passwd +postgres=> select user_name,real_name,home_phone,extra_info,home_dir,shell from passwd; + user_name | real_name | home_phone | extra_info | home_dir | shell +-----------+-----------+--------------+------------+-------------+----------- + admin | Admin | 111-222-3333 | | /root | /bin/dash + bob | Bob | 123-456-7890 | | /home/bob | /bin/zsh + alice | Alice | 098-765-4321 | | /home/alice | /bin/zsh +(3 rows) + +postgres=> update passwd set user_name = 'joe'; +ERROR: permission denied for relation passwd +-- Alice is allowed to change her own real_name, but no others +postgres=> update passwd set real_name = 'Alice Doe'; +UPDATE 1 +postgres=> update passwd set real_name = 'John Doe' where user_name = 'admin'; +UPDATE 0 +postgres=> update passwd set shell = '/bin/xx'; +ERROR: new row violates WITH CHECK OPTION for "passwd" +postgres=> delete from passwd; +ERROR: permission denied for relation passwd +postgres=> insert into passwd (user_name) values ('xxx'); +ERROR: permission denied for relation passwd +-- Alice can change her own password; RLS silently prevents updating other rows +postgres=> update passwd set pwhash = 'abc'; +UPDATE 1 + + + + All of the policies constructed thus far have been permissive policies, + meaning that when multiple policies are applied they are combined using + the OR Boolean operator. While permissive policies can be constructed + to only allow access to rows in the intended cases, it can be simpler to + combine permissive policies with restrictive policies (which the records + must pass and which are combined using the AND Boolean operator). + Building on the example above, we add a restrictive policy to require + the administrator to be connected over a local Unix socket to access the + records of the passwd table: + + + +CREATE POLICY admin_local_only ON passwd AS RESTRICTIVE TO admin + USING (pg_catalog.inet_client_addr() IS NULL); + + + + We can then see that an administrator connecting over a network will not + see any records, due to the restrictive policy: + + + +=> SELECT current_user; + current_user +-------------- + admin +(1 row) + +=> select inet_client_addr(); + inet_client_addr +------------------ + 127.0.0.1 +(1 row) + +=> TABLE passwd; + user_name | pwhash | uid | gid | real_name | home_phone | extra_info | home_dir | shell +-----------+--------+-----+-----+-----------+------------+------------+----------+------- +(0 rows) + +=> UPDATE passwd set pwhash = NULL; +UPDATE 0 + + + + Referential integrity checks, such as unique or primary key constraints + and foreign key references, always bypass row security to ensure that + data integrity is maintained. Care must be taken when developing + schemas and row level policies to avoid covert channel leaks of + information through such referential integrity checks. + + + + In some contexts it is important to be sure that row security is + not being applied. For example, when taking a backup, it could be + disastrous if row security silently caused some rows to be omitted + from the backup. In such a situation, you can set the + configuration parameter + to off. This does not in itself bypass row security; + what it does is throw an error if any query's results would get filtered + by a policy. The reason for the error can then be investigated and + fixed. + + + + In the examples above, the policy expressions consider only the current + values in the row to be accessed or updated. This is the simplest and + best-performing case; when possible, it's best to design row security + applications to work this way. If it is necessary to consult other rows + or other tables to make a policy decision, that can be accomplished using + sub-SELECTs, or functions that contain SELECTs, + in the policy expressions. Be aware however that such accesses can + create race conditions that could allow information leakage if care is + not taken. As an example, consider the following table design: + + + +-- definition of privilege groups +CREATE TABLE groups (group_id int PRIMARY KEY, + group_name text NOT NULL); + +INSERT INTO groups VALUES + (1, 'low'), + (2, 'medium'), + (5, 'high'); + +GRANT ALL ON groups TO alice; -- alice is the administrator +GRANT SELECT ON groups TO public; + +-- definition of users' privilege levels +CREATE TABLE users (user_name text PRIMARY KEY, + group_id int NOT NULL REFERENCES groups); + +INSERT INTO users VALUES + ('alice', 5), + ('bob', 2), + ('mallory', 2); + +GRANT ALL ON users TO alice; +GRANT SELECT ON users TO public; + +-- table holding the information to be protected +CREATE TABLE information (info text, + group_id int NOT NULL REFERENCES groups); + +INSERT INTO information VALUES + ('barely secret', 1), + ('slightly secret', 2), + ('very secret', 5); + +ALTER TABLE information ENABLE ROW LEVEL SECURITY; + +-- a row should be visible to/updatable by users whose security group_id is +-- greater than or equal to the row's group_id +CREATE POLICY fp_s ON information FOR SELECT + USING (group_id <= (SELECT group_id FROM users WHERE user_name = current_user)); +CREATE POLICY fp_u ON information FOR UPDATE + USING (group_id <= (SELECT group_id FROM users WHERE user_name = current_user)); + +-- we rely only on RLS to protect the information table +GRANT ALL ON information TO public; + + + + Now suppose that alice wishes to change the slightly + secret information, but decides that mallory should not + be trusted with the new content of that row, so she does: + + + +BEGIN; +UPDATE users SET group_id = 1 WHERE user_name = 'mallory'; +UPDATE information SET info = 'secret from mallory' WHERE group_id = 2; +COMMIT; + + + + That looks safe; there is no window wherein mallory should be + able to see the secret from mallory string. However, there is + a race condition here. If mallory is concurrently doing, + say, + +SELECT * FROM information WHERE group_id = 2 FOR UPDATE; + + and her transaction is in READ COMMITTED mode, it is possible + for her to see secret from mallory. That happens if her + transaction reaches the information row just + after alice's does. It blocks waiting + for alice's transaction to commit, then fetches the updated + row contents thanks to the FOR UPDATE clause. However, it + does not fetch an updated row for the + implicit SELECT from users, because that + sub-SELECT did not have FOR UPDATE; instead + the users row is read with the snapshot taken at the start + of the query. Therefore, the policy expression tests the old value + of mallory's privilege level and allows her to see the + updated row. + + + + There are several ways around this problem. One simple answer is to use + SELECT ... FOR SHARE in sub-SELECTs in row + security policies. However, that requires granting UPDATE + privilege on the referenced table (here users) to the + affected users, which might be undesirable. (But another row security + policy could be applied to prevent them from actually exercising that + privilege; or the sub-SELECT could be embedded into a security + definer function.) Also, heavy concurrent use of row share locks on the + referenced table could pose a performance problem, especially if updates + of it are frequent. Another solution, practical if updates of the + referenced table are infrequent, is to take an + ACCESS EXCLUSIVE lock on the + referenced table when updating it, so that no concurrent transactions + could be examining old row values. Or one could just wait for all + concurrent transactions to end after committing an update of the + referenced table and before making changes that rely on the new security + situation. + + + + For additional details see + and . + + + + + + Schemas + + + schema + + + + A PostgreSQL database cluster contains + one or more named databases. Roles and a few other object types are + shared across the entire cluster. A client connection to the server + can only access data in a single database, the one specified in the + connection request. + + + + + Users of a cluster do not necessarily have the privilege to access every + database in the cluster. Sharing of role names means that there + cannot be different roles named, say, joe in two databases + in the same cluster; but the system can be configured to allow + joe access to only some of the databases. + + + + + A database contains one or more named schemas, which + in turn contain tables. Schemas also contain other kinds of named + objects, including data types, functions, and operators. The same + object name can be used in different schemas without conflict; for + example, both schema1 and myschema can + contain tables named mytable. Unlike databases, + schemas are not rigidly separated: a user can access objects in any + of the schemas in the database they are connected to, if they have + privileges to do so. + + + + There are several reasons why one might want to use schemas: + + + + + To allow many users to use one database without interfering with + each other. + + + + + + To organize database objects into logical groups to make them + more manageable. + + + + + + Third-party applications can be put into separate schemas so + they do not collide with the names of other objects. + + + + + Schemas are analogous to directories at the operating system level, + except that schemas cannot be nested. + + + + Creating a Schema + + + schema + creating + + + + To create a schema, use the + command. Give the schema a name + of your choice. For example: + +CREATE SCHEMA myschema; + + + + + qualified name + + + + name + qualified + + + + To create or access objects in a schema, write a + qualified name consisting of the schema name and + table name separated by a dot: + +schema.table + + This works anywhere a table name is expected, including the table + modification commands and the data access commands discussed in + the following chapters. + (For brevity we will speak of tables only, but the same ideas apply + to other kinds of named objects, such as types and functions.) + + + + Actually, the even more general syntax + +database.schema.table + + can be used too, but at present this is just for pro forma + compliance with the SQL standard. If you write a database name, + it must be the same as the database you are connected to. + + + + So to create a table in the new schema, use: + +CREATE TABLE myschema.mytable ( + ... +); + + + + + schema + removing + + + + To drop a schema if it's empty (all objects in it have been + dropped), use: + +DROP SCHEMA myschema; + + To drop a schema including all contained objects, use: + +DROP SCHEMA myschema CASCADE; + + See for a description of the general + mechanism behind this. + + + + Often you will want to create a schema owned by someone else + (since this is one of the ways to restrict the activities of your + users to well-defined namespaces). The syntax for that is: + +CREATE SCHEMA schema_name AUTHORIZATION user_name; + + You can even omit the schema name, in which case the schema name + will be the same as the user name. See for how this can be useful. + + + + Schema names beginning with pg_ are reserved for + system purposes and cannot be created by users. + + + + + The Public Schema + + + schema + public + + + + In the previous sections we created tables without specifying any + schema names. By default such tables (and other objects) are + automatically put into a schema named public. Every new + database contains such a schema. Thus, the following are equivalent: + +CREATE TABLE products ( ... ); + + and: + +CREATE TABLE public.products ( ... ); + + + + + + The Schema Search Path + + + search path + + + + unqualified name + + + + name + unqualified + + + + Qualified names are tedious to write, and it's often best not to + wire a particular schema name into applications anyway. Therefore + tables are often referred to by unqualified names, + which consist of just the table name. The system determines which table + is meant by following a search path, which is a list + of schemas to look in. The first matching table in the search path + is taken to be the one wanted. If there is no match in the search + path, an error is reported, even if matching table names exist + in other schemas in the database. + + + + The ability to create like-named objects in different schemas complicates + writing a query that references precisely the same objects every time. It + also opens up the potential for users to change the behavior of other + users' queries, maliciously or accidentally. Due to the prevalence of + unqualified names in queries and their use + in PostgreSQL internals, adding a schema + to search_path effectively trusts all users having + CREATE privilege on that schema. When you run an + ordinary query, a malicious user able to create objects in a schema of + your search path can take control and execute arbitrary SQL functions as + though you executed them. + + + + schema + current + + + + The first schema named in the search path is called the current schema. + Aside from being the first schema searched, it is also the schema in + which new tables will be created if the CREATE TABLE + command does not specify a schema name. + + + + search_path configuration parameter + + + + To show the current search path, use the following command: + +SHOW search_path; + + In the default setup this returns: + + search_path +-------------- + "$user", public + + The first element specifies that a schema with the same name as + the current user is to be searched. If no such schema exists, + the entry is ignored. The second element refers to the + public schema that we have seen already. + + + + The first schema in the search path that exists is the default + location for creating new objects. That is the reason that by + default objects are created in the public schema. When objects + are referenced in any other context without schema qualification + (table modification, data modification, or query commands) the + search path is traversed until a matching object is found. + Therefore, in the default configuration, any unqualified access + again can only refer to the public schema. + + + + To put our new schema in the path, we use: + +SET search_path TO myschema,public; + + (We omit the $user here because we have no + immediate need for it.) And then we can access the table without + schema qualification: + +DROP TABLE mytable; + + Also, since myschema is the first element in + the path, new objects would by default be created in it. + + + + We could also have written: + +SET search_path TO myschema; + + Then we no longer have access to the public schema without + explicit qualification. There is nothing special about the public + schema except that it exists by default. It can be dropped, too. + + + + See also for other ways to manipulate + the schema search path. + + + + The search path works in the same way for data type names, function names, + and operator names as it does for table names. Data type and function + names can be qualified in exactly the same way as table names. If you + need to write a qualified operator name in an expression, there is a + special provision: you must write + +OPERATOR(schema.operator) + + This is needed to avoid syntactic ambiguity. An example is: + +SELECT 3 OPERATOR(pg_catalog.+) 4; + + In practice one usually relies on the search path for operators, + so as not to have to write anything so ugly as that. + + + + + Schemas and Privileges + + + privilege + for schemas + + + + By default, users cannot access any objects in schemas they do not + own. To allow that, the owner of the schema must grant the + USAGE privilege on the schema. To allow users + to make use of the objects in the schema, additional privileges + might need to be granted, as appropriate for the object. + + + + A user can also be allowed to create objects in someone else's + schema. To allow that, the CREATE privilege on + the schema needs to be granted. Note that by default, everyone + has CREATE and USAGE privileges on + the schema + public. This allows all users that are able to + connect to a given database to create objects in its + public schema. + Some usage patterns call for + revoking that privilege: + +REVOKE CREATE ON SCHEMA public FROM PUBLIC; + + (The first public is the schema, the second + public means every user. In the + first sense it is an identifier, in the second sense it is a + key word, hence the different capitalization; recall the + guidelines from .) + + + + + The System Catalog Schema + + + system catalog + schema + + + + In addition to public and user-created schemas, each + database contains a pg_catalog schema, which contains + the system tables and all the built-in data types, functions, and + operators. pg_catalog is always effectively part of + the search path. If it is not named explicitly in the path then + it is implicitly searched before searching the path's + schemas. This ensures that built-in names will always be + findable. However, you can explicitly place + pg_catalog at the end of your search path if you + prefer to have user-defined names override built-in names. + + + + Since system table names begin with pg_, it is best to + avoid such names to ensure that you won't suffer a conflict if some + future version defines a system table named the same as your + table. (With the default search path, an unqualified reference to + your table name would then be resolved as the system table instead.) + System tables will continue to follow the convention of having + names beginning with pg_, so that they will not + conflict with unqualified user-table names so long as users avoid + the pg_ prefix. + + + + + Usage Patterns + + + Schemas can be used to organize your data in many ways. + A secure schema usage pattern prevents untrusted + users from changing the behavior of other users' queries. When a database + does not use a secure schema usage pattern, users wishing to securely + query that database would take protective action at the beginning of each + session. Specifically, they would begin each session by + setting search_path to the empty string or otherwise + removing non-superuser-writable schemas + from search_path. There are a few usage patterns + easily supported by the default configuration: + + + + + Constrain ordinary users to user-private schemas. To implement this, + issue REVOKE CREATE ON SCHEMA public FROM PUBLIC, + and create a schema for each user with the same name as that user. + Recall that the default search path starts + with $user, which resolves to the user name. + Therefore, if each user has a separate schema, they access their own + schemas by default. After adopting this pattern in a database where + untrusted users had already logged in, consider auditing the public + schema for objects named like objects in + schema pg_catalog. This pattern is a secure schema + usage pattern unless an untrusted user is the database owner or holds + the CREATEROLE privilege, in which case no secure + schema usage pattern exists. + + + + + + + + Remove the public schema from the default search path, by modifying + postgresql.conf + or by issuing ALTER ROLE ALL SET search_path = + "$user". Everyone retains the ability to create objects in + the public schema, but only qualified names will choose those objects. + While qualified table references are fine, calls to functions in the + public schema will be unsafe or + unreliable. If you create functions or extensions in the public + schema, use the first pattern instead. Otherwise, like the first + pattern, this is secure unless an untrusted user is the database owner + or holds the CREATEROLE privilege. + + + + + + Keep the default. All users access the public schema implicitly. This + simulates the situation where schemas are not available at all, giving + a smooth transition from the non-schema-aware world. However, this is + never a secure pattern. It is acceptable only when the database has a + single user or a few mutually-trusting users. + + + + + + + For any pattern, to install shared applications (tables to be used by + everyone, additional functions provided by third parties, etc.), put them + into separate schemas. Remember to grant appropriate privileges to allow + the other users to access them. Users can then refer to these additional + objects by qualifying the names with a schema name, or they can put the + additional schemas into their search path, as they choose. + + + + + Portability + + + In the SQL standard, the notion of objects in the same schema + being owned by different users does not exist. Moreover, some + implementations do not allow you to create schemas that have a + different name than their owner. In fact, the concepts of schema + and user are nearly equivalent in a database system that + implements only the basic schema support specified in the + standard. Therefore, many users consider qualified names to + really consist of + user_name.table_name. + This is how PostgreSQL will effectively + behave if you create a per-user schema for every user. + + + + Also, there is no concept of a public schema in the + SQL standard. For maximum conformance to the standard, you should + not use the public schema. + + + + Of course, some SQL database systems might not implement schemas + at all, or provide namespace support by allowing (possibly + limited) cross-database access. If you need to work with those + systems, then maximum portability would be achieved by not using + schemas at all. + + + + + + Inheritance + + + inheritance + + + + table + inheritance + + + + PostgreSQL implements table inheritance, + which can be a useful tool for database designers. (SQL:1999 and + later define a type inheritance feature, which differs in many + respects from the features described here.) + + + + Let's start with an example: suppose we are trying to build a data + model for cities. Each state has many cities, but only one + capital. We want to be able to quickly retrieve the capital city + for any particular state. This can be done by creating two tables, + one for state capitals and one for cities that are not + capitals. However, what happens when we want to ask for data about + a city, regardless of whether it is a capital or not? The + inheritance feature can help to resolve this problem. We define the + capitals table so that it inherits from + cities: + + +CREATE TABLE cities ( + name text, + population float, + elevation int -- in feet +); + +CREATE TABLE capitals ( + state char(2) +) INHERITS (cities); + + + In this case, the capitals table inherits + all the columns of its parent table, cities. State + capitals also have an extra column, state, that shows + their state. + + + + In PostgreSQL, a table can inherit from + zero or more other tables, and a query can reference either all + rows of a table or all rows of a table plus all of its descendant tables. + The latter behavior is the default. + For example, the following query finds the names of all cities, + including state capitals, that are located at an elevation over + 500 feet: + + +SELECT name, elevation + FROM cities + WHERE elevation > 500; + + + Given the sample data from the PostgreSQL + tutorial (see ), this returns: + + + name | elevation +-----------+----------- + Las Vegas | 2174 + Mariposa | 1953 + Madison | 845 + + + + + On the other hand, the following query finds all the cities that + are not state capitals and are situated at an elevation over 500 feet: + + +SELECT name, elevation + FROM ONLY cities + WHERE elevation > 500; + + name | elevation +-----------+----------- + Las Vegas | 2174 + Mariposa | 1953 + + + + + Here the ONLY keyword indicates that the query + should apply only to cities, and not any tables + below cities in the inheritance hierarchy. Many + of the commands that we have already discussed — + SELECT, UPDATE and + DELETE — support the + ONLY keyword. + + + + You can also write the table name with a trailing * + to explicitly specify that descendant tables are included: + + +SELECT name, elevation + FROM cities* + WHERE elevation > 500; + + + Writing * is not necessary, since this behavior is always + the default. However, this syntax is still supported for + compatibility with older releases where the default could be changed. + + + + In some cases you might wish to know which table a particular row + originated from. There is a system column called + tableoid in each table which can tell you the + originating table: + + +SELECT c.tableoid, c.name, c.elevation +FROM cities c +WHERE c.elevation > 500; + + + which returns: + + + tableoid | name | elevation +----------+-----------+----------- + 139793 | Las Vegas | 2174 + 139793 | Mariposa | 1953 + 139798 | Madison | 845 + + + (If you try to reproduce this example, you will probably get + different numeric OIDs.) By doing a join with + pg_class you can see the actual table names: + + +SELECT p.relname, c.name, c.elevation +FROM cities c, pg_class p +WHERE c.elevation > 500 AND c.tableoid = p.oid; + + + which returns: + + + relname | name | elevation +----------+-----------+----------- + cities | Las Vegas | 2174 + cities | Mariposa | 1953 + capitals | Madison | 845 + + + + + Another way to get the same effect is to use the regclass + alias type, which will print the table OID symbolically: + + +SELECT c.tableoid::regclass, c.name, c.elevation +FROM cities c +WHERE c.elevation > 500; + + + + + Inheritance does not automatically propagate data from + INSERT or COPY commands to + other tables in the inheritance hierarchy. In our example, the + following INSERT statement will fail: + +INSERT INTO cities (name, population, elevation, state) +VALUES ('Albany', NULL, NULL, 'NY'); + + We might hope that the data would somehow be routed to the + capitals table, but this does not happen: + INSERT always inserts into exactly the table + specified. In some cases it is possible to redirect the insertion + using a rule (see ). However that does not + help for the above case because the cities table + does not contain the column state, and so the + command will be rejected before the rule can be applied. + + + + All check constraints and not-null constraints on a parent table are + automatically inherited by its children, unless explicitly specified + otherwise with NO INHERIT clauses. Other types of constraints + (unique, primary key, and foreign key constraints) are not inherited. + + + + A table can inherit from more than one parent table, in which case it has + the union of the columns defined by the parent tables. Any columns + declared in the child table's definition are added to these. If the + same column name appears in multiple parent tables, or in both a parent + table and the child's definition, then these columns are merged + so that there is only one such column in the child table. To be merged, + columns must have the same data types, else an error is raised. + Inheritable check constraints and not-null constraints are merged in a + similar fashion. Thus, for example, a merged column will be marked + not-null if any one of the column definitions it came from is marked + not-null. Check constraints are merged if they have the same name, + and the merge will fail if their conditions are different. + + + + Table inheritance is typically established when the child table is + created, using the INHERITS clause of the + CREATE TABLE + statement. + Alternatively, a table which is already defined in a compatible way can + have a new parent relationship added, using the INHERIT + variant of ALTER TABLE. + To do this the new child table must already include columns with + the same names and types as the columns of the parent. It must also include + check constraints with the same names and check expressions as those of the + parent. Similarly an inheritance link can be removed from a child using the + NO INHERIT variant of ALTER TABLE. + Dynamically adding and removing inheritance links like this can be useful + when the inheritance relationship is being used for table + partitioning (see ). + + + + One convenient way to create a compatible table that will later be made + a new child is to use the LIKE clause in CREATE + TABLE. This creates a new table with the same columns as + the source table. If there are any CHECK + constraints defined on the source table, the INCLUDING + CONSTRAINTS option to LIKE should be + specified, as the new child must have constraints matching the parent + to be considered compatible. + + + + A parent table cannot be dropped while any of its children remain. Neither + can columns or check constraints of child tables be dropped or altered + if they are inherited + from any parent tables. If you wish to remove a table and all of its + descendants, one easy way is to drop the parent table with the + CASCADE option (see ). + + + + ALTER TABLE will + propagate any changes in column data definitions and check + constraints down the inheritance hierarchy. Again, dropping + columns that are depended on by other tables is only possible when using + the CASCADE option. ALTER + TABLE follows the same rules for duplicate column merging + and rejection that apply during CREATE TABLE. + + + + Inherited queries perform access permission checks on the parent table + only. Thus, for example, granting UPDATE permission on + the cities table implies permission to update rows in + the capitals table as well, when they are + accessed through cities. This preserves the appearance + that the data is (also) in the parent table. But + the capitals table could not be updated directly + without an additional grant. In a similar way, the parent table's row + security policies (see ) are applied to + rows coming from child tables during an inherited query. A child table's + policies, if any, are applied only when it is the table explicitly named + in the query; and in that case, any policies attached to its parent(s) are + ignored. + + + + Foreign tables (see ) can also + be part of inheritance hierarchies, either as parent or child + tables, just as regular tables can be. If a foreign table is part + of an inheritance hierarchy then any operations not supported by + the foreign table are not supported on the whole hierarchy either. + + + + Caveats + + + Note that not all SQL commands are able to work on + inheritance hierarchies. Commands that are used for data querying, + data modification, or schema modification + (e.g., SELECT, UPDATE, DELETE, + most variants of ALTER TABLE, but + not INSERT or ALTER TABLE ... + RENAME) typically default to including child tables and + support the ONLY notation to exclude them. + Commands that do database maintenance and tuning + (e.g., REINDEX, VACUUM) + typically only work on individual, physical tables and do not + support recursing over inheritance hierarchies. The respective + behavior of each individual command is documented in its reference + page (). + + + + A serious limitation of the inheritance feature is that indexes (including + unique constraints) and foreign key constraints only apply to single + tables, not to their inheritance children. This is true on both the + referencing and referenced sides of a foreign key constraint. Thus, + in the terms of the above example: + + + + + If we declared cities.name to be + UNIQUE or a PRIMARY KEY, this would not stop the + capitals table from having rows with names duplicating + rows in cities. And those duplicate rows would by + default show up in queries from cities. In fact, by + default capitals would have no unique constraint at all, + and so could contain multiple rows with the same name. + You could add a unique constraint to capitals, but this + would not prevent duplication compared to cities. + + + + + + Similarly, if we were to specify that + cities.name REFERENCES some + other table, this constraint would not automatically propagate to + capitals. In this case you could work around it by + manually adding the same REFERENCES constraint to + capitals. + + + + + + Specifying that another table's column REFERENCES + cities(name) would allow the other table to contain city names, but + not capital names. There is no good workaround for this case. + + + + + Some functionality not implemented for inheritance hierarchies is + implemented for declarative partitioning. + Considerable care is needed in deciding whether partitioning with legacy + inheritance is useful for your application. + + + + + + + Table Partitioning + + + partitioning + + + + table + partitioning + + + + partitioned table + + + + PostgreSQL supports basic table + partitioning. This section describes why and how to implement + partitioning as part of your database design. + + + + Overview + + + Partitioning refers to splitting what is logically one large table into + smaller physical pieces. Partitioning can provide several benefits: + + + + Query performance can be improved dramatically in certain situations, + particularly when most of the heavily accessed rows of the table are in a + single partition or a small number of partitions. Partitioning + effectively substitutes for the upper tree levels of indexes, + making it more likely that the heavily-used parts of the indexes + fit in memory. + + + + + + When queries or updates access a large percentage of a single + partition, performance can be improved by using a + sequential scan of that partition instead of using an + index, which would require random-access reads scattered across the + whole table. + + + + + + Bulk loads and deletes can be accomplished by adding or removing + partitions, if the usage pattern is accounted for in the + partitioning design. Dropping an individual partition + using DROP TABLE, or doing ALTER TABLE + DETACH PARTITION, is far faster than a bulk + operation. These commands also entirely avoid the + VACUUM overhead caused by a bulk DELETE. + + + + + + Seldom-used data can be migrated to cheaper and slower storage media. + + + + + These benefits will normally be worthwhile only when a table would + otherwise be very large. The exact point at which a table will + benefit from partitioning depends on the application, although a + rule of thumb is that the size of the table should exceed the physical + memory of the database server. + + + + PostgreSQL offers built-in support for the + following forms of partitioning: + + + + Range Partitioning + + + + The table is partitioned into ranges defined + by a key column or set of columns, with no overlap between + the ranges of values assigned to different partitions. For + example, one might partition by date ranges, or by ranges of + identifiers for particular business objects. + Each range's bounds are understood as being inclusive at the + lower end and exclusive at the upper end. For example, if one + partition's range is from 1 + to 10, and the next one's range is + from 10 to 20, then + value 10 belongs to the second partition not + the first. + + + + + + List Partitioning + + + + The table is partitioned by explicitly listing which key value(s) + appear in each partition. + + + + + + Hash Partitioning + + + + The table is partitioned by specifying a modulus and a remainder for + each partition. Each partition will hold the rows for which the hash + value of the partition key divided by the specified modulus will + produce the specified remainder. + + + + + + If your application needs to use other forms of partitioning not listed + above, alternative methods such as inheritance and + UNION ALL views can be used instead. Such methods + offer flexibility but do not have some of the performance benefits + of built-in declarative partitioning. + + + + + Declarative Partitioning + + + PostgreSQL allows you to declare + that a table is divided into partitions. The table that is divided + is referred to as a partitioned table. The + declaration includes the partitioning method + as described above, plus a list of columns or expressions to be used + as the partition key. + + + + The partitioned table itself is a virtual table having + no storage of its own. Instead, the storage belongs + to partitions, which are otherwise-ordinary + tables associated with the partitioned table. + Each partition stores a subset of the data as defined by its + partition bounds. + All rows inserted into a partitioned table will be routed to the + appropriate one of the partitions based on the values of the partition + key column(s). + Updating the partition key of a row will cause it to be moved into a + different partition if it no longer satisfies the partition bounds + of its original partition. + + + + Partitions may themselves be defined as partitioned tables, resulting + in sub-partitioning. Although all partitions + must have the same columns as their partitioned parent, partitions may + have their + own indexes, constraints and default values, distinct from those of other + partitions. See for more details on + creating partitioned tables and partitions. + + + + It is not possible to turn a regular table into a partitioned table or + vice versa. However, it is possible to add an existing regular or + partitioned table as a partition of a partitioned table, or remove a + partition from a partitioned table turning it into a standalone table; + this can simplify and speed up many maintenance processes. + See to learn more about the + ATTACH PARTITION and DETACH PARTITION + sub-commands. + + + + Partitions can also be foreign tables, although they have some limitations + that normal tables do not; see for + more information. + + + + Example + + + Suppose we are constructing a database for a large ice cream company. + The company measures peak temperatures every day as well as ice cream + sales in each region. Conceptually, we want a table like: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + + + We know that most queries will access just the last week's, month's or + quarter's data, since the main use of this table will be to prepare + online reports for management. To reduce the amount of old data that + needs to be stored, we decide to keep only the most recent 3 years + worth of data. At the beginning of each month we will remove the oldest + month's data. In this situation we can use partitioning to help us meet + all of our different requirements for the measurements table. + + + + To use declarative partitioning in this case, use the following steps: + + + + + Create the measurement table as a partitioned + table by specifying the PARTITION BY clause, which + includes the partitioning method (RANGE in this + case) and the list of column(s) to use as the partition key. + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +) PARTITION BY RANGE (logdate); + + + + + + + Create partitions. Each partition's definition must specify bounds + that correspond to the partitioning method and partition key of the + parent. Note that specifying bounds such that the new partition's + values would overlap with those in one or more existing partitions will + cause an error. + + + + Partitions thus created are in every way normal + PostgreSQL + tables (or, possibly, foreign tables). It is possible to specify a + tablespace and storage parameters for each partition separately. + + + + For our example, each partition should hold one month's worth of + data, to match the requirement of deleting one month's data at a + time. So the commands might look like: + + +CREATE TABLE measurement_y2006m02 PARTITION OF measurement + FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'); + +CREATE TABLE measurement_y2006m03 PARTITION OF measurement + FOR VALUES FROM ('2006-03-01') TO ('2006-04-01'); + +... +CREATE TABLE measurement_y2007m11 PARTITION OF measurement + FOR VALUES FROM ('2007-11-01') TO ('2007-12-01'); + +CREATE TABLE measurement_y2007m12 PARTITION OF measurement + FOR VALUES FROM ('2007-12-01') TO ('2008-01-01') + TABLESPACE fasttablespace; + +CREATE TABLE measurement_y2008m01 PARTITION OF measurement + FOR VALUES FROM ('2008-01-01') TO ('2008-02-01') + WITH (parallel_workers = 4) + TABLESPACE fasttablespace; + + + (Recall that adjacent partitions can share a bound value, since + range upper bounds are treated as exclusive bounds.) + + + + If you wish to implement sub-partitioning, again specify the + PARTITION BY clause in the commands used to create + individual partitions, for example: + + +CREATE TABLE measurement_y2006m02 PARTITION OF measurement + FOR VALUES FROM ('2006-02-01') TO ('2006-03-01') + PARTITION BY RANGE (peaktemp); + + + After creating partitions of measurement_y2006m02, + any data inserted into measurement that is mapped to + measurement_y2006m02 (or data that is + directly inserted into measurement_y2006m02, + which is allowed provided its partition constraint is satisfied) + will be further redirected to one of its + partitions based on the peaktemp column. The partition + key specified may overlap with the parent's partition key, although + care should be taken when specifying the bounds of a sub-partition + such that the set of data it accepts constitutes a subset of what + the partition's own bounds allow; the system does not try to check + whether that's really the case. + + + + Inserting data into the parent table that does not map + to one of the existing partitions will cause an error; an appropriate + partition must be added manually. + + + + It is not necessary to manually create table constraints describing + the partition boundary conditions for partitions. Such constraints + will be created automatically. + + + + + + Create an index on the key column(s), as well as any other indexes you + might want, on the partitioned table. (The key index is not strictly + necessary, but in most scenarios it is helpful.) + This automatically creates a matching index on each partition, and + any partitions you create or attach later will also have such an + index. + An index or unique constraint declared on a partitioned table + is virtual in the same way that the partitioned table + is: the actual data is in child indexes on the individual partition + tables. + + +CREATE INDEX ON measurement (logdate); + + + + + + + Ensure that the + configuration parameter is not disabled in postgresql.conf. + If it is, queries will not be optimized as desired. + + + + + + + In the above example we would be creating a new partition each month, so + it might be wise to write a script that generates the required DDL + automatically. + + + + + Partition Maintenance + + + Normally the set of partitions established when initially defining the + table is not intended to remain static. It is common to want to + remove partitions holding old data and periodically add new partitions for + new data. One of the most important advantages of partitioning is + precisely that it allows this otherwise painful task to be executed + nearly instantaneously by manipulating the partition structure, rather + than physically moving large amounts of data around. + + + + The simplest option for removing old data is to drop the partition that + is no longer necessary: + +DROP TABLE measurement_y2006m02; + + This can very quickly delete millions of records because it doesn't have + to individually delete every record. Note however that the above command + requires taking an ACCESS EXCLUSIVE lock on the parent + table. + + + + Another option that is often preferable is to remove the partition from + the partitioned table but retain access to it as a table in its own + right. This has two forms: + + +ALTER TABLE measurement DETACH PARTITION measurement_y2006m02; +ALTER TABLE measurement DETACH PARTITION measurement_y2006m02 CONCURRENTLY; + + + These allow further operations to be performed on the data before + it is dropped. For example, this is often a useful time to back up + the data using COPY, pg_dump, or + similar tools. It might also be a useful time to aggregate data + into smaller formats, perform other data manipulations, or run + reports. The first form of the command requires an + ACCESS EXCLUSIVE lock on the parent table. + Adding the CONCURRENTLY qualifier as in the second + form allows the detach operation to require only + SHARE UPDATE EXCLUSIVE lock on the parent table, but see + ALTER TABLE ... DETACH PARTITION + for details on the restrictions. + + + + Similarly we can add a new partition to handle new data. We can create an + empty partition in the partitioned table just as the original partitions + were created above: + + +CREATE TABLE measurement_y2008m02 PARTITION OF measurement + FOR VALUES FROM ('2008-02-01') TO ('2008-03-01') + TABLESPACE fasttablespace; + + + As an alternative, it is sometimes more convenient to create the + new table outside the partition structure, and make it a proper + partition later. This allows new data to be loaded, checked, and + transformed prior to it appearing in the partitioned table. + The CREATE TABLE ... LIKE option is helpful + to avoid tediously repeating the parent table's definition: + + +CREATE TABLE measurement_y2008m02 + (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS) + TABLESPACE fasttablespace; + +ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02 + CHECK ( logdate >= DATE '2008-02-01' AND logdate < DATE '2008-03-01' ); + +\copy measurement_y2008m02 from 'measurement_y2008m02' +-- possibly some other data preparation work + +ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 + FOR VALUES FROM ('2008-02-01') TO ('2008-03-01' ); + + + + + Before running the ATTACH PARTITION command, it is + recommended to create a CHECK constraint on the table to + be attached that matches the expected partition constraint, as + illustrated above. That way, the system will be able to skip the scan + which is otherwise needed to validate the implicit + partition constraint. Without the CHECK constraint, + the table will be scanned to validate the partition constraint while + holding both an ACCESS EXCLUSIVE lock on that partition + and a SHARE UPDATE EXCLUSIVE lock on the parent table. + It is recommended to drop the now-redundant CHECK + constraint after ATTACH PARTITION is finished. + + + + As explained above, it is possible to create indexes on partitioned tables + so that they are applied automatically to the entire hierarchy. + This is very + convenient, as not only will the existing partitions become indexed, but + also any partitions that are created in the future will. One limitation is + that it's not possible to use the CONCURRENTLY + qualifier when creating such a partitioned index. To avoid long lock + times, it is possible to use CREATE INDEX ON ONLY + the partitioned table; such an index is marked invalid, and the partitions + do not get the index applied automatically. The indexes on partitions can + be created individually using CONCURRENTLY, and then + attached to the index on the parent using + ALTER INDEX .. ATTACH PARTITION. Once indexes for all + partitions are attached to the parent index, the parent index is marked + valid automatically. Example: + +CREATE INDEX measurement_usls_idx ON ONLY measurement (unitsales); + +CREATE INDEX measurement_usls_200602_idx + ON measurement_y2006m02 (unitsales); +ALTER INDEX measurement_usls_idx + ATTACH PARTITION measurement_usls_200602_idx; +... + + + This technique can be used with UNIQUE and + PRIMARY KEY constraints too; the indexes are created + implicitly when the constraint is created. Example: + +ALTER TABLE ONLY measurement ADD UNIQUE (city_id, logdate); + +ALTER TABLE measurement_y2006m02 ADD UNIQUE (city_id, logdate); +ALTER INDEX measurement_city_id_logdate_key + ATTACH PARTITION measurement_y2006m02_city_id_logdate_key; +... + + + + + + Limitations + + + The following limitations apply to partitioned tables: + + + + Unique constraints (and hence primary keys) on partitioned tables must + include all the partition key columns. This limitation exists because + the individual indexes making up the constraint can only directly + enforce uniqueness within their own partitions; therefore, the + partition structure itself must guarantee that there are not + duplicates in different partitions. + + + + + + There is no way to create an exclusion constraint spanning the + whole partitioned table. It is only possible to put such a + constraint on each leaf partition individually. Again, this + limitation stems from not being able to enforce cross-partition + restrictions. + + + + + + BEFORE ROW triggers on INSERT + cannot change which partition is the final destination for a new row. + + + + + + Mixing temporary and permanent relations in the same partition tree is + not allowed. Hence, if the partitioned table is permanent, so must be + its partitions and likewise if the partitioned table is temporary. When + using temporary relations, all members of the partition tree have to be + from the same session. + + + + + + + Individual partitions are linked to their partitioned table using + inheritance behind-the-scenes. However, it is not possible to use + all of the generic features of inheritance with declaratively + partitioned tables or their partitions, as discussed below. Notably, + a partition cannot have any parents other than the partitioned table + it is a partition of, nor can a table inherit from both a partitioned + table and a regular table. That means partitioned tables and their + partitions never share an inheritance hierarchy with regular tables. + + + + Since a partition hierarchy consisting of the partitioned table and its + partitions is still an inheritance hierarchy, all the normal rules of + inheritance apply as described in , with + a few exceptions: + + + + + Partitions cannot have columns that are not present in the parent. It + is not possible to specify columns when creating partitions with + CREATE TABLE, nor is it possible to add columns to + partitions after-the-fact using ALTER TABLE. + Tables may be added as a partition with ALTER TABLE + ... ATTACH PARTITION only if their columns exactly match + the parent. + + + + + + Both CHECK and NOT NULL + constraints of a partitioned table are always inherited by all its + partitions. CHECK constraints that are marked + NO INHERIT are not allowed to be created on + partitioned tables. + You cannot drop a NOT NULL constraint on a + partition's column if the same constraint is present in the parent + table. + + + + + + Using ONLY to add or drop a constraint on only + the partitioned table is supported as long as there are no + partitions. Once partitions exist, using ONLY + will result in an error. Instead, constraints on the partitions + themselves can be added and (if they are not present in the parent + table) dropped. + + + + + + As a partitioned table does not have any data itself, attempts to use + TRUNCATE ONLY on a partitioned + table will always return an error. + + + + + + + + + Partitioning Using Inheritance + + + While the built-in declarative partitioning is suitable for most + common use cases, there are some circumstances where a more flexible + approach may be useful. Partitioning can be implemented using table + inheritance, which allows for several features not supported + by declarative partitioning, such as: + + + + + For declarative partitioning, partitions must have exactly the same set + of columns as the partitioned table, whereas with table inheritance, + child tables may have extra columns not present in the parent. + + + + + + Table inheritance allows for multiple inheritance. + + + + + + Declarative partitioning only supports range, list and hash + partitioning, whereas table inheritance allows data to be divided in a + manner of the user's choosing. (Note, however, that if constraint + exclusion is unable to prune child tables effectively, query performance + might be poor.) + + + + + + + Example + + + This example builds a partitioning structure equivalent to the + declarative partitioning example above. Use + the following steps: + + + + + Create the root table, from which all of the + child tables will inherit. This table will contain no data. Do not + define any check constraints on this table, unless you intend them + to be applied equally to all child tables. There is no point in + defining any indexes or unique constraints on it, either. For our + example, the root table is the measurement + table as originally defined: + + +CREATE TABLE measurement ( + city_id int not null, + logdate date not null, + peaktemp int, + unitsales int +); + + + + + + + Create several child tables that each inherit from + the root table. Normally, these tables will not add any columns + to the set inherited from the root. Just as with declarative + partitioning, these tables are in every way normal + PostgreSQL tables (or foreign tables). + + + + +CREATE TABLE measurement_y2006m02 () INHERITS (measurement); +CREATE TABLE measurement_y2006m03 () INHERITS (measurement); +... +CREATE TABLE measurement_y2007m11 () INHERITS (measurement); +CREATE TABLE measurement_y2007m12 () INHERITS (measurement); +CREATE TABLE measurement_y2008m01 () INHERITS (measurement); + + + + + + + Add non-overlapping table constraints to the child tables to + define the allowed key values in each. + + + + Typical examples would be: + +CHECK ( x = 1 ) +CHECK ( county IN ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire' )) +CHECK ( outletID >= 100 AND outletID < 200 ) + + Ensure that the constraints guarantee that there is no overlap + between the key values permitted in different child tables. A common + mistake is to set up range constraints like: + +CHECK ( outletID BETWEEN 100 AND 200 ) +CHECK ( outletID BETWEEN 200 AND 300 ) + + This is wrong since it is not clear which child table the key + value 200 belongs in. + Instead, ranges should be defined in this style: + + +CREATE TABLE measurement_y2006m02 ( + CHECK ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' ) +) INHERITS (measurement); + +CREATE TABLE measurement_y2006m03 ( + CHECK ( logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' ) +) INHERITS (measurement); + +... +CREATE TABLE measurement_y2007m11 ( + CHECK ( logdate >= DATE '2007-11-01' AND logdate < DATE '2007-12-01' ) +) INHERITS (measurement); + +CREATE TABLE measurement_y2007m12 ( + CHECK ( logdate >= DATE '2007-12-01' AND logdate < DATE '2008-01-01' ) +) INHERITS (measurement); + +CREATE TABLE measurement_y2008m01 ( + CHECK ( logdate >= DATE '2008-01-01' AND logdate < DATE '2008-02-01' ) +) INHERITS (measurement); + + + + + + + For each child table, create an index on the key column(s), + as well as any other indexes you might want. + +CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate); +CREATE INDEX measurement_y2006m03_logdate ON measurement_y2006m03 (logdate); +CREATE INDEX measurement_y2007m11_logdate ON measurement_y2007m11 (logdate); +CREATE INDEX measurement_y2007m12_logdate ON measurement_y2007m12 (logdate); +CREATE INDEX measurement_y2008m01_logdate ON measurement_y2008m01 (logdate); + + + + + + + We want our application to be able to say INSERT INTO + measurement ... and have the data be redirected into the + appropriate child table. We can arrange that by attaching + a suitable trigger function to the root table. + If data will be added only to the latest child, we can + use a very simple trigger function: + + +CREATE OR REPLACE FUNCTION measurement_insert_trigger() +RETURNS TRIGGER AS $$ +BEGIN + INSERT INTO measurement_y2008m01 VALUES (NEW.*); + RETURN NULL; +END; +$$ +LANGUAGE plpgsql; + + + + + After creating the function, we create a trigger which + calls the trigger function: + + +CREATE TRIGGER insert_measurement_trigger + BEFORE INSERT ON measurement + FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger(); + + + We must redefine the trigger function each month so that it always + inserts into the current child table. The trigger definition does + not need to be updated, however. + + + + We might want to insert data and have the server automatically + locate the child table into which the row should be added. We + could do this with a more complex trigger function, for example: + + +CREATE OR REPLACE FUNCTION measurement_insert_trigger() +RETURNS TRIGGER AS $$ +BEGIN + IF ( NEW.logdate >= DATE '2006-02-01' AND + NEW.logdate < DATE '2006-03-01' ) THEN + INSERT INTO measurement_y2006m02 VALUES (NEW.*); + ELSIF ( NEW.logdate >= DATE '2006-03-01' AND + NEW.logdate < DATE '2006-04-01' ) THEN + INSERT INTO measurement_y2006m03 VALUES (NEW.*); + ... + ELSIF ( NEW.logdate >= DATE '2008-01-01' AND + NEW.logdate < DATE '2008-02-01' ) THEN + INSERT INTO measurement_y2008m01 VALUES (NEW.*); + ELSE + RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!'; + END IF; + RETURN NULL; +END; +$$ +LANGUAGE plpgsql; + + + The trigger definition is the same as before. + Note that each IF test must exactly match the + CHECK constraint for its child table. + + + + While this function is more complex than the single-month case, + it doesn't need to be updated as often, since branches can be + added in advance of being needed. + + + + + In practice, it might be best to check the newest child first, + if most inserts go into that child. For simplicity, we have + shown the trigger's tests in the same order as in other parts + of this example. + + + + + A different approach to redirecting inserts into the appropriate + child table is to set up rules, instead of a trigger, on the + root table. For example: + + +CREATE RULE measurement_insert_y2006m02 AS +ON INSERT TO measurement WHERE + ( logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' ) +DO INSTEAD + INSERT INTO measurement_y2006m02 VALUES (NEW.*); +... +CREATE RULE measurement_insert_y2008m01 AS +ON INSERT TO measurement WHERE + ( logdate >= DATE '2008-01-01' AND logdate < DATE '2008-02-01' ) +DO INSTEAD + INSERT INTO measurement_y2008m01 VALUES (NEW.*); + + + A rule has significantly more overhead than a trigger, but the + overhead is paid once per query rather than once per row, so this + method might be advantageous for bulk-insert situations. In most + cases, however, the trigger method will offer better performance. + + + + Be aware that COPY ignores rules. If you want to + use COPY to insert data, you'll need to copy into the + correct child table rather than directly into the root. COPY + does fire triggers, so you can use it normally if you use the trigger + approach. + + + + Another disadvantage of the rule approach is that there is no simple + way to force an error if the set of rules doesn't cover the insertion + date; the data will silently go into the root table instead. + + + + + + Ensure that the + configuration parameter is not disabled in + postgresql.conf; otherwise + child tables may be accessed unnecessarily. + + + + + + + As we can see, a complex table hierarchy could require a + substantial amount of DDL. In the above example we would be creating + a new child table each month, so it might be wise to write a script that + generates the required DDL automatically. + + + + + Maintenance for Inheritance Partitioning + + To remove old data quickly, simply drop the child table that is no longer + necessary: + +DROP TABLE measurement_y2006m02; + + + + + To remove the child table from the inheritance hierarchy table but retain access to + it as a table in its own right: + + +ALTER TABLE measurement_y2006m02 NO INHERIT measurement; + + + + + To add a new child table to handle new data, create an empty child table + just as the original children were created above: + + +CREATE TABLE measurement_y2008m02 ( + CHECK ( logdate >= DATE '2008-02-01' AND logdate < DATE '2008-03-01' ) +) INHERITS (measurement); + + + Alternatively, one may want to create and populate the new child table + before adding it to the table hierarchy. This could allow data to be + loaded, checked, and transformed before being made visible to queries on + the parent table. + + +CREATE TABLE measurement_y2008m02 + (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS); +ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02 + CHECK ( logdate >= DATE '2008-02-01' AND logdate < DATE '2008-03-01' ); +\copy measurement_y2008m02 from 'measurement_y2008m02' +-- possibly some other data preparation work +ALTER TABLE measurement_y2008m02 INHERIT measurement; + + + + + + Caveats + + + The following caveats apply to partitioning implemented using + inheritance: + + + + There is no automatic way to verify that all of the + CHECK constraints are mutually + exclusive. It is safer to create code that generates + child tables and creates and/or modifies associated objects than + to write each by hand. + + + + + + Indexes and foreign key constraints apply to single tables and not + to their inheritance children, hence they have some + caveats to be aware of. + + + + + + The schemes shown here assume that the values of a row's key column(s) + never change, or at least do not change enough to require it to move to another partition. + An UPDATE that attempts + to do that will fail because of the CHECK constraints. + If you need to handle such cases, you can put suitable update triggers + on the child tables, but it makes management of the structure + much more complicated. + + + + + + If you are using manual VACUUM or + ANALYZE commands, don't forget that + you need to run them on each child table individually. A command like: + +ANALYZE measurement; + + will only process the root table. + + + + + + INSERT statements with ON CONFLICT + clauses are unlikely to work as expected, as the ON CONFLICT + action is only taken in case of unique violations on the specified + target relation, not its child relations. + + + + + + Triggers or rules will be needed to route rows to the desired + child table, unless the application is explicitly aware of the + partitioning scheme. Triggers may be complicated to write, and will + be much slower than the tuple routing performed internally by + declarative partitioning. + + + + + + + + + Partition Pruning + + + partition pruning + + + + Partition pruning is a query optimization technique + that improves performance for declaratively partitioned tables. + As an example: + + +SET enable_partition_pruning = on; -- the default +SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01'; + + + Without partition pruning, the above query would scan each of the + partitions of the measurement table. With + partition pruning enabled, the planner will examine the definition + of each partition and prove that the partition need not + be scanned because it could not contain any rows meeting the query's + WHERE clause. When the planner can prove this, it + excludes (prunes) the partition from the query + plan. + + + + By using the EXPLAIN command and the configuration parameter, it's + possible to show the difference between a plan for which partitions have + been pruned and one for which they have not. A typical unoptimized + plan for this type of table setup is: + +SET enable_partition_pruning = off; +EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01'; + QUERY PLAN +-------------------------------------------------------------------&zwsp;---------------- + Aggregate (cost=188.76..188.77 rows=1 width=8) + -> Append (cost=0.00..181.05 rows=3085 width=0) + -> Seq Scan on measurement_y2006m02 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) + -> Seq Scan on measurement_y2006m03 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) +... + -> Seq Scan on measurement_y2007m11 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) + -> Seq Scan on measurement_y2007m12 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) + -> Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) + + + Some or all of the partitions might use index scans instead of + full-table sequential scans, but the point here is that there + is no need to scan the older partitions at all to answer this query. + When we enable partition pruning, we get a significantly + cheaper plan that will deliver the same answer: + +SET enable_partition_pruning = on; +EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01'; + QUERY PLAN +-------------------------------------------------------------------&zwsp;---------------- + Aggregate (cost=37.75..37.76 rows=1 width=8) + -> Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) + + + + + Note that partition pruning is driven only by the constraints defined + implicitly by the partition keys, not by the presence of indexes. + Therefore it isn't necessary to define indexes on the key columns. + Whether an index needs to be created for a given partition depends on + whether you expect that queries that scan the partition will + generally scan a large part of the partition or just a small part. + An index will be helpful in the latter case but not the former. + + + + Partition pruning can be performed not only during the planning of a + given query, but also during its execution. This is useful as it can + allow more partitions to be pruned when clauses contain expressions + whose values are not known at query planning time, for example, + parameters defined in a PREPARE statement, using a + value obtained from a subquery, or using a parameterized value on the + inner side of a nested loop join. Partition pruning during execution + can be performed at any of the following times: + + + + + During initialization of the query plan. Partition pruning can be + performed here for parameter values which are known during the + initialization phase of execution. Partitions which are pruned + during this stage will not show up in the query's + EXPLAIN or EXPLAIN ANALYZE. + It is possible to determine the number of partitions which were + removed during this phase by observing the + Subplans Removed property in the + EXPLAIN output. + + + + + + During actual execution of the query plan. Partition pruning may + also be performed here to remove partitions using values which are + only known during actual query execution. This includes values + from subqueries and values from execution-time parameters such as + those from parameterized nested loop joins. Since the value of + these parameters may change many times during the execution of the + query, partition pruning is performed whenever one of the + execution parameters being used by partition pruning changes. + Determining if partitions were pruned during this phase requires + careful inspection of the loops property in + the EXPLAIN ANALYZE output. Subplans + corresponding to different partitions may have different values + for it depending on how many times each of them was pruned during + execution. Some may be shown as (never executed) + if they were pruned every time. + + + + + + + Partition pruning can be disabled using the + setting. + + + + + Partitioning and Constraint Exclusion + + + constraint exclusion + + + + Constraint exclusion is a query optimization + technique similar to partition pruning. While it is primarily used + for partitioning implemented using the legacy inheritance method, it can be + used for other purposes, including with declarative partitioning. + + + + Constraint exclusion works in a very similar way to partition + pruning, except that it uses each table's CHECK + constraints — which gives it its name — whereas partition + pruning uses the table's partition bounds, which exist only in the + case of declarative partitioning. Another difference is that + constraint exclusion is only applied at plan time; there is no attempt + to remove partitions at execution time. + + + + The fact that constraint exclusion uses CHECK + constraints, which makes it slow compared to partition pruning, can + sometimes be used as an advantage: because constraints can be defined + even on declaratively-partitioned tables, in addition to their internal + partition bounds, constraint exclusion may be able + to elide additional partitions from the query plan. + + + + The default (and recommended) setting of + is neither + on nor off, but an intermediate setting + called partition, which causes the technique to be + applied only to queries that are likely to be working on inheritance partitioned + tables. The on setting causes the planner to examine + CHECK constraints in all queries, even simple ones that + are unlikely to benefit. + + + + The following caveats apply to constraint exclusion: + + + + + Constraint exclusion is only applied during query planning, unlike + partition pruning, which can also be applied during query execution. + + + + + + Constraint exclusion only works when the query's WHERE + clause contains constants (or externally supplied parameters). + For example, a comparison against a non-immutable function such as + CURRENT_TIMESTAMP cannot be optimized, since the + planner cannot know which child table the function's value might fall + into at run time. + + + + + + Keep the partitioning constraints simple, else the planner may not be + able to prove that child tables might not need to be visited. Use simple + equality conditions for list partitioning, or simple + range tests for range partitioning, as illustrated in the preceding + examples. A good rule of thumb is that partitioning constraints should + contain only comparisons of the partitioning column(s) to constants + using B-tree-indexable operators, because only B-tree-indexable + column(s) are allowed in the partition key. + + + + + + All constraints on all children of the parent table are examined + during constraint exclusion, so large numbers of children are likely + to increase query planning time considerably. So the legacy + inheritance based partitioning will work well with up to perhaps a + hundred child tables; don't try to use many thousands of children. + + + + + + + + + Best Practices for Declarative Partitioning + + + The choice of how to partition a table should be made carefully, as the + performance of query planning and execution can be negatively affected by + poor design. + + + + One of the most critical design decisions will be the column or columns + by which you partition your data. Often the best choice will be to + partition by the column or set of columns which most commonly appear in + WHERE clauses of queries being executed on the + partitioned table. WHERE clauses that are compatible + with the partition bound constraints can be used to prune unneeded + partitions. However, you may be forced into making other decisions by + requirements for the PRIMARY KEY or a + UNIQUE constraint. Removal of unwanted data is also a + factor to consider when planning your partitioning strategy. An entire + partition can be detached fairly quickly, so it may be beneficial to + design the partition strategy in such a way that all data to be removed + at once is located in a single partition. + + + + Choosing the target number of partitions that the table should be divided + into is also a critical decision to make. Not having enough partitions + may mean that indexes remain too large and that data locality remains poor + which could result in low cache hit ratios. However, dividing the table + into too many partitions can also cause issues. Too many partitions can + mean longer query planning times and higher memory consumption during both + query planning and execution, as further described below. + When choosing how to partition your table, + it's also important to consider what changes may occur in the future. For + example, if you choose to have one partition per customer and you + currently have a small number of large customers, consider the + implications if in several years you instead find yourself with a large + number of small customers. In this case, it may be better to choose to + partition by HASH and choose a reasonable number of + partitions rather than trying to partition by LIST and + hoping that the number of customers does not increase beyond what it is + practical to partition the data by. + + + + Sub-partitioning can be useful to further divide partitions that are + expected to become larger than other partitions. + Another option is to use range partitioning with multiple columns in + the partition key. + Either of these can easily lead to excessive numbers of partitions, + so restraint is advisable. + + + + It is important to consider the overhead of partitioning during + query planning and execution. The query planner is generally able to + handle partition hierarchies with up to a few thousand partitions fairly + well, provided that typical queries allow the query planner to prune all + but a small number of partitions. Planning times become longer and memory + consumption becomes higher when more partitions remain after the planner + performs partition pruning. Another + reason to be concerned about having a large number of partitions is that + the server's memory consumption may grow significantly over + time, especially if many sessions touch large numbers of partitions. + That's because each partition requires its metadata to be loaded into the + local memory of each session that touches it. + + + + With data warehouse type workloads, it can make sense to use a larger + number of partitions than with an OLTP type workload. + Generally, in data warehouses, query planning time is less of a concern as + the majority of processing time is spent during query execution. With + either of these two types of workload, it is important to make the right + decisions early, as re-partitioning large quantities of data can be + painfully slow. Simulations of the intended workload are often beneficial + for optimizing the partitioning strategy. Never just assume that more + partitions are better than fewer partitions, nor vice-versa. + + + + + + + Foreign Data + + + foreign data + + + foreign table + + + user mapping + + + + PostgreSQL implements portions of the SQL/MED + specification, allowing you to access data that resides outside + PostgreSQL using regular SQL queries. Such data is referred to as + foreign data. (Note that this usage is not to be confused + with foreign keys, which are a type of constraint within the database.) + + + + Foreign data is accessed with help from a + foreign data wrapper. A foreign data wrapper is a + library that can communicate with an external data source, hiding the + details of connecting to the data source and obtaining data from it. + There are some foreign data wrappers available as contrib + modules; see . Other kinds of foreign data + wrappers might be found as third party products. If none of the existing + foreign data wrappers suit your needs, you can write your own; see . + + + + To access foreign data, you need to create a foreign server + object, which defines how to connect to a particular external data source + according to the set of options used by its supporting foreign data + wrapper. Then you need to create one or more foreign + tables, which define the structure of the remote data. A + foreign table can be used in queries just like a normal table, but a + foreign table has no storage in the PostgreSQL server. Whenever it is + used, PostgreSQL asks the foreign data wrapper + to fetch data from the external source, or transmit data to the external + source in the case of update commands. + + + + Accessing remote data may require authenticating to the external + data source. This information can be provided by a + user mapping, which can provide additional data + such as user names and passwords based + on the current PostgreSQL role. + + + + For additional information, see + , + , + , + , and + . + + + + + Other Database Objects + + + Tables are the central objects in a relational database structure, + because they hold your data. But they are not the only objects + that exist in a database. Many other kinds of objects can be + created to make the use and management of the data more efficient + or convenient. They are not discussed in this chapter, but we give + you a list here so that you are aware of what is possible: + + + + + + Views + + + + + + Functions, procedures, and operators + + + + + + Data types and domains + + + + + + Triggers and rewrite rules + + + + + + Detailed information on + these topics appears in . + + + + + Dependency Tracking + + + CASCADE + with DROP + + + + RESTRICT + with DROP + + + + When you create complex database structures involving many tables + with foreign key constraints, views, triggers, functions, etc. you + implicitly create a net of dependencies between the objects. + For instance, a table with a foreign key constraint depends on the + table it references. + + + + To ensure the integrity of the entire database structure, + PostgreSQL makes sure that you cannot + drop objects that other objects still depend on. For example, + attempting to drop the products table we considered in , with the orders table depending on + it, would result in an error message like this: + +DROP TABLE products; + +ERROR: cannot drop table products because other objects depend on it +DETAIL: constraint orders_product_no_fkey on table orders depends on table products +HINT: Use DROP ... CASCADE to drop the dependent objects too. + + The error message contains a useful hint: if you do not want to + bother deleting all the dependent objects individually, you can run: + +DROP TABLE products CASCADE; + + and all the dependent objects will be removed, as will any objects + that depend on them, recursively. In this case, it doesn't remove + the orders table, it only removes the foreign key constraint. + It stops there because nothing depends on the foreign key constraint. + (If you want to check what DROP ... CASCADE will do, + run DROP without CASCADE and read the + DETAIL output.) + + + + Almost all DROP commands in PostgreSQL support + specifying CASCADE. Of course, the nature of + the possible dependencies varies with the type of the object. You + can also write RESTRICT instead of + CASCADE to get the default behavior, which is to + prevent dropping objects that any other objects depend on. + + + + + According to the SQL standard, specifying either + RESTRICT or CASCADE is + required in a DROP command. No database system actually + enforces that rule, but whether the default behavior + is RESTRICT or CASCADE varies + across systems. + + + + + If a DROP command lists multiple + objects, CASCADE is only required when there are + dependencies outside the specified group. For example, when saying + DROP TABLE tab1, tab2 the existence of a foreign + key referencing tab1 from tab2 would not mean + that CASCADE is needed to succeed. + + + + For user-defined functions, PostgreSQL tracks + dependencies associated with a function's externally-visible properties, + such as its argument and result types, but not dependencies + that could only be known by examining the function body. As an example, + consider this situation: + + +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', + 'green', 'blue', 'purple'); + +CREATE TABLE my_colors (color rainbow, note text); + +CREATE FUNCTION get_color_note (rainbow) RETURNS text AS + 'SELECT note FROM my_colors WHERE color = $1' + LANGUAGE SQL; + + + (See for an explanation of SQL-language + functions.) PostgreSQL will be aware that + the get_color_note function depends on the rainbow + type: dropping the type would force dropping the function, because its + argument type would no longer be defined. But PostgreSQL + will not consider get_color_note to depend on + the my_colors table, and so will not drop the function if + the table is dropped. While there are disadvantages to this approach, + there are also benefits. The function is still valid in some sense if the + table is missing, though executing it would cause an error; creating a new + table of the same name would allow the function to work again. + + + +
diff --git a/doc/src/sgml/dml.sgml b/doc/src/sgml/dml.sgml new file mode 100644 index 000000000000..cbbc5e246334 --- /dev/null +++ b/doc/src/sgml/dml.sgml @@ -0,0 +1,350 @@ + + + + Data Manipulation + + + The previous chapter discussed how to create tables and other + structures to hold your data. Now it is time to fill the tables + with data. This chapter covers how to insert, update, and delete + table data. The chapter + after this will finally explain how to extract your long-lost data + from the database. + + + + Inserting Data + + + inserting + + + + INSERT + + + + When a table is created, it contains no data. The first thing to + do before a database can be of much use is to insert data. Data is + inserted one row at a time. You can also insert more than one row + in a single command, but it is not possible to insert something that + is not a complete row. Even if you know only some column values, a + complete row must be created. + + + + To create a new row, use the + command. The command requires the + table name and column values. For + example, consider the products table from : + +CREATE TABLE products ( + product_no integer, + name text, + price numeric +); + + An example command to insert a row would be: + +INSERT INTO products VALUES (1, 'Cheese', 9.99); + + The data values are listed in the order in which the columns appear + in the table, separated by commas. Usually, the data values will + be literals (constants), but scalar expressions are also allowed. + + + + The above syntax has the drawback that you need to know the order + of the columns in the table. To avoid this you can also list the + columns explicitly. For example, both of the following commands + have the same effect as the one above: + +INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99); +INSERT INTO products (name, price, product_no) VALUES ('Cheese', 9.99, 1); + + Many users consider it good practice to always list the column + names. + + + + If you don't have values for all the columns, you can omit some of + them. In that case, the columns will be filled with their default + values. For example: + +INSERT INTO products (product_no, name) VALUES (1, 'Cheese'); +INSERT INTO products VALUES (1, 'Cheese'); + + The second form is a PostgreSQL + extension. It fills the columns from the left with as many values + as are given, and the rest will be defaulted. + + + + For clarity, you can also request default values explicitly, for + individual columns or for the entire row: + +INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', DEFAULT); +INSERT INTO products DEFAULT VALUES; + + + + + You can insert multiple rows in a single command: + +INSERT INTO products (product_no, name, price) VALUES + (1, 'Cheese', 9.99), + (2, 'Bread', 1.99), + (3, 'Milk', 2.99); + + + + + It is also possible to insert the result of a query (which might be no + rows, one row, or many rows): + +INSERT INTO products (product_no, name, price) + SELECT product_no, name, price FROM new_products + WHERE release_date = 'today'; + + This provides the full power of the SQL query mechanism () for computing the rows to be inserted. + + + + + When inserting a lot of data at the same time, consider using + the command. + It is not as flexible as the + command, but is more efficient. Refer + to for more information on improving + bulk loading performance. + + + + + + Updating Data + + + updating + + + + UPDATE + + + + The modification of data that is already in the database is + referred to as updating. You can update individual rows, all the + rows in a table, or a subset of all rows. Each column can be + updated separately; the other columns are not affected. + + + + To update existing rows, use the + command. This requires + three pieces of information: + + + The name of the table and column to update + + + + The new value of the column + + + + Which row(s) to update + + + + + + Recall from that SQL does not, in general, + provide a unique identifier for rows. Therefore it is not + always possible to directly specify which row to update. + Instead, you specify which conditions a row must meet in order to + be updated. Only if you have a primary key in the table (independent of + whether you declared it or not) can you reliably address individual rows + by choosing a condition that matches the primary key. + Graphical database access tools rely on this fact to allow you to + update rows individually. + + + + For example, this command updates all products that have a price of + 5 to have a price of 10: + +UPDATE products SET price = 10 WHERE price = 5; + + This might cause zero, one, or many rows to be updated. It is not + an error to attempt an update that does not match any rows. + + + + Let's look at that command in detail. First is the key word + UPDATE followed by the table name. As usual, + the table name can be schema-qualified, otherwise it is looked up + in the path. Next is the key word SET followed + by the column name, an equal sign, and the new column value. The + new column value can be any scalar expression, not just a constant. + For example, if you want to raise the price of all products by 10% + you could use: + +UPDATE products SET price = price * 1.10; + + As you see, the expression for the new value can refer to the existing + value(s) in the row. We also left out the WHERE clause. + If it is omitted, it means that all rows in the table are updated. + If it is present, only those rows that match the + WHERE condition are updated. Note that the equals + sign in the SET clause is an assignment while + the one in the WHERE clause is a comparison, but + this does not create any ambiguity. Of course, the + WHERE condition does + not have to be an equality test. Many other operators are + available (see ). But the expression + needs to evaluate to a Boolean result. + + + + You can update more than one column in an + UPDATE command by listing more than one + assignment in the SET clause. For example: + +UPDATE mytable SET a = 5, b = 3, c = 1 WHERE a > 0; + + + + + + Deleting Data + + + deleting + + + + DELETE + + + + So far we have explained how to add data to tables and how to + change data. What remains is to discuss how to remove data that is + no longer needed. Just as adding data is only possible in whole + rows, you can only remove entire rows from a table. In the + previous section we explained that SQL does not provide a way to + directly address individual rows. Therefore, removing rows can + only be done by specifying conditions that the rows to be removed + have to match. If you have a primary key in the table then you can + specify the exact row. But you can also remove groups of rows + matching a condition, or you can remove all rows in the table at + once. + + + + You use the + command to remove rows; the syntax is very similar to the + command. For instance, to remove all + rows from the products table that have a price of 10, use: + +DELETE FROM products WHERE price = 10; + + + + + If you simply write: + +DELETE FROM products; + + then all rows in the table will be deleted! Caveat programmer. + + + + + Returning Data from Modified Rows + + + RETURNING + + + + INSERT + RETURNING + + + + UPDATE + RETURNING + + + + DELETE + RETURNING + + + + Sometimes it is useful to obtain data from modified rows while they are + being manipulated. The INSERT, UPDATE, + and DELETE commands all have an + optional RETURNING clause that supports this. Use + of RETURNING avoids performing an extra database query to + collect the data, and is especially valuable when it would otherwise be + difficult to identify the modified rows reliably. + + + + The allowed contents of a RETURNING clause are the same as + a SELECT command's output list + (see ). It can contain column + names of the command's target table, or value expressions using those + columns. A common shorthand is RETURNING *, which selects + all columns of the target table in order. + + + + In an INSERT, the data available to RETURNING is + the row as it was inserted. This is not so useful in trivial inserts, + since it would just repeat the data provided by the client. But it can + be very handy when relying on computed default values. For example, + when using a serial + column to provide unique identifiers, RETURNING can return + the ID assigned to a new row: + +CREATE TABLE users (firstname text, lastname text, id serial primary key); + +INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id; + + The RETURNING clause is also very useful + with INSERT ... SELECT. + + + + In an UPDATE, the data available to RETURNING is + the new content of the modified row. For example: + +UPDATE products SET price = price * 1.10 + WHERE price <= 99.99 + RETURNING name, price AS new_price; + + + + + In a DELETE, the data available to RETURNING is + the content of the deleted row. For example: + +DELETE FROM products + WHERE obsoletion_date = 'today' + RETURNING *; + + + + + If there are triggers () on the target table, + the data available to RETURNING is the row as modified by + the triggers. Thus, inspecting columns computed by triggers is another + common use-case for RETURNING. + + + + diff --git a/doc/src/sgml/docguide.sgml b/doc/src/sgml/docguide.sgml new file mode 100644 index 000000000000..05dd9a8b44e0 --- /dev/null +++ b/doc/src/sgml/docguide.sgml @@ -0,0 +1,653 @@ + + + + Documentation + + + PostgreSQL has four primary documentation + formats: + + + + + Plain text, for pre-installation information + + + + + HTML, for on-line browsing and reference + + + + + PDF, for printing + + + + + man pages, for quick reference. + + + + + Additionally, a number of plain-text README files can + be found throughout the PostgreSQL source tree, + documenting various implementation issues. + + + + HTML documentation and man pages are part of a + standard distribution and are installed by default. PDF + format documentation is available separately for + download. + + + + DocBook + + The documentation sources are written in + DocBook, which is a markup language + defined in XML. In what + follows, the terms DocBook and XML are both + used, but technically they are not interchangeable. + + + + DocBook allows an author to specify the + structure and content of a technical document without worrying + about presentation details. A document style defines how that + content is rendered into one of several final forms. DocBook is + maintained by the + OASIS group. The + official DocBook site has good introductory and reference documentation and + a complete O'Reilly book for your online reading pleasure. The + + NewbieDoc Docbook Guide is very helpful for beginners. + The + FreeBSD Documentation Project also uses DocBook and has some good + information, including a number of style guidelines that might be + worth considering. + + + + + + Tool Sets + + + The following tools are used to process the documentation. Some + might be optional, as noted. + + + + DocBook DTD + + + This is the definition of DocBook itself. We currently use version + 4.5; you cannot use later or earlier versions. You need + the XML variant of the DocBook DTD, not + the SGML variant. + + + + + + DocBook XSL Stylesheets + + + These contain the processing instructions for converting the + DocBook sources to other formats, such as + HTML. + + + + The minimum required version is currently 1.77.0, but it is recommended + to use the latest available version for best results. + + + + + + Libxml2 for xmllint + + + This library and the xmllint tool it contains are + used for processing XML. Many developers will already + have Libxml2 installed, because it is also + used when building the PostgreSQL code. Note, however, + that xmllint might need to be installed from a + separate subpackage. + + + + + + Libxslt for xsltproc + + + xsltproc is an XSLT processor, that is, a program to + convert XML to other formats using XSLT stylesheets. + + + + + + FOP + + + This is a program for converting, among other things, XML to PDF. + + + + + + + + We have documented experience with several installation methods for + the various tools that are needed to process the documentation. + These will be described below. There might be some other packaged + distributions for these tools. Please report package status to the + documentation mailing list, and we will include that information + here. + + + + You can get away with not installing DocBook XML and the DocBook XSLT + stylesheets locally, because the required files will be downloaded from the + Internet and cached locally. This may in fact be the preferred solution if + your operating system packages provide only an old version of these files, + or if no packages are available at all. + If you want to prevent any attempt to access the Internet while building + the documentation, you need to pass the option + to xmllint and xsltproc; see below + for an example. + + + + Installation on Fedora, RHEL, and Derivatives + + + To install the required packages, use: + +yum install docbook-dtds docbook-style-xsl fop libxslt + + + + + + Installation on FreeBSD + + + To install the required packages with pkg, use: + +pkg install docbook-xml docbook-xsl fop libxslt + + + + + When building the documentation from the doc + directory you'll need to use gmake, because the + makefile provided is not suitable for FreeBSD's make. + + + + + Debian Packages + + + There is a full set of packages of the documentation tools + available for Debian GNU/Linux. + To install, simply use: + +apt-get install docbook-xml docbook-xsl fop libxml2-utils xsltproc + + + + + + macOS + + + On macOS, you can build the HTML and man documentation without installing + anything extra. If you want to build PDFs or want to install a local copy + of DocBook, you can get those from your preferred package manager. + + + + If you use MacPorts, the following will get you set up: + +sudo port install docbook-xml-4.5 docbook-xsl fop + + If you use Homebrew, use this: + +brew install docbook docbook-xsl fop + + + + + + Detection by <command>configure</command> + + + Before you can build the documentation you need to run the + configure script, as you would when building + the PostgreSQL programs themselves. + Check the output near the end of the run; it should look something + like this: + +checking for xmllint... xmllint +checking for xsltproc... xsltproc +checking for fop... fop +checking for dbtoepub... dbtoepub + + If xmllint or xsltproc is not + found, you will not be able to build any of the documentation. + fop is only needed to build the documentation in + PDF format. + dbtoepub is only needed to build the documentation + in EPUB format. + + + + If necessary, you can tell configure where to find + these programs, for example + +./configure ... XMLLINT=/opt/local/bin/xmllint ... + + Also, if you want to ensure that xmllint + and xsltproc will not perform any network access, + you can do something like + +./configure ... XMLLINT="xmllint --nonet" XSLTPROC="xsltproc --nonet" ... + + + + + + + Building the Documentation + + + Once you have everything set up, change to the directory + doc/src/sgml and run one of the commands + described in the following subsections to build the + documentation. (Remember to use GNU make.) + + + + HTML + + + To build the HTML version of the documentation: + +doc/src/sgml$ make html + + This is also the default target. The output appears in the + subdirectory html. + + + + To produce HTML documentation with the stylesheet used on postgresql.org instead of the + default simple style use: + +doc/src/sgml$ make STYLE=website html + + + + + If the STYLE=website option is used, the generated HTML + files include references to stylesheets hosted on postgresql.org and + require network access to view. + + + + + Manpages + + + We use the DocBook XSL stylesheets to + convert DocBook + refentry pages to *roff output suitable for man + pages. To create the man pages, use the command: + +doc/src/sgml$ make man + + + + + + PDF + + + To produce a PDF rendition of the documentation + using FOP, you can use one of the following + commands, depending on the preferred paper format: + + + + + For A4 format: + +doc/src/sgml$ make postgres-A4.pdf + + + + + + + For U.S. letter format: + +doc/src/sgml$ make postgres-US.pdf + + + + + + + + Because the PostgreSQL documentation is fairly + big, FOP will require a significant amount of + memory. Because of that, on some systems, the build will fail with a + memory-related error message. This can usually be fixed by configuring + Java heap settings in the configuration + file ~/.foprc, for example: + +# FOP binary distribution +FOP_OPTS='-Xmx1500m' +# Debian +JAVA_ARGS='-Xmx1500m' +# Red Hat +ADDITIONAL_FLAGS='-Xmx1500m' + + There is a minimum amount of memory that is required, and to some extent + more memory appears to make things a bit faster. On systems with very + little memory (less than 1 GB), the build will either be very slow due to + swapping or will not work at all. + + + + Other XSL-FO processors can also be used manually, but the automated build + process only supports FOP. + + + + + Plain Text Files + + + The installation instructions are also distributed as plain text, + in case they are needed in a situation where better reading tools + are not available. The INSTALL file + corresponds to , with some minor + changes to account for the different context. To recreate the + file, change to the directory doc/src/sgml + and enter make INSTALL. Building text output + requires Pandoc version 1.13 or newer as an + additional build tool. + + + + In the past, the release notes and regression testing instructions + were also distributed as plain text, but this practice has been + discontinued. + + + + + Syntax Check + + + Building the documentation can take very long. But there is a + method to just check the correct syntax of the documentation + files, which only takes a few seconds: + +doc/src/sgml$ make check + + + + + + + + Documentation Authoring + + + The documentation sources are most conveniently modified with an editor + that has a mode for editing XML, and even more so if it has some awareness + of XML schema languages so that it can know about + DocBook syntax specifically. + + + + Note that for historical reasons the documentation source files are named + with an extension .sgml even though they are now XML + files. So you might need to adjust your editor configuration to set the + correct mode. + + + + Emacs + + + nXML Mode, which ships with + Emacs, is the most common mode for editing + XML documents with Emacs. + It will allow you to use Emacs to insert tags + and check markup consistency, and it supports + DocBook out of the box. Check the + nXML manual for detailed documentation. + + + + src/tools/editors/emacs.samples contains + recommended settings for this mode. + + + + + + + + Style Guide + + + Reference Pages + + + Reference pages should follow a standard layout. This allows + users to find the desired information more quickly, and it also + encourages writers to document all relevant aspects of a command. + Consistency is not only desired among + PostgreSQL reference pages, but also + with reference pages provided by the operating system and other + packages. Hence the following guidelines have been developed. + They are for the most part consistent with similar guidelines + established by various operating systems. + + + + Reference pages that describe executable commands should contain + the following sections, in this order. Sections that do not apply + can be omitted. Additional top-level sections should only be used + in special circumstances; often that information belongs in the + Usage section. + + + + Name + + + This section is generated automatically. It contains the + command name and a half-sentence summary of its functionality. + + + + + + Synopsis + + + This section contains the syntax diagram of the command. The + synopsis should normally not list each command-line option; + that is done below. Instead, list the major components of the + command line, such as where input and output files go. + + + + + + Description + + + Several paragraphs explaining what the command does. + + + + + + Options + + + A list describing each command-line option. If there are a + lot of options, subsections can be used. + + + + + + Exit Status + + + If the program uses 0 for success and non-zero for failure, + then you do not need to document it. If there is a meaning + behind the different non-zero exit codes, list them here. + + + + + + Usage + + + Describe any sublanguage or run-time interface of the program. + If the program is not interactive, this section can usually be + omitted. Otherwise, this section is a catch-all for + describing run-time features. Use subsections if appropriate. + + + + + + Environment + + + List all environment variables that the program might use. + Try to be complete; even seemingly trivial variables like + SHELL might be of interest to the user. + + + + + + Files + + + List any files that the program might access implicitly. That + is, do not list input and output files that were specified on + the command line, but list configuration files, etc. + + + + + + Diagnostics + + + Explain any unusual output that the program might create. + Refrain from listing every possible error message. This is a + lot of work and has little use in practice. But if, say, the + error messages have a standard format that the user can parse, + this would be the place to explain it. + + + + + + Notes + + + Anything that doesn't fit elsewhere, but in particular bugs, + implementation flaws, security considerations, compatibility + issues. + + + + + + Examples + + + Examples + + + + + + History + + + If there were some major milestones in the history of the + program, they might be listed here. Usually, this section can + be omitted. + + + + + + Author + + + Author (only used in the contrib section) + + + + + + See Also + + + Cross-references, listed in the following order: other + PostgreSQL command reference pages, + PostgreSQL SQL command reference + pages, citation of PostgreSQL + manuals, other reference pages (e.g., operating system, other + packages), other documentation. Items in the same group are + listed alphabetically. + + + + + + + + + Reference pages describing SQL commands should contain the + following sections: Name, Synopsis, Description, Parameters, + Outputs, Notes, Examples, Compatibility, History, See + Also. The Parameters section is like the Options section, but + there is more freedom about which clauses of the command can be + listed. The Outputs section is only needed if the command returns + something other than a default command-completion tag. The Compatibility + section should explain to what extent + this command conforms to the SQL standard(s), or to which other + database system it is compatible. The See Also section of SQL + commands should list SQL commands before cross-references to + programs. + + + + + diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml new file mode 100644 index 000000000000..9d5505cb8499 --- /dev/null +++ b/doc/src/sgml/ecpg.sgml @@ -0,0 +1,10029 @@ + + + + <application>ECPG</application> — Embedded <acronym>SQL</acronym> in C + + embedded SQLin C + C + ECPG + + + This chapter describes the embedded SQL package + for PostgreSQL. It was written by + Linus Tolke (linus@epact.se) and Michael Meskes + (meskes@postgresql.org). Originally it was written to work with + C. It also works with C++, but + it does not recognize all C++ constructs yet. + + + + This documentation is quite incomplete. But since this + interface is standardized, additional information can be found in + many resources about SQL. + + + + The Concept + + + An embedded SQL program consists of code written in an ordinary + programming language, in this case C, mixed with SQL commands in + specially marked sections. To build the program, the source code (*.pgc) + is first passed through the embedded SQL preprocessor, which converts it + to an ordinary C program (*.c), and afterwards it can be processed by a C + compiler. (For details about the compiling and linking see .) + Converted ECPG applications call functions in the libpq library + through the embedded SQL library (ecpglib), and communicate with + the PostgreSQL server using the normal frontend-backend protocol. + + + + Embedded SQL has advantages over other methods + for handling SQL commands from C code. First, it + takes care of the tedious passing of information to and from + variables in your C program. Second, the SQL + code in the program is checked at build time for syntactical + correctness. Third, embedded SQL in C is + specified in the SQL standard and supported by + many other SQL database systems. The + PostgreSQL implementation is designed to match this + standard as much as possible, and it is usually possible to port + embedded SQL programs written for other SQL + databases to PostgreSQL with relative + ease. + + + + As already stated, programs written for the embedded + SQL interface are normal C programs with special + code inserted to perform database-related actions. This special + code always has the form: + +EXEC SQL ...; + + These statements syntactically take the place of a C statement. + Depending on the particular statement, they can appear at the + global level or within a function. + + + + Embedded + SQL statements follow the case-sensitivity rules of + normal SQL code, and not those of C. Also they allow nested + C-style comments as per the SQL standard. The C part of the + program, however, follows the C standard of not accepting nested comments. + Embedded SQL statements likewise use SQL rules, not + C rules, for parsing quoted strings and identifiers. + (See and + respectively. Note that + ECPG assumes that standard_conforming_strings + is on.) + Of course, the C part of the program follows C quoting rules. + + + + The following sections explain all the embedded SQL statements. + + + + + Managing Database Connections + + + This section describes how to open, close, and switch database + connections. + + + + Connecting to the Database Server + + + One connects to a database using the following statement: + +EXEC SQL CONNECT TO target AS connection-name USER user-name; + + The target can be specified in the + following ways: + + + + + dbname@hostname:port + + + + + + tcp:postgresql://hostname:port/dbname?options + + + + + + unix:postgresql://localhost:port/dbname?options + + + + + + an SQL string literal containing one of the above forms + + + + + + a reference to a character variable containing one of the above forms (see examples) + + + + + + DEFAULT + + + + + The connection target DEFAULT initiates a connection + to the default database under the default user name. No separate + user name or connection name can be specified in that case. + + + + If you specify the connection target directly (that is, not as a string + literal or variable reference), then the components of the target are + passed through normal SQL parsing; this means that, for example, + the hostname must look like one or more SQL + identifiers separated by dots, and those identifiers will be + case-folded unless double-quoted. Values of + any options must be SQL identifiers, + integers, or variable references. Of course, you can put nearly + anything into an SQL identifier by double-quoting it. + In practice, it is probably less error-prone to use a (single-quoted) + string literal or a variable reference than to write the connection + target directly. + + + + There are also different ways to specify the user name: + + + + + username + + + + + + username/password + + + + + + username IDENTIFIED BY password + + + + + + username USING password + + + + + As above, the parameters username and + password can be an SQL identifier, an + SQL string literal, or a reference to a character variable. + + + + If the connection target includes any options, + those consist of + keyword=value + specifications separated by ampersands (&). + The allowed key words are the same ones recognized + by libpq (see + ). Spaces are ignored before + any keyword or value, + though not within or after one. Note that there is no way to + write & within a value. + + + + Notice that when specifying a socket connection + (with the unix: prefix), the host name must be + exactly localhost. To select a non-default + socket directory, write the directory's pathname as the value of + a host option in + the options part of the target. + + + + The connection-name is used to handle + multiple connections in one program. It can be omitted if a + program uses only one connection. The most recently opened + connection becomes the current connection, which is used by default + when an SQL statement is to be executed (see later in this + chapter). + + + + Here are some examples of CONNECT statements: + +EXEC SQL CONNECT TO mydb@sql.mydomain.com; + +EXEC SQL CONNECT TO tcp:postgresql://sql.mydomain.com/mydb AS myconnection USER john; + +EXEC SQL BEGIN DECLARE SECTION; +const char *target = "mydb@sql.mydomain.com"; +const char *user = "john"; +const char *passwd = "secret"; +EXEC SQL END DECLARE SECTION; + ... +EXEC SQL CONNECT TO :target USER :user USING :passwd; +/* or EXEC SQL CONNECT TO :target USER :user/:passwd; */ + + The last example makes use of the feature referred to above as + character variable references. You will see in later sections how C + variables can be used in SQL statements when you prefix them with a + colon. + + + + Be advised that the format of the connection target is not + specified in the SQL standard. So if you want to develop portable + applications, you might want to use something based on the last + example above to encapsulate the connection target string + somewhere. + + + + If untrusted users have access to a database that has not adopted a + secure schema usage pattern, + begin each session by removing publicly-writable schemas + from search_path. For example, + add options=-c search_path= + to options, or + issue EXEC SQL SELECT pg_catalog.set_config('search_path', '', + false); after connecting. This consideration is not specific to + ECPG; it applies to every interface for executing arbitrary SQL commands. + + + + + Choosing a Connection + + + SQL statements in embedded SQL programs are by default executed on + the current connection, that is, the most recently opened one. If + an application needs to manage multiple connections, then there are + three ways to handle this. + + + + The first option is to explicitly choose a connection for each SQL + statement, for example: + +EXEC SQL AT connection-name SELECT ...; + + This option is particularly suitable if the application needs to + use several connections in mixed order. + + + + If your application uses multiple threads of execution, they cannot share a + connection concurrently. You must either explicitly control access to the connection + (using mutexes) or use a connection for each thread. + + + + The second option is to execute a statement to switch the current + connection. That statement is: + +EXEC SQL SET CONNECTION connection-name; + + This option is particularly convenient if many statements are to be + executed on the same connection. + + + + Here is an example program managing multiple database connections: + + +EXEC SQL BEGIN DECLARE SECTION; + char dbname[1024]; +EXEC SQL END DECLARE SECTION; + +int +main() +{ + EXEC SQL CONNECT TO testdb1 AS con1 USER testuser; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + EXEC SQL CONNECT TO testdb2 AS con2 USER testuser; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + EXEC SQL CONNECT TO testdb3 AS con3 USER testuser; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + /* This query would be executed in the last opened database "testdb3". */ + EXEC SQL SELECT current_database() INTO :dbname; + printf("current=%s (should be testdb3)\n", dbname); + + /* Using "AT" to run a query in "testdb2" */ + EXEC SQL AT con2 SELECT current_database() INTO :dbname; + printf("current=%s (should be testdb2)\n", dbname); + + /* Switch the current connection to "testdb1". */ + EXEC SQL SET CONNECTION con1; + + EXEC SQL SELECT current_database() INTO :dbname; + printf("current=%s (should be testdb1)\n", dbname); + + EXEC SQL DISCONNECT ALL; + return 0; +} +]]> + + This example would produce this output: + +current=testdb3 (should be testdb3) +current=testdb2 (should be testdb2) +current=testdb1 (should be testdb1) + + + + + The third option is to declare an SQL identifier linked to + the connection, for example: + +EXEC SQL AT connection-name DECLARE statement-name STATEMENT; +EXEC SQL PREPARE statement-name FROM :dyn-string; + + Once you link an SQL identifier to a connection, you execute dynamic SQL + without an AT clause. Note that this option behaves like preprocessor + directives, therefore the link is enabled only in the file. + + + Here is an example program using this option: + + +EXEC SQL BEGIN DECLARE SECTION; +char dbname[128]; +char *dyn_sql = "SELECT current_database()"; +EXEC SQL END DECLARE SECTION; + +int main(){ + EXEC SQL CONNECT TO postgres AS con1; + EXEC SQL CONNECT TO testdb AS con2; + EXEC SQL AT con1 DECLARE stmt STATEMENT; + EXEC SQL PREPARE stmt FROM :dyn_sql; + EXEC SQL EXECUTE stmt INTO :dbname; + printf("%s\n", dbname); + + EXEC SQL DISCONNECT ALL; + return 0; +} +]]> + + This example would produce this output, even if the default connection is testdb: + +postgres + + + + + + Closing a Connection + + + To close a connection, use the following statement: + +EXEC SQL DISCONNECT connection; + + The connection can be specified + in the following ways: + + + + + connection-name + + + + + + DEFAULT + + + + + + CURRENT + + + + + + ALL + + + + + If no connection name is specified, the current connection is + closed. + + + + It is good style that an application always explicitly disconnect + from every connection it opened. + + + + + + + Running SQL Commands + + + Any SQL command can be run from within an embedded SQL application. + Below are some examples of how to do that. + + + + Executing SQL Statements + + + Creating a table: + +EXEC SQL CREATE TABLE foo (number integer, ascii char(16)); +EXEC SQL CREATE UNIQUE INDEX num1 ON foo(number); +EXEC SQL COMMIT; + + + + + Inserting rows: + +EXEC SQL INSERT INTO foo (number, ascii) VALUES (9999, 'doodad'); +EXEC SQL COMMIT; + + + + + Deleting rows: + +EXEC SQL DELETE FROM foo WHERE number = 9999; +EXEC SQL COMMIT; + + + + + Updates: + +EXEC SQL UPDATE foo + SET ascii = 'foobar' + WHERE number = 9999; +EXEC SQL COMMIT; + + + + + SELECT statements that return a single result + row can also be executed using + EXEC SQL directly. To handle result sets with + multiple rows, an application has to use a cursor; + see below. (As a special case, an + application can fetch multiple rows at once into an array host + variable; see .) + + + + Single-row select: + +EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad'; + + + + + Also, a configuration parameter can be retrieved with the + SHOW command: + +EXEC SQL SHOW search_path INTO :var; + + + + + The tokens of the form + :something are + host variables, that is, they refer to + variables in the C program. They are explained in . + + + + + Using Cursors + + + To retrieve a result set holding multiple rows, an application has + to declare a cursor and fetch each row from the cursor. The steps + to use a cursor are the following: declare a cursor, open it, fetch + a row from the cursor, repeat, and finally close it. + + + + Select using cursors: + +EXEC SQL DECLARE foo_bar CURSOR FOR + SELECT number, ascii FROM foo + ORDER BY ascii; +EXEC SQL OPEN foo_bar; +EXEC SQL FETCH foo_bar INTO :FooBar, DooDad; +... +EXEC SQL CLOSE foo_bar; +EXEC SQL COMMIT; + + + + + For more details about declaring a cursor, see ; for more details about fetching rows from a + cursor, see . + + + + + The ECPG DECLARE command does not actually + cause a statement to be sent to the PostgreSQL backend. The + cursor is opened in the backend (using the + backend's DECLARE command) at the point when + the OPEN command is executed. + + + + + + Managing Transactions + + + In the default mode, statements are committed only when + EXEC SQL COMMIT is issued. The embedded SQL + interface also supports autocommit of transactions (similar to + psql's default behavior) via the + command-line option to ecpg (see ) or via the EXEC SQL SET AUTOCOMMIT TO + ON statement. In autocommit mode, each command is + automatically committed unless it is inside an explicit transaction + block. This mode can be explicitly turned off using EXEC + SQL SET AUTOCOMMIT TO OFF. + + + + The following transaction management commands are available: + + + + EXEC SQL COMMIT + + + Commit an in-progress transaction. + + + + + + EXEC SQL ROLLBACK + + + Roll back an in-progress transaction. + + + + + + EXEC SQL PREPARE TRANSACTION transaction_id + + + Prepare the current transaction for two-phase commit. + + + + + + EXEC SQL COMMIT PREPARED transaction_id + + + Commit a transaction that is in prepared state. + + + + + + EXEC SQL ROLLBACK PREPARED transaction_id + + + Roll back a transaction that is in prepared state. + + + + + + EXEC SQL SET AUTOCOMMIT TO ON + + + Enable autocommit mode. + + + + + + EXEC SQL SET AUTOCOMMIT TO OFF + + + Disable autocommit mode. This is the default. + + + + + + + + + Prepared Statements + + + When the values to be passed to an SQL statement are not known at + compile time, or the same statement is going to be used many + times, then prepared statements can be useful. + + + + The statement is prepared using the + command PREPARE. For the values that are not + known yet, use the + placeholder ?: + +EXEC SQL PREPARE stmt1 FROM "SELECT oid, datname FROM pg_database WHERE oid = ?"; + + + + + If a statement returns a single row, the application can + call EXECUTE after + PREPARE to execute the statement, supplying the + actual values for the placeholders with a USING + clause: + +EXEC SQL EXECUTE stmt1 INTO :dboid, :dbname USING 1; + + + + + If a statement returns multiple rows, the application can use a + cursor declared based on the prepared statement. To bind input + parameters, the cursor must be opened with + a USING clause: + +EXEC SQL PREPARE stmt1 FROM "SELECT oid,datname FROM pg_database WHERE oid > ?"; +EXEC SQL DECLARE foo_bar CURSOR FOR stmt1; + +/* when end of result set reached, break out of while loop */ +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +EXEC SQL OPEN foo_bar USING 100; +... +while (1) +{ + EXEC SQL FETCH NEXT FROM foo_bar INTO :dboid, :dbname; + ... +} +EXEC SQL CLOSE foo_bar; + + + + + When you don't need the prepared statement anymore, you should + deallocate it: + +EXEC SQL DEALLOCATE PREPARE name; + + + + + For more details about PREPARE, + see . Also + see for more details about using + placeholders and input parameters. + + + + + + Using Host Variables + + + In you saw how you can execute SQL + statements from an embedded SQL program. Some of those statements + only used fixed values and did not provide a way to insert + user-supplied values into statements or have the program process + the values returned by the query. Those kinds of statements are + not really useful in real applications. This section explains in + detail how you can pass data between your C program and the + embedded SQL statements using a simple mechanism called + host variables. In an embedded SQL program we + consider the SQL statements to be guests in the C + program code which is the host language. Therefore + the variables of the C program are called host + variables. + + + + Another way to exchange values between PostgreSQL backends and ECPG + applications is the use of SQL descriptors, described + in . + + + + Overview + + + Passing data between the C program and the SQL statements is + particularly simple in embedded SQL. Instead of having the + program paste the data into the statement, which entails various + complications, such as properly quoting the value, you can simply + write the name of a C variable into the SQL statement, prefixed by + a colon. For example: + +EXEC SQL INSERT INTO sometable VALUES (:v1, 'foo', :v2); + + This statement refers to two C variables named + v1 and v2 and also uses a + regular SQL string literal, to illustrate that you are not + restricted to use one kind of data or the other. + + + + This style of inserting C variables in SQL statements works + anywhere a value expression is expected in an SQL statement. + + + + + Declare Sections + + + To pass data from the program to the database, for example as + parameters in a query, or to pass data from the database back to + the program, the C variables that are intended to contain this + data need to be declared in specially marked sections, so the + embedded SQL preprocessor is made aware of them. + + + + This section starts with: + +EXEC SQL BEGIN DECLARE SECTION; + + and ends with: + +EXEC SQL END DECLARE SECTION; + + Between those lines, there must be normal C variable declarations, + such as: + +int x = 4; +char foo[16], bar[16]; + + As you can see, you can optionally assign an initial value to the variable. + The variable's scope is determined by the location of its declaring + section within the program. + You can also declare variables with the following syntax which implicitly + creates a declare section: + +EXEC SQL int i = 4; + + You can have as many declare sections in a program as you like. + + + + The declarations are also echoed to the output file as normal C + variables, so there's no need to declare them again. Variables + that are not intended to be used in SQL commands can be declared + normally outside these special sections. + + + + The definition of a structure or union also must be listed inside + a DECLARE section. Otherwise the preprocessor cannot + handle these types since it does not know the definition. + + + + + Retrieving Query Results + + + Now you should be able to pass data generated by your program into + an SQL command. But how do you retrieve the results of a query? + For that purpose, embedded SQL provides special variants of the + usual commands SELECT and + FETCH. These commands have a special + INTO clause that specifies which host variables + the retrieved values are to be stored in. + SELECT is used for a query that returns only + single row, and FETCH is used for a query that + returns multiple rows, using a cursor. + + + + Here is an example: + +/* + * assume this table: + * CREATE TABLE test1 (a int, b varchar(50)); + */ + +EXEC SQL BEGIN DECLARE SECTION; +int v1; +VARCHAR v2; +EXEC SQL END DECLARE SECTION; + + ... + +EXEC SQL SELECT a, b INTO :v1, :v2 FROM test; + + So the INTO clause appears between the select + list and the FROM clause. The number of + elements in the select list and the list after + INTO (also called the target list) must be + equal. + + + + Here is an example using the command FETCH: + +EXEC SQL BEGIN DECLARE SECTION; +int v1; +VARCHAR v2; +EXEC SQL END DECLARE SECTION; + + ... + +EXEC SQL DECLARE foo CURSOR FOR SELECT a, b FROM test; + + ... + +do +{ + ... + EXEC SQL FETCH NEXT FROM foo INTO :v1, :v2; + ... +} while (...); + + Here the INTO clause appears after all the + normal clauses. + + + + + + Type Mapping + + + When ECPG applications exchange values between the PostgreSQL + server and the C application, such as when retrieving query + results from the server or executing SQL statements with input + parameters, the values need to be converted between PostgreSQL + data types and host language variable types (C language data + types, concretely). One of the main points of ECPG is that it + takes care of this automatically in most cases. + + + + In this respect, there are two kinds of data types: Some simple + PostgreSQL data types, such as integer + and text, can be read and written by the application + directly. Other PostgreSQL data types, such + as timestamp and numeric can only be + accessed through special library functions; see + . + + + + shows which PostgreSQL + data types correspond to which C data types. When you wish to + send or receive a value of a given PostgreSQL data type, you + should declare a C variable of the corresponding C data type in + the declare section. + + + + Mapping Between PostgreSQL Data Types and C Variable Types + + + + PostgreSQL data type + Host variable type + + + + + + smallint + short + + + + integer + int + + + + bigint + long long int + + + + decimal + decimalThis type can only be accessed through special library functions; see . + + + + numeric + numeric + + + + real + float + + + + double precision + double + + + + smallserial + short + + + + serial + int + + + + bigserial + long long int + + + + oid + unsigned int + + + + character(n), varchar(n), text + char[n+1], VARCHAR[n+1] + + + + name + char[NAMEDATALEN] + + + + timestamp + timestamp + + + + interval + interval + + + + date + date + + + + boolean + booldeclared in ecpglib.h if not native + + + + bytea + char *, bytea[n] + + + +
+ + + Handling Character Strings + + + To handle SQL character string data types, such + as varchar and text, there are two + possible ways to declare the host variables. + + + + One way is using char[], an array + of char, which is the most common way to handle + character data in C. + +EXEC SQL BEGIN DECLARE SECTION; + char str[50]; +EXEC SQL END DECLARE SECTION; + + Note that you have to take care of the length yourself. If you + use this host variable as the target variable of a query which + returns a string with more than 49 characters, a buffer overflow + occurs. + + + + The other way is using the VARCHAR type, which is a + special type provided by ECPG. The definition on an array of + type VARCHAR is converted into a + named struct for every variable. A declaration like: + +VARCHAR var[180]; + + is converted into: + +struct varchar_var { int len; char arr[180]; } var; + + The member arr hosts the string + including a terminating zero byte. Thus, to store a string in + a VARCHAR host variable, the host variable has to be + declared with the length including the zero byte terminator. The + member len holds the length of the + string stored in the arr without the + terminating zero byte. When a host variable is used as input for + a query, if strlen(arr) + and len are different, the shorter one + is used. + + + + VARCHAR can be written in upper or lower case, but + not in mixed case. + + + + char and VARCHAR host variables can + also hold values of other SQL types, which will be stored in + their string forms. + + + + + Accessing Special Data Types + + + ECPG contains some special types that help you to interact easily + with some special data types from the PostgreSQL server. In + particular, it has implemented support for the + numeric, decimal, date, timestamp, + and interval types. These data types cannot usefully be + mapped to primitive host variable types (such + as int, long long int, + or char[]), because they have a complex internal + structure. Applications deal with these types by declaring host + variables in special types and accessing them using functions in + the pgtypes library. The pgtypes library, described in detail + in contains basic functions to deal + with those types, such that you do not need to send a query to + the SQL server just for adding an interval to a time stamp for + example. + + + + The follow subsections describe these special data types. For + more details about pgtypes library functions, + see . + + + + timestamp, date + + + Here is a pattern for handling timestamp variables + in the ECPG host application. + + + + First, the program has to include the header file for the + timestamp type: + +#include <pgtypes_timestamp.h> + + + + + Next, declare a host variable as type timestamp in + the declare section: + +EXEC SQL BEGIN DECLARE SECTION; +timestamp ts; +EXEC SQL END DECLARE SECTION; + + + + + And after reading a value into the host variable, process it + using pgtypes library functions. In following example, the + timestamp value is converted into text (ASCII) form + with the PGTYPEStimestamp_to_asc() + function: + +EXEC SQL SELECT now()::timestamp INTO :ts; + +printf("ts = %s\n", PGTYPEStimestamp_to_asc(ts)); + + This example will show some result like following: + +ts = 2010-06-27 18:03:56.949343 + + + + + In addition, the DATE type can be handled in the same way. The + program has to include pgtypes_date.h, declare a host variable + as the date type and convert a DATE value into a text form using + PGTYPESdate_to_asc() function. For more details about the + pgtypes library functions, see . + + + + + interval + + + The handling of the interval type is also similar + to the timestamp and date types. It + is required, however, to allocate memory for + an interval type value explicitly. In other words, + the memory space for the variable has to be allocated in the + heap memory, not in the stack memory. + + + + Here is an example program: + +#include <stdio.h> +#include <stdlib.h> +#include <pgtypes_interval.h> + +int +main(void) +{ +EXEC SQL BEGIN DECLARE SECTION; + interval *in; +EXEC SQL END DECLARE SECTION; + + EXEC SQL CONNECT TO testdb; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + in = PGTYPESinterval_new(); + EXEC SQL SELECT '1 min'::interval INTO :in; + printf("interval = %s\n", PGTYPESinterval_to_asc(in)); + PGTYPESinterval_free(in); + + EXEC SQL COMMIT; + EXEC SQL DISCONNECT ALL; + return 0; +} + + + + + + numeric, decimal + + + The handling of the numeric + and decimal types is similar to the + interval type: It requires defining a pointer, + allocating some memory space on the heap, and accessing the + variable using the pgtypes library functions. For more details + about the pgtypes library functions, + see . + + + + No functions are provided specifically for + the decimal type. An application has to convert it + to a numeric variable using a pgtypes library + function to do further processing. + + + + Here is an example program handling numeric + and decimal type variables. + +#include <stdio.h> +#include <stdlib.h> +#include <pgtypes_numeric.h> + +EXEC SQL WHENEVER SQLERROR STOP; + +int +main(void) +{ +EXEC SQL BEGIN DECLARE SECTION; + numeric *num; + numeric *num2; + decimal *dec; +EXEC SQL END DECLARE SECTION; + + EXEC SQL CONNECT TO testdb; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + num = PGTYPESnumeric_new(); + dec = PGTYPESdecimal_new(); + + EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec; + + printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0)); + printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1)); + printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2)); + + /* Convert decimal to numeric to show a decimal value. */ + num2 = PGTYPESnumeric_new(); + PGTYPESnumeric_from_decimal(dec, num2); + + printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0)); + printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1)); + printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2)); + + PGTYPESnumeric_free(num2); + PGTYPESdecimal_free(dec); + PGTYPESnumeric_free(num); + + EXEC SQL COMMIT; + EXEC SQL DISCONNECT ALL; + return 0; +} + + + + + + bytea + + + The handling of the bytea type is similar to + that of VARCHAR. The definition on an array of type + bytea is converted into a named struct for every + variable. A declaration like: + +bytea var[180]; + + is converted into: + +struct bytea_var { int len; char arr[180]; } var; + + The member arr hosts binary format + data. It can also handle '\0' as part of + data, unlike VARCHAR. + The data is converted from/to hex format and sent/received by + ecpglib. + + + + + bytea variable can be used only when + is set to hex. + + + + + + + Host Variables with Nonprimitive Types + + + As a host variable you can also use arrays, typedefs, structs, and + pointers. + + + + Arrays + + + There are two use cases for arrays as host variables. The first + is a way to store some text string in char[] + or VARCHAR[], as + explained in . The second use case is to + retrieve multiple rows from a query result without using a + cursor. Without an array, to process a query result consisting + of multiple rows, it is required to use a cursor and + the FETCH command. But with array host + variables, multiple rows can be received at once. The length of + the array has to be defined to be able to accommodate all rows, + otherwise a buffer overflow will likely occur. + + + + Following example scans the pg_database + system table and shows all OIDs and names of the available + databases: + +int +main(void) +{ +EXEC SQL BEGIN DECLARE SECTION; + int dbid[8]; + char dbname[8][16]; + int i; +EXEC SQL END DECLARE SECTION; + + memset(dbname, 0, sizeof(char)* 16 * 8); + memset(dbid, 0, sizeof(int) * 8); + + EXEC SQL CONNECT TO testdb; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + /* Retrieve multiple rows into arrays at once. */ + EXEC SQL SELECT oid,datname INTO :dbid, :dbname FROM pg_database; + + for (i = 0; i < 8; i++) + printf("oid=%d, dbname=%s\n", dbid[i], dbname[i]); + + EXEC SQL COMMIT; + EXEC SQL DISCONNECT ALL; + return 0; +} + + + This example shows following result. (The exact values depend on + local circumstances.) + +oid=1, dbname=template1 +oid=11510, dbname=template0 +oid=11511, dbname=postgres +oid=313780, dbname=testdb +oid=0, dbname= +oid=0, dbname= +oid=0, dbname= + + + + + + Structures + + + A structure whose member names match the column names of a query + result, can be used to retrieve multiple columns at once. The + structure enables handling multiple column values in a single + host variable. + + + + The following example retrieves OIDs, names, and sizes of the + available databases from the pg_database + system table and using + the pg_database_size() function. In this + example, a structure variable dbinfo_t with + members whose names match each column in + the SELECT result is used to retrieve one + result row without putting multiple host variables in + the FETCH statement. + +EXEC SQL BEGIN DECLARE SECTION; + typedef struct + { + int oid; + char datname[65]; + long long int size; + } dbinfo_t; + + dbinfo_t dbval; +EXEC SQL END DECLARE SECTION; + + memset(&dbval, 0, sizeof(dbinfo_t)); + + EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size FROM pg_database; + EXEC SQL OPEN cur1; + + /* when end of result set reached, break out of while loop */ + EXEC SQL WHENEVER NOT FOUND DO BREAK; + + while (1) + { + /* Fetch multiple columns into one structure. */ + EXEC SQL FETCH FROM cur1 INTO :dbval; + + /* Print members of the structure. */ + printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname, dbval.size); + } + + EXEC SQL CLOSE cur1; + + + + + This example shows following result. (The exact values depend on + local circumstances.) + +oid=1, datname=template1, size=4324580 +oid=11510, datname=template0, size=4243460 +oid=11511, datname=postgres, size=4324580 +oid=313780, datname=testdb, size=8183012 + + + + + Structure host variables absorb as many columns + as the structure as fields. Additional columns can be assigned + to other host variables. For example, the above program could + also be restructured like this, with the size + variable outside the structure: + +EXEC SQL BEGIN DECLARE SECTION; + typedef struct + { + int oid; + char datname[65]; + } dbinfo_t; + + dbinfo_t dbval; + long long int size; +EXEC SQL END DECLARE SECTION; + + memset(&dbval, 0, sizeof(dbinfo_t)); + + EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size FROM pg_database; + EXEC SQL OPEN cur1; + + /* when end of result set reached, break out of while loop */ + EXEC SQL WHENEVER NOT FOUND DO BREAK; + + while (1) + { + /* Fetch multiple columns into one structure. */ + EXEC SQL FETCH FROM cur1 INTO :dbval, :size; + + /* Print members of the structure. */ + printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname, size); + } + + EXEC SQL CLOSE cur1; + + + + + + Typedefs + + + Use the typedef keyword to map new types to already + existing types. + +EXEC SQL BEGIN DECLARE SECTION; + typedef char mychartype[40]; + typedef long serial_t; +EXEC SQL END DECLARE SECTION; + + Note that you could also use: + +EXEC SQL TYPE serial_t IS long; + + This declaration does not need to be part of a declare section. + + + + + Pointers + + + You can declare pointers to the most common types. Note however + that you cannot use pointers as target variables of queries + without auto-allocation. See + for more information on auto-allocation. + + + + +EXEC SQL BEGIN DECLARE SECTION; + int *intp; + char **charp; +EXEC SQL END DECLARE SECTION; + + + + +
+ + + Handling Nonprimitive SQL Data Types + + + This section contains information on how to handle nonscalar and + user-defined SQL-level data types in ECPG applications. Note that + this is distinct from the handling of host variables of + nonprimitive types, described in the previous section. + + + + Arrays + + + Multi-dimensional SQL-level arrays are not directly supported in ECPG. + One-dimensional SQL-level arrays can be mapped into C array host + variables and vice-versa. However, when creating a statement ecpg does + not know the types of the columns, so that it cannot check if a C array + is input into a corresponding SQL-level array. When processing the + output of an SQL statement, ecpg has the necessary information and thus + checks if both are arrays. + + + + If a query accesses elements of an array + separately, then this avoids the use of arrays in ECPG. Then, a + host variable with a type that can be mapped to the element type + should be used. For example, if a column type is array of + integer, a host variable of type int + can be used. Also if the element type is varchar + or text, a host variable of type char[] + or VARCHAR[] can be used. + + + + Here is an example. Assume the following table: + +CREATE TABLE t3 ( + ii integer[] +); + +testdb=> SELECT * FROM t3; + ii +------------- + {1,2,3,4,5} +(1 row) + + + The following example program retrieves the 4th element of the + array and stores it into a host variable of + type int: + +EXEC SQL BEGIN DECLARE SECTION; +int ii; +EXEC SQL END DECLARE SECTION; + +EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[4] FROM t3; +EXEC SQL OPEN cur1; + +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +while (1) +{ + EXEC SQL FETCH FROM cur1 INTO :ii ; + printf("ii=%d\n", ii); +} + +EXEC SQL CLOSE cur1; + + + This example shows the following result: + +ii=4 + + + + + To map multiple array elements to the multiple elements in an + array type host variables each element of array column and each + element of the host variable array have to be managed separately, + for example: + +EXEC SQL BEGIN DECLARE SECTION; +int ii_a[8]; +EXEC SQL END DECLARE SECTION; + +EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[1], ii[2], ii[3], ii[4] FROM t3; +EXEC SQL OPEN cur1; + +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +while (1) +{ + EXEC SQL FETCH FROM cur1 INTO :ii_a[0], :ii_a[1], :ii_a[2], :ii_a[3]; + ... +} + + + + + Note again that + +EXEC SQL BEGIN DECLARE SECTION; +int ii_a[8]; +EXEC SQL END DECLARE SECTION; + +EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii FROM t3; +EXEC SQL OPEN cur1; + +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +while (1) +{ + /* WRONG */ + EXEC SQL FETCH FROM cur1 INTO :ii_a; + ... +} + + would not work correctly in this case, because you cannot map an + array type column to an array host variable directly. + + + + Another workaround is to store arrays in their external string + representation in host variables of type char[] + or VARCHAR[]. For more details about this + representation, see . Note that + this means that the array cannot be accessed naturally as an + array in the host program (without further processing that parses + the text representation). + + + + + Composite Types + + + Composite types are not directly supported in ECPG, but an easy workaround is possible. + The + available workarounds are similar to the ones described for + arrays above: Either access each attribute separately or use the + external string representation. + + + + For the following examples, assume the following type and table: + +CREATE TYPE comp_t AS (intval integer, textval varchar(32)); +CREATE TABLE t4 (compval comp_t); +INSERT INTO t4 VALUES ( (256, 'PostgreSQL') ); + + + The most obvious solution is to access each attribute separately. + The following program retrieves data from the example table by + selecting each attribute of the type comp_t + separately: + +EXEC SQL BEGIN DECLARE SECTION; +int intval; +varchar textval[33]; +EXEC SQL END DECLARE SECTION; + +/* Put each element of the composite type column in the SELECT list. */ +EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4; +EXEC SQL OPEN cur1; + +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +while (1) +{ + /* Fetch each element of the composite type column into host variables. */ + EXEC SQL FETCH FROM cur1 INTO :intval, :textval; + + printf("intval=%d, textval=%s\n", intval, textval.arr); +} + +EXEC SQL CLOSE cur1; + + + + + To enhance this example, the host variables to store values in + the FETCH command can be gathered into one + structure. For more details about the host variable in the + structure form, see . + To switch to the structure, the example can be modified as below. + The two host variables, intval + and textval, become members of + the comp_t structure, and the structure + is specified on the FETCH command. + +EXEC SQL BEGIN DECLARE SECTION; +typedef struct +{ + int intval; + varchar textval[33]; +} comp_t; + +comp_t compval; +EXEC SQL END DECLARE SECTION; + +/* Put each element of the composite type column in the SELECT list. */ +EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4; +EXEC SQL OPEN cur1; + +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +while (1) +{ + /* Put all values in the SELECT list into one structure. */ + EXEC SQL FETCH FROM cur1 INTO :compval; + + printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr); +} + +EXEC SQL CLOSE cur1; + + + Although a structure is used in the FETCH + command, the attribute names in the SELECT + clause are specified one by one. This can be enhanced by using + a * to ask for all attributes of the composite + type value. + +... +EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).* FROM t4; +EXEC SQL OPEN cur1; + +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +while (1) +{ + /* Put all values in the SELECT list into one structure. */ + EXEC SQL FETCH FROM cur1 INTO :compval; + + printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr); +} +... + + This way, composite types can be mapped into structures almost + seamlessly, even though ECPG does not understand the composite + type itself. + + + + Finally, it is also possible to store composite type values in + their external string representation in host variables of + type char[] or VARCHAR[]. But that + way, it is not easily possible to access the fields of the value + from the host program. + + + + + User-Defined Base Types + + + New user-defined base types are not directly supported by ECPG. + You can use the external string representation and host variables + of type char[] or VARCHAR[], and this + solution is indeed appropriate and sufficient for many types. + + + + Here is an example using the data type complex from + the example in . The external string + representation of that type is (%f,%f), + which is defined in the + functions complex_in() + and complex_out() functions + in . The following example inserts the + complex type values (1,1) + and (3,3) into the + columns a and b, and select + them from the table after that. + + +EXEC SQL BEGIN DECLARE SECTION; + varchar a[64]; + varchar b[64]; +EXEC SQL END DECLARE SECTION; + + EXEC SQL INSERT INTO test_complex VALUES ('(1,1)', '(3,3)'); + + EXEC SQL DECLARE cur1 CURSOR FOR SELECT a, b FROM test_complex; + EXEC SQL OPEN cur1; + + EXEC SQL WHENEVER NOT FOUND DO BREAK; + + while (1) + { + EXEC SQL FETCH FROM cur1 INTO :a, :b; + printf("a=%s, b=%s\n", a.arr, b.arr); + } + + EXEC SQL CLOSE cur1; + + + This example shows following result: + +a=(1,1), b=(3,3) + + + + + Another workaround is avoiding the direct use of the user-defined + types in ECPG and instead create a function or cast that converts + between the user-defined type and a primitive type that ECPG can + handle. Note, however, that type casts, especially implicit + ones, should be introduced into the type system very carefully. + + + + For example, + +CREATE FUNCTION create_complex(r double, i double) RETURNS complex +LANGUAGE SQL +IMMUTABLE +AS $$ SELECT $1 * complex '(1,0')' + $2 * complex '(0,1)' $$; + + After this definition, the following + +EXEC SQL BEGIN DECLARE SECTION; +double a, b, c, d; +EXEC SQL END DECLARE SECTION; + +a = 1; +b = 2; +c = 3; +d = 4; + +EXEC SQL INSERT INTO test_complex VALUES (create_complex(:a, :b), create_complex(:c, :d)); + + has the same effect as + +EXEC SQL INSERT INTO test_complex VALUES ('(1,2)', '(3,4)'); + + + + + + + Indicators + + + The examples above do not handle null values. In fact, the + retrieval examples will raise an error if they fetch a null value + from the database. To be able to pass null values to the database + or retrieve null values from the database, you need to append a + second host variable specification to each host variable that + contains data. This second host variable is called the + indicator and contains a flag that tells + whether the datum is null, in which case the value of the real + host variable is ignored. Here is an example that handles the + retrieval of null values correctly: + +EXEC SQL BEGIN DECLARE SECTION; +VARCHAR val; +int val_ind; +EXEC SQL END DECLARE SECTION: + + ... + +EXEC SQL SELECT b INTO :val :val_ind FROM test1; + + The indicator variable val_ind will be zero if + the value was not null, and it will be negative if the value was + null. + + + + The indicator has another function: if the indicator value is + positive, it means that the value is not null, but it was + truncated when it was stored in the host variable. + + + + If the argument -r no_indicator is passed to + the preprocessor ecpg, it works in + no-indicator mode. In no-indicator mode, if no + indicator variable is specified, null values are signaled (on + input and output) for character string types as empty string and + for integer types as the lowest possible value for type (for + example, INT_MIN for int). + + +
+ + + Dynamic SQL + + + In many cases, the particular SQL statements that an application + has to execute are known at the time the application is written. + In some cases, however, the SQL statements are composed at run time + or provided by an external source. In these cases you cannot embed + the SQL statements directly into the C source code, but there is a + facility that allows you to call arbitrary SQL statements that you + provide in a string variable. + + + + Executing Statements without a Result Set + + + The simplest way to execute an arbitrary SQL statement is to use + the command EXECUTE IMMEDIATE. For example: + +EXEC SQL BEGIN DECLARE SECTION; +const char *stmt = "CREATE TABLE test1 (...);"; +EXEC SQL END DECLARE SECTION; + +EXEC SQL EXECUTE IMMEDIATE :stmt; + + EXECUTE IMMEDIATE can be used for SQL + statements that do not return a result set (e.g., + DDL, INSERT, UPDATE, + DELETE). You cannot execute statements that + retrieve data (e.g., SELECT) this way. The + next section describes how to do that. + + + + + Executing a Statement with Input Parameters + + + A more powerful way to execute arbitrary SQL statements is to + prepare them once and execute the prepared statement as often as + you like. It is also possible to prepare a generalized version of + a statement and then execute specific versions of it by + substituting parameters. When preparing the statement, write + question marks where you want to substitute parameters later. For + example: + +EXEC SQL BEGIN DECLARE SECTION; +const char *stmt = "INSERT INTO test1 VALUES(?, ?);"; +EXEC SQL END DECLARE SECTION; + +EXEC SQL PREPARE mystmt FROM :stmt; + ... +EXEC SQL EXECUTE mystmt USING 42, 'foobar'; + + + + + When you don't need the prepared statement anymore, you should + deallocate it: + +EXEC SQL DEALLOCATE PREPARE name; + + + + + + Executing a Statement with a Result Set + + + To execute an SQL statement with a single result row, + EXECUTE can be used. To save the result, add + an INTO clause. + ?"; +int v1, v2; +VARCHAR v3[50]; +EXEC SQL END DECLARE SECTION; + +EXEC SQL PREPARE mystmt FROM :stmt; + ... +EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37; +]]> + + An EXECUTE command can have an + INTO clause, a USING clause, + both, or neither. + + + + If a query is expected to return more than one result row, a + cursor should be used, as in the following example. + (See for more details about the + cursor.) + +EXEC SQL BEGIN DECLARE SECTION; +char dbaname[128]; +char datname[128]; +char *stmt = "SELECT u.usename as dbaname, d.datname " + " FROM pg_database d, pg_user u " + " WHERE d.datdba = u.usesysid"; +EXEC SQL END DECLARE SECTION; + +EXEC SQL CONNECT TO testdb AS con1 USER testuser; +EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + +EXEC SQL PREPARE stmt1 FROM :stmt; + +EXEC SQL DECLARE cursor1 CURSOR FOR stmt1; +EXEC SQL OPEN cursor1; + +EXEC SQL WHENEVER NOT FOUND DO BREAK; + +while (1) +{ + EXEC SQL FETCH cursor1 INTO :dbaname,:datname; + printf("dbaname=%s, datname=%s\n", dbaname, datname); +} + +EXEC SQL CLOSE cursor1; + +EXEC SQL COMMIT; +EXEC SQL DISCONNECT ALL; + + + + + + + pgtypes Library + + + The pgtypes library maps PostgreSQL database + types to C equivalents that can be used in C programs. It also offers + functions to do basic calculations with those types within C, i.e., without + the help of the PostgreSQL server. See the + following example: + + + + + + Character Strings + + Some functions such as PGTYPESnumeric_to_asc return + a pointer to a freshly allocated character string. These results should be + freed with PGTYPESchar_free instead of + free. (This is important only on Windows, where + memory allocation and release sometimes need to be done by the same + library.) + + + + + The numeric Type + + The numeric type offers to do calculations with arbitrary precision. See + for the equivalent type in the + PostgreSQL server. Because of the arbitrary precision this + variable needs to be able to expand and shrink dynamically. That's why you + can only create numeric variables on the heap, by means of the + PGTYPESnumeric_new and PGTYPESnumeric_free + functions. The decimal type, which is similar but limited in precision, + can be created on the stack as well as on the heap. + + + The following functions can be used to work with the numeric type: + + + PGTYPESnumeric_new + + + Request a pointer to a newly allocated numeric variable. + +numeric *PGTYPESnumeric_new(void); + + + + + + + PGTYPESnumeric_free + + + Free a numeric type, release all of its memory. + +void PGTYPESnumeric_free(numeric *var); + + + + + + + PGTYPESnumeric_from_asc + + + Parse a numeric type from its string notation. + +numeric *PGTYPESnumeric_from_asc(char *str, char **endptr); + + Valid formats are for example: + -2, + .794, + +3.44, + 592.49E07 or + -32.84e-4. + If the value could be parsed successfully, a valid pointer is returned, + else the NULL pointer. At the moment ECPG always parses the complete + string and so it currently does not support to store the address of the + first invalid character in *endptr. You can safely + set endptr to NULL. + + + + + + PGTYPESnumeric_to_asc + + + Returns a pointer to a string allocated by malloc that contains the string + representation of the numeric type num. + +char *PGTYPESnumeric_to_asc(numeric *num, int dscale); + + The numeric value will be printed with dscale decimal + digits, with rounding applied if necessary. + The result must be freed with PGTYPESchar_free(). + + + + + + PGTYPESnumeric_add + + + Add two numeric variables into a third one. + +int PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result); + + The function adds the variables var1 and + var2 into the result variable + result. + The function returns 0 on success and -1 in case of error. + + + + + + PGTYPESnumeric_sub + + + Subtract two numeric variables and return the result in a third one. + +int PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result); + + The function subtracts the variable var2 from + the variable var1. The result of the operation is + stored in the variable result. + The function returns 0 on success and -1 in case of error. + + + + + + PGTYPESnumeric_mul + + + Multiply two numeric variables and return the result in a third one. + +int PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result); + + The function multiplies the variables var1 and + var2. The result of the operation is stored in the + variable result. + The function returns 0 on success and -1 in case of error. + + + + + + PGTYPESnumeric_div + + + Divide two numeric variables and return the result in a third one. + +int PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result); + + The function divides the variables var1 by + var2. The result of the operation is stored in the + variable result. + The function returns 0 on success and -1 in case of error. + + + + + + PGTYPESnumeric_cmp + + + Compare two numeric variables. + +int PGTYPESnumeric_cmp(numeric *var1, numeric *var2) + + This function compares two numeric variables. In case of error, + INT_MAX is returned. On success, the function + returns one of three possible results: + + + + 1, if var1 is bigger than var2 + + + + + -1, if var1 is smaller than var2 + + + + + 0, if var1 and var2 are equal + + + + + + + + + PGTYPESnumeric_from_int + + + Convert an int variable to a numeric variable. + +int PGTYPESnumeric_from_int(signed int int_val, numeric *var); + + This function accepts a variable of type signed int and stores it + in the numeric variable var. Upon success, 0 is returned and + -1 in case of a failure. + + + + + + PGTYPESnumeric_from_long + + + Convert a long int variable to a numeric variable. + +int PGTYPESnumeric_from_long(signed long int long_val, numeric *var); + + This function accepts a variable of type signed long int and stores it + in the numeric variable var. Upon success, 0 is returned and + -1 in case of a failure. + + + + + + PGTYPESnumeric_copy + + + Copy over one numeric variable into another one. + +int PGTYPESnumeric_copy(numeric *src, numeric *dst); + + This function copies over the value of the variable that + src points to into the variable that dst + points to. It returns 0 on success and -1 if an error occurs. + + + + + + PGTYPESnumeric_from_double + + + Convert a variable of type double to a numeric. + +int PGTYPESnumeric_from_double(double d, numeric *dst); + + This function accepts a variable of type double and stores the result + in the variable that dst points to. It returns 0 on success + and -1 if an error occurs. + + + + + + PGTYPESnumeric_to_double + + + Convert a variable of type numeric to double. + +int PGTYPESnumeric_to_double(numeric *nv, double *dp) + + The function converts the numeric value from the variable that + nv points to into the double variable that dp points + to. It returns 0 on success and -1 if an error occurs, including + overflow. On overflow, the global variable errno will be set + to PGTYPES_NUM_OVERFLOW additionally. + + + + + + PGTYPESnumeric_to_int + + + Convert a variable of type numeric to int. + +int PGTYPESnumeric_to_int(numeric *nv, int *ip); + + The function converts the numeric value from the variable that + nv points to into the integer variable that ip + points to. It returns 0 on success and -1 if an error occurs, including + overflow. On overflow, the global variable errno will be set + to PGTYPES_NUM_OVERFLOW additionally. + + + + + + PGTYPESnumeric_to_long + + + Convert a variable of type numeric to long. + +int PGTYPESnumeric_to_long(numeric *nv, long *lp); + + The function converts the numeric value from the variable that + nv points to into the long integer variable that + lp points to. It returns 0 on success and -1 if an error + occurs, including overflow. On overflow, the global variable + errno will be set to PGTYPES_NUM_OVERFLOW + additionally. + + + + + + PGTYPESnumeric_to_decimal + + + Convert a variable of type numeric to decimal. + +int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst); + + The function converts the numeric value from the variable that + src points to into the decimal variable that + dst points to. It returns 0 on success and -1 if an error + occurs, including overflow. On overflow, the global variable + errno will be set to PGTYPES_NUM_OVERFLOW + additionally. + + + + + + PGTYPESnumeric_from_decimal + + + Convert a variable of type decimal to numeric. + +int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst); + + The function converts the decimal value from the variable that + src points to into the numeric variable that + dst points to. It returns 0 on success and -1 if an error + occurs. Since the decimal type is implemented as a limited version of + the numeric type, overflow cannot occur with this conversion. + + + + + + + + + The date Type + + The date type in C enables your programs to deal with data of the SQL type + date. See for the equivalent type in the + PostgreSQL server. + + + The following functions can be used to work with the date type: + + + PGTYPESdate_from_timestamp + + + Extract the date part from a timestamp. + +date PGTYPESdate_from_timestamp(timestamp dt); + + The function receives a timestamp as its only argument and returns the + extracted date part from this timestamp. + + + + + + PGTYPESdate_from_asc + + + Parse a date from its textual representation. + +date PGTYPESdate_from_asc(char *str, char **endptr); + + The function receives a C char* string str and a pointer to + a C char* string endptr. At the moment ECPG always parses + the complete string and so it currently does not support to store the + address of the first invalid character in *endptr. + You can safely set endptr to NULL. + + + Note that the function always assumes MDY-formatted dates and there is + currently no variable to change that within ECPG. + + + shows the allowed input formats. + + + Valid Input Formats for <function>PGTYPESdate_from_asc</function> + + + + Input + Result + + + + + January 8, 1999 + January 8, 1999 + + + 1999-01-08 + January 8, 1999 + + + 1/8/1999 + January 8, 1999 + + + 1/18/1999 + January 18, 1999 + + + 01/02/03 + February 1, 2003 + + + 1999-Jan-08 + January 8, 1999 + + + Jan-08-1999 + January 8, 1999 + + + 08-Jan-1999 + January 8, 1999 + + + 99-Jan-08 + January 8, 1999 + + + 08-Jan-99 + January 8, 1999 + + + 08-Jan-06 + January 8, 2006 + + + Jan-08-99 + January 8, 1999 + + + 19990108 + ISO 8601; January 8, 1999 + + + 990108 + ISO 8601; January 8, 1999 + + + 1999.008 + year and day of year + + + J2451187 + Julian day + + + January 8, 99 BC + year 99 before the Common Era + + + +
+
+
+ + + PGTYPESdate_to_asc + + + Return the textual representation of a date variable. + +char *PGTYPESdate_to_asc(date dDate); + + The function receives the date dDate as its only parameter. + It will output the date in the form 1999-01-18, i.e., in the + YYYY-MM-DD format. + The result must be freed with PGTYPESchar_free(). + + + + + + PGTYPESdate_julmdy + + + Extract the values for the day, the month and the year from a variable + of type date. + +void PGTYPESdate_julmdy(date d, int *mdy); + + + The function receives the date d and a pointer to an array + of 3 integer values mdy. The variable name indicates + the sequential order: mdy[0] will be set to contain the + number of the month, mdy[1] will be set to the value of the + day and mdy[2] will contain the year. + + + + + + PGTYPESdate_mdyjul + + + Create a date value from an array of 3 integers that specify the + day, the month and the year of the date. + +void PGTYPESdate_mdyjul(int *mdy, date *jdate); + + The function receives the array of the 3 integers (mdy) as + its first argument and as its second argument a pointer to a variable + of type date that should hold the result of the operation. + + + + + + PGTYPESdate_dayofweek + + + Return a number representing the day of the week for a date value. + +int PGTYPESdate_dayofweek(date d); + + The function receives the date variable d as its only + argument and returns an integer that indicates the day of the week for + this date. + + + + 0 - Sunday + + + + + 1 - Monday + + + + + 2 - Tuesday + + + + + 3 - Wednesday + + + + + 4 - Thursday + + + + + 5 - Friday + + + + + 6 - Saturday + + + + + + + + + PGTYPESdate_today + + + Get the current date. + +void PGTYPESdate_today(date *d); + + The function receives a pointer to a date variable (d) + that it sets to the current date. + + + + + + PGTYPESdate_fmt_asc + + + Convert a variable of type date to its textual representation using a + format mask. + +int PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf); + + The function receives the date to convert (dDate), the + format mask (fmtstring) and the string that will hold the + textual representation of the date (outbuf). + + + On success, 0 is returned and a negative value if an error occurred. + + + The following literals are the field specifiers you can use: + + + + dd - The number of the day of the month. + + + + + mm - The number of the month of the year. + + + + + yy - The number of the year as a two digit number. + + + + + yyyy - The number of the year as a four digit number. + + + + + ddd - The name of the day (abbreviated). + + + + + mmm - The name of the month (abbreviated). + + + + All other characters are copied 1:1 to the output string. + + + indicates a few possible formats. This will give + you an idea of how to use this function. All output lines are based on + the same date: November 23, 1959. + + + Valid Input Formats for <function>PGTYPESdate_fmt_asc</function> + + + + Format + Result + + + + + mmddyy + 112359 + + + ddmmyy + 231159 + + + yymmdd + 591123 + + + yy/mm/dd + 59/11/23 + + + yy mm dd + 59 11 23 + + + yy.mm.dd + 59.11.23 + + + .mm.yyyy.dd. + .11.1959.23. + + + mmm. dd, yyyy + Nov. 23, 1959 + + + mmm dd yyyy + Nov 23 1959 + + + yyyy dd mm + 1959 23 11 + + + ddd, mmm. dd, yyyy + Mon, Nov. 23, 1959 + + + (ddd) mmm. dd, yyyy + (Mon) Nov. 23, 1959 + + + +
+
+
+ + + PGTYPESdate_defmt_asc + + + Use a format mask to convert a C char* string to a value of type + date. + +int PGTYPESdate_defmt_asc(date *d, char *fmt, char *str); + + + The function receives a pointer to the date value that should hold the + result of the operation (d), the format mask to use for + parsing the date (fmt) and the C char* string containing + the textual representation of the date (str). The textual + representation is expected to match the format mask. However you do not + need to have a 1:1 mapping of the string to the format mask. The + function only analyzes the sequential order and looks for the literals + yy or yyyy that indicate the + position of the year, mm to indicate the position of + the month and dd to indicate the position of the + day. + + + indicates a few possible formats. This will give + you an idea of how to use this function. + + + Valid Input Formats for <function>rdefmtdate</function> + + + + Format + String + Result + + + + + ddmmyy + 21-2-54 + 1954-02-21 + + + ddmmyy + 2-12-54 + 1954-12-02 + + + ddmmyy + 20111954 + 1954-11-20 + + + ddmmyy + 130464 + 1964-04-13 + + + mmm.dd.yyyy + MAR-12-1967 + 1967-03-12 + + + yy/mm/dd + 1954, February 3rd + 1954-02-03 + + + mmm.dd.yyyy + 041269 + 1969-04-12 + + + yy/mm/dd + In the year 2525, in the month of July, mankind will be alive on the 28th day + 2525-07-28 + + + dd-mm-yy + I said on the 28th of July in the year 2525 + 2525-07-28 + + + mmm.dd.yyyy + 9/14/58 + 1958-09-14 + + + yy/mm/dd + 47/03/29 + 1947-03-29 + + + mmm.dd.yyyy + oct 28 1975 + 1975-10-28 + + + mmddyy + Nov 14th, 1985 + 1985-11-14 + + + +
+
+
+
+
+
+ + + The timestamp Type + + The timestamp type in C enables your programs to deal with data of the SQL + type timestamp. See for the equivalent + type in the PostgreSQL server. + + + The following functions can be used to work with the timestamp type: + + + PGTYPEStimestamp_from_asc + + + Parse a timestamp from its textual representation into a timestamp + variable. + +timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr); + + The function receives the string to parse (str) and a + pointer to a C char* (endptr). + At the moment ECPG always parses + the complete string and so it currently does not support to store the + address of the first invalid character in *endptr. + You can safely set endptr to NULL. + + + The function returns the parsed timestamp on success. On error, + PGTYPESInvalidTimestamp is returned and errno is + set to PGTYPES_TS_BAD_TIMESTAMP. See for important notes on this value. + + + In general, the input string can contain any combination of an allowed + date specification, a whitespace character and an allowed time + specification. Note that time zones are not supported by ECPG. It can + parse them but does not apply any calculation as the + PostgreSQL server does for example. Timezone + specifiers are silently discarded. + + + contains a few examples for input strings. + + + Valid Input Formats for <function>PGTYPEStimestamp_from_asc</function> + + + + Input + Result + + + + + 1999-01-08 04:05:06 + 1999-01-08 04:05:06 + + + January 8 04:05:06 1999 PST + 1999-01-08 04:05:06 + + + 1999-Jan-08 04:05:06.789-8 + 1999-01-08 04:05:06.789 (time zone specifier ignored) + + + J2451187 04:05-08:00 + 1999-01-08 04:05:00 (time zone specifier ignored) + + + +
+
+
+ + + PGTYPEStimestamp_to_asc + + + Converts a date to a C char* string. + +char *PGTYPEStimestamp_to_asc(timestamp tstamp); + + The function receives the timestamp tstamp as + its only argument and returns an allocated string that contains the + textual representation of the timestamp. + The result must be freed with PGTYPESchar_free(). + + + + + + PGTYPEStimestamp_current + + + Retrieve the current timestamp. + +void PGTYPEStimestamp_current(timestamp *ts); + + The function retrieves the current timestamp and saves it into the + timestamp variable that ts points to. + + + + + + PGTYPEStimestamp_fmt_asc + + + Convert a timestamp variable to a C char* using a format mask. + +int PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char *fmtstr); + + The function receives a pointer to the timestamp to convert as its + first argument (ts), a pointer to the output buffer + (output), the maximal length that has been allocated for + the output buffer (str_len) and the format mask to + use for the conversion (fmtstr). + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + You can use the following format specifiers for the format mask. The + format specifiers are the same ones that are used in the + strftime function in libc. Any + non-format specifier will be copied into the output buffer. + + + + + %A - is replaced by national representation of + the full weekday name. + + + + + %a - is replaced by national representation of + the abbreviated weekday name. + + + + + %B - is replaced by national representation of + the full month name. + + + + + %b - is replaced by national representation of + the abbreviated month name. + + + + + %C - is replaced by (year / 100) as decimal + number; single digits are preceded by a zero. + + + + + %c - is replaced by national representation of + time and date. + + + + + %D - is equivalent to + %m/%d/%y. + + + + + %d - is replaced by the day of the month as a + decimal number (01–31). + + + + + %E* %O* - POSIX locale + extensions. The sequences + %Ec + %EC + %Ex + %EX + %Ey + %EY + %Od + %Oe + %OH + %OI + %Om + %OM + %OS + %Ou + %OU + %OV + %Ow + %OW + %Oy + are supposed to provide alternative representations. + + + Additionally %OB implemented to represent + alternative months names (used standalone, without day mentioned). + + + + + %e - is replaced by the day of month as a decimal + number (1–31); single digits are preceded by a blank. + + + + + %F - is equivalent to %Y-%m-%d. + + + + + %G - is replaced by a year as a decimal number + with century. This year is the one that contains the greater part of + the week (Monday as the first day of the week). + + + + + %g - is replaced by the same year as in + %G, but as a decimal number without century + (00–99). + + + + + %H - is replaced by the hour (24-hour clock) as a + decimal number (00–23). + + + + + %h - the same as %b. + + + + + %I - is replaced by the hour (12-hour clock) as a + decimal number (01–12). + + + + + %j - is replaced by the day of the year as a + decimal number (001–366). + + + + + %k - is replaced by the hour (24-hour clock) as a + decimal number (0–23); single digits are preceded by a blank. + + + + + %l - is replaced by the hour (12-hour clock) as a + decimal number (1–12); single digits are preceded by a blank. + + + + + %M - is replaced by the minute as a decimal + number (00–59). + + + + + %m - is replaced by the month as a decimal number + (01–12). + + + + + %n - is replaced by a newline. + + + + + %O* - the same as %E*. + + + + + %p - is replaced by national representation of + either ante meridiem or post meridiem as appropriate. + + + + + %R - is equivalent to %H:%M. + + + + + %r - is equivalent to %I:%M:%S + %p. + + + + + %S - is replaced by the second as a decimal + number (00–60). + + + + + %s - is replaced by the number of seconds since + the Epoch, UTC. + + + + + %T - is equivalent to %H:%M:%S + + + + + %t - is replaced by a tab. + + + + + %U - is replaced by the week number of the year + (Sunday as the first day of the week) as a decimal number (00–53). + + + + + %u - is replaced by the weekday (Monday as the + first day of the week) as a decimal number (1–7). + + + + + %V - is replaced by the week number of the year + (Monday as the first day of the week) as a decimal number (01–53). + If the week containing January 1 has four or more days in the new + year, then it is week 1; otherwise it is the last week of the + previous year, and the next week is week 1. + + + + + %v - is equivalent to + %e-%b-%Y. + + + + + %W - is replaced by the week number of the year + (Monday as the first day of the week) as a decimal number (00–53). + + + + + %w - is replaced by the weekday (Sunday as the + first day of the week) as a decimal number (0–6). + + + + + %X - is replaced by national representation of + the time. + + + + + %x - is replaced by national representation of + the date. + + + + + %Y - is replaced by the year with century as a + decimal number. + + + + + %y - is replaced by the year without century as a + decimal number (00–99). + + + + + %Z - is replaced by the time zone name. + + + + + %z - is replaced by the time zone offset from + UTC; a leading plus sign stands for east of UTC, a minus sign for + west of UTC, hours and minutes follow with two digits each and no + delimiter between them (common form for RFC 822 date headers). + + + + + %+ - is replaced by national representation of + the date and time. + + + + + %-* - GNU libc extension. Do not do any padding + when performing numerical outputs. + + + + + $_* - GNU libc extension. Explicitly specify space for padding. + + + + + %0* - GNU libc extension. Explicitly specify zero + for padding. + + + + + %% - is replaced by %. + + + + + + + + + PGTYPEStimestamp_sub + + + Subtract one timestamp from another one and save the result in a + variable of type interval. + +int PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv); + + The function will subtract the timestamp variable that ts2 + points to from the timestamp variable that ts1 points to + and will store the result in the interval variable that iv + points to. + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + + + + PGTYPEStimestamp_defmt_asc + + + Parse a timestamp value from its textual representation using a + formatting mask. + +int PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d); + + The function receives the textual representation of a timestamp in the + variable str as well as the formatting mask to use in the + variable fmt. The result will be stored in the variable + that d points to. + + + If the formatting mask fmt is NULL, the function will fall + back to the default formatting mask which is %Y-%m-%d + %H:%M:%S. + + + This is the reverse function to . See the documentation there in + order to find out about the possible formatting mask entries. + + + + + + PGTYPEStimestamp_add_interval + + + Add an interval variable to a timestamp variable. + +int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout); + + The function receives a pointer to a timestamp variable tin + and a pointer to an interval variable span. It adds the + interval to the timestamp and saves the resulting timestamp in the + variable that tout points to. + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + + + + PGTYPEStimestamp_sub_interval + + + Subtract an interval variable from a timestamp variable. + +int PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout); + + The function subtracts the interval variable that span + points to from the timestamp variable that tin points to + and saves the result into the variable that tout points + to. + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + +
+
+
+ + + The interval Type + + The interval type in C enables your programs to deal with data of the SQL + type interval. See for the equivalent + type in the PostgreSQL server. + + + The following functions can be used to work with the interval type: + + + + PGTYPESinterval_new + + + Return a pointer to a newly allocated interval variable. + +interval *PGTYPESinterval_new(void); + + + + + + + PGTYPESinterval_free + + + Release the memory of a previously allocated interval variable. + +void PGTYPESinterval_free(interval *intvl); + + + + + + + PGTYPESinterval_from_asc + + + Parse an interval from its textual representation. + +interval *PGTYPESinterval_from_asc(char *str, char **endptr); + + The function parses the input string str and returns a + pointer to an allocated interval variable. + At the moment ECPG always parses + the complete string and so it currently does not support to store the + address of the first invalid character in *endptr. + You can safely set endptr to NULL. + + + + + + PGTYPESinterval_to_asc + + + Convert a variable of type interval to its textual representation. + +char *PGTYPESinterval_to_asc(interval *span); + + The function converts the interval variable that span + points to into a C char*. The output looks like this example: + @ 1 day 12 hours 59 mins 10 secs. + The result must be freed with PGTYPESchar_free(). + + + + + + PGTYPESinterval_copy + + + Copy a variable of type interval. + +int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest); + + The function copies the interval variable that intvlsrc + points to into the variable that intvldest points to. Note + that you need to allocate the memory for the destination variable + before. + + + + + + + + + The decimal Type + + The decimal type is similar to the numeric type. However it is limited to + a maximum precision of 30 significant digits. In contrast to the numeric + type which can be created on the heap only, the decimal type can be + created either on the stack or on the heap (by means of the functions + PGTYPESdecimal_new and + PGTYPESdecimal_free). + There are a lot of other functions that deal with the decimal type in the + Informix compatibility mode described in . + + + The following functions can be used to work with the decimal type and are + not only contained in the libcompat library. + + + PGTYPESdecimal_new + + + Request a pointer to a newly allocated decimal variable. + +decimal *PGTYPESdecimal_new(void); + + + + + + + PGTYPESdecimal_free + + + Free a decimal type, release all of its memory. + +void PGTYPESdecimal_free(decimal *var); + + + + + + + + + + errno Values of pgtypeslib + + + + PGTYPES_NUM_BAD_NUMERIC + + + An argument should contain a numeric variable (or point to a numeric + variable) but in fact its in-memory representation was invalid. + + + + + + PGTYPES_NUM_OVERFLOW + + + An overflow occurred. Since the numeric type can deal with almost + arbitrary precision, converting a numeric variable into other types + might cause overflow. + + + + + + PGTYPES_NUM_UNDERFLOW + + + An underflow occurred. Since the numeric type can deal with almost + arbitrary precision, converting a numeric variable into other types + might cause underflow. + + + + + + PGTYPES_NUM_DIVIDE_ZERO + + + A division by zero has been attempted. + + + + + + PGTYPES_DATE_BAD_DATE + + + An invalid date string was passed to + the PGTYPESdate_from_asc function. + + + + + + PGTYPES_DATE_ERR_EARGS + + + Invalid arguments were passed to the + PGTYPESdate_defmt_asc function. + + + + + + PGTYPES_DATE_ERR_ENOSHORTDATE + + + An invalid token in the input string was found by the + PGTYPESdate_defmt_asc function. + + + + + + PGTYPES_INTVL_BAD_INTERVAL + + + An invalid interval string was passed to the + PGTYPESinterval_from_asc function, or an + invalid interval value was passed to the + PGTYPESinterval_to_asc function. + + + + + + PGTYPES_DATE_ERR_ENOTDMY + + + There was a mismatch in the day/month/year assignment in the + PGTYPESdate_defmt_asc function. + + + + + + PGTYPES_DATE_BAD_DAY + + + An invalid day of the month value was found by + the PGTYPESdate_defmt_asc function. + + + + + + PGTYPES_DATE_BAD_MONTH + + + An invalid month value was found by + the PGTYPESdate_defmt_asc function. + + + + + + PGTYPES_TS_BAD_TIMESTAMP + + + An invalid timestamp string pass passed to + the PGTYPEStimestamp_from_asc function, + or an invalid timestamp value was passed to + the PGTYPEStimestamp_to_asc function. + + + + + + PGTYPES_TS_ERR_EINFTIME + + + An infinite timestamp value was encountered in a context that + cannot handle it. + + + + + + + + + Special Constants of pgtypeslib + + + + PGTYPESInvalidTimestamp + + + A value of type timestamp representing an invalid time stamp. This is + returned by the function PGTYPEStimestamp_from_asc on + parse error. + Note that due to the internal representation of the timestamp data type, + PGTYPESInvalidTimestamp is also a valid timestamp at + the same time. It is set to 1899-12-31 23:59:59. In order + to detect errors, make sure that your application does not only test + for PGTYPESInvalidTimestamp but also for + errno != 0 after each call to + PGTYPEStimestamp_from_asc. + + + + + + +
+ + + Using Descriptor Areas + + + An SQL descriptor area is a more sophisticated method for processing + the result of a SELECT, FETCH or + a DESCRIBE statement. An SQL descriptor area groups + the data of one row of data together with metadata items into one + data structure. The metadata is particularly useful when executing + dynamic SQL statements, where the nature of the result columns might + not be known ahead of time. PostgreSQL provides two ways to use + Descriptor Areas: the named SQL Descriptor Areas and the C-structure + SQLDAs. + + + + Named SQL Descriptor Areas + + + A named SQL descriptor area consists of a header, which contains + information concerning the entire descriptor, and one or more item + descriptor areas, which basically each describe one column in the + result row. + + + + Before you can use an SQL descriptor area, you need to allocate one: + +EXEC SQL ALLOCATE DESCRIPTOR identifier; + + The identifier serves as the variable name of the + descriptor area. + When you don't need the descriptor anymore, you should deallocate + it: + +EXEC SQL DEALLOCATE DESCRIPTOR identifier; + + + + + To use a descriptor area, specify it as the storage target in an + INTO clause, instead of listing host variables: + +EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc; + + If the result set is empty, the Descriptor Area will still contain + the metadata from the query, i.e., the field names. + + + + For not yet executed prepared queries, the DESCRIBE + statement can be used to get the metadata of the result set: + +EXEC SQL BEGIN DECLARE SECTION; +char *sql_stmt = "SELECT * FROM table1"; +EXEC SQL END DECLARE SECTION; + +EXEC SQL PREPARE stmt1 FROM :sql_stmt; +EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc; + + + + + Before PostgreSQL 9.0, the SQL keyword was optional, + so using DESCRIPTOR and SQL DESCRIPTOR + produced named SQL Descriptor Areas. Now it is mandatory, omitting + the SQL keyword produces SQLDA Descriptor Areas, + see . + + + + In DESCRIBE and FETCH statements, + the INTO and USING keywords can be + used to similarly: they produce the result set and the metadata in a + Descriptor Area. + + + + Now how do you get the data out of the descriptor area? You can + think of the descriptor area as a structure with named fields. To + retrieve the value of a field from the header and store it into a + host variable, use the following command: + +EXEC SQL GET DESCRIPTOR name :hostvar = field; + + Currently, there is only one header field defined: + COUNT, which tells how many item + descriptor areas exist (that is, how many columns are contained in + the result). The host variable needs to be of an integer type. To + get a field from the item descriptor area, use the following + command: + +EXEC SQL GET DESCRIPTOR name VALUE num :hostvar = field; + + num can be a literal integer or a host + variable containing an integer. Possible fields are: + + + + CARDINALITY (integer) + + + number of rows in the result set + + + + + + DATA + + + actual data item (therefore, the data type of this field + depends on the query) + + + + + + DATETIME_INTERVAL_CODE (integer) + + + When TYPE is 9, + DATETIME_INTERVAL_CODE will have a value of + 1 for DATE, + 2 for TIME, + 3 for TIMESTAMP, + 4 for TIME WITH TIME ZONE, or + 5 for TIMESTAMP WITH TIME ZONE. + + + + + + DATETIME_INTERVAL_PRECISION (integer) + + + not implemented + + + + + + INDICATOR (integer) + + + the indicator (indicating a null value or a value truncation) + + + + + + KEY_MEMBER (integer) + + + not implemented + + + + + + LENGTH (integer) + + + length of the datum in characters + + + + + + NAME (string) + + + name of the column + + + + + + NULLABLE (integer) + + + not implemented + + + + + + OCTET_LENGTH (integer) + + + length of the character representation of the datum in bytes + + + + + + PRECISION (integer) + + + precision (for type numeric) + + + + + + RETURNED_LENGTH (integer) + + + length of the datum in characters + + + + + + RETURNED_OCTET_LENGTH (integer) + + + length of the character representation of the datum in bytes + + + + + + SCALE (integer) + + + scale (for type numeric) + + + + + + TYPE (integer) + + + numeric code of the data type of the column + + + + + + + + In EXECUTE, DECLARE and OPEN + statements, the effect of the INTO and USING + keywords are different. A Descriptor Area can also be manually built to + provide the input parameters for a query or a cursor and + USING SQL DESCRIPTOR name + is the way to pass the input parameters into a parameterized query. The statement + to build a named SQL Descriptor Area is below: + +EXEC SQL SET DESCRIPTOR name VALUE num field = :hostvar; + + + + + PostgreSQL supports retrieving more that one record in one FETCH + statement and storing the data in host variables in this case assumes that the + variable is an array. E.g.: + +EXEC SQL BEGIN DECLARE SECTION; +int id[5]; +EXEC SQL END DECLARE SECTION; + +EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc; + +EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA; + + + + + + + + SQLDA Descriptor Areas + + + An SQLDA Descriptor Area is a C language structure which can be also used + to get the result set and the metadata of a query. One structure stores one + record from the result set. + +EXEC SQL include sqlda.h; +sqlda_t *mysqlda; + +EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda; + + Note that the SQL keyword is omitted. The paragraphs about + the use cases of the INTO and USING + keywords in also apply here with an addition. + In a DESCRIBE statement the DESCRIPTOR + keyword can be completely omitted if the INTO keyword is used: + +EXEC SQL DESCRIBE prepared_statement INTO mysqlda; + + + + + + The general flow of a program that uses SQLDA is: + + Prepare a query, and declare a cursor for it. + Declare an SQLDA for the result rows. + Declare an SQLDA for the input parameters, and initialize them (memory allocation, parameter settings). + Open a cursor with the input SQLDA. + Fetch rows from the cursor, and store them into an output SQLDA. + Read values from the output SQLDA into the host variables (with conversion if necessary). + Close the cursor. + Free the memory area allocated for the input SQLDA. + + + + SQLDA Data Structure + + + SQLDA uses three data structure + types: sqlda_t, sqlvar_t, + and struct sqlname. + + + + + PostgreSQL's SQLDA has a similar data structure to the one in + IBM DB2 Universal Database, so some technical information on + DB2's SQLDA could help understanding PostgreSQL's one better. + + + + + sqlda_t Structure + + + The structure type sqlda_t is the type of the + actual SQLDA. It holds one record. And two or + more sqlda_t structures can be connected in a + linked list with the pointer in + the desc_next field, thus + representing an ordered collection of rows. So, when two or + more rows are fetched, the application can read them by + following the desc_next pointer in + each sqlda_t node. + + + + The definition of sqlda_t is: + +struct sqlda_struct +{ + char sqldaid[8]; + long sqldabc; + short sqln; + short sqld; + struct sqlda_struct *desc_next; + struct sqlvar_struct sqlvar[1]; +}; + +typedef struct sqlda_struct sqlda_t; + + + The meaning of the fields is: + + + + sqldaid + + + It contains the literal string "SQLDA ". + + + + + + sqldabc + + + It contains the size of the allocated space in bytes. + + + + + + sqln + + + It contains the number of input parameters for a parameterized query in + case it's passed into OPEN, DECLARE or + EXECUTE statements using the USING + keyword. In case it's used as output of SELECT, + EXECUTE or FETCH statements, + its value is the same as sqld + statement + + + + + + sqld + + + It contains the number of fields in a result set. + + + + + + desc_next + + + If the query returns more than one record, multiple linked + SQLDA structures are returned, and desc_next holds + a pointer to the next entry in the list. + + + + + sqlvar + + + This is the array of the columns in the result set. + + + + + + + + + sqlvar_t Structure + + + The structure type sqlvar_t holds a column value + and metadata such as type and length. The definition of the type + is: + + +struct sqlvar_struct +{ + short sqltype; + short sqllen; + char *sqldata; + short *sqlind; + struct sqlname sqlname; +}; + +typedef struct sqlvar_struct sqlvar_t; + + + The meaning of the fields is: + + + + sqltype + + + Contains the type identifier of the field. For values, + see enum ECPGttype in ecpgtype.h. + + + + + + sqllen + + + Contains the binary length of the field. e.g., 4 bytes for ECPGt_int. + + + + + + sqldata + + + Points to the data. The format of the data is described + in . + + + + + + sqlind + + + Points to the null indicator. 0 means not null, -1 means + null. + + + + + + sqlname + + + The name of the field. + + + + + + + + + struct sqlname Structure + + + A struct sqlname structure holds a column name. It + is used as a member of the sqlvar_t structure. The + definition of the structure is: + +#define NAMEDATALEN 64 + +struct sqlname +{ + short length; + char data[NAMEDATALEN]; +}; + + The meaning of the fields is: + + + length + + + Contains the length of the field name. + + + + + data + + + Contains the actual field name. + + + + + + + + + + Retrieving a Result Set Using an SQLDA + + + + The general steps to retrieve a query result set through an + SQLDA are: + + Declare an sqlda_t structure to receive the result set. + Execute FETCH/EXECUTE/DESCRIBE commands to process a query specifying the declared SQLDA. + Check the number of records in the result set by looking at sqln, a member of the sqlda_t structure. + Get the values of each column from sqlvar[0], sqlvar[1], etc., members of the sqlda_t structure. + Go to next row (sqlda_t structure) by following the desc_next pointer, a member of the sqlda_t structure. + Repeat above as you need. + + + + Here is an example retrieving a result set through an SQLDA. + + + + First, declare a sqlda_t structure to receive the result set. + +sqlda_t *sqlda1; + + + + + Next, specify the SQLDA in a command. This is + a FETCH command example. + +EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1; + + + + + Run a loop following the linked list to retrieve the rows. + +sqlda_t *cur_sqlda; + +for (cur_sqlda = sqlda1; + cur_sqlda != NULL; + cur_sqlda = cur_sqlda->desc_next) +{ + ... +} + + + + + Inside the loop, run another loop to retrieve each column data + (sqlvar_t structure) of the row. + +for (i = 0; i < cur_sqlda->sqld; i++) +{ + sqlvar_t v = cur_sqlda->sqlvar[i]; + char *sqldata = v.sqldata; + short sqllen = v.sqllen; + ... +} + + + + + To get a column value, check the sqltype value, + a member of the sqlvar_t structure. Then, switch + to an appropriate way, depending on the column type, to copy + data from the sqlvar field to a host variable. + +char var_buf[1024]; + +switch (v.sqltype) +{ + case ECPGt_char: + memset(&var_buf, 0, sizeof(var_buf)); + memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf) - 1 : sqllen)); + break; + + case ECPGt_int: /* integer */ + memcpy(&intval, sqldata, sqllen); + snprintf(var_buf, sizeof(var_buf), "%d", intval); + break; + + ... +} + + + + + + Passing Query Parameters Using an SQLDA + + + + The general steps to use an SQLDA to pass input + parameters to a prepared query are: + + Create a prepared query (prepared statement) + Declare an sqlda_t structure as an input SQLDA. + Allocate memory area (as sqlda_t structure) for the input SQLDA. + Set (copy) input values in the allocated memory. + Open a cursor with specifying the input SQLDA. + + + + Here is an example. + + + + First, create a prepared statement. + +EXEC SQL BEGIN DECLARE SECTION; +char query[1024] = "SELECT d.oid, * FROM pg_database d, pg_stat_database s WHERE d.oid = s.datid AND (d.datname = ? OR d.oid = ?)"; +EXEC SQL END DECLARE SECTION; + +EXEC SQL PREPARE stmt1 FROM :query; + + + + + Next, allocate memory for an SQLDA, and set the number of input + parameters in sqln, a member variable of + the sqlda_t structure. When two or more input + parameters are required for the prepared query, the application + has to allocate additional memory space which is calculated by + (nr. of params - 1) * sizeof(sqlvar_t). The example shown here + allocates memory space for two input parameters. + +sqlda_t *sqlda2; + +sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t)); +memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t)); + +sqlda2->sqln = 2; /* number of input variables */ + + + + + After memory allocation, store the parameter values into the + sqlvar[] array. (This is same array used for + retrieving column values when the SQLDA is receiving a result + set.) In this example, the input parameters + are "postgres", having a string type, + and 1, having an integer type. + +sqlda2->sqlvar[0].sqltype = ECPGt_char; +sqlda2->sqlvar[0].sqldata = "postgres"; +sqlda2->sqlvar[0].sqllen = 8; + +int intval = 1; +sqlda2->sqlvar[1].sqltype = ECPGt_int; +sqlda2->sqlvar[1].sqldata = (char *) &intval; +sqlda2->sqlvar[1].sqllen = sizeof(intval); + + + + + By opening a cursor and specifying the SQLDA that was set up + beforehand, the input parameters are passed to the prepared + statement. + +EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2; + + + + + Finally, after using input SQLDAs, the allocated memory space + must be freed explicitly, unlike SQLDAs used for receiving query + results. + +free(sqlda2); + + + + + + A Sample Application Using SQLDA + + + Here is an example program, which describes how to fetch access + statistics of the databases, specified by the input parameters, + from the system catalogs. + + + + This application joins two system tables, pg_database and + pg_stat_database on the database OID, and also fetches and shows + the database statistics which are retrieved by two input + parameters (a database postgres, and OID 1). + + + + First, declare an SQLDA for input and an SQLDA for output. + +EXEC SQL include sqlda.h; + +sqlda_t *sqlda1; /* an output descriptor */ +sqlda_t *sqlda2; /* an input descriptor */ + + + + + Next, connect to the database, prepare a statement, and declare a + cursor for the prepared statement. + +int +main(void) +{ + EXEC SQL BEGIN DECLARE SECTION; + char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )"; + EXEC SQL END DECLARE SECTION; + + EXEC SQL CONNECT TO testdb AS con1 USER testuser; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + EXEC SQL PREPARE stmt1 FROM :query; + EXEC SQL DECLARE cur1 CURSOR FOR stmt1; + + + + + Next, put some values in the input SQLDA for the input + parameters. Allocate memory for the input SQLDA, and set the + number of input parameters to sqln. Store + type, value, and value length into sqltype, + sqldata, and sqllen in the + sqlvar structure. + + + /* Create SQLDA structure for input parameters. */ + sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t)); + memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t)); + sqlda2->sqln = 2; /* number of input variables */ + + sqlda2->sqlvar[0].sqltype = ECPGt_char; + sqlda2->sqlvar[0].sqldata = "postgres"; + sqlda2->sqlvar[0].sqllen = 8; + + intval = 1; + sqlda2->sqlvar[1].sqltype = ECPGt_int; + sqlda2->sqlvar[1].sqldata = (char *)&intval; + sqlda2->sqlvar[1].sqllen = sizeof(intval); + + + + + After setting up the input SQLDA, open a cursor with the input + SQLDA. + + + /* Open a cursor with input parameters. */ + EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2; + + + + + Fetch rows into the output SQLDA from the opened cursor. + (Generally, you have to call FETCH repeatedly + in the loop, to fetch all rows in the result set.) + + while (1) + { + sqlda_t *cur_sqlda; + + /* Assign descriptor to the cursor */ + EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1; + + + + + Next, retrieve the fetched records from the SQLDA, by following + the linked list of the sqlda_t structure. + + for (cur_sqlda = sqlda1 ; + cur_sqlda != NULL ; + cur_sqlda = cur_sqlda->desc_next) + { + ... + + + + + Read each columns in the first record. The number of columns is + stored in sqld, the actual data of the first + column is stored in sqlvar[0], both members of + the sqlda_t structure. + + + /* Print every column in a row. */ + for (i = 0; i < sqlda1->sqld; i++) + { + sqlvar_t v = sqlda1->sqlvar[i]; + char *sqldata = v.sqldata; + short sqllen = v.sqllen; + + strncpy(name_buf, v.sqlname.data, v.sqlname.length); + name_buf[v.sqlname.length] = '\0'; + + + + + Now, the column data is stored in the variable v. + Copy every datum into host variables, looking + at v.sqltype for the type of the column. + + switch (v.sqltype) { + int intval; + double doubleval; + unsigned long long int longlongval; + + case ECPGt_char: + memset(&var_buf, 0, sizeof(var_buf)); + memcpy(&var_buf, sqldata, (sizeof(var_buf) <= sqllen ? sizeof(var_buf)-1 : sqllen)); + break; + + case ECPGt_int: /* integer */ + memcpy(&intval, sqldata, sqllen); + snprintf(var_buf, sizeof(var_buf), "%d", intval); + break; + + ... + + default: + ... + } + + printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype); + } + + + + + Close the cursor after processing all of records, and disconnect + from the database. + + EXEC SQL CLOSE cur1; + EXEC SQL COMMIT; + + EXEC SQL DISCONNECT ALL; + + + + + The whole program is shown + in . + + + + Example SQLDA Program + +#include <stdlib.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +EXEC SQL include sqlda.h; + +sqlda_t *sqlda1; /* descriptor for output */ +sqlda_t *sqlda2; /* descriptor for input */ + +EXEC SQL WHENEVER NOT FOUND DO BREAK; +EXEC SQL WHENEVER SQLERROR STOP; + +int +main(void) +{ + EXEC SQL BEGIN DECLARE SECTION; + char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )"; + + int intval; + unsigned long long int longlongval; + EXEC SQL END DECLARE SECTION; + + EXEC SQL CONNECT TO uptimedb AS con1 USER uptime; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + EXEC SQL PREPARE stmt1 FROM :query; + EXEC SQL DECLARE cur1 CURSOR FOR stmt1; + + /* Create an SQLDA structure for an input parameter */ + sqlda2 = (sqlda_t *)malloc(sizeof(sqlda_t) + sizeof(sqlvar_t)); + memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t)); + sqlda2->sqln = 2; /* a number of input variables */ + + sqlda2->sqlvar[0].sqltype = ECPGt_char; + sqlda2->sqlvar[0].sqldata = "postgres"; + sqlda2->sqlvar[0].sqllen = 8; + + intval = 1; + sqlda2->sqlvar[1].sqltype = ECPGt_int; + sqlda2->sqlvar[1].sqldata = (char *) &intval; + sqlda2->sqlvar[1].sqllen = sizeof(intval); + + /* Open a cursor with input parameters. */ + EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2; + + while (1) + { + sqlda_t *cur_sqlda; + + /* Assign descriptor to the cursor */ + EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1; + + for (cur_sqlda = sqlda1 ; + cur_sqlda != NULL ; + cur_sqlda = cur_sqlda->desc_next) + { + int i; + char name_buf[1024]; + char var_buf[1024]; + + /* Print every column in a row. */ + for (i=0 ; i<cur_sqlda->sqld ; i++) + { + sqlvar_t v = cur_sqlda->sqlvar[i]; + char *sqldata = v.sqldata; + short sqllen = v.sqllen; + + strncpy(name_buf, v.sqlname.data, v.sqlname.length); + name_buf[v.sqlname.length] = '\0'; + + switch (v.sqltype) + { + case ECPGt_char: + memset(&var_buf, 0, sizeof(var_buf)); + memcpy(&var_buf, sqldata, (sizeof(var_buf)<=sqllen ? sizeof(var_buf)-1 : sqllen) ); + break; + + case ECPGt_int: /* integer */ + memcpy(&intval, sqldata, sqllen); + snprintf(var_buf, sizeof(var_buf), "%d", intval); + break; + + case ECPGt_long_long: /* bigint */ + memcpy(&longlongval, sqldata, sqllen); + snprintf(var_buf, sizeof(var_buf), "%lld", longlongval); + break; + + default: + { + int i; + memset(var_buf, 0, sizeof(var_buf)); + for (i = 0; i < sqllen; i++) + { + char tmpbuf[16]; + snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", (unsigned char) sqldata[i]); + strncat(var_buf, tmpbuf, sizeof(var_buf)); + } + } + break; + } + + printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype); + } + + printf("\n"); + } + } + + EXEC SQL CLOSE cur1; + EXEC SQL COMMIT; + + EXEC SQL DISCONNECT ALL; + + return 0; +} + + + + The output of this example should look something like the + following (some numbers will vary). + + + +oid = 1 (type: 1) +datname = template1 (type: 1) +datdba = 10 (type: 1) +encoding = 0 (type: 5) +datistemplate = t (type: 1) +datallowconn = t (type: 1) +datconnlimit = -1 (type: 5) +datlastsysoid = 11510 (type: 1) +datfrozenxid = 379 (type: 1) +dattablespace = 1663 (type: 1) +datconfig = (type: 1) +datacl = {=c/uptime,uptime=CTc/uptime} (type: 1) +datid = 1 (type: 1) +datname = template1 (type: 1) +numbackends = 0 (type: 5) +xact_commit = 113606 (type: 9) +xact_rollback = 0 (type: 9) +blks_read = 130 (type: 9) +blks_hit = 7341714 (type: 9) +tup_returned = 38262679 (type: 9) +tup_fetched = 1836281 (type: 9) +tup_inserted = 0 (type: 9) +tup_updated = 0 (type: 9) +tup_deleted = 0 (type: 9) + +oid = 11511 (type: 1) +datname = postgres (type: 1) +datdba = 10 (type: 1) +encoding = 0 (type: 5) +datistemplate = f (type: 1) +datallowconn = t (type: 1) +datconnlimit = -1 (type: 5) +datlastsysoid = 11510 (type: 1) +datfrozenxid = 379 (type: 1) +dattablespace = 1663 (type: 1) +datconfig = (type: 1) +datacl = (type: 1) +datid = 11511 (type: 1) +datname = postgres (type: 1) +numbackends = 0 (type: 5) +xact_commit = 221069 (type: 9) +xact_rollback = 18 (type: 9) +blks_read = 1176 (type: 9) +blks_hit = 13943750 (type: 9) +tup_returned = 77410091 (type: 9) +tup_fetched = 3253694 (type: 9) +tup_inserted = 0 (type: 9) +tup_updated = 0 (type: 9) +tup_deleted = 0 (type: 9) + + + + + + + + Error Handling + + + This section describes how you can handle exceptional conditions + and warnings in an embedded SQL program. There are two + nonexclusive facilities for this. + + + + + Callbacks can be configured to handle warning and error + conditions using the WHENEVER command. + + + + + + Detailed information about the error or warning can be obtained + from the sqlca variable. + + + + + + + Setting Callbacks + + + One simple method to catch errors and warnings is to set a + specific action to be executed whenever a particular condition + occurs. In general: + +EXEC SQL WHENEVER condition action; + + + + + condition can be one of the following: + + + + SQLERROR + + + The specified action is called whenever an error occurs during + the execution of an SQL statement. + + + + + + SQLWARNING + + + The specified action is called whenever a warning occurs + during the execution of an SQL statement. + + + + + + NOT FOUND + + + The specified action is called whenever an SQL statement + retrieves or affects zero rows. (This condition is not an + error, but you might be interested in handling it specially.) + + + + + + + + action can be one of the following: + + + + CONTINUE + + + This effectively means that the condition is ignored. This is + the default. + + + + + + GOTO label + GO TO label + + + Jump to the specified label (using a C goto + statement). + + + + + + SQLPRINT + + + Print a message to standard error. This is useful for simple + programs or during prototyping. The details of the message + cannot be configured. + + + + + + STOP + + + Call exit(1), which will terminate the + program. + + + + + + DO BREAK + + + Execute the C statement break. This should + only be used in loops or switch statements. + + + + + + DO CONTINUE + + + Execute the C statement continue. This should + only be used in loops statements. if executed, will cause the flow + of control to return to the top of the loop. + + + + + + CALL name (args) + DO name (args) + + + Call the specified C functions with the specified arguments. (This + use is different from the meaning of CALL + and DO in the normal PostgreSQL grammar.) + + + + + + The SQL standard only provides for the actions + CONTINUE and GOTO (and + GO TO). + + + + Here is an example that you might want to use in a simple program. + It prints a simple message when a warning occurs and aborts the + program when an error happens: + +EXEC SQL WHENEVER SQLWARNING SQLPRINT; +EXEC SQL WHENEVER SQLERROR STOP; + + + + + The statement EXEC SQL WHENEVER is a directive + of the SQL preprocessor, not a C statement. The error or warning + actions that it sets apply to all embedded SQL statements that + appear below the point where the handler is set, unless a + different action was set for the same condition between the first + EXEC SQL WHENEVER and the SQL statement causing + the condition, regardless of the flow of control in the C program. + So neither of the two following C program excerpts will have the + desired effect: + +/* + * WRONG + */ +int main(int argc, char *argv[]) +{ + ... + if (verbose) { + EXEC SQL WHENEVER SQLWARNING SQLPRINT; + } + ... + EXEC SQL SELECT ...; + ... +} + + + +/* + * WRONG + */ +int main(int argc, char *argv[]) +{ + ... + set_error_handler(); + ... + EXEC SQL SELECT ...; + ... +} + +static void set_error_handler(void) +{ + EXEC SQL WHENEVER SQLERROR STOP; +} + + + + + + sqlca + + + For more powerful error handling, the embedded SQL interface + provides a global variable with the name sqlca + (SQL communication area) + that has the following structure: + +struct +{ + char sqlcaid[8]; + long sqlabc; + long sqlcode; + struct + { + int sqlerrml; + char sqlerrmc[SQLERRMC_LEN]; + } sqlerrm; + char sqlerrp[8]; + long sqlerrd[6]; + char sqlwarn[8]; + char sqlstate[5]; +} sqlca; + + (In a multithreaded program, every thread automatically gets its + own copy of sqlca. This works similarly to the + handling of the standard C global variable + errno.) + + + + sqlca covers both warnings and errors. If + multiple warnings or errors occur during the execution of a + statement, then sqlca will only contain + information about the last one. + + + + If no error occurred in the last SQL statement, + sqlca.sqlcode will be 0 and + sqlca.sqlstate will be + "00000". If a warning or error occurred, then + sqlca.sqlcode will be negative and + sqlca.sqlstate will be different from + "00000". A positive + sqlca.sqlcode indicates a harmless condition, + such as that the last query returned zero rows. + sqlcode and sqlstate are two + different error code schemes; details appear below. + + + + If the last SQL statement was successful, then + sqlca.sqlerrd[1] contains the OID of the + processed row, if applicable, and + sqlca.sqlerrd[2] contains the number of + processed or returned rows, if applicable to the command. + + + + In case of an error or warning, + sqlca.sqlerrm.sqlerrmc will contain a string + that describes the error. The field + sqlca.sqlerrm.sqlerrml contains the length of + the error message that is stored in + sqlca.sqlerrm.sqlerrmc (the result of + strlen(), not really interesting for a C + programmer). Note that some messages are too long to fit in the + fixed-size sqlerrmc array; they will be truncated. + + + + In case of a warning, sqlca.sqlwarn[2] is set + to W. (In all other cases, it is set to + something different from W.) If + sqlca.sqlwarn[1] is set to + W, then a value was truncated when it was + stored in a host variable. sqlca.sqlwarn[0] is + set to W if any of the other elements are set + to indicate a warning. + + + + The fields sqlcaid, + sqlabc, + sqlerrp, and the remaining elements of + sqlerrd and + sqlwarn currently contain no useful + information. + + + + The structure sqlca is not defined in the SQL + standard, but is implemented in several other SQL database + systems. The definitions are similar at the core, but if you want + to write portable applications, then you should investigate the + different implementations carefully. + + + + Here is one example that combines the use of WHENEVER + and sqlca, printing out the contents + of sqlca when an error occurs. This is perhaps + useful for debugging or prototyping applications, before + installing a more user-friendly error handler. + + +EXEC SQL WHENEVER SQLERROR CALL print_sqlca(); + +void +print_sqlca() +{ + fprintf(stderr, "==== sqlca ====\n"); + fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode); + fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml); + fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc); + fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2], + sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]); + fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2], + sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5], + sqlca.sqlwarn[6], sqlca.sqlwarn[7]); + fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate); + fprintf(stderr, "===============\n"); +} + + + The result could look as follows (here an error due to a + misspelled table name): + + +==== sqlca ==== +sqlcode: -400 +sqlerrm.sqlerrml: 49 +sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38 +sqlerrd: 0 0 0 0 0 0 +sqlwarn: 0 0 0 0 0 0 0 0 +sqlstate: 42P01 +=============== + + + + + + <literal>SQLSTATE</literal> vs. <literal>SQLCODE</literal> + + + The fields sqlca.sqlstate and + sqlca.sqlcode are two different schemes that + provide error codes. Both are derived from the SQL standard, but + SQLCODE has been marked deprecated in the SQL-92 + edition of the standard and has been dropped in later editions. + Therefore, new applications are strongly encouraged to use + SQLSTATE. + + + + SQLSTATE is a five-character array. The five + characters contain digits or upper-case letters that represent + codes of various error and warning conditions. + SQLSTATE has a hierarchical scheme: the first + two characters indicate the general class of the condition, the + last three characters indicate a subclass of the general + condition. A successful state is indicated by the code + 00000. The SQLSTATE codes are for + the most part defined in the SQL standard. The + PostgreSQL server natively supports + SQLSTATE error codes; therefore a high degree + of consistency can be achieved by using this error code scheme + throughout all applications. For further information see + . + + + + SQLCODE, the deprecated error code scheme, is a + simple integer. A value of 0 indicates success, a positive value + indicates success with additional information, a negative value + indicates an error. The SQL standard only defines the positive + value +100, which indicates that the last command returned or + affected zero rows, and no specific negative values. Therefore, + this scheme can only achieve poor portability and does not have a + hierarchical code assignment. Historically, the embedded SQL + processor for PostgreSQL has assigned + some specific SQLCODE values for its use, which + are listed below with their numeric value and their symbolic name. + Remember that these are not portable to other SQL implementations. + To simplify the porting of applications to the + SQLSTATE scheme, the corresponding + SQLSTATE is also listed. There is, however, no + one-to-one or one-to-many mapping between the two schemes (indeed + it is many-to-many), so you should consult the global + SQLSTATE listing in + in each case. + + + + These are the assigned SQLCODE values: + + + + 0 (ECPG_NO_ERROR) + + + Indicates no error. (SQLSTATE 00000) + + + + + + 100 (ECPG_NOT_FOUND) + + + This is a harmless condition indicating that the last command + retrieved or processed zero rows, or that you are at the end of + the cursor. (SQLSTATE 02000) + + + + When processing a cursor in a loop, you could use this code as + a way to detect when to abort the loop, like this: + +while (1) +{ + EXEC SQL FETCH ... ; + if (sqlca.sqlcode == ECPG_NOT_FOUND) + break; +} + + But WHENEVER NOT FOUND DO BREAK effectively + does this internally, so there is usually no advantage in + writing this out explicitly. + + + + + + -12 (ECPG_OUT_OF_MEMORY) + + + Indicates that your virtual memory is exhausted. The numeric + value is defined as -ENOMEM. (SQLSTATE + YE001) + + + + + + -200 (ECPG_UNSUPPORTED) + + + Indicates the preprocessor has generated something that the + library does not know about. Perhaps you are running + incompatible versions of the preprocessor and the + library. (SQLSTATE YE002) + + + + + + -201 (ECPG_TOO_MANY_ARGUMENTS) + + + This means that the command specified more host variables than + the command expected. (SQLSTATE 07001 or 07002) + + + + + + -202 (ECPG_TOO_FEW_ARGUMENTS) + + + This means that the command specified fewer host variables than + the command expected. (SQLSTATE 07001 or 07002) + + + + + + -203 (ECPG_TOO_MANY_MATCHES) + + + This means a query has returned multiple rows but the statement + was only prepared to store one result row (for example, because + the specified variables are not arrays). (SQLSTATE 21000) + + + + + + -204 (ECPG_INT_FORMAT) + + + The host variable is of type int and the datum in + the database is of a different type and contains a value that + cannot be interpreted as an int. The library uses + strtol() for this conversion. (SQLSTATE + 42804) + + + + + + -205 (ECPG_UINT_FORMAT) + + + The host variable is of type unsigned int and the + datum in the database is of a different type and contains a + value that cannot be interpreted as an unsigned + int. The library uses strtoul() + for this conversion. (SQLSTATE 42804) + + + + + + -206 (ECPG_FLOAT_FORMAT) + + + The host variable is of type float and the datum + in the database is of another type and contains a value that + cannot be interpreted as a float. The library + uses strtod() for this conversion. + (SQLSTATE 42804) + + + + + + -207 (ECPG_NUMERIC_FORMAT) + + + The host variable is of type numeric and the datum + in the database is of another type and contains a value that + cannot be interpreted as a numeric value. + (SQLSTATE 42804) + + + + + + -208 (ECPG_INTERVAL_FORMAT) + + + The host variable is of type interval and the datum + in the database is of another type and contains a value that + cannot be interpreted as an interval value. + (SQLSTATE 42804) + + + + + + -209 (ECPG_DATE_FORMAT) + + + The host variable is of type date and the datum in + the database is of another type and contains a value that + cannot be interpreted as a date value. + (SQLSTATE 42804) + + + + + + -210 (ECPG_TIMESTAMP_FORMAT) + + + The host variable is of type timestamp and the + datum in the database is of another type and contains a value + that cannot be interpreted as a timestamp value. + (SQLSTATE 42804) + + + + + + -211 (ECPG_CONVERT_BOOL) + + + This means the host variable is of type bool and + the datum in the database is neither 't' nor + 'f'. (SQLSTATE 42804) + + + + + + -212 (ECPG_EMPTY) + + + The statement sent to the PostgreSQL + server was empty. (This cannot normally happen in an embedded + SQL program, so it might point to an internal error.) (SQLSTATE + YE002) + + + + + + -213 (ECPG_MISSING_INDICATOR) + + + A null value was returned and no null indicator variable was + supplied. (SQLSTATE 22002) + + + + + + -214 (ECPG_NO_ARRAY) + + + An ordinary variable was used in a place that requires an + array. (SQLSTATE 42804) + + + + + + -215 (ECPG_DATA_NOT_ARRAY) + + + The database returned an ordinary variable in a place that + requires array value. (SQLSTATE 42804) + + + + + + -216 (ECPG_ARRAY_INSERT) + + + The value could not be inserted into the array. (SQLSTATE + 42804) + + + + + + -220 (ECPG_NO_CONN) + + + The program tried to access a connection that does not exist. + (SQLSTATE 08003) + + + + + + -221 (ECPG_NOT_CONN) + + + The program tried to access a connection that does exist but is + not open. (This is an internal error.) (SQLSTATE YE002) + + + + + + -230 (ECPG_INVALID_STMT) + + + The statement you are trying to use has not been prepared. + (SQLSTATE 26000) + + + + + + -239 (ECPG_INFORMIX_DUPLICATE_KEY) + + + Duplicate key error, violation of unique constraint (Informix + compatibility mode). (SQLSTATE 23505) + + + + + + -240 (ECPG_UNKNOWN_DESCRIPTOR) + + + The descriptor specified was not found. The statement you are + trying to use has not been prepared. (SQLSTATE 33000) + + + + + + -241 (ECPG_INVALID_DESCRIPTOR_INDEX) + + + The descriptor index specified was out of range. (SQLSTATE + 07009) + + + + + + -242 (ECPG_UNKNOWN_DESCRIPTOR_ITEM) + + + An invalid descriptor item was requested. (This is an internal + error.) (SQLSTATE YE002) + + + + + + -243 (ECPG_VAR_NOT_NUMERIC) + + + During the execution of a dynamic statement, the database + returned a numeric value and the host variable was not numeric. + (SQLSTATE 07006) + + + + + + -244 (ECPG_VAR_NOT_CHAR) + + + During the execution of a dynamic statement, the database + returned a non-numeric value and the host variable was numeric. + (SQLSTATE 07006) + + + + + + -284 (ECPG_INFORMIX_SUBSELECT_NOT_ONE) + + + A result of the subquery is not single row (Informix + compatibility mode). (SQLSTATE 21000) + + + + + + -400 (ECPG_PGSQL) + + + Some error caused by the PostgreSQL + server. The message contains the error message from the + PostgreSQL server. + + + + + + -401 (ECPG_TRANS) + + + The PostgreSQL server signaled that + we cannot start, commit, or rollback the transaction. + (SQLSTATE 08007) + + + + + + -402 (ECPG_CONNECT) + + + The connection attempt to the database did not succeed. + (SQLSTATE 08001) + + + + + + -403 (ECPG_DUPLICATE_KEY) + + + Duplicate key error, violation of unique constraint. (SQLSTATE + 23505) + + + + + + -404 (ECPG_SUBSELECT_NOT_ONE) + + + A result for the subquery is not single row. (SQLSTATE 21000) + + + + + + + + + -602 (ECPG_WARNING_UNKNOWN_PORTAL) + + + An invalid cursor name was specified. (SQLSTATE 34000) + + + + + + -603 (ECPG_WARNING_IN_TRANSACTION) + + + Transaction is in progress. (SQLSTATE 25001) + + + + + + -604 (ECPG_WARNING_NO_TRANSACTION) + + + There is no active (in-progress) transaction. (SQLSTATE 25P01) + + + + + + -605 (ECPG_WARNING_PORTAL_EXISTS) + + + An existing cursor name was specified. (SQLSTATE 42P03) + + + + + + + + + + + Preprocessor Directives + + + Several preprocessor directives are available that modify how + the ecpg preprocessor parses and processes a + file. + + + + Including Files + + + To include an external file into your embedded SQL program, use: + +EXEC SQL INCLUDE filename; +EXEC SQL INCLUDE <filename>; +EXEC SQL INCLUDE "filename"; + + The embedded SQL preprocessor will look for a file named + filename.h, + preprocess it, and include it in the resulting C output. Thus, + embedded SQL statements in the included file are handled correctly. + + + + The ecpg preprocessor will search a file at + several directories in following order: + + + current directory + /usr/local/include + PostgreSQL include directory, defined at build time (e.g., /usr/local/pgsql/include) + /usr/include + + + But when EXEC SQL INCLUDE + "filename" is used, only the + current directory is searched. + + + + In each directory, the preprocessor will first look for the file + name as given, and if not found will append .h + to the file name and try again (unless the specified file name + already has that suffix). + + + + Note that EXEC SQL INCLUDE is not the same as: + +#include <filename.h> + + because this file would not be subject to SQL command preprocessing. + Naturally, you can continue to use the C + #include directive to include other header + files. + + + + + The include file name is case-sensitive, even though the rest of + the EXEC SQL INCLUDE command follows the normal + SQL case-sensitivity rules. + + + + + + The define and undef Directives + + Similar to the directive #define that is known from C, + embedded SQL has a similar concept: + +EXEC SQL DEFINE name; +EXEC SQL DEFINE name value; + + So you can define a name: + +EXEC SQL DEFINE HAVE_FEATURE; + + And you can also define constants: + +EXEC SQL DEFINE MYNUMBER 12; +EXEC SQL DEFINE MYSTRING 'abc'; + + Use undef to remove a previous definition: + +EXEC SQL UNDEF MYNUMBER; + + + + + Of course you can continue to use the C versions #define + and #undef in your embedded SQL program. The difference + is where your defined values get evaluated. If you use EXEC SQL + DEFINE then the ecpg preprocessor evaluates the defines and substitutes + the values. For example if you write: + +EXEC SQL DEFINE MYNUMBER 12; +... +EXEC SQL UPDATE Tbl SET col = MYNUMBER; + + then ecpg will already do the substitution and your C compiler will never + see any name or identifier MYNUMBER. Note that you cannot use + #define for a constant that you are going to use in an + embedded SQL query because in this case the embedded SQL precompiler is not + able to see this declaration. + + + + + ifdef, ifndef, elif, else, and endif Directives + + You can use the following directives to compile code sections conditionally: + + + + EXEC SQL ifdef name; + + + Checks a name and processes subsequent lines if + name has been defined via EXEC SQL define + name. + + + + + + EXEC SQL ifndef name; + + + Checks a name and processes subsequent lines if + name has not been defined via + EXEC SQL define name. + + + + + + EXEC SQL elif name; + + + Begins an optional alternative section after an + EXEC SQL ifdef name or + EXEC SQL ifndef name + directive. Any number of elif sections can appear. + Lines following an elif will be processed + if name has been + defined and no previous section of the same + ifdef/ifndef...endif + construct has been processed. + + + + + + EXEC SQL else; + + + Begins an optional, final alternative section after an + EXEC SQL ifdef name or + EXEC SQL ifndef name + directive. Subsequent lines will be processed if no previous section + of the same + ifdef/ifndef...endif + construct has been processed. + + + + + + EXEC SQL endif; + + + Ends an + ifdef/ifndef...endif + construct. Subsequent lines are processed normally. + + + + + + + + ifdef/ifndef...endif + constructs can be nested, up to 127 levels deep. + + + + This example will compile exactly one of the three SET + TIMEZONE commands: + +EXEC SQL ifdef TZVAR; +EXEC SQL SET TIMEZONE TO TZVAR; +EXEC SQL elif TZNAME; +EXEC SQL SET TIMEZONE TO TZNAME; +EXEC SQL else; +EXEC SQL SET TIMEZONE TO 'GMT'; +EXEC SQL endif; + + + + + + + + Processing Embedded SQL Programs + + + Now that you have an idea how to form embedded SQL C programs, you + probably want to know how to compile them. Before compiling you + run the file through the embedded SQL + C preprocessor, which converts the + SQL statements you used to special function + calls. After compiling, you must link with a special library that + contains the needed functions. These functions fetch information + from the arguments, perform the SQL command using + the libpq interface, and put the result + in the arguments specified for output. + + + + The preprocessor program is called ecpg and is + included in a normal PostgreSQL installation. + Embedded SQL programs are typically named with an extension + .pgc. If you have a program file called + prog1.pgc, you can preprocess it by simply + calling: + +ecpg prog1.pgc + + This will create a file called prog1.c. If + your input files do not follow the suggested naming pattern, you + can specify the output file explicitly using the + option. + + + + The preprocessed file can be compiled normally, for example: + +cc -c prog1.c + + The generated C source files include header files from the + PostgreSQL installation, so if you installed + PostgreSQL in a location that is not searched by + default, you have to add an option such as + -I/usr/local/pgsql/include to the compilation + command line. + + + + To link an embedded SQL program, you need to include the + libecpg library, like so: + +cc -o myprog prog1.o prog2.o ... -lecpg + + Again, you might have to add an option like + -L/usr/local/pgsql/lib to that command line. + + + + You can + use pg_configpg_configwith + ecpg + or pkg-configpkg-configwith + ecpg with package name libecpg to + get the paths for your installation. + + + + If you manage the build process of a larger project using + make, it might be convenient to include + the following implicit rule to your makefiles: + +ECPG = ecpg + +%.c: %.pgc + $(ECPG) $< + + + + + The complete syntax of the ecpg command is + detailed in . + + + + The ecpg library is thread-safe by + default. However, you might need to use some threading + command-line options to compile your client code. + + + + + Library Functions + + + The libecpg library primarily contains + hidden functions that are used to implement the + functionality expressed by the embedded SQL commands. But there + are some functions that can usefully be called directly. Note that + this makes your code unportable. + + + + + + ECPGdebug(int on, FILE + *stream) turns on debug + logging if called with the first argument non-zero. Debug logging + is done on stream. The log contains + all SQL statements with all the input + variables inserted, and the results from the + PostgreSQL server. This can be very + useful when searching for errors in your SQL + statements. + + + + On Windows, if the ecpg libraries and an application are + compiled with different flags, this function call will crash the + application because the internal representation of the + FILE pointers differ. Specifically, + multithreaded/single-threaded, release/debug, and static/dynamic + flags should be the same for the library and all applications using + that library. + + + + + + + ECPGget_PGconn(const char *connection_name) + returns the library database connection handle identified by the given name. + If connection_name is set to NULL, the current + connection handle is returned. If no connection handle can be identified, the function returns + NULL. The returned connection handle can be used to call any other functions + from libpq, if necessary. + + + + It is a bad idea to manipulate database connection handles made from ecpg directly + with libpq routines. + + + + + + + ECPGtransactionStatus(const char *connection_name) + returns the current transaction status of the given connection identified by connection_name. + See and libpq's for details about the returned status codes. + + + + + + ECPGstatus(int lineno, + const char* connection_name) + returns true if you are connected to a database and false if not. + connection_name can be NULL + if a single connection is being used. + + + + + + + Large Objects + + + Large objects are not directly supported by ECPG, but ECPG + application can manipulate large objects through the libpq large + object functions, obtaining the necessary PGconn + object by calling the ECPGget_PGconn() + function. (However, use of + the ECPGget_PGconn() function and touching + PGconn objects directly should be done very carefully + and ideally not mixed with other ECPG database access calls.) + + + + For more details about the ECPGget_PGconn(), see + . For information about the large + object function interface, see . + + + + Large object functions have to be called in a transaction block, so + when autocommit is off, BEGIN commands have to + be issued explicitly. + + + + shows an example program that + illustrates how to create, write, and read a large object in an + ECPG application. + + + + ECPG Program Accessing Large Objects + +#include +#include +#include + +EXEC SQL WHENEVER SQLERROR STOP; + +int +main(void) +{ + PGconn *conn; + Oid loid; + int fd; + char buf[256]; + int buflen = 256; + char buf2[256]; + int rc; + + memset(buf, 1, buflen); + + EXEC SQL CONNECT TO testdb AS con1; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + conn = ECPGget_PGconn("con1"); + printf("conn = %p\n", conn); + + /* create */ + loid = lo_create(conn, 0); + if (loid < 0) + printf("lo_create() failed: %s", PQerrorMessage(conn)); + + printf("loid = %d\n", loid); + + /* write test */ + fd = lo_open(conn, loid, INV_READ|INV_WRITE); + if (fd < 0) + printf("lo_open() failed: %s", PQerrorMessage(conn)); + + printf("fd = %d\n", fd); + + rc = lo_write(conn, fd, buf, buflen); + if (rc < 0) + printf("lo_write() failed\n"); + + rc = lo_close(conn, fd); + if (rc < 0) + printf("lo_close() failed: %s", PQerrorMessage(conn)); + + /* read test */ + fd = lo_open(conn, loid, INV_READ); + if (fd < 0) + printf("lo_open() failed: %s", PQerrorMessage(conn)); + + printf("fd = %d\n", fd); + + rc = lo_read(conn, fd, buf2, buflen); + if (rc < 0) + printf("lo_read() failed\n"); + + rc = lo_close(conn, fd); + if (rc < 0) + printf("lo_close() failed: %s", PQerrorMessage(conn)); + + /* check */ + rc = memcmp(buf, buf2, buflen); + printf("memcmp() = %d\n", rc); + + /* cleanup */ + rc = lo_unlink(conn, loid); + if (rc < 0) + printf("lo_unlink() failed: %s", PQerrorMessage(conn)); + + EXEC SQL COMMIT; + EXEC SQL DISCONNECT ALL; + return 0; +} +]]> + + + + + <acronym>C++</acronym> Applications + + + ECPG has some limited support for C++ applications. This section + describes some caveats. + + + + The ecpg preprocessor takes an input file + written in C (or something like C) and embedded SQL commands, + converts the embedded SQL commands into C language chunks, and + finally generates a .c file. The header file + declarations of the library functions used by the C language chunks + that ecpg generates are wrapped + in extern "C" { ... } blocks when used under + C++, so they should work seamlessly in C++. + + + + In general, however, the ecpg preprocessor only + understands C; it does not handle the special syntax and reserved + words of the C++ language. So, some embedded SQL code written in + C++ application code that uses complicated features specific to C++ + might fail to be preprocessed correctly or might not work as + expected. + + + + A safe way to use the embedded SQL code in a C++ application is + hiding the ECPG calls in a C module, which the C++ application code + calls into to access the database, and linking that together with + the rest of the C++ code. See + about that. + + + + Scope for Host Variables + + + The ecpg preprocessor understands the scope of + variables in C. In the C language, this is rather simple because + the scopes of variables is based on their code blocks. In C++, + however, the class member variables are referenced in a different + code block from the declared position, so + the ecpg preprocessor will not understand the + scope of the class member variables. + + + + For example, in the following case, the ecpg + preprocessor cannot find any declaration for the + variable dbname in the test + method, so an error will occur. + + +class TestCpp +{ + EXEC SQL BEGIN DECLARE SECTION; + char dbname[1024]; + EXEC SQL END DECLARE SECTION; + + public: + TestCpp(); + void test(); + ~TestCpp(); +}; + +TestCpp::TestCpp() +{ + EXEC SQL CONNECT TO testdb1; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; +} + +void Test::test() +{ + EXEC SQL SELECT current_database() INTO :dbname; + printf("current_database = %s\n", dbname); +} + +TestCpp::~TestCpp() +{ + EXEC SQL DISCONNECT ALL; +} + + + This code will result in an error like this: + +ecpg test_cpp.pgc +test_cpp.pgc:28: ERROR: variable "dbname" is not declared + + + + + To avoid this scope issue, the test method + could be modified to use a local variable as intermediate storage. + But this approach is only a poor workaround, because it uglifies + the code and reduces performance. + + +void TestCpp::test() +{ + EXEC SQL BEGIN DECLARE SECTION; + char tmp[1024]; + EXEC SQL END DECLARE SECTION; + + EXEC SQL SELECT current_database() INTO :tmp; + strlcpy(dbname, tmp, sizeof(tmp)); + + printf("current_database = %s\n", dbname); +} + + + + + + C++ Application Development with External C Module + + + If you understand these technical limitations of + the ecpg preprocessor in C++, you might come to + the conclusion that linking C objects and C++ objects at the link + stage to enable C++ applications to use ECPG features could be + better than writing some embedded SQL commands in C++ code + directly. This section describes a way to separate some embedded + SQL commands from C++ application code with a simple example. In + this example, the application is implemented in C++, while C and + ECPG is used to connect to the PostgreSQL server. + + + + Three kinds of files have to be created: a C file + (*.pgc), a header file, and a C++ file: + + + + test_mod.pgc + + + A sub-routine module to execute SQL commands embedded in C. + It is going to be converted + into test_mod.c by the preprocessor. + + +#include "test_mod.h" +#include <stdio.h> + +void +db_connect() +{ + EXEC SQL CONNECT TO testdb1; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; +} + +void +db_test() +{ + EXEC SQL BEGIN DECLARE SECTION; + char dbname[1024]; + EXEC SQL END DECLARE SECTION; + + EXEC SQL SELECT current_database() INTO :dbname; + printf("current_database = %s\n", dbname); +} + +void +db_disconnect() +{ + EXEC SQL DISCONNECT ALL; +} + + + + + + + test_mod.h + + + A header file with declarations of the functions in the C + module (test_mod.pgc). It is included by + test_cpp.cpp. This file has to have an + extern "C" block around the declarations, + because it will be linked from the C++ module. + + +#ifdef __cplusplus +extern "C" { +#endif + +void db_connect(); +void db_test(); +void db_disconnect(); + +#ifdef __cplusplus +} +#endif + + + + + + + test_cpp.cpp + + + The main code for the application, including + the main routine, and in this example a + C++ class. + + +#include "test_mod.h" + +class TestCpp +{ + public: + TestCpp(); + void test(); + ~TestCpp(); +}; + +TestCpp::TestCpp() +{ + db_connect(); +} + +void +TestCpp::test() +{ + db_test(); +} + +TestCpp::~TestCpp() +{ + db_disconnect(); +} + +int +main(void) +{ + TestCpp *t = new TestCpp(); + + t->test(); + return 0; +} + + + + + + + + + To build the application, proceed as follows. Convert + test_mod.pgc into test_mod.c by + running ecpg, and generate + test_mod.o by compiling + test_mod.c with the C compiler: + +ecpg -o test_mod.c test_mod.pgc +cc -c test_mod.c -o test_mod.o + + + + + Next, generate test_cpp.o by compiling + test_cpp.cpp with the C++ compiler: + +c++ -c test_cpp.cpp -o test_cpp.o + + + + + Finally, link these object files, test_cpp.o + and test_mod.o, into one executable, using the C++ + compiler driver: + +c++ test_cpp.o test_mod.o -lecpg -o test_cpp + + + + + + + Embedded SQL Commands + + + This section describes all SQL commands that are specific to + embedded SQL. Also refer to the SQL commands listed + in , which can also be used in + embedded SQL, unless stated otherwise. + + + + + ALLOCATE DESCRIPTOR + allocate an SQL descriptor area + + + + +ALLOCATE DESCRIPTOR name + + + + + Description + + + ALLOCATE DESCRIPTOR allocates a new named SQL + descriptor area, which can be used to exchange data between the + PostgreSQL server and the host program. + + + + Descriptor areas should be freed after use using + the DEALLOCATE DESCRIPTOR command. + + + + + Parameters + + + + name + + + A name of SQL descriptor, case sensitive. This can be an SQL + identifier or a host variable. + + + + + + + + Examples + + +EXEC SQL ALLOCATE DESCRIPTOR mydesc; + + + + + Compatibility + + + ALLOCATE DESCRIPTOR is specified in the SQL + standard. + + + + + See Also + + + + + + + + + + + + CONNECT + establish a database connection + + + + +CONNECT TO connection_target [ AS connection_name ] [ USER connection_user ] +CONNECT TO DEFAULT +CONNECT connection_user +DATABASE connection_target + + + + + Description + + + The CONNECT command establishes a connection + between the client and the PostgreSQL server. + + + + + Parameters + + + + connection_target + + + connection_target + specifies the target server of the connection on one of + several forms. + + + + [ database_name ] [ @host ] [ :port ] + + + Connect over TCP/IP + + + + + + unix:postgresql://host [ :port ] / [ database_name ] [ ?connection_option ] + + + Connect over Unix-domain sockets + + + + + + tcp:postgresql://host [ :port ] / [ database_name ] [ ?connection_option ] + + + Connect over TCP/IP + + + + + + SQL string constant + + + containing a value in one of the above forms + + + + + + host variable + + + host variable of type char[] + or VARCHAR[] containing a value in one of the + above forms + + + + + + + + + + connection_name + + + An optional identifier for the connection, so that it can be + referred to in other commands. This can be an SQL identifier + or a host variable. + + + + + + connection_user + + + The user name for the database connection. + + + + This parameter can also specify user name and password, using one the forms + user_name/password, + user_name IDENTIFIED BY password, or + user_name USING password. + + + + User name and password can be SQL identifiers, string + constants, or host variables. + + + + + + DEFAULT + + + Use all default connection parameters, as defined by libpq. + + + + + + + + Examples + + + Here a several variants for specifying connection parameters: + +EXEC SQL CONNECT TO "connectdb" AS main; +EXEC SQL CONNECT TO "connectdb" AS second; +EXEC SQL CONNECT TO "unix:postgresql://200.46.204.71/connectdb" AS main USER connectuser; +EXEC SQL CONNECT TO "unix:postgresql://localhost/connectdb" AS main USER connectuser; +EXEC SQL CONNECT TO 'connectdb' AS main; +EXEC SQL CONNECT TO 'unix:postgresql://localhost/connectdb' AS main USER :user; +EXEC SQL CONNECT TO :db AS :id; +EXEC SQL CONNECT TO :db USER connectuser USING :pw; +EXEC SQL CONNECT TO @localhost AS main USER connectdb; +EXEC SQL CONNECT TO REGRESSDB1 as main; +EXEC SQL CONNECT TO AS main USER connectdb; +EXEC SQL CONNECT TO connectdb AS :id; +EXEC SQL CONNECT TO connectdb AS main USER connectuser/connectdb; +EXEC SQL CONNECT TO connectdb AS main; +EXEC SQL CONNECT TO connectdb@localhost AS main; +EXEC SQL CONNECT TO tcp:postgresql://localhost/ USER connectdb; +EXEC SQL CONNECT TO tcp:postgresql://localhost/connectdb USER connectuser IDENTIFIED BY connectpw; +EXEC SQL CONNECT TO tcp:postgresql://localhost:20/connectdb USER connectuser IDENTIFIED BY connectpw; +EXEC SQL CONNECT TO unix:postgresql://localhost/ AS main USER connectdb; +EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb AS main USER connectuser; +EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb USER connectuser IDENTIFIED BY "connectpw"; +EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb USER connectuser USING "connectpw"; +EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb?connect_timeout=14 USER connectuser; + + + + + Here is an example program that illustrates the use of host + variables to specify connection parameters: + +int +main(void) +{ +EXEC SQL BEGIN DECLARE SECTION; + char *dbname = "testdb"; /* database name */ + char *user = "testuser"; /* connection user name */ + char *connection = "tcp:postgresql://localhost:5432/testdb"; + /* connection string */ + char ver[256]; /* buffer to store the version string */ +EXEC SQL END DECLARE SECTION; + + ECPGdebug(1, stderr); + + EXEC SQL CONNECT TO :dbname USER :user; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + EXEC SQL SELECT version() INTO :ver; + EXEC SQL DISCONNECT; + + printf("version: %s\n", ver); + + EXEC SQL CONNECT TO :connection USER :user; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + EXEC SQL SELECT version() INTO :ver; + EXEC SQL DISCONNECT; + + printf("version: %s\n", ver); + + return 0; +} + + + + + + Compatibility + + + CONNECT is specified in the SQL standard, but + the format of the connection parameters is + implementation-specific. + + + + + See Also + + + + + + + + + + + DEALLOCATE DESCRIPTOR + deallocate an SQL descriptor area + + + + +DEALLOCATE DESCRIPTOR name + + + + + Description + + + DEALLOCATE DESCRIPTOR deallocates a named SQL + descriptor area. + + + + + Parameters + + + + name + + + The name of the descriptor which is going to be deallocated. + It is case sensitive. This can be an SQL identifier or a host + variable. + + + + + + + + Examples + + +EXEC SQL DEALLOCATE DESCRIPTOR mydesc; + + + + + Compatibility + + + DEALLOCATE DESCRIPTOR is specified in the SQL + standard. + + + + + See Also + + + + + + + + + + + + DECLARE + define a cursor + + + + +DECLARE cursor_name [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR prepared_name +DECLARE cursor_name [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR query + + + + + Description + + + DECLARE declares a cursor for iterating over + the result set of a prepared statement. This command has + slightly different semantics from the direct SQL + command DECLARE: Whereas the latter executes a + query and prepares the result set for retrieval, this embedded + SQL command merely declares a name as a loop + variable for iterating over the result set of a query; + the actual execution happens when the cursor is opened with + the OPEN command. + + + + + Parameters + + + + cursor_name + + + A cursor name, case sensitive. This can be an SQL identifier + or a host variable. + + + + + + prepared_name + + + The name of a prepared query, either as an SQL identifier or a + host variable. + + + + + + query + + + A or + command which will provide the + rows to be returned by the cursor. + + + + + + + For the meaning of the cursor options, + see . + + + + + Examples + + + Examples declaring a cursor for a query: + +EXEC SQL DECLARE C CURSOR FOR SELECT * FROM My_Table; +EXEC SQL DECLARE C CURSOR FOR SELECT Item1 FROM T; +EXEC SQL DECLARE cur1 CURSOR FOR SELECT version(); + + + + + An example declaring a cursor for a prepared statement: + +EXEC SQL PREPARE stmt1 AS SELECT version(); +EXEC SQL DECLARE cur1 CURSOR FOR stmt1; + + + + + + Compatibility + + + DECLARE is specified in the SQL standard. + + + + + See Also + + + + + + + + + + + + DECLARE STATEMENT + declare SQL statement identifier + + + + +EXEC SQL [ AT connection_name ] DECLARE statement_name STATEMENT + + + + + Description + + + DECLARE STATEMENT declares an SQL statement identifier. + SQL statement identifier can be associated with the connection. + When the identifier is used by dynamic SQL statements, the statements + are executed using the associated connection. + The namespace of the declaration is the precompile unit, and multiple + declarations to the same SQL statement identifier are not allowed. + Note that if the precompiler runs in Informix compatibility mode and + some SQL statement is declared, "database" can not be used as a cursor + name. + + + + + Parameters + + + + connection_name + + + A database connection name established by the CONNECT command. + + + AT clause can be omitted, but such statement has no meaning. + + + + + + + + statement_name + + + The name of an SQL statement identifier, either as an SQL identifier or a host variable. + + + + + + + + Notes + + This association is valid only if the declaration is physically placed on top of a dynamic statement. + + + + + Examples + + +EXEC SQL CONNECT TO postgres AS con1; +EXEC SQL AT con1 DECLARE sql_stmt STATEMENT; +EXEC SQL DECLARE cursor_name CURSOR FOR sql_stmt; +EXEC SQL PREPARE sql_stmt FROM :dyn_string; +EXEC SQL OPEN cursor_name; +EXEC SQL FETCH cursor_name INTO :column1; +EXEC SQL CLOSE cursor_name; + + + + + Compatibility + + + DECLARE STATEMENT is a extension of the SQL standard, + but can be used in famous DBMSs. + + + + + See Also + + + + + + + + + + + + DESCRIBE + obtain information about a prepared statement or result set + + + + +DESCRIBE [ OUTPUT ] prepared_name USING [ SQL ] DESCRIPTOR descriptor_name +DESCRIBE [ OUTPUT ] prepared_name INTO [ SQL ] DESCRIPTOR descriptor_name +DESCRIBE [ OUTPUT ] prepared_name INTO sqlda_name + + + + + Description + + + DESCRIBE retrieves metadata information about + the result columns contained in a prepared statement, without + actually fetching a row. + + + + + Parameters + + + + prepared_name + + + The name of a prepared statement. This can be an SQL + identifier or a host variable. + + + + + + descriptor_name + + + A descriptor name. It is case sensitive. It can be an SQL + identifier or a host variable. + + + + + + sqlda_name + + + The name of an SQLDA variable. + + + + + + + + Examples + + +EXEC SQL ALLOCATE DESCRIPTOR mydesc; +EXEC SQL PREPARE stmt1 FROM :sql_stmt; +EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc; +EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :charvar = NAME; +EXEC SQL DEALLOCATE DESCRIPTOR mydesc; + + + + + Compatibility + + + DESCRIBE is specified in the SQL standard. + + + + + See Also + + + + + + + + + + + DISCONNECT + terminate a database connection + + + + +DISCONNECT connection_name +DISCONNECT [ CURRENT ] +DISCONNECT DEFAULT +DISCONNECT ALL + + + + + Description + + + DISCONNECT closes a connection (or all + connections) to the database. + + + + + Parameters + + + + connection_name + + + A database connection name established by + the CONNECT command. + + + + + + CURRENT + + + Close the current connection, which is either + the most recently opened connection, or the connection set by + the SET CONNECTION command. This is also + the default if no argument is given to + the DISCONNECT command. + + + + + + DEFAULT + + + Close the default connection. + + + + + + ALL + + + Close all open connections. + + + + + + + + Examples + + +int +main(void) +{ + EXEC SQL CONNECT TO testdb AS DEFAULT USER testuser; + EXEC SQL CONNECT TO testdb AS con1 USER testuser; + EXEC SQL CONNECT TO testdb AS con2 USER testuser; + EXEC SQL CONNECT TO testdb AS con3 USER testuser; + + EXEC SQL DISCONNECT CURRENT; /* close con3 */ + EXEC SQL DISCONNECT DEFAULT; /* close DEFAULT */ + EXEC SQL DISCONNECT ALL; /* close con2 and con1 */ + + return 0; +} + + + + + Compatibility + + + DISCONNECT is specified in the SQL standard. + + + + + See Also + + + + + + + + + + + EXECUTE IMMEDIATE + dynamically prepare and execute a statement + + + + +EXECUTE IMMEDIATE string + + + + + Description + + + EXECUTE IMMEDIATE immediately prepares and + executes a dynamically specified SQL statement, without + retrieving result rows. + + + + + Parameters + + + + string + + + A literal string or a host variable containing the SQL + statement to be executed. + + + + + + + + Notes + + + In typical usage, the string is a host + variable reference to a string containing a dynamically-constructed + SQL statement. The case of a literal string is not very useful; + you might as well just write the SQL statement directly, without + the extra typing of EXECUTE IMMEDIATE. + + + + If you do use a literal string, keep in mind that any double quotes + you might wish to include in the SQL statement must be written as + octal escapes (\042) not the usual C + idiom \". This is because the string is inside + an EXEC SQL section, so the ECPG lexer parses it + according to SQL rules not C rules. Any embedded backslashes will + later be handled according to C rules; but \" + causes an immediate syntax error because it is seen as ending the + literal. + + + + + Examples + + + Here is an example that executes an INSERT + statement using EXECUTE IMMEDIATE and a host + variable named command: + +sprintf(command, "INSERT INTO test (name, amount, letter) VALUES ('db: ''r1''', 1, 'f')"); +EXEC SQL EXECUTE IMMEDIATE :command; + + + + + + Compatibility + + + EXECUTE IMMEDIATE is specified in the SQL standard. + + + + + + + GET DESCRIPTOR + get information from an SQL descriptor area + + + + +GET DESCRIPTOR descriptor_name :cvariable = descriptor_header_item [, ... ] +GET DESCRIPTOR descriptor_name VALUE column_number :cvariable = descriptor_item [, ... ] + + + + + Description + + + GET DESCRIPTOR retrieves information about a + query result set from an SQL descriptor area and stores it into + host variables. A descriptor area is typically populated + using FETCH or SELECT + before using this command to transfer the information into host + language variables. + + + + This command has two forms: The first form retrieves + descriptor header items, which apply to the result + set in its entirety. One example is the row count. The second + form, which requires the column number as additional parameter, + retrieves information about a particular column. Examples are + the column name and the actual column value. + + + + + Parameters + + + + descriptor_name + + + A descriptor name. + + + + + + descriptor_header_item + + + A token identifying which header information item to retrieve. + Only COUNT, to get the number of columns in the + result set, is currently supported. + + + + + + column_number + + + The number of the column about which information is to be + retrieved. The count starts at 1. + + + + + + descriptor_item + + + A token identifying which item of information about a column + to retrieve. See for + a list of supported items. + + + + + + cvariable + + + A host variable that will receive the data retrieved from the + descriptor area. + + + + + + + + Examples + + + An example to retrieve the number of columns in a result set: + +EXEC SQL GET DESCRIPTOR d :d_count = COUNT; + + + + + An example to retrieve a data length in the first column: + +EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH; + + + + + An example to retrieve the data body of the second column as a + string: + +EXEC SQL GET DESCRIPTOR d VALUE 2 :d_data = DATA; + + + + + Here is an example for a whole procedure of + executing SELECT current_database(); and showing the number of + columns, the column data length, and the column data: + +int +main(void) +{ +EXEC SQL BEGIN DECLARE SECTION; + int d_count; + char d_data[1024]; + int d_returned_octet_length; +EXEC SQL END DECLARE SECTION; + + EXEC SQL CONNECT TO testdb AS con1 USER testuser; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + EXEC SQL ALLOCATE DESCRIPTOR d; + + /* Declare, open a cursor, and assign a descriptor to the cursor */ + EXEC SQL DECLARE cur CURSOR FOR SELECT current_database(); + EXEC SQL OPEN cur; + EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d; + + /* Get a number of total columns */ + EXEC SQL GET DESCRIPTOR d :d_count = COUNT; + printf("d_count = %d\n", d_count); + + /* Get length of a returned column */ + EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH; + printf("d_returned_octet_length = %d\n", d_returned_octet_length); + + /* Fetch the returned column as a string */ + EXEC SQL GET DESCRIPTOR d VALUE 1 :d_data = DATA; + printf("d_data = %s\n", d_data); + + /* Closing */ + EXEC SQL CLOSE cur; + EXEC SQL COMMIT; + + EXEC SQL DEALLOCATE DESCRIPTOR d; + EXEC SQL DISCONNECT ALL; + + return 0; +} + + When the example is executed, the result will look like this: + +d_count = 1 +d_returned_octet_length = 6 +d_data = testdb + + + + + + Compatibility + + + GET DESCRIPTOR is specified in the SQL standard. + + + + + See Also + + + + + + + + + + + OPEN + open a dynamic cursor + + + + +OPEN cursor_name +OPEN cursor_name USING value [, ... ] +OPEN cursor_name USING SQL DESCRIPTOR descriptor_name + + + + + Description + + + OPEN opens a cursor and optionally binds + actual values to the placeholders in the cursor's declaration. + The cursor must previously have been declared with + the DECLARE command. The execution + of OPEN causes the query to start executing on + the server. + + + + + Parameters + + + + cursor_name + + + The name of the cursor to be opened. This can be an SQL + identifier or a host variable. + + + + + + value + + + A value to be bound to a placeholder in the cursor. This can + be an SQL constant, a host variable, or a host variable with + indicator. + + + + + + descriptor_name + + + The name of a descriptor containing values to be bound to the + placeholders in the cursor. This can be an SQL identifier or + a host variable. + + + + + + + + Examples + + +EXEC SQL OPEN a; +EXEC SQL OPEN d USING 1, 'test'; +EXEC SQL OPEN c1 USING SQL DESCRIPTOR mydesc; +EXEC SQL OPEN :curname1; + + + + + Compatibility + + + OPEN is specified in the SQL standard. + + + + + See Also + + + + + + + + + + + PREPARE + prepare a statement for execution + + + + +PREPARE prepared_name FROM string + + + + + Description + + + PREPARE prepares a statement dynamically + specified as a string for execution. This is different from the + direct SQL statement , which can also + be used in embedded programs. The + command is used to execute either kind of prepared statement. + + + + + Parameters + + + + prepared_name + + + An identifier for the prepared query. + + + + + + string + + + A literal string or a host variable containing a preparable + SQL statement, one of SELECT, INSERT, UPDATE, or DELETE. + Use question marks (?) for parameter values + to be supplied at execution. + + + + + + + + Notes + + + In typical usage, the string is a host + variable reference to a string containing a dynamically-constructed + SQL statement. The case of a literal string is not very useful; + you might as well just write a direct SQL PREPARE + statement. + + + + If you do use a literal string, keep in mind that any double quotes + you might wish to include in the SQL statement must be written as + octal escapes (\042) not the usual C + idiom \". This is because the string is inside + an EXEC SQL section, so the ECPG lexer parses it + according to SQL rules not C rules. Any embedded backslashes will + later be handled according to C rules; but \" + causes an immediate syntax error because it is seen as ending the + literal. + + + + + Examples + +char *stmt = "SELECT * FROM test1 WHERE a = ? AND b = ?"; + +EXEC SQL ALLOCATE DESCRIPTOR outdesc; +EXEC SQL PREPARE foo FROM :stmt; + +EXEC SQL EXECUTE foo USING SQL DESCRIPTOR indesc INTO SQL DESCRIPTOR outdesc; + + + + + Compatibility + + + PREPARE is specified in the SQL standard. + + + + + See Also + + + + + + + + + + SET AUTOCOMMIT + set the autocommit behavior of the current session + + + + +SET AUTOCOMMIT { = | TO } { ON | OFF } + + + + + Description + + + SET AUTOCOMMIT sets the autocommit behavior of + the current database session. By default, embedded SQL programs + are not in autocommit mode, + so COMMIT needs to be issued explicitly when + desired. This command can change the session to autocommit mode, + where each individual statement is committed implicitly. + + + + + Compatibility + + + SET AUTOCOMMIT is an extension of PostgreSQL ECPG. + + + + + + + SET CONNECTION + select a database connection + + + + +SET CONNECTION [ TO | = ] connection_name + + + + + Description + + + SET CONNECTION sets the current + database connection, which is the one that all commands use + unless overridden. + + + + + Parameters + + + + connection_name + + + A database connection name established by + the CONNECT command. + + + + + + DEFAULT + + + Set the connection to the default connection. + + + + + + + + Examples + + +EXEC SQL SET CONNECTION TO con2; +EXEC SQL SET CONNECTION = con1; + + + + + Compatibility + + + SET CONNECTION is specified in the SQL standard. + + + + + See Also + + + + + + + + + + + SET DESCRIPTOR + set information in an SQL descriptor area + + + + +SET DESCRIPTOR descriptor_name descriptor_header_item = value [, ... ] +SET DESCRIPTOR descriptor_name VALUE number descriptor_item = value [, ...] + + + + + Description + + + SET DESCRIPTOR populates an SQL descriptor + area with values. The descriptor area is then typically used to + bind parameters in a prepared query execution. + + + + This command has two forms: The first form applies to the + descriptor header, which is independent of a + particular datum. The second form assigns values to particular + datums, identified by number. + + + + + Parameters + + + + descriptor_name + + + A descriptor name. + + + + + + descriptor_header_item + + + A token identifying which header information item to set. + Only COUNT, to set the number of descriptor + items, is currently supported. + + + + + + number + + + The number of the descriptor item to set. The count starts at + 1. + + + + + + descriptor_item + + + A token identifying which item of information to set in the + descriptor. See for a + list of supported items. + + + + + + value + + + A value to store into the descriptor item. This can be an SQL + constant or a host variable. + + + + + + + + Examples + +EXEC SQL SET DESCRIPTOR indesc COUNT = 1; +EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2; +EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1; +EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val1, DATA = 'some string'; +EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2null, DATA = :val2; + + + + + Compatibility + + + SET DESCRIPTOR is specified in the SQL standard. + + + + + See Also + + + + + + + + + + + TYPE + define a new data type + + + + +TYPE type_name IS ctype + + + + + Description + + + The TYPE command defines a new C type. It is + equivalent to putting a typedef into a declare + section. + + + + This command is only recognized when ecpg is + run with the option. + + + + + Parameters + + + + type_name + + + The name for the new type. It must be a valid C type name. + + + + + + ctype + + + A C type specification. + + + + + + + + Examples + + +EXEC SQL TYPE customer IS + struct + { + varchar name[50]; + int phone; + }; + +EXEC SQL TYPE cust_ind IS + struct ind + { + short name_ind; + short phone_ind; + }; + +EXEC SQL TYPE c IS char reference; +EXEC SQL TYPE ind IS union { int integer; short smallint; }; +EXEC SQL TYPE intarray IS int[AMOUNT]; +EXEC SQL TYPE str IS varchar[BUFFERSIZ]; +EXEC SQL TYPE string IS char[11]; + + + + Here is an example program that uses EXEC SQL + TYPE: + +EXEC SQL WHENEVER SQLERROR SQLPRINT; + +EXEC SQL TYPE tt IS + struct + { + varchar v[256]; + int i; + }; + +EXEC SQL TYPE tt_ind IS + struct ind { + short v_ind; + short i_ind; + }; + +int +main(void) +{ +EXEC SQL BEGIN DECLARE SECTION; + tt t; + tt_ind t_ind; +EXEC SQL END DECLARE SECTION; + + EXEC SQL CONNECT TO testdb AS con1; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + + EXEC SQL SELECT current_database(), 256 INTO :t:t_ind LIMIT 1; + + printf("t.v = %s\n", t.v.arr); + printf("t.i = %d\n", t.i); + + printf("t_ind.v_ind = %d\n", t_ind.v_ind); + printf("t_ind.i_ind = %d\n", t_ind.i_ind); + + EXEC SQL DISCONNECT con1; + + return 0; +} + + + The output from this program looks like this: + +t.v = testdb +t.i = 256 +t_ind.v_ind = 0 +t_ind.i_ind = 0 + + + + + + Compatibility + + + The TYPE command is a PostgreSQL extension. + + + + + + + VAR + define a variable + + + + +VAR varname IS ctype + + + + + Description + + + The VAR command assigns a new C data type + to a host variable. The host variable must be previously + declared in a declare section. + + + + + Parameters + + + + varname + + + A C variable name. + + + + + + ctype + + + A C type specification. + + + + + + + + Examples + + +Exec sql begin declare section; +short a; +exec sql end declare section; +EXEC SQL VAR a IS int; + + + + + Compatibility + + + The VAR command is a PostgreSQL extension. + + + + + + + WHENEVER + specify the action to be taken when an SQL statement causes a specific class condition to be raised + + + + +WHENEVER { NOT FOUND | SQLERROR | SQLWARNING } action + + + + + Description + + + Define a behavior which is called on the special cases (Rows not + found, SQL warnings or errors) in the result of SQL execution. + + + + + Parameters + + + See for a description of the + parameters. + + + + + Examples + + +EXEC SQL WHENEVER NOT FOUND CONTINUE; +EXEC SQL WHENEVER NOT FOUND DO BREAK; +EXEC SQL WHENEVER NOT FOUND DO CONTINUE; +EXEC SQL WHENEVER SQLWARNING SQLPRINT; +EXEC SQL WHENEVER SQLWARNING DO warn(); +EXEC SQL WHENEVER SQLERROR sqlprint; +EXEC SQL WHENEVER SQLERROR CALL print2(); +EXEC SQL WHENEVER SQLERROR DO handle_error("select"); +EXEC SQL WHENEVER SQLERROR DO sqlnotice(NULL, NONO); +EXEC SQL WHENEVER SQLERROR DO sqlprint(); +EXEC SQL WHENEVER SQLERROR GOTO error_label; +EXEC SQL WHENEVER SQLERROR STOP; + + + + A typical application is the use of WHENEVER NOT FOUND + BREAK to handle looping through result sets: + +int +main(void) +{ + EXEC SQL CONNECT TO testdb AS con1; + EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT; + EXEC SQL ALLOCATE DESCRIPTOR d; + EXEC SQL DECLARE cur CURSOR FOR SELECT current_database(), 'hoge', 256; + EXEC SQL OPEN cur; + + /* when end of result set reached, break out of while loop */ + EXEC SQL WHENEVER NOT FOUND DO BREAK; + + while (1) + { + EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d; + ... + } + + EXEC SQL CLOSE cur; + EXEC SQL COMMIT; + + EXEC SQL DEALLOCATE DESCRIPTOR d; + EXEC SQL DISCONNECT ALL; + + return 0; +} + + + + + + Compatibility + + + WHENEVER is specified in the SQL standard, but + most of the actions are PostgreSQL extensions. + + + + + + + <productname>Informix</productname> Compatibility Mode + + ecpg can be run in a so-called Informix compatibility mode. If + this mode is active, it tries to behave as if it were the Informix + precompiler for Informix E/SQL. Generally spoken this will allow you to use + the dollar sign instead of the EXEC SQL primitive to introduce + embedded SQL commands: + +$int j = 3; +$CONNECT TO :dbname; +$CREATE TABLE test(i INT PRIMARY KEY, j INT); +$INSERT INTO test(i, j) VALUES (7, :j); +$COMMIT; + + + + + + There must not be any white space between the $ + and a following preprocessor directive, that is, + include, define, ifdef, + etc. Otherwise, the preprocessor will parse the token as a host + variable. + + + + + There are two compatibility modes: INFORMIX, INFORMIX_SE + + + When linking programs that use this compatibility mode, remember to link + against libcompat that is shipped with ECPG. + + + Besides the previously explained syntactic sugar, the Informix compatibility + mode ports some functions for input, output and transformation of data as + well as embedded SQL statements known from E/SQL to ECPG. + + + Informix compatibility mode is closely connected to the pgtypeslib library + of ECPG. pgtypeslib maps SQL data types to data types within the C host + program and most of the additional functions of the Informix compatibility + mode allow you to operate on those C host program types. Note however that + the extent of the compatibility is limited. It does not try to copy Informix + behavior; it allows you to do more or less the same operations and gives + you functions that have the same name and the same basic behavior but it is + no drop-in replacement if you are using Informix at the moment. Moreover, + some of the data types are different. For example, + PostgreSQL's datetime and interval types do not + know about ranges like for example YEAR TO MINUTE so you won't + find support in ECPG for that either. + + + + Additional Types + + The Informix-special "string" pseudo-type for storing right-trimmed character string data is now + supported in Informix-mode without using typedef. In fact, in Informix-mode, + ECPG refuses to process source files that contain typedef sometype string; + +EXEC SQL BEGIN DECLARE SECTION; +string userid; /* this variable will contain trimmed data */ +EXEC SQL END DECLARE SECTION; + +EXEC SQL FETCH MYCUR INTO :userid; + + + + + + Additional/Missing Embedded SQL Statements + + + + CLOSE DATABASE + + + This statement closes the current connection. In fact, this is a + synonym for ECPG's DISCONNECT CURRENT: + +$CLOSE DATABASE; /* close the current connection */ +EXEC SQL CLOSE DATABASE; + + + + + + FREE cursor_name + + + Due to the differences how ECPG works compared to Informix's ESQL/C (i.e., which steps + are purely grammar transformations and which steps rely on the underlying run-time library) + there is no FREE cursor_name statement in ECPG. This is because in ECPG, + DECLARE CURSOR doesn't translate to a function call into + the run-time library that uses to the cursor name. This means that there's no run-time + bookkeeping of SQL cursors in the ECPG run-time library, only in the PostgreSQL server. + + + + + FREE statement_name + + + FREE statement_name is a synonym for DEALLOCATE PREPARE statement_name. + + + + + + + + + Informix-compatible SQLDA Descriptor Areas + + Informix-compatible mode supports a different structure than the one described in + . See below: + +struct sqlvar_compat +{ + short sqltype; + int sqllen; + char *sqldata; + short *sqlind; + char *sqlname; + char *sqlformat; + short sqlitype; + short sqlilen; + char *sqlidata; + int sqlxid; + char *sqltypename; + short sqltypelen; + short sqlownerlen; + short sqlsourcetype; + char *sqlownername; + int sqlsourceid; + char *sqlilongdata; + int sqlflags; + void *sqlreserved; +}; + +struct sqlda_compat +{ + short sqld; + struct sqlvar_compat *sqlvar; + char desc_name[19]; + short desc_occ; + struct sqlda_compat *desc_next; + void *reserved; +}; + +typedef struct sqlvar_compat sqlvar_t; +typedef struct sqlda_compat sqlda_t; + + + + + The global properties are: + + + + sqld + + + The number of fields in the SQLDA descriptor. + + + + + + sqlvar + + + Pointer to the per-field properties. + + + + + + desc_name + + + Unused, filled with zero-bytes. + + + + + + desc_occ + + + Size of the allocated structure. + + + + + + desc_next + + + Pointer to the next SQLDA structure if the result set contains more than one record. + + + + + + reserved + + + Unused pointer, contains NULL. Kept for Informix-compatibility. + + + + + + + The per-field properties are below, they are stored in the sqlvar array: + + + + + sqltype + + + Type of the field. Constants are in sqltypes.h + + + + + + sqllen + + + Length of the field data. + + + + + + sqldata + + + Pointer to the field data. The pointer is of char * type, + the data pointed by it is in a binary format. Example: + +int intval; + +switch (sqldata->sqlvar[i].sqltype) +{ + case SQLINTEGER: + intval = *(int *)sqldata->sqlvar[i].sqldata; + break; + ... +} + + + + + + + sqlind + + + Pointer to the NULL indicator. If returned by DESCRIBE or FETCH then it's always a valid pointer. + If used as input for EXECUTE ... USING sqlda; then NULL-pointer value means + that the value for this field is non-NULL. Otherwise a valid pointer and sqlitype + has to be properly set. Example: + +if (*(int2 *)sqldata->sqlvar[i].sqlind != 0) + printf("value is NULL\n"); + + + + + + + sqlname + + + Name of the field. 0-terminated string. + + + + + + sqlformat + + + Reserved in Informix, value of for the field. + + + + + + sqlitype + + + Type of the NULL indicator data. It's always SQLSMINT when returning data from the server. + When the SQLDA is used for a parameterized query, the data is treated + according to the set type. + + + + + + sqlilen + + + Length of the NULL indicator data. + + + + + + sqlxid + + + Extended type of the field, result of . + + + + + + sqltypename + sqltypelen + sqlownerlen + sqlsourcetype + sqlownername + sqlsourceid + sqlflags + sqlreserved + + + Unused. + + + + + + sqlilongdata + + + It equals to sqldata if sqllen is larger than 32kB. + + + + + + + Example: + +EXEC SQL INCLUDE sqlda.h; + + sqlda_t *sqlda; /* This doesn't need to be under embedded DECLARE SECTION */ + + EXEC SQL BEGIN DECLARE SECTION; + char *prep_stmt = "select * from table1"; + int i; + EXEC SQL END DECLARE SECTION; + + ... + + EXEC SQL PREPARE mystmt FROM :prep_stmt; + + EXEC SQL DESCRIBE mystmt INTO sqlda; + + printf("# of fields: %d\n", sqlda->sqld); + for (i = 0; i < sqlda->sqld; i++) + printf("field %d: \"%s\"\n", sqlda->sqlvar[i]->sqlname); + + EXEC SQL DECLARE mycursor CURSOR FOR mystmt; + EXEC SQL OPEN mycursor; + EXEC SQL WHENEVER NOT FOUND GOTO out; + + while (1) + { + EXEC SQL FETCH mycursor USING sqlda; + } + + EXEC SQL CLOSE mycursor; + + free(sqlda); /* The main structure is all to be free(), + * sqlda and sqlda->sqlvar is in one allocated area */ + + For more information, see the sqlda.h header and the + src/interfaces/ecpg/test/compat_informix/sqlda.pgc regression test. + + + + + Additional Functions + + + + decadd + + + Add two decimal type values. + +int decadd(decimal *arg1, decimal *arg2, decimal *sum); + + The function receives a pointer to the first operand of type decimal + (arg1), a pointer to the second operand of type decimal + (arg2) and a pointer to a value of type decimal that will + contain the sum (sum). On success, the function returns 0. + ECPG_INFORMIX_NUM_OVERFLOW is returned in case of overflow and + ECPG_INFORMIX_NUM_UNDERFLOW in case of underflow. -1 is returned for + other failures and errno is set to the respective errno number of the + pgtypeslib. + + + + + + deccmp + + + Compare two variables of type decimal. + +int deccmp(decimal *arg1, decimal *arg2); + + The function receives a pointer to the first decimal value + (arg1), a pointer to the second decimal value + (arg2) and returns an integer value that indicates which is + the bigger value. + + + + 1, if the value that arg1 points to is bigger than the + value that var2 points to + + + + + -1, if the value that arg1 points to is smaller than the + value that arg2 points to + + + + 0, if the value that arg1 points to and the value that + arg2 points to are equal + + + + + + + + + deccopy + + + Copy a decimal value. + +void deccopy(decimal *src, decimal *target); + + The function receives a pointer to the decimal value that should be + copied as the first argument (src) and a pointer to the + target structure of type decimal (target) as the second + argument. + + + + + + deccvasc + + + Convert a value from its ASCII representation into a decimal type. + +int deccvasc(char *cp, int len, decimal *np); + + The function receives a pointer to string that contains the string + representation of the number to be converted (cp) as well + as its length len. np is a pointer to the + decimal value that saves the result of the operation. + + + Valid formats are for example: + -2, + .794, + +3.44, + 592.49E07 or + -32.84e-4. + + + The function returns 0 on success. If overflow or underflow occurred, + ECPG_INFORMIX_NUM_OVERFLOW or + ECPG_INFORMIX_NUM_UNDERFLOW is returned. If the ASCII + representation could not be parsed, + ECPG_INFORMIX_BAD_NUMERIC is returned or + ECPG_INFORMIX_BAD_EXPONENT if this problem occurred while + parsing the exponent. + + + + + + deccvdbl + + + Convert a value of type double to a value of type decimal. + +int deccvdbl(double dbl, decimal *np); + + The function receives the variable of type double that should be + converted as its first argument (dbl). As the second + argument (np), the function receives a pointer to the + decimal variable that should hold the result of the operation. + + + The function returns 0 on success and a negative value if the + conversion failed. + + + + + + deccvint + + + Convert a value of type int to a value of type decimal. + +int deccvint(int in, decimal *np); + + The function receives the variable of type int that should be + converted as its first argument (in). As the second + argument (np), the function receives a pointer to the + decimal variable that should hold the result of the operation. + + + The function returns 0 on success and a negative value if the + conversion failed. + + + + + + deccvlong + + + Convert a value of type long to a value of type decimal. + +int deccvlong(long lng, decimal *np); + + The function receives the variable of type long that should be + converted as its first argument (lng). As the second + argument (np), the function receives a pointer to the + decimal variable that should hold the result of the operation. + + + The function returns 0 on success and a negative value if the + conversion failed. + + + + + + decdiv + + + Divide two variables of type decimal. + +int decdiv(decimal *n1, decimal *n2, decimal *result); + + The function receives pointers to the variables that are the first + (n1) and the second (n2) operands and + calculates n1/n2. result is a + pointer to the variable that should hold the result of the operation. + + + On success, 0 is returned and a negative value if the division fails. + If overflow or underflow occurred, the function returns + ECPG_INFORMIX_NUM_OVERFLOW or + ECPG_INFORMIX_NUM_UNDERFLOW respectively. If an attempt to + divide by zero is observed, the function returns + ECPG_INFORMIX_DIVIDE_ZERO. + + + + + + decmul + + + Multiply two decimal values. + +int decmul(decimal *n1, decimal *n2, decimal *result); + + The function receives pointers to the variables that are the first + (n1) and the second (n2) operands and + calculates n1*n2. result is a + pointer to the variable that should hold the result of the operation. + + + On success, 0 is returned and a negative value if the multiplication + fails. If overflow or underflow occurred, the function returns + ECPG_INFORMIX_NUM_OVERFLOW or + ECPG_INFORMIX_NUM_UNDERFLOW respectively. + + + + + + decsub + + + Subtract one decimal value from another. + +int decsub(decimal *n1, decimal *n2, decimal *result); + + The function receives pointers to the variables that are the first + (n1) and the second (n2) operands and + calculates n1-n2. result is a + pointer to the variable that should hold the result of the operation. + + + On success, 0 is returned and a negative value if the subtraction + fails. If overflow or underflow occurred, the function returns + ECPG_INFORMIX_NUM_OVERFLOW or + ECPG_INFORMIX_NUM_UNDERFLOW respectively. + + + + + + dectoasc + + + Convert a variable of type decimal to its ASCII representation in a C + char* string. + +int dectoasc(decimal *np, char *cp, int len, int right) + + The function receives a pointer to a variable of type decimal + (np) that it converts to its textual representation. + cp is the buffer that should hold the result of the + operation. The parameter right specifies, how many digits + right of the decimal point should be included in the output. The result + will be rounded to this number of decimal digits. Setting + right to -1 indicates that all available decimal digits + should be included in the output. If the length of the output buffer, + which is indicated by len is not sufficient to hold the + textual representation including the trailing zero byte, only a + single * character is stored in the result and -1 is + returned. + + + The function returns either -1 if the buffer cp was too + small or ECPG_INFORMIX_OUT_OF_MEMORY if memory was + exhausted. + + + + + + dectodbl + + + Convert a variable of type decimal to a double. + +int dectodbl(decimal *np, double *dblp); + + The function receives a pointer to the decimal value to convert + (np) and a pointer to the double variable that + should hold the result of the operation (dblp). + + + On success, 0 is returned and a negative value if the conversion + failed. + + + + + + dectoint + + + Convert a variable to type decimal to an integer. + +int dectoint(decimal *np, int *ip); + + The function receives a pointer to the decimal value to convert + (np) and a pointer to the integer variable that + should hold the result of the operation (ip). + + + On success, 0 is returned and a negative value if the conversion + failed. If an overflow occurred, ECPG_INFORMIX_NUM_OVERFLOW + is returned. + + + Note that the ECPG implementation differs from the Informix + implementation. Informix limits an integer to the range from -32767 to + 32767, while the limits in the ECPG implementation depend on the + architecture (-INT_MAX .. INT_MAX). + + + + + + dectolong + + + Convert a variable to type decimal to a long integer. + +int dectolong(decimal *np, long *lngp); + + The function receives a pointer to the decimal value to convert + (np) and a pointer to the long variable that + should hold the result of the operation (lngp). + + + On success, 0 is returned and a negative value if the conversion + failed. If an overflow occurred, ECPG_INFORMIX_NUM_OVERFLOW + is returned. + + + Note that the ECPG implementation differs from the Informix + implementation. Informix limits a long integer to the range from + -2,147,483,647 to 2,147,483,647, while the limits in the ECPG + implementation depend on the architecture (-LONG_MAX .. + LONG_MAX). + + + + + + rdatestr + + + Converts a date to a C char* string. + +int rdatestr(date d, char *str); + + The function receives two arguments, the first one is the date to + convert (d) and the second one is a pointer to the target + string. The output format is always yyyy-mm-dd, so you need + to allocate at least 11 bytes (including the zero-byte terminator) for the + string. + + + The function returns 0 on success and a negative value in case of + error. + + + Note that ECPG's implementation differs from the Informix + implementation. In Informix the format can be influenced by setting + environment variables. In ECPG however, you cannot change the output + format. + + + + + + rstrdate + + + Parse the textual representation of a date. + +int rstrdate(char *str, date *d); + + The function receives the textual representation of the date to convert + (str) and a pointer to a variable of type date + (d). This function does not allow you to specify a format + mask. It uses the default format mask of Informix which is + mm/dd/yyyy. Internally, this function is implemented by + means of rdefmtdate. Therefore, rstrdate is + not faster and if you have the choice you should opt for + rdefmtdate which allows you to specify the format mask + explicitly. + + + The function returns the same values as rdefmtdate. + + + + + + rtoday + + + Get the current date. + +void rtoday(date *d); + + The function receives a pointer to a date variable (d) + that it sets to the current date. + + + Internally this function uses the + function. + + + + + + rjulmdy + + + Extract the values for the day, the month and the year from a variable + of type date. + +int rjulmdy(date d, short mdy[3]); + + The function receives the date d and a pointer to an array + of 3 short integer values mdy. The variable name indicates + the sequential order: mdy[0] will be set to contain the + number of the month, mdy[1] will be set to the value of the + day and mdy[2] will contain the year. + + + The function always returns 0 at the moment. + + + Internally the function uses the + function. + + + + + + rdefmtdate + + + Use a format mask to convert a character string to a value of type + date. + +int rdefmtdate(date *d, char *fmt, char *str); + + The function receives a pointer to the date value that should hold the + result of the operation (d), the format mask to use for + parsing the date (fmt) and the C char* string containing + the textual representation of the date (str). The textual + representation is expected to match the format mask. However you do not + need to have a 1:1 mapping of the string to the format mask. The + function only analyzes the sequential order and looks for the literals + yy or yyyy that indicate the + position of the year, mm to indicate the position of + the month and dd to indicate the position of the + day. + + + The function returns the following values: + + + + 0 - The function terminated successfully. + + + + + ECPG_INFORMIX_ENOSHORTDATE - The date does not contain + delimiters between day, month and year. In this case the input + string must be exactly 6 or 8 bytes long but isn't. + + + + + ECPG_INFORMIX_ENOTDMY - The format string did not + correctly indicate the sequential order of year, month and day. + + + + + ECPG_INFORMIX_BAD_DAY - The input string does not + contain a valid day. + + + + + ECPG_INFORMIX_BAD_MONTH - The input string does not + contain a valid month. + + + + + ECPG_INFORMIX_BAD_YEAR - The input string does not + contain a valid year. + + + + + + Internally this function is implemented to use the function. See the reference there for a + table of example input. + + + + + + rfmtdate + + + Convert a variable of type date to its textual representation using a + format mask. + +int rfmtdate(date d, char *fmt, char *str); + + The function receives the date to convert (d), the format + mask (fmt) and the string that will hold the textual + representation of the date (str). + + + On success, 0 is returned and a negative value if an error occurred. + + + Internally this function uses the + function, see the reference there for examples. + + + + + + rmdyjul + + + Create a date value from an array of 3 short integers that specify the + day, the month and the year of the date. + +int rmdyjul(short mdy[3], date *d); + + The function receives the array of the 3 short integers + (mdy) and a pointer to a variable of type date that should + hold the result of the operation. + + + Currently the function returns always 0. + + + Internally the function is implemented to use the function . + + + + + + rdayofweek + + + Return a number representing the day of the week for a date value. + +int rdayofweek(date d); + + The function receives the date variable d as its only + argument and returns an integer that indicates the day of the week for + this date. + + + + 0 - Sunday + + + + + 1 - Monday + + + + + 2 - Tuesday + + + + + 3 - Wednesday + + + + + 4 - Thursday + + + + + 5 - Friday + + + + + 6 - Saturday + + + + + + Internally the function is implemented to use the function . + + + + + + dtcurrent + + + Retrieve the current timestamp. + +void dtcurrent(timestamp *ts); + + The function retrieves the current timestamp and saves it into the + timestamp variable that ts points to. + + + + + + dtcvasc + + + Parses a timestamp from its textual representation + into a timestamp variable. + +int dtcvasc(char *str, timestamp *ts); + + The function receives the string to parse (str) and a + pointer to the timestamp variable that should hold the result of the + operation (ts). + + + The function returns 0 on success and a negative value in case of + error. + + + Internally this function uses the function. See the reference there + for a table with example inputs. + + + + + + dtcvfmtasc + + + Parses a timestamp from its textual representation + using a format mask into a timestamp variable. + +dtcvfmtasc(char *inbuf, char *fmtstr, timestamp *dtvalue) + + The function receives the string to parse (inbuf), the + format mask to use (fmtstr) and a pointer to the timestamp + variable that should hold the result of the operation + (dtvalue). + + + This function is implemented by means of the function. See the documentation + there for a list of format specifiers that can be used. + + + The function returns 0 on success and a negative value in case of + error. + + + + + + dtsub + + + Subtract one timestamp from another and return a variable of type + interval. + +int dtsub(timestamp *ts1, timestamp *ts2, interval *iv); + + The function will subtract the timestamp variable that ts2 + points to from the timestamp variable that ts1 points to + and will store the result in the interval variable that iv + points to. + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + + + + dttoasc + + + Convert a timestamp variable to a C char* string. + +int dttoasc(timestamp *ts, char *output); + + The function receives a pointer to the timestamp variable to convert + (ts) and the string that should hold the result of the + operation (output). It converts ts to its + textual representation according to the SQL standard, which is + be YYYY-MM-DD HH:MM:SS. + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + + + + dttofmtasc + + + Convert a timestamp variable to a C char* using a format mask. + +int dttofmtasc(timestamp *ts, char *output, int str_len, char *fmtstr); + + The function receives a pointer to the timestamp to convert as its + first argument (ts), a pointer to the output buffer + (output), the maximal length that has been allocated for + the output buffer (str_len) and the format mask to + use for the conversion (fmtstr). + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + Internally, this function uses the function. See the reference there for + information on what format mask specifiers can be used. + + + + + + intoasc + + + Convert an interval variable to a C char* string. + +int intoasc(interval *i, char *str); + + The function receives a pointer to the interval variable to convert + (i) and the string that should hold the result of the + operation (str). It converts i to its + textual representation according to the SQL standard, which is + be YYYY-MM-DD HH:MM:SS. + + + Upon success, the function returns 0 and a negative value if an + error occurred. + + + + + + rfmtlong + + + Convert a long integer value to its textual representation using a + format mask. + +int rfmtlong(long lng_val, char *fmt, char *outbuf); + + The function receives the long value lng_val, the format + mask fmt and a pointer to the output buffer + outbuf. It converts the long value according to the format + mask to its textual representation. + + + The format mask can be composed of the following format specifying + characters: + + + + * (asterisk) - if this position would be blank + otherwise, fill it with an asterisk. + + + + + & (ampersand) - if this position would be + blank otherwise, fill it with a zero. + + + + + # - turn leading zeroes into blanks. + + + + + < - left-justify the number in the string. + + + + + , (comma) - group numbers of four or more digits + into groups of three digits separated by a comma. + + + + + . (period) - this character separates the + whole-number part of the number from the fractional part. + + + + + - (minus) - the minus sign appears if the number + is a negative value. + + + + + + (plus) - the plus sign appears if the number is + a positive value. + + + + + ( - this replaces the minus sign in front of the + negative number. The minus sign will not appear. + + + + + ) - this character replaces the minus and is + printed behind the negative value. + + + + + $ - the currency symbol. + + + + + + + + + rupshift + + + Convert a string to upper case. + +void rupshift(char *str); + + The function receives a pointer to the string and transforms every + lower case character to upper case. + + + + + + byleng + + + Return the number of characters in a string without counting trailing + blanks. + +int byleng(char *str, int len); + + The function expects a fixed-length string as its first argument + (str) and its length as its second argument + (len). It returns the number of significant characters, + that is the length of the string without trailing blanks. + + + + + + ldchar + + + Copy a fixed-length string into a null-terminated string. + +void ldchar(char *src, int len, char *dest); + + The function receives the fixed-length string to copy + (src), its length (len) and a pointer to the + destination memory (dest). Note that you need to reserve at + least len+1 bytes for the string that dest + points to. The function copies at most len bytes to the new + location (less if the source string has trailing blanks) and adds the + null-terminator. + + + + + + rgetmsg + + + +int rgetmsg(int msgnum, char *s, int maxsize); + + This function exists but is not implemented at the moment! + + + + + + rtypalign + + + +int rtypalign(int offset, int type); + + This function exists but is not implemented at the moment! + + + + + + rtypmsize + + + +int rtypmsize(int type, int len); + + This function exists but is not implemented at the moment! + + + + + + rtypwidth + + + +int rtypwidth(int sqltype, int sqllen); + + This function exists but is not implemented at the moment! + + + + + + rsetnull + + + Set a variable to NULL. + +int rsetnull(int t, char *ptr); + + The function receives an integer that indicates the type of the + variable and a pointer to the variable itself that is cast to a C + char* pointer. + + + The following types exist: + + + + CCHARTYPE - For a variable of type char or char* + + + + + CSHORTTYPE - For a variable of type short int + + + + + CINTTYPE - For a variable of type int + + + + + CBOOLTYPE - For a variable of type boolean + + + + + CFLOATTYPE - For a variable of type float + + + + + CLONGTYPE - For a variable of type long + + + + + CDOUBLETYPE - For a variable of type double + + + + + CDECIMALTYPE - For a variable of type decimal + + + + + CDATETYPE - For a variable of type date + + + + + CDTIMETYPE - For a variable of type timestamp + + + + + + + Here is an example of a call to this function: + + + + + + + + risnull + + + Test if a variable is NULL. + +int risnull(int t, char *ptr); + + The function receives the type of the variable to test (t) + as well a pointer to this variable (ptr). Note that the + latter needs to be cast to a char*. See the function for a list of possible variable types. + + + Here is an example of how to use this function: + + + + + + + + + + + Additional Constants + + Note that all constants here describe errors and all of them are defined + to represent negative values. In the descriptions of the different + constants you can also find the value that the constants represent in the + current implementation. However you should not rely on this number. You can + however rely on the fact all of them are defined to represent negative + values. + + + ECPG_INFORMIX_NUM_OVERFLOW + + + Functions return this value if an overflow occurred in a + calculation. Internally it is defined as -1200 (the Informix + definition). + + + + + + ECPG_INFORMIX_NUM_UNDERFLOW + + + Functions return this value if an underflow occurred in a calculation. + Internally it is defined as -1201 (the Informix definition). + + + + + + ECPG_INFORMIX_DIVIDE_ZERO + + + Functions return this value if an attempt to divide by zero is + observed. Internally it is defined as -1202 (the Informix definition). + + + + + + ECPG_INFORMIX_BAD_YEAR + + + Functions return this value if a bad value for a year was found while + parsing a date. Internally it is defined as -1204 (the Informix + definition). + + + + + + ECPG_INFORMIX_BAD_MONTH + + + Functions return this value if a bad value for a month was found while + parsing a date. Internally it is defined as -1205 (the Informix + definition). + + + + + + ECPG_INFORMIX_BAD_DAY + + + Functions return this value if a bad value for a day was found while + parsing a date. Internally it is defined as -1206 (the Informix + definition). + + + + + + ECPG_INFORMIX_ENOSHORTDATE + + + Functions return this value if a parsing routine needs a short date + representation but did not get the date string in the right length. + Internally it is defined as -1209 (the Informix definition). + + + + + + ECPG_INFORMIX_DATE_CONVERT + + + Functions return this value if an error occurred during date + formatting. Internally it is defined as -1210 (the + Informix definition). + + + + + + ECPG_INFORMIX_OUT_OF_MEMORY + + + Functions return this value if memory was exhausted during + their operation. Internally it is defined as -1211 (the + Informix definition). + + + + + + ECPG_INFORMIX_ENOTDMY + + + Functions return this value if a parsing routine was supposed to get a + format mask (like mmddyy) but not all fields were listed + correctly. Internally it is defined as -1212 (the Informix definition). + + + + + + ECPG_INFORMIX_BAD_NUMERIC + + + Functions return this value either if a parsing routine cannot parse + the textual representation for a numeric value because it contains + errors or if a routine cannot complete a calculation involving numeric + variables because at least one of the numeric variables is invalid. + Internally it is defined as -1213 (the Informix definition). + + + + + + ECPG_INFORMIX_BAD_EXPONENT + + + Functions return this value if a parsing routine cannot parse + an exponent. Internally it is defined as -1216 (the + Informix definition). + + + + + + ECPG_INFORMIX_BAD_DATE + + + Functions return this value if a parsing routine cannot parse + a date. Internally it is defined as -1218 (the + Informix definition). + + + + + + ECPG_INFORMIX_EXTRA_CHARS + + + Functions return this value if a parsing routine is passed extra + characters it cannot parse. Internally it is defined as -1264 (the + Informix definition). + + + + + + + + + + Internals + + + This section explains how ECPG works + internally. This information can occasionally be useful to help + users understand how to use ECPG. + + + + The first four lines written by ecpg to the + output are fixed lines. Two are comments and two are include + lines necessary to interface to the library. Then the + preprocessor reads through the file and writes output. Normally + it just echoes everything to the output. + + + + When it sees an EXEC SQL statement, it + intervenes and changes it. The command starts with EXEC + SQL and ends with ;. Everything in + between is treated as an SQL statement and + parsed for variable substitution. + + + + Variable substitution occurs when a symbol starts with a colon + (:). The variable with that name is looked up + among the variables that were previously declared within a + EXEC SQL DECLARE section. + + + + The most important function in the library is + ECPGdo, which takes care of executing most + commands. It takes a variable number of arguments. This can easily + add up to 50 or so arguments, and we hope this will not be a + problem on any platform. + + + + The arguments are: + + + + A line number + + + This is the line number of the original line; used in error + messages only. + + + + + + A string + + + This is the SQL command that is to be issued. + It is modified by the input variables, i.e., the variables that + where not known at compile time but are to be entered in the + command. Where the variables should go the string contains + ?. + + + + + + Input variables + + + Every input variable causes ten arguments to be created. (See below.) + + + + + + ECPGt_EOIT + + + An enum telling that there are no more input + variables. + + + + + + Output variables + + + Every output variable causes ten arguments to be created. + (See below.) These variables are filled by the function. + + + + + + ECPGt_EORT + + + An enum telling that there are no more variables. + + + + + + + + For every variable that is part of the SQL + command, the function gets ten arguments: + + + + + The type as a special symbol. + + + + + + A pointer to the value or a pointer to the pointer. + + + + + + The size of the variable if it is a char or varchar. + + + + + + The number of elements in the array (for array fetches). + + + + + + The offset to the next element in the array (for array fetches). + + + + + + The type of the indicator variable as a special symbol. + + + + + + A pointer to the indicator variable. + + + + + + 0 + + + + + + The number of elements in the indicator array (for array fetches). + + + + + + The offset to the next element in the indicator array (for + array fetches). + + + + + + + Note that not all SQL commands are treated in this way. For + instance, an open cursor statement like: + +EXEC SQL OPEN cursor; + + is not copied to the output. Instead, the cursor's + DECLARE command is used at the position of the OPEN command + because it indeed opens the cursor. + + + + Here is a complete example describing the output of the + preprocessor of a file foo.pgc (details might + change with each particular version of the preprocessor): + +EXEC SQL BEGIN DECLARE SECTION; +int index; +int result; +EXEC SQL END DECLARE SECTION; +... +EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index; + + is translated into: +; +#include ; + +/* exec sql begin declare section */ + +#line 1 "foo.pgc" + + int index; + int result; +/* exec sql end declare section */ +... +ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ? ", + ECPGt_int,&(index),1L,1L,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, + ECPGt_int,&(result),1L,1L,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 147 "foo.pgc" +]]> + + (The indentation here is added for readability and not + something the preprocessor does.) + + +
diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml new file mode 100644 index 000000000000..e928894726c8 --- /dev/null +++ b/doc/src/sgml/extend.sgml @@ -0,0 +1,1873 @@ + + + + Extending <acronym>SQL</acronym> + + + extending SQL + + + + In the sections that follow, we will discuss how you + can extend the PostgreSQL + SQL query language by adding: + + + + + functions (starting in ) + + + + + aggregates (starting in ) + + + + + data types (starting in ) + + + + + operators (starting in ) + + + + + operator classes for indexes (starting in ) + + + + + packages of related objects (starting in ) + + + + + + + How Extensibility Works + + + PostgreSQL is extensible because its operation is + catalog-driven. If you are familiar with standard + relational database systems, you know that they store information + about databases, tables, columns, etc., in what are + commonly known as system catalogs. (Some systems call + this the data dictionary.) The catalogs appear to the + user as tables like any other, but the DBMS stores + its internal bookkeeping in them. One key difference + between PostgreSQL and standard relational database systems is + that PostgreSQL stores much more information in its + catalogs: not only information about tables and columns, + but also information about data types, functions, access + methods, and so on. These tables can be modified by + the user, and since PostgreSQL bases its operation + on these tables, this means that PostgreSQL can be + extended by users. By comparison, conventional + database systems can only be extended by changing hardcoded + procedures in the source code or by loading modules + specially written by the DBMS vendor. + + + + The PostgreSQL server can moreover + incorporate user-written code into itself through dynamic loading. + That is, the user can specify an object code file (e.g., a shared + library) that implements a new type or function, and + PostgreSQL will load it as required. + Code written in SQL is even more trivial to add + to the server. This ability to modify its operation on the + fly makes PostgreSQL uniquely + suited for rapid prototyping of new applications and storage + structures. + + + + + The <productname>PostgreSQL</productname> Type System + + + base type + + + + data type + base + + + + composite type + + + + data type + composite + + + + container type + + + + data type + container + + + + PostgreSQL data types can be divided into base + types, container types, domains, and pseudo-types. + + + + Base Types + + + Base types are those, like integer, that are + implemented below the level of the SQL language + (typically in a low-level language such as C). They generally + correspond to what are often known as abstract data types. + PostgreSQL can only operate on such + types through functions provided by the user and only understands + the behavior of such types to the extent that the user describes + them. + The built-in base types are described in . + + + + Enumerated (enum) types can be considered as a subcategory of base + types. The main difference is that they can be created using + just SQL commands, without any low-level programming. + Refer to for more information. + + + + + Container Types + + + PostgreSQL has three kinds + of container types, which are types that contain multiple + values of other types. These are arrays, composites, and ranges. + + + + Arrays can hold multiple values that are all of the same type. An array + type is automatically created for each base type, composite type, range + type, and domain type. But there are no arrays of arrays. So far as + the type system is concerned, multi-dimensional arrays are the same as + one-dimensional arrays. Refer to for more + information. + + + + Composite types, or row types, are created whenever the user + creates a table. It is also possible to use to + define a stand-alone composite type with no associated + table. A composite type is simply a list of types with + associated field names. A value of a composite type is a row or + record of field values. Refer to + for more information. + + + + A range type can hold two values of the same type, which are the lower + and upper bounds of the range. Range types are user-created, although + a few built-in ones exist. Refer to + for more information. + + + + + Domains + + + A domain is based on a particular underlying type and for many purposes + is interchangeable with its underlying type. However, a domain can have + constraints that restrict its valid values to a subset of what the + underlying type would allow. Domains are created using + the SQL command . + Refer to for more information. + + + + + Pseudo-Types + + + There are a few pseudo-types for special purposes. + Pseudo-types cannot appear as columns of tables or components of + container types, but they can be used to declare the argument and + result types of functions. This provides a mechanism within the + type system to identify special classes of functions. lists the existing + pseudo-types. + + + + + Polymorphic Types + + + polymorphic type + + + + polymorphic function + + + + data type + polymorphic + + + + function + polymorphic + + + + Some pseudo-types of special interest are the polymorphic + types, which are used to declare polymorphic + functions. This powerful feature allows a single function + definition to operate on many different data types, with the specific + data type(s) being determined by the data types actually passed to it + in a particular call. The polymorphic types are shown in + . Some examples of + their use appear in . + + + + Polymorphic Types + + + + + + + Name + Family + Description + + + + + + anyelement + Simple + Indicates that a function accepts any data type + + + + anyarray + Simple + Indicates that a function accepts any array data type + + + + anynonarray + Simple + Indicates that a function accepts any non-array data type + + + + anyenum + Simple + Indicates that a function accepts any enum data type + (see ) + + + + + anyrange + Simple + Indicates that a function accepts any range data type + (see ) + + + + + anymultirange + Simple + Indicates that a function accepts any multirange data type + (see ) + + + + + anycompatible + Common + Indicates that a function accepts any data type, + with automatic promotion of multiple arguments to a common data type + + + + + anycompatiblearray + Common + Indicates that a function accepts any array data type, + with automatic promotion of multiple arguments to a common data type + + + + + anycompatiblenonarray + Common + Indicates that a function accepts any non-array data type, + with automatic promotion of multiple arguments to a common data type + + + + + anycompatiblerange + Common + Indicates that a function accepts any range data type, + with automatic promotion of multiple arguments to a common data type + + + + + anycompatiblemultirange + Common + Indicates that a function accepts any multirange data type, + with automatic promotion of multiple arguments to a common data type + + + + +
+ + + Polymorphic arguments and results are tied to each other and are resolved + to specific data types when a query calling a polymorphic function is + parsed. When there is more than one polymorphic argument, the actual + data types of the input values must match up as described below. If the + function's result type is polymorphic, or it has output parameters of + polymorphic types, the types of those results are deduced from the + actual types of the polymorphic inputs as described below. + + + + For the simple family of polymorphic types, the + matching and deduction rules work like this: + + + + Each position (either argument or return value) declared as + anyelement is allowed to have any specific actual + data type, but in any given call they must all be the + same actual type. Each + position declared as anyarray can have any array data type, + but similarly they must all be the same type. And similarly, + positions declared as anyrange must all be the same range + type. Likewise for anymultirange. + + + + Furthermore, if there are + positions declared anyarray and others declared + anyelement, the actual array type in the + anyarray positions must be an array whose elements are + the same type appearing in the anyelement positions. + anynonarray is treated exactly the same as anyelement, + but adds the additional constraint that the actual type must not be + an array type. + anyenum is treated exactly the same as anyelement, + but adds the additional constraint that the actual type must + be an enum type. + + + + Similarly, if there are positions declared anyrange + and others declared anyelement or anyarray, + the actual range type in the anyrange positions must be a + range whose subtype is the same type appearing in + the anyelement positions and the same as the element type + of the anyarray positions. + If there are positions declared anymultirange, + their actual multirange type must contain ranges matching parameters declared + anyrange and base elements matching parameters declared + anyelement and anyarray. + + + + Thus, when more than one argument position is declared with a polymorphic + type, the net effect is that only certain combinations of actual argument + types are allowed. For example, a function declared as + equal(anyelement, anyelement) will take any two input values, + so long as they are of the same data type. + + + + When the return value of a function is declared as a polymorphic type, + there must be at least one argument position that is also polymorphic, + and the actual data type(s) supplied for the polymorphic arguments + determine the actual + result type for that call. For example, if there were not already + an array subscripting mechanism, one could define a function that + implements subscripting as subscript(anyarray, integer) + returns anyelement. This declaration constrains the actual first + argument to be an array type, and allows the parser to infer the correct + result type from the actual first argument's type. Another example + is that a function declared as f(anyarray) returns anyenum + will only accept arrays of enum types. + + + + In most cases, the parser can infer the actual data type for a + polymorphic result type from arguments that are of a different + polymorphic type in the same family; for example anyarray + can be deduced from anyelement or vice versa. + An exception is that a + polymorphic result of type anyrange requires an argument + of type anyrange; it cannot be deduced + from anyarray or anyelement arguments. This + is because there could be multiple range types with the same subtype. + + + + Note that anynonarray and anyenum do not represent + separate type variables; they are the same type as + anyelement, just with an additional constraint. For + example, declaring a function as f(anyelement, anyenum) + is equivalent to declaring it as f(anyenum, anyenum): + both actual arguments have to be the same enum type. + + + + For the common family of polymorphic types, the + matching and deduction rules work approximately the same as for + the simple family, with one major difference: the + actual types of the arguments need not be identical, so long as they + can be implicitly cast to a single common type. The common type is + selected following the same rules as for UNION and + related constructs (see ). + Selection of the common type considers the actual types + of anycompatible and anycompatiblenonarray + inputs, the array element types of anycompatiblearray + inputs, the range subtypes of anycompatiblerange inputs, + and the multirange subtypes of anycompatiblemultirange + inputs. If anycompatiblenonarray is present then the + common type is required to be a non-array type. Once a common type is + identified, arguments in anycompatible + and anycompatiblenonarray positions are automatically + cast to that type, and arguments in anycompatiblearray + positions are automatically cast to the array type for that type. + + + + Since there is no way to select a range type knowing only its subtype, + use of anycompatiblerange and/or + anycompatiblemultirange requires that all arguments declared + with that type have the same actual range and/or multirange type, and that + that type's subtype agree with the selected common type, so that no casting + of the range values is required. As with anyrange and + anymultirange, use of anycompatiblerange and + anymultirange as a function result type requires that there be + an anycompatiblerange or anycompatiblemultirange + argument. + + + + Notice that there is no anycompatibleenum type. Such a + type would not be very useful, since there normally are not any + implicit casts to enum types, meaning that there would be no way to + resolve a common type for dissimilar enum inputs. + + + + The simple and common polymorphic + families represent two independent sets of type variables. Consider + for example + +CREATE FUNCTION myfunc(a anyelement, b anyelement, + c anycompatible, d anycompatible) +RETURNS anycompatible AS ... + + In an actual call of this function, the first two inputs must have + exactly the same type. The last two inputs must be promotable to a + common type, but this type need not have anything to do with the type + of the first two inputs. The result will have the common type of the + last two inputs. + + + + A variadic function (one taking a variable number of arguments, as in + ) can be + polymorphic: this is accomplished by declaring its last parameter as + VARIADIC anyarray or + VARIADIC anycompatiblearray. + For purposes of argument + matching and determining the actual result type, such a function behaves + the same as if you had written the appropriate number of + anynonarray or anycompatiblenonarray + parameters. + +
+
+ + &xfunc; + &xaggr; + &xtypes; + &xoper; + &xindex; + + + + Packaging Related Objects into an Extension + + + extension + + + + A useful extension to PostgreSQL typically includes + multiple SQL objects; for example, a new data type will require new + functions, new operators, and probably new index operator classes. + It is helpful to collect all these objects into a single package + to simplify database management. PostgreSQL calls + such a package an extension. To define an extension, + you need at least a script file that contains the + SQL commands to create the extension's objects, and a + control file that specifies a few basic properties + of the extension itself. If the extension includes C code, there + will typically also be a shared library file into which the C code + has been built. Once you have these files, a simple + CREATE EXTENSION command loads the objects into + your database. + + + + The main advantage of using an extension, rather than just running the + SQL script to load a bunch of loose objects + into your database, is that PostgreSQL will then + understand that the objects of the extension go together. You can + drop all the objects with a single DROP EXTENSION + command (no need to maintain a separate uninstall script). + Even more useful, pg_dump knows that it should not + dump the individual member objects of the extension — it will + just include a CREATE EXTENSION command in dumps, instead. + This vastly simplifies migration to a new version of the extension + that might contain more or different objects than the old version. + Note however that you must have the extension's control, script, and + other files available when loading such a dump into a new database. + + + + PostgreSQL will not let you drop an individual object + contained in an extension, except by dropping the whole extension. + Also, while you can change the definition of an extension member object + (for example, via CREATE OR REPLACE FUNCTION for a + function), bear in mind that the modified definition will not be dumped + by pg_dump. Such a change is usually only sensible if + you concurrently make the same change in the extension's script file. + (But there are special provisions for tables containing configuration + data; see .) + In production situations, it's generally better to create an extension + update script to perform changes to extension member objects. + + + + The extension script may set privileges on objects that are part of the + extension, using GRANT and REVOKE + statements. The final set of privileges for each object (if any are set) + will be stored in the + pg_init_privs + system catalog. When pg_dump is used, the + CREATE EXTENSION command will be included in the dump, followed + by the set of GRANT and REVOKE + statements necessary to set the privileges on the objects to what they were + at the time the dump was taken. + + + + PostgreSQL does not currently support extension scripts + issuing CREATE POLICY or SECURITY LABEL + statements. These are expected to be set after the extension has been + created. All RLS policies and security labels on extension objects will be + included in dumps created by pg_dump. + + + + The extension mechanism also has provisions for packaging modification + scripts that adjust the definitions of the SQL objects contained in an + extension. For example, if version 1.1 of an extension adds one function + and changes the body of another function compared to 1.0, the extension + author can provide an update script that makes just those + two changes. The ALTER EXTENSION UPDATE command can then + be used to apply these changes and track which version of the extension + is actually installed in a given database. + + + + The kinds of SQL objects that can be members of an extension are shown in + the description of ALTER EXTENSION. Notably, objects + that are database-cluster-wide, such as databases, roles, and tablespaces, + cannot be extension members since an extension is only known within one + database. (Although an extension script is not prohibited from creating + such objects, if it does so they will not be tracked as part of the + extension.) Also notice that while a table can be a member of an + extension, its subsidiary objects such as indexes are not directly + considered members of the extension. + Another important point is that schemas can belong to extensions, but not + vice versa: an extension as such has an unqualified name and does not + exist within any schema. The extension's member objects, + however, will belong to schemas whenever appropriate for their object + types. It may or may not be appropriate for an extension to own the + schema(s) its member objects are within. + + + + If an extension's script creates any temporary objects (such as temp + tables), those objects are treated as extension members for the + remainder of the current session, but are automatically dropped at + session end, as any temporary object would be. This is an exception + to the rule that extension member objects cannot be dropped without + dropping the whole extension. + + + + Extension Files + + + control file + + + + The CREATE EXTENSION command relies on a control + file for each extension, which must be named the same as the extension + with a suffix of .control, and must be placed in the + installation's SHAREDIR/extension directory. There + must also be at least one SQL script file, which follows the + naming pattern + extension--version.sql + (for example, foo--1.0.sql for version 1.0 of + extension foo). By default, the script file(s) are also + placed in the SHAREDIR/extension directory; but the + control file can specify a different directory for the script file(s). + + + + The file format for an extension control file is the same as for the + postgresql.conf file, namely a list of + parameter_name = value + assignments, one per line. Blank lines and comments introduced by + # are allowed. Be sure to quote any value that is not + a single word or number. + + + + A control file can set the following parameters: + + + + + directory (string) + + + The directory containing the extension's SQL script + file(s). Unless an absolute path is given, the name is relative to + the installation's SHAREDIR directory. The + default behavior is equivalent to specifying + directory = 'extension'. + + + + + + default_version (string) + + + The default version of the extension (the one that will be installed + if no version is specified in CREATE EXTENSION). Although + this can be omitted, that will result in CREATE EXTENSION + failing if no VERSION option appears, so you generally + don't want to do that. + + + + + + comment (string) + + + A comment (any string) about the extension. The comment is applied + when initially creating an extension, but not during extension updates + (since that might override user-added comments). Alternatively, + the extension's comment can be set by writing + a command in the script file. + + + + + + encoding (string) + + + The character set encoding used by the script file(s). This should + be specified if the script files contain any non-ASCII characters. + Otherwise the files will be assumed to be in the database encoding. + + + + + + module_pathname (string) + + + The value of this parameter will be substituted for each occurrence + of MODULE_PATHNAME in the script file(s). If it is not + set, no substitution is made. Typically, this is set to + $libdir/shared_library_name and + then MODULE_PATHNAME is used in CREATE + FUNCTION commands for C-language functions, so that the script + files do not need to hard-wire the name of the shared library. + + + + + + requires (string) + + + A list of names of extensions that this extension depends on, + for example requires = 'foo, bar'. Those + extensions must be installed before this one can be installed. + + + + + + superuser (boolean) + + + If this parameter is true (which is the default), + only superusers can create the extension or update it to a new + version (but see also trusted, below). + If it is set to false, just the privileges + required to execute the commands in the installation or update script + are required. + This should normally be set to true if any of the + script commands require superuser privileges. (Such commands would + fail anyway, but it's more user-friendly to give the error up front.) + + + + + + trusted (boolean) + + + This parameter, if set to true (which is not the + default), allows some non-superusers to install an extension that + has superuser set to true. + Specifically, installation will be permitted for anyone who has + CREATE privilege on the current database. + When the user executing CREATE EXTENSION is not + a superuser but is allowed to install by virtue of this parameter, + then the installation or update script is run as the bootstrap + superuser, not as the calling user. + This parameter is irrelevant if superuser is + false. + Generally, this should not be set true for extensions that could + allow access to otherwise-superuser-only abilities, such as + file system access. + Also, marking an extension trusted requires significant extra effort + to write the extension's installation and update script(s) securely; + see . + + + + + + relocatable (boolean) + + + An extension is relocatable if it is possible to move + its contained objects into a different schema after initial creation + of the extension. The default is false, i.e., the + extension is not relocatable. + See for more information. + + + + + + schema (string) + + + This parameter can only be set for non-relocatable extensions. + It forces the extension to be loaded into exactly the named schema + and not any other. + The schema parameter is consulted only when + initially creating an extension, not during extension updates. + See for more information. + + + + + + + In addition to the primary control file + extension.control, + an extension can have secondary control files named in the style + extension--version.control. + If supplied, these must be located in the script file directory. + Secondary control files follow the same format as the primary control + file. Any parameters set in a secondary control file override the + primary control file when installing or updating to that version of + the extension. However, the parameters directory and + default_version cannot be set in a secondary control file. + + + + An extension's SQL script files can contain any SQL commands, + except for transaction control commands (BEGIN, + COMMIT, etc) and commands that cannot be executed inside a + transaction block (such as VACUUM). This is because the + script files are implicitly executed within a transaction block. + + + + An extension's SQL script files can also contain lines + beginning with \echo, which will be ignored (treated as + comments) by the extension mechanism. This provision is commonly used + to throw an error if the script file is fed to psql + rather than being loaded via CREATE EXTENSION (see example + script in ). + Without that, users might accidentally load the + extension's contents as loose objects rather than as an + extension, a state of affairs that's a bit tedious to recover from. + + + + If the extension script contains the + string @extowner@, that string is replaced with the + (suitably quoted) name of the user calling CREATE + EXTENSION or ALTER EXTENSION. Typically + this feature is used by extensions that are marked trusted to assign + ownership of selected objects to the calling user rather than the + bootstrap superuser. (One should be careful about doing so, however. + For example, assigning ownership of a C-language function to a + non-superuser would create a privilege escalation path for that user.) + + + + While the script files can contain any characters allowed by the specified + encoding, control files should contain only plain ASCII, because there + is no way for PostgreSQL to know what encoding a + control file is in. In practice this is only an issue if you want to + use non-ASCII characters in the extension's comment. Recommended + practice in that case is to not use the control file comment + parameter, but instead use COMMENT ON EXTENSION + within a script file to set the comment. + + + + + + Extension Relocatability + + + Users often wish to load the objects contained in an extension into a + different schema than the extension's author had in mind. There are + three supported levels of relocatability: + + + + + + A fully relocatable extension can be moved into another schema + at any time, even after it's been loaded into a database. + This is done with the ALTER EXTENSION SET SCHEMA + command, which automatically renames all the member objects into + the new schema. Normally, this is only possible if the extension + contains no internal assumptions about what schema any of its + objects are in. Also, the extension's objects must all be in one + schema to begin with (ignoring objects that do not belong to any + schema, such as procedural languages). Mark a fully relocatable + extension by setting relocatable = true in its control + file. + + + + + + An extension might be relocatable during installation but not + afterwards. This is typically the case if the extension's script + file needs to reference the target schema explicitly, for example + in setting search_path properties for SQL functions. + For such an extension, set relocatable = false in its + control file, and use @extschema@ to refer to the target + schema in the script file. All occurrences of this string will be + replaced by the actual target schema's name before the script is + executed. The user can set the target schema using the + SCHEMA option of CREATE EXTENSION. + + + + + + If the extension does not support relocation at all, set + relocatable = false in its control file, and also set + schema to the name of the intended target schema. This + will prevent use of the SCHEMA option of CREATE + EXTENSION, unless it specifies the same schema named in the control + file. This choice is typically necessary if the extension contains + internal assumptions about schema names that can't be replaced by + uses of @extschema@. The @extschema@ + substitution mechanism is available in this case too, although it is + of limited use since the schema name is determined by the control file. + + + + + + In all cases, the script file will be executed with + initially set to point to the target + schema; that is, CREATE EXTENSION does the equivalent of + this: + +SET LOCAL search_path TO @extschema@, pg_temp; + + This allows the objects created by the script file to go into the target + schema. The script file can change search_path if it wishes, + but that is generally undesirable. search_path is restored + to its previous setting upon completion of CREATE EXTENSION. + + + + The target schema is determined by the schema parameter in + the control file if that is given, otherwise by the SCHEMA + option of CREATE EXTENSION if that is given, otherwise the + current default object creation schema (the first one in the caller's + search_path). When the control file schema + parameter is used, the target schema will be created if it doesn't + already exist, but in the other two cases it must already exist. + + + + If any prerequisite extensions are listed in requires + in the control file, their target schemas are added to the initial + setting of search_path, following the new + extension's target schema. This allows their objects to be visible to + the new extension's script file. + + + + For security, pg_temp is automatically appended to + the end of search_path in all cases. + + + + Although a non-relocatable extension can contain objects spread across + multiple schemas, it is usually desirable to place all the objects meant + for external use into a single schema, which is considered the extension's + target schema. Such an arrangement works conveniently with the default + setting of search_path during creation of dependent + extensions. + + + + + Extension Configuration Tables + + + Some extensions include configuration tables, which contain data that + might be added or changed by the user after installation of the + extension. Ordinarily, if a table is part of an extension, neither + the table's definition nor its content will be dumped by + pg_dump. But that behavior is undesirable for a + configuration table; any data changes made by the user need to be + included in dumps, or the extension will behave differently after a dump + and reload. + + + + pg_extension_config_dump + + + + To solve this problem, an extension's script file can mark a table + or a sequence it has created as a configuration relation, which will + cause pg_dump to include the table's or the sequence's + contents (not its definition) in dumps. To do that, call the function + pg_extension_config_dump(regclass, text) after creating the + table or the sequence, for example + +CREATE TABLE my_config (key text, value text); +CREATE SEQUENCE my_config_seq; + +SELECT pg_catalog.pg_extension_config_dump('my_config', ''); +SELECT pg_catalog.pg_extension_config_dump('my_config_seq', ''); + + Any number of tables or sequences can be marked this way. Sequences + associated with serial or bigserial columns can + be marked as well. + + + + When the second argument of pg_extension_config_dump is + an empty string, the entire contents of the table are dumped by + pg_dump. This is usually only correct if the table + is initially empty as created by the extension script. If there is + a mixture of initial data and user-provided data in the table, + the second argument of pg_extension_config_dump provides + a WHERE condition that selects the data to be dumped. + For example, you might do + +CREATE TABLE my_config (key text, value text, standard_entry boolean); + +SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry'); + + and then make sure that standard_entry is true only + in the rows created by the extension's script. + + + + For sequences, the second argument of pg_extension_config_dump + has no effect. + + + + More complicated situations, such as initially-provided rows that might + be modified by users, can be handled by creating triggers on the + configuration table to ensure that modified rows are marked correctly. + + + + You can alter the filter condition associated with a configuration table + by calling pg_extension_config_dump again. (This would + typically be useful in an extension update script.) The only way to mark + a table as no longer a configuration table is to dissociate it from the + extension with ALTER EXTENSION ... DROP TABLE. + + + + Note that foreign key relationships between these tables will dictate the + order in which the tables are dumped out by pg_dump. Specifically, pg_dump + will attempt to dump the referenced-by table before the referencing table. + As the foreign key relationships are set up at CREATE EXTENSION time (prior + to data being loaded into the tables) circular dependencies are not + supported. When circular dependencies exist, the data will still be dumped + out but the dump will not be able to be restored directly and user + intervention will be required. + + + + Sequences associated with serial or bigserial columns + need to be directly marked to dump their state. Marking their parent + relation is not enough for this purpose. + + + + + Extension Updates + + + One advantage of the extension mechanism is that it provides convenient + ways to manage updates to the SQL commands that define an extension's + objects. This is done by associating a version name or number with + each released version of the extension's installation script. + In addition, if you want users to be able to update their databases + dynamically from one version to the next, you should provide + update scripts that make the necessary changes to go from + one version to the next. Update scripts have names following the pattern + extension--old_version--target_version.sql + (for example, foo--1.0--1.1.sql contains the commands to modify + version 1.0 of extension foo into version + 1.1). + + + + Given that a suitable update script is available, the command + ALTER EXTENSION UPDATE will update an installed extension + to the specified new version. The update script is run in the same + environment that CREATE EXTENSION provides for installation + scripts: in particular, search_path is set up in the same + way, and any new objects created by the script are automatically added + to the extension. Also, if the script chooses to drop extension member + objects, they are automatically dissociated from the extension. + + + + If an extension has secondary control files, the control parameters + that are used for an update script are those associated with the script's + target (new) version. + + + + ALTER EXTENSION is able to execute sequences of update + script files to achieve a requested update. For example, if only + foo--1.0--1.1.sql and foo--1.1--2.0.sql are + available, ALTER EXTENSION will apply them in sequence if an + update to version 2.0 is requested when 1.0 is + currently installed. + + + + PostgreSQL doesn't assume anything about the properties + of version names: for example, it does not know whether 1.1 + follows 1.0. It just matches up the available version names + and follows the path that requires applying the fewest update scripts. + (A version name can actually be any string that doesn't contain + -- or leading or trailing -.) + + + + Sometimes it is useful to provide downgrade scripts, for + example foo--1.1--1.0.sql to allow reverting the changes + associated with version 1.1. If you do that, be careful + of the possibility that a downgrade script might unexpectedly + get applied because it yields a shorter path. The risky case is where + there is a fast path update script that jumps ahead several + versions as well as a downgrade script to the fast path's start point. + It might take fewer steps to apply the downgrade and then the fast + path than to move ahead one version at a time. If the downgrade script + drops any irreplaceable objects, this will yield undesirable results. + + + + To check for unexpected update paths, use this command: + +SELECT * FROM pg_extension_update_paths('extension_name'); + + This shows each pair of distinct known version names for the specified + extension, together with the update path sequence that would be taken to + get from the source version to the target version, or NULL if + there is no available update path. The path is shown in textual form + with -- separators. You can use + regexp_split_to_array(path,'--') if you prefer an array + format. + + + + + Installing Extensions Using Update Scripts + + + An extension that has been around for awhile will probably exist in + several versions, for which the author will need to write update scripts. + For example, if you have released a foo extension in + versions 1.0, 1.1, and 1.2, there + should be update scripts foo--1.0--1.1.sql + and foo--1.1--1.2.sql. + Before PostgreSQL 10, it was necessary to also create + new script files foo--1.1.sql and foo--1.2.sql + that directly build the newer extension versions, or else the newer + versions could not be installed directly, only by + installing 1.0 and then updating. That was tedious and + duplicative, but now it's unnecessary, because CREATE + EXTENSION can follow update chains automatically. + For example, if only the script + files foo--1.0.sql, foo--1.0--1.1.sql, + and foo--1.1--1.2.sql are available then a request to + install version 1.2 is honored by running those three + scripts in sequence. The processing is the same as if you'd first + installed 1.0 and then updated to 1.2. + (As with ALTER EXTENSION UPDATE, if multiple pathways are + available then the shortest is preferred.) Arranging an extension's + script files in this style can reduce the amount of maintenance effort + needed to produce small updates. + + + + If you use secondary (version-specific) control files with an extension + maintained in this style, keep in mind that each version needs a control + file even if it has no stand-alone installation script, as that control + file will determine how the implicit update to that version is performed. + For example, if foo--1.0.control specifies requires + = 'bar' but foo's other control files do not, the + extension's dependency on bar will be dropped when updating + from 1.0 to another version. + + + + + Security Considerations for Extensions + + + Widely-distributed extensions should assume little about the database + they occupy. Therefore, it's appropriate to write functions provided + by an extension in a secure style that cannot be compromised by + search-path-based attacks. + + + + An extension that has the superuser property set to + true must also consider security hazards for the actions taken within + its installation and update scripts. It is not terribly difficult for + a malicious user to create trojan-horse objects that will compromise + later execution of a carelessly-written extension script, allowing that + user to acquire superuser privileges. + + + + If an extension is marked trusted, then its + installation schema can be selected by the installing user, who might + intentionally use an insecure schema in hopes of gaining superuser + privileges. Therefore, a trusted extension is extremely exposed from a + security standpoint, and all its script commands must be carefully + examined to ensure that no compromise is possible. + + + + Advice about writing functions securely is provided in + below, and advice + about writing installation scripts securely is provided in + . + + + + Security Considerations for Extension Functions + + + SQL-language and PL-language functions provided by extensions are at + risk of search-path-based attacks when they are executed, since + parsing of these functions occurs at execution time not creation time. + + + + The CREATE + FUNCTION reference page contains advice about + writing SECURITY DEFINER functions safely. It's + good practice to apply those techniques for any function provided by + an extension, since the function might be called by a high-privilege + user. + + + + + If you cannot set the search_path to contain only + secure schemas, assume that each unqualified name could resolve to an + object that a malicious user has defined. Beware of constructs that + depend on search_path implicitly; for + example, IN + and CASE expression WHEN + always select an operator using the search path. In their place, use + OPERATOR(schema.=) ANY + and CASE WHEN expression. + + + + A general-purpose extension usually should not assume that it's been + installed into a secure schema, which means that even schema-qualified + references to its own objects are not entirely risk-free. For + example, if the extension has defined a + function myschema.myfunc(bigint) then a call such + as myschema.myfunc(42) could be captured by a + hostile function myschema.myfunc(integer). Be + careful that the data types of function and operator parameters exactly + match the declared argument types, using explicit casts where necessary. + + + + + Security Considerations for Extension Scripts + + + An extension installation or update script should be written to guard + against search-path-based attacks occurring when the script executes. + If an object reference in the script can be made to resolve to some + other object than the script author intended, then a compromise might + occur immediately, or later when the mis-defined extension object is + used. + + + + DDL commands such as CREATE FUNCTION + and CREATE OPERATOR CLASS are generally secure, + but beware of any command having a general-purpose expression as a + component. For example, CREATE VIEW needs to be + vetted, as does a DEFAULT expression + in CREATE FUNCTION. + + + + Sometimes an extension script might need to execute general-purpose + SQL, for example to make catalog adjustments that aren't possible via + DDL. Be careful to execute such commands with a + secure search_path; do not + trust the path provided by CREATE/ALTER EXTENSION + to be secure. Best practice is to temporarily + set search_path to 'pg_catalog, + pg_temp' and insert references to the extension's + installation schema explicitly where needed. (This practice might + also be helpful for creating views.) Examples can be found in + the contrib modules in + the PostgreSQL source code distribution. + + + + Cross-extension references are extremely difficult to make fully + secure, partially because of uncertainty about which schema the other + extension is in. The hazards are reduced if both extensions are + installed in the same schema, because then a hostile object cannot be + placed ahead of the referenced extension in the installation-time + search_path. However, no mechanism currently exists + to require that. For now, best practice is to not mark an extension + trusted if it depends on another one, unless that other one is always + installed in pg_catalog. + + + + Do not use CREATE OR REPLACE + FUNCTION, except in an update script that must change the + definition of a function that is known to be an extension member + already. (Likewise for other OR REPLACE options.) + Using OR REPLACE unnecessarily not only has a risk + of accidentally overwriting someone else's function, but it creates a + security hazard since the overwritten function would still be owned by + its original owner, who could modify it. + + + + + + Extension Example + + + Here is a complete example of an SQL-only + extension, a two-element composite type that can store any type of value + in its slots, which are named k and v. Non-text + values are automatically coerced to text for storage. + + + + The script file pair--1.0.sql looks like this: + + (LEFTARG = text, RIGHTARG = text, FUNCTION = pair); + +-- "SET search_path" is easy to get right, but qualified names perform better. +CREATE FUNCTION lower(pair) +RETURNS pair LANGUAGE SQL +AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;' +SET search_path = pg_temp; + +CREATE FUNCTION pair_concat(pair, pair) +RETURNS pair LANGUAGE SQL +AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k, + $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;'; +]]> + + + + + The control file pair.control looks like this: + + +# pair extension +comment = 'A key/value pair data type' +default_version = '1.0' +# cannot be relocatable because of use of @extschema@ +relocatable = false + + + + + While you hardly need a makefile to install these two files into the + correct directory, you could use a Makefile containing this: + + +EXTENSION = pair +DATA = pair--1.0.sql + +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) + + + This makefile relies on PGXS, which is described + in . The command make install + will install the control and script files into the correct + directory as reported by pg_config. + + + + Once the files are installed, use the + CREATE EXTENSION command to load the objects into + any particular database. + + + + + + Extension Building Infrastructure + + + pgxs + + + + If you are thinking about distributing your + PostgreSQL extension modules, setting up a + portable build system for them can be fairly difficult. Therefore + the PostgreSQL installation provides a build + infrastructure for extensions, called PGXS, so + that simple extension modules can be built simply against an + already installed server. PGXS is mainly intended + for extensions that include C code, although it can be used for + pure-SQL extensions too. Note that PGXS is not + intended to be a universal build system framework that can be used + to build any software interfacing to PostgreSQL; + it simply automates common build rules for simple server extension + modules. For more complicated packages, you might need to write your + own build system. + + + + To use the PGXS infrastructure for your extension, + you must write a simple makefile. + In the makefile, you need to set some variables + and include the global PGXS makefile. + Here is an example that builds an extension module named + isbn_issn, consisting of a shared library containing + some C code, an extension control file, an SQL script, an include file + (only needed if other modules might need to access the extension functions + without going via SQL), and a documentation text file: + +MODULES = isbn_issn +EXTENSION = isbn_issn +DATA = isbn_issn--1.0.sql +DOCS = README.isbn_issn +HEADERS_isbn_issn = isbn_issn.h + +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) + + The last three lines should always be the same. Earlier in the + file, you assign variables or add custom + make rules. + + + + Set one of these three variables to specify what is built: + + + + MODULES + + + list of shared-library objects to be built from source files with same + stem (do not include library suffixes in this list) + + + + + + MODULE_big + + + a shared library to build from multiple source files + (list object files in OBJS) + + + + + + PROGRAM + + + an executable program to build + (list object files in OBJS) + + + + + + The following variables can also be set: + + + + EXTENSION + + + extension name(s); for each name you must provide an + extension.control file, + which will be installed into + prefix/share/extension + + + + + + MODULEDIR + + + subdirectory of prefix/share + into which DATA and DOCS files should be installed + (if not set, default is extension if + EXTENSION is set, + or contrib if not) + + + + + + DATA + + + random files to install into prefix/share/$MODULEDIR + + + + + + DATA_built + + + random files to install into + prefix/share/$MODULEDIR, + which need to be built first + + + + + + DATA_TSEARCH + + + random files to install under + prefix/share/tsearch_data + + + + + + DOCS + + + random files to install under + prefix/doc/$MODULEDIR + + + + + + HEADERS + HEADERS_built + + + Files to (optionally build and) install under + prefix/include/server/$MODULEDIR/$MODULE_big. + + + Unlike DATA_built, files in HEADERS_built + are not removed by the clean target; if you want them removed, + also add them to EXTRA_CLEAN or add your own rules to do it. + + + + + + HEADERS_$MODULE + HEADERS_built_$MODULE + + + Files to install (after building if specified) under + prefix/include/server/$MODULEDIR/$MODULE, + where $MODULE must be a module name used + in MODULES or MODULE_big. + + + Unlike DATA_built, files in HEADERS_built_$MODULE + are not removed by the clean target; if you want them removed, + also add them to EXTRA_CLEAN or add your own rules to do it. + + + It is legal to use both variables for the same module, or any + combination, unless you have two module names in the + MODULES list that differ only by the presence of a + prefix built_, which would cause ambiguity. In + that (hopefully unlikely) case, you should use only the + HEADERS_built_$MODULE variables. + + + + + + SCRIPTS + + + script files (not binaries) to install into + prefix/bin + + + + + + SCRIPTS_built + + + script files (not binaries) to install into + prefix/bin, + which need to be built first + + + + + + REGRESS + + + list of regression test cases (without suffix), see below + + + + + + REGRESS_OPTS + + + additional switches to pass to pg_regress + + + + + + ISOLATION + + + list of isolation test cases, see below for more details + + + + + + ISOLATION_OPTS + + + additional switches to pass to + pg_isolation_regress + + + + + + TAP_TESTS + + + switch defining if TAP tests need to be run, see below + + + + + + NO_INSTALL + + + don't define an install target, useful for test + modules that don't need their build products to be installed + + + + + + NO_INSTALLCHECK + + + don't define an installcheck target, useful e.g., if tests require special configuration, or don't use pg_regress + + + + + + EXTRA_CLEAN + + + extra files to remove in make clean + + + + + + PG_CPPFLAGS + + + will be prepended to CPPFLAGS + + + + + + PG_CFLAGS + + + will be appended to CFLAGS + + + + + + PG_CXXFLAGS + + + will be appended to CXXFLAGS + + + + + + PG_LDFLAGS + + + will be prepended to LDFLAGS + + + + + + PG_LIBS + + + will be added to PROGRAM link line + + + + + + SHLIB_LINK + + + will be added to MODULE_big link line + + + + + + PG_CONFIG + + + path to pg_config program for the + PostgreSQL installation to build against + (typically just pg_config to use the first one in your + PATH) + + + + + + + + Put this makefile as Makefile in the directory + which holds your extension. Then you can do + make to compile, and then make + install to install your module. By default, the extension is + compiled and installed for the + PostgreSQL installation that + corresponds to the first pg_config program + found in your PATH. You can use a different installation by + setting PG_CONFIG to point to its + pg_config program, either within the makefile + or on the make command line. + + + + You can also run make in a directory outside the source + tree of your extension, if you want to keep the build directory separate. + This procedure is also called a + VPATHVPATH + build. Here's how: + +mkdir build_dir +cd build_dir +make -f /path/to/extension/source/tree/Makefile +make -f /path/to/extension/source/tree/Makefile install + + + + + Alternatively, you can set up a directory for a VPATH build in a similar + way to how it is done for the core code. One way to do this is using the + core script config/prep_buildtree. Once this has been done + you can build by setting the make variable + VPATH like this: + +make VPATH=/path/to/extension/source/tree +make VPATH=/path/to/extension/source/tree install + + This procedure can work with a greater variety of directory layouts. + + + + The scripts listed in the REGRESS variable are used for + regression testing of your module, which can be invoked by make + installcheck after doing make install. For this to + work you must have a running PostgreSQL server. + The script files listed in REGRESS must appear in a + subdirectory named sql/ in your extension's directory. + These files must have extension .sql, which must not be + included in the REGRESS list in the makefile. For each + test there should also be a file containing the expected output in a + subdirectory named expected/, with the same stem and + extension .out. make installcheck + executes each test script with psql, and compares the + resulting output to the matching expected file. Any differences will be + written to the file regression.diffs in diff + -c format. Note that trying to run a test that is missing its + expected file will be reported as trouble, so make sure you + have all expected files. + + + + The scripts listed in the ISOLATION variable are used + for tests stressing behavior of concurrent session with your module, which + can be invoked by make installcheck after doing + make install. For this to work you must have a + running PostgreSQL server. The script files + listed in ISOLATION must appear in a subdirectory + named specs/ in your extension's directory. These files + must have extension .spec, which must not be included + in the ISOLATION list in the makefile. For each test + there should also be a file containing the expected output in a + subdirectory named expected/, with the same stem and + extension .out. make installcheck + executes each test script, and compares the resulting output to the + matching expected file. Any differences will be written to the file + output_iso/regression.diffs in + diff -c format. Note that trying to run a test that is + missing its expected file will be reported as trouble, so + make sure you have all expected files. + + + + TAP_TESTS enables the use of TAP tests. Data from each + run is present in a subdirectory named tmp_check/. + See also for more details. + + + + + The easiest way to create the expected files is to create empty files, + then do a test run (which will of course report differences). Inspect + the actual result files found in the results/ + directory (for tests in REGRESS), or + output_iso/results/ directory (for tests in + ISOLATION), then copy them to + expected/ if they match what you expect from the test. + + + + + +
diff --git a/doc/src/sgml/external-projects.sgml b/doc/src/sgml/external-projects.sgml new file mode 100644 index 000000000000..bf590aba5d9d --- /dev/null +++ b/doc/src/sgml/external-projects.sgml @@ -0,0 +1,251 @@ + + + + External Projects + + + PostgreSQL is a complex software project, + and managing the project is difficult. We have found that many + enhancements to PostgreSQL can be more + efficiently developed separately from the core project. + + + + Client Interfaces + + + interfaces + externally maintained + + + + There are only two client interfaces included in the base + PostgreSQL distribution: + + + + libpq is included because it is the + primary C language interface, and because many other client interfaces + are built on top of it. + + + + + + ECPG is included because it depends on the + server-side SQL grammar, and is therefore sensitive to changes in + PostgreSQL itself. + + + + + All other language interfaces are external projects and are distributed + separately. includes a list of + some of these projects. Note that some of these packages might not be + released under the same license as PostgreSQL. For more + information on each language interface, including licensing terms, refer to + its website and documentation. + + + + Externally Maintained Client Interfaces + + + + + Name + Language + Comments + Website + + + + + + DBD::Pg + Perl + Perl DBI driver + + + + + JDBC + Java + Type 4 JDBC driver + + + + + libpqxx + C++ + C++ interface + + + + + node-postgres + JavaScript + Node.js driver + + + + + Npgsql + .NET + .NET data provider + + + + + pgtcl + Tcl + + + + + + pgtclng + Tcl + + + + + + pq + Go + Pure Go driver for Go's database/sql + + + + + psqlODBC + ODBC + ODBC driver + + + + + psycopg + Python + DB API 2.0-compliant + + + + +
+
+ + + Administration Tools + + + administration tools + externally maintained + + + + There are several administration tools available for + PostgreSQL. The most popular is + pgAdmin, + and there are several commercially available ones as well. + + + + + Procedural Languages + + + procedural language + externally maintained + + + + PostgreSQL includes several procedural + languages with the base distribution: PL/pgSQL, PL/Tcl, + PL/Perl, and PL/Python. + + + + In addition, there are a number of procedural languages that are developed + and maintained outside the core PostgreSQL + distribution. lists some of these + packages. Note that some of these projects might not be released under the same + license as PostgreSQL. For more information on each + procedural language, including licensing information, refer to its website + and documentation. + + + + Externally Maintained Procedural Languages + + + + + Name + Language + Website + + + + + + PL/Java + Java + + + + + PL/Lua + Lua + + + + + PL/R + R + + + + + PL/sh + Unix shell + + + + + PL/v8 + JavaScript + + + + +
+
+ + + Extensions + + + extension + externally maintained + + + + PostgreSQL is designed to be easily extensible. For + this reason, extensions loaded into the database can function + just like features that are built in. The + contrib/ directory shipped with the source code + contains several extensions, which are described in + . Other extensions are developed + independently, like PostGIS. Even + PostgreSQL replication solutions can be developed + externally. For example, Slony-I is a popular + primary/standby replication solution that is developed independently + from the core project. + + +
diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml new file mode 100644 index 000000000000..d1194def8200 --- /dev/null +++ b/doc/src/sgml/fdwhandler.sgml @@ -0,0 +1,2139 @@ + + + + Writing a Foreign Data Wrapper + + + foreign data wrapper + handler for + + + + All operations on a foreign table are handled through its foreign data + wrapper, which consists of a set of functions that the core server + calls. The foreign data wrapper is responsible for fetching + data from the remote data source and returning it to the + PostgreSQL executor. If updating foreign + tables is to be supported, the wrapper must handle that, too. + This chapter outlines how to write a new foreign data wrapper. + + + + The foreign data wrappers included in the standard distribution are good + references when trying to write your own. Look into the + contrib subdirectory of the source tree. + The reference page also has + some useful details. + + + + + The SQL standard specifies an interface for writing foreign data wrappers. + However, PostgreSQL does not implement that API, because the effort to + accommodate it into PostgreSQL would be large, and the standard API hasn't + gained wide adoption anyway. + + + + + Foreign Data Wrapper Functions + + + The FDW author needs to implement a handler function, and optionally + a validator function. Both functions must be written in a compiled + language such as C, using the version-1 interface. + For details on C language calling conventions and dynamic loading, + see . + + + + The handler function simply returns a struct of function pointers to + callback functions that will be called by the planner, executor, and + various maintenance commands. + Most of the effort in writing an FDW is in implementing these callback + functions. + The handler function must be registered with + PostgreSQL as taking no arguments and + returning the special pseudo-type fdw_handler. The + callback functions are plain C functions and are not visible or + callable at the SQL level. The callback functions are described in + . + + + + The validator function is responsible for validating options given in + CREATE and ALTER commands for its + foreign data wrapper, as well as foreign servers, user mappings, and + foreign tables using the wrapper. + The validator function must be registered as taking two arguments, a + text array containing the options to be validated, and an OID + representing the type of object the options are associated with (in + the form of the OID of the system catalog the object would be stored + in, either + ForeignDataWrapperRelationId, + ForeignServerRelationId, + UserMappingRelationId, + or ForeignTableRelationId). + If no validator function is supplied, options are not checked at object + creation time or object alteration time. + + + + + + Foreign Data Wrapper Callback Routines + + + The FDW handler function returns a palloc'd FdwRoutine + struct containing pointers to the callback functions described below. + The scan-related functions are required, the rest are optional. + + + + The FdwRoutine struct type is declared in + src/include/foreign/fdwapi.h, which see for additional + details. + + + + FDW Routines for Scanning Foreign Tables + + + +void +GetForeignRelSize(PlannerInfo *root, + RelOptInfo *baserel, + Oid foreigntableid); + + + Obtain relation size estimates for a foreign table. This is called + at the beginning of planning for a query that scans a foreign table. + root is the planner's global information about the query; + baserel is the planner's information about this table; and + foreigntableid is the pg_class OID of the + foreign table. (foreigntableid could be obtained from the + planner data structures, but it's passed explicitly to save effort.) + + + + This function should update baserel->rows to be the + expected number of rows returned by the table scan, after accounting for + the filtering done by the restriction quals. The initial value of + baserel->rows is just a constant default estimate, which + should be replaced if at all possible. The function may also choose to + update baserel->width if it can compute a better estimate + of the average result row width. + (The initial value is based on column data types and on column + average-width values measured by the last ANALYZE.) + Also, this function may update baserel->tuples if + it can compute a better estimate of the foreign table's total row count. + (The initial value is + from pg_class.reltuples + which represents the total row count seen by the + last ANALYZE; it will be -1 if + no ANALYZE has been done on this foreign table.) + + + + See for additional information. + + + + +void +GetForeignPaths(PlannerInfo *root, + RelOptInfo *baserel, + Oid foreigntableid); + + + Create possible access paths for a scan on a foreign table. + This is called during query planning. + The parameters are the same as for GetForeignRelSize, + which has already been called. + + + + This function must generate at least one access path + (ForeignPath node) for a scan on the foreign table and + must call add_path to add each such path to + baserel->pathlist. It's recommended to use + create_foreignscan_path to build the + ForeignPath nodes. The function can generate multiple + access paths, e.g., a path which has valid pathkeys to + represent a pre-sorted result. Each access path must contain cost + estimates, and can contain any FDW-private information that is needed to + identify the specific scan method intended. + + + + See for additional information. + + + + +ForeignScan * +GetForeignPlan(PlannerInfo *root, + RelOptInfo *baserel, + Oid foreigntableid, + ForeignPath *best_path, + List *tlist, + List *scan_clauses, + Plan *outer_plan); + + + Create a ForeignScan plan node from the selected foreign + access path. This is called at the end of query planning. + The parameters are as for GetForeignRelSize, plus + the selected ForeignPath (previously produced by + GetForeignPaths, GetForeignJoinPaths, + or GetForeignUpperPaths), + the target list to be emitted by the plan node, + the restriction clauses to be enforced by the plan node, + and the outer subplan of the ForeignScan, + which is used for rechecks performed by RecheckForeignScan. + (If the path is for a join rather than a base + relation, foreigntableid is InvalidOid.) + + + + This function must create and return a ForeignScan plan + node; it's recommended to use make_foreignscan to build the + ForeignScan node. + + + + See for additional information. + + + + +void +BeginForeignScan(ForeignScanState *node, + int eflags); + + + Begin executing a foreign scan. This is called during executor startup. + It should perform any initialization needed before the scan can start, + but not start executing the actual scan (that should be done upon the + first call to IterateForeignScan). + The ForeignScanState node has already been created, but + its fdw_state field is still NULL. Information about + the table to scan is accessible through the + ForeignScanState node (in particular, from the underlying + ForeignScan plan node, which contains any FDW-private + information provided by GetForeignPlan). + eflags contains flag bits describing the executor's + operating mode for this plan node. + + + + Note that when (eflags & EXEC_FLAG_EXPLAIN_ONLY) is + true, this function should not perform any externally-visible actions; + it should only do the minimum required to make the node state valid + for ExplainForeignScan and EndForeignScan. + + + + +TupleTableSlot * +IterateForeignScan(ForeignScanState *node); + + + Fetch one row from the foreign source, returning it in a tuple table slot + (the node's ScanTupleSlot should be used for this + purpose). Return NULL if no more rows are available. The tuple table + slot infrastructure allows either a physical or virtual tuple to be + returned; in most cases the latter choice is preferable from a + performance standpoint. Note that this is called in a short-lived memory + context that will be reset between invocations. Create a memory context + in BeginForeignScan if you need longer-lived storage, or use + the es_query_cxt of the node's EState. + + + + The rows returned must match the fdw_scan_tlist target + list if one was supplied, otherwise they must match the row type of the + foreign table being scanned. If you choose to optimize away fetching + columns that are not needed, you should insert nulls in those column + positions, or else generate a fdw_scan_tlist list with + those columns omitted. + + + + Note that PostgreSQL's executor doesn't care + whether the rows returned violate any constraints that were defined on + the foreign table — but the planner does care, and may optimize + queries incorrectly if there are rows visible in the foreign table that + do not satisfy a declared constraint. If a constraint is violated when + the user has declared that the constraint should hold true, it may be + appropriate to raise an error (just as you would need to do in the case + of a data type mismatch). + + + + +void +ReScanForeignScan(ForeignScanState *node); + + + Restart the scan from the beginning. Note that any parameters the + scan depends on may have changed value, so the new scan does not + necessarily return exactly the same rows. + + + + +void +EndForeignScan(ForeignScanState *node); + + + End the scan and release resources. It is normally not important + to release palloc'd memory, but for example open files and connections + to remote servers should be cleaned up. + + + + + + FDW Routines for Scanning Foreign Joins + + + If an FDW supports performing foreign joins remotely (rather than + by fetching both tables' data and doing the join locally), it should + provide this callback function: + + + + +void +GetForeignJoinPaths(PlannerInfo *root, + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + JoinPathExtraData *extra); + + Create possible access paths for a join of two (or more) foreign tables + that all belong to the same foreign server. This optional + function is called during query planning. As + with GetForeignPaths, this function should + generate ForeignPath path(s) for the + supplied joinrel + (use create_foreign_join_path to build them), + and call add_path to add these + paths to the set of paths considered for the join. But unlike + GetForeignPaths, it is not necessary that this function + succeed in creating at least one path, since paths involving local + joining are always possible. + + + + Note that this function will be invoked repeatedly for the same join + relation, with different combinations of inner and outer relations; it is + the responsibility of the FDW to minimize duplicated work. + + + + If a ForeignPath path is chosen for the join, it will + represent the entire join process; paths generated for the component + tables and subsidiary joins will not be used. Subsequent processing of + the join path proceeds much as it does for a path scanning a single + foreign table. One difference is that the scanrelid of + the resulting ForeignScan plan node should be set to zero, + since there is no single relation that it represents; instead, + the fs_relids field of the ForeignScan + node represents the set of relations that were joined. (The latter field + is set up automatically by the core planner code, and need not be filled + by the FDW.) Another difference is that, because the column list for a + remote join cannot be found from the system catalogs, the FDW must + fill fdw_scan_tlist with an appropriate list + of TargetEntry nodes, representing the set of columns + it will supply at run time in the tuples it returns. + + + + See for additional information. + + + + + FDW Routines for Planning Post-Scan/Join Processing + + + If an FDW supports performing remote post-scan/join processing, such as + remote aggregation, it should provide this callback function: + + + + +void +GetForeignUpperPaths(PlannerInfo *root, + UpperRelationKind stage, + RelOptInfo *input_rel, + RelOptInfo *output_rel, + void *extra); + + Create possible access paths for upper relation processing, + which is the planner's term for all post-scan/join query processing, such + as aggregation, window functions, sorting, and table updates. This + optional function is called during query planning. Currently, it is + called only if all base relation(s) involved in the query belong to the + same FDW. This function should generate ForeignPath + path(s) for any post-scan/join processing that the FDW knows how to + perform remotely + (use create_foreign_upper_path to build them), + and call add_path to add these paths to + the indicated upper relation. As with GetForeignJoinPaths, + it is not necessary that this function succeed in creating any paths, + since paths involving local processing are always possible. + + + + The stage parameter identifies which post-scan/join step is + currently being considered. output_rel is the upper relation + that should receive paths representing computation of this step, + and input_rel is the relation representing the input to this + step. The extra parameter provides additional details, + currently, it is set only for UPPERREL_PARTIAL_GROUP_AGG + or UPPERREL_GROUP_AGG, in which case it points to a + GroupPathExtraData structure; + or for UPPERREL_FINAL, in which case it points to a + FinalPathExtraData structure. + (Note that ForeignPath paths added + to output_rel would typically not have any direct dependency + on paths of the input_rel, since their processing is expected + to be done externally. However, examining paths previously generated for + the previous processing step can be useful to avoid redundant planning + work.) + + + + See for additional information. + + + + + FDW Routines for Updating Foreign Tables + + + If an FDW supports writable foreign tables, it should provide + some or all of the following callback functions depending on + the needs and capabilities of the FDW: + + + + +void +AddForeignUpdateTargets(PlannerInfo *root, + Index rtindex, + RangeTblEntry *target_rte, + Relation target_relation); + + + UPDATE and DELETE operations are performed + against rows previously fetched by the table-scanning functions. The + FDW may need extra information, such as a row ID or the values of + primary-key columns, to ensure that it can identify the exact row to + update or delete. To support that, this function can add extra hidden, + or junk, target columns to the list of columns that are to be + retrieved from the foreign table during an UPDATE or + DELETE. + + + + To do that, construct a Var representing + an extra value you need, and pass it + to add_row_identity_var, along with a name for + the junk column. (You can do this more than once if several columns + are needed.) You must choose a distinct junk column name for each + different Var you need, except + that Vars that are identical except for + the varno field can and should share a + column name. + The core system uses the junk column names + tableoid for a + table's tableoid column, + ctid + or ctidN + for ctid, + wholerow + for a whole-row Var marked with + vartype = RECORD, + and wholerowN + for a whole-row Var with + vartype equal to the table's declared rowtype. + Re-use these names when you can (the planner will combine duplicate + requests for identical junk columns). If you need another kind of + junk column besides these, it might be wise to choose a name prefixed + with your extension name, to avoid conflicts against other FDWs. + + + + If the AddForeignUpdateTargets pointer is set to + NULL, no extra target expressions are added. + (This will make it impossible to implement DELETE + operations, though UPDATE may still be feasible if the FDW + relies on an unchanging primary key to identify rows.) + + + + +List * +PlanForeignModify(PlannerInfo *root, + ModifyTable *plan, + Index resultRelation, + int subplan_index); + + + Perform any additional planning actions needed for an insert, update, or + delete on a foreign table. This function generates the FDW-private + information that will be attached to the ModifyTable plan + node that performs the update action. This private information must + have the form of a List, and will be delivered to + BeginForeignModify during the execution stage. + + + + root is the planner's global information about the query. + plan is the ModifyTable plan node, which is + complete except for the fdwPrivLists field. + resultRelation identifies the target foreign table by its + range table index. subplan_index identifies which target of + the ModifyTable plan node this is, counting from zero; + use this if you want to index into per-target-relation substructures of the + plan node. + + + + See for additional information. + + + + If the PlanForeignModify pointer is set to + NULL, no additional plan-time actions are taken, and the + fdw_private list delivered to + BeginForeignModify will be NIL. + + + + +void +BeginForeignModify(ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + int eflags); + + + Begin executing a foreign table modification operation. This routine is + called during executor startup. It should perform any initialization + needed prior to the actual table modifications. Subsequently, + ExecForeignInsert/ExecForeignBatchInsert, + ExecForeignUpdate or + ExecForeignDelete will be called for tuple(s) to be + inserted, updated, or deleted. + + + + mtstate is the overall state of the + ModifyTable plan node being executed; global data about + the plan and execution state is available via this structure. + rinfo is the ResultRelInfo struct describing + the target foreign table. (The ri_FdwState field of + ResultRelInfo is available for the FDW to store any + private state it needs for this operation.) + fdw_private contains the private data generated by + PlanForeignModify, if any. + subplan_index identifies which target of + the ModifyTable plan node this is. + eflags contains flag bits describing the executor's + operating mode for this plan node. + + + + Note that when (eflags & EXEC_FLAG_EXPLAIN_ONLY) is + true, this function should not perform any externally-visible actions; + it should only do the minimum required to make the node state valid + for ExplainForeignModify and EndForeignModify. + + + + If the BeginForeignModify pointer is set to + NULL, no action is taken during executor startup. + + + + +TupleTableSlot * +ExecForeignInsert(EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + + + Insert one tuple into the foreign table. + estate is global execution state for the query. + rinfo is the ResultRelInfo struct describing + the target foreign table. + slot contains the tuple to be inserted; it will match the + row-type definition of the foreign table. + planSlot contains the tuple that was generated by the + ModifyTable plan node's subplan; it differs from + slot in possibly containing additional junk + columns. (The planSlot is typically of little interest + for INSERT cases, but is provided for completeness.) + + + + The return value is either a slot containing the data that was actually + inserted (this might differ from the data supplied, for example as a + result of trigger actions), or NULL if no row was actually inserted + (again, typically as a result of triggers). The passed-in + slot can be re-used for this purpose. + + + + The data in the returned slot is used only if the INSERT + statement has a RETURNING clause or involves a view + WITH CHECK OPTION; or if the foreign table has + an AFTER ROW trigger. Triggers require all columns, + but the FDW could choose to optimize away returning some or all columns + depending on the contents of the RETURNING clause or + WITH CHECK OPTION constraints. Regardless, some slot + must be returned to indicate success, or the query's reported row count + will be wrong. + + + + If the ExecForeignInsert pointer is set to + NULL, attempts to insert into the foreign table will fail + with an error message. + + + + Note that this function is also called when inserting routed tuples into + a foreign-table partition or executing COPY FROM on + a foreign table, in which case it is called in a different way than it + is in the INSERT case. See the callback functions + described below that allow the FDW to support that. + + + + +TupleTableSlot ** +ExecForeignBatchInsert(EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int *numSlots); + + + Insert multiple tuples in bulk into the foreign table. + The parameters are the same for ExecForeignInsert + except slots and planSlots contain + multiple tuples and *numSlots specifies the number of + tuples in those arrays. + + + + The return value is an array of slots containing the data that was + actually inserted (this might differ from the data supplied, for + example as a result of trigger actions.) + The passed-in slots can be re-used for this purpose. + The number of successfully inserted tuples is returned in + *numSlots. + + + + The data in the returned slot is used only if the INSERT + statement involves a view + WITH CHECK OPTION; or if the foreign table has + an AFTER ROW trigger. Triggers require all columns, + but the FDW could choose to optimize away returning some or all columns + depending on the contents of the + WITH CHECK OPTION constraints. + + + + If the ExecForeignBatchInsert or + GetForeignModifyBatchSize pointer is set to + NULL, attempts to insert into the foreign table will + use ExecForeignInsert. + This function is not used if the INSERT has the + RETURNING clause. + + + + Note that this function is also called when inserting routed tuples into + a foreign-table partition. See the callback functions + described below that allow the FDW to support that. + + + + +int +GetForeignModifyBatchSize(ResultRelInfo *rinfo); + + + Report the maximum number of tuples that a single + ExecForeignBatchInsert call can handle for + the specified foreign table. The executor passes at most + the given number of tuples to ExecForeignBatchInsert. + rinfo is the ResultRelInfo struct describing + the target foreign table. + The FDW is expected to provide a foreign server and/or foreign + table option for the user to set this value, or some hard-coded value. + + + + If the ExecForeignBatchInsert or + GetForeignModifyBatchSize pointer is set to + NULL, attempts to insert into the foreign table will + use ExecForeignInsert. + + + + +TupleTableSlot * +ExecForeignUpdate(EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + + + Update one tuple in the foreign table. + estate is global execution state for the query. + rinfo is the ResultRelInfo struct describing + the target foreign table. + slot contains the new data for the tuple; it will match the + row-type definition of the foreign table. + planSlot contains the tuple that was generated by the + ModifyTable plan node's subplan. Unlike + slot, this tuple contains only the new values for + columns changed by the query, so do not rely on attribute numbers of the + foreign table to index into planSlot. + Also, planSlot typically contains + additional junk columns. In particular, any junk columns + that were requested by AddForeignUpdateTargets will + be available from this slot. + + + + The return value is either a slot containing the row as it was actually + updated (this might differ from the data supplied, for example as a + result of trigger actions), or NULL if no row was actually updated + (again, typically as a result of triggers). The passed-in + slot can be re-used for this purpose. + + + + The data in the returned slot is used only if the UPDATE + statement has a RETURNING clause or involves a view + WITH CHECK OPTION; or if the foreign table has + an AFTER ROW trigger. Triggers require all columns, + but the FDW could choose to optimize away returning some or all columns + depending on the contents of the RETURNING clause or + WITH CHECK OPTION constraints. Regardless, some slot + must be returned to indicate success, or the query's reported row count + will be wrong. + + + + If the ExecForeignUpdate pointer is set to + NULL, attempts to update the foreign table will fail + with an error message. + + + + +TupleTableSlot * +ExecForeignDelete(EState *estate, + ResultRelInfo *rinfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); + + + Delete one tuple from the foreign table. + estate is global execution state for the query. + rinfo is the ResultRelInfo struct describing + the target foreign table. + slot contains nothing useful upon call, but can be used to + hold the returned tuple. + planSlot contains the tuple that was generated by the + ModifyTable plan node's subplan; in particular, it will + carry any junk columns that were requested by + AddForeignUpdateTargets. The junk column(s) must be used + to identify the tuple to be deleted. + + + + The return value is either a slot containing the row that was deleted, + or NULL if no row was deleted (typically as a result of triggers). The + passed-in slot can be used to hold the tuple to be returned. + + + + The data in the returned slot is used only if the DELETE + query has a RETURNING clause or the foreign table has + an AFTER ROW trigger. Triggers require all columns, but the + FDW could choose to optimize away returning some or all columns depending + on the contents of the RETURNING clause. Regardless, some + slot must be returned to indicate success, or the query's reported row + count will be wrong. + + + + If the ExecForeignDelete pointer is set to + NULL, attempts to delete from the foreign table will fail + with an error message. + + + + +void +EndForeignModify(EState *estate, + ResultRelInfo *rinfo); + + + End the table update and release resources. It is normally not important + to release palloc'd memory, but for example open files and connections + to remote servers should be cleaned up. + + + + If the EndForeignModify pointer is set to + NULL, no action is taken during executor shutdown. + + + + Tuples inserted into a partitioned table by INSERT or + COPY FROM are routed to partitions. If an FDW + supports routable foreign-table partitions, it should also provide the + following callback functions. These functions are also called when + COPY FROM is executed on a foreign table. + + + + +void +BeginForeignInsert(ModifyTableState *mtstate, + ResultRelInfo *rinfo); + + + Begin executing an insert operation on a foreign table. This routine is + called right before the first tuple is inserted into the foreign table + in both cases when it is the partition chosen for tuple routing and the + target specified in a COPY FROM command. It should + perform any initialization needed prior to the actual insertion. + Subsequently, ExecForeignInsert or + ExecForeignBatchInsert will be called for + tuple(s) to be inserted into the foreign table. + + + + mtstate is the overall state of the + ModifyTable plan node being executed; global data about + the plan and execution state is available via this structure. + rinfo is the ResultRelInfo struct describing + the target foreign table. (The ri_FdwState field of + ResultRelInfo is available for the FDW to store any + private state it needs for this operation.) + + + + When this is called by a COPY FROM command, the + plan-related global data in mtstate is not provided + and the planSlot parameter of + ExecForeignInsert subsequently called for each + inserted tuple is NULL, whether the foreign table is + the partition chosen for tuple routing or the target specified in the + command. + + + + If the BeginForeignInsert pointer is set to + NULL, no action is taken for the initialization. + + + + Note that if the FDW does not support routable foreign-table partitions + and/or executing COPY FROM on foreign tables, this + function or ExecForeignInsert/ExecForeignBatchInsert + subsequently called must throw error as needed. + + + + +void +EndForeignInsert(EState *estate, + ResultRelInfo *rinfo); + + + End the insert operation and release resources. It is normally not important + to release palloc'd memory, but for example open files and connections + to remote servers should be cleaned up. + + + + If the EndForeignInsert pointer is set to + NULL, no action is taken for the termination. + + + + +int +IsForeignRelUpdatable(Relation rel); + + + Report which update operations the specified foreign table supports. + The return value should be a bit mask of rule event numbers indicating + which operations are supported by the foreign table, using the + CmdType enumeration; that is, + (1 << CMD_UPDATE) = 4 for UPDATE, + (1 << CMD_INSERT) = 8 for INSERT, and + (1 << CMD_DELETE) = 16 for DELETE. + + + + If the IsForeignRelUpdatable pointer is set to + NULL, foreign tables are assumed to be insertable, updatable, + or deletable if the FDW provides ExecForeignInsert, + ExecForeignUpdate, or ExecForeignDelete + respectively. This function is only needed if the FDW supports some + tables that are updatable and some that are not. (Even then, it's + permissible to throw an error in the execution routine instead of + checking in this function. However, this function is used to determine + updatability for display in the information_schema views.) + + + + Some inserts, updates, and deletes to foreign tables can be optimized + by implementing an alternative set of interfaces. The ordinary + interfaces for inserts, updates, and deletes fetch rows from the remote + server and then modify those rows one at a time. In some cases, this + row-by-row approach is necessary, but it can be inefficient. If it is + possible for the foreign server to determine which rows should be + modified without actually retrieving them, and if there are no local + structures which would affect the operation (row-level local triggers, + stored generated columns, or WITH CHECK OPTION + constraints from parent views), then it is possible to arrange things + so that the entire operation is performed on the remote server. The + interfaces described below make this possible. + + + + +bool +PlanDirectModify(PlannerInfo *root, + ModifyTable *plan, + Index resultRelation, + int subplan_index); + + + Decide whether it is safe to execute a direct modification + on the remote server. If so, return true after performing + planning actions needed for that. Otherwise, return false. + This optional function is called during query planning. + If this function succeeds, BeginDirectModify, + IterateDirectModify and EndDirectModify will + be called at the execution stage, instead. Otherwise, the table + modification will be executed using the table-updating functions + described above. + The parameters are the same as for PlanForeignModify. + + + + To execute the direct modification on the remote server, this function + must rewrite the target subplan with a ForeignScan plan + node that executes the direct modification on the remote server. The + operation and resultRelation fields + of the ForeignScan must be set appropriately. + operation must be set to the CmdType + enumeration corresponding to the statement kind (that is, + CMD_UPDATE for UPDATE, + CMD_INSERT for INSERT, and + CMD_DELETE for DELETE), and the + resultRelation argument must be copied to the + resultRelation field. + + + + See for additional information. + + + + If the PlanDirectModify pointer is set to + NULL, no attempts to execute a direct modification on the + remote server are taken. + + + + +void +BeginDirectModify(ForeignScanState *node, + int eflags); + + + Prepare to execute a direct modification on the remote server. + This is called during executor startup. It should perform any + initialization needed prior to the direct modification (that should be + done upon the first call to IterateDirectModify). + The ForeignScanState node has already been created, but + its fdw_state field is still NULL. Information about + the table to modify is accessible through the + ForeignScanState node (in particular, from the underlying + ForeignScan plan node, which contains any FDW-private + information provided by PlanDirectModify). + eflags contains flag bits describing the executor's + operating mode for this plan node. + + + + Note that when (eflags & EXEC_FLAG_EXPLAIN_ONLY) is + true, this function should not perform any externally-visible actions; + it should only do the minimum required to make the node state valid + for ExplainDirectModify and EndDirectModify. + + + + If the BeginDirectModify pointer is set to + NULL, no attempts to execute a direct modification on the + remote server are taken. + + + + +TupleTableSlot * +IterateDirectModify(ForeignScanState *node); + + + When the INSERT, UPDATE or DELETE + query doesn't have a RETURNING clause, just return NULL + after a direct modification on the remote server. + When the query has the clause, fetch one result containing the data + needed for the RETURNING calculation, returning it in a + tuple table slot (the node's ScanTupleSlot should be + used for this purpose). The data that was actually inserted, updated + or deleted must be stored in + node->resultRelInfo->ri_projectReturning->pi_exprContext->ecxt_scantuple. + Return NULL if no more rows are available. + Note that this is called in a short-lived memory context that will be + reset between invocations. Create a memory context in + BeginDirectModify if you need longer-lived storage, or use + the es_query_cxt of the node's EState. + + + + The rows returned must match the fdw_scan_tlist target + list if one was supplied, otherwise they must match the row type of the + foreign table being updated. If you choose to optimize away fetching + columns that are not needed for the RETURNING calculation, + you should insert nulls in those column positions, or else generate a + fdw_scan_tlist list with those columns omitted. + + + + Whether the query has the clause or not, the query's reported row count + must be incremented by the FDW itself. When the query doesn't have the + clause, the FDW must also increment the row count for the + ForeignScanState node in the EXPLAIN ANALYZE + case. + + + + If the IterateDirectModify pointer is set to + NULL, no attempts to execute a direct modification on the + remote server are taken. + + + + +void +EndDirectModify(ForeignScanState *node); + + + Clean up following a direct modification on the remote server. It is + normally not important to release palloc'd memory, but for example open + files and connections to the remote server should be cleaned up. + + + + If the EndDirectModify pointer is set to + NULL, no attempts to execute a direct modification on the + remote server are taken. + + + + + + FDW Routines for <command>TRUNCATE</command> + + + +void +ExecForeignTruncate(List *rels, + DropBehavior behavior, + bool restart_seqs); + + + Truncate foreign tables. This function is called when + is executed on a foreign table. + rels is a list of Relation + data structures of foreign tables to truncate. + + + + behavior is either DROP_RESTRICT + or DROP_CASCADE indicating that the + RESTRICT or CASCADE option was + requested in the original TRUNCATE command, + respectively. + + + + If restart_seqs is true, + the original TRUNCATE command requested the + RESTART IDENTITY behavior, otherwise the + CONTINUE IDENTITY behavior was requested. + + + + Note that the ONLY options specified + in the original TRUNCATE command are not passed to + ExecForeignTruncate. This behavior is similar to + the callback functions of SELECT, + UPDATE and DELETE on + a foreign table. + + + + ExecForeignTruncate is invoked once per + foreign server for which foreign tables are to be truncated. + This means that all foreign tables included in rels + must belong to the same server. + + + + If the ExecForeignTruncate pointer is set to + NULL, attempts to truncate foreign tables will + fail with an error message. + + + + + FDW Routines for Row Locking + + + If an FDW wishes to support late row locking (as described + in ), it must provide the following + callback functions: + + + + +RowMarkType +GetForeignRowMarkType(RangeTblEntry *rte, + LockClauseStrength strength); + + + Report which row-marking option to use for a foreign table. + rte is the RangeTblEntry node for the table + and strength describes the lock strength requested by the + relevant FOR UPDATE/SHARE clause, if any. The result must be + a member of the RowMarkType enum type. + + + + This function is called during query planning for each foreign table that + appears in an UPDATE, DELETE, or SELECT + FOR UPDATE/SHARE query and is not the target of UPDATE + or DELETE. + + + + If the GetForeignRowMarkType pointer is set to + NULL, the ROW_MARK_COPY option is always used. + (This implies that RefetchForeignRow will never be called, + so it need not be provided either.) + + + + See for more information. + + + + +void +RefetchForeignRow(EState *estate, + ExecRowMark *erm, + Datum rowid, + TupleTableSlot *slot, + bool *updated); + + + Re-fetch one tuple slot from the foreign table, after locking it if required. + estate is global execution state for the query. + erm is the ExecRowMark struct describing + the target foreign table and the row lock type (if any) to acquire. + rowid identifies the tuple to be fetched. + slot contains nothing useful upon call, but can be used to + hold the returned tuple. updated is an output parameter. + + + + This function should store the tuple into the provided slot, or clear it if + the row lock couldn't be obtained. The row lock type to acquire is + defined by erm->markType, which is the value + previously returned by GetForeignRowMarkType. + (ROW_MARK_REFERENCE means to just re-fetch the tuple + without acquiring any lock, and ROW_MARK_COPY will + never be seen by this routine.) + + + + In addition, *updated should be set to true + if what was fetched was an updated version of the tuple rather than + the same version previously obtained. (If the FDW cannot be sure about + this, always returning true is recommended.) + + + + Note that by default, failure to acquire a row lock should result in + raising an error; returning with an empty slot is only appropriate if + the SKIP LOCKED option is specified + by erm->waitPolicy. + + + + The rowid is the ctid value previously read + for the row to be re-fetched. Although the rowid value is + passed as a Datum, it can currently only be a tid. The + function API is chosen in hopes that it may be possible to allow other + data types for row IDs in future. + + + + If the RefetchForeignRow pointer is set to + NULL, attempts to re-fetch rows will fail + with an error message. + + + + See for more information. + + + + +bool +RecheckForeignScan(ForeignScanState *node, + TupleTableSlot *slot); + + Recheck that a previously-returned tuple still matches the relevant + scan and join qualifiers, and possibly provide a modified version of + the tuple. For foreign data wrappers which do not perform join pushdown, + it will typically be more convenient to set this to NULL and + instead set fdw_recheck_quals appropriately. + When outer joins are pushed down, however, it isn't sufficient to + reapply the checks relevant to all the base tables to the result tuple, + even if all needed attributes are present, because failure to match some + qualifier might result in some attributes going to NULL, rather than in + no tuple being returned. RecheckForeignScan can recheck + qualifiers and return true if they are still satisfied and false + otherwise, but it can also store a replacement tuple into the supplied + slot. + + + + To implement join pushdown, a foreign data wrapper will typically + construct an alternative local join plan which is used only for + rechecks; this will become the outer subplan of the + ForeignScan. When a recheck is required, this subplan + can be executed and the resulting tuple can be stored in the slot. + This plan need not be efficient since no base table will return more + than one row; for example, it may implement all joins as nested loops. + The function GetExistingLocalJoinPath may be used to search + existing paths for a suitable local join path, which can be used as the + alternative local join plan. GetExistingLocalJoinPath + searches for an unparameterized path in the path list of the specified + join relation. (If it does not find such a path, it returns NULL, in + which case a foreign data wrapper may build the local path by itself or + may choose not to create access paths for that join.) + + + + + FDW Routines for <command>EXPLAIN</command> + + + +void +ExplainForeignScan(ForeignScanState *node, + ExplainState *es); + + + Print additional EXPLAIN output for a foreign table scan. + This function can call ExplainPropertyText and + related functions to add fields to the EXPLAIN output. + The flag fields in es can be used to determine what to + print, and the state of the ForeignScanState node + can be inspected to provide run-time statistics in the EXPLAIN + ANALYZE case. + + + + If the ExplainForeignScan pointer is set to + NULL, no additional information is printed during + EXPLAIN. + + + + +void +ExplainForeignModify(ModifyTableState *mtstate, + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + struct ExplainState *es); + + + Print additional EXPLAIN output for a foreign table update. + This function can call ExplainPropertyText and + related functions to add fields to the EXPLAIN output. + The flag fields in es can be used to determine what to + print, and the state of the ModifyTableState node + can be inspected to provide run-time statistics in the EXPLAIN + ANALYZE case. The first four arguments are the same as for + BeginForeignModify. + + + + If the ExplainForeignModify pointer is set to + NULL, no additional information is printed during + EXPLAIN. + + + + +void +ExplainDirectModify(ForeignScanState *node, + ExplainState *es); + + + Print additional EXPLAIN output for a direct modification + on the remote server. + This function can call ExplainPropertyText and + related functions to add fields to the EXPLAIN output. + The flag fields in es can be used to determine what to + print, and the state of the ForeignScanState node + can be inspected to provide run-time statistics in the EXPLAIN + ANALYZE case. + + + + If the ExplainDirectModify pointer is set to + NULL, no additional information is printed during + EXPLAIN. + + + + + + FDW Routines for <command>ANALYZE</command> + + + +bool +AnalyzeForeignTable(Relation relation, + AcquireSampleRowsFunc *func, + BlockNumber *totalpages); + + + This function is called when is executed on + a foreign table. If the FDW can collect statistics for this + foreign table, it should return true, and provide a pointer + to a function that will collect sample rows from the table in + func, plus the estimated size of the table in pages in + totalpages. Otherwise, return false. + + + + If the FDW does not support collecting statistics for any tables, the + AnalyzeForeignTable pointer can be set to NULL. + + + + If provided, the sample collection function must have the signature + +int +AcquireSampleRowsFunc(Relation relation, + int elevel, + HeapTuple *rows, + int targrows, + double *totalrows, + double *totaldeadrows); + + + A random sample of up to targrows rows should be collected + from the table and stored into the caller-provided rows + array. The actual number of rows collected must be returned. In + addition, store estimates of the total numbers of live and dead rows in + the table into the output parameters totalrows and + totaldeadrows. (Set totaldeadrows to zero + if the FDW does not have any concept of dead rows.) + + + + + + FDW Routines for <command>IMPORT FOREIGN SCHEMA</command> + + + +List * +ImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid); + + + Obtain a list of foreign table creation commands. This function is + called when executing , and is + passed the parse tree for that statement, as well as the OID of the + foreign server to use. It should return a list of C strings, each of + which must contain a command. + These strings will be parsed and executed by the core server. + + + + Within the ImportForeignSchemaStmt struct, + remote_schema is the name of the remote schema from + which tables are to be imported. + list_type identifies how to filter table names: + FDW_IMPORT_SCHEMA_ALL means that all tables in the remote + schema should be imported (in this case table_list is + empty), FDW_IMPORT_SCHEMA_LIMIT_TO means to include only + tables listed in table_list, + and FDW_IMPORT_SCHEMA_EXCEPT means to exclude the tables + listed in table_list. + options is a list of options used for the import process. + The meanings of the options are up to the FDW. + For example, an FDW could use an option to define whether the + NOT NULL attributes of columns should be imported. + These options need not have anything to do with those supported by the + FDW as database object options. + + + + The FDW may ignore the local_schema field of + the ImportForeignSchemaStmt, because the core server + will automatically insert that name into the parsed CREATE + FOREIGN TABLE commands. + + + + The FDW does not have to concern itself with implementing the filtering + specified by list_type and table_list, + either, as the core server will automatically skip any returned commands + for tables excluded according to those options. However, it's often + useful to avoid the work of creating commands for excluded tables in the + first place. The function IsImportableForeignTable() may be + useful to test whether a given foreign-table name will pass the filter. + + + + If the FDW does not support importing table definitions, the + ImportForeignSchema pointer can be set to NULL. + + + + + + FDW Routines for Parallel Execution + + A ForeignScan node can, optionally, support parallel + execution. A parallel ForeignScan will be executed + in multiple processes and must return each row exactly once across + all cooperating processes. To do this, processes can coordinate through + fixed-size chunks of dynamic shared memory. This shared memory is not + guaranteed to be mapped at the same address in every process, so it + must not contain pointers. The following functions are all optional, + but most are required if parallel execution is to be supported. + + + + +bool +IsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte); + + Test whether a scan can be performed within a parallel worker. This + function will only be called when the planner believes that a parallel + plan might be possible, and should return true if it is safe for that scan + to run within a parallel worker. This will generally not be the case if + the remote data source has transaction semantics, unless the worker's + connection to the data can somehow be made to share the same transaction + context as the leader. + + + + If this function is not defined, it is assumed that the scan must take + place within the parallel leader. Note that returning true does not mean + that the scan itself can be done in parallel, only that the scan can be + performed within a parallel worker. Therefore, it can be useful to define + this method even when parallel execution is not supported. + + + + +Size +EstimateDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt); + + Estimate the amount of dynamic shared memory that will be required + for parallel operation. This may be higher than the amount that will + actually be used, but it must not be lower. The return value is in bytes. + This function is optional, and can be omitted if not needed; but if it + is omitted, the next three functions must be omitted as well, because + no shared memory will be allocated for the FDW's use. + + + + +void +InitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt, + void *coordinate); + + Initialize the dynamic shared memory that will be required for parallel + operation. coordinate points to a shared memory area of + size equal to the return value of EstimateDSMForeignScan. + This function is optional, and can be omitted if not needed. + + + + +void +ReInitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt, + void *coordinate); + + Re-initialize the dynamic shared memory required for parallel operation + when the foreign-scan plan node is about to be re-scanned. + This function is optional, and can be omitted if not needed. + Recommended practice is that this function reset only shared state, + while the ReScanForeignScan function resets only local + state. Currently, this function will be called + before ReScanForeignScan, but it's best not to rely on + that ordering. + + + + +void +InitializeWorkerForeignScan(ForeignScanState *node, shm_toc *toc, + void *coordinate); + + Initialize a parallel worker's local state based on the shared state + set up by the leader during InitializeDSMForeignScan. + This function is optional, and can be omitted if not needed. + + + + +void +ShutdownForeignScan(ForeignScanState *node); + + Release resources when it is anticipated the node will not be executed + to completion. This is not called in all cases; sometimes, + EndForeignScan may be called without this function having + been called first. Since the DSM segment used by parallel query is + destroyed just after this callback is invoked, foreign data wrappers that + wish to take some action before the DSM segment goes away should implement + this method. + + + + + FDW Routines for Asynchronous Execution + + A ForeignScan node can, optionally, support + asynchronous execution as described in + src/backend/executor/README. The following + functions are all optional, but are all required if asynchronous + execution is to be supported. + + + + +bool +IsForeignPathAsyncCapable(ForeignPath *path); + + Test whether a given ForeignPath path can scan + the underlying foreign relation asynchronously. + This function will only be called at the end of query planning when the + given path is a direct child of an AppendPath + path and when the planner believes that asynchronous execution improves + performance, and should return true if the given path is able to scan the + foreign relation asynchronously. + + + + If this function is not defined, it is assumed that the given path scans + the foreign relation using IterateForeignScan. + (This implies that the callback functions described below will never be + called, so they need not be provided either.) + + + + +void +ForeignAsyncRequest(AsyncRequest *areq); + + Produce one tuple asynchronously from the + ForeignScan node. areq is + the AsyncRequest struct describing the + ForeignScan node and the parent + Append node that requested the tuple from it. + This function should store the tuple into the slot specified by + areq->result, and set + areq->request_complete to true; + or if it needs to wait on an event external to the core server such as + network I/O, and cannot produce any tuple immediately, set the flag to + false, and set + areq->callback_pending to true + for the ForeignScan node to get a callback from + the callback functions described below. If no more tuples are available, + set the slot to NULL or an empty slot, and the + areq->request_complete flag to + true. It's recommended to use + ExecAsyncRequestDone or + ExecAsyncRequestPending to set the output parameters + in the areq. + + + + +void +ForeignAsyncConfigureWait(AsyncRequest *areq); + + Configure a file descriptor event for which the + ForeignScan node wishes to wait. + This function will only be called when the + ForeignScan node has the + areq->callback_pending flag set, and should add + the event to the as_eventset of the parent + Append node described by the + areq. See the comments for + ExecAsyncConfigureWait in + src/backend/executor/execAsync.c for additional + information. When the file descriptor event occurs, + ForeignAsyncNotify will be called. + + + + +void +ForeignAsyncNotify(AsyncRequest *areq); + + Process a relevant event that has occurred, then produce one tuple + asynchronously from the ForeignScan node. + This function should set the output parameters in the + areq in the same way as + ForeignAsyncRequest. + + + + + FDW Routines for Reparameterization of Paths + + + +List * +ReparameterizeForeignPathByChild(PlannerInfo *root, List *fdw_private, + RelOptInfo *child_rel); + + This function is called while converting a path parameterized by the + top-most parent of the given child relation child_rel to be + parameterized by the child relation. The function is used to reparameterize + any paths or translate any expression nodes saved in the given + fdw_private member of a ForeignPath. The + callback may use reparameterize_path_by_child, + adjust_appendrel_attrs or + adjust_appendrel_attrs_multilevel as required. + + + + + + + Foreign Data Wrapper Helper Functions + + + Several helper functions are exported from the core server so that + authors of foreign data wrappers can get easy access to attributes of + FDW-related objects, such as FDW options. + To use any of these functions, you need to include the header file + foreign/foreign.h in your source file. + That header also defines the struct types that are returned by + these functions. + + + + +ForeignDataWrapper * +GetForeignDataWrapperExtended(Oid fdwid, bits16 flags); + + + This function returns a ForeignDataWrapper + object for the foreign-data wrapper with the given OID. A + ForeignDataWrapper object contains properties + of the FDW (see foreign/foreign.h for details). + flags is a bitwise-or'd bit mask indicating + an extra set of options. It can take the value + FDW_MISSING_OK, in which case a NULL + result is returned to the caller instead of an error for an undefined + object. + + + + +ForeignDataWrapper * +GetForeignDataWrapper(Oid fdwid); + + + This function returns a ForeignDataWrapper + object for the foreign-data wrapper with the given OID. A + ForeignDataWrapper object contains properties + of the FDW (see foreign/foreign.h for details). + + + + +ForeignServer * +GetForeignServerExtended(Oid serverid, bits16 flags); + + + This function returns a ForeignServer object + for the foreign server with the given OID. A + ForeignServer object contains properties + of the server (see foreign/foreign.h for details). + flags is a bitwise-or'd bit mask indicating + an extra set of options. It can take the value + FSV_MISSING_OK, in which case a NULL + result is returned to the caller instead of an error for an undefined + object. + + + + +ForeignServer * +GetForeignServer(Oid serverid); + + + This function returns a ForeignServer object + for the foreign server with the given OID. A + ForeignServer object contains properties + of the server (see foreign/foreign.h for details). + + + + +UserMapping * +GetUserMapping(Oid userid, Oid serverid); + + + This function returns a UserMapping object for + the user mapping of the given role on the given server. (If there is no + mapping for the specific user, it will return the mapping for + PUBLIC, or throw error if there is none.) A + UserMapping object contains properties of the + user mapping (see foreign/foreign.h for details). + + + + +ForeignTable * +GetForeignTable(Oid relid); + + + This function returns a ForeignTable object for + the foreign table with the given OID. A + ForeignTable object contains properties of the + foreign table (see foreign/foreign.h for details). + + + + +List * +GetForeignColumnOptions(Oid relid, AttrNumber attnum); + + + This function returns the per-column FDW options for the column with the + given foreign table OID and attribute number, in the form of a list of + DefElem. NIL is returned if the column has no + options. + + + + Some object types have name-based lookup functions in addition to the + OID-based ones: + + + + +ForeignDataWrapper * +GetForeignDataWrapperByName(const char *name, bool missing_ok); + + + This function returns a ForeignDataWrapper + object for the foreign-data wrapper with the given name. If the wrapper + is not found, return NULL if missing_ok is true, otherwise raise an + error. + + + + +ForeignServer * +GetForeignServerByName(const char *name, bool missing_ok); + + + This function returns a ForeignServer object + for the foreign server with the given name. If the server is not found, + return NULL if missing_ok is true, otherwise raise an error. + + + + + + Foreign Data Wrapper Query Planning + + + The FDW callback functions GetForeignRelSize, + GetForeignPaths, GetForeignPlan, + PlanForeignModify, GetForeignJoinPaths, + GetForeignUpperPaths, and PlanDirectModify + must fit into the workings of the PostgreSQL planner. + Here are some notes about what they must do. + + + + The information in root and baserel can be used + to reduce the amount of information that has to be fetched from the + foreign table (and therefore reduce the cost). + baserel->baserestrictinfo is particularly interesting, as + it contains restriction quals (WHERE clauses) that should be + used to filter the rows to be fetched. (The FDW itself is not required + to enforce these quals, as the core executor can check them instead.) + baserel->reltarget->exprs can be used to determine which + columns need to be fetched; but note that it only lists columns that + have to be emitted by the ForeignScan plan node, not + columns that are used in qual evaluation but not output by the query. + + + + Various private fields are available for the FDW planning functions to + keep information in. Generally, whatever you store in FDW private fields + should be palloc'd, so that it will be reclaimed at the end of planning. + + + + baserel->fdw_private is a void pointer that is + available for FDW planning functions to store information relevant to + the particular foreign table. The core planner does not touch it except + to initialize it to NULL when the RelOptInfo node is created. + It is useful for passing information forward from + GetForeignRelSize to GetForeignPaths and/or + GetForeignPaths to GetForeignPlan, thereby + avoiding recalculation. + + + + GetForeignPaths can identify the meaning of different + access paths by storing private information in the + fdw_private field of ForeignPath nodes. + fdw_private is declared as a List pointer, but + could actually contain anything since the core planner does not touch + it. However, best practice is to use a representation that's dumpable + by nodeToString, for use with debugging support available + in the backend. + + + + GetForeignPlan can examine the fdw_private + field of the selected ForeignPath node, and can generate + fdw_exprs and fdw_private lists to be + placed in the ForeignScan plan node, where they will be + available at execution time. Both of these lists must be + represented in a form that copyObject knows how to copy. + The fdw_private list has no other restrictions and is + not interpreted by the core backend in any way. The + fdw_exprs list, if not NIL, is expected to contain + expression trees that are intended to be executed at run time. These + trees will undergo post-processing by the planner to make them fully + executable. + + + + In GetForeignPlan, generally the passed-in target list can + be copied into the plan node as-is. The passed scan_clauses list + contains the same clauses as baserel->baserestrictinfo, + but may be re-ordered for better execution efficiency. In simple cases + the FDW can just strip RestrictInfo nodes from the + scan_clauses list (using extract_actual_clauses) and put + all the clauses into the plan node's qual list, which means that all the + clauses will be checked by the executor at run time. More complex FDWs + may be able to check some of the clauses internally, in which case those + clauses can be removed from the plan node's qual list so that the + executor doesn't waste time rechecking them. + + + + As an example, the FDW might identify some restriction clauses of the + form foreign_variable = + sub_expression, which it determines can be executed on + the remote server given the locally-evaluated value of the + sub_expression. The actual identification of such a + clause should happen during GetForeignPaths, since it would + affect the cost estimate for the path. The path's + fdw_private field would probably include a pointer to + the identified clause's RestrictInfo node. Then + GetForeignPlan would remove that clause from scan_clauses, + but add the sub_expression to fdw_exprs + to ensure that it gets massaged into executable form. It would probably + also put control information into the plan node's + fdw_private field to tell the execution functions what + to do at run time. The query transmitted to the remote server would + involve something like WHERE foreign_variable = + $1, with the parameter value obtained at run time from + evaluation of the fdw_exprs expression tree. + + + + Any clauses removed from the plan node's qual list must instead be added + to fdw_recheck_quals or rechecked by + RecheckForeignScan in order to ensure correct behavior + at the READ COMMITTED isolation level. When a concurrent + update occurs for some other table involved in the query, the executor + may need to verify that all of the original quals are still satisfied for + the tuple, possibly against a different set of parameter values. Using + fdw_recheck_quals is typically easier than implementing checks + inside RecheckForeignScan, but this method will be + insufficient when outer joins have been pushed down, since the join tuples + in that case might have some fields go to NULL without rejecting the + tuple entirely. + + + + Another ForeignScan field that can be filled by FDWs + is fdw_scan_tlist, which describes the tuples returned by + the FDW for this plan node. For simple foreign table scans this can be + set to NIL, implying that the returned tuples have the + row type declared for the foreign table. A non-NIL value must be a + target list (list of TargetEntrys) containing Vars and/or + expressions representing the returned columns. This might be used, for + example, to show that the FDW has omitted some columns that it noticed + won't be needed for the query. Also, if the FDW can compute expressions + used by the query more cheaply than can be done locally, it could add + those expressions to fdw_scan_tlist. Note that join + plans (created from paths made by GetForeignJoinPaths) must + always supply fdw_scan_tlist to describe the set of + columns they will return. + + + + The FDW should always construct at least one path that depends only on + the table's restriction clauses. In join queries, it might also choose + to construct path(s) that depend on join clauses, for example + foreign_variable = + local_variable. Such clauses will not be found in + baserel->baserestrictinfo but must be sought in the + relation's join lists. A path using such a clause is called a + parameterized path. It must identify the other relations + used in the selected join clause(s) with a suitable value of + param_info; use get_baserel_parampathinfo + to compute that value. In GetForeignPlan, the + local_variable portion of the join clause would be added + to fdw_exprs, and then at run time the case works the + same as for an ordinary restriction clause. + + + + If an FDW supports remote joins, GetForeignJoinPaths should + produce ForeignPaths for potential remote joins in much + the same way as GetForeignPaths works for base tables. + Information about the intended join can be passed forward + to GetForeignPlan in the same ways described above. + However, baserestrictinfo is not relevant for join + relations; instead, the relevant join clauses for a particular join are + passed to GetForeignJoinPaths as a separate parameter + (extra->restrictlist). + + + + An FDW might additionally support direct execution of some plan actions + that are above the level of scans and joins, such as grouping or + aggregation. To offer such options, the FDW should generate paths and + insert them into the appropriate upper relation. For + example, a path representing remote aggregation should be inserted into + the UPPERREL_GROUP_AGG relation, using add_path. + This path will be compared on a cost basis with local aggregation + performed by reading a simple scan path for the foreign relation (note + that such a path must also be supplied, else there will be an error at + plan time). If the remote-aggregation path wins, which it usually would, + it will be converted into a plan in the usual way, by + calling GetForeignPlan. The recommended place to generate + such paths is in the GetForeignUpperPaths + callback function, which is called for each upper relation (i.e., each + post-scan/join processing step), if all the base relations of the query + come from the same FDW. + + + + PlanForeignModify and the other callbacks described in + are designed around the assumption + that the foreign relation will be scanned in the usual way and then + individual row updates will be driven by a local ModifyTable + plan node. This approach is necessary for the general case where an + update requires reading local tables as well as foreign tables. + However, if the operation could be executed entirely by the foreign + server, the FDW could generate a path representing that and insert it + into the UPPERREL_FINAL upper relation, where it would + compete against the ModifyTable approach. This approach + could also be used to implement remote SELECT FOR UPDATE, + rather than using the row locking callbacks described in + . Keep in mind that a path + inserted into UPPERREL_FINAL is responsible for + implementing all behavior of the query. + + + + When planning an UPDATE or DELETE, + PlanForeignModify and PlanDirectModify + can look up the RelOptInfo + struct for the foreign table and make use of the + baserel->fdw_private data previously created by the + scan-planning functions. However, in INSERT the target + table is not scanned so there is no RelOptInfo for it. + The List returned by PlanForeignModify has + the same restrictions as the fdw_private list of a + ForeignScan plan node, that is it must contain only + structures that copyObject knows how to copy. + + + + INSERT with an ON CONFLICT clause does not + support specifying the conflict target, as unique constraints or + exclusion constraints on remote tables are not locally known. This + in turn implies that ON CONFLICT DO UPDATE is not supported, + since the specification is mandatory there. + + + + + + Row Locking in Foreign Data Wrappers + + + If an FDW's underlying storage mechanism has a concept of locking + individual rows to prevent concurrent updates of those rows, it is + usually worthwhile for the FDW to perform row-level locking with as + close an approximation as practical to the semantics used in + ordinary PostgreSQL tables. There are multiple + considerations involved in this. + + + + One key decision to be made is whether to perform early + locking or late locking. In early locking, a row is + locked when it is first retrieved from the underlying store, while in + late locking, the row is locked only when it is known that it needs to + be locked. (The difference arises because some rows may be discarded by + locally-checked restriction or join conditions.) Early locking is much + simpler and avoids extra round trips to a remote store, but it can cause + locking of rows that need not have been locked, resulting in reduced + concurrency or even unexpected deadlocks. Also, late locking is only + possible if the row to be locked can be uniquely re-identified later. + Preferably the row identifier should identify a specific version of the + row, as PostgreSQL TIDs do. + + + + By default, PostgreSQL ignores locking considerations + when interfacing to FDWs, but an FDW can perform early locking without + any explicit support from the core code. The API functions described + in , which were added + in PostgreSQL 9.5, allow an FDW to use late locking if + it wishes. + + + + An additional consideration is that in READ COMMITTED + isolation mode, PostgreSQL may need to re-check + restriction and join conditions against an updated version of some + target tuple. Rechecking join conditions requires re-obtaining copies + of the non-target rows that were previously joined to the target tuple. + When working with standard PostgreSQL tables, this is + done by including the TIDs of the non-target tables in the column list + projected through the join, and then re-fetching non-target rows when + required. This approach keeps the join data set compact, but it + requires inexpensive re-fetch capability, as well as a TID that can + uniquely identify the row version to be re-fetched. By default, + therefore, the approach used with foreign tables is to include a copy of + the entire row fetched from a foreign table in the column list projected + through the join. This puts no special demands on the FDW but can + result in reduced performance of merge and hash joins. An FDW that is + capable of meeting the re-fetch requirements can choose to do it the + first way. + + + + For an UPDATE or DELETE on a foreign table, it + is recommended that the ForeignScan operation on the target + table perform early locking on the rows that it fetches, perhaps via the + equivalent of SELECT FOR UPDATE. An FDW can detect whether + a table is an UPDATE/DELETE target at plan time + by comparing its relid to root->parse->resultRelation, + or at execution time by using ExecRelationIsTargetRelation(). + An alternative possibility is to perform late locking within the + ExecForeignUpdate or ExecForeignDelete + callback, but no special support is provided for this. + + + + For foreign tables that are specified to be locked by a SELECT + FOR UPDATE/SHARE command, the ForeignScan operation can + again perform early locking by fetching tuples with the equivalent + of SELECT FOR UPDATE/SHARE. To perform late locking + instead, provide the callback functions defined + in . + In GetForeignRowMarkType, select rowmark option + ROW_MARK_EXCLUSIVE, ROW_MARK_NOKEYEXCLUSIVE, + ROW_MARK_SHARE, or ROW_MARK_KEYSHARE depending + on the requested lock strength. (The core code will act the same + regardless of which of these four options you choose.) + Elsewhere, you can detect whether a foreign table was specified to be + locked by this type of command by using get_plan_rowmark at + plan time, or ExecFindRowMark at execution time; you must + check not only whether a non-null rowmark struct is returned, but that + its strength field is not LCS_NONE. + + + + Lastly, for foreign tables that are used in an UPDATE, + DELETE or SELECT FOR UPDATE/SHARE command but + are not specified to be row-locked, you can override the default choice + to copy entire rows by having GetForeignRowMarkType select + option ROW_MARK_REFERENCE when it sees lock strength + LCS_NONE. This will cause RefetchForeignRow to + be called with that value for markType; it should then + re-fetch the row without acquiring any new lock. (If you have + a GetForeignRowMarkType function but don't wish to re-fetch + unlocked rows, select option ROW_MARK_COPY + for LCS_NONE.) + + + + See src/include/nodes/lockoptions.h, the comments + for RowMarkType and PlanRowMark + in src/include/nodes/plannodes.h, and the comments for + ExecRowMark in src/include/nodes/execnodes.h for + additional information. + + + + + diff --git a/doc/src/sgml/file-fdw.sgml b/doc/src/sgml/file-fdw.sgml new file mode 100644 index 000000000000..5b98782064f1 --- /dev/null +++ b/doc/src/sgml/file-fdw.sgml @@ -0,0 +1,282 @@ + + + + file_fdw + + + file_fdw + + + + The file_fdw module provides the foreign-data wrapper + file_fdw, which can be used to access data + files in the server's file system, or to execute programs on the server + and read their output. The data file or program output must be in a format + that can be read by COPY FROM; + see for details. + Access to data files is currently read-only. + + + + A foreign table created using this wrapper can have the following options: + + + + + + filename + + + + Specifies the file to be read. Relative paths are relative to the + data directory. + Either filename or program must be + specified, but not both. + + + + + + program + + + + Specifies the command to be executed. The standard output of this + command will be read as though COPY FROM PROGRAM were used. + Either program or filename must be + specified, but not both. + + + + + + format + + + + Specifies the data format, + the same as COPY's FORMAT option. + + + + + + header + + + + Specifies whether the data has a header line, + the same as COPY's HEADER option. + + + + + + delimiter + + + + Specifies the data delimiter character, + the same as COPY's DELIMITER option. + + + + + + quote + + + + Specifies the data quote character, + the same as COPY's QUOTE option. + + + + + + escape + + + + Specifies the data escape character, + the same as COPY's ESCAPE option. + + + + + + null + + + + Specifies the data null string, + the same as COPY's NULL option. + + + + + + encoding + + + + Specifies the data encoding, + the same as COPY's ENCODING option. + + + + + + + + Note that while COPY allows options such as HEADER + to be specified without a corresponding value, the foreign table option + syntax requires a value to be present in all cases. To activate + COPY options typically written without a value, you can pass + the value TRUE, since all such options are Booleans. + + + + A column of a foreign table created using this wrapper can have the + following options: + + + + + + force_not_null + + + + This is a Boolean option. If true, it specifies that values of the + column should not be matched against the null string (that is, the + table-level null option). This has the same effect + as listing the column in COPY's + FORCE_NOT_NULL option. + + + + + + force_null + + + + This is a Boolean option. If true, it specifies that values of the + column which match the null string are returned as NULL + even if the value is quoted. Without this option, only unquoted + values matching the null string are returned as NULL. + This has the same effect as listing the column in + COPY's FORCE_NULL option. + + + + + + + + COPY's FORCE_QUOTE option is + currently not supported by file_fdw. + + + + These options can only be specified for a foreign table or its columns, not + in the options of the file_fdw foreign-data wrapper, nor in the + options of a server or user mapping using the wrapper. + + + + Changing table-level options requires being a superuser or having the privileges + of the role pg_read_server_files (to use a filename) or + the role pg_execute_server_program (to use a program), + for security reasons: only certain users should be able to control which file is + read or which program is run. In principle regular users could be allowed to + change the other options, but that's not supported at present. + + + + When specifying the program option, keep in mind that the option + string is executed by the shell. If you need to pass any arguments to the + command that come from an untrusted source, you must be careful to strip or + escape any characters that might have special meaning to the shell. + For security reasons, it is best to use a fixed command string, or at least + avoid passing any user input in it. + + + + For a foreign table using file_fdw, EXPLAIN shows + the name of the file to be read or program to be run. + For a file, unless COSTS OFF is + specified, the file size (in bytes) is shown as well. + + + + Create a Foreign Table for PostgreSQL CSV Logs + + + One of the obvious uses for file_fdw is to make + the PostgreSQL activity log available as a table for querying. To + do this, first you must be logging to a CSV file, + which here we + will call pglog.csv. First, install file_fdw + as an extension: + + + +CREATE EXTENSION file_fdw; + + + + Then create a foreign server: + + +CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw; + + + + + Now you are ready to create the foreign data table. Using the + CREATE FOREIGN TABLE command, you will need to define + the columns for the table, the CSV file name, and its format: + + +CREATE FOREIGN TABLE pglog ( + log_time timestamp(3) with time zone, + user_name text, + database_name text, + process_id integer, + connection_from text, + session_id text, + session_line_num bigint, + command_tag text, + session_start_time timestamp with time zone, + virtual_transaction_id text, + transaction_id bigint, + error_severity text, + sql_state_code text, + message text, + detail text, + hint text, + internal_query text, + internal_query_pos integer, + context text, + query text, + query_pos integer, + location text, + application_name text, + backend_type text, + leader_pid integer, + query_id bigint +) SERVER pglog +OPTIONS ( filename 'log/pglog.csv', format 'csv' ); + + + + + That's it — now you can query your log directly. In production, of + course, you would need to define some way to deal with log rotation. + + + + diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml new file mode 100644 index 000000000000..45b701426b97 --- /dev/null +++ b/doc/src/sgml/filelist.sgml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +%allfiles; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml new file mode 100644 index 000000000000..6388385edc56 --- /dev/null +++ b/doc/src/sgml/func.sgml @@ -0,0 +1,27825 @@ + + + + Functions and Operators + + + function + + + + operator + + + + PostgreSQL provides a large number of + functions and operators for the built-in data types. This chapter + describes most of them, although additional special-purpose functions + appear in relevant sections of the manual. Users can also + define their own functions and operators, as described in + . The + psql commands \df and + \do can be used to list all + available functions and operators, respectively. + + + + The notation used throughout this chapter to describe the argument and + result data types of a function or operator is like this: + +repeat ( text, integer ) text + + which says that the function repeat takes one text and + one integer argument and returns a result of type text. The right arrow + is also used to indicate the result of an example, thus: + +repeat('Pg', 4) PgPgPgPg + + + + + If you are concerned about portability then note that most of + the functions and operators described in this chapter, with the + exception of the most trivial arithmetic and comparison operators + and some explicitly marked functions, are not specified by the + SQL standard. Some of this extended functionality + is present in other SQL database management + systems, and in many cases this functionality is compatible and + consistent between the various implementations. + + + + + Logical Operators + + + operator + logical + + + + Boolean + operators + operators, logical + + + + The usual logical operators are available: + + + AND (operator) + + + + OR (operator) + + + + NOT (operator) + + + + conjunction + + + + disjunction + + + + negation + + + +boolean AND boolean boolean +boolean OR boolean boolean +NOT boolean boolean + + + SQL uses a three-valued logic system with true, + false, and null, which represents unknown. + Observe the following truth tables: + + + + + + a + b + a AND b + a OR b + + + + + + TRUE + TRUE + TRUE + TRUE + + + + TRUE + FALSE + FALSE + TRUE + + + + TRUE + NULL + NULL + TRUE + + + + FALSE + FALSE + FALSE + FALSE + + + + FALSE + NULL + FALSE + NULL + + + + NULL + NULL + NULL + NULL + + + + + + + + + + a + NOT a + + + + + + TRUE + FALSE + + + + FALSE + TRUE + + + + NULL + NULL + + + + + + + + The operators AND and OR are + commutative, that is, you can switch the left and right operands + without affecting the result. (However, it is not guaranteed that + the left operand is evaluated before the right operand. See for more information about the + order of evaluation of subexpressions.) + + + + + Comparison Functions and Operators + + + comparison + operators + + + + The usual comparison operators are available, as shown in . + + + + Comparison Operators + + + + Operator + Description + + + + + + + datatype < datatype + boolean + + Less than + + + + + datatype > datatype + boolean + + Greater than + + + + + datatype <= datatype + boolean + + Less than or equal to + + + + + datatype >= datatype + boolean + + Greater than or equal to + + + + + datatype = datatype + boolean + + Equal + + + + + datatype <> datatype + boolean + + Not equal + + + + + datatype != datatype + boolean + + Not equal + + + +
+ + + + <> is the standard SQL notation for not + equal. != is an alias, which is converted + to <> at a very early stage of parsing. + Hence, it is not possible to implement != + and <> operators that do different things. + + + + + These comparison operators are available for all built-in data types + that have a natural ordering, including numeric, string, and date/time + types. In addition, arrays, composite types, and ranges can be compared + if their component data types are comparable. + + + + It is usually possible to compare values of related data + types as well; for example integer > + bigint will work. Some cases of this sort are implemented + directly by cross-type comparison operators, but if no + such operator is available, the parser will coerce the less-general type + to the more-general type and apply the latter's comparison operator. + + + + As shown above, all comparison operators are binary operators that + return values of type boolean. Thus, expressions like + 1 < 2 < 3 are not valid (because there is + no < operator to compare a Boolean value with + 3). Use the BETWEEN predicates + shown below to perform range tests. + + + + There are also some comparison predicates, as shown in . These behave much like + operators, but have special syntax mandated by the SQL standard. + + + + Comparison Predicates + + + + + Predicate + + + Description + + + Example(s) + + + + + + + + datatype BETWEEN datatype AND datatype + boolean + + + Between (inclusive of the range endpoints). + + + 2 BETWEEN 1 AND 3 + t + + + 2 BETWEEN 3 AND 1 + f + + + + + + datatype NOT BETWEEN datatype AND datatype + boolean + + + Not between (the negation of BETWEEN). + + + 2 NOT BETWEEN 1 AND 3 + f + + + + + + datatype BETWEEN SYMMETRIC datatype AND datatype + boolean + + + Between, after sorting the two endpoint values. + + + 2 BETWEEN SYMMETRIC 3 AND 1 + t + + + + + + datatype NOT BETWEEN SYMMETRIC datatype AND datatype + boolean + + + Not between, after sorting the two endpoint values. + + + 2 NOT BETWEEN SYMMETRIC 3 AND 1 + f + + + + + + datatype IS DISTINCT FROM datatype + boolean + + + Not equal, treating null as a comparable value. + + + 1 IS DISTINCT FROM NULL + t (rather than NULL) + + + NULL IS DISTINCT FROM NULL + f (rather than NULL) + + + + + + datatype IS NOT DISTINCT FROM datatype + boolean + + + Equal, treating null as a comparable value. + + + 1 IS NOT DISTINCT FROM NULL + f (rather than NULL) + + + NULL IS NOT DISTINCT FROM NULL + t (rather than NULL) + + + + + + datatype IS NULL + boolean + + + Test whether value is null. + + + 1.5 IS NULL + f + + + + + + datatype IS NOT NULL + boolean + + + Test whether value is not null. + + + 'null' IS NOT NULL + t + + + + + + datatype ISNULL + boolean + + + Test whether value is null (nonstandard syntax). + + + + + + datatype NOTNULL + boolean + + + Test whether value is not null (nonstandard syntax). + + + + + + boolean IS TRUE + boolean + + + Test whether boolean expression yields true. + + + true IS TRUE + t + + + NULL::boolean IS TRUE + f (rather than NULL) + + + + + + boolean IS NOT TRUE + boolean + + + Test whether boolean expression yields false or unknown. + + + true IS NOT TRUE + f + + + NULL::boolean IS NOT TRUE + t (rather than NULL) + + + + + + boolean IS FALSE + boolean + + + Test whether boolean expression yields false. + + + true IS FALSE + f + + + NULL::boolean IS FALSE + f (rather than NULL) + + + + + + boolean IS NOT FALSE + boolean + + + Test whether boolean expression yields true or unknown. + + + true IS NOT FALSE + t + + + NULL::boolean IS NOT FALSE + t (rather than NULL) + + + + + + boolean IS UNKNOWN + boolean + + + Test whether boolean expression yields unknown. + + + true IS UNKNOWN + f + + + NULL::boolean IS UNKNOWN + t (rather than NULL) + + + + + + boolean IS NOT UNKNOWN + boolean + + + Test whether boolean expression yields true or false. + + + true IS NOT UNKNOWN + t + + + NULL::boolean IS NOT UNKNOWN + f (rather than NULL) + + + + +
+ + + + BETWEEN + + + BETWEEN SYMMETRIC + + The BETWEEN predicate simplifies range tests: + +a BETWEEN x AND y + + is equivalent to + +a >= x AND a <= y + + Notice that BETWEEN treats the endpoint values as included + in the range. + BETWEEN SYMMETRIC is like BETWEEN + except there is no requirement that the argument to the left of + AND be less than or equal to the argument on the right. + If it is not, those two arguments are automatically swapped, so that + a nonempty range is always implied. + + + + The various variants of BETWEEN are implemented in + terms of the ordinary comparison operators, and therefore will work for + any data type(s) that can be compared. + + + + + The use of AND in the BETWEEN + syntax creates an ambiguity with the use of AND as a + logical operator. To resolve this, only a limited set of expression + types are allowed as the second argument of a BETWEEN + clause. If you need to write a more complex sub-expression + in BETWEEN, write parentheses around the + sub-expression. + + + + + + IS DISTINCT FROM + + + IS NOT DISTINCT FROM + + Ordinary comparison operators yield null (signifying unknown), + not true or false, when either input is null. For example, + 7 = NULL yields null, as does 7 <> NULL. When + this behavior is not suitable, use the + IS NOT DISTINCT FROM predicates: + +a IS DISTINCT FROM b +a IS NOT DISTINCT FROM b + + For non-null inputs, IS DISTINCT FROM is + the same as the <> operator. However, if both + inputs are null it returns false, and if only one input is + null it returns true. Similarly, IS NOT DISTINCT + FROM is identical to = for non-null + inputs, but it returns true when both inputs are null, and false when only + one input is null. Thus, these predicates effectively act as though null + were a normal data value, rather than unknown. + + + + + IS NULL + + + IS NOT NULL + + + ISNULL + + + NOTNULL + + To check whether a value is or is not null, use the predicates: + +expression IS NULL +expression IS NOT NULL + + or the equivalent, but nonstandard, predicates: + +expression ISNULL +expression NOTNULL + + null valuecomparing + + + + Do not write + expression = NULL + because NULL is not equal to + NULL. (The null value represents an unknown value, + and it is not known whether two unknown values are equal.) + + + + + Some applications might expect that + expression = NULL + returns true if expression evaluates to + the null value. It is highly recommended that these applications + be modified to comply with the SQL standard. However, if that + cannot be done the + configuration variable is available. If it is enabled, + PostgreSQL will convert x = + NULL clauses to x IS NULL. + + + + + If the expression is row-valued, then + IS NULL is true when the row expression itself is null + or when all the row's fields are null, while + IS NOT NULL is true when the row expression itself is non-null + and all the row's fields are non-null. Because of this behavior, + IS NULL and IS NOT NULL do not always return + inverse results for row-valued expressions; in particular, a row-valued + expression that contains both null and non-null fields will return false + for both tests. In some cases, it may be preferable to + write row IS DISTINCT FROM NULL + or row IS NOT DISTINCT FROM NULL, + which will simply check whether the overall row value is null without any + additional tests on the row fields. + + + + + IS TRUE + + + IS NOT TRUE + + + IS FALSE + + + IS NOT FALSE + + + IS UNKNOWN + + + IS NOT UNKNOWN + + Boolean values can also be tested using the predicates + +boolean_expression IS TRUE +boolean_expression IS NOT TRUE +boolean_expression IS FALSE +boolean_expression IS NOT FALSE +boolean_expression IS UNKNOWN +boolean_expression IS NOT UNKNOWN + + These will always return true or false, never a null value, even when the + operand is null. + A null input is treated as the logical value unknown. + Notice that IS UNKNOWN and IS NOT UNKNOWN are + effectively the same as IS NULL and + IS NOT NULL, respectively, except that the input + expression must be of Boolean type. + + + + Some comparison-related functions are also available, as shown in . + + + + Comparison Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + num_nonnulls + + num_nonnulls ( VARIADIC "any" ) + integer + + + Returns the number of non-null arguments. + + + num_nonnulls(1, NULL, 2) + 2 + + + + + + num_nulls + + num_nulls ( VARIADIC "any" ) + integer + + + Returns the number of null arguments. + + + num_nulls(1, NULL, 2) + 1 + + + + +
+ +
+ + + Mathematical Functions and Operators + + + Mathematical operators are provided for many + PostgreSQL types. For types without + standard mathematical conventions + (e.g., date/time types) we + describe the actual behavior in subsequent sections. + + + + shows the mathematical + operators that are available for the standard numeric types. + Unless otherwise noted, operators shown as + accepting numeric_type are available for all + the types smallint, integer, + bigint, numeric, real, + and double precision. + Operators shown as accepting integral_type + are available for the types smallint, integer, + and bigint. + Except where noted, each form of an operator returns the same data type + as its argument(s). Calls involving multiple argument data types, such + as integer + numeric, + are resolved by using the type appearing later in these lists. + + + + Mathematical Operators + + + + + + Operator + + + Description + + + Example(s) + + + + + + + + numeric_type + numeric_type + numeric_type + + + Addition + + + 2 + 3 + 5 + + + + + + + numeric_type + numeric_type + + + Unary plus (no operation) + + + + 3.5 + 3.5 + + + + + + numeric_type - numeric_type + numeric_type + + + Subtraction + + + 2 - 3 + -1 + + + + + + - numeric_type + numeric_type + + + Negation + + + - (-4) + 4 + + + + + + numeric_type * numeric_type + numeric_type + + + Multiplication + + + 2 * 3 + 6 + + + + + + numeric_type / numeric_type + numeric_type + + + Division (for integral types, division truncates the result towards + zero) + + + 5.0 / 2 + 2.5000000000000000 + + + 5 / 2 + 2 + + + (-5) / 2 + -2 + + + + + + numeric_type % numeric_type + numeric_type + + + Modulo (remainder); available for smallint, + integer, bigint, and numeric + + + 5 % 4 + 1 + + + + + + numeric ^ numeric + numeric + + + double precision ^ double precision + double precision + + + Exponentiation (unlike typical mathematical practice, multiple uses of + ^ will associate left to right) + + + 2 ^ 3 + 8 + + + 2 ^ 3 ^ 3 + 512 + + + + + + |/ double precision + double precision + + + Square root + + + |/ 25.0 + 5 + + + + + + ||/ double precision + double precision + + + Cube root + + + ||/ 64.0 + 4 + + + + + + @ numeric_type + numeric_type + + + Absolute value + + + @ -5.0 + 5 + + + + + + integral_type & integral_type + integral_type + + + Bitwise AND + + + 91 & 15 + 11 + + + + + + integral_type | integral_type + integral_type + + + Bitwise OR + + + 32 | 3 + 35 + + + + + + integral_type # integral_type + integral_type + + + Bitwise exclusive OR + + + 17 # 5 + 20 + + + + + + ~ integral_type + integral_type + + + Bitwise NOT + + + ~1 + -2 + + + + + + integral_type << integer + integral_type + + + Bitwise shift left + + + 1 << 4 + 16 + + + + + + integral_type >> integer + integral_type + + + Bitwise shift right + + + 8 >> 2 + 2 + + + + + +
+ + + shows the available + mathematical functions. + Many of these functions are provided in multiple forms with different + argument types. + Except where noted, any given form of a function returns the same + data type as its argument(s); cross-type cases are resolved in the + same way as explained above for operators. + The functions working with double precision data are mostly + implemented on top of the host system's C library; accuracy and behavior in + boundary cases can therefore vary depending on the host system. + + + + Mathematical Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + abs + + abs ( numeric_type ) + numeric_type + + + Absolute value + + + abs(-17.4) + 17.4 + + + + + + + cbrt + + cbrt ( double precision ) + double precision + + + Cube root + + + cbrt(64.0) + 4 + + + + + + + ceil + + ceil ( numeric ) + numeric + + + ceil ( double precision ) + double precision + + + Nearest integer greater than or equal to argument + + + ceil(42.2) + 43 + + + ceil(-42.8) + -42 + + + + + + + ceiling + + ceiling ( numeric ) + numeric + + + ceiling ( double precision ) + double precision + + + Nearest integer greater than or equal to argument (same + as ceil) + + + ceiling(95.3) + 96 + + + + + + + degrees + + degrees ( double precision ) + double precision + + + Converts radians to degrees + + + degrees(0.5) + 28.64788975654116 + + + + + + + div + + div ( y numeric, + x numeric ) + numeric + + + Integer quotient of y/x + (truncates towards zero) + + + div(9, 4) + 2 + + + + + + + exp + + exp ( numeric ) + numeric + + + exp ( double precision ) + double precision + + + Exponential (e raised to the given power) + + + exp(1.0) + 2.7182818284590452 + + + + + + + factorial + + factorial ( bigint ) + numeric + + + Factorial + + + factorial(5) + 120 + + + + + + + floor + + floor ( numeric ) + numeric + + + floor ( double precision ) + double precision + + + Nearest integer less than or equal to argument + + + floor(42.8) + 42 + + + floor(-42.8) + -43 + + + + + + + gcd + + gcd ( numeric_type, numeric_type ) + numeric_type + + + Greatest common divisor (the largest positive number that divides both + inputs with no remainder); returns 0 if both inputs + are zero; available for integer, bigint, + and numeric + + + gcd(1071, 462) + 21 + + + + + + + lcm + + lcm ( numeric_type, numeric_type ) + numeric_type + + + Least common multiple (the smallest strictly positive number that is + an integral multiple of both inputs); returns 0 if + either input is zero; available for integer, + bigint, and numeric + + + lcm(1071, 462) + 23562 + + + + + + + ln + + ln ( numeric ) + numeric + + + ln ( double precision ) + double precision + + + Natural logarithm + + + ln(2.0) + 0.6931471805599453 + + + + + + + log + + log ( numeric ) + numeric + + + log ( double precision ) + double precision + + + Base 10 logarithm + + + log(100) + 2 + + + + + + + log10 + + log10 ( numeric ) + numeric + + + log10 ( double precision ) + double precision + + + Base 10 logarithm (same as log) + + + log10(1000) + 3 + + + + + + log ( b numeric, + x numeric ) + numeric + + + Logarithm of x to base b + + + log(2.0, 64.0) + 6.0000000000 + + + + + + + min_scale + + min_scale ( numeric ) + integer + + + Minimum scale (number of fractional decimal digits) needed + to represent the supplied value precisely + + + min_scale(8.4100) + 2 + + + + + + + mod + + mod ( y numeric_type, + x numeric_type ) + numeric_type + + + Remainder of y/x; + available for smallint, integer, + bigint, and numeric + + + mod(9, 4) + 1 + + + + + + + pi + + pi ( ) + double precision + + + Approximate value of π + + + pi() + 3.141592653589793 + + + + + + + power + + power ( a numeric, + b numeric ) + numeric + + + power ( a double precision, + b double precision ) + double precision + + + a raised to the power of b + + + power(9, 3) + 729 + + + + + + + radians + + radians ( double precision ) + double precision + + + Converts degrees to radians + + + radians(45.0) + 0.7853981633974483 + + + + + + + round + + round ( numeric ) + numeric + + + round ( double precision ) + double precision + + + Rounds to nearest integer. For numeric, ties are + broken by rounding away from zero. For double precision, + the tie-breaking behavior is platform dependent, but + round to nearest even is the most common rule. + + + round(42.4) + 42 + + + + + + round ( v numeric, s integer ) + numeric + + + Rounds v to s decimal + places. Ties are broken by rounding away from zero. + + + round(42.4382, 2) + 42.44 + + + + + + + scale + + scale ( numeric ) + integer + + + Scale of the argument (the number of decimal digits in the fractional part) + + + scale(8.4100) + 4 + + + + + + + sign + + sign ( numeric ) + numeric + + + sign ( double precision ) + double precision + + + Sign of the argument (-1, 0, or +1) + + + sign(-8.4) + -1 + + + + + + + sqrt + + sqrt ( numeric ) + numeric + + + sqrt ( double precision ) + double precision + + + Square root + + + sqrt(2) + 1.4142135623730951 + + + + + + + trim_scale + + trim_scale ( numeric ) + numeric + + + Reduces the value's scale (number of fractional decimal digits) by + removing trailing zeroes + + + trim_scale(8.4100) + 8.41 + + + + + + + trunc + + trunc ( numeric ) + numeric + + + trunc ( double precision ) + double precision + + + Truncates to integer (towards zero) + + + trunc(42.8) + 42 + + + trunc(-42.8) + -42 + + + + + + trunc ( v numeric, s integer ) + numeric + + + Truncates v to s + decimal places + + + trunc(42.4382, 2) + 42.43 + + + + + + + width_bucket + + width_bucket ( operand numeric, low numeric, high numeric, count integer ) + integer + + + width_bucket ( operand double precision, low double precision, high double precision, count integer ) + integer + + + Returns the number of the bucket in + which operand falls in a histogram + having count equal-width buckets spanning the + range low to high. + Returns 0 + or count+1 for an input + outside that range. + + + width_bucket(5.35, 0.024, 10.06, 5) + 3 + + + + + + width_bucket ( operand anycompatible, thresholds anycompatiblearray ) + integer + + + Returns the number of the bucket in + which operand falls given an array listing the + lower bounds of the buckets. Returns 0 for an + input less than the first lower + bound. operand and the array elements can be + of any type having standard comparison operators. + The thresholds array must be + sorted, smallest first, or unexpected results will be + obtained. + + + width_bucket(now(), array['yesterday', 'today', 'tomorrow']::timestamptz[]) + 2 + + + + +
+ + + shows functions for + generating random numbers. + + + + Random Functions + + + + + + Function + + + Description + + + Example(s) + + + + + + + + + random + + random ( ) + double precision + + + Returns a random value in the range 0.0 <= x < 1.0 + + + random() + 0.897124072839091 + + + + + + + setseed + + setseed ( double precision ) + void + + + Sets the seed for subsequent random() calls; + argument must be between -1.0 and 1.0, inclusive + + + setseed(0.12345) + + + + +
+ + + The random() function uses a simple linear + congruential algorithm. It is fast but not suitable for cryptographic + applications; see the module for a more + secure alternative. + If setseed() is called, the series of results of + subsequent random() calls in the current session + can be repeated by re-issuing setseed() with the same + argument. + + + + shows the + available trigonometric functions. Each of these functions comes in + two variants, one that measures angles in radians and one that + measures angles in degrees. + + + + Trigonometric Functions + + + + + + Function + + + Description + + + Example(s) + + + + + + + + + acos + + acos ( double precision ) + double precision + + + Inverse cosine, result in radians + + + acos(1) + 0 + + + + + + + acosd + + acosd ( double precision ) + double precision + + + Inverse cosine, result in degrees + + + acosd(0.5) + 60 + + + + + + + asin + + asin ( double precision ) + double precision + + + Inverse sine, result in radians + + + asin(1) + 1.5707963267948966 + + + + + + + asind + + asind ( double precision ) + double precision + + + Inverse sine, result in degrees + + + asind(0.5) + 30 + + + + + + + atan + + atan ( double precision ) + double precision + + + Inverse tangent, result in radians + + + atan(1) + 0.7853981633974483 + + + + + + + atand + + atand ( double precision ) + double precision + + + Inverse tangent, result in degrees + + + atand(1) + 45 + + + + + + + atan2 + + atan2 ( y double precision, + x double precision ) + double precision + + + Inverse tangent of + y/x, + result in radians + + + atan2(1, 0) + 1.5707963267948966 + + + + + + + atan2d + + atan2d ( y double precision, + x double precision ) + double precision + + + Inverse tangent of + y/x, + result in degrees + + + atan2d(1, 0) + 90 + + + + + + + cos + + cos ( double precision ) + double precision + + + Cosine, argument in radians + + + cos(0) + 1 + + + + + + + cosd + + cosd ( double precision ) + double precision + + + Cosine, argument in degrees + + + cosd(60) + 0.5 + + + + + + + cot + + cot ( double precision ) + double precision + + + Cotangent, argument in radians + + + cot(0.5) + 1.830487721712452 + + + + + + + cotd + + cotd ( double precision ) + double precision + + + Cotangent, argument in degrees + + + cotd(45) + 1 + + + + + + + sin + + sin ( double precision ) + double precision + + + Sine, argument in radians + + + sin(1) + 0.8414709848078965 + + + + + + + sind + + sind ( double precision ) + double precision + + + Sine, argument in degrees + + + sind(30) + 0.5 + + + + + + + tan + + tan ( double precision ) + double precision + + + Tangent, argument in radians + + + tan(1) + 1.5574077246549023 + + + + + + + tand + + tand ( double precision ) + double precision + + + Tangent, argument in degrees + + + tand(45) + 1 + + + + +
+ + + + Another way to work with angles measured in degrees is to use the unit + transformation functions radians() + and degrees() shown earlier. + However, using the degree-based trigonometric functions is preferred, + as that way avoids round-off error for special cases such + as sind(30). + + + + + shows the + available hyperbolic functions. + + + + Hyperbolic Functions + + + + + + Function + + + Description + + + Example(s) + + + + + + + + + sinh + + sinh ( double precision ) + double precision + + + Hyperbolic sine + + + sinh(1) + 1.1752011936438014 + + + + + + + cosh + + cosh ( double precision ) + double precision + + + Hyperbolic cosine + + + cosh(0) + 1 + + + + + + + tanh + + tanh ( double precision ) + double precision + + + Hyperbolic tangent + + + tanh(1) + 0.7615941559557649 + + + + + + + asinh + + asinh ( double precision ) + double precision + + + Inverse hyperbolic sine + + + asinh(1) + 0.881373587019543 + + + + + + + acosh + + acosh ( double precision ) + double precision + + + Inverse hyperbolic cosine + + + acosh(1) + 0 + + + + + + + atanh + + atanh ( double precision ) + double precision + + + Inverse hyperbolic tangent + + + atanh(0.5) + 0.5493061443340548 + + + + +
+ +
+ + + + String Functions and Operators + + + This section describes functions and operators for examining and + manipulating string values. Strings in this context include values + of the types character, character varying, + and text. Except where noted, these functions and operators + are declared to accept and return type text. They will + interchangeably accept character varying arguments. + Values of type character will be converted + to text before the function or operator is applied, resulting + in stripping any trailing spaces in the character value. + + + + SQL defines some string functions that use + key words, rather than commas, to separate + arguments. Details are in + . + PostgreSQL also provides versions of these functions + that use the regular function invocation syntax + (see ). + + + + + The string concatenation operator (||) will accept + non-string input, so long as at least one input is of string type, as shown + in . For other cases, inserting an + explicit coercion to text can be used to have non-string input + accepted. + + + + + <acronym>SQL</acronym> String Functions and Operators + + + + + Function/Operator + + + Description + + + Example(s) + + + + + + + + + character string + concatenation + + text || text + text + + + Concatenates the two strings. + + + 'Post' || 'greSQL' + PostgreSQL + + + + + + text || anynonarray + text + + + anynonarray || text + text + + + Converts the non-string input to text, then concatenates the two + strings. (The non-string input cannot be of an array type, because + that would create ambiguity with the array || + operators. If you want to concatenate an array's text equivalent, + cast it to text explicitly.) + + + 'Value: ' || 42 + Value: 42 + + + + + + + normalized + + + Unicode normalization + + text IS NOT form NORMALIZED + boolean + + + Checks whether the string is in the specified Unicode normalization + form. The optional form key word specifies the + form: NFC (the default), NFD, + NFKC, or NFKD. This expression can + only be used when the server encoding is UTF8. Note + that checking for normalization using this expression is often faster + than normalizing possibly already normalized strings. + + + U&'\0061\0308bc' IS NFD NORMALIZED + t + + + + + + + bit_length + + bit_length ( text ) + integer + + + Returns number of bits in the string (8 + times the octet_length). + + + bit_length('jose') + 32 + + + + + + + char_length + + + character string + length + + + length + of a character string + character string, length + + char_length ( text ) + integer + + + + character_length + + character_length ( text ) + integer + + + Returns number of characters in the string. + + + char_length('josé') + 4 + + + + + + + lower + + lower ( text ) + text + + + Converts the string to all lower case, according to the rules of the + database's locale. + + + lower('TOM') + tom + + + + + + + normalize + + + Unicode normalization + + normalize ( text + , form ) + text + + + Converts the string to the specified Unicode + normalization form. The optional form key word + specifies the form: NFC (the default), + NFD, NFKC, or + NFKD. This function can only be used when the + server encoding is UTF8. + + + normalize(U&'\0061\0308bc', NFC) + U&'\00E4bc' + + + + + + + octet_length + + octet_length ( text ) + integer + + + Returns number of bytes in the string. + + + octet_length('josé') + 5 (if server encoding is UTF8) + + + + + + + octet_length + + octet_length ( character ) + integer + + + Returns number of bytes in the string. Since this version of the + function accepts type character directly, it will not + strip trailing spaces. + + + octet_length('abc '::character(4)) + 4 + + + + + + + overlay + + overlay ( string text PLACING newsubstring text FROM start integer FOR count integer ) + text + + + Replaces the substring of string that starts at + the start'th character and extends + for count characters + with newsubstring. + If count is omitted, it defaults to the length + of newsubstring. + + + overlay('Txxxxas' placing 'hom' from 2 for 4) + Thomas + + + + + + + position + + position ( substring text IN string text ) + integer + + + Returns starting index of specified substring + within string, or zero if it's not present. + + + position('om' in 'Thomas') + 3 + + + + + + + substring + + substring ( string text FROM start integer FOR count integer ) + text + + + Extracts the substring of string starting at + the start'th character if that is specified, + and stopping after count characters if that is + specified. Provide at least one of start + and count. + + + substring('Thomas' from 2 for 3) + hom + + + substring('Thomas' from 3) + omas + + + substring('Thomas' for 2) + Th + + + + + + substring ( string text FROM pattern text ) + text + + + Extracts substring matching POSIX regular expression; see + . + + + substring('Thomas' from '...$') + mas + + + + + + substring ( string text SIMILAR pattern text ESCAPE escape text ) + text + + + substring ( string text FROM pattern text FOR escape text ) + text + + + Extracts substring matching SQL regular expression; + see . The first form has + been specified since SQL:2003; the second form was only in SQL:1999 + and should be considered obsolete. + + + substring('Thomas' similar '%#"o_a#"_' escape '#') + oma + + + + + + + trim + + trim ( LEADING | TRAILING | BOTH + characters text FROM + string text ) + text + + + Removes the longest string containing only characters in + characters (a space by default) from the + start, end, or both ends (BOTH is the default) + of string. + + + trim(both 'xyz' from 'yxTomxx') + Tom + + + + + + trim ( LEADING | TRAILING | BOTH FROM + string text , + characters text ) + text + + + This is a non-standard syntax for trim(). + + + trim(both from 'yxTomxx', 'xyz') + Tom + + + + + + + upper + + upper ( text ) + text + + + Converts the string to all upper case, according to the rules of the + database's locale. + + + upper('tom') + TOM + + + + +
+ + + Additional string manipulation functions are available and are + listed in . Some of them are used internally to implement the + SQL-standard string functions listed in . + + + + Other String Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + ascii + + ascii ( text ) + integer + + + Returns the numeric code of the first character of the argument. + In UTF8 encoding, returns the Unicode code point + of the character. In other multibyte encodings, the argument must + be an ASCII character. + + + ascii('x') + 120 + + + + + + + btrim + + btrim ( string text + , characters text ) + text + + + Removes the longest string containing only characters + in characters (a space by default) + from the start and end of string. + + + btrim('xyxtrimyyx', 'xyz') + trim + + + + + + + chr + + chr ( integer ) + text + + + Returns the character with the given code. In UTF8 + encoding the argument is treated as a Unicode code point. In other + multibyte encodings the argument must designate + an ASCII character. chr(0) is + disallowed because text data types cannot store that character. + + + chr(65) + A + + + + + + + concat + + concat ( val1 "any" + [, val2 "any" [, ...] ] ) + text + + + Concatenates the text representations of all the arguments. + NULL arguments are ignored. + + + concat('abcde', 2, NULL, 22) + abcde222 + + + + + + + concat_ws + + concat_ws ( sep text, + val1 "any" + [, val2 "any" [, ...] ] ) + text + + + Concatenates all but the first argument, with separators. The first + argument is used as the separator string, and should not be NULL. + Other NULL arguments are ignored. + + + concat_ws(',', 'abcde', 2, NULL, 22) + abcde,2,22 + + + + + + + format + + format ( formatstr text + [, formatarg "any" [, ...] ] ) + text + + + Formats arguments according to a format string; + see . + This function is similar to the C function sprintf. + + + format('Hello %s, %1$s', 'World') + Hello World, World + + + + + + + initcap + + initcap ( text ) + text + + + Converts the first letter of each word to upper case and the + rest to lower case. Words are sequences of alphanumeric + characters separated by non-alphanumeric characters. + + + initcap('hi THOMAS') + Hi Thomas + + + + + + + left + + left ( string text, + n integer ) + text + + + Returns first n characters in the + string, or when n is negative, returns + all but last |n| characters. + + + left('abcde', 2) + ab + + + + + + + length + + length ( text ) + integer + + + Returns the number of characters in the string. + + + length('jose') + 4 + + + + + + + lpad + + lpad ( string text, + length integer + , fill text ) + text + + + Extends the string to length + length by prepending the characters + fill (a space by default). If the + string is already longer than + length then it is truncated (on the right). + + + lpad('hi', 5, 'xy') + xyxhi + + + + + + + ltrim + + ltrim ( string text + , characters text ) + text + + + Removes the longest string containing only characters in + characters (a space by default) from the start of + string. + + + ltrim('zzzytest', 'xyz') + test + + + + + + + md5 + + md5 ( text ) + text + + + Computes the MD5 hash of + the argument, with the result written in hexadecimal. + + + md5('abc') + 900150983cd24fb0&zwsp;d6963f7d28e17f72 + + + + + + + parse_ident + + parse_ident ( qualified_identifier text + [, strict_mode boolean DEFAULT true ] ) + text[] + + + Splits qualified_identifier into an array of + identifiers, removing any quoting of individual identifiers. By + default, extra characters after the last identifier are considered an + error; but if the second parameter is false, then such + extra characters are ignored. (This behavior is useful for parsing + names for objects like functions.) Note that this function does not + truncate over-length identifiers. If you want truncation you can cast + the result to name[]. + + + parse_ident('"SomeSchema".someTable') + {SomeSchema,sometable} + + + + + + + pg_client_encoding + + pg_client_encoding ( ) + name + + + Returns current client encoding name. + + + pg_client_encoding() + UTF8 + + + + + + + quote_ident + + quote_ident ( text ) + text + + + Returns the given string suitably quoted to be used as an identifier + in an SQL statement string. + Quotes are added only if necessary (i.e., if the string contains + non-identifier characters or would be case-folded). + Embedded quotes are properly doubled. + See also . + + + quote_ident('Foo bar') + "Foo bar" + + + + + + + quote_literal + + quote_literal ( text ) + text + + + Returns the given string suitably quoted to be used as a string literal + in an SQL statement string. + Embedded single-quotes and backslashes are properly doubled. + Note that quote_literal returns null on null + input; if the argument might be null, + quote_nullable is often more suitable. + See also . + + + quote_literal(E'O\'Reilly') + 'O''Reilly' + + + + + + quote_literal ( anyelement ) + text + + + Converts the given value to text and then quotes it as a literal. + Embedded single-quotes and backslashes are properly doubled. + + + quote_literal(42.5) + '42.5' + + + + + + + quote_nullable + + quote_nullable ( text ) + text + + + Returns the given string suitably quoted to be used as a string literal + in an SQL statement string; or, if the argument + is null, returns NULL. + Embedded single-quotes and backslashes are properly doubled. + See also . + + + quote_nullable(NULL) + NULL + + + + + + quote_nullable ( anyelement ) + text + + + Converts the given value to text and then quotes it as a literal; + or, if the argument is null, returns NULL. + Embedded single-quotes and backslashes are properly doubled. + + + quote_nullable(42.5) + '42.5' + + + + + + + regexp_match + + regexp_match ( string text, pattern text [, flags text ] ) + text[] + + + Returns captured substring(s) resulting from the first match of a POSIX + regular expression to the string; see + . + + + regexp_match('foobarbequebaz', '(bar)(beque)') + {bar,beque} + + + + + + + regexp_matches + + regexp_matches ( string text, pattern text [, flags text ] ) + setof text[] + + + Returns captured substring(s) resulting from matching a POSIX regular + expression to the string; see + . + + + regexp_matches('foobarbequebaz', 'ba.', 'g') + + + {bar} + {baz} + + + + + + + + regexp_replace + + regexp_replace ( string text, pattern text, replacement text [, flags text ] ) + text + + + Replaces substring(s) matching a POSIX regular expression; see + . + + + regexp_replace('Thomas', '.[mN]a.', 'M') + ThM + + + + + + + regexp_split_to_array + + regexp_split_to_array ( string text, pattern text [, flags text ] ) + text[] + + + Splits string using a POSIX regular + expression as the delimiter, producing an array of results; see + . + + + regexp_split_to_array('hello world', '\s+') + {hello,world} + + + + + + + regexp_split_to_table + + regexp_split_to_table ( string text, pattern text [, flags text ] ) + setof text + + + Splits string using a POSIX regular + expression as the delimiter, producing a set of results; see + . + + + regexp_split_to_table('hello world', '\s+') + + + hello + world + + + + + + + + repeat + + repeat ( string text, number integer ) + text + + + Repeats string the specified + number of times. + + + repeat('Pg', 4) + PgPgPgPg + + + + + + + replace + + replace ( string text, + from text, + to text ) + text + + + Replaces all occurrences in string of + substring from with + substring to. + + + replace('abcdefabcdef', 'cd', 'XX') + abXXefabXXef + + + + + + + reverse + + reverse ( text ) + text + + + Reverses the order of the characters in the string. + + + reverse('abcde') + edcba + + + + + + + right + + right ( string text, + n integer ) + text + + + Returns last n characters in the string, + or when n is negative, returns all but + first |n| characters. + + + right('abcde', 2) + de + + + + + + + rpad + + rpad ( string text, + length integer + , fill text ) + text + + + Extends the string to length + length by appending the characters + fill (a space by default). If the + string is already longer than + length then it is truncated. + + + rpad('hi', 5, 'xy') + hixyx + + + + + + + rtrim + + rtrim ( string text + , characters text ) + text + + + Removes the longest string containing only characters in + characters (a space by default) from the end of + string. + + + rtrim('testxxzx', 'xyz') + test + + + + + + + split_part + + split_part ( string text, + delimiter text, + n integer ) + text + + + Splits string at occurrences + of delimiter and returns + the n'th field (counting from one), + or when n is negative, returns + the |n|'th-from-last field. + + + split_part('abc~@~def~@~ghi', '~@~', 2) + def + + + split_part('abc,def,ghi,jkl', ',', -2) + ghi + + + + + + + strpos + + strpos ( string text, substring text ) + integer + + + Returns starting index of specified substring + within string, or zero if it's not present. + (Same as position(substring in + string), but note the reversed + argument order.) + + + strpos('high', 'ig') + 2 + + + + + + + substr + + substr ( string text, start integer , count integer ) + text + + + Extracts the substring of string starting at + the start'th character, + and extending for count characters if that is + specified. (Same + as substring(string + from start + for count).) + + + substr('alphabet', 3) + phabet + + + substr('alphabet', 3, 2) + ph + + + + + + + starts_with + + starts_with ( string text, prefix text ) + boolean + + + Returns true if string starts + with prefix. + + + starts_with('alphabet', 'alph') + t + + + + + + + string_to_array + + string_to_array ( string text, delimiter text , null_string text ) + text[] + + + Splits the string at occurrences + of delimiter and forms the resulting fields + into a text array. + If delimiter is NULL, + each character in the string will become a + separate element in the array. + If delimiter is an empty string, then + the string is treated as a single field. + If null_string is supplied and is + not NULL, fields matching that string are + replaced by NULL. + + + string_to_array('xx~~yy~~zz', '~~', 'yy') + {xx,NULL,zz} + + + + + + + string_to_table + + string_to_table ( string text, delimiter text , null_string text ) + setof text + + + Splits the string at occurrences + of delimiter and returns the resulting fields + as a set of text rows. + If delimiter is NULL, + each character in the string will become a + separate row of the result. + If delimiter is an empty string, then + the string is treated as a single field. + If null_string is supplied and is + not NULL, fields matching that string are + replaced by NULL. + + + string_to_table('xx~^~yy~^~zz', '~^~', 'yy') + + + xx + NULL + zz + + + + + + + + to_ascii + + to_ascii ( string text ) + text + + + to_ascii ( string text, + encoding name ) + text + + + to_ascii ( string text, + encoding integer ) + text + + + Converts string to ASCII + from another encoding, which may be identified by name or number. + If encoding is omitted the database encoding + is assumed (which in practice is the only useful case). + The conversion consists primarily of dropping accents. + Conversion is only supported + from LATIN1, LATIN2, + LATIN9, and WIN1250 encodings. + (See the module for another, more flexible + solution.) + + + to_ascii('Karél') + Karel + + + + + + + to_hex + + to_hex ( integer ) + text + + + to_hex ( bigint ) + text + + + Converts the number to its equivalent hexadecimal representation. + + + to_hex(2147483647) + 7fffffff + + + + + + + translate + + translate ( string text, + from text, + to text ) + text + + + Replaces each character in string that + matches a character in the from set with the + corresponding character in the to + set. If from is longer than + to, occurrences of the extra characters in + from are deleted. + + + translate('12345', '143', 'ax') + a2x5 + + + + + + + unistr + + unistr ( text ) + text + + + Evaluate escaped Unicode characters in the argument. Unicode characters + can be specified as + \XXXX (4 hexadecimal + digits), \+XXXXXX (6 + hexadecimal digits), + \uXXXX (4 hexadecimal + digits), or \UXXXXXXXX + (8 hexadecimal digits). To specify a backslash, write two + backslashes. All other characters are taken literally. + + + + If the server encoding is not UTF-8, the Unicode code point identified + by one of these escape sequences is converted to the actual server + encoding; an error is reported if that's not possible. + + + + This function provides a (non-standard) alternative to string + constants with Unicode escapes (see ). + + + + unistr('d\0061t\+000061') + data + + + unistr('d\u0061t\U00000061') + data + + + + + +
+ + + The concat, concat_ws and + format functions are variadic, so it is possible to + pass the values to be concatenated or formatted as an array marked with + the VARIADIC keyword (see ). The array's elements are + treated as if they were separate ordinary arguments to the function. + If the variadic array argument is NULL, concat + and concat_ws return NULL, but + format treats a NULL as a zero-element array. + + + + See also the aggregate function string_agg in + , and the functions for + converting between strings and the bytea type in + . + + + + <function>format</function> + + + format + + + + The function format produces output formatted according to + a format string, in a style similar to the C function + sprintf. + + + + +format(formatstr text [, formatarg "any" [, ...] ]) + + formatstr is a format string that specifies how the + result should be formatted. Text in the format string is copied + directly to the result, except where format specifiers are + used. Format specifiers act as placeholders in the string, defining how + subsequent function arguments should be formatted and inserted into the + result. Each formatarg argument is converted to text + according to the usual output rules for its data type, and then formatted + and inserted into the result string according to the format specifier(s). + + + + Format specifiers are introduced by a % character and have + the form + +%[position][flags][width]type + + where the component fields are: + + + + position (optional) + + + A string of the form n$ where + n is the index of the argument to print. + Index 1 means the first argument after + formatstr. If the position is + omitted, the default is to use the next argument in sequence. + + + + + + flags (optional) + + + Additional options controlling how the format specifier's output is + formatted. Currently the only supported flag is a minus sign + (-) which will cause the format specifier's output to be + left-justified. This has no effect unless the width + field is also specified. + + + + + + width (optional) + + + Specifies the minimum number of characters to use to + display the format specifier's output. The output is padded on the + left or right (depending on the - flag) with spaces as + needed to fill the width. A too-small width does not cause + truncation of the output, but is simply ignored. The width may be + specified using any of the following: a positive integer; an + asterisk (*) to use the next function argument as the + width; or a string of the form *n$ to + use the nth function argument as the width. + + + + If the width comes from a function argument, that argument is + consumed before the argument that is used for the format specifier's + value. If the width argument is negative, the result is left + aligned (as if the - flag had been specified) within a + field of length abs(width). + + + + + + type (required) + + + The type of format conversion to use to produce the format + specifier's output. The following types are supported: + + + + s formats the argument value as a simple + string. A null value is treated as an empty string. + + + + + I treats the argument value as an SQL + identifier, double-quoting it if necessary. + It is an error for the value to be null (equivalent to + quote_ident). + + + + + L quotes the argument value as an SQL literal. + A null value is displayed as the string NULL, without + quotes (equivalent to quote_nullable). + + + + + + + + + + + In addition to the format specifiers described above, the special sequence + %% may be used to output a literal % character. + + + + Here are some examples of the basic format conversions: + + +SELECT format('Hello %s', 'World'); +Result: Hello World + +SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three'); +Result: Testing one, two, three, % + +SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); +Result: INSERT INTO "Foo bar" VALUES('O''Reilly') + +SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); +Result: INSERT INTO locations VALUES('C:\Program Files') + + + + + Here are examples using width fields + and the - flag: + + +SELECT format('|%10s|', 'foo'); +Result: | foo| + +SELECT format('|%-10s|', 'foo'); +Result: |foo | + +SELECT format('|%*s|', 10, 'foo'); +Result: | foo| + +SELECT format('|%*s|', -10, 'foo'); +Result: |foo | + +SELECT format('|%-*s|', 10, 'foo'); +Result: |foo | + +SELECT format('|%-*s|', -10, 'foo'); +Result: |foo | + + + + + These examples show use of position fields: + + +SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three'); +Result: Testing three, two, one + +SELECT format('|%*2$s|', 'foo', 10, 'bar'); +Result: | bar| + +SELECT format('|%1$*2$s|', 'foo', 10, 'bar'); +Result: | foo| + + + + + Unlike the standard C function sprintf, + PostgreSQL's format function allows format + specifiers with and without position fields to be mixed + in the same format string. A format specifier without a + position field always uses the next argument after the + last argument consumed. + In addition, the format function does not require all + function arguments to be used in the format string. + For example: + + +SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); +Result: Testing three, two, three + + + + + The %I and %L format specifiers are particularly + useful for safely constructing dynamic SQL statements. See + . + + + +
+ + + + Binary String Functions and Operators + + + binary data + functions + + + + This section describes functions and operators for examining and + manipulating binary strings, that is values of type bytea. + Many of these are equivalent, in purpose and syntax, to the + text-string functions described in the previous section. + + + + SQL defines some string functions that use + key words, rather than commas, to separate + arguments. Details are in + . + PostgreSQL also provides versions of these functions + that use the regular function invocation syntax + (see ). + + + + <acronym>SQL</acronym> Binary String Functions and Operators + + + + + Function/Operator + + + Description + + + Example(s) + + + + + + + + + binary string + concatenation + + bytea || bytea + bytea + + + Concatenates the two binary strings. + + + '\x123456'::bytea || '\x789a00bcde'::bytea + \x123456789a00bcde + + + + + + + bit_length + + bit_length ( bytea ) + integer + + + Returns number of bits in the binary string (8 + times the octet_length). + + + bit_length('\x123456'::bytea) + 24 + + + + + + + octet_length + + octet_length ( bytea ) + integer + + + Returns number of bytes in the binary string. + + + octet_length('\x123456'::bytea) + 3 + + + + + + + overlay + + overlay ( bytes bytea PLACING newsubstring bytea FROM start integer FOR count integer ) + bytea + + + Replaces the substring of bytes that starts at + the start'th byte and extends + for count bytes + with newsubstring. + If count is omitted, it defaults to the length + of newsubstring. + + + overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3) + \x12020390 + + + + + + + position + + position ( substring bytea IN bytes bytea ) + integer + + + Returns starting index of specified substring + within bytes, or zero if it's not present. + + + position('\x5678'::bytea in '\x1234567890'::bytea) + 3 + + + + + + + substring + + substring ( bytes bytea FROM start integer FOR count integer ) + bytea + + + Extracts the substring of bytes starting at + the start'th byte if that is specified, + and stopping after count bytes if that is + specified. Provide at least one of start + and count. + + + substring('\x1234567890'::bytea from 3 for 2) + \x5678 + + + + + + + trim + + trim ( LEADING | TRAILING | BOTH + bytesremoved bytea FROM + bytes bytea ) + bytea + + + Removes the longest string containing only bytes appearing in + bytesremoved from the start, + end, or both ends (BOTH is the default) + of bytes. + + + trim('\x9012'::bytea from '\x1234567890'::bytea) + \x345678 + + + + + + trim ( LEADING | TRAILING | BOTH FROM + bytes bytea, + bytesremoved bytea ) + bytea + + + This is a non-standard syntax for trim(). + + + trim(both from '\x1234567890'::bytea, '\x9012'::bytea) + \x345678 + + + + +
+ + + Additional binary string manipulation functions are available and + are listed in . Some + of them are used internally to implement the + SQL-standard string functions listed in . + + + + Other Binary String Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + bit_count + + + popcount + bit_count + + bit_count ( bytes bytea ) + bigint + + + Returns the number of bits set in the binary string (also known as + popcount). + + + bit_count('\x1234567890'::bytea) + 31 + + + + + + + btrim + + btrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + Removes the longest string containing only bytes appearing in + bytesremoved from the start and end of + bytes. + + + btrim('\x1234567890'::bytea, '\x9012'::bytea) + \x345678 + + + + + + + get_bit + + get_bit ( bytes bytea, + n bigint ) + integer + + + Extracts n'th bit + from binary string. + + + get_bit('\x1234567890'::bytea, 30) + 1 + + + + + + + get_byte + + get_byte ( bytes bytea, + n integer ) + integer + + + Extracts n'th byte + from binary string. + + + get_byte('\x1234567890'::bytea, 4) + 144 + + + + + + + length + + + binary string + length + + + length + of a binary string + binary strings, length + + length ( bytea ) + integer + + + Returns the number of bytes in the binary string. + + + length('\x1234567890'::bytea) + 5 + + + + + + length ( bytes bytea, + encoding name ) + integer + + + Returns the number of characters in the binary string, assuming + that it is text in the given encoding. + + + length('jose'::bytea, 'UTF8') + 4 + + + + + + + ltrim + + ltrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + Removes the longest string containing only bytes appearing in + bytesremoved from the start of + bytes. + + + ltrim('\x1234567890'::bytea, '\x9012'::bytea) + \x34567890 + + + + + + + md5 + + md5 ( bytea ) + text + + + Computes the MD5 hash of + the binary string, with the result written in hexadecimal. + + + md5('Th\000omas'::bytea) + 8ab2d3c9689aaf18&zwsp;b4958c334c82d8b1 + + + + + + + rtrim + + rtrim ( bytes bytea, + bytesremoved bytea ) + bytea + + + Removes the longest string containing only bytes appearing in + bytesremoved from the end of + bytes. + + + rtrim('\x1234567890'::bytea, '\x9012'::bytea) + \x12345678 + + + + + + + set_bit + + set_bit ( bytes bytea, + n bigint, + newvalue integer ) + bytea + + + Sets n'th bit in + binary string to newvalue. + + + set_bit('\x1234567890'::bytea, 30, 0) + \x1234563890 + + + + + + + set_byte + + set_byte ( bytes bytea, + n integer, + newvalue integer ) + bytea + + + Sets n'th byte in + binary string to newvalue. + + + set_byte('\x1234567890'::bytea, 4, 64) + \x1234567840 + + + + + + + sha224 + + sha224 ( bytea ) + bytea + + + Computes the SHA-224 hash + of the binary string. + + + sha224('abc'::bytea) + \x23097d223405d8228642a477bda2&zwsp;55b32aadbce4bda0b3f7e36c9da7 + + + + + + + sha256 + + sha256 ( bytea ) + bytea + + + Computes the SHA-256 hash + of the binary string. + + + sha256('abc'::bytea) + \xba7816bf8f01cfea414140de5dae2223&zwsp;b00361a396177a9cb410ff61f20015ad + + + + + + + sha384 + + sha384 ( bytea ) + bytea + + + Computes the SHA-384 hash + of the binary string. + + + sha384('abc'::bytea) + \xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7 + + + + + + + sha512 + + sha512 ( bytea ) + bytea + + + Computes the SHA-512 hash + of the binary string. + + + sha512('abc'::bytea) + \xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f + + + + + + + substr + + substr ( bytes bytea, start integer , count integer ) + bytea + + + Extracts the substring of bytes starting at + the start'th byte, + and extending for count bytes if that is + specified. (Same + as substring(bytes + from start + for count).) + + + substr('\x1234567890'::bytea, 3, 2) + \x5678 + + + + +
+ + + Functions get_byte and set_byte + number the first byte of a binary string as byte 0. + Functions get_bit and set_bit + number bits from the right within each byte; for example bit 0 is the least + significant bit of the first byte, and bit 15 is the most significant bit + of the second byte. + + + + For historical reasons, the function md5 + returns a hex-encoded value of type text whereas the SHA-2 + functions return type bytea. Use the functions + encode + and decode to + convert between the two. For example write encode(sha256('abc'), + 'hex') to get a hex-encoded text representation, + or decode(md5('abc'), 'hex') to get + a bytea value. + + + + + character string + converting to binary string + + + binary string + converting to character string + + Functions for converting strings between different character sets + (encodings), and for representing arbitrary binary data in textual + form, are shown in + . For these + functions, an argument or result of type text is expressed + in the database's default encoding, while arguments or results of + type bytea are in an encoding named by another argument. + + + + Text/Binary String Conversion Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + convert + + convert ( bytes bytea, + src_encoding name, + dest_encoding name ) + bytea + + + Converts a binary string representing text in + encoding src_encoding + to a binary string in encoding dest_encoding + (see for + available conversions). + + + convert('text_in_utf8', 'UTF8', 'LATIN1') + \x746578745f696e5f75746638 + + + + + + + convert_from + + convert_from ( bytes bytea, + src_encoding name ) + text + + + Converts a binary string representing text in + encoding src_encoding + to text in the database encoding + (see for + available conversions). + + + convert_from('text_in_utf8', 'UTF8') + text_in_utf8 + + + + + + + convert_to + + convert_to ( string text, + dest_encoding name ) + bytea + + + Converts a text string (in the database encoding) to a + binary string encoded in encoding dest_encoding + (see for + available conversions). + + + convert_to('some_text', 'UTF8') + \x736f6d655f74657874 + + + + + + + encode + + encode ( bytes bytea, + format text ) + text + + + Encodes binary data into a textual representation; supported + format values are: + base64, + escape, + hex. + + + encode('123\000\001', 'base64') + MTIzAAE= + + + + + + + decode + + decode ( string text, + format text ) + bytea + + + Decodes binary data from a textual representation; supported + format values are the same as + for encode. + + + decode('MTIzAAE=', 'base64') + \x3132330001 + + + + +
+ + + The encode and decode + functions support the following textual formats: + + + + base64 + + base64 format + + + + The base64 format is that + of RFC + 2045 Section 6.8. As per the RFC, encoded lines are + broken at 76 characters. However instead of the MIME CRLF + end-of-line marker, only a newline is used for end-of-line. + The decode function ignores carriage-return, + newline, space, and tab characters. Otherwise, an error is + raised when decode is supplied invalid + base64 data — including when trailing padding is incorrect. + + + + + + escape + + escape format + + + + The escape format converts zero bytes and + bytes with the high bit set into octal escape sequences + (\nnn), and it doubles + backslashes. Other byte values are represented literally. + The decode function will raise an error if a + backslash is not followed by either a second backslash or three + octal digits; it accepts other byte values unchanged. + + + + + + hex + + hex format + + + + The hex format represents each 4 bits of + data as one hexadecimal digit, 0 + through f, writing the higher-order digit of + each byte first. The encode function outputs + the a-f hex digits in lower + case. Because the smallest unit of data is 8 bits, there are + always an even number of characters returned + by encode. + The decode function + accepts the a-f characters in + either upper or lower case. An error is raised + when decode is given invalid hex data + — including when given an odd number of characters. + + + + + + + + See also the aggregate function string_agg in + and the large object functions + in . + +
+ + + + Bit String Functions and Operators + + + bit strings + functions + + + + This section describes functions and operators for examining and + manipulating bit strings, that is values of the types + bit and bit varying. (While only + type bit is mentioned in these tables, values of + type bit varying can be used interchangeably.) + Bit strings support the usual comparison operators shown in + , as well as the + operators shown in . + + + + Bit String Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + bit || bit + bit + + + Concatenation + + + B'10001' || B'011' + 10001011 + + + + + + bit & bit + bit + + + Bitwise AND (inputs must be of equal length) + + + B'10001' & B'01101' + 00001 + + + + + + bit | bit + bit + + + Bitwise OR (inputs must be of equal length) + + + B'10001' | B'01101' + 11101 + + + + + + bit # bit + bit + + + Bitwise exclusive OR (inputs must be of equal length) + + + B'10001' # B'01101' + 11100 + + + + + + ~ bit + bit + + + Bitwise NOT + + + ~ B'10001' + 01110 + + + + + + bit << integer + bit + + + Bitwise shift left + (string length is preserved) + + + B'10001' << 3 + 01000 + + + + + + bit >> integer + bit + + + Bitwise shift right + (string length is preserved) + + + B'10001' >> 2 + 00100 + + + + +
+ + + Some of the functions available for binary strings are also available + for bit strings, as shown in . + + + + Bit String Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + bit_count + + bit_count ( bit ) + bigint + + + Returns the number of bits set in the bit string (also known as + popcount). + + + bit_count(B'10111') + 4 + + + + + + + bit_length + + bit_length ( bit ) + integer + + + Returns number of bits in the bit string. + + + bit_length(B'10111') + 5 + + + + + + + length + + + bit string + length + + length ( bit ) + integer + + + Returns number of bits in the bit string. + + + length(B'10111') + 5 + + + + + + + octet_length + + octet_length ( bit ) + integer + + + Returns number of bytes in the bit string. + + + octet_length(B'1011111011') + 2 + + + + + + + overlay + + overlay ( bits bit PLACING newsubstring bit FROM start integer FOR count integer ) + bit + + + Replaces the substring of bits that starts at + the start'th bit and extends + for count bits + with newsubstring. + If count is omitted, it defaults to the length + of newsubstring. + + + overlay(B'01010101010101010' placing B'11111' from 2 for 3) + 0111110101010101010 + + + + + + + position + + position ( substring bit IN bits bit ) + integer + + + Returns starting index of specified substring + within bits, or zero if it's not present. + + + position(B'010' in B'000001101011') + 8 + + + + + + + substring + + substring ( bits bit FROM start integer FOR count integer ) + bit + + + Extracts the substring of bits starting at + the start'th bit if that is specified, + and stopping after count bits if that is + specified. Provide at least one of start + and count. + + + substring(B'110010111111' from 3 for 2) + 00 + + + + + + + get_bit + + get_bit ( bits bit, + n integer ) + integer + + + Extracts n'th bit + from bit string; the first (leftmost) bit is bit 0. + + + get_bit(B'101010101010101010', 6) + 1 + + + + + + + set_bit + + set_bit ( bits bit, + n integer, + newvalue integer ) + bit + + + Sets n'th bit in + bit string to newvalue; + the first (leftmost) bit is bit 0. + + + set_bit(B'101010101010101010', 6, 0) + 101010001010101010 + + + + +
+ + + In addition, it is possible to cast integral values to and from type + bit. + Casting an integer to bit(n) copies the rightmost + n bits. Casting an integer to a bit string width wider + than the integer itself will sign-extend on the left. + Some examples: + +44::bit(10) 0000101100 +44::bit(3) 100 +cast(-44 as bit(12)) 111111010100 +'1110'::bit(4)::integer 14 + + Note that casting to just bit means casting to + bit(1), and so will deliver only the least significant + bit of the integer. + +
+ + + + Pattern Matching + + + pattern matching + + + + There are three separate approaches to pattern matching provided + by PostgreSQL: the traditional + SQL LIKE operator, the + more recent SIMILAR TO operator (added in + SQL:1999), and POSIX-style regular + expressions. Aside from the basic does this string match + this pattern? operators, functions are available to extract + or replace matching substrings and to split a string at matching + locations. + + + + + If you have pattern matching needs that go beyond this, + consider writing a user-defined function in Perl or Tcl. + + + + + + While most regular-expression searches can be executed very quickly, + regular expressions can be contrived that take arbitrary amounts of + time and memory to process. Be wary of accepting regular-expression + search patterns from hostile sources. If you must do so, it is + advisable to impose a statement timeout. + + + + Searches using SIMILAR TO patterns have the same + security hazards, since SIMILAR TO provides many + of the same capabilities as POSIX-style regular + expressions. + + + + LIKE searches, being much simpler than the other + two options, are safer to use with possibly-hostile pattern sources. + + + + + The pattern matching operators of all three kinds do not support + nondeterministic collations. If required, apply a different collation to + the expression to work around this limitation. + + + + <function>LIKE</function> + + + LIKE + + + +string LIKE pattern ESCAPE escape-character +string NOT LIKE pattern ESCAPE escape-character + + + + The LIKE expression returns true if the + string matches the supplied + pattern. (As + expected, the NOT LIKE expression returns + false if LIKE returns true, and vice versa. + An equivalent expression is + NOT (string LIKE + pattern).) + + + + If pattern does not contain percent + signs or underscores, then the pattern only represents the string + itself; in that case LIKE acts like the + equals operator. An underscore (_) in + pattern stands for (matches) any single + character; a percent sign (%) matches any sequence + of zero or more characters. + + + + Some examples: + +'abc' LIKE 'abc' true +'abc' LIKE 'a%' true +'abc' LIKE '_b_' true +'abc' LIKE 'c' false + + + + + LIKE pattern matching always covers the entire + string. Therefore, if it's desired to match a sequence anywhere within + a string, the pattern must start and end with a percent sign. + + + + To match a literal underscore or percent sign without matching + other characters, the respective character in + pattern must be + preceded by the escape character. The default escape + character is the backslash but a different one can be selected by + using the ESCAPE clause. To match the escape + character itself, write two escape characters. + + + + + If you have turned off, + any backslashes you write in literal string constants will need to be + doubled. See for more information. + + + + + It's also possible to select no escape character by writing + ESCAPE ''. This effectively disables the + escape mechanism, which makes it impossible to turn off the + special meaning of underscore and percent signs in the pattern. + + + + According to the SQL standard, omitting ESCAPE + means there is no escape character (rather than defaulting to a + backslash), and a zero-length ESCAPE value is + disallowed. PostgreSQL's behavior in + this regard is therefore slightly nonstandard. + + + + The key word ILIKE can be used instead of + LIKE to make the match case-insensitive according + to the active locale. This is not in the SQL standard but is a + PostgreSQL extension. + + + + The operator ~~ is equivalent to + LIKE, and ~~* corresponds to + ILIKE. There are also + !~~ and !~~* operators that + represent NOT LIKE and NOT + ILIKE, respectively. All of these operators are + PostgreSQL-specific. You may see these + operator names in EXPLAIN output and similar + places, since the parser actually translates LIKE + et al. to these operators. + + + + The phrases LIKE, ILIKE, + NOT LIKE, and NOT ILIKE are + generally treated as operators + in PostgreSQL syntax; for example they can + be used in expression + operator ANY + (subquery) constructs, although + an ESCAPE clause cannot be included there. In some + obscure cases it may be necessary to use the underlying operator names + instead. + + + + Also see the prefix operator ^@ and corresponding + starts_with function, which are useful in cases + where simply matching the beginning of a string is needed. + + + + + + <function>SIMILAR TO</function> Regular Expressions + + + regular expression + + + + + SIMILAR TO + + + substring + + + +string SIMILAR TO pattern ESCAPE escape-character +string NOT SIMILAR TO pattern ESCAPE escape-character + + + + The SIMILAR TO operator returns true or + false depending on whether its pattern matches the given string. + It is similar to LIKE, except that it + interprets the pattern using the SQL standard's definition of a + regular expression. SQL regular expressions are a curious cross + between LIKE notation and common (POSIX) regular + expression notation. + + + + Like LIKE, the SIMILAR TO + operator succeeds only if its pattern matches the entire string; + this is unlike common regular expression behavior where the pattern + can match any part of the string. + Also like + LIKE, SIMILAR TO uses + _ and % as wildcard characters denoting + any single character and any string, respectively (these are + comparable to . and .* in POSIX regular + expressions). + + + + In addition to these facilities borrowed from LIKE, + SIMILAR TO supports these pattern-matching + metacharacters borrowed from POSIX regular expressions: + + + + + | denotes alternation (either of two alternatives). + + + + + * denotes repetition of the previous item zero + or more times. + + + + + + denotes repetition of the previous item one + or more times. + + + + + ? denotes repetition of the previous item zero + or one time. + + + + + {m} denotes repetition + of the previous item exactly m times. + + + + + {m,} denotes repetition + of the previous item m or more times. + + + + + {m,n} + denotes repetition of the previous item at least m and + not more than n times. + + + + + Parentheses () can be used to group items into + a single logical item. + + + + + A bracket expression [...] specifies a character + class, just as in POSIX regular expressions. + + + + + Notice that the period (.) is not a metacharacter + for SIMILAR TO. + + + + As with LIKE, a backslash disables the special + meaning of any of these metacharacters. A different escape character + can be specified with ESCAPE, or the escape + capability can be disabled by writing ESCAPE ''. + + + + According to the SQL standard, omitting ESCAPE + means there is no escape character (rather than defaulting to a + backslash), and a zero-length ESCAPE value is + disallowed. PostgreSQL's behavior in + this regard is therefore slightly nonstandard. + + + + Another nonstandard extension is that following the escape character + with a letter or digit provides access to the escape sequences + defined for POSIX regular expressions; see + , + , and + below. + + + + Some examples: + +'abc' SIMILAR TO 'abc' true +'abc' SIMILAR TO 'a' false +'abc' SIMILAR TO '%(b|d)%' true +'abc' SIMILAR TO '(b|c)%' false +'-abc-' SIMILAR TO '%\mabc\M%' true +'xabcy' SIMILAR TO '%\mabc\M%' false + + + + + The substring function with three parameters + provides extraction of a substring that matches an SQL + regular expression pattern. The function can be written according + to standard SQL syntax: + +substring(string similar pattern escape escape-character) + + or using the now obsolete SQL:1999 syntax: + +substring(string from pattern for escape-character) + + or as a plain three-argument function: + +substring(string, pattern, escape-character) + + As with SIMILAR TO, the + specified pattern must match the entire data string, or else the + function fails and returns null. To indicate the part of the + pattern for which the matching data sub-string is of interest, + the pattern should contain + two occurrences of the escape character followed by a double quote + ("). + The text matching the portion of the pattern + between these separators is returned when the match is successful. + + + + The escape-double-quote separators actually + divide substring's pattern into three independent + regular expressions; for example, a vertical bar (|) + in any of the three sections affects only that section. Also, the first + and third of these regular expressions are defined to match the smallest + possible amount of text, not the largest, when there is any ambiguity + about how much of the data string matches which pattern. (In POSIX + parlance, the first and third regular expressions are forced to be + non-greedy.) + + + + As an extension to the SQL standard, PostgreSQL + allows there to be just one escape-double-quote separator, in which case + the third regular expression is taken as empty; or no separators, in which + case the first and third regular expressions are taken as empty. + + + + Some examples, with #" delimiting the return string: + +substring('foobar' similar '%#"o_b#"%' escape '#') oob +substring('foobar' similar '#"o_b#"%' escape '#') NULL + + + + + + <acronym>POSIX</acronym> Regular Expressions + + + regular expression + pattern matching + + + substring + + + regexp_replace + + + regexp_match + + + regexp_matches + + + regexp_split_to_table + + + regexp_split_to_array + + + + lists the available + operators for pattern matching using POSIX regular expressions. + + + + Regular Expression Match Operators + + + + + + Operator + + + Description + + + Example(s) + + + + + + + + text ~ text + boolean + + + String matches regular expression, case sensitively + + + 'thomas' ~ 't.*ma' + t + + + + + + text ~* text + boolean + + + String matches regular expression, case insensitively + + + 'thomas' ~* 'T.*ma' + t + + + + + + text !~ text + boolean + + + String does not match regular expression, case sensitively + + + 'thomas' !~ 't.*max' + t + + + + + + text !~* text + boolean + + + String does not match regular expression, case insensitively + + + 'thomas' !~* 'T.*ma' + f + + + + +
+ + + POSIX regular expressions provide a more + powerful means for pattern matching than the LIKE and + SIMILAR TO operators. + Many Unix tools such as egrep, + sed, or awk use a pattern + matching language that is similar to the one described here. + + + + A regular expression is a character sequence that is an + abbreviated definition of a set of strings (a regular + set). A string is said to match a regular expression + if it is a member of the regular set described by the regular + expression. As with LIKE, pattern characters + match string characters exactly unless they are special characters + in the regular expression language — but regular expressions use + different special characters than LIKE does. + Unlike LIKE patterns, a + regular expression is allowed to match anywhere within a string, unless + the regular expression is explicitly anchored to the beginning or + end of the string. + + + + Some examples: + +'abcd' ~ 'bc' true +'abcd' ~ 'a.c' true — dot matches any character +'abcd' ~ 'a.*d' true — * repeats the preceding pattern item +'abcd' ~ '(b|x)' true — | means OR, parentheses group +'abcd' ~ '^a' true — ^ anchors to start of string +'abcd' ~ '^(b|c)' false — would match except for anchoring + + + + + The POSIX pattern language is described in much + greater detail below. + + + + The substring function with two parameters, + substring(string from + pattern), provides extraction of a + substring + that matches a POSIX regular expression pattern. It returns null if + there is no match, otherwise the portion of the text that matched the + pattern. But if the pattern contains any parentheses, the portion + of the text that matched the first parenthesized subexpression (the + one whose left parenthesis comes first) is + returned. You can put parentheses around the whole expression + if you want to use parentheses within it without triggering this + exception. If you need parentheses in the pattern before the + subexpression you want to extract, see the non-capturing parentheses + described below. + + + + Some examples: + +substring('foobar' from 'o.b') oob +substring('foobar' from 'o(.)b') o + + + + + The regexp_replace function provides substitution of + new text for substrings that match POSIX regular expression patterns. + It has the syntax + regexp_replace(source, + pattern, replacement + , flags ). + The source string is returned unchanged if + there is no match to the pattern. If there is a + match, the source string is returned with the + replacement string substituted for the matching + substring. The replacement string can contain + \n, where n is 1 + through 9, to indicate that the source substring matching the + n'th parenthesized subexpression of the pattern should be + inserted, and it can contain \& to indicate that the + substring matching the entire pattern should be inserted. Write + \\ if you need to put a literal backslash in the replacement + text. + The flags parameter is an optional text + string containing zero or more single-letter flags that change the + function's behavior. Flag i specifies case-insensitive + matching, while flag g specifies replacement of each matching + substring rather than only the first one. Supported flags (though + not g) are + described in . + + + + Some examples: + +regexp_replace('foobarbaz', 'b..', 'X') + fooXbaz +regexp_replace('foobarbaz', 'b..', 'X', 'g') + fooXX +regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') + fooXarYXazY + + + + + The regexp_match function returns a text array of + captured substring(s) resulting from the first match of a POSIX + regular expression pattern to a string. It has the syntax + regexp_match(string, + pattern , flags ). + If there is no match, the result is NULL. + If a match is found, and the pattern contains no + parenthesized subexpressions, then the result is a single-element text + array containing the substring matching the whole pattern. + If a match is found, and the pattern contains + parenthesized subexpressions, then the result is a text array + whose n'th element is the substring matching + the n'th parenthesized subexpression of + the pattern (not counting non-capturing + parentheses; see below for details). + The flags parameter is an optional text string + containing zero or more single-letter flags that change the function's + behavior. Supported flags are described + in . + + + + Some examples: + +SELECT regexp_match('foobarbequebaz', 'bar.*que'); + regexp_match +-------------- + {barbeque} +(1 row) + +SELECT regexp_match('foobarbequebaz', '(bar)(beque)'); + regexp_match +-------------- + {bar,beque} +(1 row) + + In the common case where you just want the whole matching substring + or NULL for no match, write something like + +SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1]; + regexp_match +-------------- + barbeque +(1 row) + + + + + The regexp_matches function returns a set of text arrays + of captured substring(s) resulting from matching a POSIX regular + expression pattern to a string. It has the same syntax as + regexp_match. + This function returns no rows if there is no match, one row if there is + a match and the g flag is not given, or N + rows if there are N matches and the g flag + is given. Each returned row is a text array containing the whole + matched substring or the substrings matching parenthesized + subexpressions of the pattern, just as described above + for regexp_match. + regexp_matches accepts all the flags shown + in , plus + the g flag which commands it to return all matches, not + just the first one. + + + + Some examples: + +SELECT regexp_matches('foo', 'not there'); + regexp_matches +---------------- +(0 rows) + +SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g'); + regexp_matches +---------------- + {bar,beque} + {bazil,barf} +(2 rows) + + + + + + In most cases regexp_matches() should be used with + the g flag, since if you only want the first match, it's + easier and more efficient to use regexp_match(). + However, regexp_match() only exists + in PostgreSQL version 10 and up. When working in older + versions, a common trick is to place a regexp_matches() + call in a sub-select, for example: + +SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; + + This produces a text array if there's a match, or NULL if + not, the same as regexp_match() would do. Without the + sub-select, this query would produce no output at all for table rows + without a match, which is typically not the desired behavior. + + + + + The regexp_split_to_table function splits a string using a POSIX + regular expression pattern as a delimiter. It has the syntax + regexp_split_to_table(string, pattern + , flags ). + If there is no match to the pattern, the function returns the + string. If there is at least one match, for each match it returns + the text from the end of the last match (or the beginning of the string) + to the beginning of the match. When there are no more matches, it + returns the text from the end of the last match to the end of the string. + The flags parameter is an optional text string containing + zero or more single-letter flags that change the function's behavior. + regexp_split_to_table supports the flags described in + . + + + + The regexp_split_to_array function behaves the same as + regexp_split_to_table, except that regexp_split_to_array + returns its result as an array of text. It has the syntax + regexp_split_to_array(string, pattern + , flags ). + The parameters are the same as for regexp_split_to_table. + + + + Some examples: + + +SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo; + foo +------- + the + quick + brown + fox + jumps + over + the + lazy + dog +(9 rows) + +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+'); + regexp_split_to_array +----------------------------------------------- + {the,quick,brown,fox,jumps,over,the,lazy,dog} +(1 row) + +SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; + foo +----- + t + h + e + q + u + i + c + k + b + r + o + w + n + f + o + x +(16 rows) + + + + + As the last example demonstrates, the regexp split functions ignore + zero-length matches that occur at the start or end of the string + or immediately after a previous match. This is contrary to the strict + definition of regexp matching that is implemented by + regexp_match and + regexp_matches, but is usually the most convenient behavior + in practice. Other software systems such as Perl use similar definitions. + + + + + + Regular Expression Details + + + PostgreSQL's regular expressions are implemented + using a software package written by Henry Spencer. Much of + the description of regular expressions below is copied verbatim from his + manual. + + + + Regular expressions (REs), as defined in + POSIX 1003.2, come in two forms: + extended REs or EREs + (roughly those of egrep), and + basic REs or BREs + (roughly those of ed). + PostgreSQL supports both forms, and + also implements some extensions + that are not in the POSIX standard, but have become widely used + due to their availability in programming languages such as Perl and Tcl. + REs using these non-POSIX extensions are called + advanced REs or AREs + in this documentation. AREs are almost an exact superset of EREs, + but BREs have several notational incompatibilities (as well as being + much more limited). + We first describe the ARE and ERE forms, noting features that apply + only to AREs, and then describe how BREs differ. + + + + + PostgreSQL always initially presumes that a regular + expression follows the ARE rules. However, the more limited ERE or + BRE rules can be chosen by prepending an embedded option + to the RE pattern, as described in . + This can be useful for compatibility with applications that expect + exactly the POSIX 1003.2 rules. + + + + + A regular expression is defined as one or more + branches, separated by + |. It matches anything that matches one of the + branches. + + + + A branch is zero or more quantified atoms or + constraints, concatenated. + It matches a match for the first, followed by a match for the second, etc; + an empty branch matches the empty string. + + + + A quantified atom is an atom possibly followed + by a single quantifier. + Without a quantifier, it matches a match for the atom. + With a quantifier, it can match some number of matches of the atom. + An atom can be any of the possibilities + shown in . + The possible quantifiers and their meanings are shown in + . + + + + A constraint matches an empty string, but matches only when + specific conditions are met. A constraint can be used where an atom + could be used, except it cannot be followed by a quantifier. + The simple constraints are shown in + ; + some more constraints are described later. + + + + + Regular Expression Atoms + + + + + Atom + Description + + + + + + (re) + (where re is any regular expression) + matches a match for + re, with the match noted for possible reporting + + + + (?:re) + as above, but the match is not noted for reporting + (a non-capturing set of parentheses) + (AREs only) + + + + . + matches any single character + + + + [chars] + a bracket expression, + matching any one of the chars (see + for more detail) + + + + \k + (where k is a non-alphanumeric character) + matches that character taken as an ordinary character, + e.g., \\ matches a backslash character + + + + \c + where c is alphanumeric + (possibly followed by other characters) + is an escape, see + (AREs only; in EREs and BREs, this matches c) + + + + { + when followed by a character other than a digit, + matches the left-brace character {; + when followed by a digit, it is the beginning of a + bound (see below) + + + + x + where x is a single character with no other + significance, matches that character + + + +
+ + + An RE cannot end with a backslash (\). + + + + + If you have turned off, + any backslashes you write in literal string constants will need to be + doubled. See for more information. + + + + + Regular Expression Quantifiers + + + + + Quantifier + Matches + + + + + + * + a sequence of 0 or more matches of the atom + + + + + + a sequence of 1 or more matches of the atom + + + + ? + a sequence of 0 or 1 matches of the atom + + + + {m} + a sequence of exactly m matches of the atom + + + + {m,} + a sequence of m or more matches of the atom + + + + + {m,n} + a sequence of m through n + (inclusive) matches of the atom; m cannot exceed + n + + + + *? + non-greedy version of * + + + + +? + non-greedy version of + + + + + ?? + non-greedy version of ? + + + + {m}? + non-greedy version of {m} + + + + {m,}? + non-greedy version of {m,} + + + + + {m,n}? + non-greedy version of {m,n} + + + +
+ + + The forms using {...} + are known as bounds. + The numbers m and n within a bound are + unsigned decimal integers with permissible values from 0 to 255 inclusive. + + + + Non-greedy quantifiers (available in AREs only) match the + same possibilities as their corresponding normal (greedy) + counterparts, but prefer the smallest number rather than the largest + number of matches. + See for more detail. + + + + + A quantifier cannot immediately follow another quantifier, e.g., + ** is invalid. + A quantifier cannot + begin an expression or subexpression or follow + ^ or |. + + + + + Regular Expression Constraints + + + + + Constraint + Description + + + + + + ^ + matches at the beginning of the string + + + + $ + matches at the end of the string + + + + (?=re) + positive lookahead matches at any point + where a substring matching re begins + (AREs only) + + + + (?!re) + negative lookahead matches at any point + where no substring matching re begins + (AREs only) + + + + (?<=re) + positive lookbehind matches at any point + where a substring matching re ends + (AREs only) + + + + (?<!re) + negative lookbehind matches at any point + where no substring matching re ends + (AREs only) + + + +
+ + + Lookahead and lookbehind constraints cannot contain back + references (see ), + and all parentheses within them are considered non-capturing. + +
+ + + Bracket Expressions + + + A bracket expression is a list of + characters enclosed in []. It normally matches + any single character from the list (but see below). If the list + begins with ^, it matches any single character + not from the rest of the list. + If two characters + in the list are separated by -, this is + shorthand for the full range of characters between those two + (inclusive) in the collating sequence, + e.g., [0-9] in ASCII matches + any decimal digit. It is illegal for two ranges to share an + endpoint, e.g., a-c-e. Ranges are very + collating-sequence-dependent, so portable programs should avoid + relying on them. + + + + To include a literal ] in the list, make it the + first character (after ^, if that is used). To + include a literal -, make it the first or last + character, or the second endpoint of a range. To use a literal + - as the first endpoint of a range, enclose it + in [. and .] to make it a + collating element (see below). With the exception of these characters, + some combinations using [ + (see next paragraphs), and escapes (AREs only), all other special + characters lose their special significance within a bracket expression. + In particular, \ is not special when following + ERE or BRE rules, though it is special (as introducing an escape) + in AREs. + + + + Within a bracket expression, a collating element (a character, a + multiple-character sequence that collates as if it were a single + character, or a collating-sequence name for either) enclosed in + [. and .] stands for the + sequence of characters of that collating element. The sequence is + treated as a single element of the bracket expression's list. This + allows a bracket + expression containing a multiple-character collating element to + match more than one character, e.g., if the collating sequence + includes a ch collating element, then the RE + [[.ch.]]*c matches the first five characters of + chchcc. + + + + + PostgreSQL currently does not support multi-character collating + elements. This information describes possible future behavior. + + + + + Within a bracket expression, a collating element enclosed in + [= and =] is an equivalence + class, standing for the sequences of characters of all collating + elements equivalent to that one, including itself. (If there are + no other equivalent collating elements, the treatment is as if the + enclosing delimiters were [. and + .].) For example, if o and + ^ are the members of an equivalence class, then + [[=o=]], [[=^=]], and + [o^] are all synonymous. An equivalence class + cannot be an endpoint of a range. + + + + Within a bracket expression, the name of a character class + enclosed in [: and :] stands + for the list of all characters belonging to that class. A character + class cannot be used as an endpoint of a range. + The POSIX standard defines these character class + names: + alnum (letters and numeric digits), + alpha (letters), + blank (space and tab), + cntrl (control characters), + digit (numeric digits), + graph (printable characters except space), + lower (lower-case letters), + print (printable characters including space), + punct (punctuation), + space (any white space), + upper (upper-case letters), + and xdigit (hexadecimal digits). + The behavior of these standard character classes is generally + consistent across platforms for characters in the 7-bit ASCII set. + Whether a given non-ASCII character is considered to belong to one + of these classes depends on the collation + that is used for the regular-expression function or operator + (see ), or by default on the + database's LC_CTYPE locale setting (see + ). The classification of non-ASCII + characters can vary across platforms even in similarly-named + locales. (But the C locale never considers any + non-ASCII characters to belong to any of these classes.) + In addition to these standard character + classes, PostgreSQL defines + the word character class, which is the same as + alnum plus the underscore (_) + character, and + the ascii character class, which contains exactly + the 7-bit ASCII set. + + + + There are two special cases of bracket expressions: the bracket + expressions [[:<:]] and + [[:>:]] are constraints, + matching empty strings at the beginning + and end of a word respectively. A word is defined as a sequence + of word characters that is neither preceded nor followed by word + characters. A word character is any character belonging to the + word character class, that is, any letter, digit, + or underscore. This is an extension, compatible with but not + specified by POSIX 1003.2, and should be used with + caution in software intended to be portable to other systems. + The constraint escapes described below are usually preferable; they + are no more standard, but are easier to type. + + + + + Regular Expression Escapes + + + Escapes are special sequences beginning with \ + followed by an alphanumeric character. Escapes come in several varieties: + character entry, class shorthands, constraint escapes, and back references. + A \ followed by an alphanumeric character but not constituting + a valid escape is illegal in AREs. + In EREs, there are no escapes: outside a bracket expression, + a \ followed by an alphanumeric character merely stands for + that character as an ordinary character, and inside a bracket expression, + \ is an ordinary character. + (The latter is the one actual incompatibility between EREs and AREs.) + + + + Character-entry escapes exist to make it easier to specify + non-printing and other inconvenient characters in REs. They are + shown in . + + + + Class-shorthand escapes provide shorthands for certain + commonly-used character classes. They are + shown in . + + + + A constraint escape is a constraint, + matching the empty string if specific conditions are met, + written as an escape. They are + shown in . + + + + A back reference (\n) matches the + same string matched by the previous parenthesized subexpression specified + by the number n + (see ). For example, + ([bc])\1 matches bb or cc + but not bc or cb. + The subexpression must entirely precede the back reference in the RE. + Subexpressions are numbered in the order of their leading parentheses. + Non-capturing parentheses do not define subexpressions. + The back reference considers only the string characters matched by the + referenced subexpression, not any constraints contained in it. For + example, (^\d)\1 will match 22. + + + + Regular Expression Character-Entry Escapes + + + + + Escape + Description + + + + + + \a + alert (bell) character, as in C + + + + \b + backspace, as in C + + + + \B + synonym for backslash (\) to help reduce the need for backslash + doubling + + + + \cX + (where X is any character) the character whose + low-order 5 bits are the same as those of + X, and whose other bits are all zero + + + + \e + the character whose collating-sequence name + is ESC, + or failing that, the character with octal value 033 + + + + \f + form feed, as in C + + + + \n + newline, as in C + + + + \r + carriage return, as in C + + + + \t + horizontal tab, as in C + + + + \uwxyz + (where wxyz is exactly four hexadecimal digits) + the character whose hexadecimal value is + 0xwxyz + + + + + \Ustuvwxyz + (where stuvwxyz is exactly eight hexadecimal + digits) + the character whose hexadecimal value is + 0xstuvwxyz + + + + + \v + vertical tab, as in C + + + + \xhhh + (where hhh is any sequence of hexadecimal + digits) + the character whose hexadecimal value is + 0xhhh + (a single character no matter how many hexadecimal digits are used) + + + + + \0 + the character whose value is 0 (the null byte) + + + + \xy + (where xy is exactly two octal digits, + and is not a back reference) + the character whose octal value is + 0xy + + + + \xyz + (where xyz is exactly three octal digits, + and is not a back reference) + the character whose octal value is + 0xyz + + + +
+ + + Hexadecimal digits are 0-9, + a-f, and A-F. + Octal digits are 0-7. + + + + Numeric character-entry escapes specifying values outside the ASCII range + (0–127) have meanings dependent on the database encoding. When the + encoding is UTF-8, escape values are equivalent to Unicode code points, + for example \u1234 means the character U+1234. + For other multibyte encodings, character-entry escapes usually just + specify the concatenation of the byte values for the character. If the + escape value does not correspond to any legal character in the database + encoding, no error will be raised, but it will never match any data. + + + + The character-entry escapes are always taken as ordinary characters. + For example, \135 is ] in ASCII, but + \135 does not terminate a bracket expression. + + + + Regular Expression Class-Shorthand Escapes + + + + + Escape + Description + + + + + + \d + matches any digit, like + [[:digit:]] + + + + \s + matches any whitespace character, like + [[:space:]] + + + + \w + matches any word character, like + [[:word:]] + + + + \D + matches any non-digit, like + [^[:digit:]] + + + + \S + matches any non-whitespace character, like + [^[:space:]] + + + + \W + matches any non-word character, like + [^[:word:]] + + + +
+ + + The class-shorthand escapes also work within bracket expressions, + although the definitions shown above are not quite syntactically + valid in that context. + For example, [a-c\d] is equivalent to + [a-c[:digit:]]. + + + + Regular Expression Constraint Escapes + + + + + Escape + Description + + + + + + \A + matches only at the beginning of the string + (see for how this differs from + ^) + + + + \m + matches only at the beginning of a word + + + + \M + matches only at the end of a word + + + + \y + matches only at the beginning or end of a word + + + + \Y + matches only at a point that is not the beginning or end of a + word + + + + \Z + matches only at the end of the string + (see for how this differs from + $) + + + +
+ + + A word is defined as in the specification of + [[:<:]] and [[:>:]] above. + Constraint escapes are illegal within bracket expressions. + + + + Regular Expression Back References + + + + + Escape + Description + + + + + + \m + (where m is a nonzero digit) + a back reference to the m'th subexpression + + + + \mnn + (where m is a nonzero digit, and + nn is some more digits, and the decimal value + mnn is not greater than the number of closing capturing + parentheses seen so far) + a back reference to the mnn'th subexpression + + + +
+ + + + There is an inherent ambiguity between octal character-entry + escapes and back references, which is resolved by the following heuristics, + as hinted at above. + A leading zero always indicates an octal escape. + A single non-zero digit, not followed by another digit, + is always taken as a back reference. + A multi-digit sequence not starting with a zero is taken as a back + reference if it comes after a suitable subexpression + (i.e., the number is in the legal range for a back reference), + and otherwise is taken as octal. + + +
+ + + Regular Expression Metasyntax + + + In addition to the main syntax described above, there are some special + forms and miscellaneous syntactic facilities available. + + + + An RE can begin with one of two special director prefixes. + If an RE begins with ***:, + the rest of the RE is taken as an ARE. (This normally has no effect in + PostgreSQL, since REs are assumed to be AREs; + but it does have an effect if ERE or BRE mode had been specified by + the flags parameter to a regex function.) + If an RE begins with ***=, + the rest of the RE is taken to be a literal string, + with all characters considered ordinary characters. + + + + An ARE can begin with embedded options: + a sequence (?xyz) + (where xyz is one or more alphabetic characters) + specifies options affecting the rest of the RE. + These options override any previously determined options — + in particular, they can override the case-sensitivity behavior implied by + a regex operator, or the flags parameter to a regex + function. + The available option letters are + shown in . + Note that these same option letters are used in the flags + parameters of regex functions. + + + + ARE Embedded-Option Letters + + + + + Option + Description + + + + + + b + rest of RE is a BRE + + + + c + case-sensitive matching (overrides operator type) + + + + e + rest of RE is an ERE + + + + i + case-insensitive matching (see + ) (overrides operator type) + + + + m + historical synonym for n + + + + n + newline-sensitive matching (see + ) + + + + p + partial newline-sensitive matching (see + ) + + + + q + rest of RE is a literal (quoted) string, all ordinary + characters + + + + s + non-newline-sensitive matching (default) + + + + t + tight syntax (default; see below) + + + + w + inverse partial newline-sensitive (weird) matching + (see ) + + + + x + expanded syntax (see below) + + + +
+ + + Embedded options take effect at the ) terminating the sequence. + They can appear only at the start of an ARE (after the + ***: director if any). + + + + In addition to the usual (tight) RE syntax, in which all + characters are significant, there is an expanded syntax, + available by specifying the embedded x option. + In the expanded syntax, + white-space characters in the RE are ignored, as are + all characters between a # + and the following newline (or the end of the RE). This + permits paragraphing and commenting a complex RE. + There are three exceptions to that basic rule: + + + + + a white-space character or # preceded by \ is + retained + + + + + white space or # within a bracket expression is retained + + + + + white space and comments cannot appear within multi-character symbols, + such as (?: + + + + + For this purpose, white-space characters are blank, tab, newline, and + any character that belongs to the space character class. + + + + Finally, in an ARE, outside bracket expressions, the sequence + (?#ttt) + (where ttt is any text not containing a )) + is a comment, completely ignored. + Again, this is not allowed between the characters of + multi-character symbols, like (?:. + Such comments are more a historical artifact than a useful facility, + and their use is deprecated; use the expanded syntax instead. + + + + None of these metasyntax extensions is available if + an initial ***= director + has specified that the user's input be treated as a literal string + rather than as an RE. + +
+ + + Regular Expression Matching Rules + + + In the event that an RE could match more than one substring of a given + string, the RE matches the one starting earliest in the string. + If the RE could match more than one substring starting at that point, + either the longest possible match or the shortest possible match will + be taken, depending on whether the RE is greedy or + non-greedy. + + + + Whether an RE is greedy or not is determined by the following rules: + + + + Most atoms, and all constraints, have no greediness attribute (because + they cannot match variable amounts of text anyway). + + + + + Adding parentheses around an RE does not change its greediness. + + + + + A quantified atom with a fixed-repetition quantifier + ({m} + or + {m}?) + has the same greediness (possibly none) as the atom itself. + + + + + A quantified atom with other normal quantifiers (including + {m,n} + with m equal to n) + is greedy (prefers longest match). + + + + + A quantified atom with a non-greedy quantifier (including + {m,n}? + with m equal to n) + is non-greedy (prefers shortest match). + + + + + A branch — that is, an RE that has no top-level + | operator — has the same greediness as the first + quantified atom in it that has a greediness attribute. + + + + + An RE consisting of two or more branches connected by the + | operator is always greedy. + + + + + + + The above rules associate greediness attributes not only with individual + quantified atoms, but with branches and entire REs that contain quantified + atoms. What that means is that the matching is done in such a way that + the branch, or whole RE, matches the longest or shortest possible + substring as a whole. Once the length of the entire match + is determined, the part of it that matches any particular subexpression + is determined on the basis of the greediness attribute of that + subexpression, with subexpressions starting earlier in the RE taking + priority over ones starting later. + + + + An example of what this means: + +SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})'); +Result: 123 +SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})'); +Result: 1 + + In the first case, the RE as a whole is greedy because Y* + is greedy. It can match beginning at the Y, and it matches + the longest possible string starting there, i.e., Y123. + The output is the parenthesized part of that, or 123. + In the second case, the RE as a whole is non-greedy because Y*? + is non-greedy. It can match beginning at the Y, and it matches + the shortest possible string starting there, i.e., Y1. + The subexpression [0-9]{1,3} is greedy but it cannot change + the decision as to the overall match length; so it is forced to match + just 1. + + + + In short, when an RE contains both greedy and non-greedy subexpressions, + the total match length is either as long as possible or as short as + possible, according to the attribute assigned to the whole RE. The + attributes assigned to the subexpressions only affect how much of that + match they are allowed to eat relative to each other. + + + + The quantifiers {1,1} and {1,1}? + can be used to force greediness or non-greediness, respectively, + on a subexpression or a whole RE. + This is useful when you need the whole RE to have a greediness attribute + different from what's deduced from its elements. As an example, + suppose that we are trying to separate a string containing some digits + into the digits and the parts before and after them. We might try to + do that like this: + +SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)'); +Result: {abc0123,4,xyz} + + That didn't work: the first .* is greedy so + it eats as much as it can, leaving the \d+ to + match at the last possible place, the last digit. We might try to fix + that by making it non-greedy: + +SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)'); +Result: {abc,0,""} + + That didn't work either, because now the RE as a whole is non-greedy + and so it ends the overall match as soon as possible. We can get what + we want by forcing the RE as a whole to be greedy: + +SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); +Result: {abc,01234,xyz} + + Controlling the RE's overall greediness separately from its components' + greediness allows great flexibility in handling variable-length patterns. + + + + When deciding what is a longer or shorter match, + match lengths are measured in characters, not collating elements. + An empty string is considered longer than no match at all. + For example: + bb* + matches the three middle characters of abbbc; + (week|wee)(night|knights) + matches all ten characters of weeknights; + when (.*).* + is matched against abc the parenthesized subexpression + matches all three characters; and when + (a*)* is matched against bc + both the whole RE and the parenthesized + subexpression match an empty string. + + + + If case-independent matching is specified, + the effect is much as if all case distinctions had vanished from the + alphabet. + When an alphabetic that exists in multiple cases appears as an + ordinary character outside a bracket expression, it is effectively + transformed into a bracket expression containing both cases, + e.g., x becomes [xX]. + When it appears inside a bracket expression, all case counterparts + of it are added to the bracket expression, e.g., + [x] becomes [xX] + and [^x] becomes [^xX]. + + + + If newline-sensitive matching is specified, . + and bracket expressions using ^ + will never match the newline character + (so that matches will not cross lines unless the RE + explicitly includes a newline) + and ^ and $ + will match the empty string after and before a newline + respectively, in addition to matching at beginning and end of string + respectively. + But the ARE escapes \A and \Z + continue to match beginning or end of string only. + Also, the character class shorthands \D + and \W will match a newline regardless of this mode. + (Before PostgreSQL 14, they did not match + newlines when in newline-sensitive mode. + Write [^[:digit:]] + or [^[:word:]] to get the old behavior.) + + + + If partial newline-sensitive matching is specified, + this affects . and bracket expressions + as with newline-sensitive matching, but not ^ + and $. + + + + If inverse partial newline-sensitive matching is specified, + this affects ^ and $ + as with newline-sensitive matching, but not . + and bracket expressions. + This isn't very useful but is provided for symmetry. + + + + + Limits and Compatibility + + + No particular limit is imposed on the length of REs in this + implementation. However, + programs intended to be highly portable should not employ REs longer + than 256 bytes, + as a POSIX-compliant implementation can refuse to accept such REs. + + + + The only feature of AREs that is actually incompatible with + POSIX EREs is that \ does not lose its special + significance inside bracket expressions. + All other ARE features use syntax which is illegal or has + undefined or unspecified effects in POSIX EREs; + the *** syntax of directors likewise is outside the POSIX + syntax for both BREs and EREs. + + + + Many of the ARE extensions are borrowed from Perl, but some have + been changed to clean them up, and a few Perl extensions are not present. + Incompatibilities of note include \b, \B, + the lack of special treatment for a trailing newline, + the addition of complemented bracket expressions to the things + affected by newline-sensitive matching, + the restrictions on parentheses and back references in lookahead/lookbehind + constraints, and the longest/shortest-match (rather than first-match) + matching semantics. + + + + + Basic Regular Expressions + + + BREs differ from EREs in several respects. + In BREs, |, +, and ? + are ordinary characters and there is no equivalent + for their functionality. + The delimiters for bounds are + \{ and \}, + with { and } + by themselves ordinary characters. + The parentheses for nested subexpressions are + \( and \), + with ( and ) by themselves ordinary characters. + ^ is an ordinary character except at the beginning of the + RE or the beginning of a parenthesized subexpression, + $ is an ordinary character except at the end of the + RE or the end of a parenthesized subexpression, + and * is an ordinary character if it appears at the beginning + of the RE or the beginning of a parenthesized subexpression + (after a possible leading ^). + Finally, single-digit back references are available, and + \< and \> + are synonyms for + [[:<:]] and [[:>:]] + respectively; no other escapes are available in BREs. + + + + + + + Differences from XQuery (<literal>LIKE_REGEX</literal>) + + + LIKE_REGEX + + + + XQuery regular expressions + + + + Since SQL:2008, the SQL standard includes + a LIKE_REGEX operator that performs pattern + matching according to the XQuery regular expression + standard. PostgreSQL does not yet + implement this operator, but you can get very similar behavior using + the regexp_match() function, since XQuery + regular expressions are quite close to the ARE syntax described above. + + + + Notable differences between the existing POSIX-based + regular-expression feature and XQuery regular expressions include: + + + + + XQuery character class subtraction is not supported. An example of + this feature is using the following to match only English + consonants: [a-z-[aeiou]]. + + + + + XQuery character class shorthands \c, + \C, \i, + and \I are not supported. + + + + + XQuery character class elements + using \p{UnicodeProperty} or the + inverse \P{UnicodeProperty} are not supported. + + + + + POSIX interprets character classes such as \w + (see ) + according to the prevailing locale (which you can control by + attaching a COLLATE clause to the operator or + function). XQuery specifies these classes by reference to Unicode + character properties, so equivalent behavior is obtained only with + a locale that follows the Unicode rules. + + + + + The SQL standard (not XQuery itself) attempts to cater for more + variants of newline than POSIX does. The + newline-sensitive matching options described above consider only + ASCII NL (\n) to be a newline, but SQL would have + us treat CR (\r), CRLF (\r\n) + (a Windows-style newline), and some Unicode-only characters like + LINE SEPARATOR (U+2028) as newlines as well. + Notably, . and \s should + count \r\n as one character not two according to + SQL. + + + + + Of the character-entry escapes described in + , + XQuery supports only \n, \r, + and \t. + + + + + XQuery does not support + the [:name:] syntax + for character classes within bracket expressions. + + + + + XQuery does not have lookahead or lookbehind constraints, + nor any of the constraint escapes described in + . + + + + + The metasyntax forms described in + do not exist in XQuery. + + + + + The regular expression flag letters defined by XQuery are + related to but not the same as the option letters for POSIX + (). While the + i and q options behave the + same, others do not: + + + + XQuery's s (allow dot to match newline) + and m (allow ^ + and $ to match at newlines) flags provide + access to the same behaviors as + POSIX's n, p + and w flags, but they + do not match the behavior of + POSIX's s and m flags. + Note in particular that dot-matches-newline is the default + behavior in POSIX but not XQuery. + + + + + XQuery's x (ignore whitespace in pattern) flag + is noticeably different from POSIX's expanded-mode flag. + POSIX's x flag also + allows # to begin a comment in the pattern, + and POSIX will not ignore a whitespace character after a + backslash. + + + + + + + + + +
+
+ + + + Data Type Formatting Functions + + + formatting + + + + The PostgreSQL formatting functions + provide a powerful set of tools for converting various data types + (date/time, integer, floating point, numeric) to formatted strings + and for converting from formatted strings to specific data types. + lists them. + These functions all follow a common calling convention: the first + argument is the value to be formatted and the second argument is a + template that defines the output or input format. + + + + Formatting Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + to_char + + to_char ( timestamp, text ) + text + + + to_char ( timestamp with time zone, text ) + text + + + Converts time stamp to string according to the given format. + + + to_char(timestamp '2002-04-20 17:31:12.66', 'HH12:MI:SS') + 05:31:12 + + + + + + to_char ( interval, text ) + text + + + Converts interval to string according to the given format. + + + to_char(interval '15h 2m 12s', 'HH24:MI:SS') + 15:02:12 + + + + + + to_char ( numeric_type, text ) + text + + + Converts number to string according to the given format; available + for integer, bigint, numeric, + real, double precision. + + + to_char(125, '999') + 125 + + + to_char(125.8::real, '999D9') + 125.8 + + + to_char(-125.8, '999D99S') + 125.80- + + + + + + + to_date + + to_date ( text, text ) + date + + + Converts string to date according to the given format. + + + to_date('05 Dec 2000', 'DD Mon YYYY') + 2000-12-05 + + + + + + + to_number + + to_number ( text, text ) + numeric + + + Converts string to numeric according to the given format. + + + to_number('12,454.8-', '99G999D9S') + -12454.8 + + + + + + + to_timestamp + + to_timestamp ( text, text ) + timestamp with time zone + + + Converts string to time stamp according to the given format. + (See also to_timestamp(double precision) in + .) + + + to_timestamp('05 Dec 2000', 'DD Mon YYYY') + 2000-12-05 00:00:00-05 + + + + +
+ + + + to_timestamp and to_date + exist to handle input formats that cannot be converted by + simple casting. For most standard date/time formats, simply casting the + source string to the required data type works, and is much easier. + Similarly, to_number is unnecessary for standard numeric + representations. + + + + + In a to_char output template string, there are certain + patterns that are recognized and replaced with appropriately-formatted + data based on the given value. Any text that is not a template pattern is + simply copied verbatim. Similarly, in an input template string (for the + other functions), template patterns identify the values to be supplied by + the input data string. If there are characters in the template string + that are not template patterns, the corresponding characters in the input + data string are simply skipped over (whether or not they are equal to the + template string characters). + + + + shows the + template patterns available for formatting date and time values. + + + + Template Patterns for Date/Time Formatting + + + + Pattern + Description + + + + + HH + hour of day (01–12) + + + HH12 + hour of day (01–12) + + + HH24 + hour of day (00–23) + + + MI + minute (00–59) + + + SS + second (00–59) + + + MS + millisecond (000–999) + + + US + microsecond (000000–999999) + + + FF1 + tenth of second (0–9) + + + FF2 + hundredth of second (00–99) + + + FF3 + millisecond (000–999) + + + FF4 + tenth of a millisecond (0000–9999) + + + FF5 + hundredth of a millisecond (00000–99999) + + + FF6 + microsecond (000000–999999) + + + SSSS, SSSSS + seconds past midnight (0–86399) + + + AM, am, + PM or pm + meridiem indicator (without periods) + + + A.M., a.m., + P.M. or p.m. + meridiem indicator (with periods) + + + Y,YYY + year (4 or more digits) with comma + + + YYYY + year (4 or more digits) + + + YYY + last 3 digits of year + + + YY + last 2 digits of year + + + Y + last digit of year + + + IYYY + ISO 8601 week-numbering year (4 or more digits) + + + IYY + last 3 digits of ISO 8601 week-numbering year + + + IY + last 2 digits of ISO 8601 week-numbering year + + + I + last digit of ISO 8601 week-numbering year + + + BC, bc, + AD or ad + era indicator (without periods) + + + B.C., b.c., + A.D. or a.d. + era indicator (with periods) + + + MONTH + full upper case month name (blank-padded to 9 chars) + + + Month + full capitalized month name (blank-padded to 9 chars) + + + month + full lower case month name (blank-padded to 9 chars) + + + MON + abbreviated upper case month name (3 chars in English, localized lengths vary) + + + Mon + abbreviated capitalized month name (3 chars in English, localized lengths vary) + + + mon + abbreviated lower case month name (3 chars in English, localized lengths vary) + + + MM + month number (01–12) + + + DAY + full upper case day name (blank-padded to 9 chars) + + + Day + full capitalized day name (blank-padded to 9 chars) + + + day + full lower case day name (blank-padded to 9 chars) + + + DY + abbreviated upper case day name (3 chars in English, localized lengths vary) + + + Dy + abbreviated capitalized day name (3 chars in English, localized lengths vary) + + + dy + abbreviated lower case day name (3 chars in English, localized lengths vary) + + + DDD + day of year (001–366) + + + IDDD + day of ISO 8601 week-numbering year (001–371; day 1 of the year is Monday of the first ISO week) + + + DD + day of month (01–31) + + + D + day of the week, Sunday (1) to Saturday (7) + + + ID + ISO 8601 day of the week, Monday (1) to Sunday (7) + + + W + week of month (1–5) (the first week starts on the first day of the month) + + + WW + week number of year (1–53) (the first week starts on the first day of the year) + + + IW + week number of ISO 8601 week-numbering year (01–53; the first Thursday of the year is in week 1) + + + CC + century (2 digits) (the twenty-first century starts on 2001-01-01) + + + J + Julian Date (integer days since November 24, 4714 BC at local + midnight; see ) + + + Q + quarter + + + RM + month in upper case Roman numerals (I–XII; I=January) + + + rm + month in lower case Roman numerals (i–xii; i=January) + + + TZ + upper case time-zone abbreviation + (only supported in to_char) + + + tz + lower case time-zone abbreviation + (only supported in to_char) + + + TZH + time-zone hours + + + TZM + time-zone minutes + + + OF + time-zone offset from UTC + (only supported in to_char) + + + +
+ + + Modifiers can be applied to any template pattern to alter its + behavior. For example, FMMonth + is the Month pattern with the + FM modifier. + shows the + modifier patterns for date/time formatting. + + + + Template Pattern Modifiers for Date/Time Formatting + + + + Modifier + Description + Example + + + + + FM prefix + fill mode (suppress leading zeroes and padding blanks) + FMMonth + + + TH suffix + upper case ordinal number suffix + DDTH, e.g., 12TH + + + th suffix + lower case ordinal number suffix + DDth, e.g., 12th + + + FX prefix + fixed format global option (see usage notes) + FX Month DD Day + + + TM prefix + translation mode (use localized day and month names based on + ) + TMMonth + + + SP suffix + spell mode (not implemented) + DDSP + + + +
+ + + Usage notes for date/time formatting: + + + + + FM suppresses leading zeroes and trailing blanks + that would otherwise be added to make the output of a pattern be + fixed-width. In PostgreSQL, + FM modifies only the next specification, while in + Oracle FM affects all subsequent + specifications, and repeated FM modifiers + toggle fill mode on and off. + + + + + + TM suppresses trailing blanks whether or + not FM is specified. + + + + + + to_timestamp and to_date + ignore letter case in the input; so for + example MON, Mon, + and mon all accept the same strings. When using + the TM modifier, case-folding is done according to + the rules of the function's input collation (see + ). + + + + + + to_timestamp and to_date + skip multiple blank spaces at the beginning of the input string and + around date and time values unless the FX option is used. For example, + to_timestamp(' 2000    JUN', 'YYYY MON') and + to_timestamp('2000 - JUN', 'YYYY-MON') work, but + to_timestamp('2000    JUN', 'FXYYYY MON') returns an error + because to_timestamp expects only a single space. + FX must be specified as the first item in + the template. + + + + + + A separator (a space or non-letter/non-digit character) in the template string of + to_timestamp and to_date + matches any single separator in the input string or is skipped, + unless the FX option is used. + For example, to_timestamp('2000JUN', 'YYYY///MON') and + to_timestamp('2000/JUN', 'YYYY MON') work, but + to_timestamp('2000//JUN', 'YYYY/MON') + returns an error because the number of separators in the input string + exceeds the number of separators in the template. + + + If FX is specified, a separator in the template string + matches exactly one character in the input string. But note that the + input string character is not required to be the same as the separator from the template string. + For example, to_timestamp('2000/JUN', 'FXYYYY MON') + works, but to_timestamp('2000/JUN', 'FXYYYY  MON') + returns an error because the second space in the template string consumes + the letter J from the input string. + + + + + + A TZH template pattern can match a signed number. + Without the FX option, minus signs may be ambiguous, + and could be interpreted as a separator. + This ambiguity is resolved as follows: If the number of separators before + TZH in the template string is less than the number of + separators before the minus sign in the input string, the minus sign + is interpreted as part of TZH. + Otherwise, the minus sign is considered to be a separator between values. + For example, to_timestamp('2000 -10', 'YYYY TZH') matches + -10 to TZH, but + to_timestamp('2000 -10', 'YYYY  TZH') + matches 10 to TZH. + + + + + + Ordinary text is allowed in to_char + templates and will be output literally. You can put a substring + in double quotes to force it to be interpreted as literal text + even if it contains template patterns. For example, in + '"Hello Year "YYYY', the YYYY + will be replaced by the year data, but the single Y in Year + will not be. + In to_date, to_number, + and to_timestamp, literal text and double-quoted + strings result in skipping the number of characters contained in the + string; for example "XX" skips two input characters + (whether or not they are XX). + + + + Prior to PostgreSQL 12, it was possible to + skip arbitrary text in the input string using non-letter or non-digit + characters. For example, + to_timestamp('2000y6m1d', 'yyyy-MM-DD') used to + work. Now you can only use letter characters for this purpose. For example, + to_timestamp('2000y6m1d', 'yyyytMMtDDt') and + to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"') + skip y, m, and + d. + + + + + + + If you want to have a double quote in the output you must + precede it with a backslash, for example '\"YYYY + Month\"'. + Backslashes are not otherwise special outside of double-quoted + strings. Within a double-quoted string, a backslash causes the + next character to be taken literally, whatever it is (but this + has no special effect unless the next character is a double quote + or another backslash). + + + + + + In to_timestamp and to_date, + if the year format specification is less than four digits, e.g., + YYY, and the supplied year is less than four digits, + the year will be adjusted to be nearest to the year 2020, e.g., + 95 becomes 1995. + + + + + + In to_timestamp and to_date, + negative years are treated as signifying BC. If you write both a + negative year and an explicit BC field, you get AD + again. An input of year zero is treated as 1 BC. + + + + + + In to_timestamp and to_date, + the YYYY conversion has a restriction when + processing years with more than 4 digits. You must + use some non-digit character or template after YYYY, + otherwise the year is always interpreted as 4 digits. For example + (with the year 20000): + to_date('200001131', 'YYYYMMDD') will be + interpreted as a 4-digit year; instead use a non-digit + separator after the year, like + to_date('20000-1131', 'YYYY-MMDD') or + to_date('20000Nov31', 'YYYYMonDD'). + + + + + + In to_timestamp and to_date, + the CC (century) field is accepted but ignored + if there is a YYY, YYYY or + Y,YYY field. If CC is used with + YY or Y then the result is + computed as that year in the specified century. If the century is + specified but the year is not, the first year of the century + is assumed. + + + + + + In to_timestamp and to_date, + weekday names or numbers (DAY, D, + and related field types) are accepted but are ignored for purposes of + computing the result. The same is true for quarter + (Q) fields. + + + + + + In to_timestamp and to_date, + an ISO 8601 week-numbering date (as distinct from a Gregorian date) + can be specified in one of two ways: + + + + Year, week number, and weekday: for + example to_date('2006-42-4', 'IYYY-IW-ID') + returns the date 2006-10-19. + If you omit the weekday it is assumed to be 1 (Monday). + + + + + Year and day of year: for example to_date('2006-291', + 'IYYY-IDDD') also returns 2006-10-19. + + + + + + Attempting to enter a date using a mixture of ISO 8601 week-numbering + fields and Gregorian date fields is nonsensical, and will cause an + error. In the context of an ISO 8601 week-numbering year, the + concept of a month or day of month has no + meaning. In the context of a Gregorian year, the ISO week has no + meaning. + + + + While to_date will reject a mixture of + Gregorian and ISO week-numbering date + fields, to_char will not, since output format + specifications like YYYY-MM-DD (IYYY-IDDD) can be + useful. But avoid writing something like IYYY-MM-DD; + that would yield surprising results near the start of the year. + (See for more + information.) + + + + + + + In to_timestamp, millisecond + (MS) or microsecond (US) + fields are used as the + seconds digits after the decimal point. For example + to_timestamp('12.3', 'SS.MS') is not 3 milliseconds, + but 300, because the conversion treats it as 12 + 0.3 seconds. + So, for the format SS.MS, the input values + 12.3, 12.30, + and 12.300 specify the + same number of milliseconds. To get three milliseconds, one must write + 12.003, which the conversion treats as + 12 + 0.003 = 12.003 seconds. + + + + Here is a more + complex example: + to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US') + is 15 hours, 12 minutes, and 2 seconds + 20 milliseconds + + 1230 microseconds = 2.021230 seconds. + + + + + + to_char(..., 'ID')'s day of the week numbering + matches the extract(isodow from ...) function, but + to_char(..., 'D')'s does not match + extract(dow from ...)'s day numbering. + + + + + + to_char(interval) formats HH and + HH12 as shown on a 12-hour clock, for example zero hours + and 36 hours both output as 12, while HH24 + outputs the full hour value, which can exceed 23 in + an interval value. + + + + + + + + shows the + template patterns available for formatting numeric values. + + + + Template Patterns for Numeric Formatting + + + + Pattern + Description + + + + + 9 + digit position (can be dropped if insignificant) + + + 0 + digit position (will not be dropped, even if insignificant) + + + . (period) + decimal point + + + , (comma) + group (thousands) separator + + + PR + negative value in angle brackets + + + S + sign anchored to number (uses locale) + + + L + currency symbol (uses locale) + + + D + decimal point (uses locale) + + + G + group separator (uses locale) + + + MI + minus sign in specified position (if number < 0) + + + PL + plus sign in specified position (if number > 0) + + + SG + plus/minus sign in specified position + + + RN + Roman numeral (input between 1 and 3999) + + + TH or th + ordinal number suffix + + + V + shift specified number of digits (see notes) + + + EEEE + exponent for scientific notation + + + +
+ + + Usage notes for numeric formatting: + + + + + 0 specifies a digit position that will always be printed, + even if it contains a leading/trailing zero. 9 also + specifies a digit position, but if it is a leading zero then it will + be replaced by a space, while if it is a trailing zero and fill mode + is specified then it will be deleted. (For to_number(), + these two pattern characters are equivalent.) + + + + + + The pattern characters S, L, D, + and G represent the sign, currency symbol, decimal point, + and thousands separator characters defined by the current locale + (see + and ). The pattern characters period + and comma represent those exact characters, with the meanings of + decimal point and thousands separator, regardless of locale. + + + + + + If no explicit provision is made for a sign + in to_char()'s pattern, one column will be reserved for + the sign, and it will be anchored to (appear just left of) the + number. If S appears just left of some 9's, + it will likewise be anchored to the number. + + + + + + A sign formatted using SG, PL, or + MI is not anchored to + the number; for example, + to_char(-12, 'MI9999') produces '-  12' + but to_char(-12, 'S9999') produces '  -12'. + (The Oracle implementation does not allow the use of + MI before 9, but rather + requires that 9 precede + MI.) + + + + + + TH does not convert values less than zero + and does not convert fractional numbers. + + + + + + PL, SG, and + TH are PostgreSQL + extensions. + + + + + + In to_number, if non-data template patterns such + as L or TH are used, the + corresponding number of input characters are skipped, whether or not + they match the template pattern, unless they are data characters + (that is, digits, sign, decimal point, or comma). For + example, TH would skip two non-data characters. + + + + + + V with to_char + multiplies the input values by + 10^n, where + n is the number of digits following + V. V with + to_number divides in a similar manner. + to_char and to_number + do not support the use of + V combined with a decimal point + (e.g., 99.9V99 is not allowed). + + + + + + EEEE (scientific notation) cannot be used in + combination with any of the other formatting patterns or + modifiers other than digit and decimal point patterns, and must be at the end of the format string + (e.g., 9.99EEEE is a valid pattern). + + + + + + + Certain modifiers can be applied to any template pattern to alter its + behavior. For example, FM99.99 + is the 99.99 pattern with the + FM modifier. + shows the + modifier patterns for numeric formatting. + + + + Template Pattern Modifiers for Numeric Formatting + + + + Modifier + Description + Example + + + + + FM prefix + fill mode (suppress trailing zeroes and padding blanks) + FM99.99 + + + TH suffix + upper case ordinal number suffix + 999TH + + + th suffix + lower case ordinal number suffix + 999th + + + +
+ + + shows some + examples of the use of the to_char function. + + + + <function>to_char</function> Examples + + + + Expression + Result + + + + + to_char(current_timestamp, 'Day, DD  HH12:MI:SS') + 'Tuesday  , 06  05:39:18' + + + to_char(current_timestamp, 'FMDay, FMDD  HH12:MI:SS') + 'Tuesday, 6  05:39:18' + + + to_char(-0.1, '99.99') + '  -.10' + + + to_char(-0.1, 'FM9.99') + '-.1' + + + to_char(-0.1, 'FM90.99') + '-0.1' + + + to_char(0.1, '0.9') + ' 0.1' + + + to_char(12, '9990999.9') + '    0012.0' + + + to_char(12, 'FM9990999.9') + '0012.' + + + to_char(485, '999') + ' 485' + + + to_char(-485, '999') + '-485' + + + to_char(485, '9 9 9') + ' 4 8 5' + + + to_char(1485, '9,999') + ' 1,485' + + + to_char(1485, '9G999') + ' 1 485' + + + to_char(148.5, '999.999') + ' 148.500' + + + to_char(148.5, 'FM999.999') + '148.5' + + + to_char(148.5, 'FM999.990') + '148.500' + + + to_char(148.5, '999D999') + ' 148,500' + + + to_char(3148.5, '9G999D999') + ' 3 148,500' + + + to_char(-485, '999S') + '485-' + + + to_char(-485, '999MI') + '485-' + + + to_char(485, '999MI') + '485 ' + + + to_char(485, 'FM999MI') + '485' + + + to_char(485, 'PL999') + '+485' + + + to_char(485, 'SG999') + '+485' + + + to_char(-485, 'SG999') + '-485' + + + to_char(-485, '9SG99') + '4-85' + + + to_char(-485, '999PR') + '<485>' + + + to_char(485, 'L999') + 'DM 485' + + + to_char(485, 'RN') + '        CDLXXXV' + + + to_char(485, 'FMRN') + 'CDLXXXV' + + + to_char(5.2, 'FMRN') + 'V' + + + to_char(482, '999th') + ' 482nd' + + + to_char(485, '"Good number:"999') + 'Good number: 485' + + + to_char(485.8, '"Pre:"999" Post:" .999') + 'Pre: 485 Post: .800' + + + to_char(12, '99V999') + ' 12000' + + + to_char(12.4, '99V999') + ' 12400' + + + to_char(12.45, '99V9') + ' 125' + + + to_char(0.0004859, '9.99EEEE') + ' 4.86e-04' + + + +
+ +
+ + + + Date/Time Functions and Operators + + + shows the available + functions for date/time value processing, with details appearing in + the following subsections. illustrates the behaviors of + the basic arithmetic operators (+, + *, etc.). For formatting functions, refer to + . You should be familiar with + the background information on date/time data types from . + + + + In addition, the usual comparison operators shown in + are available for the + date/time types. Dates and timestamps (with or without time zone) are + all comparable, while times (with or without time zone) and intervals + can only be compared to other values of the same data type. When + comparing a timestamp without time zone to a timestamp with time zone, + the former value is assumed to be given in the time zone specified by + the configuration parameter, and is + rotated to UTC for comparison to the latter value (which is already + in UTC internally). Similarly, a date value is assumed to represent + midnight in the TimeZone zone when comparing it + to a timestamp. + + + + All the functions and operators described below that take time or timestamp + inputs actually come in two variants: one that takes time with time zone or timestamp + with time zone, and one that takes time without time zone or timestamp without time zone. + For brevity, these variants are not shown separately. Also, the + + and * operators come in commutative pairs (for + example both date + integer + and integer + date); we show + only one of each such pair. + + + + Date/Time Operators + + + + + + Operator + + + Description + + + Example(s) + + + + + + + + date + integer + date + + + Add a number of days to a date + + + date '2001-09-28' + 7 + 2001-10-05 + + + + + + date + interval + timestamp + + + Add an interval to a date + + + date '2001-09-28' + interval '1 hour' + 2001-09-28 01:00:00 + + + + + + date + time + timestamp + + + Add a time-of-day to a date + + + date '2001-09-28' + time '03:00' + 2001-09-28 03:00:00 + + + + + + interval + interval + interval + + + Add intervals + + + interval '1 day' + interval '1 hour' + 1 day 01:00:00 + + + + + + timestamp + interval + timestamp + + + Add an interval to a timestamp + + + timestamp '2001-09-28 01:00' + interval '23 hours' + 2001-09-29 00:00:00 + + + + + + time + interval + time + + + Add an interval to a time + + + time '01:00' + interval '3 hours' + 04:00:00 + + + + + + - interval + interval + + + Negate an interval + + + - interval '23 hours' + -23:00:00 + + + + + + date - date + integer + + + Subtract dates, producing the number of days elapsed + + + date '2001-10-01' - date '2001-09-28' + 3 + + + + + + date - integer + date + + + Subtract a number of days from a date + + + date '2001-10-01' - 7 + 2001-09-24 + + + + + + date - interval + timestamp + + + Subtract an interval from a date + + + date '2001-09-28' - interval '1 hour' + 2001-09-27 23:00:00 + + + + + + time - time + interval + + + Subtract times + + + time '05:00' - time '03:00' + 02:00:00 + + + + + + time - interval + time + + + Subtract an interval from a time + + + time '05:00' - interval '2 hours' + 03:00:00 + + + + + + timestamp - interval + timestamp + + + Subtract an interval from a timestamp + + + timestamp '2001-09-28 23:00' - interval '23 hours' + 2001-09-28 00:00:00 + + + + + + interval - interval + interval + + + Subtract intervals + + + interval '1 day' - interval '1 hour' + 1 day -01:00:00 + + + + + + timestamp - timestamp + interval + + + Subtract timestamps (converting 24-hour intervals into days, + similarly to justify_hours()) + + + timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00' + 63 days 15:00:00 + + + + + + interval * double precision + interval + + + Multiply an interval by a scalar + + + interval '1 second' * 900 + 00:15:00 + + + interval '1 day' * 21 + 21 days + + + interval '1 hour' * 3.5 + 03:30:00 + + + + + + interval / double precision + interval + + + Divide an interval by a scalar + + + interval '1 hour' / 1.5 + 00:40:00 + + + + +
+ + + Date/Time Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + age + + age ( timestamp, timestamp ) + interval + + + Subtract arguments, producing a symbolic result that + uses years and months, rather than just days + + + age(timestamp '2001-04-10', timestamp '1957-06-13') + 43 years 9 mons 27 days + + + + + + age ( timestamp ) + interval + + + Subtract argument from current_date (at midnight) + + + age(timestamp '1957-06-13') + 62 years 6 mons 10 days + + + + + + + clock_timestamp + + clock_timestamp ( ) + timestamp with time zone + + + Current date and time (changes during statement execution); + see + + + clock_timestamp() + 2019-12-23 14:39:53.662522-05 + + + + + + + current_date + + current_date + date + + + Current date; see + + + current_date + 2019-12-23 + + + + + + + current_time + + current_time + time with time zone + + + Current time of day; see + + + current_time + 14:39:53.662522-05 + + + + + + current_time ( integer ) + time with time zone + + + Current time of day, with limited precision; + see + + + current_time(2) + 14:39:53.66-05 + + + + + + + current_timestamp + + current_timestamp + timestamp with time zone + + + Current date and time (start of current transaction); + see + + + current_timestamp + 2019-12-23 14:39:53.662522-05 + + + + + + current_timestamp ( integer ) + timestamp with time zone + + + Current date and time (start of current transaction), with limited precision; + see + + + current_timestamp(0) + 2019-12-23 14:39:53-05 + + + + + + date_bin ( interval, timestamp, timestamp ) + timestamp + + + Bin input into specified interval aligned with specified origin; see + + + date_bin('15 minutes', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00') + 2001-02-16 20:35:00 + + + + + + + date_part + + date_part ( text, timestamp ) + double precision + + + Get timestamp subfield (equivalent to extract); + see + + + date_part('hour', timestamp '2001-02-16 20:38:40') + 20 + + + + + + date_part ( text, interval ) + double precision + + + Get interval subfield (equivalent to extract); + see + + + date_part('month', interval '2 years 3 months') + 3 + + + + + + + date_trunc + + date_trunc ( text, timestamp ) + timestamp + + + Truncate to specified precision; see + + + date_trunc('hour', timestamp '2001-02-16 20:38:40') + 2001-02-16 20:00:00 + + + + + + date_trunc ( text, timestamp with time zone, text ) + timestamp with time zone + + + Truncate to specified precision in the specified time zone; see + + + + date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Australia/Sydney') + 2001-02-16 13:00:00+00 + + + + + + date_trunc ( text, interval ) + interval + + + Truncate to specified precision; see + + + + date_trunc('hour', interval '2 days 3 hours 40 minutes') + 2 days 03:00:00 + + + + + + + extract + + extract ( field from timestamp ) + numeric + + + Get timestamp subfield; see + + + extract(hour from timestamp '2001-02-16 20:38:40') + 20 + + + + + + extract ( field from interval ) + numeric + + + Get interval subfield; see + + + extract(month from interval '2 years 3 months') + 3 + + + + + + + isfinite + + isfinite ( date ) + boolean + + + Test for finite date (not +/-infinity) + + + isfinite(date '2001-02-16') + true + + + + + + isfinite ( timestamp ) + boolean + + + Test for finite timestamp (not +/-infinity) + + + isfinite(timestamp 'infinity') + false + + + + + + isfinite ( interval ) + boolean + + + Test for finite interval (currently always true) + + + isfinite(interval '4 hours') + true + + + + + + + justify_days + + justify_days ( interval ) + interval + + + Adjust interval so 30-day time periods are represented as months + + + justify_days(interval '35 days') + 1 mon 5 days + + + + + + + justify_hours + + justify_hours ( interval ) + interval + + + Adjust interval so 24-hour time periods are represented as days + + + justify_hours(interval '27 hours') + 1 day 03:00:00 + + + + + + + justify_interval + + justify_interval ( interval ) + interval + + + Adjust interval using justify_days + and justify_hours, with additional sign + adjustments + + + justify_interval(interval '1 mon -1 hour') + 29 days 23:00:00 + + + + + + + localtime + + localtime + time + + + Current time of day; + see + + + localtime + 14:39:53.662522 + + + + + + localtime ( integer ) + time + + + Current time of day, with limited precision; + see + + + localtime(0) + 14:39:53 + + + + + + + localtimestamp + + localtimestamp + timestamp + + + Current date and time (start of current transaction); + see + + + localtimestamp + 2019-12-23 14:39:53.662522 + + + + + + localtimestamp ( integer ) + timestamp + + + Current date and time (start of current + transaction), with limited precision; + see + + + localtimestamp(2) + 2019-12-23 14:39:53.66 + + + + + + + make_date + + make_date ( year int, + month int, + day int ) + date + + + Create date from year, month and day fields + (negative years signify BC) + + + make_date(2013, 7, 15) + 2013-07-15 + + + + + + make_interval + + make_interval ( years int + , months int + , weeks int + , days int + , hours int + , mins int + , secs double precision + ) + interval + + + Create interval from years, months, weeks, days, hours, minutes and + seconds fields, each of which can default to zero + + + make_interval(days => 10) + 10 days + + + + + + + make_time + + make_time ( hour int, + min int, + sec double precision ) + time + + + Create time from hour, minute and seconds fields + + + make_time(8, 15, 23.5) + 08:15:23.5 + + + + + + + make_timestamp + + make_timestamp ( year int, + month int, + day int, + hour int, + min int, + sec double precision ) + timestamp + + + Create timestamp from year, month, day, hour, minute and seconds fields + (negative years signify BC) + + + make_timestamp(2013, 7, 15, 8, 15, 23.5) + 2013-07-15 08:15:23.5 + + + + + + + make_timestamptz + + make_timestamptz ( year int, + month int, + day int, + hour int, + min int, + sec double precision + , timezone text ) + timestamp with time zone + + + Create timestamp with time zone from year, month, day, hour, minute + and seconds fields (negative years signify BC). + If timezone is not + specified, the current time zone is used; the examples assume the + session time zone is Europe/London + + + make_timestamptz(2013, 7, 15, 8, 15, 23.5) + 2013-07-15 08:15:23.5+01 + + + make_timestamptz(2013, 7, 15, 8, 15, 23.5, 'America/New_York') + 2013-07-15 13:15:23.5+01 + + + + + + + now + + now ( ) + timestamp with time zone + + + Current date and time (start of current transaction); + see + + + now() + 2019-12-23 14:39:53.662522-05 + + + + + + + statement_timestamp + + statement_timestamp ( ) + timestamp with time zone + + + Current date and time (start of current statement); + see + + + statement_timestamp() + 2019-12-23 14:39:53.662522-05 + + + + + + + timeofday + + timeofday ( ) + text + + + Current date and time + (like clock_timestamp, but as a text string); + see + + + timeofday() + Mon Dec 23 14:39:53.662522 2019 EST + + + + + + + transaction_timestamp + + transaction_timestamp ( ) + timestamp with time zone + + + Current date and time (start of current transaction); + see + + + transaction_timestamp() + 2019-12-23 14:39:53.662522-05 + + + + + + + to_timestamp + + to_timestamp ( double precision ) + timestamp with time zone + + + Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to + timestamp with time zone + + + to_timestamp(1284352323) + 2010-09-13 04:32:03+00 + + + + +
+ + + + OVERLAPS + + In addition to these functions, the SQL OVERLAPS operator is + supported: + +(start1, end1) OVERLAPS (start2, end2) +(start1, length1) OVERLAPS (start2, length2) + + This expression yields true when two time periods (defined by their + endpoints) overlap, false when they do not overlap. The endpoints + can be specified as pairs of dates, times, or time stamps; or as + a date, time, or time stamp followed by an interval. When a pair + of values is provided, either the start or the end can be written + first; OVERLAPS automatically takes the earlier value + of the pair as the start. Each time period is considered to + represent the half-open interval start <= + time < end, unless + start and end are equal in which case it + represents that single time instant. This means for instance that two + time periods with only an endpoint in common do not overlap. + + + +SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS + (DATE '2001-10-30', DATE '2002-10-30'); +Result: true +SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS + (DATE '2001-10-30', DATE '2002-10-30'); +Result: false +SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS + (DATE '2001-10-30', DATE '2001-10-31'); +Result: false +SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS + (DATE '2001-10-30', DATE '2001-10-31'); +Result: true + + + + When adding an interval value to (or subtracting an + interval value from) a timestamp with time zone + value, the days component advances or decrements the date of the + timestamp with time zone by the indicated number of days, + keeping the time of day the same. + Across daylight saving time changes (when the session time zone is set to a + time zone that recognizes DST), this means interval '1 day' + does not necessarily equal interval '24 hours'. + For example, with the session time zone set + to America/Denver: + +SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; +Result: 2005-04-03 12:00:00-06 +SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; +Result: 2005-04-03 13:00:00-06 + + This happens because an hour was skipped due to a change in daylight saving + time at 2005-04-03 02:00:00 in time zone + America/Denver. + + + + Note there can be ambiguity in the months field returned by + age because different months have different numbers of + days. PostgreSQL's approach uses the month from the + earlier of the two dates when calculating partial months. For example, + age('2004-06-01', '2004-04-30') uses April to yield + 1 mon 1 day, while using May would yield 1 mon 2 + days because May has 31 days, while April has only 30. + + + + Subtraction of dates and timestamps can also be complex. One conceptually + simple way to perform subtraction is to convert each value to a number + of seconds using EXTRACT(EPOCH FROM ...), then subtract the + results; this produces the + number of seconds between the two values. This will adjust + for the number of days in each month, timezone changes, and daylight + saving time adjustments. Subtraction of date or timestamp + values with the - operator + returns the number of days (24-hours) and hours/minutes/seconds + between the values, making the same adjustments. The age + function returns years, months, days, and hours/minutes/seconds, + performing field-by-field subtraction and then adjusting for negative + field values. The following queries illustrate the differences in these + approaches. The sample results were produced with timezone + = 'US/Eastern'; there is a daylight saving time change between the + two dates used: + + + +SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') - + EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'); +Result: 10537200 +SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') - + EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00')) + / 60 / 60 / 24; +Result: 121.958333333333 +SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00'; +Result: 121 days 23:00:00 +SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00'); +Result: 4 mons + + + + <function>EXTRACT</function>, <function>date_part</function> + + + date_part + + + extract + + + +EXTRACT(field FROM source) + + + + The extract function retrieves subfields + such as year or hour from date/time values. + source must be a value expression of + type timestamp, time, or interval. + (Expressions of type date are + cast to timestamp and can therefore be used as + well.) field is an identifier or + string that selects what field to extract from the source value. + The extract function returns values of type + numeric. + The following are valid field names: + + + + + century + + + The century + + + +SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13'); +Result: 20 +SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 21 + + + + The first century starts at 0001-01-01 00:00:00 AD, although + they did not know it at the time. This definition applies to all + Gregorian calendar countries. There is no century number 0, + you go from -1 century to 1 century. + + If you disagree with this, please write your complaint to: + Pope, Cathedral Saint-Peter of Roma, Vatican. + + + + + + day + + + For timestamp values, the day (of the month) field + (1–31) ; for interval values, the number of days + + + +SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 16 + +SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute'); +Result: 40 + + + + + + + decade + + + The year field divided by 10 + + + +SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 200 + + + + + + dow + + + The day of the week as Sunday (0) to + Saturday (6) + + + +SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 5 + + + Note that extract's day of the week numbering + differs from that of the to_char(..., + 'D') function. + + + + + + + doy + + + The day of the year (1–365/366) + + + +SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 47 + + + + + + epoch + + + For timestamp with time zone values, the + number of seconds since 1970-01-01 00:00:00 UTC (negative for + timestamps before that); + for date and timestamp values, the + nominal number of seconds since 1970-01-01 00:00:00, + without regard to timezone or daylight-savings rules; + for interval values, the total number + of seconds in the interval + + + +SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08'); +Result: 982384720.12 + +SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40.12'); +Result: 982355920.12 + +SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours'); +Result: 442800 + + + + You can convert an epoch value back to a timestamp with time zone + with to_timestamp: + + +SELECT to_timestamp(982384720.12); +Result: 2001-02-17 04:38:40.12+00 + + + + Beware that applying to_timestamp to an epoch + extracted from a date or timestamp value + could produce a misleading result: the result will effectively + assume that the original value had been given in UTC, which might + not be the case. + + + + + + hour + + + The hour field (0–23) + + + +SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 20 + + + + + + isodow + + + The day of the week as Monday (1) to + Sunday (7) + + + +SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40'); +Result: 7 + + + This is identical to dow except for Sunday. This + matches the ISO 8601 day of the week numbering. + + + + + + + isoyear + + + The ISO 8601 week-numbering year that the date + falls in (not applicable to intervals) + + + +SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01'); +Result: 2005 +SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); +Result: 2006 + + + + Each ISO 8601 week-numbering year begins with the + Monday of the week containing the 4th of January, so in early + January or late December the ISO year may be + different from the Gregorian year. See the week + field for more information. + + + This field is not available in PostgreSQL releases prior to 8.3. + + + + + + julian + + + The Julian Date corresponding to the + date or timestamp (not applicable to intervals). Timestamps + that are not local midnight result in a fractional value. See + for more information. + + + +SELECT EXTRACT(JULIAN FROM DATE '2006-01-01'); +Result: 2453737 +SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00'); +Result: 2453737.50000000000000000000 + + + + + + microseconds + + + The seconds field, including fractional parts, multiplied by 1 + 000 000; note that this includes full seconds + + + +SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5'); +Result: 28500000 + + + + + + millennium + + + The millennium + + + +SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 3 + + + + Years in the 1900s are in the second millennium. + The third millennium started January 1, 2001. + + + + + + milliseconds + + + The seconds field, including fractional parts, multiplied by + 1000. Note that this includes full seconds. + + + +SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5'); +Result: 28500 + + + + + + minute + + + The minutes field (0–59) + + + +SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 38 + + + + + + month + + + For timestamp values, the number of the month + within the year (1–12) ; for interval values, + the number of months, modulo 12 (0–11) + + + +SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 2 + +SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months'); +Result: 3 + +SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); +Result: 1 + + + + + + quarter + + + The quarter of the year (1–4) that the date is in + + + +SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 1 + + + + + + second + + + The seconds field, including any fractional seconds + + + +SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 40 + +SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); +Result: 28.5 + + + + + timezone + + + The time zone offset from UTC, measured in seconds. Positive values + correspond to time zones east of UTC, negative values to + zones west of UTC. (Technically, + PostgreSQL does not use UTC because + leap seconds are not handled.) + + + + + + timezone_hour + + + The hour component of the time zone offset + + + + + + timezone_minute + + + The minute component of the time zone offset + + + + + + week + + + The number of the ISO 8601 week-numbering week of + the year. By definition, ISO weeks start on Mondays and the first + week of a year contains January 4 of that year. In other words, the + first Thursday of a year is in week 1 of that year. + + + In the ISO week-numbering system, it is possible for early-January + dates to be part of the 52nd or 53rd week of the previous year, and for + late-December dates to be part of the first week of the next year. + For example, 2005-01-01 is part of the 53rd week of year + 2004, and 2006-01-01 is part of the 52nd week of year + 2005, while 2012-12-31 is part of the first week of 2013. + It's recommended to use the isoyear field together with + week to get consistent results. + + + +SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 7 + + + + + + year + + + The year field. Keep in mind there is no 0 AD, so subtracting + BC years from AD years should be done with care. + + + +SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); +Result: 2001 + + + + + + + + + + When the input value is +/-Infinity, extract returns + +/-Infinity for monotonically-increasing fields (epoch, + julian, year, isoyear, + decade, century, and millennium). + For other fields, NULL is returned. PostgreSQL + versions before 9.6 returned zero for all cases of infinite input. + + + + + The extract function is primarily intended + for computational processing. For formatting date/time values for + display, see . + + + + The date_part function is modeled on the traditional + Ingres equivalent to the + SQL-standard function extract: + +date_part('field', source) + + Note that here the field parameter needs to + be a string value, not a name. The valid field names for + date_part are the same as for + extract. + For historical reasons, the date_part function + returns values of type double precision. This can result in + a loss of precision in certain uses. Using extract + is recommended instead. + + + +SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40'); +Result: 16 + +SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); +Result: 4 + + + + + + <function>date_trunc</function> + + + date_trunc + + + + The function date_trunc is conceptually + similar to the trunc function for numbers. + + + + +date_trunc(field, source [, time_zone ]) + + source is a value expression of type + timestamp, timestamp with time zone, + or interval. + (Values of type date and + time are cast automatically to timestamp or + interval, respectively.) + field selects to which precision to + truncate the input value. The return value is likewise of type + timestamp, timestamp with time zone, + or interval, + and it has all fields that are less significant than the + selected one set to zero (or one, for day and month). + + + + Valid values for field are: + + microseconds + milliseconds + second + minute + hour + day + week + month + quarter + year + decade + century + millennium + + + + + When the input value is of type timestamp with time zone, + the truncation is performed with respect to a particular time zone; + for example, truncation to day produces a value that + is midnight in that zone. By default, truncation is done with respect + to the current setting, but the + optional time_zone argument can be provided + to specify a different time zone. The time zone name can be specified + in any of the ways described in . + + + + A time zone cannot be specified when processing timestamp without + time zone or interval inputs. These are always + taken at face value. + + + + Examples (assuming the local time zone is America/New_York): + +SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40'); +Result: 2001-02-16 20:00:00 + +SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); +Result: 2001-01-01 00:00:00 + +SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00'); +Result: 2001-02-16 00:00:00-05 + +SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney'); +Result: 2001-02-16 08:00:00-05 + +SELECT date_trunc('hour', INTERVAL '3 days 02:47:33'); +Result: 3 days 02:00:00 + + + + + + <function>date_bin</function> + + + date_bin + + + + The function date_bin bins the input + timestamp into the specified interval (the stride) + aligned with a specified origin. + + + + +date_bin(stride, source, origin) + + source is a value expression of type + timestamp or timestamp with time zone. (Values + of type date are cast automatically to + timestamp.) stride is a value + expression of type interval. The return value is likewise + of type timestamp or timestamp with time zone, + and it marks the beginning of the bin into which the + source is placed. + + + + Examples: + +SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01'); +Result: 2020-02-11 15:30:00 + +SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01 00:02:30'); +Result: 2020-02-11 15:32:30 + + + + + In the case of full units (1 minute, 1 hour, etc.), it gives the same result as + the analogous date_trunc call, but the difference is + that date_bin can truncate to an arbitrary interval. + + + + Negative intervals are allowed and are treated the same as positive intervals. + + + + The stride interval cannot contain units of month + or larger. + + + + + <literal>AT TIME ZONE</literal> + + + time zone + conversion + + + + AT TIME ZONE + + + + The AT TIME ZONE operator converts time + stamp without time zone to/from + time stamp with time zone, and + time with time zone values to different time + zones. shows its + variants. + + + + <literal>AT TIME ZONE</literal> Variants + + + + + Operator + + + Description + + + Example(s) + + + + + + + + timestamp without time zone AT TIME ZONE zone + timestamp with time zone + + + Converts given time stamp without time zone to + time stamp with time zone, assuming the given + value is in the named time zone. + + + timestamp '2001-02-16 20:38:40' at time zone 'America/Denver' + 2001-02-17 03:38:40+00 + + + + + + timestamp with time zone AT TIME ZONE zone + timestamp without time zone + + + Converts given time stamp with time zone to + time stamp without time zone, as the time would + appear in that zone. + + + timestamp with time zone '2001-02-16 20:38:40-05' at time zone 'America/Denver' + 2001-02-16 18:38:40 + + + + + + time with time zone AT TIME ZONE zone + time with time zone + + + Converts given time with time zone to a new time + zone. Since no date is supplied, this uses the currently active UTC + offset for the named destination zone. + + + time with time zone '05:34:17-05' at time zone 'UTC' + 10:34:17+00 + + + + +
+ + + In these expressions, the desired time zone zone can be + specified either as a text value (e.g., 'America/Los_Angeles') + or as an interval (e.g., INTERVAL '-08:00'). + In the text case, a time zone name can be specified in any of the ways + described in . + The interval case is only useful for zones that have fixed offsets from + UTC, so it is not very common in practice. + + + + Examples (assuming the current setting + is America/Los_Angeles): + +SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver'; +Result: 2001-02-16 19:38:40-08 + +SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver'; +Result: 2001-02-16 18:38:40 + +SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago'; +Result: 2001-02-16 05:38:40 + + The first example adds a time zone to a value that lacks it, and + displays the value using the current TimeZone + setting. The second example shifts the time stamp with time zone value + to the specified time zone, and returns the value without a time zone. + This allows storage and display of values different from the current + TimeZone setting. The third example converts + Tokyo time to Chicago time. + + + + The function timezone(zone, + timestamp) is equivalent to the SQL-conforming construct + timestamp AT TIME ZONE + zone. + +
+ + + Current Date/Time + + + date + current + + + + time + current + + + + PostgreSQL provides a number of functions + that return values related to the current date and time. These + SQL-standard functions all return values based on the start time of + the current transaction: + +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TIME(precision) +CURRENT_TIMESTAMP(precision) +LOCALTIME +LOCALTIMESTAMP +LOCALTIME(precision) +LOCALTIMESTAMP(precision) + + + + + CURRENT_TIME and + CURRENT_TIMESTAMP deliver values with time zone; + LOCALTIME and + LOCALTIMESTAMP deliver values without time zone. + + + + CURRENT_TIME, + CURRENT_TIMESTAMP, + LOCALTIME, and + LOCALTIMESTAMP + can optionally take + a precision parameter, which causes the result to be rounded + to that many fractional digits in the seconds field. Without a precision parameter, + the result is given to the full available precision. + + + + Some examples: + +SELECT CURRENT_TIME; +Result: 14:39:53.662522-05 + +SELECT CURRENT_DATE; +Result: 2019-12-23 + +SELECT CURRENT_TIMESTAMP; +Result: 2019-12-23 14:39:53.662522-05 + +SELECT CURRENT_TIMESTAMP(2); +Result: 2019-12-23 14:39:53.66-05 + +SELECT LOCALTIMESTAMP; +Result: 2019-12-23 14:39:53.662522 + + + + + Since these functions return + the start time of the current transaction, their values do not + change during the transaction. This is considered a feature: + the intent is to allow a single transaction to have a consistent + notion of the current time, so that multiple + modifications within the same transaction bear the same + time stamp. + + + + + Other database systems might advance these values more + frequently. + + + + + PostgreSQL also provides functions that + return the start time of the current statement, as well as the actual + current time at the instant the function is called. The complete list + of non-SQL-standard time functions is: + +transaction_timestamp() +statement_timestamp() +clock_timestamp() +timeofday() +now() + + + + + transaction_timestamp() is equivalent to + CURRENT_TIMESTAMP, but is named to clearly reflect + what it returns. + statement_timestamp() returns the start time of the current + statement (more specifically, the time of receipt of the latest command + message from the client). + statement_timestamp() and transaction_timestamp() + return the same value during the first command of a transaction, but might + differ during subsequent commands. + clock_timestamp() returns the actual current time, and + therefore its value changes even within a single SQL command. + timeofday() is a historical + PostgreSQL function. Like + clock_timestamp(), it returns the actual current time, + but as a formatted text string rather than a timestamp + with time zone value. + now() is a traditional PostgreSQL + equivalent to transaction_timestamp(). + + + + All the date/time data types also accept the special literal value + now to specify the current date and time (again, + interpreted as the transaction start time). Thus, + the following three all return the same result: + +SELECT CURRENT_TIMESTAMP; +SELECT now(); +SELECT TIMESTAMP 'now'; -- but see tip below + + + + + + Do not use the third form when specifying a value to be evaluated later, + for example in a DEFAULT clause for a table column. + The system will convert now + to a timestamp as soon as the constant is parsed, so that when + the default value is needed, + the time of the table creation would be used! The first two + forms will not be evaluated until the default value is used, + because they are function calls. Thus they will give the desired + behavior of defaulting to the time of row insertion. + (See also .) + + + + + + Delaying Execution + + + pg_sleep + + + pg_sleep_for + + + pg_sleep_until + + + sleep + + + delay + + + + The following functions are available to delay execution of the server + process: + +pg_sleep ( double precision ) +pg_sleep_for ( interval ) +pg_sleep_until ( timestamp with time zone ) + + + pg_sleep makes the current session's process + sleep until the given number of seconds have + elapsed. Fractional-second delays can be specified. + pg_sleep_for is a convenience function to + allow the sleep time to be specified as an interval. + pg_sleep_until is a convenience function for when + a specific wake-up time is desired. + For example: + + +SELECT pg_sleep(1.5); +SELECT pg_sleep_for('5 minutes'); +SELECT pg_sleep_until('tomorrow 03:00'); + + + + + + The effective resolution of the sleep interval is platform-specific; + 0.01 seconds is a common value. The sleep delay will be at least as long + as specified. It might be longer depending on factors such as server load. + In particular, pg_sleep_until is not guaranteed to + wake up exactly at the specified time, but it will not wake up any earlier. + + + + + + Make sure that your session does not hold more locks than necessary + when calling pg_sleep or its variants. Otherwise + other sessions might have to wait for your sleeping process, slowing down + the entire system. + + + + +
+ + + + Enum Support Functions + + + For enum types (described in ), + there are several functions that allow cleaner programming without + hard-coding particular values of an enum type. + These are listed in . The examples + assume an enum type created as: + + +CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple'); + + + + + + Enum Support Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + enum_first + + enum_first ( anyenum ) + anyenum + + + Returns the first value of the input enum type. + + + enum_first(null::rainbow) + red + + + + + + enum_last + + enum_last ( anyenum ) + anyenum + + + Returns the last value of the input enum type. + + + enum_last(null::rainbow) + purple + + + + + + enum_range + + enum_range ( anyenum ) + anyarray + + + Returns all values of the input enum type in an ordered array. + + + enum_range(null::rainbow) + {red,orange,yellow,&zwsp;green,blue,purple} + + + + + enum_range ( anyenum, anyenum ) + anyarray + + + Returns the range between the two given enum values, as an ordered + array. The values must be from the same enum type. If the first + parameter is null, the result will start with the first value of + the enum type. + If the second parameter is null, the result will end with the last + value of the enum type. + + + enum_range('orange'::rainbow, 'green'::rainbow) + {orange,yellow,green} + + + enum_range(NULL, 'green'::rainbow) + {red,orange,&zwsp;yellow,green} + + + enum_range('orange'::rainbow, NULL) + {orange,yellow,green,&zwsp;blue,purple} + + + + +
+ + + Notice that except for the two-argument form of enum_range, + these functions disregard the specific value passed to them; they care + only about its declared data type. Either null or a specific value of + the type can be passed, with the same result. It is more common to + apply these functions to a table column or function argument than to + a hardwired type name as used in the examples. + +
+ + + Geometric Functions and Operators + + + The geometric types point, box, + lseg, line, path, + polygon, and circle have a large set of + native support functions and operators, shown in , , and . + + + + Geometric Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + geometric_type + point + geometric_type + + + Adds the coordinates of the second point to those of each + point of the first argument, thus performing translation. + Available for point, box, path, + circle. + + + box '(1,1),(0,0)' + point '(2,0)' + (3,1),(2,0) + + + + + + path + path + path + + + Concatenates two open paths (returns NULL if either path is closed). + + + path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]' + [(0,0),(1,1),(2,2),(3,3),(4,4)] + + + + + + geometric_type - point + geometric_type + + + Subtracts the coordinates of the second point from those + of each point of the first argument, thus performing translation. + Available for point, box, path, + circle. + + + box '(1,1),(0,0)' - point '(2,0)' + (-1,1),(-2,0) + + + + + + geometric_type * point + geometric_type + + + Multiplies each point of the first argument by the second + point (treating a point as being a complex number + represented by real and imaginary parts, and performing standard + complex multiplication). If one interprets + the second point as a vector, this is equivalent to + scaling the object's size and distance from the origin by the length + of the vector, and rotating it counterclockwise around the origin by + the vector's angle from the x axis. + Available for point, box,Rotating a + box with these operators only moves its corner points: the box is + still considered to have sides parallel to the axes. Hence the box's + size is not preserved, as a true rotation would do. + path, circle. + + + path '((0,0),(1,0),(1,1))' * point '(3.0,0)' + ((0,0),(3,0),(3,3)) + + + path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45)) + ((0,0),&zwsp;(0.7071067811865475,0.7071067811865475),&zwsp;(0,1.414213562373095)) + + + + + + geometric_type / point + geometric_type + + + Divides each point of the first argument by the second + point (treating a point as being a complex number + represented by real and imaginary parts, and performing standard + complex division). If one interprets + the second point as a vector, this is equivalent to + scaling the object's size and distance from the origin down by the + length of the vector, and rotating it clockwise around the origin by + the vector's angle from the x axis. + Available for point, box, path, + circle. + + + path '((0,0),(1,0),(1,1))' / point '(2.0,0)' + ((0,0),(0.5,0),(0.5,0.5)) + + + path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45)) + ((0,0),&zwsp;(0.7071067811865476,-0.7071067811865476),&zwsp;(1.4142135623730951,0)) + + + + + + @-@ geometric_type + double precision + + + Computes the total length. + Available for lseg, path. + + + @-@ path '[(0,0),(1,0),(1,1)]' + 2 + + + + + + @@ geometric_type + point + + + Computes the center point. + Available for box, lseg, path, + polygon, circle. + + + @@ box '(2,2),(0,0)' + (1,1) + + + + + + # geometric_type + integer + + + Returns the number of points. + Available for path, polygon. + + + # path '((1,0),(0,1),(-1,0))' + 3 + + + + + + geometric_type # geometric_type + point + + + Computes the point of intersection, or NULL if there is none. + Available for lseg, line. + + + lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]' + (0.5,0.5) + + + + + + box # box + box + + + Computes the intersection of two boxes, or NULL if there is none. + + + box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)' + (1,1),(-1,-1) + + + + + + geometric_type ## geometric_type + point + + + Computes the closest point to the first object on the second object. + Available for these pairs of types: + (point, box), + (point, lseg), + (point, line), + (lseg, box), + (lseg, lseg), + (lseg, line), + (line, box), + (line, lseg). + + + point '(0,0)' ## lseg '[(2,0),(0,2)]' + (1,1) + + + + + + geometric_type <-> geometric_type + double precision + + + Computes the distance between the objects. + Available for all seven geometric types, for all combinations + of point with another geometric type, and for + these additional pairs of types: + (box, lseg), + (box, line), + (lseg, line), + (polygon, circle) + (and the commutator cases). + + + circle '<(0,0),1>' <-> circle '<(5,0),1>' + 3 + + + + + + geometric_type @> geometric_type + boolean + + + Does first object contain second? + Available for these pairs of types: + (box, point), + (box, box), + (path, point), + (polygon, point), + (polygon, polygon), + (circle, point), + (circle, circle). + + + circle '<(0,0),2>' @> point '(1,1)' + t + + + + + + geometric_type <@ geometric_type + boolean + + + Is first object contained in or on second? + Available for these pairs of types: + (point, box), + (point, lseg), + (point, line), + (point, path), + (point, polygon), + (point, circle), + (box, box), + (lseg, box), + (lseg, line), + (polygon, polygon), + (circle, circle). + + + point '(1,1)' <@ circle '<(0,0),2>' + t + + + + + + geometric_type && geometric_type + boolean + + + Do these objects overlap? (One point in common makes this true.) + Available for box, polygon, + circle. + + + box '(1,1),(0,0)' && box '(2,2),(0,0)' + t + + + + + + geometric_type << geometric_type + boolean + + + Is first object strictly left of second? + Available for point, box, + polygon, circle. + + + circle '<(0,0),1>' << circle '<(5,0),1>' + t + + + + + + geometric_type >> geometric_type + boolean + + + Is first object strictly right of second? + Available for point, box, + polygon, circle. + + + circle '<(5,0),1>' >> circle '<(0,0),1>' + t + + + + + + geometric_type &< geometric_type + boolean + + + Does first object not extend to the right of second? + Available for box, polygon, + circle. + + + box '(1,1),(0,0)' &< box '(2,2),(0,0)' + t + + + + + + geometric_type &> geometric_type + boolean + + + Does first object not extend to the left of second? + Available for box, polygon, + circle. + + + box '(3,3),(0,0)' &> box '(2,2),(0,0)' + t + + + + + + geometric_type <<| geometric_type + boolean + + + Is first object strictly below second? + Available for point, box, polygon, + circle. + + + box '(3,3),(0,0)' <<| box '(5,5),(3,4)' + t + + + + + + geometric_type |>> geometric_type + boolean + + + Is first object strictly above second? + Available for point, box, polygon, + circle. + + + box '(5,5),(3,4)' |>> box '(3,3),(0,0)' + t + + + + + + geometric_type &<| geometric_type + boolean + + + Does first object not extend above second? + Available for box, polygon, + circle. + + + box '(1,1),(0,0)' &<| box '(2,2),(0,0)' + t + + + + + + geometric_type |&> geometric_type + boolean + + + Does first object not extend below second? + Available for box, polygon, + circle. + + + box '(3,3),(0,0)' |&> box '(2,2),(0,0)' + t + + + + + + box <^ box + boolean + + + Is first object below second (allows edges to touch)? + + + box '((1,1),(0,0))' <^ box '((2,2),(1,1))' + t + + + + + + box >^ box + boolean + + + Is first object above second (allows edges to touch)? + + + box '((2,2),(1,1))' >^ box '((1,1),(0,0))' + t + + + + + + geometric_type ?# geometric_type + boolean + + + Do these objects intersect? + Available for these pairs of types: + (box, box), + (lseg, box), + (lseg, lseg), + (lseg, line), + (line, box), + (line, line), + (path, path). + + + lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)' + t + + + + + + ?- line + boolean + + + ?- lseg + boolean + + + Is line horizontal? + + + ?- lseg '[(-1,0),(1,0)]' + t + + + + + + point ?- point + boolean + + + Are points horizontally aligned (that is, have same y coordinate)? + + + point '(1,0)' ?- point '(0,0)' + t + + + + + + ?| line + boolean + + + ?| lseg + boolean + + + Is line vertical? + + + ?| lseg '[(-1,0),(1,0)]' + f + + + + + + point ?| point + boolean + + + Are points vertically aligned (that is, have same x coordinate)? + + + point '(0,1)' ?| point '(0,0)' + t + + + + + + line ?-| line + boolean + + + lseg ?-| lseg + boolean + + + Are lines perpendicular? + + + lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]' + t + + + + + + line ?|| line + boolean + + + lseg ?|| lseg + boolean + + + Are lines parallel? + + + lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]' + t + + + + + + geometric_type ~= geometric_type + boolean + + + Are these objects the same? + Available for point, box, + polygon, circle. + + + polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))' + t + + + + +
+ + + + Note that the same as operator, ~=, + represents the usual notion of equality for the point, + box, polygon, and circle types. + Some of the geometric types also have an = operator, but + = compares for equal areas only. + The other scalar comparison operators (<= and so + on), where available for these types, likewise compare areas. + + + + + + Before PostgreSQL 14, the point + is strictly below/above comparison operators point + <<| point and point + |>> point were respectively + called <^ and >^. These + names are still available, but are deprecated and will eventually be + removed. + + + + + Geometric Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + area + + area ( geometric_type ) + double precision + + + Computes area. + Available for box, path, circle. + A path input must be closed, else NULL is returned. + Also, if the path is self-intersecting, the result may be + meaningless. + + + area(box '(2,2),(0,0)') + 4 + + + + + + + center + + center ( geometric_type ) + point + + + Computes center point. + Available for box, circle. + + + center(box '(1,2),(0,0)') + (0.5,1) + + + + + + + diagonal + + diagonal ( box ) + lseg + + + Extracts box's diagonal as a line segment + (same as lseg(box)). + + + diagonal(box '(1,2),(0,0)') + [(1,2),(0,0)] + + + + + + + diameter + + diameter ( circle ) + double precision + + + Computes diameter of circle. + + + diameter(circle '<(0,0),2>') + 4 + + + + + + + height + + height ( box ) + double precision + + + Computes vertical size of box. + + + height(box '(1,2),(0,0)') + 2 + + + + + + + isclosed + + isclosed ( path ) + boolean + + + Is path closed? + + + isclosed(path '((0,0),(1,1),(2,0))') + t + + + + + + + isopen + + isopen ( path ) + boolean + + + Is path open? + + + isopen(path '[(0,0),(1,1),(2,0)]') + t + + + + + + + length + + length ( geometric_type ) + double precision + + + Computes the total length. + Available for lseg, path. + + + length(path '((-1,0),(1,0))') + 4 + + + + + + + npoints + + npoints ( geometric_type ) + integer + + + Returns the number of points. + Available for path, polygon. + + + npoints(path '[(0,0),(1,1),(2,0)]') + 3 + + + + + + + pclose + + pclose ( path ) + path + + + Converts path to closed form. + + + pclose(path '[(0,0),(1,1),(2,0)]') + ((0,0),(1,1),(2,0)) + + + + + + + popen + + popen ( path ) + path + + + Converts path to open form. + + + popen(path '((0,0),(1,1),(2,0))') + [(0,0),(1,1),(2,0)] + + + + + + + radius + + radius ( circle ) + double precision + + + Computes radius of circle. + + + radius(circle '<(0,0),2>') + 2 + + + + + + + slope + + slope ( point, point ) + double precision + + + Computes slope of a line drawn through the two points. + + + slope(point '(0,0)', point '(2,1)') + 0.5 + + + + + + + width + + width ( box ) + double precision + + + Computes horizontal size of box. + + + width(box '(1,2),(0,0)') + 1 + + + + +
+ + + Geometric Type Conversion Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + box + + box ( circle ) + box + + + Computes box inscribed within the circle. + + + box(circle '<(0,0),2>') + (1.414213562373095,1.414213562373095),&zwsp;(-1.414213562373095,-1.414213562373095) + + + + + + box ( point ) + box + + + Converts point to empty box. + + + box(point '(1,0)') + (1,0),(1,0) + + + + + + box ( point, point ) + box + + + Converts any two corner points to box. + + + box(point '(0,1)', point '(1,0)') + (1,1),(0,0) + + + + + + box ( polygon ) + box + + + Computes bounding box of polygon. + + + box(polygon '((0,0),(1,1),(2,0))') + (2,1),(0,0) + + + + + + + bound_box + + bound_box ( box, box ) + box + + + Computes bounding box of two boxes. + + + bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)') + (4,4),(0,0) + + + + + + + circle + + circle ( box ) + circle + + + Computes smallest circle enclosing box. + + + circle(box '(1,1),(0,0)') + <(0.5,0.5),0.7071067811865476> + + + + + + circle ( point, double precision ) + circle + + + Constructs circle from center and radius. + + + circle(point '(0,0)', 2.0) + <(0,0),2> + + + + + + circle ( polygon ) + circle + + + Converts polygon to circle. The circle's center is the mean of the + positions of the polygon's points, and the radius is the average + distance of the polygon's points from that center. + + + circle(polygon '((0,0),(1,3),(2,0))') + <(1,1),1.6094757082487299> + + + + + + + line + + line ( point, point ) + line + + + Converts two points to the line through them. + + + line(point '(-1,0)', point '(1,0)') + {0,-1,0} + + + + + + + lseg + + lseg ( box ) + lseg + + + Extracts box's diagonal as a line segment. + + + lseg(box '(1,0),(-1,0)') + [(1,0),(-1,0)] + + + + + + lseg ( point, point ) + lseg + + + Constructs line segment from two endpoints. + + + lseg(point '(-1,0)', point '(1,0)') + [(-1,0),(1,0)] + + + + + + + path + + path ( polygon ) + path + + + Converts polygon to a closed path with the same list of points. + + + path(polygon '((0,0),(1,1),(2,0))') + ((0,0),(1,1),(2,0)) + + + + + + + point + + point ( double precision, double precision ) + point + + + Constructs point from its coordinates. + + + point(23.4, -44.5) + (23.4,-44.5) + + + + + + point ( box ) + point + + + Computes center of box. + + + point(box '(1,0),(-1,0)') + (0,0) + + + + + + point ( circle ) + point + + + Computes center of circle. + + + point(circle '<(0,0),2>') + (0,0) + + + + + + point ( lseg ) + point + + + Computes center of line segment. + + + point(lseg '[(-1,0),(1,0)]') + (0,0) + + + + + + point ( polygon ) + point + + + Computes center of polygon (the mean of the + positions of the polygon's points). + + + point(polygon '((0,0),(1,1),(2,0))') + (1,0.3333333333333333) + + + + + + + polygon + + polygon ( box ) + polygon + + + Converts box to a 4-point polygon. + + + polygon(box '(1,1),(0,0)') + ((0,0),(0,1),(1,1),(1,0)) + + + + + + polygon ( circle ) + polygon + + + Converts circle to a 12-point polygon. + + + polygon(circle '<(0,0),2>') + ((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009)) + + + + + + polygon ( integer, circle ) + polygon + + + Converts circle to an n-point polygon. + + + polygon(4, circle '<(3,0),1>') + ((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1)) + + + + + + polygon ( path ) + polygon + + + Converts closed path to a polygon with the same list of points. + + + polygon(path '((0,0),(1,1),(2,0))') + ((0,0),(1,1),(2,0)) + + + + + +
+ + + It is possible to access the two component numbers of a point + as though the point were an array with indexes 0 and 1. For example, if + t.p is a point column then + SELECT p[0] FROM t retrieves the X coordinate and + UPDATE t SET p[1] = ... changes the Y coordinate. + In the same way, a value of type box or lseg can be treated + as an array of two point values. + + +
+ + + + Network Address Functions and Operators + + + The IP network address types, cidr and inet, + support the usual comparison operators shown in + + as well as the specialized operators and functions shown in + and + . + + + + Any cidr value can be cast to inet implicitly; + therefore, the operators and functions shown below as operating on + inet also work on cidr values. (Where there are + separate functions for inet and cidr, it is + because the behavior should be different for the two cases.) + Also, it is permitted to cast an inet value + to cidr. When this is done, any bits to the right of the + netmask are silently zeroed to create a valid cidr value. + + + + IP Address Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + inet << inet + boolean + + + Is subnet strictly contained by subnet? + This operator, and the next four, test for subnet inclusion. They + consider only the network parts of the two addresses (ignoring any + bits to the right of the netmasks) and determine whether one network + is identical to or a subnet of the other. + + + inet '192.168.1.5' << inet '192.168.1/24' + t + + + inet '192.168.0.5' << inet '192.168.1/24' + f + + + inet '192.168.1/24' << inet '192.168.1/24' + f + + + + + + inet <<= inet + boolean + + + Is subnet contained by or equal to subnet? + + + inet '192.168.1/24' <<= inet '192.168.1/24' + t + + + + + + inet >> inet + boolean + + + Does subnet strictly contain subnet? + + + inet '192.168.1/24' >> inet '192.168.1.5' + t + + + + + + inet >>= inet + boolean + + + Does subnet contain or equal subnet? + + + inet '192.168.1/24' >>= inet '192.168.1/24' + t + + + + + + inet && inet + boolean + + + Does either subnet contain or equal the other? + + + inet '192.168.1/24' && inet '192.168.1.80/28' + t + + + inet '192.168.1/24' && inet '192.168.2.0/28' + f + + + + + + ~ inet + inet + + + Computes bitwise NOT. + + + ~ inet '192.168.1.6' + 63.87.254.249 + + + + + + inet & inet + inet + + + Computes bitwise AND. + + + inet '192.168.1.6' & inet '0.0.0.255' + 0.0.0.6 + + + + + + inet | inet + inet + + + Computes bitwise OR. + + + inet '192.168.1.6' | inet '0.0.0.255' + 192.168.1.255 + + + + + + inet + bigint + inet + + + Adds an offset to an address. + + + inet '192.168.1.6' + 25 + 192.168.1.31 + + + + + + bigint + inet + inet + + + Adds an offset to an address. + + + 200 + inet '::ffff:fff0:1' + ::ffff:255.240.0.201 + + + + + + inet - bigint + inet + + + Subtracts an offset from an address. + + + inet '192.168.1.43' - 36 + 192.168.1.7 + + + + + + inet - inet + bigint + + + Computes the difference of two addresses. + + + inet '192.168.1.43' - inet '192.168.1.19' + 24 + + + inet '::1' - inet '::ffff:1' + -4294901760 + + + + +
+ + + IP Address Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + abbrev + + abbrev ( inet ) + text + + + Creates an abbreviated display format as text. + (The result is the same as the inet output function + produces; it is abbreviated only in comparison to the + result of an explicit cast to text, which for historical + reasons will never suppress the netmask part.) + + + abbrev(inet '10.1.0.0/32') + 10.1.0.0 + + + + + + abbrev ( cidr ) + text + + + Creates an abbreviated display format as text. + (The abbreviation consists of dropping all-zero octets to the right + of the netmask; more examples are in + .) + + + abbrev(cidr '10.1.0.0/16') + 10.1/16 + + + + + + + broadcast + + broadcast ( inet ) + inet + + + Computes the broadcast address for the address's network. + + + broadcast(inet '192.168.1.5/24') + 192.168.1.255/24 + + + + + + + family + + family ( inet ) + integer + + + Returns the address's family: 4 for IPv4, + 6 for IPv6. + + + family(inet '::1') + 6 + + + + + + + host + + host ( inet ) + text + + + Returns the IP address as text, ignoring the netmask. + + + host(inet '192.168.1.0/24') + 192.168.1.0 + + + + + + + hostmask + + hostmask ( inet ) + inet + + + Computes the host mask for the address's network. + + + hostmask(inet '192.168.23.20/30') + 0.0.0.3 + + + + + + + inet_merge + + inet_merge ( inet, inet ) + cidr + + + Computes the smallest network that includes both of the given networks. + + + inet_merge(inet '192.168.1.5/24', inet '192.168.2.5/24') + 192.168.0.0/22 + + + + + + + inet_same_family + + inet_same_family ( inet, inet ) + boolean + + + Tests whether the addresses belong to the same IP family. + + + inet_same_family(inet '192.168.1.5/24', inet '::1') + f + + + + + + + masklen + + masklen ( inet ) + integer + + + Returns the netmask length in bits. + + + masklen(inet '192.168.1.5/24') + 24 + + + + + + + netmask + + netmask ( inet ) + inet + + + Computes the network mask for the address's network. + + + netmask(inet '192.168.1.5/24') + 255.255.255.0 + + + + + + + network + + network ( inet ) + cidr + + + Returns the network part of the address, zeroing out + whatever is to the right of the netmask. + (This is equivalent to casting the value to cidr.) + + + network(inet '192.168.1.5/24') + 192.168.1.0/24 + + + + + + + set_masklen + + set_masklen ( inet, integer ) + inet + + + Sets the netmask length for an inet value. + The address part does not change. + + + set_masklen(inet '192.168.1.5/24', 16) + 192.168.1.5/16 + + + + + + set_masklen ( cidr, integer ) + cidr + + + Sets the netmask length for a cidr value. + Address bits to the right of the new netmask are set to zero. + + + set_masklen(cidr '192.168.1.0/24', 16) + 192.168.0.0/16 + + + + + + + text + + text ( inet ) + text + + + Returns the unabbreviated IP address and netmask length as text. + (This has the same result as an explicit cast to text.) + + + text(inet '192.168.1.5') + 192.168.1.5/32 + + + + +
+ + + + The abbrev, host, + and text functions are primarily intended to offer + alternative display formats for IP addresses. + + + + + The MAC address types, macaddr and macaddr8, + support the usual comparison operators shown in + + as well as the specialized functions shown in + . + In addition, they support the bitwise logical operators + ~, & and | + (NOT, AND and OR), just as shown above for IP addresses. + + + + MAC Address Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + trunc + + trunc ( macaddr ) + macaddr + + + Sets the last 3 bytes of the address to zero. The remaining prefix + can be associated with a particular manufacturer (using data not + included in PostgreSQL). + + + trunc(macaddr '12:34:56:78:90:ab') + 12:34:56:00:00:00 + + + + + + trunc ( macaddr8 ) + macaddr8 + + + Sets the last 5 bytes of the address to zero. The remaining prefix + can be associated with a particular manufacturer (using data not + included in PostgreSQL). + + + trunc(macaddr8 '12:34:56:78:90:ab:cd:ef') + 12:34:56:00:00:00:00:00 + + + + + + + macaddr8_set7bit + + macaddr8_set7bit ( macaddr8 ) + macaddr8 + + + Sets the 7th bit of the address to one, creating what is known as + modified EUI-64, for inclusion in an IPv6 address. + + + macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef') + 02:34:56:ff:fe:ab:cd:ef + + + + +
+ +
+ + + + Text Search Functions and Operators + + + full text search + functions and operators + + + + text search + functions and operators + + + + , + and + + summarize the functions and operators that are provided + for full text searching. See for a detailed + explanation of PostgreSQL's text search + facility. + + + + Text Search Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + tsvector @@ tsquery + boolean + + + tsquery @@ tsvector + boolean + + + Does tsvector match tsquery? + (The arguments can be given in either order.) + + + to_tsvector('fat cats ate rats') @@ to_tsquery('cat & rat') + t + + + + + + text @@ tsquery + boolean + + + Does text string, after implicit invocation + of to_tsvector(), match tsquery? + + + 'fat cats ate rats' @@ to_tsquery('cat & rat') + t + + + + + + tsvector @@@ tsquery + boolean + + + tsquery @@@ tsvector + boolean + + + This is a deprecated synonym for @@. + + + to_tsvector('fat cats ate rats') @@@ to_tsquery('cat & rat') + t + + + + + + tsvector || tsvector + tsvector + + + Concatenates two tsvectors. If both inputs contain + lexeme positions, the second input's positions are adjusted + accordingly. + + + 'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector + 'a':1 'b':2,5 'c':3 'd':4 + + + + + + tsquery && tsquery + tsquery + + + ANDs two tsquerys together, producing a query that + matches documents that match both input queries. + + + 'fat | rat'::tsquery && 'cat'::tsquery + ( 'fat' | 'rat' ) & 'cat' + + + + + + tsquery || tsquery + tsquery + + + ORs two tsquerys together, producing a query that + matches documents that match either input query. + + + 'fat | rat'::tsquery || 'cat'::tsquery + 'fat' | 'rat' | 'cat' + + + + + + !! tsquery + tsquery + + + Negates a tsquery, producing a query that matches + documents that do not match the input query. + + + !! 'cat'::tsquery + !'cat' + + + + + + tsquery <-> tsquery + tsquery + + + Constructs a phrase query, which matches if the two input queries + match at successive lexemes. + + + to_tsquery('fat') <-> to_tsquery('rat') + 'fat' <-> 'rat' + + + + + + tsquery @> tsquery + boolean + + + Does first tsquery contain the second? (This considers + only whether all the lexemes appearing in one query appear in the + other, ignoring the combining operators.) + + + 'cat'::tsquery @> 'cat & rat'::tsquery + f + + + + + + tsquery <@ tsquery + boolean + + + Is first tsquery contained in the second? (This + considers only whether all the lexemes appearing in one query appear + in the other, ignoring the combining operators.) + + + 'cat'::tsquery <@ 'cat & rat'::tsquery + t + + + 'cat'::tsquery <@ '!cat & rat'::tsquery + t + + + + +
+ + + In addition to these specialized operators, the usual comparison + operators shown in are + available for types tsvector and tsquery. + These are not very + useful for text searching but allow, for example, unique indexes to be + built on columns of these types. + + + + Text Search Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + array_to_tsvector + + array_to_tsvector ( text[] ) + tsvector + + + Converts an array of lexemes to a tsvector. + The given strings are used as-is without further processing. + + + array_to_tsvector('{fat,cat,rat}'::text[]) + 'cat' 'fat' 'rat' + + + + + + + get_current_ts_config + + get_current_ts_config ( ) + regconfig + + + Returns the OID of the current default text search configuration + (as set by ). + + + get_current_ts_config() + english + + + + + + + length + + length ( tsvector ) + integer + + + Returns the number of lexemes in the tsvector. + + + length('fat:2,4 cat:3 rat:5A'::tsvector) + 3 + + + + + + + numnode + + numnode ( tsquery ) + integer + + + Returns the number of lexemes plus operators in + the tsquery. + + + numnode('(fat & rat) | cat'::tsquery) + 5 + + + + + + + plainto_tsquery + + plainto_tsquery ( + config regconfig, + query text ) + tsquery + + + Converts text to a tsquery, normalizing words according to + the specified or default configuration. Any punctuation in the string + is ignored (it does not determine query operators). The resulting + query matches documents containing all non-stopwords in the text. + + + plainto_tsquery('english', 'The Fat Rats') + 'fat' & 'rat' + + + + + + + phraseto_tsquery + + phraseto_tsquery ( + config regconfig, + query text ) + tsquery + + + Converts text to a tsquery, normalizing words according to + the specified or default configuration. Any punctuation in the string + is ignored (it does not determine query operators). The resulting + query matches phrases containing all non-stopwords in the text. + + + phraseto_tsquery('english', 'The Fat Rats') + 'fat' <-> 'rat' + + + phraseto_tsquery('english', 'The Cat and Rats') + 'cat' <2> 'rat' + + + + + + + websearch_to_tsquery + + websearch_to_tsquery ( + config regconfig, + query text ) + tsquery + + + Converts text to a tsquery, normalizing words according + to the specified or default configuration. Quoted word sequences are + converted to phrase tests. The word or is understood + as producing an OR operator, and a dash produces a NOT operator; + other punctuation is ignored. + This approximates the behavior of some common web search tools. + + + websearch_to_tsquery('english', '"fat rat" or cat dog') + 'fat' <-> 'rat' | 'cat' & 'dog' + + + + + + + querytree + + querytree ( tsquery ) + text + + + Produces a representation of the indexable portion of + a tsquery. A result that is empty or + just T indicates a non-indexable query. + + + querytree('foo & ! bar'::tsquery) + 'foo' + + + + + + + setweight + + setweight ( vector tsvector, weight "char" ) + tsvector + + + Assigns the specified weight to each element + of the vector. + + + setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A') + 'cat':3A 'fat':2A,4A 'rat':5A + + + + + + + setweight + setweight for specific lexeme(s) + + setweight ( vector tsvector, weight "char", lexemes text[] ) + tsvector + + + Assigns the specified weight to elements + of the vector that are listed + in lexemes. + + + setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}') + 'cat':3A 'fat':2,4 'rat':5A,6A + + + + + + + strip + + strip ( tsvector ) + tsvector + + + Removes positions and weights from the tsvector. + + + strip('fat:2,4 cat:3 rat:5A'::tsvector) + 'cat' 'fat' 'rat' + + + + + + + to_tsquery + + to_tsquery ( + config regconfig, + query text ) + tsquery + + + Converts text to a tsquery, normalizing words according to + the specified or default configuration. The words must be combined + by valid tsquery operators. + + + to_tsquery('english', 'The & Fat & Rats') + 'fat' & 'rat' + + + + + + + to_tsvector + + to_tsvector ( + config regconfig, + document text ) + tsvector + + + Converts text to a tsvector, normalizing words according + to the specified or default configuration. Position information is + included in the result. + + + to_tsvector('english', 'The Fat Rats') + 'fat':2 'rat':3 + + + + + + to_tsvector ( + config regconfig, + document json ) + tsvector + + + to_tsvector ( + config regconfig, + document jsonb ) + tsvector + + + Converts each string value in the JSON document to + a tsvector, normalizing words according to the specified + or default configuration. The results are then concatenated in + document order to produce the output. Position information is + generated as though one stopword exists between each pair of string + values. (Beware that document order of the fields of a + JSON object is implementation-dependent when the input + is jsonb; observe the difference in the examples.) + + + to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json) + 'dog':5 'fat':2 'rat':3 + + + to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::jsonb) + 'dog':1 'fat':4 'rat':5 + + + + + + + json_to_tsvector + + json_to_tsvector ( + config regconfig, + document json, + filter jsonb ) + tsvector + + + + jsonb_to_tsvector + + jsonb_to_tsvector ( + config regconfig, + document jsonb, + filter jsonb ) + tsvector + + + Selects each item in the JSON document that is requested by + the filter and converts each one to + a tsvector, normalizing words according to the specified + or default configuration. The results are then concatenated in + document order to produce the output. Position information is + generated as though one stopword exists between each pair of selected + items. (Beware that document order of the fields of a + JSON object is implementation-dependent when the input + is jsonb.) + The filter must be a jsonb + array containing zero or more of these keywords: + "string" (to include all string values), + "numeric" (to include all numeric values), + "boolean" (to include all boolean values), + "key" (to include all keys), or + "all" (to include all the above). + As a special case, the filter can also be a + simple JSON value that is one of these keywords. + + + json_to_tsvector('english', '{"a": "The Fat Rats", "b": 123}'::json, '["string", "numeric"]') + '123':5 'fat':2 'rat':3 + + + json_to_tsvector('english', '{"cat": "The Fat Rats", "dog": 123}'::json, '"all"') + '123':9 'cat':1 'dog':7 'fat':4 'rat':5 + + + + + + + ts_delete + + ts_delete ( vector tsvector, lexeme text ) + tsvector + + + Removes any occurrence of the given lexeme + from the vector. + + + ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat') + 'cat':3 'rat':5A + + + + + + ts_delete ( vector tsvector, lexemes text[] ) + tsvector + + + Removes any occurrences of the lexemes + in lexemes + from the vector. + + + ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat']) + 'cat':3 + + + + + + + ts_filter + + ts_filter ( vector tsvector, weights "char"[] ) + tsvector + + + Selects only elements with the given weights + from the vector. + + + ts_filter('fat:2,4 cat:3b,7c rat:5A'::tsvector, '{a,b}') + 'cat':3B 'rat':5A + + + + + + + ts_headline + + ts_headline ( + config regconfig, + document text, + query tsquery + , options text ) + text + + + Displays, in an abbreviated form, the match(es) for + the query in + the document, which must be raw text not + a tsvector. Words in the document are normalized + according to the specified or default configuration before matching to + the query. Use of this function is discussed in + , which also describes the + available options. + + + ts_headline('The fat cat ate the rat.', 'cat') + The fat <b>cat</b> ate the rat. + + + + + + ts_headline ( + config regconfig, + document json, + query tsquery + , options text ) + text + + + ts_headline ( + config regconfig, + document jsonb, + query tsquery + , options text ) + text + + + Displays, in an abbreviated form, match(es) for + the query that occur in string values + within the JSON document. + See for more details. + + + ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat') + {"cat": "raining <b>cats</b> and dogs"} + + + + + + + ts_rank + + ts_rank ( + weights real[], + vector tsvector, + query tsquery + , normalization integer ) + real + + + Computes a score showing how well + the vector matches + the query. See + for details. + + + ts_rank(to_tsvector('raining cats and dogs'), 'cat') + 0.06079271 + + + + + + + ts_rank_cd + + ts_rank_cd ( + weights real[], + vector tsvector, + query tsquery + , normalization integer ) + real + + + Computes a score showing how well + the vector matches + the query, using a cover density + algorithm. See for details. + + + ts_rank_cd(to_tsvector('raining cats and dogs'), 'cat') + 0.1 + + + + + + + ts_rewrite + + ts_rewrite ( query tsquery, + target tsquery, + substitute tsquery ) + tsquery + + + Replaces occurrences of target + with substitute + within the query. + See for details. + + + ts_rewrite('a & b'::tsquery, 'a'::tsquery, 'foo|bar'::tsquery) + 'b' & ( 'foo' | 'bar' ) + + + + + + ts_rewrite ( query tsquery, + select text ) + tsquery + + + Replaces portions of the query according to + target(s) and substitute(s) obtained by executing + a SELECT command. + See for details. + + + SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases') + 'b' & ( 'foo' | 'bar' ) + + + + + + + tsquery_phrase + + tsquery_phrase ( query1 tsquery, query2 tsquery ) + tsquery + + + Constructs a phrase query that searches + for matches of query1 + and query2 at successive lexemes (same + as <-> operator). + + + tsquery_phrase(to_tsquery('fat'), to_tsquery('cat')) + 'fat' <-> 'cat' + + + + + + tsquery_phrase ( query1 tsquery, query2 tsquery, distance integer ) + tsquery + + + Constructs a phrase query that searches + for matches of query1 and + query2 that occur exactly + distance lexemes apart. + + + tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10) + 'fat' <10> 'cat' + + + + + + + tsvector_to_array + + tsvector_to_array ( tsvector ) + text[] + + + Converts a tsvector to an array of lexemes. + + + tsvector_to_array('fat:2,4 cat:3 rat:5A'::tsvector) + {cat,fat,rat} + + + + + + + unnest + for tsvector + + unnest ( tsvector ) + setof record + ( lexeme text, + positions smallint[], + weights text ) + + + Expands a tsvector into a set of rows, one per lexeme. + + + select * from unnest('cat:3 fat:2,4 rat:5A'::tsvector) + + + lexeme | positions | weights +--------+-----------+--------- + cat | {3} | {D} + fat | {2,4} | {D,D} + rat | {5} | {A} + + + + + +
+ + + + All the text search functions that accept an optional regconfig + argument will use the configuration specified by + + when that argument is omitted. + + + + + The functions in + + are listed separately because they are not usually used in everyday text + searching operations. They are primarily helpful for development and + debugging of new text search configurations. + + + + Text Search Debugging Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + ts_debug + + ts_debug ( + config regconfig, + document text ) + setof record + ( alias text, + description text, + token text, + dictionaries regdictionary[], + dictionary regdictionary, + lexemes text[] ) + + + Extracts and normalizes tokens from + the document according to the specified or + default text search configuration, and returns information about how + each token was processed. + See for details. + + + ts_debug('english', 'The Brightest supernovaes') + (asciiword,"Word, all ASCII",The,{english_stem},english_stem,{}) ... + + + + + + + ts_lexize + + ts_lexize ( dict regdictionary, token text ) + text[] + + + Returns an array of replacement lexemes if the input token is known to + the dictionary, or an empty array if the token is known to the + dictionary but it is a stop word, or NULL if it is not a known word. + See for details. + + + ts_lexize('english_stem', 'stars') + {star} + + + + + + + ts_parse + + ts_parse ( parser_name text, + document text ) + setof record + ( tokid integer, + token text ) + + + Extracts tokens from the document using the + named parser. + See for details. + + + ts_parse('default', 'foo - bar') + (1,foo) ... + + + + + + ts_parse ( parser_oid oid, + document text ) + setof record + ( tokid integer, + token text ) + + + Extracts tokens from the document using a + parser specified by OID. + See for details. + + + ts_parse(3722, 'foo - bar') + (1,foo) ... + + + + + + + ts_token_type + + ts_token_type ( parser_name text ) + setof record + ( tokid integer, + alias text, + description text ) + + + Returns a table that describes each type of token the named parser can + recognize. + See for details. + + + ts_token_type('default') + (1,asciiword,"Word, all ASCII") ... + + + + + + ts_token_type ( parser_oid oid ) + setof record + ( tokid integer, + alias text, + description text ) + + + Returns a table that describes each type of token a parser specified + by OID can recognize. + See for details. + + + ts_token_type(3722) + (1,asciiword,"Word, all ASCII") ... + + + + + + + ts_stat + + ts_stat ( sqlquery text + , weights text ) + setof record + ( word text, + ndoc integer, + nentry integer ) + + + Executes the sqlquery, which must return a + single tsvector column, and returns statistics about each + distinct lexeme contained in the data. + See for details. + + + ts_stat('SELECT vector FROM apod') + (foo,10,15) ... + + + + +
+ +
+ + + UUID Functions + + + UUID + generating + + + + gen_random_uuid + + + + PostgreSQL includes one function to generate a UUID: + +gen_random_uuid () uuid + + This function returns a version 4 (random) UUID. This is the most commonly + used type of UUID and is appropriate for most applications. + + + + The module provides additional functions that + implement other standard algorithms for generating UUIDs. + + + + PostgreSQL also provides the usual comparison + operators shown in for + UUIDs. + + + + + + XML Functions + + + XML Functions + + + + The functions and function-like expressions described in this + section operate on values of type xml. See for information about the xml + type. The function-like expressions xmlparse + and xmlserialize for converting to and from + type xml are documented there, not in this section. + + + + Use of most of these functions + requires PostgreSQL to have been built + with configure --with-libxml. + + + + Producing XML Content + + + A set of functions and function-like expressions is available for + producing XML content from SQL data. As such, they are + particularly suitable for formatting query results into XML + documents for processing in client applications. + + + + <literal>xmlcomment</literal> + + + xmlcomment + + + +xmlcomment ( text ) xml + + + + The function xmlcomment creates an XML value + containing an XML comment with the specified text as content. + The text cannot contain -- or end with a + -, otherwise the resulting construct + would not be a valid XML comment. + If the argument is null, the result is null. + + + + Example: + +]]> + + + + + <literal>xmlconcat</literal> + + + xmlconcat + + + +xmlconcat ( xml , ... ) xml + + + + The function xmlconcat concatenates a list + of individual XML values to create a single value containing an + XML content fragment. Null values are omitted; the result is + only null if there are no nonnull arguments. + + + + Example: +', 'foo'); + + xmlconcat +---------------------- + foo +]]> + + + + XML declarations, if present, are combined as follows. If all + argument values have the same XML version declaration, that + version is used in the result, else no version is used. If all + argument values have the standalone declaration value + yes, then that value is used in the result. If + all argument values have a standalone declaration value and at + least one is no, then that is used in the result. + Else the result will have no standalone declaration. If the + result is determined to require a standalone declaration but no + version declaration, a version declaration with version 1.0 will + be used because XML requires an XML declaration to contain a + version declaration. Encoding declarations are ignored and + removed in all cases. + + + + Example: +', ''); + + xmlconcat +----------------------------------- + +]]> + + + + + <literal>xmlelement</literal> + + + xmlelement + + + +xmlelement ( NAME name , XMLATTRIBUTES ( attvalue AS attname , ... ) , content , ... ) xml + + + + The xmlelement expression produces an XML + element with the given name, attributes, and content. + The name + and attname items shown in the syntax are + simple identifiers, not values. The attvalue + and content items are expressions, which can + yield any PostgreSQL data type. The + argument(s) within XMLATTRIBUTES generate attributes + of the XML element; the content value(s) are + concatenated to form its content. + + + + Examples: + + +SELECT xmlelement(name foo, xmlattributes('xyz' as bar)); + + xmlelement +------------------ + + +SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent'); + + xmlelement +------------------------------------- + content +]]> + + + + Element and attribute names that are not valid XML names are + escaped by replacing the offending characters by the sequence + _xHHHH_, where + HHHH is the character's Unicode + codepoint in hexadecimal notation. For example: + +]]> + + + + An explicit attribute name need not be specified if the attribute + value is a column reference, in which case the column's name will + be used as the attribute name by default. In other cases, the + attribute must be given an explicit name. So this example is + valid: + +CREATE TABLE test (a xml, b xml); +SELECT xmlelement(name test, xmlattributes(a, b)) FROM test; + + But these are not: + +SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test; +SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test; + + + + + Element content, if specified, will be formatted according to + its data type. If the content is itself of type xml, + complex XML documents can be constructed. For example: + +]]> + + Content of other types will be formatted into valid XML character + data. This means in particular that the characters <, >, + and & will be converted to entities. Binary data (data type + bytea) will be represented in base64 or hex + encoding, depending on the setting of the configuration parameter + . The particular behavior for + individual data types is expected to evolve in order to align the + PostgreSQL mappings with those specified in SQL:2006 and later, + as discussed in . + + + + + <literal>xmlforest</literal> + + + xmlforest + + + +xmlforest ( content AS name , ... ) xml + + + + The xmlforest expression produces an XML + forest (sequence) of elements using the given names and content. + As for xmlelement, + each name must be a simple identifier, while + the content expressions can have any data + type. + + + + Examples: + +SELECT xmlforest('abc' AS foo, 123 AS bar); + + xmlforest +------------------------------ + <foo>abc</foo><bar>123</bar> + + +SELECT xmlforest(table_name, column_name) +FROM information_schema.columns +WHERE table_schema = 'pg_catalog'; + + xmlforest +------------------------------------&zwsp;----------------------------------- + <table_name>pg_authid</table_name>&zwsp;<column_name>rolname</column_name> + <table_name>pg_authid</table_name>&zwsp;<column_name>rolsuper</column_name> + ... + + + As seen in the second example, the element name can be omitted if + the content value is a column reference, in which case the column + name is used by default. Otherwise, a name must be specified. + + + + Element names that are not valid XML names are escaped as shown + for xmlelement above. Similarly, content + data is escaped to make valid XML content, unless it is already + of type xml. + + + + Note that XML forests are not valid XML documents if they consist + of more than one element, so it might be useful to wrap + xmlforest expressions in + xmlelement. + + + + + <literal>xmlpi</literal> + + + xmlpi + + + +xmlpi ( NAME name , content ) xml + + + + The xmlpi expression creates an XML + processing instruction. + As for xmlelement, + the name must be a simple identifier, while + the content expression can have any data type. + The content, if present, must not contain the + character sequence ?>. + + + + Example: + +]]> + + + + + <literal>xmlroot</literal> + + + xmlroot + + + +xmlroot ( xml, VERSION {text|NO VALUE} , STANDALONE {YES|NO|NO VALUE} ) xml + + + + The xmlroot expression alters the properties + of the root node of an XML value. If a version is specified, + it replaces the value in the root node's version declaration; if a + standalone setting is specified, it replaces the value in the + root node's standalone declaration. + + + +abc'), + version '1.0', standalone yes); + + xmlroot +---------------------------------------- + + abc +]]> + + + + + <literal>xmlagg</literal> + + + xmlagg + + + +xmlagg ( xml ) xml + + + + The function xmlagg is, unlike the other + functions described here, an aggregate function. It concatenates the + input values to the aggregate function call, + much like xmlconcat does, except that concatenation + occurs across rows rather than across expressions in a single row. + See for additional information + about aggregate functions. + + + + Example: +abc'); +INSERT INTO test VALUES (2, ''); +SELECT xmlagg(x) FROM test; + xmlagg +---------------------- + abc +]]> + + + + To determine the order of the concatenation, an ORDER BY + clause may be added to the aggregate call as described in + . For example: + +abc +]]> + + + + The following non-standard approach used to be recommended + in previous versions, and may still be useful in specific + cases: + +abc +]]> + + + + + + XML Predicates + + + The expressions described in this section check properties + of xml values. + + + + <literal>IS DOCUMENT</literal> + + + IS DOCUMENT + + + +xml IS DOCUMENT boolean + + + + The expression IS DOCUMENT returns true if the + argument XML value is a proper XML document, false if it is not + (that is, it is a content fragment), or null if the argument is + null. See about the difference + between documents and content fragments. + + + + + <literal>IS NOT DOCUMENT</literal> + + + IS NOT DOCUMENT + + + +xml IS NOT DOCUMENT boolean + + + + The expression IS NOT DOCUMENT returns false if the + argument XML value is a proper XML document, true if it is not (that is, + it is a content fragment), or null if the argument is null. + + + + + <literal>XMLEXISTS</literal> + + + XMLEXISTS + + + +XMLEXISTS ( text PASSING BY {REF|VALUE} xml BY {REF|VALUE} ) boolean + + + + The function xmlexists evaluates an XPath 1.0 + expression (the first argument), with the passed XML value as its context + item. The function returns false if the result of that evaluation + yields an empty node-set, true if it yields any other value. The + function returns null if any argument is null. A nonnull value + passed as the context item must be an XML document, not a content + fragment or any non-XML value. + + + + Example: + TorontoOttawa'); + + xmlexists +------------ + t +(1 row) +]]> + + + + The BY REF and BY VALUE clauses + are accepted in PostgreSQL, but are ignored, + as discussed in . + + + + In the SQL standard, the xmlexists function + evaluates an expression in the XML Query language, + but PostgreSQL allows only an XPath 1.0 + expression, as discussed in + . + + + + + <literal>xml_is_well_formed</literal> + + + xml_is_well_formed + + + + xml_is_well_formed_document + + + + xml_is_well_formed_content + + + +xml_is_well_formed ( text ) boolean +xml_is_well_formed_document ( text ) boolean +xml_is_well_formed_content ( text ) boolean + + + + These functions check whether a text string represents + well-formed XML, returning a Boolean result. + xml_is_well_formed_document checks for a well-formed + document, while xml_is_well_formed_content checks + for well-formed content. xml_is_well_formed does + the former if the configuration + parameter is set to DOCUMENT, or the latter if it is set to + CONTENT. This means that + xml_is_well_formed is useful for seeing whether + a simple cast to type xml will succeed, whereas the other two + functions are useful for seeing whether the corresponding variants of + XMLPARSE will succeed. + + + + Examples: + +'); + xml_is_well_formed +-------------------- + f +(1 row) + +SELECT xml_is_well_formed(''); + xml_is_well_formed +-------------------- + t +(1 row) + +SET xmloption TO CONTENT; +SELECT xml_is_well_formed('abc'); + xml_is_well_formed +-------------------- + t +(1 row) + +SELECT xml_is_well_formed_document('bar'); + xml_is_well_formed_document +----------------------------- + t +(1 row) + +SELECT xml_is_well_formed_document('bar'); + xml_is_well_formed_document +----------------------------- + f +(1 row) +]]> + + The last example shows that the checks include whether + namespaces are correctly matched. + + + + + + Processing XML + + + To process values of data type xml, PostgreSQL offers + the functions xpath and + xpath_exists, which evaluate XPath 1.0 + expressions, and the XMLTABLE + table function. + + + + <literal>xpath</literal> + + + XPath + + + +xpath ( xpath text, xml xml , nsarray text[] ) xml[] + + + + The function xpath evaluates the XPath 1.0 + expression xpath (given as text) + against the XML value + xml. It returns an array of XML values + corresponding to the node-set produced by the XPath expression. + If the XPath expression returns a scalar value rather than a node-set, + a single-element array is returned. + + + + The second argument must be a well formed XML document. In particular, + it must have a single root node element. + + + + The optional third argument of the function is an array of namespace + mappings. This array should be a two-dimensional text array with + the length of the second axis being equal to 2 (i.e., it should be an + array of arrays, each of which consists of exactly 2 elements). + The first element of each array entry is the namespace name (alias), the + second the namespace URI. It is not required that aliases provided in + this array be the same as those being used in the XML document itself (in + other words, both in the XML document and in the xpath + function context, aliases are local). + + + + Example: +test', + ARRAY[ARRAY['my', 'http://example.com']]); + + xpath +-------- + {test} +(1 row) +]]> + + + + To deal with default (anonymous) namespaces, do something like this: +test', + ARRAY[ARRAY['mydefns', 'http://example.com']]); + + xpath +-------- + {test} +(1 row) +]]> + + + + + <literal>xpath_exists</literal> + + + xpath_exists + + + +xpath_exists ( xpath text, xml xml , nsarray text[] ) boolean + + + + The function xpath_exists is a specialized form + of the xpath function. Instead of returning the + individual XML values that satisfy the XPath 1.0 expression, this function + returns a Boolean indicating whether the query was satisfied or not + (specifically, whether it produced any value other than an empty node-set). + This function is equivalent to the XMLEXISTS predicate, + except that it also offers support for a namespace mapping argument. + + + + Example: +test', + ARRAY[ARRAY['my', 'http://example.com']]); + + xpath_exists +-------------- + t +(1 row) +]]> + + + + + <literal>xmltable</literal> + + + xmltable + + + + table function + XMLTABLE + + + +XMLTABLE ( + XMLNAMESPACES ( namespace_uri AS namespace_name , ... ), + row_expression PASSING BY {REF|VALUE} document_expression BY {REF|VALUE} + COLUMNS name { type PATH column_expression DEFAULT default_expression NOT NULL | NULL + | FOR ORDINALITY } + , ... +) setof record + + + + The xmltable expression produces a table based + on an XML value, an XPath filter to extract rows, and a + set of column definitions. + Although it syntactically resembles a function, it can only appear + as a table in a query's FROM clause. + + + + The optional XMLNAMESPACES clause gives a + comma-separated list of namespace definitions, where + each namespace_uri is a text + expression and each namespace_name is a simple + identifier. It specifies the XML namespaces used in the document and + their aliases. A default namespace specification is not currently + supported. + + + + The required row_expression argument is an + XPath 1.0 expression (given as text) that is evaluated, + passing the XML value document_expression as + its context item, to obtain a set of XML nodes. These nodes are what + xmltable transforms into output rows. No rows + will be produced if the document_expression + is null, nor if the row_expression produces + an empty node-set or any value other than a node-set. + + + + document_expression provides the context + item for the row_expression. It must be a + well-formed XML document; fragments/forests are not accepted. + The BY REF and BY VALUE clauses + are accepted but ignored, as discussed in + . + + + + In the SQL standard, the xmltable function + evaluates expressions in the XML Query language, + but PostgreSQL allows only XPath 1.0 + expressions, as discussed in + . + + + + The required COLUMNS clause specifies the + column(s) that will be produced in the output table. + See the syntax summary above for the format. + A name is required for each column, as is a data type + (unless FOR ORDINALITY is specified, in which case + type integer is implicit). The path, default and + nullability clauses are optional. + + + + A column marked FOR ORDINALITY will be populated + with row numbers, starting with 1, in the order of nodes retrieved from + the row_expression's result node-set. + At most one column may be marked FOR ORDINALITY. + + + + + XPath 1.0 does not specify an order for nodes in a node-set, so code + that relies on a particular order of the results will be + implementation-dependent. Details can be found in + . + + + + + The column_expression for a column is an + XPath 1.0 expression that is evaluated for each row, with the current + node from the row_expression result as its + context item, to find the value of the column. If + no column_expression is given, then the + column name is used as an implicit path. + + + + If a column's XPath expression returns a non-XML value (which is limited + to string, boolean, or double in XPath 1.0) and the column has a + PostgreSQL type other than xml, the column will be set + as if by assigning the value's string representation to the PostgreSQL + type. (If the value is a boolean, its string representation is taken + to be 1 or 0 if the output + column's type category is numeric, otherwise true or + false.) + + + + If a column's XPath expression returns a non-empty set of XML nodes + and the column's PostgreSQL type is xml, the column will + be assigned the expression result exactly, if it is of document or + content form. + + + A result containing more than one element node at the top level, or + non-whitespace text outside of an element, is an example of content form. + An XPath result can be of neither form, for example if it returns an + attribute node selected from the element that contains it. Such a result + will be put into content form with each such disallowed node replaced by + its string value, as defined for the XPath 1.0 + string function. + + + + + + A non-XML result assigned to an xml output column produces + content, a single text node with the string value of the result. + An XML result assigned to a column of any other type may not have more than + one node, or an error is raised. If there is exactly one node, the column + will be set as if by assigning the node's string + value (as defined for the XPath 1.0 string function) + to the PostgreSQL type. + + + + The string value of an XML element is the concatenation, in document order, + of all text nodes contained in that element and its descendants. The string + value of an element with no descendant text nodes is an + empty string (not NULL). + Any xsi:nil attributes are ignored. + Note that the whitespace-only text() node between two non-text + elements is preserved, and that leading whitespace on a text() + node is not flattened. + The XPath 1.0 string function may be consulted for the + rules defining the string value of other XML node types and non-XML values. + + + + The conversion rules presented here are not exactly those of the SQL + standard, as discussed in . + + + + If the path expression returns an empty node-set + (typically, when it does not match) + for a given row, the column will be set to NULL, unless + a default_expression is specified; then the + value resulting from evaluating that expression is used. + + + + A default_expression, rather than being + evaluated immediately when xmltable is called, + is evaluated each time a default is needed for the column. + If the expression qualifies as stable or immutable, the repeat + evaluation may be skipped. + This means that you can usefully use volatile functions like + nextval in + default_expression. + + + + Columns may be marked NOT NULL. If the + column_expression for a NOT + NULL column does not match anything and there is + no DEFAULT or + the default_expression also evaluates to null, + an error is reported. + + + + Examples: + + + AU + Australia + + + JP + Japan + Shinzo Abe + 145935 + + + SG + Singapore + 697 + + +$$ AS data; + +SELECT xmltable.* + FROM xmldata, + XMLTABLE('//ROWS/ROW' + PASSING data + COLUMNS id int PATH '@id', + ordinality FOR ORDINALITY, + "COUNTRY_NAME" text, + country_id text PATH 'COUNTRY_ID', + size_sq_km float PATH 'SIZE[@unit = "sq_km"]', + size_other text PATH + 'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)', + premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified'); + + id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premier_name +----+------------+--------------+------------+------------+--------------+--------------- + 1 | 1 | Australia | AU | | | not specified + 5 | 2 | Japan | JP | | 145935 sq_mi | Shinzo Abe + 6 | 3 | Singapore | SG | 697 | | not specified +]]> + + The following example shows concatenation of multiple text() nodes, + usage of the column name as XPath filter, and the treatment of whitespace, + XML comments and processing instructions: + + + Hello2a2 bbbxxxCC + +$$ AS data; + +SELECT xmltable.* + FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text); + element +------------------------- + Hello2a2 bbbxxxCC +]]> + + + + The following example illustrates how + the XMLNAMESPACES clause can be used to specify + a list of namespaces + used in the XML document as well as in the XPath expressions: + + + + + +'::xml) +) +SELECT xmltable.* + FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x, + 'http://example.com/b' AS "B"), + '/x:example/x:item' + PASSING (SELECT data FROM xmldata) + COLUMNS foo int PATH '@foo', + bar int PATH '@B:bar'); + foo | bar +-----+----- + 1 | 2 + 3 | 4 + 4 | 5 +(3 rows) +]]> + + + + + + Mapping Tables to XML + + + XML export + + + + The following functions map the contents of relational tables to + XML values. They can be thought of as XML export functionality: + +table_to_xml ( table regclass, nulls boolean, + tableforest boolean, targetns text ) xml +query_to_xml ( query text, nulls boolean, + tableforest boolean, targetns text ) xml +cursor_to_xml ( cursor refcursor, count integer, nulls boolean, + tableforest boolean, targetns text ) xml + + + + + table_to_xml maps the content of the named + table, passed as parameter table. The + regclass type accepts strings identifying tables using the + usual notation, including optional schema qualification and + double quotes (see for details). + query_to_xml executes the + query whose text is passed as parameter + query and maps the result set. + cursor_to_xml fetches the indicated number of + rows from the cursor specified by the parameter + cursor. This variant is recommended if + large tables have to be mapped, because the result value is built + up in memory by each function. + + + + If tableforest is false, then the resulting + XML document looks like this: + + + data + data + + + + ... + + + ... + +]]> + + If tableforest is true, the result is an + XML content fragment that looks like this: + + data + data + + + + ... + + +... +]]> + + If no table name is available, that is, when mapping a query or a + cursor, the string table is used in the first + format, row in the second format. + + + + The choice between these formats is up to the user. The first + format is a proper XML document, which will be important in many + applications. The second format tends to be more useful in the + cursor_to_xml function if the result values are to be + reassembled into one document later on. The functions for + producing XML content discussed above, in particular + xmlelement, can be used to alter the results + to taste. + + + + The data values are mapped in the same way as described for the + function xmlelement above. + + + + The parameter nulls determines whether null + values should be included in the output. If true, null values in + columns are represented as: + +]]> + where xsi is the XML namespace prefix for XML + Schema Instance. An appropriate namespace declaration will be + added to the result value. If false, columns containing null + values are simply omitted from the output. + + + + The parameter targetns specifies the + desired XML namespace of the result. If no particular namespace + is wanted, an empty string should be passed. + + + + The following functions return XML Schema documents describing the + mappings performed by the corresponding functions above: + +table_to_xmlschema ( table regclass, nulls boolean, + tableforest boolean, targetns text ) xml +query_to_xmlschema ( query text, nulls boolean, + tableforest boolean, targetns text ) xml +cursor_to_xmlschema ( cursor refcursor, nulls boolean, + tableforest boolean, targetns text ) xml + + It is essential that the same parameters are passed in order to + obtain matching XML data mappings and XML Schema documents. + + + + The following functions produce XML data mappings and the + corresponding XML Schema in one document (or forest), linked + together. They can be useful where self-contained and + self-describing results are wanted: + +table_to_xml_and_xmlschema ( table regclass, nulls boolean, + tableforest boolean, targetns text ) xml +query_to_xml_and_xmlschema ( query text, nulls boolean, + tableforest boolean, targetns text ) xml + + + + + In addition, the following functions are available to produce + analogous mappings of entire schemas or the entire current + database: + +schema_to_xml ( schema name, nulls boolean, + tableforest boolean, targetns text ) xml +schema_to_xmlschema ( schema name, nulls boolean, + tableforest boolean, targetns text ) xml +schema_to_xml_and_xmlschema ( schema name, nulls boolean, + tableforest boolean, targetns text ) xml + +database_to_xml ( nulls boolean, + tableforest boolean, targetns text ) xml +database_to_xmlschema ( nulls boolean, + tableforest boolean, targetns text ) xml +database_to_xml_and_xmlschema ( nulls boolean, + tableforest boolean, targetns text ) xml + + + These functions ignore tables that are not readable by the current user. + The database-wide functions additionally ignore schemas that the current + user does not have USAGE (lookup) privilege for. + + + + Note that these potentially produce a lot of data, which needs to + be built up in memory. When requesting content mappings of large + schemas or databases, it might be worthwhile to consider mapping the + tables separately instead, possibly even through a cursor. + + + + The result of a schema content mapping looks like this: + + + +table1-mapping + +table2-mapping + +... + +]]> + + where the format of a table mapping depends on the + tableforest parameter as explained above. + + + + The result of a database content mapping looks like this: + + + + + ... + + + + ... + + +... + +]]> + + where the schema mapping is as above. + + + + As an example of using the output produced by these functions, + shows an XSLT stylesheet that + converts the output of + table_to_xml_and_xmlschema to an HTML + document containing a tabular rendition of the table data. In a + similar manner, the results from these functions can be + converted into other XML-based formats. + + + + XSLT Stylesheet for Converting SQL/XML Output to HTML + + + + + + + + + + + + + <xsl:value-of select="name(current())"/> + + + + + + + + + + + + + + + + +
+ + +
+ +
+]]>
+
+
+
+ + + JSON Functions and Operators + + + JSON + functions and operators + + + + This section describes: + + + + + functions and operators for processing and creating JSON data + + + + + the SQL/JSON path language + + + + + + + To learn more about the SQL/JSON standard, see + . For details on JSON types + supported in PostgreSQL, + see . + + + + Processing and Creating JSON Data + + + shows the operators that + are available for use with JSON data types (see ). + In addition, the usual comparison operators shown in are available for + jsonb, though not for json. The comparison + operators follow the ordering rules for B-tree operations outlined in + . + + + + <type>json</type> and <type>jsonb</type> Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + json -> integer + json + + + jsonb -> integer + jsonb + + + Extracts n'th element of JSON array + (array elements are indexed from zero, but negative integers count + from the end). + + + '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> 2 + {"c":"baz"} + + + '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -> -3 + {"a":"foo"} + + + + + + json -> text + json + + + jsonb -> text + jsonb + + + Extracts JSON object field with the given key. + + + '{"a": {"b":"foo"}}'::json -> 'a' + {"b":"foo"} + + + + + + json ->> integer + text + + + jsonb ->> integer + text + + + Extracts n'th element of JSON array, + as text. + + + '[1,2,3]'::json ->> 2 + 3 + + + + + + json ->> text + text + + + jsonb ->> text + text + + + Extracts JSON object field with the given key, as text. + + + '{"a":1,"b":2}'::json ->> 'b' + 2 + + + + + + json #> text[] + json + + + jsonb #> text[] + jsonb + + + Extracts JSON sub-object at the specified path, where path elements + can be either field keys or array indexes. + + + '{"a": {"b": ["foo","bar"]}}'::json #> '{a,b,1}' + "bar" + + + + + + json #>> text[] + text + + + jsonb #>> text[] + text + + + Extracts JSON sub-object at the specified path as text. + + + '{"a": {"b": ["foo","bar"]}}'::json #>> '{a,b,1}' + bar + + + + +
+ + + + The field/element/path extraction operators return NULL, rather than + failing, if the JSON input does not have the right structure to match + the request; for example if no such key or array element exists. + + + + + Some further operators exist only for jsonb, as shown + in . + + describes how these operators can be used to effectively search indexed + jsonb data. + + + + Additional <type>jsonb</type> Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + jsonb @> jsonb + boolean + + + Does the first JSON value contain the second? + (See for details about containment.) + + + '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb + t + + + + + + jsonb <@ jsonb + boolean + + + Is the first JSON value contained in the second? + + + '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb + t + + + + + + jsonb ? text + boolean + + + Does the text string exist as a top-level key or array element within + the JSON value? + + + '{"a":1, "b":2}'::jsonb ? 'b' + t + + + '["a", "b", "c"]'::jsonb ? 'b' + t + + + + + + jsonb ?| text[] + boolean + + + Do any of the strings in the text array exist as top-level keys or + array elements? + + + '{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd'] + t + + + + + + jsonb ?& text[] + boolean + + + Do all of the strings in the text array exist as top-level keys or + array elements? + + + '["a", "b", "c"]'::jsonb ?& array['a', 'b'] + t + + + + + + jsonb || jsonb + jsonb + + + Concatenates two jsonb values. + Concatenating two arrays generates an array containing all the + elements of each input. Concatenating two objects generates an + object containing the union of their + keys, taking the second object's value when there are duplicate keys. + All other cases are treated by converting a non-array input into a + single-element array, and then proceeding as for two arrays. + Does not operate recursively: only the top-level array or object + structure is merged. + + + '["a", "b"]'::jsonb || '["a", "d"]'::jsonb + ["a", "b", "a", "d"] + + + '{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb + {"a": "b", "c": "d"} + + + '[1, 2]'::jsonb || '3'::jsonb + [1, 2, 3] + + + '{"a": "b"}'::jsonb || '42'::jsonb + [{"a": "b"}, 42] + + + To append an array to another array as a single entry, wrap it + in an additional layer of array, for example: + + + '[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb) + [1, 2, [3, 4]] + + + + + + jsonb - text + jsonb + + + Deletes a key (and its value) from a JSON object, or matching string + value(s) from a JSON array. + + + '{"a": "b", "c": "d"}'::jsonb - 'a' + {"c": "d"} + + + '["a", "b", "c", "b"]'::jsonb - 'b' + ["a", "c"] + + + + + + jsonb - text[] + jsonb + + + Deletes all matching keys or array elements from the left operand. + + + '{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[] + {} + + + + + + jsonb - integer + jsonb + + + Deletes the array element with specified index (negative + integers count from the end). Throws an error if JSON value + is not an array. + + + '["a", "b"]'::jsonb - 1 + ["a"] + + + + + + jsonb #- text[] + jsonb + + + Deletes the field or array element at the specified path, where path + elements can be either field keys or array indexes. + + + '["a", {"b":1}]'::jsonb #- '{1,b}' + ["a", {}] + + + + + + jsonb @? jsonpath + boolean + + + Does JSON path return any item for the specified JSON value? + + + '{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' + t + + + + + + jsonb @@ jsonpath + boolean + + + Returns the result of a JSON path predicate check for the + specified JSON value. Only the first item of the result is taken into + account. If the result is not Boolean, then NULL + is returned. + + + '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' + t + + + + +
+ + + + The jsonpath operators @? + and @@ suppress the following errors: missing object + field or array element, unexpected JSON item type, datetime and numeric + errors. The jsonpath-related functions described below can + also be told to suppress these types of errors. This behavior might be + helpful when searching JSON document collections of varying structure. + + + + + shows the functions that are + available for constructing json and jsonb values. + + + + JSON Creation Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + to_json + + to_json ( anyelement ) + json + + + + to_jsonb + + to_jsonb ( anyelement ) + jsonb + + + Converts any SQL value to json or jsonb. + Arrays and composites are converted recursively to arrays and + objects (multidimensional arrays become arrays of arrays in JSON). + Otherwise, if there is a cast from the SQL data type + to json, the cast function will be used to perform the + conversion; + + For example, the extension has a cast + from hstore to json, so that + hstore values converted via the JSON creation functions + will be represented as JSON objects, not as primitive string values. + + + otherwise, a scalar JSON value is produced. For any scalar other than + a number, a Boolean, or a null value, the text representation will be + used, with escaping as necessary to make it a valid JSON string value. + + + to_json('Fred said "Hi."'::text) + "Fred said \"Hi.\"" + + + to_jsonb(row(42, 'Fred said "Hi."'::text)) + {"f1": 42, "f2": "Fred said \"Hi.\""} + + + + + + + array_to_json + + array_to_json ( anyarray , boolean ) + json + + + Converts an SQL array to a JSON array. The behavior is the same + as to_json except that line feeds will be added + between top-level array elements if the optional boolean parameter is + true. + + + array_to_json('{{1,5},{99,100}}'::int[]) + [[1,5],[99,100]] + + + + + + + row_to_json + + row_to_json ( record , boolean ) + json + + + Converts an SQL composite value to a JSON object. The behavior is the + same as to_json except that line feeds will be + added between top-level elements if the optional boolean parameter is + true. + + + row_to_json(row(1,'foo')) + {"f1":1,"f2":"foo"} + + + + + + + json_build_array + + json_build_array ( VARIADIC "any" ) + json + + + + jsonb_build_array + + jsonb_build_array ( VARIADIC "any" ) + jsonb + + + Builds a possibly-heterogeneously-typed JSON array out of a variadic + argument list. Each argument is converted as + per to_json or to_jsonb. + + + json_build_array(1, 2, 'foo', 4, 5) + [1, 2, "foo", 4, 5] + + + + + + + json_build_object + + json_build_object ( VARIADIC "any" ) + json + + + + jsonb_build_object + + jsonb_build_object ( VARIADIC "any" ) + jsonb + + + Builds a JSON object out of a variadic argument list. By convention, + the argument list consists of alternating keys and values. Key + arguments are coerced to text; value arguments are converted as + per to_json or to_jsonb. + + + json_build_object('foo', 1, 2, row(3,'bar')) + {"foo" : 1, "2" : {"f1":3,"f2":"bar"}} + + + + + + + json_object + + json_object ( text[] ) + json + + + + jsonb_object + + jsonb_object ( text[] ) + jsonb + + + Builds a JSON object out of a text array. The array must have either + exactly one dimension with an even number of members, in which case + they are taken as alternating key/value pairs, or two dimensions + such that each inner array has exactly two elements, which + are taken as a key/value pair. All values are converted to JSON + strings. + + + json_object('{a, 1, b, "def", c, 3.5}') + {"a" : "1", "b" : "def", "c" : "3.5"} + + json_object('{{a, 1}, {b, "def"}, {c, 3.5}}') + {"a" : "1", "b" : "def", "c" : "3.5"} + + + + + + json_object ( keys text[], values text[] ) + json + + + jsonb_object ( keys text[], values text[] ) + jsonb + + + This form of json_object takes keys and values + pairwise from separate text arrays. Otherwise it is identical to + the one-argument form. + + + json_object('{a,b}', '{1,2}') + {"a": "1", "b": "2"} + + + + +
+ + + shows the functions that + are available for processing json and jsonb values. + + + + JSON Processing Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + json_array_elements + + json_array_elements ( json ) + setof json + + + + jsonb_array_elements + + jsonb_array_elements ( jsonb ) + setof jsonb + + + Expands the top-level JSON array into a set of JSON values. + + + select * from json_array_elements('[1,true, [2,false]]') + + + value +----------- + 1 + true + [2,false] + + + + + + + + json_array_elements_text + + json_array_elements_text ( json ) + setof text + + + + jsonb_array_elements_text + + jsonb_array_elements_text ( jsonb ) + setof text + + + Expands the top-level JSON array into a set of text values. + + + select * from json_array_elements_text('["foo", "bar"]') + + + value +----------- + foo + bar + + + + + + + + json_array_length + + json_array_length ( json ) + integer + + + + jsonb_array_length + + jsonb_array_length ( jsonb ) + integer + + + Returns the number of elements in the top-level JSON array. + + + json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]') + 5 + + + + + + + json_each + + json_each ( json ) + setof record + ( key text, + value json ) + + + + jsonb_each + + jsonb_each ( jsonb ) + setof record + ( key text, + value jsonb ) + + + Expands the top-level JSON object into a set of key/value pairs. + + + select * from json_each('{"a":"foo", "b":"bar"}') + + + key | value +-----+------- + a | "foo" + b | "bar" + + + + + + + + json_each_text + + json_each_text ( json ) + setof record + ( key text, + value text ) + + + + jsonb_each_text + + jsonb_each_text ( jsonb ) + setof record + ( key text, + value text ) + + + Expands the top-level JSON object into a set of key/value pairs. + The returned values will be of + type text. + + + select * from json_each_text('{"a":"foo", "b":"bar"}') + + + key | value +-----+------- + a | foo + b | bar + + + + + + + + json_extract_path + + json_extract_path ( from_json json, VARIADIC path_elems text[] ) + json + + + + jsonb_extract_path + + jsonb_extract_path ( from_json jsonb, VARIADIC path_elems text[] ) + jsonb + + + Extracts JSON sub-object at the specified path. + (This is functionally equivalent to the #> + operator, but writing the path out as a variadic list can be more + convenient in some cases.) + + + json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6') + "foo" + + + + + + + json_extract_path_text + + json_extract_path_text ( from_json json, VARIADIC path_elems text[] ) + text + + + + jsonb_extract_path_text + + jsonb_extract_path_text ( from_json jsonb, VARIADIC path_elems text[] ) + text + + + Extracts JSON sub-object at the specified path as text. + (This is functionally equivalent to the #>> + operator.) + + + json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6') + foo + + + + + + + json_object_keys + + json_object_keys ( json ) + setof text + + + + jsonb_object_keys + + jsonb_object_keys ( jsonb ) + setof text + + + Returns the set of keys in the top-level JSON object. + + + select * from json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') + + + json_object_keys +------------------ + f1 + f2 + + + + + + + + json_populate_record + + json_populate_record ( base anyelement, from_json json ) + anyelement + + + + jsonb_populate_record + + jsonb_populate_record ( base anyelement, from_json jsonb ) + anyelement + + + Expands the top-level JSON object to a row having the composite type + of the base argument. The JSON object + is scanned for fields whose names match column names of the output row + type, and their values are inserted into those columns of the output. + (Fields that do not correspond to any output column name are ignored.) + In typical use, the value of base is just + NULL, which means that any output columns that do + not match any object field will be filled with nulls. However, + if base isn't NULL then + the values it contains will be used for unmatched columns. + + + To convert a JSON value to the SQL type of an output column, the + following rules are applied in sequence: + + + + A JSON null value is converted to an SQL null in all cases. + + + + + If the output column is of type json + or jsonb, the JSON value is just reproduced exactly. + + + + + If the output column is a composite (row) type, and the JSON value + is a JSON object, the fields of the object are converted to columns + of the output row type by recursive application of these rules. + + + + + Likewise, if the output column is an array type and the JSON value + is a JSON array, the elements of the JSON array are converted to + elements of the output array by recursive application of these + rules. + + + + + Otherwise, if the JSON value is a string, the contents of the + string are fed to the input conversion function for the column's + data type. + + + + + Otherwise, the ordinary text representation of the JSON value is + fed to the input conversion function for the column's data type. + + + + + + While the example below uses a constant JSON value, typical use would + be to reference a json or jsonb column + laterally from another table in the query's FROM + clause. Writing json_populate_record in + the FROM clause is good practice, since all of the + extracted columns are available for use without duplicate function + calls. + + + create type subrowtype as (d int, e text); + create type myrowtype as (a int, b text[], c subrowtype); + + + select * from json_populate_record(null::myrowtype, + '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}, "x": "foo"}') + + + a | b | c +---+-----------+------------- + 1 | {2,"a b"} | (4,"a b c") + + + + + + + + json_populate_recordset + + json_populate_recordset ( base anyelement, from_json json ) + setof anyelement + + + + jsonb_populate_recordset + + jsonb_populate_recordset ( base anyelement, from_json jsonb ) + setof anyelement + + + Expands the top-level JSON array of objects to a set of rows having + the composite type of the base argument. + Each element of the JSON array is processed as described above + for json[b]_populate_record. + + + create type twoints as (a int, b int); + + + select * from json_populate_recordset(null::twoints, '[{"a":1,"b":2}, {"a":3,"b":4}]') + + + a | b +---+--- + 1 | 2 + 3 | 4 + + + + + + + + json_to_record + + json_to_record ( json ) + record + + + + jsonb_to_record + + jsonb_to_record ( jsonb ) + record + + + Expands the top-level JSON object to a row having the composite type + defined by an AS clause. (As with all functions + returning record, the calling query must explicitly + define the structure of the record with an AS + clause.) The output record is filled from fields of the JSON object, + in the same way as described above + for json[b]_populate_record. Since there is no + input record value, unmatched columns are always filled with nulls. + + + create type myrowtype as (a int, b text); + + + select * from json_to_record('{"a":1,"b":[1,2,3],"c":[1,2,3],"e":"bar","r": {"a": 123, "b": "a b c"}}') as x(a int, b text, c int[], d text, r myrowtype) + + + a | b | c | d | r +---+---------+---------+---+--------------- + 1 | [1,2,3] | {1,2,3} | | (123,"a b c") + + + + + + + + json_to_recordset + + json_to_recordset ( json ) + setof record + + + + jsonb_to_recordset + + jsonb_to_recordset ( jsonb ) + setof record + + + Expands the top-level JSON array of objects to a set of rows having + the composite type defined by an AS clause. (As + with all functions returning record, the calling query + must explicitly define the structure of the record with + an AS clause.) Each element of the JSON array is + processed as described above + for json[b]_populate_record. + + + select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text) + + + a | b +---+----- + 1 | foo + 2 | + + + + + + + + jsonb_set + + jsonb_set ( target jsonb, path text[], new_value jsonb , create_if_missing boolean ) + jsonb + + + Returns target + with the item designated by path + replaced by new_value, or with + new_value added if + create_if_missing is true (which is the + default) and the item designated by path + does not exist. + All earlier steps in the path must exist, or + the target is returned unchanged. + As with the path oriented operators, negative integers that + appear in the path count from the end + of JSON arrays. + If the last path step is an array index that is out of range, + and create_if_missing is true, the new + value is added at the beginning of the array if the index is negative, + or at the end of the array if it is positive. + + + jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', '[2,3,4]', false) + [{"f1": [2, 3, 4], "f2": null}, 2, null, 3] + + + jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}', '[2,3,4]') + [{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2] + + + + + + + jsonb_set_lax + + jsonb_set_lax ( target jsonb, path text[], new_value jsonb , create_if_missing boolean , null_value_treatment text ) + jsonb + + + If new_value is not NULL, + behaves identically to jsonb_set. Otherwise behaves + according to the value + of null_value_treatment which must be one + of 'raise_exception', + 'use_json_null', 'delete_key', or + 'return_target'. The default is + 'use_json_null'. + + + jsonb_set_lax('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', null) + [{"f1":null,"f2":null},2,null,3] + + + jsonb_set_lax('[{"f1":99,"f2":null},2]', '{0,f3}', null, true, 'return_target') + [{"f1": 99, "f2": null}, 2] + + + + + + + jsonb_insert + + jsonb_insert ( target jsonb, path text[], new_value jsonb , insert_after boolean ) + jsonb + + + Returns target + with new_value inserted. If the item + designated by the path is an array + element, new_value will be inserted before + that item if insert_after is false (which + is the default), or after it + if insert_after is true. If the item + designated by the path is an object + field, new_value will be inserted only if + the object does not already contain that key. + All earlier steps in the path must exist, or + the target is returned unchanged. + As with the path oriented operators, negative integers that + appear in the path count from the end + of JSON arrays. + If the last path step is an array index that is out of range, the new + value is added at the beginning of the array if the index is negative, + or at the end of the array if it is positive. + + + jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"') + {"a": [0, "new_value", 1, 2]} + + + jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true) + {"a": [0, 1, "new_value", 2]} + + + + + + + json_strip_nulls + + json_strip_nulls ( json ) + json + + + + jsonb_strip_nulls + + jsonb_strip_nulls ( jsonb ) + jsonb + + + Deletes all object fields that have null values from the given JSON + value, recursively. Null values that are not object fields are + untouched. + + + json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]') + [{"f1":1},2,null,3] + + + + + + + jsonb_path_exists + + jsonb_path_exists ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + boolean + + + Checks whether the JSON path returns any item for the specified JSON + value. + If the vars argument is specified, it must + be a JSON object, and its fields provide named values to be + substituted into the jsonpath expression. + If the silent argument is specified and + is true, the function suppresses the same errors + as the @? and @@ operators do. + + + jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') + t + + + + + + + jsonb_path_match + + jsonb_path_match ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + boolean + + + Returns the result of a JSON path predicate check for the specified + JSON value. Only the first item of the result is taken into account. + If the result is not Boolean, then NULL is returned. + The optional vars + and silent arguments act the same as + for jsonb_path_exists. + + + jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2, "max":4}') + t + + + + + + + jsonb_path_query + + jsonb_path_query ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + setof jsonb + + + Returns all JSON items returned by the JSON path for the specified + JSON value. + The optional vars + and silent arguments act the same as + for jsonb_path_exists. + + + select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') + + + jsonb_path_query +------------------ + 2 + 3 + 4 + + + + + + + + jsonb_path_query_array + + jsonb_path_query_array ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + jsonb + + + Returns all JSON items returned by the JSON path for the specified + JSON value, as a JSON array. + The optional vars + and silent arguments act the same as + for jsonb_path_exists. + + + jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') + [2, 3, 4] + + + + + + + jsonb_path_query_first + + jsonb_path_query_first ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + jsonb + + + Returns the first JSON item returned by the JSON path for the + specified JSON value. Returns NULL if there are no + results. + The optional vars + and silent arguments act the same as + for jsonb_path_exists. + + + jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}') + 2 + + + + + + + jsonb_path_exists_tz + + jsonb_path_exists_tz ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + boolean + + + + jsonb_path_match_tz + + jsonb_path_match_tz ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + boolean + + + + jsonb_path_query_tz + + jsonb_path_query_tz ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + setof jsonb + + + + jsonb_path_query_array_tz + + jsonb_path_query_array_tz ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + jsonb + + + + jsonb_path_query_first_tz + + jsonb_path_query_first_tz ( target jsonb, path jsonpath , vars jsonb , silent boolean ) + jsonb + + + These functions act like their counterparts described above without + the _tz suffix, except that these functions support + comparisons of date/time values that require timezone-aware + conversions. The example below requires interpretation of the + date-only value 2015-08-02 as a timestamp with time + zone, so the result depends on the current + setting. Due to this dependency, these + functions are marked as stable, which means these functions cannot be + used in indexes. Their counterparts are immutable, and so can be used + in indexes; but they will throw errors if asked to make such + comparisons. + + + jsonb_path_exists_tz('["2015-08-01 12:00:00 -05"]', '$[*] ? (@.datetime() < "2015-08-02".datetime())') + t + + + + + + + jsonb_pretty + + jsonb_pretty ( jsonb ) + text + + + Converts the given JSON value to pretty-printed, indented text. + + + jsonb_pretty('[{"f1":1,"f2":null}, 2]') + + +[ + { + "f1": 1, + "f2": null + }, + 2 +] + + + + + + + + json_typeof + + json_typeof ( json ) + text + + + + jsonb_typeof + + jsonb_typeof ( jsonb ) + text + + + Returns the type of the top-level JSON value as a text string. + Possible types are + object, array, + string, number, + boolean, and null. + (The null result should not be confused + with an SQL NULL; see the examples.) + + + json_typeof('-123.4') + number + + + json_typeof('null'::json) + null + + + json_typeof(NULL::json) IS NULL + t + + + + +
+ + + See also for the aggregate + function json_agg which aggregates record + values as JSON, the aggregate function + json_object_agg which aggregates pairs of values + into a JSON object, and their jsonb equivalents, + jsonb_agg and jsonb_object_agg. + +
+ + + The SQL/JSON Path Language + + + SQL/JSON path language + + + + SQL/JSON path expressions specify the items to be retrieved + from the JSON data, similar to XPath expressions used + for SQL access to XML. In PostgreSQL, + path expressions are implemented as the jsonpath + data type and can use any elements described in + . + + + + JSON query functions and operators + pass the provided path expression to the path engine + for evaluation. If the expression matches the queried JSON data, + the corresponding JSON item, or set of items, is returned. + Path expressions are written in the SQL/JSON path language + and can include arithmetic expressions and functions. + + + + A path expression consists of a sequence of elements allowed + by the jsonpath data type. + The path expression is normally evaluated from left to right, but + you can use parentheses to change the order of operations. + If the evaluation is successful, a sequence of JSON items is produced, + and the evaluation result is returned to the JSON query function + that completes the specified computation. + + + + To refer to the JSON value being queried (the + context item), use the $ variable + in the path expression. It can be followed by one or more + accessor operators, + which go down the JSON structure level by level to retrieve sub-items + of the context item. Each operator that follows deals with the + result of the previous evaluation step. + + + + For example, suppose you have some JSON data from a GPS tracker that you + would like to parse, such as: + +{ + "track": { + "segments": [ + { + "location": [ 47.763, 13.4034 ], + "start time": "2018-10-14 10:05:14", + "HR": 73 + }, + { + "location": [ 47.706, 13.2635 ], + "start time": "2018-10-14 10:39:21", + "HR": 135 + } + ] + } +} + + + + + To retrieve the available track segments, you need to use the + .key accessor + operator to descend through surrounding JSON objects: + +$.track.segments + + + + + To retrieve the contents of an array, you typically use the + [*] operator. For example, + the following path will return the location coordinates for all + the available track segments: + +$.track.segments[*].location + + + + + To return the coordinates of the first segment only, you can + specify the corresponding subscript in the [] + accessor operator. Recall that JSON array indexes are 0-relative: + +$.track.segments[0].location + + + + + The result of each path evaluation step can be processed + by one or more jsonpath operators and methods + listed in . + Each method name must be preceded by a dot. For example, + you can get the size of an array: + +$.track.segments.size() + + More examples of using jsonpath operators + and methods within path expressions appear below in + . + + + + When defining a path, you can also use one or more + filter expressions that work similarly to the + WHERE clause in SQL. A filter expression begins with + a question mark and provides a condition in parentheses: + + +? (condition) + + + + + Filter expressions must be written just after the path evaluation step + to which they should apply. The result of that step is filtered to include + only those items that satisfy the provided condition. SQL/JSON defines + three-valued logic, so the condition can be true, false, + or unknown. The unknown value + plays the same role as SQL NULL and can be tested + for with the is unknown predicate. Further path + evaluation steps use only those items for which the filter expression + returned true. + + + + The functions and operators that can be used in filter expressions are + listed in . Within a + filter expression, the @ variable denotes the value + being filtered (i.e., one result of the preceding path step). You can + write accessor operators after @ to retrieve component + items. + + + + For example, suppose you would like to retrieve all heart rate values higher + than 130. You can achieve this using the following expression: + +$.track.segments[*].HR ? (@ > 130) + + + + + To get the start times of segments with such values, you have to + filter out irrelevant segments before returning the start times, so the + filter expression is applied to the previous step, and the path used + in the condition is different: + +$.track.segments[*] ? (@.HR > 130)."start time" + + + + + You can use several filter expressions in sequence, if required. For + example, the following expression selects start times of all segments that + contain locations with relevant coordinates and high heart rate values: + +$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time" + + + + + Using filter expressions at different nesting levels is also allowed. + The following example first filters all segments by location, and then + returns high heart rate values for these segments, if available: + +$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130) + + + + + You can also nest filter expressions within each other: + +$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size() + + This expression returns the size of the track if it contains any + segments with high heart rate values, or an empty sequence otherwise. + + + + PostgreSQL's implementation of the SQL/JSON path + language has the following deviations from the SQL/JSON standard: + + + + + + A path expression can be a Boolean predicate, although the SQL/JSON + standard allows predicates only in filters. This is necessary for + implementation of the @@ operator. For example, + the following jsonpath expression is valid in + PostgreSQL: + +$.track.segments[*].HR < 70 + + + + + + + There are minor differences in the interpretation of regular + expression patterns used in like_regex filters, as + described in . + + + + + + Strict and Lax Modes + + When you query JSON data, the path expression may not match the + actual JSON data structure. An attempt to access a non-existent + member of an object or element of an array results in a + structural error. SQL/JSON path expressions have two modes + of handling structural errors: + + + + + + lax (default) — the path engine implicitly adapts + the queried data to the specified path. + Any remaining structural errors are suppressed and converted + to empty SQL/JSON sequences. + + + + + strict — if a structural error occurs, an error is raised. + + + + + + The lax mode facilitates matching of a JSON document structure and path + expression if the JSON data does not conform to the expected schema. + If an operand does not match the requirements of a particular operation, + it can be automatically wrapped as an SQL/JSON array or unwrapped by + converting its elements into an SQL/JSON sequence before performing + this operation. Besides, comparison operators automatically unwrap their + operands in the lax mode, so you can compare SQL/JSON arrays + out-of-the-box. An array of size 1 is considered equal to its sole element. + Automatic unwrapping is not performed only when: + + + + The path expression contains type() or + size() methods that return the type + and the number of elements in the array, respectively. + + + + + The queried JSON data contain nested arrays. In this case, only + the outermost array is unwrapped, while all the inner arrays + remain unchanged. Thus, implicit unwrapping can only go one + level down within each path evaluation step. + + + + + + + For example, when querying the GPS data listed above, you can + abstract from the fact that it stores an array of segments + when using the lax mode: + +lax $.track.segments.location + + + + + In the strict mode, the specified path must exactly match the structure of + the queried JSON document to return an SQL/JSON item, so using this + path expression will cause an error. To get the same result as in + the lax mode, you have to explicitly unwrap the + segments array: + +strict $.track.segments[*].location + + + + + The .** accessor can lead to surprising results + when using the lax mode. For instance, the following query selects every + HR value twice: + +lax $.**.HR + + This happens because the .** accessor selects both + the segments array and each of its elements, while + the .HR accessor automatically unwraps arrays when + using the lax mode. To avoid surprising results, we recommend using + the .** accessor only in the strict mode. The + following query selects each HR value just once: + +strict $.**.HR + + + + + + + SQL/JSON Path Operators and Methods + + + shows the operators and + methods available in jsonpath. Note that while the unary + operators and methods can be applied to multiple values resulting from a + preceding path step, the binary operators (addition etc.) can only be + applied to single values. + + + + <type>jsonpath</type> Operators and Methods + + + + + Operator/Method + + + Description + + + Example(s) + + + + + + + + number + number + number + + + Addition + + + jsonb_path_query('[2]', '$[0] + 3') + 5 + + + + + + + number + number + + + Unary plus (no operation); unlike addition, this can iterate over + multiple values + + + jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x') + [2, 3, 4] + + + + + + number - number + number + + + Subtraction + + + jsonb_path_query('[2]', '7 - $[0]') + 5 + + + + + + - number + number + + + Negation; unlike subtraction, this can iterate over + multiple values + + + jsonb_path_query_array('{"x": [2,3,4]}', '- $.x') + [-2, -3, -4] + + + + + + number * number + number + + + Multiplication + + + jsonb_path_query('[4]', '2 * $[0]') + 8 + + + + + + number / number + number + + + Division + + + jsonb_path_query('[8.5]', '$[0] / 2') + 4.2500000000000000 + + + + + + number % number + number + + + Modulo (remainder) + + + jsonb_path_query('[32]', '$[0] % 10') + 2 + + + + + + value . type() + string + + + Type of the JSON item (see json_typeof) + + + jsonb_path_query_array('[1, "2", {}]', '$[*].type()') + ["number", "string", "object"] + + + + + + value . size() + number + + + Size of the JSON item (number of array elements, or 1 if not an + array) + + + jsonb_path_query('{"m": [11, 15]}', '$.m.size()') + 2 + + + + + + value . double() + number + + + Approximate floating-point number converted from a JSON number or + string + + + jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2') + 3.8 + + + + + + number . ceiling() + number + + + Nearest integer greater than or equal to the given number + + + jsonb_path_query('{"h": 1.3}', '$.h.ceiling()') + 2 + + + + + + number . floor() + number + + + Nearest integer less than or equal to the given number + + + jsonb_path_query('{"h": 1.7}', '$.h.floor()') + 1 + + + + + + number . abs() + number + + + Absolute value of the given number + + + jsonb_path_query('{"z": -0.3}', '$.z.abs()') + 0.3 + + + + + + string . datetime() + datetime_type + (see note) + + + Date/time value converted from a string + + + jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() < "2015-08-2".datetime())') + "2015-8-1" + + + + + + string . datetime(template) + datetime_type + (see note) + + + Date/time value converted from a string using the + specified to_timestamp template + + + jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")') + ["12:30:00", "18:40:00"] + + + + + + object . keyvalue() + array + + + The object's key-value pairs, represented as an array of objects + containing three fields: "key", + "value", and "id"; + "id" is a unique identifier of the object the + key-value pair belongs to + + + jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()') + [{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}] + + + + +
+ + + + The result type of the datetime() and + datetime(template) + methods can be date, timetz, time, + timestamptz, or timestamp. + Both methods determine their result type dynamically. + + + The datetime() method sequentially tries to + match its input string to the ISO formats + for date, timetz, time, + timestamptz, and timestamp. It stops on + the first matching format and emits the corresponding data type. + + + The datetime(template) + method determines the result type according to the fields used in the + provided template string. + + + The datetime() and + datetime(template) methods + use the same parsing rules as the to_timestamp SQL + function does (see ), with three + exceptions. First, these methods don't allow unmatched template + patterns. Second, only the following separators are allowed in the + template string: minus sign, period, solidus (slash), comma, apostrophe, + semicolon, colon and space. Third, separators in the template string + must exactly match the input string. + + + If different date/time types need to be compared, an implicit cast is + applied. A date value can be cast to timestamp + or timestamptz, timestamp can be cast to + timestamptz, and time to timetz. + However, all but the first of these conversions depend on the current + setting, and thus can only be performed + within timezone-aware jsonpath functions. + + + + + shows the available + filter expression elements. + + + + <type>jsonpath</type> Filter Expression Elements + + + + + Predicate/Value + + + Description + + + Example(s) + + + + + + + + value == value + boolean + + + Equality comparison (this, and the other comparison operators, work on + all JSON scalar values) + + + jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == 1)') + [1, 1] + + + jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == "a")') + ["a"] + + + + + + value != value + boolean + + + value <> value + boolean + + + Non-equality comparison + + + jsonb_path_query_array('[1, 2, 1, 3]', '$[*] ? (@ != 1)') + [2, 3] + + + jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <> "b")') + ["a", "c"] + + + + + + value < value + boolean + + + Less-than comparison + + + jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ < 2)') + [1] + + + + + + value <= value + boolean + + + Less-than-or-equal-to comparison + + + jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ <= "b")') + ["a", "b"] + + + + + + value > value + boolean + + + Greater-than comparison + + + jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ > 2)') + [3] + + + + + + value >= value + boolean + + + Greater-than-or-equal-to comparison + + + jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ >= 2)') + [2, 3] + + + + + + true + boolean + + + JSON constant true + + + jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == true)') + {"name": "Chris", "parent": true} + + + + + + false + boolean + + + JSON constant false + + + jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == false)') + {"name": "John", "parent": false} + + + + + + null + value + + + JSON constant null (note that, unlike in SQL, + comparison to null works normally) + + + jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name') + "Mary" + + + + + + boolean && boolean + boolean + + + Boolean AND + + + jsonb_path_query('[1, 3, 7]', '$[*] ? (@ > 1 && @ < 5)') + 3 + + + + + + boolean || boolean + boolean + + + Boolean OR + + + jsonb_path_query('[1, 3, 7]', '$[*] ? (@ < 1 || @ > 5)') + 7 + + + + + + ! boolean + boolean + + + Boolean NOT + + + jsonb_path_query('[1, 3, 7]', '$[*] ? (!(@ < 5))') + 7 + + + + + + boolean is unknown + boolean + + + Tests whether a Boolean condition is unknown. + + + jsonb_path_query('[-1, 2, 7, "foo"]', '$[*] ? ((@ > 0) is unknown)') + "foo" + + + + + + string like_regex string flag string + boolean + + + Tests whether the first operand matches the regular expression + given by the second operand, optionally with modifications + described by a string of flag characters (see + ). + + + jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")') + ["abc", "abdacb"] + + + jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c" flag "i")') + ["abc", "aBdC", "abdacb"] + + + + + + string starts with string + boolean + + + Tests whether the second operand is an initial substring of the first + operand. + + + jsonb_path_query('["John Smith", "Mary Stone", "Bob Johnson"]', '$[*] ? (@ starts with "John")') + "John Smith" + + + + + + exists ( path_expression ) + boolean + + + Tests whether a path expression matches at least one SQL/JSON item. + Returns unknown if the path expression would result + in an error; the second example uses this to avoid a no-such-key error + in strict mode. + + + jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] > 2)))') + [2, 4] + + + jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name') + [] + + + + +
+ +
+ + + SQL/JSON Regular Expressions + + + LIKE_REGEX + in SQL/JSON + + + + SQL/JSON path expressions allow matching text to a regular expression + with the like_regex filter. For example, the + following SQL/JSON path query would case-insensitively match all + strings in an array that start with an English vowel: + +$[*] ? (@ like_regex "^[aeiou]" flag "i") + + + + + The optional flag string may include one or more of + the characters + i for case-insensitive match, + m to allow ^ + and $ to match at newlines, + s to allow . to match a newline, + and q to quote the whole pattern (reducing the + behavior to a simple substring match). + + + + The SQL/JSON standard borrows its definition for regular expressions + from the LIKE_REGEX operator, which in turn uses the + XQuery standard. PostgreSQL does not currently support the + LIKE_REGEX operator. Therefore, + the like_regex filter is implemented using the + POSIX regular expression engine described in + . This leads to various minor + discrepancies from standard SQL/JSON behavior, which are cataloged in + . + Note, however, that the flag-letter incompatibilities described there + do not apply to SQL/JSON, as it translates the XQuery flag letters to + match what the POSIX engine expects. + + + + Keep in mind that the pattern argument of like_regex + is a JSON path string literal, written according to the rules given in + . This means in particular that any + backslashes you want to use in the regular expression must be doubled. + For example, to match string values of the root document that contain + only digits: + +$.* ? (@ like_regex "^\\d+$") + + + +
+
+ + + Sequence Manipulation Functions + + + sequence + + + + This section describes functions for operating on sequence + objects, also called sequence generators or just sequences. + Sequence objects are special single-row tables created with . + Sequence objects are commonly used to generate unique identifiers + for rows of a table. The sequence functions, listed in , provide simple, multiuser-safe + methods for obtaining successive sequence values from sequence + objects. + + + + Sequence Functions + + + + + Function + + + Description + + + + + + + + + nextval + + nextval ( regclass ) + bigint + + + Advances the sequence object to its next value and returns that value. + This is done atomically: even if multiple sessions + execute nextval concurrently, each will safely + receive a distinct sequence value. + If the sequence object has been created with default parameters, + successive nextval calls will return successive + values beginning with 1. Other behaviors can be obtained by using + appropriate parameters in the + command. + + + This function requires USAGE + or UPDATE privilege on the sequence. + + + + + + + setval + + setval ( regclass, bigint , boolean ) + bigint + + + Sets the sequence object's current value, and optionally + its is_called flag. The two-parameter + form sets the sequence's last_value field to the + specified value and sets its is_called field to + true, meaning that the next + nextval will advance the sequence before + returning a value. The value that will be reported + by currval is also set to the specified value. + In the three-parameter form, is_called can be set + to either true + or false. true has the same + effect as the two-parameter form. If it is set + to false, the next nextval + will return exactly the specified value, and sequence advancement + commences with the following nextval. + Furthermore, the value reported by currval is not + changed in this case. For example, + +SELECT setval('myseq', 42); Next nextval will return 43 +SELECT setval('myseq', 42, true); Same as above +SELECT setval('myseq', 42, false); Next nextval will return 42 + + The result returned by setval is just the value of its + second argument. + + + This function requires UPDATE privilege on the + sequence. + + + + + + + currval + + currval ( regclass ) + bigint + + + Returns the value most recently obtained + by nextval for this sequence in the current + session. (An error is reported if nextval has + never been called for this sequence in this session.) Because this is + returning a session-local value, it gives a predictable answer whether + or not other sessions have executed nextval since + the current session did. + + + This function requires USAGE + or SELECT privilege on the sequence. + + + + + + + lastval + + lastval () + bigint + + + Returns the value most recently returned by + nextval in the current session. This function is + identical to currval, except that instead + of taking the sequence name as an argument it refers to whichever + sequence nextval was most recently applied to + in the current session. It is an error to call + lastval if nextval + has not yet been called in the current session. + + + This function requires USAGE + or SELECT privilege on the last used sequence. + + + + +
+ + + + To avoid blocking concurrent transactions that obtain numbers from + the same sequence, a nextval operation is never + rolled back; that is, once a value has been fetched it is considered + used and will not be returned again. This is true even if the + surrounding transaction later aborts, or if the calling query ends + up not using the value. For example an INSERT with + an ON CONFLICT clause will compute the to-be-inserted + tuple, including doing any required nextval + calls, before detecting any conflict that would cause it to follow + the ON CONFLICT rule instead. Such cases will leave + unused holes in the sequence of assigned values. + Thus, PostgreSQL sequence + objects cannot be used to obtain gapless + sequences. + + + + Likewise, any sequence state changes made by setval + are not undone if the transaction rolls back. + + + + + The sequence to be operated on by a sequence function is specified by + a regclass argument, which is simply the OID of the sequence in the + pg_class system catalog. You do not have to look up the + OID by hand, however, since the regclass data type's input + converter will do the work for you. See + for details. + +
+ + + + Conditional Expressions + + + CASE + + + + conditional expression + + + + This section describes the SQL-compliant conditional expressions + available in PostgreSQL. + + + + + If your needs go beyond the capabilities of these conditional + expressions, you might want to consider writing a server-side function + in a more expressive programming language. + + + + + + Although COALESCE, GREATEST, and + LEAST are syntactically similar to functions, they are + not ordinary functions, and thus cannot be used with explicit + VARIADIC array arguments. + + + + + <literal>CASE</literal> + + + The SQL CASE expression is a + generic conditional expression, similar to if/else statements in + other programming languages: + + +CASE WHEN condition THEN result + WHEN ... + ELSE result +END + + + CASE clauses can be used wherever + an expression is valid. Each condition is an + expression that returns a boolean result. If the condition's + result is true, the value of the CASE expression is the + result that follows the condition, and the + remainder of the CASE expression is not processed. If the + condition's result is not true, any subsequent WHEN clauses + are examined in the same manner. If no WHEN + condition yields true, the value of the + CASE expression is the result of the + ELSE clause. If the ELSE clause is + omitted and no condition is true, the result is null. + + + + An example: + +SELECT * FROM test; + + a +--- + 1 + 2 + 3 + + +SELECT a, + CASE WHEN a=1 THEN 'one' + WHEN a=2 THEN 'two' + ELSE 'other' + END + FROM test; + + a | case +---+------- + 1 | one + 2 | two + 3 | other + + + + + The data types of all the result + expressions must be convertible to a single output type. + See for more details. + + + + There is a simple form of CASE expression + that is a variant of the general form above: + + +CASE expression + WHEN value THEN result + WHEN ... + ELSE result +END + + + The first + expression is computed, then compared to + each of the value expressions in the + WHEN clauses until one is found that is equal to it. If + no match is found, the result of the + ELSE clause (or a null value) is returned. This is similar + to the switch statement in C. + + + + The example above can be written using the simple + CASE syntax: + +SELECT a, + CASE a WHEN 1 THEN 'one' + WHEN 2 THEN 'two' + ELSE 'other' + END + FROM test; + + a | case +---+------- + 1 | one + 2 | two + 3 | other + + + + + A CASE expression does not evaluate any subexpressions + that are not needed to determine the result. For example, this is a + possible way of avoiding a division-by-zero failure: + +SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END; + + + + + + As described in , there are various + situations in which subexpressions of an expression are evaluated at + different times, so that the principle that CASE + evaluates only necessary subexpressions is not ironclad. For + example a constant 1/0 subexpression will usually result in + a division-by-zero failure at planning time, even if it's within + a CASE arm that would never be entered at run time. + + + + + + <literal>COALESCE</literal> + + + COALESCE + + + + NVL + + + + IFNULL + + + +COALESCE(value , ...) + + + + The COALESCE function returns the first of its + arguments that is not null. Null is returned only if all arguments + are null. It is often used to substitute a default value for + null values when data is retrieved for display, for example: + +SELECT COALESCE(description, short_description, '(none)') ... + + This returns description if it is not null, otherwise + short_description if it is not null, otherwise (none). + + + + The arguments must all be convertible to a common data type, which + will be the type of the result (see + for details). + + + + Like a CASE expression, COALESCE only + evaluates the arguments that are needed to determine the result; + that is, arguments to the right of the first non-null argument are + not evaluated. This SQL-standard function provides capabilities similar + to NVL and IFNULL, which are used in some other + database systems. + + + + + <literal>NULLIF</literal> + + + NULLIF + + + +NULLIF(value1, value2) + + + + The NULLIF function returns a null value if + value1 equals value2; + otherwise it returns value1. + This can be used to perform the inverse operation of the + COALESCE example given above: + +SELECT NULLIF(value, '(none)') ... + + In this example, if value is (none), + null is returned, otherwise the value of value + is returned. + + + + The two arguments must be of comparable types. + To be specific, they are compared exactly as if you had + written value1 + = value2, so there must be a + suitable = operator available. + + + + The result has the same type as the first argument — but there is + a subtlety. What is actually returned is the first argument of the + implied = operator, and in some cases that will have + been promoted to match the second argument's type. For + example, NULLIF(1, 2.2) yields numeric, + because there is no integer = + numeric operator, + only numeric = numeric. + + + + + + <literal>GREATEST</literal> and <literal>LEAST</literal> + + + GREATEST + + + LEAST + + + +GREATEST(value , ...) + + +LEAST(value , ...) + + + + The GREATEST and LEAST functions select the + largest or smallest value from a list of any number of expressions. + The expressions must all be convertible to a common data type, which + will be the type of the result + (see for details). NULL values + in the list are ignored. The result will be NULL only if all the + expressions evaluate to NULL. + + + + Note that GREATEST and LEAST are not in + the SQL standard, but are a common extension. Some other databases + make them return NULL if any argument is NULL, rather than only when + all are NULL. + + + + + + Array Functions and Operators + + + shows the specialized operators + available for array types. + In addition to those, the usual comparison operators shown in are available for + arrays. The comparison operators compare the array contents + element-by-element, using the default B-tree comparison function for + the element data type, and sort based on the first difference. + In multidimensional arrays the elements are visited in row-major order + (last subscript varies most rapidly). + If the contents of two arrays are equal but the dimensionality is + different, the first difference in the dimensionality information + determines the sort order. + + + + Array Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + anyarray @> anyarray + boolean + + + Does the first array contain the second, that is, does each element + appearing in the second array equal some element of the first array? + (Duplicates are not treated specially, + thus ARRAY[1] and ARRAY[1,1] are + each considered to contain the other.) + + + ARRAY[1,4,3] @> ARRAY[3,1,3] + t + + + + + + anyarray <@ anyarray + boolean + + + Is the first array contained by the second? + + + ARRAY[2,2,7] <@ ARRAY[1,7,4,2,6] + t + + + + + + anyarray && anyarray + boolean + + + Do the arrays overlap, that is, have any elements in common? + + + ARRAY[1,4,3] && ARRAY[2,1] + t + + + + + + anycompatiblearray || anycompatiblearray + anycompatiblearray + + + Concatenates the two arrays. Concatenating a null or empty array is a + no-op; otherwise the arrays must have the same number of dimensions + (as illustrated by the first example) or differ in number of + dimensions by one (as illustrated by the second). + If the arrays are not of identical element types, they will be coerced + to a common type (see ). + + + ARRAY[1,2,3] || ARRAY[4,5,6,7] + {1,2,3,4,5,6,7} + + + ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9.9]] + {{1,2,3},{4,5,6},{7,8,9.9}} + + + + + + anycompatible || anycompatiblearray + anycompatiblearray + + + Concatenates an element onto the front of an array (which must be + empty or one-dimensional). + + + 3 || ARRAY[4,5,6] + {3,4,5,6} + + + + + + anycompatiblearray || anycompatible + anycompatiblearray + + + Concatenates an element onto the end of an array (which must be + empty or one-dimensional). + + + ARRAY[4,5,6] || 7 + {4,5,6,7} + + + + +
+ + + See for more details about array operator + behavior. See for more details about + which operators support indexed operations. + + + + shows the functions + available for use with array types. See + for more information and examples of the use of these functions. + + + + Array Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + array_append + + array_append ( anycompatiblearray, anycompatible ) + anycompatiblearray + + + Appends an element to the end of an array (same as + the anycompatiblearray || anycompatible + operator). + + + array_append(ARRAY[1,2], 3) + {1,2,3} + + + + + + + array_cat + + array_cat ( anycompatiblearray, anycompatiblearray ) + anycompatiblearray + + + Concatenates two arrays (same as + the anycompatiblearray || anycompatiblearray + operator). + + + array_cat(ARRAY[1,2,3], ARRAY[4,5]) + {1,2,3,4,5} + + + + + + + array_dims + + array_dims ( anyarray ) + text + + + Returns a text representation of the array's dimensions. + + + array_dims(ARRAY[[1,2,3], [4,5,6]]) + [1:2][1:3] + + + + + + + array_fill + + array_fill ( anyelement, integer[] + , integer[] ) + anyarray + + + Returns an array filled with copies of the given value, having + dimensions of the lengths specified by the second argument. + The optional third argument supplies lower-bound values for each + dimension (which default to all 1). + + + array_fill(11, ARRAY[2,3]) + {{11,11,11},{11,11,11}} + + + array_fill(7, ARRAY[3], ARRAY[2]) + [2:4]={7,7,7} + + + + + + + array_length + + array_length ( anyarray, integer ) + integer + + + Returns the length of the requested array dimension. + + + array_length(array[1,2,3], 1) + 3 + + + + + + + array_lower + + array_lower ( anyarray, integer ) + integer + + + Returns the lower bound of the requested array dimension. + + + array_lower('[0:2]={1,2,3}'::integer[], 1) + 0 + + + + + + + array_ndims + + array_ndims ( anyarray ) + integer + + + Returns the number of dimensions of the array. + + + array_ndims(ARRAY[[1,2,3], [4,5,6]]) + 2 + + + + + + + array_position + + array_position ( anycompatiblearray, anycompatible , integer ) + integer + + + Returns the subscript of the first occurrence of the second argument + in the array, or NULL if it's not present. + If the third argument is given, the search begins at that subscript. + The array must be one-dimensional. + Comparisons are done using IS NOT DISTINCT FROM + semantics, so it is possible to search for NULL. + + + array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 'mon') + 2 + + + + + + + array_positions + + array_positions ( anycompatiblearray, anycompatible ) + integer[] + + + Returns an array of the subscripts of all occurrences of the second + argument in the array given as first argument. + The array must be one-dimensional. + Comparisons are done using IS NOT DISTINCT FROM + semantics, so it is possible to search for NULL. + NULL is returned only if the array + is NULL; if the value is not found in the array, an + empty array is returned. + + + array_positions(ARRAY['A','A','B','A'], 'A') + {1,2,4} + + + + + + + array_prepend + + array_prepend ( anycompatible, anycompatiblearray ) + anycompatiblearray + + + Prepends an element to the beginning of an array (same as + the anycompatible || anycompatiblearray + operator). + + + array_prepend(1, ARRAY[2,3]) + {1,2,3} + + + + + + + array_remove + + array_remove ( anycompatiblearray, anycompatible ) + anycompatiblearray + + + Removes all elements equal to the given value from the array. + The array must be one-dimensional. + Comparisons are done using IS NOT DISTINCT FROM + semantics, so it is possible to remove NULLs. + + + array_remove(ARRAY[1,2,3,2], 2) + {1,3} + + + + + + + array_replace + + array_replace ( anycompatiblearray, anycompatible, anycompatible ) + anycompatiblearray + + + Replaces each array element equal to the second argument with the + third argument. + + + array_replace(ARRAY[1,2,5,4], 5, 3) + {1,2,3,4} + + + + + + + array_to_string + + array_to_string ( array anyarray, delimiter text , null_string text ) + text + + + Converts each array element to its text representation, and + concatenates those separated by + the delimiter string. + If null_string is given and is + not NULL, then NULL array + entries are represented by that string; otherwise, they are omitted. + + + array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*') + 1,2,3,*,5 + + + + + + + array_upper + + array_upper ( anyarray, integer ) + integer + + + Returns the upper bound of the requested array dimension. + + + array_upper(ARRAY[1,8,3,7], 1) + 4 + + + + + + + cardinality + + cardinality ( anyarray ) + integer + + + Returns the total number of elements in the array, or 0 if the array + is empty. + + + cardinality(ARRAY[[1,2],[3,4]]) + 4 + + + + + + + trim_array + + trim_array ( array anyarray, n integer ) + anyarray + + + Trims an array by removing the last n elements. + If the array is multidimensional, only the first dimension is trimmed. + + + trim_array(ARRAY[1,2,3,4,5,6], 2) + {1,2,3,4} + + + + + + + unnest + + unnest ( anyarray ) + setof anyelement + + + Expands an array into a set of rows. + The array's elements are read out in storage order. + + + unnest(ARRAY[1,2]) + + + 1 + 2 + + + + unnest(ARRAY[['foo','bar'],['baz','quux']]) + + + foo + bar + baz + quux + + + + + + + unnest ( anyarray, anyarray , ... ) + setof anyelement, anyelement [, ... ] + + + Expands multiple arrays (possibly of different data types) into a set of + rows. If the arrays are not all the same length then the shorter ones + are padded with NULLs. This form is only allowed + in a query's FROM clause; see . + + + select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b) + + + a | b +---+----- + 1 | foo + 2 | bar + | baz + + + + + +
+ + + + There are two differences in the behavior of string_to_array + from pre-9.1 versions of PostgreSQL. + First, it will return an empty (zero-element) array rather + than NULL when the input string is of zero length. + Second, if the delimiter string is NULL, the function + splits the input into individual characters, rather than + returning NULL as before. + + + + + See also about the aggregate + function array_agg for use with arrays. + +
+ + + Range/Multirange Functions and Operators + + + See for an overview of range types. + + + + shows the specialized operators + available for range types. + shows the specialized operators + available for multirange types. + In addition to those, the usual comparison operators shown in + are available for range + and multirange types. The comparison operators order first by the range lower + bounds, and only if those are equal do they compare the upper bounds. The + multirange operators compare each range until one is unequal. This + does not usually result in a useful overall ordering, but the operators are + provided to allow unique indexes to be constructed on ranges. + + + + Range Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + anyrange @> anyrange + boolean + + + Does the first range contain the second? + + + int4range(2,4) @> int4range(2,3) + t + + + + + + anyrange @> anyelement + boolean + + + Does the range contain the element? + + + '[2011-01-01,2011-03-01)'::tsrange @> '2011-01-10'::timestamp + t + + + + + + anyrange <@ anyrange + boolean + + + Is the first range contained by the second? + + + int4range(2,4) <@ int4range(1,7) + t + + + + + + anyelement <@ anyrange + boolean + + + Is the element contained in the range? + + + 42 <@ int4range(1,7) + f + + + + + + anyrange && anyrange + boolean + + + Do the ranges overlap, that is, have any elements in common? + + + int8range(3,7) && int8range(4,12) + t + + + + + + anyrange << anyrange + boolean + + + Is the first range strictly left of the second? + + + int8range(1,10) << int8range(100,110) + t + + + + + + anyrange >> anyrange + boolean + + + Is the first range strictly right of the second? + + + int8range(50,60) >> int8range(20,30) + t + + + + + + anyrange &< anyrange + boolean + + + Does the first range not extend to the right of the second? + + + int8range(1,20) &< int8range(18,20) + t + + + + + + anyrange &> anyrange + boolean + + + Does the first range not extend to the left of the second? + + + int8range(7,20) &> int8range(5,10) + t + + + + + + anyrange -|- anyrange + boolean + + + Are the ranges adjacent? + + + numrange(1.1,2.2) -|- numrange(2.2,3.3) + t + + + + + + anyrange + anyrange + anyrange + + + Computes the union of the ranges. The ranges must overlap or be + adjacent, so that the union is a single range (but + see range_merge()). + + + numrange(5,15) + numrange(10,20) + [5,20) + + + + + + anyrange * anyrange + anyrange + + + Computes the intersection of the ranges. + + + int8range(5,15) * int8range(10,20) + [10,15) + + + + + + anyrange - anyrange + anyrange + + + Computes the difference of the ranges. The second range must not be + contained in the first in such a way that the difference would not be + a single range. + + + int8range(5,15) - int8range(10,20) + [5,10) + + + + +
+ + + Multirange Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + anymultirange @> anymultirange + boolean + + + Does the first multirange contain the second? + + + '{[2,4)}'::int4multirange @> '{[2,3)}'::int4multirange + t + + + + + + anymultirange @> anyrange + boolean + + + Does the multirange contain the range? + + + '{[2,4)}'::int4multirange @> int4range(2,3) + t + + + + + + anymultirange @> anyelement + boolean + + + Does the multirange contain the element? + + + '{[2011-01-01,2011-03-01)}'::tsmultirange @> '2011-01-10'::timestamp + t + + + + + + anyrange @> anymultirange + boolean + + + Does the range contain the multirange? + + + '[2,4)'::int4range @> '{[2,3)}'::int4multirange + t + + + + + + anymultirange <@ anymultirange + boolean + + + Is the first multirange contained by the second? + + + '{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange + t + + + + + + anymultirange <@ anyrange + boolean + + + Is the multirange contained by the range? + + + '{[2,4)}'::int4multirange <@ int4range(1,7) + t + + + + + + anyrange <@ anymultirange + boolean + + + Is the range contained by the multirange? + + + int4range(2,4) <@ '{[1,7)}'::int4multirange + t + + + + + + anyelement <@ anymultirange + boolean + + + Is the element contained by the multirange? + + + 42 <@ '{[1,7)}'::int4multirange + t + + + + + + anymultirange && anymultirange + boolean + + + Do the multiranges overlap, that is, have any elements in common? + + + '{[3,7)}'::int8multirange && '{[4,12)}'::int8multirange + t + + + + + + anymultirange && anyrange + boolean + + + Does the multirange overlap the range? + + + '{[3,7)}'::int8multirange && int8range(4,12) + t + + + + + + anyrange && anymultirange + boolean + + + Does the range overlap the multirange? + + + int8range(3,7) && '{[4,12)}'::int8multirange + t + + + + + + anymultirange << anymultirange + boolean + + + Is the first multirange strictly left of the second? + + + '{[1,10)}'::int8multirange << '{[100,110)}'::int8multirange + t + + + + + + anymultirange << anyrange + boolean + + + Is the multirange strictly left of the range? + + + '{[1,10)}'::int8multirange << int8range(100,110) + t + + + + + + anyrange << anymultirange + boolean + + + Is the range strictly left of the multirange? + + + int8range(1,10) << '{[100,110)}'::int8multirange + t + + + + + + anymultirange >> anymultirange + boolean + + + Is the first multirange strictly right of the second? + + + '{[50,60)}'::int8multirange >> '{[20,30)}'::int8multirange + t + + + + + + anymultirange >> anyrange + boolean + + + Is the multirange strictly right of the range? + + + '{[50,60)}'::int8multirange >> int8range(20,30) + t + + + + + + anyrange >> anymultirange + boolean + + + Is the range strictly right of the multirange? + + + int8range(50,60) >> '{[20,30)}'::int8multirange + t + + + + + + anymultirange &< anymultirange + boolean + + + Does the first multirange not extend to the right of the second? + + + '{[1,20)}'::int8multirange &< '{[18,20)}'::int8multirange + t + + + + + + anymultirange &< anyrange + boolean + + + Does the multirange not extend to the right of the range? + + + '{[1,20)}'::int8multirange &< int8range(18,20) + t + + + + + + anyrange &< anymultirange + boolean + + + Does the range not extend to the right of the multirange? + + + int8range(1,20) &< '{[18,20)}'::int8multirange + t + + + + + + anymultirange &> anymultirange + boolean + + + Does the first multirange not extend to the left of the second? + + + '{[7,20)}'::int8multirange &> '{[5,10)}'::int8multirange + t + + + + + + anymultirange &> anyrange + boolean + + + Does the multirange not extend to the left of the range? + + + '{[7,20)}'::int8multirange &> int8range(5,10) + t + + + + + + anyrange &> anymultirange + boolean + + + Does the range not extend to the left of the multirange? + + + int8range(7,20) &> '{[5,10)}'::int8multirange + t + + + + + + anymultirange -|- anymultirange + boolean + + + Are the multiranges adjacent? + + + '{[1.1,2.2)}'::nummultirange -|- '{[2.2,3.3)}'::nummultirange + t + + + + + + anymultirange -|- anyrange + boolean + + + Is the multirange adjacent to the range? + + + '{[1.1,2.2)}'::nummultirange -|- numrange(2.2,3.3) + t + + + + + + anyrange -|- anymultirange + boolean + + + Is the range adjacent to the multirange? + + + numrange(1.1,2.2) -|- '{[2.2,3.3)}'::nummultirange + t + + + + + + anymultirange + anymultirange + anymultirange + + + Computes the union of the multiranges. The multiranges need not overlap + or be adjacent. + + + '{[5,10)}'::nummultirange + '{[15,20)}'::nummultirange + {[5,10), [15,20)} + + + + + + anymultirange * anymultirange + anymultirange + + + Computes the intersection of the multiranges. + + + '{[5,15)}'::int8multirange * '{[10,20)}'::int8multirange + {[10,15)} + + + + + + anymultirange - anymultirange + anymultirange + + + Computes the difference of the multiranges. + + + '{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange + {[5,10), [15,20)} + + + + +
+ + + The left-of/right-of/adjacent operators always return false when an empty + range or multirange is involved; that is, an empty range is not considered to + be either before or after any other range. + + + + Elsewhere empty ranges and multiranges are treated as the additive identity: + anything unioned with an empty value is itself. Anything minus an empty + value is itself. An empty multirange has exactly the same points as an empty + range. Every range contains the empty range. Every multirange contains as many + empty ranges as you like. + + + + The range union and difference operators will fail if the resulting range would + need to contain two disjoint sub-ranges, as such a range cannot be + represented. There are separate operators for union and difference that take + multirange parameters and return a multirange, and they do not fail even if + their arguments are disjoint. So if you need a union or difference operation + for ranges that may be disjoint, you can avoid errors by first casting your + ranges to multiranges. + + + + shows the functions + available for use with range types. + shows the functions + available for use with multirange types. + + + + Range Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + lower + + lower ( anyrange ) + anyelement + + + Extracts the lower bound of the range (NULL if the + range is empty or the lower bound is infinite). + + + lower(numrange(1.1,2.2)) + 1.1 + + + + + + + upper + + upper ( anyrange ) + anyelement + + + Extracts the upper bound of the range (NULL if the + range is empty or the upper bound is infinite). + + + upper(numrange(1.1,2.2)) + 2.2 + + + + + + + isempty + + isempty ( anyrange ) + boolean + + + Is the range empty? + + + isempty(numrange(1.1,2.2)) + f + + + + + + + lower_inc + + lower_inc ( anyrange ) + boolean + + + Is the range's lower bound inclusive? + + + lower_inc(numrange(1.1,2.2)) + t + + + + + + + upper_inc + + upper_inc ( anyrange ) + boolean + + + Is the range's upper bound inclusive? + + + upper_inc(numrange(1.1,2.2)) + f + + + + + + + lower_inf + + lower_inf ( anyrange ) + boolean + + + Is the range's lower bound infinite? + + + lower_inf('(,)'::daterange) + t + + + + + + + upper_inf + + upper_inf ( anyrange ) + boolean + + + Is the range's upper bound infinite? + + + upper_inf('(,)'::daterange) + t + + + + + + + range_merge + + range_merge ( anyrange, anyrange ) + anyrange + + + Computes the smallest range that includes both of the given ranges. + + + range_merge('[1,2)'::int4range, '[3,4)'::int4range) + [1,4) + + + + +
+ + + Multirange Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + lower + + lower ( anymultirange ) + anyelement + + + Extracts the lower bound of the multirange (NULL if the + multirange is empty or the lower bound is infinite). + + + lower('{[1.1,2.2)}'::nummultirange) + 1.1 + + + + + + + upper + + upper ( anymultirange ) + anyelement + + + Extracts the upper bound of the multirange (NULL if the + multirange is empty or the upper bound is infinite). + + + upper('{[1.1,2.2)}'::nummultirange) + 2.2 + + + + + + + isempty + + isempty ( anymultirange ) + boolean + + + Is the multirange empty? + + + isempty('{[1.1,2.2)}'::nummultirange) + f + + + + + + + lower_inc + + lower_inc ( anymultirange ) + boolean + + + Is the multirange's lower bound inclusive? + + + lower_inc('{[1.1,2.2)}'::nummultirange) + t + + + + + + + upper_inc + + upper_inc ( anymultirange ) + boolean + + + Is the multirange's upper bound inclusive? + + + upper_inc('{[1.1,2.2)}'::nummultirange) + f + + + + + + + lower_inf + + lower_inf ( anymultirange ) + boolean + + + Is the multirange's lower bound infinite? + + + lower_inf('{(,)}'::datemultirange) + t + + + + + + + upper_inf + + upper_inf ( anymultirange ) + boolean + + + Is the multirange's upper bound infinite? + + + upper_inf('{(,)}'::datemultirange) + t + + + + + + + range_merge + + range_merge ( anymultirange ) + anyrange + + + Computes the smallest range that includes the entire multirange. + + + range_merge('{[1,2), [3,4)}'::int4multirange) + [1,4) + + + + + + + multirange (function) + + multirange ( anyrange ) + anymultirange + + + Returns a multirange containing just the given range. + + + multirange('[1,2)'::int4range) + {[1,2)} + + + + +
+ + + The lower_inc, upper_inc, + lower_inf, and upper_inf + functions all return false for an empty range or multirange. + +
+ + + Aggregate Functions + + + aggregate function + built-in + + + + Aggregate functions compute a single result + from a set of input values. The built-in general-purpose aggregate + functions are listed in + while statistical aggregates are in . + The built-in within-group ordered-set aggregate functions + are listed in + while the built-in within-group hypothetical-set ones are in . Grouping operations, + which are closely related to aggregate functions, are listed in + . + The special syntax considerations for aggregate + functions are explained in . + Consult for additional introductory + information. + + + + Aggregate functions that support Partial Mode + are eligible to participate in various optimizations, such as parallel + aggregation. + + + + General-Purpose Aggregate Functions + + + + + + + Function + + + Description + + Partial Mode + + + + + + + + array_agg + + array_agg ( anynonarray ) + anyarray + + + Collects all the input values, including nulls, into an array. + + No + + + + + array_agg ( anyarray ) + anyarray + + + Concatenates all the input arrays into an array of one higher + dimension. (The inputs must all have the same dimensionality, and + cannot be empty or null.) + + No + + + + + + average + + + avg + + avg ( smallint ) + numeric + + + avg ( integer ) + numeric + + + avg ( bigint ) + numeric + + + avg ( numeric ) + numeric + + + avg ( real ) + double precision + + + avg ( double precision ) + double precision + + + avg ( interval ) + interval + + + Computes the average (arithmetic mean) of all the non-null input + values. + + Yes + + + + + + bit_and + + bit_and ( smallint ) + smallint + + + bit_and ( integer ) + integer + + + bit_and ( bigint ) + bigint + + + bit_and ( bit ) + bit + + + Computes the bitwise AND of all non-null input values. + + Yes + + + + + + bit_or + + bit_or ( smallint ) + smallint + + + bit_or ( integer ) + integer + + + bit_or ( bigint ) + bigint + + + bit_or ( bit ) + bit + + + Computes the bitwise OR of all non-null input values. + + Yes + + + + + + bit_xor + + bit_xor ( smallint ) + smallint + + + bit_xor ( integer ) + integer + + + bit_xor ( bigint ) + bigint + + + bit_xor ( bit ) + bit + + + Computes the bitwise exclusive OR of all non-null input values. + Can be useful as a checksum for an unordered set of values. + + Yes + + + + + + bool_and + + bool_and ( boolean ) + boolean + + + Returns true if all non-null input values are true, otherwise false. + + Yes + + + + + + bool_or + + bool_or ( boolean ) + boolean + + + Returns true if any non-null input value is true, otherwise false. + + Yes + + + + + + count + + count ( * ) + bigint + + + Computes the number of input rows. + + Yes + + + + + count ( "any" ) + bigint + + + Computes the number of input rows in which the input value is not + null. + + Yes + + + + + + every + + every ( boolean ) + boolean + + + This is the SQL standard's equivalent to bool_and. + + Yes + + + + + + json_agg + + json_agg ( anyelement ) + json + + + + jsonb_agg + + jsonb_agg ( anyelement ) + jsonb + + + Collects all the input values, including nulls, into a JSON array. + Values are converted to JSON as per to_json + or to_jsonb. + + No + + + + + + json_object_agg + + json_object_agg ( key + "any", value + "any" ) + json + + + + jsonb_object_agg + + jsonb_object_agg ( key + "any", value + "any" ) + jsonb + + + Collects all the key/value pairs into a JSON object. Key arguments + are coerced to text; value arguments are converted as + per to_json or to_jsonb. + Values can be null, but not keys. + + No + + + + + + max + + max ( see text ) + same as input type + + + Computes the maximum of the non-null input + values. Available for any numeric, string, date/time, or enum type, + as well as inet, interval, + money, oid, pg_lsn, + tid, + and arrays of any of these types. + + Yes + + + + + + min + + min ( see text ) + same as input type + + + Computes the minimum of the non-null input + values. Available for any numeric, string, date/time, or enum type, + as well as inet, interval, + money, oid, pg_lsn, + tid, + and arrays of any of these types. + + Yes + + + + + + range_agg + + range_agg ( value + anyrange ) + anymultirange + + + Computes the union of the non-null input values. + + No + + + + + + range_intersect_agg + + range_intersect_agg ( value + anyrange ) + anymultirange + + + Computes the intersection of the non-null input values. + + No + + + + + + string_agg + + string_agg ( value + text, delimiter text ) + text + + + string_agg ( value + bytea, delimiter bytea ) + bytea + + + Concatenates the non-null input values into a string. Each value + after the first is preceded by the + corresponding delimiter (if it's not null). + + No + + + + + + sum + + sum ( smallint ) + bigint + + + sum ( integer ) + bigint + + + sum ( bigint ) + numeric + + + sum ( numeric ) + numeric + + + sum ( real ) + real + + + sum ( double precision ) + double precision + + + sum ( interval ) + interval + + + sum ( money ) + money + + + Computes the sum of the non-null input values. + + Yes + + + + + + xmlagg + + xmlagg ( xml ) + xml + + + Concatenates the non-null XML input values (see + ). + + No + + + +
+ + + It should be noted that except for count, + these functions return a null value when no rows are selected. In + particular, sum of no rows returns null, not + zero as one might expect, and array_agg + returns null rather than an empty array when there are no input + rows. The coalesce function can be used to + substitute zero or an empty array for null when necessary. + + + + The aggregate functions array_agg, + json_agg, jsonb_agg, + json_object_agg, jsonb_object_agg, + string_agg, + and xmlagg, as well as similar user-defined + aggregate functions, produce meaningfully different result values + depending on the order of the input values. This ordering is + unspecified by default, but can be controlled by writing an + ORDER BY clause within the aggregate call, as shown in + . + Alternatively, supplying the input values from a sorted subquery + will usually work. For example: + + + + Beware that this approach can fail if the outer query level contains + additional processing, such as a join, because that might cause the + subquery's output to be reordered before the aggregate is computed. + + + + + ANY + + + SOME + + + The boolean aggregates bool_and and + bool_or correspond to the standard SQL aggregates + every and any or + some. + PostgreSQL + supports every, but not any + or some, because there is an ambiguity built into + the standard syntax: + +SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...; + + Here ANY can be considered either as introducing + a subquery, or as being an aggregate function, if the subquery + returns one row with a Boolean value. + Thus the standard name cannot be given to these aggregates. + + + + + + Users accustomed to working with other SQL database management + systems might be disappointed by the performance of the + count aggregate when it is applied to the + entire table. A query like: + +SELECT count(*) FROM sometable; + + will require effort proportional to the size of the table: + PostgreSQL will need to scan either the + entire table or the entirety of an index that includes all rows in + the table. + + + + + shows + aggregate functions typically used in statistical analysis. + (These are separated out merely to avoid cluttering the listing + of more-commonly-used aggregates.) Functions shown as + accepting numeric_type are available for all + the types smallint, integer, + bigint, numeric, real, + and double precision. + Where the description mentions + N, it means the + number of input rows for which all the input expressions are non-null. + In all cases, null is returned if the computation is meaningless, + for example when N is zero. + + + + statistics + + + linear regression + + + + Aggregate Functions for Statistics + + + + + + + Function + + + Description + + Partial Mode + + + + + + + + correlation + + + corr + + corr ( Y double precision, X double precision ) + double precision + + + Computes the correlation coefficient. + + Yes + + + + + + covariance + population + + + covar_pop + + covar_pop ( Y double precision, X double precision ) + double precision + + + Computes the population covariance. + + Yes + + + + + + covariance + sample + + + covar_samp + + covar_samp ( Y double precision, X double precision ) + double precision + + + Computes the sample covariance. + + Yes + + + + + + regr_avgx + + regr_avgx ( Y double precision, X double precision ) + double precision + + + Computes the average of the independent variable, + sum(X)/N. + + Yes + + + + + + regr_avgy + + regr_avgy ( Y double precision, X double precision ) + double precision + + + Computes the average of the dependent variable, + sum(Y)/N. + + Yes + + + + + + regr_count + + regr_count ( Y double precision, X double precision ) + bigint + + + Computes the number of rows in which both inputs are non-null. + + Yes + + + + + + regression intercept + + + regr_intercept + + regr_intercept ( Y double precision, X double precision ) + double precision + + + Computes the y-intercept of the least-squares-fit linear equation + determined by the + (X, Y) pairs. + + Yes + + + + + + regr_r2 + + regr_r2 ( Y double precision, X double precision ) + double precision + + + Computes the square of the correlation coefficient. + + Yes + + + + + + regression slope + + + regr_slope + + regr_slope ( Y double precision, X double precision ) + double precision + + + Computes the slope of the least-squares-fit linear equation determined + by the (X, Y) + pairs. + + Yes + + + + + + regr_sxx + + regr_sxx ( Y double precision, X double precision ) + double precision + + + Computes the sum of squares of the independent + variable, + sum(X^2) - sum(X)^2/N. + + Yes + + + + + + regr_sxy + + regr_sxy ( Y double precision, X double precision ) + double precision + + + Computes the sum of products of independent times + dependent variables, + sum(X*Y) - sum(X) * sum(Y)/N. + + Yes + + + + + + regr_syy + + regr_syy ( Y double precision, X double precision ) + double precision + + + Computes the sum of squares of the dependent + variable, + sum(Y^2) - sum(Y)^2/N. + + Yes + + + + + + standard deviation + + + stddev + + stddev ( numeric_type ) + double precision + for real or double precision, + otherwise numeric + + + This is a historical alias for stddev_samp. + + Yes + + + + + + standard deviation + population + + + stddev_pop + + stddev_pop ( numeric_type ) + double precision + for real or double precision, + otherwise numeric + + + Computes the population standard deviation of the input values. + + Yes + + + + + + standard deviation + sample + + + stddev_samp + + stddev_samp ( numeric_type ) + double precision + for real or double precision, + otherwise numeric + + + Computes the sample standard deviation of the input values. + + Yes + + + + + + variance + + variance ( numeric_type ) + double precision + for real or double precision, + otherwise numeric + + + This is a historical alias for var_samp. + + Yes + + + + + + variance + population + + + var_pop + + var_pop ( numeric_type ) + double precision + for real or double precision, + otherwise numeric + + + Computes the population variance of the input values (square of the + population standard deviation). + + Yes + + + + + + variance + sample + + + var_samp + + var_samp ( numeric_type ) + double precision + for real or double precision, + otherwise numeric + + + Computes the sample variance of the input values (square of the sample + standard deviation). + + Yes + + + +
+ + + shows some + aggregate functions that use the ordered-set aggregate + syntax. These functions are sometimes referred to as inverse + distribution functions. Their aggregated input is introduced by + ORDER BY, and they may also take a direct + argument that is not aggregated, but is computed only once. + All these functions ignore null values in their aggregated input. + For those that take a fraction parameter, the + fraction value must be between 0 and 1; an error is thrown if not. + However, a null fraction value simply produces a + null result. + + + + ordered-set aggregate + built-in + + + inverse distribution + + + + Ordered-Set Aggregate Functions + + + + + + + Function + + + Description + + Partial Mode + + + + + + + + mode + statistical + + mode () WITHIN GROUP ( ORDER BY anyelement ) + anyelement + + + Computes the mode, the most frequent + value of the aggregated argument (arbitrarily choosing the first one + if there are multiple equally-frequent values). The aggregated + argument must be of a sortable type. + + No + + + + + + percentile + continuous + + percentile_cont ( fraction double precision ) WITHIN GROUP ( ORDER BY double precision ) + double precision + + + percentile_cont ( fraction double precision ) WITHIN GROUP ( ORDER BY interval ) + interval + + + Computes the continuous percentile, a value + corresponding to the specified fraction + within the ordered set of aggregated argument values. This will + interpolate between adjacent input items if needed. + + No + + + + + percentile_cont ( fractions double precision[] ) WITHIN GROUP ( ORDER BY double precision ) + double precision[] + + + percentile_cont ( fractions double precision[] ) WITHIN GROUP ( ORDER BY interval ) + interval[] + + + Computes multiple continuous percentiles. The result is an array of + the same dimensions as the fractions + parameter, with each non-null element replaced by the (possibly + interpolated) value corresponding to that percentile. + + No + + + + + + percentile + discrete + + percentile_disc ( fraction double precision ) WITHIN GROUP ( ORDER BY anyelement ) + anyelement + + + Computes the discrete percentile, the first + value within the ordered set of aggregated argument values whose + position in the ordering equals or exceeds the + specified fraction. The aggregated + argument must be of a sortable type. + + No + + + + + percentile_disc ( fractions double precision[] ) WITHIN GROUP ( ORDER BY anyelement ) + anyarray + + + Computes multiple discrete percentiles. The result is an array of the + same dimensions as the fractions parameter, + with each non-null element replaced by the input value corresponding + to that percentile. + The aggregated argument must be of a sortable type. + + No + + + +
+ + + hypothetical-set aggregate + built-in + + + + Each of the hypothetical-set aggregates listed in + is associated with a + window function of the same name defined in + . In each case, the aggregate's result + is the value that the associated window function would have + returned for the hypothetical row constructed from + args, if such a row had been added to the sorted + group of rows represented by the sorted_args. + For each of these functions, the list of direct arguments + given in args must match the number and types of + the aggregated arguments given in sorted_args. + Unlike most built-in aggregates, these aggregates are not strict, that is + they do not drop input rows containing nulls. Null values sort according + to the rule specified in the ORDER BY clause. + + + + Hypothetical-Set Aggregate Functions + + + + + + + Function + + + Description + + Partial Mode + + + + + + + + rank + hypothetical + + rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) + bigint + + + Computes the rank of the hypothetical row, with gaps; that is, the row + number of the first row in its peer group. + + No + + + + + + dense_rank + hypothetical + + dense_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) + bigint + + + Computes the rank of the hypothetical row, without gaps; this function + effectively counts peer groups. + + No + + + + + + percent_rank + hypothetical + + percent_rank ( args ) WITHIN GROUP ( ORDER BY sorted_args ) + double precision + + + Computes the relative rank of the hypothetical row, that is + (rank - 1) / (total rows - 1). + The value thus ranges from 0 to 1 inclusive. + + No + + + + + + cume_dist + hypothetical + + cume_dist ( args ) WITHIN GROUP ( ORDER BY sorted_args ) + double precision + + + Computes the cumulative distribution, that is (number of rows + preceding or peers with hypothetical row) / (total rows). The value + thus ranges from 1/N to 1. + + No + + + +
+ + + Grouping Operations + + + + + Function + + + Description + + + + + + + + + GROUPING + + GROUPING ( group_by_expression(s) ) + integer + + + Returns a bit mask indicating which GROUP BY + expressions are not included in the current grouping set. + Bits are assigned with the rightmost argument corresponding to the + least-significant bit; each bit is 0 if the corresponding expression + is included in the grouping criteria of the grouping set generating + the current result row, and 1 if it is not included. + + + + +
+ + + The grouping operations shown in + are used in conjunction with + grouping sets (see ) to distinguish + result rows. The arguments to the GROUPING function + are not actually evaluated, but they must exactly match expressions given + in the GROUP BY clause of the associated query level. + For example: + +=> SELECT * FROM items_sold; + make | model | sales +-------+-------+------- + Foo | GT | 10 + Foo | Tour | 20 + Bar | City | 15 + Bar | Sport | 5 +(4 rows) + +=> SELECT make, model, GROUPING(make,model), sum(sales) FROM items_sold GROUP BY ROLLUP(make,model); + make | model | grouping | sum +-------+-------+----------+----- + Foo | GT | 0 | 10 + Foo | Tour | 0 | 20 + Bar | City | 0 | 15 + Bar | Sport | 0 | 5 + Foo | | 1 | 30 + Bar | | 1 | 20 + | | 3 | 50 +(7 rows) + + Here, the grouping value 0 in the + first four rows shows that those have been grouped normally, over both the + grouping columns. The value 1 indicates + that model was not grouped by in the next-to-last two + rows, and the value 3 indicates that + neither make nor model was grouped + by in the last row (which therefore is an aggregate over all the input + rows). + + +
+ + + Window Functions + + + window function + built-in + + + + Window functions provide the ability to perform + calculations across sets of rows that are related to the current query + row. See for an introduction to this + feature, and for syntax + details. + + + + The built-in window functions are listed in + . Note that these functions + must be invoked using window function syntax, i.e., an + OVER clause is required. + + + + In addition to these functions, any built-in or user-defined + ordinary aggregate (i.e., not ordered-set or hypothetical-set aggregates) + can be used as a window function; see + for a list of the built-in aggregates. + Aggregate functions act as window functions only when an OVER + clause follows the call; otherwise they act as plain aggregates + and return a single row for the entire set. + + + + General-Purpose Window Functions + + + + + Function + + + Description + + + + + + + + + row_number + + row_number () + bigint + + + Returns the number of the current row within its partition, counting + from 1. + + + + + + + rank + + rank () + bigint + + + Returns the rank of the current row, with gaps; that is, + the row_number of the first row in its peer + group. + + + + + + + dense_rank + + dense_rank () + bigint + + + Returns the rank of the current row, without gaps; this function + effectively counts peer groups. + + + + + + + percent_rank + + percent_rank () + double precision + + + Returns the relative rank of the current row, that is + (rank - 1) / (total partition rows - 1). + The value thus ranges from 0 to 1 inclusive. + + + + + + + cume_dist + + cume_dist () + double precision + + + Returns the cumulative distribution, that is (number of partition rows + preceding or peers with current row) / (total partition rows). + The value thus ranges from 1/N to 1. + + + + + + + ntile + + ntile ( num_buckets integer ) + integer + + + Returns an integer ranging from 1 to the argument value, dividing the + partition as equally as possible. + + + + + + + lag + + lag ( value anycompatible + , offset integer + , default anycompatible ) + anycompatible + + + Returns value evaluated at + the row that is offset + rows before the current row within the partition; if there is no such + row, instead returns default + (which must be of a type compatible with + value). + Both offset and + default are evaluated + with respect to the current row. If omitted, + offset defaults to 1 and + default to NULL. + + + + + + + lead + + lead ( value anycompatible + , offset integer + , default anycompatible ) + anycompatible + + + Returns value evaluated at + the row that is offset + rows after the current row within the partition; if there is no such + row, instead returns default + (which must be of a type compatible with + value). + Both offset and + default are evaluated + with respect to the current row. If omitted, + offset defaults to 1 and + default to NULL. + + + + + + + first_value + + first_value ( value anyelement ) + anyelement + + + Returns value evaluated + at the row that is the first row of the window frame. + + + + + + + last_value + + last_value ( value anyelement ) + anyelement + + + Returns value evaluated + at the row that is the last row of the window frame. + + + + + + + nth_value + + nth_value ( value anyelement, n integer ) + anyelement + + + Returns value evaluated + at the row that is the n'th + row of the window frame (counting from 1); + returns NULL if there is no such row. + + + + +
+ + + All of the functions listed in + depend on the sort ordering + specified by the ORDER BY clause of the associated window + definition. Rows that are not distinct when considering only the + ORDER BY columns are said to be peers. + The four ranking functions (including cume_dist) are + defined so that they give the same answer for all rows of a peer group. + + + + Note that first_value, last_value, and + nth_value consider only the rows within the window + frame, which by default contains the rows from the start of the + partition through the last peer of the current row. This is + likely to give unhelpful results for last_value and + sometimes also nth_value. You can redefine the frame by + adding a suitable frame specification (RANGE, + ROWS or GROUPS) to + the OVER clause. + See for more information + about frame specifications. + + + + When an aggregate function is used as a window function, it aggregates + over the rows within the current row's window frame. + An aggregate used with ORDER BY and the default window frame + definition produces a running sum type of behavior, which may or + may not be what's wanted. To obtain + aggregation over the whole partition, omit ORDER BY or use + ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING. + Other frame specifications can be used to obtain other effects. + + + + + The SQL standard defines a RESPECT NULLS or + IGNORE NULLS option for lead, lag, + first_value, last_value, and + nth_value. This is not implemented in + PostgreSQL: the behavior is always the + same as the standard's default, namely RESPECT NULLS. + Likewise, the standard's FROM FIRST or FROM LAST + option for nth_value is not implemented: only the + default FROM FIRST behavior is supported. (You can achieve + the result of FROM LAST by reversing the ORDER BY + ordering.) + + + +
+ + + Subquery Expressions + + + EXISTS + + + + IN + + + + NOT IN + + + + ANY + + + + ALL + + + + SOME + + + + subquery + + + + This section describes the SQL-compliant subquery + expressions available in PostgreSQL. + All of the expression forms documented in this section return + Boolean (true/false) results. + + + + <literal>EXISTS</literal> + + +EXISTS (subquery) + + + + The argument of EXISTS is an arbitrary SELECT statement, + or subquery. The + subquery is evaluated to determine whether it returns any rows. + If it returns at least one row, the result of EXISTS is + true; if the subquery returns no rows, the result of EXISTS + is false. + + + + The subquery can refer to variables from the surrounding query, + which will act as constants during any one evaluation of the subquery. + + + + The subquery will generally only be executed long enough to determine + whether at least one row is returned, not all the way to completion. + It is unwise to write a subquery that has side effects (such as + calling sequence functions); whether the side effects occur + might be unpredictable. + + + + Since the result depends only on whether any rows are returned, + and not on the contents of those rows, the output list of the + subquery is normally unimportant. A common coding convention is + to write all EXISTS tests in the form + EXISTS(SELECT 1 WHERE ...). There are exceptions to + this rule however, such as subqueries that use INTERSECT. + + + + This simple example is like an inner join on col2, but + it produces at most one output row for each tab1 row, + even if there are several matching tab2 rows: + +SELECT col1 +FROM tab1 +WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); + + + + + + <literal>IN</literal> + + +expression IN (subquery) + + + + The right-hand side is a parenthesized + subquery, which must return exactly one column. The left-hand expression + is evaluated and compared to each row of the subquery result. + The result of IN is true if any equal subquery row is found. + The result is false if no equal row is found (including the + case where the subquery returns no rows). + + + + Note that if the left-hand expression yields null, or if there are + no equal right-hand values and at least one right-hand row yields + null, the result of the IN construct will be null, not false. + This is in accordance with SQL's normal rules for Boolean combinations + of null values. + + + + As with EXISTS, it's unwise to assume that the subquery will + be evaluated completely. + + + +row_constructor IN (subquery) + + + + The left-hand side of this form of IN is a row constructor, + as described in . + The right-hand side is a parenthesized + subquery, which must return exactly as many columns as there are + expressions in the left-hand row. The left-hand expressions are + evaluated and compared row-wise to each row of the subquery result. + The result of IN is true if any equal subquery row is found. + The result is false if no equal row is found (including the + case where the subquery returns no rows). + + + + As usual, null values in the rows are combined per + the normal rules of SQL Boolean expressions. Two rows are considered + equal if all their corresponding members are non-null and equal; the rows + are unequal if any corresponding members are non-null and unequal; + otherwise the result of that row comparison is unknown (null). + If all the per-row results are either unequal or null, with at least one + null, then the result of IN is null. + + + + + <literal>NOT IN</literal> + + +expression NOT IN (subquery) + + + + The right-hand side is a parenthesized + subquery, which must return exactly one column. The left-hand expression + is evaluated and compared to each row of the subquery result. + The result of NOT IN is true if only unequal subquery rows + are found (including the case where the subquery returns no rows). + The result is false if any equal row is found. + + + + Note that if the left-hand expression yields null, or if there are + no equal right-hand values and at least one right-hand row yields + null, the result of the NOT IN construct will be null, not true. + This is in accordance with SQL's normal rules for Boolean combinations + of null values. + + + + As with EXISTS, it's unwise to assume that the subquery will + be evaluated completely. + + + +row_constructor NOT IN (subquery) + + + + The left-hand side of this form of NOT IN is a row constructor, + as described in . + The right-hand side is a parenthesized + subquery, which must return exactly as many columns as there are + expressions in the left-hand row. The left-hand expressions are + evaluated and compared row-wise to each row of the subquery result. + The result of NOT IN is true if only unequal subquery rows + are found (including the case where the subquery returns no rows). + The result is false if any equal row is found. + + + + As usual, null values in the rows are combined per + the normal rules of SQL Boolean expressions. Two rows are considered + equal if all their corresponding members are non-null and equal; the rows + are unequal if any corresponding members are non-null and unequal; + otherwise the result of that row comparison is unknown (null). + If all the per-row results are either unequal or null, with at least one + null, then the result of NOT IN is null. + + + + + <literal>ANY</literal>/<literal>SOME</literal> + + +expression operator ANY (subquery) +expression operator SOME (subquery) + + + + The right-hand side is a parenthesized + subquery, which must return exactly one column. The left-hand expression + is evaluated and compared to each row of the subquery result using the + given operator, which must yield a Boolean + result. + The result of ANY is true if any true result is obtained. + The result is false if no true result is found (including the + case where the subquery returns no rows). + + + + SOME is a synonym for ANY. + IN is equivalent to = ANY. + + + + Note that if there are no successes and at least one right-hand row yields + null for the operator's result, the result of the ANY construct + will be null, not false. + This is in accordance with SQL's normal rules for Boolean combinations + of null values. + + + + As with EXISTS, it's unwise to assume that the subquery will + be evaluated completely. + + + +row_constructor operator ANY (subquery) +row_constructor operator SOME (subquery) + + + + The left-hand side of this form of ANY is a row constructor, + as described in . + The right-hand side is a parenthesized + subquery, which must return exactly as many columns as there are + expressions in the left-hand row. The left-hand expressions are + evaluated and compared row-wise to each row of the subquery result, + using the given operator. + The result of ANY is true if the comparison + returns true for any subquery row. + The result is false if the comparison returns false for every + subquery row (including the case where the subquery returns no + rows). + The result is NULL if no comparison with a subquery row returns true, + and at least one comparison returns NULL. + + + + See for details about the meaning + of a row constructor comparison. + + + + + <literal>ALL</literal> + + +expression operator ALL (subquery) + + + + The right-hand side is a parenthesized + subquery, which must return exactly one column. The left-hand expression + is evaluated and compared to each row of the subquery result using the + given operator, which must yield a Boolean + result. + The result of ALL is true if all rows yield true + (including the case where the subquery returns no rows). + The result is false if any false result is found. + The result is NULL if no comparison with a subquery row returns false, + and at least one comparison returns NULL. + + + + NOT IN is equivalent to <> ALL. + + + + As with EXISTS, it's unwise to assume that the subquery will + be evaluated completely. + + + +row_constructor operator ALL (subquery) + + + + The left-hand side of this form of ALL is a row constructor, + as described in . + The right-hand side is a parenthesized + subquery, which must return exactly as many columns as there are + expressions in the left-hand row. The left-hand expressions are + evaluated and compared row-wise to each row of the subquery result, + using the given operator. + The result of ALL is true if the comparison + returns true for all subquery rows (including the + case where the subquery returns no rows). + The result is false if the comparison returns false for any + subquery row. + The result is NULL if no comparison with a subquery row returns false, + and at least one comparison returns NULL. + + + + See for details about the meaning + of a row constructor comparison. + + + + + Single-Row Comparison + + + comparison + subquery result row + + + +row_constructor operator (subquery) + + + + The left-hand side is a row constructor, + as described in . + The right-hand side is a parenthesized subquery, which must return exactly + as many columns as there are expressions in the left-hand row. Furthermore, + the subquery cannot return more than one row. (If it returns zero rows, + the result is taken to be null.) The left-hand side is evaluated and + compared row-wise to the single subquery result row. + + + + See for details about the meaning + of a row constructor comparison. + + + + + + + Row and Array Comparisons + + + IN + + + + NOT IN + + + + ANY + + + + ALL + + + + SOME + + + + composite type + comparison + + + + row-wise comparison + + + + comparison + composite type + + + + comparison + row constructor + + + + IS DISTINCT FROM + + + + IS NOT DISTINCT FROM + + + + This section describes several specialized constructs for making + multiple comparisons between groups of values. These forms are + syntactically related to the subquery forms of the previous section, + but do not involve subqueries. + The forms involving array subexpressions are + PostgreSQL extensions; the rest are + SQL-compliant. + All of the expression forms documented in this section return + Boolean (true/false) results. + + + + <literal>IN</literal> + + +expression IN (value , ...) + + + + The right-hand side is a parenthesized list + of scalar expressions. The result is true if the left-hand expression's + result is equal to any of the right-hand expressions. This is a shorthand + notation for + + +expression = value1 +OR +expression = value2 +OR +... + + + + + Note that if the left-hand expression yields null, or if there are + no equal right-hand values and at least one right-hand expression yields + null, the result of the IN construct will be null, not false. + This is in accordance with SQL's normal rules for Boolean combinations + of null values. + + + + + <literal>NOT IN</literal> + + +expression NOT IN (value , ...) + + + + The right-hand side is a parenthesized list + of scalar expressions. The result is true if the left-hand expression's + result is unequal to all of the right-hand expressions. This is a shorthand + notation for + + +expression <> value1 +AND +expression <> value2 +AND +... + + + + + Note that if the left-hand expression yields null, or if there are + no equal right-hand values and at least one right-hand expression yields + null, the result of the NOT IN construct will be null, not true + as one might naively expect. + This is in accordance with SQL's normal rules for Boolean combinations + of null values. + + + + + x NOT IN y is equivalent to NOT (x IN y) in all + cases. However, null values are much more likely to trip up the novice when + working with NOT IN than when working with IN. + It is best to express your condition positively if possible. + + + + + + <literal>ANY</literal>/<literal>SOME</literal> (array) + + +expression operator ANY (array expression) +expression operator SOME (array expression) + + + + The right-hand side is a parenthesized expression, which must yield an + array value. + The left-hand expression + is evaluated and compared to each element of the array using the + given operator, which must yield a Boolean + result. + The result of ANY is true if any true result is obtained. + The result is false if no true result is found (including the + case where the array has zero elements). + + + + If the array expression yields a null array, the result of + ANY will be null. If the left-hand expression yields null, + the result of ANY is ordinarily null (though a non-strict + comparison operator could possibly yield a different result). + Also, if the right-hand array contains any null elements and no true + comparison result is obtained, the result of ANY + will be null, not false (again, assuming a strict comparison operator). + This is in accordance with SQL's normal rules for Boolean combinations + of null values. + + + + SOME is a synonym for ANY. + + + + + <literal>ALL</literal> (array) + + +expression operator ALL (array expression) + + + + The right-hand side is a parenthesized expression, which must yield an + array value. + The left-hand expression + is evaluated and compared to each element of the array using the + given operator, which must yield a Boolean + result. + The result of ALL is true if all comparisons yield true + (including the case where the array has zero elements). + The result is false if any false result is found. + + + + If the array expression yields a null array, the result of + ALL will be null. If the left-hand expression yields null, + the result of ALL is ordinarily null (though a non-strict + comparison operator could possibly yield a different result). + Also, if the right-hand array contains any null elements and no false + comparison result is obtained, the result of ALL + will be null, not true (again, assuming a strict comparison operator). + This is in accordance with SQL's normal rules for Boolean combinations + of null values. + + + + + Row Constructor Comparison + + +row_constructor operator row_constructor + + + + Each side is a row constructor, + as described in . + The two row values must have the same number of fields. + Each side is evaluated and they are compared row-wise. Row constructor + comparisons are allowed when the operator is + =, + <>, + <, + <=, + > or + >=. + Every row element must be of a type which has a default B-tree operator + class or the attempted comparison may generate an error. + + + + + Errors related to the number or types of elements might not occur if + the comparison is resolved using earlier columns. + + + + + The = and <> cases work slightly differently + from the others. Two rows are considered + equal if all their corresponding members are non-null and equal; the rows + are unequal if any corresponding members are non-null and unequal; + otherwise the result of the row comparison is unknown (null). + + + + For the <, <=, > and + >= cases, the row elements are compared left-to-right, + stopping as soon as an unequal or null pair of elements is found. + If either of this pair of elements is null, the result of the + row comparison is unknown (null); otherwise comparison of this pair + of elements determines the result. For example, + ROW(1,2,NULL) < ROW(1,3,0) + yields true, not null, because the third pair of elements are not + considered. + + + + + Prior to PostgreSQL 8.2, the + <, <=, > and >= + cases were not handled per SQL specification. A comparison like + ROW(a,b) < ROW(c,d) + was implemented as + a < c AND b < d + whereas the correct behavior is equivalent to + a < c OR (a = c AND b < d). + + + + +row_constructor IS DISTINCT FROM row_constructor + + + + This construct is similar to a <> row comparison, + but it does not yield null for null inputs. Instead, any null value is + considered unequal to (distinct from) any non-null value, and any two + nulls are considered equal (not distinct). Thus the result will + either be true or false, never null. + + + +row_constructor IS NOT DISTINCT FROM row_constructor + + + + This construct is similar to a = row comparison, + but it does not yield null for null inputs. Instead, any null value is + considered unequal to (distinct from) any non-null value, and any two + nulls are considered equal (not distinct). Thus the result will always + be either true or false, never null. + + + + + + Composite Type Comparison + + +record operator record + + + + The SQL specification requires row-wise comparison to return NULL if the + result depends on comparing two NULL values or a NULL and a non-NULL. + PostgreSQL does this only when comparing the + results of two row constructors (as in + ) or comparing a row constructor + to the output of a subquery (as in ). + In other contexts where two composite-type values are compared, two + NULL field values are considered equal, and a NULL is considered larger + than a non-NULL. This is necessary in order to have consistent sorting + and indexing behavior for composite types. + + + + Each side is evaluated and they are compared row-wise. Composite type + comparisons are allowed when the operator is + =, + <>, + <, + <=, + > or + >=, + or has semantics similar to one of these. (To be specific, an operator + can be a row comparison operator if it is a member of a B-tree operator + class, or is the negator of the = member of a B-tree operator + class.) The default behavior of the above operators is the same as for + IS [ NOT ] DISTINCT FROM for row constructors (see + ). + + + + To support matching of rows which include elements without a default + B-tree operator class, the following operators are defined for composite + type comparison: + *=, + *<>, + *<, + *<=, + *>, and + *>=. + These operators compare the internal binary representation of the two + rows. Two rows might have a different binary representation even + though comparisons of the two rows with the equality operator is true. + The ordering of rows under these comparison operators is deterministic + but not otherwise meaningful. These operators are used internally + for materialized views and might be useful for other specialized + purposes such as replication and B-Tree deduplication (see ). They are not intended to be + generally useful for writing queries, though. + + + + + + Set Returning Functions + + + set returning functions + functions + + + + This section describes functions that possibly return more than one row. + The most widely used functions in this class are series generating + functions, as detailed in and + . Other, more specialized + set-returning functions are described elsewhere in this manual. + See for ways to combine multiple + set-returning functions. + + + + Series Generating Functions + + + + + Function + + + Description + + + + + + + + + generate_series + + generate_series ( start integer, stop integer , step integer ) + setof integer + + + generate_series ( start bigint, stop bigint , step bigint ) + setof bigint + + + generate_series ( start numeric, stop numeric , step numeric ) + setof numeric + + + Generates a series of values from start + to stop, with a step size + of step. step + defaults to 1. + + + + + + generate_series ( start timestamp, stop timestamp, step interval ) + setof timestamp + + + generate_series ( start timestamp with time zone, stop timestamp with time zone, step interval ) + setof timestamp with time zone + + + Generates a series of values from start + to stop, with a step size + of step. + + + + +
+ + + When step is positive, zero rows are returned if + start is greater than stop. + Conversely, when step is negative, zero rows are + returned if start is less than stop. + Zero rows are also returned if any input is NULL. + It is an error + for step to be zero. Some examples follow: + +SELECT * FROM generate_series(2,4); + generate_series +----------------- + 2 + 3 + 4 +(3 rows) + +SELECT * FROM generate_series(5,1,-2); + generate_series +----------------- + 5 + 3 + 1 +(3 rows) + +SELECT * FROM generate_series(4,3); + generate_series +----------------- +(0 rows) + +SELECT generate_series(1.1, 4, 1.3); + generate_series +----------------- + 1.1 + 2.4 + 3.7 +(3 rows) + +-- this example relies on the date-plus-integer operator: +SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a); + dates +------------ + 2004-02-05 + 2004-02-12 + 2004-02-19 +(3 rows) + +SELECT * FROM generate_series('2008-03-01 00:00'::timestamp, + '2008-03-04 12:00', '10 hours'); + generate_series +--------------------- + 2008-03-01 00:00:00 + 2008-03-01 10:00:00 + 2008-03-01 20:00:00 + 2008-03-02 06:00:00 + 2008-03-02 16:00:00 + 2008-03-03 02:00:00 + 2008-03-03 12:00:00 + 2008-03-03 22:00:00 + 2008-03-04 08:00:00 +(9 rows) + + + + + Subscript Generating Functions + + + + + Function + + + Description + + + + + + + + + generate_subscripts + + generate_subscripts ( array anyarray, dim integer ) + setof integer + + + Generates a series comprising the valid subscripts of + the dim'th dimension of the given array. + + + + + + generate_subscripts ( array anyarray, dim integer, reverse boolean ) + setof integer + + + Generates a series comprising the valid subscripts of + the dim'th dimension of the given array. + When reverse is true, returns the series in + reverse order. + + + + +
+ + + generate_subscripts is a convenience function that generates + the set of valid subscripts for the specified dimension of the given + array. + Zero rows are returned for arrays that do not have the requested dimension, + or if any input is NULL. + Some examples follow: + +-- basic usage: +SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s; + s +--- + 1 + 2 + 3 + 4 +(4 rows) + +-- presenting an array, the subscript and the subscripted +-- value requires a subquery: +SELECT * FROM arrays; + a +-------------------- + {-1,-2} + {100,200,300} +(2 rows) + +SELECT a AS array, s AS subscript, a[s] AS value +FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo; + array | subscript | value +---------------+-----------+------- + {-1,-2} | 1 | -1 + {-1,-2} | 2 | -2 + {100,200,300} | 1 | 100 + {100,200,300} | 2 | 200 + {100,200,300} | 3 | 300 +(5 rows) + +-- unnest a 2D array: +CREATE OR REPLACE FUNCTION unnest2(anyarray) +RETURNS SETOF anyelement AS $$ +select $1[i][j] + from generate_subscripts($1,1) g1(i), + generate_subscripts($1,2) g2(j); +$$ LANGUAGE sql IMMUTABLE; +CREATE FUNCTION +SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]); + unnest2 +--------- + 1 + 2 + 3 + 4 +(4 rows) + + + + + ordinality + + + + When a function in the FROM clause is suffixed + by WITH ORDINALITY, a bigint column is + appended to the function's output column(s), which starts from 1 and + increments by 1 for each row of the function's output. + This is most useful in the case of set returning + functions such as unnest(). + + +-- set returning function WITH ORDINALITY: +SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); + ls | n +-----------------+---- + pg_serial | 1 + pg_twophase | 2 + postmaster.opts | 3 + pg_notify | 4 + postgresql.conf | 5 + pg_tblspc | 6 + logfile | 7 + base | 8 + postmaster.pid | 9 + pg_ident.conf | 10 + global | 11 + pg_xact | 12 + pg_snapshots | 13 + pg_multixact | 14 + PG_VERSION | 15 + pg_wal | 16 + pg_hba.conf | 17 + pg_stat_tmp | 18 + pg_subtrans | 19 +(19 rows) + + + +
+ + + System Information Functions and Operators + + + shows several + functions that extract session and system information. + + + + In addition to the functions listed in this section, there are a number of + functions related to the statistics system that also provide system + information. See for more + information. + + + + Session Information Functions + + + + + Function + + + Description + + + + + + + + + current_catalog + + current_catalog + name + + + + current_database + + current_database () + name + + + Returns the name of the current database. (Databases are + called catalogs in the SQL standard, + so current_catalog is the standard's + spelling.) + + + + + + + current_query + + current_query () + text + + + Returns the text of the currently executing query, as submitted + by the client (which might contain more than one statement). + + + + + + + current_role + + current_role + name + + + This is equivalent to current_user. + + + + + + + current_schema + + + schema + current + + current_schema + name + + + current_schema () + name + + + Returns the name of the schema that is first in the search path (or a + null value if the search path is empty). This is the schema that will + be used for any tables or other named objects that are created without + specifying a target schema. + + + + + + + current_schemas + + + search path + current + + current_schemas ( include_implicit boolean ) + name[] + + + Returns an array of the names of all schemas presently in the + effective search path, in their priority order. (Items in the current + setting that do not correspond to + existing, searchable schemas are omitted.) If the Boolean argument + is true, then implicitly-searched system schemas + such as pg_catalog are included in the result. + + + + + + + current_user + + + user + current + + current_user + name + + + Returns the user name of the current execution context. + + + + + + + inet_client_addr + + inet_client_addr () + inet + + + Returns the IP address of the current client, + or NULL if the current connection is via a + Unix-domain socket. + + + + + + + inet_client_port + + inet_client_port () + integer + + + Returns the IP port number of the current client, + or NULL if the current connection is via a + Unix-domain socket. + + + + + + + inet_server_addr + + inet_server_addr () + inet + + + Returns the IP address on which the server accepted the current + connection, + or NULL if the current connection is via a + Unix-domain socket. + + + + + + + inet_server_port + + inet_server_port () + integer + + + Returns the IP port number on which the server accepted the current + connection, + or NULL if the current connection is via a + Unix-domain socket. + + + + + + + pg_backend_pid + + pg_backend_pid () + integer + + + Returns the process ID of the server process attached to the current + session. + + + + + + + pg_blocking_pids + + pg_blocking_pids ( integer ) + integer[] + + + Returns an array of the process ID(s) of the sessions that are + blocking the server process with the specified process ID from + acquiring a lock, or an empty array if there is no such server process + or it is not blocked. + + + One server process blocks another if it either holds a lock that + conflicts with the blocked process's lock request (hard block), or is + waiting for a lock that would conflict with the blocked process's lock + request and is ahead of it in the wait queue (soft block). When using + parallel queries the result always lists client-visible process IDs + (that is, pg_backend_pid results) even if the + actual lock is held or awaited by a child worker process. As a result + of that, there may be duplicated PIDs in the result. Also note that + when a prepared transaction holds a conflicting lock, it will be + represented by a zero process ID. + + + Frequent calls to this function could have some impact on database + performance, because it needs exclusive access to the lock manager's + shared state for a short time. + + + + + + + pg_conf_load_time + + pg_conf_load_time () + timestamp with time zone + + + Returns the time when the server configuration files were last loaded. + If the current session was alive at the time, this will be the time + when the session itself re-read the configuration files (so the + reading will vary a little in different sessions). Otherwise it is + the time when the postmaster process re-read the configuration files. + + + + + + + pg_current_logfile + + + Logging + pg_current_logfile function + + + current_logfiles + and the pg_current_logfile function + + + Logging + current_logfiles file and the pg_current_logfile + function + + pg_current_logfile ( text ) + text + + + Returns the path name of the log file currently in use by the logging + collector. The path includes the + directory and the individual log file name. The result + is NULL if the logging collector is disabled. + When multiple log files exist, each in a different + format, pg_current_logfile without an argument + returns the path of the file having the first format found in the + ordered list: stderr, + csvlog. NULL is returned + if no log file has any of these formats. + To request information about a specific log file format, supply + either csvlog or stderr as the + value of the optional parameter. The result is NULL + if the log format requested is not configured in + . + The result reflects the contents of + the current_logfiles file. + + + + + + + pg_my_temp_schema + + pg_my_temp_schema () + oid + + + Returns the OID of the current session's temporary schema, or zero if + it has none (because it has not created any temporary tables). + + + + + + + pg_is_other_temp_schema + + pg_is_other_temp_schema ( oid ) + boolean + + + Returns true if the given OID is the OID of another session's + temporary schema. (This can be useful, for example, to exclude other + sessions' temporary tables from a catalog display.) + + + + + + + pg_jit_available + + pg_jit_available () + boolean + + + Returns true if a JIT compiler extension is + available (see ) and the + configuration parameter is set to + on. + + + + + + + pg_listening_channels + + pg_listening_channels () + setof text + + + Returns the set of names of asynchronous notification channels that + the current session is listening to. + + + + + + + pg_notification_queue_usage + + pg_notification_queue_usage () + double precision + + + Returns the fraction (0–1) of the asynchronous notification + queue's maximum size that is currently occupied by notifications that + are waiting to be processed. + See and + for more information. + + + + + + + pg_postmaster_start_time + + pg_postmaster_start_time () + timestamp with time zone + + + Returns the time when the server started. + + + + + + + pg_safe_snapshot_blocking_pids + + pg_safe_snapshot_blocking_pids ( integer ) + integer[] + + + Returns an array of the process ID(s) of the sessions that are blocking + the server process with the specified process ID from acquiring a safe + snapshot, or an empty array if there is no such server process or it + is not blocked. + + + A session running a SERIALIZABLE transaction blocks + a SERIALIZABLE READ ONLY DEFERRABLE transaction + from acquiring a snapshot until the latter determines that it is safe + to avoid taking any predicate locks. See + for more information about + serializable and deferrable transactions. + + + Frequent calls to this function could have some impact on database + performance, because it needs access to the predicate lock manager's + shared state for a short time. + + + + + + + pg_trigger_depth + + pg_trigger_depth () + integer + + + Returns the current nesting level + of PostgreSQL triggers (0 if not called, + directly or indirectly, from inside a trigger). + + + + + + + session_user + + session_user + name + + + Returns the session user's name. + + + + + + + user + + user + name + + + This is equivalent to current_user. + + + + + + + version + + version () + text + + + Returns a string describing the PostgreSQL + server's version. You can also get this information from + , or for a machine-readable + version use . Software + developers should use server_version_num (available + since 8.2) or instead of + parsing the text version. + + + + +
+ + + + current_catalog, + current_role, + current_schema, + current_user, + session_user, + and user have special syntactic status + in SQL: they must be called without trailing + parentheses. In PostgreSQL, parentheses can optionally be used with + current_schema, but not with the others. + + + + + The session_user is normally the user who initiated + the current database connection; but superusers can change this setting + with . + The current_user is the user identifier + that is applicable for permission checking. Normally it is equal + to the session user, but it can be changed with + . + It also changes during the execution of + functions with the attribute SECURITY DEFINER. + In Unix parlance, the session user is the real user and + the current user is the effective user. + current_role and user are + synonyms for current_user. (The SQL standard draws + a distinction between current_role + and current_user, but PostgreSQL + does not, since it unifies users and roles into a single kind of entity.) + + + + privilege + querying + + + + lists functions that + allow querying object access privileges programmatically. + (See for more information about + privileges.) + In these functions, the user whose privileges are being inquired about + can be specified by name or by OID + (pg_authid.oid), or if + the name is given as public then the privileges of the + PUBLIC pseudo-role are checked. Also, the user + argument can be omitted entirely, in which case + the current_user is assumed. + The object that is being inquired about can be specified either by name or + by OID, too. When specifying by name, a schema name can be included if + relevant. + The access privilege of interest is specified by a text string, which must + evaluate to one of the appropriate privilege keywords for the object's type + (e.g., SELECT). Optionally, WITH GRANT + OPTION can be added to a privilege type to test whether the + privilege is held with grant option. Also, multiple privilege types can be + listed separated by commas, in which case the result will be true if any of + the listed privileges is held. (Case of the privilege string is not + significant, and extra whitespace is allowed between but not within + privilege names.) + Some examples: + +SELECT has_table_privilege('myschema.mytable', 'select'); +SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION'); + + + + + Access Privilege Inquiry Functions + + + + + Function + + + Description + + + + + + + + + has_any_column_privilege + + has_any_column_privilege ( + user name or oid, + table text or oid, + privilege text ) + boolean + + + Does user have privilege for any column of table? + This succeeds either if the privilege is held for the whole table, or + if there is a column-level grant of the privilege for at least one + column. + Allowable privilege types are + SELECT, INSERT, + UPDATE, and REFERENCES. + + + + + + + has_column_privilege + + has_column_privilege ( + user name or oid, + table text or oid, + column text or smallint, + privilege text ) + boolean + + + Does user have privilege for the specified table column? + This succeeds either if the privilege is held for the whole table, or + if there is a column-level grant of the privilege for the column. + The column can be specified by name or by attribute number + (pg_attribute.attnum). + Allowable privilege types are + SELECT, INSERT, + UPDATE, and REFERENCES. + + + + + + + has_database_privilege + + has_database_privilege ( + user name or oid, + database text or oid, + privilege text ) + boolean + + + Does user have privilege for database? + Allowable privilege types are + CREATE, + CONNECT, + TEMPORARY, and + TEMP (which is equivalent to + TEMPORARY). + + + + + + + has_foreign_data_wrapper_privilege + + has_foreign_data_wrapper_privilege ( + user name or oid, + fdw text or oid, + privilege text ) + boolean + + + Does user have privilege for foreign-data wrapper? + The only allowable privilege type is USAGE. + + + + + + + has_function_privilege + + has_function_privilege ( + user name or oid, + function text or oid, + privilege text ) + boolean + + + Does user have privilege for function? + The only allowable privilege type is EXECUTE. + + + When specifying a function by name rather than by OID, the allowed + input is the same as for the regprocedure data type (see + ). + An example is: + +SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); + + + + + + + + has_language_privilege + + has_language_privilege ( + user name or oid, + language text or oid, + privilege text ) + boolean + + + Does user have privilege for language? + The only allowable privilege type is USAGE. + + + + + + + has_schema_privilege + + has_schema_privilege ( + user name or oid, + schema text or oid, + privilege text ) + boolean + + + Does user have privilege for schema? + Allowable privilege types are + CREATE and + USAGE. + + + + + + + has_sequence_privilege + + has_sequence_privilege ( + user name or oid, + sequence text or oid, + privilege text ) + boolean + + + Does user have privilege for sequence? + Allowable privilege types are + USAGE, + SELECT, and + UPDATE. + + + + + + + has_server_privilege + + has_server_privilege ( + user name or oid, + server text or oid, + privilege text ) + boolean + + + Does user have privilege for foreign server? + The only allowable privilege type is USAGE. + + + + + + + has_table_privilege + + has_table_privilege ( + user name or oid, + table text or oid, + privilege text ) + boolean + + + Does user have privilege for table? + Allowable privilege types + are SELECT, INSERT, + UPDATE, DELETE, + TRUNCATE, REFERENCES, + and TRIGGER. + + + + + + + has_tablespace_privilege + + has_tablespace_privilege ( + user name or oid, + tablespace text or oid, + privilege text ) + boolean + + + Does user have privilege for tablespace? + The only allowable privilege type is CREATE. + + + + + + + has_type_privilege + + has_type_privilege ( + user name or oid, + type text or oid, + privilege text ) + boolean + + + Does user have privilege for data type? + The only allowable privilege type is USAGE. + When specifying a type by name rather than by OID, the allowed input + is the same as for the regtype data type (see + ). + + + + + + + pg_has_role + + pg_has_role ( + user name or oid, + role text or oid, + privilege text ) + boolean + + + Does user have privilege for role? + Allowable privilege types are + MEMBER and USAGE. + MEMBER denotes direct or indirect membership in + the role (that is, the right to do SET ROLE), while + USAGE denotes whether the privileges of the role + are immediately available without doing SET ROLE. + This function does not allow the special case of + setting user to public, + because the PUBLIC pseudo-role can never be a member of real roles. + + + + + + + row_security_active + + row_security_active ( + table text or oid ) + boolean + + + Is row-level security active for the specified table in the context of + the current user and current environment? + + + + +
+ + + shows the operators + available for the aclitem type, which is the catalog + representation of access privileges. See + for information about how to read access privilege values. + + + + <type>aclitem</type> Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + + aclitemeq + + aclitem = aclitem + boolean + + + Are aclitems equal? (Notice that + type aclitem lacks the usual set of comparison + operators; it has only equality. In turn, aclitem + arrays can only be compared for equality.) + + + 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem + f + + + + + + + aclcontains + + aclitem[] @> aclitem + boolean + + + Does array contain the specified privileges? (This is true if there + is an array entry that matches the aclitem's grantee and + grantor, and has at least the specified set of privileges.) + + + '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*/hobbes'::aclitem + t + + + + + + aclitem[] ~ aclitem + boolean + + + This is a deprecated alias for @>. + + + '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] ~ 'calvin=r*/hobbes'::aclitem + t + + + + +
+ + + shows some additional + functions to manage the aclitem type. + + + + <type>aclitem</type> Functions + + + + + Function + + + Description + + + + + + + + + acldefault + + acldefault ( + type "char", + ownerId oid ) + aclitem[] + + + Constructs an aclitem array holding the default access + privileges for an object of type type belonging + to the role with OID ownerId. This represents + the access privileges that will be assumed when an object's ACL entry + is null. (The default access privileges are described in + .) + The type parameter must be one of + 'c' for COLUMN, + 'r' for TABLE and table-like objects, + 's' for SEQUENCE, + 'd' for DATABASE, + 'f' for FUNCTION or PROCEDURE, + 'l' for LANGUAGE, + 'L' for LARGE OBJECT, + 'n' for SCHEMA, + 't' for TABLESPACE, + 'F' for FOREIGN DATA WRAPPER, + 'S' for FOREIGN SERVER, + or + 'T' for TYPE or DOMAIN. + + + + + + + aclexplode + + aclexplode ( aclitem[] ) + setof record + ( grantor oid, + grantee oid, + privilege_type text, + is_grantable boolean ) + + + Returns the aclitem array as a set of rows. + If the grantee is the pseudo-role PUBLIC, it is represented by zero in + the grantee column. Each granted privilege is + represented as SELECT, INSERT, + etc. Note that each privilege is broken out as a separate row, so + only one keyword appears in the privilege_type + column. + + + + + + + makeaclitem + + makeaclitem ( + grantee oid, + grantor oid, + privileges text, + is_grantable boolean ) + aclitem + + + Constructs an aclitem with the given properties. + + + + +
+ + + shows functions that + determine whether a certain object is visible in the + current schema search path. + For example, a table is said to be visible if its + containing schema is in the search path and no table of the same + name appears earlier in the search path. This is equivalent to the + statement that the table can be referenced by name without explicit + schema qualification. Thus, to list the names of all visible tables: + +SELECT relname FROM pg_class WHERE pg_table_is_visible(oid); + + For functions and operators, an object in the search path is said to be + visible if there is no object of the same name and argument data + type(s) earlier in the path. For operator classes and families, + both the name and the associated index access method are considered. + + + + search path + object visibility + + + + Schema Visibility Inquiry Functions + + + + + Function + + + Description + + + + + + + + + pg_collation_is_visible + + pg_collation_is_visible ( collation oid ) + boolean + + + Is collation visible in search path? + + + + + + + pg_conversion_is_visible + + pg_conversion_is_visible ( conversion oid ) + boolean + + + Is conversion visible in search path? + + + + + + + pg_function_is_visible + + pg_function_is_visible ( function oid ) + boolean + + + Is function visible in search path? + (This also works for procedures and aggregates.) + + + + + + + pg_opclass_is_visible + + pg_opclass_is_visible ( opclass oid ) + boolean + + + Is operator class visible in search path? + + + + + + + pg_operator_is_visible + + pg_operator_is_visible ( operator oid ) + boolean + + + Is operator visible in search path? + + + + + + + pg_opfamily_is_visible + + pg_opfamily_is_visible ( opclass oid ) + boolean + + + Is operator family visible in search path? + + + + + + + pg_statistics_obj_is_visible + + pg_statistics_obj_is_visible ( stat oid ) + boolean + + + Is statistics object visible in search path? + + + + + + + pg_table_is_visible + + pg_table_is_visible ( table oid ) + boolean + + + Is table visible in search path? + (This works for all types of relations, including views, materialized + views, indexes, sequences and foreign tables.) + + + + + + + pg_ts_config_is_visible + + pg_ts_config_is_visible ( config oid ) + boolean + + + Is text search configuration visible in search path? + + + + + + + pg_ts_dict_is_visible + + pg_ts_dict_is_visible ( dict oid ) + boolean + + + Is text search dictionary visible in search path? + + + + + + + pg_ts_parser_is_visible + + pg_ts_parser_is_visible ( parser oid ) + boolean + + + Is text search parser visible in search path? + + + + + + + pg_ts_template_is_visible + + pg_ts_template_is_visible ( template oid ) + boolean + + + Is text search template visible in search path? + + + + + + + pg_type_is_visible + + pg_type_is_visible ( type oid ) + boolean + + + Is type (or domain) visible in search path? + + + + +
+ + + All these functions require object OIDs to identify the object to be + checked. If you want to test an object by name, it is convenient to use + the OID alias types (regclass, regtype, + regprocedure, regoperator, regconfig, + or regdictionary), + for example: + +SELECT pg_type_is_visible('myschema.widget'::regtype); + + Note that it would not make much sense to test a non-schema-qualified + type name in this way — if the name can be recognized at all, it must be visible. + + + + lists functions that + extract information from the system catalogs. + + + + System Catalog Information Functions + + + + + Function + + + Description + + + + + + + + + format_type + + format_type ( type oid, typemod integer ) + text + + + Returns the SQL name for a data type that is identified by its type + OID and possibly a type modifier. Pass NULL for the type modifier if + no specific modifier is known. + + + + + + + pg_get_catalog_foreign_keys + + pg_get_catalog_foreign_keys () + setof record + ( fktable regclass, + fkcols text[], + pktable regclass, + pkcols text[], + is_array boolean, + is_opt boolean ) + + + Returns a set of records describing the foreign key relationships + that exist within the PostgreSQL system + catalogs. + The fktable column contains the name of the + referencing catalog, and the fkcols column + contains the name(s) of the referencing column(s). Similarly, + the pktable column contains the name of the + referenced catalog, and the pkcols column + contains the name(s) of the referenced column(s). + If is_array is true, the last referencing + column is an array, each of whose elements should match some entry + in the referenced catalog. + If is_opt is true, the referencing column(s) + are allowed to contain zeroes instead of a valid reference. + + + + + + + pg_get_constraintdef + + pg_get_constraintdef ( constraint oid , pretty boolean ) + text + + + Reconstructs the creating command for a constraint. + (This is a decompiled reconstruction, not the original text + of the command.) + + + + + + + pg_get_expr + + pg_get_expr ( expr pg_node_tree, relation oid , pretty boolean ) + text + + + Decompiles the internal form of an expression stored in the system + catalogs, such as the default value for a column. If the expression + might contain Vars, specify the OID of the relation they refer to as + the second parameter; if no Vars are expected, passing zero is + sufficient. + + + + + + + pg_get_functiondef + + pg_get_functiondef ( func oid ) + text + + + Reconstructs the creating command for a function or procedure. + (This is a decompiled reconstruction, not the original text + of the command.) + The result is a complete CREATE OR REPLACE FUNCTION + or CREATE OR REPLACE PROCEDURE statement. + + + + + + + pg_get_function_arguments + + pg_get_function_arguments ( func oid ) + text + + + Reconstructs the argument list of a function or procedure, in the form + it would need to appear in within CREATE FUNCTION + (including default values). + + + + + + + pg_get_function_identity_arguments + + pg_get_function_identity_arguments ( func oid ) + text + + + Reconstructs the argument list necessary to identify a function or + procedure, in the form it would need to appear in within commands such + as ALTER FUNCTION. This form omits default values. + + + + + + + pg_get_function_result + + pg_get_function_result ( func oid ) + text + + + Reconstructs the RETURNS clause of a function, in + the form it would need to appear in within CREATE + FUNCTION. Returns NULL for a procedure. + + + + + + + pg_get_indexdef + + pg_get_indexdef ( index oid , column integer, pretty boolean ) + text + + + Reconstructs the creating command for an index. + (This is a decompiled reconstruction, not the original text + of the command.) If column is supplied and is + not zero, only the definition of that column is reconstructed. + + + + + + + pg_get_keywords + + pg_get_keywords () + setof record + ( word text, + catcode "char", + barelabel boolean, + catdesc text, + baredesc text ) + + + Returns a set of records describing the SQL keywords recognized by the + server. The word column contains the + keyword. The catcode column contains a + category code: U for an unreserved + keyword, C for a keyword that can be a column + name, T for a keyword that can be a type or + function name, or R for a fully reserved keyword. + The barelabel column + contains true if the keyword can be used as + a bare column label in SELECT lists, + or false if it can only be used + after AS. + The catdesc column contains a + possibly-localized string describing the keyword's category. + The baredesc column contains a + possibly-localized string describing the keyword's column label status. + + + + + + + pg_get_ruledef + + pg_get_ruledef ( rule oid , pretty boolean ) + text + + + Reconstructs the creating command for a rule. + (This is a decompiled reconstruction, not the original text + of the command.) + + + + + + + pg_get_serial_sequence + + pg_get_serial_sequence ( table text, column text ) + text + + + Returns the name of the sequence associated with a column, + or NULL if no sequence is associated with the column. + If the column is an identity column, the associated sequence is the + sequence internally created for that column. + For columns created using one of the serial types + (serial, smallserial, bigserial), + it is the sequence created for that serial column definition. + In the latter case, the association can be modified or removed + with ALTER SEQUENCE OWNED BY. + (This function probably should have been + called pg_get_owned_sequence; its current name + reflects the fact that it has historically been used with serial-type + columns.) The first parameter is a table name with optional + schema, and the second parameter is a column name. Because the first + parameter potentially contains both schema and table names, it is + parsed per usual SQL rules, meaning it is lower-cased by default. + The second parameter, being just a column name, is treated literally + and so has its case preserved. The result is suitably formatted + for passing to the sequence functions (see + ). + + + A typical use is in reading the current value of the sequence for an + identity or serial column, for example: + +SELECT currval(pg_get_serial_sequence('sometable', 'id')); + + + + + + + + pg_get_statisticsobjdef + + pg_get_statisticsobjdef ( statobj oid ) + text + + + Reconstructs the creating command for an extended statistics object. + (This is a decompiled reconstruction, not the original text + of the command.) + + + + + + + pg_get_triggerdef + +pg_get_triggerdef ( trigger oid , pretty boolean ) + text + + + Reconstructs the creating command for a trigger. + (This is a decompiled reconstruction, not the original text + of the command.) + + + + + + + pg_get_userbyid + + pg_get_userbyid ( role oid ) + name + + + Returns a role's name given its OID. + + + + + + + pg_get_viewdef + + pg_get_viewdef ( view oid , pretty boolean ) + text + + + Reconstructs the underlying SELECT command for a + view or materialized view. (This is a decompiled reconstruction, not + the original text of the command.) + + + + + + pg_get_viewdef ( view oid, wrap_column integer ) + text + + + Reconstructs the underlying SELECT command for a + view or materialized view. (This is a decompiled reconstruction, not + the original text of the command.) In this form of the function, + pretty-printing is always enabled, and long lines are wrapped to try + to keep them shorter than the specified number of columns. + + + + + + pg_get_viewdef ( view text , pretty boolean ) + text + + + Reconstructs the underlying SELECT command for a + view or materialized view, working from a textual name for the view + rather than its OID. (This is deprecated; use the OID variant + instead.) + + + + + + + pg_index_column_has_property + + pg_index_column_has_property ( index regclass, column integer, property text ) + boolean + + + Tests whether an index column has the named property. + Common index column properties are listed in + . + (Note that extension access methods can define additional property + names for their indexes.) + NULL is returned if the property name is not known + or does not apply to the particular object, or if the OID or column + number does not identify a valid object. + + + + + + + pg_index_has_property + + pg_index_has_property ( index regclass, property text ) + boolean + + + Tests whether an index has the named property. + Common index properties are listed in + . + (Note that extension access methods can define additional property + names for their indexes.) + NULL is returned if the property name is not known + or does not apply to the particular object, or if the OID does not + identify a valid object. + + + + + + + pg_indexam_has_property + + pg_indexam_has_property ( am oid, property text ) + boolean + + + Tests whether an index access method has the named property. + Access method properties are listed in + . + NULL is returned if the property name is not known + or does not apply to the particular object, or if the OID does not + identify a valid object. + + + + + + + pg_options_to_table + + pg_options_to_table ( options_array text[] ) + setof record + ( option_name text, + option_value text ) + + + Returns the set of storage options represented by a value from + pg_class.reloptions or + pg_attribute.attoptions. + + + + + + + pg_tablespace_databases + + pg_tablespace_databases ( tablespace oid ) + setof oid + + + Returns the set of OIDs of databases that have objects stored in the + specified tablespace. If this function returns any rows, the + tablespace is not empty and cannot be dropped. To identify the specific + objects populating the tablespace, you will need to connect to the + database(s) identified by pg_tablespace_databases + and query their pg_class catalogs. + + + + + + + pg_tablespace_location + + pg_tablespace_location ( tablespace oid ) + text + + + Returns the file system path that this tablespace is located in. + + + + + + + pg_typeof + + pg_typeof ( "any" ) + regtype + + + Returns the OID of the data type of the value that is passed to it. + This can be helpful for troubleshooting or dynamically constructing + SQL queries. The function is declared as + returning regtype, which is an OID alias type (see + ); this means that it is the same as an + OID for comparison purposes but displays as a type name. + + + For example: + +SELECT pg_typeof(33); + pg_typeof +----------- + integer + +SELECT typlen FROM pg_type WHERE oid = pg_typeof(33); + typlen +-------- + 4 + + + + + + + + COLLATION FOR + + COLLATION FOR ( "any" ) + text + + + Returns the name of the collation of the value that is passed to it. + The value is quoted and schema-qualified if necessary. If no + collation was derived for the argument expression, + then NULL is returned. If the argument is not of a + collatable data type, then an error is raised. + + + For example: + +SELECT collation for (description) FROM pg_description LIMIT 1; + pg_collation_for +------------------ + "default" + +SELECT collation for ('foo' COLLATE "de_DE"); + pg_collation_for +------------------ + "de_DE" + + + + + + + + to_regclass + + to_regclass ( text ) + regclass + + + Translates a textual relation name to its OID. A similar result is + obtained by casting the string to type regclass (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regcollation + + to_regcollation ( text ) + regcollation + + + Translates a textual collation name to its OID. A similar result is + obtained by casting the string to type regcollation (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regnamespace + + to_regnamespace ( text ) + regnamespace + + + Translates a textual schema name to its OID. A similar result is + obtained by casting the string to type regnamespace (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regoper + + to_regoper ( text ) + regoper + + + Translates a textual operator name to its OID. A similar result is + obtained by casting the string to type regoper (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found or is ambiguous. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regoperator + + to_regoperator ( text ) + regoperator + + + Translates a textual operator name (with parameter types) to its OID. A similar result is + obtained by casting the string to type regoperator (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regproc + + to_regproc ( text ) + regproc + + + Translates a textual function or procedure name to its OID. A similar result is + obtained by casting the string to type regproc (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found or is ambiguous. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regprocedure + + to_regprocedure ( text ) + regprocedure + + + Translates a textual function or procedure name (with argument types) to its OID. A similar result is + obtained by casting the string to type regprocedure (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regrole + + to_regrole ( text ) + regrole + + + Translates a textual role name to its OID. A similar result is + obtained by casting the string to type regrole (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found. Also unlike the cast, this does not accept + a numeric OID as input. + + + + + + + to_regtype + + to_regtype ( text ) + regtype + + + Translates a textual type name to its OID. A similar result is + obtained by casting the string to type regtype (see + ); however, this function will return + NULL rather than throwing an error if the name is + not found. Also unlike the cast, this does not accept + a numeric OID as input. + + + + +
+ + + Most of the functions that reconstruct (decompile) database objects + have an optional pretty flag, which + if true causes the result to + be pretty-printed. Pretty-printing suppresses unnecessary + parentheses and adds whitespace for legibility. + The pretty-printed format is more readable, but the default format + is more likely to be interpreted the same way by future versions of + PostgreSQL; so avoid using pretty-printed output + for dump purposes. Passing false for + the pretty parameter yields the same result as + omitting the parameter. + + + + Index Column Properties + + + NameDescription + + + + asc + Does the column sort in ascending order on a forward scan? + + + + desc + Does the column sort in descending order on a forward scan? + + + + nulls_first + Does the column sort with nulls first on a forward scan? + + + + nulls_last + Does the column sort with nulls last on a forward scan? + + + + orderable + Does the column possess any defined sort ordering? + + + + distance_orderable + Can the column be scanned in order by a distance + operator, for example ORDER BY col <-> constant ? + + + + returnable + Can the column value be returned by an index-only scan? + + + + search_array + Does the column natively support col = ANY(array) + searches? + + + + search_nulls + Does the column support IS NULL and + IS NOT NULL searches? + + + + +
+ + + Index Properties + + + NameDescription + + + + clusterable + Can the index be used in a CLUSTER command? + + + + index_scan + Does the index support plain (non-bitmap) scans? + + + + bitmap_scan + Does the index support bitmap scans? + + + + backward_scan + Can the scan direction be changed in mid-scan (to + support FETCH BACKWARD on a cursor without + needing materialization)? + + + + +
+ + + Index Access Method Properties + + + NameDescription + + + + can_order + Does the access method support ASC, + DESC and related keywords in + CREATE INDEX? + + + + can_unique + Does the access method support unique indexes? + + + + can_multi_col + Does the access method support indexes with multiple columns? + + + + can_exclude + Does the access method support exclusion constraints? + + + + can_include + Does the access method support the INCLUDE + clause of CREATE INDEX? + + + + +
+ + + lists functions related to + database object identification and addressing. + + + + Object Information and Addressing Functions + + + + + Function + + + Description + + + + + + + + + pg_describe_object + + pg_describe_object ( classid oid, objid oid, objsubid integer ) + text + + + Returns a textual description of a database object identified by + catalog OID, object OID, and sub-object ID (such as a column number + within a table; the sub-object ID is zero when referring to a whole + object). This description is intended to be human-readable, and might + be translated, depending on server configuration. This is especially + useful to determine the identity of an object referenced in the + pg_depend catalog. This function returns + NULL values for undefined objects. + + + + + + + pg_identify_object + + pg_identify_object ( classid oid, objid oid, objsubid integer ) + record + ( type text, + schema text, + name text, + identity text ) + + + Returns a row containing enough information to uniquely identify the + database object specified by catalog OID, object OID and sub-object + ID. + This information is intended to be machine-readable, and is never + translated. + type identifies the type of database object; + schema is the schema name that the object + belongs in, or NULL for object types that do not + belong to schemas; + name is the name of the object, quoted if + necessary, if the name (along with schema name, if pertinent) is + sufficient to uniquely identify the object, + otherwise NULL; + identity is the complete object identity, with + the precise format depending on object type, and each name within the + format being schema-qualified and quoted as necessary. Undefined + objects are identified with NULL values. + + + + + + + pg_identify_object_as_address + + pg_identify_object_as_address ( classid oid, objid oid, objsubid integer ) + record + ( type text, + object_names text[], + object_args text[] ) + + + Returns a row containing enough information to uniquely identify the + database object specified by catalog OID, object OID and sub-object + ID. + The returned information is independent of the current server, that + is, it could be used to identify an identically named object in + another server. + type identifies the type of database object; + object_names and + object_args + are text arrays that together form a reference to the object. + These three values can be passed + to pg_get_object_address to obtain the internal + address of the object. + + + + + + + pg_get_object_address + + pg_get_object_address ( type text, object_names text[], object_args text[] ) + record + ( classid oid, + objid oid, + objsubid integer ) + + + Returns a row containing enough information to uniquely identify the + database object specified by a type code and object name and argument + arrays. + The returned values are the ones that would be used in system catalogs + such as pg_depend; they can be passed to + other system functions such as pg_describe_object + or pg_identify_object. + classid is the OID of the system catalog + containing the object; + objid is the OID of the object itself, and + objsubid is the sub-object ID, or zero if none. + This function is the inverse + of pg_identify_object_as_address. + Undefined objects are identified with NULL values. + + + + +
+ + + comment + about database objects + + + + The functions shown in + extract comments previously stored with the + command. A null value is returned if no + comment could be found for the specified parameters. + + + + Comment Information Functions + + + + + Function + + + Description + + + + + + + + + col_description + + col_description ( table oid, column integer ) + text + + + Returns the comment for a table column, which is specified by the OID + of its table and its column number. + (obj_description cannot be used for table + columns, since columns do not have OIDs of their own.) + + + + + + + obj_description + + obj_description ( object oid, catalog name ) + text + + + Returns the comment for a database object specified by its OID and the + name of the containing system catalog. For + example, obj_description(123456, 'pg_class') would + retrieve the comment for the table with OID 123456. + + + + + + obj_description ( object oid ) + text + + + Returns the comment for a database object specified by its OID alone. + This is deprecated since there is no guarantee + that OIDs are unique across different system catalogs; therefore, the + wrong comment might be returned. + + + + + + + shobj_description + + shobj_description ( object oid, catalog name ) + text + + + Returns the comment for a shared database object specified by its OID + and the name of the containing system catalog. This is just + like obj_description except that it is used for + retrieving comments on shared objects (that is, databases, roles, and + tablespaces). Some system catalogs are global to all databases within + each cluster, and the descriptions for objects in them are stored + globally as well. + + + + +
+ + + The functions shown in + provide server transaction information in an exportable form. The main + use of these functions is to determine which transactions were committed + between two snapshots. + + + + Transaction ID and Snapshot Information Functions + + + + + Function + + + Description + + + + + + + + + pg_current_xact_id + + pg_current_xact_id () + xid8 + + + Returns the current transaction's ID. It will assign a new one if the + current transaction does not have one already (because it has not + performed any database updates). + + + + + + + pg_current_xact_id_if_assigned + + pg_current_xact_id_if_assigned () + xid8 + + + Returns the current transaction's ID, or NULL if no + ID is assigned yet. (It's best to use this variant if the transaction + might otherwise be read-only, to avoid unnecessary consumption of an + XID.) + + + + + + + pg_xact_status + + pg_xact_status ( xid8 ) + text + + + Reports the commit status of a recent transaction. + The result is one of in progress, + committed, or aborted, + provided that the transaction is recent enough that the system retains + the commit status of that transaction. + If it is old enough that no references to the transaction survive in + the system and the commit status information has been discarded, the + result is NULL. + Applications might use this function, for example, to determine + whether their transaction committed or aborted after the application + and database server become disconnected while + a COMMIT is in progress. + Note that prepared transactions are reported as in + progress; applications must check pg_prepared_xacts + if they need to determine whether a transaction ID belongs to a + prepared transaction. + + + + + + + pg_current_snapshot + + pg_current_snapshot () + pg_snapshot + + + Returns a current snapshot, a data structure + showing which transaction IDs are now in-progress. + + + + + + + pg_snapshot_xip + + pg_snapshot_xip ( pg_snapshot ) + setof xid8 + + + Returns the set of in-progress transaction IDs contained in a snapshot. + + + + + + + pg_snapshot_xmax + + pg_snapshot_xmax ( pg_snapshot ) + xid8 + + + Returns the xmax of a snapshot. + + + + + + + pg_snapshot_xmin + + pg_snapshot_xmin ( pg_snapshot ) + xid8 + + + Returns the xmin of a snapshot. + + + + + + + pg_visible_in_snapshot + + pg_visible_in_snapshot ( xid8, pg_snapshot ) + boolean + + + Is the given transaction ID visible according + to this snapshot (that is, was it completed before the snapshot was + taken)? Note that this function will not give the correct answer for + a subtransaction ID. + + + + +
+ + + The internal transaction ID type xid is 32 bits wide and + wraps around every 4 billion transactions. However, + the functions shown in use a + 64-bit type xid8 that does not wrap around during the life + of an installation, and can be converted to xid by casting if + required. The data type pg_snapshot stores information about + transaction ID visibility at a particular moment in time. Its components + are described in . + pg_snapshot's textual representation is + xmin:xmax:xip_list. + For example 10:20:10,14,15 means + xmin=10, xmax=20, xip_list=10, 14, 15. + + + + Snapshot Components + + + + Name + Description + + + + + + xmin + + Lowest transaction ID that was still active. All transaction IDs + less than xmin are either committed and visible, + or rolled back and dead. + + + + + xmax + + One past the highest completed transaction ID. All transaction IDs + greater than or equal to xmax had not yet + completed as of the time of the snapshot, and thus are invisible. + + + + + xip_list + + Transactions in progress at the time of the snapshot. A transaction + ID that is xmin <= X < + xmax and not in this list was already completed at the time + of the snapshot, and thus is either visible or dead according to its + commit status. This list does not include the transaction IDs of + subtransactions. + + + + +
+ + + In releases of PostgreSQL before 13 there was + no xid8 type, so variants of these functions were provided + that used bigint to represent a 64-bit XID, with a + correspondingly distinct snapshot data type txid_snapshot. + These older functions have txid in their names. They + are still supported for backward compatibility, but may be removed from a + future release. See . + + + + Deprecated Transaction ID and Snapshot Information Functions + + + + + Function + + + Description + + + + + + + + + txid_current + + txid_current () + bigint + + + See pg_current_xact_id(). + + + + + + + txid_current_if_assigned + + txid_current_if_assigned () + bigint + + + See pg_current_xact_id_if_assigned(). + + + + + + + txid_current_snapshot + + txid_current_snapshot () + txid_snapshot + + + See pg_current_snapshot(). + + + + + + + txid_snapshot_xip + + txid_snapshot_xip ( txid_snapshot ) + setof bigint + + + See pg_snapshot_xip(). + + + + + + + txid_snapshot_xmax + + txid_snapshot_xmax ( txid_snapshot ) + bigint + + + See pg_snapshot_xmax(). + + + + + + + txid_snapshot_xmin + + txid_snapshot_xmin ( txid_snapshot ) + bigint + + + See pg_snapshot_xmin(). + + + + + + + txid_visible_in_snapshot + + txid_visible_in_snapshot ( bigint, txid_snapshot ) + boolean + + + See pg_visible_in_snapshot(). + + + + + + + txid_status + + txid_status ( bigint ) + text + + + See pg_xact_status(). + + + + +
+ + + The functions shown in + provide information about when past transactions were committed. + They only provide useful data when the + configuration option is + enabled, and only for transactions that were committed after it was + enabled. + + + + Committed Transaction Information Functions + + + + + Function + + + Description + + + + + + + + + pg_xact_commit_timestamp + + pg_xact_commit_timestamp ( xid ) + timestamp with time zone + + + Returns the commit timestamp of a transaction. + + + + + + + pg_xact_commit_timestamp_origin + + pg_xact_commit_timestamp_origin ( xid ) + record + ( timestamp timestamp with time zone, + roident oid) + + + Returns the commit timestamp and replication origin of a transaction. + + + + + + + pg_last_committed_xact + + pg_last_committed_xact () + record + ( xid xid, + timestamp timestamp with time zone, + roident oid ) + + + Returns the transaction ID, commit timestamp and replication origin + of the latest committed transaction. + + + + +
+ + + The functions shown in + print information initialized during initdb, such + as the catalog version. They also show information about write-ahead + logging and checkpoint processing. This information is cluster-wide, + not specific to any one database. These functions provide most of the same + information, from the same source, as the + application. + + + + Control Data Functions + + + + + Function + + + Description + + + + + + + + + pg_control_checkpoint + + pg_control_checkpoint () + record + + + Returns information about current checkpoint state, as shown in + . + + + + + + + pg_control_system + + pg_control_system () + record + + + Returns information about current control file state, as shown in + . + + + + + + + pg_control_init + + pg_control_init () + record + + + Returns information about cluster initialization state, as shown in + . + + + + + + + pg_control_recovery + + pg_control_recovery () + record + + + Returns information about recovery state, as shown in + . + + + + +
+ + + <function>pg_control_checkpoint</function> Output Columns + + + + Column Name + Data Type + + + + + + + checkpoint_lsn + pg_lsn + + + + redo_lsn + pg_lsn + + + + redo_wal_file + text + + + + timeline_id + integer + + + + prev_timeline_id + integer + + + + full_page_writes + boolean + + + + next_xid + text + + + + next_oid + oid + + + + next_multixact_id + xid + + + + next_multi_offset + xid + + + + oldest_xid + xid + + + + oldest_xid_dbid + oid + + + + oldest_active_xid + xid + + + + oldest_multi_xid + xid + + + + oldest_multi_dbid + oid + + + + oldest_commit_ts_xid + xid + + + + newest_commit_ts_xid + xid + + + + checkpoint_time + timestamp with time zone + + + + +
+ + + <function>pg_control_system</function> Output Columns + + + + Column Name + Data Type + + + + + + + pg_control_version + integer + + + + catalog_version_no + integer + + + + system_identifier + bigint + + + + pg_control_last_modified + timestamp with time zone + + + + +
+ + + <function>pg_control_init</function> Output Columns + + + + Column Name + Data Type + + + + + + + max_data_alignment + integer + + + + database_block_size + integer + + + + blocks_per_segment + integer + + + + wal_block_size + integer + + + + bytes_per_wal_segment + integer + + + + max_identifier_length + integer + + + + max_index_columns + integer + + + + max_toast_chunk_size + integer + + + + large_object_chunk_size + integer + + + + float8_pass_by_value + boolean + + + + data_page_checksum_version + integer + + + + +
+ + + <function>pg_control_recovery</function> Output Columns + + + + Column Name + Data Type + + + + + + + min_recovery_end_lsn + pg_lsn + + + + min_recovery_end_timeline + integer + + + + backup_start_lsn + pg_lsn + + + + backup_end_lsn + pg_lsn + + + + end_of_backup_record_required + boolean + + + + +
+ +
+ + + System Administration Functions + + + The functions described in this section are used to control and + monitor a PostgreSQL installation. + + + + Configuration Settings Functions + + + SET + + + + SHOW + + + + configuration + of the server + functions + + + + shows the functions + available to query and alter run-time configuration parameters. + + + + Configuration Settings Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + current_setting + + current_setting ( setting_name text , missing_ok boolean ) + text + + + Returns the current value of the + setting setting_name. If there is no such + setting, current_setting throws an error + unless missing_ok is supplied and + is true (in which case NULL is returned). + This function corresponds to + the SQL command . + + + current_setting('datestyle') + ISO, MDY + + + + + + + set_config + + set_config ( + setting_name text, + new_value text, + is_local boolean ) + text + + + Sets the parameter setting_name + to new_value, and returns that value. + If is_local is true, the new + value will only apply during the current transaction. If you want the + new value to apply for the rest of the current session, + use false instead. This function corresponds to + the SQL command . + + + set_config('log_statement_stats', 'off', false) + off + + + + +
+ +
+ + + Server Signaling Functions + + + signal + backend processes + + + + The functions shown in send control signals to + other server processes. Use of these functions is restricted to + superusers by default but access may be granted to others using + GRANT, with noted exceptions. + + + + Each of these functions returns true if + the signal was successfully sent and false + if sending the signal failed. + + + + Server Signaling Functions + + + + + Function + + + Description + + + + + + + + + pg_cancel_backend + + pg_cancel_backend ( pid integer ) + boolean + + + Cancels the current query of the session whose backend process has the + specified process ID. This is also allowed if the + calling role is a member of the role whose backend is being canceled or + the calling role has been granted pg_signal_backend, + however only superusers can cancel superuser backends. + + + + + + + pg_log_backend_memory_contexts + + pg_log_backend_memory_contexts ( pid integer ) + boolean + + + Requests to log the memory contexts of the backend with the + specified process ID. These memory contexts will be logged at + LOG message level. They will appear in + the server log based on the log configuration set + (See for more information), + but will not be sent to the client regardless of + . + Only superusers can request to log the memory contexts. + + + + + + + pg_reload_conf + + pg_reload_conf () + boolean + + + Causes all processes of the PostgreSQL + server to reload their configuration files. (This is initiated by + sending a SIGHUP signal to the postmaster + process, which in turn sends SIGHUP to each + of its children.) You can use the + pg_file_settings and + pg_hba_file_rules views + to check the configuration files for possible errors, before reloading. + + + + + + + pg_rotate_logfile + + pg_rotate_logfile () + boolean + + + Signals the log-file manager to switch to a new output file + immediately. This works only when the built-in log collector is + running, since otherwise there is no log-file manager subprocess. + + + + + + + pg_terminate_backend + + pg_terminate_backend ( pid integer, timeout bigint DEFAULT 0 ) + boolean + + + Terminates the session whose backend process has the + specified process ID. This is also allowed if the calling role + is a member of the role whose backend is being terminated or the + calling role has been granted pg_signal_backend, + however only superusers can terminate superuser backends. + + + If timeout is not specified or zero, this + function returns true whether the process actually + terminates or not, indicating only that the sending of the signal was + successful. If the timeout is specified (in + milliseconds) and greater than zero, the function waits until the + process is actually terminated or until the given time has passed. If + the process is terminated, the function + returns true. On timeout, a warning is emitted and + false is returned. + + + + +
+ + + pg_cancel_backend and pg_terminate_backend + send signals (SIGINT or SIGTERM + respectively) to backend processes identified by process ID. + The process ID of an active backend can be found from + the pid column of the + pg_stat_activity view, or by listing the + postgres processes on the server (using + ps on Unix or the Task + Manager on Windows). + The role of an active backend can be found from the + usename column of the + pg_stat_activity view. + + + + pg_log_backend_memory_contexts can be used + to log the memory contexts of a backend process. For example: + +postgres=# SELECT pg_log_backend_memory_contexts(pg_backend_pid()); + pg_log_backend_memory_contexts +-------------------------------- + t +(1 row) + +One message for each memory context will be logged. For example: + +LOG: logging memory contexts of PID 10377 +STATEMENT: SELECT pg_log_backend_memory_contexts(pg_backend_pid()); +LOG: level: 0; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used +LOG: level: 1; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used +LOG: level: 1; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used +LOG: level: 1; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used +LOG: level: 1; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used +LOG: level: 1; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used +LOG: level: 1; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used +LOG: level: 1; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used +... +LOG: level: 1; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used +LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 used + + If there are more than 100 child contexts under the same parent, the first + 100 child contexts are logged, along with a summary of the remaining contexts. + Note that frequent calls to this function could incur significant overhead, + because it may generate a large number of log messages. + + +
+ + + Backup Control Functions + + + backup + + + + The functions shown in assist in making on-line backups. + These functions cannot be executed during recovery (except + non-exclusive pg_start_backup, + non-exclusive pg_stop_backup, + pg_is_in_backup, pg_backup_start_time + and pg_wal_lsn_diff). + + + + For details about proper usage of these functions, see + . + + + + Backup Control Functions + + + + + Function + + + Description + + + + + + + + + pg_create_restore_point + + pg_create_restore_point ( name text ) + pg_lsn + + + Creates a named marker record in the write-ahead log that can later be + used as a recovery target, and returns the corresponding write-ahead + log location. The given name can then be used with + to specify the point up to + which recovery will proceed. Avoid creating multiple restore points + with the same name, since recovery will stop at the first one whose + name matches the recovery target. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_current_wal_flush_lsn + + pg_current_wal_flush_lsn () + pg_lsn + + + Returns the current write-ahead log flush location (see notes below). + + + + + + + pg_current_wal_insert_lsn + + pg_current_wal_insert_lsn () + pg_lsn + + + Returns the current write-ahead log insert location (see notes below). + + + + + + + pg_current_wal_lsn + + pg_current_wal_lsn () + pg_lsn + + + Returns the current write-ahead log write location (see notes below). + + + + + + + pg_start_backup + + pg_start_backup ( + label text + , fast boolean + , exclusive boolean + ) + pg_lsn + + + Prepares the server to begin an on-line backup. The only required + parameter is an arbitrary user-defined label for the backup. + (Typically this would be the name under which the backup dump file + will be stored.) + If the optional second parameter is given as true, + it specifies executing pg_start_backup as quickly + as possible. This forces an immediate checkpoint which will cause a + spike in I/O operations, slowing any concurrently executing queries. + The optional third parameter specifies whether to perform an exclusive + or non-exclusive backup (default is exclusive). + + + When used in exclusive mode, this function writes a backup label file + (backup_label) and, if there are any links in + the pg_tblspc/ directory, a tablespace map file + (tablespace_map) into the database cluster's data + directory, then performs a checkpoint, and then returns the backup's + starting write-ahead log location. (The user can ignore this + result value, but it is provided in case it is useful.) When used in + non-exclusive mode, the contents of these files are instead returned + by the pg_stop_backup function, and should be + copied to the backup area by the user. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_stop_backup + + pg_stop_backup ( + exclusive boolean + , wait_for_archive boolean + ) + setof record + ( lsn pg_lsn, + labelfile text, + spcmapfile text ) + + + Finishes performing an exclusive or non-exclusive on-line backup. + The exclusive parameter must match the + previous pg_start_backup call. + In an exclusive backup, pg_stop_backup removes + the backup label file and, if it exists, the tablespace map file + created by pg_start_backup. In a non-exclusive + backup, the desired contents of these files are returned as part of + the result of the function, and should be written to files in the + backup area (not in the data directory). + + + There is an optional second parameter of type boolean. + If false, the function will return immediately after the backup is + completed, without waiting for WAL to be archived. This behavior is + only useful with backup software that independently monitors WAL + archiving. Otherwise, WAL required to make the backup consistent might + be missing and make the backup useless. By default or when this + parameter is true, pg_stop_backup will wait for + WAL to be archived when archiving is enabled. (On a standby, this + means that it will wait only when archive_mode = + always. If write activity on the primary is low, + it may be useful to run pg_switch_wal on the + primary in order to trigger an immediate segment switch.) + + + When executed on a primary, this function also creates a backup + history file in the write-ahead log archive area. The history file + includes the label given to pg_start_backup, the + starting and ending write-ahead log locations for the backup, and the + starting and ending times of the backup. After recording the ending + location, the current write-ahead log insertion point is automatically + advanced to the next write-ahead log file, so that the ending + write-ahead log file can be archived immediately to complete the + backup. + + + The result of the function is a single record. + The lsn column holds the backup's ending + write-ahead log location (which again can be ignored). The second and + third columns are NULL when ending an exclusive + backup; after a non-exclusive backup they hold the desired contents of + the label and tablespace map files. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + pg_stop_backup () + pg_lsn + + + Finishes performing an exclusive on-line backup. This simplified + version is equivalent to pg_stop_backup(true, + true), except that it only returns the pg_lsn + result. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_is_in_backup + + pg_is_in_backup () + boolean + + + Returns true if an on-line exclusive backup is in progress. + + + + + + + pg_backup_start_time + + pg_backup_start_time () + timestamp with time zone + + + Returns the start time of the current on-line exclusive backup if one + is in progress, otherwise NULL. + + + + + + + pg_switch_wal + + pg_switch_wal () + pg_lsn + + + Forces the server to switch to a new write-ahead log file, which + allows the current file to be archived (assuming you are using + continuous archiving). The result is the ending write-ahead log + location plus 1 within the just-completed write-ahead log file. If + there has been no write-ahead log activity since the last write-ahead + log switch, pg_switch_wal does nothing and + returns the start location of the write-ahead log file currently in + use. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_walfile_name + + pg_walfile_name ( lsn pg_lsn ) + text + + + Converts a write-ahead log location to the name of the WAL file + holding that location. + + + + + + + pg_walfile_name_offset + + pg_walfile_name_offset ( lsn pg_lsn ) + record + ( file_name text, + file_offset integer ) + + + Converts a write-ahead log location to a WAL file name and byte offset + within that file. + + + + + + + pg_wal_lsn_diff + + pg_wal_lsn_diff ( lsn1 pg_lsn, lsn2 pg_lsn ) + numeric + + + Calculates the difference in bytes (lsn1 - lsn2) between two write-ahead log + locations. This can be used + with pg_stat_replication or some of the + functions shown in to + get the replication lag. + + + + +
+ + + pg_current_wal_lsn displays the current write-ahead + log write location in the same format used by the above functions. + Similarly, pg_current_wal_insert_lsn displays the + current write-ahead log insertion location + and pg_current_wal_flush_lsn displays the current + write-ahead log flush location. The insertion location is + the logical end of the write-ahead log at any instant, + while the write location is the end of what has actually been written out + from the server's internal buffers, and the flush location is the last + location known to be written to durable storage. The write location is the + end of what can be examined from outside the server, and is usually what + you want if you are interested in archiving partially-complete write-ahead + log files. The insertion and flush locations are made available primarily + for server debugging purposes. These are all read-only operations and do + not require superuser permissions. + + + + You can use pg_walfile_name_offset to extract the + corresponding write-ahead log file name and byte offset from + a pg_lsn value. For example: + +postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); + file_name | file_offset +--------------------------+------------- + 00000001000000000000000D | 4039624 +(1 row) + + Similarly, pg_walfile_name extracts just the write-ahead log file name. + When the given write-ahead log location is exactly at a write-ahead log file boundary, both + these functions return the name of the preceding write-ahead log file. + This is usually the desired behavior for managing write-ahead log archiving + behavior, since the preceding file is the last one that currently + needs to be archived. + + +
+ + + Recovery Control Functions + + + The functions shown in provide information + about the current status of a standby server. + These functions may be executed both during recovery and in normal running. + + + + Recovery Information Functions + + + + + Function + + + Description + + + + + + + + + pg_is_in_recovery + + pg_is_in_recovery () + boolean + + + Returns true if recovery is still in progress. + + + + + + + pg_last_wal_receive_lsn + + pg_last_wal_receive_lsn () + pg_lsn + + + Returns the last write-ahead log location that has been received and + synced to disk by streaming replication. While streaming replication + is in progress this will increase monotonically. If recovery has + completed then this will remain static at the location of the last WAL + record received and synced to disk during recovery. If streaming + replication is disabled, or if it has not yet started, the function + returns NULL. + + + + + + + pg_last_wal_replay_lsn + + pg_last_wal_replay_lsn () + pg_lsn + + + Returns the last write-ahead log location that has been replayed + during recovery. If recovery is still in progress this will increase + monotonically. If recovery has completed then this will remain + static at the location of the last WAL record applied during recovery. + When the server has been started normally without recovery, the + function returns NULL. + + + + + + + pg_last_xact_replay_timestamp + + pg_last_xact_replay_timestamp () + timestamp with time zone + + + Returns the time stamp of the last transaction replayed during + recovery. This is the time at which the commit or abort WAL record + for that transaction was generated on the primary. If no transactions + have been replayed during recovery, the function + returns NULL. Otherwise, if recovery is still in + progress this will increase monotonically. If recovery has completed + then this will remain static at the time of the last transaction + applied during recovery. When the server has been started normally + without recovery, the function returns NULL. + + + + +
+ + + The functions shown in control the progress of recovery. + These functions may be executed only during recovery. + + + + Recovery Control Functions + + + + + Function + + + Description + + + + + + + + + pg_is_wal_replay_paused + + pg_is_wal_replay_paused () + boolean + + + Returns true if recovery pause is requested. + + + + + + + pg_get_wal_replay_pause_state + + pg_get_wal_replay_pause_state () + text + + + Returns recovery pause state. The return values are + not paused if pause is not requested, + pause requested if pause is requested but recovery is + not yet paused, and paused if the recovery is + actually paused. + + + + + + + pg_promote + + pg_promote ( wait boolean DEFAULT true, wait_seconds integer DEFAULT 60 ) + boolean + + + Promotes a standby server to primary status. + With wait set to true (the + default), the function waits until promotion is completed + or wait_seconds seconds have passed, and + returns true if promotion is successful + and false otherwise. + If wait is set to false, the + function returns true immediately after sending a + SIGUSR1 signal to the postmaster to trigger + promotion. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_wal_replay_pause + + pg_wal_replay_pause () + void + + + Request to pause recovery. A request doesn't mean that recovery stops + right away. If you want a guarantee that recovery is actually paused, + you need to check for the recovery pause state returned by + pg_get_wal_replay_pause_state(). Note that + pg_is_wal_replay_paused() returns whether a request + is made. While recovery is paused, no further database changes are applied. + If hot standby is active, all new queries will see the same consistent + snapshot of the database, and no further query conflicts will be generated + until recovery is resumed. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_wal_replay_resume + + pg_wal_replay_resume () + void + + + Restarts recovery if it was paused. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + +
+ + + pg_wal_replay_pause and + pg_wal_replay_resume cannot be executed while + a promotion is ongoing. If a promotion is triggered while recovery + is paused, the paused state ends and promotion continues. + + + + If streaming replication is disabled, the paused state may continue + indefinitely without a problem. If streaming replication is in + progress then WAL records will continue to be received, which will + eventually fill available disk space, depending upon the duration of + the pause, the rate of WAL generation and available disk space. + + +
+ + + Snapshot Synchronization Functions + + + PostgreSQL allows database sessions to synchronize their + snapshots. A snapshot determines which data is visible to the + transaction that is using the snapshot. Synchronized snapshots are + necessary when two or more sessions need to see identical content in the + database. If two sessions just start their transactions independently, + there is always a possibility that some third transaction commits + between the executions of the two START TRANSACTION commands, + so that one session sees the effects of that transaction and the other + does not. + + + + To solve this problem, PostgreSQL allows a transaction to + export the snapshot it is using. As long as the exporting + transaction remains open, other transactions can import its + snapshot, and thereby be guaranteed that they see exactly the same view + of the database that the first transaction sees. But note that any + database changes made by any one of these transactions remain invisible + to the other transactions, as is usual for changes made by uncommitted + transactions. So the transactions are synchronized with respect to + pre-existing data, but act normally for changes they make themselves. + + + + Snapshots are exported with the pg_export_snapshot function, + shown in , and + imported with the command. + + + + Snapshot Synchronization Functions + + + + + Function + + + Description + + + + + + + + + pg_export_snapshot + + pg_export_snapshot () + text + + + Saves the transaction's current snapshot and returns + a text string identifying the snapshot. This string must + be passed (outside the database) to clients that want to import the + snapshot. The snapshot is available for import only until the end of + the transaction that exported it. + + + A transaction can export more than one snapshot, if needed. Note that + doing so is only useful in READ COMMITTED + transactions, since in REPEATABLE READ and higher + isolation levels, transactions use the same snapshot throughout their + lifetime. Once a transaction has exported any snapshots, it cannot be + prepared with . + + + + +
+ +
+ + + Replication Management Functions + + + The functions shown + in are for + controlling and interacting with replication features. + See , + , and + + for information about the underlying features. + Use of functions for replication origin is only allowed to the + superuser by default, but may be allowed to other users by using the + GRANT command. + Use of functions for replication slots is restricted to superusers + and users having REPLICATION privilege. + + + + Many of these functions have equivalent commands in the replication + protocol; see . + + + + The functions described in + , + , and + + are also relevant for replication. + + + + Replication Management Functions + + + + + Function + + + Description + + + + + + + + + pg_create_physical_replication_slot + + pg_create_physical_replication_slot ( slot_name name , immediately_reserve boolean, temporary boolean ) + record + ( slot_name name, + lsn pg_lsn ) + + + Creates a new physical replication slot named + slot_name. The optional second parameter, + when true, specifies that the LSN for this + replication slot be reserved immediately; otherwise + the LSN is reserved on first connection from a streaming + replication client. Streaming changes from a physical slot is only + possible with the streaming-replication protocol — + see . The optional third + parameter, temporary, when set to true, specifies that + the slot should not be permanently stored to disk and is only meant + for use by the current session. Temporary slots are also + released upon any error. This function corresponds + to the replication protocol command CREATE_REPLICATION_SLOT + ... PHYSICAL. + + + + + + + pg_drop_replication_slot + + pg_drop_replication_slot ( slot_name name ) + void + + + Drops the physical or logical replication slot + named slot_name. Same as replication protocol + command DROP_REPLICATION_SLOT. For logical slots, this must + be called while connected to the same database the slot was created on. + + + + + + + pg_create_logical_replication_slot + + pg_create_logical_replication_slot ( slot_name name, plugin name , temporary boolean, two_phase boolean ) + record + ( slot_name name, + lsn pg_lsn ) + + + Creates a new logical (decoding) replication slot named + slot_name using the output plugin + plugin. The optional third + parameter, temporary, when set to true, specifies that + the slot should not be permanently stored to disk and is only meant + for use by the current session. Temporary slots are also + released upon any error. The optional fourth parameter, + two_phase, when set to true, specifies + that the decoding of prepared transactions is enabled for this + slot. A call to this function has the same effect as the replication + protocol command CREATE_REPLICATION_SLOT ... LOGICAL. + + + + + + + pg_copy_physical_replication_slot + + pg_copy_physical_replication_slot ( src_slot_name name, dst_slot_name name , temporary boolean ) + record + ( slot_name name, + lsn pg_lsn ) + + + Copies an existing physical replication slot named src_slot_name + to a physical replication slot named dst_slot_name. + The copied physical slot starts to reserve WAL from the same LSN as the + source slot. + temporary is optional. If temporary + is omitted, the same value as the source slot is used. + + + + + + + pg_copy_logical_replication_slot + + pg_copy_logical_replication_slot ( src_slot_name name, dst_slot_name name , temporary boolean , plugin name ) + record + ( slot_name name, + lsn pg_lsn ) + + + Copies an existing logical replication slot + named src_slot_name to a logical replication + slot named dst_slot_name, optionally changing + the output plugin and persistence. The copied logical slot starts + from the same LSN as the source logical slot. Both + temporary and plugin are + optional; if they are omitted, the values of the source slot are used. + + + + + + + pg_logical_slot_get_changes + + pg_logical_slot_get_changes ( slot_name name, upto_lsn pg_lsn, upto_nchanges integer, VARIADIC options text[] ) + setof record + ( lsn pg_lsn, + xid xid, + data text ) + + + Returns changes in the slot slot_name, starting + from the point from which changes have been consumed last. If + upto_lsn + and upto_nchanges are NULL, + logical decoding will continue until end of WAL. If + upto_lsn is non-NULL, decoding will include only + those transactions which commit prior to the specified LSN. If + upto_nchanges is non-NULL, decoding will + stop when the number of rows produced by decoding exceeds + the specified value. Note, however, that the actual number of + rows returned may be larger, since this limit is only checked after + adding the rows produced when decoding each new transaction commit. + + + + + + + pg_logical_slot_peek_changes + + pg_logical_slot_peek_changes ( slot_name name, upto_lsn pg_lsn, upto_nchanges integer, VARIADIC options text[] ) + setof record + ( lsn pg_lsn, + xid xid, + data text ) + + + Behaves just like + the pg_logical_slot_get_changes() function, + except that changes are not consumed; that is, they will be returned + again on future calls. + + + + + + + pg_logical_slot_get_binary_changes + + pg_logical_slot_get_binary_changes ( slot_name name, upto_lsn pg_lsn, upto_nchanges integer, VARIADIC options text[] ) + setof record + ( lsn pg_lsn, + xid xid, + data bytea ) + + + Behaves just like + the pg_logical_slot_get_changes() function, + except that changes are returned as bytea. + + + + + + + pg_logical_slot_peek_binary_changes + + pg_logical_slot_peek_binary_changes ( slot_name name, upto_lsn pg_lsn, upto_nchanges integer, VARIADIC options text[] ) + setof record + ( lsn pg_lsn, + xid xid, + data bytea ) + + + Behaves just like + the pg_logical_slot_peek_changes() function, + except that changes are returned as bytea. + + + + + + + pg_replication_slot_advance + + pg_replication_slot_advance ( slot_name name, upto_lsn pg_lsn ) + record + ( slot_name name, + end_lsn pg_lsn ) + + + Advances the current confirmed position of a replication slot named + slot_name. The slot will not be moved backwards, + and it will not be moved beyond the current insert location. Returns + the name of the slot and the actual position that it was advanced to. + The updated slot position information is written out at the next + checkpoint if any advancing is done. So in the event of a crash, the + slot may return to an earlier position. + + + + + + + pg_replication_origin_create + + pg_replication_origin_create ( node_name text ) + oid + + + Creates a replication origin with the given external + name, and returns the internal ID assigned to it. + + + + + + + pg_replication_origin_drop + + pg_replication_origin_drop ( node_name text ) + void + + + Deletes a previously-created replication origin, including any + associated replay progress. + + + + + + + pg_replication_origin_oid + + pg_replication_origin_oid ( node_name text ) + oid + + + Looks up a replication origin by name and returns the internal ID. If + no such replication origin is found an error is thrown. + + + + + + + pg_replication_origin_session_setup + + pg_replication_origin_session_setup ( node_name text ) + void + + + Marks the current session as replaying from the given + origin, allowing replay progress to be tracked. + Can only be used if no origin is currently selected. + Use pg_replication_origin_session_reset to undo. + + + + + + + pg_replication_origin_session_reset + + pg_replication_origin_session_reset () + void + + + Cancels the effects + of pg_replication_origin_session_setup(). + + + + + + + pg_replication_origin_session_is_setup + + pg_replication_origin_session_is_setup () + boolean + + + Returns true if a replication origin has been selected in the + current session. + + + + + + + pg_replication_origin_session_progress + + pg_replication_origin_session_progress ( flush boolean ) + pg_lsn + + + Returns the replay location for the replication origin selected in + the current session. The parameter flush + determines whether the corresponding local transaction will be + guaranteed to have been flushed to disk or not. + + + + + + + pg_replication_origin_xact_setup + + pg_replication_origin_xact_setup ( origin_lsn pg_lsn, origin_timestamp timestamp with time zone ) + void + + + Marks the current transaction as replaying a transaction that has + committed at the given LSN and timestamp. Can + only be called when a replication origin has been selected + using pg_replication_origin_session_setup. + + + + + + + pg_replication_origin_xact_reset + + pg_replication_origin_xact_reset () + void + + + Cancels the effects of + pg_replication_origin_xact_setup(). + + + + + + + pg_replication_origin_advance + + pg_replication_origin_advance ( node_name text, lsn pg_lsn ) + void + + + Sets replication progress for the given node to the given + location. This is primarily useful for setting up the initial + location, or setting a new location after configuration changes and + similar. Be aware that careless use of this function can lead to + inconsistently replicated data. + + + + + + + pg_replication_origin_progress + + pg_replication_origin_progress ( node_name text, flush boolean ) + pg_lsn + + + Returns the replay location for the given replication origin. The + parameter flush determines whether the + corresponding local transaction will be guaranteed to have been + flushed to disk or not. + + + + + + + pg_logical_emit_message + + pg_logical_emit_message ( transactional boolean, prefix text, content text ) + pg_lsn + + + pg_logical_emit_message ( transactional boolean, prefix text, content bytea ) + pg_lsn + + + Emits a logical decoding message. This can be used to pass generic + messages to logical decoding plugins through + WAL. The transactional parameter specifies if + the message should be part of the current transaction, or if it should + be written immediately and decoded as soon as the logical decoder + reads the record. The prefix parameter is a + textual prefix that can be used by logical decoding plugins to easily + recognize messages that are interesting for them. + The content parameter is the content of the + message, given either in text or binary form. + + + + +
+ +
+ + + Database Object Management Functions + + + The functions shown in calculate + the disk space usage of database objects, or assist in presentation + or understanding of usage results. bigint results + are measured in bytes. If an OID that does + not represent an existing object is passed to one of these + functions, NULL is returned. + + + + Database Object Size Functions + + + + + Function + + + Description + + + + + + + + + pg_column_size + + pg_column_size ( "any" ) + integer + + + Shows the number of bytes used to store any individual data value. If + applied directly to a table column value, this reflects any + compression that was done. + + + + + + + pg_column_compression + + pg_column_compression ( "any" ) + text + + + Shows the compression algorithm that was used to compress + an individual variable-length value. Returns NULL + if the value is not compressed. + + + + + + + pg_database_size + + pg_database_size ( name ) + bigint + + + pg_database_size ( oid ) + bigint + + + Computes the total disk space used by the database with the specified + name or OID. To use this function, you must + have CONNECT privilege on the specified database + (which is granted by default) or be a member of + the pg_read_all_stats role. + + + + + + + pg_indexes_size + + pg_indexes_size ( regclass ) + bigint + + + Computes the total disk space used by indexes attached to the + specified table. + + + + + + + pg_relation_size + + pg_relation_size ( relation regclass , fork text ) + bigint + + + Computes the disk space used by one fork of the + specified relation. (Note that for most purposes it is more + convenient to use the higher-level + functions pg_total_relation_size + or pg_table_size, which sum the sizes of all + forks.) With one argument, this returns the size of the main data + fork of the relation. The second argument can be provided to specify + which fork to examine: + + + + main returns the size of the main + data fork of the relation. + + + + + fsm returns the size of the Free Space Map + (see ) associated with the relation. + + + + + vm returns the size of the Visibility Map + (see ) associated with the relation. + + + + + init returns the size of the initialization + fork, if any, associated with the relation. + + + + + + + + + + pg_size_bytes + + pg_size_bytes ( text ) + bigint + + + Converts a size in human-readable format (as returned + by pg_size_pretty) into bytes. + + + + + + + pg_size_pretty + + pg_size_pretty ( bigint ) + text + + + pg_size_pretty ( numeric ) + text + + + Converts a size in bytes into a more easily human-readable format with + size units (bytes, kB, MB, GB or TB as appropriate). Note that the + units are powers of 2 rather than powers of 10, so 1kB is 1024 bytes, + 1MB is 10242 = 1048576 bytes, and so on. + + + + + + + pg_table_size + + pg_table_size ( regclass ) + bigint + + + Computes the disk space used by the specified table, excluding indexes + (but including its TOAST table if any, free space map, and visibility + map). + + + + + + + pg_tablespace_size + + pg_tablespace_size ( name ) + bigint + + + pg_tablespace_size ( oid ) + bigint + + + Computes the total disk space used in the tablespace with the + specified name or OID. To use this function, you must + have CREATE privilege on the specified tablespace + or be a member of the pg_read_all_stats role, + unless it is the default tablespace for the current database. + + + + + + + pg_total_relation_size + + pg_total_relation_size ( regclass ) + bigint + + + Computes the total disk space used by the specified table, including + all indexes and TOAST data. The result is + equivalent to pg_table_size + + pg_indexes_size. + + + + +
+ + + The functions above that operate on tables or indexes accept a + regclass argument, which is simply the OID of the table or index + in the pg_class system catalog. You do not have to look up + the OID by hand, however, since the regclass data type's input + converter will do the work for you. See + for details. + + + + The functions shown in assist + in identifying the specific disk files associated with database objects. + + + + Database Object Location Functions + + + + + Function + + + Description + + + + + + + + + pg_relation_filenode + + pg_relation_filenode ( relation regclass ) + oid + + + Returns the filenode number currently assigned to the + specified relation. The filenode is the base component of the file + name(s) used for the relation (see + for more information). + For most relations the result is the same as + pg_class.relfilenode, + but for certain system catalogs relfilenode + is zero and this function must be used to get the correct value. The + function returns NULL if passed a relation that does not have storage, + such as a view. + + + + + + + pg_relation_filepath + + pg_relation_filepath ( relation regclass ) + text + + + Returns the entire file path name (relative to the database cluster's + data directory, PGDATA) of the relation. + + + + + + + pg_filenode_relation + + pg_filenode_relation ( tablespace oid, filenode oid ) + regclass + + + Returns a relation's OID given the tablespace OID and filenode it is + stored under. This is essentially the inverse mapping of + pg_relation_filepath. For a relation in the + database's default tablespace, the tablespace can be specified as zero. + Returns NULL if no relation in the current database + is associated with the given values. + + + + +
+ + + lists functions used to manage + collations. + + + + Collation Management Functions + + + + + Function + + + Description + + + + + + + + + pg_collation_actual_version + + pg_collation_actual_version ( oid ) + text + + + Returns the actual version of the collation object as it is currently + installed in the operating system. If this is different from the + value in + pg_collation.collversion, + then objects depending on the collation might need to be rebuilt. See + also . + + + + + + + pg_import_system_collations + + pg_import_system_collations ( schema regnamespace ) + integer + + + Adds collations to the system + catalog pg_collation based on all the locales + it finds in the operating system. This is + what initdb uses; see + for more details. If additional + locales are installed into the operating system later on, this + function can be run again to add collations for the new locales. + Locales that match existing entries + in pg_collation will be skipped. (But + collation objects based on locales that are no longer present in the + operating system are not removed by this function.) + The schema parameter would typically + be pg_catalog, but that is not a requirement; the + collations could be installed into some other schema as well. The + function returns the number of new collation objects it created. + + + + +
+ + + lists functions that provide + information about the structure of partitioned tables. + + + + Partitioning Information Functions + + + + + Function + + + Description + + + + + + + + + pg_partition_tree + + pg_partition_tree ( regclass ) + setof record + ( relid regclass, + parentrelid regclass, + isleaf boolean, + level integer ) + + + Lists the tables or indexes in the partition tree of the + given partitioned table or partitioned index, with one row for each + partition. Information provided includes the OID of the partition, + the OID of its immediate parent, a boolean value telling if the + partition is a leaf, and an integer telling its level in the hierarchy. + The level value is 0 for the input table or index, 1 for its + immediate child partitions, 2 for their partitions, and so on. + Returns no rows if the relation does not exist or is not a partition + or partitioned table. + + + + + + + pg_partition_ancestors + + pg_partition_ancestors ( regclass ) + setof regclass + + + Lists the ancestor relations of the given partition, + including the relation itself. Returns no rows if the relation + does not exist or is not a partition or partitioned table. + + + + + + + pg_partition_root + + pg_partition_root ( regclass ) + regclass + + + Returns the top-most parent of the partition tree to which the given + relation belongs. Returns NULL if the relation + does not exist or is not a partition or partitioned table. + + + + +
+ + + For example, to check the total size of the data contained in a + partitioned table measurement, one could use the + following query: + +SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size + FROM pg_partition_tree('measurement'); + + + +
+ + + Index Maintenance Functions + + + shows the functions + available for index maintenance tasks. (Note that these maintenance + tasks are normally done automatically by autovacuum; use of these + functions is only required in special cases.) + These functions cannot be executed during recovery. + Use of these functions is restricted to superusers and the owner + of the given index. + + + + Index Maintenance Functions + + + + + Function + + + Description + + + + + + + + + brin_summarize_new_values + + brin_summarize_new_values ( index regclass ) + integer + + + Scans the specified BRIN index to find page ranges in the base table + that are not currently summarized by the index; for any such range it + creates a new summary index tuple by scanning those table pages. + Returns the number of new page range summaries that were inserted + into the index. + + + + + + + brin_summarize_range + + brin_summarize_range ( index regclass, blockNumber bigint ) + integer + + + Summarizes the page range covering the given block, if not already + summarized. This is + like brin_summarize_new_values except that it + only processes the page range that covers the given table block number. + + + + + + + brin_desummarize_range + + brin_desummarize_range ( index regclass, blockNumber bigint ) + void + + + Removes the BRIN index tuple that summarizes the page range covering + the given table block, if there is one. + + + + + + + gin_clean_pending_list + + gin_clean_pending_list ( index regclass ) + bigint + + + Cleans up the pending list of the specified GIN index + by moving entries in it, in bulk, to the main GIN data structure. + Returns the number of pages removed from the pending list. + If the argument is a GIN index built with + the fastupdate option disabled, no cleanup happens + and the result is zero, because the index doesn't have a pending list. + See and + for details about the pending list and fastupdate + option. + + + + +
+ +
+ + + Generic File Access Functions + + + The functions shown in provide native access to + files on the machine hosting the server. Only files within the + database cluster directory and the log_directory can be + accessed, unless the user is a superuser or is granted the role + pg_read_server_files. Use a relative path for files in + the cluster directory, and a path matching the log_directory + configuration setting for log files. + + + + Note that granting users the EXECUTE privilege on + pg_read_file(), or related functions, allows them the + ability to read any file on the server that the database server process can + read; these functions bypass all in-database privilege checks. This means + that, for example, a user with such access is able to read the contents of + the pg_authid table where authentication + information is stored, as well as read any table data in the database. + Therefore, granting access to these functions should be carefully + considered. + + + + Some of these functions take an optional missing_ok + parameter, which specifies the behavior when the file or directory does + not exist. If true, the function + returns NULL or an empty result set, as appropriate. + If false, an error is raised. The default + is false. + + + + Generic File Access Functions + + + + + Function + + + Description + + + + + + + + + pg_ls_dir + + pg_ls_dir ( dirname text , missing_ok boolean, include_dot_dirs boolean ) + setof text + + + Returns the names of all files (and directories and other special + files) in the specified + directory. The include_dot_dirs parameter + indicates whether . and .. are to be + included in the result set; the default is to exclude them. Including + them can be useful when missing_ok + is true, to distinguish an empty directory from a + non-existent directory. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_ls_logdir + + pg_ls_logdir () + setof record + ( name text, + size bigint, + modification timestamp with time zone ) + + + Returns the name, size, and last modification time (mtime) of each + ordinary file in the server's log directory. Filenames beginning with + a dot, directories, and other special files are excluded. + + + This function is restricted to superusers and members of + the pg_monitor role by default, but other users can + be granted EXECUTE to run the function. + + + + + + + pg_ls_waldir + + pg_ls_waldir () + setof record + ( name text, + size bigint, + modification timestamp with time zone ) + + + Returns the name, size, and last modification time (mtime) of each + ordinary file in the server's write-ahead log (WAL) directory. + Filenames beginning with a dot, directories, and other special files + are excluded. + + + This function is restricted to superusers and members of + the pg_monitor role by default, but other users can + be granted EXECUTE to run the function. + + + + + + + pg_ls_archive_statusdir + + pg_ls_archive_statusdir () + setof record + ( name text, + size bigint, + modification timestamp with time zone ) + + + Returns the name, size, and last modification time (mtime) of each + ordinary file in the server's WAL archive status directory + (pg_wal/archive_status). Filenames beginning + with a dot, directories, and other special files are excluded. + + + This function is restricted to superusers and members of + the pg_monitor role by default, but other users can + be granted EXECUTE to run the function. + + + + + + + + pg_ls_tmpdir + + pg_ls_tmpdir ( tablespace oid ) + setof record + ( name text, + size bigint, + modification timestamp with time zone ) + + + Returns the name, size, and last modification time (mtime) of each + ordinary file in the temporary file directory for the + specified tablespace. + If tablespace is not provided, + the pg_default tablespace is examined. Filenames + beginning with a dot, directories, and other special files are + excluded. + + + This function is restricted to superusers and members of + the pg_monitor role by default, but other users can + be granted EXECUTE to run the function. + + + + + + + pg_read_file + + pg_read_file ( filename text , offset bigint, length bigint , missing_ok boolean ) + text + + + Returns all or part of a text file, starting at the + given byte offset, returning at + most length bytes (less if the end of file is + reached first). If offset is negative, it is + relative to the end of the file. If offset + and length are omitted, the entire file is + returned. The bytes read from the file are interpreted as a string in + the database's encoding; an error is thrown if they are not valid in + that encoding. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_read_binary_file + + pg_read_binary_file ( filename text , offset bigint, length bigint , missing_ok boolean ) + bytea + + + Returns all or part of a file. This function is identical to + pg_read_file except that it can read arbitrary + binary data, returning the result as bytea + not text; accordingly, no encoding checks are performed. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + In combination with the convert_from function, + this function can be used to read a text file in a specified encoding + and convert to the database's encoding: + +SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8'); + + + + + + + + pg_stat_file + + pg_stat_file ( filename text , missing_ok boolean ) + record + ( size bigint, + access timestamp with time zone, + modification timestamp with time zone, + change timestamp with time zone, + creation timestamp with time zone, + isdir boolean ) + + + Returns a record containing the file's size, last access time stamp, + last modification time stamp, last file status change time stamp (Unix + platforms only), file creation time stamp (Windows only), and a flag + indicating if it is a directory. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + +
+ +
+ + + Advisory Lock Functions + + + The functions shown in + manage advisory locks. For details about proper use of these functions, + see . + + + + All these functions are intended to be used to lock application-defined + resources, which can be identified either by a single 64-bit key value or + two 32-bit key values (note that these two key spaces do not overlap). + If another session already holds a conflicting lock on the same resource + identifier, the functions will either wait until the resource becomes + available, or return a false result, as appropriate for + the function. + Locks can be either shared or exclusive: a shared lock does not conflict + with other shared locks on the same resource, only with exclusive locks. + Locks can be taken at session level (so that they are held until released + or the session ends) or at transaction level (so that they are held until + the current transaction ends; there is no provision for manual release). + Multiple session-level lock requests stack, so that if the same resource + identifier is locked three times there must then be three unlock requests + to release the resource in advance of session end. + + + + Advisory Lock Functions + + + + + Function + + + Description + + + + + + + + + pg_advisory_lock + + pg_advisory_lock ( key bigint ) + void + + + pg_advisory_lock ( key1 integer, key2 integer ) + void + + + Obtains an exclusive session-level advisory lock, waiting if necessary. + + + + + + + pg_advisory_lock_shared + + pg_advisory_lock_shared ( key bigint ) + void + + + pg_advisory_lock_shared ( key1 integer, key2 integer ) + void + + + Obtains a shared session-level advisory lock, waiting if necessary. + + + + + + + pg_advisory_unlock + + pg_advisory_unlock ( key bigint ) + boolean + + + pg_advisory_unlock ( key1 integer, key2 integer ) + boolean + + + Releases a previously-acquired exclusive session-level advisory lock. + Returns true if the lock is successfully released. + If the lock was not held, false is returned, and in + addition, an SQL warning will be reported by the server. + + + + + + + pg_advisory_unlock_all + + pg_advisory_unlock_all () + void + + + Releases all session-level advisory locks held by the current session. + (This function is implicitly invoked at session end, even if the + client disconnects ungracefully.) + + + + + + + pg_advisory_unlock_shared + + pg_advisory_unlock_shared ( key bigint ) + boolean + + + pg_advisory_unlock_shared ( key1 integer, key2 integer ) + boolean + + + Releases a previously-acquired shared session-level advisory lock. + Returns true if the lock is successfully released. + If the lock was not held, false is returned, and in + addition, an SQL warning will be reported by the server. + + + + + + + pg_advisory_xact_lock + + pg_advisory_xact_lock ( key bigint ) + void + + + pg_advisory_xact_lock ( key1 integer, key2 integer ) + void + + + Obtains an exclusive transaction-level advisory lock, waiting if + necessary. + + + + + + + pg_advisory_xact_lock_shared + + pg_advisory_xact_lock_shared ( key bigint ) + void + + + pg_advisory_xact_lock_shared ( key1 integer, key2 integer ) + void + + + Obtains a shared transaction-level advisory lock, waiting if + necessary. + + + + + + + pg_try_advisory_lock + + pg_try_advisory_lock ( key bigint ) + boolean + + + pg_try_advisory_lock ( key1 integer, key2 integer ) + boolean + + + Obtains an exclusive session-level advisory lock if available. + This will either obtain the lock immediately and + return true, or return false + without waiting if the lock cannot be acquired immediately. + + + + + + + pg_try_advisory_lock_shared + + pg_try_advisory_lock_shared ( key bigint ) + boolean + + + pg_try_advisory_lock_shared ( key1 integer, key2 integer ) + boolean + + + Obtains a shared session-level advisory lock if available. + This will either obtain the lock immediately and + return true, or return false + without waiting if the lock cannot be acquired immediately. + + + + + + + pg_try_advisory_xact_lock + + pg_try_advisory_xact_lock ( key bigint ) + boolean + + + pg_try_advisory_xact_lock ( key1 integer, key2 integer ) + boolean + + + Obtains an exclusive transaction-level advisory lock if available. + This will either obtain the lock immediately and + return true, or return false + without waiting if the lock cannot be acquired immediately. + + + + + + + pg_try_advisory_xact_lock_shared + + pg_try_advisory_xact_lock_shared ( key bigint ) + boolean + + + pg_try_advisory_xact_lock_shared ( key1 integer, key2 integer ) + boolean + + + Obtains a shared transaction-level advisory lock if available. + This will either obtain the lock immediately and + return true, or return false + without waiting if the lock cannot be acquired immediately. + + + + +
+ +
+ +
+ + + Trigger Functions + + + While many uses of triggers involve user-written trigger functions, + PostgreSQL provides a few built-in trigger + functions that can be used directly in user-defined triggers. These + are summarized in . + (Additional built-in trigger functions exist, which implement foreign + key constraints and deferred index constraints. Those are not documented + here since users need not use them directly.) + + + + For more information about creating triggers, see + . + + + + Built-In Trigger Functions + + + + + Function + + + Description + + + Example Usage + + + + + + + + + suppress_redundant_updates_trigger + + suppress_redundant_updates_trigger ( ) + trigger + + + Suppresses do-nothing update operations. See below for details. + + + CREATE TRIGGER ... suppress_redundant_updates_trigger() + + + + + + + tsvector_update_trigger + + tsvector_update_trigger ( ) + trigger + + + Automatically updates a tsvector column from associated + plain-text document column(s). The text search configuration to use + is specified by name as a trigger argument. See + for details. + + + CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body) + + + + + + + tsvector_update_trigger_column + + tsvector_update_trigger_column ( ) + trigger + + + Automatically updates a tsvector column from associated + plain-text document column(s). The text search configuration to use + is taken from a regconfig column of the table. See + for details. + + + CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body) + + + + +
+ + + The suppress_redundant_updates_trigger function, + when applied as a row-level BEFORE UPDATE trigger, + will prevent any update that does not actually change the data in the + row from taking place. This overrides the normal behavior which always + performs a physical row update + regardless of whether or not the data has changed. (This normal behavior + makes updates run faster, since no checking is required, and is also + useful in certain cases.) + + + + Ideally, you should avoid running updates that don't actually + change the data in the record. Redundant updates can cost considerable + unnecessary time, especially if there are lots of indexes to alter, + and space in dead rows that will eventually have to be vacuumed. + However, detecting such situations in client code is not + always easy, or even possible, and writing expressions to detect + them can be error-prone. An alternative is to use + suppress_redundant_updates_trigger, which will skip + updates that don't change the data. You should use this with care, + however. The trigger takes a small but non-trivial time for each record, + so if most of the records affected by updates do actually change, + use of this trigger will make updates run slower on average. + + + + The suppress_redundant_updates_trigger function can be + added to a table like this: + +CREATE TRIGGER z_min_update +BEFORE UPDATE ON tablename +FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); + + In most cases, you need to fire this trigger last for each row, so that + it does not override other triggers that might wish to alter the row. + Bearing in mind that triggers fire in name order, you would therefore + choose a trigger name that comes after the name of any other trigger + you might have on the table. (Hence the z prefix in the + example.) + +
+ + + Event Trigger Functions + + + PostgreSQL provides these helper functions + to retrieve information from event triggers. + + + + For more information about event triggers, + see . + + + + Capturing Changes at Command End + + + pg_event_trigger_ddl_commands + + + +pg_event_trigger_ddl_commands () setof record + + + + pg_event_trigger_ddl_commands returns a list of + DDL commands executed by each user action, + when invoked in a function attached to a + ddl_command_end event trigger. If called in any other + context, an error is raised. + pg_event_trigger_ddl_commands returns one row for each + base command executed; some commands that are a single SQL sentence + may return more than one row. This function returns the following + columns: + + + + + + Name + Type + Description + + + + + + classid + oid + OID of catalog the object belongs in + + + objid + oid + OID of the object itself + + + objsubid + integer + Sub-object ID (e.g., attribute number for a column) + + + command_tag + text + Command tag + + + object_type + text + Type of the object + + + schema_name + text + + Name of the schema the object belongs in, if any; otherwise NULL. + No quoting is applied. + + + + object_identity + text + + Text rendering of the object identity, schema-qualified. Each + identifier included in the identity is quoted if necessary. + + + + in_extension + boolean + True if the command is part of an extension script + + + command + pg_ddl_command + + A complete representation of the command, in internal format. + This cannot be output directly, but it can be passed to other + functions to obtain different pieces of information about the + command. + + + + + + + + + + Processing Objects Dropped by a DDL Command + + + pg_event_trigger_dropped_objects + + + +pg_event_trigger_dropped_objects () setof record + + + + pg_event_trigger_dropped_objects returns a list of all objects + dropped by the command in whose sql_drop event it is called. + If called in any other context, an error is raised. + This function returns the following columns: + + + + + + Name + Type + Description + + + + + + classid + oid + OID of catalog the object belonged in + + + objid + oid + OID of the object itself + + + objsubid + integer + Sub-object ID (e.g., attribute number for a column) + + + original + boolean + True if this was one of the root object(s) of the deletion + + + normal + boolean + + True if there was a normal dependency relationship + in the dependency graph leading to this object + + + + is_temporary + boolean + + True if this was a temporary object + + + + object_type + text + Type of the object + + + schema_name + text + + Name of the schema the object belonged in, if any; otherwise NULL. + No quoting is applied. + + + + object_name + text + + Name of the object, if the combination of schema and name can be + used as a unique identifier for the object; otherwise NULL. + No quoting is applied, and name is never schema-qualified. + + + + object_identity + text + + Text rendering of the object identity, schema-qualified. Each + identifier included in the identity is quoted if necessary. + + + + address_names + text[] + + An array that, together with object_type and + address_args, can be used by + the pg_get_object_address function to + recreate the object address in a remote server containing an + identically named object of the same kind. + + + + address_args + text[] + + Complement for address_names + + + + + + + + + The pg_event_trigger_dropped_objects function can be used + in an event trigger like this: + +CREATE FUNCTION test_event_trigger_for_drops() + RETURNS event_trigger LANGUAGE plpgsql AS $$ +DECLARE + obj record; +BEGIN + FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects() + LOOP + RAISE NOTICE '% dropped object: % %.% %', + tg_tag, + obj.object_type, + obj.schema_name, + obj.object_name, + obj.object_identity; + END LOOP; +END; +$$; +CREATE EVENT TRIGGER test_event_trigger_for_drops + ON sql_drop + EXECUTE FUNCTION test_event_trigger_for_drops(); + + + + + + Handling a Table Rewrite Event + + + The functions shown in + + provide information about a table for which a + table_rewrite event has just been called. + If called in any other context, an error is raised. + + + + Table Rewrite Information Functions + + + + + Function + + + Description + + + + + + + + + pg_event_trigger_table_rewrite_oid + + pg_event_trigger_table_rewrite_oid () + oid + + + Returns the OID of the table about to be rewritten. + + + + + + + pg_event_trigger_table_rewrite_reason + + pg_event_trigger_table_rewrite_reason () + integer + + + Returns a code explaining the reason(s) for rewriting. The exact + meaning of the codes is release dependent. + + + + +
+ + + These functions can be used in an event trigger like this: + +CREATE FUNCTION test_event_trigger_table_rewrite_oid() + RETURNS event_trigger + LANGUAGE plpgsql AS +$$ +BEGIN + RAISE NOTICE 'rewriting table % for reason %', + pg_event_trigger_table_rewrite_oid()::regclass, + pg_event_trigger_table_rewrite_reason(); +END; +$$; + +CREATE EVENT TRIGGER test_table_rewrite_oid + ON table_rewrite + EXECUTE FUNCTION test_event_trigger_table_rewrite_oid(); + + +
+
+ + + Statistics Information Functions + + + function + statistics + + + + PostgreSQL provides a function to inspect complex + statistics defined using the CREATE STATISTICS command. + + + + Inspecting MCV Lists + + + pg_mcv_list_items + + + +pg_mcv_list_items ( pg_mcv_list ) setof record + + + + pg_mcv_list_items returns a set of records describing + all items stored in a multi-column MCV list. It + returns the following columns: + + + + + + Name + Type + Description + + + + + + index + integer + index of the item in the MCV list + + + values + text[] + values stored in the MCV item + + + nulls + boolean[] + flags identifying NULL values + + + frequency + double precision + frequency of this MCV item + + + base_frequency + double precision + base frequency of this MCV item + + + + + + + + The pg_mcv_list_items function can be used like this: + + +SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), + pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts'; + + + Values of the pg_mcv_list type can be obtained only from the + pg_statistic_ext_data.stxdmcv + column. + + + + + +
diff --git a/doc/src/sgml/generate-errcodes-table.pl b/doc/src/sgml/generate-errcodes-table.pl new file mode 100644 index 000000000000..bbce3762c291 --- /dev/null +++ b/doc/src/sgml/generate-errcodes-table.pl @@ -0,0 +1,59 @@ +#!/usr/bin/perl +# +# Generate the errcodes-table.sgml file from errcodes.txt +# Copyright (c) 2000-2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +print + "\n"; + +open my $errcodes, '<', $ARGV[0] or die; + +while (<$errcodes>) +{ + chomp; + + # Skip comments + next if /^#/; + next if /^\s*$/; + + # Emit section headers + if (/^Section:/) + { + + # Remove the Section: string + s/^Section: //; + + # Escape dashes for SGML + s/-/—/; + + # Wrap PostgreSQL in + s/PostgreSQL/PostgreSQL<\/productname>/g; + + print "\n\n"; + print "\n"; + print ""; + print "$_\n"; + print "\n"; + + next; + } + + die unless /^([^\s]{5})\s+([EWS])\s+([^\s]+)(?:\s+)?([^\s]+)?/; + + (my $sqlstate, my $type, my $errcode_macro, my $condition_name) = + ($1, $2, $3, $4); + + # Skip lines without PL/pgSQL condition names + next unless defined($condition_name); + + print "\n"; + print "\n"; + print "$sqlstate\n"; + print "$condition_name\n"; + print "\n"; +} + +close $errcodes; diff --git a/doc/src/sgml/generate-keywords-table.pl b/doc/src/sgml/generate-keywords-table.pl index 824b324ef78a..30037c773d9b 100644 --- a/doc/src/sgml/generate-keywords-table.pl +++ b/doc/src/sgml/generate-keywords-table.pl @@ -1,7 +1,8 @@ #!/usr/bin/perl # -# Generate the keywords table file -# Copyright (c) 2019-2020, PostgreSQL Global Development Group +# Generate the keywords table for the documentation's SQL Key Words appendix +# +# Copyright (c) 2019-2021, PostgreSQL Global Development Group use strict; use warnings; @@ -11,8 +12,9 @@ my $srcdir = $ARGV[0]; my %keywords; +my %as_keywords; -# read SQL keywords +# read SQL-spec keywords foreach my $ver (@sql_versions) { @@ -39,9 +41,10 @@ while (<$fh>) { - if (/^PG_KEYWORD\("(\w+)", \w+, (\w+)_KEYWORD\)/) + if (/^PG_KEYWORD\("(\w+)", \w+, (\w+)_KEYWORD\, (\w+)\)/) { $keywords{ uc $1 }{'pg'}{ lc $2 } = 1; + $as_keywords{ uc $1 } = 1 if $3 eq 'AS_LABEL'; } } @@ -107,6 +110,10 @@ END { print "reserved"; } + if ($as_keywords{$word}) + { + print ", requires AS"; + } print "\n"; foreach my $ver (@sql_versions) diff --git a/doc/src/sgml/gin.sgml b/doc/src/sgml/gin.sgml new file mode 100644 index 000000000000..d68d12d515c2 --- /dev/null +++ b/doc/src/sgml/gin.sgml @@ -0,0 +1,717 @@ + + + +GIN Indexes + + + index + GIN + + + + Introduction + + + GIN stands for Generalized Inverted Index. + GIN is designed for handling cases where the items + to be indexed are composite values, and the queries to be handled by + the index need to search for element values that appear within + the composite items. For example, the items could be documents, + and the queries could be searches for documents containing specific words. + + + + We use the word item to refer to a composite value that + is to be indexed, and the word key to refer to an element + value. GIN always stores and searches for keys, + not item values per se. + + + + A GIN index stores a set of (key, posting list) pairs, + where a posting list is a set of row IDs in which the key + occurs. The same row ID can appear in multiple posting lists, since + an item can contain more than one key. Each key value is stored only + once, so a GIN index is very compact for cases + where the same key appears many times. + + + + GIN is generalized in the sense that the + GIN access method code does not need to know the + specific operations that it accelerates. + Instead, it uses custom strategies defined for particular data types. + The strategy defines how keys are extracted from indexed items and + query conditions, and how to determine whether a row that contains + some of the key values in a query actually satisfies the query. + + + + One advantage of GIN is that it allows the development + of custom data types with the appropriate access methods, by + an expert in the domain of the data type, rather than a database expert. + This is much the same advantage as using GiST. + + + + The GIN + implementation in PostgreSQL is primarily + maintained by Teodor Sigaev and Oleg Bartunov. There is more + information about GIN on their + website. + + + + + Built-in Operator Classes + + + The core PostgreSQL distribution + includes the GIN operator classes shown in + . + (Some of the optional modules described in + provide additional GIN operator classes.) + + + + Built-in <acronym>GIN</acronym> Operator Classes + + + + Name + Indexable Operators + + + + + array_ops + && (anyarray,anyarray) + + + @> (anyarray,anyarray) + + + <@ (anyarray,anyarray) + + + = (anyarray,anyarray) + + + jsonb_ops + @> (jsonb,jsonb) + + + @? (jsonb,jsonpath) + + + @@ (jsonb,jsonpath) + + + ? (jsonb,text) + + + ?| (jsonb,text[]) + + + ?& (jsonb,text[]) + + + jsonb_path_ops + @> (jsonb,jsonb) + + + @? (jsonb,jsonpath) + + + @@ (jsonb,jsonpath) + + + tsvector_ops + @@ (tsvector,tsquery) + + + @@@ (tsvector,tsquery) + + + +
+ + + Of the two operator classes for type jsonb, jsonb_ops + is the default. jsonb_path_ops supports fewer operators but + offers better performance for those operators. + See for details. + + +
+ + + Extensibility + + + The GIN interface has a high level of abstraction, + requiring the access method implementer only to implement the semantics of + the data type being accessed. The GIN layer itself + takes care of concurrency, logging and searching the tree structure. + + + + All it takes to get a GIN access method working is to + implement a few user-defined methods, which define the behavior of + keys in the tree and the relationships between keys, indexed items, + and indexable queries. In short, GIN combines + extensibility with generality, code reuse, and a clean interface. + + + + There are two methods that an operator class for + GIN must provide: + + + + Datum *extractValue(Datum itemValue, int32 *nkeys, + bool **nullFlags) + + + Returns a palloc'd array of keys given an item to be indexed. The + number of returned keys must be stored into *nkeys. + If any of the keys can be null, also palloc an array of + *nkeys bool fields, store its address at + *nullFlags, and set these null flags as needed. + *nullFlags can be left NULL (its initial value) + if all keys are non-null. + The return value can be NULL if the item contains no keys. + + + + + + Datum *extractQuery(Datum query, int32 *nkeys, + StrategyNumber n, bool **pmatch, Pointer **extra_data, + bool **nullFlags, int32 *searchMode) + + + Returns a palloc'd array of keys given a value to be queried; that is, + query is the value on the right-hand side of an + indexable operator whose left-hand side is the indexed column. + n is the strategy number of the operator within the + operator class (see ). + Often, extractQuery will need + to consult n to determine the data type of + query and the method it should use to extract key values. + The number of returned keys must be stored into *nkeys. + If any of the keys can be null, also palloc an array of + *nkeys bool fields, store its address at + *nullFlags, and set these null flags as needed. + *nullFlags can be left NULL (its initial value) + if all keys are non-null. + The return value can be NULL if the query contains no keys. + + + + searchMode is an output argument that allows + extractQuery to specify details about how the search + will be done. + If *searchMode is set to + GIN_SEARCH_MODE_DEFAULT (which is the value it is + initialized to before call), only items that match at least one of + the returned keys are considered candidate matches. + If *searchMode is set to + GIN_SEARCH_MODE_INCLUDE_EMPTY, then in addition to items + containing at least one matching key, items that contain no keys at + all are considered candidate matches. (This mode is useful for + implementing is-subset-of operators, for example.) + If *searchMode is set to GIN_SEARCH_MODE_ALL, + then all non-null items in the index are considered candidate + matches, whether they match any of the returned keys or not. (This + mode is much slower than the other two choices, since it requires + scanning essentially the entire index, but it may be necessary to + implement corner cases correctly. An operator that needs this mode + in most cases is probably not a good candidate for a GIN operator + class.) + The symbols to use for setting this mode are defined in + access/gin.h. + + + + pmatch is an output argument for use when partial match + is supported. To use it, extractQuery must allocate + an array of *nkeys bools and store its address at + *pmatch. Each element of the array should be set to true + if the corresponding key requires partial match, false if not. + If *pmatch is set to NULL then GIN assumes partial match + is not required. The variable is initialized to NULL before call, + so this argument can simply be ignored by operator classes that do + not support partial match. + + + + extra_data is an output argument that allows + extractQuery to pass additional data to the + consistent and comparePartial methods. + To use it, extractQuery must allocate + an array of *nkeys pointers and store its address at + *extra_data, then store whatever it wants to into the + individual pointers. The variable is initialized to NULL before + call, so this argument can simply be ignored by operator classes that + do not require extra data. If *extra_data is set, the + whole array is passed to the consistent method, and + the appropriate element to the comparePartial method. + + + + + + + An operator class must also provide a function to check if an indexed item + matches the query. It comes in two flavors, a Boolean consistent + function, and a ternary triConsistent function. + triConsistent covers the functionality of both, so providing + triConsistent alone is sufficient. However, if the Boolean + variant is significantly cheaper to calculate, it can be advantageous to + provide both. If only the Boolean variant is provided, some optimizations + that depend on refuting index items before fetching all the keys are + disabled. + + + + bool consistent(bool check[], StrategyNumber n, Datum query, + int32 nkeys, Pointer extra_data[], bool *recheck, + Datum queryKeys[], bool nullFlags[]) + + + Returns true if an indexed item satisfies the query operator with + strategy number n (or might satisfy it, if the recheck + indication is returned). This function does not have direct access + to the indexed item's value, since GIN does not + store items explicitly. Rather, what is available is knowledge + about which key values extracted from the query appear in a given + indexed item. The check array has length + nkeys, which is the same as the number of keys previously + returned by extractQuery for this query datum. + Each element of the + check array is true if the indexed item contains the + corresponding query key, i.e., if (check[i] == true) the i-th key of the + extractQuery result array is present in the indexed item. + The original query datum is + passed in case the consistent method needs to consult it, + and so are the queryKeys[] and nullFlags[] + arrays previously returned by extractQuery. + extra_data is the extra-data array returned by + extractQuery, or NULL if none. + + + + When extractQuery returns a null key in + queryKeys[], the corresponding check[] element + is true if the indexed item contains a null key; that is, the + semantics of check[] are like IS NOT DISTINCT + FROM. The consistent function can examine the + corresponding nullFlags[] element if it needs to tell + the difference between a regular value match and a null match. + + + + On success, *recheck should be set to true if the heap + tuple needs to be rechecked against the query operator, or false if + the index test is exact. That is, a false return value guarantees + that the heap tuple does not match the query; a true return value with + *recheck set to false guarantees that the heap tuple does + match the query; and a true return value with + *recheck set to true means that the heap tuple might match + the query, so it needs to be fetched and rechecked by evaluating the + query operator directly against the originally indexed item. + + + + + + GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query, + int32 nkeys, Pointer extra_data[], + Datum queryKeys[], bool nullFlags[]) + + + triConsistent is similar to consistent, + but instead of Booleans in the check vector, there are + three possible values for each + key: GIN_TRUE, GIN_FALSE and + GIN_MAYBE. GIN_FALSE and GIN_TRUE + have the same meaning as regular Boolean values, while + GIN_MAYBE means that the presence of that key is not known. + When GIN_MAYBE values are present, the function should only + return GIN_TRUE if the item certainly matches whether or + not the index item contains the corresponding query keys. Likewise, the + function must return GIN_FALSE only if the item certainly + does not match, whether or not it contains the GIN_MAYBE + keys. If the result depends on the GIN_MAYBE entries, i.e., + the match cannot be confirmed or refuted based on the known query keys, + the function must return GIN_MAYBE. + + + When there are no GIN_MAYBE values in the check + vector, a GIN_MAYBE return value is the equivalent of + setting the recheck flag in the + Boolean consistent function. + + + + + + + + In addition, GIN must have a way to sort the key values stored in the index. + The operator class can define the sort ordering by specifying a comparison + method: + + + + int compare(Datum a, Datum b) + + + Compares two keys (not indexed items!) and returns an integer less than + zero, zero, or greater than zero, indicating whether the first key is + less than, equal to, or greater than the second. Null keys are never + passed to this function. + + + + + + Alternatively, if the operator class does not provide a compare + method, GIN will look up the default btree operator class for the index + key data type, and use its comparison function. It is recommended to + specify the comparison function in a GIN operator class that is meant for + just one data type, as looking up the btree operator class costs a few + cycles. However, polymorphic GIN operator classes (such + as array_ops) typically cannot specify a single comparison + function. + + + + An operator class for GIN can optionally supply the + following methods: + + + + int comparePartial(Datum partial_key, Datum key, StrategyNumber n, + Pointer extra_data) + + + Compare a partial-match query key to an index key. Returns an integer + whose sign indicates the result: less than zero means the index key + does not match the query, but the index scan should continue; zero + means that the index key does match the query; greater than zero + indicates that the index scan should stop because no more matches + are possible. The strategy number n of the operator + that generated the partial match query is provided, in case its + semantics are needed to determine when to end the scan. Also, + extra_data is the corresponding element of the extra-data + array made by extractQuery, or NULL if none. + Null keys are never passed to this function. + + + + + void options(local_relopts *relopts) + + + Defines a set of user-visible parameters that control operator class + behavior. + + + + The options function is passed a pointer to a + local_relopts struct, which needs to be + filled with a set of operator class specific options. The options + can be accessed from other support functions using the + PG_HAS_OPCLASS_OPTIONS() and + PG_GET_OPCLASS_OPTIONS() macros. + + + + Since both key extraction of indexed values and representation of the + key in GIN are flexible, they may depend on + user-specified parameters. + + + + + + + + To support partial match queries, an operator class must + provide the comparePartial method, and its + extractQuery method must set the pmatch + parameter when a partial-match query is encountered. See + for details. + + + + The actual data types of the various Datum values mentioned + above vary depending on the operator class. The item values passed to + extractValue are always of the operator class's input type, and + all key values must be of the class's STORAGE type. The type of + the query argument passed to extractQuery, + consistent and triConsistent is whatever is the + right-hand input type of the class member operator identified by the + strategy number. This need not be the same as the indexed type, so long as + key values of the correct type can be extracted from it. However, it is + recommended that the SQL declarations of these three support functions use + the opclass's indexed data type for the query argument, even + though the actual type might be something else depending on the operator. + + + + + + Implementation + + + Internally, a GIN index contains a B-tree index + constructed over keys, where each key is an element of one or more indexed + items (a member of an array, for example) and where each tuple in a leaf + page contains either a pointer to a B-tree of heap pointers (a + posting tree), or a simple list of heap pointers (a posting + list) when the list is small enough to fit into a single index tuple along + with the key value. illustrates + these components of a GIN index. + + + + As of PostgreSQL 9.1, null key values can be + included in the index. Also, placeholder nulls are included in the index + for indexed items that are null or contain no keys according to + extractValue. This allows searches that should find empty + items to do so. + + + + Multicolumn GIN indexes are implemented by building + a single B-tree over composite values (column number, key value). The + key values for different columns can be of different types. + + +
+ GIN Internals + + + + + +
+ + + GIN Fast Update Technique + + + Updating a GIN index tends to be slow because of the + intrinsic nature of inverted indexes: inserting or updating one heap row + can cause many inserts into the index (one for each key extracted + from the indexed item). + GIN is capable of postponing much of this work by inserting + new tuples into a temporary, unsorted list of pending entries. + When the table is vacuumed or autoanalyzed, or when + gin_clean_pending_list function is called, or if the + pending list becomes larger than + , the entries are moved to the + main GIN data structure using the same bulk insert + techniques used during initial index creation. This greatly improves + GIN index update speed, even counting the additional + vacuum overhead. Moreover the overhead work can be done by a background + process instead of in foreground query processing. + + + + The main disadvantage of this approach is that searches must scan the list + of pending entries in addition to searching the regular index, and so + a large list of pending entries will slow searches significantly. + Another disadvantage is that, while most updates are fast, an update + that causes the pending list to become too large will incur an + immediate cleanup cycle and thus be much slower than other updates. + Proper use of autovacuum can minimize both of these problems. + + + + If consistent response time is more important than update speed, + use of pending entries can be disabled by turning off the + fastupdate storage parameter for a + GIN index. See + for details. + + + + + Partial Match Algorithm + + + GIN can support partial match queries, in which the query + does not determine an exact match for one or more keys, but the possible + matches fall within a reasonably narrow range of key values (within the + key sorting order determined by the compare support method). + The extractQuery method, instead of returning a key value + to be matched exactly, returns a key value that is the lower bound of + the range to be searched, and sets the pmatch flag true. + The key range is then scanned using the comparePartial + method. comparePartial must return zero for a matching + index key, less than zero for a non-match that is still within the range + to be searched, or greater than zero if the index key is past the range + that could match. + + + +
+ + +GIN Tips and Tricks + + + + Create vs. insert + + + Insertion into a GIN index can be slow + due to the likelihood of many keys being inserted for each item. + So, for bulk insertions into a table it is advisable to drop the GIN + index and recreate it after finishing bulk insertion. + + + + When fastupdate is enabled for GIN + (see for details), the penalty is + less than when it is not. But for very large updates it may still be + best to drop and recreate the index. + + + + + + + + + Build time for a GIN index is very sensitive to + the maintenance_work_mem setting; it doesn't pay to + skimp on work memory during index creation. + + + + + + + + + During a series of insertions into an existing GIN + index that has fastupdate enabled, the system will clean up + the pending-entry list whenever the list grows larger than + gin_pending_list_limit. To avoid fluctuations in observed + response time, it's desirable to have pending-list cleanup occur in the + background (i.e., via autovacuum). Foreground cleanup operations + can be avoided by increasing gin_pending_list_limit + or making autovacuum more aggressive. + However, enlarging the threshold of the cleanup operation means that + if a foreground cleanup does occur, it will take even longer. + + + gin_pending_list_limit can be overridden for individual + GIN indexes by changing storage parameters, which allows each + GIN index to have its own cleanup threshold. + For example, it's possible to increase the threshold only for the GIN + index which can be updated heavily, and decrease it otherwise. + + + + + + + + + The primary goal of developing GIN indexes was + to create support for highly scalable full-text search in + PostgreSQL, and there are often situations when + a full-text search returns a very large set of results. Moreover, this + often happens when the query contains very frequent words, so that the + large result set is not even useful. Since reading many + tuples from the disk and sorting them could take a lot of time, this is + unacceptable for production. (Note that the index search itself is very + fast.) + + + To facilitate controlled execution of such queries, + GIN has a configurable soft upper limit on the + number of rows returned: the + gin_fuzzy_search_limit configuration parameter. + It is set to 0 (meaning no limit) by default. + If a non-zero limit is set, then the returned set is a subset of + the whole result set, chosen at random. + + + Soft means that the actual number of returned results + could differ somewhat from the specified limit, depending on the query + and the quality of the system's random number generator. + + + From experience, values in the thousands (e.g., 5000 — 20000) + work well. + + + + + + + + + Limitations + + + GIN assumes that indexable operators are strict. This + means that extractValue will not be called at all on a null + item value (instead, a placeholder index entry is created automatically), + and extractQuery will not be called on a null query + value either (instead, the query is presumed to be unsatisfiable). Note + however that null key values contained within a non-null composite item + or query value are supported. + + + + + Examples + + + The core PostgreSQL distribution + includes the GIN operator classes previously shown in + . + The following contrib modules also contain + GIN operator classes: + + + + btree_gin + + B-tree equivalent functionality for several data types + + + + + hstore + + Module for storing (key, value) pairs + + + + + intarray + + Enhanced support for int[] + + + + + pg_trgm + + Text similarity using trigram matching + + + + + + +
diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml new file mode 100644 index 000000000000..f22efd1f6e89 --- /dev/null +++ b/doc/src/sgml/gist.sgml @@ -0,0 +1,1312 @@ + + + +GiST Indexes + + + index + GiST + + + + Introduction + + + GiST stands for Generalized Search Tree. It is a + balanced, tree-structured access method, that acts as a base template in + which to implement arbitrary indexing schemes. B-trees, R-trees and many + other indexing schemes can be implemented in GiST. + + + + One advantage of GiST is that it allows the development + of custom data types with the appropriate access methods, by + an expert in the domain of the data type, rather than a database expert. + + + + Some of the information here is derived from the University of California + at Berkeley's GiST Indexing Project + web site and + Marcel Kornacker's thesis, + + Access Methods for Next-Generation Database Systems. + The GiST + implementation in PostgreSQL is primarily + maintained by Teodor Sigaev and Oleg Bartunov, and there is more + information on their + web site. + + + + + + Built-in Operator Classes + + + The core PostgreSQL distribution + includes the GiST operator classes shown in + . + (Some of the optional modules described in + provide additional GiST operator classes.) + + + + Built-in <acronym>GiST</acronym> Operator Classes + + + + + + + Name + Indexable Operators + Ordering Operators + + + + + box_ops + << (box, box) + <-> (box, point) + + &< (box, box) + && (box, box) + &> (box, box) + >> (box, box) + ~= (box, box) + @> (box, box) + <@ (box, box) + &<| (box, box) + <<| (box, box) + |>> (box, box) + |&> (box, box) + ~ (box, box) + @ (box, box) + + + circle_ops + << (circle, circle) + <-> (circle, point) + + &< (circle, circle) + &> (circle, circle) + >> (circle, circle) + <@ (circle, circle) + @> (circle, circle) + ~= (circle, circle) + && (circle, circle) + |>> (circle, circle) + <<| (circle, circle) + &<| (circle, circle) + |&> (circle, circle) + @ (circle, circle) + ~ (circle, circle) + + + inet_ops + << (inet, inet) + + + <<= (inet, inet) + >> (inet, inet) + >>= (inet, inet) + = (inet, inet) + <> (inet, inet) + < (inet, inet) + <= (inet, inet) + > (inet, inet) + >= (inet, inet) + && (inet, inet) + + + multirange_ops + = (anymultirange, anymultirange) + + + && (anymultirange, anymultirange) + && (anymultirange, anyrange) + @> (anymultirange, anyelement) + @> (anymultirange, anymultirange) + @> (anymultirange, anyrange) + <@ (anymultirange, anymultirange) + <@ (anymultirange, anyrange) + << (anymultirange, anymultirange) + << (anymultirange, anyrange) + >> (anymultirange, anymultirange) + >> (anymultirange, anyrange) + &< (anymultirange, anymultirange) + &< (anymultirange, anyrange) + &> (anymultirange, anymultirange) + &> (anymultirange, anyrange) + -|- (anymultirange, anymultirange) + -|- (anymultirange, anyrange) + + + point_ops + |>> (point, point) + <-> (point, point) + + << (point, point) + >> (point, point) + <<| (point, point) + ~= (point, point) + <@ (point, box) + <@ (point, polygon) + <@ (point, circle) + + + poly_ops + << (polygon, polygon) + <-> (polygon, point) + + &< (polygon, polygon) + &> (polygon, polygon) + >> (polygon, polygon) + <@ (polygon, polygon) + @> (polygon, polygon) + ~= (polygon, polygon) + && (polygon, polygon) + <<| (polygon, polygon) + &<| (polygon, polygon) + |&> (polygon, polygon) + |>> (polygon, polygon) + @ (polygon, polygon) + ~ (polygon, polygon) + + + range_ops + = (anyrange, anyrange) + + + && (anyrange, anyrange) + && (anyrange, anymultirange) + @> (anyrange, anyelement) + @> (anyrange, anyrange) + @> (anyrange, anymultirange) + <@ (anyrange, anyrange) + <@ (anyrange, anymultirange) + << (anyrange, anyrange) + << (anyrange, anymultirange) + >> (anyrange, anyrange) + >> (anyrange, anymultirange) + &< (anyrange, anyrange) + &< (anyrange, anymultirange) + &> (anyrange, anyrange) + &> (anyrange, anymultirange) + -|- (anyrange, anyrange) + -|- (anyrange, anymultirange) + + + tsquery_ops + <@ (tsquery, tsquery) + + + @> (tsquery, tsquery) + + tsvector_ops + @@ (tsvector, tsquery) + + + + +
+ + + For historical reasons, the inet_ops operator class is + not the default class for types inet and cidr. + To use it, mention the class name in CREATE INDEX, + for example + +CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops); + + + +
+ + + Extensibility + + + Traditionally, implementing a new index access method meant a lot of + difficult work. It was necessary to understand the inner workings of the + database, such as the lock manager and Write-Ahead Log. The + GiST interface has a high level of abstraction, + requiring the access method implementer only to implement the semantics of + the data type being accessed. The GiST layer itself + takes care of concurrency, logging and searching the tree structure. + + + + This extensibility should not be confused with the extensibility of the + other standard search trees in terms of the data they can handle. For + example, PostgreSQL supports extensible B-trees + and hash indexes. That means that you can use + PostgreSQL to build a B-tree or hash over any + data type you want. But B-trees only support range predicates + (<, =, >), + and hash indexes only support equality queries. + + + + So if you index, say, an image collection with a + PostgreSQL B-tree, you can only issue queries + such as is imagex equal to imagey, is imagex less + than imagey and is imagex greater than imagey. + Depending on how you define equals, less than + and greater than in this context, this could be useful. + However, by using a GiST based index, you could create + ways to ask domain-specific questions, perhaps find all images of + horses or find all over-exposed images. + + + + All it takes to get a GiST access method up and running + is to implement several user-defined methods, which define the behavior of + keys in the tree. Of course these methods have to be pretty fancy to + support fancy queries, but for all the standard queries (B-trees, + R-trees, etc.) they're relatively straightforward. In short, + GiST combines extensibility along with generality, code + reuse, and a clean interface. + + + + There are five methods that an index operator class for + GiST must provide, and five that are optional. + Correctness of the index is ensured + by proper implementation of the same, consistent + and union methods, while efficiency (size and speed) of the + index will depend on the penalty and picksplit + methods. + Two optional methods are compress and + decompress, which allow an index to have internal tree data of + a different type than the data it indexes. The leaves are to be of the + indexed data type, while the other tree nodes can be of any C struct (but + you still have to follow PostgreSQL data type rules here, + see about varlena for variable sized data). If the tree's + internal data type exists at the SQL level, the STORAGE option + of the CREATE OPERATOR CLASS command can be used. + The optional eighth method is distance, which is needed + if the operator class wishes to support ordered scans (nearest-neighbor + searches). The optional ninth method fetch is needed if the + operator class wishes to support index-only scans, except when the + compress method is omitted. The optional tenth method + options is needed if the operator class provides + the user-specified parameters. + The sortsupport method is also optional and is used to + speed up building a GiST index. + + + + + consistent + + + Given an index entry p and a query value q, + this function determines whether the index entry is + consistent with the query; that is, could the predicate + indexed_column + indexable_operator q be true for + any row represented by the index entry? For a leaf index entry this is + equivalent to testing the indexable condition, while for an internal + tree node this determines whether it is necessary to scan the subtree + of the index represented by the tree node. When the result is + true, a recheck flag must also be returned. + This indicates whether the predicate is certainly true or only possibly + true. If recheck = false then the index has + tested the predicate condition exactly, whereas if recheck + = true the row is only a candidate match. In that case the + system will automatically evaluate the + indexable_operator against the actual row value to see + if it is really a match. This convention allows + GiST to support both lossless and lossy index + structures. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal) +RETURNS bool +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_consistent); + +Datum +my_consistent(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + data_type *query = PG_GETARG_DATA_TYPE_P(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + /* Oid subtype = PG_GETARG_OID(3); */ + bool *recheck = (bool *) PG_GETARG_POINTER(4); + data_type *key = DatumGetDataType(entry->key); + bool retval; + + /* + * determine return value as a function of strategy, key and query. + * + * Use GIST_LEAF(entry) to know where you're called in the index tree, + * which comes handy when supporting the = operator for example (you could + * check for non empty union() in non-leaf nodes and equality in leaf + * nodes). + */ + + *recheck = true; /* or false if check is exact */ + + PG_RETURN_BOOL(retval); +} + + + Here, key is an element in the index and query + the value being looked up in the index. The StrategyNumber + parameter indicates which operator of your operator class is being + applied — it matches one of the operator numbers in the + CREATE OPERATOR CLASS command. + + + + Depending on which operators you have included in the class, the data + type of query could vary with the operator, since it will + be whatever type is on the righthand side of the operator, which might + be different from the indexed data type appearing on the lefthand side. + (The above code skeleton assumes that only one type is possible; if + not, fetching the query argument value would have to depend + on the operator.) It is recommended that the SQL declaration of + the consistent function use the opclass's indexed data + type for the query argument, even though the actual type + might be something else depending on the operator. + + + + + + + union + + + This method consolidates information in the tree. Given a set of + entries, this function generates a new index entry that represents + all the given entries. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_union(internal, internal) +RETURNS storage_type +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_union); + +Datum +my_union(PG_FUNCTION_ARGS) +{ + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + GISTENTRY *ent = entryvec->vector; + data_type *out, + *tmp, + *old; + int numranges, + i = 0; + + numranges = entryvec->n; + tmp = DatumGetDataType(ent[0].key); + out = tmp; + + if (numranges == 1) + { + out = data_type_deep_copy(tmp); + + PG_RETURN_DATA_TYPE_P(out); + } + + for (i = 1; i < numranges; i++) + { + old = out; + tmp = DatumGetDataType(ent[i].key); + out = my_union_implementation(out, tmp); + } + + PG_RETURN_DATA_TYPE_P(out); +} + + + + + As you can see, in this skeleton we're dealing with a data type + where union(X, Y, Z) = union(union(X, Y), Z). It's easy + enough to support data types where this is not the case, by + implementing the proper union algorithm in this + GiST support method. + + + + The result of the union function must be a value of the + index's storage type, whatever that is (it might or might not be + different from the indexed column's type). The union + function should return a pointer to newly palloc()ed + memory. You can't just return the input value as-is, even if there is + no type change. + + + + As shown above, the union function's + first internal argument is actually + a GistEntryVector pointer. The second argument is a + pointer to an integer variable, which can be ignored. (It used to be + required that the union function store the size of its + result value into that variable, but this is no longer necessary.) + + + + + + compress + + + Converts a data item into a format suitable for physical storage in + an index page. + If the compress method is omitted, data items are stored + in the index without modification. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_compress(internal) +RETURNS internal +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_compress); + +Datum +my_compress(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *retval; + + if (entry->leafkey) + { + /* replace entry->key with a compressed version */ + compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type)); + + /* fill *compressed_data from entry->key ... */ + + retval = palloc(sizeof(GISTENTRY)); + gistentryinit(*retval, PointerGetDatum(compressed_data), + entry->rel, entry->page, entry->offset, FALSE); + } + else + { + /* typically we needn't do anything with non-leaf entries */ + retval = entry; + } + + PG_RETURN_POINTER(retval); +} + + + + + You have to adapt compressed_data_type to the specific + type you're converting to in order to compress your leaf nodes, of + course. + + + + + + decompress + + + Converts the stored representation of a data item into a format that + can be manipulated by the other GiST methods in the operator class. + If the decompress method is omitted, it is assumed that + the other GiST methods can work directly on the stored data format. + (decompress is not necessarily the reverse of + the compress method; in particular, + if compress is lossy then it's impossible + for decompress to exactly reconstruct the original + data. decompress is not necessarily equivalent + to fetch, either, since the other GiST methods might not + require full reconstruction of the data.) + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_decompress(internal) +RETURNS internal +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_decompress); + +Datum +my_decompress(PG_FUNCTION_ARGS) +{ + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); +} + + + The above skeleton is suitable for the case where no decompression + is needed. (But, of course, omitting the method altogether is even + easier, and is recommended in such cases.) + + + + + + penalty + + + Returns a value indicating the cost of inserting the new + entry into a particular branch of the tree. Items will be inserted + down the path of least penalty in the tree. + Values returned by penalty should be non-negative. + If a negative value is returned, it will be treated as zero. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal) +RETURNS internal +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; -- in some cases penalty functions need not be strict + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_penalty); + +Datum +my_penalty(PG_FUNCTION_ARGS) +{ + GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); + float *penalty = (float *) PG_GETARG_POINTER(2); + data_type *orig = DatumGetDataType(origentry->key); + data_type *new = DatumGetDataType(newentry->key); + + *penalty = my_penalty_implementation(orig, new); + PG_RETURN_POINTER(penalty); +} + + + For historical reasons, the penalty function doesn't + just return a float result; instead it has to store the value + at the location indicated by the third argument. The return + value per se is ignored, though it's conventional to pass back the + address of that argument. + + + + The penalty function is crucial to good performance of + the index. It'll get used at insertion time to determine which branch + to follow when choosing where to add the new entry in the tree. At + query time, the more balanced the index, the quicker the lookup. + + + + + + picksplit + + + When an index page split is necessary, this function decides which + entries on the page are to stay on the old page, and which are to move + to the new page. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_picksplit(internal, internal) +RETURNS internal +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_picksplit); + +Datum +my_picksplit(PG_FUNCTION_ARGS) +{ + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); + OffsetNumber maxoff = entryvec->n - 1; + GISTENTRY *ent = entryvec->vector; + int i, + nbytes; + OffsetNumber *left, + *right; + data_type *tmp_union; + data_type *unionL; + data_type *unionR; + GISTENTRY **raw_entryvec; + + maxoff = entryvec->n - 1; + nbytes = (maxoff + 1) * sizeof(OffsetNumber); + + v->spl_left = (OffsetNumber *) palloc(nbytes); + left = v->spl_left; + v->spl_nleft = 0; + + v->spl_right = (OffsetNumber *) palloc(nbytes); + right = v->spl_right; + v->spl_nright = 0; + + unionL = NULL; + unionR = NULL; + + /* Initialize the raw entry vector. */ + raw_entryvec = (GISTENTRY **) malloc(entryvec->n * sizeof(void *)); + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + raw_entryvec[i] = &(entryvec->vector[i]); + + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + int real_index = raw_entryvec[i] - entryvec->vector; + + tmp_union = DatumGetDataType(entryvec->vector[real_index].key); + Assert(tmp_union != NULL); + + /* + * Choose where to put the index entries and update unionL and unionR + * accordingly. Append the entries to either v->spl_left or + * v->spl_right, and care about the counters. + */ + + if (my_choice_is_left(unionL, curl, unionR, curr)) + { + if (unionL == NULL) + unionL = tmp_union; + else + unionL = my_union_implementation(unionL, tmp_union); + + *left = real_index; + ++left; + ++(v->spl_nleft); + } + else + { + /* + * Same on the right + */ + } + } + + v->spl_ldatum = DataTypeGetDatum(unionL); + v->spl_rdatum = DataTypeGetDatum(unionR); + PG_RETURN_POINTER(v); +} + + + Notice that the picksplit function's result is delivered + by modifying the passed-in v structure. The return + value per se is ignored, though it's conventional to pass back the + address of v. + + + + Like penalty, the picksplit function + is crucial to good performance of the index. Designing suitable + penalty and picksplit implementations + is where the challenge of implementing well-performing + GiST indexes lies. + + + + + + same + + + Returns true if two index entries are identical, false otherwise. + (An index entry is a value of the index's storage type, + not necessarily the original indexed column's type.) + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal) +RETURNS internal +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_same); + +Datum +my_same(PG_FUNCTION_ARGS) +{ + prefix_range *v1 = PG_GETARG_PREFIX_RANGE_P(0); + prefix_range *v2 = PG_GETARG_PREFIX_RANGE_P(1); + bool *result = (bool *) PG_GETARG_POINTER(2); + + *result = my_eq(v1, v2); + PG_RETURN_POINTER(result); +} + + + For historical reasons, the same function doesn't + just return a Boolean result; instead it has to store the flag + at the location indicated by the third argument. The return + value per se is ignored, though it's conventional to pass back the + address of that argument. + + + + + + distance + + + Given an index entry p and a query value q, + this function determines the index entry's + distance from the query value. This function must be + supplied if the operator class contains any ordering operators. + A query using the ordering operator will be implemented by returning + index entries with the smallest distance values first, + so the results must be consistent with the operator's semantics. + For a leaf index entry the result just represents the distance to + the index entry; for an internal tree node, the result must be the + smallest distance that any child entry could have. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal) +RETURNS float8 +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + And the matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_distance); + +Datum +my_distance(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + data_type *query = PG_GETARG_DATA_TYPE_P(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + /* Oid subtype = PG_GETARG_OID(3); */ + /* bool *recheck = (bool *) PG_GETARG_POINTER(4); */ + data_type *key = DatumGetDataType(entry->key); + double retval; + + /* + * determine return value as a function of strategy, key and query. + */ + + PG_RETURN_FLOAT8(retval); +} + + + The arguments to the distance function are identical to + the arguments of the consistent function. + + + + Some approximation is allowed when determining the distance, so long + as the result is never greater than the entry's actual distance. Thus, + for example, distance to a bounding box is usually sufficient in + geometric applications. For an internal tree node, the distance + returned must not be greater than the distance to any of the child + nodes. If the returned distance is not exact, the function must set + *recheck to true. (This is not necessary for internal tree + nodes; for them, the calculation is always assumed to be inexact.) In + this case the executor will calculate the accurate distance after + fetching the tuple from the heap, and reorder the tuples if necessary. + + + + If the distance function returns *recheck = true for any + leaf node, the original ordering operator's return type must + be float8 or float4, and the distance function's + result values must be comparable to those of the original ordering + operator, since the executor will sort using both distance function + results and recalculated ordering-operator results. Otherwise, the + distance function's result values can be any finite float8 + values, so long as the relative order of the result values matches the + order returned by the ordering operator. (Infinity and minus infinity + are used internally to handle cases such as nulls, so it is not + recommended that distance functions return these values.) + + + + + + + fetch + + + Converts the compressed index representation of a data item into the + original data type, for index-only scans. The returned data must be an + exact, non-lossy copy of the originally indexed value. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_fetch(internal) +RETURNS internal +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + The argument is a pointer to a GISTENTRY struct. On + entry, its key field contains a non-NULL leaf datum in + compressed form. The return value is another GISTENTRY + struct, whose key field contains the same datum in its + original, uncompressed form. If the opclass's compress function does + nothing for leaf entries, the fetch method can return the + argument as-is. Or, if the opclass does not have a compress function, + the fetch method can be omitted as well, since it would + necessarily be a no-op. + + + + The matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_fetch); + +Datum +my_fetch(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + input_data_type *in = DatumGetPointer(entry->key); + fetched_data_type *fetched_data; + GISTENTRY *retval; + + retval = palloc(sizeof(GISTENTRY)); + fetched_data = palloc(sizeof(fetched_data_type)); + + /* + * Convert 'fetched_data' into the a Datum of the original datatype. + */ + + /* fill *retval from fetched_data. */ + gistentryinit(*retval, PointerGetDatum(converted_datum), + entry->rel, entry->page, entry->offset, FALSE); + + PG_RETURN_POINTER(retval); +} + + + + + If the compress method is lossy for leaf entries, the operator class + cannot support index-only scans, and must not define + a fetch function. + + + + + + + options + + + Allows definition of user-visible parameters that control operator + class behavior. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_options(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + + + The function is passed a pointer to a local_relopts + struct, which needs to be filled with a set of operator class + specific options. The options can be accessed from other support + functions using the PG_HAS_OPCLASS_OPTIONS() and + PG_GET_OPCLASS_OPTIONS() macros. + + + + An example implementation of my_options() and parameters use + from other support functions are given below: + + +typedef enum MyEnumType +{ + MY_ENUM_ON, + MY_ENUM_OFF, + MY_ENUM_AUTO +} MyEnumType; + +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int int_param; /* integer parameter */ + double real_param; /* real parameter */ + MyEnumType enum_param; /* enum parameter */ + int str_param; /* string parameter */ +} MyOptionsStruct; + +/* String representation of enum values */ +static relopt_enum_elt_def myEnumValues[] = +{ + {"on", MY_ENUM_ON}, + {"off", MY_ENUM_OFF}, + {"auto", MY_ENUM_AUTO}, + {(const char *) NULL} /* list terminator */ +}; + +static char *str_param_default = "default"; + +/* + * Sample validator: checks that string is not longer than 8 bytes. + */ +static void +validate_my_string_relopt(const char *value) +{ + if (strlen(value) > 8) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("str_param must be at most 8 bytes"))); +} + +/* + * Sample filler: switches characters to lower case. + */ +static Size +fill_my_string_relopt(const char *value, void *ptr) +{ + char *tmp = str_tolower(value, strlen(value), DEFAULT_COLLATION_OID); + int len = strlen(tmp); + + if (ptr) + strcpy((char *) ptr, tmp); + + pfree(tmp); + return len + 1; +} + +PG_FUNCTION_INFO_V1(my_options); + +Datum +my_options(PG_FUNCTION_ARGS) +{ + local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + + init_local_reloptions(relopts, sizeof(MyOptionsStruct)); + add_local_int_reloption(relopts, "int_param", "integer parameter", + 100, 0, 1000000, + offsetof(MyOptionsStruct, int_param)); + add_local_real_reloption(relopts, "real_param", "real parameter", + 1.0, 0.0, 1000000.0, + offsetof(MyOptionsStruct, real_param)); + add_local_enum_reloption(relopts, "enum_param", "enum parameter", + myEnumValues, MY_ENUM_ON, + "Valid values are: \"on\", \"off\" and \"auto\".", + offsetof(MyOptionsStruct, enum_param)); + add_local_string_reloption(relopts, "str_param", "string parameter", + str_param_default, + &validate_my_string_relopt, + &fill_my_string_relopt, + offsetof(MyOptionsStruct, str_param)); + + PG_RETURN_VOID(); +} + +PG_FUNCTION_INFO_V1(my_compress); + +Datum +my_compress(PG_FUNCTION_ARGS) +{ + int int_param = 100; + double real_param = 1.0; + MyEnumType enum_param = MY_ENUM_ON; + char *str_param = str_param_default; + + /* + * Normally, when opclass contains 'options' method, then options are always + * passed to support functions. However, if you add 'options' method to + * existing opclass, previously defined indexes have no options, so the + * check is required. + */ + if (PG_HAS_OPCLASS_OPTIONS()) + { + MyOptionsStruct *options = (MyOptionsStruct *) PG_GET_OPCLASS_OPTIONS(); + + int_param = options->int_param; + real_param = options->real_param; + enum_param = options->enum_param; + str_param = GET_STRING_RELOPTION(options, str_param); + } + + /* the rest implementation of support function */ +} + + + + + + Since the representation of the key in GiST is + flexible, it may depend on user-specified parameters. For instance, + the length of key signature may be specified. See + gtsvector_options() for example. + + + + + + sortsupport + + + Returns a comparator function to sort data in a way that preserves + locality. It is used by CREATE INDEX and + REINDEX commands. The quality of the created index + depends on how well the sort order determined by the comparator function + preserves locality of the inputs. + + + The sortsupport method is optional. If it is not + provided, CREATE INDEX builds the index by inserting + each tuple to the tree using the penalty and + picksplit functions, which is much slower. + + + + The SQL declaration of the function must look like + this: + + +CREATE OR REPLACE FUNCTION my_sortsupport(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + The argument is a pointer to a SortSupport + struct. At a minimum, the function must fill in its comparator field. + The comparator takes three arguments: two Datums to compare, and + a pointer to the SortSupport struct. The + Datums are the two indexed values in the format that they are stored + in the index; that is, in the format returned by the + compress method. The full API is defined in + src/include/utils/sortsupport.h. + + + + The matching code in the C module could then follow this skeleton: + + +PG_FUNCTION_INFO_V1(my_sortsupport); + +static int +my_fastcmp(Datum x, Datum y, SortSupport ssup) +{ + /* establish order between x and y by computing some sorting value z */ + + int z1 = ComputeSpatialCode(x); + int z2 = ComputeSpatialCode(y); + + return z1 == z2 ? 0 : z1 > z2 ? 1 : -1; +} + +Datum +my_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + ssup->comparator = my_fastcmp; + PG_RETURN_VOID(); +} + + + + + + + + All the GiST support methods are normally called in short-lived memory + contexts; that is, CurrentMemoryContext will get reset after + each tuple is processed. It is therefore not very important to worry about + pfree'ing everything you palloc. However, in some cases it's useful for a + support method to cache data across repeated calls. To do that, allocate + the longer-lived data in fcinfo->flinfo->fn_mcxt, and + keep a pointer to it in fcinfo->flinfo->fn_extra. Such + data will survive for the life of the index operation (e.g., a single GiST + index scan, index build, or index tuple insertion). Be careful to pfree + the previous value when replacing a fn_extra value, or the leak + will accumulate for the duration of the operation. + + + + + + Implementation + + + GiST Index Build Methods + + + The simplest way to build a GiST index is just to insert all the entries, + one by one. This tends to be slow for large indexes, because if the + index tuples are scattered across the index and the index is large enough + to not fit in cache, a lot of random I/O will be + needed. PostgreSQL supports two alternative + methods for initial build of a GiST index: sorted + and buffered modes. + + + + The sorted method is only available if each of the opclasses used by the + index provides a sortsupport function, as described + in . If they do, this method is + usually the best, so it is used by default. + + + + The buffered method works by not inserting tuples directly into the index + right away. It can dramatically reduce the amount of random I/O needed + for non-ordered data sets. For well-ordered data sets the benefit is + smaller or non-existent, because only a small number of pages receive new + tuples at a time, and those pages fit in cache even if the index as a + whole does not. + + + + The buffered method needs to call the penalty + function more often than the simple method does, which consumes some + extra CPU resources. Also, the buffers need temporary disk space, up to + the size of the resulting index. Buffering can also influence the quality + of the resulting index, in both positive and negative directions. That + influence depends on various factors, like the distribution of the input + data and the operator class implementation. + + + + If sorting is not possible, then by default a GiST index build switches + to the buffering method when the index size reaches + . Buffering can be manually + forced or prevented by the buffering parameter to the + CREATE INDEX command. The default behavior is good for most cases, but + turning buffering off might speed up the build somewhat if the input data + is ordered. + + + + + + + Examples + + + The PostgreSQL source distribution includes + several examples of index methods implemented using + GiST. The core system currently provides text search + support (indexing for tsvector and tsquery) as well as + R-Tree equivalent functionality for some of the built-in geometric data types + (see src/backend/access/gist/gistproc.c). The following + contrib modules also contain GiST + operator classes: + + + + btree_gist + + B-tree equivalent functionality for several data types + + + + + cube + + Indexing for multidimensional cubes + + + + + hstore + + Module for storing (key, value) pairs + + + + + intarray + + RD-Tree for one-dimensional array of int4 values + + + + + ltree + + Indexing for tree-like structures + + + + + pg_trgm + + Text similarity using trigram matching + + + + + seg + + Indexing for float ranges + + + + + + + +
diff --git a/doc/src/sgml/glossary.sgml b/doc/src/sgml/glossary.sgml index 9d2385031ca4..c8d0440e80f5 100644 --- a/doc/src/sgml/glossary.sgml +++ b/doc/src/sgml/glossary.sgml @@ -708,7 +708,7 @@ Contains the values of row - attributes (i.e. the data) for a + attributes (i.e., the data) for a relation. The heap is realized within one or more file segments @@ -1448,7 +1448,7 @@ known as local objects. - Most local objects belong to a specific + Most local objects reside in a specific schema in their containing database, such as relations (all types), @@ -1458,7 +1458,7 @@ are enforced to be unique. - There also exist local objects that do not belong to schemas; some examples are + There also exist local objects that do not reside in schemas; some examples are extensions, data type casts, and foreign data wrappers. diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml new file mode 100644 index 000000000000..22af7dbf51b2 --- /dev/null +++ b/doc/src/sgml/high-availability.sgml @@ -0,0 +1,2342 @@ + + + + High Availability, Load Balancing, and Replication + + high availability + failover + replication + load balancing + clustering + data partitioning + + + Database servers can work together to allow a second server to + take over quickly if the primary server fails (high + availability), or to allow several computers to serve the same + data (load balancing). Ideally, database servers could work + together seamlessly. Web servers serving static web pages can + be combined quite easily by merely load-balancing web requests + to multiple machines. In fact, read-only database servers can + be combined relatively easily too. Unfortunately, most database + servers have a read/write mix of requests, and read/write servers + are much harder to combine. This is because though read-only + data needs to be placed on each server only once, a write to any + server has to be propagated to all servers so that future read + requests to those servers return consistent results. + + + + This synchronization problem is the fundamental difficulty for + servers working together. Because there is no single solution + that eliminates the impact of the sync problem for all use cases, + there are multiple solutions. Each solution addresses this + problem in a different way, and minimizes its impact for a specific + workload. + + + + Some solutions deal with synchronization by allowing only one + server to modify the data. Servers that can modify data are + called read/write, master or primary servers. + Servers that track changes in the primary are called standby + or secondary servers. A standby server that cannot be connected + to until it is promoted to a primary server is called a warm + standby server, and one that can accept connections and serves read-only + queries is called a hot standby server. + + + + Some solutions are synchronous, + meaning that a data-modifying transaction is not considered + committed until all servers have committed the transaction. This + guarantees that a failover will not lose any data and that all + load-balanced servers will return consistent results no matter + which server is queried. In contrast, asynchronous solutions allow some + delay between the time of a commit and its propagation to the other servers, + opening the possibility that some transactions might be lost in + the switch to a backup server, and that load balanced servers + might return slightly stale results. Asynchronous communication + is used when synchronous would be too slow. + + + + Solutions can also be categorized by their granularity. Some solutions + can deal only with an entire database server, while others allow control + at the per-table or per-database level. + + + + Performance must be considered in any choice. There is usually a + trade-off between functionality and + performance. For example, a fully synchronous solution over a slow + network might cut performance by more than half, while an asynchronous + one might have a minimal performance impact. + + + + The remainder of this section outlines various failover, replication, + and load balancing solutions. + + + + Comparison of Different Solutions + + + + + Shared Disk Failover + + + + Shared disk failover avoids synchronization overhead by having only one + copy of the database. It uses a single disk array that is shared by + multiple servers. If the main database server fails, the standby server + is able to mount and start the database as though it were recovering from + a database crash. This allows rapid failover with no data loss. + + + + Shared hardware functionality is common in network storage devices. + Using a network file system is also possible, though care must be + taken that the file system has full POSIX behavior (see ). One significant limitation of this + method is that if the shared disk array fails or becomes corrupt, the + primary and standby servers are both nonfunctional. Another issue is + that the standby server should never access the shared storage while + the primary server is running. + + + + + + + File System (Block Device) Replication + + + + A modified version of shared hardware functionality is file system + replication, where all changes to a file system are mirrored to a file + system residing on another computer. The only restriction is that + the mirroring must be done in a way that ensures the standby server + has a consistent copy of the file system — specifically, writes + to the standby must be done in the same order as those on the primary. + DRBD is a popular file system replication solution + for Linux. + + + + + + + + + Write-Ahead Log Shipping + + + + Warm and hot standby servers can be kept current by reading a + stream of write-ahead log (WAL) + records. If the main server fails, the standby contains + almost all of the data of the main server, and can be quickly + made the new primary database server. This can be synchronous or + asynchronous and can only be done for the entire database server. + + + A standby server can be implemented using file-based log shipping + () or streaming replication (see + ), or a combination of both. For + information on hot standby, see . + + + + + + Logical Replication + + + Logical replication allows a database server to send a stream of data + modifications to another server. PostgreSQL + logical replication constructs a stream of logical data modifications + from the WAL. Logical replication allows replication of data changes on + a per-table basis. In addition, a server that is publishing its own + changes can also subscribe to changes from another server, allowing data + to flow in multiple directions. For more information on logical + replication, see . Through the + logical decoding interface (), + third-party extensions can also provide similar functionality. + + + + + + Trigger-Based Primary-Standby Replication + + + + A trigger-based replication setup typically funnels data modification + queries to a designated primary server. Operating on a per-table basis, + the primary server sends data changes (typically) asynchronously to the + standby servers. Standby servers can answer queries while the primary is + running, and may allow some local data changes or write activity. This + form of replication is often used for offloading large analytical or data + warehouse queries. + + + + Slony-I is an example of this type of + replication, with per-table granularity, and support for multiple standby + servers. Because it updates the standby server asynchronously (in + batches), there is possible data loss during fail over. + + + + + + SQL-Based Replication Middleware + + + + With SQL-based replication middleware, a program intercepts + every SQL query and sends it to one or all servers. Each server + operates independently. Read-write queries must be sent to all servers, + so that every server receives any changes. But read-only queries can be + sent to just one server, allowing the read workload to be distributed + among them. + + + + If queries are simply broadcast unmodified, functions like + random(), CURRENT_TIMESTAMP, and + sequences can have different values on different servers. + This is because each server operates independently, and because + SQL queries are broadcast rather than actual data changes. If + this is unacceptable, either the middleware or the application + must determine such values from a single source and then use those + values in write queries. Care must also be taken that all + transactions either commit or abort on all servers, perhaps + using two-phase commit ( + and ). + Pgpool-II and Continuent Tungsten + are examples of this type of replication. + + + + + + Asynchronous Multimaster Replication + + + + For servers that are not regularly connected or have slow + communication links, like laptops or + remote servers, keeping data consistent among servers is a + challenge. Using asynchronous multimaster replication, each + server works independently, and periodically communicates with + the other servers to identify conflicting transactions. The + conflicts can be resolved by users or conflict resolution rules. + Bucardo is an example of this type of replication. + + + + + + Synchronous Multimaster Replication + + + + In synchronous multimaster replication, each server can accept + write requests, and modified data is transmitted from the + original server to every other server before each transaction + commits. Heavy write activity can cause excessive locking and + commit delays, leading to poor performance. Read requests can + be sent to any server. Some implementations use shared disk + to reduce the communication overhead. Synchronous multimaster + replication is best for mostly read workloads, though its big + advantage is that any server can accept write requests — + there is no need to partition workloads between primary and + standby servers, and because the data changes are sent from one + server to another, there is no problem with non-deterministic + functions like random(). + + + + PostgreSQL does not offer this type of replication, + though PostgreSQL two-phase commit ( and ) + can be used to implement this in application code or middleware. + + + + + + + + summarizes + the capabilities of the various solutions listed above. + + + + High Availability, Load Balancing, and Replication Feature Matrix + + + + + + + + + + + + + Feature + Shared Disk + File System Repl. + Write-Ahead Log Shipping + Logical Repl. + Trigger-&zwsp;Based Repl. + SQL Repl. Middle-ware + Async. MM Repl. + Sync. MM Repl. + + + + + + + Popular examples + NAS + DRBD + built-in streaming repl. + built-in logical repl., pglogical + Londiste, Slony + pgpool-II + Bucardo + + + + + Comm. method + shared disk + disk blocks + WAL + logical decoding + table rows + SQL + table rows + table rows and row locks + + + + No special hardware required + + + + + + + + + + + + Allows multiple primary servers + + + + + + + + + + + + No overhead on primary + + + + + + + + + + + + No waiting for multiple servers + + + with sync off + with sync off + + + + + + + + Primary failure will never lose data + + + with sync on + with sync on + + + + + + + + Replicas accept read-only queries + + + with hot standby + + + + + + + + + Per-table granularity + + + + + + + + + + + + No conflict resolution necessary + + + + + + + + + + + + +
+ + + There are a few solutions that do not fit into the above categories: + + + + + + Data Partitioning + + + + Data partitioning splits tables into data sets. Each set can + be modified by only one server. For example, data can be + partitioned by offices, e.g., London and Paris, with a server + in each office. If queries combining London and Paris data + are necessary, an application can query both servers, or + primary/standby replication can be used to keep a read-only copy + of the other office's data on each server. + + + + + + Multiple-Server Parallel Query Execution + + + + Many of the above solutions allow multiple servers to handle multiple + queries, but none allow a single query to use multiple servers to + complete faster. This solution allows multiple servers to work + concurrently on a single query. It is usually accomplished by + splitting the data among servers and having each server execute its + part of the query and return results to a central server where they + are combined and returned to the user. This can be implemented using the + PL/Proxy tool set. + + + + + + + + + It should also be noted that because PostgreSQL + is open source and easily extended, a number of companies have + taken PostgreSQL and created commercial + closed-source solutions with unique failover, replication, and load + balancing capabilities. These are not discussed here. + + +
+ + + + Log-Shipping Standby Servers + + + + Continuous archiving can be used to create a high + availability (HA) cluster configuration with one or more + standby servers ready to take over operations if the + primary server fails. This capability is widely referred to as + warm standby or log shipping. + + + + The primary and standby server work together to provide this capability, + though the servers are only loosely coupled. The primary server operates + in continuous archiving mode, while each standby server operates in + continuous recovery mode, reading the WAL files from the primary. No + changes to the database tables are required to enable this capability, + so it offers low administration overhead compared to some other + replication solutions. This configuration also has relatively low + performance impact on the primary server. + + + + Directly moving WAL records from one database server to another + is typically described as log shipping. PostgreSQL + implements file-based log shipping by transferring WAL records + one file (WAL segment) at a time. WAL files (16MB) can be + shipped easily and cheaply over any distance, whether it be to an + adjacent system, another system at the same site, or another system on + the far side of the globe. The bandwidth required for this technique + varies according to the transaction rate of the primary server. + Record-based log shipping is more granular and streams WAL changes + incrementally over a network connection (see ). + + + + It should be noted that log shipping is asynchronous, i.e., the WAL + records are shipped after transaction commit. As a result, there is a + window for data loss should the primary server suffer a catastrophic + failure; transactions not yet shipped will be lost. The size of the + data loss window in file-based log shipping can be limited by use of the + archive_timeout parameter, which can be set as low + as a few seconds. However such a low setting will + substantially increase the bandwidth required for file shipping. + Streaming replication (see ) + allows a much smaller window of data loss. + + + + Recovery performance is sufficiently good that the standby will + typically be only moments away from full + availability once it has been activated. As a result, this is called + a warm standby configuration which offers high + availability. Restoring a server from an archived base backup and + rollforward will take considerably longer, so that technique only + offers a solution for disaster recovery, not high availability. + A standby server can also be used for read-only queries, in which case + it is called a Hot Standby server. See for + more information. + + + + warm standby + + + + PITR standby + + + + standby server + + + + log shipping + + + + witness server + + + + STONITH + + + + Planning + + + It is usually wise to create the primary and standby servers + so that they are as similar as possible, at least from the + perspective of the database server. In particular, the path names + associated with tablespaces will be passed across unmodified, so both + primary and standby servers must have the same mount paths for + tablespaces if that feature is used. Keep in mind that if + + is executed on the primary, any new mount point needed for it must + be created on the primary and all standby servers before the command + is executed. Hardware need not be exactly the same, but experience shows + that maintaining two identical systems is easier than maintaining two + dissimilar ones over the lifetime of the application and system. + In any case the hardware architecture must be the same — shipping + from, say, a 32-bit to a 64-bit system will not work. + + + + In general, log shipping between servers running different major + PostgreSQL release + levels is not possible. It is the policy of the PostgreSQL Global + Development Group not to make changes to disk formats during minor release + upgrades, so it is likely that running different minor release levels + on primary and standby servers will work successfully. However, no + formal support for that is offered and you are advised to keep primary + and standby servers at the same release level as much as possible. + When updating to a new minor release, the safest policy is to update + the standby servers first — a new minor release is more likely + to be able to read WAL files from a previous minor release than vice + versa. + + + + + + Standby Server Operation + + + A server enters standby mode if a + + standby.signal + standby.signal + file exists in the data directory when the server is started. + + + + In standby mode, the server continuously applies WAL received from the + primary server. The standby server can read WAL from a WAL archive + (see ) or directly from the primary + over a TCP connection (streaming replication). The standby server will + also attempt to restore any WAL found in the standby cluster's + pg_wal directory. That typically happens after a server + restart, when the standby replays again WAL that was streamed from the + primary before the restart, but you can also manually copy files to + pg_wal at any time to have them replayed. + + + + At startup, the standby begins by restoring all WAL available in the + archive location, calling restore_command. Once it + reaches the end of WAL available there and restore_command + fails, it tries to restore any WAL available in the pg_wal directory. + If that fails, and streaming replication has been configured, the + standby tries to connect to the primary server and start streaming WAL + from the last valid record found in archive or pg_wal. If that fails + or streaming replication is not configured, or if the connection is + later disconnected, the standby goes back to step 1 and tries to + restore the file from the archive again. This loop of retries from the + archive, pg_wal, and via streaming replication goes on until the server + is stopped or failover is triggered by a trigger file. + + + + Standby mode is exited and the server switches to normal operation + when pg_ctl promote is run, + pg_promote() is called, or a trigger file is found + (promote_trigger_file). Before failover, + any WAL immediately available in the archive or in pg_wal will be + restored, but no attempt is made to connect to the primary. + + + + + Preparing the Primary for Standby Servers + + + Set up continuous archiving on the primary to an archive directory + accessible from the standby, as described + in . The archive location should be + accessible from the standby even when the primary is down, i.e., it should + reside on the standby server itself or another trusted server, not on + the primary server. + + + + If you want to use streaming replication, set up authentication on the + primary server to allow replication connections from the standby + server(s); that is, create a role and provide a suitable entry or + entries in pg_hba.conf with the database field set to + replication. Also ensure max_wal_senders is set + to a sufficiently large value in the configuration file of the primary + server. If replication slots will be used, + ensure that max_replication_slots is set sufficiently + high as well. + + + + Take a base backup as described in + to bootstrap the standby server. + + + + + Setting Up a Standby Server + + + To set up the standby server, restore the base backup taken from primary + server (see ). Create a file + standby.signalstandby.signal + in the standby's cluster data + directory. Set to a simple command to copy files from + the WAL archive. If you plan to have multiple standby servers for high + availability purposes, make sure that recovery_target_timeline is set to + latest (the default), to make the standby server follow the timeline change + that occurs at failover to another standby. + + + + + should return immediately + if the file does not exist; the server will retry the command again if + necessary. + + + + + If you want to use streaming replication, fill in + with a libpq connection string, including + the host name (or IP address) and any additional details needed to + connect to the primary server. If the primary needs a password for + authentication, the password needs to be specified in + as well. + + + + If you're setting up the standby server for high availability purposes, + set up WAL archiving, connections and authentication like the primary + server, because the standby server will work as a primary server after + failover. + + + + If you're using a WAL archive, its size can be minimized using the parameter to remove files that are no + longer required by the standby server. + The pg_archivecleanup utility is designed specifically to + be used with archive_cleanup_command in typical single-standby + configurations, see . + Note however, that if you're using the archive for backup purposes, you + need to retain files needed to recover from at least the latest base + backup, even if they're no longer needed by the standby. + + + + A simple example of configuration is: + +primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000''' +restore_command = 'cp /path/to/archive/%f %p' +archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' + + + + + You can have any number of standby servers, but if you use streaming + replication, make sure you set max_wal_senders high enough in + the primary to allow them to be connected simultaneously. + + + + + + Streaming Replication + + + Streaming Replication + + + + Streaming replication allows a standby server to stay more up-to-date + than is possible with file-based log shipping. The standby connects + to the primary, which streams WAL records to the standby as they're + generated, without waiting for the WAL file to be filled. + + + + Streaming replication is asynchronous by default + (see ), in which case there is + a small delay between committing a transaction in the primary and the + changes becoming visible in the standby. This delay is however much + smaller than with file-based log shipping, typically under one second + assuming the standby is powerful enough to keep up with the load. With + streaming replication, archive_timeout is not required to + reduce the data loss window. + + + + If you use streaming replication without file-based continuous + archiving, the server might recycle old WAL segments before the standby + has received them. If this occurs, the standby will need to be + reinitialized from a new base backup. You can avoid this by setting + wal_keep_size to a value large enough to ensure that + WAL segments are not recycled too early, or by configuring a replication + slot for the standby. If you set up a WAL archive that's accessible from + the standby, these solutions are not required, since the standby can + always use the archive to catch up provided it retains enough segments. + + + + To use streaming replication, set up a file-based log-shipping standby + server as described in . The step that + turns a file-based log-shipping standby into streaming replication + standby is setting the primary_conninfo setting + to point to the primary server. Set + and authentication options + (see pg_hba.conf) on the primary so that the standby server + can connect to the replication pseudo-database on the primary + server (see ). + + + + On systems that support the keepalive socket option, setting + , + and + helps the primary promptly + notice a broken connection. + + + + Set the maximum number of concurrent connections from the standby servers + (see for details). + + + + When the standby is started and primary_conninfo is set + correctly, the standby will connect to the primary after replaying all + WAL files available in the archive. If the connection is established + successfully, you will see a walreceiver in the standby, and + a corresponding walsender process in the primary. + + + + Authentication + + It is very important that the access privileges for replication be set up + so that only trusted users can read the WAL stream, because it is + easy to extract privileged information from it. Standby servers must + authenticate to the primary as an account that has the + REPLICATION privilege or a superuser. It is + recommended to create a dedicated user account with + REPLICATION and LOGIN + privileges for replication. While REPLICATION + privilege gives very high permissions, it does not allow the user to + modify any data on the primary system, which the + SUPERUSER privilege does. + + + + Client authentication for replication is controlled by a + pg_hba.conf record specifying replication in the + database field. For example, if the standby is running on + host IP 192.168.1.100 and the account name for replication + is foo, the administrator can add the following line to the + pg_hba.conf file on the primary: + + +# Allow the user "foo" from host 192.168.1.100 to connect to the primary +# as a replication standby if the user's password is correctly supplied. +# +# TYPE DATABASE USER ADDRESS METHOD +host replication foo 192.168.1.100/32 md5 + + + + The host name and port number of the primary, connection user name, + and password are specified in the . + The password can also be set in the ~/.pgpass file on the + standby (specify replication in the database + field). + For example, if the primary is running on host IP 192.168.1.50, + port 5432, the account name for replication is + foo, and the password is foopass, the administrator + can add the following line to the postgresql.conf file on the + standby: + + +# The standby connects to the primary that is running on host 192.168.1.50 +# and port 5432 as the user "foo" whose password is "foopass". +primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' + + + + + + Monitoring + + An important health indicator of streaming replication is the amount + of WAL records generated in the primary, but not yet applied in the + standby. You can calculate this lag by comparing the current WAL write + location on the primary with the last WAL location received by the + standby. These locations can be retrieved using + pg_current_wal_lsn on the primary and + pg_last_wal_receive_lsn on the standby, + respectively (see and + for details). + The last WAL receive location in the standby is also displayed in the + process status of the WAL receiver process, displayed using the + ps command (see for details). + + + You can retrieve a list of WAL sender processes via the + + pg_stat_replication view. Large differences between + pg_current_wal_lsn and the view's sent_lsn field + might indicate that the primary server is under heavy load, while + differences between sent_lsn and + pg_last_wal_receive_lsn on the standby might indicate + network delay, or that the standby is under heavy load. + + + On a hot standby, the status of the WAL receiver process can be retrieved + via the + pg_stat_wal_receiver view. A large + difference between pg_last_wal_replay_lsn and the + view's flushed_lsn indicates that WAL is being + received faster than it can be replayed. + + + + + + Replication Slots + + replication slot + streaming replication + + + Replication slots provide an automated way to ensure that the primary does + not remove WAL segments until they have been received by all standbys, + and that the primary does not remove rows which could cause a + recovery conflict even when the + standby is disconnected. + + + In lieu of using replication slots, it is possible to prevent the removal + of old WAL segments using , or by + storing the segments in an archive using + . + However, these methods often result in retaining more WAL segments than + required, whereas replication slots retain only the number of segments + known to be needed. On the other hand, replication slots can retain so + many WAL segments that they fill up the space allocated + for pg_wal; + limits the size of WAL files + retained by replication slots. + + + Similarly, + and provide protection against + relevant rows being removed by vacuum, but the former provides no + protection during any time period when the standby is not connected, + and the latter often needs to be set to a high value to provide adequate + protection. Replication slots overcome these disadvantages. + + + Querying and Manipulating Replication Slots + + Each replication slot has a name, which can contain lower-case letters, + numbers, and the underscore character. + + + Existing replication slots and their state can be seen in the + pg_replication_slots + view. + + + Slots can be created and dropped either via the streaming replication + protocol (see ) or via SQL + functions (see ). + + + + Configuration Example + + You can create a replication slot like this: + +postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot'); + slot_name | lsn +-------------+----- + node_a_slot | + +postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots; + slot_name | slot_type | active +-------------+-----------+-------- + node_a_slot | physical | f +(1 row) + + To configure the standby to use this slot, primary_slot_name + should be configured on the standby. Here is a simple example: + +primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' +primary_slot_name = 'node_a_slot' + + + + + + + Cascading Replication + + + Cascading Replication + + + + The cascading replication feature allows a standby server to accept replication + connections and stream WAL records to other standbys, acting as a relay. + This can be used to reduce the number of direct connections to the primary + and also to minimize inter-site bandwidth overheads. + + + + A standby acting as both a receiver and a sender is known as a cascading + standby. Standbys that are more directly connected to the primary are known + as upstream servers, while those standby servers further away are downstream + servers. Cascading replication does not place limits on the number or + arrangement of downstream servers, though each standby connects to only + one upstream server which eventually links to a single primary server. + + + + A cascading standby sends not only WAL records received from the + primary but also those restored from the archive. So even if the replication + connection in some upstream connection is terminated, streaming replication + continues downstream for as long as new WAL records are available. + + + + Cascading replication is currently asynchronous. Synchronous replication + (see ) settings have no effect on + cascading replication at present. + + + + Hot Standby feedback propagates upstream, whatever the cascaded arrangement. + + + + If an upstream standby server is promoted to become the new primary, downstream + servers will continue to stream from the new primary if + recovery_target_timeline is set to 'latest' (the default). + + + + To use cascading replication, set up the cascading standby so that it can + accept replication connections (that is, set + and , + and configure + host-based authentication). + You will also need to set primary_conninfo in the downstream + standby to point to the cascading standby. + + + + + Synchronous Replication + + + Synchronous Replication + + + + PostgreSQL streaming replication is asynchronous by + default. If the primary server + crashes then some transactions that were committed may not have been + replicated to the standby server, causing data loss. The amount + of data loss is proportional to the replication delay at the time of + failover. + + + + Synchronous replication offers the ability to confirm that all changes + made by a transaction have been transferred to one or more synchronous + standby servers. This extends that standard level of durability + offered by a transaction commit. This level of protection is referred + to as 2-safe replication in computer science theory, and group-1-safe + (group-safe and 1-safe) when synchronous_commit is set to + remote_write. + + + + When requesting synchronous replication, each commit of a + write transaction will wait until confirmation is + received that the commit has been written to the write-ahead log on disk + of both the primary and standby server. The only possibility that data + can be lost is if both the primary and the standby suffer crashes at the + same time. This can provide a much higher level of durability, though only + if the sysadmin is cautious about the placement and management of the two + servers. Waiting for confirmation increases the user's confidence that the + changes will not be lost in the event of server crashes but it also + necessarily increases the response time for the requesting transaction. + The minimum wait time is the round-trip time between primary to standby. + + + + Read only transactions and transaction rollbacks need not wait for + replies from standby servers. Subtransaction commits do not wait for + responses from standby servers, only top-level commits. Long + running actions such as data loading or index building do not wait + until the very final commit message. All two-phase commit actions + require commit waits, including both prepare and commit. + + + + A synchronous standby can be a physical replication standby or a logical + replication subscriber. It can also be any other physical or logical WAL + replication stream consumer that knows how to send the appropriate + feedback messages. Besides the built-in physical and logical replication + systems, this includes special programs such + as pg_receivewal and pg_recvlogical + as well as some third-party replication systems and custom programs. + Check the respective documentation for details on synchronous replication + support. + + + + Basic Configuration + + + Once streaming replication has been configured, configuring synchronous + replication requires only one additional configuration step: + must be set to + a non-empty value. synchronous_commit must also be set to + on, but since this is the default value, typically no change is + required. (See and + .) + This configuration will cause each commit to wait for + confirmation that the standby has written the commit record to durable + storage. + synchronous_commit can be set by individual + users, so it can be configured in the configuration file, for particular + users or databases, or dynamically by applications, in order to control + the durability guarantee on a per-transaction basis. + + + + After a commit record has been written to disk on the primary, the + WAL record is then sent to the standby. The standby sends reply + messages each time a new batch of WAL data is written to disk, unless + wal_receiver_status_interval is set to zero on the standby. + In the case that synchronous_commit is set to + remote_apply, the standby sends reply messages when the commit + record is replayed, making the transaction visible. + If the standby is chosen as a synchronous standby, according to the setting + of synchronous_standby_names on the primary, the reply + messages from that standby will be considered along with those from other + synchronous standbys to decide when to release transactions waiting for + confirmation that the commit record has been received. These parameters + allow the administrator to specify which standby servers should be + synchronous standbys. Note that the configuration of synchronous + replication is mainly on the primary. Named standbys must be directly + connected to the primary; the primary knows nothing about downstream + standby servers using cascaded replication. + + + + Setting synchronous_commit to remote_write will + cause each commit to wait for confirmation that the standby has received + the commit record and written it out to its own operating system, but not + for the data to be flushed to disk on the standby. This + setting provides a weaker guarantee of durability than on + does: the standby could lose the data in the event of an operating system + crash, though not a PostgreSQL crash. + However, it's a useful setting in practice + because it can decrease the response time for the transaction. + Data loss could only occur if both the primary and the standby crash and + the database of the primary gets corrupted at the same time. + + + + Setting synchronous_commit to remote_apply will + cause each commit to wait until the current synchronous standbys report + that they have replayed the transaction, making it visible to user + queries. In simple cases, this allows for load balancing with causal + consistency. + + + + Users will stop waiting if a fast shutdown is requested. However, as + when using asynchronous replication, the server will not fully + shutdown until all outstanding WAL records are transferred to the currently + connected standby servers. + + + + + + Multiple Synchronous Standbys + + + Synchronous replication supports one or more synchronous standby servers; + transactions will wait until all the standby servers which are considered + as synchronous confirm receipt of their data. The number of synchronous + standbys that transactions must wait for replies from is specified in + synchronous_standby_names. This parameter also specifies + a list of standby names and the method (FIRST and + ANY) to choose synchronous standbys from the listed ones. + + + The method FIRST specifies a priority-based synchronous + replication and makes transaction commits wait until their WAL records are + replicated to the requested number of synchronous standbys chosen based on + their priorities. The standbys whose names appear earlier in the list are + given higher priority and will be considered as synchronous. Other standby + servers appearing later in this list represent potential synchronous + standbys. If any of the current synchronous standbys disconnects for + whatever reason, it will be replaced immediately with the + next-highest-priority standby. + + + An example of synchronous_standby_names for + a priority-based multiple synchronous standbys is: + +synchronous_standby_names = 'FIRST 2 (s1, s2, s3)' + + In this example, if four standby servers s1, s2, + s3 and s4 are running, the two standbys + s1 and s2 will be chosen as synchronous standbys + because their names appear early in the list of standby names. + s3 is a potential synchronous standby and will take over + the role of synchronous standby when either of s1 or + s2 fails. s4 is an asynchronous standby since + its name is not in the list. + + + The method ANY specifies a quorum-based synchronous + replication and makes transaction commits wait until their WAL records + are replicated to at least the requested number of + synchronous standbys in the list. + + + An example of synchronous_standby_names for + a quorum-based multiple synchronous standbys is: + +synchronous_standby_names = 'ANY 2 (s1, s2, s3)' + + In this example, if four standby servers s1, s2, + s3 and s4 are running, transaction commits will + wait for replies from at least any two standbys of s1, + s2 and s3. s4 is an asynchronous + standby since its name is not in the list. + + + The synchronous states of standby servers can be viewed using + the pg_stat_replication view. + + + + + Planning for Performance + + + Synchronous replication usually requires carefully planned and placed + standby servers to ensure applications perform acceptably. Waiting + doesn't utilize system resources, but transaction locks continue to be + held until the transfer is confirmed. As a result, incautious use of + synchronous replication will reduce performance for database + applications because of increased response times and higher contention. + + + + PostgreSQL allows the application developer + to specify the durability level required via replication. This can be + specified for the system overall, though it can also be specified for + specific users or connections, or even individual transactions. + + + + For example, an application workload might consist of: + 10% of changes are important customer details, while + 90% of changes are less important data that the business can more + easily survive if it is lost, such as chat messages between users. + + + + With synchronous replication options specified at the application level + (on the primary) we can offer synchronous replication for the most + important changes, without slowing down the bulk of the total workload. + Application level options are an important and practical tool for allowing + the benefits of synchronous replication for high performance applications. + + + + You should consider that the network bandwidth must be higher than + the rate of generation of WAL data. + + + + + + Planning for High Availability + + + synchronous_standby_names specifies the number and + names of synchronous standbys that transaction commits made when + synchronous_commit is set to on, + remote_apply or remote_write will wait for + responses from. Such transaction commits may never be completed + if any one of synchronous standbys should crash. + + + + The best solution for high availability is to ensure you keep as many + synchronous standbys as requested. This can be achieved by naming multiple + potential synchronous standbys using synchronous_standby_names. + + + + In a priority-based synchronous replication, the standbys whose names + appear earlier in the list will be used as synchronous standbys. + Standbys listed after these will take over the role of synchronous standby + if one of current ones should fail. + + + + In a quorum-based synchronous replication, all the standbys appearing + in the list will be used as candidates for synchronous standbys. + Even if one of them should fail, the other standbys will keep performing + the role of candidates of synchronous standby. + + + + When a standby first attaches to the primary, it will not yet be properly + synchronized. This is described as catchup mode. Once + the lag between standby and primary reaches zero for the first time + we move to real-time streaming state. + The catch-up duration may be long immediately after the standby has + been created. If the standby is shut down, then the catch-up period + will increase according to the length of time the standby has been down. + The standby is only able to become a synchronous standby + once it has reached streaming state. + This state can be viewed using + the pg_stat_replication view. + + + + If primary restarts while commits are waiting for acknowledgment, those + waiting transactions will be marked fully committed once the primary + database recovers. + There is no way to be certain that all standbys have received all + outstanding WAL data at time of the crash of the primary. Some + transactions may not show as committed on the standby, even though + they show as committed on the primary. The guarantee we offer is that + the application will not receive explicit acknowledgment of the + successful commit of a transaction until the WAL data is known to be + safely received by all the synchronous standbys. + + + + If you really cannot keep as many synchronous standbys as requested + then you should decrease the number of synchronous standbys that + transaction commits must wait for responses from + in synchronous_standby_names (or disable it) and + reload the configuration file on the primary server. + + + + If the primary is isolated from remaining standby servers you should + fail over to the best candidate of those other remaining standby servers. + + + + If you need to re-create a standby server while transactions are + waiting, make sure that the commands pg_start_backup() and + pg_stop_backup() are run in a session with + synchronous_commit = off, otherwise those + requests will wait forever for the standby to appear. + + + + + + + Continuous Archiving in Standby + + + continuous archiving + in standby + + + + When continuous WAL archiving is used in a standby, there are two + different scenarios: the WAL archive can be shared between the primary + and the standby, or the standby can have its own WAL archive. When + the standby has its own WAL archive, set archive_mode + to always, and the standby will call the archive + command for every WAL segment it receives, whether it's by restoring + from the archive or by streaming replication. The shared archive can + be handled similarly, but the archive_command must + test if the file being archived exists already, and if the existing file + has identical contents. This requires more care in the + archive_command, as it must + be careful to not overwrite an existing file with different contents, + but return success if the exactly same file is archived twice. And + all that must be done free of race conditions, if two servers attempt + to archive the same file at the same time. + + + + If archive_mode is set to on, the + archiver is not enabled during recovery or standby mode. If the standby + server is promoted, it will start archiving after the promotion, but + will not archive any WAL or timeline history files that + it did not generate itself. To get a complete + series of WAL files in the archive, you must ensure that all WAL is + archived, before it reaches the standby. This is inherently true with + file-based log shipping, as the standby can only restore files that + are found in the archive, but not if streaming replication is enabled. + When a server is not in recovery mode, there is no difference between + on and always modes. + + + + + + Failover + + + If the primary server fails then the standby server should begin + failover procedures. + + + + If the standby server fails then no failover need take place. If the + standby server can be restarted, even some time later, then the recovery + process can also be restarted immediately, taking advantage of + restartable recovery. If the standby server cannot be restarted, then a + full new standby server instance should be created. + + + + If the primary server fails and the standby server becomes the + new primary, and then the old primary restarts, you must have + a mechanism for informing the old primary that it is no longer the primary. This is + sometimes known as STONITH (Shoot The Other Node In The Head), which is + necessary to avoid situations where both systems think they are the + primary, which will lead to confusion and ultimately data loss. + + + + Many failover systems use just two systems, the primary and the standby, + connected by some kind of heartbeat mechanism to continually verify the + connectivity between the two and the viability of the primary. It is + also possible to use a third system (called a witness server) to prevent + some cases of inappropriate failover, but the additional complexity + might not be worthwhile unless it is set up with sufficient care and + rigorous testing. + + + + PostgreSQL does not provide the system + software required to identify a failure on the primary and notify + the standby database server. Many such tools exist and are well + integrated with the operating system facilities required for + successful failover, such as IP address migration. + + + + Once failover to the standby occurs, there is only a + single server in operation. This is known as a degenerate state. + The former standby is now the primary, but the former primary is down + and might stay down. To return to normal operation, a standby server + must be recreated, + either on the former primary system when it comes up, or on a third, + possibly new, system. The utility can be + used to speed up this process on large clusters. + Once complete, the primary and standby can be + considered to have switched roles. Some people choose to use a third + server to provide backup for the new primary until the new standby + server is recreated, + though clearly this complicates the system configuration and + operational processes. + + + + So, switching from primary to standby server can be fast but requires + some time to re-prepare the failover cluster. Regular switching from + primary to standby is useful, since it allows regular downtime on + each system for maintenance. This also serves as a test of the + failover mechanism to ensure that it will really work when you need it. + Written administration procedures are advised. + + + + To trigger failover of a log-shipping standby server, run + pg_ctl promote, call pg_promote(), + or create a trigger file with the file name and path specified by the + promote_trigger_file. If you're planning to use + pg_ctl promote or to call + pg_promote() to fail over, + promote_trigger_file is not required. If you're + setting up the reporting servers that are only used to offload read-only + queries from the primary, not for high availability purposes, you don't + need to promote it. + + + + + Hot Standby + + + Hot Standby + + + + Hot Standby is the term used to describe the ability to connect to + the server and run read-only queries while the server is in archive + recovery or standby mode. This + is useful both for replication purposes and for restoring a backup + to a desired state with great precision. + The term Hot Standby also refers to the ability of the server to move + from recovery through to normal operation while users continue running + queries and/or keep their connections open. + + + + Running queries in hot standby mode is similar to normal query operation, + though there are several usage and administrative differences + explained below. + + + + User's Overview + + + When the parameter is set to true on a + standby server, it will begin accepting connections once the recovery has + brought the system to a consistent state. All such connections are + strictly read-only; not even temporary tables may be written. + + + + The data on the standby takes some time to arrive from the primary server + so there will be a measurable delay between primary and standby. Running the + same query nearly simultaneously on both primary and standby might therefore + return differing results. We say that data on the standby is + eventually consistent with the primary. Once the + commit record for a transaction is replayed on the standby, the changes + made by that transaction will be visible to any new snapshots taken on + the standby. Snapshots may be taken at the start of each query or at the + start of each transaction, depending on the current transaction isolation + level. For more details, see . + + + + Transactions started during hot standby may issue the following commands: + + + + + Query access: SELECT, COPY TO + + + + + Cursor commands: DECLARE, FETCH, CLOSE + + + + + Settings: SHOW, SET, RESET + + + + + Transaction management commands: + + + + BEGIN, END, ABORT, START TRANSACTION + + + + + SAVEPOINT, RELEASE, ROLLBACK TO SAVEPOINT + + + + + EXCEPTION blocks and other internal subtransactions + + + + + + + + LOCK TABLE, though only when explicitly in one of these modes: + ACCESS SHARE, ROW SHARE or ROW EXCLUSIVE. + + + + + Plans and resources: PREPARE, EXECUTE, + DEALLOCATE, DISCARD + + + + + Plugins and extensions: LOAD + + + + + UNLISTEN + + + + + + + Transactions started during hot standby will never be assigned a + transaction ID and cannot write to the system write-ahead log. + Therefore, the following actions will produce error messages: + + + + + Data Manipulation Language (DML): INSERT, + UPDATE, DELETE, COPY FROM, + TRUNCATE. + Note that there are no allowed actions that result in a trigger + being executed during recovery. This restriction applies even to + temporary tables, because table rows cannot be read or written without + assigning a transaction ID, which is currently not possible in a + Hot Standby environment. + + + + + Data Definition Language (DDL): CREATE, + DROP, ALTER, COMMENT. + This restriction applies even to temporary tables, because carrying + out these operations would require updating the system catalog tables. + + + + + SELECT ... FOR SHARE | UPDATE, because row locks cannot be + taken without updating the underlying data files. + + + + + Rules on SELECT statements that generate DML commands. + + + + + LOCK that explicitly requests a mode higher than ROW EXCLUSIVE MODE. + + + + + LOCK in short default form, since it requests ACCESS EXCLUSIVE MODE. + + + + + Transaction management commands that explicitly set non-read-only state: + + + + BEGIN READ WRITE, + START TRANSACTION READ WRITE + + + + + SET TRANSACTION READ WRITE, + SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE + + + + + SET transaction_read_only = off + + + + + + + + Two-phase commit commands: PREPARE TRANSACTION, + COMMIT PREPARED, ROLLBACK PREPARED + because even read-only transactions need to write WAL in the + prepare phase (the first phase of two phase commit). + + + + + Sequence updates: nextval(), setval() + + + + + LISTEN, NOTIFY + + + + + + + In normal operation, read-only transactions are allowed to + use LISTEN and NOTIFY, + so Hot Standby sessions operate under slightly tighter + restrictions than ordinary read-only sessions. It is possible that some + of these restrictions might be loosened in a future release. + + + + During hot standby, the parameter transaction_read_only is always + true and may not be changed. But as long as no attempt is made to modify + the database, connections during hot standby will act much like any other + database connection. If failover or switchover occurs, the database will + switch to normal processing mode. Sessions will remain connected while the + server changes mode. Once hot standby finishes, it will be possible to + initiate read-write transactions (even from a session begun during + hot standby). + + + + Users can determine whether hot standby is currently active for their + session by issuing SHOW in_hot_standby. + (In server versions before 14, the in_hot_standby + parameter did not exist; a workable substitute method for older servers + is SHOW transaction_read_only.) In addition, a set of + functions () allow users to + access information about the standby server. These allow you to write + programs that are aware of the current state of the database. These + can be used to monitor the progress of recovery, or to allow you to + write complex programs that restore the database to particular states. + + + + + Handling Query Conflicts + + + The primary and standby servers are in many ways loosely connected. Actions + on the primary will have an effect on the standby. As a result, there is + potential for negative interactions or conflicts between them. The easiest + conflict to understand is performance: if a huge data load is taking place + on the primary then this will generate a similar stream of WAL records on the + standby, so standby queries may contend for system resources, such as I/O. + + + + There are also additional types of conflict that can occur with Hot Standby. + These conflicts are hard conflicts in the sense that queries + might need to be canceled and, in some cases, sessions disconnected to resolve them. + The user is provided with several ways to handle these + conflicts. Conflict cases include: + + + + + Access Exclusive locks taken on the primary server, including both + explicit LOCK commands and various DDL + actions, conflict with table accesses in standby queries. + + + + + Dropping a tablespace on the primary conflicts with standby queries + using that tablespace for temporary work files. + + + + + Dropping a database on the primary conflicts with sessions connected + to that database on the standby. + + + + + Application of a vacuum cleanup record from WAL conflicts with + standby transactions whose snapshots can still see any of + the rows to be removed. + + + + + Application of a vacuum cleanup record from WAL conflicts with + queries accessing the target page on the standby, whether or not + the data to be removed is visible. + + + + + + + On the primary server, these cases simply result in waiting; and the + user might choose to cancel either of the conflicting actions. However, + on the standby there is no choice: the WAL-logged action already occurred + on the primary so the standby must not fail to apply it. Furthermore, + allowing WAL application to wait indefinitely may be very undesirable, + because the standby's state will become increasingly far behind the + primary's. Therefore, a mechanism is provided to forcibly cancel standby + queries that conflict with to-be-applied WAL records. + + + + An example of the problem situation is an administrator on the primary + server running DROP TABLE on a table that is currently being + queried on the standby server. Clearly the standby query cannot continue + if the DROP TABLE is applied on the standby. If this situation + occurred on the primary, the DROP TABLE would wait until the + other query had finished. But when DROP TABLE is run on the + primary, the primary doesn't have information about what queries are + running on the standby, so it will not wait for any such standby + queries. The WAL change records come through to the standby while the + standby query is still running, causing a conflict. The standby server + must either delay application of the WAL records (and everything after + them, too) or else cancel the conflicting query so that the DROP + TABLE can be applied. + + + + When a conflicting query is short, it's typically desirable to allow it to + complete by delaying WAL application for a little bit; but a long delay in + WAL application is usually not desirable. So the cancel mechanism has + parameters, and , that define the maximum + allowed delay in WAL application. Conflicting queries will be canceled + once it has taken longer than the relevant delay setting to apply any + newly-received WAL data. There are two parameters so that different delay + values can be specified for the case of reading WAL data from an archive + (i.e., initial recovery from a base backup or catching up a + standby server that has fallen far behind) versus reading WAL data via + streaming replication. + + + + In a standby server that exists primarily for high availability, it's + best to set the delay parameters relatively short, so that the server + cannot fall far behind the primary due to delays caused by standby + queries. However, if the standby server is meant for executing + long-running queries, then a high or even infinite delay value may be + preferable. Keep in mind however that a long-running query could + cause other sessions on the standby server to not see recent changes + on the primary, if it delays application of WAL records. + + + + Once the delay specified by max_standby_archive_delay or + max_standby_streaming_delay has been exceeded, conflicting + queries will be canceled. This usually results just in a cancellation + error, although in the case of replaying a DROP DATABASE + the entire conflicting session will be terminated. Also, if the conflict + is over a lock held by an idle transaction, the conflicting session is + terminated (this behavior might change in the future). + + + + Canceled queries may be retried immediately (after beginning a new + transaction, of course). Since query cancellation depends on + the nature of the WAL records being replayed, a query that was + canceled may well succeed if it is executed again. + + + + Keep in mind that the delay parameters are compared to the elapsed time + since the WAL data was received by the standby server. Thus, the grace + period allowed to any one query on the standby is never more than the + delay parameter, and could be considerably less if the standby has already + fallen behind as a result of waiting for previous queries to complete, or + as a result of being unable to keep up with a heavy update load. + + + + The most common reason for conflict between standby queries and WAL replay + is early cleanup. Normally, PostgreSQL allows + cleanup of old row versions when there are no transactions that need to + see them to ensure correct visibility of data according to MVCC rules. + However, this rule can only be applied for transactions executing on the + primary. So it is possible that cleanup on the primary will remove row + versions that are still visible to a transaction on the standby. + + + + Experienced users should note that both row version cleanup and row version + freezing will potentially conflict with standby queries. Running a manual + VACUUM FREEZE is likely to cause conflicts even on tables with + no updated or deleted rows. + + + + Users should be clear that tables that are regularly and heavily updated + on the primary server will quickly cause cancellation of longer running + queries on the standby. In such cases the setting of a finite value for + max_standby_archive_delay or + max_standby_streaming_delay can be considered similar to + setting statement_timeout. + + + + Remedial possibilities exist if the number of standby-query cancellations + is found to be unacceptable. The first option is to set the parameter + hot_standby_feedback, which prevents VACUUM from + removing recently-dead rows and so cleanup conflicts do not occur. + If you do this, you + should note that this will delay cleanup of dead rows on the primary, + which may result in undesirable table bloat. However, the cleanup + situation will be no worse than if the standby queries were running + directly on the primary server, and you are still getting the benefit of + off-loading execution onto the standby. + If standby servers connect and disconnect frequently, you + might want to make adjustments to handle the period when + hot_standby_feedback feedback is not being provided. + For example, consider increasing max_standby_archive_delay + so that queries are not rapidly canceled by conflicts in WAL archive + files during disconnected periods. You should also consider increasing + max_standby_streaming_delay to avoid rapid cancellations + by newly-arrived streaming WAL entries after reconnection. + + + + Another option is to increase + on the primary server, so that dead rows will not be cleaned up as quickly + as they normally would be. This will allow more time for queries to + execute before they are canceled on the standby, without having to set + a high max_standby_streaming_delay. However it is + difficult to guarantee any specific execution-time window with this + approach, since vacuum_defer_cleanup_age is measured in + transactions executed on the primary server. + + + + The number of query cancels and the reason for them can be viewed using + the pg_stat_database_conflicts system view on the standby + server. The pg_stat_database system view also contains + summary information. + + + + Users can control whether a log message is produced when WAL replay is waiting + longer than deadlock_timeout for conflicts. This + is controlled by the parameter. + + + + + Administrator's Overview + + + If hot_standby is on in postgresql.conf + (the default value) and there is a + standby.signalstandby.signalfor hot standby + file present, the server will run in Hot Standby mode. + However, it may take some time for Hot Standby connections to be allowed, + because the server will not accept connections until it has completed + sufficient recovery to provide a consistent state against which queries + can run. During this period, + clients that attempt to connect will be refused with an error message. + To confirm the server has come up, either loop trying to connect from + the application, or look for these messages in the server logs: + + +LOG: entering standby mode + +... then some time later ... + +LOG: consistent recovery state reached +LOG: database system is ready to accept read only connections + + + Consistency information is recorded once per checkpoint on the primary. + It is not possible to enable hot standby when reading WAL + written during a period when wal_level was not set to + replica or logical on the primary. Reaching + a consistent state can also be delayed in the presence of both of these + conditions: + + + + + A write transaction has more than 64 subtransactions + + + + + Very long-lived write transactions + + + + + If you are running file-based log shipping ("warm standby"), you might need + to wait until the next WAL file arrives, which could be as long as the + archive_timeout setting on the primary. + + + + The settings of some parameters determine the size of shared memory for + tracking transaction IDs, locks, and prepared transactions. These shared + memory structures must be no smaller on a standby than on the primary in + order to ensure that the standby does not run out of shared memory during + recovery. For example, if the primary had used a prepared transaction but + the standby had not allocated any shared memory for tracking prepared + transactions, then recovery could not continue until the standby's + configuration is changed. The parameters affected are: + + + + + max_connections + + + + + max_prepared_transactions + + + + + max_locks_per_transaction + + + + + max_wal_senders + + + + + max_worker_processes + + + + + The easiest way to ensure this does not become a problem is to have these + parameters set on the standbys to values equal to or greater than on the + primary. Therefore, if you want to increase these values, you should do + so on all standby servers first, before applying the changes to the + primary server. Conversely, if you want to decrease these values, you + should do so on the primary server first, before applying the changes to + all standby servers. Keep in mind that when a standby is promoted, it + becomes the new reference for the required parameter settings for the + standbys that follow it. Therefore, to avoid this becoming a problem + during a switchover or failover, it is recommended to keep these settings + the same on all standby servers. + + + + The WAL tracks changes to these parameters on the + primary. If a hot standby processes WAL that indicates that the current + value on the primary is higher than its own value, it will log a warning + and pause recovery, for example: + +WARNING: hot standby is not possible because of insufficient parameter settings +DETAIL: max_connections = 80 is a lower setting than on the primary server, where its value was 100. +LOG: recovery has paused +DETAIL: If recovery is unpaused, the server will shut down. +HINT: You can then restart the server after making the necessary configuration changes. + + At that point, the settings on the standby need to be updated and the + instance restarted before recovery can continue. If the standby is not a + hot standby, then when it encounters the incompatible parameter change, it + will shut down immediately without pausing, since there is then no value + in keeping it up. + + + + It is important that the administrator select appropriate settings for + and . The best choices vary + depending on business priorities. For example if the server is primarily + tasked as a High Availability server, then you will want low delay + settings, perhaps even zero, though that is a very aggressive setting. If + the standby server is tasked as an additional server for decision support + queries then it might be acceptable to set the maximum delay values to + many hours, or even -1 which means wait forever for queries to complete. + + + + Transaction status "hint bits" written on the primary are not WAL-logged, + so data on the standby will likely re-write the hints again on the standby. + Thus, the standby server will still perform disk writes even though + all users are read-only; no changes occur to the data values + themselves. Users will still write large sort temporary files and + re-generate relcache info files, so no part of the database + is truly read-only during hot standby mode. + Note also that writes to remote databases using + dblink module, and other operations outside the + database using PL functions will still be possible, even though the + transaction is read-only locally. + + + + The following types of administration commands are not accepted + during recovery mode: + + + + + Data Definition Language (DDL): e.g., CREATE INDEX + + + + + Privilege and Ownership: GRANT, REVOKE, + REASSIGN + + + + + Maintenance commands: ANALYZE, VACUUM, + CLUSTER, REINDEX + + + + + + + Again, note that some of these commands are actually allowed during + "read only" mode transactions on the primary. + + + + As a result, you cannot create additional indexes that exist solely + on the standby, nor statistics that exist solely on the standby. + If these administration commands are needed, they should be executed + on the primary, and eventually those changes will propagate to the + standby. + + + + pg_cancel_backend() + and pg_terminate_backend() will work on user backends, + but not the Startup process, which performs + recovery. pg_stat_activity does not show + recovering transactions as active. As a result, + pg_prepared_xacts is always empty during + recovery. If you wish to resolve in-doubt prepared transactions, view + pg_prepared_xacts on the primary and issue commands to + resolve transactions there or resolve them after the end of recovery. + + + + pg_locks will show locks held by backends, + as normal. pg_locks also shows + a virtual transaction managed by the Startup process that owns all + AccessExclusiveLocks held by transactions being replayed by recovery. + Note that the Startup process does not acquire locks to + make database changes, and thus locks other than AccessExclusiveLocks + do not show in pg_locks for the Startup + process; they are just presumed to exist. + + + + The Nagios plugin check_pgsql will + work, because the simple information it checks for exists. + The check_postgres monitoring script will also work, + though some reported values could give different or confusing results. + For example, last vacuum time will not be maintained, since no + vacuum occurs on the standby. Vacuums running on the primary + do still send their changes to the standby. + + + + WAL file control commands will not work during recovery, + e.g., pg_start_backup, pg_switch_wal etc. + + + + Dynamically loadable modules work, including pg_stat_statements. + + + + Advisory locks work normally in recovery, including deadlock detection. + Note that advisory locks are never WAL logged, so it is impossible for + an advisory lock on either the primary or the standby to conflict with WAL + replay. Nor is it possible to acquire an advisory lock on the primary + and have it initiate a similar advisory lock on the standby. Advisory + locks relate only to the server on which they are acquired. + + + + Trigger-based replication systems such as Slony, + Londiste and Bucardo won't run on the + standby at all, though they will run happily on the primary server as + long as the changes are not sent to standby servers to be applied. + WAL replay is not trigger-based so you cannot relay from the + standby to any system that requires additional database writes or + relies on the use of triggers. + + + + New OIDs cannot be assigned, though some UUID generators may still + work as long as they do not rely on writing new status to the database. + + + + Currently, temporary table creation is not allowed during read only + transactions, so in some cases existing scripts will not run correctly. + This restriction might be relaxed in a later release. This is + both an SQL Standard compliance issue and a technical issue. + + + + DROP TABLESPACE can only succeed if the tablespace is empty. + Some standby users may be actively using the tablespace via their + temp_tablespaces parameter. If there are temporary files in the + tablespace, all active queries are canceled to ensure that temporary + files are removed, so the tablespace can be removed and WAL replay + can continue. + + + + Running DROP DATABASE or ALTER DATABASE ... SET + TABLESPACE on the primary + will generate a WAL entry that will cause all users connected to that + database on the standby to be forcibly disconnected. This action occurs + immediately, whatever the setting of + max_standby_streaming_delay. Note that + ALTER DATABASE ... RENAME does not disconnect users, which + in most cases will go unnoticed, though might in some cases cause a + program confusion if it depends in some way upon database name. + + + + In normal (non-recovery) mode, if you issue DROP USER or DROP ROLE + for a role with login capability while that user is still connected then + nothing happens to the connected user — they remain connected. The user cannot + reconnect however. This behavior applies in recovery also, so a + DROP USER on the primary does not disconnect that user on the standby. + + + + The statistics collector is active during recovery. All scans, reads, blocks, + index usage, etc., will be recorded normally on the standby. Replayed + actions will not duplicate their effects on primary, so replaying an + insert will not increment the Inserts column of pg_stat_user_tables. + The stats file is deleted at the start of recovery, so stats from primary + and standby will differ; this is considered a feature, not a bug. + + + + Autovacuum is not active during recovery. It will start normally at the + end of recovery. + + + + The checkpointer process and the background writer process are active during + recovery. The checkpointer process will perform restartpoints (similar to + checkpoints on the primary) and the background writer process will perform + normal block cleaning activities. This can include updates of the hint bit + information stored on the standby server. + The CHECKPOINT command is accepted during recovery, + though it performs a restartpoint rather than a new checkpoint. + + + + + Hot Standby Parameter Reference + + + Various parameters have been mentioned above in + and + . + + + + On the primary, parameters and + can be used. + and + have no effect if set on + the primary. + + + + On the standby, parameters , + and + can be used. + has no effect + as long as the server remains in standby mode, though it will + become relevant if the standby becomes primary. + + + + + Caveats + + + There are several limitations of Hot Standby. + These can and probably will be fixed in future releases: + + + + + Full knowledge of running transactions is required before snapshots + can be taken. Transactions that use large numbers of subtransactions + (currently greater than 64) will delay the start of read only + connections until the completion of the longest running write transaction. + If this situation occurs, explanatory messages will be sent to the server log. + + + + + Valid starting points for standby queries are generated at each + checkpoint on the primary. If the standby is shut down while the primary + is in a shutdown state, it might not be possible to re-enter Hot Standby + until the primary is started up, so that it generates further starting + points in the WAL logs. This situation isn't a problem in the most + common situations where it might happen. Generally, if the primary is + shut down and not available anymore, that's likely due to a serious + failure that requires the standby being converted to operate as + the new primary anyway. And in situations where the primary is + being intentionally taken down, coordinating to make sure the standby + becomes the new primary smoothly is also standard procedure. + + + + + At the end of recovery, AccessExclusiveLocks held by prepared transactions + will require twice the normal number of lock table entries. If you plan + on running either a large number of concurrent prepared transactions + that normally take AccessExclusiveLocks, or you plan on having one + large transaction that takes many AccessExclusiveLocks, you are + advised to select a larger value of max_locks_per_transaction, + perhaps as much as twice the value of the parameter on + the primary server. You need not consider this at all if + your setting of max_prepared_transactions is 0. + + + + + The Serializable transaction isolation level is not yet available in hot + standby. (See and + for details.) + An attempt to set a transaction to the serializable isolation level in + hot standby mode will generate an error. + + + + + + + + + +
diff --git a/doc/src/sgml/hstore.sgml b/doc/src/sgml/hstore.sgml new file mode 100644 index 000000000000..870063c288ba --- /dev/null +++ b/doc/src/sgml/hstore.sgml @@ -0,0 +1,981 @@ + + + + hstore + + + hstore + + + + This module implements the hstore data type for storing sets of + key/value pairs within a single PostgreSQL value. + This can be useful in various scenarios, such as rows with many attributes + that are rarely examined, or semi-structured data. Keys and values are + simply text strings. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + <type>hstore</type> External Representation + + + + The text representation of an hstore, used for input and output, + includes zero or more key => + value pairs separated by commas. Some examples: + + +k => v +foo => bar, baz => whatever +"1-a" => "anything at all" + + + The order of the pairs is not significant (and may not be reproduced on + output). Whitespace between pairs or around the => sign is + ignored. Double-quote keys and values that include whitespace, commas, + =s or >s. To include a double quote or a + backslash in a key or value, escape it with a backslash. + + + + Each key in an hstore is unique. If you declare an hstore + with duplicate keys, only one will be stored in the hstore and + there is no guarantee as to which will be kept: + + +SELECT 'a=>1,a=>2'::hstore; + hstore +---------- + "a"=>"1" + + + + + A value (but not a key) can be an SQL NULL. For example: + + +key => NULL + + + The NULL keyword is case-insensitive. Double-quote the + NULL to treat it as the ordinary string NULL. + + + + + Keep in mind that the hstore text format, when used for input, + applies before any required quoting or escaping. If you are + passing an hstore literal via a parameter, then no additional + processing is needed. But if you're passing it as a quoted literal + constant, then any single-quote characters and (depending on the setting of + the standard_conforming_strings configuration parameter) + backslash characters need to be escaped correctly. See + for more on the handling of string + constants. + + + + + On output, double quotes always surround keys and values, even when it's + not strictly necessary. + + + + + + <type>hstore</type> Operators and Functions + + + The operators provided by the hstore module are + shown in , the functions + in . + + + + <type>hstore</type> Operators + + + + + Operator + + + Description + + + Example(s) + + + + + + + + hstore -> text + text + + + Returns value associated with given key, or NULL if + not present. + + + 'a=>x, b=>y'::hstore -> 'a' + x + + + + + + hstore -> text[] + text[] + + + Returns values associated with given keys, or NULL + if not present. + + + 'a=>x, b=>y, c=>z'::hstore -> ARRAY['c','a'] + {"z","x"} + + + + + + hstore || hstore + hstore + + + Concatenates two hstores. + + + 'a=>b, c=>d'::hstore || 'c=>x, d=>q'::hstore + "a"=>"b", "c"=>"x", "d"=>"q" + + + + + + hstore ? text + boolean + + + Does hstore contain key? + + + 'a=>1'::hstore ? 'a' + t + + + + + + hstore ?& text[] + boolean + + + Does hstore contain all the specified keys? + + + 'a=>1,b=>2'::hstore ?& ARRAY['a','b'] + t + + + + + + hstore ?| text[] + boolean + + + Does hstore contain any of the specified keys? + + + 'a=>1,b=>2'::hstore ?| ARRAY['b','c'] + t + + + + + + hstore @> hstore + boolean + + + Does left operand contain right? + + + 'a=>b, b=>1, c=>NULL'::hstore @> 'b=>1' + t + + + + + + hstore <@ hstore + boolean + + + Is left operand contained in right? + + + 'a=>c'::hstore <@ 'a=>b, b=>1, c=>NULL' + f + + + + + + hstore - text + hstore + + + Deletes key from left operand. + + + 'a=>1, b=>2, c=>3'::hstore - 'b'::text + "a"=>"1", "c"=>"3" + + + + + + hstore - text[] + hstore + + + Deletes keys from left operand. + + + 'a=>1, b=>2, c=>3'::hstore - ARRAY['a','b'] + "c"=>"3" + + + + + + hstore - hstore + hstore + + + Deletes pairs from left operand that match pairs in the right operand. + + + 'a=>1, b=>2, c=>3'::hstore - 'a=>4, b=>2'::hstore + "a"=>"1", "c"=>"3" + + + + + + anyelement #= hstore + anyelement + + + Replaces fields in the left operand (which must be a composite type) + with matching values from hstore. + + + ROW(1,3) #= 'f1=>11'::hstore + (11,3) + + + + + + %% hstore + text[] + + + Converts hstore to an array of alternating keys and + values. + + + %% 'a=>foo, b=>bar'::hstore + {a,foo,b,bar} + + + + + + %# hstore + text[] + + + Converts hstore to a two-dimensional key/value array. + + + %# 'a=>foo, b=>bar'::hstore + {{a,foo},{b,bar}} + + + + +
+ + + <type>hstore</type> Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + hstore + hstore ( record ) + hstore + + + Constructs an hstore from a record or row. + + + hstore(ROW(1,2)) + "f1"=>"1", "f2"=>"2" + + + + + + hstore ( text[] ) + hstore + + + Constructs an hstore from an array, which may be either + a key/value array, or a two-dimensional array. + + + hstore(ARRAY['a','1','b','2']) + "a"=>"1", "b"=>"2" + + + hstore(ARRAY[['c','3'],['d','4']]) + "c"=>"3", "d"=>"4" + + + + + + hstore ( text[], text[] ) + hstore + + + Constructs an hstore from separate key and value arrays. + + + hstore(ARRAY['a','b'], ARRAY['1','2']) + "a"=>"1", "b"=>"2" + + + + + + hstore ( text, text ) + hstore + + + Makes a single-item hstore. + + + hstore('a', 'b') + "a"=>"b" + + + + + + akeys + akeys ( hstore ) + text[] + + + Extracts an hstore's keys as an array. + + + akeys('a=>1,b=>2') + {a,b} + + + + + + skeys + skeys ( hstore ) + setof text + + + Extracts an hstore's keys as a set. + + + skeys('a=>1,b=>2') + + +a +b + + + + + + + avals + avals ( hstore ) + text[] + + + Extracts an hstore's values as an array. + + + avals('a=>1,b=>2') + {1,2} + + + + + + svals + svals ( hstore ) + setof text + + + Extracts an hstore's values as a set. + + + svals('a=>1,b=>2') + + +1 +2 + + + + + + + hstore_to_array + hstore_to_array ( hstore ) + text[] + + + Extracts an hstore's keys and values as an array of + alternating keys and values. + + + hstore_to_array('a=>1,b=>2') + {a,1,b,2} + + + + + + hstore_to_matrix + hstore_to_matrix ( hstore ) + text[] + + + Extracts an hstore's keys and values as a two-dimensional + array. + + + hstore_to_matrix('a=>1,b=>2') + {{a,1},{b,2}} + + + + + + hstore_to_json + hstore_to_json ( hstore ) + json + + + Converts an hstore to a json value, + converting all non-null values to JSON strings. + + + This function is used implicitly when an hstore value is + cast to json. + + + hstore_to_json('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4') + {"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"} + + + + + + hstore_to_jsonb + hstore_to_jsonb ( hstore ) + jsonb + + + Converts an hstore to a jsonb value, + converting all non-null values to JSON strings. + + + This function is used implicitly when an hstore value is + cast to jsonb. + + + hstore_to_jsonb('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4') + {"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"} + + + + + + hstore_to_json_loose + hstore_to_json_loose ( hstore ) + json + + + Converts an hstore to a json value, but + attempts to distinguish numerical and Boolean values so they are + unquoted in the JSON. + + + hstore_to_json_loose('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4') + {"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4} + + + + + + hstore_to_jsonb_loose + hstore_to_jsonb_loose ( hstore ) + jsonb + + + Converts an hstore to a jsonb value, but + attempts to distinguish numerical and Boolean values so they are + unquoted in the JSON. + + + hstore_to_jsonb_loose('"a key"=>1, b=>t, c=>null, d=>12345, e=>012345, f=>1.234, g=>2.345e+4') + {"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4} + + + + + + slice + slice ( hstore, text[] ) + hstore + + + Extracts a subset of an hstore containing only the + specified keys. + + + slice('a=>1,b=>2,c=>3'::hstore, ARRAY['b','c','x']) + "b"=>"2", "c"=>"3" + + + + + + each + each ( hstore ) + setof record + ( key text, + value text ) + + + Extracts an hstore's keys and values as a set of records. + + + select * from each('a=>1,b=>2') + + + key | value +-----+------- + a | 1 + b | 2 + + + + + + + exist + exist ( hstore, text ) + boolean + + + Does hstore contain key? + + + exist('a=>1', 'a') + t + + + + + + defined + defined ( hstore, text ) + boolean + + + Does hstore contain a non-NULL value + for key? + + + defined('a=>NULL', 'a') + f + + + + + + delete + delete ( hstore, text ) + hstore + + + Deletes pair with matching key. + + + delete('a=>1,b=>2', 'b') + "a"=>"1" + + + + + + delete ( hstore, text[] ) + hstore + + + Deletes pairs with matching keys. + + + delete('a=>1,b=>2,c=>3', ARRAY['a','b']) + "c"=>"3" + + + + + + delete ( hstore, hstore ) + hstore + + + Deletes pairs matching those in the second argument. + + + delete('a=>1,b=>2', 'a=>4,b=>2'::hstore) + "a"=>"1" + + + + + + populate_record + populate_record ( anyelement, hstore ) + anyelement + + + Replaces fields in the left operand (which must be a composite type) + with matching values from hstore. + + + populate_record(ROW(1,2), 'f1=>42'::hstore) + (42,2) + + + + +
+ + + In addition to these operators and functions, values of + the hstore type can be subscripted, allowing them to act + like associative arrays. Only a single subscript of type text + can be specified; it is interpreted as a key and the corresponding + value is fetched or stored. For example, + + +CREATE TABLE mytable (h hstore); +INSERT INTO mytable VALUES ('a=>b, c=>d'); +SELECT h['a'] FROM mytable; + h +--- + b +(1 row) + +UPDATE mytable SET h['c'] = 'new'; +SELECT h FROM mytable; + h +---------------------- + "a"=>"b", "c"=>"new" +(1 row) + + + A subscripted fetch returns NULL if the subscript + is NULL or that key does not exist in + the hstore. (Thus, a subscripted fetch is not greatly + different from the -> operator.) + A subscripted update fails if the subscript is NULL; + otherwise, it replaces the value for that key, adding an entry to + the hstore if the key does not already exist. + +
+ + + Indexes + + + hstore has GiST and GIN index support for the @>, + ?, ?& and ?| operators. For example: + + +CREATE INDEX hidx ON testhstore USING GIST (h); + +CREATE INDEX hidx ON testhstore USING GIN (h); + + + + gist_hstore_ops GiST opclass approximates a set of + key/value pairs as a bitmap signature. Its optional integer parameter + siglen determines the + signature length in bytes. The default length is 16 bytes. + Valid values of signature length are between 1 and 2024 bytes. Longer + signatures lead to a more precise search (scanning a smaller fraction of the index and + fewer heap pages), at the cost of a larger index. + + + + Example of creating such an index with a signature length of 32 bytes: + +CREATE INDEX hidx ON testhstore USING GIST (h gist_hstore_ops(siglen=32)); + + + + + hstore also supports btree or hash indexes for + the = operator. This allows hstore columns to be + declared UNIQUE, or to be used in GROUP BY, + ORDER BY or DISTINCT expressions. The sort ordering + for hstore values is not particularly useful, but these indexes + may be useful for equivalence lookups. Create indexes for = + comparisons as follows: + + +CREATE INDEX hidx ON testhstore USING BTREE (h); + +CREATE INDEX hidx ON testhstore USING HASH (h); + + + + + Examples + + + Add a key, or update an existing key with a new value: + +UPDATE tab SET h['c'] = '3'; + + Another way to do the same thing is: + +UPDATE tab SET h = h || hstore('c', '3'); + + If multiple keys are to be added or changed in one operation, + the concatenation approach is more efficient than subscripting: + +UPDATE tab SET h = h || hstore(array['q', 'w'], array['11', '12']); + + + + + Delete a key: + +UPDATE tab SET h = delete(h, 'k1'); + + + + + Convert a record to an hstore: + +CREATE TABLE test (col1 integer, col2 text, col3 text); +INSERT INTO test VALUES (123, 'foo', 'bar'); + +SELECT hstore(t) FROM test AS t; + hstore +--------------------------------------------- + "col1"=>"123", "col2"=>"foo", "col3"=>"bar" +(1 row) + + + + + Convert an hstore to a predefined record type: + +CREATE TABLE test (col1 integer, col2 text, col3 text); + +SELECT * FROM populate_record(null::test, + '"col1"=>"456", "col2"=>"zzz"'); + col1 | col2 | col3 +------+------+------ + 456 | zzz | +(1 row) + + + + + Modify an existing record using the values from an hstore: + +CREATE TABLE test (col1 integer, col2 text, col3 text); +INSERT INTO test VALUES (123, 'foo', 'bar'); + +SELECT (r).* FROM (SELECT t #= '"col3"=>"baz"' AS r FROM test t) s; + col1 | col2 | col3 +------+------+------ + 123 | foo | baz +(1 row) + + + + + + Statistics + + + The hstore type, because of its intrinsic liberality, could + contain a lot of different keys. Checking for valid keys is the task of the + application. The following examples demonstrate several techniques for + checking keys and obtaining statistics. + + + + Simple example: + +SELECT * FROM each('aaa=>bq, b=>NULL, ""=>1'); + + + + + Using a table: + +CREATE TABLE stat AS SELECT (each(h)).key, (each(h)).value FROM testhstore; + + + + + Online statistics: + +SELECT key, count(*) FROM + (SELECT (each(h)).key FROM testhstore) AS stat + GROUP BY key + ORDER BY count DESC, key; + key | count +-----------+------- + line | 883 + query | 207 + pos | 203 + node | 202 + space | 197 + status | 195 + public | 194 + title | 190 + org | 189 +................... + + + + + + Compatibility + + + As of PostgreSQL 9.0, hstore uses a different internal + representation than previous versions. This presents no obstacle for + dump/restore upgrades since the text representation (used in the dump) is + unchanged. + + + + In the event of a binary upgrade, upward compatibility is maintained by + having the new code recognize old-format data. This will entail a slight + performance penalty when processing data that has not yet been modified by + the new code. It is possible to force an upgrade of all values in a table + column by doing an UPDATE statement as follows: + +UPDATE tablename SET hstorecol = hstorecol || ''; + + + + + Another way to do it is: + +ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || ''; + + The ALTER TABLE method requires an + ACCESS EXCLUSIVE lock on the table, + but does not result in bloating the table with old row versions. + + + + + + Transforms + + + Additional extensions are available that implement transforms for + the hstore type for the languages PL/Perl and PL/Python. The + extensions for PL/Perl are called hstore_plperl + and hstore_plperlu, for trusted and untrusted PL/Perl. + If you install these transforms and specify them when creating a + function, hstore values are mapped to Perl hashes. The + extensions for PL/Python are + called hstore_plpythonu, hstore_plpython2u, + and hstore_plpython3u + (see for the PL/Python naming + convention). If you use them, hstore values are mapped to + Python dictionaries. + + + + + It is strongly recommended that the transform extensions be installed in + the same schema as hstore. Otherwise there are + installation-time security hazards if a transform extension's schema + contains objects defined by a hostile user. + + + + + + Authors + + + Oleg Bartunov oleg@sai.msu.su, Moscow, Moscow University, Russia + + + + Teodor Sigaev teodor@sigaev.ru, Moscow, Delta-Soft Ltd., Russia + + + + Additional enhancements by Andrew Gierth andrew@tao11.riddles.org.uk, + United Kingdom + + + +
diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml new file mode 100644 index 000000000000..b2326b72e3cf --- /dev/null +++ b/doc/src/sgml/indexam.sgml @@ -0,0 +1,1485 @@ + + + + Index Access Method Interface Definition + + + Index Access Method + + + indexam + Index Access Method + + + + This chapter defines the interface between the core + PostgreSQL system and index access + methods, which manage individual index types. The core system + knows nothing about indexes beyond what is specified here, so it is + possible to develop entirely new index types by writing add-on code. + + + + All indexes in PostgreSQL are what are known + technically as secondary indexes; that is, the index is + physically separate from the table file that it describes. Each index + is stored as its own physical relation and so is described + by an entry in the pg_class catalog. The contents of an + index are entirely under the control of its index access method. In + practice, all index access methods divide indexes into standard-size + pages so that they can use the regular storage manager and buffer manager + to access the index contents. (All the existing index access methods + furthermore use the standard page layout described in , and most use the same format for index + tuple headers; but these decisions are not forced on an access method.) + + + + An index is effectively a mapping from some data key values to + tuple identifiers, or TIDs, of row versions + (tuples) in the index's parent table. A TID consists of a + block number and an item number within that block (see ). This is sufficient + information to fetch a particular row version from the table. + Indexes are not directly aware that under MVCC, there might be multiple + extant versions of the same logical row; to an index, each tuple is + an independent object that needs its own index entry. Thus, an + update of a row always creates all-new index entries for the row, even if + the key values did not change. (HOT tuples are an exception to this + statement; but indexes do not deal with those, either.) Index entries for + dead tuples are reclaimed (by vacuuming) when the dead tuples themselves + are reclaimed. + + + + Basic API Structure for Indexes + + + Each index access method is described by a row in the + pg_am + system catalog. The pg_am entry + specifies a name and a handler function for the index + access method. These entries can be created and deleted using the + and + SQL commands. + + + + An index access method handler function must be declared to accept a + single argument of type internal and to return the + pseudo-type index_am_handler. The argument is a dummy value that + simply serves to prevent handler functions from being called directly from + SQL commands. The result of the function must be a palloc'd struct of + type IndexAmRoutine, which contains everything + that the core code needs to know to make use of the index access method. + The IndexAmRoutine struct, also called the access + method's API struct, includes fields specifying assorted + fixed properties of the access method, such as whether it can support + multicolumn indexes. More importantly, it contains pointers to support + functions for the access method, which do all of the real work to access + indexes. These support functions are plain C functions and are not + visible or callable at the SQL level. The support functions are described + in . + + + + The structure IndexAmRoutine is defined thus: + +typedef struct IndexAmRoutine +{ + NodeTag type; + + /* + * Total number of strategies (operators) by which we can traverse/search + * this AM. Zero if AM does not have a fixed set of strategy assignments. + */ + uint16 amstrategies; + /* total number of support functions that this AM uses */ + uint16 amsupport; + /* opclass options support function number or 0 */ + uint16 amoptsprocnum; + /* does AM support ORDER BY indexed column's value? */ + bool amcanorder; + /* does AM support ORDER BY result of an operator on indexed column? */ + bool amcanorderbyop; + /* does AM support backward scanning? */ + bool amcanbackward; + /* does AM support UNIQUE indexes? */ + bool amcanunique; + /* does AM support multi-column indexes? */ + bool amcanmulticol; + /* does AM require scans to have a constraint on the first index column? */ + bool amoptionalkey; + /* does AM handle ScalarArrayOpExpr quals? */ + bool amsearcharray; + /* does AM handle IS NULL/IS NOT NULL quals? */ + bool amsearchnulls; + /* can index storage data type differ from column data type? */ + bool amstorage; + /* can an index of this type be clustered on? */ + bool amclusterable; + /* does AM handle predicate locks? */ + bool ampredlocks; + /* does AM support parallel scan? */ + bool amcanparallel; + /* does AM support columns included with clause INCLUDE? */ + bool amcaninclude; + /* does AM use maintenance_work_mem? */ + bool amusemaintenanceworkmem; + /* OR of parallel vacuum flags */ + uint8 amparallelvacuumoptions; + /* type of data stored in index, or InvalidOid if variable */ + Oid amkeytype; + + /* interface functions */ + ambuild_function ambuild; + ambuildempty_function ambuildempty; + aminsert_function aminsert; + ambulkdelete_function ambulkdelete; + amvacuumcleanup_function amvacuumcleanup; + amcanreturn_function amcanreturn; /* can be NULL */ + amcostestimate_function amcostestimate; + amoptions_function amoptions; + amproperty_function amproperty; /* can be NULL */ + ambuildphasename_function ambuildphasename; /* can be NULL */ + amvalidate_function amvalidate; + amadjustmembers_function amadjustmembers; /* can be NULL */ + ambeginscan_function ambeginscan; + amrescan_function amrescan; + amgettuple_function amgettuple; /* can be NULL */ + amgetbitmap_function amgetbitmap; /* can be NULL */ + amendscan_function amendscan; + ammarkpos_function ammarkpos; /* can be NULL */ + amrestrpos_function amrestrpos; /* can be NULL */ + + /* interface functions to support parallel index scans */ + amestimateparallelscan_function amestimateparallelscan; /* can be NULL */ + aminitparallelscan_function aminitparallelscan; /* can be NULL */ + amparallelrescan_function amparallelrescan; /* can be NULL */ +} IndexAmRoutine; + + + + + To be useful, an index access method must also have one or more + operator families and + operator classes defined in + pg_opfamily, + pg_opclass, + pg_amop, and + pg_amproc. + These entries allow the planner + to determine what kinds of query qualifications can be used with + indexes of this access method. Operator families and classes are described + in , which is prerequisite material for reading + this chapter. + + + + An individual index is defined by a + pg_class + entry that describes it as a physical relation, plus a + pg_index + entry that shows the logical content of the index — that is, the set + of index columns it has and the semantics of those columns, as captured by + the associated operator classes. The index columns (key values) can be + either simple columns of the underlying table or expressions over the table + rows. The index access method normally has no interest in where the index + key values come from (it is always handed precomputed key values) but it + will be very interested in the operator class information in + pg_index. Both of these catalog entries can be + accessed as part of the Relation data structure that is + passed to all operations on the index. + + + + Some of the flag fields of IndexAmRoutine have nonobvious + implications. The requirements of amcanunique + are discussed in . + The amcanmulticol flag asserts that the + access method supports multi-key-column indexes, while + amoptionalkey asserts that it allows scans + where no indexable restriction clause is given for the first index column. + When amcanmulticol is false, + amoptionalkey essentially says whether the + access method supports full-index scans without any restriction clause. + Access methods that support multiple index columns must + support scans that omit restrictions on any or all of the columns after + the first; however they are permitted to require some restriction to + appear for the first index column, and this is signaled by setting + amoptionalkey false. + One reason that an index AM might set + amoptionalkey false is if it doesn't index + null values. Since most indexable operators are + strict and hence cannot return true for null inputs, + it is at first sight attractive to not store index entries for null values: + they could never be returned by an index scan anyway. However, this + argument fails when an index scan has no restriction clause for a given + index column. In practice this means that + indexes that have amoptionalkey true must + index nulls, since the planner might decide to use such an index + with no scan keys at all. A related restriction is that an index + access method that supports multiple index columns must + support indexing null values in columns after the first, because the planner + will assume the index can be used for queries that do not restrict + these columns. For example, consider an index on (a,b) and a query with + WHERE a = 4. The system will assume the index can be + used to scan for rows with a = 4, which is wrong if the + index omits rows where b is null. + It is, however, OK to omit rows where the first indexed column is null. + An index access method that does index nulls may also set + amsearchnulls, indicating that it supports + IS NULL and IS NOT NULL clauses as search + conditions. + + + + The amcaninclude flag indicates whether the + access method supports included columns, that is it can + store (without processing) additional columns beyond the key column(s). + The requirements of the preceding paragraph apply only to the key + columns. In particular, the combination + of amcanmulticol=false + and amcaninclude=true is + sensible: it means that there can only be one key column, but there can + also be included column(s). Also, included columns must be allowed to be + null, independently of amoptionalkey. + + + + + + Index Access Method Functions + + + The index construction and maintenance functions that an index access + method must provide in IndexAmRoutine are: + + + + +IndexBuildResult * +ambuild (Relation heapRelation, + Relation indexRelation, + IndexInfo *indexInfo); + + Build a new index. The index relation has been physically created, + but is empty. It must be filled in with whatever fixed data the + access method requires, plus entries for all tuples already existing + in the table. Ordinarily the ambuild function will call + table_index_build_scan() to scan the table for existing tuples + and compute the keys that need to be inserted into the index. + The function must return a palloc'd struct containing statistics about + the new index. + + + + +void +ambuildempty (Relation indexRelation); + + Build an empty index, and write it to the initialization fork (INIT_FORKNUM) + of the given relation. This method is called only for unlogged indexes; the + empty index written to the initialization fork will be copied over the main + relation fork on each server restart. + + + + +bool +aminsert (Relation indexRelation, + Datum *values, + bool *isnull, + ItemPointer heap_tid, + Relation heapRelation, + IndexUniqueCheck checkUnique, + bool indexUnchanged, + IndexInfo *indexInfo); + + Insert a new tuple into an existing index. The values and + isnull arrays give the key values to be indexed, and + heap_tid is the TID to be indexed. + If the access method supports unique indexes (its + amcanunique flag is true) then + checkUnique indicates the type of uniqueness check to + perform. This varies depending on whether the unique constraint is + deferrable; see for details. + Normally the access method only needs the heapRelation + parameter when performing uniqueness checking (since then it will have to + look into the heap to verify tuple liveness). + + + + The indexUnchanged boolean value gives a hint + about the nature of the tuple to be indexed. When it is true, + the tuple is a duplicate of some existing tuple in the index. The + new tuple is a logically unchanged successor MVCC tuple version. This + happens when an UPDATE takes place that does not + modify any columns covered by the index, but nevertheless requires a + new version in the index. The index AM may use this hint to decide + to apply bottom-up index deletion in parts of the index where many + versions of the same logical row accumulate. Note that updating a + non-key column does not affect the value of + indexUnchanged. + + + + The function's Boolean result value is significant only when + checkUnique is UNIQUE_CHECK_PARTIAL. + In this case a true result means the new entry is known unique, whereas + false means it might be non-unique (and a deferred uniqueness check must + be scheduled). For other cases a constant false result is recommended. + + + + Some indexes might not index all tuples. If the tuple is not to be + indexed, aminsert should just return without doing anything. + + + + If the index AM wishes to cache data across successive index insertions + within an SQL statement, it can allocate space + in indexInfo->ii_Context and store a pointer to the + data in indexInfo->ii_AmCache (which will be NULL + initially). + + + + +IndexBulkDeleteResult * +ambulkdelete (IndexVacuumInfo *info, + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); + + Delete tuple(s) from the index. This is a bulk delete operation + that is intended to be implemented by scanning the whole index and checking + each entry to see if it should be deleted. + The passed-in callback function must be called, in the style + callback(TID, callback_state) returns bool, + to determine whether any particular index entry, as identified by its + referenced TID, is to be deleted. Must return either NULL or a palloc'd + struct containing statistics about the effects of the deletion operation. + It is OK to return NULL if no information needs to be passed on to + amvacuumcleanup. + + + + Because of limited maintenance_work_mem, + ambulkdelete might need to be called more than once when many + tuples are to be deleted. The stats argument is the result + of the previous call for this index (it is NULL for the first call within a + VACUUM operation). This allows the AM to accumulate statistics + across the whole operation. Typically, ambulkdelete will + modify and return the same struct if the passed stats is not + null. + + + + +IndexBulkDeleteResult * +amvacuumcleanup (IndexVacuumInfo *info, + IndexBulkDeleteResult *stats); + + Clean up after a VACUUM operation (zero or more + ambulkdelete calls). This does not have to do anything + beyond returning index statistics, but it might perform bulk cleanup + such as reclaiming empty index pages. stats is whatever the + last ambulkdelete call returned, or NULL if + ambulkdelete was not called because no tuples needed to be + deleted. If the result is not NULL it must be a palloc'd struct. + The statistics it contains will be used to update pg_class, + and will be reported by VACUUM if VERBOSE is given. + It is OK to return NULL if the index was not changed at all during the + VACUUM operation, but otherwise correct stats should + be returned. + + + + amvacuumcleanup will also be called at completion of an + ANALYZE operation. In this case stats is always + NULL and any return value will be ignored. This case can be distinguished + by checking info->analyze_only. It is recommended + that the access method do nothing except post-insert cleanup in such a + call, and that only in an autovacuum worker process. + + + + +bool +amcanreturn (Relation indexRelation, int attno); + + Check whether the index can support index-only scans on + the given column, by returning the column's original indexed value. + The attribute number is 1-based, i.e., the first column's attno is 1. + Returns true if supported, else false. + This function should always return true for included columns + (if those are supported), since there's little point in an included + column that can't be retrieved. + If the access method does not support index-only scans at all, + the amcanreturn field in its IndexAmRoutine + struct can be set to NULL. + + + + +void +amcostestimate (PlannerInfo *root, + IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); + + Estimate the costs of an index scan. This function is described fully + in , below. + + + + +bytea * +amoptions (ArrayType *reloptions, + bool validate); + + Parse and validate the reloptions array for an index. This is called only + when a non-null reloptions array exists for the index. + reloptions is a text array containing entries of the + form name=value. + The function should construct a bytea value, which will be copied + into the rd_options field of the index's relcache entry. + The data contents of the bytea value are open for the access + method to define; most of the standard access methods use struct + StdRdOptions. + When validate is true, the function should report a suitable + error message if any of the options are unrecognized or have invalid + values; when validate is false, invalid entries should be + silently ignored. (validate is false when loading options + already stored in pg_catalog; an invalid entry could only + be found if the access method has changed its rules for options, and in + that case ignoring obsolete entries is appropriate.) + It is OK to return NULL if default behavior is wanted. + + + + +bool +amproperty (Oid index_oid, int attno, + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); + + The amproperty method allows index access methods to override + the default behavior of pg_index_column_has_property + and related functions. + If the access method does not have any special behavior for index property + inquiries, the amproperty field in + its IndexAmRoutine struct can be set to NULL. + Otherwise, the amproperty method will be called with + index_oid and attno both zero for + pg_indexam_has_property calls, + or with index_oid valid and attno zero for + pg_index_has_property calls, + or with index_oid valid and attno greater than + zero for pg_index_column_has_property calls. + prop is an enum value identifying the property being tested, + while propname is the original property name string. + If the core code does not recognize the property name + then prop is AMPROP_UNKNOWN. + Access methods can define custom property names by + checking propname for a match (use pg_strcasecmp + to match, for consistency with the core code); for names known to the core + code, it's better to inspect prop. + If the amproperty method returns true then + it has determined the property test result: it must set *res + to the boolean value to return, or set *isnull + to true to return a NULL. (Both of the referenced variables + are initialized to false before the call.) + If the amproperty method returns false then + the core code will proceed with its normal logic for determining the + property test result. + + + + Access methods that support ordering operators should + implement AMPROP_DISTANCE_ORDERABLE property testing, as the + core code does not know how to do that and will return NULL. It may + also be advantageous to implement AMPROP_RETURNABLE testing, + if that can be done more cheaply than by opening the index and calling + amcanreturn, which is the core code's default behavior. + The default behavior should be satisfactory for all other standard + properties. + + + + +char * +ambuildphasename (int64 phasenum); + + Return the textual name of the given build phase number. + The phase numbers are those reported during an index build via the + pgstat_progress_update_param interface. + The phase names are then exposed in the + pg_stat_progress_create_index view. + + + + +bool +amvalidate (Oid opclassoid); + + Validate the catalog entries for the specified operator class, so far as + the access method can reasonably do that. For example, this might include + testing that all required support functions are provided. + The amvalidate function must return false if the opclass is + invalid. Problems should be reported with ereport + messages, typically at INFO level. + + + + +void +amadjustmembers (Oid opfamilyoid, + Oid opclassoid, + List *operators, + List *functions); + + Validate proposed new operator and function members of an operator family, + so far as the access method can reasonably do that, and set their + dependency types if the default is not satisfactory. This is called + during CREATE OPERATOR CLASS and during + ALTER OPERATOR FAMILY ADD; in the latter + case opclassoid is InvalidOid. + The List arguments are lists + of OpFamilyMember structs, as defined + in amapi.h. + + Tests done by this function will typically be a subset of those + performed by amvalidate, + since amadjustmembers cannot assume that it is + seeing a complete set of members. For example, it would be reasonable + to check the signature of a support function, but not to check whether + all required support functions are provided. Any problems can be + reported by throwing an error. + + The dependency-related fields of + the OpFamilyMember structs are initialized by + the core code to create hard dependencies on the opclass if this + is CREATE OPERATOR CLASS, or soft dependencies on the + opfamily if this is ALTER OPERATOR FAMILY ADD. + amadjustmembers can adjust these fields if some other + behavior is more appropriate. For example, GIN, GiST, and SP-GiST + always set operator members to have soft dependencies on the opfamily, + since the connection between an operator and an opclass is relatively + weak in these index types; so it is reasonable to allow operator members + to be added and removed freely. Optional support functions are typically + also given soft dependencies, so that they can be removed if necessary. + + + + + The purpose of an index, of course, is to support scans for tuples matching + an indexable WHERE condition, often called a + qualifier or scan key. The semantics of + index scanning are described more fully in , + below. An index access method can support plain index scans, + bitmap index scans, or both. The scan-related functions that an + index access method must or may provide are: + + + + +IndexScanDesc +ambeginscan (Relation indexRelation, + int nkeys, + int norderbys); + + Prepare for an index scan. The nkeys and norderbys + parameters indicate the number of quals and ordering operators that will be + used in the scan; these may be useful for space allocation purposes. + Note that the actual values of the scan keys aren't provided yet. + The result must be a palloc'd struct. + For implementation reasons the index access method + must create this struct by calling + RelationGetIndexScan(). In most cases + ambeginscan does little beyond making that call and perhaps + acquiring locks; + the interesting parts of index-scan startup are in amrescan. + + + + +void +amrescan (IndexScanDesc scan, + ScanKey keys, + int nkeys, + ScanKey orderbys, + int norderbys); + + Start or restart an index scan, possibly with new scan keys. (To restart + using previously-passed keys, NULL is passed for keys and/or + orderbys.) Note that it is not allowed for + the number of keys or order-by operators to be larger than + what was passed to ambeginscan. In practice the restart + feature is used when a new outer tuple is selected by a nested-loop join + and so a new key comparison value is needed, but the scan key structure + remains the same. + + + + +boolean +amgettuple (IndexScanDesc scan, + ScanDirection direction); + + Fetch the next tuple in the given scan, moving in the given + direction (forward or backward in the index). Returns true if a tuple was + obtained, false if no matching tuples remain. In the true case the tuple + TID is stored into the scan structure. Note that + success means only that the index contains an entry that matches + the scan keys, not that the tuple necessarily still exists in the heap or + will pass the caller's snapshot test. On success, amgettuple + must also set scan->xs_recheck to true or false. + False means it is certain that the index entry matches the scan keys. + True means this is not certain, and the conditions represented by the + scan keys must be rechecked against the heap tuple after fetching it. + This provision supports lossy index operators. + Note that rechecking will extend only to the scan conditions; a partial + index predicate (if any) is never rechecked by amgettuple + callers. + + + + If the index supports index-only + scans (i.e., amcanreturn returns true for any + of its columns), + then on success the AM must also check scan->xs_want_itup, + and if that is true it must return the originally indexed data for the + index entry. Columns for which amcanreturn returns + false can be returned as nulls. + The data can be returned in the form of an + IndexTuple pointer stored at scan->xs_itup, + with tuple descriptor scan->xs_itupdesc; or in the form of + a HeapTuple pointer stored at scan->xs_hitup, + with tuple descriptor scan->xs_hitupdesc. (The latter + format should be used when reconstructing data that might possibly not fit + into an IndexTuple.) In either case, + management of the data referenced by the pointer is the access method's + responsibility. The data must remain good at least until the next + amgettuple, amrescan, or amendscan + call for the scan. + + + + The amgettuple function need only be provided if the access + method supports plain index scans. If it doesn't, the + amgettuple field in its IndexAmRoutine + struct must be set to NULL. + + + + +int64 +amgetbitmap (IndexScanDesc scan, + TIDBitmap *tbm); + + Fetch all tuples in the given scan and add them to the caller-supplied + TIDBitmap (that is, OR the set of tuple IDs into whatever set is already + in the bitmap). The number of tuples fetched is returned (this might be + just an approximate count, for instance some AMs do not detect duplicates). + While inserting tuple IDs into the bitmap, amgetbitmap can + indicate that rechecking of the scan conditions is required for specific + tuple IDs. This is analogous to the xs_recheck output parameter + of amgettuple. Note: in the current implementation, support + for this feature is conflated with support for lossy storage of the bitmap + itself, and therefore callers recheck both the scan conditions and the + partial index predicate (if any) for recheckable tuples. That might not + always be true, however. + amgetbitmap and + amgettuple cannot be used in the same index scan; there + are other restrictions too when using amgetbitmap, as explained + in . + + + + The amgetbitmap function need only be provided if the access + method supports bitmap index scans. If it doesn't, the + amgetbitmap field in its IndexAmRoutine + struct must be set to NULL. + + + + +void +amendscan (IndexScanDesc scan); + + End a scan and release resources. The scan struct itself + should not be freed, but any locks or pins taken internally by the + access method must be released, as well as any other memory allocated + by ambeginscan and other scan-related functions. + + + + +void +ammarkpos (IndexScanDesc scan); + + Mark current scan position. The access method need only support one + remembered scan position per scan. + + + + The ammarkpos function need only be provided if the access + method supports ordered scans. If it doesn't, + the ammarkpos field in its IndexAmRoutine + struct may be set to NULL. + + + + +void +amrestrpos (IndexScanDesc scan); + + Restore the scan to the most recently marked position. + + + + The amrestrpos function need only be provided if the access + method supports ordered scans. If it doesn't, + the amrestrpos field in its IndexAmRoutine + struct may be set to NULL. + + + + In addition to supporting ordinary index scans, some types of index + may wish to support parallel index scans, which allow + multiple backends to cooperate in performing an index scan. The + index access method should arrange things so that each cooperating + process returns a subset of the tuples that would be performed by + an ordinary, non-parallel index scan, but in such a way that the + union of those subsets is equal to the set of tuples that would be + returned by an ordinary, non-parallel index scan. Furthermore, while + there need not be any global ordering of tuples returned by a parallel + scan, the ordering of that subset of tuples returned within each + cooperating backend must match the requested ordering. The following + functions may be implemented to support parallel index scans: + + + + +Size +amestimateparallelscan (void); + + Estimate and return the number of bytes of dynamic shared memory which + the access method will be needed to perform a parallel scan. (This number + is in addition to, not in lieu of, the amount of space needed for + AM-independent data in ParallelIndexScanDescData.) + + + + It is not necessary to implement this function for access methods which + do not support parallel scans or for which the number of additional bytes + of storage required is zero. + + + + +void +aminitparallelscan (void *target); + + This function will be called to initialize dynamic shared memory at the + beginning of a parallel scan. target will point to at least + the number of bytes previously returned by + amestimateparallelscan, and this function may use that + amount of space to store whatever data it wishes. + + + + It is not necessary to implement this function for access methods which + do not support parallel scans or in cases where the shared memory space + required needs no initialization. + + + + +void +amparallelrescan (IndexScanDesc scan); + + This function, if implemented, will be called when a parallel index scan + must be restarted. It should reset any shared state set up by + aminitparallelscan such that the scan will be restarted from + the beginning. + + + + + + Index Scanning + + + In an index scan, the index access method is responsible for regurgitating + the TIDs of all the tuples it has been told about that match the + scan keys. The access method is not involved in + actually fetching those tuples from the index's parent table, nor in + determining whether they pass the scan's visibility test or other + conditions. + + + + A scan key is the internal representation of a WHERE clause of + the form index_key operator + constant, where the index key is one of the columns of the + index and the operator is one of the members of the operator family + associated with that index column. An index scan has zero or more scan + keys, which are implicitly ANDed — the returned tuples are expected + to satisfy all the indicated conditions. + + + + The access method can report that the index is lossy, or + requires rechecks, for a particular query. This implies that the index + scan will return all the entries that pass the scan key, plus possibly + additional entries that do not. The core system's index-scan machinery + will then apply the index conditions again to the heap tuple to verify + whether or not it really should be selected. If the recheck option is not + specified, the index scan must return exactly the set of matching entries. + + + + Note that it is entirely up to the access method to ensure that it + correctly finds all and only the entries passing all the given scan keys. + Also, the core system will simply hand off all the WHERE + clauses that match the index keys and operator families, without any + semantic analysis to determine whether they are redundant or + contradictory. As an example, given + WHERE x > 4 AND x > 14 where x is a b-tree + indexed column, it is left to the b-tree amrescan function + to realize that the first scan key is redundant and can be discarded. + The extent of preprocessing needed during amrescan will + depend on the extent to which the index access method needs to reduce + the scan keys to a normalized form. + + + + Some access methods return index entries in a well-defined order, others + do not. There are actually two different ways that an access method can + support sorted output: + + + + + Access methods that always return entries in the natural ordering + of their data (such as btree) should set + amcanorder to true. + Currently, such access methods must use btree-compatible strategy + numbers for their equality and ordering operators. + + + + + Access methods that support ordering operators should set + amcanorderbyop to true. + This indicates that the index is capable of returning entries in + an order satisfying ORDER BY index_key + operator constant. Scan modifiers + of that form can be passed to amrescan as described + previously. + + + + + + + The amgettuple function has a direction argument, + which can be either ForwardScanDirection (the normal case) + or BackwardScanDirection. If the first call after + amrescan specifies BackwardScanDirection, then the + set of matching index entries is to be scanned back-to-front rather than in + the normal front-to-back direction, so amgettuple must return + the last matching tuple in the index, rather than the first one as it + normally would. (This will only occur for access + methods that set amcanorder to true.) After the + first call, amgettuple must be prepared to advance the scan in + either direction from the most recently returned entry. (But if + amcanbackward is false, all subsequent + calls will have the same direction as the first one.) + + + + Access methods that support ordered scans must support marking a + position in a scan and later returning to the marked position. The same + position might be restored multiple times. However, only one position need + be remembered per scan; a new ammarkpos call overrides the + previously marked position. An access method that does not support ordered + scans need not provide ammarkpos and amrestrpos + functions in IndexAmRoutine; set those pointers to NULL + instead. + + + + Both the scan position and the mark position (if any) must be maintained + consistently in the face of concurrent insertions or deletions in the + index. It is OK if a freshly-inserted entry is not returned by a scan that + would have found the entry if it had existed when the scan started, or for + the scan to return such an entry upon rescanning or backing + up even though it had not been returned the first time through. Similarly, + a concurrent delete might or might not be reflected in the results of a scan. + What is important is that insertions or deletions not cause the scan to + miss or multiply return entries that were not themselves being inserted or + deleted. + + + + If the index stores the original indexed data values (and not some lossy + representation of them), it is useful to + support index-only scans, in + which the index returns the actual data not just the TID of the heap tuple. + This will only avoid I/O if the visibility map shows that the TID is on an + all-visible page; else the heap tuple must be visited anyway to check + MVCC visibility. But that is no concern of the access method's. + + + + Instead of using amgettuple, an index scan can be done with + amgetbitmap to fetch all tuples in one call. This can be + noticeably more efficient than amgettuple because it allows + avoiding lock/unlock cycles within the access method. In principle + amgetbitmap should have the same effects as repeated + amgettuple calls, but we impose several restrictions to + simplify matters. First of all, amgetbitmap returns all + tuples at once and marking or restoring scan positions isn't + supported. Secondly, the tuples are returned in a bitmap which doesn't + have any specific ordering, which is why amgetbitmap doesn't + take a direction argument. (Ordering operators will never be + supplied for such a scan, either.) + Also, there is no provision for index-only scans with + amgetbitmap, since there is no way to return the contents of + index tuples. + Finally, amgetbitmap + does not guarantee any locking of the returned tuples, with implications + spelled out in . + + + + Note that it is permitted for an access method to implement only + amgetbitmap and not amgettuple, or vice versa, + if its internal implementation is unsuited to one API or the other. + + + + + + Index Locking Considerations + + + Index access methods must handle concurrent updates + of the index by multiple processes. + The core PostgreSQL system obtains + AccessShareLock on the index during an index scan, and + RowExclusiveLock when updating the index (including plain + VACUUM). Since these lock types do not conflict, the access + method is responsible for handling any fine-grained locking it might need. + An ACCESS EXCLUSIVE lock on the index as a whole will be + taken only during index creation, destruction, or REINDEX + (SHARE UPDATE EXCLUSIVE is taken instead with + CONCURRENTLY). + + + + Building an index type that supports concurrent updates usually requires + extensive and subtle analysis of the required behavior. For the b-tree + and hash index types, you can read about the design decisions involved in + src/backend/access/nbtree/README and + src/backend/access/hash/README. + + + + Aside from the index's own internal consistency requirements, concurrent + updates create issues about consistency between the parent table (the + heap) and the index. Because + PostgreSQL separates accesses + and updates of the heap from those of the index, there are windows in + which the index might be inconsistent with the heap. We handle this problem + with the following rules: + + + + + A new heap entry is made before making its index entries. (Therefore + a concurrent index scan is likely to fail to see the heap entry. + This is okay because the index reader would be uninterested in an + uncommitted row anyway. But see .) + + + + + When a heap entry is to be deleted (by VACUUM), all its + index entries must be removed first. + + + + + An index scan must maintain a pin + on the index page holding the item last returned by + amgettuple, and ambulkdelete cannot delete + entries from pages that are pinned by other backends. The need + for this rule is explained below. + + + + + Without the third rule, it is possible for an index reader to + see an index entry just before it is removed by VACUUM, and + then to arrive at the corresponding heap entry after that was removed by + VACUUM. + This creates no serious problems if that item + number is still unused when the reader reaches it, since an empty + item slot will be ignored by heap_fetch(). But what if a + third backend has already re-used the item slot for something else? + When using an MVCC-compliant snapshot, there is no problem because + the new occupant of the slot is certain to be too new to pass the + snapshot test. However, with a non-MVCC-compliant snapshot (such as + SnapshotAny), it would be possible to accept and return + a row that does not in fact match the scan keys. We could defend + against this scenario by requiring the scan keys to be rechecked + against the heap row in all cases, but that is too expensive. Instead, + we use a pin on an index page as a proxy to indicate that the reader + might still be in flight from the index entry to the matching + heap entry. Making ambulkdelete block on such a pin ensures + that VACUUM cannot delete the heap entry before the reader + is done with it. This solution costs little in run time, and adds blocking + overhead only in the rare cases where there actually is a conflict. + + + + This solution requires that index scans be synchronous: we have + to fetch each heap tuple immediately after scanning the corresponding index + entry. This is expensive for a number of reasons. An + asynchronous scan in which we collect many TIDs from the index, + and only visit the heap tuples sometime later, requires much less index + locking overhead and can allow a more efficient heap access pattern. + Per the above analysis, we must use the synchronous approach for + non-MVCC-compliant snapshots, but an asynchronous scan is workable + for a query using an MVCC snapshot. + + + + In an amgetbitmap index scan, the access method does not + keep an index pin on any of the returned tuples. Therefore + it is only safe to use such scans with MVCC-compliant snapshots. + + + + When the ampredlocks flag is not set, any scan using that + index access method within a serializable transaction will acquire a + nonblocking predicate lock on the full index. This will generate a + read-write conflict with the insert of any tuple into that index by a + concurrent serializable transaction. If certain patterns of read-write + conflicts are detected among a set of concurrent serializable + transactions, one of those transactions may be canceled to protect data + integrity. When the flag is set, it indicates that the index access + method implements finer-grained predicate locking, which will tend to + reduce the frequency of such transaction cancellations. + + + + + + Index Uniqueness Checks + + + PostgreSQL enforces SQL uniqueness constraints + using unique indexes, which are indexes that disallow + multiple entries with identical keys. An access method that supports this + feature sets amcanunique true. + (At present, only b-tree supports it.) Columns listed in the + INCLUDE clause are not considered when enforcing + uniqueness. + + + + Because of MVCC, it is always necessary to allow duplicate entries to + exist physically in an index: the entries might refer to successive + versions of a single logical row. The behavior we actually want to + enforce is that no MVCC snapshot could include two rows with equal + index keys. This breaks down into the following cases that must be + checked when inserting a new row into a unique index: + + + + + If a conflicting valid row has been deleted by the current transaction, + it's okay. (In particular, since an UPDATE always deletes the old row + version before inserting the new version, this will allow an UPDATE on + a row without changing the key.) + + + + + If a conflicting row has been inserted by an as-yet-uncommitted + transaction, the would-be inserter must wait to see if that transaction + commits. If it rolls back then there is no conflict. If it commits + without deleting the conflicting row again, there is a uniqueness + violation. (In practice we just wait for the other transaction to + end and then redo the visibility check in toto.) + + + + + Similarly, if a conflicting valid row has been deleted by an + as-yet-uncommitted transaction, the would-be inserter must wait + for that transaction to commit or abort, and then repeat the test. + + + + + + + Furthermore, immediately before reporting a uniqueness violation + according to the above rules, the access method must recheck the + liveness of the row being inserted. If it is committed dead then + no violation should be reported. (This case cannot occur during the + ordinary scenario of inserting a row that's just been created by + the current transaction. It can happen during + CREATE UNIQUE INDEX CONCURRENTLY, however.) + + + + We require the index access method to apply these tests itself, which + means that it must reach into the heap to check the commit status of + any row that is shown to have a duplicate key according to the index + contents. This is without a doubt ugly and non-modular, but it saves + redundant work: if we did a separate probe then the index lookup for + a conflicting row would be essentially repeated while finding the place to + insert the new row's index entry. What's more, there is no obvious way + to avoid race conditions unless the conflict check is an integral part + of insertion of the new index entry. + + + + If the unique constraint is deferrable, there is additional complexity: + we need to be able to insert an index entry for a new row, but defer any + uniqueness-violation error until end of statement or even later. To + avoid unnecessary repeat searches of the index, the index access method + should do a preliminary uniqueness check during the initial insertion. + If this shows that there is definitely no conflicting live tuple, we + are done. Otherwise, we schedule a recheck to occur when it is time to + enforce the constraint. If, at the time of the recheck, both the inserted + tuple and some other tuple with the same key are live, then the error + must be reported. (Note that for this purpose, live actually + means any tuple in the index entry's HOT chain is live.) + To implement this, the aminsert function is passed a + checkUnique parameter having one of the following values: + + + + + UNIQUE_CHECK_NO indicates that no uniqueness checking + should be done (this is not a unique index). + + + + + UNIQUE_CHECK_YES indicates that this is a non-deferrable + unique index, and the uniqueness check must be done immediately, as + described above. + + + + + UNIQUE_CHECK_PARTIAL indicates that the unique + constraint is deferrable. PostgreSQL + will use this mode to insert each row's index entry. The access + method must allow duplicate entries into the index, and report any + potential duplicates by returning false from aminsert. + For each row for which false is returned, a deferred recheck will + be scheduled. + + + + The access method must identify any rows which might violate the + unique constraint, but it is not an error for it to report false + positives. This allows the check to be done without waiting for other + transactions to finish; conflicts reported here are not treated as + errors and will be rechecked later, by which time they may no longer + be conflicts. + + + + + UNIQUE_CHECK_EXISTING indicates that this is a deferred + recheck of a row that was reported as a potential uniqueness violation. + Although this is implemented by calling aminsert, the + access method must not insert a new index entry in this + case. The index entry is already present. Rather, the access method + must check to see if there is another live index entry. If so, and + if the target row is also still live, report error. + + + + It is recommended that in a UNIQUE_CHECK_EXISTING call, + the access method further verify that the target row actually does + have an existing entry in the index, and report error if not. This + is a good idea because the index tuple values passed to + aminsert will have been recomputed. If the index + definition involves functions that are not really immutable, we + might be checking the wrong area of the index. Checking that the + target row is found in the recheck verifies that we are scanning + for the same tuple values as were used in the original insertion. + + + + + + + + + Index Cost Estimation Functions + + + The amcostestimate function is given information describing + a possible index scan, including lists of WHERE and ORDER BY clauses that + have been determined to be usable with the index. It must return estimates + of the cost of accessing the index and the selectivity of the WHERE + clauses (that is, the fraction of parent-table rows that will be + retrieved during the index scan). For simple cases, nearly all the + work of the cost estimator can be done by calling standard routines + in the optimizer; the point of having an amcostestimate function is + to allow index access methods to provide index-type-specific knowledge, + in case it is possible to improve on the standard estimates. + + + + Each amcostestimate function must have the signature: + + +void +amcostestimate (PlannerInfo *root, + IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); + + + The first three parameters are inputs: + + + + root + + + The planner's information about the query being processed. + + + + + + path + + + The index access path being considered. All fields except cost and + selectivity values are valid. + + + + + + loop_count + + + The number of repetitions of the index scan that should be factored + into the cost estimates. This will typically be greater than one when + considering a parameterized scan for use in the inside of a nestloop + join. Note that the cost estimates should still be for just one scan; + a larger loop_count means that it may be appropriate + to allow for some caching effects across multiple scans. + + + + + + + + The last five parameters are pass-by-reference outputs: + + + + *indexStartupCost + + + Set to cost of index start-up processing + + + + + + *indexTotalCost + + + Set to total cost of index processing + + + + + + *indexSelectivity + + + Set to index selectivity + + + + + + *indexCorrelation + + + Set to correlation coefficient between index scan order and + underlying table's order + + + + + + *indexPages + + + Set to number of index leaf pages + + + + + + + + Note that cost estimate functions must be written in C, not in SQL or + any available procedural language, because they must access internal + data structures of the planner/optimizer. + + + + The index access costs should be computed using the parameters used by + src/backend/optimizer/path/costsize.c: a sequential + disk block fetch has cost seq_page_cost, a nonsequential fetch + has cost random_page_cost, and the cost of processing one index + row should usually be taken as cpu_index_tuple_cost. In + addition, an appropriate multiple of cpu_operator_cost should + be charged for any comparison operators invoked during index processing + (especially evaluation of the indexquals themselves). + + + + The access costs should include all disk and CPU costs associated with + scanning the index itself, but not the costs of retrieving or + processing the parent-table rows that are identified by the index. + + + + The start-up cost is the part of the total scan cost that + must be expended before we can begin to fetch the first row. For most + indexes this can be taken as zero, but an index type with a high start-up + cost might want to set it nonzero. + + + + The indexSelectivity should be set to the estimated fraction of the parent + table rows that will be retrieved during the index scan. In the case + of a lossy query, this will typically be higher than the fraction of + rows that actually pass the given qual conditions. + + + + The indexCorrelation should be set to the correlation (ranging between + -1.0 and 1.0) between the index order and the table order. This is used + to adjust the estimate for the cost of fetching rows from the parent + table. + + + + The indexPages should be set to the number of leaf pages. + This is used to estimate the number of workers for parallel index scan. + + + + When loop_count is greater than one, the returned numbers + should be averages expected for any one scan of the index. + + + + Cost Estimation + + A typical cost estimator will proceed as follows: + + + + + Estimate and return the fraction of parent-table rows that will be visited + based on the given qual conditions. In the absence of any index-type-specific + knowledge, use the standard optimizer function clauselist_selectivity(): + + +*indexSelectivity = clauselist_selectivity(root, path->indexquals, + path->indexinfo->rel->relid, + JOIN_INNER, NULL); + + + + + + + Estimate the number of index rows that will be visited during the + scan. For many index types this is the same as indexSelectivity times + the number of rows in the index, but it might be more. (Note that the + index's size in pages and rows is available from the + path->indexinfo struct.) + + + + + + Estimate the number of index pages that will be retrieved during the scan. + This might be just indexSelectivity times the index's size in pages. + + + + + + Compute the index access cost. A generic estimator might do this: + + +/* + * Our generic assumption is that the index pages will be read + * sequentially, so they cost seq_page_cost each, not random_page_cost. + * Also, we charge for evaluation of the indexquals at each index row. + * All the costs are assumed to be paid incrementally during the scan. + */ +cost_qual_eval(&index_qual_cost, path->indexquals, root); +*indexStartupCost = index_qual_cost.startup; +*indexTotalCost = seq_page_cost * numIndexPages + + (cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples; + + + However, the above does not account for amortization of index reads + across repeated index scans. + + + + + + Estimate the index correlation. For a simple ordered index on a single + field, this can be retrieved from pg_statistic. If the correlation + is not known, the conservative estimate is zero (no correlation). + + + + + + Examples of cost estimator functions can be found in + src/backend/utils/adt/selfuncs.c. + + + diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml new file mode 100644 index 000000000000..56fbd4517836 --- /dev/null +++ b/doc/src/sgml/indices.sgml @@ -0,0 +1,1600 @@ + + + + Indexes + + + index + + + + Indexes are a common way to enhance database performance. An index + allows the database server to find and retrieve specific rows much + faster than it could do without an index. But indexes also add + overhead to the database system as a whole, so they should be used + sensibly. + + + + + Introduction + + + Suppose we have a table similar to this: + +CREATE TABLE test1 ( + id integer, + content varchar +); + + and the application issues many queries of the form: + +SELECT content FROM test1 WHERE id = constant; + + With no advance preparation, the system would have to scan the entire + test1 table, row by row, to find all + matching entries. If there are many rows in + test1 and only a few rows (perhaps zero + or one) that would be returned by such a query, this is clearly an + inefficient method. But if the system has been instructed to maintain an + index on the id column, it can use a more + efficient method for locating matching rows. For instance, it + might only have to walk a few levels deep into a search tree. + + + + A similar approach is used in most non-fiction books: terms and + concepts that are frequently looked up by readers are collected in + an alphabetic index at the end of the book. The interested reader + can scan the index relatively quickly and flip to the appropriate + page(s), rather than having to read the entire book to find the + material of interest. Just as it is the task of the author to + anticipate the items that readers are likely to look up, + it is the task of the database programmer to foresee which indexes + will be useful. + + + + The following command can be used to create an index on the + id column, as discussed: + +CREATE INDEX test1_id_index ON test1 (id); + + The name test1_id_index can be chosen + freely, but you should pick something that enables you to remember + later what the index was for. + + + + To remove an index, use the DROP INDEX command. + Indexes can be added to and removed from tables at any time. + + + + Once an index is created, no further intervention is required: the + system will update the index when the table is modified, and it will + use the index in queries when it thinks doing so would be more efficient + than a sequential table scan. But you might have to run the + ANALYZE command regularly to update + statistics to allow the query planner to make educated decisions. + See for information about + how to find out whether an index is used and when and why the + planner might choose not to use an index. + + + + Indexes can also benefit UPDATE and + DELETE commands with search conditions. + Indexes can moreover be used in join searches. Thus, + an index defined on a column that is part of a join condition can + also significantly speed up queries with joins. + + + + Creating an index on a large table can take a long time. By default, + PostgreSQL allows reads (SELECT statements) to occur + on the table in parallel with index creation, but writes (INSERT, + UPDATE, DELETE) are blocked until the index build is finished. + In production environments this is often unacceptable. + It is possible to allow writes to occur in parallel with index + creation, but there are several caveats to be aware of — + for more information see . + + + + After an index is created, the system has to keep it synchronized with the + table. This adds overhead to data manipulation operations. + Therefore indexes that are seldom or never used in queries + should be removed. + + + + + + Index Types + + + PostgreSQL provides several index types: + B-tree, Hash, GiST, SP-GiST, GIN and BRIN. + Each index type uses a different + algorithm that is best suited to different types of queries. + By default, the CREATE + INDEX command creates + B-tree indexes, which fit the most common situations. + The other index types are selected by writing the keyword + USING followed by the index type name. + For example, to create a Hash index: + +CREATE INDEX name ON table USING HASH (column); + + + + + B-Tree + + + index + B-Tree + + + B-Tree + index + + + + B-trees can handle equality and range queries on data that can be sorted + into some ordering. + In particular, the PostgreSQL query planner + will consider using a B-tree index whenever an indexed column is + involved in a comparison using one of these operators: + + +<   <=   =   >=   > + + + Constructs equivalent to combinations of these operators, such as + BETWEEN and IN, can also be implemented with + a B-tree index search. Also, an IS NULL or IS NOT + NULL condition on an index column can be used with a B-tree index. + + + + The optimizer can also use a B-tree index for queries involving the + pattern matching operators LIKE and ~ + if the pattern is a constant and is anchored to + the beginning of the string — for example, col LIKE + 'foo%' or col ~ '^foo', but not + col LIKE '%bar'. However, if your database does not + use the C locale you will need to create the index with a special + operator class to support indexing of pattern-matching queries; see + below. It is also possible to use + B-tree indexes for ILIKE and + ~*, but only if the pattern starts with + non-alphabetic characters, i.e., characters that are not affected by + upper/lower case conversion. + + + + B-tree indexes can also be used to retrieve data in sorted order. + This is not always faster than a simple scan and sort, but it is + often helpful. + + + + + Hash + + + index + hash + + + hash + index + + + + Hash indexes store a 32-bit hash code derived from the + value of the indexed column. Hence, + such indexes can only handle simple equality comparisons. + The query planner will consider using a hash index whenever an + indexed column is involved in a comparison using the + equal operator: + + += + + + + + + GiST + + + index + GiST + + + GiST + index + + + + GiST indexes are not a single kind of index, but rather an infrastructure + within which many different indexing strategies can be implemented. + Accordingly, the particular operators with which a GiST index can be + used vary depending on the indexing strategy (the operator + class). As an example, the standard distribution of + PostgreSQL includes GiST operator classes + for several two-dimensional geometric data types, which support indexed + queries using these operators: + + +<<   &<   &>   >>   <<|   &<|   |&>   |>>   @>   <@   ~=   && + + + (See for the meaning of + these operators.) + The GiST operator classes included in the standard distribution are + documented in . + Many other GiST operator + classes are available in the contrib collection or as separate + projects. For more information see . + + + + GiST indexes are also capable of optimizing nearest-neighbor + searches, such as + point '(101,456)' LIMIT 10; +]]> + + which finds the ten places closest to a given target point. The ability + to do this is again dependent on the particular operator class being used. + In , operators that can be + used in this way are listed in the column Ordering Operators. + + + + + SP-GiST + + + index + SP-GiST + + + SP-GiST + index + + + + SP-GiST indexes, like GiST indexes, offer an infrastructure that supports + various kinds of searches. SP-GiST permits implementation of a wide range + of different non-balanced disk-based data structures, such as quadtrees, + k-d trees, and radix trees (tries). As an example, the standard distribution of + PostgreSQL includes SP-GiST operator classes + for two-dimensional points, which support indexed + queries using these operators: + + +<<   >>   ~=   <@   <<|   |>> + + + (See for the meaning of + these operators.) + The SP-GiST operator classes included in the standard distribution are + documented in . + For more information see . + + + + Like GiST, SP-GiST supports nearest-neighbor searches. + For SP-GiST operator classes that support distance ordering, the + corresponding operator is listed in the Ordering Operators + column in . + + + + + GIN + + + index + GIN + + + GIN + index + + + + GIN indexes are inverted indexes which are appropriate for + data values that contain multiple component values, such as arrays. An + inverted index contains a separate entry for each component value, and + can efficiently handle queries that test for the presence of specific + component values. + + + + Like GiST and SP-GiST, GIN can support + many different user-defined indexing strategies, and the particular + operators with which a GIN index can be used vary depending on the + indexing strategy. + As an example, the standard distribution of + PostgreSQL includes a GIN operator class + for arrays, which supports indexed queries using these operators: + + +<@   @>   =   && + + + (See for the meaning of + these operators.) + The GIN operator classes included in the standard distribution are + documented in . + Many other GIN operator + classes are available in the contrib collection or as separate + projects. For more information see . + + + + + BRIN + + + index + BRIN + + + BRIN + index + + + + BRIN indexes (a shorthand for Block Range INdexes) store summaries about + the values stored in consecutive physical block ranges of a table. + Thus, they are most effective for columns whose values are well-correlated + with the physical order of the table rows. + Like GiST, SP-GiST and GIN, + BRIN can support many different indexing strategies, + and the particular operators with which a BRIN index can be used + vary depending on the indexing strategy. + For data types that have a linear sort order, the indexed data + corresponds to the minimum and maximum values of the + values in the column for each block range. This supports indexed queries + using these operators: + + +<   <=   =   >=   > + + + The BRIN operator classes included in the standard distribution are + documented in . + For more information see . + + + + + + + Multicolumn Indexes + + + index + multicolumn + + + + An index can be defined on more than one column of a table. For example, if + you have a table of this form: + +CREATE TABLE test2 ( + major int, + minor int, + name varchar +); + + (say, you keep your /dev + directory in a database...) and you frequently issue queries like: + +SELECT name FROM test2 WHERE major = constant AND minor = constant; + + then it might be appropriate to define an index on the columns + major and + minor together, e.g.: + +CREATE INDEX test2_mm_idx ON test2 (major, minor); + + + + + Currently, only the B-tree, GiST, GIN, and BRIN index types support + multiple-key-column indexes. Whether there can be multiple key + columns is independent of whether INCLUDE columns + can be added to the index. Indexes can have up to 32 columns, + including INCLUDE columns. (This limit can be + altered when building PostgreSQL; see the + file pg_config_manual.h.) + + + + A multicolumn B-tree index can be used with query conditions that + involve any subset of the index's columns, but the index is most + efficient when there are constraints on the leading (leftmost) columns. + The exact rule is that equality constraints on leading columns, plus + any inequality constraints on the first column that does not have an + equality constraint, will be used to limit the portion of the index + that is scanned. Constraints on columns to the right of these columns + are checked in the index, so they save visits to the table proper, but + they do not reduce the portion of the index that has to be scanned. + For example, given an index on (a, b, c) and a + query condition WHERE a = 5 AND b >= 42 AND c < 77, + the index would have to be scanned from the first entry with + a = 5 and b = 42 up through the last entry with + a = 5. Index entries with c >= 77 would be + skipped, but they'd still have to be scanned through. + This index could in principle be used for queries that have constraints + on b and/or c with no constraint on a + — but the entire index would have to be scanned, so in most cases + the planner would prefer a sequential table scan over using the index. + + + + A multicolumn GiST index can be used with query conditions that + involve any subset of the index's columns. Conditions on additional + columns restrict the entries returned by the index, but the condition on + the first column is the most important one for determining how much of + the index needs to be scanned. A GiST index will be relatively + ineffective if its first column has only a few distinct values, even if + there are many distinct values in additional columns. + + + + A multicolumn GIN index can be used with query conditions that + involve any subset of the index's columns. Unlike B-tree or GiST, + index search effectiveness is the same regardless of which index column(s) + the query conditions use. + + + + A multicolumn BRIN index can be used with query conditions that + involve any subset of the index's columns. Like GIN and unlike B-tree or + GiST, index search effectiveness is the same regardless of which index + column(s) the query conditions use. The only reason to have multiple BRIN + indexes instead of one multicolumn BRIN index on a single table is to have + a different pages_per_range storage parameter. + + + + Of course, each column must be used with operators appropriate to the index + type; clauses that involve other operators will not be considered. + + + + Multicolumn indexes should be used sparingly. In most situations, + an index on a single column is sufficient and saves space and time. + Indexes with more than three columns are unlikely to be helpful + unless the usage of the table is extremely stylized. See also + and + for some discussion of the + merits of different index configurations. + + + + + + Indexes and <literal>ORDER BY</literal> + + + index + and ORDER BY + + + + In addition to simply finding the rows to be returned by a query, + an index may be able to deliver them in a specific sorted order. + This allows a query's ORDER BY specification to be honored + without a separate sorting step. Of the index types currently + supported by PostgreSQL, only B-tree + can produce sorted output — the other index types return + matching rows in an unspecified, implementation-dependent order. + + + + The planner will consider satisfying an ORDER BY specification + either by scanning an available index that matches the specification, + or by scanning the table in physical order and doing an explicit + sort. For a query that requires scanning a large fraction of the + table, an explicit sort is likely to be faster than using an index + because it requires + less disk I/O due to following a sequential access pattern. Indexes are + more useful when only a few rows need be fetched. An important + special case is ORDER BY in combination with + LIMIT n: an explicit sort will have to process + all the data to identify the first n rows, but if there is + an index matching the ORDER BY, the first n + rows can be retrieved directly, without scanning the remainder at all. + + + + By default, B-tree indexes store their entries in ascending order + with nulls last (table TID is treated as a tiebreaker column among + otherwise equal entries). This means that a forward scan of an + index on column x produces output satisfying ORDER BY x + (or more verbosely, ORDER BY x ASC NULLS LAST). The + index can also be scanned backward, producing output satisfying + ORDER BY x DESC + (or more verbosely, ORDER BY x DESC NULLS FIRST, since + NULLS FIRST is the default for ORDER BY DESC). + + + + You can adjust the ordering of a B-tree index by including the + options ASC, DESC, NULLS FIRST, + and/or NULLS LAST when creating the index; for example: + +CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST); +CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); + + An index stored in ascending order with nulls first can satisfy + either ORDER BY x ASC NULLS FIRST or + ORDER BY x DESC NULLS LAST depending on which direction + it is scanned in. + + + + You might wonder why bother providing all four options, when two + options together with the possibility of backward scan would cover + all the variants of ORDER BY. In single-column indexes + the options are indeed redundant, but in multicolumn indexes they can be + useful. Consider a two-column index on (x, y): this can + satisfy ORDER BY x, y if we scan forward, or + ORDER BY x DESC, y DESC if we scan backward. + But it might be that the application frequently needs to use + ORDER BY x ASC, y DESC. There is no way to get that + ordering from a plain index, but it is possible if the index is defined + as (x ASC, y DESC) or (x DESC, y ASC). + + + + Obviously, indexes with non-default sort orderings are a fairly + specialized feature, but sometimes they can produce tremendous + speedups for certain queries. Whether it's worth maintaining such an + index depends on how often you use queries that require a special + sort ordering. + + + + + + Combining Multiple Indexes + + + index + combining multiple indexes + + + + bitmap scan + + + + A single index scan can only use query clauses that use the index's + columns with operators of its operator class and are joined with + AND. For example, given an index on (a, b) + a query condition like WHERE a = 5 AND b = 6 could + use the index, but a query like WHERE a = 5 OR b = 6 could not + directly use the index. + + + + Fortunately, + PostgreSQL has the ability to combine multiple indexes + (including multiple uses of the same index) to handle cases that cannot + be implemented by single index scans. The system can form AND + and OR conditions across several index scans. For example, + a query like WHERE x = 42 OR x = 47 OR x = 53 OR x = 99 + could be broken down into four separate scans of an index on x, + each scan using one of the query clauses. The results of these scans are + then ORed together to produce the result. Another example is that if we + have separate indexes on x and y, one possible + implementation of a query like WHERE x = 5 AND y = 6 is to + use each index with the appropriate query clause and then AND together + the index results to identify the result rows. + + + + To combine multiple indexes, the system scans each needed index and + prepares a bitmap in memory giving the locations of + table rows that are reported as matching that index's conditions. + The bitmaps are then ANDed and ORed together as needed by the query. + Finally, the actual table rows are visited and returned. The table rows + are visited in physical order, because that is how the bitmap is laid + out; this means that any ordering of the original indexes is lost, and + so a separate sort step will be needed if the query has an ORDER + BY clause. For this reason, and because each additional index scan + adds extra time, the planner will sometimes choose to use a simple index + scan even though additional indexes are available that could have been + used as well. + + + + In all but the simplest applications, there are various combinations of + indexes that might be useful, and the database developer must make + trade-offs to decide which indexes to provide. Sometimes multicolumn + indexes are best, but sometimes it's better to create separate indexes + and rely on the index-combination feature. For example, if your + workload includes a mix of queries that sometimes involve only column + x, sometimes only column y, and sometimes both + columns, you might choose to create two separate indexes on + x and y, relying on index combination to + process the queries that use both columns. You could also create a + multicolumn index on (x, y). This index would typically be + more efficient than index combination for queries involving both + columns, but as discussed in , it + would be almost useless for queries involving only y, so it + should not be the only index. A combination of the multicolumn index + and a separate index on y would serve reasonably well. For + queries involving only x, the multicolumn index could be + used, though it would be larger and hence slower than an index on + x alone. The last alternative is to create all three + indexes, but this is probably only reasonable if the table is searched + much more often than it is updated and all three types of query are + common. If one of the types of query is much less common than the + others, you'd probably settle for creating just the two indexes that + best match the common types. + + + + + + + Unique Indexes + + + index + unique + + + + Indexes can also be used to enforce uniqueness of a column's value, + or the uniqueness of the combined values of more than one column. + +CREATE UNIQUE INDEX name ON table (column , ...); + + Currently, only B-tree indexes can be declared unique. + + + + When an index is declared unique, multiple table rows with equal + indexed values are not allowed. Null values are not considered + equal. A multicolumn unique index will only reject cases where all + indexed columns are equal in multiple rows. + + + + PostgreSQL automatically creates a unique + index when a unique constraint or primary key is defined for a table. + The index covers the columns that make up the primary key or unique + constraint (a multicolumn index, if appropriate), and is the mechanism + that enforces the constraint. + + + + + There's no need to manually + create indexes on unique columns; doing so would just duplicate + the automatically-created index. + + + + + + + Indexes on Expressions + + + index + on expressions + + + + An index column need not be just a column of the underlying table, + but can be a function or scalar expression computed from one or + more columns of the table. This feature is useful to obtain fast + access to tables based on the results of computations. + + + + For example, a common way to do case-insensitive comparisons is to + use the lower function: + +SELECT * FROM test1 WHERE lower(col1) = 'value'; + + This query can use an index if one has been + defined on the result of the lower(col1) + function: + +CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1)); + + + + + If we were to declare this index UNIQUE, it would prevent + creation of rows whose col1 values differ only in case, + as well as rows whose col1 values are actually identical. + Thus, indexes on expressions can be used to enforce constraints that + are not definable as simple unique constraints. + + + + As another example, if one often does queries like: + +SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith'; + + then it might be worth creating an index like this: + +CREATE INDEX people_names ON people ((first_name || ' ' || last_name)); + + + + + The syntax of the CREATE INDEX command normally requires + writing parentheses around index expressions, as shown in the second + example. The parentheses can be omitted when the expression is just + a function call, as in the first example. + + + + Index expressions are relatively expensive to maintain, because the + derived expression(s) must be computed for each row upon insertion + and whenever it is updated. However, the index expressions are + not recomputed during an indexed search, since they are + already stored in the index. In both examples above, the system + sees the query as just WHERE indexedcolumn = 'constant' + and so the speed of the search is equivalent to any other simple index + query. Thus, indexes on expressions are useful when retrieval speed + is more important than insertion and update speed. + + + + + + Partial Indexes + + + index + partial + + + + A partial index is an index built over a + subset of a table; the subset is defined by a conditional + expression (called the predicate of the + partial index). The index contains entries only for those table + rows that satisfy the predicate. Partial indexes are a specialized + feature, but there are several situations in which they are useful. + + + + One major reason for using a partial index is to avoid indexing common + values. Since a query searching for a common value (one that + accounts for more than a few percent of all the table rows) will not + use the index anyway, there is no point in keeping those rows in the + index at all. This reduces the size of the index, which will speed + up those queries that do use the index. It will also speed up many table + update operations because the index does not need to be + updated in all cases. shows a + possible application of this idea. + + + + Setting up a Partial Index to Exclude Common Values + + + Suppose you are storing web server access logs in a database. + Most accesses originate from the IP address range of your organization but + some are from elsewhere (say, employees on dial-up connections). + If your searches by IP are primarily for outside accesses, + you probably do not need to index the IP range that corresponds to your + organization's subnet. + + + + Assume a table like this: + +CREATE TABLE access_log ( + url varchar, + client_ip inet, + ... +); + + + + + To create a partial index that suits our example, use a command + such as this: + +CREATE INDEX access_log_client_ip_ix ON access_log (client_ip) +WHERE NOT (client_ip > inet '192.168.100.0' AND + client_ip < inet '192.168.100.255'); + + + + + A typical query that can use this index would be: + +SELECT * +FROM access_log +WHERE url = '/index.html' AND client_ip = inet '212.78.10.32'; + + Here the query's IP address is covered by the partial index. The + following query cannot use the partial index, as it uses an IP address + that is excluded from the index: + +SELECT * +FROM access_log +WHERE url = '/index.html' AND client_ip = inet '192.168.100.23'; + + + + + Observe that this kind of partial index requires that the common + values be predetermined, so such partial indexes are best used for + data distributions that do not change. Such indexes can be recreated + occasionally to adjust for new data distributions, but this adds + maintenance effort. + + + + + Another possible use for a partial index is to exclude values from the + index that the + typical query workload is not interested in; this is shown in . This results in the same + advantages as listed above, but it prevents the + uninteresting values from being accessed via that + index, even if an index scan might be profitable in that + case. Obviously, setting up partial indexes for this kind of + scenario will require a lot of care and experimentation. + + + + Setting up a Partial Index to Exclude Uninteresting Values + + + If you have a table that contains both billed and unbilled orders, + where the unbilled orders take up a small fraction of the total + table and yet those are the most-accessed rows, you can improve + performance by creating an index on just the unbilled rows. The + command to create the index would look like this: + +CREATE INDEX orders_unbilled_index ON orders (order_nr) + WHERE billed is not true; + + + + + A possible query to use this index would be: + +SELECT * FROM orders WHERE billed is not true AND order_nr < 10000; + + However, the index can also be used in queries that do not involve + order_nr at all, e.g.: + +SELECT * FROM orders WHERE billed is not true AND amount > 5000.00; + + This is not as efficient as a partial index on the + amount column would be, since the system has to + scan the entire index. Yet, if there are relatively few unbilled + orders, using this partial index just to find the unbilled orders + could be a win. + + + + Note that this query cannot use this index: + +SELECT * FROM orders WHERE order_nr = 3501; + + The order 3501 might be among the billed or unbilled + orders. + + + + + also illustrates that the + indexed column and the column used in the predicate do not need to + match. PostgreSQL supports partial + indexes with arbitrary predicates, so long as only columns of the + table being indexed are involved. However, keep in mind that the + predicate must match the conditions used in the queries that + are supposed to benefit from the index. To be precise, a partial + index can be used in a query only if the system can recognize that + the WHERE condition of the query mathematically implies + the predicate of the index. + PostgreSQL does not have a sophisticated + theorem prover that can recognize mathematically equivalent + expressions that are written in different forms. (Not + only is such a general theorem prover extremely difficult to + create, it would probably be too slow to be of any real use.) + The system can recognize simple inequality implications, for example + x < 1 implies x < 2; otherwise + the predicate condition must exactly match part of the query's + WHERE condition + or the index will not be recognized as usable. Matching takes + place at query planning time, not at run time. As a result, + parameterized query clauses do not work with a partial index. For + example a prepared query with a parameter might specify + x < ? which will never imply + x < 2 for all possible values of the parameter. + + + + A third possible use for partial indexes does not require the + index to be used in queries at all. The idea here is to create + a unique index over a subset of a table, as in . This enforces uniqueness + among the rows that satisfy the index predicate, without constraining + those that do not. + + + + Setting up a Partial Unique Index + + + Suppose that we have a table describing test outcomes. We wish + to ensure that there is only one successful entry for + a given subject and target combination, but there might be any number of + unsuccessful entries. Here is one way to do it: + +CREATE TABLE tests ( + subject text, + target text, + success boolean, + ... +); + +CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) + WHERE success; + + This is a particularly efficient approach when there are few + successful tests and many unsuccessful ones. It is also possible to + allow only one null in a column by creating a unique partial index + with an IS NULL restriction. + + + + + + Finally, a partial index can also be used to override the system's + query plan choices. Also, data sets with peculiar + distributions might cause the system to use an index when it really + should not. In that case the index can be set up so that it is not + available for the offending query. Normally, + PostgreSQL makes reasonable choices about index + usage (e.g., it avoids them when retrieving common values, so the + earlier example really only saves index size, it is not required to + avoid index usage), and grossly incorrect plan choices are cause + for a bug report. + + + + Keep in mind that setting up a partial index indicates that you + know at least as much as the query planner knows, in particular you + know when an index might be profitable. Forming this knowledge + requires experience and understanding of how indexes in + PostgreSQL work. In most cases, the + advantage of a partial index over a regular index will be minimal. + There are cases where they are quite counterproductive, as in . + + + + Do Not Use Partial Indexes as a Substitute for Partitioning + + + You might be tempted to create a large set of non-overlapping partial + indexes, for example + + +CREATE INDEX mytable_cat_1 ON mytable (data) WHERE category = 1; +CREATE INDEX mytable_cat_2 ON mytable (data) WHERE category = 2; +CREATE INDEX mytable_cat_3 ON mytable (data) WHERE category = 3; +... +CREATE INDEX mytable_cat_N ON mytable (data) WHERE category = N; + + + This is a bad idea! Almost certainly, you'll be better off with a + single non-partial index, declared like + + +CREATE INDEX mytable_cat_data ON mytable (category, data); + + + (Put the category column first, for the reasons described in + .) While a search in this larger + index might have to descend through a couple more tree levels than a + search in a smaller index, that's almost certainly going to be cheaper + than the planner effort needed to select the appropriate one of the + partial indexes. The core of the problem is that the system does not + understand the relationship among the partial indexes, and will + laboriously test each one to see if it's applicable to the current + query. + + + + If your table is large enough that a single index really is a bad idea, + you should look into using partitioning instead (see + ). With that mechanism, the system + does understand that the tables and indexes are non-overlapping, so + far better performance is possible. + + + + + More information about partial indexes can be found in , , and . + + + + + + Index-Only Scans and Covering Indexes + + + index + index-only scans + + + index-only scan + + + index + covering + + + covering index + + + + All indexes in PostgreSQL + are secondary indexes, meaning that each index is + stored separately from the table's main data area (which is called the + table's heap + in PostgreSQL terminology). This means that + in an ordinary index scan, each row retrieval requires fetching data from + both the index and the heap. Furthermore, while the index entries that + match a given indexable WHERE condition are usually + close together in the index, the table rows they reference might be + anywhere in the heap. The heap-access portion of an index scan thus + involves a lot of random access into the heap, which can be slow, + particularly on traditional rotating media. (As described in + , bitmap scans try to alleviate + this cost by doing the heap accesses in sorted order, but that only goes + so far.) + + + + To solve this performance problem, PostgreSQL + supports index-only scans, which can answer + queries from an index alone without any heap access. The basic idea is + to return values directly out of each index entry instead of consulting + the associated heap entry. There are two fundamental restrictions on + when this method can be used: + + + + + The index type must support index-only scans. B-tree indexes always + do. GiST and SP-GiST indexes support index-only scans for some + operator classes but not others. Other index types have no support. + The underlying requirement is that the index must physically store, or + else be able to reconstruct, the original data value for each index + entry. As a counterexample, GIN indexes cannot support index-only + scans because each index entry typically holds only part of the + original data value. + + + + + + The query must reference only columns stored in the index. For + example, given an index on columns x + and y of a table that also has a + column z, these queries could use index-only scans: + +SELECT x, y FROM tab WHERE x = 'key'; +SELECT x FROM tab WHERE x = 'key' AND y < 42; + + but these queries could not: + +SELECT x, z FROM tab WHERE x = 'key'; +SELECT x FROM tab WHERE x = 'key' AND z < 42; + + (Expression indexes and partial indexes complicate this rule, + as discussed below.) + + + + + + + If these two fundamental requirements are met, then all the data values + required by the query are available from the index, so an index-only scan + is physically possible. But there is an additional requirement for any + table scan in PostgreSQL: it must verify that + each retrieved row be visible to the query's MVCC + snapshot, as discussed in . Visibility information + is not stored in index entries, only in heap entries; so at first glance + it would seem that every row retrieval would require a heap access + anyway. And this is indeed the case, if the table row has been modified + recently. However, for seldom-changing data there is a way around this + problem. PostgreSQL tracks, for each page in + a table's heap, whether all rows stored in that page are old enough to be + visible to all current and future transactions. This information is + stored in a bit in the table's visibility map. An + index-only scan, after finding a candidate index entry, checks the + visibility map bit for the corresponding heap page. If it's set, the row + is known visible and so the data can be returned with no further work. + If it's not set, the heap entry must be visited to find out whether it's + visible, so no performance advantage is gained over a standard index + scan. Even in the successful case, this approach trades visibility map + accesses for heap accesses; but since the visibility map is four orders + of magnitude smaller than the heap it describes, far less physical I/O is + needed to access it. In most situations the visibility map remains + cached in memory all the time. + + + + In short, while an index-only scan is possible given the two fundamental + requirements, it will be a win only if a significant fraction of the + table's heap pages have their all-visible map bits set. But tables in + which a large fraction of the rows are unchanging are common enough to + make this type of scan very useful in practice. + + + + + INCLUDE + in index definitions + + To make effective use of the index-only scan feature, you might choose to + create a covering index, which is an index + specifically designed to include the columns needed by a particular + type of query that you run frequently. Since queries typically need to + retrieve more columns than just the ones they search + on, PostgreSQL allows you to create an index + in which some columns are just payload and are not part + of the search key. This is done by adding an INCLUDE + clause listing the extra columns. For example, if you commonly run + queries like + +SELECT y FROM tab WHERE x = 'key'; + + the traditional approach to speeding up such queries would be to create + an index on x only. However, an index defined as + +CREATE INDEX tab_x_y ON tab(x) INCLUDE (y); + + could handle these queries as index-only scans, + because y can be obtained from the index without + visiting the heap. + + + + Because column y is not part of the index's search + key, it does not have to be of a data type that the index can handle; + it's merely stored in the index and is not interpreted by the index + machinery. Also, if the index is a unique index, that is + +CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); + + the uniqueness condition applies to just column x, + not to the combination of x and y. + (An INCLUDE clause can also be written + in UNIQUE and PRIMARY KEY + constraints, providing alternative syntax for setting up an index like + this.) + + + + It's wise to be conservative about adding non-key payload columns to an + index, especially wide columns. If an index tuple exceeds the + maximum size allowed for the index type, data insertion will fail. + In any case, non-key columns duplicate data from the index's table + and bloat the size of the index, thus potentially slowing searches. + And remember that there is little point in including payload columns in an + index unless the table changes slowly enough that an index-only scan is + likely to not need to access the heap. If the heap tuple must be visited + anyway, it costs nothing more to get the column's value from there. + Other restrictions are that expressions are not currently supported as + included columns, and that only B-tree, GiST and SP-GiST indexes currently + support included columns. + + + + Before PostgreSQL had + the INCLUDE feature, people sometimes made covering + indexes by writing the payload columns as ordinary index columns, + that is writing + +CREATE INDEX tab_x_y ON tab(x, y); + + even though they had no intention of ever using y as + part of a WHERE clause. This works fine as long as + the extra columns are trailing columns; making them be leading columns is + unwise for the reasons explained in . + However, this method doesn't support the case where you want the index to + enforce uniqueness on the key column(s). + + + + Suffix truncation always removes non-key + columns from upper B-Tree levels. As payload columns, they are + never used to guide index scans. The truncation process also + removes one or more trailing key column(s) when the remaining + prefix of key column(s) happens to be sufficient to describe tuples + on the lowest B-Tree level. In practice, covering indexes without + an INCLUDE clause often avoid storing columns + that are effectively payload in the upper levels. However, + explicitly defining payload columns as non-key columns + reliably keeps the tuples in upper levels + small. + + + + In principle, index-only scans can be used with expression indexes. + For example, given an index on f(x) + where x is a table column, it should be possible to + execute + +SELECT f(x) FROM tab WHERE f(x) < 1; + + as an index-only scan; and this is very attractive + if f() is an expensive-to-compute function. + However, PostgreSQL's planner is currently not + very smart about such cases. It considers a query to be potentially + executable by index-only scan only when all columns + needed by the query are available from the index. In this + example, x is not needed except in the + context f(x), but the planner does not notice that and + concludes that an index-only scan is not possible. If an index-only scan + seems sufficiently worthwhile, this can be worked around by + adding x as an included column, for example + +CREATE INDEX tab_f_x ON tab (f(x)) INCLUDE (x); + + An additional caveat, if the goal is to avoid + recalculating f(x), is that the planner won't + necessarily match uses of f(x) that aren't in + indexable WHERE clauses to the index column. It will + usually get this right in simple queries such as shown above, but not in + queries that involve joins. These deficiencies may be remedied in future + versions of PostgreSQL. + + + + Partial indexes also have interesting interactions with index-only scans. + Consider the partial index shown in : + +CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) + WHERE success; + + In principle, we could do an index-only scan on this index to satisfy a + query like + +SELECT target FROM tests WHERE subject = 'some-subject' AND success; + + But there's a problem: the WHERE clause refers + to success which is not available as a result column + of the index. Nonetheless, an index-only scan is possible because the + plan does not need to recheck that part of the WHERE + clause at run time: all entries found in the index necessarily + have success = true so this need not be explicitly + checked in the plan. PostgreSQL versions 9.6 + and later will recognize such cases and allow index-only scans to be + generated, but older versions will not. + + + + + + Operator Classes and Operator Families + + + operator class + + + + operator family + + + + An index definition can specify an operator + class for each column of an index. + +CREATE INDEX name ON table (column opclass [ ( opclass_options ) ] sort options , ...); + + The operator class identifies the operators to be used by the index + for that column. For example, a B-tree index on the type int4 + would use the int4_ops class; this operator + class includes comparison functions for values of type int4. + In practice the default operator class for the column's data type is + usually sufficient. The main reason for having operator classes is + that for some data types, there could be more than one meaningful + index behavior. For example, we might want to sort a complex-number data + type either by absolute value or by real part. We could do this by + defining two operator classes for the data type and then selecting + the proper class when making an index. The operator class determines + the basic sort ordering (which can then be modified by adding sort options + COLLATE, + ASC/DESC and/or + NULLS FIRST/NULLS LAST). + + + + There are also some built-in operator classes besides the default ones: + + + + + The operator classes text_pattern_ops, + varchar_pattern_ops, and + bpchar_pattern_ops support B-tree indexes on + the types text, varchar, and + char respectively. The + difference from the default operator classes is that the values + are compared strictly character by character rather than + according to the locale-specific collation rules. This makes + these operator classes suitable for use by queries involving + pattern matching expressions (LIKE or POSIX + regular expressions) when the database does not use the standard + C locale. As an example, you might index a + varchar column like this: + +CREATE INDEX test_index ON test_table (col varchar_pattern_ops); + + Note that you should also create an index with the default operator + class if you want queries involving ordinary <, + <=, >, or >= comparisons + to use an index. Such queries cannot use the + xxx_pattern_ops + operator classes. (Ordinary equality comparisons can use these + operator classes, however.) It is possible to create multiple + indexes on the same column with different operator classes. + If you do use the C locale, you do not need the + xxx_pattern_ops + operator classes, because an index with the default operator class + is usable for pattern-matching queries in the C locale. + + + + + + + The following query shows all defined operator classes: + + +SELECT am.amname AS index_method, + opc.opcname AS opclass_name, + opc.opcintype::regtype AS indexed_type, + opc.opcdefault AS is_default + FROM pg_am am, pg_opclass opc + WHERE opc.opcmethod = am.oid + ORDER BY index_method, opclass_name; + + + + + An operator class is actually just a subset of a larger structure called an + operator family. In cases where several data types have + similar behaviors, it is frequently useful to define cross-data-type + operators and allow these to work with indexes. To do this, the operator + classes for each of the types must be grouped into the same operator + family. The cross-type operators are members of the family, but are not + associated with any single class within the family. + + + + This expanded version of the previous query shows the operator family + each operator class belongs to: + +SELECT am.amname AS index_method, + opc.opcname AS opclass_name, + opf.opfname AS opfamily_name, + opc.opcintype::regtype AS indexed_type, + opc.opcdefault AS is_default + FROM pg_am am, pg_opclass opc, pg_opfamily opf + WHERE opc.opcmethod = am.oid AND + opc.opcfamily = opf.oid + ORDER BY index_method, opclass_name; + + + + + This query shows all defined operator families and all + the operators included in each family: + +SELECT am.amname AS index_method, + opf.opfname AS opfamily_name, + amop.amopopr::regoperator AS opfamily_operator + FROM pg_am am, pg_opfamily opf, pg_amop amop + WHERE opf.opfmethod = am.oid AND + amop.amopfamily = opf.oid + ORDER BY index_method, opfamily_name, opfamily_operator; + + + + + + has + commands \dAc, \dAf, + and \dAo, which provide slightly more sophisticated + versions of these queries. + + + + + + + Indexes and Collations + + + An index can support only one collation per index column. + If multiple collations are of interest, multiple indexes may be needed. + + + + Consider these statements: + +CREATE TABLE test1c ( + id integer, + content varchar COLLATE "x" +); + +CREATE INDEX test1c_content_index ON test1c (content); + + The index automatically uses the collation of the + underlying column. So a query of the form + +SELECT * FROM test1c WHERE content > constant; + + could use the index, because the comparison will by default use the + collation of the column. However, this index cannot accelerate queries + that involve some other collation. So if queries of the form, say, + +SELECT * FROM test1c WHERE content > constant COLLATE "y"; + + are also of interest, an additional index could be created that supports + the "y" collation, like this: + +CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); + + + + + + + Examining Index Usage + + + index + examining usage + + + + Although indexes in PostgreSQL do not need + maintenance or tuning, it is still important to check + which indexes are actually used by the real-life query workload. + Examining index usage for an individual query is done with the + + command; its application for this purpose is + illustrated in . + It is also possible to gather overall statistics about index usage + in a running server, as described in . + + + + It is difficult to formulate a general procedure for determining + which indexes to create. There are a number of typical cases that + have been shown in the examples throughout the previous sections. + A good deal of experimentation is often necessary. + The rest of this section gives some tips for that: + + + + + + Always run + first. This command + collects statistics about the distribution of the values in the + table. This information is required to estimate the number of rows + returned by a query, which is needed by the planner to assign + realistic costs to each possible query plan. In absence of any + real statistics, some default values are assumed, which are + almost certain to be inaccurate. Examining an application's + index usage without having run ANALYZE is + therefore a lost cause. + See + and for more information. + + + + + + Use real data for experimentation. Using test data for setting + up indexes will tell you what indexes you need for the test data, + but that is all. + + + + It is especially fatal to use very small test data sets. + While selecting 1000 out of 100000 rows could be a candidate for + an index, selecting 1 out of 100 rows will hardly be, because the + 100 rows probably fit within a single disk page, and there + is no plan that can beat sequentially fetching 1 disk page. + + + + Also be careful when making up test data, which is often + unavoidable when the application is not yet in production. + Values that are very similar, completely random, or inserted in + sorted order will skew the statistics away from the distribution + that real data would have. + + + + + + When indexes are not used, it can be useful for testing to force + their use. There are run-time parameters that can turn off + various plan types (see ). + For instance, turning off sequential scans + (enable_seqscan) and nested-loop joins + (enable_nestloop), which are the most basic plans, + will force the system to use a different plan. If the system + still chooses a sequential scan or nested-loop join then there is + probably a more fundamental reason why the index is not being + used; for example, the query condition does not match the index. + (What kind of query can use what kind of index is explained in + the previous sections.) + + + + + + If forcing index usage does use the index, then there are two + possibilities: Either the system is right and using the index is + indeed not appropriate, or the cost estimates of the query plans + are not reflecting reality. So you should time your query with + and without indexes. The EXPLAIN ANALYZE + command can be useful here. + + + + + + If it turns out that the cost estimates are wrong, there are, + again, two possibilities. The total cost is computed from the + per-row costs of each plan node times the selectivity estimate of + the plan node. The costs estimated for the plan nodes can be adjusted + via run-time parameters (described in ). + An inaccurate selectivity estimate is due to + insufficient statistics. It might be possible to improve this by + tuning the statistics-gathering parameters (see + ). + + + + If you do not succeed in adjusting the costs to be more + appropriate, then you might have to resort to forcing index usage + explicitly. You might also want to contact the + PostgreSQL developers to examine the issue. + + + + + diff --git a/doc/src/sgml/information_schema.sgml b/doc/src/sgml/information_schema.sgml new file mode 100644 index 000000000000..41001982528b --- /dev/null +++ b/doc/src/sgml/information_schema.sgml @@ -0,0 +1,8667 @@ + + + + The Information Schema + + + information schema + + + + The information schema consists of a set of views that contain + information about the objects defined in the current database. The + information schema is defined in the SQL standard and can therefore + be expected to be portable and remain stable — unlike the system + catalogs, which are specific to + PostgreSQL and are modeled after + implementation concerns. The information schema views do not, + however, contain information about + PostgreSQL-specific features; to inquire + about those you need to query the system catalogs or other + PostgreSQL-specific views. + + + + + When querying the database for constraint information, it is possible + for a standard-compliant query that expects to return one row to + return several. This is because the SQL standard requires constraint + names to be unique within a schema, but + PostgreSQL does not enforce this + restriction. PostgreSQL + automatically-generated constraint names avoid duplicates in the + same schema, but users can specify such duplicate names. + + + + This problem can appear when querying information schema views such + as check_constraint_routine_usage, + check_constraints, domain_constraints, and + referential_constraints. Some other views have similar + issues but contain the table name to help distinguish duplicate + rows, e.g., constraint_column_usage, + constraint_table_usage, table_constraints. + + + + + + The Schema + + + The information schema itself is a schema named + information_schema. This schema automatically + exists in all databases. The owner of this schema is the initial + database user in the cluster, and that user naturally has all the + privileges on this schema, including the ability to drop it (but + the space savings achieved by that are minuscule). + + + + By default, the information schema is not in the schema search + path, so you need to access all objects in it through qualified + names. Since the names of some of the objects in the information + schema are generic names that might occur in user applications, you + should be careful if you want to put the information schema in the + path. + + + + + Data Types + + + The columns of the information schema views use special data types + that are defined in the information schema. These are defined as + simple domains over ordinary built-in types. You should not use + these types for work outside the information schema, but your + applications must be prepared for them if they select from the + information schema. + + + + These types are: + + + + cardinal_number + + + A nonnegative integer. + + + + + + character_data + + + A character string (without specific maximum length). + + + + + + sql_identifier + + + A character string. This type is used for SQL identifiers, the + type character_data is used for any other kind of + text data. + + + + + + time_stamp + + + A domain over the type timestamp with time zone + + + + + + yes_or_no + + + A character string domain that contains + either YES or NO. This + is used to represent Boolean (true/false) data in the + information schema. (The information schema was invented + before the type boolean was added to the SQL + standard, so this convention is necessary to keep the + information schema backward compatible.) + + + + + + Every column in the information schema has one of these five types. + + + + + <literal>information_schema_catalog_name</literal> + + + information_schema_catalog_name is a table that + always contains one row and one column containing the name of the + current database (current catalog, in SQL terminology). + + + + <structname>information_schema_catalog_name</structname> Columns + + + + + Column Type + + + Description + + + + + + + + catalog_name sql_identifier + + + Name of the database that contains this information schema + + + + +
+
+ + + <literal>administrable_role_&zwsp;authorizations</literal> + + + The view administrable_role_authorizations + identifies all roles that the current user has the admin option + for. + + + + <structname>administrable_role_authorizations</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantee sql_identifier + + + Name of the role to which this role membership was granted (can + be the current user, or a different role in case of nested role + memberships) + + + + + + role_name sql_identifier + + + Name of a role + + + + + + is_grantable yes_or_no + + + Always YES + + + + +
+
+ + + <literal>applicable_roles</literal> + + + The view applicable_roles identifies all roles + whose privileges the current user can use. This means there is + some chain of role grants from the current user to the role in + question. The current user itself is also an applicable role. The + set of applicable roles is generally used for permission checking. + applicable role + roleapplicable + + + + <structname>applicable_roles</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantee sql_identifier + + + Name of the role to which this role membership was granted (can + be the current user, or a different role in case of nested role + memberships) + + + + + + role_name sql_identifier + + + Name of a role + + + + + + is_grantable yes_or_no + + + YES if the grantee has the admin option on + the role, NO if not + + + + +
+
+ + + <literal>attributes</literal> + + + The view attributes contains information about + the attributes of composite data types defined in the database. + (Note that the view does not give information about table columns, + which are sometimes called attributes in PostgreSQL contexts.) + Only those attributes are shown that the current user has access to (by way + of being the owner of or having some privilege on the type). + + + + <structname>attributes</structname> Columns + + + + + Column Type + + + Description + + + + + + + + udt_catalog sql_identifier + + + Name of the database containing the data type (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema containing the data type + + + + + + udt_name sql_identifier + + + Name of the data type + + + + + + attribute_name sql_identifier + + + Name of the attribute + + + + + + ordinal_position cardinal_number + + + Ordinal position of the attribute within the data type (count starts at 1) + + + + + + attribute_default character_data + + + Default expression of the attribute + + + + + + is_nullable yes_or_no + + + YES if the attribute is possibly nullable, + NO if it is known not nullable. + + + + + + data_type character_data + + + Data type of the attribute, if it is a built-in type, or + ARRAY if it is some array (in that case, see + the view element_types), else + USER-DEFINED (in that case, the type is + identified in attribute_udt_name and + associated columns). + + + + + + character_maximum_length cardinal_number + + + If data_type identifies a character or bit + string type, the declared maximum length; null for all other + data types or if no maximum length was declared. + + + + + + character_octet_length cardinal_number + + + If data_type identifies a character type, + the maximum possible length in octets (bytes) of a datum; null + for all other data types. The maximum octet length depends on + the declared character maximum length (see above) and the + server encoding. + + + + + + character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_catalog sql_identifier + + + Name of the database containing the collation of the attribute + (always the current database), null if default or the data type + of the attribute is not collatable + + + + + + collation_schema sql_identifier + + + Name of the schema containing the collation of the attribute, + null if default or the data type of the attribute is not + collatable + + + + + + collation_name sql_identifier + + + Name of the collation of the attribute, null if default or the + data type of the attribute is not collatable + + + + + + numeric_precision cardinal_number + + + If data_type identifies a numeric type, this + column contains the (declared or implicit) precision of the + type for this attribute. The precision indicates the number of + significant digits. It can be expressed in decimal (base 10) + or binary (base 2) terms, as specified in the column + numeric_precision_radix. For all other data + types, this column is null. + + + + + + numeric_precision_radix cardinal_number + + + If data_type identifies a numeric type, this + column indicates in which base the values in the columns + numeric_precision and + numeric_scale are expressed. The value is + either 2 or 10. For all other data types, this column is null. + + + + + + numeric_scale cardinal_number + + + If data_type identifies an exact numeric + type, this column contains the (declared or implicit) scale of + the type for this attribute. The scale indicates the number of + significant digits to the right of the decimal point. It can + be expressed in decimal (base 10) or binary (base 2) terms, as + specified in the column + numeric_precision_radix. For all other data + types, this column is null. + + + + + + datetime_precision cardinal_number + + + If data_type identifies a date, time, + timestamp, or interval type, this column contains the (declared + or implicit) fractional seconds precision of the type for this + attribute, that is, the number of decimal digits maintained + following the decimal point in the seconds value. For all + other data types, this column is null. + + + + + + interval_type character_data + + + If data_type identifies an interval type, + this column contains the specification which fields the + intervals include for this attribute, e.g., YEAR TO + MONTH, DAY TO SECOND, etc. If no + field restrictions were specified (that is, the interval + accepts all fields), and for all other data types, this field + is null. + + + + + + interval_precision cardinal_number + + + Applies to a feature not available + in PostgreSQL + (see datetime_precision for the fractional + seconds precision of interval type attributes) + + + + + + attribute_udt_catalog sql_identifier + + + Name of the database that the attribute data type is defined in + (always the current database) + + + + + + attribute_udt_schema sql_identifier + + + Name of the schema that the attribute data type is defined in + + + + + + attribute_udt_name sql_identifier + + + Name of the attribute data type + + + + + + scope_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + maximum_cardinality cardinal_number + + + Always null, because arrays always have unlimited maximum cardinality in PostgreSQL + + + + + + dtd_identifier sql_identifier + + + An identifier of the data type descriptor of the column, unique + among the data type descriptors pertaining to the table. This + is mainly useful for joining with other instances of such + identifiers. (The specific format of the identifier is not + defined and not guaranteed to remain the same in future + versions.) + + + + + + is_derived_reference_attribute yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + +
+ + + See also under , a similarly + structured view, for further information on some of the columns. + +
+ + + <literal>character_sets</literal> + + + The view character_sets identifies the character + sets available in the current database. Since PostgreSQL does not + support multiple character sets within one database, this view only + shows one, which is the database encoding. + + + + Take note of how the following terms are used in the SQL standard: + + + character repertoire + + + An abstract collection of characters, for + example UNICODE, UCS, or + LATIN1. Not exposed as an SQL object, but + visible in this view. + + + + + + character encoding form + + + An encoding of some character repertoire. Most older character + repertoires only use one encoding form, and so there are no + separate names for them (e.g., LATIN1 is an + encoding form applicable to the LATIN1 + repertoire). But for example Unicode has the encoding forms + UTF8, UTF16, etc. (not + all supported by PostgreSQL). Encoding forms are not exposed + as an SQL object, but are visible in this view. + + + + + + character set + + + A named SQL object that identifies a character repertoire, a + character encoding, and a default collation. A predefined + character set would typically have the same name as an encoding + form, but users could define other names. For example, the + character set UTF8 would typically identify + the character repertoire UCS, encoding + form UTF8, and some default collation. + + + + + + You can think of an encoding in PostgreSQL either as + a character set or a character encoding form. They will have the + same name, and there can only be one in one database. + + + + <structname>character_sets</structname> Columns + + + + + Column Type + + + Description + + + + + + + + character_set_catalog sql_identifier + + + Character sets are currently not implemented as schema objects, so this column is null. + + + + + + character_set_schema sql_identifier + + + Character sets are currently not implemented as schema objects, so this column is null. + + + + + + character_set_name sql_identifier + + + Name of the character set, currently implemented as showing the name of the database encoding + + + + + + character_repertoire sql_identifier + + + Character repertoire, showing UCS if the encoding is UTF8, else just the encoding name + + + + + + form_of_use sql_identifier + + + Character encoding form, same as the database encoding + + + + + + default_collate_catalog sql_identifier + + + Name of the database containing the default collation (always the current database, if any collation is identified) + + + + + + default_collate_schema sql_identifier + + + Name of the schema containing the default collation + + + + + + default_collate_name sql_identifier + + + Name of the default collation. The default collation is + identified as the collation that matches + the COLLATE and CTYPE + settings of the current database. If there is no such + collation, then this column and the associated schema and + catalog columns are null. + + + + +
+
+ + + <literal>check_constraint_routine_usage</literal> + + + The view check_constraint_routine_usage + identifies routines (functions and procedures) that are used by a + check constraint. Only those routines are shown that are owned by + a currently enabled role. + + + + <structname>check_constraint_routine_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + constraint_catalog sql_identifier + + + Name of the database containing the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema containing the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + +
+
+ + + <literal>check_constraints</literal> + + + The view check_constraints contains all check + constraints, either defined on a table or on a domain, that are + owned by a currently enabled role. (The owner of the table or + domain is the owner of the constraint.) + + + + <structname>check_constraints</structname> Columns + + + + + Column Type + + + Description + + + + + + + + constraint_catalog sql_identifier + + + Name of the database containing the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema containing the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + + + check_clause character_data + + + The check expression of the check constraint + + + + +
+
+ + + <literal>collations</literal> + + + The view collations contains the collations + available in the current database. + + + + <structname>collations</structname> Columns + + + + + Column Type + + + Description + + + + + + + + collation_catalog sql_identifier + + + Name of the database containing the collation (always the current database) + + + + + + collation_schema sql_identifier + + + Name of the schema containing the collation + + + + + + collation_name sql_identifier + + + Name of the default collation + + + + + + pad_attribute character_data + + + Always NO PAD (The alternative PAD + SPACE is not supported by PostgreSQL.) + + + + +
+
+ + + <literal>collation_character_set_&zwsp;applicability</literal> + + + The view collation_character_set_applicability + identifies which character set the available collations are + applicable to. In PostgreSQL, there is only one character set per + database (see explanation + in ), so this view does + not provide much useful information. + + + + <structname>collation_character_set_applicability</structname> Columns + + + + + Column Type + + + Description + + + + + + + + collation_catalog sql_identifier + + + Name of the database containing the collation (always the current database) + + + + + + collation_schema sql_identifier + + + Name of the schema containing the collation + + + + + + collation_name sql_identifier + + + Name of the default collation + + + + + + character_set_catalog sql_identifier + + + Character sets are currently not implemented as schema objects, so this column is null + + + + + + character_set_schema sql_identifier + + + Character sets are currently not implemented as schema objects, so this column is null + + + + + + character_set_name sql_identifier + + + Name of the character set + + + + +
+
+ + + <literal>column_column_usage</literal> + + + The view column_column_usage identifies all generated + columns that depend on another base column in the same table. Only tables + owned by a currently enabled role are included. + + + + <structname>column_column_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database containing the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema containing the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + column_name sql_identifier + + + Name of the base column that a generated column depends on + + + + + + dependent_column sql_identifier + + + Name of the generated column + + + + +
+
+ + + <literal>column_domain_usage</literal> + + + The view column_domain_usage identifies all + columns (of a table or a view) that make use of some domain defined + in the current database and owned by a currently enabled role. + + + + <structname>column_domain_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + domain_catalog sql_identifier + + + Name of the database containing the domain (always the current database) + + + + + + domain_schema sql_identifier + + + Name of the schema containing the domain + + + + + + domain_name sql_identifier + + + Name of the domain + + + + + + table_catalog sql_identifier + + + Name of the database containing the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema containing the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + column_name sql_identifier + + + Name of the column + + + + +
+
+ + + <literal>column_options</literal> + + + The view column_options contains all the + options defined for foreign table columns in the current database. Only + those foreign table columns are shown that the current user has access to + (by way of being the owner or having some privilege). + + + + <structname>column_options</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database that contains the foreign table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the foreign table + + + + + + table_name sql_identifier + + + Name of the foreign table + + + + + + column_name sql_identifier + + + Name of the column + + + + + + option_name sql_identifier + + + Name of an option + + + + + + option_value character_data + + + Value of the option + + + + +
+
+ + + <literal>column_privileges</literal> + + + The view column_privileges identifies all + privileges granted on columns to a currently enabled role or by a + currently enabled role. There is one row for each combination of + column, grantor, and grantee. + + + + If a privilege has been granted on an entire table, it will show up in + this view as a grant for each column, but only for the + privilege types where column granularity is possible: + SELECT, INSERT, + UPDATE, REFERENCES. + + + + <structname>column_privileges</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that contains the column (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that contains the column + + + + + + table_name sql_identifier + + + Name of the table that contains the column + + + + + + column_name sql_identifier + + + Name of the column + + + + + + privilege_type character_data + + + Type of the privilege: SELECT, + INSERT, UPDATE, or + REFERENCES + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>column_udt_usage</literal> + + + The view column_udt_usage identifies all columns + that use data types owned by a currently enabled role. Note that in + PostgreSQL, built-in data types behave + like user-defined types, so they are included here as well. See + also for details. + + + + <structname>column_udt_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + udt_catalog sql_identifier + + + Name of the database that the column data type (the underlying + type of the domain, if applicable) is defined in (always the + current database) + + + + + + udt_schema sql_identifier + + + Name of the schema that the column data type (the underlying + type of the domain, if applicable) is defined in + + + + + + udt_name sql_identifier + + + Name of the column data type (the underlying type of the + domain, if applicable) + + + + + + table_catalog sql_identifier + + + Name of the database containing the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema containing the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + column_name sql_identifier + + + Name of the column + + + + +
+
+ + + <literal>columns</literal> + + + The view columns contains information about all + table columns (or view columns) in the database. System columns + (ctid, etc.) are not included. Only those columns are + shown that the current user has access to (by way of being the + owner or having some privilege). + + + + <structname>columns</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database containing the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema containing the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + column_name sql_identifier + + + Name of the column + + + + + + ordinal_position cardinal_number + + + Ordinal position of the column within the table (count starts at 1) + + + + + + column_default character_data + + + Default expression of the column + + + + + + is_nullable yes_or_no + + + YES if the column is possibly nullable, + NO if it is known not nullable. A not-null + constraint is one way a column can be known not nullable, but + there can be others. + + + + + + data_type character_data + + + Data type of the column, if it is a built-in type, or + ARRAY if it is some array (in that case, see + the view element_types), else + USER-DEFINED (in that case, the type is + identified in udt_name and associated + columns). If the column is based on a domain, this column + refers to the type underlying the domain (and the domain is + identified in domain_name and associated + columns). + + + + + + character_maximum_length cardinal_number + + + If data_type identifies a character or bit + string type, the declared maximum length; null for all other + data types or if no maximum length was declared. + + + + + + character_octet_length cardinal_number + + + If data_type identifies a character type, + the maximum possible length in octets (bytes) of a datum; null + for all other data types. The maximum octet length depends on + the declared character maximum length (see above) and the + server encoding. + + + + + + numeric_precision cardinal_number + + + If data_type identifies a numeric type, this + column contains the (declared or implicit) precision of the + type for this column. The precision indicates the number of + significant digits. It can be expressed in decimal (base 10) + or binary (base 2) terms, as specified in the column + numeric_precision_radix. For all other data + types, this column is null. + + + + + + numeric_precision_radix cardinal_number + + + If data_type identifies a numeric type, this + column indicates in which base the values in the columns + numeric_precision and + numeric_scale are expressed. The value is + either 2 or 10. For all other data types, this column is null. + + + + + + numeric_scale cardinal_number + + + If data_type identifies an exact numeric + type, this column contains the (declared or implicit) scale of + the type for this column. The scale indicates the number of + significant digits to the right of the decimal point. It can + be expressed in decimal (base 10) or binary (base 2) terms, as + specified in the column + numeric_precision_radix. For all other data + types, this column is null. + + + + + + datetime_precision cardinal_number + + + If data_type identifies a date, time, + timestamp, or interval type, this column contains the (declared + or implicit) fractional seconds precision of the type for this + column, that is, the number of decimal digits maintained + following the decimal point in the seconds value. For all + other data types, this column is null. + + + + + + interval_type character_data + + + If data_type identifies an interval type, + this column contains the specification which fields the + intervals include for this column, e.g., YEAR TO + MONTH, DAY TO SECOND, etc. If no + field restrictions were specified (that is, the interval + accepts all fields), and for all other data types, this field + is null. + + + + + + interval_precision cardinal_number + + + Applies to a feature not available + in PostgreSQL + (see datetime_precision for the fractional + seconds precision of interval type columns) + + + + + + character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_catalog sql_identifier + + + Name of the database containing the collation of the column + (always the current database), null if default or the data type + of the column is not collatable + + + + + + collation_schema sql_identifier + + + Name of the schema containing the collation of the column, null + if default or the data type of the column is not collatable + + + + + + collation_name sql_identifier + + + Name of the collation of the column, null if default or the + data type of the column is not collatable + + + + + + domain_catalog sql_identifier + + + If the column has a domain type, the name of the database that + the domain is defined in (always the current database), else + null. + + + + + + domain_schema sql_identifier + + + If the column has a domain type, the name of the schema that + the domain is defined in, else null. + + + + + + domain_name sql_identifier + + + If the column has a domain type, the name of the domain, else null. + + + + + + udt_catalog sql_identifier + + + Name of the database that the column data type (the underlying + type of the domain, if applicable) is defined in (always the + current database) + + + + + + udt_schema sql_identifier + + + Name of the schema that the column data type (the underlying + type of the domain, if applicable) is defined in + + + + + + udt_name sql_identifier + + + Name of the column data type (the underlying type of the + domain, if applicable) + + + + + + scope_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + maximum_cardinality cardinal_number + + + Always null, because arrays always have unlimited maximum cardinality in PostgreSQL + + + + + + dtd_identifier sql_identifier + + + An identifier of the data type descriptor of the column, unique + among the data type descriptors pertaining to the table. This + is mainly useful for joining with other instances of such + identifiers. (The specific format of the identifier is not + defined and not guaranteed to remain the same in future + versions.) + + + + + + is_self_referencing yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + is_identity yes_or_no + + + If the column is an identity column, then YES, + else NO. + + + + + + identity_generation character_data + + + If the column is an identity column, then ALWAYS + or BY DEFAULT, reflecting the definition of the + column. + + + + + + identity_start character_data + + + If the column is an identity column, then the start value of the + internal sequence, else null. + + + + + + identity_increment character_data + + + If the column is an identity column, then the increment of the internal + sequence, else null. + + + + + + identity_maximum character_data + + + If the column is an identity column, then the maximum value of the + internal sequence, else null. + + + + + + identity_minimum character_data + + + If the column is an identity column, then the minimum value of the + internal sequence, else null. + + + + + + identity_cycle yes_or_no + + + If the column is an identity column, then YES if the + internal sequence cycles or NO if it does not; + otherwise null. + + + + + + is_generated character_data + + + If the column is a generated column, then ALWAYS, + else NEVER. + + + + + + generation_expression character_data + + + If the column is a generated column, then the generation expression, + else null. + + + + + + is_updatable yes_or_no + + + YES if the column is updatable, + NO if not (Columns in base tables are always + updatable, columns in views not necessarily) + + + + +
+ + + Since data types can be defined in a variety of ways in SQL, and + PostgreSQL contains additional ways to + define data types, their representation in the information schema + can be somewhat difficult. The column data_type + is supposed to identify the underlying built-in type of the column. + In PostgreSQL, this means that the type + is defined in the system catalog schema + pg_catalog. This column might be useful if the + application can handle the well-known built-in types specially (for + example, format the numeric types differently or use the data in + the precision columns). The columns udt_name, + udt_schema, and udt_catalog + always identify the underlying data type of the column, even if the + column is based on a domain. (Since + PostgreSQL treats built-in types like + user-defined types, built-in types appear here as well. This is an + extension of the SQL standard.) These columns should be used if an + application wants to process data differently according to the + type, because in that case it wouldn't matter if the column is + really based on a domain. If the column is based on a domain, the + identity of the domain is stored in the columns + domain_name, domain_schema, + and domain_catalog. If you want to pair up + columns with their associated data types and treat domains as + separate types, you could write coalesce(domain_name, + udt_name), etc. + +
+ + + <literal>constraint_column_usage</literal> + + + The view constraint_column_usage identifies all + columns in the current database that are used by some constraint. + Only those columns are shown that are contained in a table owned by + a currently enabled role. For a check constraint, this view + identifies the columns that are used in the check expression. For + a foreign key constraint, this view identifies the columns that the + foreign key references. For a unique or primary key constraint, + this view identifies the constrained columns. + + + + <structname>constraint_column_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that contains the + column that is used by some constraint (always the current + database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that contains the + column that is used by some constraint + + + + + + table_name sql_identifier + + + Name of the table that contains the column that is used by some + constraint + + + + + + column_name sql_identifier + + + Name of the column that is used by some constraint + + + + + + constraint_catalog sql_identifier + + + Name of the database that contains the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema that contains the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + +
+
+ + + <literal>constraint_table_usage</literal> + + + The view constraint_table_usage identifies all + tables in the current database that are used by some constraint and + are owned by a currently enabled role. (This is different from the + view table_constraints, which identifies all + table constraints along with the table they are defined on.) For a + foreign key constraint, this view identifies the table that the + foreign key references. For a unique or primary key constraint, + this view simply identifies the table the constraint belongs to. + Check constraints and not-null constraints are not included in this + view. + + + + <structname>constraint_table_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that is used by + some constraint (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that is used by some + constraint + + + + + + table_name sql_identifier + + + Name of the table that is used by some constraint + + + + + + constraint_catalog sql_identifier + + + Name of the database that contains the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema that contains the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + +
+
+ + + <literal>data_type_privileges</literal> + + + The view data_type_privileges identifies all + data type descriptors that the current user has access to, by way + of being the owner of the described object or having some privilege + for it. A data type descriptor is generated whenever a data type + is used in the definition of a table column, a domain, or a + function (as parameter or return type) and stores some information + about how the data type is used in that instance (for example, the + declared maximum length, if applicable). Each data type + descriptor is assigned an arbitrary identifier that is unique + among the data type descriptor identifiers assigned for one object + (table, domain, function). This view is probably not useful for + applications, but it is used to define some other views in the + information schema. + + + + <structname>data_type_privileges</structname> Columns + + + + + Column Type + + + Description + + + + + + + + object_catalog sql_identifier + + + Name of the database that contains the described object (always the current database) + + + + + + object_schema sql_identifier + + + Name of the schema that contains the described object + + + + + + object_name sql_identifier + + + Name of the described object + + + + + + object_type character_data + + + The type of the described object: one of + TABLE (the data type descriptor pertains to + a column of that table), DOMAIN (the data + type descriptors pertains to that domain), + ROUTINE (the data type descriptor pertains + to a parameter or the return data type of that function). + + + + + + dtd_identifier sql_identifier + + + The identifier of the data type descriptor, which is unique + among the data type descriptors for that same object. + + + + +
+
+ + + <literal>domain_constraints</literal> + + + The view domain_constraints contains all constraints + belonging to domains defined in the current database. Only those domains + are shown that the current user has access to (by way of being the owner or + having some privilege). + + + + <structname>domain_constraints</structname> Columns + + + + + Column Type + + + Description + + + + + + + + constraint_catalog sql_identifier + + + Name of the database that contains the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema that contains the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + + + domain_catalog sql_identifier + + + Name of the database that contains the domain (always the current database) + + + + + + domain_schema sql_identifier + + + Name of the schema that contains the domain + + + + + + domain_name sql_identifier + + + Name of the domain + + + + + + is_deferrable yes_or_no + + + YES if the constraint is deferrable, NO if not + + + + + + initially_deferred yes_or_no + + + YES if the constraint is deferrable and initially deferred, NO if not + + + + +
+
+ + + <literal>domain_udt_usage</literal> + + + The view domain_udt_usage identifies all domains + that are based on data types owned by a currently enabled role. + Note that in PostgreSQL, built-in data + types behave like user-defined types, so they are included here as + well. + + + + <structname>domain_udt_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + udt_catalog sql_identifier + + + Name of the database that the domain data type is defined in (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema that the domain data type is defined in + + + + + + udt_name sql_identifier + + + Name of the domain data type + + + + + + domain_catalog sql_identifier + + + Name of the database that contains the domain (always the current database) + + + + + + domain_schema sql_identifier + + + Name of the schema that contains the domain + + + + + + domain_name sql_identifier + + + Name of the domain + + + + +
+
+ + + <literal>domains</literal> + + + The view domains contains all domains defined in the + current database. Only those domains are shown that the current user has + access to (by way of being the owner or having some privilege). + + + + <structname>domains</structname> Columns + + + + + Column Type + + + Description + + + + + + + + domain_catalog sql_identifier + + + Name of the database that contains the domain (always the current database) + + + + + + domain_schema sql_identifier + + + Name of the schema that contains the domain + + + + + + domain_name sql_identifier + + + Name of the domain + + + + + + data_type character_data + + + Data type of the domain, if it is a built-in type, or + ARRAY if it is some array (in that case, see + the view element_types), else + USER-DEFINED (in that case, the type is + identified in udt_name and associated + columns). + + + + + + character_maximum_length cardinal_number + + + If the domain has a character or bit string type, the declared + maximum length; null for all other data types or if no maximum + length was declared. + + + + + + character_octet_length cardinal_number + + + If the domain has a character type, the maximum possible length + in octets (bytes) of a datum; null for all other data types. + The maximum octet length depends on the declared character + maximum length (see above) and the server encoding. + + + + + + character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_catalog sql_identifier + + + Name of the database containing the collation of the domain + (always the current database), null if default or the data type + of the domain is not collatable + + + + + + collation_schema sql_identifier + + + Name of the schema containing the collation of the domain, null + if default or the data type of the domain is not collatable + + + + + + collation_name sql_identifier + + + Name of the collation of the domain, null if default or the + data type of the domain is not collatable + + + + + + numeric_precision cardinal_number + + + If the domain has a numeric type, this column contains the + (declared or implicit) precision of the type for this domain. + The precision indicates the number of significant digits. It + can be expressed in decimal (base 10) or binary (base 2) terms, + as specified in the column + numeric_precision_radix. For all other data + types, this column is null. + + + + + + numeric_precision_radix cardinal_number + + + If the domain has a numeric type, this column indicates in + which base the values in the columns + numeric_precision and + numeric_scale are expressed. The value is + either 2 or 10. For all other data types, this column is null. + + + + + + numeric_scale cardinal_number + + + If the domain has an exact numeric type, this column contains + the (declared or implicit) scale of the type for this domain. + The scale indicates the number of significant digits to the + right of the decimal point. It can be expressed in decimal + (base 10) or binary (base 2) terms, as specified in the column + numeric_precision_radix. For all other data + types, this column is null. + + + + + + datetime_precision cardinal_number + + + If data_type identifies a date, time, + timestamp, or interval type, this column contains the (declared + or implicit) fractional seconds precision of the type for this + domain, that is, the number of decimal digits maintained + following the decimal point in the seconds value. For all + other data types, this column is null. + + + + + + interval_type character_data + + + If data_type identifies an interval type, + this column contains the specification which fields the + intervals include for this domain, e.g., YEAR TO + MONTH, DAY TO SECOND, etc. If no + field restrictions were specified (that is, the interval + accepts all fields), and for all other data types, this field + is null. + + + + + + interval_precision cardinal_number + + + Applies to a feature not available + in PostgreSQL + (see datetime_precision for the fractional + seconds precision of interval type domains) + + + + + + domain_default character_data + + + Default expression of the domain + + + + + + udt_catalog sql_identifier + + + Name of the database that the domain data type is defined in (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema that the domain data type is defined in + + + + + + udt_name sql_identifier + + + Name of the domain data type + + + + + + scope_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + maximum_cardinality cardinal_number + + + Always null, because arrays always have unlimited maximum cardinality in PostgreSQL + + + + + + dtd_identifier sql_identifier + + + An identifier of the data type descriptor of the domain, unique + among the data type descriptors pertaining to the domain (which + is trivial, because a domain only contains one data type + descriptor). This is mainly useful for joining with other + instances of such identifiers. (The specific format of the + identifier is not defined and not guaranteed to remain the same + in future versions.) + + + + +
+
+ + + <literal>element_types</literal> + + + The view element_types contains the data type + descriptors of the elements of arrays. When a table column, composite-type attribute, + domain, function parameter, or function return value is defined to + be of an array type, the respective information schema view only + contains ARRAY in the column + data_type. To obtain information on the element + type of the array, you can join the respective view with this view. + For example, to show the columns of a table with data types and + array element types, if applicable, you could do: + +SELECT c.column_name, c.data_type, e.data_type AS element_type +FROM information_schema.columns c LEFT JOIN information_schema.element_types e + ON ((c.table_catalog, c.table_schema, c.table_name, 'TABLE', c.dtd_identifier) + = (e.object_catalog, e.object_schema, e.object_name, e.object_type, e.collection_type_identifier)) +WHERE c.table_schema = '...' AND c.table_name = '...' +ORDER BY c.ordinal_position; + + This view only includes objects that the current user has access + to, by way of being the owner or having some privilege. + + + + <structname>element_types</structname> Columns + + + + + Column Type + + + Description + + + + + + + + object_catalog sql_identifier + + + Name of the database that contains the object that uses the + array being described (always the current database) + + + + + + object_schema sql_identifier + + + Name of the schema that contains the object that uses the array + being described + + + + + + object_name sql_identifier + + + Name of the object that uses the array being described + + + + + + object_type character_data + + + The type of the object that uses the array being described: one + of TABLE (the array is used by a column of + that table), USER-DEFINED TYPE (the array is + used by an attribute of that composite type), + DOMAIN (the array is used by that domain), + ROUTINE (the array is used by a parameter or + the return data type of that function). + + + + + + collection_type_identifier sql_identifier + + + The identifier of the data type descriptor of the array being + described. Use this to join with the + dtd_identifier columns of other information + schema views. + + + + + + data_type character_data + + + Data type of the array elements, if it is a built-in type, else + USER-DEFINED (in that case, the type is + identified in udt_name and associated + columns). + + + + + + character_maximum_length cardinal_number + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + character_octet_length cardinal_number + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_catalog sql_identifier + + + Name of the database containing the collation of the element + type (always the current database), null if default or the data + type of the element is not collatable + + + + + + collation_schema sql_identifier + + + Name of the schema containing the collation of the element + type, null if default or the data type of the element is not + collatable + + + + + + collation_name sql_identifier + + + Name of the collation of the element type, null if default or + the data type of the element is not collatable + + + + + + numeric_precision cardinal_number + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + numeric_precision_radix cardinal_number + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + numeric_scale cardinal_number + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + datetime_precision cardinal_number + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + interval_type character_data + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + interval_precision cardinal_number + + + Always null, since this information is not applied to array element data types in PostgreSQL + + + + + + domain_default character_data + + + Not yet implemented + + + + + + udt_catalog sql_identifier + + + Name of the database that the data type of the elements is + defined in (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema that the data type of the elements is + defined in + + + + + + udt_name sql_identifier + + + Name of the data type of the elements + + + + + + scope_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + maximum_cardinality cardinal_number + + + Always null, because arrays always have unlimited maximum cardinality in PostgreSQL + + + + + + dtd_identifier sql_identifier + + + An identifier of the data type descriptor of the element. This + is currently not useful. + + + + +
+
+ + + <literal>enabled_roles</literal> + + + The view enabled_roles identifies the currently + enabled roles. The enabled roles are recursively + defined as the current user together with all roles that have been + granted to the enabled roles with automatic inheritance. In other + words, these are all roles that the current user has direct or + indirect, automatically inheriting membership in. + enabled role + roleenabled + + + + For permission checking, the set of applicable roles + is applied, which can be broader than the set of enabled roles. So + generally, it is better to use the view + applicable_roles instead of this one; See + for details on + applicable_roles view. + + + + <structname>enabled_roles</structname> Columns + + + + + Column Type + + + Description + + + + + + + + role_name sql_identifier + + + Name of a role + + + + +
+
+ + + <literal>foreign_data_wrapper_options</literal> + + + The view foreign_data_wrapper_options contains + all the options defined for foreign-data wrappers in the current + database. Only those foreign-data wrappers are shown that the + current user has access to (by way of being the owner or having + some privilege). + + + + <structname>foreign_data_wrapper_options</structname> Columns + + + + + Column Type + + + Description + + + + + + + + foreign_data_wrapper_catalog sql_identifier + + + Name of the database that the foreign-data wrapper is defined in (always the current database) + + + + + + foreign_data_wrapper_name sql_identifier + + + Name of the foreign-data wrapper + + + + + + option_name sql_identifier + + + Name of an option + + + + + + option_value character_data + + + Value of the option + + + + +
+
+ + + <literal>foreign_data_wrappers</literal> + + + The view foreign_data_wrappers contains all + foreign-data wrappers defined in the current database. Only those + foreign-data wrappers are shown that the current user has access to + (by way of being the owner or having some privilege). + + + + <structname>foreign_data_wrappers</structname> Columns + + + + + Column Type + + + Description + + + + + + + + foreign_data_wrapper_catalog sql_identifier + + + Name of the database that contains the foreign-data + wrapper (always the current database) + + + + + + foreign_data_wrapper_name sql_identifier + + + Name of the foreign-data wrapper + + + + + + authorization_identifier sql_identifier + + + Name of the owner of the foreign server + + + + + + library_name character_data + + + File name of the library that implementing this foreign-data wrapper + + + + + + foreign_data_wrapper_language character_data + + + Language used to implement this foreign-data wrapper + + + + +
+
+ + + <literal>foreign_server_options</literal> + + + The view foreign_server_options contains all the + options defined for foreign servers in the current database. Only + those foreign servers are shown that the current user has access to + (by way of being the owner or having some privilege). + + + + <structname>foreign_server_options</structname> Columns + + + + + Column Type + + + Description + + + + + + + + foreign_server_catalog sql_identifier + + + Name of the database that the foreign server is defined in (always the current database) + + + + + + foreign_server_name sql_identifier + + + Name of the foreign server + + + + + + option_name sql_identifier + + + Name of an option + + + + + + option_value character_data + + + Value of the option + + + + +
+
+ + + <literal>foreign_servers</literal> + + + The view foreign_servers contains all foreign + servers defined in the current database. Only those foreign + servers are shown that the current user has access to (by way of + being the owner or having some privilege). + + + + <structname>foreign_servers</structname> Columns + + + + + Column Type + + + Description + + + + + + + + foreign_server_catalog sql_identifier + + + Name of the database that the foreign server is defined in (always the current database) + + + + + + foreign_server_name sql_identifier + + + Name of the foreign server + + + + + + foreign_data_wrapper_catalog sql_identifier + + + Name of the database that contains the foreign-data + wrapper used by the foreign server (always the current database) + + + + + + foreign_data_wrapper_name sql_identifier + + + Name of the foreign-data wrapper used by the foreign server + + + + + + foreign_server_type character_data + + + Foreign server type information, if specified upon creation + + + + + + foreign_server_version character_data + + + Foreign server version information, if specified upon creation + + + + + + authorization_identifier sql_identifier + + + Name of the owner of the foreign server + + + + +
+
+ + + <literal>foreign_table_options</literal> + + + The view foreign_table_options contains all the + options defined for foreign tables in the current database. Only + those foreign tables are shown that the current user has access to + (by way of being the owner or having some privilege). + + + + <structname>foreign_table_options</structname> Columns + + + + + Column Type + + + Description + + + + + + + + foreign_table_catalog sql_identifier + + + Name of the database that contains the foreign table (always the current database) + + + + + + foreign_table_schema sql_identifier + + + Name of the schema that contains the foreign table + + + + + + foreign_table_name sql_identifier + + + Name of the foreign table + + + + + + option_name sql_identifier + + + Name of an option + + + + + + option_value character_data + + + Value of the option + + + + +
+
+ + + <literal>foreign_tables</literal> + + + The view foreign_tables contains all foreign + tables defined in the current database. Only those foreign + tables are shown that the current user has access to (by way of + being the owner or having some privilege). + + + + <structname>foreign_tables</structname> Columns + + + + + Column Type + + + Description + + + + + + + + foreign_table_catalog sql_identifier + + + Name of the database that the foreign table is defined in (always the current database) + + + + + + foreign_table_schema sql_identifier + + + Name of the schema that contains the foreign table + + + + + + foreign_table_name sql_identifier + + + Name of the foreign table + + + + + + foreign_server_catalog sql_identifier + + + Name of the database that the foreign server is defined in (always the current database) + + + + + + foreign_server_name sql_identifier + + + Name of the foreign server + + + + +
+
+ + + <literal>key_column_usage</literal> + + + The view key_column_usage identifies all columns + in the current database that are restricted by some unique, primary + key, or foreign key constraint. Check constraints are not included + in this view. Only those columns are shown that the current user + has access to, by way of being the owner or having some privilege. + + + + <structname>key_column_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + constraint_catalog sql_identifier + + + Name of the database that contains the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema that contains the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that contains the + column that is restricted by this constraint (always the + current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that contains the + column that is restricted by this constraint + + + + + + table_name sql_identifier + + + Name of the table that contains the column that is restricted + by this constraint + + + + + + column_name sql_identifier + + + Name of the column that is restricted by this constraint + + + + + + ordinal_position cardinal_number + + + Ordinal position of the column within the constraint key (count + starts at 1) + + + + + + position_in_unique_constraint cardinal_number + + + For a foreign-key constraint, ordinal position of the referenced + column within its unique constraint (count starts at 1); + otherwise null + + + + +
+
+ + + <literal>parameters</literal> + + + The view parameters contains information about + the parameters (arguments) of all functions in the current database. + Only those functions are shown that the current user has access to + (by way of being the owner or having some privilege). + + + + <structname>parameters</structname> Columns + + + + + Column Type + + + Description + + + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + + + ordinal_position cardinal_number + + + Ordinal position of the parameter in the argument list of the + function (count starts at 1) + + + + + + parameter_mode character_data + + + IN for input parameter, + OUT for output parameter, + and INOUT for input/output parameter. + + + + + + is_result yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + as_locator yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + parameter_name sql_identifier + + + Name of the parameter, or null if the parameter has no name + + + + + + data_type character_data + + + Data type of the parameter, if it is a built-in type, or + ARRAY if it is some array (in that case, see + the view element_types), else + USER-DEFINED (in that case, the type is + identified in udt_name and associated + columns). + + + + + + character_maximum_length cardinal_number + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + character_octet_length cardinal_number + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_catalog sql_identifier + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + collation_schema sql_identifier + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + collation_name sql_identifier + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + numeric_precision cardinal_number + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + numeric_precision_radix cardinal_number + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + numeric_scale cardinal_number + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + datetime_precision cardinal_number + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + interval_type character_data + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + interval_precision cardinal_number + + + Always null, since this information is not applied to parameter data types in PostgreSQL + + + + + + udt_catalog sql_identifier + + + Name of the database that the data type of the parameter is + defined in (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema that the data type of the parameter is + defined in + + + + + + udt_name sql_identifier + + + Name of the data type of the parameter + + + + + + scope_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + maximum_cardinality cardinal_number + + + Always null, because arrays always have unlimited maximum cardinality in PostgreSQL + + + + + + dtd_identifier sql_identifier + + + An identifier of the data type descriptor of the parameter, + unique among the data type descriptors pertaining to the + function. This is mainly useful for joining with other + instances of such identifiers. (The specific format of the + identifier is not defined and not guaranteed to remain the same + in future versions.) + + + + + + parameter_default character_data + + + The default expression of the parameter, or null if none or if the + function is not owned by a currently enabled role. + + + + +
+
+ + + <literal>referential_constraints</literal> + + + The view referential_constraints contains all + referential (foreign key) constraints in the current database. + Only those constraints are shown for which the current user has + write access to the referencing table (by way of being the + owner or having some privilege other than SELECT). + + + + <structname>referential_constraints</structname> Columns + + + + + Column Type + + + Description + + + + + + + + constraint_catalog sql_identifier + + + Name of the database containing the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema containing the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + + + unique_constraint_catalog sql_identifier + + + Name of the database that contains the unique or primary key + constraint that the foreign key constraint references (always + the current database) + + + + + + unique_constraint_schema sql_identifier + + + Name of the schema that contains the unique or primary key + constraint that the foreign key constraint references + + + + + + unique_constraint_name sql_identifier + + + Name of the unique or primary key constraint that the foreign + key constraint references + + + + + + match_option character_data + + + Match option of the foreign key constraint: + FULL, PARTIAL, or + NONE. + + + + + + update_rule character_data + + + Update rule of the foreign key constraint: + CASCADE, SET NULL, + SET DEFAULT, RESTRICT, or + NO ACTION. + + + + + + delete_rule character_data + + + Delete rule of the foreign key constraint: + CASCADE, SET NULL, + SET DEFAULT, RESTRICT, or + NO ACTION. + + + + +
+ +
+ + + <literal>role_column_grants</literal> + + + The view role_column_grants identifies all + privileges granted on columns where the grantor or grantee is a + currently enabled role. Further information can be found under + column_privileges. The only effective + difference between this view + and column_privileges is that this view omits + columns that have been made accessible to the current user by way + of a grant to PUBLIC. + + + + <structname>role_column_grants</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that contains the column (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that contains the column + + + + + + table_name sql_identifier + + + Name of the table that contains the column + + + + + + column_name sql_identifier + + + Name of the column + + + + + + privilege_type character_data + + + Type of the privilege: SELECT, + INSERT, UPDATE, or + REFERENCES + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>role_routine_grants</literal> + + + The view role_routine_grants identifies all + privileges granted on functions where the grantor or grantee is a + currently enabled role. Further information can be found under + routine_privileges. The only effective + difference between this view + and routine_privileges is that this view omits + functions that have been made accessible to the current user by way + of a grant to PUBLIC. + + + + <structname>role_routine_grants</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + + + routine_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + routine_schema sql_identifier + + + Name of the schema containing the function + + + + + + routine_name sql_identifier + + + Name of the function (might be duplicated in case of overloading) + + + + + + privilege_type character_data + + + Always EXECUTE (the only privilege type for functions) + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>role_table_grants</literal> + + + The view role_table_grants identifies all + privileges granted on tables or views where the grantor or grantee + is a currently enabled role. Further information can be found + under table_privileges. The only effective + difference between this view + and table_privileges is that this view omits + tables that have been made accessible to the current user by way of + a grant to PUBLIC. + + + + <structname>role_table_grants</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + privilege_type character_data + + + Type of the privilege: SELECT, + INSERT, UPDATE, + DELETE, TRUNCATE, + REFERENCES, or TRIGGER + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + + + with_hierarchy yes_or_no + + + In the SQL standard, WITH HIERARCHY OPTION + is a separate (sub-)privilege allowing certain operations on + table inheritance hierarchies. In PostgreSQL, this is included + in the SELECT privilege, so this column + shows YES if the privilege + is SELECT, else NO. + + + + +
+
+ + + <literal>role_udt_grants</literal> + + + The view role_udt_grants is intended to identify + USAGE privileges granted on user-defined types + where the grantor or grantee is a currently enabled role. Further + information can be found under + udt_privileges. The only effective difference + between this view and udt_privileges is that + this view omits objects that have been made accessible to the + current user by way of a grant to PUBLIC. Since + data types do not have real privileges in PostgreSQL, but only an + implicit grant to PUBLIC, this view is empty. + + + + <structname>role_udt_grants</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + The name of the role that granted the privilege + + + + + + grantee sql_identifier + + + The name of the role that the privilege was granted to + + + + + + udt_catalog sql_identifier + + + Name of the database containing the type (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema containing the type + + + + + + udt_name sql_identifier + + + Name of the type + + + + + + privilege_type character_data + + + Always TYPE USAGE + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>role_usage_grants</literal> + + + The view role_usage_grants identifies + USAGE privileges granted on various kinds of + objects where the grantor or grantee is a currently enabled role. + Further information can be found under + usage_privileges. The only effective difference + between this view and usage_privileges is that + this view omits objects that have been made accessible to the + current user by way of a grant to PUBLIC. + + + + <structname>role_usage_grants</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + The name of the role that granted the privilege + + + + + + grantee sql_identifier + + + The name of the role that the privilege was granted to + + + + + + object_catalog sql_identifier + + + Name of the database containing the object (always the current database) + + + + + + object_schema sql_identifier + + + Name of the schema containing the object, if applicable, + else an empty string + + + + + + object_name sql_identifier + + + Name of the object + + + + + + object_type character_data + + + COLLATION or DOMAIN or FOREIGN DATA WRAPPER or FOREIGN SERVER or SEQUENCE + + + + + + privilege_type character_data + + + Always USAGE + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>routine_column_usage</literal> + + + The view routine_column_usage is meant to identify all + columns that are used by a function or procedure. This information is + currently not tracked by PostgreSQL. + + + + <literal>routine_column_usage</literal> Columns + + + + + + Column Type + + + Description + + + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + + + routine_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + routine_schema sql_identifier + + + Name of the schema containing the function + + + + + + routine_name sql_identifier + + + Name of the function (might be duplicated in case of overloading) + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that is used by the + function (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that is used by the function + + + + + + table_name sql_identifier + + + Name of the table that is used by the function + + + + + + column_name sql_identifier + + + Name of the column that is used by the function + + + + +
+
+ + + <literal>routine_privileges</literal> + + + The view routine_privileges identifies all + privileges granted on functions to a currently enabled role or by a + currently enabled role. There is one row for each combination of function, + grantor, and grantee. + + + + <structname>routine_privileges</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + + + routine_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + routine_schema sql_identifier + + + Name of the schema containing the function + + + + + + routine_name sql_identifier + + + Name of the function (might be duplicated in case of overloading) + + + + + + privilege_type character_data + + + Always EXECUTE (the only privilege type for functions) + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>routine_routine_usage</literal> + + + The view routine_routine_usage is meant to identify all + functions or procedures that are used by another (or the same) function or + procedure, either in the body or in parameter default expressions. + Currently, only functions used in parameter default expressions are + tracked. An entry is included here only if the used function is owned by a + currently enabled role. (There is no such restriction on the using + function.) + + + + Note that the entries for both functions in the view refer to the + specific name of the routine, even though the column names + are used in a way that is inconsistent with other information schema views + about routines. This is per SQL standard, although it is arguably a + misdesign. See for more information + about specific names. + + + + <literal>routine_routine_usage</literal> Columns + + + + + + Column Type + + + Description + + + + + + + + specific_catalog sql_identifier + + + Name of the database containing the using function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the using function + + + + + + specific_name sql_identifier + + + The specific name of the using function. + + + + + + routine_catalog sql_identifier + + + Name of the database that contains the function that is used by the + first function (always the current database) + + + + + + routine_schema sql_identifier + + + Name of the schema that contains the function that is used by the first + function + + + + + + routine_name sql_identifier + + + The specific name of the function that is used by the + first function. + + + + +
+
+ + + <literal>routine_sequence_usage</literal> + + + The view routine_sequence_usage is meant to identify all + sequences that are used by a function or procedure, either in the body or + in parameter default expressions. Currently, only sequences used in + parameter default expressions are tracked. A sequence is only included if + that sequence is owned by a currently enabled role. + + + + <literal>routine_sequence_usage</literal> Columns + + + + + + Column Type + + + Description + + + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + + + routine_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + routine_schema sql_identifier + + + Name of the schema containing the function + + + + + + routine_name sql_identifier + + + Name of the function (might be duplicated in case of overloading) + + + + + + schema_catalog sql_identifier + + + Name of the database that contains the sequence that is used by the + function (always the current database) + + + + + + sequence_schema sql_identifier + + + Name of the schema that contains the sequence that is used by the function + + + + + + sequence_name sql_identifier + + + Name of the sequence that is used by the function + + + + +
+
+ + + <literal>routine_table_usage</literal> + + + The view routine_table_usage is meant to identify all + tables that are used by a function or procedure. This information is + currently not tracked by PostgreSQL. + + + + <literal>routine_table_usage</literal> Columns + + + + + + Column Type + + + Description + + + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + + + routine_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + routine_schema sql_identifier + + + Name of the schema containing the function + + + + + + routine_name sql_identifier + + + Name of the function (might be duplicated in case of overloading) + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that is used by the + function (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that is used by the function + + + + + + table_name sql_identifier + + + Name of the table that is used by the function + + + + +
+
+ + + <literal>routines</literal> + + + The view routines contains all functions and procedures in the + current database. Only those functions and procedures are shown that the current + user has access to (by way of being the owner or having some + privilege). + + + + <structname>routines</structname> Columns + + + + + Column Type + + + Description + + + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. This is a + name that uniquely identifies the function in the schema, even + if the real name of the function is overloaded. The format of + the specific name is not defined, it should only be used to + compare it to other instances of specific routine names. + + + + + + routine_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + routine_schema sql_identifier + + + Name of the schema containing the function + + + + + + routine_name sql_identifier + + + Name of the function (might be duplicated in case of overloading) + + + + + + routine_type character_data + + + FUNCTION for a + function, PROCEDURE for a procedure + + + + + + module_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + module_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + module_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + udt_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + udt_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + udt_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + data_type character_data + + + Return data type of the function, if it is a built-in type, or + ARRAY if it is some array (in that case, see + the view element_types), else + USER-DEFINED (in that case, the type is + identified in type_udt_name and associated + columns). Null for a procedure. + + + + + + character_maximum_length cardinal_number + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + character_octet_length cardinal_number + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_catalog sql_identifier + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + collation_schema sql_identifier + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + collation_name sql_identifier + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + numeric_precision cardinal_number + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + numeric_precision_radix cardinal_number + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + numeric_scale cardinal_number + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + datetime_precision cardinal_number + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + interval_type character_data + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + interval_precision cardinal_number + + + Always null, since this information is not applied to return data types in PostgreSQL + + + + + + type_udt_catalog sql_identifier + + + Name of the database that the return data type of the function + is defined in (always the current database). Null for a procedure. + + + + + + type_udt_schema sql_identifier + + + Name of the schema that the return data type of the function is + defined in. Null for a procedure. + + + + + + type_udt_name sql_identifier + + + Name of the return data type of the function. Null for a procedure. + + + + + + scope_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + scope_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + maximum_cardinality cardinal_number + + + Always null, because arrays always have unlimited maximum cardinality in PostgreSQL + + + + + + dtd_identifier sql_identifier + + + An identifier of the data type descriptor of the return data + type of this function, unique among the data type descriptors + pertaining to the function. This is mainly useful for joining + with other instances of such identifiers. (The specific format + of the identifier is not defined and not guaranteed to remain + the same in future versions.) + + + + + + routine_body character_data + + + If the function is an SQL function, then + SQL, else EXTERNAL. + + + + + + routine_definition character_data + + + The source text of the function (null if the function is not + owned by a currently enabled role). (According to the SQL + standard, this column is only applicable if + routine_body is SQL, but + in PostgreSQL it will contain + whatever source text was specified when the function was + created.) + + + + + + external_name character_data + + + If this function is a C function, then the external name (link + symbol) of the function; else null. (This works out to be the + same value that is shown in + routine_definition.) + + + + + + external_language character_data + + + The language the function is written in + + + + + + parameter_style character_data + + + Always GENERAL (The SQL standard defines + other parameter styles, which are not available in PostgreSQL.) + + + + + + is_deterministic yes_or_no + + + If the function is declared immutable (called deterministic in + the SQL standard), then YES, else + NO. (You cannot query the other volatility + levels available in PostgreSQL through the information schema.) + + + + + + sql_data_access character_data + + + Always MODIFIES, meaning that the function + possibly modifies SQL data. This information is not useful for + PostgreSQL. + + + + + + is_null_call yes_or_no + + + If the function automatically returns null if any of its + arguments are null, then YES, else + NO. Null for a procedure. + + + + + + sql_path character_data + + + Applies to a feature not available in PostgreSQL + + + + + + schema_level_routine yes_or_no + + + Always YES (The opposite would be a method + of a user-defined type, which is a feature not available in + PostgreSQL.) + + + + + + max_dynamic_result_sets cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + is_user_defined_cast yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + is_implicitly_invocable yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + security_type character_data + + + If the function runs with the privileges of the current user, + then INVOKER, if the function runs with the + privileges of the user who defined it, then + DEFINER. + + + + + + to_sql_specific_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + to_sql_specific_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + to_sql_specific_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + as_locator yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + created time_stamp + + + Applies to a feature not available in PostgreSQL + + + + + + last_altered time_stamp + + + Applies to a feature not available in PostgreSQL + + + + + + new_savepoint_level yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + is_udt_dependent yes_or_no + + + Currently always NO. The alternative + YES applies to a feature not available in + PostgreSQL. + + + + + + result_cast_from_data_type character_data + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_as_locator yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_char_max_length cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_char_octet_length cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_char_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_char_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_char_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_collation_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_collation_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_collation_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_numeric_precision cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_numeric_precision_radix cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_numeric_scale cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_datetime_precision cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_interval_type character_data + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_interval_precision cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_type_udt_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_type_udt_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_type_udt_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_scope_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_scope_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_scope_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_maximum_cardinality cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + result_cast_dtd_identifier sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + +
+
+ + + <literal>schemata</literal> + + + The view schemata contains all schemas in the current + database that the current user has access to (by way of being the owner or + having some privilege). + + + + <structname>schemata</structname> Columns + + + + + Column Type + + + Description + + + + + + + + catalog_name sql_identifier + + + Name of the database that the schema is contained in (always the current database) + + + + + + schema_name sql_identifier + + + Name of the schema + + + + + + schema_owner sql_identifier + + + Name of the owner of the schema + + + + + + default_character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + default_character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + default_character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + sql_path character_data + + + Applies to a feature not available in PostgreSQL + + + + +
+
+ + + <literal>sequences</literal> + + + The view sequences contains all sequences + defined in the current database. Only those sequences are shown + that the current user has access to (by way of being the owner or + having some privilege). + + + + <structname>sequences</structname> Columns + + + + + Column Type + + + Description + + + + + + + + sequence_catalog sql_identifier + + + Name of the database that contains the sequence (always the current database) + + + + + + sequence_schema sql_identifier + + + Name of the schema that contains the sequence + + + + + + sequence_name sql_identifier + + + Name of the sequence + + + + + + data_type character_data + + + The data type of the sequence. + + + + + + numeric_precision cardinal_number + + + This column contains the (declared or implicit) precision of + the sequence data type (see above). The precision indicates + the number of significant digits. It can be expressed in + decimal (base 10) or binary (base 2) terms, as specified in the + column numeric_precision_radix. + + + + + + numeric_precision_radix cardinal_number + + + This column indicates in which base the values in the columns + numeric_precision and + numeric_scale are expressed. The value is + either 2 or 10. + + + + + + numeric_scale cardinal_number + + + This column contains the (declared or implicit) scale of the + sequence data type (see above). The scale indicates the number + of significant digits to the right of the decimal point. It + can be expressed in decimal (base 10) or binary (base 2) terms, + as specified in the column + numeric_precision_radix. + + + + + + start_value character_data + + + The start value of the sequence + + + + + + minimum_value character_data + + + The minimum value of the sequence + + + + + + maximum_value character_data + + + The maximum value of the sequence + + + + + + increment character_data + + + The increment of the sequence + + + + + + cycle_option yes_or_no + + + YES if the sequence cycles, else NO + + + + +
+ + + Note that in accordance with the SQL standard, the start, minimum, + maximum, and increment values are returned as character strings. + +
+ + + <literal>sql_features</literal> + + + The table sql_features contains information + about which formal features defined in the SQL standard are + supported by PostgreSQL. This is the + same information that is presented in . + There you can also find some additional background information. + + + + <structname>sql_features</structname> Columns + + + + + Column Type + + + Description + + + + + + + + feature_id character_data + + + Identifier string of the feature + + + + + + feature_name character_data + + + Descriptive name of the feature + + + + + + sub_feature_id character_data + + + Identifier string of the subfeature, or a zero-length string if not a subfeature + + + + + + sub_feature_name character_data + + + Descriptive name of the subfeature, or a zero-length string if not a subfeature + + + + + + is_supported yes_or_no + + + YES if the feature is fully supported by the + current version of PostgreSQL, NO if not + + + + + + is_verified_by character_data + + + Always null, since the PostgreSQL development group does not + perform formal testing of feature conformance + + + + + + comments character_data + + + Possibly a comment about the supported status of the feature + + + + +
+
+ + + <literal>sql_implementation_info</literal> + + + The table sql_implementation_info contains + information about various aspects that are left + implementation-defined by the SQL standard. This information is + primarily intended for use in the context of the ODBC interface; + users of other interfaces will probably find this information to be + of little use. For this reason, the individual implementation + information items are not described here; you will find them in the + description of the ODBC interface. + + + + <structname>sql_implementation_info</structname> Columns + + + + + Column Type + + + Description + + + + + + + + implementation_info_id character_data + + + Identifier string of the implementation information item + + + + + + implementation_info_name character_data + + + Descriptive name of the implementation information item + + + + + + integer_value cardinal_number + + + Value of the implementation information item, or null if the + value is contained in the column + character_value + + + + + + character_value character_data + + + Value of the implementation information item, or null if the + value is contained in the column + integer_value + + + + + + comments character_data + + + Possibly a comment pertaining to the implementation information item + + + + +
+
+ + + <literal>sql_parts</literal> + + + The table sql_parts contains information about + which of the several parts of the SQL standard are supported by + PostgreSQL. + + + + <structname>sql_parts</structname> Columns + + + + + Column Type + + + Description + + + + + + + + feature_id character_data + + + An identifier string containing the number of the part + + + + + + feature_name character_data + + + Descriptive name of the part + + + + + + is_supported yes_or_no + + + YES if the part is fully supported by the + current version of PostgreSQL, + NO if not + + + + + + is_verified_by character_data + + + Always null, since the PostgreSQL development group does not + perform formal testing of feature conformance + + + + + + comments character_data + + + Possibly a comment about the supported status of the part + + + + +
+
+ + + <literal>sql_sizing</literal> + + + The table sql_sizing contains information about + various size limits and maximum values in + PostgreSQL. This information is + primarily intended for use in the context of the ODBC interface; + users of other interfaces will probably find this information to be + of little use. For this reason, the individual sizing items are + not described here; you will find them in the description of the + ODBC interface. + + + + <structname>sql_sizing</structname> Columns + + + + + Column Type + + + Description + + + + + + + + sizing_id cardinal_number + + + Identifier of the sizing item + + + + + + sizing_name character_data + + + Descriptive name of the sizing item + + + + + + supported_value cardinal_number + + + Value of the sizing item, or 0 if the size is unlimited or + cannot be determined, or null if the features for which the + sizing item is applicable are not supported + + + + + + comments character_data + + + Possibly a comment pertaining to the sizing item + + + + +
+
+ + + <literal>table_constraints</literal> + + + The view table_constraints contains all + constraints belonging to tables that the current user owns or has + some privilege other than SELECT on. + + + + <structname>table_constraints</structname> Columns + + + + + Column Type + + + Description + + + + + + + + constraint_catalog sql_identifier + + + Name of the database that contains the constraint (always the current database) + + + + + + constraint_schema sql_identifier + + + Name of the schema that contains the constraint + + + + + + constraint_name sql_identifier + + + Name of the constraint + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + constraint_type character_data + + + Type of the constraint: CHECK, + FOREIGN KEY, PRIMARY KEY, + or UNIQUE + + + + + + is_deferrable yes_or_no + + + YES if the constraint is deferrable, NO if not + + + + + + initially_deferred yes_or_no + + + YES if the constraint is deferrable and initially deferred, NO if not + + + + + + enforced yes_or_no + + + Applies to a feature not available in + PostgreSQL (currently always + YES) + + + + +
+
+ + + <literal>table_privileges</literal> + + + The view table_privileges identifies all + privileges granted on tables or views to a currently enabled role + or by a currently enabled role. There is one row for each + combination of table, grantor, and grantee. + + + + <structname>table_privileges</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + privilege_type character_data + + + Type of the privilege: SELECT, + INSERT, UPDATE, + DELETE, TRUNCATE, + REFERENCES, or TRIGGER + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + + + with_hierarchy yes_or_no + + + In the SQL standard, WITH HIERARCHY OPTION + is a separate (sub-)privilege allowing certain operations on + table inheritance hierarchies. In PostgreSQL, this is included + in the SELECT privilege, so this column + shows YES if the privilege + is SELECT, else NO. + + + + +
+
+ + + <literal>tables</literal> + + + The view tables contains all tables and views + defined in the current database. Only those tables and views are + shown that the current user has access to (by way of being the + owner or having some privilege). + + + + <structname>tables</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table + + + + + + table_name sql_identifier + + + Name of the table + + + + + + table_type character_data + + + Type of the table: BASE TABLE for a + persistent base table (the normal table type), + VIEW for a view, FOREIGN + for a foreign table, or + LOCAL TEMPORARY for a temporary table + + + + + + self_referencing_column_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + reference_generation character_data + + + Applies to a feature not available in PostgreSQL + + + + + + user_defined_type_catalog sql_identifier + + + If the table is a typed table, the name of the database that + contains the underlying data type (always the current + database), else null. + + + + + + user_defined_type_schema sql_identifier + + + If the table is a typed table, the name of the schema that + contains the underlying data type, else null. + + + + + + user_defined_type_name sql_identifier + + + If the table is a typed table, the name of the underlying data + type, else null. + + + + + + is_insertable_into yes_or_no + + + YES if the table is insertable into, + NO if not (Base tables are always insertable + into, views not necessarily.) + + + + + + is_typed yes_or_no + + + YES if the table is a typed table, NO if not + + + + + + commit_action character_data + + + Not yet implemented + + + + +
+
+ + + <literal>transforms</literal> + + + The view transforms contains information about the + transforms defined in the current database. More precisely, it contains a + row for each function contained in a transform (the from SQL + or to SQL function). + + + + <structname>transforms</structname> Columns + + + + + Column Type + + + Description + + + + + + + + udt_catalog sql_identifier + + + Name of the database that contains the type the transform is for (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema that contains the type the transform is for + + + + + + udt_name sql_identifier + + + Name of the type the transform is for + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + + + group_name sql_identifier + + + The SQL standard allows defining transforms in groups, + and selecting a group at run time. PostgreSQL does not support this. + Instead, transforms are specific to a language. As a compromise, this + field contains the language the transform is for. + + + + + + transform_type character_data + + + FROM SQL or TO SQL + + + + +
+
+ + + <literal>triggered_update_columns</literal> + + + For triggers in the current database that specify a column list + (like UPDATE OF column1, column2), the + view triggered_update_columns identifies these + columns. Triggers that do not specify a column list are not + included in this view. Only those columns are shown that the + current user owns or has some privilege other than + SELECT on. + + + + <structname>triggered_update_columns</structname> Columns + + + + + Column Type + + + Description + + + + + + + + trigger_catalog sql_identifier + + + Name of the database that contains the trigger (always the current database) + + + + + + trigger_schema sql_identifier + + + Name of the schema that contains the trigger + + + + + + trigger_name sql_identifier + + + Name of the trigger + + + + + + event_object_catalog sql_identifier + + + Name of the database that contains the table that the trigger + is defined on (always the current database) + + + + + + event_object_schema sql_identifier + + + Name of the schema that contains the table that the trigger is defined on + + + + + + event_object_table sql_identifier + + + Name of the table that the trigger is defined on + + + + + + event_object_column sql_identifier + + + Name of the column that the trigger is defined on + + + + +
+
+ + + <literal>triggers</literal> + + + The view triggers contains all triggers defined + in the current database on tables and views that the current user owns + or has some privilege other than SELECT on. + + + + <structname>triggers</structname> Columns + + + + + Column Type + + + Description + + + + + + + + trigger_catalog sql_identifier + + + Name of the database that contains the trigger (always the current database) + + + + + + trigger_schema sql_identifier + + + Name of the schema that contains the trigger + + + + + + trigger_name sql_identifier + + + Name of the trigger + + + + + + event_manipulation character_data + + + Event that fires the trigger (INSERT, + UPDATE, or DELETE) + + + + + + event_object_catalog sql_identifier + + + Name of the database that contains the table that the trigger + is defined on (always the current database) + + + + + + event_object_schema sql_identifier + + + Name of the schema that contains the table that the trigger is defined on + + + + + + event_object_table sql_identifier + + + Name of the table that the trigger is defined on + + + + + + action_order cardinal_number + + + Firing order among triggers on the same table having the same + event_manipulation, + action_timing, and + action_orientation. In + PostgreSQL, triggers are fired in name + order, so this column reflects that. + + + + + + action_condition character_data + + + WHEN condition of the trigger, null if none + (also null if the table is not owned by a currently enabled + role) + + + + + + action_statement character_data + + + Statement that is executed by the trigger (currently always + EXECUTE FUNCTION + function(...)) + + + + + + action_orientation character_data + + + Identifies whether the trigger fires once for each processed + row or once for each statement (ROW or + STATEMENT) + + + + + + action_timing character_data + + + Time at which the trigger fires (BEFORE, + AFTER, or INSTEAD OF) + + + + + + action_reference_old_table sql_identifier + + + Name of the old transition table, or null if none + + + + + + action_reference_new_table sql_identifier + + + Name of the new transition table, or null if none + + + + + + action_reference_old_row sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + action_reference_new_row sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + created time_stamp + + + Applies to a feature not available in PostgreSQL + + + + +
+ + + Triggers in PostgreSQL have two + incompatibilities with the SQL standard that affect the + representation in the information schema. First, trigger names are + local to each table in PostgreSQL, rather + than being independent schema objects. Therefore there can be duplicate + trigger names defined in one schema, so long as they belong to + different tables. (trigger_catalog and + trigger_schema are really the values pertaining + to the table that the trigger is defined on.) Second, triggers can + be defined to fire on multiple events in + PostgreSQL (e.g., ON INSERT OR + UPDATE), whereas the SQL standard only allows one. If a + trigger is defined to fire on multiple events, it is represented as + multiple rows in the information schema, one for each type of + event. As a consequence of these two issues, the primary key of + the view triggers is really + (trigger_catalog, trigger_schema, event_object_table, + trigger_name, event_manipulation) instead of + (trigger_catalog, trigger_schema, trigger_name), + which is what the SQL standard specifies. Nonetheless, if you + define your triggers in a manner that conforms with the SQL + standard (trigger names unique in the schema and only one event + type per trigger), this will not affect you. + + + + + Prior to PostgreSQL 9.1, this view's columns + action_timing, + action_reference_old_table, + action_reference_new_table, + action_reference_old_row, and + action_reference_new_row + were named + condition_timing, + condition_reference_old_table, + condition_reference_new_table, + condition_reference_old_row, and + condition_reference_new_row + respectively. + That was how they were named in the SQL:1999 standard. + The new naming conforms to SQL:2003 and later. + + +
+ + + <literal>udt_privileges</literal> + + + The view udt_privileges identifies + USAGE privileges granted on user-defined types to a + currently enabled role or by a currently enabled role. There is one row for + each combination of type, grantor, and grantee. This view shows only + composite types (see under + for why); see + for domain privileges. + + + + <structname>udt_privileges</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + udt_catalog sql_identifier + + + Name of the database containing the type (always the current database) + + + + + + udt_schema sql_identifier + + + Name of the schema containing the type + + + + + + udt_name sql_identifier + + + Name of the type + + + + + + privilege_type character_data + + + Always TYPE USAGE + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>usage_privileges</literal> + + + The view usage_privileges identifies + USAGE privileges granted on various kinds of + objects to a currently enabled role or by a currently enabled role. + In PostgreSQL, this currently applies to + collations, domains, foreign-data wrappers, foreign servers, and sequences. There is one + row for each combination of object, grantor, and grantee. + + + + Since collations do not have real privileges + in PostgreSQL, this view shows implicit + non-grantable USAGE privileges granted by the + owner to PUBLIC for all collations. The other + object types, however, show real privileges. + + + + In PostgreSQL, sequences also support SELECT + and UPDATE privileges in addition to + the USAGE privilege. These are nonstandard and therefore + not visible in the information schema. + + + + <structname>usage_privileges</structname> Columns + + + + + Column Type + + + Description + + + + + + + + grantor sql_identifier + + + Name of the role that granted the privilege + + + + + + grantee sql_identifier + + + Name of the role that the privilege was granted to + + + + + + object_catalog sql_identifier + + + Name of the database containing the object (always the current database) + + + + + + object_schema sql_identifier + + + Name of the schema containing the object, if applicable, + else an empty string + + + + + + object_name sql_identifier + + + Name of the object + + + + + + object_type character_data + + + COLLATION or DOMAIN or FOREIGN DATA WRAPPER or FOREIGN SERVER or SEQUENCE + + + + + + privilege_type character_data + + + Always USAGE + + + + + + is_grantable yes_or_no + + + YES if the privilege is grantable, NO if not + + + + +
+
+ + + <literal>user_defined_types</literal> + + + The view user_defined_types currently contains + all composite types defined in the current database. + Only those types are shown that the current user has access to (by way + of being the owner or having some privilege). + + + + SQL knows about two kinds of user-defined types: structured types + (also known as composite types + in PostgreSQL) and distinct types (not + implemented in PostgreSQL). To be + future-proof, use the + column user_defined_type_category to + differentiate between these. Other user-defined types such as base + types and enums, which are PostgreSQL + extensions, are not shown here. For domains, + see instead. + + + + <structname>user_defined_types</structname> Columns + + + + + Column Type + + + Description + + + + + + + + user_defined_type_catalog sql_identifier + + + Name of the database that contains the type (always the current database) + + + + + + user_defined_type_schema sql_identifier + + + Name of the schema that contains the type + + + + + + user_defined_type_name sql_identifier + + + Name of the type + + + + + + user_defined_type_category character_data + + + Currently always STRUCTURED + + + + + + is_instantiable yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + is_final yes_or_no + + + Applies to a feature not available in PostgreSQL + + + + + + ordering_form character_data + + + Applies to a feature not available in PostgreSQL + + + + + + ordering_category character_data + + + Applies to a feature not available in PostgreSQL + + + + + + ordering_routine_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + ordering_routine_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + ordering_routine_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + reference_type character_data + + + Applies to a feature not available in PostgreSQL + + + + + + data_type character_data + + + Applies to a feature not available in PostgreSQL + + + + + + character_maximum_length cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + character_octet_length cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + character_set_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_catalog sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_schema sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + collation_name sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + numeric_precision cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + numeric_precision_radix cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + numeric_scale cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + datetime_precision cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + interval_type character_data + + + Applies to a feature not available in PostgreSQL + + + + + + interval_precision cardinal_number + + + Applies to a feature not available in PostgreSQL + + + + + + source_dtd_identifier sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + + + ref_dtd_identifier sql_identifier + + + Applies to a feature not available in PostgreSQL + + + + +
+
+ + + <literal>user_mapping_options</literal> + + + The view user_mapping_options contains all the + options defined for user mappings in the current database. Only + those user mappings are shown where the current user has access to + the corresponding foreign server (by way of being the owner or + having some privilege). + + + + <structname>user_mapping_options</structname> Columns + + + + + Column Type + + + Description + + + + + + + + authorization_identifier sql_identifier + + + Name of the user being mapped, + or PUBLIC if the mapping is public + + + + + + foreign_server_catalog sql_identifier + + + Name of the database that the foreign server used by this + mapping is defined in (always the current database) + + + + + + foreign_server_name sql_identifier + + + Name of the foreign server used by this mapping + + + + + + option_name sql_identifier + + + Name of an option + + + + + + option_value character_data + + + Value of the option. This column will show as null + unless the current user is the user being mapped, or the mapping + is for PUBLIC and the current user is the + server owner, or the current user is a superuser. The intent is + to protect password information stored as user mapping + option. + + + + +
+
+ + + <literal>user_mappings</literal> + + + The view user_mappings contains all user + mappings defined in the current database. Only those user mappings + are shown where the current user has access to the corresponding + foreign server (by way of being the owner or having some + privilege). + + + + <structname>user_mappings</structname> Columns + + + + + Column Type + + + Description + + + + + + + + authorization_identifier sql_identifier + + + Name of the user being mapped, + or PUBLIC if the mapping is public + + + + + + foreign_server_catalog sql_identifier + + + Name of the database that the foreign server used by this + mapping is defined in (always the current database) + + + + + + foreign_server_name sql_identifier + + + Name of the foreign server used by this mapping + + + + +
+
+ + + <literal>view_column_usage</literal> + + + The view view_column_usage identifies all + columns that are used in the query expression of a view (the + SELECT statement that defines the view). A + column is only included if the table that contains the column is + owned by a currently enabled role. + + + + + Columns of system tables are not included. This should be fixed + sometime. + + + + + <structname>view_column_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + view_catalog sql_identifier + + + Name of the database that contains the view (always the current database) + + + + + + view_schema sql_identifier + + + Name of the schema that contains the view + + + + + + view_name sql_identifier + + + Name of the view + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that contains the + column that is used by the view (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that contains the + column that is used by the view + + + + + + table_name sql_identifier + + + Name of the table that contains the column that is used by the + view + + + + + + column_name sql_identifier + + + Name of the column that is used by the view + + + + +
+
+ + + <literal>view_routine_usage</literal> + + + The view view_routine_usage identifies all + routines (functions and procedures) that are used in the query + expression of a view (the SELECT statement that + defines the view). A routine is only included if that routine is + owned by a currently enabled role. + + + + <structname>view_routine_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database containing the view (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema containing the view + + + + + + table_name sql_identifier + + + Name of the view + + + + + + specific_catalog sql_identifier + + + Name of the database containing the function (always the current database) + + + + + + specific_schema sql_identifier + + + Name of the schema containing the function + + + + + + specific_name sql_identifier + + + The specific name of the function. See for more information. + + + + +
+
+ + + <literal>view_table_usage</literal> + + + The view view_table_usage identifies all tables + that are used in the query expression of a view (the + SELECT statement that defines the view). A + table is only included if that table is owned by a currently + enabled role. + + + + + System tables are not included. This should be fixed sometime. + + + + + <structname>view_table_usage</structname> Columns + + + + + Column Type + + + Description + + + + + + + + view_catalog sql_identifier + + + Name of the database that contains the view (always the current database) + + + + + + view_schema sql_identifier + + + Name of the schema that contains the view + + + + + + view_name sql_identifier + + + Name of the view + + + + + + table_catalog sql_identifier + + + Name of the database that contains the table that is + used by the view (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the table that is used by the + view + + + + + + table_name sql_identifier + + + Name of the table that is used by the view + + + + +
+
+ + + <literal>views</literal> + + + The view views contains all views defined in the + current database. Only those views are shown that the current user + has access to (by way of being the owner or having some privilege). + + + + <structname>views</structname> Columns + + + + + Column Type + + + Description + + + + + + + + table_catalog sql_identifier + + + Name of the database that contains the view (always the current database) + + + + + + table_schema sql_identifier + + + Name of the schema that contains the view + + + + + + table_name sql_identifier + + + Name of the view + + + + + + view_definition character_data + + + Query expression defining the view (null if the view is not + owned by a currently enabled role) + + + + + + check_option character_data + + + CASCADED or LOCAL if the view + has a CHECK OPTION defined on it, + NONE if not + + + + + + is_updatable yes_or_no + + + YES if the view is updatable (allows + UPDATE and DELETE), + NO if not + + + + + + is_insertable_into yes_or_no + + + YES if the view is insertable into (allows + INSERT), NO if not + + + + + + is_trigger_updatable yes_or_no + + + YES if the view has an INSTEAD OF + UPDATE trigger defined on it, NO if not + + + + + + is_trigger_deletable yes_or_no + + + YES if the view has an INSTEAD OF + DELETE trigger defined on it, NO if not + + + + + + is_trigger_insertable_into yes_or_no + + + YES if the view has an INSTEAD OF + INSERT trigger defined on it, NO if not + + + + +
+
+ +
diff --git a/doc/src/sgml/install-binaries.sgml b/doc/src/sgml/install-binaries.sgml new file mode 100644 index 000000000000..001c3c7be01f --- /dev/null +++ b/doc/src/sgml/install-binaries.sgml @@ -0,0 +1,24 @@ + + + Installation from Binaries + + + installation + binaries + + + + PostgreSQL is available in the form of binary + packages for most common operating systems today. When available, this is + the recommended way to install PostgreSQL for users of the system. Building + from source (see ) is only recommended for + people developing PostgreSQL or extensions. + + + + For an updated list of platforms providing binary packages, please visit + the download section on the PostgreSQL website at + and follow the + instructions for the specific platform. + + diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml new file mode 100644 index 000000000000..312edc6f7aa3 --- /dev/null +++ b/doc/src/sgml/install-windows.sgml @@ -0,0 +1,521 @@ + + + + Installation from Source Code on <productname>Windows</productname> + + + installation + on Windows + + + + It is recommended that most users download the binary distribution for + Windows, available as a graphical installer package + from the PostgreSQL website at + . Building from source + is only intended for people developing PostgreSQL + or extensions. + + + + There are several different ways of building PostgreSQL on + Windows. The simplest way to build with + Microsoft tools is to install Visual Studio 2019 + and use the included compiler. It is also possible to build with the full + Microsoft Visual C++ 2013 to 2019. + In some cases that requires the installation of the + Windows SDK in addition to the compiler. + + + + It is also possible to build PostgreSQL using the GNU compiler tools + provided by MinGW, or using + Cygwin for older versions of + Windows. + + + + Building using MinGW or + Cygwin uses the normal build system, see + and the specific notes in + and . + To produce native 64 bit binaries in these environments, use the tools from + MinGW-w64. These tools can also be used to + cross-compile for 32 bit and 64 bit Windows + targets on other hosts, such as Linux and + macOS. + Cygwin is not recommended for running a + production server, and it should only be used for running on + older versions of Windows where + the native build does not work. The official + binaries are built using Visual Studio. + + + + Native builds of psql don't support command + line editing. The Cygwin build does support + command line editing, so it should be used where psql is needed for + interactive use on Windows. + + + + Building with <productname>Visual C++</productname> or the + <productname>Microsoft Windows SDK</productname> + + + PostgreSQL can be built using the Visual C++ compiler suite from Microsoft. + These compilers can be either from Visual Studio, + Visual Studio Express or some versions of the + Microsoft Windows SDK. If you do not already have a + Visual Studio environment set up, the easiest + ways are to use the compilers from + Visual Studio 2019 or those in the + Windows SDK 10, which are both free downloads + from Microsoft. + + + + Both 32-bit and 64-bit builds are possible with the Microsoft Compiler suite. + 32-bit PostgreSQL builds are possible with + Visual Studio 2013 to + Visual Studio 2019, + as well as standalone Windows SDK releases 8.1a to 10. + 64-bit PostgreSQL builds are supported with + Microsoft Windows SDK version 8.1a to 10 or + Visual Studio 2013 and above. Compilation + is supported down to Windows 7 and + Windows Server 2008 R2 SP1 when building with + Visual Studio 2013 to + Visual Studio 2019. + + + + + The tools for building using Visual C++ or + Platform SDK are in the + src\tools\msvc directory. When building, make sure + there are no tools from MinGW or + Cygwin present in your system PATH. Also, make + sure you have all the required Visual C++ tools available in the PATH. In + Visual Studio, start the + Visual Studio Command Prompt. + If you wish to build a 64-bit version, you must use the 64-bit version of + the command, and vice versa. + Starting with Visual Studio 2017 this can be + done from the command line using VsDevCmd.bat, see + -help for the available options and their default values. + vsvars32.bat is available in + Visual Studio 2015 and earlier versions for the + same purpose. + From the Visual Studio Command Prompt, you can + change the targeted CPU architecture, build type, and target OS by using the + vcvarsall.bat command, e.g., + vcvarsall.bat x64 10.0.10240.0 to target Windows 10 + with a 64-bit release build. See -help for the other + options of vcvarsall.bat. All commands should be run from + the src\tools\msvc directory. + + + + Before you build, you may need to edit the file config.pl + to reflect any configuration options you want to change, or the paths to + any third party libraries to use. The complete configuration is determined + by first reading and parsing the file config_default.pl, + and then apply any changes from config.pl. For example, + to specify the location of your Python installation, + put the following in config.pl: + +$config->{python} = 'c:\python26'; + + You only need to specify those parameters that are different from what's in + config_default.pl. + + + + If you need to set any other environment variables, create a file called + buildenv.pl and put the required commands there. For + example, to add the path for bison when it's not in the PATH, create a file + containing: + +$ENV{PATH}=$ENV{PATH} . ';c:\some\where\bison\bin'; + + + + + To pass additional command line arguments to the Visual Studio build + command (msbuild or vcbuild): + +$ENV{MSBFLAGS}="/m"; + + + + + Requirements + + The following additional products are required to build + PostgreSQL. Use the + config.pl file to specify which directories the libraries + are available in. + + + + Microsoft Windows SDK + + If your build environment doesn't ship with a supported version of the + Microsoft Windows SDK it + is recommended that you upgrade to the latest version (currently + version 10), available for download from + . + + + You must always include the + Windows Headers and Libraries part of the SDK. + If you install a Windows SDK + including the Visual C++ Compilers, + you don't need Visual Studio to build. + Note that as of Version 8.0a the Windows SDK no longer ships with a + complete command-line build environment. + + + + + ActiveState Perl + + ActiveState Perl is required to run the build generation scripts. MinGW + or Cygwin Perl will not work. It must also be present in the PATH. + Binaries can be downloaded from + + (Note: version 5.8.3 or later is required, + the free Standard Distribution is sufficient). + + + + + + + The following additional products are not required to get started, + but are required to build the complete package. Use the + config.pl file to specify which directories the libraries + are available in. + + + + ActiveState TCL + + Required for building PL/Tcl (Note: version + 8.4 is required, the free Standard Distribution is sufficient). + + + + + Bison and + Flex + + + Bison and Flex are + required to build from Git, but not required when building from a release + file. Only Bison 1.875 or versions 2.2 and later + will work. Flex must be version 2.5.31 or later. + + + + Both Bison and Flex + are included in the msys tool suite, available + from as part of the + MinGW compiler suite. + + + + You will need to add the directory containing + flex.exe and bison.exe to the + PATH environment variable in buildenv.pl unless + they are already in PATH. In the case of MinGW, the directory is the + \msys\1.0\bin subdirectory of your MinGW + installation directory. + + + + + The Bison distribution from GnuWin32 appears to have a bug that + causes Bison to malfunction when installed in a directory with + spaces in the name, such as the default location on English + installations C:\Program Files\GnuWin32. + Consider installing into C:\GnuWin32 or use the + NTFS short name path to GnuWin32 in your PATH environment setting + (e.g., C:\PROGRA~1\GnuWin32). + + + + + + + + Diff + + Diff is required to run the regression tests, and can be downloaded + from . + + + + + Gettext + + Gettext is required to build with NLS support, and can be downloaded + from . Note that binaries, + dependencies and developer files are all needed. + + + + + MIT Kerberos + + Required for GSSAPI authentication support. MIT Kerberos can be + downloaded from + . + + + + + libxml2 and + libxslt + + Required for XML support. Binaries can be downloaded from + or source from + . Note that libxml2 requires iconv, + which is available from the same download location. + + + + + LZ4 + + Required for supporting LZ4 compression + method for compressing the table data. Binaries and source can be + downloaded from + . + + + + + OpenSSL + + Required for SSL support. Binaries can be downloaded from + + or source from . + + + + + ossp-uuid + + Required for UUID-OSSP support (contrib only). Source can be + downloaded from + . + + + + + Python + + Required for building PL/Python. Binaries can + be downloaded from . + + + + + zlib + + Required for compression support in pg_dump + and pg_restore. Binaries can be downloaded + from . + + + + + + + + + Special Considerations for 64-Bit Windows + + + PostgreSQL will only build for the x64 architecture on 64-bit Windows, there + is no support for Itanium processors. + + + + Mixing 32- and 64-bit versions in the same build tree is not supported. + The build system will automatically detect if it's running in a 32- or + 64-bit environment, and build PostgreSQL accordingly. For this reason, it + is important to start the correct command prompt before building. + + + + To use a server-side third party library such as python or + OpenSSL, this library must also be + 64-bit. There is no support for loading a 32-bit library in a 64-bit + server. Several of the third party libraries that PostgreSQL supports may + only be available in 32-bit versions, in which case they cannot be used with + 64-bit PostgreSQL. + + + + + Building + + + To build all of PostgreSQL in release configuration (the default), run the + command: + +build + + To build all of PostgreSQL in debug configuration, run the command: + +build DEBUG + + To build just a single project, for example psql, run the commands: + +build psql +build DEBUG psql + + To change the default build configuration to debug, put the following + in the buildenv.pl file: + +$ENV{CONFIG}="Debug"; + + + + + It is also possible to build from inside the Visual Studio GUI. In this + case, you need to run: + +perl mkvcbuild.pl + + from the command prompt, and then open the generated + pgsql.sln (in the root directory of the source tree) + in Visual Studio. + + + + + Cleaning and Installing + + + Most of the time, the automatic dependency tracking in Visual Studio will + handle changed files. But if there have been large changes, you may need + to clean the installation. To do this, simply run the + clean.bat command, which will automatically clean out + all generated files. You can also run it with the + dist parameter, in which case it will behave like + make distclean and remove the flex/bison output files + as well. + + + + By default, all files are written into a subdirectory of the + debug or release directories. To + install these files using the standard layout, and also generate the files + required to initialize and use the database, run the command: + +install c:\destination\directory + + + + + If you want to install only the client applications and + interface libraries, then you can use these commands: + +install c:\destination\directory client + + + + + + Running the Regression Tests + + + To run the regression tests, make sure you have completed the build of all + required parts first. Also, make sure that the DLLs required to load all + parts of the system (such as the Perl and Python DLLs for the procedural + languages) are present in the system path. If they are not, set it through + the buildenv.pl file. To run the tests, run one of + the following commands from the src\tools\msvc + directory: + +vcregress check +vcregress installcheck +vcregress plcheck +vcregress contribcheck +vcregress modulescheck +vcregress ecpgcheck +vcregress isolationcheck +vcregress bincheck +vcregress recoverycheck +vcregress upgradecheck + + + To change the schedule used (default is parallel), append it to the + command line like: + +vcregress check serial + + + For more information about the regression tests, see + . + + + + Running the regression tests on client programs, with + vcregress bincheck, or on recovery tests, with + vcregress recoverycheck, requires an additional Perl module + to be installed: + + + IPC::Run + + As of this writing, IPC::Run is not included in the + ActiveState Perl installation, nor in the ActiveState Perl Package + Manager (PPM) library. To install, download the + IPC-Run-<version>.tar.gz source archive from CPAN, + at , and + uncompress. Edit the buildenv.pl file, and add a PERL5LIB + variable to point to the lib subdirectory from the + extracted archive. For example: + +$ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; + + + + + + + + The TAP tests run with vcregress support the + environment variables PROVE_TESTS, that is expanded + automatically using the name patterns given, and + PROVE_FLAGS. These can be set on a Windows terminal, + before running vcregress: + +set PROVE_FLAGS=--timer --jobs 2 +set PROVE_TESTS=t/020*.pl t/010*.pl + + It is also possible to set up those parameters in + buildenv.pl: + +$ENV{PROVE_FLAGS}='--timer --jobs 2' +$ENV{PROVE_TESTS}='t/020*.pl t/010*.pl' + + + + + + diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml new file mode 100644 index 000000000000..3c0aa118c76b --- /dev/null +++ b/doc/src/sgml/installation.sgml @@ -0,0 +1,2619 @@ + + + + + Installation from Source Code + + + installation + + + + + This chapter describes the installation of + PostgreSQL using the source code + distribution. If you are installing a pre-packaged distribution, + such as an RPM or Debian package, ignore this chapter + and see instead. + + + + If you are building PostgreSQL for Microsoft + Windows, read this chapter if you intend to build with MinGW or Cygwin; + but if you intend to build with Microsoft's Visual + C++, see instead. + + + + Short Version + + + +./configure +make +su +make install +adduser postgres +mkdir /usr/local/pgsql/data +chown postgres /usr/local/pgsql/data +su - postgres +/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data +/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start +/usr/local/pgsql/bin/createdb test +/usr/local/pgsql/bin/psql test + + The long version is the rest of this + chapter. + + + + + + Requirements + + + In general, a modern Unix-compatible platform should be able to run + PostgreSQL. + The platforms that had received specific testing at the + time of release are described in + below. + + + + The following software packages are required for building + PostgreSQL: + + + + + + make + + + GNU make version 3.80 or newer is required; other + make programs or older GNU make versions will not work. + (GNU make is sometimes installed under + the name gmake.) To test for GNU + make enter: + +make --version + + + + + + + You need an ISO/ANSI C compiler (at least + C99-compliant). Recent + versions of GCC are recommended, but + PostgreSQL is known to build using a wide variety + of compilers from different vendors. + + + + + + tar is required to unpack the source + distribution, in addition to either + gzip or bzip2. + + + + + + + readline + + + libedit + + + The GNU Readline library is used by + default. It allows psql (the + PostgreSQL command line SQL interpreter) to remember each + command you type, and allows you to use arrow keys to recall and + edit previous commands. This is very helpful and is strongly + recommended. If you don't want to use it then you must specify + the option to + configure. As an alternative, you can often use the + BSD-licensed libedit library, originally + developed on NetBSD. The + libedit library is + GNU Readline-compatible and is used if + libreadline is not found, or if + is used as an + option to configure. If you are using a package-based + Linux distribution, be aware that you need both the + readline and readline-devel packages, if + those are separate in your distribution. + + + + + + + zlib + + + The zlib compression library is + used by default. If you don't want to use it then you must + specify the option to + configure. Using this option disables + support for compressed archives in pg_dump and + pg_restore. + + + + + + + The following packages are optional. They are not required in the + default configuration, but they are needed when certain build + options are enabled, as explained below: + + + + + To build the server programming language + PL/Perl you need a full + Perl installation, including the + libperl library and the header files. + The minimum required version is Perl 5.8.3. + Since PL/Perl will be a shared + library, the libperl + libperl library must be a shared library + also on most platforms. This appears to be the default in + recent Perl versions, but it was not + in earlier versions, and in any case it is the choice of whomever + installed Perl at your site. configure will fail + if building PL/Perl is selected but it cannot + find a shared libperl. In that case, you will have + to rebuild and install Perl manually to be + able to build PL/Perl. During the + configuration process for Perl, request a + shared library. + + + + If you intend to make more than incidental use of + PL/Perl, you should ensure that the + Perl installation was built with the + usemultiplicity option enabled (perl -V + will show whether this is the case). + + + + + + To build the PL/Python server programming + language, you need a Python + installation with the header files and + the distutils module. The minimum + required version is Python 2.6. + Python 3 is supported if it's + version 3.1 or later; but see + + when using Python 3. + + + + Since PL/Python will be a shared + library, the libpython + libpython library must be a shared library + also on most platforms. This is not the case in a default + Python installation built from source, but a + shared library is available in many operating system + distributions. configure will fail if + building PL/Python is selected but it cannot + find a shared libpython. That might mean that you + either have to install additional packages or rebuild (part of) your + Python installation to provide this shared + library. When building from source, run Python's + configure with the --enable-shared flag. + + + + + + To build the PL/Tcl + procedural language, you of course need a Tcl + installation. The minimum required version is + Tcl 8.4. + + + + + + To enable Native Language Support (NLS), that + is, the ability to display a program's messages in a language + other than English, you need an implementation of the + Gettext API. Some operating + systems have this built-in (e.g., Linux, NetBSD, + Solaris), for other systems you + can download an add-on package from . + If you are using the Gettext implementation in + the GNU C library then you will additionally + need the GNU Gettext package for some + utility programs. For any of the other implementations you will + not need it. + + + + + + You need OpenSSL, if you want to support + encrypted client connections. OpenSSL is + also required for random number generation on platforms that do not + have /dev/urandom (except Windows). The minimum + version required is 1.0.1. + + + + + + You need Kerberos, OpenLDAP, + and/or PAM, if you want to support authentication + using those services. + + + + + + You need LZ4, if you want to support + compression of data with this method; see + . + + + + + + To build the PostgreSQL documentation, + there is a separate set of requirements; see + . + + + + + + + If you are building from a Git tree instead of + using a released source package, or if you want to do server development, + you also need the following packages: + + + + + + flex + + + lex + + + bison + + + yacc + + + Flex and Bison + are needed to build from a Git checkout, or if you changed the actual + scanner and parser definition files. If you need them, be sure + to get Flex 2.5.31 or later and + Bison 1.875 or later. Other lex + and yacc programs cannot be used. + + + + + + perl + + + Perl 5.8.3 or later is needed to build from a Git checkout, + or if you changed the input files for any of the build steps that + use Perl scripts. If building on Windows you will need + Perl in any case. Perl is + also required to run some test suites. + + + + + + + If you need to get a GNU package, you can find + it at your local GNU mirror site (see + for a list) or at . + + + + Also check that you have sufficient disk space. You will need about + 350 MB for the source tree during compilation and about 60 MB for + the installation directory. An empty database cluster takes about + 40 MB; databases take about five times the amount of space that a + flat text file with the same data would take. If you are going to + run the regression tests you will temporarily need up to an extra + 300 MB. Use the df command to check free disk + space. + + + + + Getting the Source + + + The PostgreSQL &version; sources can be obtained from the + download section of our + website: . You + should get a file named postgresql-&version;.tar.gz + or postgresql-&version;.tar.bz2. After + you have obtained the file, unpack it: + +gunzip postgresql-&version;.tar.gz +tar xf postgresql-&version;.tar + + (Use bunzip2 instead of gunzip if + you have the .bz2 file. Also, note that most + modern versions of tar can unpack compressed archives + directly, so you don't really need the + separate gunzip or bunzip2 step.) + This will create a directory + postgresql-&version; under the current directory + with the PostgreSQL sources. + Change into that directory for the rest + of the installation procedure. + + + + You can also get the source directly from the version control repository, see + . + + + + + Installation Procedure + + + + + Configuration + + + configure + + + + The first step of the installation procedure is to configure the + source tree for your system and choose the options you would like. + This is done by running the configure script. For a + default installation simply enter: + +./configure + + This script will run a number of tests to determine values for various + system dependent variables and detect any quirks of your + operating system, and finally will create several files in the + build tree to record what it found. + + + + You can also run configure in a directory outside + the source tree, and then build there, if you want to keep the build + directory separate from the original source files. This procedure is + called a + VPATHVPATH + build. Here's how: + +mkdir build_dir +cd build_dir +/path/to/source/tree/configure [options go here] +make + + + + + The default configuration will build the server and utilities, as + well as all client applications and interfaces that require only a + C compiler. All files will be installed under + /usr/local/pgsql by default. + + + + You can customize the build and installation process by supplying one + or more command line options to configure. + Typically you would customize the install location, or the set of + optional features that are built. configure + has a large number of options, which are described in + . + + + + Also, configure responds to certain environment + variables, as described in . + These provide additional ways to customize the configuration. + + + + + Build + + + To start the build, type either of: + +make +make all + + (Remember to use GNU make.) + The build will take a few minutes depending on your + hardware. The last line displayed should be: + +All of PostgreSQL successfully made. Ready to install. + + + + + If you want to build everything that can be built, including the + documentation (HTML and man pages), and the additional modules + (contrib), type instead: + +make world + + The last line displayed should be: + +PostgreSQL, contrib, and documentation successfully made. Ready to install. + + + + + If you want to invoke the build from another makefile rather than + manually, you must unset MAKELEVEL or set it to zero, + for instance like this: + +build-postgresql: + $(MAKE) -C postgresql MAKELEVEL=0 all + + Failure to do that can lead to strange error messages, typically about + missing header files. + + + + + Regression Tests + + + regression test + + + + If you want to test the newly built server before you install it, + you can run the regression tests at this point. The regression + tests are a test suite to verify that PostgreSQL + runs on your machine in the way the developers expected it + to. Type: + +make check + + (This won't work as root; do it as an unprivileged user.) + See for + detailed information about interpreting the test results. You can + repeat this test at any later time by issuing the same command. + + + + + Installing the Files + + + + If you are upgrading an existing system be sure to read + , + which has instructions about upgrading a + cluster. + + + + + To install PostgreSQL enter: + +make install + + This will install files into the directories that were specified + in . Make sure that you have appropriate + permissions to write into that area. Normally you need to do this + step as root. Alternatively, you can create the target + directories in advance and arrange for appropriate permissions to + be granted. + + + + To install the documentation (HTML and man pages), enter: + +make install-docs + + + + + If you built the world above, type instead: + +make install-world + + This also installs the documentation. + + + + You can use make install-strip instead of + make install to strip the executable files and + libraries as they are installed. This will save some space. If + you built with debugging support, stripping will effectively + remove the debugging support, so it should only be done if + debugging is no longer needed. install-strip + tries to do a reasonable job saving space, but it does not have + perfect knowledge of how to strip every unneeded byte from an + executable file, so if you want to save all the disk space you + possibly can, you will have to do manual work. + + + + The standard installation provides all the header files needed for client + application development as well as for server-side program + development, such as custom functions or data types written in C. + + + + Client-only installation: + + If you want to install only the client applications and + interface libraries, then you can use these commands: + +make -C src/bin install +make -C src/include install +make -C src/interfaces install +make -C doc install + + src/bin has a few binaries for server-only use, + but they are small. + + + + + + + Uninstallation: + + To undo the installation use the command make + uninstall. However, this will not remove any created directories. + + + + + Cleaning: + + + After the installation you can free disk space by removing the built + files from the source tree with the command make + clean. This will preserve the files made by the configure + program, so that you can rebuild everything with make + later on. To reset the source tree to the state in which it was + distributed, use make distclean. If you are going to + build for several platforms within the same source tree you must do + this and re-configure for each platform. (Alternatively, use + a separate build tree for each platform, so that the source tree + remains unmodified.) + + + + + If you perform a build and then discover that your configure + options were wrong, or if you change anything that configure + investigates (for example, software upgrades), then it's a good + idea to do make distclean before reconfiguring and + rebuilding. Without this, your changes in configuration choices + might not propagate everywhere they need to. + + + + <filename>configure</filename> Options + + + configure options + + + + configure's command line options are explained below. + This list is not exhaustive (use ./configure --help + to get one that is). The options not covered here are meant for + advanced use-cases such as cross-compilation, and are documented in + the standard Autoconf documentation. + + + + Installation Locations + + + These options control where make install will put + the files. The option is sufficient for + most cases. If you have special needs, you can customize the + installation subdirectories with the other options described in this + section. Beware however that changing the relative locations of the + different subdirectories may render the installation non-relocatable, + meaning you won't be able to move it after installation. + (The man and doc locations are + not affected by this restriction.) For relocatable installs, you + might want to use the --disable-rpath option + described later. + + + + + + + + Install all files under the directory PREFIX + instead of /usr/local/pgsql. The actual + files will be installed into various subdirectories; no files + will ever be installed directly into the + PREFIX directory. + + + + + + + + + You can install architecture-dependent files under a + different prefix, EXEC-PREFIX, than what + PREFIX was set to. This can be useful to + share architecture-independent files between hosts. If you + omit this, then EXEC-PREFIX is set equal to + PREFIX and both architecture-dependent and + independent files will be installed under the same tree, + which is probably what you want. + + + + + + + + + Specifies the directory for executable programs. The default + is EXEC-PREFIX/bin, which + normally means /usr/local/pgsql/bin. + + + + + + + + + Sets the directory for various configuration files, + PREFIX/etc by default. + + + + + + + + + Sets the location to install libraries and dynamically loadable + modules. The default is + EXEC-PREFIX/lib. + + + + + + + + + Sets the directory for installing C and C++ header files. The + default is PREFIX/include. + + + + + + + + + Sets the root directory for various types of read-only data + files. This only sets the default for some of the following + options. The default is + PREFIX/share. + + + + + + + + + Sets the directory for read-only data files used by the + installed programs. The default is + DATAROOTDIR. Note that this has + nothing to do with where your database files will be placed. + + + + + + + + + Sets the directory for installing locale data, in particular + message translation catalog files. The default is + DATAROOTDIR/locale. + + + + + + + + + The man pages that come with PostgreSQL will be installed under + this directory, in their respective + manx subdirectories. + The default is DATAROOTDIR/man. + + + + + + + + + Sets the root directory for installing documentation files, + except man pages. This only sets the default for + the following options. The default value for this option is + DATAROOTDIR/doc/postgresql. + + + + + + + + + The HTML-formatted documentation for + PostgreSQL will be installed under + this directory. The default is + DATAROOTDIR. + + + + + + + + Care has been taken to make it possible to install + PostgreSQL into shared installation locations + (such as /usr/local/include) without + interfering with the namespace of the rest of the system. First, + the string /postgresql is + automatically appended to datadir, + sysconfdir, and docdir, + unless the fully expanded directory name already contains the + string postgres or + pgsql. For example, if you choose + /usr/local as prefix, the documentation will + be installed in /usr/local/doc/postgresql, + but if the prefix is /opt/postgres, then it + will be in /opt/postgres/doc. The public C + header files of the client interfaces are installed into + includedir and are namespace-clean. The + internal header files and the server header files are installed + into private directories under includedir. See + the documentation of each interface for information about how to + access its header files. Finally, a private subdirectory will + also be created, if appropriate, under libdir + for dynamically loadable modules. + + + + + + + <productname>PostgreSQL</productname> Features + + + The options described in this section enable building of + various PostgreSQL features that are not + built by default. Most of these are non-default only because they + require additional software, as described in + . + + + + + + + + + Enables Native Language Support (NLS), + that is, the ability to display a program's messages in a + language other than English. + LANGUAGES is an optional space-separated + list of codes of the languages that you want supported, for + example --enable-nls='de fr'. (The intersection + between your list and the set of actually provided + translations will be computed automatically.) If you do not + specify a list, then all available translations are + installed. + + + + To use this option, you will need an implementation of the + Gettext API. + + + + + + + + + Build the PL/Perl server-side language. + + + + + + + + + Build the PL/Python server-side language. + + + + + + + + + Build the PL/Tcl server-side language. + + + + + + + + + Tcl installs the file tclConfig.sh, which + contains configuration information needed to build modules + interfacing to Tcl. This file is normally found automatically + at a well-known location, but if you want to use a different + version of Tcl you can specify the directory in which to look + for tclConfig.sh. + + + + + + + + + Build with support for + the ICUICU + library, enabling use of ICU collation + features (see + ). + This requires the ICU4C package + to be installed. The minimum required version + of ICU4C is currently 4.2. + + + + By default, + pkg-configpkg-config + will be used to find the required compilation options. This is + supported for ICU4C version 4.6 and later. + For older versions, or if pkg-config is + not available, the variables ICU_CFLAGS + and ICU_LIBS can be specified + to configure, like in this example: + +./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' + + (If ICU4C is in the default search path + for the compiler, then you still need to specify nonempty strings in + order to avoid use of pkg-config, for + example, ICU_CFLAGS=' '.) + + + + + + + + + Build with support for LLVM based + JIT compilation (see ). This + requires the LLVM library to be installed. + The minimum required version of LLVM is + currently 3.9. + + + llvm-configllvm-config + will be used to find the required compilation options. + llvm-config, and then + llvm-config-$major-$minor for all supported + versions, will be searched for in your PATH. If + that would not yield the desired program, + use LLVM_CONFIG to specify a path to the + correct llvm-config. For example + +./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config' + + + + + LLVM support requires a compatible + clang compiler (specified, if necessary, using the + CLANG environment variable), and a working C++ + compiler (specified, if necessary, using the CXX + environment variable). + + + + + + + + + Build with LZ4 compression support. + This allows the use of LZ4 for + compression of table data. + + + + + + + + OpenSSL + SSL + + + + + Build with support for SSL (encrypted) + connections. The only LIBRARY + supported is . This requires the + OpenSSL package to be installed. + configure will check for the required + header files and libraries to make sure that your + OpenSSL installation is sufficient + before proceeding. + + + + + + + + + Obsolete equivalent of --with-ssl=openssl. + + + + + + + + + Build with support for GSSAPI authentication. On many systems, the + GSSAPI system (usually a part of the Kerberos installation) is not + installed in a location + that is searched by default (e.g., /usr/include, + /usr/lib), so you must use the options + and in + addition to this option. configure will check + for the required header files and libraries to make sure that + your GSSAPI installation is sufficient before proceeding. + + + + + + + + + Build with LDAPLDAP + support for authentication and connection parameter lookup (see + and + for more information). On Unix, + this requires the OpenLDAP package to be + installed. On Windows, the default WinLDAP + library is used. configure will check for the required + header files and libraries to make sure that your + OpenLDAP installation is sufficient before + proceeding. + + + + + + + + + Build with PAMPAM + (Pluggable Authentication Modules) support. + + + + + + + + + Build with BSD Authentication support. + (The BSD Authentication framework is + currently only available on OpenBSD.) + + + + + + + + + Build with support + for systemdsystemd + service notifications. This improves integration if the server + is started under systemd but has no impact + otherwise; see for more + information. libsystemd and the + associated header files need to be installed to use this option. + + + + + + + + + Build with support for Bonjour automatic service discovery. + This requires Bonjour support in your operating system. + Recommended on macOS. + + + + + + + + + Build the module + (which provides functions to generate UUIDs), using the specified + UUID library.UUID + LIBRARY must be one of: + + + + + to use the UUID functions found in FreeBSD, NetBSD, + and some other BSD-derived systems + + + + + to use the UUID library created by + the e2fsprogs project; this library is present in most + Linux systems and in macOS, and can be obtained for other + platforms as well + + + + + to use the OSSP UUID library + + + + + + + + + + + Obsolete equivalent of --with-uuid=ossp. + + + + + + + + + Build with libxml2, enabling SQL/XML support. Libxml2 version 2.6.23 or + later is required for this feature. + + + + To detect the required compiler and linker options, PostgreSQL will + query pkg-config, if that is installed and knows + about libxml2. Otherwise the program xml2-config, + which is installed by libxml2, will be used if it is found. Use + of pkg-config is preferred, because it can deal + with multi-architecture installations better. + + + + To use a libxml2 installation that is in an unusual location, you + can set pkg-config-related environment + variables (see its documentation), or set the environment variable + XML2_CONFIG to point to + the xml2-config program belonging to the libxml2 + installation, or set the variables XML2_CFLAGS + and XML2_LIBS. (If pkg-config is + installed, then to override its idea of where libxml2 is you must + either set XML2_CONFIG or set + both XML2_CFLAGS and XML2_LIBS to + nonempty strings.) + + + + + + + + + Build with libxslt, enabling the + + module to perform XSL transformations of XML. + must be specified as well. + + + + + + + + + + Anti-Features + + + The options described in this section allow disabling + certain PostgreSQL features that are built + by default, but which might need to be turned off if the required + software or system features are not available. Using these options is + not recommended unless really necessary. + + + + + + + + + Prevents use of the Readline library + (and libedit as well). This option disables + command-line editing and history in + psql. + + + + + + + + + Favors the use of the BSD-licensed libedit library + rather than GPL-licensed Readline. This option + is significant only if you have both libraries installed; the + default in that case is to use Readline. + + + + + + + + + + zlib + + Prevents use of the Zlib library. + This disables + support for compressed archives in pg_dump + and pg_restore. + + + + + + + + + Allow the build to succeed even if PostgreSQL + has no CPU spinlock support for the platform. The lack of + spinlock support will result in very poor performance; therefore, + this option should only be used if the build aborts and + informs you that the platform lacks spinlock support. If this + option is required to build PostgreSQL on + your platform, please report the problem to the + PostgreSQL developers. + + + + + + + + + Disable use of CPU atomic operations. This option does nothing on + platforms that lack such operations. On platforms that do have + them, this will result in poor performance. This option is only + useful for debugging or making performance comparisons. + + + + + + + + + Disable the thread-safety of client libraries. This prevents + concurrent threads in libpq and + ECPG programs from safely controlling + their private connection handles. Use this only on platforms + with deficient threading support. + + + + + + + + + + Build Process Details + + + + + + + + DIRECTORIES is a colon-separated list of + directories that will be added to the list the compiler + searches for header files. If you have optional packages + (such as GNU Readline) installed in a non-standard + location, + you have to use this option and probably also the corresponding + option. + + + Example: --with-includes=/opt/gnu/include:/usr/sup/include. + + + + + + + + + DIRECTORIES is a colon-separated list of + directories to search for libraries. You will probably have + to use this option (and the corresponding + option) if you have packages + installed in non-standard locations. + + + Example: --with-libraries=/opt/gnu/lib:/usr/sup/lib. + + + + + + + + time zone data + + + + + PostgreSQL includes its own time zone database, + which it requires for date and time operations. This time zone + database is in fact compatible with the IANA time zone + database provided by many operating systems such as FreeBSD, + Linux, and Solaris, so it would be redundant to install it again. + When this option is used, the system-supplied time zone database + in DIRECTORY is used instead of the one + included in the PostgreSQL source distribution. + DIRECTORY must be specified as an + absolute path. /usr/share/zoneinfo is a + likely directory on some operating systems. Note that the + installation routine will not detect mismatching or erroneous time + zone data. If you use this option, you are advised to run the + regression tests to verify that the time zone data you have + pointed to works correctly with PostgreSQL. + + + cross compilation + + + This option is mainly aimed at binary package distributors + who know their target operating system well. The main + advantage of using this option is that the PostgreSQL package + won't need to be upgraded whenever any of the many local + daylight-saving time rules change. Another advantage is that + PostgreSQL can be cross-compiled more straightforwardly if the + time zone database files do not need to be built during the + installation. + + + + + + + + + Append STRING to the PostgreSQL version number. You + can use this, for example, to mark binaries built from unreleased Git + snapshots or containing custom patches with an extra version string, + such as a git describe identifier or a + distribution package release number. + + + + + + + + + Do not mark PostgreSQL's executables + to indicate that they should search for shared libraries in the + installation's library directory (see ). + On most platforms, this marking uses an absolute path to the + library directory, so that it will be unhelpful if you relocate + the installation later. However, you will then need to provide + some other way for the executables to find the shared libraries. + Typically this requires configuring the operating system's + dynamic linker to search the library directory; see + for more detail. + + + + + + + + + + Miscellaneous + + + It's fairly common, particularly for test builds, to adjust the + default port number with . + The other options in this section are recommended only for advanced + users. + + + + + + + + + Set NUMBER as the default port number for + server and clients. The default is 5432. The port can always + be changed later on, but if you specify it here then both + server and clients will have the same default compiled in, + which can be very convenient. Usually the only good reason + to select a non-default value is if you intend to run multiple + PostgreSQL servers on the same machine. + + + + + + + + + The default name of the Kerberos service principal used + by GSSAPI. + postgres is the default. There's usually no + reason to change this unless you are building for a Windows + environment, in which case it must be set to upper case + POSTGRES. + + + + + + + + + Set the segment size, in gigabytes. Large tables are + divided into multiple operating-system files, each of size equal + to the segment size. This avoids problems with file size limits + that exist on many platforms. The default segment size, 1 gigabyte, + is safe on all supported platforms. If your operating system has + largefile support (which most do, nowadays), you can use + a larger segment size. This can be helpful to reduce the number of + file descriptors consumed when working with very large tables. + But be careful not to select a value larger than is supported + by your platform and the file systems you intend to use. Other + tools you might wish to use, such as tar, could + also set limits on the usable file size. + It is recommended, though not absolutely required, that this value + be a power of 2. + Note that changing this value breaks on-disk database compatibility, + meaning you cannot use pg_upgrade to upgrade to + a build with a different segment size. + + + + + + + + + Set the block size, in kilobytes. This is the unit + of storage and I/O within tables. The default, 8 kilobytes, + is suitable for most situations; but other values may be useful + in special cases. + The value must be a power of 2 between 1 and 32 (kilobytes). + Note that changing this value breaks on-disk database compatibility, + meaning you cannot use pg_upgrade to upgrade to + a build with a different block size. + + + + + + + + + Set the WAL block size, in kilobytes. This is the unit + of storage and I/O within the WAL log. The default, 8 kilobytes, + is suitable for most situations; but other values may be useful + in special cases. + The value must be a power of 2 between 1 and 64 (kilobytes). + Note that changing this value breaks on-disk database compatibility, + meaning you cannot use pg_upgrade to upgrade to + a build with a different WAL block size. + + + + + + + + + + Developer Options + + + Most of the options in this section are only of interest for + developing or debugging PostgreSQL. + They are not recommended for production builds, except + for , which can be useful to enable + detailed bug reports in the unlucky event that you encounter a bug. + On platforms supporting DTrace, + may also be reasonable to use in production. + + + + When building an installation that will be used to develop code inside + the server, it is recommended to use at least the + options + and . + + + + + + + + + Compiles all programs and libraries with debugging symbols. + This means that you can run the programs in a debugger + to analyze problems. This enlarges the size of the installed + executables considerably, and on non-GCC compilers it usually + also disables compiler optimization, causing slowdowns. However, + having the symbols available is extremely helpful for dealing + with any problems that might arise. Currently, this option is + recommended for production installations only if you use GCC. + But you should always have it on if you are doing development work + or running a beta version. + + + + + + + + + Enables assertion checks in the server, which test for + many cannot happen conditions. This is invaluable for + code development purposes, but the tests can slow down the + server significantly. + Also, having the tests turned on won't necessarily enhance the + stability of your server! The assertion checks are not categorized + for severity, and so what might be a relatively harmless bug will + still lead to server restarts if it triggers an assertion + failure. This option is not recommended for production use, but + you should have it on for development work or when running a beta + version. + + + + + + + + + Enable tests using the Perl TAP tools. This requires a Perl + installation and the Perl module IPC::Run. + See for more information. + + + + + + + + + Enables automatic dependency tracking. With this option, the + makefiles are set up so that all affected object files will + be rebuilt when any header file is changed. This is useful + if you are doing development work, but is just wasted overhead + if you intend only to compile once and install. At present, + this option only works with GCC. + + + + + + + + + If using GCC, all programs and libraries are compiled with + code coverage testing instrumentation. When run, they + generate files in the build directory with code coverage + metrics. + See + for more information. This option is for use only with GCC + and when doing development work. + + + + + + + + + If using GCC, all programs and libraries are compiled so they + can be profiled. On backend exit, a subdirectory will be created + that contains the gmon.out file containing + profile data. + This option is for use only with GCC and when doing development work. + + + + + + + + + + DTrace + + Compiles PostgreSQL with support for the + dynamic tracing tool DTrace. + See + for more information. + + + + To point to the dtrace program, the + environment variable DTRACE can be set. This + will often be necessary because dtrace is + typically installed under /usr/sbin, + which might not be in your PATH. + + + + Extra command-line options for the dtrace program + can be specified in the environment variable + DTRACEFLAGS. On Solaris, + to include DTrace support in a 64-bit binary, you must specify + DTRACEFLAGS="-64". For example, + using the GCC compiler: + +./configure CC='gcc -m64' --enable-dtrace DTRACEFLAGS='-64' ... + + Using Sun's compiler: + +./configure CC='/opt/SUNWspro/bin/cc -xtarget=native64' --enable-dtrace DTRACEFLAGS='-64' ... + + + + + + + + + + + + <filename>configure</filename> Environment Variables + + + configure environment variables + + + + In addition to the ordinary command-line options described above, + configure responds to a number of environment + variables. + You can specify environment variables on the + configure command line, for example: + +./configure CC=/opt/bin/gcc CFLAGS='-O2 -pipe' + + In this usage an environment variable is little different from a + command-line option. + You can also set such variables beforehand: + +export CC=/opt/bin/gcc +export CFLAGS='-O2 -pipe' +./configure + + This usage can be convenient because many programs' configuration + scripts respond to these variables in similar ways. + + + + The most commonly used of these environment variables are + CC and CFLAGS. + If you prefer a C compiler different from the one + configure picks, you can set the + variable CC to the program of your choice. + By default, configure will pick + gcc if available, else the platform's + default (usually cc). Similarly, you can override the + default compiler flags if needed with the CFLAGS variable. + + + + Here is a list of the significant variables that can be set in + this manner: + + + + BISON + + + Bison program + + + + + + CC + + + C compiler + + + + + + CFLAGS + + + options to pass to the C compiler + + + + + + CLANG + + + path to clang program used to process source code + for inlining when compiling with --with-llvm + + + + + + CPP + + + C preprocessor + + + + + + CPPFLAGS + + + options to pass to the C preprocessor + + + + + + CXX + + + C++ compiler + + + + + + CXXFLAGS + + + options to pass to the C++ compiler + + + + + + DTRACE + + + location of the dtrace program + + + + + + DTRACEFLAGS + + + options to pass to the dtrace program + + + + + + FLEX + + + Flex program + + + + + + LDFLAGS + + + options to use when linking either executables or shared libraries + + + + + + LDFLAGS_EX + + + additional options for linking executables only + + + + + + LDFLAGS_SL + + + additional options for linking shared libraries only + + + + + + LLVM_CONFIG + + + llvm-config program used to locate the + LLVM installation + + + + + + MSGFMT + + + msgfmt program for native language support + + + + + + PERL + + + Perl interpreter program. This will be used to determine the + dependencies for building PL/Perl. The default is + perl. + + + + + + PYTHON + + + Python interpreter program. This will be used to + determine the dependencies for building PL/Python. Also, + whether Python 2 or 3 is specified here (or otherwise + implicitly chosen) determines which variant of the PL/Python + language becomes available. See + + for more information. If this is not set, the following are probed + in this order: python python3 python2. + + + + + + TCLSH + + + Tcl interpreter program. This will be used to + determine the dependencies for building PL/Tcl. + If this is not set, the following are probed in this + order: tclsh tcl tclsh8.6 tclsh86 tclsh8.5 tclsh85 + tclsh8.4 tclsh84. + + + + + + XML2_CONFIG + + + xml2-config program used to locate the + libxml2 installation + + + + + + + + Sometimes it is useful to add compiler flags after-the-fact to the set + that were chosen by configure. An important example is + that gcc's option cannot be included + in the CFLAGS passed to configure, because + it will break many of configure's built-in tests. To add + such flags, include them in the COPT environment variable + while running make. The contents of COPT + are added to both the CFLAGS and LDFLAGS + options set up by configure. For example, you could do + +make COPT='-Werror' + + or + +export COPT='-Werror' +make + + + + + + If using GCC, it is best to build with an optimization level of + at least , because using no optimization + () disables some important compiler warnings (such + as the use of uninitialized variables). However, non-zero + optimization levels can complicate debugging because stepping + through compiled code will usually not match up one-to-one with + source code lines. If you get confused while trying to debug + optimized code, recompile the specific files of interest with + . An easy way to do this is by passing an option + to make: make PROFILE=-O0 file.o. + + + + The COPT and PROFILE environment variables are + actually handled identically by the PostgreSQL + makefiles. Which to use is a matter of preference, but a common habit + among developers is to use PROFILE for one-time flag + adjustments, while COPT might be kept set all the time. + + + + + + + Post-Installation Setup + + + Shared Libraries + + + shared library + + + + On some systems with shared libraries + you need to tell the system how to find the newly installed + shared libraries. The systems on which this is + not necessary include + FreeBSD, + HP-UX, + Linux, + NetBSD, OpenBSD, and + Solaris. + + + + The method to set the shared library search path varies between + platforms, but the most widely-used method is to set the + environment variable LD_LIBRARY_PATH like so: In Bourne + shells (sh, ksh, bash, zsh): + +LD_LIBRARY_PATH=/usr/local/pgsql/lib +export LD_LIBRARY_PATH + + or in csh or tcsh: + +setenv LD_LIBRARY_PATH /usr/local/pgsql/lib + + Replace /usr/local/pgsql/lib with whatever you set + to in . + You should put these commands into a shell start-up file such as + /etc/profile or ~/.bash_profile. Some + good information about the caveats associated with this method can + be found at . + + + + On some systems it might be preferable to set the environment + variable LD_RUN_PATH before + building. + + + + On Cygwin, put the library + directory in the PATH or move the + .dll files into the bin + directory. + + + + If in doubt, refer to the manual pages of your system (perhaps + ld.so or rld). If you later + get a message like: + +psql: error in loading shared libraries +libpq.so.2.1: cannot open shared object file: No such file or directory + + then this step was necessary. Simply take care of it then. + + + + + ldconfig + + If you are on Linux and you have root + access, you can run: + +/sbin/ldconfig /usr/local/pgsql/lib + + (or equivalent directory) after installation to enable the + run-time linker to find the shared libraries faster. Refer to the + manual page of ldconfig for more information. On + FreeBSD, NetBSD, and OpenBSD the command is: + +/sbin/ldconfig -m /usr/local/pgsql/lib + + instead. Other systems are not known to have an equivalent + command. + + + + + Environment Variables + + + PATH + + + + If you installed into /usr/local/pgsql or some other + location that is not searched for programs by default, you should + add /usr/local/pgsql/bin (or whatever you set + to in ) + into your PATH. Strictly speaking, this is not + necessary, but it will make the use of PostgreSQL + much more convenient. + + + + To do this, add the following to your shell start-up file, such as + ~/.bash_profile (or /etc/profile, if you + want it to affect all users): + +PATH=/usr/local/pgsql/bin:$PATH +export PATH + + If you are using csh or tcsh, then use this command: + +set path = ( /usr/local/pgsql/bin $path ) + + + + + + MANPATH + + To enable your system to find the man + documentation, you need to add lines like the following to a + shell start-up file unless you installed into a location that is + searched by default: + +MANPATH=/usr/local/pgsql/share/man:$MANPATH +export MANPATH + + + + + The environment variables PGHOST and PGPORT + specify to client applications the host and port of the database + server, overriding the compiled-in defaults. If you are going to + run client applications remotely then it is convenient if every + user that plans to use the database sets PGHOST. This + is not required, however; the settings can be communicated via command + line options to most client programs. + + + + + + Supported Platforms + + + A platform (that is, a CPU architecture and operating system combination) + is considered supported by the PostgreSQL development + community if the code contains provisions to work on that platform and + it has recently been verified to build and pass its regression tests + on that platform. Currently, most testing of platform compatibility + is done automatically by test machines in the + PostgreSQL Build Farm. + If you are interested in using PostgreSQL on a platform + that is not represented in the build farm, but on which the code works + or can be made to work, you are strongly encouraged to set up a build + farm member machine so that continued compatibility can be assured. + + + + In general, PostgreSQL can be expected to work on + these CPU architectures: x86, x86_64, IA64, PowerPC, + PowerPC 64, S/390, S/390x, Sparc, Sparc 64, ARM, MIPS, MIPSEL, + and PA-RISC. Code support exists for M68K, M32R, and VAX, but these + architectures are not known to have been tested recently. It is often + possible to build on an unsupported CPU type by configuring with + , but performance will be poor. + + + + PostgreSQL can be expected to work on these operating + systems: Linux (all recent distributions), Windows (XP and later), + FreeBSD, OpenBSD, NetBSD, macOS, AIX, HP/UX, and Solaris. + Other Unix-like systems may also work but are not currently + being tested. In most cases, all CPU architectures supported by + a given operating system will work. Look in + below to see if + there is information + specific to your operating system, particularly if using an older system. + + + + If you have installation problems on a platform that is known + to be supported according to recent build farm results, please report + it to pgsql-bugs@lists.postgresql.org. If you are interested + in porting PostgreSQL to a new platform, + pgsql-hackers@lists.postgresql.org is the appropriate place + to discuss that. + + + + + Platform-Specific Notes + + + This section documents additional platform-specific issues + regarding the installation and setup of PostgreSQL. Be sure to + read the installation instructions, and in + particular as well. Also, + check regarding the + interpretation of regression test results. + + + + Platforms that are not covered here have no known platform-specific + installation issues. + + + + AIX + + + AIX + installation on + + + + PostgreSQL works on AIX, but AIX versions before about 6.1 have + various issues and are not recommended. + You can use GCC or the native IBM compiler xlc. + + + + Memory Management + + + + AIX can be somewhat peculiar with regards to the way it does + memory management. You can have a server with many multiples of + gigabytes of RAM free, but still get out of memory or address + space errors when running applications. One example + is loading of extensions failing with unusual errors. + For example, running as the owner of the PostgreSQL installation: + +=# CREATE EXTENSION plperl; +ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process. + + Running as a non-owner in the group possessing the PostgreSQL + installation: + +=# CREATE EXTENSION plperl; +ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address + + Another example is out of memory errors in the PostgreSQL server + logs, with every memory allocation near or greater than 256 MB + failing. + + + + The overall cause of all these problems is the default bittedness + and memory model used by the server process. By default, all + binaries built on AIX are 32-bit. This does not depend upon + hardware type or kernel in use. These 32-bit processes are + limited to 4 GB of memory laid out in 256 MB segments using one + of a few models. The default allows for less than 256 MB in the + heap as it shares a single segment with the stack. + + + + In the case of the plperl example, above, + check your umask and the permissions of the binaries in your + PostgreSQL installation. The binaries involved in that example + were 32-bit and installed as mode 750 instead of 755. Due to the + permissions being set in this fashion, only the owner or a member + of the possessing group can load the library. Since it isn't + world-readable, the loader places the object into the process' + heap instead of the shared library segments where it would + otherwise be placed. + + + + The ideal solution for this is to use a 64-bit + build of PostgreSQL, but that is not always practical, because + systems with 32-bit processors can build, but not run, 64-bit + binaries. + + + + If a 32-bit binary is desired, set LDR_CNTRL to + MAXDATA=0xn0000000, + where 1 <= n <= 8, before starting the PostgreSQL server, + and try different values and postgresql.conf + settings to find a configuration that works satisfactorily. This + use of LDR_CNTRL tells AIX that you want the + server to have MAXDATA bytes set aside for the + heap, allocated in 256 MB segments. When you find a workable + configuration, + ldedit can be used to modify the binaries so + that they default to using the desired heap size. PostgreSQL can + also be rebuilt, passing configure + LDFLAGS="-Wl,-bmaxdata:0xn0000000" + to achieve the same effect. + + + + For a 64-bit build, set OBJECT_MODE to 64 and + pass CC="gcc -maix64" + and LDFLAGS="-Wl,-bbigtoc" + to configure. (Options for + xlc might differ.) If you omit the export of + OBJECT_MODE, your build may fail with linker errors. When + OBJECT_MODE is set, it tells AIX's build utilities + such as ar, as, and ld what + type of objects to default to handling. + + + + By default, overcommit of paging space can happen. While we have + not seen this occur, AIX will kill processes when it runs out of + memory and the overcommit is accessed. The closest to this that + we have seen is fork failing because the system decided that + there was not enough memory for another process. Like many other + parts of AIX, the paging space allocation method and + out-of-memory kill is configurable on a system- or process-wide + basis if this becomes a problem. + + + + + + Cygwin + + + Cygwin + installation on + + + + PostgreSQL can be built using Cygwin, a Linux-like environment for + Windows, but that method is inferior to the native Windows build + (see ) and + running a server under Cygwin is no longer recommended. + + + + When building from source, proceed according to the Unix-style + installation procedure (i.e., ./configure; + make; etc.), noting the following Cygwin-specific + differences: + + + + + Set your path to use the Cygwin bin directory before the + Windows utilities. This will help prevent problems with + compilation. + + + + + + The adduser command is not supported; use + the appropriate user management application on Windows NT, + 2000, or XP. Otherwise, skip this step. + + + + + + The su command is not supported; use ssh to + simulate su on Windows NT, 2000, or XP. Otherwise, skip this + step. + + + + + + OpenSSL is not supported. + + + + + + Start cygserver for shared memory support. + To do this, enter the command /usr/sbin/cygserver + &. This program needs to be running anytime you + start the PostgreSQL server or initialize a database cluster + (initdb). The + default cygserver configuration may need to + be changed (e.g., increase SEMMNS) to prevent + PostgreSQL from failing due to a lack of system resources. + + + + + + Building might fail on some systems where a locale other than + C is in use. To fix this, set the locale to C by doing + export LANG=C.utf8 before building, and then + setting it back to the previous setting after you have installed + PostgreSQL. + + + + + + The parallel regression tests (make check) + can generate spurious regression test failures due to + overflowing the listen() backlog queue + which causes connection refused errors or hangs. You can limit + the number of connections using the make + variable MAX_CONNECTIONS thus: + +make MAX_CONNECTIONS=5 check + + (On some systems you can have up to about 10 simultaneous + connections.) + + + + + + + It is possible to install cygserver and the + PostgreSQL server as Windows NT services. For information on how + to do this, please refer to the README + document included with the PostgreSQL binary package on Cygwin. + It is installed in the + directory /usr/share/doc/Cygwin. + + + + + macOS + + + macOS + installation on + + + + To build PostgreSQL from source + on macOS, you will need to install Apple's + command line developer tools, which can be done by issuing + +xcode-select --install + + (note that this will pop up a GUI dialog window for confirmation). + You may or may not wish to also install Xcode. + + + + On recent macOS releases, it's necessary to + embed the sysroot path in the include switches used to + find some system header files. This results in the outputs of + the configure script varying depending on + which SDK version was used during configure. + That shouldn't pose any problem in simple scenarios, but if you are + trying to do something like building an extension on a different machine + than the server code was built on, you may need to force use of a + different sysroot path. To do that, set PG_SYSROOT, + for example + +make PG_SYSROOT=/desired/path all + + To find out the appropriate path on your machine, run + +xcrun --show-sdk-path + + Note that building an extension using a different sysroot version than + was used to build the core server is not really recommended; in the + worst case it could result in hard-to-debug ABI inconsistencies. + + + + You can also select a non-default sysroot path when configuring, by + specifying PG_SYSROOT + to configure: + +./configure ... PG_SYSROOT=/desired/path + + This would primarily be useful to cross-compile for some other + macOS version. There is no guarantee that the resulting executables + will run on the current host. + + + + To suppress the options altogether, use + +./configure ... PG_SYSROOT=none + + (any nonexistent pathname will work). This might be useful if you wish + to build with a non-Apple compiler, but beware that that case is not + tested or supported by the PostgreSQL developers. + + + + macOS's System Integrity + Protection (SIP) feature breaks make check, + because it prevents passing the needed setting + of DYLD_LIBRARY_PATH down to the executables being + tested. You can work around that by doing make + install before make check. + Most PostgreSQL developers just turn off SIP, though. + + + + + MinGW/Native Windows + + + MinGW + installation on + + + + PostgreSQL for Windows can be built using MinGW, a Unix-like build + environment for Microsoft operating systems, or using + Microsoft's Visual C++ compiler suite. + The MinGW build procedure uses the normal build system described in + this chapter; the Visual C++ build works completely differently + and is described in . + + + + The native Windows port requires a 32 or 64-bit version of Windows + 2000 or later. Earlier operating systems do + not have sufficient infrastructure (but Cygwin may be used on + those). MinGW, the Unix-like build tools, and MSYS, a collection + of Unix tools required to run shell scripts + like configure, can be downloaded + from . Neither is + required to run the resulting binaries; they are needed only for + creating the binaries. + + + + To build 64 bit binaries using MinGW, install the 64 bit tool set + from , put its bin + directory in the PATH, and run + configure with the + --host=x86_64-w64-mingw32 option. + + + + After you have everything installed, it is suggested that you + run psql + under CMD.EXE, as the MSYS console has + buffering issues. + + + + Collecting Crash Dumps on Windows + + + If PostgreSQL on Windows crashes, it has the ability to generate + minidumps that can be used to track down the cause + for the crash, similar to core dumps on Unix. These dumps can be + read using the Windows Debugger Tools or using + Visual Studio. To enable the generation of dumps + on Windows, create a subdirectory named crashdumps + inside the cluster data directory. The dumps will then be written + into this directory with a unique name based on the identifier of + the crashing process and the current time of the crash. + + + + + + Solaris + + + Solaris + installation on + + + + PostgreSQL is well-supported on Solaris. The more up to date your + operating system, the fewer issues you will experience. + + + + Required Tools + + + You can build with either GCC or Sun's compiler suite. For + better code optimization, Sun's compiler is strongly recommended + on the SPARC architecture. If + you are using Sun's compiler, be careful not to select + /usr/ucb/cc; + use /opt/SUNWspro/bin/cc. + + + + You can download Sun Studio + from . + Many GNU tools are integrated into Solaris 10, or they are + present on the Solaris companion CD. If you need packages for + older versions of Solaris, you can find these tools + at . + If you prefer + sources, look + at . + + + + + configure Complains About a Failed Test Program + + + If configure complains about a failed test + program, this is probably a case of the run-time linker being + unable to find some library, probably libz, libreadline or some + other non-standard library such as libssl. To point it to the + right location, set the LDFLAGS environment + variable on the configure command line, e.g., + +configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib" + + See + the ld1 + man page for more information. + + + + + Compiling for Optimal Performance + + + On the SPARC architecture, Sun Studio is strongly recommended for + compilation. Try using the optimization + flag to generate significantly faster binaries. Do not use any + flags that modify behavior of floating-point operations + and errno processing (e.g., + ). + + + + If you do not have a reason to use 64-bit binaries on SPARC, + prefer the 32-bit version. The 64-bit operations are slower and + 64-bit binaries are slower than the 32-bit variants. On the + other hand, 32-bit code on the AMD64 CPU family is not native, + so 32-bit code is significantly slower on that CPU family. + + + + + Using DTrace for Tracing PostgreSQL + + + Yes, using DTrace is possible. See for + further information. + + + + If you see the linking of the postgres executable abort with an + error message like: + +Undefined first referenced + symbol in file +AbortTransaction utils/probes.o +CommitTransaction utils/probes.o +ld: fatal: Symbol referencing errors. No output written to postgres +collect2: ld returned 1 exit status +make: *** [postgres] Error 1 + + your DTrace installation is too old to handle probes in static + functions. You need Solaris 10u4 or newer to use DTrace. + + + + + + diff --git a/doc/src/sgml/intarray.sgml b/doc/src/sgml/intarray.sgml new file mode 100644 index 000000000000..f930c08eeb78 --- /dev/null +++ b/doc/src/sgml/intarray.sgml @@ -0,0 +1,498 @@ + + + + intarray + + + intarray + + + + The intarray module provides a number of useful functions + and operators for manipulating null-free arrays of integers. + There is also support for indexed searches using some of the operators. + + + + All of these operations will throw an error if a supplied array contains any + NULL elements. + + + + Many of these operations are only sensible for one-dimensional arrays. + Although they will accept input arrays of more dimensions, the data is + treated as though it were a linear array in storage order. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + <filename>intarray</filename> Functions and Operators + + + The functions provided by the intarray module + are shown in , the operators + in . + + + + <filename>intarray</filename> Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + icount + icount ( integer[] ) + integer + + + Returns the number of elements in the array. + + + icount('{1,2,3}'::integer[]) + 3 + + + + + + sort + sort ( integer[], dir text ) + integer[] + + + Sorts the array in either ascending or descending order. + dir must be asc + or desc. + + + sort('{1,3,2}'::integer[], 'desc') + {3,2,1} + + + + + + sort ( integer[] ) + integer[] + + + sort_asc + sort_asc ( integer[] ) + integer[] + + + Sorts in ascending order. + + + sort(array[11,77,44]) + {11,44,77} + + + + + + sort_desc + sort_desc ( integer[] ) + integer[] + + + Sorts in descending order. + + + sort_desc(array[11,77,44]) + {77,44,11} + + + + + + uniq + uniq ( integer[] ) + integer[] + + + Removes adjacent duplicates. + + + uniq(sort('{1,2,3,2,1}'::integer[])) + {1,2,3} + + + + + + idx + idx ( integer[], item integer ) + integer + + + Returns index of the first array element + matching item, or 0 if no match. + + + idx(array[11,22,33,22,11], 22) + 2 + + + + + + subarray + subarray ( integer[], start integer, len integer ) + integer[] + + + Extracts the portion of the array starting at + position start, with len + elements. + + + subarray('{1,2,3,2,1}'::integer[], 2, 3) + {2,3,2} + + + + + + subarray ( integer[], start integer ) + integer[] + + + Extracts the portion of the array starting at + position start. + + + subarray('{1,2,3,2,1}'::integer[], 2) + {2,3,2,1} + + + + + + intset + intset ( integer ) + integer[] + + + Makes a single-element array. + + + intset(42) + {42} + + + + +
+ + + <filename>intarray</filename> Operators + + + + + Operator + + + Description + + + + + + + + integer[] && integer[] + boolean + + + Do arrays overlap (have at least one element in common)? + + + + + + integer[] @> integer[] + boolean + + + Does left array contain right array? + + + + + + integer[] <@ integer[] + boolean + + + Is left array contained in right array? + + + + + + # integer[] + integer + + + Returns the number of elements in the array. + + + + + + integer[] # integer + integer + + + Returns index of the first array element + matching the right argument, or 0 if no match. + (Same as idx function.) + + + + + + integer[] + integer + integer[] + + + Adds element to end of array. + + + + + + integer[] + integer[] + integer[] + + + Concatenates the arrays. + + + + + + integer[] - integer + integer[] + + + Removes entries matching the right argument from the array. + + + + + + integer[] - integer[] + integer[] + + + Removes elements of the right array from the left array. + + + + + + integer[] | integer + integer[] + + + Computes the union of the arguments. + + + + + + integer[] | integer[] + integer[] + + + Computes the union of the arguments. + + + + + + integer[] & integer[] + integer[] + + + Computes the intersection of the arguments. + + + + + + integer[] @@ query_int + boolean + + + Does array satisfy query? (see below) + + + + + + query_int ~~ integer[] + boolean + + + Does array satisfy query? (commutator of @@) + + + + +
+ + + The operators &&, @> and + <@ are equivalent to PostgreSQL's built-in + operators of the same names, except that they work only on integer arrays + that do not contain nulls, while the built-in operators work for any array + type. This restriction makes them faster than the built-in operators + in many cases. + + + + The @@ and ~~ operators test whether an array + satisfies a query, which is expressed as a value of a + specialized data type query_int. A query + consists of integer values that are checked against the elements of + the array, possibly combined using the operators & + (AND), | (OR), and ! (NOT). Parentheses + can be used as needed. For example, + the query 1&(2|3) matches arrays that contain 1 + and also contain either 2 or 3. + +
+ + + Index Support + + + intarray provides index support for the + &&, @>, + and @@ operators, as well as regular array equality. + + + + Two parameterized GiST index operator classes are provided: + gist__int_ops (used by default) is suitable for + small- to medium-size data sets, while + gist__intbig_ops uses a larger signature and is more + suitable for indexing large data sets (i.e., columns containing + a large number of distinct array values). + The implementation uses an RD-tree data structure with + built-in lossy compression. + + + + gist__int_ops approximates an integer set as an array of + integer ranges. Its optional integer parameter numranges + determines the maximum number of ranges in + one index key. The default value of numranges is 100. + Valid values are between 1 and 253. Using larger arrays as GiST index + keys leads to a more precise search (scanning a smaller fraction of the index and + fewer heap pages), at the cost of a larger index. + + + + gist__intbig_ops approximates an integer set as a bitmap + signature. Its optional integer parameter siglen + determines the signature length in bytes. + The default signature length is 16 bytes. Valid values of signature length + are between 1 and 2024 bytes. Longer signatures lead to a more precise + search (scanning a smaller fraction of the index and fewer heap pages), at + the cost of a larger index. + + + + There is also a non-default GIN operator class + gin__int_ops, which supports these operators as well + as <@. + + + + The choice between GiST and GIN indexing depends on the relative + performance characteristics of GiST and GIN, which are discussed elsewhere. + + + + + Example + + +-- a message can be in one or more sections +CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...); + +-- create specialized index with signature length of 32 bytes +CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen = 32)); + +-- select messages in section 1 OR 2 - OVERLAP operator +SELECT message.mid FROM message WHERE message.sections && '{1,2}'; + +-- select messages in sections 1 AND 2 - CONTAINS operator +SELECT message.mid FROM message WHERE message.sections @> '{1,2}'; + +-- the same, using QUERY operator +SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int; + + + + + Benchmark + + + The source directory contrib/intarray/bench contains a + benchmark test suite, which can be run against an installed + PostgreSQL server. (It also requires DBD::Pg + to be installed.) To run: + + + +cd .../contrib/intarray/bench +createdb TEST +psql -c "CREATE EXTENSION intarray" TEST +./create_test.pl | psql TEST +./bench.pl + + + + The bench.pl script has numerous options, which + are displayed when it is run without any arguments. + + + + + Authors + + + All work was done by Teodor Sigaev (teodor@sigaev.ru) and + Oleg Bartunov (oleg@sai.msu.su). See + for + additional information. Andrey Oktyabrski did a great work on adding new + functions and operations. + + + +
diff --git a/doc/src/sgml/isn.sgml b/doc/src/sgml/isn.sgml new file mode 100644 index 000000000000..709bc8345c7e --- /dev/null +++ b/doc/src/sgml/isn.sgml @@ -0,0 +1,424 @@ + + + + isn + + + isn + + + + The isn module provides data types for the following + international product numbering standards: EAN13, UPC, ISBN (books), ISMN + (music), and ISSN (serials). Numbers are validated on input according to a + hard-coded list of prefixes; this list of prefixes is also used to hyphenate + numbers on output. Since new prefixes are assigned from time to time, the + list of prefixes may be out of date. It is hoped that a future version of + this module will obtain the prefix list from one or more tables that + can be easily updated by users as needed; however, at present, the + list can only be updated by modifying the source code and recompiling. + Alternatively, prefix validation and hyphenation support may be + dropped from a future version of this module. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Data Types + + + shows the data types provided by + the isn module. + + + + <filename>isn</filename> Data Types + + + + + + Data Type + Description + + + + + + EAN13 + + European Article Numbers, always displayed in the EAN13 display format + + + + + ISBN13 + + International Standard Book Numbers to be displayed in + the new EAN13 display format + + + + + ISMN13 + + International Standard Music Numbers to be displayed in + the new EAN13 display format + + + + ISSN13 + + International Standard Serial Numbers to be displayed in the new + EAN13 display format + + + + ISBN + + International Standard Book Numbers to be displayed in the old + short display format + + + + ISMN + + International Standard Music Numbers to be displayed in the + old short display format + + + + ISSN + + International Standard Serial Numbers to be displayed in the + old short display format + + + + UPC + + Universal Product Codes + + + + +
+ + + Some notes: + + + + + ISBN13, ISMN13, ISSN13 numbers are all EAN13 numbers. + + + EAN13 numbers aren't always ISBN13, ISMN13 or ISSN13 (some + are). + + + Some ISBN13 numbers can be displayed as ISBN. + + + Some ISMN13 numbers can be displayed as ISMN. + + + Some ISSN13 numbers can be displayed as ISSN. + + + UPC numbers are a subset of the EAN13 numbers (they are basically + EAN13 without the first 0 digit). + + + All UPC, ISBN, ISMN and ISSN numbers can be represented as EAN13 + numbers. + + + + + Internally, all these types use the same representation (a 64-bit + integer), and all are interchangeable. Multiple types are provided + to control display formatting and to permit tighter validity checking + of input that is supposed to denote one particular type of number. + + + + The ISBN, ISMN, and ISSN types will display the + short version of the number (ISxN 10) whenever it's possible, and will show + ISxN 13 format for numbers that do not fit in the short version. + The EAN13, ISBN13, ISMN13 and + ISSN13 types will always display the long version of the ISxN + (EAN13). + +
+ + + Casts + + + The isn module provides the following pairs of type casts: + + + + + + ISBN13 <=> EAN13 + + + + + ISMN13 <=> EAN13 + + + + + ISSN13 <=> EAN13 + + + + + ISBN <=> EAN13 + + + + + ISMN <=> EAN13 + + + + + ISSN <=> EAN13 + + + + + UPC <=> EAN13 + + + + + ISBN <=> ISBN13 + + + + + ISMN <=> ISMN13 + + + + + ISSN <=> ISSN13 + + + + + + When casting from EAN13 to another type, there is a run-time + check that the value is within the domain of the other type, and an error + is thrown if not. The other casts are simply relabelings that will + always succeed. + + + + + Functions and Operators + + + The isn module provides the standard comparison operators, + plus B-tree and hash indexing support for all these data types. In + addition there are several specialized functions; shown in . + In this table, + isn means any one of the module's data types. + + + + <filename>isn</filename> Functions + + + + + Function + + + Description + + + + + + + + isn_weak + isn_weak ( boolean ) + boolean + + + Sets the weak input mode, and returns new setting. + + + + + + isn_weak () + boolean + + + Returns the current status of the weak mode. + + + + + + make_valid + make_valid ( isn ) + isn + + + Validates an invalid number (clears the invalid flag). + + + + + + is_valid + is_valid ( isn ) + boolean + + + Checks for the presence of the invalid flag. + + + + +
+ + + Weak mode is used to be able to insert invalid data + into a table. Invalid means the check digit is wrong, not that there are + missing numbers. + + + + Why would you want to use the weak mode? Well, it could be that + you have a huge collection of ISBN numbers, and that there are so many of + them that for weird reasons some have the wrong check digit (perhaps the + numbers were scanned from a printed list and the OCR got the numbers wrong, + perhaps the numbers were manually captured... who knows). Anyway, the point + is you might want to clean the mess up, but you still want to be able to + have all the numbers in your database and maybe use an external tool to + locate the invalid numbers in the database so you can verify the + information and validate it more easily; so for example you'd want to + select all the invalid numbers in the table. + + + + When you insert invalid numbers in a table using the weak mode, the number + will be inserted with the corrected check digit, but it will be displayed + with an exclamation mark (!) at the end, for example + 0-11-000322-5!. This invalid marker can be checked with + the is_valid function and cleared with the + make_valid function. + + + + You can also force the insertion of invalid numbers even when not in the + weak mode, by appending the ! character at the end of the + number. + + + + Another special feature is that during input, you can write + ? in place of the check digit, and the correct check digit + will be inserted automatically. + +
+ + + Examples + + +--Using the types directly: +SELECT isbn('978-0-393-04002-9'); +SELECT isbn13('0901690546'); +SELECT issn('1436-4522'); + +--Casting types: +-- note that you can only cast from ean13 to another type when the +-- number would be valid in the realm of the target type; +-- thus, the following will NOT work: select isbn(ean13('0220356483481')); +-- but these will: +SELECT upc(ean13('0220356483481')); +SELECT ean13(upc('220356483481')); + +--Create a table with a single column to hold ISBN numbers: +CREATE TABLE test (id isbn); +INSERT INTO test VALUES('9780393040029'); + +--Automatically calculate check digits (observe the '?'): +INSERT INTO test VALUES('220500896?'); +INSERT INTO test VALUES('978055215372?'); + +SELECT issn('3251231?'); +SELECT ismn('979047213542?'); + +--Using the weak mode: +SELECT isn_weak(true); +INSERT INTO test VALUES('978-0-11-000533-4'); +INSERT INTO test VALUES('9780141219307'); +INSERT INTO test VALUES('2-205-00876-X'); +SELECT isn_weak(false); + +SELECT id FROM test WHERE NOT is_valid(id); +UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!'; + +SELECT * FROM test; + +SELECT isbn13(id) FROM test; + + + + + Bibliography + + + The information to implement this module was collected from + several sites, including: + + + + + + + + The prefixes used for hyphenation were also compiled from: + + + + + + + + + Care was taken during the creation of the algorithms and they + were meticulously verified against the suggested algorithms + in the official ISBN, ISMN, ISSN User Manuals. + + + + + Author + + Germán Méndez Bravo (Kronuz), 2004–2006 + + + + This module was inspired by Garrett A. Wollman's + isbn_issn code. + + + +
diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml new file mode 100644 index 000000000000..1b5103e2694b --- /dev/null +++ b/doc/src/sgml/json.sgml @@ -0,0 +1,1006 @@ + + + + <acronym>JSON</acronym> Types + + + JSON + + + + JSONB + + + + JSON data types are for storing JSON (JavaScript Object Notation) + data, as specified in RFC + 7159. Such data can also be stored as text, but + the JSON data types have the advantage of enforcing that each + stored value is valid according to the JSON rules. There are also + assorted JSON-specific functions and operators available for data stored + in these data types; see . + + + + PostgreSQL offers two types for storing JSON + data: json and jsonb. To implement efficient query + mechanisms for these data types, PostgreSQL + also provides the jsonpath data type described in + . + + + + The json and jsonb data types + accept almost identical sets of values as + input. The major practical difference is one of efficiency. The + json data type stores an exact copy of the input text, + which processing functions must reparse on each execution; while + jsonb data is stored in a decomposed binary format that + makes it slightly slower to input due to added conversion + overhead, but significantly faster to process, since no reparsing + is needed. jsonb also supports indexing, which can be a + significant advantage. + + + + Because the json type stores an exact copy of the input text, it + will preserve semantically-insignificant white space between tokens, as + well as the order of keys within JSON objects. Also, if a JSON object + within the value contains the same key more than once, all the key/value + pairs are kept. (The processing functions consider the last value as the + operative one.) By contrast, jsonb does not preserve white + space, does not preserve the order of object keys, and does not keep + duplicate object keys. If duplicate keys are specified in the input, + only the last value is kept. + + + + In general, most applications should prefer to store JSON data as + jsonb, unless there are quite specialized needs, such as + legacy assumptions about ordering of object keys. + + + + RFC 7159 specifies that JSON strings should be encoded in UTF8. + It is therefore not possible for the JSON + types to conform rigidly to the JSON specification unless the database + encoding is UTF8. Attempts to directly include characters that + cannot be represented in the database encoding will fail; conversely, + characters that can be represented in the database encoding but not + in UTF8 will be allowed. + + + + RFC 7159 permits JSON strings to contain Unicode escape sequences + denoted by \uXXXX. In the input + function for the json type, Unicode escapes are allowed + regardless of the database encoding, and are checked only for syntactic + correctness (that is, that four hex digits follow \u). + However, the input function for jsonb is stricter: it disallows + Unicode escapes for characters that cannot be represented in the database + encoding. The jsonb type also + rejects \u0000 (because that cannot be represented in + PostgreSQL's text type), and it insists + that any use of Unicode surrogate pairs to designate characters outside + the Unicode Basic Multilingual Plane be correct. Valid Unicode escapes + are converted to the equivalent single character for storage; + this includes folding surrogate pairs into a single character. + + + + + Many of the JSON processing functions described + in will convert Unicode escapes to + regular characters, and will therefore throw the same types of errors + just described even if their input is of type json + not jsonb. The fact that the json input function does + not make these checks may be considered a historical artifact, although + it does allow for simple storage (without processing) of JSON Unicode + escapes in a database encoding that does not support the represented + characters. + + + + + When converting textual JSON input into jsonb, the primitive + types described by RFC 7159 are effectively mapped onto + native PostgreSQL types, as shown + in . + Therefore, there are some minor additional constraints on what + constitutes valid jsonb data that do not apply to + the json type, nor to JSON in the abstract, corresponding + to limits on what can be represented by the underlying data type. + Notably, jsonb will reject numbers that are outside the + range of the PostgreSQL numeric data + type, while json will not. Such implementation-defined + restrictions are permitted by RFC 7159. However, in + practice such problems are far more likely to occur in other + implementations, as it is common to represent JSON's number + primitive type as IEEE 754 double precision floating point + (which RFC 7159 explicitly anticipates and allows for). + When using JSON as an interchange format with such systems, the danger + of losing numeric precision compared to data originally stored + by PostgreSQL should be considered. + + + + Conversely, as noted in the table there are some minor restrictions on + the input format of JSON primitive types that do not apply to + the corresponding PostgreSQL types. + + + + JSON Primitive Types and Corresponding <productname>PostgreSQL</productname> Types + + + + + + + JSON primitive type + PostgreSQL type + Notes + + + + + string + text + \u0000 is disallowed, as are Unicode escapes + representing characters not available in the database encoding + + + number + numeric + NaN and infinity values are disallowed + + + boolean + boolean + Only lowercase true and false spellings are accepted + + + null + (none) + SQL NULL is a different concept + + + +
+ + + JSON Input and Output Syntax + + The input/output syntax for the JSON data types is as specified in + RFC 7159. + + + The following are all valid json (or jsonb) expressions: + +-- Simple scalar/primitive value +-- Primitive values can be numbers, quoted strings, true, false, or null +SELECT '5'::json; + +-- Array of zero or more elements (elements need not be of same type) +SELECT '[1, 2, "foo", null]'::json; + +-- Object containing pairs of keys and values +-- Note that object keys must always be quoted strings +SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json; + +-- Arrays and objects can be nested arbitrarily +SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json; + + + + + As previously stated, when a JSON value is input and then printed without + any additional processing, json outputs the same text that was + input, while jsonb does not preserve semantically-insignificant + details such as whitespace. For example, note the differences here: + +SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json; + json +------------------------------------------------- + {"bar": "baz", "balance": 7.77, "active":false} +(1 row) + +SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb; + jsonb +-------------------------------------------------- + {"bar": "baz", "active": false, "balance": 7.77} +(1 row) + + One semantically-insignificant detail worth noting is that + in jsonb, numbers will be printed according to the behavior of the + underlying numeric type. In practice this means that numbers + entered with E notation will be printed without it, for + example: + +SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb; + json | jsonb +-----------------------+------------------------- + {"reading": 1.230e-5} | {"reading": 0.00001230} +(1 row) + + However, jsonb will preserve trailing fractional zeroes, as seen + in this example, even though those are semantically insignificant for + purposes such as equality checks. + + + + For the list of built-in functions and operators available for + constructing and processing JSON values, see . + + + + + Designing JSON Documents + + Representing data as JSON can be considerably more flexible than + the traditional relational data model, which is compelling in + environments where requirements are fluid. It is quite possible + for both approaches to co-exist and complement each other within + the same application. However, even for applications where maximal + flexibility is desired, it is still recommended that JSON documents + have a somewhat fixed structure. The structure is typically + unenforced (though enforcing some business rules declaratively is + possible), but having a predictable structure makes it easier to write + queries that usefully summarize a set of documents (datums) + in a table. + + + JSON data is subject to the same concurrency-control + considerations as any other data type when stored in a table. + Although storing large documents is practicable, keep in mind that + any update acquires a row-level lock on the whole row. + Consider limiting JSON documents to a + manageable size in order to decrease lock contention among updating + transactions. Ideally, JSON documents should each + represent an atomic datum that business rules dictate cannot + reasonably be further subdivided into smaller datums that + could be modified independently. + + + + + <type>jsonb</type> Containment and Existence + + jsonb + containment + + + jsonb + existence + + + Testing containment is an important capability of + jsonb. There is no parallel set of facilities for the + json type. Containment tests whether + one jsonb document has contained within it another one. + These examples return true except as noted: + + +-- Simple scalar/primitive values contain only the identical value: +SELECT '"foo"'::jsonb @> '"foo"'::jsonb; + +-- The array on the right side is contained within the one on the left: +SELECT '[1, 2, 3]'::jsonb @> '[1, 3]'::jsonb; + +-- Order of array elements is not significant, so this is also true: +SELECT '[1, 2, 3]'::jsonb @> '[3, 1]'::jsonb; + +-- Duplicate array elements don't matter either: +SELECT '[1, 2, 3]'::jsonb @> '[1, 2, 2]'::jsonb; + +-- The object with a single pair on the right side is contained +-- within the object on the left side: +SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @> '{"version": 9.4}'::jsonb; + +-- The array on the right side is not considered contained within the +-- array on the left, even though a similar array is nested within it: +SELECT '[1, 2, [1, 3]]'::jsonb @> '[1, 3]'::jsonb; -- yields false + +-- But with a layer of nesting, it is contained: +SELECT '[1, 2, [1, 3]]'::jsonb @> '[[1, 3]]'::jsonb; + +-- Similarly, containment is not reported here: +SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields false + +-- A top-level key and an empty object is contained: +SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"foo": {}}'::jsonb; + + + + The general principle is that the contained object must match the + containing object as to structure and data contents, possibly after + discarding some non-matching array elements or object key/value pairs + from the containing object. + But remember that the order of array elements is not significant when + doing a containment match, and duplicate array elements are effectively + considered only once. + + + + As a special exception to the general principle that the structures + must match, an array may contain a primitive value: + + +-- This array contains the primitive string value: +SELECT '["foo", "bar"]'::jsonb @> '"bar"'::jsonb; + +-- This exception is not reciprocal -- non-containment is reported here: +SELECT '"bar"'::jsonb @> '["bar"]'::jsonb; -- yields false + + + + jsonb also has an existence operator, which is + a variation on the theme of containment: it tests whether a string + (given as a text value) appears as an object key or array + element at the top level of the jsonb value. + These examples return true except as noted: + + +-- String exists as array element: +SELECT '["foo", "bar", "baz"]'::jsonb ? 'bar'; + +-- String exists as object key: +SELECT '{"foo": "bar"}'::jsonb ? 'foo'; + +-- Object values are not considered: +SELECT '{"foo": "bar"}'::jsonb ? 'bar'; -- yields false + +-- As with containment, existence must match at the top level: +SELECT '{"foo": {"bar": "baz"}}'::jsonb ? 'bar'; -- yields false + +-- A string is considered to exist if it matches a primitive JSON string: +SELECT '"foo"'::jsonb ? 'foo'; + + + + JSON objects are better suited than arrays for testing containment or + existence when there are many keys or elements involved, because + unlike arrays they are internally optimized for searching, and do not + need to be searched linearly. + + + + + Because JSON containment is nested, an appropriate query can skip + explicit selection of sub-objects. As an example, suppose that we have + a doc column containing objects at the top level, with + most objects containing tags fields that contain arrays of + sub-objects. This query finds entries in which sub-objects containing + both "term":"paris" and "term":"food" appear, + while ignoring any such keys outside the tags array: + +SELECT doc->'site_name' FROM websites + WHERE doc @> '{"tags":[{"term":"paris"}, {"term":"food"}]}'; + + One could accomplish the same thing with, say, + +SELECT doc->'site_name' FROM websites + WHERE doc->'tags' @> '[{"term":"paris"}, {"term":"food"}]'; + + but that approach is less flexible, and often less efficient as well. + + + + On the other hand, the JSON existence operator is not nested: it will + only look for the specified key or array element at top level of the + JSON value. + + + + + The various containment and existence operators, along with all other + JSON operators and functions are documented + in . + + + + + <type>jsonb</type> Indexing + + jsonb + indexes on + + + + GIN indexes can be used to efficiently search for + keys or key/value pairs occurring within a large number of + jsonb documents (datums). + Two GIN operator classes are provided, offering different + performance and flexibility trade-offs. + + + The default GIN operator class for jsonb supports queries with + top-level key-exists operators ?, ?& + and ?| operators and path/value-exists operator + @>. + (For details of the semantics that these operators + implement, see .) + An example of creating an index with this operator class is: + +CREATE INDEX idxgin ON api USING GIN (jdoc); + + The non-default GIN operator class jsonb_path_ops + supports indexing the @> operator only. + An example of creating an index with this operator class is: + +CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops); + + + + + Consider the example of a table that stores JSON documents + retrieved from a third-party web service, with a documented schema + definition. A typical document is: + +{ + "guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a", + "name": "Angela Barton", + "is_active": true, + "company": "Magnafone", + "address": "178 Howard Place, Gulf, Washington, 702", + "registered": "2009-11-07T08:53:22 +08:00", + "latitude": 19.793713, + "longitude": 86.513373, + "tags": [ + "enim", + "aliquip", + "qui" + ] +} + + We store these documents in a table named api, + in a jsonb column named jdoc. + If a GIN index is created on this column, + queries like the following can make use of the index: + +-- Find documents in which the key "company" has value "Magnafone" +SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}'; + + However, the index could not be used for queries like the + following, because though the operator ? is indexable, + it is not applied directly to the indexed column jdoc: + +-- Find documents in which the key "tags" contains key or array element "qui" +SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui'; + + Still, with appropriate use of expression indexes, the above + query can use an index. If querying for particular items within + the "tags" key is common, defining an index like this + may be worthwhile: + +CREATE INDEX idxgintags ON api USING GIN ((jdoc -> 'tags')); + + Now, the WHERE clause jdoc -> 'tags' ? 'qui' + will be recognized as an application of the indexable + operator ? to the indexed + expression jdoc -> 'tags'. + (More information on expression indexes can be found in .) + + + Also, GIN index supports @@ and @? + operators, which perform jsonpath matching. + +SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @@ '$.tags[*] == "qui"'; + + +SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @? '$.tags[*] ? (@ == "qui")'; + + GIN index extracts statements of following form out of + jsonpath: accessors_chain = const. + Accessors chain may consist of .key, + [*], and [index] accessors. + jsonb_ops additionally supports .* + and .** accessors. + + + Another approach to querying is to exploit containment, for example: + +-- Find documents in which the key "tags" contains array element "qui" +SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}'; + + A simple GIN index on the jdoc column can support this + query. But note that such an index will store copies of every key and + value in the jdoc column, whereas the expression index + of the previous example stores only data found under + the tags key. While the simple-index approach is far more + flexible (since it supports queries about any key), targeted expression + indexes are likely to be smaller and faster to search than a simple + index. + + + + Although the jsonb_path_ops operator class supports + only queries with the @>, @@ + and @? operators, it has notable + performance advantages over the default operator + class jsonb_ops. A jsonb_path_ops + index is usually much smaller than a jsonb_ops + index over the same data, and the specificity of searches is better, + particularly when queries contain keys that appear frequently in the + data. Therefore search operations typically perform better + than with the default operator class. + + + + The technical difference between a jsonb_ops + and a jsonb_path_ops GIN index is that the former + creates independent index items for each key and value in the data, + while the latter creates index items only for each value in the + data. + + + For this purpose, the term value includes array elements, + though JSON terminology sometimes considers array elements distinct + from values within objects. + + + Basically, each jsonb_path_ops index item is + a hash of the value and the key(s) leading to it; for example to index + {"foo": {"bar": "baz"}}, a single index item would + be created incorporating all three of foo, bar, + and baz into the hash value. Thus a containment query + looking for this structure would result in an extremely specific index + search; but there is no way at all to find out whether foo + appears as a key. On the other hand, a jsonb_ops + index would create three index items representing foo, + bar, and baz separately; then to do the + containment query, it would look for rows containing all three of + these items. While GIN indexes can perform such an AND search fairly + efficiently, it will still be less specific and slower than the + equivalent jsonb_path_ops search, especially if + there are a very large number of rows containing any single one of the + three index items. + + + + A disadvantage of the jsonb_path_ops approach is + that it produces no index entries for JSON structures not containing + any values, such as {"a": {}}. If a search for + documents containing such a structure is requested, it will require a + full-index scan, which is quite slow. jsonb_path_ops is + therefore ill-suited for applications that often perform such searches. + + + + jsonb also supports btree and hash + indexes. These are usually useful only if it's important to check + equality of complete JSON documents. + The btree ordering for jsonb datums is seldom + of great interest, but for completeness it is: + +Object > Array > Boolean > Number > String > Null + +Object with n pairs > object with n - 1 pairs + +Array with n elements > array with n - 1 elements + + Objects with equal numbers of pairs are compared in the order: + +key-1, value-1, key-2 ... + + Note that object keys are compared in their storage order; + in particular, since shorter keys are stored before longer keys, this + can lead to results that might be unintuitive, such as: + +{ "aa": 1, "c": 1} > {"b": 1, "d": 1} + + Similarly, arrays with equal numbers of elements are compared in the + order: + +element-1, element-2 ... + + Primitive JSON values are compared using the same + comparison rules as for the underlying + PostgreSQL data type. Strings are + compared using the default database collation. + + + + + <type>jsonb</type> Subscripting + + The jsonb data type supports array-style subscripting expressions + to extract and modify elements. Nested values can be indicated by chaining + subscripting expressions, following the same rules as the path + argument in the jsonb_set function. If a jsonb + value is an array, numeric subscripts start at zero, and negative integers count + backwards from the last element of the array. Slice expressions are not supported. + The result of a subscripting expression is always of the jsonb data type. + + + + UPDATE statements may use subscripting in the + SET clause to modify jsonb values. Subscript + paths must be traversible for all affected values insofar as they exist. For + instance, the path val['a']['b']['c'] can be traversed all + the way to c if every val, + val['a'], and val['a']['b'] is an + object. If any val['a'] or val['a']['b'] + is not defined, it will be created as an empty object and filled as + necessary. However, if any val itself or one of the + intermediary values is defined as a non-object such as a string, number, or + jsonb null, traversal cannot proceed so + an error is raised and the transaction aborted. + + + + An example of subscripting syntax: + + + +-- Extract object value by key +SELECT ('{"a": 1}'::jsonb)['a']; + +-- Extract nested object value by key path +SELECT ('{"a": {"b": {"c": 1}}}'::jsonb)['a']['b']['c']; + +-- Extract array element by index +SELECT ('[1, "2", null]'::jsonb)[1]; + +-- Update object value by key. Note the quotes around '1': the assigned +-- value must be of the jsonb type as well +UPDATE table_name SET jsonb_field['key'] = '1'; + +-- This will raise an error if any record's jsonb_field['a']['b'] is something +-- other than an object. For example, the value {"a": 1} has a numeric value +-- of the key 'a'. +UPDATE table_name SET jsonb_field['a']['b']['c'] = '1'; + +-- Filter records using a WHERE clause with subscripting. Since the result of +-- subscripting is jsonb, the value we compare it against must also be jsonb. +-- The double quotes make "value" also a valid jsonb string. +SELECT * FROM table_name WHERE jsonb_field['key'] = '"value"'; + + + jsonb assignment via subscripting handles a few edge cases + differently from jsonb_set. When a source jsonb + value is NULL, assignment via subscripting will proceed + as if it was an empty JSON value of the type (object or array) implied by the + subscript key: + + +-- Where jsonb_field was NULL, it is now {"a": 1} +UPDATE table_name SET jsonb_field['a'] = '1'; + +-- Where jsonb_field was NULL, it is now [1] +UPDATE table_name SET jsonb_field[0] = '1'; + + + If an index is specified for an array containing too few elements, + NULL elements will be appended until the index is reachable + and the value can be set. + + +-- Where jsonb_field was [], it is now [null, null, 2]; +-- where jsonb_field was [0], it is now [0, null, 2] +UPDATE table_name SET jsonb_field[2] = '2'; + + + A jsonb value will accept assignments to nonexistent subscript + paths as long as the last existing element to be traversed is an object or + array, as implied by the corresponding subscript (the element indicated by + the last subscript in the path is not traversed and may be anything). Nested + array and object structures will be created, and in the former case + null-padded, as specified by the subscript path until the + assigned value can be placed. + + +-- Where jsonb_field was {}, it is now {'a': [{'b': 1}]} +UPDATE table_name SET jsonb_field['a'][0]['b'] = '1'; + +-- Where jsonb_field was [], it is now [null, {'a': 1}] +UPDATE table_name SET jsonb_field[1]['a'] = '1'; + + + + + + + Transforms + + + Additional extensions are available that implement transforms for the + jsonb type for different procedural languages. + + + + The extensions for PL/Perl are called jsonb_plperl and + jsonb_plperlu. If you use them, jsonb + values are mapped to Perl arrays, hashes, and scalars, as appropriate. + + + + The extensions for PL/Python are called jsonb_plpythonu, + jsonb_plpython2u, and + jsonb_plpython3u (see for the PL/Python naming convention). If you + use them, jsonb values are mapped to Python dictionaries, + lists, and scalars, as appropriate. + + + + Of these extensions, jsonb_plperl is + considered trusted, that is, it can be installed by + non-superusers who have CREATE privilege on the + current database. The rest require superuser privilege to install. + + + + + jsonpath Type + + + jsonpath + + + + The jsonpath type implements support for the SQL/JSON path language + in PostgreSQL to efficiently query JSON data. + It provides a binary representation of the parsed SQL/JSON path + expression that specifies the items to be retrieved by the path + engine from the JSON data for further processing with the + SQL/JSON query functions. + + + + The semantics of SQL/JSON path predicates and operators generally follow SQL. + At the same time, to provide a natural way of working with JSON data, + SQL/JSON path syntax uses some JavaScript conventions: + + + + + + Dot (.) is used for member access. + + + + + Square brackets ([]) are used for array access. + + + + + SQL/JSON arrays are 0-relative, unlike regular SQL arrays that start from 1. + + + + + + An SQL/JSON path expression is typically written in an SQL query as an + SQL character string literal, so it must be enclosed in single quotes, + and any single quotes desired within the value must be doubled + (see ). + Some forms of path expressions require string literals within them. + These embedded string literals follow JavaScript/ECMAScript conventions: + they must be surrounded by double quotes, and backslash escapes may be + used within them to represent otherwise-hard-to-type characters. + In particular, the way to write a double quote within an embedded string + literal is \", and to write a backslash itself, you + must write \\. Other special backslash sequences + include those recognized in JSON strings: + \b, + \f, + \n, + \r, + \t, + \v + for various ASCII control characters, and + \uNNNN for a Unicode + character identified by its 4-hex-digit code point. The backslash + syntax also includes two cases not allowed by JSON: + \xNN for a character code + written with only two hex digits, and + \u{N...} for a character + code written with 1 to 6 hex digits. + + + + A path expression consists of a sequence of path elements, + which can be any of the following: + + + + Path literals of JSON primitive types: + Unicode text, numeric, true, false, or null. + + + + + Path variables listed in . + + + + + Accessor operators listed in . + + + + + jsonpath operators and methods listed + in . + + + + + Parentheses, which can be used to provide filter expressions + or define the order of path evaluation. + + + + + + + For details on using jsonpath expressions with SQL/JSON + query functions, see . + + + + <type>jsonpath</type> Variables + + + + + + Variable + Description + + + + + $ + A variable representing the JSON value being queried + (the context item). + + + + $varname + + A named variable. Its value can be set by the parameter + vars of several JSON processing functions; + see for details. + + + + + @ + A variable representing the result of path evaluation + in filter expressions. + + + + +
+ + + <type>jsonpath</type> Accessors + + + + + + Accessor Operator + Description + + + + + + + .key + + + ."$varname" + + + + + Member accessor that returns an object member with + the specified key. If the key name matches some named variable + starting with $ or does not meet the + JavaScript rules for an identifier, it must be enclosed in + double quotes to make it a string literal. + + + + + + + .* + + + + + Wildcard member accessor that returns the values of all + members located at the top level of the current object. + + + + + + + .** + + + + + Recursive wildcard member accessor that processes all levels + of the JSON hierarchy of the current object and returns all + the member values, regardless of their nesting level. This + is a PostgreSQL extension of + the SQL/JSON standard. + + + + + + + .**{level} + + + .**{start_level to + end_level} + + + + + Like .**, but selects only the specified + levels of the JSON hierarchy. Nesting levels are specified as integers. + Level zero corresponds to the current object. To access the lowest + nesting level, you can use the last keyword. + This is a PostgreSQL extension of + the SQL/JSON standard. + + + + + + + [subscript, ...] + + + + + Array element accessor. + subscript can be + given in two forms: index + or start_index to end_index. + The first form returns a single array element by its index. The second + form returns an array slice by the range of indexes, including the + elements that correspond to the provided + start_index and end_index. + + + The specified index can be an integer, as + well as an expression returning a single numeric value, which is + automatically cast to integer. Index zero corresponds to the first + array element. You can also use the last keyword + to denote the last array element, which is useful for handling arrays + of unknown length. + + + + + + + [*] + + + + + Wildcard array element accessor that returns all array elements. + + + + + +
+ +
+
diff --git a/doc/src/sgml/keywords.sgml b/doc/src/sgml/keywords.sgml new file mode 100644 index 000000000000..a7bf30c50468 --- /dev/null +++ b/doc/src/sgml/keywords.sgml @@ -0,0 +1,90 @@ + + + + <acronym>SQL</acronym> Key Words + + + key word + list of + + + + lists all tokens that are key words + in the SQL standard and in PostgreSQL + &version;. Background information can be found in . + (For space reasons, only the latest two versions of the SQL standard, and + SQL-92 for historical comparison, are included. The differences between + those and the other intermediate standard versions are small.) + + + + SQL distinguishes between reserved and + non-reserved key words. According to the standard, + reserved key words + are the only real key words; they are never allowed as identifiers. + Non-reserved key words only have a special meaning in particular + contexts and can be used as identifiers in other contexts. Most + non-reserved key words are actually the names of built-in tables + and functions specified by SQL. The concept of non-reserved key + words essentially only exists to declare that some predefined meaning + is attached to a word in some contexts. + + + + In the PostgreSQL parser, life is a bit + more complicated. There are several different classes of tokens + ranging from those that can never be used as an identifier to those + that have absolutely no special status in the parser, but are considered + ordinary identifiers. (The latter is usually the case for + functions specified by SQL.) Even reserved key words are not + completely reserved in PostgreSQL, but + can be used as column labels (for example, SELECT 55 AS + CHECK, even though CHECK is a reserved key + word). + + + + In in the column for + PostgreSQL we classify as + non-reserved those key words that are explicitly + known to the parser but are allowed as column or table names. + Some key words that are otherwise + non-reserved cannot be used as function or data type names and are + marked accordingly. (Most of these words represent built-in + functions or data types with special syntax. The function or type + is still available but it cannot be redefined by the user.) Labeled + reserved are those tokens that are not allowed as + column or table names. Some reserved key words are + allowable as names for functions or data types; this is also shown in the + table. If not so marked, a reserved key word is only allowed as a + column label. + A blank entry in this column means that the word is treated as an + ordinary identifier by PostgreSQL. + + + + Furthermore, while most key words can be used as bare + column labels without writing AS before them (as + described in ), there are a few + that require a leading AS to avoid ambiguity. These + are marked in the table as requires AS. + + + + As a general rule, if you get spurious parser errors for commands + that use any of the listed key words as an identifier, you should + try quoting the identifier to see if the problem goes away. + + + + It is important to understand before studying that the fact that a key word is not + reserved in PostgreSQL does not mean that + the feature related to the word is not implemented. Conversely, the + presence of a key word does not indicate the existence of a feature. + + + &keywords-table; + + diff --git a/doc/src/sgml/legal.sgml b/doc/src/sgml/legal.sgml new file mode 100644 index 000000000000..f3d31b002aa0 --- /dev/null +++ b/doc/src/sgml/legal.sgml @@ -0,0 +1,48 @@ + + +2021 + + + 1996–2021 + The PostgreSQL Global Development Group + + + + Legal Notice + + + PostgreSQL is Copyright © 1996–2021 + by the PostgreSQL Global Development Group. + + + + Postgres95 is Copyright © 1994–5 + by the Regents of the University of California. + + + + Permission to use, copy, modify, and distribute this software and + its documentation for any purpose, without fee, and without a + written agreement is hereby granted, provided that the above + copyright notice and this paragraph and the following two paragraphs + appear in all copies. + + + + IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY + PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL + DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS + SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA + HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + + THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE + PROVIDED HEREUNDER IS ON AN AS-IS BASIS, AND THE UNIVERSITY OF + CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, + UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + + diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml new file mode 100644 index 000000000000..641970f2a612 --- /dev/null +++ b/doc/src/sgml/libpq.sgml @@ -0,0 +1,9485 @@ + + + + <application>libpq</application> — C Library + + + libpq + + + + C + + + + libpq is the C + application programmer's interface to PostgreSQL. + libpq is a set of library functions that allow + client programs to pass queries to the PostgreSQL + backend server and to receive the results of these queries. + + + + libpq is also the underlying engine for several + other PostgreSQL application interfaces, including + those written for C++, Perl, Python, Tcl and ECPG. + So some aspects of libpq's behavior will be + important to you if you use one of those packages. In particular, + , + and + + describe behavior that is visible to the user of any application + that uses libpq. + + + + Some short programs are included at the end of this chapter () to show how + to write programs that use libpq. There are also several + complete examples of libpq applications in the + directory src/test/examples in the source code distribution. + + + + Client programs that use libpq must + include the header file + libpq-fe.hlibpq-fe.h + and must link with the libpq library. + + + + Database Connection Control Functions + + + The following functions deal with making a connection to a + PostgreSQL backend server. An + application program can have several backend connections open at + one time. (One reason to do that is to access more than one + database.) Each connection is represented by a + PGconnPGconn object, which + is obtained from the function , + , or + . Note that these functions will always + return a non-null object pointer, unless perhaps there is too + little memory even to allocate the PGconn object. + The function should be called to check + the return value for a successful connection before queries are sent + via the connection object. + + + + If untrusted users have access to a database that has not adopted a + secure schema usage pattern, + begin each session by removing publicly-writable schemas from + search_path. One can set parameter key + word options to + value -csearch_path=. Alternately, one can + issue PQexec(conn, "SELECT + pg_catalog.set_config('search_path', '', false)") after + connecting. This consideration is not specific + to libpq; it applies to every interface for + executing arbitrary SQL commands. + + + + + + On Unix, forking a process with open libpq connections can lead to + unpredictable results because the parent and child processes share + the same sockets and operating system resources. For this reason, + such usage is not recommended, though doing an exec from + the child process to load a new executable is safe. + + + + + + PQconnectdbParamsPQconnectdbParams + + + Makes a new connection to the database server. + + +PGconn *PQconnectdbParams(const char * const *keywords, + const char * const *values, + int expand_dbname); + + + + + This function opens a new database connection using the parameters taken + from two NULL-terminated arrays. The first, + keywords, is defined as an array of strings, each one + being a key word. The second, values, gives the value + for each key word. Unlike below, the parameter + set can be extended without changing the function signature, so use of + this function (or its nonblocking analogs + and PQconnectPoll) is preferred for new application + programming. + + + + The currently recognized parameter key words are listed in + . + + + + The passed arrays can be empty to use all default parameters, or can + contain one or more parameter settings. They must be matched in length. + Processing will stop at the first NULL entry + in the keywords array. + Also, if the values entry associated with a + non-NULL keywords entry is + NULL or an empty string, that entry is ignored and + processing continues with the next pair of array entries. + + + + When expand_dbname is non-zero, the value for + the first dbname key word is checked to see + if it is a connection string. If so, it + is expanded into the individual connection + parameters extracted from the string. The value is considered to + be a connection string, rather than just a database name, if it + contains an equal sign (=) or it begins with a + URI scheme designator. (More details on connection string formats + appear in .) Only the first + occurrence of dbname is treated in this way; + any subsequent dbname parameter is processed + as a plain database name. + + + + In general the parameter arrays are processed from start to end. + If any key word is repeated, the last value (that is + not NULL or empty) is used. This rule applies in + particular when a key word found in a connection string conflicts + with one appearing in the keywords array. Thus, + the programmer may determine whether array entries can override or + be overridden by values taken from a connection string. Array + entries appearing before an expanded dbname + entry can be overridden by fields of the connection string, and in + turn those fields are overridden by array entries appearing + after dbname (but, again, only if those + entries supply non-empty values). + + + + After processing all the array entries and any expanded connection + string, any connection parameters that remain unset are filled with + default values. If an unset parameter's corresponding environment + variable (see ) is set, its value is + used. If the environment variable is not set either, then the + parameter's built-in default value is used. + + + + + + + PQconnectdbPQconnectdb + + + Makes a new connection to the database server. + + +PGconn *PQconnectdb(const char *conninfo); + + + + + This function opens a new database connection using the parameters taken + from the string conninfo. + + + + The passed string can be empty to use all default parameters, or it can + contain one or more parameter settings separated by whitespace, + or it can contain a URI. + See for details. + + + + + + + + PQsetdbLoginPQsetdbLogin + + + Makes a new connection to the database server. + +PGconn *PQsetdbLogin(const char *pghost, + const char *pgport, + const char *pgoptions, + const char *pgtty, + const char *dbName, + const char *login, + const char *pwd); + + + + + This is the predecessor of with a fixed + set of parameters. It has the same functionality except that the + missing parameters will always take on default values. Write NULL or an + empty string for any one of the fixed parameters that is to be defaulted. + + + + If the dbName contains + an = sign or has a valid connection URI prefix, it + is taken as a conninfo string in exactly the same way as + if it had been passed to , and the remaining + parameters are then applied as specified for . + + + + pgtty is no longer used and any value passed will + be ignored. + + + + + + PQsetdbPQsetdb + + + Makes a new connection to the database server. + +PGconn *PQsetdb(char *pghost, + char *pgport, + char *pgoptions, + char *pgtty, + char *dbName); + + + + + This is a macro that calls with null pointers + for the login and pwd parameters. It is provided + for backward compatibility with very old programs. + + + + + + PQconnectStartParamsPQconnectStartParams + PQconnectStartPQconnectStart + PQconnectPollPQconnectPoll + + + nonblocking connection + Make a connection to the database server in a nonblocking manner. + + +PGconn *PQconnectStartParams(const char * const *keywords, + const char * const *values, + int expand_dbname); + +PGconn *PQconnectStart(const char *conninfo); + +PostgresPollingStatusType PQconnectPoll(PGconn *conn); + + + + + These three functions are used to open a connection to a database server such + that your application's thread of execution is not blocked on remote I/O + whilst doing so. The point of this approach is that the waits for I/O to + complete can occur in the application's main loop, rather than down inside + or , and so the + application can manage this operation in parallel with other activities. + + + + With , the database connection is made + using the parameters taken from the keywords and + values arrays, and controlled by expand_dbname, + as described above for . + + + + With PQconnectStart, the database connection is made + using the parameters taken from the string conninfo as + described above for . + + + + Neither nor PQconnectStart + nor PQconnectPoll will block, so long as a number of + restrictions are met: + + + + The hostaddr parameter must be used appropriately + to prevent DNS queries from being made. See the documentation of + this parameter in for details. + + + + + + If you call , ensure that the stream object + into which you trace will not block. + + + + + + You must ensure that the socket is in the appropriate state + before calling PQconnectPoll, as described below. + + + + + + + To begin a nonblocking connection request, + call PQconnectStart + or . If the result is null, + then libpq has been unable to allocate a + new PGconn structure. Otherwise, a + valid PGconn pointer is returned (though not + yet representing a valid connection to the database). Next + call PQstatus(conn). If the result + is CONNECTION_BAD, the connection attempt has already + failed, typically because of invalid connection parameters. + + + + If PQconnectStart + or succeeds, the next stage + is to poll libpq so that it can proceed with + the connection sequence. + Use PQsocket(conn) to obtain the descriptor of the + socket underlying the database connection. + (Caution: do not assume that the socket remains the same + across PQconnectPoll calls.) + Loop thus: If PQconnectPoll(conn) last returned + PGRES_POLLING_READING, wait until the socket is ready to + read (as indicated by select(), poll(), or + similar system function). + Then call PQconnectPoll(conn) again. + Conversely, if PQconnectPoll(conn) last returned + PGRES_POLLING_WRITING, wait until the socket is ready + to write, then call PQconnectPoll(conn) again. + On the first iteration, i.e., if you have yet to call + PQconnectPoll, behave as if it last returned + PGRES_POLLING_WRITING. Continue this loop until + PQconnectPoll(conn) returns + PGRES_POLLING_FAILED, indicating the connection procedure + has failed, or PGRES_POLLING_OK, indicating the connection + has been successfully made. + + + + At any time during connection, the status of the connection can be + checked by calling . If this call returns CONNECTION_BAD, then the + connection procedure has failed; if the call returns CONNECTION_OK, then the + connection is ready. Both of these states are equally detectable + from the return value of PQconnectPoll, described above. Other states might also occur + during (and only during) an asynchronous connection procedure. These + indicate the current stage of the connection procedure and might be useful + to provide feedback to the user for example. These statuses are: + + + + CONNECTION_STARTED + + + Waiting for connection to be made. + + + + + + CONNECTION_MADE + + + Connection OK; waiting to send. + + + + + + CONNECTION_AWAITING_RESPONSE + + + Waiting for a response from the server. + + + + + + CONNECTION_AUTH_OK + + + Received authentication; waiting for backend start-up to finish. + + + + + + CONNECTION_SSL_STARTUP + + + Negotiating SSL encryption. + + + + + + CONNECTION_SETENV + + + Negotiating environment-driven parameter settings. + + + + + + CONNECTION_CHECK_WRITABLE + + + Checking if connection is able to handle write transactions. + + + + + + CONNECTION_CONSUME + + + Consuming any remaining response messages on connection. + + + + + + Note that, although these constants will remain (in order to maintain + compatibility), an application should never rely upon these occurring in a + particular order, or at all, or on the status always being one of these + documented values. An application might do something like this: + +switch(PQstatus(conn)) +{ + case CONNECTION_STARTED: + feedback = "Connecting..."; + break; + + case CONNECTION_MADE: + feedback = "Connected to server..."; + break; +. +. +. + default: + feedback = "Connecting..."; +} + + + + + The connect_timeout connection parameter is ignored + when using PQconnectPoll; it is the application's + responsibility to decide whether an excessive amount of time has elapsed. + Otherwise, PQconnectStart followed by a + PQconnectPoll loop is equivalent to + . + + + + Note that when PQconnectStart + or returns a non-null + pointer, you must call when you are + finished with it, in order to dispose of the structure and any + associated memory blocks. This must be done even if the connection + attempt fails or is abandoned. + + + + + + PQconndefaultsPQconndefaults + + + Returns the default connection options. + +PQconninfoOption *PQconndefaults(void); + +typedef struct +{ + char *keyword; /* The keyword of the option */ + char *envvar; /* Fallback environment variable name */ + char *compiled; /* Fallback compiled in default value */ + char *val; /* Option's current value, or NULL */ + char *label; /* Label for field in connect dialog */ + char *dispchar; /* Indicates how to display this field + in a connect dialog. Values are: + "" Display entered value as is + "*" Password field - hide value + "D" Debug option - don't show by default */ + int dispsize; /* Field size in characters for dialog */ +} PQconninfoOption; + + + + + Returns a connection options array. This can be used to determine + all possible options and their + current default values. The return value points to an array of + PQconninfoOption structures, which ends + with an entry having a null keyword pointer. The + null pointer is returned if memory could not be allocated. Note that + the current default values (val fields) + will depend on environment variables and other context. A + missing or invalid service file will be silently ignored. Callers + must treat the connection options data as read-only. + + + + After processing the options array, free it by passing it to + . If this is not done, a small amount of memory + is leaked for each call to . + + + + + + + PQconninfoPQconninfo + + + Returns the connection options used by a live connection. + +PQconninfoOption *PQconninfo(PGconn *conn); + + + + + Returns a connection options array. This can be used to determine + all possible options and the + values that were used to connect to the server. The return + value points to an array of PQconninfoOption + structures, which ends with an entry having a null keyword + pointer. All notes above for also + apply to the result of . + + + + + + + + PQconninfoParsePQconninfoParse + + + Returns parsed connection options from the provided connection string. + + +PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); + + + + + Parses a connection string and returns the resulting options as an + array; or returns NULL if there is a problem with the connection + string. This function can be used to extract + the options in the provided + connection string. The return value points to an array of + PQconninfoOption structures, which ends + with an entry having a null keyword pointer. + + + + All legal options will be present in the result array, but the + PQconninfoOption for any option not present + in the connection string will have val set to + NULL; default values are not inserted. + + + + If errmsg is not NULL, then *errmsg is set + to NULL on success, else to a malloc'd error string explaining + the problem. (It is also possible for *errmsg to be + set to NULL and the function to return NULL; + this indicates an out-of-memory condition.) + + + + After processing the options array, free it by passing it to + . If this is not done, some memory + is leaked for each call to . + Conversely, if an error occurs and errmsg is not NULL, + be sure to free the error string using . + + + + + + + PQfinishPQfinish + + + Closes the connection to the server. Also frees + memory used by the PGconn object. + +void PQfinish(PGconn *conn); + + + + + Note that even if the server connection attempt fails (as + indicated by ), the application should call + to free the memory used by the PGconn object. + The PGconn pointer must not be used again after + has been called. + + + + + + PQresetPQreset + + + Resets the communication channel to the server. + +void PQreset(PGconn *conn); + + + + + This function will close the connection + to the server and attempt to establish a new + connection, using all the same + parameters previously used. This might be useful for + error recovery if a working connection is lost. + + + + + + PQresetStartPQresetStart + PQresetPollPQresetPoll + + + Reset the communication channel to the server, in a nonblocking manner. + + +int PQresetStart(PGconn *conn); + +PostgresPollingStatusType PQresetPoll(PGconn *conn); + + + + + These functions will close the connection to the server and attempt to + establish a new connection, using all the same + parameters previously used. This can be useful for error recovery if a + working connection is lost. They differ from (above) in that they + act in a nonblocking manner. These functions suffer from the same + restrictions as , PQconnectStart + and PQconnectPoll. + + + + To initiate a connection reset, call + . If it returns 0, the reset has + failed. If it returns 1, poll the reset using + PQresetPoll in exactly the same way as you + would create the connection using PQconnectPoll. + + + + + + PQpingParamsPQpingParams + + + reports the status of the + server. It accepts connection parameters identical to those of + , described above. It is not + necessary to supply correct user name, password, or database name + values to obtain the server status; however, if incorrect values + are provided, the server will log a failed connection attempt. + + +PGPing PQpingParams(const char * const *keywords, + const char * const *values, + int expand_dbname); + + + The function returns one of the following values: + + + + PQPING_OK + + + The server is running and appears to be accepting connections. + + + + + + PQPING_REJECT + + + The server is running but is in a state that disallows connections + (startup, shutdown, or crash recovery). + + + + + + PQPING_NO_RESPONSE + + + The server could not be contacted. This might indicate that the + server is not running, or that there is something wrong with the + given connection parameters (for example, wrong port number), or + that there is a network connectivity problem (for example, a + firewall blocking the connection request). + + + + + + PQPING_NO_ATTEMPT + + + No attempt was made to contact the server, because the supplied + parameters were obviously incorrect or there was some client-side + problem (for example, out of memory). + + + + + + + + + + + + PQpingPQping + + + reports the status of the + server. It accepts connection parameters identical to those of + , described above. It is not + necessary to supply correct user name, password, or database name + values to obtain the server status; however, if incorrect values + are provided, the server will log a failed connection attempt. + + +PGPing PQping(const char *conninfo); + + + + + The return values are the same as for . + + + + + + + PQsetSSLKeyPassHook_OpenSSLPQsetSSLKeyPassHook_OpenSSL + + + PQsetSSLKeyPassHook_OpenSSL lets an application override + libpq's default + handling of encrypted client certificate key files using + or interactive prompting. + + +void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook); + + + The application passes a pointer to a callback function with signature: + +int callback_fn(char *buf, int size, PGconn *conn); + + which libpq will then call + instead of its default + PQdefaultSSLKeyPassHook_OpenSSL handler. The + callback should determine the password for the key and copy it to + result-buffer buf of size + size. The string in buf + must be null-terminated. The callback must return the length of the + password stored in buf excluding the null + terminator. On failure, the callback should set + buf[0] = '\0' and return 0. See + PQdefaultSSLKeyPassHook_OpenSSL in + libpq's source code for an example. + + + + If the user specified an explicit key location, + its path will be in conn->sslkey when the callback + is invoked. This will be empty if the default key path is being used. + For keys that are engine specifiers, it is up to engine implementations + whether they use the OpenSSL password + callback or define their own handling. + + + + The app callback may choose to delegate unhandled cases to + PQdefaultSSLKeyPassHook_OpenSSL, + or call it first and try something else if it returns 0, or completely override it. + + + + The callback must not escape normal flow control with exceptions, + longjmp(...), etc. It must return normally. + + + + + + + PQgetSSLKeyPassHook_OpenSSLPQgetSSLKeyPassHook_OpenSSL + + + PQgetSSLKeyPassHook_OpenSSL returns the current + client certificate key password hook, or NULL + if none has been set. + + +PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void); + + + + + + + + + + + Connection Strings + + + conninfo + + + + URI + + + + Several libpq functions parse a user-specified string to obtain + connection parameters. There are two accepted formats for these strings: + plain keyword/value strings + and URIs. URIs generally follow + RFC + 3986, except that multi-host connection strings are allowed + as further described below. + + + + Keyword/Value Connection Strings + + + In the keyword/value format, each parameter setting is in the form + keyword = + value, with space(s) between settings. + Spaces around a setting's equal sign are + optional. To write an empty value, or a value containing spaces, surround it + with single quotes, for example keyword = 'a value'. + Single quotes and backslashes within + a value must be escaped with a backslash, i.e., \' and + \\. + + + + Example: + +host=localhost port=5432 dbname=mydb connect_timeout=10 + + + + + The recognized parameter key words are listed in . + + + + + Connection URIs + + + The general form for a connection URI is: + +postgresql://userspec@hostspec/dbname?paramspec + +where userspec is: + +user:password + +and hostspec is: + +host:port,... + +and paramspec is: + +name=value&... + + + + + The URI scheme designator can be either + postgresql:// or postgres://. Each + of the remaining URI parts is optional. The + following examples illustrate valid URI syntax: + +postgresql:// +postgresql://localhost +postgresql://localhost:5433 +postgresql://localhost/mydb +postgresql://user@localhost +postgresql://user:secret@localhost +postgresql://other@localhost/otherdb?connect_timeout=10&application_name=myapp +postgresql://host1:123,host2:456/somedb?target_session_attrs=any&application_name=myapp + + Values that would normally appear in the hierarchical part of + the URI can alternatively be given as named + parameters. For example: + +postgresql:///mydb?host=localhost&port=5433 + + All named parameters must match key words listed in + , except that for compatibility + with JDBC connection URIs, instances + of ssl=true are translated into + sslmode=require. + + + + The connection URI needs to be encoded with percent-encoding + if it includes symbols with special meaning in any of its parts. Here is + an example where the equal sign (=) is replaced with + %3D and the space character with + %20: + +postgresql://user@localhost:5433/mydb?options=-c%20synchronous_commit%3Doff + + + + + The host part may be either a host name or an IP address. To specify an + IPv6 address, enclose it in square brackets: + +postgresql://[2001:db8::1234]/database + + + + + The host part is interpreted as described for the parameter . In particular, a Unix-domain socket + connection is chosen if the host part is either empty or looks like an + absolute path name, + otherwise a TCP/IP connection is initiated. Note, however, that the + slash is a reserved character in the hierarchical part of the URI. So, to + specify a non-standard Unix-domain socket directory, either omit the host + part of the URI and specify the host as a named parameter, or + percent-encode the path in the host part of the URI: + +postgresql:///dbname?host=/var/lib/postgresql +postgresql://%2Fvar%2Flib%2Fpostgresql/dbname + + + + + It is possible to specify multiple host components, each with an optional + port component, in a single URI. A URI of the form + postgresql://host1:port1,host2:port2,host3:port3/ + is equivalent to a connection string of the form + host=host1,host2,host3 port=port1,port2,port3. + As further described below, each + host will be tried in turn until a connection is successfully established. + + + + + Specifying Multiple Hosts + + + It is possible to specify multiple hosts to connect to, so that they are + tried in the given order. In the Keyword/Value format, the host, + hostaddr, and port options accept comma-separated + lists of values. The same number of elements must be given in each + option that is specified, such + that e.g., the first hostaddr corresponds to the first host name, + the second hostaddr corresponds to the second host name, and so + forth. As an exception, if only one port is specified, it + applies to all the hosts. + + + + In the connection URI format, you can list multiple host:port pairs + separated by commas in the host component of the URI. + + + + In either format, a single host name can translate to multiple network + addresses. A common example of this is a host that has both an IPv4 and + an IPv6 address. + + + + When multiple hosts are specified, or when a single host name is + translated to multiple addresses, all the hosts and addresses will be + tried in order, until one succeeds. If none of the hosts can be reached, + the connection fails. If a connection is established successfully, but + authentication fails, the remaining hosts in the list are not tried. + + + + If a password file is used, you can have different passwords for + different hosts. All the other connection options are the same for every + host in the list; it is not possible to e.g., specify different + usernames for different hosts. + + + + + + Parameter Key Words + + + The currently recognized parameter key words are: + + + + host + + + Name of host to connect to.host + name If a host name looks like an absolute path + name, it specifies Unix-domain communication rather than TCP/IP + communication; the value is the name of the directory in which the + socket file is stored. (On Unix, an absolute path name begins with a + slash. On Windows, paths starting with drive letters are also + recognized.) If the host name starts with @, it is + taken as a Unix-domain socket in the abstract namespace (currently + supported on Linux and Windows). + The default behavior when host is not + specified, or is empty, is to connect to a Unix-domain + socketUnix domain socket in + /tmp (or whatever socket directory was specified + when PostgreSQL was built). On Windows and + on machines without Unix-domain sockets, the default is to connect to + localhost. + + + A comma-separated list of host names is also accepted, in which case + each host name in the list is tried in order; an empty item in the + list selects the default behavior as explained above. See + for details. + + + + + + hostaddr + + + Numeric IP address of host to connect to. This should be in the + standard IPv4 address format, e.g., 172.28.40.9. If + your machine supports IPv6, you can also use those addresses. + TCP/IP communication is + always used when a nonempty string is specified for this parameter. + If this parameter is not specified, the value of host + will be looked up to find the corresponding IP address — or, if + host specifies an IP address, that value will be + used directly. + + + + Using hostaddr allows the + application to avoid a host name look-up, which might be important + in applications with time constraints. However, a host name is + required for GSSAPI or SSPI authentication + methods, as well as for verify-full SSL + certificate verification. The following rules are used: + + + + If host is specified + without hostaddr, a host name lookup occurs. + (When using PQconnectPoll, the lookup occurs + when PQconnectPoll first considers this host + name, and it may cause PQconnectPoll to block + for a significant amount of time.) + + + + + If hostaddr is specified without host, + the value for hostaddr gives the server network address. + The connection attempt will fail if the authentication + method requires a host name. + + + + + If both host and hostaddr are specified, + the value for hostaddr gives the server network address. + The value for host is ignored unless the + authentication method requires it, in which case it will be + used as the host name. + + + + Note that authentication is likely to fail if host + is not the name of the server at network address hostaddr. + Also, when both host and hostaddr + are specified, host + is used to identify the connection in a password file (see + ). + + + + A comma-separated list of hostaddr values is also + accepted, in which case each host in the list is tried in order. + An empty item in the list causes the corresponding host name to be + used, or the default host name if that is empty as well. See + for details. + + + Without either a host name or host address, + libpq will connect using a local + Unix-domain socket; or on Windows and on machines without Unix-domain + sockets, it will attempt to connect to localhost. + + + + + + port + + + Port number to connect to at the server host, or socket file + name extension for Unix-domain + connections.port + If multiple hosts were given in the host or + hostaddr parameters, this parameter may specify a + comma-separated list of ports of the same length as the host list, or + it may specify a single port number to be used for all hosts. + An empty string, or an empty item in a comma-separated list, + specifies the default port number established + when PostgreSQL was built. + + + + + + dbname + + + The database name. Defaults to be the same as the user name. + In certain contexts, the value is checked for extended + formats; see for more details on + those. + + + + + + user + + + PostgreSQL user name to connect as. + Defaults to be the same as the operating system name of the user + running the application. + + + + + + password + + + Password to be used if the server demands password authentication. + + + + + + passfile + + + Specifies the name of the file used to store passwords + (see ). + Defaults to ~/.pgpass, or + %APPDATA%\postgresql\pgpass.conf on Microsoft Windows. + (No error is reported if this file does not exist.) + + + + + + channel_binding + + + This option controls the client's use of channel binding. A setting + of require means that the connection must employ + channel binding, prefer means that the client will + choose channel binding if available, and disable + prevents the use of channel binding. The default + is prefer if + PostgreSQL is compiled with SSL support; + otherwise the default is disable. + + + Channel binding is a method for the server to authenticate itself to + the client. It is only supported over SSL connections + with PostgreSQL 11 or later servers using + the SCRAM authentication method. + + + + + + connect_timeout + + + Maximum time to wait while connecting, in seconds (write as a decimal integer, + e.g., 10). Zero, negative, or not specified means + wait indefinitely. The minimum allowed timeout is 2 seconds, therefore + a value of 1 is interpreted as 2. + This timeout applies separately to each host name or IP address. + For example, if you specify two hosts and connect_timeout + is 5, each host will time out if no connection is made within 5 + seconds, so the total time spent waiting for a connection might be + up to 10 seconds. + + + + + + client_encoding + + + This sets the client_encoding + configuration parameter for this connection. In addition to + the values accepted by the corresponding server option, you + can use auto to determine the right + encoding from the current locale in the client + (LC_CTYPE environment variable on Unix + systems). + + + + + + options + + + Specifies command-line options to send to the server at connection + start. For example, setting this to -c geqo=off sets the + session's value of the geqo parameter to + off. Spaces within this string are considered to + separate command-line arguments, unless escaped with a backslash + (\); write \\ to represent a literal + backslash. For a detailed discussion of the available + options, consult . + + + + + + application_name + + + Specifies a value for the + configuration parameter. + + + + + + fallback_application_name + + + Specifies a fallback value for the configuration parameter. + This value will be used if no value has been given for + application_name via a connection parameter or the + PGAPPNAME environment variable. Specifying + a fallback name is useful in generic utility programs that + wish to set a default application name but allow it to be + overridden by the user. + + + + + + keepalives + + + Controls whether client-side TCP keepalives are used. The default + value is 1, meaning on, but you can change this to 0, meaning off, + if keepalives are not wanted. This parameter is ignored for + connections made via a Unix-domain socket. + + + + + + keepalives_idle + + + Controls the number of seconds of inactivity after which TCP should + send a keepalive message to the server. A value of zero uses the + system default. This parameter is ignored for connections made via a + Unix-domain socket, or if keepalives are disabled. + It is only supported on systems where TCP_KEEPIDLE or + an equivalent socket option is available, and on Windows; on other + systems, it has no effect. + + + + + + keepalives_interval + + + Controls the number of seconds after which a TCP keepalive message + that is not acknowledged by the server should be retransmitted. A + value of zero uses the system default. This parameter is ignored for + connections made via a Unix-domain socket, or if keepalives are disabled. + It is only supported on systems where TCP_KEEPINTVL or + an equivalent socket option is available, and on Windows; on other + systems, it has no effect. + + + + + + keepalives_count + + + Controls the number of TCP keepalives that can be lost before the + client's connection to the server is considered dead. A value of + zero uses the system default. This parameter is ignored for + connections made via a Unix-domain socket, or if keepalives are disabled. + It is only supported on systems where TCP_KEEPCNT or + an equivalent socket option is available; on other systems, it has no + effect. + + + + + + tcp_user_timeout + + + Controls the number of milliseconds that transmitted data may + remain unacknowledged before a connection is forcibly closed. + A value of zero uses the system default. This parameter is + ignored for connections made via a Unix-domain socket. + It is only supported on systems where TCP_USER_TIMEOUT + is available; on other systems, it has no effect. + + + + + + tty + + + Ignored (formerly, this specified where to send server debug output). + + + + + + replication + + + This option determines whether the connection should use the + replication protocol instead of the normal protocol. This is what + PostgreSQL replication connections as well as tools such as + pg_basebackup use internally, but it can + also be used by third-party applications. For a description of the + replication protocol, consult . + + + + The following values, which are case-insensitive, are supported: + + + + true, on, + yes, 1 + + + + The connection goes into physical replication mode. + + + + + + database + + + The connection goes into logical replication mode, connecting to + the database specified in the dbname parameter. + + + + + + + false, off, + no, 0 + + + + The connection is a regular one, which is the default behavior. + + + + + + + + In physical or logical replication mode, only the simple query protocol + can be used. + + + + + + gssencmode + + + This option determines whether or with what priority a secure + GSS TCP/IP connection will be negotiated with the + server. There are three modes: + + + + disable + + + only try a non-GSSAPI-encrypted connection + + + + + + prefer (default) + + + if there are GSSAPI credentials present (i.e., + in a credentials cache), first try + a GSSAPI-encrypted connection; if that fails or + there are no credentials, try a + non-GSSAPI-encrypted connection. This is the + default when PostgreSQL has been + compiled with GSSAPI support. + + + + + + require + + + only try a GSSAPI-encrypted connection + + + + + + + + gssencmode is ignored for Unix domain socket + communication. If PostgreSQL is compiled + without GSSAPI support, using the require option + will cause an error, while prefer will be accepted + but libpq will not actually attempt + a GSSAPI-encrypted + connection.GSSAPIwith + libpq + + + + + + sslmode + + + This option determines whether or with what priority a secure + SSL TCP/IP connection will be negotiated with the + server. There are six modes: + + + + disable + + + only try a non-SSL connection + + + + + + allow + + + first try a non-SSL connection; if that + fails, try an SSL connection + + + + + + prefer (default) + + + first try an SSL connection; if that fails, + try a non-SSL connection + + + + + + require + + + only try an SSL connection. If a root CA + file is present, verify the certificate in the same way as + if verify-ca was specified + + + + + + verify-ca + + + only try an SSL connection, and verify that + the server certificate is issued by a trusted + certificate authority (CA) + + + + + + verify-full + + + only try an SSL connection, verify that the + server certificate is issued by a + trusted CA and that the requested server host name + matches that in the certificate + + + + + + See for a detailed description of how + these options work. + + + + sslmode is ignored for Unix domain socket + communication. + If PostgreSQL is compiled without SSL support, + using options require, verify-ca, or + verify-full will cause an error, while + options allow and prefer will be + accepted but libpq will not actually attempt + an SSL + connection.SSLwith libpq + + + + Note that if GSSAPI encryption is possible, + that will be used in preference to SSL + encryption, regardless of the value of sslmode. + To force use of SSL encryption in an + environment that has working GSSAPI + infrastructure (such as a Kerberos server), also + set gssencmode to disable. + + + + + + requiressl + + + This option is deprecated in favor of the sslmode + setting. + + + + If set to 1, an SSL connection to the server + is required (this is equivalent to sslmode + require). libpq will then refuse + to connect if the server does not accept an + SSL connection. If set to 0 (default), + libpq will negotiate the connection type with + the server (equivalent to sslmode + prefer). This option is only available if + PostgreSQL is compiled with SSL support. + + + + + + sslcompression + + + If set to 1, data sent over SSL connections will be compressed. If + set to 0, compression will be disabled. The default is 0. This + parameter is ignored if a connection without SSL is made. + + + + SSL compression is nowadays considered insecure and its use is no + longer recommended. OpenSSL 1.1.0 disables + compression by default, and many operating system distributions + disable it in prior versions as well, so setting this parameter to on + will not have any effect if the server does not accept compression. + PostgreSQL 14 disables compression + completely in the backend. + + + + If security is not a primary concern, compression can improve + throughput if the network is the bottleneck. Disabling compression + can improve response time and throughput if CPU performance is the + limiting factor. + + + + + + sslcert + + + This parameter specifies the file name of the client SSL + certificate, replacing the default + ~/.postgresql/postgresql.crt. + This parameter is ignored if an SSL connection is not made. + + + + + + sslkey + + + This parameter specifies the location for the secret key used for + the client certificate. It can either specify a file name that will + be used instead of the default + ~/.postgresql/postgresql.key, or it can specify a key + obtained from an external engine (engines are + OpenSSL loadable modules). An external engine + specification should consist of a colon-separated engine name and + an engine-specific key identifier. This parameter is ignored if an + SSL connection is not made. + + + + + + sslpassword + + + This parameter specifies the password for the secret key specified in + sslkey, allowing client certificate private keys + to be stored in encrypted form on disk even when interactive passphrase + input is not practical. + + + Specifying this parameter with any non-empty value suppresses the + Enter PEM pass phrase: + prompt that OpenSSL will emit by default + when an encrypted client certificate key is provided to + libpq. + + + If the key is not encrypted this parameter is ignored. The parameter + has no effect on keys specified by OpenSSL + engines unless the engine uses the OpenSSL + password callback mechanism for prompts. + + + There is no environment variable equivalent to this option, and no + facility for looking it up in .pgpass. It can be + used in a service file connection definition. Users with + more sophisticated uses should consider using openssl engines and + tools like PKCS#11 or USB crypto offload devices. + + + + + + sslrootcert + + + This parameter specifies the name of a file containing SSL + certificate authority (CA) certificate(s). + If the file exists, the server's certificate will be verified + to be signed by one of these authorities. The default is + ~/.postgresql/root.crt. + + + + + + sslcrl + + + This parameter specifies the file name of the SSL certificate + revocation list (CRL). Certificates listed in this file, if it + exists, will be rejected while attempting to authenticate the + server's certificate. If neither + nor + is set, this setting is + taken as + ~/.postgresql/root.crl. + + + + + + sslcrldir + + + This parameter specifies the directory name of the SSL certificate + revocation list (CRL). Certificates listed in the files in this + directory, if it exists, will be rejected while attempting to + authenticate the server's certificate. + + + + The directory needs to be prepared with the + OpenSSL command + openssl rehash or c_rehash. See + its documentation for details. + + + + Both sslcrl and sslcrldir can be + specified together. + + + + + + sslsniServer Name Indication + + + By default, libpq sets the TLS extension Server Name + Indication (SNI) on SSL-enabled connections. + By setting this parameter to 0, this is turned off. + + + + The Server Name Indication can be used by SSL-aware proxies to route + connections without having to decrypt the SSL stream. (Note that this + requires a proxy that is aware of the PostgreSQL protocol handshake, + not just any SSL proxy.) However, SNI makes the + destination host name appear in cleartext in the network traffic, so + it might be undesirable in some cases. + + + + + + requirepeer + + + This parameter specifies the operating-system user name of the + server, for example requirepeer=postgres. + When making a Unix-domain socket connection, if this + parameter is set, the client checks at the beginning of the + connection that the server process is running under the specified + user name; if it is not, the connection is aborted with an error. + This parameter can be used to provide server authentication similar + to that available with SSL certificates on TCP/IP connections. + (Note that if the Unix-domain socket is in + /tmp or another publicly writable location, + any user could start a server listening there. Use this parameter + to ensure that you are connected to a server run by a trusted user.) + This option is only supported on platforms for which the + peer authentication method is implemented; see + . + + + + + + ssl_min_protocol_version + + + This parameter specifies the minimum SSL/TLS protocol version to allow + for the connection. Valid values are TLSv1, + TLSv1.1, TLSv1.2 and + TLSv1.3. The supported protocols depend on the + version of OpenSSL used, older versions + not supporting the most modern protocol versions. If not specified, + the default is TLSv1.2, which satisfies industry + best practices as of this writing. + + + + + + ssl_max_protocol_version + + + This parameter specifies the maximum SSL/TLS protocol version to allow + for the connection. Valid values are TLSv1, + TLSv1.1, TLSv1.2 and + TLSv1.3. The supported protocols depend on the + version of OpenSSL used, older versions + not supporting the most modern protocol versions. If not set, this + parameter is ignored and the connection will use the maximum bound + defined by the backend, if set. Setting the maximum protocol version + is mainly useful for testing or if some component has issues working + with a newer protocol. + + + + + + krbsrvname + + + Kerberos service name to use when authenticating with GSSAPI. + This must match the service name specified in the server + configuration for Kerberos authentication to succeed. (See also + .) + The default value is normally postgres, + but that can be changed when + building PostgreSQL via + the option + of configure. + In most environments, this parameter never needs to be changed. + Some Kerberos implementations might require a different service name, + such as Microsoft Active Directory which requires the service name + to be in upper case (POSTGRES). + + + + + + gsslib + + + GSS library to use for GSSAPI authentication. + Currently this is disregarded except on Windows builds that include + both GSSAPI and SSPI support. In that case, set + this to gssapi to cause libpq to use the GSSAPI + library for authentication instead of the default SSPI. + + + + + + service + + + Service name to use for additional parameters. It specifies a service + name in pg_service.conf that holds additional connection parameters. + This allows applications to specify only a service name so connection parameters + can be centrally maintained. See . + + + + + + target_session_attrs + + + This option determines whether the session must have certain + properties to be acceptable. It's typically used in combination + with multiple host names to select the first acceptable alternative + among several hosts. There are six modes: + + + + any (default) + + + any successful connection is acceptable + + + + + + read-write + + + session must accept read-write transactions by default (that + is, the server must not be in hot standby mode and + the default_transaction_read_only parameter + must be off) + + + + + + read-only + + + session must not accept read-write transactions by default (the + converse) + + + + + + primary + + + server must not be in hot standby mode + + + + + + standby + + + server must be in hot standby mode + + + + + + prefer-standby + + + first try to find a standby server, but if none of the listed + hosts is a standby server, try again in any + mode + + + + + + + + + + + + + + Connection Status Functions + + + These functions can be used to interrogate the status + of an existing database connection object. + + + + + libpq-fe.h + libpq-int.h + libpq application programmers should be careful to + maintain the PGconn abstraction. Use the accessor + functions described below to get at the contents of PGconn. + Reference to internal PGconn fields using + libpq-int.h is not recommended because they are subject to change + in the future. + + + + + The following functions return parameter values established at connection. + These values are fixed for the life of the connection. If a multi-host + connection string is used, the values of , + , and can change if a new connection + is established using the same PGconn object. Other values + are fixed for the lifetime of the PGconn object. + + + + PQdbPQdb + + + + Returns the database name of the connection. + +char *PQdb(const PGconn *conn); + + + + + + + PQuserPQuser + + + + Returns the user name of the connection. + +char *PQuser(const PGconn *conn); + + + + + + + PQpassPQpass + + + + Returns the password of the connection. + +char *PQpass(const PGconn *conn); + + + + + will return either the password specified + in the connection parameters, or if there was none and the password + was obtained from the password + file, it will return that. In the latter case, + if multiple hosts were specified in the connection parameters, it is + not possible to rely on the result of until + the connection is established. The status of the connection can be + checked using the function . + + + + + + PQhostPQhost + + + + Returns the server host name of the active connection. + This can be a host name, an IP address, or a directory path if the + connection is via Unix socket. (The path case can be distinguished + because it will always be an absolute path, beginning + with /.) + +char *PQhost(const PGconn *conn); + + + + + If the connection parameters specified both host and + hostaddr, then will + return the host information. If only + hostaddr was specified, then that is returned. + If multiple hosts were specified in the connection parameters, + returns the host actually connected to. + + + + returns NULL if the + conn argument is NULL. + Otherwise, if there is an error producing the host information (perhaps + if the connection has not been fully established or there was an + error), it returns an empty string. + + + + If multiple hosts were specified in the connection parameters, it is + not possible to rely on the result of until + the connection is established. The status of the connection can be + checked using the function . + + + + + + + PQhostaddrPQhostaddr + + + + Returns the server IP address of the active connection. + This can be the address that a host name resolved to, + or an IP address provided through the hostaddr + parameter. + +char *PQhostaddr(const PGconn *conn); + + + + + returns NULL if the + conn argument is NULL. + Otherwise, if there is an error producing the host information + (perhaps if the connection has not been fully established or + there was an error), it returns an empty string. + + + + + + PQportPQport + + + + Returns the port of the active connection. + + +char *PQport(const PGconn *conn); + + + + + If multiple ports were specified in the connection parameters, + returns the port actually connected to. + + + + returns NULL if the + conn argument is NULL. + Otherwise, if there is an error producing the port information (perhaps + if the connection has not been fully established or there was an + error), it returns an empty string. + + + + If multiple ports were specified in the connection parameters, it is + not possible to rely on the result of until + the connection is established. The status of the connection can be + checked using the function . + + + + + + PQttyPQtty + + + + This function no longer does anything, but it remains for backwards + compatibility. The function always return an empty string, or + NULL if the conn argument is + NULL. + + +char *PQtty(const PGconn *conn); + + + + + + + PQoptionsPQoptions + + + + Returns the command-line options passed in the connection request. + +char *PQoptions(const PGconn *conn); + + + + + + + + + The following functions return status data that can change as operations + are executed on the PGconn object. + + + + PQstatusPQstatus + + + + Returns the status of the connection. + +ConnStatusType PQstatus(const PGconn *conn); + + + + + The status can be one of a number of values. However, only two of + these are seen outside of an asynchronous connection procedure: + CONNECTION_OK and + CONNECTION_BAD. A good connection to the database + has the status CONNECTION_OK. A failed + connection attempt is signaled by status + CONNECTION_BAD. Ordinarily, an OK status will + remain so until , but a communications + failure might result in the status changing to + CONNECTION_BAD prematurely. In that case the + application could try to recover by calling + . + + + + See the entry for , PQconnectStart + and PQconnectPoll with regards to other status codes that + might be returned. + + + + + + PQtransactionStatusPQtransactionStatus + + + + Returns the current in-transaction status of the server. + + +PGTransactionStatusType PQtransactionStatus(const PGconn *conn); + + + The status can be PQTRANS_IDLE (currently idle), + PQTRANS_ACTIVE (a command is in progress), + PQTRANS_INTRANS (idle, in a valid transaction block), + or PQTRANS_INERROR (idle, in a failed transaction block). + PQTRANS_UNKNOWN is reported if the connection is bad. + PQTRANS_ACTIVE is reported only when a query + has been sent to the server and not yet completed. + + + + + + PQparameterStatusPQparameterStatus + + + + Looks up a current parameter setting of the server. + + +const char *PQparameterStatus(const PGconn *conn, const char *paramName); + + + Certain parameter values are reported by the server automatically at + connection startup or whenever their values change. + can be used to interrogate these settings. + It returns the current value of a parameter if known, or NULL + if the parameter is not known. + + + + Parameters reported as of the current release include + server_version, + server_encoding, + client_encoding, + application_name, + default_transaction_read_only, + in_hot_standby, + is_superuser, + session_authorization, + DateStyle, + IntervalStyle, + TimeZone, + integer_datetimes, and + standard_conforming_strings. + (server_encoding, TimeZone, and + integer_datetimes were not reported by releases before 8.0; + standard_conforming_strings was not reported by releases + before 8.1; + IntervalStyle was not reported by releases before 8.4; + application_name was not reported by releases before + 9.0; + default_transaction_read_only and + in_hot_standby were not reported by releases before + 14.) + Note that + server_version, + server_encoding and + integer_datetimes + cannot change after startup. + + + + If no value for standard_conforming_strings is reported, + applications can assume it is off, that is, backslashes + are treated as escapes in string literals. Also, the presence of + this parameter can be taken as an indication that the escape string + syntax (E'...') is accepted. + + + + Although the returned pointer is declared const, it in fact + points to mutable storage associated with the PGconn structure. + It is unwise to assume the pointer will remain valid across queries. + + + + + + PQprotocolVersionPQprotocolVersion + + + + Interrogates the frontend/backend protocol being used. + +int PQprotocolVersion(const PGconn *conn); + + Applications might wish to use this function to determine whether certain + features are supported. Currently, the possible values are 3 + (3.0 protocol), or zero (connection bad). The protocol version will + not change after connection startup is complete, but it could + theoretically change during a connection reset. The 3.0 protocol is + supported by PostgreSQL server versions 7.4 + and above. + + + + + + PQserverVersionPQserverVersion + + + + Returns an integer representing the server version. + +int PQserverVersion(const PGconn *conn); + + + + + Applications might use this function to determine the version of the + database server they are connected to. The result is formed by + multiplying the server's major version number by 10000 and adding + the minor version number. For example, version 10.1 will be + returned as 100001, and version 11.0 will be returned as 110000. + Zero is returned if the connection is bad. + + + + Prior to major version 10, PostgreSQL used + three-part version numbers in which the first two parts together + represented the major version. For those + versions, uses two digits for each + part; for example version 9.1.5 will be returned as 90105, and + version 9.2.0 will be returned as 90200. + + + + Therefore, for purposes of determining feature compatibility, + applications should divide the result of + by 100 not 10000 to determine a logical major version number. + In all release series, only the last two digits differ between + minor releases (bug-fix releases). + + + + + + PQerrorMessagePQerrorMessage + + + + error message Returns the error message + most recently generated by an operation on the connection. + + +char *PQerrorMessage(const PGconn *conn); + + + + + + Nearly all libpq functions will set a message for + if they fail. Note that by + libpq convention, a nonempty + result can consist of multiple lines, + and will include a trailing newline. The caller should not free + the result directly. It will be freed when the associated + PGconn handle is passed to + . The result string should not be + expected to remain the same across operations on the + PGconn structure. + + + + + + PQsocketPQsocket + + + Obtains the file descriptor number of the connection socket to + the server. A valid descriptor will be greater than or equal + to 0; a result of -1 indicates that no server connection is + currently open. (This will not change during normal operation, + but could change during connection setup or reset.) + + +int PQsocket(const PGconn *conn); + + + + + + + + PQbackendPIDPQbackendPID + + + Returns the process ID (PID) + PID + determining PID of server process + in libpq + + of the backend process handling this connection. + + +int PQbackendPID(const PGconn *conn); + + + + + The backend PID is useful for debugging + purposes and for comparison to NOTIFY + messages (which include the PID of the + notifying backend process). Note that the + PID belongs to a process executing on the + database server host, not the local host! + + + + + + PQconnectionNeedsPasswordPQconnectionNeedsPassword + + + Returns true (1) if the connection authentication method + required a password, but none was available. + Returns false (0) if not. + + +int PQconnectionNeedsPassword(const PGconn *conn); + + + + + This function can be applied after a failed connection attempt + to decide whether to prompt the user for a password. + + + + + + PQconnectionUsedPasswordPQconnectionUsedPassword + + + Returns true (1) if the connection authentication method + used a password. Returns false (0) if not. + + +int PQconnectionUsedPassword(const PGconn *conn); + + + + + This function can be applied after either a failed or successful + connection attempt to detect whether the server demanded a password. + + + + + + + + The following functions return information related to SSL. This information + usually doesn't change after a connection is established. + + + + PQsslInUsePQsslInUse + + + Returns true (1) if the connection uses SSL, false (0) if not. + + +int PQsslInUse(const PGconn *conn); + + + + + + + + PQsslAttributePQsslAttribute + + + Returns SSL-related information about the connection. + + +const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); + + + + + The list of available attributes varies depending on the SSL library + being used, and the type of connection. If an attribute is not + available, returns NULL. + + + + The following attributes are commonly available: + + + library + + + Name of the SSL implementation in use. (Currently, only + "OpenSSL" is implemented) + + + + + protocol + + + SSL/TLS version in use. Common values + are "TLSv1", "TLSv1.1" + and "TLSv1.2", but an implementation may + return other strings if some other protocol is used. + + + + + key_bits + + + Number of key bits used by the encryption algorithm. + + + + + cipher + + + A short name of the ciphersuite used, e.g., + "DHE-RSA-DES-CBC3-SHA". The names are specific + to each SSL implementation. + + + + + compression + + + If SSL compression is in use, returns the name of the compression + algorithm, or "on" if compression is used but the algorithm is + not known. If compression is not in use, returns "off". + + + + + + + + + + PQsslAttributeNamesPQsslAttributeNames + + + Return an array of SSL attribute names available. The array is terminated by a NULL pointer. + +const char * const * PQsslAttributeNames(const PGconn *conn); + + + + + + + PQsslStructPQsslStruct + + + Return a pointer to an SSL-implementation-specific object describing + the connection. + +void *PQsslStruct(const PGconn *conn, const char *struct_name); + + + + The struct(s) available depend on the SSL implementation in use. + For OpenSSL, there is one struct, + available under the name "OpenSSL", and it returns a pointer to the + OpenSSL SSL struct. + To use this function, code along the following lines could be used: + +#include + +... + + SSL *ssl; + + dbconn = PQconnectdb(...); + ... + + ssl = PQsslStruct(dbconn, "OpenSSL"); + if (ssl) + { + /* use OpenSSL functions to access ssl */ + } +]]> + + + This structure can be used to verify encryption levels, check server + certificates, and more. Refer to the OpenSSL + documentation for information about this structure. + + + + + + PQgetsslPQgetssl + + + SSLin libpq + Returns the SSL structure used in the connection, or null + if SSL is not in use. + + +void *PQgetssl(const PGconn *conn); + + + + + This function is equivalent to PQsslStruct(conn, "OpenSSL"). It should + not be used in new applications, because the returned struct is + specific to OpenSSL and will not be + available if another SSL implementation is used. + To check if a connection uses SSL, call + instead, and for more details about the + connection, use . + + + + + + + + + + + Command Execution Functions + + + Once a connection to a database server has been successfully + established, the functions described here are used to perform + SQL queries and commands. + + + + Main Functions + + + + + PQexecPQexec + + + + Submits a command to the server and waits for the result. + + +PGresult *PQexec(PGconn *conn, const char *command); + + + + + Returns a PGresult pointer or possibly a null + pointer. A non-null pointer will generally be returned except in + out-of-memory conditions or serious errors such as inability to send + the command to the server. The function + should be called to check the return value for any errors (including + the value of a null pointer, in which case it will return + PGRES_FATAL_ERROR). Use + to get more information about such + errors. + + + + + + The command string can include multiple SQL commands + (separated by semicolons). Multiple queries sent in a single + call are processed in a single transaction, unless + there are explicit BEGIN/COMMIT + commands included in the query string to divide it into multiple + transactions. (See + for more details about how the server handles multi-query strings.) + Note however that the returned + PGresult structure describes only the result + of the last command executed from the string. Should one of the + commands fail, processing of the string stops with it and the returned + PGresult describes the error condition. + + + + + + PQexecParamsPQexecParams + + + + Submits a command to the server and waits for the result, + with the ability to pass parameters separately from the SQL + command text. + + +PGresult *PQexecParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char * const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + + + + + is like , but offers additional + functionality: parameter values can be specified separately from the command + string proper, and query results can be requested in either text or binary + format. + + + + The function arguments are: + + + + conn + + + + The connection object to send the command through. + + + + + + command + + + The SQL command string to be executed. If parameters are used, + they are referred to in the command string as $1, + $2, etc. + + + + + + nParams + + + The number of parameters supplied; it is the length of the arrays + paramTypes[], paramValues[], + paramLengths[], and paramFormats[]. (The + array pointers can be NULL when nParams + is zero.) + + + + + + paramTypes[] + + + Specifies, by OID, the data types to be assigned to the + parameter symbols. If paramTypes is + NULL, or any particular element in the array + is zero, the server infers a data type for the parameter symbol + in the same way it would do for an untyped literal string. + + + + + + paramValues[] + + + Specifies the actual values of the parameters. A null pointer + in this array means the corresponding parameter is null; + otherwise the pointer points to a zero-terminated text string + (for text format) or binary data in the format expected by the + server (for binary format). + + + + + + paramLengths[] + + + Specifies the actual data lengths of binary-format parameters. + It is ignored for null parameters and text-format parameters. + The array pointer can be null when there are no binary parameters. + + + + + + paramFormats[] + + + Specifies whether parameters are text (put a zero in the + array entry for the corresponding parameter) or binary (put + a one in the array entry for the corresponding parameter). + If the array pointer is null then all parameters are presumed + to be text strings. + + + Values passed in binary format require knowledge of + the internal representation expected by the backend. + For example, integers must be passed in network byte + order. Passing numeric values requires + knowledge of the server storage format, as implemented + in + src/backend/utils/adt/numeric.c::numeric_send() and + src/backend/utils/adt/numeric.c::numeric_recv(). + + + + + + resultFormat + + + Specify zero to obtain results in text format, or one to obtain + results in binary format. (There is not currently a provision + to obtain different result columns in different formats, + although that is possible in the underlying protocol.) + + + + + + + + + + + + The primary advantage of over + is that parameter values can be separated from the + command string, thus avoiding the need for tedious and error-prone + quoting and escaping. + + + + Unlike , allows at most + one SQL command in the given string. (There can be semicolons in it, + but not more than one nonempty command.) This is a limitation of the + underlying protocol, but has some usefulness as an extra defense against + SQL-injection attacks. + + + + + Specifying parameter types via OIDs is tedious, particularly if you prefer + not to hard-wire particular OID values into your program. However, you can + avoid doing so even in cases where the server by itself cannot determine the + type of the parameter, or chooses a different type than you want. In the + SQL command text, attach an explicit cast to the parameter symbol to show what + data type you will send. For example: + +SELECT * FROM mytable WHERE x = $1::bigint; + + This forces parameter $1 to be treated as bigint, whereas + by default it would be assigned the same type as x. Forcing the + parameter type decision, either this way or by specifying a numeric type OID, + is strongly recommended when sending parameter values in binary format, because + binary format has less redundancy than text format and so there is less chance + that the server will detect a type mismatch mistake for you. + + + + + + + PQpreparePQprepare + + + + Submits a request to create a prepared statement with the + given parameters, and waits for completion. + +PGresult *PQprepare(PGconn *conn, + const char *stmtName, + const char *query, + int nParams, + const Oid *paramTypes); + + + + + creates a prepared statement for later + execution with . This feature allows + commands to be executed repeatedly without being parsed and + planned each time; see for details. + + + + The function creates a prepared statement named + stmtName from the query string, which + must contain a single SQL command. stmtName can be + "" to create an unnamed statement, in which case any + pre-existing unnamed statement is automatically replaced; otherwise + it is an error if the statement name is already defined in the + current session. If any parameters are used, they are referred + to in the query as $1, $2, etc. + nParams is the number of parameters for which types + are pre-specified in the array paramTypes[]. (The + array pointer can be NULL when + nParams is zero.) paramTypes[] + specifies, by OID, the data types to be assigned to the parameter + symbols. If paramTypes is NULL, + or any particular element in the array is zero, the server assigns + a data type to the parameter symbol in the same way it would do + for an untyped literal string. Also, the query can use parameter + symbols with numbers higher than nParams; data types + will be inferred for these symbols as well. (See + for a means to find out + what data types were inferred.) + + + + As with , the result is normally a + PGresult object whose contents indicate + server-side success or failure. A null result indicates + out-of-memory or inability to send the command at all. Use + to get more information about + such errors. + + + + + + Prepared statements for use with can also + be created by executing SQL + statements. Also, although there is no libpq + function for deleting a prepared statement, the SQL statement + can be used for that purpose. + + + + + + PQexecPreparedPQexecPrepared + + + + Sends a request to execute a prepared statement with given + parameters, and waits for the result. + +PGresult *PQexecPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char * const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + + + + + is like , + but the command to be executed is specified by naming a + previously-prepared statement, instead of giving a query string. + This feature allows commands that will be used repeatedly to be + parsed and planned just once, rather than each time they are + executed. The statement must have been prepared previously in + the current session. + + + + The parameters are identical to , except that the + name of a prepared statement is given instead of a query string, and the + paramTypes[] parameter is not present (it is not needed since + the prepared statement's parameter types were determined when it was created). + + + + + + PQdescribePreparedPQdescribePrepared + + + + Submits a request to obtain information about the specified + prepared statement, and waits for completion. + +PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName); + + + + + allows an application to obtain + information about a previously prepared statement. + + + + stmtName can be "" or NULL to reference + the unnamed statement, otherwise it must be the name of an existing + prepared statement. On success, a PGresult with + status PGRES_COMMAND_OK is returned. The + functions and + can be applied to this + PGresult to obtain information about the parameters + of the prepared statement, and the functions + , , + , etc provide information about the + result columns (if any) of the statement. + + + + + + PQdescribePortalPQdescribePortal + + + + Submits a request to obtain information about the specified + portal, and waits for completion. + +PGresult *PQdescribePortal(PGconn *conn, const char *portalName); + + + + + allows an application to obtain + information about a previously created portal. + (libpq does not provide any direct access to + portals, but you can use this function to inspect the properties + of a cursor created with a DECLARE CURSOR SQL command.) + + + + portalName can be "" or NULL to reference + the unnamed portal, otherwise it must be the name of an existing + portal. On success, a PGresult with status + PGRES_COMMAND_OK is returned. The functions + , , + , etc can be applied to the + PGresult to obtain information about the result + columns (if any) of the portal. + + + + + + + + The PGresultPGresult + structure encapsulates the result returned by the server. + libpq application programmers should be + careful to maintain the PGresult abstraction. + Use the accessor functions below to get at the contents of + PGresult. Avoid directly referencing the + fields of the PGresult structure because they + are subject to change in the future. + + + + PQresultStatusPQresultStatus + + + + Returns the result status of the command. + +ExecStatusType PQresultStatus(const PGresult *res); + + + + + can return one of the following values: + + + + PGRES_EMPTY_QUERY + + + The string sent to the server was empty. + + + + + + PGRES_COMMAND_OK + + + Successful completion of a command returning no data. + + + + + + PGRES_TUPLES_OK + + + Successful completion of a command returning data (such as + a SELECT or SHOW). + + + + + + PGRES_COPY_OUT + + + Copy Out (from server) data transfer started. + + + + + + PGRES_COPY_IN + + + Copy In (to server) data transfer started. + + + + + + PGRES_BAD_RESPONSE + + + The server's response was not understood. + + + + + + PGRES_NONFATAL_ERROR + + + A nonfatal error (a notice or warning) occurred. + + + + + + PGRES_FATAL_ERROR + + + A fatal error occurred. + + + + + + PGRES_COPY_BOTH + + + Copy In/Out (to and from server) data transfer started. This + feature is currently used only for streaming replication, + so this status should not occur in ordinary applications. + + + + + + PGRES_SINGLE_TUPLE + + + The PGresult contains a single result tuple + from the current command. This status occurs only when + single-row mode has been selected for the query + (see ). + + + + + + PGRES_PIPELINE_SYNC + + + The PGresult represents a + synchronization point in pipeline mode, requested by + . + This status occurs only when pipeline mode has been selected. + + + + + + PGRES_PIPELINE_ABORTED + + + The PGresult represents a pipeline that has + received an error from the server. PQgetResult + must be called repeatedly, and each time it will return this status code + until the end of the current pipeline, at which point it will return + PGRES_PIPELINE_SYNC and normal processing can + resume. + + + + + + + If the result status is PGRES_TUPLES_OK or + PGRES_SINGLE_TUPLE, then + the functions described below can be used to retrieve the rows + returned by the query. Note that a SELECT + command that happens to retrieve zero rows still shows + PGRES_TUPLES_OK. + PGRES_COMMAND_OK is for commands that can never + return rows (INSERT or UPDATE + without a RETURNING clause, + etc.). A response of PGRES_EMPTY_QUERY might + indicate a bug in the client software. + + + + A result of status PGRES_NONFATAL_ERROR will + never be returned directly by or other + query execution functions; results of this kind are instead passed + to the notice processor (see ). + + + + + + PQresStatusPQresStatus + + + + Converts the enumerated type returned by + into a string constant describing the + status code. The caller should not free the result. + + +char *PQresStatus(ExecStatusType status); + + + + + + + PQresultErrorMessagePQresultErrorMessage + + + + Returns the error message associated with the command, or an empty string + if there was no error. + +char *PQresultErrorMessage(const PGresult *res); + + If there was an error, the returned string will include a trailing + newline. The caller should not free the result directly. It will + be freed when the associated PGresult handle is + passed to . + + + + Immediately following a or + call, + (on the connection) will return + the same string as (on + the result). However, a PGresult will + retain its error message until destroyed, whereas the connection's + error message will change when subsequent operations are done. + Use when you want to + know the status associated with a particular + PGresult; use + when you want to know the + status from the latest operation on the connection. + + + + + + PQresultVerboseErrorMessagePQresultVerboseErrorMessage + + + + Returns a reformatted version of the error message associated with + a PGresult object. + +char *PQresultVerboseErrorMessage(const PGresult *res, + PGVerbosity verbosity, + PGContextVisibility show_context); + + In some situations a client might wish to obtain a more detailed + version of a previously-reported error. + addresses this need + by computing the message that would have been produced + by if the specified + verbosity settings had been in effect for the connection when the + given PGresult was generated. If + the PGresult is not an error result, + PGresult is not an error result is reported instead. + The returned string includes a trailing newline. + + + + Unlike most other functions for extracting data from + a PGresult, the result of this function is a freshly + allocated string. The caller must free it + using PQfreemem() when the string is no longer needed. + + + + A NULL return is possible if there is insufficient memory. + + + + + + PQresultErrorFieldPQresultErrorField + + + Returns an individual field of an error report. + +char *PQresultErrorField(const PGresult *res, int fieldcode); + + fieldcode is an error field identifier; see the symbols + listed below. NULL is returned if the + PGresult is not an error or warning result, + or does not include the specified field. Field values will normally + not include a trailing newline. The caller should not free the + result directly. It will be freed when the + associated PGresult handle is passed to + . + + + + The following field codes are available: + + + PG_DIAG_SEVERITY + + + The severity; the field contents are ERROR, + FATAL, or PANIC (in an error message), + or WARNING, NOTICE, DEBUG, + INFO, or LOG (in a notice message), or + a localized translation of one of these. Always present. + + + + + + PG_DIAG_SEVERITY_NONLOCALIZED + + + The severity; the field contents are ERROR, + FATAL, or PANIC (in an error message), + or WARNING, NOTICE, DEBUG, + INFO, or LOG (in a notice message). + This is identical to the PG_DIAG_SEVERITY field except + that the contents are never localized. This is present only in + reports generated by PostgreSQL versions 9.6 + and later. + + + + + + PG_DIAG_SQLSTATEerror codeslibpq + + + The SQLSTATE code for the error. The SQLSTATE code identifies + the type of error that has occurred; it can be used by + front-end applications to perform specific operations (such + as error handling) in response to a particular database error. + For a list of the possible SQLSTATE codes, see . This field is not localizable, + and is always present. + + + + + + PG_DIAG_MESSAGE_PRIMARY + + + The primary human-readable error message (typically one line). + Always present. + + + + + + PG_DIAG_MESSAGE_DETAIL + + + Detail: an optional secondary error message carrying more + detail about the problem. Might run to multiple lines. + + + + + + PG_DIAG_MESSAGE_HINT + + + Hint: an optional suggestion what to do about the problem. + This is intended to differ from detail in that it offers advice + (potentially inappropriate) rather than hard facts. Might + run to multiple lines. + + + + + + PG_DIAG_STATEMENT_POSITION + + + A string containing a decimal integer indicating an error cursor + position as an index into the original statement string. The + first character has index 1, and positions are measured in + characters not bytes. + + + + + + PG_DIAG_INTERNAL_POSITION + + + This is defined the same as the + PG_DIAG_STATEMENT_POSITION field, but it is used + when the cursor position refers to an internally generated + command rather than the one submitted by the client. The + PG_DIAG_INTERNAL_QUERY field will always appear when + this field appears. + + + + + + PG_DIAG_INTERNAL_QUERY + + + The text of a failed internally-generated command. This could + be, for example, an SQL query issued by a PL/pgSQL function. + + + + + + PG_DIAG_CONTEXT + + + An indication of the context in which the error occurred. + Presently this includes a call stack traceback of active + procedural language functions and internally-generated queries. + The trace is one entry per line, most recent first. + + + + + + PG_DIAG_SCHEMA_NAME + + + If the error was associated with a specific database object, + the name of the schema containing that object, if any. + + + + + + PG_DIAG_TABLE_NAME + + + If the error was associated with a specific table, the name of the + table. (Refer to the schema name field for the name of the + table's schema.) + + + + + + PG_DIAG_COLUMN_NAME + + + If the error was associated with a specific table column, the name + of the column. (Refer to the schema and table name fields to + identify the table.) + + + + + + PG_DIAG_DATATYPE_NAME + + + If the error was associated with a specific data type, the name of + the data type. (Refer to the schema name field for the name of + the data type's schema.) + + + + + + PG_DIAG_CONSTRAINT_NAME + + + If the error was associated with a specific constraint, the name + of the constraint. Refer to fields listed above for the + associated table or domain. (For this purpose, indexes are + treated as constraints, even if they weren't created with + constraint syntax.) + + + + + + PG_DIAG_SOURCE_FILE + + + The file name of the source-code location where the error was + reported. + + + + + + PG_DIAG_SOURCE_LINE + + + The line number of the source-code location where the error + was reported. + + + + + + PG_DIAG_SOURCE_FUNCTION + + + The name of the source-code function reporting the error. + + + + + + + + + The fields for schema name, table name, column name, data type name, + and constraint name are supplied only for a limited number of error + types; see . Do not assume that + the presence of any of these fields guarantees the presence of + another field. Core error sources observe the interrelationships + noted above, but user-defined functions may use these fields in other + ways. In the same vein, do not assume that these fields denote + contemporary objects in the current database. + + + + + The client is responsible for formatting displayed information to meet + its needs; in particular it should break long lines as needed. + Newline characters appearing in the error message fields should be + treated as paragraph breaks, not line breaks. + + + + Errors generated internally by libpq will + have severity and primary message, but typically no other fields. + + + + Note that error fields are only available from + PGresult objects, not + PGconn objects; there is no + PQerrorField function. + + + + + + PQclearPQclear + + + Frees the storage associated with a + PGresult. Every command result should be + freed via when it is no longer + needed. + + +void PQclear(PGresult *res); + + + + + You can keep a PGresult object around for + as long as you need it; it does not go away when you issue a new + command, nor even if you close the connection. To get rid of it, + you must call . Failure to do this + will result in memory leaks in your application. + + + + + + + + + Retrieving Query Result Information + + + These functions are used to extract information from a + PGresult object that represents a successful + query result (that is, one that has status + PGRES_TUPLES_OK or PGRES_SINGLE_TUPLE). + They can also be used to extract + information from a successful Describe operation: a Describe's result + has all the same column information that actual execution of the query + would provide, but it has zero rows. For objects with other status values, + these functions will act as though the result has zero rows and zero columns. + + + + + PQntuplesPQntuples + + + + Returns the number of rows (tuples) in the query result. + (Note that PGresult objects are limited to no more + than INT_MAX rows, so an int result is + sufficient.) + + +int PQntuples(const PGresult *res); + + + + + + + + PQnfieldsPQnfields + + + + Returns the number of columns (fields) in each row of the query + result. + + +int PQnfields(const PGresult *res); + + + + + + + PQfnamePQfname + + + + Returns the column name associated with the given column number. + Column numbers start at 0. The caller should not free the result + directly. It will be freed when the associated + PGresult handle is passed to + . + +char *PQfname(const PGresult *res, + int column_number); + + + + + NULL is returned if the column number is out of range. + + + + + + PQfnumberPQfnumber + + + + Returns the column number associated with the given column name. + +int PQfnumber(const PGresult *res, + const char *column_name); + + + + + -1 is returned if the given name does not match any column. + + + + The given name is treated like an identifier in an SQL command, + that is, it is downcased unless double-quoted. For example, given + a query result generated from the SQL command: + +SELECT 1 AS FOO, 2 AS "BAR"; + + we would have the results: + +PQfname(res, 0) foo +PQfname(res, 1) BAR +PQfnumber(res, "FOO") 0 +PQfnumber(res, "foo") 0 +PQfnumber(res, "BAR") -1 +PQfnumber(res, "\"BAR\"") 1 + + + + + + + PQftablePQftable + + + + Returns the OID of the table from which the given column was + fetched. Column numbers start at 0. + +Oid PQftable(const PGresult *res, + int column_number); + + + + + InvalidOid is returned if the column number is out of range, + or if the specified column is not a simple reference to a table column. + You can query the system table pg_class to determine + exactly which table is referenced. + + + + The type Oid and the constant + InvalidOid will be defined when you include + the libpq header file. They will both + be some integer type. + + + + + + PQftablecolPQftablecol + + + + Returns the column number (within its table) of the column making + up the specified query result column. Query-result column numbers + start at 0, but table columns have nonzero numbers. + +int PQftablecol(const PGresult *res, + int column_number); + + + + + Zero is returned if the column number is out of range, or if the + specified column is not a simple reference to a table column. + + + + + + PQfformatPQfformat + + + + Returns the format code indicating the format of the given + column. Column numbers start at 0. + +int PQfformat(const PGresult *res, + int column_number); + + + + + Format code zero indicates textual data representation, while format + code one indicates binary representation. (Other codes are reserved + for future definition.) + + + + + + PQftypePQftype + + + + Returns the data type associated with the given column number. + The integer returned is the internal OID number of the type. + Column numbers start at 0. + +Oid PQftype(const PGresult *res, + int column_number); + + + + + You can query the system table pg_type to + obtain the names and properties of the various data types. The + OIDs of the built-in data types are defined + in the file catalog/pg_type_d.h + in the PostgreSQL + installation's include directory. + + + + + + PQfmodPQfmod + + + + Returns the type modifier of the column associated with the + given column number. Column numbers start at 0. + +int PQfmod(const PGresult *res, + int column_number); + + + + + The interpretation of modifier values is type-specific; they + typically indicate precision or size limits. The value -1 is + used to indicate no information available. Most data + types do not use modifiers, in which case the value is always + -1. + + + + + + PQfsizePQfsize + + + + Returns the size in bytes of the column associated with the + given column number. Column numbers start at 0. + +int PQfsize(const PGresult *res, + int column_number); + + + + + returns the space allocated for this column + in a database row, in other words the size of the server's + internal representation of the data type. (Accordingly, it is + not really very useful to clients.) A negative value indicates + the data type is variable-length. + + + + + + PQbinaryTuplesPQbinaryTuples + + + + Returns 1 if the PGresult contains binary data + and 0 if it contains text data. + +int PQbinaryTuples(const PGresult *res); + + + + + This function is deprecated (except for its use in connection with + COPY), because it is possible for a single + PGresult to contain text data in some columns and + binary data in others. is preferred. + returns 1 only if all columns of the + result are binary (format 1). + + + + + + PQgetvaluePQgetvalue + + + + Returns a single field value of one row of a + PGresult. Row and column numbers start + at 0. The caller should not free the result directly. It will + be freed when the associated PGresult handle is + passed to . + +char *PQgetvalue(const PGresult *res, + int row_number, + int column_number); + + + + + For data in text format, the value returned by + is a null-terminated character + string representation of the field value. For data in binary + format, the value is in the binary representation determined by + the data type's typsend and typreceive + functions. (The value is actually followed by a zero byte in + this case too, but that is not ordinarily useful, since the + value is likely to contain embedded nulls.) + + + + An empty string is returned if the field value is null. See + to distinguish null values from + empty-string values. + + + + The pointer returned by points + to storage that is part of the PGresult + structure. One should not modify the data it points to, and one + must explicitly copy the data into other storage if it is to be + used past the lifetime of the PGresult + structure itself. + + + + + + PQgetisnullPQgetisnullnull valuein libpq + + + + Tests a field for a null value. Row and column numbers start + at 0. + +int PQgetisnull(const PGresult *res, + int row_number, + int column_number); + + + + + This function returns 1 if the field is null and 0 if it + contains a non-null value. (Note that + will return an empty string, + not a null pointer, for a null field.) + + + + + + PQgetlengthPQgetlength + + + + Returns the actual length of a field value in bytes. Row and + column numbers start at 0. + +int PQgetlength(const PGresult *res, + int row_number, + int column_number); + + + + + This is the actual data length for the particular data value, + that is, the size of the object pointed to by + . For text data format this is + the same as strlen(). For binary format this is + essential information. Note that one should not + rely on to obtain the actual data + length. + + + + + + PQnparamsPQnparams + + + + Returns the number of parameters of a prepared statement. + +int PQnparams(const PGresult *res); + + + + + This function is only useful when inspecting the result of + . For other types of queries it + will return zero. + + + + + + PQparamtypePQparamtype + + + + Returns the data type of the indicated statement parameter. + Parameter numbers start at 0. + +Oid PQparamtype(const PGresult *res, int param_number); + + + + + This function is only useful when inspecting the result of + . For other types of queries it + will return zero. + + + + + + PQprintPQprint + + + + Prints out all the rows and, optionally, the column names to + the specified output stream. + +void PQprint(FILE *fout, /* output stream */ + const PGresult *res, + const PQprintOpt *po); +typedef struct +{ + pqbool header; /* print output field headings and row count */ + pqbool align; /* fill align the fields */ + pqbool standard; /* old brain dead format */ + pqbool html3; /* output HTML tables */ + pqbool expanded; /* expand tables */ + pqbool pager; /* use pager for output if needed */ + char *fieldSep; /* field separator */ + char *tableOpt; /* attributes for HTML table element */ + char *caption; /* HTML table caption */ + char **fieldName; /* null-terminated array of replacement field names */ +} PQprintOpt; + + + + + This function was formerly used by psql + to print query results, but this is no longer the case. Note + that it assumes all the data is in text format. + + + + + + + + Retrieving Other Result Information + + + These functions are used to extract other information from + PGresult objects. + + + + + PQcmdStatusPQcmdStatus + + + + Returns the command status tag from the SQL command that generated + the PGresult. + +char *PQcmdStatus(PGresult *res); + + + + + Commonly this is just the name of the command, but it might include + additional data such as the number of rows processed. The caller + should not free the result directly. It will be freed when the + associated PGresult handle is passed to + . + + + + + + PQcmdTuplesPQcmdTuples + + + + Returns the number of rows affected by the SQL command. + +char *PQcmdTuples(PGresult *res); + + + + + This function returns a string containing the number of rows + affected by the SQL statement that generated the + PGresult. This function can only be used following + the execution of a SELECT, CREATE TABLE AS, + INSERT, UPDATE, DELETE, + MOVE, FETCH, or COPY statement, + or an EXECUTE of a prepared query that contains an + INSERT, UPDATE, or DELETE statement. + If the command that generated the PGresult was anything + else, returns an empty string. The caller + should not free the return value directly. It will be freed when + the associated PGresult handle is passed to + . + + + + + + PQoidValuePQoidValue + + + + Returns the OIDOIDin libpq + of the inserted row, if the SQL command was an + INSERT that inserted exactly one row into a table that + has OIDs, or a EXECUTE of a prepared query containing + a suitable INSERT statement. Otherwise, this function + returns InvalidOid. This function will also + return InvalidOid if the table affected by the + INSERT statement does not contain OIDs. + +Oid PQoidValue(const PGresult *res); + + + + + + + PQoidStatusPQoidStatus + + + + This function is deprecated in favor of + and is not thread-safe. + It returns a string with the OID of the inserted row, while + returns the OID value. + +char *PQoidStatus(const PGresult *res); + + + + + + + + + + + Escaping Strings for Inclusion in SQL Commands + + + escaping strings + in libpq + + + + + PQescapeLiteralPQescapeLiteral + + + + +char *PQescapeLiteral(PGconn *conn, const char *str, size_t length); + + + + + escapes a string for + use within an SQL command. This is useful when inserting data + values as literal constants in SQL commands. Certain characters + (such as quotes and backslashes) must be escaped to prevent them + from being interpreted specially by the SQL parser. + performs this operation. + + + + returns an escaped version of the + str parameter in memory allocated with + malloc(). This memory should be freed using + PQfreemem() when the result is no longer needed. + A terminating zero byte is not required, and should not be + counted in length. (If a terminating zero byte is found + before length bytes are processed, + stops at the zero; the behavior is + thus rather like strncpy.) The + return string has all special characters replaced so that they can + be properly processed by the PostgreSQL + string literal parser. A terminating zero byte is also added. The + single quotes that must surround PostgreSQL + string literals are included in the result string. + + + + On error, returns NULL and a suitable + message is stored in the conn object. + + + + + It is especially important to do proper escaping when handling + strings that were received from an untrustworthy source. + Otherwise there is a security risk: you are vulnerable to + SQL injection attacks wherein unwanted SQL commands are + fed to your database. + + + + + Note that it is neither necessary nor correct to do escaping when a data + value is passed as a separate parameter in or + its sibling routines. + + + + + + PQescapeIdentifierPQescapeIdentifier + + + + +char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length); + + + + + escapes a string for + use as an SQL identifier, such as a table, column, or function name. + This is useful when a user-supplied identifier might contain + special characters that would otherwise not be interpreted as part + of the identifier by the SQL parser, or when the identifier might + contain upper case characters whose case should be preserved. + + + + returns a version of the + str parameter escaped as an SQL identifier + in memory allocated with malloc(). This memory must be + freed using PQfreemem() when the result is no longer + needed. A terminating zero byte is not required, and should not be + counted in length. (If a terminating zero byte is found + before length bytes are processed, + stops at the zero; the behavior is + thus rather like strncpy.) The + return string has all special characters replaced so that it + will be properly processed as an SQL identifier. A terminating zero byte + is also added. The return string will also be surrounded by double + quotes. + + + + On error, returns NULL and a suitable + message is stored in the conn object. + + + + + As with string literals, to prevent SQL injection attacks, + SQL identifiers must be escaped when they are received from an + untrustworthy source. + + + + + + + PQescapeStringConnPQescapeStringConn + + + + +size_t PQescapeStringConn(PGconn *conn, + char *to, const char *from, size_t length, + int *error); + + + + + escapes string literals, much like + . Unlike , + the caller is responsible for providing an appropriately sized buffer. + Furthermore, does not generate the + single quotes that must surround PostgreSQL string + literals; they should be provided in the SQL command that the + result is inserted into. The parameter from points to + the first character of the string that is to be escaped, and the + length parameter gives the number of bytes in this + string. A terminating zero byte is not required, and should not be + counted in length. (If a terminating zero byte is found + before length bytes are processed, + stops at the zero; the behavior is + thus rather like strncpy.) to shall point + to a buffer that is able to hold at least one more byte than twice + the value of length, otherwise the behavior is undefined. + Behavior is likewise undefined if the to and + from strings overlap. + + + + If the error parameter is not NULL, then + *error is set to zero on success, nonzero on error. + Presently the only possible error conditions involve invalid multibyte + encoding in the source string. The output string is still generated + on error, but it can be expected that the server will reject it as + malformed. On error, a suitable message is stored in the + conn object, whether or not error is NULL. + + + + returns the number of bytes written + to to, not including the terminating zero byte. + + + + + + PQescapeStringPQescapeString + + + + is an older, deprecated version of + . + +size_t PQescapeString (char *to, const char *from, size_t length); + + + + + The only difference from is that + does not take PGconn + or error parameters. + Because of this, it cannot adjust its behavior depending on the + connection properties (such as character encoding) and therefore + it might give the wrong results. Also, it has no way + to report error conditions. + + + + can be used safely in + client programs that work with only one PostgreSQL + connection at a time (in this case it can find out what it needs to + know behind the scenes). In other contexts it is a security + hazard and should be avoided in favor of + . + + + + + + PQescapeByteaConnPQescapeByteaConn + + + + Escapes binary data for use within an SQL command with the type + bytea. As with , + this is only used when inserting data directly into an SQL command string. + +unsigned char *PQescapeByteaConn(PGconn *conn, + const unsigned char *from, + size_t from_length, + size_t *to_length); + + + + + Certain byte values must be escaped when used as part of a + bytea literal in an SQL statement. + escapes bytes using + either hex encoding or backslash escaping. See for more information. + + + + The from parameter points to the first + byte of the string that is to be escaped, and the + from_length parameter gives the number of + bytes in this binary string. (A terminating zero byte is + neither necessary nor counted.) The to_length + parameter points to a variable that will hold the resultant + escaped string length. This result string length includes the terminating + zero byte of the result. + + + + returns an escaped version of the + from parameter binary string in memory + allocated with malloc(). This memory should be freed using + PQfreemem() when the result is no longer needed. The + return string has all special characters replaced so that they can + be properly processed by the PostgreSQL + string literal parser, and the bytea input function. A + terminating zero byte is also added. The single quotes that must + surround PostgreSQL string literals are + not part of the result string. + + + + On error, a null pointer is returned, and a suitable error message + is stored in the conn object. Currently, the only + possible error is insufficient memory for the result string. + + + + + + PQescapeByteaPQescapeBytea + + + + is an older, deprecated version of + . + +unsigned char *PQescapeBytea(const unsigned char *from, + size_t from_length, + size_t *to_length); + + + + + The only difference from is that + does not take a PGconn + parameter. Because of this, can + only be used safely in client programs that use a single + PostgreSQL connection at a time (in this case + it can find out what it needs to know behind the + scenes). It might give the wrong results if + used in programs that use multiple database connections (use + in such cases). + + + + + + PQunescapeByteaPQunescapeBytea + + + + Converts a string representation of binary data into binary data + — the reverse of . This + is needed when retrieving bytea data in text format, + but not when retrieving it in binary format. + + +unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); + + + + + The from parameter points to a string + such as might be returned by when applied + to a bytea column. + converts this string representation into its binary representation. + It returns a pointer to a buffer allocated with + malloc(), or NULL on error, and puts the size of + the buffer in to_length. The result must be + freed using when it is no longer needed. + + + + This conversion is not exactly the inverse of + , because the string is not expected + to be escaped when received from . + In particular this means there is no need for string quoting considerations, + and so no need for a PGconn parameter. + + + + + + + + + + + Asynchronous Command Processing + + + nonblocking connection + + + + The function is adequate for submitting + commands in normal, synchronous applications. It has a few + deficiencies, however, that can be of importance to some users: + + + + + waits for the command to be completed. + The application might have other work to do (such as maintaining a + user interface), in which case it won't want to block waiting for + the response. + + + + + + Since the execution of the client application is suspended while it + waits for the result, it is hard for the application to decide that + it would like to try to cancel the ongoing command. (It can be done + from a signal handler, but not otherwise.) + + + + + + can return only one + PGresult structure. If the submitted command + string contains multiple SQL commands, all but + the last PGresult are discarded by + . + + + + + + always collects the command's entire result, + buffering it in a single PGresult. While + this simplifies error-handling logic for the application, it can be + impractical for results containing many rows. + + + + + + + Applications that do not like these limitations can instead use the + underlying functions that is built from: + and . + There are also + , + , + , + , and + , + which can be used with to duplicate + the functionality of + , + , + , + , and + + respectively. + + + + PQsendQueryPQsendQuery + + + + Submits a command to the server without waiting for the result(s). + 1 is returned if the command was successfully dispatched and 0 if + not (in which case, use to get more + information about the failure). + +int PQsendQuery(PGconn *conn, const char *command); + + + After successfully calling , call + one or more times to obtain the + results. cannot be called again + (on the same connection) until + has returned a null pointer, indicating that the command is done. + + + + + + PQsendQueryParamsPQsendQueryParams + + + + Submits a command and separate parameters to the server without + waiting for the result(s). + +int PQsendQueryParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char * const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + + + This is equivalent to except that + query parameters can be specified separately from the query string. + The function's parameters are handled identically to + . Like + , it allows only one command in the + query string. + + + + + + PQsendPreparePQsendPrepare + + + + Sends a request to create a prepared statement with the given + parameters, without waiting for completion. + +int PQsendPrepare(PGconn *conn, + const char *stmtName, + const char *query, + int nParams, + const Oid *paramTypes); + + + This is an asynchronous version of : it + returns 1 if it was able to dispatch the request, and 0 if not. + After a successful call, call to + determine whether the server successfully created the prepared + statement. The function's parameters are handled identically to + . + + + + + + PQsendQueryPreparedPQsendQueryPrepared + + + + Sends a request to execute a prepared statement with given + parameters, without waiting for the result(s). + +int PQsendQueryPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char * const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); + + + This is similar to , but + the command to be executed is specified by naming a + previously-prepared statement, instead of giving a query string. + The function's parameters are handled identically to + . + + + + + + PQsendDescribePreparedPQsendDescribePrepared + + + + Submits a request to obtain information about the specified + prepared statement, without waiting for completion. + +int PQsendDescribePrepared(PGconn *conn, const char *stmtName); + + + This is an asynchronous version of : + it returns 1 if it was able to dispatch the request, and 0 if not. + After a successful call, call to + obtain the results. The function's parameters are handled + identically to . + + + + + + PQsendDescribePortalPQsendDescribePortal + + + + Submits a request to obtain information about the specified + portal, without waiting for completion. + +int PQsendDescribePortal(PGconn *conn, const char *portalName); + + + This is an asynchronous version of : + it returns 1 if it was able to dispatch the request, and 0 if not. + After a successful call, call to + obtain the results. The function's parameters are handled + identically to . + + + + + + PQgetResultPQgetResult + + + + Waits for the next result from a prior + , + , + , + , + , + , or + + call, and returns it. + A null pointer is returned when the command is complete and there + will be no more results. + +PGresult *PQgetResult(PGconn *conn); + + + + + must be called repeatedly until + it returns a null pointer, indicating that the command is done. + (If called when no command is active, + will just return a null pointer + at once.) Each non-null result from + should be processed using the + same PGresult accessor functions previously + described. Don't forget to free each result object with + when done with it. Note that + will block only if a command is + active and the necessary response data has not yet been read by + . + + + + In pipeline mode, PQgetResult will return normally + unless an error occurs; for any subsequent query sent after the one + that caused the error until (and excluding) the next synchronization point, + a special result of type PGRES_PIPELINE_ABORTED will + be returned, and a null pointer will be returned after it. + When the pipeline synchronization point is reached, a result of type + PGRES_PIPELINE_SYNC will be returned. + The result of the next query after the synchronization point follows + immediately (that is, no null pointer is returned after + the synchronization point.) + + + + + Even when indicates a fatal + error, should be called until it + returns a null pointer, to allow libpq to + process the error information completely. + + + + + + + + + Using and + solves one of + 's problems: If a command string contains + multiple SQL commands, the results of those commands + can be obtained individually. (This allows a simple form of overlapped + processing, by the way: the client can be handling the results of one + command while the server is still working on later queries in the same + command string.) + + + + Another frequently-desired feature that can be obtained with + and + is retrieving large query results a row at a time. This is discussed + in . + + + + By itself, calling + will still cause the client to block until the server completes the + next SQL command. This can be avoided by proper + use of two more functions: + + + + PQconsumeInputPQconsumeInput + + + + + If input is available from the server, consume it. + +int PQconsumeInput(PGconn *conn); + + + + + normally returns 1 indicating + no error, but returns 0 if there was some kind of + trouble (in which case can be + consulted). Note that the result does not say whether any input + data was actually collected. After calling + , the application can check + and/or + PQnotifies to see if their state has changed. + + + + can be called even if the + application is not prepared to deal with a result or notification + just yet. The function will read available data and save it in + a buffer, thereby causing a select() + read-ready indication to go away. The application can thus use + to clear the + select() condition immediately, and then + examine the results at leisure. + + + + + + PQisBusyPQisBusy + + + + Returns 1 if a command is busy, that is, + would block waiting for input. + A 0 return indicates that can be + called with assurance of not blocking. + +int PQisBusy(PGconn *conn); + + + + + will not itself attempt to read data + from the server; therefore + must be invoked first, or the busy state will never end. + + + + + + + + A typical application using these functions will have a main loop that + uses select() or poll() to wait for + all the conditions that it must respond to. One of the conditions + will be input available from the server, which in terms of + select() means readable data on the file + descriptor identified by . When the main + loop detects input ready, it should call + to read the input. It can then + call , followed by + if + returns false (0). It can also call PQnotifies + to detect NOTIFY messages (see ). + + + + A client that uses + / + can also attempt to cancel a command that is still being processed + by the server; see . But regardless of + the return value of , the application + must continue with the normal result-reading sequence using + . A successful cancellation will + simply cause the command to terminate sooner than it would have + otherwise. + + + + By using the functions described above, it is possible to avoid + blocking while waiting for input from the database server. However, + it is still possible that the application will block waiting to send + output to the server. This is relatively uncommon but can happen if + very long SQL commands or data values are sent. (It is much more + probable if the application sends data via COPY IN, + however.) To prevent this possibility and achieve completely + nonblocking database operation, the following additional functions + can be used. + + + + PQsetnonblockingPQsetnonblocking + + + + Sets the nonblocking status of the connection. + +int PQsetnonblocking(PGconn *conn, int arg); + + + + + Sets the state of the connection to nonblocking if + arg is 1, or blocking if + arg is 0. Returns 0 if OK, -1 if error. + + + + In the nonblocking state, calls to + , , + , , + and will not block but instead return + an error if they need to be called again. + + + + Note that does not honor nonblocking + mode; if it is called, it will act in blocking fashion anyway. + + + + + + PQisnonblockingPQisnonblocking + + + + Returns the blocking status of the database connection. + +int PQisnonblocking(const PGconn *conn); + + + + + Returns 1 if the connection is set to nonblocking mode and 0 if + blocking. + + + + + + PQflushPQflush + + + + Attempts to flush any queued output data to the server. Returns + 0 if successful (or if the send queue is empty), -1 if it failed + for some reason, or 1 if it was unable to send all the data in + the send queue yet (this case can only occur if the connection + is nonblocking). + +int PQflush(PGconn *conn); + + + + + + + + + After sending any command or data on a nonblocking connection, call + . If it returns 1, wait for the socket + to become read- or write-ready. If it becomes write-ready, call + again. If it becomes read-ready, call + , then call + again. Repeat until + returns 0. (It is necessary to check for + read-ready and drain the input with , + because the server can block trying to send us data, e.g., NOTICE + messages, and won't read our data until we read its.) Once + returns 0, wait for the socket to be + read-ready and then read the response as described above. + + + + + + Pipeline Mode + + + libpq + pipeline mode + + + + pipelining + in libpq + + + + batch mode + in libpq + + + + libpq pipeline mode allows applications to + send a query without having to read the result of the previously + sent query. Taking advantage of the pipeline mode, a client will wait + less for the server, since multiple queries/results can be + sent/received in a single network transaction. + + + + While pipeline mode provides a significant performance boost, writing + clients using the pipeline mode is more complex because it involves + managing a queue of pending queries and finding which result + corresponds to which query in the queue. + + + + Pipeline mode also generally consumes more memory on both the client and server, + though careful and aggressive management of the send/receive queue can mitigate + this. This applies whether or not the connection is in blocking or non-blocking + mode. + + + + While the pipeline API was introduced in + PostgreSQL 14, it is a client-side feature + which doesn't require special server support, and works on any server + that supports the v3 extended query protocol. + + + + Using Pipeline Mode + + + To issue pipelines, the application must switch the connection + into pipeline mode, + which is done with . + can be used + to test whether pipeline mode is active. + In pipeline mode, only asynchronous operations + are permitted, and COPY is disallowed. + Using synchronous command execution functions + such as PQfn, + PQexec, + PQexecParams, + PQprepare, + PQexecPrepared, + PQdescribePrepared, + PQdescribePortal, + is an error condition. + Once all dispatched commands have had their results processed, and + the end pipeline result has been consumed, the application may return + to non-pipelined mode with . + + + + + It is best to use pipeline mode with libpq in + non-blocking mode. If used + in blocking mode it is possible for a client/server deadlock to occur. + + + The client will block trying to send queries to the server, but the + server will block trying to send results to the client from queries + it has already processed. This only occurs when the client sends + enough queries to fill both its output buffer and the server's receive + buffer before it switches to processing input from the server, + but it's hard to predict exactly when that will happen. + + + + + + + Issuing Queries + + + After entering pipeline mode, the application dispatches requests using + , + , + or its prepared-query sibling + . + These requests are queued on the client-side until flushed to the server; + this occurs when is used to + establish a synchronization point in the pipeline, + or when is called. + The functions , + , and + also work in pipeline mode. + Result processing is described below. + + + + The server executes statements, and returns results, in the order the + client sends them. The server will begin executing the commands in the + pipeline immediately, not waiting for the end of the pipeline. + If any statement encounters an error, the server aborts the current + transaction and does not execute any subsequent command in the queue + until the next synchronization point established by + PQpipelineSync; + a PGRES_PIPELINE_ABORTED result is produced for + each such command. + (This remains true even if the commands in the pipeline would rollback + the transaction.) + Query processing resumes after the synchronization point. + + + + It's fine for one operation to depend on the results of a + prior one; for example, one query may define a table that the next + query in the same pipeline uses. Similarly, an application may + create a named prepared statement and execute it with later + statements in the same pipeline. + + + + + Processing Results + + + To process the result of one query in a pipeline, the application calls + PQgetResult repeatedly and handles each result + until PQgetResult returns null. + The result from the next query in the pipeline may then be retrieved using + PQgetResult again and the cycle repeated. + The application handles individual statement results as normal. + When the results of all the queries in the pipeline have been + returned, PQgetResult returns a result + containing the status value PGRES_PIPELINE_SYNC + + + + The client may choose to defer result processing until the complete + pipeline has been sent, or interleave that with sending further + queries in the pipeline; see . + + + + To enter single-row mode, call PQsetSingleRowMode + before retrieving results with PQgetResult. + This mode selection is effective only for the query currently + being processed. For more information on the use of + PQsetSingleRowMode, + refer to . + + + + PQgetResult behaves the same as for normal + asynchronous processing except that it may contain the new + PGresult types PGRES_PIPELINE_SYNC + and PGRES_PIPELINE_ABORTED. + PGRES_PIPELINE_SYNC is reported exactly once for each + PQpipelineSync at the corresponding point + in the pipeline. + PGRES_PIPELINE_ABORTED is emitted in place of a normal + query result for the first error and all subsequent results + until the next PGRES_PIPELINE_SYNC; + see . + + + + PQisBusy, PQconsumeInput, etc + operate as normal when processing pipeline results. + + + + libpq does not provide any information to the + application about the query currently being processed (except that + PQgetResult returns null to indicate that we start + returning the results of next query). The application must keep track + of the order in which it sent queries, to associate them with their + corresponding results. + Applications will typically use a state machine or a FIFO queue for this. + + + + + + Error Handling + + + From the client's perspective, after PQresultStatus + returns PGRES_FATAL_ERROR, + the pipeline is flagged as aborted. + PQresultStatus will report a + PGRES_PIPELINE_ABORTED result for each remaining queued + operation in an aborted pipeline. The result for + PQpipelineSync is reported as + PGRES_PIPELINE_SYNC to signal the end of the aborted pipeline + and resumption of normal result processing. + + + + The client must process results with + PQgetResult during error recovery. + + + + If the pipeline used an implicit transaction, then operations that have + already executed are rolled back and operations that were queued to follow + the failed operation are skipped entirely. The same behavior holds if the + pipeline starts and commits a single explicit transaction (i.e. the first + statement is BEGIN and the last is + COMMIT) except that the session remains in an aborted + transaction state at the end of the pipeline. If a pipeline contains + multiple explicit transactions, all transactions that + committed prior to the error remain committed, the currently in-progress + transaction is aborted, and all subsequent operations are skipped completely, + including subsequent transactions. If a pipeline synchronization point + occurs with an explicit transaction block in aborted state, the next pipeline + will become aborted immediately unless the next command puts the transaction + in normal mode with ROLLBACK. + + + + + The client must not assume that work is committed when it + sends a COMMIT — only when the + corresponding result is received to confirm the commit is complete. + Because errors arrive asynchronously, the application needs to be able to + restart from the last received committed change and + resend work done after that point if something goes wrong. + + + + + + Interleaving Result Processing and Query Dispatch + + + To avoid deadlocks on large pipelines the client should be structured + around a non-blocking event loop using operating system facilities + such as select, poll, + WaitForMultipleObjectEx, etc. + + + + The client application should generally maintain a queue of work + remaining to be dispatched and a queue of work that has been dispatched + but not yet had its results processed. When the socket is writable + it should dispatch more work. When the socket is readable it should + read results and process them, matching them up to the next entry in + its corresponding results queue. Based on available memory, results from the + socket should be read frequently: there's no need to wait until the + pipeline end to read the results. Pipelines should be scoped to logical + units of work, usually (but not necessarily) one transaction per pipeline. + There's no need to exit pipeline mode and re-enter it between pipelines, + or to wait for one pipeline to finish before sending the next. + + + + An example using select() and a simple state + machine to track sent and received work is in + src/test/modules/libpq_pipeline/libpq_pipeline.c + in the PostgreSQL source distribution. + + + + + + Functions Associated with Pipeline Mode + + + + + PQpipelineStatusPQpipelineStatus + + + + Returns the current pipeline mode status of the + libpq connection. + +PGpipelineStatus PQpipelineStatus(const PGconn *conn); + + + + + PQpipelineStatus can return one of the following values: + + + + + PQ_PIPELINE_ON + + + + The libpq connection is in + pipeline mode. + + + + + + + PQ_PIPELINE_OFF + + + + The libpq connection is + not in pipeline mode. + + + + + + + PQ_PIPELINE_ABORTED + + + + The libpq connection is in pipeline + mode and an error occurred while processing the current pipeline. + The aborted flag is cleared when PQgetResult + returns a result of type PGRES_PIPELINE_SYNC. + + + + + + + + + + + PQenterPipelineModePQenterPipelineMode + + + + Causes a connection to enter pipeline mode if it is currently idle or + already in pipeline mode. + + +int PQenterPipelineMode(PGconn *conn); + + + + + Returns 1 for success. + Returns 0 and has no effect if the connection is not currently + idle, i.e., it has a result ready, or it is waiting for more + input from the server, etc. + This function does not actually send anything to the server, + it just changes the libpq connection + state. + + + + + + PQexitPipelineModePQexitPipelineMode + + + + Causes a connection to exit pipeline mode if it is currently in pipeline mode + with an empty queue and no pending results. + +int PQexitPipelineMode(PGconn *conn); + + + + Returns 1 for success. Returns 1 and takes no action if not in + pipeline mode. If the current statement isn't finished processing, + or PQgetResult has not been called to collect + results from all previously sent query, returns 0 (in which case, + use to get more information + about the failure). + + + + + + PQpipelineSyncPQpipelineSync + + + + Marks a synchronization point in a pipeline by sending a + sync message + and flushing the send buffer. This serves as + the delimiter of an implicit transaction and an error recovery + point; see . + + +int PQpipelineSync(PGconn *conn); + + + + Returns 1 for success. Returns 0 if the connection is not in + pipeline mode or sending a + sync message + failed. + + + + + + + + When to Use Pipeline Mode + + + Much like asynchronous query mode, there is no meaningful performance + overhead when using pipeline mode. It increases client application complexity, + and extra caution is required to prevent client/server deadlocks, but + pipeline mode can offer considerable performance improvements, in exchange for + increased memory usage from leaving state around longer. + + + + Pipeline mode is most useful when the server is distant, i.e., network latency + (ping time) is high, and also when many small operations + are being performed in rapid succession. There is usually less benefit + in using pipelined commands when each query takes many multiples of the client/server + round-trip time to execute. A 100-statement operation run on a server + 300ms round-trip-time away would take 30 seconds in network latency alone + without pipelining; with pipelining it may spend as little as 0.3s waiting for + results from the server. + + + + Use pipelined commands when your application does lots of small + INSERT, UPDATE and + DELETE operations that can't easily be transformed + into operations on sets, or into a COPY operation. + + + + Pipeline mode is not useful when information from one operation is required by + the client to produce the next operation. In such cases, the client + would have to introduce a synchronization point and wait for a full client/server + round-trip to get the results it needs. However, it's often possible to + adjust the client design to exchange the required information server-side. + Read-modify-write cycles are especially good candidates; for example: + +BEGIN; +SELECT x FROM mytable WHERE id = 42 FOR UPDATE; +-- result: x=2 +-- client adds 1 to x: +UPDATE mytable SET x = 3 WHERE id = 42; +COMMIT; + + could be much more efficiently done with: + +UPDATE mytable SET x = x + 1 WHERE id = 42; + + + + + Pipelining is less useful, and more complex, when a single pipeline contains + multiple transactions (see ). + + + + + + Retrieving Query Results Row-by-Row + + + libpq + single-row mode + + + + Ordinarily, libpq collects an SQL command's + entire result and returns it to the application as a single + PGresult. This can be unworkable for commands + that return a large number of rows. For such cases, applications can use + and in + single-row mode. In this mode, the result row(s) are + returned to the application one at a time, as they are received from the + server. + + + + To enter single-row mode, call + immediately after a successful call of + (or a sibling function). This mode selection is effective only for the + currently executing query. Then call + repeatedly, until it returns null, as documented in . If the query returns any rows, they are returned + as individual PGresult objects, which look like + normal query results except for having status code + PGRES_SINGLE_TUPLE instead of + PGRES_TUPLES_OK. After the last row, or immediately if + the query returns zero rows, a zero-row object with status + PGRES_TUPLES_OK is returned; this is the signal that no + more rows will arrive. (But note that it is still necessary to continue + calling until it returns null.) All of + these PGresult objects will contain the same row + description data (column names, types, etc) that an ordinary + PGresult object for the query would have. + Each object should be freed with as usual. + + + + When using pipeline mode, single-row mode needs to be activated for each + query in the pipeline before retrieving results for that query + with PQgetResult. + See for more information. + + + + + + PQsetSingleRowModePQsetSingleRowMode + + + + Select single-row mode for the currently-executing query. + + +int PQsetSingleRowMode(PGconn *conn); + + + + + This function can only be called immediately after + or one of its sibling functions, + before any other operation on the connection such as + or + . If called at the correct time, + the function activates single-row mode for the current query and + returns 1. Otherwise the mode stays unchanged and the function + returns 0. In any case, the mode reverts to normal after + completion of the current query. + + + + + + + + + While processing a query, the server may return some rows and then + encounter an error, causing the query to be aborted. Ordinarily, + libpq discards any such rows and reports only the + error. But in single-row mode, those rows will have already been + returned to the application. Hence, the application will see some + PGRES_SINGLE_TUPLE PGresult + objects followed by a PGRES_FATAL_ERROR object. For + proper transactional behavior, the application must be designed to + discard or undo whatever has been done with the previously-processed + rows, if the query ultimately fails. + + + + + + + Canceling Queries in Progress + + + canceling + SQL command + + + + A client application can request cancellation of a command that is + still being processed by the server, using the functions described in + this section. + + + + PQgetCancelPQgetCancel + + + + Creates a data structure containing the information needed to cancel + a command issued through a particular database connection. + +PGcancel *PQgetCancel(PGconn *conn); + + + + + creates a + PGcancelPGcancel object + given a PGconn connection object. It will return + NULL if the given conn is NULL or an invalid + connection. The PGcancel object is an opaque + structure that is not meant to be accessed directly by the + application; it can only be passed to + or . + + + + + + PQfreeCancelPQfreeCancel + + + + Frees a data structure created by . + +void PQfreeCancel(PGcancel *cancel); + + + + + frees a data object previously created + by . + + + + + + PQcancelPQcancel + + + + Requests that the server abandon processing of the current command. + +int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); + + + + + The return value is 1 if the cancel request was successfully + dispatched and 0 if not. If not, errbuf is filled + with an explanatory error message. errbuf + must be a char array of size errbufsize (the + recommended size is 256 bytes). + + + + Successful dispatch is no guarantee that the request will have + any effect, however. If the cancellation is effective, the current + command will terminate early and return an error result. If the + cancellation fails (say, because the server was already done + processing the command), then there will be no visible result at + all. + + + + can safely be invoked from a signal + handler, if the errbuf is a local variable in the + signal handler. The PGcancel object is read-only + as far as is concerned, so it can + also be invoked from a thread that is separate from the one + manipulating the PGconn object. + + + + + + + + PQrequestCancelPQrequestCancel + + + + is a deprecated variant of + . + +int PQrequestCancel(PGconn *conn); + + + + + Requests that the server abandon processing of the current + command. It operates directly on the + PGconn object, and in case of failure stores the + error message in the PGconn object (whence it can + be retrieved by ). Although + the functionality is the same, this approach creates hazards for + multiple-thread programs and signal handlers, since it is possible + that overwriting the PGconn's error message will + mess up the operation currently in progress on the connection. + + + + + + + + + + The Fast-Path Interface + + + fast path + + + + PostgreSQL provides a fast-path interface + to send simple function calls to the server. + + + + + This interface is somewhat obsolete, as one can achieve similar + performance and greater functionality by setting up a prepared + statement to define the function call. Then, executing the statement + with binary transmission of parameters and results substitutes for a + fast-path function call. + + + + + The function PQfnPQfn + requests execution of a server function via the fast-path interface: + +PGresult *PQfn(PGconn *conn, + int fnid, + int *result_buf, + int *result_len, + int result_is_int, + const PQArgBlock *args, + int nargs); + +typedef struct +{ + int len; + int isint; + union + { + int *ptr; + int integer; + } u; +} PQArgBlock; + + + + + The fnid argument is the OID of the function to be + executed. args and nargs define the + parameters to be passed to the function; they must match the declared + function argument list. When the isint field of a + parameter structure is true, the u.integer value is sent + to the server as an integer of the indicated length (this must be + 2 or 4 bytes); proper byte-swapping occurs. When isint + is false, the indicated number of bytes at *u.ptr are + sent with no processing; the data must be in the format expected by + the server for binary transmission of the function's argument data + type. (The declaration of u.ptr as being of + type int * is historical; it would be better to consider + it void *.) + result_buf points to the buffer in which to place + the function's return value. The caller must have allocated sufficient + space to store the return value. (There is no check!) The actual result + length in bytes will be returned in the integer pointed to by + result_len. If a 2- or 4-byte integer result + is expected, set result_is_int to 1, otherwise + set it to 0. Setting result_is_int to 1 causes + libpq to byte-swap the value if necessary, so that it + is delivered as a proper int value for the client machine; + note that a 4-byte integer is delivered into *result_buf + for either allowed result size. + When result_is_int is 0, the binary-format byte string + sent by the server is returned unmodified. (In this case it's better + to consider result_buf as being of + type void *.) + + + + PQfn always returns a valid + PGresult pointer, with + status PGRES_COMMAND_OK for success + or PGRES_FATAL_ERROR if some problem was encountered. + The result status should be + checked before the result is used. The caller is responsible for + freeing the PGresult with + when it is no longer needed. + + + + To pass a NULL argument to the function, set + the len field of that parameter structure + to -1; the isint + and u fields are then irrelevant. + + + + If the function returns NULL, *result_len is set + to -1, and *result_buf is not + modified. + + + + Note that it is not possible to handle set-valued results when using + this interface. Also, the function must be a plain function, not an + aggregate, window function, or procedure. + + + + + + Asynchronous Notification + + + NOTIFY + in libpq + + + + PostgreSQL offers asynchronous notification + via the LISTEN and NOTIFY + commands. A client session registers its interest in a particular + notification channel with the LISTEN command (and + can stop listening with the UNLISTEN command). All + sessions listening on a particular channel will be notified + asynchronously when a NOTIFY command with that + channel name is executed by any session. A payload string can + be passed to communicate additional data to the listeners. + + + + libpq applications submit + LISTEN, UNLISTEN, + and NOTIFY commands as + ordinary SQL commands. The arrival of NOTIFY + messages can subsequently be detected by calling + PQnotifies.PQnotifies + + + + The function PQnotifies returns the next notification + from a list of unhandled notification messages received from the server. + It returns a null pointer if there are no pending notifications. Once a + notification is returned from PQnotifies, it is considered + handled and will be removed from the list of notifications. + + +PGnotify *PQnotifies(PGconn *conn); + +typedef struct pgNotify +{ + char *relname; /* notification channel name */ + int be_pid; /* process ID of notifying server process */ + char *extra; /* notification payload string */ +} PGnotify; + + + After processing a PGnotify object returned + by PQnotifies, be sure to free it with + . It is sufficient to free the + PGnotify pointer; the + relname and extra + fields do not represent separate allocations. (The names of these fields + are historical; in particular, channel names need not have anything to + do with relation names.) + + + + gives a sample program that illustrates + the use of asynchronous notification. + + + + PQnotifies does not actually read data from the + server; it just returns messages previously absorbed by another + libpq function. In ancient releases of + libpq, the only way to ensure timely receipt + of NOTIFY messages was to constantly submit commands, even + empty ones, and then check PQnotifies after each + . While this still works, it is deprecated + as a waste of processing power. + + + + A better way to check for NOTIFY messages when you have no + useful commands to execute is to call + , then check + PQnotifies. You can use + select() to wait for data to arrive from the + server, thereby using no CPU power unless there is + something to do. (See to obtain the file + descriptor number to use with select().) Note that + this will work OK whether you submit commands with + / or + simply use . You should, however, remember + to check PQnotifies after each + or , to + see if any notifications came in during the processing of the command. + + + + + + Functions Associated with the <command>COPY</command> Command + + + COPY + with libpq + + + + The COPY command in + PostgreSQL has options to read from or write + to the network connection used by libpq. + The functions described in this section allow applications to take + advantage of this capability by supplying or consuming copied data. + + + + The overall process is that the application first issues the SQL + COPY command via or one + of the equivalent functions. The response to this (if there is no + error in the command) will be a PGresult object bearing + a status code of PGRES_COPY_OUT or + PGRES_COPY_IN (depending on the specified copy + direction). The application should then use the functions of this + section to receive or transmit data rows. When the data transfer is + complete, another PGresult object is returned to indicate + success or failure of the transfer. Its status will be + PGRES_COMMAND_OK for success or + PGRES_FATAL_ERROR if some problem was encountered. + At this point further SQL commands can be issued via + . (It is not possible to execute other SQL + commands using the same connection while the COPY + operation is in progress.) + + + + If a COPY command is issued via + in a string that could contain additional + commands, the application must continue fetching results via + after completing the COPY + sequence. Only when returns + NULL is it certain that the + command string is done and it is safe to issue more commands. + + + + The functions of this section should be executed only after obtaining + a result status of PGRES_COPY_OUT or + PGRES_COPY_IN from or + . + + + + A PGresult object bearing one of these status values + carries some additional data about the COPY operation + that is starting. This additional data is available using functions + that are also used in connection with query results: + + + + PQnfieldsPQnfieldswith COPY + + + + Returns the number of columns (fields) to be copied. + + + + + + PQbinaryTuplesPQbinaryTupleswith COPY + + + + 0 indicates the overall copy format is textual (rows separated by + newlines, columns separated by separator characters, etc). 1 + indicates the overall copy format is binary. See for more information. + + + + + + PQfformatPQfformatwith COPY + + + + Returns the format code (0 for text, 1 for binary) associated with + each column of the copy operation. The per-column format codes + will always be zero when the overall copy format is textual, but + the binary format can support both text and binary columns. + (However, as of the current implementation of COPY, + only binary columns appear in a binary copy; so the per-column + formats always match the overall format at present.) + + + + + + + + Functions for Sending <command>COPY</command> Data + + + These functions are used to send data during COPY FROM + STDIN. They will fail if called when the connection is not in + COPY_IN state. + + + + + PQputCopyDataPQputCopyData + + + + Sends data to the server during COPY_IN state. + +int PQputCopyData(PGconn *conn, + const char *buffer, + int nbytes); + + + + + Transmits the COPY data in the specified + buffer, of length nbytes, to the server. + The result is 1 if the data was queued, zero if it was not queued + because of full buffers (this will only happen in nonblocking mode), + or -1 if an error occurred. + (Use to retrieve details if + the return value is -1. If the value is zero, wait for write-ready + and try again.) + + + + The application can divide the COPY data stream + into buffer loads of any convenient size. Buffer-load boundaries + have no semantic significance when sending. The contents of the + data stream must match the data format expected by the + COPY command; see for details. + + + + + + PQputCopyEndPQputCopyEnd + + + + Sends end-of-data indication to the server during COPY_IN state. + +int PQputCopyEnd(PGconn *conn, + const char *errormsg); + + + + + Ends the COPY_IN operation successfully if + errormsg is NULL. If + errormsg is not NULL then the + COPY is forced to fail, with the string pointed to by + errormsg used as the error message. (One should not + assume that this exact error message will come back from the server, + however, as the server might have already failed the + COPY for its own reasons.) + + + + The result is 1 if the termination message was sent; or in + nonblocking mode, this may only indicate that the termination + message was successfully queued. (In nonblocking mode, to be + certain that the data has been sent, you should next wait for + write-ready and call , repeating until it + returns zero.) Zero indicates that the function could not queue + the termination message because of full buffers; this will only + happen in nonblocking mode. (In this case, wait for + write-ready and try the call + again.) If a hard error occurs, -1 is returned; you can use + to retrieve details. + + + + After successfully calling , call + to obtain the final result status of the + COPY command. One can wait for this result to be + available in the usual way. Then return to normal operation. + + + + + + + + + Functions for Receiving <command>COPY</command> Data + + + These functions are used to receive data during COPY TO + STDOUT. They will fail if called when the connection is not in + COPY_OUT state. + + + + + PQgetCopyDataPQgetCopyData + + + + Receives data from the server during COPY_OUT state. + +int PQgetCopyData(PGconn *conn, + char **buffer, + int async); + + + + + Attempts to obtain another row of data from the server during a + COPY. Data is always returned one data row at + a time; if only a partial row is available, it is not returned. + Successful return of a data row involves allocating a chunk of + memory to hold the data. The buffer parameter must + be non-NULL. *buffer is set to + point to the allocated memory, or to NULL in cases + where no buffer is returned. A non-NULL result + buffer should be freed using when no longer + needed. + + + + When a row is successfully returned, the return value is the number + of data bytes in the row (this will always be greater than zero). + The returned string is always null-terminated, though this is + probably only useful for textual COPY. A result + of zero indicates that the COPY is still in + progress, but no row is yet available (this is only possible when + async is true). A result of -1 indicates that the + COPY is done. A result of -2 indicates that an + error occurred (consult for the reason). + + + + When async is true (not zero), + will not block waiting for input; it + will return zero if the COPY is still in progress + but no complete row is available. (In this case wait for read-ready + and then call before calling + again.) When async is + false (zero), will block until data is + available or the operation completes. + + + + After returns -1, call + to obtain the final result status of the + COPY command. One can wait for this result to be + available in the usual way. Then return to normal operation. + + + + + + + + + Obsolete Functions for <command>COPY</command> + + + These functions represent older methods of handling COPY. + Although they still work, they are deprecated due to poor error handling, + inconvenient methods of detecting end-of-data, and lack of support for binary + or nonblocking transfers. + + + + + PQgetlinePQgetline + + + + Reads a newline-terminated line of characters (transmitted + by the server) into a buffer string of size length. + +int PQgetline(PGconn *conn, + char *buffer, + int length); + + + + + This function copies up to length-1 characters into + the buffer and converts the terminating newline into a zero byte. + returns EOF at the + end of input, 0 if the entire line has been read, and 1 if the + buffer is full but the terminating newline has not yet been read. + + + Note that the application must check to see if a new line consists + of the two characters \., which indicates + that the server has finished sending the results of the + COPY command. If the application might receive + lines that are more than length-1 characters long, + care is needed to be sure it recognizes the \. + line correctly (and does not, for example, mistake the end of a + long data line for a terminator line). + + + + + + PQgetlineAsyncPQgetlineAsync + + + + Reads a row of COPY data (transmitted by the + server) into a buffer without blocking. + +int PQgetlineAsync(PGconn *conn, + char *buffer, + int bufsize); + + + + + This function is similar to , but it can be used + by applications + that must read COPY data asynchronously, that is, without blocking. + Having issued the COPY command and gotten a PGRES_COPY_OUT + response, the + application should call and + until the + end-of-data signal is detected. + + + Unlike , this function takes + responsibility for detecting end-of-data. + + + + On each call, will return data if a + complete data row is available in libpq's input buffer. + Otherwise, no data is returned until the rest of the row arrives. + The function returns -1 if the end-of-copy-data marker has been recognized, + or 0 if no data is available, or a positive number giving the number of + bytes of data returned. If -1 is returned, the caller must next call + , and then return to normal processing. + + + + The data returned will not extend beyond a data-row boundary. If possible + a whole row will be returned at one time. But if the buffer offered by + the caller is too small to hold a row sent by the server, then a partial + data row will be returned. With textual data this can be detected by testing + whether the last returned byte is \n or not. (In a binary + COPY, actual parsing of the COPY data format will be needed to make the + equivalent determination.) + The returned string is not null-terminated. (If you want to add a + terminating null, be sure to pass a bufsize one smaller + than the room actually available.) + + + + + + PQputlinePQputline + + + + Sends a null-terminated string to the server. Returns 0 if + OK and EOF if unable to send the string. + +int PQputline(PGconn *conn, + const char *string); + + + + + The COPY data stream sent by a series of calls + to has the same format as that + returned by , except that + applications are not obliged to send exactly one data row per + call; it is okay to send a partial + line or multiple lines per call. + + + + + Before PostgreSQL protocol 3.0, it was necessary + for the application to explicitly send the two characters + \. as a final line to indicate to the server that it had + finished sending COPY data. While this still works, it is deprecated and the + special meaning of \. can be expected to be removed in a + future release. It is sufficient to call after + having sent the actual data. + + + + + + + PQputnbytesPQputnbytes + + + + Sends a non-null-terminated string to the server. Returns + 0 if OK and EOF if unable to send the string. + +int PQputnbytes(PGconn *conn, + const char *buffer, + int nbytes); + + + + + This is exactly like , except that the data + buffer need not be null-terminated since the number of bytes to send is + specified directly. Use this procedure when sending binary data. + + + + + + PQendcopyPQendcopy + + + + Synchronizes with the server. + +int PQendcopy(PGconn *conn); + + This function waits until the server has finished the copying. + It should either be issued when the last string has been sent + to the server using or when the + last string has been received from the server using + PQgetline. It must be issued or the server + will get out of sync with the client. Upon return + from this function, the server is ready to receive the next SQL + command. The return value is 0 on successful completion, + nonzero otherwise. (Use to + retrieve details if the return value is nonzero.) + + + + When using , the application should + respond to a PGRES_COPY_OUT result by executing + repeatedly, followed by + after the terminator line is seen. + It should then return to the loop + until returns a null pointer. + Similarly a PGRES_COPY_IN result is processed + by a series of calls followed by + , then return to the + loop. This arrangement will + ensure that a COPY command embedded in a series + of SQL commands will be executed correctly. + + + + Older applications are likely to submit a COPY + via and assume that the transaction + is done after . This will work + correctly only if the COPY is the only + SQL command in the command string. + + + + + + + + + + + Control Functions + + + These functions control miscellaneous details of libpq's + behavior. + + + + + PQclientEncodingPQclientEncoding + + + + Returns the client encoding. + +int PQclientEncoding(const PGconn *conn); + + + Note that it returns the encoding ID, not a symbolic string + such as EUC_JP. If unsuccessful, it returns -1. + To convert an encoding ID to an encoding name, you + can use: + + +char *pg_encoding_to_char(int encoding_id); + + + + + + + PQsetClientEncodingPQsetClientEncoding + + + + Sets the client encoding. + +int PQsetClientEncoding(PGconn *conn, const char *encoding); + + + conn is a connection to the server, + and encoding is the encoding you want to + use. If the function successfully sets the encoding, it returns 0, + otherwise -1. The current encoding for this connection can be + determined by using . + + + + + + PQsetErrorVerbosityPQsetErrorVerbosity + + + + Determines the verbosity of messages returned by + and . + +typedef enum +{ + PQERRORS_TERSE, + PQERRORS_DEFAULT, + PQERRORS_VERBOSE, + PQERRORS_SQLSTATE +} PGVerbosity; + +PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); + + + sets the verbosity mode, + returning the connection's previous setting. + In TERSE mode, returned messages include + severity, primary text, and position only; this will normally fit on a + single line. The DEFAULT mode produces messages + that include the above plus any detail, hint, or context fields (these + might span multiple lines). The VERBOSE mode + includes all available fields. The SQLSTATE + mode includes only the error severity and the SQLSTATE + error code, if one is available (if not, the output is like + TERSE mode). + + + + Changing the verbosity setting does not affect the messages available + from already-existing PGresult objects, only + subsequently-created ones. + (But see if you + want to print a previous error with a different verbosity.) + + + + + + PQsetErrorContextVisibilityPQsetErrorContextVisibility + + + + Determines the handling of CONTEXT fields in messages + returned by + and . + +typedef enum +{ + PQSHOW_CONTEXT_NEVER, + PQSHOW_CONTEXT_ERRORS, + PQSHOW_CONTEXT_ALWAYS +} PGContextVisibility; + +PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context); + + + sets the context display mode, + returning the connection's previous setting. This mode controls + whether the CONTEXT field is included in messages. + The NEVER mode + never includes CONTEXT, while ALWAYS always + includes it if available. In ERRORS mode (the + default), CONTEXT fields are included only in error + messages, not in notices and warnings. + (However, if the verbosity setting is TERSE + or SQLSTATE, CONTEXT fields + are omitted regardless of the context display mode.) + + + + Changing this mode does not + affect the messages available from + already-existing PGresult objects, only + subsequently-created ones. + (But see if you + want to print a previous error with a different display mode.) + + + + + + PQtracePQtrace + + + + Enables tracing of the client/server communication to a debugging file + stream. + +void PQtrace(PGconn *conn, FILE *stream); + + + + + Each line consists of: an optional timestamp, a direction indicator + (F for messages from client to server + or B for messages from server to client), + message length, message type, and message contents. + Non-message contents fields (timestamp, direction, length and message type) + are separated by a tab. Message contents are separated by a space. + Protocol strings are enclosed in double quotes, while strings used as data + values are enclosed in single quotes. Non-printable chars are printed as + hexadecimal escapes. + Further message-type-specific detail can be found in + . + + + + + On Windows, if the libpq library and an application are + compiled with different flags, this function call will crash the + application because the internal representation of the FILE + pointers differ. Specifically, multithreaded/single-threaded, + release/debug, and static/dynamic flags should be the same for the + library and all applications using that library. + + + + + + + + PQsetTraceFlagsPQsetTraceFlags + + + + Controls the tracing behavior of client/server communication. + +void PQsetTraceFlags(PGconn *conn, int flags); + + + + + flags contains flag bits describing the operating mode + of tracing. + If flags contains PQTRACE_SUPPRESS_TIMESTAMPS, + then the timestamp is not included when printing each message. + If flags contains PQTRACE_REGRESS_MODE, + then some fields are redacted when printing each message, such as object + OIDs, to make the output more convenient to use in testing frameworks. + This function must be called after calling PQtrace. + + + + + + + PQuntracePQuntrace + + + + Disables tracing started by . + +void PQuntrace(PGconn *conn); + + + + + + + + + + Miscellaneous Functions + + + As always, there are some functions that just don't fit anywhere. + + + + + PQfreememPQfreemem + + + + Frees memory allocated by libpq. + +void PQfreemem(void *ptr); + + + + + Frees memory allocated by libpq, particularly + , + , + , + and PQnotifies. + It is particularly important that this function, rather than + free(), be used on Microsoft Windows. This is because + allocating memory in a DLL and releasing it in the application works + only if multithreaded/single-threaded, release/debug, and static/dynamic + flags are the same for the DLL and the application. On non-Microsoft + Windows platforms, this function is the same as the standard library + function free(). + + + + + + PQconninfoFreePQconninfoFree + + + + Frees the data structures allocated by + or . + +void PQconninfoFree(PQconninfoOption *connOptions); + + + + + A simple will not do for this, since + the array contains references to subsidiary strings. + + + + + + PQencryptPasswordConnPQencryptPasswordConn + + + + Prepares the encrypted form of a PostgreSQL password. + +char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm); + + This function is intended to be used by client applications that + wish to send commands like ALTER USER joe PASSWORD + 'pwd'. It is good practice not to send the original cleartext + password in such a command, because it might be exposed in command + logs, activity displays, and so on. Instead, use this function to + convert the password to encrypted form before it is sent. + + + + The passwd and user arguments + are the cleartext password, and the SQL name of the user it is for. + algorithm specifies the encryption algorithm + to use to encrypt the password. Currently supported algorithms are + md5 and scram-sha-256 (on and + off are also accepted as aliases for md5, for + compatibility with older server versions). Note that support for + scram-sha-256 was introduced in PostgreSQL + version 10, and will not work correctly with older server versions. If + algorithm is NULL, this function will query + the server for the current value of the + setting. That can block, and + will fail if the current transaction is aborted, or if the connection + is busy executing another query. If you wish to use the default + algorithm for the server but want to avoid blocking, query + password_encryption yourself before calling + , and pass that value as the + algorithm. + + + + The return value is a string allocated by malloc. + The caller can assume the string doesn't contain any special characters + that would require escaping. Use to free the + result when done with it. On error, returns NULL, and + a suitable message is stored in the connection object. + + + + + + + PQencryptPasswordPQencryptPassword + + + + Prepares the md5-encrypted form of a PostgreSQL password. + +char *PQencryptPassword(const char *passwd, const char *user); + + is an older, deprecated version of + . The difference is that + does not + require a connection object, and md5 is always used as the + encryption algorithm. + + + + + + PQmakeEmptyPGresultPQmakeEmptyPGresult + + + + Constructs an empty PGresult object with the given status. + +PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); + + + + + This is libpq's internal function to allocate and + initialize an empty PGresult object. This + function returns NULL if memory could not be allocated. It is + exported because some applications find it useful to generate result + objects (particularly objects with error status) themselves. If + conn is not null and status + indicates an error, the current error message of the specified + connection is copied into the PGresult. + Also, if conn is not null, any event procedures + registered in the connection are copied into the + PGresult. (They do not get + PGEVT_RESULTCREATE calls, but see + .) + Note that should eventually be called + on the object, just as with a PGresult + returned by libpq itself. + + + + + + PQfireResultCreateEventsPQfireResultCreateEvents + + + Fires a PGEVT_RESULTCREATE event (see ) for each event procedure registered in the + PGresult object. Returns non-zero for success, + zero if any event procedure fails. + + +int PQfireResultCreateEvents(PGconn *conn, PGresult *res); + + + + + The conn argument is passed through to event procedures + but not used directly. It can be NULL if the event + procedures won't use it. + + + + Event procedures that have already received a + PGEVT_RESULTCREATE or PGEVT_RESULTCOPY event + for this object are not fired again. + + + + The main reason that this function is separate from + is that it is often appropriate + to create a PGresult and fill it with data + before invoking the event procedures. + + + + + + PQcopyResultPQcopyResult + + + + Makes a copy of a PGresult object. The copy is + not linked to the source result in any way and + must be called when the copy is no longer + needed. If the function fails, NULL is returned. + + +PGresult *PQcopyResult(const PGresult *src, int flags); + + + + + This is not intended to make an exact copy. The returned result is + always put into PGRES_TUPLES_OK status, and does not + copy any error message in the source. (It does copy the command status + string, however.) The flags argument determines + what else is copied. It is a bitwise OR of several flags. + PG_COPYRES_ATTRS specifies copying the source + result's attributes (column definitions). + PG_COPYRES_TUPLES specifies copying the source + result's tuples. (This implies copying the attributes, too.) + PG_COPYRES_NOTICEHOOKS specifies + copying the source result's notify hooks. + PG_COPYRES_EVENTS specifies copying the source + result's events. (But any instance data associated with the source + is not copied.) + + + + + + PQsetResultAttrsPQsetResultAttrs + + + + Sets the attributes of a PGresult object. + +int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs); + + + + + The provided attDescs are copied into the result. + If the attDescs pointer is NULL or + numAttributes is less than one, the request is + ignored and the function succeeds. If res + already contains attributes, the function will fail. If the function + fails, the return value is zero. If the function succeeds, the return + value is non-zero. + + + + + + PQsetvaluePQsetvalue + + + + Sets a tuple field value of a PGresult object. + +int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); + + + + + The function will automatically grow the result's internal tuples array + as needed. However, the tup_num argument must be + less than or equal to , meaning this + function can only grow the tuples array one tuple at a time. But any + field of any existing tuple can be modified in any order. If a value at + field_num already exists, it will be overwritten. + If len is -1 or + value is NULL, the field value + will be set to an SQL null value. The + value is copied into the result's private storage, + thus is no longer needed after the function + returns. If the function fails, the return value is zero. If the + function succeeds, the return value is non-zero. + + + + + + PQresultAllocPQresultAlloc + + + + Allocate subsidiary storage for a PGresult object. + +void *PQresultAlloc(PGresult *res, size_t nBytes); + + + + + Any memory allocated with this function will be freed when + res is cleared. If the function fails, + the return value is NULL. The result is + guaranteed to be adequately aligned for any type of data, + just as for malloc. + + + + + + PQresultMemorySizePQresultMemorySize + + + + Retrieves the number of bytes allocated for + a PGresult object. + +size_t PQresultMemorySize(const PGresult *res); + + + + + This value is the sum of all malloc requests + associated with the PGresult object, that is, + all the space that will be freed by . + This information can be useful for managing memory consumption. + + + + + + PQlibVersionPQlibVersionPQserverVersion + + + + Return the version of libpq that is being used. + +int PQlibVersion(void); + + + + + The result of this function can be used to determine, at + run time, whether specific functionality is available in the currently + loaded version of libpq. The function can be used, for example, + to determine which connection options are available in + . + + + + The result is formed by multiplying the library's major version + number by 10000 and adding the minor version number. For example, + version 10.1 will be returned as 100001, and version 11.0 will be + returned as 110000. + + + + Prior to major version 10, PostgreSQL used + three-part version numbers in which the first two parts together + represented the major version. For those + versions, uses two digits for each + part; for example version 9.1.5 will be returned as 90105, and + version 9.2.0 will be returned as 90200. + + + + Therefore, for purposes of determining feature compatibility, + applications should divide the result of + by 100 not 10000 to determine a logical major version number. + In all release series, only the last two digits differ between + minor releases (bug-fix releases). + + + + + This function appeared in PostgreSQL version 9.1, so + it cannot be used to detect required functionality in earlier + versions, since calling it will create a link dependency + on version 9.1 or later. + + + + + + + + + + + Notice Processing + + + notice processing + in libpq + + + + Notice and warning messages generated by the server are not returned + by the query execution functions, since they do not imply failure of + the query. Instead they are passed to a notice handling function, and + execution continues normally after the handler returns. The default + notice handling function prints the message on + stderr, but the application can override this + behavior by supplying its own handling function. + + + + For historical reasons, there are two levels of notice handling, called + the notice receiver and notice processor. The default behavior is for + the notice receiver to format the notice and pass a string to the notice + processor for printing. However, an application that chooses to provide + its own notice receiver will typically ignore the notice processor + layer and just do all the work in the notice receiver. + + + + The function PQsetNoticeReceiver + notice receiver + PQsetNoticeReceiver sets or + examines the current notice receiver for a connection object. + Similarly, PQsetNoticeProcessor + notice processor + PQsetNoticeProcessor sets or + examines the current notice processor. + + +typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res); + +PQnoticeReceiver +PQsetNoticeReceiver(PGconn *conn, + PQnoticeReceiver proc, + void *arg); + +typedef void (*PQnoticeProcessor) (void *arg, const char *message); + +PQnoticeProcessor +PQsetNoticeProcessor(PGconn *conn, + PQnoticeProcessor proc, + void *arg); + + + Each of these functions returns the previous notice receiver or + processor function pointer, and sets the new value. If you supply a + null function pointer, no action is taken, but the current pointer is + returned. + + + + When a notice or warning message is received from the server, or + generated internally by libpq, the notice + receiver function is called. It is passed the message in the form of + a PGRES_NONFATAL_ERROR + PGresult. (This allows the receiver to extract + individual fields using , or obtain a + complete preformatted message using + or .) The same + void pointer passed to PQsetNoticeReceiver is also + passed. (This pointer can be used to access application-specific state + if needed.) + + + + The default notice receiver simply extracts the message (using + ) and passes it to the notice + processor. + + + + The notice processor is responsible for handling a notice or warning + message given in text form. It is passed the string text of the message + (including a trailing newline), plus a void pointer that is the same + one passed to PQsetNoticeProcessor. (This pointer + can be used to access application-specific state if needed.) + + + + The default notice processor is simply: + +static void +defaultNoticeProcessor(void *arg, const char *message) +{ + fprintf(stderr, "%s", message); +} + + + + + Once you have set a notice receiver or processor, you should expect + that that function could be called as long as either the + PGconn object or PGresult objects made + from it exist. At creation of a PGresult, the + PGconn's current notice handling pointers are copied + into the PGresult for possible use by functions like + . + + + + + + Event System + + + libpq's event system is designed to notify + registered event handlers about interesting + libpq events, such as the creation or + destruction of PGconn and + PGresult objects. A principal use case is that + this allows applications to associate their own data with a + PGconn or PGresult + and ensure that that data is freed at an appropriate time. + + + + Each registered event handler is associated with two pieces of data, + known to libpq only as opaque void * + pointers. There is a passthrough pointer that is provided + by the application when the event handler is registered with a + PGconn. The passthrough pointer never changes for the + life of the PGconn and all PGresults + generated from it; so if used, it must point to long-lived data. + In addition there is an instance data pointer, which starts + out NULL in every PGconn and PGresult. + This pointer can be manipulated using the + , + , + and + PQsetResultInstanceData functions. Note that + unlike the passthrough pointer, instance data of a PGconn + is not automatically inherited by PGresults created from + it. libpq does not know what passthrough + and instance data pointers point to (if anything) and will never attempt + to free them — that is the responsibility of the event handler. + + + + Event Types + + + The enum PGEventId names the types of events handled by + the event system. All its values have names beginning with + PGEVT. For each event type, there is a corresponding + event info structure that carries the parameters passed to the event + handlers. The event types are: + + + + + PGEVT_REGISTER + + + The register event occurs when + is called. It is the ideal time to initialize any + instanceData an event procedure may need. Only one + register event will be fired per event handler per connection. If the + event procedure fails, the registration is aborted. + + +typedef struct +{ + PGconn *conn; +} PGEventRegister; + + + When a PGEVT_REGISTER event is received, the + evtInfo pointer should be cast to a + PGEventRegister *. This structure contains a + PGconn that should be in the + CONNECTION_OK status; guaranteed if one calls + right after obtaining a good + PGconn. When returning a failure code, all + cleanup must be performed as no PGEVT_CONNDESTROY + event will be sent. + + + + + + PGEVT_CONNRESET + + + The connection reset event is fired on completion of + or PQresetPoll. In + both cases, the event is only fired if the reset was successful. If + the event procedure fails, the entire connection reset will fail; the + PGconn is put into + CONNECTION_BAD status and + PQresetPoll will return + PGRES_POLLING_FAILED. + + +typedef struct +{ + PGconn *conn; +} PGEventConnReset; + + + When a PGEVT_CONNRESET event is received, the + evtInfo pointer should be cast to a + PGEventConnReset *. Although the contained + PGconn was just reset, all event data remains + unchanged. This event should be used to reset/reload/requery any + associated instanceData. Note that even if the + event procedure fails to process PGEVT_CONNRESET, it will + still receive a PGEVT_CONNDESTROY event when the connection + is closed. + + + + + + PGEVT_CONNDESTROY + + + The connection destroy event is fired in response to + . It is the event procedure's + responsibility to properly clean up its event data as libpq has no + ability to manage this memory. Failure to clean up will lead + to memory leaks. + + +typedef struct +{ + PGconn *conn; +} PGEventConnDestroy; + + + When a PGEVT_CONNDESTROY event is received, the + evtInfo pointer should be cast to a + PGEventConnDestroy *. This event is fired + prior to performing any other cleanup. + The return value of the event procedure is ignored since there is no + way of indicating a failure from . Also, + an event procedure failure should not abort the process of cleaning up + unwanted memory. + + + + + + PGEVT_RESULTCREATE + + + The result creation event is fired in response to any query execution + function that generates a result, including + . This event will only be fired after + the result has been created successfully. + + +typedef struct +{ + PGconn *conn; + PGresult *result; +} PGEventResultCreate; + + + When a PGEVT_RESULTCREATE event is received, the + evtInfo pointer should be cast to a + PGEventResultCreate *. The + conn is the connection used to generate the + result. This is the ideal place to initialize any + instanceData that needs to be associated with the + result. If the event procedure fails, the result will be cleared and + the failure will be propagated. The event procedure must not try to + the result object for itself. When returning a + failure code, all cleanup must be performed as no + PGEVT_RESULTDESTROY event will be sent. + + + + + + PGEVT_RESULTCOPY + + + The result copy event is fired in response to + . This event will only be fired after + the copy is complete. Only event procedures that have + successfully handled the PGEVT_RESULTCREATE + or PGEVT_RESULTCOPY event for the source result + will receive PGEVT_RESULTCOPY events. + + +typedef struct +{ + const PGresult *src; + PGresult *dest; +} PGEventResultCopy; + + + When a PGEVT_RESULTCOPY event is received, the + evtInfo pointer should be cast to a + PGEventResultCopy *. The + src result is what was copied while the + dest result is the copy destination. This event + can be used to provide a deep copy of instanceData, + since PQcopyResult cannot do that. If the event + procedure fails, the entire copy operation will fail and the + dest result will be cleared. When returning a + failure code, all cleanup must be performed as no + PGEVT_RESULTDESTROY event will be sent for the + destination result. + + + + + + PGEVT_RESULTDESTROY + + + The result destroy event is fired in response to a + . It is the event procedure's + responsibility to properly clean up its event data as libpq has no + ability to manage this memory. Failure to clean up will lead + to memory leaks. + + +typedef struct +{ + PGresult *result; +} PGEventResultDestroy; + + + When a PGEVT_RESULTDESTROY event is received, the + evtInfo pointer should be cast to a + PGEventResultDestroy *. This event is fired + prior to performing any other cleanup. + The return value of the event procedure is ignored since there is no + way of indicating a failure from . Also, + an event procedure failure should not abort the process of cleaning up + unwanted memory. + + + + + + + + Event Callback Procedure + + + + PGEventProcPGEventProc + + + + PGEventProc is a typedef for a pointer to an + event procedure, that is, the user callback function that receives + events from libpq. The signature of an event procedure must be + + +int eventproc(PGEventId evtId, void *evtInfo, void *passThrough) + + + The evtId parameter indicates which + PGEVT event occurred. The + evtInfo pointer must be cast to the appropriate + structure type to obtain further information about the event. + The passThrough parameter is the pointer + provided to when the event + procedure was registered. The function should return a non-zero value + if it succeeds and zero if it fails. + + + + A particular event procedure can be registered only once in any + PGconn. This is because the address of the procedure + is used as a lookup key to identify the associated instance data. + + + + + On Windows, functions can have two different addresses: one visible + from outside a DLL and another visible from inside the DLL. One + should be careful that only one of these addresses is used with + libpq's event-procedure functions, else confusion will + result. The simplest rule for writing code that will work is to + ensure that event procedures are declared static. If the + procedure's address must be available outside its own source file, + expose a separate function to return the address. + + + + + + + + + Event Support Functions + + + + PQregisterEventProcPQregisterEventProc + + + + Registers an event callback procedure with libpq. + + +int PQregisterEventProc(PGconn *conn, PGEventProc proc, + const char *name, void *passThrough); + + + + + An event procedure must be registered once on each + PGconn you want to receive events about. There is no + limit, other than memory, on the number of event procedures that + can be registered with a connection. The function returns a non-zero + value if it succeeds and zero if it fails. + + + + The proc argument will be called when a libpq + event is fired. Its memory address is also used to lookup + instanceData. The name + argument is used to refer to the event procedure in error messages. + This value cannot be NULL or a zero-length string. The name string is + copied into the PGconn, so what is passed need not be + long-lived. The passThrough pointer is passed + to the proc whenever an event occurs. This + argument can be NULL. + + + + + + PQsetInstanceDataPQsetInstanceData + + + Sets the connection conn's instanceData + for procedure proc to data. This + returns non-zero for success and zero for failure. (Failure is + only possible if proc has not been properly + registered in conn.) + + +int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data); + + + + + + + PQinstanceDataPQinstanceData + + + Returns the + connection conn's instanceData + associated with procedure proc, + or NULL if there is none. + + +void *PQinstanceData(const PGconn *conn, PGEventProc proc); + + + + + + + PQresultSetInstanceDataPQresultSetInstanceData + + + Sets the result's instanceData + for proc to data. This returns + non-zero for success and zero for failure. (Failure is only + possible if proc has not been properly registered + in the result.) + + +int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data); + + + + + Beware that any storage represented by data + will not be accounted for by , + unless it is allocated using . + (Doing so is recommendable because it eliminates the need to free + such storage explicitly when the result is destroyed.) + + + + + + PQresultInstanceDataPQresultInstanceData + + + Returns the result's instanceData associated with proc, or NULL + if there is none. + + +void *PQresultInstanceData(const PGresult *res, PGEventProc proc); + + + + + + + + + Event Example + + + Here is a skeleton example of managing private data associated with + libpq connections and results. + + + + + +/* The instanceData */ +typedef struct +{ + int n; + char *str; +} mydata; + +/* PGEventProc */ +static int myEventProc(PGEventId evtId, void *evtInfo, void *passThrough); + +int +main(void) +{ + mydata *data; + PGresult *res; + PGconn *conn = + PQconnectdb("dbname=postgres options=-csearch_path="); + + if (PQstatus(conn) != CONNECTION_OK) + { + /* PQerrorMessage's result includes a trailing newline */ + fprintf(stderr, "%s", PQerrorMessage(conn)); + PQfinish(conn); + return 1; + } + + /* called once on any connection that should receive events. + * Sends a PGEVT_REGISTER to myEventProc. + */ + if (!PQregisterEventProc(conn, myEventProc, "mydata_proc", NULL)) + { + fprintf(stderr, "Cannot register PGEventProc\n"); + PQfinish(conn); + return 1; + } + + /* conn instanceData is available */ + data = PQinstanceData(conn, myEventProc); + + /* Sends a PGEVT_RESULTCREATE to myEventProc */ + res = PQexec(conn, "SELECT 1 + 1"); + + /* result instanceData is available */ + data = PQresultInstanceData(res, myEventProc); + + /* If PG_COPYRES_EVENTS is used, sends a PGEVT_RESULTCOPY to myEventProc */ + res_copy = PQcopyResult(res, PG_COPYRES_TUPLES | PG_COPYRES_EVENTS); + + /* result instanceData is available if PG_COPYRES_EVENTS was + * used during the PQcopyResult call. + */ + data = PQresultInstanceData(res_copy, myEventProc); + + /* Both clears send a PGEVT_RESULTDESTROY to myEventProc */ + PQclear(res); + PQclear(res_copy); + + /* Sends a PGEVT_CONNDESTROY to myEventProc */ + PQfinish(conn); + + return 0; +} + +static int +myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) +{ + switch (evtId) + { + case PGEVT_REGISTER: + { + PGEventRegister *e = (PGEventRegister *)evtInfo; + mydata *data = get_mydata(e->conn); + + /* associate app specific data with connection */ + PQsetInstanceData(e->conn, myEventProc, data); + break; + } + + case PGEVT_CONNRESET: + { + PGEventConnReset *e = (PGEventConnReset *)evtInfo; + mydata *data = PQinstanceData(e->conn, myEventProc); + + if (data) + memset(data, 0, sizeof(mydata)); + break; + } + + case PGEVT_CONNDESTROY: + { + PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo; + mydata *data = PQinstanceData(e->conn, myEventProc); + + /* free instance data because the conn is being destroyed */ + if (data) + free_mydata(data); + break; + } + + case PGEVT_RESULTCREATE: + { + PGEventResultCreate *e = (PGEventResultCreate *)evtInfo; + mydata *conn_data = PQinstanceData(e->conn, myEventProc); + mydata *res_data = dup_mydata(conn_data); + + /* associate app specific data with result (copy it from conn) */ + PQsetResultInstanceData(e->result, myEventProc, res_data); + break; + } + + case PGEVT_RESULTCOPY: + { + PGEventResultCopy *e = (PGEventResultCopy *)evtInfo; + mydata *src_data = PQresultInstanceData(e->src, myEventProc); + mydata *dest_data = dup_mydata(src_data); + + /* associate app specific data with result (copy it from a result) */ + PQsetResultInstanceData(e->dest, myEventProc, dest_data); + break; + } + + case PGEVT_RESULTDESTROY: + { + PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo; + mydata *data = PQresultInstanceData(e->result, myEventProc); + + /* free instance data because the result is being destroyed */ + if (data) + free_mydata(data); + break; + } + + /* unknown event ID, just return true. */ + default: + break; + } + + return true; /* event processing succeeded */ +} +]]> + + + + + + Environment Variables + + + environment variable + + + + The following environment variables can be used to select default + connection parameter values, which will be used by + , and + if no value is directly specified by the calling + code. These are useful to avoid hard-coding database connection + information into simple client applications, for example. + + + + + + PGHOST + + PGHOST behaves the same as the connection parameter. + + + + + + + PGHOSTADDR + + PGHOSTADDR behaves the same as the connection parameter. + This can be set instead of or in addition to PGHOST + to avoid DNS lookup overhead. + + + + + + + PGPORT + + PGPORT behaves the same as the connection parameter. + + + + + + + PGDATABASE + + PGDATABASE behaves the same as the connection parameter. + + + + + + + PGUSER + + PGUSER behaves the same as the connection parameter. + + + + + + + PGPASSWORD + + PGPASSWORD behaves the same as the connection parameter. + Use of this environment variable + is not recommended for security reasons, as some operating systems + allow non-root users to see process environment variables via + ps; instead consider using a password file + (see ). + + + + + + + PGPASSFILE + + PGPASSFILE behaves the same as the connection parameter. + + + + + + + PGCHANNELBINDING + + PGCHANNELBINDING behaves the same as the connection parameter. + + + + + + + PGSERVICE + + PGSERVICE behaves the same as the connection parameter. + + + + + + + PGSERVICEFILE + + PGSERVICEFILE specifies the name of the per-user + connection service file. If not set, it defaults + to ~/.pg_service.conf + (see ). + + + + + + + PGOPTIONS + + PGOPTIONS behaves the same as the connection parameter. + + + + + + + PGAPPNAME + + PGAPPNAME behaves the same as the connection parameter. + + + + + + + PGSSLMODE + + PGSSLMODE behaves the same as the connection parameter. + + + + + + + PGREQUIRESSL + + PGREQUIRESSL behaves the same as the connection parameter. + This environment variable is deprecated in favor of the + PGSSLMODE variable; setting both variables suppresses the + effect of this one. + + + + + + + PGSSLCOMPRESSION + + PGSSLCOMPRESSION behaves the same as the connection parameter. + + + + + + + PGSSLCERT + + PGSSLCERT behaves the same as the connection parameter. + + + + + + + PGSSLKEY + + PGSSLKEY behaves the same as the connection parameter. + + + + + + + PGSSLROOTCERT + + PGSSLROOTCERT behaves the same as the connection parameter. + + + + + + + PGSSLCRL + + PGSSLCRL behaves the same as the connection parameter. + + + + + + + PGSSLCRLDIR + + PGSSLCRLDIR behaves the same as the connection parameter. + + + + + + + PGSSLSNI + + PGSSLSNI behaves the same as the connection parameter. + + + + + + + PGREQUIREPEER + + PGREQUIREPEER behaves the same as the connection parameter. + + + + + + + PGSSLMINPROTOCOLVERSION + + PGSSLMINPROTOCOLVERSION behaves the same as the connection parameter. + + + + + + + PGSSLMAXPROTOCOLVERSION + + PGSSLMAXPROTOCOLVERSION behaves the same as the connection parameter. + + + + + + + PGGSSENCMODE + + PGGSSENCMODE behaves the same as the connection parameter. + + + + + + + PGKRBSRVNAME + + PGKRBSRVNAME behaves the same as the connection parameter. + + + + + + + PGGSSLIB + + PGGSSLIB behaves the same as the connection parameter. + + + + + + + PGCONNECT_TIMEOUT + + PGCONNECT_TIMEOUT behaves the same as the connection parameter. + + + + + + + PGCLIENTENCODING + + PGCLIENTENCODING behaves the same as the connection parameter. + + + + + + + PGTARGETSESSIONATTRS + + PGTARGETSESSIONATTRS behaves the same as the connection parameter. + + + + + + + The following environment variables can be used to specify default + behavior for each PostgreSQL session. (See + also the + and + commands for ways to set default behavior on a per-user or per-database + basis.) + + + + + + PGDATESTYLE + + PGDATESTYLE sets the default style of date/time + representation. (Equivalent to SET datestyle TO + ....) + + + + + + + PGTZ + + PGTZ sets the default time zone. (Equivalent to + SET timezone TO ....) + + + + + + + PGGEQO + + PGGEQO sets the default mode for the genetic query + optimizer. (Equivalent to SET geqo TO ....) + + + + + Refer to the SQL command + for information on correct values for these + environment variables. + + + + The following environment variables determine internal behavior of + libpq; they override compiled-in defaults. + + + + + + PGSYSCONFDIR + + PGSYSCONFDIR sets the directory containing the + pg_service.conf file and in a future version + possibly other system-wide configuration files. + + + + + + + PGLOCALEDIR + + PGLOCALEDIR sets the directory containing the + locale files for message localization. + + + + + + + + + + The Password File + + + password file + + + .pgpass + + + + The file .pgpass in a user's home directory can + contain passwords to + be used if the connection requires a password (and no password has been + specified otherwise). On Microsoft Windows the file is named + %APPDATA%\postgresql\pgpass.conf (where + %APPDATA% refers to the Application Data subdirectory in + the user's profile). + Alternatively, a password file can be specified + using the connection parameter + or the environment variable PGPASSFILE. + + + + This file should contain lines of the following format: + +hostname:port:database:username:password + + (You can add a reminder comment to the file by copying the line above and + preceding it with #.) + Each of the first four fields can be a literal value, or + *, which matches anything. The password field from + the first line that matches the current connection parameters will be + used. (Therefore, put more-specific entries first when you are using + wildcards.) If an entry needs to contain : or + \, escape this character with \. + The host name field is matched to the host connection + parameter if that is specified, otherwise to + the hostaddr parameter if that is specified; if neither + are given then the host name localhost is searched for. + The host name localhost is also searched for when + the connection is a Unix-domain socket connection and + the host parameter + matches libpq's default socket directory path. + In a standby server, a database field of replication + matches streaming replication connections made to the primary server. + The database field is of limited usefulness otherwise, because users have + the same password for all databases in the same cluster. + + + + On Unix systems, the permissions on a password file must + disallow any access to world or group; achieve this by a command such as + chmod 0600 ~/.pgpass. If the permissions are less + strict than this, the file will be ignored. On Microsoft Windows, it + is assumed that the file is stored in a directory that is secure, so + no special permissions check is made. + + + + + + The Connection Service File + + + connection service file + + + pg_service.conf + + + .pg_service.conf + + + + The connection service file allows libpq connection parameters to be + associated with a single service name. That service name can then be + specified in a libpq connection string, and the associated settings will be + used. This allows connection parameters to be modified without requiring + a recompile of the libpq-using application. The service name can also be + specified using the PGSERVICE environment variable. + + + + Service names can be defined in either a per-user service file or a + system-wide file. If the same service name exists in both the user + and the system file, the user file takes precedence. + By default, the per-user service file is located + at ~/.pg_service.conf; this can be overridden by + setting the environment variable PGSERVICEFILE. + The system-wide file is named pg_service.conf. + By default it is sought in the etc directory + of the PostgreSQL installation + (use pg_config --sysconfdir to identify this + directory precisely). Another directory, but not a different file + name, can be specified by setting the environment variable + PGSYSCONFDIR. + + + + Either service file uses an INI file format where the section + name is the service name and the parameters are connection + parameters; see for a list. For + example: + +# comment +[mydb] +host=somehost +port=5433 +user=admin + + An example file is provided in + the PostgreSQL installation at + share/pg_service.conf.sample. + + + + Connection parameters obtained from a service file are combined with + parameters obtained from other sources. A service file setting + overrides the corresponding environment variable, and in turn can be + overridden by a value given directly in the connection string. + For example, using the above service file, a connection string + service=mydb port=5434 will use + host somehost, port 5434, + user admin, and other parameters as set by + environment variables or built-in defaults. + + + + + + LDAP Lookup of Connection Parameters + + + LDAP connection parameter lookup + + + + If libpq has been compiled with LDAP support (option + for configure) + it is possible to retrieve connection options like host + or dbname via LDAP from a central server. + The advantage is that if the connection parameters for a database change, + the connection information doesn't have to be updated on all client machines. + + + + LDAP connection parameter lookup uses the connection service file + pg_service.conf (see ). A line in a + pg_service.conf stanza that starts with + ldap:// will be recognized as an LDAP URL and an + LDAP query will be performed. The result must be a list of + keyword = value pairs which will be used to set + connection options. The URL must conform to + RFC 1959 + and be of the form + +ldap://[hostname[:port]]/search_base?attribute?search_scope?filter + + where hostname defaults to + localhost and port + defaults to 389. + + + + Processing of pg_service.conf is terminated after + a successful LDAP lookup, but is continued if the LDAP server cannot + be contacted. This is to provide a fallback with further LDAP URL + lines that point to different LDAP servers, classical keyword + = value pairs, or default connection options. If you would + rather get an error message in this case, add a syntactically incorrect + line after the LDAP URL. + + + + A sample LDAP entry that has been created with the LDIF file + +version:1 +dn:cn=mydatabase,dc=mycompany,dc=com +changetype:add +objectclass:top +objectclass:device +cn:mydatabase +description:host=dbserver.mycompany.com +description:port=5439 +description:dbname=mydb +description:user=mydb_user +description:sslmode=require + + might be queried with the following LDAP URL: + +ldap://ldap.mycompany.com/dc=mycompany,dc=com?description?one?(cn=mydatabase) + + + + + You can also mix regular service file entries with LDAP lookups. + A complete example for a stanza in pg_service.conf + would be: + +# only host and port are stored in LDAP, specify dbname and user explicitly +[customerdb] +dbname=customer +user=appuser +ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) + + + + + + + + SSL Support + + + SSL + + + + PostgreSQL has native support for using SSL + connections to encrypt client/server communications for increased + security. See for details about the server-side + SSL functionality. + + + + libpq reads the system-wide + OpenSSL configuration file. By default, this + file is named openssl.cnf and is located in the + directory reported by openssl version -d. This default + can be overridden by setting environment variable + OPENSSL_CONF to the name of the desired configuration + file. + + + + Client Verification of Server Certificates + + + By default, PostgreSQL will not perform any verification of + the server certificate. This means that it is possible to spoof the server + identity (for example by modifying a DNS record or by taking over the server + IP address) without the client knowing. In order to prevent spoofing, + the client must be able to verify the server's identity via a chain of + trust. A chain of trust is established by placing a root (self-signed) + certificate authority (CA) certificate on one + computer and a leaf certificate signed by the + root certificate on another computer. It is also possible to use an + intermediate certificate which is signed by the root + certificate and signs leaf certificates. + + + + To allow the client to verify the identity of the server, place a root + certificate on the client and a leaf certificate signed by the root + certificate on the server. To allow the server to verify the identity + of the client, place a root certificate on the server and a leaf + certificate signed by the root certificate on the client. One or more + intermediate certificates (usually stored with the leaf certificate) + can also be used to link the leaf certificate to the root certificate. + + + + Once a chain of trust has been established, there are two ways for + the client to validate the leaf certificate sent by the server. + If the parameter sslmode is set to verify-ca, + libpq will verify that the server is trustworthy by checking the + certificate chain up to the root certificate stored on the client. + If sslmode is set to verify-full, + libpq will also verify that the server host + name matches the name stored in the server certificate. The + SSL connection will fail if the server certificate cannot be + verified. verify-full is recommended in most + security-sensitive environments. + + + + In verify-full mode, the host name is matched against the + certificate's Subject Alternative Name attribute(s), or against the + Common Name attribute if no Subject Alternative Name of type dNSName is + present. If the certificate's name attribute starts with an asterisk + (*), the asterisk will be treated as + a wildcard, which will match all characters except a dot + (.). This means the certificate will not match subdomains. + If the connection is made using an IP address instead of a host name, the + IP address will be matched (without doing any DNS lookups). + + + + To allow server certificate verification, one or more root certificates + must be placed in the file ~/.postgresql/root.crt + in the user's home directory. (On Microsoft Windows the file is named + %APPDATA%\postgresql\root.crt.) Intermediate + certificates should also be added to the file if they are needed to link + the certificate chain sent by the server to the root certificates + stored on the client. + + + + Certificate Revocation List (CRL) entries are also checked + if the file ~/.postgresql/root.crl exists + (%APPDATA%\postgresql\root.crl on Microsoft + Windows). + + + + The location of the root certificate file and the CRL can be changed by + setting + the connection parameters sslrootcert and sslcrl + or the environment variables PGSSLROOTCERT and PGSSLCRL. + + + + + For backwards compatibility with earlier versions of PostgreSQL, if a + root CA file exists, the behavior of + sslmode=require will be the same + as that of verify-ca, meaning the server certificate + is validated against the CA. Relying on this behavior is discouraged, + and applications that need certificate validation should always use + verify-ca or verify-full. + + + + + + Client Certificates + + + If the server attempts to verify the identity of the + client by requesting the client's leaf certificate, + libpq will send the certificates stored in + file ~/.postgresql/postgresql.crt in the user's home + directory. The certificates must chain to the root certificate trusted + by the server. A matching + private key file ~/.postgresql/postgresql.key must also + be present. The private + key file must not allow any access to world or group; achieve this by the + command chmod 0600 ~/.postgresql/postgresql.key. + On Microsoft Windows these files are named + %APPDATA%\postgresql\postgresql.crt and + %APPDATA%\postgresql\postgresql.key, and there + is no special permissions check since the directory is presumed secure. + The location of the certificate and key files can be overridden by the + connection parameters sslcert and sslkey or the + environment variables PGSSLCERT and PGSSLKEY. + + + + The first certificate in postgresql.crt must be the + client's certificate because it must match the client's private key. + Intermediate certificates can be optionally appended + to the file — doing so avoids requiring storage of intermediate + certificates on the server (). + + + + The certificate and key may be in PEM or ASN.1 DER format. + + + + The key may be + stored in cleartext or encrypted with a passphrase using any algorithm + supported by OpenSSL, like AES-128. If the key + is stored encrypted, then the passphrase may be provided in the + connection option. If an + encrypted key is supplied and the sslpassword option + is absent or blank, a password will be prompted for interactively by + OpenSSL with a + Enter PEM pass phrase: prompt if a TTY is available. + Applications can override the client certificate prompt and the handling + of the sslpassword parameter by supplying their own + key password callback; see + . + + + + For instructions on creating certificates, see . + + + + + Protection Provided in Different Modes + + + The different values for the sslmode parameter provide different + levels of protection. SSL can provide + protection against three types of attacks: + + + + Eavesdropping + + If a third party can examine the network traffic between the + client and the server, it can read both connection information (including + the user name and password) and the data that is passed. SSL + uses encryption to prevent this. + + + + + + Man-in-the-middle (MITM) + + If a third party can modify the data while passing between the + client and server, it can pretend to be the server and therefore see and + modify data even if it is encrypted. The third party can then + forward the connection information and data to the original server, + making it impossible to detect this attack. Common vectors to do this + include DNS poisoning and address hijacking, whereby the client is directed + to a different server than intended. There are also several other + attack methods that can accomplish this. SSL uses certificate + verification to prevent this, by authenticating the server to the client. + + + + + + Impersonation + + If a third party can pretend to be an authorized client, it can + simply access data it should not have access to. Typically this can + happen through insecure password management. SSL uses + client certificates to prevent this, by making sure that only holders + of valid certificates can access the server. + + + + + + + + For a connection to be known SSL-secured, SSL usage must be configured + on both the client and the server before the connection + is made. If it is only configured on the server, the client may end up + sending sensitive information (e.g., passwords) before + it knows that the server requires high security. In libpq, secure + connections can be ensured + by setting the sslmode parameter to verify-full or + verify-ca, and providing the system with a root certificate to + verify against. This is analogous to using an https + URL for encrypted web browsing. + + + + Once the server has been authenticated, the client can pass sensitive data. + This means that up until this point, the client does not need to know if + certificates will be used for authentication, making it safe to specify that + only in the server configuration. + + + + All SSL options carry overhead in the form of encryption and + key-exchange, so there is a trade-off that has to be made between performance + and security. + illustrates the risks the different sslmode values + protect against, and what statement they make about security and overhead. + + + + SSL Mode Descriptions + + + + + + + + sslmode + Eavesdropping protection + MITM protection + Statement + + + + + + disable + No + No + I don't care about security, and I don't want to pay the overhead + of encryption. + + + + + allow + Maybe + No + I don't care about security, but I will pay the overhead of + encryption if the server insists on it. + + + + + prefer + Maybe + No + I don't care about encryption, but I wish to pay the overhead of + encryption if the server supports it. + + + + + require + Yes + No + I want my data to be encrypted, and I accept the overhead. I trust + that the network will make sure I always connect to the server I want. + + + + + verify-ca + Yes + Depends on CA policy + I want my data encrypted, and I accept the overhead. I want to be + sure that I connect to a server that I trust. + + + + + verify-full + Yes + Yes + I want my data encrypted, and I accept the overhead. I want to be + sure that I connect to a server I trust, and that it's the one I + specify. + + + + + +
+ + + The difference between verify-ca and verify-full + depends on the policy of the root CA. If a public + CA is used, verify-ca allows connections to a server + that somebody else may have registered with the CA. + In this case, verify-full should always be used. If + a local CA is used, or even a self-signed certificate, using + verify-ca often provides enough protection. + + + + The default value for sslmode is prefer. As is shown + in the table, this makes no sense from a security point of view, and it only + promises performance overhead if possible. It is only provided as the default + for backward compatibility, and is not recommended in secure deployments. + + +
+ + + SSL Client File Usage + + + summarizes the files that are + relevant to the SSL setup on the client. + + + + Libpq/Client SSL File Usage + + + + File + Contents + Effect + + + + + + + ~/.postgresql/postgresql.crt + client certificate + sent to server + + + + ~/.postgresql/postgresql.key + client private key + proves client certificate sent by owner; does not indicate + certificate owner is trustworthy + + + + ~/.postgresql/root.crt + trusted certificate authorities + checks that server certificate is signed by a trusted certificate + authority + + + + ~/.postgresql/root.crl + certificates revoked by certificate authorities + server certificate must not be on this list + + + + +
+
+ + + SSL Library Initialization + + + If your application initializes libssl and/or + libcrypto libraries and libpq + is built with SSL support, you should call + to tell libpq + that the libssl and/or libcrypto libraries + have been initialized by your application, so that + libpq will not also initialize those libraries. + + + + + + PQinitOpenSSLPQinitOpenSSL + + + + Allows applications to select which security libraries to initialize. + +void PQinitOpenSSL(int do_ssl, int do_crypto); + + + + + When do_ssl is non-zero, libpq + will initialize the OpenSSL library before first + opening a database connection. When do_crypto is + non-zero, the libcrypto library will be initialized. By + default (if is not called), both libraries + are initialized. When SSL support is not compiled in, this function is + present but does nothing. + + + + If your application uses and initializes either OpenSSL + or its underlying libcrypto library, you must + call this function with zeroes for the appropriate parameter(s) + before first opening a database connection. Also be sure that you + have done that initialization before opening a database connection. + + + + + + PQinitSSLPQinitSSL + + Allows applications to select which security libraries to initialize. + +void PQinitSSL(int do_ssl); + + + + + This function is equivalent to + PQinitOpenSSL(do_ssl, do_ssl). + It is sufficient for applications that initialize both or neither + of OpenSSL and libcrypto. + + + + has been present since + PostgreSQL 8.0, while + was added in PostgreSQL 8.4, so + might be preferable for applications that need to work with older + versions of libpq. + + + + + + + +
+ + + + Behavior in Threaded Programs + + + threads + with libpq + + + + libpq is reentrant and thread-safe by default. + You might need to use special compiler command-line + options when you compile your application code. Refer to your + system's documentation for information about how to build + thread-enabled applications, or look in + src/Makefile.global for PTHREAD_CFLAGS + and PTHREAD_LIBS. This function allows the querying of + libpq's thread-safe status: + + + + + PQisthreadsafePQisthreadsafe + + + + Returns the thread safety status of the + libpq library. + +int PQisthreadsafe(); + + + + + Returns 1 if the libpq is thread-safe + and 0 if it is not. + + + + + + + One thread restriction is that no two threads attempt to manipulate + the same PGconn object at the same time. In particular, + you cannot issue concurrent commands from different threads through + the same connection object. (If you need to run concurrent commands, + use multiple connections.) + + + + PGresult objects are normally read-only after creation, + and so can be passed around freely between threads. However, if you use + any of the PGresult-modifying functions described in + or , it's up + to you to avoid concurrent operations on the same PGresult, + too. + + + + The deprecated functions and + are not thread-safe and should not be + used in multithread programs. + can be replaced by . + can be replaced by + . + + + + If you are using Kerberos inside your application (in addition to inside + libpq), you will need to do locking around + Kerberos calls because Kerberos functions are not thread-safe. See + function PQregisterThreadLock in the + libpq source code for a way to do cooperative + locking between libpq and your application. + + + + + + Building <application>libpq</application> Programs + + + compiling + libpq applications + + + + To build (i.e., compile and link) a program using + libpq you need to do all of the following + things: + + + + + Include the libpq-fe.h header file: + +#include <libpq-fe.h> + + If you failed to do that then you will normally get error messages + from your compiler similar to: + +foo.c: In function `main': +foo.c:34: `PGconn' undeclared (first use in this function) +foo.c:35: `PGresult' undeclared (first use in this function) +foo.c:54: `CONNECTION_BAD' undeclared (first use in this function) +foo.c:68: `PGRES_COMMAND_OK' undeclared (first use in this function) +foo.c:95: `PGRES_TUPLES_OK' undeclared (first use in this function) + + + + + + + Point your compiler to the directory where the PostgreSQL header + files were installed, by supplying the + -Idirectory option + to your compiler. (In some cases the compiler will look into + the directory in question by default, so you can omit this + option.) For instance, your compile command line could look + like: + +cc -c -I/usr/local/pgsql/include testprog.c + + If you are using makefiles then add the option to the + CPPFLAGS variable: + +CPPFLAGS += -I/usr/local/pgsql/include + + + + + If there is any chance that your program might be compiled by + other users then you should not hardcode the directory location + like that. Instead, you can run the utility + pg_configpg_configwith libpq to find out where the header + files are on the local system: + +$ pg_config --includedir +/usr/local/include + + + + + If you + have pkg-configpkg-configwith + libpq installed, you can run instead: + +$ pkg-config --cflags libpq +-I/usr/local/include + + Note that this will already include the in front of + the path. + + + + Failure to specify the correct option to the compiler will + result in an error message such as: + +testlibpq.c:8:22: libpq-fe.h: No such file or directory + + + + + + + When linking the final program, specify the option + -lpq so that the libpq + library gets pulled in, as well as the option + -Ldirectory to point + the compiler to the directory where the + libpq library resides. (Again, the + compiler will search some directories by default.) For maximum + portability, put the option before the + option. For example: + +cc -o testprog testprog1.o testprog2.o -L/usr/local/pgsql/lib -lpq + + + + + You can find out the library directory using + pg_config as well: + +$ pg_config --libdir +/usr/local/pgsql/lib + + + + + Or again use pkg-config: + +$ pkg-config --libs libpq +-L/usr/local/pgsql/lib -lpq + + Note again that this prints the full options, not only the path. + + + + Error messages that point to problems in this area could look like + the following: + +testlibpq.o: In function `main': +testlibpq.o(.text+0x60): undefined reference to `PQsetdbLogin' +testlibpq.o(.text+0x71): undefined reference to `PQstatus' +testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage' + + This means you forgot . + +/usr/bin/ld: cannot find -lpq + + This means you forgot the option or did not + specify the right directory. + + + + + + + + + + Example Programs + + + These examples and others can be found in the + directory src/test/examples in the source code + distribution. + + + + <application>libpq</application> Example Program 1 + + + +#include +#include "libpq-fe.h" + +static void +exit_nicely(PGconn *conn) +{ + PQfinish(conn); + exit(1); +} + +int +main(int argc, char **argv) +{ + const char *conninfo; + PGconn *conn; + PGresult *res; + int nFields; + int i, + j; + + /* + * If the user supplies a parameter on the command line, use it as the + * conninfo string; otherwise default to setting dbname=postgres and using + * environment variables or defaults for all other connection parameters. + */ + if (argc > 1) + conninfo = argv[1]; + else + conninfo = "dbname = postgres"; + + /* Make a connection to the database */ + conn = PQconnectdb(conninfo); + + /* Check to see that the backend connection was successfully made */ + if (PQstatus(conn) != CONNECTION_OK) + { + fprintf(stderr, "%s", PQerrorMessage(conn)); + exit_nicely(conn); + } + + /* Set always-secure search path, so malicious users can't take control. */ + res = PQexec(conn, + "SELECT pg_catalog.set_config('search_path', '', false)"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + + /* + * Should PQclear PGresult whenever it is no longer needed to avoid memory + * leaks + */ + PQclear(res); + + /* + * Our test case here involves using a cursor, for which we must be inside + * a transaction block. We could do the whole thing with a single + * PQexec() of "select * from pg_database", but that's too trivial to make + * a good example. + */ + + /* Start a transaction block */ + res = PQexec(conn, "BEGIN"); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + PQclear(res); + + /* + * Fetch rows from pg_database, the system catalog of databases + */ + res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database"); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + PQclear(res); + + res = PQexec(conn, "FETCH ALL in myportal"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + + /* first, print out the attribute names */ + nFields = PQnfields(res); + for (i = 0; i < nFields; i++) + printf("%-15s", PQfname(res, i)); + printf("\n\n"); + + /* next, print out the rows */ + for (i = 0; i < PQntuples(res); i++) + { + for (j = 0; j < nFields; j++) + printf("%-15s", PQgetvalue(res, i, j)); + printf("\n"); + } + + PQclear(res); + + /* close the portal ... we don't bother to check for errors ... */ + res = PQexec(conn, "CLOSE myportal"); + PQclear(res); + + /* end the transaction */ + res = PQexec(conn, "END"); + PQclear(res); + + /* close the connection to the database and cleanup */ + PQfinish(conn); + + return 0; +} +]]> + + + + + <application>libpq</application> Example Program 2 + + + +#endif +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#include "libpq-fe.h" + +static void +exit_nicely(PGconn *conn) +{ + PQfinish(conn); + exit(1); +} + +int +main(int argc, char **argv) +{ + const char *conninfo; + PGconn *conn; + PGresult *res; + PGnotify *notify; + int nnotifies; + + /* + * If the user supplies a parameter on the command line, use it as the + * conninfo string; otherwise default to setting dbname=postgres and using + * environment variables or defaults for all other connection parameters. + */ + if (argc > 1) + conninfo = argv[1]; + else + conninfo = "dbname = postgres"; + + /* Make a connection to the database */ + conn = PQconnectdb(conninfo); + + /* Check to see that the backend connection was successfully made */ + if (PQstatus(conn) != CONNECTION_OK) + { + fprintf(stderr, "%s", PQerrorMessage(conn)); + exit_nicely(conn); + } + + /* Set always-secure search path, so malicious users can't take control. */ + res = PQexec(conn, + "SELECT pg_catalog.set_config('search_path', '', false)"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + + /* + * Should PQclear PGresult whenever it is no longer needed to avoid memory + * leaks + */ + PQclear(res); + + /* + * Issue LISTEN command to enable notifications from the rule's NOTIFY. + */ + res = PQexec(conn, "LISTEN TBL2"); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + PQclear(res); + + /* Quit after four notifies are received. */ + nnotifies = 0; + while (nnotifies < 4) + { + /* + * Sleep until something happens on the connection. We use select(2) + * to wait for input, but you could also use poll() or similar + * facilities. + */ + int sock; + fd_set input_mask; + + sock = PQsocket(conn); + + if (sock < 0) + break; /* shouldn't happen */ + + FD_ZERO(&input_mask); + FD_SET(sock, &input_mask); + + if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0) + { + fprintf(stderr, "select() failed: %s\n", strerror(errno)); + exit_nicely(conn); + } + + /* Now check for input */ + PQconsumeInput(conn); + while ((notify = PQnotifies(conn)) != NULL) + { + fprintf(stderr, + "ASYNC NOTIFY of '%s' received from backend PID %d\n", + notify->relname, notify->be_pid); + PQfreemem(notify); + nnotifies++; + PQconsumeInput(conn); + } + } + + fprintf(stderr, "Done.\n"); + + /* close the connection to the database and cleanup */ + PQfinish(conn); + + return 0; +} +]]> + + + + + <application>libpq</application> Example Program 3 + + + +#endif + +#include +#include +#include +#include +#include +#include "libpq-fe.h" + +/* for ntohl/htonl */ +#include +#include + + +static void +exit_nicely(PGconn *conn) +{ + PQfinish(conn); + exit(1); +} + +/* + * This function prints a query result that is a binary-format fetch from + * a table defined as in the comment above. We split it out because the + * main() function uses it twice. + */ +static void +show_binary_results(PGresult *res) +{ + int i, + j; + int i_fnum, + t_fnum, + b_fnum; + + /* Use PQfnumber to avoid assumptions about field order in result */ + i_fnum = PQfnumber(res, "i"); + t_fnum = PQfnumber(res, "t"); + b_fnum = PQfnumber(res, "b"); + + for (i = 0; i < PQntuples(res); i++) + { + char *iptr; + char *tptr; + char *bptr; + int blen; + int ival; + + /* Get the field values (we ignore possibility they are null!) */ + iptr = PQgetvalue(res, i, i_fnum); + tptr = PQgetvalue(res, i, t_fnum); + bptr = PQgetvalue(res, i, b_fnum); + + /* + * The binary representation of INT4 is in network byte order, which + * we'd better coerce to the local byte order. + */ + ival = ntohl(*((uint32_t *) iptr)); + + /* + * The binary representation of TEXT is, well, text, and since libpq + * was nice enough to append a zero byte to it, it'll work just fine + * as a C string. + * + * The binary representation of BYTEA is a bunch of bytes, which could + * include embedded nulls so we have to pay attention to field length. + */ + blen = PQgetlength(res, i, b_fnum); + + printf("tuple %d: got\n", i); + printf(" i = (%d bytes) %d\n", + PQgetlength(res, i, i_fnum), ival); + printf(" t = (%d bytes) '%s'\n", + PQgetlength(res, i, t_fnum), tptr); + printf(" b = (%d bytes) ", blen); + for (j = 0; j < blen; j++) + printf("\\%03o", bptr[j]); + printf("\n\n"); + } +} + +int +main(int argc, char **argv) +{ + const char *conninfo; + PGconn *conn; + PGresult *res; + const char *paramValues[1]; + int paramLengths[1]; + int paramFormats[1]; + uint32_t binaryIntVal; + + /* + * If the user supplies a parameter on the command line, use it as the + * conninfo string; otherwise default to setting dbname=postgres and using + * environment variables or defaults for all other connection parameters. + */ + if (argc > 1) + conninfo = argv[1]; + else + conninfo = "dbname = postgres"; + + /* Make a connection to the database */ + conn = PQconnectdb(conninfo); + + /* Check to see that the backend connection was successfully made */ + if (PQstatus(conn) != CONNECTION_OK) + { + fprintf(stderr, "%s", PQerrorMessage(conn)); + exit_nicely(conn); + } + + /* Set always-secure search path, so malicious users can't take control. */ + res = PQexec(conn, "SET search_path = testlibpq3"); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + PQclear(res); + + /* + * The point of this program is to illustrate use of PQexecParams() with + * out-of-line parameters, as well as binary transmission of data. + * + * This first example transmits the parameters as text, but receives the + * results in binary format. By using out-of-line parameters we can avoid + * a lot of tedious mucking about with quoting and escaping, even though + * the data is text. Notice how we don't have to do anything special with + * the quote mark in the parameter value. + */ + + /* Here is our out-of-line parameter value */ + paramValues[0] = "joe's place"; + + res = PQexecParams(conn, + "SELECT * FROM test1 WHERE t = $1", + 1, /* one param */ + NULL, /* let the backend deduce param type */ + paramValues, + NULL, /* don't need param lengths since text */ + NULL, /* default to all text params */ + 1); /* ask for binary results */ + + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + + show_binary_results(res); + + PQclear(res); + + /* + * In this second example we transmit an integer parameter in binary form, + * and again retrieve the results in binary form. + * + * Although we tell PQexecParams we are letting the backend deduce + * parameter type, we really force the decision by casting the parameter + * symbol in the query text. This is a good safety measure when sending + * binary parameters. + */ + + /* Convert integer value "2" to network byte order */ + binaryIntVal = htonl((uint32_t) 2); + + /* Set up parameter arrays for PQexecParams */ + paramValues[0] = (char *) &binaryIntVal; + paramLengths[0] = sizeof(binaryIntVal); + paramFormats[0] = 1; /* binary */ + + res = PQexecParams(conn, + "SELECT * FROM test1 WHERE i = $1::int4", + 1, /* one param */ + NULL, /* let the backend deduce param type */ + paramValues, + paramLengths, + paramFormats, + 1); /* ask for binary results */ + + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + + show_binary_results(res); + + PQclear(res); + + /* close the connection to the database and cleanup */ + PQfinish(conn); + + return 0; +} +]]> + + + + +
diff --git a/doc/src/sgml/lobj.sgml b/doc/src/sgml/lobj.sgml new file mode 100644 index 000000000000..012e44c73615 --- /dev/null +++ b/doc/src/sgml/lobj.sgml @@ -0,0 +1,994 @@ + + + + Large Objects + + large object + BLOBlarge object + + + PostgreSQL has a large object + facility, which provides stream-style access to user data that is stored + in a special large-object structure. Streaming access is useful + when working with data values that are too large to manipulate + conveniently as a whole. + + + + This chapter describes the implementation and the programming and + query language interfaces to PostgreSQL + large object data. We use the libpq C + library for the examples in this chapter, but most programming + interfaces native to PostgreSQL support + equivalent functionality. Other interfaces might use the large + object interface internally to provide generic support for large + values. This is not described here. + + + + Introduction + + + TOAST + versus large objects + + + + All large objects are stored in a single system table named pg_largeobject. + Each large object also has an entry in the system table pg_largeobject_metadata. + Large objects can be created, modified, and deleted using a read/write API + that is similar to standard operations on files. + + + + PostgreSQL also supports a storage system called + TOAST, + which automatically stores values + larger than a single database page into a secondary storage area per table. + This makes the large object facility partially obsolete. One + remaining advantage of the large object facility is that it allows values + up to 4 TB in size, whereas TOASTed fields can be at + most 1 GB. Also, reading and updating portions of a large object can be + done efficiently, while most operations on a TOASTed + field will read or write the whole value as a unit. + + + + + + Implementation Features + + + The large object implementation breaks large + objects up into chunks and stores the chunks in + rows in the database. A B-tree index guarantees fast + searches for the correct chunk number when doing random + access reads and writes. + + + + The chunks stored for a large object do not have to be contiguous. + For example, if an application opens a new large object, seeks to offset + 1000000, and writes a few bytes there, this does not result in allocation + of 1000000 bytes worth of storage; only of chunks covering the range of + data bytes actually written. A read operation will, however, read out + zeroes for any unallocated locations preceding the last existing chunk. + This corresponds to the common behavior of sparsely allocated + files in Unix file systems. + + + + As of PostgreSQL 9.0, large objects have an owner + and a set of access permissions, which can be managed using + and + . + SELECT privileges are required to read a large + object, and + UPDATE privileges are required to write or + truncate it. + Only the large object's owner (or a database superuser) can delete, + comment on, or change the owner of a large object. + To adjust this behavior for compatibility with prior releases, see the + run-time parameter. + + + + + Client Interfaces + + + This section describes the facilities that + PostgreSQL's libpq + client interface library provides for accessing large objects. + The PostgreSQL large object interface is + modeled after the Unix file-system interface, with + analogues of open, read, + write, + lseek, etc. + + + + All large object manipulation using these functions + must take place within an SQL transaction block, + since large object file descriptors are only valid for the duration of + a transaction. + + + + If an error occurs while executing any one of these functions, the + function will return an otherwise-impossible value, typically 0 or -1. + A message describing the error is stored in the connection object and + can be retrieved with . + + + + Client applications that use these functions should include the header file + libpq/libpq-fs.h and link with the + libpq library. + + + + Client applications cannot use these functions while a libpq connection is in pipeline mode. + + + + Creating a Large Object + + + lo_creat + The function + +Oid lo_creat(PGconn *conn, int mode); + + creates a new large object. + The return value is the OID that was assigned to the new large object, + or InvalidOid (zero) on failure. + + mode is unused and + ignored as of PostgreSQL 8.1; however, for + backward compatibility with earlier releases it is best to + set it to INV_READ, INV_WRITE, + or INV_READ | INV_WRITE. + (These symbolic constants are defined + in the header file libpq/libpq-fs.h.) + + + + An example: + +inv_oid = lo_creat(conn, INV_READ|INV_WRITE); + + + + + lo_create + The function + +Oid lo_create(PGconn *conn, Oid lobjId); + + also creates a new large object. The OID to be assigned can be + specified by lobjId; + if so, failure occurs if that OID is already in use for some large + object. If lobjId + is InvalidOid (zero) then lo_create assigns an unused + OID (this is the same behavior as lo_creat). + The return value is the OID that was assigned to the new large object, + or InvalidOid (zero) on failure. + + + + lo_create is new as of PostgreSQL + 8.1; if this function is run against an older server version, it will + fail and return InvalidOid. + + + + An example: + +inv_oid = lo_create(conn, desired_oid); + + + + + + Importing a Large Object + + + lo_import + To import an operating system file as a large object, call + +Oid lo_import(PGconn *conn, const char *filename); + + filename + specifies the operating system name of + the file to be imported as a large object. + The return value is the OID that was assigned to the new large object, + or InvalidOid (zero) on failure. + Note that the file is read by the client interface library, not by + the server; so it must exist in the client file system and be readable + by the client application. + + + + lo_import_with_oid + The function + +Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); + + also imports a new large object. The OID to be assigned can be + specified by lobjId; + if so, failure occurs if that OID is already in use for some large + object. If lobjId + is InvalidOid (zero) then lo_import_with_oid assigns an unused + OID (this is the same behavior as lo_import). + The return value is the OID that was assigned to the new large object, + or InvalidOid (zero) on failure. + + + + lo_import_with_oid is new as of PostgreSQL + 8.4 and uses lo_create internally which is new in 8.1; if this function is run against 8.0 or before, it will + fail and return InvalidOid. + + + + + Exporting a Large Object + + + lo_export + To export a large object + into an operating system file, call + +int lo_export(PGconn *conn, Oid lobjId, const char *filename); + + The lobjId argument specifies the OID of the large + object to export and the filename argument + specifies the operating system name of the file. Note that the file is + written by the client interface library, not by the server. Returns 1 + on success, -1 on failure. + + + + + Opening an Existing Large Object + + + lo_open + To open an existing large object for reading or writing, call + +int lo_open(PGconn *conn, Oid lobjId, int mode); + + The lobjId argument specifies the OID of the large + object to open. The mode bits control whether the + object is opened for reading (INV_READ), writing + (INV_WRITE), or both. + (These symbolic constants are defined + in the header file libpq/libpq-fs.h.) + lo_open returns a (non-negative) large object + descriptor for later use in lo_read, + lo_write, lo_lseek, + lo_lseek64, lo_tell, + lo_tell64, lo_truncate, + lo_truncate64, and lo_close. + The descriptor is only valid for + the duration of the current transaction. + On failure, -1 is returned. + + + + The server currently does not distinguish between modes + INV_WRITE and INV_READ | + INV_WRITE: you are allowed to read from the descriptor + in either case. However there is a significant difference between + these modes and INV_READ alone: with INV_READ + you cannot write on the descriptor, and the data read from it will + reflect the contents of the large object at the time of the transaction + snapshot that was active when lo_open was executed, + regardless of later writes by this or other transactions. Reading + from a descriptor opened with INV_WRITE returns + data that reflects all writes of other committed transactions as well + as writes of the current transaction. This is similar to the behavior + of REPEATABLE READ versus READ COMMITTED transaction + modes for ordinary SQL SELECT commands. + + + + lo_open will fail if SELECT + privilege is not available for the large object, or + if INV_WRITE is specified and UPDATE + privilege is not available. + (Prior to PostgreSQL 11, these privilege + checks were instead performed at the first actual read or write call + using the descriptor.) + These privilege checks can be disabled with the + run-time parameter. + + + + An example: + +inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE); + + + + + +Writing Data to a Large Object + + + lo_write + The function + +int lo_write(PGconn *conn, int fd, const char *buf, size_t len); + + writes len bytes from buf + (which must be of size len) to large object + descriptor fd. The fd argument must + have been returned by a previous lo_open. The + number of bytes actually written is returned (in the current + implementation, this will always equal len unless + there is an error). In the event of an error, the return value is -1. + + + + Although the len parameter is declared as + size_t, this function will reject length values larger than + INT_MAX. In practice, it's best to transfer data in chunks + of at most a few megabytes anyway. + + + + +Reading Data from a Large Object + + + lo_read + The function + +int lo_read(PGconn *conn, int fd, char *buf, size_t len); + + reads up to len bytes from large object descriptor + fd into buf (which must be + of size len). The fd + argument must have been returned by a previous + lo_open. The number of bytes actually read is + returned; this will be less than len if the end of + the large object is reached first. In the event of an error, the return + value is -1. + + + + Although the len parameter is declared as + size_t, this function will reject length values larger than + INT_MAX. In practice, it's best to transfer data in chunks + of at most a few megabytes anyway. + + + + +Seeking in a Large Object + + + lo_lseek + To change the current read or write location associated with a + large object descriptor, call + +int lo_lseek(PGconn *conn, int fd, int offset, int whence); + + This function moves the + current location pointer for the large object descriptor identified by + fd to the new location specified by + offset. The valid values for whence + are SEEK_SET (seek from object start), + SEEK_CUR (seek from current position), and + SEEK_END (seek from object end). The return value is + the new location pointer, or -1 on error. + + + + lo_lseek64 + When dealing with large objects that might exceed 2GB in size, + instead use + +pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); + + This function has the same behavior + as lo_lseek, but it can accept an + offset larger than 2GB and/or deliver a result larger + than 2GB. + Note that lo_lseek will fail if the new location + pointer would be greater than 2GB. + + + + lo_lseek64 is new as of PostgreSQL + 9.3. If this function is run against an older server version, it will + fail and return -1. + + + + + +Obtaining the Seek Position of a Large Object + + + lo_tell + To obtain the current read or write location of a large object descriptor, + call + +int lo_tell(PGconn *conn, int fd); + + If there is an error, the return value is -1. + + + + lo_tell64 + When dealing with large objects that might exceed 2GB in size, + instead use + +pg_int64 lo_tell64(PGconn *conn, int fd); + + This function has the same behavior + as lo_tell, but it can deliver a result larger + than 2GB. + Note that lo_tell will fail if the current + read/write location is greater than 2GB. + + + + lo_tell64 is new as of PostgreSQL + 9.3. If this function is run against an older server version, it will + fail and return -1. + + + + +Truncating a Large Object + + + lo_truncate + To truncate a large object to a given length, call + +int lo_truncate(PGcon *conn, int fd, size_t len); + + This function truncates the large object + descriptor fd to length len. The + fd argument must have been returned by a + previous lo_open. If len is + greater than the large object's current length, the large object + is extended to the specified length with null bytes ('\0'). + On success, lo_truncate returns + zero. On error, the return value is -1. + + + + The read/write location associated with the descriptor + fd is not changed. + + + + Although the len parameter is declared as + size_t, lo_truncate will reject length + values larger than INT_MAX. + + + + lo_truncate64 + When dealing with large objects that might exceed 2GB in size, + instead use + +int lo_truncate64(PGcon *conn, int fd, pg_int64 len); + + This function has the same + behavior as lo_truncate, but it can accept a + len value exceeding 2GB. + + + + lo_truncate is new as of PostgreSQL + 8.3; if this function is run against an older server version, it will + fail and return -1. + + + + lo_truncate64 is new as of PostgreSQL + 9.3; if this function is run against an older server version, it will + fail and return -1. + + + + +Closing a Large Object Descriptor + + + lo_close + A large object descriptor can be closed by calling + +int lo_close(PGconn *conn, int fd); + + where fd is a + large object descriptor returned by lo_open. + On success, lo_close returns zero. On + error, the return value is -1. + + + + Any large object descriptors that remain open at the end of a + transaction will be closed automatically. + + + + + Removing a Large Object + + + lo_unlink + To remove a large object from the database, call + +int lo_unlink(PGconn *conn, Oid lobjId); + + The lobjId argument specifies the OID of the + large object to remove. Returns 1 if successful, -1 on failure. + + + + + + +Server-Side Functions + + + Server-side functions tailored for manipulating large objects from SQL are + listed in . + + + + SQL-Oriented Large Object Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + + lo_from_bytea + + lo_from_bytea ( loid oid, data bytea ) + oid + + + Creates a large object and stores data in it. + If loid is zero then the system will choose a + free OID, otherwise that OID is used (with an error if some large + object already has that OID). On success, the large object's OID is + returned. + + + lo_from_bytea(0, '\xffffff00') + 24528 + + + + + + + lo_put + + lo_put ( loid oid, offset bigint, data bytea ) + void + + + Writes data starting at the given offset within + the large object; the large object is enlarged if necessary. + + + lo_put(24528, 1, '\xaa') + + + + + + + + lo_get + + lo_get ( loid oid , offset bigint, length integer ) + bytea + + + Extracts the large object's contents, or a substring thereof. + + + lo_get(24528, 0, 3) + \xffaaff + + + + +
+ + + There are additional server-side functions corresponding to each of the + client-side functions described earlier; indeed, for the most part the + client-side functions are simply interfaces to the equivalent server-side + functions. The ones just as convenient to call via SQL commands are + lo_creatlo_creat, + lo_create, + lo_unlinklo_unlink, + lo_importlo_import, and + lo_exportlo_export. + Here are examples of their use: + + +CREATE TABLE image ( + name text, + raster oid +); + +SELECT lo_creat(-1); -- returns OID of new, empty large object + +SELECT lo_create(43213); -- attempts to create large object with OID 43213 + +SELECT lo_unlink(173454); -- deletes large object with OID 173454 + +INSERT INTO image (name, raster) + VALUES ('beautiful image', lo_import('/etc/motd')); + +INSERT INTO image (name, raster) -- same as above, but specify OID to use + VALUES ('beautiful image', lo_import('/etc/motd', 68583)); + +SELECT lo_export(image.raster, '/tmp/motd') FROM image + WHERE name = 'beautiful image'; + + + + + The server-side lo_import and + lo_export functions behave considerably differently + from their client-side analogs. These two functions read and write files + in the server's file system, using the permissions of the database's + owning user. Therefore, by default their use is restricted to superusers. + In contrast, the client-side import and export functions read and write + files in the client's file system, using the permissions of the client + program. The client-side functions do not require any database + privileges, except the privilege to read or write the large object in + question. + + + + + It is possible to use of the + server-side lo_import + and lo_export functions to non-superusers, but + careful consideration of the security implications is required. A + malicious user of such privileges could easily parlay them into becoming + superuser (for example by rewriting server configuration files), or could + attack the rest of the server's file system without bothering to obtain + database superuser privileges as such. Access to roles having + such privilege must therefore be guarded just as carefully as access to + superuser roles. Nonetheless, if use of + server-side lo_import + or lo_export is needed for some routine task, it's + safer to use a role with such privileges than one with full superuser + privileges, as that helps to reduce the risk of damage from accidental + errors. + + + + + The functionality of lo_read and + lo_write is also available via server-side calls, + but the names of the server-side functions differ from the client side + interfaces in that they do not contain underscores. You must call + these functions as loread and lowrite. + + +
+ + +Example Program + + + is a sample program which shows how the large object + interface + in libpq can be used. Parts of the program are + commented out but are left in the source for the reader's + benefit. This program can also be found in + src/test/examples/testlo.c in the source distribution. + + + + Large Objects with <application>libpq</application> Example Program + +#include + +#include +#include +#include +#include + +#include "libpq-fe.h" +#include "libpq/libpq-fs.h" + +#define BUFSIZE 1024 + +/* + * importFile - + * import file "in_filename" into database as large object "lobjOid" + * + */ +static Oid +importFile(PGconn *conn, char *filename) +{ + Oid lobjId; + int lobj_fd; + char buf[BUFSIZE]; + int nbytes, + tmp; + int fd; + + /* + * open the file to be read in + */ + fd = open(filename, O_RDONLY, 0666); + if (fd < 0) + { /* error */ + fprintf(stderr, "cannot open unix file\"%s\"\n", filename); + } + + /* + * create the large object + */ + lobjId = lo_creat(conn, INV_READ | INV_WRITE); + if (lobjId == 0) + fprintf(stderr, "cannot create large object"); + + lobj_fd = lo_open(conn, lobjId, INV_WRITE); + + /* + * read in from the Unix file and write to the inversion file + */ + while ((nbytes = read(fd, buf, BUFSIZE)) > 0) + { + tmp = lo_write(conn, lobj_fd, buf, nbytes); + if (tmp < nbytes) + fprintf(stderr, "error while reading \"%s\"", filename); + } + + close(fd); + lo_close(conn, lobj_fd); + + return lobjId; +} + +static void +pickout(PGconn *conn, Oid lobjId, int start, int len) +{ + int lobj_fd; + char *buf; + int nbytes; + int nread; + + lobj_fd = lo_open(conn, lobjId, INV_READ); + if (lobj_fd < 0) + fprintf(stderr, "cannot open large object %u", lobjId); + + lo_lseek(conn, lobj_fd, start, SEEK_SET); + buf = malloc(len + 1); + + nread = 0; + while (len - nread > 0) + { + nbytes = lo_read(conn, lobj_fd, buf, len - nread); + buf[nbytes] = '\0'; + fprintf(stderr, ">>> %s", buf); + nread += nbytes; + if (nbytes <= 0) + break; /* no more data? */ + } + free(buf); + fprintf(stderr, "\n"); + lo_close(conn, lobj_fd); +} + +static void +overwrite(PGconn *conn, Oid lobjId, int start, int len) +{ + int lobj_fd; + char *buf; + int nbytes; + int nwritten; + int i; + + lobj_fd = lo_open(conn, lobjId, INV_WRITE); + if (lobj_fd < 0) + fprintf(stderr, "cannot open large object %u", lobjId); + + lo_lseek(conn, lobj_fd, start, SEEK_SET); + buf = malloc(len + 1); + + for (i = 0; i < len; i++) + buf[i] = 'X'; + buf[i] = '\0'; + + nwritten = 0; + while (len - nwritten > 0) + { + nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten); + nwritten += nbytes; + if (nbytes <= 0) + { + fprintf(stderr, "\nWRITE FAILED!\n"); + break; + } + } + free(buf); + fprintf(stderr, "\n"); + lo_close(conn, lobj_fd); +} + + +/* + * exportFile - + * export large object "lobjOid" to file "out_filename" + * + */ +static void +exportFile(PGconn *conn, Oid lobjId, char *filename) +{ + int lobj_fd; + char buf[BUFSIZE]; + int nbytes, + tmp; + int fd; + + /* + * open the large object + */ + lobj_fd = lo_open(conn, lobjId, INV_READ); + if (lobj_fd < 0) + fprintf(stderr, "cannot open large object %u", lobjId); + + /* + * open the file to be written to + */ + fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (fd < 0) + { /* error */ + fprintf(stderr, "cannot open unix file\"%s\"", + filename); + } + + /* + * read in from the inversion file and write to the Unix file + */ + while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) + { + tmp = write(fd, buf, nbytes); + if (tmp < nbytes) + { + fprintf(stderr, "error while writing \"%s\"", + filename); + } + } + + lo_close(conn, lobj_fd); + close(fd); +} + +static void +exit_nicely(PGconn *conn) +{ + PQfinish(conn); + exit(1); +} + +int +main(int argc, char **argv) +{ + char *in_filename, + *out_filename; + char *database; + Oid lobjOid; + PGconn *conn; + PGresult *res; + + if (argc != 4) + { + fprintf(stderr, "Usage: %s database_name in_filename out_filename\n", + argv[0]); + exit(1); + } + + database = argv[1]; + in_filename = argv[2]; + out_filename = argv[3]; + + /* + * set up the connection + */ + conn = PQsetdb(NULL, NULL, NULL, NULL, database); + + /* check to see that the backend connection was successfully made */ + if (PQstatus(conn) != CONNECTION_OK) + { + fprintf(stderr, "%s", PQerrorMessage(conn)); + exit_nicely(conn); + } + + /* Set always-secure search path, so malicious users can't take control. */ + res = PQexec(conn, + "SELECT pg_catalog.set_config('search_path', '', false)"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); + PQclear(res); + exit_nicely(conn); + } + PQclear(res); + + res = PQexec(conn, "begin"); + PQclear(res); + printf("importing file \"%s\" ...\n", in_filename); +/* lobjOid = importFile(conn, in_filename); */ + lobjOid = lo_import(conn, in_filename); + if (lobjOid == 0) + fprintf(stderr, "%s\n", PQerrorMessage(conn)); + else + { + printf("\tas large object %u.\n", lobjOid); + + printf("picking out bytes 1000-2000 of the large object\n"); + pickout(conn, lobjOid, 1000, 1000); + + printf("overwriting bytes 1000-2000 of the large object with X's\n"); + overwrite(conn, lobjOid, 1000, 1000); + + printf("exporting large object to file \"%s\" ...\n", out_filename); +/* exportFile(conn, lobjOid, out_filename); */ + if (lo_export(conn, lobjOid, out_filename) < 0) + fprintf(stderr, "%s\n", PQerrorMessage(conn)); + } + + res = PQexec(conn, "end"); + PQclear(res); + PQfinish(conn); + return 0; +} +]]> + + + + +
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml new file mode 100644 index 000000000000..88646bc859df --- /dev/null +++ b/doc/src/sgml/logical-replication.sgml @@ -0,0 +1,660 @@ + + + + Logical Replication + + + Logical replication is a method of replicating data objects and their + changes, based upon their replication identity (usually a primary key). We + use the term logical in contrast to physical replication, which uses exact + block addresses and byte-by-byte replication. PostgreSQL supports both + mechanisms concurrently, see . Logical + replication allows fine-grained control over both data replication and + security. + + + + Logical replication uses a publish + and subscribe model with one or + more subscribers subscribing to one or more + publications on a publisher + node. Subscribers pull data from the publications they subscribe to and may + subsequently re-publish data to allow cascading replication or more complex + configurations. + + + + Logical replication of a table typically starts with taking a snapshot + of the data on the publisher database and copying that to the subscriber. + Once that is done, the changes on the publisher are sent to the subscriber + as they occur in real-time. The subscriber applies the data in the same + order as the publisher so that transactional consistency is guaranteed for + publications within a single subscription. This method of data replication + is sometimes referred to as transactional replication. + + + + The typical use-cases for logical replication are: + + + + + Sending incremental changes in a single database or a subset of a + database to subscribers as they occur. + + + + + + Firing triggers for individual changes as they arrive on the + subscriber. + + + + + + Consolidating multiple databases into a single one (for example for + analytical purposes). + + + + + + Replicating between different major versions of PostgreSQL. + + + + + + Replicating between PostgreSQL instances on different platforms (for + example Linux to Windows) + + + + + + Giving access to replicated data to different groups of users. + + + + + + Sharing a subset of the database between multiple databases. + + + + + + + The subscriber database behaves in the same way as any other PostgreSQL + instance and can be used as a publisher for other databases by defining its + own publications. When the subscriber is treated as read-only by + application, there will be no conflicts from a single subscription. On the + other hand, if there are other writes done either by an application or by other + subscribers to the same set of tables, conflicts can arise. + + + + Publication + + + A publication can be defined on any physical + replication primary. The node where a publication is defined is referred to + as publisher. A publication is a set of changes + generated from a table or a group of tables, and might also be described as + a change set or replication set. Each publication exists in only one database. + + + + Publications are different from schemas and do not affect how the table is + accessed. Each table can be added to multiple publications if needed. + Publications may currently only contain tables. Objects must be added + explicitly, except when a publication is created for ALL + TABLES. + + + + Publications can choose to limit the changes they produce to + any combination of INSERT, UPDATE, + DELETE, and TRUNCATE, similar to how triggers are fired by + particular event types. By default, all operation types are replicated. + + + + A published table must have a replica identity configured in + order to be able to replicate UPDATE + and DELETE operations, so that appropriate rows to + update or delete can be identified on the subscriber side. By default, + this is the primary key, if there is one. Another unique index (with + certain additional requirements) can also be set to be the replica + identity. If the table does not have any suitable key, then it can be set + to replica identity full, which means the entire row becomes + the key. This, however, is very inefficient and should only be used as a + fallback if no other solution is possible. If a replica identity other + than full is set on the publisher side, a replica identity + comprising the same or fewer columns must also be set on the subscriber + side. See for details on + how to set the replica identity. If a table without a replica identity is + added to a publication that replicates UPDATE + or DELETE operations then + subsequent UPDATE or DELETE + operations will cause an error on the publisher. INSERT + operations can proceed regardless of any replica identity. + + + + Every publication can have multiple subscribers. + + + + A publication is created using the CREATE PUBLICATION + command and may later be altered or dropped using corresponding commands. + + + + The individual tables can be added and removed dynamically using + ALTER PUBLICATION. Both the ADD + TABLE and DROP TABLE operations are + transactional; so the table will start or stop replicating at the correct + snapshot once the transaction has committed. + + + + + Subscription + + + A subscription is the downstream side of logical + replication. The node where a subscription is defined is referred to as + the subscriber. A subscription defines the connection + to another database and set of publications (one or more) to which it wants + to subscribe. + + + + The subscriber database behaves in the same way as any other PostgreSQL + instance and can be used as a publisher for other databases by defining its + own publications. + + + + A subscriber node may have multiple subscriptions if desired. It is + possible to define multiple subscriptions between a single + publisher-subscriber pair, in which case care must be taken to ensure + that the subscribed publication objects don't overlap. + + + + Each subscription will receive changes via one replication slot (see + ). Additional replication + slots may be required for the initial data synchronization of + pre-existing table data and those will be dropped at the end of data + synchronization. + + + + A logical replication subscription can be a standby for synchronous + replication (see ). The standby + name is by default the subscription name. An alternative name can be + specified as application_name in the connection + information of the subscription. + + + + Subscriptions are dumped by pg_dump if the current user + is a superuser. Otherwise a warning is written and subscriptions are + skipped, because non-superusers cannot read all subscription information + from the pg_subscription catalog. + + + + The subscription is added using CREATE SUBSCRIPTION and + can be stopped/resumed at any time using the + ALTER SUBSCRIPTION command and removed using + DROP SUBSCRIPTION. + + + + When a subscription is dropped and recreated, the synchronization + information is lost. This means that the data has to be resynchronized + afterwards. + + + + The schema definitions are not replicated, and the published tables must + exist on the subscriber. Only regular tables may be + the target of replication. For example, you can't replicate to a view. + + + + The tables are matched between the publisher and the subscriber using the + fully qualified table name. Replication to differently-named tables on the + subscriber is not supported. + + + + Columns of a table are also matched by name. The order of columns in the + subscriber table does not need to match that of the publisher. The data + types of the columns do not need to match, as long as the text + representation of the data can be converted to the target type. For + example, you can replicate from a column of type integer to a + column of type bigint. The target table can also have + additional columns not provided by the published table. Any such columns + will be filled with the default value as specified in the definition of the + target table. + + + + Replication Slot Management + + + As mentioned earlier, each (active) subscription receives changes from a + replication slot on the remote (publishing) side. + + + Additional table synchronization slots are normally transient, created + internally to perform initial table synchronization and dropped + automatically when they are no longer needed. These table synchronization + slots have generated names: pg_%u_sync_%u_%llu + (parameters: Subscription oid, + Table relid, system identifier sysid) + + + Normally, the remote replication slot is created automatically when the + subscription is created using CREATE SUBSCRIPTION and it + is dropped automatically when the subscription is dropped using + DROP SUBSCRIPTION. In some situations, however, it can + be useful or necessary to manipulate the subscription and the underlying + replication slot separately. Here are some scenarios: + + + + + When creating a subscription, the replication slot already exists. In + that case, the subscription can be created using + the create_slot = false option to associate with the + existing slot. + + + + + + When creating a subscription, the remote host is not reachable or in an + unclear state. In that case, the subscription can be created using + the connect = false option. The remote host will then not + be contacted at all. This is what pg_dump + uses. The remote replication slot will then have to be created + manually before the subscription can be activated. + + + + + + When dropping a subscription, the replication slot should be kept. + This could be useful when the subscriber database is being moved to a + different host and will be activated from there. In that case, + disassociate the slot from the subscription using ALTER + SUBSCRIPTION before attempting to drop the subscription. + + + + + + When dropping a subscription, the remote host is not reachable. In + that case, disassociate the slot from the subscription + using ALTER SUBSCRIPTION before attempting to drop + the subscription. If the remote database instance no longer exists, no + further action is then necessary. If, however, the remote database + instance is just unreachable, the replication slot (and any still + remaining table synchronization slots) should then be + dropped manually; otherwise it/they would continue to reserve WAL and might + eventually cause the disk to fill up. Such cases should be carefully + investigated. + + + + + + + + + Conflicts + + + Logical replication behaves similarly to normal DML operations in that + the data will be updated even if it was changed locally on the subscriber + node. If incoming data violates any constraints the replication will + stop. This is referred to as a conflict. When + replicating UPDATE or DELETE + operations, missing data will not produce a conflict and such operations + will simply be skipped. + + + + A conflict will produce an error and will stop the replication; it must be + resolved manually by the user. Details about the conflict can be found in + the subscriber's server log. + + + + The resolution can be done either by changing data on the subscriber so + that it does not conflict with the incoming change or by skipping the + transaction that conflicts with the existing data. The transaction can be + skipped by calling the + pg_replication_origin_advance() function with + a node_name corresponding to the subscription name, + and a position. The current position of origins can be seen in the + + pg_replication_origin_status system view. + + + + + Restrictions + + + Logical replication currently has the following restrictions or missing + functionality. These might be addressed in future releases. + + + + + + The database schema and DDL commands are not replicated. The initial + schema can be copied by hand using pg_dump + --schema-only. Subsequent schema changes would need to be kept + in sync manually. (Note, however, that there is no need for the schemas + to be absolutely the same on both sides.) Logical replication is robust + when schema definitions change in a live database: When the schema is + changed on the publisher and replicated data starts arriving at the + subscriber but does not fit into the table schema, replication will error + until the schema is updated. In many cases, intermittent errors can be + avoided by applying additive schema changes to the subscriber first. + + + + + + Sequence data is not replicated. The data in serial or identity columns + backed by sequences will of course be replicated as part of the table, + but the sequence itself would still show the start value on the + subscriber. If the subscriber is used as a read-only database, then this + should typically not be a problem. If, however, some kind of switchover + or failover to the subscriber database is intended, then the sequences + would need to be updated to the latest values, either by copying the + current data from the publisher (perhaps + using pg_dump) or by determining a sufficiently high + value from the tables themselves. + + + + + + Replication of TRUNCATE commands is supported, but + some care must be taken when truncating groups of tables connected by + foreign keys. When replicating a truncate action, the subscriber will + truncate the same group of tables that was truncated on the publisher, + either explicitly specified or implicitly collected via + CASCADE, minus tables that are not part of the + subscription. This will work correctly if all affected tables are part + of the same subscription. But if some tables to be truncated on the + subscriber have foreign-key links to tables that are not part of the same + (or any) subscription, then the application of the truncate action on the + subscriber will fail. + + + + + + Large objects (see ) are not replicated. + There is no workaround for that, other than storing data in normal + tables. + + + + + + Replication is only supported by tables, including partitioned tables. + Attempts to replicate other types of relations, such as views, materialized + views, or foreign tables, will result in an error. + + + + + + When replicating between partitioned tables, the actual replication + originates, by default, from the leaf partitions on the publisher, so + partitions on the publisher must also exist on the subscriber as valid + target tables. (They could either be leaf partitions themselves, or they + could be further subpartitioned, or they could even be independent + tables.) Publications can also specify that changes are to be replicated + using the identity and schema of the partitioned root table instead of + that of the individual leaf partitions in which the changes actually + originate (see CREATE PUBLICATION). + + + + + + + Architecture + + + Logical replication starts by copying a snapshot of the data on the + publisher database. Once that is done, changes on the publisher are sent + to the subscriber as they occur in real time. The subscriber applies data + in the order in which commits were made on the publisher so that + transactional consistency is guaranteed for the publications within any + single subscription. + + + + Logical replication is built with an architecture similar to physical + streaming replication (see ). It is + implemented by walsender and apply + processes. The walsender process starts logical decoding (described + in ) of the WAL and loads the standard + logical decoding plugin (pgoutput). The plugin transforms the changes read + from WAL to the logical replication protocol + (see ) and filters the data + according to the publication specification. The data is then continuously + transferred using the streaming replication protocol to the apply worker, + which maps the data to local tables and applies the individual changes as + they are received, in correct transactional order. + + + + The apply process on the subscriber database always runs with + session_replication_role set + to replica, which produces the usual effects on triggers + and constraints. + + + + The logical replication apply process currently only fires row triggers, + not statement triggers. The initial table synchronization, however, is + implemented like a COPY command and thus fires both row + and statement triggers for INSERT. + + + + Initial Snapshot + + The initial data in existing subscribed tables are snapshotted and + copied in a parallel instance of a special kind of apply process. + This process will create its own replication slot and copy the existing + data. As soon as the copy is finished the table contents will become + visible to other backends. Once existing data is copied, the worker + enters synchronization mode, which ensures that the table is brought + up to a synchronized state with the main apply process by streaming + any changes that happened during the initial data copy using standard + logical replication. During this synchronization phase, the changes + are applied and committed in the same order as they happened on the + publisher. Once synchronization is done, control of the + replication of the table is given back to the main apply process where + replication continues as normal. + + + + + + Monitoring + + + Because logical replication is based on a similar architecture as + physical streaming replication, + the monitoring on a publication node is similar to monitoring of a + physical replication primary + (see ). + + + + The monitoring information about subscription is visible in + + pg_stat_subscription. + This view contains one row for every subscription worker. A subscription + can have zero or more active subscription workers depending on its state. + + + + Normally, there is a single apply process running for an enabled + subscription. A disabled subscription or a crashed subscription will have + zero rows in this view. If the initial data synchronization of any + table is in progress, there will be additional workers for the tables + being synchronized. + + + + + Security + + + A user able to modify the schema of subscriber-side tables can execute + arbitrary code as a superuser. Limit ownership + and TRIGGER privilege on such tables to roles that + superusers trust. Moreover, if untrusted users can create tables, use only + publications that list tables explicitly. That is to say, create a + subscription FOR ALL TABLES only when superusers trust + every user permitted to create a non-temp table on the publisher or the + subscriber. + + + + The role used for the replication connection must have + the REPLICATION attribute (or be a superuser). If the + role lacks SUPERUSER and BYPASSRLS, + publisher row security policies can execute. If the role does not trust + all table owners, include options=-crow_security=off in + the connection string; if a table owner then adds a row security policy, + that setting will cause replication to halt rather than execute the policy. + Access for the role must be configured in pg_hba.conf + and it must have the LOGIN attribute. + + + + In order to be able to copy the initial table data, the role used for the + replication connection must have the SELECT privilege on + a published table (or be a superuser). + + + + To create a publication, the user must have the CREATE + privilege in the database. + + + + To add tables to a publication, the user must have ownership rights on the + table. To create a publication that publishes all tables automatically, + the user must be a superuser. + + + + To create a subscription, the user must be a superuser. + + + + The subscription apply process will run in the local database with the + privileges of a superuser. + + + + Privileges are only checked once at the start of a replication connection. + They are not re-checked as each change record is read from the publisher, + nor are they re-checked for each change when applied. + + + + + Configuration Settings + + + Logical replication requires several configuration options to be set. + + + + On the publisher side, wal_level must be set to + logical, and max_replication_slots + must be set to at least the number of subscriptions expected to connect, + plus some reserve for table synchronization. And + max_wal_senders should be set to at least the same as + max_replication_slots plus the number of physical + replicas that are connected at the same time. + + + + max_replication_slots must also be set on the subscriber. + It should be set to at least the number of subscriptions that will be added + to the subscriber, plus some reserve for table synchronization. + max_logical_replication_workers must be set to at least + the number of subscriptions, again plus some reserve for the table + synchronization. Additionally the max_worker_processes + may need to be adjusted to accommodate for replication workers, at least + (max_logical_replication_workers + + 1). Note that some extensions and parallel queries + also take worker slots from max_worker_processes. + + + + + Quick Setup + + + First set the configuration options in postgresql.conf: + +wal_level = logical + + The other required settings have default values that are sufficient for a + basic setup. + + + + pg_hba.conf needs to be adjusted to allow replication + (the values here depend on your actual network configuration and user you + want to use for connecting): + +host all repuser 0.0.0.0/0 md5 + + + + + Then on the publisher database: + +CREATE PUBLICATION mypub FOR TABLE users, departments; + + + + + And on the subscriber database: + +CREATE SUBSCRIPTION mysub CONNECTION 'dbname=foo host=bar user=repuser' PUBLICATION mypub; + + + + + The above will start the replication process, which synchronizes the + initial table contents of the tables users and + departments and then starts replicating + incremental changes to those tables. + + + diff --git a/doc/src/sgml/logicaldecoding.sgml b/doc/src/sgml/logicaldecoding.sgml new file mode 100644 index 000000000000..5b8065901a4f --- /dev/null +++ b/doc/src/sgml/logicaldecoding.sgml @@ -0,0 +1,1327 @@ + + + Logical Decoding + + Logical Decoding + + + PostgreSQL provides infrastructure to stream the modifications performed + via SQL to external consumers. This functionality can be used for a + variety of purposes, including replication solutions and auditing. + + + + Changes are sent out in streams identified by logical replication slots. + + + + The format in which those changes are streamed is determined by the output + plugin used. An example plugin is provided in the PostgreSQL distribution. + Additional plugins can be + written to extend the choice of available formats without modifying any + core code. + Every output plugin has access to each individual new row produced + by INSERT and the new row version created + by UPDATE. Availability of old row versions for + UPDATE and DELETE depends on + the configured replica identity (see ). + + + + Changes can be consumed either using the streaming replication protocol + (see and + ), or by calling functions + via SQL (see ). It is also possible + to write additional methods of consuming the output of a replication slot + without modifying core code + (see ). + + + + Logical Decoding Examples + + + The following example demonstrates controlling logical decoding using the + SQL interface. + + + + Before you can use logical decoding, you must set + to logical and + to at least 1. Then, you + should connect to the target database (in the example + below, postgres) as a superuser. + + + +postgres=# -- Create a slot named 'regression_slot' using the output plugin 'test_decoding' +postgres=# SELECT * FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true); + slot_name | lsn +-----------------+----------- + regression_slot | 0/16B1970 +(1 row) + +postgres=# SELECT slot_name, plugin, slot_type, database, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots; + slot_name | plugin | slot_type | database | active | restart_lsn | confirmed_flush_lsn +-----------------+---------------+-----------+----------+--------+-------------+----------------- + regression_slot | test_decoding | logical | postgres | f | 0/16A4408 | 0/16A4440 +(1 row) + +postgres=# -- There are no changes to see yet +postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----+-----+------ +(0 rows) + +postgres=# CREATE TABLE data(id serial primary key, data text); +CREATE TABLE + +postgres=# -- DDL isn't replicated, so all you'll see is the transaction +postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-------+-------------- + 0/BA2DA58 | 10297 | BEGIN 10297 + 0/BA5A5A0 | 10297 | COMMIT 10297 +(2 rows) + +postgres=# -- Once changes are read, they're consumed and not emitted +postgres=# -- in a subsequent call: +postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----+-----+------ +(0 rows) + +postgres=# BEGIN; +postgres=*# INSERT INTO data(data) VALUES('1'); +postgres=*# INSERT INTO data(data) VALUES('2'); +postgres=*# COMMIT; + +postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-------+--------------------------------------------------------- + 0/BA5A688 | 10298 | BEGIN 10298 + 0/BA5A6F0 | 10298 | table public.data: INSERT: id[integer]:1 data[text]:'1' + 0/BA5A7F8 | 10298 | table public.data: INSERT: id[integer]:2 data[text]:'2' + 0/BA5A8A8 | 10298 | COMMIT 10298 +(4 rows) + +postgres=# INSERT INTO data(data) VALUES('3'); + +postgres=# -- You can also peek ahead in the change stream without consuming changes +postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-------+--------------------------------------------------------- + 0/BA5A8E0 | 10299 | BEGIN 10299 + 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3' + 0/BA5A990 | 10299 | COMMIT 10299 +(3 rows) + +postgres=# -- The next call to pg_logical_slot_peek_changes() returns the same changes again +postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-------+--------------------------------------------------------- + 0/BA5A8E0 | 10299 | BEGIN 10299 + 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3' + 0/BA5A990 | 10299 | COMMIT 10299 +(3 rows) + +postgres=# -- options can be passed to output plugin, to influence the formatting +postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-timestamp', 'on'); + lsn | xid | data +-----------+-------+--------------------------------------------------------- + 0/BA5A8E0 | 10299 | BEGIN 10299 + 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3' + 0/BA5A990 | 10299 | COMMIT 10299 (at 2017-05-10 12:07:21.272494-04) +(3 rows) + +postgres=# -- Remember to destroy a slot you no longer need to stop it consuming +postgres=# -- server resources: +postgres=# SELECT pg_drop_replication_slot('regression_slot'); + pg_drop_replication_slot +----------------------- + +(1 row) + + + + The following example shows how logical decoding is controlled over the + streaming replication protocol, using the + program included in the PostgreSQL + distribution. This requires that client authentication is set up to allow + replication connections + (see ) and + that max_wal_senders is set sufficiently high to allow + an additional connection. + + +$ pg_recvlogical -d postgres --slot=test --create-slot +$ pg_recvlogical -d postgres --slot=test --start -f - +ControlZ +$ psql -d postgres -c "INSERT INTO data(data) VALUES('4');" +$ fg +BEGIN 693 +table public.data: INSERT: id[integer]:4 data[text]:'4' +COMMIT 693 +ControlC +$ pg_recvlogical -d postgres --slot=test --drop-slot + + + + The following example shows SQL interface that can be used to decode prepared + transactions. Before you use two-phase commit commands, you must set + max_prepared_transactions to at least 1. You must also have + set the two-phase parameter as 'true' while creating the slot using + pg_create_logical_replication_slot + Note that we will stream the entire transaction after the commit if it + is not already decoded. + + +postgres=# BEGIN; +postgres=*# INSERT INTO data(data) VALUES('5'); +postgres=*# PREPARE TRANSACTION 'test_prepared1'; + +postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-----+--------------------------------------------------------- + 0/1689DC0 | 529 | BEGIN 529 + 0/1689DC0 | 529 | table public.data: INSERT: id[integer]:3 data[text]:'5' + 0/1689FC0 | 529 | PREPARE TRANSACTION 'test_prepared1', txid 529 +(3 rows) + +postgres=# COMMIT PREPARED 'test_prepared1'; +postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-----+-------------------------------------------- + 0/168A060 | 529 | COMMIT PREPARED 'test_prepared1', txid 529 +(4 row) + +postgres=#-- you can also rollback a prepared transaction +postgres=# BEGIN; +postgres=*# INSERT INTO data(data) VALUES('6'); +postgres=*# PREPARE TRANSACTION 'test_prepared2'; +postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-----+--------------------------------------------------------- + 0/168A180 | 530 | BEGIN 530 + 0/168A1E8 | 530 | table public.data: INSERT: id[integer]:4 data[text]:'6' + 0/168A430 | 530 | PREPARE TRANSACTION 'test_prepared2', txid 530 +(3 rows) + +postgres=# ROLLBACK PREPARED 'test_prepared2'; +postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL); + lsn | xid | data +-----------+-----+---------------------------------------------- + 0/168A4B8 | 530 | ROLLBACK PREPARED 'test_prepared2', txid 530 +(1 row) + + + + + Logical Decoding Concepts + + Logical Decoding + + + Logical Decoding + + + + Logical decoding is the process of extracting all persistent changes + to a database's tables into a coherent, easy to understand format which + can be interpreted without detailed knowledge of the database's internal + state. + + + + In PostgreSQL, logical decoding is implemented + by decoding the contents of the write-ahead + log, which describe changes on a storage level, into an + application-specific form such as a stream of tuples or SQL statements. + + + + + Replication Slots + + + replication slot + logical replication + + + + In the context of logical replication, a slot represents a stream of + changes that can be replayed to a client in the order they were made on + the origin server. Each slot streams a sequence of changes from a single + database. + + + + PostgreSQL also has streaming replication slots + (see ), but they are used somewhat + differently there. + + + + + A replication slot has an identifier that is unique across all databases + in a PostgreSQL cluster. Slots persist + independently of the connection using them and are crash-safe. + + + + A logical slot will emit each change just once in normal operation. + The current position of each slot is persisted only at checkpoint, so in + the case of a crash the slot may return to an earlier LSN, which will + then cause recent changes to be sent again when the server restarts. + Logical decoding clients are responsible for avoiding ill effects from + handling the same message more than once. Clients may wish to record + the last LSN they saw when decoding and skip over any repeated data or + (when using the replication protocol) request that decoding start from + that LSN rather than letting the server determine the start point. + The Replication Progress Tracking feature is designed for this purpose, + refer to replication origins. + + + + Multiple independent slots may exist for a single database. Each slot has + its own state, allowing different consumers to receive changes from + different points in the database change stream. For most applications, a + separate slot will be required for each consumer. + + + + A logical replication slot knows nothing about the state of the + receiver(s). It's even possible to have multiple different receivers using + the same slot at different times; they'll just get the changes following + on from when the last receiver stopped consuming them. Only one receiver + may consume changes from a slot at any given time. + + + + + Replication slots persist across crashes and know nothing about the state + of their consumer(s). They will prevent removal of required resources + even when there is no connection using them. This consumes storage + because neither required WAL nor required rows from the system catalogs + can be removed by VACUUM as long as they are required by a replication + slot. In extreme cases this could cause the database to shut down to prevent + transaction ID wraparound (see ). + So if a slot is no longer required it should be dropped. + + + + + + Output Plugins + + Output plugins transform the data from the write-ahead log's internal + representation into the format the consumer of a replication slot desires. + + + + + Exported Snapshots + + When a new replication slot is created using the streaming replication + interface (see ), a + snapshot is exported + (see ), which will show + exactly the state of the database after which all changes will be + included in the change stream. This can be used to create a new replica by + using SET TRANSACTION + SNAPSHOT to read the state of the database at the moment + the slot was created. This transaction can then be used to dump the + database's state at that point in time, which afterwards can be updated + using the slot's contents without losing any changes. + + + Creation of a snapshot is not always possible. In particular, it will + fail when connected to a hot standby. Applications that do not require + snapshot export may suppress it with the NOEXPORT_SNAPSHOT + option. + + + + + + Streaming Replication Protocol Interface + + + The commands + + + CREATE_REPLICATION_SLOT slot_name LOGICAL output_plugin + + + + DROP_REPLICATION_SLOT slot_name WAIT + + + + START_REPLICATION SLOT slot_name LOGICAL ... + + + are used to create, drop, and stream changes from a replication + slot, respectively. These commands are only available over a replication + connection; they cannot be used via SQL. + See for details on these commands. + + + + The command can be used to control + logical decoding over a streaming replication connection. (It uses + these commands internally.) + + + + + Logical Decoding <acronym>SQL</acronym> Interface + + + See for detailed documentation on + the SQL-level API for interacting with logical decoding. + + + + Synchronous replication (see ) is + only supported on replication slots used over the streaming replication interface. The + function interface and additional, non-core interfaces do not support + synchronous replication. + + + + + System Catalogs Related to Logical Decoding + + + The pg_replication_slots + view and the + + pg_stat_replication + view provide information about the current state of replication slots and + streaming replication connections respectively. These views apply to both physical and + logical replication. The + + pg_stat_replication_slots + view provides statistics information about the logical replication slots. + + + + + Logical Decoding Output Plugins + + An example output plugin can be found in the + + contrib/test_decoding + + subdirectory of the PostgreSQL source tree. + + + Initialization Function + + _PG_output_plugin_init + + + An output plugin is loaded by dynamically loading a shared library with + the output plugin's name as the library base name. The normal library + search path is used to locate the library. To provide the required output + plugin callbacks and to indicate that the library is actually an output + plugin it needs to provide a function named + _PG_output_plugin_init. This function is passed a + struct that needs to be filled with the callback function pointers for + individual actions. + +typedef struct OutputPluginCallbacks +{ + LogicalDecodeStartupCB startup_cb; + LogicalDecodeBeginCB begin_cb; + LogicalDecodeChangeCB change_cb; + LogicalDecodeTruncateCB truncate_cb; + LogicalDecodeCommitCB commit_cb; + LogicalDecodeMessageCB message_cb; + LogicalDecodeFilterByOriginCB filter_by_origin_cb; + LogicalDecodeShutdownCB shutdown_cb; + LogicalDecodeFilterPrepareCB filter_prepare_cb; + LogicalDecodeBeginPrepareCB begin_prepare_cb; + LogicalDecodePrepareCB prepare_cb; + LogicalDecodeCommitPreparedCB commit_prepared_cb; + LogicalDecodeRollbackPreparedCB rollback_prepared_cb; + LogicalDecodeStreamStartCB stream_start_cb; + LogicalDecodeStreamStopCB stream_stop_cb; + LogicalDecodeStreamAbortCB stream_abort_cb; + LogicalDecodeStreamPrepareCB stream_prepare_cb; + LogicalDecodeStreamCommitCB stream_commit_cb; + LogicalDecodeStreamChangeCB stream_change_cb; + LogicalDecodeStreamMessageCB stream_message_cb; + LogicalDecodeStreamTruncateCB stream_truncate_cb; +} OutputPluginCallbacks; + +typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb); + + The begin_cb, change_cb + and commit_cb callbacks are required, + while startup_cb, + filter_by_origin_cb, truncate_cb, + and shutdown_cb are optional. + If truncate_cb is not set but a + TRUNCATE is to be decoded, the action will be ignored. + + + + An output plugin may also define functions to support streaming of large, + in-progress transactions. The stream_start_cb, + stream_stop_cb, stream_abort_cb, + stream_commit_cb, stream_change_cb, + and stream_prepare_cb + are required, while stream_message_cb and + stream_truncate_cb are optional. + + + + An output plugin may also define functions to support two-phase commits, + which allows actions to be decoded on the PREPARE TRANSACTION. + The begin_prepare_cb, prepare_cb, + stream_prepare_cb, + commit_prepared_cb and rollback_prepared_cb + callbacks are required, while filter_prepare_cb is optional. + + + + + Capabilities + + + To decode, format and output changes, output plugins can use most of the + backend's normal infrastructure, including calling output functions. Read + only access to relations is permitted as long as only relations are + accessed that either have been created by initdb in + the pg_catalog schema, or have been marked as user + provided catalog tables using + +ALTER TABLE user_catalog_table SET (user_catalog_table = true); +CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true); + + Note that access to user catalog tables or regular system catalog tables + in the output plugins has to be done via the systable_* + scan APIs only. Access via the heap_* scan APIs will + error out. Additionally, any actions leading to transaction ID assignment + are prohibited. That, among others, includes writing to tables, performing + DDL changes, and calling pg_current_xact_id(). + + + + + Output Modes + + + Output plugin callbacks can pass data to the consumer in nearly arbitrary + formats. For some use cases, like viewing the changes via SQL, returning + data in a data type that can contain arbitrary data (e.g., bytea) is + cumbersome. If the output plugin only outputs textual data in the + server's encoding, it can declare that by + setting OutputPluginOptions.output_type + to OUTPUT_PLUGIN_TEXTUAL_OUTPUT instead + of OUTPUT_PLUGIN_BINARY_OUTPUT in + the startup + callback. In that case, all the data has to be in the server's encoding + so that a text datum can contain it. This is checked in assertion-enabled + builds. + + + + + Output Plugin Callbacks + + + An output plugin gets notified about changes that are happening via + various callbacks it needs to provide. + + + + Concurrent transactions are decoded in commit order, and only changes + belonging to a specific transaction are decoded between + the begin and commit + callbacks. Transactions that were rolled back explicitly or implicitly + never get + decoded. Successful savepoints are + folded into the transaction containing them in the order they were + executed within that transaction. A transaction that is prepared for + a two-phase commit using PREPARE TRANSACTION will + also be decoded if the output plugin callbacks needed for decoding + them are provided. It is possible that the current prepared transaction + which is being decoded is aborted concurrently via a + ROLLBACK PREPARED command. In that case, the logical + decoding of this transaction will be aborted too. All the changes of such + a transaction are skipped once the abort is detected and the + prepare_cb callback is invoked. Thus even in case of + a concurrent abort, enough information is provided to the output plugin + for it to properly deal with ROLLBACK PREPARED once + that is decoded. + + + + + Only transactions that have already safely been flushed to disk will be + decoded. That can lead to a COMMIT not immediately being decoded in a + directly following pg_logical_slot_get_changes() + when synchronous_commit is set + to off. + + + + + Startup Callback + + The optional startup_cb callback is called whenever + a replication slot is created or asked to stream changes, independent + of the number of changes that are ready to be put out. + +typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx, + OutputPluginOptions *options, + bool is_init); + + The is_init parameter will be true when the + replication slot is being created and false + otherwise. options points to a struct of options + that output plugins can set: + +typedef struct OutputPluginOptions +{ + OutputPluginOutputType output_type; + bool receive_rewrites; +} OutputPluginOptions; + + output_type has to either be set to + OUTPUT_PLUGIN_TEXTUAL_OUTPUT + or OUTPUT_PLUGIN_BINARY_OUTPUT. See also + . + If receive_rewrites is true, the output plugin will + also be called for changes made by heap rewrites during certain DDL + operations. These are of interest to plugins that handle DDL + replication, but they require special handling. + + + + The startup callback should validate the options present in + ctx->output_plugin_options. If the output plugin + needs to have a state, it can + use ctx->output_plugin_private to store it. + + + + + Shutdown Callback + + + The optional shutdown_cb callback is called + whenever a formerly active replication slot is not used anymore and can + be used to deallocate resources private to the output plugin. The slot + isn't necessarily being dropped, streaming is just being stopped. + +typedef void (*LogicalDecodeShutdownCB) (struct LogicalDecodingContext *ctx); + + + + + + Transaction Begin Callback + + + The required begin_cb callback is called whenever a + start of a committed transaction has been decoded. Aborted transactions + and their contents never get decoded. + +typedef void (*LogicalDecodeBeginCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + + The txn parameter contains meta information about + the transaction, like the time stamp at which it has been committed and + its XID. + + + + + Transaction End Callback + + + The required commit_cb callback is called whenever + a transaction commit has been + decoded. The change_cb callbacks for all modified + rows will have been called before this, if there have been any modified + rows. + +typedef void (*LogicalDecodeCommitCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + + + + + + Change Callback + + + The required change_cb callback is called for every + individual row modification inside a transaction, may it be + an INSERT, UPDATE, + or DELETE. Even if the original command modified + several rows at once the callback will be called individually for each + row. The change_cb callback may access system or + user catalog tables to aid in the process of outputting the row + modification details. In case of decoding a prepared (but yet + uncommitted) transaction or decoding of an uncommitted transaction, this + change callback might also error out due to simultaneous rollback of + this very same transaction. In that case, the logical decoding of this + aborted transaction is stopped gracefully. + +typedef void (*LogicalDecodeChangeCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); + + The ctx and txn parameters + have the same contents as for the begin_cb + and commit_cb callbacks, but additionally the + relation descriptor relation points to the + relation the row belongs to and a struct + change describing the row modification are passed + in. + + + + + Only changes in user defined tables that are not unlogged + (see ) and not temporary + (see ) can be extracted using + logical decoding. + + + + + + Truncate Callback + + + The truncate_cb callback is called for a + TRUNCATE command. + +typedef void (*LogicalDecodeTruncateCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); + + The parameters are analogous to the change_cb + callback. However, because TRUNCATE actions on + tables connected by foreign keys need to be executed together, this + callback receives an array of relations instead of just a single one. + See the description of the statement for + details. + + + + + Origin Filter Callback + + + The optional filter_by_origin_cb callback + is called to determine whether data that has been replayed + from origin_id is of interest to the + output plugin. + +typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx, + RepOriginId origin_id); + + The ctx parameter has the same contents + as for the other callbacks. No information but the origin is + available. To signal that changes originating on the passed in + node are irrelevant, return true, causing them to be filtered + away; false otherwise. The other callbacks will not be called + for transactions and changes that have been filtered away. + + + This is useful when implementing cascading or multidirectional + replication solutions. Filtering by the origin allows to + prevent replicating the same changes back and forth in such + setups. While transactions and changes also carry information + about the origin, filtering via this callback is noticeably + more efficient. + + + + + Generic Message Callback + + + The optional message_cb callback is called whenever + a logical decoding message has been decoded. + +typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, + Size message_size, + const char *message); + + The txn parameter contains meta information about + the transaction, like the time stamp at which it has been committed and + its XID. Note however that it can be NULL when the message is + non-transactional and the XID was not assigned yet in the transaction + which logged the message. The lsn has WAL + location of the message. The transactional says + if the message was sent as transactional or not. Similar to the change + callback, in case of decoding a prepared (but yet uncommitted) + transaction or decoding of an uncommitted transaction, this message + callback might also error out due to simultaneous rollback of + this very same transaction. In that case, the logical decoding of this + aborted transaction is stopped gracefully. + + The prefix is arbitrary null-terminated prefix + which can be used for identifying interesting messages for the current + plugin. And finally the message parameter holds + the actual message of message_size size. + + + Extra care should be taken to ensure that the prefix the output plugin + considers interesting is unique. Using name of the extension or the + output plugin itself is often a good choice. + + + + + Prepare Filter Callback + + + The optional filter_prepare_cb callback + is called to determine whether data that is part of the current + two-phase commit transaction should be considered for decoding + at this prepare stage or later as a regular one-phase transaction at + COMMIT PREPARED time. To signal that + decoding should be skipped, return true; + false otherwise. When the callback is not + defined, false is assumed (i.e. no filtering, all + transactions using two-phase commit are decoded in two phases as well). + +typedef bool (*LogicalDecodeFilterPrepareCB) (struct LogicalDecodingContext *ctx, + TransactionId xid, + const char *gid); + + The ctx parameter has the same contents as for + the other callbacks. The parameters xid + and gid provide two different ways to identify + the transaction. The later COMMIT PREPARED or + ROLLBACK PREPARED carries both identifiers, + providing an output plugin the choice of what to use. + + + The callback may be invoked multiple times per transaction to decode + and must provide the same static answer for a given pair of + xid and gid every time + it is called. + + + + + Transaction Begin Prepare Callback + + + The required begin_prepare_cb callback is called + whenever the start of a prepared transaction has been decoded. The + gid field, which is part of the + txn parameter, can be used in this callback to + check if the plugin has already received this PREPARE + in which case it can either error out or skip the remaining changes of + the transaction. + +typedef void (*LogicalDecodeBeginPrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + + + + + + Transaction Prepare Callback + + + The required prepare_cb callback is called whenever + a transaction which is prepared for two-phase commit has been + decoded. The change_cb callback for all modified + rows will have been called before this, if there have been any modified + rows. The gid field, which is part of the + txn parameter, can be used in this callback. + +typedef void (*LogicalDecodePrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); + + + + + + Transaction Commit Prepared Callback + + + The required commit_prepared_cb callback is called + whenever a transaction COMMIT PREPARED has been decoded. + The gid field, which is part of the + txn parameter, can be used in this callback. + +typedef void (*LogicalDecodeCommitPreparedCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + + + + + + Transaction Rollback Prepared Callback + + + The required rollback_prepared_cb callback is called + whenever a transaction ROLLBACK PREPARED has been + decoded. The gid field, which is part of the + txn parameter, can be used in this callback. The + parameters prepare_end_lsn and + prepare_time can be used to check if the plugin + has received this PREPARE TRANSACTION in which case + it can apply the rollback, otherwise, it can skip the rollback operation. The + gid alone is not sufficient because the downstream + node can have a prepared transaction with same identifier. + +typedef void (*LogicalDecodeRollbackPreparedCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time); + + + + + + Stream Start Callback + + The stream_start_cb callback is called when opening + a block of streamed changes from an in-progress transaction. + +typedef void (*LogicalDecodeStreamStartCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + + + + + + Stream Stop Callback + + The stream_stop_cb callback is called when closing + a block of streamed changes from an in-progress transaction. + +typedef void (*LogicalDecodeStreamStopCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); + + + + + + Stream Abort Callback + + The stream_abort_cb callback is called to abort + a previously streamed transaction. + +typedef void (*LogicalDecodeStreamAbortCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr abort_lsn); + + + + + + Stream Prepare Callback + + The stream_prepare_cb callback is called to prepare + a previously streamed transaction as part of a two-phase commit. + +typedef void (*LogicalDecodeStreamPrepareCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); + + + + + + Stream Commit Callback + + The stream_commit_cb callback is called to commit + a previously streamed transaction. + +typedef void (*LogicalDecodeStreamCommitCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); + + + + + + Stream Change Callback + + The stream_change_cb callback is called when sending + a change in a block of streamed changes (demarcated by + stream_start_cb and stream_stop_cb calls). + The actual changes are not displayed as the transaction can abort at a later + point in time and we don't decode changes for aborted transactions. + +typedef void (*LogicalDecodeStreamChangeCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + Relation relation, + ReorderBufferChange *change); + + + + + + Stream Message Callback + + The stream_message_cb callback is called when sending + a generic message in a block of streamed changes (demarcated by + stream_start_cb and stream_stop_cb calls). + The message contents for transactional messages are not displayed as the transaction + can abort at a later point in time and we don't decode changes for aborted + transactions. + +typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr message_lsn, + bool transactional, + const char *prefix, + Size message_size, + const char *message); + + + + + + Stream Truncate Callback + + The stream_truncate_cb callback is called for a + TRUNCATE command in a block of streamed changes + (demarcated by stream_start_cb and + stream_stop_cb calls). + +typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + int nrelations, + Relation relations[], + ReorderBufferChange *change); + + The parameters are analogous to the stream_change_cb + callback. However, because TRUNCATE actions on + tables connected by foreign keys need to be executed together, this + callback receives an array of relations instead of just a single one. + See the description of the statement for + details. + + + + + + + Functions for Producing Output + + + To actually produce output, output plugins can write data to + the StringInfo output buffer + in ctx->out when inside + the begin_cb, commit_cb, + or change_cb callbacks. Before writing to the output + buffer, OutputPluginPrepareWrite(ctx, last_write) has + to be called, and after finishing writing to the + buffer, OutputPluginWrite(ctx, last_write) has to be + called to perform the write. The last_write + indicates whether a particular write was the callback's last write. + + + + The following example shows how to output data to the consumer of an + output plugin: + +OutputPluginPrepareWrite(ctx, true); +appendStringInfo(ctx->out, "BEGIN %u", txn->xid); +OutputPluginWrite(ctx, true); + + + + + + + Logical Decoding Output Writers + + + It is possible to add more output methods for logical decoding. + For details, see + src/backend/replication/logical/logicalfuncs.c. + Essentially, three functions need to be provided: one to read WAL, one to + prepare writing output, and one to write the output + (see ). + + + + + Synchronous Replication Support for Logical Decoding + + Overview + + + Logical decoding can be used to build + synchronous + replication solutions with the same user interface as synchronous + replication for streaming + replication. To do this, the streaming replication interface + (see ) must be used to stream out + data. Clients have to send Standby status update (F) + (see ) messages, just like streaming + replication clients do. + + + + + A synchronous replica receiving changes via logical decoding will work in + the scope of a single database. Since, in contrast to + that, synchronous_standby_names currently is + server wide, this means this technique will not work properly if more + than one database is actively used. + + + + + + Caveats + + + In synchronous replication setup, a deadlock can happen, if the transaction + has locked [user] catalog tables exclusively. See + for information on user + catalog tables. This is because logical decoding of transactions can lock + catalog tables to access them. To avoid this users must refrain from taking + an exclusive lock on [user] catalog tables. This can happen in the following + ways: + + + + + Issuing an explicit LOCK on pg_class + in a transaction. + + + + + + Perform CLUSTER on pg_class in + a transaction. + + + + + + PREPARE TRANSACTION after LOCK command + on pg_class and allow logical decoding of two-phase + transactions. + + + + + + PREPARE TRANSACTION after CLUSTER + command on pg_trigger and allow logical decoding of + two-phase transactions. This will lead to deadlock only when published table + have a trigger. + + + + + + Executing TRUNCATE on [user] catalog table in a + transaction. + + + + + Note that these commands that can cause deadlock apply to not only explicitly + indicated system catalog tables above but also to any other [user] catalog + table. + + + + + + Streaming of Large Transactions for Logical Decoding + + + The basic output plugin callbacks (e.g., begin_cb, + change_cb, commit_cb and + message_cb) are only invoked when the transaction + actually commits. The changes are still decoded from the transaction + log, but are only passed to the output plugin at commit (and discarded + if the transaction aborts). + + + + This means that while the decoding happens incrementally, and may spill + to disk to keep memory usage under control, all the decoded changes have + to be transmitted when the transaction finally commits (or more precisely, + when the commit is decoded from the transaction log). Depending on the + size of the transaction and network bandwidth, the transfer time may + significantly increase the apply lag. + + + + To reduce the apply lag caused by large transactions, an output plugin + may provide additional callback to support incremental streaming of + in-progress transactions. There are multiple required streaming callbacks + (stream_start_cb, stream_stop_cb, + stream_abort_cb, stream_commit_cb + and stream_change_cb) and two optional callbacks + (stream_message_cb and stream_truncate_cb). + + + + When streaming an in-progress transaction, the changes (and messages) are + streamed in blocks demarcated by stream_start_cb + and stream_stop_cb callbacks. Once all the decoded + changes are transmitted, the transaction can be committed using the + the stream_commit_cb callback + (or possibly aborted using the stream_abort_cb callback). + If two-phase commits are supported, the transaction can be prepared using the + stream_prepare_cb callback, + COMMIT PREPARED using the + commit_prepared_cb callback or aborted using the + rollback_prepared_cb. + + + + One example sequence of streaming callback calls for one transaction may + look like this: + +stream_start_cb(...); <-- start of first block of changes + stream_change_cb(...); + stream_change_cb(...); + stream_message_cb(...); + stream_change_cb(...); + ... + stream_change_cb(...); +stream_stop_cb(...); <-- end of first block of changes + +stream_start_cb(...); <-- start of second block of changes + stream_change_cb(...); + stream_change_cb(...); + stream_change_cb(...); + ... + stream_message_cb(...); + stream_change_cb(...); +stream_stop_cb(...); <-- end of second block of changes + +stream_commit_cb(...); <-- commit of the streamed transaction + + + + + The actual sequence of callback calls may be more complicated, of course. + There may be blocks for multiple streamed transactions, some of the + transactions may get aborted, etc. + + + + Similar to spill-to-disk behavior, streaming is triggered when the total + amount of changes decoded from the WAL (for all in-progress transactions) + exceeds the limit defined by logical_decoding_work_mem setting. + At that point, the largest toplevel transaction (measured by the amount of memory + currently used for decoded changes) is selected and streamed. However, in + some cases we still have to spill to disk even if streaming is enabled + because we exceed the memory threshold but still have not decoded the + complete tuple e.g., only decoded toast table insert but not the main table + insert. + + + + Even when streaming large transactions, the changes are still applied in + commit order, preserving the same guarantees as the non-streaming mode. + + + + + + Two-phase commit support for Logical Decoding + + + With the basic output plugin callbacks (eg., begin_cb, + change_cb, commit_cb and + message_cb) two-phase commit commands like + PREPARE TRANSACTION, COMMIT PREPARED + and ROLLBACK PREPARED are not decoded. While the + PREPARE TRANSACTION is ignored, + COMMIT PREPARED is decoded as a COMMIT + and ROLLBACK PREPARED is decoded as a + ROLLBACK. + + + + To support the streaming of two-phase commands, an output plugin needs to + provide additional callbacks. There are multiple two-phase commit callbacks + that are required, (begin_prepare_cb, + prepare_cb, commit_prepared_cb, + rollback_prepared_cb and + stream_prepare_cb) and an optional callback + (filter_prepare_cb). + + + + If the output plugin callbacks for decoding two-phase commit commands are + provided, then on PREPARE TRANSACTION, the changes of + that transaction are decoded, passed to the output plugin, and the + prepare_cb callback is invoked. This differs from the + basic decoding setup where changes are only passed to the output plugin + when a transaction is committed. The start of a prepared transaction is + indicated by the begin_prepare_cb callback. + + + + When a prepared transaction is rolled back using the + ROLLBACK PREPARED, then the + rollback_prepared_cb callback is invoked and when the + prepared transaction is committed using COMMIT PREPARED, + then the commit_prepared_cb callback is invoked. + + + + Optionally the output plugin can define filtering rules via + filter_prepare_cb to decode only specific transaction + in two phases. This can be achieved by pattern matching on the + gid or via lookups using the + xid. + + + + The users that want to decode prepared transactions need to be careful about + below mentioned points: + + + + + If the prepared transaction has locked [user] catalog tables exclusively + then decoding prepare can block till the main transaction is committed. + + + + + + The logical replication solution that builds distributed two phase commit + using this feature can deadlock if the prepared transaction has locked + [user] catalog tables exclusively. To avoid this users must refrain from + having locks on catalog tables (e.g. explicit LOCK command) + in such transactions. + See for the details. + + + + + + + diff --git a/doc/src/sgml/ltree.sgml b/doc/src/sgml/ltree.sgml new file mode 100644 index 000000000000..436be76bfaa4 --- /dev/null +++ b/doc/src/sgml/ltree.sgml @@ -0,0 +1,861 @@ + + + + ltree + + + ltree + + + + This module implements a data type ltree for representing + labels of data stored in a hierarchical tree-like structure. + Extensive facilities for searching through label trees are provided. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Definitions + + + A label is a sequence of alphanumeric characters + and underscores (for example, in C locale the characters + A-Za-z0-9_ are allowed). + Labels must be less than 256 characters long. + + + + Examples: 42, Personal_Services + + + + A label path is a sequence of zero or more + labels separated by dots, for example L1.L2.L3, representing + a path from the root of a hierarchical tree to a particular node. The + length of a label path cannot exceed 65535 labels. + + + + Example: Top.Countries.Europe.Russia + + + + The ltree module provides several data types: + + + + + + ltree stores a label path. + + + + + + lquery represents a regular-expression-like pattern + for matching ltree values. A simple word matches that + label within a path. A star symbol (*) matches zero + or more labels. These can be joined with dots to form a pattern that + must match the whole label path. For example: + +foo Match the exact label path foo +*.foo.* Match any label path containing the label foo +*.foo Match any label path whose last label is foo + + + + + Both star symbols and simple words can be quantified to restrict how many + labels they can match: + +*{n} Match exactly n labels +*{n,} Match at least n labels +*{n,m} Match at least n but not more than m labels +*{,m} Match at most m labels — same as *{0,m} +foo{n,m} Match at least n but not more than m occurrences of foo +foo{,} Match any number of occurrences of foo, including zero + + In the absence of any explicit quantifier, the default for a star symbol + is to match any number of labels (that is, {,}) while + the default for a non-star item is to match exactly once (that + is, {1}). + + + + There are several modifiers that can be put at the end of a non-star + lquery item to make it match more than just the exact match: + +@ Match case-insensitively, for example a@ matches A +* Match any label with this prefix, for example foo* matches foobar +% Match initial underscore-separated words + + The behavior of % is a bit complicated. It tries to match + words rather than the entire label. For example + foo_bar% matches foo_bar_baz but not + foo_barbaz. If combined with *, prefix + matching applies to each word separately, for example + foo_bar%* matches foo1_bar2_baz but + not foo1_br2_baz. + + + + Also, you can write several possibly-modified non-star items separated with + | (OR) to match any of those items, and you can put + ! (NOT) at the start of a non-star group to match any + label that doesn't match any of the alternatives. A quantifier, if any, + goes at the end of the group; it means some number of matches for the + group as a whole (that is, some number of labels matching or not matching + any of the alternatives). + + + + Here's an annotated example of lquery: + +Top.*{0,2}.sport*@.!football|tennis{1,}.Russ*|Spain +a. b. c. d. e. + + This query will match any label path that: + + + + + begins with the label Top + + + + + and next has zero to two labels before + + + + + a label beginning with the case-insensitive prefix sport + + + + + then has one or more labels, none of which + match football nor tennis + + + + + and then ends with a label beginning with Russ or + exactly matching Spain. + + + + + + + ltxtquery represents a full-text-search-like + pattern for matching ltree values. An + ltxtquery value contains words, possibly with the + modifiers @, *, % at the end; + the modifiers have the same meanings as in lquery. + Words can be combined with & (AND), + | (OR), ! (NOT), and parentheses. + The key difference from + lquery is that ltxtquery matches words without + regard to their position in the label path. + + + + Here's an example ltxtquery: + +Europe & Russia*@ & !Transportation + + This will match paths that contain the label Europe and + any label beginning with Russia (case-insensitive), + but not paths containing the label Transportation. + The location of these words within the path is not important. + Also, when % is used, the word can be matched to any + underscore-separated word within a label, regardless of position. + + + + + + + Note: ltxtquery allows whitespace between symbols, but + ltree and lquery do not. + + + + + Operators and Functions + + + Type ltree has the usual comparison operators + =, <>, + <, >, <=, >=. + Comparison sorts in the order of a tree traversal, with the children + of a node sorted by label text. In addition, the specialized + operators shown in are available. + + + + <type>ltree</type> Operators + + + + + Operator + + + Description + + + + + + + + ltree @> ltree + boolean + + + Is left argument an ancestor of right (or equal)? + + + + + + ltree <@ ltree + boolean + + + Is left argument a descendant of right (or equal)? + + + + + + ltree ~ lquery + boolean + + + lquery ~ ltree + boolean + + + Does ltree match lquery? + + + + + + ltree ? lquery[] + boolean + + + lquery[] ? ltree + boolean + + + Does ltree match any lquery in array? + + + + + + ltree @ ltxtquery + boolean + + + ltxtquery @ ltree + boolean + + + Does ltree match ltxtquery? + + + + + + ltree || ltree + ltree + + + Concatenates ltree paths. + + + + + + ltree || text + ltree + + + text || ltree + ltree + + + Converts text to ltree and concatenates. + + + + + + ltree[] @> ltree + boolean + + + ltree <@ ltree[] + boolean + + + Does array contain an ancestor of ltree? + + + + + + ltree[] <@ ltree + boolean + + + ltree @> ltree[] + boolean + + + Does array contain a descendant of ltree? + + + + + + ltree[] ~ lquery + boolean + + + lquery ~ ltree[] + boolean + + + Does array contain any path matching lquery? + + + + + + ltree[] ? lquery[] + boolean + + + lquery[] ? ltree[] + boolean + + + Does ltree array contain any path matching + any lquery? + + + + + + ltree[] @ ltxtquery + boolean + + + ltxtquery @ ltree[] + boolean + + + Does array contain any path matching ltxtquery? + + + + + + ltree[] ?@> ltree + ltree + + + Returns first array entry that is an ancestor of ltree, + or NULL if none. + + + + + + ltree[] ?<@ ltree + ltree + + + Returns first array entry that is a descendant of ltree, + or NULL if none. + + + + + + ltree[] ?~ lquery + ltree + + + Returns first array entry that matches lquery, + or NULL if none. + + + + + + ltree[] ?@ ltxtquery + ltree + + + Returns first array entry that matches ltxtquery, + or NULL if none. + + + + +
+ + + The operators <@, @>, + @ and ~ have analogues + ^<@, ^@>, ^@, + ^~, which are the same except they do not use + indexes. These are useful only for testing purposes. + + + + The available functions are shown in . + + + + <type>ltree</type> Functions + + + + + Function + + + Description + + + Example(s) + + + + + + + + subltree + subltree ( ltree, start integer, end integer ) + ltree + + + Returns subpath of ltree from + position start to + position end-1 (counting from 0). + + + subltree('Top.Child1.Child2', 1, 2) + Child1 + + + + + + subpath + subpath ( ltree, offset integer, len integer ) + ltree + + + Returns subpath of ltree starting at + position offset, with + length len. If offset + is negative, subpath starts that far from the end of the path. + If len is negative, leaves that many labels off + the end of the path. + + + subpath('Top.Child1.Child2', 0, 2) + Top.Child1 + + + + + + subpath ( ltree, offset integer ) + ltree + + + Returns subpath of ltree starting at + position offset, extending to end of path. + If offset is negative, subpath starts that far + from the end of the path. + + + subpath('Top.Child1.Child2', 1) + Child1.Child2 + + + + + + nlevel + nlevel ( ltree ) + integer + + + Returns number of labels in path. + + + nlevel('Top.Child1.Child2') + 3 + + + + + + index + index ( a ltree, b ltree ) + integer + + + Returns position of first occurrence of b in + a, or -1 if not found. + + + index('0.1.2.3.5.4.5.6.8.5.6.8', '5.6') + 6 + + + + + + index ( a ltree, b ltree, offset integer ) + integer + + + Returns position of first occurrence of b + in a, or -1 if not found. The search starts at + position offset; + negative offset means + start -offset labels from the end of the path. + + + index('0.1.2.3.5.4.5.6.8.5.6.8', '5.6', -4) + 9 + + + + + + text2ltree + text2ltree ( text ) + ltree + + + Casts text to ltree. + + + + + + ltree2text + ltree2text ( ltree ) + text + + + Casts ltree to text. + + + + + + lca + lca ( ltree , ltree , ... ) + ltree + + + Computes longest common ancestor of paths + (up to 8 arguments are supported). + + + lca('1.2.3', '1.2.3.4.5.6') + 1.2 + + + + + + lca ( ltree[] ) + ltree + + + Computes longest common ancestor of paths in array. + + + lca(array['1.2.3'::ltree,'1.2.3.4']) + 1.2 + + + + +
+
+ + + Indexes + + ltree supports several types of indexes that can speed + up the indicated operators: + + + + + + B-tree index over ltree: + <, <=, =, + >=, > + + + + + GiST index over ltree (gist_ltree_ops + opclass): + <, <=, =, + >=, >, + @>, <@, + @, ~, ? + + + gist_ltree_ops GiST opclass approximates a set of + path labels as a bitmap signature. Its optional integer parameter + siglen determines the + signature length in bytes. The default signature length is 8 bytes. + Valid values of signature length are between 1 and 2024 bytes. Longer + signatures lead to a more precise search (scanning a smaller fraction of the index and + fewer heap pages), at the cost of a larger index. + + + Example of creating such an index with the default signature length of 8 bytes: + + +CREATE INDEX path_gist_idx ON test USING GIST (path); + + + Example of creating such an index with a signature length of 100 bytes: + + +CREATE INDEX path_gist_idx ON test USING GIST (path gist_ltree_ops(siglen=100)); + + + + + GiST index over ltree[] (gist__ltree_ops + opclass): + ltree[] <@ ltree, ltree @> ltree[], + @, ~, ? + + + gist__ltree_ops GiST opclass works similarly to + gist_ltree_ops and also takes signature length as + a parameter. The default value of siglen in + gist__ltree_ops is 28 bytes. + + + Example of creating such an index with the default signature length of 28 bytes: + + +CREATE INDEX path_gist_idx ON test USING GIST (array_path); + + + Example of creating such an index with a signature length of 100 bytes: + + +CREATE INDEX path_gist_idx ON test USING GIST (array_path gist__ltree_ops(siglen=100)); + + + Note: This index type is lossy. + + + + + + + Example + + + This example uses the following data (also available in file + contrib/ltree/ltreetest.sql in the source distribution): + + + +CREATE TABLE test (path ltree); +INSERT INTO test VALUES ('Top'); +INSERT INTO test VALUES ('Top.Science'); +INSERT INTO test VALUES ('Top.Science.Astronomy'); +INSERT INTO test VALUES ('Top.Science.Astronomy.Astrophysics'); +INSERT INTO test VALUES ('Top.Science.Astronomy.Cosmology'); +INSERT INTO test VALUES ('Top.Hobbies'); +INSERT INTO test VALUES ('Top.Hobbies.Amateurs_Astronomy'); +INSERT INTO test VALUES ('Top.Collections'); +INSERT INTO test VALUES ('Top.Collections.Pictures'); +INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy'); +INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Stars'); +INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Galaxies'); +INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Astronauts'); +CREATE INDEX path_gist_idx ON test USING GIST (path); +CREATE INDEX path_idx ON test USING BTREE (path); + + + + Now, we have a table test populated with data describing + the hierarchy shown below: + + + + Top + / | \ + Science Hobbies Collections + / | \ + Astronomy Amateurs_Astronomy Pictures + / \ | +Astrophysics Cosmology Astronomy + / | \ + Galaxies Stars Astronauts + + + + We can do inheritance: + +ltreetest=> SELECT path FROM test WHERE path <@ 'Top.Science'; + path +------------------------------------ + Top.Science + Top.Science.Astronomy + Top.Science.Astronomy.Astrophysics + Top.Science.Astronomy.Cosmology +(4 rows) + + + + + Here are some examples of path matching: + +ltreetest=> SELECT path FROM test WHERE path ~ '*.Astronomy.*'; + path +----------------------------------------------- + Top.Science.Astronomy + Top.Science.Astronomy.Astrophysics + Top.Science.Astronomy.Cosmology + Top.Collections.Pictures.Astronomy + Top.Collections.Pictures.Astronomy.Stars + Top.Collections.Pictures.Astronomy.Galaxies + Top.Collections.Pictures.Astronomy.Astronauts +(7 rows) + +ltreetest=> SELECT path FROM test WHERE path ~ '*.!pictures@.Astronomy.*'; + path +------------------------------------ + Top.Science.Astronomy + Top.Science.Astronomy.Astrophysics + Top.Science.Astronomy.Cosmology +(3 rows) + + + + + Here are some examples of full text search: + +ltreetest=> SELECT path FROM test WHERE path @ 'Astro*% & !pictures@'; + path +------------------------------------ + Top.Science.Astronomy + Top.Science.Astronomy.Astrophysics + Top.Science.Astronomy.Cosmology + Top.Hobbies.Amateurs_Astronomy +(4 rows) + +ltreetest=> SELECT path FROM test WHERE path @ 'Astro* & !pictures@'; + path +------------------------------------ + Top.Science.Astronomy + Top.Science.Astronomy.Astrophysics + Top.Science.Astronomy.Cosmology +(3 rows) + + + + + Path construction using functions: + +ltreetest=> SELECT subpath(path,0,2)||'Space'||subpath(path,2) FROM test WHERE path <@ 'Top.Science.Astronomy'; + ?column? +------------------------------------------ + Top.Science.Space.Astronomy + Top.Science.Space.Astronomy.Astrophysics + Top.Science.Space.Astronomy.Cosmology +(3 rows) + + + + + We could simplify this by creating an SQL function that inserts a label + at a specified position in a path: + +CREATE FUNCTION ins_label(ltree, int, text) RETURNS ltree + AS 'select subpath($1,0,$2) || $3 || subpath($1,$2);' + LANGUAGE SQL IMMUTABLE; + +ltreetest=> SELECT ins_label(path,2,'Space') FROM test WHERE path <@ 'Top.Science.Astronomy'; + ins_label +------------------------------------------ + Top.Science.Space.Astronomy + Top.Science.Space.Astronomy.Astrophysics + Top.Science.Space.Astronomy.Cosmology +(3 rows) + + + + + + Transforms + + + Additional extensions are available that implement transforms for + the ltree type for PL/Python. The extensions are + called ltree_plpythonu, ltree_plpython2u, + and ltree_plpython3u + (see for the PL/Python naming + convention). If you install these transforms and specify them when + creating a function, ltree values are mapped to Python lists. + (The reverse is currently not supported, however.) + + + + + It is strongly recommended that the transform extensions be installed in + the same schema as ltree. Otherwise there are + installation-time security hazards if a transform extension's schema + contains objects defined by a hostile user. + + + + + + Authors + + + All work was done by Teodor Sigaev (teodor@stack.net) and + Oleg Bartunov (oleg@sai.msu.su). See + for + additional information. Authors would like to thank Eugeny Rodichev for + helpful discussions. Comments and bug reports are welcome. + + + +
diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml new file mode 100644 index 000000000000..4b535809b63e --- /dev/null +++ b/doc/src/sgml/maintenance.sgml @@ -0,0 +1,1057 @@ + + + + Routine Database Maintenance Tasks + + + maintenance + + + + routine maintenance + + + + PostgreSQL, like any database software, requires that certain tasks + be performed regularly to achieve optimum performance. The tasks + discussed here are required, but they + are repetitive in nature and can easily be automated using standard + tools such as cron scripts or + Windows' Task Scheduler. It is the database + administrator's responsibility to set up appropriate scripts, and to + check that they execute successfully. + + + + One obvious maintenance task is the creation of backup copies of the data on a + regular schedule. Without a recent backup, you have no chance of recovery + after a catastrophe (disk failure, fire, mistakenly dropping a critical + table, etc.). The backup and recovery mechanisms available in + PostgreSQL are discussed at length in + . + + + + The other main category of maintenance task is periodic vacuuming + of the database. This activity is discussed in + . Closely related to this is updating + the statistics that will be used by the query planner, as discussed in + . + + + + Another task that might need periodic attention is log file management. + This is discussed in . + + + + check_postgres + is available for monitoring database health and reporting unusual + conditions. check_postgres integrates with + Nagios and MRTG, but can be run standalone too. + + + + PostgreSQL is low-maintenance compared + to some other database management systems. Nonetheless, + appropriate attention to these tasks will go far towards ensuring a + pleasant and productive experience with the system. + + + + Routine Vacuuming + + + vacuum + + + + PostgreSQL databases require periodic + maintenance known as vacuuming. For many installations, it + is sufficient to let vacuuming be performed by the autovacuum + daemon, which is described in . You might + need to adjust the autovacuuming parameters described there to obtain best + results for your situation. Some database administrators will want to + supplement or replace the daemon's activities with manually-managed + VACUUM commands, which typically are executed according to a + schedule by cron or Task + Scheduler scripts. To set up manually-managed vacuuming properly, + it is essential to understand the issues discussed in the next few + subsections. Administrators who rely on autovacuuming may still wish + to skim this material to help them understand and adjust autovacuuming. + + + + Vacuuming Basics + + + PostgreSQL's + VACUUM command has to + process each table on a regular basis for several reasons: + + + + To recover or reuse disk space occupied by updated or deleted + rows. + + + + To update data statistics used by the + PostgreSQL query planner. + + + + To update the visibility map, which speeds + up index-only + scans. + + + + To protect against loss of very old data due to + transaction ID wraparound or + multixact ID wraparound. + + + + Each of these reasons dictates performing VACUUM operations + of varying frequency and scope, as explained in the following subsections. + + + + There are two variants of VACUUM: standard VACUUM + and VACUUM FULL. VACUUM FULL can reclaim more + disk space but runs much more slowly. Also, + the standard form of VACUUM can run in parallel with production + database operations. (Commands such as SELECT, + INSERT, UPDATE, and + DELETE will continue to function normally, though you + will not be able to modify the definition of a table with commands such as + ALTER TABLE while it is being vacuumed.) + VACUUM FULL requires an + ACCESS EXCLUSIVE lock on the table it is + working on, and therefore cannot be done in parallel with other use + of the table. Generally, therefore, + administrators should strive to use standard VACUUM and + avoid VACUUM FULL. + + + + VACUUM creates a substantial amount of I/O + traffic, which can cause poor performance for other active sessions. + There are configuration parameters that can be adjusted to reduce the + performance impact of background vacuuming — see + . + + + + + Recovering Disk Space + + + disk space + + + + In PostgreSQL, an + UPDATE or DELETE of a row does not + immediately remove the old version of the row. + This approach is necessary to gain the benefits of multiversion + concurrency control (MVCC, see ): the row version + must not be deleted while it is still potentially visible to other + transactions. But eventually, an outdated or deleted row version is no + longer of interest to any transaction. The space it occupies must then be + reclaimed for reuse by new rows, to avoid unbounded growth of disk + space requirements. This is done by running VACUUM. + + + + The standard form of VACUUM removes dead row + versions in tables and indexes and marks the space available for + future reuse. However, it will not return the space to the operating + system, except in the special case where one or more pages at the + end of a table become entirely free and an exclusive table lock can be + easily obtained. In contrast, VACUUM FULL actively compacts + tables by writing a complete new version of the table file with no dead + space. This minimizes the size of the table, but can take a long time. + It also requires extra disk space for the new copy of the table, until + the operation completes. + + + + The usual goal of routine vacuuming is to do standard VACUUMs + often enough to avoid needing VACUUM FULL. The + autovacuum daemon attempts to work this way, and in fact will + never issue VACUUM FULL. In this approach, the idea + is not to keep tables at their minimum size, but to maintain steady-state + usage of disk space: each table occupies space equivalent to its + minimum size plus however much space gets used up between vacuum runs. + Although VACUUM FULL can be used to shrink a table back + to its minimum size and return the disk space to the operating system, + there is not much point in this if the table will just grow again in the + future. Thus, moderately-frequent standard VACUUM runs are a + better approach than infrequent VACUUM FULL runs for + maintaining heavily-updated tables. + + + + Some administrators prefer to schedule vacuuming themselves, for example + doing all the work at night when load is low. + The difficulty with doing vacuuming according to a fixed schedule + is that if a table has an unexpected spike in update activity, it may + get bloated to the point that VACUUM FULL is really necessary + to reclaim space. Using the autovacuum daemon alleviates this problem, + since the daemon schedules vacuuming dynamically in response to update + activity. It is unwise to disable the daemon completely unless you + have an extremely predictable workload. One possible compromise is + to set the daemon's parameters so that it will only react to unusually + heavy update activity, thus keeping things from getting out of hand, + while scheduled VACUUMs are expected to do the bulk of the + work when the load is typical. + + + + For those not using autovacuum, a typical approach is to schedule a + database-wide VACUUM once a day during a low-usage period, + supplemented by more frequent vacuuming of heavily-updated tables as + necessary. (Some installations with extremely high update rates vacuum + their busiest tables as often as once every few minutes.) If you have + multiple databases in a cluster, don't forget to + VACUUM each one; the program might be helpful. + + + + + Plain VACUUM may not be satisfactory when + a table contains large numbers of dead row versions as a result of + massive update or delete activity. If you have such a table and + you need to reclaim the excess disk space it occupies, you will need + to use VACUUM FULL, or alternatively + CLUSTER + or one of the table-rewriting variants of + ALTER TABLE. + These commands rewrite an entire new copy of the table and build + new indexes for it. All these options require an + ACCESS EXCLUSIVE lock. Note that + they also temporarily use extra disk space approximately equal to the size + of the table, since the old copies of the table and indexes can't be + released until the new ones are complete. + + + + + + If you have a table whose entire contents are deleted on a periodic + basis, consider doing it with + TRUNCATE rather + than using DELETE followed by + VACUUM. TRUNCATE removes the + entire content of the table immediately, without requiring a + subsequent VACUUM or VACUUM + FULL to reclaim the now-unused disk space. + The disadvantage is that strict MVCC semantics are violated. + + + + + + Updating Planner Statistics + + + statistics + of the planner + + + + ANALYZE + + + + The PostgreSQL query planner relies on + statistical information about the contents of tables in order to + generate good plans for queries. These statistics are gathered by + the ANALYZE command, + which can be invoked by itself or + as an optional step in VACUUM. It is important to have + reasonably accurate statistics, otherwise poor choices of plans might + degrade database performance. + + + + The autovacuum daemon, if enabled, will automatically issue + ANALYZE commands whenever the content of a table has + changed sufficiently. However, administrators might prefer to rely + on manually-scheduled ANALYZE operations, particularly + if it is known that update activity on a table will not affect the + statistics of interesting columns. The daemon schedules + ANALYZE strictly as a function of the number of rows + inserted or updated; it has no knowledge of whether that will lead + to meaningful statistical changes. + + + + As with vacuuming for space recovery, frequent updates of statistics + are more useful for heavily-updated tables than for seldom-updated + ones. But even for a heavily-updated table, there might be no need for + statistics updates if the statistical distribution of the data is + not changing much. A simple rule of thumb is to think about how much + the minimum and maximum values of the columns in the table change. + For example, a timestamp column that contains the time + of row update will have a constantly-increasing maximum value as + rows are added and updated; such a column will probably need more + frequent statistics updates than, say, a column containing URLs for + pages accessed on a website. The URL column might receive changes just + as often, but the statistical distribution of its values probably + changes relatively slowly. + + + + It is possible to run ANALYZE on specific tables and even + just specific columns of a table, so the flexibility exists to update some + statistics more frequently than others if your application requires it. + In practice, however, it is usually best to just analyze the entire + database, because it is a fast operation. ANALYZE uses a + statistically random sampling of the rows of a table rather than reading + every single row. + + + + + Although per-column tweaking of ANALYZE frequency might not be + very productive, you might find it worthwhile to do per-column + adjustment of the level of detail of the statistics collected by + ANALYZE. Columns that are heavily used in WHERE + clauses and have highly irregular data distributions might require a + finer-grain data histogram than other columns. See ALTER TABLE + SET STATISTICS, or change the database-wide default using the configuration parameter. + + + + Also, by default there is limited information available about + the selectivity of functions. However, if you create a statistics + object or an expression + index that uses a function call, useful statistics will be + gathered about the function, which can greatly improve query + plans that use the expression index. + + + + + + The autovacuum daemon does not issue ANALYZE commands for + foreign tables, since it has no means of determining how often that + might be useful. If your queries require statistics on foreign tables + for proper planning, it's a good idea to run manually-managed + ANALYZE commands on those tables on a suitable schedule. + + + + + + Updating the Visibility Map + + + Vacuum maintains a visibility map for each + table to keep track of which pages contain only tuples that are known to be + visible to all active transactions (and all future transactions, until the + page is again modified). This has two purposes. First, vacuum + itself can skip such pages on the next run, since there is nothing to + clean up. + + + + Second, it allows PostgreSQL to answer some + queries using only the index, without reference to the underlying table. + Since PostgreSQL indexes don't contain tuple + visibility information, a normal index scan fetches the heap tuple for each + matching index entry, to check whether it should be seen by the current + transaction. + An index-only + scan, on the other hand, checks the visibility map first. + If it's known that all tuples on the page are + visible, the heap fetch can be skipped. This is most useful on + large data sets where the visibility map can prevent disk accesses. + The visibility map is vastly smaller than the heap, so it can easily be + cached even when the heap is very large. + + + + + Preventing Transaction ID Wraparound Failures + + + transaction ID + wraparound + + + + wraparound + of transaction IDs + + + + PostgreSQL's + MVCC transaction semantics + depend on being able to compare transaction ID (XID) + numbers: a row version with an insertion XID greater than the current + transaction's XID is in the future and should not be visible + to the current transaction. But since transaction IDs have limited size + (32 bits) a cluster that runs for a long time (more + than 4 billion transactions) would suffer transaction ID + wraparound: the XID counter wraps around to zero, and all of a sudden + transactions that were in the past appear to be in the future — which + means their output become invisible. In short, catastrophic data loss. + (Actually the data is still there, but that's cold comfort if you cannot + get at it.) To avoid this, it is necessary to vacuum every table + in every database at least once every two billion transactions. + + + + The reason that periodic vacuuming solves the problem is that + VACUUM will mark rows as frozen, indicating that + they were inserted by a transaction that committed sufficiently far in + the past that the effects of the inserting transaction are certain to be + visible to all current and future transactions. + Normal XIDs are + compared using modulo-232 arithmetic. This means + that for every normal XID, there are two billion XIDs that are + older and two billion that are newer; another + way to say it is that the normal XID space is circular with no + endpoint. Therefore, once a row version has been created with a particular + normal XID, the row version will appear to be in the past for + the next two billion transactions, no matter which normal XID we are + talking about. If the row version still exists after more than two billion + transactions, it will suddenly appear to be in the future. To + prevent this, PostgreSQL reserves a special XID, + FrozenTransactionId, which does not follow the normal XID + comparison rules and is always considered older + than every normal XID. + Frozen row versions are treated as if the inserting XID were + FrozenTransactionId, so that they will appear to be + in the past to all normal transactions regardless of wraparound + issues, and so such row versions will be valid until deleted, no matter + how long that is. + + + + + In PostgreSQL versions before 9.4, freezing was + implemented by actually replacing a row's insertion XID + with FrozenTransactionId, which was visible in the + row's xmin system column. Newer versions just set a flag + bit, preserving the row's original xmin for possible + forensic use. However, rows with xmin equal + to FrozenTransactionId (2) may still be found + in databases pg_upgrade'd from pre-9.4 versions. + + + Also, system catalogs may contain rows with xmin equal + to BootstrapTransactionId (1), indicating that they were + inserted during the first phase of initdb. + Like FrozenTransactionId, this special XID is treated as + older than every normal XID. + + + + + + controls how old an XID value has to be before rows bearing that XID will be + frozen. Increasing this setting may avoid unnecessary work if the + rows that would otherwise be frozen will soon be modified again, + but decreasing this setting increases + the number of transactions that can elapse before the table must be + vacuumed again. + + + + VACUUM uses the visibility map + to determine which pages of a table must be scanned. Normally, it + will skip pages that don't have any dead row versions even if those pages + might still have row versions with old XID values. Therefore, normal + VACUUMs won't always freeze every old row version in the table. + Periodically, VACUUM will perform an aggressive + vacuum, skipping only those pages which contain neither dead rows nor + any unfrozen XID or MXID values. + + controls when VACUUM does that: all-visible but not all-frozen + pages are scanned if the number of transactions that have passed since the + last such scan is greater than vacuum_freeze_table_age minus + vacuum_freeze_min_age. Setting + vacuum_freeze_table_age to 0 forces VACUUM to + use this more aggressive strategy for all scans. + + + + The maximum time that a table can go unvacuumed is two billion + transactions minus the vacuum_freeze_min_age value at + the time of the last aggressive vacuum. If it were to go + unvacuumed for longer than + that, data loss could result. To ensure that this does not happen, + autovacuum is invoked on any table that might contain unfrozen rows with + XIDs older than the age specified by the configuration parameter . (This will happen even if + autovacuum is disabled.) + + + + This implies that if a table is not otherwise vacuumed, + autovacuum will be invoked on it approximately once every + autovacuum_freeze_max_age minus + vacuum_freeze_min_age transactions. + For tables that are regularly vacuumed for space reclamation purposes, + this is of little importance. However, for static tables + (including tables that receive inserts, but no updates or deletes), + there is no need to vacuum for space reclamation, so it can + be useful to try to maximize the interval between forced autovacuums + on very large static tables. Obviously one can do this either by + increasing autovacuum_freeze_max_age or decreasing + vacuum_freeze_min_age. + + + + The effective maximum for vacuum_freeze_table_age is 0.95 * + autovacuum_freeze_max_age; a setting higher than that will be + capped to the maximum. A value higher than + autovacuum_freeze_max_age wouldn't make sense because an + anti-wraparound autovacuum would be triggered at that point anyway, and + the 0.95 multiplier leaves some breathing room to run a manual + VACUUM before that happens. As a rule of thumb, + vacuum_freeze_table_age should be set to a value somewhat + below autovacuum_freeze_max_age, leaving enough gap so that + a regularly scheduled VACUUM or an autovacuum triggered by + normal delete and update activity is run in that window. Setting it too + close could lead to anti-wraparound autovacuums, even though the table + was recently vacuumed to reclaim space, whereas lower values lead to more + frequent aggressive vacuuming. + + + + The sole disadvantage of increasing autovacuum_freeze_max_age + (and vacuum_freeze_table_age along with it) is that + the pg_xact and pg_commit_ts + subdirectories of the database cluster will take more space, because it + must store the commit status and (if track_commit_timestamp is + enabled) timestamp of all transactions back to + the autovacuum_freeze_max_age horizon. The commit status uses + two bits per transaction, so if + autovacuum_freeze_max_age is set to its maximum allowed value + of two billion, pg_xact can be expected to grow to about half + a gigabyte and pg_commit_ts to about 20GB. If this + is trivial compared to your total database size, + setting autovacuum_freeze_max_age to its maximum allowed value + is recommended. Otherwise, set it depending on what you are willing to + allow for pg_xact and pg_commit_ts storage. + (The default, 200 million transactions, translates to about 50MB + of pg_xact storage and about 2GB of pg_commit_ts + storage.) + + + + One disadvantage of decreasing vacuum_freeze_min_age is that + it might cause VACUUM to do useless work: freezing a row + version is a waste of time if the row is modified + soon thereafter (causing it to acquire a new XID). So the setting should + be large enough that rows are not frozen until they are unlikely to change + any more. + + + + To track the age of the oldest unfrozen XIDs in a database, + VACUUM stores XID + statistics in the system tables pg_class and + pg_database. In particular, + the relfrozenxid column of a table's + pg_class row contains the freeze cutoff XID that was used + by the last aggressive VACUUM for that table. All rows + inserted by transactions with XIDs older than this cutoff XID are + guaranteed to have been frozen. Similarly, + the datfrozenxid column of a database's + pg_database row is a lower bound on the unfrozen XIDs + appearing in that database — it is just the minimum of the + per-table relfrozenxid values within the database. + A convenient way to + examine this information is to execute queries such as: + + +SELECT c.oid::regclass as table_name, + greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age +FROM pg_class c +LEFT JOIN pg_class t ON c.reltoastrelid = t.oid +WHERE c.relkind IN ('r', 'm'); + +SELECT datname, age(datfrozenxid) FROM pg_database; + + + The age column measures the number of transactions from the + cutoff XID to the current transaction's XID. + + + + VACUUM normally only scans pages that have been modified + since the last vacuum, but relfrozenxid can only be + advanced when every page of the table + that might contain unfrozen XIDs is scanned. This happens when + relfrozenxid is more than + vacuum_freeze_table_age transactions old, when + VACUUM's FREEZE option is used, or when all + pages that are not already all-frozen happen to + require vacuuming to remove dead row versions. When VACUUM + scans every page in the table that is not already all-frozen, it should + set age(relfrozenxid) to a value just a little more than the + vacuum_freeze_min_age setting + that was used (more by the number of transactions started since the + VACUUM started). If no relfrozenxid-advancing + VACUUM is issued on the table until + autovacuum_freeze_max_age is reached, an autovacuum will soon + be forced for the table. + + + + If for some reason autovacuum fails to clear old XIDs from a table, the + system will begin to emit warning messages like this when the database's + oldest XIDs reach forty million transactions from the wraparound point: + + +WARNING: database "mydb" must be vacuumed within 39985967 transactions +HINT: To avoid a database shutdown, execute a database-wide VACUUM in that database. + + + (A manual VACUUM should fix the problem, as suggested by the + hint; but note that the VACUUM must be performed by a + superuser, else it will fail to process system catalogs and thus not + be able to advance the database's datfrozenxid.) + If these warnings are + ignored, the system will shut down and refuse to start any new + transactions once there are fewer than three million transactions left + until wraparound: + + +ERROR: database is not accepting commands to avoid wraparound data loss in database "mydb" +HINT: Stop the postmaster and vacuum that database in single-user mode. + + + The three-million-transaction safety margin exists to let the + administrator recover without data loss, by manually executing the + required VACUUM commands. However, since the system will not + execute commands once it has gone into the safety shutdown mode, + the only way to do this is to stop the server and start the server in single-user + mode to execute VACUUM. The shutdown mode is not enforced + in single-user mode. See the reference + page for details about using single-user mode. + + + + Multixacts and Wraparound + + + MultiXactId + + + + wraparound + of multixact IDs + + + + Multixact IDs are used to support row locking by + multiple transactions. Since there is only limited space in a tuple + header to store lock information, that information is encoded as + a multiple transaction ID, or multixact ID for short, + whenever there is more than one transaction concurrently locking a + row. Information about which transaction IDs are included in any + particular multixact ID is stored separately in + the pg_multixact subdirectory, and only the multixact ID + appears in the xmax field in the tuple header. + Like transaction IDs, multixact IDs are implemented as a + 32-bit counter and corresponding storage, all of which requires + careful aging management, storage cleanup, and wraparound handling. + There is a separate storage area which holds the list of members in + each multixact, which also uses a 32-bit counter and which must also + be managed. + + + + Whenever VACUUM scans any part of a table, it will replace + any multixact ID it encounters which is older than + + by a different value, which can be the zero value, a single + transaction ID, or a newer multixact ID. For each table, + pg_class.relminmxid stores the oldest + possible multixact ID still appearing in any tuple of that table. + If this value is older than + , an aggressive + vacuum is forced. As discussed in the previous section, an aggressive + vacuum means that only those pages which are known to be all-frozen will + be skipped. mxid_age() can be used on + pg_class.relminmxid to find its age. + + + + Aggressive VACUUM scans, regardless of + what causes them, enable advancing the value for that table. + Eventually, as all tables in all databases are scanned and their + oldest multixact values are advanced, on-disk storage for older + multixacts can be removed. + + + + As a safety device, an aggressive vacuum scan will occur for any table + whose multixact-age is greater than + . Aggressive + vacuum scans will also occur progressively for all tables, starting with + those that have the oldest multixact-age, if the amount of used member + storage space exceeds the amount 50% of the addressable storage space. + Both of these kinds of aggressive scans will occur even if autovacuum is + nominally disabled. + + + + + + The Autovacuum Daemon + + + autovacuum + general information + + + PostgreSQL has an optional but highly + recommended feature called autovacuum, + whose purpose is to automate the execution of + VACUUM and ANALYZE commands. + When enabled, autovacuum checks for + tables that have had a large number of inserted, updated or deleted + tuples. These checks use the statistics collection facility; + therefore, autovacuum cannot be used unless is set to true. + In the default configuration, autovacuuming is enabled and the related + configuration parameters are appropriately set. + + + + The autovacuum daemon actually consists of multiple processes. + There is a persistent daemon process, called the + autovacuum launcher, which is in charge of starting + autovacuum worker processes for all databases. The + launcher will distribute the work across time, attempting to start one + worker within each database every + seconds. (Therefore, if the installation has N databases, + a new worker will be launched every + autovacuum_naptime/N seconds.) + A maximum of worker processes + are allowed to run at the same time. If there are more than + autovacuum_max_workers databases to be processed, + the next database will be processed as soon as the first worker finishes. + Each worker process will check each table within its database and + execute VACUUM and/or ANALYZE as needed. + can be set to monitor + autovacuum workers' activity. + + + + If several large tables all become eligible for vacuuming in a short + amount of time, all autovacuum workers might become occupied with + vacuuming those tables for a long period. This would result + in other tables and databases not being vacuumed until a worker becomes + available. There is no limit on how many workers might be in a + single database, but workers do try to avoid repeating work that has + already been done by other workers. Note that the number of running + workers does not count towards or + limits. + + + + Tables whose relfrozenxid value is more than + transactions old are always + vacuumed (this also applies to those tables whose freeze max age has + been modified via storage parameters; see below). Otherwise, if the + number of tuples obsoleted since the last + VACUUM exceeds the vacuum threshold, the + table is vacuumed. The vacuum threshold is defined as: + +vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples + + where the vacuum base threshold is + , + the vacuum scale factor is + , + and the number of tuples is + pg_class.reltuples. + + + + The table is also vacuumed if the number of tuples inserted since the last + vacuum has exceeded the defined insert threshold, which is defined as: + +vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples + + where the vacuum insert base threshold is + , + and vacuum insert scale factor is + . + Such vacuums may allow portions of the table to be marked as + all visible and also allow tuples to be frozen, which + can reduce the work required in subsequent vacuums. + For tables which receive INSERT operations but no or + almost no UPDATE/DELETE operations, + it may be beneficial to lower the table's + as this may allow + tuples to be frozen by earlier vacuums. The number of obsolete tuples and + the number of inserted tuples are obtained from the statistics collector; + it is a semi-accurate count updated by each UPDATE, + DELETE and INSERT operation. (It is + only semi-accurate because some information might be lost under heavy + load.) If the relfrozenxid value of the table + is more than vacuum_freeze_table_age transactions old, + an aggressive vacuum is performed to freeze old tuples and advance + relfrozenxid; otherwise, only pages that have been modified + since the last vacuum are scanned. + + + + For analyze, a similar condition is used: the threshold, defined as: + +analyze threshold = analyze base threshold + analyze scale factor * number of tuples + + is compared to the total number of tuples inserted, updated, or deleted + since the last ANALYZE. + For partitioned tables, inserts, updates and deletes on partitions + are counted towards this threshold; however, DDL + operations such as ATTACH, DETACH + and DROP are not, so running a manual + ANALYZE is recommended if the partition added or + removed contains a statistically significant volume of data. + + + + Temporary tables cannot be accessed by autovacuum. Therefore, + appropriate vacuum and analyze operations should be performed via + session SQL commands. + + + + The default thresholds and scale factors are taken from + postgresql.conf, but it is possible to override them + (and many other autovacuum control parameters) on a per-table basis; see + for more information. + If a setting has been changed via a table's storage parameters, that value + is used when processing that table; otherwise the global settings are + used. See for more details on + the global settings. + + + + When multiple workers are running, the autovacuum cost delay parameters + (see ) are + balanced among all the running workers, so that the + total I/O impact on the system is the same regardless of the number + of workers actually running. However, any workers processing tables whose + per-table autovacuum_vacuum_cost_delay or + autovacuum_vacuum_cost_limit storage parameters have been set + are not considered in the balancing algorithm. + + + + Autovacuum workers generally don't block other commands. If a process + attempts to acquire a lock that conflicts with the + SHARE UPDATE EXCLUSIVE lock held by autovacuum, lock + acquisition will interrupt the autovacuum. For conflicting lock modes, + see . However, if the autovacuum + is running to prevent transaction ID wraparound (i.e., the autovacuum query + name in the pg_stat_activity view ends with + (to prevent wraparound)), the autovacuum is not + automatically interrupted. + + + + + Regularly running commands that acquire locks conflicting with a + SHARE UPDATE EXCLUSIVE lock (e.g., ANALYZE) can + effectively prevent autovacuums from ever completing. + + + + + + + + Routine Reindexing + + + reindex + + + + In some situations it is worthwhile to rebuild indexes periodically + with the command or a series of individual + rebuilding steps. + + + + + B-tree index pages that have become completely empty are reclaimed for + re-use. However, there is still a possibility + of inefficient use of space: if all but a few index keys on a page have + been deleted, the page remains allocated. Therefore, a usage + pattern in which most, but not all, keys in each range are eventually + deleted will see poor use of space. For such usage patterns, + periodic reindexing is recommended. + + + + The potential for bloat in non-B-tree indexes has not been well + researched. It is a good idea to periodically monitor the index's physical + size when using any non-B-tree index type. + + + + Also, for B-tree indexes, a freshly-constructed index is slightly faster to + access than one that has been updated many times because logically + adjacent pages are usually also physically adjacent in a newly built index. + (This consideration does not apply to non-B-tree indexes.) It + might be worthwhile to reindex periodically just to improve access speed. + + + + can be used safely and easily in all cases. + This command requires an ACCESS EXCLUSIVE lock by + default, hence it is often preferable to execute it with its + CONCURRENTLY option, which requires only a + SHARE UPDATE EXCLUSIVE lock. + + + + + + Log File Maintenance + + + server log + log file maintenance + + + + It is a good idea to save the database server's log output + somewhere, rather than just discarding it via /dev/null. + The log output is invaluable when diagnosing + problems. However, the log output tends to be voluminous + (especially at higher debug levels) so you won't want to save it + indefinitely. You need to rotate the log files so that + new log files are started and old ones removed after a reasonable + period of time. + + + + If you simply direct the stderr of + postgres into a + file, you will have log output, but + the only way to truncate the log file is to stop and restart + the server. This might be acceptable if you are using + PostgreSQL in a development environment, + but few production servers would find this behavior acceptable. + + + + A better approach is to send the server's + stderr output to some type of log rotation program. + There is a built-in log rotation facility, which you can use by + setting the configuration parameter logging_collector to + true in postgresql.conf. The control + parameters for this program are described in . You can also use this approach + to capture the log data in machine readable CSV + (comma-separated values) format. + + + + Alternatively, you might prefer to use an external log rotation + program if you have one that you are already using with other + server software. For example, the rotatelogs + tool included in the Apache distribution + can be used with PostgreSQL. One way to + do this is to pipe the server's + stderr output to the desired program. + If you start the server with + pg_ctl, then stderr + is already redirected to stdout, so you just need a + pipe command, for example: + + +pg_ctl start | rotatelogs /var/log/pgsql_log 86400 + + + + + You can combine these approaches by setting up logrotate + to collect log files produced by PostgreSQL built-in + logging collector. In this case, the logging collector defines the names and + location of the log files, while logrotate + periodically archives these files. When initiating log rotation, + logrotate must ensure that the application + sends further output to the new file. This is commonly done with a + postrotate script that sends a SIGHUP + signal to the application, which then reopens the log file. + In PostgreSQL, you can run pg_ctl + with the logrotate option instead. When the server receives + this command, the server either switches to a new log file or reopens the + existing file, depending on the logging configuration + (see ). + + + + + When using static log file names, the server might fail to reopen the log + file if the max open file limit is reached or a file table overflow occurs. + In this case, log messages are sent to the old log file until a + successful log rotation. If logrotate is + configured to compress the log file and delete it, the server may lose + the messages logged in this time frame. To avoid this issue, you can + configure the logging collector to dynamically assign log file names + and use a prerotate script to ignore open log files. + + + + + Another production-grade approach to managing log output is to + send it to syslog and let + syslog deal with file rotation. To do this, set the + configuration parameter log_destination to syslog + (to log to syslog only) in + postgresql.conf. Then you can send a SIGHUP + signal to the syslog daemon whenever you want to force it + to start writing a new log file. If you want to automate log + rotation, the logrotate program can be + configured to work with log files from + syslog. + + + + On many systems, however, syslog is not very reliable, + particularly with large log messages; it might truncate or drop messages + just when you need them the most. Also, on Linux, + syslog will flush each message to disk, yielding poor + performance. (You can use a - at the start of the file name + in the syslog configuration file to disable syncing.) + + + + Note that all the solutions described above take care of starting new + log files at configurable intervals, but they do not handle deletion + of old, no-longer-useful log files. You will probably want to set + up a batch job to periodically delete old log files. Another possibility + is to configure the rotation program so that old log files are overwritten + cyclically. + + + + pgBadger + is an external project that does sophisticated log file analysis. + check_postgres + provides Nagios alerts when important messages appear in the log + files, as well as detection of many other extraordinary conditions. + + + diff --git a/doc/src/sgml/manage-ag.sgml b/doc/src/sgml/manage-ag.sgml new file mode 100644 index 000000000000..74055a470655 --- /dev/null +++ b/doc/src/sgml/manage-ag.sgml @@ -0,0 +1,546 @@ + + + + Managing Databases + + database + + + Every instance of a running PostgreSQL + server manages one or more databases. Databases are therefore the + topmost hierarchical level for organizing SQL + objects (database objects). This chapter describes + the properties of databases, and how to create, manage, and destroy + them. + + + + Overview + + + schema + + + + A small number of objects, like role, database, and tablespace + names, are defined at the cluster level and stored in the + pg_global tablespace. Inside the cluster are + multiple databases, which are isolated from each other but can access + cluster-level objects. Inside each database are multiple schemas, + which contain objects like tables and functions. So the full hierarchy + is: cluster, database, schema, table (or some other kind of object, + such as a function). + + + + When connecting to the database server, a client must specify the + database name in its connection request. + It is not possible to access more than one database per + connection. However, clients can open multiple connections to + the same database, or different databases. + Database-level security has two components: access control + (see ), managed at the + connection level, and authorization control + (see ), managed via the grant system. + Foreign data wrappers (see ) + allow for objects within one database to act as proxies for objects in + other database or clusters. + The older dblink module (see ) provides a similar capability. + By default, all users can connect to all databases using all connection methods. + + + + If one PostgreSQL server cluster is planned to contain + unrelated projects or users that should be, for the most part, unaware + of each other, it is recommended to put them into separate databases and + adjust authorizations and access controls accordingly. + If the projects or users are interrelated, and thus should be able to use + each other's resources, they should be put in the same database but probably + into separate schemas; this provides a modular structure with namespace + isolation and authorization control. + More information about managing schemas is in . + + + + While multiple databases can be created within a single cluster, it is advised + to consider carefully whether the benefits outweigh the risks and limitations. + In particular, the impact that having a shared WAL (see ) + has on backup and recovery options. While individual databases in the cluster + are isolated when considered from the user's perspective, they are closely bound + from the database administrator's point-of-view. + + + + Databases are created with the CREATE DATABASE command + (see ) and destroyed with the + DROP DATABASE command + (see ). + To determine the set of existing databases, examine the + pg_database system catalog, for example + +SELECT datname FROM pg_database; + + The program's \l meta-command + and command-line option are also useful for listing the + existing databases. + + + + + The SQL standard calls databases catalogs, but there + is no difference in practice. + + + + + + Creating a Database + + CREATE DATABASE + + + In order to create a database, the PostgreSQL + server must be up and running (see ). + + + + Databases are created with the SQL command + : + +CREATE DATABASE name; + + where name follows the usual rules for + SQL identifiers. The current role automatically + becomes the owner of the new database. It is the privilege of the + owner of a database to remove it later (which also removes all + the objects in it, even if they have a different owner). + + + + The creation of databases is a restricted operation. See for how to grant permission. + + + + Since you need to be connected to the database server in order to + execute the CREATE DATABASE command, the + question remains how the first database at any given + site can be created. The first database is always created by the + initdb command when the data storage area is + initialized. (See .) This + database is called + postgres.postgres So to + create the first ordinary database you can connect to + postgres. + + + + A second database, + template1,template1 + is also created during database cluster initialization. Whenever a + new database is created within the + cluster, template1 is essentially cloned. + This means that any changes you make in template1 are + propagated to all subsequently created databases. Because of this, + avoid creating objects in template1 unless you want them + propagated to every newly created database. More details + appear in . + + + + As a convenience, there is a program you can + execute from the shell to create new databases, + createdb.createdb + + +createdb dbname + + + createdb does no magic. It connects to the postgres + database and issues the CREATE DATABASE command, + exactly as described above. + The reference page contains the invocation + details. Note that createdb without any arguments will create + a database with the current user name. + + + + + contains information about + how to restrict who can connect to a given database. + + + + + Sometimes you want to create a database for someone else, and have them + become the owner of the new database, so they can + configure and manage it themselves. To achieve that, use one of the + following commands: + +CREATE DATABASE dbname OWNER rolename; + + from the SQL environment, or: + +createdb -O rolename dbname + + from the shell. + Only the superuser is allowed to create a database for + someone else (that is, for a role you are not a member of). + + + + + Template Databases + + + CREATE DATABASE actually works by copying an existing + database. By default, it copies the standard system database named + template1.template1 Thus that + database is the template from which new databases are + made. If you add objects to template1, these objects + will be copied into subsequently created user databases. This + behavior allows site-local modifications to the standard set of + objects in databases. For example, if you install the procedural + language PL/Perl in template1, it will + automatically be available in user databases without any extra + action being taken when those databases are created. + + + + There is a second standard system database named + template0.template0 This + database contains the same data as the initial contents of + template1, that is, only the standard objects + predefined by your version of + PostgreSQL. template0 + should never be changed after the database cluster has been + initialized. By instructing + CREATE DATABASE to copy template0 instead + of template1, you can create a pristine user + database (one where no user-defined objects exist and where the system + objects have not been altered) that contains none of the site-local additions in + template1. This is particularly handy when restoring a + pg_dump dump: the dump script should be restored in a + pristine database to ensure that one recreates the correct contents + of the dumped database, without conflicting with objects that + might have been added to template1 later on. + + + + Another common reason for copying template0 instead + of template1 is that new encoding and locale settings + can be specified when copying template0, whereas a copy + of template1 must use the same settings it does. + This is because template1 might contain encoding-specific + or locale-specific data, while template0 is known not to. + + + + To create a database by copying template0, use: + +CREATE DATABASE dbname TEMPLATE template0; + + from the SQL environment, or: + +createdb -T template0 dbname + + from the shell. + + + + It is possible to create additional template databases, and indeed + one can copy any database in a cluster by specifying its name + as the template for CREATE DATABASE. It is important to + understand, however, that this is not (yet) intended as + a general-purpose COPY DATABASE facility. + The principal limitation is that no other sessions can be connected to + the source database while it is being copied. CREATE + DATABASE will fail if any other connection exists when it starts; + during the copy operation, new connections to the source database + are prevented. + + + + Two useful flags exist in pg_databasepg_database for each + database: the columns datistemplate and + datallowconn. datistemplate + can be set to indicate that a database is intended as a template for + CREATE DATABASE. If this flag is set, the database can be + cloned by any user with CREATEDB privileges; if it is not set, + only superusers and the owner of the database can clone it. + If datallowconn is false, then no new connections + to that database will be allowed (but existing sessions are not terminated + simply by setting the flag false). The template0 + database is normally marked datallowconn = false to prevent its modification. + Both template0 and template1 + should always be marked with datistemplate = true. + + + + + template1 and template0 do not have any special + status beyond the fact that the name template1 is the default + source database name for CREATE DATABASE. + For example, one could drop template1 and recreate it from + template0 without any ill effects. This course of action + might be advisable if one has carelessly added a bunch of junk in + template1. (To delete template1, + it must have pg_database.datistemplate = false.) + + + + The postgres database is also created when a database + cluster is initialized. This database is meant as a default database for + users and applications to connect to. It is simply a copy of + template1 and can be dropped and recreated if necessary. + + + + + + Database Configuration + + + Recall from that the + PostgreSQL server provides a large number of + run-time configuration variables. You can set database-specific + default values for many of these settings. + + + + For example, if for some reason you want to disable the + GEQO optimizer for a given database, you'd + ordinarily have to either disable it for all databases or make sure + that every connecting client is careful to issue SET geqo + TO off. To make this setting the default within a particular + database, you can execute the command: + +ALTER DATABASE mydb SET geqo TO off; + + This will save the setting (but not set it immediately). In + subsequent connections to this database it will appear as though + SET geqo TO off; had been executed just before the + session started. + Note that users can still alter this setting during their sessions; it + will only be the default. To undo any such setting, use + ALTER DATABASE dbname RESET + varname. + + + + + Destroying a Database + + + Databases are destroyed with the command + :DROP DATABASE + +DROP DATABASE name; + + Only the owner of the database, or + a superuser, can drop a database. Dropping a database removes all objects + that were + contained within the database. The destruction of a database cannot + be undone. + + + + You cannot execute the DROP DATABASE command + while connected to the victim database. You can, however, be + connected to any other database, including the template1 + database. + template1 would be the only option for dropping the last user database of a + given cluster. + + + + For convenience, there is also a shell program to drop + databases, :dropdb + +dropdb dbname + + (Unlike createdb, it is not the default action to drop + the database with the current user name.) + + + + + Tablespaces + + + tablespace + + + + Tablespaces in PostgreSQL allow database administrators to + define locations in the file system where the files representing + database objects can be stored. Once created, a tablespace can be referred + to by name when creating database objects. + + + + By using tablespaces, an administrator can control the disk layout + of a PostgreSQL installation. This is useful in at + least two ways. First, if the partition or volume on which the + cluster was initialized runs out of space and cannot be extended, + a tablespace can be created on a different partition and used + until the system can be reconfigured. + + + + Second, tablespaces allow an administrator to use knowledge of the + usage pattern of database objects to optimize performance. For + example, an index which is very heavily used can be placed on a + very fast, highly available disk, such as an expensive solid state + device. At the same time a table storing archived data which is + rarely used or not performance critical could be stored on a less + expensive, slower disk system. + + + + + Even though located outside the main PostgreSQL data directory, + tablespaces are an integral part of the database cluster and + cannot be treated as an autonomous collection + of data files. They are dependent on metadata contained in the main + data directory, and therefore cannot be attached to a different + database cluster or backed up individually. Similarly, if you lose + a tablespace (file deletion, disk failure, etc), the database cluster + might become unreadable or unable to start. Placing a tablespace + on a temporary file system like a RAM disk risks the reliability of + the entire cluster. + + + + + To define a tablespace, use the + command, for example:CREATE TABLESPACE: + +CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data'; + + The location must be an existing, empty directory that is owned by + the PostgreSQL operating system user. All objects subsequently + created within the tablespace will be stored in files underneath this + directory. The location must not be on removable or transient storage, + as the cluster might fail to function if the tablespace is missing + or lost. + + + + + There is usually not much point in making more than one + tablespace per logical file system, since you cannot control the location + of individual files within a logical file system. However, + PostgreSQL does not enforce any such limitation, and + indeed it is not directly aware of the file system boundaries on your + system. It just stores files in the directories you tell it to use. + + + + + Creation of the tablespace itself must be done as a database superuser, + but after that you can allow ordinary database users to use it. + To do that, grant them the CREATE privilege on it. + + + + Tables, indexes, and entire databases can be assigned to + particular tablespaces. To do so, a user with the CREATE + privilege on a given tablespace must pass the tablespace name as a + parameter to the relevant command. For example, the following creates + a table in the tablespace space1: + +CREATE TABLE foo(i int) TABLESPACE space1; + + + + + Alternatively, use the parameter: + +SET default_tablespace = space1; +CREATE TABLE foo(i int); + + When default_tablespace is set to anything but an empty + string, it supplies an implicit TABLESPACE clause for + CREATE TABLE and CREATE INDEX commands that + do not have an explicit one. + + + + There is also a parameter, which + determines the placement of temporary tables and indexes, as well as + temporary files that are used for purposes such as sorting large data + sets. This can be a list of tablespace names, rather than only one, + so that the load associated with temporary objects can be spread over + multiple tablespaces. A random member of the list is picked each time + a temporary object is to be created. + + + + The tablespace associated with a database is used to store the system + catalogs of that database. Furthermore, it is the default tablespace + used for tables, indexes, and temporary files created within the database, + if no TABLESPACE clause is given and no other selection is + specified by default_tablespace or + temp_tablespaces (as appropriate). + If a database is created without specifying a tablespace for it, + it uses the same tablespace as the template database it is copied from. + + + + Two tablespaces are automatically created when the database cluster + is initialized. The + pg_global tablespace is used for shared system catalogs. The + pg_default tablespace is the default tablespace of the + template1 and template0 databases (and, therefore, + will be the default tablespace for other databases as well, unless + overridden by a TABLESPACE clause in CREATE + DATABASE). + + + + Once created, a tablespace can be used from any database, provided + the requesting user has sufficient privilege. This means that a tablespace + cannot be dropped until all objects in all databases using the tablespace + have been removed. + + + + To remove an empty tablespace, use the + command. + + + + To determine the set of existing tablespaces, examine the + pg_tablespace + system catalog, for example + +SELECT spcname FROM pg_tablespace; + + The program's \db meta-command + is also useful for listing the existing tablespaces. + + + + PostgreSQL makes use of symbolic links + to simplify the implementation of tablespaces. This + means that tablespaces can be used only on systems + that support symbolic links. + + + + The directory $PGDATA/pg_tblspc contains symbolic links that + point to each of the non-built-in tablespaces defined in the cluster. + Although not recommended, it is possible to adjust the tablespace + layout by hand by redefining these links. Under no circumstances perform + this operation while the server is running. Note that in PostgreSQL 9.1 + and earlier you will also need to update the pg_tablespace + catalog with the new locations. (If you do not, pg_dump will + continue to output the old tablespace locations.) + + + + diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml new file mode 100644 index 000000000000..dcbb10fb6ff3 --- /dev/null +++ b/doc/src/sgml/monitoring.sgml @@ -0,0 +1,7465 @@ + + + + Monitoring Database Activity + + + monitoring + database activity + + + + database activity + monitoring + + + + A database administrator frequently wonders, What is the system + doing right now? + This chapter discusses how to find that out. + + + + Several tools are available for monitoring database activity and + analyzing performance. Most of this chapter is devoted to describing + PostgreSQL's statistics collector, + but one should not neglect regular Unix monitoring programs such as + ps, top, iostat, and vmstat. + Also, once one has identified a + poorly-performing query, further investigation might be needed using + PostgreSQL's EXPLAIN command. + discusses EXPLAIN + and other methods for understanding the behavior of an individual + query. + + + + Standard Unix Tools + + + ps + to monitor activity + + + + On most Unix platforms, PostgreSQL modifies its + command title as reported by ps, so that individual server + processes can readily be identified. A sample display is + + +$ ps auxww | grep ^postgres +postgres 15551 0.0 0.1 57536 7132 pts/0 S 18:02 0:00 postgres -i +postgres 15554 0.0 0.0 57536 1184 ? Ss 18:02 0:00 postgres: background writer +postgres 15555 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: checkpointer +postgres 15556 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: walwriter +postgres 15557 0.0 0.0 58504 2244 ? Ss 18:02 0:00 postgres: autovacuum launcher +postgres 15558 0.0 0.0 17512 1068 ? Ss 18:02 0:00 postgres: stats collector +postgres 15582 0.0 0.0 58772 3080 ? Ss 18:04 0:00 postgres: joe runbug 127.0.0.1 idle +postgres 15606 0.0 0.0 58772 3052 ? Ss 18:07 0:00 postgres: tgl regression [local] SELECT waiting +postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl regression [local] idle in transaction + + + (The appropriate invocation of ps varies across different + platforms, as do the details of what is shown. This example is from a + recent Linux system.) The first process listed here is the + primary server process. The command arguments + shown for it are the same ones used when it was launched. The next five + processes are background worker processes automatically launched by the + primary process. (The stats collector process will not be present + if you have set the system not to start the statistics collector; likewise + the autovacuum launcher process can be disabled.) + Each of the remaining + processes is a server process handling one client connection. Each such + process sets its command line display in the form + + +postgres: user database host activity + + + The user, database, and (client) host items remain the same for + the life of the client connection, but the activity indicator changes. + The activity can be idle (i.e., waiting for a client command), + idle in transaction (waiting for client inside a BEGIN block), + or a command type name such as SELECT. Also, + waiting is appended if the server process is presently waiting + on a lock held by another session. In the above example we can infer + that process 15606 is waiting for process 15610 to complete its transaction + and thereby release some lock. (Process 15610 must be the blocker, because + there is no other active session. In more complicated cases it would be + necessary to look into the + pg_locks + system view to determine who is blocking whom.) + + + + If has been configured the + cluster name will also be shown in ps output: + +$ psql -c 'SHOW cluster_name' + cluster_name +-------------- + server1 +(1 row) + +$ ps aux|grep server1 +postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: server1: background writer +... + + + + + If you have turned off then the + activity indicator is not updated; the process title is set only once + when a new process is launched. On some platforms this saves a measurable + amount of per-command overhead; on others it's insignificant. + + + + + Solaris requires special handling. You must + use /usr/ucb/ps, rather than + /bin/ps. You also must use two + flags, not just one. In addition, your original invocation of the + postgres command must have a shorter + ps status display than that provided by each + server process. If you fail to do all three things, the ps + output for each server process will be the original postgres + command line. + + + + + + The Statistics Collector + + + statistics + + + + PostgreSQL's statistics collector + is a subsystem that supports collection and reporting of information about + server activity. Presently, the collector can count accesses to tables + and indexes in both disk-block and individual-row terms. It also tracks + the total number of rows in each table, and information about vacuum and + analyze actions for each table. It can also count calls to user-defined + functions and the total time spent in each one. + + + + PostgreSQL also supports reporting dynamic + information about exactly what is going on in the system right now, such as + the exact command currently being executed by other server processes, and + which other connections exist in the system. This facility is independent + of the collector process. + + + + Statistics Collection Configuration + + + Since collection of statistics adds some overhead to query execution, + the system can be configured to collect or not collect information. + This is controlled by configuration parameters that are normally set in + postgresql.conf. (See for + details about setting configuration parameters.) + + + + The parameter enables monitoring + of the current command being executed by any server process. + + + + The parameter controls whether + statistics are collected about table and index accesses. + + + + The parameter enables tracking of + usage of user-defined functions. + + + + The parameter enables monitoring + of block read and write times. + + + + The parameter enables monitoring + of WAL write times. + + + + Normally these parameters are set in postgresql.conf so + that they apply to all server processes, but it is possible to turn + them on or off in individual sessions using the command. (To prevent + ordinary users from hiding their activity from the administrator, + only superusers are allowed to change these parameters with + SET.) + + + + The statistics collector transmits the collected information to other + PostgreSQL processes through temporary files. + These files are stored in the directory named by the + parameter, + pg_stat_tmp by default. + For better performance, stats_temp_directory can be + pointed at a RAM-based file system, decreasing physical I/O requirements. + When the server shuts down cleanly, a permanent copy of the statistics + data is stored in the pg_stat subdirectory, so that + statistics can be retained across server restarts. When recovery is + performed at server start (e.g., after immediate shutdown, server crash, + and point-in-time recovery), all statistics counters are reset. + + + + + + Viewing Statistics + + + Several predefined views, listed in , are available to show + the current state of the system. There are also several other + views, listed in , available to show the results + of statistics collection. Alternatively, one can + build custom views using the underlying statistics functions, as discussed + in . + + + + When using the statistics to monitor collected data, it is important + to realize that the information does not update instantaneously. + Each individual server process transmits new statistical counts to + the collector just before going idle; so a query or transaction still in + progress does not affect the displayed totals. Also, the collector itself + emits a new report at most once per PGSTAT_STAT_INTERVAL + milliseconds (500 ms unless altered while building the server). So the + displayed information lags behind actual activity. However, current-query + information collected by track_activities is + always up-to-date. + + + + Another important point is that when a server process is asked to display + any of these statistics, it first fetches the most recent report emitted by + the collector process and then continues to use this snapshot for all + statistical views and functions until the end of its current transaction. + So the statistics will show static information as long as you continue the + current transaction. Similarly, information about the current queries of + all sessions is collected when any such information is first requested + within a transaction, and the same information will be displayed throughout + the transaction. + This is a feature, not a bug, because it allows you to perform several + queries on the statistics and correlate the results without worrying that + the numbers are changing underneath you. But if you want to see new + results with each query, be sure to do the queries outside any transaction + block. Alternatively, you can invoke + pg_stat_clear_snapshot(), which will discard the + current transaction's statistics snapshot (if any). The next use of + statistical information will cause a new snapshot to be fetched. + + + + A transaction can also see its own statistics (as yet untransmitted to the + collector) in the views pg_stat_xact_all_tables, + pg_stat_xact_sys_tables, + pg_stat_xact_user_tables, and + pg_stat_xact_user_functions. These numbers do not act as + stated above; instead they update continuously throughout the transaction. + + + + Some of the information in the dynamic statistics views shown in is security restricted. + Ordinary users can only see all the information about their own sessions + (sessions belonging to a role that they are a member of). In rows about + other sessions, many columns will be null. Note, however, that the + existence of a session and its general properties such as its sessions user + and database are visible to all users. Superusers and members of the + built-in role pg_read_all_stats (see also ) can see all the information about all sessions. + + + + Dynamic Statistics Views + + + + + View Name + Description + + + + + + + pg_stat_activity + pg_stat_activity + + + One row per server process, showing information related to + the current activity of that process, such as state and current query. + See + pg_stat_activity for details. + + + + + pg_stat_replicationpg_stat_replication + One row per WAL sender process, showing statistics about + replication to that sender's connected standby server. + See + pg_stat_replication for details. + + + + + pg_stat_replication_slotspg_stat_replication_slots + One row per replication slot, showing statistics about + the replication slot's usage. + See + pg_stat_replication_slots for details. + + + + + pg_stat_wal_receiverpg_stat_wal_receiver + Only one row, showing statistics about the WAL receiver from + that receiver's connected server. + See + pg_stat_wal_receiver for details. + + + + + pg_stat_subscriptionpg_stat_subscription + At least one row per subscription, showing information about + the subscription workers. + See + pg_stat_subscription for details. + + + + + pg_stat_sslpg_stat_ssl + One row per connection (regular and replication), showing information about + SSL used on this connection. + See + pg_stat_ssl for details. + + + + + pg_stat_gssapipg_stat_gssapi + One row per connection (regular and replication), showing information about + GSSAPI authentication and encryption used on this connection. + See + pg_stat_gssapi for details. + + + + + pg_stat_progress_analyzepg_stat_progress_analyze + One row for each backend (including autovacuum worker processes) running + ANALYZE, showing current progress. + See . + + + + + pg_stat_progress_create_indexpg_stat_progress_create_index + One row for each backend running CREATE INDEX or REINDEX, showing + current progress. + See . + + + + + pg_stat_progress_vacuumpg_stat_progress_vacuum + One row for each backend (including autovacuum worker processes) running + VACUUM, showing current progress. + See . + + + + + pg_stat_progress_clusterpg_stat_progress_cluster + One row for each backend running + CLUSTER or VACUUM FULL, showing current progress. + See . + + + + + pg_stat_progress_basebackuppg_stat_progress_basebackup + One row for each WAL sender process streaming a base backup, + showing current progress. + See . + + + + + pg_stat_progress_copypg_stat_progress_copy + One row for each backend running COPY, showing current progress. + See . + + + + +
+ + + Collected Statistics Views + + + + + View Name + Description + + + + + + pg_stat_archiverpg_stat_archiver + One row only, showing statistics about the + WAL archiver process's activity. See + + pg_stat_archiver for details. + + + + + pg_stat_bgwriterpg_stat_bgwriter + One row only, showing statistics about the + background writer process's activity. See + + pg_stat_bgwriter for details. + + + + + pg_stat_walpg_stat_wal + One row only, showing statistics about WAL activity. See + + pg_stat_wal for details. + + + + + pg_stat_databasepg_stat_database + One row per database, showing database-wide statistics. See + + pg_stat_database for details. + + + + + pg_stat_database_conflictspg_stat_database_conflicts + + One row per database, showing database-wide statistics about + query cancels due to conflict with recovery on standby servers. + See + pg_stat_database_conflicts for details. + + + + + pg_stat_all_tablespg_stat_all_tables + + One row for each table in the current database, showing statistics + about accesses to that specific table. + See + pg_stat_all_tables for details. + + + + + pg_stat_sys_tablespg_stat_sys_tables + Same as pg_stat_all_tables, except that only + system tables are shown. + + + + pg_stat_user_tablespg_stat_user_tables + Same as pg_stat_all_tables, except that only user + tables are shown. + + + + pg_stat_xact_all_tablespg_stat_xact_all_tables + Similar to pg_stat_all_tables, but counts actions + taken so far within the current transaction (which are not + yet included in pg_stat_all_tables and related views). + The columns for numbers of live and dead rows and vacuum and + analyze actions are not present in this view. + + + + pg_stat_xact_sys_tablespg_stat_xact_sys_tables + Same as pg_stat_xact_all_tables, except that only + system tables are shown. + + + + pg_stat_xact_user_tablespg_stat_xact_user_tables + Same as pg_stat_xact_all_tables, except that only + user tables are shown. + + + + pg_stat_all_indexespg_stat_all_indexes + + One row for each index in the current database, showing statistics + about accesses to that specific index. + See + pg_stat_all_indexes for details. + + + + + pg_stat_sys_indexespg_stat_sys_indexes + Same as pg_stat_all_indexes, except that only + indexes on system tables are shown. + + + + pg_stat_user_indexespg_stat_user_indexes + Same as pg_stat_all_indexes, except that only + indexes on user tables are shown. + + + + pg_statio_all_tablespg_statio_all_tables + + One row for each table in the current database, showing statistics + about I/O on that specific table. + See + pg_statio_all_tables for details. + + + + + pg_statio_sys_tablespg_statio_sys_tables + Same as pg_statio_all_tables, except that only + system tables are shown. + + + + pg_statio_user_tablespg_statio_user_tables + Same as pg_statio_all_tables, except that only + user tables are shown. + + + + pg_statio_all_indexespg_statio_all_indexes + + One row for each index in the current database, + showing statistics about I/O on that specific index. + See + pg_statio_all_indexes for details. + + + + + pg_statio_sys_indexespg_statio_sys_indexes + Same as pg_statio_all_indexes, except that only + indexes on system tables are shown. + + + + pg_statio_user_indexespg_statio_user_indexes + Same as pg_statio_all_indexes, except that only + indexes on user tables are shown. + + + + pg_statio_all_sequencespg_statio_all_sequences + + One row for each sequence in the current database, + showing statistics about I/O on that specific sequence. + See + pg_statio_all_sequences for details. + + + + + pg_statio_sys_sequencespg_statio_sys_sequences + Same as pg_statio_all_sequences, except that only + system sequences are shown. (Presently, no system sequences are defined, + so this view is always empty.) + + + + pg_statio_user_sequencespg_statio_user_sequences + Same as pg_statio_all_sequences, except that only + user sequences are shown. + + + + pg_stat_user_functionspg_stat_user_functions + + One row for each tracked function, showing statistics + about executions of that function. See + + pg_stat_user_functions for details. + + + + + pg_stat_xact_user_functionspg_stat_xact_user_functions + Similar to pg_stat_user_functions, but counts only + calls during the current transaction (which are not + yet included in pg_stat_user_functions). + + + + pg_stat_slrupg_stat_slru + One row per SLRU, showing statistics of operations. See + + pg_stat_slru for details. + + + + + +
+ + + The per-index statistics are particularly useful to determine which + indexes are being used and how effective they are. + + + + The pg_statio_ views are primarily useful to + determine the effectiveness of the buffer cache. When the number + of actual disk reads is much smaller than the number of buffer + hits, then the cache is satisfying most read requests without + invoking a kernel call. However, these statistics do not give the + entire story: due to the way in which PostgreSQL + handles disk I/O, data that is not in the + PostgreSQL buffer cache might still reside in the + kernel's I/O cache, and might therefore still be fetched without + requiring a physical read. Users interested in obtaining more + detailed information on PostgreSQL I/O behavior are + advised to use the PostgreSQL statistics collector + in combination with operating system utilities that allow insight + into the kernel's handling of I/O. + + +
+ + + <structname>pg_stat_activity</structname> + + + pg_stat_activity + + + + The pg_stat_activity view will have one row + per server process, showing information related to + the current activity of that process. + + + + <structname>pg_stat_activity</structname> View + + + + + Column Type + + + Description + + + + + + + + datid oid + + + OID of the database this backend is connected to + + + + + + datname name + + + Name of the database this backend is connected to + + + + + + pid integer + + + Process ID of this backend + + + + + + leader_pid integer + + + Process ID of the parallel group leader, if this process is a + parallel query worker. NULL if this process is a + parallel group leader or does not participate in parallel query. + + + + + + usesysid oid + + + OID of the user logged into this backend + + + + + + usename name + + + Name of the user logged into this backend + + + + + + application_name text + + + Name of the application that is connected + to this backend + + + + + + client_addr inet + + + IP address of the client connected to this backend. + If this field is null, it indicates either that the client is + connected via a Unix socket on the server machine or that this is an + internal process such as autovacuum. + + + + + + client_hostname text + + + Host name of the connected client, as reported by a + reverse DNS lookup of client_addr. This field will + only be non-null for IP connections, and only when is enabled. + + + + + + client_port integer + + + TCP port number that the client is using for communication + with this backend, or -1 if a Unix socket is used. + If this field is null, it indicates that this is an internal server process. + + + + + + backend_start timestamp with time zone + + + Time when this process was started. For client backends, + this is the time the client connected to the server. + + + + + + xact_start timestamp with time zone + + + Time when this process' current transaction was started, or null + if no transaction is active. If the current + query is the first of its transaction, this column is equal to the + query_start column. + + + + + + query_start timestamp with time zone + + + Time when the currently active query was started, or if + state is not active, when the last query + was started + + + + + + state_change timestamp with time zone + + + Time when the state was last changed + + + + + + wait_event_type text + + + The type of event for which the backend is waiting, if any; + otherwise NULL. See . + + + + + + wait_event text + + + Wait event name if backend is currently waiting, otherwise NULL. + See through + . + + + + + + state text + + + Current overall state of this backend. + Possible values are: + + + + active: The backend is executing a query. + + + + + idle: The backend is waiting for a new client command. + + + + + idle in transaction: The backend is in a transaction, + but is not currently executing a query. + + + + + idle in transaction (aborted): This state is similar to + idle in transaction, except one of the statements in + the transaction caused an error. + + + + + fastpath function call: The backend is executing a + fast-path function. + + + + + disabled: This state is reported if is disabled in this backend. + + + + + + + + + backend_xid xid + + + Top-level transaction identifier of this backend, if any. + + + + + + backend_xmin xid + + + The current backend's xmin horizon. + + + + + + query_id bigint + + + Identifier of this backend's most recent query. If + state is active this + field shows the identifier of the currently executing query. In + all other states, it shows the identifier of last query that was + executed. Query identifiers are not computed by default so this + field will be null unless + parameter is enabled or a third-party module that computes query + identifiers is configured. + + + + + + query text + + + Text of this backend's most recent query. If + state is active this field shows the + currently executing query. In all other states, it shows the last query + that was executed. By default the query text is truncated at 1024 + bytes; this value can be changed via the parameter + . + + + + + + backend_type text + + + Type of current backend. Possible types are + autovacuum launcher, autovacuum worker, + logical replication launcher, + logical replication worker, + parallel worker, background writer, + client backend, checkpointer, + archiver, + startup, walreceiver, + walsender and walwriter. + In addition, background workers registered by extensions may have + additional types. + + + + +
+ + + + The wait_event and state columns are + independent. If a backend is in the active state, + it may or may not be waiting on some event. If the state + is active and wait_event is non-null, it + means that a query is being executed, but is being blocked somewhere + in the system. + + + + + Wait Event Types + + + + Wait Event Type + Description + + + + + + Activity + The server process is idle. This event type indicates a process + waiting for activity in its main processing loop. + wait_event will identify the specific wait point; + see . + + + + BufferPin + The server process is waiting for exclusive access to + a data buffer. Buffer pin waits can be protracted if + another process holds an open cursor that last read data from the + buffer in question. See . + + + + Client + The server process is waiting for activity on a socket + connected to a user application. Thus, the server expects something + to happen that is independent of its internal processes. + wait_event will identify the specific wait point; + see . + + + + Extension + The server process is waiting for some condition defined by an + extension module. + See . + + + + IO + The server process is waiting for an I/O operation to complete. + wait_event will identify the specific wait point; + see . + + + + IPC + The server process is waiting for some interaction with + another server process. wait_event will + identify the specific wait point; + see . + + + + Lock + The server process is waiting for a heavyweight lock. + Heavyweight locks, also known as lock manager locks or simply locks, + primarily protect SQL-visible objects such as tables. However, + they are also used to ensure mutual exclusion for certain internal + operations such as relation extension. wait_event + will identify the type of lock awaited; + see . + + + + LWLock + The server process is waiting for a lightweight lock. + Most such locks protect a particular data structure in shared memory. + wait_event will contain a name identifying the purpose + of the lightweight lock. (Some locks have specific names; others + are part of a group of locks each with a similar purpose.) + See . + + + + Timeout + The server process is waiting for a timeout + to expire. wait_event will identify the specific wait + point; see . + + + + +
+ + + Wait Events of Type <literal>Activity</literal> + + + + Activity Wait Event + Description + + + + + + ArchiverMain + Waiting in main loop of archiver process. + + + AutoVacuumMain + Waiting in main loop of autovacuum launcher process. + + + BgWriterHibernate + Waiting in background writer process, hibernating. + + + BgWriterMain + Waiting in main loop of background writer process. + + + CheckpointerMain + Waiting in main loop of checkpointer process. + + + LogicalApplyMain + Waiting in main loop of logical replication apply process. + + + LogicalLauncherMain + Waiting in main loop of logical replication launcher process. + + + PgStatMain + Waiting in main loop of statistics collector process. + + + RecoveryWalStream + Waiting in main loop of startup process for WAL to arrive, during + streaming recovery. + + + SysLoggerMain + Waiting in main loop of syslogger process. + + + WalReceiverMain + Waiting in main loop of WAL receiver process. + + + WalSenderMain + Waiting in main loop of WAL sender process. + + + WalWriterMain + Waiting in main loop of WAL writer process. + + + +
+ + + Wait Events of Type <literal>BufferPin</literal> + + + + BufferPin Wait Event + Description + + + + + + BufferPin + Waiting to acquire an exclusive pin on a buffer. + + + +
+ + + Wait Events of Type <literal>Client</literal> + + + + Client Wait Event + Description + + + + + + ClientRead + Waiting to read data from the client. + + + ClientWrite + Waiting to write data to the client. + + + GSSOpenServer + Waiting to read data from the client while establishing a GSSAPI + session. + + + LibPQWalReceiverConnect + Waiting in WAL receiver to establish connection to remote + server. + + + LibPQWalReceiverReceive + Waiting in WAL receiver to receive data from remote server. + + + SSLOpenServer + Waiting for SSL while attempting connection. + + + WalSenderWaitForWAL + Waiting for WAL to be flushed in WAL sender process. + + + WalSenderWriteData + Waiting for any activity when processing replies from WAL + receiver in WAL sender process. + + + +
+ + + Wait Events of Type <literal>Extension</literal> + + + + Extension Wait Event + Description + + + + + + Extension + Waiting in an extension. + + + +
+ + + Wait Events of Type <literal>IO</literal> + + + + IO Wait Event + Description + + + + + + BaseBackupRead + Waiting for base backup to read from a file. + + + BufFileRead + Waiting for a read from a buffered file. + + + BufFileWrite + Waiting for a write to a buffered file. + + + BufFileTruncate + Waiting for a buffered file to be truncated. + + + ControlFileRead + Waiting for a read from the pg_control + file. + + + ControlFileSync + Waiting for the pg_control file to reach + durable storage. + + + ControlFileSyncUpdate + Waiting for an update to the pg_control file + to reach durable storage. + + + ControlFileWrite + Waiting for a write to the pg_control + file. + + + ControlFileWriteUpdate + Waiting for a write to update the pg_control + file. + + + CopyFileRead + Waiting for a read during a file copy operation. + + + CopyFileWrite + Waiting for a write during a file copy operation. + + + DSMFillZeroWrite + Waiting to fill a dynamic shared memory backing file with + zeroes. + + + DataFileExtend + Waiting for a relation data file to be extended. + + + DataFileFlush + Waiting for a relation data file to reach durable storage. + + + DataFileImmediateSync + Waiting for an immediate synchronization of a relation data file to + durable storage. + + + DataFilePrefetch + Waiting for an asynchronous prefetch from a relation data + file. + + + DataFileRead + Waiting for a read from a relation data file. + + + DataFileSync + Waiting for changes to a relation data file to reach durable storage. + + + DataFileTruncate + Waiting for a relation data file to be truncated. + + + DataFileWrite + Waiting for a write to a relation data file. + + + LockFileAddToDataDirRead + Waiting for a read while adding a line to the data directory lock + file. + + + LockFileAddToDataDirSync + Waiting for data to reach durable storage while adding a line to the + data directory lock file. + + + LockFileAddToDataDirWrite + Waiting for a write while adding a line to the data directory + lock file. + + + LockFileCreateRead + Waiting to read while creating the data directory lock + file. + + + LockFileCreateSync + Waiting for data to reach durable storage while creating the data + directory lock file. + + + LockFileCreateWrite + Waiting for a write while creating the data directory lock + file. + + + LockFileReCheckDataDirRead + Waiting for a read during recheck of the data directory lock + file. + + + LogicalRewriteCheckpointSync + Waiting for logical rewrite mappings to reach durable storage + during a checkpoint. + + + LogicalRewriteMappingSync + Waiting for mapping data to reach durable storage during a logical + rewrite. + + + LogicalRewriteMappingWrite + Waiting for a write of mapping data during a logical + rewrite. + + + LogicalRewriteSync + Waiting for logical rewrite mappings to reach durable + storage. + + + LogicalRewriteTruncate + Waiting for truncate of mapping data during a logical + rewrite. + + + LogicalRewriteWrite + Waiting for a write of logical rewrite mappings. + + + RelationMapRead + Waiting for a read of the relation map file. + + + RelationMapSync + Waiting for the relation map file to reach durable storage. + + + RelationMapWrite + Waiting for a write to the relation map file. + + + ReorderBufferRead + Waiting for a read during reorder buffer management. + + + ReorderBufferWrite + Waiting for a write during reorder buffer management. + + + ReorderLogicalMappingRead + Waiting for a read of a logical mapping during reorder buffer + management. + + + ReplicationSlotRead + Waiting for a read from a replication slot control file. + + + ReplicationSlotRestoreSync + Waiting for a replication slot control file to reach durable storage + while restoring it to memory. + + + ReplicationSlotSync + Waiting for a replication slot control file to reach durable + storage. + + + ReplicationSlotWrite + Waiting for a write to a replication slot control file. + + + SLRUFlushSync + Waiting for SLRU data to reach durable storage during a checkpoint + or database shutdown. + + + SLRURead + Waiting for a read of an SLRU page. + + + SLRUSync + Waiting for SLRU data to reach durable storage following a page + write. + + + SLRUWrite + Waiting for a write of an SLRU page. + + + SnapbuildRead + Waiting for a read of a serialized historical catalog + snapshot. + + + SnapbuildSync + Waiting for a serialized historical catalog snapshot to reach + durable storage. + + + SnapbuildWrite + Waiting for a write of a serialized historical catalog + snapshot. + + + TimelineHistoryFileSync + Waiting for a timeline history file received via streaming + replication to reach durable storage. + + + TimelineHistoryFileWrite + Waiting for a write of a timeline history file received via + streaming replication. + + + TimelineHistoryRead + Waiting for a read of a timeline history file. + + + TimelineHistorySync + Waiting for a newly created timeline history file to reach durable + storage. + + + TimelineHistoryWrite + Waiting for a write of a newly created timeline history + file. + + + TwophaseFileRead + Waiting for a read of a two phase state file. + + + TwophaseFileSync + Waiting for a two phase state file to reach durable storage. + + + TwophaseFileWrite + Waiting for a write of a two phase state file. + + + WALBootstrapSync + Waiting for WAL to reach durable storage during + bootstrapping. + + + WALBootstrapWrite + Waiting for a write of a WAL page during bootstrapping. + + + WALCopyRead + Waiting for a read when creating a new WAL segment by copying an + existing one. + + + WALCopySync + Waiting for a new WAL segment created by copying an existing one to + reach durable storage. + + + WALCopyWrite + Waiting for a write when creating a new WAL segment by copying an + existing one. + + + WALInitSync + Waiting for a newly initialized WAL file to reach durable + storage. + + + WALInitWrite + Waiting for a write while initializing a new WAL file. + + + WALRead + Waiting for a read from a WAL file. + + + WALSenderTimelineHistoryRead + Waiting for a read from a timeline history file during a walsender + timeline command. + + + WALSync + Waiting for a WAL file to reach durable storage. + + + WALSyncMethodAssign + Waiting for data to reach durable storage while assigning a new + WAL sync method. + + + WALWrite + Waiting for a write to a WAL file. + + + LogicalChangesRead + Waiting for a read from a logical changes file. + + + LogicalChangesWrite + Waiting for a write to a logical changes file. + + + LogicalSubxactRead + Waiting for a read from a logical subxact file. + + + LogicalSubxactWrite + Waiting for a write to a logical subxact file. + + + +
+ + + Wait Events of Type <literal>IPC</literal> + + + + IPC Wait Event + Description + + + + + + AppendReady + Waiting for subplan nodes of an Append plan + node to be ready. + + + BackendTermination + Waiting for the termination of another backend. + + + BackupWaitWalArchive + Waiting for WAL files required for a backup to be successfully + archived. + + + BgWorkerShutdown + Waiting for background worker to shut down. + + + BgWorkerStartup + Waiting for background worker to start up. + + + BtreePage + Waiting for the page number needed to continue a parallel B-tree + scan to become available. + + + BufferIO + Waiting for buffer I/O to complete. + + + CheckpointDone + Waiting for a checkpoint to complete. + + + CheckpointStart + Waiting for a checkpoint to start. + + + ExecuteGather + Waiting for activity from a child process while + executing a Gather plan node. + + + HashBatchAllocate + Waiting for an elected Parallel Hash participant to allocate a hash + table. + + + HashBatchElect + Waiting to elect a Parallel Hash participant to allocate a hash + table. + + + HashBatchLoad + Waiting for other Parallel Hash participants to finish loading a + hash table. + + + HashBuildAllocate + Waiting for an elected Parallel Hash participant to allocate the + initial hash table. + + + HashBuildElect + Waiting to elect a Parallel Hash participant to allocate the + initial hash table. + + + HashBuildHashInner + Waiting for other Parallel Hash participants to finish hashing the + inner relation. + + + HashBuildHashOuter + Waiting for other Parallel Hash participants to finish partitioning + the outer relation. + + + HashGrowBatchesAllocate + Waiting for an elected Parallel Hash participant to allocate more + batches. + + + HashGrowBatchesDecide + Waiting to elect a Parallel Hash participant to decide on future + batch growth. + + + HashGrowBatchesElect + Waiting to elect a Parallel Hash participant to allocate more + batches. + + + HashGrowBatchesFinish + Waiting for an elected Parallel Hash participant to decide on + future batch growth. + + + HashGrowBatchesRepartition + Waiting for other Parallel Hash participants to finish + repartitioning. + + + HashGrowBucketsAllocate + Waiting for an elected Parallel Hash participant to finish + allocating more buckets. + + + HashGrowBucketsElect + Waiting to elect a Parallel Hash participant to allocate more + buckets. + + + HashGrowBucketsReinsert + Waiting for other Parallel Hash participants to finish inserting + tuples into new buckets. + + + LogicalSyncData + Waiting for a logical replication remote server to send data for + initial table synchronization. + + + LogicalSyncStateChange + Waiting for a logical replication remote server to change + state. + + + MessageQueueInternal + Waiting for another process to be attached to a shared message + queue. + + + MessageQueuePutMessage + Waiting to write a protocol message to a shared message queue. + + + MessageQueueReceive + Waiting to receive bytes from a shared message queue. + + + MessageQueueSend + Waiting to send bytes to a shared message queue. + + + ParallelBitmapScan + Waiting for parallel bitmap scan to become initialized. + + + ParallelCreateIndexScan + Waiting for parallel CREATE INDEX workers to + finish heap scan. + + + ParallelFinish + Waiting for parallel workers to finish computing. + + + ProcArrayGroupUpdate + Waiting for the group leader to clear the transaction ID at + end of a parallel operation. + + + ProcSignalBarrier + Waiting for a barrier event to be processed by all + backends. + + + Promote + Waiting for standby promotion. + + + RecoveryConflictSnapshot + Waiting for recovery conflict resolution for a vacuum + cleanup. + + + RecoveryConflictTablespace + Waiting for recovery conflict resolution for dropping a + tablespace. + + + RecoveryPause + Waiting for recovery to be resumed. + + + ReplicationOriginDrop + Waiting for a replication origin to become inactive so it can be + dropped. + + + ReplicationSlotDrop + Waiting for a replication slot to become inactive so it can be + dropped. + + + SafeSnapshot + Waiting to obtain a valid snapshot for a READ ONLY + DEFERRABLE transaction. + + + SyncRep + Waiting for confirmation from a remote server during synchronous + replication. + + + WalReceiverExit + Waiting for the WAL receiver to exit. + + + WalReceiverWaitStart + Waiting for startup process to send initial data for streaming + replication. + + + XactGroupUpdate + Waiting for the group leader to update transaction status at + end of a parallel operation. + + + +
+ + + Wait Events of Type <literal>Lock</literal> + + + + Lock Wait Event + Description + + + + + + advisory + Waiting to acquire an advisory user lock. + + + extend + Waiting to extend a relation. + + + frozenid + Waiting to + update pg_database.datfrozenxid + and pg_database.datminmxid. + + + object + Waiting to acquire a lock on a non-relation database object. + + + page + Waiting to acquire a lock on a page of a relation. + + + relation + Waiting to acquire a lock on a relation. + + + spectoken + Waiting to acquire a speculative insertion lock. + + + transactionid + Waiting for a transaction to finish. + + + tuple + Waiting to acquire a lock on a tuple. + + + userlock + Waiting to acquire a user lock. + + + virtualxid + Waiting to acquire a virtual transaction ID lock. + + + +
+ + + Wait Events of Type <literal>LWLock</literal> + + + + LWLock Wait Event + Description + + + + + + AddinShmemInit + Waiting to manage an extension's space allocation in shared + memory. + + + AutoFile + Waiting to update the postgresql.auto.conf + file. + + + Autovacuum + Waiting to read or update the current state of autovacuum + workers. + + + AutovacuumSchedule + Waiting to ensure that a table selected for autovacuum + still needs vacuuming. + + + BackgroundWorker + Waiting to read or update background worker state. + + + BtreeVacuum + Waiting to read or update vacuum-related information for a + B-tree index. + + + BufferContent + Waiting to access a data page in memory. + + + BufferMapping + Waiting to associate a data block with a buffer in the buffer + pool. + + + CheckpointerComm + Waiting to manage fsync requests. + + + CommitTs + Waiting to read or update the last value set for a + transaction commit timestamp. + + + CommitTsBuffer + Waiting for I/O on a commit timestamp SLRU buffer. + + + CommitTsSLRU + Waiting to access the commit timestamp SLRU cache. + + + ControlFile + Waiting to read or update the pg_control + file or create a new WAL file. + + + DynamicSharedMemoryControl + Waiting to read or update dynamic shared memory allocation + information. + + + LockFastPath + Waiting to read or update a process' fast-path lock + information. + + + LockManager + Waiting to read or update information + about heavyweight locks. + + + LogicalRepWorker + Waiting to read or update the state of logical replication + workers. + + + MultiXactGen + Waiting to read or update shared multixact state. + + + MultiXactMemberBuffer + Waiting for I/O on a multixact member SLRU buffer. + + + MultiXactMemberSLRU + Waiting to access the multixact member SLRU cache. + + + MultiXactOffsetBuffer + Waiting for I/O on a multixact offset SLRU buffer. + + + MultiXactOffsetSLRU + Waiting to access the multixact offset SLRU cache. + + + MultiXactTruncation + Waiting to read or truncate multixact information. + + + NotifyBuffer + Waiting for I/O on a NOTIFY message SLRU + buffer. + + + NotifyQueue + Waiting to read or update NOTIFY messages. + + + NotifyQueueTail + Waiting to update limit on NOTIFY message + storage. + + + NotifySLRU + Waiting to access the NOTIFY message SLRU + cache. + + + OidGen + Waiting to allocate a new OID. + + + OldSnapshotTimeMap + Waiting to read or update old snapshot control information. + + + ParallelAppend + Waiting to choose the next subplan during Parallel Append plan + execution. + + + ParallelHashJoin + Waiting to synchronize workers during Parallel Hash Join plan + execution. + + + ParallelQueryDSA + Waiting for parallel query dynamic shared memory allocation. + + + PerSessionDSA + Waiting for parallel query dynamic shared memory allocation. + + + PerSessionRecordType + Waiting to access a parallel query's information about composite + types. + + + PerSessionRecordTypmod + Waiting to access a parallel query's information about type + modifiers that identify anonymous record types. + + + PerXactPredicateList + Waiting to access the list of predicate locks held by the current + serializable transaction during a parallel query. + + + PredicateLockManager + Waiting to access predicate lock information used by + serializable transactions. + + + ProcArray + Waiting to access the shared per-process data structures + (typically, to get a snapshot or report a session's transaction + ID). + + + RelationMapping + Waiting to read or update + a pg_filenode.map file (used to track the + filenode assignments of certain system catalogs). + + + RelCacheInit + Waiting to read or update a pg_internal.init + relation cache initialization file. + + + ReplicationOrigin + Waiting to create, drop or use a replication origin. + + + ReplicationOriginState + Waiting to read or update the progress of one replication + origin. + + + ReplicationSlotAllocation + Waiting to allocate or free a replication slot. + + + ReplicationSlotControl + Waiting to read or update replication slot state. + + + ReplicationSlotIO + Waiting for I/O on a replication slot. + + + SerialBuffer + Waiting for I/O on a serializable transaction conflict SLRU + buffer. + + + SerializableFinishedList + Waiting to access the list of finished serializable + transactions. + + + SerializablePredicateList + Waiting to access the list of predicate locks held by + serializable transactions. + + + SerializableXactHash + Waiting to read or update information about serializable + transactions. + + + SerialSLRU + Waiting to access the serializable transaction conflict SLRU + cache. + + + SharedTidBitmap + Waiting to access a shared TID bitmap during a parallel bitmap + index scan. + + + SharedTupleStore + Waiting to access a shared tuple store during parallel + query. + + + ShmemIndex + Waiting to find or allocate space in shared memory. + + + SInvalRead + Waiting to retrieve messages from the shared catalog invalidation + queue. + + + SInvalWrite + Waiting to add a message to the shared catalog invalidation + queue. + + + SubtransBuffer + Waiting for I/O on a sub-transaction SLRU buffer. + + + SubtransSLRU + Waiting to access the sub-transaction SLRU cache. + + + SyncRep + Waiting to read or update information about the state of + synchronous replication. + + + SyncScan + Waiting to select the starting location of a synchronized table + scan. + + + TablespaceCreate + Waiting to create or drop a tablespace. + + + TwoPhaseState + Waiting to read or update the state of prepared transactions. + + + WALBufMapping + Waiting to replace a page in WAL buffers. + + + WALInsert + Waiting to insert WAL data into a memory buffer. + + + WALWrite + Waiting for WAL buffers to be written to disk. + + + WrapLimitsVacuum + Waiting to update limits on transaction id and multixact + consumption. + + + XactBuffer + Waiting for I/O on a transaction status SLRU buffer. + + + XactSLRU + Waiting to access the transaction status SLRU cache. + + + XactTruncation + Waiting to execute pg_xact_status or update + the oldest transaction ID available to it. + + + XidGen + Waiting to allocate a new transaction ID. + + + +
+ + + + Extensions can add LWLock types to the list shown in + . In some cases, the name + assigned by an extension will not be available in all server processes; + so an LWLock wait event might be reported as + just extension rather than the + extension-assigned name. + + + + + Wait Events of Type <literal>Timeout</literal> + + + + Timeout Wait Event + Description + + + + + + BaseBackupThrottle + Waiting during base backup when throttling activity. + + + PgSleep + Waiting due to a call to pg_sleep or + a sibling function. + + + RecoveryApplyDelay + Waiting to apply WAL during recovery because of a delay + setting. + + + RecoveryRetrieveRetryInterval + Waiting during recovery when WAL data is not available from any + source (pg_wal, archive or stream). + + + VacuumDelay + Waiting in a cost-based vacuum delay point. + + + +
+ + + Here is an example of how wait events can be viewed: + + +SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL; + pid | wait_event_type | wait_event +------+-----------------+------------ + 2540 | Lock | relation + 6644 | LWLock | ProcArray +(2 rows) + + + +
+ + + <structname>pg_stat_replication</structname> + + + pg_stat_replication + + + + The pg_stat_replication view will contain one row + per WAL sender process, showing statistics about replication to that + sender's connected standby server. Only directly connected standbys are + listed; no information is available about downstream standby servers. + + + + <structname>pg_stat_replication</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of a WAL sender process + + + + + + usesysid oid + + + OID of the user logged into this WAL sender process + + + + + + usename name + + + Name of the user logged into this WAL sender process + + + + + + application_name text + + + Name of the application that is connected + to this WAL sender + + + + + + client_addr inet + + + IP address of the client connected to this WAL sender. + If this field is null, it indicates that the client is + connected via a Unix socket on the server machine. + + + + + + client_hostname text + + + Host name of the connected client, as reported by a + reverse DNS lookup of client_addr. This field will + only be non-null for IP connections, and only when is enabled. + + + + + + client_port integer + + + TCP port number that the client is using for communication + with this WAL sender, or -1 if a Unix socket is used + + + + + + backend_start timestamp with time zone + + + Time when this process was started, i.e., when the + client connected to this WAL sender + + + + + + backend_xmin xid + + + This standby's xmin horizon reported + by . + + + + + + state text + + + Current WAL sender state. + Possible values are: + + + + startup: This WAL sender is starting up. + + + + + catchup: This WAL sender's connected standby is + catching up with the primary. + + + + + streaming: This WAL sender is streaming changes + after its connected standby server has caught up with the primary. + + + + + backup: This WAL sender is sending a backup. + + + + + stopping: This WAL sender is stopping. + + + + + + + + + sent_lsn pg_lsn + + + Last write-ahead log location sent on this connection + + + + + + write_lsn pg_lsn + + + Last write-ahead log location written to disk by this standby + server + + + + + + flush_lsn pg_lsn + + + Last write-ahead log location flushed to disk by this standby + server + + + + + + replay_lsn pg_lsn + + + Last write-ahead log location replayed into the database on this + standby server + + + + + + write_lag interval + + + Time elapsed between flushing recent WAL locally and receiving + notification that this standby server has written it (but not yet + flushed it or applied it). This can be used to gauge the delay that + synchronous_commit level + remote_write incurred while committing if this + server was configured as a synchronous standby. + + + + + + flush_lag interval + + + Time elapsed between flushing recent WAL locally and receiving + notification that this standby server has written and flushed it + (but not yet applied it). This can be used to gauge the delay that + synchronous_commit level + on incurred while committing if this + server was configured as a synchronous standby. + + + + + + replay_lag interval + + + Time elapsed between flushing recent WAL locally and receiving + notification that this standby server has written, flushed and + applied it. This can be used to gauge the delay that + synchronous_commit level + remote_apply incurred while committing if this + server was configured as a synchronous standby. + + + + + + sync_priority integer + + + Priority of this standby server for being chosen as the + synchronous standby in a priority-based synchronous replication. + This has no effect in a quorum-based synchronous replication. + + + + + + sync_state text + + + Synchronous state of this standby server. + Possible values are: + + + + async: This standby server is asynchronous. + + + + + potential: This standby server is now asynchronous, + but can potentially become synchronous if one of current + synchronous ones fails. + + + + + sync: This standby server is synchronous. + + + + + quorum: This standby server is considered as a candidate + for quorum standbys. + + + + + + + + + reply_time timestamp with time zone + + + Send time of last reply message received from standby server + + + + +
+ + + The lag times reported in the pg_stat_replication + view are measurements of the time taken for recent WAL to be written, + flushed and replayed and for the sender to know about it. These times + represent the commit delay that was (or would have been) introduced by each + synchronous commit level, if the remote server was configured as a + synchronous standby. For an asynchronous standby, the + replay_lag column approximates the delay + before recent transactions became visible to queries. If the standby + server has entirely caught up with the sending server and there is no more + WAL activity, the most recently measured lag times will continue to be + displayed for a short time and then show NULL. + + + + Lag times work automatically for physical replication. Logical decoding + plugins may optionally emit tracking messages; if they do not, the tracking + mechanism will simply display NULL lag. + + + + + The reported lag times are not predictions of how long it will take for + the standby to catch up with the sending server assuming the current + rate of replay. Such a system would show similar times while new WAL is + being generated, but would differ when the sender becomes idle. In + particular, when the standby has caught up completely, + pg_stat_replication shows the time taken to + write, flush and replay the most recent reported WAL location rather than + zero as some users might expect. This is consistent with the goal of + measuring synchronous commit and transaction visibility delays for + recent write transactions. + To reduce confusion for users expecting a different model of lag, the + lag columns revert to NULL after a short time on a fully replayed idle + system. Monitoring systems should choose whether to represent this + as missing data, zero or continue to display the last known value. + + + +
+ + + <structname>pg_stat_replication_slots</structname> + + + pg_stat_replication_slots + + + + The pg_stat_replication_slots view will contain + one row per logical replication slot, showing statistics about its usage. + + + + <structname>pg_stat_replication_slots</structname> View + + + + + Column Type + + + Description + + + + + + + + slot_name text + + + A unique, cluster-wide identifier for the replication slot + + + + + + spill_txns bigint + + + Number of transactions spilled to disk once the memory used by + logical decoding to decode changes from WAL has exceeded + logical_decoding_work_mem. The counter gets + incremented for both toplevel transactions and subtransactions. + + + + + + spill_count bigint + + + Number of times transactions were spilled to disk while decoding + changes from WAL for this slot. This counter is incremented each time + a transaction is spilled, and the same transaction may be spilled + multiple times. + + + + + + spill_bytes bigint + + + Amount of decoded transaction data spilled to disk while performing + decoding of changes from WAL for this slot. This and other spill + counters can be used to gauge the I/O which occurred during logical + decoding and allow tuning logical_decoding_work_mem. + + + + + + stream_txns bigint + + + Number of in-progress transactions streamed to the decoding output + plugin after the memory used by logical decoding to decode changes + from WAL for this slot has exceeded + logical_decoding_work_mem. Streaming only + works with toplevel transactions (subtransactions can't be streamed + independently), so the counter is not incremented for subtransactions. + + + + + + stream_countbigint + + + Number of times in-progress transactions were streamed to the decoding + output plugin while decoding changes from WAL for this slot. This + counter is incremented each time a transaction is streamed, and the + same transaction may be streamed multiple times. + + + + + + stream_bytesbigint + + + Amount of transaction data decoded for streaming in-progress + transactions to the decoding output plugin while decoding changes from + WAL for this slot. This and other streaming counters for this slot can + be used to tune logical_decoding_work_mem. + + + + + + + total_txns bigint + + + Number of decoded transactions sent to the decoding output plugin for + this slot. This counts toplevel transactions only, and is not incremented + for subtransactions. Note that this includes the transactions that are + streamed and/or spilled. + + + + + + total_bytesbigint + + + Amount of transaction data decoded for sending transactions to the + decoding output plugin while decoding changes from WAL for this slot. + Note that this includes data that is streamed and/or spilled. + + + + + + + stats_reset timestamp with time zone + + + Time at which these statistics were last reset + + + + +
+ +
+ + + <structname>pg_stat_wal_receiver</structname> + + + pg_stat_wal_receiver + + + + The pg_stat_wal_receiver view will contain only + one row, showing statistics about the WAL receiver from that receiver's + connected server. + + + + <structname>pg_stat_wal_receiver</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of the WAL receiver process + + + + + + status text + + + Activity status of the WAL receiver process + + + + + + receive_start_lsn pg_lsn + + + First write-ahead log location used when WAL receiver is + started + + + + + + receive_start_tli integer + + + First timeline number used when WAL receiver is started + + + + + + written_lsn pg_lsn + + + Last write-ahead log location already received and written to disk, + but not flushed. This should not be used for data integrity checks. + + + + + + flushed_lsn pg_lsn + + + Last write-ahead log location already received and flushed to + disk, the initial value of this field being the first log location used + when WAL receiver is started + + + + + + received_tli integer + + + Timeline number of last write-ahead log location received and + flushed to disk, the initial value of this field being the timeline + number of the first log location used when WAL receiver is started + + + + + + last_msg_send_time timestamp with time zone + + + Send time of last message received from origin WAL sender + + + + + + last_msg_receipt_time timestamp with time zone + + + Receipt time of last message received from origin WAL sender + + + + + + latest_end_lsn pg_lsn + + + Last write-ahead log location reported to origin WAL sender + + + + + + latest_end_time timestamp with time zone + + + Time of last write-ahead log location reported to origin WAL sender + + + + + + slot_name text + + + Replication slot name used by this WAL receiver + + + + + + sender_host text + + + Host of the PostgreSQL instance + this WAL receiver is connected to. This can be a host name, + an IP address, or a directory path if the connection is via + Unix socket. (The path case can be distinguished because it + will always be an absolute path, beginning with /.) + + + + + + sender_port integer + + + Port number of the PostgreSQL instance + this WAL receiver is connected to. + + + + + + conninfo text + + + Connection string used by this WAL receiver, + with security-sensitive fields obfuscated. + + + + +
+ +
+ + + <structname>pg_stat_subscription</structname> + + + pg_stat_subscription + + + + The pg_stat_subscription view will contain one + row per subscription for main worker (with null PID if the worker is + not running), and additional rows for workers handling the initial data + copy of the subscribed tables. + + + + <structname>pg_stat_subscription</structname> View + + + + + Column Type + + + Description + + + + + + + + subid oid + + + OID of the subscription + + + + + + subname name + + + Name of the subscription + + + + + + pid integer + + + Process ID of the subscription worker process + + + + + + relid oid + + + OID of the relation that the worker is synchronizing; null for the + main apply worker + + + + + + received_lsn pg_lsn + + + Last write-ahead log location received, the initial value of + this field being 0 + + + + + + last_msg_send_time timestamp with time zone + + + Send time of last message received from origin WAL sender + + + + + + last_msg_receipt_time timestamp with time zone + + + Receipt time of last message received from origin WAL sender + + + + + + latest_end_lsn pg_lsn + + + Last write-ahead log location reported to origin WAL sender + + + + + + latest_end_time timestamp with time zone + + + Time of last write-ahead log location reported to origin WAL + sender + + + + +
+ +
+ + + <structname>pg_stat_ssl</structname> + + + pg_stat_ssl + + + + The pg_stat_ssl view will contain one row per + backend or WAL sender process, showing statistics about SSL usage on + this connection. It can be joined to pg_stat_activity + or pg_stat_replication on the + pid column to get more details about the + connection. + + + + <structname>pg_stat_ssl</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of a backend or WAL sender process + + + + + + ssl boolean + + + True if SSL is used on this connection + + + + + + version text + + + Version of SSL in use, or NULL if SSL is not in use + on this connection + + + + + + cipher text + + + Name of SSL cipher in use, or NULL if SSL is not in use + on this connection + + + + + + bits integer + + + Number of bits in the encryption algorithm used, or NULL + if SSL is not used on this connection + + + + + + client_dn text + + + Distinguished Name (DN) field from the client certificate + used, or NULL if no client certificate was supplied or if SSL + is not in use on this connection. This field is truncated if the + DN field is longer than NAMEDATALEN (64 characters + in a standard build). + + + + + + client_serial numeric + + + Serial number of the client certificate, or NULL if no client + certificate was supplied or if SSL is not in use on this connection. The + combination of certificate serial number and certificate issuer uniquely + identifies a certificate (unless the issuer erroneously reuses serial + numbers). + + + + + + issuer_dn text + + + DN of the issuer of the client certificate, or NULL if no client + certificate was supplied or if SSL is not in use on this connection. + This field is truncated like client_dn. + + + + +
+ +
+ + + <structname>pg_stat_gssapi</structname> + + + pg_stat_gssapi + + + + The pg_stat_gssapi view will contain one row per + backend, showing information about GSSAPI usage on this connection. It can + be joined to pg_stat_activity or + pg_stat_replication on the + pid column to get more details about the + connection. + + + + <structname>pg_stat_gssapi</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of a backend + + + + + + gss_authenticated boolean + + + True if GSSAPI authentication was used for this connection + + + + + + principal text + + + Principal used to authenticate this connection, or NULL + if GSSAPI was not used to authenticate this connection. This + field is truncated if the principal is longer than + NAMEDATALEN (64 characters in a standard build). + + + + + + encrypted boolean + + + True if GSSAPI encryption is in use on this connection + + + + +
+ +
+ + + <structname>pg_stat_archiver</structname> + + + pg_stat_archiver + + + + The pg_stat_archiver view will always have a + single row, containing data about the archiver process of the cluster. + + + + <structname>pg_stat_archiver</structname> View + + + + + Column Type + + + Description + + + + + + + + archived_count bigint + + + Number of WAL files that have been successfully archived + + + + + + last_archived_wal text + + + Name of the last WAL file successfully archived + + + + + + last_archived_time timestamp with time zone + + + Time of the last successful archive operation + + + + + + failed_count bigint + + + Number of failed attempts for archiving WAL files + + + + + + last_failed_wal text + + + Name of the WAL file of the last failed archival operation + + + + + + last_failed_time timestamp with time zone + + + Time of the last failed archival operation + + + + + + stats_reset timestamp with time zone + + + Time at which these statistics were last reset + + + + +
+ +
+ + + <structname>pg_stat_bgwriter</structname> + + + pg_stat_bgwriter + + + + The pg_stat_bgwriter view will always have a + single row, containing global data for the cluster. + + + + <structname>pg_stat_bgwriter</structname> View + + + + + Column Type + + + Description + + + + + + + + checkpoints_timed bigint + + + Number of scheduled checkpoints that have been performed + + + + + + checkpoints_req bigint + + + Number of requested checkpoints that have been performed + + + + + + checkpoint_write_time double precision + + + Total amount of time that has been spent in the portion of + checkpoint processing where files are written to disk, in milliseconds + + + + + + checkpoint_sync_time double precision + + + Total amount of time that has been spent in the portion of + checkpoint processing where files are synchronized to disk, in + milliseconds + + + + + + buffers_checkpoint bigint + + + Number of buffers written during checkpoints + + + + + + buffers_clean bigint + + + Number of buffers written by the background writer + + + + + + maxwritten_clean bigint + + + Number of times the background writer stopped a cleaning + scan because it had written too many buffers + + + + + + buffers_backend bigint + + + Number of buffers written directly by a backend + + + + + + buffers_backend_fsync bigint + + + Number of times a backend had to execute its own + fsync call (normally the background writer handles those + even when the backend does its own write) + + + + + + buffers_alloc bigint + + + Number of buffers allocated + + + + + + stats_reset timestamp with time zone + + + Time at which these statistics were last reset + + + + +
+ +
+ + + <structname>pg_stat_wal</structname> + + + pg_stat_wal + + + + The pg_stat_wal view will always have a + single row, containing data about WAL activity of the cluster. + + + + <structname>pg_stat_wal</structname> View + + + + + Column Type + + + Description + + + + + + + + wal_records bigint + + + Total number of WAL records generated + + + + + + wal_fpi bigint + + + Total number of WAL full page images generated + + + + + + wal_bytes numeric + + + Total amount of WAL generated in bytes + + + + + + wal_buffers_full bigint + + + Number of times WAL data was written to disk because WAL buffers became full + + + + + + wal_write bigint + + + Number of times WAL buffers were written out to disk via + XLogWrite request. + See for more information about + the internal WAL function XLogWrite. + + + + + + wal_sync bigint + + + Number of times WAL files were synced to disk via + issue_xlog_fsync request + (if is on and + is either + fdatasync, fsync or + fsync_writethrough, otherwise zero). + See for more information about + the internal WAL function issue_xlog_fsync. + + + + + + wal_write_time double precision + + + Total amount of time spent writing WAL buffers to disk via + XLogWrite request, in milliseconds + (if is enabled, + otherwise zero). This includes the sync time when + wal_sync_method is either + open_datasync or open_sync. + + + + + + wal_sync_time double precision + + + Total amount of time spent syncing WAL files to disk via + issue_xlog_fsync request, in milliseconds + (if track_wal_io_timing is enabled, + fsync is on, and + wal_sync_method is either + fdatasync, fsync or + fsync_writethrough, otherwise zero). + + + + + + stats_reset timestamp with time zone + + + Time at which these statistics were last reset + + + + +
+ +
+ + + <structname>pg_stat_database</structname> + + + pg_stat_database + + + + The pg_stat_database view will contain one row + for each database in the cluster, plus one for shared objects, showing + database-wide statistics. + + + + <structname>pg_stat_database</structname> View + + + + + Column Type + + + Description + + + + + + + + datid oid + + + OID of this database, or 0 for objects belonging to a shared + relation + + + + + + datname name + + + Name of this database, or NULL for shared + objects. + + + + + + numbackends integer + + + Number of backends currently connected to this database, or + NULL for shared objects. This is the only column + in this view that returns a value reflecting current state; all other + columns return the accumulated values since the last reset. + + + + + + xact_commit bigint + + + Number of transactions in this database that have been + committed + + + + + + xact_rollback bigint + + + Number of transactions in this database that have been + rolled back + + + + + + blks_read bigint + + + Number of disk blocks read in this database + + + + + + blks_hit bigint + + + Number of times disk blocks were found already in the buffer + cache, so that a read was not necessary (this only includes hits in the + PostgreSQL buffer cache, not the operating system's file system cache) + + + + + + tup_returned bigint + + + Number of rows returned by queries in this database + + + + + + tup_fetched bigint + + + Number of rows fetched by queries in this database + + + + + + tup_inserted bigint + + + Number of rows inserted by queries in this database + + + + + + tup_updated bigint + + + Number of rows updated by queries in this database + + + + + + tup_deleted bigint + + + Number of rows deleted by queries in this database + + + + + + conflicts bigint + + + Number of queries canceled due to conflicts with recovery + in this database. (Conflicts occur only on standby servers; see + + pg_stat_database_conflicts for details.) + + + + + + temp_files bigint + + + Number of temporary files created by queries in this database. + All temporary files are counted, regardless of why the temporary file + was created (e.g., sorting or hashing), and regardless of the + setting. + + + + + + temp_bytes bigint + + + Total amount of data written to temporary files by queries in + this database. All temporary files are counted, regardless of why + the temporary file was created, and + regardless of the setting. + + + + + + deadlocks bigint + + + Number of deadlocks detected in this database + + + + + + checksum_failures bigint + + + Number of data page checksum failures detected in this + database (or on a shared object), or NULL if data checksums are not + enabled. + + + + + + checksum_last_failure timestamp with time zone + + + Time at which the last data page checksum failure was detected in + this database (or on a shared object), or NULL if data checksums are not + enabled. + + + + + + blk_read_time double precision + + + Time spent reading data file blocks by backends in this database, + in milliseconds (if is enabled, + otherwise zero) + + + + + + blk_write_time double precision + + + Time spent writing data file blocks by backends in this database, + in milliseconds (if is enabled, + otherwise zero) + + + + + + session_time double precision + + + Time spent by database sessions in this database, in milliseconds + (note that statistics are only updated when the state of a session + changes, so if sessions have been idle for a long time, this idle time + won't be included) + + + + + + active_time double precision + + + Time spent executing SQL statements in this database, in milliseconds + (this corresponds to the states active and + fastpath function call in + + pg_stat_activity) + + + + + + idle_in_transaction_time double precision + + + Time spent idling while in a transaction in this database, in milliseconds + (this corresponds to the states idle in transaction and + idle in transaction (aborted) in + + pg_stat_activity) + + + + + + sessions bigint + + + Total number of sessions established to this database + + + + + + sessions_abandoned bigint + + + Number of database sessions to this database that were terminated + because connection to the client was lost + + + + + + sessions_fatal bigint + + + Number of database sessions to this database that were terminated + by fatal errors + + + + + + sessions_killed bigint + + + Number of database sessions to this database that were terminated + by operator intervention + + + + + + stats_reset timestamp with time zone + + + Time at which these statistics were last reset + + + + +
+ +
+ + + <structname>pg_stat_database_conflicts</structname> + + + pg_stat_database_conflicts + + + + The pg_stat_database_conflicts view will contain + one row per database, showing database-wide statistics about + query cancels occurring due to conflicts with recovery on standby servers. + This view will only contain information on standby servers, since + conflicts do not occur on primary servers. + + + + <structname>pg_stat_database_conflicts</structname> View + + + + + Column Type + + + Description + + + + + + + + datid oid + + + OID of a database + + + + + + datname name + + + Name of this database + + + + + + confl_tablespace bigint + + + Number of queries in this database that have been canceled due to + dropped tablespaces + + + + + + confl_lock bigint + + + Number of queries in this database that have been canceled due to + lock timeouts + + + + + + confl_snapshot bigint + + + Number of queries in this database that have been canceled due to + old snapshots + + + + + + confl_bufferpin bigint + + + Number of queries in this database that have been canceled due to + pinned buffers + + + + + + confl_deadlock bigint + + + Number of queries in this database that have been canceled due to + deadlocks + + + + +
+ +
+ + + <structname>pg_stat_all_tables</structname> + + + pg_stat_all_tables + + + + The pg_stat_all_tables view will contain + one row for each table in the current database (including TOAST + tables), showing statistics about accesses to that specific table. The + pg_stat_user_tables and + pg_stat_sys_tables views + contain the same information, + but filtered to only show user and system tables respectively. + + + + <structname>pg_stat_all_tables</structname> View + + + + + Column Type + + + Description + + + + + + + + relid oid + + + OID of a table + + + + + + schemaname name + + + Name of the schema that this table is in + + + + + + relname name + + + Name of this table + + + + + + seq_scan bigint + + + Number of sequential scans initiated on this table + + + + + + seq_tup_read bigint + + + Number of live rows fetched by sequential scans + + + + + + idx_scan bigint + + + Number of index scans initiated on this table + + + + + + idx_tup_fetch bigint + + + Number of live rows fetched by index scans + + + + + + n_tup_ins bigint + + + Number of rows inserted + + + + + + n_tup_upd bigint + + + Number of rows updated (includes HOT updated rows) + + + + + + n_tup_del bigint + + + Number of rows deleted + + + + + + n_tup_hot_upd bigint + + + Number of rows HOT updated (i.e., with no separate index + update required) + + + + + + n_live_tup bigint + + + Estimated number of live rows + + + + + + n_dead_tup bigint + + + Estimated number of dead rows + + + + + + n_mod_since_analyze bigint + + + Estimated number of rows modified since this table was last analyzed + + + + + + n_ins_since_vacuum bigint + + + Estimated number of rows inserted since this table was last vacuumed + + + + + + last_vacuum timestamp with time zone + + + Last time at which this table was manually vacuumed + (not counting VACUUM FULL) + + + + + + last_autovacuum timestamp with time zone + + + Last time at which this table was vacuumed by the autovacuum + daemon + + + + + + last_analyze timestamp with time zone + + + Last time at which this table was manually analyzed + + + + + + last_autoanalyze timestamp with time zone + + + Last time at which this table was analyzed by the autovacuum + daemon + + + + + + vacuum_count bigint + + + Number of times this table has been manually vacuumed + (not counting VACUUM FULL) + + + + + + autovacuum_count bigint + + + Number of times this table has been vacuumed by the autovacuum + daemon + + + + + + analyze_count bigint + + + Number of times this table has been manually analyzed + + + + + + autoanalyze_count bigint + + + Number of times this table has been analyzed by the autovacuum + daemon + + + + +
+ +
+ + + <structname>pg_stat_all_indexes</structname> + + + pg_stat_all_indexes + + + + The pg_stat_all_indexes view will contain + one row for each index in the current database, + showing statistics about accesses to that specific index. The + pg_stat_user_indexes and + pg_stat_sys_indexes views + contain the same information, + but filtered to only show user and system indexes respectively. + + + + <structname>pg_stat_all_indexes</structname> View + + + + + Column Type + + + Description + + + + + + + + relid oid + + + OID of the table for this index + + + + + + indexrelid oid + + + OID of this index + + + + + + schemaname name + + + Name of the schema this index is in + + + + + + relname name + + + Name of the table for this index + + + + + + indexrelname name + + + Name of this index + + + + + + idx_scan bigint + + + Number of index scans initiated on this index + + + + + + idx_tup_read bigint + + + Number of index entries returned by scans on this index + + + + + + idx_tup_fetch bigint + + + Number of live table rows fetched by simple index scans using this + index + + + + +
+ + + Indexes can be used by simple index scans, bitmap index scans, + and the optimizer. In a bitmap scan + the output of several indexes can be combined via AND or OR rules, + so it is difficult to associate individual heap row fetches + with specific indexes when a bitmap scan is used. Therefore, a bitmap + scan increments the + pg_stat_all_indexes.idx_tup_read + count(s) for the index(es) it uses, and it increments the + pg_stat_all_tables.idx_tup_fetch + count for the table, but it does not affect + pg_stat_all_indexes.idx_tup_fetch. + The optimizer also accesses indexes to check for supplied constants + whose values are outside the recorded range of the optimizer statistics + because the optimizer statistics might be stale. + + + + + The idx_tup_read and idx_tup_fetch counts + can be different even without any use of bitmap scans, + because idx_tup_read counts + index entries retrieved from the index while idx_tup_fetch + counts live rows fetched from the table. The latter will be less if any + dead or not-yet-committed rows are fetched using the index, or if any + heap fetches are avoided by means of an index-only scan. + + + +
+ + + <structname>pg_statio_all_tables</structname> + + + pg_statio_all_tables + + + + The pg_statio_all_tables view will contain + one row for each table in the current database (including TOAST + tables), showing statistics about I/O on that specific table. The + pg_statio_user_tables and + pg_statio_sys_tables views + contain the same information, + but filtered to only show user and system tables respectively. + + + + <structname>pg_statio_all_tables</structname> View + + + + + Column Type + + + Description + + + + + + + + relid oid + + + OID of a table + + + + + + schemaname name + + + Name of the schema that this table is in + + + + + + relname name + + + Name of this table + + + + + + heap_blks_read bigint + + + Number of disk blocks read from this table + + + + + + heap_blks_hit bigint + + + Number of buffer hits in this table + + + + + + idx_blks_read bigint + + + Number of disk blocks read from all indexes on this table + + + + + + idx_blks_hit bigint + + + Number of buffer hits in all indexes on this table + + + + + + toast_blks_read bigint + + + Number of disk blocks read from this table's TOAST table (if any) + + + + + + toast_blks_hit bigint + + + Number of buffer hits in this table's TOAST table (if any) + + + + + + tidx_blks_read bigint + + + Number of disk blocks read from this table's TOAST table indexes (if any) + + + + + + tidx_blks_hit bigint + + + Number of buffer hits in this table's TOAST table indexes (if any) + + + + +
+ +
+ + + <structname>pg_statio_all_indexes</structname> + + + pg_statio_all_indexes + + + + The pg_statio_all_indexes view will contain + one row for each index in the current database, + showing statistics about I/O on that specific index. The + pg_statio_user_indexes and + pg_statio_sys_indexes views + contain the same information, + but filtered to only show user and system indexes respectively. + + + + <structname>pg_statio_all_indexes</structname> View + + + + + Column Type + + + Description + + + + + + + + relid oid + + + OID of the table for this index + + + + + + indexrelid oid + + + OID of this index + + + + + + schemaname name + + + Name of the schema this index is in + + + + + + relname name + + + Name of the table for this index + + + + + + indexrelname name + + + Name of this index + + + + + + idx_blks_read bigint + + + Number of disk blocks read from this index + + + + + + idx_blks_hit bigint + + + Number of buffer hits in this index + + + + +
+ +
+ + + <structname>pg_statio_all_sequences</structname> + + + pg_statio_all_sequences + + + + The pg_statio_all_sequences view will contain + one row for each sequence in the current database, + showing statistics about I/O on that specific sequence. + + + + <structname>pg_statio_all_sequences</structname> View + + + + + Column Type + + + Description + + + + + + + + relid oid + + + OID of a sequence + + + + + + schemaname name + + + Name of the schema this sequence is in + + + + + + relname name + + + Name of this sequence + + + + + + blks_read bigint + + + Number of disk blocks read from this sequence + + + + + + blks_hit bigint + + + Number of buffer hits in this sequence + + + + +
+ +
+ + + <structname>pg_stat_user_functions</structname> + + + pg_stat_user_functions + + + + The pg_stat_user_functions view will contain + one row for each tracked function, showing statistics about executions of + that function. The parameter + controls exactly which functions are tracked. + + + + <structname>pg_stat_user_functions</structname> View + + + + + Column Type + + + Description + + + + + + + + funcid oid + + + OID of a function + + + + + + schemaname name + + + Name of the schema this function is in + + + + + + funcname name + + + Name of this function + + + + + + calls bigint + + + Number of times this function has been called + + + + + + total_time double precision + + + Total time spent in this function and all other functions + called by it, in milliseconds + + + + + + self_time double precision + + + Total time spent in this function itself, not including + other functions called by it, in milliseconds + + + + +
+ +
+ + + <structname>pg_stat_slru</structname> + + + SLRU + + + + pg_stat_slru + + + + PostgreSQL accesses certain on-disk information + via SLRU (simple least-recently-used) caches. + The pg_stat_slru view will contain + one row for each tracked SLRU cache, showing statistics about access + to cached pages. + + + + <structname>pg_stat_slru</structname> View + + + + + Column Type + + + Description + + + + + + + + name text + + + Name of the SLRU + + + + + + blks_zeroed bigint + + + Number of blocks zeroed during initializations + + + + + + blks_hit bigint + + + Number of times disk blocks were found already in the SLRU, + so that a read was not necessary (this only includes hits in the + SLRU, not the operating system's file system cache) + + + + + + blks_read bigint + + + Number of disk blocks read for this SLRU + + + + + + blks_written bigint + + + Number of disk blocks written for this SLRU + + + + + + blks_exists bigint + + + Number of blocks checked for existence for this SLRU + + + + + + flushes bigint + + + Number of flushes of dirty data for this SLRU + + + + + + truncates bigint + + + Number of truncates for this SLRU + + + + + + stats_reset timestamp with time zone + + + Time at which these statistics were last reset + + + + +
+ +
+ + + Statistics Functions + + + Other ways of looking at the statistics can be set up by writing + queries that use the same underlying statistics access functions used by + the standard views shown above. For details such as the functions' names, + consult the definitions of the standard views. (For example, in + psql you could issue \d+ pg_stat_activity.) + The access functions for per-database statistics take a database OID as an + argument to identify which database to report on. + The per-table and per-index functions take a table or index OID. + The functions for per-function statistics take a function OID. + Note that only tables, indexes, and functions in the current database + can be seen with these functions. + + + + Additional functions related to statistics collection are listed in . + + + + Additional Statistics Functions + + + + + Function + + + Description + + + + + + + + + pg_backend_pid () + integer + + + Returns the process ID of the server process attached to the current + session. + + + + + + + pg_stat_get_activity + + pg_stat_get_activity ( integer ) + setof record + + + Returns a record of information about the backend with the specified + process ID, or one record for each active backend in the system + if NULL is specified. The fields returned are a + subset of those in the pg_stat_activity view. + + + + + + + pg_stat_get_snapshot_timestamp + + pg_stat_get_snapshot_timestamp () + timestamp with time zone + + + Returns the timestamp of the current statistics snapshot. + + + + + + + pg_stat_clear_snapshot + + pg_stat_clear_snapshot () + void + + + Discards the current statistics snapshot. + + + + + + + pg_stat_reset + + pg_stat_reset () + void + + + Resets all statistics counters for the current database to zero. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_stat_reset_shared + + pg_stat_reset_shared ( text ) + void + + + Resets some cluster-wide statistics counters to zero, depending on the + argument. The argument can be bgwriter to reset + all the counters shown in + the pg_stat_bgwriter + view, archiver to reset all the counters shown in + the pg_stat_archiver view or wal + to reset all the counters shown in the pg_stat_wal view. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_stat_reset_single_table_counters + + pg_stat_reset_single_table_counters ( oid ) + void + + + Resets statistics for a single table or index in the current database + to zero. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_stat_reset_single_function_counters + + pg_stat_reset_single_function_counters ( oid ) + void + + + Resets statistics for a single function in the current database to + zero. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_stat_reset_slru + + pg_stat_reset_slru ( text ) + void + + + Resets statistics to zero for a single SLRU cache, or for all SLRUs in + the cluster. If the argument is NULL, all counters shown in + the pg_stat_slru view for all SLRU caches are + reset. The argument can be one of + CommitTs, + MultiXactMember, + MultiXactOffset, + Notify, + Serial, + Subtrans, or + Xact + to reset the counters for only that entry. + If the argument is other (or indeed, any + unrecognized name), then the counters for all other SLRU caches, such + as extension-defined caches, are reset. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + + + + pg_stat_reset_replication_slot + + pg_stat_reset_replication_slot ( text ) + void + + + Resets statistics of the replication slot defined by the argument. If + the argument is NULL, resets statistics for all + the replication slots. + + + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + + + +
+ + + pg_stat_get_activity, the underlying function of + the pg_stat_activity view, returns a set of records + containing all the available information about each backend process. + Sometimes it may be more convenient to obtain just a subset of this + information. In such cases, an older set of per-backend statistics + access functions can be used; these are shown in . + These access functions use a backend ID number, which ranges from one + to the number of currently active backends. + The function pg_stat_get_backend_idset provides a + convenient way to generate one row for each active backend for + invoking these functions. For example, to show the PIDs and + current queries of all backends: + + +SELECT pg_stat_get_backend_pid(s.backendid) AS pid, + pg_stat_get_backend_activity(s.backendid) AS query + FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s; + + + + + Per-Backend Statistics Functions + + + + + Function + + + Description + + + + + + + + + pg_stat_get_backend_idset + + pg_stat_get_backend_idset () + setof integer + + + Returns the set of currently active backend ID numbers (from 1 to the + number of active backends). + + + + + + + pg_stat_get_backend_activity + + pg_stat_get_backend_activity ( integer ) + text + + + Returns the text of this backend's most recent query. + + + + + + + pg_stat_get_backend_activity_start + + pg_stat_get_backend_activity_start ( integer ) + timestamp with time zone + + + Returns the time when the backend's most recent query was started. + + + + + + + pg_stat_get_backend_client_addr + + pg_stat_get_backend_client_addr ( integer ) + inet + + + Returns the IP address of the client connected to this backend. + + + + + + + pg_stat_get_backend_client_port + + pg_stat_get_backend_client_port ( integer ) + integer + + + Returns the TCP port number that the client is using for communication. + + + + + + + pg_stat_get_backend_dbid + + pg_stat_get_backend_dbid ( integer ) + oid + + + Returns the OID of the database this backend is connected to. + + + + + + + pg_stat_get_backend_pid + + pg_stat_get_backend_pid ( integer ) + integer + + + Returns the process ID of this backend. + + + + + + + pg_stat_get_backend_start + + pg_stat_get_backend_start ( integer ) + timestamp with time zone + + + Returns the time when this process was started. + + + + + + + pg_stat_get_backend_userid + + pg_stat_get_backend_userid ( integer ) + oid + + + Returns the OID of the user logged into this backend. + + + + + + + pg_stat_get_backend_wait_event_type + + pg_stat_get_backend_wait_event_type ( integer ) + text + + + Returns the wait event type name if this backend is currently waiting, + otherwise NULL. See for details. + + + + + + + pg_stat_get_backend_wait_event + + pg_stat_get_backend_wait_event ( integer ) + text + + + Returns the wait event name if this backend is currently waiting, + otherwise NULL. See through + . + + + + + + + pg_stat_get_backend_xact_start + + pg_stat_get_backend_xact_start ( integer ) + timestamp with time zone + + + Returns the time when the backend's current transaction was started. + + + + +
+ +
+
+ + + Viewing Locks + + + lock + monitoring + + + + Another useful tool for monitoring database activity is the + pg_locks system table. It allows the + database administrator to view information about the outstanding + locks in the lock manager. For example, this capability can be used + to: + + + + + View all the locks currently outstanding, all the locks on + relations in a particular database, all the locks on a + particular relation, or all the locks held by a particular + PostgreSQL session. + + + + + + Determine the relation in the current database with the most + ungranted locks (which might be a source of contention among + database clients). + + + + + + Determine the effect of lock contention on overall database + performance, as well as the extent to which contention varies + with overall database traffic. + + + + + Details of the pg_locks view appear in + . + For more information on locking and managing concurrency with + PostgreSQL, refer to . + + + + + Progress Reporting + + + PostgreSQL has the ability to report the progress of + certain commands during command execution. Currently, the only commands + which support progress reporting are ANALYZE, + CLUSTER, + CREATE INDEX, VACUUM, + COPY, + and (i.e., replication + command that issues to take + a base backup). + This may be expanded in the future. + + + + ANALYZE Progress Reporting + + + pg_stat_progress_analyze + + + + Whenever ANALYZE is running, the + pg_stat_progress_analyze view will contain a + row for each backend that is currently running that command. The tables + below describe the information that will be reported and provide + information about how to interpret it. + + + + <structname>pg_stat_progress_analyze</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of backend. + + + + + + datid oid + + + OID of the database to which this backend is connected. + + + + + + datname name + + + Name of the database to which this backend is connected. + + + + + + relid oid + + + OID of the table being analyzed. + + + + + + phase text + + + Current processing phase. See . + + + + + + sample_blks_total bigint + + + Total number of heap blocks that will be sampled. + + + + + + sample_blks_scanned bigint + + + Number of heap blocks scanned. + + + + + + ext_stats_total bigint + + + Number of extended statistics. + + + + + + ext_stats_computed bigint + + + Number of extended statistics computed. This counter only advances + when the phase is computing extended statistics. + + + + + + child_tables_total bigint + + + Number of child tables. + + + + + + child_tables_done bigint + + + Number of child tables scanned. This counter only advances when the + phase is acquiring inherited sample rows. + + + + + + current_child_table_relid oid + + + OID of the child table currently being scanned. This field is + only valid when the phase is + acquiring inherited sample rows. + + + + +
+ + + ANALYZE phases + + + + + + Phase + Description + + + + + initializing + + The command is preparing to begin scanning the heap. This phase is + expected to be very brief. + + + + acquiring sample rows + + The command is currently scanning the table given by + relid to obtain sample rows. + + + + acquiring inherited sample rows + + The command is currently scanning child tables to obtain sample rows. + Columns child_tables_total, + child_tables_done, and + current_child_table_relid contain the + progress information for this phase. + + + + computing statistics + + The command is computing statistics from the sample rows obtained + during the table scan. + + + + computing extended statistics + + The command is computing extended statistics from the sample rows + obtained during the table scan. + + + + finalizing analyze + + The command is updating pg_class. When this + phase is completed, ANALYZE will end. + + + + +
+ + + + Note that when ANALYZE is run on a partitioned table, + all of its partitions are also recursively analyzed. + In that case, ANALYZE + progress is reported first for the parent table, whereby its inheritance + statistics are collected, followed by that for each partition. + + +
+ + + CREATE INDEX Progress Reporting + + + pg_stat_progress_create_index + + + + Whenever CREATE INDEX or REINDEX is running, the + pg_stat_progress_create_index view will contain + one row for each backend that is currently creating indexes. The tables + below describe the information that will be reported and provide information + about how to interpret it. + + + + <structname>pg_stat_progress_create_index</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of backend. + + + + + + datid oid + + + OID of the database to which this backend is connected. + + + + + + datname name + + + Name of the database to which this backend is connected. + + + + + + relid oid + + + OID of the table on which the index is being created. + + + + + + index_relid oid + + + OID of the index being created or reindexed. During a + non-concurrent CREATE INDEX, this is 0. + + + + + + command text + + + The command that is running: CREATE INDEX, + CREATE INDEX CONCURRENTLY, + REINDEX, or REINDEX CONCURRENTLY. + + + + + + phase text + + + Current processing phase of index creation. See . + + + + + + lockers_total bigint + + + Total number of lockers to wait for, when applicable. + + + + + + lockers_done bigint + + + Number of lockers already waited for. + + + + + + current_locker_pid bigint + + + Process ID of the locker currently being waited for. + + + + + + blocks_total bigint + + + Total number of blocks to be processed in the current phase. + + + + + + blocks_done bigint + + + Number of blocks already processed in the current phase. + + + + + + tuples_total bigint + + + Total number of tuples to be processed in the current phase. + + + + + + tuples_done bigint + + + Number of tuples already processed in the current phase. + + + + + + partitions_total bigint + + + When creating an index on a partitioned table, this column is set to + the total number of partitions on which the index is to be created. + This field is 0 during a REINDEX. + + + + + + partitions_done bigint + + + When creating an index on a partitioned table, this column is set to + the number of partitions on which the index has been created. + This field is 0 during a REINDEX. + + + + +
+ + + CREATE INDEX Phases + + + + + + Phase + Description + + + + + initializing + + CREATE INDEX or REINDEX is preparing to create the index. This + phase is expected to be very brief. + + + + waiting for writers before build + + CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY is waiting for transactions + with write locks that can potentially see the table to finish. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + building index + + The index is being built by the access method-specific code. In this phase, + access methods that support progress reporting fill in their own progress data, + and the subphase is indicated in this column. Typically, + blocks_total and blocks_done + will contain progress data, as well as potentially + tuples_total and tuples_done. + + + + waiting for writers before validation + + CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY is waiting for transactions + with write locks that can potentially write into the table to finish. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + index validation: scanning index + + CREATE INDEX CONCURRENTLY is scanning the index searching + for tuples that need to be validated. + This phase is skipped when not in concurrent mode. + Columns blocks_total (set to the total size of the index) + and blocks_done contain the progress information for this phase. + + + + index validation: sorting tuples + + CREATE INDEX CONCURRENTLY is sorting the output of the + index scanning phase. + + + + index validation: scanning table + + CREATE INDEX CONCURRENTLY is scanning the table + to validate the index tuples collected in the previous two phases. + This phase is skipped when not in concurrent mode. + Columns blocks_total (set to the total size of the table) + and blocks_done contain the progress information for this phase. + + + + waiting for old snapshots + + CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY is waiting for transactions + that can potentially see the table to release their snapshots. This + phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + waiting for readers before marking dead + + REINDEX CONCURRENTLY is waiting for transactions + with read locks on the table to finish, before marking the old index dead. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + waiting for readers before dropping + + REINDEX CONCURRENTLY is waiting for transactions + with read locks on the table to finish, before dropping the old index. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + +
+ +
+ + + VACUUM Progress Reporting + + + pg_stat_progress_vacuum + + + + Whenever VACUUM is running, the + pg_stat_progress_vacuum view will contain + one row for each backend (including autovacuum worker processes) that is + currently vacuuming. The tables below describe the information + that will be reported and provide information about how to interpret it. + Progress for VACUUM FULL commands is reported via + pg_stat_progress_cluster + because both VACUUM FULL and CLUSTER + rewrite the table, while regular VACUUM only modifies it + in place. See . + + + + <structname>pg_stat_progress_vacuum</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of backend. + + + + + + datid oid + + + OID of the database to which this backend is connected. + + + + + + datname name + + + Name of the database to which this backend is connected. + + + + + + relid oid + + + OID of the table being vacuumed. + + + + + + phase text + + + Current processing phase of vacuum. See . + + + + + + heap_blks_total bigint + + + Total number of heap blocks in the table. This number is reported + as of the beginning of the scan; blocks added later will not be (and + need not be) visited by this VACUUM. + + + + + + heap_blks_scanned bigint + + + Number of heap blocks scanned. Because the + visibility map is used to optimize scans, + some blocks will be skipped without inspection; skipped blocks are + included in this total, so that this number will eventually become + equal to heap_blks_total when the vacuum is complete. + This counter only advances when the phase is scanning heap. + + + + + + heap_blks_vacuumed bigint + + + Number of heap blocks vacuumed. Unless the table has no indexes, this + counter only advances when the phase is vacuuming heap. + Blocks that contain no dead tuples are skipped, so the counter may + sometimes skip forward in large increments. + + + + + + index_vacuum_count bigint + + + Number of completed index vacuum cycles. + + + + + + max_dead_tuples bigint + + + Number of dead tuples that we can store before needing to perform + an index vacuum cycle, based on + . + + + + + + num_dead_tuples bigint + + + Number of dead tuples collected since the last index vacuum cycle. + + + + +
+ + + VACUUM Phases + + + + + + Phase + Description + + + + + + initializing + + VACUUM is preparing to begin scanning the heap. This + phase is expected to be very brief. + + + + scanning heap + + VACUUM is currently scanning the heap. It will prune and + defragment each page if required, and possibly perform freezing + activity. The heap_blks_scanned column can be used + to monitor the progress of the scan. + + + + vacuuming indexes + + VACUUM is currently vacuuming the indexes. If a table has + any indexes, this will happen at least once per vacuum, after the heap + has been completely scanned. It may happen multiple times per vacuum + if is insufficient to + store the number of dead tuples found. + + + + vacuuming heap + + VACUUM is currently vacuuming the heap. Vacuuming the heap + is distinct from scanning the heap, and occurs after each instance of + vacuuming indexes. If heap_blks_scanned is less than + heap_blks_total, the system will return to scanning + the heap after this phase is completed; otherwise, it will begin + cleaning up indexes after this phase is completed. + + + + cleaning up indexes + + VACUUM is currently cleaning up indexes. This occurs after + the heap has been completely scanned and all vacuuming of the indexes + and the heap has been completed. + + + + truncating heap + + VACUUM is currently truncating the heap so as to return + empty pages at the end of the relation to the operating system. This + occurs after cleaning up indexes. + + + + performing final cleanup + + VACUUM is performing final cleanup. During this phase, + VACUUM will vacuum the free space map, update statistics + in pg_class, and report statistics to the statistics + collector. When this phase is completed, VACUUM will end. + + + + +
+ +
+ + + CLUSTER Progress Reporting + + + pg_stat_progress_cluster + + + + Whenever CLUSTER or VACUUM FULL is + running, the pg_stat_progress_cluster view will + contain a row for each backend that is currently running either command. + The tables below describe the information that will be reported and + provide information about how to interpret it. + + + + <structname>pg_stat_progress_cluster</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of backend. + + + + + + datid oid + + + OID of the database to which this backend is connected. + + + + + + datname name + + + Name of the database to which this backend is connected. + + + + + + relid oid + + + OID of the table being clustered. + + + + + + command text + + + The command that is running. Either CLUSTER or VACUUM FULL. + + + + + + phase text + + + Current processing phase. See . + + + + + + cluster_index_relid oid + + + If the table is being scanned using an index, this is the OID of the + index being used; otherwise, it is zero. + + + + + + heap_tuples_scanned bigint + + + Number of heap tuples scanned. + This counter only advances when the phase is + seq scanning heap, + index scanning heap + or writing new heap. + + + + + + heap_tuples_written bigint + + + Number of heap tuples written. + This counter only advances when the phase is + seq scanning heap, + index scanning heap + or writing new heap. + + + + + + heap_blks_total bigint + + + Total number of heap blocks in the table. This number is reported + as of the beginning of seq scanning heap. + + + + + + heap_blks_scanned bigint + + + Number of heap blocks scanned. This counter only advances when the + phase is seq scanning heap. + + + + + + index_rebuild_count bigint + + + Number of indexes rebuilt. This counter only advances when the phase + is rebuilding index. + + + + +
+ + + CLUSTER and VACUUM FULL Phases + + + + + + Phase + Description + + + + + + initializing + + The command is preparing to begin scanning the heap. This phase is + expected to be very brief. + + + + seq scanning heap + + The command is currently scanning the table using a sequential scan. + + + + index scanning heap + + CLUSTER is currently scanning the table using an index scan. + + + + sorting tuples + + CLUSTER is currently sorting tuples. + + + + writing new heap + + CLUSTER is currently writing the new heap. + + + + swapping relation files + + The command is currently swapping newly-built files into place. + + + + rebuilding index + + The command is currently rebuilding an index. + + + + performing final cleanup + + The command is performing final cleanup. When this phase is + completed, CLUSTER + or VACUUM FULL will end. + + + + +
+
+ + + Base Backup Progress Reporting + + + pg_stat_progress_basebackup + + + + Whenever an application like pg_basebackup + is taking a base backup, the + pg_stat_progress_basebackup + view will contain a row for each WAL sender process that is currently + running the BASE_BACKUP replication command + and streaming the backup. The tables below describe the information + that will be reported and provide information about how to interpret it. + + + + <structname>pg_stat_progress_basebackup</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of a WAL sender process. + + + + + + phase text + + + Current processing phase. See . + + + + + + backup_total bigint + + + Total amount of data that will be streamed. This is estimated and + reported as of the beginning of + streaming database files phase. Note that + this is only an approximation since the database + may change during streaming database files phase + and WAL log may be included in the backup later. This is always + the same value as backup_streamed + once the amount of data streamed exceeds the estimated + total size. If the estimation is disabled in + pg_basebackup + (i.e., --no-estimate-size option is specified), + this is NULL. + + + + + + backup_streamed bigint + + + Amount of data streamed. This counter only advances + when the phase is streaming database files or + transferring wal files. + + + + + + tablespaces_total bigint + + + Total number of tablespaces that will be streamed. + + + + + + tablespaces_streamed bigint + + + Number of tablespaces streamed. This counter only + advances when the phase is streaming database files. + + + + +
+ + + Base backup phases + + + + + + Phase + Description + + + + + initializing + + The WAL sender process is preparing to begin the backup. + This phase is expected to be very brief. + + + + waiting for checkpoint to finish + + The WAL sender process is currently performing + pg_start_backup to prepare to + take a base backup, and waiting for the start-of-backup + checkpoint to finish. + + + + estimating backup size + + The WAL sender process is currently estimating the total amount + of database files that will be streamed as a base backup. + + + + streaming database files + + The WAL sender process is currently streaming database files + as a base backup. + + + + waiting for wal archiving to finish + + The WAL sender process is currently performing + pg_stop_backup to finish the backup, + and waiting for all the WAL files required for the base backup + to be successfully archived. + If either --wal-method=none or + --wal-method=stream is specified in + pg_basebackup, the backup will end + when this phase is completed. + + + + transferring wal files + + The WAL sender process is currently transferring all WAL logs + generated during the backup. This phase occurs after + waiting for wal archiving to finish phase if + --wal-method=fetch is specified in + pg_basebackup. The backup will end + when this phase is completed. + + + + +
+ +
+ + + COPY Progress Reporting + + + pg_stat_progress_copy + + + + Whenever COPY is running, the + pg_stat_progress_copy view will contain one row + for each backend that is currently running a COPY command. + The table below describes the information that will be reported and provides + information about how to interpret it. + + + + <structname>pg_stat_progress_copy</structname> View + + + + + Column Type + + + Description + + + + + + + + pid integer + + + Process ID of backend. + + + + + + datid oid + + + OID of the database to which this backend is connected. + + + + + + datname name + + + Name of the database to which this backend is connected. + + + + + + relid oid + + + OID of the table on which the COPY command is + executed. It is set to 0 if copying from a + SELECT query. + + + + + + command text + + + The command that is running: COPY FROM, or + COPY TO. + + + + + + type text + + + The io type that the data is read from or written to: + FILE, PROGRAM, + PIPE (for COPY FROM STDIN and + COPY TO STDOUT), or CALLBACK + (used for example during the initial table synchronization in + logical replication). + + + + + + bytes_processed bigint + + + Number of bytes already processed by COPY command. + + + + + + bytes_total bigint + + + Size of source file for COPY FROM command in bytes. + It is set to 0 if not available. + + + + + + tuples_processed bigint + + + Number of tuples already processed by COPY command. + + + + + + tuples_excluded bigint + + + Number of tuples not processed because they were excluded by the + WHERE clause of the COPY command. + + + + +
+
+ +
+ + + Dynamic Tracing + + + DTrace + + + + PostgreSQL provides facilities to support + dynamic tracing of the database server. This allows an external + utility to be called at specific points in the code and thereby trace + execution. + + + + A number of probes or trace points are already inserted into the source + code. These probes are intended to be used by database developers and + administrators. By default the probes are not compiled into + PostgreSQL; the user needs to explicitly tell + the configure script to make the probes available. + + + + Currently, the + DTrace + utility is supported, which, at the time of this writing, is available + on Solaris, macOS, FreeBSD, NetBSD, and Oracle Linux. The + SystemTap project + for Linux provides a DTrace equivalent and can also be used. Supporting other dynamic + tracing utilities is theoretically possible by changing the definitions for + the macros in src/include/utils/probes.h. + + + + Compiling for Dynamic Tracing + + + By default, probes are not available, so you will need to + explicitly tell the configure script to make the probes available + in PostgreSQL. To include DTrace support + specify to configure. See for further information. + + + + + Built-in Probes + + + A number of standard probes are provided in the source code, + as shown in ; + + shows the types used in the probes. More probes can certainly be + added to enhance PostgreSQL's observability. + + + + Built-in DTrace Probes + + + + + + + Name + Parameters + Description + + + + + + + transaction-start + (LocalTransactionId) + Probe that fires at the start of a new transaction. + arg0 is the transaction ID. + + + transaction-commit + (LocalTransactionId) + Probe that fires when a transaction completes successfully. + arg0 is the transaction ID. + + + transaction-abort + (LocalTransactionId) + Probe that fires when a transaction completes unsuccessfully. + arg0 is the transaction ID. + + + query-start + (const char *) + Probe that fires when the processing of a query is started. + arg0 is the query string. + + + query-done + (const char *) + Probe that fires when the processing of a query is complete. + arg0 is the query string. + + + query-parse-start + (const char *) + Probe that fires when the parsing of a query is started. + arg0 is the query string. + + + query-parse-done + (const char *) + Probe that fires when the parsing of a query is complete. + arg0 is the query string. + + + query-rewrite-start + (const char *) + Probe that fires when the rewriting of a query is started. + arg0 is the query string. + + + query-rewrite-done + (const char *) + Probe that fires when the rewriting of a query is complete. + arg0 is the query string. + + + query-plan-start + () + Probe that fires when the planning of a query is started. + + + query-plan-done + () + Probe that fires when the planning of a query is complete. + + + query-execute-start + () + Probe that fires when the execution of a query is started. + + + query-execute-done + () + Probe that fires when the execution of a query is complete. + + + statement-status + (const char *) + Probe that fires anytime the server process updates its + pg_stat_activity.status. + arg0 is the new status string. + + + checkpoint-start + (int) + Probe that fires when a checkpoint is started. + arg0 holds the bitwise flags used to distinguish different checkpoint + types, such as shutdown, immediate or force. + + + checkpoint-done + (int, int, int, int, int) + Probe that fires when a checkpoint is complete. + (The probes listed next fire in sequence during checkpoint processing.) + arg0 is the number of buffers written. arg1 is the total number of + buffers. arg2, arg3 and arg4 contain the number of WAL files added, + removed and recycled respectively. + + + clog-checkpoint-start + (bool) + Probe that fires when the CLOG portion of a checkpoint is started. + arg0 is true for normal checkpoint, false for shutdown + checkpoint. + + + clog-checkpoint-done + (bool) + Probe that fires when the CLOG portion of a checkpoint is + complete. arg0 has the same meaning as for clog-checkpoint-start. + + + subtrans-checkpoint-start + (bool) + Probe that fires when the SUBTRANS portion of a checkpoint is + started. + arg0 is true for normal checkpoint, false for shutdown + checkpoint. + + + subtrans-checkpoint-done + (bool) + Probe that fires when the SUBTRANS portion of a checkpoint is + complete. arg0 has the same meaning as for + subtrans-checkpoint-start. + + + multixact-checkpoint-start + (bool) + Probe that fires when the MultiXact portion of a checkpoint is + started. + arg0 is true for normal checkpoint, false for shutdown + checkpoint. + + + multixact-checkpoint-done + (bool) + Probe that fires when the MultiXact portion of a checkpoint is + complete. arg0 has the same meaning as for + multixact-checkpoint-start. + + + buffer-checkpoint-start + (int) + Probe that fires when the buffer-writing portion of a checkpoint + is started. + arg0 holds the bitwise flags used to distinguish different checkpoint + types, such as shutdown, immediate or force. + + + buffer-sync-start + (int, int) + Probe that fires when we begin to write dirty buffers during + checkpoint (after identifying which buffers must be written). + arg0 is the total number of buffers. + arg1 is the number that are currently dirty and need to be written. + + + buffer-sync-written + (int) + Probe that fires after each buffer is written during checkpoint. + arg0 is the ID number of the buffer. + + + buffer-sync-done + (int, int, int) + Probe that fires when all dirty buffers have been written. + arg0 is the total number of buffers. + arg1 is the number of buffers actually written by the checkpoint process. + arg2 is the number that were expected to be written (arg1 of + buffer-sync-start); any difference reflects other processes flushing + buffers during the checkpoint. + + + buffer-checkpoint-sync-start + () + Probe that fires after dirty buffers have been written to the + kernel, and before starting to issue fsync requests. + + + buffer-checkpoint-done + () + Probe that fires when syncing of buffers to disk is + complete. + + + twophase-checkpoint-start + () + Probe that fires when the two-phase portion of a checkpoint is + started. + + + twophase-checkpoint-done + () + Probe that fires when the two-phase portion of a checkpoint is + complete. + + + buffer-read-start + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool) + Probe that fires when a buffer read is started. + arg0 and arg1 contain the fork and block numbers of the page (but + arg1 will be -1 if this is a relation extension request). + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + arg5 is the ID of the backend which created the temporary relation for a + local buffer, or InvalidBackendId (-1) for a shared buffer. + arg6 is true for a relation extension request, false for normal + read. + + + buffer-read-done + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool) + Probe that fires when a buffer read is complete. + arg0 and arg1 contain the fork and block numbers of the page (if this + is a relation extension request, arg1 now contains the block number + of the newly added block). + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + arg5 is the ID of the backend which created the temporary relation for a + local buffer, or InvalidBackendId (-1) for a shared buffer. + arg6 is true for a relation extension request, false for normal + read. + arg7 is true if the buffer was found in the pool, false if not. + + + buffer-flush-start + (ForkNumber, BlockNumber, Oid, Oid, Oid) + Probe that fires before issuing any write request for a shared + buffer. + arg0 and arg1 contain the fork and block numbers of the page. + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + + + buffer-flush-done + (ForkNumber, BlockNumber, Oid, Oid, Oid) + Probe that fires when a write request is complete. (Note + that this just reflects the time to pass the data to the kernel; + it's typically not actually been written to disk yet.) + The arguments are the same as for buffer-flush-start. + + + buffer-write-dirty-start + (ForkNumber, BlockNumber, Oid, Oid, Oid) + Probe that fires when a server process begins to write a dirty + buffer. (If this happens often, it implies that + is too + small or the background writer control parameters need adjustment.) + arg0 and arg1 contain the fork and block numbers of the page. + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + + + buffer-write-dirty-done + (ForkNumber, BlockNumber, Oid, Oid, Oid) + Probe that fires when a dirty-buffer write is complete. + The arguments are the same as for buffer-write-dirty-start. + + + wal-buffer-write-dirty-start + () + Probe that fires when a server process begins to write a + dirty WAL buffer because no more WAL buffer space is available. + (If this happens often, it implies that + is too small.) + + + wal-buffer-write-dirty-done + () + Probe that fires when a dirty WAL buffer write is complete. + + + wal-insert + (unsigned char, unsigned char) + Probe that fires when a WAL record is inserted. + arg0 is the resource manager (rmid) for the record. + arg1 contains the info flags. + + + wal-switch + () + Probe that fires when a WAL segment switch is requested. + + + smgr-md-read-start + (ForkNumber, BlockNumber, Oid, Oid, Oid, int) + Probe that fires when beginning to read a block from a relation. + arg0 and arg1 contain the fork and block numbers of the page. + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + arg5 is the ID of the backend which created the temporary relation for a + local buffer, or InvalidBackendId (-1) for a shared buffer. + + + smgr-md-read-done + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) + Probe that fires when a block read is complete. + arg0 and arg1 contain the fork and block numbers of the page. + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + arg5 is the ID of the backend which created the temporary relation for a + local buffer, or InvalidBackendId (-1) for a shared buffer. + arg6 is the number of bytes actually read, while arg7 is the number + requested (if these are different it indicates trouble). + + + smgr-md-write-start + (ForkNumber, BlockNumber, Oid, Oid, Oid, int) + Probe that fires when beginning to write a block to a relation. + arg0 and arg1 contain the fork and block numbers of the page. + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + arg5 is the ID of the backend which created the temporary relation for a + local buffer, or InvalidBackendId (-1) for a shared buffer. + + + smgr-md-write-done + (ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int) + Probe that fires when a block write is complete. + arg0 and arg1 contain the fork and block numbers of the page. + arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs + identifying the relation. + arg5 is the ID of the backend which created the temporary relation for a + local buffer, or InvalidBackendId (-1) for a shared buffer. + arg6 is the number of bytes actually written, while arg7 is the number + requested (if these are different it indicates trouble). + + + sort-start + (int, bool, int, int, bool, int) + Probe that fires when a sort operation is started. + arg0 indicates heap, index or datum sort. + arg1 is true for unique-value enforcement. + arg2 is the number of key columns. + arg3 is the number of kilobytes of work memory allowed. + arg4 is true if random access to the sort result is required. + arg5 indicates serial when 0, parallel worker when + 1, or parallel leader when 2. + + + sort-done + (bool, long) + Probe that fires when a sort is complete. + arg0 is true for external sort, false for internal sort. + arg1 is the number of disk blocks used for an external sort, + or kilobytes of memory used for an internal sort. + + + lwlock-acquire + (char *, LWLockMode) + Probe that fires when an LWLock has been acquired. + arg0 is the LWLock's tranche. + arg1 is the requested lock mode, either exclusive or shared. + + + lwlock-release + (char *) + Probe that fires when an LWLock has been released (but note + that any released waiters have not yet been awakened). + arg0 is the LWLock's tranche. + + + lwlock-wait-start + (char *, LWLockMode) + Probe that fires when an LWLock was not immediately available and + a server process has begun to wait for the lock to become available. + arg0 is the LWLock's tranche. + arg1 is the requested lock mode, either exclusive or shared. + + + lwlock-wait-done + (char *, LWLockMode) + Probe that fires when a server process has been released from its + wait for an LWLock (it does not actually have the lock yet). + arg0 is the LWLock's tranche. + arg1 is the requested lock mode, either exclusive or shared. + + + lwlock-condacquire + (char *, LWLockMode) + Probe that fires when an LWLock was successfully acquired when the + caller specified no waiting. + arg0 is the LWLock's tranche. + arg1 is the requested lock mode, either exclusive or shared. + + + lwlock-condacquire-fail + (char *, LWLockMode) + Probe that fires when an LWLock was not successfully acquired when + the caller specified no waiting. + arg0 is the LWLock's tranche. + arg1 is the requested lock mode, either exclusive or shared. + + + lock-wait-start + (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) + Probe that fires when a request for a heavyweight lock (lmgr lock) + has begun to wait because the lock is not available. + arg0 through arg3 are the tag fields identifying the object being + locked. arg4 indicates the type of object being locked. + arg5 indicates the lock type being requested. + + + lock-wait-done + (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE) + Probe that fires when a request for a heavyweight lock (lmgr lock) + has finished waiting (i.e., has acquired the lock). + The arguments are the same as for lock-wait-start. + + + deadlock-found + () + Probe that fires when a deadlock is found by the deadlock + detector. + + + + +
+ + + Defined Types Used in Probe Parameters + + + + Type + Definition + + + + + + + LocalTransactionId + unsigned int + + + LWLockMode + int + + + LOCKMODE + int + + + BlockNumber + unsigned int + + + Oid + unsigned int + + + ForkNumber + int + + + bool + unsigned char + + + + +
+ + +
+ + + Using Probes + + + The example below shows a DTrace script for analyzing transaction + counts in the system, as an alternative to snapshotting + pg_stat_database before and after a performance test: + +#!/usr/sbin/dtrace -qs + +postgresql$1:::transaction-start +{ + @start["Start"] = count(); + self->ts = timestamp; +} + +postgresql$1:::transaction-abort +{ + @abort["Abort"] = count(); +} + +postgresql$1:::transaction-commit +/self->ts/ +{ + @commit["Commit"] = count(); + @time["Total time (ns)"] = sum(timestamp - self->ts); + self->ts=0; +} + + When executed, the example D script gives output such as: + +# ./txn_count.d `pgrep -n postgres` or ./txn_count.d <PID> +^C + +Start 71 +Commit 70 +Total time (ns) 2312105013 + + + + + + SystemTap uses a different notation for trace scripts than DTrace does, + even though the underlying trace points are compatible. One point worth + noting is that at this writing, SystemTap scripts must reference probe + names using double underscores in place of hyphens. This is expected to + be fixed in future SystemTap releases. + + + + + You should remember that DTrace scripts need to be carefully written and + debugged, otherwise the trace information collected might + be meaningless. In most cases where problems are found it is the + instrumentation that is at fault, not the underlying system. When + discussing information found using dynamic tracing, be sure to enclose + the script used to allow that too to be checked and discussed. + + + + + Defining New Probes + + + New probes can be defined within the code wherever the developer + desires, though this will require a recompilation. Below are the steps + for inserting new probes: + + + + + + Decide on probe names and data to be made available through the probes + + + + + + Add the probe definitions to src/backend/utils/probes.d + + + + + + Include pg_trace.h if it is not already present in the + module(s) containing the probe points, and insert + TRACE_POSTGRESQL probe macros at the desired locations + in the source code + + + + + + Recompile and verify that the new probes are available + + + + + + Example: + + Here is an example of how you would add a probe to trace all new + transactions by transaction ID. + + + + + + + Decide that the probe will be named transaction-start and + requires a parameter of type LocalTransactionId + + + + + + Add the probe definition to src/backend/utils/probes.d: + +probe transaction__start(LocalTransactionId); + + Note the use of the double underline in the probe name. In a DTrace + script using the probe, the double underline needs to be replaced with a + hyphen, so transaction-start is the name to document for + users. + + + + + + At compile time, transaction__start is converted to a macro + called TRACE_POSTGRESQL_TRANSACTION_START (notice the + underscores are single here), which is available by including + pg_trace.h. Add the macro call to the appropriate location + in the source code. In this case, it looks like the following: + + +TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); + + + + + + + After recompiling and running the new binary, check that your newly added + probe is available by executing the following DTrace command. You + should see similar output: + +# dtrace -ln transaction-start + ID PROVIDER MODULE FUNCTION NAME +18705 postgresql49878 postgres StartTransactionCommand transaction-start +18755 postgresql49877 postgres StartTransactionCommand transaction-start +18805 postgresql49876 postgres StartTransactionCommand transaction-start +18855 postgresql49875 postgres StartTransactionCommand transaction-start +18986 postgresql49873 postgres StartTransactionCommand transaction-start + + + + + + + There are a few things to be careful about when adding trace macros + to the C code: + + + + + You should take care that the data types specified for a probe's + parameters match the data types of the variables used in the macro. + Otherwise, you will get compilation errors. + + + + + + + On most platforms, if PostgreSQL is + built with , the arguments to a trace + macro will be evaluated whenever control passes through the + macro, even if no tracing is being done. This is + usually not worth worrying about if you are just reporting the + values of a few local variables. But beware of putting expensive + function calls into the arguments. If you need to do that, + consider protecting the macro with a check to see if the trace + is actually enabled: + + +if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED()) + TRACE_POSTGRESQL_TRANSACTION_START(some_function(...)); + + + Each trace macro has a corresponding ENABLED macro. + + + + + + + + +
+ +
diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml new file mode 100644 index 000000000000..d358bbe4a6a0 --- /dev/null +++ b/doc/src/sgml/mvcc.sgml @@ -0,0 +1,1837 @@ + + + + Concurrency Control + + + concurrency + + + + This chapter describes the behavior of the + PostgreSQL database system when two or + more sessions try to access the same data at the same time. The + goals in that situation are to allow efficient access for all + sessions while maintaining strict data integrity. Every developer + of database applications should be familiar with the topics covered + in this chapter. + + + + Introduction + + + Multiversion Concurrency Control + + + + MVCC + + + + Serializable Snapshot Isolation + + + + SSI + + + + PostgreSQL provides a rich set of tools + for developers to manage concurrent access to data. Internally, + data consistency is maintained by using a multiversion + model (Multiversion Concurrency Control, MVCC). + This means that each SQL statement sees + a snapshot of data (a database version) + as it was some + time ago, regardless of the current state of the underlying data. + This prevents statements from viewing inconsistent data produced + by concurrent transactions performing updates on the same + data rows, providing transaction isolation + for each database session. MVCC, by eschewing + the locking methodologies of traditional database systems, + minimizes lock contention in order to allow for reasonable + performance in multiuser environments. + + + + The main advantage of using the MVCC model of + concurrency control rather than locking is that in + MVCC locks acquired for querying (reading) data + do not conflict with locks acquired for writing data, and so + reading never blocks writing and writing never blocks reading. + PostgreSQL maintains this guarantee + even when providing the strictest level of transaction + isolation through the use of an innovative Serializable + Snapshot Isolation (SSI) level. + + + + Table- and row-level locking facilities are also available in + PostgreSQL for applications which don't + generally need full transaction isolation and prefer to explicitly + manage particular points of conflict. However, proper + use of MVCC will generally provide better + performance than locks. In addition, application-defined advisory + locks provide a mechanism for acquiring locks that are not tied + to a single transaction. + + + + + Transaction Isolation + + + transaction isolation + + + + The SQL standard defines four levels of + transaction isolation. The most strict is Serializable, + which is defined by the standard in a paragraph which says that any + concurrent execution of a set of Serializable transactions is guaranteed + to produce the same effect as running them one at a time in some order. + The other three levels are defined in terms of phenomena, resulting from + interaction between concurrent transactions, which must not occur at + each level. The standard notes that due to the definition of + Serializable, none of these phenomena are possible at that level. (This + is hardly surprising -- if the effect of the transactions must be + consistent with having been run one at a time, how could you see any + phenomena caused by interactions?) + + + + The phenomena which are prohibited at various levels are: + + + + + dirty read + dirty read + + + + A transaction reads data written by a concurrent uncommitted transaction. + + + + + + + nonrepeatable read + nonrepeatable read + + + + A transaction re-reads data it has previously read and finds that data + has been modified by another transaction (that committed since the + initial read). + + + + + + + phantom read + phantom read + + + + A transaction re-executes a query returning a set of rows that satisfy a + search condition and finds that the set of rows satisfying the condition + has changed due to another recently-committed transaction. + + + + + + + serialization anomaly + serialization anomaly + + + + The result of successfully committing a group of transactions + is inconsistent with all possible orderings of running those + transactions one at a time. + + + + + + + + + transaction isolation level + + The SQL standard and PostgreSQL-implemented transaction isolation levels + are described in . + + + + Transaction Isolation Levels + + + + + Isolation Level + + + Dirty Read + + + Nonrepeatable Read + + + Phantom Read + + + Serialization Anomaly + + + + + + + Read uncommitted + + + Allowed, but not in PG + + + Possible + + + Possible + + + Possible + + + + + + Read committed + + + Not possible + + + Possible + + + Possible + + + Possible + + + + + + Repeatable read + + + Not possible + + + Not possible + + + Allowed, but not in PG + + + Possible + + + + + + Serializable + + + Not possible + + + Not possible + + + Not possible + + + Not possible + + + + +
+ + + In PostgreSQL, you can request any of + the four standard transaction isolation levels, but internally only + three distinct isolation levels are implemented, i.e., PostgreSQL's + Read Uncommitted mode behaves like Read Committed. This is because + it is the only sensible way to map the standard isolation levels to + PostgreSQL's multiversion concurrency control architecture. + + + + The table also shows that PostgreSQL's Repeatable Read implementation + does not allow phantom reads. Stricter behavior is permitted by the + SQL standard: the four isolation levels only define which phenomena + must not happen, not which phenomena must happen. + The behavior of the available isolation levels is detailed in the + following subsections. + + + + To set the transaction isolation level of a transaction, use the + command . + + + + + Some PostgreSQL data types and functions have + special rules regarding transactional behavior. In particular, changes + made to a sequence (and therefore the counter of a + column declared using serial) are immediately visible + to all other transactions and are not rolled back if the transaction + that made the changes aborts. See + and . + + + + + Read Committed Isolation Level + + + transaction isolation level + read committed + + + + read committed + + + + Read Committed is the default isolation + level in PostgreSQL. When a transaction + uses this isolation level, a SELECT query + (without a FOR UPDATE/SHARE clause) sees only data + committed before the query began; it never sees either uncommitted + data or changes committed during query execution by concurrent + transactions. In effect, a SELECT query sees + a snapshot of the database as of the instant the query begins to + run. However, SELECT does see the effects + of previous updates executed within its own transaction, even + though they are not yet committed. Also note that two successive + SELECT commands can see different data, even + though they are within a single transaction, if other transactions + commit changes after the first SELECT starts and + before the second SELECT starts. + + + + UPDATE, DELETE, SELECT + FOR UPDATE, and SELECT FOR SHARE commands + behave the same as SELECT + in terms of searching for target rows: they will only find target rows + that were committed as of the command start time. However, such a target + row might have already been updated (or deleted or locked) by + another concurrent transaction by the time it is found. In this case, the + would-be updater will wait for the first updating transaction to commit or + roll back (if it is still in progress). If the first updater rolls back, + then its effects are negated and the second updater can proceed with + updating the originally found row. If the first updater commits, the + second updater will ignore the row if the first updater deleted it, + otherwise it will attempt to apply its operation to the updated version of + the row. The search condition of the command (the WHERE clause) is + re-evaluated to see if the updated version of the row still matches the + search condition. If so, the second updater proceeds with its operation + using the updated version of the row. In the case of + SELECT FOR UPDATE and SELECT FOR + SHARE, this means it is the updated version of the row that is + locked and returned to the client. + + + + INSERT with an ON CONFLICT DO UPDATE clause + behaves similarly. In Read Committed mode, each row proposed for insertion + will either insert or update. Unless there are unrelated errors, one of + those two outcomes is guaranteed. If a conflict originates in another + transaction whose effects are not yet visible to the INSERT + , the UPDATE clause will affect that row, + even though possibly no version of that row is + conventionally visible to the command. + + + + INSERT with an ON CONFLICT DO + NOTHING clause may have insertion not proceed for a row due to + the outcome of another transaction whose effects are not visible + to the INSERT snapshot. Again, this is only + the case in Read Committed mode. + + + + Because of the above rules, it is possible for an updating command to see + an inconsistent snapshot: it can see the effects of concurrent updating + commands on the same rows it is trying to update, but it + does not see effects of those commands on other rows in the database. + This behavior makes Read Committed mode unsuitable for commands that + involve complex search conditions; however, it is just right for simpler + cases. For example, consider updating bank balances with transactions + like: + + +BEGIN; +UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 12345; +UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534; +COMMIT; + + + If two such transactions concurrently try to change the balance of account + 12345, we clearly want the second transaction to start with the updated + version of the account's row. Because each command is affecting only a + predetermined row, letting it see the updated version of the row does + not create any troublesome inconsistency. + + + + More complex usage can produce undesirable results in Read Committed + mode. For example, consider a DELETE command + operating on data that is being both added and removed from its + restriction criteria by another command, e.g., assume + website is a two-row table with + website.hits equaling 9 and + 10: + + +BEGIN; +UPDATE website SET hits = hits + 1; +-- run from another session: DELETE FROM website WHERE hits = 10; +COMMIT; + + + The DELETE will have no effect even though + there is a website.hits = 10 row before and + after the UPDATE. This occurs because the + pre-update row value 9 is skipped, and when the + UPDATE completes and DELETE + obtains a lock, the new row value is no longer 10 but + 11, which no longer matches the criteria. + + + + Because Read Committed mode starts each command with a new snapshot + that includes all transactions committed up to that instant, + subsequent commands in the same transaction will see the effects + of the committed concurrent transaction in any case. The point + at issue above is whether or not a single command + sees an absolutely consistent view of the database. + + + + The partial transaction isolation provided by Read Committed mode + is adequate for many applications, and this mode is fast and simple + to use; however, it is not sufficient for all cases. Applications + that do complex queries and updates might require a more rigorously + consistent view of the database than Read Committed mode provides. + + + + + Repeatable Read Isolation Level + + + transaction isolation level + repeatable read + + + + repeatable read + + + + The Repeatable Read isolation level only sees + data committed before the transaction began; it never sees either + uncommitted data or changes committed during transaction execution + by concurrent transactions. (However, the query does see the + effects of previous updates executed within its own transaction, + even though they are not yet committed.) This is a stronger + guarantee than is required by the SQL standard + for this isolation level, and prevents all of the phenomena described + in except for serialization + anomalies. As mentioned above, this is + specifically allowed by the standard, which only describes the + minimum protections each isolation level must + provide. + + + + This level is different from Read Committed in that a query in a + repeatable read transaction sees a snapshot as of the start of the + first non-transaction-control statement in the + transaction, not as of the start + of the current statement within the transaction. Thus, successive + SELECT commands within a single + transaction see the same data, i.e., they do not see changes made by + other transactions that committed after their own transaction started. + + + + Applications using this level must be prepared to retry transactions + due to serialization failures. + + + + UPDATE, DELETE, SELECT + FOR UPDATE, and SELECT FOR SHARE commands + behave the same as SELECT + in terms of searching for target rows: they will only find target rows + that were committed as of the transaction start time. However, such a + target row might have already been updated (or deleted or locked) by + another concurrent transaction by the time it is found. In this case, the + repeatable read transaction will wait for the first updating transaction to commit or + roll back (if it is still in progress). If the first updater rolls back, + then its effects are negated and the repeatable read transaction can proceed + with updating the originally found row. But if the first updater commits + (and actually updated or deleted the row, not just locked it) + then the repeatable read transaction will be rolled back with the message + + +ERROR: could not serialize access due to concurrent update + + + because a repeatable read transaction cannot modify or lock rows changed by + other transactions after the repeatable read transaction began. + + + + When an application receives this error message, it should abort + the current transaction and retry the whole transaction from + the beginning. The second time through, the transaction will see the + previously-committed change as part of its initial view of the database, + so there is no logical conflict in using the new version of the row + as the starting point for the new transaction's update. + + + + Note that only updating transactions might need to be retried; read-only + transactions will never have serialization conflicts. + + + + The Repeatable Read mode provides a rigorous guarantee that each + transaction sees a completely stable view of the database. However, + this view will not necessarily always be consistent with some serial + (one at a time) execution of concurrent transactions of the same level. + For example, even a read only transaction at this level may see a + control record updated to show that a batch has been completed but + not see one of the detail records which is logically + part of the batch because it read an earlier revision of the control + record. Attempts to enforce business rules by transactions running at + this isolation level are not likely to work correctly without careful use + of explicit locks to block conflicting transactions. + + + + The Repeatable Read isolation level is implemented using a technique + known in academic database literature and in some other database products + as Snapshot Isolation. Differences in behavior + and performance may be observed when compared with systems that use a + traditional locking technique that reduces concurrency. Some other + systems may even offer Repeatable Read and Snapshot Isolation as distinct + isolation levels with different behavior. The permitted phenomena that + distinguish the two techniques were not formalized by database researchers + until after the SQL standard was developed, and are outside the scope of + this manual. For a full treatment, please see + . + + + + + Prior to PostgreSQL version 9.1, a request + for the Serializable transaction isolation level provided exactly the + same behavior described here. To retain the legacy Serializable + behavior, Repeatable Read should now be requested. + + + + + + Serializable Isolation Level + + + transaction isolation level + serializable + + + + serializable + + + + predicate locking + + + + serialization anomaly + + + + The Serializable isolation level provides + the strictest transaction isolation. This level emulates serial + transaction execution for all committed transactions; + as if transactions had been executed one after another, serially, + rather than concurrently. However, like the Repeatable Read level, + applications using this level must + be prepared to retry transactions due to serialization failures. + In fact, this isolation level works exactly the same as Repeatable + Read except that it monitors for conditions which could make + execution of a concurrent set of serializable transactions behave + in a manner inconsistent with all possible serial (one at a time) + executions of those transactions. This monitoring does not + introduce any blocking beyond that present in repeatable read, but + there is some overhead to the monitoring, and detection of the + conditions which could cause a + serialization anomaly will trigger a + serialization failure. + + + + As an example, + consider a table mytab, initially containing: + + class | value +-------+------- + 1 | 10 + 1 | 20 + 2 | 100 + 2 | 200 + + Suppose that serializable transaction A computes: + +SELECT SUM(value) FROM mytab WHERE class = 1; + + and then inserts the result (30) as the value in a + new row with class = 2. Concurrently, serializable + transaction B computes: + +SELECT SUM(value) FROM mytab WHERE class = 2; + + and obtains the result 300, which it inserts in a new row with + class = 1. Then both transactions try to commit. + If either transaction were running at the Repeatable Read isolation level, + both would be allowed to commit; but since there is no serial order of execution + consistent with the result, using Serializable transactions will allow one + transaction to commit and will roll the other back with this message: + + +ERROR: could not serialize access due to read/write dependencies among transactions + + + This is because if A had + executed before B, B would have computed the sum 330, not 300, and + similarly the other order would have resulted in a different sum + computed by A. + + + + When relying on Serializable transactions to prevent anomalies, it is + important that any data read from a permanent user table not be + considered valid until the transaction which read it has successfully + committed. This is true even for read-only transactions, except that + data read within a deferrable read-only + transaction is known to be valid as soon as it is read, because such a + transaction waits until it can acquire a snapshot guaranteed to be free + from such problems before starting to read any data. In all other cases + applications must not depend on results read during a transaction that + later aborted; instead, they should retry the transaction until it + succeeds. + + + + To guarantee true serializability PostgreSQL + uses predicate locking, which means that it keeps locks + which allow it to determine when a write would have had an impact on + the result of a previous read from a concurrent transaction, had it run + first. In PostgreSQL these locks do not + cause any blocking and therefore can not play any part in + causing a deadlock. They are used to identify and flag dependencies + among concurrent Serializable transactions which in certain combinations + can lead to serialization anomalies. In contrast, a Read Committed or + Repeatable Read transaction which wants to ensure data consistency may + need to take out a lock on an entire table, which could block other + users attempting to use that table, or it may use SELECT FOR + UPDATE or SELECT FOR SHARE which not only + can block other transactions but cause disk access. + + + + Predicate locks in PostgreSQL, like in most + other database systems, are based on data actually accessed by a + transaction. These will show up in the + pg_locks + system view with a mode of SIReadLock. The + particular locks + acquired during execution of a query will depend on the plan used by + the query, and multiple finer-grained locks (e.g., tuple locks) may be + combined into fewer coarser-grained locks (e.g., page locks) during the + course of the transaction to prevent exhaustion of the memory used to + track the locks. A READ ONLY transaction may be able to + release its SIRead locks before completion, if it detects that no + conflicts can still occur which could lead to a serialization anomaly. + In fact, READ ONLY transactions will often be able to + establish that fact at startup and avoid taking any predicate locks. + If you explicitly request a SERIALIZABLE READ ONLY DEFERRABLE + transaction, it will block until it can establish this fact. (This is + the only case where Serializable transactions block but + Repeatable Read transactions don't.) On the other hand, SIRead locks + often need to be kept past transaction commit, until overlapping read + write transactions complete. + + + + Consistent use of Serializable transactions can simplify development. + The guarantee that any set of successfully committed concurrent + Serializable transactions will have the same effect as if they were run + one at a time means that if you can demonstrate that a single transaction, + as written, will do the right thing when run by itself, you can have + confidence that it will do the right thing in any mix of Serializable + transactions, even without any information about what those other + transactions might do, or it will not successfully commit. It is + important that an environment which uses this technique have a + generalized way of handling serialization failures (which always return + with an SQLSTATE value of '40001'), because it will be very hard to + predict exactly which transactions might contribute to the read/write + dependencies and need to be rolled back to prevent serialization + anomalies. The monitoring of read/write dependencies has a cost, as does + the restart of transactions which are terminated with a serialization + failure, but balanced against the cost and blocking involved in use of + explicit locks and SELECT FOR UPDATE or SELECT FOR + SHARE, Serializable transactions are the best performance choice + for some environments. + + + + While PostgreSQL's Serializable transaction isolation + level only allows concurrent transactions to commit if it can prove there + is a serial order of execution that would produce the same effect, it + doesn't always prevent errors from being raised that would not occur in + true serial execution. In particular, it is possible to see unique + constraint violations caused by conflicts with overlapping Serializable + transactions even after explicitly checking that the key isn't present + before attempting to insert it. This can be avoided by making sure + that all Serializable transactions that insert potentially + conflicting keys explicitly check if they can do so first. For example, + imagine an application that asks the user for a new key and then checks + that it doesn't exist already by trying to select it first, or generates + a new key by selecting the maximum existing key and adding one. If some + Serializable transactions insert new keys directly without following this + protocol, unique constraints violations might be reported even in cases + where they could not occur in a serial execution of the concurrent + transactions. + + + + For optimal performance when relying on Serializable transactions for + concurrency control, these issues should be considered: + + + + + Declare transactions as READ ONLY when possible. + + + + + Control the number of active connections, using a connection pool if + needed. This is always an important performance consideration, but + it can be particularly important in a busy system using Serializable + transactions. + + + + + Don't put more into a single transaction than needed for integrity + purposes. + + + + + Don't leave connections dangling idle in transaction + longer than necessary. The configuration parameter + may be used to + automatically disconnect lingering sessions. + + + + + Eliminate explicit locks, SELECT FOR UPDATE, and + SELECT FOR SHARE where no longer needed due to the + protections automatically provided by Serializable transactions. + + + + + When the system is forced to combine multiple page-level predicate + locks into a single relation-level predicate lock because the predicate + lock table is short of memory, an increase in the rate of serialization + failures may occur. You can avoid this by increasing + , + , and/or + . + + + + + A sequential scan will always necessitate a relation-level predicate + lock. This can result in an increased rate of serialization failures. + It may be helpful to encourage the use of index scans by reducing + and/or increasing + . Be sure to weigh any decrease + in transaction rollbacks and restarts against any overall change in + query execution time. + + + + + + + The Serializable isolation level is implemented using a technique known + in academic database literature as Serializable Snapshot Isolation, which + builds on Snapshot Isolation by adding checks for serialization anomalies. + Some differences in behavior and performance may be observed when compared + with other systems that use a traditional locking technique. Please see + for detailed information. + + +
+ + + Explicit Locking + + + lock + + + + PostgreSQL provides various lock modes + to control concurrent access to data in tables. These modes can + be used for application-controlled locking in situations where + MVCC does not give the desired behavior. Also, + most PostgreSQL commands automatically + acquire locks of appropriate modes to ensure that referenced + tables are not dropped or modified in incompatible ways while the + command executes. (For example, TRUNCATE cannot safely be + executed concurrently with other operations on the same table, so it + obtains an ACCESS EXCLUSIVE lock on the table to + enforce that.) + + + + To examine a list of the currently outstanding locks in a database + server, use the + pg_locks + system view. For more information on monitoring the status of the lock + manager subsystem, refer to . + + + + Table-Level Locks + + + LOCK + + + + The list below shows the available lock modes and the contexts in + which they are used automatically by + PostgreSQL. You can also acquire any + of these locks explicitly with the command . + Remember that all of these lock modes are table-level locks, + even if the name contains the word + row; the names of the lock modes are historical. + To some extent the names reflect the typical usage of each lock + mode — but the semantics are all the same. The only real difference + between one lock mode and another is the set of lock modes with + which each conflicts (see ). + Two transactions cannot hold locks of conflicting + modes on the same table at the same time. (However, a transaction + never conflicts with itself. For example, it might acquire + ACCESS EXCLUSIVE lock and later acquire + ACCESS SHARE lock on the same table.) Non-conflicting + lock modes can be held concurrently by many transactions. Notice in + particular that some lock modes are self-conflicting (for example, + an ACCESS EXCLUSIVE lock cannot be held by more than one + transaction at a time) while others are not self-conflicting (for example, + an ACCESS SHARE lock can be held by multiple transactions). + + + + Table-Level Lock Modes + + + ACCESS SHARE + + + + Conflicts with the ACCESS EXCLUSIVE lock + mode only. + + + + The SELECT command acquires a lock of this mode on + referenced tables. In general, any query that only reads a table + and does not modify it will acquire this lock mode. + + + + + + + ROW SHARE + + + + Conflicts with the EXCLUSIVE and + ACCESS EXCLUSIVE lock modes. + + + + The SELECT FOR UPDATE and + SELECT FOR SHARE commands acquire a + lock of this mode on the target table(s) (in addition to + ACCESS SHARE locks on any other tables + that are referenced but not selected + ). + + + + + + + ROW EXCLUSIVE + + + + Conflicts with the SHARE, SHARE ROW + EXCLUSIVE, EXCLUSIVE, and + ACCESS EXCLUSIVE lock modes. + + + + The commands UPDATE, + DELETE, and INSERT + acquire this lock mode on the target table (in addition to + ACCESS SHARE locks on any other referenced + tables). In general, this lock mode will be acquired by any + command that modifies data in a table. + + + + + + + SHARE UPDATE EXCLUSIVE + + + + Conflicts with the SHARE UPDATE EXCLUSIVE, + SHARE, SHARE ROW + EXCLUSIVE, EXCLUSIVE, and + ACCESS EXCLUSIVE lock modes. + This mode protects a table against + concurrent schema changes and VACUUM runs. + + + + Acquired by VACUUM (without ), + ANALYZE, CREATE INDEX CONCURRENTLY, + REINDEX CONCURRENTLY, + CREATE STATISTICS, and certain ALTER + INDEX and ALTER TABLE variants (for full + details see the documentation of these commands). + + + + + + + SHARE + + + + Conflicts with the ROW EXCLUSIVE, + SHARE UPDATE EXCLUSIVE, SHARE ROW + EXCLUSIVE, EXCLUSIVE, and + ACCESS EXCLUSIVE lock modes. + This mode protects a table against concurrent data changes. + + + + Acquired by CREATE INDEX + (without ). + + + + + + + SHARE ROW EXCLUSIVE + + + + Conflicts with the ROW EXCLUSIVE, + SHARE UPDATE EXCLUSIVE, + SHARE, SHARE ROW + EXCLUSIVE, EXCLUSIVE, and + ACCESS EXCLUSIVE lock modes. + This mode protects a table against concurrent data changes, and + is self-exclusive so that only one session can hold it at a time. + + + + Acquired by CREATE TRIGGER and some forms of + ALTER TABLE. + + + + + + + EXCLUSIVE + + + + Conflicts with the ROW SHARE, ROW + EXCLUSIVE, SHARE UPDATE + EXCLUSIVE, SHARE, SHARE + ROW EXCLUSIVE, EXCLUSIVE, and + ACCESS EXCLUSIVE lock modes. + This mode allows only concurrent ACCESS SHARE locks, + i.e., only reads from the table can proceed in parallel with a + transaction holding this lock mode. + + + + Acquired by REFRESH MATERIALIZED VIEW CONCURRENTLY. + + + + + + + ACCESS EXCLUSIVE + + + + Conflicts with locks of all modes (ACCESS + SHARE, ROW SHARE, ROW + EXCLUSIVE, SHARE UPDATE + EXCLUSIVE, SHARE, SHARE + ROW EXCLUSIVE, EXCLUSIVE, and + ACCESS EXCLUSIVE). + This mode guarantees that the + holder is the only transaction accessing the table in any way. + + + + Acquired by the DROP TABLE, + TRUNCATE, REINDEX, + CLUSTER, VACUUM FULL, + and REFRESH MATERIALIZED VIEW (without + ) + commands. Many forms of ALTER INDEX and ALTER TABLE also acquire + a lock at this level. This is also the default lock mode for + LOCK TABLE statements that do not specify + a mode explicitly. + + + + + + + + Only an ACCESS EXCLUSIVE lock blocks a + SELECT (without ) + statement. + + + + + Once acquired, a lock is normally held until the end of the transaction. But if a + lock is acquired after establishing a savepoint, the lock is released + immediately if the savepoint is rolled back to. This is consistent with + the principle that ROLLBACK cancels all effects of the + commands since the savepoint. The same holds for locks acquired within a + PL/pgSQL exception block: an error escape from the block + releases locks acquired within it. + + + + + + Conflicting Lock Modes + + + + + + + + + + + + + + Requested Lock Mode + Existing Lock Mode + + + ACCESS SHARE + ROW SHARE + ROW EXCL. + SHARE UPDATE EXCL. + SHARE + SHARE ROW EXCL. + EXCL. + ACCESS EXCL. + + + + + ACCESS SHARE + + + + + + + + X + + + ROW SHARE + + + + + + + X + X + + + ROW EXCL. + + + + + X + X + X + X + + + SHARE UPDATE EXCL. + + + + X + X + X + X + X + + + SHARE + + + X + X + + X + X + X + + + SHARE ROW EXCL. + + + X + X + X + X + X + X + + + EXCL. + + X + X + X + X + X + X + X + + + ACCESS EXCL. + X + X + X + X + X + X + X + X + + + +
+
+ + + Row-Level Locks + + + In addition to table-level locks, there are row-level locks, which + are listed as below with the contexts in which they are used + automatically by PostgreSQL. See + for a complete table of + row-level lock conflicts. Note that a transaction can hold + conflicting locks on the same row, even in different subtransactions; + but other than that, two transactions can never hold conflicting locks + on the same row. Row-level locks do not affect data querying; they + block only writers and lockers to the same + row. Row-level locks are released at transaction end or during + savepoint rollback, just like table-level locks. + + + + + Row-Level Lock Modes + + + FOR UPDATE + + + + FOR UPDATE causes the rows retrieved by the + SELECT statement to be locked as though for + update. This prevents them from being locked, modified or deleted by + other transactions until the current transaction ends. That is, + other transactions that attempt UPDATE, + DELETE, + SELECT FOR UPDATE, + SELECT FOR NO KEY UPDATE, + SELECT FOR SHARE or + SELECT FOR KEY SHARE + of these rows will be blocked until the current transaction ends; + conversely, SELECT FOR UPDATE will wait for a + concurrent transaction that has run any of those commands on the + same row, + and will then lock and return the updated row (or no row, if the + row was deleted). Within a REPEATABLE READ or + SERIALIZABLE transaction, + however, an error will be thrown if a row to be locked has changed + since the transaction started. For further discussion see + . + + + The FOR UPDATE lock mode + is also acquired by any DELETE on a row, and also by an + UPDATE that modifies the values of certain columns. Currently, + the set of columns considered for the UPDATE case are those that + have a unique index on them that can be used in a foreign key (so partial + indexes and expressional indexes are not considered), but this may change + in the future. + + + + + + + FOR NO KEY UPDATE + + + + Behaves similarly to FOR UPDATE, except that the lock + acquired is weaker: this lock will not block + SELECT FOR KEY SHARE commands that attempt to acquire + a lock on the same rows. This lock mode is also acquired by any + UPDATE that does not acquire a FOR UPDATE lock. + + + + + + + FOR SHARE + + + + Behaves similarly to FOR NO KEY UPDATE, except that it + acquires a shared lock rather than exclusive lock on each retrieved + row. A shared lock blocks other transactions from performing + UPDATE, DELETE, + SELECT FOR UPDATE or + SELECT FOR NO KEY UPDATE on these rows, but it does not + prevent them from performing SELECT FOR SHARE or + SELECT FOR KEY SHARE. + + + + + + + FOR KEY SHARE + + + + Behaves similarly to FOR SHARE, except that the + lock is weaker: SELECT FOR UPDATE is blocked, but not + SELECT FOR NO KEY UPDATE. A key-shared lock blocks + other transactions from performing DELETE or + any UPDATE that changes the key values, but not + other UPDATE, and neither does it prevent + SELECT FOR NO KEY UPDATE, SELECT FOR SHARE, + or SELECT FOR KEY SHARE. + + + + + + + PostgreSQL doesn't remember any + information about modified rows in memory, so there is no limit on + the number of rows locked at one time. However, locking a row + might cause a disk write, e.g., SELECT FOR + UPDATE modifies selected rows to mark them locked, and so + will result in disk writes. + + + + Conflicting Row-Level Locks + + + + + + + + + + Requested Lock Mode + Current Lock Mode + + + FOR KEY SHARE + FOR SHARE + FOR NO KEY UPDATE + FOR UPDATE + + + + + FOR KEY SHARE + + + + X + + + FOR SHARE + + + X + X + + + FOR NO KEY UPDATE + + X + X + X + + + FOR UPDATE + X + X + X + X + + + +
+
+ + + Page-Level Locks + + + In addition to table and row locks, page-level share/exclusive locks are + used to control read/write access to table pages in the shared buffer + pool. These locks are released immediately after a row is fetched or + updated. Application developers normally need not be concerned with + page-level locks, but they are mentioned here for completeness. + + + + + + Deadlocks + + + deadlock + + + + The use of explicit locking can increase the likelihood of + deadlocks, wherein two (or more) transactions each + hold locks that the other wants. For example, if transaction 1 + acquires an exclusive lock on table A and then tries to acquire + an exclusive lock on table B, while transaction 2 has already + exclusive-locked table B and now wants an exclusive lock on table + A, then neither one can proceed. + PostgreSQL automatically detects + deadlock situations and resolves them by aborting one of the + transactions involved, allowing the other(s) to complete. + (Exactly which transaction will be aborted is difficult to + predict and should not be relied upon.) + + + + Note that deadlocks can also occur as the result of row-level + locks (and thus, they can occur even if explicit locking is not + used). Consider the case in which two concurrent + transactions modify a table. The first transaction executes: + + +UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111; + + + This acquires a row-level lock on the row with the specified + account number. Then, the second transaction executes: + + +UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222; +UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111; + + + The first UPDATE statement successfully + acquires a row-level lock on the specified row, so it succeeds in + updating that row. However, the second UPDATE + statement finds that the row it is attempting to update has + already been locked, so it waits for the transaction that + acquired the lock to complete. Transaction two is now waiting on + transaction one to complete before it continues execution. Now, + transaction one executes: + + +UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; + + + Transaction one attempts to acquire a row-level lock on the + specified row, but it cannot: transaction two already holds such + a lock. So it waits for transaction two to complete. Thus, + transaction one is blocked on transaction two, and transaction + two is blocked on transaction one: a deadlock + condition. PostgreSQL will detect this + situation and abort one of the transactions. + + + + The best defense against deadlocks is generally to avoid them by + being certain that all applications using a database acquire + locks on multiple objects in a consistent order. In the example + above, if both transactions + had updated the rows in the same order, no deadlock would have + occurred. One should also ensure that the first lock acquired on + an object in a transaction is the most restrictive mode that will be + needed for that object. If it is not feasible to verify this in + advance, then deadlocks can be handled on-the-fly by retrying + transactions that abort due to deadlocks. + + + + So long as no deadlock situation is detected, a transaction seeking + either a table-level or row-level lock will wait indefinitely for + conflicting locks to be released. This means it is a bad idea for + applications to hold transactions open for long periods of time + (e.g., while waiting for user input). + + + + + Advisory Locks + + + advisory lock + + + + lock + advisory + + + + PostgreSQL provides a means for + creating locks that have application-defined meanings. These are + called advisory locks, because the system does not + enforce their use — it is up to the application to use them + correctly. Advisory locks can be useful for locking strategies + that are an awkward fit for the MVCC model. + For example, a common use of advisory locks is to emulate pessimistic + locking strategies typical of so-called flat file data + management systems. + While a flag stored in a table could be used for the same purpose, + advisory locks are faster, avoid table bloat, and are automatically + cleaned up by the server at the end of the session. + + + + There are two ways to acquire an advisory lock in + PostgreSQL: at session level or at + transaction level. + Once acquired at session level, an advisory lock is held until + explicitly released or the session ends. Unlike standard lock requests, + session-level advisory lock requests do not honor transaction semantics: + a lock acquired during a transaction that is later rolled back will still + be held following the rollback, and likewise an unlock is effective even + if the calling transaction fails later. A lock can be acquired multiple + times by its owning process; for each completed lock request there must + be a corresponding unlock request before the lock is actually released. + Transaction-level lock requests, on the other hand, behave more like + regular lock requests: they are automatically released at the end of the + transaction, and there is no explicit unlock operation. This behavior + is often more convenient than the session-level behavior for short-term + usage of an advisory lock. + Session-level and transaction-level lock requests for the same advisory + lock identifier will block each other in the expected way. + If a session already holds a given advisory lock, additional requests by + it will always succeed, even if other sessions are awaiting the lock; this + statement is true regardless of whether the existing lock hold and new + request are at session level or transaction level. + + + + Like all locks in + PostgreSQL, a complete list of advisory locks + currently held by any session can be found in the pg_locks system + view. + + + + Both advisory locks and regular locks are stored in a shared memory + pool whose size is defined by the configuration variables + and + . + Care must be taken not to exhaust this + memory or the server will be unable to grant any locks at all. + This imposes an upper limit on the number of advisory locks + grantable by the server, typically in the tens to hundreds of thousands + depending on how the server is configured. + + + + In certain cases using advisory locking methods, especially in queries + involving explicit ordering and LIMIT clauses, care must be + taken to control the locks acquired because of the order in which SQL + expressions are evaluated. For example: + +SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok +SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100; -- danger! +SELECT pg_advisory_lock(q.id) FROM +( + SELECT id FROM foo WHERE id > 12345 LIMIT 100 +) q; -- ok + + In the above queries, the second form is dangerous because the + LIMIT is not guaranteed to be applied before the locking + function is executed. This might cause some locks to be acquired + that the application was not expecting, and hence would fail to release + (until it ends the session). + From the point of view of the application, such locks + would be dangling, although still viewable in + pg_locks. + + + + The functions provided to manipulate advisory locks are described in + . + + + +
+ + + Data Consistency Checks at the Application Level + + + It is very difficult to enforce business rules regarding data integrity + using Read Committed transactions because the view of the data is + shifting with each statement, and even a single statement may not + restrict itself to the statement's snapshot if a write conflict occurs. + + + + While a Repeatable Read transaction has a stable view of the data + throughout its execution, there is a subtle issue with using + MVCC snapshots for data consistency checks, involving + something known as read/write conflicts. + If one transaction writes data and a concurrent transaction attempts + to read the same data (whether before or after the write), it cannot + see the work of the other transaction. The reader then appears to have + executed first regardless of which started first or which committed + first. If that is as far as it goes, there is no problem, but + if the reader also writes data which is read by a concurrent transaction + there is now a transaction which appears to have run before either of + the previously mentioned transactions. If the transaction which appears + to have executed last actually commits first, it is very easy for a + cycle to appear in a graph of the order of execution of the transactions. + When such a cycle appears, integrity checks will not work correctly + without some help. + + + + As mentioned in , Serializable + transactions are just Repeatable Read transactions which add + nonblocking monitoring for dangerous patterns of read/write conflicts. + When a pattern is detected which could cause a cycle in the apparent + order of execution, one of the transactions involved is rolled back to + break the cycle. + + + + Enforcing Consistency with Serializable Transactions + + + If the Serializable transaction isolation level is used for all writes + and for all reads which need a consistent view of the data, no other + effort is required to ensure consistency. Software from other + environments which is written to use serializable transactions to + ensure consistency should just work in this regard in + PostgreSQL. + + + + When using this technique, it will avoid creating an unnecessary burden + for application programmers if the application software goes through a + framework which automatically retries transactions which are rolled + back with a serialization failure. It may be a good idea to set + default_transaction_isolation to serializable. + It would also be wise to take some action to ensure that no other + transaction isolation level is used, either inadvertently or to + subvert integrity checks, through checks of the transaction isolation + level in triggers. + + + + See for performance suggestions. + + + + + This level of integrity protection using Serializable transactions + does not yet extend to hot standby mode (). + Because of that, those using hot standby may want to use Repeatable + Read and explicit locking on the primary. + + + + + + Enforcing Consistency with Explicit Blocking Locks + + + When non-serializable writes are possible, + to ensure the current validity of a row and protect it against + concurrent updates one must use SELECT FOR UPDATE, + SELECT FOR SHARE, or an appropriate LOCK + TABLE statement. (SELECT FOR UPDATE + and SELECT FOR SHARE lock just the + returned rows against concurrent updates, while LOCK + TABLE locks the whole table.) This should be taken into + account when porting applications to + PostgreSQL from other environments. + + + + Also of note to those converting from other environments is the fact + that SELECT FOR UPDATE does not ensure that a + concurrent transaction will not update or delete a selected row. + To do that in PostgreSQL you must actually + update the row, even if no values need to be changed. + SELECT FOR UPDATE temporarily blocks + other transactions from acquiring the same lock or executing an + UPDATE or DELETE which would + affect the locked row, but once the transaction holding this lock + commits or rolls back, a blocked transaction will proceed with the + conflicting operation unless an actual UPDATE of + the row was performed while the lock was held. + + + + Global validity checks require extra thought under + non-serializable MVCC. + For example, a banking application might wish to check that the sum of + all credits in one table equals the sum of debits in another table, + when both tables are being actively updated. Comparing the results of two + successive SELECT sum(...) commands will not work reliably in + Read Committed mode, since the second query will likely include the results + of transactions not counted by the first. Doing the two sums in a + single repeatable read transaction will give an accurate picture of only the + effects of transactions that committed before the repeatable read transaction + started — but one might legitimately wonder whether the answer is still + relevant by the time it is delivered. If the repeatable read transaction + itself applied some changes before trying to make the consistency check, + the usefulness of the check becomes even more debatable, since now it + includes some but not all post-transaction-start changes. In such cases + a careful person might wish to lock all tables needed for the check, + in order to get an indisputable picture of current reality. A + SHARE mode (or higher) lock guarantees that there are no + uncommitted changes in the locked table, other than those of the current + transaction. + + + + Note also that if one is relying on explicit locking to prevent concurrent + changes, one should either use Read Committed mode, or in Repeatable Read + mode be careful to obtain + locks before performing queries. A lock obtained by a + repeatable read transaction guarantees that no other transactions modifying + the table are still running, but if the snapshot seen by the + transaction predates obtaining the lock, it might predate some now-committed + changes in the table. A repeatable read transaction's snapshot is actually + frozen at the start of its first query or data-modification command + (SELECT, INSERT, + UPDATE, or DELETE), so + it is possible to obtain locks explicitly before the snapshot is + frozen. + + + + + + Caveats + + + Some DDL commands, currently only TRUNCATE and the + table-rewriting forms of ALTER TABLE, are not + MVCC-safe. This means that after the truncation or rewrite commits, the + table will appear empty to concurrent transactions, if they are using a + snapshot taken before the DDL command committed. This will only be an + issue for a transaction that did not access the table in question + before the DDL command started — any transaction that has done so + would hold at least an ACCESS SHARE table lock, + which would block the DDL command until that transaction completes. + So these commands will not cause any apparent inconsistency in the + table contents for successive queries on the target table, but they + could cause visible inconsistency between the contents of the target + table and other tables in the database. + + + + Support for the Serializable transaction isolation level has not yet + been added to Hot Standby replication targets (described in + ). The strictest isolation level currently + supported in hot standby mode is Repeatable Read. While performing all + permanent database writes within Serializable transactions on the + primary will ensure that all standbys will eventually reach a consistent + state, a Repeatable Read transaction run on the standby can sometimes + see a transient state that is inconsistent with any serial execution + of the transactions on the primary. + + + + Internal access to the system catalogs is not done using the isolation + level of the current transaction. This means that newly created database + objects such as tables are visible to concurrent Repeatable Read and + Serializable transactions, even though the rows they contain are not. In + contrast, queries that explicitly examine the system catalogs don't see + rows representing concurrently created database objects, in the higher + isolation levels. + + + + + Locking and Indexes + + + index + locks + + + + Though PostgreSQL + provides nonblocking read/write access to table + data, nonblocking read/write access is not currently offered for every + index access method implemented + in PostgreSQL. + The various index types are handled as follows: + + + + + B-tree, GiST and SP-GiST indexes + + + + Short-term share/exclusive page-level locks are used for + read/write access. Locks are released immediately after each + index row is fetched or inserted. These index types provide + the highest concurrency without deadlock conditions. + + + + + + + Hash indexes + + + + Share/exclusive hash-bucket-level locks are used for read/write + access. Locks are released after the whole bucket is processed. + Bucket-level locks provide better concurrency than index-level + ones, but deadlock is possible since the locks are held longer + than one index operation. + + + + + + + GIN indexes + + + + Short-term share/exclusive page-level locks are used for + read/write access. Locks are released immediately after each + index row is fetched or inserted. But note that insertion of a + GIN-indexed value usually produces several index key insertions + per row, so GIN might do substantial work for a single value's + insertion. + + + + + + + + Currently, B-tree indexes offer the best performance for concurrent + applications; since they also have more features than hash + indexes, they are the recommended index type for concurrent + applications that need to index scalar data. When dealing with + non-scalar data, B-trees are not useful, and GiST, SP-GiST or GIN + indexes should be used instead. + + +
diff --git a/doc/src/sgml/nls.sgml b/doc/src/sgml/nls.sgml new file mode 100644 index 000000000000..d49f44f3f23b --- /dev/null +++ b/doc/src/sgml/nls.sgml @@ -0,0 +1,532 @@ + + + + Native Language Support + + + For the Translator + + + PostgreSQL + programs (server and client) can issue their messages in + your favorite language — if the messages have been translated. + Creating and maintaining translated message sets needs the help of + people who speak their own language well and want to contribute to + the PostgreSQL effort. You do not have to be a + programmer at all + to do this. This section explains how to help. + + + + Requirements + + + We won't judge your language skills — this section is about + software tools. Theoretically, you only need a text editor. But + this is only in the unlikely event that you do not want to try out + your translated messages. When you configure your source tree, be + sure to use the option. This will + also check for the libintl library and the + msgfmt program, which all end users will need + anyway. To try out your work, follow the applicable portions of + the installation instructions. + + + + If you want to start a new translation effort or want to do a + message catalog merge (described later), you will need the + programs xgettext and + msgmerge, respectively, in a GNU-compatible + implementation. Later, we will try to arrange it so that if you + use a packaged source distribution, you won't need + xgettext. (If working from Git, you will still need + it.) GNU Gettext 0.10.36 or later is currently recommended. + + + + Your local gettext implementation should come with its own + documentation. Some of that is probably duplicated in what + follows, but for additional details you should look there. + + + + + Concepts + + + The pairs of original (English) messages and their (possibly) + translated equivalents are kept in message + catalogs, one for each program (although related + programs can share a message catalog) and for each target + language. There are two file formats for message catalogs: The + first is the PO file (for Portable Object), which + is a plain text file with special syntax that translators edit. + The second is the MO file (for Machine Object), + which is a binary file generated from the respective PO file and + is used while the internationalized program is run. Translators + do not deal with MO files; in fact hardly anyone does. + + + + The extension of the message catalog file is to no surprise either + .po or .mo. The base + name is either the name of the program it accompanies, or the + language the file is for, depending on the situation. This is a + bit confusing. Examples are psql.po (PO file + for psql) or fr.mo (MO file in French). + + + + The file format of the PO files is illustrated here: + +# comment + +msgid "original string" +msgstr "translated string" + +msgid "more original" +msgstr "another translated" +"string can be broken up like this" + +... + + The msgid lines are extracted from the program source. (They need not + be, but this is the most common way.) The msgstr lines are + initially empty and are filled in with useful strings by the + translator. The strings can contain C-style escape characters and + can be continued across lines as illustrated. (The next line must + start at the beginning of the line.) + + + + The # character introduces a comment. If whitespace immediately + follows the # character, then this is a comment maintained by the + translator. There can also be automatic comments, which have a + non-whitespace character immediately following the #. These are + maintained by the various tools that operate on the PO files and + are intended to aid the translator. + +#. automatic comment +#: filename.c:1023 +#, flags, flags + + The #. style comments are extracted from the source file where the + message is used. Possibly the programmer has inserted information + for the translator, such as about expected alignment. The #: + comments indicate the exact locations where the message is used + in the source. The translator need not look at the program + source, but can if there is doubt about the correct + translation. The #, comments contain flags that describe the + message in some way. There are currently two flags: + fuzzy is set if the message has possibly been + outdated because of changes in the program source. The translator + can then verify this and possibly remove the fuzzy flag. Note + that fuzzy messages are not made available to the end user. The + other flag is c-format, which indicates that + the message is a printf-style format + template. This means that the translation should also be a format + string with the same number and type of placeholders. There are + tools that can verify this, which key off the c-format flag. + + + + + Creating and Maintaining Message Catalogs + + + OK, so how does one create a blank message + catalog? First, go into the directory that contains the program + whose messages you want to translate. If there is a file + nls.mk, then this program has been prepared + for translation. + + + + If there are already some .po files, then + someone has already done some translation work. The files are + named language.po, + where language is the + + ISO 639-1 two-letter language code (in lower case), e.g., + fr.po for French. If there is really a need + for more than one translation effort per language then the files + can also be named + language_region.po + where region is the + + ISO 3166-1 two-letter country code (in upper case), + e.g., + pt_BR.po for Portuguese in Brazil. If you + find the language you wanted you can just start working on that + file. + + + + If you need to start a new translation effort, then first run the + command: + +make init-po + + This will create a file + progname.pot. + (.pot to distinguish it from PO files that + are in production. The T stands for + template.) + Copy this file to + language.po and + edit it. To make it known that the new language is available, + also edit the file nls.mk and add the + language (or language and country) code to the line that looks like: + +AVAIL_LANGUAGES := de fr + + (Other languages can appear, of course.) + + + + As the underlying program or library changes, messages might be + changed or added by the programmers. In this case you do not need + to start from scratch. Instead, run the command: + +make update-po + + which will create a new blank message catalog file (the pot file + you started with) and will merge it with the existing PO files. + If the merge algorithm is not sure about a particular message it + marks it fuzzy as explained above. The new PO file + is saved with a .po.new extension. + + + + + Editing the PO Files + + + The PO files can be edited with a regular text editor. The + translator should only change the area between the quotes after + the msgstr directive, add comments, and alter the fuzzy flag. + There is (unsurprisingly) a PO mode for Emacs, which I find quite + useful. + + + + The PO files need not be completely filled in. The software will + automatically fall back to the original string if no translation + (or an empty translation) is available. It is no problem to + submit incomplete translations for inclusions in the source tree; + that gives room for other people to pick up your work. However, + you are encouraged to give priority to removing fuzzy entries + after doing a merge. Remember that fuzzy entries will not be + installed; they only serve as reference for what might be the right + translation. + + + + Here are some things to keep in mind while editing the + translations: + + + + Make sure that if the original ends with a newline, the + translation does, too. Similarly for tabs, etc. + + + + + + If the original is a printf format string, the translation + also needs to be. The translation also needs to have the same + format specifiers in the same order. Sometimes the natural + rules of the language make this impossible or at least awkward. + In that case you can modify the format specifiers like this: + +msgstr "Die Datei %2$s hat %1$u Zeichen." + + Then the first placeholder will actually use the second + argument from the list. The + digits$ needs to + follow the % immediately, before any other format manipulators. + (This feature really exists in the printf + family of functions. You might not have heard of it before because + there is little use for it outside of message + internationalization.) + + + + + + If the original string contains a linguistic mistake, report + that (or fix it yourself in the program source) and translate + normally. The corrected string can be merged in when the + program sources have been updated. If the original string + contains a factual mistake, report that (or fix it yourself) + and do not translate it. Instead, you can mark the string with + a comment in the PO file. + + + + + + Maintain the style and tone of the original string. + Specifically, messages that are not sentences (cannot + open file %s) should probably not start with a + capital letter (if your language distinguishes letter case) or + end with a period (if your language uses punctuation marks). + It might help to read . + + + + + + If you don't know what a message means, or if it is ambiguous, + ask on the developers' mailing list. Chances are that English + speaking end users might also not understand it or find it + ambiguous, so it's best to improve the message. + + + + + + + + + + + + For the Programmer + + + Mechanics + + + This section describes how to implement native language support in a + program or library that is part of the + PostgreSQL distribution. + Currently, it only applies to C programs. + + + + Adding NLS Support to a Program + + + + Insert this code into the start-up sequence of the program: + +#ifdef ENABLE_NLS +#include <locale.h> +#endif + +... + +#ifdef ENABLE_NLS +setlocale(LC_ALL, ""); +bindtextdomain("progname", LOCALEDIR); +textdomain("progname"); +#endif + + (The progname can actually be chosen + freely.) + + + + + + Wherever a message that is a candidate for translation is found, + a call to gettext() needs to be inserted. E.g.: + +fprintf(stderr, "panic level %d\n", lvl); + + would be changed to: + +fprintf(stderr, gettext("panic level %d\n"), lvl); + + (gettext is defined as a no-op if NLS support is + not configured.) + + + + This tends to add a lot of clutter. One common shortcut is to use: + +#define _(x) gettext(x) + + Another solution is feasible if the program does much of its + communication through one or a few functions, such as + ereport() in the backend. Then you make this + function call gettext internally on all + input strings. + + + + + + Add a file nls.mk in the directory with the + program sources. This file will be read as a makefile. The + following variable assignments need to be made here: + + + + CATALOG_NAME + + + + The program name, as provided in the + textdomain() call. + + + + + + AVAIL_LANGUAGES + + + + List of provided translations — initially empty. + + + + + + GETTEXT_FILES + + + + List of files that contain translatable strings, i.e., those + marked with gettext or an alternative + solution. Eventually, this will include nearly all source + files of the program. If this list gets too long you can + make the first file be a + + and the second word be a file that contains one file name per + line. + + + + + + GETTEXT_TRIGGERS + + + + The tools that generate message catalogs for the translators + to work on need to know what function calls contain + translatable strings. By default, only + gettext() calls are known. If you used + _ or other identifiers you need to list + them here. If the translatable string is not the first + argument, the item needs to be of the form + func:2 (for the second argument). + If you have a function that supports pluralized messages, + the item should look like func:1,2 + (identifying the singular and plural message arguments). + + + + + + + + + + + The build system will automatically take care of building and + installing the message catalogs. + + + + + Message-Writing Guidelines + + + Here are some guidelines for writing messages that are easily + translatable. + + + + + Do not construct sentences at run-time, like: + +printf("Files were %s.\n", flag ? "copied" : "removed"); + + The word order within the sentence might be different in other + languages. Also, even if you remember to call gettext() on + each fragment, the fragments might not translate well separately. It's + better to duplicate a little code so that each message to be + translated is a coherent whole. Only numbers, file names, and + such-like run-time variables should be inserted at run time into + a message text. + + + + + + For similar reasons, this won't work: + +printf("copied %d file%s", n, n!=1 ? "s" : ""); + + because it assumes how the plural is formed. If you figured you + could solve it like this: + +if (n==1) + printf("copied 1 file"); +else + printf("copied %d files", n): + + then be disappointed. Some languages have more than two forms, + with some peculiar rules. It's often best to design the message + to avoid the issue altogether, for instance like this: + +printf("number of copied files: %d", n); + + + + + If you really want to construct a properly pluralized message, + there is support for this, but it's a bit awkward. When generating + a primary or detail error message in ereport(), you can + write something like this: + +errmsg_plural("copied %d file", + "copied %d files", + n, + n) + + The first argument is the format string appropriate for English + singular form, the second is the format string appropriate for + English plural form, and the third is the integer control value + that determines which plural form to use. Subsequent arguments + are formatted per the format string as usual. (Normally, the + pluralization control value will also be one of the values to be + formatted, so it has to be written twice.) In English it only + matters whether n is 1 or not 1, but in other + languages there can be many different plural forms. The translator + sees the two English forms as a group and has the opportunity to + supply multiple substitute strings, with the appropriate one being + selected based on the run-time value of n. + + + + If you need to pluralize a message that isn't going directly to an + errmsg or errdetail report, you have to use + the underlying function ngettext. See the gettext + documentation. + + + + + + If you want to communicate something to the translator, such as + about how a message is intended to line up with other output, + precede the occurrence of the string with a comment that starts + with translator, e.g.: + +/* translator: This message is not what it seems to be. */ + + These comments are copied to the message catalog files so that + the translators can see them. + + + + + + + + diff --git a/doc/src/sgml/oldsnapshot.sgml b/doc/src/sgml/oldsnapshot.sgml new file mode 100644 index 000000000000..a665ae72e789 --- /dev/null +++ b/doc/src/sgml/oldsnapshot.sgml @@ -0,0 +1,33 @@ + + + + old_snapshot + + + old_snapshot + + + + The old_snapshot module allows inspection + of the server state that is used to implement + . + + + + Functions + + + + pg_old_snapshot_time_mapping(array_offset OUT int4, end_timestamp OUT timestamptz, newest_xmin OUT xid) returns setof record + + + Returns all of the entries in the server's timestamp to XID mapping. + Each entry represents the newest xmin of any snapshot taken in the + corresponding minute. + + + + + + + diff --git a/doc/src/sgml/pageinspect.sgml b/doc/src/sgml/pageinspect.sgml new file mode 100644 index 000000000000..24b5e463ed9a --- /dev/null +++ b/doc/src/sgml/pageinspect.sgml @@ -0,0 +1,913 @@ + + + + pageinspect + + + pageinspect + + + + The pageinspect module provides functions that allow you to + inspect the contents of database pages at a low level, which is useful for + debugging purposes. All of these functions may be used only by superusers. + + + + General Functions + + + + + get_raw_page(relname text, fork text, blkno bigint) returns bytea + + get_raw_page + + + + + + get_raw_page reads the specified block of the named + relation and returns a copy as a bytea value. This allows a + single time-consistent copy of the block to be obtained. + fork should be 'main' for + the main data fork, 'fsm' for the free space map, + 'vm' for the visibility map, or 'init' + for the initialization fork. + + + + + + + get_raw_page(relname text, blkno bigint) returns bytea + + + + + A shorthand version of get_raw_page, for reading + from the main fork. Equivalent to + get_raw_page(relname, 'main', blkno) + + + + + + + page_header(page bytea) returns record + + page_header + + + + + + page_header shows fields that are common to all + PostgreSQL heap and index pages. + + + + A page image obtained with get_raw_page should be + passed as argument. For example: + +test=# SELECT * FROM page_header(get_raw_page('pg_class', 0)); + lsn | checksum | flags | lower | upper | special | pagesize | version | prune_xid +-----------+----------+--------+-------+-------+---------+----------+---------+----------- + 0/24A1B50 | 0 | 1 | 232 | 368 | 8192 | 8192 | 4 | 0 + + The returned columns correspond to the fields in the + PageHeaderData struct. + See src/include/storage/bufpage.h for details. + + + + The checksum field is the checksum stored in + the page, which might be incorrect if the page is somehow corrupted. If + data checksums are not enabled for this instance, then the value stored + is meaningless. + + + + + + + page_checksum(page bytea, blkno bigint) returns smallint + + page_checksum + + + + + + page_checksum computes the checksum for the page, as if + it was located at the given block. + + + + A page image obtained with get_raw_page should be + passed as argument. For example: + +test=# SELECT page_checksum(get_raw_page('pg_class', 0), 0); + page_checksum +--------------- + 13443 + + Note that the checksum depends on the block number, so matching block + numbers should be passed (except when doing esoteric debugging). + + + + The checksum computed with this function can be compared with + the checksum result field of the + function page_header. If data checksums are + enabled for this instance, then the two values should be equal. + + + + + + + fsm_page_contents(page bytea) returns text + + fsm_page_contents + + + + + + fsm_page_contents shows the internal node structure + of an FSM page. For example: + +test=# SELECT fsm_page_contents(get_raw_page('pg_class', 'fsm', 0)); + + The output is a multiline string, with one line per node in the binary + tree within the page. Only those nodes that are not zero are printed. + The so-called "next" pointer, which points to the next slot to be + returned from the page, is also printed. + + + See src/backend/storage/freespace/README for more + information on the structure of an FSM page. + + + + + + + + Heap Functions + + + + + heap_page_items(page bytea) returns setof record + + heap_page_items + + + + + + heap_page_items shows all line pointers on a heap + page. For those line pointers that are in use, tuple headers as well + as tuple raw data are also shown. All tuples are shown, whether or not + the tuples were visible to an MVCC snapshot at the time the raw page + was copied. + + + A heap page image obtained with get_raw_page should + be passed as argument. For example: + +test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0)); + + See src/include/storage/itemid.h and + src/include/access/htup_details.h for explanations of the fields + returned. + + + The heap_tuple_infomask_flags function can be + used to unpack the flag bits of t_infomask + and t_infomask2 for heap tuples. + + + + + + + tuple_data_split(rel_oid oid, t_data bytea, t_infomask integer, t_infomask2 integer, t_bits text [, do_detoast bool]) returns bytea[] + + tuple_data_split + + + + + tuple_data_split splits tuple data into attributes + in the same way as backend internals. + +test=# SELECT tuple_data_split('pg_class'::regclass, t_data, t_infomask, t_infomask2, t_bits) FROM heap_page_items(get_raw_page('pg_class', 0)); + + This function should be called with the same arguments as the return + attributes of heap_page_items. + + + If do_detoast is true, + attributes will be detoasted as needed. Default value is + false. + + + + + + + heap_page_item_attrs(page bytea, rel_oid regclass [, do_detoast bool]) returns setof record + + heap_page_item_attrs + + + + + heap_page_item_attrs is equivalent to + heap_page_items except that it returns + tuple raw data as an array of attributes that can optionally + be detoasted by do_detoast which is + false by default. + + + A heap page image obtained with get_raw_page should + be passed as argument. For example: + +test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class'::regclass); + + + + + + + + heap_tuple_infomask_flags(t_infomask integer, t_infomask2 integer) returns record + + heap_tuple_infomask_flags + + + + + heap_tuple_infomask_flags decodes the + t_infomask and + t_infomask2 returned by + heap_page_items into a human-readable + set of arrays made of flag names, with one column for all + the flags and one column for combined flags. For example: + +test=# SELECT t_ctid, raw_flags, combined_flags + FROM heap_page_items(get_raw_page('pg_class', 0)), + LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2) + WHERE t_infomask IS NOT NULL OR t_infomask2 IS NOT NULL; + + This function should be called with the same arguments as the return + attributes of heap_page_items. + + + Combined flags are displayed for source-level macros that take into + account the value of more than one raw bit, such as + HEAP_XMIN_FROZEN. + + + See src/include/access/htup_details.h for + explanations of the flag names returned. + + + + + + + + B-Tree Functions + + + + + bt_metap(relname text) returns record + + bt_metap + + + + + + bt_metap returns information about a B-tree + index's metapage. For example: + +test=# SELECT * FROM bt_metap('pg_cast_oid_index'); +-[ RECORD 1 ]-------------+------- +magic | 340322 +version | 4 +root | 1 +level | 0 +fastroot | 1 +fastlevel | 0 +last_cleanup_num_delpages | 0 +last_cleanup_num_tuples | 230 +allequalimage | f + + + + + + + + bt_page_stats(relname text, blkno bigint) returns record + + bt_page_stats + + + + + + bt_page_stats returns summary information about + single pages of B-tree indexes. For example: + +test=# SELECT * FROM bt_page_stats('pg_cast_oid_index', 1); +-[ RECORD 1 ]-+----- +blkno | 1 +type | l +live_items | 224 +dead_items | 0 +avg_item_size | 16 +page_size | 8192 +free_size | 3668 +btpo_prev | 0 +btpo_next | 0 +btpo_level | 0 +btpo_flags | 3 + + + + + + + + bt_page_items(relname text, blkno bigint) returns setof record + + bt_page_items + + + + + + bt_page_items returns detailed information about + all of the items on a B-tree index page. For example: + +test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids + FROM bt_page_items('tenk2_hundred', 5); + itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids +------------+-----------+---------+-------+------+-------------------------+------+--------+--------------------- + 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | | + 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"} + 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"} + 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"} + 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"} + 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"} + 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"} + 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"} + 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"} + 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"} + 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"} + 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"} + 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} +(13 rows) + + This is a B-tree leaf page. All tuples that point to the table + happen to be posting list tuples (all of which store a total of + 100 6 byte TIDs). There is also a high key tuple + at itemoffset number 1. + ctid is used to store encoded + information about each tuple in this example, though leaf page + tuples often store a heap TID directly in the + ctid field instead. + tids is the list of TIDs stored as a + posting list. + + + In an internal page (not shown), the block number part of + ctid is a downlink, + which is a block number of another page in the index itself. + The offset part (the second number) of + ctid stores encoded information about + the tuple, such as the number of columns present (suffix + truncation may have removed unneeded suffix columns). Truncated + columns are treated as having the value minus + infinity. + + + htid shows a heap TID for the tuple, + regardless of the underlying tuple representation. This value + may match ctid, or may be decoded + from the alternative representations used by posting list tuples + and tuples from internal pages. Tuples in internal pages + usually have the implementation level heap TID column truncated + away, which is represented as a NULL + htid value. + + + Note that the first item on any non-rightmost page (any page with + a non-zero value in the btpo_next field) is the + page's high key, meaning its data + serves as an upper bound on all items appearing on the page, while + its ctid field does not point to + another block. Also, on internal pages, the first real data + item (the first item that is not a high key) reliably has every + column truncated away, leaving no actual value in its + data field. Such an item does have a + valid downlink in its ctid field, + however. + + + For more details about the structure of B-tree indexes, see + . For more details about + deduplication and posting lists, see . + + + + + + + bt_page_items(page bytea) returns setof record + + bt_page_items + + + + + + It is also possible to pass a page to bt_page_items + as a bytea value. A page image obtained + with get_raw_page should be passed as argument. So + the last example could also be rewritten like this: + +test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids + FROM bt_page_items(get_raw_page('tenk2_hundred', 5)); + itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids +------------+-----------+---------+-------+------+-------------------------+------+--------+--------------------- + 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | | + 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"} + 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"} + 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"} + 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"} + 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"} + 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"} + 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"} + 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"} + 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"} + 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"} + 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"} + 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"} +(13 rows) + + All the other details are the same as explained in the previous item. + + + + + + + + BRIN Functions + + + + + brin_page_type(page bytea) returns text + + brin_page_type + + + + + + brin_page_type returns the page type of the given + BRIN index page, or throws an error if the page is + not a valid BRIN page. For example: + +test=# SELECT brin_page_type(get_raw_page('brinidx', 0)); + brin_page_type +---------------- + meta + + + + + + + + brin_metapage_info(page bytea) returns record + + brin_metapage_info + + + + + + brin_metapage_info returns assorted information + about a BRIN index metapage. For example: + +test=# SELECT * FROM brin_metapage_info(get_raw_page('brinidx', 0)); + magic | version | pagesperrange | lastrevmappage +------------+---------+---------------+---------------- + 0xA8109CFA | 1 | 4 | 2 + + + + + + + + brin_revmap_data(page bytea) returns setof tid + + brin_revmap_data + + + + + + brin_revmap_data returns the list of tuple + identifiers in a BRIN index range map page. + For example: + +test=# SELECT * FROM brin_revmap_data(get_raw_page('brinidx', 2)) LIMIT 5; + pages +--------- + (6,137) + (6,138) + (6,139) + (6,140) + (6,141) + + + + + + + + brin_page_items(page bytea, index oid) returns setof record + + brin_page_items + + + + + + brin_page_items returns the data stored in the + BRIN data page. For example: + +test=# SELECT * FROM brin_page_items(get_raw_page('brinidx', 5), + 'brinidx') + ORDER BY blknum, attnum LIMIT 6; + itemoffset | blknum | attnum | allnulls | hasnulls | placeholder | value +------------+--------+--------+----------+----------+-------------+-------------- + 137 | 0 | 1 | t | f | f | + 137 | 0 | 2 | f | f | f | {1 .. 88} + 138 | 4 | 1 | t | f | f | + 138 | 4 | 2 | f | f | f | {89 .. 176} + 139 | 8 | 1 | t | f | f | + 139 | 8 | 2 | f | f | f | {177 .. 264} + + The returned columns correspond to the fields in the + BrinMemTuple and BrinValues structs. + See src/include/access/brin_tuple.h for details. + + + + + + + + GIN Functions + + + + + gin_metapage_info(page bytea) returns record + + gin_metapage_info + + + + + + gin_metapage_info returns information about + a GIN index metapage. For example: + +test=# SELECT * FROM gin_metapage_info(get_raw_page('gin_index', 0)); +-[ RECORD 1 ]----+----------- +pending_head | 4294967295 +pending_tail | 4294967295 +tail_free_size | 0 +n_pending_pages | 0 +n_pending_tuples | 0 +n_total_pages | 7 +n_entry_pages | 6 +n_data_pages | 0 +n_entries | 693 +version | 2 + + + + + + + + gin_page_opaque_info(page bytea) returns record + + gin_page_opaque_info + + + + + + gin_page_opaque_info returns information about + a GIN index opaque area, like the page type. + For example: + +test=# SELECT * FROM gin_page_opaque_info(get_raw_page('gin_index', 2)); + rightlink | maxoff | flags +-----------+--------+------------------------ + 5 | 0 | {data,leaf,compressed} +(1 row) + + + + + + + + gin_leafpage_items(page bytea) returns setof record + + gin_leafpage_items + + + + + + gin_leafpage_items returns information about + the data stored in a GIN leaf page. For example: + +test=# SELECT first_tid, nbytes, tids[0:5] AS some_tids + FROM gin_leafpage_items(get_raw_page('gin_test_idx', 2)); + first_tid | nbytes | some_tids +-----------+--------+---------------------------------------------------------- + (8,41) | 244 | {"(8,41)","(8,43)","(8,44)","(8,45)","(8,46)"} + (10,45) | 248 | {"(10,45)","(10,46)","(10,47)","(10,48)","(10,49)"} + (12,52) | 248 | {"(12,52)","(12,53)","(12,54)","(12,55)","(12,56)"} + (14,59) | 320 | {"(14,59)","(14,60)","(14,61)","(14,62)","(14,63)"} + (167,16) | 376 | {"(167,16)","(167,17)","(167,18)","(167,19)","(167,20)"} + (170,30) | 376 | {"(170,30)","(170,31)","(170,32)","(170,33)","(170,34)"} + (173,44) | 197 | {"(173,44)","(173,45)","(173,46)","(173,47)","(173,48)"} +(7 rows) + + + + + + + + + GiST Functions + + + + + gist_page_opaque_info(page bytea) returns record + + gist_page_opaque_info + + + + + + gist_page_opaque_info returns information from + a GiST index page's opaque area, such as the NSN, + rightlink and page type. + For example: + +test=# SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 2)); + lsn | nsn | rightlink | flags +-----+-----+-----------+-------- + 0/1 | 0/0 | 1 | {leaf} +(1 row) + + + + + + + + gist_page_items(page bytea, index_oid regclass) returns setof record + + gist_page_items + + + + + + gist_page_items returns information about + the data stored in a page of a GiST index. For example: + +test=# SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 0), 'test_gist_idx'); + itemoffset | ctid | itemlen | dead | keys +------------+-----------+---------+------+------------------- + 1 | (1,65535) | 40 | f | (p)=((166,166)) + 2 | (2,65535) | 40 | f | (p)=((332,332)) + 3 | (3,65535) | 40 | f | (p)=((498,498)) + 4 | (4,65535) | 40 | f | (p)=((664,664)) + 5 | (5,65535) | 40 | f | (p)=((830,830)) + 6 | (6,65535) | 40 | f | (p)=((996,996)) + 7 | (7,65535) | 40 | f | (p)=((1000,1000)) +(7 rows) + + + + + + + + gist_page_items_bytea(page bytea) returns setof record + + gist_page_items_bytea + + + + + + Same as gist_page_items, but returns the key data + as a raw bytea blob. Since it does not attempt to decode + the key, it does not need to know which index is involved. For + example: + +test=# SELECT * FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0)); + itemoffset | ctid | itemlen | dead | key_data +------------+-----------+---------+------+-----------------------------------------&zwsp;------------------------------------------- + 1 | (1,65535) | 40 | f | \x00000100ffff28000000000000c0644000000000&zwsp;00c06440000000000000f03f000000000000f03f + 2 | (2,65535) | 40 | f | \x00000200ffff28000000000000c0744000000000&zwsp;00c074400000000000e064400000000000e06440 + 3 | (3,65535) | 40 | f | \x00000300ffff28000000000000207f4000000000&zwsp;00207f400000000000d074400000000000d07440 + 4 | (4,65535) | 40 | f | \x00000400ffff28000000000000c0844000000000&zwsp;00c084400000000000307f400000000000307f40 + 5 | (5,65535) | 40 | f | \x00000500ffff28000000000000f0894000000000&zwsp;00f089400000000000c884400000000000c88440 + 6 | (6,65535) | 40 | f | \x00000600ffff28000000000000208f4000000000&zwsp;00208f400000000000f889400000000000f88940 + 7 | (7,65535) | 40 | f | \x00000700ffff28000000000000408f4000000000&zwsp;00408f400000000000288f400000000000288f40 +(7 rows) + + + + + + + + + Hash Functions + + + + + hash_page_type(page bytea) returns text + + hash_page_type + + + + + + hash_page_type returns page type of + the given HASH index page. For example: + +test=# SELECT hash_page_type(get_raw_page('con_hash_index', 0)); + hash_page_type +---------------- + metapage + + + + + + + + hash_page_stats(page bytea) returns setof record + + hash_page_stats + + + + + + hash_page_stats returns information about + a bucket or overflow page of a HASH index. + For example: + +test=# SELECT * FROM hash_page_stats(get_raw_page('con_hash_index', 1)); +-[ RECORD 1 ]---+----------- +live_items | 407 +dead_items | 0 +page_size | 8192 +free_size | 8 +hasho_prevblkno | 4096 +hasho_nextblkno | 8474 +hasho_bucket | 0 +hasho_flag | 66 +hasho_page_id | 65408 + + + + + + + + hash_page_items(page bytea) returns setof record + + hash_page_items + + + + + + hash_page_items returns information about + the data stored in a bucket or overflow page of a HASH + index page. For example: + +test=# SELECT * FROM hash_page_items(get_raw_page('con_hash_index', 1)) LIMIT 5; + itemoffset | ctid | data +------------+-----------+------------ + 1 | (899,77) | 1053474816 + 2 | (897,29) | 1053474816 + 3 | (894,207) | 1053474816 + 4 | (892,159) | 1053474816 + 5 | (890,111) | 1053474816 + + + + + + + + hash_bitmap_info(index oid, blkno bigint) returns record + + hash_bitmap_info + + + + + + hash_bitmap_info shows the status of a bit + in the bitmap page for a particular overflow page of HASH + index. For example: + +test=# SELECT * FROM hash_bitmap_info('con_hash_index', 2052); + bitmapblkno | bitmapbit | bitstatus +-------------+-----------+----------- + 65 | 3 | t + + + + + + + + hash_metapage_info(page bytea) returns record + + hash_metapage_info + + + + + + hash_metapage_info returns information stored + in the meta page of a HASH index. For example: + +test=# SELECT magic, version, ntuples, ffactor, bsize, bmsize, bmshift, +test-# maxbucket, highmask, lowmask, ovflpoint, firstfree, nmaps, procid, +test-# regexp_replace(spares::text, '(,0)*}', '}') as spares, +test-# regexp_replace(mapp::text, '(,0)*}', '}') as mapp +test-# FROM hash_metapage_info(get_raw_page('con_hash_index', 0)); +-[ RECORD 1 ]-------------------------------------------------&zwsp;------------------------------ +magic | 105121344 +version | 4 +ntuples | 500500 +ffactor | 40 +bsize | 8152 +bmsize | 4096 +bmshift | 15 +maxbucket | 12512 +highmask | 16383 +lowmask | 8191 +ovflpoint | 28 +firstfree | 1204 +nmaps | 1 +procid | 450 +spares | {0,0,0,0,0,0,1,1,1,1,1,1,1,1,3,4,4,4,45,55,58,59,&zwsp;508,567,628,704,1193,1202,1204} +mapp | {65} + + + + + + + + diff --git a/doc/src/sgml/parallel.sgml b/doc/src/sgml/parallel.sgml new file mode 100644 index 000000000000..479e24a1dcb0 --- /dev/null +++ b/doc/src/sgml/parallel.sgml @@ -0,0 +1,597 @@ + + + + Parallel Query + + + parallel query + + + + PostgreSQL can devise query plans which can leverage + multiple CPUs in order to answer queries faster. This feature is known + as parallel query. Many queries cannot benefit from parallel query, either + due to limitations of the current implementation or because there is no + imaginable query plan which is any faster than the serial query plan. + However, for queries that can benefit, the speedup from parallel query + is often very significant. Many queries can run more than twice as fast + when using parallel query, and some queries can run four times faster or + even more. Queries that touch a large amount of data but return only a + few rows to the user will typically benefit most. This chapter explains + some details of how parallel query works and in which situations it can be + used so that users who wish to make use of it can understand what to expect. + + + + How Parallel Query Works + + + When the optimizer determines that parallel query is the fastest execution + strategy for a particular query, it will create a query plan which includes + a Gather or Gather Merge + node. Here is a simple example: + + +EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; + QUERY PLAN +-------------------------------------------------------------------&zwsp;------------------ + Gather (cost=1000.00..217018.43 rows=1 width=97) + Workers Planned: 2 + -> Parallel Seq Scan on pgbench_accounts (cost=0.00..216018.33 rows=1 width=97) + Filter: (filler ~~ '%x%'::text) +(4 rows) + + + + + In all cases, the Gather or + Gather Merge node will have exactly one + child plan, which is the portion of the plan that will be executed in + parallel. If the Gather or Gather Merge node is + at the very top of the plan tree, then the entire query will execute in + parallel. If it is somewhere else in the plan tree, then only the portion + of the plan below it will run in parallel. In the example above, the + query accesses only one table, so there is only one plan node other than + the Gather node itself; since that plan node is a child of the + Gather node, it will run in parallel. + + + + Using EXPLAIN, you can see the number of + workers chosen by the planner. When the Gather node is reached + during query execution, the process which is implementing the user's + session will request a number of background + worker processes equal to the number + of workers chosen by the planner. The number of background workers that + the planner will consider using is limited to at most + . The total number + of background workers that can exist at any one time is limited by both + and + . Therefore, it is possible for a + parallel query to run with fewer workers than planned, or even with + no workers at all. The optimal plan may depend on the number of workers + that are available, so this can result in poor query performance. If this + occurrence is frequent, consider increasing + max_worker_processes and max_parallel_workers + so that more workers can be run simultaneously or alternatively reducing + max_parallel_workers_per_gather so that the planner + requests fewer workers. + + + + Every background worker process which is successfully started for a given + parallel query will execute the parallel portion of the plan. The leader + will also execute that portion of the plan, but it has an additional + responsibility: it must also read all of the tuples generated by the + workers. When the parallel portion of the plan generates only a small + number of tuples, the leader will often behave very much like an additional + worker, speeding up query execution. Conversely, when the parallel portion + of the plan generates a large number of tuples, the leader may be almost + entirely occupied with reading the tuples generated by the workers and + performing any further processing steps which are required by plan nodes + above the level of the Gather node or + Gather Merge node. In such cases, the leader will + do very little of the work of executing the parallel portion of the plan. + + + + When the node at the top of the parallel portion of the plan is + Gather Merge rather than Gather, it indicates that + each process executing the parallel portion of the plan is producing + tuples in sorted order, and that the leader is performing an + order-preserving merge. In contrast, Gather reads tuples + from the workers in whatever order is convenient, destroying any sort + order that may have existed. + + + + + When Can Parallel Query Be Used? + + + There are several settings which can cause the query planner not to + generate a parallel query plan under any circumstances. In order for + any parallel query plans whatsoever to be generated, the following + settings must be configured as indicated. + + + + + + must be set to a + value which is greater than zero. This is a special case of the more + general principle that no more workers should be used than the number + configured via max_parallel_workers_per_gather. + + + + + + In addition, the system must not be running in single-user mode. Since + the entire database system is running in single process in this situation, + no background workers will be available. + + + + Even when it is in general possible for parallel query plans to be + generated, the planner will not generate them for a given query + if any of the following are true: + + + + + + The query writes any data or locks any database rows. If a query + contains a data-modifying operation either at the top level or within + a CTE, no parallel plans for that query will be generated. As an + exception, the following commands which create a new table and populate + it can use a parallel plan for the underlying SELECT + part of the query: + + + + CREATE TABLE ... AS + + + SELECT INTO + + + CREATE MATERIALIZED VIEW + + + REFRESH MATERIALIZED VIEW + + + + + + + + The query might be suspended during execution. In any situation in + which the system thinks that partial or incremental execution might + occur, no parallel plan is generated. For example, a cursor created + using DECLARE CURSOR will never use + a parallel plan. Similarly, a PL/pgSQL loop of the form + FOR x IN query LOOP .. END LOOP will never use a + parallel plan, because the parallel query system is unable to verify + that the code in the loop is safe to execute while parallel query is + active. + + + + + + The query uses any function marked PARALLEL UNSAFE. + Most system-defined functions are PARALLEL SAFE, + but user-defined functions are marked PARALLEL + UNSAFE by default. See the discussion of + . + + + + + + The query is running inside of another query that is already parallel. + For example, if a function called by a parallel query issues an SQL + query itself, that query will never use a parallel plan. This is a + limitation of the current implementation, but it may not be desirable + to remove this limitation, since it could result in a single query + using a very large number of processes. + + + + + + Even when parallel query plan is generated for a particular query, there + are several circumstances under which it will be impossible to execute + that plan in parallel at execution time. If this occurs, the leader + will execute the portion of the plan below the Gather + node entirely by itself, almost as if the Gather node were + not present. This will happen if any of the following conditions are met: + + + + + + No background workers can be obtained because of the limitation that + the total number of background workers cannot exceed + . + + + + + + No background workers can be obtained because of the limitation that + the total number of background workers launched for purposes of + parallel query cannot exceed . + + + + + + The client sends an Execute message with a non-zero fetch count. + See the discussion of the + extended query protocol. + Since libpq currently provides no way to + send such a message, this can only occur when using a client that + does not rely on libpq. If this is a frequent + occurrence, it may be a good idea to set + to zero in + sessions where it is likely, so as to avoid generating query plans + that may be suboptimal when run serially. + + + + + + + Parallel Plans + + + Because each worker executes the parallel portion of the plan to + completion, it is not possible to simply take an ordinary query plan + and run it using multiple workers. Each worker would produce a full + copy of the output result set, so the query would not run any faster + than normal but would produce incorrect results. Instead, the parallel + portion of the plan must be what is known internally to the query + optimizer as a partial plan; that is, it must be constructed + so that each process which executes the plan will generate only a + subset of the output rows in such a way that each required output row + is guaranteed to be generated by exactly one of the cooperating processes. + Generally, this means that the scan on the driving table of the query + must be a parallel-aware scan. + + + + Parallel Scans + + + The following types of parallel-aware table scans are currently supported. + + + + + In a parallel sequential scan, the table's blocks will + be divided among the cooperating processes. Blocks are handed out one + at a time, so that access to the table remains sequential. + + + + + In a parallel bitmap heap scan, one process is chosen + as the leader. That process performs a scan of one or more indexes + and builds a bitmap indicating which table blocks need to be visited. + These blocks are then divided among the cooperating processes as in + a parallel sequential scan. In other words, the heap scan is performed + in parallel, but the underlying index scan is not. + + + + + In a parallel index scan or parallel index-only + scan, the cooperating processes take turns reading data from the + index. Currently, parallel index scans are supported only for + btree indexes. Each process will claim a single index block and will + scan and return all tuples referenced by that block; other processes can + at the same time be returning tuples from a different index block. + The results of a parallel btree scan are returned in sorted order + within each worker process. + + + + + Other scan types, such as scans of non-btree indexes, may support + parallel scans in the future. + + + + + Parallel Joins + + + Just as in a non-parallel plan, the driving table may be joined to one or + more other tables using a nested loop, hash join, or merge join. The + inner side of the join may be any kind of non-parallel plan that is + otherwise supported by the planner provided that it is safe to run within + a parallel worker. Depending on the join type, the inner side may also be + a parallel plan. + + + + + + In a nested loop join, the inner side is always + non-parallel. Although it is executed in full, this is efficient if + the inner side is an index scan, because the outer tuples and thus + the loops that look up values in the index are divided over the + cooperating processes. + + + + + In a merge join, the inner side is always + a non-parallel plan and therefore executed in full. This may be + inefficient, especially if a sort must be performed, because the work + and resulting data are duplicated in every cooperating process. + + + + + In a hash join (without the "parallel" prefix), + the inner side is executed in full by every cooperating process + to build identical copies of the hash table. This may be inefficient + if the hash table is large or the plan is expensive. In a + parallel hash join, the inner side is a + parallel hash that divides the work of building + a shared hash table over the cooperating processes. + + + + + + + Parallel Aggregation + + PostgreSQL supports parallel aggregation by aggregating in + two stages. First, each process participating in the parallel portion of + the query performs an aggregation step, producing a partial result for + each group of which that process is aware. This is reflected in the plan + as a Partial Aggregate node. Second, the partial results are + transferred to the leader via Gather or Gather + Merge. Finally, the leader re-aggregates the results across all + workers in order to produce the final result. This is reflected in the + plan as a Finalize Aggregate node. + + + + Because the Finalize Aggregate node runs on the leader + process, queries which produce a relatively large number of groups in + comparison to the number of input rows will appear less favorable to the + query planner. For example, in the worst-case scenario the number of + groups seen by the Finalize Aggregate node could be as many as + the number of input rows which were seen by all worker processes in the + Partial Aggregate stage. For such cases, there is clearly + going to be no performance benefit to using parallel aggregation. The + query planner takes this into account during the planning process and is + unlikely to choose parallel aggregate in this scenario. + + + + Parallel aggregation is not supported in all situations. Each aggregate + must be safe for parallelism and must + have a combine function. If the aggregate has a transition state of type + internal, it must have serialization and deserialization + functions. See for more details. + Parallel aggregation is not supported if any aggregate function call + contains DISTINCT or ORDER BY clause and is also + not supported for ordered set aggregates or when the query involves + GROUPING SETS. It can only be used when all joins involved in + the query are also part of the parallel portion of the plan. + + + + + + Parallel Append + + + Whenever PostgreSQL needs to combine rows + from multiple sources into a single result set, it uses an + Append or MergeAppend plan node. + This commonly happens when implementing UNION ALL or + when scanning a partitioned table. Such nodes can be used in parallel + plans just as they can in any other plan. However, in a parallel plan, + the planner may instead use a Parallel Append node. + + + + When an Append node is used in a parallel plan, each + process will execute the child plans in the order in which they appear, + so that all participating processes cooperate to execute the first child + plan until it is complete and then move to the second plan at around the + same time. When a Parallel Append is used instead, the + executor will instead spread out the participating processes as evenly as + possible across its child plans, so that multiple child plans are executed + simultaneously. This avoids contention, and also avoids paying the startup + cost of a child plan in those processes that never execute it. + + + + Also, unlike a regular Append node, which can only have + partial children when used within a parallel plan, a Parallel + Append node can have both partial and non-partial child plans. + Non-partial children will be scanned by only a single process, since + scanning them more than once would produce duplicate results. Plans that + involve appending multiple results sets can therefore achieve + coarse-grained parallelism even when efficient partial plans are not + available. For example, consider a query against a partitioned table + which can only be implemented efficiently by using an index that does + not support parallel scans. The planner might choose a Parallel + Append of regular Index Scan plans; each + individual index scan would have to be executed to completion by a single + process, but different scans could be performed at the same time by + different processes. + + + + can be used to disable + this feature. + + + + + Parallel Plan Tips + + + If a query that is expected to do so does not produce a parallel plan, + you can try reducing or + . Of course, this plan may turn + out to be slower than the serial plan which the planner preferred, but + this will not always be the case. If you don't get a parallel + plan even with very small values of these settings (e.g., after setting + them both to zero), there may be some reason why the query planner is + unable to generate a parallel plan for your query. See + and + for information on why this may be + the case. + + + + When executing a parallel plan, you can use EXPLAIN (ANALYZE, + VERBOSE) to display per-worker statistics for each plan node. + This may be useful in determining whether the work is being evenly + distributed between all plan nodes and more generally in understanding the + performance characteristics of the plan. + + + + + + + Parallel Safety + + + The planner classifies operations involved in a query as either + parallel safe, parallel restricted, + or parallel unsafe. A parallel safe operation is one which + does not conflict with the use of parallel query. A parallel restricted + operation is one which cannot be performed in a parallel worker, but which + can be performed in the leader while parallel query is in use. Therefore, + parallel restricted operations can never occur below a Gather + or Gather Merge node, but can occur elsewhere in a plan which + contains such a node. A parallel unsafe operation is one which cannot + be performed while parallel query is in use, not even in the leader. + When a query contains anything which is parallel unsafe, parallel query + is completely disabled for that query. + + + + The following operations are always parallel restricted: + + + + + + Scans of common table expressions (CTEs). + + + + + + Scans of temporary tables. + + + + + + Scans of foreign tables, unless the foreign data wrapper has + an IsForeignScanParallelSafe API which indicates otherwise. + + + + + + Plan nodes to which an InitPlan is attached. + + + + + + Plan nodes which reference a correlated SubPlan. + + + + + + Parallel Labeling for Functions and Aggregates + + + The planner cannot automatically determine whether a user-defined + function or aggregate is parallel safe, parallel restricted, or parallel + unsafe, because this would require predicting every operation which the + function could possibly perform. In general, this is equivalent to the + Halting Problem and therefore impossible. Even for simple functions + where it could conceivably be done, we do not try, since this would be expensive + and error-prone. Instead, all user-defined functions are assumed to + be parallel unsafe unless otherwise marked. When using + or + , markings can be set by specifying + PARALLEL SAFE, PARALLEL RESTRICTED, or + PARALLEL UNSAFE as appropriate. When using + , the + PARALLEL option can be specified with SAFE, + RESTRICTED, or UNSAFE as the corresponding value. + + + + Functions and aggregates must be marked PARALLEL UNSAFE if + they write to the database, access sequences, change the transaction state + even temporarily (e.g., a PL/pgSQL function which establishes an + EXCEPTION block to catch errors), or make persistent changes to + settings. Similarly, functions must be marked PARALLEL + RESTRICTED if they access temporary tables, client connection state, + cursors, prepared statements, or miscellaneous backend-local state which + the system cannot synchronize across workers. For example, + setseed and random are parallel restricted for + this last reason. + + + + In general, if a function is labeled as being safe when it is restricted or + unsafe, or if it is labeled as being restricted when it is in fact unsafe, + it may throw errors or produce wrong answers when used in a parallel query. + C-language functions could in theory exhibit totally undefined behavior if + mislabeled, since there is no way for the system to protect itself against + arbitrary C code, but in most likely cases the result will be no worse than + for any other function. If in doubt, it is probably best to label functions + as UNSAFE. + + + + If a function executed within a parallel worker acquires locks which are + not held by the leader, for example by querying a table not referenced in + the query, those locks will be released at worker exit, not end of + transaction. If you write a function which does this, and this behavior + difference is important to you, mark such functions as + PARALLEL RESTRICTED + to ensure that they execute only in the leader. + + + + Note that the query planner does not consider deferring the evaluation of + parallel-restricted functions or aggregates involved in the query in + order to obtain a superior plan. So, for example, if a WHERE + clause applied to a particular table is parallel restricted, the query + planner will not consider performing a scan of that table in the parallel + portion of a plan. In some cases, it would be + possible (and perhaps even efficient) to include the scan of that table in + the parallel portion of the query and defer the evaluation of the + WHERE clause so that it happens above the Gather + node. However, the planner does not do this. + + + + + + + diff --git a/doc/src/sgml/passwordcheck.sgml b/doc/src/sgml/passwordcheck.sgml new file mode 100644 index 000000000000..0d89bb95b9de --- /dev/null +++ b/doc/src/sgml/passwordcheck.sgml @@ -0,0 +1,62 @@ + + + + passwordcheck + + + passwordcheck + + + + The passwordcheck module checks users' passwords + whenever they are set with + or + . + If a password is considered too weak, it will be rejected and + the command will terminate with an error. + + + + To enable this module, add '$libdir/passwordcheck' + to in + postgresql.conf, then restart the server. + + + + You can adapt this module to your needs by changing the source code. + For example, you can use + CrackLib + to check passwords — this only requires uncommenting + two lines in the Makefile and rebuilding the + module. (We cannot include CrackLib + by default for license reasons.) + Without CrackLib, the module enforces a few + simple rules for password strength, which you can modify or extend + as you see fit. + + + + + To prevent unencrypted passwords from being sent across the network, + written to the server log or otherwise stolen by a database administrator, + PostgreSQL allows the user to supply + pre-encrypted passwords. Many client programs make use of this + functionality and encrypt the password before sending it to the server. + + + This limits the usefulness of the passwordcheck + module, because in that case it can only try to guess the password. + For this reason, passwordcheck is not + recommended if your security requirements are high. + It is more secure to use an external authentication method such as GSSAPI + (see ) than to rely on + passwords within the database. + + + Alternatively, you could modify passwordcheck + to reject pre-encrypted passwords, but forcing users to set their + passwords in clear text carries its own security risks. + + + + diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml new file mode 100644 index 000000000000..ddd6c3ff3e0e --- /dev/null +++ b/doc/src/sgml/perform.sgml @@ -0,0 +1,1960 @@ + + + + Performance Tips + + + performance + + + + Query performance can be affected by many things. Some of these can + be controlled by the user, while others are fundamental to the underlying + design of the system. This chapter provides some hints about understanding + and tuning PostgreSQL performance. + + + + Using <command>EXPLAIN</command> + + + EXPLAIN + + + + query plan + + + + PostgreSQL devises a query + plan for each query it receives. Choosing the right + plan to match the query structure and the properties of the data + is absolutely critical for good performance, so the system includes + a complex planner that tries to choose good plans. + You can use the EXPLAIN command + to see what query plan the planner creates for any query. + Plan-reading is an art that requires some experience to master, + but this section attempts to cover the basics. + + + + Examples in this section are drawn from the regression test database + after doing a VACUUM ANALYZE, using 9.3 development sources. + You should be able to get similar results if you try the examples + yourself, but your estimated costs and row counts might vary slightly + because ANALYZE's statistics are random samples rather + than exact, and because costs are inherently somewhat platform-dependent. + + + + The examples use EXPLAIN's default text output + format, which is compact and convenient for humans to read. + If you want to feed EXPLAIN's output to a program for further + analysis, you should use one of its machine-readable output formats + (XML, JSON, or YAML) instead. + + + + <command>EXPLAIN</command> Basics + + + The structure of a query plan is a tree of plan nodes. + Nodes at the bottom level of the tree are scan nodes: they return raw rows + from a table. There are different types of scan nodes for different + table access methods: sequential scans, index scans, and bitmap index + scans. There are also non-table row sources, such as VALUES + clauses and set-returning functions in FROM, which have their + own scan node types. + If the query requires joining, aggregation, sorting, or other + operations on the raw rows, then there will be additional nodes + above the scan nodes to perform these operations. Again, + there is usually more than one possible way to do these operations, + so different node types can appear here too. The output + of EXPLAIN has one line for each node in the plan + tree, showing the basic node type plus the cost estimates that the planner + made for the execution of that plan node. Additional lines might appear, + indented from the node's summary line, + to show additional properties of the node. + The very first line (the summary line for the topmost + node) has the estimated total execution cost for the plan; it is this + number that the planner seeks to minimize. + + + + Here is a trivial example, just to show what the output looks like: + + +EXPLAIN SELECT * FROM tenk1; + + QUERY PLAN +------------------------------------------------------------- + Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244) + + + + + Since this query has no WHERE clause, it must scan all the + rows of the table, so the planner has chosen to use a simple sequential + scan plan. The numbers that are quoted in parentheses are (left + to right): + + + + + Estimated start-up cost. This is the time expended before the output + phase can begin, e.g., time to do the sorting in a sort node. + + + + + + Estimated total cost. This is stated on the assumption that the plan + node is run to completion, i.e., all available rows are retrieved. + In practice a node's parent node might stop short of reading all + available rows (see the LIMIT example below). + + + + + + Estimated number of rows output by this plan node. Again, the node + is assumed to be run to completion. + + + + + + Estimated average width of rows output by this plan node (in bytes). + + + + + + + The costs are measured in arbitrary units determined by the planner's + cost parameters (see ). + Traditional practice is to measure the costs in units of disk page + fetches; that is, is conventionally + set to 1.0 and the other cost parameters are set relative + to that. The examples in this section are run with the default cost + parameters. + + + + It's important to understand that the cost of an upper-level node includes + the cost of all its child nodes. It's also important to realize that + the cost only reflects things that the planner cares about. + In particular, the cost does not consider the time spent transmitting + result rows to the client, which could be an important + factor in the real elapsed time; but the planner ignores it because + it cannot change it by altering the plan. (Every correct plan will + output the same row set, we trust.) + + + + The rows value is a little tricky because it is + not the number of rows processed or scanned by the + plan node, but rather the number emitted by the node. This is often + less than the number scanned, as a result of filtering by any + WHERE-clause conditions that are being applied at the node. + Ideally the top-level rows estimate will approximate the number of rows + actually returned, updated, or deleted by the query. + + + + Returning to our example: + + +EXPLAIN SELECT * FROM tenk1; + + QUERY PLAN +------------------------------------------------------------- + Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244) + + + + + These numbers are derived very straightforwardly. If you do: + + +SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1'; + + + you will find that tenk1 has 358 disk + pages and 10000 rows. The estimated cost is computed as (disk pages read * + ) + (rows scanned * + ). By default, + seq_page_cost is 1.0 and cpu_tuple_cost is 0.01, + so the estimated cost is (358 * 1.0) + (10000 * 0.01) = 458. + + + + Now let's modify the query to add a WHERE condition: + + +EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 7000; + + QUERY PLAN +------------------------------------------------------------ + Seq Scan on tenk1 (cost=0.00..483.00 rows=7001 width=244) + Filter: (unique1 < 7000) + + + Notice that the EXPLAIN output shows the WHERE + clause being applied as a filter condition attached to the Seq + Scan plan node. This means that + the plan node checks the condition for each row it scans, and outputs + only the ones that pass the condition. + The estimate of output rows has been reduced because of the + WHERE clause. + However, the scan will still have to visit all 10000 rows, so the cost + hasn't decreased; in fact it has gone up a bit (by 10000 * , to be exact) to reflect the extra CPU + time spent checking the WHERE condition. + + + + The actual number of rows this query would select is 7000, but the rows + estimate is only approximate. If you try to duplicate this experiment, + you will probably get a slightly different estimate; moreover, it can + change after each ANALYZE command, because the + statistics produced by ANALYZE are taken from a + randomized sample of the table. + + + + Now, let's make the condition more restrictive: + + +EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------- + Bitmap Heap Scan on tenk1 (cost=5.07..229.20 rows=101 width=244) + Recheck Cond: (unique1 < 100) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) + Index Cond: (unique1 < 100) + + + Here the planner has decided to use a two-step plan: the child plan + node visits an index to find the locations of rows matching the index + condition, and then the upper plan node actually fetches those rows + from the table itself. Fetching rows separately is much more + expensive than reading them sequentially, but because not all the pages + of the table have to be visited, this is still cheaper than a sequential + scan. (The reason for using two plan levels is that the upper plan + node sorts the row locations identified by the index into physical order + before reading them, to minimize the cost of separate fetches. + The bitmap mentioned in the node names is the mechanism that + does the sorting.) + + + + Now let's add another condition to the WHERE clause: + + +EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND stringu1 = 'xxx'; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------- + Bitmap Heap Scan on tenk1 (cost=5.04..229.43 rows=1 width=244) + Recheck Cond: (unique1 < 100) + Filter: (stringu1 = 'xxx'::name) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) + Index Cond: (unique1 < 100) + + + The added condition stringu1 = 'xxx' reduces the + output row count estimate, but not the cost because we still have to visit + the same set of rows. Notice that the stringu1 clause + cannot be applied as an index condition, since this index is only on + the unique1 column. Instead it is applied as a filter on + the rows retrieved by the index. Thus the cost has actually gone up + slightly to reflect this extra checking. + + + + In some cases the planner will prefer a simple index scan plan: + + +EXPLAIN SELECT * FROM tenk1 WHERE unique1 = 42; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;---------- + Index Scan using tenk1_unique1 on tenk1 (cost=0.29..8.30 rows=1 width=244) + Index Cond: (unique1 = 42) + + + In this type of plan the table rows are fetched in index order, which + makes them even more expensive to read, but there are so few that the + extra cost of sorting the row locations is not worth it. You'll most + often see this plan type for queries that fetch just a single row. It's + also often used for queries that have an ORDER BY condition + that matches the index order, because then no extra sorting step is needed + to satisfy the ORDER BY. In this example, adding + ORDER BY unique1 would use the same plan because the + index already implicitly provides the requested ordering. + + + + The planner may implement an ORDER BY clause in several + ways. The above example shows that such an ordering clause may be + implemented implicitly. The planner may also add an explicit + sort step: + + +EXPLAIN SELECT * FROM tenk1 ORDER BY unique1; + QUERY PLAN +------------------------------------------------------------------- + Sort (cost=1109.39..1134.39 rows=10000 width=244) + Sort Key: unique1 + -> Seq Scan on tenk1 (cost=0.00..445.00 rows=10000 width=244) + + + If a part of the plan guarantees an ordering on a prefix of the + required sort keys, then the planner may instead decide to use an + incremental sort step: + + +EXPLAIN SELECT * FROM tenk1 ORDER BY four, ten LIMIT 100; + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------------------- + Limit (cost=521.06..538.05 rows=100 width=244) + -> Incremental Sort (cost=521.06..2220.95 rows=10000 width=244) + Sort Key: four, ten + Presorted Key: four + -> Index Scan using index_tenk1_on_four on tenk1 (cost=0.29..1510.08 rows=10000 width=244) + + + Compared to regular sorts, sorting incrementally allows returning tuples + before the entire result set has been sorted, which particularly enables + optimizations with LIMIT queries. It may also reduce + memory usage and the likelihood of spilling sorts to disk, but it comes at + the cost of the increased overhead of splitting the result set into multiple + sorting batches. + + + + If there are separate indexes on several of the columns referenced + in WHERE, the planner might choose to use an AND or OR + combination of the indexes: + + +EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;------------------ + Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244) + Recheck Cond: ((unique1 < 100) AND (unique2 > 9000)) + -> BitmapAnd (cost=25.08..25.08 rows=10 width=0) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) + Index Cond: (unique1 < 100) + -> Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0) + Index Cond: (unique2 > 9000) + + + But this requires visiting both indexes, so it's not necessarily a win + compared to using just one index and treating the other condition as + a filter. If you vary the ranges involved you'll see the plan change + accordingly. + + + + Here is an example showing the effects of LIMIT: + + +EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;------------------ + Limit (cost=0.29..14.48 rows=2 width=244) + -> Index Scan using tenk1_unique2 on tenk1 (cost=0.29..71.27 rows=10 width=244) + Index Cond: (unique2 > 9000) + Filter: (unique1 < 100) + + + + + This is the same query as above, but we added a LIMIT so that + not all the rows need be retrieved, and the planner changed its mind about + what to do. Notice that the total cost and row count of the Index Scan + node are shown as if it were run to completion. However, the Limit node + is expected to stop after retrieving only a fifth of those rows, so its + total cost is only a fifth as much, and that's the actual estimated cost + of the query. This plan is preferred over adding a Limit node to the + previous plan because the Limit could not avoid paying the startup cost + of the bitmap scan, so the total cost would be something over 25 units + with that approach. + + + + Let's try joining two tables, using the columns we have been discussing: + + +EXPLAIN SELECT * +FROM tenk1 t1, tenk2 t2 +WHERE t1.unique1 < 10 AND t1.unique2 = t2.unique2; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;------------------- + Nested Loop (cost=4.65..118.62 rows=10 width=488) + -> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244) + Recheck Cond: (unique1 < 10) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) + Index Cond: (unique1 < 10) + -> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244) + Index Cond: (unique2 = t1.unique2) + + + + + In this plan, we have a nested-loop join node with two table scans as + inputs, or children. The indentation of the node summary lines reflects + the plan tree structure. The join's first, or outer, child + is a bitmap scan similar to those we saw before. Its cost and row count + are the same as we'd get from SELECT ... WHERE unique1 < 10 + because we are + applying the WHERE clause unique1 < 10 + at that node. + The t1.unique2 = t2.unique2 clause is not relevant yet, + so it doesn't affect the row count of the outer scan. The nested-loop + join node will run its second, + or inner child once for each row obtained from the outer child. + Column values from the current outer row can be plugged into the inner + scan; here, the t1.unique2 value from the outer row is available, + so we get a plan and costs similar to what we saw above for a simple + SELECT ... WHERE t2.unique2 = constant case. + (The estimated cost is actually a bit lower than what was seen above, + as a result of caching that's expected to occur during the repeated + index scans on t2.) The + costs of the loop node are then set on the basis of the cost of the outer + scan, plus one repetition of the inner scan for each outer row (10 * 7.91, + here), plus a little CPU time for join processing. + + + + In this example the join's output row count is the same as the product + of the two scans' row counts, but that's not true in all cases because + there can be additional WHERE clauses that mention both tables + and so can only be applied at the join point, not to either input scan. + Here's an example: + + +EXPLAIN SELECT * +FROM tenk1 t1, tenk2 t2 +WHERE t1.unique1 < 10 AND t2.unique2 < 10 AND t1.hundred < t2.hundred; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;-------------------------- + Nested Loop (cost=4.65..49.46 rows=33 width=488) + Join Filter: (t1.hundred < t2.hundred) + -> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244) + Recheck Cond: (unique1 < 10) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) + Index Cond: (unique1 < 10) + -> Materialize (cost=0.29..8.51 rows=10 width=244) + -> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..8.46 rows=10 width=244) + Index Cond: (unique2 < 10) + + + The condition t1.hundred < t2.hundred can't be + tested in the tenk2_unique2 index, so it's applied at the + join node. This reduces the estimated output row count of the join node, + but does not change either input scan. + + + + Notice that here the planner has chosen to materialize the inner + relation of the join, by putting a Materialize plan node atop it. This + means that the t2 index scan will be done just once, even + though the nested-loop join node needs to read that data ten times, once + for each row from the outer relation. The Materialize node saves the data + in memory as it's read, and then returns the data from memory on each + subsequent pass. + + + + When dealing with outer joins, you might see join plan nodes with both + Join Filter and plain Filter conditions attached. + Join Filter conditions come from the outer join's ON clause, + so a row that fails the Join Filter condition could still get emitted as + a null-extended row. But a plain Filter condition is applied after the + outer-join rules and so acts to remove rows unconditionally. In an inner + join there is no semantic difference between these types of filters. + + + + If we change the query's selectivity a bit, we might get a very different + join plan: + + +EXPLAIN SELECT * +FROM tenk1 t1, tenk2 t2 +WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------- + Hash Join (cost=230.47..713.98 rows=101 width=488) + Hash Cond: (t2.unique2 = t1.unique2) + -> Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) + -> Hash (cost=229.20..229.20 rows=101 width=244) + -> Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) + Recheck Cond: (unique1 < 100) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) + Index Cond: (unique1 < 100) + + + + + Here, the planner has chosen to use a hash join, in which rows of one + table are entered into an in-memory hash table, after which the other + table is scanned and the hash table is probed for matches to each row. + Again note how the indentation reflects the plan structure: the bitmap + scan on tenk1 is the input to the Hash node, which constructs + the hash table. That's then returned to the Hash Join node, which reads + rows from its outer child plan and searches the hash table for each one. + + + + Another possible type of join is a merge join, illustrated here: + + +EXPLAIN SELECT * +FROM tenk1 t1, onek t2 +WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------- + Merge Join (cost=198.11..268.19 rows=10 width=488) + Merge Cond: (t1.unique2 = t2.unique2) + -> Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244) + Filter: (unique1 < 100) + -> Sort (cost=197.83..200.33 rows=1000 width=244) + Sort Key: t2.unique2 + -> Seq Scan on onek t2 (cost=0.00..148.00 rows=1000 width=244) + + + + + Merge join requires its input data to be sorted on the join keys. In this + plan the tenk1 data is sorted by using an index scan to visit + the rows in the correct order, but a sequential scan and sort is preferred + for onek, because there are many more rows to be visited in + that table. + (Sequential-scan-and-sort frequently beats an index scan for sorting many rows, + because of the nonsequential disk access required by the index scan.) + + + + One way to look at variant plans is to force the planner to disregard + whatever strategy it thought was the cheapest, using the enable/disable + flags described in . + (This is a crude tool, but useful. See + also .) + For example, if we're unconvinced that sequential-scan-and-sort is the best way to + deal with table onek in the previous example, we could try + + +SET enable_sort = off; + +EXPLAIN SELECT * +FROM tenk1 t1, onek t2 +WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------- + Merge Join (cost=0.56..292.65 rows=10 width=488) + Merge Cond: (t1.unique2 = t2.unique2) + -> Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244) + Filter: (unique1 < 100) + -> Index Scan using onek_unique2 on onek t2 (cost=0.28..224.79 rows=1000 width=244) + + + which shows that the planner thinks that sorting onek by + index-scanning is about 12% more expensive than sequential-scan-and-sort. + Of course, the next question is whether it's right about that. + We can investigate that using EXPLAIN ANALYZE, as discussed + below. + + + + + + <command>EXPLAIN ANALYZE</command> + + + It is possible to check the accuracy of the planner's estimates + by using EXPLAIN's ANALYZE option. With this + option, EXPLAIN actually executes the query, and then displays + the true row counts and true run time accumulated within each plan node, + along with the same estimates that a plain EXPLAIN + shows. For example, we might get a result like this: + + +EXPLAIN ANALYZE SELECT * +FROM tenk1 t1, tenk2 t2 +WHERE t1.unique1 < 10 AND t1.unique2 = t2.unique2; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;-------------------------------------------------------------- + Nested Loop (cost=4.65..118.62 rows=10 width=488) (actual time=0.128..0.377 rows=10 loops=1) + -> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244) (actual time=0.057..0.121 rows=10 loops=1) + Recheck Cond: (unique1 < 10) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) (actual time=0.024..0.024 rows=10 loops=1) + Index Cond: (unique1 < 10) + -> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244) (actual time=0.021..0.022 rows=1 loops=10) + Index Cond: (unique2 = t1.unique2) + Planning time: 0.181 ms + Execution time: 0.501 ms + + + Note that the actual time values are in milliseconds of + real time, whereas the cost estimates are expressed in + arbitrary units; so they are unlikely to match up. + The thing that's usually most important to look for is whether the + estimated row counts are reasonably close to reality. In this example + the estimates were all dead-on, but that's quite unusual in practice. + + + + In some query plans, it is possible for a subplan node to be executed more + than once. For example, the inner index scan will be executed once per + outer row in the above nested-loop plan. In such cases, the + loops value reports the + total number of executions of the node, and the actual time and rows + values shown are averages per-execution. This is done to make the numbers + comparable with the way that the cost estimates are shown. Multiply by + the loops value to get the total time actually spent in + the node. In the above example, we spent a total of 0.220 milliseconds + executing the index scans on tenk2. + + + + In some cases EXPLAIN ANALYZE shows additional execution + statistics beyond the plan node execution times and row counts. + For example, Sort and Hash nodes provide extra information: + + +EXPLAIN ANALYZE SELECT * +FROM tenk1 t1, tenk2 t2 +WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2 ORDER BY t1.fivethous; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;-------------------------------------------------------------------&zwsp;------ + Sort (cost=717.34..717.59 rows=101 width=488) (actual time=7.761..7.774 rows=100 loops=1) + Sort Key: t1.fivethous + Sort Method: quicksort Memory: 77kB + -> Hash Join (cost=230.47..713.98 rows=101 width=488) (actual time=0.711..7.427 rows=100 loops=1) + Hash Cond: (t2.unique2 = t1.unique2) + -> Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.007..2.583 rows=10000 loops=1) + -> Hash (cost=229.20..229.20 rows=101 width=244) (actual time=0.659..0.659 rows=100 loops=1) + Buckets: 1024 Batches: 1 Memory Usage: 28kB + -> Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1) + Recheck Cond: (unique1 < 100) + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.049..0.049 rows=100 loops=1) + Index Cond: (unique1 < 100) + Planning time: 0.194 ms + Execution time: 8.008 ms + + + The Sort node shows the sort method used (in particular, whether the sort + was in-memory or on-disk) and the amount of memory or disk space needed. + The Hash node shows the number of hash buckets and batches as well as the + peak amount of memory used for the hash table. (If the number of batches + exceeds one, there will also be disk space usage involved, but that is not + shown.) + + + + Another type of extra information is the number of rows removed by a + filter condition: + + +EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten < 7; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;-------------------------------------- + Seq Scan on tenk1 (cost=0.00..483.00 rows=7000 width=244) (actual time=0.016..5.107 rows=7000 loops=1) + Filter: (ten < 7) + Rows Removed by Filter: 3000 + Planning time: 0.083 ms + Execution time: 5.905 ms + + + These counts can be particularly valuable for filter conditions applied at + join nodes. The Rows Removed line only appears when at least + one scanned row, or potential join pair in the case of a join node, + is rejected by the filter condition. + + + + A case similar to filter conditions occurs with lossy + index scans. For example, consider this search for polygons containing a + specific point: + + +EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @> polygon '(0.5,2.0)'; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------------------- + Seq Scan on polygon_tbl (cost=0.00..1.05 rows=1 width=32) (actual time=0.044..0.044 rows=0 loops=1) + Filter: (f1 @> '((0.5,2))'::polygon) + Rows Removed by Filter: 4 + Planning time: 0.040 ms + Execution time: 0.083 ms + + + The planner thinks (quite correctly) that this sample table is too small + to bother with an index scan, so we have a plain sequential scan in which + all the rows got rejected by the filter condition. But if we force an + index scan to be used, we see: + + +SET enable_seqscan TO off; + +EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @> polygon '(0.5,2.0)'; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;------------------------------------------------------- + Index Scan using gpolygonind on polygon_tbl (cost=0.13..8.15 rows=1 width=32) (actual time=0.062..0.062 rows=0 loops=1) + Index Cond: (f1 @> '((0.5,2))'::polygon) + Rows Removed by Index Recheck: 1 + Planning time: 0.034 ms + Execution time: 0.144 ms + + + Here we can see that the index returned one candidate row, which was + then rejected by a recheck of the index condition. This happens because a + GiST index is lossy for polygon containment tests: it actually + returns the rows with polygons that overlap the target, and then we have + to do the exact containment test on those rows. + + + + EXPLAIN has a BUFFERS option that can be used with + ANALYZE to get even more run time statistics: + + +EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;-------------------------------------------------------------- + Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244) (actual time=0.323..0.342 rows=10 loops=1) + Recheck Cond: ((unique1 < 100) AND (unique2 > 9000)) + Buffers: shared hit=15 + -> BitmapAnd (cost=25.08..25.08 rows=10 width=0) (actual time=0.309..0.309 rows=0 loops=1) + Buffers: shared hit=7 + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.043..0.043 rows=100 loops=1) + Index Cond: (unique1 < 100) + Buffers: shared hit=2 + -> Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0) (actual time=0.227..0.227 rows=999 loops=1) + Index Cond: (unique2 > 9000) + Buffers: shared hit=5 + Planning time: 0.088 ms + Execution time: 0.423 ms + + + The numbers provided by BUFFERS help to identify which parts + of the query are the most I/O-intensive. + + + + Keep in mind that because EXPLAIN ANALYZE actually + runs the query, any side-effects will happen as usual, even though + whatever results the query might output are discarded in favor of + printing the EXPLAIN data. If you want to analyze a + data-modifying query without changing your tables, you can + roll the command back afterwards, for example: + + +BEGIN; + +EXPLAIN ANALYZE UPDATE tenk1 SET hundred = hundred + 1 WHERE unique1 < 100; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;------------------------------------------------------------- + Update on tenk1 (cost=5.08..230.08 rows=0 width=0) (actual time=3.791..3.792 rows=0 loops=1) + -> Bitmap Heap Scan on tenk1 (cost=5.08..230.08 rows=102 width=10) (actual time=0.069..0.513 rows=100 loops=1) + Recheck Cond: (unique1 < 100) + Heap Blocks: exact=90 + -> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.05 rows=102 width=0) (actual time=0.036..0.037 rows=300 loops=1) + Index Cond: (unique1 < 100) + Planning Time: 0.113 ms + Execution Time: 3.850 ms + +ROLLBACK; + + + + + As seen in this example, when the query is an INSERT, + UPDATE, or DELETE command, the actual work of + applying the table changes is done by a top-level Insert, Update, + or Delete plan node. The plan nodes underneath this node perform + the work of locating the old rows and/or computing the new data. + So above, we see the same sort of bitmap table scan we've seen already, + and its output is fed to an Update node that stores the updated rows. + It's worth noting that although the data-modifying node can take a + considerable amount of run time (here, it's consuming the lion's share + of the time), the planner does not currently add anything to the cost + estimates to account for that work. That's because the work to be done is + the same for every correct query plan, so it doesn't affect planning + decisions. + + + + When an UPDATE or DELETE command affects an + inheritance hierarchy, the output might look like this: + + +EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101; + QUERY PLAN +-------------------------------------------------------------------&zwsp;----------------------------------- + Update on parent (cost=0.00..24.59 rows=0 width=0) + Update on parent parent_1 + Update on child1 parent_2 + Update on child2 parent_3 + Update on child3 parent_4 + -> Result (cost=0.00..24.59 rows=4 width=14) + -> Append (cost=0.00..24.54 rows=4 width=14) + -> Seq Scan on parent parent_1 (cost=0.00..0.00 rows=1 width=14) + Filter: (f1 = 101) + -> Index Scan using child1_pkey on child1 parent_2 (cost=0.15..8.17 rows=1 width=14) + Index Cond: (f1 = 101) + -> Index Scan using child2_pkey on child2 parent_3 (cost=0.15..8.17 rows=1 width=14) + Index Cond: (f1 = 101) + -> Index Scan using child3_pkey on child3 parent_4 (cost=0.15..8.17 rows=1 width=14) + Index Cond: (f1 = 101) + + + In this example the Update node needs to consider three child tables as + well as the originally-mentioned parent table. So there are four input + scanning subplans, one per table. For clarity, the Update node is + annotated to show the specific target tables that will be updated, in the + same order as the corresponding subplans. + + + + The Planning time shown by EXPLAIN + ANALYZE is the time it took to generate the query plan from the + parsed query and optimize it. It does not include parsing or rewriting. + + + + The Execution time shown by EXPLAIN + ANALYZE includes executor start-up and shut-down time, as well + as the time to run any triggers that are fired, but it does not include + parsing, rewriting, or planning time. + Time spent executing BEFORE triggers, if any, is included in + the time for the related Insert, Update, or Delete node; but time + spent executing AFTER triggers is not counted there because + AFTER triggers are fired after completion of the whole plan. + The total time spent in each trigger + (either BEFORE or AFTER) is also shown separately. + Note that deferred constraint triggers will not be executed + until end of transaction and are thus not considered at all by + EXPLAIN ANALYZE. + + + + + + Caveats + + + There are two significant ways in which run times measured by + EXPLAIN ANALYZE can deviate from normal execution of + the same query. First, since no output rows are delivered to the client, + network transmission costs and I/O conversion costs are not included. + Second, the measurement overhead added by EXPLAIN + ANALYZE can be significant, especially on machines with slow + gettimeofday() operating-system calls. You can use the + tool to measure the overhead of timing + on your system. + + + + EXPLAIN results should not be extrapolated to situations + much different from the one you are actually testing; for example, + results on a toy-sized table cannot be assumed to apply to large tables. + The planner's cost estimates are not linear and so it might choose + a different plan for a larger or smaller table. An extreme example + is that on a table that only occupies one disk page, you'll nearly + always get a sequential scan plan whether indexes are available or not. + The planner realizes that it's going to take one disk page read to + process the table in any case, so there's no value in expending additional + page reads to look at an index. (We saw this happening in the + polygon_tbl example above.) + + + + There are cases in which the actual and estimated values won't match up + well, but nothing is really wrong. One such case occurs when + plan node execution is stopped short by a LIMIT or similar + effect. For example, in the LIMIT query we used before, + + +EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; + + QUERY PLAN +-------------------------------------------------------------------&zwsp;------------------------------------------------------------ + Limit (cost=0.29..14.71 rows=2 width=244) (actual time=0.177..0.249 rows=2 loops=1) + -> Index Scan using tenk1_unique2 on tenk1 (cost=0.29..72.42 rows=10 width=244) (actual time=0.174..0.244 rows=2 loops=1) + Index Cond: (unique2 > 9000) + Filter: (unique1 < 100) + Rows Removed by Filter: 287 + Planning time: 0.096 ms + Execution time: 0.336 ms + + + the estimated cost and row count for the Index Scan node are shown as + though it were run to completion. But in reality the Limit node stopped + requesting rows after it got two, so the actual row count is only 2 and + the run time is less than the cost estimate would suggest. This is not + an estimation error, only a discrepancy in the way the estimates and true + values are displayed. + + + + Merge joins also have measurement artifacts that can confuse the unwary. + A merge join will stop reading one input if it's exhausted the other input + and the next key value in the one input is greater than the last key value + of the other input; in such a case there can be no more matches and so no + need to scan the rest of the first input. This results in not reading all + of one child, with results like those mentioned for LIMIT. + Also, if the outer (first) child contains rows with duplicate key values, + the inner (second) child is backed up and rescanned for the portion of its + rows matching that key value. EXPLAIN ANALYZE counts these + repeated emissions of the same inner rows as if they were real additional + rows. When there are many outer duplicates, the reported actual row count + for the inner child plan node can be significantly larger than the number + of rows that are actually in the inner relation. + + + + BitmapAnd and BitmapOr nodes always report their actual row counts as zero, + due to implementation limitations. + + + + Normally, EXPLAIN will display every plan node + created by the planner. However, there are cases where the executor + can determine that certain nodes need not be executed because they + cannot produce any rows, based on parameter values that were not + available at planning time. (Currently this can only happen for child + nodes of an Append or MergeAppend node that is scanning a partitioned + table.) When this happens, those plan nodes are omitted from + the EXPLAIN output and a Subplans + Removed: N annotation appears + instead. + + + + + + + Statistics Used by the Planner + + + statistics + of the planner + + + + Single-Column Statistics + + As we saw in the previous section, the query planner needs to estimate + the number of rows retrieved by a query in order to make good choices + of query plans. This section provides a quick look at the statistics + that the system uses for these estimates. + + + + One component of the statistics is the total number of entries in + each table and index, as well as the number of disk blocks occupied + by each table and index. This information is kept in the table + pg_class, + in the columns reltuples and + relpages. We can look at it with + queries similar to this one: + + +SELECT relname, relkind, reltuples, relpages +FROM pg_class +WHERE relname LIKE 'tenk1%'; + + relname | relkind | reltuples | relpages +----------------------+---------+-----------+---------- + tenk1 | r | 10000 | 358 + tenk1_hundred | i | 10000 | 30 + tenk1_thous_tenthous | i | 10000 | 30 + tenk1_unique1 | i | 10000 | 30 + tenk1_unique2 | i | 10000 | 30 +(5 rows) + + + Here we can see that tenk1 contains 10000 + rows, as do its indexes, but the indexes are (unsurprisingly) much + smaller than the table. + + + + For efficiency reasons, reltuples + and relpages are not updated on-the-fly, + and so they usually contain somewhat out-of-date values. + They are updated by VACUUM, ANALYZE, and a + few DDL commands such as CREATE INDEX. A VACUUM + or ANALYZE operation that does not scan the entire table + (which is commonly the case) will incrementally update the + reltuples count on the basis of the part + of the table it did scan, resulting in an approximate value. + In any case, the planner + will scale the values it finds in pg_class + to match the current physical table size, thus obtaining a closer + approximation. + + + + pg_statistic + + + + Most queries retrieve only a fraction of the rows in a table, due + to WHERE clauses that restrict the rows to be + examined. The planner thus needs to make an estimate of the + selectivity of WHERE clauses, that is, + the fraction of rows that match each condition in the + WHERE clause. The information used for this task is + stored in the + pg_statistic + system catalog. Entries in pg_statistic + are updated by the ANALYZE and VACUUM + ANALYZE commands, and are always approximate even when freshly + updated. + + + + pg_stats + + + + Rather than look at pg_statistic directly, + it's better to look at its view + pg_stats + when examining the statistics manually. pg_stats + is designed to be more easily readable. Furthermore, + pg_stats is readable by all, whereas + pg_statistic is only readable by a superuser. + (This prevents unprivileged users from learning something about + the contents of other people's tables from the statistics. The + pg_stats view is restricted to show only + rows about tables that the current user can read.) + For example, we might do: + + +SELECT attname, inherited, n_distinct, + array_to_string(most_common_vals, E'\n') as most_common_vals +FROM pg_stats +WHERE tablename = 'road'; + + attname | inherited | n_distinct | most_common_vals +---------+-----------+------------+------------------------------------ + name | f | -0.363388 | I- 580 Ramp+ + | | | I- 880 Ramp+ + | | | Sp Railroad + + | | | I- 580 + + | | | I- 680 Ramp + name | t | -0.284859 | I- 880 Ramp+ + | | | I- 580 Ramp+ + | | | I- 680 Ramp+ + | | | I- 580 + + | | | State Hwy 13 Ramp +(2 rows) + + + Note that two rows are displayed for the same column, one corresponding + to the complete inheritance hierarchy starting at the + road table (inherited=t), + and another one including only the road table itself + (inherited=f). + + + + The amount of information stored in pg_statistic + by ANALYZE, in particular the maximum number of entries in the + most_common_vals and histogram_bounds + arrays for each column, can be set on a + column-by-column basis using the ALTER TABLE SET STATISTICS + command, or globally by setting the + configuration variable. + The default limit is presently 100 entries. Raising the limit + might allow more accurate planner estimates to be made, particularly for + columns with irregular data distributions, at the price of consuming + more space in pg_statistic and slightly more + time to compute the estimates. Conversely, a lower limit might be + sufficient for columns with simple data distributions. + + + + Further details about the planner's use of statistics can be found in + . + + + + + Extended Statistics + + + statistics + of the planner + + + + correlation + in the query planner + + + + pg_statistic_ext + + + + pg_statistic_ext_data + + + + It is common to see slow queries running bad execution plans because + multiple columns used in the query clauses are correlated. + The planner normally assumes that multiple conditions + are independent of each other, + an assumption that does not hold when column values are correlated. + Regular statistics, because of their per-individual-column nature, + cannot capture any knowledge about cross-column correlation. + However, PostgreSQL has the ability to compute + multivariate statistics, which can capture + such information. + + + + Because the number of possible column combinations is very large, + it's impractical to compute multivariate statistics automatically. + Instead, extended statistics objects, more often + called just statistics objects, can be created to instruct + the server to obtain statistics across interesting sets of columns. + + + + Statistics objects are created using the + CREATE STATISTICS command. + Creation of such an object merely creates a catalog entry expressing + interest in the statistics. Actual data collection is performed + by ANALYZE (either a manual command, or background + auto-analyze). The collected values can be examined in the + pg_statistic_ext_data + catalog. + + + + ANALYZE computes extended statistics based on the same + sample of table rows that it takes for computing regular single-column + statistics. Since the sample size is increased by increasing the + statistics target for the table or any of its columns (as described in + the previous section), a larger statistics target will normally result in + more accurate extended statistics, as well as more time spent calculating + them. + + + + The following subsections describe the kinds of extended statistics + that are currently supported. + + + + Functional Dependencies + + + The simplest kind of extended statistics tracks functional + dependencies, a concept used in definitions of database normal forms. + We say that column b is functionally dependent on + column a if knowledge of the value of + a is sufficient to determine the value + of b, that is there are no two rows having the same value + of a but different values of b. + In a fully normalized database, functional dependencies should exist + only on primary keys and superkeys. However, in practice many data sets + are not fully normalized for various reasons; intentional + denormalization for performance reasons is a common example. + Even in a fully normalized database, there may be partial correlation + between some columns, which can be expressed as partial functional + dependency. + + + + The existence of functional dependencies directly affects the accuracy + of estimates in certain queries. If a query contains conditions on + both the independent and the dependent column(s), the + conditions on the dependent columns do not further reduce the result + size; but without knowledge of the functional dependency, the query + planner will assume that the conditions are independent, resulting + in underestimating the result size. + + + + To inform the planner about functional dependencies, ANALYZE + can collect measurements of cross-column dependency. Assessing the + degree of dependency between all sets of columns would be prohibitively + expensive, so data collection is limited to those groups of columns + appearing together in a statistics object defined with + the dependencies option. It is advisable to create + dependencies statistics only for column groups that are + strongly correlated, to avoid unnecessary overhead in both + ANALYZE and later query planning. + + + + Here is an example of collecting functional-dependency statistics: + +CREATE STATISTICS stts (dependencies) ON city, zip FROM zipcodes; + +ANALYZE zipcodes; + +SELECT stxname, stxkeys, stxddependencies + FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid) + WHERE stxname = 'stts'; + stxname | stxkeys | stxddependencies +---------+---------+------------------------------------------ + stts | 1 5 | {"1 => 5": 1.000000, "5 => 1": 0.423130} +(1 row) + + Here it can be seen that column 1 (zip code) fully determines column + 5 (city) so the coefficient is 1.0, while city only determines zip code + about 42% of the time, meaning that there are many cities (58%) that are + represented by more than a single ZIP code. + + + + When computing the selectivity for a query involving functionally + dependent columns, the planner adjusts the per-condition selectivity + estimates using the dependency coefficients so as not to produce + an underestimate. + + + + Limitations of Functional Dependencies + + + Functional dependencies are currently only applied when considering + simple equality conditions that compare columns to constant values, + and IN clauses with constant values. + They are not used to improve estimates for equality conditions + comparing two columns or comparing a column to an expression, nor for + range clauses, LIKE or any other type of condition. + + + + When estimating with functional dependencies, the planner assumes that + conditions on the involved columns are compatible and hence redundant. + If they are incompatible, the correct estimate would be zero rows, but + that possibility is not considered. For example, given a query like + +SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '94105'; + + the planner will disregard the city clause as not + changing the selectivity, which is correct. However, it will make + the same assumption about + +SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210'; + + even though there will really be zero rows satisfying this query. + Functional dependency statistics do not provide enough information + to conclude that, however. + + + + In many practical situations, this assumption is usually satisfied; + for example, there might be a GUI in the application that only allows + selecting compatible city and ZIP code values to use in a query. + But if that's not the case, functional dependencies may not be a viable + option. + + + + + + Multivariate N-Distinct Counts + + + Single-column statistics store the number of distinct values in each + column. Estimates of the number of distinct values when combining more + than one column (for example, for GROUP BY a, b) are + frequently wrong when the planner only has single-column statistical + data, causing it to select bad plans. + + + + To improve such estimates, ANALYZE can collect n-distinct + statistics for groups of columns. As before, it's impractical to do + this for every possible column grouping, so data is collected only for + those groups of columns appearing together in a statistics object + defined with the ndistinct option. Data will be collected + for each possible combination of two or more columns from the set of + listed columns. + + + + Continuing the previous example, the n-distinct counts in a + table of ZIP codes might look like the following: + +CREATE STATISTICS stts2 (ndistinct) ON city, state, zip FROM zipcodes; + +ANALYZE zipcodes; + +SELECT stxkeys AS k, stxdndistinct AS nd + FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid) + WHERE stxname = 'stts2'; +-[ RECORD 1 ]------------------------------------------------------&zwsp;-- +k | 1 2 5 +nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178} +(1 row) + + This indicates that there are three combinations of columns that + have 33178 distinct values: ZIP code and state; ZIP code and city; + and ZIP code, city and state (the fact that they are all equal is + expected given that ZIP code alone is unique in this table). On the + other hand, the combination of city and state has only 27435 distinct + values. + + + + It's advisable to create ndistinct statistics objects only + on combinations of columns that are actually used for grouping, and + for which misestimation of the number of groups is resulting in bad + plans. Otherwise, the ANALYZE cycles are just wasted. + + + + + Multivariate MCV Lists + + + Another type of statistics stored for each column are most-common value + lists. This allows very accurate estimates for individual columns, but + may result in significant misestimates for queries with conditions on + multiple columns. + + + + To improve such estimates, ANALYZE can collect MCV + lists on combinations of columns. Similarly to functional dependencies + and n-distinct coefficients, it's impractical to do this for every + possible column grouping. Even more so in this case, as the MCV list + (unlike functional dependencies and n-distinct coefficients) does store + the common column values. So data is collected only for those groups + of columns appearing together in a statistics object defined with the + mcv option. + + + + Continuing the previous example, the MCV list for a table of ZIP codes + might look like the following (unlike for simpler types of statistics, + a function is required for inspection of MCV contents): + + +CREATE STATISTICS stts3 (mcv) ON city, state FROM zipcodes; + +ANALYZE zipcodes; + +SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), + pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts3'; + + index | values | nulls | frequency | base_frequency +-------+------------------------+-------+-----------+---------------- + 0 | {Washington, DC} | {f,f} | 0.003467 | 2.7e-05 + 1 | {Apo, AE} | {f,f} | 0.003067 | 1.9e-05 + 2 | {Houston, TX} | {f,f} | 0.002167 | 0.000133 + 3 | {El Paso, TX} | {f,f} | 0.002 | 0.000113 + 4 | {New York, NY} | {f,f} | 0.001967 | 0.000114 + 5 | {Atlanta, GA} | {f,f} | 0.001633 | 3.3e-05 + 6 | {Sacramento, CA} | {f,f} | 0.001433 | 7.8e-05 + 7 | {Miami, FL} | {f,f} | 0.0014 | 6e-05 + 8 | {Dallas, TX} | {f,f} | 0.001367 | 8.8e-05 + 9 | {Chicago, IL} | {f,f} | 0.001333 | 5.1e-05 + ... +(99 rows) + + This indicates that the most common combination of city and state is + Washington in DC, with actual frequency (in the sample) about 0.35%. + The base frequency of the combination (as computed from the simple + per-column frequencies) is only 0.0027%, resulting in two orders of + magnitude under-estimates. + + + + It's advisable to create MCV statistics objects only + on combinations of columns that are actually used in conditions together, + and for which misestimation of the number of groups is resulting in bad + plans. Otherwise, the ANALYZE and planning cycles + are just wasted. + + + + + + + + Controlling the Planner with Explicit <literal>JOIN</literal> Clauses + + + join + controlling the order + + + + It is possible + to control the query planner to some extent by using the explicit JOIN + syntax. To see why this matters, we first need some background. + + + + In a simple join query, such as: + +SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id; + + the planner is free to join the given tables in any order. For + example, it could generate a query plan that joins A to B, using + the WHERE condition a.id = b.id, and then + joins C to this joined table, using the other WHERE + condition. Or it could join B to C and then join A to that result. + Or it could join A to C and then join them with B — but that + would be inefficient, since the full Cartesian product of A and C + would have to be formed, there being no applicable condition in the + WHERE clause to allow optimization of the join. (All + joins in the PostgreSQL executor happen + between two input tables, so it's necessary to build up the result + in one or another of these fashions.) The important point is that + these different join possibilities give semantically equivalent + results but might have hugely different execution costs. Therefore, + the planner will explore all of them to try to find the most + efficient query plan. + + + + When a query only involves two or three tables, there aren't many join + orders to worry about. But the number of possible join orders grows + exponentially as the number of tables expands. Beyond ten or so input + tables it's no longer practical to do an exhaustive search of all the + possibilities, and even for six or seven tables planning might take an + annoyingly long time. When there are too many input tables, the + PostgreSQL planner will switch from exhaustive + search to a genetic probabilistic search + through a limited number of possibilities. (The switch-over threshold is + set by the run-time + parameter.) + The genetic search takes less time, but it won't + necessarily find the best possible plan. + + + + When the query involves outer joins, the planner has less freedom + than it does for plain (inner) joins. For example, consider: + +SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id); + + Although this query's restrictions are superficially similar to the + previous example, the semantics are different because a row must be + emitted for each row of A that has no matching row in the join of B and C. + Therefore the planner has no choice of join order here: it must join + B to C and then join A to that result. Accordingly, this query takes + less time to plan than the previous query. In other cases, the planner + might be able to determine that more than one join order is safe. + For example, given: + +SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id); + + it is valid to join A to either B or C first. Currently, only + FULL JOIN completely constrains the join order. Most + practical cases involving LEFT JOIN or RIGHT JOIN + can be rearranged to some extent. + + + + Explicit inner join syntax (INNER JOIN, CROSS + JOIN, or unadorned JOIN) is semantically the same as + listing the input relations in FROM, so it does not + constrain the join order. + + + + Even though most kinds of JOIN don't completely constrain + the join order, it is possible to instruct the + PostgreSQL query planner to treat all + JOIN clauses as constraining the join order anyway. + For example, these three queries are logically equivalent: + +SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id; +SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id; +SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id); + + But if we tell the planner to honor the JOIN order, + the second and third take less time to plan than the first. This effect + is not worth worrying about for only three tables, but it can be a + lifesaver with many tables. + + + + To force the planner to follow the join order laid out by explicit + JOINs, + set the run-time parameter to 1. + (Other possible values are discussed below.) + + + + You do not need to constrain the join order completely in order to + cut search time, because it's OK to use JOIN operators + within items of a plain FROM list. For example, consider: + +SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...; + + With join_collapse_limit = 1, this + forces the planner to join A to B before joining them to other tables, + but doesn't constrain its choices otherwise. In this example, the + number of possible join orders is reduced by a factor of 5. + + + + Constraining the planner's search in this way is a useful technique + both for reducing planning time and for directing the planner to a + good query plan. If the planner chooses a bad join order by default, + you can force it to choose a better order via JOIN syntax + — assuming that you know of a better order, that is. Experimentation + is recommended. + + + + A closely related issue that affects planning time is collapsing of + subqueries into their parent query. For example, consider: + +SELECT * +FROM x, y, + (SELECT * FROM a, b, c WHERE something) AS ss +WHERE somethingelse; + + This situation might arise from use of a view that contains a join; + the view's SELECT rule will be inserted in place of the view + reference, yielding a query much like the above. Normally, the planner + will try to collapse the subquery into the parent, yielding: + +SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; + + This usually results in a better plan than planning the subquery + separately. (For example, the outer WHERE conditions might be such that + joining X to A first eliminates many rows of A, thus avoiding the need to + form the full logical output of the subquery.) But at the same time, + we have increased the planning time; here, we have a five-way join + problem replacing two separate three-way join problems. Because of the + exponential growth of the number of possibilities, this makes a big + difference. The planner tries to avoid getting stuck in huge join search + problems by not collapsing a subquery if more than from_collapse_limit + FROM items would result in the parent + query. You can trade off planning time against quality of plan by + adjusting this run-time parameter up or down. + + + + and + are similarly named because they do almost the same thing: one controls + when the planner will flatten out subqueries, and the + other controls when it will flatten out explicit joins. Typically + you would either set join_collapse_limit equal to + from_collapse_limit (so that explicit joins and subqueries + act similarly) or set join_collapse_limit to 1 (if you want + to control join order with explicit joins). But you might set them + differently if you are trying to fine-tune the trade-off between planning + time and run time. + + + + + Populating a Database + + + One might need to insert a large amount of data when first populating + a database. This section contains some suggestions on how to make + this process as efficient as possible. + + + + Disable Autocommit + + + autocommit + bulk-loading data + + + + When using multiple INSERTs, turn off autocommit and just do + one commit at the end. (In plain + SQL, this means issuing BEGIN at the start and + COMMIT at the end. Some client libraries might + do this behind your back, in which case you need to make sure the + library does it when you want it done.) If you allow each + insertion to be committed separately, + PostgreSQL is doing a lot of work for + each row that is added. An additional benefit of doing all + insertions in one transaction is that if the insertion of one row + were to fail then the insertion of all rows inserted up to that + point would be rolled back, so you won't be stuck with partially + loaded data. + + + + + Use <command>COPY</command> + + + Use COPY to load + all the rows in one command, instead of using a series of + INSERT commands. The COPY + command is optimized for loading large numbers of rows; it is less + flexible than INSERT, but incurs significantly + less overhead for large data loads. Since COPY + is a single command, there is no need to disable autocommit if you + use this method to populate a table. + + + + If you cannot use COPY, it might help to use PREPARE to create a + prepared INSERT statement, and then use + EXECUTE as many times as required. This avoids + some of the overhead of repeatedly parsing and planning + INSERT. Different interfaces provide this facility + in different ways; look for prepared statements in the interface + documentation. + + + + Note that loading a large number of rows using + COPY is almost always faster than using + INSERT, even if PREPARE is used and + multiple insertions are batched into a single transaction. + + + + COPY is fastest when used within the same + transaction as an earlier CREATE TABLE or + TRUNCATE command. In such cases no WAL + needs to be written, because in case of an error, the files + containing the newly loaded data will be removed anyway. + However, this consideration only applies when + is minimal + as all commands must write WAL otherwise. + + + + + + Remove Indexes + + + If you are loading a freshly created table, the fastest method is to + create the table, bulk load the table's data using + COPY, then create any indexes needed for the + table. Creating an index on pre-existing data is quicker than + updating it incrementally as each row is loaded. + + + + If you are adding large amounts of data to an existing table, + it might be a win to drop the indexes, + load the table, and then recreate the indexes. Of course, the + database performance for other users might suffer + during the time the indexes are missing. One should also think + twice before dropping a unique index, since the error checking + afforded by the unique constraint will be lost while the index is + missing. + + + + + Remove Foreign Key Constraints + + + Just as with indexes, a foreign key constraint can be checked + in bulk more efficiently than row-by-row. So it might be + useful to drop foreign key constraints, load data, and re-create + the constraints. Again, there is a trade-off between data load + speed and loss of error checking while the constraint is missing. + + + + What's more, when you load data into a table with existing foreign key + constraints, each new row requires an entry in the server's list of + pending trigger events (since it is the firing of a trigger that checks + the row's foreign key constraint). Loading many millions of rows can + cause the trigger event queue to overflow available memory, leading to + intolerable swapping or even outright failure of the command. Therefore + it may be necessary, not just desirable, to drop and re-apply + foreign keys when loading large amounts of data. If temporarily removing + the constraint isn't acceptable, the only other recourse may be to split + up the load operation into smaller transactions. + + + + + Increase <varname>maintenance_work_mem</varname> + + + Temporarily increasing the + configuration variable when loading large amounts of data can + lead to improved performance. This will help to speed up CREATE + INDEX commands and ALTER TABLE ADD FOREIGN KEY commands. + It won't do much for COPY itself, so this advice is + only useful when you are using one or both of the above techniques. + + + + + Increase <varname>max_wal_size</varname> + + + Temporarily increasing the + configuration variable can also + make large data loads faster. This is because loading a large + amount of data into PostgreSQL will + cause checkpoints to occur more often than the normal checkpoint + frequency (specified by the checkpoint_timeout + configuration variable). Whenever a checkpoint occurs, all dirty + pages must be flushed to disk. By increasing + max_wal_size temporarily during bulk + data loads, the number of checkpoints that are required can be + reduced. + + + + + Disable WAL Archival and Streaming Replication + + + When loading large amounts of data into an installation that uses + WAL archiving or streaming replication, it might be faster to take a + new base backup after the load has completed than to process a large + amount of incremental WAL data. To prevent incremental WAL logging + while loading, disable archiving and streaming replication, by setting + to minimal, + to off, and + to zero. + But note that changing these settings requires a server restart, + and makes any base backups taken before unavailable for archive + recovery and standby server, which may lead to data loss. + + + + Aside from avoiding the time for the archiver or WAL sender to process the + WAL data, doing this will actually make certain commands faster, because + they do not to write WAL at all if wal_level + is minimal and the current subtransaction (or top-level + transaction) created or truncated the table or index they change. (They + can guarantee crash safety more cheaply by doing + an fsync at the end than by writing WAL.) + + + + + Run <command>ANALYZE</command> Afterwards + + + Whenever you have significantly altered the distribution of data + within a table, running ANALYZE is strongly recommended. This + includes bulk loading large amounts of data into the table as well as + attaching, detaching or dropping partitions. Running + ANALYZE (or VACUUM ANALYZE) + ensures that the planner has up-to-date statistics about the + table. With no statistics or obsolete statistics, the planner might + make poor decisions during query planning, leading to poor + performance on any tables with inaccurate or nonexistent + statistics. Note that if the autovacuum daemon is enabled, it might + run ANALYZE automatically; see + + and for more information. + + + + + Some Notes about <application>pg_dump</application> + + + Dump scripts generated by pg_dump automatically apply + several, but not all, of the above guidelines. To reload a + pg_dump dump as quickly as possible, you need to + do a few extra things manually. (Note that these points apply while + restoring a dump, not while creating it. + The same points apply whether loading a text dump with + psql or using pg_restore to load + from a pg_dump archive file.) + + + + By default, pg_dump uses COPY, and when + it is generating a complete schema-and-data dump, it is careful to + load data before creating indexes and foreign keys. So in this case + several guidelines are handled automatically. What is left + for you to do is to: + + + + Set appropriate (i.e., larger than normal) values for + maintenance_work_mem and + max_wal_size. + + + + + If using WAL archiving or streaming replication, consider disabling + them during the restore. To do that, set archive_mode + to off, + wal_level to minimal, and + max_wal_senders to zero before loading the dump. + Afterwards, set them back to the right values and take a fresh + base backup. + + + + + Experiment with the parallel dump and restore modes of both + pg_dump and pg_restore and find the + optimal number of concurrent jobs to use. Dumping and restoring in + parallel by means of the option should give you a + significantly higher performance over the serial mode. + + + + + Consider whether the whole dump should be restored as a single + transaction. To do that, pass the or + command-line option to + psql or pg_restore. When using this + mode, even the smallest of errors will rollback the entire restore, + possibly discarding many hours of processing. Depending on how + interrelated the data is, that might seem preferable to manual cleanup, + or not. COPY commands will run fastest if you use a single + transaction and have WAL archiving turned off. + + + + + If multiple CPUs are available in the database server, consider using + pg_restore's option. This + allows concurrent data loading and index creation. + + + + + Run ANALYZE afterwards. + + + + + + + A data-only dump will still use COPY, but it does not + drop or recreate indexes, and it does not normally touch foreign + keys. + + + + You can get the effect of disabling foreign keys by using + the option — but realize that + that eliminates, rather than just postpones, foreign key + validation, and so it is possible to insert bad data if you use it. + + + + So when loading a data-only dump, it is up to you to drop and recreate + indexes and foreign keys if you wish to use those techniques. + It's still useful to increase max_wal_size + while loading the data, but don't bother increasing + maintenance_work_mem; rather, you'd do that while + manually recreating indexes and foreign keys afterwards. + And don't forget to ANALYZE when you're done; see + + and for more information. + + + + + + Non-Durable Settings + + + non-durable + + + + Durability is a database feature that guarantees the recording of + committed transactions even if the server crashes or loses + power. However, durability adds significant database overhead, + so if your site does not require such a guarantee, + PostgreSQL can be configured to run + much faster. The following are configuration changes you can make + to improve performance in such cases. Except as noted below, durability + is still guaranteed in case of a crash of the database software; + only an abrupt operating system crash creates a risk of data loss + or corruption when these settings are used. + + + + + Place the database cluster's data directory in a memory-backed + file system (i.e., RAM disk). This eliminates all + database disk I/O, but limits data storage to the amount of + available memory (and perhaps swap). + + + + + + Turn off ; there is no need to flush + data to disk. + + + + + + Turn off ; there might be no + need to force WAL writes to disk on every + commit. This setting does risk transaction loss (though not data + corruption) in case of a crash of the database. + + + + + + Turn off ; there is no need + to guard against partial page writes. + + + + + + Increase and ; this reduces the frequency + of checkpoints, but increases the storage requirements of + /pg_wal. + + + + + + Create unlogged + tables to avoid WAL writes, though it + makes the tables non-crash-safe. + + + + + + + + diff --git a/doc/src/sgml/pgbuffercache.sgml b/doc/src/sgml/pgbuffercache.sgml new file mode 100644 index 000000000000..e68d159d30f1 --- /dev/null +++ b/doc/src/sgml/pgbuffercache.sgml @@ -0,0 +1,213 @@ + + + + pg_buffercache + + + pg_buffercache + + + + The pg_buffercache module provides a means for + examining what's happening in the shared buffer cache in real time. + + + + pg_buffercache_pages + + + + The module provides a C function pg_buffercache_pages + that returns a set of records, plus a view + pg_buffercache that wraps the function for + convenient use. + + + + By default, use is restricted to superusers and members of the + pg_monitor role. Access may be granted to others + using GRANT. + + + + The <structname>pg_buffercache</structname> View + + + The definitions of the columns exposed by the view are shown in . + + + + <structname>pg_buffercache</structname> Columns + + + + + Column Type + + + Description + + + + + + + + bufferid integer + + + ID, in the range 1..shared_buffers + + + + + + relfilenode oid + (references pg_class.relfilenode) + + + Filenode number of the relation + + + + + + reltablespace oid + (references pg_tablespace.oid) + + + Tablespace OID of the relation + + + + + + reldatabase oid + (references pg_database.oid) + + + Database OID of the relation + + + + + + relforknumber smallint + + + Fork number within the relation; see + common/relpath.h + + + + + + relblocknumber bigint + + + Page number within the relation + + + + + + isdirty boolean + + + Is the page dirty? + + + + + + usagecount smallint + + + Clock-sweep access count + + + + + + pinning_backends integer + + + Number of backends pinning this buffer + + + + +
+ + + There is one row for each buffer in the shared cache. Unused buffers are + shown with all fields null except bufferid. Shared system + catalogs are shown as belonging to database zero. + + + + Because the cache is shared by all the databases, there will normally be + pages from relations not belonging to the current database. This means + that there may not be matching join rows in pg_class for + some rows, or that there could even be incorrect joins. If you are + trying to join against pg_class, it's a good idea to + restrict the join to rows having reldatabase equal to + the current database's OID or zero. + + + + Since buffer manager locks are not taken to copy the buffer state data that + the view will display, accessing pg_buffercache view + has less impact on normal buffer activity but it doesn't provide a consistent + set of results across all buffers. However, we ensure that the information of + each buffer is self-consistent. + +
+ + + Sample Output + + +regression=# SELECT n.nspname, c.relname, count(*) AS buffers + FROM pg_buffercache b JOIN pg_class c + ON b.relfilenode = pg_relation_filenode(c.oid) AND + b.reldatabase IN (0, (SELECT oid FROM pg_database + WHERE datname = current_database())) + JOIN pg_namespace n ON n.oid = c.relnamespace + GROUP BY n.nspname, c.relname + ORDER BY 3 DESC + LIMIT 10; + + nspname | relname | buffers +------------+------------------------+--------- + public | delete_test_table | 593 + public | delete_test_table_pkey | 494 + pg_catalog | pg_attribute | 472 + public | quad_poly_tbl | 353 + public | tenk2 | 349 + public | tenk1 | 349 + public | gin_test_idx | 306 + pg_catalog | pg_largeobject | 206 + public | gin_test_tbl | 188 + public | spgist_text_tbl | 182 +(10 rows) + + + + + Authors + + + Mark Kirkwood markir@paradise.net.nz + + + + Design suggestions: Neil Conway neilc@samurai.com + + + + Debugging advice: Tom Lane tgl@sss.pgh.pa.us + + + +
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml new file mode 100644 index 000000000000..c4dce94001b9 --- /dev/null +++ b/doc/src/sgml/pgcrypto.sgml @@ -0,0 +1,1427 @@ + + + + pgcrypto + + + pgcrypto + + + + encryption + for specific columns + + + + The pgcrypto module provides cryptographic functions for + PostgreSQL. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + General Hashing Functions + + + <function>digest()</function> + + + digest + + + +digest(data text, type text) returns bytea +digest(data bytea, type text) returns bytea + + + + Computes a binary hash of the given data. + type is the algorithm to use. + Standard algorithms are md5, sha1, + sha224, sha256, + sha384 and sha512. + If pgcrypto was built with + OpenSSL, more algorithms are available, as + detailed in . + + + + If you want the digest as a hexadecimal string, use + encode() on the result. For example: + +CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$ + SELECT encode(digest($1, 'sha1'), 'hex') +$$ LANGUAGE SQL STRICT IMMUTABLE; + + + + + + <function>hmac()</function> + + + hmac + + + +hmac(data text, key text, type text) returns bytea +hmac(data bytea, key bytea, type text) returns bytea + + + + Calculates hashed MAC for data with key key. + type is the same as in digest(). + + + + This is similar to digest() but the hash can only be + recalculated knowing the key. This prevents the scenario of someone + altering data and also changing the hash to match. + + + + If the key is larger than the hash block size it will first be hashed and + the result will be used as key. + + + + + + Password Hashing Functions + + + The functions crypt() and gen_salt() + are specifically designed for hashing passwords. + crypt() does the hashing and gen_salt() + prepares algorithm parameters for it. + + + + The algorithms in crypt() differ from the usual + MD5 or SHA1 hashing algorithms in the following respects: + + + + + + They are slow. As the amount of data is so small, this is the only + way to make brute-forcing passwords hard. + + + + + They use a random value, called the salt, so that users + having the same password will have different encrypted passwords. + This is also an additional defense against reversing the algorithm. + + + + + They include the algorithm type in the result, so passwords hashed with + different algorithms can co-exist. + + + + + Some of them are adaptive — that means when computers get + faster, you can tune the algorithm to be slower, without + introducing incompatibility with existing passwords. + + + + + + lists the algorithms + supported by the crypt() function. + + + + Supported Algorithms for <function>crypt()</function> + + + + Algorithm + Max Password Length + Adaptive? + Salt Bits + Output Length + Description + + + + + bf + 72 + yes + 128 + 60 + Blowfish-based, variant 2a + + + md5 + unlimited + no + 48 + 34 + MD5-based crypt + + + xdes + 8 + yes + 24 + 20 + Extended DES + + + des + 8 + no + 12 + 13 + Original UNIX crypt + + + +
+ + + <function>crypt()</function> + + + crypt + + + +crypt(password text, salt text) returns text + + + + Calculates a crypt(3)-style hash of password. + When storing a new password, you need to use + gen_salt() to generate a new salt value. + To check a password, pass the stored hash value as salt, + and test whether the result matches the stored value. + + + Example of setting a new password: + +UPDATE ... SET pswhash = crypt('new password', gen_salt('md5')); + + + + Example of authentication: + +SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ; + + This returns true if the entered password is correct. + + + + + <function>gen_salt()</function> + + + gen_salt + + + +gen_salt(type text [, iter_count integer ]) returns text + + + + Generates a new random salt string for use in crypt(). + The salt string also tells crypt() which algorithm to use. + + + + The type parameter specifies the hashing algorithm. + The accepted types are: des, xdes, + md5 and bf. + + + + The iter_count parameter lets the user specify the iteration + count, for algorithms that have one. + The higher the count, the more time it takes to hash + the password and therefore the more time to break it. Although with + too high a count the time to calculate a hash may be several years + — which is somewhat impractical. If the iter_count + parameter is omitted, the default iteration count is used. + Allowed values for iter_count depend on the algorithm and + are shown in . + + + + Iteration Counts for <function>crypt()</function> + + + + Algorithm + Default + Min + Max + + + + + xdes + 725 + 1 + 16777215 + + + bf + 6 + 4 + 31 + + + +
+ + + For xdes there is an additional limitation that the + iteration count must be an odd number. + + + + To pick an appropriate iteration count, consider that + the original DES crypt was designed to have the speed of 4 hashes per + second on the hardware of that time. + Slower than 4 hashes per second would probably dampen usability. + Faster than 100 hashes per second is probably too fast. + + + + gives an overview of the relative slowness + of different hashing algorithms. + The table shows how much time it would take to try all + combinations of characters in an 8-character password, assuming + that the password contains either only lower case letters, or + upper- and lower-case letters and numbers. + In the crypt-bf entries, the number after a slash is + the iter_count parameter of + gen_salt. + + + + Hash Algorithm Speeds + + + + Algorithm + Hashes/sec + For [a-z] + For [A-Za-z0-9] + Duration relative to md5 hash + + + + + crypt-bf/8 + 1792 + 4 years + 3927 years + 100k + + + crypt-bf/7 + 3648 + 2 years + 1929 years + 50k + + + crypt-bf/6 + 7168 + 1 year + 982 years + 25k + + + crypt-bf/5 + 13504 + 188 days + 521 years + 12.5k + + + crypt-md5 + 171584 + 15 days + 41 years + 1k + + + crypt-des + 23221568 + 157.5 minutes + 108 days + 7 + + + sha1 + 37774272 + 90 minutes + 68 days + 4 + + + md5 (hash) + 150085504 + 22.5 minutes + 17 days + 1 + + + +
+ + + Notes: + + + + + + The machine used is an Intel Mobile Core i3. + + + + + crypt-des and crypt-md5 algorithm numbers are + taken from John the Ripper v1.6.38 -test output. + + + + + md5 hash numbers are from mdcrack 1.2. + + + + + sha1 numbers are from lcrack-20031130-beta. + + + + + crypt-bf numbers are taken using a simple program that + loops over 1000 8-character passwords. That way I can show the speed + with different numbers of iterations. For reference: john + -test shows 13506 loops/sec for crypt-bf/5. + (The very small + difference in results is in accordance with the fact that the + crypt-bf implementation in pgcrypto + is the same one used in John the Ripper.) + + + + + + Note that try all combinations is not a realistic exercise. + Usually password cracking is done with the help of dictionaries, which + contain both regular words and various mutations of them. So, even + somewhat word-like passwords could be cracked much faster than the above + numbers suggest, while a 6-character non-word-like password may escape + cracking. Or not. + +
+
+ + + PGP Encryption Functions + + + The functions here implement the encryption part of the OpenPGP + (RFC 4880) + standard. Supported are both symmetric-key and public-key encryption. + + + + An encrypted PGP message consists of 2 parts, or packets: + + + + + Packet containing a session key — either symmetric-key or public-key + encrypted. + + + + + Packet containing data encrypted with the session key. + + + + + + When encrypting with a symmetric key (i.e., a password): + + + + + The given password is hashed using a String2Key (S2K) algorithm. This is + rather similar to crypt() algorithms — purposefully + slow and with random salt — but it produces a full-length binary + key. + + + + + If a separate session key is requested, a new random key will be + generated. Otherwise the S2K key will be used directly as the session + key. + + + + + If the S2K key is to be used directly, then only S2K settings will be put + into the session key packet. Otherwise the session key will be encrypted + with the S2K key and put into the session key packet. + + + + + + When encrypting with a public key: + + + + + A new random session key is generated. + + + + + It is encrypted using the public key and put into the session key packet. + + + + + + In either case the data to be encrypted is processed as follows: + + + + + Optional data-manipulation: compression, conversion to UTF-8, + and/or conversion of line-endings. + + + + + The data is prefixed with a block of random bytes. This is equivalent + to using a random IV. + + + + + A SHA1 hash of the random prefix and data is appended. + + + + + All this is encrypted with the session key and placed in the data packet. + + + + + + <function>pgp_sym_encrypt()</function> + + + pgp_sym_encrypt + + + + pgp_sym_encrypt_bytea + + + +pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea +pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea + + + Encrypt data with a symmetric PGP key psw. + The options parameter can contain option settings, + as described below. + + + + + <function>pgp_sym_decrypt()</function> + + + pgp_sym_decrypt + + + + pgp_sym_decrypt_bytea + + + +pgp_sym_decrypt(msg bytea, psw text [, options text ]) returns text +pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea + + + Decrypt a symmetric-key-encrypted PGP message. + + + Decrypting bytea data with pgp_sym_decrypt is disallowed. + This is to avoid outputting invalid character data. Decrypting + originally textual data with pgp_sym_decrypt_bytea is fine. + + + The options parameter can contain option settings, + as described below. + + + + + <function>pgp_pub_encrypt()</function> + + + pgp_pub_encrypt + + + + pgp_pub_encrypt_bytea + + + +pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea +pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea + + + Encrypt data with a public PGP key key. + Giving this function a secret key will produce an error. + + + The options parameter can contain option settings, + as described below. + + + + + <function>pgp_pub_decrypt()</function> + + + pgp_pub_decrypt + + + + pgp_pub_decrypt_bytea + + + +pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text ]]) returns text +pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) returns bytea + + + Decrypt a public-key-encrypted message. key must be the + secret key corresponding to the public key that was used to encrypt. + If the secret key is password-protected, you must give the password in + psw. If there is no password, but you want to specify + options, you need to give an empty password. + + + Decrypting bytea data with pgp_pub_decrypt is disallowed. + This is to avoid outputting invalid character data. Decrypting + originally textual data with pgp_pub_decrypt_bytea is fine. + + + The options parameter can contain option settings, + as described below. + + + + + <function>pgp_key_id()</function> + + + pgp_key_id + + + +pgp_key_id(bytea) returns text + + + pgp_key_id extracts the key ID of a PGP public or secret key. + Or it gives the key ID that was used for encrypting the data, if given + an encrypted message. + + + It can return 2 special key IDs: + + + + + SYMKEY + + + The message is encrypted with a symmetric key. + + + + + ANYKEY + + + The message is public-key encrypted, but the key ID has been removed. + That means you will need to try all your secret keys on it to see + which one decrypts it. pgcrypto itself does not produce + such messages. + + + + + Note that different keys may have the same ID. This is rare but a normal + event. The client application should then try to decrypt with each one, + to see which fits — like handling ANYKEY. + + + + + <function>armor()</function>, <function>dearmor()</function> + + + armor + + + + dearmor + + + +armor(data bytea [ , keys text[], values text[] ]) returns text +dearmor(data text) returns bytea + + + These functions wrap/unwrap binary data into PGP ASCII-armor format, + which is basically Base64 with CRC and additional formatting. + + + + If the keys and values arrays are specified, + an armor header is added to the armored format for each + key/value pair. Both arrays must be single-dimensional, and they must + be of the same length. The keys and values cannot contain any non-ASCII + characters. + + + + + <function>pgp_armor_headers</function> + + + pgp_armor_headers + + + +pgp_armor_headers(data text, key out text, value out text) returns setof record + + + pgp_armor_headers() extracts the armor headers from + data. The return value is a set of rows with two columns, + key and value. If the keys or values contain any non-ASCII characters, + they are treated as UTF-8. + + + + + Options for PGP Functions + + + Options are named to be similar to GnuPG. An option's value should be + given after an equal sign; separate options from each other with commas. + For example: + +pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256') + + + + + All of the options except convert-crlf apply only to + encrypt functions. Decrypt functions get the parameters from the PGP + data. + + + + The most interesting options are probably + compress-algo and unicode-mode. + The rest should have reasonable defaults. + + + + cipher-algo + + + Which cipher algorithm to use. + + +Values: bf, aes128, aes192, aes256 (OpenSSL-only: 3des, cast5) +Default: aes128 +Applies to: pgp_sym_encrypt, pgp_pub_encrypt + + + + + compress-algo + + + Which compression algorithm to use. Only available if + PostgreSQL was built with zlib. + + +Values: + 0 - no compression + 1 - ZIP compression + 2 - ZLIB compression (= ZIP plus meta-data and block CRCs) +Default: 0 +Applies to: pgp_sym_encrypt, pgp_pub_encrypt + + + + + compress-level + + + How much to compress. Higher levels compress smaller but are slower. + 0 disables compression. + + +Values: 0, 1-9 +Default: 6 +Applies to: pgp_sym_encrypt, pgp_pub_encrypt + + + + + convert-crlf + + + Whether to convert \n into \r\n when + encrypting and \r\n to \n when + decrypting. RFC 4880 specifies that text data should be stored using + \r\n line-feeds. Use this to get fully RFC-compliant + behavior. + + +Values: 0, 1 +Default: 0 +Applies to: pgp_sym_encrypt, pgp_pub_encrypt, pgp_sym_decrypt, pgp_pub_decrypt + + + + + disable-mdc + + + Do not protect data with SHA-1. The only good reason to use this + option is to achieve compatibility with ancient PGP products, predating + the addition of SHA-1 protected packets to RFC 4880. + Recent gnupg.org and pgp.com software supports it fine. + + +Values: 0, 1 +Default: 0 +Applies to: pgp_sym_encrypt, pgp_pub_encrypt + + + + + sess-key + + + Use separate session key. Public-key encryption always uses a separate + session key; this option is for symmetric-key encryption, which by default + uses the S2K key directly. + + +Values: 0, 1 +Default: 0 +Applies to: pgp_sym_encrypt + + + + + s2k-mode + + + Which S2K algorithm to use. + + +Values: + 0 - Without salt. Dangerous! + 1 - With salt but with fixed iteration count. + 3 - Variable iteration count. +Default: 3 +Applies to: pgp_sym_encrypt + + + + + s2k-count + + + The number of iterations of the S2K algorithm to use. It must + be a value between 1024 and 65011712, inclusive. + + +Default: A random value between 65536 and 253952 +Applies to: pgp_sym_encrypt, only with s2k-mode=3 + + + + + s2k-digest-algo + + + Which digest algorithm to use in S2K calculation. + + +Values: md5, sha1 +Default: sha1 +Applies to: pgp_sym_encrypt + + + + + s2k-cipher-algo + + + Which cipher to use for encrypting separate session key. + + +Values: bf, aes, aes128, aes192, aes256 +Default: use cipher-algo +Applies to: pgp_sym_encrypt + + + + + unicode-mode + + + Whether to convert textual data from database internal encoding to + UTF-8 and back. If your database already is UTF-8, no conversion will + be done, but the message will be tagged as UTF-8. Without this option + it will not be. + + +Values: 0, 1 +Default: 0 +Applies to: pgp_sym_encrypt, pgp_pub_encrypt + + + + + + Generating PGP Keys with GnuPG + + + To generate a new key: + +gpg --gen-key + + + + The preferred key type is DSA and Elgamal. + + + For RSA encryption you must create either DSA or RSA sign-only key + as master and then add an RSA encryption subkey with + gpg --edit-key. + + + To list keys: + +gpg --list-secret-keys + + + + To export a public key in ASCII-armor format: + +gpg -a --export KEYID > public.key + + + + To export a secret key in ASCII-armor format: + +gpg -a --export-secret-keys KEYID > secret.key + + + + You need to use dearmor() on these keys before giving them to + the PGP functions. Or if you can handle binary data, you can drop + -a from the command. + + + For more details see man gpg, + The GNU + Privacy Handbook and other documentation on + . + + + + + Limitations of PGP Code + + + + + No support for signing. That also means that it is not checked + whether the encryption subkey belongs to the master key. + + + + + No support for encryption key as master key. As such practice + is generally discouraged, this should not be a problem. + + + + + No support for several subkeys. This may seem like a problem, as this + is common practice. On the other hand, you should not use your regular + GPG/PGP keys with pgcrypto, but create new ones, + as the usage scenario is rather different. + + + + + + + + Raw Encryption Functions + + + These functions only run a cipher over data; they don't have any advanced + features of PGP encryption. Therefore they have some major problems: + + + + + They use user key directly as cipher key. + + + + + They don't provide any integrity checking, to see + if the encrypted data was modified. + + + + + They expect that users manage all encryption parameters + themselves, even IV. + + + + + They don't handle text. + + + + + So, with the introduction of PGP encryption, usage of raw + encryption functions is discouraged. + + + + encrypt + + + + decrypt + + + + encrypt_iv + + + + decrypt_iv + + + +encrypt(data bytea, key bytea, type text) returns bytea +decrypt(data bytea, key bytea, type text) returns bytea + +encrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea +decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea + + + + Encrypt/decrypt data using the cipher method specified by + type. The syntax of the + type string is: + + +algorithm - mode /pad: padding + + where algorithm is one of: + + + bf — Blowfish + aes — AES (Rijndael-128, -192 or -256) + + and mode is one of: + + + + cbc — next block depends on previous (default) + + + + + ecb — each block is encrypted separately (for + testing only) + + + + and padding is one of: + + + + pkcs — data may be any length (default) + + + + + none — data must be multiple of cipher block size + + + + + + So, for example, these are equivalent: + +encrypt(data, 'fooz', 'bf') +encrypt(data, 'fooz', 'bf-cbc/pad:pkcs') + + + + In encrypt_iv and decrypt_iv, the + iv parameter is the initial value for the CBC mode; + it is ignored for ECB. + It is clipped or padded with zeroes if not exactly block size. + It defaults to all zeroes in the functions without this parameter. + + + + + Random-Data Functions + + + gen_random_bytes + + + +gen_random_bytes(count integer) returns bytea + + + Returns count cryptographically strong random bytes. + At most 1024 bytes can be extracted at a time. This is to avoid + draining the randomness generator pool. + + + + gen_random_uuid + + + +gen_random_uuid() returns uuid + + + Returns a version 4 (random) UUID. (Obsolete, this function is now also + included in core PostgreSQL.) + + + + + Notes + + + Configuration + + + pgcrypto configures itself according to the findings of the + main PostgreSQL configure script. The options that + affect it are --with-zlib and + --with-ssl=openssl. + + + + When compiled with zlib, PGP encryption functions are able to + compress data before encrypting. + + + + When compiled with OpenSSL, there will be + more algorithms available. Also public-key encryption functions will + be faster as OpenSSL has more optimized + BIGNUM functions. + + + + Summary of Functionality with and without OpenSSL + + + + Functionality + Built-in + With OpenSSL + + + + + MD5 + yes + yes + + + SHA1 + yes + yes + + + SHA224/256/384/512 + yes + yes + + + Other digest algorithms + no + yes (Note 1) + + + Blowfish + yes + yes + + + AES + yes + yes + + + DES/3DES/CAST5 + no + yes + + + Raw encryption + yes + yes + + + PGP Symmetric encryption + yes + yes + + + PGP Public-Key encryption + yes + yes + + + +
+ + + Notes: + + + + + + Any digest algorithm OpenSSL supports + is automatically picked up. + This is not possible with ciphers, which need to be supported + explicitly. + + + +
+ + + NULL Handling + + + As is standard in SQL, all functions return NULL, if any of the arguments + are NULL. This may create security risks on careless usage. + + + + + Security Limitations + + + All pgcrypto functions run inside the database server. + That means that all + the data and passwords move between pgcrypto and client + applications in clear text. Thus you must: + + + + + Connect locally or use SSL connections. + + + Trust both system and database administrator. + + + + + If you cannot, then better do crypto inside client application. + + + + The implementation does not resist + side-channel + attacks. For example, the time required for + a pgcrypto decryption function to complete varies among + ciphertexts of a given size. + + + + + Useful Reading + + + + + The GNU Privacy Handbook. + + + + Describes the crypt-blowfish algorithm. + + + + + + How to choose a good password. + + + + Interesting idea for picking passwords. + + + + + + Describes good and bad cryptography. + + + + + + Technical References + + + + + OpenPGP message format. + + + + The MD5 Message-Digest Algorithm. + + + + HMAC: Keyed-Hashing for Message Authentication. + + + + + + Comparison of crypt-des, crypt-md5 and bcrypt algorithms. + + + + + + Description of Fortuna CSPRNG. + + + + Jean-Luc Cooke Fortuna-based /dev/random driver for Linux. + + + +
+ + + Author + + + Marko Kreen markokr@gmail.com + + + + pgcrypto uses code from the following sources: + + + + + + + Algorithm + Author + Source origin + + + + + DES crypt + David Burren and others + FreeBSD libcrypt + + + MD5 crypt + Poul-Henning Kamp + FreeBSD libcrypt + + + Blowfish crypt + Solar Designer + www.openwall.com + + + Blowfish cipher + Simon Tatham + PuTTY + + + Rijndael cipher + Brian Gladman + OpenBSD sys/crypto + + + MD5 hash and SHA1 + WIDE Project + KAME kame/sys/crypto + + + SHA256/384/512 + Aaron D. Gifford + OpenBSD sys/crypto + + + BIGNUM math + Michael J. Fromberger + dartmouth.edu/~sting/sw/imath + + + + + + +
diff --git a/doc/src/sgml/pgfreespacemap.sgml b/doc/src/sgml/pgfreespacemap.sgml new file mode 100644 index 000000000000..5025498249d8 --- /dev/null +++ b/doc/src/sgml/pgfreespacemap.sgml @@ -0,0 +1,120 @@ + + + + pg_freespacemap + + + pg_freespacemap + + + + The pg_freespacemap module provides a means for examining the + free space map (FSM). It provides a function called + pg_freespace, or two overloaded functions, to be + precise. The functions show the value recorded in the free space map for + a given page, or for all pages in the relation. + + + + By default use is restricted to superusers and members of the + pg_stat_scan_tables role. Access may be granted to others + using GRANT. + + + + Functions + + + + + pg_freespace(rel regclass IN, blkno bigint IN) returns int2 + + pg_freespace + + + + + + Returns the amount of free space on the page of the relation, specified + by blkno, according to the FSM. + + + + + + + + pg_freespace(rel regclass IN, blkno OUT bigint, avail OUT int2) + + + + + Displays the amount of free space on each page of the relation, + according to the FSM. A set of (blkno bigint, avail int2) + tuples is returned, one tuple for each page in the relation. + + + + + + + The values stored in the free space map are not exact. They're rounded + to precision of 1/256th of BLCKSZ (32 bytes with default BLCKSZ), and + they're not kept fully up-to-date as tuples are inserted and updated. + + + + For indexes, what is tracked is entirely-unused pages, rather than free + space within pages. Therefore, the values are not meaningful, just + whether a page is full or empty. + + + + + Sample Output + + +postgres=# SELECT * FROM pg_freespace('foo'); + blkno | avail +-------+------- + 0 | 0 + 1 | 0 + 2 | 0 + 3 | 32 + 4 | 704 + 5 | 704 + 6 | 704 + 7 | 1216 + 8 | 704 + 9 | 704 + 10 | 704 + 11 | 704 + 12 | 704 + 13 | 704 + 14 | 704 + 15 | 704 + 16 | 704 + 17 | 704 + 18 | 704 + 19 | 3648 +(20 rows) + +postgres=# SELECT * FROM pg_freespace('foo', 7); + pg_freespace +-------------- + 1216 +(1 row) + + + + + Author + + + Original version by Mark Kirkwood markir@paradise.net.nz. + Rewritten in version 8.4 to suit new FSM implementation by Heikki + Linnakangas heikki@enterprisedb.com + + + + diff --git a/doc/src/sgml/pgrowlocks.sgml b/doc/src/sgml/pgrowlocks.sgml new file mode 100644 index 000000000000..392d5f1f9a77 --- /dev/null +++ b/doc/src/sgml/pgrowlocks.sgml @@ -0,0 +1,150 @@ + + + + pgrowlocks + + + pgrowlocks + + + + The pgrowlocks module provides a function to show row + locking information for a specified table. + + + + By default use is restricted to superusers, members of the + pg_stat_scan_tables role, and users with + SELECT permissions on the table. + + + + + Overview + + + pgrowlocks + + + +pgrowlocks(text) returns setof record + + + + The parameter is the name of a table. The result is a set of records, + with one row for each locked row within the table. The output columns + are shown in . + + + + <function>pgrowlocks</function> Output Columns + + + + + Name + Type + Description + + + + + + locked_row + tid + Tuple ID (TID) of locked row + + + locker + xid + Transaction ID of locker, or multixact ID if multitransaction + + + multi + boolean + True if locker is a multitransaction + + + xids + xid[] + Transaction IDs of lockers (more than one if multitransaction) + + + modes + text[] + Lock mode of lockers (more than one if multitransaction), + an array of Key Share, Share, + For No Key Update, No Key Update, + For Update, Update. + + + + pids + integer[] + Process IDs of locking backends (more than one if multitransaction) + + + + +
+ + + pgrowlocks takes AccessShareLock for the + target table and reads each row one by one to collect the row locking + information. This is not very speedy for a large table. Note that: + + + + + + If an ACCESS EXCLUSIVE lock is taken on the table, + pgrowlocks will be blocked. + + + + + pgrowlocks is not guaranteed to produce a + self-consistent snapshot. It is possible that a new row lock is taken, + or an old lock is freed, during its execution. + + + + + + pgrowlocks does not show the contents of locked + rows. If you want to take a look at the row contents at the same time, you + could do something like this: + + +SELECT * FROM accounts AS a, pgrowlocks('accounts') AS p + WHERE p.locked_row = a.ctid; + + + Be aware however that such a query will be very inefficient. + +
+ + + Sample Output + + +=# SELECT * FROM pgrowlocks('t1'); + locked_row | locker | multi | xids | modes | pids +------------+--------+-------+-------+----------------+-------- + (0,1) | 609 | f | {609} | {"For Share"} | {3161} + (0,2) | 609 | f | {609} | {"For Share"} | {3161} + (0,3) | 607 | f | {607} | {"For Update"} | {3107} + (0,4) | 607 | f | {607} | {"For Update"} | {3107} +(4 rows) + + + + + Author + + + Tatsuo Ishii + + + +
diff --git a/doc/src/sgml/pgstatstatements.sgml b/doc/src/sgml/pgstatstatements.sgml new file mode 100644 index 000000000000..f20b255d4e42 --- /dev/null +++ b/doc/src/sgml/pgstatstatements.sgml @@ -0,0 +1,862 @@ + + + + pg_stat_statements + + + pg_stat_statements + + + + The pg_stat_statements module provides a means for + tracking planning and execution statistics of all SQL statements executed by + a server. + + + + The module must be loaded by adding pg_stat_statements to + in + postgresql.conf, because it requires additional shared memory. + This means that a server restart is needed to add or remove the module. + In addition, query identifier calculation must be enabled in order for the + module to be active, which is done automatically if + is set to auto or on, or any third-party + module that calculates query identifiers is loaded. + + + + When pg_stat_statements is active, it tracks + statistics across all databases of the server. To access and manipulate + these statistics, the module provides views + pg_stat_statements and + pg_stat_statements_info, + and the utility functions pg_stat_statements_reset and + pg_stat_statements. These are not available globally but + can be enabled for a specific database with + CREATE EXTENSION pg_stat_statements. + + + + The <structname>pg_stat_statements</structname> View + + + The statistics gathered by the module are made available via a + view named pg_stat_statements. This view + contains one row for each distinct database ID, user ID, query ID and + toplevel (up to the maximum number of distinct statements that the module + can track). The columns of the view are shown in + . + + + + <structname>pg_stat_statements</structname> Columns + + + + + Column Type + + + Description + + + + + + + + userid oid + (references pg_authid.oid) + + + OID of user who executed the statement + + + + + + dbid oid + (references pg_database.oid) + + + OID of database in which the statement was executed + + + + + + toplevel bool + + + True if the query was executed as a top level statement + (always true if pg_stat_statements.track is set to + top) + + + + + + queryid bigint + + + Hash code to identify identical normalized queries. + + + + + + query text + + + Text of a representative statement + + + + + + plans bigint + + + Number of times the statement was planned + (if pg_stat_statements.track_planning is enabled, + otherwise zero) + + + + + + total_plan_time double precision + + + Total time spent planning the statement, in milliseconds + (if pg_stat_statements.track_planning is enabled, + otherwise zero) + + + + + + min_plan_time double precision + + + Minimum time spent planning the statement, in milliseconds + (if pg_stat_statements.track_planning is enabled, + otherwise zero) + + + + + + max_plan_time double precision + + + Maximum time spent planning the statement, in milliseconds + (if pg_stat_statements.track_planning is enabled, + otherwise zero) + + + + + + mean_plan_time double precision + + + Mean time spent planning the statement, in milliseconds + (if pg_stat_statements.track_planning is enabled, + otherwise zero) + + + + + + stddev_plan_time double precision + + + Population standard deviation of time spent planning the statement, + in milliseconds + (if pg_stat_statements.track_planning is enabled, + otherwise zero) + + + + + + calls bigint + + + Number of times the statement was executed + + + + + + total_exec_time double precision + + + Total time spent executing the statement, in milliseconds + + + + + + min_exec_time double precision + + + Minimum time spent executing the statement, in milliseconds + + + + + + max_exec_time double precision + + + Maximum time spent executing the statement, in milliseconds + + + + + + mean_exec_time double precision + + + Mean time spent executing the statement, in milliseconds + + + + + + stddev_exec_time double precision + + + Population standard deviation of time spent executing the statement, in milliseconds + + + + + + rows bigint + + + Total number of rows retrieved or affected by the statement + + + + + + shared_blks_hit bigint + + + Total number of shared block cache hits by the statement + + + + + + shared_blks_read bigint + + + Total number of shared blocks read by the statement + + + + + + shared_blks_dirtied bigint + + + Total number of shared blocks dirtied by the statement + + + + + + shared_blks_written bigint + + + Total number of shared blocks written by the statement + + + + + + local_blks_hit bigint + + + Total number of local block cache hits by the statement + + + + + + local_blks_read bigint + + + Total number of local blocks read by the statement + + + + + + local_blks_dirtied bigint + + + Total number of local blocks dirtied by the statement + + + + + + local_blks_written bigint + + + Total number of local blocks written by the statement + + + + + + temp_blks_read bigint + + + Total number of temp blocks read by the statement + + + + + + temp_blks_written bigint + + + Total number of temp blocks written by the statement + + + + + + blk_read_time double precision + + + Total time the statement spent reading blocks, in milliseconds + (if is enabled, otherwise zero) + + + + + + blk_write_time double precision + + + Total time the statement spent writing blocks, in milliseconds + (if is enabled, otherwise zero) + + + + + + wal_records bigint + + + Total number of WAL records generated by the statement + + + + + + wal_fpi bigint + + + Total number of WAL full page images generated by the statement + + + + + + wal_bytes numeric + + + Total amount of WAL generated by the statement in bytes + + + + +
+ + + For security reasons, only superusers and members of the + pg_read_all_stats role are allowed to see the SQL text and + queryid of queries executed by other users. + Other users can see the statistics, however, if the view has been installed + in their database. + + + + Plannable queries (that is, SELECT, INSERT, + UPDATE, and DELETE) are combined into a single + pg_stat_statements entry whenever they have identical query + structures according to an internal hash calculation. Typically, two + queries will be considered the same for this purpose if they are + semantically equivalent except for the values of literal constants + appearing in the query. Utility commands (that is, all other commands) + are compared strictly on the basis of their textual query strings, however. + + + + + The following details about constant replacement and + queryid only apply when is enabled. If you use an external + module instead to compute queryid, you + should refer to its documentation for details. + + + + + When a constant's value has been ignored for purposes of matching the query + to other queries, the constant is replaced by a parameter symbol, such + as $1, in the pg_stat_statements + display. + The rest of the query text is that of the first query that had the + particular queryid hash value associated with the + pg_stat_statements entry. + + + + In some cases, queries with visibly different texts might get merged into a + single pg_stat_statements entry. Normally this will happen + only for semantically equivalent queries, but there is a small chance of + hash collisions causing unrelated queries to be merged into one entry. + (This cannot happen for queries belonging to different users or databases, + however.) + + + + Since the queryid hash value is computed on the + post-parse-analysis representation of the queries, the opposite is + also possible: queries with identical texts might appear as + separate entries, if they have different meanings as a result of + factors such as different search_path settings. + + + + Consumers of pg_stat_statements may wish to use + queryid (perhaps in combination with + dbid and userid) as a more stable + and reliable identifier for each entry than its query text. + However, it is important to understand that there are only limited + guarantees around the stability of the queryid hash + value. Since the identifier is derived from the + post-parse-analysis tree, its value is a function of, among other + things, the internal object identifiers appearing in this representation. + This has some counterintuitive implications. For example, + pg_stat_statements will consider two apparently-identical + queries to be distinct, if they reference a table that was dropped + and recreated between the executions of the two queries. + The hashing process is also sensitive to differences in + machine architecture and other facets of the platform. + Furthermore, it is not safe to assume that queryid + will be stable across major versions of PostgreSQL. + + + + As a rule of thumb, queryid values can be assumed to be + stable and comparable only so long as the underlying server version and + catalog metadata details stay exactly the same. Two servers + participating in replication based on physical WAL replay can be expected + to have identical queryid values for the same query. + However, logical replication schemes do not promise to keep replicas + identical in all relevant details, so queryid will + not be a useful identifier for accumulating costs across a set of logical + replicas. If in doubt, direct testing is recommended. + + + + The parameter symbols used to replace constants in + representative query texts start from the next number after the + highest $n parameter in the original query + text, or $1 if there was none. It's worth noting that in + some cases there may be hidden parameter symbols that affect this + numbering. For example, PL/pgSQL uses hidden parameter + symbols to insert values of function local variables into queries, so that + a PL/pgSQL statement like SELECT i + 1 INTO j + would have representative text like SELECT i + $2. + + + + The representative query texts are kept in an external disk file, and do + not consume shared memory. Therefore, even very lengthy query texts can + be stored successfully. However, if many long query texts are + accumulated, the external file might grow unmanageably large. As a + recovery method if that happens, pg_stat_statements may + choose to discard the query texts, whereupon all existing entries in + the pg_stat_statements view will show + null query fields, though the statistics associated with + each queryid are preserved. If this happens, consider + reducing pg_stat_statements.max to prevent + recurrences. + + + + plans and calls aren't + always expected to match because planning and execution statistics are + updated at their respective end phase, and only for successful operations. + For example, if a statement is successfully planned but fails during + the execution phase, only its planning statistics will be updated. + If planning is skipped because a cached plan is used, only its execution + statistics will be updated. + +
+ + + The <structname>pg_stat_statements_info</structname> View + + + pg_stat_statements_info + + + + The statistics of the pg_stat_statements module + itself are tracked and made available via a view named + pg_stat_statements_info. This view contains + only a single row. The columns of the view are shown in + . + + + + <structname>pg_stat_statements_info</structname> Columns + + + + + Column Type + + + Description + + + + + + + + dealloc bigint + + + Total number of times pg_stat_statements + entries about the least-executed statements were deallocated + because more distinct statements than + pg_stat_statements.max were observed + + + + + stats_reset timestamp with time zone + + + Time at which all statistics in the + pg_stat_statements view were last reset. + + + + + +
+
+ + + Functions + + + + + pg_stat_statements_reset(userid Oid, dbid Oid, queryid bigint) returns void + + pg_stat_statements_reset + + + + + + pg_stat_statements_reset discards statistics + gathered so far by pg_stat_statements corresponding + to the specified userid, dbid + and queryid. If any of the parameters are not + specified, the default value 0(invalid) is used for + each of them and the statistics that match with other parameters will be + reset. If no parameter is specified or all the specified parameters are + 0(invalid), it will discard all statistics. + If all statistics in the pg_stat_statements + view are discarded, it will also reset the statistics in the + pg_stat_statements_info view. + By default, this function can only be executed by superusers. + Access may be granted to others using GRANT. + + + + + + + pg_stat_statements(showtext boolean) returns setof record + + pg_stat_statements + function + + + + + + The pg_stat_statements view is defined in + terms of a function also named pg_stat_statements. + It is possible for clients to call + the pg_stat_statements function directly, and by + specifying showtext := false have query text be + omitted (that is, the OUT argument that corresponds + to the view's query column will return nulls). This + feature is intended to support external tools that might wish to avoid + the overhead of repeatedly retrieving query texts of indeterminate + length. Such tools can instead cache the first query text observed + for each entry themselves, since that is + all pg_stat_statements itself does, and then retrieve + query texts only as needed. Since the server stores query texts in a + file, this approach may reduce physical I/O for repeated examination + of the pg_stat_statements data. + + + + + + + + Configuration Parameters + + + + + pg_stat_statements.max (integer) + + + + + pg_stat_statements.max is the maximum number of + statements tracked by the module (i.e., the maximum number of rows + in the pg_stat_statements view). If more distinct + statements than that are observed, information about the least-executed + statements is discarded. The number of times such information was + discarded can be seen in the + pg_stat_statements_info view. + The default value is 5000. + This parameter can only be set at server start. + + + + + + + pg_stat_statements.track (enum) + + + + + pg_stat_statements.track controls which statements + are counted by the module. + Specify top to track top-level statements (those issued + directly by clients), all to also track nested statements + (such as statements invoked within functions), or none to + disable statement statistics collection. + The default value is top. + Only superusers can change this setting. + + + + + + + pg_stat_statements.track_utility (boolean) + + + + + pg_stat_statements.track_utility controls whether + utility commands are tracked by the module. Utility commands are + all those other than SELECT, INSERT, + UPDATE and DELETE. + The default value is on. + Only superusers can change this setting. + + + + + + + pg_stat_statements.track_planning (boolean) + + + + + pg_stat_statements.track_planning controls whether + planning operations and duration are tracked by the module. + Enabling this parameter may incur a noticeable performance penalty, + especially when a fewer kinds of queries are executed on many + concurrent connections. + The default value is off. + Only superusers can change this setting. + + + + + + + pg_stat_statements.save (boolean) + + + + + pg_stat_statements.save specifies whether to + save statement statistics across server shutdowns. + If it is off then statistics are not saved at + shutdown nor reloaded at server start. + The default value is on. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + The module requires additional shared memory proportional to + pg_stat_statements.max. Note that this + memory is consumed whenever the module is loaded, even if + pg_stat_statements.track is set to none. + + + + These parameters must be set in postgresql.conf. + Typical usage might be: + + +# postgresql.conf +shared_preload_libraries = 'pg_stat_statements' + +compute_query_id = on +pg_stat_statements.max = 10000 +pg_stat_statements.track = all + + + + + + Sample Output + + +bench=# SELECT pg_stat_statements_reset(); + +$ pgbench -i bench +$ pgbench -c10 -t300 bench + +bench=# \x +bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit / + nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent + FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5; +-[ RECORD 1 ]---+--------------------------------------------------&zwsp;------------------ +query | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2 +calls | 3000 +total_exec_time | 25565.855387 +rows | 3000 +hit_percent | 100.0000000000000000 +-[ RECORD 2 ]---+--------------------------------------------------&zwsp;------------------ +query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 +calls | 3000 +total_exec_time | 20756.669379 +rows | 3000 +hit_percent | 100.0000000000000000 +-[ RECORD 3 ]---+--------------------------------------------------&zwsp;------------------ +query | copy pgbench_accounts from stdin +calls | 1 +total_exec_time | 291.865911 +rows | 100000 +hit_percent | 100.0000000000000000 +-[ RECORD 4 ]---+--------------------------------------------------&zwsp;------------------ +query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 +calls | 3000 +total_exec_time | 271.232977 +rows | 3000 +hit_percent | 98.8454011741682975 +-[ RECORD 5 ]---+--------------------------------------------------&zwsp;------------------ +query | alter table pgbench_accounts add primary key (aid) +calls | 1 +total_exec_time | 160.588563 +rows | 0 +hit_percent | 100.0000000000000000 + + +bench=# SELECT pg_stat_statements_reset(0,0,s.queryid) FROM pg_stat_statements AS s + WHERE s.query = 'UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2'; + +bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit / + nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent + FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5; +-[ RECORD 1 ]---+--------------------------------------------------&zwsp;------------------ +query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 +calls | 3000 +total_exec_time | 20756.669379 +rows | 3000 +hit_percent | 100.0000000000000000 +-[ RECORD 2 ]---+--------------------------------------------------&zwsp;------------------ +query | copy pgbench_accounts from stdin +calls | 1 +total_exec_time | 291.865911 +rows | 100000 +hit_percent | 100.0000000000000000 +-[ RECORD 3 ]---+--------------------------------------------------&zwsp;------------------ +query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 +calls | 3000 +total_exec_time | 271.232977 +rows | 3000 +hit_percent | 98.8454011741682975 +-[ RECORD 4 ]---+--------------------------------------------------&zwsp;------------------ +query | alter table pgbench_accounts add primary key (aid) +calls | 1 +total_exec_time | 160.588563 +rows | 0 +hit_percent | 100.0000000000000000 +-[ RECORD 5 ]---+--------------------------------------------------&zwsp;------------------ +query | vacuum analyze pgbench_accounts +calls | 1 +total_exec_time | 136.448116 +rows | 0 +hit_percent | 99.9201915403032721 + +bench=# SELECT pg_stat_statements_reset(0,0,0); + +bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit / + nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent + FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5; +-[ RECORD 1 ]---+--------------------------------------------------&zwsp;--------------------------- +query | SELECT pg_stat_statements_reset(0,0,0) +calls | 1 +total_exec_time | 0.189497 +rows | 1 +hit_percent | +-[ RECORD 2 ]---+--------------------------------------------------&zwsp;--------------------------- +query | SELECT query, calls, total_exec_time, rows, $1 * shared_blks_hit / + + | nullif(shared_blks_hit + shared_blks_read, $2) AS hit_percent+ + | FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT $3 +calls | 0 +total_exec_time | 0 +rows | 0 +hit_percent | + + + + + + Authors + + + Takahiro Itagaki itagaki.takahiro@oss.ntt.co.jp. + Query normalization added by Peter Geoghegan peter@2ndquadrant.com. + + + +
diff --git a/doc/src/sgml/pgsurgery.sgml b/doc/src/sgml/pgsurgery.sgml new file mode 100644 index 000000000000..134be9bebde0 --- /dev/null +++ b/doc/src/sgml/pgsurgery.sgml @@ -0,0 +1,107 @@ + + + + pg_surgery + + + pg_surgery + + + + The pg_surgery module provides various functions to + perform surgery on a damaged relation. These functions are unsafe by design + and using them may corrupt (or further corrupt) your database. For example, + these functions can easily be used to make a table inconsistent with its + own indexes, to cause UNIQUE or + FOREIGN KEY constraint violations, or even to make + tuples visible which, when read, will cause a database server crash. + They should be used with great caution and only as a last resort. + + + + Functions + + + + + heap_force_kill(regclass, tid[]) returns void + + + + + heap_force_kill marks used line + pointers as dead without examining the tuples. The + intended use of this function is to forcibly remove tuples that are not + otherwise accessible. For example: + +test=> select * from t1 where ctid = '(0, 1)'; +ERROR: could not access status of transaction 4007513275 +DETAIL: Could not open file "pg_xact/0EED": No such file or directory. + +test=# select heap_force_kill('t1'::regclass, ARRAY['(0, 1)']::tid[]); + heap_force_kill +----------------- + +(1 row) + +test=# select * from t1 where ctid = '(0, 1)'; +(0 rows) + + + + + + + + + heap_force_freeze(regclass, tid[]) returns void + + + + + heap_force_freeze marks tuples as frozen without + examining the tuple data. The intended use of this function is to + make accessible tuples which are inaccessible due to corrupted + visibility information, or which prevent the table from being + successfully vacuumed due to corrupted visibility information. + For example: + +test=> vacuum t1; +ERROR: found xmin 507 from before relfrozenxid 515 +CONTEXT: while scanning block 0 of relation "public.t1" + +test=# select ctid from t1 where xmin = 507; + ctid +------- + (0,3) +(1 row) + +test=# select heap_force_freeze('t1'::regclass, ARRAY['(0, 3)']::tid[]); + heap_force_freeze +------------------- + +(1 row) + +test=# select ctid from t1 where xmin = 2; + ctid +------- + (0,3) +(1 row) + + + + + + + + + + + Authors + + + Ashutosh Sharma ashu.coek88@gmail.com + + + + diff --git a/doc/src/sgml/pgtrgm.sgml b/doc/src/sgml/pgtrgm.sgml new file mode 100644 index 000000000000..7e292822553e --- /dev/null +++ b/doc/src/sgml/pgtrgm.sgml @@ -0,0 +1,642 @@ + + + + pg_trgm + + + pg_trgm + + + + The pg_trgm module provides functions and operators + for determining the similarity of + alphanumeric text based on trigram matching, as + well as index operator classes that support fast searching for similar + strings. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Trigram (or Trigraph) Concepts + + + A trigram is a group of three consecutive characters taken + from a string. We can measure the similarity of two strings by + counting the number of trigrams they share. This simple idea + turns out to be very effective for measuring the similarity of + words in many natural languages. + + + + + pg_trgm ignores non-word characters + (non-alphanumerics) when extracting trigrams from a string. + Each word is considered to have two spaces + prefixed and one space suffixed when determining the set + of trigrams contained in the string. + For example, the set of trigrams in the string + cat is + c, + ca, + cat, and + at . + The set of trigrams in the string + foo|bar is + f, + fo, + foo, + oo , + b, + ba, + bar, and + ar . + + + + + + Functions and Operators + + + The functions provided by the pg_trgm module + are shown in , the operators + in . + + + + <filename>pg_trgm</filename> Functions + + + + + Function + + + Description + + + + + + + + similarity + similarity ( text, text ) + real + + + Returns a number that indicates how similar the two arguments are. + The range of the result is zero (indicating that the two strings are + completely dissimilar) to one (indicating that the two strings are + identical). + + + + + + show_trgm + show_trgm ( text ) + text[] + + + Returns an array of all the trigrams in the given string. + (In practice this is seldom useful except for debugging.) + + + + + + word_similarity + word_similarity ( text, text ) + real + + + Returns a number that indicates the greatest similarity between + the set of trigrams in the first string and any continuous extent + of an ordered set of trigrams in the second string. For details, see + the explanation below. + + + + + + strict_word_similarity + strict_word_similarity ( text, text ) + real + + + Same as word_similarity, but forces + extent boundaries to match word boundaries. Since we don't have + cross-word trigrams, this function actually returns greatest similarity + between first string and any continuous extent of words of the second + string. + + + + + + show_limit + show_limit () + real + + + Returns the current similarity threshold used by the % + operator. This sets the minimum similarity between + two words for them to be considered similar enough to + be misspellings of each other, for example. + (Deprecated; instead use SHOW + pg_trgm.similarity_threshold.) + + + + + + set_limit + set_limit ( real ) + real + + + Sets the current similarity threshold that is used by the % + operator. The threshold must be between 0 and 1 (default is 0.3). + Returns the same value passed in. + (Deprecated; instead use SET + pg_trgm.similarity_threshold.) + + + + +
+ + + Consider the following example: + + +# SELECT word_similarity('word', 'two words'); + word_similarity +----------------- + 0.8 +(1 row) + + + In the first string, the set of trigrams is + {" w"," wo","wor","ord","rd "}. + In the second string, the ordered set of trigrams is + {" t"," tw","two","wo "," w"," wo","wor","ord","rds","ds "}. + The most similar extent of an ordered set of trigrams in the second string + is {" w"," wo","wor","ord"}, and the similarity is + 0.8. + + + + This function returns a value that can be approximately understood as the + greatest similarity between the first string and any substring of the second + string. However, this function does not add padding to the boundaries of + the extent. Thus, the number of additional characters present in the + second string is not considered, except for the mismatched word boundaries. + + + + At the same time, strict_word_similarity + selects an extent of words in the second string. In the example above, + strict_word_similarity would select the + extent of a single word 'words', whose set of trigrams is + {" w"," wo","wor","ord","rds","ds "}. + + +# SELECT strict_word_similarity('word', 'two words'), similarity('word', 'words'); + strict_word_similarity | similarity +------------------------+------------ + 0.571429 | 0.571429 +(1 row) + + + + + Thus, the strict_word_similarity function + is useful for finding the similarity to whole words, while + word_similarity is more suitable for + finding the similarity for parts of words. + + + + <filename>pg_trgm</filename> Operators + + + + + Operator + + + Description + + + + + + + + text % text + boolean + + + Returns true if its arguments have a similarity + that is greater than the current similarity threshold set by + pg_trgm.similarity_threshold. + + + + + + text <% text + boolean + + + Returns true if the similarity between the trigram + set in the first argument and a continuous extent of an ordered trigram + set in the second argument is greater than the current word similarity + threshold set by pg_trgm.word_similarity_threshold + parameter. + + + + + + text %> text + boolean + + + Commutator of the <% operator. + + + + + + text <<% text + boolean + + + Returns true if its second argument has a continuous + extent of an ordered trigram set that matches word boundaries, + and its similarity to the trigram set of the first argument is greater + than the current strict word similarity threshold set by the + pg_trgm.strict_word_similarity_threshold parameter. + + + + + + text %>> text + boolean + + + Commutator of the <<% operator. + + + + + + text <-> text + real + + + Returns the distance between the arguments, that is + one minus the similarity() value. + + + + + + text <<-> text + real + + + Returns the distance between the arguments, that is + one minus the word_similarity() value. + + + + + + text <->> text + real + + + Commutator of the <<-> operator. + + + + + + text <<<-> text + real + + + Returns the distance between the arguments, that is + one minus the strict_word_similarity() value. + + + + + + text <->>> text + real + + + Commutator of the <<<-> operator. + + + + +
+
+ + + GUC Parameters + + + + + pg_trgm.similarity_threshold (real) + + pg_trgm.similarity_threshold configuration parameter + + + + + Sets the current similarity threshold that is used by the % + operator. The threshold must be between 0 and 1 (default is 0.3). + + + + + + pg_trgm.word_similarity_threshold (real) + + pg_trgm.word_similarity_threshold configuration parameter + + + + + Sets the current word similarity threshold that is used by the + <% and %> operators. The threshold + must be between 0 and 1 (default is 0.6). + + + + + + pg_trgm.strict_word_similarity_threshold (real) + + pg_trgm.strict_word_similarity_threshold configuration parameter + + + + + Sets the current strict word similarity threshold that is used by the + <<% and %>> operators. The threshold + must be between 0 and 1 (default is 0.5). + + + + + + + + Index Support + + + The pg_trgm module provides GiST and GIN index + operator classes that allow you to create an index over a text column for + the purpose of very fast similarity searches. These index types support + the above-described similarity operators, and additionally support + trigram-based index searches for LIKE, ILIKE, + ~, ~* and = queries. + Inequality operators are not supported. + Note that those indexes may not be as efficient as regular B-tree indexes + for equality operator. + + + + Example: + + +CREATE TABLE test_trgm (t text); +CREATE INDEX trgm_idx ON test_trgm USING GIST (t gist_trgm_ops); + +or + +CREATE INDEX trgm_idx ON test_trgm USING GIN (t gin_trgm_ops); + + + + + gist_trgm_ops GiST opclass approximates a set of + trigrams as a bitmap signature. Its optional integer parameter + siglen determines the + signature length in bytes. The default length is 12 bytes. + Valid values of signature length are between 1 and 2024 bytes. Longer + signatures lead to a more precise search (scanning a smaller fraction of the index and + fewer heap pages), at the cost of a larger index. + + + + Example of creating such an index with a signature length of 32 bytes: + + +CREATE INDEX trgm_idx ON test_trgm USING GIST (t gist_trgm_ops(siglen=32)); + + + + At this point, you will have an index on the t column that + you can use for similarity searching. A typical query is + +SELECT t, similarity(t, 'word') AS sml + FROM test_trgm + WHERE t % 'word' + ORDER BY sml DESC, t; + + This will return all values in the text column that are sufficiently + similar to word, sorted from best match to worst. The + index will be used to make this a fast operation even over very large data + sets. + + + + A variant of the above query is + +SELECT t, t <-> 'word' AS dist + FROM test_trgm + ORDER BY dist LIMIT 10; + + This can be implemented quite efficiently by GiST indexes, but not + by GIN indexes. It will usually beat the first formulation when only + a small number of the closest matches is wanted. + + + + Also you can use an index on the t column for word + similarity or strict word similarity. Typical queries are: + +SELECT t, word_similarity('word', t) AS sml + FROM test_trgm + WHERE 'word' <% t + ORDER BY sml DESC, t; + + and + +SELECT t, strict_word_similarity('word', t) AS sml + FROM test_trgm + WHERE 'word' <<% t + ORDER BY sml DESC, t; + + This will return all values in the text column for which there is a + continuous extent in the corresponding ordered trigram set that is + sufficiently similar to the trigram set of word, + sorted from best match to worst. The index will be used to make this + a fast operation even over very large data sets. + + + + Possible variants of the above queries are: + +SELECT t, 'word' <<-> t AS dist + FROM test_trgm + ORDER BY dist LIMIT 10; + + and + +SELECT t, 'word' <<<-> t AS dist + FROM test_trgm + ORDER BY dist LIMIT 10; + + This can be implemented quite efficiently by GiST indexes, but not + by GIN indexes. + + + + + Beginning in PostgreSQL 9.1, these index types also support + index searches for LIKE and ILIKE, for example + +SELECT * FROM test_trgm WHERE t LIKE '%foo%bar'; + + The index search works by extracting trigrams from the search string + and then looking these up in the index. The more trigrams in the search + string, the more effective the index search is. Unlike B-tree based + searches, the search string need not be left-anchored. + + + + Beginning in PostgreSQL 9.3, these index types also support + index searches for regular-expression matches + (~ and ~* operators), for example + +SELECT * FROM test_trgm WHERE t ~ '(foo|bar)'; + + The index search works by extracting trigrams from the regular expression + and then looking these up in the index. The more trigrams that can be + extracted from the regular expression, the more effective the index search + is. Unlike B-tree based searches, the search string need not be + left-anchored. + + + + For both LIKE and regular-expression searches, keep in mind + that a pattern with no extractable trigrams will degenerate to a full-index + scan. + + + + The choice between GiST and GIN indexing depends on the relative + performance characteristics of GiST and GIN, which are discussed elsewhere. + + + + + Text Search Integration + + + Trigram matching is a very useful tool when used in conjunction + with a full text index. In particular it can help to recognize + misspelled input words that will not be matched directly by the + full text search mechanism. + + + + The first step is to generate an auxiliary table containing all + the unique words in the documents: + + +CREATE TABLE words AS SELECT word FROM + ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents'); + + + where documents is a table that has a text field + bodytext that we wish to search. The reason for using + the simple configuration with the to_tsvector + function, instead of using a language-specific configuration, + is that we want a list of the original (unstemmed) words. + + + + Next, create a trigram index on the word column: + + +CREATE INDEX words_idx ON words USING GIN (word gin_trgm_ops); + + + Now, a SELECT query similar to the previous example can + be used to suggest spellings for misspelled words in user search terms. + A useful extra test is to require that the selected words are also of + similar length to the misspelled word. + + + + + Since the words table has been generated as a separate, + static table, it will need to be periodically regenerated so that + it remains reasonably up-to-date with the document collection. + Keeping it exactly current is usually unnecessary. + + + + + + References + + + GiST Development Site + + + + Tsearch2 Development Site + + + + + + Authors + + + Oleg Bartunov oleg@sai.msu.su, Moscow, Moscow University, Russia + + + Teodor Sigaev teodor@sigaev.ru, Moscow, Delta-Soft Ltd.,Russia + + + Alexander Korotkov a.korotkov@postgrespro.ru, Moscow, Postgres Professional, Russia + + + Documentation: Christopher Kings-Lynne + + + This module is sponsored by Delta-Soft Ltd., Moscow, Russia. + + + +
diff --git a/doc/src/sgml/plperl.sgml b/doc/src/sgml/plperl.sgml new file mode 100644 index 000000000000..01f9870773da --- /dev/null +++ b/doc/src/sgml/plperl.sgml @@ -0,0 +1,1584 @@ + + + + PL/Perl — Perl Procedural Language + + + PL/Perl + + + + Perl + + + + PL/Perl is a loadable procedural language that enables you to write + PostgreSQL functions and procedures in the + Perl programming language. + + + + The main advantage to using PL/Perl is that this allows use, + within stored functions and procedures, of the manyfold string + munging operators and functions available for Perl. Parsing + complex strings might be easier using Perl than it is with the + string functions and control structures provided in PL/pgSQL. + + + + To install PL/Perl in a particular database, use + CREATE EXTENSION plperl. + + + + + If a language is installed into template1, all subsequently + created databases will have the language installed automatically. + + + + + + Users of source packages must specially enable the build of + PL/Perl during the installation process. (Refer to for more information.) Users of + binary packages might find PL/Perl in a separate subpackage. + + + + + PL/Perl Functions and Arguments + + + To create a function in the PL/Perl language, use the standard + + syntax: + + +CREATE FUNCTION funcname (argument-types) +RETURNS return-type +-- function attributes can go here +AS $$ + # PL/Perl function body goes here +$$ LANGUAGE plperl; + + + The body of the function is ordinary Perl code. In fact, the PL/Perl + glue code wraps it inside a Perl subroutine. A PL/Perl function is + called in a scalar context, so it can't return a list. You can return + non-scalar values (arrays, records, and sets) by returning a reference, + as discussed below. + + + + In a PL/Perl procedure, any return value from the Perl code is ignored. + + + + PL/Perl also supports anonymous code blocks called with the + statement: + + +DO $$ + # PL/Perl code +$$ LANGUAGE plperl; + + + An anonymous code block receives no arguments, and whatever value it + might return is discarded. Otherwise it behaves just like a function. + + + + + The use of named nested subroutines is dangerous in Perl, especially if + they refer to lexical variables in the enclosing scope. Because a PL/Perl + function is wrapped in a subroutine, any named subroutine you place inside + one will be nested. In general, it is far safer to create anonymous + subroutines which you call via a coderef. For more information, see the + entries for Variable "%s" will not stay shared and + Variable "%s" is not available in the + perldiag man page, or + search the Internet for perl nested named subroutine. + + + + + The syntax of the CREATE FUNCTION command requires + the function body to be written as a string constant. It is usually + most convenient to use dollar quoting (see ) for the string constant. + If you choose to use escape string syntax E'', + you must double any single quote marks (') and backslashes + (\) used in the body of the function + (see ). + + + + Arguments and results are handled as in any other Perl subroutine: + arguments are passed in @_, and a result value + is returned with return or as the last expression + evaluated in the function. + + + + For example, a function returning the greater of two integer values + could be defined as: + + +CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ + if ($_[0] > $_[1]) { return $_[0]; } + return $_[1]; +$$ LANGUAGE plperl; + + + + + + Arguments will be converted from the database's encoding to UTF-8 + for use inside PL/Perl, and then converted from UTF-8 back to the + database encoding upon return. + + + + + If an SQL null valuenull valuein PL/Perl is passed to a function, + the argument value will appear as undefined in Perl. The + above function definition will not behave very nicely with null + inputs (in fact, it will act as though they are zeroes). We could + add STRICT to the function definition to make + PostgreSQL do something more reasonable: + if a null value is passed, the function will not be called at all, + but will just return a null result automatically. Alternatively, + we could check for undefined inputs in the function body. For + example, suppose that we wanted perl_max with + one null and one nonnull argument to return the nonnull argument, + rather than a null value: + + +CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$ + my ($x, $y) = @_; + if (not defined $x) { + return undef if not defined $y; + return $y; + } + return $x if not defined $y; + return $x if $x > $y; + return $y; +$$ LANGUAGE plperl; + + As shown above, to return an SQL null value from a PL/Perl + function, return an undefined value. This can be done whether the + function is strict or not. + + + + Anything in a function argument that is not a reference is + a string, which is in the standard PostgreSQL + external text representation for the relevant data type. In the case of + ordinary numeric or text types, Perl will just do the right thing and + the programmer will normally not have to worry about it. However, in + other cases the argument will need to be converted into a form that is + more usable in Perl. For example, the decode_bytea + function can be used to convert an argument of + type bytea into unescaped binary. + + + + Similarly, values passed back to PostgreSQL + must be in the external text representation format. For example, the + encode_bytea function can be used to + escape binary data for a return value of type bytea. + + + + One case that is particularly important is boolean values. As just + stated, the default behavior for bool values is that they + are passed to Perl as text, thus either 't' + or 'f'. This is problematic, since Perl will not + treat 'f' as false! It is possible to improve matters + by using a transform (see + ). Suitable transforms are provided + by the bool_plperl extension. To use it, install + the extension: + +CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU + + Then use the TRANSFORM function attribute for a + PL/Perl function that takes or returns bool, for example: + +CREATE FUNCTION perl_and(bool, bool) RETURNS bool +TRANSFORM FOR TYPE bool +AS $$ + my ($a, $b) = @_; + return $a && $b; +$$ LANGUAGE plperl; + + When this transform is applied, bool arguments will be seen + by Perl as being 1 or empty, thus properly true or + false. If the function result is type bool, it will be true + or false according to whether Perl would evaluate the returned value as + true. + Similar transformations are also performed for boolean query arguments + and results of SPI queries performed inside the function + (). + + + + Perl can return PostgreSQL arrays as + references to Perl arrays. Here is an example: + + +CREATE OR REPLACE function returns_array() +RETURNS text[][] AS $$ + return [['a"b','c,d'],['e\\f','g']]; +$$ LANGUAGE plperl; + +select returns_array(); + + + + + Perl passes PostgreSQL arrays as a blessed + PostgreSQL::InServer::ARRAY object. This object may be treated as an array + reference or a string, allowing for backward compatibility with Perl + code written for PostgreSQL versions below 9.1 to + run. For example: + + +CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$ + my $arg = shift; + my $result = ""; + return undef if (!defined $arg); + + # as an array reference + for (@$arg) { + $result .= $_; + } + + # also works as a string + $result .= $arg; + + return $result; +$$ LANGUAGE plperl; + +SELECT concat_array_elements(ARRAY['PL','/','Perl']); + + + + + Multidimensional arrays are represented as references to + lower-dimensional arrays of references in a way common to every Perl + programmer. + + + + + + Composite-type arguments are passed to the function as references + to hashes. The keys of the hash are the attribute names of the + composite type. Here is an example: + + +CREATE TABLE employee ( + name text, + basesalary integer, + bonus integer +); + +CREATE FUNCTION empcomp(employee) RETURNS integer AS $$ + my ($emp) = @_; + return $emp->{basesalary} + $emp->{bonus}; +$$ LANGUAGE plperl; + +SELECT name, empcomp(employee.*) FROM employee; + + + + + A PL/Perl function can return a composite-type result using the same + approach: return a reference to a hash that has the required attributes. + For example: + + +CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text); + +CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$ + return {f2 => 'hello', f1 => 1, f3 => 'world'}; +$$ LANGUAGE plperl; + +SELECT * FROM perl_row(); + + + Any columns in the declared result data type that are not present in the + hash will be returned as null values. + + + + Similarly, output arguments of procedures can be returned as a hash + reference: + + +CREATE PROCEDURE perl_triple(INOUT a integer, INOUT b integer) AS $$ + my ($a, $b) = @_; + return {a => $a * 3, b => $b * 3}; +$$ LANGUAGE plperl; + +CALL perl_triple(5, 10); + + + + + PL/Perl functions can also return sets of either scalar or + composite types. Usually you'll want to return rows one at a + time, both to speed up startup time and to keep from queuing up + the entire result set in memory. You can do this with + return_next as illustrated below. Note that + after the last return_next, you must put + either return or (better) return + undef. + + +CREATE OR REPLACE FUNCTION perl_set_int(int) +RETURNS SETOF INTEGER AS $$ + foreach (0..$_[0]) { + return_next($_); + } + return undef; +$$ LANGUAGE plperl; + +SELECT * FROM perl_set_int(5); + +CREATE OR REPLACE FUNCTION perl_set() +RETURNS SETOF testrowperl AS $$ + return_next({ f1 => 1, f2 => 'Hello', f3 => 'World' }); + return_next({ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' }); + return_next({ f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }); + return undef; +$$ LANGUAGE plperl; + + + For small result sets, you can return a reference to an array that + contains either scalars, references to arrays, or references to + hashes for simple types, array types, and composite types, + respectively. Here are some simple examples of returning the entire + result set as an array reference: + + +CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$ + return [0..$_[0]]; +$$ LANGUAGE plperl; + +SELECT * FROM perl_set_int(5); + +CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$ + return [ + { f1 => 1, f2 => 'Hello', f3 => 'World' }, + { f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' }, + { f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' } + ]; +$$ LANGUAGE plperl; + +SELECT * FROM perl_set(); + + + + + If you wish to use the strict pragma with your code you + have a few options. For temporary global use you can SET + plperl.use_strict to true. + This will affect subsequent compilations of PL/Perl + functions, but not functions already compiled in the current session. + For permanent global use you can set plperl.use_strict + to true in the postgresql.conf file. + + + + For permanent use in specific functions you can simply put: + +use strict; + + at the top of the function body. + + + + The feature pragma is also available to use if your Perl is version 5.10.0 or higher. + + + + + + Data Values in PL/Perl + + + The argument values supplied to a PL/Perl function's code are + simply the input arguments converted to text form (just as if they + had been displayed by a SELECT statement). + Conversely, the return and return_next + commands will accept any string that is acceptable input format + for the function's declared return type. + + + + If this behavior is inconvenient for a particular case, it can be + improved by using a transform, as already illustrated + for bool values. Several examples of transform modules + are included in the PostgreSQL distribution. + + + + + Built-in Functions + + + Database Access from PL/Perl + + + Access to the database itself from your Perl function can be done + via the following functions: + + + + + + spi_exec_query(query [, max-rows]) + + spi_exec_query + in PL/Perl + + + + + spi_exec_query executes an SQL command and +returns the entire row set as a reference to an array of hash +references. You should only use this command when you know +that the result set will be relatively small. Here is an +example of a query (SELECT command) with the +optional maximum number of rows: + + +$rv = spi_exec_query('SELECT * FROM my_table', 5); + + This returns up to 5 rows from the table + my_table. If my_table + has a column my_column, you can get that + value from row $i of the result like this: + +$foo = $rv->{rows}[$i]->{my_column}; + + The total number of rows returned from a SELECT + query can be accessed like this: + +$nrows = $rv->{processed} + + + + + Here is an example using a different command type: + +$query = "INSERT INTO my_table VALUES (1, 'test')"; +$rv = spi_exec_query($query); + + You can then access the command status (e.g., + SPI_OK_INSERT) like this: + +$res = $rv->{status}; + + To get the number of rows affected, do: + +$nrows = $rv->{processed}; + + + + + Here is a complete example: + +CREATE TABLE test ( + i int, + v varchar +); + +INSERT INTO test (i, v) VALUES (1, 'first line'); +INSERT INTO test (i, v) VALUES (2, 'second line'); +INSERT INTO test (i, v) VALUES (3, 'third line'); +INSERT INTO test (i, v) VALUES (4, 'immortal'); + +CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$ + my $rv = spi_exec_query('select i, v from test;'); + my $status = $rv->{status}; + my $nrows = $rv->{processed}; + foreach my $rn (0 .. $nrows - 1) { + my $row = $rv->{rows}[$rn]; + $row->{i} += 200 if defined($row->{i}); + $row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v})); + return_next($row); + } + return undef; +$$ LANGUAGE plperl; + +SELECT * FROM test_munge(); + + + + + + + + spi_query(command) + + spi_query + in PL/Perl + + + + spi_fetchrow(cursor) + + spi_fetchrow + in PL/Perl + + + + spi_cursor_close(cursor) + + spi_cursor_close + in PL/Perl + + + + + + spi_query and spi_fetchrow + work together as a pair for row sets which might be large, or for cases + where you wish to return rows as they arrive. + spi_fetchrow works only with + spi_query. The following example illustrates how + you use them together: + + +CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT); + +CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$ + use Digest::MD5 qw(md5_hex); + my $file = '/usr/share/dict/words'; + my $t = localtime; + elog(NOTICE, "opening file $file at $t" ); + open my $fh, '<', $file # ooh, it's a file access! + or elog(ERROR, "cannot open $file for reading: $!"); + my @words = <$fh>; + close $fh; + $t = localtime; + elog(NOTICE, "closed file $file at $t"); + chomp(@words); + my $row; + my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)"); + while (defined ($row = spi_fetchrow($sth))) { + return_next({ + the_num => $row->{a}, + the_text => md5_hex($words[rand @words]) + }); + } + return; +$$ LANGUAGE plperlu; + +SELECT * from lotsa_md5(500); + + + + + Normally, spi_fetchrow should be repeated until it + returns undef, indicating that there are no more + rows to read. The cursor returned by spi_query + is automatically freed when + spi_fetchrow returns undef. + If you do not wish to read all the rows, instead call + spi_cursor_close to free the cursor. + Failure to do so will result in memory leaks. + + + + + + + + spi_prepare(command, argument types) + + spi_prepare + in PL/Perl + + + + spi_query_prepared(plan, arguments) + + spi_query_prepared + in PL/Perl + + + + spi_exec_prepared(plan [, attributes], arguments) + + spi_exec_prepared + in PL/Perl + + + + spi_freeplan(plan) + + spi_freeplan + in PL/Perl + + + + + + spi_prepare, spi_query_prepared, spi_exec_prepared, + and spi_freeplan implement the same functionality but for prepared queries. + spi_prepare accepts a query string with numbered argument placeholders ($1, $2, etc) + and a string list of argument types: + +$plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2', + 'INTEGER', 'TEXT'); + + Once a query plan is prepared by a call to spi_prepare, the plan can be used instead + of the string query, either in spi_exec_prepared, where the result is the same as returned + by spi_exec_query, or in spi_query_prepared which returns a cursor + exactly as spi_query does, which can be later passed to spi_fetchrow. + The optional second parameter to spi_exec_prepared is a hash reference of attributes; + the only attribute currently supported is limit, which sets the maximum number of rows returned by a query. + + + + The advantage of prepared queries is that is it possible to use one prepared plan for more + than one query execution. After the plan is not needed anymore, it can be freed with + spi_freeplan: + +CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$ + $_SHARED{my_plan} = spi_prepare('SELECT (now() + $1)::date AS now', + 'INTERVAL'); +$$ LANGUAGE plperl; + +CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$ + return spi_exec_prepared( + $_SHARED{my_plan}, + $_[0] + )->{rows}->[0]->{now}; +$$ LANGUAGE plperl; + +CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$ + spi_freeplan( $_SHARED{my_plan}); + undef $_SHARED{my_plan}; +$$ LANGUAGE plperl; + +SELECT init(); +SELECT add_time('1 day'), add_time('2 days'), add_time('3 days'); +SELECT done(); + + add_time | add_time | add_time +------------+------------+------------ + 2005-12-10 | 2005-12-11 | 2005-12-12 + + Note that the parameter subscript in spi_prepare is defined via + $1, $2, $3, etc, so avoid declaring query strings in double quotes that might easily + lead to hard-to-catch bugs. + + + + Another example illustrates usage of an optional parameter in spi_exec_prepared: + +CREATE TABLE hosts AS SELECT id, ('192.168.1.'||id)::inet AS address + FROM generate_series(1,3) AS id; + +CREATE OR REPLACE FUNCTION init_hosts_query() RETURNS VOID AS $$ + $_SHARED{plan} = spi_prepare('SELECT * FROM hosts + WHERE address << $1', 'inet'); +$$ LANGUAGE plperl; + +CREATE OR REPLACE FUNCTION query_hosts(inet) RETURNS SETOF hosts AS $$ + return spi_exec_prepared( + $_SHARED{plan}, + {limit => 2}, + $_[0] + )->{rows}; +$$ LANGUAGE plperl; + +CREATE OR REPLACE FUNCTION release_hosts_query() RETURNS VOID AS $$ + spi_freeplan($_SHARED{plan}); + undef $_SHARED{plan}; +$$ LANGUAGE plperl; + +SELECT init_hosts_query(); +SELECT query_hosts('192.168.1.0/30'); +SELECT release_hosts_query(); + + query_hosts +----------------- + (1,192.168.1.1) + (2,192.168.1.2) +(2 rows) + + + + + + + + spi_commit() + + spi_commit + in PL/Perl + + + + spi_rollback() + + spi_rollback + in PL/Perl + + + + + Commit or roll back the current transaction. This can only be called + in a procedure or anonymous code block (DO command) + called from the top level. (Note that it is not possible to run the + SQL commands COMMIT or ROLLBACK + via spi_exec_query or similar. It has to be done + using these functions.) After a transaction is ended, a new + transaction is automatically started, so there is no separate function + for that. + + + + Here is an example: + +CREATE PROCEDURE transaction_test1() +LANGUAGE plperl +AS $$ +foreach my $i (0..9) { + spi_exec_query("INSERT INTO test1 (a) VALUES ($i)"); + if ($i % 2 == 0) { + spi_commit(); + } else { + spi_rollback(); + } +} +$$; + +CALL transaction_test1(); + + + + + + + + + Utility Functions in PL/Perl + + + + + elog(level, msg) + + elog + in PL/Perl + + + + + Emit a log or error message. Possible levels are + DEBUG, LOG, INFO, + NOTICE, WARNING, and ERROR. + ERROR + raises an error condition; if this is not trapped by the surrounding + Perl code, the error propagates out to the calling query, causing + the current transaction or subtransaction to be aborted. This + is effectively the same as the Perl die command. + The other levels only generate messages of different + priority levels. + Whether messages of a particular priority are reported to the client, + written to the server log, or both is controlled by the + and + configuration + variables. See for more + information. + + + + + + + quote_literal(string) + + quote_literal + in PL/Perl + + + + + Return the given string suitably quoted to be used as a string literal in an SQL + statement string. Embedded single-quotes and backslashes are properly doubled. + Note that quote_literal returns undef on undef input; if the argument + might be undef, quote_nullable is often more suitable. + + + + + + + quote_nullable(string) + + quote_nullable + in PL/Perl + + + + + Return the given string suitably quoted to be used as a string literal in an SQL + statement string; or, if the argument is undef, return the unquoted string "NULL". + Embedded single-quotes and backslashes are properly doubled. + + + + + + + quote_ident(string) + + quote_ident + in PL/Perl + + + + + Return the given string suitably quoted to be used as an identifier in + an SQL statement string. Quotes are added only if necessary (i.e., if + the string contains non-identifier characters or would be case-folded). + Embedded quotes are properly doubled. + + + + + + + decode_bytea(string) + + decode_bytea + in PL/Perl + + + + + Return the unescaped binary data represented by the contents of the given string, + which should be bytea encoded. + + + + + + + encode_bytea(string) + + encode_bytea + in PL/Perl + + + + + Return the bytea encoded form of the binary data contents of the given string. + + + + + + + encode_array_literal(array) + + encode_array_literal + in PL/Perl + + + + encode_array_literal(array, delimiter) + + + + Returns the contents of the referenced array as a string in array literal format + (see ). + Returns the argument value unaltered if it's not a reference to an array. + The delimiter used between elements of the array literal defaults to ", " + if a delimiter is not specified or is undef. + + + + + + + encode_typed_literal(value, typename) + + encode_typed_literal + in PL/Perl + + + + + Converts a Perl variable to the value of the data type passed as a + second argument and returns a string representation of this value. + Correctly handles nested arrays and values of composite types. + + + + + + + encode_array_constructor(array) + + encode_array_constructor + in PL/Perl + + + + + Returns the contents of the referenced array as a string in array constructor format + (see ). + Individual values are quoted using quote_nullable. + Returns the argument value, quoted using quote_nullable, + if it's not a reference to an array. + + + + + + + looks_like_number(string) + + looks_like_number + in PL/Perl + + + + + Returns a true value if the content of the given string looks like a + number, according to Perl, returns false otherwise. + Returns undef if the argument is undef. Leading and trailing space is + ignored. Inf and Infinity are regarded as numbers. + + + + + + + is_array_ref(argument) + + is_array_ref + in PL/Perl + + + + + Returns a true value if the given argument may be treated as an + array reference, that is, if ref of the argument is ARRAY or + PostgreSQL::InServer::ARRAY. Returns false otherwise. + + + + + + + + + + Global Values in PL/Perl + + + You can use the global hash %_SHARED to store + data, including code references, between function calls for the + lifetime of the current session. + + + + Here is a simple example for shared data: + +CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$ + if ($_SHARED{$_[0]} = $_[1]) { + return 'ok'; + } else { + return "cannot set shared variable $_[0] to $_[1]"; + } +$$ LANGUAGE plperl; + +CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$ + return $_SHARED{$_[0]}; +$$ LANGUAGE plperl; + +SELECT set_var('sample', 'Hello, PL/Perl! How''s tricks?'); +SELECT get_var('sample'); + + + + + Here is a slightly more complicated example using a code reference: + + +CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ + $_SHARED{myquote} = sub { + my $arg = shift; + $arg =~ s/(['\\])/\\$1/g; + return "'$arg'"; + }; +$$ LANGUAGE plperl; + +SELECT myfuncs(); /* initializes the function */ + +/* Set up a function that uses the quote function */ + +CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$ + my $text_to_quote = shift; + my $qfunc = $_SHARED{myquote}; + return &$qfunc($text_to_quote); +$$ LANGUAGE plperl; + + + (You could have replaced the above with the one-liner + return $_SHARED{myquote}->($_[0]); + at the expense of readability.) + + + + For security reasons, PL/Perl executes functions called by any one SQL role + in a separate Perl interpreter for that role. This prevents accidental or + malicious interference by one user with the behavior of another user's + PL/Perl functions. Each such interpreter has its own value of the + %_SHARED variable and other global state. Thus, two + PL/Perl functions will share the same value of %_SHARED + if and only if they are executed by the same SQL role. In an application + wherein a single session executes code under multiple SQL roles (via + SECURITY DEFINER functions, use of SET ROLE, etc) + you may need to take explicit steps to ensure that PL/Perl functions can + share data via %_SHARED. To do that, make sure that + functions that should communicate are owned by the same user, and mark + them SECURITY DEFINER. You must of course take care that + such functions can't be used to do anything unintended. + + + + + Trusted and Untrusted PL/Perl + + + trusted + PL/Perl + + + + Normally, PL/Perl is installed as a trusted programming + language named plperl. In this setup, certain Perl + operations are disabled to preserve security. In general, the + operations that are restricted are those that interact with the + environment. This includes file handle operations, + require, and use (for + external modules). There is no way to access internals of the + database server process or to gain OS-level access with the + permissions of the server process, + as a C function can do. Thus, any unprivileged database user can + be permitted to use this language. + + + + Here is an example of a function that will not work because file + system operations are not allowed for security reasons: + +CREATE FUNCTION badfunc() RETURNS integer AS $$ + my $tmpfile = "/tmp/badfile"; + open my $fh, '>', $tmpfile + or elog(ERROR, qq{could not open the file "$tmpfile": $!}); + print $fh "Testing writing to a file\n"; + close $fh or elog(ERROR, qq{could not close the file "$tmpfile": $!}); + return 1; +$$ LANGUAGE plperl; + + The creation of this function will fail as its use of a forbidden + operation will be caught by the validator. + + + + Sometimes it is desirable to write Perl functions that are not + restricted. For example, one might want a Perl function that sends + mail. To handle these cases, PL/Perl can also be installed as an + untrusted language (usually called + PL/PerlUPL/PerlU). + In this case the full Perl language is available. When installing the + language, the language name plperlu will select + the untrusted PL/Perl variant. + + + + The writer of a PL/PerlU function must take care that the function + cannot be used to do anything unwanted, since it will be able to do + anything that could be done by a user logged in as the database + administrator. Note that the database system allows only database + superusers to create functions in untrusted languages. + + + + If the above function was created by a superuser using the language + plperlu, execution would succeed. + + + + In the same way, anonymous code blocks written in Perl can use + restricted operations if the language is specified as + plperlu rather than plperl, but the caller + must be a superuser. + + + + + While PL/Perl functions run in a separate Perl + interpreter for each SQL role, all PL/PerlU functions + executed in a given session run in a single Perl interpreter (which is + not any of the ones used for PL/Perl functions). + This allows PL/PerlU functions to share data freely, + but no communication can occur between PL/Perl and + PL/PerlU functions. + + + + + + Perl cannot support multiple interpreters within one process unless + it was built with the appropriate flags, namely either + usemultiplicity or useithreads. + (usemultiplicity is preferred unless you actually need + to use threads. For more details, see the + perlembed man page.) + If PL/Perl is used with a copy of Perl that was not built + this way, then it is only possible to have one Perl interpreter per + session, and so any one session can only execute either + PL/PerlU functions, or PL/Perl functions + that are all called by the same SQL role. + + + + + + + PL/Perl Triggers + + + PL/Perl can be used to write trigger functions. In a trigger function, + the hash reference $_TD contains information about the + current trigger event. $_TD is a global variable, + which gets a separate local value for each invocation of the trigger. + The fields of the $_TD hash reference are: + + + + $_TD->{new}{foo} + + + NEW value of column foo + + + + + + $_TD->{old}{foo} + + + OLD value of column foo + + + + + + $_TD->{name} + + + Name of the trigger being called + + + + + + $_TD->{event} + + + Trigger event: INSERT, UPDATE, + DELETE, TRUNCATE, or UNKNOWN + + + + + + $_TD->{when} + + + When the trigger was called: BEFORE, + AFTER, INSTEAD OF, or + UNKNOWN + + + + + + $_TD->{level} + + + The trigger level: ROW, STATEMENT, or UNKNOWN + + + + + + $_TD->{relid} + + + OID of the table on which the trigger fired + + + + + + $_TD->{table_name} + + + Name of the table on which the trigger fired + + + + + + $_TD->{relname} + + + Name of the table on which the trigger fired. This has been deprecated, + and could be removed in a future release. + Please use $_TD->{table_name} instead. + + + + + + $_TD->{table_schema} + + + Name of the schema in which the table on which the trigger fired, is + + + + + + $_TD->{argc} + + + Number of arguments of the trigger function + + + + + + @{$_TD->{args}} + + + Arguments of the trigger function. Does not exist if $_TD->{argc} is 0. + + + + + + + + + Row-level triggers can return one of the following: + + + + return; + + + Execute the operation + + + + + + "SKIP" + + + Don't execute the operation + + + + + + "MODIFY" + + + Indicates that the NEW row was modified by + the trigger function + + + + + + + + Here is an example of a trigger function, illustrating some of the + above: + +CREATE TABLE test ( + i int, + v varchar +); + +CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$ + if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) { + return "SKIP"; # skip INSERT/UPDATE command + } elsif ($_TD->{new}{v} ne "immortal") { + $_TD->{new}{v} .= "(modified by trigger)"; + return "MODIFY"; # modify row and execute INSERT/UPDATE command + } else { + return; # execute INSERT/UPDATE command + } +$$ LANGUAGE plperl; + +CREATE TRIGGER test_valid_id_trig + BEFORE INSERT OR UPDATE ON test + FOR EACH ROW EXECUTE FUNCTION valid_id(); + + + + + + PL/Perl Event Triggers + + + PL/Perl can be used to write event trigger functions. In an event trigger + function, the hash reference $_TD contains information + about the current trigger event. $_TD is a global variable, + which gets a separate local value for each invocation of the trigger. The + fields of the $_TD hash reference are: + + + + $_TD->{event} + + + The name of the event the trigger is fired for. + + + + + + $_TD->{tag} + + + The command tag for which the trigger is fired. + + + + + + + + The return value of the trigger function is ignored. + + + + Here is an example of an event trigger function, illustrating some of the + above: + +CREATE OR REPLACE FUNCTION perlsnitch() RETURNS event_trigger AS $$ + elog(NOTICE, "perlsnitch: " . $_TD->{event} . " " . $_TD->{tag} . " "); +$$ LANGUAGE plperl; + +CREATE EVENT TRIGGER perl_a_snitch + ON ddl_command_start + EXECUTE FUNCTION perlsnitch(); + + + + + + PL/Perl Under the Hood + + + Configuration + + + This section lists configuration parameters that affect PL/Perl. + + + + + + + plperl.on_init (string) + + plperl.on_init configuration parameter + + + + + Specifies Perl code to be executed when a Perl interpreter is first + initialized, before it is specialized for use by plperl or + plperlu. + The SPI functions are not available when this code is executed. + If the code fails with an error it will abort the initialization of + the interpreter and propagate out to the calling query, causing the + current transaction or subtransaction to be aborted. + + + The Perl code is limited to a single string. Longer code can be placed + into a module and loaded by the on_init string. + Examples: + +plperl.on_init = 'require "plperlinit.pl"' +plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;' + + + + Any modules loaded by plperl.on_init, either directly or + indirectly, will be available for use by plperl. This may + create a security risk. To see what modules have been loaded you can use: + +DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl; + + + + Initialization will happen in the postmaster if the plperl library is + included in , in which + case extra consideration should be given to the risk of destabilizing + the postmaster. The principal reason for making use of this feature + is that Perl modules loaded by plperl.on_init need be + loaded only at postmaster start, and will be instantly available + without loading overhead in individual database sessions. However, + keep in mind that the overhead is avoided only for the first Perl + interpreter used by a database session — either PL/PerlU, or + PL/Perl for the first SQL role that calls a PL/Perl function. Any + additional Perl interpreters created in a database session will have + to execute plperl.on_init afresh. Also, on Windows there + will be no savings whatsoever from preloading, since the Perl + interpreter created in the postmaster process does not propagate to + child processes. + + + This parameter can only be set in the postgresql.conf file or on the server command line. + + + + + + + plperl.on_plperl_init (string) + + plperl.on_plperl_init configuration parameter + + + + plperl.on_plperlu_init (string) + + plperl.on_plperlu_init configuration parameter + + + + + These parameters specify Perl code to be executed when a Perl + interpreter is specialized for plperl or + plperlu respectively. This will happen when a PL/Perl or + PL/PerlU function is first executed in a database session, or when + an additional interpreter has to be created because the other language + is called or a PL/Perl function is called by a new SQL role. This + follows any initialization done by plperl.on_init. + The SPI functions are not available when this code is executed. + The Perl code in plperl.on_plperl_init is executed after + locking down the interpreter, and thus it can only perform + trusted operations. + + + If the code fails with an error it will abort the initialization and + propagate out to the calling query, causing the current transaction or + subtransaction to be aborted. Any actions already done within Perl + won't be undone; however, that interpreter won't be used again. + If the language is used again the initialization will be attempted + again within a fresh Perl interpreter. + + + Only superusers can change these settings. Although these settings + can be changed within a session, such changes will not affect Perl + interpreters that have already been used to execute functions. + + + + + + + plperl.use_strict (boolean) + + plperl.use_strict configuration parameter + + + + + When set true subsequent compilations of PL/Perl functions will have + the strict pragma enabled. This parameter does not affect + functions already compiled in the current session. + + + + + + + + + Limitations and Missing Features + + + The following features are currently missing from PL/Perl, but they + would make welcome contributions. + + + + + PL/Perl functions cannot call each other directly. + + + + + + SPI is not yet fully implemented. + + + + + + If you are fetching very large data sets using + spi_exec_query, you should be aware that + these will all go into memory. You can avoid this by using + spi_query/spi_fetchrow as + illustrated earlier. + + + A similar problem occurs if a set-returning function passes a + large set of rows back to PostgreSQL via return. You + can avoid this problem too by instead using + return_next for each row returned, as shown + previously. + + + + + + When a session ends normally, not due to a fatal error, any + END blocks that have been defined are executed. + Currently no other actions are performed. Specifically, + file handles are not automatically flushed and objects are + not automatically destroyed. + + + + + + + + + diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml new file mode 100644 index 000000000000..4cd4bcba802d --- /dev/null +++ b/doc/src/sgml/plpgsql.sgml @@ -0,0 +1,6080 @@ + + + + <application>PL/pgSQL</application> — <acronym>SQL</acronym> Procedural Language + + + PL/pgSQL + + + + Overview + + + PL/pgSQL is a loadable procedural + language for the PostgreSQL database + system. The design goals of PL/pgSQL were to create + a loadable procedural language that + + + + + can be used to create functions, procedures, and triggers, + + + + + adds control structures to the SQL language, + + + + + can perform complex computations, + + + + + inherits all user-defined types, functions, procedures, and operators, + + + + + can be defined to be trusted by the server, + + + + + is easy to use. + + + + + + + Functions created with PL/pgSQL can be + used anywhere that built-in functions could be used. + For example, it is possible to + create complex conditional computation functions and later use + them to define operators or use them in index expressions. + + + + In PostgreSQL 9.0 and later, + PL/pgSQL is installed by default. + However it is still a loadable module, so especially security-conscious + administrators could choose to remove it. + + + + Advantages of Using <application>PL/pgSQL</application> + + + SQL is the language PostgreSQL + and most other relational databases use as query language. It's + portable and easy to learn. But every SQL + statement must be executed individually by the database server. + + + + That means that your client application must send each query to + the database server, wait for it to be processed, receive and + process the results, do some computation, then send further + queries to the server. All this incurs interprocess + communication and will also incur network overhead if your client + is on a different machine than the database server. + + + + With PL/pgSQL you can group a block of + computation and a series of queries inside + the database server, thus having the power of a procedural + language and the ease of use of SQL, but with considerable + savings of client/server communication overhead. + + + + Extra round trips between + client and server are eliminated + + Intermediate results that the client does not + need do not have to be marshaled or transferred between server + and client + + Multiple rounds of query + parsing can be avoided + + + This can result in a considerable performance increase as + compared to an application that does not use stored functions. + + + + Also, with PL/pgSQL you can use all + the data types, operators and functions of SQL. + + + + + Supported Argument and Result Data Types + + + Functions written in PL/pgSQL can accept + as arguments any scalar or array data type supported by the server, + and they can return a result of any of these types. They can also + accept or return any composite type (row type) specified by name. + It is also possible to declare a PL/pgSQL + function as accepting record, which means that any + composite type will do as input, or + as returning record, which means that the result + is a row type whose columns are determined by specification in the + calling query, as discussed in . + + + + PL/pgSQL functions can be declared to accept a variable + number of arguments by using the VARIADIC marker. This + works exactly the same way as for SQL functions, as discussed in + . + + + + PL/pgSQL functions can also be declared to + accept and return the polymorphic types described in + , thus allowing the actual data + types handled by the function to vary from call to call. + Examples appear in . + + + + PL/pgSQL functions can also be declared to return + a set (or table) of any data type that can be returned as + a single instance. Such a function generates its output by executing + RETURN NEXT for each desired element of the result + set, or by using RETURN QUERY to output the result of + evaluating a query. + + + + Finally, a PL/pgSQL function can be declared to return + void if it has no useful return value. (Alternatively, it + could be written as a procedure in that case.) + + + + PL/pgSQL functions can also be declared with output + parameters in place of an explicit specification of the return type. + This does not add any fundamental capability to the language, but + it is often convenient, especially for returning multiple values. + The RETURNS TABLE notation can also be used in place + of RETURNS SETOF. + + + + Specific examples appear in + and + . + + + + + + Structure of <application>PL/pgSQL</application> + + + Functions written in PL/pgSQL are defined + to the server by executing commands. + Such a command would normally look like, say, + +CREATE FUNCTION somefunc(integer, text) RETURNS integer +AS 'function body text' +LANGUAGE plpgsql; + + The function body is simply a string literal so far as CREATE + FUNCTION is concerned. It is often helpful to use dollar quoting + (see ) to write the function + body, rather than the normal single quote syntax. Without dollar quoting, + any single quotes or backslashes in the function body must be escaped by + doubling them. Almost all the examples in this chapter use dollar-quoted + literals for their function bodies. + + + + PL/pgSQL is a block-structured language. + The complete text of a function body must be a + block. A block is defined as: + + + <<label>> + DECLARE + declarations +BEGIN + statements +END label ; + + + + + Each declaration and each statement within a block is terminated + by a semicolon. A block that appears within another block must + have a semicolon after END, as shown above; + however the final END that + concludes a function body does not require a semicolon. + + + + + A common mistake is to write a semicolon immediately after + BEGIN. This is incorrect and will result in a syntax error. + + + + + A label is only needed if you want to + identify the block for use + in an EXIT statement, or to qualify the names of the + variables declared in the block. If a label is given after + END, it must match the label at the block's beginning. + + + + All key words are case-insensitive. + Identifiers are implicitly converted to lower case + unless double-quoted, just as they are in ordinary SQL commands. + + + + Comments work the same way in PL/pgSQL code as in + ordinary SQL. A double dash (--) starts a comment + that extends to the end of the line. A /* starts a + block comment that extends to the matching occurrence of + */. Block comments nest. + + + + Any statement in the statement section of a block + can be a subblock. Subblocks can be used for + logical grouping or to localize variables to a small group + of statements. Variables declared in a subblock mask any + similarly-named variables of outer blocks for the duration + of the subblock; but you can access the outer variables anyway + if you qualify their names with their block's label. For example: + +CREATE FUNCTION somefunc() RETURNS integer AS $$ +<< outerblock >> +DECLARE + quantity integer := 30; +BEGIN + RAISE NOTICE 'Quantity here is %', quantity; -- Prints 30 + quantity := 50; + -- + -- Create a subblock + -- + DECLARE + quantity integer := 80; + BEGIN + RAISE NOTICE 'Quantity here is %', quantity; -- Prints 80 + RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Prints 50 + END; + + RAISE NOTICE 'Quantity here is %', quantity; -- Prints 50 + + RETURN quantity; +END; +$$ LANGUAGE plpgsql; + + + + + + There is actually a hidden outer block surrounding the body + of any PL/pgSQL function. This block provides the + declarations of the function's parameters (if any), as well as some + special variables such as FOUND (see + ). The outer block is + labeled with the function's name, meaning that parameters and special + variables can be qualified with the function's name. + + + + + It is important not to confuse the use of + BEGIN/END for grouping statements in + PL/pgSQL with the similarly-named SQL commands + for transaction + control. PL/pgSQL's BEGIN/END + are only for grouping; they do not start or end a transaction. + See for information on managing + transactions in PL/pgSQL. + Also, a block containing an EXCEPTION clause effectively + forms a subtransaction that can be rolled back without affecting the + outer transaction. For more about that see . + + + + + Declarations + + + All variables used in a block must be declared in the + declarations section of the block. + (The only exceptions are that the loop variable of a FOR loop + iterating over a range of integer values is automatically declared as an + integer variable, and likewise the loop variable of a FOR loop + iterating over a cursor's result is automatically declared as a + record variable.) + + + + PL/pgSQL variables can have any SQL data type, such as + integer, varchar, and + char. + + + + Here are some examples of variable declarations: + +user_id integer; +quantity numeric(5); +url varchar; +myrow tablename%ROWTYPE; +myfield tablename.columnname%TYPE; +arow RECORD; + + + + + The general syntax of a variable declaration is: + +name CONSTANT type COLLATE collation_name NOT NULL { DEFAULT | := | = } expression ; + + The DEFAULT clause, if given, specifies the initial value assigned + to the variable when the block is entered. If the DEFAULT clause + is not given then the variable is initialized to the + SQL null value. + The CONSTANT option prevents the variable from being + assigned to after initialization, so that its value will remain constant + for the duration of the block. + The COLLATE option specifies a collation to use for the + variable (see ). + If NOT NULL + is specified, an assignment of a null value results in a run-time + error. All variables declared as NOT NULL + must have a nonnull default value specified. + Equal (=) can be used instead of PL/SQL-compliant + :=. + + + + A variable's default value is evaluated and assigned to the variable + each time the block is entered (not just once per function call). + So, for example, assigning now() to a variable of type + timestamp causes the variable to have the + time of the current function call, not the time when the function was + precompiled. + + + + Examples: + +quantity integer DEFAULT 32; +url varchar := 'http://mysite.com'; +user_id CONSTANT integer := 10; + + + + + Declaring Function Parameters + + + Parameters passed to functions are named with the identifiers + $1, $2, + etc. Optionally, aliases can be declared for + $n + parameter names for increased readability. Either the alias or the + numeric identifier can then be used to refer to the parameter value. + + + + There are two ways to create an alias. The preferred way is to give a + name to the parameter in the CREATE FUNCTION command, + for example: + +CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$ +BEGIN + RETURN subtotal * 0.06; +END; +$$ LANGUAGE plpgsql; + + The other way is to explicitly declare an alias, using the + declaration syntax + + +name ALIAS FOR $n; + + + The same example in this style looks like: + +CREATE FUNCTION sales_tax(real) RETURNS real AS $$ +DECLARE + subtotal ALIAS FOR $1; +BEGIN + RETURN subtotal * 0.06; +END; +$$ LANGUAGE plpgsql; + + + + + + These two examples are not perfectly equivalent. In the first case, + subtotal could be referenced as + sales_tax.subtotal, but in the second case it could not. + (Had we attached a label to the inner block, subtotal could + be qualified with that label, instead.) + + + + + Some more examples: + +CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$ +DECLARE + v_string ALIAS FOR $1; + index ALIAS FOR $2; +BEGIN + -- some computations using v_string and index here +END; +$$ LANGUAGE plpgsql; + + +CREATE FUNCTION concat_selected_fields(in_t sometablename) RETURNS text AS $$ +BEGIN + RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7; +END; +$$ LANGUAGE plpgsql; + + + + + When a PL/pgSQL function is declared + with output parameters, the output parameters are given + $n names and optional + aliases in just the same way as the normal input parameters. An + output parameter is effectively a variable that starts out NULL; + it should be assigned to during the execution of the function. + The final value of the parameter is what is returned. For instance, + the sales-tax example could also be done this way: + + +CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$ +BEGIN + tax := subtotal * 0.06; +END; +$$ LANGUAGE plpgsql; + + + Notice that we omitted RETURNS real — we could have + included it, but it would be redundant. + + + + To call a function with OUT parameters, omit the + output parameter(s) in the function call: + +SELECT sales_tax(100.00); + + + + + Output parameters are most useful when returning multiple values. + A trivial example is: + + +CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$ +BEGIN + sum := x + y; + prod := x * y; +END; +$$ LANGUAGE plpgsql; + +SELECT * FROM sum_n_product(2, 4); + sum | prod +-----+------ + 6 | 8 + + + As discussed in , this + effectively creates an anonymous record type for the function's + results. If a RETURNS clause is given, it must say + RETURNS record. + + + + This also works with procedures, for example: + + +CREATE PROCEDURE sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$ +BEGIN + sum := x + y; + prod := x * y; +END; +$$ LANGUAGE plpgsql; + + + In a call to a procedure, all the parameters must be specified. For + output parameters, NULL may be specified when + calling the procedure from plain SQL: + +CALL sum_n_product(2, 4, NULL, NULL); + sum | prod +-----+------ + 6 | 8 + + + However, when calling a procedure + from PL/pgSQL, you should instead write a + variable for any output parameter; the variable will receive the result + of the call. See + for details. + + + + Another way to declare a PL/pgSQL function + is with RETURNS TABLE, for example: + + +CREATE FUNCTION extended_sales(p_itemno int) +RETURNS TABLE(quantity int, total numeric) AS $$ +BEGIN + RETURN QUERY SELECT s.quantity, s.quantity * s.price FROM sales AS s + WHERE s.itemno = p_itemno; +END; +$$ LANGUAGE plpgsql; + + + This is exactly equivalent to declaring one or more OUT + parameters and specifying RETURNS SETOF + sometype. + + + + When the return type of a PL/pgSQL function + is declared as a polymorphic type (see + ), a special + parameter $0 is created. Its data type is the actual + return type of the function, as deduced from the actual input types. + This allows the function to access its actual return type + as shown in . + $0 is initialized to null and can be modified by + the function, so it can be used to hold the return value if desired, + though that is not required. $0 can also be + given an alias. For example, this function works on any data type + that has a + operator: + + +CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement) +RETURNS anyelement AS $$ +DECLARE + result ALIAS FOR $0; +BEGIN + result := v1 + v2 + v3; + RETURN result; +END; +$$ LANGUAGE plpgsql; + + + + + The same effect can be obtained by declaring one or more output parameters as + polymorphic types. In this case the + special $0 parameter is not used; the output + parameters themselves serve the same purpose. For example: + + +CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement, + OUT sum anyelement) +AS $$ +BEGIN + sum := v1 + v2 + v3; +END; +$$ LANGUAGE plpgsql; + + + + + In practice it might be more useful to declare a polymorphic function + using the anycompatible family of types, so that automatic + promotion of the input arguments to a common type will occur. + For example: + + +CREATE FUNCTION add_three_values(v1 anycompatible, v2 anycompatible, v3 anycompatible) +RETURNS anycompatible AS $$ +BEGIN + RETURN v1 + v2 + v3; +END; +$$ LANGUAGE plpgsql; + + + With this example, a call such as + + +SELECT add_three_values(1, 2, 4.7); + + + will work, automatically promoting the integer inputs to numeric. + The function using anyelement would require you to + cast the three inputs to the same type manually. + + + + + <literal>ALIAS</literal> + + +newname ALIAS FOR oldname; + + + + The ALIAS syntax is more general than is suggested in the + previous section: you can declare an alias for any variable, not just + function parameters. The main practical use for this is to assign + a different name for variables with predetermined names, such as + NEW or OLD within + a trigger function. + + + + Examples: + +DECLARE + prior ALIAS FOR old; + updated ALIAS FOR new; + + + + + Since ALIAS creates two different ways to name the same + object, unrestricted use can be confusing. It's best to use it only + for the purpose of overriding predetermined names. + + + + + Copying Types + + +variable%TYPE + + + + %TYPE provides the data type of a variable or + table column. You can use this to declare variables that will hold + database values. For example, let's say you have a column named + user_id in your users + table. To declare a variable with the same data type as + users.user_id you write: + +user_id users.user_id%TYPE; + + + + + By using %TYPE you don't need to know the data + type of the structure you are referencing, and most importantly, + if the data type of the referenced item changes in the future (for + instance: you change the type of user_id + from integer to real), you might not need + to change your function definition. + + + + %TYPE is particularly valuable in polymorphic + functions, since the data types needed for internal variables can + change from one call to the next. Appropriate variables can be + created by applying %TYPE to the function's + arguments or result placeholders. + + + + + + Row Types + + +name table_name%ROWTYPE; +name composite_type_name; + + + + A variable of a composite type is called a row + variable (or row-type variable). Such a variable + can hold a whole row of a SELECT or FOR + query result, so long as that query's column set matches the + declared type of the variable. + The individual fields of the row value + are accessed using the usual dot notation, for example + rowvar.field. + + + + A row variable can be declared to have the same type as the rows of + an existing table or view, by using the + table_name%ROWTYPE + notation; or it can be declared by giving a composite type's name. + (Since every table has an associated composite type of the same name, + it actually does not matter in PostgreSQL whether you + write %ROWTYPE or not. But the form with + %ROWTYPE is more portable.) + + + + Parameters to a function can be + composite types (complete table rows). In that case, the + corresponding identifier $n will be a row variable, and fields can + be selected from it, for example $1.user_id. + + + + Here is an example of using composite types. table1 + and table2 are existing tables having at least the + mentioned fields: + + +CREATE FUNCTION merge_fields(t_row table1) RETURNS text AS $$ +DECLARE + t2_row table2%ROWTYPE; +BEGIN + SELECT * INTO t2_row FROM table2 WHERE ... ; + RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7; +END; +$$ LANGUAGE plpgsql; + +SELECT merge_fields(t.*) FROM table1 t WHERE ... ; + + + + + + Record Types + + +name RECORD; + + + + Record variables are similar to row-type variables, but they have no + predefined structure. They take on the actual row structure of the + row they are assigned during a SELECT or FOR command. The substructure + of a record variable can change each time it is assigned to. + A consequence of this is that until a record variable is first assigned + to, it has no substructure, and any attempt to access a + field in it will draw a run-time error. + + + + Note that RECORD is not a true data type, only a placeholder. + One should also realize that when a PL/pgSQL + function is declared to return type record, this is not quite the + same concept as a record variable, even though such a function might + use a record variable to hold its result. In both cases the actual row + structure is unknown when the function is written, but for a function + returning record the actual structure is determined when the + calling query is parsed, whereas a record variable can change its row + structure on-the-fly. + + + + + Collation of <application>PL/pgSQL</application> Variables + + + collation + in PL/pgSQL + + + + When a PL/pgSQL function has one or more + parameters of collatable data types, a collation is identified for each + function call depending on the collations assigned to the actual + arguments, as described in . If a collation is + successfully identified (i.e., there are no conflicts of implicit + collations among the arguments) then all the collatable parameters are + treated as having that collation implicitly. This will affect the + behavior of collation-sensitive operations within the function. + For example, consider + + +CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ +BEGIN + RETURN a < b; +END; +$$ LANGUAGE plpgsql; + +SELECT less_than(text_field_1, text_field_2) FROM table1; +SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1; + + + The first use of less_than will use the common collation + of text_field_1 and text_field_2 for + the comparison, while the second use will use C collation. + + + + Furthermore, the identified collation is also assumed as the collation of + any local variables that are of collatable types. Thus this function + would not work any differently if it were written as + + +CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$ +DECLARE + local_a text := a; + local_b text := b; +BEGIN + RETURN local_a < local_b; +END; +$$ LANGUAGE plpgsql; + + + + + If there are no parameters of collatable data types, or no common + collation can be identified for them, then parameters and local variables + use the default collation of their data type (which is usually the + database's default collation, but could be different for variables of + domain types). + + + + A local variable of a collatable data type can have a different collation + associated with it by including the COLLATE option in its + declaration, for example + + +DECLARE + local_a text COLLATE "en_US"; + + + This option overrides the collation that would otherwise be + given to the variable according to the rules above. + + + + Also, of course explicit COLLATE clauses can be written inside + a function if it is desired to force a particular collation to be used in + a particular operation. For example, + + +CREATE FUNCTION less_than_c(a text, b text) RETURNS boolean AS $$ +BEGIN + RETURN a < b COLLATE "C"; +END; +$$ LANGUAGE plpgsql; + + + This overrides the collations associated with the table columns, + parameters, or local variables used in the expression, just as would + happen in a plain SQL command. + + + + + + Expressions + + + All expressions used in PL/pgSQL + statements are processed using the server's main + SQL executor. For example, when you write + a PL/pgSQL statement like + +IF expression THEN ... + + PL/pgSQL will evaluate the expression by + feeding a query like + +SELECT expression + + to the main SQL engine. While forming the SELECT command, + any occurrences of PL/pgSQL variable names + are replaced by query parameters, as discussed in detail in + . + This allows the query plan for the SELECT to + be prepared just once and then reused for subsequent + evaluations with different values of the variables. Thus, what + really happens on first use of an expression is essentially a + PREPARE command. For example, if we have declared + two integer variables x and y, and we write + +IF x < y THEN ... + + what happens behind the scenes is equivalent to + +PREPARE statement_name(integer, integer) AS SELECT $1 < $2; + + and then this prepared statement is EXECUTEd for each + execution of the IF statement, with the current values + of the PL/pgSQL variables supplied as + parameter values. Normally these details are + not important to a PL/pgSQL user, but + they are useful to know when trying to diagnose a problem. + More information appears in . + + + + Since an expression is converted to a + SELECT command, it can contain the same clauses + that an ordinary SELECT would, except that it + cannot include a top-level UNION, + INTERSECT, or EXCEPT clause. + Thus for example one could test whether a table is non-empty with + +IF count(*) > 0 FROM my_table THEN ... + + since the expression + between IF and THEN is parsed as + though it were SELECT count(*) > 0 FROM my_table. + The SELECT must produce a single column, and not + more than one row. (If it produces no rows, the result is taken as + NULL.) + + + + + Basic Statements + + + In this section and the following ones, we describe all the statement + types that are explicitly understood by + PL/pgSQL. + Anything not recognized as one of these statement types is presumed + to be an SQL command and is sent to the main database engine to execute, + as described in . + + + + Assignment + + + An assignment of a value to a PL/pgSQL + variable is written as: + +variable { := | = } expression; + + As explained previously, the expression in such a statement is evaluated + by means of an SQL SELECT command sent to the main + database engine. The expression must yield a single value (possibly + a row value, if the variable is a row or record variable). The target + variable can be a simple variable (optionally qualified with a block + name), a field of a row or record target, or an element or slice of + an array target. Equal (=) can be + used instead of PL/SQL-compliant :=. + + + + If the expression's result data type doesn't match the variable's + data type, the value will be coerced as though by an assignment cast + (see ). If no assignment cast is known + for the pair of data types involved, the PL/pgSQL + interpreter will attempt to convert the result value textually, that is + by applying the result type's output function followed by the variable + type's input function. Note that this could result in run-time errors + generated by the input function, if the string form of the result value + is not acceptable to the input function. + + + + Examples: + +tax := subtotal * 0.06; +my_record.user_id := 20; +my_array[j] := 20; +my_array[1:3] := array[1,2,3]; +complex_array[n].realpart = 12.3; + + + + + + Executing SQL Commands + + + In general, any SQL command that does not return rows can be executed + within a PL/pgSQL function just by writing + the command. For example, you could create and fill a table by writing + +CREATE TABLE mytable (id int primary key, data text); +INSERT INTO mytable VALUES (1,'one'), (2,'two'); + + + + + If the command does return rows (for example SELECT, + or INSERT/UPDATE/DELETE + with RETURNING), there are two ways to proceed. + When the command will return at most one row, or you only care about + the first row of output, write the command as usual but add + an INTO clause to capture the output, as described + in . + To process all of the output rows, write the command as the data + source for a FOR loop, as described in + . + + + + Usually it is not sufficient just to execute statically-defined SQL + commands. Typically you'll want a command to use varying data values, + or even to vary in more fundamental ways such as by using different + table names at different times. Again, there are two ways to proceed + depending on the situation. + + + + PL/pgSQL variable values can be + automatically inserted into optimizable SQL commands, which + are SELECT, INSERT, + UPDATE, DELETE, and certain + utility commands that incorporate one of these, such + as EXPLAIN and CREATE TABLE ... AS + SELECT. In these commands, + any PL/pgSQL variable name appearing + in the command text is replaced by a query parameter, and then the + current value of the variable is provided as the parameter value + at run time. This is exactly like the processing described earlier + for expressions; for details see . + + + + When executing an optimizable SQL command in this way, + PL/pgSQL may cache and re-use the execution + plan for the command, as discussed in + . + + + + Non-optimizable SQL commands (also called utility commands) are not + capable of accepting query parameters. So automatic substitution + of PL/pgSQL variables does not work in such + commands. To include non-constant text in a utility command executed + from PL/pgSQL, you must build the utility + command as a string and then EXECUTE it, as + discussed in . + + + + EXECUTE must also be used if you want to modify + the command in some other way than supplying a data value, for example + by changing a table name. + + + + Sometimes it is useful to evaluate an expression or SELECT + query but discard the result, for example when calling a function + that has side-effects but no useful result value. To do + this in PL/pgSQL, use the + PERFORM statement: + + +PERFORM query; + + + This executes query and discards the + result. Write the query the same + way you would write an SQL SELECT command, but replace the + initial keyword SELECT with PERFORM. + For WITH queries, use PERFORM and then + place the query in parentheses. (In this case, the query can only + return one row.) + PL/pgSQL variables will be + substituted into the query just as described above, + and the plan is cached in the same way. Also, the special variable + FOUND is set to true if the query produced at + least one row, or false if it produced no rows (see + ). + + + + + One might expect that writing SELECT directly + would accomplish this result, but at + present the only accepted way to do it is + PERFORM. An SQL command that can return rows, + such as SELECT, will be rejected as an error + unless it has an INTO clause as discussed in the + next section. + + + + + An example: + +PERFORM create_mv('cs_session_page_requests_mv', my_query); + + + + + + Executing a Command with a Single-Row Result + + + SELECT INTO + in PL/pgSQL + + + + RETURNING INTO + in PL/pgSQL + + + + The result of an SQL command yielding a single row (possibly of multiple + columns) can be assigned to a record variable, row-type variable, or list + of scalar variables. This is done by writing the base SQL command and + adding an INTO clause. For example, + + +SELECT select_expressions INTO STRICT target FROM ...; +INSERT ... RETURNING expressions INTO STRICT target; +UPDATE ... RETURNING expressions INTO STRICT target; +DELETE ... RETURNING expressions INTO STRICT target; + + + where target can be a record variable, a row + variable, or a comma-separated list of simple variables and + record/row fields. + PL/pgSQL variables will be + substituted into the rest of the command (that is, everything but the + INTO clause) just as described above, + and the plan is cached in the same way. + This works for SELECT, + INSERT/UPDATE/DELETE with + RETURNING, and certain utility commands + that return row sets, such as EXPLAIN. + Except for the INTO clause, the SQL command is the same + as it would be written outside PL/pgSQL. + + + + + Note that this interpretation of SELECT with INTO + is quite different from PostgreSQL's regular + SELECT INTO command, wherein the INTO + target is a newly created table. If you want to create a table from a + SELECT result inside a + PL/pgSQL function, use the syntax + CREATE TABLE ... AS SELECT. + + + + + If a row variable or a variable list is used as target, + the command's result columns + must exactly match the structure of the target as to number and data + types, or else a run-time error + occurs. When a record variable is the target, it automatically + configures itself to the row type of the command's result columns. + + + + The INTO clause can appear almost anywhere in the SQL + command. Customarily it is written either just before or just after + the list of select_expressions in a + SELECT command, or at the end of the command for other + command types. It is recommended that you follow this convention + in case the PL/pgSQL parser becomes + stricter in future versions. + + + + If STRICT is not specified in the INTO + clause, then target will be set to the first + row returned by the command, or to nulls if the command returned no rows. + (Note that the first row is not + well-defined unless you've used ORDER BY.) Any result rows + after the first row are discarded. + You can check the special FOUND variable (see + ) to + determine whether a row was returned: + + +SELECT * INTO myrec FROM emp WHERE empname = myname; +IF NOT FOUND THEN + RAISE EXCEPTION 'employee % not found', myname; +END IF; + + + If the STRICT option is specified, the command must + return exactly one row or a run-time error will be reported, either + NO_DATA_FOUND (no rows) or TOO_MANY_ROWS + (more than one row). You can use an exception block if you wish + to catch the error, for example: + + +BEGIN + SELECT * INTO STRICT myrec FROM emp WHERE empname = myname; + EXCEPTION + WHEN NO_DATA_FOUND THEN + RAISE EXCEPTION 'employee % not found', myname; + WHEN TOO_MANY_ROWS THEN + RAISE EXCEPTION 'employee % not unique', myname; +END; + + Successful execution of a command with STRICT + always sets FOUND to true. + + + + For INSERT/UPDATE/DELETE with + RETURNING, PL/pgSQL reports + an error for more than one returned row, even when + STRICT is not specified. This is because there + is no option such as ORDER BY with which to determine + which affected row should be returned. + + + + If print_strict_params is enabled for the function, + then when an error is thrown because the requirements + of STRICT are not met, the DETAIL part of + the error message will include information about the parameters + passed to the command. + You can change the print_strict_params + setting for all functions by setting + plpgsql.print_strict_params, though only subsequent + function compilations will be affected. You can also enable it + on a per-function basis by using a compiler option, for example: + +CREATE FUNCTION get_userid(username text) RETURNS int +AS $$ +#print_strict_params on +DECLARE +userid int; +BEGIN + SELECT users.userid INTO STRICT userid + FROM users WHERE users.username = get_userid.username; + RETURN userid; +END; +$$ LANGUAGE plpgsql; + + On failure, this function might produce an error message such as + +ERROR: query returned no rows +DETAIL: parameters: $1 = 'nosuchuser' +CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement + + + + + + The STRICT option matches the behavior of + Oracle PL/SQL's SELECT INTO and related statements. + + + + + + + Executing Dynamic Commands + + + Oftentimes you will want to generate dynamic commands inside your + PL/pgSQL functions, that is, commands + that will involve different tables or different data types each + time they are executed. PL/pgSQL's + normal attempts to cache plans for commands (as discussed in + ) will not work in such + scenarios. To handle this sort of problem, the + EXECUTE statement is provided: + + +EXECUTE command-string INTO STRICT target USING expression , ... ; + + + where command-string is an expression + yielding a string (of type text) containing the + command to be executed. The optional target + is a record variable, a row variable, or a comma-separated list of + simple variables and record/row fields, into which the results of + the command will be stored. The optional USING expressions + supply values to be inserted into the command. + + + + No substitution of PL/pgSQL variables is done on the + computed command string. Any required variable values must be inserted + in the command string as it is constructed; or you can use parameters + as described below. + + + + Also, there is no plan caching for commands executed via + EXECUTE. Instead, the command is always planned + each time the statement is run. Thus the command + string can be dynamically created within the function to perform + actions on different tables and columns. + + + + The INTO clause specifies where the results of + an SQL command returning rows should be assigned. If a row variable + or variable list is provided, it must exactly match the structure + of the command's results; if a + record variable is provided, it will configure itself to match the + result structure automatically. If multiple rows are returned, + only the first will be assigned to the INTO + variable(s). If no rows are returned, NULL is assigned to the + INTO variable(s). If no INTO + clause is specified, the command results are discarded. + + + + If the STRICT option is given, an error is reported + unless the command produces exactly one row. + + + + The command string can use parameter values, which are referenced + in the command as $1, $2, etc. + These symbols refer to values supplied in the USING + clause. This method is often preferable to inserting data values + into the command string as text: it avoids run-time overhead of + converting the values to text and back, and it is much less prone + to SQL-injection attacks since there is no need for quoting or escaping. + An example is: + +EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' + INTO c + USING checked_user, checked_date; + + + + + Note that parameter symbols can only be used for data values + — if you want to use dynamically determined table or column + names, you must insert them into the command string textually. + For example, if the preceding query needed to be done against a + dynamically selected table, you could do this: + +EXECUTE 'SELECT count(*) FROM ' + || quote_ident(tabname) + || ' WHERE inserted_by = $1 AND inserted <= $2' + INTO c + USING checked_user, checked_date; + + A cleaner approach is to use format()'s %I + specification to insert table or column names with automatic quoting: + +EXECUTE format('SELECT count(*) FROM %I ' + 'WHERE inserted_by = $1 AND inserted <= $2', tabname) + INTO c + USING checked_user, checked_date; + + (This example relies on the SQL rule that string literals separated by a + newline are implicitly concatenated.) + + + + Another restriction on parameter symbols is that they only work in + optimizable SQL commands + (SELECT, INSERT, UPDATE, + DELETE, and certain commands containing one of these). + In other statement + types (generically called utility statements), you must insert + values textually even if they are just data values. + + + + An EXECUTE with a simple constant command string and some + USING parameters, as in the first example above, is + functionally equivalent to just writing the command directly in + PL/pgSQL and allowing replacement of + PL/pgSQL variables to happen automatically. + The important difference is that EXECUTE will re-plan + the command on each execution, generating a plan that is specific + to the current parameter values; whereas + PL/pgSQL may otherwise create a generic plan + and cache it for re-use. In situations where the best plan depends + strongly on the parameter values, it can be helpful to use + EXECUTE to positively ensure that a generic plan is not + selected. + + + + SELECT INTO is not currently supported within + EXECUTE; instead, execute a plain SELECT + command and specify INTO as part of the EXECUTE + itself. + + + + + The PL/pgSQL + EXECUTE statement is not related to the + EXECUTE SQL + statement supported by the + PostgreSQL server. The server's + EXECUTE statement cannot be used directly within + PL/pgSQL functions (and is not needed). + + + + + Quoting Values in Dynamic Queries + + + quote_ident + use in PL/pgSQL + + + + quote_literal + use in PL/pgSQL + + + + quote_nullable + use in PL/pgSQL + + + + format + use in PL/pgSQL + + + + When working with dynamic commands you will often have to handle escaping + of single quotes. The recommended method for quoting fixed text in your + function body is dollar quoting. (If you have legacy code that does + not use dollar quoting, please refer to the + overview in , which can save you + some effort when translating said code to a more reasonable scheme.) + + + + Dynamic values require careful handling since they might contain + quote characters. + An example using format() (this assumes that you are + dollar quoting the function body so quote marks need not be doubled): + +EXECUTE format('UPDATE tbl SET %I = $1 ' + 'WHERE key = $2', colname) USING newvalue, keyvalue; + + It is also possible to call the quoting functions directly: + +EXECUTE 'UPDATE tbl SET ' + || quote_ident(colname) + || ' = ' + || quote_literal(newvalue) + || ' WHERE key = ' + || quote_literal(keyvalue); + + + + + This example demonstrates the use of the + quote_ident and + quote_literal functions (see ). For safety, expressions containing column + or table identifiers should be passed through + quote_ident before insertion in a dynamic query. + Expressions containing values that should be literal strings in the + constructed command should be passed through quote_literal. + These functions take the appropriate steps to return the input text + enclosed in double or single quotes respectively, with any embedded + special characters properly escaped. + + + + Because quote_literal is labeled + STRICT, it will always return null when called with a + null argument. In the above example, if newvalue or + keyvalue were null, the entire dynamic query string would + become null, leading to an error from EXECUTE. + You can avoid this problem by using the quote_nullable + function, which works the same as quote_literal except that + when called with a null argument it returns the string NULL. + For example, + +EXECUTE 'UPDATE tbl SET ' + || quote_ident(colname) + || ' = ' + || quote_nullable(newvalue) + || ' WHERE key = ' + || quote_nullable(keyvalue); + + If you are dealing with values that might be null, you should usually + use quote_nullable in place of quote_literal. + + + + As always, care must be taken to ensure that null values in a query do + not deliver unintended results. For example the WHERE clause + +'WHERE key = ' || quote_nullable(keyvalue) + + will never succeed if keyvalue is null, because the + result of using the equality operator = with a null operand + is always null. If you wish null to work like an ordinary key value, + you would need to rewrite the above as + +'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue) + + (At present, IS NOT DISTINCT FROM is handled much less + efficiently than =, so don't do this unless you must. + See for + more information on nulls and IS DISTINCT.) + + + + Note that dollar quoting is only useful for quoting fixed text. + It would be a very bad idea to try to write this example as: + +EXECUTE 'UPDATE tbl SET ' + || quote_ident(colname) + || ' = $$' + || newvalue + || '$$ WHERE key = ' + || quote_literal(keyvalue); + + because it would break if the contents of newvalue + happened to contain $$. The same objection would + apply to any other dollar-quoting delimiter you might pick. + So, to safely quote text that is not known in advance, you + must use quote_literal, + quote_nullable, or quote_ident, as appropriate. + + + + Dynamic SQL statements can also be safely constructed using the + format function (see ). For example: + +EXECUTE format('UPDATE tbl SET %I = %L ' + 'WHERE key = %L', colname, newvalue, keyvalue); + + %I is equivalent to quote_ident, and + %L is equivalent to quote_nullable. + The format function can be used in conjunction with + the USING clause: + +EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) + USING newvalue, keyvalue; + + This form is better because the variables are handled in their native + data type format, rather than unconditionally converting them to + text and quoting them via %L. It is also more efficient. + + + + + A much larger example of a dynamic command and + EXECUTE can be seen in , which builds and executes a + CREATE FUNCTION command to define a new function. + + + + + Obtaining the Result Status + + + There are several ways to determine the effect of a command. The + first method is to use the GET DIAGNOSTICS + command, which has the form: + + +GET CURRENT DIAGNOSTICS variable { = | := } item , ... ; + + + This command allows retrieval of system status indicators. + CURRENT is a noise word (but see also GET STACKED + DIAGNOSTICS in ). + Each item is a key word identifying a status + value to be assigned to the specified variable + (which should be of the right data type to receive it). The currently + available status items are shown + in . Colon-equal + (:=) can be used instead of the SQL-standard = + token. An example: + +GET DIAGNOSTICS integer_var = ROW_COUNT; + + + + + Available Diagnostics Items + + + + + + + Name + Type + Description + + + + + ROW_COUNT + bigint + the number of rows processed by the most + recent SQL command + + + PG_CONTEXT + text + line(s) of text describing the current call stack + (see ) + + + +
+ + + The second method to determine the effects of a command is to check the + special variable named FOUND, which is of + type boolean. FOUND starts out + false within each PL/pgSQL function call. + It is set by each of the following types of statements: + + + + + A SELECT INTO statement sets + FOUND true if a row is assigned, false if no + row is returned. + + + + + A PERFORM statement sets FOUND + true if it produces (and discards) one or more rows, false if + no row is produced. + + + + + UPDATE, INSERT, and DELETE + statements set FOUND true if at least one + row is affected, false if no row is affected. + + + + + A FETCH statement sets FOUND + true if it returns a row, false if no row is returned. + + + + + A MOVE statement sets FOUND + true if it successfully repositions the cursor, false otherwise. + + + + + A FOR or FOREACH statement sets + FOUND true + if it iterates one or more times, else false. + FOUND is set this way when the + loop exits; inside the execution of the loop, + FOUND is not modified by the + loop statement, although it might be changed by the + execution of other statements within the loop body. + + + + + RETURN QUERY and RETURN QUERY + EXECUTE statements set FOUND + true if the query returns at least one row, false if no row + is returned. + + + + + Other PL/pgSQL statements do not change + the state of FOUND. + Note in particular that EXECUTE + changes the output of GET DIAGNOSTICS, but + does not change FOUND. + + + + FOUND is a local variable within each + PL/pgSQL function; any changes to it + affect only the current function. + + +
+ + + Doing Nothing At All + + + Sometimes a placeholder statement that does nothing is useful. + For example, it can indicate that one arm of an if/then/else + chain is deliberately empty. For this purpose, use the + NULL statement: + + +NULL; + + + + + For example, the following two fragments of code are equivalent: + +BEGIN + y := x / 0; +EXCEPTION + WHEN division_by_zero THEN + NULL; -- ignore the error +END; + + + +BEGIN + y := x / 0; +EXCEPTION + WHEN division_by_zero THEN -- ignore the error +END; + + Which is preferable is a matter of taste. + + + + + In Oracle's PL/SQL, empty statement lists are not allowed, and so + NULL statements are required for situations + such as this. PL/pgSQL allows you to + just write nothing, instead. + + + + +
+ + + Control Structures + + + Control structures are probably the most useful (and + important) part of PL/pgSQL. With + PL/pgSQL's control structures, + you can manipulate PostgreSQL data in a very + flexible and powerful way. + + + + Returning from a Function + + + There are two commands available that allow you to return data + from a function: RETURN and RETURN + NEXT. + + + + <command>RETURN</command> + + +RETURN expression; + + + + RETURN with an expression terminates the + function and returns the value of + expression to the caller. This form + is used for PL/pgSQL functions that do + not return a set. + + + + In a function that returns a scalar type, the expression's result will + automatically be cast into the function's return type as described for + assignments. But to return a composite (row) value, you must write an + expression delivering exactly the requested column set. This may + require use of explicit casting. + + + + If you declared the function with output parameters, write just + RETURN with no expression. The current values + of the output parameter variables will be returned. + + + + If you declared the function to return void, a + RETURN statement can be used to exit the function + early; but do not write an expression following + RETURN. + + + + The return value of a function cannot be left undefined. If + control reaches the end of the top-level block of the function + without hitting a RETURN statement, a run-time + error will occur. This restriction does not apply to functions + with output parameters and functions returning void, + however. In those cases a RETURN statement is + automatically executed if the top-level block finishes. + + + + Some examples: + + +-- functions returning a scalar type +RETURN 1 + 2; +RETURN scalar_var; + +-- functions returning a composite type +RETURN composite_type_var; +RETURN (1, 2, 'three'::text); -- must cast columns to correct types + + + + + + <command>RETURN NEXT</command> and <command>RETURN QUERY</command> + + RETURN NEXT + in PL/pgSQL + + + RETURN QUERY + in PL/pgSQL + + + +RETURN NEXT expression; +RETURN QUERY query; +RETURN QUERY EXECUTE command-string USING expression , ... ; + + + + When a PL/pgSQL function is declared to return + SETOF sometype, the procedure + to follow is slightly different. In that case, the individual + items to return are specified by a sequence of RETURN + NEXT or RETURN QUERY commands, and + then a final RETURN command with no argument + is used to indicate that the function has finished executing. + RETURN NEXT can be used with both scalar and + composite data types; with a composite result type, an entire + table of results will be returned. + RETURN QUERY appends the results of executing + a query to the function's result set. RETURN + NEXT and RETURN QUERY can be freely + intermixed in a single set-returning function, in which case + their results will be concatenated. + + + + RETURN NEXT and RETURN + QUERY do not actually return from the function — + they simply append zero or more rows to the function's result + set. Execution then continues with the next statement in the + PL/pgSQL function. As successive + RETURN NEXT or RETURN + QUERY commands are executed, the result set is built + up. A final RETURN, which should have no + argument, causes control to exit the function (or you can just + let control reach the end of the function). + + + + RETURN QUERY has a variant + RETURN QUERY EXECUTE, which specifies the + query to be executed dynamically. Parameter expressions can + be inserted into the computed query string via USING, + in just the same way as in the EXECUTE command. + + + + If you declared the function with output parameters, write just + RETURN NEXT with no expression. On each + execution, the current values of the output parameter + variable(s) will be saved for eventual return as a row of the + result. Note that you must declare the function as returning + SETOF record when there are multiple output + parameters, or SETOF sometype + when there is just one output parameter of type + sometype, in order to create a set-returning + function with output parameters. + + + + Here is an example of a function using RETURN + NEXT: + + +CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT); +INSERT INTO foo VALUES (1, 2, 'three'); +INSERT INTO foo VALUES (4, 5, 'six'); + +CREATE OR REPLACE FUNCTION get_all_foo() RETURNS SETOF foo AS +$BODY$ +DECLARE + r foo%rowtype; +BEGIN + FOR r IN + SELECT * FROM foo WHERE fooid > 0 + LOOP + -- can do some processing here + RETURN NEXT r; -- return current row of SELECT + END LOOP; + RETURN; +END; +$BODY$ +LANGUAGE plpgsql; + +SELECT * FROM get_all_foo(); + + + + + Here is an example of a function using RETURN + QUERY: + + +CREATE FUNCTION get_available_flightid(date) RETURNS SETOF integer AS +$BODY$ +BEGIN + RETURN QUERY SELECT flightid + FROM flight + WHERE flightdate >= $1 + AND flightdate < ($1 + 1); + + -- Since execution is not finished, we can check whether rows were returned + -- and raise exception if not. + IF NOT FOUND THEN + RAISE EXCEPTION 'No flight at %.', $1; + END IF; + + RETURN; + END; +$BODY$ +LANGUAGE plpgsql; + +-- Returns available flights or raises exception if there are no +-- available flights. +SELECT * FROM get_available_flightid(CURRENT_DATE); + + + + + + The current implementation of RETURN NEXT + and RETURN QUERY stores the entire result set + before returning from the function, as discussed above. That + means that if a PL/pgSQL function produces a + very large result set, performance might be poor: data will be + written to disk to avoid memory exhaustion, but the function + itself will not return until the entire result set has been + generated. A future version of PL/pgSQL might + allow users to define set-returning functions + that do not have this limitation. Currently, the point at + which data begins being written to disk is controlled by the + + configuration variable. Administrators who have sufficient + memory to store larger result sets in memory should consider + increasing this parameter. + + + + + + + Returning from a Procedure + + + A procedure does not have a return value. A procedure can therefore end + without a RETURN statement. If you wish to use + a RETURN statement to exit the code early, write + just RETURN with no expression. + + + + If the procedure has output parameters, the final values of the output + parameter variables will be returned to the caller. + + + + + Calling a Procedure + + + A PL/pgSQL function, procedure, + or DO block can call a procedure + using CALL. Output parameters are handled + differently from the way that CALL works in plain + SQL. Each OUT or INOUT + parameter of the procedure must + correspond to a variable in the CALL statement, and + whatever the procedure returns is assigned back to that variable after + it returns. For example: + +CREATE PROCEDURE triple(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x * 3; +END; +$$; + +DO $$ +DECLARE myvar int := 5; +BEGIN + CALL triple(myvar); + RAISE NOTICE 'myvar = %', myvar; -- prints 15 +END; +$$; + + The variable corresponding to an output parameter can be a simple + variable or a field of a composite-type variable. Currently, + it cannot be an element of an array. + + + + + Conditionals + + + IF and CASE statements let you execute + alternative commands based on certain conditions. + PL/pgSQL has three forms of IF: + + + IF ... THEN ... END IF + + + IF ... THEN ... ELSE ... END IF + + + IF ... THEN ... ELSIF ... THEN ... ELSE ... END IF + + + + and two forms of CASE: + + + CASE ... WHEN ... THEN ... ELSE ... END CASE + + + CASE WHEN ... THEN ... ELSE ... END CASE + + + + + + <literal>IF-THEN</literal> + + +IF boolean-expression THEN + statements +END IF; + + + + IF-THEN statements are the simplest form of + IF. The statements between + THEN and END IF will be + executed if the condition is true. Otherwise, they are + skipped. + + + + Example: + +IF v_user_id <> 0 THEN + UPDATE users SET email = v_email WHERE user_id = v_user_id; +END IF; + + + + + + <literal>IF-THEN-ELSE</literal> + + +IF boolean-expression THEN + statements +ELSE + statements +END IF; + + + + IF-THEN-ELSE statements add to + IF-THEN by letting you specify an + alternative set of statements that should be executed if the + condition is not true. (Note this includes the case where the + condition evaluates to NULL.) + + + + Examples: + +IF parentid IS NULL OR parentid = '' +THEN + RETURN fullname; +ELSE + RETURN hp_true_filename(parentid) || '/' || fullname; +END IF; + + + +IF v_count > 0 THEN + INSERT INTO users_count (count) VALUES (v_count); + RETURN 't'; +ELSE + RETURN 'f'; +END IF; + + + + + + <literal>IF-THEN-ELSIF</literal> + + +IF boolean-expression THEN + statements + ELSIF boolean-expression THEN + statements + ELSIF boolean-expression THEN + statements + ... + + + ELSE + statements +END IF; + + + + Sometimes there are more than just two alternatives. + IF-THEN-ELSIF provides a convenient + method of checking several alternatives in turn. + The IF conditions are tested successively + until the first one that is true is found. Then the + associated statement(s) are executed, after which control + passes to the next statement after END IF. + (Any subsequent IF conditions are not + tested.) If none of the IF conditions is true, + then the ELSE block (if any) is executed. + + + + Here is an example: + + +IF number = 0 THEN + result := 'zero'; +ELSIF number > 0 THEN + result := 'positive'; +ELSIF number < 0 THEN + result := 'negative'; +ELSE + -- hmm, the only other possibility is that number is null + result := 'NULL'; +END IF; + + + + + The key word ELSIF can also be spelled + ELSEIF. + + + + An alternative way of accomplishing the same task is to nest + IF-THEN-ELSE statements, as in the + following example: + + +IF demo_row.sex = 'm' THEN + pretty_sex := 'man'; +ELSE + IF demo_row.sex = 'f' THEN + pretty_sex := 'woman'; + END IF; +END IF; + + + + + However, this method requires writing a matching END IF + for each IF, so it is much more cumbersome than + using ELSIF when there are many alternatives. + + + + + Simple <literal>CASE</literal> + + +CASE search-expression + WHEN expression , expression ... THEN + statements + WHEN expression , expression ... THEN + statements + ... + ELSE + statements +END CASE; + + + + The simple form of CASE provides conditional execution + based on equality of operands. The search-expression + is evaluated (once) and successively compared to each + expression in the WHEN clauses. + If a match is found, then the corresponding + statements are executed, and then control + passes to the next statement after END CASE. (Subsequent + WHEN expressions are not evaluated.) If no match is + found, the ELSE statements are + executed; but if ELSE is not present, then a + CASE_NOT_FOUND exception is raised. + + + + Here is a simple example: + + +CASE x + WHEN 1, 2 THEN + msg := 'one or two'; + ELSE + msg := 'other value than one or two'; +END CASE; + + + + + + Searched <literal>CASE</literal> + + +CASE + WHEN boolean-expression THEN + statements + WHEN boolean-expression THEN + statements + ... + ELSE + statements +END CASE; + + + + The searched form of CASE provides conditional execution + based on truth of Boolean expressions. Each WHEN clause's + boolean-expression is evaluated in turn, + until one is found that yields true. Then the + corresponding statements are executed, and + then control passes to the next statement after END CASE. + (Subsequent WHEN expressions are not evaluated.) + If no true result is found, the ELSE + statements are executed; + but if ELSE is not present, then a + CASE_NOT_FOUND exception is raised. + + + + Here is an example: + + +CASE + WHEN x BETWEEN 0 AND 10 THEN + msg := 'value is between zero and ten'; + WHEN x BETWEEN 11 AND 20 THEN + msg := 'value is between eleven and twenty'; +END CASE; + + + + + This form of CASE is entirely equivalent to + IF-THEN-ELSIF, except for the rule that reaching + an omitted ELSE clause results in an error rather + than doing nothing. + + + + + + + Simple Loops + + + loop + in PL/pgSQL + + + + With the LOOP, EXIT, + CONTINUE, WHILE, FOR, + and FOREACH statements, you can arrange for your + PL/pgSQL function to repeat a series of commands. + + + + <literal>LOOP</literal> + + + <<label>> +LOOP + statements +END LOOP label ; + + + + LOOP defines an unconditional loop that is repeated + indefinitely until terminated by an EXIT or + RETURN statement. The optional + label can be used by EXIT + and CONTINUE statements within nested loops to + specify which loop those statements refer to. + + + + + <literal>EXIT</literal> + + + EXIT + in PL/pgSQL + + + +EXIT label WHEN boolean-expression ; + + + + If no label is given, the innermost + loop is terminated and the statement following END + LOOP is executed next. If label + is given, it must be the label of the current or some outer + level of nested loop or block. Then the named loop or block is + terminated and control continues with the statement after the + loop's/block's corresponding END. + + + + If WHEN is specified, the loop exit occurs only if + boolean-expression is true. Otherwise, control passes + to the statement after EXIT. + + + + EXIT can be used with all types of loops; it is + not limited to use with unconditional loops. + + + + When used with a + BEGIN block, EXIT passes + control to the next statement after the end of the block. + Note that a label must be used for this purpose; an unlabeled + EXIT is never considered to match a + BEGIN block. (This is a change from + pre-8.4 releases of PostgreSQL, which + would allow an unlabeled EXIT to match + a BEGIN block.) + + + + Examples: + +LOOP + -- some computations + IF count > 0 THEN + EXIT; -- exit loop + END IF; +END LOOP; + +LOOP + -- some computations + EXIT WHEN count > 0; -- same result as previous example +END LOOP; + +<<ablock>> +BEGIN + -- some computations + IF stocks > 100000 THEN + EXIT ablock; -- causes exit from the BEGIN block + END IF; + -- computations here will be skipped when stocks > 100000 +END; + + + + + + <literal>CONTINUE</literal> + + + CONTINUE + in PL/pgSQL + + + +CONTINUE label WHEN boolean-expression ; + + + + If no label is given, the next iteration of + the innermost loop is begun. That is, all statements remaining + in the loop body are skipped, and control returns + to the loop control expression (if any) to determine whether + another loop iteration is needed. + If label is present, it + specifies the label of the loop whose execution will be + continued. + + + + If WHEN is specified, the next iteration of the + loop is begun only if boolean-expression is + true. Otherwise, control passes to the statement after + CONTINUE. + + + + CONTINUE can be used with all types of loops; it + is not limited to use with unconditional loops. + + + + Examples: + +LOOP + -- some computations + EXIT WHEN count > 100; + CONTINUE WHEN count < 50; + -- some computations for count IN [50 .. 100] +END LOOP; + + + + + + + <literal>WHILE</literal> + + + WHILE + in PL/pgSQL + + + + <<label>> +WHILE boolean-expression LOOP + statements +END LOOP label ; + + + + The WHILE statement repeats a + sequence of statements so long as the + boolean-expression + evaluates to true. The expression is checked just before + each entry to the loop body. + + + + For example: + +WHILE amount_owed > 0 AND gift_certificate_balance > 0 LOOP + -- some computations here +END LOOP; + +WHILE NOT done LOOP + -- some computations here +END LOOP; + + + + + + <literal>FOR</literal> (Integer Variant) + + + <<label>> +FOR name IN REVERSE expression .. expression BY expression LOOP + statements +END LOOP label ; + + + + This form of FOR creates a loop that iterates over a range + of integer values. The variable + name is automatically defined as type + integer and exists only inside the loop (any existing + definition of the variable name is ignored within the loop). + The two expressions giving + the lower and upper bound of the range are evaluated once when entering + the loop. If the BY clause isn't specified the iteration + step is 1, otherwise it's the value specified in the BY + clause, which again is evaluated once on loop entry. + If REVERSE is specified then the step value is + subtracted, rather than added, after each iteration. + + + + Some examples of integer FOR loops: + +FOR i IN 1..10 LOOP + -- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop +END LOOP; + +FOR i IN REVERSE 10..1 LOOP + -- i will take on the values 10,9,8,7,6,5,4,3,2,1 within the loop +END LOOP; + +FOR i IN REVERSE 10..1 BY 2 LOOP + -- i will take on the values 10,8,6,4,2 within the loop +END LOOP; + + + + + If the lower bound is greater than the upper bound (or less than, + in the REVERSE case), the loop body is not + executed at all. No error is raised. + + + + If a label is attached to the + FOR loop then the integer loop variable can be + referenced with a qualified name, using that + label. + + + + + + Looping through Query Results + + + Using a different type of FOR loop, you can iterate through + the results of a query and manipulate that data + accordingly. The syntax is: + + <<label>> +FOR target IN query LOOP + statements +END LOOP label ; + + The target is a record variable, row variable, + or comma-separated list of scalar variables. + The target is successively assigned each row + resulting from the query and the loop body is + executed for each row. Here is an example: + +CREATE FUNCTION refresh_mviews() RETURNS integer AS $$ +DECLARE + mviews RECORD; +BEGIN + RAISE NOTICE 'Refreshing all materialized views...'; + + FOR mviews IN + SELECT n.nspname AS mv_schema, + c.relname AS mv_name, + pg_catalog.pg_get_userbyid(c.relowner) AS owner + FROM pg_catalog.pg_class c + LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace) + WHERE c.relkind = 'm' + ORDER BY 1 + LOOP + + -- Now "mviews" has one record with information about the materialized view + + RAISE NOTICE 'Refreshing materialized view %.% (owner: %)...', + quote_ident(mviews.mv_schema), + quote_ident(mviews.mv_name), + quote_ident(mviews.owner); + EXECUTE format('REFRESH MATERIALIZED VIEW %I.%I', mviews.mv_schema, mviews.mv_name); + END LOOP; + + RAISE NOTICE 'Done refreshing materialized views.'; + RETURN 1; +END; +$$ LANGUAGE plpgsql; + + + If the loop is terminated by an EXIT statement, the last + assigned row value is still accessible after the loop. + + + + The query used in this type of FOR + statement can be any SQL command that returns rows to the caller: + SELECT is the most common case, + but you can also use INSERT, UPDATE, or + DELETE with a RETURNING clause. Some utility + commands such as EXPLAIN will work too. + + + + PL/pgSQL variables are replaced by query parameters, + and the query plan is cached for possible re-use, as discussed in + detail in and + . + + + + The FOR-IN-EXECUTE statement is another way to iterate over + rows: + + <<label>> +FOR target IN EXECUTE text_expression USING expression , ... LOOP + statements +END LOOP label ; + + This is like the previous form, except that the source query + is specified as a string expression, which is evaluated and replanned + on each entry to the FOR loop. This allows the programmer to + choose the speed of a preplanned query or the flexibility of a dynamic + query, just as with a plain EXECUTE statement. + As with EXECUTE, parameter values can be inserted + into the dynamic command via USING. + + + + Another way to specify the query whose results should be iterated + through is to declare it as a cursor. This is described in + . + + + + + Looping through Arrays + + + The FOREACH loop is much like a FOR loop, + but instead of iterating through the rows returned by an SQL query, + it iterates through the elements of an array value. + (In general, FOREACH is meant for looping through + components of a composite-valued expression; variants for looping + through composites besides arrays may be added in future.) + The FOREACH statement to loop over an array is: + + + <<label>> +FOREACH target SLICE number IN ARRAY expression LOOP + statements +END LOOP label ; + + + + + Without SLICE, or if SLICE 0 is specified, + the loop iterates through individual elements of the array produced + by evaluating the expression. + The target variable is assigned each + element value in sequence, and the loop body is executed for each element. + Here is an example of looping through the elements of an integer + array: + + +CREATE FUNCTION sum(int[]) RETURNS int8 AS $$ +DECLARE + s int8 := 0; + x int; +BEGIN + FOREACH x IN ARRAY $1 + LOOP + s := s + x; + END LOOP; + RETURN s; +END; +$$ LANGUAGE plpgsql; + + + The elements are visited in storage order, regardless of the number of + array dimensions. Although the target is + usually just a single variable, it can be a list of variables when + looping through an array of composite values (records). In that case, + for each array element, the variables are assigned from successive + columns of the composite value. + + + + With a positive SLICE value, FOREACH + iterates through slices of the array rather than single elements. + The SLICE value must be an integer constant not larger + than the number of dimensions of the array. The + target variable must be an array, + and it receives successive slices of the array value, where each slice + is of the number of dimensions specified by SLICE. + Here is an example of iterating through one-dimensional slices: + + +CREATE FUNCTION scan_rows(int[]) RETURNS void AS $$ +DECLARE + x int[]; +BEGIN + FOREACH x SLICE 1 IN ARRAY $1 + LOOP + RAISE NOTICE 'row = %', x; + END LOOP; +END; +$$ LANGUAGE plpgsql; + +SELECT scan_rows(ARRAY[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]); + +NOTICE: row = {1,2,3} +NOTICE: row = {4,5,6} +NOTICE: row = {7,8,9} +NOTICE: row = {10,11,12} + + + + + + Trapping Errors + + + exceptions + in PL/pgSQL + + + + By default, any error occurring in a PL/pgSQL + function aborts execution of the function and the + surrounding transaction. You can trap errors and recover + from them by using a BEGIN block with an + EXCEPTION clause. The syntax is an extension of the + normal syntax for a BEGIN block: + + + <<label>> + DECLARE + declarations +BEGIN + statements +EXCEPTION + WHEN condition OR condition ... THEN + handler_statements + WHEN condition OR condition ... THEN + handler_statements + ... +END; + + + + + If no error occurs, this form of block simply executes all the + statements, and then control passes + to the next statement after END. But if an error + occurs within the statements, further + processing of the statements is + abandoned, and control passes to the EXCEPTION list. + The list is searched for the first condition + matching the error that occurred. If a match is found, the + corresponding handler_statements are + executed, and then control passes to the next statement after + END. If no match is found, the error propagates out + as though the EXCEPTION clause were not there at all: + the error can be caught by an enclosing block with + EXCEPTION, or if there is none it aborts processing + of the function. + + + + The condition names can be any of + those shown in . A category + name matches any error within its category. The special + condition name OTHERS matches every error type except + QUERY_CANCELED and ASSERT_FAILURE. + (It is possible, but often unwise, to trap those two error types + by name.) Condition names are + not case-sensitive. Also, an error condition can be specified + by SQLSTATE code; for example these are equivalent: + +WHEN division_by_zero THEN ... +WHEN SQLSTATE '22012' THEN ... + + + + + If a new error occurs within the selected + handler_statements, it cannot be caught + by this EXCEPTION clause, but is propagated out. + A surrounding EXCEPTION clause could catch it. + + + + When an error is caught by an EXCEPTION clause, + the local variables of the PL/pgSQL function + remain as they were when the error occurred, but all changes + to persistent database state within the block are rolled back. + As an example, consider this fragment: + + +INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones'); +BEGIN + UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones'; + x := x + 1; + y := x / 0; +EXCEPTION + WHEN division_by_zero THEN + RAISE NOTICE 'caught division_by_zero'; + RETURN x; +END; + + + When control reaches the assignment to y, it will + fail with a division_by_zero error. This will be caught by + the EXCEPTION clause. The value returned in the + RETURN statement will be the incremented value of + x, but the effects of the UPDATE command will + have been rolled back. The INSERT command preceding the + block is not rolled back, however, so the end result is that the database + contains Tom Jones not Joe Jones. + + + + + A block containing an EXCEPTION clause is significantly + more expensive to enter and exit than a block without one. Therefore, + don't use EXCEPTION without need. + + + + + Exceptions with <command>UPDATE</command>/<command>INSERT</command> + + + This example uses exception handling to perform either + UPDATE or INSERT, as appropriate. It is + recommended that applications use INSERT with + ON CONFLICT DO UPDATE rather than actually using + this pattern. This example serves primarily to illustrate use of + PL/pgSQL control flow structures: + + +CREATE TABLE db (a INT PRIMARY KEY, b TEXT); + +CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS +$$ +BEGIN + LOOP + -- first try to update the key + UPDATE db SET b = data WHERE a = key; + IF found THEN + RETURN; + END IF; + -- not there, so try to insert the key + -- if someone else inserts the same key concurrently, + -- we could get a unique-key failure + BEGIN + INSERT INTO db(a,b) VALUES (key, data); + RETURN; + EXCEPTION WHEN unique_violation THEN + -- Do nothing, and loop to try the UPDATE again. + END; + END LOOP; +END; +$$ +LANGUAGE plpgsql; + +SELECT merge_db(1, 'david'); +SELECT merge_db(1, 'dennis'); + + + This coding assumes the unique_violation error is caused by + the INSERT, and not by, say, an INSERT in a + trigger function on the table. It might also misbehave if there is + more than one unique index on the table, since it will retry the + operation regardless of which index caused the error. + More safety could be had by using the + features discussed next to check that the trapped error was the one + expected. + + + + + Obtaining Information about an Error + + + Exception handlers frequently need to identify the specific error that + occurred. There are two ways to get information about the current + exception in PL/pgSQL: special variables and the + GET STACKED DIAGNOSTICS command. + + + + Within an exception handler, the special variable + SQLSTATE contains the error code that corresponds to + the exception that was raised (refer to + for a list of possible error codes). The special variable + SQLERRM contains the error message associated with the + exception. These variables are undefined outside exception handlers. + + + + Within an exception handler, one may also retrieve + information about the current exception by using the + GET STACKED DIAGNOSTICS command, which has the form: + + +GET STACKED DIAGNOSTICS variable { = | := } item , ... ; + + + Each item is a key word identifying a status + value to be assigned to the specified variable + (which should be of the right data type to receive it). The currently + available status items are shown + in . + + + + Error Diagnostics Items + + + + + + + Name + Type + Description + + + + + RETURNED_SQLSTATE + text + the SQLSTATE error code of the exception + + + COLUMN_NAME + text + the name of the column related to exception + + + CONSTRAINT_NAME + text + the name of the constraint related to exception + + + PG_DATATYPE_NAME + text + the name of the data type related to exception + + + MESSAGE_TEXT + text + the text of the exception's primary message + + + TABLE_NAME + text + the name of the table related to exception + + + SCHEMA_NAME + text + the name of the schema related to exception + + + PG_EXCEPTION_DETAIL + text + the text of the exception's detail message, if any + + + PG_EXCEPTION_HINT + text + the text of the exception's hint message, if any + + + PG_EXCEPTION_CONTEXT + text + line(s) of text describing the call stack at the time of the + exception (see ) + + + +
+ + + If the exception did not set a value for an item, an empty string + will be returned. + + + + Here is an example: + +DECLARE + text_var1 text; + text_var2 text; + text_var3 text; +BEGIN + -- some processing which might cause an exception + ... +EXCEPTION WHEN OTHERS THEN + GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT, + text_var2 = PG_EXCEPTION_DETAIL, + text_var3 = PG_EXCEPTION_HINT; +END; + + +
+
+ + + Obtaining Execution Location Information + + + The GET DIAGNOSTICS command, previously described + in , retrieves information + about current execution state (whereas the GET STACKED + DIAGNOSTICS command discussed above reports information about + the execution state as of a previous error). Its PG_CONTEXT + status item is useful for identifying the current execution + location. PG_CONTEXT returns a text string with line(s) + of text describing the call stack. The first line refers to the current + function and currently executing GET DIAGNOSTICS + command. The second and any subsequent lines refer to calling functions + further up the call stack. For example: + + +CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$ +BEGIN + RETURN inner_func(); +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION inner_func() RETURNS integer AS $$ +DECLARE + stack text; +BEGIN + GET DIAGNOSTICS stack = PG_CONTEXT; + RAISE NOTICE E'--- Call Stack ---\n%', stack; + RETURN 1; +END; +$$ LANGUAGE plpgsql; + +SELECT outer_func(); + +NOTICE: --- Call Stack --- +PL/pgSQL function inner_func() line 5 at GET DIAGNOSTICS +PL/pgSQL function outer_func() line 3 at RETURN +CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN + outer_func + ------------ + 1 +(1 row) + + + + + + GET STACKED DIAGNOSTICS ... PG_EXCEPTION_CONTEXT + returns the same sort of stack trace, but describing the location + at which an error was detected, rather than the current location. + + +
+ + + Cursors + + + cursor + in PL/pgSQL + + + + Rather than executing a whole query at once, it is possible to set + up a cursor that encapsulates the query, and then read + the query result a few rows at a time. One reason for doing this is + to avoid memory overrun when the result contains a large number of + rows. (However, PL/pgSQL users do not normally need + to worry about that, since FOR loops automatically use a cursor + internally to avoid memory problems.) A more interesting usage is to + return a reference to a cursor that a function has created, allowing the + caller to read the rows. This provides an efficient way to return + large row sets from functions. + + + + Declaring Cursor Variables + + + All access to cursors in PL/pgSQL goes through + cursor variables, which are always of the special data type + refcursor. One way to create a cursor variable + is just to declare it as a variable of type refcursor. + Another way is to use the cursor declaration syntax, + which in general is: + +name NO SCROLL CURSOR ( arguments ) FOR query; + + (FOR can be replaced by IS for + Oracle compatibility.) + If SCROLL is specified, the cursor will be capable of + scrolling backward; if NO SCROLL is specified, backward + fetches will be rejected; if neither specification appears, it is + query-dependent whether backward fetches will be allowed. + arguments, if specified, is a + comma-separated list of pairs name + datatype that define names to be + replaced by parameter values in the given query. The actual + values to substitute for these names will be specified later, + when the cursor is opened. + + + Some examples: + +DECLARE + curs1 refcursor; + curs2 CURSOR FOR SELECT * FROM tenk1; + curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key; + + All three of these variables have the data type refcursor, + but the first can be used with any query, while the second has + a fully specified query already bound to it, and the last + has a parameterized query bound to it. (key will be + replaced by an integer parameter value when the cursor is opened.) + The variable curs1 + is said to be unbound since it is not bound to + any particular query. + + + + The SCROLL option cannot be used when the cursor's + query uses FOR UPDATE/SHARE. Also, it is + best to use NO SCROLL with a query that involves + volatile functions. The implementation of SCROLL + assumes that re-reading the query's output will give consistent + results, which a volatile function might not do. + + + + + Opening Cursors + + + Before a cursor can be used to retrieve rows, it must be + opened. (This is the equivalent action to the SQL + command DECLARE CURSOR.) PL/pgSQL has + three forms of the OPEN statement, two of which use unbound + cursor variables while the third uses a bound cursor variable. + + + + + Bound cursor variables can also be used without explicitly opening the cursor, + via the FOR statement described in + . + + + + + <command>OPEN FOR</command> <replaceable>query</replaceable> + + +OPEN unbound_cursorvar NO SCROLL FOR query; + + + + The cursor variable is opened and given the specified query to + execute. The cursor cannot be open already, and it must have been + declared as an unbound cursor variable (that is, as a simple + refcursor variable). The query must be a + SELECT, or something else that returns rows + (such as EXPLAIN). The query + is treated in the same way as other SQL commands in + PL/pgSQL: PL/pgSQL + variable names are substituted, and the query plan is cached for + possible reuse. When a PL/pgSQL + variable is substituted into the cursor query, the value that is + substituted is the one it has at the time of the OPEN; + subsequent changes to the variable will not affect the cursor's + behavior. + The SCROLL and NO SCROLL + options have the same meanings as for a bound cursor. + + + + An example: + +OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey; + + + + + + <command>OPEN FOR EXECUTE</command> + + +OPEN unbound_cursorvar NO SCROLL FOR EXECUTE query_string + USING expression , ... ; + + + + The cursor variable is opened and given the specified query to + execute. The cursor cannot be open already, and it must have been + declared as an unbound cursor variable (that is, as a simple + refcursor variable). The query is specified as a string + expression, in the same way as in the EXECUTE + command. As usual, this gives flexibility so the query plan can vary + from one run to the next (see ), + and it also means that variable substitution is not done on the + command string. As with EXECUTE, parameter values + can be inserted into the dynamic command via + format() and USING. + The SCROLL and + NO SCROLL options have the same meanings as for a bound + cursor. + + + + An example: + +OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING keyvalue; + + In this example, the table name is inserted into the query via + format(). The comparison value for col1 + is inserted via a USING parameter, so it needs + no quoting. + + + + + Opening a Bound Cursor + + +OPEN bound_cursorvar ( argument_name := argument_value , ... ) ; + + + + This form of OPEN is used to open a cursor + variable whose query was bound to it when it was declared. The + cursor cannot be open already. A list of actual argument value + expressions must appear if and only if the cursor was declared to + take arguments. These values will be substituted in the query. + + + + The query plan for a bound cursor is always considered cacheable; + there is no equivalent of EXECUTE in this case. + Notice that SCROLL and NO SCROLL cannot be + specified in OPEN, as the cursor's scrolling + behavior was already determined. + + + + Argument values can be passed using either positional + or named notation. In positional + notation, all arguments are specified in order. In named notation, + each argument's name is specified using := to + separate it from the argument expression. Similar to calling + functions, described in , it + is also allowed to mix positional and named notation. + + + + Examples (these use the cursor declaration examples above): + +OPEN curs2; +OPEN curs3(42); +OPEN curs3(key := 42); + + + + + Because variable substitution is done on a bound cursor's query, + there are really two ways to pass values into the cursor: either + with an explicit argument to OPEN, or implicitly by + referencing a PL/pgSQL variable in the query. + However, only variables declared before the bound cursor was + declared will be substituted into it. In either case the value to + be passed is determined at the time of the OPEN. + For example, another way to get the same effect as the + curs3 example above is + +DECLARE + key integer; + curs4 CURSOR FOR SELECT * FROM tenk1 WHERE unique1 = key; +BEGIN + key := 42; + OPEN curs4; + + + + + + + Using Cursors + + + Once a cursor has been opened, it can be manipulated with the + statements described here. + + + + These manipulations need not occur in the same function that + opened the cursor to begin with. You can return a refcursor + value out of a function and let the caller operate on the cursor. + (Internally, a refcursor value is simply the string name + of a so-called portal containing the active query for the cursor. This name + can be passed around, assigned to other refcursor variables, + and so on, without disturbing the portal.) + + + + All portals are implicitly closed at transaction end. Therefore + a refcursor value is usable to reference an open cursor + only until the end of the transaction. + + + + <literal>FETCH</literal> + + +FETCH direction { FROM | IN } cursor INTO target; + + + + FETCH retrieves the next row from the + cursor into a target, which might be a row variable, a record + variable, or a comma-separated list of simple variables, just like + SELECT INTO. If there is no next row, the + target is set to NULL(s). As with SELECT + INTO, the special variable FOUND can + be checked to see whether a row was obtained or not. + + + + The direction clause can be any of the + variants allowed in the SQL + command except the ones that can fetch + more than one row; namely, it can be + NEXT, + PRIOR, + FIRST, + LAST, + ABSOLUTE count, + RELATIVE count, + FORWARD, or + BACKWARD. + Omitting direction is the same + as specifying NEXT. + In the forms using a count, + the count can be any integer-valued + expression (unlike the SQL FETCH command, + which only allows an integer constant). + direction values that require moving + backward are likely to fail unless the cursor was declared or opened + with the SCROLL option. + + + + cursor must be the name of a refcursor + variable that references an open cursor portal. + + + + Examples: + +FETCH curs1 INTO rowvar; +FETCH curs2 INTO foo, bar, baz; +FETCH LAST FROM curs3 INTO x, y; +FETCH RELATIVE -2 FROM curs4 INTO x; + + + + + + <literal>MOVE</literal> + + +MOVE direction { FROM | IN } cursor; + + + + MOVE repositions a cursor without retrieving + any data. MOVE works exactly like the + FETCH command, except it only repositions the + cursor and does not return the row moved to. As with SELECT + INTO, the special variable FOUND can + be checked to see whether there was a next row to move to. + + + + Examples: + +MOVE curs1; +MOVE LAST FROM curs3; +MOVE RELATIVE -2 FROM curs4; +MOVE FORWARD 2 FROM curs4; + + + + + + <literal>UPDATE/DELETE WHERE CURRENT OF</literal> + + +UPDATE table SET ... WHERE CURRENT OF cursor; +DELETE FROM table WHERE CURRENT OF cursor; + + + + When a cursor is positioned on a table row, that row can be updated + or deleted using the cursor to identify the row. There are + restrictions on what the cursor's query can be (in particular, + no grouping) and it's best to use FOR UPDATE in the + cursor. For more information see the + + reference page. + + + + An example: + +UPDATE foo SET dataval = myval WHERE CURRENT OF curs1; + + + + + + <literal>CLOSE</literal> + + +CLOSE cursor; + + + + CLOSE closes the portal underlying an open + cursor. This can be used to release resources earlier than end of + transaction, or to free up the cursor variable to be opened again. + + + + An example: + +CLOSE curs1; + + + + + + Returning Cursors + + + PL/pgSQL functions can return cursors to the + caller. This is useful to return multiple rows or columns, + especially with very large result sets. To do this, the function + opens the cursor and returns the cursor name to the caller (or simply + opens the cursor using a portal name specified by or otherwise known + to the caller). The caller can then fetch rows from the cursor. The + cursor can be closed by the caller, or it will be closed automatically + when the transaction closes. + + + + The portal name used for a cursor can be specified by the + programmer or automatically generated. To specify a portal name, + simply assign a string to the refcursor variable before + opening it. The string value of the refcursor variable + will be used by OPEN as the name of the underlying portal. + However, if the refcursor variable is null, + OPEN automatically generates a name that does not + conflict with any existing portal, and assigns it to the + refcursor variable. + + + + + A bound cursor variable is initialized to the string value + representing its name, so that the portal name is the same as + the cursor variable name, unless the programmer overrides it + by assignment before opening the cursor. But an unbound cursor + variable defaults to the null value initially, so it will receive + an automatically-generated unique name, unless overridden. + + + + + The following example shows one way a cursor name can be supplied by + the caller: + + +CREATE TABLE test (col text); +INSERT INTO test VALUES ('123'); + +CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS ' +BEGIN + OPEN $1 FOR SELECT col FROM test; + RETURN $1; +END; +' LANGUAGE plpgsql; + +BEGIN; +SELECT reffunc('funccursor'); +FETCH ALL IN funccursor; +COMMIT; + + + + + The following example uses automatic cursor name generation: + + +CREATE FUNCTION reffunc2() RETURNS refcursor AS ' +DECLARE + ref refcursor; +BEGIN + OPEN ref FOR SELECT col FROM test; + RETURN ref; +END; +' LANGUAGE plpgsql; + +-- need to be in a transaction to use cursors. +BEGIN; +SELECT reffunc2(); + + reffunc2 +-------------------- + <unnamed cursor 1> +(1 row) + +FETCH ALL IN "<unnamed cursor 1>"; +COMMIT; + + + + + The following example shows one way to return multiple cursors + from a single function: + + +CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$ +BEGIN + OPEN $1 FOR SELECT * FROM table_1; + RETURN NEXT $1; + OPEN $2 FOR SELECT * FROM table_2; + RETURN NEXT $2; +END; +$$ LANGUAGE plpgsql; + +-- need to be in a transaction to use cursors. +BEGIN; + +SELECT * FROM myfunc('a', 'b'); + +FETCH ALL FROM a; +FETCH ALL FROM b; +COMMIT; + + + + + + + Looping through a Cursor's Result + + + There is a variant of the FOR statement that allows + iterating through the rows returned by a cursor. The syntax is: + + + <<label>> +FOR recordvar IN bound_cursorvar ( argument_name := argument_value , ... ) LOOP + statements +END LOOP label ; + + + The cursor variable must have been bound to some query when it was + declared, and it cannot be open already. The + FOR statement automatically opens the cursor, and it closes + the cursor again when the loop exits. A list of actual argument value + expressions must appear if and only if the cursor was declared to take + arguments. These values will be substituted in the query, in just + the same way as during an OPEN (see ). + + + + The variable recordvar is automatically + defined as type record and exists only inside the loop (any + existing definition of the variable name is ignored within the loop). + Each row returned by the cursor is successively assigned to this + record variable and the loop body is executed. + + + + + + + Transaction Management + + + In procedures invoked by the CALL command + as well as in anonymous code blocks (DO command), + it is possible to end transactions using the + commands COMMIT and ROLLBACK. A new + transaction is started automatically after a transaction is ended using + these commands, so there is no separate START + TRANSACTION command. (Note that BEGIN and + END have different meanings in PL/pgSQL.) + + + + Here is a simple example: + +CREATE PROCEDURE transaction_test1() +LANGUAGE plpgsql +AS $$ +BEGIN + FOR i IN 0..9 LOOP + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT; + ELSE + ROLLBACK; + END IF; + END LOOP; +END; +$$; + +CALL transaction_test1(); + + + + + chained transactions + in PL/pgSQL + + + + A new transaction starts out with default transaction characteristics such + as transaction isolation level. In cases where transactions are committed + in a loop, it might be desirable to start new transactions automatically + with the same characteristics as the previous one. The commands + COMMIT AND CHAIN and ROLLBACK AND + CHAIN accomplish this. + + + + Transaction control is only possible in CALL or + DO invocations from the top level or nested + CALL or DO invocations without any + other intervening command. For example, if the call stack is + CALL proc1()CALL proc2() + → CALL proc3(), then the second and third + procedures can perform transaction control actions. But if the call stack + is CALL proc1()SELECT + func2()CALL proc3(), then the last + procedure cannot do transaction control, because of the + SELECT in between. + + + + Special considerations apply to cursor loops. Consider this example: + +CREATE PROCEDURE transaction_test2() +LANGUAGE plpgsql +AS $$ +DECLARE + r RECORD; +BEGIN + FOR r IN SELECT * FROM test2 ORDER BY x LOOP + INSERT INTO test1 (a) VALUES (r.x); + COMMIT; + END LOOP; +END; +$$; + +CALL transaction_test2(); + + Normally, cursors are automatically closed at transaction commit. + However, a cursor created as part of a loop like this is automatically + converted to a holdable cursor by the first COMMIT or + ROLLBACK. That means that the cursor is fully + evaluated at the first COMMIT or + ROLLBACK rather than row by row. The cursor is still + removed automatically after the loop, so this is mostly invisible to the + user. + + + + Transaction commands are not allowed in cursor loops driven by commands + that are not read-only (for example UPDATE + ... RETURNING). + + + + A transaction cannot be ended inside a block with exception handlers. + + + + + Errors and Messages + + + Reporting Errors and Messages + + + RAISE + in PL/pgSQL + + + + reporting errors + in PL/pgSQL + + + + Use the RAISE statement to report messages and + raise errors. + + +RAISE level 'format' , expression , ... USING option = expression , ... ; +RAISE level condition_name USING option = expression , ... ; +RAISE level SQLSTATE 'sqlstate' USING option = expression , ... ; +RAISE level USING option = expression , ... ; +RAISE ; + + + The level option specifies + the error severity. Allowed levels are DEBUG, + LOG, INFO, + NOTICE, WARNING, + and EXCEPTION, with EXCEPTION + being the default. + EXCEPTION raises an error (which normally aborts the + current transaction); the other levels only generate messages of different + priority levels. + Whether messages of a particular priority are reported to the client, + written to the server log, or both is controlled by the + and + configuration + variables. See for more + information. + + + + After level if any, + you can write a format + (which must be a simple string literal, not an expression). The + format string specifies the error message text to be reported. + The format string can be followed + by optional argument expressions to be inserted into the message. + Inside the format string, % is replaced by the + string representation of the next optional argument's value. Write + %% to emit a literal %. + The number of arguments must match the number of % + placeholders in the format string, or an error is raised during + the compilation of the function. + + + + In this example, the value of v_job_id will replace the + % in the string: + +RAISE NOTICE 'Calling cs_create_job(%)', v_job_id; + + + + + You can attach additional information to the error report by writing + USING followed by option = expression items. Each + expression can be any + string-valued expression. The allowed option key words are: + + + + MESSAGE + + Sets the error message text. This option can't be used in the + form of RAISE that includes a format string + before USING. + + + + + DETAIL + + Supplies an error detail message. + + + + + HINT + + Supplies a hint message. + + + + + ERRCODE + + Specifies the error code (SQLSTATE) to report, either by condition + name, as shown in , or directly as a + five-character SQLSTATE code. + + + + + COLUMN + CONSTRAINT + DATATYPE + TABLE + SCHEMA + + Supplies the name of a related object. + + + + + + + This example will abort the transaction with the given error message + and hint: + +RAISE EXCEPTION 'Nonexistent ID --> %', user_id + USING HINT = 'Please check your user ID'; + + + + + These two examples show equivalent ways of setting the SQLSTATE: + +RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation'; +RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505'; + + + + + There is a second RAISE syntax in which the main argument + is the condition name or SQLSTATE to be reported, for example: + +RAISE division_by_zero; +RAISE SQLSTATE '22012'; + + In this syntax, USING can be used to supply a custom + error message, detail, or hint. Another way to do the earlier + example is + +RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; + + + + + Still another variant is to write RAISE USING or RAISE + level USING and put + everything else into the USING list. + + + + The last variant of RAISE has no parameters at all. + This form can only be used inside a BEGIN block's + EXCEPTION clause; + it causes the error currently being handled to be re-thrown. + + + + + Before PostgreSQL 9.1, RAISE without + parameters was interpreted as re-throwing the error from the block + containing the active exception handler. Thus an EXCEPTION + clause nested within that handler could not catch it, even if the + RAISE was within the nested EXCEPTION clause's + block. This was deemed surprising as well as being incompatible with + Oracle's PL/SQL. + + + + + If no condition name nor SQLSTATE is specified in a + RAISE EXCEPTION command, the default is to use + ERRCODE_RAISE_EXCEPTION (P0001). + If no message text is specified, the default is to use the condition + name or SQLSTATE as message text. + + + + + When specifying an error code by SQLSTATE code, you are not + limited to the predefined error codes, but can select any + error code consisting of five digits and/or upper-case ASCII + letters, other than 00000. It is recommended that + you avoid throwing error codes that end in three zeroes, because + these are category codes and can only be trapped by trapping + the whole category. + + + + + + + Checking Assertions + + + ASSERT + in PL/pgSQL + + + + assertions + in PL/pgSQL + + + + plpgsql.check_asserts configuration parameter + + + + The ASSERT statement is a convenient shorthand for + inserting debugging checks into PL/pgSQL + functions. + + +ASSERT condition , message ; + + + The condition is a Boolean + expression that is expected to always evaluate to true; if it does, + the ASSERT statement does nothing further. If the + result is false or null, then an ASSERT_FAILURE exception + is raised. (If an error occurs while evaluating + the condition, it is + reported as a normal error.) + + + + If the optional message is + provided, it is an expression whose result (if not null) replaces the + default error message text assertion failed, should + the condition fail. + The message expression is + not evaluated in the normal case where the assertion succeeds. + + + + Testing of assertions can be enabled or disabled via the configuration + parameter plpgsql.check_asserts, which takes a Boolean + value; the default is on. If this parameter + is off then ASSERT statements do nothing. + + + + Note that ASSERT is meant for detecting program + bugs, not for reporting ordinary error conditions. Use + the RAISE statement, described above, for that. + + + + + + + + Trigger Functions + + + trigger + in PL/pgSQL + + + + PL/pgSQL can be used to define trigger + functions on data changes or database events. + A trigger function is created with the CREATE FUNCTION + command, declaring it as a function with no arguments and a return type of + trigger (for data change triggers) or + event_trigger (for database event triggers). + Special local variables named TG_something are + automatically defined to describe the condition that triggered the call. + + + + Triggers on Data Changes + + + A data change trigger is declared as a + function with no arguments and a return type of trigger. + Note that the function must be declared with no arguments even if it + expects to receive some arguments specified in CREATE TRIGGER + — such arguments are passed via TG_ARGV, as described + below. + + + + When a PL/pgSQL function is called as a + trigger, several special variables are created automatically in the + top-level block. They are: + + + + NEW + + + Data type RECORD; variable holding the new + database row for INSERT/UPDATE operations in row-level + triggers. This variable is null in statement-level triggers + and for DELETE operations. + + + + + + OLD + + + Data type RECORD; variable holding the old + database row for UPDATE/DELETE operations in row-level + triggers. This variable is null in statement-level triggers + and for INSERT operations. + + + + + + TG_NAME + + + Data type name; variable that contains the name of the trigger actually + fired. + + + + + + TG_WHEN + + + Data type text; a string of + BEFORE, AFTER, or + INSTEAD OF, depending on the trigger's definition. + + + + + + TG_LEVEL + + + Data type text; a string of either + ROW or STATEMENT + depending on the trigger's definition. + + + + + + TG_OP + + + Data type text; a string of + INSERT, UPDATE, + DELETE, or TRUNCATE + telling for which operation the trigger was fired. + + + + + + TG_RELID + + + Data type oid; the object ID of the table that caused the + trigger invocation. + + + + + + TG_RELNAME + + + Data type name; the name of the table that caused the trigger + invocation. This is now deprecated, and could disappear in a future + release. Use TG_TABLE_NAME instead. + + + + + + TG_TABLE_NAME + + + Data type name; the name of the table that + caused the trigger invocation. + + + + + + TG_TABLE_SCHEMA + + + Data type name; the name of the schema of the + table that caused the trigger invocation. + + + + + + TG_NARGS + + + Data type integer; the number of arguments given to the trigger + function in the CREATE TRIGGER statement. + + + + + + TG_ARGV[] + + + Data type array of text; the arguments from + the CREATE TRIGGER statement. + The index counts from 0. Invalid + indexes (less than 0 or greater than or equal to tg_nargs) + result in a null value. + + + + + + + + A trigger function must return either NULL or a + record/row value having exactly the structure of the table the + trigger was fired for. + + + + Row-level triggers fired BEFORE can return null to signal the + trigger manager to skip the rest of the operation for this row + (i.e., subsequent triggers are not fired, and the + INSERT/UPDATE/DELETE does not occur + for this row). If a nonnull + value is returned then the operation proceeds with that row value. + Returning a row value different from the original value + of NEW alters the row that will be inserted or + updated. Thus, if the trigger function wants the triggering + action to succeed normally without altering the row + value, NEW (or a value equal thereto) has to be + returned. To alter the row to be stored, it is possible to + replace single values directly in NEW and return the + modified NEW, or to build a complete new record/row to + return. In the case of a before-trigger + on DELETE, the returned value has no direct + effect, but it has to be nonnull to allow the trigger action to + proceed. Note that NEW is null + in DELETE triggers, so returning that is + usually not sensible. The usual idiom in DELETE + triggers is to return OLD. + + + + INSTEAD OF triggers (which are always row-level triggers, + and may only be used on views) can return null to signal that they did + not perform any updates, and that the rest of the operation for this + row should be skipped (i.e., subsequent triggers are not fired, and the + row is not counted in the rows-affected status for the surrounding + INSERT/UPDATE/DELETE). + Otherwise a nonnull value should be returned, to signal + that the trigger performed the requested operation. For + INSERT and UPDATE operations, the return value + should be NEW, which the trigger function may modify to + support INSERT RETURNING and UPDATE RETURNING + (this will also affect the row value passed to any subsequent triggers, + or passed to a special EXCLUDED alias reference within + an INSERT statement with an ON CONFLICT DO + UPDATE clause). For DELETE operations, the return + value should be OLD. + + + + The return value of a row-level trigger + fired AFTER or a statement-level trigger + fired BEFORE or AFTER is + always ignored; it might as well be null. However, any of these types of + triggers might still abort the entire operation by raising an error. + + + + shows an example of a + trigger function in PL/pgSQL. + + + + A <application>PL/pgSQL</application> Trigger Function + + + This example trigger ensures that any time a row is inserted or updated + in the table, the current user name and time are stamped into the + row. And it checks that an employee's name is given and that the + salary is a positive value. + + + +CREATE TABLE emp ( + empname text, + salary integer, + last_date timestamp, + last_user text +); + +CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$ + BEGIN + -- Check that empname and salary are given + IF NEW.empname IS NULL THEN + RAISE EXCEPTION 'empname cannot be null'; + END IF; + IF NEW.salary IS NULL THEN + RAISE EXCEPTION '% cannot have null salary', NEW.empname; + END IF; + + -- Who works for us when they must pay for it? + IF NEW.salary < 0 THEN + RAISE EXCEPTION '% cannot have a negative salary', NEW.empname; + END IF; + + -- Remember who changed the payroll when + NEW.last_date := current_timestamp; + NEW.last_user := current_user; + RETURN NEW; + END; +$emp_stamp$ LANGUAGE plpgsql; + +CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp + FOR EACH ROW EXECUTE FUNCTION emp_stamp(); + + + + + Another way to log changes to a table involves creating a new table that + holds a row for each insert, update, or delete that occurs. This approach + can be thought of as auditing changes to a table. + shows an example of an + audit trigger function in PL/pgSQL. + + + + A <application>PL/pgSQL</application> Trigger Function for Auditing + + + This example trigger ensures that any insert, update or delete of a row + in the emp table is recorded (i.e., audited) in the emp_audit table. + The current time and user name are stamped into the row, together with + the type of operation performed on it. + + + +CREATE TABLE emp ( + empname text NOT NULL, + salary integer +); + +CREATE TABLE emp_audit( + operation char(1) NOT NULL, + stamp timestamp NOT NULL, + userid text NOT NULL, + empname text NOT NULL, + salary integer +); + +CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$ + BEGIN + -- + -- Create a row in emp_audit to reflect the operation performed on emp, + -- making use of the special variable TG_OP to work out the operation. + -- + IF (TG_OP = 'DELETE') THEN + INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*; + ELSIF (TG_OP = 'UPDATE') THEN + INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*; + END IF; + RETURN NULL; -- result is ignored since this is an AFTER trigger + END; +$emp_audit$ LANGUAGE plpgsql; + +CREATE TRIGGER emp_audit +AFTER INSERT OR UPDATE OR DELETE ON emp + FOR EACH ROW EXECUTE FUNCTION process_emp_audit(); + + + + + A variation of the previous example uses a view joining the main table + to the audit table, to show when each entry was last modified. This + approach still records the full audit trail of changes to the table, + but also presents a simplified view of the audit trail, showing just + the last modified timestamp derived from the audit trail for each entry. + shows an example + of an audit trigger on a view in PL/pgSQL. + + + + A <application>PL/pgSQL</application> View Trigger Function for Auditing + + + This example uses a trigger on the view to make it updatable, and + ensure that any insert, update or delete of a row in the view is + recorded (i.e., audited) in the emp_audit table. The current time + and user name are recorded, together with the type of operation + performed, and the view displays the last modified time of each row. + + + +CREATE TABLE emp ( + empname text PRIMARY KEY, + salary integer +); + +CREATE TABLE emp_audit( + operation char(1) NOT NULL, + userid text NOT NULL, + empname text NOT NULL, + salary integer, + stamp timestamp NOT NULL +); + +CREATE VIEW emp_view AS + SELECT e.empname, + e.salary, + max(ea.stamp) AS last_updated + FROM emp e + LEFT JOIN emp_audit ea ON ea.empname = e.empname + GROUP BY 1, 2; + +CREATE OR REPLACE FUNCTION update_emp_view() RETURNS TRIGGER AS $$ + BEGIN + -- + -- Perform the required operation on emp, and create a row in emp_audit + -- to reflect the change made to emp. + -- + IF (TG_OP = 'DELETE') THEN + DELETE FROM emp WHERE empname = OLD.empname; + IF NOT FOUND THEN RETURN NULL; END IF; + + OLD.last_updated = now(); + INSERT INTO emp_audit VALUES('D', user, OLD.*); + RETURN OLD; + ELSIF (TG_OP = 'UPDATE') THEN + UPDATE emp SET salary = NEW.salary WHERE empname = OLD.empname; + IF NOT FOUND THEN RETURN NULL; END IF; + + NEW.last_updated = now(); + INSERT INTO emp_audit VALUES('U', user, NEW.*); + RETURN NEW; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO emp VALUES(NEW.empname, NEW.salary); + + NEW.last_updated = now(); + INSERT INTO emp_audit VALUES('I', user, NEW.*); + RETURN NEW; + END IF; + END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER emp_audit +INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view + FOR EACH ROW EXECUTE FUNCTION update_emp_view(); + + + + + One use of triggers is to maintain a summary table + of another table. The resulting summary can be used in place of the + original table for certain queries — often with vastly reduced run + times. + This technique is commonly used in Data Warehousing, where the tables + of measured or observed data (called fact tables) might be extremely large. + shows an example of a + trigger function in PL/pgSQL that maintains + a summary table for a fact table in a data warehouse. + + + + + A <application>PL/pgSQL</application> Trigger Function for Maintaining a Summary Table + + + The schema detailed here is partly based on the Grocery Store + example from The Data Warehouse Toolkit + by Ralph Kimball. + + + +-- +-- Main tables - time dimension and sales fact. +-- +CREATE TABLE time_dimension ( + time_key integer NOT NULL, + day_of_week integer NOT NULL, + day_of_month integer NOT NULL, + month integer NOT NULL, + quarter integer NOT NULL, + year integer NOT NULL +); +CREATE UNIQUE INDEX time_dimension_key ON time_dimension(time_key); + +CREATE TABLE sales_fact ( + time_key integer NOT NULL, + product_key integer NOT NULL, + store_key integer NOT NULL, + amount_sold numeric(12,2) NOT NULL, + units_sold integer NOT NULL, + amount_cost numeric(12,2) NOT NULL +); +CREATE INDEX sales_fact_time ON sales_fact(time_key); + +-- +-- Summary table - sales by time. +-- +CREATE TABLE sales_summary_bytime ( + time_key integer NOT NULL, + amount_sold numeric(15,2) NOT NULL, + units_sold numeric(12) NOT NULL, + amount_cost numeric(15,2) NOT NULL +); +CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key); + +-- +-- Function and trigger to amend summarized column(s) on UPDATE, INSERT, DELETE. +-- +CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER +AS $maint_sales_summary_bytime$ + DECLARE + delta_time_key integer; + delta_amount_sold numeric(15,2); + delta_units_sold numeric(12); + delta_amount_cost numeric(15,2); + BEGIN + + -- Work out the increment/decrement amount(s). + IF (TG_OP = 'DELETE') THEN + + delta_time_key = OLD.time_key; + delta_amount_sold = -1 * OLD.amount_sold; + delta_units_sold = -1 * OLD.units_sold; + delta_amount_cost = -1 * OLD.amount_cost; + + ELSIF (TG_OP = 'UPDATE') THEN + + -- forbid updates that change the time_key - + -- (probably not too onerous, as DELETE + INSERT is how most + -- changes will be made). + IF ( OLD.time_key != NEW.time_key) THEN + RAISE EXCEPTION 'Update of time_key : % -> % not allowed', + OLD.time_key, NEW.time_key; + END IF; + + delta_time_key = OLD.time_key; + delta_amount_sold = NEW.amount_sold - OLD.amount_sold; + delta_units_sold = NEW.units_sold - OLD.units_sold; + delta_amount_cost = NEW.amount_cost - OLD.amount_cost; + + ELSIF (TG_OP = 'INSERT') THEN + + delta_time_key = NEW.time_key; + delta_amount_sold = NEW.amount_sold; + delta_units_sold = NEW.units_sold; + delta_amount_cost = NEW.amount_cost; + + END IF; + + + -- Insert or update the summary row with the new values. + <<insert_update>> + LOOP + UPDATE sales_summary_bytime + SET amount_sold = amount_sold + delta_amount_sold, + units_sold = units_sold + delta_units_sold, + amount_cost = amount_cost + delta_amount_cost + WHERE time_key = delta_time_key; + + EXIT insert_update WHEN found; + + BEGIN + INSERT INTO sales_summary_bytime ( + time_key, + amount_sold, + units_sold, + amount_cost) + VALUES ( + delta_time_key, + delta_amount_sold, + delta_units_sold, + delta_amount_cost + ); + + EXIT insert_update; + + EXCEPTION + WHEN UNIQUE_VIOLATION THEN + -- do nothing + END; + END LOOP insert_update; + + RETURN NULL; + + END; +$maint_sales_summary_bytime$ LANGUAGE plpgsql; + +CREATE TRIGGER maint_sales_summary_bytime +AFTER INSERT OR UPDATE OR DELETE ON sales_fact + FOR EACH ROW EXECUTE FUNCTION maint_sales_summary_bytime(); + +INSERT INTO sales_fact VALUES(1,1,1,10,3,15); +INSERT INTO sales_fact VALUES(1,2,1,20,5,35); +INSERT INTO sales_fact VALUES(2,2,1,40,15,135); +INSERT INTO sales_fact VALUES(2,3,1,10,1,13); +SELECT * FROM sales_summary_bytime; +DELETE FROM sales_fact WHERE product_key = 1; +SELECT * FROM sales_summary_bytime; +UPDATE sales_fact SET units_sold = units_sold * 2; +SELECT * FROM sales_summary_bytime; + + + + + AFTER triggers can also make use of transition + tables to inspect the entire set of rows changed by the triggering + statement. The CREATE TRIGGER command assigns names to one + or both transition tables, and then the function can refer to those names + as though they were read-only temporary tables. + shows an example. + + + + Auditing with Transition Tables + + + This example produces the same results as + , but instead of using a + trigger that fires for every row, it uses a trigger that fires once + per statement, after collecting the relevant information in a transition + table. This can be significantly faster than the row-trigger approach + when the invoking statement has modified many rows. Notice that we must + make a separate trigger declaration for each kind of event, since the + REFERENCING clauses must be different for each case. But + this does not stop us from using a single trigger function if we choose. + (In practice, it might be better to use three separate functions and + avoid the run-time tests on TG_OP.) + + + +CREATE TABLE emp ( + empname text NOT NULL, + salary integer +); + +CREATE TABLE emp_audit( + operation char(1) NOT NULL, + stamp timestamp NOT NULL, + userid text NOT NULL, + empname text NOT NULL, + salary integer +); + +CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$ + BEGIN + -- + -- Create rows in emp_audit to reflect the operations performed on emp, + -- making use of the special variable TG_OP to work out the operation. + -- + IF (TG_OP = 'DELETE') THEN + INSERT INTO emp_audit + SELECT 'D', now(), user, o.* FROM old_table o; + ELSIF (TG_OP = 'UPDATE') THEN + INSERT INTO emp_audit + SELECT 'U', now(), user, n.* FROM new_table n; + ELSIF (TG_OP = 'INSERT') THEN + INSERT INTO emp_audit + SELECT 'I', now(), user, n.* FROM new_table n; + END IF; + RETURN NULL; -- result is ignored since this is an AFTER trigger + END; +$emp_audit$ LANGUAGE plpgsql; + +CREATE TRIGGER emp_audit_ins + AFTER INSERT ON emp + REFERENCING NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit(); +CREATE TRIGGER emp_audit_upd + AFTER UPDATE ON emp + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit(); +CREATE TRIGGER emp_audit_del + AFTER DELETE ON emp + REFERENCING OLD TABLE AS old_table + FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit(); + + + + + + + Triggers on Events + + + PL/pgSQL can be used to define + event triggers. + PostgreSQL requires that a function that + is to be called as an event trigger must be declared as a function with + no arguments and a return type of event_trigger. + + + + When a PL/pgSQL function is called as an + event trigger, several special variables are created automatically + in the top-level block. They are: + + + + TG_EVENT + + + Data type text; a string representing the event the + trigger is fired for. + + + + + + TG_TAG + + + Data type text; variable that contains the command tag + for which the trigger is fired. + + + + + + + + shows an example of an + event trigger function in PL/pgSQL. + + + + A <application>PL/pgSQL</application> Event Trigger Function + + + This example trigger simply raises a NOTICE message + each time a supported command is executed. + + + +CREATE OR REPLACE FUNCTION snitch() RETURNS event_trigger AS $$ +BEGIN + RAISE NOTICE 'snitch: % %', tg_event, tg_tag; +END; +$$ LANGUAGE plpgsql; + +CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); + + + + + + + + <application>PL/pgSQL</application> under the Hood + + + This section discusses some implementation details that are + frequently important for PL/pgSQL users to know. + + + + Variable Substitution + + + SQL statements and expressions within a PL/pgSQL function + can refer to variables and parameters of the function. Behind the scenes, + PL/pgSQL substitutes query parameters for such references. + Query parameters will only be substituted in places where they are + syntactically permissible. As an extreme case, consider + this example of poor programming style: + +INSERT INTO foo (foo) VALUES (foo(foo)); + + The first occurrence of foo must syntactically be a table + name, so it will not be substituted, even if the function has a variable + named foo. The second occurrence must be the name of a + column of that table, so it will not be substituted either. Likewise + the third occurrence must be a function name, so it also will not be + substituted for. Only the last occurrence is a candidate to be a + reference to a variable of the PL/pgSQL + function. + + + + Another way to understand this is that variable substitution can only + insert data values into an SQL command; it cannot dynamically change which + database objects are referenced by the command. (If you want to do + that, you must build a command string dynamically, as explained in + .) + + + + Since the names of variables are syntactically no different from the names + of table columns, there can be ambiguity in statements that also refer to + tables: is a given name meant to refer to a table column, or a variable? + Let's change the previous example to + +INSERT INTO dest (col) SELECT foo + bar FROM src; + + Here, dest and src must be table names, and + col must be a column of dest, but foo + and bar might reasonably be either variables of the function + or columns of src. + + + + By default, PL/pgSQL will report an error if a name + in an SQL statement could refer to either a variable or a table column. + You can fix such a problem by renaming the variable or column, + or by qualifying the ambiguous reference, or by telling + PL/pgSQL which interpretation to prefer. + + + + The simplest solution is to rename the variable or column. + A common coding rule is to use a + different naming convention for PL/pgSQL + variables than you use for column names. For example, + if you consistently name function variables + v_something while none of your + column names start with v_, no conflicts will occur. + + + + Alternatively you can qualify ambiguous references to make them clear. + In the above example, src.foo would be an unambiguous reference + to the table column. To create an unambiguous reference to a variable, + declare it in a labeled block and use the block's label + (see ). For example, + +<<block>> +DECLARE + foo int; +BEGIN + foo := ...; + INSERT INTO dest (col) SELECT block.foo + bar FROM src; + + Here block.foo means the variable even if there is a column + foo in src. Function parameters, as well as + special variables such as FOUND, can be qualified by the + function's name, because they are implicitly declared in an outer block + labeled with the function's name. + + + + Sometimes it is impractical to fix all the ambiguous references in a + large body of PL/pgSQL code. In such cases you can + specify that PL/pgSQL should resolve ambiguous references + as the variable (which is compatible with PL/pgSQL's + behavior before PostgreSQL 9.0), or as the + table column (which is compatible with some other systems such as + Oracle). + + + + plpgsql.variable_conflict configuration parameter + + + + To change this behavior on a system-wide basis, set the configuration + parameter plpgsql.variable_conflict to one of + error, use_variable, or + use_column (where error is the factory default). + This parameter affects subsequent compilations + of statements in PL/pgSQL functions, but not statements + already compiled in the current session. + Because changing this setting + can cause unexpected changes in the behavior of PL/pgSQL + functions, it can only be changed by a superuser. + + + + You can also set the behavior on a function-by-function basis, by + inserting one of these special commands at the start of the function + text: + +#variable_conflict error +#variable_conflict use_variable +#variable_conflict use_column + + These commands affect only the function they are written in, and override + the setting of plpgsql.variable_conflict. An example is + +CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ + #variable_conflict use_variable + DECLARE + curtime timestamp := now(); + BEGIN + UPDATE users SET last_modified = curtime, comment = comment + WHERE users.id = id; + END; +$$ LANGUAGE plpgsql; + + In the UPDATE command, curtime, comment, + and id will refer to the function's variable and parameters + whether or not users has columns of those names. Notice + that we had to qualify the reference to users.id in the + WHERE clause to make it refer to the table column. + But we did not have to qualify the reference to comment + as a target in the UPDATE list, because syntactically + that must be a column of users. We could write the same + function without depending on the variable_conflict setting + in this way: + +CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$ + <<fn>> + DECLARE + curtime timestamp := now(); + BEGIN + UPDATE users SET last_modified = fn.curtime, comment = stamp_user.comment + WHERE users.id = stamp_user.id; + END; +$$ LANGUAGE plpgsql; + + + + + Variable substitution does not happen in a command string given + to EXECUTE or one of its variants. If you need to + insert a varying value into such a command, do so as part of + constructing the string value, or use USING, as illustrated in + . + + + + Variable substitution currently works only in SELECT, + INSERT, UPDATE, + DELETE, and commands containing one of + these (such as EXPLAIN and CREATE TABLE + ... AS SELECT), + because the main SQL engine allows query parameters only in these + commands. To use a non-constant name or value in other statement + types (generically called utility statements), you must construct + the utility statement as a string and EXECUTE it. + + + + + + Plan Caching + + + The PL/pgSQL interpreter parses the function's source + text and produces an internal binary instruction tree the first time the + function is called (within each session). The instruction tree + fully translates the + PL/pgSQL statement structure, but individual + SQL expressions and SQL commands + used in the function are not translated immediately. + + + + + preparing a query + in PL/pgSQL + + As each expression and SQL command is first + executed in the function, the PL/pgSQL interpreter + parses and analyzes the command to create a prepared statement, + using the SPI manager's + SPI_prepare function. + Subsequent visits to that expression or command + reuse the prepared statement. Thus, a function with conditional code + paths that are seldom visited will never incur the overhead of + analyzing those commands that are never executed within the current + session. A disadvantage is that errors + in a specific expression or command cannot be detected until that + part of the function is reached in execution. (Trivial syntax + errors will be detected during the initial parsing pass, but + anything deeper will not be detected until execution.) + + + + PL/pgSQL (or more precisely, the SPI manager) can + furthermore attempt to cache the execution plan associated with any + particular prepared statement. If a cached plan is not used, then + a fresh execution plan is generated on each visit to the statement, + and the current parameter values (that is, PL/pgSQL + variable values) can be used to optimize the selected plan. If the + statement has no parameters, or is executed many times, the SPI manager + will consider creating a generic plan that is not dependent + on specific parameter values, and caching that for re-use. Typically + this will happen only if the execution plan is not very sensitive to + the values of the PL/pgSQL variables referenced in it. + If it is, generating a plan each time is a net win. See for more information about the behavior of + prepared statements. + + + + Because PL/pgSQL saves prepared statements + and sometimes execution plans in this way, + SQL commands that appear directly in a + PL/pgSQL function must refer to the + same tables and columns on every execution; that is, you cannot use + a parameter as the name of a table or column in an SQL command. To get + around this restriction, you can construct dynamic commands using + the PL/pgSQL EXECUTE + statement — at the price of performing new parse analysis and + constructing a new execution plan on every execution. + + + + The mutable nature of record variables presents another problem in this + connection. When fields of a record variable are used in + expressions or statements, the data types of the fields must not + change from one call of the function to the next, since each + expression will be analyzed using the data type that is present + when the expression is first reached. EXECUTE can be + used to get around this problem when necessary. + + + + If the same function is used as a trigger for more than one table, + PL/pgSQL prepares and caches statements + independently for each such table — that is, there is a cache + for each trigger function and table combination, not just for each + function. This alleviates some of the problems with varying + data types; for instance, a trigger function will be able to work + successfully with a column named key even if it happens + to have different types in different tables. + + + + Likewise, functions having polymorphic argument types have a separate + statement cache for each combination of actual argument types they have + been invoked for, so that data type differences do not cause unexpected + failures. + + + + Statement caching can sometimes have surprising effects on the + interpretation of time-sensitive values. For example there + is a difference between what these two functions do: + + +CREATE FUNCTION logfunc1(logtxt text) RETURNS void AS $$ + BEGIN + INSERT INTO logtable VALUES (logtxt, 'now'); + END; +$$ LANGUAGE plpgsql; + + + and: + + +CREATE FUNCTION logfunc2(logtxt text) RETURNS void AS $$ + DECLARE + curtime timestamp; + BEGIN + curtime := 'now'; + INSERT INTO logtable VALUES (logtxt, curtime); + END; +$$ LANGUAGE plpgsql; + + + + + In the case of logfunc1, the + PostgreSQL main parser knows when + analyzing the INSERT that the + string 'now' should be interpreted as + timestamp, because the target column of + logtable is of that type. Thus, + 'now' will be converted to a timestamp + constant when the + INSERT is analyzed, and then used in all + invocations of logfunc1 during the lifetime + of the session. Needless to say, this isn't what the programmer + wanted. A better idea is to use the now() or + current_timestamp function. + + + + In the case of logfunc2, the + PostgreSQL main parser does not know + what type 'now' should become and therefore + it returns a data value of type text containing the string + now. During the ensuing assignment + to the local variable curtime, the + PL/pgSQL interpreter casts this + string to the timestamp type by calling the + textout and timestamp_in + functions for the conversion. So, the computed time stamp is updated + on each execution as the programmer expects. Even though this + happens to work as expected, it's not terribly efficient, so + use of the now() function would still be a better idea. + + + + + + + + Tips for Developing in <application>PL/pgSQL</application> + + + One good way to develop in + PL/pgSQL is to use the text editor of your + choice to create your functions, and in another window, use + psql to load and test those functions. + If you are doing it this way, it + is a good idea to write the function using CREATE OR + REPLACE FUNCTION. That way you can just reload the file to update + the function definition. For example: + +CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $$ + .... +$$ LANGUAGE plpgsql; + + + + + While running psql, you can load or reload such + a function definition file with: + +\i filename.sql + + and then immediately issue SQL commands to test the function. + + + + Another good way to develop in PL/pgSQL is with a + GUI database access tool that facilitates development in a + procedural language. One example of such a tool is + pgAdmin, although others exist. These tools often + provide convenient features such as escaping single quotes and + making it easier to recreate and debug functions. + + + + Handling of Quotation Marks + + + The code of a PL/pgSQL function is specified in + CREATE FUNCTION as a string literal. If you + write the string literal in the ordinary way with surrounding + single quotes, then any single quotes inside the function body + must be doubled; likewise any backslashes must be doubled (assuming + escape string syntax is used). + Doubling quotes is at best tedious, and in more complicated cases + the code can become downright incomprehensible, because you can + easily find yourself needing half a dozen or more adjacent quote marks. + It's recommended that you instead write the function body as a + dollar-quoted string literal (see ). In the dollar-quoting + approach, you never double any quote marks, but instead take care to + choose a different dollar-quoting delimiter for each level of + nesting you need. For example, you might write the CREATE + FUNCTION command as: + +CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$ + .... +$PROC$ LANGUAGE plpgsql; + + Within this, you might use quote marks for simple literal strings in + SQL commands and $$ to delimit fragments of SQL commands + that you are assembling as strings. If you need to quote text that + includes $$, you could use $Q$, and so on. + + + + The following chart shows what you have to do when writing quote + marks without dollar quoting. It might be useful when translating + pre-dollar quoting code into something more comprehensible. + + + + + 1 quotation mark + + + To begin and end the function body, for example: + +CREATE FUNCTION foo() RETURNS integer AS ' + .... +' LANGUAGE plpgsql; + + Anywhere within a single-quoted function body, quote marks + must appear in pairs. + + + + + + 2 quotation marks + + + For string literals inside the function body, for example: + +a_output := ''Blah''; +SELECT * FROM users WHERE f_name=''foobar''; + + In the dollar-quoting approach, you'd just write: + +a_output := 'Blah'; +SELECT * FROM users WHERE f_name='foobar'; + + which is exactly what the PL/pgSQL parser would see + in either case. + + + + + + 4 quotation marks + + + When you need a single quotation mark in a string constant inside the + function body, for example: + +a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz'' + + The value actually appended to a_output would be: + AND name LIKE 'foobar' AND xyz. + + + In the dollar-quoting approach, you'd write: + +a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$ + + being careful that any dollar-quote delimiters around this are not + just $$. + + + + + + 6 quotation marks + + + When a single quotation mark in a string inside the function body is + adjacent to the end of that string constant, for example: + +a_output := a_output || '' AND name LIKE ''''foobar'''''' + + The value appended to a_output would then be: + AND name LIKE 'foobar'. + + + In the dollar-quoting approach, this becomes: + +a_output := a_output || $$ AND name LIKE 'foobar'$$ + + + + + + + 10 quotation marks + + + When you want two single quotation marks in a string constant (which + accounts for 8 quotation marks) and this is adjacent to the end of that + string constant (2 more). You will probably only need that if + you are writing a function that generates other functions, as in + . + For example: + +a_output := a_output || '' if v_'' || + referrer_keys.kind || '' like '''''''''' + || referrer_keys.key_string || '''''''''' + then return '''''' || referrer_keys.referrer_type + || ''''''; end if;''; + + The value of a_output would then be: + +if v_... like ''...'' then return ''...''; end if; + + + + In the dollar-quoting approach, this becomes: + +a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ + || referrer_keys.key_string || $$' + then return '$$ || referrer_keys.referrer_type + || $$'; end if;$$; + + where we assume we only need to put single quote marks into + a_output, because it will be re-quoted before use. + + + + + + + + Additional Compile-Time and Run-Time Checks + + + To aid the user in finding instances of simple but common problems before + they cause harm, PL/pgSQL provides additional + checks. When enabled, depending on the configuration, they + can be used to emit either a WARNING or an ERROR + during the compilation of a function. A function which has received + a WARNING can be executed without producing further messages, + so you are advised to test in a separate development environment. + + + + Setting plpgsql.extra_warnings, or + plpgsql.extra_errors, as appropriate, to "all" + is encouraged in development and/or testing environments. + + + + These additional checks are enabled through the configuration variables + plpgsql.extra_warnings for warnings and + plpgsql.extra_errors for errors. Both can be set either to + a comma-separated list of checks, "none" or + "all". The default is "none". Currently + the list of available checks includes: + + + shadowed_variables + + + Checks if a declaration shadows a previously defined variable. + + + + + + strict_multi_assignment + + + Some PL/PgSQL commands allow assigning + values to more than one variable at a time, such as + SELECT INTO. Typically, the number of target + variables and the number of source variables should match, though + PL/PgSQL will use NULL + for missing values and extra variables are ignored. Enabling this + check will cause PL/PgSQL to throw a + WARNING or ERROR whenever the + number of target variables and the number of source variables are + different. + + + + + + too_many_rows + + + Enabling this check will cause PL/PgSQL to + check if a given query returns more than one row when an + INTO clause is used. As an INTO + statement will only ever use one row, having a query return multiple + rows is generally either inefficient and/or nondeterministic and + therefore is likely an error. + + + + + + The following example shows the effect of plpgsql.extra_warnings + set to shadowed_variables: + +SET plpgsql.extra_warnings TO 'shadowed_variables'; + +CREATE FUNCTION foo(f1 int) RETURNS int AS $$ +DECLARE +f1 int; +BEGIN +RETURN f1; +END; +$$ LANGUAGE plpgsql; +WARNING: variable "f1" shadows a previously defined variable +LINE 3: f1 int; + ^ +CREATE FUNCTION + + The below example shows the effects of setting + plpgsql.extra_warnings to + strict_multi_assignment: + +SET plpgsql.extra_warnings TO 'strict_multi_assignment'; + +CREATE OR REPLACE FUNCTION public.foo() + RETURNS void + LANGUAGE plpgsql +AS $$ +DECLARE + x int; + y int; +BEGIN + SELECT 1 INTO x, y; + SELECT 1, 2 INTO x, y; + SELECT 1, 2, 3 INTO x, y; +END; +$$; + +SELECT foo(); +WARNING: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_warnings is active. +HINT: Make sure the query returns the exact list of columns. +WARNING: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_warnings is active. +HINT: Make sure the query returns the exact list of columns. + + foo +----- + +(1 row) + + + + + + + + + Porting from <productname>Oracle</productname> PL/SQL + + + Oracle + porting from PL/SQL to PL/pgSQL + + + + PL/SQL (Oracle) + porting to PL/pgSQL + + + + This section explains differences between + PostgreSQL's PL/pgSQL + language and Oracle's PL/SQL language, + to help developers who port applications from + Oracle to PostgreSQL. + + + + PL/pgSQL is similar to PL/SQL in many + aspects. It is a block-structured, imperative language, and all + variables have to be declared. Assignments, loops, and conditionals + are similar. The main differences you should keep in mind when + porting from PL/SQL to + PL/pgSQL are: + + + + + If a name used in an SQL command could be either a column name of a + table used in the command or a reference to a variable of the function, + PL/SQL treats it as a column name. + By default, PL/pgSQL will throw an error + complaining that the name is ambiguous. You can specify + plpgsql.variable_conflict = use_column + to change this behavior to match PL/SQL, + as explained in . + It's often best to avoid such ambiguities in the first place, + but if you have to port a large amount of code that depends on + this behavior, setting variable_conflict may be the + best solution. + + + + + + In PostgreSQL the function body must be written as + a string literal. Therefore you need to use dollar quoting or escape + single quotes in the function body. (See .) + + + + + + Data type names often need translation. For example, in Oracle string + values are commonly declared as being of type varchar2, which + is a non-SQL-standard type. In PostgreSQL, + use type varchar or text instead. Similarly, replace + type number with numeric, or use some other numeric + data type if there's a more appropriate one. + + + + + + Instead of packages, use schemas to organize your functions + into groups. + + + + + + Since there are no packages, there are no package-level variables + either. This is somewhat annoying. You can keep per-session state + in temporary tables instead. + + + + + + Integer FOR loops with REVERSE work + differently: PL/SQL counts down from the second + number to the first, while PL/pgSQL counts down + from the first number to the second, requiring the loop bounds + to be swapped when porting. This incompatibility is unfortunate + but is unlikely to be changed. (See .) + + + + + + FOR loops over queries (other than cursors) also work + differently: the target variable(s) must have been declared, + whereas PL/SQL always declares them implicitly. + An advantage of this is that the variable values are still accessible + after the loop exits. + + + + + + There are various notational differences for the use of cursor + variables. + + + + + + + + Porting Examples + + + shows how to port a simple + function from PL/SQL to PL/pgSQL. + + + + Porting a Simple Function from <application>PL/SQL</application> to <application>PL/pgSQL</application> + + + Here is an Oracle PL/SQL function: + +CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar2, + v_version varchar2) +RETURN varchar2 IS +BEGIN + IF v_version IS NULL THEN + RETURN v_name; + END IF; + RETURN v_name || '/' || v_version; +END; +/ +show errors; + + + + + Let's go through this function and see the differences compared to + PL/pgSQL: + + + + + The type name varchar2 has to be changed to varchar + or text. In the examples in this section, we'll + use varchar, but text is often a better choice if + you do not need specific string length limits. + + + + + + The RETURN key word in the function + prototype (not the function body) becomes + RETURNS in + PostgreSQL. + Also, IS becomes AS, and you need to + add a LANGUAGE clause because PL/pgSQL + is not the only possible function language. + + + + + + In PostgreSQL, the function body is considered + to be a string literal, so you need to use quote marks or dollar + quotes around it. This substitutes for the terminating / + in the Oracle approach. + + + + + + The show errors command does not exist in + PostgreSQL, and is not needed since errors are + reported automatically. + + + + + + + This is how this function would look when ported to + PostgreSQL: + + +CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar, + v_version varchar) +RETURNS varchar AS $$ +BEGIN + IF v_version IS NULL THEN + RETURN v_name; + END IF; + RETURN v_name || '/' || v_version; +END; +$$ LANGUAGE plpgsql; + + + + + + shows how to port a + function that creates another function and how to handle the + ensuing quoting problems. + + + + Porting a Function that Creates Another Function from <application>PL/SQL</application> to <application>PL/pgSQL</application> + + + The following procedure grabs rows from a + SELECT statement and builds a large function + with the results in IF statements, for the + sake of efficiency. + + + + This is the Oracle version: + +CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc IS + CURSOR referrer_keys IS + SELECT * FROM cs_referrer_keys + ORDER BY try_order; + func_cmd VARCHAR(4000); +BEGIN + func_cmd := 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host IN VARCHAR2, + v_domain IN VARCHAR2, v_url IN VARCHAR2) RETURN VARCHAR2 IS BEGIN'; + + FOR referrer_key IN referrer_keys LOOP + func_cmd := func_cmd || + ' IF v_' || referrer_key.kind + || ' LIKE ''' || referrer_key.key_string + || ''' THEN RETURN ''' || referrer_key.referrer_type + || '''; END IF;'; + END LOOP; + + func_cmd := func_cmd || ' RETURN NULL; END;'; + + EXECUTE IMMEDIATE func_cmd; +END; +/ +show errors; + + + + + Here is how this function would end up in PostgreSQL: + +CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$ +DECLARE + referrer_keys CURSOR IS + SELECT * FROM cs_referrer_keys + ORDER BY try_order; + func_body text; + func_cmd text; +BEGIN + func_body := 'BEGIN'; + + FOR referrer_key IN referrer_keys LOOP + func_body := func_body || + ' IF v_' || referrer_key.kind + || ' LIKE ' || quote_literal(referrer_key.key_string) + || ' THEN RETURN ' || quote_literal(referrer_key.referrer_type) + || '; END IF;' ; + END LOOP; + + func_body := func_body || ' RETURN NULL; END;'; + + func_cmd := + 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host varchar, + v_domain varchar, + v_url varchar) + RETURNS varchar AS ' + || quote_literal(func_body) + || ' LANGUAGE plpgsql;' ; + + EXECUTE func_cmd; +END; +$func$ LANGUAGE plpgsql; + + Notice how the body of the function is built separately and passed + through quote_literal to double any quote marks in it. This + technique is needed because we cannot safely use dollar quoting for + defining the new function: we do not know for sure what strings will + be interpolated from the referrer_key.key_string field. + (We are assuming here that referrer_key.kind can be + trusted to always be host, domain, or + url, but referrer_key.key_string might be + anything, in particular it might contain dollar signs.) This function + is actually an improvement on the Oracle original, because it will + not generate broken code when referrer_key.key_string or + referrer_key.referrer_type contain quote marks. + + + + + shows how to port a function + with OUT parameters and string manipulation. + PostgreSQL does not have a built-in + instr function, but you can create one + using a combination of other + functions. In there is a + PL/pgSQL implementation of + instr that you can use to make your porting + easier. + + + + Porting a Procedure With String Manipulation and + <literal>OUT</literal> Parameters from <application>PL/SQL</application> to + <application>PL/pgSQL</application> + + + The following Oracle PL/SQL procedure is used + to parse a URL and return several elements (host, path, and query). + + + + This is the Oracle version: + +CREATE OR REPLACE PROCEDURE cs_parse_url( + v_url IN VARCHAR2, + v_host OUT VARCHAR2, -- This will be passed back + v_path OUT VARCHAR2, -- This one too + v_query OUT VARCHAR2) -- And this one +IS + a_pos1 INTEGER; + a_pos2 INTEGER; +BEGIN + v_host := NULL; + v_path := NULL; + v_query := NULL; + a_pos1 := instr(v_url, '//'); + + IF a_pos1 = 0 THEN + RETURN; + END IF; + a_pos2 := instr(v_url, '/', a_pos1 + 2); + IF a_pos2 = 0 THEN + v_host := substr(v_url, a_pos1 + 2); + v_path := '/'; + RETURN; + END IF; + + v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2); + a_pos1 := instr(v_url, '?', a_pos2 + 1); + + IF a_pos1 = 0 THEN + v_path := substr(v_url, a_pos2); + RETURN; + END IF; + + v_path := substr(v_url, a_pos2, a_pos1 - a_pos2); + v_query := substr(v_url, a_pos1 + 1); +END; +/ +show errors; + + + + + Here is a possible translation into PL/pgSQL: + +CREATE OR REPLACE FUNCTION cs_parse_url( + v_url IN VARCHAR, + v_host OUT VARCHAR, -- This will be passed back + v_path OUT VARCHAR, -- This one too + v_query OUT VARCHAR) -- And this one +AS $$ +DECLARE + a_pos1 INTEGER; + a_pos2 INTEGER; +BEGIN + v_host := NULL; + v_path := NULL; + v_query := NULL; + a_pos1 := instr(v_url, '//'); + + IF a_pos1 = 0 THEN + RETURN; + END IF; + a_pos2 := instr(v_url, '/', a_pos1 + 2); + IF a_pos2 = 0 THEN + v_host := substr(v_url, a_pos1 + 2); + v_path := '/'; + RETURN; + END IF; + + v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2); + a_pos1 := instr(v_url, '?', a_pos2 + 1); + + IF a_pos1 = 0 THEN + v_path := substr(v_url, a_pos2); + RETURN; + END IF; + + v_path := substr(v_url, a_pos2, a_pos1 - a_pos2); + v_query := substr(v_url, a_pos1 + 1); +END; +$$ LANGUAGE plpgsql; + + + This function could be used like this: + +SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz'); + + + + + + shows how to port a procedure + that uses numerous features that are specific to Oracle. + + + + Porting a Procedure from <application>PL/SQL</application> to <application>PL/pgSQL</application> + + + The Oracle version: + + +CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS + a_running_job_count INTEGER; +BEGIN + LOCK TABLE cs_jobs IN EXCLUSIVE MODE; + + SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; + + IF a_running_job_count > 0 THEN + COMMIT; -- free lock + raise_application_error(-20000, + 'Unable to create a new job: a job is currently running.'); + END IF; + + DELETE FROM cs_active_job; + INSERT INTO cs_active_job(job_id) VALUES (v_job_id); + + BEGIN + INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); + EXCEPTION + WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists + END; + COMMIT; +END; +/ +show errors + + + + + This is how we could port this procedure to PL/pgSQL: + + +CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$ +DECLARE + a_running_job_count integer; +BEGIN + LOCK TABLE cs_jobs IN EXCLUSIVE MODE; + + SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL; + + IF a_running_job_count > 0 THEN + COMMIT; -- free lock + RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; -- + END IF; + + DELETE FROM cs_active_job; + INSERT INTO cs_active_job(job_id) VALUES (v_job_id); + + BEGIN + INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); + EXCEPTION + WHEN unique_violation THEN -- + -- don't worry if it already exists + END; + COMMIT; +END; +$$ LANGUAGE plpgsql; + + + + + + The syntax of RAISE is considerably different from + Oracle's statement, although the basic case RAISE + exception_name works + similarly. + + + + + The exception names supported by PL/pgSQL are + different from Oracle's. The set of built-in exception names + is much larger (see ). There + is not currently a way to declare user-defined exception names, + although you can throw user-chosen SQLSTATE values instead. + + + + + + + + + Other Things to Watch For + + + This section explains a few other things to watch for when porting + Oracle PL/SQL functions to + PostgreSQL. + + + + Implicit Rollback after Exceptions + + + In PL/pgSQL, when an exception is caught by an + EXCEPTION clause, all database changes since the block's + BEGIN are automatically rolled back. That is, the behavior + is equivalent to what you'd get in Oracle with: + + +BEGIN + SAVEPOINT s1; + ... code here ... +EXCEPTION + WHEN ... THEN + ROLLBACK TO s1; + ... code here ... + WHEN ... THEN + ROLLBACK TO s1; + ... code here ... +END; + + + If you are translating an Oracle procedure that uses + SAVEPOINT and ROLLBACK TO in this style, + your task is easy: just omit the SAVEPOINT and + ROLLBACK TO. If you have a procedure that uses + SAVEPOINT and ROLLBACK TO in a different way + then some actual thought will be required. + + + + + <command>EXECUTE</command> + + + The PL/pgSQL version of + EXECUTE works similarly to the + PL/SQL version, but you have to remember to use + quote_literal and + quote_ident as described in . Constructs of the + type EXECUTE 'SELECT * FROM $1'; will not work + reliably unless you use these functions. + + + + + Optimizing <application>PL/pgSQL</application> Functions + + + PostgreSQL gives you two function creation + modifiers to optimize execution: volatility (whether + the function always returns the same result when given the same + arguments) and strictness (whether the function + returns null if any argument is null). Consult the + reference page for details. + + + + When making use of these optimization attributes, your + CREATE FUNCTION statement might look something + like this: + + +CREATE FUNCTION foo(...) RETURNS integer AS $$ +... +$$ LANGUAGE plpgsql STRICT IMMUTABLE; + + + + + + + Appendix + + + This section contains the code for a set of Oracle-compatible + instr functions that you can use to simplify + your porting efforts. + + + + instr function + + + 0 THEN + temp_str := substring(string FROM beg_index); + pos := position(string_to_search_for IN temp_str); + + IF pos = 0 THEN + RETURN 0; + ELSE + RETURN pos + beg_index - 1; + END IF; + ELSIF beg_index < 0 THEN + ss_length := char_length(string_to_search_for); + length := char_length(string); + beg := length + 1 + beg_index; + + WHILE beg > 0 LOOP + temp_str := substring(string FROM beg FOR ss_length); + IF string_to_search_for = temp_str THEN + RETURN beg; + END IF; + + beg := beg - 1; + END LOOP; + + RETURN 0; + ELSE + RETURN 0; + END IF; +END; +$$ LANGUAGE plpgsql STRICT IMMUTABLE; + + +CREATE FUNCTION instr(string varchar, string_to_search_for varchar, + beg_index integer, occur_index integer) +RETURNS integer AS $$ +DECLARE + pos integer NOT NULL DEFAULT 0; + occur_number integer NOT NULL DEFAULT 0; + temp_str varchar; + beg integer; + i integer; + length integer; + ss_length integer; +BEGIN + IF occur_index <= 0 THEN + RAISE 'argument ''%'' is out of range', occur_index + USING ERRCODE = '22003'; + END IF; + + IF beg_index > 0 THEN + beg := beg_index - 1; + FOR i IN 1..occur_index LOOP + temp_str := substring(string FROM beg + 1); + pos := position(string_to_search_for IN temp_str); + IF pos = 0 THEN + RETURN 0; + END IF; + beg := beg + pos; + END LOOP; + + RETURN beg; + ELSIF beg_index < 0 THEN + ss_length := char_length(string_to_search_for); + length := char_length(string); + beg := length + 1 + beg_index; + + WHILE beg > 0 LOOP + temp_str := substring(string FROM beg FOR ss_length); + IF string_to_search_for = temp_str THEN + occur_number := occur_number + 1; + IF occur_number = occur_index THEN + RETURN beg; + END IF; + END IF; + + beg := beg - 1; + END LOOP; + + RETURN 0; + ELSE + RETURN 0; + END IF; +END; +$$ LANGUAGE plpgsql STRICT IMMUTABLE; +]]> + + + + + +
diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml new file mode 100644 index 000000000000..c2540b8ec9d3 --- /dev/null +++ b/doc/src/sgml/plpython.sgml @@ -0,0 +1,1563 @@ + + + + PL/Python — Python Procedural Language + + PL/Python + Python + + + The PL/Python procedural language allows + PostgreSQL functions and procedures to be written in the + Python language. + + + + To install PL/Python in a particular database, use + CREATE EXTENSION plpythonu (but + see also ). + + + + + If a language is installed into template1, all subsequently + created databases will have the language installed automatically. + + + + + PL/Python is only available as an untrusted language, meaning + it does not offer any way of restricting what users can do in it and + is therefore named plpythonu. A trusted + variant plpython might become available in the future + if a secure execution mechanism is developed in Python. The + writer of a function in untrusted PL/Python must take care that the + function cannot be used to do anything unwanted, since it will be + able to do anything that could be done by a user logged in as the + database administrator. Only superusers can create functions in + untrusted languages such as plpythonu. + + + + + Users of source packages must specially enable the build of + PL/Python during the installation process. (Refer to the + installation instructions for more information.) Users of binary + packages might find PL/Python in a separate subpackage. + + + + + Python 2 vs. Python 3 + + + PL/Python supports both the Python 2 and Python 3 language + variants. (The PostgreSQL installation instructions might contain + more precise information about the exact supported minor versions + of Python.) Because the Python 2 and Python 3 language variants + are incompatible in some important aspects, the following naming + and transitioning scheme is used by PL/Python to avoid mixing them: + + + + + The PostgreSQL language named plpython2u + implements PL/Python based on the Python 2 language variant. + + + + + + The PostgreSQL language named plpython3u + implements PL/Python based on the Python 3 language variant. + + + + + + The language named plpythonu implements + PL/Python based on the default Python language variant, which is + currently Python 2. (This default is independent of what any + local Python installations might consider to be + their default, for example, + what /usr/bin/python might be.) The + default will probably be changed to Python 3 in a distant future + release of PostgreSQL, depending on the progress of the + migration to Python 3 in the Python community. + + + + + This scheme is analogous to the recommendations in PEP 394 regarding the + naming and transitioning of the python command. + + + + It depends on the build configuration or the installed packages + whether PL/Python for Python 2 or Python 3 or both are available. + + + + + The built variant depends on which Python version was found during + the installation or which version was explicitly set using + the PYTHON environment variable; + see . To make both variants of + PL/Python available in one installation, the source tree has to be + configured and built twice. + + + + + This results in the following usage and migration strategy: + + + + + Existing users and users who are currently not interested in + Python 3 use the language name plpythonu and + don't have to change anything for the foreseeable future. It is + recommended to gradually future-proof the code + via migration to Python 2.6/2.7 to simplify the eventual + migration to Python 3. + + + + In practice, many PL/Python functions will migrate to Python 3 + with few or no changes. + + + + + + Users who know that they have heavily Python 2 dependent code + and don't plan to ever change it can make use of + the plpython2u language name. This will + continue to work into the very distant future, until Python 2 + support might be completely dropped by PostgreSQL. + + + + + + Users who want to dive into Python 3 can use + the plpython3u language name, which will keep + working forever by today's standards. In the distant future, + when Python 3 might become the default, they might like to + remove the 3 for aesthetic reasons. + + + + + + Daredevils, who want to build a Python-3-only operating system + environment, can change the contents of + plpythonu's extension control and script files + to make plpythonu be equivalent + to plpython3u, keeping in mind that this + would make their installation incompatible with most of the rest + of the world. + + + + + + + See also the + document What's + New In Python 3.0 for more information about porting to + Python 3. + + + + It is not allowed to use PL/Python based on Python 2 and PL/Python + based on Python 3 in the same session, because the symbols in the + dynamic modules would clash, which could result in crashes of the + PostgreSQL server process. There is a check that prevents mixing + Python major versions in a session, which will abort the session if + a mismatch is detected. It is possible, however, to use both + PL/Python variants in the same database, from separate sessions. + + + + + PL/Python Functions + + + Functions in PL/Python are declared via the + standard syntax: + + +CREATE FUNCTION funcname (argument-list) + RETURNS return-type +AS $$ + # PL/Python function body +$$ LANGUAGE plpythonu; + + + + + The body of a function is simply a Python script. When the function + is called, its arguments are passed as elements of the list + args; named arguments are also passed as + ordinary variables to the Python script. Use of named arguments is + usually more readable. The result is returned from the Python code + in the usual way, with return or + yield (in case of a result-set statement). If + you do not provide a return value, Python returns the default + None. PL/Python translates + Python's None into the SQL null value. In a procedure, + the result from the Python code must be None (typically + achieved by ending the procedure without a return + statement or by using a return statement without + argument); otherwise, an error will be raised. + + + + For example, a function to return the greater of two integers can be + defined as: + + +CREATE FUNCTION pymax (a integer, b integer) + RETURNS integer +AS $$ + if a > b: + return a + return b +$$ LANGUAGE plpythonu; + + + The Python code that is given as the body of the function definition + is transformed into a Python function. For example, the above results in: + + +def __plpython_procedure_pymax_23456(): + if a > b: + return a + return b + + + assuming that 23456 is the OID assigned to the function by + PostgreSQL. + + + + The arguments are set as global variables. Because of the scoping + rules of Python, this has the subtle consequence that an argument + variable cannot be reassigned inside the function to the value of + an expression that involves the variable name itself, unless the + variable is redeclared as global in the block. For example, the + following won't work: + +CREATE FUNCTION pystrip(x text) + RETURNS text +AS $$ + x = x.strip() # error + return x +$$ LANGUAGE plpythonu; + + because assigning to x + makes x a local variable for the entire block, + and so the x on the right-hand side of the + assignment refers to a not-yet-assigned local + variable x, not the PL/Python function + parameter. Using the global statement, this can + be made to work: + +CREATE FUNCTION pystrip(x text) + RETURNS text +AS $$ + global x + x = x.strip() # ok now + return x +$$ LANGUAGE plpythonu; + + But it is advisable not to rely on this implementation detail of + PL/Python. It is better to treat the function parameters as + read-only. + + + + + Data Values + + Generally speaking, the aim of PL/Python is to provide + a natural mapping between the PostgreSQL and the + Python worlds. This informs the data mapping rules described + below. + + + + Data Type Mapping + + When a PL/Python function is called, its arguments are converted from + their PostgreSQL data type to a corresponding Python type: + + + + + PostgreSQL boolean is converted to Python bool. + + + + + + PostgreSQL smallint and int are + converted to Python int. + PostgreSQL bigint and oid are converted + to long in Python 2 and to int in + Python 3. + + + + + + PostgreSQL real and double are converted to + Python float. + + + + + + PostgreSQL numeric is converted to + Python Decimal. This type is imported from + the cdecimal package if that is available. + Otherwise, + decimal.Decimal from the standard library will be + used. cdecimal is significantly faster + than decimal. In Python 3.3 and up, + however, cdecimal has been integrated into the + standard library under the name decimal, so there is + no longer any difference. + + + + + + PostgreSQL bytea is converted to + Python str in Python 2 and to bytes + in Python 3. In Python 2, the string should be treated as a + byte sequence without any character encoding. + + + + + + All other data types, including the PostgreSQL character string + types, are converted to a Python str. In Python + 2, this string will be in the PostgreSQL server encoding; in + Python 3, it will be a Unicode string like all strings. + + + + + + For nonscalar data types, see below. + + + + + + + When a PL/Python function returns, its return value is converted to the + function's declared PostgreSQL return data type as follows: + + + + + When the PostgreSQL return type is boolean, the + return value will be evaluated for truth according to the + Python rules. That is, 0 and empty string + are false, but notably 'f' is true. + + + + + + When the PostgreSQL return type is bytea, the + return value will be converted to a string (Python 2) or bytes + (Python 3) using the respective Python built-ins, with the + result being converted to bytea. + + + + + + For all other PostgreSQL return types, the return value is converted + to a string using the Python built-in str, and the + result is passed to the input function of the PostgreSQL data type. + (If the Python value is a float, it is converted using + the repr built-in instead of str, to + avoid loss of precision.) + + + + Strings in Python 2 are required to be in the PostgreSQL server + encoding when they are passed to PostgreSQL. Strings that are + not valid in the current server encoding will raise an error, + but not all encoding mismatches can be detected, so garbage + data can still result when this is not done correctly. Unicode + strings are converted to the correct encoding automatically, so + it can be safer and more convenient to use those. In Python 3, + all strings are Unicode strings. + + + + + + For nonscalar data types, see below. + + + + + Note that logical mismatches between the declared PostgreSQL + return type and the Python data type of the actual return object + are not flagged; the value will be converted in any case. + + + + + Null, None + + If an SQL null valuenull valuein PL/Python is passed to a + function, the argument value will appear as None in + Python. For example, the function definition of pymax + shown in will return the wrong answer for null + inputs. We could add STRICT to the function definition + to make PostgreSQL do something more reasonable: + if a null value is passed, the function will not be called at all, + but will just return a null result automatically. Alternatively, + we could check for null inputs in the function body: + + +CREATE FUNCTION pymax (a integer, b integer) + RETURNS integer +AS $$ + if (a is None) or (b is None): + return None + if a > b: + return a + return b +$$ LANGUAGE plpythonu; + + + As shown above, to return an SQL null value from a PL/Python + function, return the value None. This can be done whether the + function is strict or not. + + + + + Arrays, Lists + + SQL array values are passed into PL/Python as a Python list. To + return an SQL array value out of a PL/Python function, return a + Python list: + + +CREATE FUNCTION return_arr() + RETURNS int[] +AS $$ +return [1, 2, 3, 4, 5] +$$ LANGUAGE plpythonu; + +SELECT return_arr(); + return_arr +------------- + {1,2,3,4,5} +(1 row) + + + Multidimensional arrays are passed into PL/Python as nested Python lists. + A 2-dimensional array is a list of lists, for example. When returning + a multi-dimensional SQL array out of a PL/Python function, the inner + lists at each level must all be of the same size. For example: + + +CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$ +plpy.info(x, type(x)) +return x +$$ LANGUAGE plpythonu; + +SELECT * FROM test_type_conversion_array_int4(ARRAY[[1,2,3],[4,5,6]]); +INFO: ([[1, 2, 3], [4, 5, 6]], <type 'list'>) + test_type_conversion_array_int4 +--------------------------------- + {{1,2,3},{4,5,6}} +(1 row) + + + Other Python sequences, like tuples, are also accepted for + backwards-compatibility with PostgreSQL versions 9.6 and below, when + multi-dimensional arrays were not supported. However, they are always + treated as one-dimensional arrays, because they are ambiguous with + composite types. For the same reason, when a composite type is used in a + multi-dimensional array, it must be represented by a tuple, rather than a + list. + + + Note that in Python, strings are sequences, which can have + undesirable effects that might be familiar to Python programmers: + + +CREATE FUNCTION return_str_arr() + RETURNS varchar[] +AS $$ +return "hello" +$$ LANGUAGE plpythonu; + +SELECT return_str_arr(); + return_str_arr +---------------- + {h,e,l,l,o} +(1 row) + + + + + + Composite Types + + Composite-type arguments are passed to the function as Python mappings. The + element names of the mapping are the attribute names of the composite type. + If an attribute in the passed row has the null value, it has the value + None in the mapping. Here is an example: + + +CREATE TABLE employee ( + name text, + salary integer, + age integer +); + +CREATE FUNCTION overpaid (e employee) + RETURNS boolean +AS $$ + if e["salary"] > 200000: + return True + if (e["age"] < 30) and (e["salary"] > 100000): + return True + return False +$$ LANGUAGE plpythonu; + + + + + There are multiple ways to return row or composite types from a Python + function. The following examples assume we have: + + +CREATE TYPE named_value AS ( + name text, + value integer +); + + + A composite result can be returned as a: + + + + Sequence type (a tuple or list, but not a set because + it is not indexable) + + + Returned sequence objects must have the same number of items as the + composite result type has fields. The item with index 0 is assigned to + the first field of the composite type, 1 to the second and so on. For + example: + + +CREATE FUNCTION make_pair (name text, value integer) + RETURNS named_value +AS $$ + return ( name, value ) + # or alternatively, as tuple: return [ name, value ] +$$ LANGUAGE plpythonu; + + + To return an SQL null for any column, insert None at + the corresponding position. + + + When an array of composite types is returned, it cannot be returned as a list, + because it is ambiguous whether the Python list represents a composite type, + or another array dimension. + + + + + + Mapping (dictionary) + + + The value for each result type column is retrieved from the mapping + with the column name as key. Example: + + +CREATE FUNCTION make_pair (name text, value integer) + RETURNS named_value +AS $$ + return { "name": name, "value": value } +$$ LANGUAGE plpythonu; + + + Any extra dictionary key/value pairs are ignored. Missing keys are + treated as errors. + To return an SQL null value for any column, insert + None with the corresponding column name as the key. + + + + + + Object (any object providing method __getattr__) + + + This works the same as a mapping. + Example: + + +CREATE FUNCTION make_pair (name text, value integer) + RETURNS named_value +AS $$ + class named_value: + def __init__ (self, n, v): + self.name = n + self.value = v + return named_value(name, value) + + # or simply + class nv: pass + nv.name = name + nv.value = value + return nv +$$ LANGUAGE plpythonu; + + + + + + + + + Functions with OUT parameters are also supported. For example: + +CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$ +return (1, 2) +$$ LANGUAGE plpythonu; + +SELECT * FROM multiout_simple(); + + + + + Output parameters of procedures are passed back the same way. For example: + +CREATE PROCEDURE python_triple(INOUT a integer, INOUT b integer) AS $$ +return (a * 3, b * 3) +$$ LANGUAGE plpythonu; + +CALL python_triple(5, 10); + + + + + + Set-Returning Functions + + A PL/Python function can also return sets of + scalar or composite types. There are several ways to achieve this because + the returned object is internally turned into an iterator. The following + examples assume we have composite type: + + +CREATE TYPE greeting AS ( + how text, + who text +); + + + A set result can be returned from a: + + + + Sequence type (tuple, list, set) + + + +CREATE FUNCTION greet (how text) + RETURNS SETOF greeting +AS $$ + # return tuple containing lists as composite types + # all other combinations work also + return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] ) +$$ LANGUAGE plpythonu; + + + + + + + Iterator (any object providing __iter__ and + next methods) + + + +CREATE FUNCTION greet (how text) + RETURNS SETOF greeting +AS $$ + class producer: + def __init__ (self, how, who): + self.how = how + self.who = who + self.ndx = -1 + + def __iter__ (self): + return self + + def next (self): + self.ndx += 1 + if self.ndx == len(self.who): + raise StopIteration + return ( self.how, self.who[self.ndx] ) + + return producer(how, [ "World", "PostgreSQL", "PL/Python" ]) +$$ LANGUAGE plpythonu; + + + + + + + Generator (yield) + + + +CREATE FUNCTION greet (how text) + RETURNS SETOF greeting +AS $$ + for who in [ "World", "PostgreSQL", "PL/Python" ]: + yield ( how, who ) +$$ LANGUAGE plpythonu; + + + + + + + + + + Set-returning functions with OUT parameters + (using RETURNS SETOF record) are also + supported. For example: + +CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$ +return [(1, 2)] * n +$$ LANGUAGE plpythonu; + +SELECT * FROM multiout_simple_setof(3); + + + + + + + Sharing Data + + The global dictionary SD is available to store + private data between repeated calls to the same function. + The global dictionary GD is public data, + that is available to all Python functions within a session; use with + care.global data + in PL/Python + + + + Each function gets its own execution environment in the + Python interpreter, so that global data and function arguments from + myfunc are not available to + myfunc2. The exception is the data in the + GD dictionary, as mentioned above. + + + + + Anonymous Code Blocks + + + PL/Python also supports anonymous code blocks called with the + statement: + + +DO $$ + # PL/Python code +$$ LANGUAGE plpythonu; + + + An anonymous code block receives no arguments, and whatever value it + might return is discarded. Otherwise it behaves just like a function. + + + + + Trigger Functions + + + trigger + in PL/Python + + + + When a function is used as a trigger, the dictionary + TD contains trigger-related values: + + + TD["event"] + + + contains the event as a string: + INSERT, UPDATE, + DELETE, or TRUNCATE. + + + + + + TD["when"] + + + contains one of BEFORE, AFTER, or + INSTEAD OF. + + + + + + TD["level"] + + + contains ROW or STATEMENT. + + + + + + TD["new"] + TD["old"] + + + For a row-level trigger, one or both of these fields contain + the respective trigger rows, depending on the trigger event. + + + + + + TD["name"] + + + contains the trigger name. + + + + + + TD["table_name"] + + + contains the name of the table on which the trigger occurred. + + + + + + TD["table_schema"] + + + contains the schema of the table on which the trigger occurred. + + + + + + TD["relid"] + + + contains the OID of the table on which the trigger occurred. + + + + + + TD["args"] + + + If the CREATE TRIGGER command + included arguments, they are available in TD["args"][0] to + TD["args"][n-1]. + + + + + + + + If TD["when"] is BEFORE or + INSTEAD OF and + TD["level"] is ROW, you can + return None or "OK" from the + Python function to indicate the row is unmodified, + "SKIP" to abort the event, or if TD["event"] + is INSERT or UPDATE you can return + "MODIFY" to indicate you've modified the new row. + Otherwise the return value is ignored. + + + + + Database Access + + + The PL/Python language module automatically imports a Python module + called plpy. The functions and constants in + this module are available to you in the Python code as + plpy.foo. + + + + Database Access Functions + + + The plpy module provides several functions to execute + database commands: + + + + + plpy.execute(query [, max-rows]) + + + Calling plpy.execute with a query string and an + optional row limit argument causes that query to be run and the result to + be returned in a result object. + + + + The result object emulates a list or dictionary object. The result + object can be accessed by row number and column name. For example: + +rv = plpy.execute("SELECT * FROM my_table", 5) + + returns up to 5 rows from my_table. If + my_table has a column + my_column, it would be accessed as: + +foo = rv[i]["my_column"] + + The number of rows returned can be obtained using the built-in + len function. + + + + The result object has these additional methods: + + + nrows() + + + Returns the number of rows processed by the command. Note that this + is not necessarily the same as the number of rows returned. For + example, an UPDATE command will set this value but + won't return any rows (unless RETURNING is used). + + + + + + status() + + + The SPI_execute() return value. + + + + + + colnames() + coltypes() + coltypmods() + + + Return a list of column names, list of column type OIDs, and list of + type-specific type modifiers for the columns, respectively. + + + + These methods raise an exception when called on a result object from + a command that did not produce a result set, e.g., + UPDATE without RETURNING, or + DROP TABLE. But it is OK to use these methods on + a result set containing zero rows. + + + + + + __str__() + + + The standard __str__ method is defined so that it + is possible for example to debug query execution results + using plpy.debug(rv). + + + + + + + + The result object can be modified. + + + + Note that calling plpy.execute will cause the entire + result set to be read into memory. Only use that function when you are + sure that the result set will be relatively small. If you don't want to + risk excessive memory usage when fetching large results, + use plpy.cursor rather + than plpy.execute. + + + + + + plpy.prepare(query [, argtypes]) + plpy.execute(plan [, arguments [, max-rows]]) + + + preparing a queryin PL/Python + plpy.prepare prepares the execution plan for a + query. It is called with a query string and a list of parameter types, + if you have parameter references in the query. For example: + +plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", ["text"]) + + text is the type of the variable you will be passing + for $1. The second argument is optional if you don't + want to pass any parameters to the query. + + + After preparing a statement, you use a variant of the + function plpy.execute to run it: + +rv = plpy.execute(plan, ["name"], 5) + + Pass the plan as the first argument (instead of the query string), and a + list of values to substitute into the query as the second argument. The + second argument is optional if the query does not expect any parameters. + The third argument is the optional row limit as before. + + + + Alternatively, you can call the execute method on + the plan object: + +rv = plan.execute(["name"], 5) + + + + + Query parameters and result row fields are converted between PostgreSQL + and Python data types as described in . + + + + When you prepare a plan using the PL/Python module it is automatically + saved. Read the SPI documentation () for a + description of what this means. In order to make effective use of this + across function calls one needs to use one of the persistent storage + dictionaries SD or GD (see + ). For example: + +CREATE FUNCTION usesavedplan() RETURNS trigger AS $$ + if "plan" in SD: + plan = SD["plan"] + else: + plan = plpy.prepare("SELECT 1") + SD["plan"] = plan + # rest of function +$$ LANGUAGE plpythonu; + + + + + + + plpy.cursor(query) + plpy.cursor(plan [, arguments]) + + + The plpy.cursor function accepts the same arguments + as plpy.execute (except for the row limit) and returns + a cursor object, which allows you to process large result sets in smaller + chunks. As with plpy.execute, either a query string + or a plan object along with a list of arguments can be used, or + the cursor function can be called as a method of + the plan object. + + + + The cursor object provides a fetch method that accepts + an integer parameter and returns a result object. Each time you + call fetch, the returned object will contain the next + batch of rows, never larger than the parameter value. Once all rows are + exhausted, fetch starts returning an empty result + object. Cursor objects also provide an + iterator + interface, yielding one row at a time until all rows are + exhausted. Data fetched that way is not returned as result objects, but + rather as dictionaries, each dictionary corresponding to a single result + row. + + + + An example of two ways of processing data from a large table is: + +CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$ +odd = 0 +for row in plpy.cursor("select num from largetable"): + if row['num'] % 2: + odd += 1 +return odd +$$ LANGUAGE plpythonu; + +CREATE FUNCTION count_odd_fetch(batch_size integer) RETURNS integer AS $$ +odd = 0 +cursor = plpy.cursor("select num from largetable") +while True: + rows = cursor.fetch(batch_size) + if not rows: + break + for row in rows: + if row['num'] % 2: + odd += 1 +return odd +$$ LANGUAGE plpythonu; + +CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$ +odd = 0 +plan = plpy.prepare("select num from largetable where num % $1 <> 0", ["integer"]) +rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2])) + +return len(rows) +$$ LANGUAGE plpythonu; + + + + + Cursors are automatically disposed of. But if you want to explicitly + release all resources held by a cursor, use the close + method. Once closed, a cursor cannot be fetched from anymore. + + + + + Do not confuse objects created by plpy.cursor with + DB-API cursors as defined by + the Python + Database API specification. They don't have anything in common + except for the name. + + + + + + + + + + Trapping Errors + + + Functions accessing the database might encounter errors, which + will cause them to abort and raise an exception. Both + plpy.execute and + plpy.prepare can raise an instance of a subclass of + plpy.SPIError, which by default will terminate + the function. This error can be handled just like any other + Python exception, by using the try/except + construct. For example: + +CREATE FUNCTION try_adding_joe() RETURNS text AS $$ + try: + plpy.execute("INSERT INTO users(username) VALUES ('joe')") + except plpy.SPIError: + return "something went wrong" + else: + return "Joe added" +$$ LANGUAGE plpythonu; + + + + + The actual class of the exception being raised corresponds to the + specific condition that caused the error. Refer + to for a list of possible + conditions. The module + plpy.spiexceptions defines an exception class + for each PostgreSQL condition, deriving + their names from the condition name. For + instance, division_by_zero + becomes DivisionByZero, unique_violation + becomes UniqueViolation, fdw_error + becomes FdwError, and so on. Each of these + exception classes inherits from SPIError. This + separation makes it easier to handle specific errors, for + instance: + +CREATE FUNCTION insert_fraction(numerator int, denominator int) RETURNS text AS $$ +from plpy import spiexceptions +try: + plan = plpy.prepare("INSERT INTO fractions (frac) VALUES ($1 / $2)", ["int", "int"]) + plpy.execute(plan, [numerator, denominator]) +except spiexceptions.DivisionByZero: + return "denominator cannot equal zero" +except spiexceptions.UniqueViolation: + return "already have that fraction" +except plpy.SPIError as e: + return "other error, SQLSTATE %s" % e.sqlstate +else: + return "fraction inserted" +$$ LANGUAGE plpythonu; + + Note that because all exceptions from + the plpy.spiexceptions module inherit + from SPIError, an except + clause handling it will catch any database access error. + + + + As an alternative way of handling different error conditions, you + can catch the SPIError exception and determine + the specific error condition inside the except + block by looking at the sqlstate attribute of + the exception object. This attribute is a string value containing + the SQLSTATE error code. This approach provides + approximately the same functionality + + + + + + Explicit Subtransactions + + + Recovering from errors caused by database access as described in + can lead to an undesirable + situation where some operations succeed before one of them fails, + and after recovering from that error the data is left in an + inconsistent state. PL/Python offers a solution to this problem in + the form of explicit subtransactions. + + + + Subtransaction Context Managers + + + Consider a function that implements a transfer between two + accounts: + +CREATE FUNCTION transfer_funds() RETURNS void AS $$ +try: + plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'") + plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'") +except plpy.SPIError as e: + result = "error transferring funds: %s" % e.args +else: + result = "funds transferred correctly" +plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"]) +plpy.execute(plan, [result]) +$$ LANGUAGE plpythonu; + + If the second UPDATE statement results in an + exception being raised, this function will report the error, but + the result of the first UPDATE will + nevertheless be committed. In other words, the funds will be + withdrawn from Joe's account, but will not be transferred to + Mary's account. + + + + To avoid such issues, you can wrap your + plpy.execute calls in an explicit + subtransaction. The plpy module provides a + helper object to manage explicit subtransactions that gets created + with the plpy.subtransaction() function. + Objects created by this function implement the + + context manager interface. Using explicit subtransactions + we can rewrite our function as: + +CREATE FUNCTION transfer_funds2() RETURNS void AS $$ +try: + with plpy.subtransaction(): + plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'") + plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'") +except plpy.SPIError as e: + result = "error transferring funds: %s" % e.args +else: + result = "funds transferred correctly" +plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"]) +plpy.execute(plan, [result]) +$$ LANGUAGE plpythonu; + + Note that the use of try/catch is still + required. Otherwise the exception would propagate to the top of + the Python stack and would cause the whole function to abort with + a PostgreSQL error, so that the + operations table would not have any row + inserted into it. The subtransaction context manager does not + trap errors, it only assures that all database operations executed + inside its scope will be atomically committed or rolled back. A + rollback of the subtransaction block occurs on any kind of + exception exit, not only ones caused by errors originating from + database access. A regular Python exception raised inside an + explicit subtransaction block would also cause the subtransaction + to be rolled back. + + + + + Older Python Versions + + + Context managers syntax using the with keyword + is available by default in Python 2.6. For compatibility with + older Python versions, you can call the + subtransaction manager's __enter__ and + __exit__ functions using the + enter and exit convenience + aliases. The example function that transfers funds could be + written as: + +CREATE FUNCTION transfer_funds_old() RETURNS void AS $$ +try: + subxact = plpy.subtransaction() + subxact.enter() + try: + plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'") + plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'") + except: + import sys + subxact.exit(*sys.exc_info()) + raise + else: + subxact.exit(None, None, None) +except plpy.SPIError as e: + result = "error transferring funds: %s" % e.args +else: + result = "funds transferred correctly" + +plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"]) +plpy.execute(plan, [result]) +$$ LANGUAGE plpythonu; + + + + + + + Transaction Management + + + In a procedure called from the top level or an anonymous code block + (DO command) called from the top level it is possible to + control transactions. To commit the current transaction, call + plpy.commit(). To roll back the current transaction, + call plpy.rollback(). (Note that it is not possible to + run the SQL commands COMMIT or + ROLLBACK via plpy.execute or + similar. It has to be done using these functions.) After a transaction is + ended, a new transaction is automatically started, so there is no separate + function for that. + + + + Here is an example: + +CREATE PROCEDURE transaction_test1() +LANGUAGE plpythonu +AS $$ +for i in range(0, 10): + plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i) + if i % 2 == 0: + plpy.commit() + else: + plpy.rollback() +$$; + +CALL transaction_test1(); + + + + + Transactions cannot be ended when an explicit subtransaction is active. + + + + + Utility Functions + + The plpy module also provides the functions + + plpy.debug(msg, **kwargs) + plpy.log(msg, **kwargs) + plpy.info(msg, **kwargs) + plpy.notice(msg, **kwargs) + plpy.warning(msg, **kwargs) + plpy.error(msg, **kwargs) + plpy.fatal(msg, **kwargs) + + elogin PL/Python + plpy.error and plpy.fatal + actually raise a Python exception which, if uncaught, propagates out to + the calling query, causing the current transaction or subtransaction to + be aborted. raise plpy.Error(msg) and + raise plpy.Fatal(msg) are + equivalent to calling plpy.error(msg) and + plpy.fatal(msg), respectively but + the raise form does not allow passing keyword arguments. + The other functions only generate messages of different priority levels. + Whether messages of a particular priority are reported to the client, + written to the server log, or both is controlled by the + and + configuration + variables. See for more information. + + + + The msg argument is given as a positional argument. For + backward compatibility, more than one positional argument can be given. In + that case, the string representation of the tuple of positional arguments + becomes the message reported to the client. + + + + The following keyword-only arguments are accepted: + + detail + hint + sqlstate + schema_name + table_name + column_name + datatype_name + constraint_name + + The string representation of the objects passed as keyword-only arguments + is used to enrich the messages reported to the client. For example: + + +CREATE FUNCTION raise_custom_exception() RETURNS void AS $$ +plpy.error("custom exception message", + detail="some info about exception", + hint="hint for users") +$$ LANGUAGE plpythonu; + +=# SELECT raise_custom_exception(); +ERROR: plpy.Error: custom exception message +DETAIL: some info about exception +HINT: hint for users +CONTEXT: Traceback (most recent call last): + PL/Python function "raise_custom_exception", line 4, in <module> + hint="hint for users") +PL/Python function "raise_custom_exception" + + + + + Another set of utility functions are + plpy.quote_literal(string), + plpy.quote_nullable(string), and + plpy.quote_ident(string). They + are equivalent to the built-in quoting functions described in . They are useful when constructing + ad-hoc queries. A PL/Python equivalent of dynamic SQL from would be: + +plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % ( + plpy.quote_ident(colname), + plpy.quote_nullable(newvalue), + plpy.quote_literal(keyvalue))) + + + + + + Environment Variables + + + Some of the environment variables that are accepted by the Python + interpreter can also be used to affect PL/Python behavior. They + would need to be set in the environment of the main PostgreSQL + server process, for example in a start script. The available + environment variables depend on the version of Python; see the + Python documentation for details. At the time of this writing, the + following environment variables have an affect on PL/Python, + assuming an adequate Python version: + + + PYTHONHOME + + + + PYTHONPATH + + + + PYTHONY2K + + + + PYTHONOPTIMIZE + + + + PYTHONDEBUG + + + + PYTHONVERBOSE + + + + PYTHONCASEOK + + + + PYTHONDONTWRITEBYTECODE + + + + PYTHONIOENCODING + + + + PYTHONUSERBASE + + + + PYTHONHASHSEED + + + + (It appears to be a Python implementation detail beyond the control + of PL/Python that some of the environment variables listed on + the python man page are only effective in a + command-line interpreter and not an embedded Python interpreter.) + + + diff --git a/doc/src/sgml/pltcl.sgml b/doc/src/sgml/pltcl.sgml new file mode 100644 index 000000000000..1759fc44985d --- /dev/null +++ b/doc/src/sgml/pltcl.sgml @@ -0,0 +1,1131 @@ + + + + PL/Tcl — Tcl Procedural Language + + + PL/Tcl + + + + Tcl + + + + PL/Tcl is a loadable procedural language for the + PostgreSQL database system + that enables the + Tcl language to be used to write + PostgreSQL functions and procedures. + + + + + + Overview + + + PL/Tcl offers most of the capabilities a function writer has in + the C language, with a few restrictions, and with the addition of + the powerful string processing libraries that are available for + Tcl. + + + One compelling good restriction is that + everything is executed from within the safety of the context of a + Tcl interpreter. In addition to the limited command set of safe + Tcl, only a few commands are available to access the database via + SPI and to raise messages via elog(). PL/Tcl + provides no way to access internals of the database server or to + gain OS-level access under the permissions of the + PostgreSQL server process, as a C + function can do. Thus, unprivileged database users can be trusted + to use this language; it does not give them unlimited authority. + + + The other notable implementation restriction is that Tcl functions + cannot be used to create input/output functions for new data + types. + + + Sometimes it is desirable to write Tcl functions that are not restricted + to safe Tcl. For example, one might want a Tcl function that sends + email. To handle these cases, there is a variant of PL/Tcl called PL/TclU + (for untrusted Tcl). This is exactly the same language except that a full + Tcl interpreter is used. If PL/TclU is used, it must be + installed as an untrusted procedural language so that only + database superusers can create functions in it. The writer of a PL/TclU + function must take care that the function cannot be used to do anything + unwanted, since it will be able to do anything that could be done by + a user logged in as the database administrator. + + + The shared object code for the PL/Tcl and + PL/TclU call handlers is automatically built and + installed in the PostgreSQL library + directory if Tcl support is specified in the configuration step of + the installation procedure. To install PL/Tcl + and/or PL/TclU in a particular database, use the + CREATE EXTENSION command, for example + CREATE EXTENSION pltcl or + CREATE EXTENSION pltclu. + + + + + + + PL/Tcl Functions and Arguments + + + To create a function in the PL/Tcl language, use + the standard syntax: + + +CREATE FUNCTION funcname (argument-types) RETURNS return-type AS $$ + # PL/Tcl function body +$$ LANGUAGE pltcl; + + + PL/TclU is the same, except that the language has to be specified as + pltclu. + + + + The body of the function is simply a piece of Tcl script. + When the function is called, the argument values are passed to the + Tcl script as variables named 1 + ... n. The result is + returned from the Tcl code in the usual way, with + a return statement. In a procedure, the return value + from the Tcl code is ignored. + + + + For example, a function + returning the greater of two integer values could be defined as: + + +CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ + if {$1 > $2} {return $1} + return $2 +$$ LANGUAGE pltcl STRICT; + + + Note the clause STRICT, which saves us from + having to think about null input values: if a null value is passed, the + function will not be called at all, but will just return a null + result automatically. + + + + In a nonstrict function, + if the actual value of an argument is null, the corresponding + $n variable will be set to an empty string. + To detect whether a particular argument is null, use the function + argisnull. For example, suppose that we wanted tcl_max + with one null and one nonnull argument to return the nonnull + argument, rather than null: + + +CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$ + if {[argisnull 1]} { + if {[argisnull 2]} { return_null } + return $2 + } + if {[argisnull 2]} { return $1 } + if {$1 > $2} {return $1} + return $2 +$$ LANGUAGE pltcl; + + + + + As shown above, + to return a null value from a PL/Tcl function, execute + return_null. This can be done whether the + function is strict or not. + + + + Composite-type arguments are passed to the function as Tcl + arrays. The element names of the array are the attribute names + of the composite type. If an attribute in the passed row has the + null value, it will not appear in the array. Here is an example: + + +CREATE TABLE employee ( + name text, + salary integer, + age integer +); + +CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$ + if {200000.0 < $1(salary)} { + return "t" + } + if {$1(age) < 30 && 100000.0 < $1(salary)} { + return "t" + } + return "f" +$$ LANGUAGE pltcl; + + + + + PL/Tcl functions can return composite-type results, too. To do this, + the Tcl code must return a list of column name/value pairs matching + the expected result type. Any column names omitted from the list + are returned as nulls, and an error is raised if there are unexpected + column names. Here is an example: + + +CREATE FUNCTION square_cube(in int, out squared int, out cubed int) AS $$ + return [list squared [expr {$1 * $1}] cubed [expr {$1 * $1 * $1}]] +$$ LANGUAGE pltcl; + + + + + Output arguments of procedures are returned in the same way, for example: + + +CREATE PROCEDURE tcl_triple(INOUT a integer, INOUT b integer) AS $$ + return [list a [expr {$1 * 3}] b [expr {$2 * 3}]] +$$ LANGUAGE pltcl; + +CALL tcl_triple(5, 10); + + + + + + The result list can be made from an array representation of the + desired tuple with the array get Tcl command. For example: + + +CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$ + set 1(salary) [expr {$1(salary) + $2}] + return [array get 1] +$$ LANGUAGE pltcl; + + + + + + PL/Tcl functions can return sets. To do this, the Tcl code should + call return_next once per row to be returned, + passing either the appropriate value when returning a scalar type, + or a list of column name/value pairs when returning a composite type. + Here is an example returning a scalar type: + + +CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$ + for {set i $1} {$i < $2} {incr i} { + return_next $i + } +$$ LANGUAGE pltcl; + + + and here is one returning a composite type: + + +CREATE FUNCTION table_of_squares(int, int) RETURNS TABLE (x int, x2 int) AS $$ + for {set i $1} {$i < $2} {incr i} { + return_next [list x $i x2 [expr {$i * $i}]] + } +$$ LANGUAGE pltcl; + + + + + + + Data Values in PL/Tcl + + + The argument values supplied to a PL/Tcl function's code are simply + the input arguments converted to text form (just as if they had been + displayed by a SELECT statement). Conversely, the + return and return_next commands will accept + any string that is acceptable input format for the function's declared + result type, or for the specified column of a composite result type. + + + + + + Global Data in PL/Tcl + + + global data + in PL/Tcl + + + + Sometimes it + is useful to have some global data that is held between two + calls to a function or is shared between different functions. + This is easily done in PL/Tcl, but there are some restrictions that + must be understood. + + + + For security reasons, PL/Tcl executes functions called by any one SQL + role in a separate Tcl interpreter for that role. This prevents + accidental or malicious interference by one user with the behavior of + another user's PL/Tcl functions. Each such interpreter will have its own + values for any global Tcl variables. Thus, two PL/Tcl + functions will share the same global variables if and only if they are + executed by the same SQL role. In an application wherein a single + session executes code under multiple SQL roles (via SECURITY + DEFINER functions, use of SET ROLE, etc) you may need to + take explicit steps to ensure that PL/Tcl functions can share data. To + do that, make sure that functions that should communicate are owned by + the same user, and mark them SECURITY DEFINER. You must of + course take care that such functions can't be used to do anything + unintended. + + + + All PL/TclU functions used in a session execute in the same Tcl + interpreter, which of course is distinct from the interpreter(s) + used for PL/Tcl functions. So global data is automatically shared + between PL/TclU functions. This is not considered a security risk + because all PL/TclU functions execute at the same trust level, + namely that of a database superuser. + + + + To help protect PL/Tcl functions from unintentionally interfering + with each other, a global + array is made available to each function via the upvar + command. The global name of this variable is the function's internal + name, and the local name is GD. It is recommended that + GD be used + for persistent private data of a function. Use regular Tcl global + variables only for values that you specifically intend to be shared among + multiple functions. (Note that the GD arrays are only + global within a particular interpreter, so they do not bypass the + security restrictions mentioned above.) + + + + An example of using GD appears in the + spi_execp example below. + + + + + Database Access from PL/Tcl + + + The following commands are available to access the database from + the body of a PL/Tcl function: + + + + + spi_exec -count n -array name command loop-body + + + Executes an SQL command given as a string. An error in the command + causes an error to be raised. Otherwise, the return value of spi_exec + is the number of rows processed (selected, inserted, updated, or + deleted) by the command, or zero if the command is a utility + statement. In addition, if the command is a SELECT statement, the + values of the selected columns are placed in Tcl variables as + described below. + + + The optional -count value tells + spi_exec the maximum number of rows + to process in the command. The effect of this is comparable to + setting up a query as a cursor and then saying FETCH n. + + + If the command is a SELECT statement, the values of the + result columns are placed into Tcl variables named after the columns. + If the -array option is given, the column values are + instead stored into elements of the named associative array, with the + column names used as array indexes. In addition, the current row + number within the result (counting from zero) is stored into the array + element named .tupno, unless that name is + in use as a column name in the result. + + + If the command is a SELECT statement and no loop-body + script is given, then only the first row of results are stored into + Tcl variables or array elements; remaining rows, if any, are ignored. + No storing occurs if the query returns no rows. (This case can be + detected by checking the result of spi_exec.) + For example: + +spi_exec "SELECT count(*) AS cnt FROM pg_proc" + + will set the Tcl variable $cnt to the number of rows in + the pg_proc system catalog. + + + If the optional loop-body argument is given, it is + a piece of Tcl script that is executed once for each row in the + query result. (loop-body is ignored if the given + command is not a SELECT.) + The values of the current row's columns + are stored into Tcl variables or array elements before each iteration. + For example: + +spi_exec -array C "SELECT * FROM pg_class" { + elog DEBUG "have table $C(relname)" +} + + will print a log message for every row of pg_class. This + feature works similarly to other Tcl looping constructs; in + particular continue and break work in the + usual way inside the loop body. + + + If a column of a query result is null, the target + variable for it is unset rather than being set. + + + + + + spi_prepare query typelist + + + Prepares and saves a query plan for later execution. The + saved plan will be retained for the life of the current + session.preparing a query + in PL/Tcl + + + The query can use parameters, that is, placeholders for + values to be supplied whenever the plan is actually executed. + In the query string, refer to parameters + by the symbols $1 ... $n. + If the query uses parameters, the names of the parameter types + must be given as a Tcl list. (Write an empty list for + typelist if no parameters are used.) + + + The return value from spi_prepare is a query ID + to be used in subsequent calls to spi_execp. See + spi_execp for an example. + + + + + + spi_execp -count n -array name -nulls string queryid value-list loop-body + + + Executes a query previously prepared with spi_prepare. + queryid is the ID returned by + spi_prepare. If the query references parameters, + a value-list must be supplied. This + is a Tcl list of actual values for the parameters. The list must be + the same length as the parameter type list previously given to + spi_prepare. Omit value-list + if the query has no parameters. + + + The optional value for -nulls is a string of spaces and + 'n' characters telling spi_execp + which of the parameters are null values. If given, it must have exactly the + same length as the value-list. If it + is not given, all the parameter values are nonnull. + + + Except for the way in which the query and its parameters are specified, + spi_execp works just like spi_exec. + The -count, -array, and + loop-body options are the same, + and so is the result value. + + + Here's an example of a PL/Tcl function using a prepared plan: + + +CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$ + if {![ info exists GD(plan) ]} { + # prepare the saved plan on the first call + set GD(plan) [ spi_prepare \ + "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \ + [ list int4 int4 ] ] + } + spi_execp -count 1 $GD(plan) [ list $1 $2 ] + return $cnt +$$ LANGUAGE pltcl; + + + We need backslashes inside the query string given to + spi_prepare to ensure that the + $n markers will be passed + through to spi_prepare as-is, and not replaced by Tcl + variable substitution. + + + + + + + subtransaction command + + + The Tcl script contained in command is + executed within an SQL subtransaction. If the script returns an + error, that entire subtransaction is rolled back before returning the + error out to the surrounding Tcl code. + See for more details and an + example. + + + + + + quote string + + + Doubles all occurrences of single quote and backslash characters + in the given string. This can be used to safely quote strings + that are to be inserted into SQL commands given + to spi_exec or + spi_prepare. + For example, think about an SQL command string like: + + +"SELECT '$val' AS ret" + + + where the Tcl variable val actually contains + doesn't. This would result + in the final command string: + + +SELECT 'doesn't' AS ret + + + which would cause a parse error during + spi_exec or + spi_prepare. + To work properly, the submitted command should contain: + + +SELECT 'doesn''t' AS ret + + + which can be formed in PL/Tcl using: + + +"SELECT '[ quote $val ]' AS ret" + + + One advantage of spi_execp is that you don't + have to quote parameter values like this, since the parameters are never + parsed as part of an SQL command string. + + + + + + + elog level msg + + elog + in PL/Tcl + + + + + Emits a log or error message. Possible levels are + DEBUG, LOG, INFO, + NOTICE, WARNING, ERROR, and + FATAL. ERROR + raises an error condition; if this is not trapped by the surrounding + Tcl code, the error propagates out to the calling query, causing + the current transaction or subtransaction to be aborted. This + is effectively the same as the Tcl error command. + FATAL aborts the transaction and causes the current + session to shut down. (There is probably no good reason to use + this error level in PL/Tcl functions, but it's provided for + completeness.) The other levels only generate messages of different + priority levels. + Whether messages of a particular priority are reported to the client, + written to the server log, or both is controlled by the + and + configuration + variables. See + and + for more information. + + + + + + + + + + + Trigger Functions in PL/Tcl + + + trigger + in PL/Tcl + + + + Trigger functions can be written in PL/Tcl. + PostgreSQL requires that a function that is to be called + as a trigger must be declared as a function with no arguments + and a return type of trigger. + + + The information from the trigger manager is passed to the function body + in the following variables: + + + + + $TG_name + + + The name of the trigger from the CREATE TRIGGER statement. + + + + + + $TG_relid + + + The object ID of the table that caused the trigger function + to be invoked. + + + + + + $TG_table_name + + + The name of the table that caused the trigger function + to be invoked. + + + + + + $TG_table_schema + + + The schema of the table that caused the trigger function + to be invoked. + + + + + + $TG_relatts + + + A Tcl list of the table column names, prefixed with an empty list + element. So looking up a column name in the list with Tcl's + lsearch command returns the element's number starting + with 1 for the first column, the same way the columns are customarily + numbered in PostgreSQL. (Empty list + elements also appear in the positions of columns that have been + dropped, so that the attribute numbering is correct for columns + to their right.) + + + + + + $TG_when + + + The string BEFORE, AFTER, or + INSTEAD OF, depending on the type of trigger event. + + + + + + $TG_level + + + The string ROW or STATEMENT depending on the + type of trigger event. + + + + + + $TG_op + + + The string INSERT, UPDATE, + DELETE, or TRUNCATE depending on the type of + trigger event. + + + + + + $NEW + + + An associative array containing the values of the new table + row for INSERT or UPDATE actions, or + empty for DELETE. The array is indexed by column + name. Columns that are null will not appear in the array. + This is not set for statement-level triggers. + + + + + + $OLD + + + An associative array containing the values of the old table + row for UPDATE or DELETE actions, or + empty for INSERT. The array is indexed by column + name. Columns that are null will not appear in the array. + This is not set for statement-level triggers. + + + + + + $args + + + A Tcl list of the arguments to the function as given in the + CREATE TRIGGER statement. These arguments are also accessible as + $1 ... $n in the function body. + + + + + + + + + The return value from a trigger function can be one of the strings + OK or SKIP, or a list of column name/value pairs. + If the return value is OK, + the operation (INSERT/UPDATE/DELETE) + that fired the trigger will proceed + normally. SKIP tells the trigger manager to silently suppress + the operation for this row. If a list is returned, it tells PL/Tcl to + return a modified row to the trigger manager; the contents of the + modified row are specified by the column names and values in the list. + Any columns not mentioned in the list are set to null. + Returning a modified row is only meaningful + for row-level BEFORE INSERT or UPDATE + triggers, for which the modified row will be inserted instead of the one + given in $NEW; or for row-level INSTEAD OF + INSERT or UPDATE triggers where the returned row + is used as the source data for INSERT RETURNING or + UPDATE RETURNING clauses. + In row-level BEFORE DELETE or INSTEAD + OF DELETE triggers, returning a modified row has the same + effect as returning OK, that is the operation proceeds. + The trigger return value is ignored for all other types of triggers. + + + + + The result list can be made from an array representation of the + modified tuple with the array get Tcl command. + + + + + Here's a little example trigger function that forces an integer value + in a table to keep track of the number of updates that are performed on the + row. For new rows inserted, the value is initialized to 0 and then + incremented on every update operation. + + +CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$ + switch $TG_op { + INSERT { + set NEW($1) 0 + } + UPDATE { + set NEW($1) $OLD($1) + incr NEW($1) + } + default { + return OK + } + } + return [array get NEW] +$$ LANGUAGE pltcl; + +CREATE TABLE mytab (num integer, description text, modcnt integer); + +CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab + FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt'); + + + Notice that the trigger function itself does not know the column + name; that's supplied from the trigger arguments. This lets the + trigger function be reused with different tables. + + + + + Event Trigger Functions in PL/Tcl + + + event trigger + in PL/Tcl + + + + Event trigger functions can be written in PL/Tcl. + PostgreSQL requires that a function that is + to be called as an event trigger must be declared as a function with no + arguments and a return type of event_trigger. + + + The information from the trigger manager is passed to the function body + in the following variables: + + + + + $TG_event + + + The name of the event the trigger is fired for. + + + + + + $TG_tag + + + The command tag for which the trigger is fired. + + + + + + + + The return value of the trigger function is ignored. + + + + Here's a little example event trigger function that simply raises + a NOTICE message each time a supported command is + executed: + + +CREATE OR REPLACE FUNCTION tclsnitch() RETURNS event_trigger AS $$ + elog NOTICE "tclsnitch: $TG_event $TG_tag" +$$ LANGUAGE pltcl; + +CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitch(); + + + + + + Error Handling in PL/Tcl + + + exceptions + in PL/Tcl + + + + Tcl code within or called from a PL/Tcl function can raise an error, + either by executing some invalid operation or by generating an error + using the Tcl error command or + PL/Tcl's elog command. Such errors can be caught + within Tcl using the Tcl catch command. If an + error is not caught but is allowed to propagate out to the top level of + execution of the PL/Tcl function, it is reported as an SQL error in the + function's calling query. + + + + Conversely, SQL errors that occur within PL/Tcl's + spi_exec, spi_prepare, + and spi_execp commands are reported as Tcl errors, + so they are catchable by Tcl's catch command. + (Each of these PL/Tcl commands runs its SQL operation in a + subtransaction, which is rolled back on error, so that any + partially-completed operation is automatically cleaned up.) + Again, if an error propagates out to the top level without being caught, + it turns back into an SQL error. + + + + Tcl provides an errorCode variable that can represent + additional information about an error in a form that is easy for Tcl + programs to interpret. The contents are in Tcl list format, and the + first word identifies the subsystem or library reporting the error; + beyond that the contents are left to the individual subsystem or + library. For database errors reported by PL/Tcl commands, the first + word is POSTGRES, the second word is the PostgreSQL + version number, and additional words are field name/value pairs + providing detailed information about the error. + Fields SQLSTATE, condition, + and message are always supplied + (the first two represent the error code and condition name as shown + in ). + Fields that may be present include + detail, hint, context, + schema, table, column, + datatype, constraint, + statement, cursor_position, + filename, lineno, and + funcname. + + + + A convenient way to work with PL/Tcl's errorCode + information is to load it into an array, so that the field names become + array subscripts. Code for doing that might look like + +if {[catch { spi_exec $sql_command }]} { + if {[lindex $::errorCode 0] == "POSTGRES"} { + array set errorArray $::errorCode + if {$errorArray(condition) == "undefined_table"} { + # deal with missing table + } else { + # deal with some other type of SQL error + } + } +} + + (The double colons explicitly specify that errorCode + is a global variable.) + + + + + Explicit Subtransactions in PL/Tcl + + + subtransactions + in PL/Tcl + + + + Recovering from errors caused by database access as described in + can lead to an undesirable + situation where some operations succeed before one of them fails, + and after recovering from that error the data is left in an + inconsistent state. PL/Tcl offers a solution to this problem in + the form of explicit subtransactions. + + + + Consider a function that implements a transfer between two accounts: + +CREATE FUNCTION transfer_funds() RETURNS void AS $$ + if [catch { + spi_exec "UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'" + spi_exec "UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'" + } errormsg] { + set result [format "error transferring funds: %s" $errormsg] + } else { + set result "funds transferred successfully" + } + spi_exec "INSERT INTO operations (result) VALUES ('[quote $result]')" +$$ LANGUAGE pltcl; + + If the second UPDATE statement results in an + exception being raised, this function will log the failure, but + the result of the first UPDATE will + nevertheless be committed. In other words, the funds will be + withdrawn from Joe's account, but will not be transferred to + Mary's account. This happens because each spi_exec + is a separate subtransaction, and only one of those subtransactions + got rolled back. + + + + To handle such cases, you can wrap multiple database operations in an + explicit subtransaction, which will succeed or roll back as a whole. + PL/Tcl provides a subtransaction command to manage + this. We can rewrite our function as: + +CREATE FUNCTION transfer_funds2() RETURNS void AS $$ + if [catch { + subtransaction { + spi_exec "UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'" + spi_exec "UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'" + } + } errormsg] { + set result [format "error transferring funds: %s" $errormsg] + } else { + set result "funds transferred successfully" + } + spi_exec "INSERT INTO operations (result) VALUES ('[quote $result]')" +$$ LANGUAGE pltcl; + + Note that use of catch is still required for this + purpose. Otherwise the error would propagate to the top level of the + function, preventing the desired insertion into + the operations table. + The subtransaction command does not trap errors, it + only assures that all database operations executed inside its scope will + be rolled back together when an error is reported. + + + + A rollback of an explicit subtransaction occurs on any error reported + by the contained Tcl code, not only errors originating from database + access. Thus a regular Tcl exception raised inside + a subtransaction command will also cause the + subtransaction to be rolled back. However, non-error exits out of the + contained Tcl code (for instance, due to return) do + not cause a rollback. + + + + + Transaction Management + + + In a procedure called from the top level or an anonymous code block + (DO command) called from the top level it is possible + to control transactions. To commit the current transaction, call the + commit command. To roll back the current transaction, + call the rollback command. (Note that it is not + possible to run the SQL commands COMMIT or + ROLLBACK via spi_exec or similar. + It has to be done using these functions.) After a transaction is ended, + a new transaction is automatically started, so there is no separate + command for that. + + + + Here is an example: + +CREATE PROCEDURE transaction_test1() +LANGUAGE pltcl +AS $$ +for {set i 0} {$i < 10} {incr i} { + spi_exec "INSERT INTO test1 (a) VALUES ($i)" + if {$i % 2 == 0} { + commit + } else { + rollback + } +} +$$; + +CALL transaction_test1(); + + + + + Transactions cannot be ended when an explicit subtransaction is active. + + + + + PL/Tcl Configuration + + + This section lists configuration parameters that + affect PL/Tcl. + + + + + + + pltcl.start_proc (string) + + pltcl.start_proc configuration parameter + + + + + This parameter, if set to a nonempty string, specifies the name + (possibly schema-qualified) of a parameterless PL/Tcl function that + is to be executed whenever a new Tcl interpreter is created for + PL/Tcl. Such a function can perform per-session initialization, such + as loading additional Tcl code. A new Tcl interpreter is created + when a PL/Tcl function is first executed in a database session, or + when an additional interpreter has to be created because a PL/Tcl + function is called by a new SQL role. + + + + The referenced function must be written in the pltcl + language, and must not be marked SECURITY DEFINER. + (These restrictions ensure that it runs in the interpreter it's + supposed to initialize.) The current user must have permission to + call it, too. + + + + If the function fails with an error it will abort the function call + that caused the new interpreter to be created and propagate out to + the calling query, causing the current transaction or subtransaction + to be aborted. Any actions already done within Tcl won't be undone; + however, that interpreter won't be used again. If the language is + used again the initialization will be attempted again within a fresh + Tcl interpreter. + + + + Only superusers can change this setting. Although this setting + can be changed within a session, such changes will not affect Tcl + interpreters that have already been created. + + + + + + + pltclu.start_proc (string) + + pltclu.start_proc configuration parameter + + + + + This parameter is exactly like pltcl.start_proc, + except that it applies to PL/TclU. The referenced function must + be written in the pltclu language. + + + + + + + + + Tcl Procedure Names + + + In PostgreSQL, the same function name can be used for + different function definitions as long as the number of arguments or their types + differ. Tcl, however, requires all procedure names to be distinct. + PL/Tcl deals with this by making the internal Tcl procedure names contain + the object + ID of the function from the system table pg_proc as part of their name. Thus, + PostgreSQL functions with the same name + and different argument types will be different Tcl procedures, too. This + is not normally a concern for a PL/Tcl programmer, but it might be visible + when debugging. + + + + diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml new file mode 100644 index 000000000000..d96c3d0f0cd3 --- /dev/null +++ b/doc/src/sgml/postgres-fdw.sgml @@ -0,0 +1,967 @@ + + + + postgres_fdw + + + postgres_fdw + + + + The postgres_fdw module provides the foreign-data wrapper + postgres_fdw, which can be used to access data + stored in external PostgreSQL servers. + + + + The functionality provided by this module overlaps substantially + with the functionality of the older module. + But postgres_fdw provides more transparent and + standards-compliant syntax for accessing remote tables, and can give + better performance in many cases. + + + + To prepare for remote access using postgres_fdw: + + + + Install the postgres_fdw extension using . + + + + + Create a foreign server object, using , + to represent each remote database you want to connect to. + Specify connection information, except user and + password, as options of the server object. + + + + + Create a user mapping, using , for + each database user you want to allow to access each foreign server. + Specify the remote user name and password to use as + user and password options of the + user mapping. + + + + + Create a foreign table, using + or , + for each remote table you want to access. The columns of the foreign + table must match the referenced remote table. You can, however, use + table and/or column names different from the remote table's, if you + specify the correct remote names as options of the foreign table object. + + + + + + + Now you need only SELECT from a foreign table to access + the data stored in its underlying remote table. You can also modify + the remote table using INSERT, UPDATE, + DELETE, or TRUNCATE. + (Of course, the remote user you have specified in your user mapping must + have privileges to do these things.) + + + + Note that the ONLY option specified in + SELECT, UPDATE, + DELETE or TRUNCATE + has no effect when accessing or modifying the remote table. + + + + Note that postgres_fdw currently lacks support for + INSERT statements with an ON CONFLICT DO + UPDATE clause. However, the ON CONFLICT DO NOTHING + clause is supported, provided a unique index inference specification + is omitted. + Note also that postgres_fdw supports row movement + invoked by UPDATE statements executed on partitioned + tables, but it currently does not handle the case where a remote partition + chosen to insert a moved row into is also an UPDATE + target partition that will be updated elsewhere in the same command. + + + + It is generally recommended that the columns of a foreign table be declared + with exactly the same data types, and collations if applicable, as the + referenced columns of the remote table. Although postgres_fdw + is currently rather forgiving about performing data type conversions at + need, surprising semantic anomalies may arise when types or collations do + not match, due to the remote server interpreting WHERE clauses + slightly differently from the local server. + + + + Note that a foreign table can be declared with fewer columns, or with a + different column order, than its underlying remote table has. Matching + of columns to the remote table is by name, not position. + + + + FDW Options of postgres_fdw + + + Connection Options + + + A foreign server using the postgres_fdw foreign data wrapper + can have the same options that libpq accepts in + connection strings, as described in , + except that these options are not allowed or have special handling: + + + + + user, password and sslpassword (specify these + in a user mapping, instead, or use a service file) + + + + + client_encoding (this is automatically set from the local + server encoding) + + + + + fallback_application_name (always set to + postgres_fdw) + + + + + sslkey and sslcert - these may + appear in either or both a connection and a user + mapping. If both are present, the user mapping setting overrides the + connection setting. + + + + + + + Only superusers may create or modify user mappings with the + sslcert or sslkey settings. + + + Only superusers may connect to foreign servers without password + authentication, so always specify the password option + for user mappings belonging to non-superusers. + + + A superuser may override this check on a per-user-mapping basis by setting + the user mapping option password_required 'false', e.g., + +ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw +OPTIONS (ADD password_required 'false'); + + To prevent unprivileged users from exploiting the authentication rights + of the unix user the postgres server is running as to escalate to superuser + rights, only the superuser may set this option on a user mapping. + + + Care is required to ensure that this does not allow the mapped + user the ability to connect as superuser to the mapped database per + CVE-2007-3278 and CVE-2007-6601. Don't set + password_required=false + on the public role. Keep in mind that the mapped + user can potentially use any client certificates, + .pgpass, + .pg_service.conf etc in the unix home directory of the + system user the postgres server runs as. They can also use any trust + relationship granted by authentication modes like peer + or ident authentication. + + + + + Object Name Options + + + These options can be used to control the names used in SQL statements + sent to the remote PostgreSQL server. These + options are needed when a foreign table is created with names different + from the underlying remote table's names. + + + + + + schema_name + + + This option, which can be specified for a foreign table, gives the + schema name to use for the foreign table on the remote server. If this + option is omitted, the name of the foreign table's schema is used. + + + + + + table_name + + + This option, which can be specified for a foreign table, gives the + table name to use for the foreign table on the remote server. If this + option is omitted, the foreign table's name is used. + + + + + + column_name + + + This option, which can be specified for a column of a foreign table, + gives the column name to use for the column on the remote server. + If this option is omitted, the column's name is used. + + + + + + + + + + Cost Estimation Options + + + postgres_fdw retrieves remote data by executing queries + against remote servers, so ideally the estimated cost of scanning a + foreign table should be whatever it costs to be done on the remote + server, plus some overhead for communication. The most reliable way to + get such an estimate is to ask the remote server and then add something + for overhead — but for simple queries, it may not be worth the cost + of an additional remote query to get a cost estimate. + So postgres_fdw provides the following options to control + how cost estimation is done: + + + + + + use_remote_estimate + + + This option, which can be specified for a foreign table or a foreign + server, controls whether postgres_fdw issues remote + EXPLAIN commands to obtain cost estimates. + A setting for a foreign table overrides any setting for its server, + but only for that table. + The default is false. + + + + + + fdw_startup_cost + + + This option, which can be specified for a foreign server, is a numeric + value that is added to the estimated startup cost of any foreign-table + scan on that server. This represents the additional overhead of + establishing a connection, parsing and planning the query on the + remote side, etc. + The default value is 100. + + + + + + fdw_tuple_cost + + + This option, which can be specified for a foreign server, is a numeric + value that is used as extra cost per-tuple for foreign-table + scans on that server. This represents the additional overhead of + data transfer between servers. You might increase or decrease this + number to reflect higher or lower network delay to the remote server. + The default value is 0.01. + + + + + + + + When use_remote_estimate is true, + postgres_fdw obtains row count and cost estimates from the + remote server and then adds fdw_startup_cost and + fdw_tuple_cost to the cost estimates. When + use_remote_estimate is false, + postgres_fdw performs local row count and cost estimation + and then adds fdw_startup_cost and + fdw_tuple_cost to the cost estimates. This local + estimation is unlikely to be very accurate unless local copies of the + remote table's statistics are available. Running + on the foreign table is the way to update + the local statistics; this will perform a scan of the remote table and + then calculate and store statistics just as though the table were local. + Keeping local statistics can be a useful way to reduce per-query planning + overhead for a remote table — but if the remote table is + frequently updated, the local statistics will soon be obsolete. + + + + + + Remote Execution Options + + + By default, only WHERE clauses using built-in operators and + functions will be considered for execution on the remote server. Clauses + involving non-built-in functions are checked locally after rows are + fetched. If such functions are available on the remote server and can be + relied on to produce the same results as they do locally, performance can + be improved by sending such WHERE clauses for remote + execution. This behavior can be controlled using the following option: + + + + + + extensions + + + This option is a comma-separated list of names + of PostgreSQL extensions that are installed, in + compatible versions, on both the local and remote servers. Functions + and operators that are immutable and belong to a listed extension will + be considered shippable to the remote server. + This option can only be specified for foreign servers, not per-table. + + + + When using the extensions option, it is the + user's responsibility that the listed extensions exist and behave + identically on both the local and remote servers. Otherwise, remote + queries may fail or behave unexpectedly. + + + + + + fetch_size + + + This option specifies the number of rows postgres_fdw + should get in each fetch operation. It can be specified for a foreign + table or a foreign server. The option specified on a table overrides + an option specified for the server. + The default is 100. + + + + + + batch_size + + + This option specifies the number of rows postgres_fdw + should insert in each insert operation. It can be specified for a + foreign table or a foreign server. The option specified on a table + overrides an option specified for the server. + The default is 1. + + + + Note the actual number of rows postgres_fdw inserts at + once depends on the number of columns and the provided + batch_size value. The batch is executed as a single + query, and the libpq protocol (which postgres_fdw + uses to connect to a remote server) limits the number of parameters in a + single query to 65535. When the number of columns * batch_size + exceeds the limit, the batch_size will be adjusted to + avoid an error. + + + + + + + + + + Asynchronous Execution Options + + + postgres_fdw supports asynchronous execution, which + runs multiple parts of an Append node + concurrently rather than serially to improve performance. + This execution can be controlled using the following option: + + + + + + async_capable + + + This option controls whether postgres_fdw allows + foreign tables to be scanned concurrently for asynchronous execution. + It can be specified for a foreign table or a foreign server. + A table-level option overrides a server-level option. + The default is false. + + + + In order to ensure that the data being returned from a foreign server + is consistent, postgres_fdw will only open one + connection for a given foreign server and will run all queries against + that server sequentially even if there are multiple foreign tables + involved, unless those tables are subject to different user mappings. + In such a case, it may be more performant to disable this option to + eliminate the overhead associated with running queries asynchronously. + + + + Asynchronous execution is applied even when an + Append node contains subplan(s) executed + synchronously as well as subplan(s) executed asynchronously. + In such a case, if the asynchronous subplans are ones processed using + postgres_fdw, tuples from the asynchronous + subplans are not returned until after at least one synchronous subplan + returns all tuples, as that subplan is executed while the asynchronous + subplans are waiting for the results of asynchronous queries sent to + foreign servers. + This behavior might change in a future release. + + + + + + + + + Updatability Options + + + By default all foreign tables using postgres_fdw are assumed + to be updatable. This may be overridden using the following option: + + + + + + updatable + + + This option controls whether postgres_fdw allows foreign + tables to be modified using INSERT, UPDATE and + DELETE commands. It can be specified for a foreign table + or a foreign server. A table-level option overrides a server-level + option. + The default is true. + + + + Of course, if the remote table is not in fact updatable, an error + would occur anyway. Use of this option primarily allows the error to + be thrown locally without querying the remote server. Note however + that the information_schema views will report a + postgres_fdw foreign table to be updatable (or not) + according to the setting of this option, without any check of the + remote server. + + + + + + + + + Truncatability Options + + + By default all foreign tables using postgres_fdw are assumed + to be truncatable. This may be overridden using the following option: + + + + + + truncatable + + + This option controls whether postgres_fdw allows + foreign tables to be truncated using the TRUNCATE + command. It can be specified for a foreign table or a foreign server. + A table-level option overrides a server-level option. + The default is true. + + + + Of course, if the remote table is not in fact truncatable, an error + would occur anyway. Use of this option primarily allows the error to + be thrown locally without querying the remote server. + + + + + + + + Importing Options + + + postgres_fdw is able to import foreign table definitions + using . This command creates + foreign table definitions on the local server that match tables or + views present on the remote server. If the remote tables to be imported + have columns of user-defined data types, the local server must have + compatible types of the same names. + + + + Importing behavior can be customized with the following options + (given in the IMPORT FOREIGN SCHEMA command): + + + + + import_collate + + + This option controls whether column COLLATE options + are included in the definitions of foreign tables imported + from a foreign server. The default is true. You might + need to turn this off if the remote server has a different set of + collation names than the local server does, which is likely to be the + case if it's running on a different operating system. + + + + + import_default + + + This option controls whether column DEFAULT expressions + are included in the definitions of foreign tables imported + from a foreign server. The default is false. If you + enable this option, be wary of defaults that might get computed + differently on the local server than they would be on the remote + server; nextval() is a common source of problems. + The IMPORT will fail altogether if an imported default + expression uses a function or operator that does not exist locally. + + + + + import_not_null + + + This option controls whether column NOT NULL + constraints are included in the definitions of foreign tables imported + from a foreign server. The default is true. + + + + + + + Note that constraints other than NOT NULL will never be + imported from the remote tables. Although PostgreSQL + does support check constraints on foreign tables, there is no + provision for importing them automatically, because of the risk that a + constraint expression could evaluate differently on the local and remote + servers. Any such inconsistency in the behavior of a check + constraint could lead to hard-to-detect errors in query optimization. + So if you wish to import check constraints, you must do so + manually, and you should verify the semantics of each one carefully. + For more detail about the treatment of check constraints on + foreign tables, see . + + + + Tables or foreign tables which are partitions of some other table are + imported only when they are explicitly specified in + LIMIT TO clause. Otherwise they are automatically + excluded from . + Since all data can be accessed through the partitioned table + which is the root of the partitioning hierarchy, importing only + partitioned tables should allow access to all the data without + creating extra objects. + + + + + + Connection Management Options + + + By default, all connections that postgres_fdw + establishes to foreign servers are kept open in the local session + for re-use. + + + + + + keep_connections + + + This option controls whether postgres_fdw keeps + the connections to the foreign server open so that subsequent + queries can re-use them. It can only be specified for a foreign server. + The default is on. If set to off, + all connections to this foreign server will be discarded at the end of + each transaction. + + + + + + + + + + Functions + + + + postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record + + + This function returns the foreign server names of all the open + connections that postgres_fdw established from + the local session to the foreign servers. It also returns whether + each connection is valid or not. false is returned + if the foreign server connection is used in the current local + transaction but its foreign server or user mapping is changed or + dropped (Note that server name of an invalid connection will be + NULL if the server is dropped), + and then such invalid connection will be closed at + the end of that transaction. true is returned + otherwise. If there are no open connections, no record is returned. + Example usage of the function: + +postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; + server_name | valid +-------------+------- + loopback1 | t + loopback2 | f + + + + + + + postgres_fdw_disconnect(server_name text) returns boolean + + + This function discards the open connections that are established by + postgres_fdw from the local session to + the foreign server with the given name. Note that there can be + multiple connections to the given server using different user mappings. + If the connections are used in the current local transaction, + they are not disconnected and warning messages are reported. + This function returns true if it disconnects + at least one connection, otherwise false. + If no foreign server with the given name is found, an error is reported. + Example usage of the function: + +postgres=# SELECT postgres_fdw_disconnect('loopback1'); + postgres_fdw_disconnect +------------------------- + t + + + + + + + postgres_fdw_disconnect_all() returns boolean + + + This function discards all the open connections that are established by + postgres_fdw from the local session to + foreign servers. If the connections are used in the current local + transaction, they are not disconnected and warning messages are reported. + This function returns true if it disconnects + at least one connection, otherwise false. + Example usage of the function: + +postgres=# SELECT postgres_fdw_disconnect_all(); + postgres_fdw_disconnect_all +----------------------------- + t + + + + + + + + + + Connection Management + + + postgres_fdw establishes a connection to a + foreign server during the first query that uses a foreign table + associated with the foreign server. By default this connection + is kept and re-used for subsequent queries in the same session. + This behavior can be controlled using + keep_connections option for a foreign server. If + multiple user identities (user mappings) are used to access the foreign + server, a connection is established for each user mapping. + + + + When changing the definition of or removing a foreign server or + a user mapping, the associated connections are closed. + But note that if any connections are in use in the current local transaction, + they are kept until the end of the transaction. + Closed connections will be re-established when they are necessary + by future queries using a foreign table. + + + + Once a connection to a foreign server has been established, + it's by default kept until the local or corresponding remote + session exits. To disconnect a connection explicitly, + keep_connections option for a foreign server + may be disabled, or + postgres_fdw_disconnect and + postgres_fdw_disconnect_all functions + may be used. For example, these are useful to close + connections that are no longer necessary, thereby releasing + connections on the foreign server. + + + + + Transaction Management + + + During a query that references any remote tables on a foreign server, + postgres_fdw opens a transaction on the + remote server if one is not already open corresponding to the current + local transaction. The remote transaction is committed or aborted when + the local transaction commits or aborts. Savepoints are similarly + managed by creating corresponding remote savepoints. + + + + The remote transaction uses SERIALIZABLE + isolation level when the local transaction has SERIALIZABLE + isolation level; otherwise it uses REPEATABLE READ + isolation level. This choice ensures that if a query performs multiple + table scans on the remote server, it will get snapshot-consistent results + for all the scans. A consequence is that successive queries within a + single transaction will see the same data from the remote server, even if + concurrent updates are occurring on the remote server due to other + activities. That behavior would be expected anyway if the local + transaction uses SERIALIZABLE or REPEATABLE READ + isolation level, but it might be surprising for a READ + COMMITTED local transaction. A future + PostgreSQL release might modify these rules. + + + + Note that it is currently not supported by + postgres_fdw to prepare the remote transaction for + two-phase commit. + + + + + Remote Query Optimization + + + postgres_fdw attempts to optimize remote queries to reduce + the amount of data transferred from foreign servers. This is done by + sending query WHERE clauses to the remote server for + execution, and by not retrieving table columns that are not needed for + the current query. To reduce the risk of misexecution of queries, + WHERE clauses are not sent to the remote server unless they use + only data types, operators, and functions that are built-in or belong to an + extension that's listed in the foreign server's extensions + option. Operators and functions in such clauses must + be IMMUTABLE as well. + For an UPDATE or DELETE query, + postgres_fdw attempts to optimize the query execution by + sending the whole query to the remote server if there are no query + WHERE clauses that cannot be sent to the remote server, + no local joins for the query, no row-level local BEFORE or + AFTER triggers or stored generated columns on the target + table, and no CHECK OPTION constraints from parent + views. In UPDATE, + expressions to assign to target columns must use only built-in data types, + IMMUTABLE operators, or IMMUTABLE functions, + to reduce the risk of misexecution of the query. + + + + When postgres_fdw encounters a join between foreign tables on + the same foreign server, it sends the entire join to the foreign server, + unless for some reason it believes that it will be more efficient to fetch + rows from each table individually, or unless the table references involved + are subject to different user mappings. While sending the JOIN + clauses, it takes the same precautions as mentioned above for the + WHERE clauses. + + + + The query that is actually sent to the remote server for execution can + be examined using EXPLAIN VERBOSE. + + + + + Remote Query Execution Environment + + + In the remote sessions opened by postgres_fdw, + the parameter is set to + just pg_catalog, so that only built-in objects are visible + without schema qualification. This is not an issue for queries + generated by postgres_fdw itself, because it always + supplies such qualification. However, this can pose a hazard for + functions that are executed on the remote server via triggers or rules + on remote tables. For example, if a remote table is actually a view, + any functions used in that view will be executed with the restricted + search path. It is recommended to schema-qualify all names in such + functions, or else attach SET search_path options + (see ) to such functions + to establish their expected search path environment. + + + + postgres_fdw likewise establishes remote session settings + for various parameters: + + + + is set to UTC + + + + + is set to ISO + + + + + is set to postgres + + + + + is set to 3 for remote + servers 9.0 and newer and is set to 2 for older versions + + + + These are less likely to be problematic than search_path, but + can be handled with function SET options if the need arises. + + + + It is not recommended that you override this behavior by + changing the session-level settings of these parameters; that is likely + to cause postgres_fdw to malfunction. + + + + + Cross-Version Compatibility + + + postgres_fdw can be used with remote servers dating back + to PostgreSQL 8.3. Read-only capability is available + back to 8.1. A limitation however is that postgres_fdw + generally assumes that immutable built-in functions and operators are + safe to send to the remote server for execution, if they appear in a + WHERE clause for a foreign table. Thus, a built-in + function that was added since the remote server's release might be sent + to it for execution, resulting in function does not exist or + a similar error. This type of failure can be worked around by + rewriting the query, for example by embedding the foreign table + reference in a sub-SELECT with OFFSET 0 as an + optimization fence, and placing the problematic function or operator + outside the sub-SELECT. + + + + + Examples + + + Here is an example of creating a foreign table with + postgres_fdw. First install the extension: + + + +CREATE EXTENSION postgres_fdw; + + + + Then create a foreign server using . + In this example we wish to connect to a PostgreSQL server + on host 192.83.123.89 listening on + port 5432. The database to which the connection is made + is named foreign_db on the remote server: + + +CREATE SERVER foreign_server + FOREIGN DATA WRAPPER postgres_fdw + OPTIONS (host '192.83.123.89', port '5432', dbname 'foreign_db'); + + + + + A user mapping, defined with , is + needed as well to identify the role that will be used on the remote + server: + + +CREATE USER MAPPING FOR local_user + SERVER foreign_server + OPTIONS (user 'foreign_user', password 'password'); + + + + + Now it is possible to create a foreign table with + . In this example we + wish to access the table named some_schema.some_table + on the remote server. The local name for it will + be foreign_table: + + +CREATE FOREIGN TABLE foreign_table ( + id integer NOT NULL, + data text +) + SERVER foreign_server + OPTIONS (schema_name 'some_schema', table_name 'some_table'); + + + It's essential that the data types and other properties of the columns + declared in CREATE FOREIGN TABLE match the actual remote table. + Column names must match as well, unless you attach column_name + options to the individual columns to show how they are named in the remote + table. + In many cases, use of IMPORT FOREIGN SCHEMA is + preferable to constructing foreign table definitions manually. + + + + + Author + + Shigeru Hanada shigeru.hanada@gmail.com + + + + diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml new file mode 100644 index 000000000000..d453be390903 --- /dev/null +++ b/doc/src/sgml/postgres.sgml @@ -0,0 +1,299 @@ + + + +%version; + +%filelist; + + + + + + +]> + + + PostgreSQL &version; Documentation + + + The PostgreSQL Global Development Group + PostgreSQL + &version; + &legal; + + + &intro; + + + Tutorial + + + + Welcome to the PostgreSQL Tutorial. The + following few chapters are intended to give a simple introduction + to PostgreSQL, relational database + concepts, and the SQL language to those who are new to any one of + these aspects. We only assume some general knowledge about how to + use computers. No particular Unix or programming experience is + required. This part is mainly intended to give you some hands-on + experience with important aspects of the + PostgreSQL system. It makes no attempt + to be a complete or thorough treatment of the topics it covers. + + + + After you have worked through this tutorial you might want to move + on to reading to gain a more formal knowledge + of the SQL language, or for + information about developing applications for + PostgreSQL. Those who set up and + manage their own server should also read . + + + + &start; + &query; + &advanced; + + + + + The SQL Language + + + + This part describes the use of the SQL language + in PostgreSQL. We start with + describing the general syntax of SQL, then + explain how to create the structures to hold data, how to populate + the database, and how to query it. The middle part lists the + available data types and functions for use in + SQL commands. The rest treats several + aspects that are important for tuning a database for optimal + performance. + + + + The information in this part is arranged so that a novice user can + follow it start to end to gain a full understanding of the topics + without having to refer forward too many times. The chapters are + intended to be self-contained, so that advanced users can read the + chapters individually as they choose. The information in this + part is presented in a narrative fashion in topical units. + Readers looking for a complete description of a particular command + should see . + + + + Readers of this part should know how to connect to a + PostgreSQL database and issue + SQL commands. Readers that are unfamiliar with + these issues are encouraged to read + first. SQL commands are typically entered + using the PostgreSQL interactive terminal + psql, but other programs that have + similar functionality can be used as well. + + + + &syntax; + &ddl; + &dml; + &queries; + &datatype; + &func; + &typeconv; + &indices; + &textsearch; + &mvcc; + &perform; + ∥ + + + + + Server Administration + + + + This part covers topics that are of interest to a + PostgreSQL database administrator. This includes + installation of the software, set up and configuration of the + server, management of users and databases, and maintenance tasks. + Anyone who runs a PostgreSQL server, even for + personal use, but especially in production, should be familiar + with the topics covered in this part. + + + + The information in this part is arranged approximately in the + order in which a new user should read it. But the chapters are + self-contained and can be read individually as desired. The + information in this part is presented in a narrative fashion in + topical units. Readers looking for a complete description of a + particular command should see . + + + + The first few chapters are written so they can be understood + without prerequisite knowledge, so new users who need to set + up their own server can begin their exploration with this part. + The rest of this part is about tuning and management; that material + assumes that the reader is familiar with the general use of + the PostgreSQL database system. Readers are + encouraged to look at and for additional information. + + + + &installbin; + &installation; + &installw; + &runtime; + &config; + &client-auth; + &user-manag; + &manage-ag; + &charset; + &maintenance; + &backup; + &high-availability; + &monitoring; + &diskusage; + &wal; + &logical-replication; + &jit; + ®ress; + + + + + Client Interfaces + + + + This part describes the client programming interfaces distributed + with PostgreSQL. Each of these chapters can be + read independently. Note that there are many other programming + interfaces for client programs that are distributed separately and + contain their own documentation ( + lists some of the more popular ones). Readers of this part should be + familiar with using SQL commands to manipulate + and query the database (see ) and of course + with the programming language that the interface uses. + + + + &libpq; + &lobj; + &ecpg; + &infoschema; + + + + + Server Programming + + + + This part is about extending the server functionality with + user-defined functions, data types, triggers, etc. These are + advanced topics which should probably be approached only after all + the other user documentation about PostgreSQL has + been understood. Later chapters in this part describe the server-side + programming languages available in the + PostgreSQL distribution as well as + general issues concerning server-side programming languages. It + is essential to read at least the earlier sections of (covering functions) before diving into the + material about server-side programming languages. + + + + &extend; + &trigger; + &event-trigger; + &rules; + + &xplang; + &plsql; + &pltcl; + &plperl; + &plpython; + + &spi; + &bgworker; + &logicaldecoding; + &replication-origins; + + + + &reference; + + + Internals + + + + This part contains assorted information that might be of use to + PostgreSQL developers. + + + + &arch-dev; + &catalogs; + &protocol; + &sources; + &nls; + &plhandler; + &fdwhandler; + &tablesample-method; + &custom-scan; + &geqo; + &tableam; + &indexam; + &generic-wal; + &btree; + &gist; + &spgist; + &gin; + &brin; + &storage; + &bki; + &planstats; + &backup-manifest; + + + + + Appendixes + + &errcodes; + &datetime; + &keywords; + &features; + &release; + &contrib; + &external-projects; + &sourcerepo; + &docguide; + &limits; + &acronyms; + &glossary; + &color; + &obsolete; + + + + &biblio; + + + diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml new file mode 100644 index 000000000000..01e87617f405 --- /dev/null +++ b/doc/src/sgml/protocol.sgml @@ -0,0 +1,7595 @@ + + + + Frontend/Backend Protocol + + + protocol + frontend-backend + + + + PostgreSQL uses a message-based protocol + for communication between frontends and backends (clients and servers). + The protocol is supported over TCP/IP and also over + Unix-domain sockets. Port number 5432 has been registered with IANA as + the customary TCP port number for servers supporting this protocol, but + in practice any non-privileged port number can be used. + + + + This document describes version 3.0 of the protocol, implemented in + PostgreSQL 7.4 and later. For descriptions + of the earlier protocol versions, see previous releases of the + PostgreSQL documentation. A single server + can support multiple protocol versions. The initial startup-request + message tells the server which protocol version the client is attempting to + use. If the major version requested by the client is not supported by + the server, the connection will be rejected (for example, this would occur + if the client requested protocol version 4.0, which does not exist as of + this writing). If the minor version requested by the client is not + supported by the server (e.g., the client requests version 3.1, but the + server supports only 3.0), the server may either reject the connection or + may respond with a NegotiateProtocolVersion message containing the highest + minor protocol version which it supports. The client may then choose either + to continue with the connection using the specified protocol version or + to abort the connection. + + + + In order to serve multiple clients efficiently, the server launches + a new backend process for each client. + In the current implementation, a new child + process is created immediately after an incoming connection is detected. + This is transparent to the protocol, however. For purposes of the + protocol, the terms backend and server are + interchangeable; likewise frontend and client + are interchangeable. + + + + Overview + + + The protocol has separate phases for startup and normal operation. + In the startup phase, the frontend opens a connection to the server + and authenticates itself to the satisfaction of the server. (This might + involve a single message, or multiple messages depending on the + authentication method being used.) If all goes well, the server then sends + status information to the frontend, and finally enters normal operation. + Except for the initial startup-request message, this part of the + protocol is driven by the server. + + + + During normal operation, the frontend sends queries and + other commands to the backend, and the backend sends back query results + and other responses. There are a few cases (such as NOTIFY) + wherein the + backend will send unsolicited messages, but for the most part this portion + of a session is driven by frontend requests. + + + + Termination of the session is normally by frontend choice, but can be + forced by the backend in certain cases. In any case, when the backend + closes the connection, it will roll back any open (incomplete) transaction + before exiting. + + + + Within normal operation, SQL commands can be executed through either of + two sub-protocols. In the simple query protocol, the frontend + just sends a textual query string, which is parsed and immediately + executed by the backend. In the extended query protocol, + processing of queries is separated into multiple steps: parsing, + binding of parameter values, and execution. This offers flexibility + and performance benefits, at the cost of extra complexity. + + + + Normal operation has additional sub-protocols for special operations + such as COPY. + + + + Messaging Overview + + + All communication is through a stream of messages. The first byte of a + message identifies the message type, and the next four bytes specify the + length of the rest of the message (this length count includes itself, but + not the message-type byte). The remaining contents of the message are + determined by the message type. For historical reasons, the very first + message sent by the client (the startup message) has no initial + message-type byte. + + + + To avoid losing synchronization with the message stream, both servers and + clients typically read an entire message into a buffer (using the byte + count) before attempting to process its contents. This allows easy + recovery if an error is detected while processing the contents. In + extreme situations (such as not having enough memory to buffer the + message), the receiver can use the byte count to determine how much + input to skip before it resumes reading messages. + + + + Conversely, both servers and clients must take care never to send an + incomplete message. This is commonly done by marshaling the entire message + in a buffer before beginning to send it. If a communications failure + occurs partway through sending or receiving a message, the only sensible + response is to abandon the connection, since there is little hope of + recovering message-boundary synchronization. + + + + + Extended Query Overview + + + In the extended-query protocol, execution of SQL commands is divided + into multiple steps. The state retained between steps is represented + by two types of objects: prepared statements and + portals. A prepared statement represents the result of + parsing and semantic analysis of a textual query string. + A prepared statement is not in itself ready to execute, because it might + lack specific values for parameters. A portal represents + a ready-to-execute or already-partially-executed statement, with any + missing parameter values filled in. (For SELECT statements, + a portal is equivalent to an open cursor, but we choose to use a different + term since cursors don't handle non-SELECT statements.) + + + + The overall execution cycle consists of a parse step, + which creates a prepared statement from a textual query string; a + bind step, which creates a portal given a prepared + statement and values for any needed parameters; and an + execute step that runs a portal's query. In the case of + a query that returns rows (SELECT, SHOW, etc), + the execute step can be told to fetch only + a limited number of rows, so that multiple execute steps might be needed + to complete the operation. + + + + The backend can keep track of multiple prepared statements and portals + (but note that these exist only within a session, and are never shared + across sessions). Existing prepared statements and portals are + referenced by names assigned when they were created. In addition, + an unnamed prepared statement and portal exist. Although these + behave largely the same as named objects, operations on them are optimized + for the case of executing a query only once and then discarding it, + whereas operations on named objects are optimized on the expectation + of multiple uses. + + + + + Formats and Format Codes + + + Data of a particular data type might be transmitted in any of several + different formats. As of PostgreSQL 7.4 + the only supported formats are text and binary, + but the protocol makes provision for future extensions. The desired + format for any value is specified by a format code. + Clients can specify a format code for each transmitted parameter value + and for each column of a query result. Text has format code zero, + binary has format code one, and all other format codes are reserved + for future definition. + + + + The text representation of values is whatever strings are produced + and accepted by the input/output conversion functions for the + particular data type. In the transmitted representation, there is + no trailing null character; the frontend must add one to received + values if it wants to process them as C strings. + (The text format does not allow embedded nulls, by the way.) + + + + Binary representations for integers use network byte order (most + significant byte first). For other data types consult the documentation + or source code to learn about the binary representation. Keep in mind + that binary representations for complex data types might change across + server versions; the text format is usually the more portable choice. + + + + + + Message Flow + + + This section describes the message flow and the semantics of each + message type. (Details of the exact representation of each message + appear in .) There are + several different sub-protocols depending on the state of the + connection: start-up, query, function call, + COPY, and termination. There are also special + provisions for asynchronous operations (including notification + responses and command cancellation), which can occur at any time + after the start-up phase. + + + + Start-up + + + To begin a session, a frontend opens a connection to the server and sends + a startup message. This message includes the names of the user and of the + database the user wants to connect to; it also identifies the particular + protocol version to be used. (Optionally, the startup message can include + additional settings for run-time parameters.) + The server then uses this information and + the contents of its configuration files (such as + pg_hba.conf) to determine + whether the connection is provisionally acceptable, and what additional + authentication is required (if any). + + + + The server then sends an appropriate authentication request message, + to which the frontend must reply with an appropriate authentication + response message (such as a password). + For all authentication methods except GSSAPI, SSPI and SASL, there is at + most one request and one response. In some methods, no response + at all is needed from the frontend, and so no authentication request + occurs. For GSSAPI, SSPI and SASL, multiple exchanges of packets may be + needed to complete the authentication. + + + + The authentication cycle ends with the server either rejecting the + connection attempt (ErrorResponse), or sending AuthenticationOk. + + + + The possible messages from the server in this phase are: + + + + ErrorResponse + + + The connection attempt has been rejected. + The server then immediately closes the connection. + + + + + + AuthenticationOk + + + The authentication exchange is successfully completed. + + + + + + AuthenticationKerberosV5 + + + The frontend must now take part in a Kerberos V5 + authentication dialog (not described here, part of the + Kerberos specification) with the server. If this is + successful, the server responds with an AuthenticationOk, + otherwise it responds with an ErrorResponse. This is no + longer supported. + + + + + + AuthenticationCleartextPassword + + + The frontend must now send a PasswordMessage containing the + password in clear-text form. If + this is the correct password, the server responds with an + AuthenticationOk, otherwise it responds with an ErrorResponse. + + + + + + AuthenticationMD5Password + + + The frontend must now send a PasswordMessage containing the + password (with user name) encrypted via MD5, then encrypted + again using the 4-byte random salt specified in the + AuthenticationMD5Password message. If this is the correct + password, the server responds with an AuthenticationOk, + otherwise it responds with an ErrorResponse. The actual + PasswordMessage can be computed in SQL as concat('md5', + md5(concat(md5(concat(password, username)), random-salt))). + (Keep in mind the md5() function returns its + result as a hex string.) + + + + + + AuthenticationSCMCredential + + + This response is only possible for local Unix-domain connections + on platforms that support SCM credential messages. The frontend + must issue an SCM credential message and then send a single data + byte. (The contents of the data byte are uninteresting; it's + only used to ensure that the server waits long enough to receive + the credential message.) If the credential is acceptable, + the server responds with an + AuthenticationOk, otherwise it responds with an ErrorResponse. + (This message type is only issued by pre-9.1 servers. It may + eventually be removed from the protocol specification.) + + + + + + AuthenticationGSS + + + The frontend must now initiate a GSSAPI negotiation. The frontend + will send a GSSResponse message with the first part of the GSSAPI + data stream in response to this. If further messages are needed, + the server will respond with AuthenticationGSSContinue. + + + + + + AuthenticationSSPI + + + The frontend must now initiate an SSPI negotiation. The frontend + will send a GSSResponse with the first part of the SSPI + data stream in response to this. If further messages are needed, + the server will respond with AuthenticationGSSContinue. + + + + + + AuthenticationGSSContinue + + + This message contains the response data from the previous step + of GSSAPI or SSPI negotiation (AuthenticationGSS, AuthenticationSSPI + or a previous AuthenticationGSSContinue). If the GSSAPI + or SSPI data in this message + indicates more data is needed to complete the authentication, + the frontend must send that data as another GSSResponse message. If + GSSAPI or SSPI authentication is completed by this message, the server + will next send AuthenticationOk to indicate successful authentication + or ErrorResponse to indicate failure. + + + + + + AuthenticationSASL + + + The frontend must now initiate a SASL negotiation, using one of the + SASL mechanisms listed in the message. The frontend will send a + SASLInitialResponse with the name of the selected mechanism, and the + first part of the SASL data stream in response to this. If further + messages are needed, the server will respond with + AuthenticationSASLContinue. See + for details. + + + + + + AuthenticationSASLContinue + + + This message contains challenge data from the previous step of SASL + negotiation (AuthenticationSASL, or a previous + AuthenticationSASLContinue). The frontend must respond with a + SASLResponse message. + + + + + + AuthenticationSASLFinal + + + SASL authentication has completed with additional mechanism-specific + data for the client. The server will next send AuthenticationOk to + indicate successful authentication, or an ErrorResponse to indicate + failure. This message is sent only if the SASL mechanism specifies + additional data to be sent from server to client at completion. + + + + + + NegotiateProtocolVersion + + + The server does not support the minor protocol version requested + by the client, but does support an earlier version of the protocol; + this message indicates the highest supported minor version. This + message will also be sent if the client requested unsupported protocol + options (i.e., beginning with _pq_.) in the + startup packet. This message will be followed by an ErrorResponse or + a message indicating the success or failure of authentication. + + + + + + + + + If the frontend does not support the authentication method + requested by the server, then it should immediately close the + connection. + + + + After having received AuthenticationOk, the frontend must wait + for further messages from the server. In this phase a backend process + is being started, and the frontend is just an interested bystander. + It is still possible for the startup attempt + to fail (ErrorResponse) or the server to decline support for the requested + minor protocol version (NegotiateProtocolVersion), but in the normal case + the backend will send some ParameterStatus messages, BackendKeyData, and + finally ReadyForQuery. + + + + During this phase the backend will attempt to apply any additional + run-time parameter settings that were given in the startup message. + If successful, these values become session defaults. An error causes + ErrorResponse and exit. + + + + The possible messages from the backend in this phase are: + + + + BackendKeyData + + + This message provides secret-key data that the frontend must + save if it wants to be able to issue cancel requests later. + The frontend should not respond to this message, but should + continue listening for a ReadyForQuery message. + + + + + + ParameterStatus + + + This message informs the frontend about the current (initial) + setting of backend parameters, such as or . + The frontend can ignore this message, or record the settings + for its future use; see for + more details. The frontend should not respond to this + message, but should continue listening for a ReadyForQuery + message. + + + + + + ReadyForQuery + + + Start-up is completed. The frontend can now issue commands. + + + + + + ErrorResponse + + + Start-up failed. The connection is closed after sending this + message. + + + + + + NoticeResponse + + + A warning message has been issued. The frontend should + display the message but continue listening for ReadyForQuery + or ErrorResponse. + + + + + + + + The ReadyForQuery message is the same one that the backend will + issue after each command cycle. Depending on the coding needs of + the frontend, it is reasonable to consider ReadyForQuery as + starting a command cycle, or to consider ReadyForQuery as ending the + start-up phase and each subsequent command cycle. + + + + + Simple Query + + + A simple query cycle is initiated by the frontend sending a Query message + to the backend. The message includes an SQL command (or commands) + expressed as a text string. + The backend then sends one or more response + messages depending on the contents of the query command string, + and finally a ReadyForQuery response message. ReadyForQuery + informs the frontend that it can safely send a new command. + (It is not actually necessary for the frontend to wait for + ReadyForQuery before issuing another command, but the frontend must + then take responsibility for figuring out what happens if the earlier + command fails and already-issued later commands succeed.) + + + + The possible response messages from the backend are: + + + + CommandComplete + + + An SQL command completed normally. + + + + + + CopyInResponse + + + The backend is ready to copy data from the frontend to a + table; see . + + + + + + CopyOutResponse + + + The backend is ready to copy data from a table to the + frontend; see . + + + + + + RowDescription + + + Indicates that rows are about to be returned in response to + a SELECT, FETCH, etc query. + The contents of this message describe the column layout of the rows. + This will be followed by a DataRow message for each row being returned + to the frontend. + + + + + + DataRow + + + One of the set of rows returned by + a SELECT, FETCH, etc query. + + + + + + EmptyQueryResponse + + + An empty query string was recognized. + + + + + + ErrorResponse + + + An error has occurred. + + + + + + ReadyForQuery + + + Processing of the query string is complete. A separate + message is sent to indicate this because the query string might + contain multiple SQL commands. (CommandComplete marks the + end of processing one SQL command, not the whole string.) + ReadyForQuery will always be sent, whether processing + terminates successfully or with an error. + + + + + + NoticeResponse + + + A warning message has been issued in relation to the query. + Notices are in addition to other responses, i.e., the backend + will continue processing the command. + + + + + + + + + The response to a SELECT query (or other queries that + return row sets, such as EXPLAIN or SHOW) + normally consists of RowDescription, zero or more + DataRow messages, and then CommandComplete. + COPY to or from the frontend invokes special protocol + as described in . + All other query types normally produce only + a CommandComplete message. + + + + Since a query string could contain several queries (separated by + semicolons), there might be several such response sequences before the + backend finishes processing the query string. ReadyForQuery is issued + when the entire string has been processed and the backend is ready to + accept a new query string. + + + + If a completely empty (no contents other than whitespace) query string + is received, the response is EmptyQueryResponse followed by ReadyForQuery. + + + + In the event of an error, ErrorResponse is issued followed by + ReadyForQuery. All further processing of the query string is aborted by + ErrorResponse (even if more queries remained in it). Note that this + might occur partway through the sequence of messages generated by an + individual query. + + + + In simple Query mode, the format of retrieved values is always text, + except when the given command is a FETCH from a cursor + declared with the BINARY option. In that case, the + retrieved values are in binary format. The format codes given in + the RowDescription message tell which format is being used. + + + + A frontend must be prepared to accept ErrorResponse and + NoticeResponse messages whenever it is expecting any other type of + message. See also concerning messages + that the backend might generate due to outside events. + + + + Recommended practice is to code frontends in a state-machine style + that will accept any message type at any time that it could make sense, + rather than wiring in assumptions about the exact sequence of messages. + + + + Multiple Statements in a Simple Query + + + When a simple Query message contains more than one SQL statement + (separated by semicolons), those statements are executed as a single + transaction, unless explicit transaction control commands are included + to force a different behavior. For example, if the message contains + +INSERT INTO mytable VALUES(1); +SELECT 1/0; +INSERT INTO mytable VALUES(2); + + then the divide-by-zero failure in the SELECT will force + rollback of the first INSERT. Furthermore, because + execution of the message is abandoned at the first error, the second + INSERT is never attempted at all. + + + + If instead the message contains + +BEGIN; +INSERT INTO mytable VALUES(1); +COMMIT; +INSERT INTO mytable VALUES(2); +SELECT 1/0; + + then the first INSERT is committed by the + explicit COMMIT command. The second INSERT + and the SELECT are still treated as a single transaction, + so that the divide-by-zero failure will roll back the + second INSERT, but not the first one. + + + + This behavior is implemented by running the statements in a + multi-statement Query message in an implicit transaction + block unless there is some explicit transaction block for them to + run in. The main difference between an implicit transaction block and + a regular one is that an implicit block is closed automatically at the + end of the Query message, either by an implicit commit if there was no + error, or an implicit rollback if there was an error. This is similar + to the implicit commit or rollback that happens for a statement + executed by itself (when not in a transaction block). + + + + If the session is already in a transaction block, as a result of + a BEGIN in some previous message, then the Query message + simply continues that transaction block, whether the message contains + one statement or several. However, if the Query message contains + a COMMIT or ROLLBACK closing the existing + transaction block, then any following statements are executed in an + implicit transaction block. + Conversely, if a BEGIN appears in a multi-statement Query + message, then it starts a regular transaction block that will only be + terminated by an explicit COMMIT or ROLLBACK, + whether that appears in this Query message or a later one. + If the BEGIN follows some statements that were executed as + an implicit transaction block, those statements are not immediately + committed; in effect, they are retroactively included into the new + regular transaction block. + + + + A COMMIT or ROLLBACK appearing in an implicit + transaction block is executed as normal, closing the implicit block; + however, a warning will be issued since a COMMIT + or ROLLBACK without a previous BEGIN might + represent a mistake. If more statements follow, a new implicit + transaction block will be started for them. + + + + Savepoints are not allowed in an implicit transaction block, since + they would conflict with the behavior of automatically closing the + block upon any error. + + + + Remember that, regardless of any transaction control commands that may + be present, execution of the Query message stops at the first error. + Thus for example given + +BEGIN; +SELECT 1/0; +ROLLBACK; + + in a single Query message, the session will be left inside a failed + regular transaction block, since the ROLLBACK is not + reached after the divide-by-zero error. Another ROLLBACK + will be needed to restore the session to a usable state. + + + + Another behavior of note is that initial lexical and syntactic + analysis is done on the entire query string before any of it is + executed. Thus simple errors (such as a misspelled keyword) in later + statements can prevent execution of any of the statements. This + is normally invisible to users since the statements would all roll + back anyway when done as an implicit transaction block. However, + it can be visible when attempting to do multiple transactions within a + multi-statement Query. For instance, if a typo turned our previous + example into + +BEGIN; +INSERT INTO mytable VALUES(1); +COMMIT; +INSERT INTO mytable VALUES(2); +SELCT 1/0; + + then none of the statements would get run, resulting in the visible + difference that the first INSERT is not committed. + Errors detected at semantic analysis or later, such as a misspelled + table or column name, do not have this effect. + + + + + + Extended Query + + + The extended query protocol breaks down the above-described simple + query protocol into multiple steps. The results of preparatory + steps can be re-used multiple times for improved efficiency. + Furthermore, additional features are available, such as the possibility + of supplying data values as separate parameters instead of having to + insert them directly into a query string. + + + + In the extended protocol, the frontend first sends a Parse message, + which contains a textual query string, optionally some information + about data types of parameter placeholders, and the + name of a destination prepared-statement object (an empty string + selects the unnamed prepared statement). The response is + either ParseComplete or ErrorResponse. Parameter data types can be + specified by OID; if not given, the parser attempts to infer the + data types in the same way as it would do for untyped literal string + constants. + + + + + A parameter data type can be left unspecified by setting it to zero, + or by making the array of parameter type OIDs shorter than the + number of parameter symbols ($n) + used in the query string. Another special case is that a parameter's + type can be specified as void (that is, the OID of the + void pseudo-type). This is meant to allow parameter symbols + to be used for function parameters that are actually OUT parameters. + Ordinarily there is no context in which a void parameter + could be used, but if such a parameter symbol appears in a function's + parameter list, it is effectively ignored. For example, a function + call such as foo($1,$2,$3,$4) could match a function with + two IN and two OUT arguments, if $3 and $4 + are specified as having type void. + + + + + + The query string contained in a Parse message cannot include more + than one SQL statement; else a syntax error is reported. This + restriction does not exist in the simple-query protocol, but it + does exist in the extended protocol, because allowing prepared + statements or portals to contain multiple commands would complicate + the protocol unduly. + + + + + If successfully created, a named prepared-statement object lasts till + the end of the current session, unless explicitly destroyed. An unnamed + prepared statement lasts only until the next Parse statement specifying + the unnamed statement as destination is issued. (Note that a simple + Query message also destroys the unnamed statement.) Named prepared + statements must be explicitly closed before they can be redefined by + another Parse message, but this is not required for the unnamed statement. + Named prepared statements can also be created and accessed at the SQL + command level, using PREPARE and EXECUTE. + + + + Once a prepared statement exists, it can be readied for execution using a + Bind message. The Bind message gives the name of the source prepared + statement (empty string denotes the unnamed prepared statement), the name + of the destination portal (empty string denotes the unnamed portal), and + the values to use for any parameter placeholders present in the prepared + statement. The + supplied parameter set must match those needed by the prepared statement. + (If you declared any void parameters in the Parse message, + pass NULL values for them in the Bind message.) + Bind also specifies the format to use for any data returned + by the query; the format can be specified overall, or per-column. + The response is either BindComplete or ErrorResponse. + + + + + The choice between text and binary output is determined by the format + codes given in Bind, regardless of the SQL command involved. The + BINARY attribute in cursor declarations is irrelevant when + using extended query protocol. + + + + + Query planning typically occurs when the Bind message is processed. + If the prepared statement has no parameters, or is executed repeatedly, + the server might save the created plan and re-use it during subsequent + Bind messages for the same prepared statement. However, it will do so + only if it finds that a generic plan can be created that is not much + less efficient than a plan that depends on the specific parameter values + supplied. This happens transparently so far as the protocol is concerned. + + + + If successfully created, a named portal object lasts till the end of the + current transaction, unless explicitly destroyed. An unnamed portal is + destroyed at the end of the transaction, or as soon as the next Bind + statement specifying the unnamed portal as destination is issued. (Note + that a simple Query message also destroys the unnamed portal.) Named + portals must be explicitly closed before they can be redefined by another + Bind message, but this is not required for the unnamed portal. + Named portals can also be created and accessed at the SQL + command level, using DECLARE CURSOR and FETCH. + + + + Once a portal exists, it can be executed using an Execute message. + The Execute message specifies the portal name (empty string denotes the + unnamed portal) and + a maximum result-row count (zero meaning fetch all rows). + The result-row count is only meaningful for portals + containing commands that return row sets; in other cases the command is + always executed to completion, and the row count is ignored. + The possible + responses to Execute are the same as those described above for queries + issued via simple query protocol, except that Execute doesn't cause + ReadyForQuery or RowDescription to be issued. + + + + If Execute terminates before completing the execution of a portal + (due to reaching a nonzero result-row count), it will send a + PortalSuspended message; the appearance of this message tells the frontend + that another Execute should be issued against the same portal to + complete the operation. The CommandComplete message indicating + completion of the source SQL command is not sent until + the portal's execution is completed. Therefore, an Execute phase is + always terminated by the appearance of exactly one of these messages: + CommandComplete, EmptyQueryResponse (if the portal was created from + an empty query string), ErrorResponse, or PortalSuspended. + + + + At completion of each series of extended-query messages, the frontend + should issue a Sync message. This parameterless message causes the + backend to close the current transaction if it's not inside a + BEGIN/COMMIT transaction block (close + meaning to commit if no error, or roll back if error). Then a + ReadyForQuery response is issued. The purpose of Sync is to provide + a resynchronization point for error recovery. When an error is detected + while processing any extended-query message, the backend issues + ErrorResponse, then reads and discards messages until a Sync is reached, + then issues ReadyForQuery and returns to normal message processing. + (But note that no skipping occurs if an error is detected + while processing Sync — this ensures that there is one + and only one ReadyForQuery sent for each Sync.) + + + + + Sync does not cause a transaction block opened with BEGIN + to be closed. It is possible to detect this situation since the + ReadyForQuery message includes transaction status information. + + + + + In addition to these fundamental, required operations, there are several + optional operations that can be used with extended-query protocol. + + + + The Describe message (portal variant) specifies the name of an existing + portal (or an empty string for the unnamed portal). The response is a + RowDescription message describing the rows that will be returned by + executing the portal; or a NoData message if the portal does not contain a + query that will return rows; or ErrorResponse if there is no such portal. + + + + The Describe message (statement variant) specifies the name of an existing + prepared statement (or an empty string for the unnamed prepared + statement). The response is a ParameterDescription message describing the + parameters needed by the statement, followed by a RowDescription message + describing the rows that will be returned when the statement is eventually + executed (or a NoData message if the statement will not return rows). + ErrorResponse is issued if there is no such prepared statement. Note that + since Bind has not yet been issued, the formats to be used for returned + columns are not yet known to the backend; the format code fields in the + RowDescription message will be zeroes in this case. + + + + + In most scenarios the frontend should issue one or the other variant + of Describe before issuing Execute, to ensure that it knows how to + interpret the results it will get back. + + + + + The Close message closes an existing prepared statement or portal + and releases resources. It is not an error to issue Close against + a nonexistent statement or portal name. The response is normally + CloseComplete, but could be ErrorResponse if some difficulty is + encountered while releasing resources. Note that closing a prepared + statement implicitly closes any open portals that were constructed + from that statement. + + + + The Flush message does not cause any specific output to be generated, + but forces the backend to deliver any data pending in its output + buffers. A Flush must be sent after any extended-query command except + Sync, if the frontend wishes to examine the results of that command before + issuing more commands. Without Flush, messages returned by the backend + will be combined into the minimum possible number of packets to minimize + network overhead. + + + + + The simple Query message is approximately equivalent to the series Parse, + Bind, portal Describe, Execute, Close, Sync, using the unnamed prepared + statement and portal objects and no parameters. One difference is that + it will accept multiple SQL statements in the query string, automatically + performing the bind/describe/execute sequence for each one in succession. + Another difference is that it will not return ParseComplete, BindComplete, + CloseComplete, or NoData messages. + + + + + + Function Call + + + The Function Call sub-protocol allows the client to request a direct + call of any function that exists in the database's + pg_proc system catalog. The client must have + execute permission for the function. + + + + + The Function Call sub-protocol is a legacy feature that is probably best + avoided in new code. Similar results can be accomplished by setting up + a prepared statement that does SELECT function($1, ...). + The Function Call cycle can then be replaced with Bind/Execute. + + + + + A Function Call cycle is initiated by the frontend sending a + FunctionCall message to the backend. The backend then sends one + or more response messages depending on the results of the function + call, and finally a ReadyForQuery response message. ReadyForQuery + informs the frontend that it can safely send a new query or + function call. + + + + The possible response messages from the backend are: + + + + ErrorResponse + + + An error has occurred. + + + + + + FunctionCallResponse + + + The function call was completed and returned the result given + in the message. + (Note that the Function Call protocol can only handle a single + scalar result, not a row type or set of results.) + + + + + + ReadyForQuery + + + Processing of the function call is complete. ReadyForQuery + will always be sent, whether processing terminates + successfully or with an error. + + + + + + NoticeResponse + + + A warning message has been issued in relation to the function + call. Notices are in addition to other responses, i.e., the + backend will continue processing the command. + + + + + + + + + COPY Operations + + + The COPY command allows high-speed bulk data transfer + to or from the server. Copy-in and copy-out operations each switch + the connection into a distinct sub-protocol, which lasts until the + operation is completed. + + + + Copy-in mode (data transfer to the server) is initiated when the + backend executes a COPY FROM STDIN SQL statement. The backend + sends a CopyInResponse message to the frontend. The frontend should + then send zero or more CopyData messages, forming a stream of input + data. (The message boundaries are not required to have anything to do + with row boundaries, although that is often a reasonable choice.) + The frontend can terminate the copy-in mode by sending either a CopyDone + message (allowing successful termination) or a CopyFail message (which + will cause the COPY SQL statement to fail with an + error). The backend then reverts to the command-processing mode it was + in before the COPY started, which will be either simple or + extended query protocol. It will next send either CommandComplete + (if successful) or ErrorResponse (if not). + + + + In the event of a backend-detected error during copy-in mode (including + receipt of a CopyFail message), the backend will issue an ErrorResponse + message. If the COPY command was issued via an extended-query + message, the backend will now discard frontend messages until a Sync + message is received, then it will issue ReadyForQuery and return to normal + processing. If the COPY command was issued in a simple + Query message, the rest of that message is discarded and ReadyForQuery + is issued. In either case, any subsequent CopyData, CopyDone, or CopyFail + messages issued by the frontend will simply be dropped. + + + + The backend will ignore Flush and Sync messages received during copy-in + mode. Receipt of any other non-copy message type constitutes an error + that will abort the copy-in state as described above. (The exception for + Flush and Sync is for the convenience of client libraries that always + send Flush or Sync after an Execute message, without checking whether + the command to be executed is a COPY FROM STDIN.) + + + + Copy-out mode (data transfer from the server) is initiated when the + backend executes a COPY TO STDOUT SQL statement. The backend + sends a CopyOutResponse message to the frontend, followed by + zero or more CopyData messages (always one per row), followed by CopyDone. + The backend then reverts to the command-processing mode it was + in before the COPY started, and sends CommandComplete. + The frontend cannot abort the transfer (except by closing the connection + or issuing a Cancel request), + but it can discard unwanted CopyData and CopyDone messages. + + + + In the event of a backend-detected error during copy-out mode, + the backend will issue an ErrorResponse message and revert to normal + processing. The frontend should treat receipt of ErrorResponse as + terminating the copy-out mode. + + + + It is possible for NoticeResponse and ParameterStatus messages to be + interspersed between CopyData messages; frontends must handle these cases, + and should be prepared for other asynchronous message types as well (see + ). Otherwise, any message type other than + CopyData or CopyDone may be treated as terminating copy-out mode. + + + + There is another Copy-related mode called copy-both, which allows + high-speed bulk data transfer to and from the server. + Copy-both mode is initiated when a backend in walsender mode + executes a START_REPLICATION statement. The + backend sends a CopyBothResponse message to the frontend. Both + the backend and the frontend may then send CopyData messages + until either end sends a CopyDone message. After the client + sends a CopyDone message, the connection goes from copy-both mode to + copy-out mode, and the client may not send any more CopyData messages. + Similarly, when the server sends a CopyDone message, the connection + goes into copy-in mode, and the server may not send any more CopyData + messages. After both sides have sent a CopyDone message, the copy mode + is terminated, and the backend reverts to the command-processing mode. + In the event of a backend-detected error during copy-both mode, + the backend will issue an ErrorResponse message, discard frontend messages + until a Sync message is received, and then issue ReadyForQuery and return + to normal processing. The frontend should treat receipt of ErrorResponse + as terminating the copy in both directions; no CopyDone should be sent + in this case. See for more + information on the subprotocol transmitted over copy-both mode. + + + + The CopyInResponse, CopyOutResponse and CopyBothResponse messages + include fields that inform the frontend of the number of columns + per row and the format codes being used for each column. (As of + the present implementation, all columns in a given COPY + operation will use the same format, but the message design does not + assume this.) + + + + + + Asynchronous Operations + + + There are several cases in which the backend will send messages that + are not specifically prompted by the frontend's command stream. + Frontends must be prepared to deal with these messages at any time, + even when not engaged in a query. + At minimum, one should check for these cases before beginning to + read a query response. + + + + It is possible for NoticeResponse messages to be generated due to + outside activity; for example, if the database administrator commands + a fast database shutdown, the backend will send a NoticeResponse + indicating this fact before closing the connection. Accordingly, + frontends should always be prepared to accept and display NoticeResponse + messages, even when the connection is nominally idle. + + + + ParameterStatus messages will be generated whenever the active + value changes for any of the parameters the backend believes the + frontend should know about. Most commonly this occurs in response + to a SET SQL command executed by the frontend, and + this case is effectively synchronous — but it is also possible + for parameter status changes to occur because the administrator + changed a configuration file and then sent the + SIGHUP signal to the server. Also, + if a SET command is rolled back, an appropriate + ParameterStatus message will be generated to report the current + effective value. + + + + At present there is a hard-wired set of parameters for which + ParameterStatus will be generated: they are + server_version, + server_encoding, + client_encoding, + application_name, + default_transaction_read_only, + in_hot_standby, + is_superuser, + session_authorization, + DateStyle, + IntervalStyle, + TimeZone, + integer_datetimes, and + standard_conforming_strings. + (server_encoding, TimeZone, and + integer_datetimes were not reported by releases before 8.0; + standard_conforming_strings was not reported by releases + before 8.1; + IntervalStyle was not reported by releases before 8.4; + application_name was not reported by releases before + 9.0; + default_transaction_read_only and + in_hot_standby were not reported by releases before + 14.) + Note that + server_version, + server_encoding and + integer_datetimes + are pseudo-parameters that cannot change after startup. + This set might change in the future, or even become configurable. + Accordingly, a frontend should simply ignore ParameterStatus for + parameters that it does not understand or care about. + + + + If a frontend issues a LISTEN command, then the + backend will send a NotificationResponse message (not to be + confused with NoticeResponse!) whenever a + NOTIFY command is executed for the same + channel name. + + + + + At present, NotificationResponse can only be sent outside a + transaction, and thus it will not occur in the middle of a + command-response series, though it might occur just before ReadyForQuery. + It is unwise to design frontend logic that assumes that, however. + Good practice is to be able to accept NotificationResponse at any + point in the protocol. + + + + + + Canceling Requests in Progress + + + During the processing of a query, the frontend might request + cancellation of the query. The cancel request is not sent + directly on the open connection to the backend for reasons of + implementation efficiency: we don't want to have the backend + constantly checking for new input from the frontend during query + processing. Cancel requests should be relatively infrequent, so + we make them slightly cumbersome in order to avoid a penalty in + the normal case. + + + + To issue a cancel request, the frontend opens a new connection to + the server and sends a CancelRequest message, rather than the + StartupMessage message that would ordinarily be sent across a new + connection. The server will process this request and then close + the connection. For security reasons, no direct reply is made to + the cancel request message. + + + + A CancelRequest message will be ignored unless it contains the + same key data (PID and secret key) passed to the frontend during + connection start-up. If the request matches the PID and secret + key for a currently executing backend, the processing of the + current query is aborted. (In the existing implementation, this is + done by sending a special signal to the backend process that is + processing the query.) + + + + The cancellation signal might or might not have any effect — for + example, if it arrives after the backend has finished processing + the query, then it will have no effect. If the cancellation is + effective, it results in the current command being terminated + early with an error message. + + + + The upshot of all this is that for reasons of both security and + efficiency, the frontend has no direct way to tell whether a + cancel request has succeeded. It must continue to wait for the + backend to respond to the query. Issuing a cancel simply improves + the odds that the current query will finish soon, and improves the + odds that it will fail with an error message instead of + succeeding. + + + + Since the cancel request is sent across a new connection to the + server and not across the regular frontend/backend communication + link, it is possible for the cancel request to be issued by any + process, not just the frontend whose query is to be canceled. + This might provide additional flexibility when building + multiple-process applications. It also introduces a security + risk, in that unauthorized persons might try to cancel queries. + The security risk is addressed by requiring a dynamically + generated secret key to be supplied in cancel requests. + + + + + Termination + + + The normal, graceful termination procedure is that the frontend + sends a Terminate message and immediately closes the connection. + On receipt of this message, the backend closes the connection and + terminates. + + + + In rare cases (such as an administrator-commanded database shutdown) + the backend might disconnect without any frontend request to do so. + In such cases the backend will attempt to send an error or notice message + giving the reason for the disconnection before it closes the connection. + + + + Other termination scenarios arise from various failure cases, such as core + dump at one end or the other, loss of the communications link, loss of + message-boundary synchronization, etc. If either frontend or backend sees + an unexpected closure of the connection, it should clean + up and terminate. The frontend has the option of launching a new backend + by recontacting the server if it doesn't want to terminate itself. + Closing the connection is also advisable if an unrecognizable message type + is received, since this probably indicates loss of message-boundary sync. + + + + For either normal or abnormal termination, any open transaction is + rolled back, not committed. One should note however that if a + frontend disconnects while a non-SELECT query + is being processed, the backend will probably finish the query + before noticing the disconnection. If the query is outside any + transaction block (BEGIN ... COMMIT + sequence) then its results might be committed before the + disconnection is recognized. + + + + + <acronym>SSL</acronym> Session Encryption + + + If PostgreSQL was built with + SSL support, frontend/backend communications + can be encrypted using SSL. This provides + communication security in environments where attackers might be + able to capture the session traffic. For more information on + encrypting PostgreSQL sessions with + SSL, see . + + + + To initiate an SSL-encrypted connection, the + frontend initially sends an SSLRequest message rather than a + StartupMessage. The server then responds with a single byte + containing S or N, indicating that it is + willing or unwilling to perform SSL, + respectively. The frontend might close the connection at this point + if it is dissatisfied with the response. To continue after + S, perform an SSL startup handshake + (not described here, part of the SSL + specification) with the server. If this is successful, continue + with sending the usual StartupMessage. In this case the + StartupMessage and all subsequent data will be + SSL-encrypted. To continue after + N, send the usual StartupMessage and proceed without + encryption. + (Alternatively, it is permissible to issue a GSSENCRequest message + after an N response to try to + use GSSAPI encryption instead + of SSL.) + + + + The frontend should also be prepared to handle an ErrorMessage + response to SSLRequest from the server. This would only occur if + the server predates the addition of SSL support + to PostgreSQL. (Such servers are now very ancient, + and likely do not exist in the wild anymore.) + In this case the connection must + be closed, but the frontend might choose to open a fresh connection + and proceed without requesting SSL. + + + + An initial SSLRequest can also be used in a connection that is being + opened to send a CancelRequest message. + + + + While the protocol itself does not provide a way for the server to + force SSL encryption, the administrator can + configure the server to reject unencrypted sessions as a byproduct + of authentication checking. + + + + + <acronym>GSSAPI</acronym> Session Encryption + + + If PostgreSQL was built with + GSSAPI support, frontend/backend communications + can be encrypted using GSSAPI. This provides + communication security in environments where attackers might be + able to capture the session traffic. For more information on + encrypting PostgreSQL sessions with + GSSAPI, see . + + + + To initiate a GSSAPI-encrypted connection, the + frontend initially sends a GSSENCRequest message rather than a + StartupMessage. The server then responds with a single byte + containing G or N, indicating that it + is willing or unwilling to perform GSSAPI encryption, + respectively. The frontend might close the connection at this point + if it is dissatisfied with the response. To continue after + G, using the GSSAPI C bindings as discussed in + RFC 2744 + or equivalent, perform a GSSAPI initialization by + calling gss_init_sec_context() in a loop and sending + the result to the server, starting with an empty input and then with each + result from the server, until it returns no output. When sending the + results of gss_init_sec_context() to the server, + prepend the length of the message as a four byte integer in network byte + order. + To continue after + N, send the usual StartupMessage and proceed without + encryption. + (Alternatively, it is permissible to issue an SSLRequest message + after an N response to try to + use SSL encryption instead + of GSSAPI.) + + + + The frontend should also be prepared to handle an ErrorMessage + response to GSSENCRequest from the server. This would only occur if + the server predates the addition of GSSAPI encryption + support to PostgreSQL. In this case the + connection must be closed, but the frontend might choose to open a fresh + connection and proceed without requesting GSSAPI + encryption. + + + + An initial GSSENCRequest can also be used in a connection that is being + opened to send a CancelRequest message. + + + + Once GSSAPI encryption has been successfully + established, use gss_wrap() to + encrypt the usual StartupMessage and all subsequent data, prepending the + length of the result from gss_wrap() as a four byte + integer in network byte order to the actual encrypted payload. Note that + the server will only accept encrypted packets from the client which are less + than 16kB; gss_wrap_size_limit() should be used by the + client to determine the size of the unencrypted message which will fit + within this limit and larger messages should be broken up into multiple + gss_wrap() calls. Typical segments are 8kB of + unencrypted data, resulting in encrypted packets of slightly larger than 8kB + but well within the 16kB maximum. The server can be expected to not send + encrypted packets of larger than 16kB to the client. + + + + While the protocol itself does not provide a way for the server to + force GSSAPI encryption, the administrator can + configure the server to reject unencrypted sessions as a byproduct + of authentication checking. + + + + + +SASL Authentication + + +SASL is a framework for authentication in connection-oriented +protocols. At the moment, PostgreSQL implements two SASL +authentication mechanisms, SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. More +might be added in the future. The below steps illustrate how SASL +authentication is performed in general, while the next subsection gives +more details on SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. + + + +SASL Authentication Message Flow + + + + To begin a SASL authentication exchange, the server sends an + AuthenticationSASL message. It includes a list of SASL authentication + mechanisms that the server can accept, in the server's preferred order. + + + + + + The client selects one of the supported mechanisms from the list, and sends + a SASLInitialResponse message to the server. The message includes the name + of the selected mechanism, and an optional Initial Client Response, if the + selected mechanism uses that. + + + + + + One or more server-challenge and client-response message will follow. Each + server-challenge is sent in an AuthenticationSASLContinue message, followed + by a response from client in a SASLResponse message. The particulars of + the messages are mechanism specific. + + + + + + Finally, when the authentication exchange is completed successfully, the + server sends an AuthenticationSASLFinal message, followed + immediately by an AuthenticationOk message. The AuthenticationSASLFinal + contains additional server-to-client data, whose content is particular to the + selected authentication mechanism. If the authentication mechanism doesn't + use additional data that's sent at completion, the AuthenticationSASLFinal + message is not sent. + + + + + +On error, the server can abort the authentication at any stage, and send an +ErrorMessage. + + + + SCRAM-SHA-256 Authentication + + + The implemented SASL mechanisms at the moment + are SCRAM-SHA-256 and its variant with channel + binding SCRAM-SHA-256-PLUS. They are described in + detail in RFC 7677 + and RFC 5802. + + + +When SCRAM-SHA-256 is used in PostgreSQL, the server will ignore the user name +that the client sends in the client-first-message. The user name +that was already sent in the startup message is used instead. +PostgreSQL supports multiple character encodings, while SCRAM +dictates UTF-8 to be used for the user name, so it might be impossible to +represent the PostgreSQL user name in UTF-8. + + + +The SCRAM specification dictates that the password is also in UTF-8, and is +processed with the SASLprep algorithm. +PostgreSQL, however, does not require UTF-8 to be used for +the password. When a user's password is set, it is processed with SASLprep +as if it was in UTF-8, regardless of the actual encoding used. However, if +it is not a legal UTF-8 byte sequence, or it contains UTF-8 byte sequences +that are prohibited by the SASLprep algorithm, the raw password will be used +without SASLprep processing, instead of throwing an error. This allows the +password to be normalized when it is in UTF-8, but still allows a non-UTF-8 +password to be used, and doesn't require the system to know which encoding +the password is in. + + + +Channel binding is supported in PostgreSQL builds with +SSL support. The SASL mechanism name for SCRAM with channel binding is +SCRAM-SHA-256-PLUS. The channel binding type used by +PostgreSQL is tls-server-end-point. + + + + In SCRAM without channel binding, the server chooses + a random number that is transmitted to the client to be mixed with the + user-supplied password in the transmitted password hash. While this + prevents the password hash from being successfully retransmitted in + a later session, it does not prevent a fake server between the real + server and client from passing through the server's random value + and successfully authenticating. + + + + SCRAM with channel binding prevents such + man-in-the-middle attacks by mixing the signature of the server's + certificate into the transmitted password hash. While a fake server can + retransmit the real server's certificate, it doesn't have access to the + private key matching that certificate, and therefore cannot prove it is + the owner, causing SSL connection failure. + + + +Example + + + The server sends an AuthenticationSASL message. It includes a list of + SASL authentication mechanisms that the server can accept. + This will be SCRAM-SHA-256-PLUS + and SCRAM-SHA-256 if the server is built with SSL + support, or else just the latter. + + + + + The client responds by sending a SASLInitialResponse message, which + indicates the chosen mechanism, SCRAM-SHA-256 or + SCRAM-SHA-256-PLUS. (A client is free to choose either + mechanism, but for better security it should choose the channel-binding + variant if it can support it.) In the Initial Client response field, the + message contains the SCRAM client-first-message. + The client-first-message also contains the channel + binding type chosen by the client. + + + + + Server sends an AuthenticationSASLContinue message, with a SCRAM + server-first-message as the content. + + + + + Client sends a SASLResponse message, with SCRAM + client-final-message as the content. + + + + + Server sends an AuthenticationSASLFinal message, with the SCRAM + server-final-message, followed immediately by + an AuthenticationOk message. + + + + + + + +Streaming Replication Protocol + + +To initiate streaming replication, the frontend sends the +replication parameter in the startup message. A Boolean +value of true (or on, +yes, 1) tells the backend to go into +physical replication walsender mode, wherein a small set of replication +commands, shown below, can be issued instead of SQL statements. + + + +Passing database as the value for the +replication parameter instructs the backend to go into +logical replication walsender mode, connecting to the database specified in +the dbname parameter. In logical replication walsender +mode, the replication commands shown below as well as normal SQL commands can +be issued. + + + +In either physical replication or logical replication walsender mode, only the +simple query protocol can be used. + + + + For the purpose of testing replication commands, you can make a replication + connection via psql or any other + libpq-using tool with a connection string including + the replication option, + e.g.: + +psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;" + + However, it is often more useful to use + (for physical replication) or + (for logical replication). + + + +Replication commands are logged in the server log when + is enabled. + + + +The commands accepted in replication mode are: + + + IDENTIFY_SYSTEM + IDENTIFY_SYSTEM + + + + Requests the server to identify itself. Server replies with a result + set of a single row, containing four fields: + + + + + + + systemid (text) + + + + The unique system identifier identifying the cluster. This + can be used to check that the base backup used to initialize the + standby came from the same cluster. + + + + + + + timeline (int4) + + + + Current timeline ID. Also useful to check that the standby is + consistent with the primary. + + + + + + + xlogpos (text) + + + + Current WAL flush location. Useful to get a known location in the + write-ahead log where streaming can start. + + + + + + + dbname (text) + + + + Database connected to or null. + + + + + + + + + + + SHOW name + SHOW + + + + Requests the server to send the current setting of a run-time parameter. + This is similar to the SQL command . + + + + + name + + + The name of a run-time parameter. Available parameters are documented + in . + + + + + + + + + TIMELINE_HISTORY tli + TIMELINE_HISTORY + + + + Requests the server to send over the timeline history file for timeline + tli. Server replies with a + result set of a single row, containing two fields. While the fields + are labeled as text, they effectively return raw bytes, + with no encoding conversion: + + + + + + + filename (text) + + + + File name of the timeline history file, e.g., 00000002.history. + + + + + + + content (text) + + + + Contents of the timeline history file. + + + + + + + + + + + CREATE_REPLICATION_SLOT slot_name [ TEMPORARY ] { PHYSICAL [ RESERVE_WAL ] | LOGICAL output_plugin [ EXPORT_SNAPSHOT | NOEXPORT_SNAPSHOT | USE_SNAPSHOT ] } + CREATE_REPLICATION_SLOT + + + + Create a physical or logical replication + slot. See for more about + replication slots. + + + + slot_name + + + The name of the slot to create. Must be a valid replication slot + name (see ). + + + + + + output_plugin + + + The name of the output plugin used for logical decoding + (see ). + + + + + + TEMPORARY + + + Specify that this replication slot is a temporary one. Temporary + slots are not saved to disk and are automatically dropped on error + or when the session has finished. + + + + + + RESERVE_WAL + + + Specify that this physical replication slot reserves WAL + immediately. Otherwise, WAL is only reserved upon + connection from a streaming replication client. + + + + + + EXPORT_SNAPSHOT + NOEXPORT_SNAPSHOT + USE_SNAPSHOT + + + Decides what to do with the snapshot created during logical slot + initialization. EXPORT_SNAPSHOT, which is the default, + will export the snapshot for use in other sessions. This option can't + be used inside a transaction. USE_SNAPSHOT will use the + snapshot for the current transaction executing the command. This + option must be used in a transaction, and + CREATE_REPLICATION_SLOT must be the first command + run in that transaction. Finally, NOEXPORT_SNAPSHOT will + just use the snapshot for logical decoding as normal but won't do + anything else with it. + + + + + + + In response to this command, the server will send a one-row result set + containing the following fields: + + + + slot_name (text) + + + The name of the newly-created replication slot. + + + + + + consistent_point (text) + + + The WAL location at which the slot became consistent. This is the + earliest location from which streaming can start on this replication + slot. + + + + + + snapshot_name (text) + + + The identifier of the snapshot exported by the command. The + snapshot is valid until a new command is executed on this connection + or the replication connection is closed. Null if the created slot + is physical. + + + + + + output_plugin (text) + + + The name of the output plugin used by the newly-created replication + slot. Null if the created slot is physical. + + + + + + + + + + START_REPLICATION [ SLOT slot_name ] [ PHYSICAL ] XXX/XXX [ TIMELINE tli ] + START_REPLICATION + + + + Instructs server to start streaming WAL, starting at + WAL location XXX/XXX. + If TIMELINE option is specified, + streaming starts on timeline tli; + otherwise, the server's current timeline is selected. The server can + reply with an error, for example if the requested section of WAL has already + been recycled. On success, server responds with a CopyBothResponse + message, and then starts to stream WAL to the frontend. + + + + If a slot's name is provided + via slot_name, it will be updated + as replication progresses so that the server knows which WAL segments, + and if hot_standby_feedback is on which transactions, + are still needed by the standby. + + + + If the client requests a timeline that's not the latest but is part of + the history of the server, the server will stream all the WAL on that + timeline starting from the requested start point up to the point where + the server switched to another timeline. If the client requests + streaming at exactly the end of an old timeline, the server skips COPY + mode entirely. + + + + After streaming all the WAL on a timeline that is not the latest one, + the server will end streaming by exiting the COPY mode. When the client + acknowledges this by also exiting COPY mode, the server sends a result + set with one row and two columns, indicating the next timeline in this + server's history. The first column is the next timeline's ID (type int8), and the + second column is the WAL location where the switch happened (type text). Usually, + the switch position is the end of the WAL that was streamed, but there + are corner cases where the server can send some WAL from the old + timeline that it has not itself replayed before promoting. Finally, the + server sends two CommandComplete messages (one that ends the CopyData + and the other ends the START_REPLICATION itself), and + is ready to accept a new command. + + + + WAL data is sent as a series of CopyData messages. (This allows + other information to be intermixed; in particular the server can send + an ErrorResponse message if it encounters a failure after beginning + to stream.) The payload of each CopyData message from server to the + client contains a message of one of the following formats: + + + + + + + XLogData (B) + + + + + + + Byte1('w') + + + + Identifies the message as WAL data. + + + + + + Int64 + + + + The starting point of the WAL data in this message. + + + + + + Int64 + + + + The current end of WAL on the server. + + + + + + Int64 + + + + The server's system clock at the time of transmission, as + microseconds since midnight on 2000-01-01. + + + + + + Byten + + + + A section of the WAL data stream. + + + A single WAL record is never split across two XLogData messages. + When a WAL record crosses a WAL page boundary, and is therefore + already split using continuation records, it can be split at the page + boundary. In other words, the first main WAL record and its + continuation records can be sent in different XLogData messages. + + + + + + + + + + Primary keepalive message (B) + + + + + + + Byte1('k') + + + + Identifies the message as a sender keepalive. + + + + + + Int64 + + + + The current end of WAL on the server. + + + + + + Int64 + + + + The server's system clock at the time of transmission, as + microseconds since midnight on 2000-01-01. + + + + + + Byte1 + + + + 1 means that the client should reply to this message as soon as + possible, to avoid a timeout disconnect. 0 otherwise. + + + + + + + + + + + + The receiving process can send replies back to the sender at any time, + using one of the following message formats (also in the payload of a + CopyData message): + + + + + + + Standby status update (F) + + + + + + + Byte1('r') + + + + Identifies the message as a receiver status update. + + + + + + Int64 + + + + The location of the last WAL byte + 1 received and written to disk + in the standby. + + + + + + Int64 + + + + The location of the last WAL byte + 1 flushed to disk in + the standby. + + + + + + Int64 + + + + The location of the last WAL byte + 1 applied in the standby. + + + + + + Int64 + + + + The client's system clock at the time of transmission, as + microseconds since midnight on 2000-01-01. + + + + + + Byte1 + + + + If 1, the client requests the server to reply to this message + immediately. This can be used to ping the server, to test if + the connection is still healthy. + + + + + + + + + + + + + + + Hot Standby feedback message (F) + + + + + + + Byte1('h') + + + + Identifies the message as a Hot Standby feedback message. + + + + + + Int64 + + + + The client's system clock at the time of transmission, as + microseconds since midnight on 2000-01-01. + + + + + + Int32 + + + + The standby's current global xmin, excluding the catalog_xmin from any + replication slots. If both this value and the following + catalog_xmin are 0 this is treated as a notification that Hot Standby + feedback will no longer be sent on this connection. Later non-zero + messages may reinitiate the feedback mechanism. + + + + + + Int32 + + + + The epoch of the global xmin xid on the standby. + + + + + + Int32 + + + + The lowest catalog_xmin of any replication slots on the standby. Set to 0 + if no catalog_xmin exists on the standby or if hot standby feedback is being + disabled. + + + + + + Int32 + + + + The epoch of the catalog_xmin xid on the standby. + + + + + + + + + + + + + START_REPLICATION SLOT slot_name LOGICAL XXX/XXX [ ( option_name [ option_value ] [, ...] ) ] + + + Instructs server to start streaming WAL for logical replication, starting + at WAL location XXX/XXX. The server can + reply with an error, for example if the requested section of WAL has already + been recycled. On success, server responds with a CopyBothResponse + message, and then starts to stream WAL to the frontend. + + + + The messages inside the CopyBothResponse messages are of the same format + documented for START_REPLICATION ... PHYSICAL, including + two CommandComplete messages. + + + + The output plugin associated with the selected slot is used + to process the output for streaming. + + + + + SLOT slot_name + + + The name of the slot to stream changes from. This parameter is required, + and must correspond to an existing logical replication slot created + with CREATE_REPLICATION_SLOT in + LOGICAL mode. + + + + + XXX/XXX + + + The WAL location to begin streaming at. + + + + + option_name + + + The name of an option passed to the slot's logical decoding plugin. + + + + + option_value + + + Optional value, in the form of a string constant, associated with the + specified option. + + + + + + + + + + DROP_REPLICATION_SLOT slot_name WAIT + DROP_REPLICATION_SLOT + + + + Drops a replication slot, freeing any reserved server-side resources. + If the slot is a logical slot that was created in a database other than + the database the walsender is connected to, this command fails. + + + + slot_name + + + The name of the slot to drop. + + + + + + WAIT + + + This option causes the command to wait if the slot is active until + it becomes inactive, instead of the default behavior of raising an + error. + + + + + + + + + BASE_BACKUP [ LABEL 'label' ] [ PROGRESS ] [ FAST ] [ WAL ] [ NOWAIT ] [ MAX_RATE rate ] [ TABLESPACE_MAP ] [ NOVERIFY_CHECKSUMS ] [ MANIFEST manifest_option ] [ MANIFEST_CHECKSUMS checksum_algorithm ] + BASE_BACKUP + + + + Instructs the server to start streaming a base backup. + The system will automatically be put in backup mode before the backup + is started, and taken out of it when the backup is complete. The + following options are accepted: + + + LABEL 'label' + + + Sets the label of the backup. If none is specified, a backup label + of base backup will be used. The quoting rules + for the label are the same as a standard SQL string with + turned on. + + + + + + PROGRESS + + + Request information required to generate a progress report. This will + send back an approximate size in the header of each tablespace, which + can be used to calculate how far along the stream is done. This is + calculated by enumerating all the file sizes once before the transfer + is even started, and might as such have a negative impact on the + performance. In particular, it might take longer before the first data + is streamed. Since the database files can change during the backup, + the size is only approximate and might both grow and shrink between + the time of approximation and the sending of the actual files. + + + + + + FAST + + + Request a fast checkpoint. + + + + + + WAL + + + Include the necessary WAL segments in the backup. This will include + all the files between start and stop backup in the + pg_wal directory of the base directory tar + file. + + + + + + NOWAIT + + + By default, the backup will wait until the last required WAL + segment has been archived, or emit a warning if log archiving is + not enabled. Specifying NOWAIT disables both + the waiting and the warning, leaving the client responsible for + ensuring the required log is available. + + + + + + MAX_RATE rate + + + Limit (throttle) the maximum amount of data transferred from server + to client per unit of time. The expected unit is kilobytes per second. + If this option is specified, the value must either be equal to zero + or it must fall within the range from 32 kB through 1 GB (inclusive). + If zero is passed or the option is not specified, no restriction is + imposed on the transfer. + + + + + + TABLESPACE_MAP + + + Include information about symbolic links present in the directory + pg_tblspc in a file named + tablespace_map. The tablespace map file includes + each symbolic link name as it exists in the directory + pg_tblspc/ and the full path of that symbolic link. + + + + + + NOVERIFY_CHECKSUMS + + + By default, checksums are verified during a base backup if they are + enabled. Specifying NOVERIFY_CHECKSUMS disables + this verification. + + + + + + MANIFEST manifest_option + + + When this option is specified with a value of yes + or force-encode, a backup manifest is created + and sent along with the backup. The manifest is a list of every + file present in the backup with the exception of any WAL files that + may be included. It also stores the size, last modification time, and + optionally a checksum for each file. + A value of force-encode forces all filenames + to be hex-encoded; otherwise, this type of encoding is performed only + for files whose names are non-UTF8 octet sequences. + force-encode is intended primarily for testing + purposes, to be sure that clients which read the backup manifest + can handle this case. For compatibility with previous releases, + the default is MANIFEST 'no'. + + + + + + MANIFEST_CHECKSUMS checksum_algorithm + + + Specifies the checksum algorithm that should be applied to each file included + in the backup manifest. Currently, the available + algorithms are NONE, CRC32C, + SHA224, SHA256, + SHA384, and SHA512. + The default is CRC32C. + + + + + + + When the backup is started, the server will first send two + ordinary result sets, followed by one or more CopyOutResponse + results. + + + The first ordinary result set contains the starting position of the + backup, in a single row with two columns. The first column contains + the start position given in XLogRecPtr format, and the second column + contains the corresponding timeline ID. + + + The second ordinary result set has one row for each tablespace. + The fields in this row are: + + + spcoid (oid) + + + The OID of the tablespace, or null if it's the base + directory. + + + + + spclocation (text) + + + The full path of the tablespace directory, or null + if it's the base directory. + + + + + size (int8) + + + The approximate size of the tablespace, in kilobytes (1024 bytes), + if progress report has been requested; otherwise it's null. + + + + + + + After the second regular result set, one or more CopyOutResponse results + will be sent, one for the main data directory and one for each additional tablespace other + than pg_default and pg_global. The data in + the CopyOutResponse results will be a tar format (following the + ustar interchange format specified in the POSIX 1003.1-2008 + standard) dump of the tablespace contents, except that the two trailing + blocks of zeroes specified in the standard are omitted. + After the tar data is complete, and if a backup manifest was requested, + another CopyOutResponse result is sent, containing the manifest data for the + current base backup. In any case, a final ordinary result set will be + sent, containing the WAL end position of the backup, in the same format as + the start position. + + + + The tar archive for the data directory and each tablespace will contain + all files in the directories, regardless of whether they are + PostgreSQL files or other files added to the same + directory. The only excluded files are: + + + + postmaster.pid + + + + + postmaster.opts + + + + + pg_internal.init (found in multiple directories) + + + + + Various temporary files and directories created during the operation + of the PostgreSQL server, such as any file or directory beginning + with pgsql_tmp and temporary relations. + + + + + Unlogged relations, except for the init fork which is required to + recreate the (empty) unlogged relation on recovery. + + + + + pg_wal, including subdirectories. If the backup is run + with WAL files included, a synthesized version of pg_wal will be + included, but it will only contain the files necessary for the + backup to work, not the rest of the contents. + + + + + pg_dynshmem, pg_notify, + pg_replslot, pg_serial, + pg_snapshots, pg_stat_tmp, and + pg_subtrans are copied as empty directories (even if + they are symbolic links). + + + + + Files other than regular files and directories, such as symbolic + links (other than for the directories listed above) and special + device files, are skipped. (Symbolic links + in pg_tblspc are maintained.) + + + + Owner, group, and file mode are set if the underlying file system on + the server supports it. + + + + + + + + + + + Logical Streaming Replication Protocol + + + This section describes the logical replication protocol, which is the message + flow started by the START_REPLICATION + SLOT slot_name + LOGICAL replication command. + + + + The logical streaming replication protocol builds on the primitives of + the physical streaming replication protocol. + + + + Logical Streaming Replication Parameters + + + The logical replication START_REPLICATION command + accepts following parameters: + + + + + proto_version + + + + Protocol version. Currently versions 1 and + 2 are supported. The version 2 + is supported only for server version 14 and above, and it allows + streaming of large in-progress transactions. + + + + + + + publication_names + + + + Comma separated list of publication names for which to subscribe + (receive changes). The individual publication names are treated + as standard objects names and can be quoted the same as needed. + + + + + + + + + + Logical Replication Protocol Messages + + + The individual protocol messages are discussed in the following + subsections. Individual messages are described in + . + + + + All top-level protocol messages begin with a message type byte. + While represented in code as a character, this is a signed byte with no + associated encoding. + + + + Since the streaming replication protocol supplies a message length there + is no need for top-level protocol messages to embed a length in their + header. + + + + + + Logical Replication Protocol Message Flow + + + With the exception of the START_REPLICATION command and + the replay progress messages, all information flows only from the backend + to the frontend. + + + + The logical replication protocol sends individual transactions one by one. + This means that all messages between a pair of Begin and Commit messages + belong to the same transaction. It also sends changes of large in-progress + transactions between a pair of Stream Start and Stream Stop messages. The + last stream of such a transaction contains Stream Commit or Stream Abort + message. + + + + Every sent transaction contains zero or more DML messages (Insert, + Update, Delete). In case of a cascaded setup it can also contain Origin + messages. The origin message indicates that the transaction originated on + different replication node. Since a replication node in the scope of logical + replication protocol can be pretty much anything, the only identifier + is the origin name. It's downstream's responsibility to handle this as + needed (if needed). The Origin message is always sent before any DML + messages in the transaction. + + + + Every DML message contains an arbitrary relation ID, which can be mapped to + an ID in the Relation messages. The Relation messages describe the schema of the + given relation. The Relation message is sent for a given relation either + because it is the first time we send a DML message for given relation in the + current session or because the relation definition has changed since the + last Relation message was sent for it. The protocol assumes that the client + is capable of caching the metadata for as many relations as needed. + + + + + +Message Data Types + + +This section describes the base data types used in messages. + + + + + + Intn(i) + + + + An n-bit integer in network byte + order (most significant byte first). + If i is specified it + is the exact value that will appear, otherwise the value + is variable. Eg. Int16, Int32(42). + + + + + + + Intn[k] + + + + An array of k + n-bit integers, each in network + byte order. The array length k + is always determined by an earlier field in the message. + Eg. Int16[M]. + + + + + + + String(s) + + + + A null-terminated string (C-style string). There is no + specific length limitation on strings. + If s is specified it is the exact + value that will appear, otherwise the value is variable. + Eg. String, String("user"). + + + + +There is no predefined limit on the length of a string +that can be returned by the backend. Good coding strategy for a frontend +is to use an expandable buffer so that anything that fits in memory can be +accepted. If that's not feasible, read the full string and discard trailing +characters that don't fit into your fixed-size buffer. + + + + + + + + Byten(c) + + + + Exactly n bytes. If the field + width n is not a constant, it is + always determinable from an earlier field in the message. + If c is specified it is the exact + value. Eg. Byte2, Byte1('\n'). + + + + + + + + + +Message Formats + + +This section describes the detailed format of each message. Each is marked to +indicate that it can be sent by a frontend (F), a backend (B), or both +(F & B). +Notice that although each message includes a byte count at the beginning, +the message format is defined so that the message end can be found without +reference to the byte count. This aids validity checking. (The CopyData +message is an exception, because it forms part of a data stream; the contents +of any individual CopyData message cannot be interpretable on their own.) + + + + + + + +AuthenticationOk (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(0) + + + + Specifies that the authentication was successful. + + + + + + + + + + + + +AuthenticationKerberosV5 (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(2) + + + + Specifies that Kerberos V5 authentication is required. + + + + + + + + + + + +AuthenticationCleartextPassword (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(3) + + + + Specifies that a clear-text password is required. + + + + + + + + + + + +AuthenticationMD5Password (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32(12) + + + + Length of message contents in bytes, including self. + + + + + + Int32(5) + + + + Specifies that an MD5-encrypted password is required. + + + + + + Byte4 + + + + The salt to use when encrypting the password. + + + + + + + + + + + + +AuthenticationSCMCredential (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(6) + + + + Specifies that an SCM credentials message is required. + + + + + + + + + + + + +AuthenticationGSS (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(7) + + + + Specifies that GSSAPI authentication is required. + + + + + + + + + + + + +AuthenticationGSSContinue (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32(8) + + + + Specifies that this message contains GSSAPI or SSPI data. + + + + + + Byten + + + + GSSAPI or SSPI authentication data. + + + + + + + + + + + + +AuthenticationSSPI (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(9) + + + + Specifies that SSPI authentication is required. + + + + + + + + + + + + +AuthenticationSASL (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32(10) + + + + Specifies that SASL authentication is required. + + + + +The message body is a list of SASL authentication mechanisms, in the +server's order of preference. A zero byte is required as terminator after +the last authentication mechanism name. For each mechanism, there is the +following: + + + + String + + + + Name of a SASL authentication mechanism. + + + + + + + + + + + + +AuthenticationSASLContinue (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32(11) + + + + Specifies that this message contains a SASL challenge. + + + + + + Byten + + + + SASL data, specific to the SASL mechanism being used. + + + + + + + + + + + + +AuthenticationSASLFinal (B) + + + + + + + + Byte1('R') + + + + Identifies the message as an authentication request. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32(12) + + + + Specifies that SASL authentication has completed. + + + + + + Byten + + + + SASL outcome "additional data", specific to the SASL mechanism + being used. + + + + + + + + + + + + +BackendKeyData (B) + + + + + + + + Byte1('K') + + + + Identifies the message as cancellation key data. + The frontend must save these values if it wishes to be + able to issue CancelRequest messages later. + + + + + + Int32(12) + + + + Length of message contents in bytes, including self. + + + + + + Int32 + + + + The process ID of this backend. + + + + + + Int32 + + + + The secret key of this backend. + + + + + + + + + + + + +Bind (F) + + + + + + + + Byte1('B') + + + + Identifies the message as a Bind command. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + The name of the destination portal + (an empty string selects the unnamed portal). + + + + + + String + + + + The name of the source prepared statement + (an empty string selects the unnamed prepared statement). + + + + + + Int16 + + + + The number of parameter format codes that follow + (denoted C below). + This can be zero to indicate that there are no parameters + or that the parameters all use the default format (text); + or one, in which case the specified format code is applied + to all parameters; or it can equal the actual number of + parameters. + + + + + + Int16[C] + + + + The parameter format codes. Each must presently be + zero (text) or one (binary). + + + + + + Int16 + + + + The number of parameter values that follow (possibly zero). + This must match the number of parameters needed by the query. + + + + + Next, the following pair of fields appear for each parameter: + + + + Int32 + + + + The length of the parameter value, in bytes (this count + does not include itself). Can be zero. + As a special case, -1 indicates a NULL parameter value. + No value bytes follow in the NULL case. + + + + + + Byten + + + + The value of the parameter, in the format indicated by the + associated format code. + n is the above length. + + + + + After the last parameter, the following fields appear: + + + + Int16 + + + + The number of result-column format codes that follow + (denoted R below). + This can be zero to indicate that there are no result columns + or that the result columns should all use the default format + (text); + or one, in which case the specified format code is applied + to all result columns (if any); or it can equal the actual + number of result columns of the query. + + + + + + Int16[R] + + + + The result-column format codes. Each must presently be + zero (text) or one (binary). + + + + + + + + + + + +BindComplete (B) + + + + + + + + Byte1('2') + + + + Identifies the message as a Bind-complete indicator. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +CancelRequest (F) + + + + + + + + Int32(16) + + + + Length of message contents in bytes, including self. + + + + + + Int32(80877102) + + + + The cancel request code. The value is chosen to contain + 1234 in the most significant 16 bits, and 5678 in the + least significant 16 bits. (To avoid confusion, this code + must not be the same as any protocol version number.) + + + + + + Int32 + + + + The process ID of the target backend. + + + + + + Int32 + + + + The secret key for the target backend. + + + + + + + + + + + + +Close (F) + + + + + + + + Byte1('C') + + + + Identifies the message as a Close command. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Byte1 + + + + 'S' to close a prepared statement; or + 'P' to close a portal. + + + + + + String + + + + The name of the prepared statement or portal to close + (an empty string selects the unnamed prepared statement + or portal). + + + + + + + + + + + +CloseComplete (B) + + + + + + + + Byte1('3') + + + + Identifies the message as a Close-complete indicator. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +CommandComplete (B) + + + + + + + + Byte1('C') + + + + Identifies the message as a command-completed response. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + The command tag. This is usually a single + word that identifies which SQL command was completed. + + + + For an INSERT command, the tag is + INSERT oid + rows, where + rows is the number of rows + inserted. oid used to be the object ID + of the inserted row if rows was 1 + and the target table had OIDs, but OIDs system columns are + not supported anymore; therefore oid + is always 0. + + + + For a DELETE command, the tag is + DELETE rows where + rows is the number of rows deleted. + + + + For an UPDATE command, the tag is + UPDATE rows where + rows is the number of rows updated. + + + + For a SELECT or CREATE TABLE AS + command, the tag is SELECT rows + where rows is the number of rows retrieved. + + + + For a MOVE command, the tag is + MOVE rows where + rows is the number of rows the + cursor's position has been changed by. + + + + For a FETCH command, the tag is + FETCH rows where + rows is the number of rows that + have been retrieved from the cursor. + + + + For a COPY command, the tag is + COPY rows where + rows is the number of rows copied. + (Note: the row count appears only in + PostgreSQL 8.2 and later.) + + + + + + + + + + + + + +CopyData (F & B) + + + + + + + Byte1('d') + + + + Identifies the message as COPY data. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Byten + + + + Data that forms part of a COPY data stream. Messages sent + from the backend will always correspond to single data rows, + but messages sent by frontends might divide the data stream + arbitrarily. + + + + + + + + + + + +CopyDone (F & B) + + + + + + + + Byte1('c') + + + + Identifies the message as a COPY-complete indicator. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +CopyFail (F) + + + + + + + + Byte1('f') + + + + Identifies the message as a COPY-failure indicator. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + An error message to report as the cause of failure. + + + + + + + + + + + + +CopyInResponse (B) + + + + + + + + Byte1('G') + + + + Identifies the message as a Start Copy In response. + The frontend must now send copy-in data (if not + prepared to do so, send a CopyFail message). + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int8 + + + + 0 indicates the overall COPY format is textual (rows + separated by newlines, columns separated by separator + characters, etc). + 1 indicates the overall copy format is binary (similar + to DataRow format). + See + for more information. + + + + + + Int16 + + + + The number of columns in the data to be copied + (denoted N below). + + + + + + Int16[N] + + + + The format codes to be used for each column. + Each must presently be zero (text) or one (binary). + All must be zero if the overall copy format is textual. + + + + + + + + + + + + +CopyOutResponse (B) + + + + + + + + Byte1('H') + + + + Identifies the message as a Start Copy Out response. + This message will be followed by copy-out data. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int8 + + + + 0 indicates the overall COPY format + is textual (rows separated by newlines, columns + separated by separator characters, etc). 1 indicates + the overall copy format is binary (similar to DataRow + format). See for more information. + + + + + + Int16 + + + + The number of columns in the data to be copied + (denoted N below). + + + + + + Int16[N] + + + + The format codes to be used for each column. + Each must presently be zero (text) or one (binary). + All must be zero if the overall copy format is textual. + + + + + + + + + + + + +CopyBothResponse (B) + + + + + + + + Byte1('W') + + + + Identifies the message as a Start Copy Both response. + This message is used only for Streaming Replication. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int8 + + + + 0 indicates the overall COPY format + is textual (rows separated by newlines, columns + separated by separator characters, etc). 1 indicates + the overall copy format is binary (similar to DataRow + format). See for more information. + + + + + + Int16 + + + + The number of columns in the data to be copied + (denoted N below). + + + + + + Int16[N] + + + + The format codes to be used for each column. + Each must presently be zero (text) or one (binary). + All must be zero if the overall copy format is textual. + + + + + + + + + + + + +DataRow (B) + + + + + + + Byte1('D') + + + + Identifies the message as a data row. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int16 + + + + The number of column values that follow (possibly zero). + + + + + Next, the following pair of fields appear for each column: + + + + Int32 + + + + The length of the column value, in bytes (this count + does not include itself). Can be zero. + As a special case, -1 indicates a NULL column value. + No value bytes follow in the NULL case. + + + + + + Byten + + + + The value of the column, in the format indicated by the + associated format code. + n is the above length. + + + + + + + + + + + + +Describe (F) + + + + + + + + Byte1('D') + + + + Identifies the message as a Describe command. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Byte1 + + + + 'S' to describe a prepared statement; or + 'P' to describe a portal. + + + + + + String + + + + The name of the prepared statement or portal to describe + (an empty string selects the unnamed prepared statement + or portal). + + + + + + + + + + + +EmptyQueryResponse (B) + + + + + + + + Byte1('I') + + + + Identifies the message as a response to an empty query string. + (This substitutes for CommandComplete.) + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +ErrorResponse (B) + + + + + + + + Byte1('E') + + + + Identifies the message as an error. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + The message body consists of one or more identified fields, + followed by a zero byte as a terminator. Fields can appear in + any order. For each field there is the following: + + + + Byte1 + + + + A code identifying the field type; if zero, this is + the message terminator and no string follows. + The presently defined field types are listed in + . + Since more field types might be added in future, + frontends should silently ignore fields of unrecognized + type. + + + + + + String + + + + The field value. + + + + + + + + + + + + +Execute (F) + + + + + + + + Byte1('E') + + + + Identifies the message as an Execute command. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + The name of the portal to execute + (an empty string selects the unnamed portal). + + + + + + Int32 + + + + Maximum number of rows to return, if portal contains + a query that returns rows (ignored otherwise). Zero + denotes no limit. + + + + + + + + + + + +Flush (F) + + + + + + + + Byte1('H') + + + + Identifies the message as a Flush command. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +FunctionCall (F) + + + + + + + + Byte1('F') + + + + Identifies the message as a function call. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32 + + + + Specifies the object ID of the function to call. + + + + + + Int16 + + + + The number of argument format codes that follow + (denoted C below). + This can be zero to indicate that there are no arguments + or that the arguments all use the default format (text); + or one, in which case the specified format code is applied + to all arguments; or it can equal the actual number of + arguments. + + + + + + Int16[C] + + + + The argument format codes. Each must presently be + zero (text) or one (binary). + + + + + + Int16 + + + + Specifies the number of arguments being supplied to the + function. + + + + + Next, the following pair of fields appear for each argument: + + + + Int32 + + + + The length of the argument value, in bytes (this count + does not include itself). Can be zero. + As a special case, -1 indicates a NULL argument value. + No value bytes follow in the NULL case. + + + + + + Byten + + + + The value of the argument, in the format indicated by the + associated format code. + n is the above length. + + + + + After the last argument, the following field appears: + + + + Int16 + + + + The format code for the function result. Must presently be + zero (text) or one (binary). + + + + + + + + + + + + +FunctionCallResponse (B) + + + + + + + + Byte1('V') + + + + Identifies the message as a function call result. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32 + + + + The length of the function result value, in bytes (this count + does not include itself). Can be zero. + As a special case, -1 indicates a NULL function result. + No value bytes follow in the NULL case. + + + + + + Byten + + + + The value of the function result, in the format indicated by + the associated format code. + n is the above length. + + + + + + + + + + + + +GSSENCRequest (F) + + + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(80877104) + + + + The GSSAPI Encryption request code. The value is chosen to contain + 1234 in the most significant 16 bits, and 5680 in the + least significant 16 bits. (To avoid confusion, this code + must not be the same as any protocol version number.) + + + + + + + + + + + + +GSSResponse (F) + + + + + + + + Byte1('p') + + + + Identifies the message as a GSSAPI or SSPI response. Note that + this is also used for SASL and password response messages. + The exact message type can be deduced from the context. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Byten + + + + GSSAPI/SSPI specific message data. + + + + + + + + + + +NegotiateProtocolVersion (B) + + + + + + + + Byte1('v') + + + + Identifies the message as a protocol version negotiation + message. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32 + + + + Newest minor protocol version supported by the server + for the major protocol version requested by the client. + + + + + + Int32 + + + + Number of protocol options not recognized by the server. + + + + + Then, for protocol option not recognized by the server, there + is the following: + + + + String + + + + The option name. + + + + + + + + + + +NoData (B) + + + + + + + + Byte1('n') + + + + Identifies the message as a no-data indicator. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +NoticeResponse (B) + + + + + + + + Byte1('N') + + + + Identifies the message as a notice. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + The message body consists of one or more identified fields, + followed by a zero byte as a terminator. Fields can appear in + any order. For each field there is the following: + + + + Byte1 + + + + A code identifying the field type; if zero, this is + the message terminator and no string follows. + The presently defined field types are listed in + . + Since more field types might be added in future, + frontends should silently ignore fields of unrecognized + type. + + + + + + String + + + + The field value. + + + + + + + + + + + + +NotificationResponse (B) + + + + + + + + Byte1('A') + + + + Identifies the message as a notification response. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32 + + + + The process ID of the notifying backend process. + + + + + + String + + + + The name of the channel that the notify has been raised on. + + + + + + String + + + + The payload string passed from the notifying process. + + + + + + + + + + + + +ParameterDescription (B) + + + + + + + + Byte1('t') + + + + Identifies the message as a parameter description. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int16 + + + + The number of parameters used by the statement + (can be zero). + + + + + Then, for each parameter, there is the following: + + + + Int32 + + + + Specifies the object ID of the parameter data type. + + + + + + + + + + + +ParameterStatus (B) + + + + + + + + Byte1('S') + + + + Identifies the message as a run-time parameter status report. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + The name of the run-time parameter being reported. + + + + + + String + + + + The current value of the parameter. + + + + + + + + + + + +Parse (F) + + + + + + + + Byte1('P') + + + + Identifies the message as a Parse command. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + The name of the destination prepared statement + (an empty string selects the unnamed prepared statement). + + + + + + String + + + + The query string to be parsed. + + + + + + Int16 + + + + The number of parameter data types specified + (can be zero). Note that this is not an indication of + the number of parameters that might appear in the + query string, only the number that the frontend wants to + prespecify types for. + + + + + Then, for each parameter, there is the following: + + + + Int32 + + + + Specifies the object ID of the parameter data type. + Placing a zero here is equivalent to leaving the type + unspecified. + + + + + + + + + + + +ParseComplete (B) + + + + + + + + Byte1('1') + + + + Identifies the message as a Parse-complete indicator. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +PasswordMessage (F) + + + + + + + + Byte1('p') + + + + Identifies the message as a password response. Note that + this is also used for GSSAPI, SSPI and SASL response messages. + The exact message type can be deduced from the context. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + The password (encrypted, if requested). + + + + + + + + + + + +PortalSuspended (B) + + + + + + + + Byte1('s') + + + + Identifies the message as a portal-suspended indicator. + Note this only appears if an Execute message's row-count limit + was reached. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +Query (F) + + + + + + + + Byte1('Q') + + + + Identifies the message as a simple query. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + The query string itself. + + + + + + + + + + + + +ReadyForQuery (B) + + + + + + + + Byte1('Z') + + + + Identifies the message type. ReadyForQuery is sent + whenever the backend is ready for a new query cycle. + + + + + + Int32(5) + + + + Length of message contents in bytes, including self. + + + + + + Byte1 + + + + Current backend transaction status indicator. + Possible values are 'I' if idle (not in + a transaction block); 'T' if in a transaction + block; or 'E' if in a failed transaction + block (queries will be rejected until block is ended). + + + + + + + + + + + + +RowDescription (B) + + + + + + + + Byte1('T') + + + + Identifies the message as a row description. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int16 + + + + Specifies the number of fields in a row (can be zero). + + + + + Then, for each field, there is the following: + + + + String + + + + The field name. + + + + + + Int32 + + + + If the field can be identified as a column of a specific + table, the object ID of the table; otherwise zero. + + + + + + Int16 + + + + If the field can be identified as a column of a specific + table, the attribute number of the column; otherwise zero. + + + + + + Int32 + + + + The object ID of the field's data type. + + + + + + Int16 + + + + The data type size (see pg_type.typlen). + Note that negative values denote variable-width types. + + + + + + Int32 + + + + The type modifier (see pg_attribute.atttypmod). + The meaning of the modifier is type-specific. + + + + + + Int16 + + + + The format code being used for the field. Currently will + be zero (text) or one (binary). In a RowDescription + returned from the statement variant of Describe, the + format code is not yet known and will always be zero. + + + + + + + + + + + + +SASLInitialResponse (F) + + + + + + + + Byte1('p') + + + + Identifies the message as an initial SASL response. Note that + this is also used for GSSAPI, SSPI and password response messages. + The exact message type is deduced from the context. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + String + + + + Name of the SASL authentication mechanism that the client + selected. + + + + + + Int32 + + + + Length of SASL mechanism specific "Initial Client Response" that + follows, or -1 if there is no Initial Response. + + + + + + Byten + + + + SASL mechanism specific "Initial Response". + + + + + + + + + + + +SASLResponse (F) + + + + + + + + Byte1('p') + + + + Identifies the message as a SASL response. Note that + this is also used for GSSAPI, SSPI and password response messages. + The exact message type can be deduced from the context. + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Byten + + + + SASL mechanism specific message data. + + + + + + + + + + + +SSLRequest (F) + + + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(80877103) + + + + The SSL request code. The value is chosen to contain + 1234 in the most significant 16 bits, and 5679 in the + least significant 16 bits. (To avoid confusion, this code + must not be the same as any protocol version number.) + + + + + + + + + + + + +StartupMessage (F) + + + + + + + + Int32 + + + + Length of message contents in bytes, including self. + + + + + + Int32(196608) + + + + The protocol version number. The most significant 16 bits are + the major version number (3 for the protocol described here). + The least significant 16 bits are the minor version number + (0 for the protocol described here). + + + + + The protocol version number is followed by one or more pairs of + parameter name and value strings. A zero byte is required as a + terminator after the last name/value pair. + Parameters can appear in any + order. user is required, others are optional. + Each parameter is specified as: + + + + String + + + + The parameter name. Currently recognized names are: + + + + + user + + + + The database user name to connect as. Required; + there is no default. + + + + + + database + + + + The database to connect to. Defaults to the user name. + + + + + + options + + + + Command-line arguments for the backend. (This is + deprecated in favor of setting individual run-time + parameters.) Spaces within this string are + considered to separate arguments, unless escaped with + a backslash (\); write \\ to + represent a literal backslash. + + + + + + replication + + + + Used to connect in streaming replication mode, where + a small set of replication commands can be issued + instead of SQL statements. Value can be + true, false, or + database, and the default is + false. See + for details. + + + + + + In addition to the above, other parameters may be listed. + Parameter names beginning with _pq_. are + reserved for use as protocol extensions, while others are + treated as run-time parameters to be set at backend start + time. Such settings will be applied during backend start + (after parsing the command-line arguments if any) and will + act as session defaults. + + + + + + String + + + + The parameter value. + + + + + + + + + + + + +Sync (F) + + + + + + + + Byte1('S') + + + + Identifies the message as a Sync command. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + +Terminate (F) + + + + + + + + Byte1('X') + + + + Identifies the message as a termination. + + + + + + Int32(4) + + + + Length of message contents in bytes, including self. + + + + + + + + + + + + + + + + +Error and Notice Message Fields + + +This section describes the fields that can appear in ErrorResponse and +NoticeResponse messages. Each field type has a single-byte identification +token. Note that any given field type should appear at most once per +message. + + + + + + +S + + + + Severity: the field contents are + ERROR, FATAL, or + PANIC (in an error message), or + WARNING, NOTICE, DEBUG, + INFO, or LOG (in a notice message), + or a localized translation of one of these. Always present. + + + + + + +V + + + + Severity: the field contents are + ERROR, FATAL, or + PANIC (in an error message), or + WARNING, NOTICE, DEBUG, + INFO, or LOG (in a notice message). + This is identical to the S field except + that the contents are never localized. This is present only in + messages generated by PostgreSQL versions 9.6 + and later. + + + + + + +C + + + + Code: the SQLSTATE code for the error (see ). Not localizable. Always present. + + + + + + +M + + + + Message: the primary human-readable error message. + This should be accurate but terse (typically one line). + Always present. + + + + + + +D + + + + Detail: an optional secondary error message carrying more + detail about the problem. Might run to multiple lines. + + + + + + +H + + + + Hint: an optional suggestion what to do about the problem. + This is intended to differ from Detail in that it offers advice + (potentially inappropriate) rather than hard facts. + Might run to multiple lines. + + + + + + +P + + + + Position: the field value is a decimal ASCII integer, indicating + an error cursor position as an index into the original query string. + The first character has index 1, and positions are measured in + characters not bytes. + + + + + + +p + + + + Internal position: this is defined the same as the P + field, but it is used when the cursor position refers to an internally + generated command rather than the one submitted by the client. + The q field will always appear when this field appears. + + + + + + +q + + + + Internal query: the text of a failed internally-generated command. + This could be, for example, an SQL query issued by a PL/pgSQL function. + + + + + + +W + + + + Where: an indication of the context in which the error occurred. + Presently this includes a call stack traceback of active + procedural language functions and internally-generated queries. + The trace is one entry per line, most recent first. + + + + + + +s + + + + Schema name: if the error was associated with a specific database + object, the name of the schema containing that object, if any. + + + + + + +t + + + + Table name: if the error was associated with a specific table, the + name of the table. (Refer to the schema name field for the name of + the table's schema.) + + + + + + +c + + + + Column name: if the error was associated with a specific table column, + the name of the column. (Refer to the schema and table name fields to + identify the table.) + + + + + + +d + + + + Data type name: if the error was associated with a specific data type, + the name of the data type. (Refer to the schema name field for the + name of the data type's schema.) + + + + + + +n + + + + Constraint name: if the error was associated with a specific + constraint, the name of the constraint. Refer to fields listed above + for the associated table or domain. (For this purpose, indexes are + treated as constraints, even if they weren't created with constraint + syntax.) + + + + + + +F + + + + File: the file name of the source-code location where the error + was reported. + + + + + + +L + + + + Line: the line number of the source-code location where the error + was reported. + + + + + + +R + + + + Routine: the name of the source-code routine reporting the error. + + + + + + + + + The fields for schema name, table name, column name, data type name, and + constraint name are supplied only for a limited number of error types; + see . Frontends should not assume that + the presence of any of these fields guarantees the presence of another + field. Core error sources observe the interrelationships noted above, but + user-defined functions may use these fields in other ways. In the same + vein, clients should not assume that these fields denote contemporary + objects in the current database. + + + + +The client is responsible for formatting displayed information to meet its +needs; in particular it should break long lines as needed. Newline characters +appearing in the error message fields should be treated as paragraph breaks, +not line breaks. + + + + + +Logical Replication Message Formats + + +This section describes the detailed format of each logical replication message. +These messages are returned either by the replication slot SQL interface or are +sent by a walsender. In case of a walsender they are encapsulated inside the replication +protocol WAL messages as described in +and generally obey same message flow as physical replication. + + + + + + +Begin + + + + + + + + Byte1('B') + + + + Identifies the message as a begin message. + + + + + + Int64 + + + + The final LSN of the transaction. + + + + + + Int64 + + + + Commit timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + + + + + + Int32 + + + + Xid of the transaction. + + + + + + + + + + + +Message + + + + + + + + Byte1('M') + + + + Identifies the message as a logical decoding message. + + + + + + Int32 + + + + Xid of the transaction (only present for streamed transactions). + This field is available since protocol version 2. + + + + + + Int8 + + + + Flags; Either 0 for no flags or 1 if the logical decoding + message is transactional. + + + + + + Int64 + + + + The LSN of the logical decoding message. + + + + + + String + + + + The prefix of the logical decoding message. + + + + + + + Int32 + + + + Length of the content. + + + + + + + Byten + + + + The content of the logical decoding message. + + + + + + + + + + + +Commit + + + + + + + + Byte1('C') + + + + Identifies the message as a commit message. + + + + + + Int8 + + + + Flags; currently unused (must be 0). + + + + + + Int64 + + + + The LSN of the commit. + + + + + + Int64 + + + + The end LSN of the transaction. + + + + + + Int64 + + + + Commit timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + + + + + + + + + + + +Origin + + + + + + + + Byte1('O') + + + + Identifies the message as an origin message. + + + + + + Int64 + + + + The LSN of the commit on the origin server. + + + + + + String + + + + Name of the origin. + + + + + + + + + Note that there can be multiple Origin messages inside a single transaction. + + + + + + + +Relation + + + + + + + + Byte1('R') + + + + Identifies the message as a relation message. + + + + + + Int32 + + + + Xid of the transaction (only present for streamed transactions). + This field is available since protocol version 2. + + + + + + Int32 + + + + ID of the relation. + + + + + + String + + + + Namespace (empty string for pg_catalog). + + + + + + String + + + + Relation name. + + + + + + + Int8 + + + + Replica identity setting for the relation (same as + relreplident in pg_class). + + + + + + + Int16 + + + + Number of columns. + + + + + Next, the following message part appears for each column (except generated columns): + + + + Int8 + + + + Flags for the column. Currently can be either 0 for no flags + or 1 which marks the column as part of the key. + + + + + + String + + + + Name of the column. + + + + + + Int32 + + + + ID of the column's data type. + + + + + + Int32 + + + + Type modifier of the column (atttypmod). + + + + + + + + + + + +Type + + + + + + + + Byte1('Y') + + + + Identifies the message as a type message. + + + + + + Int32 + + + + Xid of the transaction (only present for streamed transactions). + This field is available since protocol version 2. + + + + + + Int32 + + + + ID of the data type. + + + + + + String + + + + Namespace (empty string for pg_catalog). + + + + + + String + + + + Name of the data type. + + + + + + + + + + + +Insert + + + + + + + + Byte1('I') + + + + Identifies the message as an insert message. + + + + + + Int32 + + + + Xid of the transaction (only present for streamed transactions). + This field is available since protocol version 2. + + + + + + Int32 + + + + ID of the relation corresponding to the ID in the relation + message. + + + + + + Byte1('N') + + + + Identifies the following TupleData message as a new tuple. + + + + + + + TupleData + + + + TupleData message part representing the contents of new tuple. + + + + + + + + + + + +Update + + + + + + + + Byte1('U') + + + + Identifies the message as an update message. + + + + + + Int32 + + + + Xid of the transaction (only present for streamed transactions). + This field is available since protocol version 2. + + + + + + Int32 + + + + ID of the relation corresponding to the ID in the relation + message. + + + + + + + Byte1('K') + + + + Identifies the following TupleData submessage as a key. + This field is optional and is only present if + the update changed data in any of the column(s) that are + part of the REPLICA IDENTITY index. + + + + + + + Byte1('O') + + + + Identifies the following TupleData submessage as an old tuple. + This field is optional and is only present if table in which + the update happened has REPLICA IDENTITY set to FULL. + + + + + + + TupleData + + + + TupleData message part representing the contents of the old tuple + or primary key. Only present if the previous 'O' or 'K' part + is present. + + + + + + + Byte1('N') + + + + Identifies the following TupleData message as a new tuple. + + + + + + + TupleData + + + + TupleData message part representing the contents of a new tuple. + + + + + + + + + The Update message may contain either a 'K' message part or an 'O' message part + or neither of them, but never both of them. + + + + + + + +Delete + + + + + + + + Byte1('D') + + + + Identifies the message as a delete message. + + + + + + Int32 + + + + Xid of the transaction (only present for streamed transactions). + This field is available since protocol version 2. + + + + + + Int32 + + + + ID of the relation corresponding to the ID in the relation + message. + + + + + + + Byte1('K') + + + + Identifies the following TupleData submessage as a key. + This field is present if the table in which the delete has + happened uses an index as REPLICA IDENTITY. + + + + + + + Byte1('O') + + + + Identifies the following TupleData message as an old tuple. + This field is present if the table in which the delete + happened has REPLICA IDENTITY set to FULL. + + + + + + + TupleData + + + + TupleData message part representing the contents of the old tuple + or primary key, depending on the previous field. + + + + + + + + The Delete message may contain either a 'K' message part or an 'O' message part, + but never both of them. + + + + + + + +Truncate + + + + + + + + Byte1('T') + + + + Identifies the message as a truncate message. + + + + + + Int32 + + + + Xid of the transaction (only present for streamed transactions). + This field is available since protocol version 2. + + + + + + Int32 + + + + Number of relations + + + + + + Int8 + + + + Option bits for TRUNCATE: + 1 for CASCADE, 2 for RESTART IDENTITY + + + + + + Int32 + + + + ID of the relation corresponding to the ID in the relation + message. This field is repeated for each relation. + + + + + + + + + + + + + +The following messages (Stream Start, Stream End, Stream Commit, and +Stream Abort) are available since protocol version 2. + + + + + + + +Stream Start + + + + + + + + Byte1('S') + + + + Identifies the message as a stream start message. + + + + + + Int32 + + + + Xid of the transaction. + + + + + + Int8 + + + + A value of 1 indicates this is the first stream segment for + this XID, 0 for any other stream segment. + + + + + + + + + + + +Stream Stop + + + + + + + + Byte1('E') + + + + Identifies the message as a stream stop message. + + + + + + + + + + + +Stream Commit + + + + + + + + Byte1('c') + + + + Identifies the message as a stream commit message. + + + + + + Int32 + + + + Xid of the transaction. + + + + + + Int8 + + + + Flags; currently unused (must be 0). + + + + + + Int64 + + + + The LSN of the commit. + + + + + + Int64 + + + + The end LSN of the transaction. + + + + + + Int64 + + + + Commit timestamp of the transaction. The value is in number + of microseconds since PostgreSQL epoch (2000-01-01). + + + + + + + + + + + +Stream Abort + + + + + + + + Byte1('A') + + + + Identifies the message as a stream abort message. + + + + + + Int32 + + + + Xid of the transaction. + + + + + + Int32 + + + + Xid of the subtransaction (will be same as xid of the transaction for top-level + transactions). + + + + + + + + + + + + + +The following message parts are shared by the above messages. + + + + + + + +TupleData + + + + + + + + Int16 + + + + Number of columns. + + + + + Next, one of the following submessages appears for each column (except generated columns): + + + + Byte1('n') + + + + Identifies the data as NULL value. + + + + + Or + + + + Byte1('u') + + + + Identifies unchanged TOASTed value (the actual value is not + sent). + + + + + Or + + + + Byte1('t') + + + + Identifies the data as text formatted value. + + + + + Or + + + + Byte1('b') + + + + Identifies the data as binary formatted value. + + + + + + Int32 + + + + Length of the column value. + + + + + + Byten + + + + The value of the column, either in binary or in text format. + (As specified in the preceding format byte). + n is the above length. + + + + + + + + + + + + + + + +Summary of Changes since Protocol 2.0 + + +This section provides a quick checklist of changes, for the benefit of +developers trying to update existing client libraries to protocol 3.0. + + + +The initial startup packet uses a flexible list-of-strings format +instead of a fixed format. Notice that session default values for run-time +parameters can now be specified directly in the startup packet. (Actually, +you could do that before using the options field, but given the +limited width of options and the lack of any way to quote +whitespace in the values, it wasn't a very safe technique.) + + + +All messages now have a length count immediately following the message type +byte (except for startup packets, which have no type byte). Also note that +PasswordMessage now has a type byte. + + + +ErrorResponse and NoticeResponse ('E' and 'N') +messages now contain multiple fields, from which the client code can +assemble an error message of the desired level of verbosity. Note that +individual fields will typically not end with a newline, whereas the single +string sent in the older protocol always did. + + + +The ReadyForQuery ('Z') message includes a transaction status +indicator. + + + +The distinction between BinaryRow and DataRow message types is gone; the +single DataRow message type serves for returning data in all formats. +Note that the layout of DataRow has changed to make it easier to parse. +Also, the representation of binary values has changed: it is no longer +directly tied to the server's internal representation. + + + +There is a new extended query sub-protocol, which adds the frontend +message types Parse, Bind, Execute, Describe, Close, Flush, and Sync, and the +backend message types ParseComplete, BindComplete, PortalSuspended, +ParameterDescription, NoData, and CloseComplete. Existing clients do not +have to concern themselves with this sub-protocol, but making use of it +might allow improvements in performance or functionality. + + + +COPY data is now encapsulated into CopyData and CopyDone messages. There +is a well-defined way to recover from errors during COPY. The special +\. last line is not needed anymore, and is not sent +during COPY OUT. +(It is still recognized as a terminator during COPY IN, but its use is +deprecated and will eventually be removed.) Binary COPY is supported. +The CopyInResponse and CopyOutResponse messages include fields indicating +the number of columns and the format of each column. + + + +The layout of FunctionCall and FunctionCallResponse messages has changed. +FunctionCall can now support passing NULL arguments to functions. It also +can handle passing parameters and retrieving results in either text or +binary format. There is no longer any reason to consider FunctionCall a +potential security hole, since it does not offer direct access to internal +server data representations. + + + +The backend sends ParameterStatus ('S') messages during connection +startup for all parameters it considers interesting to the client library. +Subsequently, a ParameterStatus message is sent whenever the active value +changes for any of these parameters. + + + +The RowDescription ('T') message carries new table OID and column +number fields for each column of the described row. It also shows the format +code for each column. + + + +The CursorResponse ('P') message is no longer generated by +the backend. + + + +The NotificationResponse ('A') message has an additional string +field, which can carry a payload string passed +from the NOTIFY event sender. + + + +The EmptyQueryResponse ('I') message used to include an empty +string parameter; this has been removed. + + + + + diff --git a/doc/src/sgml/queries.sgml b/doc/src/sgml/queries.sgml new file mode 100644 index 000000000000..834b83b50982 --- /dev/null +++ b/doc/src/sgml/queries.sgml @@ -0,0 +1,2706 @@ + + + + Queries + + + query + + + + SELECT + + + + The previous chapters explained how to create tables, how to fill + them with data, and how to manipulate that data. Now we finally + discuss how to retrieve the data from the database. + + + + + Overview + + + The process of retrieving or the command to retrieve data from a + database is called a query. In SQL the + SELECT command is + used to specify queries. The general syntax of the + SELECT command is + +WITH with_queries SELECT select_list FROM table_expression sort_specification + + The following sections describe the details of the select list, the + table expression, and the sort specification. WITH + queries are treated last since they are an advanced feature. + + + + A simple kind of query has the form: + +SELECT * FROM table1; + + Assuming that there is a table called table1, + this command would retrieve all rows and all user-defined columns from + table1. (The method of retrieval depends on the + client application. For example, the + psql program will display an ASCII-art + table on the screen, while client libraries will offer functions to + extract individual values from the query result.) The select list + specification * means all columns that the table + expression happens to provide. A select list can also select a + subset of the available columns or make calculations using the + columns. For example, if + table1 has columns named a, + b, and c (and perhaps others) you can make + the following query: + +SELECT a, b + c FROM table1; + + (assuming that b and c are of a numerical + data type). + See for more details. + + + + FROM table1 is a simple kind of + table expression: it reads just one table. In general, table + expressions can be complex constructs of base tables, joins, and + subqueries. But you can also omit the table expression entirely and + use the SELECT command as a calculator: + +SELECT 3 * 4; + + This is more useful if the expressions in the select list return + varying results. For example, you could call a function this way: + +SELECT random(); + + + + + + + Table Expressions + + + table expression + + + + A table expression computes a table. The + table expression contains a FROM clause that is + optionally followed by WHERE, GROUP BY, and + HAVING clauses. Trivial table expressions simply refer + to a table on disk, a so-called base table, but more complex + expressions can be used to modify or combine base tables in various + ways. + + + + The optional WHERE, GROUP BY, and + HAVING clauses in the table expression specify a + pipeline of successive transformations performed on the table + derived in the FROM clause. All these transformations + produce a virtual table that provides the rows that are passed to + the select list to compute the output rows of the query. + + + + The <literal>FROM</literal> Clause + + + The FROM clause derives a + table from one or more other tables given in a comma-separated + table reference list. + +FROM table_reference , table_reference , ... + + + A table reference can be a table name (possibly schema-qualified), + or a derived table such as a subquery, a JOIN construct, or + complex combinations of these. If more than one table reference is + listed in the FROM clause, the tables are cross-joined + (that is, the Cartesian product of their rows is formed; see below). + The result of the FROM list is an intermediate virtual + table that can then be subject to + transformations by the WHERE, GROUP BY, + and HAVING clauses and is finally the result of the + overall table expression. + + + + ONLY + + + + When a table reference names a table that is the parent of a + table inheritance hierarchy, the table reference produces rows of + not only that table but all of its descendant tables, unless the + key word ONLY precedes the table name. However, the + reference produces only the columns that appear in the named table + — any columns added in subtables are ignored. + + + + Instead of writing ONLY before the table name, you can write + * after the table name to explicitly specify that descendant + tables are included. There is no real reason to use this syntax any more, + because searching descendant tables is now always the default behavior. + However, it is supported for compatibility with older releases. + + + + Joined Tables + + + join + + + + A joined table is a table derived from two other (real or + derived) tables according to the rules of the particular join + type. Inner, outer, and cross-joins are available. + The general syntax of a joined table is + +T1 join_type T2 join_condition + + Joins of all types can be chained together, or nested: either or + both T1 and + T2 can be joined tables. Parentheses + can be used around JOIN clauses to control the join + order. In the absence of parentheses, JOIN clauses + nest left-to-right. + + + + Join Types + + + Cross join + + join + cross + + + + cross join + + + + + +T1 CROSS JOIN T2 + + + + For every possible combination of rows from + T1 and + T2 (i.e., a Cartesian product), + the joined table will contain a + row consisting of all columns in T1 + followed by all columns in T2. If + the tables have N and M rows respectively, the joined + table will have N * M rows. + + + + FROM T1 CROSS JOIN + T2 is equivalent to + FROM T1 INNER JOIN + T2 ON TRUE (see below). + It is also equivalent to + FROM T1, + T2. + + + This latter equivalence does not hold exactly when more than two + tables appear, because JOIN binds more tightly than + comma. For example + FROM T1 CROSS JOIN + T2 INNER JOIN T3 + ON condition + is not the same as + FROM T1, + T2 INNER JOIN T3 + ON condition + because the condition can + reference T1 in the first case but not + the second. + + + + + + + + Qualified joins + + join + outer + + + + outer join + + + + + +T1 { INNER | { LEFT | RIGHT | FULL } OUTER } JOIN T2 ON boolean_expression +T1 { INNER | { LEFT | RIGHT | FULL } OUTER } JOIN T2 USING ( join column list ) +T1 NATURAL { INNER | { LEFT | RIGHT | FULL } OUTER } JOIN T2 + + + + The words INNER and + OUTER are optional in all forms. + INNER is the default; + LEFT, RIGHT, and + FULL imply an outer join. + + + + The join condition is specified in the + ON or USING clause, or implicitly by + the word NATURAL. The join condition determines + which rows from the two source tables are considered to + match, as explained in detail below. + + + + The possible types of qualified join are: + + + + INNER JOIN + + + + For each row R1 of T1, the joined table has a row for each + row in T2 that satisfies the join condition with R1. + + + + + + LEFT OUTER JOIN + + join + left + + + + left join + + + + + + First, an inner join is performed. Then, for each row in + T1 that does not satisfy the join condition with any row in + T2, a joined row is added with null values in columns of + T2. Thus, the joined table always has at least + one row for each row in T1. + + + + + + RIGHT OUTER JOIN + + join + right + + + + right join + + + + + + First, an inner join is performed. Then, for each row in + T2 that does not satisfy the join condition with any row in + T1, a joined row is added with null values in columns of + T1. This is the converse of a left join: the result table + will always have a row for each row in T2. + + + + + + FULL OUTER JOIN + + + + First, an inner join is performed. Then, for each row in + T1 that does not satisfy the join condition with any row in + T2, a joined row is added with null values in columns of + T2. Also, for each row of T2 that does not satisfy the + join condition with any row in T1, a joined row with null + values in the columns of T1 is added. + + + + + + + + The ON clause is the most general kind of join + condition: it takes a Boolean value expression of the same + kind as is used in a WHERE clause. A pair of rows + from T1 and T2 match if the + ON expression evaluates to true. + + + + The USING clause is a shorthand that allows you to take + advantage of the specific situation where both sides of the join use + the same name for the joining column(s). It takes a + comma-separated list of the shared column names + and forms a join condition that includes an equality comparison + for each one. For example, joining T1 + and T2 with USING (a, b) produces + the join condition ON T1.a + = T2.a AND T1.b + = T2.b. + + + + Furthermore, the output of JOIN USING suppresses + redundant columns: there is no need to print both of the matched + columns, since they must have equal values. While JOIN + ON produces all columns from T1 followed by all + columns from T2, JOIN USING produces one + output column for each of the listed column pairs (in the listed + order), followed by any remaining columns from T1, + followed by any remaining columns from T2. + + + + + join + natural + + + natural join + + Finally, NATURAL is a shorthand form of + USING: it forms a USING list + consisting of all column names that appear in both + input tables. As with USING, these columns appear + only once in the output table. If there are no common + column names, NATURAL JOIN behaves like + JOIN ... ON TRUE, producing a cross-product join. + + + + + USING is reasonably safe from column changes + in the joined relations since only the listed columns + are combined. NATURAL is considerably more risky since + any schema changes to either relation that cause a new matching + column name to be present will cause the join to combine that new + column as well. + + + + + + + + To put this together, assume we have tables t1: + + num | name +-----+------ + 1 | a + 2 | b + 3 | c + + and t2: + + num | value +-----+------- + 1 | xxx + 3 | yyy + 5 | zzz + + then we get the following results for the various joins: + +=> SELECT * FROM t1 CROSS JOIN t2; + num | name | num | value +-----+------+-----+------- + 1 | a | 1 | xxx + 1 | a | 3 | yyy + 1 | a | 5 | zzz + 2 | b | 1 | xxx + 2 | b | 3 | yyy + 2 | b | 5 | zzz + 3 | c | 1 | xxx + 3 | c | 3 | yyy + 3 | c | 5 | zzz +(9 rows) + +=> SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num; + num | name | num | value +-----+------+-----+------- + 1 | a | 1 | xxx + 3 | c | 3 | yyy +(2 rows) + +=> SELECT * FROM t1 INNER JOIN t2 USING (num); + num | name | value +-----+------+------- + 1 | a | xxx + 3 | c | yyy +(2 rows) + +=> SELECT * FROM t1 NATURAL INNER JOIN t2; + num | name | value +-----+------+------- + 1 | a | xxx + 3 | c | yyy +(2 rows) + +=> SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num; + num | name | num | value +-----+------+-----+------- + 1 | a | 1 | xxx + 2 | b | | + 3 | c | 3 | yyy +(3 rows) + +=> SELECT * FROM t1 LEFT JOIN t2 USING (num); + num | name | value +-----+------+------- + 1 | a | xxx + 2 | b | + 3 | c | yyy +(3 rows) + +=> SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num; + num | name | num | value +-----+------+-----+------- + 1 | a | 1 | xxx + 3 | c | 3 | yyy + | | 5 | zzz +(3 rows) + +=> SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num; + num | name | num | value +-----+------+-----+------- + 1 | a | 1 | xxx + 2 | b | | + 3 | c | 3 | yyy + | | 5 | zzz +(4 rows) + + + + + The join condition specified with ON can also contain + conditions that do not relate directly to the join. This can + prove useful for some queries but needs to be thought out + carefully. For example: + +=> SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx'; + num | name | num | value +-----+------+-----+------- + 1 | a | 1 | xxx + 2 | b | | + 3 | c | | +(3 rows) + + Notice that placing the restriction in the WHERE clause + produces a different result: + +=> SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx'; + num | name | num | value +-----+------+-----+------- + 1 | a | 1 | xxx +(1 row) + + This is because a restriction placed in the ON + clause is processed before the join, while + a restriction placed in the WHERE clause is processed + after the join. + That does not matter with inner joins, but it matters a lot with outer + joins. + + + + + Table and Column Aliases + + + alias + in the FROM clause + + + + label + alias + + + + A temporary name can be given to tables and complex table + references to be used for references to the derived table in + the rest of the query. This is called a table + alias. + + + + To create a table alias, write + +FROM table_reference AS alias + + or + +FROM table_reference alias + + The AS key word is optional noise. + alias can be any identifier. + + + + A typical application of table aliases is to assign short + identifiers to long table names to keep the join clauses + readable. For example: + +SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.id = a.num; + + + + + The alias becomes the new name of the table reference so far as the + current query is concerned — it is not allowed to refer to the + table by the original name elsewhere in the query. Thus, this is not + valid: + +SELECT * FROM my_table AS m WHERE my_table.a > 5; -- wrong + + + + + Table aliases are mainly for notational convenience, but it is + necessary to use them when joining a table to itself, e.g.: + +SELECT * FROM people AS mother JOIN people AS child ON mother.id = child.mother_id; + + Additionally, an alias is required if the table reference is a + subquery (see ). + + + + Parentheses are used to resolve ambiguities. In the following example, + the first statement assigns the alias b to the second + instance of my_table, but the second statement assigns the + alias to the result of the join: + +SELECT * FROM my_table AS a CROSS JOIN my_table AS b ... +SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b ... + + + + + Another form of table aliasing gives temporary names to the columns of + the table, as well as the table itself: + +FROM table_reference AS alias ( column1 , column2 , ... ) + + If fewer column aliases are specified than the actual table has + columns, the remaining columns are not renamed. This syntax is + especially useful for self-joins or subqueries. + + + + When an alias is applied to the output of a JOIN + clause, the alias hides the original + name(s) within the JOIN. For example: + +SELECT a.* FROM my_table AS a JOIN your_table AS b ON ... + + is valid SQL, but: + +SELECT a.* FROM (my_table AS a JOIN your_table AS b ON ...) AS c + + is not valid; the table alias a is not visible + outside the alias c. + + + + + Subqueries + + + subquery + + + + Subqueries specifying a derived table must be enclosed in + parentheses and must be assigned a table + alias name (as in ). For + example: + +FROM (SELECT * FROM table1) AS alias_name + + + + + This example is equivalent to FROM table1 AS + alias_name. More interesting cases, which cannot be + reduced to a plain join, arise when the subquery involves + grouping or aggregation. + + + + A subquery can also be a VALUES list: + +FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow')) + AS names(first, last) + + Again, a table alias is required. Assigning alias names to the columns + of the VALUES list is optional, but is good practice. + For more information see . + + + + + Table Functions + + table function + + + function + in the FROM clause + + + + Table functions are functions that produce a set of rows, made up + of either base data types (scalar types) or composite data types + (table rows). They are used like a table, view, or subquery in + the FROM clause of a query. Columns returned by table + functions can be included in SELECT, + JOIN, or WHERE clauses in the same manner + as columns of a table, view, or subquery. + + + + Table functions may also be combined using the ROWS FROM + syntax, with the results returned in parallel columns; the number of + result rows in this case is that of the largest function result, with + smaller results padded with null values to match. + + + +function_call WITH ORDINALITY AS table_alias (column_alias , ... ) +ROWS FROM( function_call , ... ) WITH ORDINALITY AS table_alias (column_alias , ... ) + + + + If the WITH ORDINALITY clause is specified, an + additional column of type bigint will be added to the + function result columns. This column numbers the rows of the function + result set, starting from 1. (This is a generalization of the + SQL-standard syntax for UNNEST ... WITH ORDINALITY.) + By default, the ordinal column is called ordinality, but + a different column name can be assigned to it using + an AS clause. + + + + The special table function UNNEST may be called with + any number of array parameters, and it returns a corresponding number of + columns, as if UNNEST + () had been called on each parameter + separately and combined using the ROWS FROM construct. + + + +UNNEST( array_expression , ... ) WITH ORDINALITY AS table_alias (column_alias , ... ) + + + + If no table_alias is specified, the function + name is used as the table name; in the case of a ROWS FROM() + construct, the first function's name is used. + + + + If column aliases are not supplied, then for a function returning a base + data type, the column name is also the same as the function name. For a + function returning a composite type, the result columns get the names + of the individual attributes of the type. + + + + Some examples: + +CREATE TABLE foo (fooid int, foosubid int, fooname text); + +CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$ + SELECT * FROM foo WHERE fooid = $1; +$$ LANGUAGE SQL; + +SELECT * FROM getfoo(1) AS t1; + +SELECT * FROM foo + WHERE foosubid IN ( + SELECT foosubid + FROM getfoo(foo.fooid) z + WHERE z.fooid = foo.fooid + ); + +CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1); + +SELECT * FROM vw_getfoo; + + + + + In some cases it is useful to define table functions that can + return different column sets depending on how they are invoked. + To support this, the table function can be declared as returning + the pseudo-type record with no OUT + parameters. When such a function is used in + a query, the expected row structure must be specified in the + query itself, so that the system can know how to parse and plan + the query. This syntax looks like: + + + +function_call AS alias (column_definition , ... ) +function_call AS alias (column_definition , ... ) +ROWS FROM( ... function_call AS (column_definition , ... ) , ... ) + + + + When not using the ROWS FROM() syntax, + the column_definition list replaces the column + alias list that could otherwise be attached to the FROM + item; the names in the column definitions serve as column aliases. + When using the ROWS FROM() syntax, + a column_definition list can be attached to + each member function separately; or if there is only one member function + and no WITH ORDINALITY clause, + a column_definition list can be written in + place of a column alias list following ROWS FROM(). + + + + Consider this example: + +SELECT * + FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc') + AS t1(proname name, prosrc text) + WHERE proname LIKE 'bytea%'; + + The function + (part of the module) executes + a remote query. It is declared to return + record since it might be used for any kind of query. + The actual column set must be specified in the calling query so + that the parser knows, for example, what * should + expand to. + + + + This example uses ROWS FROM: + +SELECT * +FROM ROWS FROM + ( + json_to_recordset('[{"a":40,"b":"foo"},{"a":"100","b":"bar"}]') + AS (a INTEGER, b TEXT), + generate_series(1, 3) + ) AS x (p, q, s) +ORDER BY p; + + p | q | s +-----+-----+--- + 40 | foo | 1 + 100 | bar | 2 + | | 3 + + It joins two functions into a single FROM + target. json_to_recordset() is instructed + to return two columns, the first integer + and the second text. The result of + generate_series() is used directly. + The ORDER BY clause sorts the column values + as integers. + + + + + <literal>LATERAL</literal> Subqueries + + + LATERAL + in the FROM clause + + + + Subqueries appearing in FROM can be + preceded by the key word LATERAL. This allows them to + reference columns provided by preceding FROM items. + (Without LATERAL, each subquery is + evaluated independently and so cannot cross-reference any other + FROM item.) + + + + Table functions appearing in FROM can also be + preceded by the key word LATERAL, but for functions the + key word is optional; the function's arguments can contain references + to columns provided by preceding FROM items in any case. + + + + A LATERAL item can appear at top level in the + FROM list, or within a JOIN tree. In the latter + case it can also refer to any items that are on the left-hand side of a + JOIN that it is on the right-hand side of. + + + + When a FROM item contains LATERAL + cross-references, evaluation proceeds as follows: for each row of the + FROM item providing the cross-referenced column(s), or + set of rows of multiple FROM items providing the + columns, the LATERAL item is evaluated using that + row or row set's values of the columns. The resulting row(s) are + joined as usual with the rows they were computed from. This is + repeated for each row or set of rows from the column source table(s). + + + + A trivial example of LATERAL is + +SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss; + + This is not especially useful since it has exactly the same result as + the more conventional + +SELECT * FROM foo, bar WHERE bar.id = foo.bar_id; + + LATERAL is primarily useful when the cross-referenced + column is necessary for computing the row(s) to be joined. A common + application is providing an argument value for a set-returning function. + For example, supposing that vertices(polygon) returns the + set of vertices of a polygon, we could identify close-together vertices + of polygons stored in a table with: + +SELECT p1.id, p2.id, v1, v2 +FROM polygons p1, polygons p2, + LATERAL vertices(p1.poly) v1, + LATERAL vertices(p2.poly) v2 +WHERE (v1 <-> v2) < 10 AND p1.id != p2.id; + + This query could also be written + +SELECT p1.id, p2.id, v1, v2 +FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1, + polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2 +WHERE (v1 <-> v2) < 10 AND p1.id != p2.id; + + or in several other equivalent formulations. (As already mentioned, + the LATERAL key word is unnecessary in this example, but + we use it for clarity.) + + + + It is often particularly handy to LEFT JOIN to a + LATERAL subquery, so that source rows will appear in + the result even if the LATERAL subquery produces no + rows for them. For example, if get_product_names() returns + the names of products made by a manufacturer, but some manufacturers in + our table currently produce no products, we could find out which ones + those are like this: + +SELECT m.name +FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true +WHERE pname IS NULL; + + + + + + + The <literal>WHERE</literal> Clause + + + WHERE + + + + The syntax of the WHERE + clause is + +WHERE search_condition + + where search_condition is any value + expression (see ) that + returns a value of type boolean. + + + + After the processing of the FROM clause is done, each + row of the derived virtual table is checked against the search + condition. If the result of the condition is true, the row is + kept in the output table, otherwise (i.e., if the result is + false or null) it is discarded. The search condition typically + references at least one column of the table generated in the + FROM clause; this is not required, but otherwise the + WHERE clause will be fairly useless. + + + + + The join condition of an inner join can be written either in + the WHERE clause or in the JOIN clause. + For example, these table expressions are equivalent: + +FROM a, b WHERE a.id = b.id AND b.val > 5 + + and: + +FROM a INNER JOIN b ON (a.id = b.id) WHERE b.val > 5 + + or perhaps even: + +FROM a NATURAL JOIN b WHERE b.val > 5 + + Which one of these you use is mainly a matter of style. The + JOIN syntax in the FROM clause is + probably not as portable to other SQL database management systems, + even though it is in the SQL standard. For + outer joins there is no choice: they must be done in + the FROM clause. The ON or USING + clause of an outer join is not equivalent to a + WHERE condition, because it results in the addition + of rows (for unmatched input rows) as well as the removal of rows + in the final result. + + + + + Here are some examples of WHERE clauses: + +SELECT ... FROM fdt WHERE c1 > 5 + +SELECT ... FROM fdt WHERE c1 IN (1, 2, 3) + +SELECT ... FROM fdt WHERE c1 IN (SELECT c1 FROM t2) + +SELECT ... FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) + +SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100 + +SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1) + + fdt is the table derived in the + FROM clause. Rows that do not meet the search + condition of the WHERE clause are eliminated from + fdt. Notice the use of scalar subqueries as + value expressions. Just like any other query, the subqueries can + employ complex table expressions. Notice also how + fdt is referenced in the subqueries. + Qualifying c1 as fdt.c1 is only necessary + if c1 is also the name of a column in the derived + input table of the subquery. But qualifying the column name adds + clarity even when it is not needed. This example shows how the column + naming scope of an outer query extends into its inner queries. + + + + + + The <literal>GROUP BY</literal> and <literal>HAVING</literal> Clauses + + + GROUP BY + + + + grouping + + + + After passing the WHERE filter, the derived input + table might be subject to grouping, using the GROUP BY + clause, and elimination of group rows using the HAVING + clause. + + + +SELECT select_list + FROM ... + WHERE ... + GROUP BY grouping_column_reference , grouping_column_reference... + + + + The GROUP BY clause is + used to group together those rows in a table that have the same + values in all the columns listed. The order in which the columns + are listed does not matter. The effect is to combine each set + of rows having common values into one group row that + represents all rows in the group. This is done to + eliminate redundancy in the output and/or compute aggregates that + apply to these groups. For instance: + +=> SELECT * FROM test1; + x | y +---+--- + a | 3 + c | 2 + b | 5 + a | 1 +(4 rows) + +=> SELECT x FROM test1 GROUP BY x; + x +--- + a + b + c +(3 rows) + + + + + In the second query, we could not have written SELECT * + FROM test1 GROUP BY x, because there is no single value + for the column y that could be associated with each + group. The grouped-by columns can be referenced in the select list since + they have a single value in each group. + + + + In general, if a table is grouped, columns that are not + listed in GROUP BY cannot be referenced except in aggregate + expressions. An example with aggregate expressions is: + +=> SELECT x, sum(y) FROM test1 GROUP BY x; + x | sum +---+----- + a | 4 + b | 5 + c | 2 +(3 rows) + + Here sum is an aggregate function that + computes a single value over the entire group. More information + about the available aggregate functions can be found in . + + + + + Grouping without aggregate expressions effectively calculates the + set of distinct values in a column. This can also be achieved + using the DISTINCT clause (see ). + + + + + Here is another example: it calculates the total sales for each + product (rather than the total sales of all products): + +SELECT product_id, p.name, (sum(s.units) * p.price) AS sales + FROM products p LEFT JOIN sales s USING (product_id) + GROUP BY product_id, p.name, p.price; + + In this example, the columns product_id, + p.name, and p.price must be + in the GROUP BY clause since they are referenced in + the query select list (but see below). The column + s.units does not have to be in the GROUP + BY list since it is only used in an aggregate expression + (sum(...)), which represents the sales + of a product. For each product, the query returns a summary row about + all sales of the product. + + + functional dependency + + + If the products table is set up so that, say, + product_id is the primary key, then it would be + enough to group by product_id in the above example, + since name and price would be functionally + dependent on the product ID, and so there would be no + ambiguity about which name and price value to return for each product + ID group. + + + + In strict SQL, GROUP BY can only group by columns of + the source table but PostgreSQL extends + this to also allow GROUP BY to group by columns in the + select list. Grouping by value expressions instead of simple + column names is also allowed. + + + + HAVING + + + + If a table has been grouped using GROUP BY, + but only certain groups are of interest, the + HAVING clause can be used, much like a + WHERE clause, to eliminate groups from the result. + The syntax is: + +SELECT select_list FROM ... WHERE ... GROUP BY ... HAVING boolean_expression + + Expressions in the HAVING clause can refer both to + grouped expressions and to ungrouped expressions (which necessarily + involve an aggregate function). + + + + Example: + +=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3; + x | sum +---+----- + a | 4 + b | 5 +(2 rows) + +=> SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c'; + x | sum +---+----- + a | 4 + b | 5 +(2 rows) + + + + + Again, a more realistic example: + +SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit + FROM products p LEFT JOIN sales s USING (product_id) + WHERE s.date > CURRENT_DATE - INTERVAL '4 weeks' + GROUP BY product_id, p.name, p.price, p.cost + HAVING sum(p.price * s.units) > 5000; + + In the example above, the WHERE clause is selecting + rows by a column that is not grouped (the expression is only true for + sales during the last four weeks), while the HAVING + clause restricts the output to groups with total gross sales over + 5000. Note that the aggregate expressions do not necessarily need + to be the same in all parts of the query. + + + + If a query contains aggregate function calls, but no GROUP BY + clause, grouping still occurs: the result is a single group row (or + perhaps no rows at all, if the single row is then eliminated by + HAVING). + The same is true if it contains a HAVING clause, even + without any aggregate function calls or GROUP BY clause. + + + + + <literal>GROUPING SETS</literal>, <literal>CUBE</literal>, and <literal>ROLLUP</literal> + + + GROUPING SETS + + + CUBE + + + ROLLUP + + + + More complex grouping operations than those described above are possible + using the concept of grouping sets. The data selected by + the FROM and WHERE clauses is grouped separately + by each specified grouping set, aggregates computed for each group just as + for simple GROUP BY clauses, and then the results returned. + For example: + +=> SELECT * FROM items_sold; + brand | size | sales +-------+------+------- + Foo | L | 10 + Foo | M | 20 + Bar | M | 15 + Bar | L | 5 +(4 rows) + +=> SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ()); + brand | size | sum +-------+------+----- + Foo | | 30 + Bar | | 20 + | L | 15 + | M | 35 + | | 50 +(5 rows) + + + + + Each sublist of GROUPING SETS may specify zero or more columns + or expressions and is interpreted the same way as though it were directly + in the GROUP BY clause. An empty grouping set means that all + rows are aggregated down to a single group (which is output even if no + input rows were present), as described above for the case of aggregate + functions with no GROUP BY clause. + + + + References to the grouping columns or expressions are replaced + by null values in result rows for grouping sets in which those + columns do not appear. To distinguish which grouping a particular output + row resulted from, see . + + + + A shorthand notation is provided for specifying two common types of grouping set. + A clause of the form + +ROLLUP ( e1, e2, e3, ... ) + + represents the given list of expressions and all prefixes of the list including + the empty list; thus it is equivalent to + +GROUPING SETS ( + ( e1, e2, e3, ... ), + ... + ( e1, e2 ), + ( e1 ), + ( ) +) + + This is commonly used for analysis over hierarchical data; e.g., total + salary by department, division, and company-wide total. + + + + A clause of the form + +CUBE ( e1, e2, ... ) + + represents the given list and all of its possible subsets (i.e., the power + set). Thus + +CUBE ( a, b, c ) + + is equivalent to + +GROUPING SETS ( + ( a, b, c ), + ( a, b ), + ( a, c ), + ( a ), + ( b, c ), + ( b ), + ( c ), + ( ) +) + + + + + The individual elements of a CUBE or ROLLUP + clause may be either individual expressions, or sublists of elements in + parentheses. In the latter case, the sublists are treated as single + units for the purposes of generating the individual grouping sets. + For example: + +CUBE ( (a, b), (c, d) ) + + is equivalent to + +GROUPING SETS ( + ( a, b, c, d ), + ( a, b ), + ( c, d ), + ( ) +) + + and + +ROLLUP ( a, (b, c), d ) + + is equivalent to + +GROUPING SETS ( + ( a, b, c, d ), + ( a, b, c ), + ( a ), + ( ) +) + + + + + The CUBE and ROLLUP constructs can be used either + directly in the GROUP BY clause, or nested inside a + GROUPING SETS clause. If one GROUPING SETS clause + is nested inside another, the effect is the same as if all the elements of + the inner clause had been written directly in the outer clause. + + + + If multiple grouping items are specified in a single GROUP BY + clause, then the final list of grouping sets is the cross product of the + individual items. For example: + +GROUP BY a, CUBE (b, c), GROUPING SETS ((d), (e)) + + is equivalent to + +GROUP BY GROUPING SETS ( + (a, b, c, d), (a, b, c, e), + (a, b, d), (a, b, e), + (a, c, d), (a, c, e), + (a, d), (a, e) +) + + + + + + ALL + GROUP BY ALL + + + DISTINCT + GROUP BY DISTINCT + + When specifying multiple grouping items together, the final set of grouping + sets might contain duplicates. For example: + +GROUP BY ROLLUP (a, b), ROLLUP (a, c) + + is equivalent to + +GROUP BY GROUPING SETS ( + (a, b, c), + (a, b), + (a, b), + (a, c), + (a), + (a), + (a, c), + (a), + () +) + + If these duplicates are undesirable, they can be removed using the + DISTINCT clause directly on the GROUP BY. + Therefore: + +GROUP BY DISTINCT ROLLUP (a, b), ROLLUP (a, c) + + is equivalent to + +GROUP BY GROUPING SETS ( + (a, b, c), + (a, b), + (a, c), + (a), + () +) + + This is not the same as using SELECT DISTINCT because the output + rows may still contain duplicates. If any of the ungrouped columns contains NULL, + it will be indistinguishable from the NULL used when that same column is grouped. + + + + + The construct (a, b) is normally recognized in expressions as + a row constructor. + Within the GROUP BY clause, this does not apply at the top + levels of expressions, and (a, b) is parsed as a list of + expressions as described above. If for some reason you need + a row constructor in a grouping expression, use ROW(a, b). + + + + + + Window Function Processing + + + window function + order of execution + + + + If the query contains any window functions (see + , + and + ), these functions are evaluated + after any grouping, aggregation, and HAVING filtering is + performed. That is, if the query uses any aggregates, GROUP + BY, or HAVING, then the rows seen by the window functions + are the group rows instead of the original table rows from + FROM/WHERE. + + + + When multiple window functions are used, all the window functions having + syntactically equivalent PARTITION BY and ORDER BY + clauses in their window definitions are guaranteed to be evaluated in a + single pass over the data. Therefore they will see the same sort ordering, + even if the ORDER BY does not uniquely determine an ordering. + However, no guarantees are made about the evaluation of functions having + different PARTITION BY or ORDER BY specifications. + (In such cases a sort step is typically required between the passes of + window function evaluations, and the sort is not guaranteed to preserve + ordering of rows that its ORDER BY sees as equivalent.) + + + + Currently, window functions always require presorted data, and so the + query output will be ordered according to one or another of the window + functions' PARTITION BY/ORDER BY clauses. + It is not recommended to rely on this, however. Use an explicit + top-level ORDER BY clause if you want to be sure the + results are sorted in a particular way. + + + + + + + Select Lists + + + SELECT + select list + + + + As shown in the previous section, + the table expression in the SELECT command + constructs an intermediate virtual table by possibly combining + tables, views, eliminating rows, grouping, etc. This table is + finally passed on to processing by the select list. The select + list determines which columns of the + intermediate table are actually output. + + + + Select-List Items + + + * + + + + The simplest kind of select list is * which + emits all columns that the table expression produces. Otherwise, + a select list is a comma-separated list of value expressions (as + defined in ). For instance, it + could be a list of column names: + +SELECT a, b, c FROM ... + + The columns names a, b, and c + are either the actual names of the columns of tables referenced + in the FROM clause, or the aliases given to them as + explained in . The name + space available in the select list is the same as in the + WHERE clause, unless grouping is used, in which case + it is the same as in the HAVING clause. + + + + If more than one table has a column of the same name, the table + name must also be given, as in: + +SELECT tbl1.a, tbl2.a, tbl1.b FROM ... + + When working with multiple tables, it can also be useful to ask for + all the columns of a particular table: + +SELECT tbl1.*, tbl2.a FROM ... + + See for more about + the table_name.* notation. + + + + If an arbitrary value expression is used in the select list, it + conceptually adds a new virtual column to the returned table. The + value expression is evaluated once for each result row, with + the row's values substituted for any column references. But the + expressions in the select list do not have to reference any + columns in the table expression of the FROM clause; + they can be constant arithmetic expressions, for instance. + + + + + Column Labels + + + alias + in the select list + + + + The entries in the select list can be assigned names for subsequent + processing, such as for use in an ORDER BY clause + or for display by the client application. For example: + +SELECT a AS value, b + c AS sum FROM ... + + + + + If no output column name is specified using AS, + the system assigns a default column name. For simple column references, + this is the name of the referenced column. For function + calls, this is the name of the function. For complex expressions, + the system will generate a generic name. + + + + The AS key word is usually optional, but in some + cases where the desired column name matches a + PostgreSQL key word, you must write + AS or double-quote the column name in order to + avoid ambiguity. + ( shows which key words + require AS to be used as a column label.) + For example, FROM is one such key word, so this + does not work: + +SELECT a from, b + c AS sum FROM ... + + but either of these do: + +SELECT a AS from, b + c AS sum FROM ... +SELECT a "from", b + c AS sum FROM ... + + For greatest safety against possible + future key word additions, it is recommended that you always either + write AS or double-quote the output column name. + + + + + The naming of output columns here is different from that done in + the FROM clause (see ). It is possible + to rename the same column twice, but the name assigned in + the select list is the one that will be passed on. + + + + + + <literal>DISTINCT</literal> + + + ALL + SELECT ALL + + + DISTINCT + SELECT DISTINCT + + + + duplicates + + + + After the select list has been processed, the result table can + optionally be subject to the elimination of duplicate rows. The + DISTINCT key word is written directly after + SELECT to specify this: + +SELECT DISTINCT select_list ... + + (Instead of DISTINCT the key word ALL + can be used to specify the default behavior of retaining all rows.) + + + + null value + in DISTINCT + + + + Obviously, two rows are considered distinct if they differ in at + least one column value. Null values are considered equal in this + comparison. + + + + Alternatively, an arbitrary expression can determine what rows are + to be considered distinct: + +SELECT DISTINCT ON (expression , expression ...) select_list ... + + Here expression is an arbitrary value + expression that is evaluated for all rows. A set of rows for + which all the expressions are equal are considered duplicates, and + only the first row of the set is kept in the output. Note that + the first row of a set is unpredictable unless the + query is sorted on enough columns to guarantee a unique ordering + of the rows arriving at the DISTINCT filter. + (DISTINCT ON processing occurs after ORDER + BY sorting.) + + + + The DISTINCT ON clause is not part of the SQL standard + and is sometimes considered bad style because of the potentially + indeterminate nature of its results. With judicious use of + GROUP BY and subqueries in FROM, this + construct can be avoided, but it is often the most convenient + alternative. + + + + + + + Combining Queries (<literal>UNION</literal>, <literal>INTERSECT</literal>, <literal>EXCEPT</literal>) + + + UNION + + + INTERSECT + + + EXCEPT + + + set union + + + set intersection + + + set difference + + + set operation + + + + The results of two queries can be combined using the set operations + union, intersection, and difference. The syntax is + +query1 UNION ALL query2 +query1 INTERSECT ALL query2 +query1 EXCEPT ALL query2 + + query1 and + query2 are queries that can use any of + the features discussed up to this point. Set operations can also + be nested and chained, for example + +query1 UNION query2 UNION query3 + + which is executed as: + +(query1 UNION query2) UNION query3 + + + + + UNION effectively appends the result of + query2 to the result of + query1 (although there is no guarantee + that this is the order in which the rows are actually returned). + Furthermore, it eliminates duplicate rows from its result, in the same + way as DISTINCT, unless UNION ALL is used. + + + + INTERSECT returns all rows that are both in the result + of query1 and in the result of + query2. Duplicate rows are eliminated + unless INTERSECT ALL is used. + + + + EXCEPT returns all rows that are in the result of + query1 but not in the result of + query2. (This is sometimes called the + difference between two queries.) Again, duplicates + are eliminated unless EXCEPT ALL is used. + + + + In order to calculate the union, intersection, or difference of two + queries, the two queries must be union compatible, + which means that they return the same number of columns and + the corresponding columns have compatible data types, as + described in . + + + + + + Sorting Rows (<literal>ORDER BY</literal>) + + + sorting + + + + ORDER BY + + + + After a query has produced an output table (after the select list + has been processed) it can optionally be sorted. If sorting is not + chosen, the rows will be returned in an unspecified order. The actual + order in that case will depend on the scan and join plan types and + the order on disk, but it must not be relied on. A particular + output ordering can only be guaranteed if the sort step is explicitly + chosen. + + + + The ORDER BY clause specifies the sort order: + +SELECT select_list + FROM table_expression + ORDER BY sort_expression1 ASC | DESC NULLS { FIRST | LAST } + , sort_expression2 ASC | DESC NULLS { FIRST | LAST } ... + + The sort expression(s) can be any expression that would be valid in the + query's select list. An example is: + +SELECT a, b FROM table1 ORDER BY a + b, c; + + When more than one expression is specified, + the later values are used to sort rows that are equal according to the + earlier values. Each expression can be followed by an optional + ASC or DESC keyword to set the sort direction to + ascending or descending. ASC order is the default. + Ascending order puts smaller values first, where + smaller is defined in terms of the + < operator. Similarly, descending order is + determined with the > operator. + + + Actually, PostgreSQL uses the default B-tree + operator class for the expression's data type to determine the sort + ordering for ASC and DESC. Conventionally, + data types will be set up so that the < and + > operators correspond to this sort ordering, + but a user-defined data type's designer could choose to do something + different. + + + + + + The NULLS FIRST and NULLS LAST options can be + used to determine whether nulls appear before or after non-null values + in the sort ordering. By default, null values sort as if larger than any + non-null value; that is, NULLS FIRST is the default for + DESC order, and NULLS LAST otherwise. + + + + Note that the ordering options are considered independently for each + sort column. For example ORDER BY x, y DESC means + ORDER BY x ASC, y DESC, which is not the same as + ORDER BY x DESC, y DESC. + + + + A sort_expression can also be the column label or number + of an output column, as in: + +SELECT a + b AS sum, c FROM table1 ORDER BY sum; +SELECT a, max(b) FROM table1 GROUP BY a ORDER BY 1; + + both of which sort by the first output column. Note that an output + column name has to stand alone, that is, it cannot be used in an expression + — for example, this is not correct: + +SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- wrong + + This restriction is made to reduce ambiguity. There is still + ambiguity if an ORDER BY item is a simple name that + could match either an output column name or a column from the table + expression. The output column is used in such cases. This would + only cause confusion if you use AS to rename an output + column to match some other table column's name. + + + + ORDER BY can be applied to the result of a + UNION, INTERSECT, or EXCEPT + combination, but in this case it is only permitted to sort by + output column names or numbers, not by expressions. + + + + + + <literal>LIMIT</literal> and <literal>OFFSET</literal> + + + LIMIT + + + + OFFSET + + + + LIMIT and OFFSET allow you to retrieve just + a portion of the rows that are generated by the rest of the query: + +SELECT select_list + FROM table_expression + ORDER BY ... + LIMIT { number | ALL } OFFSET number + + + + + If a limit count is given, no more than that many rows will be + returned (but possibly fewer, if the query itself yields fewer rows). + LIMIT ALL is the same as omitting the LIMIT + clause, as is LIMIT with a NULL argument. + + + + OFFSET says to skip that many rows before beginning to + return rows. OFFSET 0 is the same as omitting the + OFFSET clause, as is OFFSET with a NULL argument. + + + + If both OFFSET + and LIMIT appear, then OFFSET rows are + skipped before starting to count the LIMIT rows that + are returned. + + + + When using LIMIT, it is important to use an + ORDER BY clause that constrains the result rows into a + unique order. Otherwise you will get an unpredictable subset of + the query's rows. You might be asking for the tenth through + twentieth rows, but tenth through twentieth in what ordering? The + ordering is unknown, unless you specified ORDER BY. + + + + The query optimizer takes LIMIT into account when + generating query plans, so you are very likely to get different + plans (yielding different row orders) depending on what you give + for LIMIT and OFFSET. Thus, using + different LIMIT/OFFSET values to select + different subsets of a query result will give + inconsistent results unless you enforce a predictable + result ordering with ORDER BY. This is not a bug; it + is an inherent consequence of the fact that SQL does not promise to + deliver the results of a query in any particular order unless + ORDER BY is used to constrain the order. + + + + The rows skipped by an OFFSET clause still have to be + computed inside the server; therefore a large OFFSET + might be inefficient. + + + + + + <literal>VALUES</literal> Lists + + + VALUES + + + + VALUES provides a way to generate a constant table + that can be used in a query without having to actually create and populate + a table on-disk. The syntax is + +VALUES ( expression [, ...] ) [, ...] + + Each parenthesized list of expressions generates a row in the table. + The lists must all have the same number of elements (i.e., the number + of columns in the table), and corresponding entries in each list must + have compatible data types. The actual data type assigned to each column + of the result is determined using the same rules as for UNION + (see ). + + + + As an example: + +VALUES (1, 'one'), (2, 'two'), (3, 'three'); + + + will return a table of two columns and three rows. It's effectively + equivalent to: + +SELECT 1 AS column1, 'one' AS column2 +UNION ALL +SELECT 2, 'two' +UNION ALL +SELECT 3, 'three'; + + + By default, PostgreSQL assigns the names + column1, column2, etc. to the columns of a + VALUES table. The column names are not specified by the + SQL standard and different database systems do it differently, so + it's usually better to override the default names with a table alias + list, like this: + +=> SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter); + num | letter +-----+-------- + 1 | one + 2 | two + 3 | three +(3 rows) + + + + + Syntactically, VALUES followed by expression lists is + treated as equivalent to: + +SELECT select_list FROM table_expression + + and can appear anywhere a SELECT can. For example, you can + use it as part of a UNION, or attach a + sort_specification (ORDER BY, + LIMIT, and/or OFFSET) to it. VALUES + is most commonly used as the data source in an INSERT command, + and next most commonly as a subquery. + + + + For more information see . + + + + + + + <literal>WITH</literal> Queries (Common Table Expressions) + + + WITH + in SELECT + + + + common table expression + WITH + + + + WITH provides a way to write auxiliary statements for use in a + larger query. These statements, which are often referred to as Common + Table Expressions or CTEs, can be thought of as defining + temporary tables that exist just for one query. Each auxiliary statement + in a WITH clause can be a SELECT, + INSERT, UPDATE, or DELETE; and the + WITH clause itself is attached to a primary statement that can + also be a SELECT, INSERT, UPDATE, or + DELETE. + + + + <command>SELECT</command> in <literal>WITH</literal> + + + The basic value of SELECT in WITH is to + break down complicated queries into simpler parts. An example is: + + +WITH regional_sales AS ( + SELECT region, SUM(amount) AS total_sales + FROM orders + GROUP BY region +), top_regions AS ( + SELECT region + FROM regional_sales + WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales) +) +SELECT region, + product, + SUM(quantity) AS product_units, + SUM(amount) AS product_sales +FROM orders +WHERE region IN (SELECT region FROM top_regions) +GROUP BY region, product; + + + which displays per-product sales totals in only the top sales regions. + The WITH clause defines two auxiliary statements named + regional_sales and top_regions, + where the output of regional_sales is used in + top_regions and the output of top_regions + is used in the primary SELECT query. + This example could have been written without WITH, + but we'd have needed two levels of nested sub-SELECTs. It's a bit + easier to follow this way. + + + + + Recursive Queries + + + + RECURSIVE + in common table expressions + + The optional RECURSIVE modifier changes WITH + from a mere syntactic convenience into a feature that accomplishes + things not otherwise possible in standard SQL. Using + RECURSIVE, a WITH query can refer to its own + output. A very simple example is this query to sum the integers from 1 + through 100: + + +WITH RECURSIVE t(n) AS ( + VALUES (1) + UNION ALL + SELECT n+1 FROM t WHERE n < 100 +) +SELECT sum(n) FROM t; + + + The general form of a recursive WITH query is always a + non-recursive term, then UNION (or + UNION ALL), then a + recursive term, where only the recursive term can contain + a reference to the query's own output. Such a query is executed as + follows: + + + + Recursive Query Evaluation + + + + Evaluate the non-recursive term. For UNION (but not + UNION ALL), discard duplicate rows. Include all remaining + rows in the result of the recursive query, and also place them in a + temporary working table. + + + + + + So long as the working table is not empty, repeat these steps: + + + + + Evaluate the recursive term, substituting the current contents of + the working table for the recursive self-reference. + For UNION (but not UNION ALL), discard + duplicate rows and rows that duplicate any previous result row. + Include all remaining rows in the result of the recursive query, and + also place them in a temporary intermediate table. + + + + + + Replace the contents of the working table with the contents of the + intermediate table, then empty the intermediate table. + + + + + + + + + Strictly speaking, this process is iteration not recursion, but + RECURSIVE is the terminology chosen by the SQL standards + committee. + + + + + In the example above, the working table has just a single row in each step, + and it takes on the values from 1 through 100 in successive steps. In + the 100th step, there is no output because of the WHERE + clause, and so the query terminates. + + + + Recursive queries are typically used to deal with hierarchical or + tree-structured data. A useful example is this query to find all the + direct and indirect sub-parts of a product, given only a table that + shows immediate inclusions: + + +WITH RECURSIVE included_parts(sub_part, part, quantity) AS ( + SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product' + UNION ALL + SELECT p.sub_part, p.part, p.quantity + FROM included_parts pr, parts p + WHERE p.part = pr.sub_part +) +SELECT sub_part, SUM(quantity) as total_quantity +FROM included_parts +GROUP BY sub_part + + + + + Search Order + + + When computing a tree traversal using a recursive query, you might want to + order the results in either depth-first or breadth-first order. This can + be done by computing an ordering column alongside the other data columns + and using that to sort the results at the end. Note that this does not + actually control in which order the query evaluation visits the rows; that + is as always in SQL implementation-dependent. This approach merely + provides a convenient way to order the results afterwards. + + + + To create a depth-first order, we compute for each result row an array of + rows that we have visited so far. For example, consider the following + query that searches a table tree using a + link field: + + +WITH RECURSIVE search_tree(id, link, data) AS ( + SELECT t.id, t.link, t.data + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data + FROM tree t, search_tree st + WHERE t.id = st.link +) +SELECT * FROM search_tree; + + + To add depth-first ordering information, you can write this: + + +WITH RECURSIVE search_tree(id, link, data, path) AS ( + SELECT t.id, t.link, t.data, ARRAY[t.id] + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data, path || t.id + FROM tree t, search_tree st + WHERE t.id = st.link +) +SELECT * FROM search_tree ORDER BY path; + + + + + In the general case where more than one field needs to be used to identify + a row, use an array of rows. For example, if we needed to track fields + f1 and f2: + + +WITH RECURSIVE search_tree(id, link, data, path) AS ( + SELECT t.id, t.link, t.data, ARRAY[ROW(t.f1, t.f2)] + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data, path || ROW(t.f1, t.f2) + FROM tree t, search_tree st + WHERE t.id = st.link +) +SELECT * FROM search_tree ORDER BY path; + + + + + + Omit the ROW() syntax in the common case where only one + field needs to be tracked. This allows a simple array rather than a + composite-type array to be used, gaining efficiency. + + + + + To create a breadth-first order, you can add a column that tracks the depth + of the search, for example: + + +WITH RECURSIVE search_tree(id, link, data, depth) AS ( + SELECT t.id, t.link, t.data, 0 + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data, depth + 1 + FROM tree t, search_tree st + WHERE t.id = st.link +) +SELECT * FROM search_tree ORDER BY depth; + + + To get a stable sort, add data columns as secondary sorting columns. + + + + + The recursive query evaluation algorithm produces its output in + breadth-first search order. However, this is an implementation detail and + it is perhaps unsound to rely on it. The order of the rows within each + level is certainly undefined, so some explicit ordering might be desired + in any case. + + + + + There is built-in syntax to compute a depth- or breadth-first sort column. + For example: + + +WITH RECURSIVE search_tree(id, link, data) AS ( + SELECT t.id, t.link, t.data + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data + FROM tree t, search_tree st + WHERE t.id = st.link +) SEARCH DEPTH FIRST BY id SET ordercol +SELECT * FROM search_tree ORDER BY ordercol; + +WITH RECURSIVE search_tree(id, link, data) AS ( + SELECT t.id, t.link, t.data + FROM tree t + UNION ALL + SELECT t.id, t.link, t.data + FROM tree t, search_tree st + WHERE t.id = st.link +) SEARCH BREADTH FIRST BY id SET ordercol +SELECT * FROM search_tree ORDER BY ordercol; + + This syntax is internally expanded to something similar to the above + hand-written forms. The SEARCH clause specifies whether + depth- or breadth first search is wanted, the list of columns to track for + sorting, and a column name that will contain the result data that can be + used for sorting. That column will implicitly be added to the output rows + of the CTE. + + + + + Cycle Detection + + + When working with recursive queries it is important to be sure that + the recursive part of the query will eventually return no tuples, + or else the query will loop indefinitely. Sometimes, using + UNION instead of UNION ALL can accomplish this + by discarding rows that duplicate previous output rows. However, often a + cycle does not involve output rows that are completely duplicate: it may be + necessary to check just one or a few fields to see if the same point has + been reached before. The standard method for handling such situations is + to compute an array of the already-visited values. For example, consider again + the following query that searches a table graph using a + link field: + + +WITH RECURSIVE search_graph(id, link, data, depth) AS ( + SELECT g.id, g.link, g.data, 0 + FROM graph g + UNION ALL + SELECT g.id, g.link, g.data, sg.depth + 1 + FROM graph g, search_graph sg + WHERE g.id = sg.link +) +SELECT * FROM search_graph; + + + This query will loop if the link relationships contain + cycles. Because we require a depth output, just changing + UNION ALL to UNION would not eliminate the looping. + Instead we need to recognize whether we have reached the same row again + while following a particular path of links. We add two columns + is_cycle and path to the loop-prone query: + + +WITH RECURSIVE search_graph(id, link, data, depth, is_cycle, path) AS ( + SELECT g.id, g.link, g.data, 0, + false, + ARRAY[g.id] + FROM graph g + UNION ALL + SELECT g.id, g.link, g.data, sg.depth + 1, + g.id = ANY(path), + path || g.id + FROM graph g, search_graph sg + WHERE g.id = sg.link AND NOT is_cycle +) +SELECT * FROM search_graph; + + + Aside from preventing cycles, the array value is often useful in its own + right as representing the path taken to reach any particular row. + + + + In the general case where more than one field needs to be checked to + recognize a cycle, use an array of rows. For example, if we needed to + compare fields f1 and f2: + + +WITH RECURSIVE search_graph(id, link, data, depth, is_cycle, path) AS ( + SELECT g.id, g.link, g.data, 0, + false, + ARRAY[ROW(g.f1, g.f2)] + FROM graph g + UNION ALL + SELECT g.id, g.link, g.data, sg.depth + 1, + ROW(g.f1, g.f2) = ANY(path), + path || ROW(g.f1, g.f2) + FROM graph g, search_graph sg + WHERE g.id = sg.link AND NOT is_cycle +) +SELECT * FROM search_graph; + + + + + + Omit the ROW() syntax in the common case where only one field + needs to be checked to recognize a cycle. This allows a simple array + rather than a composite-type array to be used, gaining efficiency. + + + + + There is built-in syntax to simplify cycle detection. The above query can + also be written like this: + +WITH RECURSIVE search_graph(id, link, data, depth) AS ( + SELECT g.id, g.link, g.data, 1 + FROM graph g + UNION ALL + SELECT g.id, g.link, g.data, sg.depth + 1 + FROM graph g, search_graph sg + WHERE g.id = sg.link +) CYCLE id SET is_cycle USING path +SELECT * FROM search_graph; + + and it will be internally rewritten to the above form. The + CYCLE clause specifies first the list of columns to + track for cycle detection, then a column name that will show whether a + cycle has been detected, and finally the name of another column that will track the + path. The cycle and path columns will implicitly be added to the output + rows of the CTE. + + + + + The cycle path column is computed in the same way as the depth-first + ordering column show in the previous section. A query can have both a + SEARCH and a CYCLE clause, but a + depth-first search specification and a cycle detection specification would + create redundant computations, so it's more efficient to just use the + CYCLE clause and order by the path column. If + breadth-first ordering is wanted, then specifying both + SEARCH and CYCLE can be useful. + + + + + A helpful trick for testing queries + when you are not certain if they might loop is to place a LIMIT + in the parent query. For example, this query would loop forever without + the LIMIT: + + +WITH RECURSIVE t(n) AS ( + SELECT 1 + UNION ALL + SELECT n+1 FROM t +) +SELECT n FROM t LIMIT 100; + + + This works because PostgreSQL's implementation + evaluates only as many rows of a WITH query as are actually + fetched by the parent query. Using this trick in production is not + recommended, because other systems might work differently. Also, it + usually won't work if you make the outer query sort the recursive query's + results or join them to some other table, because in such cases the + outer query will usually try to fetch all of the WITH query's + output anyway. + + + + + + Common Table Expression Materialization + + + A useful property of WITH queries is that they are + normally evaluated only once per execution of the parent query, even if + they are referred to more than once by the parent query or + sibling WITH queries. + Thus, expensive calculations that are needed in multiple places can be + placed within a WITH query to avoid redundant work. Another + possible application is to prevent unwanted multiple evaluations of + functions with side-effects. + However, the other side of this coin is that the optimizer is not able to + push restrictions from the parent query down into a multiply-referenced + WITH query, since that might affect all uses of the + WITH query's output when it should affect only one. + The multiply-referenced WITH query will be + evaluated as written, without suppression of rows that the parent query + might discard afterwards. (But, as mentioned above, evaluation might stop + early if the reference(s) to the query demand only a limited number of + rows.) + + + + However, if a WITH query is non-recursive and + side-effect-free (that is, it is a SELECT containing + no volatile functions) then it can be folded into the parent query, + allowing joint optimization of the two query levels. By default, this + happens if the parent query references the WITH query + just once, but not if it references the WITH query + more than once. You can override that decision by + specifying MATERIALIZED to force separate calculation + of the WITH query, or by specifying NOT + MATERIALIZED to force it to be merged into the parent query. + The latter choice risks duplicate computation of + the WITH query, but it can still give a net savings if + each usage of the WITH query needs only a small part + of the WITH query's full output. + + + + A simple example of these rules is + +WITH w AS ( + SELECT * FROM big_table +) +SELECT * FROM w WHERE key = 123; + + This WITH query will be folded, producing the same + execution plan as + +SELECT * FROM big_table WHERE key = 123; + + In particular, if there's an index on key, + it will probably be used to fetch just the rows having key = + 123. On the other hand, in + +WITH w AS ( + SELECT * FROM big_table +) +SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref +WHERE w2.key = 123; + + the WITH query will be materialized, producing a + temporary copy of big_table that is then + joined with itself — without benefit of any index. This query + will be executed much more efficiently if written as + +WITH w AS NOT MATERIALIZED ( + SELECT * FROM big_table +) +SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref +WHERE w2.key = 123; + + so that the parent query's restrictions can be applied directly + to scans of big_table. + + + + An example where NOT MATERIALIZED could be + undesirable is + +WITH w AS ( + SELECT key, very_expensive_function(val) as f FROM some_table +) +SELECT * FROM w AS w1 JOIN w AS w2 ON w1.f = w2.f; + + Here, materialization of the WITH query ensures + that very_expensive_function is evaluated only + once per table row, not twice. + + + + The examples above only show WITH being used with + SELECT, but it can be attached in the same way to + INSERT, UPDATE, or DELETE. + In each case it effectively provides temporary table(s) that can + be referred to in the main command. + + + + + Data-Modifying Statements in <literal>WITH</literal> + + + You can use data-modifying statements (INSERT, + UPDATE, or DELETE) in WITH. This + allows you to perform several different operations in the same query. + An example is: + + +WITH moved_rows AS ( + DELETE FROM products + WHERE + "date" >= '2010-10-01' AND + "date" < '2010-11-01' + RETURNING * +) +INSERT INTO products_log +SELECT * FROM moved_rows; + + + This query effectively moves rows from products to + products_log. The DELETE in WITH + deletes the specified rows from products, returning their + contents by means of its RETURNING clause; and then the + primary query reads that output and inserts it into + products_log. + + + + A fine point of the above example is that the WITH clause is + attached to the INSERT, not the sub-SELECT within + the INSERT. This is necessary because data-modifying + statements are only allowed in WITH clauses that are attached + to the top-level statement. However, normal WITH visibility + rules apply, so it is possible to refer to the WITH + statement's output from the sub-SELECT. + + + + Data-modifying statements in WITH usually have + RETURNING clauses (see ), + as shown in the example above. + It is the output of the RETURNING clause, not the + target table of the data-modifying statement, that forms the temporary + table that can be referred to by the rest of the query. If a + data-modifying statement in WITH lacks a RETURNING + clause, then it forms no temporary table and cannot be referred to in + the rest of the query. Such a statement will be executed nonetheless. + A not-particularly-useful example is: + + +WITH t AS ( + DELETE FROM foo +) +DELETE FROM bar; + + + This example would remove all rows from tables foo and + bar. The number of affected rows reported to the client + would only include rows removed from bar. + + + + Recursive self-references in data-modifying statements are not + allowed. In some cases it is possible to work around this limitation by + referring to the output of a recursive WITH, for example: + + +WITH RECURSIVE included_parts(sub_part, part) AS ( + SELECT sub_part, part FROM parts WHERE part = 'our_product' + UNION ALL + SELECT p.sub_part, p.part + FROM included_parts pr, parts p + WHERE p.part = pr.sub_part +) +DELETE FROM parts + WHERE part IN (SELECT part FROM included_parts); + + + This query would remove all direct and indirect subparts of a product. + + + + Data-modifying statements in WITH are executed exactly once, + and always to completion, independently of whether the primary query + reads all (or indeed any) of their output. Notice that this is different + from the rule for SELECT in WITH: as stated in the + previous section, execution of a SELECT is carried only as far + as the primary query demands its output. + + + + The sub-statements in WITH are executed concurrently with + each other and with the main query. Therefore, when using data-modifying + statements in WITH, the order in which the specified updates + actually happen is unpredictable. All the statements are executed with + the same snapshot (see ), so they + cannot see one another's effects on the target tables. This + alleviates the effects of the unpredictability of the actual order of row + updates, and means that RETURNING data is the only way to + communicate changes between different WITH sub-statements and + the main query. An example of this is that in + + +WITH t AS ( + UPDATE products SET price = price * 1.05 + RETURNING * +) +SELECT * FROM products; + + + the outer SELECT would return the original prices before the + action of the UPDATE, while in + + +WITH t AS ( + UPDATE products SET price = price * 1.05 + RETURNING * +) +SELECT * FROM t; + + + the outer SELECT would return the updated data. + + + + Trying to update the same row twice in a single statement is not + supported. Only one of the modifications takes place, but it is not easy + (and sometimes not possible) to reliably predict which one. This also + applies to deleting a row that was already updated in the same statement: + only the update is performed. Therefore you should generally avoid trying + to modify a single row twice in a single statement. In particular avoid + writing WITH sub-statements that could affect the same rows + changed by the main statement or a sibling sub-statement. The effects + of such a statement will not be predictable. + + + + At present, any table used as the target of a data-modifying statement in + WITH must not have a conditional rule, nor an ALSO + rule, nor an INSTEAD rule that expands to multiple statements. + + + + + + + diff --git a/doc/src/sgml/query.sgml b/doc/src/sgml/query.sgml new file mode 100644 index 000000000000..71d644f43234 --- /dev/null +++ b/doc/src/sgml/query.sgml @@ -0,0 +1,876 @@ + + + + The <acronym>SQL</acronym> Language + + + Introduction + + + This chapter provides an overview of how to use + SQL to perform simple operations. This + tutorial is only intended to give you an introduction and is in no + way a complete tutorial on SQL. Numerous books + have been written on SQL, including and . + You should be aware that some PostgreSQL + language features are extensions to the standard. + + + + In the examples that follow, we assume that you have created a + database named mydb, as described in the previous + chapter, and have been able to start psql. + + + + Examples in this manual can also be found in the + PostgreSQL source distribution + in the directory src/tutorial/. (Binary + distributions of PostgreSQL might not + provide those files.) To use those + files, first change to that directory and run make: + + +$ cd .../src/tutorial +$ make + + + This creates the scripts and compiles the C files containing user-defined + functions and types. Then, to start the tutorial, do the following: + + +$ psql -s mydb + +... + +mydb=> \i basics.sql + + + The \i command reads in commands from the + specified file. psql's -s option puts you in + single step mode which pauses before sending each statement to the + server. The commands used in this section are in the file + basics.sql. + + + + + + Concepts + + + relational database + hierarchical database + object-oriented database + relation + table + + PostgreSQL is a relational + database management system (RDBMS). + That means it is a system for managing data stored in + relations. Relation is essentially a + mathematical term for table. The notion of + storing data in tables is so commonplace today that it might + seem inherently obvious, but there are a number of other ways of + organizing databases. Files and directories on Unix-like + operating systems form an example of a hierarchical database. A + more modern development is the object-oriented database. + + + + row + column + + Each table is a named collection of rows. + Each row of a given table has the same set of named + columns, + and each column is of a specific data type. Whereas columns have + a fixed order in each row, it is important to remember that SQL + does not guarantee the order of the rows within the table in any + way (although they can be explicitly sorted for display). + + + + database cluster + clusterof databasesdatabase cluster + + Tables are grouped into databases, and a collection of databases + managed by a single PostgreSQL server + instance constitutes a database cluster. + + + + + + Creating a New Table + + + CREATE TABLE + + + + You can create a new table by specifying the table + name, along with all column names and their types: + + +CREATE TABLE weather ( + city varchar(80), + temp_lo int, -- low temperature + temp_hi int, -- high temperature + prcp real, -- precipitation + date date +); + + + You can enter this into psql with the line + breaks. psql will recognize that the command + is not terminated until the semicolon. + + + + White space (i.e., spaces, tabs, and newlines) can be used freely + in SQL commands. That means you can type the command aligned + differently than above, or even all on one line. Two dashes + (--) introduce comments. + Whatever follows them is ignored up to the end of the line. SQL + is case insensitive about key words and identifiers, except + when identifiers are double-quoted to preserve the case (not done + above). + + + + varchar(80) specifies a data type that can store + arbitrary character strings up to 80 characters in length. + int is the normal integer type. real is + a type for storing single precision floating-point numbers. + date should be self-explanatory. (Yes, the column of + type date is also named date. + This might be convenient or confusing — you choose.) + + + + PostgreSQL supports the standard + SQL types int, + smallint, real, double + precision, char(N), + varchar(N), date, + time, timestamp, and + interval, as well as other types of general utility + and a rich set of geometric types. + PostgreSQL can be customized with an + arbitrary number of user-defined data types. Consequently, type + names are not key words in the syntax, except where required to + support special cases in the SQL standard. + + + + The second example will store cities and their associated + geographical location: + +CREATE TABLE cities ( + name varchar(80), + location point +); + + The point type is an example of a + PostgreSQL-specific data type. + + + + + DROP TABLE + + + Finally, it should be mentioned that if you don't need a table any + longer or want to recreate it differently you can remove it using + the following command: + +DROP TABLE tablename; + + + + + + + Populating a Table With Rows + + + INSERT + + + + The INSERT statement is used to populate a table with + rows: + + +INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27'); + + + Note that all data types use rather obvious input formats. + Constants that are not simple numeric values usually must be + surrounded by single quotes ('), as in the example. + The + date type is actually quite flexible in what it + accepts, but for this tutorial we will stick to the unambiguous + format shown here. + + + + The point type requires a coordinate pair as input, + as shown here: + +INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)'); + + + + + The syntax used so far requires you to remember the order of the + columns. An alternative syntax allows you to list the columns + explicitly: + +INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) + VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29'); + + You can list the columns in a different order if you wish or + even omit some columns, e.g., if the precipitation is unknown: + +INSERT INTO weather (date, city, temp_hi, temp_lo) + VALUES ('1994-11-29', 'Hayward', 54, 37); + + Many developers consider explicitly listing the columns better + style than relying on the order implicitly. + + + + Please enter all the commands shown above so you have some data to + work with in the following sections. + + + + + COPY + + + You could also have used COPY to load large + amounts of data from flat-text files. This is usually faster + because the COPY command is optimized for this + application while allowing less flexibility than + INSERT. An example would be: + + +COPY weather FROM '/home/user/weather.txt'; + + + where the file name for the source file must be available on the + machine running the backend process, not the client, since the backend process + reads the file directly. You can read more about the + COPY command in . + + + + + + Querying a Table + + + query + SELECT + + To retrieve data from a table, the table is + queried. An SQL + SELECT statement is used to do this. The + statement is divided into a select list (the part that lists the + columns to be returned), a table list (the part that lists the + tables from which to retrieve the data), and an optional + qualification (the part that specifies any restrictions). For + example, to retrieve all the rows of table + weather, type: + +SELECT * FROM weather; + + Here * is a shorthand for all columns. + + + While SELECT * is useful for off-the-cuff + queries, it is widely considered bad style in production code, + since adding a column to the table would change the results. + + + So the same result would be had with: + +SELECT city, temp_lo, temp_hi, prcp, date FROM weather; + + + The output should be: + + + city | temp_lo | temp_hi | prcp | date +---------------+---------+---------+------+------------ + San Francisco | 46 | 50 | 0.25 | 1994-11-27 + San Francisco | 43 | 57 | 0 | 1994-11-29 + Hayward | 37 | 54 | | 1994-11-29 +(3 rows) + + + + + You can write expressions, not just simple column references, in the + select list. For example, you can do: + +SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather; + + This should give: + + city | temp_avg | date +---------------+----------+------------ + San Francisco | 48 | 1994-11-27 + San Francisco | 50 | 1994-11-29 + Hayward | 45 | 1994-11-29 +(3 rows) + + Notice how the AS clause is used to relabel the + output column. (The AS clause is optional.) + + + + A query can be qualified by adding a WHERE + clause that specifies which rows are wanted. The WHERE + clause contains a Boolean (truth value) expression, and only rows for + which the Boolean expression is true are returned. The usual + Boolean operators (AND, + OR, and NOT) are allowed in + the qualification. For example, the following + retrieves the weather of San Francisco on rainy days: + + +SELECT * FROM weather + WHERE city = 'San Francisco' AND prcp > 0.0; + + Result: + + city | temp_lo | temp_hi | prcp | date +---------------+---------+---------+------+------------ + San Francisco | 46 | 50 | 0.25 | 1994-11-27 +(1 row) + + + + + ORDER BY + + You can request that the results of a query + be returned in sorted order: + + +SELECT * FROM weather + ORDER BY city; + + + + city | temp_lo | temp_hi | prcp | date +---------------+---------+---------+------+------------ + Hayward | 37 | 54 | | 1994-11-29 + San Francisco | 43 | 57 | 0 | 1994-11-29 + San Francisco | 46 | 50 | 0.25 | 1994-11-27 + + + In this example, the sort order isn't fully specified, and so you + might get the San Francisco rows in either order. But you'd always + get the results shown above if you do: + + +SELECT * FROM weather + ORDER BY city, temp_lo; + + + + + DISTINCT + duplicate + + You can request that duplicate rows be removed from the result of + a query: + + +SELECT DISTINCT city + FROM weather; + + + + city +--------------- + Hayward + San Francisco +(2 rows) + + + Here again, the result row ordering might vary. + You can ensure consistent results by using DISTINCT and + ORDER BY together: + + + In some database systems, including older versions of + PostgreSQL, the implementation of + DISTINCT automatically orders the rows and + so ORDER BY is unnecessary. But this is not + required by the SQL standard, and current + PostgreSQL does not guarantee that + DISTINCT causes the rows to be ordered. + + + + +SELECT DISTINCT city + FROM weather + ORDER BY city; + + + + + + + Joins Between Tables + + + join + + + + Thus far, our queries have only accessed one table at a time. + Queries can access multiple tables at once, or access the same + table in such a way that multiple rows of the table are being + processed at the same time. Queries that access multiple tables + (or multiple instances of the same table) at one time are called + join queries. They combine rows from one table + with rows from a second table, with an expression specifying which rows + are to be paired. For example, to return all the weather records together + with the location of the associated city, the database needs to compare + the city + column of each row of the weather table with the + name column of all rows in the cities + table, and select the pairs of rows where these values match. + + This is only a conceptual model. The join is usually performed + in a more efficient manner than actually comparing each possible + pair of rows, but this is invisible to the user. + + + This would be accomplished by the following query: + + +SELECT * FROM weather JOIN cities ON city = name; + + + + city | temp_lo | temp_hi | prcp | date | name | location +---------------+---------+---------+------+------------+---------------+----------- + San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53) + San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53) +(2 rows) + + + + + + Observe two things about the result set: + + + + There is no result row for the city of Hayward. This is + because there is no matching entry in the + cities table for Hayward, so the join + ignores the unmatched rows in the weather table. We will see + shortly how this can be fixed. + + + + + + There are two columns containing the city name. This is + correct because the lists of columns from the + weather and + cities tables are concatenated. In + practice this is undesirable, though, so you will probably want + to list the output columns explicitly rather than using + *: + +SELECT city, temp_lo, temp_hi, prcp, date, location + FROM weather JOIN cities ON city = name; + + + + + + + + Since the columns all had different names, the parser + automatically found which table they belong to. If there + were duplicate column names in the two tables you'd need to + qualify the column names to show which one you + meant, as in: + + +SELECT weather.city, weather.temp_lo, weather.temp_hi, + weather.prcp, weather.date, cities.location + FROM weather JOIN cities ON weather.city = cities.name; + + + It is widely considered good style to qualify all column names + in a join query, so that the query won't fail if a duplicate + column name is later added to one of the tables. + + + + Join queries of the kind seen thus far can also be written in this + form: + + +SELECT * + FROM weather, cities + WHERE city = name; + + + This syntax pre-dates the JOIN/ON + syntax, which was introduced in SQL-92. The tables are simply listed in + the FROM clause, and the comparison expression is added + to the WHERE clause. The results from this older + implicit syntax and the newer explicit + JOIN/ON syntax are identical. But + for a reader of the query, the explicit syntax makes its meaning easier to + understand: The join condition is introduced by its own key word whereas + previously the condition was mixed into the WHERE + clause together with other conditions. + + + joinouter + + + Now we will figure out how we can get the Hayward records back in. + What we want the query to do is to scan the + weather table and for each row to find the + matching cities row(s). If no matching row is + found we want some empty values to be substituted + for the cities table's columns. This kind + of query is called an outer join. (The + joins we have seen so far are inner joins.) + The command looks like this: + + +SELECT * + FROM weather LEFT OUTER JOIN cities ON weather.city = cities.name; + + + + city | temp_lo | temp_hi | prcp | date | name | location +---------------+---------+---------+------+------------+---------------+----------- + Hayward | 37 | 54 | | 1994-11-29 | | + San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53) + San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53) +(3 rows) + + + This query is called a left outer + join because the table mentioned on the left of the + join operator will have each of its rows in the output at least + once, whereas the table on the right will only have those rows + output that match some row of the left table. When outputting a + left-table row for which there is no right-table match, empty (null) + values are substituted for the right-table columns. + + + + Exercise: + + + There are also right outer joins and full outer joins. Try to + find out what those do. + + + + joinself + aliasfor table name in query + + We can also join a table against itself. This is called a + self join. As an example, suppose we wish + to find all the weather records that are in the temperature range + of other weather records. So we need to compare the + temp_lo and temp_hi columns of + each weather row to the + temp_lo and + temp_hi columns of all other + weather rows. We can do this with the + following query: + + +SELECT w1.city, w1.temp_lo AS low, w1.temp_hi AS high, + w2.city, w2.temp_lo AS low, w2.temp_hi AS high + FROM weather w1 JOIN weather w2 + ON w1.temp_lo < w2.temp_lo AND w1.temp_hi > w2.temp_hi; + + + + city | low | high | city | low | high +---------------+-----+------+---------------+-----+------ + San Francisco | 43 | 57 | San Francisco | 46 | 50 + Hayward | 37 | 54 | San Francisco | 46 | 50 +(2 rows) + + + Here we have relabeled the weather table as w1 and + w2 to be able to distinguish the left and right side + of the join. You can also use these kinds of aliases in other + queries to save some typing, e.g.: + +SELECT * + FROM weather w JOIN cities c ON w.city = c.name; + + You will encounter this style of abbreviating quite frequently. + + + + + + Aggregate Functions + + + aggregate function + + + + Like most other relational database products, + PostgreSQL supports + aggregate functions. + An aggregate function computes a single result from multiple input rows. + For example, there are aggregates to compute the + count, sum, + avg (average), max (maximum) and + min (minimum) over a set of rows. + + + + As an example, we can find the highest low-temperature reading anywhere + with: + + +SELECT max(temp_lo) FROM weather; + + + + max +----- + 46 +(1 row) + + + + + subquery + + If we wanted to know what city (or cities) that reading occurred in, + we might try: + + +SELECT city FROM weather WHERE temp_lo = max(temp_lo); WRONG + + + but this will not work since the aggregate + max cannot be used in the + WHERE clause. (This restriction exists because + the WHERE clause determines which rows will be + included in the aggregate calculation; so obviously it has to be evaluated + before aggregate functions are computed.) + However, as is often the case + the query can be restated to accomplish the desired result, here + by using a subquery: + + +SELECT city FROM weather + WHERE temp_lo = (SELECT max(temp_lo) FROM weather); + + + + city +--------------- + San Francisco +(1 row) + + + This is OK because the subquery is an independent computation + that computes its own aggregate separately from what is happening + in the outer query. + + + + GROUP BY + HAVING + + Aggregates are also very useful in combination with GROUP + BY clauses. For example, we can get the maximum low + temperature observed in each city with: + + +SELECT city, max(temp_lo) + FROM weather + GROUP BY city; + + + + city | max +---------------+----- + Hayward | 37 + San Francisco | 46 +(2 rows) + + + which gives us one output row per city. Each aggregate result is + computed over the table rows matching that city. + We can filter these grouped + rows using HAVING: + + +SELECT city, max(temp_lo) + FROM weather + GROUP BY city + HAVING max(temp_lo) < 40; + + + + city | max +---------+----- + Hayward | 37 +(1 row) + + + which gives us the same results for only the cities that have all + temp_lo values below 40. Finally, if we only care about + cities whose + names begin with S, we might do: + + +SELECT city, max(temp_lo) + FROM weather + WHERE city LIKE 'S%' -- + GROUP BY city + HAVING max(temp_lo) < 40; + + + + + The LIKE operator does pattern matching and + is explained in . + + + + + + + It is important to understand the interaction between aggregates and + SQL's WHERE and HAVING clauses. + The fundamental difference between WHERE and + HAVING is this: WHERE selects + input rows before groups and aggregates are computed (thus, it controls + which rows go into the aggregate computation), whereas + HAVING selects group rows after groups and + aggregates are computed. Thus, the + WHERE clause must not contain aggregate functions; + it makes no sense to try to use an aggregate to determine which rows + will be inputs to the aggregates. On the other hand, the + HAVING clause always contains aggregate functions. + (Strictly speaking, you are allowed to write a HAVING + clause that doesn't use aggregates, but it's seldom useful. The same + condition could be used more efficiently at the WHERE + stage.) + + + + In the previous example, we can apply the city name restriction in + WHERE, since it needs no aggregate. This is + more efficient than adding the restriction to HAVING, + because we avoid doing the grouping and aggregate calculations + for all rows that fail the WHERE check. + + + + + + Updates + + + UPDATE + + + + You can update existing rows using the + UPDATE command. + Suppose you discover the temperature readings are + all off by 2 degrees after November 28. You can correct the + data as follows: + + +UPDATE weather + SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2 + WHERE date > '1994-11-28'; + + + + + Look at the new state of the data: + +SELECT * FROM weather; + + city | temp_lo | temp_hi | prcp | date +---------------+---------+---------+------+------------ + San Francisco | 46 | 50 | 0.25 | 1994-11-27 + San Francisco | 41 | 55 | 0 | 1994-11-29 + Hayward | 35 | 52 | | 1994-11-29 +(3 rows) + + + + + + Deletions + + + DELETE + + + + Rows can be removed from a table using the DELETE + command. + Suppose you are no longer interested in the weather of Hayward. + Then you can do the following to delete those rows from the table: + +DELETE FROM weather WHERE city = 'Hayward'; + + + All weather records belonging to Hayward are removed. + + +SELECT * FROM weather; + + + + city | temp_lo | temp_hi | prcp | date +---------------+---------+---------+------+------------ + San Francisco | 46 | 50 | 0.25 | 1994-11-27 + San Francisco | 41 | 55 | 0 | 1994-11-29 +(2 rows) + + + + + One should be wary of statements of the form + +DELETE FROM tablename; + + + Without a qualification, DELETE will + remove all rows from the given table, leaving it + empty. The system will not request confirmation before + doing this! + + + + diff --git a/doc/src/sgml/rangetypes.sgml b/doc/src/sgml/rangetypes.sgml new file mode 100644 index 000000000000..92ea0e83dab7 --- /dev/null +++ b/doc/src/sgml/rangetypes.sgml @@ -0,0 +1,592 @@ + + + + Range Types + + + range type + + + + multirange type + + + + Range types are data types representing a range of values of some + element type (called the range's subtype). + For instance, ranges + of timestamp might be used to represent the ranges of + time that a meeting room is reserved. In this case the data type + is tsrange (short for timestamp range), + and timestamp is the subtype. The subtype must have + a total order so that it is well-defined whether element values are + within, before, or after a range of values. + + + + Range types are useful because they represent many element values in a + single range value, and because concepts such as overlapping ranges can + be expressed clearly. The use of time and date ranges for scheduling + purposes is the clearest example; but price ranges, measurement + ranges from an instrument, and so forth can also be useful. + + + + Every range type has a corresponding multirange type. A multirange is + an ordered list of non-contiguous, non-empty, non-null ranges. Most + range operators also work on multiranges, and they have a few functions + of their own. + + + + Built-in Range and Multirange Types + + + PostgreSQL comes with the following built-in range types: + + + + int4range — Range of integer, + int4multirange — corresponding Multirange + + + + + int8range — Range of bigint, + int8multirange — corresponding Multirange + + + + + numrange — Range of numeric, + nummultirange — corresponding Multirange + + + + + tsrange — Range of timestamp without time zone, + tsmultirange — corresponding Multirange + + + + + tstzrange — Range of timestamp with time zone, + tstzmultirange — corresponding Multirange + + + + + daterange — Range of date, + datemultirange — corresponding Multirange + + + + In addition, you can define your own range types; + see for more information. + + + + + Examples + + + +CREATE TABLE reservation (room int, during tsrange); +INSERT INTO reservation VALUES + (1108, '[2010-01-01 14:30, 2010-01-01 15:30)'); + +-- Containment +SELECT int4range(10, 20) @> 3; + +-- Overlaps +SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0); + +-- Extract the upper bound +SELECT upper(int8range(15, 25)); + +-- Compute the intersection +SELECT int4range(10, 20) * int4range(15, 25); + +-- Is the range empty? +SELECT isempty(numrange(1, 5)); + + + See + and for complete lists of + operators and functions on range types. + + + + + Inclusive and Exclusive Bounds + + + Every non-empty range has two bounds, the lower bound and the upper + bound. All points between these values are included in the range. An + inclusive bound means that the boundary point itself is included in + the range as well, while an exclusive bound means that the boundary + point is not included in the range. + + + + In the text form of a range, an inclusive lower bound is represented by + [ while an exclusive lower bound is + represented by (. Likewise, an inclusive upper bound is represented by + ], while an exclusive upper bound is + represented by ). + (See for more details.) + + + + The functions lower_inc + and upper_inc test the inclusivity of the lower + and upper bounds of a range value, respectively. + + + + + Infinite (Unbounded) Ranges + + + The lower bound of a range can be omitted, meaning that all + values less than the upper bound are included in the range, e.g., + (,3]. Likewise, if the upper bound of the range + is omitted, then all values greater than the lower bound are included + in the range. If both lower and upper bounds are omitted, all values + of the element type are considered to be in the range. Specifying a + missing bound as inclusive is automatically converted to exclusive, + e.g., [,] is converted to (,). + You can think of these missing values as +/-infinity, but they are + special range type values and are considered to be beyond any range + element type's +/-infinity values. + + + + Element types that have the notion of infinity can + use them as explicit bound values. For example, with timestamp + ranges, [today,infinity) excludes the special + timestamp value infinity, + while [today,infinity] include it, as does + [today,) and [today,]. + + + + The functions lower_inf + and upper_inf test for infinite lower + and upper bounds of a range, respectively. + + + + + Range Input/Output + + + The input for a range value must follow one of the following patterns: + +(lower-bound,upper-bound) +(lower-bound,upper-bound] +[lower-bound,upper-bound) +[lower-bound,upper-bound] +empty + + The parentheses or brackets indicate whether the lower and upper bounds + are exclusive or inclusive, as described previously. + Notice that the final pattern is empty, which + represents an empty range (a range that contains no points). + + + + The lower-bound may be either a string + that is valid input for the subtype, or empty to indicate no + lower bound. Likewise, upper-bound may be + either a string that is valid input for the subtype, or empty to + indicate no upper bound. + + + + Each bound value can be quoted using " (double quote) + characters. This is necessary if the bound value contains parentheses, + brackets, commas, double quotes, or backslashes, since these characters + would otherwise be taken as part of the range syntax. To put a double + quote or backslash in a quoted bound value, precede it with a + backslash. (Also, a pair of double quotes within a double-quoted bound + value is taken to represent a double quote character, analogously to the + rules for single quotes in SQL literal strings.) Alternatively, you can + avoid quoting and use backslash-escaping to protect all data characters + that would otherwise be taken as range syntax. Also, to write a bound + value that is an empty string, write "", since writing + nothing means an infinite bound. + + + + Whitespace is allowed before and after the range value, but any whitespace + between the parentheses or brackets is taken as part of the lower or upper + bound value. (Depending on the element type, it might or might not be + significant.) + + + + + These rules are very similar to those for writing field values in + composite-type literals. See for + additional commentary. + + + + + Examples: + +-- includes 3, does not include 7, and does include all points in between +SELECT '[3,7)'::int4range; + +-- does not include either 3 or 7, but includes all points in between +SELECT '(3,7)'::int4range; + +-- includes only the single point 4 +SELECT '[4,4]'::int4range; + +-- includes no points (and will be normalized to 'empty') +SELECT '[4,4)'::int4range; + + + + + The input for a multirange is curly brackets ({ and + }) containing zero or more valid ranges, + separated by commas. Whitespace is permitted around the brackets and + commas. This is intended to be reminiscent of array syntax, although + multiranges are much simpler: they have just one dimension and there is + no need to quote their contents. (The bounds of their ranges may be + quoted as above however.) + + + + Examples: + +SELECT '{}'::int4multirange; +SELECT '{[3,7)}'::int4multirange; +SELECT '{[3,7), [8,9)}'::int4multirange; + + + + + + + Constructing Ranges and Multiranges + + + Each range type has a constructor function with the same name as the range + type. Using the constructor function is frequently more convenient than + writing a range literal constant, since it avoids the need for extra + quoting of the bound values. The constructor function + accepts two or three arguments. The two-argument form constructs a range + in standard form (lower bound inclusive, upper bound exclusive), while + the three-argument form constructs a range with bounds of the form + specified by the third argument. + The third argument must be one of the strings + (), + (], + [), or + []. + For example: + + +-- The full form is: lower bound, upper bound, and text argument indicating +-- inclusivity/exclusivity of bounds. +SELECT numrange(1.0, 14.0, '(]'); + +-- If the third argument is omitted, '[)' is assumed. +SELECT numrange(1.0, 14.0); + +-- Although '(]' is specified here, on display the value will be converted to +-- canonical form, since int8range is a discrete range type (see below). +SELECT int8range(1, 14, '(]'); + +-- Using NULL for either bound causes the range to be unbounded on that side. +SELECT numrange(NULL, 2.2); + + + + + Each range type also has a multirange constructor with the same name as the + multirange type. The constructor function takes zero or more arguments + which are all ranges of the appropriate type. + For example: + + +SELECT nummultirange(); +SELECT nummultirange(numrange(1.0, 14.0)); +SELECT nummultirange(numrange(1.0, 14.0), numrange(20.0, 25.0)); + + + + + + Discrete Range Types + + + A discrete range is one whose element type has a well-defined + step, such as integer or date. + In these types two elements can be said to be adjacent, when there are + no valid values between them. This contrasts with continuous ranges, + where it's always (or almost always) possible to identify other element + values between two given values. For example, a range over the + numeric type is continuous, as is a range over timestamp. + (Even though timestamp has limited precision, and so could + theoretically be treated as discrete, it's better to consider it continuous + since the step size is normally not of interest.) + + + + Another way to think about a discrete range type is that there is a clear + idea of a next or previous value for each element value. + Knowing that, it is possible to convert between inclusive and exclusive + representations of a range's bounds, by choosing the next or previous + element value instead of the one originally given. + For example, in an integer range type [4,8] and + (3,9) denote the same set of values; but this would not be so + for a range over numeric. + + + + A discrete range type should have a canonicalization + function that is aware of the desired step size for the element type. + The canonicalization function is charged with converting equivalent values + of the range type to have identical representations, in particular + consistently inclusive or exclusive bounds. + If a canonicalization function is not specified, then ranges with different + formatting will always be treated as unequal, even though they might + represent the same set of values in reality. + + + + The built-in range types int4range, int8range, + and daterange all use a canonical form that includes + the lower bound and excludes the upper bound; that is, + [). User-defined range types can use other conventions, + however. + + + + + Defining New Range Types + + + Users can define their own range types. The most common reason to do + this is to use ranges over subtypes not provided among the built-in + range types. + For example, to define a new range type of subtype float8: + + +CREATE TYPE floatrange AS RANGE ( + subtype = float8, + subtype_diff = float8mi +); + +SELECT '[1.234, 5.678]'::floatrange; + + + Because float8 has no meaningful + step, we do not define a canonicalization + function in this example. + + + + When you define your own range you automatically get a corresponding + multirange type. + + + + Defining your own range type also allows you to specify a different + subtype B-tree operator class or collation to use, so as to change the sort + ordering that determines which values fall into a given range. + + + + If the subtype is considered to have discrete rather than continuous + values, the CREATE TYPE command should specify a + canonical function. + The canonicalization function takes an input range value, and must return + an equivalent range value that may have different bounds and formatting. + The canonical output for two ranges that represent the same set of values, + for example the integer ranges [1, 7] and [1, + 8), must be identical. It doesn't matter which representation + you choose to be the canonical one, so long as two equivalent values with + different formattings are always mapped to the same value with the same + formatting. In addition to adjusting the inclusive/exclusive bounds + format, a canonicalization function might round off boundary values, in + case the desired step size is larger than what the subtype is capable of + storing. For instance, a range type over timestamp could be + defined to have a step size of an hour, in which case the canonicalization + function would need to round off bounds that weren't a multiple of an hour, + or perhaps throw an error instead. + + + + In addition, any range type that is meant to be used with GiST or SP-GiST + indexes should define a subtype difference, or subtype_diff, + function. (The index will still work without subtype_diff, + but it is likely to be considerably less efficient than if a difference + function is provided.) The subtype difference function takes two input + values of the subtype, and returns their difference + (i.e., X minus Y) represented as + a float8 value. In our example above, the + function float8mi that underlies the regular float8 + minus operator can be used; but for any other subtype, some type + conversion would be necessary. Some creative thought about how to + represent differences as numbers might be needed, too. To the greatest + extent possible, the subtype_diff function should agree with + the sort ordering implied by the selected operator class and collation; + that is, its result should be positive whenever its first argument is + greater than its second according to the sort ordering. + + + + A less-oversimplified example of a subtype_diff function is: + + + +CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS +'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE; + +CREATE TYPE timerange AS RANGE ( + subtype = time, + subtype_diff = time_subtype_diff +); + +SELECT '[11:10, 23:00]'::timerange; + + + + See for more information about creating + range types. + + + + + Indexing + + + range type + indexes on + + + + GiST and SP-GiST indexes can be created for table columns of range types. + GiST indexes can be also created for table columns of multirange types. + For instance, to create a GiST index: + +CREATE INDEX reservation_idx ON reservation USING GIST (during); + + A GiST or SP-GiST index on ranges can accelerate queries involving these + range operators: + =, + &&, + <@, + @>, + <<, + >>, + -|-, + &<, and + &>. + A GiST index on multiranges can accelerate queries involving the same + set of multirange operators. + A GiST index on ranges and GiST index on multiranges can also accelerate + queries involving these cross-type range to multirange and multirange to + range operators correspondingly: + &&, + <@, + @>, + <<, + >>, + -|-, + &<, and + &>. + See for more information. + + + + In addition, B-tree and hash indexes can be created for table columns of + range types. For these index types, basically the only useful range + operation is equality. There is a B-tree sort ordering defined for range + values, with corresponding < and > operators, + but the ordering is rather arbitrary and not usually useful in the real + world. Range types' B-tree and hash support is primarily meant to + allow sorting and hashing internally in queries, rather than creation of + actual indexes. + + + + + Constraints on Ranges + + + range type + exclude + + + + While UNIQUE is a natural constraint for scalar + values, it is usually unsuitable for range types. Instead, an + exclusion constraint is often more appropriate + (see CREATE TABLE + ... CONSTRAINT ... EXCLUDE). Exclusion constraints allow the + specification of constraints such as non-overlapping on a + range type. For example: + + +CREATE TABLE reservation ( + during tsrange, + EXCLUDE USING GIST (during WITH &&) +); + + + That constraint will prevent any overlapping values from existing + in the table at the same time: + + +INSERT INTO reservation VALUES + ('[2010-01-01 11:30, 2010-01-01 15:00)'); +INSERT 0 1 + +INSERT INTO reservation VALUES + ('[2010-01-01 14:45, 2010-01-01 15:45)'); +ERROR: conflicting key value violates exclusion constraint "reservation_during_excl" +DETAIL: Key (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00")) conflicts +with existing key (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")). + + + + + You can use the btree_gist + extension to define exclusion constraints on plain scalar data types, which + can then be combined with range exclusions for maximum flexibility. For + example, after btree_gist is installed, the following + constraint will reject overlapping ranges only if the meeting room numbers + are equal: + + +CREATE EXTENSION btree_gist; +CREATE TABLE room_reservation ( + room text, + during tsrange, + EXCLUDE USING GIST (room WITH =, during WITH &&) +); + +INSERT INTO room_reservation VALUES + ('123A', '[2010-01-01 14:00, 2010-01-01 15:00)'); +INSERT 0 1 + +INSERT INTO room_reservation VALUES + ('123A', '[2010-01-01 14:30, 2010-01-01 15:30)'); +ERROR: conflicting key value violates exclusion constraint "room_reservation_room_during_excl" +DETAIL: Key (room, during)=(123A, ["2010-01-01 14:30:00","2010-01-01 15:30:00")) conflicts +with existing key (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")). + +INSERT INTO room_reservation VALUES + ('123B', '[2010-01-01 14:30, 2010-01-01 15:30)'); +INSERT 0 1 + + + + diff --git a/doc/src/sgml/ref/abort.sgml b/doc/src/sgml/ref/abort.sgml index 037291336516..16b5602487d7 100644 --- a/doc/src/sgml/ref/abort.sgml +++ b/doc/src/sgml/ref/abort.sgml @@ -33,7 +33,7 @@ ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] all the updates made by the transaction to be discarded. This command is identical in behavior to the standard SQL command - , + ROLLBACK, and is present only for historical reasons.
@@ -57,8 +57,8 @@ ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] If AND CHAIN is specified, a new transaction is - immediately started with the same transaction characteristics (see ) as the just finished one. Otherwise, + immediately started with the same transaction characteristics (see SET TRANSACTION) as the just finished one. Otherwise, no new transaction is started. @@ -70,7 +70,7 @@ ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] Notes - Use to + Use COMMIT to successfully terminate a transaction. diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml index cb5e6fc42db5..b5519dd79b06 100644 --- a/doc/src/sgml/ref/allfiles.sgml +++ b/doc/src/sgml/ref/allfiles.sgml @@ -200,6 +200,7 @@ Complete list of usable sgml source files in this directory. + @@ -219,7 +220,7 @@ Complete list of usable sgml source files in this directory. - + diff --git a/doc/src/sgml/ref/alter_aggregate.sgml b/doc/src/sgml/ref/alter_aggregate.sgml index 2ad3e0440bf8..aee10a5ca2e0 100644 --- a/doc/src/sgml/ref/alter_aggregate.sgml +++ b/doc/src/sgml/ref/alter_aggregate.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation ALTER AGGREGATE name ( aggregate_signature ) RENAME TO new_name ALTER AGGREGATE name ( aggregate_signature ) - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER AGGREGATE name ( aggregate_signature ) SET SCHEMA new_schema where aggregate_signature is: @@ -142,7 +142,7 @@ ALTER AGGREGATE name ( aggregate_signatu The recommended syntax for referencing an ordered-set aggregate is to write ORDER BY between the direct and aggregated argument specifications, in the same style as in - . However, it will also work to + CREATE AGGREGATE. However, it will also work to omit ORDER BY and just run the direct and aggregated argument specifications into a single list. In this abbreviated form, if VARIADIC "any" was used in both the direct and diff --git a/doc/src/sgml/ref/alter_collation.sgml b/doc/src/sgml/ref/alter_collation.sgml index bee6f0dd3ca1..9bcb91e8ff9b 100644 --- a/doc/src/sgml/ref/alter_collation.sgml +++ b/doc/src/sgml/ref/alter_collation.sgml @@ -24,7 +24,7 @@ PostgreSQL documentation ALTER COLLATION name REFRESH VERSION ALTER COLLATION name RENAME TO new_name -ALTER COLLATION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER COLLATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER COLLATION name SET SCHEMA new_schema @@ -129,12 +129,24 @@ HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg correctly. - When using collations provided by libc and - PostgreSQL was built with the GNU C library, the - C library's version is used as a collation version. Since collation - definitions typically change only with GNU C library releases, this provides - some defense against corruption, but it is not completely reliable. + When using collations provided by libc, version + information is recorded on systems using the GNU C library (most Linux + systems), FreeBSD and Windows. + + + When using the GNU C library for collations, the C library's version + is used as a proxy for the collation version. Many Linux distributions + change collation definitions only when upgrading the C library, but this + approach is imperfect as maintainers are free to back-port newer + collation definitions to older C library releases. + + + When using Windows for collations, version information is only available + for collations defined with BCP 47 language tags such as + en-US. + + Currently, there is no version tracking for the database default collation. diff --git a/doc/src/sgml/ref/alter_conversion.sgml b/doc/src/sgml/ref/alter_conversion.sgml index c42bd8b3e404..a128f20f3e8a 100644 --- a/doc/src/sgml/ref/alter_conversion.sgml +++ b/doc/src/sgml/ref/alter_conversion.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation ALTER CONVERSION name RENAME TO new_name -ALTER CONVERSION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER CONVERSION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER CONVERSION name SET SCHEMA new_schema diff --git a/doc/src/sgml/ref/alter_database.sgml b/doc/src/sgml/ref/alter_database.sgml index 7db878cf532c..81e37536a3f6 100644 --- a/doc/src/sgml/ref/alter_database.sgml +++ b/doc/src/sgml/ref/alter_database.sgml @@ -31,7 +31,7 @@ ALTER DATABASE name [ [ WITH ] name RENAME TO new_name -ALTER DATABASE name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER DATABASE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER DATABASE name SET TABLESPACE new_tablespace diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml index 8201cbb65fcd..2db53725139c 100644 --- a/doc/src/sgml/ref/alter_domain.sgml +++ b/doc/src/sgml/ref/alter_domain.sgml @@ -36,7 +36,7 @@ ALTER DOMAIN name ALTER DOMAIN name VALIDATE CONSTRAINT constraint_name ALTER DOMAIN name - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER DOMAIN name RENAME TO new_name ALTER DOMAIN name @@ -80,7 +80,7 @@ ALTER DOMAIN name This form adds a new constraint to a domain using the same syntax as - . + CREATE DOMAIN. When a new constraint is added to a domain, all columns using that domain will be checked against the newly added constraint. These checks can be suppressed by adding the new constraint using the diff --git a/doc/src/sgml/ref/alter_event_trigger.sgml b/doc/src/sgml/ref/alter_event_trigger.sgml index 61919f7845db..ef5253bf37eb 100644 --- a/doc/src/sgml/ref/alter_event_trigger.sgml +++ b/doc/src/sgml/ref/alter_event_trigger.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation ALTER EVENT TRIGGER name DISABLE ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ] -ALTER EVENT TRIGGER name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER EVENT TRIGGER name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER EVENT TRIGGER name RENAME TO new_name diff --git a/doc/src/sgml/ref/alter_extension.sgml b/doc/src/sgml/ref/alter_extension.sgml index a2d405d6cdfb..c819c7bb4e3c 100644 --- a/doc/src/sgml/ref/alter_extension.sgml +++ b/doc/src/sgml/ref/alter_extension.sgml @@ -251,7 +251,7 @@ ALTER EXTENSION name DROP The data type(s) of the operator's arguments (optionally schema-qualified). Write NONE for the missing argument - of a prefix or postfix operator. + of a prefix operator. diff --git a/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml index 14f3d616e71c..54f34c2c0151 100644 --- a/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml +++ b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml @@ -25,7 +25,7 @@ ALTER FOREIGN DATA WRAPPER name [ HANDLER handler_function | NO HANDLER ] [ VALIDATOR validator_function | NO VALIDATOR ] [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) ] -ALTER FOREIGN DATA WRAPPER name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER FOREIGN DATA WRAPPER name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER FOREIGN DATA WRAPPER name RENAME TO new_name diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml index 0f11897c9977..7ca03f3ac9f1 100644 --- a/doc/src/sgml/ref/alter_foreign_table.sgml +++ b/doc/src/sgml/ref/alter_foreign_table.sgml @@ -53,7 +53,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] nameparent_table NO INHERIT parent_table - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) @@ -71,7 +71,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name This form adds a new column to the foreign table, using the same syntax as - . + CREATE FOREIGN TABLE. Unlike the case when adding a column to a regular table, nothing happens to the underlying storage: this action simply declares that some new column is now accessible through the foreign table. @@ -133,8 +133,8 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name This form sets the per-column statistics-gathering target for subsequent - operations. - See the similar form of + ANALYZE operations. + See the similar form of ALTER TABLE for more details. @@ -146,7 +146,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name This form sets or resets per-attribute options. - See the similar form of + See the similar form of ALTER TABLE for more details. @@ -159,7 +159,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name This form sets the storage mode for a column. - See the similar form of + See the similar form of ALTER TABLE for more details. Note that the storage mode has no effect unless the table's foreign-data wrapper chooses to pay attention to it. @@ -172,7 +172,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name This form adds a new constraint to a foreign table, using the same - syntax as . + syntax as CREATE FOREIGN TABLE. Currently only CHECK constraints are supported. @@ -181,7 +181,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name.) + in CREATE FOREIGN TABLE.) If the constraint is marked NOT VALID, then it isn't assumed to hold, but is only recorded for possible future use. @@ -216,7 +216,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name These forms configure the firing of trigger(s) belonging to the foreign - table. See the similar form of for more + table. See the similar form of ALTER TABLE for more details. @@ -239,7 +239,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name This form adds the target foreign table as a new child of the specified parent table. - See the similar form of + See the similar form of ALTER TABLE for more details. @@ -503,7 +503,7 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name - Refer to for a further description of valid + Refer to CREATE FOREIGN TABLE for a further description of valid parameters. diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml index c8ae245f11a4..3c99b450e0a3 100644 --- a/doc/src/sgml/ref/alter_function.sgml +++ b/doc/src/sgml/ref/alter_function.sgml @@ -26,7 +26,7 @@ ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] RENAME TO new_name ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] SET SCHEMA new_schema ALTER FUNCTION name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] @@ -35,7 +35,8 @@ ALTER FUNCTION name [ ( [ [ action is one of: CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT - IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF + IMMUTABLE | STABLE | VOLATILE + [ NOT ] LEAKPROOF [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER PARALLEL { UNSAFE | RESTRICTED | SAFE } EXECUTE ON { ANY | MASTER | ALL SEGMENTS } diff --git a/doc/src/sgml/ref/alter_group.sgml b/doc/src/sgml/ref/alter_group.sgml index 39cc2b88cfa2..fa4a8df91249 100644 --- a/doc/src/sgml/ref/alter_group.sgml +++ b/doc/src/sgml/ref/alter_group.sgml @@ -27,6 +27,7 @@ ALTER GROUP role_specification DROP where role_specification can be: role_name + | CURRENT_ROLE | CURRENT_USER | SESSION_USER @@ -50,14 +51,14 @@ ALTER GROUP group_name RENAME TO group for this purpose.) These variants are effectively equivalent to granting or revoking membership in the role named as the group; so the preferred way to do this is to use - or - . + GRANT or + REVOKE. The third variant changes the name of the group. This is exactly equivalent to renaming the role with - . + ALTER ROLE. diff --git a/doc/src/sgml/ref/alter_index.sgml b/doc/src/sgml/ref/alter_index.sgml index a5e3b06ee493..e26efec064be 100644 --- a/doc/src/sgml/ref/alter_index.sgml +++ b/doc/src/sgml/ref/alter_index.sgml @@ -24,7 +24,7 @@ PostgreSQL documentation ALTER INDEX [ IF EXISTS ] name RENAME TO new_name ALTER INDEX [ IF EXISTS ] name SET TABLESPACE tablespace_name ALTER INDEX name ATTACH PARTITION index_name -ALTER INDEX name DEPENDS ON EXTENSION extension_name +ALTER INDEX name [ NO ] DEPENDS ON EXTENSION extension_name ALTER INDEX [ IF EXISTS ] name SET ( storage_parameter [= value] [, ... ] ) ALTER INDEX [ IF EXISTS ] name RESET ( storage_parameter [, ... ] ) ALTER INDEX [ IF EXISTS ] name ALTER [ COLUMN ] column_number @@ -81,7 +81,7 @@ ALTER INDEX ALL IN TABLESPACE name this command, use ALTER DATABASE or explicit ALTER INDEX invocations instead if desired. See also - . + CREATE TABLESPACE. @@ -118,11 +118,11 @@ ALTER INDEX ALL IN TABLESPACE name This form changes one or more index-method-specific storage parameters for the index. See - + CREATE INDEX for details on the available parameters. Note that the index contents will not be modified immediately by this command; depending on the parameter you might need to rebuild the index with - + REINDEX to get the desired effects. @@ -144,7 +144,7 @@ ALTER INDEX ALL IN TABLESPACE name This form sets the per-column statistics-gathering target for - subsequent operations, though can + subsequent ANALYZE operations, though can be used only on index columns that are defined as an expression. Since expressions lack a unique name, we refer to them using the ordinal number of the index column. @@ -252,7 +252,7 @@ ALTER INDEX ALL IN TABLESPACE name These operations are also possible using - . + ALTER TABLE. ALTER INDEX is in fact just an alias for the forms of ALTER TABLE that apply to indexes. diff --git a/doc/src/sgml/ref/alter_language.sgml b/doc/src/sgml/ref/alter_language.sgml index eac63dec1322..0b61c18aee36 100644 --- a/doc/src/sgml/ref/alter_language.sgml +++ b/doc/src/sgml/ref/alter_language.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO new_name -ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } diff --git a/doc/src/sgml/ref/alter_large_object.sgml b/doc/src/sgml/ref/alter_large_object.sgml index 356f8a8eabf4..17ea1491ba37 100644 --- a/doc/src/sgml/ref/alter_large_object.sgml +++ b/doc/src/sgml/ref/alter_large_object.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -ALTER LARGE OBJECT large_object_oid OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER LARGE OBJECT large_object_oid OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } diff --git a/doc/src/sgml/ref/alter_materialized_view.sgml b/doc/src/sgml/ref/alter_materialized_view.sgml index 7321183dd0db..7011a0e7da04 100644 --- a/doc/src/sgml/ref/alter_materialized_view.sgml +++ b/doc/src/sgml/ref/alter_materialized_view.sgml @@ -24,7 +24,7 @@ PostgreSQL documentation ALTER MATERIALIZED VIEW [ IF EXISTS ] name action [, ... ] ALTER MATERIALIZED VIEW name - DEPENDS ON EXTENSION extension_name + [ NO ] DEPENDS ON EXTENSION extension_name ALTER MATERIALIZED VIEW [ IF EXISTS ] name RENAME [ COLUMN ] column_name TO new_column_name ALTER MATERIALIZED VIEW [ IF EXISTS ] name @@ -40,11 +40,12 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE namecolumn_name SET ( attribute_option = value [, ... ] ) ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN } + ALTER [ COLUMN ] column_name SET COMPRESSION compression_method CLUSTER ON index_name SET WITHOUT CLUSTER SET ( storage_parameter [= value] [, ... ] ) RESET ( storage_parameter [, ... ] ) - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } @@ -72,7 +73,8 @@ ALTER MATERIALIZED VIEW ALL IN TABLESPACE nameALTER MATERIALIZED VIEW
are a subset of those available for ALTER TABLE, and have the same meaning when used for - materialized views. See the descriptions for + materialized views. See the descriptions for + ALTER TABLE for details. diff --git a/doc/src/sgml/ref/alter_opclass.sgml b/doc/src/sgml/ref/alter_opclass.sgml index 59a64caa4fad..b1db459b113c 100644 --- a/doc/src/sgml/ref/alter_opclass.sgml +++ b/doc/src/sgml/ref/alter_opclass.sgml @@ -25,7 +25,7 @@ ALTER OPERATOR CLASS name USING index_method - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER OPERATOR CLASS name USING index_method SET SCHEMA new_schema diff --git a/doc/src/sgml/ref/alter_operator.sgml b/doc/src/sgml/ref/alter_operator.sgml index b3bfa9ccbe97..ad90c137f149 100644 --- a/doc/src/sgml/ref/alter_operator.sgml +++ b/doc/src/sgml/ref/alter_operator.sgml @@ -21,13 +21,13 @@ PostgreSQL documentation -ALTER OPERATOR name ( { left_type | NONE } , { right_type | NONE } ) - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER OPERATOR name ( { left_type | NONE } , right_type ) + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } -ALTER OPERATOR name ( { left_type | NONE } , { right_type | NONE } ) +ALTER OPERATOR name ( { left_type | NONE } , right_type ) SET SCHEMA new_schema -ALTER OPERATOR name ( { left_type | NONE } , { right_type | NONE } ) +ALTER OPERATOR name ( { left_type | NONE } , right_type ) SET ( { RESTRICT = { res_proc | NONE } | JOIN = { join_proc | NONE } } [, ... ] ) @@ -79,8 +79,7 @@ ALTER OPERATOR name ( { left_typeright_type - The data type of the operator's right operand; write - NONE if the operator has no right operand. + The data type of the operator's right operand. diff --git a/doc/src/sgml/ref/alter_opfamily.sgml b/doc/src/sgml/ref/alter_opfamily.sgml index 4ac1cca95a3f..b2e5b9b72ec8 100644 --- a/doc/src/sgml/ref/alter_opfamily.sgml +++ b/doc/src/sgml/ref/alter_opfamily.sgml @@ -37,7 +37,7 @@ ALTER OPERATOR FAMILY name USING index_method - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER OPERATOR FAMILY name USING index_method SET SCHEMA new_schema @@ -141,7 +141,7 @@ ALTER OPERATOR FAMILY name USING - The operators should not be defined by SQL functions. A SQL function + The operators should not be defined by SQL functions. An SQL function is likely to be inlined into the calling query, which will prevent the optimizer from recognizing that the query matches an index. diff --git a/doc/src/sgml/ref/alter_policy.sgml b/doc/src/sgml/ref/alter_policy.sgml index a1c720a95693..fbc262ba20d1 100644 --- a/doc/src/sgml/ref/alter_policy.sgml +++ b/doc/src/sgml/ref/alter_policy.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation ALTER POLICY - change the definition of a row level security policy + change the definition of a row-level security policy @@ -24,7 +24,7 @@ PostgreSQL documentation ALTER POLICY name ON table_name RENAME TO new_name ALTER POLICY name ON table_name - [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ] + [ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ] [ USING ( using_expression ) ] [ WITH CHECK ( check_expression ) ] diff --git a/doc/src/sgml/ref/alter_procedure.sgml b/doc/src/sgml/ref/alter_procedure.sgml index dae80076d953..033fda92ee51 100644 --- a/doc/src/sgml/ref/alter_procedure.sgml +++ b/doc/src/sgml/ref/alter_procedure.sgml @@ -26,11 +26,11 @@ ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] RENAME TO new_name ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] SET SCHEMA new_schema ALTER PROCEDURE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] - DEPENDS ON EXTENSION extension_name + [ NO ] DEPENDS ON EXTENSION extension_name where action is one of: @@ -81,8 +81,9 @@ ALTER PROCEDURE name [ ( [ [ ALTER PROCEDURE does not actually pay any attention to argument names, since only the argument data - types are needed to determine the procedure's identity. + types are used to determine the procedure's identity. @@ -107,6 +108,8 @@ ALTER PROCEDURE name [ ( [ [ for the details of how + the procedure is looked up using the argument data type(s). diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml index 534e598d93e4..faa114b2c681 100644 --- a/doc/src/sgml/ref/alter_publication.sgml +++ b/doc/src/sgml/ref/alter_publication.sgml @@ -25,7 +25,7 @@ ALTER PUBLICATION name ADD TABLE [ ALTER PUBLICATION name SET TABLE [ ONLY ] table_name [ * ] [, ...] ALTER PUBLICATION name DROP TABLE [ ONLY ] table_name [ * ] [, ...] ALTER PUBLICATION name SET ( publication_parameter [= value] [, ... ] ) -ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER PUBLICATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER PUBLICATION name RENAME TO new_name @@ -62,11 +62,12 @@ ALTER PUBLICATION name RENAME TO You must own the publication to use ALTER PUBLICATION. + Adding a table to a publication additionally requires owning that table. To alter the owner, you must also be a direct or indirect member of the new owning role. The new owner must have CREATE privilege on the database. Also, the new owner of a FOR ALL TABLES publication must be a superuser. However, a superuser can change the - ownership of a publication while circumventing these restrictions. + ownership of a publication regardless of these restrictions. diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml index 0ada4fe1da78..c9047374effd 100644 --- a/doc/src/sgml/ref/alter_role.sgml +++ b/doc/src/sgml/ref/alter_role.sgml @@ -53,6 +53,7 @@ ALTER ROLE name RESOURCE GROUP {where role_specification can be: role_name + | CURRENT_ROLE | CURRENT_USER | SESSION_USER @@ -69,15 +70,17 @@ ALTER ROLE name RESOURCE GROUP { The first variant of this command listed in the synopsis can change many of the role attributes that can be specified in - . + CREATE ROLE. (All the possible attributes are covered, except that there are no options for adding or removing memberships; use - and - for that.) + GRANT and + REVOKE for that.) Attributes not mentioned in the command retain their previous settings. Database superusers can change any of these settings for any role. Roles having CREATEROLE privilege can change any of these - settings, but only for non-superuser and non-replication roles. + settings except SUPERUSER, REPLICATION, + and BYPASSRLS; but only for non-superuser and + non-replication roles. Ordinary roles can only change their own password. @@ -109,8 +112,8 @@ ALTER ROLE name RESOURCE GROUP {postgresql.conf or has been received from the postgres command line. This only happens at login time; executing - or - does not cause new + SET ROLE or + SET SESSION AUTHORIZATION does not cause new configuration values to be set. Settings set for all databases are overridden by database-specific settings attached to a role. Settings for specific databases or specific roles override @@ -141,6 +144,7 @@ ALTER ROLE name RESOURCE GROUP { + CURRENT_ROLE CURRENT_USER @@ -181,7 +185,7 @@ ALTER ROLE name RESOURCE GROUP { These clauses alter attributes originally set by - . For more information, see the + CREATE ROLE. For more information, see the CREATE ROLE reference page. @@ -252,8 +256,8 @@ ALTER ROLE name RESOURCE GROUP { Role-specific variable settings take effect only at login; - and - + SET ROLE and + SET SESSION AUTHORIZATION do not process role-specific variable settings. @@ -271,14 +275,14 @@ ALTER ROLE name RESOURCE GROUP {Notes - Use - to add new roles, and to remove a role. + Use CREATE ROLE + to add new roles, and DROP ROLE to remove a role. ALTER ROLE cannot change a role's memberships. - Use and - + Use GRANT and + REVOKE to do that. diff --git a/doc/src/sgml/ref/alter_routine.sgml b/doc/src/sgml/ref/alter_routine.sgml index d1699691e10f..d6c9dea2ebc7 100644 --- a/doc/src/sgml/ref/alter_routine.sgml +++ b/doc/src/sgml/ref/alter_routine.sgml @@ -26,15 +26,16 @@ ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] RENAME TO new_name ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] SET SCHEMA new_schema ALTER ROUTINE name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] - DEPENDS ON EXTENSION extension_name + [ NO ] DEPENDS ON EXTENSION extension_name where action is one of: - IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF + IMMUTABLE | STABLE | VOLATILE + [ NOT ] LEAKPROOF [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER PARALLEL { UNSAFE | RESTRICTED | SAFE } COST execution_cost diff --git a/doc/src/sgml/ref/alter_schema.sgml b/doc/src/sgml/ref/alter_schema.sgml index 2937214026ec..04624c5a5eb0 100644 --- a/doc/src/sgml/ref/alter_schema.sgml +++ b/doc/src/sgml/ref/alter_schema.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation ALTER SCHEMA name RENAME TO new_name -ALTER SCHEMA name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER SCHEMA name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } diff --git a/doc/src/sgml/ref/alter_sequence.sgml b/doc/src/sgml/ref/alter_sequence.sgml index bfd20af6d3d5..3cd9ece49f22 100644 --- a/doc/src/sgml/ref/alter_sequence.sgml +++ b/doc/src/sgml/ref/alter_sequence.sgml @@ -31,7 +31,7 @@ ALTER SEQUENCE [ IF EXISTS ] name [ RESTART [ [ WITH ] restart ] ] [ CACHE cache ] [ [ NO ] CYCLE ] [ OWNED BY { table_name.column_name | NONE } ] -ALTER SEQUENCE [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER SEQUENCE [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER SEQUENCE [ IF EXISTS ] name RENAME TO new_name ALTER SEQUENCE [ IF EXISTS ] name SET SCHEMA new_schema diff --git a/doc/src/sgml/ref/alter_server.sgml b/doc/src/sgml/ref/alter_server.sgml index 17e55b093e93..186f38b5f82e 100644 --- a/doc/src/sgml/ref/alter_server.sgml +++ b/doc/src/sgml/ref/alter_server.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation ALTER SERVER name [ VERSION 'new_version' ] [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) ] -ALTER SERVER name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER SERVER name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER SERVER name RENAME TO new_name diff --git a/doc/src/sgml/ref/alter_statistics.sgml b/doc/src/sgml/ref/alter_statistics.sgml index be4c3f1f0576..ce6cdf2bb1ec 100644 --- a/doc/src/sgml/ref/alter_statistics.sgml +++ b/doc/src/sgml/ref/alter_statistics.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation -ALTER STATISTICS name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER STATISTICS name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER STATISTICS name RENAME TO new_name ALTER STATISTICS name SET SCHEMA new_schema ALTER STATISTICS name SET STATISTICS new_target @@ -99,9 +99,10 @@ ALTER STATISTICS name SET STATISTIC The statistic-gathering target for this statistics object for subsequent - operations. + ANALYZE operations. The target can be set in the range 0 to 10000; alternatively, set it - to -1 to revert to using the system default statistics + to -1 to revert to using the maximum of the statistics target of the + referenced columns, if set, or the system default statistics target (). For more information on the use of statistics by the PostgreSQL query planner, refer to diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml index 81c4e70cdf45..b3d173179f4c 100644 --- a/doc/src/sgml/ref/alter_subscription.sgml +++ b/doc/src/sgml/ref/alter_subscription.sgml @@ -22,12 +22,14 @@ PostgreSQL documentation ALTER SUBSCRIPTION name CONNECTION 'conninfo' -ALTER SUBSCRIPTION name SET PUBLICATION publication_name [, ...] [ WITH ( set_publication_option [= value] [, ... ] ) ] +ALTER SUBSCRIPTION name SET PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] +ALTER SUBSCRIPTION name ADD PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] +ALTER SUBSCRIPTION name DROP PUBLICATION publication_name [, ...] [ WITH ( publication_option [= value] [, ... ] ) ] ALTER SUBSCRIPTION name REFRESH PUBLICATION [ WITH ( refresh_option [= value] [, ... ] ) ] ALTER SUBSCRIPTION name ENABLE ALTER SUBSCRIPTION name DISABLE ALTER SUBSCRIPTION name SET ( subscription_parameter [= value] [, ... ] ) -ALTER SUBSCRIPTION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER SUBSCRIPTION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER SUBSCRIPTION name RENAME TO new_name @@ -48,6 +50,24 @@ ALTER SUBSCRIPTION name RENAME TO < (Currently, all subscription owners must be superusers, so the owner checks will be bypassed in practice. But this might change in the future.) + + + When refreshing a publication we remove the relations that are no longer + part of the publication and we also remove the table synchronization slots + if there are any. It is necessary to remove these slots so that the resources + allocated for the subscription on the remote host are released. If due to + network breakdown or some other error, PostgreSQL + is unable to remove the slots, an ERROR will be reported. To proceed in this + situation, the user either needs to retry the operation or disassociate the + slot from the subscription and drop the subscription as explained in + . + + + + Commands ALTER SUBSCRIPTION ... REFRESH PUBLICATION and + ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ... with refresh + option as true cannot be executed inside a transaction block. + @@ -76,16 +96,23 @@ ALTER SUBSCRIPTION name RENAME TO < SET PUBLICATION publication_name + ADD PUBLICATION publication_name + DROP PUBLICATION publication_name - Changes list of subscribed publications. See - for more information. - By default this command will also act like REFRESH - PUBLICATION. + Changes the list of subscribed publications. SET + replaces the entire list of publications with a new list, + ADD adds additional publications to the list of + publications, and DROP removes the publications from + the list of publications. See + for more information. By default, this command will also act like + REFRESH PUBLICATION, except that in case of + ADD or DROP, only the added or + dropped publications are refreshed. - set_publication_option specifies additional + publication_option specifies additional options for this operation. The supported options are: @@ -102,7 +129,8 @@ ALTER SUBSCRIPTION name RENAME TO < Additionally, refresh options as described - under REFRESH PUBLICATION may be specified. + under REFRESH PUBLICATION may be specified, + except in the case of DROP PUBLICATION. @@ -165,8 +193,9 @@ ALTER SUBSCRIPTION name RENAME TO < . See there for more information. The parameters that can be altered are slot_name, - synchronous_commit, and - binary. + synchronous_commit, + binary, and + streaming. diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index 65fa52d21822..f9c7e6482507 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -36,7 +36,7 @@ ALTER TABLE ALL IN TABLESPACE name ALTER TABLE [ IF EXISTS ] name ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT } ALTER TABLE [ IF EXISTS ] name - DETACH PARTITION partition_name + DETACH PARTITION partition_name [ CONCURRENTLY | FINALIZE ] ALTER TABLE [ IF EXISTS ] [ONLY] name SET WITH (REORGANIZE=true|false) @@ -65,6 +65,7 @@ ALTER TABLE name ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] ) ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] ) ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN } + ALTER [ COLUMN ] column_name SET COMPRESSION compression_method ADD table_constraint [ NOT VALID ] ADD table_constraint_using_index ALTER CONSTRAINT constraint_name [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] @@ -94,7 +95,7 @@ ALTER TABLE name NO INHERIT parent_table OF type_name NOT OF - OWNER TO { new_owner | CURRENT_USER | SESSION_USER } + OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING } and partition_bound_spec is: @@ -223,7 +224,7 @@ Where column_reference_storage_directive is: This form adds a new column to the table, using the same syntax as - . If IF NOT EXISTS + CREATE TABLE. If IF NOT EXISTS is specified and a column already exists with this name, no error is thrown. @@ -339,7 +340,7 @@ Where column_reference_storage_directive is: These forms change whether a column is an identity column or change the generation attribute of an existing identity column. - See for details. + See CREATE TABLE for details. Like SET DEFAULT, these forms only affect the behavior of subsequent INSERT and UPDATE commands; they do not cause rows @@ -361,7 +362,7 @@ Where column_reference_storage_directive is: These forms alter the sequence that underlies an existing identity column. sequence_option is an option - supported by such + supported by ALTER SEQUENCE such as INCREMENT BY. @@ -373,7 +374,7 @@ Where column_reference_storage_directive is: This form sets the per-column statistics-gathering target for subsequent - operations. + ANALYZE operations. The target can be set in the range 0 to 10000; alternatively, set it to -1 to revert to using the system default statistics target (). @@ -397,7 +398,7 @@ Where column_reference_storage_directive is: defined per-attribute options are n_distinct and n_distinct_inherited, which override the number-of-distinct-values estimates made by subsequent - + ANALYZE operations. n_distinct affects the statistics for the table itself, while n_distinct_inherited affects the statistics gathered for the table plus its inheritance children. When set to a @@ -454,12 +455,42 @@ Where column_reference_storage_directive is: + + + SET COMPRESSION compression_method + + + + This form sets the compression method for a column, determining how + values inserted in future will be compressed (if the storage mode + permits compression at all). + This does not cause the table to be rewritten, so existing data may still + be compressed with other compression methods. If the table is restored + with pg_restore, then all values are rewritten + with the configured compression method. + However, when data is inserted from another relation (for example, + by INSERT ... SELECT), values from the source table are + not necessarily detoasted, so any previously compressed data may retain + its existing compression method, rather than being recompressed with the + compression method of the target column. + The supported compression + methods are pglz and lz4. + (lz4 is available only if + was used when building PostgreSQL.) In + addition, compression_method + can be default, which selects the default behavior of + consulting the setting + at the time of data insertion to determine the method to use. + + + + ADD table_constraint [ NOT VALID ] This form adds a new constraint to a table using the same constraint - syntax as , plus the option NOT + syntax as CREATE TABLE, plus the option NOT VALID, which is currently only allowed for foreign key and CHECK constraints. @@ -493,7 +524,7 @@ Where column_reference_storage_directive is: Additional restrictions apply when unique or primary key constraints - are added to partitioned tables; see . + are added to partitioned tables; see CREATE TABLE. Also, foreign key constraints on partitioned tables may not be declared NOT VALID at present. @@ -577,6 +608,9 @@ Where column_reference_storage_directive is: (See below for an explanation of the usefulness of this command.) + + This command acquires a SHARE UPDATE EXCLUSIVE lock. + @@ -666,10 +700,10 @@ Where column_reference_storage_directive is: These forms control the application of row security policies belonging to the table. If enabled and no policies exist for the table, then a default-deny policy is applied. Note that policies can exist for a table - even if row level security is disabled. In this case, the policies will + even if row-level security is disabled. In this case, the policies will not be applied and the policies will be ignored. See also - . + CREATE POLICY. @@ -679,12 +713,12 @@ Where column_reference_storage_directive is: These forms control the application of row security policies belonging - to the table when the user is the table owner. If enabled, row level + to the table when the user is the table owner. If enabled, row-level security policies will be applied when the user is the table owner. If - disabled (the default) then row level security will not be applied when + disabled (the default) then row-level security will not be applied when the user is the table owner. See also - . + CREATE POLICY. @@ -694,7 +728,7 @@ Where column_reference_storage_directive is: This form selects the default index for future - + CLUSTER operations. It does not actually re-cluster the table. @@ -708,7 +742,7 @@ Where column_reference_storage_directive is: This form removes the most recently used - + CLUSTER index specification from the table. This affects future cluster operations that don't specify an index. @@ -750,7 +784,7 @@ Where column_reference_storage_directive is: When applied to a partitioned table, nothing is moved, but any partitions created afterwards with CREATE TABLE PARTITION OF will use that tablespace, - unless the TABLESPACE clause is used to override it. + unless overridden by a TABLESPACE clause. @@ -766,7 +800,7 @@ Where column_reference_storage_directive is: information_schema relations are not considered part of the system catalogs and will be moved. See also - . + CREATE TABLESPACE. @@ -788,12 +822,12 @@ Where column_reference_storage_directive is: This form changes one or more storage parameters for the table. See in the - documentation + CREATE TABLE documentation for details on the available parameters. Note that the table contents will not be modified immediately by this command; depending on the parameter you might need to rewrite the table to get the desired effects. - That can be done with VACUUM - FULL, or one of the forms + That can be done with VACUUM + FULL, CLUSTER or one of the forms of ALTER TABLE that forces a table rewrite. For planner related parameters, changes will take effect from the next time the table is locked so currently executing queries will not be @@ -892,7 +926,7 @@ Where column_reference_storage_directive is: - + REPLICA IDENTITY @@ -959,7 +993,7 @@ Where column_reference_storage_directive is: A partition using FOR VALUES uses same syntax for partition_bound_spec as - . The partition bound specification + CREATE TABLE. The partition bound specification must correspond to the partitioning strategy and partition key of the target table. The table to be attached must have all the same columns as the target table and no more; moreover, the column types must also @@ -970,7 +1004,7 @@ Where column_reference_storage_directive is: from the parent table will be created in the partition, if they don't already exist. If any of the CHECK constraints of the table being - attached is marked NO INHERIT, the command will fail; + attached are marked NO INHERIT, the command will fail; such constraints must be recreated without the NO INHERIT clause. @@ -1018,8 +1052,9 @@ Where column_reference_storage_directive is: - - DETACH PARTITION partition_name + + DETACH PARTITION partition_name [ CONCURRENTLY | FINALIZE ] + This form detaches the specified partition of the target table. The detached @@ -1027,6 +1062,31 @@ Where column_reference_storage_directive is: ties to the table from which it was detached. Any indexes that were attached to the target table's indexes are detached. Any triggers that were created as clones of those in the target table are removed. + SHARE lock is obtained on any tables that reference + this partitioned table in foreign key constraints. + + + If CONCURRENTLY is specified, it runs using a reduced + lock level to avoid blocking other sessions that might be accessing the + partitioned table. In this mode, two transactions are used internally. + During the first transaction, a SHARE UPDATE EXCLUSIVE + lock is taken on both parent table and partition, and the partition is + marked as undergoing detach; at that point, the transaction is committed + and all other transactions using the partitioned table are waited for. + Once all those transactions have completed, the second transaction + acquires SHARE UPDATE EXCLUSIVE on the partitioned + table and ACCESS EXCLUSIVE on the partition, + and the detach process completes. A CHECK constraint + that duplicates the partition constraint is added to the partition. + CONCURRENTLY cannot be run in a transaction block and + is not allowed if the partitioned table contains a default partition. + + + If FINALIZE is specified, a previous + DETACH CONCURRENTLY invocation that was cancelled or + interrupted is completed. + At most one partition in a partitioned table can be pending detach at + a time. diff --git a/doc/src/sgml/ref/alter_tablespace.sgml b/doc/src/sgml/ref/alter_tablespace.sgml index 356fb9f93f32..6de80746d564 100644 --- a/doc/src/sgml/ref/alter_tablespace.sgml +++ b/doc/src/sgml/ref/alter_tablespace.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation ALTER TABLESPACE name RENAME TO new_name -ALTER TABLESPACE name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER TABLESPACE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER TABLESPACE name SET ( tablespace_option = value [, ... ] ) ALTER TABLESPACE name RESET ( tablespace_option [, ... ] ) diff --git a/doc/src/sgml/ref/alter_trigger.sgml b/doc/src/sgml/ref/alter_trigger.sgml index 6d4784c82f19..43a7da4f0bcf 100644 --- a/doc/src/sgml/ref/alter_trigger.sgml +++ b/doc/src/sgml/ref/alter_trigger.sgml @@ -93,7 +93,7 @@ ALTER TRIGGER name ON The ability to temporarily enable or disable a trigger is provided by - , not by + ALTER TABLE, not by ALTER TRIGGER, because ALTER TRIGGER has no convenient way to express the option of enabling or disabling all of a table's triggers at once. diff --git a/doc/src/sgml/ref/alter_tsconfig.sgml b/doc/src/sgml/ref/alter_tsconfig.sgml index ebe0b94b27e5..8fafcd3bbd82 100644 --- a/doc/src/sgml/ref/alter_tsconfig.sgml +++ b/doc/src/sgml/ref/alter_tsconfig.sgml @@ -32,7 +32,7 @@ ALTER TEXT SEARCH CONFIGURATION name ALTER TEXT SEARCH CONFIGURATION name DROP MAPPING [ IF EXISTS ] FOR token_type [, ... ] ALTER TEXT SEARCH CONFIGURATION name RENAME TO new_name -ALTER TEXT SEARCH CONFIGURATION name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER TEXT SEARCH CONFIGURATION name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER TEXT SEARCH CONFIGURATION name SET SCHEMA new_schema diff --git a/doc/src/sgml/ref/alter_tsdictionary.sgml b/doc/src/sgml/ref/alter_tsdictionary.sgml index b29865e11e92..d1923ef1609f 100644 --- a/doc/src/sgml/ref/alter_tsdictionary.sgml +++ b/doc/src/sgml/ref/alter_tsdictionary.sgml @@ -25,7 +25,7 @@ ALTER TEXT SEARCH DICTIONARY name ( option [ = value ] [, ... ] ) ALTER TEXT SEARCH DICTIONARY name RENAME TO new_name -ALTER TEXT SEARCH DICTIONARY name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER TEXT SEARCH DICTIONARY name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER TEXT SEARCH DICTIONARY name SET SCHEMA new_schema diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml index f015fcd2689b..21887e88a0f2 100644 --- a/doc/src/sgml/ref/alter_type.sgml +++ b/doc/src/sgml/ref/alter_type.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation -ALTER TYPE name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER TYPE name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER TYPE name RENAME TO new_name ALTER TYPE name SET SCHEMA new_schema ALTER TYPE name RENAME ATTRIBUTE attribute_name TO new_attribute_name [ CASCADE | RESTRICT ] @@ -90,7 +90,7 @@ ALTER TYPE name SET ( This form adds a new attribute to a composite type, using the same syntax as - . + CREATE TYPE. @@ -194,6 +194,14 @@ ALTER TYPE name SET ( + + + SUBSCRIPT can be set to the name of a type-specific + subscripting handler function, or NONE to remove + the type's subscripting handler function. Using this option + requires superuser privilege. + + STORAGE diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml index 9ee61a41e47a..d6a77dccbaf5 100644 --- a/doc/src/sgml/ref/alter_user.sgml +++ b/doc/src/sgml/ref/alter_user.sgml @@ -47,6 +47,7 @@ ALTER USER { role_specification | A where role_specification can be: role_name + | CURRENT_ROLE | CURRENT_USER | SESSION_USER @@ -57,7 +58,7 @@ ALTER USER { role_specification | A ALTER USER is now an alias for - . + ALTER ROLE. diff --git a/doc/src/sgml/ref/alter_user_mapping.sgml b/doc/src/sgml/ref/alter_user_mapping.sgml index 7a9b5a188af4..ee5aee9bc9e5 100644 --- a/doc/src/sgml/ref/alter_user_mapping.sgml +++ b/doc/src/sgml/ref/alter_user_mapping.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -ALTER USER MAPPING FOR { user_name | USER | CURRENT_USER | SESSION_USER | PUBLIC } +ALTER USER MAPPING FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC } SERVER server_name OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) @@ -51,7 +51,7 @@ ALTER USER MAPPING FOR { user_name user_name - User name of the mapping. CURRENT_USER + User name of the mapping. CURRENT_ROLE, CURRENT_USER, and USER match the name of the current user. PUBLIC is used to match all present and future user names in the system. diff --git a/doc/src/sgml/ref/alter_view.sgml b/doc/src/sgml/ref/alter_view.sgml index e8d9e11e0f6f..98c312c5bf6b 100644 --- a/doc/src/sgml/ref/alter_view.sgml +++ b/doc/src/sgml/ref/alter_view.sgml @@ -23,7 +23,7 @@ PostgreSQL documentation ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name SET DEFAULT expression ALTER VIEW [ IF EXISTS ] name ALTER [ COLUMN ] column_name DROP DEFAULT -ALTER VIEW [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } +ALTER VIEW [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER VIEW [ IF EXISTS ] name RENAME [ COLUMN ] column_name TO new_column_name ALTER VIEW [ IF EXISTS ] name RENAME TO new_name ALTER VIEW [ IF EXISTS ] name SET SCHEMA new_schema diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml index 5ac3ba832193..176c7cb2256b 100644 --- a/doc/src/sgml/ref/analyze.sgml +++ b/doc/src/sgml/ref/analyze.sgml @@ -174,7 +174,7 @@ ANALYZE [ VERBOSE ] [ table_and_columns + strategy for read-mostly databases is to run VACUUM and ANALYZE once a day during a low-usage time of day. (This will not be sufficient if there is heavy update activity.) @@ -205,7 +205,7 @@ ANALYZE [ VERBOSE ] [ table_and_columnsANALYZE is run, even if the actual table contents did not change. This might result in small changes in the planner's estimated costs shown by - . + EXPLAIN. In rare situations, this non-determinism will cause the planner's choices of query plans to change after ANALYZE is run. To avoid this, raise the amount of statistics collected by @@ -216,8 +216,8 @@ ANALYZE [ VERBOSE ] [ table_and_columns configuration variable, or on a column-by-column basis by setting the per-column statistics - target with ALTER TABLE ... ALTER COLUMN ... SET - STATISTICS (see ). + target with ALTER TABLE ... ALTER COLUMN ... SET + STATISTICS. The target value sets the maximum number of entries in the most-common-value list and the maximum number of bins in the histogram. The default target value @@ -246,25 +246,42 @@ ANALYZE [ VERBOSE ] [ table_and_columnsALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...) - (see ). + ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...). - If the table being analyzed has one or more children, - ANALYZE will gather statistics twice: once on the - rows of the parent table only, and a second time on the rows of the - parent table with all of its children. This second set of statistics - is needed when planning queries that traverse the entire inheritance - tree. The autovacuum daemon, however, will only consider inserts or - updates on the parent table itself when deciding whether to trigger an - automatic analyze for that table. If that table is rarely inserted into - or updated, the inheritance statistics will not be up to date unless you - run ANALYZE manually. + If the table being analyzed is partitioned, ANALYZE + will gather statistics by sampling blocks randomly from its partitions; + in addition, it will recurse into each partition and update its statistics. + (However, in multi-level partitioning scenarios, each leaf partition + will only be analyzed once.) + By contrast, if the table being analyzed has inheritance children, + ANALYZE will gather statistics for it twice: + once on the rows of the parent table only, and a second time on the + rows of the parent table with all of its children. This second set of + statistics is needed when planning queries that traverse the entire + inheritance tree. The child tables themselves are not individually + analyzed in this case. - If any of the child tables are foreign tables whose foreign data wrappers + The autovacuum daemon counts inserts, updates and deletes in the + partitions to determine if auto-analyze is needed. However, adding + or removing partitions does not affect autovacuum daemon decisions, + so triggering a manual ANALYZE is recommended + when this occurs. + + + + Tuples changed in inheritance children do not count towards analyze + on the parent table. If the parent table is empty or rarely modified, + it may never be processed by autovacuum. It's necessary to + periodically run a manual ANALYZE to keep the + statistics of the table hierarchy up to date. + + + + If any of the child tables or partitions are foreign tables whose foreign data wrappers do not support ANALYZE, those child tables are ignored while gathering inheritance statistics. @@ -274,6 +291,12 @@ ANALYZE [ VERBOSE ] [ table_and_columns + + + Each backend running ANALYZE will report its progress + in the pg_stat_progress_analyze view. See + for details. + @@ -292,6 +315,7 @@ ANALYZE [ VERBOSE ] [ table_and_columns + diff --git a/doc/src/sgml/ref/begin.sgml b/doc/src/sgml/ref/begin.sgml index c23bbfb4e711..016b02148741 100644 --- a/doc/src/sgml/ref/begin.sgml +++ b/doc/src/sgml/ref/begin.sgml @@ -37,9 +37,9 @@ BEGIN [ WORK | TRANSACTION ] [ transaction_mode BEGIN initiates a transaction block, that is, all statements after a BEGIN command will be - executed in a single transaction until an explicit or is given. + executed in a single transaction until an explicit COMMIT or ROLLBACK is given. By default (without BEGIN), PostgreSQL executes transactions in autocommit mode, that is, each @@ -60,7 +60,7 @@ BEGIN [ WORK | TRANSACTION ] [ transaction_mode If the isolation level, read/write mode, or deferrable mode is specified, the new transaction has those characteristics, as if - + SET TRANSACTION was executed. @@ -90,13 +90,13 @@ BEGIN [ WORK | TRANSACTION ] [ transaction_modeNotes - has the same functionality + START TRANSACTION has the same functionality as BEGIN. - Use or - + Use COMMIT or + ROLLBACK to terminate a transaction block. @@ -131,7 +131,7 @@ BEGIN; BEGIN is a PostgreSQL language extension. It is equivalent to the SQL-standard command - , whose reference page + START TRANSACTION, whose reference page contains additional compatibility information. diff --git a/doc/src/sgml/ref/call.sgml b/doc/src/sgml/ref/call.sgml index abaa81c78b94..9e83a77b7c9d 100644 --- a/doc/src/sgml/ref/call.sgml +++ b/doc/src/sgml/ref/call.sgml @@ -55,9 +55,24 @@ CALL name ( [ argument - An input argument for the procedure call. - See for the full details on - function and procedure call syntax, including use of named parameters. + An argument expression for the procedure call. + + + + Arguments can include parameter names, using the syntax + name => value. + This works the same as in ordinary function calls; see + for details. + + + + Arguments must be supplied for all procedure parameters that lack + defaults, including OUT parameters. However, + arguments matching OUT parameters are not evaluated, + so it's customary to just write NULL for them. + (Writing something else for an OUT parameter + might cause compatibility problems with + future PostgreSQL versions.) @@ -101,7 +116,10 @@ CALL do_db_maintenance(); Compatibility - CALL conforms to the SQL standard. + CALL conforms to the SQL standard, + except for the handling of output parameters. The standard + says that users should write variables to receive the values + of output parameters. diff --git a/doc/src/sgml/ref/close.sgml b/doc/src/sgml/ref/close.sgml index e464df1965d9..32d20edd6aa4 100644 --- a/doc/src/sgml/ref/close.sgml +++ b/doc/src/sgml/ref/close.sgml @@ -84,7 +84,7 @@ CLOSE { name | ALL } PostgreSQL does not have an explicit OPEN cursor statement; a cursor is considered open when it is declared. Use the - + DECLARE statement to declare a cursor. diff --git a/doc/src/sgml/ref/cluster.sgml b/doc/src/sgml/ref/cluster.sgml index 978a6a5acef2..4627c33aaee1 100644 --- a/doc/src/sgml/ref/cluster.sgml +++ b/doc/src/sgml/ref/cluster.sgml @@ -22,7 +22,12 @@ PostgreSQL documentation CLUSTER [VERBOSE] table_name [ USING index_name ] +CLUSTER ( option [, ...] ) table_name [ USING index_name ] CLUSTER [VERBOSE] + +where option can be one of: + + VERBOSE [ boolean ] @@ -57,7 +62,7 @@ CLUSTER [VERBOSE] CLUSTER table_name reclusters the table using the same index as before. You can also use the CLUSTER or SET WITHOUT CLUSTER - forms of to set the index to be used for + forms of ALTER TABLE to set the index to be used for future cluster operations, or to clear any previous setting. @@ -107,6 +112,20 @@ CLUSTER [VERBOSE] + + + boolean + + + Specifies whether the selected option should be turned on or off. + You can write TRUE, ON, or + 1 to enable the option, and FALSE, + OFF, or 0 to disable it. The + boolean value can also + be omitted, in which case TRUE is assumed. + + + @@ -170,7 +189,7 @@ CLUSTER [VERBOSE] Because the planner records statistics about the ordering of - tables, it is advisable to run + tables, it is advisable to run ANALYZE on the newly clustered table. Otherwise, the planner might make poor choices of query plans. @@ -183,6 +202,11 @@ CLUSTER [VERBOSE] are periodically reclustered. + + Each backend running CLUSTER will report its progress + in the pg_stat_progress_cluster view. See + for details. + @@ -233,6 +257,7 @@ CLUSTER index_name ON + diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml index 177856ca74d2..c838b22c4405 100644 --- a/doc/src/sgml/ref/clusterdb.sgml +++ b/doc/src/sgml/ref/clusterdb.sgml @@ -90,12 +90,15 @@ PostgreSQL documentation - Specifies the name of the database to be clustered. - If this is not specified and (or - ) is not used, the database name is read + Specifies the name of the database to be clustered, + when / is not used. + If this is not specified, the database name is read from the environment variable PGDATABASE. If that is not set, the user name specified for the connection is - used. + used. The dbname can be a connection string. If so, + connection string parameters will override any conflicting command + line options. @@ -246,10 +249,16 @@ PostgreSQL documentation - Specifies the name of the database to connect to discover what other - databases should be clustered. If not specified, the - postgres database will be used, - and if that does not exist, template1 will be used. + Specifies the name of the database to connect to to discover which + databases should be clustered, + when / is used. + If not specified, the postgres database will be used, + or if that does not exist, template1 will be used. + This can be a connection + string. If so, connection string parameters will override any + conflicting command line options. Also, connection string parameters + other than the database name itself will be re-used when connecting + to other databases. diff --git a/doc/src/sgml/ref/comment.sgml b/doc/src/sgml/ref/comment.sgml index ade77e4a89d8..8a850dc98652 100644 --- a/doc/src/sgml/ref/comment.sgml +++ b/doc/src/sgml/ref/comment.sgml @@ -130,10 +130,8 @@ COMMENT ON trigger_name - The name of the object to be commented. Names of tables, - aggregates, collations, conversions, domains, foreign tables, functions, - indexes, operators, operator classes, operator families, procedures, routines, sequences, - statistics, text search objects, types, and views can be + The name of the object to be commented. Names of objects that reside in + schemas (tables, functions, etc.) can be schema-qualified. When commenting on a column, relation_name must refer to a table, view, composite type, or foreign table. @@ -225,7 +223,7 @@ COMMENT ON The data type(s) of the operator's arguments (optionally schema-qualified). Write NONE for the missing argument - of a prefix or postfix operator. + of a prefix operator. @@ -307,7 +305,7 @@ COMMENT ON TABLE mytable IS NULL; Some more examples: -COMMENT ON ACCESS METHOD rtree IS 'R-Tree access method'; +COMMENT ON ACCESS METHOD gin IS 'GIN index access method'; COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance'; COMMENT ON CAST (text AS int4) IS 'Allow casts from text to int4'; COMMENT ON COLLATION "fr_CA" IS 'Canadian French'; @@ -317,6 +315,7 @@ COMMENT ON CONSTRAINT bar_col_cons ON bar IS 'Constrains column col'; COMMENT ON CONSTRAINT dom_col_constr ON DOMAIN dom IS 'Constrains col of domain'; COMMENT ON DATABASE my_database IS 'Development Database'; COMMENT ON DOMAIN my_domain IS 'Email Address Domain'; +COMMENT ON EVENT TRIGGER abort_ddl IS 'Aborts all DDL commands'; COMMENT ON EXTENSION hstore IS 'implements the hstore data type'; COMMENT ON FOREIGN DATA WRAPPER mywrapper IS 'my foreign data wrapper'; COMMENT ON FOREIGN TABLE my_foreign_table IS 'Employee Information in other database'; @@ -331,12 +330,15 @@ COMMENT ON OPERATOR CLASS int4ops USING btree IS '4 byte integer operators for b COMMENT ON OPERATOR FAMILY integer_ops USING btree IS 'all integer operators for btrees'; COMMENT ON POLICY my_policy ON mytable IS 'Filter rows by users'; COMMENT ON PROCEDURE my_proc (integer, integer) IS 'Runs a report'; +COMMENT ON PUBLICATION alltables IS 'Publishes all operations on all tables'; COMMENT ON ROLE my_role IS 'Administration group for finance tables'; +COMMENT ON ROUTINE my_routine (integer, integer) IS 'Runs a routine (which is a function or procedure)'; COMMENT ON RULE my_rule ON my_table IS 'Logs updates of employee records'; COMMENT ON SCHEMA my_schema IS 'Departmental data'; COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys'; COMMENT ON SERVER myserver IS 'my foreign server'; COMMENT ON STATISTICS my_statistics IS 'Improves planner row estimations'; +COMMENT ON SUBSCRIPTION alltables IS 'Subscription for all operations on all tables'; COMMENT ON TABLE my_schema.my_table IS 'Employee Information'; COMMENT ON TABLESPACE my_tablespace IS 'Tablespace for indexes'; COMMENT ON TEXT SEARCH CONFIGURATION my_config IS 'Special word filtering'; diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 94b59ce145f1..7adb0812866d 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -88,6 +88,12 @@ COPY { table_name [ ( + + + Each backend running COPY will report its progress + in the pg_stat_progress_copy view. See + for details. + @@ -118,9 +124,11 @@ COPY { table_name [ ( query - A , , - , or - command whose results are to be + A SELECT, + VALUES, + INSERT, + UPDATE, or + DELETE command whose results are to be copied. Note that parentheses are required around the query. @@ -447,10 +455,16 @@ COPY count Notes - COPY TO can only be used with plain tables, not - with views. However, you can write COPY (SELECT * FROM - viewname) TO ... - to copy the current contents of a view. + COPY TO can be used only with plain + tables, not views, and does not copy rows from child tables + or child partitions. For example, COPY table TO copies + the same rows as SELECT * FROM ONLY table. + The syntax COPY (SELECT * FROM table) TO ... can be used to + dump all of the rows in an inheritance hierarchy, partitioned table, + or view. @@ -459,16 +473,6 @@ COPY count INSTEAD OF INSERT triggers. - - COPY only deals with the specific table named; - it does not copy data to or from child tables. Thus for example - COPY table TO - shows the same data as SELECT * FROM ONLY table. But COPY - (SELECT * FROM table) TO ... - can be used to dump all of the data in an inheritance hierarchy. - - You must have select privilege on the table whose values are read by COPY TO, and @@ -497,7 +501,7 @@ COPY count by the server, not by the client application, must be executable by the PostgreSQL user. COPY naming a file or command is only allowed to - database superusers or users who are granted one of the default roles + database superusers or users who are granted one of the roles pg_read_server_files, pg_write_server_files, or pg_execute_server_program, since it allows reading @@ -1090,5 +1094,13 @@ COPY [ BINARY ] table_name [ WITH NULL AS 'null_string' ] + + + See Also + + + + + diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml index c3f9b1383c75..4e6204a1f8a9 100644 --- a/doc/src/sgml/ref/create_aggregate.sgml +++ b/doc/src/sgml/ref/create_aggregate.sgml @@ -642,7 +642,7 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; The meanings of PARALLEL SAFE, PARALLEL RESTRICTED, and PARALLEL UNSAFE are the same as - in . An aggregate will not be + in CREATE FUNCTION. An aggregate will not be considered for parallelization if it is marked PARALLEL UNSAFE (which is the default!) or PARALLEL RESTRICTED. Note that the parallel-safety markings of the aggregate's support diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml index 2b4d4d557328..bad75bc1dce5 100644 --- a/doc/src/sgml/ref/create_cast.sgml +++ b/doc/src/sgml/ref/create_cast.sgml @@ -304,7 +304,7 @@ SELECT CAST ( 2 AS numeric ) + 4.0; Notes - Use to remove user-defined casts. + Use DROP CAST to remove user-defined casts. diff --git a/doc/src/sgml/ref/create_conversion.sgml b/doc/src/sgml/ref/create_conversion.sgml index e7700fecfc53..75d7b0094558 100644 --- a/doc/src/sgml/ref/create_conversion.sgml +++ b/doc/src/sgml/ref/create_conversion.sgml @@ -117,9 +117,15 @@ conv_proc( integer, -- destination encoding ID cstring, -- source string (null terminated C string) internal, -- destination (fill with a null terminated C string) - integer -- source string length -) RETURNS void; - + integer, -- source string length + boolean -- if true, don't throw an error if conversion fails +) RETURNS integer; + + The return value is the number of source bytes that were successfully + converted. If the last argument is false, the function must throw an + error on invalid input, and the return value is always equal to the + source string length. + diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml index d116b321bce9..41cb4068ec2f 100644 --- a/doc/src/sgml/ref/create_database.sgml +++ b/doc/src/sgml/ref/create_database.sgml @@ -139,7 +139,7 @@ CREATE DATABASE name Collation order (LC_COLLATE) to use in the new database. - This affects the sort order applied to strings, e.g. in queries with + This affects the sort order applied to strings, e.g., in queries with ORDER BY, as well as the order used in indexes on text columns. The default is to use the collation order of the template database. See below for additional restrictions. @@ -151,7 +151,7 @@ CREATE DATABASE name Character classification (LC_CTYPE) to use in the new - database. This affects the categorization of characters, e.g. lower, + database. This affects the categorization of characters, e.g., lower, upper and digit. The default is to use the character classification of the template database. See below for additional restrictions. @@ -226,7 +226,7 @@ CREATE DATABASE name - Use to remove a database. + Use DROP DATABASE to remove a database. @@ -235,9 +235,9 @@ CREATE DATABASE name - Database-level configuration parameters (set via ) and database-level permissions (set via - ) are not copied from the template database. + Database-level configuration parameters (set via ALTER DATABASE) and database-level permissions (set via + GRANT) are not copied from the template database. diff --git a/doc/src/sgml/ref/create_event_trigger.sgml b/doc/src/sgml/ref/create_event_trigger.sgml index 52ba746166be..becd31bcadf7 100644 --- a/doc/src/sgml/ref/create_event_trigger.sgml +++ b/doc/src/sgml/ref/create_event_trigger.sgml @@ -86,7 +86,7 @@ CREATE EVENT TRIGGER name A list of values for the associated filter_variable for which the trigger should fire. For TAG, this means a - list of command tags (e.g. 'DROP FUNCTION'). + list of command tags (e.g., 'DROP FUNCTION'). diff --git a/doc/src/sgml/ref/create_extension.sgml b/doc/src/sgml/ref/create_extension.sgml index efd7fc646560..ca2b80d669c5 100644 --- a/doc/src/sgml/ref/create_extension.sgml +++ b/doc/src/sgml/ref/create_extension.sgml @@ -223,8 +223,7 @@ CREATE EXTENSION hstore SCHEMA addons; SET search_path = addons; CREATE EXTENSION hstore; - - + diff --git a/doc/src/sgml/ref/create_foreign_table.sgml b/doc/src/sgml/ref/create_foreign_table.sgml index 2e2243601f48..7d9f25244926 100644 --- a/doc/src/sgml/ref/create_foreign_table.sgml +++ b/doc/src/sgml/ref/create_foreign_table.sgml @@ -159,7 +159,7 @@ CHECK ( expression ) [ NO INHERIT ] tables from which the new foreign table automatically inherits all columns. Parent tables can be plain tables or foreign tables. See the similar form of - for more details. + CREATE TABLE for more details. @@ -171,7 +171,7 @@ CHECK ( expression ) [ NO INHERIT ] This form can be used to create the foreign table as partition of the given parent table with specified partition bound values. See the similar form of - for more details. + CREATE TABLE for more details. Note that it is currently not allowed to create the foreign table as a partition of the parent table if there are UNIQUE indexes on the parent table. (See also diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index 84d4e024db4d..0c9e2d19d2e5 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -28,9 +28,10 @@ CREATE [ OR REPLACE ] FUNCTION { LANGUAGE lang_name | TRANSFORM { FOR TYPE type_name } [, ... ] | WINDOW - | IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF - | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT - | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER + | { IMMUTABLE | STABLE | VOLATILE } + | [ NOT ] LEAKPROOF + | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT } + | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER } | PARALLEL { UNSAFE | RESTRICTED | SAFE } | EXECUTE ON { ANY | MASTER | ALL SEGMENTS } | COST execution_cost @@ -39,6 +40,7 @@ CREATE [ OR REPLACE ] FUNCTION | SET configuration_parameter { TO value | = value | FROM CURRENT } | AS 'definition' | AS 'obj_file', 'link_symbol' + | sql_body } ... @@ -101,6 +103,11 @@ CREATE [ OR REPLACE ] FUNCTION To be able to create a function, you must have USAGE privilege on the argument types and the return type. + + + Refer to for further information on writing + functions. + @@ -258,7 +265,9 @@ CREATE [ OR REPLACE ] FUNCTION The name of the language that the function is implemented in. It can be sql, c, internal, or the name of a user-defined - procedural language, e.g. plpgsql. Enclosing the + procedural language, e.g., plpgsql. The default is + sql if sql_body is specified. Enclosing the name in single quotes is deprecated and requires matching case. @@ -432,11 +441,11 @@ CREATE [ OR REPLACE ] FUNCTION Functions should be labeled parallel unsafe if they modify any database state, or if they make changes to the transaction such as using sub-transactions, or if they access sequences or attempt to make - persistent changes to settings (e.g. setval). They should + persistent changes to settings (e.g., setval). They should be labeled as parallel restricted if they access temporary tables, client connection state, cursors, prepared statements, or miscellaneous backend-local state which the system cannot synchronize in parallel mode - (e.g. setseed cannot be executed other than by the group + (e.g., setseed cannot be executed other than by the group leader because a change made by another process would not be reflected in the leader). In general, if a function is labeled as being safe when it is restricted or unsafe, or if it is labeled as being restricted when @@ -558,7 +567,7 @@ CREATE [ OR REPLACE ] FUNCTION the SQL function. The string obj_file is the name of the shared library file containing the compiled C function, and is interpreted - as for the command. The string + as for the LOAD command. The string link_symbol is the function's link symbol, that is, the name of the function in the C language source code. If the link symbol is omitted, it is assumed to @@ -578,13 +587,45 @@ CREATE [ OR REPLACE ] FUNCTION - + + sql_body - - Refer to for further information on writing - functions. - + + + The body of a LANGUAGE SQL function. This can + either be a single statement + +RETURN expression + + or a block + +BEGIN ATOMIC + statement; + statement; + ... + statement; +END + + + + + This is similar to writing the text of the function body as a string + constant (see definition above), but there + are some differences: This form only works for LANGUAGE + SQL, the string constant form works for all languages. This + form is parsed at function definition time, the string constant form is + parsed at execution time; therefore this form cannot support + polymorphic argument types and other constructs that are not resolvable + at function definition time. This form tracks dependencies between the + function and objects used in the function body, so DROP + ... CASCADE will work correctly, whereas the form using + string literals may leave dangling functions. Finally, this form is + more compatible with the SQL standard and other SQL implementations. + + + + @@ -662,14 +703,22 @@ CREATE FUNCTION foo(int, int default 42) ... Examples - Here are some trivial examples to help you get started. For more - information and examples, see . + Add two integers using an SQL function: CREATE FUNCTION add(integer, integer) RETURNS integer AS 'select $1 + $2;' LANGUAGE SQL IMMUTABLE RETURNS NULL ON NULL INPUT; + + The same function written in a more SQL-conforming style, using argument + names and an unquoted body: + +CREATE FUNCTION add(a integer, b integer) RETURNS integer + LANGUAGE SQL + IMMUTABLE + RETURNS NULL ON NULL INPUT + RETURN a + b; @@ -811,23 +860,74 @@ COMMIT; Compatibility - A CREATE FUNCTION command is defined in the SQL standard. - The PostgreSQL version is similar but - not fully compatible. The attributes are not portable, neither are the - different available languages. + A CREATE FUNCTION command is defined in the SQL + standard. The PostgreSQL implementation can be + used in a compatible way but has many extensions. Conversely, the SQL + standard specifies a number of optional features that are not implemented + in PostgreSQL. - For compatibility with some other database systems, - argmode can be written - either before or after argname. - But only the first way is standard-compliant. + The following are important compatibility issues: + + + + + OR REPLACE is a PostgreSQL extension. + + + + + + For compatibility with some other database systems, argmode can be written either before or + after argname. But only + the first way is standard-compliant. + + + + + + For parameter defaults, the SQL standard specifies only the syntax with + the DEFAULT key word. The syntax with + = is used in T-SQL and Firebird. + + + + + + The SETOF modifier is a PostgreSQL extension. + + + + + + Only SQL is standardized as a language. + + + + + + All other attributes except CALLED ON NULL INPUT and + RETURNS NULL ON NULL INPUT are not standardized. + + + + + + For the body of LANGUAGE SQL functions, the SQL + standard only specifies the sql_body form. + + + - For parameter defaults, the SQL standard specifies only the syntax with - the DEFAULT key word. The syntax - with = is used in T-SQL and Firebird. + Simple LANGUAGE SQL functions can be written in a way + that is both standard-conforming and portable to other implementations. + More complex functions using advanced features, optimization attributes, or + other languages will necessarily be specific to PostgreSQL in a significant + way. diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index c6dab3dae4f4..57ca2c8fa458 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -187,8 +187,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - Currently, the B-tree and the GiST index access methods support this - feature. In B-tree and the GiST indexes, the values of columns listed + Currently, the B-tree, GiST and SP-GiST index access methods support + this feature. In these indexes, the values of columns listed in the INCLUDE clause are included in leaf tuples which correspond to heap tuples, but are not included in upper-level index entries used for tree navigation. @@ -386,24 +386,46 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] The fillfactor for an index is a percentage that determines how full the index method will try to pack index pages. For B-trees, leaf pages - are filled to this percentage during initial index build, and also + are filled to this percentage during initial index builds, and also when extending the index at the right (adding new largest key values). If pages subsequently become completely full, they will be split, leading to - gradual degradation in the index's efficiency. B-trees use a default + fragmentation of the on-disk index structure. B-trees use a default fillfactor of 90, but any integer value from 10 to 100 can be selected. - If the table is static then fillfactor 100 is best to minimize the - index's physical size, but for heavily updated tables a smaller - fillfactor is better to minimize the need for page splits. The - other index methods use fillfactor in different but roughly analogous - ways; the default fillfactor varies between methods. + + + B-tree indexes on tables where many inserts and/or updates are + anticipated can benefit from lower fillfactor settings at + CREATE INDEX time (following bulk loading into the + table). Values in the range of 50 - 90 can usefully smooth + out the rate of page splits during the + early life of the B-tree index (lowering fillfactor like this may even + lower the absolute number of page splits, though this effect is highly + workload dependent). The B-tree bottom-up index deletion technique + described in is dependent on having + some extra space on pages to store extra + tuple versions, and so can be affected by fillfactor (though the effect + is usually not significant). + + + In other specific cases it might be useful to increase fillfactor to + 100 at CREATE INDEX time as a way of maximizing + space utilization. You should only consider this when you are + completely sure that the table is static (i.e. that it will never be + affected by either inserts or updates). A fillfactor setting of 100 + otherwise risks harming performance: even a few + updates or inserts will cause a sudden flood of page splits. + + + The other index methods use fillfactor in different but roughly + analogous ways; the default fillfactor varies between methods. - B-tree indexes also accept these parameters: + B-tree indexes additionally accept this parameter: @@ -434,20 +456,6 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - - - vacuum_cleanup_index_scale_factor (floating point) - - vacuum_cleanup_index_scale_factor - storage parameter - - - - - Per-index value for . - - - @@ -463,11 +471,15 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - Determines whether the buffering build technique described in + Determines whether the buffered build technique described in is used to build the index. With - OFF it is disabled, with ON it is enabled, and - with AUTO it is initially disabled, but turned on - on-the-fly once the index size reaches . The default is AUTO. + OFF buffering is disabled, with ON + it is enabled, and with AUTO it is initially disabled, + but is turned on on-the-fly once the index size reaches + . The default + is AUTO. + Note that if sorted build is possible, it will be used instead of + buffered build unless buffering=ON is specified. @@ -600,7 +612,10 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] ) predating the second - scan to terminate. Then finally the index can be marked ready for use, + scan to terminate, including transactions used by any phase of concurrent + index builds on other tables, if the indexes involved are partial or have + columns that are not simple column references. + Then finally the index can be marked ready for use, and the CREATE INDEX command terminates. Even then, however, the index may not be immediately usable for queries: in the worst case, it cannot be used as long as transactions exist that @@ -680,7 +695,10 @@ Indexes: Currently, only the B-tree, GiST, GIN, and BRIN index methods support - multicolumn indexes. Up to 32 fields can be specified by default. + multiple-key-column indexes. Whether there can be multiple key + columns is independent of whether INCLUDE columns + can be added to the index. Indexes can have up to 32 columns, + including INCLUDE columns. (This limit can be altered when building PostgreSQL.) Only B-tree currently supports unique indexes. @@ -741,6 +759,16 @@ Indexes: sort high, in queries that depend on indexes to avoid sorting steps. + + The system regularly collects statistics on all of a table's + columns. Newly-created non-expression indexes can immediately + use these statistics to determine an index's usefulness. + For new expression indexes, it is necessary to run ANALYZE or wait for + the autovacuum daemon to analyze + the table to generate statistics for these indexes. + + For most index methods, the speed of creating an index is dependent on the setting of . @@ -771,7 +799,7 @@ Indexes: least a 32MB share of the total maintenance_work_mem budget. There must also be a remaining 32MB share for the leader process. - Increasing + Increasing may allow more workers to be used, which will reduce the time needed for index creation, so long as the index build is not already I/O bound. Of course, there should also be sufficient @@ -779,8 +807,8 @@ Indexes: - Setting a value for parallel_workers via directly controls how many parallel + Setting a value for parallel_workers via ALTER TABLE directly controls how many parallel worker processes will be requested by a CREATE INDEX against the table. This bypasses the cost model completely, and prevents maintenance_work_mem @@ -808,10 +836,18 @@ Indexes: - Use + Use DROP INDEX to remove an index. + + Like any long-running transaction, CREATE INDEX on a + table can affect which tuples can be removed by concurrent + VACUUM on any other table. + Excepted from this are operations with the CONCURRENTLY + option for indexes that are not partial and do not index any expressions. + + Prior releases of PostgreSQL also had an R-tree index method. This method has been removed because @@ -820,6 +856,12 @@ Indexes: will interpret it as USING gist, to simplify conversion of old databases to GiST. + + + Each backend running CREATE INDEX will report its + progress in the pg_stat_progress_create_index + view. See for details. + @@ -945,6 +987,7 @@ CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity); + diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml index 10d1533d6d8c..102efe5a6c7f 100644 --- a/doc/src/sgml/ref/create_language.sgml +++ b/doc/src/sgml/ref/create_language.sgml @@ -137,7 +137,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE inline_handler is the name of a previously registered function that will be called to execute an anonymous code block - ( command) + (DO command) in this language. If no inline_handler function is specified, the language does not support anonymous code @@ -183,7 +183,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE to drop procedural languages. + Use DROP LANGUAGE to drop procedural languages. diff --git a/doc/src/sgml/ref/create_materialized_view.sgml b/doc/src/sgml/ref/create_materialized_view.sgml index de9f17655c63..d8c48252f49f 100644 --- a/doc/src/sgml/ref/create_materialized_view.sgml +++ b/doc/src/sgml/ref/create_materialized_view.sgml @@ -48,6 +48,12 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name A materialized view has many of the same properties as a table, but there is no support for temporary materialized views. + + + CREATE MATERIALIZED VIEW requires + CREATE privilege on the schema used for the materialized + view. + @@ -132,8 +138,8 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name query - A , TABLE, - or command. This query will run within a + A SELECT, TABLE, + or VALUES command. This query will run within a security-restricted operation; in particular, calls to functions that themselves create temporary tables will fail. diff --git a/doc/src/sgml/ref/create_opclass.sgml b/doc/src/sgml/ref/create_opclass.sgml index f42fb6494c6b..f1d6a4cbbe28 100644 --- a/doc/src/sgml/ref/create_opclass.sgml +++ b/doc/src/sgml/ref/create_opclass.sgml @@ -161,7 +161,7 @@ CREATE OPERATOR CLASS name [ DEFAUL In an OPERATOR clause, the operand data type(s) of the operator, or NONE to - signify a left-unary or right-unary operator. The operand data + signify a prefix operator. The operand data types can be omitted in the normal case where they are the same as the operator class's data type. @@ -234,7 +234,7 @@ CREATE OPERATOR CLASS name [ DEFAUL The data type actually stored in the index. Normally this is the same as the column data type, but some index methods - (currently GiST, GIN and BRIN) allow it to be different. The + (currently GiST, GIN, SP-GiST and BRIN) allow it to be different. The STORAGE clause must be omitted unless the index method allows a different type to be used. If the column data_type is specified @@ -265,7 +265,7 @@ CREATE OPERATOR CLASS name [ DEFAUL - The operators should not be defined by SQL functions. A SQL function + The operators should not be defined by SQL functions. An SQL function is likely to be inlined into the calling query, which will prevent the optimizer from recognizing that the query matches an index. diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml index d5c385c087f5..e27512ff3919 100644 --- a/doc/src/sgml/ref/create_operator.sgml +++ b/doc/src/sgml/ref/create_operator.sgml @@ -86,13 +86,9 @@ CREATE OPERATOR name ( - At least one of LEFTARG and RIGHTARG must be defined. For - binary operators, both must be defined. For right unary - operators, only LEFTARG should be defined, while for left - unary operators only RIGHTARG should be defined. - - - + For binary operators, both LEFTARG and + RIGHTARG must be defined. For prefix operators only + RIGHTARG should be defined. The function_name function must have been previously defined using CREATE FUNCTION and must be defined to accept the correct number @@ -153,7 +149,7 @@ CREATE OPERATOR name ( The data type of the operator's left operand, if any. - This option would be omitted for a left-unary operator. + This option would be omitted for a prefix operator. @@ -162,8 +158,7 @@ CREATE OPERATOR name ( right_type - The data type of the operator's right operand, if any. - This option would be omitted for a right-unary operator. + The data type of the operator's right operand. @@ -256,8 +251,8 @@ COMMUTATOR = OPERATOR(myschema.===) , - Use to delete user-defined operators - from a database. Use to modify operators in a + Use DROP OPERATOR to delete user-defined operators + from a database. Use ALTER OPERATOR to modify operators in a database. diff --git a/doc/src/sgml/ref/create_policy.sgml b/doc/src/sgml/ref/create_policy.sgml index 2e1229c4f94c..9f532068e640 100644 --- a/doc/src/sgml/ref/create_policy.sgml +++ b/doc/src/sgml/ref/create_policy.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation CREATE POLICY - define a new row level security policy for a table + define a new row-level security policy for a table @@ -24,7 +24,7 @@ PostgreSQL documentation CREATE POLICY name ON table_name [ AS { PERMISSIVE | RESTRICTIVE } ] [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ] - [ TO { role_name | PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ] + [ TO { role_name | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ] [ USING ( using_expression ) ] [ WITH CHECK ( check_expression ) ] @@ -188,7 +188,7 @@ CREATE POLICY name ON SQL conditional expression (returning boolean). The conditional expression cannot contain any aggregate or window functions. This expression will be added - to queries that refer to the table if row level security is enabled. + to queries that refer to the table if row-level security is enabled. Rows for which the expression returns true will be visible. Any rows for which the expression returns false or null will not be visible to the user (in a SELECT), and will not be @@ -207,7 +207,7 @@ CREATE POLICY name ON boolean). The conditional expression cannot contain any aggregate or window functions. This expression will be used in INSERT and UPDATE queries against - the table if row level security is enabled. Only rows for which the + the table if row-level security is enabled. Only rows for which the expression evaluates to true will be allowed. An error will be thrown if the expression evaluates to false or null for any of the records inserted or any of the records that result from the update. Note that diff --git a/doc/src/sgml/ref/create_procedure.sgml b/doc/src/sgml/ref/create_procedure.sgml index 0ea6513cb588..03a14c868458 100644 --- a/doc/src/sgml/ref/create_procedure.sgml +++ b/doc/src/sgml/ref/create_procedure.sgml @@ -29,6 +29,7 @@ CREATE [ OR REPLACE ] PROCEDURE | SET configuration_parameter { TO value | = value | FROM CURRENT } | AS 'definition' | AS 'obj_file', 'link_symbol' + | sql_body } ... @@ -76,6 +77,11 @@ CREATE [ OR REPLACE ] PROCEDURE To be able to create a procedure, you must have USAGE privilege on the argument types. + + + Refer to for further information on writing + procedures. + @@ -97,11 +103,9 @@ CREATE [ OR REPLACE ] PROCEDURE - The mode of an argument: IN, + The mode of an argument: IN, OUT, INOUT, or VARIADIC. If omitted, - the default is IN. (OUT - arguments are currently not supported for procedures. Use - INOUT instead.) + the default is IN. @@ -164,7 +168,9 @@ CREATE [ OR REPLACE ] PROCEDURE The name of the language that the procedure is implemented in. It can be sql, c, internal, or the name of a user-defined - procedural language, e.g. plpgsql. Enclosing the + procedural language, e.g., plpgsql. The default is + sql if sql_body is specified. Enclosing the name in single quotes is deprecated and requires matching case. @@ -285,7 +291,7 @@ CREATE [ OR REPLACE ] PROCEDURE the SQL procedure. The string obj_file is the name of the shared library file containing the compiled C procedure, and is interpreted - as for the command. The string + as for the LOAD command. The string link_symbol is the procedure's link symbol, that is, the name of the procedure in the C language source code. If the link symbol is omitted, it is assumed @@ -301,6 +307,41 @@ CREATE [ OR REPLACE ] PROCEDURE + + + sql_body + + + + The body of a LANGUAGE SQL procedure. This should + be a block + +BEGIN ATOMIC + statement; + statement; + ... + statement; +END + + + + + This is similar to writing the text of the procedure body as a string + constant (see definition above), but there + are some differences: This form only works for LANGUAGE + SQL, the string constant form works for all languages. This + form is parsed at procedure definition time, the string constant form is + parsed at execution time; therefore this form cannot support + polymorphic argument types and other constructs that are not resolvable + at procedure definition time. This form tracks dependencies between the + procedure and objects used in the procedure body, so DROP + ... CASCADE will work correctly, whereas the form using + string literals may leave dangling procedures. Finally, this form is + more compatible with the SQL standard and other SQL implementations. + + + + @@ -320,6 +361,7 @@ CREATE [ OR REPLACE ] PROCEDURE Examples + CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL @@ -327,9 +369,20 @@ AS $$ INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); $$; - -CALL insert_data(1, 2); + or + +CREATE PROCEDURE insert_data(a integer, b integer) +LANGUAGE SQL +BEGIN ATOMIC + INSERT INTO tbl VALUES (a); + INSERT INTO tbl VALUES (b); +END; + + and call like this: + +CALL insert_data(1, 2); + @@ -337,9 +390,9 @@ CALL insert_data(1, 2); A CREATE PROCEDURE command is defined in the SQL - standard. The PostgreSQL version is similar but - not fully compatible. For details see - also . + standard. The PostgreSQL implementation can be + used in a compatible way but has many extensions. For details see also + . diff --git a/doc/src/sgml/ref/create_role.sgml b/doc/src/sgml/ref/create_role.sgml index ae2fbaa2348d..d6e06939a3a6 100644 --- a/doc/src/sgml/ref/create_role.sgml +++ b/doc/src/sgml/ref/create_role.sgml @@ -169,7 +169,7 @@ in sync when changing the above synopsis! If not specified, NOLOGIN is the default, except when CREATE ROLE is invoked through its alternative spelling - . + CREATE USER. @@ -188,6 +188,8 @@ in sync when changing the above synopsis! highly privileged role, and should only be used on roles actually used for replication. If not specified, NOREPLICATION is the default. + You must be a superuser to create a new role having the + REPLICATION attribute. @@ -199,11 +201,16 @@ in sync when changing the above synopsis! These clauses determine whether a role bypasses every row-level security (RLS) policy. NOBYPASSRLS is the default. + You must be a superuser to create a new role having + the BYPASSRLS attribute. + + + Note that pg_dump will set row_security to OFF by default, to ensure all contents of a table are dumped out. If the user running pg_dump does not have appropriate - permissions, an error will be returned. The superuser and owner of the - table being dumped always bypass RLS. + permissions, an error will be returned. However, superusers and the + owner of the table being dumped always bypass RLS. @@ -382,8 +389,8 @@ in sync when changing the above synopsis! Notes - Use to - change the attributes of a role, and + Use ALTER ROLE to + change the attributes of a role, and DROP ROLE to remove a role. All the attributes specified by CREATE ROLE can be modified by later ALTER ROLE commands. @@ -392,13 +399,13 @@ in sync when changing the above synopsis! The preferred way to add and remove members of roles that are being used as groups is to use - and - . + GRANT and + REVOKE. The VALID UNTIL clause defines an expiration time for a - password only, not for the role per se. In + password only, not for the role per se. In particular, the expiration time is not enforced when logging in using a non-password-based authentication method. @@ -411,7 +418,7 @@ in sync when changing the above synopsis! a member of a role with CREATEDB privilege does not immediately grant the ability to create databases, even if INHERIT is set; it would be necessary to become that role via - before + SET ROLE before creating a database. diff --git a/doc/src/sgml/ref/create_schema.sgml b/doc/src/sgml/ref/create_schema.sgml index ffbe1ba3bcc2..3c2dddb1631e 100644 --- a/doc/src/sgml/ref/create_schema.sgml +++ b/doc/src/sgml/ref/create_schema.sgml @@ -29,6 +29,7 @@ CREATE SCHEMA IF NOT EXISTS AUTHORIZATION role_sp where role_specification can be: user_name + | CURRENT_ROLE | CURRENT_USER | SESSION_USER diff --git a/doc/src/sgml/ref/create_statistics.sgml b/doc/src/sgml/ref/create_statistics.sgml index 5b583aacb433..9a8c904c0885 100644 --- a/doc/src/sgml/ref/create_statistics.sgml +++ b/doc/src/sgml/ref/create_statistics.sgml @@ -21,9 +21,13 @@ PostgreSQL documentation +CREATE STATISTICS [ IF NOT EXISTS ] statistics_name + ON ( expression ) + FROM table_name + CREATE STATISTICS [ IF NOT EXISTS ] statistics_name [ ( statistics_kind [, ... ] ) ] - ON column_name, column_name [, ...] + ON { column_name | ( expression ) }, { column_name | ( expression ) } [, ...] FROM table_name @@ -39,6 +43,19 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na database and will be owned by the user issuing the command. + + The CREATE STATISTICS command has two basic forms. The + first form allows univariate statistics for a single expression to be + collected, providing benefits similar to an expression index without the + overhead of index maintenance. This form does not allow the statistics + kind to be specified, since the various statistics kinds refer only to + multivariate statistics. The second form of the command allows + multivariate statistics on multiple columns and/or expressions to be + collected, optionally specifying which statistics kinds to include. This + form will also automatically cause univariate statistics to be collected on + any expressions included in the list. + + If a schema name is given (for example, CREATE STATISTICS myschema.mystat ...) then the statistics object is created in the @@ -79,14 +96,16 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na statistics_kind - A statistics kind to be computed in this statistics object. + A multivariate statistics kind to be computed in this statistics object. Currently supported kinds are ndistinct, which enables n-distinct statistics, dependencies, which enables functional dependency statistics, and mcv which enables most-common values lists. If this clause is omitted, all supported statistics kinds are - included in the statistics object. + included in the statistics object. Univariate expression statistics are + built automatically if the statistics definition includes any complex + expressions rather than just simple column references. For more information, see and . @@ -98,8 +117,22 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na The name of a table column to be covered by the computed statistics. - At least two column names must be given; the order of the column names - is insignificant. + This is only allowed when building multivariate statistics. At least + two column names or expressions must be specified, and their order is + not significant. + + + + + + expression + + + An expression to be covered by the computed statistics. This may be + used to build univariate statistics on a single expression, or as part + of a list of multiple column names and/or expressions to build + multivariate statistics. In the latter case, separate univariate + statistics are built automatically for each expression in the list. @@ -125,13 +158,20 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na reading it. Once created, however, the ownership of the statistics object is independent of the underlying table(s). + + + Expression statistics are per-expression and are similar to creating an + index on the expression, except that they avoid the overhead of index + maintenance. Expression statistics are built automatically for each + expression in the statistics object definition. + Examples - Create table t1 with two functionally dependent columns, i.e. + Create table t1 with two functionally dependent columns, i.e., knowledge of a value in the first column is sufficient for determining the value in the other column. Then functional dependency statistics are built on those columns: @@ -168,7 +208,7 @@ EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0); Create table t2 with two perfectly correlated columns - (containing identical data), and a MCV list on those columns: + (containing identical data), and an MCV list on those columns: CREATE TABLE t2 ( @@ -196,6 +236,72 @@ EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2); in the table, allowing it to generate better estimates in both cases. + + Create table t3 with a single timestamp column, + and run queries using expressions on that column. Without extended + statistics, the planner has no information about the data distribution for + the expressions, and uses default estimates. The planner also does not + realize that the value of the date truncated to the month is fully + determined by the value of the date truncated to the day. Then expression + and ndistinct statistics are built on those two expressions: + + +CREATE TABLE t3 ( + a timestamp +); + +INSERT INTO t3 SELECT i FROM generate_series('2020-01-01'::timestamp, + '2020-12-31'::timestamp, + '1 minute'::interval) s(i); + +ANALYZE t3; + +-- the number of matching rows will be drastically underestimated: +EXPLAIN ANALYZE SELECT * FROM t3 + WHERE date_trunc('month', a) = '2020-01-01'::timestamp; + +EXPLAIN ANALYZE SELECT * FROM t3 + WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp + AND '2020-06-30'::timestamp; + +EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a) + FROM t3 GROUP BY 1, 2; + +-- build ndistinct statistics on the pair of expressions (per-expression +-- statistics are built automatically) +CREATE STATISTICS s3 (ndistinct) ON date_trunc('month', a), date_trunc('day', a) FROM t3; + +ANALYZE t3; + +-- now the row count estimates are more accurate: +EXPLAIN ANALYZE SELECT * FROM t3 + WHERE date_trunc('month', a) = '2020-01-01'::timestamp; + +EXPLAIN ANALYZE SELECT * FROM t3 + WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp + AND '2020-06-30'::timestamp; + +EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a) + FROM t3 GROUP BY 1, 2; + + + Without expression and ndistinct statistics, the planner has no information + about the number of distinct values for the expressions, and has to rely + on default estimates. The equality and range conditions are assumed to have + 0.5% selectivity, and the number of distinct values in the expression is + assumed to be the same as for the column (i.e. unique). This results in a + significant underestimate of the row count in the first two queries. Moreover, + the planner has no information about the relationship between the expressions, + so it assumes the two WHERE and GROUP BY + conditions are independent, and multiplies their selectivities together to + arrive at a severe overestimate of the group count in the aggregate query. + This is further exacerbated by the lack of accurate statistics for the + expressions, forcing the planner to use a default ndistinct estimate for the + expression derived from ndistinct for the column. With such statistics, the + planner recognizes that the conditions are correlated, and arrives at much + more accurate estimates. + + diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml index cdb22c54feab..e812beee3738 100644 --- a/doc/src/sgml/ref/create_subscription.sgml +++ b/doc/src/sgml/ref/create_subscription.sgml @@ -160,7 +160,7 @@ CREATE SUBSCRIPTION subscription_name It is safe to use off for logical replication: If the subscriber loses transactions because of missing - synchronization, the data will be resent from the publisher. + synchronization, the data will be sent again from the publisher. @@ -228,6 +228,17 @@ CREATE SUBSCRIPTION subscription_name + + streaming (boolean) + + + Specifies whether streaming of in-progress transactions should + be enabled for this subscription. By default, all transactions + are fully decoded on the publisher, and only then sent to the + subscriber as a whole. + + + diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index e9a9f7ac9f51..6303bf75d194 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -118,7 +118,7 @@ class="parameter">referential_action ] [ ON UPDATE and like_option is: -{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } +{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } and partition_bound_spec is: @@ -256,8 +256,9 @@ Where column_reference_storage_directive is: If specified, the table is created as a temporary table. Temporary tables are automatically dropped at the end of a session, or optionally at the end of the current transaction - (see ON COMMIT below). Existing permanent - tables with the same name are not visible to the current session + (see ON COMMIT below). The default + search_path includes the temporary schema first and so identically + named existing permanent tables are not chosen for new plans while the temporary table exists, unless they are referenced with schema-qualified names. Any indexes created on a temporary table are automatically temporary as well. @@ -372,6 +373,31 @@ Where column_reference_storage_directive is: + + COMPRESSION compression_method + + + The COMPRESSION clause sets the compression method + for the column. Compression is supported only for variable-width data + types, and is used only when the column's storage mode + is main or extended. + (See for information on + column storage modes.) Setting this property for a partitioned table + has no direct effect, because such tables have no storage of their own, + but the configured value will be inherited by newly-created partitions. + The supported compression methods are pglz and + lz4. (lz4 is available only if + was used when building + PostgreSQL.) In addition, + compression_method + can be default to explicitly specify the default + behavior, which is to consult the + setting at the time of + data insertion to determine the method to use. + + + + INHERITS ( parent_table [, ... ] ) @@ -689,6 +715,17 @@ Where column_reference_storage_directive is: + + INCLUDING COMPRESSION + + + Compression method of the columns will be copied. The default + behavior is to exclude compression methods, resulting in columns + having the default compression method. + + + + INCLUDING CONSTRAINTS @@ -933,6 +970,7 @@ Where column_reference_storage_directive is: column. It will have an implicit sequence attached to it and the column in new rows will automatically have values from the sequence assigned to it. + Such a column is implicitly NOT NULL. @@ -971,15 +1009,17 @@ Where column_reference_storage_directive is: UNIQUE (column constraint) UNIQUE ( column_name [, ... ] ) - INCLUDE ( column_name [, ...]) (table constraint) + INCLUDE ( column_name [, ...]) (table constraint) The UNIQUE constraint specifies that a group of one or more columns of a table can contain - only unique values. The behavior of the unique table constraint - is the same as that for column constraints, with the additional - capability to span multiple columns. + only unique values. The behavior of a unique table constraint + is the same as that of a unique column constraint, with the + additional capability to span multiple columns. The constraint + therefore enforces that any two rows must differ in at least one + of these columns. @@ -988,10 +1028,10 @@ Where column_reference_storage_directive is: - Each unique table constraint must name a set of columns that is + Each unique constraint should name a set of columns that is different from the set of columns named by any other unique or - primary key constraint defined for the table. (Otherwise it - would just be the same constraint listed twice.) + primary key constraint defined for the table. (Otherwise, redundant + unique constraints will be discarded.) @@ -1004,11 +1044,16 @@ Where column_reference_storage_directive is: Adding a unique constraint will automatically create a unique btree index on the column or group of columns used in the constraint. - The optional clause INCLUDE adds to that index - one or more columns on which the uniqueness is not enforced. - Note that although the constraint is not enforced on the included columns, - it still depends on them. Consequently, some operations on these columns - (e.g. DROP COLUMN) can cause cascaded constraint and + + + + The optional INCLUDE clause adds to that index + one or more columns that are simply payload: uniqueness + is not enforced on them, and the index cannot be searched on the basis + of those columns. However they can be retrieved by an index-only scan. + Note that although the constraint is not enforced on included columns, + it still depends on them. Consequently, some operations on such columns + (e.g., DROP COLUMN) can cause cascaded constraint and index deletion. @@ -1017,7 +1062,7 @@ Where column_reference_storage_directive is: PRIMARY KEY (column constraint) PRIMARY KEY ( column_name [, ... ] ) - INCLUDE ( column_name [, ...]) (table constraint) + INCLUDE ( column_name [, ...]) (table constraint) The PRIMARY KEY constraint specifies that a column or @@ -1035,27 +1080,34 @@ Where column_reference_storage_directive is: PRIMARY KEY enforces the same data constraints as - a combination of UNIQUE and NOT NULL, but + a combination of UNIQUE and NOT + NULL. However, identifying a set of columns as the primary key also provides metadata about the design of the schema, since a primary key implies that other tables can rely on this set of columns as a unique identifier for rows. - PRIMARY KEY constraints share the restrictions that - UNIQUE constraints have when placed on partitioned - tables. + When placed on a partitioned table, PRIMARY KEY + constraints share the restrictions previously described + for UNIQUE constraints. Adding a PRIMARY KEY constraint will automatically create a unique btree index on the column or group of columns used in the - constraint. The optional INCLUDE clause allows a list - of columns to be specified which will be included in the non-key portion - of the index. Although uniqueness is not enforced on the included columns, - the constraint still depends on them. Consequently, some operations on the - included columns (e.g. DROP COLUMN) can cause cascaded - constraint and index deletion. + constraint. + + + + The optional INCLUDE clause adds to that index + one or more columns that are simply payload: uniqueness + is not enforced on them, and the index cannot be searched on the basis + of those columns. However they can be retrieved by an index-only scan. + Note that although the constraint is not enforced on included columns, + it still depends on them. Consequently, some operations on such columns + (e.g., DROP COLUMN) can cause cascaded constraint and + index deletion. @@ -1246,7 +1298,7 @@ Where column_reference_storage_directive is: constraint that is not deferrable will be checked immediately after every command. Checking of constraints that are deferrable can be postponed until the end of the transaction - (using the command). + (using the SET CONSTRAINTS command). NOT DEFERRABLE is the default. Currently, only UNIQUE, PRIMARY KEY, EXCLUDE, and @@ -1270,7 +1322,7 @@ Where column_reference_storage_directive is: statement. This is the default. If the constraint is INITIALLY DEFERRED, it is checked only at the end of the transaction. The constraint check time can be - altered with the command. + altered with the SET CONSTRAINTS command. @@ -1338,8 +1390,8 @@ Where column_reference_storage_directive is: All rows in the temporary table will be deleted at the end - of each transaction block. Essentially, an automatic is done + of each transaction block. Essentially, an automatic TRUNCATE is done at each commit. When used on a partitioned table, this is not cascaded to its partitions. @@ -1416,8 +1468,8 @@ Where column_reference_storage_directive is: If a table parameter value is set and the equivalent toast. parameter is not, the TOAST table will use the table's parameter value. - Specifying these parameters for partitioned tables is not supported, - but you may specify them for individual leaf partitions. + Except where noted, these parameters are not supported on partitioned + tables; however, you can specify them on individual leaf partitions. @@ -1453,10 +1505,11 @@ Where column_reference_storage_directive is: The toast_tuple_target specifies the minimum tuple length required before - we try to move long column values into TOAST tables, and is also the - target length we try to reduce the length below once toasting begins. - This only affects columns marked as either External or Extended - and applies only to new tuples; there is no effect on existing rows. + we try to compress and/or move long column values into TOAST tables, and + is also the target length we try to reduce the length below once toasting + begins. This affects columns marked as External (for move), + Main (for compression), or Extended (for both) and applies only to new + tuples. There is no effect on existing rows. By default this parameter is set to allow at least 4 tuples per block, which with the default block size will be 2040 bytes. Valid values are between 128 bytes and the (block size - header), by default 8160 bytes. @@ -1498,6 +1551,8 @@ Where column_reference_storage_directive is: If true, the autovacuum daemon will perform automatic VACUUM and/or ANALYZE operations on this table following the rules discussed in . + This parameter can be set for partitioned tables to prevent autovacuum + from running ANALYZE on them. If false, this table will not be autovacuumed, except to prevent transaction ID wraparound. See for more about wraparound prevention. @@ -1512,20 +1567,27 @@ Where column_reference_storage_directive is: - vacuum_index_cleanup, toast.vacuum_index_cleanup (boolean) + vacuum_index_cleanup, toast.vacuum_index_cleanup (enum) vacuum_index_cleanup storage parameter - Enables or disables index cleanup when VACUUM is - run on this table. The default value is true. - Disabling index cleanup can speed up VACUUM very - significantly, but may also lead to severely bloated indexes if table - modifications are frequent. The INDEX_CLEANUP - parameter of , if specified, overrides - the value of this option. + Forces or disables index cleanup when VACUUM + is run on this table. The default value is + AUTO. With OFF, index + cleanup is disabled, with ON it is enabled, + and with AUTO a decision is made dynamically, + each time VACUUM runs. The dynamic behavior + allows VACUUM to avoid needlessly scanning + indexes to remove very few dead tuples. Forcibly disabling all + index cleanup can speed up VACUUM very + significantly, but may also lead to severely bloated indexes if + table modifications are frequent. The + INDEX_CLEANUP parameter of VACUUM, if + specified, overrides the value of this option. @@ -1545,7 +1607,7 @@ Where column_reference_storage_directive is: the truncated pages is returned to the operating system. Note that the truncation requires ACCESS EXCLUSIVE lock on the table. The TRUNCATE parameter - of , if specified, overrides the value + of VACUUM, if specified, overrides the value of this option. @@ -1566,7 +1628,7 @@ Where column_reference_storage_directive is: - + autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (floating point) autovacuum_vacuum_scale_factor @@ -1597,7 +1659,7 @@ Where column_reference_storage_directive is: - autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (float4) + autovacuum_vacuum_insert_scale_factor, toast.autovacuum_vacuum_insert_scale_factor (floating point) autovacuum_vacuum_insert_scale_factor storage parameter @@ -1622,6 +1684,7 @@ Where column_reference_storage_directive is: Per-table value for parameter. + This parameter can be set for partitioned tables. @@ -1637,6 +1700,7 @@ Where column_reference_storage_directive is: Per-table value for parameter. + This parameter can be set for partitioned tables. @@ -1656,7 +1720,7 @@ Where column_reference_storage_directive is: - + autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) autovacuum_vacuum_cost_limit diff --git a/doc/src/sgml/ref/create_table_as.sgml b/doc/src/sgml/ref/create_table_as.sgml index e2ad538cdb69..fc2df51772e9 100644 --- a/doc/src/sgml/ref/create_table_as.sgml +++ b/doc/src/sgml/ref/create_table_as.sgml @@ -64,6 +64,11 @@ where storage_parameter is: defining SELECT statement whenever it is queried. + + + CREATE TABLE AS requires CREATE + privilege on the schema used for the table. + @@ -196,8 +201,8 @@ where storage_parameter is: All rows in the temporary table will be deleted at the end - of each transaction block. Essentially, an automatic is done + of each transaction block. Essentially, an automatic TRUNCATE is done at each commit. @@ -233,9 +238,9 @@ where storage_parameter is: query - A , TABLE, or - command, or an command that runs a + A SELECT, TABLE, or VALUES + command, or an EXECUTE command that runs a prepared SELECT, TABLE, or VALUES query. diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml index 462b8831c274..84fa7ee5e29e 100644 --- a/doc/src/sgml/ref/create_tablespace.sgml +++ b/doc/src/sgml/ref/create_tablespace.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation CREATE TABLESPACE tablespace_name - [ OWNER { new_owner | CURRENT_USER | SESSION_USER } ] + [ OWNER { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ] LOCATION 'directory' [ WITH ( tablespace_option = value [, ... ] ) ] diff --git a/doc/src/sgml/ref/create_transform.sgml b/doc/src/sgml/ref/create_transform.sgml index 5b46c23196db..3f81dc6bba2c 100644 --- a/doc/src/sgml/ref/create_transform.sgml +++ b/doc/src/sgml/ref/create_transform.sgml @@ -147,7 +147,7 @@ CREATE [ OR REPLACE ] TRANSFORM FOR type_name LANGUAG Notes - Use to remove transforms. + Use DROP TRANSFORM to remove transforms. diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml index 6a6c513f1561..8417b8319755 100644 --- a/doc/src/sgml/ref/create_trigger.sgml +++ b/doc/src/sgml/ref/create_trigger.sgml @@ -26,7 +26,7 @@ PostgreSQL documentation -CREATE [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] } +CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] } ON table_name [ FROM referenced_table_name ] [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ] @@ -48,13 +48,21 @@ CREATE [ CONSTRAINT ] TRIGGER name Description - CREATE TRIGGER creates a new trigger. The + CREATE TRIGGER creates a new trigger. + CREATE OR REPLACE TRIGGER will either create a + new trigger, or replace an existing trigger. The trigger will be associated with the specified table, view, or foreign table and will execute the specified function function_name when certain operations are performed on that table. + + To replace the current definition of an existing trigger, use + CREATE OR REPLACE TRIGGER, specifying the existing + trigger's name and parent table. All other properties are replaced. + + The trigger can be specified to fire before the operation is attempted on a row (before constraints are checked and @@ -170,7 +178,7 @@ CREATE [ CONSTRAINT ] TRIGGER name When the CONSTRAINT option is specified, this command creates a constraint trigger. This is the same as a regular trigger except that the timing of the trigger firing can be adjusted using - . + SET CONSTRAINTS. Constraint triggers must be AFTER ROW triggers on plain tables (not foreign tables). They can be fired either at the end of the statement causing the triggering @@ -436,13 +444,24 @@ UPDATE OF column_name1 [, column_name2Notes - To create a trigger on a table, the user must have the + To create or replace a trigger on a table, the user must have the TRIGGER privilege on the table. The user must also have EXECUTE privilege on the trigger function. - Use to remove a trigger. + Use DROP TRIGGER to remove a trigger. + + + + Creating a row-level trigger on a partitioned table will cause an + identical clone trigger to be created on each of its + existing partitions; and any partitions created or attached later will have + an identical trigger, too. If there is a conflictingly-named trigger on a + child partition already, an error occurs unless CREATE OR REPLACE + TRIGGER is used, in which case that trigger is replaced with a + clone trigger. When a partition is detached from its parent, its clone + triggers are removed. @@ -457,12 +476,6 @@ UPDATE OF column_name1 [, column_name2 - - There are a few built-in trigger functions that can be used to - solve common problems without having to write your own trigger code; - see . - - In a BEFORE trigger, the WHEN condition is evaluated just before the function is or would be executed, so using @@ -502,7 +515,7 @@ UPDATE OF column_name1 [, column_name2ON UPDATE CASCADE or ON DELETE SET NULL, are treated as part of the SQL command that caused them (note that such actions are never deferred). Relevant triggers on the affected table will - be fired, so that this provides another way in which a SQL command might + be fired, so that this provides another way in which an SQL command might fire triggers not directly matching its type. In simple cases, triggers that request transition relations will see all changes caused in their table by a single original SQL command as a single transition relation. @@ -528,14 +541,6 @@ UPDATE OF column_name1 [, column_name2 - - Creating a row-level trigger on a partitioned table will cause identical - triggers to be created in all its existing partitions; and any partitions - created or attached later will contain an identical trigger, too. - If the partition is detached from its parent, the trigger is removed. - Triggers on partitioned tables may not be INSTEAD OF. - - Modifying a partitioned table or a table with inheritance children fires statement-level triggers attached to the explicitly named table, but not @@ -546,9 +551,32 @@ UPDATE OF column_name1 [, column_name2REFERENCING clause, then before and after images of rows are visible from all affected partitions or child tables. In the case of inheritance children, the row images include only columns - that are present in the table that the trigger is attached to. Currently, - row-level triggers with transition relations cannot be defined on - partitions or inheritance child tables. + that are present in the table that the trigger is attached to. + + + + Currently, row-level triggers with transition relations cannot be defined + on partitions or inheritance child tables. Also, triggers on partitioned + tables may not be INSTEAD OF. + + + + Currently, the OR REPLACE option is not supported for + constraint triggers. + + + + Replacing an existing trigger within a transaction that has already + performed updating actions on the trigger's table is not recommended. + Trigger firing decisions, or portions of firing decisions, that have + already been made will not be reconsidered, so the effects could be + surprising. + + + + There are a few built-in trigger functions that can be used to + solve common problems without having to write your own trigger code; + see . @@ -566,11 +594,12 @@ CREATE TRIGGER check_update EXECUTE FUNCTION check_account_update(); - The same, but only execute the function if column balance - is specified as a target in the UPDATE command: + Modify that trigger definition to only execute the function if + column balance is specified as a target in + the UPDATE command: -CREATE TRIGGER check_update +CREATE OR REPLACE TRIGGER check_update BEFORE UPDATE OF balance ON accounts FOR EACH ROW EXECUTE FUNCTION check_account_update(); @@ -728,6 +757,7 @@ CREATE TRIGGER paired_items_update CREATE CONSTRAINT TRIGGER is a PostgreSQL extension of the SQL standard. + So is the OR REPLACE option. diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index 33fa3164cb6f..3ea3d661bf80 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -33,6 +33,7 @@ CREATE TYPE name AS RANGE ( [ , COLLATION = collation ] [ , CANONICAL = canonical_function ] [ , SUBTYPE_DIFF = subtype_diff_function ] + [ , MULTIRANGE_TYPE_NAME = multirange_type_name ] ) CREATE TYPE name ( @@ -43,6 +44,7 @@ CREATE TYPE name ( [ , TYPMOD_IN = type_modifier_input_function ] [ , TYPMOD_OUT = type_modifier_output_function ] [ , ANALYZE = analyze_function ] + [ , SUBSCRIPT = subscript_function ] [ , INTERNALLENGTH = { internallength | VARIABLE } ] [ , PASSEDBYVALUE ] [ , ALIGNMENT = alignment ] @@ -124,8 +126,8 @@ CREATE TYPE name must be less than NAMEDATALEN bytes long (64 bytes in a standard PostgreSQL build). (It is possible to create an enumerated type with zero labels, but such a type cannot be used - to hold values before at least one label is added using .) + to hold values before at least one label is added using ALTER TYPE.) @@ -176,6 +178,17 @@ CREATE TYPE name the range type. See for more information. + + + The optional multirange_type_name + parameter specifies the name of the corresponding multirange type. If not + specified, this name is chosen automatically as follows. + If the range type name contains the substring range, then + the multirange type name is formed by replacement of the range + substring with multirange in the range + type name. Otherwise, the multirange type name is formed by appending a + _multirange suffix to the range type name. + @@ -199,8 +212,9 @@ CREATE TYPE name receive_function, send_function, type_modifier_input_function, - type_modifier_output_function and - analyze_function + type_modifier_output_function, + analyze_function, and + subscript_function are optional. Generally these functions have to be coded in C or another low-level language. @@ -321,6 +335,28 @@ CREATE TYPE name in src/include/commands/vacuum.h. + + The optional subscript_function + allows the data type to be subscripted in SQL commands. Specifying this + function does not cause the type to be considered a true + array type; for example, it will not be a candidate for the result type + of ARRAY[] constructs. But if subscripting a value + of the type is a natural notation for extracting data from it, then + a subscript_function can + be written to define what that means. The subscript function must be + declared to take a single argument of type internal, and + return an internal result, which is a pointer to a struct + of methods (functions) that implement subscripting. + The detailed API for subscript functions appears + in src/include/nodes/subscripting.h. + It may also be useful to read the array implementation + in src/backend/utils/adt/arraysubs.c, + or the simpler code + in contrib/hstore/hstore_subs.c. + Additional information appears in + below. + + While the details of the new type's internal representation are only known to the I/O functions and other functions you create to work with @@ -431,11 +467,12 @@ CREATE TYPE name - To indicate that a type is an array, specify the type of the array + To indicate that a type is a fixed-length array type, + specify the type of the array elements using the ELEMENT key word. For example, to define an array of 4-byte integers (int4), specify - ELEMENT = int4. More details about array types - appear below. + ELEMENT = int4. For more details, + see below. @@ -459,7 +496,7 @@ CREATE TYPE name - + Array Types @@ -472,14 +509,16 @@ CREATE TYPE name repeated until a non-colliding name is found.) This implicitly-created array type is variable length and uses the built-in input and output functions array_in and - array_out. The array type tracks any changes in its + array_out. Furthermore, this type is what the system + uses for constructs such as ARRAY[] over the + user-defined type. The array type tracks any changes in its element type's owner or schema, and is dropped if the element type is. You might reasonably ask why there is an option, if the system makes the correct array type automatically. - The only case where it's useful to use is when you are + The main case where it's useful to use is when you are making a fixed-length type that happens to be internally an array of a number of identical things, and you want to allow these things to be accessed directly by subscripting, in addition to whatever operations you plan @@ -488,13 +527,32 @@ CREATE TYPE name using point[0] and point[1]. Note that this facility only works for fixed-length types whose internal form - is exactly a sequence of identical fixed-length fields. A subscriptable - variable-length type must have the generalized internal representation - used by array_in and array_out. + is exactly a sequence of identical fixed-length fields. For historical reasons (i.e., this is clearly wrong but it's far too late to change it), subscripting of fixed-length array types starts from zero, rather than from one as for variable-length arrays. + + + Specifying the option allows a data type to + be subscripted, even though the system does not otherwise regard it as + an array type. The behavior just described for fixed-length arrays is + actually implemented by the handler + function raw_array_subscript_handler, which is + used automatically if you specify for a + fixed-length type without also writing . + + + + When specifying a custom function, it is + not necessary to specify unless + the handler function needs to + consult typelem to find out what to return. + Be aware that specifying causes the system to + assume that the new type contains, or is somehow physically dependent on, + the element type; thus for example changing properties of the element + type won't be allowed if there are any columns of the dependent type. + @@ -587,6 +645,15 @@ CREATE TYPE name + + multirange_type_name + + + The name of the corresponding multirange type. + + + + input_function @@ -657,6 +724,16 @@ CREATE TYPE name + + subscript_function + + + The name of a function that defines what subscripting a value of the + data type does. + + + + internallength @@ -793,7 +870,7 @@ CREATE TYPE name Before PostgreSQL version 8.3, the name of a generated array type was always exactly the element type's name with one underscore character (_) prepended. (Type names were - therefore restricted in length to one less character than other names.) + therefore restricted in length to one fewer character than other names.) While this is still usually the case, the array type name may vary from this in case of maximum-length names or collisions with user type names that begin with underscore. Writing code that depends on this convention diff --git a/doc/src/sgml/ref/create_user.sgml b/doc/src/sgml/ref/create_user.sgml index 2f8881d77c9e..7d1e42c607d2 100644 --- a/doc/src/sgml/ref/create_user.sgml +++ b/doc/src/sgml/ref/create_user.sgml @@ -50,7 +50,7 @@ CREATE USER name [ [ WITH ] CREATE USER is now an alias for - . + CREATE ROLE. The only difference is that when the command is spelled CREATE USER, LOGIN is assumed by default, whereas NOLOGIN is assumed when diff --git a/doc/src/sgml/ref/create_user_mapping.sgml b/doc/src/sgml/ref/create_user_mapping.sgml index 9719a4ff2c0d..55debd54012d 100644 --- a/doc/src/sgml/ref/create_user_mapping.sgml +++ b/doc/src/sgml/ref/create_user_mapping.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -CREATE USER MAPPING [ IF NOT EXISTS ] FOR { user_name | USER | CURRENT_USER | PUBLIC } +CREATE USER MAPPING [ IF NOT EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER server_name [ OPTIONS ( option 'value' [ , ... ] ) ] @@ -67,7 +67,7 @@ CREATE USER MAPPING [ IF NOT EXISTS ] FOR { user_ The name of an existing user that is mapped to foreign server. - CURRENT_USER and USER match the name of + CURRENT_ROLE, CURRENT_USER, and USER match the name of the current user. When PUBLIC is specified, a so-called public mapping is created that is used when no user-specific mapping is applicable. diff --git a/doc/src/sgml/ref/create_view.sgml b/doc/src/sgml/ref/create_view.sgml index eb5591b63c73..4b5b1cf79531 100644 --- a/doc/src/sgml/ref/create_view.sgml +++ b/doc/src/sgml/ref/create_view.sgml @@ -137,8 +137,8 @@ CREATE VIEW [ schema . ] view_namelocal or cascaded, and is equivalent to specifying WITH [ CASCADED | LOCAL ] CHECK OPTION (see below). - This option can be changed on existing views using . + This option can be changed on existing views using ALTER VIEW. @@ -160,8 +160,8 @@ CREATE VIEW [ schema . ] view_namequery - A or - command + A SELECT or + VALUES command which will provide the columns and rows of the view. @@ -245,7 +245,7 @@ CREATE VIEW [ schema . ] view_nameNotes - Use the + Use the DROP VIEW statement to drop views. diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml index d3c92943f071..86473455c9d0 100644 --- a/doc/src/sgml/ref/createdb.sgml +++ b/doc/src/sgml/ref/createdb.sgml @@ -46,7 +46,7 @@ PostgreSQL documentation createdb is a wrapper around the - SQL command . + SQL command CREATE DATABASE. There is no effective difference between creating databases via this utility and via other methods for accessing the server. @@ -197,7 +197,7 @@ PostgreSQL documentation The options , , , , and correspond to options of the underlying - SQL command ; see there for more information + SQL command CREATE DATABASE; see there for more information about them. @@ -284,6 +284,9 @@ PostgreSQL documentation database will be used; if that does not exist (or if it is the name of the new database being created), template1 will be used. + This can be a connection + string. If so, connection string parameters will override any + conflicting command line options. diff --git a/doc/src/sgml/ref/createuser.sgml b/doc/src/sgml/ref/createuser.sgml index 9d24df8b7a88..17579e50afbb 100644 --- a/doc/src/sgml/ref/createuser.sgml +++ b/doc/src/sgml/ref/createuser.sgml @@ -44,12 +44,12 @@ PostgreSQL documentation If you wish to create a new superuser, you must connect as a superuser, not merely with CREATEROLE privilege. Being a superuser implies the ability to bypass all access permission - checks within the database, so superuserdom should not be granted lightly. + checks within the database, so superuser access should not be granted lightly. createuser is a wrapper around the - SQL command . + SQL command CREATE ROLE. There is no effective difference between creating users via this utility and via other methods for accessing the server. diff --git a/doc/src/sgml/ref/declare.sgml b/doc/src/sgml/ref/declare.sgml index 7151cb8765c7..2c61f006de4d 100644 --- a/doc/src/sgml/ref/declare.sgml +++ b/doc/src/sgml/ref/declare.sgml @@ -39,7 +39,7 @@ DECLARE name [ BINARY ] [ INSENSITI can be used to retrieve a small number of rows at a time out of a larger query. After the cursor is created, rows are fetched from it using - . + FETCH. @@ -91,14 +91,25 @@ DECLARE name [ BINARY ] [ INSENSITI + ASENSITIVE INSENSITIVE - Indicates that data retrieved from the cursor should be - unaffected by updates to the table(s) underlying the cursor that occur - after the cursor is created. In PostgreSQL, - this is the default behavior; so this key word has no - effect and is only accepted for compatibility with the SQL standard. + Cursor sensitivity determines whether changes to the data underlying the + cursor, done in the same transaction, after the cursor has been + declared, are visible in the cursor. INSENSITIVE + means they are not visible, ASENSITIVE means the + behavior is implementation-dependent. A third behavior, + SENSITIVE, meaning that such changes are visible in + the cursor, is not available in PostgreSQL. + In PostgreSQL, all cursors are insensitive; + so these key words have no effect and are only accepted for + compatibility with the SQL standard. + + + + Specifying INSENSITIVE together with FOR + UPDATE or FOR SHARE is an error. @@ -148,8 +159,8 @@ DECLARE name [ BINARY ] [ INSENSITI query - A or - command + A SELECT or + VALUES command which will provide the rows to be returned by the cursor. @@ -157,7 +168,7 @@ DECLARE name [ BINARY ] [ INSENSITI - The key words BINARY, + The key words ASENSITIVE, BINARY, INSENSITIVE, and SCROLL can appear in any order. @@ -207,9 +218,9 @@ DECLARE name [ BINARY ] [ INSENSITI PostgreSQL reports an error if such a command is used outside a transaction block. Use - and - - (or ) + BEGIN and + COMMIT + (or ROLLBACK) to define a transaction block. @@ -252,12 +263,14 @@ DECLARE name [ BINARY ] [ INSENSITI - Scrollable and WITH HOLD cursors may give unexpected + Scrollable cursors may give unexpected results if they invoke any volatile functions (see ). When a previously fetched row is re-fetched, the functions might be re-executed, perhaps leading to - results different from the first time. One workaround for such cases - is to declare the cursor WITH HOLD and commit the + results different from the first time. It's best to + specify NO SCROLL for a query involving volatile + functions. If that is not practical, one workaround + is to declare the cursor SCROLL WITH HOLD and commit the transaction before reading any rows from it. This will force the entire output of the cursor to be materialized in temporary storage, so that volatile functions are executed exactly once for each row. @@ -268,12 +281,9 @@ DECLARE name [ BINARY ] [ INSENSITI If the cursor's query includes FOR UPDATE or FOR SHARE, then returned rows are locked at the time they are first fetched, in the same way as for a regular - command with + SELECT command with these options. - In addition, the returned rows will be the most up-to-date versions; - therefore these options provide the equivalent of what the SQL standard - calls a sensitive cursor. (Specifying INSENSITIVE - together with FOR UPDATE or FOR SHARE is an error.) + In addition, the returned rows will be the most up-to-date versions. @@ -302,7 +312,7 @@ DECLARE name [ BINARY ] [ INSENSITI The main reason not to use FOR UPDATE with WHERE CURRENT OF is if you need the cursor to be scrollable, or to be - insensitive to the subsequent updates (that is, continue to show the old + isolated from concurrent updates (that is, continue to show the old data). If this is a requirement, pay close heed to the caveats shown above. @@ -342,20 +352,21 @@ DECLARE liahona CURSOR FOR SELECT * FROM films; Compatibility - - The SQL standard says that it is implementation-dependent whether cursors - are sensitive to concurrent updates of the underlying data by default. In - PostgreSQL, cursors are insensitive by default, - and can be made sensitive by specifying FOR UPDATE. Other - products may work differently. - - The SQL standard allows cursors only in embedded SQL and in modules. PostgreSQL permits cursors to be used interactively. + + According to the SQL standard, changes made to insensitive cursors by + UPDATE ... WHERE CURRENT OF and DELETE + ... WHERE CURRENT OF statements are visible in that same + cursor. PostgreSQL treats these statements like + all other data changing statements in that they are not visible in + insensitive cursors. + + Binary cursors are a PostgreSQL extension. diff --git a/doc/src/sgml/ref/delete.sgml b/doc/src/sgml/ref/delete.sgml index ec3c40df2ea9..1b81b4e7d743 100644 --- a/doc/src/sgml/ref/delete.sgml +++ b/doc/src/sgml/ref/delete.sgml @@ -41,7 +41,7 @@ DELETE FROM [ ONLY ] table_name [ * - provides a + TRUNCATE provides a faster mechanism to remove all rows from a table. diff --git a/doc/src/sgml/ref/drop_group.sgml b/doc/src/sgml/ref/drop_group.sgml index 47d4a72121b6..eb7dc182c82b 100644 --- a/doc/src/sgml/ref/drop_group.sgml +++ b/doc/src/sgml/ref/drop_group.sgml @@ -30,7 +30,7 @@ DROP GROUP [ IF EXISTS ] name [, .. DROP GROUP is now an alias for - . + DROP ROLE. diff --git a/doc/src/sgml/ref/drop_index.sgml b/doc/src/sgml/ref/drop_index.sgml index 0aedd71bd68d..aabc85e23002 100644 --- a/doc/src/sgml/ref/drop_index.sgml +++ b/doc/src/sgml/ref/drop_index.sgml @@ -45,9 +45,10 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] name Drop the index without locking out concurrent selects, inserts, updates, and deletes on the index's table. A normal DROP INDEX - acquires exclusive lock on the table, blocking other accesses until the - index drop can be completed. With this option, the command instead - waits until conflicting transactions have completed. + acquires an ACCESS EXCLUSIVE lock on the table, + blocking other accesses until the index drop can be completed. With + this option, the command instead waits until conflicting transactions + have completed. There are several caveats to be aware of when using this option. @@ -57,6 +58,8 @@ DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] nameDROP INDEX commands can be performed within a transaction block, but DROP INDEX CONCURRENTLY cannot. + Lastly, indexes on partitioned tables cannot be dropped using this + option. For temporary tables, DROP INDEX is always diff --git a/doc/src/sgml/ref/drop_language.sgml b/doc/src/sgml/ref/drop_language.sgml index 4705836ac79e..8ba6621bc4af 100644 --- a/doc/src/sgml/ref/drop_language.sgml +++ b/doc/src/sgml/ref/drop_language.sgml @@ -38,7 +38,7 @@ DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name As of PostgreSQL 9.1, most procedural languages have been made into extensions, and should - therefore be removed with + therefore be removed with DROP EXTENSION not DROP LANGUAGE. diff --git a/doc/src/sgml/ref/drop_operator.sgml b/doc/src/sgml/ref/drop_operator.sgml index 2dff050ecf22..7bcdd082ae70 100644 --- a/doc/src/sgml/ref/drop_operator.sgml +++ b/doc/src/sgml/ref/drop_operator.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , { right_type | NONE } ) [, ...] [ CASCADE | RESTRICT ] +DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ] @@ -73,8 +73,7 @@ DROP OPERATOR [ IF EXISTS ] name ( right_type - The data type of the operator's right operand; write - NONE if the operator has no right operand. + The data type of the operator's right operand. @@ -113,24 +112,17 @@ DROP OPERATOR ^ (integer, integer); - Remove the left unary bitwise complement operator + Remove the bitwise-complement prefix operator ~b for type bit: DROP OPERATOR ~ (none, bit); - - Remove the right unary factorial operator x! - for type bigint: - -DROP OPERATOR ! (bigint, none); - - Remove multiple operators in one command: -DROP OPERATOR ~ (none, bit), ! (bigint, none); +DROP OPERATOR ~ (none, bit), ^ (integer, integer); diff --git a/doc/src/sgml/ref/drop_owned.sgml b/doc/src/sgml/ref/drop_owned.sgml index 09107bef6474..8fa8c414a10e 100644 --- a/doc/src/sgml/ref/drop_owned.sgml +++ b/doc/src/sgml/ref/drop_owned.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -DROP OWNED BY { name | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ] +DROP OWNED BY { name | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ] @@ -90,7 +90,7 @@ DROP OWNED BY { name | CURRENT_USER - The command is an alternative that + The REASSIGN OWNED command is an alternative that reassigns the ownership of all the database objects owned by one or more roles. However, REASSIGN OWNED does not deal with privileges for other objects. diff --git a/doc/src/sgml/ref/drop_policy.sgml b/doc/src/sgml/ref/drop_policy.sgml index 9297ade1133c..d7d3771faea5 100644 --- a/doc/src/sgml/ref/drop_policy.sgml +++ b/doc/src/sgml/ref/drop_policy.sgml @@ -16,7 +16,7 @@ PostgreSQL documentation DROP POLICY - remove a row level security policy from a table + remove a row-level security policy from a table @@ -31,9 +31,9 @@ DROP POLICY [ IF EXISTS ] name ON < DROP POLICY removes the specified policy from the table. Note that if the last policy is removed for a table and the table still has - row level security enabled via ALTER TABLE, then the + row-level security enabled via ALTER TABLE, then the default-deny policy will be used. ALTER TABLE ... DISABLE ROW - LEVEL SECURITY can be used to disable row level security for a + LEVEL SECURITY can be used to disable row-level security for a table, whether policies for the table exist or not. diff --git a/doc/src/sgml/ref/drop_procedure.sgml b/doc/src/sgml/ref/drop_procedure.sgml index 6da266ae2dae..4c86062f3430 100644 --- a/doc/src/sgml/ref/drop_procedure.sgml +++ b/doc/src/sgml/ref/drop_procedure.sgml @@ -30,10 +30,10 @@ DROP PROCEDURE [ IF EXISTS ] name [ Description - DROP PROCEDURE removes the definition of an existing - procedure. To execute this command the user must be the - owner of the procedure. The argument types to the - procedure must be specified, since several different procedures + DROP PROCEDURE removes the definition of one or more + existing procedures. To execute this command the user must be the + owner of the procedure(s). The argument types to the + procedure(s) usually must be specified, since several different procedures can exist with the same name and different argument lists. @@ -56,8 +56,7 @@ DROP PROCEDURE [ IF EXISTS ] name [ name - The name (optionally schema-qualified) of an existing procedure. If no - argument list is specified, the name must be unique in its schema. + The name (optionally schema-qualified) of an existing procedure. @@ -67,8 +66,9 @@ DROP PROCEDURE [ IF EXISTS ] name [ - The mode of an argument: IN or VARIADIC. - If omitted, the default is IN. + The mode of an argument: IN, OUT, + INOUT, or VARIADIC. If omitted, + the default is IN (but see below). @@ -81,7 +81,7 @@ DROP PROCEDURE [ IF EXISTS ] name [ The name of an argument. Note that DROP PROCEDURE does not actually pay any attention to argument names, since only the argument data - types are needed to determine the procedure's identity. + types are used to determine the procedure's identity. @@ -93,6 +93,7 @@ DROP PROCEDURE [ IF EXISTS ] name [ The data type(s) of the procedure's arguments (optionally schema-qualified), if any. + See below for details. @@ -120,12 +121,81 @@ DROP PROCEDURE [ IF EXISTS ] name [ + + Notes + + + If there is only one procedure of the given name, the argument list + can be omitted. Omit the parentheses too in this case. + + + + In PostgreSQL, it's sufficient to list the + input (including INOUT) arguments, + because no two routines of the same name are allowed to share the same + input-argument list. Moreover, the DROP command + will not actually check that you wrote the types + of OUT arguments correctly; so any arguments that + are explicitly marked OUT are just noise. But + writing them is recommendable for consistency with the + corresponding CREATE command. + + + + For compatibility with the SQL standard, it is also allowed to write + all the argument data types (including those of OUT + arguments) without + any argmode markers. + When this is done, the types of the procedure's OUT + argument(s) will be verified against the command. + This provision creates an ambiguity, in that when the argument list + contains no argmode + markers, it's unclear which rule is intended. + The DROP command will attempt the lookup both ways, + and will throw an error if two different procedures are found. + To avoid the risk of such ambiguity, it's recommendable to + write IN markers explicitly rather than letting them + be defaulted, thus forcing the + traditional PostgreSQL interpretation to be + used. + + + + The lookup rules just explained are also used by other commands that + act on existing procedures, such as ALTER PROCEDURE + and COMMENT ON PROCEDURE. + + + Examples + + If there is only one procedure do_db_maintenance, + this command is sufficient to drop it: + +DROP PROCEDURE do_db_maintenance; + + + + + Given this procedure definition: + +CREATE PROCEDURE do_db_maintenance(IN target_schema text, OUT results text) ... + + any one of these commands would work to drop it: -DROP PROCEDURE do_db_maintenance(); +DROP PROCEDURE do_db_maintenance(IN target_schema text, OUT results text); +DROP PROCEDURE do_db_maintenance(IN text, OUT text); +DROP PROCEDURE do_db_maintenance(IN text); +DROP PROCEDURE do_db_maintenance(text); +DROP PROCEDURE do_db_maintenance(text, text); -- potentially ambiguous + However, the last example would be ambiguous if there is also, say, + +CREATE PROCEDURE do_db_maintenance(IN target_schema text, IN options text) ... + + @@ -139,10 +209,11 @@ DROP PROCEDURE do_db_maintenance(); The standard only allows one procedure to be dropped per command. - The IF EXISTS option + The IF EXISTS option is an extension. - The ability to specify argument modes and names + The ability to specify argument modes and names is an + extension, and the lookup rules differ when modes are given. diff --git a/doc/src/sgml/ref/drop_role.sgml b/doc/src/sgml/ref/drop_role.sgml index 13079f3e1f4a..13dc1cc64998 100644 --- a/doc/src/sgml/ref/drop_role.sgml +++ b/doc/src/sgml/ref/drop_role.sgml @@ -40,7 +40,9 @@ DROP ROLE [ IF EXISTS ] name [, ... of the cluster; an error will be raised if so. Before dropping the role, you must drop all the objects it owns (or reassign their ownership) and revoke any privileges the role has been granted on other objects. - The and + The REASSIGN + OWNED and DROP + OWNED commands can be useful for this purpose; see for more discussion. diff --git a/doc/src/sgml/ref/drop_routine.sgml b/doc/src/sgml/ref/drop_routine.sgml index 6c50eb44a199..0a0a140ba0f4 100644 --- a/doc/src/sgml/ref/drop_routine.sgml +++ b/doc/src/sgml/ref/drop_routine.sgml @@ -30,15 +30,44 @@ DROP ROUTINE [ IF EXISTS ] name [ ( Description - DROP ROUTINE removes the definition of an existing - routine, which can be an aggregate function, a normal function, or a - procedure. See + DROP ROUTINE removes the definition of one or more + existing routines. The term routine includes + aggregate functions, normal functions, and procedures. See under , , and for the description of the parameters, more examples, and further details. + + Notes + + + The lookup rules used by DROP ROUTINE are + fundamentally the same as for DROP PROCEDURE; in + particular, DROP ROUTINE shares that command's + behavior of considering an argument list that has + no argmode markers to be + possibly using the SQL standard's definition that OUT + arguments are included in the list. (DROP AGGREGATE + and DROP FUNCTION do not do that.) + + + + In some cases where the same name is shared by routines of different + kinds, it is possible for DROP ROUTINE to fail with + an ambiguity error when a more specific command (DROP + FUNCTION, etc.) would work. Specifying the argument type + list more carefully will also resolve such problems. + + + + These lookup rules are also used by other commands that + act on existing routines, such as ALTER ROUTINE + and COMMENT ON ROUTINE. + + + Examples @@ -64,13 +93,14 @@ DROP ROUTINE foo(integer); The standard only allows one routine to be dropped per command. - The IF EXISTS option + The IF EXISTS option is an extension. - The ability to specify argument modes and names + The ability to specify argument modes and names is an + extension, and the lookup rules differ when modes are given. - Aggregate functions are an extension. + User-definable aggregate functions are an extension. diff --git a/doc/src/sgml/ref/drop_subscription.sgml b/doc/src/sgml/ref/drop_subscription.sgml index adbdeafb4e18..aee961554635 100644 --- a/doc/src/sgml/ref/drop_subscription.sgml +++ b/doc/src/sgml/ref/drop_subscription.sgml @@ -79,7 +79,8 @@ DROP SUBSCRIPTION [ IF EXISTS ] name When dropping a subscription that is associated with a replication slot on the remote host (the normal state), DROP SUBSCRIPTION - will connect to the remote host and try to drop the replication slot as + will connect to the remote host and try to drop the replication slot (and + any remaining table synchronization slots) as part of its operation. This is necessary so that the resources allocated for the subscription on the remote host are released. If this fails, either because the remote host is not reachable or because the remote @@ -89,7 +90,8 @@ DROP SUBSCRIPTION [ IF EXISTS ] nameALTER SUBSCRIPTION ... SET (slot_name = NONE). After that, DROP SUBSCRIPTION will no longer attempt any actions on a remote host. Note that if the remote replication slot still - exists, it should then be dropped manually; otherwise it will continue to + exists, it (and any related table synchronization slots) should then be + dropped manually; otherwise it/they will continue to reserve WAL and might eventually cause the disk to fill up. See also . diff --git a/doc/src/sgml/ref/drop_table.sgml b/doc/src/sgml/ref/drop_table.sgml index bf8996d19858..450458fd2a42 100644 --- a/doc/src/sgml/ref/drop_table.sgml +++ b/doc/src/sgml/ref/drop_table.sgml @@ -32,8 +32,8 @@ DROP TABLE [ IF EXISTS ] name [, .. DROP TABLE removes tables from the database. Only the table owner, the schema owner, and superuser can drop a table. To empty a table of rows - without destroying the table, use - or . + without destroying the table, use DELETE + or TRUNCATE. diff --git a/doc/src/sgml/ref/drop_user.sgml b/doc/src/sgml/ref/drop_user.sgml index 37ab856125d1..74e736b0ebd8 100644 --- a/doc/src/sgml/ref/drop_user.sgml +++ b/doc/src/sgml/ref/drop_user.sgml @@ -30,7 +30,7 @@ DROP USER [ IF EXISTS ] name [, ... DROP USER is simply an alternate spelling of - . + DROP ROLE. diff --git a/doc/src/sgml/ref/drop_user_mapping.sgml b/doc/src/sgml/ref/drop_user_mapping.sgml index 7cb09f1166dd..9e8896a307f7 100644 --- a/doc/src/sgml/ref/drop_user_mapping.sgml +++ b/doc/src/sgml/ref/drop_user_mapping.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -DROP USER MAPPING [ IF EXISTS ] FOR { user_name | USER | CURRENT_USER | PUBLIC } SERVER server_name +DROP USER MAPPING [ IF EXISTS ] FOR { user_name | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER server_name @@ -59,7 +59,7 @@ DROP USER MAPPING [ IF EXISTS ] FOR { user_nameuser_name - User name of the mapping. CURRENT_USER + User name of the mapping. CURRENT_ROLE, CURRENT_USER, and USER match the name of the current user. PUBLIC is used to match all present and future user names in the system. diff --git a/doc/src/sgml/ref/dropdb.sgml b/doc/src/sgml/ref/dropdb.sgml index ded85b0e232d..d36aed38c527 100644 --- a/doc/src/sgml/ref/dropdb.sgml +++ b/doc/src/sgml/ref/dropdb.sgml @@ -41,7 +41,7 @@ PostgreSQL documentation dropdb is a wrapper around the - SQL command . + SQL command DROP DATABASE. There is no effective difference between dropping databases via this utility and via other methods for accessing the server. @@ -217,6 +217,9 @@ PostgreSQL documentation target database. If not specified, the postgres database will be used; if that does not exist (or is the database being dropped), template1 will be used. + This can be a connection + string. If so, connection string parameters will override any + conflicting command line options. diff --git a/doc/src/sgml/ref/dropuser.sgml b/doc/src/sgml/ref/dropuser.sgml index f9aab340d3ba..81580507e826 100644 --- a/doc/src/sgml/ref/dropuser.sgml +++ b/doc/src/sgml/ref/dropuser.sgml @@ -42,7 +42,7 @@ PostgreSQL documentation dropuser is a wrapper around the - SQL command . + SQL command DROP ROLE. There is no effective difference between dropping users via this utility and via other methods for accessing the server. diff --git a/doc/src/sgml/ref/end.sgml b/doc/src/sgml/ref/end.sgml index 8b8f4f0dbb9f..498652919ad8 100644 --- a/doc/src/sgml/ref/end.sgml +++ b/doc/src/sgml/ref/end.sgml @@ -33,7 +33,7 @@ END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] made by the transaction become visible to others and are guaranteed to be durable if a crash occurs. This command is a PostgreSQL extension - that is equivalent to . + that is equivalent to COMMIT. @@ -69,7 +69,7 @@ END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] Notes - Use to + Use ROLLBACK to abort a transaction. @@ -94,8 +94,8 @@ END; END is a PostgreSQL - extension that provides functionality equivalent to , which is + extension that provides functionality equivalent to COMMIT, which is specified in the SQL standard. diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml index 1c19e254dc24..4d758fb237e3 100644 --- a/doc/src/sgml/ref/explain.sgml +++ b/doc/src/sgml/ref/explain.sgml @@ -136,8 +136,10 @@ ROLLBACK; the output column list for each node in the plan tree, schema-qualify table and function names, always label variables in expressions with their range table alias, and always print the name of each trigger for - which statistics are displayed. This parameter defaults to - FALSE. + which statistics are displayed. The query identifier will also be + displayed if one has been computed, see for more details. This parameter + defaults to FALSE. @@ -187,8 +189,7 @@ ROLLBACK; query processing. The number of blocks shown for an upper-level node includes those used by all its child nodes. In text - format, only non-zero values are printed. This parameter may only be - used when ANALYZE is also enabled. It defaults to + format, only non-zero values are printed. It defaults to FALSE. @@ -199,9 +200,9 @@ ROLLBACK; Include information on WAL record generation. Specifically, include the - number of records, number of full page images (fpi) and amount of WAL - bytes generated. In text format, only non-zero values are printed. This - parameter may only be used when ANALYZE is also + number of records, number of full page images (fpi) and the amount of WAL + generated in bytes. In text format, only non-zero values are printed. + This parameter may only be used when ANALYZE is also enabled. It defaults to FALSE. @@ -303,7 +304,7 @@ ROLLBACK; the autovacuum daemon will take care of that automatically. But if a table has recently had substantial changes in its contents, you might need to do a manual - rather than wait for autovacuum to catch up + ANALYZE rather than wait for autovacuum to catch up with the changes. diff --git a/doc/src/sgml/ref/fetch.sgml b/doc/src/sgml/ref/fetch.sgml index e802be61c8c6..ec843f568442 100644 --- a/doc/src/sgml/ref/fetch.sgml +++ b/doc/src/sgml/ref/fetch.sgml @@ -335,9 +335,9 @@ FETCH count - + DECLARE is used to define a cursor. Use - + MOVE to change cursor position without retrieving data. diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index 0cd9b20940ff..3dcadffa087c 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -26,58 +26,71 @@ GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER } ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] ) [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) } ON [ TABLE ] table_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { { USAGE | SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON { SEQUENCE sequence_name [, ...] | ALL SEQUENCES IN SCHEMA schema_name [, ...] } TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } ON DATABASE database_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON DOMAIN domain_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPER fdw_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN SERVER server_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { EXECUTE | ALL [ PRIVILEGES ] } ON { { FUNCTION | PROCEDURE | ROUTINE } routine_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] } TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGE lang_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON LARGE OBJECT loid [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } ON SCHEMA schema_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE tablespace_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT { USAGE | ALL [ PRIVILEGES ] } ON TYPE type_name [, ...] TO role_specification [, ...] [ WITH GRANT OPTION ] + [ GRANTED BY role_specification ] GRANT role_name [, ...] TO role_specification [, ...] [ WITH ADMIN OPTION ] @@ -87,6 +100,7 @@ GRANT role_name [, ...] TO role_name | PUBLIC + | CURRENT_ROLE | CURRENT_USER | SESSION_USER @@ -132,6 +146,12 @@ GRANT role_name [, ...] TO PUBLIC. + + If GRANTED BY is specified, the specified grantor must + be the current user. This clause is currently present in this form only + for SQL compatibility. + + There is no need to grant privileges to the owner of an object (usually the user that created it), @@ -295,7 +315,7 @@ GRANT role_name [, ...] TO Notes - The command is used + The REVOKE command is used to revoke access privileges. @@ -446,9 +466,9 @@ GRANT admins TO joe; The SQL standard allows the GRANTED BY option to - be used in all forms of GRANT. PostgreSQL only - supports it when granting role membership, and even then only superusers - may use it in nontrivial ways. + specify only CURRENT_USER or + CURRENT_ROLE. The other variants are PostgreSQL + extensions. diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml index 7f52209743d9..42a482da8119 100644 --- a/doc/src/sgml/ref/initdb.sgml +++ b/doc/src/sgml/ref/initdb.sgml @@ -86,7 +86,7 @@ PostgreSQL documentation initdb initializes the database cluster's default locale and character set encoding. The character set encoding, collation order (LC_COLLATE) and character set classes - (LC_CTYPE, e.g. upper, lower, digit) can be set separately + (LC_CTYPE, e.g., upper, lower, digit) can be set separately for a database when it is created. initdb determines those settings for the template1 database, which will serve as the default for all other databases. @@ -219,6 +219,7 @@ PostgreSQL documentation failures will be reported in the pg_stat_database view. + See for details. @@ -275,6 +276,19 @@ PostgreSQL documentation + + + + + By default, initdb will write instructions for how + to start the cluster at the end of its output. This option causes + those instructions to be left out. This is primarily intended for use + by tools that wrap initdb in platform specific + behavior, where those instructions are likely to be incorrect. + + + + diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index 0c4688603d9f..4cdfae2279e3 100644 --- a/doc/src/sgml/ref/lock.sgml +++ b/doc/src/sgml/ref/lock.sgml @@ -186,9 +186,9 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] PostgreSQL reports an error if LOCK is used outside a transaction block. Use - and - - (or ) + BEGIN and + COMMIT + (or ROLLBACK) to define a transaction block. diff --git a/doc/src/sgml/ref/pg_amcheck.sgml b/doc/src/sgml/ref/pg_amcheck.sgml new file mode 100644 index 000000000000..46d12110b19f --- /dev/null +++ b/doc/src/sgml/ref/pg_amcheck.sgml @@ -0,0 +1,649 @@ + + + + + pg_amcheck + + + + pg_amcheck + 1 + Application + + + + pg_amcheck + checks for corruption in one or more + PostgreSQL databases + + + + + pg_amcheck + option + dbname + + + + + Description + + + pg_amcheck supports running + 's corruption checking functions against one or + more databases, with options to select which schemas, tables and indexes to + check, which kinds of checking to perform, and whether to perform the checks + in parallel, and if so, the number of parallel connections to establish and + use. + + + + Only table relations and btree indexes are currently supported. Other + relation types are silently skipped. + + + + If dbname is specified, it should be the name of a + single database to check, and no other database selection options should + be present. Otherwise, if any database selection options are present, + all matching databases will be checked. If no such options are present, + the default database will be checked. Database selection options include + , and + . They also include + , , + , , + , and , + but only when such options are used with a three-part pattern + (e.g. ). Finally, they include + and + when such options are used with a two-part pattern + (e.g. ). + + + + dbname can also be a + connection string. + + + + + Options + + + The following command-line options control what is checked: + + + + + + + + Check all databases, except for any excluded via + . + + + + + + + + + + Check databases matching the specified + pattern, + except for any excluded by . + This option can be specified more than once. + + + + + + + + + + Exclude databases matching the given + pattern. + This option can be specified more than once. + + + + + + + + + + Check indexes matching the specified + pattern, + unless they are otherwise excluded. + This option can be specified more than once. + + + This is similar to the option, except that + it applies only to indexes, not tables. + + + + + + + + + + Exclude indexes matching the specified + pattern. + This option can be specified more than once. + + + This is similar to the option, + except that it applies only to indexes, not tables. + + + + + + + + + + Check relations matching the specified + pattern, + unless they are otherwise excluded. + This option can be specified more than once. + + + Patterns may be unqualified, e.g. myrel*, or they + may be schema-qualified, e.g. myschema*.myrel* or + database-qualified and schema-qualified, e.g. + mydb*.myscheam*.myrel*. A database-qualified + pattern will add matching databases to the list of databases to be + checked. + + + + + + + + + + Exclude relations matching the specified + pattern. + This option can be specified more than once. + + + As with , the + pattern may be unqualified, schema-qualified, + or database- and schema-qualified. + + + + + + + + + + Check tables and indexes in schemas matching the specified + pattern, unless they are otherwise excluded. + This option can be specified more than once. + + + To select only tables in schemas matching a particular pattern, + consider using something like + --table=SCHEMAPAT.* --no-dependent-indexes. + To select only indexes, consider using something like + --index=SCHEMAPAT.*. + + + A schema pattern may be database-qualified. For example, you may + write --schema=mydb*.myschema* to select + schemas matching myschema* in databases matching + mydb*. + + + + + + + + + + Exclude tables and indexes in schemas matching the specified + pattern. + This option can be specified more than once. + + + As with , the pattern may be + database-qualified. + + + + + + + + + + Check tables matching the specified + pattern, + unless they are otherwise excluded. + This option can be specified more than once. + + + This is similar to the option, except that + it applies only to tables, not indexes. + + + + + + + + + + Exclude tables matching the specified + pattern. + This option can be specified more than once. + + + This is similar to the option, + except that it applies only to tables, not indexes. + + + + + + + + + By default, if a table is checked, any btree indexes of that table + will also be checked, even if they are not explicitly selected by + an option such as --index or + --relation. This option suppresses that behavior. + + + + + + + + + By default, if a table is checked, its toast table, if any, will also + be checked, even if it is not explicitly selected by an option + such as --table or --relation. + This option suppresses that behavior. + + + + + + + + + By default, if an argument to --database, + --table, --index, + or --relation matches no objects, it is a fatal + error. This option downgrades that error to a warning. + If this option is used with --quiet, the warning + will be suppressed as well. + + + + + + + + The following command-line options control checking of tables: + + + + + + + By default, whenever a toast pointer is encountered in a table, + a lookup is performed to ensure that it references apparently-valid + entries in the toast table. These checks can be quite slow, and this + option can be used to skip them. + + + + + + + + + After reporting all corruptions on the first page of a table where + corruption is found, stop processing that table relation and move on + to the next table or index. + + + Note that index checking always stops after the first corrupt page. + This option only has meaning relative to table relations. + + + + + + + + + If all-frozen is given, table corruption checks + will skip over pages in all tables that are marked as all frozen. + + + If all-visible is given, table corruption checks + will skip over pages in all tables that are marked as all visible. + + + By default, no pages are skipped. This can be specified as + none, but since this is the default, it need not be + mentioned. + + + + + + + + + Start checking at the specified block number. An error will occur if + the table relation being checked has fewer than this number of blocks. + This option does not apply to indexes, and is probably only useful + when checking a single table relation. See --endblock + for further caveats. + + + + + + + + + End checking at the specified block number. An error will occur if the + table relation being checked has fewer than this number of blocks. + This option does not apply to indexes, and is probably only useful when + checking a single table relation. If both a regular table and a toast + table are checked, this option will apply to both, but higher-numbered + toast blocks may still be accessed while validating toast pointers, + unless that is suppressed using + . + + + + + + + + The following command-line options control checking of B-tree indexes: + + + + + + + For each index checked, verify the presence of all heap tuples as index + tuples in the index using 's + option. + + + + + + + + + For each btree index checked, use 's + bt_index_parent_check function, which performs + additional checks of parent/child relationships during index checking. + + + The default is to use amcheck's + bt_index_check function, but note that use of the + option implicitly selects + bt_index_parent_check. + + + + + + + + + For each index checked, re-find tuples on the leaf level by performing a + new search from the root page for each tuple using + 's option. + + + Use of this option implicitly also selects the + option. + + + This form of verification was originally written to help in the + development of btree index features. It may be of limited use or even + of no use in helping detect the kinds of corruption that occur in + practice. It may also cause corruption checking to take considerably + longer and consume considerably more resources on the server. + + + + + + + + The following command-line options control the connection to the server: + + + + + + + + Specifies the host name of the machine on which the server is running. + If the value begins with a slash, it is used as the directory for the + Unix domain socket. + + + + + + + + + + Specifies the TCP port or local Unix domain socket file extension on + which the server is listening for connections. + + + + + + + + + + User name to connect as. + + + + + + + + + + Never issue a password prompt. If the server requires password + authentication and a password is not available by other means such as + a .pgpass file, the connection attempt will fail. + This option can be useful in batch jobs and scripts where no user is + present to enter a password. + + + + + + + + + + Force pg_amcheck to prompt for a password + before connecting to a database. + + + This option is never essential, since + pg_amcheck will automatically prompt for a + password if the server demands password authentication. However, + pg_amcheck will waste a connection attempt + finding out that the server wants a password. In some cases it is + worth typing to avoid the extra connection attempt. + + + + + + + + + Specifies a database or + connection string to be + used to discover the list of databases to be checked. If neither + nor any option including a database pattern is + used, no such connection is required and this option does nothing. + Otherwise, any connection string parameters other than + the database name which are included in the value for this option + will also be used when connecting to the databases + being checked. If this option is omitted, the default is + postgres or, if that fails, + template1. + + + + + + + + Other options are also available: + + + + + + + + Echo to stdout all SQL sent to the server. + + + + + + + + + + Use num concurrent connections to the server, + or one per object to be checked, whichever is less. + + + The default is to use a single connection. + + + + + + + + + + Print fewer messages, and less detail regarding any server errors. + + + + + + + + + + Show progress information. Progress information includes the number + of relations for which checking has been completed, and the total + size of those relations. It also includes the total number of relations + that will eventually be checked, and the estimated size of those + relations. + + + + + + + + + + Print more messages. In particular, this will print a message for + each relation being checked, and will increase the level of detail + shown for server errors. + + + + + + + + + + Print the pg_amcheck version and exit. + + + + + + + + + + Install any missing extensions that are required to check the + database(s). If not yet installed, each extension's objects will be + installed into the given + schema, or if not specified + into schema pg_catalog. + + + At present, the only required extension is . + + + + + + + + + + Show help about pg_amcheck command line + arguments, and exit. + + + + + + + + + Notes + + + pg_amcheck is designed to work with + PostgreSQL 14.0 and later. + + + + + See Also + + + + + + diff --git a/doc/src/sgml/ref/pg_basebackup.sgml b/doc/src/sgml/ref/pg_basebackup.sgml index aa0b27c9f300..9e6807b4574d 100644 --- a/doc/src/sgml/ref/pg_basebackup.sgml +++ b/doc/src/sgml/ref/pg_basebackup.sgml @@ -83,8 +83,14 @@ PostgreSQL documentation - If you are using -X none, there is no guarantee that all - WAL files required for the backup are archived at the end of backup. + pg_basebackup cannot force the standby + to switch to a new WAL file at the end of backup. + When you are using -X none, if write activity on + the primary is low, pg_basebackup may + need to wait a long time for the last WAL file required for the backup + to be switched and archived. In this case, it may be useful to run + pg_switch_wal on the primary in order to + trigger an immediate WAL file switch. @@ -161,6 +167,7 @@ PostgreSQL documentation tablespaces, the main data directory will be placed in the target directory, but all other tablespaces will be placed in the same absolute path as they have on the source server. + (See to change that.) This is the default format. @@ -198,7 +205,10 @@ PostgreSQL documentation - Creates a standby.signal file and appends + Creates a + standby.signal + standby.signalpg_basebackup --write-recovery-conf + file and appends connection settings to the postgresql.auto.conf file in the target directory (or within the base archive file when using tar format). This eases setting up a standby server using the @@ -241,7 +251,12 @@ PostgreSQL documentation the main data directory are updated to point to the new location. So the new data directory is ready to be used for a new server instance with all tablespaces in the updated locations. - + + + + Currently, this option only works with plain output format; it is + ignored if tar format is selected. + @@ -368,7 +383,7 @@ PostgreSQL documentation The following command-line options control the generation of the - backup and the running of the program: + backup and the invocation of the program: @@ -540,7 +555,7 @@ PostgreSQL documentation of each file for users who wish to verify that the backup has not been tampered with, while the CRC32C algorithm provides a checksum that is much faster to calculate; it is good at catching errors due to accidental - changes but is not resistant to targeted modifications. Note that, to + changes but is not resistant to malicious modifications. Note that, to be useful against an adversary who has access to the backup, the backup manifest would need to be stored securely elsewhere or otherwise verified not to have been modified since the backup was taken. @@ -653,8 +668,9 @@ PostgreSQL documentation - Specifies parameters used to connect to the server, as a connection - string. See for more information. + Specifies parameters used to connect to the server, as a connection string; these + will override any conflicting command line options. The option is called --dbname for consistency with other @@ -903,6 +919,7 @@ PostgreSQL documentation + diff --git a/doc/src/sgml/ref/pg_checksums.sgml b/doc/src/sgml/ref/pg_checksums.sgml index 8e7807f86bd9..c84bc5c5b23d 100644 --- a/doc/src/sgml/ref/pg_checksums.sgml +++ b/doc/src/sgml/ref/pg_checksums.sgml @@ -28,7 +28,7 @@ PostgreSQL documentation - datadir + datadir @@ -47,8 +47,8 @@ PostgreSQL documentation When verifying checksums, every file in the cluster is scanned. When - enabling checksums, every file in the cluster is rewritten. Disabling - checksums only updates the file pg_control. + enabling checksums, every file in the cluster is rewritten in-place. + Disabling checksums only updates the file pg_control. diff --git a/doc/src/sgml/ref/pg_controldata.sgml b/doc/src/sgml/ref/pg_controldata.sgml index 4aae8b193dea..b47fdca9dfcb 100644 --- a/doc/src/sgml/ref/pg_controldata.sgml +++ b/doc/src/sgml/ref/pg_controldata.sgml @@ -25,10 +25,10 @@ PostgreSQL documentation option - + - datadir + datadir diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index fa1c2cd56f46..6780933d88aa 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -176,8 +176,8 @@ PostgreSQL documentation - This option is only meaningful for the plain-text format. For - the archive formats, you can specify the option when you + This option is ignored when emitting an archive (non-text) output + file. For the archive formats, you can specify the option when you call pg_restore. @@ -208,13 +208,51 @@ PostgreSQL documentation - This option is only meaningful for the plain-text format. For - the archive formats, you can specify the option when you + This option is ignored when emitting an archive (non-text) output + file. For the archive formats, you can specify the option when you call pg_restore. + + + + + + Dump only extensions matching pattern. When this option is not + specified, all non-system extensions in the target database will be + dumped. Multiple extensions can be selected by writing multiple + switches. The pattern parameter is interpreted as a + pattern according to the same rules used by + psql's \d commands (see + ), so multiple extensions can also + be selected by writing wildcard characters in the pattern. When using + wildcards, be careful to quote the pattern if needed to prevent the + shell from expanding the wildcards. + + + + Any configuration relation registered by + pg_extension_config_dump is included in the + dump if its extension is specified by . + + + + + When is specified, + pg_dump makes no attempt to dump any other + database objects that the selected extension(s) might depend upon. + Therefore, there is no guarantee that the results of a + specific-extension dump can be successfully restored by themselves + into a clean database. + + + + + @@ -322,7 +360,7 @@ PostgreSQL documentation Run the dump in parallel by dumping njobs - tables simultaneously. This option reduces the time of the dump but it also + tables simultaneously. This option may reduce the time needed to perform the dump but it also increases the load on the database server. You can only use this option with the directory output format because this is the only output format where multiple processes can write their data at the same time. @@ -456,8 +494,8 @@ PostgreSQL documentation - This option is only meaningful for the plain-text format. For - the archive formats, you can specify the option when you + This option is ignored when emitting an archive (non-text) output + file. For the archive formats, you can specify the option when you call pg_restore. @@ -517,9 +555,7 @@ PostgreSQL documentation Dump only tables with names matching - pattern. - For this purpose, table includes views, materialized views, - sequences, and foreign tables. Multiple tables + pattern. Multiple tables can be selected by writing multiple switches. The pattern parameter is interpreted as a pattern according to the same rules used by @@ -531,6 +567,14 @@ PostgreSQL documentation below. + + As well as tables, this option can be used to dump the definition of matching + views, materialized views, foreign tables, and sequences. It will not dump the + contents of views or materialized views, and the contents of foreign tables will + only be dumped if the corresponding foreign server is specified with + . + + The and switches have no effect when is used, because tables selected by will @@ -548,18 +592,6 @@ PostgreSQL documentation - - - The behavior of the switch is not entirely upward - compatible with pre-8.2 PostgreSQL - versions. Formerly, writing -t tab would dump all - tables named tab, but now it just dumps whichever one - is visible in your default search path. To get the old behavior - you can write -t '*.tab'. Also, you must write something - like -t sch.tab to select a table in a particular schema, - rather than the old locution of -n sch -t tab. - - @@ -594,6 +626,8 @@ PostgreSQL documentation pg_dump to output detailed object comments and start/stop times to the dump file, and progress messages to standard error. + Repeating the option causes additional debug-level messages + to appear on standard error. @@ -625,7 +659,7 @@ PostgreSQL documentation Specify the compression level to use. Zero means no compression. - For the custom archive format, this specifies compression of + For the custom and directory archive formats, this specifies compression of individual table-data segments, and the default is to compress at a moderate level. For plain text output, setting a nonzero compression level causes @@ -697,8 +731,8 @@ PostgreSQL documentation - This option is only meaningful for the plain-text format. For - the archive formats, you can specify the option when you + This option is ignored when emitting an archive (non-text) output + file. For the archive formats, you can specify the option when you call pg_restore. @@ -759,7 +793,7 @@ PostgreSQL documentation - Use conditional commands (i.e. add an IF EXISTS + Use conditional commands (i.e., add an IF EXISTS clause) when cleaning database objects. This option is not valid unless is also specified. @@ -928,13 +962,25 @@ PostgreSQL documentation - This option is only meaningful for the plain-text format. For - the archive formats, you can specify the option when you + This option is ignored when emitting an archive (non-text) output + file. For the archive formats, you can specify the option when you call pg_restore. + + + + + Do not output commands to set TOAST compression + methods. + With this option, all columns will be restored with the default + compression setting. + + + + @@ -1071,11 +1117,12 @@ PostgreSQL documentation - Require that each schema - (/) and table - (/) qualifier match at - least one schema/table in the database to be dumped. Note that if - none of the schema/table qualifiers find + Require that each + extension (/), + schema (/) and + table (/) qualifier + match at least one extension/schema/table in the database to be dumped. + Note that if none of the extension/schema/table qualifiers find matches, pg_dump will generate an error even without . @@ -1130,14 +1177,10 @@ PostgreSQL documentation Specifies the name of the database to connect to. This is equivalent to specifying dbname as the first non-option - argument on the command line. - - - If this parameter contains an = sign or starts - with a valid URI prefix - (postgresql:// - or postgres://), it is treated as a - conninfo string. See for more information. + argument on the command line. The dbname + can be a connection string. + If so, connection string parameters will override any conflicting + command line options. @@ -1376,7 +1419,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; Examples - To dump a database called mydb into a SQL-script file: + To dump a database called mydb into an SQL-script file: $ pg_dump mydb > db.sql diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index 79b3175b8076..1181e182b1a6 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -237,7 +237,9 @@ PostgreSQL documentation Specifies verbose mode. This will cause pg_dumpall to output start/stop times to the dump file, and progress messages to standard error. - It will also enable verbose output in pg_dump. + Repeating the option causes additional debug-level messages + to appear on standard error. + The option is also passed down to pg_dump. @@ -356,7 +358,7 @@ PostgreSQL documentation - Use conditional commands (i.e. add an IF EXISTS + Use conditional commands (i.e., add an IF EXISTS clause) to drop databases and other objects. This option is not valid unless is also specified. @@ -408,10 +410,7 @@ PostgreSQL documentation the dump. Instead, fail if unable to lock a table within the specified timeout. The timeout may be specified in any of the formats accepted by SET - statement_timeout. Allowed values vary depending on the server - version you are dumping from, but an integer number of milliseconds - is accepted by all versions since 7.3. This option is ignored when - dumping from a pre-7.3 server. + statement_timeout. @@ -494,6 +493,18 @@ PostgreSQL documentation + + + + + Do not output commands to set TOAST compression + methods. + With this option, all columns will be restored with the default + compression setting. + + + + @@ -585,8 +596,9 @@ PostgreSQL documentation - Specifies parameters used to connect to the server, as a connection - string. See for more information. + Specifies parameters used to connect to the server, as a connection string; these + will override any conflicting command line options. The option is called --dbname for consistency with other diff --git a/doc/src/sgml/ref/pg_isready.sgml b/doc/src/sgml/ref/pg_isready.sgml index 3d5b551b87f2..ba25ca65a40e 100644 --- a/doc/src/sgml/ref/pg_isready.sgml +++ b/doc/src/sgml/ref/pg_isready.sgml @@ -47,15 +47,11 @@ PostgreSQL documentation - Specifies the name of the database to connect to. - - - If this parameter contains an = sign or starts - with a valid URI prefix - (postgresql:// - or postgres://), it is treated as a - conninfo string. See for more information. + Specifies the name of the database to connect to. The + dbname can be a connection string. If so, + connection string parameters will override any conflicting command + line options. diff --git a/doc/src/sgml/ref/pg_receivewal.sgml b/doc/src/sgml/ref/pg_receivewal.sgml index 865ec8426219..45b544cf498e 100644 --- a/doc/src/sgml/ref/pg_receivewal.sgml +++ b/doc/src/sgml/ref/pg_receivewal.sgml @@ -252,8 +252,9 @@ PostgreSQL documentation - Specifies parameters used to connect to the server, as a connection - string. See for more information. + Specifies parameters used to connect to the server, as a connection string; these + will override any conflicting command line options. The option is called --dbname for consistency with other diff --git a/doc/src/sgml/ref/pg_recvlogical.sgml b/doc/src/sgml/ref/pg_recvlogical.sgml index 41508fdc1e56..6b1d98d06ef1 100644 --- a/doc/src/sgml/ref/pg_recvlogical.sgml +++ b/doc/src/sgml/ref/pg_recvlogical.sgml @@ -273,14 +273,16 @@ PostgreSQL documentation - - + + - The database to connect to. See the description of the actions for - what this means in detail. This can be a libpq connection string; - see for more information. Defaults - to user name. + The database to connect to. See the description + of the actions for what this means in detail. + The dbname can be a connection string. If so, + connection string parameters will override any conflicting + command line options. Defaults to the user name. diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml index 9cbbe756814d..3e4882cdc65d 100644 --- a/doc/src/sgml/ref/pg_resetwal.sgml +++ b/doc/src/sgml/ref/pg_resetwal.sgml @@ -23,20 +23,20 @@ PostgreSQL documentation pg_resetwal - + - + option - + - datadir + datadir diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index b942cb238b1b..35cd56297c87 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -156,7 +156,10 @@ PostgreSQL documentation Connect to database dbname and restore directly - into the database. + into the database. The dbname can + be a connection string. + If so, connection string parameters will override any conflicting + command line options. @@ -483,7 +486,12 @@ PostgreSQL documentation - Specifies verbose mode. + Specifies verbose mode. This will cause + pg_restore to output detailed object + comments and start/stop times to the output file, and progress + messages to standard error. + Repeating the option causes additional debug-level messages + to appear on standard error. @@ -572,7 +580,7 @@ PostgreSQL documentation - Use conditional commands (i.e. add an IF EXISTS + Use conditional commands (i.e., add an IF EXISTS clause) to drop database objects. This option is not valid unless is also specified. @@ -914,8 +922,10 @@ CREATE DATABASE foo WITH TEMPLATE template0; Once restored, it is wise to run ANALYZE on each - restored table so the optimizer has useful statistics; see - and + restored table so the optimizer has useful statistics. + If the table is a partition or an inheritance child, it may also be useful + to analyze the parent to update statistics for the table hierarchy. + See and for more information. diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index 440eed7d4b71..33e6bb64ad61 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -25,7 +25,7 @@ PostgreSQL documentation option - + directory @@ -73,8 +73,8 @@ PostgreSQL documentation from the WAL archive to the pg_wal directory, or run pg_rewind with the -c option to automatically retrieve them from the WAL archive. The use of - pg_rewind is not limited to failover, e.g. a standby - server can be promoted, run some write transactions, and then rewinded + pg_rewind is not limited to failover, e.g., a standby + server can be promoted, run some write transactions, and then rewound to become a standby again. @@ -173,7 +173,7 @@ PostgreSQL documentation with a role having sufficient permissions to execute the functions used by pg_rewind on the source server (see Notes section for details) or a superuser role. This option - requires the source server to be running and not in recovery mode. + requires the source server to be running and accepting connections. @@ -211,7 +211,7 @@ PostgreSQL documentation pg_rewind to return without waiting, which is faster, but means that a subsequent operating system crash can leave the synchronized data directory corrupt. Generally, this option is - useful for testing but should not be used when creating a production + useful for testing but should not be used on a production installation. @@ -322,7 +322,7 @@ GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, b When executing pg_rewind using an online cluster as source which has been recently promoted, it is necessary - to execute a CHECKPOINT after promotion so as its + to execute a CHECKPOINT after promotion such that its control file reflects up-to-date timeline information, which is used by pg_rewind to check if the target cluster can be rewound using the designated source cluster. diff --git a/doc/src/sgml/ref/pg_verifybackup.sgml b/doc/src/sgml/ref/pg_verifybackup.sgml index c160992e6d7d..5f83c987063d 100644 --- a/doc/src/sgml/ref/pg_verifybackup.sgml +++ b/doc/src/sgml/ref/pg_verifybackup.sgml @@ -40,7 +40,7 @@ PostgreSQL documentation It is important to note that the validation which is performed by - pg_verifybackup does not and can not include + pg_verifybackup does not and cannot include every check which will be performed by a running server when attempting to make use of the backup. Even if you use this tool, you should still perform test restores and verify that the resulting databases work as @@ -82,8 +82,8 @@ PostgreSQL documentation for any files for which the computed checksum does not match the checksum stored in the manifest. This step is not performed for any files which produced errors in the previous step, since they are already known - to have problems. Also, files which were ignored in the previous step are - also ignored in this step. + to have problems. Files which were ignored in the previous step are also + ignored in this step. @@ -121,7 +121,8 @@ PostgreSQL documentation Options - The following command-line options control the behavior. + pg_verifybackup accepts the following + command-line arguments: diff --git a/doc/src/sgml/ref/pgarchivecleanup.sgml b/doc/src/sgml/ref/pgarchivecleanup.sgml index 56f02fc0e62e..e27db3c07737 100644 --- a/doc/src/sgml/ref/pgarchivecleanup.sgml +++ b/doc/src/sgml/ref/pgarchivecleanup.sgml @@ -205,11 +205,4 @@ archive_cleanup_command = 'pg_archivecleanup -d /mnt/standby/archive %r 2>>clean - - See Also - - - - - diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index 9f3bb5fce65c..0c60077e1f9b 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -58,8 +58,10 @@ number of clients: 10 number of threads: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 -tps = 85.184871 (including connections establishing) -tps = 85.296346 (excluding connections establishing) +latency average = 11.013 ms +latency stddev = 7.351 ms +initial connection time = 45.758 ms +tps = 896.967014 (without initial connection time) The first six lines report some of the most important parameter @@ -68,8 +70,7 @@ tps = 85.296346 (excluding connections establishing) and number of transactions per client); these will be equal unless the run failed before completion. (In mode, only the actual number of transactions is printed.) - The last two lines report the number of transactions per second, - figured with and without counting the time to start database sessions. + The last line reports the number of transactions per second. @@ -151,6 +152,18 @@ pgbench options d + + dbname + + + Specifies the name of the database to test in. If this is + not specified, the environment variable + PGDATABASE is used. If that is not set, the + user name specified for the connection is used. + + + + @@ -396,15 +409,19 @@ pgbench options d =scriptname[@weight] - Add the specified built-in script to the list of executed scripts. - An optional integer weight after @ allows to adjust the - probability of drawing the script. If not specified, it is set to 1. + Add the specified built-in script to the list of scripts to be executed. Available built-in scripts are: tpcb-like, simple-update and select-only. Unambiguous prefixes of built-in names are accepted. - With special name list, show the list of built-in scripts + With the special name list, show the list of built-in scripts and exit immediately. + + Optionally, write an integer weight after @ to + adjust the probability of selecting this script versus other ones. + The default weight is 1. + See below for details. + @@ -457,10 +474,16 @@ pgbench options d filename[@weight] - Add a transaction script read from filename to - the list of executed scripts. - An optional integer weight after @ allows to adjust the - probability of drawing the test. + Add a transaction script read from filename + to the list of scripts to be executed. + + + Optionally, write an integer weight after @ to + adjust the probability of selecting this script versus other ones. + The default weight is 1. + (To use a script file name that includes an @ + character, append a weight so that there is no ambiguity, for + example filen@me@1.) See below for details. @@ -617,7 +640,7 @@ pgbench options d transaction to finish. The wait time is called the schedule lag time, and its average and maximum are also reported separately. The transaction latency with respect to the actual transaction start time, - i.e. the time spent executing the transaction in the database, can be + i.e., the time spent executing the transaction in the database, can be computed by subtracting the schedule lag time from the reported latency. @@ -767,7 +790,7 @@ pgbench options d client per thread and there are no external or data dependencies. From a statistical viewpoint reproducing runs exactly is a bad idea because it can hide the performance variability or improve performance unduly, - e.g. by hitting the same pages as a previous run. + e.g., by hitting the same pages as a previous run. However, it may also be of great help for debugging, for instance re-running a tricky case which leads to an error. Use wisely. @@ -787,7 +810,7 @@ pgbench options d Remember to take the sampling rate into account when processing the log file. For example, when computing TPS values, you need to multiply - the numbers accordingly (e.g. with 0.01 sample rate, you'll only get + the numbers accordingly (e.g., with 0.01 sample rate, you'll only get 1/100 of the actual TPS). @@ -812,8 +835,8 @@ pgbench options d Common Options - pgbench accepts the following command-line - common arguments: + pgbench also accepts the following common command-line + arguments for connection parameters: @@ -890,6 +913,7 @@ pgbench options d + PGDATABASE PGHOST PGPORT PGUSER @@ -925,10 +949,10 @@ pgbench options d pgbench executes test scripts chosen randomly from a specified list. - They include built-in scripts with and - user-provided custom scripts with . - Each script may be given a relative weight specified after a - @ so as to change its drawing probability. + The scripts may include built-in scripts specified with + and user-provided scripts specified with . + Each script may be given a relative weight specified after an + @ so as to change its selection probability. The default weight is 1. Scripts with a weight of 0 are ignored. @@ -988,7 +1012,7 @@ pgbench options d Before PostgreSQL 9.6, SQL commands in script files were terminated by newlines, and so they could not be continued across lines. Now a semicolon is required to separate consecutive - SQL commands (though a SQL command does not need one if it is followed + SQL commands (though an SQL command does not need one if it is followed by a meta command). If you need to create a script file that works with both old and new versions of pgbench, be sure to write each SQL command on a single line ending with a semicolon. @@ -998,7 +1022,7 @@ pgbench options d There is a simple variable-substitution facility for script files. Variable names must consist of letters (including non-Latin letters), - digits, and underscores. + digits, and underscores, with the first character not being a digit. Variables can be set by the command-line option, explained above, or by the meta commands explained below. In addition to any variables preset by command-line options, @@ -1006,7 +1030,7 @@ pgbench options d . A value specified for these variables using takes precedence over the automatic presets. Once set, a variable's - value can be inserted into a SQL command by writing + value can be inserted into an SQL command by writing :variablename. When running more than one client session, each session has its own set of variables. pgbench supports up to 255 variable uses in one @@ -1033,7 +1057,7 @@ pgbench options d default_seed - seed used in hash functions by default + seed used in hash and pseudorandom permutation functions by default @@ -1086,6 +1110,12 @@ pgbench options d row, the last value is kept. + + \gset and \aset cannot be used in + pipeline mode, since the query results are not yet available by the time + the commands would need them. + + The following example puts the final account balance from the first query into variable abalance, and fills variables @@ -1246,6 +1276,22 @@ SELECT 4 AS four \; SELECT 5 AS five \aset + + + \startpipeline + \endpipeline + + + + These commands delimit the start and end of a pipeline of SQL + statements. In pipeline mode, statements are sent to the server + without waiting for the results of previous statements. See + for more details. + Pipeline mode requires the use of extended query protocol. + + + + @@ -1818,6 +1864,24 @@ SELECT 4 AS four \; SELECT 5 AS five \aset + + + permute ( i, size [, seed ] ) + integer + + + Permuted value of i, in the range + [0, size). This is the new position of + i (modulo size) in a + pseudorandom permutation of the integers 0...size-1, + parameterized by seed, see below. + + + permute(0, 4) + an integer between 0 and 3 + + + pi () @@ -1991,7 +2055,7 @@ f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) / 2.0 / parameter, that is a relative 1.0 / parameter around the mean; for instance, if parameter is 4.0, 67% of values are drawn from the - middle quarter (1.0 / 4.0) of the interval (i.e. from + middle quarter (1.0 / 4.0) of the interval (i.e., from 3.0 / 8.0 to 5.0 / 8.0) and 95% from the middle half (2.0 / 4.0) of the interval (second and third quartiles). The minimum allowed parameter @@ -2025,29 +2089,70 @@ f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) / + + + When designing a benchmark which selects rows non-uniformly, be aware + that the rows chosen may be correlated with other data such as IDs from + a sequence or the physical row ordering, which may skew performance + measurements. + + + To avoid this, you may wish to use the permute + function, or some other additional step with similar effect, to shuffle + the selected rows and remove such correlations. + + + Hash functions hash, hash_murmur2 and hash_fnv1a accept an input value and an optional seed parameter. In case the seed isn't provided the value of :default_seed is used, which is initialized randomly unless set by the command-line - -D option. Hash functions can be used to scatter the - distribution of random functions such as random_zipfian or - random_exponential. For instance, the following pgbench - script simulates possible real world workload typical for social media and - blogging platforms where few accounts generate excessive load: + -D option. + + + + permute accepts an input value, a size, and an optional + seed parameter. It generates a pseudorandom permutation of integers in + the range [0, size), and returns the index of the input + value in the permuted values. The permutation chosen is parameterized by + the seed, which defaults to :default_seed, if not + specified. Unlike the hash functions, permute ensures + that there are no collisions or holes in the output values. Input values + outside the interval are interpreted modulo the size. The function raises + an error if the size is not positive. permute can be + used to scatter the distribution of non-uniform random functions such as + random_zipfian or random_exponential + so that values drawn more often are not trivially correlated. For + instance, the following pgbench script + simulates a possible real world workload typical for social media and + blogging platforms where a few accounts generate excessive load: -\set r random_zipfian(0, 100000000, 1.07) -\set k abs(hash(:r)) % 1000000 +\set size 1000000 +\set r random_zipfian(1, :size, 1.07) +\set k 1 + permute(:r, :size) In some cases several distinct distributions are needed which don't correlate - with each other and this is when implicit seed parameter comes in handy: + with each other and this is when the optional seed parameter comes in handy: -\set k1 abs(hash(:r, :default_seed + 123)) % 1000000 -\set k2 abs(hash(:r, :default_seed + 321)) % 1000000 +\set k1 1 + permute(:r, :size, :default_seed + 123) +\set k2 1 + permute(:r, :size, :default_seed + 321) + + A similar behavior can also be approximated with hash: + + +\set size 1000000 +\set r random_zipfian(1, 100 * :size, 1.07) +\set k 1 + abs(hash(:r)) % :size + + + However, since hash generates collisions, some values + will not be reachable and others will be more frequent than expected from + the original distribution. @@ -2186,7 +2291,7 @@ END; and max_lag, are only present if the option is used. They provide statistics about the time each transaction had to wait for the - previous one to finish, i.e. the difference between each transaction's + previous one to finish, i.e., the difference between each transaction's scheduled start time and the time it actually started. The very last field, skipped, is only present if the option is used, too. @@ -2234,22 +2339,22 @@ number of clients: 10 number of threads: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 -latency average = 15.844 ms -latency stddev = 2.715 ms -tps = 618.764555 (including connections establishing) -tps = 622.977698 (excluding connections establishing) +latency average = 10.870 ms +latency stddev = 7.341 ms +initial connection time = 30.954 ms +tps = 907.949122 (without initial connection time) statement latencies in milliseconds: - 0.002 \set aid random(1, 100000 * :scale) - 0.005 \set bid random(1, 1 * :scale) - 0.002 \set tid random(1, 10 * :scale) - 0.001 \set delta random(-5000, 5000) - 0.326 BEGIN; - 0.603 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; - 0.454 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; - 5.528 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; - 7.335 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; - 0.371 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); - 1.212 END; + 0.001 \set aid random(1, 100000 * :scale) + 0.001 \set bid random(1, 1 * :scale) + 0.001 \set tid random(1, 10 * :scale) + 0.000 \set delta random(-5000, 5000) + 0.046 BEGIN; + 0.151 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; + 0.107 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; + 4.241 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; + 5.245 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; + 0.102 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); + 0.974 END; diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index 6779a5bddcf3..a83c63cd98f4 100644 --- a/doc/src/sgml/ref/pgupgrade.sgml +++ b/doc/src/sgml/ref/pgupgrade.sgml @@ -41,8 +41,8 @@ PostgreSQL documentation pg_upgrade (formerly called pg_migrator) allows data stored in PostgreSQL data files to be upgraded to a later PostgreSQL major version without the data dump/reload typically required for - major version upgrades, e.g. from 9.5.8 to 9.6.4 or from 10.7 to 11.2. - It is not required for minor version upgrades, e.g. from 9.6.2 to 9.6.3 + major version upgrades, e.g., from 9.5.8 to 9.6.4 or from 10.7 to 11.2. + It is not required for minor version upgrades, e.g., from 9.6.2 to 9.6.3 or from 10.1 to 10.2. @@ -60,7 +60,7 @@ PostgreSQL documentation pg_upgrade does its best to - make sure the old and new clusters are binary-compatible, e.g. by + make sure the old and new clusters are binary-compatible, e.g., by checking for compatible compile-time settings, including 32/64-bit binaries. It is important that any external modules are also binary compatible, though this cannot @@ -239,13 +239,13 @@ PostgreSQL documentation Optionally move the old cluster - If you are using a version-specific installation directory, e.g. + If you are using a version-specific installation directory, e.g., /opt/PostgreSQL/&majorversion;, you do not need to move the old cluster. The graphical installers all use version-specific installation directories. - If your installation directory is not version-specific, e.g. + If your installation directory is not version-specific, e.g., /usr/local/pgsql, it is necessary to move the current PostgreSQL install directory so it does not interfere with the new PostgreSQL installation. Once the current PostgreSQL server is shut down, it is safe to rename the @@ -303,9 +303,9 @@ make prefix=/usr/local/pgsql.new install Install any custom shared object files (or DLLs) used by the old cluster - into the new cluster, e.g. pgcrypto.so, + into the new cluster, e.g., pgcrypto.so, whether they are from contrib - or some other source. Do not install the schema definitions, e.g. + or some other source. Do not install the schema definitions, e.g., CREATE EXTENSION pgcrypto, because these will be upgraded from the old cluster. Also, any custom full text search files (dictionary, synonym, @@ -360,7 +360,7 @@ NET STOP postgresql-&majorversion; Latest checkpoint location values match in all clusters. (There will be a mismatch if old standby servers were shut down before the old primary or if the old standby servers are still running.) - Also, make sure wal_level is not set to + Also, make sure wal_level is not set to minimal in the postgresql.conf file on the new primary cluster. @@ -516,9 +516,10 @@ pg_upgrade.exe Save any configuration files from the old standbys' configuration - directories you need to keep, e.g. postgresql.conf, - pg_hba.conf, because these will be overwritten or - removed in the next step. + directories you need to keep, e.g., postgresql.conf + (and any files included by it), postgresql.auto.conf, + pg_hba.conf, because these will be overwritten + or removed in the next step. @@ -542,7 +543,7 @@ rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster on the standby. The directory structure under the specified directories on the primary and standbys must match. Consult the rsync manual page for details on specifying the - remote directory, e.g. + remote directory, e.g., rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/9.5 \ @@ -606,7 +607,8 @@ rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tb If you modified pg_hba.conf, restore its original settings. It might also be necessary to adjust other configuration files in the new - cluster to match the old cluster, e.g. postgresql.conf. + cluster to match the old cluster, e.g., postgresql.conf + (and any files included by it), postgresql.auto.conf. @@ -667,7 +669,7 @@ psql --username=postgres --file=script.sql postgres pg_upgrade completes. (Automatic deletion is not possible if you have user-defined tablespaces inside the old data directory.) You can also delete the old installation directories - (e.g. bin, share). + (e.g., bin, share). @@ -791,7 +793,7 @@ psql --username=postgres --file=script.sql postgres If you are upgrading a pre-PostgreSQL 9.2 cluster that uses a configuration-file-only directory, you must pass the real data directory location to pg_upgrade, and - pass the configuration directory location to the server, e.g. + pass the configuration directory location to the server, e.g., -d /real-data-directory -o '-D /configuration-directory'. @@ -813,7 +815,7 @@ psql --username=postgres --file=script.sql postgres copy with any changes to make it consistent. ( is necessary because rsync only has file modification-time granularity of one second.) You might want to exclude some - files, e.g. postmaster.pid, as documented in postmaster.pid, as documented in . If your file system supports file system snapshots or copy-on-write file copies, you can use that to make a backup of the old cluster and tablespaces, though the snapshot diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml index 6e62f54c597c..4aaa7abe1a28 100644 --- a/doc/src/sgml/ref/postgres-ref.sgml +++ b/doc/src/sgml/ref/postgres-ref.sgml @@ -143,8 +143,8 @@ PostgreSQL documentation This option is meant for other programs that interact with a server instance, such as , to query configuration - parameter values. User-facing applications should instead use or the pg_settings view. + parameter values. User-facing applications should instead use SHOW or the pg_settings view. @@ -280,32 +280,6 @@ PostgreSQL documentation - - - - - The command-line-style arguments specified in extra-options are passed to - all server processes started by this - postgres process. - - - - Spaces within extra-options are - considered to separate arguments, unless escaped with a backslash - (\); write \\ to represent a literal - backslash. Multiple arguments can also be specified via multiple - uses of . - - - - The use of this option is obsolete; all command-line options - for server processes can be specified directly on the - postgres command line. - - - - @@ -821,7 +795,7 @@ PostgreSQL documentation To start postgres with a specific - port, e.g. 1234: + port, e.g., 1234: $ postgres -p 1234 diff --git a/doc/src/sgml/ref/prepare.sgml b/doc/src/sgml/ref/prepare.sgml index 5ec86aee10d3..aae91946c757 100644 --- a/doc/src/sgml/ref/prepare.sgml +++ b/doc/src/sgml/ref/prepare.sgml @@ -66,14 +66,14 @@ PREPARE name [ ( command. + manually cleaned up using the DEALLOCATE command. Prepared statements potentially have the largest performance advantage when a single session is being used to execute a large number of similar statements. The performance difference will be particularly - significant if the statements are complex to plan or rewrite, e.g. + significant if the statements are complex to plan or rewrite, e.g., if the query involves a join of many tables or requires the application of several rules. If the statement is relatively simple to plan and rewrite but relatively expensive to execute, the @@ -163,7 +163,7 @@ PREPARE name [ ( To examine the query plan PostgreSQL is using - for a prepared statement, use , for example + for a prepared statement, use EXPLAIN, for example EXPLAIN EXECUTE name(parameter_values); @@ -184,7 +184,8 @@ EXPLAIN EXECUTE name(parameter_valuesPostgreSQL will force re-analysis and re-planning of the statement before using it whenever database objects used in the statement have undergone - definitional (DDL) changes since the previous use of the prepared + definitional (DDL) changes or their planner statistics have + been updated since the previous use of the prepared statement. Also, if the value of changes from one use to the next, the statement will be re-parsed using the new search_path. (This latter behavior is new as of diff --git a/doc/src/sgml/ref/prepare_transaction.sgml b/doc/src/sgml/ref/prepare_transaction.sgml index 18051983e160..f4f6118ac316 100644 --- a/doc/src/sgml/ref/prepare_transaction.sgml +++ b/doc/src/sgml/ref/prepare_transaction.sgml @@ -39,8 +39,8 @@ PREPARE TRANSACTION transaction_id Once prepared, a transaction can later be committed or rolled back - with - or , + with COMMIT PREPARED + or ROLLBACK PREPARED, respectively. Those commands can be issued from any session, not only the one that executed the original transaction. @@ -92,8 +92,8 @@ PREPARE TRANSACTION transaction_id - This command must be used inside a transaction block. Use to start one. + This command must be used inside a transaction block. Use BEGIN to start one. diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 99ba3e0d34bf..4fb725776909 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -168,15 +168,10 @@ EOF Specifies the name of the database to connect to. This is equivalent to specifying dbname as the first non-option - argument on the command line. - - - If this parameter contains an = sign or starts - with a valid URI prefix - (postgresql:// - or postgres://), it is treated as a - conninfo string. See for more information. + argument on the command line. The dbname + can be a connection string. + If so, connection string parameters will override any conflicting + command line options. @@ -498,7 +493,7 @@ EOF Never issue a password prompt. If the server requires password - authentication and a password is not available by other means + authentication and a password is not available from other sources such as a .pgpass file, the connection attempt will fail. This option can be useful in batch jobs and scripts where no user is present to enter a password. @@ -518,13 +513,15 @@ EOF Force psql to prompt for a - password before connecting to a database. + password before connecting to a database, even if the password will + not be used. - This option is never essential, since psql - will automatically prompt for a password if the server demands - password authentication. However, psql + If the server requires password authentication and a password is not + available from other sources such as a .pgpass + file, psql will prompt for a + password in any case. However, psql will waste a connection attempt finding out that the server wants a password. In some cases it is worth typing to avoid the extra connection attempt. @@ -635,7 +632,7 @@ EOF psql returns 0 to the shell if it - finished normally, 1 if a fatal error of its own occurs (e.g. out of memory, + finished normally, 1 if a fatal error of its own occurs (e.g., out of memory, file not found), 2 if the connection to the server went bad and the session was not interactive, and 3 if an error occurred in a script and the variable ON_ERROR_STOP was set. @@ -773,8 +770,8 @@ testdb=> Whenever a command is executed, psql also polls for asynchronous notification events generated by - and - . + LISTEN and + NOTIFY. @@ -906,40 +903,65 @@ testdb=> Establishes a new connection to a PostgreSQL server. The connection parameters to use can be specified either - using a positional syntax, or using conninfo connection - strings as detailed in . + using a positional syntax (one or more of database name, user, + host, and port), or using a conninfo + connection string as detailed in + . If no arguments are given, a + new connection is made using the same parameters as before. - Where the command omits database name, user, host, or port, the new - connection can reuse values from the previous connection. By default, - values from the previous connection are reused except when processing - a conninfo string. Passing a first argument - of -reuse-previous=on - or -reuse-previous=off overrides that default. - When the command neither specifies nor reuses a particular parameter, - the libpq default is used. Specifying any + Specifying any of dbname, username, host or port as - is equivalent to omitting that parameter. - If hostaddr was specified in the original - connection's conninfo, that address is reused - for the new connection (disregarding any other host specification). + + + + The new connection can re-use connection parameters from the previous + connection; not only database name, user, host, and port, but other + settings such as sslmode. By default, + parameters are re-used in the positional syntax, but not when + a conninfo string is given. Passing a + first argument of -reuse-previous=on + or -reuse-previous=off overrides that default. If + parameters are re-used, then any parameter not explicitly specified as + a positional parameter or in the conninfo + string is taken from the existing connection's parameters. An + exception is that if the host setting + is changed from its previous value using the positional syntax, + any hostaddr setting present in the + existing connection's parameters is dropped. + Also, any password used for the existing connection will be re-used + only if the user, host, and port settings are not changed. + When the command neither specifies nor reuses a particular parameter, + the libpq default is used. If the new connection is successfully made, the previous connection is closed. - If the connection attempt failed (wrong user name, access - denied, etc.), the previous connection will only be kept if - psql is in interactive mode. When - executing a non-interactive script, processing will - immediately stop with an error. This distinction was chosen as + If the connection attempt fails (wrong user name, access + denied, etc.), the previous connection will be kept if + psql is in interactive mode. But when + executing a non-interactive script, the old connection is closed + and an error is reported. That may or may not terminate the + script; if it does not, all database-accessing commands will fail + until another \connect command is successfully + executed. This distinction was chosen as a user convenience against typos on the one hand, and a safety mechanism that scripts are not accidentally acting on the wrong database on the other hand. + Note that whenever a \connect command attempts + to re-use parameters, the values re-used are those of the last + successful connection, not of any failed attempts made subsequently. + However, in the case of a + non-interactive \connect failure, no parameters + are allowed to be re-used later, since the script would likely be + expecting the values from the failed \connect + to be re-used. @@ -949,6 +971,7 @@ testdb=> => \c mydb myuser host.dom 6432 => \c service=foo => \c "host=localhost port=5432 dbname=mydb connect_timeout=10 sslmode=disable" +=> \c -reuse-previous=on sslmode=require -- changes only sslmode => \c postgresql://tom@localhost/mydb?application_name=myapp @@ -1010,7 +1033,7 @@ testdb=> Performs a frontend (client) copy. This is an operation that - runs an SQL + runs an SQL COPY command, but instead of the server reading or writing the specified file, psql reads or writes the file and @@ -1035,7 +1058,7 @@ testdb=> For \copy ... from stdin, data rows are read from the same source that issued the command, continuing until \. is read or the stream reaches EOF. This option is useful - for populating tables in-line within a SQL script file. + for populating tables in-line within an SQL script file. For \copy ... to stdout, output is sent to the same place as psql command output, and the COPY count command status is @@ -1047,9 +1070,9 @@ testdb=> The syntax of this command is similar to that of the - SQL + SQL COPY command. All options other than the data source/destination are - as specified for . + as specified for COPY. Because of this, special parsing rules apply to the \copy meta-command. Unlike most other meta-commands, the entire remainder of the line is always taken to be the arguments of \copy, @@ -1196,8 +1219,10 @@ testdb=> more information is displayed: any comments associated with the columns of the table are shown, as is the presence of OIDs in the table, the view definition if the relation is a view, a non-default - replica - identity setting. + replica + identity setting and the + access method name + if the relation has an access method. @@ -1412,8 +1437,8 @@ testdb=> - Descriptions for objects can be created with the + Descriptions for objects can be created with the COMMENT SQL command. @@ -1450,9 +1475,9 @@ testdb=> - The command is used to set - default access privileges. The meaning of the - privilege display is explained in + The ALTER DEFAULT + PRIVILEGES command is used to set default access + privileges. The meaning of the privilege display is explained in . @@ -1564,7 +1589,7 @@ testdb=> - \df[anptwS+] [ pattern ] + \df[anptwS+] [ pattern [ arg_pattern ... ] ] @@ -1577,6 +1602,11 @@ testdb=> If pattern is specified, only functions whose names match the pattern are shown. + Any additional arguments are type-name patterns, which are matched + to the type names of the first, second, and so on arguments of the + function. (Matching functions can have more arguments than what + you specify. To prevent that, write a dash - as + the last arg_pattern.) By default, only user-created objects are shown; supply a pattern or the S modifier to include system objects. @@ -1586,14 +1616,6 @@ testdb=> language, source code and description. - - - To look up functions taking arguments or returning values of a specific - data type, use your pager's search capability to scroll through the - \df output. - - - @@ -1718,12 +1740,19 @@ testdb=> - \do[S+] [ pattern ] + \do[S+] [ pattern [ arg_pattern [ arg_pattern ] ] ] Lists operators with their operand and result types. If pattern is specified, only operators whose names match the pattern are listed. + If one arg_pattern is + specified, only prefix operators whose right argument's type name + matches that pattern are listed. + If two arg_patterns + are specified, only binary operators whose argument type names match + those patterns are listed. (Alternatively, write - + for the unused argument of a unary operator.) By default, only user-created objects are shown; supply a pattern or the S modifier to include system objects. @@ -1767,8 +1796,8 @@ testdb=> - The and - + The GRANT and + REVOKE commands are used to set access privileges. The meaning of the privilege display is explained in . @@ -1823,8 +1852,8 @@ testdb=> - The and - + The ALTER ROLE and + ALTER DATABASE commands are used to define per-role and per-database configuration settings. @@ -1909,6 +1938,28 @@ testdb=> + + \dX [ pattern ] + + + Lists extended statistics. + If pattern + is specified, only those extended statistics whose names match the + pattern are listed. + + + + The status of each kind of extended statistics is shown in a column + named after its statistic kind (e.g. Ndistinct). + "defined" means that it was requested when creating the statistics, + and NULL means it wasn't requested. + You can use pg_stats_ext if you'd like to know whether + ANALYZE was run and statistics are available to the + planner. + + + + \dy[+] [ pattern ] @@ -1939,7 +1990,9 @@ testdb=> - The new contents of the query buffer are then re-parsed according to + If you edit a file or the previous query, and you quit the editor without + modifying the file, the query buffer is cleared. + Otherwise, the new contents of the query buffer are re-parsed according to the normal rules of psql, treating the whole buffer as a single line. Any complete queries are immediately executed; that is, if the query buffer contains or ends with a @@ -2008,7 +2061,8 @@ Tue Oct 26 21:40:57 CEST 1999 in the form of a CREATE OR REPLACE FUNCTION or CREATE OR REPLACE PROCEDURE command. Editing is done in the same way as for \edit. - After the editor exits, the updated command is executed immediately + If you quit the editor without saving, the statement is discarded. + If you save and exit the editor, the updated command is executed immediately if you added a semicolon to it. Otherwise it is redisplayed; type semicolon or \g to send it, or \r to cancel. @@ -2084,7 +2138,8 @@ Tue Oct 26 21:40:57 CEST 1999 This command fetches and edits the definition of the named view, in the form of a CREATE OR REPLACE VIEW command. Editing is done in the same way as for \edit. - After the editor exits, the updated command is executed immediately + If you quit the editor without saving, the statement is discarded. + If you save and exit the editor, the updated command is executed immediately if you added a semicolon to it. Otherwise it is redisplayed; type semicolon or \g to send it, or \r to cancel. @@ -2203,7 +2258,7 @@ Tue Oct 26 21:40:57 CEST 1999 Sends the current query buffer to the server, then treats - each column of each row of the query's output (if any) as a SQL + each column of each row of the query's output (if any) as an SQL statement to be executed. For example, to create an index on each column of my_table: @@ -3026,7 +3081,7 @@ lo_import 152801 In latex-longtable format, this controls the proportional width of each column containing a left-aligned data type. It is specified as a whitespace-separated list of values, - e.g. '0.2 0.2 0.6'. Unspecified output columns + e.g., '0.2 0.2 0.6'. Unspecified output columns use the last specified value. @@ -3195,7 +3250,7 @@ lo_import 152801 This command is unrelated to the SQL - command . + command SET. @@ -3470,7 +3525,7 @@ testdb=> \setenv LESS -imx4F - Normally, psql will dispatch a SQL command to the + Normally, psql will dispatch an SQL command to the server as soon as it reaches the command-ending semicolon, even if more input remains on the current line. Thus for example entering @@ -3843,6 +3898,17 @@ bar + + HIDE_TOAST_COMPRESSION + + + If this variable is set to true, column + compression method details are not displayed. This is mainly + useful for regression tests. + + + + HISTCONTROL @@ -3875,7 +3941,7 @@ bar or %APPDATA%\postgresql\psql_history on Windows. For example, putting: -\set HISTFILE ~/.psql_history- :DBNAME +\set HISTFILE ~/.psql_history-:DBNAME in ~/.psqlrc will cause psql to maintain a separate history for @@ -4484,7 +4550,7 @@ testdb=> \set PROMPT1 '%[%033[1;33;40m%]%n@%/%R%[%033[0m%]%# ' psql starts up. Tab-completion is also supported, although the completion logic makes no claim to be an SQL parser. The queries generated by tab-completion - can also interfere with other SQL commands, e.g. SET + can also interfere with other SQL commands, e.g., SET TRANSACTION ISOLATION LEVEL. If for some reason you do not like the tab completion, you can turn it off by putting this in a file named @@ -4939,6 +5005,22 @@ second | four + + Here is an example of using the \df command to + find only functions with names matching int*pl + and whose second argument is of type bigint: + +testdb=> \df int*pl * bigint + List of functions + Schema | Name | Result data type | Argument data types | Type +------------+---------+------------------+---------------------+------ + pg_catalog | int28pl | bigint | smallint, bigint | func + pg_catalog | int48pl | bigint | integer, bigint | func + pg_catalog | int8pl | bigint | bigint, bigint | func +(3 rows) + + + When suitable, query results can be shown in a crosstab representation with the \crosstabview command: diff --git a/doc/src/sgml/ref/reassign_owned.sgml b/doc/src/sgml/ref/reassign_owned.sgml index 42f72a726fd1..ab692bd06908 100644 --- a/doc/src/sgml/ref/reassign_owned.sgml +++ b/doc/src/sgml/ref/reassign_owned.sgml @@ -21,8 +21,8 @@ PostgreSQL documentation -REASSIGN OWNED BY { old_role | CURRENT_USER | SESSION_USER } [, ...] - TO { new_role | CURRENT_USER | SESSION_USER } +REASSIGN OWNED BY { old_role | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] + TO { new_role | CURRENT_ROLE | CURRENT_USER | SESSION_USER } @@ -82,7 +82,7 @@ REASSIGN OWNED BY { old_role | CURR - The command is an alternative that + The DROP OWNED command is an alternative that simply drops all the database objects owned by one or more roles. diff --git a/doc/src/sgml/ref/refresh_materialized_view.sgml b/doc/src/sgml/ref/refresh_materialized_view.sgml index 8ae62671adab..3bf888444782 100644 --- a/doc/src/sgml/ref/refresh_materialized_view.sgml +++ b/doc/src/sgml/ref/refresh_materialized_view.sgml @@ -94,7 +94,7 @@ REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name While the default index for future - + CLUSTER operations is retained, REFRESH MATERIALIZED VIEW does not order the generated rows based on this property. If you want the data to be ordered upon generation, you must use an ORDER BY diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index 33af4ae02a13..27362661b339 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -25,7 +25,9 @@ REINDEX [ ( option [, ...] ) ] { IN where option can be one of: - VERBOSE + CONCURRENTLY [ boolean ] + TABLESPACE new_tablespace + VERBOSE [ boolean ] @@ -177,6 +179,15 @@ REINDEX [ ( option [, ...] ) ] { IN + + TABLESPACE + + + Specifies that indexes will be rebuilt on a new tablespace. + + + + VERBOSE @@ -185,6 +196,29 @@ REINDEX [ ( option [, ...] ) ] { IN + + + boolean + + + Specifies whether the selected option should be turned on or off. + You can write TRUE, ON, or + 1 to enable the option, and FALSE, + OFF, or 0 to disable it. The + boolean value can also + be omitted, in which case TRUE is assumed. + + + + + + new_tablespace + + + The tablespace where indexes will be rebuilt. + + + @@ -239,20 +273,21 @@ REINDEX [ ( option [, ...] ) ] { IN REINDEX is similar to a drop and recreate of the index in that the index contents are rebuilt from scratch. However, the locking considerations are rather different. REINDEX locks out writes - but not reads of the index's parent table. It also takes an exclusive lock - on the specific index being processed, which will block reads that attempt - to use that index. In contrast, DROP INDEX momentarily takes - an exclusive lock on the parent table, blocking both writes and reads. The - subsequent CREATE INDEX locks out writes but not reads; since - the index is not there, no read will attempt to use it, meaning that there - will be no blocking but reads might be forced into expensive sequential - scans. + but not reads of the index's parent table. It also takes an + ACCESS EXCLUSIVE lock on the specific index being processed, + which will block reads that attempt to use that index. In contrast, + DROP INDEX momentarily takes an + ACCESS EXCLUSIVE lock on the parent table, blocking both + writes and reads. The subsequent CREATE INDEX locks out + writes but not reads; since the index is not there, no read will attempt to + use it, meaning that there will be no blocking but reads might be forced + into expensive sequential scans. Reindexing a single index or table requires being the owner of that index or table. Reindexing a schema or database requires being the - owner of that schema or database. Note that is therefore sometimes + owner of that schema or database. Note specifically that it's thus possible for non-superusers to rebuild indexes of tables owned by other users. However, as a special exception, when REINDEX DATABASE, REINDEX SCHEMA @@ -270,6 +305,14 @@ REINDEX [ ( option [, ...] ) ] { IN a transaction block when working on a partitioned table or index. + + If SCHEMA, DATABASE or + SYSTEM is used with TABLESPACE, + system relations are skipped and a single WARNING + will be generated. Indexes on TOAST tables are rebuilt, but not moved + to the new tablespace. + + Rebuilding Indexes Concurrently @@ -411,6 +454,14 @@ Indexes: CONCURRENTLY cannot. + + Like any long-running transaction, REINDEX on a table + can affect which tuples can be removed by concurrent + VACUUM on any other table. + Excepted from this are operations with the CONCURRENTLY + option for indexes that are not partial and do not index any expressions. + + REINDEX SYSTEM does not support CONCURRENTLY since system catalogs cannot be reindexed @@ -424,6 +475,12 @@ Indexes: is reindexed concurrently, those indexes will be skipped. (It is possible to reindex such indexes without the CONCURRENTLY option.) + + + Each backend running REINDEX will report its progress + in the pg_stat_progress_create_index view. See + for details. + @@ -482,6 +539,7 @@ REINDEX TABLE CONCURRENTLY my_broken_table; + diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml index 026fd018d93e..80a7f84886be 100644 --- a/doc/src/sgml/ref/reindexdb.sgml +++ b/doc/src/sgml/ref/reindexdb.sgml @@ -28,8 +28,8 @@ PostgreSQL documentation - + schema @@ -38,8 +38,8 @@ PostgreSQL documentation - + table @@ -48,8 +48,8 @@ PostgreSQL documentation - + index @@ -64,8 +64,8 @@ PostgreSQL documentation option - + @@ -75,8 +75,8 @@ PostgreSQL documentation option - + dbname @@ -93,7 +93,7 @@ PostgreSQL documentation reindexdb is a wrapper around the SQL - command . + command REINDEX. There is no effective difference between reindexing databases via this utility and via other methods for accessing the server. @@ -134,12 +134,15 @@ PostgreSQL documentation - Specifies the name of the database to be reindexed. - If this is not specified and (or - ) is not used, the database name is read + Specifies the name of the database to be reindexed, + when / is not used. + If this is not specified, the database name is read from the environment variable PGDATABASE. If that is not set, the user name specified for the connection is - used. + used. The dbname can be a connection string. If so, + connection string parameters will override any conflicting command + line options. @@ -174,8 +177,8 @@ PostgreSQL documentation Execute the reindex commands in parallel by running njobs - commands simultaneously. This option reduces the time of the - processing but it also increases the load on the database server. + commands simultaneously. This option may reduce the processing time + but it also increases the load on the database server. reindexdb will open @@ -234,6 +237,16 @@ PostgreSQL documentation + + + + + Specifies the tablespace where indexes are rebuilt. (This name is + processed as a double-quoted identifier.) + + + + @@ -348,10 +361,16 @@ PostgreSQL documentation - Specifies the name of the database to connect to discover what other - databases should be reindexed. If not specified, the - postgres database will be used, - and if that does not exist, template1 will be used. + Specifies the name of the database to connect to to discover which + databases should be reindexed, + when / is used. + If not specified, the postgres database will be used, + or if that does not exist, template1 will be used. + This can be a connection + string. If so, connection string parameters will override any + conflicting command line options. Also, connection string parameters + other than the database name itself will be re-used when connecting + to other databases. diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml index b6bac21c57a3..3014c864ea3c 100644 --- a/doc/src/sgml/ref/revoke.sgml +++ b/doc/src/sgml/ref/revoke.sgml @@ -27,6 +27,7 @@ REVOKE [ GRANT OPTION FOR ] ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] } FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] @@ -34,6 +35,7 @@ REVOKE [ GRANT OPTION FOR ] [, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) } ON [ TABLE ] table_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] @@ -42,30 +44,35 @@ REVOKE [ GRANT OPTION FOR ] ON { SEQUENCE sequence_name [, ...] | ALL SEQUENCES IN SCHEMA schema_name [, ...] } FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] } ON DATABASE database_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } ON DOMAIN domain_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN DATA WRAPPER fdw_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } ON FOREIGN SERVER server_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] @@ -73,36 +80,42 @@ REVOKE [ GRANT OPTION FOR ] ON { { FUNCTION | PROCEDURE | ROUTINE } function_name [ ( [ [ argmode ] [ arg_name ] arg_type [, ...] ] ) ] [, ...] | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA schema_name [, ...] } FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } ON LANGUAGE lang_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] } ON LARGE OBJECT loid [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] } ON SCHEMA schema_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { CREATE | ALL [ PRIVILEGES ] } ON TABLESPACE tablespace_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ GRANT OPTION FOR ] { USAGE | ALL [ PRIVILEGES ] } ON TYPE type_name [, ...] FROM role_specification [, ...] + [ GRANTED BY role_specification ] [ CASCADE | RESTRICT ] REVOKE [ ADMIN OPTION FOR ] @@ -114,6 +127,7 @@ REVOKE [ ADMIN OPTION FOR ] [ GROUP ] role_name | PUBLIC + | CURRENT_ROLE | CURRENT_USER | SESSION_USER @@ -130,7 +144,7 @@ REVOKE [ ADMIN OPTION FOR ] - See the description of the command for + See the description of the GRANT command for the meaning of the privilege types. @@ -291,7 +305,7 @@ REVOKE admins FROM joe; Compatibility - The compatibility notes of the command + The compatibility notes of the GRANT command apply analogously to REVOKE. The keyword RESTRICT or CASCADE is required according to the standard, but PostgreSQL diff --git a/doc/src/sgml/ref/rollback.sgml b/doc/src/sgml/ref/rollback.sgml index 1357eaa8323a..142f71e77425 100644 --- a/doc/src/sgml/ref/rollback.sgml +++ b/doc/src/sgml/ref/rollback.sgml @@ -70,7 +70,7 @@ ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] Notes - Use to + Use COMMIT to successfully terminate a transaction. diff --git a/doc/src/sgml/ref/rollback_to.sgml b/doc/src/sgml/ref/rollback_to.sgml index 4d5647a302e2..3d5a241e1aa9 100644 --- a/doc/src/sgml/ref/rollback_to.sgml +++ b/doc/src/sgml/ref/rollback_to.sgml @@ -64,7 +64,7 @@ ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_nameNotes - Use to destroy a savepoint + Use RELEASE SAVEPOINT to destroy a savepoint without discarding the effects of commands executed after it was established. diff --git a/doc/src/sgml/ref/savepoint.sgml b/doc/src/sgml/ref/savepoint.sgml index 87243b1d2046..b17342a1ee6a 100644 --- a/doc/src/sgml/ref/savepoint.sgml +++ b/doc/src/sgml/ref/savepoint.sgml @@ -64,8 +64,8 @@ SAVEPOINT savepoint_name Notes - Use to - rollback to a savepoint. Use + Use ROLLBACK TO to + rollback to a savepoint. Use RELEASE SAVEPOINT to destroy a savepoint, keeping the effects of commands executed after it was established. diff --git a/doc/src/sgml/ref/security_label.sgml b/doc/src/sgml/ref/security_label.sgml index e9688cce214b..20a839ff0c32 100644 --- a/doc/src/sgml/ref/security_label.sgml +++ b/doc/src/sgml/ref/security_label.sgml @@ -99,9 +99,8 @@ SECURITY LABEL [ FOR provider ] ON routine_name - The name of the object to be labeled. Names of tables, - aggregates, domains, foreign tables, functions, procedures, routines, sequences, types, and - views can be schema-qualified. + The name of the object to be labeled. Names of objects that reside in + schemas (tables, functions, etc.) can be schema-qualified. diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index ab0bd7e0cae4..7737633a092f 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -75,7 +75,7 @@ where window_specification can be: [ LATERAL ] function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] ) [ LATERAL ] ROWS FROM( function_name ( [ argument [, ...] ] ) [ AS ( column_definition [, ...] ) ] [, ...] ) [ WITH ORDINALITY ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] - from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ] + from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) [ AS join_using_alias ] ] and grouping_element can be one of: @@ -89,6 +89,8 @@ where window_specification can be: and with_query is: with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( select | values | insert | update | delete ) + [ SEARCH { BREADTH | DEPTH } FIRST BY column_name [, ...] SET search_seq_col_name ] + [ CYCLE column_name [, ...] SET cycle_mark_col_name [ TO cycle_mark_value DEFAULT cycle_mark_default ] USING cycle_path_col_name ] TABLE [ ONLY ] table_name [ * ] @@ -292,6 +294,50 @@ TABLE [ ONLY ] table_name [ * ] queries that do not use recursion or forward references. + + The optional SEARCH clause computes a search + sequence column that can be used for ordering the results of a + recursive query in either breadth-first or depth-first order. The + supplied column name list specifies the row key that is to be used for + keeping track of visited rows. A column named + search_seq_col_name will be added to the result + column list of the WITH query. This column can be + ordered by in the outer query to achieve the respective ordering. See + for examples. + + + + The optional CYCLE clause is used to detect cycles in + recursive queries. The supplied column name list specifies the row key + that is to be used for keeping track of visited rows. A column named + cycle_mark_col_name will be added to the result + column list of the WITH query. This column will be set + to cycle_mark_value when a cycle has been + detected, else to cycle_mark_default. + Furthermore, processing of the recursive union will stop when a cycle has + been detected. cycle_mark_value and + cycle_mark_default must be constants and they + must be coercible to a common data type, and the data type must have an + inequality operator. (The SQL standard requires that they be Boolean + constants or character strings, but PostgreSQL does not require that.) By + default, TRUE and FALSE (of type + boolean) are used. Furthermore, a column + named cycle_path_col_name will be added to the + result column list of the WITH query. This column is + used internally for tracking visited rows. See for examples. + + + + Both the SEARCH and the CYCLE clause + are only valid for recursive WITH queries. The + with_query must be a UNION + (or UNION ALL) of two SELECT (or + equivalent) commands (no nested UNIONs). If both + clauses are used, the column added by the SEARCH clause + appears before the columns added by the CYCLE clause. + + The primary query and the WITH queries are all (notionally) executed at the same time. This implies that the effects of @@ -462,7 +508,7 @@ TABLE [ ONLY ] table_name [ * ] sub-SELECT must be surrounded by parentheses, and an alias must be provided for it. A - command + VALUES command can also be used here. @@ -492,9 +538,17 @@ TABLE [ ONLY ] table_name [ * ] result sets, but any function can be used.) This acts as though the function's output were created as a temporary table for the duration of this single SELECT command. - When the optional WITH ORDINALITY clause is - added to the function call, a new column is appended after - all the function's output columns with numbering for each row. + If the function's result type is composite (including the case of a + function with multiple OUT parameters), each + attribute becomes a separate column in the implicit table. + + + + When the optional WITH ORDINALITY clause is added + to the function call, an additional column of type bigint + will be appended to the function's result column(s). This column + numbers the rows of the function's result set, starting from 1. + By default, this column is named ordinality. @@ -502,8 +556,7 @@ TABLE [ ONLY ] table_name [ * ] If an alias is written, a column alias list can also be written to provide substitute names for one or more attributes of the function's composite return - type, including the column added by ORDINALITY - if present. + type, including the ordinality column if present. @@ -639,7 +692,7 @@ TABLE [ ONLY ] table_name [ * ] - USING ( join_column [, ...] ) + USING ( join_column [, ...] ) [ AS join_using_alias ] A clause of the form USING ( a, b, ... ) is @@ -649,6 +702,18 @@ TABLE [ ONLY ] table_name [ * ] equivalent columns will be included in the join output, not both. + + + If a join_using_alias + name is specified, it provides a table alias for the join columns. + Only the join columns listed in the USING clause + are addressable by this name. Unlike a regular alias, this does not hide the names of + the joined tables from the rest of the query. Also unlike a regular + alias, you cannot write a + column alias list — the output names of the join columns are the + same as they appear in the USING list. + @@ -741,7 +806,7 @@ WHERE condition The optional GROUP BY clause has the general form -GROUP BY grouping_element [, ...] +GROUP BY [ ALL | DISTINCT ] grouping_element [, ...] @@ -765,7 +830,10 @@ GROUP BY grouping_element [, ...] independent grouping sets. The effect of this is equivalent to constructing a UNION ALL between subqueries with the individual grouping sets as their - GROUP BY clauses. For further details on the handling + GROUP BY clauses. The optional DISTINCT + clause removes duplicate sets before processing; it does not + transform the UNION ALL into a UNION DISTINCT. + For further details on the handling of grouping sets see . @@ -1550,7 +1618,7 @@ KEY SHARE to the row-level lock(s) — the required ROW SHARE table-level lock is still taken in the ordinary way (see ). You can use - + LOCK with the NOWAIT option first, if you need to acquire the table-level lock without waiting. @@ -1950,18 +2018,6 @@ SELECT 2+2; by introducing a dummy one-row table from which to do the SELECT. - - - Note that if a FROM clause is not specified, - the query cannot reference any database tables. For example, the - following query is invalid: - -SELECT distributors.* WHERE distributors.name = 'Westward'; -PostgreSQL releases prior to - 8.1 would accept queries of this form, and add an implicit entry - to the query's FROM clause for each table - referenced by the query. This is no longer allowed. - diff --git a/doc/src/sgml/ref/select_into.sgml b/doc/src/sgml/ref/select_into.sgml index e4133adf4709..76bafaa2d0b8 100644 --- a/doc/src/sgml/ref/select_into.sgml +++ b/doc/src/sgml/ref/select_into.sgml @@ -94,7 +94,7 @@ SELECT [ ALL | DISTINCT [ ON ( expressionNotes - is functionally similar to + CREATE TABLE AS is functionally similar to SELECT INTO. CREATE TABLE AS is the recommended syntax, since this form of SELECT INTO is not available in ECPG @@ -108,8 +108,8 @@ SELECT [ ALL | DISTINCT [ ON ( expressionCREATE TABLE AS, SELECT INTO does not allow to specify properties like a table's access method with or the table's - tablespace with . Use if necessary. Therefore, the default table + tablespace with . Use + CREATE TABLE AS if necessary. Therefore, the default table access method is chosen for the new table. See for more information. @@ -137,9 +137,11 @@ SELECT * INTO films_recent FROM films WHERE date_prod >= '2002-01-01'; in ECPG (see ) and PL/pgSQL (see ). The PostgreSQL usage of SELECT - INTO to represent table creation is historical. It is - best to use CREATE TABLE AS for this purpose in - new code. + INTO to represent table creation is historical. Some other SQL + implementations also use SELECT INTO in this way (but + most SQL implementations support CREATE TABLE AS + instead). Apart from such compatibility considerations, it is best to use + CREATE TABLE AS for this purpose in new code. diff --git a/doc/src/sgml/ref/set.sgml b/doc/src/sgml/ref/set.sgml index 63f312e812a8..339ee9eec948 100644 --- a/doc/src/sgml/ref/set.sgml +++ b/doc/src/sgml/ref/set.sgml @@ -267,7 +267,7 @@ SELECT setseed(value); The function set_config provides equivalent - functionality; see . + functionality; see . Also, it is possible to UPDATE the pg_settings system view to perform the equivalent of SET. diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml index a4842f363c8b..f02babf3af36 100644 --- a/doc/src/sgml/ref/set_role.sgml +++ b/doc/src/sgml/ref/set_role.sgml @@ -48,14 +48,21 @@ RESET ROLE The SESSION and LOCAL modifiers act the same - as for the regular + as for the regular SET command. - The NONE and RESET forms reset the current - user identifier to be the current session user identifier. - These forms can be executed by any user. + SET ROLE NONE sets the current user identifier to the + current session user identifier, as returned by + session_user. RESET ROLE sets the + current user identifier to the connection-time setting specified by the + command-line options, + ALTER ROLE, or + ALTER DATABASE, + if any such settings exist. Otherwise, RESET ROLE sets + the current user identifier to the current session user identifier. These + forms can be executed by any user. @@ -82,7 +89,7 @@ RESET ROLE SET ROLE has effects comparable to - , but the privilege + SET SESSION AUTHORIZATION, but the privilege checks involved are quite different. Also, SET SESSION AUTHORIZATION determines which roles are allowable for later SET ROLE commands, whereas changing @@ -92,7 +99,7 @@ RESET ROLE SET ROLE does not process session variables as specified by - the role's settings; this only happens during + the role's ALTER ROLE settings; this only happens during login. diff --git a/doc/src/sgml/ref/set_session_auth.sgml b/doc/src/sgml/ref/set_session_auth.sgml index 6a838e58b764..e44e78ed8d67 100644 --- a/doc/src/sgml/ref/set_session_auth.sgml +++ b/doc/src/sgml/ref/set_session_auth.sgml @@ -45,7 +45,7 @@ RESET SESSION AUTHORIZATION identifier is normally equal to the session user identifier, but might change temporarily in the context of SECURITY DEFINER functions and similar mechanisms; it can also be changed by - . + SET ROLE. The current user identifier is relevant for permission checking. @@ -58,7 +58,7 @@ RESET SESSION AUTHORIZATION The SESSION and LOCAL modifiers act the same - as for the regular + as for the regular SET command. diff --git a/doc/src/sgml/ref/show.sgml b/doc/src/sgml/ref/show.sgml index 945b0491b14e..93789ee0be05 100644 --- a/doc/src/sgml/ref/show.sgml +++ b/doc/src/sgml/ref/show.sgml @@ -129,7 +129,7 @@ SHOW ALL The function current_setting produces - equivalent output; see . + equivalent output; see . Also, the pg_settings system view produces the same information. diff --git a/doc/src/sgml/ref/start_transaction.sgml b/doc/src/sgml/ref/start_transaction.sgml index d6cd1d417792..74ccd7e3456c 100644 --- a/doc/src/sgml/ref/start_transaction.sgml +++ b/doc/src/sgml/ref/start_transaction.sgml @@ -37,8 +37,8 @@ START TRANSACTION [ transaction_mode This command begins a new transaction block. If the isolation level, read/write mode, or deferrable mode is specified, the new transaction has those - characteristics, as if was executed. This is the same - as the command. + characteristics, as if SET TRANSACTION was executed. This is the same + as the BEGIN command. diff --git a/doc/src/sgml/ref/truncate.sgml b/doc/src/sgml/ref/truncate.sgml index 5922ee579e11..9d846f88c9f6 100644 --- a/doc/src/sgml/ref/truncate.sgml +++ b/doc/src/sgml/ref/truncate.sgml @@ -160,8 +160,7 @@ TRUNCATE [ TABLE ] [ ONLY ] name [ When RESTART IDENTITY is specified, the implied ALTER SEQUENCE RESTART operations are also done transactionally; that is, they will be rolled back if the surrounding - transaction does not commit. This is unlike the normal behavior of - ALTER SEQUENCE RESTART. Be aware that if any additional + transaction does not commit. Be aware that if any additional sequence operations are done on the restarted sequences before the transaction rolls back, the effects of these operations on the sequences will be rolled back, but not their effects on currval(); @@ -173,9 +172,9 @@ TRUNCATE [ TABLE ] [ ONLY ] name [ - TRUNCATE is not currently supported for foreign tables. - This implies that if a specified table has any descendant tables that are - foreign, the command will fail. + TRUNCATE can be used for foreign tables if + supported by the foreign data wrapper, for instance, + see . diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index a48f75ad7baf..3df32b58ee69 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -32,7 +32,8 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ boolean ] DISABLE_PAGE_SKIPPING [ boolean ] SKIP_LOCKED [ boolean ] - INDEX_CLEANUP [ boolean ] + INDEX_CLEANUP { AUTO | ON | OFF } + PROCESS_TOAST [ boolean ] TRUNCATE [ boolean ] PARALLEL integer @@ -82,8 +83,8 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ INDEX_CLEANUP - Specifies that VACUUM should attempt to remove - index entries pointing to dead tuples. This is normally the desired - behavior and is the default unless the - vacuum_index_cleanup option has been set to false - for the table to be vacuumed. Setting this option to false may be - useful when it is necessary to make vacuum run as quickly as possible, - for example to avoid imminent transaction ID wraparound - (see ). However, if index - cleanup is not performed regularly, performance may suffer, because - as the table is modified, indexes will accumulate dead tuples - and the table itself will accumulate dead line pointers that cannot be - removed until index cleanup is completed. This option has no effect - for tables that do not have an index and is ignored if the + Normally, VACUUM will skip index vacuuming + when there are very few dead tuples in the table. The cost of + processing all of the table's indexes is expected to greatly + exceed the benefit of removing dead index tuples when this + happens. This option can be used to force + VACUUM to process indexes when there are more + than zero dead tuples. The default is AUTO, + which allows VACUUM to skip index vacuuming + when appropriate. If INDEX_CLEANUP is set to + ON, VACUUM will + conservatively remove all dead tuples from indexes. This may be + useful for backwards compatibility with earlier releases of + PostgreSQL where this was the + standard behavior. + + + INDEX_CLEANUP can also be set to + OFF to force VACUUM to + always skip index vacuuming, even when + there are many dead tuples in the table. This may be useful + when it is necessary to make VACUUM run as + quickly as possible to avoid imminent transaction ID wraparound + (see ). However, the + wraparound failsafe mechanism controlled by will generally trigger + automatically to avoid transaction ID wraparound failure, and + should be preferred. If index cleanup is not performed + regularly, performance may suffer, because as the table is + modified indexes will accumulate dead tuples and the table + itself will accumulate dead line pointers that cannot be removed + until index cleanup is completed. + + + This option has no effect for tables that have no index and is + ignored if the FULL option is used. It also + has no effect on the transaction ID wraparound failsafe + mechanism. When triggered it will skip index vacuuming, even + when INDEX_CLEANUP is set to + ON. + + + + + + PROCESS_TOAST + + + Specifies that VACUUM should attempt to process the + corresponding TOAST table for each relation, if one + exists. This is usually the desired behavior and is the default. + Setting this option to false may be useful when it is only necessary to + vacuum the main relation. This option is required when the FULL option is used. @@ -235,22 +275,22 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ integer background workers (for the details of each vacuum phase, please - refer to ). In plain VACUUM - (without FULL), if the PARALLEL option - is omitted, then the number of workers is determined based on the number of - indexes on the relation that support parallel vacuum operation and is further - limited by . An index - can participate in parallel vacuum if and only if the size of the index is - more than . Please note - that it is not guaranteed that the number of parallel workers specified in - integer will be used during - execution. It is possible for a vacuum to run with fewer workers than - specified, or even with no workers at all. Only one worker can be used per - index. So parallel workers are launched only when there are at least - 2 indexes in the table. Workers for vacuum are launched - before the start of each phase and exit at the end of the phase. These - behaviors might change in a future release. This option can't be used with - the FULL option. + refer to ). The number of workers used + to perform the operation is equal to the number of indexes on the + relation that support parallel vacuum which is limited by the number of + workers specified with PARALLEL option if any which is + further limited by . + An index can participate in parallel vacuum if and only if the size of the + index is more than . + Please note that it is not guaranteed that the number of parallel workers + specified in integer will be + used during execution. It is possible for a vacuum to run with fewer + workers than specified, or even with no workers at all. Only one worker + can be used per index. So parallel workers are launched only when there + are at least 2 indexes in the table. Workers for + vacuum are launched before the start of each phase and exit at the end of + the phase. These behaviors might change in a future release. This + option can't be used with the FULL option. @@ -378,6 +418,15 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ . + + Each backend running VACUUM without the + FULL option will report its progress in the + pg_stat_progress_vacuum view. Backends running + VACUUM FULL will instead report their progress in the + pg_stat_progress_cluster view. See + and + for details. + @@ -407,6 +456,8 @@ VACUUM (VERBOSE, ANALYZE) onek; + + diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index 95d6894cb03a..223b986b920d 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -28,8 +28,8 @@ PostgreSQL documentation - + table ( column [,...] ) @@ -44,8 +44,8 @@ PostgreSQL documentation connection-option option - + @@ -62,7 +62,7 @@ PostgreSQL documentation vacuumdb is a wrapper around the SQL - command . + command VACUUM. There is no effective difference between vacuuming and analyzing databases via this utility and via other methods for accessing the server. @@ -92,12 +92,15 @@ PostgreSQL documentation - Specifies the name of the database to be cleaned or analyzed. - If this is not specified and (or - ) is not used, the database name is read + Specifies the name of the database to be cleaned or analyzed, + when / is not used. + If this is not specified, the database name is read from the environment variable PGDATABASE. If that is not set, the user name specified for the connection is - used. + used. The dbname can be a connection string. If so, + connection string parameters will override any conflicting command + line options. @@ -148,6 +151,21 @@ PostgreSQL documentation + + + + + Always remove index entries pointing to dead tuples. + + + + This option is only available for servers running + PostgreSQL 12 and later. + + + + + @@ -155,8 +173,8 @@ PostgreSQL documentation Execute the vacuum or analyze commands in parallel by running njobs - commands simultaneously. This option reduces the time of the - processing but it also increases the load on the database server. + commands simultaneously. This option may reduce the processing time + but it also increases the load on the database server. vacuumdb will open @@ -241,6 +259,21 @@ PostgreSQL documentation + + + + + Skip the TOAST table associated with the table to vacuum, if any. + + + + This option is only available for servers running + PostgreSQL 14 and later. + + + + + @@ -257,11 +290,11 @@ PostgreSQL documentation - - + + - Specify the parallel degree of parallel vacuum. + Specify the number of parallel workers for parallel vacuum. This allows the vacuum to leverage multiple CPUs to process indexes. See . @@ -471,10 +504,16 @@ PostgreSQL documentation - Specifies the name of the database to connect to discover what other - databases should be vacuumed. If not specified, the - postgres database will be used, - and if that does not exist, template1 will be used. + Specifies the name of the database to connect to to discover which + databases should be vacuumed, + when / is used. + If not specified, the postgres database will be used, + or if that does not exist, template1 will be used. + This can be a connection + string. If so, connection string parameters will override any + conflicting command line options. Also, connection string parameters + other than the database name itself will be re-used when connecting + to other databases. diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml new file mode 100644 index 000000000000..da421ff24e25 --- /dev/null +++ b/doc/src/sgml/reference.sgml @@ -0,0 +1,295 @@ + + + + Reference + + + + The entries in this Reference are meant to provide in reasonable + length an authoritative, complete, and formal summary about their + respective subjects. More information about the use of + PostgreSQL, in narrative, tutorial, or + example form, can be found in other parts of this book. See the + cross-references listed on each reference page. + + + + The reference entries are also available as traditional + man pages. + + + + + SQL Commands + + + + This part contains reference information for the + SQL commands supported by + PostgreSQL. By SQL the + language in general is meant; information about the standards + conformance and compatibility of each command can be found on the + respective reference page. + + + + &abort; + &alterAggregate; + &alterCollation; + &alterConversion; + &alterDatabase; + &alterDefaultPrivileges; + &alterDomain; + &alterEventTrigger; + &alterExtension; + &alterForeignDataWrapper; + &alterForeignTable; + &alterFunction; + &alterGroup; + &alterIndex; + &alterLanguage; + &alterLargeObject; + &alterMaterializedView; + &alterOperator; + &alterOperatorClass; + &alterOperatorFamily; + &alterPolicy; + &alterProcedure; + &alterPublication; + &alterRole; + &alterRoutine; + &alterRule; + &alterSchema; + &alterSequence; + &alterServer; + &alterStatistics; + &alterSubscription; + &alterSystem; + &alterTable; + &alterTableSpace; + &alterTSConfig; + &alterTSDictionary; + &alterTSParser; + &alterTSTemplate; + &alterTrigger; + &alterType; + &alterUser; + &alterUserMapping; + &alterView; + &analyze; + &begin; + &call; + &checkpoint; + &close; + &cluster; + &commentOn; + &commit; + &commitPrepared; + ©Table; + &createAccessMethod; + &createAggregate; + &createCast; + &createCollation; + &createConversion; + &createDatabase; + &createDomain; + &createEventTrigger; + &createExtension; + &createForeignDataWrapper; + &createForeignTable; + &createFunction; + &createGroup; + &createIndex; + &createLanguage; + &createMaterializedView; + &createOperator; + &createOperatorClass; + &createOperatorFamily; + &createPolicy; + &createProcedure; + &createPublication; + &createRole; + &createRule; + &createSchema; + &createSequence; + &createServer; + &createStatistics; + &createSubscription; + &createTable; + &createTableAs; + &createTableSpace; + &createTSConfig; + &createTSDictionary; + &createTSParser; + &createTSTemplate; + &createTransform; + &createTrigger; + &createType; + &createUser; + &createUserMapping; + &createView; + &deallocate; + &declare; + &delete; + &discard; + &do; + &dropAccessMethod; + &dropAggregate; + &dropCast; + &dropCollation; + &dropConversion; + &dropDatabase; + &dropDomain; + &dropEventTrigger; + &dropExtension; + &dropForeignDataWrapper; + &dropForeignTable; + &dropFunction; + &dropGroup; + &dropIndex; + &dropLanguage; + &dropMaterializedView; + &dropOperator; + &dropOperatorClass; + &dropOperatorFamily; + &dropOwned; + &dropPolicy; + &dropProcedure; + &dropPublication; + &dropRole; + &dropRoutine; + &dropRule; + &dropSchema; + &dropSequence; + &dropServer; + &dropStatistics; + &dropSubscription; + &dropTable; + &dropTableSpace; + &dropTSConfig; + &dropTSDictionary; + &dropTSParser; + &dropTSTemplate; + &dropTransform; + &dropTrigger; + &dropType; + &dropUser; + &dropUserMapping; + &dropView; + &end; + &execute; + &explain; + &fetch; + &grant; + &importForeignSchema; + &insert; + &listen; + &load; + &lock; + &move; + ¬ify; + &prepare; + &prepareTransaction; + &reassignOwned; + &refreshMaterializedView; + &reindex; + &releaseSavepoint; + &reset; + &revoke; + &rollback; + &rollbackPrepared; + &rollbackTo; + &savepoint; + &securityLabel; + &select; + &selectInto; + &set; + &setConstraints; + &setRole; + &setSessionAuth; + &setTransaction; + &show; + &startTransaction; + &truncate; + &unlisten; + &update; + &vacuum; + &values; + + + + + PostgreSQL Client Applications + + + + This part contains reference information for + PostgreSQL client applications and + utilities. Not all of these commands are of general utility; some + might require special privileges. The common feature of these + applications is that they can be run on any host, independent of + where the database server resides. + + + + When specified on the command line, user and database names have + their case preserved — the presence of spaces or special + characters might require quoting. Table names and other identifiers + do not have their case preserved, except where documented, and + might require quoting. + + + + &clusterdb; + &createdb; + &createuser; + &dropdb; + &dropuser; + &ecpgRef; + &pgamcheck; + &pgBasebackup; + &pgbench; + &pgConfig; + &pgDump; + &pgDumpall; + &pgIsready; + &pgReceivewal; + &pgRecvlogical; + &pgRestore; + &pgVerifyBackup; + &psqlRef; + &reindexdb; + &vacuumdb; + + + + + PostgreSQL Server Applications + + + + This part contains reference information for + PostgreSQL server applications and + support utilities. These commands can only be run usefully on the + host where the database server resides. Other utility programs + are listed in . + + + + &initdb; + &pgarchivecleanup; + &pgChecksums; + &pgControldata; + &pgCtl; + &pgResetwal; + &pgRewind; + &pgtestfsync; + &pgtesttiming; + &pgupgrade; + &pgwaldump; + &postgres; + &postmaster; + + + + diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml new file mode 100644 index 000000000000..cb401a45b35a --- /dev/null +++ b/doc/src/sgml/regress.sgml @@ -0,0 +1,884 @@ + + + + Regression Tests + + + regression tests + + + + test + + + + The regression tests are a comprehensive set of tests for the SQL + implementation in PostgreSQL. They test + standard SQL operations as well as the extended capabilities of + PostgreSQL. + + + + Running the Tests + + + The regression tests can be run against an already installed and + running server, or using a temporary installation within the build + tree. Furthermore, there is a parallel and a + sequential mode for running the tests. The + sequential method runs each test script alone, while the + parallel method starts up multiple server processes to run groups + of tests in parallel. Parallel testing adds confidence that + interprocess communication and locking are working correctly. + + + + Running the Tests Against a Temporary Installation + + + To run the parallel regression tests after building but before installation, + type: + +make check + + in the top-level directory. (Or you can change to + src/test/regress and run the command there.) + At the end you should see something like: + + +======================= + All 193 tests passed. +======================= + + + or otherwise a note about which tests failed. See below before assuming that a + failure represents a serious problem. + + + + Because this test method runs a temporary server, it will not work + if you did the build as the root user, since the server will not start as + root. Recommended procedure is not to do the build as root, or else to + perform testing after completing the installation. + + + + If you have configured PostgreSQL to install + into a location where an older PostgreSQL + installation already exists, and you perform make check + before installing the new version, you might find that the tests fail + because the new programs try to use the already-installed shared + libraries. (Typical symptoms are complaints about undefined symbols.) + If you wish to run the tests before overwriting the old installation, + you'll need to build with configure --disable-rpath. + It is not recommended that you use this option for the final installation, + however. + + + + The parallel regression test starts quite a few processes under your + user ID. Presently, the maximum concurrency is twenty parallel test + scripts, which means forty processes: there's a server process and a + psql process for each test script. + So if your system enforces a per-user limit on the number of processes, + make sure this limit is at least fifty or so, else you might get + random-seeming failures in the parallel test. If you are not in + a position to raise the limit, you can cut down the degree of parallelism + by setting the MAX_CONNECTIONS parameter. For example: + +make MAX_CONNECTIONS=10 check + + runs no more than ten tests concurrently. + + + + + Running the Tests Against an Existing Installation + + + To run the tests after installation (see ), + initialize a data directory and start the + server as explained in , then type: + +make installcheck + +or for a parallel test: + +make installcheck-parallel + + The tests will expect to contact the server at the local host and the + default port number, unless directed otherwise by PGHOST and + PGPORT environment variables. The tests will be run in a + database named regression; any existing database by this name + will be dropped. + + + + The tests will also transiently create some cluster-wide objects, such as + roles, tablespaces, and subscriptions. These objects will have names + beginning with regress_. Beware of + using installcheck mode with an installation that has + any actual global objects named that way. + + + + + Additional Test Suites + + + The make check and make installcheck commands + run only the core regression tests, which test built-in + functionality of the PostgreSQL server. The source + distribution contains many additional test suites, most of them having + to do with add-on functionality such as optional procedural languages. + + + + To run all test suites applicable to the modules that have been selected + to be built, including the core tests, type one of these commands at the + top of the build tree: + +make check-world +make installcheck-world + + These commands run the tests using temporary servers or an + already-installed server, respectively, just as previously explained + for make check and make installcheck. Other + considerations are the same as previously explained for each method. + Note that make check-world builds a separate instance + (temporary data directory) for each tested module, so it requires more + time and disk space than make installcheck-world. + + + + On a modern machine with multiple CPU cores and no tight operating-system + limits, you can make things go substantially faster with parallelism. + The recipe that most PostgreSQL developers actually use for running all + tests is something like + +make check-world -j8 >/dev/null + + with a limit near to or a bit more than the number + of available cores. Discarding stdout + eliminates chatter that's not interesting when you just want to verify + success. (In case of failure, the stderr + messages are usually enough to determine where to look closer.) + + + + Alternatively, you can run individual test suites by typing + make check or make installcheck in the appropriate + subdirectory of the build tree. Keep in mind that make + installcheck assumes you've installed the relevant module(s), not + only the core server. + + + + The additional tests that can be invoked this way include: + + + + + + Regression tests for optional procedural languages. + These are located under src/pl. + + + + + Regression tests for contrib modules, + located under contrib. + Not all contrib modules have tests. + + + + + Regression tests for the ECPG interface library, + located in src/interfaces/ecpg/test. + + + + + Tests for core-supported authentication methods, + located in src/test/authentication. + (See below for additional authentication-related tests.) + + + + + Tests stressing behavior of concurrent sessions, + located in src/test/isolation. + + + + + Tests for crash recovery and physical replication, + located in src/test/recovery. + + + + + Tests for logical replication, + located in src/test/subscription. + + + + + Tests of client programs, located under src/bin. + + + + + + When using installcheck mode, these tests will create + and destroy test databases whose names + include regression, for + example pl_regression + or contrib_regression. Beware of + using installcheck mode with an installation that has + any non-test databases named that way. + + + + Some of these auxiliary test suites use the TAP infrastructure explained + in . + The TAP-based tests are run only when PostgreSQL was configured with the + option . This is recommended for + development, but can be omitted if there is no suitable Perl installation. + + + + Some test suites are not run by default, either because they are not secure + to run on a multiuser system or because they require special software. You + can decide which test suites to run additionally by setting the + make or environment variable + PG_TEST_EXTRA to a whitespace-separated list, for + example: + +make check-world PG_TEST_EXTRA='kerberos ldap ssl' + + The following values are currently supported: + + + kerberos + + + Runs the test suite under src/test/kerberos. This + requires an MIT Kerberos installation and opens TCP/IP listen sockets. + + + + + + ldap + + + Runs the test suite under src/test/ldap. This + requires an OpenLDAP installation and opens + TCP/IP listen sockets. + + + + + + ssl + + + Runs the test suite under src/test/ssl. This opens TCP/IP listen sockets. + + + + + + Tests for features that are not supported by the current build + configuration are not run even if they are mentioned in + PG_TEST_EXTRA. + + + + In addition, there are tests in src/test/modules + which will be run by make check-world but not + by make installcheck-world. This is because they + install non-production extensions or have other side-effects that are + considered undesirable for a production installation. You can + use make install and make + installcheck in one of those subdirectories if you wish, + but it's not recommended to do so with a non-test server. + + + + + Locale and Encoding + + + By default, tests using a temporary installation use the + locale defined in the current environment and the corresponding + database encoding as determined by initdb. It + can be useful to test different locales by setting the appropriate + environment variables, for example: + +make check LANG=C +make check LC_COLLATE=en_US.utf8 LC_CTYPE=fr_CA.utf8 + + For implementation reasons, setting LC_ALL does not + work for this purpose; all the other locale-related environment + variables do work. + + + + When testing against an existing installation, the locale is + determined by the existing database cluster and cannot be set + separately for the test run. + + + + You can also choose the database encoding explicitly by setting + the variable ENCODING, for example: + +make check LANG=C ENCODING=EUC_JP + + Setting the database encoding this way typically only makes sense + if the locale is C; otherwise the encoding is chosen automatically + from the locale, and specifying an encoding that does not match + the locale will result in an error. + + + + The database encoding can be set for tests against either a temporary or + an existing installation, though in the latter case it must be + compatible with the installation's locale. + + + + + Custom Server Settings + + + Custom server settings to use when running a regression test suite can be + set in the PGOPTIONS environment variable (for settings + that allow this): + +make check PGOPTIONS="-c log_checkpoints=on -c work_mem=50MB" + + When running against a temporary installation, custom settings can also be + set by supplying a pre-written postgresql.conf: + +echo 'log_checkpoints = on' > test_postgresql.conf +echo 'work_mem = 50MB' >> test_postgresql.conf +make check EXTRA_REGRESS_OPTS="--temp-config=test_postgresql.conf" + + + + + This can be useful to enable additional logging, adjust resource limits, + or enable extra run-time checks such as . + + + + + Extra Tests + + + The core regression test suite contains a few test files that are not + run by default, because they might be platform-dependent or take a + very long time to run. You can run these or other extra test + files by setting the variable EXTRA_TESTS. For + example, to run the numeric_big test: + +make check EXTRA_TESTS=numeric_big + + + + + + Testing Hot Standby + + + The source distribution also contains regression tests for the static + behavior of Hot Standby. These tests require a running primary server + and a running standby server that is accepting new WAL changes from the + primary (using either file-based log shipping or streaming replication). + Those servers are not automatically created for you, nor is replication + setup documented here. Please check the various sections of the + documentation devoted to the required commands and related issues. + + + + To run the Hot Standby tests, first create a database + called regression on the primary: + +psql -h primary -c "CREATE DATABASE regression" + + Next, run the preparatory script + src/test/regress/sql/hs_primary_setup.sql + on the primary in the regression database, for example: + +psql -h primary -f src/test/regress/sql/hs_primary_setup.sql regression + + Allow these changes to propagate to the standby. + + + + Now arrange for the default database connection to be to the standby + server under test (for example, by setting the PGHOST and + PGPORT environment variables). + Finally, run make standbycheck in the regression directory: + +cd src/test/regress +make standbycheck + + + + + Some extreme behaviors can also be generated on the primary using the + script src/test/regress/sql/hs_primary_extremes.sql + to allow the behavior of the standby to be tested. + + + + + + Test Evaluation + + + Some properly installed and fully functional + PostgreSQL installations can + fail some of these regression tests due to + platform-specific artifacts such as varying floating-point representation + and message wording. The tests are currently evaluated using a simple + diff comparison against the outputs + generated on a reference system, so the results are sensitive to + small system differences. When a test is reported as + failed, always examine the differences between + expected and actual results; you might find that the + differences are not significant. Nonetheless, we still strive to + maintain accurate reference files across all supported platforms, + so it can be expected that all tests pass. + + + + The actual outputs of the regression tests are in files in the + src/test/regress/results directory. The test + script uses diff to compare each output + file against the reference outputs stored in the + src/test/regress/expected directory. Any + differences are saved for your inspection in + src/test/regress/regression.diffs. + (When running a test suite other than the core tests, these files + of course appear in the relevant subdirectory, + not src/test/regress.) + + + + If you don't + like the diff options that are used by default, set the + environment variable PG_REGRESS_DIFF_OPTS, for + instance PG_REGRESS_DIFF_OPTS='-c'. (Or you + can run diff yourself, if you prefer.) + + + + If for some reason a particular platform generates a failure + for a given test, but inspection of the output convinces you that + the result is valid, you can add a new comparison file to silence + the failure report in future test runs. See + for details. + + + + Error Message Differences + + + Some of the regression tests involve intentional invalid input + values. Error messages can come from either the + PostgreSQL code or from the host + platform system routines. In the latter case, the messages can + vary between platforms, but should reflect similar + information. These differences in messages will result in a + failed regression test that can be validated by + inspection. + + + + + Locale Differences + + + If you run the tests against a server that was + initialized with a collation-order locale other than C, then + there might be differences due to sort order and subsequent + failures. The regression test suite is set up to handle this + problem by providing alternate result files that together are + known to handle a large number of locales. + + + + To run the tests in a different locale when using the + temporary-installation method, pass the appropriate + locale-related environment variables on + the make command line, for example: + +make check LANG=de_DE.utf8 + + (The regression test driver unsets LC_ALL, so it + does not work to choose the locale using that variable.) To use + no locale, either unset all locale-related environment variables + (or set them to C) or use the following + special invocation: + +make check NO_LOCALE=1 + + When running the tests against an existing installation, the + locale setup is determined by the existing installation. To + change it, initialize the database cluster with a different + locale by passing the appropriate options + to initdb. + + + + In general, it is advisable to try to run the + regression tests in the locale setup that is wanted for + production use, as this will exercise the locale- and + encoding-related code portions that will actually be used in + production. Depending on the operating system environment, you + might get failures, but then you will at least know what + locale-specific behaviors to expect when running real + applications. + + + + + Date and Time Differences + + + Most of the date and time results are dependent on the time zone + environment. The reference files are generated for time zone + PST8PDT (Berkeley, California), and there will be + apparent failures if the tests are not run with that time zone setting. + The regression test driver sets environment variable + PGTZ to PST8PDT, which normally + ensures proper results. + + + + + Floating-Point Differences + + + Some of the tests involve computing 64-bit floating-point numbers (double + precision) from table columns. Differences in + results involving mathematical functions of double + precision columns have been observed. The float8 and + geometry tests are particularly prone to small differences + across platforms, or even with different compiler optimization settings. + Human eyeball comparison is needed to determine the real + significance of these differences which are usually 10 places to + the right of the decimal point. + + + + Some systems display minus zero as -0, while others + just show 0. + + + + Some systems signal errors from pow() and + exp() differently from the mechanism + expected by the current PostgreSQL + code. + + + + + Row Ordering Differences + + +You might see differences in which the same rows are output in a +different order than what appears in the expected file. In most cases +this is not, strictly speaking, a bug. Most of the regression test +scripts are not so pedantic as to use an ORDER BY for every single +SELECT, and so their result row orderings are not well-defined +according to the SQL specification. In practice, since we are +looking at the same queries being executed on the same data by the same +software, we usually get the same result ordering on all platforms, +so the lack of ORDER BY is not a problem. Some queries do exhibit +cross-platform ordering differences, however. When testing against an +already-installed server, ordering differences can also be caused by +non-C locale settings or non-default parameter settings, such as custom values +of work_mem or the planner cost parameters. + + + +Therefore, if you see an ordering difference, it's not something to +worry about, unless the query does have an ORDER BY that your +result is violating. However, please report it anyway, so that we can add an +ORDER BY to that particular query to eliminate the bogus +failure in future releases. + + + +You might wonder why we don't order all the regression test queries explicitly +to get rid of this issue once and for all. The reason is that that would +make the regression tests less useful, not more, since they'd tend +to exercise query plan types that produce ordered results to the +exclusion of those that don't. + + + + + Insufficient Stack Depth + + + If the errors test results in a server crash + at the select infinite_recurse() command, it means that + the platform's limit on process stack size is smaller than the + parameter indicates. This + can be fixed by running the server under a higher stack + size limit (4MB is recommended with the default value of + max_stack_depth). If you are unable to do that, an + alternative is to reduce the value of max_stack_depth. + + + + On platforms supporting getrlimit(), the server should + automatically choose a safe value of max_stack_depth; + so unless you've manually overridden this setting, a failure of this + kind is a reportable bug. + + + + + The <quote>random</quote> Test + + + The random test script is intended to produce + random results. In very rare cases, this causes that regression + test to fail. Typing: + +diff results/random.out expected/random.out + + should produce only one or a few lines of differences. You need + not worry unless the random test fails repeatedly. + + + + + Configuration Parameters + + + When running the tests against an existing installation, some non-default + parameter settings could cause the tests to fail. For example, changing + parameters such as enable_seqscan or + enable_indexscan could cause plan changes that would + affect the results of tests that use EXPLAIN. + + + + + + + Variant Comparison Files + + + Since some of the tests inherently produce environment-dependent + results, we have provided ways to specify alternate expected + result files. Each regression test can have several comparison files + showing possible results on different platforms. There are two + independent mechanisms for determining which comparison file is used + for each test. + + + + The first mechanism allows comparison files to be selected for + specific platforms. There is a mapping file, + src/test/regress/resultmap, that defines + which comparison file to use for each platform. + To eliminate bogus test failures for a particular platform, + you first choose or make a variant result file, and then add a line to the + resultmap file. + + + + Each line in the mapping file is of the form + +testname:output:platformpattern=comparisonfilename + + The test name is just the name of the particular regression test + module. The output value indicates which output file to check. For the + standard regression tests, this is always out. The + value corresponds to the file extension of the output file. + The platform pattern is a pattern in the style of the Unix + tool expr (that is, a regular expression with an implicit + ^ anchor at the start). It is matched against the + platform name as printed by config.guess. + The comparison file name is the base name of the substitute result + comparison file. + + + + For example: some systems lack a working strtof function, + for which our workaround causes rounding errors in the + float4 regression test. + Therefore, we provide a variant comparison file, + float4-misrounded-input.out, which includes + the results to be expected on these systems. To silence the bogus + failure message on HP-UX 10 + platforms, resultmap includes: + +float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out + + which will trigger on any machine where the output of + config.guess matches hppa.*-hp-hpux10.*. + Other lines in resultmap select the variant comparison + file for other platforms where it's appropriate. + + + + The second selection mechanism for variant comparison files is + much more automatic: it simply uses the best match among + several supplied comparison files. The regression test driver + script considers both the standard comparison file for a test, + testname.out, and variant files named + testname_digit.out + (where the digit is any single digit + 0-9). If any such file is an exact match, + the test is considered to pass; otherwise, the one that generates + the shortest diff is used to create the failure report. (If + resultmap includes an entry for the particular + test, then the base testname is the substitute + name given in resultmap.) + + + + For example, for the char test, the comparison file + char.out contains results that are expected + in the C and POSIX locales, while + the file char_1.out contains results sorted as + they appear in many other locales. + + + + The best-match mechanism was devised to cope with locale-dependent + results, but it can be used in any situation where the test results + cannot be predicted easily from the platform name alone. A limitation of + this mechanism is that the test driver cannot tell which variant is + actually correct for the current environment; it will just pick + the variant that seems to work best. Therefore it is safest to use this + mechanism only for variant results that you are willing to consider + equally valid in all contexts. + + + + + + TAP Tests + + + Various tests, particularly the client program tests + under src/bin, use the Perl TAP tools and are run + using the Perl testing program prove. You can pass + command-line options to prove by setting + the make variable PROVE_FLAGS, for example: + +make -C src/bin check PROVE_FLAGS='--timer' + + See the manual page of prove for more information. + + + + The make variable PROVE_TESTS + can be used to define a whitespace-separated list of paths relative + to the Makefile invoking prove + to run the specified subset of tests instead of the default + t/*.pl. For example: + +make check PROVE_TESTS='t/001_test1.pl t/003_test3.pl' + + + + + The TAP tests require the Perl module IPC::Run. + This module is available from CPAN or an operating system package. + + + + Generically speaking, the TAP tests will test the executables in a + previously-installed installation tree if you say make + installcheck, or will build a new local installation tree from + current sources if you say make check. In either + case they will initialize a local instance (data directory) and + transiently run a server in it. Some of these tests run more than one + server. Thus, these tests can be fairly resource-intensive. + + + + It's important to realize that the TAP tests will start test server(s) + even when you say make installcheck; this is unlike + the traditional non-TAP testing infrastructure, which expects to use an + already-running test server in that case. Some PostgreSQL + subdirectories contain both traditional-style and TAP-style tests, + meaning that make installcheck will produce a mix of + results from temporary servers and the already-running test server. + + + + + Test Coverage Examination + + + The PostgreSQL source code can be compiled with coverage testing + instrumentation, so that it becomes possible to examine which + parts of the code are covered by the regression tests or any other + test suite that is run with the code. This is currently supported + when compiling with GCC, and it requires the gcov + and lcov programs. + + + + A typical workflow looks like this: + +./configure --enable-coverage ... OTHER OPTIONS ... +make +make check # or other test suite +make coverage-html + + Then point your HTML browser + to coverage/index.html. + + + + If you don't have lcov or prefer text output over an + HTML report, you can run + +make coverage + + instead of make coverage-html, which will + produce .gcov output files for each source file + relevant to the test. (make coverage and make + coverage-html will overwrite each other's files, so mixing them + might be confusing.) + + + + You can run several different tests before making the coverage report; + the execution counts will accumulate. If you want + to reset the execution counts between test runs, run: + +make coverage-clean + + + + + You can run the make coverage-html or make + coverage command in a subdirectory if you want a coverage + report for only a portion of the code tree. + + + + Use make distclean to clean up when done. + + + + diff --git a/doc/src/sgml/release-14.sgml b/doc/src/sgml/release-14.sgml index 9116a34b91f8..000f4e64c42d 100644 --- a/doc/src/sgml/release-14.sgml +++ b/doc/src/sgml/release-14.sgml @@ -6,11 +6,4029 @@ Release date: - 2021-??-?? + 2021-??-?? (AS OF 2021-06-20) - - This is just a placeholder for now. - + + Overview + + + PostgreSQL 14 contains many new features and + enhancements, including: + + + + + + + + + + + The above items and other new features + of PostgreSQL 14 are explained in more + detail in the sections below. + + + + + + + Migration to Version 14 + + + A dump/restore using or use of or logical replication is required for those + wishing to migrate data from any previous release. See for general information on migrating to new major + releases. + + + + Version 14 contains a number of changes that may affect compatibility + with previous releases. Observe the following incompatibilities: + + + + + + + + + Prevent the containment operators (<@ and @>) for from using GiST indexes (Tom Lane) + + + + Previously a full GiST index scan was required, so just avoid + that and scan the heap, which is faster. Indexes created for this + purpose should be removed. + + + + + + + + Remove deprecated containment operators @ and ~ for built-in + geometric data types and + contrib modules , , + , and (Justin Pryzby) + + + + The more consistent <@ and @> have been recommended for + many years. + + + + + + + + Fix to_tsquery() + and websearch_to_tsquery() to properly parse + query text containing discarded tokens (Alexander Korotkov) + + + + Certain discarded tokens, like underscore, caused the output of + these functions to produce incorrect tsquery output, e.g., both + websearch_to_tsquery('"pg_class pg"') and to_tsquery('pg_class + <-> pg') used to output '( pg & class ) <-> pg', + but now both output 'pg <-> class <-> pg'. + + + + + + + + Fix websearch_to_tsquery() + to properly parse multiple adjacent discarded tokens in quotes + (Alexander Korotkov) + + + + Previously, quoted text that contained multiple adjacent discarded + tokens were treated as multiple tokens, causing incorrect tsquery + output, e.g., websearch_to_tsquery('"aaa: bbb"') used to output + 'aaa <2> bbb', but now outputs 'aaa <-> bbb'. + + + + + + + + Change the default of the + server parameter to scram-sha-256 (Peter + Eisentraut) + + + + Previously it was md5. All new passwords will + be stored as SHA256 unless this server variable is changed or + the password is specified in md5 format. Also, the legacy (and + undocumented) boolean-like values which were previously synonyms + for md5 are no longer accepted. + + + + + + + + Overhaul the specification of clientcert in pg_hba.conf + (Kyotaro Horiguchi) + + + + Values + 1/0/no-verify + are no longer supported; only the strings + verify-ca and verify-full + can be used. Also, disallow verify-ca if cert + authentication is enabled since cert requires + verify-full checking. + + + + + + + + Remove support for SSL + compression (Daniel Gustafsson, Michael Paquier) + + + + This was already disabled by default in previous Postgres releases, + and most modern OpenSSL and TLS versions no + longer support it. + + + + + + + + Remove server and libpq support + for the version 2 wire protocol + (Heikki Linnakangas) + + + + This was last used as the default in Postgres 7.3 (year 2002). + + + + + + + + Change EXTRACT + to return the NUMERIC data type (Peter Eisentraut) + + + + EXTRACT(date) now throws an error for units + that are not part of the date data type. + + + + + + + + Fix handling of infinite window function ranges + (Tom Lane) + + + + Previously window frame clauses like 'inf' PRECEDING AND + 'inf' FOLLOWING returned incorrect results. + + + + + + + + Prevent 's function + normal_rand() from accepting negative values + (Ashutosh Bapat) + + + + Negative values produced undesirable results. + + + + + + + + Change var_samp() + and stddev_samp() with numeric parameters to + return NULL for a single NaN value (Tom Lane) + + + + Previously NaN was returned. + + + + + + + + User-defined objects that reference some built-in array functions + along with their argument types must be recreated (Tom Lane) + + + + Specifically, array_append(), + array_prepend(), + array_cat(), + array_position(), + array_positions(), + array_remove(), + array_replace(), or width_bucket() + used to take anyarray arguments but now take + anycompatiblearray. Therefore, user-defined objects + like aggregates and operators that reference old array function + signatures must be dropped before upgrading and recreated once the + upgrade completes. + + + + + + + + Remove factorial operators ! and + !! (Mark Dilger) + + + + The factorial() + function is still supported. Also remove function + numeric_fac(). + + + + + + + + Disallow factorial() of negative numbers + (Peter Eisentraut) + + + + Previously such cases returned 1. + + + + + + + + Remove support for postfix + (right-unary) operators (Mark Dilger) + + + + pg_dump and + pg_upgrade will warn if postfix operators + are being dumped. + + + + + + + + Allow \D and \W shorthands to + match newlines in regular + expression newline-sensitive mode (Tom Lane) + + + + Previously they did not match; [^[:digit:]] or + [^[:word:]] can be used to get the old behavior. + + + + + + + + Improve handling of regular expression back-references (Tom Lane) + + + + For example, disregard ^ in its expansion in + \1 in (^\d+).*\1. + + + + + + + + Disallow \w as range start/end in character + classes (Tom Lane) + + + + This previously was allowed but produced incorrect results. + + + + + + + + Require custom server + variable names to use only character which are valid for + unquoted SQL identifiers (Tom Lane) + + + + + + + + Remove server variable + vacuum_cleanup_index_scale_factor (Peter Geoghegan) + + + + This setting was ignored starting in + PostgreSQL version 13.3. + + + + + + + + Return false for has_column_privilege() + checks on non-existent or dropped columns when using attribute + numbers (Joe Conway) + + + + Previously such attribute numbers returned an invalid column error. + + + + + + + + Pass doubled quote marks in + SQL command strings literally (Tom Lane) + + + + Previously 'abc''def' was passed to the server + as 'abc'def', and "abc""def" + was passed as "abc"def". + + + + + + + + Disallow single-quoting of the language name in the + CREATE/DROP + LANGUAGE command (Peter Eisentraut) + + + + + + + + Remove contrib program pg_standby + (Justin Pryzby) + + + + + + + + Remove composite + types for sequences or toast tables (Tom Lane) + + + + + + + + Remove operator_precedence_warning setting + (Tom Lane) + + + + This was needed for warning applications about + PostgreSQL 9.5 changes. + + + + + + + + + Changes + + + Below you will find a detailed account of the changes between + PostgreSQL 14 and the previous major + release. + + + + Server + + + + + + + + Add predefined roles pg_read_all_data + and pg_write_all_data (Stephen Frost) + + + + These non-login roles can be used to give read or write permission + to all tables, views, and sequences. + + + + + + + + Add a predefined role to match the database owner (Noah Misch) + + + + It is called pg_database_owner; + this is useful in template databases. + + + + + + + + Remove temporary files after backend crashes (Euler Taveira) + + + + These files were previously retained for debugging + purposes; deletion can be disabled with . + + + + + + + + Allow long-running queries to be canceled if the client disconnects + (Sergey Cherkashin, Thomas Munro) + + + + The server variable allows some + supported operating systems to automatically cancel queries by + disconnected clients. + + + + + + + + Add an optional timeout parameter to pg_terminate_backend() + + + + + + + + Allow wide tuples to be always added to almost-empty heap pages + (John Naylor, Floris van Nee) + + + + Previously tuples whose insertion would have exceeded the page's + fill factor were instead + added to new pages. + + + + + + + + Add Server Name Indication (SNI) for + SSL connection packets (Peter Eisentraut) + + + + This can be disabled by turning off client option sslsni. + + + + + + + <link linkend="routine-vacuuming">Vacuuming</link> + + + + + + + + Allow vacuum to skip index vacuuming when the number of removable + index entries is insignificant (Masahiko Sawada, Peter Geoghegan) + + + + The vacuum parameter INDEX_CLEANUP has a + new default of auto to enable this optimization. + + + + + + + + Allow vacuum to eagerly add newly deleted btree pages to the free + space map (Peter Geoghegan) + + + + Previously vacuum could only place preexisting deleted pages in + the free space map. + + + + + + + + Allow vacuum to reclaim space used by unused trailing heap + line pointers (Matthias van de Meent, Peter Geoghegan) + + + + + + + + Speed up vacuuming of databases with many relations (Tatsuhito + Kasahara) + + + + + + + + Reduce the default value of to better reflects current + hardware capabilities (Peter Geoghegan) + + + + + + + + Add ability to skip vacuuming of TOAST tables + (Nathan Bossart) + + + + VACUUM now + has a PROCESS_TOAST option which can be set to + false to disable TOAST processing, and vacuumdb + has a option. + + + + + + + + Have COPY FREEZE + appropriately update page visibility bits (Anastasia Lubennikova, + Pavan Deolasee, Jeff Janes) + + + + + + + + Cause vacuum operations to be more aggressive if the table is near + xid or multixact wraparound (Masahiko Sawada, Peter Geoghegan) + + + + This is controlled by + and . + + + + + + + + Increase warning time and hard limit before transaction id and + multi-transaction wraparound (Noah Misch) + + + + This should reduce the possibility of failures that occur without + having issued warnings about wraparound. + + + + + + + + Autovacuum now analyzes + partitioned tables (Yuzuko Hosoya, Álvaro Herrera) + + + + Insert, update, and delete tuple counts from partitions are now + propagated to their parent tables so autovacuum knows when to + process them. + + + + + + + + Add per-index information to autovacuum logging + output (Masahiko Sawada) + + + + + + + + <link linkend="ddl-partitioning">Partitioning</link> + + + + + + + + Improve the performance of updates/deletes on partitioned tables + when only a few partitions are affected (Amit Langote, Tom Lane) + + + + This also allows updates/deletes on partitioned tables to use + execution-time partition pruning. + + + + + + + + Allow partitions to be detached in a non-blocking manner + (Álvaro Herrera) + + + + The syntax is ALTER TABLE ... DETACH PARTITION + ... CONCURRENTLY, and FINALIZE. + + + + + + + + Allow arbitrary collations of partition boundary values (Tom Lane) + + + + Previously it had to match the collation of the partition key. + + + + + + + + + Indexes + + + + + + + + Allow btree index additions to remove expired index entries + to prevent page splits (Peter Geoghegan) + + + + This is particularly helpful for reducing index bloat on tables + whose indexed columns are frequently updated. + + + + + + + + Allow BRIN indexes + to record multiple min/max values per range (Tomas Vondra) + + + + This is useful if there are groups of values in each page range. + + + + + + + + Allow BRIN indexes to use bloom filters + (Tomas Vondra) + + + + This allows BRIN indexes to be used effectively + with data that is not physically localized in the heap. + + + + + + + + Allow some GiST indexes to be built + by presorting the data (Andrey Borodin) + + + + Presorting happens automatically and allows for faster index + creation and smaller indexes. + + + + + + + + Allow SP-GiST to use + INCLUDE'd columns (Pavel Borisov) + + + + + + + + + Optimizer + + + + + + + + Allow hash lookup of IN clause with many + constants (James Coleman, David Rowley) + + + + Previously the only option was to sequentially scan the list + of constants. + + + + + + + + Increase the number of places extended statistics can + be used for OR clause estimation (Tomas Vondra, + Dean Rasheed) + + + + + + + + Allow extended statistics on expressions (Tomas Vondra) + + + + This allows statistics on a group of expressions and columns, + rather than only columns like previously. System view pg_stats_ext_exprs + reports such statistics. ALTER TABLE ... ALTER COLUMN + ... TYPE RESETS STASTISTICS? + + + + + + + + Allow efficient heap scanning of a range of TIDs (Edmund + Horner, David Rowley) + + + + Previously a sequential scan was required for non-equality + TID specifications. + + + + + + + + Fix EXPLAIN CREATE TABLE + AS and EXPLAIN CREATE MATERIALIZED + VIEW to honor IF NOT EXISTS + (Bharath Rupireddy) + + + + Previously, if the object already existed, + EXPLAIN would fail. + + + + + + + + + General Performance + + + + + + + + Improve the speed of computing MVCC visibility snapshots on systems with many + CPUs and high session counts (Andres Freund) + + + + This also improves performance when there are many idle sessions. + + + + + + + + Add executor method to cache results from the inner-side of nested + loop joins (David Rowley) + + + + This is useful if only a small percentage of rows is checked on + the inner side. + + + + + + + + Allow window functions + to perform incremental sorts (David Rowley) + + + + + + + + Improve the I/O performance of parallel sequential scans (Thomas + Munro, David Rowley) + + + + This was done by allocating blocks in groups to parallel workers. + + + + + + + + Allow a query referencing multiple foreign tables to perform + foreign table scans in parallel (Robert Haas, Kyotaro Horiguchi, + Thomas Munro, Etsuro Fujita) + + + + The postgres_fdw + supports these type of scans if async_capable + is set. + + + + + + + + Allow analyze to do + page prefetching (Stephen Frost) + + + + This is controlled by . + + + + + + + + Improve the performance of regular expression + comparisons (Tom Lane) + + + + + + + + Dramatically improve Unicode normalization (John Naylor) + + + + This speeds normalize() + and IS NORMALIZED. + + + + + + + + Add ability to use LZ4 + compression on TOAST data (Dilip Kumar) + + + + This can be set at the column level, or set as a default via server + setting . + The server must be compiled with + to support this feature; the default is still pglz. + + + + + + + + + Monitoring + + + + + + + + If server variable + is enabled, display the query id in pg_stat_activity, + EXPLAIN + VERBOSE, csvlog, and optionally in + (Julien Rouhaud) + + + + A query id computed by an extension will also be displayed. + + + + + + + + Add system view pg_backend_memory_contexts + to report session memory usage (Atsushi Torikoshi, Fujii Masao) + + + + + + + + Add function pg_log_backend_memory_contexts() + to output the memory contexts of arbitrary backends (Atsushi + Torikoshi) + + + + + + + + Improve logging of auto-vacuum + and auto-analyze (Stephen Frost, Jakub Wartak) + + + + This reports I/O timings for auto-vacuum and auto-analyze if is enabled. Also, report buffer + read and dirty rates for auto-analyze. + + + + + + + + Add information about the original user name supplied by the + client to the output of + (Jacob Champion) + + + + + + + + + System Views + + + + + + + + Add view pg_stat_progress_copy + to report COPY progress (Josef Šimánek, + Matthias van de Meent) + + + + + + + + Add session statistics to the pg_stat_database + system view (Laurenz Albe) + + + + + + + + Add columns to pg_prepared_statements + to report generic and custom plan counts (Atsushi Torikoshi, + Kyotaro Horiguchi) + + + + + + + + Add lock wait start time to pg_locks + (Atsushi Torikoshi) + + + + + + + + Add system view pg_stat_wal + which reports WAL activity (Masahiro Ikeda) + + + + + + + + Add system view pg_stat_replication_slots + to report replication slot activity (Sawada Masahiko, Amit Kapila, + Vignesh C) + + + + The function pg_stat_reset_replication_slot() + resets slot statistics. + + + + + + + + Make the archiver process visible in + pg_stat_activity (Kyotaro Horiguchi) + + + + + + + + Add wait event WalReceiverExit + to report WAL receiver exit wait time (Fujii + Masao) + + + + + + + + Implement information schema view routine_column_usage + to track columns referenced by function and procedure default + expressions (Peter Eisentraut) + + + + + + + + + <acronym>Authentication</acronym> + + + + + + + + Allow the certificate's distinguished name (DN) + to be matched for client certificate authentication (Andrew + Dunstan) + + + + The new pg_hba.conf + keyword clientname=DN allows comparison with + certificate attributes beyond the CN and can + be combined with ident maps. + + + + + + + + Allow pg_hba.conf and pg_ident.conf + records to span multiple lines (Fabien Coelho) + + + + A backslash at the end of a line allows record contents to be + continued on the next line. + + + + + + + + Allow the specification of a certificate revocation list + (CRL) directory (Kyotaro Horiguchi) + + + + This is controlled by server variable and libpq connection option sslcrldir. + Previously only CRL files could be specified. + + + + + + + + Allow passwords of an arbitrary length (Tom Lane, Nathan Bossart) + + + + + + + + + Server Configuration + + + + + + + + Add server setting + to close idle sessions (Li Japin) + + + + This is similar to . + + + + + + + + Change default + to 0.9 (Stephen Frost) + + + + The previous default was 0.5. + + + + + + + + Allow %P in to report the + parallel group leader (Justin Pryzby) + + + + + + + + Allow to specify + paths as individual, comma-separated quoted strings (Ian Lawrence + Barwick) + + + + Previously all the paths had to be in a single quoted string. + + + + + + + + Allow startup allocation of dynamic shared memory (Thomas Munro) + + + + This is controlled by . This allows more + use of huge pages. + + + + + + + + Add setting to control the + size of huge pages used on Linux (Odin Ugedal) + + + + + + + + + + + Streaming Replication and Recovery + + + + + + + + Allow standby servers to be rewound via pg_rewind + (Heikki Linnakangas) + + + + + + + + Allow setting to be changed + during a server reload (Sergei Kornilov) + + + + You can also set restore_command to an empty + string and reload to force recovery to only read from the pg_wal + directory. + + + + + + + + Add server variable to report long recovery + conflict wait times (Bertrand Drouvot, Masahiko Sawada) + + + + + + + + Pause recovery if the primary changes its parameters in a way that + prevents replay on the hot standby (Peter Eisentraut) + + + + Previously the standby would shut down immediately. + + + + + + + + Add function pg_get_wal_replay_pause_state() + to report the recovery state (Dilip Kumar) + + + + It gives more detailed information than pg_is_wal_replay_paused(), + which still exists. + + + + + + + + Add new server-side variable + (Haribabu Kommi, Greg Nancarrow, Tom Lane) + + + + + + + + Speed truncation of small tables during recovery on clusters with + a large number of shared buffers (Kirk Jamison) + + + + + + + + Allow file system sync at the start of crash recovery on Linux + (Thomas Munro) + + + + By default, Postgres opens and fsyncs every data file + at the start of crash recovery. This new setting, =syncfs, + instead syncs each filesystem used by the database cluster. + This allows for faster recovery on systems with many database files. + + + + + + + + Add function pg_xact_commit_timestamp_origin() + to return the commit timestamp and replication origin of the + specified transaction (Movead Li) + + + + + + + + Add the replication origin to the record returned by pg_last_committed_xact() + (Movead Li) + + + + + + + + Allow replication origin + functions to be controlled using standard function permission + controls (Martín Marqués) + + + + Previously these functions could only be executed by super-users, + and this is still the default. + + + + + + + + Improve signal handling reliability (Fujii Masao) + + + + GENERAL ENOUGH? + + + + + + + <link linkend="logical-replication">Logical Replication</link> + + + + + + + + Allow logical replication to stream long in-progress transactions + to subscribers (Dilip Kumar, Amit Kapila, Ajin + Cherian, Tomas Vondra, Nikhil Sontakke, Stas Kelvich) + + + + Previously transactions that exceeded were written to disk + until the transaction completed. + + + + + + + + Enhance the logical replication API to allow + streaming large in-progress transactions (Tomas Vondra, Dilip + Kumar, Amit Kapila) + + + + The output functions begin with stream. + test_decoding also supports these. + + + + + + + + Allow multiple transactions during table sync in logical + replication (Peter Smith, Amit Kapila, and Takamichi Osumi) + + + + + + + + Immediately WAL-log subtransaction and top-level + XID association (Tomas Vondra, Dilip Kumar, Amit + Kapila) + + + + This is useful for logical decoding. + + + + + + + + Enhance logical decoding APIs to handle two-phase commits (Ajin + Cherian, Amit Kapila, Nikhil Sontakke, Stas Kelvich) + + + + This is controlled via pg_create_logical_replication_slot(). + + + + + + + + Generate WAL invalidation messages during + command completion when using logical replication (Dilip Kumar, + Tomas Vondra, Amit Kapila) + + + + When logical replication is disabled, WAL + invalidation messages are generated at transaction completion. + This allows logical streaming of in-progress transactions. + + + + + + + + Allow logical decoding to more efficiently process cache + invalidation messages (Dilip Kumar) + + + + This allows logical decoding + to work efficiently in presence of a large amount of + DDL. + + + + + + + + Allow control over whether logical decoding messages are sent to + the replication stream (David Pirotte, Euler Taveira) + + + + + + + + Allow logical replication subscriptions to use binary transfer mode + (Dave Cramer) + + + + This is faster than text mode, but slightly less robust. + + + + + + + + Allow logical decoding to be filtered by xid (Markus Wanner) + + + + + + + + + + <link linkend="sql-select"><command>SELECT</command></link>, <link linkend="sql-insert"><command>INSERT</command></link> + + + + + + + + Reduce the number of keywords that can't be used as column labels + without AS (Mark Dilger) + + + + There are now 90% fewer restricted keywords. + + + + + + + + Allow an alias to be specified for JOIN's + USING clause (Peter Eisentraut) + + + + The alias is created by using AS after the + USING clause and represents an alias for the + USING columns. + + + + + + + + Allow DISTINCT to be added to GROUP + BY to remove duplicate GROUPING SET + combinations (Vik Fearing) + + + + For example, GROUP BY CUBE (a,b), CUBE (b,c) + will generate duplicate grouping combinations without + DISTINCT. + + + + + + + + Properly handle DEFAULT values for columns in + multi-column inserts (Dean Rasheed) + + + + This used to throw an error. + + + + + + + + Add SQL-standard SEARCH + and CYCLE clauses for common table expressions (Peter + Eisentraut) + + + + This could be accomplished previously using existing syntax. + + + + + + + + Allow the WHERE clause of ON + CONFLICT to be table-qualified (Tom Lane) + + + + Only the target table can be referenced. + + + + + + + + + Utility Commands + + + + + + + + Allow REFRESH + MATERIALIZED VIEW to use parallelism (Bharath + Rupireddy) + + + + + + + + Allow REINDEX + to change the tablespace of the new index (Alexey Kondratov, + Michael Paquier, Justin Pryzby) + + + + This is done by specifying a TABLESPACE clause. + A option was also added to reindexdb + to control this. + + + + + + + + Allow REINDEX to process all child tables or + indexes of a partitioned relation (Justin Pryzby, Michael Paquier) + + + + + + + + Improve the performance of COPY + FROM in binary mode (Bharath Rupireddy, Amit + Langote) + + + + + + + + Preserve SQL standard syntax in view definitions, if possible + (Tom Lane) + + + + Previously non-function call + SQL standard syntax, e.g. EXTRACT, + were converted to non-SQL standard function + calls. + + + + + + + + Add the SQL-standard + clause GRANTED BY to GRANT and REVOKE (Peter + Eisentraut) + + + + + + + + Add OR REPLACE for CREATE TRIGGER + (Takamichi Osumi) + + + + This allows pre-existing triggers to be conditionally replaced. + + + + + + + + Allow TRUNCATE to + operate on foreign tables (Kazutaka Onishi, Kohei KaiGai) + + + + The postgres_fdw + module also now supports this. + + + + + + + + Allow publications to be more easily added and removed (Japin Li) + + + + The new syntax is ALTER SUBSCRIPTION + ... ADD/DROP PUBLICATION. This avoids having to + specify all publications to add/remove entries. + + + + + + + + Add primary keys, unique constraints, and foreign keys to system catalogs (Peter Eisentraut) + + + + This helps GUI tools analyze the system tables. + + + + + + + + Allow CURRENT_ROLE + every place CURRENT_USER is accepted (Peter + Eisentraut) + + + + + + + + + Data Types + + + + + + + + Allow extensions and built-in data types to implement subscripting (Dmitry Dolgov) + + + + Previously subscript handling was hard-coded into the server, so + that subscripting could only be applied to array types. This change + allows subscript notation to be used to extract or assign portions + of a value of any type for which the concept makes sense. + + + + + + + + Allow subscripting of JSONB (Dmitry Dolgov) + + + + JSONB subscripting can be used to extract and assign + to portions of JSONB documents. + + + + + + + + Add support for multirange data + types (Paul Jungwirth, Alexander Korotkov) + + + + These are like range data types, but they allow the specification + of multiple, ordered, non-overlapping ranges. All existing range + types now also support multirange versions. + + + + + + + + Add point operators + <<| and |>> to be strictly above/below geometry + (Emre Hasegeli) + + + + Previously >^ and <^ were marked as performing this test, but + non-point geometric operators used these operators for non-strict + comparisons, leading to confusion. The old operators still exist + but will be eventually removed. ACCURATE? + + + + + + + + Add support for the stemming of + languages Armenian, Basque, Catalan, Hindi, Serbian, and Yiddish + (Peter Eisentraut) + + + + + + + + Allow tsearch data + files to have unlimited line lengths (Tom Lane) + + + + The previous limit was 4k bytes. Also remove function + t_readline(). + + + + + + + + Add support for infinity and + -infinity values to the numeric data type (Tom Lane) + + + + Floating point data types already supported these. + + + + + + + + Improve the accuracy of floating point computations involving + infinity (Tom Lane) + + + + + + + + Have non-zero float values + divided by infinity return zero (Kyotaro Horiguchi) + + + + Previously such operations produced underflow errors. + + + + + + + + Cause floating-point division of NaN by zero to return NaN + (Tom Lane) + + + + Previously this returned an error. Division with Numerics always + returned NaN. + + + + + + + + Add operators to add and subtract LSN and numeric + (byte) values (Fujii Masao) + + + + + + + + Allow binary data + transfer to be more forgiving of array and record + OID mismatches (Tom Lane) + + + + + + + + Create composite array types for most system relations (Wenjing + Zeng) + + + + + + + + + Functions + + + + + + + + Allow SQL-language functions and procedures to use + SQL-standard function bodies (Peter Eisentraut) + + + + Previously only single-quoted or $$-quoted function bodies were + supported. + + + + + + + + Allow procedures to have + OUT parameters (Peter Eisentraut) + + + + + + + + Allow some array functions to operate on a mix of compatible data + types (Tom Lane) + + + + The functions are array_append(), + array_prepend(), + array_cat(), + array_position(), + array_positions(), + array_remove(), + array_replace(), and width_bucket(). + Previously only identical data types could be used. + + + + + + + + Add SQL-standard trim_array() + function (Vik Fearing) + + + + This can already be done with array slices. + + + + + + + + Add bytea equivalents of ltrim() + and rtrim() (Joel Jacobson) + + + + + + + + Support negative indexes in split_part() + (Nikhil Benesch) + + + + Negative values start from the last field and count backward. + + + + + + + + Add string_to_table() + function to split a string on delimiters (Pavel Stehule) + + + + This is similar to the regexp_split_to_table() + function. + + + + + + + + Add unistr() + function to allow Unicode characters to be specified as + backslash-hex escapes in strings (Pavel Stehule) + + + + This is similar to how Unicode can be specified in literal string. + + + + + + + + Add bit_xor() + XOR aggregate function (Alexey Bashtanov) + + + + + + + + Add function bit_count() + to return the number of bits set in a bit or byte string (David + Fetter) + + + + + + + + Add date_bin() + function (John Naylor) + + + + The function date_bin() "bins" the input + timestamp into a specified interval aligned with a specified origin. + + + + + + + + Allow make_timestamp()/make_timestamptz() + to accept negative years (Peter Eisentraut) + + + + They are interpreted as BC years. + + + + + + + + Add newer regular expression substring() + syntax (Peter Eisentraut) + + + + The new syntax is SUBSTRING(text SIMILAR pattern ESCAPE + escapechar). The previous standard syntax was + SUBSTRING(text FROM pattern FOR escapechar), + and is still supported by Postgres. + + + + + + + + Allow complemented character class escapes \D, \S, + and \W within regex brackets (Tom Lane) + + + + + + + + Add [[:word:]] + as a character class to match \w (Tom Lane) + + + + + + + + Allow more flexible data types for default values of lead() + and lag() window functions (Vik Fearing) + + + + + + + + Cause exp() and + power() for negative-infinity exponents to + return zero (Tom Lane) + + + + Previously they often returned underflow errors. + + + + + + + + Mark built-in type coercion functions as leakproof where possible + (Tom Lane) + + + + This allows more use of functions that require type conversion in + security-sensitive situations. + + + + + + + + Mark pg_stat_get_subscription() as returning + a set (Tom Lane) + + + + While it worked in previous releases, it didn't report proper + optimizer statistics and couldn't be used in the target list. + FUNCTION NOT DOCUMENTED. + + + + + + + + Prevent inet_server_addr() + and inet_server_port() from being run by + parallel workers (Masahiko Sawada) + + + + + + + + Change pg_describe_object(), + pg_identify_object(), and + pg_identify_object_as_address() to always report + helpful error messages for non-existent objects (Michael Paquier) + + + + + + + + + <link linkend="plpgsql">PL/pgSQL</link> + + + + + + + + Improve PL/pgSQL's expression and assignment parsing + (Tom Lane) + + + + This adds nested record and array slicing support. + + + + + + + + Allow plpgsql's RETURN + QUERY to execute its query using parallelism + (Tom Lane) + + + + + + + + Improve performance of repeated CALLs within plpgsql + procedures (Pavel Stehule, Tom Lane) + + + + + + + + + Client Interfaces + + + + + + + + Add pipeline mode + to libpq (Craig Ringer, Matthieu Garrigues, Álvaro Herrera) + + + + This allows multiple queries to be sent and only wait for completion + when a specific synchronization message is sent. + + + + + + + + Enhance libpq's + parameter options (Haribabu Kommi, Greg Nancarrow, Vignesh C, + Tom Lane) + + + + The new options are read-only, + primary, standby, and + prefer-standby. + + + + + + + + Improve the output format of libpq's PQtrace() + (Aya Iwata, Álvaro Herrera) + + + + + + + + Allow an ECPG SQL identifier to be linked to + a specific connection (Hayato Kuroda) + + + + This is done via DECLARE + ... STATEMENT. + + + + + + + + + Client Applications + + + + + + + + Allow vacuumdb + to skip index cleanup and truncation (Nathan Bossart) + + + + The options are and + . + + + + + + + + Allow pg_dump + to dump only certain extensions (Guillaume Lelarge) + + + + This is controlled by option . + + + + + + + + Add pgbench + permute() function to randomly shuffle values + (Fabien Coelho, Hironobu Suzuki, Dean Rasheed) + + + + + + + + Allow multiple verbose option specifications () + to increase the logging verbosity (Tom Lane) + + + + This is now supported by pg_dump, + pg_dumpall, + and pg_restore. + + + + + + + <xref linkend="app-psql"/> + + + + + + + + Allow psql's \df and \do commands to + specify function and operator argument types (Greg Sabino Mullane, + Tom Lane) + + + + This helps reduce the number of matches for overloaded entries. + + + + + + + + Add an access method column to psql's + \d[i|m|t]+ output (Georgios Kokolatos) + + + + + + + + Allow psql's \dt and \di to show + TOAST tables and their indexes (Justin Pryzby) + + + + + + + + Add psql command \dX to list extended + statistics objects (Tatsuro Yamada) + + + + + + + + Fix psql's \dT to understand array + syntax and backend grammar aliases, like "int" for "integer" + (Greg Sabino Mullane, Tom Lane) + + + + + + + + When editing the previous query or a file with + psql's \e, or using \ef and \ev, ignore + the contents if the editor exits without saving (Laurenz Albe) + + + + Previously, such edits would still execute the editor contents. + + + + + + + + Improve psql's handling of \connect + with (Tom Lane) + + + + Specifically, properly reuse the password previously specified, + and prompt for a new password if the previous one failed. + + + + + + + + Improve tab completion (Vignesh C, Michael Paquier, Justin Pryzby, + Georgios Kokolatos, Julien Rouhaud, ADD NAMES) + + + + + + + + + + + Server Applications + + + + + + + + Add command-line utility pg_amcheck + to simplify running contrib/amcheck operations on many relations + (Mark Dilger) + + + + + + + + Add option to initdb + (Magnus Hagander) + + + + This removes the server start instructions that are normally output. + + + + + + + + Stop pg_upgrade + from creating analyze_new_cluster script + (Michael Paquier) + + + + Instead, give comparable vacuumdb + instructions. + + + + + + + + Remove support for the postmaster + option (Magnus Hagander) + + + + This option was unnecessary since all passed options could already + be specified directly. + + + + + + + + + Documentation + + + + + + + + Rename "Default Roles" to "Predefined Roles" (Bruce Momjian, + Stephen Frost) + + + + + + + + Add documentation for the factorial() + function (Peter Eisentraut) + + + + With the removal of the ! operator in this release, + factorial() is the only built-in way to compute + a factorial. + + + + + + + + + Source Code + + + + + + + + Add configure option --with-ssl={openssl} + to behave like (Daniel Gustafsson, + Michael Paquier) + + + + The option is kept for + compatibility. + + + + + + + + Add support for abstract + Unix-domain sockets (Peter Eisentraut) + + + + This is currently supported on Linux + and Windows. + + + + + + + + Allow Windows to properly handle files larger than four gigabytes + (Juan José Santamaría Flecha) + + + + For example this allows COPY, WAL + files, and relation segment files to be larger than four gigabytes. + + + + + + + + Add + to control cache overwriting (Craig Ringer) + + + + Previously this could only be controlled at compile time and is + enabled only in assert builds. + + + + + + + + Various improvements in valgrind + detection (Álvaro Herrera, Peter Geoghegan) + + + + + + + + Add a test module for the regular expression package (Tom Lane) + + + + + + + + Add support for LLVM version 12 + (Andres Freund) + + + + + + + + Change SHA1, SHA2, and MD5 hash computations to use the + OpenSSL EVP API + (Michael Paquier) + + + + This is more modern and supports FIPS mode. + + + + + + + + Remove build control over the random library used (Daniel + Gustafsson) + + + + + + + + Add direct conversion routines between EUC_TW and Big5 (Heikki + Linnakangas) + + + + + + + + Add collation versions for FreeBSD + (Thomas Munro) + + + + + + + + Add amadjustmembers + to the index access method API (Tom Lane) + + + + REMOVE? + + + + + + + + + Additional Modules + + + + + + + + Allow subscripting of hstore values + (Tom Lane, Dmitry Dolgov) + + + + + + + + Allow GiST/GIN pg_trgm indexes + to do equality lookups (Julien Rouhaud) + + + + This is similar to LIKE except no wildcards + are honored. + + + + + + + + Allow the cube data type + to be transferred in binary mode (KaiGai Kohei) + + + + + + + + Allow pgstattuple_approx() to report on + TOAST tables (Peter Eisentraut) + + + + + + + + Add contrib module pg_surgery + which allows changes to row visibility (Ashutosh Sharma) + + + + This is useful for correcting database corruption. + + + + + + + + Add contrib module old_snapshot + to report the XID/time mapping used by an active + (Robert Haas) + + + + + + + + Allow amcheck to + also check heap pages (Mark Dilger) + + + + Previously it only checked B-Tree index pages. + + + + + + + + Allow pageinspect + to inspect GiST indexes (Andrey Borodin, Heikki Linnakangas) + + + + + + + + Change pageinspect block numbers + to be bigints + (Peter Eisentraut) + + + + + + + + Mark btree_gist + functions as parallel safe (Steven Winfield) + + + + + + + <link linkend="pgstatstatements">pg_stat_statements</link> + + + + + + + + Move query hash computation from + pg_stat_statements to the core server + (Julien Rouhaud) + + + + The new server variable 's + default of auto will automatically enable query + id computation when this extension is loaded. + + + + + + + + Allow pg_stat_statements to track top + and nested statements independently (Julien Rohaud) + + + + Previously, when tracking all statements, identical top and nested + statements were tracked together. + + + + + + + + Add row counts for utility commands to + pg_stat_statements (Fujii Masao, Katsuragi + Yuta, Seino Yuki) + + + + + + + + Add pg_stat_statements_info system view + to show pg_stat_statements activity + (Katsuragi Yuta, Yuki Seino, Naoki Nakamichi) + + + + + + + + + <link linkend="postgres-fdw"><application>postgres_fdw</application></link> + + + + + + + + Allow postgres_fdw to + INSERT rows in bulk (Takayuki Tsunakawa, Tomas + Vondra, Amit Langote) + + + + + + + + Allow postgres_fdw + to import table partitions if specified by IMPORT FOREIGN SCHEMA + ... LIMIT TO (Matthias van de Meent) + + + + By default, only the root of partitioned tables is imported. + + + + + + + + Add postgres_fdw function + postgres_fdw_get_connections() to report open + foreign server connections (Bharath Rupireddy) + + + + + + + + Allow control over whether foreign servers keep connections open + after transaction completion (Bharath Rupireddy) + + + + This is controlled by keep_connections and + defaults to on. + + + + + + + + Allow postgres_fdw to reestablish + foreign server connections if necessary (Bharath Rupireddy) + + + + Previously foreign server restarts could cause foreign table + access errors. + + + + + + + + Add postgres_fdw functions to discard + cached connections (Bharath Rupireddy) + + + + + + + + + + + + + Acknowledgments + + + The following individuals (in alphabetical order) have contributed + to this release as patch authors, committers, reviewers, testers, + or reporters of issues. + + + + + + diff --git a/doc/src/sgml/replication-origins.sgml b/doc/src/sgml/replication-origins.sgml new file mode 100644 index 000000000000..7e02c4605b25 --- /dev/null +++ b/doc/src/sgml/replication-origins.sgml @@ -0,0 +1,96 @@ + + + Replication Progress Tracking + + + Replication Progress Tracking + + + Replication Origins + + + + Replication origins are intended to make it easier to implement + logical replication solutions on top + of logical decoding. + They provide a solution to two common problems: + + + How to safely keep track of replication progress + + + How to change replication behavior based on the + origin of a row; for example, to prevent loops in bi-directional + replication setups + + + + + + Replication origins have just two properties, a name and an OID. The name, + which is what should be used to refer to the origin across systems, is + free-form text. It should be used in a way that makes conflicts + between replication origins created by different replication solutions + unlikely; e.g., by prefixing the replication solution's name to it. + The OID is used only to avoid having to store the long version + in situations where space efficiency is important. It should never be shared + across systems. + + + + Replication origins can be created using the function + pg_replication_origin_create(); + dropped using + pg_replication_origin_drop(); + and seen in the + pg_replication_origin + system catalog. + + + + One nontrivial part of building a replication solution is to keep track of + replay progress in a safe manner. When the applying process, or the whole + cluster, dies, it needs to be possible to find out up to where data has + successfully been replicated. Naive solutions to this, such as updating a + row in a table for every replayed transaction, have problems like run-time + overhead and database bloat. + + + + Using the replication origin infrastructure a session can be + marked as replaying from a remote node (using the + pg_replication_origin_session_setup() + function). Additionally the LSN and commit + time stamp of every source transaction can be configured on a per + transaction basis using + pg_replication_origin_xact_setup(). + If that's done replication progress will persist in a crash safe + manner. Replay progress for all replication origins can be seen in the + + pg_replication_origin_status + view. An individual origin's progress, e.g., when resuming + replication, can be acquired using + pg_replication_origin_progress() + for any origin or + pg_replication_origin_session_progress() + for the origin configured in the current session. + + + + In replication topologies more complex than replication from exactly one + system to one other system, another problem can be that it is hard to avoid + replicating replayed rows again. That can lead both to cycles in the + replication and inefficiencies. Replication origins provide an optional + mechanism to recognize and prevent that. When configured using the functions + referenced in the previous paragraph, every change and transaction passed to + output plugin callbacks (see ) + generated by the session is tagged with the replication origin of the + generating session. This allows treating them differently in the output + plugin, e.g., ignoring all but locally-originating rows. Additionally + the + filter_by_origin_cb callback can be used + to filter the logical decoding change stream based on the + source. While less flexible, filtering via that callback is + considerably more efficient than doing it in the output plugin. + + diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml new file mode 100644 index 000000000000..5024e4ff704f --- /dev/null +++ b/doc/src/sgml/rules.sgml @@ -0,0 +1,2434 @@ + + + +The Rule System + + + rule + + + + This chapter discusses the rule system in + PostgreSQL. Production rule systems + are conceptually simple, but there are many subtle points + involved in actually using them. + + + + Some other database systems define active database rules, which + are usually stored procedures and triggers. In + PostgreSQL, these can be implemented + using functions and triggers as well. + + + + The rule system (more precisely speaking, the query rewrite rule + system) is totally different from stored procedures and triggers. + It modifies queries to take rules into consideration, and then + passes the modified query to the query planner for planning and + execution. It is very powerful, and can be used for many things + such as query language procedures, views, and versions. The + theoretical foundations and the power of this rule system are + also discussed in and . + + + +The Query Tree + + + query tree + + + + To understand how the rule system works it is necessary to know + when it is invoked and what its input and results are. + + + + The rule system is located between the parser and the planner. + It takes the output of the parser, one query tree, and the user-defined + rewrite rules, which are also + query trees with some extra information, and creates zero or more + query trees as result. So its input and output are always things + the parser itself could have produced and thus, anything it sees + is basically representable as an SQL statement. + + + + Now what is a query tree? It is an internal representation of an + SQL statement where the single parts that it is + built from are stored separately. These query trees can be shown + in the server log if you set the configuration parameters + debug_print_parse, + debug_print_rewritten, or + debug_print_plan. The rule actions are also + stored as query trees, in the system catalog + pg_rewrite. They are not formatted like + the log output, but they contain exactly the same information. + + + + Reading a raw query tree requires some experience. But since + SQL representations of query trees are + sufficient to understand the rule system, this chapter will not + teach how to read them. + + + + When reading the SQL representations of the + query trees in this chapter it is necessary to be able to identify + the parts the statement is broken into when it is in the query tree + structure. The parts of a query tree are + + + + + the command type + + + + This is a simple value telling which command + (SELECT, INSERT, + UPDATE, DELETE) produced + the query tree. + + + + + + + the range table + range table + + + + The range table is a list of relations that are used in the query. + In a SELECT statement these are the relations given after + the FROM key word. + + + + Every range table entry identifies a table or view and tells + by which name it is called in the other parts of the query. + In the query tree, the range table entries are referenced by + number rather than by name, so here it doesn't matter if there + are duplicate names as it would in an SQL + statement. This can happen after the range tables of rules + have been merged in. The examples in this chapter will not have + this situation. + + + + + + + the result relation + + + + This is an index into the range table that identifies the + relation where the results of the query go. + + + + SELECT queries don't have a result + relation. (The special case of SELECT INTO is + mostly identical to CREATE TABLE followed by + INSERT ... SELECT, and is not discussed + separately here.) + + + + For INSERT, UPDATE, and + DELETE commands, the result relation is the table + (or view!) where the changes are to take effect. + + + + + + + the target list + target list + + + + The target list is a list of expressions that define the + result of the query. In the case of a + SELECT, these expressions are the ones that + build the final output of the query. They correspond to the + expressions between the key words SELECT + and FROM. (* is just an + abbreviation for all the column names of a relation. It is + expanded by the parser into the individual columns, so the + rule system never sees it.) + + + + DELETE commands don't need a normal target list + because they don't produce any result. Instead, the planner + adds a special CTID entry to the empty target list, + to allow the executor to find the row to be deleted. + (CTID is added when the result relation is an ordinary + table. If it is a view, a whole-row variable is added instead, by + the rule system, as described in .) + + + + For INSERT commands, the target list describes + the new rows that should go into the result relation. It consists of the + expressions in the VALUES clause or the ones from the + SELECT clause in INSERT + ... SELECT. The first step of the rewrite process adds + target list entries for any columns that were not assigned to by + the original command but have defaults. Any remaining columns (with + neither a given value nor a default) will be filled in by the + planner with a constant null expression. + + + + For UPDATE commands, the target list + describes the new rows that should replace the old ones. In the + rule system, it contains just the expressions from the SET + column = expression part of the command. The planner will + handle missing columns by inserting expressions that copy the values + from the old row into the new one. Just as for DELETE, + a CTID or whole-row variable is added so that + the executor can identify the old row to be updated. + + + + Every entry in the target list contains an expression that can + be a constant value, a variable pointing to a column of one + of the relations in the range table, a parameter, or an expression + tree made of function calls, constants, variables, operators, etc. + + + + + + + the qualification + + + + The query's qualification is an expression much like one of + those contained in the target list entries. The result value of + this expression is a Boolean that tells whether the operation + (INSERT, UPDATE, + DELETE, or SELECT) for the + final result row should be executed or not. It corresponds to the WHERE clause + of an SQL statement. + + + + + + + the join tree + + + + The query's join tree shows the structure of the FROM clause. + For a simple query like SELECT ... FROM a, b, c, the join tree is just + a list of the FROM items, because we are allowed to join them in + any order. But when JOIN expressions, particularly outer joins, + are used, we have to join in the order shown by the joins. + In that case, the join tree shows the structure of the JOIN expressions. The + restrictions associated with particular JOIN clauses (from ON or + USING expressions) are stored as qualification expressions attached + to those join-tree nodes. It turns out to be convenient to store + the top-level WHERE expression as a qualification attached to the + top-level join-tree item, too. So really the join tree represents + both the FROM and WHERE clauses of a SELECT. + + + + + + + the others + + + + The other parts of the query tree like the ORDER BY + clause aren't of interest here. The rule system + substitutes some entries there while applying rules, but that + doesn't have much to do with the fundamentals of the rule + system. + + + + + + + + + +Views and the Rule System + + + rule + and views + + + + view + implementation through rules + + + + Views in PostgreSQL are implemented + using the rule system. In fact, there is essentially no difference + between: + + +CREATE VIEW myview AS SELECT * FROM mytab; + + + compared against the two commands: + + +CREATE TABLE myview (same column list as mytab); +CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD + SELECT * FROM mytab; + + + because this is exactly what the CREATE VIEW + command does internally. This has some side effects. One of them + is that the information about a view in the + PostgreSQL system catalogs is exactly + the same as it is for a table. So for the parser, there is + absolutely no difference between a table and a view. They are the + same thing: relations. + + + +How <command>SELECT</command> Rules Work + + + rule + for SELECT + + + + Rules ON SELECT are applied to all queries as the last step, even + if the command given is an INSERT, + UPDATE or DELETE. And they + have different semantics from rules on the other command types in that they modify the + query tree in place instead of creating a new one. So + SELECT rules are described first. + + + + Currently, there can be only one action in an ON SELECT rule, and it must + be an unconditional SELECT action that is INSTEAD. This restriction was + required to make rules safe enough to open them for ordinary users, and + it restricts ON SELECT rules to act like views. + + + + The examples for this chapter are two join views that do some + calculations and some more views using them in turn. One of the + two first views is customized later by adding rules for + INSERT, UPDATE, and + DELETE operations so that the final result will + be a view that behaves like a real table with some magic + functionality. This is not such a simple example to start from and + this makes things harder to get into. But it's better to have one + example that covers all the points discussed step by step rather + than having many different ones that might mix up in mind. + + + + The real tables we need in the first two rule system descriptions + are these: + + +CREATE TABLE shoe_data ( + shoename text, -- primary key + sh_avail integer, -- available number of pairs + slcolor text, -- preferred shoelace color + slminlen real, -- minimum shoelace length + slmaxlen real, -- maximum shoelace length + slunit text -- length unit +); + +CREATE TABLE shoelace_data ( + sl_name text, -- primary key + sl_avail integer, -- available number of pairs + sl_color text, -- shoelace color + sl_len real, -- shoelace length + sl_unit text -- length unit +); + +CREATE TABLE unit ( + un_name text, -- primary key + un_fact real -- factor to transform to cm +); + + + As you can see, they represent shoe-store data. + + + + The views are created as: + + +CREATE VIEW shoe AS + SELECT sh.shoename, + sh.sh_avail, + sh.slcolor, + sh.slminlen, + sh.slminlen * un.un_fact AS slminlen_cm, + sh.slmaxlen, + sh.slmaxlen * un.un_fact AS slmaxlen_cm, + sh.slunit + FROM shoe_data sh, unit un + WHERE sh.slunit = un.un_name; + +CREATE VIEW shoelace AS + SELECT s.sl_name, + s.sl_avail, + s.sl_color, + s.sl_len, + s.sl_unit, + s.sl_len * u.un_fact AS sl_len_cm + FROM shoelace_data s, unit u + WHERE s.sl_unit = u.un_name; + +CREATE VIEW shoe_ready AS + SELECT rsh.shoename, + rsh.sh_avail, + rsl.sl_name, + rsl.sl_avail, + least(rsh.sh_avail, rsl.sl_avail) AS total_avail + FROM shoe rsh, shoelace rsl + WHERE rsl.sl_color = rsh.slcolor + AND rsl.sl_len_cm >= rsh.slminlen_cm + AND rsl.sl_len_cm <= rsh.slmaxlen_cm; + + + The CREATE VIEW command for the + shoelace view (which is the simplest one we + have) will create a relation shoelace and an entry in + pg_rewrite that tells that there is a + rewrite rule that must be applied whenever the relation shoelace + is referenced in a query's range table. The rule has no rule + qualification (discussed later, with the non-SELECT rules, since + SELECT rules currently cannot have them) and it is INSTEAD. Note + that rule qualifications are not the same as query qualifications. + The action of our rule has a query qualification. + The action of the rule is one query tree that is a copy of the + SELECT statement in the view creation command. + + + + + The two extra range + table entries for NEW and OLD that you can see in + the pg_rewrite entry aren't of interest + for SELECT rules. + + + + + Now we populate unit, shoe_data + and shoelace_data and run a simple query on a view: + + +INSERT INTO unit VALUES ('cm', 1.0); +INSERT INTO unit VALUES ('m', 100.0); +INSERT INTO unit VALUES ('inch', 2.54); + +INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm'); +INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch'); +INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm'); +INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch'); + +INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm'); +INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm'); +INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch'); +INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch'); +INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm'); +INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm'); +INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm'); +INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch'); + +SELECT * FROM shoelace; + + sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm +-----------+----------+----------+--------+---------+----------- + sl1 | 5 | black | 80 | cm | 80 + sl2 | 6 | black | 100 | cm | 100 + sl7 | 7 | brown | 60 | cm | 60 + sl3 | 0 | black | 35 | inch | 88.9 + sl4 | 8 | black | 40 | inch | 101.6 + sl8 | 1 | brown | 40 | inch | 101.6 + sl5 | 4 | brown | 1 | m | 100 + sl6 | 0 | brown | 0.9 | m | 90 +(8 rows) + + + + + This is the simplest SELECT you can do on our + views, so we take this opportunity to explain the basics of view + rules. The SELECT * FROM shoelace was + interpreted by the parser and produced the query tree: + + +SELECT shoelace.sl_name, shoelace.sl_avail, + shoelace.sl_color, shoelace.sl_len, + shoelace.sl_unit, shoelace.sl_len_cm + FROM shoelace shoelace; + + + and this is given to the rule system. The rule system walks through the + range table and checks if there are rules + for any relation. When processing the range table entry for + shoelace (the only one up to now) it finds the + _RETURN rule with the query tree: + + +SELECT s.sl_name, s.sl_avail, + s.sl_color, s.sl_len, s.sl_unit, + s.sl_len * u.un_fact AS sl_len_cm + FROM shoelace old, shoelace new, + shoelace_data s, unit u + WHERE s.sl_unit = u.un_name; + + + + + To expand the view, the rewriter simply creates a subquery range-table + entry containing the rule's action query tree, and substitutes this + range table entry for the original one that referenced the view. The + resulting rewritten query tree is almost the same as if you had typed: + + +SELECT shoelace.sl_name, shoelace.sl_avail, + shoelace.sl_color, shoelace.sl_len, + shoelace.sl_unit, shoelace.sl_len_cm + FROM (SELECT s.sl_name, + s.sl_avail, + s.sl_color, + s.sl_len, + s.sl_unit, + s.sl_len * u.un_fact AS sl_len_cm + FROM shoelace_data s, unit u + WHERE s.sl_unit = u.un_name) shoelace; + + + There is one difference however: the subquery's range table has two + extra entries shoelace old and shoelace new. These entries don't + participate directly in the query, since they aren't referenced by + the subquery's join tree or target list. The rewriter uses them + to store the access privilege check information that was originally present + in the range-table entry that referenced the view. In this way, the + executor will still check that the user has proper privileges to access + the view, even though there's no direct use of the view in the rewritten + query. + + + + That was the first rule applied. The rule system will continue checking + the remaining range-table entries in the top query (in this example there + are no more), and it will recursively check the range-table entries in + the added subquery to see if any of them reference views. (But it + won't expand old or new — otherwise we'd have infinite recursion!) + In this example, there are no rewrite rules for shoelace_data or unit, + so rewriting is complete and the above is the final result given to + the planner. + + + + Now we want to write a query that finds out for which shoes currently in the store + we have the matching shoelaces (color and length) and where the + total number of exactly matching pairs is greater or equal to two. + + +SELECT * FROM shoe_ready WHERE total_avail >= 2; + + shoename | sh_avail | sl_name | sl_avail | total_avail +----------+----------+---------+----------+------------- + sh1 | 2 | sl1 | 5 | 2 + sh3 | 4 | sl7 | 7 | 4 +(2 rows) + + + + + The output of the parser this time is the query tree: + + +SELECT shoe_ready.shoename, shoe_ready.sh_avail, + shoe_ready.sl_name, shoe_ready.sl_avail, + shoe_ready.total_avail + FROM shoe_ready shoe_ready + WHERE shoe_ready.total_avail >= 2; + + + The first rule applied will be the one for the + shoe_ready view and it results in the + query tree: + + +SELECT shoe_ready.shoename, shoe_ready.sh_avail, + shoe_ready.sl_name, shoe_ready.sl_avail, + shoe_ready.total_avail + FROM (SELECT rsh.shoename, + rsh.sh_avail, + rsl.sl_name, + rsl.sl_avail, + least(rsh.sh_avail, rsl.sl_avail) AS total_avail + FROM shoe rsh, shoelace rsl + WHERE rsl.sl_color = rsh.slcolor + AND rsl.sl_len_cm >= rsh.slminlen_cm + AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready + WHERE shoe_ready.total_avail >= 2; + + + Similarly, the rules for shoe and + shoelace are substituted into the range table of + the subquery, leading to a three-level final query tree: + + +SELECT shoe_ready.shoename, shoe_ready.sh_avail, + shoe_ready.sl_name, shoe_ready.sl_avail, + shoe_ready.total_avail + FROM (SELECT rsh.shoename, + rsh.sh_avail, + rsl.sl_name, + rsl.sl_avail, + least(rsh.sh_avail, rsl.sl_avail) AS total_avail + FROM (SELECT sh.shoename, + sh.sh_avail, + sh.slcolor, + sh.slminlen, + sh.slminlen * un.un_fact AS slminlen_cm, + sh.slmaxlen, + sh.slmaxlen * un.un_fact AS slmaxlen_cm, + sh.slunit + FROM shoe_data sh, unit un + WHERE sh.slunit = un.un_name) rsh, + (SELECT s.sl_name, + s.sl_avail, + s.sl_color, + s.sl_len, + s.sl_unit, + s.sl_len * u.un_fact AS sl_len_cm + FROM shoelace_data s, unit u + WHERE s.sl_unit = u.un_name) rsl + WHERE rsl.sl_color = rsh.slcolor + AND rsl.sl_len_cm >= rsh.slminlen_cm + AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready + WHERE shoe_ready.total_avail > 2; + + + + + This might look inefficient, but the planner will collapse this into a + single-level query tree by pulling up the subqueries, + and then it will plan the joins just as if we'd written them out + manually. So collapsing the query tree is an optimization that the + rewrite system doesn't have to concern itself with. + + + + +View Rules in Non-<command>SELECT</command> Statements + + + Two details of the query tree aren't touched in the description of + view rules above. These are the command type and the result relation. + In fact, the command type is not needed by view rules, but the result + relation may affect the way in which the query rewriter works, because + special care needs to be taken if the result relation is a view. + + + + There are only a few differences between a query tree for a + SELECT and one for any other + command. Obviously, they have a different command type and for a + command other than a SELECT, the result + relation points to the range-table entry where the result should + go. Everything else is absolutely the same. So having two tables + t1 and t2 with columns a and + b, the query trees for the two statements: + + +SELECT t2.b FROM t1, t2 WHERE t1.a = t2.a; + +UPDATE t1 SET b = t2.b FROM t2 WHERE t1.a = t2.a; + + + are nearly identical. In particular: + + + + + The range tables contain entries for the tables t1 and t2. + + + + + + The target lists contain one variable that points to column + b of the range table entry for table t2. + + + + + + The qualification expressions compare the columns a of both + range-table entries for equality. + + + + + + The join trees show a simple join between t1 and t2. + + + + + + + The consequence is, that both query trees result in similar + execution plans: They are both joins over the two tables. For the + UPDATE the missing columns from t1 are added to + the target list by the planner and the final query tree will read + as: + + +UPDATE t1 SET a = t1.a, b = t2.b FROM t2 WHERE t1.a = t2.a; + + + and thus the executor run over the join will produce exactly the + same result set as: + + +SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a = t2.a; + + + But there is a little problem in + UPDATE: the part of the executor plan that does + the join does not care what the results from the join are + meant for. It just produces a result set of rows. The fact that + one is a SELECT command and the other is an + UPDATE is handled higher up in the executor, where + it knows that this is an UPDATE, and it knows that + this result should go into table t1. But which of the rows + that are there has to be replaced by the new row? + + + + To resolve this problem, another entry is added to the target list + in UPDATE (and also in + DELETE) statements: the current tuple ID + (CTID).CTID + This is a system column containing the + file block number and position in the block for the row. Knowing + the table, the CTID can be used to retrieve the + original row of t1 to be updated. After adding the + CTID to the target list, the query actually looks like: + + +SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a; + + + Now another detail of PostgreSQL enters + the stage. Old table rows aren't overwritten, and this + is why ROLLBACK is fast. In an UPDATE, + the new result row is inserted into the table (after stripping the + CTID) and in the row header of the old row, which the + CTID pointed to, the cmax and + xmax entries are set to the current command counter + and current transaction ID. Thus the old row is hidden, and after + the transaction commits the vacuum cleaner can eventually remove + the dead row. + + + + Knowing all that, we can simply apply view rules in absolutely + the same way to any command. There is no difference. + + + + +The Power of Views in <productname>PostgreSQL</productname> + + + The above demonstrates how the rule system incorporates view + definitions into the original query tree. In the second example, a + simple SELECT from one view created a final + query tree that is a join of 4 tables (unit was used twice with + different names). + + + + The benefit of implementing views with the rule system is + that the planner has all + the information about which tables have to be scanned plus the + relationships between these tables plus the restrictive + qualifications from the views plus the qualifications from + the original query + in one single query tree. And this is still the situation + when the original query is already a join over views. + The planner has to decide which is + the best path to execute the query, and the more information + the planner has, the better this decision can be. And + the rule system as implemented in PostgreSQL + ensures that this is all information available about the query + up to that point. + + + + +Updating a View + + + What happens if a view is named as the target relation for an + INSERT, UPDATE, or + DELETE? Doing the substitutions + described above would give a query tree in which the result + relation points at a subquery range-table entry, which will not + work. There are several ways in which PostgreSQL + can support the appearance of updating a view, however. + In order of user-experienced complexity those are: automatically substitute + in the underlying table for the view, execute a user-defined trigger, + or rewrite the query per a user-defined rule. + These options are discussed below. + + + + If the subquery selects from a single base relation and is simple + enough, the rewriter can automatically replace the subquery with the + underlying base relation so that the INSERT, + UPDATE, or DELETE is applied to + the base relation in the appropriate way. Views that are + simple enough for this are called automatically + updatable. For detailed information on the kinds of view that can + be automatically updated, see . + + + + Alternatively, the operation may be handled by a user-provided + INSTEAD OF trigger on the view + (see ). + Rewriting works slightly differently + in this case. For INSERT, the rewriter does + nothing at all with the view, leaving it as the result relation + for the query. For UPDATE and + DELETE, it's still necessary to expand the + view query to produce the old rows that the command will + attempt to update or delete. So the view is expanded as normal, + but another unexpanded range-table entry is added to the query + to represent the view in its capacity as the result relation. + + + + The problem that now arises is how to identify the rows to be + updated in the view. Recall that when the result relation + is a table, a special CTID entry is added to the target + list to identify the physical locations of the rows to be updated. + This does not work if the result relation is a view, because a view + does not have any CTID, since its rows do not have + actual physical locations. Instead, for an UPDATE + or DELETE operation, a special wholerow + entry is added to the target list, which expands to include all + columns from the view. The executor uses this value to supply the + old row to the INSTEAD OF trigger. It is + up to the trigger to work out what to update based on the old and + new row values. + + + + Another possibility is for the user to define INSTEAD + rules that specify substitute actions for INSERT, + UPDATE, and DELETE commands on + a view. These rules will rewrite the command, typically into a command + that updates one or more tables, rather than views. That is the topic + of . + + + + Note that rules are evaluated first, rewriting the original query + before it is planned and executed. Therefore, if a view has + INSTEAD OF triggers as well as rules on INSERT, + UPDATE, or DELETE, then the rules will be + evaluated first, and depending on the result, the triggers may not be + used at all. + + + + Automatic rewriting of an INSERT, + UPDATE, or DELETE query on a + simple view is always tried last. Therefore, if a view has rules or + triggers, they will override the default behavior of automatically + updatable views. + + + + If there are no INSTEAD rules or INSTEAD OF + triggers for the view, and the rewriter cannot automatically rewrite + the query as an update on the underlying base relation, an error will + be thrown because the executor cannot update a view as such. + + + + + + + +Materialized Views + + + rule + and materialized views + + + + materialized view + implementation through rules + + + + view + materialized + + + + Materialized views in PostgreSQL use the + rule system like views do, but persist the results in a table-like form. + The main differences between: + + +CREATE MATERIALIZED VIEW mymatview AS SELECT * FROM mytab; + + + and: + + +CREATE TABLE mymatview AS SELECT * FROM mytab; + + + are that the materialized view cannot subsequently be directly updated + and that the query used to create the materialized view is stored in + exactly the same way that a view's query is stored, so that fresh data + can be generated for the materialized view with: + + +REFRESH MATERIALIZED VIEW mymatview; + + + The information about a materialized view in the + PostgreSQL system catalogs is exactly + the same as it is for a table or view. So for the parser, a + materialized view is a relation, just like a table or a view. When + a materialized view is referenced in a query, the data is returned + directly from the materialized view, like from a table; the rule is + only used for populating the materialized view. + + + + While access to the data stored in a materialized view is often much + faster than accessing the underlying tables directly or through a view, + the data is not always current; yet sometimes current data is not needed. + Consider a table which records sales: + + +CREATE TABLE invoice ( + invoice_no integer PRIMARY KEY, + seller_no integer, -- ID of salesperson + invoice_date date, -- date of sale + invoice_amt numeric(13,2) -- amount of sale +); + + + If people want to be able to quickly graph historical sales data, they + might want to summarize, and they may not care about the incomplete data + for the current date: + + +CREATE MATERIALIZED VIEW sales_summary AS + SELECT + seller_no, + invoice_date, + sum(invoice_amt)::numeric(13,2) as sales_amt + FROM invoice + WHERE invoice_date < CURRENT_DATE + GROUP BY + seller_no, + invoice_date + ORDER BY + seller_no, + invoice_date; + +CREATE UNIQUE INDEX sales_summary_seller + ON sales_summary (seller_no, invoice_date); + + + This materialized view might be useful for displaying a graph in the + dashboard created for salespeople. A job could be scheduled to update + the statistics each night using this SQL statement: + + +REFRESH MATERIALIZED VIEW sales_summary; + + + + + Another use for a materialized view is to allow faster access to data + brought across from a remote system through a foreign data wrapper. + A simple example using file_fdw is below, with timings, + but since this is using cache on the local system the performance + difference compared to access to a remote system would usually be greater + than shown here. Notice we are also exploiting the ability to put an + index on the materialized view, whereas file_fdw does + not support indexes; this advantage might not apply for other sorts of + foreign data access. + + + + Setup: + + +CREATE EXTENSION file_fdw; +CREATE SERVER local_file FOREIGN DATA WRAPPER file_fdw; +CREATE FOREIGN TABLE words (word text NOT NULL) + SERVER local_file + OPTIONS (filename '/usr/share/dict/words'); +CREATE MATERIALIZED VIEW wrd AS SELECT * FROM words; +CREATE UNIQUE INDEX wrd_word ON wrd (word); +CREATE EXTENSION pg_trgm; +CREATE INDEX wrd_trgm ON wrd USING gist (word gist_trgm_ops); +VACUUM ANALYZE wrd; + + + Now let's spell-check a word. Using file_fdw directly: + + +SELECT count(*) FROM words WHERE word = 'caterpiler'; + + count +------- + 0 +(1 row) + + + With EXPLAIN ANALYZE, we see: + + + Aggregate (cost=21763.99..21764.00 rows=1 width=0) (actual time=188.180..188.181 rows=1 loops=1) + -> Foreign Scan on words (cost=0.00..21761.41 rows=1032 width=0) (actual time=188.177..188.177 rows=0 loops=1) + Filter: (word = 'caterpiler'::text) + Rows Removed by Filter: 479829 + Foreign File: /usr/share/dict/words + Foreign File Size: 4953699 + Planning time: 0.118 ms + Execution time: 188.273 ms + + + If the materialized view is used instead, the query is much faster: + + + Aggregate (cost=4.44..4.45 rows=1 width=0) (actual time=0.042..0.042 rows=1 loops=1) + -> Index Only Scan using wrd_word on wrd (cost=0.42..4.44 rows=1 width=0) (actual time=0.039..0.039 rows=0 loops=1) + Index Cond: (word = 'caterpiler'::text) + Heap Fetches: 0 + Planning time: 0.164 ms + Execution time: 0.117 ms + + + Either way, the word is spelled wrong, so let's look for what we might + have wanted. Again using file_fdw and + pg_trgm: + + +SELECT word FROM words ORDER BY word <-> 'caterpiler' LIMIT 10; + + word +--------------- + cater + caterpillar + Caterpillar + caterpillars + caterpillar's + Caterpillar's + caterer + caterer's + caters + catered +(10 rows) + + + + Limit (cost=11583.61..11583.64 rows=10 width=32) (actual time=1431.591..1431.594 rows=10 loops=1) + -> Sort (cost=11583.61..11804.76 rows=88459 width=32) (actual time=1431.589..1431.591 rows=10 loops=1) + Sort Key: ((word <-> 'caterpiler'::text)) + Sort Method: top-N heapsort Memory: 25kB + -> Foreign Scan on words (cost=0.00..9672.05 rows=88459 width=32) (actual time=0.057..1286.455 rows=479829 loops=1) + Foreign File: /usr/share/dict/words + Foreign File Size: 4953699 + Planning time: 0.128 ms + Execution time: 1431.679 ms + + + Using the materialized view: + + + Limit (cost=0.29..1.06 rows=10 width=10) (actual time=187.222..188.257 rows=10 loops=1) + -> Index Scan using wrd_trgm on wrd (cost=0.29..37020.87 rows=479829 width=10) (actual time=187.219..188.252 rows=10 loops=1) + Order By: (word <-> 'caterpiler'::text) + Planning time: 0.196 ms + Execution time: 198.640 ms + + + If you can tolerate periodic update of the remote data to the local + database, the performance benefit can be substantial. + + + + + +Rules on <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command> + + + rule + for INSERT + + + + rule + for UPDATE + + + + rule + for DELETE + + + + Rules that are defined on INSERT, UPDATE, + and DELETE are significantly different from the view rules + described in the previous section. First, their CREATE + RULE command allows more: + + + + + They are allowed to have no action. + + + + + + They can have multiple actions. + + + + + + They can be INSTEAD or ALSO (the default). + + + + + + The pseudorelations NEW and OLD become useful. + + + + + + They can have rule qualifications. + + + + + Second, they don't modify the query tree in place. Instead they + create zero or more new query trees and can throw away the + original one. + + + + + In many cases, tasks that could be performed by rules + on INSERT/UPDATE/DELETE are better done + with triggers. Triggers are notationally a bit more complicated, but their + semantics are much simpler to understand. Rules tend to have surprising + results when the original query contains volatile functions: volatile + functions may get executed more times than expected in the process of + carrying out the rules. + + + + Also, there are some cases that are not supported by these types of rules at + all, notably including WITH clauses in the original query and + multiple-assignment sub-SELECTs in the SET list + of UPDATE queries. This is because copying these constructs + into a rule query would result in multiple evaluations of the sub-query, + contrary to the express intent of the query's author. + + + + +How Update Rules Work + + + Keep the syntax: + + +CREATE [ OR REPLACE ] RULE name AS ON event + TO table [ WHERE condition ] + DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) } + + + in mind. + In the following, update rules means rules that are defined + on INSERT, UPDATE, or DELETE. + + + + Update rules get applied by the rule system when the result + relation and the command type of a query tree are equal to the + object and event given in the CREATE RULE command. + For update rules, the rule system creates a list of query trees. + Initially the query-tree list is empty. + There can be zero (NOTHING key word), one, or multiple actions. + To simplify, we will look at a rule with one action. This rule + can have a qualification or not and it can be INSTEAD or + ALSO (the default). + + + + What is a rule qualification? It is a restriction that tells + when the actions of the rule should be done and when not. This + qualification can only reference the pseudorelations NEW and/or OLD, + which basically represent the relation that was given as object (but with a + special meaning). + + + + So we have three cases that produce the following query trees for + a one-action rule. + + + + No qualification, with either ALSO or + INSTEAD + + + the query tree from the rule action with the original query + tree's qualification added + + + + + + Qualification given and ALSO + + + the query tree from the rule action with the rule + qualification and the original query tree's qualification + added + + + + + + Qualification given and INSTEAD + + + the query tree from the rule action with the rule + qualification and the original query tree's qualification; and + the original query tree with the negated rule qualification + added + + + + + + Finally, if the rule is ALSO, the unchanged original query tree is + added to the list. Since only qualified INSTEAD rules already add the + original query tree, we end up with either one or two output query trees + for a rule with one action. + + + + For ON INSERT rules, the original query (if not suppressed by INSTEAD) + is done before any actions added by rules. This allows the actions to + see the inserted row(s). But for ON UPDATE and ON + DELETE rules, the original query is done after the actions added by rules. + This ensures that the actions can see the to-be-updated or to-be-deleted + rows; otherwise, the actions might do nothing because they find no rows + matching their qualifications. + + + + The query trees generated from rule actions are thrown into the + rewrite system again, and maybe more rules get applied resulting + in additional or fewer query trees. + So a rule's actions must have either a different + command type or a different result relation than the rule itself is + on, otherwise this recursive process will end up in an infinite loop. + (Recursive expansion of a rule will be detected and reported as an + error.) + + + + The query trees found in the actions of the + pg_rewrite system catalog are only + templates. Since they can reference the range-table entries for + NEW and OLD, some substitutions have to be made before they can be + used. For any reference to NEW, the target list of the original + query is searched for a corresponding entry. If found, that + entry's expression replaces the reference. Otherwise, NEW means the + same as OLD (for an UPDATE) or is replaced by + a null value (for an INSERT). Any reference to OLD is + replaced by a reference to the range-table entry that is the + result relation. + + + + After the system is done applying update rules, it applies view rules to the + produced query tree(s). Views cannot insert new update actions so + there is no need to apply update rules to the output of view rewriting. + + + +A First Rule Step by Step + + + Say we want to trace changes to the sl_avail column in the + shoelace_data relation. So we set up a log table + and a rule that conditionally writes a log entry when an + UPDATE is performed on + shoelace_data. + + +CREATE TABLE shoelace_log ( + sl_name text, -- shoelace changed + sl_avail integer, -- new available value + log_who text, -- who did it + log_when timestamp -- when +); + +CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data + WHERE NEW.sl_avail <> OLD.sl_avail + DO INSERT INTO shoelace_log VALUES ( + NEW.sl_name, + NEW.sl_avail, + current_user, + current_timestamp + ); + + + + + Now someone does: + + +UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7'; + + + and we look at the log table: + + +SELECT * FROM shoelace_log; + + sl_name | sl_avail | log_who | log_when +---------+----------+---------+---------------------------------- + sl7 | 6 | Al | Tue Oct 20 16:14:45 1998 MET DST +(1 row) + + + + + That's what we expected. What happened in the background is the following. + The parser created the query tree: + + +UPDATE shoelace_data SET sl_avail = 6 + FROM shoelace_data shoelace_data + WHERE shoelace_data.sl_name = 'sl7'; + + + There is a rule log_shoelace that is ON UPDATE with the rule + qualification expression: + + +NEW.sl_avail <> OLD.sl_avail + + + and the action: + + +INSERT INTO shoelace_log VALUES ( + new.sl_name, new.sl_avail, + current_user, current_timestamp ) + FROM shoelace_data new, shoelace_data old; + + + (This looks a little strange since you cannot normally write + INSERT ... VALUES ... FROM. The FROM + clause here is just to indicate that there are range-table entries + in the query tree for new and old. + These are needed so that they can be referenced by variables in + the INSERT command's query tree.) + + + + The rule is a qualified ALSO rule, so the rule system + has to return two query trees: the modified rule action and the original + query tree. In step 1, the range table of the original query is + incorporated into the rule's action query tree. This results in: + + +INSERT INTO shoelace_log VALUES ( + new.sl_name, new.sl_avail, + current_user, current_timestamp ) + FROM shoelace_data new, shoelace_data old, + shoelace_data shoelace_data; + + + In step 2, the rule qualification is added to it, so the result set + is restricted to rows where sl_avail changes: + + +INSERT INTO shoelace_log VALUES ( + new.sl_name, new.sl_avail, + current_user, current_timestamp ) + FROM shoelace_data new, shoelace_data old, + shoelace_data shoelace_data + WHERE new.sl_avail <> old.sl_avail; + + + (This looks even stranger, since INSERT ... VALUES doesn't have + a WHERE clause either, but the planner and executor will have no + difficulty with it. They need to support this same functionality + anyway for INSERT ... SELECT.) + + + + In step 3, the original query tree's qualification is added, + restricting the result set further to only the rows that would have been touched + by the original query: + + +INSERT INTO shoelace_log VALUES ( + new.sl_name, new.sl_avail, + current_user, current_timestamp ) + FROM shoelace_data new, shoelace_data old, + shoelace_data shoelace_data + WHERE new.sl_avail <> old.sl_avail + AND shoelace_data.sl_name = 'sl7'; + + + + + Step 4 replaces references to NEW by the target list entries from the + original query tree or by the matching variable references + from the result relation: + + +INSERT INTO shoelace_log VALUES ( + shoelace_data.sl_name, 6, + current_user, current_timestamp ) + FROM shoelace_data new, shoelace_data old, + shoelace_data shoelace_data + WHERE 6 <> old.sl_avail + AND shoelace_data.sl_name = 'sl7'; + + + + + + Step 5 changes OLD references into result relation references: + + +INSERT INTO shoelace_log VALUES ( + shoelace_data.sl_name, 6, + current_user, current_timestamp ) + FROM shoelace_data new, shoelace_data old, + shoelace_data shoelace_data + WHERE 6 <> shoelace_data.sl_avail + AND shoelace_data.sl_name = 'sl7'; + + + + + That's it. Since the rule is ALSO, we also output the + original query tree. In short, the output from the rule system + is a list of two query trees that correspond to these statements: + + +INSERT INTO shoelace_log VALUES ( + shoelace_data.sl_name, 6, + current_user, current_timestamp ) + FROM shoelace_data + WHERE 6 <> shoelace_data.sl_avail + AND shoelace_data.sl_name = 'sl7'; + +UPDATE shoelace_data SET sl_avail = 6 + WHERE sl_name = 'sl7'; + + + These are executed in this order, and that is exactly what + the rule was meant to do. + + + + The substitutions and the added qualifications + ensure that, if the original query would be, say: + + +UPDATE shoelace_data SET sl_color = 'green' + WHERE sl_name = 'sl7'; + + + no log entry would get written. In that case, the original query + tree does not contain a target list entry for + sl_avail, so NEW.sl_avail will get + replaced by shoelace_data.sl_avail. Thus, the extra + command generated by the rule is: + + +INSERT INTO shoelace_log VALUES ( + shoelace_data.sl_name, shoelace_data.sl_avail, + current_user, current_timestamp ) + FROM shoelace_data + WHERE shoelace_data.sl_avail <> shoelace_data.sl_avail + AND shoelace_data.sl_name = 'sl7'; + + + and that qualification will never be true. + + + + It will also work if the original query modifies multiple rows. So + if someone issued the command: + + +UPDATE shoelace_data SET sl_avail = 0 + WHERE sl_color = 'black'; + + + four rows in fact get updated (sl1, sl2, sl3, and sl4). + But sl3 already has sl_avail = 0. In this case, the original + query trees qualification is different and that results + in the extra query tree: + + +INSERT INTO shoelace_log +SELECT shoelace_data.sl_name, 0, + current_user, current_timestamp + FROM shoelace_data + WHERE 0 <> shoelace_data.sl_avail + AND shoelace_data.sl_color = 'black'; + + + being generated by the rule. This query tree will surely insert + three new log entries. And that's absolutely correct. + + + + Here we can see why it is important that the original query tree + is executed last. If the UPDATE had been + executed first, all the rows would have already been set to zero, so the + logging INSERT would not find any row where + 0 <> shoelace_data.sl_avail. + + + + + + +Cooperation with Views + +viewupdating + + + A simple way to protect view relations from the mentioned + possibility that someone can try to run INSERT, + UPDATE, or DELETE on them is + to let those query trees get thrown away. So we could create the rules: + + +CREATE RULE shoe_ins_protect AS ON INSERT TO shoe + DO INSTEAD NOTHING; +CREATE RULE shoe_upd_protect AS ON UPDATE TO shoe + DO INSTEAD NOTHING; +CREATE RULE shoe_del_protect AS ON DELETE TO shoe + DO INSTEAD NOTHING; + + + If someone now tries to do any of these operations on the view + relation shoe, the rule system will + apply these rules. Since the rules have + no actions and are INSTEAD, the resulting list of + query trees will be empty and the whole query will become + nothing because there is nothing left to be optimized or + executed after the rule system is done with it. + + + + A more sophisticated way to use the rule system is to + create rules that rewrite the query tree into one that + does the right operation on the real tables. To do that + on the shoelace view, we create + the following rules: + + +CREATE RULE shoelace_ins AS ON INSERT TO shoelace + DO INSTEAD + INSERT INTO shoelace_data VALUES ( + NEW.sl_name, + NEW.sl_avail, + NEW.sl_color, + NEW.sl_len, + NEW.sl_unit + ); + +CREATE RULE shoelace_upd AS ON UPDATE TO shoelace + DO INSTEAD + UPDATE shoelace_data + SET sl_name = NEW.sl_name, + sl_avail = NEW.sl_avail, + sl_color = NEW.sl_color, + sl_len = NEW.sl_len, + sl_unit = NEW.sl_unit + WHERE sl_name = OLD.sl_name; + +CREATE RULE shoelace_del AS ON DELETE TO shoelace + DO INSTEAD + DELETE FROM shoelace_data + WHERE sl_name = OLD.sl_name; + + + + + If you want to support RETURNING queries on the view, + you need to make the rules include RETURNING clauses that + compute the view rows. This is usually pretty trivial for views on a + single table, but it's a bit tedious for join views such as + shoelace. An example for the insert case is: + + +CREATE RULE shoelace_ins AS ON INSERT TO shoelace + DO INSTEAD + INSERT INTO shoelace_data VALUES ( + NEW.sl_name, + NEW.sl_avail, + NEW.sl_color, + NEW.sl_len, + NEW.sl_unit + ) + RETURNING + shoelace_data.*, + (SELECT shoelace_data.sl_len * u.un_fact + FROM unit u WHERE shoelace_data.sl_unit = u.un_name); + + + Note that this one rule supports both INSERT and + INSERT RETURNING queries on the view — the + RETURNING clause is simply ignored for INSERT. + + + + Now assume that once in a while, a pack of shoelaces arrives at + the shop and a big parts list along with it. But you don't want + to manually update the shoelace view every + time. Instead we set up two little tables: one where you can + insert the items from the part list, and one with a special + trick. The creation commands for these are: + + +CREATE TABLE shoelace_arrive ( + arr_name text, + arr_quant integer +); + +CREATE TABLE shoelace_ok ( + ok_name text, + ok_quant integer +); + +CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok + DO INSTEAD + UPDATE shoelace + SET sl_avail = sl_avail + NEW.ok_quant + WHERE sl_name = NEW.ok_name; + + + Now you can fill the table shoelace_arrive with + the data from the parts list: + + +SELECT * FROM shoelace_arrive; + + arr_name | arr_quant +----------+----------- + sl3 | 10 + sl6 | 20 + sl8 | 20 +(3 rows) + + + Take a quick look at the current data: + + +SELECT * FROM shoelace; + + sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm +----------+----------+----------+--------+---------+----------- + sl1 | 5 | black | 80 | cm | 80 + sl2 | 6 | black | 100 | cm | 100 + sl7 | 6 | brown | 60 | cm | 60 + sl3 | 0 | black | 35 | inch | 88.9 + sl4 | 8 | black | 40 | inch | 101.6 + sl8 | 1 | brown | 40 | inch | 101.6 + sl5 | 4 | brown | 1 | m | 100 + sl6 | 0 | brown | 0.9 | m | 90 +(8 rows) + + + Now move the arrived shoelaces in: + + +INSERT INTO shoelace_ok SELECT * FROM shoelace_arrive; + + + and check the results: + + +SELECT * FROM shoelace ORDER BY sl_name; + + sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm +----------+----------+----------+--------+---------+----------- + sl1 | 5 | black | 80 | cm | 80 + sl2 | 6 | black | 100 | cm | 100 + sl7 | 6 | brown | 60 | cm | 60 + sl4 | 8 | black | 40 | inch | 101.6 + sl3 | 10 | black | 35 | inch | 88.9 + sl8 | 21 | brown | 40 | inch | 101.6 + sl5 | 4 | brown | 1 | m | 100 + sl6 | 20 | brown | 0.9 | m | 90 +(8 rows) + +SELECT * FROM shoelace_log; + + sl_name | sl_avail | log_who| log_when +---------+----------+--------+---------------------------------- + sl7 | 6 | Al | Tue Oct 20 19:14:45 1998 MET DST + sl3 | 10 | Al | Tue Oct 20 19:25:16 1998 MET DST + sl6 | 20 | Al | Tue Oct 20 19:25:16 1998 MET DST + sl8 | 21 | Al | Tue Oct 20 19:25:16 1998 MET DST +(4 rows) + + + + + It's a long way from the one INSERT ... SELECT + to these results. And the description of the query-tree + transformation will be the last in this chapter. First, there is + the parser's output: + + +INSERT INTO shoelace_ok +SELECT shoelace_arrive.arr_name, shoelace_arrive.arr_quant + FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok; + + + Now the first rule shoelace_ok_ins is applied and turns this + into: + + +UPDATE shoelace + SET sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant + FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok, + shoelace_ok old, shoelace_ok new, + shoelace shoelace + WHERE shoelace.sl_name = shoelace_arrive.arr_name; + + + and throws away the original INSERT on + shoelace_ok. This rewritten query is passed to + the rule system again, and the second applied rule + shoelace_upd produces: + + +UPDATE shoelace_data + SET sl_name = shoelace.sl_name, + sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant, + sl_color = shoelace.sl_color, + sl_len = shoelace.sl_len, + sl_unit = shoelace.sl_unit + FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok, + shoelace_ok old, shoelace_ok new, + shoelace shoelace, shoelace old, + shoelace new, shoelace_data shoelace_data + WHERE shoelace.sl_name = shoelace_arrive.arr_name + AND shoelace_data.sl_name = shoelace.sl_name; + + + Again it's an INSTEAD rule and the previous query tree is trashed. + Note that this query still uses the view shoelace. + But the rule system isn't finished with this step, so it continues + and applies the _RETURN rule on it, and we get: + + +UPDATE shoelace_data + SET sl_name = s.sl_name, + sl_avail = s.sl_avail + shoelace_arrive.arr_quant, + sl_color = s.sl_color, + sl_len = s.sl_len, + sl_unit = s.sl_unit + FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok, + shoelace_ok old, shoelace_ok new, + shoelace shoelace, shoelace old, + shoelace new, shoelace_data shoelace_data, + shoelace old, shoelace new, + shoelace_data s, unit u + WHERE s.sl_name = shoelace_arrive.arr_name + AND shoelace_data.sl_name = s.sl_name; + + + Finally, the rule log_shoelace gets applied, + producing the extra query tree: + + +INSERT INTO shoelace_log +SELECT s.sl_name, + s.sl_avail + shoelace_arrive.arr_quant, + current_user, + current_timestamp + FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok, + shoelace_ok old, shoelace_ok new, + shoelace shoelace, shoelace old, + shoelace new, shoelace_data shoelace_data, + shoelace old, shoelace new, + shoelace_data s, unit u, + shoelace_data old, shoelace_data new + shoelace_log shoelace_log + WHERE s.sl_name = shoelace_arrive.arr_name + AND shoelace_data.sl_name = s.sl_name + AND (s.sl_avail + shoelace_arrive.arr_quant) <> s.sl_avail; + + + After that the rule system runs out of rules and returns the + generated query trees. + + + + So we end up with two final query trees that are equivalent to the + SQL statements: + + +INSERT INTO shoelace_log +SELECT s.sl_name, + s.sl_avail + shoelace_arrive.arr_quant, + current_user, + current_timestamp + FROM shoelace_arrive shoelace_arrive, shoelace_data shoelace_data, + shoelace_data s + WHERE s.sl_name = shoelace_arrive.arr_name + AND shoelace_data.sl_name = s.sl_name + AND s.sl_avail + shoelace_arrive.arr_quant <> s.sl_avail; + +UPDATE shoelace_data + SET sl_avail = shoelace_data.sl_avail + shoelace_arrive.arr_quant + FROM shoelace_arrive shoelace_arrive, + shoelace_data shoelace_data, + shoelace_data s + WHERE s.sl_name = shoelace_arrive.sl_name + AND shoelace_data.sl_name = s.sl_name; + + + The result is that data coming from one relation inserted into another, + changed into updates on a third, changed into updating + a fourth plus logging that final update in a fifth + gets reduced into two queries. + + + + There is a little detail that's a bit ugly. Looking at the two + queries, it turns out that the shoelace_data + relation appears twice in the range table where it could + definitely be reduced to one. The planner does not handle it and + so the execution plan for the rule systems output of the + INSERT will be + + +Nested Loop + -> Merge Join + -> Seq Scan + -> Sort + -> Seq Scan on s + -> Seq Scan + -> Sort + -> Seq Scan on shoelace_arrive + -> Seq Scan on shoelace_data + + + while omitting the extra range table entry would result in a + + +Merge Join + -> Seq Scan + -> Sort + -> Seq Scan on s + -> Seq Scan + -> Sort + -> Seq Scan on shoelace_arrive + + + which produces exactly the same entries in the log table. Thus, + the rule system caused one extra scan on the table + shoelace_data that is absolutely not + necessary. And the same redundant scan is done once more in the + UPDATE. But it was a really hard job to make + that all possible at all. + + + + Now we make a final demonstration of the + PostgreSQL rule system and its power. + Say you add some shoelaces with extraordinary colors to your + database: + + +INSERT INTO shoelace VALUES ('sl9', 0, 'pink', 35.0, 'inch', 0.0); +INSERT INTO shoelace VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0); + + + We would like to make a view to check which + shoelace entries do not fit any shoe in color. + The view for this is: + + +CREATE VIEW shoelace_mismatch AS + SELECT * FROM shoelace WHERE NOT EXISTS + (SELECT shoename FROM shoe WHERE slcolor = sl_color); + + + Its output is: + + +SELECT * FROM shoelace_mismatch; + + sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm +---------+----------+----------+--------+---------+----------- + sl9 | 0 | pink | 35 | inch | 88.9 + sl10 | 1000 | magenta | 40 | inch | 101.6 + + + + + Now we want to set it up so that mismatching shoelaces that are + not in stock are deleted from the database. + To make it a little harder for PostgreSQL, + we don't delete it directly. Instead we create one more view: + + +CREATE VIEW shoelace_can_delete AS + SELECT * FROM shoelace_mismatch WHERE sl_avail = 0; + + + and do it this way: + + +DELETE FROM shoelace WHERE EXISTS + (SELECT * FROM shoelace_can_delete + WHERE sl_name = shoelace.sl_name); + + + The results are: + + +SELECT * FROM shoelace; + + sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm +---------+----------+----------+--------+---------+----------- + sl1 | 5 | black | 80 | cm | 80 + sl2 | 6 | black | 100 | cm | 100 + sl7 | 6 | brown | 60 | cm | 60 + sl4 | 8 | black | 40 | inch | 101.6 + sl3 | 10 | black | 35 | inch | 88.9 + sl8 | 21 | brown | 40 | inch | 101.6 + sl10 | 1000 | magenta | 40 | inch | 101.6 + sl5 | 4 | brown | 1 | m | 100 + sl6 | 20 | brown | 0.9 | m | 90 +(9 rows) + + + + + A DELETE on a view, with a subquery qualification that + in total uses 4 nesting/joined views, where one of them + itself has a subquery qualification containing a view + and where calculated view columns are used, + gets rewritten into + one single query tree that deletes the requested data + from a real table. + + + + There are probably only a few situations out in the real world + where such a construct is necessary. But it makes you feel + comfortable that it works. + + + + + + +Rules and Privileges + + + privilege + with rules + + + + privilege + with views + + + + Due to rewriting of queries by the PostgreSQL + rule system, other tables/views than those used in the original + query get accessed. When update rules are used, this can include write access + to tables. + + + + Rewrite rules don't have a separate owner. The owner of + a relation (table or view) is automatically the owner of the + rewrite rules that are defined for it. + The PostgreSQL rule system changes the + behavior of the default access control system. Relations that + are used due to rules get checked against the + privileges of the rule owner, not the user invoking the rule. + This means that users only need the required privileges + for the tables/views that are explicitly named in their queries. + + + + For example: A user has a list of phone numbers where some of + them are private, the others are of interest for the assistant of the office. + The user can construct the following: + + +CREATE TABLE phone_data (person text, phone text, private boolean); +CREATE VIEW phone_number AS + SELECT person, CASE WHEN NOT private THEN phone END AS phone + FROM phone_data; +GRANT SELECT ON phone_number TO assistant; + + + Nobody except that user (and the database superusers) can access the + phone_data table. But because of the GRANT, + the assistant can run a SELECT on the + phone_number view. The rule system will rewrite the + SELECT from phone_number into a + SELECT from phone_data. + Since the user is the owner of + phone_number and therefore the owner of the rule, the + read access to phone_data is now checked against the user's + privileges and the query is permitted. The check for accessing + phone_number is also performed, but this is done + against the invoking user, so nobody but the user and the + assistant can use it. + + + + The privileges are checked rule by rule. So the assistant is for now the + only one who can see the public phone numbers. But the assistant can set up + another view and grant access to that to the public. Then, anyone + can see the phone_number data through the assistant's view. + What the assistant cannot do is to create a view that directly + accesses phone_data. (Actually the assistant can, but it will not work since + every access will be denied during the permission checks.) + And as soon as the user notices that the assistant opened + their phone_number view, the user can revoke the assistant's access. Immediately, any + access to the assistant's view would fail. + + + + One might think that this rule-by-rule checking is a security + hole, but in fact it isn't. But if it did not work this way, the assistant + could set up a table with the same columns as phone_number and + copy the data to there once per day. Then it's the assistant's own data and + the assistant can grant access to everyone they want. A + GRANT command means, I trust you. + If someone you trust does the thing above, it's time to + think it over and then use REVOKE. + + + + Note that while views can be used to hide the contents of certain + columns using the technique shown above, they cannot be used to reliably + conceal the data in unseen rows unless the + security_barrier flag has been set. For example, + the following view is insecure: + +CREATE VIEW phone_number AS + SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%'; + + This view might seem secure, since the rule system will rewrite any + SELECT from phone_number into a + SELECT from phone_data and add the + qualification that only entries where phone does not begin + with 412 are wanted. But if the user can create their own functions, + it is not difficult to convince the planner to execute the user-defined + function prior to the NOT LIKE expression. + For example: + +CREATE FUNCTION tricky(text, text) RETURNS bool AS $$ +BEGIN + RAISE NOTICE '% => %', $1, $2; + RETURN true; +END; +$$ LANGUAGE plpgsql COST 0.0000000000000000000001; + +SELECT * FROM phone_number WHERE tricky(person, phone); + + Every person and phone number in the phone_data table will be + printed as a NOTICE, because the planner will choose to + execute the inexpensive tricky function before the + more expensive NOT LIKE. Even if the user is + prevented from defining new functions, built-in functions can be used in + similar attacks. (For example, most casting functions include their + input values in the error messages they produce.) + + + + Similar considerations apply to update rules. In the examples of + the previous section, the owner of the tables in the example + database could grant the privileges SELECT, + INSERT, UPDATE, and DELETE on + the shoelace view to someone else, but only + SELECT on shoelace_log. The rule action to + write log entries will still be executed successfully, and that + other user could see the log entries. But they could not create fake + entries, nor could they manipulate or remove existing ones. In this + case, there is no possibility of subverting the rules by convincing + the planner to alter the order of operations, because the only rule + which references shoelace_log is an unqualified + INSERT. This might not be true in more complex scenarios. + + + + When it is necessary for a view to provide row-level security, the + security_barrier attribute should be applied to + the view. This prevents maliciously-chosen functions and operators from + being passed values from rows until after the view has done its work. For + example, if the view shown above had been created like this, it would + be secure: + +CREATE VIEW phone_number WITH (security_barrier) AS + SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%'; + + Views created with the security_barrier may perform + far worse than views created without this option. In general, there is + no way to avoid this: the fastest possible plan must be rejected + if it may compromise security. For this reason, this option is not + enabled by default. + + + + The query planner has more flexibility when dealing with functions that + have no side effects. Such functions are referred to as LEAKPROOF, and + include many simple, commonly used operators, such as many equality + operators. The query planner can safely allow such functions to be evaluated + at any point in the query execution process, since invoking them on rows + invisible to the user will not leak any information about the unseen rows. + Further, functions which do not take arguments or which are not passed any + arguments from the security barrier view do not have to be marked as + LEAKPROOF to be pushed down, as they never receive data + from the view. In contrast, a function that might throw an error depending + on the values received as arguments (such as one that throws an error in the + event of overflow or division by zero) is not leak-proof, and could provide + significant information about the unseen rows if applied before the security + view's row filters. + + + + It is important to understand that even a view created with the + security_barrier option is intended to be secure only + in the limited sense that the contents of the invisible tuples will not be + passed to possibly-insecure functions. The user may well have other means + of making inferences about the unseen data; for example, they can see the + query plan using EXPLAIN, or measure the run time of + queries against the view. A malicious attacker might be able to infer + something about the amount of unseen data, or even gain some information + about the data distribution or most common values (since these things may + affect the run time of the plan; or even, since they are also reflected in + the optimizer statistics, the choice of plan). If these types of "covert + channel" attacks are of concern, it is probably unwise to grant any access + to the data at all. + + + + +Rules and Command Status + + + The PostgreSQL server returns a command + status string, such as INSERT 149592 1, for each + command it receives. This is simple enough when there are no rules + involved, but what happens when the query is rewritten by rules? + + + + Rules affect the command status as follows: + + + + + If there is no unconditional INSTEAD rule for the query, then + the originally given query will be executed, and its command + status will be returned as usual. (But note that if there were + any conditional INSTEAD rules, the negation of their qualifications + will have been added to the original query. This might reduce the + number of rows it processes, and if so the reported status will + be affected.) + + + + + + If there is any unconditional INSTEAD rule for the query, then + the original query will not be executed at all. In this case, + the server will return the command status for the last query + that was inserted by an INSTEAD rule (conditional or + unconditional) and is of the same command type + (INSERT, UPDATE, or + DELETE) as the original query. If no query + meeting those requirements is added by any rule, then the + returned command status shows the original query type and + zeroes for the row-count and OID fields. + + + + + + + The programmer can ensure that any desired INSTEAD rule is the one + that sets the command status in the second case, by giving it the + alphabetically last rule name among the active rules, so that it + gets applied last. + + + + +Rules Versus Triggers + + + rule + compared with triggers + + + + trigger + compared with rules + + + + Many things that can be done using triggers can also be + implemented using the PostgreSQL + rule system. One of the things that cannot be implemented by + rules are some kinds of constraints, especially foreign keys. It is possible + to place a qualified rule that rewrites a command to NOTHING + if the value of a column does not appear in another table. + But then the data is silently thrown away and that's + not a good idea. If checks for valid values are required, + and in the case of an invalid value an error message should + be generated, it must be done by a trigger. + + + + In this chapter, we focused on using rules to update views. All of + the update rule examples in this chapter can also be implemented + using INSTEAD OF triggers on the views. Writing such + triggers is often easier than writing rules, particularly if complex + logic is required to perform the update. + + + + For the things that can be implemented by both, which is best + depends on the usage of the database. + A trigger is fired once for each affected row. A rule modifies + the query or generates an additional query. So if many + rows are affected in one statement, a rule issuing one extra + command is likely to be faster than a trigger that is + called for every single row and must re-determine what to do + many times. However, the trigger approach is conceptually far + simpler than the rule approach, and is easier for novices to get right. + + + + Here we show an example of how the choice of rules versus triggers + plays out in one situation. There are two tables: + + +CREATE TABLE computer ( + hostname text, -- indexed + manufacturer text -- indexed +); + +CREATE TABLE software ( + software text, -- indexed + hostname text -- indexed +); + + + Both tables have many thousands of rows and the indexes on + hostname are unique. The rule or trigger should + implement a constraint that deletes rows from software + that reference a deleted computer. The trigger would use this command: + + +DELETE FROM software WHERE hostname = $1; + + + Since the trigger is called for each individual row deleted from + computer, it can prepare and save the plan for this + command and pass the hostname value in the + parameter. The rule would be written as: + + +CREATE RULE computer_del AS ON DELETE TO computer + DO DELETE FROM software WHERE hostname = OLD.hostname; + + + + + Now we look at different types of deletes. In the case of a: + + +DELETE FROM computer WHERE hostname = 'mypc.local.net'; + + + the table computer is scanned by index (fast), and the + command issued by the trigger would also use an index scan (also fast). + The extra command from the rule would be: + + +DELETE FROM software WHERE computer.hostname = 'mypc.local.net' + AND software.hostname = computer.hostname; + + + Since there are appropriate indexes set up, the planner + will create a plan of + + +Nestloop + -> Index Scan using comp_hostidx on computer + -> Index Scan using soft_hostidx on software + + + So there would be not that much difference in speed between + the trigger and the rule implementation. + + + + With the next delete we want to get rid of all the 2000 computers + where the hostname starts with + old. There are two possible commands to do that. One + is: + + +DELETE FROM computer WHERE hostname >= 'old' + AND hostname < 'ole' + + + The command added by the rule will be: + + +DELETE FROM software WHERE computer.hostname >= 'old' AND computer.hostname < 'ole' + AND software.hostname = computer.hostname; + + + with the plan + + +Hash Join + -> Seq Scan on software + -> Hash + -> Index Scan using comp_hostidx on computer + + + The other possible command is: + + +DELETE FROM computer WHERE hostname ~ '^old'; + + + which results in the following executing plan for the command + added by the rule: + + +Nestloop + -> Index Scan using comp_hostidx on computer + -> Index Scan using soft_hostidx on software + + + This shows, that the planner does not realize that the + qualification for hostname in + computer could also be used for an index scan on + software when there are multiple qualification + expressions combined with AND, which is what it does + in the regular-expression version of the command. The trigger will + get invoked once for each of the 2000 old computers that have to be + deleted, and that will result in one index scan over + computer and 2000 index scans over + software. The rule implementation will do it with two + commands that use indexes. And it depends on the overall size of + the table software whether the rule will still be faster in the + sequential scan situation. 2000 command executions from the trigger over the SPI + manager take some time, even if all the index blocks will soon be in the cache. + + + + The last command we look at is: + + +DELETE FROM computer WHERE manufacturer = 'bim'; + + + Again this could result in many rows to be deleted from + computer. So the trigger will again run many commands + through the executor. The command generated by the rule will be: + + +DELETE FROM software WHERE computer.manufacturer = 'bim' + AND software.hostname = computer.hostname; + + + The plan for that command will again be the nested loop over two + index scans, only using a different index on computer: + + +Nestloop + -> Index Scan using comp_manufidx on computer + -> Index Scan using soft_hostidx on software + + + In any of these cases, the extra commands from the rule system + will be more or less independent from the number of affected rows + in a command. + + + + The summary is, rules will only be significantly slower than + triggers if their actions result in large and badly qualified + joins, a situation where the planner fails. + + + + diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml new file mode 100644 index 000000000000..f1cbc1d9e922 --- /dev/null +++ b/doc/src/sgml/runtime.sgml @@ -0,0 +1,2749 @@ + + + + Server Setup and Operation + + + This chapter discusses how to set up and run the database server, + and its interactions with the operating system. + + + + The directions in this chapter assume that you are working with + plain PostgreSQL without any additional + infrastructure, for example a copy that you built from source + according to the directions in the preceding chapters. + If you are working with a pre-packaged or vendor-supplied + version of PostgreSQL, it is likely that + the packager has made special provisions for installing and starting + the database server according to your system's conventions. + Consult the package-level documentation for details. + + + + The <productname>PostgreSQL</productname> User Account + + + postgres user + + + + As with any server daemon that is accessible to the outside world, + it is advisable to run PostgreSQL under a + separate user account. This user account should only own the data + that is managed by the server, and should not be shared with other + daemons. (For example, using the user nobody is a bad + idea.) In particular, it is advisable that this user account not own + the PostgreSQL executable files, to ensure + that a compromised server process could not modify those executables. + + + + Pre-packaged versions of PostgreSQL will + typically create a suitable user account automatically during + package installation. + + + + To add a Unix user account to your system, look for a command + useradd or adduser. The user + name postgres is often used, and is assumed + throughout this book, but you can use another name if you like. + + + + + Creating a Database Cluster + + + database cluster + + + + data area + database cluster + + + + Before you can do anything, you must initialize a database storage + area on disk. We call this a database cluster. + (The SQL standard uses the term catalog cluster.) A + database cluster is a collection of databases that is managed by a + single instance of a running database server. After initialization, a + database cluster will contain a database named postgres, + which is meant as a default database for use by utilities, users and third + party applications. The database server itself does not require the + postgres database to exist, but many external utility + programs assume it exists. Another database created within each cluster + during initialization is called + template1. As the name suggests, this will be used + as a template for subsequently created databases; it should not be + used for actual work. (See for + information about creating new databases within a cluster.) + + + + In file system terms, a database cluster is a single directory + under which all data will be stored. We call this the data + directory or data area. It is + completely up to you where you choose to store your data. There is no + default, although locations such as + /usr/local/pgsql/data or + /var/lib/pgsql/data are popular. + The data directory must be initialized before being used, using the program + initdb + which is installed with PostgreSQL. + + + + If you are using a pre-packaged version + of PostgreSQL, it may well have a specific + convention for where to place the data directory, and it may also + provide a script for creating the data directory. In that case you + should use that script in preference to + running initdb directly. + Consult the package-level documentation for details. + + + + To initialize a database cluster manually, + run initdb and specify the desired + file system location of the database cluster with the + option, for example: + +$ initdb -D /usr/local/pgsql/data + + Note that you must execute this command while logged into the + PostgreSQL user account, which is + described in the previous section. + + + + + As an alternative to the option, you can set + the environment variable PGDATA. + PGDATA + + + + + Alternatively, you can run initdb via + the + programpg_ctl like so: + +$ pg_ctl -D /usr/local/pgsql/data initdb + + This may be more intuitive if you are + using pg_ctl for starting and stopping the + server (see ), so + that pg_ctl would be the sole command you use + for managing the database server instance. + + + + initdb will attempt to create the directory you + specify if it does not already exist. Of course, this will fail if + initdb does not have permissions to write in the + parent directory. It's generally recommendable that the + PostgreSQL user own not just the data + directory but its parent directory as well, so that this should not + be a problem. If the desired parent directory doesn't exist either, + you will need to create it first, using root privileges if the + grandparent directory isn't writable. So the process might look + like this: + +root# mkdir /usr/local/pgsql +root# chown postgres /usr/local/pgsql +root# su postgres +postgres$ initdb -D /usr/local/pgsql/data + + + + + initdb will refuse to run if the data directory + exists and already contains files; this is to prevent accidentally + overwriting an existing installation. + + + + Because the data directory contains all the data stored in the + database, it is essential that it be secured from unauthorized + access. initdb therefore revokes access + permissions from everyone but the + PostgreSQL user, and optionally, group. + Group access, when enabled, is read-only. This allows an unprivileged + user in the same group as the cluster owner to take a backup of the + cluster data or perform other operations that only require read access. + + + + Note that enabling or disabling group access on an existing cluster requires + the cluster to be shut down and the appropriate mode to be set on all + directories and files before restarting + PostgreSQL. Otherwise, a mix of modes might + exist in the data directory. For clusters that allow access only by the + owner, the appropriate modes are 0700 for directories + and 0600 for files. For clusters that also allow + reads by the group, the appropriate modes are 0750 + for directories and 0640 for files. + + + + However, while the directory contents are secure, the default + client authentication setup allows any local user to connect to the + database and even become the database superuser. If you do not + trust other local users, we recommend you use one of + initdb's , + or options to assign a password to the + database superuser. + password + of the superuser + + Also, specify or + so that the default trust authentication + mode is not used; or modify the generated pg_hba.conf + file after running initdb, but + before you start the server for the first time. (Other + reasonable approaches include using peer authentication + or file system permissions to restrict connections. See for more information.) + + + + initdb also initializes the default + localelocale for the database cluster. + Normally, it will just take the locale settings in the environment + and apply them to the initialized database. It is possible to + specify a different locale for the database; more information about + that can be found in . The default sort order used + within the particular database cluster is set by + initdb, and while you can create new databases using + different sort order, the order used in the template databases that initdb + creates cannot be changed without dropping and recreating them. + There is also a performance impact for using locales + other than C or POSIX. Therefore, it is + important to make this choice correctly the first time. + + + + initdb also sets the default character set encoding + for the database cluster. Normally this should be chosen to match the + locale setting. For details see . + + + + Non-C and non-POSIX locales rely on the + operating system's collation library for character set ordering. + This controls the ordering of keys stored in indexes. For this reason, + a cluster cannot switch to an incompatible collation library version, + either through snapshot restore, binary streaming replication, a + different operating system, or an operating system upgrade. + + + + Use of Secondary File Systems + + + file system mount points + + + + Many installations create their database clusters on file systems + (volumes) other than the machine's root volume. If you + choose to do this, it is not advisable to try to use the secondary + volume's topmost directory (mount point) as the data directory. + Best practice is to create a directory within the mount-point + directory that is owned by the PostgreSQL + user, and then create the data directory within that. This avoids + permissions problems, particularly for operations such + as pg_upgrade, and it also ensures clean failures if + the secondary volume is taken offline. + + + + + + File Systems + + + Generally, any file system with POSIX semantics can be used for + PostgreSQL. Users prefer different file systems for a variety of reasons, + including vendor support, performance, and familiarity. Experience + suggests that, all other things being equal, one should not expect major + performance or behavior changes merely from switching file systems or + making minor file system configuration changes. + + + + NFS + + + NFS + + + + It is possible to use an NFS file system for storing + the PostgreSQL data directory. + PostgreSQL does nothing special for + NFS file systems, meaning it assumes + NFS behaves exactly like locally-connected drives. + PostgreSQL does not use any functionality that + is known to have nonstandard behavior on NFS, such as + file locking. + + + + The only firm requirement for using NFS with + PostgreSQL is that the file system is mounted + using the hard option. With the + hard option, processes can hang + indefinitely if there are network problems, so this configuration will + require a careful monitoring setup. The soft option + will interrupt system calls in case of network problems, but + PostgreSQL will not repeat system calls + interrupted in this way, so any such interruption will result in an I/O + error being reported. + + + + It is not necessary to use the sync mount option. The + behavior of the async option is sufficient, since + PostgreSQL issues fsync + calls at appropriate times to flush the write caches. (This is analogous + to how it works on a local file system.) However, it is strongly + recommended to use the sync export option on the NFS + server on systems where it exists (mainly Linux). + Otherwise, an fsync or equivalent on the NFS client is + not actually guaranteed to reach permanent storage on the server, which + could cause corruption similar to running with the parameter off. The defaults of these mount and export + options differ between vendors and versions, so it is recommended to + check and perhaps specify them explicitly in any case to avoid any + ambiguity. + + + + In some cases, an external storage product can be accessed either via NFS + or a lower-level protocol such as iSCSI. In the latter case, the storage + appears as a block device and any available file system can be created on + it. That approach might relieve the DBA from having to deal with some of + the idiosyncrasies of NFS, but of course the complexity of managing + remote storage then happens at other levels. + + + + + + + + Starting the Database Server + + + Before anyone can access the database, you must start the database + server. The database server program is called + postgres.postgres + + + + If you are using a pre-packaged version + of PostgreSQL, it almost certainly includes + provisions for running the server as a background task according to the + conventions of your operating system. Using the package's + infrastructure to start the server will be much less work than figuring + out how to do this yourself. Consult the package-level documentation + for details. + + + + The bare-bones way to start the server manually is just to invoke + postgres directly, specifying the location of the + data directory with the option, for example: + +$ postgres -D /usr/local/pgsql/data + + which will leave the server running in the foreground. This must be + done while logged into the PostgreSQL user + account. Without , the server will try to use + the data directory named by the environment variable PGDATA. + If that variable is not provided either, it will fail. + + + + Normally it is better to start postgres in the + background. For this, use the usual Unix shell syntax: + +$ postgres -D /usr/local/pgsql/data >logfile 2>&1 & + + It is important to store the server's stdout and + stderr output somewhere, as shown above. It will help + for auditing purposes and to diagnose problems. (See for a more thorough discussion of log + file handling.) + + + + The postgres program also takes a number of other + command-line options. For more information, see the + reference page + and below. + + + + This shell syntax can get tedious quickly. Therefore the wrapper + program + pg_ctl + is provided to simplify some tasks. For example: + +pg_ctl start -l logfile + + will start the server in the background and put the output into the + named log file. The option has the same meaning + here as for postgres. pg_ctl + is also capable of stopping the server. + + + + Normally, you will want to start the database server when the + computer boots. + booting + starting the server during + + Autostart scripts are operating-system-specific. + There are a few example scripts distributed with + PostgreSQL in the + contrib/start-scripts directory. Installing one will require + root privileges. + + + + Different systems have different conventions for starting up daemons + at boot time. Many systems have a file + /etc/rc.local or + /etc/rc.d/rc.local. Others use init.d or + rc.d directories. Whatever you do, the server must be + run by the PostgreSQL user account + and not by root or any other user. Therefore you + probably should form your commands using + su postgres -c '...'. For example: + +su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog' + + + + + Here are a few more operating-system-specific suggestions. (In each + case be sure to use the proper installation directory and user + name where we show generic values.) + + + + + For FreeBSD, look at the file + contrib/start-scripts/freebsd in the + PostgreSQL source distribution. + FreeBSDstart script + + + + + + On OpenBSD, add the following lines + to the file /etc/rc.local: + OpenBSDstart script + +if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then + su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data' + echo -n ' postgresql' +fi + + + + + + + On Linux systems either add + Linuxstart script + +/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data + + to /etc/rc.d/rc.local + or /etc/rc.local or look at the file + contrib/start-scripts/linux in the + PostgreSQL source distribution. + + + + When using systemd, you can use the following + service unit file (e.g., + at /etc/systemd/system/postgresql.service):systemd + +[Unit] +Description=PostgreSQL database server +Documentation=man:postgres(1) + +[Service] +Type=notify +User=postgres +ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data +ExecReload=/bin/kill -HUP $MAINPID +KillMode=mixed +KillSignal=SIGINT +TimeoutSec=0 + +[Install] +WantedBy=multi-user.target + + Using Type=notify requires that the server binary was + built with configure --with-systemd. + + + + Consider carefully the timeout + setting. systemd has a default timeout of 90 + seconds as of this writing and will kill a process that does not notify + readiness within that time. But a PostgreSQL + server that might have to perform crash recovery at startup could take + much longer to become ready. The suggested value of 0 disables the + timeout logic. + + + + + + On NetBSD, use either the + FreeBSD or + Linux start scripts, depending on + preference. + NetBSDstart script + + + + + + On Solaris, create a file called + /etc/init.d/postgresql that contains + the following line: + Solarisstart script + +su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data" + + Then, create a symbolic link to it in /etc/rc3.d as + S99postgresql. + + + + + + + + While the server is running, its + PID is stored in the file + postmaster.pid in the data directory. This is + used to prevent multiple server instances from + running in the same data directory and can also be used for + shutting down the server. + + + + Server Start-up Failures + + + There are several common reasons the server might fail to + start. Check the server's log file, or start it by hand (without + redirecting standard output or standard error) and see what error + messages appear. Below we explain some of the most common error + messages in more detail. + + + + +LOG: could not bind IPv4 address "127.0.0.1": Address already in use +HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. +FATAL: could not create any TCP/IP sockets + + This usually means just what it suggests: you tried to start + another server on the same port where one is already running. + However, if the kernel error message is not Address + already in use or some variant of that, there might + be a different problem. For example, trying to start a server + on a reserved port number might draw something like: + +$ postgres -p 666 +LOG: could not bind IPv4 address "127.0.0.1": Permission denied +HINT: Is another postmaster already running on port 666? If not, wait a few seconds and retry. +FATAL: could not create any TCP/IP sockets + + + + + A message like: + +FATAL: could not create shared memory segment: Invalid argument +DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600). + + probably means your kernel's limit on the size of shared memory is + smaller than the work area PostgreSQL + is trying to create (4011376640 bytes in this example). + This is only likely to happen if you have set shared_memory_type + to sysv. In that case, you + can try starting the server with a smaller-than-normal number of + buffers (), or + reconfigure your kernel to increase the allowed shared memory + size. You might also see this message when trying to start multiple + servers on the same machine, if their total space requested + exceeds the kernel limit. + + + + An error like: + +FATAL: could not create semaphores: No space left on device +DETAIL: Failed system call was semget(5440126, 17, 03600). + + does not mean you've run out of disk + space. It means your kernel's limit on the number of System V semaphores is smaller than the number + PostgreSQL wants to create. As above, + you might be able to work around the problem by starting the + server with a reduced number of allowed connections + (), but you'll eventually want to + increase the kernel limit. + + + + Details about configuring System V + IPC facilities are given in . + + + + + Client Connection Problems + + + Although the error conditions possible on the client side are quite + varied and application-dependent, a few of them might be directly + related to how the server was started. Conditions other than + those shown below should be documented with the respective client + application. + + + + +psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused + Is the server running on that host and accepting TCP/IP connections? + + This is the generic I couldn't find a server to talk + to failure. It looks like the above when TCP/IP + communication is attempted. A common mistake is to forget to + configure the server to allow TCP/IP connections. + + + + Alternatively, you might get this when attempting Unix-domain socket + communication to a local server: + +psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory + Is the server running locally and accepting connections on that socket? + + If the server is indeed running, check that the client's idea of the + socket path (here /tmp) agrees with the server's + setting. + + + + A connection failure message always shows the server address or socket + path name, which is useful in verifying that the client is trying to + connect to the right place. If there is in fact no server + listening there, the kernel error message will typically be either + Connection refused or + No such file or directory, as + illustrated. (It is important to realize that + Connection refused in this context + does not mean that the server got your + connection request and rejected it. That case will produce a + different message, as shown in .) Other error messages + such as Connection timed out might + indicate more fundamental problems, like lack of network + connectivity, or a firewall blocking the connection. + + + + + + Managing Kernel Resources + + + PostgreSQL can sometimes exhaust various operating system + resource limits, especially when multiple copies of the server are running + on the same system, or in very large installations. This section explains + the kernel resources used by PostgreSQL and the steps you + can take to resolve problems related to kernel resource consumption. + + + + Shared Memory and Semaphores + + + shared memory + + + + semaphores + + + + PostgreSQL requires the operating system to provide + inter-process communication (IPC) features, specifically + shared memory and semaphores. Unix-derived systems typically provide + System V IPC, + POSIX IPC, or both. + Windows has its own implementation of + these features and is not discussed here. + + + + By default, PostgreSQL allocates + a very small amount of System V shared memory, as well as a much larger + amount of anonymous mmap shared memory. + Alternatively, a single large System V shared memory region can be used + (see ). + + In addition a significant number of semaphores, which can be either + System V or POSIX style, are created at server startup. Currently, + POSIX semaphores are used on Linux and FreeBSD systems while other + platforms use System V semaphores. + + + + System V IPC features are typically constrained by + system-wide allocation limits. + When PostgreSQL exceeds one of these limits, + the server will refuse to start and + should leave an instructive error message describing the problem + and what to do about it. (See also .) The relevant kernel + parameters are named consistently across different systems; gives an overview. The methods to set + them, however, vary. Suggestions for some platforms are given below. + + + + <systemitem class="osname">System V</systemitem> <acronym>IPC</acronym> Parameters + + + + + + + + Name + Description + Values needed to run one PostgreSQL instance + + + + + + SHMMAX + Maximum size of shared memory segment (bytes) + at least 1kB, but the default is usually much higher + + + + SHMMIN + Minimum size of shared memory segment (bytes) + 1 + + + + SHMALL + Total amount of shared memory available (bytes or pages) + same as SHMMAX if bytes, + or ceil(SHMMAX/PAGE_SIZE) if pages, + plus room for other applications + + + + SHMSEG + Maximum number of shared memory segments per process + only 1 segment is needed, but the default is much higher + + + + SHMMNI + Maximum number of shared memory segments system-wide + like SHMSEG plus room for other applications + + + + SEMMNI + Maximum number of semaphore identifiers (i.e., sets) + at least ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) plus room for other applications + + + + SEMMNS + Maximum number of semaphores system-wide + ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) * 17 plus room for other applications + + + + SEMMSL + Maximum number of semaphores per set + at least 17 + + + + SEMMAP + Number of entries in semaphore map + see text + + + + SEMVMX + Maximum value of semaphore + at least 1000 (The default is often 32767; do not change unless necessary) + + + + +
+ + + PostgreSQL requires a few bytes of System V shared memory + (typically 48 bytes, on 64-bit platforms) for each copy of the server. + On most modern operating systems, this amount can easily be allocated. + However, if you are running many copies of the server or you explicitly + configure the server to use large amounts of System V shared memory (see + and ), it may be necessary to + increase SHMALL, which is the total amount of System V shared + memory system-wide. Note that SHMALL is measured in pages + rather than bytes on many systems. + + + + Less likely to cause problems is the minimum size for shared + memory segments (SHMMIN), which should be at most + approximately 32 bytes for PostgreSQL (it is + usually just 1). The maximum number of segments system-wide + (SHMMNI) or per-process (SHMSEG) are unlikely + to cause a problem unless your system has them set to zero. + + + + When using System V semaphores, + PostgreSQL uses one semaphore per allowed connection + (), allowed autovacuum worker process + () and allowed background + process (), in sets of 16. + Each such set will + also contain a 17th semaphore which contains a magic + number, to detect collision with semaphore sets used by + other applications. The maximum number of semaphores in the system + is set by SEMMNS, which consequently must be at least + as high as max_connections plus + autovacuum_max_workers plus max_wal_senders, + plus max_worker_processes, plus one extra for each 16 + allowed connections plus workers (see the formula in ). The parameter SEMMNI + determines the limit on the number of semaphore sets that can + exist on the system at one time. Hence this parameter must be at + least ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16). + Lowering the number + of allowed connections is a temporary workaround for failures, + which are usually confusingly worded No space + left on device, from the function semget. + + + + In some cases it might also be necessary to increase + SEMMAP to be at least on the order of + SEMMNS. If the system has this parameter + (many do not), it defines the size of the semaphore + resource map, in which each contiguous block of available semaphores + needs an entry. When a semaphore set is freed it is either added to + an existing entry that is adjacent to the freed block or it is + registered under a new map entry. If the map is full, the freed + semaphores get lost (until reboot). Fragmentation of the semaphore + space could over time lead to fewer available semaphores than there + should be. + + + + Various other settings related to semaphore undo, such as + SEMMNU and SEMUME, do not affect + PostgreSQL. + + + + When using POSIX semaphores, the number of semaphores needed is the + same as for System V, that is one semaphore per allowed connection + (), allowed autovacuum worker process + () and allowed background + process (). + On the platforms where this option is preferred, there is no specific + kernel limit on the number of POSIX semaphores. + + + + + + AIX + AIXIPC configuration + + + + It should not be necessary to do + any special configuration for such parameters as + SHMMAX, as it appears this is configured to + allow all memory to be used as shared memory. That is the + sort of configuration commonly used for other databases such + as DB/2. + + It might, however, be necessary to modify the global + ulimit information in + /etc/security/limits, as the default hard + limits for file sizes (fsize) and numbers of + files (nofiles) might be too low. + + + + + + + FreeBSD + FreeBSDIPC configuration + + + + The default shared memory settings are usually good enough, unless + you have set shared_memory_type to sysv. + System V semaphores are not used on this platform. + + + + The default IPC settings can be changed using + the sysctl or + loader interfaces. The following + parameters can be set using sysctl: + +# sysctl kern.ipc.shmall=32768 +# sysctl kern.ipc.shmmax=134217728 + + To make these settings persist over reboots, modify + /etc/sysctl.conf. + + + + If you have set shared_memory_type to + sysv, you might also want to configure your kernel + to lock System V shared memory into RAM and prevent it from being paged + out to swap. This can be accomplished using the sysctl + setting kern.ipc.shm_use_phys. + + + + If running in a FreeBSD jail, you should set its + sysvshm parameter to new, so that + it has its own separate System V shared memory namespace. + (Before FreeBSD 11.0, it was necessary to enable shared access to + the host's IPC namespace from jails, and take measures to avoid + collisions.) + + + + + + + NetBSD + NetBSDIPC configuration + + + + The default shared memory settings are usually good enough, unless + you have set shared_memory_type to sysv. + You will usually want to increase kern.ipc.semmni + and kern.ipc.semmns, + as NetBSD's default settings + for these are uncomfortably small. + + + + IPC parameters can be adjusted using sysctl, + for example: + +# sysctl -w kern.ipc.semmni=100 + + To make these settings persist over reboots, modify + /etc/sysctl.conf. + + + + If you have set shared_memory_type to + sysv, you might also want to configure your kernel + to lock System V shared memory into RAM and prevent it from being paged + out to swap. This can be accomplished using the sysctl + setting kern.ipc.shm_use_phys. + + + + + + OpenBSD + OpenBSDIPC configuration + + + + The default shared memory settings are usually good enough, unless + you have set shared_memory_type to sysv. + You will usually want to + increase kern.seminfo.semmni + and kern.seminfo.semmns, + as OpenBSD's default settings + for these are uncomfortably small. + + + + IPC parameters can be adjusted using sysctl, + for example: + +# sysctl kern.seminfo.semmni=100 + + To make these settings persist over reboots, modify + /etc/sysctl.conf. + + + + + + + HP-UX + HP-UXIPC configuration + + + + The default settings tend to suffice for normal installations. + + + IPC parameters can be set in the System + Administration Manager (SAM) under + Kernel + ConfigurationConfigurable Parameters. Choose + Create A New Kernel when you're done. + + + + + + + Linux + LinuxIPC configuration + + + + The default shared memory settings are usually good enough, unless + you have set shared_memory_type to sysv, + and even then only on older kernel versions that shipped with low defaults. + System V semaphores are not used on this platform. + + + + The shared memory size settings can be changed via the + sysctl interface. For example, to allow 16 GB: + +$ sysctl -w kernel.shmmax=17179869184 +$ sysctl -w kernel.shmall=4194304 + + To make these settings persist over reboots, see + /etc/sysctl.conf. + + + + + + + + macOS + macOSIPC configuration + + + + The default shared memory and semaphore settings are usually good enough, unless + you have set shared_memory_type to sysv. + + + The recommended method for configuring shared memory in macOS + is to create a file named /etc/sysctl.conf, + containing variable assignments such as: + +kern.sysv.shmmax=4194304 +kern.sysv.shmmin=1 +kern.sysv.shmmni=32 +kern.sysv.shmseg=8 +kern.sysv.shmall=1024 + + Note that in some macOS versions, + all five shared-memory parameters must be set in + /etc/sysctl.conf, else the values will be ignored. + + + + SHMMAX can only be set to a multiple of 4096. + + + + SHMALL is measured in 4 kB pages on this platform. + + + + It is possible to change all but SHMMNI on the fly, using + sysctl. But it's still best to set up your preferred + values via /etc/sysctl.conf, so that the values will be + kept across reboots. + + + + + + + Solaris + illumos + + + The default shared memory and semaphore settings are usually good enough for most + PostgreSQL applications. Solaris defaults + to a SHMMAX of one-quarter of system RAM. + To further adjust this setting, use a project setting associated + with the postgres user. For example, run the + following as root: + +projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres + + + + + This command adds the user.postgres project and + sets the shared memory maximum for the postgres + user to 8GB, and takes effect the next time that user logs + in, or when you restart PostgreSQL (not reload). + The above assumes that PostgreSQL is run by + the postgres user in the postgres + group. No server reboot is required. + + + + Other recommended kernel setting changes for database servers which will + have a large number of connections are: + +project.max-shm-ids=(priv,32768,deny) +project.max-sem-ids=(priv,4096,deny) +project.max-msg-ids=(priv,4096,deny) + + + + + Additionally, if you are running PostgreSQL + inside a zone, you may need to raise the zone resource usage + limits as well. See "Chapter2: Projects and Tasks" in the + System Administrator's Guide for more + information on projects and prctl. + + + + + + +
+ + + systemd RemoveIPC + + + systemd + RemoveIPC + + + + If systemd is in use, some care must be taken + that IPC resources (including shared memory) are not prematurely + removed by the operating system. This is especially of concern when + installing PostgreSQL from source. Users of distribution packages of + PostgreSQL are less likely to be affected, as + the postgres user is then normally created as a system + user. + + + + The setting RemoveIPC + in logind.conf controls whether IPC objects are + removed when a user fully logs out. System users are exempt. This + setting defaults to on in stock systemd, but + some operating system distributions default it to off. + + + + A typical observed effect when this setting is on is that shared memory + objects used for parallel query execution are removed at apparently random + times, leading to errors and warnings while attempting to open and remove + them, like + +WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory + + Different types of IPC objects (shared memory vs. semaphores, System V + vs. POSIX) are treated slightly differently + by systemd, so one might observe that some IPC + resources are not removed in the same way as others. But it is not + advisable to rely on these subtle differences. + + + + A user logging out might happen as part of a maintenance + job or manually when an administrator logs in as + the postgres user or something similar, so it is hard + to prevent in general. + + + + What is a system user is determined + at systemd compile time from + the SYS_UID_MAX setting + in /etc/login.defs. + + + + Packaging and deployment scripts should be careful to create + the postgres user as a system user by + using useradd -r, adduser --system, + or equivalent. + + + + Alternatively, if the user account was created incorrectly or cannot be + changed, it is recommended to set + +RemoveIPC=no + + in /etc/systemd/logind.conf or another appropriate + configuration file. + + + + + At least one of these two things has to be ensured, or the PostgreSQL + server will be very unreliable. + + + + + + Resource Limits + + + Unix-like operating systems enforce various kinds of resource limits + that might interfere with the operation of your + PostgreSQL server. Of particular + importance are limits on the number of processes per user, the + number of open files per process, and the amount of memory available + to each process. Each of these have a hard and a + soft limit. The soft limit is what actually counts + but it can be changed by the user up to the hard limit. The hard + limit can only be changed by the root user. The system call + setrlimit is responsible for setting these + parameters. The shell's built-in command ulimit + (Bourne shells) or limit (csh) is + used to control the resource limits from the command line. On + BSD-derived systems the file /etc/login.conf + controls the various resource limits set during login. See the + operating system documentation for details. The relevant + parameters are maxproc, + openfiles, and datasize. For + example: + +default:\ +... + :datasize-cur=256M:\ + :maxproc-cur=256:\ + :openfiles-cur=256:\ +... + + (-cur is the soft limit. Append + -max to set the hard limit.) + + + + Kernels can also have system-wide limits on some resources. + + + + On Linux + /proc/sys/fs/file-max determines the + maximum number of open files that the kernel will support. It can + be changed by writing a different number into the file or by + adding an assignment in /etc/sysctl.conf. + The maximum limit of files per process is fixed at the time the + kernel is compiled; see + /usr/src/linux/Documentation/proc.txt for + more information. + + + + + + + The PostgreSQL server uses one process + per connection so you should provide for at least as many processes + as allowed connections, in addition to what you need for the rest + of your system. This is usually not a problem but if you run + several servers on one machine things might get tight. + + + + The factory default limit on open files is often set to + socially friendly values that allow many users to + coexist on a machine without using an inappropriate fraction of + the system resources. If you run many servers on a machine this + is perhaps what you want, but on dedicated servers you might want to + raise this limit. + + + + On the other side of the coin, some systems allow individual + processes to open large numbers of files; if more than a few + processes do so then the system-wide limit can easily be exceeded. + If you find this happening, and you do not want to alter the + system-wide limit, you can set PostgreSQL's configuration parameter to + limit the consumption of open files. + + + + + Linux Memory Overcommit + + + memory overcommit + + + + OOM + + + + overcommit + + + + The default virtual memory behavior on Linux is not + optimal for PostgreSQL. Because of the + way that the kernel implements memory overcommit, the kernel might + terminate the PostgreSQL postmaster (the + supervisor server process) if the memory demands of either + PostgreSQL or another process cause the + system to run out of virtual memory. + + + + If this happens, you will see a kernel message that looks like + this (consult your system documentation and configuration on where + to look for such a message): + +Out of Memory: Killed process 12345 (postgres). + + This indicates that the postgres process + has been terminated due to memory pressure. + Although existing database connections will continue to function + normally, no new connections will be accepted. To recover, + PostgreSQL will need to be restarted. + + + + One way to avoid this problem is to run + PostgreSQL on a machine where you can + be sure that other processes will not run the machine out of + memory. If memory is tight, increasing the swap space of the + operating system can help avoid the problem, because the + out-of-memory (OOM) killer is invoked only when physical memory and + swap space are exhausted. + + + + If PostgreSQL itself is the cause of the + system running out of memory, you can avoid the problem by changing + your configuration. In some cases, it may help to lower memory-related + configuration parameters, particularly + shared_buffers, + work_mem, and + hash_mem_multiplier. + In other cases, the problem may be caused by allowing too many + connections to the database server itself. In many cases, it may + be better to reduce + max_connections + and instead make use of external connection-pooling software. + + + + It is possible to modify the + kernel's behavior so that it will not overcommit memory. + Although this setting will not prevent the OOM killer from being invoked + altogether, it will lower the chances significantly and will therefore + lead to more robust system behavior. This is done by selecting strict + overcommit mode via sysctl: + +sysctl -w vm.overcommit_memory=2 + + or placing an equivalent entry in /etc/sysctl.conf. + You might also wish to modify the related setting + vm.overcommit_ratio. For details see the kernel documentation + file . + + + + Another approach, which can be used with or without altering + vm.overcommit_memory, is to set the process-specific + OOM score adjustment value for the postmaster process to + -1000, thereby guaranteeing it will not be targeted by the OOM + killer. The simplest way to do this is to execute + +echo -1000 > /proc/self/oom_score_adj + + in the postmaster's startup script just before invoking the postmaster. + Note that this action must be done as root, or it will have no effect; + so a root-owned startup script is the easiest place to do it. If you + do this, you should also set these environment variables in the startup + script before invoking the postmaster: + +export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj +export PG_OOM_ADJUST_VALUE=0 + + These settings will cause postmaster child processes to run with the + normal OOM score adjustment of zero, so that the OOM killer can still + target them at need. You could use some other value for + PG_OOM_ADJUST_VALUE if you want the child processes to run + with some other OOM score adjustment. (PG_OOM_ADJUST_VALUE + can also be omitted, in which case it defaults to zero.) If you do not + set PG_OOM_ADJUST_FILE, the child processes will run with the + same OOM score adjustment as the postmaster, which is unwise since the + whole point is to ensure that the postmaster has a preferential setting. + + + + + + Linux Huge Pages + + + Using huge pages reduces overhead when using large contiguous chunks of + memory, as PostgreSQL does, particularly when + using large values of . To use this + feature in PostgreSQL you need a kernel + with CONFIG_HUGETLBFS=y and + CONFIG_HUGETLB_PAGE=y. You will also have to configure + the operating system to provide enough huge pages of the desired size. + To estimate the number of huge pages needed, start + PostgreSQL without huge pages enabled and check + the postmaster's anonymous shared memory segment size, as well as the + system's default and supported huge page sizes, using the + /proc and /sys file systems. + This might look like: + +$ head -1 $PGDATA/postmaster.pid +4170 +$ pmap 4170 | awk '/rw-s/ && /zero/ {print $2}' +6490428K +$ grep ^Hugepagesize /proc/meminfo +Hugepagesize: 2048 kB +$ ls /sys/kernel/mm/hugepages +hugepages-1048576kB hugepages-2048kB + + + In this example the default is 2MB, but you can also explicitly request + either 2MB or 1GB with . + + Assuming 2MB huge pages, + 6490428 / 2048 gives approximately + 3169.154, so in this example we need at + least 3170 huge pages. A larger setting would be + appropriate if other programs on the machine also need huge pages. + We can set this with: + +# sysctl -w vm.nr_hugepages=3170 + + Don't forget to add this setting to /etc/sysctl.conf + so that it is reapplied after reboots. For non-default huge page sizes, + we can instead use: + +# echo 3170 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + + It is also possible to provide these settings at boot time using + kernel parameters such as hugepagesz=2M hugepages=3170. + + + + Sometimes the kernel is not able to allocate the desired number of huge + pages immediately due to fragmentation, so it might be necessary + to repeat the command or to reboot. (Immediately after a reboot, most of + the machine's memory should be available to convert into huge pages.) + To verify the huge page allocation situation for a given size, use: + +$ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + + + + + It may also be necessary to give the database server's operating system + user permission to use huge pages by setting + vm.hugetlb_shm_group via sysctl, and/or + give permission to lock memory with ulimit -l. + + + + The default behavior for huge pages in + PostgreSQL is to use them when possible, with + the system's default huge page size, and + to fall back to normal pages on failure. To enforce the use of huge + pages, you can set + to on in postgresql.conf. + Note that with this setting PostgreSQL will fail to + start if not enough huge pages are available. + + + + For a detailed description of the Linux huge + pages feature have a look + at . + + + +
+ + + + Shutting Down the Server + + + shutdown + + + + There are several ways to shut down the database server. + Under the hood, they all reduce to sending a signal to the supervisor + postgres process. + + + + If you are using a pre-packaged version + of PostgreSQL, and you used its provisions + for starting the server, then you should also use its provisions for + stopping the server. Consult the package-level documentation for + details. + + + + When managing the server directly, you can control the type of shutdown + by sending different signals to the postgres + process: + + + + SIGTERMSIGTERM + + + This is the Smart Shutdown mode. + After receiving SIGTERM, the server + disallows new connections, but lets existing sessions end their + work normally. It shuts down only after all of the sessions terminate. + If the server is in online backup mode, it additionally waits + until online backup mode is no longer active. While backup mode is + active, new connections will still be allowed, but only to superusers + (this exception allows a superuser to connect to terminate + online backup mode). If the server is in recovery when a smart + shutdown is requested, recovery and streaming replication will be + stopped only after all regular sessions have terminated. + + + + + + SIGINTSIGINT + + + This is the Fast Shutdown mode. + The server disallows new connections and sends all existing + server processes SIGTERM, which will cause them + to abort their current transactions and exit promptly. It then + waits for all server processes to exit and finally shuts down. + If the server is in online backup mode, backup mode will be + terminated, rendering the backup useless. + + + + + + SIGQUITSIGQUIT + + + This is the Immediate Shutdown mode. + The server will send SIGQUIT to all child + processes and wait for them to terminate. If any do not terminate + within 5 seconds, they will be sent SIGKILL. + The supervisor server process exits as soon as all child processes have + exited, without doing normal database shutdown processing. + This will lead to recovery (by + replaying the WAL log) upon next start-up. This is recommended + only in emergencies. + + + + + + + + The program provides a convenient + interface for sending these signals to shut down the server. + Alternatively, you can send the signal directly using kill + on non-Windows systems. + The PID of the postgres process can be + found using the ps program, or from the file + postmaster.pid in the data directory. For + example, to do a fast shutdown: + +$ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` + + + + + + It is best not to use SIGKILL to shut down the + server. Doing so will prevent the server from releasing shared memory and + semaphores. Furthermore, SIGKILL kills + the postgres process without letting it relay the + signal to its subprocesses, so it might be necessary to kill the + individual subprocesses by hand as well. + + + + + To terminate an individual session while allowing other sessions to + continue, use pg_terminate_backend() (see ) or send a + SIGTERM signal to the child process associated with + the session. + + + + + Upgrading a <productname>PostgreSQL</productname> Cluster + + + upgrading + + + + version + compatibility + + + + This section discusses how to upgrade your database data from one + PostgreSQL release to a newer one. + + + + Current PostgreSQL version numbers consist of a + major and a minor version number. For example, in the version number 10.1, + the 10 is the major version number and the 1 is the minor version number, + meaning this would be the first minor release of the major release 10. For + releases before PostgreSQL version 10.0, version + numbers consist of three numbers, for example, 9.5.3. In those cases, the + major version consists of the first two digit groups of the version number, + e.g., 9.5, and the minor version is the third number, e.g., 3, meaning this + would be the third minor release of the major release 9.5. + + + + Minor releases never change the internal storage format and are always + compatible with earlier and later minor releases of the same major version + number. For example, version 10.1 is compatible with version 10.0 and + version 10.6. Similarly, for example, 9.5.3 is compatible with 9.5.0, + 9.5.1, and 9.5.6. To update between compatible versions, you simply + replace the executables while the server is down and restart the server. + The data directory remains unchanged — minor upgrades are that + simple. + + + + For major releases of PostgreSQL, the + internal data storage format is subject to change, thus complicating + upgrades. The traditional method for moving data to a new major version + is to dump and reload the database, though this can be slow. A + faster method is . Replication methods are + also available, as discussed below. + (If you are using a pre-packaged version + of PostgreSQL, it may provide scripts to + assist with major version upgrades. Consult the package-level + documentation for details.) + + + + New major versions also typically introduce some user-visible + incompatibilities, so application programming changes might be required. + All user-visible changes are listed in the release notes (); pay particular attention to the section + labeled "Migration". Though you can upgrade from one major version + to another without upgrading to intervening versions, you should read + the major release notes of all intervening versions. + + + + Cautious users will want to test their client applications on the new + version before switching over fully; therefore, it's often a good idea to + set up concurrent installations of old and new versions. When + testing a PostgreSQL major upgrade, consider the + following categories of possible changes: + + + + + + Administration + + + The capabilities available for administrators to monitor and control + the server often change and improve in each major release. + + + + + + SQL + + + Typically this includes new SQL command capabilities and not changes + in behavior, unless specifically mentioned in the release notes. + + + + + + Library API + + + Typically libraries like libpq only add new + functionality, again unless mentioned in the release notes. + + + + + + System Catalogs + + + System catalog changes usually only affect database management tools. + + + + + + Server C-language API + + + This involves changes in the backend function API, which is written + in the C programming language. Such changes affect code that + references backend functions deep inside the server. + + + + + + + + Upgrading Data via <application>pg_dumpall</application> + + + One upgrade method is to dump data from one major version of + PostgreSQL and reload it in another — to do + this, you must use a logical backup tool like + pg_dumpall; file system + level backup methods will not work. (There are checks in place that prevent + you from using a data directory with an incompatible version of + PostgreSQL, so no great harm can be done by + trying to start the wrong server version on a data directory.) + + + + It is recommended that you use the pg_dump and + pg_dumpall programs from the newer + version of + PostgreSQL, to take advantage of enhancements + that might have been made in these programs. Current releases of the + dump programs can read data from any server version back to 7.0. + + + + These instructions assume that your existing installation is under the + /usr/local/pgsql directory, and that the data area is in + /usr/local/pgsql/data. Substitute your paths + appropriately. + + + + + + If making a backup, make sure that your database is not being updated. + This does not affect the integrity of the backup, but the changed + data would of course not be included. If necessary, edit the + permissions in the file /usr/local/pgsql/data/pg_hba.conf + (or equivalent) to disallow access from everyone except you. + See for additional information on + access control. + + + + + pg_dumpall + use during upgrade + + + To back up your database installation, type: + +pg_dumpall > outputfile + + + + + To make the backup, you can use the pg_dumpall + command from the version you are currently running; see for more details. For best + results, however, try to use the pg_dumpall + command from PostgreSQL &version;, + since this version contains bug fixes and improvements over older + versions. While this advice might seem idiosyncratic since you + haven't installed the new version yet, it is advisable to follow + it if you plan to install the new version in parallel with the + old version. In that case you can complete the installation + normally and transfer the data later. This will also decrease + the downtime. + + + + + + Shut down the old server: + +pg_ctl stop + + On systems that have PostgreSQL started at boot time, + there is probably a start-up file that will accomplish the same thing. For + example, on a Red Hat Linux system one + might find that this works: + +/etc/rc.d/init.d/postgresql stop + + See for details about starting and + stopping the server. + + + + + + If restoring from backup, rename or delete the old installation + directory if it is not version-specific. It is a good idea to + rename the directory, rather than + delete it, in case you have trouble and need to revert to it. Keep + in mind the directory might consume significant disk space. To rename + the directory, use a command like this: + +mv /usr/local/pgsql /usr/local/pgsql.old + + (Be sure to move the directory as a single unit so relative paths + remain unchanged.) + + + + + + Install the new version of PostgreSQL as + outlined in . + + + + + + Create a new database cluster if needed. Remember that you must + execute these commands while logged in to the special database user + account (which you already have if you are upgrading). + +/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data + + + + + + + Restore your previous pg_hba.conf and any + postgresql.conf modifications. + + + + + + Start the database server, again using the special database user + account: + +/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data + + + + + + + Finally, restore your data from backup with: + +/usr/local/pgsql/bin/psql -d postgres -f outputfile + + using the new psql. + + + + + + The least downtime can be achieved by installing the new server in + a different directory and running both the old and the new servers + in parallel, on different ports. Then you can use something like: + + +pg_dumpall -p 5432 | psql -d postgres -p 5433 + + to transfer your data. + + + + + + Upgrading Data via <application>pg_upgrade</application> + + + The module allows an installation to + be migrated in-place from one major PostgreSQL + version to another. Upgrades can be performed in minutes, + particularly with mode. It requires steps similar to + pg_dumpall above, e.g., starting/stopping the server, + running initdb. The pg_upgrade documentation outlines the necessary steps. + + + + + + Upgrading Data via Replication + + + It is also possible to use logical replication methods to create a standby + server with the updated version of PostgreSQL. + This is possible because logical replication supports + replication between different major versions of + PostgreSQL. The standby can be on the same computer or + a different computer. Once it has synced up with the primary server + (running the older version of PostgreSQL), you can + switch primaries and make the standby the primary and shut down the older + database instance. Such a switch-over results in only several seconds + of downtime for an upgrade. + + + + This method of upgrading can be performed using the built-in logical + replication facilities as well as using external logical replication + systems such as pglogical, + Slony, Londiste, and + Bucardo. + + + + + + Preventing Server Spoofing + + + server spoofing + + + + While the server is running, it is not possible for a malicious user + to take the place of the normal database server. However, when the + server is down, it is possible for a local user to spoof the normal + server by starting their own server. The spoof server could read + passwords and queries sent by clients, but could not return any data + because the PGDATA directory would still be secure because + of directory permissions. Spoofing is possible because any user can + start a database server; a client cannot identify an invalid server + unless it is specially configured. + + + + One way to prevent spoofing of local + connections is to use a Unix domain socket directory () that has write permission only + for a trusted local user. This prevents a malicious user from creating + their own socket file in that directory. If you are concerned that + some applications might still reference /tmp for the + socket file and hence be vulnerable to spoofing, during operating system + startup create a symbolic link /tmp/.s.PGSQL.5432 that points + to the relocated socket file. You also might need to modify your + /tmp cleanup script to prevent removal of the symbolic link. + + + + Another option for local connections is for clients to use + requirepeer + to specify the required owner of the server process connected to + the socket. + + + + To prevent spoofing on TCP connections, either use + SSL certificates and make sure that clients check the server's certificate, + or use GSSAPI encryption (or both, if they're on separate connections). + + + + To prevent spoofing with SSL, the server + must be configured to accept only hostssl connections () and have SSL key and certificate files + (). The TCP client must connect using + sslmode=verify-ca or + verify-full and have the appropriate root certificate + file installed (). + + + + To prevent spoofing with GSSAPI, the server must be configured to accept + only hostgssenc connections + () and use gss + authentication with them. The TCP client must connect + using gssencmode=require. + + + + + Encryption Options + + + encryption + + + + PostgreSQL offers encryption at several + levels, and provides flexibility in protecting data from disclosure + due to database server theft, unscrupulous administrators, and + insecure networks. Encryption might also be required to secure + sensitive data such as medical records or financial transactions. + + + + + + Password Encryption + + + + Database user passwords are stored as hashes (determined by the setting + ), so the administrator cannot + determine the actual password assigned to the user. If SCRAM or MD5 + encryption is used for client authentication, the unencrypted password is + never even temporarily present on the server because the client encrypts + it before being sent across the network. SCRAM is preferred, because it + is an Internet standard and is more secure than the PostgreSQL-specific + MD5 authentication protocol. + + + + + + Encryption For Specific Columns + + + + The module allows certain fields to be + stored encrypted. + This is useful if only some of the data is sensitive. + The client supplies the decryption key and the data is decrypted + on the server and then sent to the client. + + + + The decrypted data and the decryption key are present on the + server for a brief time while it is being decrypted and + communicated between the client and server. This presents a brief + moment where the data and keys can be intercepted by someone with + complete access to the database server, such as the system + administrator. + + + + + + Data Partition Encryption + + + + Storage encryption can be performed at the file system level or the + block level. Linux file system encryption options include eCryptfs + and EncFS, while FreeBSD uses PEFS. Block level or full disk + encryption options include dm-crypt + LUKS on Linux and GEOM + modules geli and gbde on FreeBSD. Many other operating systems + support this functionality, including Windows. + + + + This mechanism prevents unencrypted data from being read from the + drives if the drives or the entire computer is stolen. This does + not protect against attacks while the file system is mounted, + because when mounted, the operating system provides an unencrypted + view of the data. However, to mount the file system, you need some + way for the encryption key to be passed to the operating system, + and sometimes the key is stored somewhere on the host that mounts + the disk. + + + + + + Encrypting Data Across A Network + + + + SSL connections encrypt all data sent across the network: the + password, the queries, and the data returned. The + pg_hba.conf file allows administrators to specify + which hosts can use non-encrypted connections (host) + and which require SSL-encrypted connections + (hostssl). Also, clients can specify that they + connect to servers only via SSL. + + + + GSSAPI-encrypted connections encrypt all data sent across the network, + including queries and data returned. (No password is sent across the + network.) The pg_hba.conf file allows + administrators to specify which hosts can use non-encrypted connections + (host) and which require GSSAPI-encrypted connections + (hostgssenc). Also, clients can specify that they + connect to servers only on GSSAPI-encrypted connections + (gssencmode=require). + + + + Stunnel or + SSH can also be used to encrypt + transmissions. + + + + + + SSL Host Authentication + + + + It is possible for both the client and server to provide SSL + certificates to each other. It takes some extra configuration + on each side, but this provides stronger verification of identity + than the mere use of passwords. It prevents a computer from + pretending to be the server just long enough to read the password + sent by the client. It also helps prevent man in the middle + attacks where a computer between the client and server pretends to + be the server and reads and passes all data between the client and + server. + + + + + + Client-Side Encryption + + + + If the system administrator for the server's machine cannot be trusted, + it is necessary + for the client to encrypt the data; this way, unencrypted data + never appears on the database server. Data is encrypted on the + client before being sent to the server, and database results have + to be decrypted on the client before being used. + + + + + + + + + + Secure TCP/IP Connections with SSL + + + SSL + + + + PostgreSQL has native support for using + SSL connections to encrypt client/server communications + for increased security. This requires that + OpenSSL is installed on both client and + server systems and that support in PostgreSQL is + enabled at build time (see ). + + + + Basic Setup + + + With SSL support compiled in, the + PostgreSQL server can be started with + SSL enabled by setting the parameter + to on in + postgresql.conf. The server will listen for both normal + and SSL connections on the same TCP port, and will negotiate + with any connecting client on whether to use SSL. By + default, this is at the client's option; see about how to set up the server to require + use of SSL for some or all connections. + + + + To start in SSL mode, files containing the server certificate + and private key must exist. By default, these files are expected to be + named server.crt and server.key, respectively, in + the server's data directory, but other names and locations can be specified + using the configuration parameters + and . + + + + On Unix systems, the permissions on server.key must + disallow any access to world or group; achieve this by the command + chmod 0600 server.key. Alternatively, the file can be + owned by root and have group read access (that is, 0640 + permissions). That setup is intended for installations where certificate + and key files are managed by the operating system. The user under which + the PostgreSQL server runs should then be made a + member of the group that has access to those certificate and key files. + + + + If the data directory allows group read access then certificate files may + need to be located outside of the data directory in order to conform to the + security requirements outlined above. Generally, group access is enabled + to allow an unprivileged user to backup the database, and in that case the + backup software will not be able to read the certificate files and will + likely error. + + + + If the private key is protected with a passphrase, the + server will prompt for the passphrase and will not start until it has + been entered. + Using a passphrase by default disables the ability to change the server's + SSL configuration without a server restart, but see . + Furthermore, passphrase-protected private keys cannot be used at all + on Windows. + + + + The first certificate in server.crt must be the + server's certificate because it must match the server's private key. + The certificates of intermediate certificate authorities + can also be appended to the file. Doing this avoids the necessity of + storing intermediate certificates on clients, assuming the root and + intermediate certificates were created with v3_ca + extensions. (This sets the certificate's basic constraint of + CA to true.) + This allows easier expiration of intermediate certificates. + + + + It is not necessary to add the root certificate to + server.crt. Instead, clients must have the root + certificate of the server's certificate chain. + + + + + OpenSSL Configuration + + + PostgreSQL reads the system-wide + OpenSSL configuration file. By default, this + file is named openssl.cnf and is located in the + directory reported by openssl version -d. + This default can be overridden by setting environment variable + OPENSSL_CONF to the name of the desired configuration file. + + + + OpenSSL supports a wide range of ciphers + and authentication algorithms, of varying strength. While a list of + ciphers can be specified in the OpenSSL + configuration file, you can specify ciphers specifically for use by + the database server by modifying in + postgresql.conf. + + + + + It is possible to have authentication without encryption overhead by + using NULL-SHA or NULL-MD5 ciphers. However, + a man-in-the-middle could read and pass communications between client + and server. Also, encryption overhead is minimal compared to the + overhead of authentication. For these reasons NULL ciphers are not + recommended. + + + + + + Using Client Certificates + + + To require the client to supply a trusted certificate, + place certificates of the root certificate authorities + (CAs) you trust in a file in the data + directory, set the parameter in + postgresql.conf to the new file name, and add the + authentication option clientcert=verify-ca or + clientcert=verify-full to the appropriate + hostssl line(s) in pg_hba.conf. + A certificate will then be requested from the client during SSL + connection startup. (See for a description + of how to set up certificates on the client.) + + + + For a hostssl entry with + clientcert=verify-ca, the server will verify + that the client's certificate is signed by one of the trusted + certificate authorities. If clientcert=verify-full + is specified, the server will not only verify the certificate + chain, but it will also check whether the username or its mapping + matches the cn (Common Name) of the provided certificate. + Note that certificate chain validation is always ensured when the + cert authentication method is used + (see ). + + + + Intermediate certificates that chain up to existing root certificates + can also appear in the file if + you wish to avoid storing them on clients (assuming the root and + intermediate certificates were created with v3_ca + extensions). Certificate Revocation List (CRL) entries are also + checked if the parameter is set. + + + + The clientcert authentication option is available for + all authentication methods, but only in pg_hba.conf lines + specified as hostssl. When clientcert is + not specified, the server verifies the client certificate against its CA + file only if a client certificate is presented and the CA is configured. + + + + There are two approaches to enforce that users provide a certificate during login. + + + + The first approach makes use of the cert authentication + method for hostssl entries in pg_hba.conf, + such that the certificate itself is used for authentication while also + providing ssl connection security. See for details. + (It is not necessary to specify any clientcert options + explicitly when using the cert authentication method.) + In this case, the cn (Common Name) provided in + the certificate is checked against the user name or an applicable mapping. + + + + The second approach combines any authentication method for hostssl + entries with the verification of client certificates by setting the + clientcert authentication option to verify-ca + or verify-full. The former option only enforces that + the certificate is valid, while the latter also ensures that the + cn (Common Name) in the certificate matches + the user name or an applicable mapping. + + + + + SSL Server File Usage + + + summarizes the files that are + relevant to the SSL setup on the server. (The shown file names are default + names. The locally configured names could be different.) + + + + SSL Server File Usage + + + + File + Contents + Effect + + + + + + + ($PGDATA/server.crt) + server certificate + sent to client to indicate server's identity + + + + ($PGDATA/server.key) + server private key + proves server certificate was sent by the owner; does not indicate + certificate owner is trustworthy + + + + + trusted certificate authorities + checks that client certificate is + signed by a trusted certificate authority + + + + + certificates revoked by certificate authorities + client certificate must not be on this list + + + + +
+ + + The server reads these files at server start and whenever the server + configuration is reloaded. On Windows + systems, they are also re-read whenever a new backend process is spawned + for a new client connection. + + + + If an error in these files is detected at server start, the server will + refuse to start. But if an error is detected during a configuration + reload, the files are ignored and the old SSL configuration continues to + be used. On Windows systems, if an error in + these files is detected at backend start, that backend will be unable to + establish an SSL connection. In all these cases, the error condition is + reported in the server log. + +
+ + + Creating Certificates + + + To create a simple self-signed certificate for the server, valid for 365 + days, use the following OpenSSL command, + replacing dbhost.yourdomain.com with the + server's host name: + +openssl req -new -x509 -days 365 -nodes -text -out server.crt \ + -keyout server.key -subj "/CN=dbhost.yourdomain.com" + + Then do: + +chmod og-rwx server.key + + because the server will reject the file if its permissions are more + liberal than this. + For more details on how to create your server private key and + certificate, refer to the OpenSSL documentation. + + + + While a self-signed certificate can be used for testing, a certificate + signed by a certificate authority (CA) (usually an + enterprise-wide root CA) should be used in production. + + + + To create a server certificate whose identity can be validated + by clients, first create a certificate signing request + (CSR) and a public/private key file: + +openssl req -new -nodes -text -out root.csr \ + -keyout root.key -subj "/CN=root.yourdomain.com" +chmod og-rwx root.key + + Then, sign the request with the key to create a root certificate + authority (using the default OpenSSL + configuration file location on Linux): + +openssl x509 -req -in root.csr -text -days 3650 \ + -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ + -signkey root.key -out root.crt + + Finally, create a server certificate signed by the new root certificate + authority: + +openssl req -new -nodes -text -out server.csr \ + -keyout server.key -subj "/CN=dbhost.yourdomain.com" +chmod og-rwx server.key + +openssl x509 -req -in server.csr -text -days 365 \ + -CA root.crt -CAkey root.key -CAcreateserial \ + -out server.crt + + server.crt and server.key + should be stored on the server, and root.crt should + be stored on the client so the client can verify that the server's leaf + certificate was signed by its trusted root certificate. + root.key should be stored offline for use in + creating future certificates. + + + + It is also possible to create a chain of trust that includes + intermediate certificates: + +# root +openssl req -new -nodes -text -out root.csr \ + -keyout root.key -subj "/CN=root.yourdomain.com" +chmod og-rwx root.key +openssl x509 -req -in root.csr -text -days 3650 \ + -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ + -signkey root.key -out root.crt + +# intermediate +openssl req -new -nodes -text -out intermediate.csr \ + -keyout intermediate.key -subj "/CN=intermediate.yourdomain.com" +chmod og-rwx intermediate.key +openssl x509 -req -in intermediate.csr -text -days 1825 \ + -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ + -CA root.crt -CAkey root.key -CAcreateserial \ + -out intermediate.crt + +# leaf +openssl req -new -nodes -text -out server.csr \ + -keyout server.key -subj "/CN=dbhost.yourdomain.com" +chmod og-rwx server.key +openssl x509 -req -in server.csr -text -days 365 \ + -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \ + -out server.crt + + server.crt and + intermediate.crt should be concatenated + into a certificate file bundle and stored on the server. + server.key should also be stored on the server. + root.crt should be stored on the client so + the client can verify that the server's leaf certificate was signed + by a chain of certificates linked to its trusted root certificate. + root.key and intermediate.key + should be stored offline for use in creating future certificates. + + + +
+ + + Secure TCP/IP Connections with GSSAPI Encryption + + + gssapi + + + + PostgreSQL also has native support for + using GSSAPI to encrypt client/server communications for + increased security. Support requires that a GSSAPI + implementation (such as MIT Kerberos) is installed on both client and server + systems, and that support in PostgreSQL is + enabled at build time (see ). + + + + Basic Setup + + + The PostgreSQL server will listen for both + normal and GSSAPI-encrypted connections on the same TCP + port, and will negotiate with any connecting client whether to + use GSSAPI for encryption (and for authentication). By + default, this decision is up to the client (which means it can be + downgraded by an attacker); see about + setting up the server to require the use of GSSAPI for + some or all connections. + + + + When using GSSAPI for encryption, it is common to + use GSSAPI for authentication as well, since the + underlying mechanism will determine both client and server identities + (according to the GSSAPI implementation) in any + case. But this is not required; + another PostgreSQL authentication method + can be chosen to perform additional verification. + + + + Other than configuration of the negotiation + behavior, GSSAPI encryption requires no setup beyond + that which is necessary for GSSAPI authentication. (For more information + on configuring that, see .) + + + + + + Secure TCP/IP Connections with <application>SSH</application> Tunnels + + + ssh + + + + It is possible to use SSH to encrypt the network + connection between clients and a + PostgreSQL server. Done properly, this + provides an adequately secure network connection, even for non-SSL-capable + clients. + + + + First make sure that an SSH server is + running properly on the same machine as the + PostgreSQL server and that you can log in using + ssh as some user; you then can establish a + secure tunnel to the remote server. A secure tunnel listens on a + local port and forwards all traffic to a port on the remote machine. + Traffic sent to the remote port can arrive on its + localhost address, or different bind + address if desired; it does not appear as coming from your + local machine. This command creates a secure tunnel from the client + machine to the remote machine foo.com: + +ssh -L 63333:localhost:5432 joe@foo.com + + The first number in the argument, 63333, is the + local port number of the tunnel; it can be any unused port. (IANA + reserves ports 49152 through 65535 for private use.) The name or IP + address after this is the remote bind address you are connecting to, + i.e., localhost, which is the default. The second + number, 5432, is the remote end of the tunnel, e.g., the port number + your database server is using. In order to connect to the database + server using this tunnel, you connect to port 63333 on the local + machine: + +psql -h localhost -p 63333 postgres + + To the database server it will then look as though you are + user joe on host foo.com + connecting to the localhost bind address, and it + will use whatever authentication procedure was configured for + connections by that user to that bind address. Note that the server will not + think the connection is SSL-encrypted, since in fact it is not + encrypted between the + SSH server and the + PostgreSQL server. This should not pose any + extra security risk because they are on the same machine. + + + + In order for the + tunnel setup to succeed you must be allowed to connect via + ssh as joe@foo.com, just + as if you had attempted to use ssh to create a + terminal session. + + + + You could also have set up port forwarding as + +ssh -L 63333:foo.com:5432 joe@foo.com + + but then the database server will see the connection as coming in + on its foo.com bind address, which is not opened by + the default setting listen_addresses = + 'localhost'. This is usually not what you want. + + + + If you have to hop to the database server via some + login host, one possible setup could look like this: + +ssh -L 63333:db.foo.com:5432 joe@shell.foo.com + + Note that this way the connection + from shell.foo.com + to db.foo.com will not be encrypted by the SSH + tunnel. + SSH offers quite a few configuration possibilities when the network + is restricted in various ways. Please refer to the SSH + documentation for details. + + + + + Several other applications exist that can provide secure tunnels using + a procedure similar in concept to the one just described. + + + + + + + Registering <application>Event Log</application> on <systemitem + class="osname">Windows</systemitem> + + + event log + event log + + + + To register a Windows + event log library with the operating system, + issue this command: + +regsvr32 pgsql_library_directory/pgevent.dll + + This creates registry entries used by the event viewer, under the default + event source named PostgreSQL. + + + + To specify a different event source name (see + ), use the /n + and /i options: + +regsvr32 /n /i:event_source_name pgsql_library_directory/pgevent.dll + + + + + To unregister the event log library from + the operating system, issue this command: + +regsvr32 /u [/i:event_source_name] pgsql_library_directory/pgevent.dll + + + + + + To enable event logging in the database server, modify + to include + eventlog in postgresql.conf. + + + + +
diff --git a/doc/src/sgml/seg.sgml b/doc/src/sgml/seg.sgml new file mode 100644 index 000000000000..9be69e3609fa --- /dev/null +++ b/doc/src/sgml/seg.sgml @@ -0,0 +1,415 @@ + + + + seg + + + seg + + + + This module implements a data type seg for + representing line segments, or floating point intervals. + seg can represent uncertainty in the interval endpoints, + making it especially useful for representing laboratory measurements. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Rationale + + + The geometry of measurements is usually more complex than that of a + point in a numeric continuum. A measurement is usually a segment of + that continuum with somewhat fuzzy limits. The measurements come out + as intervals because of uncertainty and randomness, as well as because + the value being measured may naturally be an interval indicating some + condition, such as the temperature range of stability of a protein. + + + + Using just common sense, it appears more convenient to store such data + as intervals, rather than pairs of numbers. In practice, it even turns + out more efficient in most applications. + + + + Further along the line of common sense, the fuzziness of the limits + suggests that the use of traditional numeric data types leads to a + certain loss of information. Consider this: your instrument reads + 6.50, and you input this reading into the database. What do you get + when you fetch it? Watch: + + +test=> select 6.50 :: float8 as "pH"; + pH +--- +6.5 +(1 row) + + + In the world of measurements, 6.50 is not the same as 6.5. It may + sometimes be critically different. The experimenters usually write + down (and publish) the digits they trust. 6.50 is actually a fuzzy + interval contained within a bigger and even fuzzier interval, 6.5, + with their center points being (probably) the only common feature they + share. We definitely do not want such different data items to appear the + same. + + + + Conclusion? It is nice to have a special data type that can record the + limits of an interval with arbitrarily variable precision. Variable in + the sense that each data element records its own precision. + + + + Check this out: + + +test=> select '6.25 .. 6.50'::seg as "pH"; + pH +------------ +6.25 .. 6.50 +(1 row) + + + + + + Syntax + + + The external representation of an interval is formed using one or two + floating-point numbers joined by the range operator (.. + or ...). Alternatively, it can be specified as a + center point plus or minus a deviation. + Optional certainty indicators (<, + > or ~) can be stored as well. + (Certainty indicators are ignored by all the built-in operators, however.) + gives an overview of allowed + representations; shows some + examples. + + + + In , x, y, and + delta denote + floating-point numbers. x and y, but + not delta, can be preceded by a certainty indicator. + + + + <type>seg</type> External Representations + + + + x + Single value (zero-length interval) + + + + x .. y + Interval from x to y + + + + x (+-) delta + Interval from x - delta to + x + delta + + + + x .. + Open interval with lower bound x + + + + .. x + Open interval with upper bound x + + + + +
+ + + Examples of Valid <type>seg</type> Input + + + + + + 5.0 + + Creates a zero-length segment (a point, if you will) + + + + ~5.0 + + Creates a zero-length segment and records + ~ in the data. ~ is ignored + by seg operations, but + is preserved as a comment. + + + + <5.0 + + Creates a point at 5.0. < is ignored but + is preserved as a comment. + + + + >5.0 + + Creates a point at 5.0. > is ignored but + is preserved as a comment. + + + + 5(+-)0.3 + + Creates an interval 4.7 .. 5.3. + Note that the (+-) notation isn't preserved. + + + + 50 .. + Everything that is greater than or equal to 50 + + + .. 0 + Everything that is less than or equal to 0 + + + 1.5e-2 .. 2E-2 + Creates an interval 0.015 .. 0.02 + + + 1 ... 2 + + The same as 1...2, or 1 .. 2, + or 1..2 + (spaces around the range operator are ignored) + + + + +
+ + + Because the ... operator is widely used in data sources, it is allowed + as an alternative spelling of the .. operator. Unfortunately, this + creates a parsing ambiguity: it is not clear whether the upper bound + in 0...23 is meant to be 23 or 0.23. + This is resolved by requiring at least one digit before the decimal + point in all numbers in seg input. + + + + As a sanity check, seg rejects intervals with the lower bound + greater than the upper, for example 5 .. 2. + + +
+ + + Precision + + + seg values are stored internally as pairs of 32-bit floating point + numbers. This means that numbers with more than 7 significant digits + will be truncated. + + + + Numbers with 7 or fewer significant digits retain their + original precision. That is, if your query returns 0.00, you will be + sure that the trailing zeroes are not the artifacts of formatting: they + reflect the precision of the original data. The number of leading + zeroes does not affect precision: the value 0.0067 is considered to + have just 2 significant digits. + + + + + Usage + + + The seg module includes a GiST index operator class for + seg values. + The operators supported by the GiST operator class are shown in . + + + + Seg GiST Operators + + + + + Operator + + + Description + + + + + + + + seg << seg + boolean + + + Is the first seg entirely to the left of the second? + [a, b] << [c, d] is true if b < c. + + + + + + seg >> seg + boolean + + + Is the first seg entirely to the right of the second? + [a, b] >> [c, d] is true if a > d. + + + + + + seg &< seg + boolean + + + Does the first seg not extend to the right of the + second? + [a, b] &< [c, d] is true if b <= d. + + + + + + seg &> seg + boolean + + + Does the first seg not extend to the left of the + second? + [a, b] &> [c, d] is true if a >= c. + + + + + + seg = seg + boolean + + + Are the two segs equal? + + + + + + seg && seg + boolean + + + Do the two segs overlap? + + + + + + seg @> seg + boolean + + + Does the first seg contain the second? + + + + + + seg <@ seg + boolean + + + Is the first seg contained in the second? + + + + +
+ + + In addition to the above operators, the usual comparison + operators shown in are + available for type seg. These operators + first compare (a) to (c), + and if these are equal, compare (b) to (d). That results in + reasonably good sorting in most cases, which is useful if + you want to use ORDER BY with this type. + +
+ + + Notes + + + For examples of usage, see the regression test sql/seg.sql. + + + + The mechanism that converts (+-) to regular ranges + isn't completely accurate in determining the number of significant digits + for the boundaries. For example, it adds an extra digit to the lower + boundary if the resulting interval includes a power of ten: + + +postgres=> select '10(+-)1'::seg as seg; + seg +--------- +9.0 .. 11 -- should be: 9 .. 11 + + + + + The performance of an R-tree index can largely depend on the initial + order of input values. It may be very helpful to sort the input table + on the seg column; see the script sort-segments.pl + for an example. + + + + + Credits + + + Original author: Gene Selkov, Jr. selkovjr@mcs.anl.gov, + Mathematics and Computer Science Division, Argonne National Laboratory. + + + + My thanks are primarily to Prof. Joe Hellerstein + () for elucidating the + gist of the GiST (). I am + also grateful to all Postgres developers, present and past, for enabling + myself to create my own world and live undisturbed in it. And I would like + to acknowledge my gratitude to Argonne Lab and to the U.S. Department of + Energy for the years of faithful support of my database research. + + + + +
diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml new file mode 100644 index 000000000000..e896a44ce591 --- /dev/null +++ b/doc/src/sgml/sepgsql.sgml @@ -0,0 +1,828 @@ + + + + sepgsql + + + sepgsql + + + + sepgsql is a loadable module that supports label-based + mandatory access control (MAC) based on SELinux security + policy. + + + + + The current implementation has significant limitations, and does not + enforce mandatory access control for all actions. See + . + + + + + Overview + + + This module integrates with SELinux to provide an + additional layer of security checking above and beyond what is normally + provided by PostgreSQL. From the perspective of + SELinux, this module allows + PostgreSQL to function as a user-space object + manager. Each table or function access initiated by a DML query will be + checked against the system security policy. This check is in addition to + the usual SQL permissions checking performed by + PostgreSQL. + + + + SELinux access control decisions are made using + security labels, which are represented by strings such as + system_u:object_r:sepgsql_table_t:s0. Each access control + decision involves two labels: the label of the subject attempting to + perform the action, and the label of the object on which the operation is + to be performed. Since these labels can be applied to any sort of object, + access control decisions for objects stored within the database can be + (and, with this module, are) subjected to the same general criteria used + for objects of any other type, such as files. This design is intended to + allow a centralized security policy to protect information assets + independent of the particulars of how those assets are stored. + + + + The SECURITY LABEL statement allows assignment of + a security label to a database object. + + + + + Installation + + + sepgsql can only be used on Linux + 2.6.28 or higher with SELinux enabled. + It is not available on any other platform. You will also need + libselinux 2.1.10 or higher and + selinux-policy 3.9.13 or higher (although some + distributions may backport the necessary rules into older policy + versions). + + + + The sestatus command allows you to check the status of + SELinux. A typical display is: + +$ sestatus +SELinux status: enabled +SELinuxfs mount: /selinux +Current mode: enforcing +Mode from config file: enforcing +Policy version: 24 +Policy from config file: targeted + + If SELinux is disabled or not installed, you must set + that product up first before installing this module. + + + + To build this module, include the option --with-selinux in + your PostgreSQL configure command. Be sure that the + libselinux-devel RPM is installed at build time. + + + + To use this module, you must include sepgsql + in the parameter in + postgresql.conf. The module will not function correctly + if loaded in any other manner. Once the module is loaded, you + should execute sepgsql.sql in each database. + This will install functions needed for security label management, and + assign initial security labels. + + + + Here is an example showing how to initialize a fresh database cluster + with sepgsql functions and security labels installed. + Adjust the paths shown as appropriate for your installation: + + + +$ export PGDATA=/path/to/data/directory +$ initdb +$ vi $PGDATA/postgresql.conf + change + #shared_preload_libraries = '' # (change requires restart) + to + shared_preload_libraries = 'sepgsql' # (change requires restart) +$ for DBNAME in template0 template1 postgres; do + postgres --single -F -c exit_on_error=true $DBNAME \ + </usr/local/pgsql/share/contrib/sepgsql.sql >/dev/null + done + + + + Please note that you may see some or all of the following notifications + depending on the particular versions you have of + libselinux and selinux-policy: + +/etc/selinux/targeted/contexts/sepgsql_contexts: line 33 has invalid object type db_blobs +/etc/selinux/targeted/contexts/sepgsql_contexts: line 36 has invalid object type db_language +/etc/selinux/targeted/contexts/sepgsql_contexts: line 37 has invalid object type db_language +/etc/selinux/targeted/contexts/sepgsql_contexts: line 38 has invalid object type db_language +/etc/selinux/targeted/contexts/sepgsql_contexts: line 39 has invalid object type db_language +/etc/selinux/targeted/contexts/sepgsql_contexts: line 40 has invalid object type db_language + + These messages are harmless and should be ignored. + + + + If the installation process completes without error, you can now start the + server normally. + + + + + Regression Tests + + + Due to the nature of SELinux, running the + regression tests for sepgsql requires several extra + configuration steps, some of which must be done as root. + The regression tests will not be run by an ordinary + make check or make installcheck command; you must + set up the configuration and then invoke the test script manually. + The tests must be run in the contrib/sepgsql directory + of a configured PostgreSQL build tree. Although they require a build tree, + the tests are designed to be executed against an installed server, + that is they are comparable to make installcheck not + make check. + + + + First, set up sepgsql in a working database + according to the instructions in . + Note that the current operating system user must be able to connect to the + database as superuser without password authentication. + + + + Second, build and install the policy package for the regression test. + The sepgsql-regtest policy is a special purpose policy package + which provides a set of rules to be allowed during the regression tests. + It should be built from the policy source file + sepgsql-regtest.te, which is done using + make with a Makefile supplied by SELinux. + You will need to locate the appropriate + Makefile on your system; the path shown below is only an example. + (This Makefile is usually supplied by the + selinux-policy-devel or + selinux-policy RPM.) + Once built, install this policy package using the + semodule command, which loads supplied policy packages + into the kernel. If the package is correctly installed, + semodule -l should list sepgsql-regtest as an + available policy package: + + + +$ cd .../contrib/sepgsql +$ make -f /usr/share/selinux/devel/Makefile +$ sudo semodule -u sepgsql-regtest.pp +$ sudo semodule -l | grep sepgsql +sepgsql-regtest 1.07 + + + + Third, turn on sepgsql_regression_test_mode. + For security reasons, the rules in sepgsql-regtest + are not enabled by default; + the sepgsql_regression_test_mode parameter enables + the rules needed to launch the regression tests. + It can be turned on using the setsebool command: + + + +$ sudo setsebool sepgsql_regression_test_mode on +$ getsebool sepgsql_regression_test_mode +sepgsql_regression_test_mode --> on + + + + Fourth, verify your shell is operating in the unconfined_t + domain: + + +$ id -Z +unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 + + + + See for details on adjusting your + working domain, if necessary. + + + + Finally, run the regression test script: + + +$ ./test_sepgsql + + + + This script will attempt to verify that you have done all the configuration + steps correctly, and then it will run the regression tests for the + sepgsql module. + + + + After completing the tests, it's recommended you disable + the sepgsql_regression_test_mode parameter: + + + +$ sudo setsebool sepgsql_regression_test_mode off + + + + You might prefer to remove the sepgsql-regtest policy + entirely: + + + +$ sudo semodule -r sepgsql-regtest + + + + + GUC Parameters + + + + + sepgsql.permissive (boolean) + + sepgsql.permissive configuration parameter + + + + + This parameter enables sepgsql to function + in permissive mode, regardless of the system setting. + The default is off. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + When this parameter is on, sepgsql functions + in permissive mode, even if SELinux in general is working in enforcing + mode. This parameter is primarily useful for testing purposes. + + + + + + + sepgsql.debug_audit (boolean) + + sepgsql.debug_audit configuration parameter + + + + + This parameter enables the printing of audit messages regardless of + the system policy settings. + The default is off, which means that messages will be printed according + to the system settings. + + + + The security policy of SELinux also has rules to + control whether or not particular accesses are logged. + By default, access violations are logged, but allowed + accesses are not. + + + + This parameter forces all possible logging to be turned on, regardless + of the system policy. + + + + + + + + Features + + Controlled Object Classes + + The security model of SELinux describes all the access + control rules as relationships between a subject entity (typically, + a client of the database) and an object entity (such as a database + object), each of which is + identified by a security label. If access to an unlabeled object is + attempted, the object is treated as if it were assigned the label + unlabeled_t. + + + + Currently, sepgsql allows security labels to be + assigned to schemas, tables, columns, sequences, views, and functions. + When sepgsql is in use, security labels are + automatically assigned to supported database objects at creation time. + This label is called a default security label, and is decided according + to the system security policy, which takes as input the creator's label, + the label assigned to the new object's parent object and optionally name + of the constructed object. + + + + A new database object basically inherits the security label of the parent + object, except when the security policy has special rules known as + type-transition rules, in which case a different label may be applied. + For schemas, the parent object is the current database; for tables, + sequences, views, and functions, it is the containing schema; for columns, + it is the containing table. + + + + + DML Permissions + + + For tables, db_table:select, db_table:insert, + db_table:update or db_table:delete are + checked for all the referenced target tables depending on the kind of + statement; in addition, db_table:select is also checked for + all the tables that contain columns referenced in the + WHERE or RETURNING clause, as a data source + for UPDATE, and so on. + + + + Column-level permissions will also be checked for each referenced column. + db_column:select is checked on not only the columns being + read using SELECT, but those being referenced in other DML + statements; db_column:update or db_column:insert + will also be checked for columns being modified by UPDATE or + INSERT. + + + + For example, consider: + +UPDATE t1 SET x = 2, y = func1(y) WHERE z = 100; + + + Here, db_column:update will be checked for + t1.x, since it is being updated, + db_column:{select update} will be checked for + t1.y, since it is both updated and referenced, and + db_column:select will be checked for t1.z, since + it is only referenced. + db_table:{select update} will also be checked + at the table level. + + + + For sequences, db_sequence:get_value is checked when we + reference a sequence object using SELECT; however, note that we + do not currently check permissions on execution of corresponding functions + such as lastval(). + + + + For views, db_view:expand will be checked, then any other + required permissions will be checked on the objects being + expanded from the view, individually. + + + + For functions, db_procedure:{execute} will be checked when + user tries to execute a function as a part of query, or using fast-path + invocation. If this function is a trusted procedure, it also checks + db_procedure:{entrypoint} permission to check whether it + can perform as entry point of trusted procedure. + + + + In order to access any schema object, db_schema:search + permission is required on the containing schema. When an object is + referenced without schema qualification, schemas on which this + permission is not present will not be searched (just as if the user did + not have USAGE privilege on the schema). If an explicit schema + qualification is present, an error will occur if the user does not have + the requisite permission on the named schema. + + + + The client must be allowed to access all referenced tables and + columns, even if they originated from views which were then expanded, + so that we apply consistent access control rules independent of the manner + in which the table contents are referenced. + + + + The default database privilege system allows database superusers to + modify system catalogs using DML commands, and reference or modify + toast tables. These operations are prohibited when + sepgsql is enabled. + + + + + DDL Permissions + + SELinux defines several permissions to control common + operations for each object type; such as creation, alter, drop and + relabel of security label. In addition, several object types have + special permissions to control their characteristic operations; such as + addition or deletion of name entries within a particular schema. + + + Creating a new database object requires create permission. + SELinux will grant or deny this permission based on the + client's security label and the proposed security label for the new + object. In some cases, additional privileges are required: + + + + + + CREATE DATABASE additionally requires + getattr permission for the source or template database. + + + + + Creating a schema object additionally requires add_name + permission on the parent schema. + + + + + Creating a table additionally requires permission to create each + individual table column, just as if each table column were a + separate top-level object. + + + + + Creating a function marked as LEAKPROOF additionally + requires install permission. (This permission is also + checked when LEAKPROOF is set for an existing function.) + + + + + + When DROP command is executed, drop will be + checked on the object being removed. Permissions will be also checked for + objects dropped indirectly via CASCADE. Deletion of objects + contained within a particular schema (tables, views, sequences and + procedures) additionally requires remove_name on the schema. + + + + When ALTER command is executed, setattr will be + checked on the object being modified for each object types, except for + subsidiary objects such as the indexes or triggers of a table, where + permissions are instead checked on the parent object. In some cases, + additional permissions are required: + + + + + + Moving an object to a new schema additionally requires + remove_name permission on the old schema and + add_name permission on the new one. + + + + + Setting the LEAKPROOF attribute on a function requires + install permission. + + + + + Using SECURITY LABEL on an object additionally + requires relabelfrom permission for the object in + conjunction with its old security label and relabelto + permission for the object in conjunction with its new security label. + (In cases where multiple label providers are installed and the user + tries to set a security label, but it is not managed by + SELinux, only setattr should be checked here. + This is currently not done due to implementation restrictions.) + + + + + + + + Trusted Procedures + + Trusted procedures are similar to security definer functions or setuid + commands. SELinux provides a feature to allow trusted + code to run using a security label different from that of the client, + generally for the purpose of providing highly controlled access to + sensitive data (e.g., rows might be omitted, or the precision of stored + values might be reduced). Whether or not a function acts as a trusted + procedure is controlled by its security label and the operating system + security policy. For example: + + + +postgres=# CREATE TABLE customer ( + cid int primary key, + cname text, + credit text + ); +CREATE TABLE +postgres=# SECURITY LABEL ON COLUMN customer.credit + IS 'system_u:object_r:sepgsql_secret_table_t:s0'; +SECURITY LABEL +postgres=# CREATE FUNCTION show_credit(int) RETURNS text + AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'') + FROM customer WHERE cid = $1' + LANGUAGE sql; +CREATE FUNCTION +postgres=# SECURITY LABEL ON FUNCTION show_credit(int) + IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0'; +SECURITY LABEL + + + + The above operations should be performed by an administrative user. + + + +postgres=# SELECT * FROM customer; +ERROR: SELinux: security policy violation +postgres=# SELECT cid, cname, show_credit(cid) FROM customer; + cid | cname | show_credit +-----+--------+--------------------- + 1 | taro | 1111-2222-3333-xxxx + 2 | hanako | 5555-6666-7777-xxxx +(2 rows) + + + + In this case, a regular user cannot reference customer.credit + directly, but a trusted procedure show_credit allows the user + to print the credit card numbers of customers with some of the digits + masked out. + + + + + Dynamic Domain Transitions + + It is possible to use SELinux's dynamic domain transition feature + to switch the security label of the client process, the client domain, + to a new context, if that is allowed by the security policy. + The client domain needs the setcurrent permission and also + dyntransition from the old to the new domain. + + + Dynamic domain transitions should be considered carefully, because they + allow users to switch their label, and therefore their privileges, + at their option, rather than (as in the case of a trusted procedure) + as mandated by the system. + Thus, the dyntransition permission is only considered + safe when used to switch to a domain with a smaller set of privileges than + the original one. For example: + + +regression=# select sepgsql_getcon(); + sepgsql_getcon +------------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 +(1 row) + +regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c4'); + sepgsql_setcon +---------------- + t +(1 row) + +regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c1023'); +ERROR: SELinux: security policy violation + + + In this example above we were allowed to switch from the larger MCS + range c1.c1023 to the smaller range c1.c4, but + switching back was denied. + + + A combination of dynamic domain transition and trusted procedure + enables an interesting use case that fits the typical process life-cycle + of connection pooling software. + Even if your connection pooling software is not allowed to run most + of SQL commands, you can allow it to switch the security label + of the client using the sepgsql_setcon() function + from within a trusted procedure; that should take some + credential to authorize the request to switch the client label. + After that, this session will have the privileges of the target user, + rather than the connection pooler. + The connection pooler can later revert the security label change by + again using sepgsql_setcon() with + NULL argument, again invoked from within a trusted + procedure with appropriate permissions checks. + The point here is that only the trusted procedure actually has permission + to change the effective security label, and only does so when given proper + credentials. Of course, for secure operation, the credential store + (table, procedure definition, or whatever) must be protected from + unauthorized access. + + + + + Miscellaneous + + We reject the LOAD command across the board, because + any module loaded could easily circumvent security policy enforcement. + + + + + + + Sepgsql Functions + + shows the available functions. + + + + Sepgsql Functions + + + + + Function + + + Description + + + + + + + + sepgsql_getcon () + text + + + Returns the client domain, the current security label of the client. + + + + + + sepgsql_setcon ( text ) + boolean + + + Switches the client domain of the current session to the new domain, + if allowed by the security policy. + It also accepts NULL input as a request to transition + to the client's original domain. + + + + + + sepgsql_mcstrans_in ( text ) + text + + + Translates the given qualified MLS/MCS range into raw format if + the mcstrans daemon is running. + + + + + + sepgsql_mcstrans_out ( text ) + text + + + Translates the given raw MLS/MCS range into qualified format if + the mcstrans daemon is running. + + + + + + sepgsql_restorecon ( text ) + boolean + + + Sets up initial security labels for all objects within the + current database. The argument may be NULL, or the + name of a specfile to be used as alternative of the system default. + + + + +
+
+ + + Limitations + + + + Data Definition Language (DDL) Permissions + + + Due to implementation restrictions, some DDL operations do not + check permissions. + + + + + + Data Control Language (DCL) Permissions + + + Due to implementation restrictions, DCL operations do not check + permissions. + + + + + + Row-level access control + + + PostgreSQL supports row-level access, but + sepgsql does not. + + + + + + Covert channels + + + sepgsql does not try to hide the existence of + a certain object, even if the user is not allowed to reference it. + For example, we can infer the existence of an invisible object as + a result of primary key conflicts, foreign key violations, and so on, + even if we cannot obtain the contents of the object. The existence + of a top secret table cannot be hidden; we only hope to conceal its + contents. + + + + + + + + External Resources + + + SE-PostgreSQL Introduction + + + This wiki page provides a brief overview, security design, architecture, + administration and upcoming features. + + + + + SELinux User's and Administrator's Guide + + + This document provides a wide spectrum of knowledge to administer + SELinux on your systems. + It focuses primarily on Red Hat operating systems, but is not limited to them. + + + + + Fedora SELinux FAQ + + + This document answers frequently asked questions about + SELinux. + It focuses primarily on Fedora, but is not limited to Fedora. + + + + + + + + Author + + KaiGai Kohei kaigai@ak.jp.nec.com + + +
diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml new file mode 100644 index 000000000000..3f2c40b75091 --- /dev/null +++ b/doc/src/sgml/sources.sgml @@ -0,0 +1,1019 @@ + + + + PostgreSQL Coding Conventions + + + Formatting + + + Source code formatting uses 4 column tab spacing, with + tabs preserved (i.e., tabs are not expanded to spaces). + Each logical indentation level is one additional tab stop. + + + + Layout rules (brace positioning, etc) follow BSD conventions. In + particular, curly braces for the controlled blocks of if, + while, switch, etc go on their own lines. + + + + Limit line lengths so that the code is readable in an 80-column window. + (This doesn't mean that you must never go past 80 columns. For instance, + breaking a long error message string in arbitrary places just to keep the + code within 80 columns is probably not a net gain in readability.) + + + + To maintain a consistent coding style, do not use C++ style comments + (// comments). pgindent + will replace them with /* ... */. + + + + The preferred style for multi-line comment blocks is + +/* + * comment text begins here + * and continues here + */ + + Note that comment blocks that begin in column 1 will be preserved as-is + by pgindent, but it will re-flow indented comment blocks + as though they were plain text. If you want to preserve the line breaks + in an indented block, add dashes like this: + + /*---------- + * comment text begins here + * and continues here + *---------- + */ + + + + + While submitted patches do not absolutely have to follow these formatting + rules, it's a good idea to do so. Your code will get run through + pgindent before the next release, so there's no point in + making it look nice under some other set of formatting conventions. + A good rule of thumb for patches is make the new code look like + the existing code around it. + + + + The src/tools directory contains sample settings + files that can be used with the emacs, + xemacs or vim + editors to help ensure that they format code according to these + conventions. + + + + The text browsing tools more and + less can be invoked as: + +more -x4 +less -x4 + + to make them show tabs appropriately. + + + + + Reporting Errors Within the Server + + + ereport + + + elog + + + + Error, warning, and log messages generated within the server code + should be created using ereport, or its older cousin + elog. The use of this function is complex enough to + require some explanation. + + + + There are two required elements for every message: a severity level + (ranging from DEBUG to PANIC) and a primary + message text. In addition there are optional elements, the most + common of which is an error identifier code that follows the SQL spec's + SQLSTATE conventions. + ereport itself is just a shell macro that exists + mainly for the syntactic convenience of making message generation + look like a single function call in the C source code. The only parameter + accepted directly by ereport is the severity level. + The primary message text and any optional message elements are + generated by calling auxiliary functions, such as errmsg, + within the ereport call. + + + + A typical call to ereport might look like this: + +ereport(ERROR, + errcode(ERRCODE_DIVISION_BY_ZERO), + errmsg("division by zero")); + + This specifies error severity level ERROR (a run-of-the-mill + error). The errcode call specifies the SQLSTATE error code + using a macro defined in src/include/utils/errcodes.h. The + errmsg call provides the primary message text. + + + + You will also frequently see this older style, with an extra set of + parentheses surrounding the auxiliary function calls: + +ereport(ERROR, + (errcode(ERRCODE_DIVISION_BY_ZERO), + errmsg("division by zero"))); + + The extra parentheses were required + before PostgreSQL version 12, but are now + optional. + + + + Here is a more complex example: + +ereport(ERROR, + errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("function %s is not unique", + func_signature_string(funcname, nargs, + NIL, actual_arg_types)), + errhint("Unable to choose a best candidate function. " + "You might need to add explicit typecasts.")); + + This illustrates the use of format codes to embed run-time values into + a message text. Also, an optional hint message is provided. + The auxiliary function calls can be written in any order, but + conventionally errcode + and errmsg appear first. + + + + If the severity level is ERROR or higher, + ereport aborts execution of the current query + and does not return to the caller. If the severity level is + lower than ERROR, ereport returns normally. + + + + The available auxiliary routines for ereport are: + + + + errcode(sqlerrcode) specifies the SQLSTATE error identifier + code for the condition. If this routine is not called, the error + identifier defaults to + ERRCODE_INTERNAL_ERROR when the error severity level is + ERROR or higher, ERRCODE_WARNING when the + error level is WARNING, otherwise (for NOTICE + and below) ERRCODE_SUCCESSFUL_COMPLETION. + While these defaults are often convenient, always think whether they + are appropriate before omitting the errcode() call. + + + + + errmsg(const char *msg, ...) specifies the primary error + message text, and possibly run-time values to insert into it. Insertions + are specified by sprintf-style format codes. In addition to + the standard format codes accepted by sprintf, the format + code %m can be used to insert the error message returned + by strerror for the current value of errno. + + + That is, the value that was current when the ereport call + was reached; changes of errno within the auxiliary reporting + routines will not affect it. That would not be true if you were to + write strerror(errno) explicitly in errmsg's + parameter list; accordingly, do not do so. + + + %m does not require any + corresponding entry in the parameter list for errmsg. + Note that the message string will be run through gettext + for possible localization before format codes are processed. + + + + + errmsg_internal(const char *msg, ...) is the same as + errmsg, except that the message string will not be + translated nor included in the internationalization message dictionary. + This should be used for cannot happen cases that are probably + not worth expending translation effort on. + + + + + errmsg_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n, ...) is like errmsg, but with + support for various plural forms of the message. + fmt_singular is the English singular format, + fmt_plural is the English plural format, + n is the integer value that determines which plural + form is needed, and the remaining arguments are formatted according + to the selected format string. For more information see + . + + + + + errdetail(const char *msg, ...) supplies an optional + detail message; this is to be used when there is additional + information that seems inappropriate to put in the primary message. + The message string is processed in just the same way as for + errmsg. + + + + + errdetail_internal(const char *msg, ...) is the same + as errdetail, except that the message string will not be + translated nor included in the internationalization message dictionary. + This should be used for detail messages that are not worth expending + translation effort on, for instance because they are too technical to be + useful to most users. + + + + + errdetail_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n, ...) is like errdetail, but with + support for various plural forms of the message. + For more information see . + + + + + errdetail_log(const char *msg, ...) is the same as + errdetail except that this string goes only to the server + log, never to the client. If both errdetail (or one of + its equivalents above) and + errdetail_log are used then one string goes to the client + and the other to the log. This is useful for error details that are + too security-sensitive or too bulky to include in the report + sent to the client. + + + + + errdetail_log_plural(const char *fmt_singular, const char + *fmt_plural, unsigned long n, ...) is like + errdetail_log, but with support for various plural forms of + the message. + For more information see . + + + + + errhint(const char *msg, ...) supplies an optional + hint message; this is to be used when offering suggestions + about how to fix the problem, as opposed to factual details about + what went wrong. + The message string is processed in just the same way as for + errmsg. + + + + + errhint_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n, ...) is like errhint, but with + support for various plural forms of the message. + For more information see . + + + + + errcontext(const char *msg, ...) is not normally called + directly from an ereport message site; rather it is used + in error_context_stack callback functions to provide + information about the context in which an error occurred, such as the + current location in a PL function. + The message string is processed in just the same way as for + errmsg. Unlike the other auxiliary functions, this can + be called more than once per ereport call; the successive + strings thus supplied are concatenated with separating newlines. + + + + + errposition(int cursorpos) specifies the textual location + of an error within a query string. Currently it is only useful for + errors detected in the lexical and syntactic analysis phases of + query processing. + + + + + errtable(Relation rel) specifies a relation whose + name and schema name should be included as auxiliary fields in the error + report. + + + + + errtablecol(Relation rel, int attnum) specifies + a column whose name, table name, and schema name should be included as + auxiliary fields in the error report. + + + + + errtableconstraint(Relation rel, const char *conname) + specifies a table constraint whose name, table name, and schema name + should be included as auxiliary fields in the error report. Indexes + should be considered to be constraints for this purpose, whether or + not they have an associated pg_constraint entry. Be + careful to pass the underlying heap relation, not the index itself, as + rel. + + + + + errdatatype(Oid datatypeOid) specifies a data + type whose name and schema name should be included as auxiliary fields + in the error report. + + + + + errdomainconstraint(Oid datatypeOid, const char *conname) + specifies a domain constraint whose name, domain name, and schema name + should be included as auxiliary fields in the error report. + + + + + errcode_for_file_access() is a convenience function that + selects an appropriate SQLSTATE error identifier for a failure in a + file-access-related system call. It uses the saved + errno to determine which error code to generate. + Usually this should be used in combination with %m in the + primary error message text. + + + + + errcode_for_socket_access() is a convenience function that + selects an appropriate SQLSTATE error identifier for a failure in a + socket-related system call. + + + + + errhidestmt(bool hide_stmt) can be called to specify + suppression of the STATEMENT: portion of a message in the + postmaster log. Generally this is appropriate if the message text + includes the current statement already. + + + + + errhidecontext(bool hide_ctx) can be called to + specify suppression of the CONTEXT: portion of a message in + the postmaster log. This should only be used for verbose debugging + messages where the repeated inclusion of context would bloat the log + too much. + + + + + + + + At most one of the functions errtable, + errtablecol, errtableconstraint, + errdatatype, or errdomainconstraint should + be used in an ereport call. These functions exist to + allow applications to extract the name of a database object associated + with the error condition without having to examine the + potentially-localized error message text. + These functions should be used in error reports for which it's likely + that applications would wish to have automatic error handling. As of + PostgreSQL 9.3, complete coverage exists only for + errors in SQLSTATE class 23 (integrity constraint violation), but this + is likely to be expanded in future. + + + + + There is an older function elog that is still heavily used. + An elog call: + +elog(level, "format string", ...); + + is exactly equivalent to: + +ereport(level, errmsg_internal("format string", ...)); + + Notice that the SQLSTATE error code is always defaulted, and the message + string is not subject to translation. + Therefore, elog should be used only for internal errors and + low-level debug logging. Any message that is likely to be of interest to + ordinary users should go through ereport. Nonetheless, + there are enough internal cannot happen error checks in the + system that elog is still widely used; it is preferred for + those messages for its notational simplicity. + + + + Advice about writing good error messages can be found in + . + + + + + Error Message Style Guide + + + This style guide is offered in the hope of maintaining a consistent, + user-friendly style throughout all the messages generated by + PostgreSQL. + + + + What Goes Where + + + The primary message should be short, factual, and avoid reference to + implementation details such as specific function names. + Short means should fit on one line under normal + conditions. Use a detail message if needed to keep the primary + message short, or if you feel a need to mention implementation details + such as the particular system call that failed. Both primary and detail + messages should be factual. Use a hint message for suggestions about what + to do to fix the problem, especially if the suggestion might not always be + applicable. + + + + For example, instead of: + +IpcMemoryCreate: shmget(key=%d, size=%u, 0%o) failed: %m +(plus a long addendum that is basically a hint) + + write: + +Primary: could not create shared memory segment: %m +Detail: Failed syscall was shmget(key=%d, size=%u, 0%o). +Hint: the addendum + + + + + Rationale: keeping the primary message short helps keep it to the point, + and lets clients lay out screen space on the assumption that one line is + enough for error messages. Detail and hint messages can be relegated to a + verbose mode, or perhaps a pop-up error-details window. Also, details and + hints would normally be suppressed from the server log to save + space. Reference to implementation details is best avoided since users + aren't expected to know the details. + + + + + + Formatting + + + Don't put any specific assumptions about formatting into the message + texts. Expect clients and the server log to wrap lines to fit their own + needs. In long messages, newline characters (\n) can be used to indicate + suggested paragraph breaks. Don't end a message with a newline. Don't + use tabs or other formatting characters. (In error context displays, + newlines are automatically added to separate levels of context such as + function calls.) + + + + Rationale: Messages are not necessarily displayed on terminal-type + displays. In GUI displays or browsers these formatting instructions are + at best ignored. + + + + + + Quotation Marks + + + English text should use double quotes when quoting is appropriate. + Text in other languages should consistently use one kind of quotes that is + consistent with publishing customs and computer output of other programs. + + + + Rationale: The choice of double quotes over single quotes is somewhat + arbitrary, but tends to be the preferred use. Some have suggested + choosing the kind of quotes depending on the type of object according to + SQL conventions (namely, strings single quoted, identifiers double + quoted). But this is a language-internal technical issue that many users + aren't even familiar with, it won't scale to other kinds of quoted terms, + it doesn't translate to other languages, and it's pretty pointless, too. + + + + + + Use of Quotes + + + Always use quotes to delimit file names, user-supplied identifiers, and + other variables that might contain words. Do not use them to mark up + variables that will not contain words (for example, operator names). + + + + There are functions in the backend that will double-quote their own output + as needed (for example, format_type_be()). Do not put + additional quotes around the output of such functions. + + + + Rationale: Objects can have names that create ambiguity when embedded in a + message. Be consistent about denoting where a plugged-in name starts and + ends. But don't clutter messages with unnecessary or duplicate quote + marks. + + + + + + Grammar and Punctuation + + + The rules are different for primary error messages and for detail/hint + messages: + + + + Primary error messages: Do not capitalize the first letter. Do not end a + message with a period. Do not even think about ending a message with an + exclamation point. + + + + Detail and hint messages: Use complete sentences, and end each with + a period. Capitalize the first word of sentences. Put two spaces after + the period if another sentence follows (for English text; might be + inappropriate in other languages). + + + + Error context strings: Do not capitalize the first letter and do + not end the string with a period. Context strings should normally + not be complete sentences. + + + + Rationale: Avoiding punctuation makes it easier for client applications to + embed the message into a variety of grammatical contexts. Often, primary + messages are not grammatically complete sentences anyway. (And if they're + long enough to be more than one sentence, they should be split into + primary and detail parts.) However, detail and hint messages are longer + and might need to include multiple sentences. For consistency, they should + follow complete-sentence style even when there's only one sentence. + + + + + + Upper Case vs. Lower Case + + + Use lower case for message wording, including the first letter of a + primary error message. Use upper case for SQL commands and key words if + they appear in the message. + + + + Rationale: It's easier to make everything look more consistent this + way, since some messages are complete sentences and some not. + + + + + + Avoid Passive Voice + + + Use the active voice. Use complete sentences when there is an acting + subject (A could not do B). Use telegram style without + subject if the subject would be the program itself; do not use + I for the program. + + + + Rationale: The program is not human. Don't pretend otherwise. + + + + + + Present vs. Past Tense + + + Use past tense if an attempt to do something failed, but could perhaps + succeed next time (perhaps after fixing some problem). Use present tense + if the failure is certainly permanent. + + + + There is a nontrivial semantic difference between sentences of the form: + +could not open file "%s": %m + +and: + +cannot open file "%s" + + The first one means that the attempt to open the file failed. The + message should give a reason, such as disk full or + file doesn't exist. The past tense is appropriate because + next time the disk might not be full anymore or the file in question might + exist. + + + + The second form indicates that the functionality of opening the named file + does not exist at all in the program, or that it's conceptually + impossible. The present tense is appropriate because the condition will + persist indefinitely. + + + + Rationale: Granted, the average user will not be able to draw great + conclusions merely from the tense of the message, but since the language + provides us with a grammar we should use it correctly. + + + + + + Type of the Object + + + When citing the name of an object, state what kind of object it is. + + + + Rationale: Otherwise no one will know what foo.bar.baz + refers to. + + + + + + Brackets + + + Square brackets are only to be used (1) in command synopses to denote + optional arguments, or (2) to denote an array subscript. + + + + Rationale: Anything else does not correspond to widely-known customary + usage and will confuse people. + + + + + + Assembling Error Messages + + + When a message includes text that is generated elsewhere, embed it in + this style: + +could not open file %s: %m + + + + + Rationale: It would be difficult to account for all possible error codes + to paste this into a single smooth sentence, so some sort of punctuation + is needed. Putting the embedded text in parentheses has also been + suggested, but it's unnatural if the embedded text is likely to be the + most important part of the message, as is often the case. + + + + + + Reasons for Errors + + + Messages should always state the reason why an error occurred. + For example: + +BAD: could not open file %s +BETTER: could not open file %s (I/O failure) + + If no reason is known you better fix the code. + + + + + + Function Names + + + Don't include the name of the reporting routine in the error text. We have + other mechanisms for finding that out when needed, and for most users it's + not helpful information. If the error text doesn't make as much sense + without the function name, reword it. + +BAD: pg_strtoint32: error in "z": cannot parse "z" +BETTER: invalid input syntax for type integer: "z" + + + + + Avoid mentioning called function names, either; instead say what the code + was trying to do: + +BAD: open() failed: %m +BETTER: could not open file %s: %m + + If it really seems necessary, mention the system call in the detail + message. (In some cases, providing the actual values passed to the + system call might be appropriate information for the detail message.) + + + + Rationale: Users don't know what all those functions do. + + + + + + Tricky Words to Avoid + + + Unable + + Unable is nearly the passive voice. Better use + cannot or could not, as appropriate. + + + + + Bad + + Error messages like bad result are really hard to interpret + intelligently. It's better to write why the result is bad, + e.g., invalid format. + + + + + Illegal + + Illegal stands for a violation of the law, the rest is + invalid. Better yet, say why it's invalid. + + + + + Unknown + + Try to avoid unknown. Consider error: unknown + response. If you don't know what the response is, how do you know + it's erroneous? Unrecognized is often a better choice. + Also, be sure to include the value being complained of. + +BAD: unknown node type +BETTER: unrecognized node type: 42 + + + + + + Find vs. Exists + + If the program uses a nontrivial algorithm to locate a resource (e.g., a + path search) and that algorithm fails, it is fair to say that the program + couldn't find the resource. If, on the other hand, the + expected location of the resource is known but the program cannot access + it there then say that the resource doesn't exist. Using + find in this case sounds weak and confuses the issue. + + + + + May vs. Can vs. Might + + May suggests permission (e.g., "You may borrow my rake."), + and has little use in documentation or error messages. + Can suggests ability (e.g., "I can lift that log."), + and might suggests possibility (e.g., "It might rain + today."). Using the proper word clarifies meaning and assists + translation. + + + + + Contractions + + Avoid contractions, like can't; use + cannot instead. + + + + + + + Proper Spelling + + + Spell out words in full. For instance, avoid: + + + + spec + + + + + stats + + + + + parens + + + + + auth + + + + + xact + + + + + + + Rationale: This will improve consistency. + + + + + + Localization + + + Keep in mind that error message texts need to be translated into other + languages. Follow the guidelines in + to avoid making life difficult for translators. + + + + + + + Miscellaneous Coding Conventions + + + C Standard + + Code in PostgreSQL should only rely on language + features available in the C99 standard. That means a conforming + C99 compiler has to be able to compile postgres, at least aside + from a few platform dependent pieces. + + + A few features included in the C99 standard are, at this time, not + permitted to be used in core PostgreSQL + code. This currently includes variable length arrays, intermingled + declarations and code, // comments, universal + character names. Reasons for that include portability and historical + practices. + + + Features from later revisions of the C standard or compiler specific + features can be used, if a fallback is provided. + + + For example _Static_assert() and + __builtin_constant_p are currently used, even though + they are from newer revisions of the C standard and a + GCC extension respectively. If not available + we respectively fall back to using a C99 compatible replacement that + performs the same checks, but emits rather cryptic messages and do not + use __builtin_constant_p. + + + + + Function-Like Macros and Inline Functions + + Both, macros with arguments and static inline + functions, may be used. The latter are preferable if there are + multiple-evaluation hazards when written as a macro, as e.g., the + case with + +#define Max(x, y) ((x) > (y) ? (x) : (y)) + + or when the macro would be very long. In other cases it's only + possible to use macros, or at least easier. For example because + expressions of various types need to be passed to the macro. + + + When the definition of an inline function references symbols + (i.e., variables, functions) that are only available as part of the + backend, the function may not be visible when included from frontend + code. + +#ifndef FRONTEND +static inline MemoryContext +MemoryContextSwitchTo(MemoryContext context) +{ + MemoryContext old = CurrentMemoryContext; + + CurrentMemoryContext = context; + return old; +} +#endif /* FRONTEND */ + + In this example CurrentMemoryContext, which is only + available in the backend, is referenced and the function thus + hidden with a #ifndef FRONTEND. This rule + exists because some compilers emit references to symbols + contained in inline functions even if the function is not used. + + + + + Writing Signal Handlers + + To be suitable to run inside a signal handler code has to be + written very carefully. The fundamental problem is that, unless + blocked, a signal handler can interrupt code at any time. If code + inside the signal handler uses the same state as code outside + chaos may ensue. As an example consider what happens if a signal + handler tries to acquire a lock that's already held in the + interrupted code. + + + Barring special arrangements code in signal handlers may only + call async-signal safe functions (as defined in POSIX) and access + variables of type volatile sig_atomic_t. A few + functions in postgres are also deemed signal safe, importantly + SetLatch(). + + + In most cases signal handlers should do nothing more than note + that a signal has arrived, and wake up code running outside of + the handler using a latch. An example of such a handler is the + following: + +static void +handle_sighup(SIGNAL_ARGS) +{ + int save_errno = errno; + + got_SIGHUP = true; + SetLatch(MyLatch); + + errno = save_errno; +} + + errno is saved and restored because + SetLatch() might change it. If that were not done + interrupted code that's currently inspecting errno might see the wrong + value. + + + + + Calling Function Pointers + + + For clarity, it is preferred to explicitly dereference a function pointer + when calling the pointed-to function if the pointer is a simple variable, + for example: + +(*emit_log_hook) (edata); + + (even though emit_log_hook(edata) would also work). + When the function pointer is part of a structure, then the extra + punctuation can and usually should be omitted, for example: + +paramInfo->paramFetch(paramInfo, paramId); + + + + + diff --git a/doc/src/sgml/spgist.sgml b/doc/src/sgml/spgist.sgml new file mode 100644 index 000000000000..18f1f3cdbd83 --- /dev/null +++ b/doc/src/sgml/spgist.sgml @@ -0,0 +1,1075 @@ + + + +SP-GiST Indexes + + + index + SP-GiST + + + + Introduction + + + SP-GiST is an abbreviation for space-partitioned + GiST. SP-GiST supports partitioned + search trees, which facilitate development of a wide range of different + non-balanced data structures, such as quad-trees, k-d trees, and radix + trees (tries). The common feature of these structures is that they + repeatedly divide the search space into partitions that need not be + of equal size. Searches that are well matched to the partitioning rule + can be very fast. + + + + These popular data structures were originally developed for in-memory + usage. In main memory, they are usually designed as a set of dynamically + allocated nodes linked by pointers. This is not suitable for direct + storing on disk, since these chains of pointers can be rather long which + would require too many disk accesses. In contrast, disk-based data + structures should have a high fanout to minimize I/O. The challenge + addressed by SP-GiST is to map search tree nodes to + disk pages in such a way that a search need access only a few disk pages, + even if it traverses many nodes. + + + + Like GiST, SP-GiST is meant to allow + the development of custom data types with the appropriate access methods, + by an expert in the domain of the data type, rather than a database expert. + + + + Some of the information here is derived from Purdue University's + SP-GiST Indexing Project + web site. + The SP-GiST implementation in + PostgreSQL is primarily maintained by Teodor + Sigaev and Oleg Bartunov, and there is more information on their + + web site. + + + + + + Built-in Operator Classes + + + The core PostgreSQL distribution + includes the SP-GiST operator classes shown in + . + + + + Built-in <acronym>SP-GiST</acronym> Operator Classes + + + + Name + Indexable Operators + Ordering Operators + + + + + box_ops + << (box,box) + <-> (box,point) + + &< (box,box) + &> (box,box) + >> (box,box) + <@ (box,box) + @> (box,box) + ~= (box,box) + && (box,box) + <<| (box,box) + &<| (box,box) + |&> (box,box) + |>> (box,box) + + + kd_point_ops + |>> (point,point) + <-> (point,point) + + << (point,point) + >> (point,point) + <<| (point,point) + ~= (point,point) + <@ (point,box) + + + network_ops + << (inet,inet) + + + <<= (inet,inet) + >> (inet,inet) + >>= (inet,inet) + = (inet,inet) + <> (inet,inet) + < (inet,inet) + <= (inet,inet) + > (inet,inet) + >= (inet,inet) + && (inet,inet) + + + poly_ops + << (polygon,polygon) + <-> (polygon,point) + + &< (polygon,polygon) + &> (polygon,polygon) + >> (polygon,polygon) + <@ (polygon,polygon) + @> (polygon,polygon) + ~= (polygon,polygon) + && (polygon,polygon) + <<| (polygon,polygon) + &<| (polygon,polygon) + |>> (polygon,polygon) + |&> (polygon,polygon) + + + quad_point_ops + |>> (point,point) + <-> (point,point) + + << (point,point) + >> (point,point) + <<| (point,point) + ~= (point,point) + <@ (point,box) + + + range_ops + = (anyrange,anyrange) + + + && (anyrange,anyrange) + @> (anyrange,anyelement) + @> (anyrange,anyrange) + <@ (anyrange,anyrange) + << (anyrange,anyrange) + >> (anyrange,anyrange) + &< (anyrange,anyrange) + &> (anyrange,anyrange) + -|- (anyrange,anyrange) + + + text_ops + = (text,text) + + + < (text,text) + <= (text,text) + > (text,text) + >= (text,text) + ~<~ (text,text) + ~<=~ (text,text) + ~>=~ (text,text) + ~>~ (text,text) + ^@ (text,text) + + +
+ + + Of the two operator classes for type point, + quad_point_ops is the default. kd_point_ops + supports the same operators but uses a different index data structure that + may offer better performance in some applications. + + + The quad_point_ops, kd_point_ops and + poly_ops operator classes support the <-> + ordering operator, which enables the k-nearest neighbor (k-NN) + search over indexed point or polygon data sets. + + +
+ + + Extensibility + + + SP-GiST offers an interface with a high level of + abstraction, requiring the access method developer to implement only + methods specific to a given data type. The SP-GiST core + is responsible for efficient disk mapping and searching the tree structure. + It also takes care of concurrency and logging considerations. + + + + Leaf tuples of an SP-GiST tree usually contain values + of the same data type as the indexed column, although it is also possible + for them to contain lossy representations of the indexed column. + Leaf tuples stored at the root level will directly represent + the original indexed data value, but leaf tuples at lower + levels might contain only a partial value, such as a suffix. + In that case the operator class support functions must be able to + reconstruct the original value using information accumulated from the + inner tuples that are passed through to reach the leaf level. + + + + When an SP-GiST index is created with + INCLUDE columns, the values of those columns are also + stored in leaf tuples. The INCLUDE columns are of no + concern to the SP-GiST operator class, so they are + not discussed further here. + + + + Inner tuples are more complex, since they are branching points in the + search tree. Each inner tuple contains a set of one or more + nodes, which represent groups of similar leaf values. + A node contains a downlink that leads either to another, lower-level inner + tuple, or to a short list of leaf tuples that all lie on the same index page. + Each node normally has a label that describes it; for example, + in a radix tree the node label could be the next character of the string + value. (Alternatively, an operator class can omit the node labels, if it + works with a fixed set of nodes for all inner tuples; + see .) + Optionally, an inner tuple can have a prefix value + that describes all its members. In a radix tree this could be the common + prefix of the represented strings. The prefix value is not necessarily + really a prefix, but can be any data needed by the operator class; + for example, in a quad-tree it can store the central point that the four + quadrants are measured with respect to. A quad-tree inner tuple would + then also contain four nodes corresponding to the quadrants around this + central point. + + + + Some tree algorithms require knowledge of level (or depth) of the current + tuple, so the SP-GiST core provides the possibility for + operator classes to manage level counting while descending the tree. + There is also support for incrementally reconstructing the represented + value when that is needed, and for passing down additional data (called + traverse values) during a tree descent. + + + + + The SP-GiST core code takes care of null entries. + Although SP-GiST indexes do store entries for nulls + in indexed columns, this is hidden from the index operator class code: + no null index entries or search conditions will ever be passed to the + operator class methods. (It is assumed that SP-GiST + operators are strict and so cannot succeed for null values.) Null values + are therefore not discussed further here. + + + + + There are five user-defined methods that an index operator class for + SP-GiST must provide, and two are optional. All five + mandatory methods follow the convention of accepting two internal + arguments, the first of which is a pointer to a C struct containing input + values for the support method, while the second argument is a pointer to a + C struct where output values must be placed. Four of the mandatory methods just + return void, since all their results appear in the output struct; but + leaf_consistent returns a boolean result. + The methods must not modify any fields of their input structs. In all + cases, the output struct is initialized to zeroes before calling the + user-defined method. The optional sixth method compress + accepts a datum to be indexed as the only argument and returns a value suitable + for physical storage in a leaf tuple. The optional seventh method + options accepts an internal pointer to a C struct, where + opclass-specific parameters should be placed, and returns void. + + + + The five mandatory user-defined methods are: + + + + + config + + + Returns static information about the index implementation, including + the data type OIDs of the prefix and node label data types. + + + The SQL declaration of the function must look like this: + +CREATE FUNCTION my_config(internal, internal) RETURNS void ... + + The first argument is a pointer to a spgConfigIn + C struct, containing input data for the function. + The second argument is a pointer to a spgConfigOut + C struct, which the function must fill with result data. + +typedef struct spgConfigIn +{ + Oid attType; /* Data type to be indexed */ +} spgConfigIn; + +typedef struct spgConfigOut +{ + Oid prefixType; /* Data type of inner-tuple prefixes */ + Oid labelType; /* Data type of inner-tuple node labels */ + Oid leafType; /* Data type of leaf-tuple values */ + bool canReturnData; /* Opclass can reconstruct original data */ + bool longValuesOK; /* Opclass can cope with values > 1 page */ +} spgConfigOut; + + + attType is passed in order to support polymorphic + index operator classes; for ordinary fixed-data-type operator classes, it + will always have the same value and so can be ignored. + + + + For operator classes that do not use prefixes, + prefixType can be set to VOIDOID. + Likewise, for operator classes that do not use node labels, + labelType can be set to VOIDOID. + canReturnData should be set true if the operator class + is capable of reconstructing the originally-supplied index value. + longValuesOK should be set true only when the + attType is of variable length and the operator + class is capable of segmenting long values by repeated suffixing + (see ). + + + + leafType should match the index storage type + defined by the operator class's opckeytype + catalog entry. + (Note that opckeytype can be zero, + implying the storage type is the same as the operator class's input + type, which is the most common situation.) + For reasons of backward compatibility, the config + method can set leafType to some other value, + and that value will be used; but this is deprecated since the index + contents are then incorrectly identified in the catalogs. + Also, it's permissible to + leave leafType uninitialized (zero); + that is interpreted as meaning the index storage type derived from + opckeytype. + + + + When attType + and leafType are different, the optional + method compress must be provided. + Method compress is responsible + for transformation of datums to be indexed from attType + to leafType. + + + + + + choose + + + Chooses a method for inserting a new value into an inner tuple. + + + + The SQL declaration of the function must look like this: + +CREATE FUNCTION my_choose(internal, internal) RETURNS void ... + + The first argument is a pointer to a spgChooseIn + C struct, containing input data for the function. + The second argument is a pointer to a spgChooseOut + C struct, which the function must fill with result data. + +typedef struct spgChooseIn +{ + Datum datum; /* original datum to be indexed */ + Datum leafDatum; /* current datum to be stored at leaf */ + int level; /* current level (counting from zero) */ + + /* Data from current inner tuple */ + bool allTheSame; /* tuple is marked all-the-same? */ + bool hasPrefix; /* tuple has a prefix? */ + Datum prefixDatum; /* if so, the prefix value */ + int nNodes; /* number of nodes in the inner tuple */ + Datum *nodeLabels; /* node label values (NULL if none) */ +} spgChooseIn; + +typedef enum spgChooseResultType +{ + spgMatchNode = 1, /* descend into existing node */ + spgAddNode, /* add a node to the inner tuple */ + spgSplitTuple /* split inner tuple (change its prefix) */ +} spgChooseResultType; + +typedef struct spgChooseOut +{ + spgChooseResultType resultType; /* action code, see above */ + union + { + struct /* results for spgMatchNode */ + { + int nodeN; /* descend to this node (index from 0) */ + int levelAdd; /* increment level by this much */ + Datum restDatum; /* new leaf datum */ + } matchNode; + struct /* results for spgAddNode */ + { + Datum nodeLabel; /* new node's label */ + int nodeN; /* where to insert it (index from 0) */ + } addNode; + struct /* results for spgSplitTuple */ + { + /* Info to form new upper-level inner tuple with one child tuple */ + bool prefixHasPrefix; /* tuple should have a prefix? */ + Datum prefixPrefixDatum; /* if so, its value */ + int prefixNNodes; /* number of nodes */ + Datum *prefixNodeLabels; /* their labels (or NULL for + * no labels) */ + int childNodeN; /* which node gets child tuple */ + + /* Info to form new lower-level inner tuple with all old nodes */ + bool postfixHasPrefix; /* tuple should have a prefix? */ + Datum postfixPrefixDatum; /* if so, its value */ + } splitTuple; + } result; +} spgChooseOut; + + + datum is the original datum of + spgConfigIn.attType + type that was to be inserted into the index. + leafDatum is a value of + spgConfigOut.leafType + type, which is initially a result of method + compress applied to datum + when method compress is provided, or the same value as + datum otherwise. + leafDatum can change at lower levels of the tree + if the choose or picksplit + methods change it. When the insertion search reaches a leaf page, + the current value of leafDatum is what will be stored + in the newly created leaf tuple. + level is the current inner tuple's level, starting at + zero for the root level. + allTheSame is true if the current inner tuple is + marked as containing multiple equivalent nodes + (see ). + hasPrefix is true if the current inner tuple contains + a prefix; if so, + prefixDatum is its value. + nNodes is the number of child nodes contained in the + inner tuple, and + nodeLabels is an array of their label values, or + NULL if there are no labels. + + + + The choose function can determine either that + the new value matches one of the existing child nodes, or that a new + child node must be added, or that the new value is inconsistent with + the tuple prefix and so the inner tuple must be split to create a + less restrictive prefix. + + + + If the new value matches one of the existing child nodes, + set resultType to spgMatchNode. + Set nodeN to the index (from zero) of that node in + the node array. + Set levelAdd to the increment in + level caused by descending through that node, + or leave it as zero if the operator class does not use levels. + Set restDatum to equal leafDatum + if the operator class does not modify datums from one level to the + next, or otherwise set it to the modified value to be used as + leafDatum at the next level. + + + + If a new child node must be added, + set resultType to spgAddNode. + Set nodeLabel to the label to be used for the new + node, and set nodeN to the index (from zero) at which + to insert the node in the node array. + After the node has been added, the choose + function will be called again with the modified inner tuple; + that call should result in an spgMatchNode result. + + + + If the new value is inconsistent with the tuple prefix, + set resultType to spgSplitTuple. + This action moves all the existing nodes into a new lower-level + inner tuple, and replaces the existing inner tuple with a tuple + having a single downlink pointing to the new lower-level inner tuple. + Set prefixHasPrefix to indicate whether the new + upper tuple should have a prefix, and if so set + prefixPrefixDatum to the prefix value. This new + prefix value must be sufficiently less restrictive than the original + to accept the new value to be indexed. + Set prefixNNodes to the number of nodes needed in the + new tuple, and set prefixNodeLabels to a palloc'd array + holding their labels, or to NULL if node labels are not required. + Note that the total size of the new upper tuple must be no more + than the total size of the tuple it is replacing; this constrains + the lengths of the new prefix and new labels. + Set childNodeN to the index (from zero) of the node + that will downlink to the new lower-level inner tuple. + Set postfixHasPrefix to indicate whether the new + lower-level inner tuple should have a prefix, and if so set + postfixPrefixDatum to the prefix value. The + combination of these two prefixes and the downlink node's label + (if any) must have the same meaning as the original prefix, because + there is no opportunity to alter the node labels that are moved to + the new lower-level tuple, nor to change any child index entries. + After the node has been split, the choose + function will be called again with the replacement inner tuple. + That call may return an spgAddNode result, if no suitable + node was created by the spgSplitTuple action. Eventually + choose must return spgMatchNode to + allow the insertion to descend to the next level. + + + + + + picksplit + + + Decides how to create a new inner tuple over a set of leaf tuples. + + + + The SQL declaration of the function must look like this: + +CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ... + + The first argument is a pointer to a spgPickSplitIn + C struct, containing input data for the function. + The second argument is a pointer to a spgPickSplitOut + C struct, which the function must fill with result data. + +typedef struct spgPickSplitIn +{ + int nTuples; /* number of leaf tuples */ + Datum *datums; /* their datums (array of length nTuples) */ + int level; /* current level (counting from zero) */ +} spgPickSplitIn; + +typedef struct spgPickSplitOut +{ + bool hasPrefix; /* new inner tuple should have a prefix? */ + Datum prefixDatum; /* if so, its value */ + + int nNodes; /* number of nodes for new inner tuple */ + Datum *nodeLabels; /* their labels (or NULL for no labels) */ + + int *mapTuplesToNodes; /* node index for each leaf tuple */ + Datum *leafTupleDatums; /* datum to store in each new leaf tuple */ +} spgPickSplitOut; + + + nTuples is the number of leaf tuples provided. + datums is an array of their datum values of + spgConfigOut.leafType + type. + level is the current level that all the leaf tuples + share, which will become the level of the new inner tuple. + + + + Set hasPrefix to indicate whether the new inner + tuple should have a prefix, and if so set + prefixDatum to the prefix value. + Set nNodes to indicate the number of nodes that + the new inner tuple will contain, and + set nodeLabels to an array of their label values, + or to NULL if node labels are not required. + Set mapTuplesToNodes to an array that gives the index + (from zero) of the node that each leaf tuple should be assigned to. + Set leafTupleDatums to an array of the values to + be stored in the new leaf tuples (these will be the same as the + input datums if the operator class does not modify + datums from one level to the next). + Note that the picksplit function is + responsible for palloc'ing the + nodeLabels, mapTuplesToNodes and + leafTupleDatums arrays. + + + + If more than one leaf tuple is supplied, it is expected that the + picksplit function will classify them into more than + one node; otherwise it is not possible to split the leaf tuples + across multiple pages, which is the ultimate purpose of this + operation. Therefore, if the picksplit function + ends up placing all the leaf tuples in the same node, the core + SP-GiST code will override that decision and generate an inner + tuple in which the leaf tuples are assigned at random to several + identically-labeled nodes. Such a tuple is marked + allTheSame to signify that this has happened. The + choose and inner_consistent functions + must take suitable care with such inner tuples. + See for more information. + + + + picksplit can be applied to a single leaf tuple only + in the case that the config function set + longValuesOK to true and a larger-than-a-page input + value has been supplied. In this case the point of the operation is + to strip off a prefix and produce a new, shorter leaf datum value. + The call will be repeated until a leaf datum short enough to fit on + a page has been produced. See for + more information. + + + + + + inner_consistent + + + Returns set of nodes (branches) to follow during tree search. + + + + The SQL declaration of the function must look like this: + +CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ... + + The first argument is a pointer to a spgInnerConsistentIn + C struct, containing input data for the function. + The second argument is a pointer to a spgInnerConsistentOut + C struct, which the function must fill with result data. + + +typedef struct spgInnerConsistentIn +{ + ScanKey scankeys; /* array of operators and comparison values */ + ScanKey orderbys; /* array of ordering operators and comparison + * values */ + int nkeys; /* length of scankeys array */ + int norderbys; /* length of orderbys array */ + + Datum reconstructedValue; /* value reconstructed at parent */ + void *traversalValue; /* opclass-specific traverse value */ + MemoryContext traversalMemoryContext; /* put new traverse values here */ + int level; /* current level (counting from zero) */ + bool returnData; /* original data must be returned? */ + + /* Data from current inner tuple */ + bool allTheSame; /* tuple is marked all-the-same? */ + bool hasPrefix; /* tuple has a prefix? */ + Datum prefixDatum; /* if so, the prefix value */ + int nNodes; /* number of nodes in the inner tuple */ + Datum *nodeLabels; /* node label values (NULL if none) */ +} spgInnerConsistentIn; + +typedef struct spgInnerConsistentOut +{ + int nNodes; /* number of child nodes to be visited */ + int *nodeNumbers; /* their indexes in the node array */ + int *levelAdds; /* increment level by this much for each */ + Datum *reconstructedValues; /* associated reconstructed values */ + void **traversalValues; /* opclass-specific traverse values */ + double **distances; /* associated distances */ +} spgInnerConsistentOut; + + + The array scankeys, of length nkeys, + describes the index search condition(s). These conditions are + combined with AND — only index entries that satisfy all of + them are interesting. (Note that nkeys = 0 implies + that all index entries satisfy the query.) Usually the consistent + function only cares about the sk_strategy and + sk_argument fields of each array entry, which + respectively give the indexable operator and comparison value. + In particular it is not necessary to check sk_flags to + see if the comparison value is NULL, because the SP-GiST core code + will filter out such conditions. + The array orderbys, of length norderbys, + describes ordering operators (if any) in the same manner. + reconstructedValue is the value reconstructed for the + parent tuple; it is (Datum) 0 at the root level or if the + inner_consistent function did not provide a value at the + parent level. + traversalValue is a pointer to any traverse data + passed down from the previous call of inner_consistent + on the parent index tuple, or NULL at the root level. + traversalMemoryContext is the memory context in which + to store output traverse values (see below). + level is the current inner tuple's level, starting at + zero for the root level. + returnData is true if reconstructed data is + required for this query; this will only be so if the + config function asserted canReturnData. + allTheSame is true if the current inner tuple is + marked all-the-same; in this case all the nodes have the + same label (if any) and so either all or none of them match the query + (see ). + hasPrefix is true if the current inner tuple contains + a prefix; if so, + prefixDatum is its value. + nNodes is the number of child nodes contained in the + inner tuple, and + nodeLabels is an array of their label values, or + NULL if the nodes do not have labels. + + + + nNodes must be set to the number of child nodes that + need to be visited by the search, and + nodeNumbers must be set to an array of their indexes. + If the operator class keeps track of levels, set + levelAdds to an array of the level increments + required when descending to each node to be visited. (Often these + increments will be the same for all the nodes, but that's not + necessarily so, so an array is used.) + If value reconstruction is needed, set + reconstructedValues to an array of the values + reconstructed for each child node to be visited; otherwise, leave + reconstructedValues as NULL. + The reconstructed values are assumed to be of type + spgConfigOut.leafType. + (However, since the core system will do nothing with them except + possibly copy them, it is sufficient for them to have the + same typlen and typbyval + properties as leafType.) + If ordered search is performed, set distances + to an array of distance values according to orderbys + array (nodes with lowest distances will be processed first). Leave it + NULL otherwise. + If it is desired to pass down additional out-of-band information + (traverse values) to lower levels of the tree search, + set traversalValues to an array of the appropriate + traverse values, one for each child node to be visited; otherwise, + leave traversalValues as NULL. + Note that the inner_consistent function is + responsible for palloc'ing the + nodeNumbers, levelAdds, + distances, + reconstructedValues, and + traversalValues arrays in the current memory context. + However, any output traverse values pointed to by + the traversalValues array should be allocated + in traversalMemoryContext. + Each traverse value must be a single palloc'd chunk. + + + + + + leaf_consistent + + + Returns true if a leaf tuple satisfies a query. + + + + The SQL declaration of the function must look like this: + +CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ... + + The first argument is a pointer to a spgLeafConsistentIn + C struct, containing input data for the function. + The second argument is a pointer to a spgLeafConsistentOut + C struct, which the function must fill with result data. + +typedef struct spgLeafConsistentIn +{ + ScanKey scankeys; /* array of operators and comparison values */ + ScanKey orderbys; /* array of ordering operators and comparison + * values */ + int nkeys; /* length of scankeys array */ + int norderbys; /* length of orderbys array */ + + Datum reconstructedValue; /* value reconstructed at parent */ + void *traversalValue; /* opclass-specific traverse value */ + int level; /* current level (counting from zero) */ + bool returnData; /* original data must be returned? */ + + Datum leafDatum; /* datum in leaf tuple */ +} spgLeafConsistentIn; + +typedef struct spgLeafConsistentOut +{ + Datum leafValue; /* reconstructed original data, if any */ + bool recheck; /* set true if operator must be rechecked */ + bool recheckDistances; /* set true if distances must be rechecked */ + double *distances; /* associated distances */ +} spgLeafConsistentOut; + + + The array scankeys, of length nkeys, + describes the index search condition(s). These conditions are + combined with AND — only index entries that satisfy all of + them satisfy the query. (Note that nkeys = 0 implies + that all index entries satisfy the query.) Usually the consistent + function only cares about the sk_strategy and + sk_argument fields of each array entry, which + respectively give the indexable operator and comparison value. + In particular it is not necessary to check sk_flags to + see if the comparison value is NULL, because the SP-GiST core code + will filter out such conditions. + The array orderbys, of length norderbys, + describes the ordering operators in the same manner. + reconstructedValue is the value reconstructed for the + parent tuple; it is (Datum) 0 at the root level or if the + inner_consistent function did not provide a value at the + parent level. + traversalValue is a pointer to any traverse data + passed down from the previous call of inner_consistent + on the parent index tuple, or NULL at the root level. + level is the current leaf tuple's level, starting at + zero for the root level. + returnData is true if reconstructed data is + required for this query; this will only be so if the + config function asserted canReturnData. + leafDatum is the key value of + spgConfigOut.leafType + stored in the current leaf tuple. + + + + The function must return true if the leaf tuple matches the + query, or false if not. In the true case, + if returnData is true then + leafValue must be set to the value (of type + spgConfigIn.attType) + originally supplied to be indexed for this leaf tuple. Also, + recheck may be set to true if the match + is uncertain and so the operator(s) must be re-applied to the actual + heap tuple to verify the match. + If ordered search is performed, set distances + to an array of distance values according to orderbys + array. Leave it NULL otherwise. If at least one of returned distances + is not exact, set recheckDistances to true. + In this case, the executor will calculate the exact distances after + fetching the tuple from the heap, and will reorder the tuples if needed. + + + + + + + The optional user-defined methods are: + + + + + Datum compress(Datum in) + + + Converts a data item into a format suitable for physical storage in + a leaf tuple of the index. It accepts a value of type + spgConfigIn.attType + and returns a value of type + spgConfigOut.leafType. + The output value must not contain an out-of-line TOAST pointer. + + + + Note: the compress method is only applied to + values to be stored. The consistent methods receive query scankeys + unchanged, without transformation using compress. + + + + + + options + + + Defines a set of user-visible parameters that control operator class + behavior. + + + + The SQL declaration of the function must look like this: + + +CREATE OR REPLACE FUNCTION my_options(internal) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + + + + + The function is passed a pointer to a local_relopts + struct, which needs to be filled with a set of operator class + specific options. The options can be accessed from other support + functions using the PG_HAS_OPCLASS_OPTIONS() and + PG_GET_OPCLASS_OPTIONS() macros. + + + + Since the representation of the key in SP-GiST is + flexible, it may depend on user-specified parameters. + + + + + + + All the SP-GiST support methods are normally called in a short-lived + memory context; that is, CurrentMemoryContext will be reset + after processing of each tuple. It is therefore not very important to + worry about pfree'ing everything you palloc. (The config + method is an exception: it should try to avoid leaking memory. But + usually the config method need do nothing but assign + constants into the passed parameter struct.) + + + + If the indexed column is of a collatable data type, the index collation + will be passed to all the support methods, using the standard + PG_GET_COLLATION() mechanism. + + + + + + Implementation + + + This section covers implementation details and other tricks that are + useful for implementers of SP-GiST operator classes to + know. + + + + SP-GiST Limits + + + Individual leaf tuples and inner tuples must fit on a single index page + (8kB by default). Therefore, when indexing values of variable-length + data types, long values can only be supported by methods such as radix + trees, in which each level of the tree includes a prefix that is short + enough to fit on a page, and the final leaf level includes a suffix also + short enough to fit on a page. The operator class should set + longValuesOK to true only if it is prepared to arrange for + this to happen. Otherwise, the SP-GiST core will + reject any request to index a value that is too large to fit + on an index page. + + + + Likewise, it is the operator class's responsibility that inner tuples + do not grow too large to fit on an index page; this limits the number + of child nodes that can be used in one inner tuple, as well as the + maximum size of a prefix value. + + + + Another limitation is that when an inner tuple's node points to a set + of leaf tuples, those tuples must all be in the same index page. + (This is a design decision to reduce seeking and save space in the + links that chain such tuples together.) If the set of leaf tuples + grows too large for a page, a split is performed and an intermediate + inner tuple is inserted. For this to fix the problem, the new inner + tuple must divide the set of leaf values into more than one + node group. If the operator class's picksplit function + fails to do that, the SP-GiST core resorts to + extraordinary measures described in . + + + + When longValuesOK is true, it is expected + that successive levels of the SP-GiST tree will + absorb more and more information into the prefixes and node labels of + the inner tuples, making the required leaf datum smaller and smaller, + so that eventually it will fit on a page. + To prevent bugs in operator classes from causing infinite insertion + loops, the SP-GiST core will raise an error if the + leaf datum does not become any smaller within ten cycles + of choose method calls. + + + + + SP-GiST Without Node Labels + + + Some tree algorithms use a fixed set of nodes for each inner tuple; + for example, in a quad-tree there are always exactly four nodes + corresponding to the four quadrants around the inner tuple's centroid + point. In such a case the code typically works with the nodes by + number, and there is no need for explicit node labels. To suppress + node labels (and thereby save some space), the picksplit + function can return NULL for the nodeLabels array, + and likewise the choose function can return NULL for + the prefixNodeLabels array during + a spgSplitTuple action. + This will in turn result in nodeLabels being NULL during + subsequent calls to choose and inner_consistent. + In principle, node labels could be used for some inner tuples and omitted + for others in the same index. + + + + When working with an inner tuple having unlabeled nodes, it is an error + for choose to return spgAddNode, since the set + of nodes is supposed to be fixed in such cases. + + + + + <quote>All-the-Same</quote> Inner Tuples + + + The SP-GiST core can override the results of the + operator class's picksplit function when + picksplit fails to divide the supplied leaf values into + at least two node categories. When this happens, the new inner tuple + is created with multiple nodes that each have the same label (if any) + that picksplit gave to the one node it did use, and the + leaf values are divided at random among these equivalent nodes. + The allTheSame flag is set on the inner tuple to warn the + choose and inner_consistent functions that the + tuple does not have the node set that they might otherwise expect. + + + + When dealing with an allTheSame tuple, a choose + result of spgMatchNode is interpreted to mean that the new + value can be assigned to any of the equivalent nodes; the core code will + ignore the supplied nodeN value and descend into one + of the nodes at random (so as to keep the tree balanced). It is an + error for choose to return spgAddNode, since + that would make the nodes not all equivalent; the + spgSplitTuple action must be used if the value to be inserted + doesn't match the existing nodes. + + + + When dealing with an allTheSame tuple, the + inner_consistent function should return either all or none + of the nodes as targets for continuing the index search, since they are + all equivalent. This may or may not require any special-case code, + depending on how much the inner_consistent function normally + assumes about the meaning of the nodes. + + + + + + + Examples + + + The PostgreSQL source distribution includes + several examples of index operator classes for SP-GiST, + as described in . Look + into src/backend/access/spgist/ + and src/backend/utils/adt/ to see the code. + + + + +
diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml new file mode 100644 index 000000000000..d6ff492ba997 --- /dev/null +++ b/doc/src/sgml/spi.sgml @@ -0,0 +1,5356 @@ + + + + Server Programming Interface + + + SPI + + + + The Server Programming Interface + (SPI) gives writers of user-defined + C functions the ability to run + SQL commands inside their functions or procedures. + SPI is a set of + interface functions to simplify access to the parser, planner, + and executor. SPI also does some + memory management. + + + + + The available procedural languages provide various means to + execute SQL commands from functions. Most of these facilities are + based on SPI, so this documentation might be of use for users + of those languages as well. + + + + + Note that if a command invoked via SPI fails, then control will not be + returned to your C function. Rather, the + transaction or subtransaction in which your C function executes will be + rolled back. (This might seem surprising given that the SPI functions mostly + have documented error-return conventions. Those conventions only apply + for errors detected within the SPI functions themselves, however.) + It is possible to recover control after an error by establishing your own + subtransaction surrounding SPI calls that might fail. + + + + SPI functions return a nonnegative result on + success (either via a returned integer value or in the global + variable SPI_result, as described below). On + error, a negative result or NULL will be returned. + + + + Source code files that use SPI must include the header file + executor/spi.h. + + + + + Interface Functions + + + SPI_connect + SPI_connect_ext + + + SPI_connect + 3 + + + + SPI_connect + SPI_connect_ext + connect a C function to the SPI manager + + + + +int SPI_connect(void) + + + +int SPI_connect_ext(int options) + + + + + Description + + + SPI_connect opens a connection from a + C function invocation to the SPI manager. You must call this + function if you want to execute commands through SPI. Some utility + SPI functions can be called from unconnected C functions. + + + + SPI_connect_ext does the same but has an argument that + allows passing option flags. Currently, the following option values are + available: + + + SPI_OPT_NONATOMIC + + + Sets the SPI connection to be nonatomic, which + means that transaction control calls SPI_commit, + SPI_rollback, and + SPI_start_transaction are allowed. Otherwise, + calling these functions will result in an immediate error. + + + + + + + + SPI_connect() is equivalent to + SPI_connect_ext(0). + + + + + Return Value + + + + SPI_OK_CONNECT + + + on success + + + + + + SPI_ERROR_CONNECT + + + on error + + + + + + + + + + + SPI_finish + + + SPI_finish + 3 + + + + SPI_finish + disconnect a C function from the SPI manager + + + + +int SPI_finish(void) + + + + + Description + + + SPI_finish closes an existing connection to + the SPI manager. You must call this function after completing the + SPI operations needed during your C function's current invocation. + You do not need to worry about making this happen, however, if you + abort the transaction via elog(ERROR). In that + case SPI will clean itself up automatically. + + + + + Return Value + + + + SPI_OK_FINISH + + + if properly disconnected + + + + + + SPI_ERROR_UNCONNECTED + + + if called from an unconnected C function + + + + + + + + + + + SPI_execute + + + SPI_execute + 3 + + + + SPI_execute + execute a command + + + + +int SPI_execute(const char * command, bool read_only, long count) + + + + + Description + + + SPI_execute executes the specified SQL command + for count rows. If read_only + is true, the command must be read-only, and execution overhead + is somewhat reduced. + + + + This function can only be called from a connected C function. + + + + If count is zero then the command is executed + for all rows that it applies to. If count + is greater than zero, then no more than count rows + will be retrieved; execution stops when the count is reached, much like + adding a LIMIT clause to the query. For example, + +SPI_execute("SELECT * FROM foo", true, 5); + + will retrieve at most 5 rows from the table. Note that such a limit + is only effective when the command actually returns rows. For example, + +SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5); + + inserts all rows from bar, ignoring the + count parameter. However, with + +SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); + + at most 5 rows would be inserted, since execution would stop after the + fifth RETURNING result row is retrieved. + + + + You can pass multiple commands in one string; + SPI_execute returns the + result for the command executed last. The count + limit applies to each command separately (even though only the last + result will actually be returned). The limit is not applied to any + hidden commands generated by rules. + + + + When read_only is false, + SPI_execute increments the command + counter and computes a new snapshot before executing each + command in the string. The snapshot does not actually change if the + current transaction isolation level is SERIALIZABLE or REPEATABLE READ, but in + READ COMMITTED mode the snapshot update allows each command to + see the results of newly committed transactions from other sessions. + This is essential for consistent behavior when the commands are modifying + the database. + + + + When read_only is true, + SPI_execute does not update either the snapshot + or the command counter, and it allows only plain SELECT + commands to appear in the command string. The commands are executed + using the snapshot previously established for the surrounding query. + This execution mode is somewhat faster than the read/write mode due + to eliminating per-command overhead. It also allows genuinely + stable functions to be built: since successive executions + will all use the same snapshot, there will be no change in the results. + + + + It is generally unwise to mix read-only and read-write commands within + a single function using SPI; that could result in very confusing behavior, + since the read-only queries would not see the results of any database + updates done by the read-write queries. + + + + The actual number of rows for which the (last) command was executed + is returned in the global variable SPI_processed. + If the return value of the function is SPI_OK_SELECT, + SPI_OK_INSERT_RETURNING, + SPI_OK_DELETE_RETURNING, or + SPI_OK_UPDATE_RETURNING, + then you can use the + global pointer SPITupleTable *SPI_tuptable to + access the result rows. Some utility commands (such as + EXPLAIN) also return row sets, and SPI_tuptable + will contain the result in these cases too. Some utility commands + (COPY, CREATE TABLE AS) don't return a row set, so + SPI_tuptable is NULL, but they still return the number of + rows processed in SPI_processed. + + + + The structure SPITupleTable is defined + thus: + +typedef struct SPITupleTable +{ + /* Public members */ + TupleDesc tupdesc; /* tuple descriptor */ + HeapTuple *vals; /* array of tuples */ + uint64 numvals; /* number of valid tuples */ + + /* Private members, not intended for external callers */ + uint64 alloced; /* allocated length of vals array */ + MemoryContext tuptabcxt; /* memory context of result table */ + slist_node next; /* link for internal bookkeeping */ + SubTransactionId subid; /* subxact in which tuptable was created */ +} SPITupleTable; + + The fields tupdesc, + vals, and + numvals + can be used by SPI callers; the remaining fields are internal. + vals is an array of pointers to rows. + The number of rows is given by numvals + (for somewhat historical reasons, this count is also returned + in SPI_processed). + tupdesc is a row descriptor which you can pass to + SPI functions dealing with rows. + + + + SPI_finish frees all + SPITupleTables allocated during the current + C function. You can free a particular result table earlier, if you + are done with it, by calling SPI_freetuptable. + + + + + Arguments + + + + const char * command + + + string containing command to execute + + + + + + bool read_only + + true for read-only execution + + + + + long count + + + maximum number of rows to return, + or 0 for no limit + + + + + + + + Return Value + + + If the execution of the command was successful then one of the + following (nonnegative) values will be returned: + + + + SPI_OK_SELECT + + + if a SELECT (but not SELECT + INTO) was executed + + + + + + SPI_OK_SELINTO + + + if a SELECT INTO was executed + + + + + + SPI_OK_INSERT + + + if an INSERT was executed + + + + + + SPI_OK_DELETE + + + if a DELETE was executed + + + + + + SPI_OK_UPDATE + + + if an UPDATE was executed + + + + + + SPI_OK_INSERT_RETURNING + + + if an INSERT RETURNING was executed + + + + + + SPI_OK_DELETE_RETURNING + + + if a DELETE RETURNING was executed + + + + + + SPI_OK_UPDATE_RETURNING + + + if an UPDATE RETURNING was executed + + + + + + SPI_OK_UTILITY + + + if a utility command (e.g., CREATE TABLE) + was executed + + + + + + SPI_OK_REWRITTEN + + + if the command was rewritten into another kind of command (e.g., + UPDATE became an INSERT) by a rule. + + + + + + + + On error, one of the following negative values is returned: + + + + SPI_ERROR_ARGUMENT + + + if command is NULL or + count is less than 0 + + + + + + SPI_ERROR_COPY + + + if COPY TO stdout or COPY FROM stdin + was attempted + + + + + + SPI_ERROR_TRANSACTION + + + if a transaction manipulation command was attempted + (BEGIN, + COMMIT, + ROLLBACK, + SAVEPOINT, + PREPARE TRANSACTION, + COMMIT PREPARED, + ROLLBACK PREPARED, + or any variant thereof) + + + + + + SPI_ERROR_OPUNKNOWN + + + if the command type is unknown (shouldn't happen) + + + + + + SPI_ERROR_UNCONNECTED + + + if called from an unconnected C function + + + + + + + + + Notes + + + All SPI query-execution functions set both + SPI_processed and + SPI_tuptable (just the pointer, not the contents + of the structure). Save these two global variables into local + C function variables if you need to access the result table of + SPI_execute or another query-execution function + across later calls. + + + + + + + + SPI_exec + + + SPI_exec + 3 + + + + SPI_exec + execute a read/write command + + + + +int SPI_exec(const char * command, long count) + + + + + Description + + + SPI_exec is the same as + SPI_execute, with the latter's + read_only parameter always taken as + false. + + + + + Arguments + + + + const char * command + + + string containing command to execute + + + + + + long count + + + maximum number of rows to return, + or 0 for no limit + + + + + + + + Return Value + + + See SPI_execute. + + + + + + + + SPI_execute_extended + + + SPI_execute_extended + 3 + + + + SPI_execute_extended + execute a command with out-of-line parameters + + + + +int SPI_execute_extended(const char *command, + const SPIExecuteOptions * options) + + + + + Description + + + SPI_execute_extended executes a command that might + include references to externally supplied parameters. The command text + refers to a parameter as $n, + and the options->params object (if supplied) + provides values and type information for each such symbol. + Various execution options can be specified + in the options struct, too. + + + + The options->params object should normally + mark each parameter with the PARAM_FLAG_CONST flag, + since a one-shot plan is always used for the query. + + + + If options->dest is not NULL, then result + tuples are passed to that object as they are generated by the executor, + instead of being accumulated in SPI_tuptable. Using + a caller-supplied DestReceiver object is particularly + helpful for queries that might generate many tuples, since the data can + be processed on-the-fly instead of being accumulated in memory. + + + + + Arguments + + + + const char * command + + + command string + + + + + + const SPIExecuteOptions * options + + + struct containing optional arguments + + + + + + + Callers should always zero out the entire options + struct, then fill whichever fields they want to set. This ensures forward + compatibility of code, since any fields that are added to the struct in + future will be defined to behave backwards-compatibly if they are zero. + The currently available options fields are: + + + + + ParamListInfo params + + + data structure containing query parameter types and values; NULL if none + + + + + + bool read_only + + true for read-only execution + + + + + bool allow_nonatomic + + + true allows non-atomic execution of CALL and DO + statements + + + + + + uint64 tcount + + + maximum number of rows to return, + or 0 for no limit + + + + + + DestReceiver * dest + + + DestReceiver object that will receive any tuples + emitted by the query; if NULL, result tuples are accumulated into + a SPI_tuptable structure, as + in SPI_execute + + + + + + ResourceOwner owner + + + This field is present for consistency + with SPI_execute_plan_extended, but it is + ignored, since the plan used + by SPI_execute_extended is never saved. + + + + + + + + Return Value + + + The return value is the same as for SPI_execute. + + + + When options->dest is NULL, + SPI_processed and + SPI_tuptable are set as in + SPI_execute. + When options->dest is not NULL, + SPI_processed is set to zero and + SPI_tuptable is set to NULL. If a tuple count + is required, the caller's DestReceiver object must + calculate it. + + + + + + + + SPI_execute_with_args + + + SPI_execute_with_args + 3 + + + + SPI_execute_with_args + execute a command with out-of-line parameters + + + + +int SPI_execute_with_args(const char *command, + int nargs, Oid *argtypes, + Datum *values, const char *nulls, + bool read_only, long count) + + + + + Description + + + SPI_execute_with_args executes a command that might + include references to externally supplied parameters. The command text + refers to a parameter as $n, and + the call specifies data types and values for each such symbol. + read_only and count have + the same interpretation as in SPI_execute. + + + + The main advantage of this routine compared to + SPI_execute is that data values can be inserted + into the command without tedious quoting/escaping, and thus with much + less risk of SQL-injection attacks. + + + + Similar results can be achieved with SPI_prepare followed by + SPI_execute_plan; however, when using this function + the query plan is always customized to the specific parameter values + provided. + For one-time query execution, this function should be preferred. + If the same command is to be executed with many different parameters, + either method might be faster, depending on the cost of re-planning + versus the benefit of custom plans. + + + + + Arguments + + + + const char * command + + + command string + + + + + + int nargs + + + number of input parameters ($1, $2, etc.) + + + + + + Oid * argtypes + + + an array of length nargs, containing the + OIDs of the data types of the parameters + + + + + + Datum * values + + + an array of length nargs, containing the actual + parameter values + + + + + + const char * nulls + + + an array of length nargs, describing which + parameters are null + + + + If nulls is NULL then + SPI_execute_with_args assumes that no parameters + are null. Otherwise, each entry of the nulls + array should be ' ' if the corresponding parameter + value is non-null, or 'n' if the corresponding parameter + value is null. (In the latter case, the actual value in the + corresponding values entry doesn't matter.) Note + that nulls is not a text string, just an array: + it does not need a '\0' terminator. + + + + + + bool read_only + + true for read-only execution + + + + + long count + + + maximum number of rows to return, + or 0 for no limit + + + + + + + + Return Value + + + The return value is the same as for SPI_execute. + + + + SPI_processed and + SPI_tuptable are set as in + SPI_execute if successful. + + + + + + + + SPI_prepare + + + SPI_prepare + 3 + + + + SPI_prepare + prepare a statement, without executing it yet + + + + +SPIPlanPtr SPI_prepare(const char * command, int nargs, Oid * argtypes) + + + + + Description + + + SPI_prepare creates and returns a prepared + statement for the specified command, but doesn't execute the command. + The prepared statement can later be executed repeatedly using + SPI_execute_plan. + + + + When the same or a similar command is to be executed repeatedly, it + is generally advantageous to perform parse analysis only once, and + might furthermore be advantageous to re-use an execution plan for the + command. + SPI_prepare converts a command string into a + prepared statement that encapsulates the results of parse analysis. + The prepared statement also provides a place for caching an execution plan + if it is found that generating a custom plan for each execution is not + helpful. + + + + A prepared command can be generalized by writing parameters + ($1, $2, etc.) in place of what would be + constants in a normal command. The actual values of the parameters + are then specified when SPI_execute_plan is called. + This allows the prepared command to be used over a wider range of + situations than would be possible without parameters. + + + + The statement returned by SPI_prepare can be used + only in the current invocation of the C function, since + SPI_finish frees memory allocated for such a + statement. But the statement can be saved for longer using the functions + SPI_keepplan or SPI_saveplan. + + + + + Arguments + + + + const char * command + + + command string + + + + + + int nargs + + + number of input parameters ($1, $2, etc.) + + + + + + Oid * argtypes + + + pointer to an array containing the OIDs of + the data types of the parameters + + + + + + + + Return Value + + + SPI_prepare returns a non-null pointer to an + SPIPlan, which is an opaque struct representing a prepared + statement. On error, NULL will be returned, + and SPI_result will be set to one of the same + error codes used by SPI_execute, except that + it is set to SPI_ERROR_ARGUMENT if + command is NULL, or if + nargs is less than 0, or if nargs is + greater than 0 and argtypes is NULL. + + + + + Notes + + + If no parameters are defined, a generic plan will be created at the + first use of SPI_execute_plan, and used for all + subsequent executions as well. If there are parameters, the first few uses + of SPI_execute_plan will generate custom plans + that are specific to the supplied parameter values. After enough uses + of the same prepared statement, SPI_execute_plan will + build a generic plan, and if that is not too much more expensive than the + custom plans, it will start using the generic plan instead of re-planning + each time. If this default behavior is unsuitable, you can alter it by + passing the CURSOR_OPT_GENERIC_PLAN or + CURSOR_OPT_CUSTOM_PLAN flag to + SPI_prepare_cursor, to force use of generic or custom + plans respectively. + + + + Although the main point of a prepared statement is to avoid repeated parse + analysis and planning of the statement, PostgreSQL will + force re-analysis and re-planning of the statement before using it + whenever database objects used in the statement have undergone + definitional (DDL) changes since the previous use of the prepared + statement. Also, if the value of changes + from one use to the next, the statement will be re-parsed using the new + search_path. (This latter behavior is new as of + PostgreSQL 9.3.) See for more information about the behavior of prepared + statements. + + + + This function should only be called from a connected C function. + + + + SPIPlanPtr is declared as a pointer to an opaque struct type in + spi.h. It is unwise to try to access its contents + directly, as that makes your code much more likely to break in + future revisions of PostgreSQL. + + + + The name SPIPlanPtr is somewhat historical, since the data + structure no longer necessarily contains an execution plan. + + + + + + + + SPI_prepare_cursor + + + SPI_prepare_cursor + 3 + + + + SPI_prepare_cursor + prepare a statement, without executing it yet + + + + +SPIPlanPtr SPI_prepare_cursor(const char * command, int nargs, + Oid * argtypes, int cursorOptions) + + + + + Description + + + SPI_prepare_cursor is identical to + SPI_prepare, except that it also allows specification + of the planner's cursor options parameter. This is a bit mask + having the values shown in nodes/parsenodes.h + for the options field of DeclareCursorStmt. + SPI_prepare always takes the cursor options as zero. + + + + This function is now deprecated in favor + of SPI_prepare_extended. + + + + + Arguments + + + + const char * command + + + command string + + + + + + int nargs + + + number of input parameters ($1, $2, etc.) + + + + + + Oid * argtypes + + + pointer to an array containing the OIDs of + the data types of the parameters + + + + + + int cursorOptions + + + integer bit mask of cursor options; zero produces default behavior + + + + + + + + Return Value + + + SPI_prepare_cursor has the same return conventions as + SPI_prepare. + + + + + Notes + + + Useful bits to set in cursorOptions include + CURSOR_OPT_SCROLL, + CURSOR_OPT_NO_SCROLL, + CURSOR_OPT_FAST_PLAN, + CURSOR_OPT_GENERIC_PLAN, and + CURSOR_OPT_CUSTOM_PLAN. Note in particular that + CURSOR_OPT_HOLD is ignored. + + + + + + + + SPI_prepare_extended + + + SPI_prepare_extended + 3 + + + + SPI_prepare_extended + prepare a statement, without executing it yet + + + + +SPIPlanPtr SPI_prepare_extended(const char * command, + const SPIPrepareOptions * options) + + + + + Description + + + SPI_prepare_extended creates and returns a prepared + statement for the specified command, but doesn't execute the command. + This function is equivalent to SPI_prepare, + with the addition that the caller can specify options to control + the parsing of external parameter references, as well as other facets + of query parsing and planning. + + + + + Arguments + + + + const char * command + + + command string + + + + + + const SPIPrepareOptions * options + + + struct containing optional arguments + + + + + + + Callers should always zero out the entire options + struct, then fill whichever fields they want to set. This ensures forward + compatibility of code, since any fields that are added to the struct in + future will be defined to behave backwards-compatibly if they are zero. + The currently available options fields are: + + + + + ParserSetupHook parserSetup + + + Parser hook setup function + + + + + + void * parserSetupArg + + + pass-through argument for parserSetup + + + + + + RawParseMode parseMode + + + mode for raw parsing; RAW_PARSE_DEFAULT (zero) + produces default behavior + + + + + + int cursorOptions + + + integer bit mask of cursor options; zero produces default behavior + + + + + + + + Return Value + + + SPI_prepare_extended has the same return conventions as + SPI_prepare. + + + + + + + + SPI_prepare_params + + + SPI_prepare_params + 3 + + + + SPI_prepare_params + prepare a statement, without executing it yet + + + + +SPIPlanPtr SPI_prepare_params(const char * command, + ParserSetupHook parserSetup, + void * parserSetupArg, + int cursorOptions) + + + + + Description + + + SPI_prepare_params creates and returns a prepared + statement for the specified command, but doesn't execute the command. + This function is equivalent to SPI_prepare_cursor, + with the addition that the caller can specify parser hook functions + to control the parsing of external parameter references. + + + + This function is now deprecated in favor + of SPI_prepare_extended. + + + + + Arguments + + + + const char * command + + + command string + + + + + + ParserSetupHook parserSetup + + + Parser hook setup function + + + + + + void * parserSetupArg + + + pass-through argument for parserSetup + + + + + + int cursorOptions + + + integer bit mask of cursor options; zero produces default behavior + + + + + + + + Return Value + + + SPI_prepare_params has the same return conventions as + SPI_prepare. + + + + + + + + SPI_getargcount + + + SPI_getargcount + 3 + + + + SPI_getargcount + return the number of arguments needed by a statement + prepared by SPI_prepare + + + + +int SPI_getargcount(SPIPlanPtr plan) + + + + + Description + + + SPI_getargcount returns the number of arguments needed + to execute a statement prepared by SPI_prepare. + + + + + Arguments + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + + + Return Value + + The count of expected arguments for the plan. + If the plan is NULL or invalid, + SPI_result is set to SPI_ERROR_ARGUMENT + and -1 is returned. + + + + + + + + SPI_getargtypeid + + + SPI_getargtypeid + 3 + + + + SPI_getargtypeid + return the data type OID for an argument of + a statement prepared by SPI_prepare + + + + +Oid SPI_getargtypeid(SPIPlanPtr plan, int argIndex) + + + + + Description + + + SPI_getargtypeid returns the OID representing the type + for the argIndex'th argument of a statement prepared by + SPI_prepare. First argument is at index zero. + + + + + Arguments + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + int argIndex + + + zero based index of the argument + + + + + + + + Return Value + + The type OID of the argument at the given index. + If the plan is NULL or invalid, + or argIndex is less than 0 or + not less than the number of arguments declared for the + plan, + SPI_result is set to SPI_ERROR_ARGUMENT + and InvalidOid is returned. + + + + + + + + SPI_is_cursor_plan + + + SPI_is_cursor_plan + 3 + + + + SPI_is_cursor_plan + return true if a statement + prepared by SPI_prepare can be used with + SPI_cursor_open + + + + +bool SPI_is_cursor_plan(SPIPlanPtr plan) + + + + + Description + + + SPI_is_cursor_plan returns true + if a statement prepared by SPI_prepare can be passed + as an argument to SPI_cursor_open, or + false if that is not the case. The criteria are that the + plan represents one single command and that this + command returns tuples to the caller; for example, SELECT + is allowed unless it contains an INTO clause, and + UPDATE is allowed only if it contains a RETURNING + clause. + + + + + Arguments + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + + + Return Value + + true or false to indicate if the + plan can produce a cursor or not, with + SPI_result set to zero. + If it is not possible to determine the answer (for example, + if the plan is NULL or invalid, + or if called when not connected to SPI), then + SPI_result is set to a suitable error code + and false is returned. + + + + + + + + SPI_execute_plan + + + SPI_execute_plan + 3 + + + + SPI_execute_plan + execute a statement prepared by SPI_prepare + + + + +int SPI_execute_plan(SPIPlanPtr plan, Datum * values, const char * nulls, + bool read_only, long count) + + + + + Description + + + SPI_execute_plan executes a statement prepared by + SPI_prepare or one of its siblings. + read_only and + count have the same interpretation as in + SPI_execute. + + + + + Arguments + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + Datum * values + + + An array of actual parameter values. Must have same length as the + statement's number of arguments. + + + + + + const char * nulls + + + An array describing which parameters are null. Must have same length as + the statement's number of arguments. + + + + If nulls is NULL then + SPI_execute_plan assumes that no parameters + are null. Otherwise, each entry of the nulls + array should be ' ' if the corresponding parameter + value is non-null, or 'n' if the corresponding parameter + value is null. (In the latter case, the actual value in the + corresponding values entry doesn't matter.) Note + that nulls is not a text string, just an array: + it does not need a '\0' terminator. + + + + + + bool read_only + + true for read-only execution + + + + + long count + + + maximum number of rows to return, + or 0 for no limit + + + + + + + + Return Value + + + The return value is the same as for SPI_execute, + with the following additional possible error (negative) results: + + + + SPI_ERROR_ARGUMENT + + + if plan is NULL or invalid, + or count is less than 0 + + + + + + SPI_ERROR_PARAM + + + if values is NULL and + plan was prepared with some parameters + + + + + + + + SPI_processed and + SPI_tuptable are set as in + SPI_execute if successful. + + + + + + + + SPI_execute_plan_extended + + + SPI_execute_plan_extended + 3 + + + + SPI_execute_plan_extended + execute a statement prepared by SPI_prepare + + + + +int SPI_execute_plan_extended(SPIPlanPtr plan, + const SPIExecuteOptions * options) + + + + + Description + + + SPI_execute_plan_extended executes a statement + prepared by SPI_prepare or one of its siblings. + This function is equivalent to SPI_execute_plan, + except that information about the parameter values to be passed to the + query is presented differently, and additional execution-controlling + options can be passed. + + + + Query parameter values are represented by + a ParamListInfo struct, which is convenient for passing + down values that are already available in that format. Dynamic parameter + sets can also be used, via hook functions specified + in ParamListInfo. + + + + Also, instead of always accumulating the result tuples into a + SPI_tuptable structure, tuples can be passed to a + caller-supplied DestReceiver object as they are + generated by the executor. This is particularly helpful for queries + that might generate many tuples, since the data can be processed + on-the-fly instead of being accumulated in memory. + + + + + Arguments + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + const SPIExecuteOptions * options + + + struct containing optional arguments + + + + + + + Callers should always zero out the entire options + struct, then fill whichever fields they want to set. This ensures forward + compatibility of code, since any fields that are added to the struct in + future will be defined to behave backwards-compatibly if they are zero. + The currently available options fields are: + + + + + ParamListInfo params + + + data structure containing query parameter types and values; NULL if none + + + + + + bool read_only + + true for read-only execution + + + + + bool allow_nonatomic + + + true allows non-atomic execution of CALL and DO + statements + + + + + + uint64 tcount + + + maximum number of rows to return, + or 0 for no limit + + + + + + DestReceiver * dest + + + DestReceiver object that will receive any tuples + emitted by the query; if NULL, result tuples are accumulated into + a SPI_tuptable structure, as + in SPI_execute_plan + + + + + + ResourceOwner owner + + + The resource owner that will hold a reference count on the plan while + it is executed. If NULL, CurrentResourceOwner is used. Ignored for + non-saved plans, as SPI does not acquire reference counts on those. + + + + + + + + Return Value + + + The return value is the same as for SPI_execute_plan. + + + + When options->dest is NULL, + SPI_processed and + SPI_tuptable are set as in + SPI_execute_plan. + When options->dest is not NULL, + SPI_processed is set to zero and + SPI_tuptable is set to NULL. If a tuple count + is required, the caller's DestReceiver object must + calculate it. + + + + + + + + SPI_execute_plan_with_paramlist + + + SPI_execute_plan_with_paramlist + 3 + + + + SPI_execute_plan_with_paramlist + execute a statement prepared by SPI_prepare + + + + +int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, + ParamListInfo params, + bool read_only, + long count) + + + + + Description + + + SPI_execute_plan_with_paramlist executes a statement + prepared by SPI_prepare. + This function is equivalent to SPI_execute_plan + except that information about the parameter values to be passed to the + query is presented differently. The ParamListInfo + representation can be convenient for passing down values that are + already available in that format. It also supports use of dynamic + parameter sets via hook functions specified in ParamListInfo. + + + + This function is now deprecated in favor + of SPI_execute_plan_extended. + + + + + Arguments + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + ParamListInfo params + + + data structure containing parameter types and values; NULL if none + + + + + + bool read_only + + true for read-only execution + + + + + long count + + + maximum number of rows to return, + or 0 for no limit + + + + + + + + Return Value + + + The return value is the same as for SPI_execute_plan. + + + + SPI_processed and + SPI_tuptable are set as in + SPI_execute_plan if successful. + + + + + + + + SPI_execp + + + SPI_execp + 3 + + + + SPI_execp + execute a statement in read/write mode + + + + +int SPI_execp(SPIPlanPtr plan, Datum * values, const char * nulls, long count) + + + + + Description + + + SPI_execp is the same as + SPI_execute_plan, with the latter's + read_only parameter always taken as + false. + + + + + Arguments + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + Datum * values + + + An array of actual parameter values. Must have same length as the + statement's number of arguments. + + + + + + const char * nulls + + + An array describing which parameters are null. Must have same length as + the statement's number of arguments. + + + + If nulls is NULL then + SPI_execp assumes that no parameters + are null. Otherwise, each entry of the nulls + array should be ' ' if the corresponding parameter + value is non-null, or 'n' if the corresponding parameter + value is null. (In the latter case, the actual value in the + corresponding values entry doesn't matter.) Note + that nulls is not a text string, just an array: + it does not need a '\0' terminator. + + + + + + long count + + + maximum number of rows to return, + or 0 for no limit + + + + + + + + Return Value + + + See SPI_execute_plan. + + + + SPI_processed and + SPI_tuptable are set as in + SPI_execute if successful. + + + + + + + + SPI_cursor_open + + + SPI_cursor_open + 3 + + + + SPI_cursor_open + set up a cursor using a statement created with SPI_prepare + + + + +Portal SPI_cursor_open(const char * name, SPIPlanPtr plan, + Datum * values, const char * nulls, + bool read_only) + + + + + Description + + + SPI_cursor_open sets up a cursor (internally, + a portal) that will execute a statement prepared by + SPI_prepare. The parameters have the same + meanings as the corresponding parameters to + SPI_execute_plan. + + + + Using a cursor instead of executing the statement directly has two + benefits. First, the result rows can be retrieved a few at a time, + avoiding memory overrun for queries that return many rows. Second, + a portal can outlive the current C function (it can, in fact, live + to the end of the current transaction). Returning the portal name + to the C function's caller provides a way of returning a row set as + result. + + + + The passed-in parameter data will be copied into the cursor's portal, so it + can be freed while the cursor still exists. + + + + + Arguments + + + + const char * name + + + name for portal, or NULL to let the system + select a name + + + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + Datum * values + + + An array of actual parameter values. Must have same length as the + statement's number of arguments. + + + + + + const char * nulls + + + An array describing which parameters are null. Must have same length as + the statement's number of arguments. + + + + If nulls is NULL then + SPI_cursor_open assumes that no parameters + are null. Otherwise, each entry of the nulls + array should be ' ' if the corresponding parameter + value is non-null, or 'n' if the corresponding parameter + value is null. (In the latter case, the actual value in the + corresponding values entry doesn't matter.) Note + that nulls is not a text string, just an array: + it does not need a '\0' terminator. + + + + + + bool read_only + + true for read-only execution + + + + + + + Return Value + + + Pointer to portal containing the cursor. Note there is no error + return convention; any error will be reported via elog. + + + + + + + + SPI_cursor_open_with_args + + + SPI_cursor_open_with_args + 3 + + + + SPI_cursor_open_with_args + set up a cursor using a query and parameters + + + + +Portal SPI_cursor_open_with_args(const char *name, + const char *command, + int nargs, Oid *argtypes, + Datum *values, const char *nulls, + bool read_only, int cursorOptions) + + + + + Description + + + SPI_cursor_open_with_args sets up a cursor + (internally, a portal) that will execute the specified query. + Most of the parameters have the same meanings as the corresponding + parameters to SPI_prepare_cursor + and SPI_cursor_open. + + + + For one-time query execution, this function should be preferred + over SPI_prepare_cursor followed by + SPI_cursor_open. + If the same command is to be executed with many different parameters, + either method might be faster, depending on the cost of re-planning + versus the benefit of custom plans. + + + + The passed-in parameter data will be copied into the cursor's portal, so it + can be freed while the cursor still exists. + + + + This function is now deprecated in favor + of SPI_cursor_parse_open, which provides equivalent + functionality using a more modern API for handling query parameters. + + + + + Arguments + + + + const char * name + + + name for portal, or NULL to let the system + select a name + + + + + + const char * command + + + command string + + + + + + int nargs + + + number of input parameters ($1, $2, etc.) + + + + + + Oid * argtypes + + + an array of length nargs, containing the + OIDs of the data types of the parameters + + + + + + Datum * values + + + an array of length nargs, containing the actual + parameter values + + + + + + const char * nulls + + + an array of length nargs, describing which + parameters are null + + + + If nulls is NULL then + SPI_cursor_open_with_args assumes that no parameters + are null. Otherwise, each entry of the nulls + array should be ' ' if the corresponding parameter + value is non-null, or 'n' if the corresponding parameter + value is null. (In the latter case, the actual value in the + corresponding values entry doesn't matter.) Note + that nulls is not a text string, just an array: + it does not need a '\0' terminator. + + + + + + bool read_only + + true for read-only execution + + + + + int cursorOptions + + + integer bit mask of cursor options; zero produces default behavior + + + + + + + + Return Value + + + Pointer to portal containing the cursor. Note there is no error + return convention; any error will be reported via elog. + + + + + + + + SPI_cursor_open_with_paramlist + + + SPI_cursor_open_with_paramlist + 3 + + + + SPI_cursor_open_with_paramlist + set up a cursor using parameters + + + + +Portal SPI_cursor_open_with_paramlist(const char *name, + SPIPlanPtr plan, + ParamListInfo params, + bool read_only) + + + + + Description + + + SPI_cursor_open_with_paramlist sets up a cursor + (internally, a portal) that will execute a statement prepared by + SPI_prepare. + This function is equivalent to SPI_cursor_open + except that information about the parameter values to be passed to the + query is presented differently. The ParamListInfo + representation can be convenient for passing down values that are + already available in that format. It also supports use of dynamic + parameter sets via hook functions specified in ParamListInfo. + + + + The passed-in parameter data will be copied into the cursor's portal, so it + can be freed while the cursor still exists. + + + + + Arguments + + + + const char * name + + + name for portal, or NULL to let the system + select a name + + + + + + SPIPlanPtr plan + + + prepared statement (returned by SPI_prepare) + + + + + + ParamListInfo params + + + data structure containing parameter types and values; NULL if none + + + + + + bool read_only + + true for read-only execution + + + + + + + Return Value + + + Pointer to portal containing the cursor. Note there is no error + return convention; any error will be reported via elog. + + + + + + + + SPI_cursor_parse_open + + + SPI_cursor_parse_open + 3 + + + + SPI_cursor_parse_open + set up a cursor using a query string and parameters + + + + +Portal SPI_cursor_parse_open(const char *name, + const char *command, + const SPIParseOpenOptions * options) + + + + + Description + + + SPI_cursor_parse_open sets up a cursor + (internally, a portal) that will execute the specified query string. + This is comparable to SPI_prepare_cursor followed + by SPI_cursor_open_with_paramlist, except that + parameter references within the query string are handled entirely by + supplying a ParamListInfo object. + + + + For one-time query execution, this function should be preferred + over SPI_prepare_cursor followed by + SPI_cursor_open_with_paramlist. + If the same command is to be executed with many different parameters, + either method might be faster, depending on the cost of re-planning + versus the benefit of custom plans. + + + + The options->params object should normally + mark each parameter with the PARAM_FLAG_CONST flag, + since a one-shot plan is always used for the query. + + + + The passed-in parameter data will be copied into the cursor's portal, so it + can be freed while the cursor still exists. + + + + + Arguments + + + + const char * name + + + name for portal, or NULL to let the system + select a name + + + + + + const char * command + + + command string + + + + + + const SPIParseOpenOptions * options + + + struct containing optional arguments + + + + + + + Callers should always zero out the entire options + struct, then fill whichever fields they want to set. This ensures forward + compatibility of code, since any fields that are added to the struct in + future will be defined to behave backwards-compatibly if they are zero. + The currently available options fields are: + + + + + ParamListInfo params + + + data structure containing query parameter types and values; NULL if none + + + + + + int cursorOptions + + + integer bit mask of cursor options; zero produces default behavior + + + + + + bool read_only + + true for read-only execution + + + + + + + Return Value + + + Pointer to portal containing the cursor. Note there is no error + return convention; any error will be reported via elog. + + + + + + + + SPI_cursor_find + + + SPI_cursor_find + 3 + + + + SPI_cursor_find + find an existing cursor by name + + + + +Portal SPI_cursor_find(const char * name) + + + + + Description + + + SPI_cursor_find finds an existing portal by + name. This is primarily useful to resolve a cursor name returned + as text by some other function. + + + + + Arguments + + + + const char * name + + + name of the portal + + + + + + + + Return Value + + + pointer to the portal with the specified name, or + NULL if none was found + + + + + + + + SPI_cursor_fetch + + + SPI_cursor_fetch + 3 + + + + SPI_cursor_fetch + fetch some rows from a cursor + + + + +void SPI_cursor_fetch(Portal portal, bool forward, long count) + + + + + Description + + + SPI_cursor_fetch fetches some rows from a + cursor. This is equivalent to a subset of the SQL command + FETCH (see SPI_scroll_cursor_fetch + for more functionality). + + + + + Arguments + + + + Portal portal + + + portal containing the cursor + + + + + + bool forward + + + true for fetch forward, false for fetch backward + + + + + + long count + + + maximum number of rows to fetch + + + + + + + + Return Value + + + SPI_processed and + SPI_tuptable are set as in + SPI_execute if successful. + + + + + Notes + + + Fetching backward may fail if the cursor's plan was not created + with the CURSOR_OPT_SCROLL option. + + + + + + + + SPI_cursor_move + + + SPI_cursor_move + 3 + + + + SPI_cursor_move + move a cursor + + + + +void SPI_cursor_move(Portal portal, bool forward, long count) + + + + + Description + + + SPI_cursor_move skips over some number of rows + in a cursor. This is equivalent to a subset of the SQL command + MOVE (see SPI_scroll_cursor_move + for more functionality). + + + + + Arguments + + + + Portal portal + + + portal containing the cursor + + + + + + bool forward + + + true for move forward, false for move backward + + + + + + long count + + + maximum number of rows to move + + + + + + + + Notes + + + Moving backward may fail if the cursor's plan was not created + with the CURSOR_OPT_SCROLL option. + + + + + + + + SPI_scroll_cursor_fetch + + + SPI_scroll_cursor_fetch + 3 + + + + SPI_scroll_cursor_fetch + fetch some rows from a cursor + + + + +void SPI_scroll_cursor_fetch(Portal portal, FetchDirection direction, + long count) + + + + + Description + + + SPI_scroll_cursor_fetch fetches some rows from a + cursor. This is equivalent to the SQL command FETCH. + + + + + Arguments + + + + Portal portal + + + portal containing the cursor + + + + + + FetchDirection direction + + + one of FETCH_FORWARD, + FETCH_BACKWARD, + FETCH_ABSOLUTE or + FETCH_RELATIVE + + + + + + long count + + + number of rows to fetch for + FETCH_FORWARD or + FETCH_BACKWARD; absolute row number to fetch for + FETCH_ABSOLUTE; or relative row number to fetch for + FETCH_RELATIVE + + + + + + + + Return Value + + + SPI_processed and + SPI_tuptable are set as in + SPI_execute if successful. + + + + + Notes + + + See the SQL command + for details of the interpretation of the + direction and + count parameters. + + + + Direction values other than FETCH_FORWARD + may fail if the cursor's plan was not created + with the CURSOR_OPT_SCROLL option. + + + + + + + + SPI_scroll_cursor_move + + + SPI_scroll_cursor_move + 3 + + + + SPI_scroll_cursor_move + move a cursor + + + + +void SPI_scroll_cursor_move(Portal portal, FetchDirection direction, + long count) + + + + + Description + + + SPI_scroll_cursor_move skips over some number of rows + in a cursor. This is equivalent to the SQL command + MOVE. + + + + + Arguments + + + + Portal portal + + + portal containing the cursor + + + + + + FetchDirection direction + + + one of FETCH_FORWARD, + FETCH_BACKWARD, + FETCH_ABSOLUTE or + FETCH_RELATIVE + + + + + + long count + + + number of rows to move for + FETCH_FORWARD or + FETCH_BACKWARD; absolute row number to move to for + FETCH_ABSOLUTE; or relative row number to move to for + FETCH_RELATIVE + + + + + + + + Return Value + + + SPI_processed is set as in + SPI_execute if successful. + SPI_tuptable is set to NULL, since + no rows are returned by this function. + + + + + Notes + + + See the SQL command + for details of the interpretation of the + direction and + count parameters. + + + + Direction values other than FETCH_FORWARD + may fail if the cursor's plan was not created + with the CURSOR_OPT_SCROLL option. + + + + + + + + SPI_cursor_close + + + SPI_cursor_close + 3 + + + + SPI_cursor_close + close a cursor + + + + +void SPI_cursor_close(Portal portal) + + + + + Description + + + SPI_cursor_close closes a previously created + cursor and releases its portal storage. + + + + All open cursors are closed automatically at the end of a + transaction. SPI_cursor_close need only be + invoked if it is desirable to release resources sooner. + + + + + Arguments + + + + Portal portal + + + portal containing the cursor + + + + + + + + + + + SPI_keepplan + + + SPI_keepplan + 3 + + + + SPI_keepplan + save a prepared statement + + + + +int SPI_keepplan(SPIPlanPtr plan) + + + + + Description + + + SPI_keepplan saves a passed statement (prepared by + SPI_prepare) so that it will not be freed + by SPI_finish nor by the transaction manager. + This gives you the ability to reuse prepared statements in the subsequent + invocations of your C function in the current session. + + + + + Arguments + + + + SPIPlanPtr plan + + + the prepared statement to be saved + + + + + + + + Return Value + + + 0 on success; + SPI_ERROR_ARGUMENT if plan + is NULL or invalid + + + + + Notes + + + The passed-in statement is relocated to permanent storage by means + of pointer adjustment (no data copying is required). If you later + wish to delete it, use SPI_freeplan on it. + + + + + + + + SPI_saveplan + + + SPI_saveplan + 3 + + + + SPI_saveplan + save a prepared statement + + + + +SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) + + + + + Description + + + SPI_saveplan copies a passed statement (prepared by + SPI_prepare) into memory that will not be freed + by SPI_finish nor by the transaction manager, + and returns a pointer to the copied statement. This gives you the + ability to reuse prepared statements in the subsequent invocations of + your C function in the current session. + + + + + Arguments + + + + SPIPlanPtr plan + + + the prepared statement to be saved + + + + + + + + Return Value + + + Pointer to the copied statement; or NULL if unsuccessful. + On error, SPI_result is set thus: + + + + SPI_ERROR_ARGUMENT + + + if plan is NULL or invalid + + + + + + SPI_ERROR_UNCONNECTED + + + if called from an unconnected C function + + + + + + + + + Notes + + + The originally passed-in statement is not freed, so you might wish to do + SPI_freeplan on it to avoid leaking memory + until SPI_finish. + + + + In most cases, SPI_keepplan is preferred to this + function, since it accomplishes largely the same result without needing + to physically copy the prepared statement's data structures. + + + + + + + + SPI_register_relation + + + ephemeral named relation + registering with SPI + + + + SPI_register_relation + 3 + + + + SPI_register_relation + make an ephemeral named relation available by name in SPI queries + + + + +int SPI_register_relation(EphemeralNamedRelation enr) + + + + + Description + + + SPI_register_relation makes an ephemeral named + relation, with associated information, available to queries planned and + executed through the current SPI connection. + + + + + Arguments + + + + EphemeralNamedRelation enr + + + the ephemeral named relation registry entry + + + + + + + + Return Value + + + If the execution of the command was successful then the following + (nonnegative) value will be returned: + + + + SPI_OK_REL_REGISTER + + + if the relation has been successfully registered by name + + + + + + + + On error, one of the following negative values is returned: + + + + SPI_ERROR_ARGUMENT + + + if enr is NULL or its + name field is NULL + + + + + + SPI_ERROR_UNCONNECTED + + + if called from an unconnected C function + + + + + + SPI_ERROR_REL_DUPLICATE + + + if the name specified in the name field of + enr is already registered for this connection + + + + + + + + + + + + SPI_unregister_relation + + + ephemeral named relation + unregistering from SPI + + + + SPI_unregister_relation + 3 + + + + SPI_unregister_relation + remove an ephemeral named relation from the registry + + + + +int SPI_unregister_relation(const char * name) + + + + + Description + + + SPI_unregister_relation removes an ephemeral named + relation from the registry for the current connection. + + + + + Arguments + + + + const char * name + + + the relation registry entry name + + + + + + + + Return Value + + + If the execution of the command was successful then the following + (nonnegative) value will be returned: + + + + SPI_OK_REL_UNREGISTER + + + if the tuplestore has been successfully removed from the registry + + + + + + + + On error, one of the following negative values is returned: + + + + SPI_ERROR_ARGUMENT + + + if name is NULL + + + + + + SPI_ERROR_UNCONNECTED + + + if called from an unconnected C function + + + + + + SPI_ERROR_REL_NOT_FOUND + + + if name is not found in the registry for the + current connection + + + + + + + + + + + + SPI_register_trigger_data + + + ephemeral named relation + registering with SPI + + + + transition tables + implementation in PLs + + + + SPI_register_trigger_data + 3 + + + + SPI_register_trigger_data + make ephemeral trigger data available in SPI queries + + + + +int SPI_register_trigger_data(TriggerData *tdata) + + + + + Description + + + SPI_register_trigger_data makes any ephemeral + relations captured by a trigger available to queries planned and executed + through the current SPI connection. Currently, this means the transition + tables captured by an AFTER trigger defined with a + REFERENCING OLD/NEW TABLE AS ... clause. This function + should be called by a PL trigger handler function after connecting. + + + + + Arguments + + + + TriggerData *tdata + + + the TriggerData object passed to a trigger + handler function as fcinfo->context + + + + + + + + Return Value + + + If the execution of the command was successful then the following + (nonnegative) value will be returned: + + + + SPI_OK_TD_REGISTER + + + if the captured trigger data (if any) has been successfully registered + + + + + + + + On error, one of the following negative values is returned: + + + + SPI_ERROR_ARGUMENT + + + if tdata is NULL + + + + + + SPI_ERROR_UNCONNECTED + + + if called from an unconnected C function + + + + + + SPI_ERROR_REL_DUPLICATE + + + if the name of any trigger data transient relation is already + registered for this connection + + + + + + + + + + + + + + Interface Support Functions + + + The functions described here provide an interface for extracting + information from result sets returned by SPI_execute and + other SPI functions. + + + + All functions described in this section can be used by both + connected and unconnected C functions. + + + + + + SPI_fname + + + SPI_fname + 3 + + + + SPI_fname + determine the column name for the specified column number + + + + +char * SPI_fname(TupleDesc rowdesc, int colnumber) + + + + + Description + + + SPI_fname returns a copy of the column name of the + specified column. (You can use pfree to + release the copy of the name when you don't need it anymore.) + + + + + Arguments + + + + TupleDesc rowdesc + + + input row description + + + + + + int colnumber + + + column number (count starts at 1) + + + + + + + + Return Value + + + The column name; NULL if + colnumber is out of range. + SPI_result set to + SPI_ERROR_NOATTRIBUTE on error. + + + + + + + + SPI_fnumber + + + SPI_fnumber + 3 + + + + SPI_fnumber + determine the column number for the specified column name + + + + +int SPI_fnumber(TupleDesc rowdesc, const char * colname) + + + + + Description + + + SPI_fnumber returns the column number for the + column with the specified name. + + + + If colname refers to a system column (e.g., + ctid) then the appropriate negative column number will + be returned. The caller should be careful to test the return value + for exact equality to SPI_ERROR_NOATTRIBUTE to + detect an error; testing the result for less than or equal to 0 is + not correct unless system columns should be rejected. + + + + + Arguments + + + + TupleDesc rowdesc + + + input row description + + + + + + const char * colname + + + column name + + + + + + + + Return Value + + + Column number (count starts at 1 for user-defined columns), or + SPI_ERROR_NOATTRIBUTE if the named column was not + found. + + + + + + + + SPI_getvalue + + + SPI_getvalue + 3 + + + + SPI_getvalue + return the string value of the specified column + + + + +char * SPI_getvalue(HeapTuple row, TupleDesc rowdesc, int colnumber) + + + + + Description + + + SPI_getvalue returns the string representation + of the value of the specified column. + + + + The result is returned in memory allocated using + palloc. (You can use + pfree to release the memory when you don't + need it anymore.) + + + + + Arguments + + + + HeapTuple row + + + input row to be examined + + + + + + TupleDesc rowdesc + + + input row description + + + + + + int colnumber + + + column number (count starts at 1) + + + + + + + + Return Value + + + Column value, or NULL if the column is null, + colnumber is out of range + (SPI_result is set to + SPI_ERROR_NOATTRIBUTE), or no output function is + available (SPI_result is set to + SPI_ERROR_NOOUTFUNC). + + + + + + + + SPI_getbinval + + + SPI_getbinval + 3 + + + + SPI_getbinval + return the binary value of the specified column + + + + +Datum SPI_getbinval(HeapTuple row, TupleDesc rowdesc, int colnumber, + bool * isnull) + + + + + Description + + + SPI_getbinval returns the value of the + specified column in the internal form (as type Datum). + + + + This function does not allocate new space for the datum. In the + case of a pass-by-reference data type, the return value will be a + pointer into the passed row. + + + + + Arguments + + + + HeapTuple row + + + input row to be examined + + + + + + TupleDesc rowdesc + + + input row description + + + + + + int colnumber + + + column number (count starts at 1) + + + + + + bool * isnull + + + flag for a null value in the column + + + + + + + + Return Value + + + The binary value of the column is returned. The variable pointed + to by isnull is set to true if the column is + null, else to false. + + + + SPI_result is set to + SPI_ERROR_NOATTRIBUTE on error. + + + + + + + + SPI_gettype + + + SPI_gettype + 3 + + + + SPI_gettype + return the data type name of the specified column + + + + +char * SPI_gettype(TupleDesc rowdesc, int colnumber) + + + + + Description + + + SPI_gettype returns a copy of the data type name of the + specified column. (You can use pfree to + release the copy of the name when you don't need it anymore.) + + + + + Arguments + + + + TupleDesc rowdesc + + + input row description + + + + + + int colnumber + + + column number (count starts at 1) + + + + + + + + Return Value + + + The data type name of the specified column, or + NULL on error. SPI_result is + set to SPI_ERROR_NOATTRIBUTE on error. + + + + + + + + SPI_gettypeid + + + SPI_gettypeid + 3 + + + + SPI_gettypeid + return the data type OID of the specified column + + + + +Oid SPI_gettypeid(TupleDesc rowdesc, int colnumber) + + + + + Description + + + SPI_gettypeid returns the + OID of the data type of the specified column. + + + + + Arguments + + + + TupleDesc rowdesc + + + input row description + + + + + + int colnumber + + + column number (count starts at 1) + + + + + + + + Return Value + + + The OID of the data type of the specified column + or InvalidOid on error. On error, + SPI_result is set to + SPI_ERROR_NOATTRIBUTE. + + + + + + + + SPI_getrelname + + + SPI_getrelname + 3 + + + + SPI_getrelname + return the name of the specified relation + + + + +char * SPI_getrelname(Relation rel) + + + + + Description + + + SPI_getrelname returns a copy of the name of the + specified relation. (You can use pfree to + release the copy of the name when you don't need it anymore.) + + + + + Arguments + + + + Relation rel + + + input relation + + + + + + + + Return Value + + + The name of the specified relation. + + + + + + SPI_getnspname + + + SPI_getnspname + 3 + + + + SPI_getnspname + return the namespace of the specified relation + + + + +char * SPI_getnspname(Relation rel) + + + + + Description + + + SPI_getnspname returns a copy of the name of + the namespace that the specified Relation + belongs to. This is equivalent to the relation's schema. You should + pfree the return value of this function when + you are finished with it. + + + + + Arguments + + + + Relation rel + + + input relation + + + + + + + + Return Value + + + The name of the specified relation's namespace. + + + + + + SPI_result_code_string + + + SPI_result_code_string + 3 + + + + SPI_result_code_string + return error code as string + + + + +const char * SPI_result_code_string(int code); + + + + + Description + + + SPI_result_code_string returns a string representation + of the result code returned by various SPI functions or stored + in SPI_result. + + + + + Arguments + + + + int code + + + result code + + + + + + + + Return Value + + + A string representation of the result code. + + + + + + + + Memory Management + + + + memory context + in SPI + + PostgreSQL allocates memory within + memory contexts, which provide a convenient method of + managing allocations made in many different places that need to + live for differing amounts of time. Destroying a context releases + all the memory that was allocated in it. Thus, it is not necessary + to keep track of individual objects to avoid memory leaks; instead + only a relatively small number of contexts have to be managed. + palloc and related functions allocate memory + from the current context. + + + + SPI_connect creates a new memory context and + makes it current. SPI_finish restores the + previous current memory context and destroys the context created by + SPI_connect. These actions ensure that + transient memory allocations made inside your C function are + reclaimed at C function exit, avoiding memory leakage. + + + + However, if your C function needs to return an object in allocated + memory (such as a value of a pass-by-reference data type), you + cannot allocate that memory using palloc, at + least not while you are connected to SPI. If you try, the object + will be deallocated by SPI_finish, and your + C function will not work reliably. To solve this problem, use + SPI_palloc to allocate memory for your return + object. SPI_palloc allocates memory in the + upper executor context, that is, the memory context + that was current when SPI_connect was called, + which is precisely the right context for a value returned from your + C function. Several of the other utility functions described in + this section also return objects created in the upper executor context. + + + + When SPI_connect is called, the private + context of the C function, which is created by + SPI_connect, is made the current context. All + allocations made by palloc, + repalloc, or SPI utility functions (except as + described in this section) are made in this context. When a + C function disconnects from the SPI manager (via + SPI_finish) the current context is restored to + the upper executor context, and all allocations made in the + C function memory context are freed and cannot be used any more. + + + + + + SPI_palloc + + + SPI_palloc + 3 + + + + SPI_palloc + allocate memory in the upper executor context + + + + +void * SPI_palloc(Size size) + + + + + Description + + + SPI_palloc allocates memory in the upper + executor context. + + + + This function can only be used while connected to SPI. + Otherwise, it throws an error. + + + + + Arguments + + + + Size size + + + size in bytes of storage to allocate + + + + + + + + Return Value + + + pointer to new storage space of the specified size + + + + + + + + SPI_repalloc + + + SPI_repalloc + 3 + + + + SPI_repalloc + reallocate memory in the upper executor context + + + + +void * SPI_repalloc(void * pointer, Size size) + + + + + Description + + + SPI_repalloc changes the size of a memory + segment previously allocated using SPI_palloc. + + + + This function is no longer different from plain + repalloc. It's kept just for backward + compatibility of existing code. + + + + + Arguments + + + + void * pointer + + + pointer to existing storage to change + + + + + + Size size + + + size in bytes of storage to allocate + + + + + + + + Return Value + + + pointer to new storage space of specified size with the contents + copied from the existing area + + + + + + + + SPI_pfree + + + SPI_pfree + 3 + + + + SPI_pfree + free memory in the upper executor context + + + + +void SPI_pfree(void * pointer) + + + + + Description + + + SPI_pfree frees memory previously allocated + using SPI_palloc or + SPI_repalloc. + + + + This function is no longer different from plain + pfree. It's kept just for backward + compatibility of existing code. + + + + + Arguments + + + + void * pointer + + + pointer to existing storage to free + + + + + + + + + + + SPI_copytuple + + + SPI_copytuple + 3 + + + + SPI_copytuple + make a copy of a row in the upper executor context + + + + +HeapTuple SPI_copytuple(HeapTuple row) + + + + + Description + + + SPI_copytuple makes a copy of a row in the + upper executor context. This is normally used to return a modified + row from a trigger. In a function declared to return a composite + type, use SPI_returntuple instead. + + + + This function can only be used while connected to SPI. + Otherwise, it returns NULL and sets SPI_result to + SPI_ERROR_UNCONNECTED. + + + + + Arguments + + + + HeapTuple row + + + row to be copied + + + + + + + + Return Value + + + the copied row, or NULL on error + (see SPI_result for an error indication) + + + + + + + + SPI_returntuple + + + SPI_returntuple + 3 + + + + SPI_returntuple + prepare to return a tuple as a Datum + + + + +HeapTupleHeader SPI_returntuple(HeapTuple row, TupleDesc rowdesc) + + + + + Description + + + SPI_returntuple makes a copy of a row in + the upper executor context, returning it in the form of a row type Datum. + The returned pointer need only be converted to Datum via PointerGetDatum + before returning. + + + + This function can only be used while connected to SPI. + Otherwise, it returns NULL and sets SPI_result to + SPI_ERROR_UNCONNECTED. + + + + Note that this should be used for functions that are declared to return + composite types. It is not used for triggers; use + SPI_copytuple for returning a modified row in a trigger. + + + + + Arguments + + + + HeapTuple row + + + row to be copied + + + + + + TupleDesc rowdesc + + + descriptor for row (pass the same descriptor each time for most + effective caching) + + + + + + + + Return Value + + + HeapTupleHeader pointing to copied row, + or NULL on error + (see SPI_result for an error indication) + + + + + + + + SPI_modifytuple + + + SPI_modifytuple + 3 + + + + SPI_modifytuple + create a row by replacing selected fields of a given row + + + + +HeapTuple SPI_modifytuple(Relation rel, HeapTuple row, int ncols, + int * colnum, Datum * values, const char * nulls) + + + + + Description + + + SPI_modifytuple creates a new row by + substituting new values for selected columns, copying the original + row's columns at other positions. The input row is not modified. + The new row is returned in the upper executor context. + + + + This function can only be used while connected to SPI. + Otherwise, it returns NULL and sets SPI_result to + SPI_ERROR_UNCONNECTED. + + + + + Arguments + + + + Relation rel + + + Used only as the source of the row descriptor for the row. + (Passing a relation rather than a row descriptor is a + misfeature.) + + + + + + HeapTuple row + + + row to be modified + + + + + + int ncols + + + number of columns to be changed + + + + + + int * colnum + + + an array of length ncols, containing the numbers + of the columns that are to be changed (column numbers start at 1) + + + + + + Datum * values + + + an array of length ncols, containing the + new values for the specified columns + + + + + + const char * nulls + + + an array of length ncols, describing which + new values are null + + + + If nulls is NULL then + SPI_modifytuple assumes that no new values + are null. Otherwise, each entry of the nulls + array should be ' ' if the corresponding new value is + non-null, or 'n' if the corresponding new value is + null. (In the latter case, the actual value in the corresponding + values entry doesn't matter.) Note that + nulls is not a text string, just an array: it + does not need a '\0' terminator. + + + + + + + + Return Value + + + new row with modifications, allocated in the upper executor + context, or NULL on error + (see SPI_result for an error indication) + + + + On error, SPI_result is set as follows: + + + SPI_ERROR_ARGUMENT + + + if rel is NULL, or if + row is NULL, or if ncols + is less than or equal to 0, or if colnum is + NULL, or if values is NULL. + + + + + + SPI_ERROR_NOATTRIBUTE + + + if colnum contains an invalid column number (less + than or equal to 0 or greater than the number of columns in + row) + + + + + + SPI_ERROR_UNCONNECTED + + + if SPI is not active + + + + + + + + + + + + SPI_freetuple + + + SPI_freetuple + 3 + + + + SPI_freetuple + free a row allocated in the upper executor context + + + + +void SPI_freetuple(HeapTuple row) + + + + + Description + + + SPI_freetuple frees a row previously allocated + in the upper executor context. + + + + This function is no longer different from plain + heap_freetuple. It's kept just for backward + compatibility of existing code. + + + + + Arguments + + + + HeapTuple row + + + row to free + + + + + + + + + + + SPI_freetuptable + + + SPI_freetuptable + 3 + + + + SPI_freetuptable + free a row set created by SPI_execute or a similar + function + + + + +void SPI_freetuptable(SPITupleTable * tuptable) + + + + + Description + + + SPI_freetuptable frees a row set created by a + prior SPI command execution function, such as + SPI_execute. Therefore, this function is often called + with the global variable SPI_tuptable as + argument. + + + + This function is useful if an SPI-using C function needs to execute + multiple commands and does not want to keep the results of earlier + commands around until it ends. Note that any unfreed row sets will + be freed anyway at SPI_finish. + Also, if a subtransaction is started and then aborted within execution + of an SPI-using C function, SPI automatically frees any row sets created while + the subtransaction was running. + + + + Beginning in PostgreSQL 9.3, + SPI_freetuptable contains guard logic to protect + against duplicate deletion requests for the same row set. In previous + releases, duplicate deletions would lead to crashes. + + + + + Arguments + + + + SPITupleTable * tuptable + + + pointer to row set to free, or NULL to do nothing + + + + + + + + + + + SPI_freeplan + + + SPI_freeplan + 3 + + + + SPI_freeplan + free a previously saved prepared statement + + + + +int SPI_freeplan(SPIPlanPtr plan) + + + + + Description + + + SPI_freeplan releases a prepared statement + previously returned by SPI_prepare or saved by + SPI_keepplan or SPI_saveplan. + + + + + Arguments + + + + SPIPlanPtr plan + + + pointer to statement to free + + + + + + + + Return Value + + + 0 on success; + SPI_ERROR_ARGUMENT if plan + is NULL or invalid + + + + + + + + Transaction Management + + + It is not possible to run transaction control commands such + as COMMIT and ROLLBACK through SPI + functions such as SPI_execute. There are, however, + separate interface functions that allow transaction control through SPI. + + + + It is not generally safe and sensible to start and end transactions in + arbitrary user-defined SQL-callable functions without taking into account + the context in which they are called. For example, a transaction boundary + in the middle of a function that is part of a complex SQL expression that + is part of some SQL command will probably result in obscure internal errors + or crashes. The interface functions presented here are primarily intended + to be used by procedural language implementations to support transaction + management in SQL-level procedures that are invoked by the CALL + command, taking the context of the CALL invocation into + account. SPI-using procedures implemented in C can implement the same logic, but + the details of that are beyond the scope of this documentation. + + + + + + SPI_commit + SPI_commit_and_chain + + + SPI_commit + 3 + + + + SPI_commit + SPI_commit_and_chain + commit the current transaction + + + + +void SPI_commit(void) + + + +void SPI_commit_and_chain(void) + + + + + Description + + + SPI_commit commits the current transaction. It is + approximately equivalent to running the SQL + command COMMIT. After a transaction is committed, a new + transaction has to be started + using SPI_start_transaction before further database + actions can be executed. + + + + SPI_commit_and_chain is the same, but a new + transaction is immediately started with the same transaction + characteristics as the just finished one, like with the SQL command + COMMIT AND CHAIN. + + + + These functions can only be executed if the SPI connection has been set as + nonatomic in the call to SPI_connect_ext. + + + + + + + + SPI_rollback + SPI_rollback_and_chain + + + SPI_rollback + 3 + + + + SPI_rollback + SPI_rollback_and_chain + abort the current transaction + + + + +void SPI_rollback(void) + + + +void SPI_rollback_and_chain(void) + + + + + Description + + + SPI_rollback rolls back the current transaction. It + is approximately equivalent to running the SQL + command ROLLBACK. After a transaction is rolled back, a + new transaction has to be started + using SPI_start_transaction before further database + actions can be executed. + + + SPI_rollback_and_chain is the same, but a new + transaction is immediately started with the same transaction + characteristics as the just finished one, like with the SQL command + ROLLBACK AND CHAIN. + + + + These functions can only be executed if the SPI connection has been set as + nonatomic in the call to SPI_connect_ext. + + + + + + + + SPI_start_transaction + + + SPI_start_transaction + 3 + + + + SPI_start_transaction + start a new transaction + + + + +void SPI_start_transaction(void) + + + + + Description + + + SPI_start_transaction starts a new transaction. It + can only be called after SPI_commit + or SPI_rollback, as there is no transaction active at + that point. Normally, when an SPI-using procedure is called, there is already a + transaction active, so attempting to start another one before closing out + the current one will result in an error. + + + + This function can only be executed if the SPI connection has been set as + nonatomic in the call to SPI_connect_ext. + + + + + + + + Visibility of Data Changes + + + The following rules govern the visibility of data changes in + functions that use SPI (or any other C function): + + + + + During the execution of an SQL command, any data changes made by + the command are invisible to the command itself. For + example, in: + +INSERT INTO a SELECT * FROM a; + + the inserted rows are invisible to the SELECT + part. + + + + + + Changes made by a command C are visible to all commands that are + started after C, no matter whether they are started inside C + (during the execution of C) or after C is done. + + + + + + Commands executed via SPI inside a function called by an SQL command + (either an ordinary function or a trigger) follow one or the + other of the above rules depending on the read/write flag passed + to SPI. Commands executed in read-only mode follow the first + rule: they cannot see changes of the calling command. Commands executed + in read-write mode follow the second rule: they can see all changes made + so far. + + + + + + All standard procedural languages set the SPI read-write mode + depending on the volatility attribute of the function. Commands of + STABLE and IMMUTABLE functions are done in + read-only mode, while commands of VOLATILE functions are + done in read-write mode. While authors of C functions are able to + violate this convention, it's unlikely to be a good idea to do so. + + + + + + + The next section contains an example that illustrates the + application of these rules. + + + + + Examples + + + This section contains a very simple example of SPI usage. The + C function execq takes an SQL command as its + first argument and a row count as its second, executes the command + using SPI_exec and returns the number of rows + that were processed by the command. You can find more complex + examples for SPI in the source tree in + src/test/regress/regress.c and in the + module. + + + +#include "postgres.h" + +#include "executor/spi.h" +#include "utils/builtins.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(execq); + +Datum +execq(PG_FUNCTION_ARGS) +{ + char *command; + int cnt; + int ret; + uint64 proc; + + /* Convert given text object to a C string */ + command = text_to_cstring(PG_GETARG_TEXT_PP(0)); + cnt = PG_GETARG_INT32(1); + + SPI_connect(); + + ret = SPI_exec(command, cnt); + + proc = SPI_processed; + + /* + * If some rows were fetched, print them via elog(INFO). + */ + if (ret > 0 && SPI_tuptable != NULL) + { + SPITupleTable *tuptable = SPI_tuptable; + TupleDesc tupdesc = tuptable->tupdesc; + char buf[8192]; + uint64 j; + + for (j = 0; j < tuptable->numvals; j++) + { + HeapTuple tuple = tuptable->vals[j]; + int i; + + for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++) + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %s%s", + SPI_getvalue(tuple, tupdesc, i), + (i == tupdesc->natts) ? " " : " |"); + elog(INFO, "EXECQ: %s", buf); + } + } + + SPI_finish(); + pfree(command); + + PG_RETURN_INT64(proc); +} + + + + This is how you declare the function after having compiled it into + a shared library (details are in .): + + +CREATE FUNCTION execq(text, integer) RETURNS int8 + AS 'filename' + LANGUAGE C STRICT; + + + + + Here is a sample session: + + +=> SELECT execq('CREATE TABLE a (x integer)', 0); + execq +------- + 0 +(1 row) + +=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0)); +INSERT 0 1 +=> SELECT execq('SELECT * FROM a', 0); +INFO: EXECQ: 0 -- inserted by execq +INFO: EXECQ: 1 -- returned by execq and inserted by upper INSERT + + execq +------- + 2 +(1 row) + +=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a', 1); + execq +------- + 1 +(1 row) + +=> SELECT execq('SELECT * FROM a', 10); +INFO: EXECQ: 0 +INFO: EXECQ: 1 +INFO: EXECQ: 2 -- 0 + 2, only one row inserted - as specified + + execq +------- + 3 -- 10 is the max value only, 3 is the real number of rows +(1 row) + +=> DELETE FROM a; +DELETE 3 +=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1); +INSERT 0 1 +=> SELECT * FROM a; + x +--- + 1 -- no rows in a (0) + 1 +(1 row) + +=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1); +INFO: EXECQ: 1 +INSERT 0 1 +=> SELECT * FROM a; + x +--- + 1 + 2 -- there was one row in a + 1 +(2 rows) + +-- This demonstrates the data changes visibility rule: + +=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a; +INFO: EXECQ: 1 +INFO: EXECQ: 2 +INFO: EXECQ: 1 +INFO: EXECQ: 2 +INFO: EXECQ: 2 +INSERT 0 2 +=> SELECT * FROM a; + x +--- + 1 + 2 + 2 -- 2 rows * 1 (x in first row) + 6 -- 3 rows (2 + 1 just inserted) * 2 (x in second row) +(4 rows) ^^^^^^ + rows visible to execq() in different invocations + + + + diff --git a/doc/src/sgml/sslinfo.sgml b/doc/src/sgml/sslinfo.sgml new file mode 100644 index 000000000000..2a9c45a111bd --- /dev/null +++ b/doc/src/sgml/sslinfo.sgml @@ -0,0 +1,263 @@ + + + + sslinfo + + + sslinfo + + + + The sslinfo module provides information about the SSL + certificate that the current client provided when connecting to + PostgreSQL. The module is useless (most functions + will return NULL) if the current connection does not use SSL. + + + + Some of the information available through this module can also be obtained + using the built-in system view + pg_stat_ssl. + + + + This extension won't build at all unless the installation was + configured with --with-ssl=openssl. + + + + Functions Provided + + + + + ssl_is_used() returns boolean + + ssl_is_used + + + + + Returns true if current connection to server uses SSL, and false + otherwise. + + + + + + + ssl_version() returns text + + ssl_version + + + + + Returns the name of the protocol used for the SSL connection (e.g., TLSv1.0, + TLSv1.1, TLSv1.2 or TLSv1.3). + + + + + + + ssl_cipher() returns text + + ssl_cipher + + + + + Returns the name of the cipher used for the SSL connection + (e.g., DHE-RSA-AES256-SHA). + + + + + + + ssl_client_cert_present() returns boolean + + ssl_client_cert_present + + + + + Returns true if current client has presented a valid SSL client + certificate to the server, and false otherwise. (The server + might or might not be configured to require a client certificate.) + + + + + + + ssl_client_serial() returns numeric + + ssl_client_serial + + + + + Returns serial number of current client certificate. The combination of + certificate serial number and certificate issuer is guaranteed to + uniquely identify a certificate (but not its owner — the owner + ought to regularly change their keys, and get new certificates from the + issuer). + + + + So, if you run your own CA and allow only certificates from this CA to + be accepted by the server, the serial number is the most reliable (albeit + not very mnemonic) means to identify a user. + + + + + + + ssl_client_dn() returns text + + ssl_client_dn + + + + + Returns the full subject of the current client certificate, converting + character data into the current database encoding. It is assumed that + if you use non-ASCII characters in the certificate names, your + database is able to represent these characters, too. If your database + uses the SQL_ASCII encoding, non-ASCII characters in the name will be + represented as UTF-8 sequences. + + + + The result looks like /CN=Somebody /C=Some country/O=Some organization. + + + + + + + ssl_issuer_dn() returns text + + ssl_issuer_dn + + + + + Returns the full issuer name of the current client certificate, converting + character data into the current database encoding. Encoding conversions + are handled the same as for ssl_client_dn. + + + The combination of the return value of this function with the + certificate serial number uniquely identifies the certificate. + + + This function is really useful only if you have more than one trusted CA + certificate in your server's certificate authority file, or if this CA + has issued some intermediate certificate authority certificates. + + + + + + + ssl_client_dn_field(fieldname text) returns text + + ssl_client_dn_field + + + + + This function returns the value of the specified field in the + certificate subject, or NULL if the field is not present. + Field names are string constants that are converted into ASN1 object + identifiers using the OpenSSL object + database. The following values are acceptable: + + +commonName (alias CN) +surname (alias SN) +name +givenName (alias GN) +countryName (alias C) +localityName (alias L) +stateOrProvinceName (alias ST) +organizationName (alias O) +organizationalUnitName (alias OU) +title +description +initials +postalCode +streetAddress +generationQualifier +description +dnQualifier +x500UniqueIdentifier +pseudonym +role +emailAddress + + + All of these fields are optional, except commonName. + It depends + entirely on your CA's policy which of them would be included and which + wouldn't. The meaning of these fields, however, is strictly defined by + the X.500 and X.509 standards, so you cannot just assign arbitrary + meaning to them. + + + + + + + ssl_issuer_field(fieldname text) returns text + + ssl_issuer_field + + + + + Same as ssl_client_dn_field, but for the certificate issuer + rather than the certificate subject. + + + + + + + ssl_extension_info() returns setof record + + ssl_extension_info + + + + + Provide information about extensions of client certificate: extension name, + extension value, and if it is a critical extension. + + + + + + + + Author + + + Victor Wagner vitus@cryptocom.ru, Cryptocom LTD + + + + Dmitry Voronin carriingfate92@yandex.ru + + + + E-Mail of Cryptocom OpenSSL development group: + openssl@cryptocom.ru + + + + diff --git a/doc/src/sgml/standalone-profile.xsl b/doc/src/sgml/standalone-profile.xsl new file mode 100644 index 000000000000..8bdf58632cd1 --- /dev/null +++ b/doc/src/sgml/standalone-profile.xsl @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + document + + + + the documentation about client authentication and libpq + + + + the main documentation's appendix on documentation + + + + the documentation + + + + the configuration parameter default_toast_compression + + + + the documentation + + + + pgcrypto + + + + the PL/Python documentation + + + + the file + src/test/regress/README + and the documentation + + + + the documentation + + + + uuid-ossp + + + + xml2 + + + diff --git a/doc/src/sgml/start.sgml b/doc/src/sgml/start.sgml new file mode 100644 index 000000000000..f4ae1d0fcf78 --- /dev/null +++ b/doc/src/sgml/start.sgml @@ -0,0 +1,409 @@ + + + + Getting Started + + + Installation + + + Before you can use PostgreSQL you need + to install it, of course. It is possible that + PostgreSQL is already installed at your + site, either because it was included in your operating system + distribution or because the system administrator already installed + it. If that is the case, you should obtain information from the + operating system documentation or your system administrator about + how to access PostgreSQL. + + + + If you are not sure whether PostgreSQL + is already available or whether you can use it for your + experimentation then you can install it yourself. Doing so is not + hard and it can be a good exercise. + PostgreSQL can be installed by any + unprivileged user; no superuser (root) + access is required. + + + + If you are installing PostgreSQL + yourself, then refer to + for instructions on installation, and return to + this guide when the installation is complete. Be sure to follow + closely the section about setting up the appropriate environment + variables. + + + + If your site administrator has not set things up in the default + way, you might have some more work to do. For example, if the + database server machine is a remote machine, you will need to set + the PGHOST environment variable to the name of the + database server machine. The environment variable + PGPORT might also have to be set. The bottom line is + this: if you try to start an application program and it complains + that it cannot connect to the database, you should consult your + site administrator or, if that is you, the documentation to make + sure that your environment is properly set up. If you did not + understand the preceding paragraph then read the next section. + + + + + + Architectural Fundamentals + + + Before we proceed, you should understand the basic + PostgreSQL system architecture. + Understanding how the parts of + PostgreSQL interact will make this + chapter somewhat clearer. + + + + In database jargon, PostgreSQL uses a + client/server model. A PostgreSQL + session consists of the following cooperating processes + (programs): + + + + + A server process, which manages the database files, accepts + connections to the database from client applications, and + performs database actions on behalf of the clients. The + database server program is called + postgres. + postgres + + + + + + The user's client (frontend) application that wants to perform + database operations. Client applications can be very diverse + in nature: a client could be a text-oriented tool, a graphical + application, a web server that accesses the database to + display web pages, or a specialized database maintenance tool. + Some client applications are supplied with the + PostgreSQL distribution; most are + developed by users. + + + + + + + + As is typical of client/server applications, the client and the + server can be on different hosts. In that case they communicate + over a TCP/IP network connection. You should keep this in mind, + because the files that can be accessed on a client machine might + not be accessible (or might only be accessible using a different + file name) on the database server machine. + + + + The PostgreSQL server can handle + multiple concurrent connections from clients. To achieve this it + starts (forks) a new process for each connection. + From that point on, the client and the new server process + communicate without intervention by the original + postgres process. Thus, the + supervisor server process is always running, waiting for + client connections, whereas client and associated server processes + come and go. (All of this is of course invisible to the user. We + only mention it here for completeness.) + + + + + + Creating a Database + + + database + creating + + + + createdb + + + + The first test to see whether you can access the database server + is to try to create a database. A running + PostgreSQL server can manage many + databases. Typically, a separate database is used for each + project or for each user. + + + + Possibly, your site administrator has already created a database + for your use. In that case you can omit this step and skip ahead + to the next section. + + + + To create a new database, in this example named + mydb, you use the following command: + +$ createdb mydb + + If this produces no response then this step was successful and you can skip over the + remainder of this section. + + + + If you see a message similar to: + +createdb: command not found + + then PostgreSQL was not installed properly. Either it was not + installed at all or your shell's search path was not set to include it. + Try calling the command with an absolute path instead: + +$ /usr/local/pgsql/bin/createdb mydb + + The path at your site might be different. Contact your site + administrator or check the installation instructions to + correct the situation. + + + + Another response could be this: + +createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory + Is the server running locally and accepting connections on that socket? + + This means that the server was not started, or it is not listening + where createdb expects to contact it. Again, check the + installation instructions or consult the administrator. + + + + Another response could be this: + +createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: role "joe" does not exist + + where your own login name is mentioned. This will happen if the + administrator has not created a PostgreSQL user account + for you. (PostgreSQL user accounts are distinct from + operating system user accounts.) If you are the administrator, see + for help creating accounts. You will need to + become the operating system user under which PostgreSQL + was installed (usually postgres) to create the first user + account. It could also be that you were assigned a + PostgreSQL user name that is different from your + operating system user name; in that case you need to use the + switch or set the PGUSER environment variable to specify your + PostgreSQL user name. + + + + If you have a user account but it does not have the privileges required to + create a database, you will see the following: + +createdb: error: database creation failed: ERROR: permission denied to create database + + Not every user has authorization to create new databases. If + PostgreSQL refuses to create databases + for you then the site administrator needs to grant you permission + to create databases. Consult your site administrator if this + occurs. If you installed PostgreSQL + yourself then you should log in for the purposes of this tutorial + under the user account that you started the server as. + + + + As an explanation for why this works: + PostgreSQL user names are separate + from operating system user accounts. When you connect to a + database, you can choose what + PostgreSQL user name to connect as; + if you don't, it will default to the same name as your current + operating system account. As it happens, there will always be a + PostgreSQL user account that has the + same name as the operating system user that started the server, + and it also happens that that user always has permission to + create databases. Instead of logging in as that user you can + also specify the option everywhere to select + a PostgreSQL user name to connect as. + + + + + + You can also create databases with other names. + PostgreSQL allows you to create any + number of databases at a given site. Database names must have an + alphabetic first character and are limited to 63 bytes in + length. A convenient choice is to create a database with the same + name as your current user name. Many tools assume that database + name as the default, so it can save you some typing. To create + that database, simply type: + +$ createdb + + + + + If you do not want to use your database anymore you can remove it. + For example, if you are the owner (creator) of the database + mydb, you can destroy it using the following + command: + +$ dropdb mydb + + (For this command, the database name does not default to the user + account name. You always need to specify it.) This action + physically removes all files associated with the database and + cannot be undone, so this should only be done with a great deal of + forethought. + + + + More about createdb and dropdb can + be found in and + respectively. + + + + + + Accessing a Database + + + psql + + + + Once you have created a database, you can access it by: + + + + + Running the PostgreSQL interactive + terminal program, called psql, which allows you + to interactively enter, edit, and execute + SQL commands. + + + + + + Using an existing graphical frontend tool like + pgAdmin or an office suite with + ODBC or JDBC support to create and manipulate a + database. These possibilities are not covered in this + tutorial. + + + + + + Writing a custom application, using one of the several + available language bindings. These possibilities are discussed + further in . + + + + + You probably want to start up psql to try + the examples in this tutorial. It can be activated for the + mydb database by typing the command: + +$ psql mydb + + If you do not supply the database name then it will default to your + user account name. You already discovered this scheme in the + previous section using createdb. + + + + In psql, you will be greeted with the following + message: + +psql (&version;) +Type "help" for help. + +mydb=> + + superuser + The last line could also be: + +mydb=# + + That would mean you are a database superuser, which is most likely + the case if you installed the PostgreSQL instance + yourself. Being a superuser means that you are not subject to + access controls. For the purposes of this tutorial that is not + important. + + + + If you encounter problems starting psql + then go back to the previous section. The diagnostics of + createdb and psql are + similar, and if the former worked the latter should work as well. + + + + The last line printed out by psql is the + prompt, and it indicates that psql is listening + to you and that you can type SQL queries into a + work space maintained by psql. Try out these + commands: + version + +mydb=> SELECT version(); + version +-------------------------------------------------------------------&zwsp;----------------------- + PostgreSQL &version; on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit +(1 row) + +mydb=> SELECT current_date; + date +------------ + 2016-01-07 +(1 row) + +mydb=> SELECT 2 + 2; + ?column? +---------- + 4 +(1 row) + + + + + The psql program has a number of internal + commands that are not SQL commands. They begin with the backslash + character, \. + For example, + you can get help on the syntax of various + PostgreSQL SQL + commands by typing: + +mydb=> \h + + + + + To get out of psql, type: + +mydb=> \q + + and psql will quit and return you to your + command shell. (For more internal commands, type + \? at the psql prompt.) The + full capabilities of psql are documented in + . In this tutorial we will not use these + features explicitly, but you can use them yourself when it is helpful. + + + + diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml new file mode 100644 index 000000000000..7136bbe7a32f --- /dev/null +++ b/doc/src/sgml/storage.sgml @@ -0,0 +1,1077 @@ + + + + +Database Physical Storage + + +This chapter provides an overview of the physical storage format used by +PostgreSQL databases. + + + + +Database File Layout + + +This section describes the storage format at the level of files and +directories. + + + +Traditionally, the configuration and data files used by a database +cluster are stored together within the cluster's data +directory, commonly referred to as PGDATA (after the name of the +environment variable that can be used to define it). A common location for +PGDATA is /var/lib/pgsql/data. Multiple clusters, +managed by different server instances, can exist on the same machine. + + + +The PGDATA directory contains several subdirectories and control +files, as shown in . In addition to +these required items, the cluster configuration files +postgresql.conf, pg_hba.conf, and +pg_ident.conf are traditionally stored in +PGDATA, although it is possible to place them elsewhere. + + + +Contents of <varname>PGDATA</varname> + + + + +Item + +Description + + + + + + + PG_VERSION + A file containing the major version number of PostgreSQL + + + + base + Subdirectory containing per-database subdirectories + + + + current_logfiles + File recording the log file(s) currently written to by the logging + collector + + + + global + Subdirectory containing cluster-wide tables, such as + pg_database + + + + pg_commit_ts + Subdirectory containing transaction commit timestamp data + + + + pg_dynshmem + Subdirectory containing files used by the dynamic shared memory + subsystem + + + + pg_logical + Subdirectory containing status data for logical decoding + + + + pg_multixact + Subdirectory containing multitransaction status data + (used for shared row locks) + + + + pg_notify + Subdirectory containing LISTEN/NOTIFY status data + + + + pg_replslot + Subdirectory containing replication slot data + + + + pg_serial + Subdirectory containing information about committed serializable transactions + + + + pg_snapshots + Subdirectory containing exported snapshots + + + + pg_stat + Subdirectory containing permanent files for the statistics + subsystem + + + + pg_stat_tmp + Subdirectory containing temporary files for the statistics + subsystem + + + + pg_subtrans + Subdirectory containing subtransaction status data + + + + pg_tblspc + Subdirectory containing symbolic links to tablespaces + + + + pg_twophase + Subdirectory containing state files for prepared transactions + + + + pg_wal + Subdirectory containing WAL (Write Ahead Log) files + + + + pg_xact + Subdirectory containing transaction commit status data + + + + postgresql.auto.conf + A file used for storing configuration parameters that are set by +ALTER SYSTEM + + + + postmaster.opts + A file recording the command-line options the server was +last started with + + + + postmaster.pid + A lock file recording the current postmaster process ID (PID), + cluster data directory path, + postmaster start timestamp, + port number, + Unix-domain socket directory path (could be empty), + first valid listen_address (IP address or *, or empty if + not listening on TCP), + and shared memory segment ID + (this file is not present after server shutdown) + + + + +
+ + +For each database in the cluster there is a subdirectory within +PGDATA/base, named after the database's OID in +pg_database. This subdirectory is the default location +for the database's files; in particular, its system catalogs are stored +there. + + + + Note that the following sections describe the behavior of the builtin + heap table access method, + and the builtin index access methods. Due + to the extensible nature of PostgreSQL, other + access methods might work differently. + + + +Each table and index is stored in a separate file. For ordinary relations, +these files are named after the table or index's filenode number, +which can be found in pg_class.relfilenode. But +for temporary relations, the file name is of the form +tBBB_FFF, where BBB +is the backend ID of the backend which created the file, and FFF +is the filenode number. In either case, in addition to the main file (a/k/a +main fork), each table and index has a free space map (see ), which stores information about free space available in +the relation. The free space map is stored in a file named with the filenode +number plus the suffix _fsm. Tables also have a +visibility map, stored in a fork with the suffix _vm, +to track which pages are known to have no dead tuples. The visibility map is +described further in . Unlogged tables and indexes +have a third fork, known as the initialization fork, which is stored in a fork +with the suffix _init (see ). + + + + +Note that while a table's filenode often matches its OID, this is +not necessarily the case; some operations, like +TRUNCATE, REINDEX, CLUSTER and some forms +of ALTER TABLE, can change the filenode while preserving the OID. +Avoid assuming that filenode and table OID are the same. +Also, for certain system catalogs including pg_class itself, +pg_class.relfilenode contains zero. The +actual filenode number of these catalogs is stored in a lower-level data +structure, and can be obtained using the pg_relation_filenode() +function. + + + + +When a table or index exceeds 1 GB, it is divided into gigabyte-sized +segments. The first segment's file name is the same as the +filenode; subsequent segments are named filenode.1, filenode.2, etc. +This arrangement avoids problems on platforms that have file size limitations. +(Actually, 1 GB is just the default segment size. The segment size can be +adjusted using the configuration option +when building PostgreSQL.) +In principle, free space map and visibility map forks could require multiple +segments as well, though this is unlikely to happen in practice. + + + +A table that has columns with potentially large entries will have an +associated TOAST table, which is used for out-of-line storage of +field values that are too large to keep in the table rows proper. +pg_class.reltoastrelid links from a table to +its TOAST table, if any. +See for more information. + + + +The contents of tables and indexes are discussed further in +. + + + +Tablespaces make the scenario more complicated. Each user-defined tablespace +has a symbolic link inside the PGDATA/pg_tblspc +directory, which points to the physical tablespace directory (i.e., the +location specified in the tablespace's CREATE TABLESPACE command). +This symbolic link is named after +the tablespace's OID. Inside the physical tablespace directory there is +a subdirectory with a name that depends on the PostgreSQL +server version, such as PG_9.0_201008051. (The reason for using +this subdirectory is so that successive versions of the database can use +the same CREATE TABLESPACE location value without conflicts.) +Within the version-specific subdirectory, there is +a subdirectory for each database that has elements in the tablespace, named +after the database's OID. Tables and indexes are stored within that +directory, using the filenode naming scheme. +The pg_default tablespace is not accessed through +pg_tblspc, but corresponds to +PGDATA/base. Similarly, the pg_global +tablespace is not accessed through pg_tblspc, but corresponds to +PGDATA/global. + + + +The pg_relation_filepath() function shows the entire path +(relative to PGDATA) of any relation. It is often useful +as a substitute for remembering many of the above rules. But keep in +mind that this function just gives the name of the first segment of the +main fork of the relation — you may need to append a segment number +and/or _fsm, _vm, or _init to find all +the files associated with the relation. + + + +Temporary files (for operations such as sorting more data than can fit in +memory) are created within PGDATA/base/pgsql_tmp, +or within a pgsql_tmp subdirectory of a tablespace directory +if a tablespace other than pg_default is specified for them. +The name of a temporary file has the form +pgsql_tmpPPP.NNN, +where PPP is the PID of the owning backend and +NNN distinguishes different temporary files of that backend. + + +
+ + + +TOAST + + + TOAST + + sliced breadTOAST + + +This section provides an overview of TOAST (The +Oversized-Attribute Storage Technique). + + + +PostgreSQL uses a fixed page size (commonly +8 kB), and does not allow tuples to span multiple pages. Therefore, it is +not possible to store very large field values directly. To overcome +this limitation, large field values are compressed and/or broken up into +multiple physical rows. This happens transparently to the user, with only +small impact on most of the backend code. The technique is affectionately +known as TOAST (or the best thing since sliced bread). +The TOAST infrastructure is also used to improve handling of +large data values in-memory. + + + +Only certain data types support TOAST — there is no need to +impose the overhead on data types that cannot produce large field values. +To support TOAST, a data type must have a variable-length +(varlena) representation, in which, ordinarily, the first +four-byte word of any stored value contains the total length of the value in +bytes (including itself). TOAST does not constrain the rest +of the data type's representation. The special representations collectively +called TOASTed values work by modifying or +reinterpreting this initial length word. Therefore, the C-level functions +supporting a TOAST-able data type must be careful about how they +handle potentially TOASTed input values: an input might not +actually consist of a four-byte length word and contents until after it's +been detoasted. (This is normally done by invoking +PG_DETOAST_DATUM before doing anything with an input value, +but in some cases more efficient approaches are possible. +See for more detail.) + + + +TOAST usurps two bits of the varlena length word (the high-order +bits on big-endian machines, the low-order bits on little-endian machines), +thereby limiting the logical size of any value of a TOAST-able +data type to 1 GB (230 - 1 bytes). When both bits are zero, +the value is an ordinary un-TOASTed value of the data type, and +the remaining bits of the length word give the total datum size (including +length word) in bytes. When the highest-order or lowest-order bit is set, +the value has only a single-byte header instead of the normal four-byte +header, and the remaining bits of that byte give the total datum size +(including length byte) in bytes. This alternative supports space-efficient +storage of values shorter than 127 bytes, while still allowing the data type +to grow to 1 GB at need. Values with single-byte headers aren't aligned on +any particular boundary, whereas values with four-byte headers are aligned on +at least a four-byte boundary; this omission of alignment padding provides +additional space savings that is significant compared to short values. +As a special case, if the remaining bits of a single-byte header are all +zero (which would be impossible for a self-inclusive length), the value is +a pointer to out-of-line data, with several possible alternatives as +described below. The type and size of such a TOAST pointer +are determined by a code stored in the second byte of the datum. +Lastly, when the highest-order or lowest-order bit is clear but the adjacent +bit is set, the content of the datum has been compressed and must be +decompressed before use. In this case the remaining bits of the four-byte +length word give the total size of the compressed datum, not the +original data. Note that compression is also possible for out-of-line data +but the varlena header does not tell whether it has occurred — +the content of the TOAST pointer tells that, instead. + + + +The compression technique used for either in-line or out-of-line compressed +data can be selected for each column by setting +the COMPRESSION column option in CREATE +TABLE or ALTER TABLE. The default for columns +with no explicit setting is to consult the + parameter at the time data is +inserted. + + + +As mentioned, there are multiple types of TOAST pointer datums. +The oldest and most common type is a pointer to out-of-line data stored in +a TOAST table that is separate from, but +associated with, the table containing the TOAST pointer datum +itself. These on-disk pointer datums are created by the +TOAST management code (in access/common/toast_internals.c) +when a tuple to be stored on disk is too large to be stored as-is. +Further details appear in . +Alternatively, a TOAST pointer datum can contain a pointer to +out-of-line data that appears elsewhere in memory. Such datums are +necessarily short-lived, and will never appear on-disk, but they are very +useful for avoiding copying and redundant processing of large data values. +Further details appear in . + + + + Out-of-Line, On-Disk TOAST Storage + + +If any of the columns of a table are TOAST-able, the table will +have an associated TOAST table, whose OID is stored in the table's +pg_class.reltoastrelid entry. On-disk +TOASTed values are kept in the TOAST table, as +described in more detail below. + + + +Out-of-line values are divided (after compression if used) into chunks of at +most TOAST_MAX_CHUNK_SIZE bytes (by default this value is chosen +so that four chunk rows will fit on a page, making it about 2000 bytes). +Each chunk is stored as a separate row in the TOAST table +belonging to the owning table. Every +TOAST table has the columns chunk_id (an OID +identifying the particular TOASTed value), +chunk_seq (a sequence number for the chunk within its value), +and chunk_data (the actual data of the chunk). A unique index +on chunk_id and chunk_seq provides fast +retrieval of the values. A pointer datum representing an out-of-line on-disk +TOASTed value therefore needs to store the OID of the +TOAST table in which to look and the OID of the specific value +(its chunk_id). For convenience, pointer datums also store the +logical datum size (original uncompressed data length), physical stored size +(different if compression was applied), and the compression method used, if +any. Allowing for the varlena header bytes, +the total size of an on-disk TOAST pointer datum is therefore 18 +bytes regardless of the actual size of the represented value. + + + +The TOAST management code is triggered only +when a row value to be stored in a table is wider than +TOAST_TUPLE_THRESHOLD bytes (normally 2 kB). +The TOAST code will compress and/or move +field values out-of-line until the row value is shorter than +TOAST_TUPLE_TARGET bytes (also normally 2 kB, adjustable) +or no more gains can be had. During an UPDATE +operation, values of unchanged fields are normally preserved as-is; so an +UPDATE of a row with out-of-line values incurs no TOAST costs if +none of the out-of-line values change. + + + +The TOAST management code recognizes four different strategies +for storing TOAST-able columns on disk: + + + + + PLAIN prevents either compression or + out-of-line storage; furthermore it disables use of single-byte headers + for varlena types. + This is the only possible strategy for + columns of non-TOAST-able data types. + + + + + EXTENDED allows both compression and out-of-line + storage. This is the default for most TOAST-able data types. + Compression will be attempted first, then out-of-line storage if + the row is still too big. + + + + + EXTERNAL allows out-of-line storage but not + compression. Use of EXTERNAL will + make substring operations on wide text and + bytea columns faster (at the penalty of increased storage + space) because these operations are optimized to fetch only the + required parts of the out-of-line value when it is not compressed. + + + + + MAIN allows compression but not out-of-line + storage. (Actually, out-of-line storage will still be performed + for such columns, but only as a last resort when there is no other + way to make the row small enough to fit on a page.) + + + + +Each TOAST-able data type specifies a default strategy for columns +of that data type, but the strategy for a given table column can be altered +with ALTER TABLE ... SET STORAGE. + + + +TOAST_TUPLE_TARGET can be adjusted for each table using +ALTER TABLE ... SET (toast_tuple_target = N) + + + +This scheme has a number of advantages compared to a more straightforward +approach such as allowing row values to span pages. Assuming that queries are +usually qualified by comparisons against relatively small key values, most of +the work of the executor will be done using the main row entry. The big values +of TOASTed attributes will only be pulled out (if selected at all) +at the time the result set is sent to the client. Thus, the main table is much +smaller and more of its rows fit in the shared buffer cache than would be the +case without any out-of-line storage. Sort sets shrink also, and sorts will +more often be done entirely in memory. A little test showed that a table +containing typical HTML pages and their URLs was stored in about half of the +raw data size including the TOAST table, and that the main table +contained only about 10% of the entire data (the URLs and some small HTML +pages). There was no run time difference compared to an un-TOASTed +comparison table, in which all the HTML pages were cut down to 7 kB to fit. + + + + + + Out-of-Line, In-Memory TOAST Storage + + +TOAST pointers can point to data that is not on disk, but is +elsewhere in the memory of the current server process. Such pointers +obviously cannot be long-lived, but they are nonetheless useful. There +are currently two sub-cases: +pointers to indirect data and +pointers to expanded data. + + + +Indirect TOAST pointers simply point at a non-indirect varlena +value stored somewhere in memory. This case was originally created merely +as a proof of concept, but it is currently used during logical decoding to +avoid possibly having to create physical tuples exceeding 1 GB (as pulling +all out-of-line field values into the tuple might do). The case is of +limited use since the creator of the pointer datum is entirely responsible +that the referenced data survives for as long as the pointer could exist, +and there is no infrastructure to help with this. + + + +Expanded TOAST pointers are useful for complex data types +whose on-disk representation is not especially suited for computational +purposes. As an example, the standard varlena representation of a +PostgreSQL array includes dimensionality information, a +nulls bitmap if there are any null elements, then the values of all the +elements in order. When the element type itself is variable-length, the +only way to find the N'th element is to scan through all the +preceding elements. This representation is appropriate for on-disk storage +because of its compactness, but for computations with the array it's much +nicer to have an expanded or deconstructed +representation in which all the element starting locations have been +identified. The TOAST pointer mechanism supports this need by +allowing a pass-by-reference Datum to point to either a standard varlena +value (the on-disk representation) or a TOAST pointer that +points to an expanded representation somewhere in memory. The details of +this expanded representation are up to the data type, though it must have +a standard header and meet the other API requirements given +in src/include/utils/expandeddatum.h. C-level functions +working with the data type can choose to handle either representation. +Functions that do not know about the expanded representation, but simply +apply PG_DETOAST_DATUM to their inputs, will automatically +receive the traditional varlena representation; so support for an expanded +representation can be introduced incrementally, one function at a time. + + + +TOAST pointers to expanded values are further broken down +into read-write and read-only pointers. +The pointed-to representation is the same either way, but a function that +receives a read-write pointer is allowed to modify the referenced value +in-place, whereas one that receives a read-only pointer must not; it must +first create a copy if it wants to make a modified version of the value. +This distinction and some associated conventions make it possible to avoid +unnecessary copying of expanded values during query execution. + + + +For all types of in-memory TOAST pointer, the TOAST +management code ensures that no such pointer datum can accidentally get +stored on disk. In-memory TOAST pointers are automatically +expanded to normal in-line varlena values before storage — and then +possibly converted to on-disk TOAST pointers, if the containing +tuple would otherwise be too big. + + + + + + + + +Free Space Map + + + Free Space Map + +FSMFree Space Map + + +Each heap and index relation, except for hash indexes, has a Free Space Map +(FSM) to keep track of available space in the relation. It's stored +alongside the main relation data in a separate relation fork, named after the +filenode number of the relation, plus a _fsm suffix. For example, +if the filenode of a relation is 12345, the FSM is stored in a file called +12345_fsm, in the same directory as the main relation file. + + + +The Free Space Map is organized as a tree of FSM pages. The +bottom level FSM pages store the free space available on each +heap (or index) page, using one byte to represent each such page. The upper +levels aggregate information from the lower levels. + + + +Within each FSM page is a binary tree, stored in an array with +one byte per node. Each leaf node represents a heap page, or a lower level +FSM page. In each non-leaf node, the higher of its children's +values is stored. The maximum value in the leaf nodes is therefore stored +at the root. + + + +See src/backend/storage/freespace/README for more details on +how the FSM is structured, and how it's updated and searched. +The module +can be used to examine the information stored in free space maps. + + + + + + +Visibility Map + + + Visibility Map + +VMVisibility Map + + +Each heap relation has a Visibility Map +(VM) to keep track of which pages contain only tuples that are known to be +visible to all active transactions; it also keeps track of which pages contain +only frozen tuples. It's stored +alongside the main relation data in a separate relation fork, named after the +filenode number of the relation, plus a _vm suffix. For example, +if the filenode of a relation is 12345, the VM is stored in a file called +12345_vm, in the same directory as the main relation file. +Note that indexes do not have VMs. + + + +The visibility map stores two bits per heap page. The first bit, if set, +indicates that the page is all-visible, or in other words that the page does +not contain any tuples that need to be vacuumed. +This information can also be used +by index-only +scans to answer queries using only the index tuple. +The second bit, if set, means that all tuples on the page have been frozen. +That means that even an anti-wraparound vacuum need not revisit the page. + + + +The map is conservative in the sense that we make sure that whenever a bit is +set, we know the condition is true, but if a bit is not set, it might or +might not be true. Visibility map bits are only set by vacuum, but are +cleared by any data-modifying operations on a page. + + + +The module can be used to examine the +information stored in the visibility map. + + + + + + +The Initialization Fork + + + Initialization Fork + + + +Each unlogged table, and each index on an unlogged table, has an initialization +fork. The initialization fork is an empty table or index of the appropriate +type. When an unlogged table must be reset to empty due to a crash, the +initialization fork is copied over the main fork, and any other forks are +erased (they will be recreated automatically as needed). + + + + + + +Database Page Layout + + +This section provides an overview of the page format used within +PostgreSQL tables and indexes. + + Actually, use of this page format is not required for either table or + index access methods. The heap table access method + always uses this format. All the existing index methods also use the + basic format, but the data kept on index metapages usually doesn't follow + the item layout rules. + + +Sequences and TOAST tables are formatted just like a regular table. + + + +In the following explanation, a +byte +is assumed to contain 8 bits. In addition, the term +item +refers to an individual data value that is stored on a page. In a table, +an item is a row; in an index, an item is an index entry. + + + +Every table and index is stored as an array of pages of a +fixed size (usually 8 kB, although a different page size can be selected +when compiling the server). In a table, all the pages are logically +equivalent, so a particular item (row) can be stored in any page. In +indexes, the first page is generally reserved as a metapage +holding control information, and there can be different types of pages +within the index, depending on the index access method. + + + + shows the overall layout of a page. +There are five parts to each page. + + + +Overall Page Layout +Page Layout + + + + +Item + +Description + + + + + + + PageHeaderData + 24 bytes long. Contains general information about the page, including +free space pointers. + + + +ItemIdData +Array of item identifiers pointing to the actual items. Each +entry is an (offset,length) pair. 4 bytes per item. + + + +Free space +The unallocated space. New item identifiers are allocated from +the start of this area, new items from the end. + + + +Items +The actual items themselves. + + + +Special space +Index access method specific data. Different methods store different +data. Empty in ordinary tables. + + + + +
+ + + + The first 24 bytes of each page consists of a page header + (PageHeaderData). Its format is detailed in . The first field tracks the most + recent WAL entry related to this page. The second field contains + the page checksum if are + enabled. Next is a 2-byte field containing flag bits. This is followed + by three 2-byte integer fields (pd_lower, + pd_upper, and + pd_special). These contain byte offsets + from the page start to the start of unallocated space, to the end of + unallocated space, and to the start of the special space. The next 2 + bytes of the page header, pd_pagesize_version, + store both the page size and a version indicator. Beginning with + PostgreSQL 8.3 the version number is 4; + PostgreSQL 8.1 and 8.2 used version number 3; + PostgreSQL 8.0 used version number 2; + PostgreSQL 7.3 and 7.4 used version number 1; + prior releases used version number 0. + (The basic page layout and header format has not changed in most of these + versions, but the layout of heap row headers has.) The page size + is basically only present as a cross-check; there is no support for having + more than one page size in an installation. + The last field is a hint that shows whether pruning the page is likely + to be profitable: it tracks the oldest un-pruned XMAX on the page. + + + + + PageHeaderData Layout + PageHeaderData Layout + + + + Field + Type + Length + Description + + + + + pd_lsn + PageXLogRecPtr + 8 bytes + LSN: next byte after last byte of WAL record for last change + to this page + + + pd_checksum + uint16 + 2 bytes + Page checksum + + + pd_flags + uint16 + 2 bytes + Flag bits + + + pd_lower + LocationIndex + 2 bytes + Offset to start of free space + + + pd_upper + LocationIndex + 2 bytes + Offset to end of free space + + + pd_special + LocationIndex + 2 bytes + Offset to start of special space + + + pd_pagesize_version + uint16 + 2 bytes + Page size and layout version number information + + + pd_prune_xid + TransactionId + 4 bytes + Oldest unpruned XMAX on page, or zero if none + + + +
+ + + All the details can be found in + src/include/storage/bufpage.h. + + + + Following the page header are item identifiers + (ItemIdData), each requiring four bytes. + An item identifier contains a byte-offset to + the start of an item, its length in bytes, and a few attribute bits + which affect its interpretation. + New item identifiers are allocated + as needed from the beginning of the unallocated space. + The number of item identifiers present can be determined by looking at + pd_lower, which is increased to allocate a new identifier. + Because an item + identifier is never moved until it is freed, its index can be used on a + long-term basis to reference an item, even when the item itself is moved + around on the page to compact free space. In fact, every pointer to an + item (ItemPointer, also known as + CTID) created by + PostgreSQL consists of a page number and the + index of an item identifier. + + + + + + The items themselves are stored in space allocated backwards from the end + of unallocated space. The exact structure varies depending on what the + table is to contain. Tables and sequences both use a structure named + HeapTupleHeaderData, described below. + + + + + + The final section is the special section which can + contain anything the access method wishes to store. For example, + b-tree indexes store links to the page's left and right siblings, + as well as some other data relevant to the index structure. + Ordinary tables do not use a special section at all (indicated by setting + pd_special to equal the page size). + + + + + illustrates how these parts are + laid out in a page. + + +
+ Page Layout + + + + + +
+ + + + Table Row Layout + + + + All table rows are structured in the same way. There is a fixed-size + header (occupying 23 bytes on most machines), followed by an optional null + bitmap, an optional object ID field, and the user data. The header is + detailed + in . The actual user data + (columns of the row) begins at the offset indicated by + t_hoff, which must always be a multiple of the MAXALIGN + distance for the platform. + The null bitmap is + only present if the HEAP_HASNULL bit is set in + t_infomask. If it is present it begins just after + the fixed header and occupies enough bytes to have one bit per data column + (that is, the number of bits that equals the attribute count in + t_infomask2). In this list of bits, a + 1 bit indicates not-null, a 0 bit is a null. When the bitmap is not + present, all columns are assumed not-null. + The object ID is only present if the HEAP_HASOID_OLD bit + is set in t_infomask. If present, it appears just + before the t_hoff boundary. Any padding needed to make + t_hoff a MAXALIGN multiple will appear between the null + bitmap and the object ID. (This in turn ensures that the object ID is + suitably aligned.) + + + + + HeapTupleHeaderData Layout + HeapTupleHeaderData Layout + + + + Field + Type + Length + Description + + + + + t_xmin + TransactionId + 4 bytes + insert XID stamp + + + t_xmax + TransactionId + 4 bytes + delete XID stamp + + + t_cid + CommandId + 4 bytes + insert and/or delete CID stamp (overlays with t_xvac) + + + t_xvac + TransactionId + 4 bytes + XID for VACUUM operation moving a row version + + + t_ctid + ItemPointerData + 6 bytes + current TID of this or newer row version + + + t_infomask2 + uint16 + 2 bytes + number of attributes, plus various flag bits + + + t_infomask + uint16 + 2 bytes + various flag bits + + + t_hoff + uint8 + 1 byte + offset to user data + + + +
+ + + All the details can be found in + src/include/access/htup_details.h. + + + + + Interpreting the actual data can only be done with information obtained + from other tables, mostly pg_attribute. The + key values needed to identify field locations are + attlen and attalign. + There is no way to directly get a + particular attribute, except when there are only fixed width fields and no + null values. All this trickery is wrapped up in the functions + heap_getattr, fastgetattr + and heap_getsysattr. + + + + + To read the data you need to examine each attribute in turn. First check + whether the field is NULL according to the null bitmap. If it is, go to + the next. Then make sure you have the right alignment. If the field is a + fixed width field, then all the bytes are simply placed. If it's a + variable length field (attlen = -1) then it's a bit more complicated. + All variable-length data types share the common header structure + struct varlena, which includes the total length of the stored + value and some flag bits. Depending on the flags, the data can be either + inline or in a TOAST table; + it might be compressed, too (see ). + + +
+
+ +
diff --git a/doc/src/sgml/stylesheet.xsl b/doc/src/sgml/stylesheet.xsl new file mode 100644 index 000000000000..0eac594f0cc4 --- /dev/null +++ b/doc/src/sgml/stylesheet.xsl @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + + + + stylesheet.css + + https://www.postgresql.org/media/css/docs-complete.css + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml new file mode 100644 index 000000000000..d66560b587c6 --- /dev/null +++ b/doc/src/sgml/syntax.sgml @@ -0,0 +1,2737 @@ + + + + SQL Syntax + + + syntax + SQL + + + + This chapter describes the syntax of SQL. It forms the foundation + for understanding the following chapters which will go into detail + about how SQL commands are applied to define and modify data. + + + + We also advise users who are already familiar with SQL to read this + chapter carefully because it contains several rules and concepts that + are implemented inconsistently among SQL databases or that are + specific to PostgreSQL. + + + + Lexical Structure + + + token + + + + SQL input consists of a sequence of + commands. A command is composed of a + sequence of tokens, terminated by a + semicolon (;). The end of the input stream also + terminates a command. Which tokens are valid depends on the syntax + of the particular command. + + + + A token can be a key word, an + identifier, a quoted + identifier, a literal (or + constant), or a special character symbol. Tokens are normally + separated by whitespace (space, tab, newline), but need not be if + there is no ambiguity (which is generally only the case if a + special character is adjacent to some other token type). + + + + For example, the following is (syntactically) valid SQL input: + +SELECT * FROM MY_TABLE; +UPDATE MY_TABLE SET A = 5; +INSERT INTO MY_TABLE VALUES (3, 'hi there'); + + This is a sequence of three commands, one per line (although this + is not required; more than one command can be on a line, and + commands can usefully be split across lines). + + + + Additionally, comments can occur in SQL + input. They are not tokens, they are effectively equivalent to + whitespace. + + + + The SQL syntax is not very consistent regarding what tokens + identify commands and which are operands or parameters. The first + few tokens are generally the command name, so in the above example + we would usually speak of a SELECT, an + UPDATE, and an INSERT command. But + for instance the UPDATE command always requires + a SET token to appear in a certain position, and + this particular variation of INSERT also + requires a VALUES in order to be complete. The + precise syntax rules for each command are described in . + + + + Identifiers and Key Words + + + identifier + syntax of + + + + name + syntax of + + + + key word + syntax of + + + + Tokens such as SELECT, UPDATE, or + VALUES in the example above are examples of + key words, that is, words that have a fixed + meaning in the SQL language. The tokens MY_TABLE + and A are examples of + identifiers. They identify names of + tables, columns, or other database objects, depending on the + command they are used in. Therefore they are sometimes simply + called names. Key words and identifiers have the + same lexical structure, meaning that one cannot know whether a + token is an identifier or a key word without knowing the language. + A complete list of key words can be found in . + + + + SQL identifiers and key words must begin with a letter + (a-z, but also letters with + diacritical marks and non-Latin letters) or an underscore + (_). Subsequent characters in an identifier or + key word can be letters, underscores, digits + (0-9), or dollar signs + ($). Note that dollar signs are not allowed in identifiers + according to the letter of the SQL standard, so their use might render + applications less portable. + The SQL standard will not define a key word that contains + digits or starts or ends with an underscore, so identifiers of this + form are safe against possible conflict with future extensions of the + standard. + + + + identifierlength + The system uses no more than NAMEDATALEN-1 + bytes of an identifier; longer names can be written in + commands, but they will be truncated. By default, + NAMEDATALEN is 64 so the maximum identifier + length is 63 bytes. If this limit is problematic, it can be raised by + changing the NAMEDATALEN constant in + src/include/pg_config_manual.h. + + + + + case sensitivity + of SQL commands + + Key words and unquoted identifiers are case insensitive. Therefore: + +UPDATE MY_TABLE SET A = 5; + + can equivalently be written as: + +uPDaTE my_TabLE SeT a = 5; + + A convention often used is to write key words in upper + case and names in lower case, e.g.: + +UPDATE my_table SET a = 5; + + + + + + quotation marks + and identifiers + + There is a second kind of identifier: the delimited + identifier or quoted + identifier. It is formed by enclosing an arbitrary + sequence of characters in double-quotes + ("). A delimited + identifier is always an identifier, never a key word. So + "select" could be used to refer to a column or + table named select, whereas an unquoted + select would be taken as a key word and + would therefore provoke a parse error when used where a table or + column name is expected. The example can be written with quoted + identifiers like this: + +UPDATE "my_table" SET "a" = 5; + + + + + Quoted identifiers can contain any character, except the character + with code zero. (To include a double quote, write two double quotes.) + This allows constructing table or column names that would + otherwise not be possible, such as ones containing spaces or + ampersands. The length limitation still applies. + + + + Quoting an identifier also makes it case-sensitive, whereas + unquoted names are always folded to lower case. For example, the + identifiers FOO, foo, and + "foo" are considered the same by + PostgreSQL, but + "Foo" and "FOO" are + different from these three and each other. (The folding of + unquoted names to lower case in PostgreSQL is + incompatible with the SQL standard, which says that unquoted names + should be folded to upper case. Thus, foo + should be equivalent to "FOO" not + "foo" according to the standard. If you want + to write portable applications you are advised to always quote a + particular name or never quote it.) + + + + Unicode escape + in identifiers + + + + A variant of quoted + identifiers allows including escaped Unicode characters identified + by their code points. This variant starts + with U& (upper or lower case U followed by + ampersand) immediately before the opening double quote, without + any spaces in between, for example U&"foo". + (Note that this creates an ambiguity with the + operator &. Use spaces around the operator to + avoid this problem.) Inside the quotes, Unicode characters can be + specified in escaped form by writing a backslash followed by the + four-digit hexadecimal code point number or alternatively a + backslash followed by a plus sign followed by a six-digit + hexadecimal code point number. For example, the + identifier "data" could be written as + +U&"d\0061t\+000061" + + The following less trivial example writes the Russian + word slon (elephant) in Cyrillic letters: + +U&"\0441\043B\043E\043D" + + + + + If a different escape character than backslash is desired, it can + be specified using + the UESCAPEUESCAPE + clause after the string, for example: + +U&"d!0061t!+000061" UESCAPE '!' + + The escape character can be any single character other than a + hexadecimal digit, the plus sign, a single quote, a double quote, + or a whitespace character. Note that the escape character is + written in single quotes, not double quotes, + after UESCAPE. + + + + To include the escape character in the identifier literally, write + it twice. + + + + Either the 4-digit or the 6-digit escape form can be used to + specify UTF-16 surrogate pairs to compose characters with code + points larger than U+FFFF, although the availability of the + 6-digit form technically makes this unnecessary. (Surrogate + pairs are not stored directly, but are combined into a single + code point.) + + + + If the server encoding is not UTF-8, the Unicode code point identified + by one of these escape sequences is converted to the actual server + encoding; an error is reported if that's not possible. + + + + + + Constants + + + constant + + + + There are three kinds of implicitly-typed + constants in PostgreSQL: + strings, bit strings, and numbers. + Constants can also be specified with explicit types, which can + enable more accurate representation and more efficient handling by + the system. These alternatives are discussed in the following + subsections. + + + + String Constants + + + character string + constant + + + + + quotation marks + escaping + + A string constant in SQL is an arbitrary sequence of characters + bounded by single quotes ('), for example + 'This is a string'. To include + a single-quote character within a string constant, + write two adjacent single quotes, e.g., + 'Dianne''s horse'. + Note that this is not the same as a double-quote + character ("). + + + + Two string constants that are only separated by whitespace + with at least one newline are concatenated + and effectively treated as if the string had been written as one + constant. For example: + +SELECT 'foo' +'bar'; + + is equivalent to: + +SELECT 'foobar'; + + but: + +SELECT 'foo' 'bar'; + + is not valid syntax. (This slightly bizarre behavior is specified + by SQL; PostgreSQL is + following the standard.) + + + + + String Constants with C-Style Escapes + + + escape string syntax + + + backslash escapes + + + + PostgreSQL also accepts escape + string constants, which are an extension to the SQL standard. + An escape string constant is specified by writing the letter + E (upper or lower case) just before the opening single + quote, e.g., E'foo'. (When continuing an escape string + constant across lines, write E only before the first opening + quote.) + Within an escape string, a backslash character (\) begins a + C-like backslash escape sequence, in which the combination + of backslash and following character(s) represent a special byte + value, as shown in . + + + + Backslash Escape Sequences + + + + Backslash Escape Sequence + Interpretation + + + + + + \b + backspace + + + \f + form feed + + + \n + newline + + + \r + carriage return + + + \t + tab + + + + \o, + \oo, + \ooo + (o = 0–7) + + octal byte value + + + + \xh, + \xhh + (h = 0–9, A–F) + + hexadecimal byte value + + + + \uxxxx, + \Uxxxxxxxx + (x = 0–9, A–F) + + 16 or 32-bit hexadecimal Unicode character value + + + +
+ + + Any other + character following a backslash is taken literally. Thus, to + include a backslash character, write two backslashes (\\). + Also, a single quote can be included in an escape string by writing + \', in addition to the normal way of ''. + + + + It is your responsibility that the byte sequences you create, + especially when using the octal or hexadecimal escapes, compose + valid characters in the server character set encoding. + A useful alternative is to use Unicode escapes or the + alternative Unicode escape syntax, explained + in ; then the server + will check that the character conversion is possible. + + + + + If the configuration parameter + is off, + then PostgreSQL recognizes backslash escapes + in both regular and escape string constants. However, as of + PostgreSQL 9.1, the default is on, meaning + that backslash escapes are recognized only in escape string constants. + This behavior is more standards-compliant, but might break applications + which rely on the historical behavior, where backslash escapes + were always recognized. As a workaround, you can set this parameter + to off, but it is better to migrate away from using backslash + escapes. If you need to use a backslash escape to represent a special + character, write the string constant with an E. + + + + In addition to standard_conforming_strings, the configuration + parameters and + govern treatment of backslashes + in string constants. + + + + + The character with the code zero cannot be in a string constant. + +
+ + + String Constants with Unicode Escapes + + + Unicode escape + in string constants + + + + PostgreSQL also supports another type + of escape syntax for strings that allows specifying arbitrary + Unicode characters by code point. A Unicode escape string + constant starts with U& (upper or lower case + letter U followed by ampersand) immediately before the opening + quote, without any spaces in between, for + example U&'foo'. (Note that this creates an + ambiguity with the operator &. Use spaces + around the operator to avoid this problem.) Inside the quotes, + Unicode characters can be specified in escaped form by writing a + backslash followed by the four-digit hexadecimal code point + number or alternatively a backslash followed by a plus sign + followed by a six-digit hexadecimal code point number. For + example, the string 'data' could be written as + +U&'d\0061t\+000061' + + The following less trivial example writes the Russian + word slon (elephant) in Cyrillic letters: + +U&'\0441\043B\043E\043D' + + + + + If a different escape character than backslash is desired, it can + be specified using + the UESCAPEUESCAPE + clause after the string, for example: + +U&'d!0061t!+000061' UESCAPE '!' + + The escape character can be any single character other than a + hexadecimal digit, the plus sign, a single quote, a double quote, + or a whitespace character. + + + + To include the escape character in the string literally, write + it twice. + + + + Either the 4-digit or the 6-digit escape form can be used to + specify UTF-16 surrogate pairs to compose characters with code + points larger than U+FFFF, although the availability of the + 6-digit form technically makes this unnecessary. (Surrogate + pairs are not stored directly, but are combined into a single + code point.) + + + + If the server encoding is not UTF-8, the Unicode code point identified + by one of these escape sequences is converted to the actual server + encoding; an error is reported if that's not possible. + + + + Also, the Unicode escape syntax for string constants only works + when the configuration + parameter is + turned on. This is because otherwise this syntax could confuse + clients that parse the SQL statements to the point that it could + lead to SQL injections and similar security issues. If the + parameter is set to off, this syntax will be rejected with an + error message. + + + + + Dollar-Quoted String Constants + + + dollar quoting + + + + While the standard syntax for specifying string constants is usually + convenient, it can be difficult to understand when the desired string + contains many single quotes or backslashes, since each of those must + be doubled. To allow more readable queries in such situations, + PostgreSQL provides another way, called + dollar quoting, to write string constants. + A dollar-quoted string constant + consists of a dollar sign ($), an optional + tag of zero or more characters, another dollar + sign, an arbitrary sequence of characters that makes up the + string content, a dollar sign, the same tag that began this + dollar quote, and a dollar sign. For example, here are two + different ways to specify the string Dianne's horse + using dollar quoting: + +$$Dianne's horse$$ +$SomeTag$Dianne's horse$SomeTag$ + + Notice that inside the dollar-quoted string, single quotes can be + used without needing to be escaped. Indeed, no characters inside + a dollar-quoted string are ever escaped: the string content is always + written literally. Backslashes are not special, and neither are + dollar signs, unless they are part of a sequence matching the opening + tag. + + + + It is possible to nest dollar-quoted string constants by choosing + different tags at each nesting level. This is most commonly used in + writing function definitions. For example: + +$function$ +BEGIN + RETURN ($1 ~ $q$[\t\r\n\v\\]$q$); +END; +$function$ + + Here, the sequence $q$[\t\r\n\v\\]$q$ represents a + dollar-quoted literal string [\t\r\n\v\\], which will + be recognized when the function body is executed by + PostgreSQL. But since the sequence does not match + the outer dollar quoting delimiter $function$, it is + just some more characters within the constant so far as the outer + string is concerned. + + + + The tag, if any, of a dollar-quoted string follows the same rules + as an unquoted identifier, except that it cannot contain a dollar sign. + Tags are case sensitive, so $tag$String content$tag$ + is correct, but $TAG$String content$tag$ is not. + + + + A dollar-quoted string that follows a keyword or identifier must + be separated from it by whitespace; otherwise the dollar quoting + delimiter would be taken as part of the preceding identifier. + + + + Dollar quoting is not part of the SQL standard, but it is often a more + convenient way to write complicated string literals than the + standard-compliant single quote syntax. It is particularly useful when + representing string constants inside other constants, as is often needed + in procedural function definitions. With single-quote syntax, each + backslash in the above example would have to be written as four + backslashes, which would be reduced to two backslashes in parsing the + original string constant, and then to one when the inner string constant + is re-parsed during function execution. + + + + + Bit-String Constants + + + bit string + constant + + + + Bit-string constants look like regular string constants with a + B (upper or lower case) immediately before the + opening quote (no intervening whitespace), e.g., + B'1001'. The only characters allowed within + bit-string constants are 0 and + 1. + + + + Alternatively, bit-string constants can be specified in hexadecimal + notation, using a leading X (upper or lower case), + e.g., X'1FF'. This notation is equivalent to + a bit-string constant with four binary digits for each hexadecimal digit. + + + + Both forms of bit-string constant can be continued + across lines in the same way as regular string constants. + Dollar quoting cannot be used in a bit-string constant. + + + + + Numeric Constants + + + number + constant + + + + Numeric constants are accepted in these general forms: + +digits +digits.digitse+-digits +digits.digitse+-digits +digitse+-digits + + where digits is one or more decimal + digits (0 through 9). At least one digit must be before or after the + decimal point, if one is used. At least one digit must follow the + exponent marker (e), if one is present. + There cannot be any spaces or other characters embedded in the + constant. Note that any leading plus or minus sign is not actually + considered part of the constant; it is an operator applied to the + constant. + + + + These are some examples of valid numeric constants: + +42 +3.5 +4. +.001 +5e2 +1.925e-3 + + + + + integer + bigint + numeric + A numeric constant that contains neither a decimal point nor an + exponent is initially presumed to be type integer if its + value fits in type integer (32 bits); otherwise it is + presumed to be type bigint if its + value fits in type bigint (64 bits); otherwise it is + taken to be type numeric. Constants that contain decimal + points and/or exponents are always initially presumed to be type + numeric. + + + + The initially assigned data type of a numeric constant is just a + starting point for the type resolution algorithms. In most cases + the constant will be automatically coerced to the most + appropriate type depending on context. When necessary, you can + force a numeric value to be interpreted as a specific data type + by casting it.type cast + For example, you can force a numeric value to be treated as type + real (float4) by writing: + + +REAL '1.23' -- string style +1.23::REAL -- PostgreSQL (historical) style + + + These are actually just special cases of the general casting + notations discussed next. + + + + + Constants of Other Types + + + data type + constant + + + + A constant of an arbitrary type can be + entered using any one of the following notations: + +type 'string' +'string'::type +CAST ( 'string' AS type ) + + The string constant's text is passed to the input conversion + routine for the type called type. The + result is a constant of the indicated type. The explicit type + cast can be omitted if there is no ambiguity as to the type the + constant must be (for example, when it is assigned directly to a + table column), in which case it is automatically coerced. + + + + The string constant can be written using either regular SQL + notation or dollar-quoting. + + + + It is also possible to specify a type coercion using a function-like + syntax: + +typename ( 'string' ) + + but not all type names can be used in this way; see for details. + + + + The ::, CAST(), and + function-call syntaxes can also be used to specify run-time type + conversions of arbitrary expressions, as discussed in . To avoid syntactic ambiguity, the + type 'string' + syntax can only be used to specify the type of a simple literal constant. + Another restriction on the + type 'string' + syntax is that it does not work for array types; use :: + or CAST() to specify the type of an array constant. + + + + The CAST() syntax conforms to SQL. The + type 'string' + syntax is a generalization of the standard: SQL specifies this syntax only + for a few data types, but PostgreSQL allows it + for all types. The syntax with + :: is historical PostgreSQL + usage, as is the function-call syntax. + + +
+ + + Operators + + + operator + syntax + + + + An operator name is a sequence of up to NAMEDATALEN-1 + (63 by default) characters from the following list: + ++ - * / < > = ~ ! @ # % ^ & | ` ? + + + There are a few restrictions on operator names, however: + + + + -- and /* cannot appear + anywhere in an operator name, since they will be taken as the + start of a comment. + + + + + + A multiple-character operator name cannot end in + or -, + unless the name also contains at least one of these characters: + +~ ! @ # % ^ & | ` ? + + For example, @- is an allowed operator name, + but *- is not. This restriction allows + PostgreSQL to parse SQL-compliant + queries without requiring spaces between tokens. + + + + + + + When working with non-SQL-standard operator names, you will usually + need to separate adjacent operators with spaces to avoid ambiguity. + For example, if you have defined a prefix operator named @, + you cannot write X*@Y; you must write + X* @Y to ensure that + PostgreSQL reads it as two operator names + not one. + + + + + Special Characters + + + Some characters that are not alphanumeric have a special meaning + that is different from being an operator. Details on the usage can + be found at the location where the respective syntax element is + described. This section only exists to advise the existence and + summarize the purposes of these characters. + + + + + A dollar sign ($) followed by digits is used + to represent a positional parameter in the body of a function + definition or a prepared statement. In other contexts the + dollar sign can be part of an identifier or a dollar-quoted string + constant. + + + + + + Parentheses (()) have their usual meaning to + group expressions and enforce precedence. In some cases + parentheses are required as part of the fixed syntax of a + particular SQL command. + + + + + + Brackets ([]) are used to select the elements + of an array. See for more information + on arrays. + + + + + + Commas (,) are used in some syntactical + constructs to separate the elements of a list. + + + + + + The semicolon (;) terminates an SQL command. + It cannot appear anywhere within a command, except within a + string constant or quoted identifier. + + + + + + The colon (:) is used to select + slices from arrays. (See .) In certain SQL dialects (such as Embedded + SQL), the colon is used to prefix variable names. + + + + + + The asterisk (*) is used in some contexts to denote + all the fields of a table row or composite value. It also + has a special meaning when used as the argument of an + aggregate function, namely that the aggregate does not require + any explicit parameter. + + + + + + The period (.) is used in numeric + constants, and to separate schema, table, and column names. + + + + + + + + + Comments + + + comment + in SQL + + + + A comment is a sequence of characters beginning with + double dashes and extending to the end of the line, e.g.: + +-- This is a standard SQL comment + + + + + Alternatively, C-style block comments can be used: + +/* multiline comment + * with nesting: /* nested block comment */ + */ + + where the comment begins with /* and extends to + the matching occurrence of */. These block + comments nest, as specified in the SQL standard but unlike C, so that one can + comment out larger blocks of code that might contain existing block + comments. + + + + A comment is removed from the input stream before further syntax + analysis and is effectively replaced by whitespace. + + + + + Operator Precedence + + + operator + precedence + + + + shows the precedence and + associativity of the operators in PostgreSQL. + Most operators have the same precedence and are left-associative. + The precedence and associativity of the operators is hard-wired + into the parser. + Add parentheses if you want an expression with multiple operators + to be parsed in some other way than what the precedence rules imply. + + + + Operator Precedence (highest to lowest) + + + + + + + + Operator/Element + Associativity + Description + + + + + + . + left + table/column name separator + + + + :: + left + PostgreSQL-style typecast + + + + [ ] + left + array element selection + + + + + - + right + unary plus, unary minus + + + + ^ + left + exponentiation + + + + * / % + left + multiplication, division, modulo + + + + + - + left + addition, subtraction + + + + (any other operator) + left + all other native and user-defined operators + + + + BETWEEN IN LIKE ILIKE SIMILAR + + range containment, set membership, string matching + + + + < > = <= >= <> + + + comparison operators + + + + IS ISNULL NOTNULL + + IS TRUE, IS FALSE, IS + NULL, IS DISTINCT FROM, etc + + + + NOT + right + logical negation + + + + AND + left + logical conjunction + + + + OR + left + logical disjunction + + + +
+ + + Note that the operator precedence rules also apply to user-defined + operators that have the same names as the built-in operators + mentioned above. For example, if you define a + + operator for some custom data type it will have + the same precedence as the built-in + operator, no + matter what yours does. + + + + When a schema-qualified operator name is used in the + OPERATOR syntax, as for example in: + +SELECT 3 OPERATOR(pg_catalog.+) 4; + + the OPERATOR construct is taken to have the default precedence + shown in for + any other operator. This is true no matter + which specific operator appears inside OPERATOR(). + + + + + PostgreSQL versions before 9.5 used slightly different + operator precedence rules. In particular, <= + >= and <> used to be treated as + generic operators; IS tests used to have higher priority; + and NOT BETWEEN and related constructs acted inconsistently, + being taken in some cases as having the precedence of NOT + rather than BETWEEN. These rules were changed for better + compliance with the SQL standard and to reduce confusion from + inconsistent treatment of logically equivalent constructs. In most + cases, these changes will result in no behavioral change, or perhaps + in no such operator failures which can be resolved by adding + parentheses. However there are corner cases in which a query might + change behavior without any parsing error being reported. + + +
+
+ + + Value Expressions + + + expression + syntax + + + + value expression + + + + scalar + expression + + + + Value expressions are used in a variety of contexts, such + as in the target list of the SELECT command, as + new column values in INSERT or + UPDATE, or in search conditions in a number of + commands. The result of a value expression is sometimes called a + scalar, to distinguish it from the result of + a table expression (which is a table). Value expressions are + therefore also called scalar expressions (or + even simply expressions). The expression + syntax allows the calculation of values from primitive parts using + arithmetic, logical, set, and other operations. + + + + A value expression is one of the following: + + + + + A constant or literal value + + + + + + A column reference + + + + + + A positional parameter reference, in the body of a function definition + or prepared statement + + + + + + A subscripted expression + + + + + + A field selection expression + + + + + + An operator invocation + + + + + + A function call + + + + + + An aggregate expression + + + + + + A window function call + + + + + + A type cast + + + + + + A collation expression + + + + + + A scalar subquery + + + + + + An array constructor + + + + + + A row constructor + + + + + + Another value expression in parentheses (used to group + subexpressions and override + precedenceparenthesis) + + + + + + + In addition to this list, there are a number of constructs that can + be classified as an expression but do not follow any general syntax + rules. These generally have the semantics of a function or + operator and are explained in the appropriate location in . An example is the IS NULL + clause. + + + + We have already discussed constants in . The following sections discuss + the remaining options. + + + + Column References + + + column reference + + + + A column can be referenced in the form: + +correlation.columnname + + + + + correlation is the name of a + table (possibly qualified with a schema name), or an alias for a table + defined by means of a FROM clause. + The correlation name and separating dot can be omitted if the column name + is unique across all the tables being used in the current query. (See also .) + + + + + Positional Parameters + + + parameter + syntax + + + + $ + + + + A positional parameter reference is used to indicate a value + that is supplied externally to an SQL statement. Parameters are + used in SQL function definitions and in prepared queries. Some + client libraries also support specifying data values separately + from the SQL command string, in which case parameters are used to + refer to the out-of-line data values. + The form of a parameter reference is: + +$number + + + + + For example, consider the definition of a function, + dept, as: + + +CREATE FUNCTION dept(text) RETURNS dept + AS $$ SELECT * FROM dept WHERE name = $1 $$ + LANGUAGE SQL; + + + Here the $1 references the value of the first + function argument whenever the function is invoked. + + + + + Subscripts + + + subscript + + + + If an expression yields a value of an array type, then a specific + element of the array value can be extracted by writing + +expression[subscript] + + or multiple adjacent elements (an array slice) can be extracted + by writing + +expression[lower_subscript:upper_subscript] + + (Here, the brackets [ ] are meant to appear literally.) + Each subscript is itself an expression, + which will be rounded to the nearest integer value. + + + + In general the array expression must be + parenthesized, but the parentheses can be omitted when the expression + to be subscripted is just a column reference or positional parameter. + Also, multiple subscripts can be concatenated when the original array + is multidimensional. + For example: + + +mytable.arraycolumn[4] +mytable.two_d_column[17][34] +$1[10:42] +(arrayfunction(a,b))[42] + + + The parentheses in the last example are required. + See for more about arrays. + + + + + Field Selection + + + field selection + + + + If an expression yields a value of a composite type (row type), then a + specific field of the row can be extracted by writing + +expression.fieldname + + + + + In general the row expression must be + parenthesized, but the parentheses can be omitted when the expression + to be selected from is just a table reference or positional parameter. + For example: + + +mytable.mycolumn +$1.somecolumn +(rowfunction(a,b)).col3 + + + (Thus, a qualified column reference is actually just a special case + of the field selection syntax.) An important special case is + extracting a field from a table column that is of a composite type: + + +(compositecol).somefield +(mytable.compositecol).somefield + + + The parentheses are required here to show that + compositecol is a column name not a table name, + or that mytable is a table name not a schema name + in the second case. + + + + You can ask for all fields of a composite value by + writing .*: + +(compositecol).* + + This notation behaves differently depending on context; + see for details. + + + + + Operator Invocations + + + operator + invocation + + + + There are two possible syntaxes for an operator invocation: + + expression operator expression (binary infix operator) + operator expression (unary prefix operator) + + where the operator token follows the syntax + rules of , or is one of the + key words AND, OR, and + NOT, or is a qualified operator name in the form: + +OPERATOR(schema.operatorname) + + Which particular operators exist and whether + they are unary or binary depends on what operators have been + defined by the system or the user. + describes the built-in operators. + + + + + Function Calls + + + function + invocation + + + + The syntax for a function call is the name of a function + (possibly qualified with a schema name), followed by its argument list + enclosed in parentheses: + + +function_name (expression , expression ... ) + + + + + For example, the following computes the square root of 2: + +sqrt(2) + + + + + The list of built-in functions is in . + Other functions can be added by the user. + + + + When issuing queries in a database where some users mistrust other users, + observe security precautions from when + writing function calls. + + + + The arguments can optionally have names attached. + See for details. + + + + + A function that takes a single argument of composite type can + optionally be called using field-selection syntax, and conversely + field selection can be written in functional style. That is, the + notations col(table) and table.col are + interchangeable. This behavior is not SQL-standard but is provided + in PostgreSQL because it allows use of functions to + emulate computed fields. For more information see + . + + + + + + Aggregate Expressions + + + aggregate function + invocation + + + + ordered-set aggregate + + + + WITHIN GROUP + + + + FILTER + + + + An aggregate expression represents the + application of an aggregate function across the rows selected by a + query. An aggregate function reduces multiple inputs to a single + output value, such as the sum or average of the inputs. The + syntax of an aggregate expression is one of the following: + + +aggregate_name (expression [ , ... ] [ order_by_clause ] ) [ FILTER ( WHERE filter_clause ) ] +aggregate_name (ALL expression [ , ... ] [ order_by_clause ] ) [ FILTER ( WHERE filter_clause ) ] +aggregate_name (DISTINCT expression [ , ... ] [ order_by_clause ] ) [ FILTER ( WHERE filter_clause ) ] +aggregate_name ( * ) [ FILTER ( WHERE filter_clause ) ] +aggregate_name ( [ expression [ , ... ] ] ) WITHIN GROUP ( order_by_clause ) [ FILTER ( WHERE filter_clause ) ] + + + where aggregate_name is a previously + defined aggregate (possibly qualified with a schema name) and + expression is + any value expression that does not itself contain an aggregate + expression or a window function call. The optional + order_by_clause and + filter_clause are described below. + + + + The first form of aggregate expression invokes the aggregate + once for each input row. + The second form is the same as the first, since + ALL is the default. + The third form invokes the aggregate once for each distinct value + of the expression (or distinct set of values, for multiple expressions) + found in the input rows. + The fourth form invokes the aggregate once for each input row; since no + particular input value is specified, it is generally only useful + for the count(*) aggregate function. + The last form is used with ordered-set aggregate + functions, which are described below. + + + + Most aggregate functions ignore null inputs, so that rows in which + one or more of the expression(s) yield null are discarded. This + can be assumed to be true, unless otherwise specified, for all + built-in aggregates. + + + + For example, count(*) yields the total number + of input rows; count(f1) yields the number of + input rows in which f1 is non-null, since + count ignores nulls; and + count(distinct f1) yields the number of + distinct non-null values of f1. + + + + Ordinarily, the input rows are fed to the aggregate function in an + unspecified order. In many cases this does not matter; for example, + min produces the same result no matter what order it + receives the inputs in. However, some aggregate functions + (such as array_agg and string_agg) produce + results that depend on the ordering of the input rows. When using + such an aggregate, the optional order_by_clause can be + used to specify the desired ordering. The order_by_clause + has the same syntax as for a query-level ORDER BY clause, as + described in , except that its expressions + are always just expressions and cannot be output-column names or numbers. + For example: + +SELECT array_agg(a ORDER BY b DESC) FROM table; + + + + + When dealing with multiple-argument aggregate functions, note that the + ORDER BY clause goes after all the aggregate arguments. + For example, write this: + +SELECT string_agg(a, ',' ORDER BY a) FROM table; + + not this: + +SELECT string_agg(a ORDER BY a, ',') FROM table; -- incorrect + + The latter is syntactically valid, but it represents a call of a + single-argument aggregate function with two ORDER BY keys + (the second one being rather useless since it's a constant). + + + + If DISTINCT is specified in addition to an + order_by_clause, then all the ORDER BY + expressions must match regular arguments of the aggregate; that is, + you cannot sort on an expression that is not included in the + DISTINCT list. + + + + + The ability to specify both DISTINCT and ORDER BY + in an aggregate function is a PostgreSQL extension. + + + + + Placing ORDER BY within the aggregate's regular argument + list, as described so far, is used when ordering the input rows for + general-purpose and statistical aggregates, for which ordering is + optional. There is a + subclass of aggregate functions called ordered-set + aggregates for which an order_by_clause + is required, usually because the aggregate's computation is + only sensible in terms of a specific ordering of its input rows. + Typical examples of ordered-set aggregates include rank and percentile + calculations. For an ordered-set aggregate, + the order_by_clause is written + inside WITHIN GROUP (...), as shown in the final syntax + alternative above. The expressions in + the order_by_clause are evaluated once per + input row just like regular aggregate arguments, sorted as per + the order_by_clause's requirements, and fed + to the aggregate function as input arguments. (This is unlike the case + for a non-WITHIN GROUP order_by_clause, + which is not treated as argument(s) to the aggregate function.) The + argument expressions preceding WITHIN GROUP, if any, are + called direct arguments to distinguish them from + the aggregated arguments listed in + the order_by_clause. Unlike regular aggregate + arguments, direct arguments are evaluated only once per aggregate call, + not once per input row. This means that they can contain variables only + if those variables are grouped by GROUP BY; this restriction + is the same as if the direct arguments were not inside an aggregate + expression at all. Direct arguments are typically used for things like + percentile fractions, which only make sense as a single value per + aggregation calculation. The direct argument list can be empty; in this + case, write just () not (*). + (PostgreSQL will actually accept either spelling, but + only the first way conforms to the SQL standard.) + + + + + median + percentile + + An example of an ordered-set aggregate call is: + + +SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY income) FROM households; + percentile_cont +----------------- + 50489 + + + which obtains the 50th percentile, or median, value of + the income column from table households. + Here, 0.5 is a direct argument; it would make no sense + for the percentile fraction to be a value varying across rows. + + + + If FILTER is specified, then only the input + rows for which the filter_clause + evaluates to true are fed to the aggregate function; other rows + are discarded. For example: + +SELECT + count(*) AS unfiltered, + count(*) FILTER (WHERE i < 5) AS filtered +FROM generate_series(1,10) AS s(i); + unfiltered | filtered +------------+---------- + 10 | 4 +(1 row) + + + + + The predefined aggregate functions are described in . Other aggregate functions can be added + by the user. + + + + An aggregate expression can only appear in the result list or + HAVING clause of a SELECT command. + It is forbidden in other clauses, such as WHERE, + because those clauses are logically evaluated before the results + of aggregates are formed. + + + + When an aggregate expression appears in a subquery (see + and + ), the aggregate is normally + evaluated over the rows of the subquery. But an exception occurs + if the aggregate's arguments (and filter_clause + if any) contain only outer-level variables: + the aggregate then belongs to the nearest such outer level, and is + evaluated over the rows of that query. The aggregate expression + as a whole is then an outer reference for the subquery it appears in, + and acts as a constant over any one evaluation of that subquery. + The restriction about + appearing only in the result list or HAVING clause + applies with respect to the query level that the aggregate belongs to. + + + + + Window Function Calls + + + window function + invocation + + + + OVER clause + + + + A window function call represents the application + of an aggregate-like function over some portion of the rows selected + by a query. Unlike non-window aggregate calls, this is not tied + to grouping of the selected rows into a single output row — each + row remains separate in the query output. However the window function + has access to all the rows that would be part of the current row's + group according to the grouping specification (PARTITION BY + list) of the window function call. + The syntax of a window function call is one of the following: + + +function_name (expression , expression ... ) [ FILTER ( WHERE filter_clause ) ] OVER window_name +function_name (expression , expression ... ) [ FILTER ( WHERE filter_clause ) ] OVER ( window_definition ) +function_name ( * ) [ FILTER ( WHERE filter_clause ) ] OVER window_name +function_name ( * ) [ FILTER ( WHERE filter_clause ) ] OVER ( window_definition ) + + where window_definition + has the syntax + +[ existing_window_name ] +[ PARTITION BY expression [, ...] ] +[ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] +[ frame_clause ] + + The optional frame_clause + can be one of + +{ RANGE | ROWS | GROUPS } frame_start [ frame_exclusion ] +{ RANGE | ROWS | GROUPS } BETWEEN frame_start AND frame_end [ frame_exclusion ] + + where frame_start + and frame_end can be one of + +UNBOUNDED PRECEDING +offset PRECEDING +CURRENT ROW +offset FOLLOWING +UNBOUNDED FOLLOWING + + and frame_exclusion can be one of + +EXCLUDE CURRENT ROW +EXCLUDE GROUP +EXCLUDE TIES +EXCLUDE NO OTHERS + + + + + Here, expression represents any value + expression that does not itself contain window function calls. + + + + window_name is a reference to a named window + specification defined in the query's WINDOW clause. + Alternatively, a full window_definition can + be given within parentheses, using the same syntax as for defining a + named window in the WINDOW clause; see the + reference page for details. It's worth + pointing out that OVER wname is not exactly equivalent to + OVER (wname ...); the latter implies copying and modifying the + window definition, and will be rejected if the referenced window + specification includes a frame clause. + + + + The PARTITION BY clause groups the rows of the query into + partitions, which are processed separately by the window + function. PARTITION BY works similarly to a query-level + GROUP BY clause, except that its expressions are always just + expressions and cannot be output-column names or numbers. + Without PARTITION BY, all rows produced by the query are + treated as a single partition. + The ORDER BY clause determines the order in which the rows + of a partition are processed by the window function. It works similarly + to a query-level ORDER BY clause, but likewise cannot use + output-column names or numbers. Without ORDER BY, rows are + processed in an unspecified order. + + + + The frame_clause specifies + the set of rows constituting the window frame, which is a + subset of the current partition, for those window functions that act on + the frame instead of the whole partition. The set of rows in the frame + can vary depending on which row is the current row. The frame can be + specified in RANGE, ROWS + or GROUPS mode; in each case, it runs from + the frame_start to + the frame_end. + If frame_end is omitted, the end defaults + to CURRENT ROW. + + + + A frame_start of UNBOUNDED PRECEDING means + that the frame starts with the first row of the partition, and similarly + a frame_end of UNBOUNDED FOLLOWING means + that the frame ends with the last row of the partition. + + + + In RANGE or GROUPS mode, + a frame_start of + CURRENT ROW means the frame starts with the current + row's first peer row (a row that the + window's ORDER BY clause sorts as equivalent to the + current row), while a frame_end of + CURRENT ROW means the frame ends with the current + row's last peer row. + In ROWS mode, CURRENT ROW simply + means the current row. + + + + In the offset PRECEDING + and offset FOLLOWING frame + options, the offset must be an expression not + containing any variables, aggregate functions, or window functions. + The meaning of the offset depends on the + frame mode: + + + + In ROWS mode, + the offset must yield a non-null, + non-negative integer, and the option means that the frame starts or + ends the specified number of rows before or after the current row. + + + + + In GROUPS mode, + the offset again must yield a non-null, + non-negative integer, and the option means that the frame starts or + ends the specified number of peer groups + before or after the current row's peer group, where a peer group is a + set of rows that are equivalent in the ORDER BY + ordering. (There must be an ORDER BY clause + in the window definition to use GROUPS mode.) + + + + + In RANGE mode, these options require that + the ORDER BY clause specify exactly one column. + The offset specifies the maximum + difference between the value of that column in the current row and + its value in preceding or following rows of the frame. The data type + of the offset expression varies depending + on the data type of the ordering column. For numeric ordering + columns it is typically of the same type as the ordering column, + but for datetime ordering columns it is an interval. + For example, if the ordering column is of type date + or timestamp, one could write RANGE BETWEEN + '1 day' PRECEDING AND '10 days' FOLLOWING. + The offset is still required to be + non-null and non-negative, though the meaning + of non-negative depends on its data type. + + + + In any case, the distance to the end of the frame is limited by the + distance to the end of the partition, so that for rows near the partition + ends the frame might contain fewer rows than elsewhere. + + + + Notice that in both ROWS and GROUPS + mode, 0 PRECEDING and 0 FOLLOWING + are equivalent to CURRENT ROW. This normally holds + in RANGE mode as well, for an appropriate + data-type-specific meaning of zero. + + + + The frame_exclusion option allows rows around + the current row to be excluded from the frame, even if they would be + included according to the frame start and frame end options. + EXCLUDE CURRENT ROW excludes the current row from the + frame. + EXCLUDE GROUP excludes the current row and its + ordering peers from the frame. + EXCLUDE TIES excludes any peers of the current + row from the frame, but not the current row itself. + EXCLUDE NO OTHERS simply specifies explicitly the + default behavior of not excluding the current row or its peers. + + + + The default framing option is RANGE UNBOUNDED PRECEDING, + which is the same as RANGE BETWEEN UNBOUNDED PRECEDING AND + CURRENT ROW. With ORDER BY, this sets the frame to be + all rows from the partition start up through the current row's last + ORDER BY peer. Without ORDER BY, + this means all rows of the partition are included in the window frame, + since all rows become peers of the current row. + + + + Restrictions are that + frame_start cannot be UNBOUNDED FOLLOWING, + frame_end cannot be UNBOUNDED PRECEDING, + and the frame_end choice cannot appear earlier in the + above list of frame_start + and frame_end options than + the frame_start choice does — for example + RANGE BETWEEN CURRENT ROW AND offset + PRECEDING is not allowed. + But, for example, ROWS BETWEEN 7 PRECEDING AND 8 + PRECEDING is allowed, even though it would never select any + rows. + + + + If FILTER is specified, then only the input + rows for which the filter_clause + evaluates to true are fed to the window function; other rows + are discarded. Only window functions that are aggregates accept + a FILTER clause. + + + + The built-in window functions are described in . Other window functions can be added by + the user. Also, any built-in or user-defined general-purpose or + statistical aggregate can be used as a window function. (Ordered-set + and hypothetical-set aggregates cannot presently be used as window functions.) + + + + The syntaxes using * are used for calling parameter-less + aggregate functions as window functions, for example + count(*) OVER (PARTITION BY x ORDER BY y). + The asterisk (*) is customarily not used for + window-specific functions. Window-specific functions do not + allow DISTINCT or ORDER BY to be used within the + function argument list. + + + + Window function calls are permitted only in the SELECT + list and the ORDER BY clause of the query. + + + + More information about window functions can be found in + , + , and + . + + + + + Type Casts + + + data type + type cast + + + + type cast + + + + :: + + + + A type cast specifies a conversion from one data type to another. + PostgreSQL accepts two equivalent syntaxes + for type casts: + +CAST ( expression AS type ) +expression::type + + The CAST syntax conforms to SQL; the syntax with + :: is historical PostgreSQL + usage. + + + + When a cast is applied to a value expression of a known type, it + represents a run-time type conversion. The cast will succeed only + if a suitable type conversion operation has been defined. Notice that this + is subtly different from the use of casts with constants, as shown in + . A cast applied to an + unadorned string literal represents the initial assignment of a type + to a literal constant value, and so it will succeed for any type + (if the contents of the string literal are acceptable input syntax for the + data type). + + + + An explicit type cast can usually be omitted if there is no ambiguity as + to the type that a value expression must produce (for example, when it is + assigned to a table column); the system will automatically apply a + type cast in such cases. However, automatic casting is only done for + casts that are marked OK to apply implicitly + in the system catalogs. Other casts must be invoked with + explicit casting syntax. This restriction is intended to prevent + surprising conversions from being applied silently. + + + + It is also possible to specify a type cast using a function-like + syntax: + +typename ( expression ) + + However, this only works for types whose names are also valid as + function names. For example, double precision + cannot be used this way, but the equivalent float8 + can. Also, the names interval, time, and + timestamp can only be used in this fashion if they are + double-quoted, because of syntactic conflicts. Therefore, the use of + the function-like cast syntax leads to inconsistencies and should + probably be avoided. + + + + + The function-like syntax is in fact just a function call. When + one of the two standard cast syntaxes is used to do a run-time + conversion, it will internally invoke a registered function to + perform the conversion. By convention, these conversion functions + have the same name as their output type, and thus the function-like + syntax is nothing more than a direct invocation of the underlying + conversion function. Obviously, this is not something that a portable + application should rely on. For further details see + . + + + + + + Collation Expressions + + + COLLATE + + + + The COLLATE clause overrides the collation of + an expression. It is appended to the expression it applies to: + +expr COLLATE collation + + where collation is a possibly + schema-qualified identifier. The COLLATE + clause binds tighter than operators; parentheses can be used when + necessary. + + + + If no collation is explicitly specified, the database system + either derives a collation from the columns involved in the + expression, or it defaults to the default collation of the + database if no column is involved in the expression. + + + + The two common uses of the COLLATE clause are + overriding the sort order in an ORDER BY clause, for + example: + +SELECT a, b, c FROM tbl WHERE ... ORDER BY a COLLATE "C"; + + and overriding the collation of a function or operator call that + has locale-sensitive results, for example: + +SELECT * FROM tbl WHERE a > 'foo' COLLATE "C"; + + Note that in the latter case the COLLATE clause is + attached to an input argument of the operator we wish to affect. + It doesn't matter which argument of the operator or function call the + COLLATE clause is attached to, because the collation that is + applied by the operator or function is derived by considering all + arguments, and an explicit COLLATE clause will override the + collations of all other arguments. (Attaching non-matching + COLLATE clauses to more than one argument, however, is an + error. For more details see .) + Thus, this gives the same result as the previous example: + +SELECT * FROM tbl WHERE a COLLATE "C" > 'foo'; + + But this is an error: + +SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C"; + + because it attempts to apply a collation to the result of the + > operator, which is of the non-collatable data type + boolean. + + + + + Scalar Subqueries + + + subquery + + + + A scalar subquery is an ordinary + SELECT query in parentheses that returns exactly one + row with one column. (See for information about writing queries.) + The SELECT query is executed + and the single returned value is used in the surrounding value expression. + It is an error to use a query that + returns more than one row or more than one column as a scalar subquery. + (But if, during a particular execution, the subquery returns no rows, + there is no error; the scalar result is taken to be null.) + The subquery can refer to variables from the surrounding query, + which will act as constants during any one evaluation of the subquery. + See also for other expressions involving subqueries. + + + + For example, the following finds the largest city population in each + state: + +SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name) + FROM states; + + + + + + Array Constructors + + + array + constructor + + + + ARRAY + + + + An array constructor is an expression that builds an + array value using values for its member elements. A simple array + constructor + consists of the key word ARRAY, a left square bracket + [, a list of expressions (separated by commas) for the + array element values, and finally a right square bracket ]. + For example: + +SELECT ARRAY[1,2,3+4]; + array +--------- + {1,2,7} +(1 row) + + By default, + the array element type is the common type of the member expressions, + determined using the same rules as for UNION or + CASE constructs (see ). + You can override this by explicitly casting the array constructor to the + desired type, for example: + +SELECT ARRAY[1,2,22.7]::integer[]; + array +---------- + {1,2,23} +(1 row) + + This has the same effect as casting each expression to the array + element type individually. + For more on casting, see . + + + + Multidimensional array values can be built by nesting array + constructors. + In the inner constructors, the key word ARRAY can + be omitted. For example, these produce the same result: + + +SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]]; + array +--------------- + {{1,2},{3,4}} +(1 row) + +SELECT ARRAY[[1,2],[3,4]]; + array +--------------- + {{1,2},{3,4}} +(1 row) + + + Since multidimensional arrays must be rectangular, inner constructors + at the same level must produce sub-arrays of identical dimensions. + Any cast applied to the outer ARRAY constructor propagates + automatically to all the inner constructors. + + + + Multidimensional array constructor elements can be anything yielding + an array of the proper kind, not only a sub-ARRAY construct. + For example: + +CREATE TABLE arr(f1 int[], f2 int[]); + +INSERT INTO arr VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]); + +SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM arr; + array +------------------------------------------------ + {{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}} +(1 row) + + + + + You can construct an empty array, but since it's impossible to have an + array with no type, you must explicitly cast your empty array to the + desired type. For example: + +SELECT ARRAY[]::integer[]; + array +------- + {} +(1 row) + + + + + It is also possible to construct an array from the results of a + subquery. In this form, the array constructor is written with the + key word ARRAY followed by a parenthesized (not + bracketed) subquery. For example: + +SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%'); + array +------------------------------------------------------------------ + {2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31,2412} +(1 row) + +SELECT ARRAY(SELECT ARRAY[i, i*2] FROM generate_series(1,5) AS a(i)); + array +---------------------------------- + {{1,2},{2,4},{3,6},{4,8},{5,10}} +(1 row) + + The subquery must return a single column. + If the subquery's output column is of a non-array type, the resulting + one-dimensional array will have an element for each row in the + subquery result, with an element type matching that of the + subquery's output column. + If the subquery's output column is of an array type, the result will be + an array of the same type but one higher dimension; in this case all + the subquery rows must yield arrays of identical dimensionality, else + the result would not be rectangular. + + + + The subscripts of an array value built with ARRAY + always begin with one. For more information about arrays, see + . + + + + + + Row Constructors + + + composite type + constructor + + + + row type + constructor + + + + ROW + + + + A row constructor is an expression that builds a row value (also + called a composite value) using values + for its member fields. A row constructor consists of the key word + ROW, a left parenthesis, zero or more + expressions (separated by commas) for the row field values, and finally + a right parenthesis. For example: + +SELECT ROW(1,2.5,'this is a test'); + + The key word ROW is optional when there is more than one + expression in the list. + + + + A row constructor can include the syntax + rowvalue.*, + which will be expanded to a list of the elements of the row value, + just as occurs when the .* syntax is used at the top level + of a SELECT list (see ). + For example, if table t has + columns f1 and f2, these are the same: + +SELECT ROW(t.*, 42) FROM t; +SELECT ROW(t.f1, t.f2, 42) FROM t; + + + + + + Before PostgreSQL 8.2, the + .* syntax was not expanded in row constructors, so + that writing ROW(t.*, 42) created a two-field row whose first + field was another row value. The new behavior is usually more useful. + If you need the old behavior of nested row values, write the inner + row value without .*, for instance + ROW(t, 42). + + + + + By default, the value created by a ROW expression is of + an anonymous record type. If necessary, it can be cast to a named + composite type — either the row type of a table, or a composite type + created with CREATE TYPE AS. An explicit cast might be needed + to avoid ambiguity. For example: + +CREATE TABLE mytable(f1 int, f2 float, f3 text); + +CREATE FUNCTION getf1(mytable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL; + +-- No cast needed since only one getf1() exists +SELECT getf1(ROW(1,2.5,'this is a test')); + getf1 +------- + 1 +(1 row) + +CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric); + +CREATE FUNCTION getf1(myrowtype) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL; + +-- Now we need a cast to indicate which function to call: +SELECT getf1(ROW(1,2.5,'this is a test')); +ERROR: function getf1(record) is not unique + +SELECT getf1(ROW(1,2.5,'this is a test')::mytable); + getf1 +------- + 1 +(1 row) + +SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype)); + getf1 +------- + 11 +(1 row) + + + + + Row constructors can be used to build composite values to be stored + in a composite-type table column, or to be passed to a function that + accepts a composite parameter. Also, + it is possible to compare two row values or test a row with + IS NULL or IS NOT NULL, for example: + +SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); + +SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows + + For more detail see . + Row constructors can also be used in connection with subqueries, + as discussed in . + + + + + + Expression Evaluation Rules + + + expression + order of evaluation + + + + The order of evaluation of subexpressions is not defined. In + particular, the inputs of an operator or function are not necessarily + evaluated left-to-right or in any other fixed order. + + + + Furthermore, if the result of an expression can be determined by + evaluating only some parts of it, then other subexpressions + might not be evaluated at all. For instance, if one wrote: + +SELECT true OR somefunc(); + + then somefunc() would (probably) not be called + at all. The same would be the case if one wrote: + +SELECT somefunc() OR true; + + Note that this is not the same as the left-to-right + short-circuiting of Boolean operators that is found + in some programming languages. + + + + As a consequence, it is unwise to use functions with side effects + as part of complex expressions. It is particularly dangerous to + rely on side effects or evaluation order in WHERE and HAVING clauses, + since those clauses are extensively reprocessed as part of + developing an execution plan. Boolean + expressions (AND/OR/NOT combinations) in those clauses can be reorganized + in any manner allowed by the laws of Boolean algebra. + + + + When it is essential to force evaluation order, a CASE + construct (see ) can be + used. For example, this is an untrustworthy way of trying to + avoid division by zero in a WHERE clause: + +SELECT ... WHERE x > 0 AND y/x > 1.5; + + But this is safe: + +SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END; + + A CASE construct used in this fashion will defeat optimization + attempts, so it should only be done when necessary. (In this particular + example, it would be better to sidestep the problem by writing + y > 1.5*x instead.) + + + + CASE is not a cure-all for such issues, however. + One limitation of the technique illustrated above is that it does not + prevent early evaluation of constant subexpressions. + As described in , functions and + operators marked IMMUTABLE can be evaluated when + the query is planned rather than when it is executed. Thus for example + +SELECT CASE WHEN x > 0 THEN x ELSE 1/0 END FROM tab; + + is likely to result in a division-by-zero failure due to the planner + trying to simplify the constant subexpression, + even if every row in the table has x > 0 so that the + ELSE arm would never be entered at run time. + + + + While that particular example might seem silly, related cases that don't + obviously involve constants can occur in queries executed within + functions, since the values of function arguments and local variables + can be inserted into queries as constants for planning purposes. + Within PL/pgSQL functions, for example, using an + IF-THEN-ELSE statement to protect + a risky computation is much safer than just nesting it in a + CASE expression. + + + + Another limitation of the same kind is that a CASE cannot + prevent evaluation of an aggregate expression contained within it, + because aggregate expressions are computed before other + expressions in a SELECT list or HAVING clause + are considered. For example, the following query can cause a + division-by-zero error despite seemingly having protected against it: + +SELECT CASE WHEN min(employees) > 0 + THEN avg(expenses / employees) + END + FROM departments; + + The min() and avg() aggregates are computed + concurrently over all the input rows, so if any row + has employees equal to zero, the division-by-zero error + will occur before there is any opportunity to test the result of + min(). Instead, use a WHERE + or FILTER clause to prevent problematic input rows from + reaching an aggregate function in the first place. + + + + + + Calling Functions + + + notation + functions + + + + PostgreSQL allows functions that have named + parameters to be called using either positional or + named notation. Named notation is especially + useful for functions that have a large number of parameters, since it + makes the associations between parameters and actual arguments more + explicit and reliable. + In positional notation, a function call is written with + its argument values in the same order as they are defined in the function + declaration. In named notation, the arguments are matched to the + function parameters by name and can be written in any order. + For each notation, also consider the effect of function argument types, + documented in . + + + + In either notation, parameters that have default values given in the + function declaration need not be written in the call at all. But this + is particularly useful in named notation, since any combination of + parameters can be omitted; while in positional notation parameters can + only be omitted from right to left. + + + + PostgreSQL also supports + mixed notation, which combines positional and + named notation. In this case, positional parameters are written first + and named parameters appear after them. + + + + The following examples will illustrate the usage of all three + notations, using the following function definition: + +CREATE FUNCTION concat_lower_or_upper(a text, b text, uppercase boolean DEFAULT false) +RETURNS text +AS +$$ + SELECT CASE + WHEN $3 THEN UPPER($1 || ' ' || $2) + ELSE LOWER($1 || ' ' || $2) + END; +$$ +LANGUAGE SQL IMMUTABLE STRICT; + + Function concat_lower_or_upper has two mandatory + parameters, a and b. Additionally + there is one optional parameter uppercase which defaults + to false. The a and + b inputs will be concatenated, and forced to either + upper or lower case depending on the uppercase + parameter. The remaining details of this function + definition are not important here (see for + more information). + + + + Using Positional Notation + + + function + positional notation + + + + Positional notation is the traditional mechanism for passing arguments + to functions in PostgreSQL. An example is: + +SELECT concat_lower_or_upper('Hello', 'World', true); + concat_lower_or_upper +----------------------- + HELLO WORLD +(1 row) + + All arguments are specified in order. The result is upper case since + uppercase is specified as true. + Another example is: + +SELECT concat_lower_or_upper('Hello', 'World'); + concat_lower_or_upper +----------------------- + hello world +(1 row) + + Here, the uppercase parameter is omitted, so it + receives its default value of false, resulting in + lower case output. In positional notation, arguments can be omitted + from right to left so long as they have defaults. + + + + + Using Named Notation + + + function + named notation + + + + In named notation, each argument's name is specified using + => to separate it from the argument expression. + For example: + +SELECT concat_lower_or_upper(a => 'Hello', b => 'World'); + concat_lower_or_upper +----------------------- + hello world +(1 row) + + Again, the argument uppercase was omitted + so it is set to false implicitly. One advantage of + using named notation is that the arguments may be specified in any + order, for example: + +SELECT concat_lower_or_upper(a => 'Hello', b => 'World', uppercase => true); + concat_lower_or_upper +----------------------- + HELLO WORLD +(1 row) + +SELECT concat_lower_or_upper(a => 'Hello', uppercase => true, b => 'World'); + concat_lower_or_upper +----------------------- + HELLO WORLD +(1 row) + + + + + An older syntax based on ":=" is supported for backward compatibility: + +SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World'); + concat_lower_or_upper +----------------------- + HELLO WORLD +(1 row) + + + + + + Using Mixed Notation + + + function + mixed notation + + + + The mixed notation combines positional and named notation. However, as + already mentioned, named arguments cannot precede positional arguments. + For example: + +SELECT concat_lower_or_upper('Hello', 'World', uppercase => true); + concat_lower_or_upper +----------------------- + HELLO WORLD +(1 row) + + In the above query, the arguments a and + b are specified positionally, while + uppercase is specified by name. In this example, + that adds little except documentation. With a more complex function + having numerous parameters that have default values, named or mixed + notation can save a great deal of writing and reduce chances for error. + + + + + Named and mixed call notations currently cannot be used when calling an + aggregate function (but they do work when an aggregate function is used + as a window function). + + + + + +
diff --git a/doc/src/sgml/tableam.sgml b/doc/src/sgml/tableam.sgml new file mode 100644 index 000000000000..a4fed6ea577a --- /dev/null +++ b/doc/src/sgml/tableam.sgml @@ -0,0 +1,111 @@ + + + + Table Access Method Interface Definition + + + Table Access Method + + + tableam + Table Access Method + + + + This chapter explains the interface between the core + PostgreSQL system and table access + methods, which manage the storage for tables. The core system + knows little about these access methods beyond what is specified here, so + it is possible to develop entirely new access method types by writing + add-on code. + + + + Each table access method is described by a row in the pg_am system + catalog. The pg_am entry specifies a name and a + handler function for the table access method. These + entries can be created and deleted using the and SQL commands. + + + + A table access method handler function must be declared to accept a single + argument of type internal and to return the pseudo-type + table_am_handler. The argument is a dummy value that simply + serves to prevent handler functions from being called directly from SQL commands. + + The result of the function must be a pointer to a struct of type + TableAmRoutine, which contains everything that the + core code needs to know to make use of the table access method. The return + value needs to be of server lifetime, which is typically achieved by + defining it as a static const variable in global + scope. The TableAmRoutine struct, also called the + access method's API struct, defines the behavior of + the access method using callbacks. These callbacks are pointers to plain C + functions and are not visible or callable at the SQL level. All the + callbacks and their behavior is defined in the + TableAmRoutine structure (with comments inside the + struct defining the requirements for callbacks). Most callbacks have + wrapper functions, which are documented from the point of view of a user + (rather than an implementor) of the table access method. For details, + please refer to the + src/include/access/tableam.h file. + + + + To implement an access method, an implementor will typically need to + implement an AM-specific type of tuple table slot (see + + src/include/executor/tuptable.h), which allows + code outside the access method to hold references to tuples of the AM, and + to access the columns of the tuple. + + + + Currently, the way an AM actually stores data is fairly unconstrained. For + example, it's possible, but not required, to use postgres' shared buffer + cache. In case it is used, it likely makes sense to use + PostgreSQL's standard page layout as described in + . + + + + One fairly large constraint of the table access method API is that, + currently, if the AM wants to support modifications and/or indexes, it is + necessary for each tuple to have a tuple identifier (TID) + consisting of a block number and an item number (see also ). It is not strictly necessary that the + sub-parts of TIDs have the same meaning they e.g., have + for heap, but if bitmap scan support is desired (it is + optional), the block number needs to provide locality. + + + + For crash safety, an AM can use postgres' WAL, or a custom implementation. + If WAL is chosen, either Generic WAL Records can be used, + or a new type of WAL records can be implemented. + Generic WAL Records are easy, but imply higher WAL volume. + Implementation of a new type of WAL record + currently requires modifications to core code (specifically, + src/include/access/rmgrlist.h). + + + + To implement transactional support in a manner that allows different table + access methods be accessed within a single transaction, it likely is + necessary to closely integrate with the machinery in + src/backend/access/transam/xlog.c. + + + + Any developer of a new table access method can refer to + the existing heap implementation present in + src/backend/access/heap/heapam_handler.c for details of + its implementation. + + + diff --git a/doc/src/sgml/tablefunc.sgml b/doc/src/sgml/tablefunc.sgml new file mode 100644 index 000000000000..808162b89b0b --- /dev/null +++ b/doc/src/sgml/tablefunc.sgml @@ -0,0 +1,865 @@ + + + + tablefunc + + + tablefunc + + + + The tablefunc module includes various functions that return + tables (that is, multiple rows). These functions are useful both in their + own right and as examples of how to write C functions that return + multiple rows. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Functions Provided + + + summarizes the functions provided + by the tablefunc module. + + + + <filename>tablefunc</filename> Functions + + + + + Function + + + Description + + + + + + + + normal_rand ( numvals integer, mean float8, stddev float8 ) + setof float8 + + + Produces a set of normally distributed random values. + + + + + + crosstab ( sql text ) + setof record + + + Produces a pivot table containing + row names plus N value columns, where + N is determined by the row type specified + in the calling query. + + + + + + crosstabN ( sql text ) + setof table_crosstab_N + + + Produces a pivot table containing + row names plus N value columns. + crosstab2, crosstab3, and + crosstab4 are predefined, but you can create additional + crosstabN functions as described below. + + + + + + crosstab ( source_sql text, category_sql text ) + setof record + + + Produces a pivot table + with the value columns specified by a second query. + + + + + + crosstab ( sql text, N integer ) + setof record + + + Obsolete version of crosstab(text). + The parameter N is now ignored, since the + number of value columns is always determined by the calling query. + + + + + + connectby + connectby ( relname text, keyid_fld text, parent_keyid_fld text + , orderby_fld text , start_with text, max_depth integer + , branch_delim text ) + setof record + + + Produces a representation of a hierarchical tree structure. + + + + +
+ + + <function>normal_rand</function> + + + normal_rand + + + +normal_rand(int numvals, float8 mean, float8 stddev) returns setof float8 + + + + normal_rand produces a set of normally distributed random + values (Gaussian distribution). + + + + numvals is the number of values to be returned + from the function. mean is the mean of the normal + distribution of values and stddev is the standard + deviation of the normal distribution of values. + + + + For example, this call requests 1000 values with a mean of 5 and a + standard deviation of 3: + + + +test=# SELECT * FROM normal_rand(1000, 5, 3); + normal_rand +---------------------- + 1.56556322244898 + 9.10040991424657 + 5.36957140345079 + -0.369151492880995 + 0.283600703686639 + . + . + . + 4.82992125404908 + 9.71308014517282 + 2.49639286969028 +(1000 rows) + + + + + <function>crosstab(text)</function> + + + crosstab + + + +crosstab(text sql) +crosstab(text sql, int N) + + + + The crosstab function is used to produce pivot + displays, wherein data is listed across the page rather than down. + For example, we might have data like + +row1 val11 +row1 val12 +row1 val13 +... +row2 val21 +row2 val22 +row2 val23 +... + + which we wish to display like + +row1 val11 val12 val13 ... +row2 val21 val22 val23 ... +... + + The crosstab function takes a text parameter that is an SQL + query producing raw data formatted in the first way, and produces a table + formatted in the second way. + + + + The sql parameter is an SQL statement that produces + the source set of data. This statement must return one + row_name column, one + category column, and one + value column. N is an + obsolete parameter, ignored if supplied (formerly this had to match the + number of output value columns, but now that is determined by the + calling query). + + + + For example, the provided query might produce a set something like: + + row_name cat value +----------+-------+------- + row1 cat1 val1 + row1 cat2 val2 + row1 cat3 val3 + row1 cat4 val4 + row2 cat1 val5 + row2 cat2 val6 + row2 cat3 val7 + row2 cat4 val8 + + + + + The crosstab function is declared to return setof + record, so the actual names and types of the output columns must be + defined in the FROM clause of the calling SELECT + statement, for example: + +SELECT * FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text); + + This example produces a set something like: + + <== value columns ==> + row_name category_1 category_2 +----------+------------+------------ + row1 val1 val2 + row2 val5 val6 + + + + + The FROM clause must define the output as one + row_name column (of the same data type as the first result + column of the SQL query) followed by N value columns + (all of the same data type as the third result column of the SQL query). + You can set up as many output value columns as you wish. The names of the + output columns are up to you. + + + + The crosstab function produces one output row for each + consecutive group of input rows with the same + row_name value. It fills the output + value columns, left to right, with the + value fields from these rows. If there + are fewer rows in a group than there are output value + columns, the extra output columns are filled with nulls; if there are + more rows, the extra input rows are skipped. + + + + In practice the SQL query should always specify ORDER BY 1,2 + to ensure that the input rows are properly ordered, that is, values with + the same row_name are brought together and + correctly ordered within the row. Notice that crosstab + itself does not pay any attention to the second column of the query + result; it's just there to be ordered by, to control the order in which + the third-column values appear across the page. + + + + Here is a complete example: + +CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT); +INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1'); +INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2'); +INSERT INTO ct(rowid, attribute, value) VALUES('test1','att3','val3'); +INSERT INTO ct(rowid, attribute, value) VALUES('test1','att4','val4'); +INSERT INTO ct(rowid, attribute, value) VALUES('test2','att1','val5'); +INSERT INTO ct(rowid, attribute, value) VALUES('test2','att2','val6'); +INSERT INTO ct(rowid, attribute, value) VALUES('test2','att3','val7'); +INSERT INTO ct(rowid, attribute, value) VALUES('test2','att4','val8'); + +SELECT * +FROM crosstab( + 'select rowid, attribute, value + from ct + where attribute = ''att2'' or attribute = ''att3'' + order by 1,2') +AS ct(row_name text, category_1 text, category_2 text, category_3 text); + + row_name | category_1 | category_2 | category_3 +----------+------------+------------+------------ + test1 | val2 | val3 | + test2 | val6 | val7 | +(2 rows) + + + + + You can avoid always having to write out a FROM clause to + define the output columns, by setting up a custom crosstab function that + has the desired output row type wired into its definition. This is + described in the next section. Another possibility is to embed the + required FROM clause in a view definition. + + + + + See also the \crosstabview + command in psql, which provides functionality similar + to crosstab(). + + + + + + + <function>crosstab<replaceable>N</replaceable>(text)</function> + + + crosstab + + + +crosstabN(text sql) + + + + The crosstabN functions are examples of how + to set up custom wrappers for the general crosstab function, + so that you need not write out column names and types in the calling + SELECT query. The tablefunc module includes + crosstab2, crosstab3, and + crosstab4, whose output row types are defined as + + + +CREATE TYPE tablefunc_crosstab_N AS ( + row_name TEXT, + category_1 TEXT, + category_2 TEXT, + . + . + . + category_N TEXT +); + + + + Thus, these functions can be used directly when the input query produces + row_name and value columns of type + text, and you want 2, 3, or 4 output values columns. + In all other ways they behave exactly as described above for the + general crosstab function. + + + + For instance, the example given in the previous section would also + work as + +SELECT * +FROM crosstab3( + 'select rowid, attribute, value + from ct + where attribute = ''att2'' or attribute = ''att3'' + order by 1,2'); + + + + + These functions are provided mostly for illustration purposes. You + can create your own return types and functions based on the + underlying crosstab() function. There are two ways + to do it: + + + + + Create a composite type describing the desired output columns, + similar to the examples in + contrib/tablefunc/tablefunc--1.0.sql. + Then define a + unique function name accepting one text parameter and returning + setof your_type_name, but linking to the same underlying + crosstab C function. For example, if your source data + produces row names that are text, and values that are + float8, and you want 5 value columns: + +CREATE TYPE my_crosstab_float8_5_cols AS ( + my_row_name text, + my_category_1 float8, + my_category_2 float8, + my_category_3 float8, + my_category_4 float8, + my_category_5 float8 +); + +CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(text) + RETURNS setof my_crosstab_float8_5_cols + AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT; + + + + + + + Use OUT parameters to define the return type implicitly. + The same example could also be done this way: + +CREATE OR REPLACE FUNCTION crosstab_float8_5_cols( + IN text, + OUT my_row_name text, + OUT my_category_1 float8, + OUT my_category_2 float8, + OUT my_category_3 float8, + OUT my_category_4 float8, + OUT my_category_5 float8) + RETURNS setof record + AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT; + + + + + + + + + + <function>crosstab(text, text)</function> + + + crosstab + + + +crosstab(text source_sql, text category_sql) + + + + The main limitation of the single-parameter form of crosstab + is that it treats all values in a group alike, inserting each value into + the first available column. If you want the value + columns to correspond to specific categories of data, and some groups + might not have data for some of the categories, that doesn't work well. + The two-parameter form of crosstab handles this case by + providing an explicit list of the categories corresponding to the + output columns. + + + + source_sql is an SQL statement that produces the + source set of data. This statement must return one + row_name column, one + category column, and one + value column. It may also have one or more + extra columns. + The row_name column must be first. The + category and value + columns must be the last two columns, in that order. Any columns between + row_name and + category are treated as extra. + The extra columns are expected to be the same for all rows + with the same row_name value. + + + + For example, source_sql might produce a set + something like: + +SELECT row_name, extra_col, cat, value FROM foo ORDER BY 1; + + row_name extra_col cat value +----------+------------+-----+--------- + row1 extra1 cat1 val1 + row1 extra1 cat2 val2 + row1 extra1 cat4 val4 + row2 extra2 cat1 val5 + row2 extra2 cat2 val6 + row2 extra2 cat3 val7 + row2 extra2 cat4 val8 + + + + + category_sql is an SQL statement that produces + the set of categories. This statement must return only one column. + It must produce at least one row, or an error will be generated. + Also, it must not produce duplicate values, or an error will be + generated. category_sql might be something like: + + +SELECT DISTINCT cat FROM foo ORDER BY 1; + cat + ------- + cat1 + cat2 + cat3 + cat4 + + + + + The crosstab function is declared to return setof + record, so the actual names and types of the output columns must be + defined in the FROM clause of the calling SELECT + statement, for example: + + +SELECT * FROM crosstab('...', '...') + AS ct(row_name text, extra text, cat1 text, cat2 text, cat3 text, cat4 text); + + + + + This will produce a result something like: + + <== value columns ==> +row_name extra cat1 cat2 cat3 cat4 +---------+-------+------+------+------+------ + row1 extra1 val1 val2 val4 + row2 extra2 val5 val6 val7 val8 + + + + + The FROM clause must define the proper number of output + columns of the proper data types. If there are N + columns in the source_sql query's result, the first + N-2 of them must match up with the first + N-2 output columns. The remaining output columns + must have the type of the last column of the source_sql + query's result, and there must be exactly as many of them as there + are rows in the category_sql query's result. + + + + The crosstab function produces one output row for each + consecutive group of input rows with the same + row_name value. The output + row_name column, plus any extra + columns, are copied from the first row of the group. The output + value columns are filled with the + value fields from rows having matching + category values. If a row's category + does not match any output of the category_sql + query, its value is ignored. Output + columns whose matching category is not present in any input row + of the group are filled with nulls. + + + + In practice the source_sql query should always + specify ORDER BY 1 to ensure that values with the same + row_name are brought together. However, + ordering of the categories within a group is not important. + Also, it is essential to be sure that the order of the + category_sql query's output matches the specified + output column order. + + + + Here are two complete examples: + +create table sales(year int, month int, qty int); +insert into sales values(2007, 1, 1000); +insert into sales values(2007, 2, 1500); +insert into sales values(2007, 7, 500); +insert into sales values(2007, 11, 1500); +insert into sales values(2007, 12, 2000); +insert into sales values(2008, 1, 1000); + +select * from crosstab( + 'select year, month, qty from sales order by 1', + 'select m from generate_series(1,12) m' +) as ( + year int, + "Jan" int, + "Feb" int, + "Mar" int, + "Apr" int, + "May" int, + "Jun" int, + "Jul" int, + "Aug" int, + "Sep" int, + "Oct" int, + "Nov" int, + "Dec" int +); + year | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec +------+------+------+-----+-----+-----+-----+-----+-----+-----+-----+------+------ + 2007 | 1000 | 1500 | | | | | 500 | | | | 1500 | 2000 + 2008 | 1000 | | | | | | | | | | | +(2 rows) + + + +CREATE TABLE cth(rowid text, rowdt timestamp, attribute text, val text); +INSERT INTO cth VALUES('test1','01 March 2003','temperature','42'); +INSERT INTO cth VALUES('test1','01 March 2003','test_result','PASS'); +INSERT INTO cth VALUES('test1','01 March 2003','volts','2.6987'); +INSERT INTO cth VALUES('test2','02 March 2003','temperature','53'); +INSERT INTO cth VALUES('test2','02 March 2003','test_result','FAIL'); +INSERT INTO cth VALUES('test2','02 March 2003','test_startdate','01 March 2003'); +INSERT INTO cth VALUES('test2','02 March 2003','volts','3.1234'); + +SELECT * FROM crosstab +( + 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1', + 'SELECT DISTINCT attribute FROM cth ORDER BY 1' +) +AS +( + rowid text, + rowdt timestamp, + temperature int4, + test_result text, + test_startdate timestamp, + volts float8 +); + rowid | rowdt | temperature | test_result | test_startdate | volts +-------+--------------------------+-------------+-------------+--------------------------+-------- + test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987 + test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234 +(2 rows) + + + + + You can create predefined functions to avoid having to write out + the result column names and types in each query. See the examples + in the previous section. The underlying C function for this form + of crosstab is named crosstab_hash. + + + + + + <function>connectby</function> + + + connectby + + + +connectby(text relname, text keyid_fld, text parent_keyid_fld + [, text orderby_fld ], text start_with, int max_depth + [, text branch_delim ]) + + + + The connectby function produces a display of hierarchical + data that is stored in a table. The table must have a key field that + uniquely identifies rows, and a parent-key field that references the + parent (if any) of each row. connectby can display the + sub-tree descending from any row. + + + + explains the + parameters. + + + + <function>connectby</function> Parameters + + + + Parameter + Description + + + + + relname + Name of the source relation + + + keyid_fld + Name of the key field + + + parent_keyid_fld + Name of the parent-key field + + + orderby_fld + Name of the field to order siblings by (optional) + + + start_with + Key value of the row to start at + + + max_depth + Maximum depth to descend to, or zero for unlimited depth + + + branch_delim + String to separate keys with in branch output (optional) + + + +
+ + + The key and parent-key fields can be any data type, but they must be + the same type. Note that the start_with value must be + entered as a text string, regardless of the type of the key field. + + + + The connectby function is declared to return setof + record, so the actual names and types of the output columns must be + defined in the FROM clause of the calling SELECT + statement, for example: + + + +SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~') + AS t(keyid text, parent_keyid text, level int, branch text, pos int); + + + + The first two output columns are used for the current row's key and + its parent row's key; they must match the type of the table's key field. + The third output column is the depth in the tree and must be of type + integer. If a branch_delim parameter was + given, the next output column is the branch display and must be of type + text. Finally, if an orderby_fld + parameter was given, the last output column is a serial number, and must + be of type integer. + + + + The branch output column shows the path of keys taken to + reach the current row. The keys are separated by the specified + branch_delim string. If no branch display is + wanted, omit both the branch_delim parameter + and the branch column in the output column list. + + + + If the ordering of siblings of the same parent is important, + include the orderby_fld parameter to + specify which field to order siblings by. This field can be of any + sortable data type. The output column list must include a final + integer serial-number column, if and only if + orderby_fld is specified. + + + + The parameters representing table and field names are copied as-is + into the SQL queries that connectby generates internally. + Therefore, include double quotes if the names are mixed-case or contain + special characters. You may also need to schema-qualify the table name. + + + + In large tables, performance will be poor unless there is an index on + the parent-key field. + + + + It is important that the branch_delim string + not appear in any key values, else connectby may incorrectly + report an infinite-recursion error. Note that if + branch_delim is not provided, a default value + of ~ is used for recursion detection purposes. + + + + + Here is an example: + +CREATE TABLE connectby_tree(keyid text, parent_keyid text, pos int); + +INSERT INTO connectby_tree VALUES('row1',NULL, 0); +INSERT INTO connectby_tree VALUES('row2','row1', 0); +INSERT INTO connectby_tree VALUES('row3','row1', 0); +INSERT INTO connectby_tree VALUES('row4','row2', 1); +INSERT INTO connectby_tree VALUES('row5','row2', 0); +INSERT INTO connectby_tree VALUES('row6','row4', 0); +INSERT INTO connectby_tree VALUES('row7','row3', 0); +INSERT INTO connectby_tree VALUES('row8','row6', 0); +INSERT INTO connectby_tree VALUES('row9','row5', 0); + +-- with branch, without orderby_fld (order of results is not guaranteed) +SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0, '~') + AS t(keyid text, parent_keyid text, level int, branch text); + keyid | parent_keyid | level | branch +-------+--------------+-------+--------------------- + row2 | | 0 | row2 + row4 | row2 | 1 | row2~row4 + row6 | row4 | 2 | row2~row4~row6 + row8 | row6 | 3 | row2~row4~row6~row8 + row5 | row2 | 1 | row2~row5 + row9 | row5 | 2 | row2~row5~row9 +(6 rows) + +-- without branch, without orderby_fld (order of results is not guaranteed) +SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0) + AS t(keyid text, parent_keyid text, level int); + keyid | parent_keyid | level +-------+--------------+------- + row2 | | 0 + row4 | row2 | 1 + row6 | row4 | 2 + row8 | row6 | 3 + row5 | row2 | 1 + row9 | row5 | 2 +(6 rows) + +-- with branch, with orderby_fld (notice that row5 comes before row4) +SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~') + AS t(keyid text, parent_keyid text, level int, branch text, pos int); + keyid | parent_keyid | level | branch | pos +-------+--------------+-------+---------------------+----- + row2 | | 0 | row2 | 1 + row5 | row2 | 1 | row2~row5 | 2 + row9 | row5 | 2 | row2~row5~row9 | 3 + row4 | row2 | 1 | row2~row4 | 4 + row6 | row4 | 2 | row2~row4~row6 | 5 + row8 | row6 | 3 | row2~row4~row6~row8 | 6 +(6 rows) + +-- without branch, with orderby_fld (notice that row5 comes before row4) +SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0) + AS t(keyid text, parent_keyid text, level int, pos int); + keyid | parent_keyid | level | pos +-------+--------------+-------+----- + row2 | | 0 | 1 + row5 | row2 | 1 | 2 + row9 | row5 | 2 | 3 + row4 | row2 | 1 | 4 + row6 | row4 | 2 | 5 + row8 | row6 | 3 | 6 +(6 rows) + + +
+ +
+ + + Author + + + Joe Conway + + + + +
diff --git a/doc/src/sgml/tablesample-method.sgml b/doc/src/sgml/tablesample-method.sgml new file mode 100644 index 000000000000..c821941b71bc --- /dev/null +++ b/doc/src/sgml/tablesample-method.sgml @@ -0,0 +1,300 @@ + + + + Writing a Table Sampling Method + + + table sampling method + + + + TABLESAMPLE method + + + + PostgreSQL's implementation of the TABLESAMPLE + clause supports custom table sampling methods, in addition to + the BERNOULLI and SYSTEM methods that are required + by the SQL standard. The sampling method determines which rows of the + table will be selected when the TABLESAMPLE clause is used. + + + + At the SQL level, a table sampling method is represented by a single SQL + function, typically implemented in C, having the signature + +method_name(internal) RETURNS tsm_handler + + The name of the function is the same method name appearing in the + TABLESAMPLE clause. The internal argument is a dummy + (always having value zero) that simply serves to prevent this function from + being called directly from an SQL command. + The result of the function must be a palloc'd struct of + type TsmRoutine, which contains pointers to support functions for + the sampling method. These support functions are plain C functions and + are not visible or callable at the SQL level. The support functions are + described in . + + + + In addition to function pointers, the TsmRoutine struct must + provide these additional fields: + + + + + List *parameterTypes + + + This is an OID list containing the data type OIDs of the parameter(s) + that will be accepted by the TABLESAMPLE clause when this + sampling method is used. For example, for the built-in methods, this + list contains a single item with value FLOAT4OID, which + represents the sampling percentage. Custom sampling methods can have + more or different parameters. + + + + + + bool repeatable_across_queries + + + If true, the sampling method can deliver identical samples + across successive queries, if the same parameters + and REPEATABLE seed value are supplied each time and the + table contents have not changed. When this is false, + the REPEATABLE clause is not accepted for use with the + sampling method. + + + + + + bool repeatable_across_scans + + + If true, the sampling method can deliver identical samples + across successive scans in the same query (assuming unchanging + parameters, seed value, and snapshot). + When this is false, the planner will not select plans that + would require scanning the sampled table more than once, since that + might result in inconsistent query output. + + + + + + + The TsmRoutine struct type is declared + in src/include/access/tsmapi.h, which see for additional + details. + + + + The table sampling methods included in the standard distribution are good + references when trying to write your own. Look into + the src/backend/access/tablesample subdirectory of the source + tree for the built-in sampling methods, and into the contrib + subdirectory for add-on methods. + + + + Sampling Method Support Functions + + + The TSM handler function returns a palloc'd TsmRoutine struct + containing pointers to the support functions described below. Most of + the functions are required, but some are optional, and those pointers can + be NULL. + + + + +void +SampleScanGetSampleSize (PlannerInfo *root, + RelOptInfo *baserel, + List *paramexprs, + BlockNumber *pages, + double *tuples); + + + This function is called during planning. It must estimate the number of + relation pages that will be read during a sample scan, and the number of + tuples that will be selected by the scan. (For example, these might be + determined by estimating the sampling fraction, and then multiplying + the baserel->pages and baserel->tuples + numbers by that, being sure to round the results to integral values.) + The paramexprs list holds the expression(s) that are + parameters to the TABLESAMPLE clause. It is recommended to + use estimate_expression_value() to try to reduce these + expressions to constants, if their values are needed for estimation + purposes; but the function must provide size estimates even if they cannot + be reduced, and it should not fail even if the values appear invalid + (remember that they're only estimates of what the run-time values will be). + The pages and tuples parameters are outputs. + + + + +void +InitSampleScan (SampleScanState *node, + int eflags); + + + Initialize for execution of a SampleScan plan node. + This is called during executor startup. + It should perform any initialization needed before processing can start. + The SampleScanState node has already been created, but + its tsm_state field is NULL. + The InitSampleScan function can palloc whatever internal + state data is needed by the sampling method, and store a pointer to + it in node->tsm_state. + Information about the table to scan is accessible through other fields + of the SampleScanState node (but note that the + node->ss.ss_currentScanDesc scan descriptor is not set + up yet). + eflags contains flag bits describing the executor's + operating mode for this plan node. + + + + When (eflags & EXEC_FLAG_EXPLAIN_ONLY) is true, + the scan will not actually be performed, so this function should only do + the minimum required to make the node state valid for EXPLAIN + and EndSampleScan. + + + + This function can be omitted (set the pointer to NULL), in which case + BeginSampleScan must perform all initialization needed + by the sampling method. + + + + +void +BeginSampleScan (SampleScanState *node, + Datum *params, + int nparams, + uint32 seed); + + + Begin execution of a sampling scan. + This is called just before the first attempt to fetch a tuple, and + may be called again if the scan needs to be restarted. + Information about the table to scan is accessible through fields + of the SampleScanState node (but note that the + node->ss.ss_currentScanDesc scan descriptor is not set + up yet). + The params array, of length nparams, contains the + values of the parameters supplied in the TABLESAMPLE clause. + These will have the number and types specified in the sampling + method's parameterTypes list, and have been checked + to not be null. + seed contains a seed to use for any random numbers generated + within the sampling method; it is either a hash derived from the + REPEATABLE value if one was given, or the result + of random() if not. + + + + This function may adjust the fields node->use_bulkread + and node->use_pagemode. + If node->use_bulkread is true, which it is by + default, the scan will use a buffer access strategy that encourages + recycling buffers after use. It might be reasonable to set this + to false if the scan will visit only a small fraction of the + table's pages. + If node->use_pagemode is true, which it is by + default, the scan will perform visibility checking in a single pass for + all tuples on each visited page. It might be reasonable to set this + to false if the scan will select only a small fraction of the + tuples on each visited page. That will result in fewer tuple visibility + checks being performed, though each one will be more expensive because it + will require more locking. + + + + If the sampling method is + marked repeatable_across_scans, it must be able to + select the same set of tuples during a rescan as it did originally, that is + a fresh call of BeginSampleScan must lead to selecting the + same tuples as before (if the TABLESAMPLE parameters + and seed don't change). + + + + +BlockNumber +NextSampleBlock (SampleScanState *node, BlockNumber nblocks); + + + Returns the block number of the next page to be scanned, or + InvalidBlockNumber if no pages remain to be scanned. + + + + This function can be omitted (set the pointer to NULL), in which case + the core code will perform a sequential scan of the entire relation. + Such a scan can use synchronized scanning, so that the sampling method + cannot assume that the relation pages are visited in the same order on + each scan. + + + + +OffsetNumber +NextSampleTuple (SampleScanState *node, + BlockNumber blockno, + OffsetNumber maxoffset); + + + Returns the offset number of the next tuple to be sampled on the + specified page, or InvalidOffsetNumber if no tuples remain to + be sampled. maxoffset is the largest offset number in use + on the page. + + + + + NextSampleTuple is not explicitly told which of the offset + numbers in the range 1 .. maxoffset actually contain valid + tuples. This is not normally a problem since the core code ignores + requests to sample missing or invisible tuples; that should not result in + any bias in the sample. However, if necessary, the function can use + node->donetuples to examine how many of the tuples + it returned were valid and visible. + + + + + + NextSampleTuple must not assume + that blockno is the same page number returned by the most + recent NextSampleBlock call. It was returned by some + previous NextSampleBlock call, but the core code is allowed + to call NextSampleBlock in advance of actually scanning + pages, so as to support prefetching. It is OK to assume that once + sampling of a given page begins, successive NextSampleTuple + calls all refer to the same page until InvalidOffsetNumber is + returned. + + + + + +void +EndSampleScan (SampleScanState *node); + + + End the scan and release resources. It is normally not important + to release palloc'd memory, but any externally-visible resources + should be cleaned up. + This function can be omitted (set the pointer to NULL) in the common + case where no such resources exist. + + + + + diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml new file mode 100644 index 000000000000..20db7b7afe6c --- /dev/null +++ b/doc/src/sgml/textsearch.sgml @@ -0,0 +1,4003 @@ + + + + Full Text Search + + + full text search + + + + text search + + + + Introduction + + + Full Text Searching (or just text search) provides + the capability to identify natural-language documents that + satisfy a query, and optionally to sort them by + relevance to the query. The most common type of search + is to find all documents containing given query terms + and return them in order of their similarity to the + query. Notions of query and + similarity are very flexible and depend on the specific + application. The simplest search considers query as a + set of words and similarity as the frequency of query + words in the document. + + + + Textual search operators have existed in databases for years. + PostgreSQL has + ~, ~*, LIKE, and + ILIKE operators for textual data types, but they lack + many essential properties required by modern information systems: + + + + + + There is no linguistic support, even for English. Regular expressions + are not sufficient because they cannot easily handle derived words, e.g., + satisfies and satisfy. You might + miss documents that contain satisfies, although you + probably would like to find them when searching for + satisfy. It is possible to use OR + to search for multiple derived forms, but this is tedious and error-prone + (some words can have several thousand derivatives). + + + + + + They provide no ordering (ranking) of search results, which makes them + ineffective when thousands of matching documents are found. + + + + + + They tend to be slow because there is no index support, so they must + process all documents for every search. + + + + + + Full text indexing allows documents to be preprocessed + and an index saved for later rapid searching. Preprocessing includes: + + + + + + Parsing documents into tokens. It is + useful to identify various classes of tokens, e.g., numbers, words, + complex words, email addresses, so that they can be processed + differently. In principle token classes depend on the specific + application, but for most purposes it is adequate to use a predefined + set of classes. + PostgreSQL uses a parser to + perform this step. A standard parser is provided, and custom parsers + can be created for specific needs. + + + + + + Converting tokens into lexemes. + A lexeme is a string, just like a token, but it has been + normalized so that different forms of the same word + are made alike. For example, normalization almost always includes + folding upper-case letters to lower-case, and often involves removal + of suffixes (such as s or es in English). + This allows searches to find variant forms of the + same word, without tediously entering all the possible variants. + Also, this step typically eliminates stop words, which + are words that are so common that they are useless for searching. + (In short, then, tokens are raw fragments of the document text, while + lexemes are words that are believed useful for indexing and searching.) + PostgreSQL uses dictionaries to + perform this step. Various standard dictionaries are provided, and + custom ones can be created for specific needs. + + + + + + Storing preprocessed documents optimized for + searching. For example, each document can be represented + as a sorted array of normalized lexemes. Along with the lexemes it is + often desirable to store positional information to use for + proximity ranking, so that a document that + contains a more dense region of query words is + assigned a higher rank than one with scattered query words. + + + + + + Dictionaries allow fine-grained control over how tokens are normalized. + With appropriate dictionaries, you can: + + + + + + Define stop words that should not be indexed. + + + + + + Map synonyms to a single word using Ispell. + + + + + + Map phrases to a single word using a thesaurus. + + + + + + Map different variations of a word to a canonical form using + an Ispell dictionary. + + + + + + Map different variations of a word to a canonical form using + Snowball stemmer rules. + + + + + + A data type tsvector is provided for storing preprocessed + documents, along with a type tsquery for representing processed + queries (). There are many + functions and operators available for these data types + (), the most important of which is + the match operator @@, which we introduce in + . Full text searches can be accelerated + using indexes (). + + + + + What Is a Document? + + + document + text search + + + + A document is the unit of searching in a full text search + system; for example, a magazine article or email message. The text search + engine must be able to parse documents and store associations of lexemes + (key words) with their parent document. Later, these associations are + used to search for documents that contain query words. + + + + For searches within PostgreSQL, + a document is normally a textual field within a row of a database table, + or possibly a combination (concatenation) of such fields, perhaps stored + in several tables or obtained dynamically. In other words, a document can + be constructed from different parts for indexing and it might not be + stored anywhere as a whole. For example: + + +SELECT title || ' ' || author || ' ' || abstract || ' ' || body AS document +FROM messages +WHERE mid = 12; + +SELECT m.title || ' ' || m.author || ' ' || m.abstract || ' ' || d.body AS document +FROM messages m, docs d +WHERE m.mid = d.did AND m.mid = 12; + + + + + + Actually, in these example queries, coalesce + should be used to prevent a single NULL attribute from + causing a NULL result for the whole document. + + + + + Another possibility is to store the documents as simple text files in the + file system. In this case, the database can be used to store the full text + index and to execute searches, and some unique identifier can be used to + retrieve the document from the file system. However, retrieving files + from outside the database requires superuser permissions or special + function support, so this is usually less convenient than keeping all + the data inside PostgreSQL. Also, keeping + everything inside the database allows easy access + to document metadata to assist in indexing and display. + + + + For text search purposes, each document must be reduced to the + preprocessed tsvector format. Searching and ranking + are performed entirely on the tsvector representation + of a document — the original text need only be retrieved + when the document has been selected for display to a user. + We therefore often speak of the tsvector as being the + document, but of course it is only a compact representation of + the full document. + + + + + Basic Text Matching + + + Full text searching in PostgreSQL is based on + the match operator @@, which returns + true if a tsvector + (document) matches a tsquery (query). + It doesn't matter which data type is written first: + + +SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & rat'::tsquery; + ?column? +---------- + t + +SELECT 'fat & cow'::tsquery @@ 'a fat cat sat on a mat and ate a fat rat'::tsvector; + ?column? +---------- + f + + + + + As the above example suggests, a tsquery is not just raw + text, any more than a tsvector is. A tsquery + contains search terms, which must be already-normalized lexemes, and + may combine multiple terms using AND, OR, NOT, and FOLLOWED BY operators. + (For syntax details see .) There are + functions to_tsquery, plainto_tsquery, + and phraseto_tsquery + that are helpful in converting user-written text into a proper + tsquery, primarily by normalizing words appearing in + the text. Similarly, to_tsvector is used to parse and + normalize a document string. So in practice a text search match would + look more like this: + + +SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat & rat'); + ?column? +---------- + t + + + Observe that this match would not succeed if written as + + +SELECT 'fat cats ate fat rats'::tsvector @@ to_tsquery('fat & rat'); + ?column? +---------- + f + + + since here no normalization of the word rats will occur. + The elements of a tsvector are lexemes, which are assumed + already normalized, so rats does not match rat. + + + + The @@ operator also + supports text input, allowing explicit conversion of a text + string to tsvector or tsquery to be skipped + in simple cases. The variants available are: + + +tsvector @@ tsquery +tsquery @@ tsvector +text @@ tsquery +text @@ text + + + + + The first two of these we saw already. + The form text @@ tsquery + is equivalent to to_tsvector(x) @@ y. + The form text @@ text + is equivalent to to_tsvector(x) @@ plainto_tsquery(y). + + + + Within a tsquery, the & (AND) operator + specifies that both its arguments must appear in the document to have a + match. Similarly, the | (OR) operator specifies that + at least one of its arguments must appear, while the ! (NOT) + operator specifies that its argument must not appear in + order to have a match. + For example, the query fat & ! rat matches documents that + contain fat but not rat. + + + + Searching for phrases is possible with the help of + the <-> (FOLLOWED BY) tsquery operator, which + matches only if its arguments have matches that are adjacent and in the + given order. For example: + + +SELECT to_tsvector('fatal error') @@ to_tsquery('fatal <-> error'); + ?column? +---------- + t + +SELECT to_tsvector('error is not fatal') @@ to_tsquery('fatal <-> error'); + ?column? +---------- + f + + + There is a more general version of the FOLLOWED BY operator having the + form <N>, + where N is an integer standing for the difference between + the positions of the matching lexemes. <1> is + the same as <->, while <2> + allows exactly one other lexeme to appear between the matches, and so + on. The phraseto_tsquery function makes use of this + operator to construct a tsquery that can match a multi-word + phrase when some of the words are stop words. For example: + + +SELECT phraseto_tsquery('cats ate rats'); + phraseto_tsquery +------------------------------- + 'cat' <-> 'ate' <-> 'rat' + +SELECT phraseto_tsquery('the cats ate the rats'); + phraseto_tsquery +------------------------------- + 'cat' <-> 'ate' <2> 'rat' + + + + + A special case that's sometimes useful is that <0> + can be used to require that two patterns match the same word. + + + + Parentheses can be used to control nesting of the tsquery + operators. Without parentheses, | binds least tightly, + then &, then <->, + and ! most tightly. + + + + It's worth noticing that the AND/OR/NOT operators mean something subtly + different when they are within the arguments of a FOLLOWED BY operator + than when they are not, because within FOLLOWED BY the exact position of + the match is significant. For example, normally !x matches + only documents that do not contain x anywhere. + But !x <-> y matches y if it is not + immediately after an x; an occurrence of x + elsewhere in the document does not prevent a match. Another example is + that x & y normally only requires that x + and y both appear somewhere in the document, but + (x & y) <-> z requires x + and y to match at the same place, immediately before + a z. Thus this query behaves differently from + x <-> z & y <-> z, which will match a + document containing two separate sequences x z and + y z. (This specific query is useless as written, + since x and y could not match at the same place; + but with more complex situations such as prefix-match patterns, a query + of this form could be useful.) + + + + + Configurations + + + The above are all simple text search examples. As mentioned before, full + text search functionality includes the ability to do many more things: + skip indexing certain words (stop words), process synonyms, and use + sophisticated parsing, e.g., parse based on more than just white space. + This functionality is controlled by text search + configurations. PostgreSQL comes with predefined + configurations for many languages, and you can easily create your own + configurations. (psql's \dF command + shows all available configurations.) + + + + During installation an appropriate configuration is selected and + is set accordingly + in postgresql.conf. If you are using the same text search + configuration for the entire cluster you can use the value in + postgresql.conf. To use different configurations + throughout the cluster but the same configuration within any one database, + use ALTER DATABASE ... SET. Otherwise, you can set + default_text_search_config in each session. + + + + Each text search function that depends on a configuration has an optional + regconfig argument, so that the configuration to use can be + specified explicitly. default_text_search_config + is used only when this argument is omitted. + + + + To make it easier to build custom text search configurations, a + configuration is built up from simpler database objects. + PostgreSQL's text search facility provides + four types of configuration-related database objects: + + + + + + Text search parsers break documents into tokens + and classify each token (for example, as words or numbers). + + + + + + Text search dictionaries convert tokens to normalized + form and reject stop words. + + + + + + Text search templates provide the functions underlying + dictionaries. (A dictionary simply specifies a template and a set + of parameters for the template.) + + + + + + Text search configurations select a parser and a set + of dictionaries to use to normalize the tokens produced by the parser. + + + + + + Text search parsers and templates are built from low-level C functions; + therefore it requires C programming ability to develop new ones, and + superuser privileges to install one into a database. (There are examples + of add-on parsers and templates in the contrib/ area of the + PostgreSQL distribution.) Since dictionaries and + configurations just parameterize and connect together some underlying + parsers and templates, no special privilege is needed to create a new + dictionary or configuration. Examples of creating custom dictionaries and + configurations appear later in this chapter. + + + + + + + + Tables and Indexes + + + The examples in the previous section illustrated full text matching using + simple constant strings. This section shows how to search table data, + optionally using indexes. + + + + Searching a Table + + + It is possible to do a full text search without an index. A simple query + to print the title of each row that contains the word + friend in its body field is: + + +SELECT title +FROM pgweb +WHERE to_tsvector('english', body) @@ to_tsquery('english', 'friend'); + + + This will also find related words such as friends + and friendly, since all these are reduced to the same + normalized lexeme. + + + + The query above specifies that the english configuration + is to be used to parse and normalize the strings. Alternatively we + could omit the configuration parameters: + + +SELECT title +FROM pgweb +WHERE to_tsvector(body) @@ to_tsquery('friend'); + + + This query will use the configuration set by . + + + + A more complex example is to + select the ten most recent documents that contain create and + table in the title or body: + + +SELECT title +FROM pgweb +WHERE to_tsvector(title || ' ' || body) @@ to_tsquery('create & table') +ORDER BY last_mod_date DESC +LIMIT 10; + + + For clarity we omitted the coalesce function calls + which would be needed to find rows that contain NULL + in one of the two fields. + + + + Although these queries will work without an index, most applications + will find this approach too slow, except perhaps for occasional ad-hoc + searches. Practical use of text searching usually requires creating + an index. + + + + + + Creating Indexes + + + We can create a GIN index () to speed up text searches: + + +CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', body)); + + + Notice that the 2-argument version of to_tsvector is + used. Only text search functions that specify a configuration name can + be used in expression indexes (). + This is because the index contents must be unaffected by . If they were affected, the + index contents might be inconsistent because different entries could + contain tsvectors that were created with different text search + configurations, and there would be no way to guess which was which. It + would be impossible to dump and restore such an index correctly. + + + + Because the two-argument version of to_tsvector was + used in the index above, only a query reference that uses the 2-argument + version of to_tsvector with the same configuration + name will use that index. That is, WHERE + to_tsvector('english', body) @@ 'a & b' can use the index, + but WHERE to_tsvector(body) @@ 'a & b' cannot. + This ensures that an index will be used only with the same configuration + used to create the index entries. + + + + It is possible to set up more complex expression indexes wherein the + configuration name is specified by another column, e.g.: + + +CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector(config_name, body)); + + + where config_name is a column in the pgweb + table. This allows mixed configurations in the same index while + recording which configuration was used for each index entry. This + would be useful, for example, if the document collection contained + documents in different languages. Again, + queries that are meant to use the index must be phrased to match, e.g., + WHERE to_tsvector(config_name, body) @@ 'a & b'. + + + + Indexes can even concatenate columns: + + +CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body)); + + + + + Another approach is to create a separate tsvector column + to hold the output of to_tsvector. To keep this + column automatically up to date with its source data, use a stored + generated column. This example is a + concatenation of title and body, + using coalesce to ensure that one field will still be + indexed when the other is NULL: + + +ALTER TABLE pgweb + ADD COLUMN textsearchable_index_col tsvector + GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED; + + + Then we create a GIN index to speed up the search: + + +CREATE INDEX textsearch_idx ON pgweb USING GIN (textsearchable_index_col); + + + Now we are ready to perform a fast full text search: + + +SELECT title +FROM pgweb +WHERE textsearchable_index_col @@ to_tsquery('create & table') +ORDER BY last_mod_date DESC +LIMIT 10; + + + + + One advantage of the separate-column approach over an expression index + is that it is not necessary to explicitly specify the text search + configuration in queries in order to make use of the index. As shown + in the example above, the query can depend on + default_text_search_config. Another advantage is that + searches will be faster, since it will not be necessary to redo the + to_tsvector calls to verify index matches. (This is more + important when using a GiST index than a GIN index; see .) The expression-index approach is + simpler to set up, however, and it requires less disk space since the + tsvector representation is not stored explicitly. + + + + + + + + Controlling Text Search + + + To implement full text searching there must be a function to create a + tsvector from a document and a tsquery from a + user query. Also, we need to return results in a useful order, so we need + a function that compares documents with respect to their relevance to + the query. It's also important to be able to display the results nicely. + PostgreSQL provides support for all of these + functions. + + + + Parsing Documents + + + PostgreSQL provides the + function to_tsvector for converting a document to + the tsvector data type. + + + + to_tsvector + + + +to_tsvector( config regconfig, document text) returns tsvector + + + + to_tsvector parses a textual document into tokens, + reduces the tokens to lexemes, and returns a tsvector which + lists the lexemes together with their positions in the document. + The document is processed according to the specified or default + text search configuration. + Here is a simple example: + + +SELECT to_tsvector('english', 'a fat cat sat on a mat - it ate a fat rats'); + to_tsvector +----------------------------------------------------- + 'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4 + + + + + In the example above we see that the resulting tsvector does not + contain the words a, on, or + it, the word rats became + rat, and the punctuation sign - was + ignored. + + + + The to_tsvector function internally calls a parser + which breaks the document text into tokens and assigns a type to + each token. For each token, a list of + dictionaries () is consulted, + where the list can vary depending on the token type. The first dictionary + that recognizes the token emits one or more normalized + lexemes to represent the token. For example, + rats became rat because one of the + dictionaries recognized that the word rats is a plural + form of rat. Some words are recognized as + stop words (), which + causes them to be ignored since they occur too frequently to be useful in + searching. In our example these are + a, on, and it. + If no dictionary in the list recognizes the token then it is also ignored. + In this example that happened to the punctuation sign - + because there are in fact no dictionaries assigned for its token type + (Space symbols), meaning space tokens will never be + indexed. The choices of parser, dictionaries and which types of tokens to + index are determined by the selected text search configuration (). It is possible to have + many different configurations in the same database, and predefined + configurations are available for various languages. In our example + we used the default configuration english for the + English language. + + + + The function setweight can be used to label the + entries of a tsvector with a given weight, + where a weight is one of the letters A, B, + C, or D. + This is typically used to mark entries coming from + different parts of a document, such as title versus body. Later, this + information can be used for ranking of search results. + + + + Because to_tsvector(NULL) will + return NULL, it is recommended to use + coalesce whenever a field might be null. + Here is the recommended method for creating + a tsvector from a structured document: + + +UPDATE tt SET ti = + setweight(to_tsvector(coalesce(title,'')), 'A') || + setweight(to_tsvector(coalesce(keyword,'')), 'B') || + setweight(to_tsvector(coalesce(abstract,'')), 'C') || + setweight(to_tsvector(coalesce(body,'')), 'D'); + + + Here we have used setweight to label the source + of each lexeme in the finished tsvector, and then merged + the labeled tsvector values using the tsvector + concatenation operator ||. ( gives details about these + operations.) + + + + + + Parsing Queries + + + PostgreSQL provides the + functions to_tsquery, + plainto_tsquery, + phraseto_tsquery and + websearch_to_tsquery + for converting a query to the tsquery data type. + to_tsquery offers access to more features + than either plainto_tsquery or + phraseto_tsquery, but it is less forgiving about its + input. websearch_to_tsquery is a simplified version + of to_tsquery with an alternative syntax, similar + to the one used by web search engines. + + + + to_tsquery + + + +to_tsquery( config regconfig, querytext text) returns tsquery + + + + to_tsquery creates a tsquery value from + querytext, which must consist of single tokens + separated by the tsquery operators & (AND), + | (OR), ! (NOT), and + <-> (FOLLOWED BY), possibly grouped + using parentheses. In other words, the input to + to_tsquery must already follow the general rules for + tsquery input, as described in . The difference is that while basic + tsquery input takes the tokens at face value, + to_tsquery normalizes each token into a lexeme using + the specified or default configuration, and discards any tokens that are + stop words according to the configuration. For example: + + +SELECT to_tsquery('english', 'The & Fat & Rats'); + to_tsquery +--------------- + 'fat' & 'rat' + + + As in basic tsquery input, weight(s) can be attached to each + lexeme to restrict it to match only tsvector lexemes of those + weight(s). For example: + + +SELECT to_tsquery('english', 'Fat | Rats:AB'); + to_tsquery +------------------ + 'fat' | 'rat':AB + + + Also, * can be attached to a lexeme to specify prefix matching: + + +SELECT to_tsquery('supern:*A & star:A*B'); + to_tsquery +-------------------------- + 'supern':*A & 'star':*AB + + + Such a lexeme will match any word in a tsvector that begins + with the given string. + + + + to_tsquery can also accept single-quoted + phrases. This is primarily useful when the configuration includes a + thesaurus dictionary that may trigger on such phrases. + In the example below, a thesaurus contains the rule supernovae + stars : sn: + + +SELECT to_tsquery('''supernovae stars'' & !crab'); + to_tsquery +--------------- + 'sn' & !'crab' + + + Without quotes, to_tsquery will generate a syntax + error for tokens that are not separated by an AND, OR, or FOLLOWED BY + operator. + + + + plainto_tsquery + + + +plainto_tsquery( config regconfig, querytext text) returns tsquery + + + + plainto_tsquery transforms the unformatted text + querytext to a tsquery value. + The text is parsed and normalized much as for to_tsvector, + then the & (AND) tsquery operator is + inserted between surviving words. + + + + Example: + + +SELECT plainto_tsquery('english', 'The Fat Rats'); + plainto_tsquery +----------------- + 'fat' & 'rat' + + + Note that plainto_tsquery will not + recognize tsquery operators, weight labels, + or prefix-match labels in its input: + + +SELECT plainto_tsquery('english', 'The Fat & Rats:C'); + plainto_tsquery +--------------------- + 'fat' & 'rat' & 'c' + + + Here, all the input punctuation was discarded. + + + + phraseto_tsquery + + + +phraseto_tsquery( config regconfig, querytext text) returns tsquery + + + + phraseto_tsquery behaves much like + plainto_tsquery, except that it inserts + the <-> (FOLLOWED BY) operator between + surviving words instead of the & (AND) operator. + Also, stop words are not simply discarded, but are accounted for by + inserting <N> operators rather + than <-> operators. This function is useful + when searching for exact lexeme sequences, since the FOLLOWED BY + operators check lexeme order not just the presence of all the lexemes. + + + + Example: + + +SELECT phraseto_tsquery('english', 'The Fat Rats'); + phraseto_tsquery +------------------ + 'fat' <-> 'rat' + + + Like plainto_tsquery, the + phraseto_tsquery function will not + recognize tsquery operators, weight labels, + or prefix-match labels in its input: + + +SELECT phraseto_tsquery('english', 'The Fat & Rats:C'); + phraseto_tsquery +----------------------------- + 'fat' <-> 'rat' <-> 'c' + + + + +websearch_to_tsquery( config regconfig, querytext text) returns tsquery + + + + websearch_to_tsquery creates a tsquery + value from querytext using an alternative + syntax in which simple unformatted text is a valid query. + Unlike plainto_tsquery + and phraseto_tsquery, it also recognizes certain + operators. Moreover, this function will never raise syntax errors, + which makes it possible to use raw user-supplied input for search. + The following syntax is supported: + + + + + unquoted text: text not inside quote marks will be + converted to terms separated by & operators, as + if processed by plainto_tsquery. + + + + + "quoted text": text inside quote marks will be + converted to terms separated by <-> + operators, as if processed by phraseto_tsquery. + + + + + OR: the word or will be converted to + the | operator. + + + + + -: a dash will be converted to + the ! operator. + + + + + Other punctuation is ignored. So + like plainto_tsquery + and phraseto_tsquery, + the websearch_to_tsquery function will not + recognize tsquery operators, weight labels, or prefix-match + labels in its input. + + + + Examples: + +SELECT websearch_to_tsquery('english', 'The fat rats'); + websearch_to_tsquery +---------------------- + 'fat' & 'rat' +(1 row) + +SELECT websearch_to_tsquery('english', '"supernovae stars" -crab'); + websearch_to_tsquery +---------------------------------- + 'supernova' <-> 'star' & !'crab' +(1 row) + +SELECT websearch_to_tsquery('english', '"sad cat" or "fat rat"'); + websearch_to_tsquery +----------------------------------- + 'sad' <-> 'cat' | 'fat' <-> 'rat' +(1 row) + +SELECT websearch_to_tsquery('english', 'signal -"segmentation fault"'); + websearch_to_tsquery +--------------------------------------- + 'signal' & !( 'segment' <-> 'fault' ) +(1 row) + +SELECT websearch_to_tsquery('english', '""" )( dummy \\ query <->'); + websearch_to_tsquery +---------------------- + 'dummi' & 'queri' +(1 row) + + + + + + Ranking Search Results + + + Ranking attempts to measure how relevant documents are to a particular + query, so that when there are many matches the most relevant ones can be + shown first. PostgreSQL provides two + predefined ranking functions, which take into account lexical, proximity, + and structural information; that is, they consider how often the query + terms appear in the document, how close together the terms are in the + document, and how important is the part of the document where they occur. + However, the concept of relevancy is vague and very application-specific. + Different applications might require additional information for ranking, + e.g., document modification time. The built-in ranking functions are only + examples. You can write your own ranking functions and/or combine their + results with additional factors to fit your specific needs. + + + + The two ranking functions currently available are: + + + + + + + + ts_rank + + + ts_rank( weights float4[], vector tsvector, query tsquery , normalization integer ) returns float4 + + + + + Ranks vectors based on the frequency of their matching lexemes. + + + + + + + + + ts_rank_cd + + + ts_rank_cd( weights float4[], vector tsvector, query tsquery , normalization integer ) returns float4 + + + + + This function computes the cover density + ranking for the given document vector and query, as described in + Clarke, Cormack, and Tudhope's "Relevance Ranking for One to Three + Term Queries" in the journal "Information Processing and Management", + 1999. Cover density is similar to ts_rank ranking + except that the proximity of matching lexemes to each other is + taken into consideration. + + + + This function requires lexeme positional information to perform + its calculation. Therefore, it ignores any stripped + lexemes in the tsvector. If there are no unstripped + lexemes in the input, the result will be zero. (See for more information + about the strip function and positional information + in tsvectors.) + + + + + + + + + + For both these functions, + the optional weights + argument offers the ability to weigh word instances more or less + heavily depending on how they are labeled. The weight arrays specify + how heavily to weigh each category of word, in the order: + + +{D-weight, C-weight, B-weight, A-weight} + + + If no weights are provided, + then these defaults are used: + + +{0.1, 0.2, 0.4, 1.0} + + + Typically weights are used to mark words from special areas of the + document, like the title or an initial abstract, so they can be + treated with more or less importance than words in the document body. + + + + Since a longer document has a greater chance of containing a query term + it is reasonable to take into account document size, e.g., a hundred-word + document with five instances of a search word is probably more relevant + than a thousand-word document with five instances. Both ranking functions + take an integer normalization option that + specifies whether and how a document's length should impact its rank. + The integer option controls several behaviors, so it is a bit mask: + you can specify one or more behaviors using + | (for example, 2|4). + + + + + 0 (the default) ignores the document length + + + + + 1 divides the rank by 1 + the logarithm of the document length + + + + + 2 divides the rank by the document length + + + + + 4 divides the rank by the mean harmonic distance between extents + (this is implemented only by ts_rank_cd) + + + + + 8 divides the rank by the number of unique words in document + + + + + 16 divides the rank by 1 + the logarithm of the number + of unique words in document + + + + + 32 divides the rank by itself + 1 + + + + + If more than one flag bit is specified, the transformations are + applied in the order listed. + + + + It is important to note that the ranking functions do not use any global + information, so it is impossible to produce a fair normalization to 1% or + 100% as sometimes desired. Normalization option 32 + (rank/(rank+1)) can be applied to scale all ranks + into the range zero to one, but of course this is just a cosmetic change; + it will not affect the ordering of the search results. + + + + Here is an example that selects only the ten highest-ranked matches: + + +SELECT title, ts_rank_cd(textsearch, query) AS rank +FROM apod, to_tsquery('neutrino|(dark & matter)') query +WHERE query @@ textsearch +ORDER BY rank DESC +LIMIT 10; + title | rank +-----------------------------------------------+---------- + Neutrinos in the Sun | 3.1 + The Sudbury Neutrino Detector | 2.4 + A MACHO View of Galactic Dark Matter | 2.01317 + Hot Gas and Dark Matter | 1.91171 + The Virgo Cluster: Hot Plasma and Dark Matter | 1.90953 + Rafting for Solar Neutrinos | 1.9 + NGC 4650A: Strange Galaxy and Dark Matter | 1.85774 + Hot Gas and Dark Matter | 1.6123 + Ice Fishing for Cosmic Neutrinos | 1.6 + Weak Lensing Distorts the Universe | 0.818218 + + + This is the same example using normalized ranking: + + +SELECT title, ts_rank_cd(textsearch, query, 32 /* rank/(rank+1) */ ) AS rank +FROM apod, to_tsquery('neutrino|(dark & matter)') query +WHERE query @@ textsearch +ORDER BY rank DESC +LIMIT 10; + title | rank +-----------------------------------------------+------------------- + Neutrinos in the Sun | 0.756097569485493 + The Sudbury Neutrino Detector | 0.705882361190954 + A MACHO View of Galactic Dark Matter | 0.668123210574724 + Hot Gas and Dark Matter | 0.65655958650282 + The Virgo Cluster: Hot Plasma and Dark Matter | 0.656301290640973 + Rafting for Solar Neutrinos | 0.655172410958162 + NGC 4650A: Strange Galaxy and Dark Matter | 0.650072921219637 + Hot Gas and Dark Matter | 0.617195790024749 + Ice Fishing for Cosmic Neutrinos | 0.615384618911517 + Weak Lensing Distorts the Universe | 0.450010798361481 + + + + + Ranking can be expensive since it requires consulting the + tsvector of each matching document, which can be I/O bound and + therefore slow. Unfortunately, it is almost impossible to avoid since + practical queries often result in large numbers of matches. + + + + + + Highlighting Results + + + To present search results it is ideal to show a part of each document and + how it is related to the query. Usually, search engines show fragments of + the document with marked search terms. PostgreSQL + provides a function ts_headline that + implements this functionality. + + + + ts_headline + + + +ts_headline( config regconfig, document text, query tsquery , options text ) returns text + + + + ts_headline accepts a document along + with a query, and returns an excerpt from + the document in which terms from the query are highlighted. The + configuration to be used to parse the document can be specified by + config; if config + is omitted, the + default_text_search_config configuration is used. + + + + If an options string is specified it must + consist of a comma-separated list of one or more + option=value pairs. + The available options are: + + + + + MaxWords, MinWords (integers): + these numbers determine the longest and shortest headlines to output. + The default values are 35 and 15. + + + + + ShortWord (integer): words of this length or less + will be dropped at the start and end of a headline, unless they are + query terms. The default value of three eliminates common English + articles. + + + + + HighlightAll (boolean): if + true the whole document will be used as the + headline, ignoring the preceding three parameters. The default + is false. + + + + + MaxFragments (integer): maximum number of text + fragments to display. The default value of zero selects a + non-fragment-based headline generation method. A value greater + than zero selects fragment-based headline generation (see below). + + + + + StartSel, StopSel (strings): + the strings with which to delimit query words appearing in the + document, to distinguish them from other excerpted words. The + default values are <b> and + </b>, which can be suitable + for HTML output. + + + + + FragmentDelimiter (string): When more than one + fragment is displayed, the fragments will be separated by this string. + The default is ... . + + + + + These option names are recognized case-insensitively. + You must double-quote string values if they contain spaces or commas. + + + + In non-fragment-based headline + generation, ts_headline locates matches for the + given query and chooses a + single one to display, preferring matches that have more query words + within the allowed headline length. + In fragment-based headline generation, ts_headline + locates the query matches and splits each match + into fragments of no more than MaxWords + words each, preferring fragments with more query words, and when + possible stretching fragments to include surrounding + words. The fragment-based mode is thus more useful when the query + matches span large sections of the document, or when it's desirable to + display multiple matches. + In either mode, if no query matches can be identified, then a single + fragment of the first MinWords words in the document + will be displayed. + + + + For example: + + +SELECT ts_headline('english', + 'The most common type of search +is to find all documents containing given query terms +and return them in order of their similarity to the +query.', + to_tsquery('english', 'query & similarity')); + ts_headline +------------------------------------------------------------ + containing given <b>query</b> terms + + and return them in order of their <b>similarity</b> to the+ + <b>query</b>. + +SELECT ts_headline('english', + 'Search terms may occur +many times in a document, +requiring ranking of the search matches to decide which +occurrences to display in the result.', + to_tsquery('english', 'search & term'), + 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<, StopSel=>>'); + ts_headline +------------------------------------------------------------ + <<Search>> <<terms>> may occur + + many times ... ranking of the <<search>> matches to decide + + + + + ts_headline uses the original document, not a + tsvector summary, so it can be slow and should be used with + care. + + + + + + + + Additional Features + + + This section describes additional functions and operators that are + useful in connection with text search. + + + + Manipulating Documents + + + showed how raw textual + documents can be converted into tsvector values. + PostgreSQL also provides functions and + operators that can be used to manipulate documents that are already + in tsvector form. + + + + + + + + + tsvector concatenation + + + tsvector || tsvector + + + + + The tsvector concatenation operator + returns a vector which combines the lexemes and positional information + of the two vectors given as arguments. Positions and weight labels + are retained during the concatenation. + Positions appearing in the right-hand vector are offset by the largest + position mentioned in the left-hand vector, so that the result is + nearly equivalent to the result of performing to_tsvector + on the concatenation of the two original document strings. (The + equivalence is not exact, because any stop-words removed from the + end of the left-hand argument will not affect the result, whereas + they would have affected the positions of the lexemes in the + right-hand argument if textual concatenation were used.) + + + + One advantage of using concatenation in the vector form, rather than + concatenating text before applying to_tsvector, is that + you can use different configurations to parse different sections + of the document. Also, because the setweight function + marks all lexemes of the given vector the same way, it is necessary + to parse the text and do setweight before concatenating + if you want to label different parts of the document with different + weights. + + + + + + + + + setweight + + + setweight(vector tsvector, weight "char") returns tsvector + + + + + setweight returns a copy of the input vector in which every + position has been labeled with the given weight, either + A, B, C, or + D. (D is the default for new + vectors and as such is not displayed on output.) These labels are + retained when vectors are concatenated, allowing words from different + parts of a document to be weighted differently by ranking functions. + + + + Note that weight labels apply to positions, not + lexemes. If the input vector has been stripped of + positions then setweight does nothing. + + + + + + + + length(tsvector) + + + length(vector tsvector) returns integer + + + + + Returns the number of lexemes stored in the vector. + + + + + + + + + strip + + + strip(vector tsvector) returns tsvector + + + + + Returns a vector that lists the same lexemes as the given vector, but + lacks any position or weight information. The result is usually much + smaller than an unstripped vector, but it is also less useful. + Relevance ranking does not work as well on stripped vectors as + unstripped ones. Also, + the <-> (FOLLOWED BY) tsquery operator + will never match stripped input, since it cannot determine the + distance between lexeme occurrences. + + + + + + + + + A full list of tsvector-related functions is available + in . + + + + + + Manipulating Queries + + + showed how raw textual + queries can be converted into tsquery values. + PostgreSQL also provides functions and + operators that can be used to manipulate queries that are already + in tsquery form. + + + + + + + + tsquery && tsquery + + + + + Returns the AND-combination of the two given queries. + + + + + + + + + tsquery || tsquery + + + + + Returns the OR-combination of the two given queries. + + + + + + + + + !! tsquery + + + + + Returns the negation (NOT) of the given query. + + + + + + + + + tsquery <-> tsquery + + + + + Returns a query that searches for a match to the first given query + immediately followed by a match to the second given query, using + the <-> (FOLLOWED BY) + tsquery operator. For example: + + +SELECT to_tsquery('fat') <-> to_tsquery('cat | rat'); + ?column? +---------------------------- + 'fat' <-> ( 'cat' | 'rat' ) + + + + + + + + + + + tsquery_phrase + + + tsquery_phrase(query1 tsquery, query2 tsquery [, distance integer ]) returns tsquery + + + + + Returns a query that searches for a match to the first given query + followed by a match to the second given query at a distance of exactly + distance lexemes, using + the <N> + tsquery operator. For example: + + +SELECT tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10); + tsquery_phrase +------------------ + 'fat' <10> 'cat' + + + + + + + + + + + numnode + + + numnode(query tsquery) returns integer + + + + + Returns the number of nodes (lexemes plus operators) in a + tsquery. This function is useful + to determine if the query is meaningful + (returns > 0), or contains only stop words (returns 0). + Examples: + + +SELECT numnode(plainto_tsquery('the any')); +NOTICE: query contains only stopword(s) or doesn't contain lexeme(s), ignored + numnode +--------- + 0 + +SELECT numnode('foo & bar'::tsquery); + numnode +--------- + 3 + + + + + + + + + + querytree + + + querytree(query tsquery) returns text + + + + + Returns the portion of a tsquery that can be used for + searching an index. This function is useful for detecting + unindexable queries, for example those containing only stop words + or only negated terms. For example: + + +SELECT querytree(to_tsquery('defined')); + querytree +----------- + 'defin' + +SELECT querytree(to_tsquery('!defined')); + querytree +----------- + T + + + + + + + + + Query Rewriting + + + ts_rewrite + + + + The ts_rewrite family of functions search a + given tsquery for occurrences of a target + subquery, and replace each occurrence with a + substitute subquery. In essence this operation is a + tsquery-specific version of substring replacement. + A target and substitute combination can be + thought of as a query rewrite rule. A collection + of such rewrite rules can be a powerful search aid. + For example, you can expand the search using synonyms + (e.g., new york, big apple, nyc, + gotham) or narrow the search to direct the user to some hot + topic. There is some overlap in functionality between this feature + and thesaurus dictionaries (). + However, you can modify a set of rewrite rules on-the-fly without + reindexing, whereas updating a thesaurus requires reindexing to be + effective. + + + + + + + + ts_rewrite (query tsquery, target tsquery, substitute tsquery) returns tsquery + + + + + This form of ts_rewrite simply applies a single + rewrite rule: target + is replaced by substitute + wherever it appears in query. For example: + + +SELECT ts_rewrite('a & b'::tsquery, 'a'::tsquery, 'c'::tsquery); + ts_rewrite +------------ + 'b' & 'c' + + + + + + + + + ts_rewrite (query tsquery, select text) returns tsquery + + + + + This form of ts_rewrite accepts a starting + query and an SQL select command, which + is given as a text string. The select must yield two + columns of tsquery type. For each row of the + select result, occurrences of the first column value + (the target) are replaced by the second column value (the substitute) + within the current query value. For example: + + +CREATE TABLE aliases (t tsquery PRIMARY KEY, s tsquery); +INSERT INTO aliases VALUES('a', 'c'); + +SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases'); + ts_rewrite +------------ + 'b' & 'c' + + + + + Note that when multiple rewrite rules are applied in this way, + the order of application can be important; so in practice you will + want the source query to ORDER BY some ordering key. + + + + + + + + Let's consider a real-life astronomical example. We'll expand query + supernovae using table-driven rewriting rules: + + +CREATE TABLE aliases (t tsquery primary key, s tsquery); +INSERT INTO aliases VALUES(to_tsquery('supernovae'), to_tsquery('supernovae|sn')); + +SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT * FROM aliases'); + ts_rewrite +--------------------------------- + 'crab' & ( 'supernova' | 'sn' ) + + + We can change the rewriting rules just by updating the table: + + +UPDATE aliases +SET s = to_tsquery('supernovae|sn & !nebulae') +WHERE t = to_tsquery('supernovae'); + +SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT * FROM aliases'); + ts_rewrite +--------------------------------------------- + 'crab' & ( 'supernova' | 'sn' & !'nebula' ) + + + + + Rewriting can be slow when there are many rewriting rules, since it + checks every rule for a possible match. To filter out obvious non-candidate + rules we can use the containment operators for the tsquery + type. In the example below, we select only those rules which might match + the original query: + + +SELECT ts_rewrite('a & b'::tsquery, + 'SELECT t,s FROM aliases WHERE ''a & b''::tsquery @> t'); + ts_rewrite +------------ + 'b' & 'c' + + + + + + + + + Triggers for Automatic Updates + + + trigger + for updating a derived tsvector column + + + + + The method described in this section has been obsoleted by the use of + stored generated columns, as described in . + + + + + When using a separate column to store the tsvector representation + of your documents, it is necessary to create a trigger to update the + tsvector column when the document content columns change. + Two built-in trigger functions are available for this, or you can write + your own. + + + +tsvector_update_trigger(tsvector_column_name,&zwsp; config_name, text_column_name , ... ) +tsvector_update_trigger_column(tsvector_column_name,&zwsp; config_column_name, text_column_name , ... ) + + + + These trigger functions automatically compute a tsvector + column from one or more textual columns, under the control of + parameters specified in the CREATE TRIGGER command. + An example of their use is: + + +CREATE TABLE messages ( + title text, + body text, + tsv tsvector +); + +CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE +ON messages FOR EACH ROW EXECUTE FUNCTION +tsvector_update_trigger(tsv, 'pg_catalog.english', title, body); + +INSERT INTO messages VALUES('title here', 'the body text is here'); + +SELECT * FROM messages; + title | body | tsv +------------+-----------------------+---------------------------- + title here | the body text is here | 'bodi':4 'text':5 'titl':1 + +SELECT title, body FROM messages WHERE tsv @@ to_tsquery('title & body'); + title | body +------------+----------------------- + title here | the body text is here + + + Having created this trigger, any change in title or + body will automatically be reflected into + tsv, without the application having to worry about it. + + + + The first trigger argument must be the name of the tsvector + column to be updated. The second argument specifies the text search + configuration to be used to perform the conversion. For + tsvector_update_trigger, the configuration name is simply + given as the second trigger argument. It must be schema-qualified as + shown above, so that the trigger behavior will not change with changes + in search_path. For + tsvector_update_trigger_column, the second trigger argument + is the name of another table column, which must be of type + regconfig. This allows a per-row selection of configuration + to be made. The remaining argument(s) are the names of textual columns + (of type text, varchar, or char). These + will be included in the document in the order given. NULL values will + be skipped (but the other columns will still be indexed). + + + + A limitation of these built-in triggers is that they treat all the + input columns alike. To process columns differently — for + example, to weight title differently from body — it is necessary + to write a custom trigger. Here is an example using + PL/pgSQL as the trigger language: + + +CREATE FUNCTION messages_trigger() RETURNS trigger AS $$ +begin + new.tsv := + setweight(to_tsvector('pg_catalog.english', coalesce(new.title,'')), 'A') || + setweight(to_tsvector('pg_catalog.english', coalesce(new.body,'')), 'D'); + return new; +end +$$ LANGUAGE plpgsql; + +CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE + ON messages FOR EACH ROW EXECUTE FUNCTION messages_trigger(); + + + + + Keep in mind that it is important to specify the configuration name + explicitly when creating tsvector values inside triggers, + so that the column's contents will not be affected by changes to + default_text_search_config. Failure to do this is likely to + lead to problems such as search results changing after a dump and reload. + + + + + + Gathering Document Statistics + + + ts_stat + + + + The function ts_stat is useful for checking your + configuration and for finding stop-word candidates. + + + +ts_stat(sqlquery text, weights text, + OUT word text, OUT ndoc integer, + OUT nentry integer) returns setof record + + + + sqlquery is a text value containing an SQL + query which must return a single tsvector column. + ts_stat executes the query and returns statistics about + each distinct lexeme (word) contained in the tsvector + data. The columns returned are + + + + + word text — the value of a lexeme + + + + + ndoc integer — number of documents + (tsvectors) the word occurred in + + + + + nentry integer — total number of + occurrences of the word + + + + + If weights is supplied, only occurrences + having one of those weights are counted. + + + + For example, to find the ten most frequent words in a document collection: + + +SELECT * FROM ts_stat('SELECT vector FROM apod') +ORDER BY nentry DESC, ndoc DESC, word +LIMIT 10; + + + The same, but counting only word occurrences with weight A + or B: + + +SELECT * FROM ts_stat('SELECT vector FROM apod', 'ab') +ORDER BY nentry DESC, ndoc DESC, word +LIMIT 10; + + + + + + + + + Parsers + + + Text search parsers are responsible for splitting raw document text + into tokens and identifying each token's type, where + the set of possible types is defined by the parser itself. + Note that a parser does not modify the text at all — it simply + identifies plausible word boundaries. Because of this limited scope, + there is less need for application-specific custom parsers than there is + for custom dictionaries. At present PostgreSQL + provides just one built-in parser, which has been found to be useful for a + wide range of applications. + + + + The built-in parser is named pg_catalog.default. + It recognizes 23 token types, shown in . + + + + Default Parser's Token Types + + + + + + + Alias + Description + Example + + + + + asciiword + Word, all ASCII letters + elephant + + + word + Word, all letters + mañana + + + numword + Word, letters and digits + beta1 + + + asciihword + Hyphenated word, all ASCII + up-to-date + + + hword + Hyphenated word, all letters + lógico-matemática + + + numhword + Hyphenated word, letters and digits + postgresql-beta1 + + + hword_asciipart + Hyphenated word part, all ASCII + postgresql in the context postgresql-beta1 + + + hword_part + Hyphenated word part, all letters + lógico or matemática + in the context lógico-matemática + + + hword_numpart + Hyphenated word part, letters and digits + beta1 in the context + postgresql-beta1 + + + email + Email address + foo@example.com + + + protocol + Protocol head + http:// + + + url + URL + example.com/stuff/index.html + + + host + Host + example.com + + + url_path + URL path + /stuff/index.html, in the context of a URL + + + file + File or path name + /usr/local/foo.txt, if not within a URL + + + sfloat + Scientific notation + -1.234e56 + + + float + Decimal notation + -1.234 + + + int + Signed integer + -1234 + + + uint + Unsigned integer + 1234 + + + version + Version number + 8.3.0 + + + tag + XML tag + <a href="dictionaries.html"> + + + entity + XML entity + &amp; + + + blank + Space symbols + (any whitespace or punctuation not otherwise recognized) + + + +
+ + + + The parser's notion of a letter is determined by the database's + locale setting, specifically lc_ctype. Words containing + only the basic ASCII letters are reported as a separate token type, + since it is sometimes useful to distinguish them. In most European + languages, token types word and asciiword + should be treated alike. + + + + email does not support all valid email characters as + defined by RFC 5322. + Specifically, the only non-alphanumeric characters supported for + email user names are period, dash, and underscore. + + + + + It is possible for the parser to produce overlapping tokens from the same + piece of text. As an example, a hyphenated word will be reported both + as the entire word and as each component: + + +SELECT alias, description, token FROM ts_debug('foo-bar-beta1'); + alias | description | token +-----------------+------------------------------------------+--------------- + numhword | Hyphenated word, letters and digits | foo-bar-beta1 + hword_asciipart | Hyphenated word part, all ASCII | foo + blank | Space symbols | - + hword_asciipart | Hyphenated word part, all ASCII | bar + blank | Space symbols | - + hword_numpart | Hyphenated word part, letters and digits | beta1 + + + This behavior is desirable since it allows searches to work for both + the whole compound word and for components. Here is another + instructive example: + + +SELECT alias, description, token FROM ts_debug('http://example.com/stuff/index.html'); + alias | description | token +----------+---------------+------------------------------ + protocol | Protocol head | http:// + url | URL | example.com/stuff/index.html + host | Host | example.com + url_path | URL path | /stuff/index.html + + + +
+ + + Dictionaries + + + Dictionaries are used to eliminate words that should not be considered in a + search (stop words), and to normalize words so + that different derived forms of the same word will match. A successfully + normalized word is called a lexeme. Aside from + improving search quality, normalization and removal of stop words reduce the + size of the tsvector representation of a document, thereby + improving performance. Normalization does not always have linguistic meaning + and usually depends on application semantics. + + + + Some examples of normalization: + + + + + + Linguistic — Ispell dictionaries try to reduce input words to a + normalized form; stemmer dictionaries remove word endings + + + + + URL locations can be canonicalized to make + equivalent URLs match: + + + + + http://www.pgsql.ru/db/mw/index.html + + + + + http://www.pgsql.ru/db/mw/ + + + + + http://www.pgsql.ru/db/../db/mw/index.html + + + + + + + + Color names can be replaced by their hexadecimal values, e.g., + red, green, blue, magenta -> FF0000, 00FF00, 0000FF, FF00FF + + + + + If indexing numbers, we can + remove some fractional digits to reduce the range of possible + numbers, so for example 3.14159265359, + 3.1415926, 3.14 will be the same + after normalization if only two digits are kept after the decimal point. + + + + + + + + A dictionary is a program that accepts a token as + input and returns: + + + + an array of lexemes if the input token is known to the dictionary + (notice that one token can produce more than one lexeme) + + + + + a single lexeme with the TSL_FILTER flag set, to replace + the original token with a new token to be passed to subsequent + dictionaries (a dictionary that does this is called a + filtering dictionary) + + + + + an empty array if the dictionary knows the token, but it is a stop word + + + + + NULL if the dictionary does not recognize the input token + + + + + + + PostgreSQL provides predefined dictionaries for + many languages. There are also several predefined templates that can be + used to create new dictionaries with custom parameters. Each predefined + dictionary template is described below. If no existing + template is suitable, it is possible to create new ones; see the + contrib/ area of the PostgreSQL distribution + for examples. + + + + A text search configuration binds a parser together with a set of + dictionaries to process the parser's output tokens. For each token + type that the parser can return, a separate list of dictionaries is + specified by the configuration. When a token of that type is found + by the parser, each dictionary in the list is consulted in turn, + until some dictionary recognizes it as a known word. If it is identified + as a stop word, or if no dictionary recognizes the token, it will be + discarded and not indexed or searched for. + Normally, the first dictionary that returns a non-NULL + output determines the result, and any remaining dictionaries are not + consulted; but a filtering dictionary can replace the given word + with a modified word, which is then passed to subsequent dictionaries. + + + + The general rule for configuring a list of dictionaries + is to place first the most narrow, most specific dictionary, then the more + general dictionaries, finishing with a very general dictionary, like + a Snowball stemmer or simple, which + recognizes everything. For example, for an astronomy-specific search + (astro_en configuration) one could bind token type + asciiword (ASCII word) to a synonym dictionary of astronomical + terms, a general English dictionary and a Snowball English + stemmer: + + +ALTER TEXT SEARCH CONFIGURATION astro_en + ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem; + + + + + A filtering dictionary can be placed anywhere in the list, except at the + end where it'd be useless. Filtering dictionaries are useful to partially + normalize words to simplify the task of later dictionaries. For example, + a filtering dictionary could be used to remove accents from accented + letters, as is done by the module. + + + + Stop Words + + + Stop words are words that are very common, appear in almost every + document, and have no discrimination value. Therefore, they can be ignored + in the context of full text searching. For example, every English text + contains words like a and the, so it is + useless to store them in an index. However, stop words do affect the + positions in tsvector, which in turn affect ranking: + + +SELECT to_tsvector('english', 'in the list of stop words'); + to_tsvector +---------------------------- + 'list':3 'stop':5 'word':6 + + + The missing positions 1,2,4 are because of stop words. Ranks + calculated for documents with and without stop words are quite different: + + +SELECT ts_rank_cd (to_tsvector('english', 'in the list of stop words'), to_tsquery('list & stop')); + ts_rank_cd +------------ + 0.05 + +SELECT ts_rank_cd (to_tsvector('english', 'list stop words'), to_tsquery('list & stop')); + ts_rank_cd +------------ + 0.1 + + + + + + It is up to the specific dictionary how it treats stop words. For example, + ispell dictionaries first normalize words and then + look at the list of stop words, while Snowball stemmers + first check the list of stop words. The reason for the different + behavior is an attempt to decrease noise. + + + + + + Simple Dictionary + + + The simple dictionary template operates by converting the + input token to lower case and checking it against a file of stop words. + If it is found in the file then an empty array is returned, causing + the token to be discarded. If not, the lower-cased form of the word + is returned as the normalized lexeme. Alternatively, the dictionary + can be configured to report non-stop-words as unrecognized, allowing + them to be passed on to the next dictionary in the list. + + + + Here is an example of a dictionary definition using the simple + template: + + +CREATE TEXT SEARCH DICTIONARY public.simple_dict ( + TEMPLATE = pg_catalog.simple, + STOPWORDS = english +); + + + Here, english is the base name of a file of stop words. + The file's full name will be + $SHAREDIR/tsearch_data/english.stop, + where $SHAREDIR means the + PostgreSQL installation's shared-data directory, + often /usr/local/share/postgresql (use pg_config + --sharedir to determine it if you're not sure). + The file format is simply a list + of words, one per line. Blank lines and trailing spaces are ignored, + and upper case is folded to lower case, but no other processing is done + on the file contents. + + + + Now we can test our dictionary: + + +SELECT ts_lexize('public.simple_dict', 'YeS'); + ts_lexize +----------- + {yes} + +SELECT ts_lexize('public.simple_dict', 'The'); + ts_lexize +----------- + {} + + + + + We can also choose to return NULL, instead of the lower-cased + word, if it is not found in the stop words file. This behavior is + selected by setting the dictionary's Accept parameter to + false. Continuing the example: + + +ALTER TEXT SEARCH DICTIONARY public.simple_dict ( Accept = false ); + +SELECT ts_lexize('public.simple_dict', 'YeS'); + ts_lexize +----------- + + +SELECT ts_lexize('public.simple_dict', 'The'); + ts_lexize +----------- + {} + + + + + With the default setting of Accept = true, + it is only useful to place a simple dictionary at the end + of a list of dictionaries, since it will never pass on any token to + a following dictionary. Conversely, Accept = false + is only useful when there is at least one following dictionary. + + + + + Most types of dictionaries rely on configuration files, such as files of + stop words. These files must be stored in UTF-8 encoding. + They will be translated to the actual database encoding, if that is + different, when they are read into the server. + + + + + + Normally, a database session will read a dictionary configuration file + only once, when it is first used within the session. If you modify a + configuration file and want to force existing sessions to pick up the + new contents, issue an ALTER TEXT SEARCH DICTIONARY command + on the dictionary. This can be a dummy update that doesn't + actually change any parameter values. + + + + + + + Synonym Dictionary + + + This dictionary template is used to create dictionaries that replace a + word with a synonym. Phrases are not supported (use the thesaurus + template () for that). A synonym + dictionary can be used to overcome linguistic problems, for example, to + prevent an English stemmer dictionary from reducing the word Paris to + pari. It is enough to have a Paris paris line in the + synonym dictionary and put it before the english_stem + dictionary. For example: + + +SELECT * FROM ts_debug('english', 'Paris'); + alias | description | token | dictionaries | dictionary | lexemes +-----------+-----------------+-------+----------------+--------------+--------- + asciiword | Word, all ASCII | Paris | {english_stem} | english_stem | {pari} + +CREATE TEXT SEARCH DICTIONARY my_synonym ( + TEMPLATE = synonym, + SYNONYMS = my_synonyms +); + +ALTER TEXT SEARCH CONFIGURATION english + ALTER MAPPING FOR asciiword + WITH my_synonym, english_stem; + +SELECT * FROM ts_debug('english', 'Paris'); + alias | description | token | dictionaries | dictionary | lexemes +-----------+-----------------+-------+---------------------------+------------+--------- + asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris} + + + + + The only parameter required by the synonym template is + SYNONYMS, which is the base name of its configuration file + — my_synonyms in the above example. + The file's full name will be + $SHAREDIR/tsearch_data/my_synonyms.syn + (where $SHAREDIR means the + PostgreSQL installation's shared-data directory). + The file format is just one line + per word to be substituted, with the word followed by its synonym, + separated by white space. Blank lines and trailing spaces are ignored. + + + + The synonym template also has an optional parameter + CaseSensitive, which defaults to false. When + CaseSensitive is false, words in the synonym file + are folded to lower case, as are input tokens. When it is + true, words and tokens are not folded to lower case, + but are compared as-is. + + + + An asterisk (*) can be placed at the end of a synonym + in the configuration file. This indicates that the synonym is a prefix. + The asterisk is ignored when the entry is used in + to_tsvector(), but when it is used in + to_tsquery(), the result will be a query item with + the prefix match marker (see + ). + For example, suppose we have these entries in + $SHAREDIR/tsearch_data/synonym_sample.syn: + +postgres pgsql +postgresql pgsql +postgre pgsql +gogle googl +indices index* + + Then we will get these results: + +mydb=# CREATE TEXT SEARCH DICTIONARY syn (template=synonym, synonyms='synonym_sample'); +mydb=# SELECT ts_lexize('syn', 'indices'); + ts_lexize +----------- + {index} +(1 row) + +mydb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple); +mydb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn; +mydb=# SELECT to_tsvector('tst', 'indices'); + to_tsvector +------------- + 'index':1 +(1 row) + +mydb=# SELECT to_tsquery('tst', 'indices'); + to_tsquery +------------ + 'index':* +(1 row) + +mydb=# SELECT 'indexes are very useful'::tsvector; + tsvector +--------------------------------- + 'are' 'indexes' 'useful' 'very' +(1 row) + +mydb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst', 'indices'); + ?column? +---------- + t +(1 row) + + + + + + Thesaurus Dictionary + + + A thesaurus dictionary (sometimes abbreviated as TZ) is + a collection of words that includes information about the relationships + of words and phrases, i.e., broader terms (BT), narrower + terms (NT), preferred terms, non-preferred terms, related + terms, etc. + + + + Basically a thesaurus dictionary replaces all non-preferred terms by one + preferred term and, optionally, preserves the original terms for indexing + as well. PostgreSQL's current implementation of the + thesaurus dictionary is an extension of the synonym dictionary with added + phrase support. A thesaurus dictionary requires + a configuration file of the following format: + + +# this is a comment +sample word(s) : indexed word(s) +more sample word(s) : more indexed word(s) +... + + + where the colon (:) symbol acts as a delimiter between a + phrase and its replacement. + + + + A thesaurus dictionary uses a subdictionary (which + is specified in the dictionary's configuration) to normalize the input + text before checking for phrase matches. It is only possible to select one + subdictionary. An error is reported if the subdictionary fails to + recognize a word. In that case, you should remove the use of the word or + teach the subdictionary about it. You can place an asterisk + (*) at the beginning of an indexed word to skip applying + the subdictionary to it, but all sample words must be known + to the subdictionary. + + + + The thesaurus dictionary chooses the longest match if there are multiple + phrases matching the input, and ties are broken by using the last + definition. + + + + Specific stop words recognized by the subdictionary cannot be + specified; instead use ? to mark the location where any + stop word can appear. For example, assuming that a and + the are stop words according to the subdictionary: + + +? one ? two : swsw + + + matches a one the two and the one a two; + both would be replaced by swsw. + + + + Since a thesaurus dictionary has the capability to recognize phrases it + must remember its state and interact with the parser. A thesaurus dictionary + uses these assignments to check if it should handle the next word or stop + accumulation. The thesaurus dictionary must be configured + carefully. For example, if the thesaurus dictionary is assigned to handle + only the asciiword token, then a thesaurus dictionary + definition like one 7 will not work since token type + uint is not assigned to the thesaurus dictionary. + + + + + Thesauruses are used during indexing so any change in the thesaurus + dictionary's parameters requires reindexing. + For most other dictionary types, small changes such as adding or + removing stopwords does not force reindexing. + + + + + Thesaurus Configuration + + + To define a new thesaurus dictionary, use the thesaurus + template. For example: + + +CREATE TEXT SEARCH DICTIONARY thesaurus_simple ( + TEMPLATE = thesaurus, + DictFile = mythesaurus, + Dictionary = pg_catalog.english_stem +); + + + Here: + + + + thesaurus_simple is the new dictionary's name + + + + + mythesaurus is the base name of the thesaurus + configuration file. + (Its full name will be $SHAREDIR/tsearch_data/mythesaurus.ths, + where $SHAREDIR means the installation shared-data + directory.) + + + + + pg_catalog.english_stem is the subdictionary (here, + a Snowball English stemmer) to use for thesaurus normalization. + Notice that the subdictionary will have its own + configuration (for example, stop words), which is not shown here. + + + + + Now it is possible to bind the thesaurus dictionary thesaurus_simple + to the desired token types in a configuration, for example: + + +ALTER TEXT SEARCH CONFIGURATION russian + ALTER MAPPING FOR asciiword, asciihword, hword_asciipart + WITH thesaurus_simple; + + + + + + + Thesaurus Example + + + Consider a simple astronomical thesaurus thesaurus_astro, + which contains some astronomical word combinations: + + +supernovae stars : sn +crab nebulae : crab + + + Below we create a dictionary and bind some token types to + an astronomical thesaurus and English stemmer: + + +CREATE TEXT SEARCH DICTIONARY thesaurus_astro ( + TEMPLATE = thesaurus, + DictFile = thesaurus_astro, + Dictionary = english_stem +); + +ALTER TEXT SEARCH CONFIGURATION russian + ALTER MAPPING FOR asciiword, asciihword, hword_asciipart + WITH thesaurus_astro, english_stem; + + + Now we can see how it works. + ts_lexize is not very useful for testing a thesaurus, + because it treats its input as a single token. Instead we can use + plainto_tsquery and to_tsvector + which will break their input strings into multiple tokens: + + +SELECT plainto_tsquery('supernova star'); + plainto_tsquery +----------------- + 'sn' + +SELECT to_tsvector('supernova star'); + to_tsvector +------------- + 'sn':1 + + + In principle, one can use to_tsquery if you quote + the argument: + + +SELECT to_tsquery('''supernova star'''); + to_tsquery +------------ + 'sn' + + + Notice that supernova star matches supernovae + stars in thesaurus_astro because we specified + the english_stem stemmer in the thesaurus definition. + The stemmer removed the e and s. + + + + To index the original phrase as well as the substitute, just include it + in the right-hand part of the definition: + + +supernovae stars : sn supernovae stars + +SELECT plainto_tsquery('supernova star'); + plainto_tsquery +----------------------------- + 'sn' & 'supernova' & 'star' + + + + + + + + + <application>Ispell</application> Dictionary + + + The Ispell dictionary template supports + morphological dictionaries, which can normalize many + different linguistic forms of a word into the same lexeme. For example, + an English Ispell dictionary can match all declensions and + conjugations of the search term bank, e.g., + banking, banked, banks, + banks', and bank's. + + + + The standard PostgreSQL distribution does + not include any Ispell configuration files. + Dictionaries for a large number of languages are available from Ispell. + Also, some more modern dictionary file formats are supported — MySpell (OO < 2.0.1) + and Hunspell + (OO >= 2.0.2). A large list of dictionaries is available on the OpenOffice + Wiki. + + + + To create an Ispell dictionary perform these steps: + + + + + download dictionary configuration files. OpenOffice + extension files have the .oxt extension. It is necessary + to extract .aff and .dic files, change + extensions to .affix and .dict. For some + dictionary files it is also needed to convert characters to the UTF-8 + encoding with commands (for example, for a Norwegian language dictionary): + +iconv -f ISO_8859-1 -t UTF-8 -o nn_no.affix nn_NO.aff +iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic + + + + + + copy files to the $SHAREDIR/tsearch_data directory + + + + + load files into PostgreSQL with the following command: + +CREATE TEXT SEARCH DICTIONARY english_hunspell ( + TEMPLATE = ispell, + DictFile = en_us, + AffFile = en_us, + Stopwords = english); + + + + + + + Here, DictFile, AffFile, and StopWords + specify the base names of the dictionary, affixes, and stop-words files. + The stop-words file has the same format explained above for the + simple dictionary type. The format of the other files is + not specified here but is available from the above-mentioned web sites. + + + + Ispell dictionaries usually recognize a limited set of words, so they + should be followed by another broader dictionary; for + example, a Snowball dictionary, which recognizes everything. + + + + The .affix file of Ispell has the following + structure: + +prefixes +flag *A: + . > RE # As in enter > reenter +suffixes +flag T: + E > ST # As in late > latest + [^AEIOU]Y > -Y,IEST # As in dirty > dirtiest + [AEIOU]Y > EST # As in gray > grayest + [^EY] > EST # As in small > smallest + + + + And the .dict file has the following structure: + +lapse/ADGRS +lard/DGRS +large/PRTY +lark/MRS + + + + + Format of the .dict file is: + +basic_form/affix_class_name + + + + + In the .affix file every affix flag is described in the + following format: + +condition > [-stripping_letters,] adding_affix + + + + + Here, condition has a format similar to the format of regular expressions. + It can use groupings [...] and [^...]. + For example, [AEIOU]Y means that the last letter of the word + is "y" and the penultimate letter is "a", + "e", "i", "o" or "u". + [^EY] means that the last letter is neither "e" + nor "y". + + + + Ispell dictionaries support splitting compound words; + a useful feature. + Notice that the affix file should specify a special flag using the + compoundwords controlled statement that marks dictionary + words that can participate in compound formation: + + +compoundwords controlled z + + + Here are some examples for the Norwegian language: + + +SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent'); + {over,buljong,terning,pakk,mester,assistent} +SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk'); + {sjokoladefabrikk,sjokolade,fabrikk} + + + + + MySpell format is a subset of Hunspell. + The .affix file of Hunspell has the following + structure: + +PFX A Y 1 +PFX A 0 re . +SFX T N 4 +SFX T 0 st e +SFX T y iest [^aeiou]y +SFX T 0 est [aeiou]y +SFX T 0 est [^ey] + + + + + The first line of an affix class is the header. Fields of an affix rules are + listed after the header: + + + + + parameter name (PFX or SFX) + + + + + flag (name of the affix class) + + + + + stripping characters from beginning (at prefix) or end (at suffix) of the + word + + + + + adding affix + + + + + condition that has a format similar to the format of regular expressions. + + + + + + The .dict file looks like the .dict file of + Ispell: + +larder/M +lardy/RT +large/RSPMYT +largehearted + + + + + + MySpell does not support compound words. + Hunspell has sophisticated support for compound words. At + present, PostgreSQL implements only the basic + compound word operations of Hunspell. + + + + + + + <application>Snowball</application> Dictionary + + + The Snowball dictionary template is based on a project + by Martin Porter, inventor of the popular Porter's stemming algorithm + for the English language. Snowball now provides stemming algorithms for + many languages (see the Snowball + site for more information). Each algorithm understands how to + reduce common variant forms of words to a base, or stem, spelling within + its language. A Snowball dictionary requires a language + parameter to identify which stemmer to use, and optionally can specify a + stopword file name that gives a list of words to eliminate. + (PostgreSQL's standard stopword lists are also + provided by the Snowball project.) + For example, there is a built-in definition equivalent to + + +CREATE TEXT SEARCH DICTIONARY english_stem ( + TEMPLATE = snowball, + Language = english, + StopWords = english +); + + + The stopword file format is the same as already explained. + + + + A Snowball dictionary recognizes everything, whether + or not it is able to simplify the word, so it should be placed + at the end of the dictionary list. It is useless to have it + before any other dictionary because a token will never pass through it to + the next dictionary. + + + + + + + + Configuration Example + + + A text search configuration specifies all options necessary to transform a + document into a tsvector: the parser to use to break text + into tokens, and the dictionaries to use to transform each token into a + lexeme. Every call of + to_tsvector or to_tsquery + needs a text search configuration to perform its processing. + The configuration parameter + + specifies the name of the default configuration, which is the + one used by text search functions if an explicit configuration + parameter is omitted. + It can be set in postgresql.conf, or set for an + individual session using the SET command. + + + + Several predefined text search configurations are available, and + you can create custom configurations easily. To facilitate management + of text search objects, a set of SQL commands + is available, and there are several psql commands that display information + about text search objects (). + + + + As an example we will create a configuration + pg, starting by duplicating the built-in + english configuration: + + +CREATE TEXT SEARCH CONFIGURATION public.pg ( COPY = pg_catalog.english ); + + + + + We will use a PostgreSQL-specific synonym list + and store it in $SHAREDIR/tsearch_data/pg_dict.syn. + The file contents look like: + + +postgres pg +pgsql pg +postgresql pg + + + We define the synonym dictionary like this: + + +CREATE TEXT SEARCH DICTIONARY pg_dict ( + TEMPLATE = synonym, + SYNONYMS = pg_dict +); + + + Next we register the Ispell dictionary + english_ispell, which has its own configuration files: + + +CREATE TEXT SEARCH DICTIONARY english_ispell ( + TEMPLATE = ispell, + DictFile = english, + AffFile = english, + StopWords = english +); + + + Now we can set up the mappings for words in configuration + pg: + + +ALTER TEXT SEARCH CONFIGURATION pg + ALTER MAPPING FOR asciiword, asciihword, hword_asciipart, + word, hword, hword_part + WITH pg_dict, english_ispell, english_stem; + + + We choose not to index or search some token types that the built-in + configuration does handle: + + +ALTER TEXT SEARCH CONFIGURATION pg + DROP MAPPING FOR email, url, url_path, sfloat, float; + + + + + Now we can test our configuration: + + +SELECT * FROM ts_debug('public.pg', ' +PostgreSQL, the highly scalable, SQL compliant, open source object-relational +database management system, is now undergoing beta testing of the next +version of our software. +'); + + + + + The next step is to set the session to use the new configuration, which was + created in the public schema: + + +=> \dF + List of text search configurations + Schema | Name | Description +---------+------+------------- + public | pg | + +SET default_text_search_config = 'public.pg'; +SET + +SHOW default_text_search_config; + default_text_search_config +---------------------------- + public.pg + + + + + + + Testing and Debugging Text Search + + + The behavior of a custom text search configuration can easily become + confusing. The functions described + in this section are useful for testing text search objects. You can + test a complete configuration, or test parsers and dictionaries separately. + + + + Configuration Testing + + + The function ts_debug allows easy testing of a + text search configuration. + + + + ts_debug + + + +ts_debug( config regconfig, document text, + OUT alias text, + OUT description text, + OUT token text, + OUT dictionaries regdictionary[], + OUT dictionary regdictionary, + OUT lexemes text[]) + returns setof record + + + + ts_debug displays information about every token of + document as produced by the + parser and processed by the configured dictionaries. It uses the + configuration specified by config, + or default_text_search_config if that argument is + omitted. + + + + ts_debug returns one row for each token identified in the text + by the parser. The columns returned are + + + + + alias text — short name of the token type + + + + + description text — description of the + token type + + + + + token text — text of the token + + + + + dictionaries regdictionary[] — the + dictionaries selected by the configuration for this token type + + + + + dictionary regdictionary — the dictionary + that recognized the token, or NULL if none did + + + + + lexemes text[] — the lexeme(s) produced + by the dictionary that recognized the token, or NULL if + none did; an empty array ({}) means it was recognized as a + stop word + + + + + + + Here is a simple example: + + +SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats'); + alias | description | token | dictionaries | dictionary | lexemes +-----------+-----------------+-------+----------------+--------------+--------- + asciiword | Word, all ASCII | a | {english_stem} | english_stem | {} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | cat | {english_stem} | english_stem | {cat} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | sat | {english_stem} | english_stem | {sat} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | on | {english_stem} | english_stem | {} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | a | {english_stem} | english_stem | {} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | mat | {english_stem} | english_stem | {mat} + blank | Space symbols | | {} | | + blank | Space symbols | - | {} | | + asciiword | Word, all ASCII | it | {english_stem} | english_stem | {} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | ate | {english_stem} | english_stem | {ate} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | a | {english_stem} | english_stem | {} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | rats | {english_stem} | english_stem | {rat} + + + + + For a more extensive demonstration, we + first create a public.english configuration and + Ispell dictionary for the English language: + + + +CREATE TEXT SEARCH CONFIGURATION public.english ( COPY = pg_catalog.english ); + +CREATE TEXT SEARCH DICTIONARY english_ispell ( + TEMPLATE = ispell, + DictFile = english, + AffFile = english, + StopWords = english +); + +ALTER TEXT SEARCH CONFIGURATION public.english + ALTER MAPPING FOR asciiword WITH english_ispell, english_stem; + + + +SELECT * FROM ts_debug('public.english', 'The Brightest supernovaes'); + alias | description | token | dictionaries | dictionary | lexemes +-----------+-----------------+-------------+-------------------------------+----------------+------------- + asciiword | Word, all ASCII | The | {english_ispell,english_stem} | english_ispell | {} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | Brightest | {english_ispell,english_stem} | english_ispell | {bright} + blank | Space symbols | | {} | | + asciiword | Word, all ASCII | supernovaes | {english_ispell,english_stem} | english_stem | {supernova} + + + + In this example, the word Brightest was recognized by the + parser as an ASCII word (alias asciiword). + For this token type the dictionary list is + english_ispell and + english_stem. The word was recognized by + english_ispell, which reduced it to the noun + bright. The word supernovaes is + unknown to the english_ispell dictionary so it + was passed to the next dictionary, and, fortunately, was recognized (in + fact, english_stem is a Snowball dictionary which + recognizes everything; that is why it was placed at the end of the + dictionary list). + + + + The word The was recognized by the + english_ispell dictionary as a stop word () and will not be indexed. + The spaces are discarded too, since the configuration provides no + dictionaries at all for them. + + + + You can reduce the width of the output by explicitly specifying which columns + you want to see: + + +SELECT alias, token, dictionary, lexemes +FROM ts_debug('public.english', 'The Brightest supernovaes'); + alias | token | dictionary | lexemes +-----------+-------------+----------------+------------- + asciiword | The | english_ispell | {} + blank | | | + asciiword | Brightest | english_ispell | {bright} + blank | | | + asciiword | supernovaes | english_stem | {supernova} + + + + + + + Parser Testing + + + The following functions allow direct testing of a text search parser. + + + + ts_parse + + + +ts_parse(parser_name text, document text, + OUT tokid integer, OUT token text) returns setof record +ts_parse(parser_oid oid, document text, + OUT tokid integer, OUT token text) returns setof record + + + + ts_parse parses the given document + and returns a series of records, one for each token produced by + parsing. Each record includes a tokid showing the + assigned token type and a token which is the text of the + token. For example: + + +SELECT * FROM ts_parse('default', '123 - a number'); + tokid | token +-------+-------- + 22 | 123 + 12 | + 12 | - + 1 | a + 12 | + 1 | number + + + + + ts_token_type + + + +ts_token_type(parser_name text, OUT tokid integer, + OUT alias text, OUT description text) returns setof record +ts_token_type(parser_oid oid, OUT tokid integer, + OUT alias text, OUT description text) returns setof record + + + + ts_token_type returns a table which describes each type of + token the specified parser can recognize. For each token type, the table + gives the integer tokid that the parser uses to label a + token of that type, the alias that names the token type + in configuration commands, and a short description. For + example: + + +SELECT * FROM ts_token_type('default'); + tokid | alias | description +-------+-----------------+------------------------------------------ + 1 | asciiword | Word, all ASCII + 2 | word | Word, all letters + 3 | numword | Word, letters and digits + 4 | email | Email address + 5 | url | URL + 6 | host | Host + 7 | sfloat | Scientific notation + 8 | version | Version number + 9 | hword_numpart | Hyphenated word part, letters and digits + 10 | hword_part | Hyphenated word part, all letters + 11 | hword_asciipart | Hyphenated word part, all ASCII + 12 | blank | Space symbols + 13 | tag | XML tag + 14 | protocol | Protocol head + 15 | numhword | Hyphenated word, letters and digits + 16 | asciihword | Hyphenated word, all ASCII + 17 | hword | Hyphenated word, all letters + 18 | url_path | URL path + 19 | file | File or path name + 20 | float | Decimal notation + 21 | int | Signed integer + 22 | uint | Unsigned integer + 23 | entity | XML entity + + + + + + + Dictionary Testing + + + The ts_lexize function facilitates dictionary testing. + + + + ts_lexize + + + +ts_lexize(dict regdictionary, token text) returns text[] + + + + ts_lexize returns an array of lexemes if the input + token is known to the dictionary, + or an empty array if the token + is known to the dictionary but it is a stop word, or + NULL if it is an unknown word. + + + + Examples: + + +SELECT ts_lexize('english_stem', 'stars'); + ts_lexize +----------- + {star} + +SELECT ts_lexize('english_stem', 'a'); + ts_lexize +----------- + {} + + + + + + The ts_lexize function expects a single + token, not text. Here is a case + where this can be confusing: + + +SELECT ts_lexize('thesaurus_astro', 'supernovae stars') is null; + ?column? +---------- + t + + + The thesaurus dictionary thesaurus_astro does know the + phrase supernovae stars, but ts_lexize + fails since it does not parse the input text but treats it as a single + token. Use plainto_tsquery or to_tsvector to + test thesaurus dictionaries, for example: + + +SELECT plainto_tsquery('supernovae stars'); + plainto_tsquery +----------------- + 'sn' + + + + + + + + + + GIN and GiST Index Types + + + text search + indexes + + + + There are two kinds of indexes that can be used to speed up full text + searches. + Note that indexes are not mandatory for full text searching, but in + cases where a column is searched on a regular basis, an index is + usually desirable. + + + + + + + + index + GIN + text search + + + CREATE INDEX name ON table USING GIN (column); + + + + + Creates a GIN (Generalized Inverted Index)-based index. + The column must be of tsvector type. + + + + + + + + + index + GiST + text search + + + CREATE INDEX name ON table USING GIST (column [ { DEFAULT | tsvector_ops } (siglen = number) ] ); + + + + + Creates a GiST (Generalized Search Tree)-based index. + The column can be of tsvector or + tsquery type. + Optional integer parameter siglen determines + signature length in bytes (see below for details). + + + + + + + + + GIN indexes are the preferred text search index type. As inverted + indexes, they contain an index entry for each word (lexeme), with a + compressed list of matching locations. Multi-word searches can find + the first match, then use the index to remove rows that are lacking + additional words. GIN indexes store only the words (lexemes) of + tsvector values, and not their weight labels. Thus a table + row recheck is needed when using a query that involves weights. + + + + A GiST index is lossy, meaning that the index + might produce false matches, and it is necessary + to check the actual table row to eliminate such false matches. + (PostgreSQL does this automatically when needed.) + GiST indexes are lossy because each document is represented in the + index by a fixed-length signature. The signature length in bytes is determined + by the value of the optional integer parameter siglen. + The default signature length (when siglen is not specified) is + 124 bytes, the maximum signature length is 2024 bytes. The signature is generated by hashing + each word into a single bit in an n-bit string, with all these bits OR-ed + together to produce an n-bit document signature. When two words hash to + the same bit position there will be a false match. If all words in + the query have matches (real or false) then the table row must be + retrieved to see if the match is correct. Longer signatures lead to a more + precise search (scanning a smaller fraction of the index and fewer heap + pages), at the cost of a larger index. + + + + A GiST index can be covering, i.e., use the INCLUDE + clause. Included columns can have data types without any GiST operator + class. Included attributes will be stored uncompressed. + + + + Lossiness causes performance degradation due to unnecessary fetches of table + records that turn out to be false matches. Since random access to table + records is slow, this limits the usefulness of GiST indexes. The + likelihood of false matches depends on several factors, in particular the + number of unique words, so using dictionaries to reduce this number is + recommended. + + + + Note that GIN index build time can often be improved + by increasing , while + GiST index build time is not sensitive to that + parameter. + + + + Partitioning of big collections and the proper use of GIN and GiST indexes + allows the implementation of very fast searches with online update. + Partitioning can be done at the database level using table inheritance, + or by distributing documents over + servers and collecting external search results, e.g., via Foreign Data access. + The latter is possible because ranking functions use + only local information. + + + + + + <application>psql</application> Support + + + Information about text search configuration objects can be obtained + in psql using a set of commands: + +\dF{d,p,t}+ PATTERN + + An optional + produces more details. + + + + The optional parameter PATTERN can be the name of + a text search object, optionally schema-qualified. If + PATTERN is omitted then information about all + visible objects will be displayed. PATTERN can be a + regular expression and can provide separate patterns + for the schema and object names. The following examples illustrate this: + + +=> \dF *fulltext* + List of text search configurations + Schema | Name | Description +--------+--------------+------------- + public | fulltext_cfg | + + + +=> \dF *.fulltext* + List of text search configurations + Schema | Name | Description +----------+---------------------------- + fulltext | fulltext_cfg | + public | fulltext_cfg | + + + The available commands are: + + + + + \dF+ PATTERN + + + List text search configurations (add + for more detail). + +=> \dF russian + List of text search configurations + Schema | Name | Description +------------+---------+------------------------------------ + pg_catalog | russian | configuration for russian language + +=> \dF+ russian +Text search configuration "pg_catalog.russian" +Parser: "pg_catalog.default" + Token | Dictionaries +-----------------+-------------- + asciihword | english_stem + asciiword | english_stem + email | simple + file | simple + float | simple + host | simple + hword | russian_stem + hword_asciipart | english_stem + hword_numpart | simple + hword_part | russian_stem + int | simple + numhword | simple + numword | simple + sfloat | simple + uint | simple + url | simple + url_path | simple + version | simple + word | russian_stem + + + + + + + \dFd+ PATTERN + + + List text search dictionaries (add + for more detail). + +=> \dFd + List of text search dictionaries + Schema | Name | Description +------------+-----------------+----------------------------------------------------------- + pg_catalog | arabic_stem | snowball stemmer for arabic language + pg_catalog | armenian_stem | snowball stemmer for armenian language + pg_catalog | basque_stem | snowball stemmer for basque language + pg_catalog | catalan_stem | snowball stemmer for catalan language + pg_catalog | danish_stem | snowball stemmer for danish language + pg_catalog | dutch_stem | snowball stemmer for dutch language + pg_catalog | english_stem | snowball stemmer for english language + pg_catalog | finnish_stem | snowball stemmer for finnish language + pg_catalog | french_stem | snowball stemmer for french language + pg_catalog | german_stem | snowball stemmer for german language + pg_catalog | greek_stem | snowball stemmer for greek language + pg_catalog | hindi_stem | snowball stemmer for hindi language + pg_catalog | hungarian_stem | snowball stemmer for hungarian language + pg_catalog | indonesian_stem | snowball stemmer for indonesian language + pg_catalog | irish_stem | snowball stemmer for irish language + pg_catalog | italian_stem | snowball stemmer for italian language + pg_catalog | lithuanian_stem | snowball stemmer for lithuanian language + pg_catalog | nepali_stem | snowball stemmer for nepali language + pg_catalog | norwegian_stem | snowball stemmer for norwegian language + pg_catalog | portuguese_stem | snowball stemmer for portuguese language + pg_catalog | romanian_stem | snowball stemmer for romanian language + pg_catalog | russian_stem | snowball stemmer for russian language + pg_catalog | serbian_stem | snowball stemmer for serbian language + pg_catalog | simple | simple dictionary: just lower case and check for stopword + pg_catalog | spanish_stem | snowball stemmer for spanish language + pg_catalog | swedish_stem | snowball stemmer for swedish language + pg_catalog | tamil_stem | snowball stemmer for tamil language + pg_catalog | turkish_stem | snowball stemmer for turkish language + pg_catalog | yiddish_stem | snowball stemmer for yiddish language + + + + + + + \dFp+ PATTERN + + + List text search parsers (add + for more detail). + +=> \dFp + List of text search parsers + Schema | Name | Description +------------+---------+--------------------- + pg_catalog | default | default word parser +=> \dFp+ + Text search parser "pg_catalog.default" + Method | Function | Description +-----------------+----------------+------------- + Start parse | prsd_start | + Get next token | prsd_nexttoken | + End parse | prsd_end | + Get headline | prsd_headline | + Get token types | prsd_lextype | + + Token types for parser "pg_catalog.default" + Token name | Description +-----------------+------------------------------------------ + asciihword | Hyphenated word, all ASCII + asciiword | Word, all ASCII + blank | Space symbols + email | Email address + entity | XML entity + file | File or path name + float | Decimal notation + host | Host + hword | Hyphenated word, all letters + hword_asciipart | Hyphenated word part, all ASCII + hword_numpart | Hyphenated word part, letters and digits + hword_part | Hyphenated word part, all letters + int | Signed integer + numhword | Hyphenated word, letters and digits + numword | Word, letters and digits + protocol | Protocol head + sfloat | Scientific notation + tag | XML tag + uint | Unsigned integer + url | URL + url_path | URL path + version | Version number + word | Word, all letters +(23 rows) + + + + + + + \dFt+ PATTERN + + + List text search templates (add + for more detail). + +=> \dFt + List of text search templates + Schema | Name | Description +------------+-----------+----------------------------------------------------------- + pg_catalog | ispell | ispell dictionary + pg_catalog | simple | simple dictionary: just lower case and check for stopword + pg_catalog | snowball | snowball stemmer + pg_catalog | synonym | synonym dictionary: replace word by its synonym + pg_catalog | thesaurus | thesaurus dictionary: phrase by phrase substitution + + + + + + + + + + Limitations + + + The current limitations of PostgreSQL's + text search features are: + + + The length of each lexeme must be less than 2 kilobytes + + + The length of a tsvector (lexemes + positions) must be + less than 1 megabyte + + + + The number of lexemes must be less than + 264 + + + Position values in tsvector must be greater than 0 and + no more than 16,383 + + + The match distance in a <N> + (FOLLOWED BY) tsquery operator cannot be more than + 16,384 + + + No more than 256 positions per lexeme + + + The number of nodes (lexemes + operators) in a tsquery + must be less than 32,768 + + + + + + For comparison, the PostgreSQL 8.1 documentation + contained 10,441 unique words, a total of 335,420 words, and the most + frequent word postgresql was mentioned 6,127 times in 655 + documents. + + + + + Another example — the PostgreSQL mailing + list archives contained 910,989 unique words with 57,491,343 lexemes in + 461,020 messages. + + + + +
diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml new file mode 100644 index 000000000000..f1a845f75686 --- /dev/null +++ b/doc/src/sgml/trigger.sgml @@ -0,0 +1,1000 @@ + + + + Triggers + + + trigger + + + + This chapter provides general information about writing trigger functions. + Trigger functions can be written in most of the available procedural + languages, including + PL/pgSQL (), + PL/Tcl (), + PL/Perl (), and + PL/Python (). + After reading this chapter, you should consult the chapter for + your favorite procedural language to find out the language-specific + details of writing a trigger in it. + + + + It is also possible to write a trigger function in C, although + most people find it easier to use one of the procedural languages. + It is not currently possible to write a trigger function in the + plain SQL function language. + + + + Overview of Trigger Behavior + + + A trigger is a specification that the database should automatically + execute a particular function whenever a certain type of operation is + performed. Triggers can be attached to tables (partitioned or not), + views, and foreign tables. + + + + On tables and foreign tables, triggers can be defined to execute either + before or after any INSERT, UPDATE, + or DELETE operation, either once per modified row, + or once per SQL statement. + UPDATE triggers can moreover be set to fire only if + certain columns are mentioned in the SET clause of + the UPDATE statement. Triggers can also fire + for TRUNCATE statements. If a trigger event occurs, + the trigger's function is called at the appropriate time to handle the + event. + + + + On views, triggers can be defined to execute instead of + INSERT, UPDATE, or + DELETE operations. + Such INSTEAD OF triggers + are fired once for each row that needs to be modified in the view. + It is the responsibility of the + trigger's function to perform the necessary modifications to the view's + underlying base table(s) and, where appropriate, return the modified + row as it will appear in the view. Triggers on views can also be defined + to execute once per SQL statement, before or after + INSERT, UPDATE, or + DELETE operations. + However, such triggers are fired only if there is also + an INSTEAD OF trigger on the view. Otherwise, + any statement targeting the view must be rewritten into a statement + affecting its underlying base table(s), and then the triggers + that will be fired are the ones attached to the base table(s). + + + + The trigger function must be defined before the trigger itself can be + created. The trigger function must be declared as a + function taking no arguments and returning type trigger. + (The trigger function receives its input through a specially-passed + TriggerData structure, not in the form of ordinary function + arguments.) + + + + Once a suitable trigger function has been created, the trigger is + established with + . + The same trigger function can be used for multiple triggers. + + + + PostgreSQL offers both per-row + triggers and per-statement triggers. With a per-row + trigger, the trigger function + is invoked once for each row that is affected by the statement + that fired the trigger. In contrast, a per-statement trigger is + invoked only once when an appropriate statement is executed, + regardless of the number of rows affected by that statement. In + particular, a statement that affects zero rows will still result + in the execution of any applicable per-statement triggers. These + two types of triggers are sometimes called row-level + triggers and statement-level triggers, + respectively. Triggers on TRUNCATE may only be + defined at statement level, not per-row. + + + + Triggers are also classified according to whether they fire + before, after, or + instead of the operation. These are referred to + as BEFORE triggers, AFTER triggers, and + INSTEAD OF triggers respectively. + Statement-level BEFORE triggers naturally fire before the + statement starts to do anything, while statement-level AFTER + triggers fire at the very end of the statement. These types of + triggers may be defined on tables, views, or foreign tables. Row-level + BEFORE triggers fire immediately before a particular row is + operated on, while row-level AFTER triggers fire at the end of + the statement (but before any statement-level AFTER triggers). + These types of triggers may only be defined on tables and + foreign tables, not views. + INSTEAD OF triggers may only be + defined on views, and only at row level; they fire immediately as each + row in the view is identified as needing to be operated on. + + + + A statement that targets a parent table in an inheritance or partitioning + hierarchy does not cause the statement-level triggers of affected child + tables to be fired; only the parent table's statement-level triggers are + fired. However, row-level triggers of any affected child tables will be + fired. + + + + If an INSERT contains an ON CONFLICT + DO UPDATE clause, it is possible that the effects of + row-level BEFORE INSERT triggers and + row-level BEFORE UPDATE triggers can + both be applied in a way that is apparent from the final state of + the updated row, if an EXCLUDED column is referenced. + There need not be an EXCLUDED column reference for + both sets of row-level BEFORE triggers to execute, + though. The + possibility of surprising outcomes should be considered when there + are both BEFORE INSERT and + BEFORE UPDATE row-level triggers + that change a row being inserted/updated (this can be + problematic even if the modifications are more or less equivalent, if + they're not also idempotent). Note that statement-level + UPDATE triggers are executed when ON + CONFLICT DO UPDATE is specified, regardless of whether or not + any rows were affected by the UPDATE (and + regardless of whether the alternative UPDATE + path was ever taken). An INSERT with an + ON CONFLICT DO UPDATE clause will execute + statement-level BEFORE INSERT + triggers first, then statement-level BEFORE + UPDATE triggers, followed by statement-level + AFTER UPDATE triggers and finally + statement-level AFTER INSERT + triggers. + + + + If an UPDATE on a partitioned table causes a row to move + to another partition, it will be performed as a DELETE + from the original partition followed by an INSERT into + the new partition. In this case, all row-level BEFORE + UPDATE triggers and all row-level + BEFORE DELETE triggers are fired on + the original partition. Then all row-level BEFORE + INSERT triggers are fired on the destination partition. + The possibility of surprising outcomes should be considered when all these + triggers affect the row being moved. As far as AFTER ROW + triggers are concerned, AFTER DELETE + and AFTER INSERT triggers are + applied; but AFTER UPDATE triggers + are not applied because the UPDATE has been converted to + a DELETE and an INSERT. As far as + statement-level triggers are concerned, none of the + DELETE or INSERT triggers are fired, + even if row movement occurs; only the UPDATE triggers + defined on the target table used in the UPDATE statement + will be fired. + + + + Trigger functions invoked by per-statement triggers should always + return NULL. Trigger functions invoked by per-row + triggers can return a table row (a value of + type HeapTuple) to the calling executor, + if they choose. A row-level trigger fired before an operation has + the following choices: + + + + + It can return NULL to skip the operation for the + current row. This instructs the executor to not perform the + row-level operation that invoked the trigger (the insertion, + modification, or deletion of a particular table row). + + + + + + For row-level INSERT + and UPDATE triggers only, the returned row + becomes the row that will be inserted or will replace the row + being updated. This allows the trigger function to modify the + row being inserted or updated. + + + + + A row-level BEFORE trigger that does not intend to cause + either of these behaviors must be careful to return as its result the same + row that was passed in (that is, the NEW row + for INSERT and UPDATE + triggers, the OLD row for + DELETE triggers). + + + + A row-level INSTEAD OF trigger should either return + NULL to indicate that it did not modify any data from + the view's underlying base tables, or it should return the view + row that was passed in (the NEW row + for INSERT and UPDATE + operations, or the OLD row for + DELETE operations). A nonnull return value is + used to signal that the trigger performed the necessary data + modifications in the view. This will cause the count of the number + of rows affected by the command to be incremented. For + INSERT and UPDATE operations only, the trigger + may modify the NEW row before returning it. This will + change the data returned by + INSERT RETURNING or UPDATE RETURNING, + and is useful when the view will not show exactly the same data + that was provided. + + + + The return value is ignored for row-level triggers fired after an + operation, and so they can return NULL. + + + + Some considerations apply for generated + columns.generated columnin + triggers Stored generated columns are computed after + BEFORE triggers and before AFTER + triggers. Therefore, the generated value can be inspected in + AFTER triggers. In BEFORE triggers, + the OLD row contains the old generated value, as one + would expect, but the NEW row does not yet contain the + new generated value and should not be accessed. In the C language + interface, the content of the column is undefined at this point; a + higher-level programming language should prevent access to a stored + generated column in the NEW row in a + BEFORE trigger. Changes to the value of a generated + column in a BEFORE trigger are ignored and will be + overwritten. + + + + If more than one trigger is defined for the same event on the same + relation, the triggers will be fired in alphabetical order by + trigger name. In the case of BEFORE and + INSTEAD OF triggers, the possibly-modified row returned by + each trigger becomes the input to the next trigger. If any + BEFORE or INSTEAD OF trigger returns + NULL, the operation is abandoned for that row and subsequent + triggers are not fired (for that row). + + + + A trigger definition can also specify a Boolean WHEN + condition, which will be tested to see whether the trigger should + be fired. In row-level triggers the WHEN condition can + examine the old and/or new values of columns of the row. (Statement-level + triggers can also have WHEN conditions, although the feature + is not so useful for them.) In a BEFORE trigger, the + WHEN + condition is evaluated just before the function is or would be executed, + so using WHEN is not materially different from testing the + same condition at the beginning of the trigger function. However, in + an AFTER trigger, the WHEN condition is evaluated + just after the row update occurs, and it determines whether an event is + queued to fire the trigger at the end of statement. So when an + AFTER trigger's + WHEN condition does not return true, it is not necessary + to queue an event nor to re-fetch the row at end of statement. This + can result in significant speedups in statements that modify many + rows, if the trigger only needs to be fired for a few of the rows. + INSTEAD OF triggers do not support + WHEN conditions. + + + + Typically, row-level BEFORE triggers are used for checking or + modifying the data that will be inserted or updated. For example, + a BEFORE trigger might be used to insert the current time into a + timestamp column, or to check that two elements of the row are + consistent. Row-level AFTER triggers are most sensibly + used to propagate the updates to other tables, or make consistency + checks against other tables. The reason for this division of labor is + that an AFTER trigger can be certain it is seeing the final + value of the row, while a BEFORE trigger cannot; there might + be other BEFORE triggers firing after it. If you have no + specific reason to make a trigger BEFORE or + AFTER, the BEFORE case is more efficient, since + the information about + the operation doesn't have to be saved until end of statement. + + + + If a trigger function executes SQL commands then these + commands might fire triggers again. This is known as cascading + triggers. There is no direct limitation on the number of cascade + levels. It is possible for cascades to cause a recursive invocation + of the same trigger; for example, an INSERT + trigger might execute a command that inserts an additional row + into the same table, causing the INSERT trigger + to be fired again. It is the trigger programmer's responsibility + to avoid infinite recursion in such scenarios. + + + + + trigger + arguments for trigger functions + + When a trigger is being defined, arguments can be specified for + it. The purpose of including arguments in the + trigger definition is to allow different triggers with similar + requirements to call the same function. As an example, there + could be a generalized trigger function that takes as its + arguments two column names and puts the current user in one and + the current time stamp in the other. Properly written, this + trigger function would be independent of the specific table it is + triggering on. So the same function could be used for + INSERT events on any table with suitable + columns, to automatically track creation of records in a + transaction table for example. It could also be used to track + last-update events if defined as an UPDATE + trigger. + + + + Each programming language that supports triggers has its own method + for making the trigger input data available to the trigger function. + This input data includes the type of trigger event (e.g., + INSERT or UPDATE) as well as any + arguments that were listed in CREATE TRIGGER. + For a row-level trigger, the input data also includes the + NEW row for INSERT and + UPDATE triggers, and/or the OLD row + for UPDATE and DELETE triggers. + + + + By default, statement-level triggers do not have any way to examine the + individual row(s) modified by the statement. But an AFTER + STATEMENT trigger can request that transition tables + be created to make the sets of affected rows available to the trigger. + AFTER ROW triggers can also request transition tables, so + that they can see the total changes in the table as well as the change in + the individual row they are currently being fired for. The method for + examining the transition tables again depends on the programming language + that is being used, but the typical approach is to make the transition + tables act like read-only temporary tables that can be accessed by SQL + commands issued within the trigger function. + + + + + + Visibility of Data Changes + + + If you execute SQL commands in your trigger function, and these + commands access the table that the trigger is for, then + you need to be aware of the data visibility rules, because they determine + whether these SQL commands will see the data change that the trigger + is fired for. Briefly: + + + + + + Statement-level triggers follow simple visibility rules: none of + the changes made by a statement are visible to statement-level + BEFORE triggers, whereas all + modifications are visible to statement-level AFTER + triggers. + + + + + + The data change (insertion, update, or deletion) causing the + trigger to fire is naturally not visible + to SQL commands executed in a row-level BEFORE trigger, + because it hasn't happened yet. + + + + + + However, SQL commands executed in a row-level BEFORE + trigger will see the effects of data + changes for rows previously processed in the same outer + command. This requires caution, since the ordering of these + change events is not in general predictable; an SQL command that + affects multiple rows can visit the rows in any order. + + + + + + Similarly, a row-level INSTEAD OF trigger will see the + effects of data changes made by previous firings of INSTEAD + OF triggers in the same outer command. + + + + + + When a row-level AFTER trigger is fired, all data + changes made + by the outer command are already complete, and are visible to + the invoked trigger function. + + + + + + + If your trigger function is written in any of the standard procedural + languages, then the above statements apply only if the function is + declared VOLATILE. Functions that are declared + STABLE or IMMUTABLE will not see changes made by + the calling command in any case. + + + + Further information about data visibility rules can be found in + . The example in contains a demonstration of these rules. + + + + + Writing Trigger Functions in C + + + trigger + in C + + + + transition tables + referencing from C trigger + + + + This section describes the low-level details of the interface to a + trigger function. This information is only needed when writing + trigger functions in C. If you are using a higher-level language then + these details are handled for you. In most cases you should consider + using a procedural language before writing your triggers in C. The + documentation of each procedural language explains how to write a + trigger in that language. + + + + Trigger functions must use the version 1 function manager + interface. + + + + When a function is called by the trigger manager, it is not passed + any normal arguments, but it is passed a context + pointer pointing to a TriggerData structure. C + functions can check whether they were called from the trigger + manager or not by executing the macro: + +CALLED_AS_TRIGGER(fcinfo) + + which expands to: + +((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData)) + + If this returns true, then it is safe to cast + fcinfo->context to type TriggerData + * and make use of the pointed-to + TriggerData structure. The function must + not alter the TriggerData + structure or any of the data it points to. + + + + struct TriggerData is defined in + commands/trigger.h: + + +typedef struct TriggerData +{ + NodeTag type; + TriggerEvent tg_event; + Relation tg_relation; + HeapTuple tg_trigtuple; + HeapTuple tg_newtuple; + Trigger *tg_trigger; + TupleTableSlot *tg_trigslot; + TupleTableSlot *tg_newslot; + Tuplestorestate *tg_oldtable; + Tuplestorestate *tg_newtable; + const Bitmapset *tg_updatedcols; +} TriggerData; + + + where the members are defined as follows: + + + + type + + + Always T_TriggerData. + + + + + + tg_event + + + Describes the event for which the function is called. You can use the + following macros to examine tg_event: + + + + TRIGGER_FIRED_BEFORE(tg_event) + + + Returns true if the trigger fired before the operation. + + + + + + TRIGGER_FIRED_AFTER(tg_event) + + + Returns true if the trigger fired after the operation. + + + + + + TRIGGER_FIRED_INSTEAD(tg_event) + + + Returns true if the trigger fired instead of the operation. + + + + + + TRIGGER_FIRED_FOR_ROW(tg_event) + + + Returns true if the trigger fired for a row-level event. + + + + + + TRIGGER_FIRED_FOR_STATEMENT(tg_event) + + + Returns true if the trigger fired for a statement-level event. + + + + + + TRIGGER_FIRED_BY_INSERT(tg_event) + + + Returns true if the trigger was fired by an INSERT command. + + + + + + TRIGGER_FIRED_BY_UPDATE(tg_event) + + + Returns true if the trigger was fired by an UPDATE command. + + + + + + TRIGGER_FIRED_BY_DELETE(tg_event) + + + Returns true if the trigger was fired by a DELETE command. + + + + + + TRIGGER_FIRED_BY_TRUNCATE(tg_event) + + + Returns true if the trigger was fired by a TRUNCATE command. + + + + + + + + + + tg_relation + + + A pointer to a structure describing the relation that the trigger fired for. + Look at utils/rel.h for details about + this structure. The most interesting things are + tg_relation->rd_att (descriptor of the relation + tuples) and tg_relation->rd_rel->relname + (relation name; the type is not char* but + NameData; use + SPI_getrelname(tg_relation) to get a char* if you + need a copy of the name). + + + + + + tg_trigtuple + + + A pointer to the row for which the trigger was fired. This is + the row being inserted, updated, or deleted. If this trigger + was fired for an INSERT or + DELETE then this is what you should return + from the function if you don't want to replace the row with + a different one (in the case of INSERT) or + skip the operation. For triggers on foreign tables, values of system + columns herein are unspecified. + + + + + + tg_newtuple + + + A pointer to the new version of the row, if the trigger was + fired for an UPDATE, and NULL if + it is for an INSERT or a + DELETE. This is what you have to return + from the function if the event is an UPDATE + and you don't want to replace this row by a different one or + skip the operation. For triggers on foreign tables, values of system + columns herein are unspecified. + + + + + + tg_trigger + + + A pointer to a structure of type Trigger, + defined in utils/reltrigger.h: + + +typedef struct Trigger +{ + Oid tgoid; + char *tgname; + Oid tgfoid; + int16 tgtype; + char tgenabled; + bool tgisinternal; + Oid tgconstrrelid; + Oid tgconstrindid; + Oid tgconstraint; + bool tgdeferrable; + bool tginitdeferred; + int16 tgnargs; + int16 tgnattr; + int16 *tgattr; + char **tgargs; + char *tgqual; + char *tgoldtable; + char *tgnewtable; +} Trigger; + + + where tgname is the trigger's name, + tgnargs is the number of arguments in + tgargs, and tgargs is an array of + pointers to the arguments specified in the CREATE + TRIGGER statement. The other members are for internal use + only. + + + + + + tg_trigslot + + + The slot containing tg_trigtuple, + or a NULL pointer if there is no such tuple. + + + + + + tg_newslot + + + The slot containing tg_newtuple, + or a NULL pointer if there is no such tuple. + + + + + + tg_oldtable + + + A pointer to a structure of type Tuplestorestate + containing zero or more rows in the format specified by + tg_relation, or a NULL pointer + if there is no OLD TABLE transition relation. + + + + + + tg_newtable + + + A pointer to a structure of type Tuplestorestate + containing zero or more rows in the format specified by + tg_relation, or a NULL pointer + if there is no NEW TABLE transition relation. + + + + + + tg_updatedcols + + + For UPDATE triggers, a bitmap set indicating the + columns that were updated by the triggering command. Generic trigger + functions can use this to optimize actions by not having to deal with + columns that were not changed. + + + + As an example, to determine whether a column with attribute number + attnum (1-based) is a member of this bitmap set, + call bms_is_member(attnum - + FirstLowInvalidHeapAttributeNumber, + trigdata->tg_updatedcols)). + + + + For triggers other than UPDATE triggers, this will + be NULL. + + + + + + + + To allow queries issued through SPI to reference transition tables, see + . + + + + A trigger function must return either a + HeapTuple pointer or a NULL pointer + (not an SQL null value, that is, do not set isNull true). + Be careful to return either + tg_trigtuple or tg_newtuple, + as appropriate, if you don't want to modify the row being operated on. + + + + + A Complete Trigger Example + + + Here is a very simple example of a trigger function written in C. + (Examples of triggers written in procedural languages can be found + in the documentation of the procedural languages.) + + + + The function trigf reports the number of rows in the + table ttest and skips the actual operation if the + command attempts to insert a null value into the column + x. (So the trigger acts as a not-null constraint but + doesn't abort the transaction.) + + + + First, the table definition: + +CREATE TABLE ttest ( + x integer +); + + + + + This is the source code of the trigger function: +context; + TupleDesc tupdesc; + HeapTuple rettuple; + char *when; + bool checknull = false; + bool isnull; + int ret, i; + + /* make sure it's called as a trigger at all */ + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "trigf: not called by trigger manager"); + + /* tuple to return to executor */ + if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + rettuple = trigdata->tg_newtuple; + else + rettuple = trigdata->tg_trigtuple; + + /* check for null values */ + if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event) + && TRIGGER_FIRED_BEFORE(trigdata->tg_event)) + checknull = true; + + if (TRIGGER_FIRED_BEFORE(trigdata->tg_event)) + when = "before"; + else + when = "after "; + + tupdesc = trigdata->tg_relation->rd_att; + + /* connect to SPI manager */ + if ((ret = SPI_connect()) < 0) + elog(ERROR, "trigf (fired %s): SPI_connect returned %d", when, ret); + + /* get number of rows in table */ + ret = SPI_exec("SELECT count(*) FROM ttest", 0); + + if (ret < 0) + elog(ERROR, "trigf (fired %s): SPI_exec returned %d", when, ret); + + /* count(*) returns int8, so be careful to convert */ + i = DatumGetInt64(SPI_getbinval(SPI_tuptable->vals[0], + SPI_tuptable->tupdesc, + 1, + &isnull)); + + elog (INFO, "trigf (fired %s): there are %d rows in ttest", when, i); + + SPI_finish(); + + if (checknull) + { + SPI_getbinval(rettuple, tupdesc, 1, &isnull); + if (isnull) + rettuple = NULL; + } + + return PointerGetDatum(rettuple); +} +]]> + + + + + After you have compiled the source code (see ), declare the function and the triggers: + +CREATE FUNCTION trigf() RETURNS trigger + AS 'filename' + LANGUAGE C; + +CREATE TRIGGER tbefore BEFORE INSERT OR UPDATE OR DELETE ON ttest + FOR EACH ROW EXECUTE FUNCTION trigf(); + +CREATE TRIGGER tafter AFTER INSERT OR UPDATE OR DELETE ON ttest + FOR EACH ROW EXECUTE FUNCTION trigf(); + + + + + Now you can test the operation of the trigger: + +=> INSERT INTO ttest VALUES (NULL); +INFO: trigf (fired before): there are 0 rows in ttest +INSERT 0 0 + +-- Insertion skipped and AFTER trigger is not fired + +=> SELECT * FROM ttest; + x +--- +(0 rows) + +=> INSERT INTO ttest VALUES (1); +INFO: trigf (fired before): there are 0 rows in ttest +INFO: trigf (fired after ): there are 1 rows in ttest + ^^^^^^^^ + remember what we said about visibility. +INSERT 167793 1 +vac=> SELECT * FROM ttest; + x +--- + 1 +(1 row) + +=> INSERT INTO ttest SELECT x * 2 FROM ttest; +INFO: trigf (fired before): there are 1 rows in ttest +INFO: trigf (fired after ): there are 2 rows in ttest + ^^^^^^ + remember what we said about visibility. +INSERT 167794 1 +=> SELECT * FROM ttest; + x +--- + 1 + 2 +(2 rows) + +=> UPDATE ttest SET x = NULL WHERE x = 2; +INFO: trigf (fired before): there are 2 rows in ttest +UPDATE 0 +=> UPDATE ttest SET x = 4 WHERE x = 2; +INFO: trigf (fired before): there are 2 rows in ttest +INFO: trigf (fired after ): there are 2 rows in ttest +UPDATE 1 +vac=> SELECT * FROM ttest; + x +--- + 1 + 4 +(2 rows) + +=> DELETE FROM ttest; +INFO: trigf (fired before): there are 2 rows in ttest +INFO: trigf (fired before): there are 1 rows in ttest +INFO: trigf (fired after ): there are 0 rows in ttest +INFO: trigf (fired after ): there are 0 rows in ttest + ^^^^^^ + remember what we said about visibility. +DELETE 2 +=> SELECT * FROM ttest; + x +--- +(0 rows) + + + + + + There are more complex examples in + src/test/regress/regress.c and + in . + + + diff --git a/doc/src/sgml/tsm-system-rows.sgml b/doc/src/sgml/tsm-system-rows.sgml new file mode 100644 index 000000000000..d960aa3e0fbc --- /dev/null +++ b/doc/src/sgml/tsm-system-rows.sgml @@ -0,0 +1,69 @@ + + + + tsm_system_rows + + + tsm_system_rows + + + + The tsm_system_rows module provides the table sampling method + SYSTEM_ROWS, which can be used in + the TABLESAMPLE clause of a SELECT + command. + + + + This table sampling method accepts a single integer argument that is the + maximum number of rows to read. The resulting sample will always contain + exactly that many rows, unless the table does not contain enough rows, in + which case the whole table is selected. + + + + Like the built-in SYSTEM sampling + method, SYSTEM_ROWS performs block-level sampling, so + that the sample is not completely random but may be subject to clustering + effects, especially if only a small number of rows are requested. + + + + SYSTEM_ROWS does not support + the REPEATABLE clause. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Examples + + + Here is an example of selecting a sample of a table with + SYSTEM_ROWS. First install the extension: + + + +CREATE EXTENSION tsm_system_rows; + + + + Then you can use it in a SELECT command, for instance: + + +SELECT * FROM my_table TABLESAMPLE SYSTEM_ROWS(100); + + + + + This command will return a sample of 100 rows from the + table my_table (unless the table does not have 100 + visible rows, in which case all its rows are returned). + + + + diff --git a/doc/src/sgml/tsm-system-time.sgml b/doc/src/sgml/tsm-system-time.sgml new file mode 100644 index 000000000000..df6e83a9236e --- /dev/null +++ b/doc/src/sgml/tsm-system-time.sgml @@ -0,0 +1,71 @@ + + + + tsm_system_time + + + tsm_system_time + + + + The tsm_system_time module provides the table sampling method + SYSTEM_TIME, which can be used in + the TABLESAMPLE clause of a SELECT + command. + + + + This table sampling method accepts a single floating-point argument that + is the maximum number of milliseconds to spend reading the table. This + gives you direct control over how long the query takes, at the price that + the size of the sample becomes hard to predict. The resulting sample will + contain as many rows as could be read in the specified time, unless the + whole table has been read first. + + + + Like the built-in SYSTEM sampling + method, SYSTEM_TIME performs block-level sampling, so + that the sample is not completely random but may be subject to clustering + effects, especially if only a small number of rows are selected. + + + + SYSTEM_TIME does not support + the REPEATABLE clause. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + Examples + + + Here is an example of selecting a sample of a table with + SYSTEM_TIME. First install the extension: + + + +CREATE EXTENSION tsm_system_time; + + + + Then you can use it in a SELECT command, for instance: + + +SELECT * FROM my_table TABLESAMPLE SYSTEM_TIME(1000); + + + + + This command will return as large a sample of my_table as + it can read in 1 second (1000 milliseconds). Of course, if the whole + table can be read in under 1 second, all its rows will be returned. + + + + diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml new file mode 100644 index 000000000000..287487424866 --- /dev/null +++ b/doc/src/sgml/typeconv.sgml @@ -0,0 +1,1262 @@ + + + +Type Conversion + + + data type + conversion + + + +SQL statements can, intentionally or not, require +the mixing of different data types in the same expression. +PostgreSQL has extensive facilities for +evaluating mixed-type expressions. + + + +In many cases a user does not need +to understand the details of the type conversion mechanism. +However, implicit conversions done by PostgreSQL +can affect the results of a query. When necessary, these results +can be tailored by using explicit type conversion. + + + +This chapter introduces the PostgreSQL +type conversion mechanisms and conventions. +Refer to the relevant sections in and +for more information on specific data types and allowed functions and +operators. + + + +Overview + + +SQL is a strongly typed language. That is, every data item +has an associated data type which determines its behavior and allowed usage. +PostgreSQL has an extensible type system that is +more general and flexible than other SQL implementations. +Hence, most type conversion behavior in PostgreSQL +is governed by general rules rather than by ad hoc +heuristics. This allows the use of mixed-type expressions even with +user-defined types. + + + +The PostgreSQL scanner/parser divides lexical +elements into five fundamental categories: integers, non-integer numbers, +strings, identifiers, and key words. Constants of most non-numeric types are +first classified as strings. The SQL language definition +allows specifying type names with strings, and this mechanism can be used in +PostgreSQL to start the parser down the correct +path. For example, the query: + + +SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; + + label | value +--------+------- + Origin | (0,0) +(1 row) + + +has two literal constants, of type text and point. +If a type is not specified for a string literal, then the placeholder type +unknown is assigned initially, to be resolved in later +stages as described below. + + + +There are four fundamental SQL constructs requiring +distinct type conversion rules in the PostgreSQL +parser: + + + + +Function calls + + + +Much of the PostgreSQL type system is built around a +rich set of functions. Functions can have one or more arguments. +Since PostgreSQL permits function +overloading, the function name alone does not uniquely identify the function +to be called; the parser must select the right function based on the data +types of the supplied arguments. + + + + + +Operators + + + +PostgreSQL allows expressions with +prefix (one-argument) operators, +as well as infix (two-argument) operators. Like functions, operators can +be overloaded, so the same problem of selecting the right operator +exists. + + + + + +Value Storage + + + +SQL INSERT and UPDATE statements place the results of +expressions into a table. The expressions in the statement must be matched up +with, and perhaps converted to, the types of the target columns. + + + + + +UNION, CASE, and related constructs + + + +Since all query results from a unionized SELECT statement +must appear in a single set of columns, the types of the results of each +SELECT clause must be matched up and converted to a uniform set. +Similarly, the result expressions of a CASE construct must be +converted to a common type so that the CASE expression as a whole +has a known output type. Some other constructs, such +as ARRAY[] and the GREATEST +and LEAST functions, likewise require determination of a +common type for several subexpressions. + + + + + + + +The system catalogs store information about which conversions, or +casts, exist between which data types, and how to +perform those conversions. Additional casts can be added by the user +with the +command. (This is usually +done in conjunction with defining new data types. The set of casts +between built-in types has been carefully crafted and is best not +altered.) + + + + data type + category + + + +An additional heuristic provided by the parser allows improved determination +of the proper casting behavior among groups of types that have implicit casts. +Data types are divided into several basic type +categories, including boolean, numeric, +string, bitstring, datetime, +timespan, geometric, network, and +user-defined. (For a list see ; +but note it is also possible to create custom type categories.) Within each +category there can be one or more preferred types, which +are preferred when there is a choice of possible types. With careful selection +of preferred types and available implicit casts, it is possible to ensure that +ambiguous expressions (those with multiple candidate parsing solutions) can be +resolved in a useful way. + + + +All type conversion rules are designed with several principles in mind: + + + + +Implicit conversions should never have surprising or unpredictable outcomes. + + + + + +There should be no extra overhead in the parser or executor +if a query does not need implicit type conversion. +That is, if a query is well-formed and the types already match, then the query should execute +without spending extra time in the parser and without introducing unnecessary implicit conversion +calls in the query. + + + + + +Additionally, if a query usually requires an implicit conversion for a function, and +if then the user defines a new function with the correct argument types, the parser +should use this new function and no longer do implicit conversion to use the old function. + + + + + + + + +Operators + + + operator + type resolution in an invocation + + + + The specific operator that is referenced by an operator expression + is determined using the following procedure. + Note that this procedure is indirectly affected + by the precedence of the operators involved, since that will determine + which sub-expressions are taken to be the inputs of which operators. + See for more information. + + + +Operator Type Resolution + + + +Select the operators to be considered from the +pg_operator system catalog. If a non-schema-qualified +operator name was used (the usual case), the operators +considered are those with the matching name and argument count that are +visible in the current search path (see ). +If a qualified operator name was given, only operators in the specified +schema are considered. + + + + + +If the search path finds multiple operators with identical argument types, +only the one appearing earliest in the path is considered. Operators with +different argument types are considered on an equal footing regardless of +search path position. + + + + + + + +Check for an operator accepting exactly the input argument types. +If one exists (there can be only one exact match in the set of +operators considered), use it. Lack of an exact match creates a security +hazard when calling, via qualified name + + + + The hazard does not arise with a non-schema-qualified name, because a + search path containing schemas that permit untrusted users to create + objects is not a secure schema usage + pattern. + + +(not typical), any operator found in a schema that permits untrusted users to +create objects. In such situations, cast arguments to force an exact match. + + + + + +If one argument of a binary operator invocation is of the unknown type, +then assume it is the same type as the other argument for this check. +Invocations involving two unknown inputs, or a prefix operator +with an unknown input, will never find a match at this step. + + + + +If one argument of a binary operator invocation is of the unknown +type and the other is of a domain type, next check to see if there is an +operator accepting exactly the domain's base type on both sides; if so, use it. + + + + + + + +Look for the best match. + + + + +Discard candidate operators for which the input types do not match +and cannot be converted (using an implicit conversion) to match. +unknown literals are +assumed to be convertible to anything for this purpose. If only one +candidate remains, use it; else continue to the next step. + + + + +If any input argument is of a domain type, treat it as being of the +domain's base type for all subsequent steps. This ensures that domains +act like their base types for purposes of ambiguous-operator resolution. + + + + +Run through all candidates and keep those with the most exact matches +on input types. Keep all candidates if none have exact matches. +If only one candidate remains, use it; else continue to the next step. + + + + +Run through all candidates and keep those that accept preferred types (of the +input data type's type category) at the most positions where type conversion +will be required. +Keep all candidates if none accept preferred types. +If only one candidate remains, use it; else continue to the next step. + + + + +If any input arguments are unknown, check the type +categories accepted at those argument positions by the remaining +candidates. At each position, select the string category +if any +candidate accepts that category. (This bias towards string is appropriate +since an unknown-type literal looks like a string.) Otherwise, if +all the remaining candidates accept the same type category, select that +category; otherwise fail because the correct choice cannot be deduced +without more clues. Now discard +candidates that do not accept the selected type category. Furthermore, +if any candidate accepts a preferred type in that category, +discard candidates that accept non-preferred types for that argument. +Keep all candidates if none survive these tests. +If only one candidate remains, use it; else continue to the next step. + + + + +If there are both unknown and known-type arguments, and all +the known-type arguments have the same type, assume that the +unknown arguments are also of that type, and check which +candidates can accept that type at the unknown-argument +positions. If exactly one candidate passes this test, use it. +Otherwise, fail. + + + + + + + +Some examples follow. + + + +Square Root Operator Type Resolution + + +There is only one square root operator (prefix |/) +defined in the standard catalog, and it takes an argument of type +double precision. +The scanner assigns an initial type of integer to the argument +in this query expression: + +SELECT |/ 40 AS "square root of 40"; + square root of 40 +------------------- + 6.324555320336759 +(1 row) + + +So the parser does a type conversion on the operand and the query +is equivalent to: + + +SELECT |/ CAST(40 AS double precision) AS "square root of 40"; + + + + + +String Concatenation Operator Type Resolution + + +A string-like syntax is used for working with string types and for +working with complex extension types. +Strings with unspecified type are matched with likely operator candidates. + + + +An example with one unspecified argument: + +SELECT text 'abc' || 'def' AS "text and unknown"; + + text and unknown +------------------ + abcdef +(1 row) + + + + +In this case the parser looks to see if there is an operator taking text +for both arguments. Since there is, it assumes that the second argument should +be interpreted as type text. + + + +Here is a concatenation of two values of unspecified types: + +SELECT 'abc' || 'def' AS "unspecified"; + + unspecified +------------- + abcdef +(1 row) + + + + +In this case there is no initial hint for which type to use, since no types +are specified in the query. So, the parser looks for all candidate operators +and finds that there are candidates accepting both string-category and +bit-string-category inputs. Since string category is preferred when available, +that category is selected, and then the +preferred type for strings, text, is used as the specific +type to resolve the unknown-type literals as. + + + + +Absolute-Value and Negation Operator Type Resolution + + +The PostgreSQL operator catalog has several +entries for the prefix operator @, all of which implement +absolute-value operations for various numeric data types. One of these +entries is for type float8, which is the preferred type in +the numeric category. Therefore, PostgreSQL +will use that entry when faced with an unknown input: + +SELECT @ '-4.5' AS "abs"; + abs +----- + 4.5 +(1 row) + +Here the system has implicitly resolved the unknown-type literal as type +float8 before applying the chosen operator. We can verify that +float8 and not some other type was used: + +SELECT @ '-4.5e500' AS "abs"; + +ERROR: "-4.5e500" is out of range for type double precision + + + + +On the other hand, the prefix operator ~ (bitwise negation) +is defined only for integer data types, not for float8. So, if we +try a similar case with ~, we get: + +SELECT ~ '20' AS "negation"; + +ERROR: operator is not unique: ~ "unknown" +HINT: Could not choose a best candidate operator. You might need to add +explicit type casts. + +This happens because the system cannot decide which of the several +possible ~ operators should be preferred. We can help +it out with an explicit cast: + +SELECT ~ CAST('20' AS int8) AS "negation"; + + negation +---------- + -21 +(1 row) + + + + + +Array Inclusion Operator Type Resolution + + +Here is another example of resolving an operator with one known and one +unknown input: + +SELECT array[1,2] <@ '{1,2,3}' as "is subset"; + + is subset +----------- + t +(1 row) + +The PostgreSQL operator catalog has several +entries for the infix operator <@, but the only two that +could possibly accept an integer array on the left-hand side are +array inclusion (anyarray <@ anyarray) +and range inclusion (anyelement <@ anyrange). +Since none of these polymorphic pseudo-types (see ) are considered preferred, the parser cannot +resolve the ambiguity on that basis. +However, tells +it to assume that the unknown-type literal is of the same type as the other +input, that is, integer array. Now only one of the two operators can match, +so array inclusion is selected. (Had range inclusion been selected, we would +have gotten an error, because the string does not have the right format to be +a range literal.) + + + + +Custom Operator on a Domain Type + + +Users sometimes try to declare operators applying just to a domain type. +This is possible but is not nearly as useful as it might seem, because the +operator resolution rules are designed to select operators applying to the +domain's base type. As an example consider + +CREATE DOMAIN mytext AS text CHECK(...); +CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...; +CREATE OPERATOR = (procedure=mytext_eq_text, leftarg=mytext, rightarg=text); +CREATE TABLE mytable (val mytext); + +SELECT * FROM mytable WHERE val = 'foo'; + +This query will not use the custom operator. The parser will first see if +there is a mytext = mytext operator +(), which there is not; +then it will consider the domain's base type text, and see if +there is a text = text operator +(), which there is; +so it resolves the unknown-type literal as text and +uses the text = text operator. +The only way to get the custom operator to be used is to explicitly cast +the literal: + +SELECT * FROM mytable WHERE val = text 'foo'; + +so that the mytext = text operator is found +immediately according to the exact-match rule. If the best-match rules +are reached, they actively discriminate against operators on domain types. +If they did not, such an operator would create too many ambiguous-operator +failures, because the casting rules always consider a domain as castable +to or from its base type, and so the domain operator would be considered +usable in all the same cases as a similarly-named operator on the base type. + + + + + + +Functions + + + function + type resolution in an invocation + + + + The specific function that is referenced by a function call + is determined using the following procedure. + + + +Function Type Resolution + + + +Select the functions to be considered from the +pg_proc system catalog. If a non-schema-qualified +function name was used, the functions +considered are those with the matching name and argument count that are +visible in the current search path (see ). +If a qualified function name was given, only functions in the specified +schema are considered. + + + + + +If the search path finds multiple functions of identical argument types, +only the one appearing earliest in the path is considered. Functions of +different argument types are considered on an equal footing regardless of +search path position. + + + + +If a function is declared with a VARIADIC array parameter, and +the call does not use the VARIADIC keyword, then the function +is treated as if the array parameter were replaced by one or more occurrences +of its element type, as needed to match the call. After such expansion the +function might have effective argument types identical to some non-variadic +function. In that case the function appearing earlier in the search path is +used, or if the two functions are in the same schema, the non-variadic one is +preferred. + + +This creates a security hazard when calling, via qualified name + + + + The hazard does not arise with a non-schema-qualified name, because a + search path containing schemas that permit untrusted users to create + objects is not a secure schema usage + pattern. + + , +a variadic function found in a schema that permits untrusted users to create +objects. A malicious user can take control and execute arbitrary SQL +functions as though you executed them. Substitute a call bearing +the VARIADIC keyword, which bypasses this hazard. Calls +populating VARIADIC "any" parameters often have no +equivalent formulation containing the VARIADIC keyword. To +issue those calls safely, the function's schema must permit only trusted users +to create objects. + + + + +Functions that have default values for parameters are considered to match any +call that omits zero or more of the defaultable parameter positions. If more +than one such function matches a call, the one appearing earliest in the +search path is used. If there are two or more such functions in the same +schema with identical parameter types in the non-defaulted positions (which is +possible if they have different sets of defaultable parameters), the system +will not be able to determine which to prefer, and so an ambiguous +function call error will result if no better match to the call can be +found. + + +This creates an availability hazard when calling, via qualified +name, any function found in a +schema that permits untrusted users to create objects. A malicious user can +create a function with the name of an existing function, replicating that +function's parameters and appending novel parameters having default values. +This precludes new calls to the original function. To forestall this hazard, +place functions in schemas that permit only trusted users to create objects. + + + + + + + +Check for a function accepting exactly the input argument types. +If one exists (there can be only one exact match in the set of +functions considered), use it. Lack of an exact match creates a security +hazard when calling, via qualified +name, a function found in a +schema that permits untrusted users to create objects. In such situations, +cast arguments to force an exact match. (Cases involving unknown +will never find a match at this step.) + + + + + +If no exact match is found, see if the function call appears +to be a special type conversion request. This happens if the function call +has just one argument and the function name is the same as the (internal) +name of some data type. Furthermore, the function argument must be either +an unknown-type literal, or a type that is binary-coercible to the named +data type, or a type that could be converted to the named data type by +applying that type's I/O functions (that is, the conversion is either to or +from one of the standard string types). When these conditions are met, +the function call is treated as a form of CAST specification. + + + The reason for this step is to support function-style cast specifications + in cases where there is not an actual cast function. If there is a cast + function, it is conventionally named after its output type, and so there + is no need to have a special case. See + + for additional commentary. + + + + + + +Look for the best match. + + + + +Discard candidate functions for which the input types do not match +and cannot be converted (using an implicit conversion) to match. +unknown literals are +assumed to be convertible to anything for this purpose. If only one +candidate remains, use it; else continue to the next step. + + + + +If any input argument is of a domain type, treat it as being of the +domain's base type for all subsequent steps. This ensures that domains +act like their base types for purposes of ambiguous-function resolution. + + + + +Run through all candidates and keep those with the most exact matches +on input types. Keep all candidates if none have exact matches. +If only one candidate remains, use it; else continue to the next step. + + + + +Run through all candidates and keep those that accept preferred types (of the +input data type's type category) at the most positions where type conversion +will be required. +Keep all candidates if none accept preferred types. +If only one candidate remains, use it; else continue to the next step. + + + + +If any input arguments are unknown, check the type categories +accepted +at those argument positions by the remaining candidates. At each position, +select the string category if any candidate accepts that category. +(This bias towards string +is appropriate since an unknown-type literal looks like a string.) +Otherwise, if all the remaining candidates accept the same type category, +select that category; otherwise fail because +the correct choice cannot be deduced without more clues. +Now discard candidates that do not accept the selected type category. +Furthermore, if any candidate accepts a preferred type in that category, +discard candidates that accept non-preferred types for that argument. +Keep all candidates if none survive these tests. +If only one candidate remains, use it; else continue to the next step. + + + + +If there are both unknown and known-type arguments, and all +the known-type arguments have the same type, assume that the +unknown arguments are also of that type, and check which +candidates can accept that type at the unknown-argument +positions. If exactly one candidate passes this test, use it. +Otherwise, fail. + + + + + + + +Note that the best match rules are identical for operator and +function type resolution. +Some examples follow. + + + +Rounding Function Argument Type Resolution + + +There is only one round function that takes two +arguments; it takes a first argument of type numeric and +a second argument of type integer. +So the following query automatically converts +the first argument of type integer to +numeric: + + +SELECT round(4, 4); + + round +-------- + 4.0000 +(1 row) + + +That query is actually transformed by the parser to: + +SELECT round(CAST (4 AS numeric), 4); + + + + +Since numeric constants with decimal points are initially assigned the +type numeric, the following query will require no type +conversion and therefore might be slightly more efficient: + +SELECT round(4.0, 4); + + + + + +Variadic Function Resolution + + + +CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int + LANGUAGE sql AS 'SELECT 1'; +CREATE FUNCTION + + +This function accepts, but does not require, the VARIADIC keyword. It +tolerates both integer and numeric arguments: + + +SELECT public.variadic_example(0), + public.variadic_example(0.0), + public.variadic_example(VARIADIC array[0.0]); + variadic_example | variadic_example | variadic_example +------------------+------------------+------------------ + 1 | 1 | 1 +(1 row) + + +However, the first and second calls will prefer more-specific functions, if +available: + + +CREATE FUNCTION public.variadic_example(numeric) RETURNS int + LANGUAGE sql AS 'SELECT 2'; +CREATE FUNCTION + +CREATE FUNCTION public.variadic_example(int) RETURNS int + LANGUAGE sql AS 'SELECT 3'; +CREATE FUNCTION + +SELECT public.variadic_example(0), + public.variadic_example(0.0), + public.variadic_example(VARIADIC array[0.0]); + variadic_example | variadic_example | variadic_example +------------------+------------------+------------------ + 3 | 2 | 1 +(1 row) + + +Given the default configuration and only the first function existing, the +first and second calls are insecure. Any user could intercept them by +creating the second or third function. By matching the argument type exactly +and using the VARIADIC keyword, the third call is secure. + + + + +Substring Function Type Resolution + + +There are several substr functions, one of which +takes types text and integer. If called +with a string constant of unspecified type, the system chooses the +candidate function that accepts an argument of the preferred category +string (namely of type text). + + +SELECT substr('1234', 3); + + substr +-------- + 34 +(1 row) + + + + +If the string is declared to be of type varchar, as might be the case +if it comes from a table, then the parser will try to convert it to become text: + +SELECT substr(varchar '1234', 3); + + substr +-------- + 34 +(1 row) + + +This is transformed by the parser to effectively become: + +SELECT substr(CAST (varchar '1234' AS text), 3); + + + + + +The parser learns from the pg_cast catalog that +text and varchar +are binary-compatible, meaning that one can be passed to a function that +accepts the other without doing any physical conversion. Therefore, no +type conversion call is really inserted in this case. + + + + + +And, if the function is called with an argument of type integer, +the parser will try to convert that to text: + +SELECT substr(1234, 3); +ERROR: function substr(integer, integer) does not exist +HINT: No function matches the given name and argument types. You might need +to add explicit type casts. + + +This does not work because integer does not have an implicit cast +to text. An explicit cast will work, however: + +SELECT substr(CAST (1234 AS text), 3); + + substr +-------- + 34 +(1 row) + + + + + + + +Value Storage + + + Values to be inserted into a table are converted to the destination + column's data type according to the + following steps. + + + +Value Storage Type Conversion + + + +Check for an exact match with the target. + + + + + +Otherwise, try to convert the expression to the target type. This is possible +if an assignment cast between the two types is registered in the +pg_cast catalog (see ). +Alternatively, if the expression is an unknown-type literal, the contents of +the literal string will be fed to the input conversion routine for the target +type. + + + + + +Check to see if there is a sizing cast for the target type. A sizing +cast is a cast from that type to itself. If one is found in the +pg_cast catalog, apply it to the expression before storing +into the destination column. The implementation function for such a cast +always takes an extra parameter of type integer, which receives +the destination column's atttypmod value (typically its +declared length, although the interpretation of atttypmod +varies for different data types), and it may take a third boolean +parameter that says whether the cast is explicit or implicit. The cast +function +is responsible for applying any length-dependent semantics such as size +checking or truncation. + + + + + + +<type>character</type> Storage Type Conversion + + +For a target column declared as character(20) the following +statement shows that the stored value is sized correctly: + + +CREATE TABLE vv (v character(20)); +INSERT INTO vv SELECT 'abc' || 'def'; +SELECT v, octet_length(v) FROM vv; + + v | octet_length +----------------------+-------------- + abcdef | 20 +(1 row) + + + + +What has really happened here is that the two unknown literals are resolved +to text by default, allowing the || operator +to be resolved as text concatenation. Then the text +result of the operator is converted to bpchar (blank-padded +char, the internal name of the character data type) to match the target +column type. (Since the conversion from text to +bpchar is binary-coercible, this conversion does +not insert any real function call.) Finally, the sizing function +bpchar(bpchar, integer, boolean) is found in the system catalog +and applied to the operator's result and the stored column length. This +type-specific function performs the required length check and addition of +padding spaces. + + + + + +<literal>UNION</literal>, <literal>CASE</literal>, and Related Constructs + + + UNION + determination of result type + + + + CASE + determination of result type + + + + ARRAY + determination of result type + + + + VALUES + determination of result type + + + + GREATEST + determination of result type + + + + LEAST + determination of result type + + + +SQL UNION constructs must match up possibly dissimilar +types to become a single result set. The resolution algorithm is +applied separately to each output column of a union query. The +INTERSECT and EXCEPT constructs resolve +dissimilar types in the same way as UNION. +Some other constructs, including +CASE, ARRAY, VALUES, +and the GREATEST and LEAST +functions, use the identical +algorithm to match up their component expressions and select a result +data type. + + + +Type Resolution for <literal>UNION</literal>, <literal>CASE</literal>, +and Related Constructs + + + +If all inputs are of the same type, and it is not unknown, +resolve as that type. + + + + + +If any input is of a domain type, treat it as being of the +domain's base type for all subsequent steps. + + + Somewhat like the treatment of domain inputs for operators and + functions, this behavior allows a domain type to be preserved through + a UNION or similar construct, so long as the user is + careful to ensure that all inputs are implicitly or explicitly of that + exact type. Otherwise the domain's base type will be used. + + + + + + + +If all inputs are of type unknown, resolve as type +text (the preferred type of the string category). +Otherwise, unknown inputs are ignored for the purposes +of the remaining rules. + + + + + +If the non-unknown inputs are not all of the same type category, fail. + + + + + +Select the first non-unknown input type as the candidate type, +then consider each other non-unknown input type, left to right. + + + For historical reasons, CASE treats + its ELSE clause (if any) as the first + input, with the THEN clauses(s) considered after + that. In all other cases, left to right means the order + in which the expressions appear in the query text. + + +If the candidate type can be implicitly converted to the other type, +but not vice-versa, select the other type as the new candidate type. +Then continue considering the remaining inputs. If, at any stage of this +process, a preferred type is selected, stop considering additional +inputs. + + + + + +Convert all inputs to the final candidate type. Fail if there is not an +implicit conversion from a given input type to the candidate type. + + + + + +Some examples follow. + + + +Type Resolution with Underspecified Types in a Union + + + +SELECT text 'a' AS "text" UNION SELECT 'b'; + + text +------ + a + b +(2 rows) + +Here, the unknown-type literal 'b' will be resolved to type text. + + + + +Type Resolution in a Simple Union + + + +SELECT 1.2 AS "numeric" UNION SELECT 1; + + numeric +--------- + 1 + 1.2 +(2 rows) + +The literal 1.2 is of type numeric, +and the integer value 1 can be cast implicitly to +numeric, so that type is used. + + + + +Type Resolution in a Transposed Union + + + +SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); + + real +------ + 1 + 2.2 +(2 rows) + +Here, since type real cannot be implicitly cast to integer, +but integer can be implicitly cast to real, the union +result type is resolved as real. + + + + +Type Resolution in a Nested Union + + + +SELECT NULL UNION SELECT NULL UNION SELECT 1; + +ERROR: UNION types text and integer cannot be matched + +This failure occurs because PostgreSQL treats +multiple UNIONs as a nest of pairwise operations; +that is, this input is the same as + +(SELECT NULL UNION SELECT NULL) UNION SELECT 1; + +The inner UNION is resolved as emitting +type text, according to the rules given above. Then the +outer UNION has inputs of types text +and integer, leading to the observed error. The problem +can be fixed by ensuring that the leftmost UNION +has at least one input of the desired result type. + + + +INTERSECT and EXCEPT operations are +likewise resolved pairwise. However, the other constructs described in this +section consider all of their inputs in one resolution step. + + + + + +<literal>SELECT</literal> Output Columns + + + SELECT + determination of result type + + + +The rules given in the preceding sections will result in assignment +of non-unknown data types to all expressions in an SQL query, +except for unspecified-type literals that appear as simple output +columns of a SELECT command. For example, in + + +SELECT 'Hello World'; + + +there is nothing to identify what type the string literal should be +taken as. In this situation PostgreSQL will fall back +to resolving the literal's type as text. + + + +When the SELECT is one arm of a UNION +(or INTERSECT or EXCEPT) construct, or when it +appears within INSERT ... SELECT, this rule is not applied +since rules given in preceding sections take precedence. The type of an +unspecified-type literal can be taken from the other UNION arm +in the first case, or from the destination column in the second case. + + + +RETURNING lists are treated the same as SELECT +output lists for this purpose. + + + + + Prior to PostgreSQL 10, this rule did not exist, and + unspecified-type literals in a SELECT output list were + left as type unknown. That had assorted bad consequences, + so it's been changed. + + + + + diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml new file mode 100644 index 000000000000..fe0bdb75999c --- /dev/null +++ b/doc/src/sgml/user-manag.sgml @@ -0,0 +1,672 @@ + + + + Database Roles + + + PostgreSQL manages database access permissions + using the concept of roles. A role can be thought of as + either a database user, or a group of database users, depending on how + the role is set up. Roles can own database objects (for example, tables + and functions) and can assign privileges on those objects to other roles to + control who has access to which objects. Furthermore, it is possible + to grant membership in a role to another role, thus + allowing the member role to use privileges assigned to another role. + + + + The concept of roles subsumes the concepts of users and + groups. In PostgreSQL versions + before 8.1, users and groups were distinct kinds of entities, but now + there are only roles. Any role can act as a user, a group, or both. + + + + This chapter describes how to create and manage roles. + More information about the effects of role privileges on various + database objects can be found in . + + + + Database Roles + + + role + + + + user + + + + CREATE ROLE + + + + DROP ROLE + + + + Database roles are conceptually completely separate from + operating system users. In practice it might be convenient to + maintain a correspondence, but this is not required. Database roles + are global across a database cluster installation (and not + per individual database). To create a role use the CREATE ROLE SQL command: + +CREATE ROLE name; + + name follows the rules for SQL + identifiers: either unadorned without special characters, or + double-quoted. (In practice, you will usually want to add additional + options, such as LOGIN, to the command. More details appear + below.) To remove an existing role, use the analogous + DROP ROLE command: + +DROP ROLE name; + + + + + createuser + + + + dropuser + + + + For convenience, the programs + and are provided as wrappers + around these SQL commands that can be called from the shell command + line: + +createuser name +dropuser name + + + + + To determine the set of existing roles, examine the pg_roles + system catalog, for example + +SELECT rolname FROM pg_roles; + + The program's \du meta-command + is also useful for listing the existing roles. + + + + In order to bootstrap the database system, a freshly initialized + system always contains one predefined role. This role is always + a superuser, and by default (unless altered when running + initdb) it will have the same name as the + operating system user that initialized the database + cluster. Customarily, this role will be named + postgres. In order to create more roles you + first have to connect as this initial role. + + + + Every connection to the database server is made using the name of some + particular role, and this role determines the initial access privileges for + commands issued in that connection. + The role name to use for a particular database + connection is indicated by the client that is initiating the + connection request in an application-specific fashion. For example, + the psql program uses the + command line option to indicate the role to + connect as. Many applications assume the name of the current + operating system user by default (including + createuser and psql). Therefore it + is often convenient to maintain a naming correspondence between + roles and operating system users. + + + + The set of database roles a given client connection can connect as + is determined by the client authentication setup, as explained in + . (Thus, a client is not + limited to connect as the role matching + its operating system user, just as a person's login name + need not match his or her real name.) Since the role + identity determines the set of privileges available to a connected + client, it is important to carefully configure privileges when setting up + a multiuser environment. + + + + + Role Attributes + + + A database role can have a number of attributes that define its + privileges and interact with the client authentication system. + + + + login privilegelogin privilege + + + Only roles that have the LOGIN attribute can be used + as the initial role name for a database connection. A role with + the LOGIN attribute can be considered the same + as a database user. To create a role with login privilege, + use either: + +CREATE ROLE name LOGIN; +CREATE USER name; + + (CREATE USER is equivalent to CREATE ROLE + except that CREATE USER includes LOGIN by + default, while CREATE ROLE does not.) + + + + + + superuser statussuperuser + + + A database superuser bypasses all permission checks, except the right + to log in. This is a dangerous privilege and should not be used + carelessly; it is best to do most of your work as a role that is not a + superuser. To create a new database superuser, use CREATE + ROLE name SUPERUSER. You must do + this as a role that is already a superuser. + + + + + + database creationdatabaseprivilege to create + + + A role must be explicitly given permission to create databases + (except for superusers, since those bypass all permission + checks). To create such a role, use CREATE ROLE + name CREATEDB. + + + + + + role creationroleprivilege to create + + + A role must be explicitly given permission to create more roles + (except for superusers, since those bypass all permission + checks). To create such a role, use CREATE ROLE + name CREATEROLE. + A role with CREATEROLE privilege can alter and drop + other roles, too, as well as grant or revoke membership in them. + However, to create, alter, drop, or change membership of a + superuser role, superuser status is required; + CREATEROLE is insufficient for that. + + + + + + initiating replicationroleprivilege to initiate replication + + + A role must explicitly be given permission to initiate streaming + replication (except for superusers, since those bypass all permission + checks). A role used for streaming replication must + have LOGIN permission as well. To create such a role, use + CREATE ROLE name REPLICATION + LOGIN. + + + + + + passwordpassword + + + A password is only significant if the client authentication + method requires the user to supply a password when connecting + to the database. The and + authentication methods + make use of passwords. Database passwords are separate from + operating system passwords. Specify a password upon role + creation with CREATE ROLE + name PASSWORD 'string'. + + + + + + A role's attributes can be modified after creation with + ALTER ROLE.ALTER ROLE + See the reference pages for the + and commands for details. + + + + + It is good practice to create a role that has the CREATEDB + and CREATEROLE privileges, but is not a superuser, and then + use this role for all routine management of databases and roles. This + approach avoids the dangers of operating as a superuser for tasks that + do not really require it. + + + + + A role can also have role-specific defaults for many of the run-time + configuration settings described in . For example, if for some reason you + want to disable index scans (hint: not a good idea) anytime you + connect, you can use: + +ALTER ROLE myname SET enable_indexscan TO off; + + This will save the setting (but not set it immediately). In + subsequent connections by this role it will appear as though + SET enable_indexscan TO off had been executed + just before the session started. + You can still alter this setting during the session; it will only + be the default. To remove a role-specific default setting, use + ALTER ROLE rolename RESET varname. + Note that role-specific defaults attached to roles without + LOGIN privilege are fairly useless, since they will never + be invoked. + + + + + Role Membership + + + rolemembership in + + + + It is frequently convenient to group users together to ease + management of privileges: that way, privileges can be granted to, or + revoked from, a group as a whole. In PostgreSQL + this is done by creating a role that represents the group, and then + granting membership in the group role to individual user + roles. + + + + To set up a group role, first create the role: + +CREATE ROLE name; + + Typically a role being used as a group would not have the LOGIN + attribute, though you can set it if you wish. + + + + Once the group role exists, you can add and remove members using the + GRANT and + REVOKE commands: + +GRANT group_role TO role1, ... ; +REVOKE group_role FROM role1, ... ; + + You can grant membership to other group roles, too (since there isn't + really any distinction between group roles and non-group roles). The + database will not let you set up circular membership loops. Also, + it is not permitted to grant membership in a role to + PUBLIC. + + + + The members of a group role can use the privileges of the role in two + ways. First, every member of a group can explicitly do + SET ROLE to + temporarily become the group role. In this state, the + database session has access to the privileges of the group role rather + than the original login role, and any database objects created are + considered owned by the group role not the login role. Second, member + roles that have the INHERIT attribute automatically have use + of the privileges of roles of which they are members, including any + privileges inherited by those roles. + As an example, suppose we have done: + +CREATE ROLE joe LOGIN INHERIT; +CREATE ROLE admin NOINHERIT; +CREATE ROLE wheel NOINHERIT; +GRANT admin TO joe; +GRANT wheel TO admin; + + Immediately after connecting as role joe, a database + session will have use of privileges granted directly to joe + plus any privileges granted to admin, because joe + inherits admin's privileges. However, privileges + granted to wheel are not available, because even though + joe is indirectly a member of wheel, the + membership is via admin which has the NOINHERIT + attribute. After: + +SET ROLE admin; + + the session would have use of only those privileges granted to + admin, and not those granted to joe. After: + +SET ROLE wheel; + + the session would have use of only those privileges granted to + wheel, and not those granted to either joe + or admin. The original privilege state can be restored + with any of: + +SET ROLE joe; +SET ROLE NONE; +RESET ROLE; + + + + + + The SET ROLE command always allows selecting any role + that the original login role is directly or indirectly a member of. + Thus, in the above example, it is not necessary to become + admin before becoming wheel. + + + + + + In the SQL standard, there is a clear distinction between users and roles, + and users do not automatically inherit privileges while roles do. This + behavior can be obtained in PostgreSQL by giving + roles being used as SQL roles the INHERIT attribute, while + giving roles being used as SQL users the NOINHERIT attribute. + However, PostgreSQL defaults to giving all roles + the INHERIT attribute, for backward compatibility with pre-8.1 + releases in which users always had use of permissions granted to groups + they were members of. + + + + + The role attributes LOGIN, SUPERUSER, + CREATEDB, and CREATEROLE can be thought of as + special privileges, but they are never inherited as ordinary privileges + on database objects are. You must actually SET ROLE to a + specific role having one of these attributes in order to make use of + the attribute. Continuing the above example, we might choose to + grant CREATEDB and CREATEROLE to the + admin role. Then a session connecting as role joe + would not have these privileges immediately, only after doing + SET ROLE admin. + + + + + + + To destroy a group role, use DROP ROLE: + +DROP ROLE name; + + Any memberships in the group role are automatically revoked (but the + member roles are not otherwise affected). + + + + + Dropping Roles + + + Because roles can own database objects and can hold privileges + to access other objects, dropping a role is often not just a matter of a + quick DROP ROLE. Any objects owned by the role must + first be dropped or reassigned to other owners; and any permissions + granted to the role must be revoked. + + + + Ownership of objects can be transferred one at a time + using ALTER commands, for example: + +ALTER TABLE bobs_table OWNER TO alice; + + Alternatively, the REASSIGN OWNED command can be + used to reassign ownership of all objects owned by the role-to-be-dropped + to a single other role. Because REASSIGN OWNED cannot access + objects in other databases, it is necessary to run it in each database + that contains objects owned by the role. (Note that the first + such REASSIGN OWNED will change the ownership of any + shared-across-databases objects, that is databases or tablespaces, that + are owned by the role-to-be-dropped.) + + + + Once any valuable objects have been transferred to new owners, any + remaining objects owned by the role-to-be-dropped can be dropped with + the DROP OWNED command. Again, this command cannot + access objects in other databases, so it is necessary to run it in each + database that contains objects owned by the role. Also, DROP + OWNED will not drop entire databases or tablespaces, so it is + necessary to do that manually if the role owns any databases or + tablespaces that have not been transferred to new owners. + + + + DROP OWNED also takes care of removing any privileges granted + to the target role for objects that do not belong to it. + Because REASSIGN OWNED does not touch such objects, it's + typically necessary to run both REASSIGN OWNED + and DROP OWNED (in that order!) to fully remove the + dependencies of a role to be dropped. + + + + In short then, the most general recipe for removing a role that has been + used to own objects is: + + +REASSIGN OWNED BY doomed_role TO successor_role; +DROP OWNED BY doomed_role; +-- repeat the above commands in each database of the cluster +DROP ROLE doomed_role; + + + + When not all owned objects are to be transferred to the same successor + owner, it's best to handle the exceptions manually and then perform + the above steps to mop up. + + + + If DROP ROLE is attempted while dependent objects still + remain, it will issue messages identifying which objects need to be + reassigned or dropped. + + + + + Predefined Roles + + + role + + + + PostgreSQL provides a set of predefined roles + that provide access to certain, commonly needed, privileged capabilities + and information. Administrators (including roles that have the + CREATEROLE privilege) can GRANT these + roles to users and/or other roles in their environment, providing those + users with access to the specified capabilities and information. + + + + The predefined roles are described in . + Note that the specific permissions for each of the roles may change in + the future as additional capabilities are added. Administrators + should monitor the release notes for changes. + + + + Predefined Roles + + + + + + Role + Allowed Access + + + + + pg_read_all_data + Read all data (tables, views, sequences), as if having SELECT + rights on those objects, and USAGE rights on all schemas, even without + having it explicitly. This role does not have the role attribute + BYPASSRLS set. If RLS is being used, an administrator + may wish to set BYPASSRLS on roles which this role is + GRANTed to. + + + pg_write_all_data + Write all data (tables, views, sequences), as if having INSERT, + UPDATE, and DELETE rights on those objects, and USAGE rights on all + schemas, even without having it explicitly. This role does not have the + role attribute BYPASSRLS set. If RLS is being used, + an administrator may wish to set BYPASSRLS on roles + which this role is GRANTed to. + + + pg_read_all_settings + Read all configuration variables, even those normally visible only to + superusers. + + + pg_read_all_stats + Read all pg_stat_* views and use various statistics related extensions, + even those normally visible only to superusers. + + + pg_stat_scan_tables + Execute monitoring functions that may take ACCESS SHARE locks on tables, + potentially for a long time. + + + pg_monitor + Read/execute various monitoring views and functions. + This role is a member of pg_read_all_settings, + pg_read_all_stats and + pg_stat_scan_tables. + + + pg_database_owner + None. Membership consists, implicitly, of the current database owner. + + + pg_signal_backend + Signal another backend to cancel a query or terminate its session. + + + pg_read_server_files + Allow reading files from any location the database can access on the server with COPY and + other file-access functions. + + + pg_write_server_files + Allow writing to files in any location the database can access on the server with COPY and + other file-access functions. + + + pg_execute_server_program + Allow executing programs on the database server as the user the database runs as with + COPY and other functions which allow executing a server-side program. + + + +
+ + + The pg_monitor, pg_read_all_settings, + pg_read_all_stats and pg_stat_scan_tables + roles are intended to allow administrators to easily configure a role for the + purpose of monitoring the database server. They grant a set of common privileges + allowing the role to read various useful configuration settings, statistics and + other system information normally restricted to superusers. + + + + The pg_database_owner role has one implicit, + situation-dependent member, namely the owner of the current database. The + role conveys no rights at first. Like any role, it can own objects or + receive grants of access privileges. Consequently, once + pg_database_owner has rights within a template database, + each owner of a database instantiated from that template will exercise those + rights. pg_database_owner cannot be a member of any + role, and it cannot have non-implicit members. + + + + The pg_signal_backend role is intended to allow + administrators to enable trusted, but non-superuser, roles to send signals + to other backends. Currently this role enables sending of signals for + canceling a query on another backend or terminating its session. A user + granted this role cannot however send signals to a backend owned by a + superuser. See . + + + + The pg_read_server_files, pg_write_server_files and + pg_execute_server_program roles are intended to allow administrators to have + trusted, but non-superuser, roles which are able to access files and run programs on the + database server as the user the database runs as. As these roles are able to access any file on + the server file system, they bypass all database-level permission checks when accessing files + directly and they could be used to gain superuser-level access, therefore + great care should be taken when granting these roles to users. + + + + Care should be taken when granting these roles to ensure they are only used where + needed and with the understanding that these roles grant access to privileged + information. + + + + Administrators can grant access to these roles to users using the + GRANT command, for example: + + +GRANT pg_signal_backend TO admin_user; + + + +
+ + + Function Security + + + Functions, triggers and row-level security policies allow users to insert + code into the backend server that other users might execute + unintentionally. Hence, these mechanisms permit users to Trojan + horse others with relative ease. The strongest protection is tight + control over who can define objects. Where that is infeasible, write + queries referring only to objects having trusted owners. Remove + from search_path the public schema and any other schemas + that permit untrusted users to create objects. + + + + Functions run inside the backend + server process with the operating system permissions of the + database server daemon. If the programming language + used for the function allows unchecked memory accesses, it is + possible to change the server's internal data structures. + Hence, among many other things, such functions can circumvent any + system access controls. Function languages that allow such access + are considered untrusted, and + PostgreSQL allows only superusers to + create functions written in those languages. + + + +
diff --git a/doc/src/sgml/uuid-ossp.sgml b/doc/src/sgml/uuid-ossp.sgml new file mode 100644 index 000000000000..359d3c012895 --- /dev/null +++ b/doc/src/sgml/uuid-ossp.sgml @@ -0,0 +1,242 @@ + + + + uuid-ossp + + + uuid-ossp + + + + The uuid-ossp module provides functions to generate universally + unique identifiers (UUIDs) using one of several standard algorithms. There + are also functions to produce certain special UUID constants. + This module is only necessary for special requirements beyond what is + available in core PostgreSQL. See for built-in ways to generate UUIDs. + + + + This module is considered trusted, that is, it can be + installed by non-superusers who have CREATE privilege + on the current database. + + + + <literal>uuid-ossp</literal> Functions + + + shows the functions available to + generate UUIDs. + The relevant standards ITU-T Rec. X.667, ISO/IEC 9834-8:2005, and + RFC 4122 + specify four algorithms for generating UUIDs, identified by the + version numbers 1, 3, 4, and 5. (There is no version 2 algorithm.) + Each of these algorithms could be suitable for a different set of + applications. + + + + Functions for UUID Generation + + + + + Function + + + Description + + + + + + + + uuid_generate_v1 + uuid_generate_v1 () + uuid + + + Generates a version 1 UUID. This involves the MAC + address of the computer and a time stamp. Note that UUIDs of this + kind reveal the identity of the computer that created the identifier + and the time at which it did so, which might make it unsuitable for + certain security-sensitive applications. + + + + + + uuid_generate_v1mc + uuid_generate_v1mc () + uuid + + + Generates a version 1 UUID, but uses a random multicast + MAC address instead of the real MAC address of the computer. + + + + + + uuid_generate_v3 + uuid_generate_v3 ( namespace uuid, name text ) + uuid + + + Generates a version 3 UUID in the given namespace using + the specified input name. The namespace should be one of the special + constants produced by the uuid_ns_*() functions + shown in . (It could be any UUID + in theory.) The name is an identifier in the selected namespace. + + + For example: + + +SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org'); + + + The name parameter will be MD5-hashed, so the cleartext cannot be + derived from the generated UUID. + The generation of UUIDs by this method has no random or + environment-dependent element and is therefore reproducible. + + + + + + uuid_generate_v4 () + uuid + + + Generates a version 4 UUID, which is derived entirely + from random numbers. + + + + + + uuid_generate_v5 ( namespace uuid, name text ) + uuid + + + Generates a version 5 UUID, which works like a version 3 + UUID except that SHA-1 is used as a hashing method. Version 5 should + be preferred over version 3 because SHA-1 is thought to be more secure + than MD5. + + + + +
+ + + Functions Returning UUID Constants + + + + + Function + + + Description + + + + + + + + uuid_nil () + uuid + + + Returns a nil UUID constant, which does not occur as a + real UUID. + + + + + + uuid_ns_dns () + uuid + + + Returns a constant designating the DNS namespace for UUIDs. + + + + + + uuid_ns_url () + uuid + + + Returns a constant designating the URL namespace for UUIDs. + + + + + + uuid_ns_oid () + uuid + + + Returns a constant designating the ISO object identifier (OID) namespace for + UUIDs. (This pertains to ASN.1 OIDs, which are unrelated to the OIDs + used in PostgreSQL.) + + + + + + uuid_ns_x500 () + uuid + + + Returns a constant designating the X.500 distinguished name (DN) + namespace for UUIDs. + + + + +
+
+ + + Building <filename>uuid-ossp</filename> + + + Historically this module depended on the OSSP UUID library, which accounts + for the module's name. While the OSSP UUID library can still be found + at , it is not well + maintained, and is becoming increasingly difficult to port to newer + platforms. uuid-ossp can now be built without the OSSP + library on some platforms. On FreeBSD, NetBSD, and some other BSD-derived + platforms, suitable UUID creation functions are included in the + core libc library. On Linux, macOS, and some other + platforms, suitable functions are provided in the libuuid + library, which originally came from the e2fsprogs project + (though on modern Linux it is considered part + of util-linux-ng). When invoking configure, + specify to use the BSD functions, + or to + use e2fsprogs' libuuid, or + to use the OSSP UUID library. + More than one of these libraries might be available on a particular + machine, so configure does not automatically choose one. + + + + + Author + + + Peter Eisentraut peter_e@gmx.net + + + + +
diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml new file mode 100644 index 000000000000..60f066d24739 --- /dev/null +++ b/doc/src/sgml/wal.sgml @@ -0,0 +1,898 @@ + + + + Reliability and the Write-Ahead Log + + + This chapter explains how the Write-Ahead Log is used to obtain + efficient, reliable operation. + + + + Reliability + + + Reliability is an important property of any serious database + system, and PostgreSQL does everything possible to + guarantee reliable operation. One aspect of reliable operation is + that all data recorded by a committed transaction should be stored + in a nonvolatile area that is safe from power loss, operating + system failure, and hardware failure (except failure of the + nonvolatile area itself, of course). Successfully writing the data + to the computer's permanent storage (disk drive or equivalent) + ordinarily meets this requirement. In fact, even if a computer is + fatally damaged, if the disk drives survive they can be moved to + another computer with similar hardware and all committed + transactions will remain intact. + + + + While forcing data to the disk platters periodically might seem like + a simple operation, it is not. Because disk drives are dramatically + slower than main memory and CPUs, several layers of caching exist + between the computer's main memory and the disk platters. + First, there is the operating system's buffer cache, which caches + frequently requested disk blocks and combines disk writes. Fortunately, + all operating systems give applications a way to force writes from + the buffer cache to disk, and PostgreSQL uses those + features. (See the parameter + to adjust how this is done.) + + + + Next, there might be a cache in the disk drive controller; this is + particularly common on RAID controller cards. Some of + these caches are write-through, meaning writes are sent + to the drive as soon as they arrive. Others are + write-back, meaning data is sent to the drive at + some later time. Such caches can be a reliability hazard because the + memory in the disk controller cache is volatile, and will lose its + contents in a power failure. Better controller cards have + battery-backup units (BBUs), meaning + the card has a battery that + maintains power to the cache in case of system power loss. After power + is restored the data will be written to the disk drives. + + + + And finally, most disk drives have caches. Some are write-through + while some are write-back, and the same concerns about data loss + exist for write-back drive caches as for disk controller + caches. Consumer-grade IDE and SATA drives are particularly likely + to have write-back caches that will not survive a power failure. Many + solid-state drives (SSD) also have volatile write-back caches. + + + + These caches can typically be disabled; however, the method for doing + this varies by operating system and drive type: + + + + + + On Linux, IDE and SATA drives can be queried using + hdparm -I; write caching is enabled if there is + a * next to Write cache. hdparm -W 0 + can be used to turn off write caching. SCSI drives can be queried + using sdparm. + Use sdparm --get=WCE to check + whether the write cache is enabled and sdparm --clear=WCE + to disable it. + + + + + + On FreeBSD, IDE drives can be queried using + atacontrol and write caching turned off using + hw.ata.wc=0 in /boot/loader.conf; + SCSI drives can be queried using camcontrol identify, + and the write cache both queried and changed using + sdparm when available. + + + + + + On Solaris, the disk write cache is controlled by + format -e. + (The Solaris ZFS file system is safe with disk write-cache + enabled because it issues its own disk cache flush commands.) + + + + + + On Windows, if wal_sync_method is + open_datasync (the default), write caching can be disabled + by unchecking My Computer\Open\disk drive\Properties\Hardware\Properties\Policies\Enable write caching on the disk. + Alternatively, set wal_sync_method to + fsync or fsync_writethrough, which prevent + write caching. + + + + + + On macOS, write caching can be prevented by + setting wal_sync_method to fsync_writethrough. + + + + + + Recent SATA drives (those following ATAPI-6 or later) + offer a drive cache flush command (FLUSH CACHE EXT), + while SCSI drives have long supported a similar command + SYNCHRONIZE CACHE. These commands are not directly + accessible to PostgreSQL, but some file systems + (e.g., ZFS, ext4) can use them to flush + data to the platters on write-back-enabled drives. Unfortunately, such + file systems behave suboptimally when combined with battery-backup unit + (BBU) disk controllers. In such setups, the synchronize + command forces all data from the controller cache to the disks, + eliminating much of the benefit of the BBU. You can run the + program to see + if you are affected. If you are affected, the performance benefits + of the BBU can be regained by turning off write barriers in + the file system or reconfiguring the disk controller, if that is + an option. If write barriers are turned off, make sure the battery + remains functional; a faulty battery can potentially lead to data loss. + Hopefully file system and disk controller designers will eventually + address this suboptimal behavior. + + + + When the operating system sends a write request to the storage hardware, + there is little it can do to make sure the data has arrived at a truly + non-volatile storage area. Rather, it is the + administrator's responsibility to make certain that all storage components + ensure integrity for both data and file-system metadata. + Avoid disk controllers that have non-battery-backed write caches. + At the drive level, disable write-back caching if the + drive cannot guarantee the data will be written before shutdown. + If you use SSDs, be aware that many of these do not honor cache flush + commands by default. + You can test for reliable I/O subsystem behavior using diskchecker.pl. + + + + Another risk of data loss is posed by the disk platter write + operations themselves. Disk platters are divided into sectors, + commonly 512 bytes each. Every physical read or write operation + processes a whole sector. + When a write request arrives at the drive, it might be for some multiple + of 512 bytes (PostgreSQL typically writes 8192 bytes, or + 16 sectors, at a time), and the process of writing could fail due + to power loss at any time, meaning some of the 512-byte sectors were + written while others were not. To guard against such failures, + PostgreSQL periodically writes full page images to + permanent WAL storage before modifying the actual page on + disk. By doing this, during crash recovery PostgreSQL can + restore partially-written pages from WAL. If you have file-system software + that prevents partial page writes (e.g., ZFS), you can turn off + this page imaging by turning off the parameter. Battery-Backed Unit + (BBU) disk controllers do not prevent partial page writes unless + they guarantee that data is written to the BBU as full (8kB) pages. + + + PostgreSQL also protects against some kinds of data corruption + on storage devices that may occur because of hardware errors or media failure over time, + such as reading/writing garbage data. + + + + Each individual record in a WAL file is protected by a CRC-32 (32-bit) check + that allows us to tell if record contents are correct. The CRC value + is set when we write each WAL record and checked during crash recovery, + archive recovery and replication. + + + + + Data pages are not currently checksummed by default, though full page images + recorded in WAL records will be protected; see initdb + for details about enabling data checksums. + + + + + Internal data structures such as pg_xact, pg_subtrans, pg_multixact, + pg_serial, pg_notify, pg_stat, pg_snapshots are not directly + checksummed, nor are pages protected by full page writes. However, where + such data structures are persistent, WAL records are written that allow + recent changes to be accurately rebuilt at crash recovery and those + WAL records are protected as discussed above. + + + + + Individual state files in pg_twophase are protected by CRC-32. + + + + + Temporary data files used in larger SQL queries for sorts, + materializations and intermediate results are not currently checksummed, + nor will WAL records be written for changes to those files. + + + + + + PostgreSQL does not protect against correctable memory errors + and it is assumed you will operate using RAM that uses industry standard + Error Correcting Codes (ECC) or better protection. + + + + + Data Checksums + + checksums + + + + By default, data pages are not protected by checksums, but this can + optionally be enabled for a cluster. When enabled, each data page includes + a checksum that is updated when the page is written and verified each time + the page is read. Only data pages are protected by checksums; internal data + structures and temporary files are not. + + + + Checksums are normally enabled when the cluster is initialized using initdb. + They can also be enabled or disabled at a later time as an offline + operation. Data checksums are enabled or disabled at the full cluster + level, and cannot be specified individually for databases or tables. + + + + The current state of checksums in the cluster can be verified by viewing the + value of the read-only configuration variable by issuing the command SHOW + data_checksums. + + + + When attempting to recover from page corruptions, it may be necessary to + bypass the checksum protection. To do this, temporarily set the + configuration parameter . + + + + Off-line Enabling of Checksums + + + The pg_checksums + application can be used to enable or disable data checksums, as well as + verify checksums, on an offline cluster. + + + + + + + Write-Ahead Logging (<acronym>WAL</acronym>) + + + WAL + + + + transaction log + WAL + + + + Write-Ahead Logging (WAL) + is a standard method for ensuring data integrity. A detailed + description can be found in most (if not all) books about + transaction processing. Briefly, WAL's central + concept is that changes to data files (where tables and indexes + reside) must be written only after those changes have been logged, + that is, after log records describing the changes have been flushed + to permanent storage. If we follow this procedure, we do not need + to flush data pages to disk on every transaction commit, because we + know that in the event of a crash we will be able to recover the + database using the log: any changes that have not been applied to + the data pages can be redone from the log records. (This is + roll-forward recovery, also known as REDO.) + + + + + Because WAL restores database file + contents after a crash, journaled file systems are not necessary for + reliable storage of the data files or WAL files. In fact, journaling + overhead can reduce performance, especially if journaling + causes file system data to be flushed + to disk. Fortunately, data flushing during journaling can + often be disabled with a file system mount option, e.g., + data=writeback on a Linux ext3 file system. + Journaled file systems do improve boot speed after a crash. + + + + + + Using WAL results in a + significantly reduced number of disk writes, because only the log + file needs to be flushed to disk to guarantee that a transaction is + committed, rather than every data file changed by the transaction. + The log file is written sequentially, + and so the cost of syncing the log is much less than the cost of + flushing the data pages. This is especially true for servers + handling many small transactions touching different parts of the data + store. Furthermore, when the server is processing many small concurrent + transactions, one fsync of the log file may + suffice to commit many transactions. + + + + WAL also makes it possible to support on-line + backup and point-in-time recovery, as described in . By archiving the WAL data we can support + reverting to any time instant covered by the available WAL data: + we simply install a prior physical backup of the database, and + replay the WAL log just as far as the desired time. What's more, + the physical backup doesn't have to be an instantaneous snapshot + of the database state — if it is made over some period of time, + then replaying the WAL log for that period will fix any internal + inconsistencies. + + + + + Asynchronous Commit + + + synchronous commit + + + + asynchronous commit + + + + Asynchronous commit is an option that allows transactions + to complete more quickly, at the cost that the most recent transactions may + be lost if the database should crash. In many applications this is an + acceptable trade-off. + + + + As described in the previous section, transaction commit is normally + synchronous: the server waits for the transaction's + WAL records to be flushed to permanent storage + before returning a success indication to the client. The client is + therefore guaranteed that a transaction reported to be committed will + be preserved, even in the event of a server crash immediately after. + However, for short transactions this delay is a major component of the + total transaction time. Selecting asynchronous commit mode means that + the server returns success as soon as the transaction is logically + completed, before the WAL records it generated have + actually made their way to disk. This can provide a significant boost + in throughput for small transactions. + + + + Asynchronous commit introduces the risk of data loss. There is a short + time window between the report of transaction completion to the client + and the time that the transaction is truly committed (that is, it is + guaranteed not to be lost if the server crashes). Thus asynchronous + commit should not be used if the client will take external actions + relying on the assumption that the transaction will be remembered. + As an example, a bank would certainly not use asynchronous commit for + a transaction recording an ATM's dispensing of cash. But in many + scenarios, such as event logging, there is no need for a strong + guarantee of this kind. + + + + The risk that is taken by using asynchronous commit is of data loss, + not data corruption. If the database should crash, it will recover + by replaying WAL up to the last record that was + flushed. The database will therefore be restored to a self-consistent + state, but any transactions that were not yet flushed to disk will + not be reflected in that state. The net effect is therefore loss of + the last few transactions. Because the transactions are replayed in + commit order, no inconsistency can be introduced — for example, + if transaction B made changes relying on the effects of a previous + transaction A, it is not possible for A's effects to be lost while B's + effects are preserved. + + + + The user can select the commit mode of each transaction, so that + it is possible to have both synchronous and asynchronous commit + transactions running concurrently. This allows flexible trade-offs + between performance and certainty of transaction durability. + The commit mode is controlled by the user-settable parameter + , which can be changed in any of + the ways that a configuration parameter can be set. The mode used for + any one transaction depends on the value of + synchronous_commit when transaction commit begins. + + + + Certain utility commands, for instance DROP TABLE, are + forced to commit synchronously regardless of the setting of + synchronous_commit. This is to ensure consistency + between the server's file system and the logical state of the database. + The commands supporting two-phase commit, such as PREPARE + TRANSACTION, are also always synchronous. + + + + If the database crashes during the risk window between an + asynchronous commit and the writing of the transaction's + WAL records, + then changes made during that transaction will be lost. + The duration of the + risk window is limited because a background process (the WAL + writer) flushes unwritten WAL records to disk + every milliseconds. + The actual maximum duration of the risk window is three times + wal_writer_delay because the WAL writer is + designed to favor writing whole pages at a time during busy periods. + + + + + An immediate-mode shutdown is equivalent to a server crash, and will + therefore cause loss of any unflushed asynchronous commits. + + + + + Asynchronous commit provides behavior different from setting + = off. + fsync is a server-wide + setting that will alter the behavior of all transactions. It disables + all logic within PostgreSQL that attempts to synchronize + writes to different portions of the database, and therefore a system + crash (that is, a hardware or operating system crash, not a failure of + PostgreSQL itself) could result in arbitrarily bad + corruption of the database state. In many scenarios, asynchronous + commit provides most of the performance improvement that could be + obtained by turning off fsync, but without the risk + of data corruption. + + + + also sounds very similar to + asynchronous commit, but it is actually a synchronous commit method + (in fact, commit_delay is ignored during an + asynchronous commit). commit_delay causes a delay + just before a transaction flushes WAL to disk, in + the hope that a single flush executed by one such transaction can also + serve other transactions committing at about the same time. The + setting can be thought of as a way of increasing the time window in + which transactions can join a group about to participate in a single + flush, to amortize the cost of the flush among multiple transactions. + + + + + + <acronym>WAL</acronym> Configuration + + + There are several WAL-related configuration parameters that + affect database performance. This section explains their use. + Consult for general information about + setting server configuration parameters. + + + + Checkpointscheckpoint + are points in the sequence of transactions at which it is guaranteed + that the heap and index data files have been updated with all + information written before that checkpoint. At checkpoint time, all + dirty data pages are flushed to disk and a special checkpoint record is + written to the log file. (The change records were previously flushed + to the WAL files.) + In the event of a crash, the crash recovery procedure looks at the latest + checkpoint record to determine the point in the log (known as the redo + record) from which it should start the REDO operation. Any changes made to + data files before that point are guaranteed to be already on disk. + Hence, after a checkpoint, log segments preceding the one containing + the redo record are no longer needed and can be recycled or removed. (When + WAL archiving is being done, the log segments must be + archived before being recycled or removed.) + + + + The checkpoint requirement of flushing all dirty data pages to disk + can cause a significant I/O load. For this reason, checkpoint + activity is throttled so that I/O begins at checkpoint start and completes + before the next checkpoint is due to start; this minimizes performance + degradation during checkpoints. + + + + The server's checkpointer process automatically performs + a checkpoint every so often. A checkpoint is begun every seconds, or if + is about to be exceeded, + whichever comes first. + The default settings are 5 minutes and 1 GB, respectively. + If no WAL has been written since the previous checkpoint, new checkpoints + will be skipped even if checkpoint_timeout has passed. + (If WAL archiving is being used and you want to put a lower limit on how + often files are archived in order to bound potential data loss, you should + adjust the parameter rather than the + checkpoint parameters.) + It is also possible to force a checkpoint by using the SQL + command CHECKPOINT. + + + + Reducing checkpoint_timeout and/or + max_wal_size causes checkpoints to occur + more often. This allows faster after-crash recovery, since less work + will need to be redone. However, one must balance this against the + increased cost of flushing dirty data pages more often. If + is set (as is the default), there is + another factor to consider. To ensure data page consistency, + the first modification of a data page after each checkpoint results in + logging the entire page content. In that case, + a smaller checkpoint interval increases the volume of output to the WAL log, + partially negating the goal of using a smaller interval, + and in any case causing more disk I/O. + + + + Checkpoints are fairly expensive, first because they require writing + out all currently dirty buffers, and second because they result in + extra subsequent WAL traffic as discussed above. It is therefore + wise to set the checkpointing parameters high enough so that checkpoints + don't happen too often. As a simple sanity check on your checkpointing + parameters, you can set the + parameter. If checkpoints happen closer together than + checkpoint_warning seconds, + a message will be output to the server log recommending increasing + max_wal_size. Occasional appearance of such + a message is not cause for alarm, but if it appears often then the + checkpoint control parameters should be increased. Bulk operations such + as large COPY transfers might cause a number of such warnings + to appear if you have not set max_wal_size high + enough. + + + + To avoid flooding the I/O system with a burst of page writes, + writing dirty buffers during a checkpoint is spread over a period of time. + That period is controlled by + , which is + given as a fraction of the checkpoint interval (configured by using + checkpoint_timeout). + The I/O rate is adjusted so that the checkpoint finishes when the + given fraction of + checkpoint_timeout seconds have elapsed, or before + max_wal_size is exceeded, whichever is sooner. + With the default value of 0.9, + PostgreSQL can be expected to complete each checkpoint + a bit before the next scheduled checkpoint (at around 90% of the last checkpoint's + duration). This spreads out the I/O as much as possible so that the checkpoint + I/O load is consistent throughout the checkpoint interval. The disadvantage of + this is that prolonging checkpoints affects recovery time, because more WAL + segments will need to be kept around for possible use in recovery. A user + concerned about the amount of time required to recover might wish to reduce + checkpoint_timeout so that checkpoints occur more frequently + but still spread the I/O across the checkpoint interval. Alternatively, + checkpoint_completion_target could be reduced, but this would + result in times of more intense I/O (during the checkpoint) and times of less I/O + (after the checkpoint completed but before the next scheduled checkpoint) and + therefore is not recommended. + Although checkpoint_completion_target could be set as high as + 1.0, it is typically recommended to set it to no higher than 0.9 (the default) + since checkpoints include some other activities besides writing dirty buffers. + A setting of 1.0 is quite likely to result in checkpoints not being + completed on time, which would result in performance loss due to + unexpected variation in the number of WAL segments needed. + + + + On Linux and POSIX platforms + allows to force the OS that pages written by the checkpoint should be + flushed to disk after a configurable number of bytes. Otherwise, these + pages may be kept in the OS's page cache, inducing a stall when + fsync is issued at the end of a checkpoint. This setting will + often help to reduce transaction latency, but it also can have an adverse + effect on performance; particularly for workloads that are bigger than + , but smaller than the OS's page cache. + + + + The number of WAL segment files in pg_wal directory depends on + min_wal_size, max_wal_size and + the amount of WAL generated in previous checkpoint cycles. When old log + segment files are no longer needed, they are removed or recycled (that is, + renamed to become future segments in the numbered sequence). If, due to a + short-term peak of log output rate, max_wal_size is + exceeded, the unneeded segment files will be removed until the system + gets back under this limit. Below that limit, the system recycles enough + WAL files to cover the estimated need until the next checkpoint, and + removes the rest. The estimate is based on a moving average of the number + of WAL files used in previous checkpoint cycles. The moving average + is increased immediately if the actual usage exceeds the estimate, so it + accommodates peak usage rather than average usage to some extent. + min_wal_size puts a minimum on the amount of WAL files + recycled for future usage; that much WAL is always recycled for future use, + even if the system is idle and the WAL usage estimate suggests that little + WAL is needed. + + + + Independently of max_wal_size, + the most recent megabytes of + WAL files plus one additional WAL file are + kept at all times. Also, if WAL archiving is used, old segments cannot be + removed or recycled until they are archived. If WAL archiving cannot keep up + with the pace that WAL is generated, or if archive_command + fails repeatedly, old WAL files will accumulate in pg_wal + until the situation is resolved. A slow or failed standby server that + uses a replication slot will have the same effect (see + ). + + + + In archive recovery or standby mode, the server periodically performs + restartpoints,restartpoint + which are similar to checkpoints in normal operation: the server forces + all its state to disk, updates the pg_control file to + indicate that the already-processed WAL data need not be scanned again, + and then recycles any old log segment files in the pg_wal + directory. + Restartpoints can't be performed more frequently than checkpoints on the + primary because restartpoints can only be performed at checkpoint records. + A restartpoint is triggered when a checkpoint record is reached if at + least checkpoint_timeout seconds have passed since the last + restartpoint, or if WAL size is about to exceed + max_wal_size. However, because of limitations on when a + restartpoint can be performed, max_wal_size is often exceeded + during recovery, by up to one checkpoint cycle's worth of WAL. + (max_wal_size is never a hard limit anyway, so you should + always leave plenty of headroom to avoid running out of disk space.) + + + + There are two commonly used internal WAL functions: + XLogInsertRecord and XLogFlush. + XLogInsertRecord is used to place a new record into + the WAL buffers in shared memory. If there is no + space for the new record, XLogInsertRecord will have + to write (move to kernel cache) a few filled WAL + buffers. This is undesirable because XLogInsertRecord + is used on every database low level modification (for example, row + insertion) at a time when an exclusive lock is held on affected + data pages, so the operation needs to be as fast as possible. What + is worse, writing WAL buffers might also force the + creation of a new log segment, which takes even more + time. Normally, WAL buffers should be written + and flushed by an XLogFlush request, which is + made, for the most part, at transaction commit time to ensure that + transaction records are flushed to permanent storage. On systems + with high log output, XLogFlush requests might + not occur often enough to prevent XLogInsertRecord + from having to do writes. On such systems + one should increase the number of WAL buffers by + modifying the parameter. When + is set and the system is very busy, + setting wal_buffers higher will help smooth response times + during the period immediately following each checkpoint. + + + + The parameter defines for how many + microseconds a group commit leader process will sleep after acquiring a + lock within XLogFlush, while group commit + followers queue up behind the leader. This delay allows other server + processes to add their commit records to the WAL buffers so that all of + them will be flushed by the leader's eventual sync operation. No sleep + will occur if is not enabled, or if fewer + than other sessions are currently + in active transactions; this avoids sleeping when it's unlikely that + any other session will commit soon. Note that on some platforms, the + resolution of a sleep request is ten milliseconds, so that any nonzero + commit_delay setting between 1 and 10000 + microseconds would have the same effect. Note also that on some + platforms, sleep operations may take slightly longer than requested by + the parameter. + + + + Since the purpose of commit_delay is to allow the + cost of each flush operation to be amortized across concurrently + committing transactions (potentially at the expense of transaction + latency), it is necessary to quantify that cost before the setting can + be chosen intelligently. The higher that cost is, the more effective + commit_delay is expected to be in increasing + transaction throughput, up to a point. The program can be used to measure the average time + in microseconds that a single WAL flush operation takes. A value of + half of the average time the program reports it takes to flush after a + single 8kB write operation is often the most effective setting for + commit_delay, so this value is recommended as the + starting point to use when optimizing for a particular workload. While + tuning commit_delay is particularly useful when the + WAL log is stored on high-latency rotating disks, benefits can be + significant even on storage media with very fast sync times, such as + solid-state drives or RAID arrays with a battery-backed write cache; + but this should definitely be tested against a representative workload. + Higher values of commit_siblings should be used in + such cases, whereas smaller commit_siblings values + are often helpful on higher latency media. Note that it is quite + possible that a setting of commit_delay that is too + high can increase transaction latency by so much that total transaction + throughput suffers. + + + + When commit_delay is set to zero (the default), it + is still possible for a form of group commit to occur, but each group + will consist only of sessions that reach the point where they need to + flush their commit records during the window in which the previous + flush operation (if any) is occurring. At higher client counts a + gangway effect tends to occur, so that the effects of group + commit become significant even when commit_delay is + zero, and thus explicitly setting commit_delay tends + to help less. Setting commit_delay can only help + when (1) there are some concurrently committing transactions, and (2) + throughput is limited to some degree by commit rate; but with high + rotational latency this setting can be effective in increasing + transaction throughput with as few as two clients (that is, a single + committing client with one sibling transaction). + + + + The parameter determines how + PostgreSQL will ask the kernel to force + WAL updates out to disk. + All the options should be the same in terms of reliability, with + the exception of fsync_writethrough, which can sometimes + force a flush of the disk cache even when other options do not do so. + However, it's quite platform-specific which one will be the fastest. + You can test the speeds of different options using the program. + Note that this parameter is irrelevant if fsync + has been turned off. + + + + Enabling the configuration parameter + (provided that PostgreSQL has been + compiled with support for it) will result in each + XLogInsertRecord and XLogFlush + WAL call being logged to the server log. This + option might be replaced by a more general mechanism in the future. + + + + There are two internal functions to write WAL data to disk: + XLogWrite and issue_xlog_fsync. + When is enabled, the total + amounts of time XLogWrite writes and + issue_xlog_fsync syncs WAL data to disk are counted as + wal_write_time and wal_sync_time in + , respectively. + XLogWrite is normally called by + XLogInsertRecord (when there is no space for the new + record in WAL buffers), XLogFlush and the WAL writer, + to write WAL buffers to disk and call issue_xlog_fsync. + issue_xlog_fsync is normally called by + XLogWrite to sync WAL files to disk. + If wal_sync_method is either + open_datasync or open_sync, + a write operation in XLogWrite guarantees to sync written + WAL data to disk and issue_xlog_fsync does nothing. + If wal_sync_method is either fdatasync, + fsync, or fsync_writethrough, + the write operation moves WAL buffers to kernel cache and + issue_xlog_fsync syncs them to disk. Regardless + of the setting of track_wal_io_timing, the number + of times XLogWrite writes and + issue_xlog_fsync syncs WAL data to disk are also + counted as wal_write and wal_sync + in pg_stat_wal, respectively. + + + + + WAL Internals + + + LSN + + + + WAL is automatically enabled; no action is + required from the administrator except ensuring that the + disk-space requirements for the WAL logs are met, + and that any necessary tuning is done (see ). + + + + WAL records are appended to the WAL + logs as each new record is written. The insert position is described by + a Log Sequence Number (LSN) that is a byte offset into + the logs, increasing monotonically with each new record. + LSN values are returned as the datatype + pg_lsn. Values can be + compared to calculate the volume of WAL data that + separates them, so they are used to measure the progress of replication + and recovery. + + + + WAL logs are stored in the directory + pg_wal under the data directory, as a set of + segment files, normally each 16 MB in size (but the size can be changed + by altering the initdb option). Each segment is + divided into pages, normally 8 kB each (this size can be changed via the + configure option). The log record headers + are described in access/xlogrecord.h; the record + content is dependent on the type of event that is being logged. Segment + files are given ever-increasing numbers as names, starting at + 000000010000000000000001. The numbers do not wrap, + but it will take a very, very long time to exhaust the + available stock of numbers. + + + + It is advantageous if the log is located on a different disk from the + main database files. This can be achieved by moving the + pg_wal directory to another location (while the server + is shut down, of course) and creating a symbolic link from the + original location in the main data directory to the new location. + + + + The aim of WAL is to ensure that the log is + written before database records are altered, but this can be subverted by + disk drivesdisk drive that falsely report a + successful write to the kernel, + when in fact they have only cached the data and not yet stored it + on the disk. A power failure in such a situation might lead to + irrecoverable data corruption. Administrators should try to ensure + that disks holding PostgreSQL's + WAL log files do not make such false reports. + (See .) + + + + After a checkpoint has been made and the log flushed, the + checkpoint's position is saved in the file + pg_control. Therefore, at the start of recovery, + the server first reads pg_control and + then the checkpoint record; then it performs the REDO operation by + scanning forward from the log location indicated in the checkpoint + record. Because the entire content of data pages is saved in the + log on the first page modification after a checkpoint (assuming + is not disabled), all pages + changed since the checkpoint will be restored to a consistent + state. + + + + To deal with the case where pg_control is + corrupt, we should support the possibility of scanning existing log + segments in reverse order — newest to oldest — in order to find the + latest checkpoint. This has not been implemented yet. + pg_control is small enough (less than one disk page) + that it is not subject to partial-write problems, and as of this writing + there have been no reports of database failures due solely to the inability + to read pg_control itself. So while it is + theoretically a weak spot, pg_control does not + seem to be a problem in practice. + + + diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml new file mode 100644 index 000000000000..93f1155ab972 --- /dev/null +++ b/doc/src/sgml/xaggr.sgml @@ -0,0 +1,670 @@ + + + + User-Defined Aggregates + + + aggregate function + user-defined + + + + Aggregate functions in PostgreSQL + are defined in terms of state values + and state transition functions. + That is, an aggregate operates using a state value that is updated + as each successive input row is processed. + To define a new aggregate + function, one selects a data type for the state value, + an initial value for the state, and a state transition + function. The state transition function takes the previous state + value and the aggregate's input value(s) for the current row, and + returns a new state value. + A final function + can also be specified, in case the desired result of the aggregate + is different from the data that needs to be kept in the running + state value. The final function takes the ending state value + and returns whatever is wanted as the aggregate result. + In principle, the transition and final functions are just ordinary + functions that could also be used outside the context of the + aggregate. (In practice, it's often helpful for performance reasons + to create specialized transition functions that can only work when + called as part of an aggregate.) + + + + Thus, in addition to the argument and result data types seen by a user + of the aggregate, there is an internal state-value data type that + might be different from both the argument and result types. + + + + If we define an aggregate that does not use a final function, + we have an aggregate that computes a running function of + the column values from each row. sum is an + example of this kind of aggregate. sum starts at + zero and always adds the current row's value to + its running total. For example, if we want to make a sum + aggregate to work on a data type for complex numbers, + we only need the addition function for that data type. + The aggregate definition would be: + + +CREATE AGGREGATE sum (complex) +( + sfunc = complex_add, + stype = complex, + initcond = '(0,0)' +); + + + which we might use like this: + + +SELECT sum(a) FROM test_complex; + + sum +----------- + (34,53.9) + + + (Notice that we are relying on function overloading: there is more than + one aggregate named sum, but + PostgreSQL can figure out which kind + of sum applies to a column of type complex.) + + + + The above definition of sum will return zero + (the initial state value) if there are no nonnull input values. + Perhaps we want to return null in that case instead — the SQL standard + expects sum to behave that way. We can do this simply by + omitting the initcond phrase, so that the initial state + value is null. Ordinarily this would mean that the sfunc + would need to check for a null state-value input. But for + sum and some other simple aggregates like + max and min, + it is sufficient to insert the first nonnull input value into + the state variable and then start applying the transition function + at the second nonnull input value. PostgreSQL + will do that automatically if the initial state value is null and + the transition function is marked strict (i.e., not to be called + for null inputs). + + + + Another bit of default behavior for a strict transition function + is that the previous state value is retained unchanged whenever a + null input value is encountered. Thus, null values are ignored. If you + need some other behavior for null inputs, do not declare your + transition function as strict; instead code it to test for null inputs and + do whatever is needed. + + + + avg (average) is a more complex example of an aggregate. + It requires + two pieces of running state: the sum of the inputs and the count + of the number of inputs. The final result is obtained by dividing + these quantities. Average is typically implemented by using an + array as the state value. For example, + the built-in implementation of avg(float8) + looks like: + + +CREATE AGGREGATE avg (float8) +( + sfunc = float8_accum, + stype = float8[], + finalfunc = float8_avg, + initcond = '{0,0,0}' +); + + + + + + float8_accum requires a three-element array, not just + two elements, because it accumulates the sum of squares as well as + the sum and count of the inputs. This is so that it can be used for + some other aggregates as well as avg. + + + + + Aggregate function calls in SQL allow DISTINCT + and ORDER BY options that control which rows are fed + to the aggregate's transition function and in what order. These + options are implemented behind the scenes and are not the concern + of the aggregate's support functions. + + + + For further details see the + + command. + + + + Moving-Aggregate Mode + + + moving-aggregate mode + + + + aggregate function + moving aggregate + + + + Aggregate functions can optionally support moving-aggregate + mode, which allows substantially faster execution of aggregate + functions within windows with moving frame starting points. + (See + and for information about use of + aggregate functions as window functions.) + The basic idea is that in addition to a normal forward + transition function, the aggregate provides an inverse + transition function, which allows rows to be removed from the + aggregate's running state value when they exit the window frame. + For example a sum aggregate, which uses addition as the + forward transition function, would use subtraction as the inverse + transition function. Without an inverse transition function, the window + function mechanism must recalculate the aggregate from scratch each time + the frame starting point moves, resulting in run time proportional to the + number of input rows times the average frame length. With an inverse + transition function, the run time is only proportional to the number of + input rows. + + + + The inverse transition function is passed the current state value and the + aggregate input value(s) for the earliest row included in the current + state. It must reconstruct what the state value would have been if the + given input row had never been aggregated, but only the rows following + it. This sometimes requires that the forward transition function keep + more state than is needed for plain aggregation mode. Therefore, the + moving-aggregate mode uses a completely separate implementation from the + plain mode: it has its own state data type, its own forward transition + function, and its own final function if needed. These can be the same as + the plain mode's data type and functions, if there is no need for extra + state. + + + + As an example, we could extend the sum aggregate given above + to support moving-aggregate mode like this: + + +CREATE AGGREGATE sum (complex) +( + sfunc = complex_add, + stype = complex, + initcond = '(0,0)', + msfunc = complex_add, + minvfunc = complex_sub, + mstype = complex, + minitcond = '(0,0)' +); + + + The parameters whose names begin with m define the + moving-aggregate implementation. Except for the inverse transition + function minvfunc, they correspond to the plain-aggregate + parameters without m. + + + + The forward transition function for moving-aggregate mode is not allowed + to return null as the new state value. If the inverse transition + function returns null, this is taken as an indication that the inverse + function cannot reverse the state calculation for this particular input, + and so the aggregate calculation will be redone from scratch for the + current frame starting position. This convention allows moving-aggregate + mode to be used in situations where there are some infrequent cases that + are impractical to reverse out of the running state value. The inverse + transition function can punt on these cases, and yet still come + out ahead so long as it can work for most cases. As an example, an + aggregate working with floating-point numbers might choose to punt when + a NaN (not a number) input has to be removed from the running + state value. + + + + When writing moving-aggregate support functions, it is important to be + sure that the inverse transition function can reconstruct the correct + state value exactly. Otherwise there might be user-visible differences + in results depending on whether the moving-aggregate mode is used. + An example of an aggregate for which adding an inverse transition + function seems easy at first, yet where this requirement cannot be met + is sum over float4 or float8 inputs. A + naive declaration of sum(float8) could be + + +CREATE AGGREGATE unsafe_sum (float8) +( + stype = float8, + sfunc = float8pl, + mstype = float8, + msfunc = float8pl, + minvfunc = float8mi +); + + + This aggregate, however, can give wildly different results than it would + have without the inverse transition function. For example, consider + + +SELECT + unsafe_sum(x) OVER (ORDER BY n ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING) +FROM (VALUES (1, 1.0e20::float8), + (2, 1.0::float8)) AS v (n,x); + + + This query returns 0 as its second result, rather than the + expected answer of 1. The cause is the limited precision of + floating-point values: adding 1 to 1e20 results + in 1e20 again, and so subtracting 1e20 from that + yields 0, not 1. Note that this is a limitation + of floating-point arithmetic in general, not a limitation + of PostgreSQL. + + + + + + Polymorphic and Variadic Aggregates + + + aggregate function + polymorphic + + + + aggregate function + variadic + + + + Aggregate functions can use polymorphic + state transition functions or final functions, so that the same functions + can be used to implement multiple aggregates. + See + for an explanation of polymorphic functions. + Going a step further, the aggregate function itself can be specified + with polymorphic input type(s) and state type, allowing a single + aggregate definition to serve for multiple input data types. + Here is an example of a polymorphic aggregate: + + +CREATE AGGREGATE array_accum (anycompatible) +( + sfunc = array_append, + stype = anycompatiblearray, + initcond = '{}' +); + + + Here, the actual state type for any given aggregate call is the array type + having the actual input type as elements. The behavior of the aggregate + is to concatenate all the inputs into an array of that type. + (Note: the built-in aggregate array_agg provides similar + functionality, with better performance than this definition would have.) + + + + Here's the output using two different actual data types as arguments: + + +SELECT attrelid::regclass, array_accum(attname) + FROM pg_attribute + WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass + GROUP BY attrelid; + + attrelid | array_accum +---------------+--------------------------------------- + pg_tablespace | {spcname,spcowner,spcacl,spcoptions} +(1 row) + +SELECT attrelid::regclass, array_accum(atttypid::regtype) + FROM pg_attribute + WHERE attnum > 0 AND attrelid = 'pg_tablespace'::regclass + GROUP BY attrelid; + + attrelid | array_accum +---------------+--------------------------- + pg_tablespace | {name,oid,aclitem[],text[]} +(1 row) + + + + + Ordinarily, an aggregate function with a polymorphic result type has a + polymorphic state type, as in the above example. This is necessary + because otherwise the final function cannot be declared sensibly: it + would need to have a polymorphic result type but no polymorphic argument + type, which CREATE FUNCTION will reject on the grounds that + the result type cannot be deduced from a call. But sometimes it is + inconvenient to use a polymorphic state type. The most common case is + where the aggregate support functions are to be written in C and the + state type should be declared as internal because there is + no SQL-level equivalent for it. To address this case, it is possible to + declare the final function as taking extra dummy arguments + that match the input arguments of the aggregate. Such dummy arguments + are always passed as null values since no specific value is available when the + final function is called. Their only use is to allow a polymorphic + final function's result type to be connected to the aggregate's input + type(s). For example, the definition of the built-in + aggregate array_agg is equivalent to + + +CREATE FUNCTION array_agg_transfn(internal, anynonarray) + RETURNS internal ...; +CREATE FUNCTION array_agg_finalfn(internal, anynonarray) + RETURNS anyarray ...; + +CREATE AGGREGATE array_agg (anynonarray) +( + sfunc = array_agg_transfn, + stype = internal, + finalfunc = array_agg_finalfn, + finalfunc_extra +); + + + Here, the finalfunc_extra option specifies that the final + function receives, in addition to the state value, extra dummy + argument(s) corresponding to the aggregate's input argument(s). + The extra anynonarray argument allows the declaration + of array_agg_finalfn to be valid. + + + + An aggregate function can be made to accept a varying number of arguments + by declaring its last argument as a VARIADIC array, in much + the same fashion as for regular functions; see + . The aggregate's transition + function(s) must have the same array type as their last argument. The + transition function(s) typically would also be marked VARIADIC, + but this is not strictly required. + + + + + Variadic aggregates are easily misused in connection with + the ORDER BY option (see ), + since the parser cannot tell whether the wrong number of actual arguments + have been given in such a combination. Keep in mind that everything to + the right of ORDER BY is a sort key, not an argument to the + aggregate. For example, in + +SELECT myaggregate(a ORDER BY a, b, c) FROM ... + + the parser will see this as a single aggregate function argument and + three sort keys. However, the user might have intended + +SELECT myaggregate(a, b, c ORDER BY a) FROM ... + + If myaggregate is variadic, both these calls could be + perfectly valid. + + + + For the same reason, it's wise to think twice before creating aggregate + functions with the same names and different numbers of regular arguments. + + + + + + + Ordered-Set Aggregates + + + aggregate function + ordered set + + + + The aggregates we have been describing so far are normal + aggregates. PostgreSQL also + supports ordered-set aggregates, which differ from + normal aggregates in two key ways. First, in addition to ordinary + aggregated arguments that are evaluated once per input row, an + ordered-set aggregate can have direct arguments that are + evaluated only once per aggregation operation. Second, the syntax + for the ordinary aggregated arguments specifies a sort ordering + for them explicitly. An ordered-set aggregate is usually + used to implement a computation that depends on a specific row + ordering, for instance rank or percentile, so that the sort ordering + is a required aspect of any call. For example, the built-in + definition of percentile_disc is equivalent to: + + +CREATE FUNCTION ordered_set_transition(internal, anyelement) + RETURNS internal ...; +CREATE FUNCTION percentile_disc_final(internal, float8, anyelement) + RETURNS anyelement ...; + +CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement) +( + sfunc = ordered_set_transition, + stype = internal, + finalfunc = percentile_disc_final, + finalfunc_extra +); + + + This aggregate takes a float8 direct argument (the percentile + fraction) and an aggregated input that can be of any sortable data type. + It could be used to obtain a median household income like this: + + +SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; + percentile_disc +----------------- + 50489 + + + Here, 0.5 is a direct argument; it would make no sense + for the percentile fraction to be a value varying across rows. + + + + Unlike the case for normal aggregates, the sorting of input rows for + an ordered-set aggregate is not done behind the scenes, + but is the responsibility of the aggregate's support functions. + The typical implementation approach is to keep a reference to + a tuplesort object in the aggregate's state value, feed the + incoming rows into that object, and then complete the sorting and + read out the data in the final function. This design allows the + final function to perform special operations such as injecting + additional hypothetical rows into the data to be sorted. + While normal aggregates can often be implemented with support + functions written in PL/pgSQL or another + PL language, ordered-set aggregates generally have to be written in + C, since their state values aren't definable as any SQL data type. + (In the above example, notice that the state value is declared as + type internal — this is typical.) + Also, because the final function performs the sort, it is not possible + to continue adding input rows by executing the transition function again + later. This means the final function is not READ_ONLY; + it must be declared in CREATE AGGREGATE + as READ_WRITE, or as SHAREABLE if + it's possible for additional final-function calls to make use of the + already-sorted state. + + + + The state transition function for an ordered-set aggregate receives + the current state value plus the aggregated input values for + each row, and returns the updated state value. This is the + same definition as for normal aggregates, but note that the direct + arguments (if any) are not provided. The final function receives + the last state value, the values of the direct arguments if any, + and (if finalfunc_extra is specified) null values + corresponding to the aggregated input(s). As with normal + aggregates, finalfunc_extra is only really useful if the + aggregate is polymorphic; then the extra dummy argument(s) are needed + to connect the final function's result type to the aggregate's input + type(s). + + + + Currently, ordered-set aggregates cannot be used as window functions, + and therefore there is no need for them to support moving-aggregate mode. + + + + + + Partial Aggregation + + + aggregate function + partial aggregation + + + + Optionally, an aggregate function can support partial + aggregation. The idea of partial aggregation is to run the aggregate's + state transition function over different subsets of the input data + independently, and then to combine the state values resulting from those + subsets to produce the same state value that would have resulted from + scanning all the input in a single operation. This mode can be used for + parallel aggregation by having different worker processes scan different + portions of a table. Each worker produces a partial state value, and at + the end those state values are combined to produce a final state value. + (In the future this mode might also be used for purposes such as combining + aggregations over local and remote tables; but that is not implemented + yet.) + + + + To support partial aggregation, the aggregate definition must provide + a combine function, which takes two values of the + aggregate's state type (representing the results of aggregating over two + subsets of the input rows) and produces a new value of the state type, + representing what the state would have been after aggregating over the + combination of those sets of rows. It is unspecified what the relative + order of the input rows from the two sets would have been. This means + that it's usually impossible to define a useful combine function for + aggregates that are sensitive to input row order. + + + + As simple examples, MAX and MIN aggregates can be + made to support partial aggregation by specifying the combine function as + the same greater-of-two or lesser-of-two comparison function that is used + as their transition function. SUM aggregates just need an + addition function as combine function. (Again, this is the same as their + transition function, unless the state value is wider than the input data + type.) + + + + The combine function is treated much like a transition function that + happens to take a value of the state type, not of the underlying input + type, as its second argument. In particular, the rules for dealing + with null values and strict functions are similar. Also, if the aggregate + definition specifies a non-null initcond, keep in mind that + that will be used not only as the initial state for each partial + aggregation run, but also as the initial state for the combine function, + which will be called to combine each partial result into that state. + + + + If the aggregate's state type is declared as internal, it is + the combine function's responsibility that its result is allocated in + the correct memory context for aggregate state values. This means in + particular that when the first input is NULL it's invalid + to simply return the second input, as that value will be in the wrong + context and will not have sufficient lifespan. + + + + When the aggregate's state type is declared as internal, it is + usually also appropriate for the aggregate definition to provide a + serialization function and a deserialization + function, which allow such a state value to be copied from one process + to another. Without these functions, parallel aggregation cannot be + performed, and future applications such as local/remote aggregation will + probably not work either. + + + + A serialization function must take a single argument of + type internal and return a result of type bytea, which + represents the state value packaged up into a flat blob of bytes. + Conversely, a deserialization function reverses that conversion. It must + take two arguments of types bytea and internal, and + return a result of type internal. (The second argument is unused + and is always zero, but it is required for type-safety reasons.) The + result of the deserialization function should simply be allocated in the + current memory context, as unlike the combine function's result, it is not + long-lived. + + + + Worth noting also is that for an aggregate to be executed in parallel, + the aggregate itself must be marked PARALLEL SAFE. The + parallel-safety markings on its support functions are not consulted. + + + + + + Support Functions for Aggregates + + + aggregate function + support functions for + + + + A function written in C can detect that it is being called as an + aggregate support function by calling + AggCheckCallContext, for example: + +if (AggCheckCallContext(fcinfo, NULL)) + + One reason for checking this is that when it is true, the first input + must be a temporary state value and can therefore safely be modified + in-place rather than allocating a new copy. + See int8inc() for an example. + (While aggregate transition functions are always allowed to modify + the transition value in-place, aggregate final functions are generally + discouraged from doing so; if they do so, the behavior must be declared + when creating the aggregate. See + for more detail.) + + + + The second argument of AggCheckCallContext can be used to + retrieve the memory context in which aggregate state values are being kept. + This is useful for transition functions that wish to use expanded + objects (see ) as their state values. + On first call, the transition function should return an expanded object + whose memory context is a child of the aggregate state context, and then + keep returning the same expanded object on subsequent calls. See + array_append() for an example. (array_append() + is not the transition function of any built-in aggregate, but it is written + to behave efficiently when used as transition function of a custom + aggregate.) + + + + Another support routine available to aggregate functions written in C + is AggGetAggref, which returns the Aggref + parse node that defines the aggregate call. This is mainly useful + for ordered-set aggregates, which can inspect the substructure of + the Aggref node to find out what sort ordering they are + supposed to implement. Examples can be found + in orderedsetaggs.c in the PostgreSQL + source code. + + + + + diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml new file mode 100644 index 000000000000..584d389d4586 --- /dev/null +++ b/doc/src/sgml/xfunc.sgml @@ -0,0 +1,3630 @@ + + + + User-Defined Functions + + + function + user-defined + + + + PostgreSQL provides four kinds of + functions: + + + + + query language functions (functions written in + SQL) () + + + + + procedural language functions (functions written in, for + example, PL/pgSQL or PL/Tcl) + () + + + + + internal functions () + + + + + C-language functions () + + + + + + + Every kind + of function can take base types, composite types, or + combinations of these as arguments (parameters). In addition, + every kind of function can return a base type or + a composite type. Functions can also be defined to return + sets of base or composite values. + + + + Many kinds of functions can take or return certain pseudo-types + (such as polymorphic types), but the available facilities vary. + Consult the description of each kind of function for more details. + + + + It's easiest to define SQL + functions, so we'll start by discussing those. + Most of the concepts presented for SQL functions + will carry over to the other types of functions. + + + + Throughout this chapter, it can be useful to look at the reference + page of the CREATE + FUNCTION command to + understand the examples better. Some examples from this chapter + can be found in funcs.sql and + funcs.c in the src/tutorial + directory in the PostgreSQL source + distribution. + + + + + User-Defined Procedures + + + procedure + user-defined + + + + A procedure is a database object similar to a function. + The key differences are: + + + + + Procedures are defined with + the CREATE + PROCEDURE command, not CREATE + FUNCTION. + + + + + Procedures do not return a function value; hence CREATE + PROCEDURE lacks a RETURNS clause. + However, procedures can instead return data to their callers via + output parameters. + + + + + While a function is called as part of a query or DML command, a + procedure is called in isolation using + the CALL command. + + + + + A procedure can commit or roll back transactions during its + execution (then automatically beginning a new transaction), so long + as the invoking CALL command is not part of an + explicit transaction block. A function cannot do that. + + + + + Certain function attributes, such as strictness, don't apply to + procedures. Those attributes control how the function is + used in a query, which isn't relevant to procedures. + + + + + + + The explanations in the following sections about how to define + user-defined functions apply to procedures as well, except for the + points made above. + + + + Collectively, functions and procedures are also known + as routinesroutine. + There are commands such as ALTER ROUTINE + and DROP ROUTINE that can operate on functions and + procedures without having to know which kind it is. Note, however, that + there is no CREATE ROUTINE command. + + + + + Query Language (<acronym>SQL</acronym>) Functions + + + function + user-defined + in SQL + + + + SQL functions execute an arbitrary list of SQL statements, returning + the result of the last query in the list. + In the simple (non-set) + case, the first row of the last query's result will be returned. + (Bear in mind that the first row of a multirow + result is not well-defined unless you use ORDER BY.) + If the last query happens + to return no rows at all, the null value will be returned. + + + + Alternatively, an SQL function can be declared to return a set (that is, + multiple rows) by specifying the function's return type as SETOF + sometype, or equivalently by declaring it as + RETURNS TABLE(columns). In this case + all rows of the last query's result are returned. Further details appear + below. + + + + The body of an SQL function must be a list of SQL + statements separated by semicolons. A semicolon after the last + statement is optional. Unless the function is declared to return + void, the last statement must be a SELECT, + or an INSERT, UPDATE, or DELETE + that has a RETURNING clause. + + + + Any collection of commands in the SQL + language can be packaged together and defined as a function. + Besides SELECT queries, the commands can include data + modification queries (INSERT, + UPDATE, and DELETE), as well as + other SQL commands. (You cannot use transaction control commands, e.g., + COMMIT, SAVEPOINT, and some utility + commands, e.g., VACUUM, in SQL functions.) + However, the final command + must be a SELECT or have a RETURNING + clause that returns whatever is + specified as the function's return type. Alternatively, if you + want to define an SQL function that performs actions but has no + useful value to return, you can define it as returning void. + For example, this function removes rows with negative salaries from + the emp table: + + +CREATE FUNCTION clean_emp() RETURNS void AS ' + DELETE FROM emp + WHERE salary < 0; +' LANGUAGE SQL; + +SELECT clean_emp(); + + clean_emp +----------- + +(1 row) + + + + + You can also write this as a procedure, thus avoiding the issue of the + return type. For example: + +CREATE PROCEDURE clean_emp() AS ' + DELETE FROM emp + WHERE salary < 0; +' LANGUAGE SQL; + +CALL clean_emp(); + + In simple cases like this, the difference between a function returning + void and a procedure is mostly stylistic. However, + procedures offer additional functionality such as transaction control + that is not available in functions. Also, procedures are SQL standard + whereas returning void is a PostgreSQL extension. + + + + + The entire body of an SQL function is parsed before any of it is + executed. While an SQL function can contain commands that alter + the system catalogs (e.g., CREATE TABLE), the effects + of such commands will not be visible during parse analysis of + later commands in the function. Thus, for example, + CREATE TABLE foo (...); INSERT INTO foo VALUES(...); + will not work as desired if packaged up into a single SQL function, + since foo won't exist yet when the INSERT + command is parsed. It's recommended to use PL/pgSQL + instead of an SQL function in this type of situation. + + + + + The syntax of the CREATE FUNCTION command requires + the function body to be written as a string constant. It is usually + most convenient to use dollar quoting (see ) for the string constant. + If you choose to use regular single-quoted string constant syntax, + you must double single quote marks (') and backslashes + (\) (assuming escape string syntax) in the body of + the function (see ). + + + + Arguments for <acronym>SQL</acronym> Functions + + + function + named argument + + + + Arguments of an SQL function can be referenced in the function + body using either names or numbers. Examples of both methods appear + below. + + + + To use a name, declare the function argument as having a name, and + then just write that name in the function body. If the argument name + is the same as any column name in the current SQL command within the + function, the column name will take precedence. To override this, + qualify the argument name with the name of the function itself, that is + function_name.argument_name. + (If this would conflict with a qualified column name, again the column + name wins. You can avoid the ambiguity by choosing a different alias for + the table within the SQL command.) + + + + In the older numeric approach, arguments are referenced using the syntax + $n: $1 refers to the first input + argument, $2 to the second, and so on. This will work + whether or not the particular argument was declared with a name. + + + + If an argument is of a composite type, then the dot notation, + e.g., argname.fieldname or + $1.fieldname, can be used to access attributes of the + argument. Again, you might need to qualify the argument's name with the + function name to make the form with an argument name unambiguous. + + + + SQL function arguments can only be used as data values, + not as identifiers. Thus for example this is reasonable: + +INSERT INTO mytable VALUES ($1); + +but this will not work: + +INSERT INTO $1 VALUES (42); + + + + + + The ability to use names to reference SQL function arguments was added + in PostgreSQL 9.2. Functions to be used in + older servers must use the $n notation. + + + + + + <acronym>SQL</acronym> Functions on Base Types + + + The simplest possible SQL function has no arguments and + simply returns a base type, such as integer: + + +CREATE FUNCTION one() RETURNS integer AS $$ + SELECT 1 AS result; +$$ LANGUAGE SQL; + +-- Alternative syntax for string literal: +CREATE FUNCTION one() RETURNS integer AS ' + SELECT 1 AS result; +' LANGUAGE SQL; + +SELECT one(); + + one +----- + 1 + + + + + Notice that we defined a column alias within the function body for the result of the function + (with the name result), but this column alias is not visible + outside the function. Hence, the result is labeled one + instead of result. + + + + It is almost as easy to define SQL functions + that take base types as arguments: + + +CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$ + SELECT x + y; +$$ LANGUAGE SQL; + +SELECT add_em(1, 2) AS answer; + + answer +-------- + 3 + + + + + Alternatively, we could dispense with names for the arguments and + use numbers: + + +CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$ + SELECT $1 + $2; +$$ LANGUAGE SQL; + +SELECT add_em(1, 2) AS answer; + + answer +-------- + 3 + + + + + Here is a more useful function, which might be used to debit a + bank account: + + +CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$ + UPDATE bank + SET balance = balance - debit + WHERE accountno = tf1.accountno; + SELECT 1; +$$ LANGUAGE SQL; + + + A user could execute this function to debit account 17 by $100.00 as + follows: + + +SELECT tf1(17, 100.0); + + + + + In this example, we chose the name accountno for the first + argument, but this is the same as the name of a column in the + bank table. Within the UPDATE command, + accountno refers to the column bank.accountno, + so tf1.accountno must be used to refer to the argument. + We could of course avoid this by using a different name for the argument. + + + + In practice one would probably like a more useful result from the + function than a constant 1, so a more likely definition + is: + + +CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$ + UPDATE bank + SET balance = balance - debit + WHERE accountno = tf1.accountno; + SELECT balance FROM bank WHERE accountno = tf1.accountno; +$$ LANGUAGE SQL; + + + which adjusts the balance and returns the new balance. + The same thing could be done in one command using RETURNING: + + +CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$ + UPDATE bank + SET balance = balance - debit + WHERE accountno = tf1.accountno + RETURNING balance; +$$ LANGUAGE SQL; + + + + + If the final SELECT or RETURNING + clause in a SQL function does not return exactly + the function's declared result + type, PostgreSQL will automatically cast + the value to the required type, if that is possible with an implicit + or assignment cast. Otherwise, you must write an explicit cast. + For example, suppose we wanted the + previous add_em function to return + type float8 instead. It's sufficient to write + + +CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$ + SELECT $1 + $2; +$$ LANGUAGE SQL; + + + since the integer sum can be implicitly cast + to float8. + (See or + for more about casts.) + + + + + <acronym>SQL</acronym> Functions on Composite Types + + + When writing functions with arguments of composite types, we must not + only specify which argument we want but also the desired attribute + (field) of that argument. For example, suppose that + emp is a table containing employee data, and therefore + also the name of the composite type of each row of the table. Here + is a function double_salary that computes what someone's + salary would be if it were doubled: + + +CREATE TABLE emp ( + name text, + salary numeric, + age integer, + cubicle point +); + +INSERT INTO emp VALUES ('Bill', 4200, 45, '(2,1)'); + +CREATE FUNCTION double_salary(emp) RETURNS numeric AS $$ + SELECT $1.salary * 2 AS salary; +$$ LANGUAGE SQL; + +SELECT name, double_salary(emp.*) AS dream + FROM emp + WHERE emp.cubicle ~= point '(2,1)'; + + name | dream +------+------- + Bill | 8400 + + + + + Notice the use of the syntax $1.salary + to select one field of the argument row value. Also notice + how the calling SELECT command + uses table_name.* to select + the entire current row of a table as a composite value. The table + row can alternatively be referenced using just the table name, + like this: + +SELECT name, double_salary(emp) AS dream + FROM emp + WHERE emp.cubicle ~= point '(2,1)'; + + but this usage is deprecated since it's easy to get confused. + (See for details about these + two notations for the composite value of a table row.) + + + + Sometimes it is handy to construct a composite argument value + on-the-fly. This can be done with the ROW construct. + For example, we could adjust the data being passed to the function: + +SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream + FROM emp; + + + + + It is also possible to build a function that returns a composite type. + This is an example of a function + that returns a single emp row: + + +CREATE FUNCTION new_emp() RETURNS emp AS $$ + SELECT text 'None' AS name, + 1000.0 AS salary, + 25 AS age, + point '(2,2)' AS cubicle; +$$ LANGUAGE SQL; + + + In this example we have specified each of the attributes + with a constant value, but any computation + could have been substituted for these constants. + + + + Note two important things about defining the function: + + + + + The select list order in the query must be exactly the same as + that in which the columns appear in the composite type. + (Naming the columns, as we did above, + is irrelevant to the system.) + + + + + We must ensure each expression's type can be cast to that of + the corresponding column of the composite type. + Otherwise we'll get errors like this: + + +ERROR: return type mismatch in function declared to return emp +DETAIL: Final statement returns text instead of point at column 4. + + + As with the base-type case, the system will not insert explicit + casts automatically, only implicit or assignment casts. + + + + + + + A different way to define the same function is: + + +CREATE FUNCTION new_emp() RETURNS emp AS $$ + SELECT ROW('None', 1000.0, 25, '(2,2)')::emp; +$$ LANGUAGE SQL; + + + Here we wrote a SELECT that returns just a single + column of the correct composite type. This isn't really better + in this situation, but it is a handy alternative in some cases + — for example, if we need to compute the result by calling + another function that returns the desired composite value. + Another example is that if we are trying to write a function that + returns a domain over composite, rather than a plain composite type, + it is always necessary to write it as returning a single column, + since there is no way to cause a coercion of the whole row result. + + + + We could call this function directly either by using it in + a value expression: + + +SELECT new_emp(); + + new_emp +-------------------------- + (None,1000.0,25,"(2,2)") + + + or by calling it as a table function: + + +SELECT * FROM new_emp(); + + name | salary | age | cubicle +------+--------+-----+--------- + None | 1000.0 | 25 | (2,2) + + + The second way is described more fully in . + + + + When you use a function that returns a composite type, + you might want only one field (attribute) from its result. + You can do that with syntax like this: + + +SELECT (new_emp()).name; + + name +------ + None + + + The extra parentheses are needed to keep the parser from getting + confused. If you try to do it without them, you get something like this: + + +SELECT new_emp().name; +ERROR: syntax error at or near "." +LINE 1: SELECT new_emp().name; + ^ + + + + + Another option is to use functional notation for extracting an attribute: + + +SELECT name(new_emp()); + + name +------ + None + + + As explained in , the field notation and + functional notation are equivalent. + + + + Another way to use a function returning a composite type is to pass the + result to another function that accepts the correct row type as input: + + +CREATE FUNCTION getname(emp) RETURNS text AS $$ + SELECT $1.name; +$$ LANGUAGE SQL; + +SELECT getname(new_emp()); + getname +--------- + None +(1 row) + + + + + + <acronym>SQL</acronym> Functions with Output Parameters + + + function + output parameter + + + + An alternative way of describing a function's results is to define it + with output parameters, as in this example: + + +CREATE FUNCTION add_em (IN x int, IN y int, OUT sum int) +AS 'SELECT x + y' +LANGUAGE SQL; + +SELECT add_em(3,7); + add_em +-------- + 10 +(1 row) + + + This is not essentially different from the version of add_em + shown in . The real value of + output parameters is that they provide a convenient way of defining + functions that return several columns. For example, + + +CREATE FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int) +AS 'SELECT x + y, x * y' +LANGUAGE SQL; + + SELECT * FROM sum_n_product(11,42); + sum | product +-----+--------- + 53 | 462 +(1 row) + + + What has essentially happened here is that we have created an anonymous + composite type for the result of the function. The above example has + the same end result as + + +CREATE TYPE sum_prod AS (sum int, product int); + +CREATE FUNCTION sum_n_product (int, int) RETURNS sum_prod +AS 'SELECT $1 + $2, $1 * $2' +LANGUAGE SQL; + + + but not having to bother with the separate composite type definition + is often handy. Notice that the names attached to the output parameters + are not just decoration, but determine the column names of the anonymous + composite type. (If you omit a name for an output parameter, the + system will choose a name on its own.) + + + + Notice that output parameters are not included in the calling argument + list when invoking such a function from SQL. This is because + PostgreSQL considers only the input + parameters to define the function's calling signature. That means + also that only the input parameters matter when referencing the function + for purposes such as dropping it. We could drop the above function + with either of + + +DROP FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int); +DROP FUNCTION sum_n_product (int, int); + + + + + Parameters can be marked as IN (the default), + OUT, INOUT, or VARIADIC. + An INOUT + parameter serves as both an input parameter (part of the calling + argument list) and an output parameter (part of the result record type). + VARIADIC parameters are input parameters, but are treated + specially as described below. + + + + + <acronym>SQL</acronym> Procedures with Output Parameters + + + procedures + output parameter + + + + Output parameters are also supported in procedures, but they work a bit + differently from functions. In CALL commands, + output parameters must be included in the argument list. + For example, the bank account debiting routine from earlier could be + written like this: + +CREATE PROCEDURE tp1 (accountno integer, debit numeric, OUT new_balance numeric) AS $$ + UPDATE bank + SET balance = balance - debit + WHERE accountno = tp1.accountno + RETURNING balance; +$$ LANGUAGE SQL; + + To call this procedure, an argument matching the OUT + parameter must be included. It's customary to write + NULL: + +CALL tp1(17, 100.0, NULL); + + If you write something else, it must be an expression that is implicitly + coercible to the declared type of the parameter, just as for input + parameters. Note however that such an expression will not be evaluated. + + + + When calling a procedure from PL/pgSQL, + instead of writing NULL you must write a variable + that will receive the procedure's output. See for details. + + + + + <acronym>SQL</acronym> Functions with Variable Numbers of Arguments + + + function + variadic + + + + variadic function + + + + SQL functions can be declared to accept + variable numbers of arguments, so long as all the optional + arguments are of the same data type. The optional arguments will be + passed to the function as an array. The function is declared by + marking the last parameter as VARIADIC; this parameter + must be declared as being of an array type. For example: + + +CREATE FUNCTION mleast(VARIADIC arr numeric[]) RETURNS numeric AS $$ + SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); +$$ LANGUAGE SQL; + +SELECT mleast(10, -1, 5, 4.4); + mleast +-------- + -1 +(1 row) + + + Effectively, all the actual arguments at or beyond the + VARIADIC position are gathered up into a one-dimensional + array, as if you had written + + +SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work + + + You can't actually write that, though — or at least, it will + not match this function definition. A parameter marked + VARIADIC matches one or more occurrences of its element + type, not of its own type. + + + + Sometimes it is useful to be able to pass an already-constructed array + to a variadic function; this is particularly handy when one variadic + function wants to pass on its array parameter to another one. Also, + this is the only secure way to call a variadic function found in a schema + that permits untrusted users to create objects; see + . You can do this by + specifying VARIADIC in the call: + + +SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); + + + This prevents expansion of the function's variadic parameter into its + element type, thereby allowing the array argument value to match + normally. VARIADIC can only be attached to the last + actual argument of a function call. + + + + Specifying VARIADIC in the call is also the only way to + pass an empty array to a variadic function, for example: + + +SELECT mleast(VARIADIC ARRAY[]::numeric[]); + + + Simply writing SELECT mleast() does not work because a + variadic parameter must match at least one actual argument. + (You could define a second function also named mleast, + with no parameters, if you wanted to allow such calls.) + + + + The array element parameters generated from a variadic parameter are + treated as not having any names of their own. This means it is not + possible to call a variadic function using named arguments (), except when you specify + VARIADIC. For example, this will work: + + +SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]); + + + but not these: + + +SELECT mleast(arr => 10); +SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); + + + + + + <acronym>SQL</acronym> Functions with Default Values for Arguments + + + function + default values for arguments + + + + Functions can be declared with default values for some or all input + arguments. The default values are inserted whenever the function is + called with insufficiently many actual arguments. Since arguments + can only be omitted from the end of the actual argument list, all + parameters after a parameter with a default value have to have + default values as well. (Although the use of named argument notation + could allow this restriction to be relaxed, it's still enforced so that + positional argument notation works sensibly.) Whether or not you use it, + this capability creates a need for precautions when calling functions in + databases where some users mistrust other users; see + . + + + + For example: + +CREATE FUNCTION foo(a int, b int DEFAULT 2, c int DEFAULT 3) +RETURNS int +LANGUAGE SQL +AS $$ + SELECT $1 + $2 + $3; +$$; + +SELECT foo(10, 20, 30); + foo +----- + 60 +(1 row) + +SELECT foo(10, 20); + foo +----- + 33 +(1 row) + +SELECT foo(10); + foo +----- + 15 +(1 row) + +SELECT foo(); -- fails since there is no default for the first argument +ERROR: function foo() does not exist + + The = sign can also be used in place of the + key word DEFAULT. + + + + + <acronym>SQL</acronym> Functions as Table Sources + + + All SQL functions can be used in the FROM clause of a query, + but it is particularly useful for functions returning composite types. + If the function is defined to return a base type, the table function + produces a one-column table. If the function is defined to return + a composite type, the table function produces a column for each attribute + of the composite type. + + + + Here is an example: + + +CREATE TABLE foo (fooid int, foosubid int, fooname text); +INSERT INTO foo VALUES (1, 1, 'Joe'); +INSERT INTO foo VALUES (1, 2, 'Ed'); +INSERT INTO foo VALUES (2, 1, 'Mary'); + +CREATE FUNCTION getfoo(int) RETURNS foo AS $$ + SELECT * FROM foo WHERE fooid = $1; +$$ LANGUAGE SQL; + +SELECT *, upper(fooname) FROM getfoo(1) AS t1; + + fooid | foosubid | fooname | upper +-------+----------+---------+------- + 1 | 1 | Joe | JOE +(1 row) + + + As the example shows, we can work with the columns of the function's + result just the same as if they were columns of a regular table. + + + + Note that we only got one row out of the function. This is because + we did not use SETOF. That is described in the next section. + + + + + <acronym>SQL</acronym> Functions Returning Sets + + + function + with SETOF + + + + When an SQL function is declared as returning SETOF + sometype, the function's final + query is executed to completion, and each row it + outputs is returned as an element of the result set. + + + + This feature is normally used when calling the function in the FROM + clause. In this case each row returned by the function becomes + a row of the table seen by the query. For example, assume that + table foo has the same contents as above, and we say: + + +CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$ + SELECT * FROM foo WHERE fooid = $1; +$$ LANGUAGE SQL; + +SELECT * FROM getfoo(1) AS t1; + + + Then we would get: + + fooid | foosubid | fooname +-------+----------+--------- + 1 | 1 | Joe + 1 | 2 | Ed +(2 rows) + + + + + It is also possible to return multiple rows with the columns defined by + output parameters, like this: + + +CREATE TABLE tab (y int, z int); +INSERT INTO tab VALUES (1, 2), (3, 4), (5, 6), (7, 8); + +CREATE FUNCTION sum_n_product_with_tab (x int, OUT sum int, OUT product int) +RETURNS SETOF record +AS $$ + SELECT $1 + tab.y, $1 * tab.y FROM tab; +$$ LANGUAGE SQL; + +SELECT * FROM sum_n_product_with_tab(10); + sum | product +-----+--------- + 11 | 10 + 13 | 30 + 15 | 50 + 17 | 70 +(4 rows) + + + The key point here is that you must write RETURNS SETOF record + to indicate that the function returns multiple rows instead of just one. + If there is only one output parameter, write that parameter's type + instead of record. + + + + It is frequently useful to construct a query's result by invoking a + set-returning function multiple times, with the parameters for each + invocation coming from successive rows of a table or subquery. The + preferred way to do this is to use the LATERAL key word, + which is described in . + Here is an example using a set-returning function to enumerate + elements of a tree structure: + + +SELECT * FROM nodes; + name | parent +-----------+-------- + Top | + Child1 | Top + Child2 | Top + Child3 | Top + SubChild1 | Child1 + SubChild2 | Child1 +(6 rows) + +CREATE FUNCTION listchildren(text) RETURNS SETOF text AS $$ + SELECT name FROM nodes WHERE parent = $1 +$$ LANGUAGE SQL STABLE; + +SELECT * FROM listchildren('Top'); + listchildren +-------------- + Child1 + Child2 + Child3 +(3 rows) + +SELECT name, child FROM nodes, LATERAL listchildren(name) AS child; + name | child +--------+----------- + Top | Child1 + Top | Child2 + Top | Child3 + Child1 | SubChild1 + Child1 | SubChild2 +(5 rows) + + + This example does not do anything that we couldn't have done with a + simple join, but in more complex calculations the option to put + some of the work into a function can be quite convenient. + + + + Functions returning sets can also be called in the select list + of a query. For each row that the query + generates by itself, the set-returning function is invoked, and an output + row is generated for each element of the function's result set. + The previous example could also be done with queries like + these: + + +SELECT listchildren('Top'); + listchildren +-------------- + Child1 + Child2 + Child3 +(3 rows) + +SELECT name, listchildren(name) FROM nodes; + name | listchildren +--------+-------------- + Top | Child1 + Top | Child2 + Top | Child3 + Child1 | SubChild1 + Child1 | SubChild2 +(5 rows) + + + In the last SELECT, + notice that no output row appears for Child2, Child3, etc. + This happens because listchildren returns an empty set + for those arguments, so no result rows are generated. This is the same + behavior as we got from an inner join to the function result when using + the LATERAL syntax. + + + + PostgreSQL's behavior for a set-returning function in a + query's select list is almost exactly the same as if the set-returning + function had been written in a LATERAL FROM-clause item + instead. For example, + +SELECT x, generate_series(1,5) AS g FROM tab; + + is almost equivalent to + +SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; + + It would be exactly the same, except that in this specific example, + the planner could choose to put g on the outside of the + nested-loop join, since g has no actual lateral dependency + on tab. That would result in a different output row + order. Set-returning functions in the select list are always evaluated + as though they are on the inside of a nested-loop join with the rest of + the FROM clause, so that the function(s) are run to + completion before the next row from the FROM clause is + considered. + + + + If there is more than one set-returning function in the query's select + list, the behavior is similar to what you get from putting the functions + into a single LATERAL ROWS FROM( ... ) FROM-clause + item. For each row from the underlying query, there is an output row + using the first result from each function, then an output row using the + second result, and so on. If some of the set-returning functions + produce fewer outputs than others, null values are substituted for the + missing data, so that the total number of rows emitted for one + underlying row is the same as for the set-returning function that + produced the most outputs. Thus the set-returning functions + run in lockstep until they are all exhausted, and then + execution continues with the next underlying row. + + + + Set-returning functions can be nested in a select list, although that is + not allowed in FROM-clause items. In such cases, each level + of nesting is treated separately, as though it were + a separate LATERAL ROWS FROM( ... ) item. For example, in + +SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab; + + the set-returning functions srf2, srf3, + and srf5 would be run in lockstep for each row + of tab, and then srf1 and srf4 + would be applied in lockstep to each row produced by the lower + functions. + + + + Set-returning functions cannot be used within conditional-evaluation + constructs, such as CASE or COALESCE. For + example, consider + +SELECT x, CASE WHEN x > 0 THEN generate_series(1, 5) ELSE 0 END FROM tab; + + It might seem that this should produce five repetitions of input rows + that have x > 0, and a single repetition of those that do + not; but actually, because generate_series(1, 5) would be + run in an implicit LATERAL FROM item before + the CASE expression is ever evaluated, it would produce five + repetitions of every input row. To reduce confusion, such cases produce + a parse-time error instead. + + + + + If a function's last command is INSERT, UPDATE, + or DELETE with RETURNING, that command will + always be executed to completion, even if the function is not declared + with SETOF or the calling query does not fetch all the + result rows. Any extra rows produced by the RETURNING + clause are silently dropped, but the commanded table modifications + still happen (and are all completed before returning from the function). + + + + + + Before PostgreSQL 10, putting more than one + set-returning function in the same select list did not behave very + sensibly unless they always produced equal numbers of rows. Otherwise, + what you got was a number of output rows equal to the least common + multiple of the numbers of rows produced by the set-returning + functions. Also, nested set-returning functions did not work as + described above; instead, a set-returning function could have at most + one set-returning argument, and each nest of set-returning functions + was run independently. Also, conditional execution (set-returning + functions inside CASE etc) was previously allowed, + complicating things even more. + Use of the LATERAL syntax is recommended when writing + queries that need to work in older PostgreSQL versions, + because that will give consistent results across different versions. + If you have a query that is relying on conditional execution of a + set-returning function, you may be able to fix it by moving the + conditional test into a custom set-returning function. For example, + +SELECT x, CASE WHEN y > 0 THEN generate_series(1, z) ELSE 5 END FROM tab; + + could become + +CREATE FUNCTION case_generate_series(cond bool, start int, fin int, els int) + RETURNS SETOF int AS $$ +BEGIN + IF cond THEN + RETURN QUERY SELECT generate_series(start, fin); + ELSE + RETURN QUERY SELECT els; + END IF; +END$$ LANGUAGE plpgsql; + +SELECT x, case_generate_series(y > 0, 1, z, 5) FROM tab; + + This formulation will work the same in all versions + of PostgreSQL. + + + + + + <acronym>SQL</acronym> Functions Returning <literal>TABLE</literal> + + + function + RETURNS TABLE + + + + There is another way to declare a function as returning a set, + which is to use the syntax + RETURNS TABLE(columns). + This is equivalent to using one or more OUT parameters plus + marking the function as returning SETOF record (or + SETOF a single output parameter's type, as appropriate). + This notation is specified in recent versions of the SQL standard, and + thus may be more portable than using SETOF. + + + + For example, the preceding sum-and-product example could also be + done this way: + + +CREATE FUNCTION sum_n_product_with_tab (x int) +RETURNS TABLE(sum int, product int) AS $$ + SELECT $1 + tab.y, $1 * tab.y FROM tab; +$$ LANGUAGE SQL; + + + It is not allowed to use explicit OUT or INOUT + parameters with the RETURNS TABLE notation — you must + put all the output columns in the TABLE list. + + + + + Polymorphic <acronym>SQL</acronym> Functions + + + SQL functions can be declared to accept and + return the polymorphic types described in . Here is a polymorphic + function make_array that builds up an array + from two arbitrary data type elements: + +CREATE FUNCTION make_array(anyelement, anyelement) RETURNS anyarray AS $$ + SELECT ARRAY[$1, $2]; +$$ LANGUAGE SQL; + +SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray; + intarray | textarray +----------+----------- + {1,2} | {a,b} +(1 row) + + + + + Notice the use of the typecast 'a'::text + to specify that the argument is of type text. This is + required if the argument is just a string literal, since otherwise + it would be treated as type + unknown, and array of unknown is not a valid + type. + Without the typecast, you will get errors like this: + +ERROR: could not determine polymorphic type because input has type unknown + + + + + With make_array declared as above, you must + provide two arguments that are of exactly the same data type; the + system will not attempt to resolve any type differences. Thus for + example this does not work: + +SELECT make_array(1, 2.5) AS numericarray; +ERROR: function make_array(integer, numeric) does not exist + + An alternative approach is to use the common family of + polymorphic types, which allows the system to try to identify a + suitable common type: + +CREATE FUNCTION make_array2(anycompatible, anycompatible) +RETURNS anycompatiblearray AS $$ + SELECT ARRAY[$1, $2]; +$$ LANGUAGE SQL; + +SELECT make_array2(1, 2.5) AS numericarray; + numericarray +-------------- + {1,2.5} +(1 row) + + Because the rules for common type resolution default to choosing + type text when all inputs are of unknown types, this + also works: + +SELECT make_array2('a', 'b') AS textarray; + textarray +----------- + {a,b} +(1 row) + + + + + It is permitted to have polymorphic arguments with a fixed + return type, but the converse is not. For example: + +CREATE FUNCTION is_greater(anyelement, anyelement) RETURNS boolean AS $$ + SELECT $1 > $2; +$$ LANGUAGE SQL; + +SELECT is_greater(1, 2); + is_greater +------------ + f +(1 row) + +CREATE FUNCTION invalid_func() RETURNS anyelement AS $$ + SELECT 1; +$$ LANGUAGE SQL; +ERROR: cannot determine result data type +DETAIL: A result of type anyelement requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. + + + + + Polymorphism can be used with functions that have output arguments. + For example: + +CREATE FUNCTION dup (f1 anyelement, OUT f2 anyelement, OUT f3 anyarray) +AS 'select $1, array[$1,$1]' LANGUAGE SQL; + +SELECT * FROM dup(22); + f2 | f3 +----+--------- + 22 | {22,22} +(1 row) + + + + + Polymorphism can also be used with variadic functions. + For example: + +CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ + SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i); +$$ LANGUAGE SQL; + +SELECT anyleast(10, -1, 5, 4); + anyleast +---------- + -1 +(1 row) + +SELECT anyleast('abc'::text, 'def'); + anyleast +---------- + abc +(1 row) + +CREATE FUNCTION concat_values(text, VARIADIC anyarray) RETURNS text AS $$ + SELECT array_to_string($2, $1); +$$ LANGUAGE SQL; + +SELECT concat_values('|', 1, 4, 2); + concat_values +--------------- + 1|4|2 +(1 row) + + + + + + <acronym>SQL</acronym> Functions with Collations + + + collation + in SQL functions + + + + When an SQL function has one or more parameters of collatable data types, + a collation is identified for each function call depending on the + collations assigned to the actual arguments, as described in . If a collation is successfully identified + (i.e., there are no conflicts of implicit collations among the arguments) + then all the collatable parameters are treated as having that collation + implicitly. This will affect the behavior of collation-sensitive + operations within the function. For example, using the + anyleast function described above, the result of + +SELECT anyleast('abc'::text, 'ABC'); + + will depend on the database's default collation. In C locale + the result will be ABC, but in many other locales it will + be abc. The collation to use can be forced by adding + a COLLATE clause to any of the arguments, for example + +SELECT anyleast('abc'::text, 'ABC' COLLATE "C"); + + Alternatively, if you wish a function to operate with a particular + collation regardless of what it is called with, insert + COLLATE clauses as needed in the function definition. + This version of anyleast would always use en_US + locale to compare strings: + +CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$ + SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i); +$$ LANGUAGE SQL; + + But note that this will throw an error if applied to a non-collatable + data type. + + + + If no common collation can be identified among the actual arguments, + then an SQL function treats its parameters as having their data types' + default collation (which is usually the database's default collation, + but could be different for parameters of domain types). + + + + The behavior of collatable parameters can be thought of as a limited + form of polymorphism, applicable only to textual data types. + + + + + + Function Overloading + + + overloading + functions + + + + More than one function can be defined with the same SQL name, so long + as the arguments they take are different. In other words, + function names can be overloaded. Whether or not + you use it, this capability entails security precautions when calling + functions in databases where some users mistrust other users; see + . When a query is executed, the server + will determine which function to call from the data types and the number + of the provided arguments. Overloading can also be used to simulate + functions with a variable number of arguments, up to a finite maximum + number. + + + + When creating a family of overloaded functions, one should be + careful not to create ambiguities. For instance, given the + functions: + +CREATE FUNCTION test(int, real) RETURNS ... +CREATE FUNCTION test(smallint, double precision) RETURNS ... + + it is not immediately clear which function would be called with + some trivial input like test(1, 1.5). The + currently implemented resolution rules are described in + , but it is unwise to design a system that subtly + relies on this behavior. + + + + A function that takes a single argument of a composite type should + generally not have the same name as any attribute (field) of that type. + Recall that attribute(table) + is considered equivalent + to table.attribute. + In the case that there is an + ambiguity between a function on a composite type and an attribute of + the composite type, the attribute will always be used. It is possible + to override that choice by schema-qualifying the function name + (that is, schema.func(table) + ) but it's better to + avoid the problem by not choosing conflicting names. + + + + Another possible conflict is between variadic and non-variadic functions. + For instance, it is possible to create both foo(numeric) and + foo(VARIADIC numeric[]). In this case it is unclear which one + should be matched to a call providing a single numeric argument, such as + foo(10.1). The rule is that the function appearing + earlier in the search path is used, or if the two functions are in the + same schema, the non-variadic one is preferred. + + + + When overloading C-language functions, there is an additional + constraint: The C name of each function in the family of + overloaded functions must be different from the C names of all + other functions, either internal or dynamically loaded. If this + rule is violated, the behavior is not portable. You might get a + run-time linker error, or one of the functions will get called + (usually the internal one). The alternative form of the + AS clause for the SQL CREATE + FUNCTION command decouples the SQL function name from + the function name in the C source code. For instance: + +CREATE FUNCTION test(int) RETURNS int + AS 'filename', 'test_1arg' + LANGUAGE C; +CREATE FUNCTION test(int, int) RETURNS int + AS 'filename', 'test_2arg' + LANGUAGE C; + + The names of the C functions here reflect one of many possible conventions. + + + + + Function Volatility Categories + + + volatility + functions + + + VOLATILE + + + STABLE + + + IMMUTABLE + + + + Every function has a volatility classification, with + the possibilities being VOLATILE, STABLE, or + IMMUTABLE. VOLATILE is the default if the + CREATE FUNCTION + command does not specify a category. The volatility category is a + promise to the optimizer about the behavior of the function: + + + + + A VOLATILE function can do anything, including modifying + the database. It can return different results on successive calls with + the same arguments. The optimizer makes no assumptions about the + behavior of such functions. A query using a volatile function will + re-evaluate the function at every row where its value is needed. + + + + + A STABLE function cannot modify the database and is + guaranteed to return the same results given the same arguments + for all rows within a single statement. This category allows the + optimizer to optimize multiple calls of the function to a single + call. In particular, it is safe to use an expression containing + such a function in an index scan condition. (Since an index scan + will evaluate the comparison value only once, not once at each + row, it is not valid to use a VOLATILE function in an + index scan condition.) + + + + + An IMMUTABLE function cannot modify the database and is + guaranteed to return the same results given the same arguments forever. + This category allows the optimizer to pre-evaluate the function when + a query calls it with constant arguments. For example, a query like + SELECT ... WHERE x = 2 + 2 can be simplified on sight to + SELECT ... WHERE x = 4, because the function underlying + the integer addition operator is marked IMMUTABLE. + + + + + + + For best optimization results, you should label your functions with the + strictest volatility category that is valid for them. + + + + Any function with side-effects must be labeled + VOLATILE, so that calls to it cannot be optimized away. + Even a function with no side-effects needs to be labeled + VOLATILE if its value can change within a single query; + some examples are random(), currval(), + timeofday(). + + + + Another important example is that the current_timestamp + family of functions qualify as STABLE, since their values do + not change within a transaction. + + + + There is relatively little difference between STABLE and + IMMUTABLE categories when considering simple interactive + queries that are planned and immediately executed: it doesn't matter + a lot whether a function is executed once during planning or once during + query execution startup. But there is a big difference if the plan is + saved and reused later. Labeling a function IMMUTABLE when + it really isn't might allow it to be prematurely folded to a constant during + planning, resulting in a stale value being re-used during subsequent uses + of the plan. This is a hazard when using prepared statements or when + using function languages that cache plans (such as + PL/pgSQL). + + + + For functions written in SQL or in any of the standard procedural + languages, there is a second important property determined by the + volatility category, namely the visibility of any data changes that have + been made by the SQL command that is calling the function. A + VOLATILE function will see such changes, a STABLE + or IMMUTABLE function will not. This behavior is implemented + using the snapshotting behavior of MVCC (see ): + STABLE and IMMUTABLE functions use a snapshot + established as of the start of the calling query, whereas + VOLATILE functions obtain a fresh snapshot at the start of + each query they execute. + + + + + Functions written in C can manage snapshots however they want, but it's + usually a good idea to make C functions work this way too. + + + + + Because of this snapshotting behavior, + a function containing only SELECT commands can safely be + marked STABLE, even if it selects from tables that might be + undergoing modifications by concurrent queries. + PostgreSQL will execute all commands of a + STABLE function using the snapshot established for the + calling query, and so it will see a fixed view of the database throughout + that query. + + + + The same snapshotting behavior is used for SELECT commands + within IMMUTABLE functions. It is generally unwise to select + from database tables within an IMMUTABLE function at all, + since the immutability will be broken if the table contents ever change. + However, PostgreSQL does not enforce that you + do not do that. + + + + A common error is to label a function IMMUTABLE when its + results depend on a configuration parameter. For example, a function + that manipulates timestamps might well have results that depend on the + setting. For safety, such functions should + be labeled STABLE instead. + + + + + PostgreSQL requires that STABLE + and IMMUTABLE functions contain no SQL commands other + than SELECT to prevent data modification. + (This is not a completely bulletproof test, since such functions could + still call VOLATILE functions that modify the database. + If you do that, you will find that the STABLE or + IMMUTABLE function does not notice the database changes + applied by the called function, since they are hidden from its snapshot.) + + + + + + Procedural Language Functions + + + PostgreSQL allows user-defined functions + to be written in other languages besides SQL and C. These other + languages are generically called procedural + languages (PLs). + Procedural languages aren't built into the + PostgreSQL server; they are offered + by loadable modules. + See and following chapters for more + information. + + + + + Internal Functions + + functioninternal + + + Internal functions are functions written in C that have been statically + linked into the PostgreSQL server. + The body of the function definition + specifies the C-language name of the function, which need not be the + same as the name being declared for SQL use. + (For reasons of backward compatibility, an empty body + is accepted as meaning that the C-language function name is the + same as the SQL name.) + + + + Normally, all internal functions present in the + server are declared during the initialization of the database cluster + (see ), + but a user could use CREATE FUNCTION + to create additional alias names for an internal function. + Internal functions are declared in CREATE FUNCTION + with language name internal. For instance, to + create an alias for the sqrt function: + +CREATE FUNCTION square_root(double precision) RETURNS double precision + AS 'dsqrt' + LANGUAGE internal + STRICT; + + (Most internal functions expect to be declared strict.) + + + + + Not all predefined functions are + internal in the above sense. Some predefined + functions are written in SQL. + + + + + + C-Language Functions + + + function + user-defined + in C + + + + User-defined functions can be written in C (or a language that can + be made compatible with C, such as C++). Such functions are + compiled into dynamically loadable objects (also called shared + libraries) and are loaded by the server on demand. The dynamic + loading feature is what distinguishes C language functions + from internal functions — the actual coding conventions + are essentially the same for both. (Hence, the standard internal + function library is a rich source of coding examples for user-defined + C functions.) + + + + Currently only one calling convention is used for C functions + (version 1). Support for that calling convention is + indicated by writing a PG_FUNCTION_INFO_V1() macro + call for the function, as illustrated below. + + + + Dynamic Loading + + + dynamic loading + + + + The first time a user-defined function in a particular + loadable object file is called in a session, + the dynamic loader loads that object file into memory so that the + function can be called. The CREATE FUNCTION + for a user-defined C function must therefore specify two pieces of + information for the function: the name of the loadable + object file, and the C name (link symbol) of the specific function to call + within that object file. If the C name is not explicitly specified then + it is assumed to be the same as the SQL function name. + + + + The following algorithm is used to locate the shared object file + based on the name given in the CREATE FUNCTION + command: + + + + + If the name is an absolute path, the given file is loaded. + + + + + + If the name starts with the string $libdir, + that part is replaced by the PostgreSQL package + library directory + name, which is determined at build time.$libdir + + + + + + If the name does not contain a directory part, the file is + searched for in the path specified by the configuration variable + .dynamic_library_path + + + + + + Otherwise (the file was not found in the path, or it contains a + non-absolute directory part), the dynamic loader will try to + take the name as given, which will most likely fail. (It is + unreliable to depend on the current working directory.) + + + + + If this sequence does not work, the platform-specific shared + library file name extension (often .so) is + appended to the given name and this sequence is tried again. If + that fails as well, the load will fail. + + + + It is recommended to locate shared libraries either relative to + $libdir or through the dynamic library path. + This simplifies version upgrades if the new installation is at a + different location. The actual directory that + $libdir stands for can be found out with the + command pg_config --pkglibdir. + + + + The user ID the PostgreSQL server runs + as must be able to traverse the path to the file you intend to + load. Making the file or a higher-level directory not readable + and/or not executable by the postgres + user is a common mistake. + + + + In any case, the file name that is given in the + CREATE FUNCTION command is recorded literally + in the system catalogs, so if the file needs to be loaded again + the same procedure is applied. + + + + + PostgreSQL will not compile a C function + automatically. The object file must be compiled before it is referenced + in a CREATE + FUNCTION command. See for additional + information. + + + + + magic block + + + + To ensure that a dynamically loaded object file is not loaded into an + incompatible server, PostgreSQL checks that the + file contains a magic block with the appropriate contents. + This allows the server to detect obvious incompatibilities, such as code + compiled for a different major version of + PostgreSQL. To include a magic block, + write this in one (and only one) of the module source files, after having + included the header fmgr.h: + + +PG_MODULE_MAGIC; + + + + + After it is used for the first time, a dynamically loaded object + file is retained in memory. Future calls in the same session to + the function(s) in that file will only incur the small overhead of + a symbol table lookup. If you need to force a reload of an object + file, for example after recompiling it, begin a fresh session. + + + + _PG_init + + + _PG_fini + + + library initialization function + + + library finalization function + + + + Optionally, a dynamically loaded file can contain initialization and + finalization functions. If the file includes a function named + _PG_init, that function will be called immediately after + loading the file. The function receives no parameters and should + return void. If the file includes a function named + _PG_fini, that function will be called immediately before + unloading the file. Likewise, the function receives no parameters and + should return void. Note that _PG_fini will only be called + during an unload of the file, not during process termination. + (Presently, unloads are disabled and will never occur, but this may + change in the future.) + + + + + + Base Types in C-Language Functions + + + data type + internal organization + + + + To know how to write C-language functions, you need to know how + PostgreSQL internally represents base + data types and how they can be passed to and from functions. + Internally, PostgreSQL regards a base + type as a blob of memory. The user-defined + functions that you define over a type in turn define the way that + PostgreSQL can operate on it. That + is, PostgreSQL will only store and + retrieve the data from disk and use your user-defined functions + to input, process, and output the data. + + + + Base types can have one of three internal formats: + + + + + pass by value, fixed-length + + + + + pass by reference, fixed-length + + + + + pass by reference, variable-length + + + + + + + By-value types can only be 1, 2, or 4 bytes in length + (also 8 bytes, if sizeof(Datum) is 8 on your machine). + You should be careful to define your types such that they will be the + same size (in bytes) on all architectures. For example, the + long type is dangerous because it is 4 bytes on some + machines and 8 bytes on others, whereas int type is 4 bytes + on most Unix machines. A reasonable implementation of the + int4 type on Unix machines might be: + + +/* 4-byte integer, passed by value */ +typedef int int4; + + + (The actual PostgreSQL C code calls this type int32, because + it is a convention in C that intXX + means XX bits. Note + therefore also that the C type int8 is 1 byte in size. The + SQL type int8 is called int64 in C. See also + .) + + + + On the other hand, fixed-length types of any size can + be passed by-reference. For example, here is a sample + implementation of a PostgreSQL type: + + +/* 16-byte structure, passed by reference */ +typedef struct +{ + double x, y; +} Point; + + + Only pointers to such types can be used when passing + them in and out of PostgreSQL functions. + To return a value of such a type, allocate the right amount of + memory with palloc, fill in the allocated memory, + and return a pointer to it. (Also, if you just want to return the + same value as one of your input arguments that's of the same data type, + you can skip the extra palloc and just return the + pointer to the input value.) + + + + Finally, all variable-length types must also be passed + by reference. All variable-length types must begin + with an opaque length field of exactly 4 bytes, which will be set + by SET_VARSIZE; never set this field directly! All data to + be stored within that type must be located in the memory + immediately following that length field. The + length field contains the total length of the structure, + that is, it includes the size of the length field + itself. + + + + Another important point is to avoid leaving any uninitialized bits + within data type values; for example, take care to zero out any + alignment padding bytes that might be present in structs. Without + this, logically-equivalent constants of your data type might be + seen as unequal by the planner, leading to inefficient (though not + incorrect) plans. + + + + + Never modify the contents of a pass-by-reference input + value. If you do so you are likely to corrupt on-disk data, since + the pointer you are given might point directly into a disk buffer. + The sole exception to this rule is explained in + . + + + + + As an example, we can define the type text as + follows: + + +typedef struct { + int32 length; + char data[FLEXIBLE_ARRAY_MEMBER]; +} text; + + + The [FLEXIBLE_ARRAY_MEMBER] notation means that the actual + length of the data part is not specified by this declaration. + + + + When manipulating + variable-length types, we must be careful to allocate + the correct amount of memory and set the length field correctly. + For example, if we wanted to store 40 bytes in a text + structure, we might use a code fragment like this: + +data, buffer, 40); +... +]]> + + + VARHDRSZ is the same as sizeof(int32), but + it's considered good style to use the macro VARHDRSZ + to refer to the size of the overhead for a variable-length type. + Also, the length field must be set using the + SET_VARSIZE macro, not by simple assignment. + + + + specifies which C type + corresponds to which SQL type when writing a C-language function + that uses a built-in type of PostgreSQL. + The Defined In column gives the header file that + needs to be included to get the type definition. (The actual + definition might be in a different file that is included by the + listed file. It is recommended that users stick to the defined + interface.) Note that you should always include + postgres.h first in any source file, because + it declares a number of things that you will need anyway. + + + + Equivalent C Types for Built-in SQL Types + + + + + + + + SQL Type + + + C Type + + + Defined In + + + + + + boolean + bool + postgres.h (maybe compiler built-in) + + + box + BOX* + utils/geo_decls.h + + + bytea + bytea* + postgres.h + + + "char" + char + (compiler built-in) + + + character + BpChar* + postgres.h + + + cid + CommandId + postgres.h + + + date + DateADT + utils/date.h + + + smallint (int2) + int16 + postgres.h + + + int2vector + int2vector* + postgres.h + + + integer (int4) + int32 + postgres.h + + + real (float4) + float4* + postgres.h + + + double precision (float8) + float8* + postgres.h + + + interval + Interval* + datatype/timestamp.h + + + lseg + LSEG* + utils/geo_decls.h + + + name + Name + postgres.h + + + oid + Oid + postgres.h + + + oidvector + oidvector* + postgres.h + + + path + PATH* + utils/geo_decls.h + + + point + POINT* + utils/geo_decls.h + + + regproc + regproc + postgres.h + + + text + text* + postgres.h + + + tid + ItemPointer + storage/itemptr.h + + + time + TimeADT + utils/date.h + + + time with time zone + TimeTzADT + utils/date.h + + + timestamp + Timestamp + datatype/timestamp.h + + + varchar + VarChar* + postgres.h + + + xid + TransactionId + postgres.h + + + +
+ + + Now that we've gone over all of the possible structures + for base types, we can show some examples of real functions. + +
+ + + Version 1 Calling Conventions + + + The version-1 calling convention relies on macros to suppress most + of the complexity of passing arguments and results. The C declaration + of a version-1 function is always: + +Datum funcname(PG_FUNCTION_ARGS) + + In addition, the macro call: + +PG_FUNCTION_INFO_V1(funcname); + + must appear in the same source file. (Conventionally, it's + written just before the function itself.) This macro call is not + needed for internal-language functions, since + PostgreSQL assumes that all internal functions + use the version-1 convention. It is, however, required for + dynamically-loaded functions. + + + + In a version-1 function, each actual argument is fetched using a + PG_GETARG_xxx() + macro that corresponds to the argument's data type. (In non-strict + functions there needs to be a previous check about argument null-ness + using PG_ARGISNULL(); see below.) + The result is returned using a + PG_RETURN_xxx() + macro for the return type. + PG_GETARG_xxx() + takes as its argument the number of the function argument to + fetch, where the count starts at 0. + PG_RETURN_xxx() + takes as its argument the actual value to return. + + + + Here are some examples using the version-1 calling convention: + + + +#include "fmgr.h" +#include "utils/geo_decls.h" + +PG_MODULE_MAGIC; + +/* by value */ + +PG_FUNCTION_INFO_V1(add_one); + +Datum +add_one(PG_FUNCTION_ARGS) +{ + int32 arg = PG_GETARG_INT32(0); + + PG_RETURN_INT32(arg + 1); +} + +/* by reference, fixed length */ + +PG_FUNCTION_INFO_V1(add_one_float8); + +Datum +add_one_float8(PG_FUNCTION_ARGS) +{ + /* The macros for FLOAT8 hide its pass-by-reference nature. */ + float8 arg = PG_GETARG_FLOAT8(0); + + PG_RETURN_FLOAT8(arg + 1.0); +} + +PG_FUNCTION_INFO_V1(makepoint); + +Datum +makepoint(PG_FUNCTION_ARGS) +{ + /* Here, the pass-by-reference nature of Point is not hidden. */ + Point *pointx = PG_GETARG_POINT_P(0); + Point *pointy = PG_GETARG_POINT_P(1); + Point *new_point = (Point *) palloc(sizeof(Point)); + + new_point->x = pointx->x; + new_point->y = pointy->y; + + PG_RETURN_POINT_P(new_point); +} + +/* by reference, variable length */ + +PG_FUNCTION_INFO_V1(copytext); + +Datum +copytext(PG_FUNCTION_ARGS) +{ + text *t = PG_GETARG_TEXT_PP(0); + + /* + * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the + * VARHDRSZ or VARHDRSZ_SHORT of its header. Construct the copy with a + * full-length header. + */ + text *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ); + SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ); + + /* + * VARDATA is a pointer to the data region of the new struct. The source + * could be a short datum, so retrieve its data through VARDATA_ANY. + */ + memcpy((void *) VARDATA(new_t), /* destination */ + (void *) VARDATA_ANY(t), /* source */ + VARSIZE_ANY_EXHDR(t)); /* how many bytes */ + PG_RETURN_TEXT_P(new_t); +} + +PG_FUNCTION_INFO_V1(concat_text); + +Datum +concat_text(PG_FUNCTION_ARGS) +{ + text *arg1 = PG_GETARG_TEXT_PP(0); + text *arg2 = PG_GETARG_TEXT_PP(1); + int32 arg1_size = VARSIZE_ANY_EXHDR(arg1); + int32 arg2_size = VARSIZE_ANY_EXHDR(arg2); + int32 new_text_size = arg1_size + arg2_size + VARHDRSZ; + text *new_text = (text *) palloc(new_text_size); + + SET_VARSIZE(new_text, new_text_size); + memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size); + memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size); + PG_RETURN_TEXT_P(new_text); +} +]]> + + + + Supposing that the above code has been prepared in file + funcs.c and compiled into a shared object, + we could define the functions to PostgreSQL + with commands like this: + + + +CREATE FUNCTION add_one(integer) RETURNS integer + AS 'DIRECTORY/funcs', 'add_one' + LANGUAGE C STRICT; + +-- note overloading of SQL function name "add_one" +CREATE FUNCTION add_one(double precision) RETURNS double precision + AS 'DIRECTORY/funcs', 'add_one_float8' + LANGUAGE C STRICT; + +CREATE FUNCTION makepoint(point, point) RETURNS point + AS 'DIRECTORY/funcs', 'makepoint' + LANGUAGE C STRICT; + +CREATE FUNCTION copytext(text) RETURNS text + AS 'DIRECTORY/funcs', 'copytext' + LANGUAGE C STRICT; + +CREATE FUNCTION concat_text(text, text) RETURNS text + AS 'DIRECTORY/funcs', 'concat_text' + LANGUAGE C STRICT; + + + + Here, DIRECTORY stands for the + directory of the shared library file (for instance the + PostgreSQL tutorial directory, which + contains the code for the examples used in this section). + (Better style would be to use just 'funcs' in the + AS clause, after having added + DIRECTORY to the search path. In any + case, we can omit the system-specific extension for a shared + library, commonly .so.) + + + + Notice that we have specified the functions as strict, + meaning that + the system should automatically assume a null result if any input + value is null. By doing this, we avoid having to check for null inputs + in the function code. Without this, we'd have to check for null values + explicitly, using PG_ARGISNULL(). + + + + The macro PG_ARGISNULL(n) + allows a function to test whether each input is null. (Of course, doing + this is only necessary in functions not declared strict.) + As with the + PG_GETARG_xxx() macros, + the input arguments are counted beginning at zero. Note that one + should refrain from executing + PG_GETARG_xxx() until + one has verified that the argument isn't null. + To return a null result, execute PG_RETURN_NULL(); + this works in both strict and nonstrict functions. + + + + At first glance, the version-1 coding conventions might appear + to be just pointless obscurantism, compared to using + plain C calling conventions. They do however allow + us to deal with NULLable arguments/return values, + and toasted (compressed or out-of-line) values. + + + + Other options provided by the version-1 interface are two + variants of the + PG_GETARG_xxx() + macros. The first of these, + PG_GETARG_xxx_COPY(), + guarantees to return a copy of the specified argument that is + safe for writing into. (The normal macros will sometimes return a + pointer to a value that is physically stored in a table, which + must not be written to. Using the + PG_GETARG_xxx_COPY() + macros guarantees a writable result.) + The second variant consists of the + PG_GETARG_xxx_SLICE() + macros which take three arguments. The first is the number of the + function argument (as above). The second and third are the offset and + length of the segment to be returned. Offsets are counted from + zero, and a negative length requests that the remainder of the + value be returned. These macros provide more efficient access to + parts of large values in the case where they have storage type + external. (The storage type of a column can be specified using + ALTER TABLE tablename ALTER + COLUMN colname SET STORAGE + storagetype. storagetype is one of + plain, external, extended, + or main.) + + + + Finally, the version-1 function call conventions make it possible + to return set results () and + implement trigger functions () and + procedural-language call handlers (). For more details + see src/backend/utils/fmgr/README in the + source distribution. + + + + + Writing Code + + + Before we turn to the more advanced topics, we should discuss + some coding rules for PostgreSQL + C-language functions. While it might be possible to load functions + written in languages other than C into + PostgreSQL, this is usually difficult + (when it is possible at all) because other languages, such as + C++, FORTRAN, or Pascal often do not follow the same calling + convention as C. That is, other languages do not pass argument + and return values between functions in the same way. For this + reason, we will assume that your C-language functions are + actually written in C. + + + + The basic rules for writing and building C functions are as follows: + + + + + Use pg_config + --includedir-serverpg_configwith user-defined C functions + to find out where the PostgreSQL server header + files are installed on your system (or the system that your + users will be running on). + + + + + + Compiling and linking your code so that it can be dynamically + loaded into PostgreSQL always + requires special flags. See for a + detailed explanation of how to do it for your particular + operating system. + + + + + + Remember to define a magic block for your shared library, + as described in . + + + + + + When allocating memory, use the + PostgreSQL functions + pallocpalloc and pfreepfree + instead of the corresponding C library functions + malloc and free. + The memory allocated by palloc will be + freed automatically at the end of each transaction, preventing + memory leaks. + + + + + + Always zero the bytes of your structures using memset + (or allocate them with palloc0 in the first place). + Even if you assign to each field of your structure, there might be + alignment padding (holes in the structure) that contain + garbage values. Without this, it's difficult to + support hash indexes or hash joins, as you must pick out only + the significant bits of your data structure to compute a hash. + The planner also sometimes relies on comparing constants via + bitwise equality, so you can get undesirable planning results if + logically-equivalent values aren't bitwise equal. + + + + + + Most of the internal PostgreSQL + types are declared in postgres.h, while + the function manager interfaces + (PG_FUNCTION_ARGS, etc.) are in + fmgr.h, so you will need to include at + least these two files. For portability reasons it's best to + include postgres.h first, + before any other system or user header files. Including + postgres.h will also include + elog.h and palloc.h + for you. + + + + + + Symbol names defined within object files must not conflict + with each other or with symbols defined in the + PostgreSQL server executable. You + will have to rename your functions or variables if you get + error messages to this effect. + + + + + + +&dfunc; + + + Composite-Type Arguments + + + Composite types do not have a fixed layout like C structures. + Instances of a composite type can contain null fields. In + addition, composite types that are part of an inheritance + hierarchy can have different fields than other members of the + same inheritance hierarchy. Therefore, + PostgreSQL provides a function + interface for accessing fields of composite types from C. + + + + Suppose we want to write a function to answer the query: + + +SELECT name, c_overpaid(emp, 1500) AS overpaid + FROM emp + WHERE name = 'Bill' OR name = 'Sam'; + + + Using the version-1 calling conventions, we can define + c_overpaid as: + + limit); +} +]]> + + + + + GetAttributeByName is the + PostgreSQL system function that + returns attributes out of the specified row. It has + three arguments: the argument of type HeapTupleHeader passed + into + the function, the name of the desired attribute, and a + return parameter that tells whether the attribute + is null. GetAttributeByName returns a Datum + value that you can convert to the proper data type by using the + appropriate DatumGetXXX() + macro. Note that the return value is meaningless if the null flag is + set; always check the null flag before trying to do anything with the + result. + + + + There is also GetAttributeByNum, which selects + the target attribute by column number instead of name. + + + + The following command declares the function + c_overpaid in SQL: + + +CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean + AS 'DIRECTORY/funcs', 'c_overpaid' + LANGUAGE C STRICT; + + + Notice we have used STRICT so that we did not have to + check whether the input arguments were NULL. + + + + + Returning Rows (Composite Types) + + + To return a row or composite-type value from a C-language + function, you can use a special API that provides macros and + functions to hide most of the complexity of building composite + data types. To use this API, the source file must include: + +#include "funcapi.h" + + + + + There are two ways you can build a composite data value (henceforth + a tuple): you can build it from an array of Datum values, + or from an array of C strings that can be passed to the input + conversion functions of the tuple's column data types. In either + case, you first need to obtain or construct a TupleDesc + descriptor for the tuple structure. When working with Datums, you + pass the TupleDesc to BlessTupleDesc, + and then call heap_form_tuple for each row. When working + with C strings, you pass the TupleDesc to + TupleDescGetAttInMetadata, and then call + BuildTupleFromCStrings for each row. In the case of a + function returning a set of tuples, the setup steps can all be done + once during the first call of the function. + + + + Several helper functions are available for setting up the needed + TupleDesc. The recommended way to do this in most + functions returning composite values is to call: + +TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, + Oid *resultTypeId, + TupleDesc *resultTupleDesc) + + passing the same fcinfo struct passed to the calling function + itself. (This of course requires that you use the version-1 + calling conventions.) resultTypeId can be specified + as NULL or as the address of a local variable to receive the + function's result type OID. resultTupleDesc should be the + address of a local TupleDesc variable. Check that the + result is TYPEFUNC_COMPOSITE; if so, + resultTupleDesc has been filled with the needed + TupleDesc. (If it is not, you can report an error along + the lines of function returning record called in context that + cannot accept type record.) + + + + + get_call_result_type can resolve the actual type of a + polymorphic function result; so it is useful in functions that return + scalar polymorphic results, not only functions that return composites. + The resultTypeId output is primarily useful for functions + returning polymorphic scalars. + + + + + + get_call_result_type has a sibling + get_expr_result_type, which can be used to resolve the + expected output type for a function call represented by an expression + tree. This can be used when trying to determine the result type from + outside the function itself. There is also + get_func_result_type, which can be used when only the + function's OID is available. However these functions are not able + to deal with functions declared to return record, and + get_func_result_type cannot resolve polymorphic types, + so you should preferentially use get_call_result_type. + + + + + Older, now-deprecated functions for obtaining + TupleDescs are: + +TupleDesc RelationNameGetTupleDesc(const char *relname) + + to get a TupleDesc for the row type of a named relation, + and: + +TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) + + to get a TupleDesc based on a type OID. This can + be used to get a TupleDesc for a base or + composite type. It will not work for a function that returns + record, however, and it cannot resolve polymorphic + types. + + + + Once you have a TupleDesc, call: + +TupleDesc BlessTupleDesc(TupleDesc tupdesc) + + if you plan to work with Datums, or: + +AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc) + + if you plan to work with C strings. If you are writing a function + returning set, you can save the results of these functions in the + FuncCallContext structure — use the + tuple_desc or attinmeta field + respectively. + + + + When working with Datums, use: + +HeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull) + + to build a HeapTuple given user data in Datum form. + + + + When working with C strings, use: + +HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values) + + to build a HeapTuple given user data + in C string form. values is an array of C strings, + one for each attribute of the return row. Each C string should be in + the form expected by the input function of the attribute data + type. In order to return a null value for one of the attributes, + the corresponding pointer in the values array + should be set to NULL. This function will need to + be called again for each row you return. + + + + Once you have built a tuple to return from your function, it + must be converted into a Datum. Use: + +HeapTupleGetDatum(HeapTuple tuple) + + to convert a HeapTuple into a valid Datum. This + Datum can be returned directly if you intend to return + just a single row, or it can be used as the current return value + in a set-returning function. + + + + An example appears in the next section. + + + + + + Returning Sets + + + C-language functions have two options for returning sets (multiple + rows). In one method, called ValuePerCall + mode, a set-returning function is called repeatedly (passing the same + arguments each time) and it returns one new row on each call, until + it has no more rows to return and signals that by returning NULL. + The set-returning function (SRF) must therefore + save enough state across calls to remember what it was doing and + return the correct next item on each call. + In the other method, called Materialize mode, + an SRF fills and returns a tuplestore object containing its + entire result; then only one call occurs for the whole result, and + no inter-call state is needed. + + + + When using ValuePerCall mode, it is important to remember that the + query is not guaranteed to be run to completion; that is, due to + options such as LIMIT, the executor might stop + making calls to the set-returning function before all rows have been + fetched. This means it is not safe to perform cleanup activities in + the last call, because that might not ever happen. It's recommended + to use Materialize mode for functions that need access to external + resources, such as file descriptors. + + + + The remainder of this section documents a set of helper macros that + are commonly used (though not required to be used) for SRFs using + ValuePerCall mode. Additional details about Materialize mode can be + found in src/backend/utils/fmgr/README. Also, + the contrib modules in + the PostgreSQL source distribution contain + many examples of SRFs using both ValuePerCall and Materialize mode. + + + + To use the ValuePerCall support macros described here, + include funcapi.h. These macros work with a + structure FuncCallContext that contains the + state that needs to be saved across calls. Within the calling + SRF, fcinfo->flinfo->fn_extra is used to + hold a pointer to FuncCallContext across + calls. The macros automatically fill that field on first use, + and expect to find the same pointer there on subsequent uses. + +typedef struct FuncCallContext +{ + /* + * Number of times we've been called before + * + * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and + * incremented for you every time SRF_RETURN_NEXT() is called. + */ + uint64 call_cntr; + + /* + * OPTIONAL maximum number of calls + * + * max_calls is here for convenience only and setting it is optional. + * If not set, you must provide alternative means to know when the + * function is done. + */ + uint64 max_calls; + + /* + * OPTIONAL pointer to miscellaneous user-provided context information + * + * user_fctx is for use as a pointer to your own data to retain + * arbitrary context information between calls of your function. + */ + void *user_fctx; + + /* + * OPTIONAL pointer to struct containing attribute type input metadata + * + * attinmeta is for use when returning tuples (i.e., composite data types) + * and is not used when returning base data types. It is only needed + * if you intend to use BuildTupleFromCStrings() to create the return + * tuple. + */ + AttInMetadata *attinmeta; + + /* + * memory context used for structures that must live for multiple calls + * + * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used + * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory + * context for any memory that is to be reused across multiple calls + * of the SRF. + */ + MemoryContext multi_call_memory_ctx; + + /* + * OPTIONAL pointer to struct containing tuple description + * + * tuple_desc is for use when returning tuples (i.e., composite data types) + * and is only needed if you are going to build the tuples with + * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that + * the TupleDesc pointer stored here should usually have been run through + * BlessTupleDesc() first. + */ + TupleDesc tuple_desc; + +} FuncCallContext; + + + + + The macros to be used by an SRF using this + infrastructure are: + +SRF_IS_FIRSTCALL() + + Use this to determine if your function is being called for the first or a + subsequent time. On the first call (only), call: + +SRF_FIRSTCALL_INIT() + + to initialize the FuncCallContext. On every function call, + including the first, call: + +SRF_PERCALL_SETUP() + + to set up for using the FuncCallContext. + + + + If your function has data to return in the current call, use: + +SRF_RETURN_NEXT(funcctx, result) + + to return it to the caller. (result must be of type + Datum, either a single value or a tuple prepared as + described above.) Finally, when your function is finished + returning data, use: + +SRF_RETURN_DONE(funcctx) + + to clean up and end the SRF. + + + + The memory context that is current when the SRF is called is + a transient context that will be cleared between calls. This means + that you do not need to call pfree on everything + you allocated using palloc; it will go away anyway. However, if you want to allocate + any data structures to live across calls, you need to put them somewhere + else. The memory context referenced by + multi_call_memory_ctx is a suitable location for any + data that needs to survive until the SRF is finished running. In most + cases, this means that you should switch into + multi_call_memory_ctx while doing the + first-call setup. + Use funcctx->user_fctx to hold a pointer to + any such cross-call data structures. + (Data you allocate + in multi_call_memory_ctx will go away + automatically when the query ends, so it is not necessary to free + that data manually, either.) + + + + + While the actual arguments to the function remain unchanged between + calls, if you detoast the argument values (which is normally done + transparently by the + PG_GETARG_xxx macro) + in the transient context then the detoasted copies will be freed on + each cycle. Accordingly, if you keep references to such values in + your user_fctx, you must either copy them into the + multi_call_memory_ctx after detoasting, or ensure + that you detoast the values only in that context. + + + + + A complete pseudo-code example looks like the following: + +Datum +my_set_returning_function(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + Datum result; + further declarations as needed + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + /* One-time setup code appears here: */ + user code + if returning composite + build TupleDesc, and perhaps AttInMetadata + endif returning composite + user code + MemoryContextSwitchTo(oldcontext); + } + + /* Each-time setup code appears here: */ + user code + funcctx = SRF_PERCALL_SETUP(); + user code + + /* this is just one way we might test whether we are done: */ + if (funcctx->call_cntr < funcctx->max_calls) + { + /* Here we want to return another item: */ + user code + obtain result Datum + SRF_RETURN_NEXT(funcctx, result); + } + else + { + /* Here we are done returning items, so just report that fact. */ + /* (Resist the temptation to put cleanup code here.) */ + SRF_RETURN_DONE(funcctx); + } +} + + + + + A complete example of a simple SRF returning a composite type + looks like: +multi_call_memory_ctx); + + /* total number of tuples to be returned */ + funcctx->max_calls = PG_GETARG_UINT32(0); + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + + /* + * generate attribute metadata needed later to produce tuples from raw + * C strings + */ + attinmeta = TupleDescGetAttInMetadata(tupdesc); + funcctx->attinmeta = attinmeta; + + MemoryContextSwitchTo(oldcontext); + } + + /* stuff done on every call of the function */ + funcctx = SRF_PERCALL_SETUP(); + + call_cntr = funcctx->call_cntr; + max_calls = funcctx->max_calls; + attinmeta = funcctx->attinmeta; + + if (call_cntr < max_calls) /* do when there is more left to send */ + { + char **values; + HeapTuple tuple; + Datum result; + + /* + * Prepare a values array for building the returned tuple. + * This should be an array of C strings which will + * be processed later by the type input functions. + */ + values = (char **) palloc(3 * sizeof(char *)); + values[0] = (char *) palloc(16 * sizeof(char)); + values[1] = (char *) palloc(16 * sizeof(char)); + values[2] = (char *) palloc(16 * sizeof(char)); + + snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1)); + snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1)); + snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1)); + + /* build a tuple */ + tuple = BuildTupleFromCStrings(attinmeta, values); + + /* make the tuple into a datum */ + result = HeapTupleGetDatum(tuple); + + /* clean up (this is not really necessary) */ + pfree(values[0]); + pfree(values[1]); + pfree(values[2]); + pfree(values); + + SRF_RETURN_NEXT(funcctx, result); + } + else /* do when there is no more left */ + { + SRF_RETURN_DONE(funcctx); + } +} +]]> + + + One way to declare this function in SQL is: + +CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer); + +CREATE OR REPLACE FUNCTION retcomposite(integer, integer) + RETURNS SETOF __retcomposite + AS 'filename', 'retcomposite' + LANGUAGE C IMMUTABLE STRICT; + + A different way is to use OUT parameters: + +CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer, + OUT f1 integer, OUT f2 integer, OUT f3 integer) + RETURNS SETOF record + AS 'filename', 'retcomposite' + LANGUAGE C IMMUTABLE STRICT; + + Notice that in this method the output type of the function is formally + an anonymous record type. + + + + + Polymorphic Arguments and Return Types + + + C-language functions can be declared to accept and + return the polymorphic types described in . + When a function's arguments or return types + are defined as polymorphic types, the function author cannot know + in advance what data type it will be called with, or + need to return. There are two routines provided in fmgr.h + to allow a version-1 C function to discover the actual data types + of its arguments and the type it is expected to return. The routines are + called get_fn_expr_rettype(FmgrInfo *flinfo) and + get_fn_expr_argtype(FmgrInfo *flinfo, int argnum). + They return the result or argument type OID, or InvalidOid if the + information is not available. + The structure flinfo is normally accessed as + fcinfo->flinfo. The parameter argnum + is zero based. get_call_result_type can also be used + as an alternative to get_fn_expr_rettype. + There is also get_fn_expr_variadic, which can be used to + find out whether variadic arguments have been merged into an array. + This is primarily useful for VARIADIC "any" functions, + since such merging will always have occurred for variadic functions + taking ordinary array types. + + + + For example, suppose we want to write a function to accept a single + element of any type, and return a one-dimensional array of that type: + + +PG_FUNCTION_INFO_V1(make_array); +Datum +make_array(PG_FUNCTION_ARGS) +{ + ArrayType *result; + Oid element_type = get_fn_expr_argtype(fcinfo->flinfo, 0); + Datum element; + bool isnull; + int16 typlen; + bool typbyval; + char typalign; + int ndims; + int dims[MAXDIM]; + int lbs[MAXDIM]; + + if (!OidIsValid(element_type)) + elog(ERROR, "could not determine data type of input"); + + /* get the provided element, being careful in case it's NULL */ + isnull = PG_ARGISNULL(0); + if (isnull) + element = (Datum) 0; + else + element = PG_GETARG_DATUM(0); + + /* we have one dimension */ + ndims = 1; + /* and one element */ + dims[0] = 1; + /* and lower bound is 1 */ + lbs[0] = 1; + + /* get required info about the element type */ + get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign); + + /* now build the array */ + result = construct_md_array(&element, &isnull, ndims, dims, lbs, + element_type, typlen, typbyval, typalign); + + PG_RETURN_ARRAYTYPE_P(result); +} + + + + + The following command declares the function + make_array in SQL: + + +CREATE FUNCTION make_array(anyelement) RETURNS anyarray + AS 'DIRECTORY/funcs', 'make_array' + LANGUAGE C IMMUTABLE; + + + + + There is a variant of polymorphism that is only available to C-language + functions: they can be declared to take parameters of type + "any". (Note that this type name must be double-quoted, + since it's also an SQL reserved word.) This works like + anyelement except that it does not constrain different + "any" arguments to be the same type, nor do they help + determine the function's result type. A C-language function can also + declare its final parameter to be VARIADIC "any". This will + match one or more actual arguments of any type (not necessarily the same + type). These arguments will not be gathered into an array + as happens with normal variadic functions; they will just be passed to + the function separately. The PG_NARGS() macro and the + methods described above must be used to determine the number of actual + arguments and their types when using this feature. Also, users of such + a function might wish to use the VARIADIC keyword in their + function call, with the expectation that the function would treat the + array elements as separate arguments. The function itself must implement + that behavior if wanted, after using get_fn_expr_variadic to + detect that the actual argument was marked with VARIADIC. + + + + + Shared Memory and LWLocks + + + Add-ins can reserve LWLocks and an allocation of shared memory on server + startup. The add-in's shared library must be preloaded by specifying + it in + shared_preload_libraries. + Shared memory is reserved by calling: + +void RequestAddinShmemSpace(int size) + + from your _PG_init function. + + + LWLocks are reserved by calling: + +void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) + + from _PG_init. This will ensure that an array of + num_lwlocks LWLocks is available under the name + tranche_name. Use GetNamedLWLockTranche + to get a pointer to this array. + + + To avoid possible race-conditions, each backend should use the LWLock + AddinShmemInitLock when connecting to and initializing + its allocation of shared memory, as shown here: + +static mystruct *ptr = NULL; + +if (!ptr) +{ + bool found; + + LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); + ptr = ShmemInitStruct("my struct name", size, &found); + if (!found) + { + initialize contents of shmem area; + acquire any requested LWLocks using: + ptr->locks = GetNamedLWLockTranche("my tranche name"); + } + LWLockRelease(AddinShmemInitLock); +} + + + + + + Using C++ for Extensibility + + + C++ + + + + Although the PostgreSQL backend is written in + C, it is possible to write extensions in C++ if these guidelines are + followed: + + + + + All functions accessed by the backend must present a C interface + to the backend; these C functions can then call C++ functions. + For example, extern C linkage is required for + backend-accessed functions. This is also necessary for any + functions that are passed as pointers between the backend and + C++ code. + + + + + Free memory using the appropriate deallocation method. For example, + most backend memory is allocated using palloc(), so use + pfree() to free it. Using C++ + delete in such cases will fail. + + + + + Prevent exceptions from propagating into the C code (use a catch-all + block at the top level of all extern C functions). This + is necessary even if the C++ code does not explicitly throw any + exceptions, because events like out-of-memory can still throw + exceptions. Any exceptions must be caught and appropriate errors + passed back to the C interface. If possible, compile C++ with + to eliminate exceptions entirely; in such + cases, you must check for failures in your C++ code, e.g., check for + NULL returned by new(). + + + + + If calling backend functions from C++ code, be sure that the + C++ call stack contains only plain old data structures + (POD). This is necessary because backend errors + generate a distant longjmp() that does not properly + unroll a C++ call stack with non-POD objects. + + + + + + + In summary, it is best to place C++ code behind a wall of + extern C functions that interface to the backend, + and avoid exception, memory, and call stack leakage. + + + +
+ + + Function Optimization Information + + + optimization information + for functions + + + + By default, a function is just a black box that the + database system knows very little about the behavior of. However, + that means that queries using the function may be executed much less + efficiently than they could be. It is possible to supply additional + knowledge that helps the planner optimize function calls. + + + + Some basic facts can be supplied by declarative annotations provided in + the CREATE FUNCTION command. Most important of + these is the function's volatility + category (IMMUTABLE, STABLE, + or VOLATILE); one should always be careful to + specify this correctly when defining a function. + The parallel safety property (PARALLEL + UNSAFE, PARALLEL RESTRICTED, or + PARALLEL SAFE) must also be specified if you hope + to use the function in parallelized queries. + It can also be useful to specify the function's estimated execution + cost, and/or the number of rows a set-returning function is estimated + to return. However, the declarative way of specifying those two + facts only allows specifying a constant value, which is often + inadequate. + + + + It is also possible to attach a planner support + function to an SQL-callable function (called + its target function), and thereby provide + knowledge about the target function that is too complex to be + represented declaratively. Planner support functions have to be + written in C (although their target functions might not be), so this is + an advanced feature that relatively few people will use. + + + + A planner support function must have the SQL signature + +supportfn(internal) returns internal + + It is attached to its target function by specifying + the SUPPORT clause when creating the target function. + + + + The details of the API for planner support functions can be found in + file src/include/nodes/supportnodes.h in the + PostgreSQL source code. Here we provide + just an overview of what planner support functions can do. + The set of possible requests to a support function is extensible, + so more things might be possible in future versions. + + + + Some function calls can be simplified during planning based on + properties specific to the function. For example, + int4mul(n, 1) could be simplified to + just n. This type of transformation can be + performed by a planner support function, by having it implement + the SupportRequestSimplify request type. + The support function will be called for each instance of its target + function found in a query parse tree. If it finds that the particular + call can be simplified into some other form, it can build and return a + parse tree representing that expression. This will automatically work + for operators based on the function, too — in the example just + given, n * 1 would also be simplified to + n. + (But note that this is just an example; this particular + optimization is not actually performed by + standard PostgreSQL.) + We make no guarantee that PostgreSQL will + never call the target function in cases that the support function could + simplify. Ensure rigorous equivalence between the simplified + expression and an actual execution of the target function. + + + + For target functions that return boolean, it is often useful to estimate + the fraction of rows that will be selected by a WHERE clause using that + function. This can be done by a support function that implements + the SupportRequestSelectivity request type. + + + + If the target function's run time is highly dependent on its inputs, + it may be useful to provide a non-constant cost estimate for it. + This can be done by a support function that implements + the SupportRequestCost request type. + + + + For target functions that return sets, it is often useful to provide + a non-constant estimate for the number of rows that will be returned. + This can be done by a support function that implements + the SupportRequestRows request type. + + + + For target functions that return boolean, it may be possible to + convert a function call appearing in WHERE into an indexable operator + clause or clauses. The converted clauses might be exactly equivalent + to the function's condition, or they could be somewhat weaker (that is, + they might accept some values that the function condition does not). + In the latter case the index condition is said to + be lossy; it can still be used to scan an index, + but the function call will have to be executed for each row returned by + the index to see if it really passes the WHERE condition or not. + To create such conditions, the support function must implement + the SupportRequestIndexCondition request type. + + diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml new file mode 100644 index 000000000000..0a4fe9a776ab --- /dev/null +++ b/doc/src/sgml/xindex.sgml @@ -0,0 +1,1450 @@ + + + + Interfacing Extensions to Indexes + + + index + for user-defined data type + + + + The procedures described thus far let you define new types, new + functions, and new operators. However, we cannot yet define an + index on a column of a new data type. To do this, we must define an + operator class for the new data type. Later in this + section, we will illustrate this concept in an example: a new + operator class for the B-tree index method that stores and sorts + complex numbers in ascending absolute value order. + + + + Operator classes can be grouped into operator families + to show the relationships between semantically compatible classes. + When only a single data type is involved, an operator class is sufficient, + so we'll focus on that case first and then return to operator families. + + + + Index Methods and Operator Classes + + + The pg_am table contains one row for every + index method (internally known as access method). Support for + regular access to tables is built into + PostgreSQL, but all index methods are + described in pg_am. It is possible to add a + new index access method by writing the necessary code and + then creating an entry in pg_am — but that is + beyond the scope of this chapter (see ). + + + + The routines for an index method do not directly know anything + about the data types that the index method will operate on. + Instead, an operator + classoperator class + identifies the set of operations that the index method needs to use + to work with a particular data type. Operator classes are so + called because one thing they specify is the set of + WHERE-clause operators that can be used with an index + (i.e., can be converted into an index-scan qualification). An + operator class can also specify some support + function that are needed by the internal operations of the + index method, but do not directly correspond to any + WHERE-clause operator that can be used with the index. + + + + It is possible to define multiple operator classes for the same + data type and index method. By doing this, multiple + sets of indexing semantics can be defined for a single data type. + For example, a B-tree index requires a sort ordering to be defined + for each data type it works on. + It might be useful for a complex-number data type + to have one B-tree operator class that sorts the data by complex + absolute value, another that sorts by real part, and so on. + Typically, one of the operator classes will be deemed most commonly + useful and will be marked as the default operator class for that + data type and index method. + + + + The same operator class name + can be used for several different index methods (for example, both B-tree + and hash index methods have operator classes named + int4_ops), but each such class is an independent + entity and must be defined separately. + + + + + Index Method Strategies + + + The operators associated with an operator class are identified by + strategy numbers, which serve to identify the semantics of + each operator within the context of its operator class. + For example, B-trees impose a strict ordering on keys, lesser to greater, + and so operators like less than and greater than or equal + to are interesting with respect to a B-tree. + Because + PostgreSQL allows the user to define operators, + PostgreSQL cannot look at the name of an operator + (e.g., < or >=) and tell what kind of + comparison it is. Instead, the index method defines a set of + strategies, which can be thought of as generalized operators. + Each operator class specifies which actual operator corresponds to each + strategy for a particular data type and interpretation of the index + semantics. + + + + The B-tree index method defines five strategies, shown in . + + + + B-Tree Strategies + + + + Operation + Strategy Number + + + + + less than + 1 + + + less than or equal + 2 + + + equal + 3 + + + greater than or equal + 4 + + + greater than + 5 + + + +
+ + + Hash indexes support only equality comparisons, and so they use only one + strategy, shown in . + + + + Hash Strategies + + + + Operation + Strategy Number + + + + + equal + 1 + + + +
+ + + GiST indexes are more flexible: they do not have a fixed set of + strategies at all. Instead, the consistency support routine + of each particular GiST operator class interprets the strategy numbers + however it likes. As an example, several of the built-in GiST index + operator classes index two-dimensional geometric objects, providing + the R-tree strategies shown in + . Four of these are true + two-dimensional tests (overlaps, same, contains, contained by); + four of them consider only the X direction; and the other four + provide the same tests in the Y direction. + + + + GiST Two-Dimensional <quote>R-tree</quote> Strategies + + + + Operation + Strategy Number + + + + + strictly left of + 1 + + + does not extend to right of + 2 + + + overlaps + 3 + + + does not extend to left of + 4 + + + strictly right of + 5 + + + same + 6 + + + contains + 7 + + + contained by + 8 + + + does not extend above + 9 + + + strictly below + 10 + + + strictly above + 11 + + + does not extend below + 12 + + + +
+ + + SP-GiST indexes are similar to GiST indexes in flexibility: they don't have + a fixed set of strategies. Instead the support routines of each operator + class interpret the strategy numbers according to the operator class's + definition. As an example, the strategy numbers used by the built-in + operator classes for points are shown in . + + + + SP-GiST Point Strategies + + + + Operation + Strategy Number + + + + + strictly left of + 1 + + + strictly right of + 5 + + + same + 6 + + + contained by + 8 + + + strictly below + 10 + + + strictly above + 11 + + + +
+ + + GIN indexes are similar to GiST and SP-GiST indexes, in that they don't + have a fixed set of strategies either. Instead the support routines of + each operator class interpret the strategy numbers according to the + operator class's definition. As an example, the strategy numbers used by + the built-in operator class for arrays are shown in + . + + + + GIN Array Strategies + + + + Operation + Strategy Number + + + + + overlap + 1 + + + contains + 2 + + + is contained by + 3 + + + equal + 4 + + + +
+ + + BRIN indexes are similar to GiST, SP-GiST and GIN indexes in that they + don't have a fixed set of strategies either. Instead the support routines + of each operator class interpret the strategy numbers according to the + operator class's definition. As an example, the strategy numbers used by + the built-in Minmax operator classes are shown in + . + + + + BRIN Minmax Strategies + + + + Operation + Strategy Number + + + + + less than + 1 + + + less than or equal + 2 + + + equal + 3 + + + greater than or equal + 4 + + + greater than + 5 + + + +
+ + + Notice that all the operators listed above return Boolean values. In + practice, all operators defined as index method search operators must + return type boolean, since they must appear at the top + level of a WHERE clause to be used with an index. + (Some index access methods also support ordering operators, + which typically don't return Boolean values; that feature is discussed + in .) + +
+ + + Index Method Support Routines + + + Strategies aren't usually enough information for the system to figure + out how to use an index. In practice, the index methods require + additional support routines in order to work. For example, the B-tree + index method must be able to compare two keys and determine whether one + is greater than, equal to, or less than the other. Similarly, the + hash index method must be able to compute hash codes for key values. + These operations do not correspond to operators used in qualifications in + SQL commands; they are administrative routines used by + the index methods, internally. + + + + Just as with strategies, the operator class identifies which specific + functions should play each of these roles for a given data type and + semantic interpretation. The index method defines the set + of functions it needs, and the operator class identifies the correct + functions to use by assigning them to the support function numbers + specified by the index method. + + + + Additionally, some opclasses allow users to specify parameters which + control their behavior. Each builtin index access method has an optional + options support function, which defines a set of + opclass-specific parameters. + + + + B-trees require a comparison support function, + and allow four additional support functions to be + supplied at the operator class author's option, as shown in . + The requirements for these support functions are explained further in + . + + + + B-Tree Support Functions + + + + + + Function + Support Number + + + + + + Compare two keys and return an integer less than zero, zero, or + greater than zero, indicating whether the first key is less than, + equal to, or greater than the second + + 1 + + + + Return the addresses of C-callable sort support function(s) + (optional) + + 2 + + + + Compare a test value to a base value plus/minus an offset, and return + true or false according to the comparison result (optional) + + 3 + + + + Determine if it is safe for indexes that use the operator + class to apply the btree deduplication optimization (optional) + + 4 + + + + Defines a set of options that are specific to this operator class + (optional) + + 5 + + + +
+ + + Hash indexes require one support function, and allow two additional ones to + be supplied at the operator class author's option, as shown in . + + + + Hash Support Functions + + + + + + Function + Support Number + + + + + Compute the 32-bit hash value for a key + 1 + + + + Compute the 64-bit hash value for a key given a 64-bit salt; if + the salt is 0, the low 32 bits of the result must match the value + that would have been computed by function 1 + (optional) + + 2 + + + + Defines a set of options that are specific to this operator class + (optional) + + 3 + + + +
+ + + GiST indexes have ten support functions, three of which are optional, + as shown in . + (For more information see .) + + + + GiST Support Functions + + + + + + + Function + Description + Support Number + + + + + consistent + determine whether key satisfies the + query qualifier + 1 + + + union + compute union of a set of keys + 2 + + + compress + compute a compressed representation of a key or value + to be indexed + 3 + + + decompress + compute a decompressed representation of a + compressed key + 4 + + + penalty + compute penalty for inserting new key into subtree + with given subtree's key + 5 + + + picksplit + determine which entries of a page are to be moved + to the new page and compute the union keys for resulting pages + 6 + + + equal + compare two keys and return true if they are equal + 7 + + + distance + determine distance from key to query value (optional) + 8 + + + fetch + compute original representation of a compressed key for + index-only scans (optional) + 9 + + + options + + Defines a set of options that are specific to this operator class + (optional) + + 10 + + + +
+ + + SP-GiST indexes have six support functions, one of which is optional, as + shown in . + (For more information see .) + + + + SP-GiST Support Functions + + + + + + + Function + Description + Support Number + + + + + config + provide basic information about the operator class + 1 + + + choose + determine how to insert a new value into an inner tuple + 2 + + + picksplit + determine how to partition a set of values + 3 + + + inner_consistent + determine which sub-partitions need to be searched for a + query + 4 + + + leaf_consistent + determine whether key satisfies the + query qualifier + 5 + + + options + + Defines a set of options that are specific to this operator class + (optional) + + 6 + + + +
+ + + GIN indexes have seven support functions, four of which are optional, + as shown in . + (For more information see .) + + + + GIN Support Functions + + + + + + + Function + Description + Support Number + + + + + compare + + compare two keys and return an integer less than zero, zero, + or greater than zero, indicating whether the first key is less than, + equal to, or greater than the second + + 1 + + + extractValue + extract keys from a value to be indexed + 2 + + + extractQuery + extract keys from a query condition + 3 + + + consistent + + determine whether value matches query condition (Boolean variant) + (optional if support function 6 is present) + + 4 + + + comparePartial + + compare partial key from + query and key from index, and return an integer less than zero, zero, + or greater than zero, indicating whether GIN should ignore this index + entry, treat the entry as a match, or stop the index scan (optional) + + 5 + + + triConsistent + + determine whether value matches query condition (ternary variant) + (optional if support function 4 is present) + + 6 + + + options + + Defines a set of options that are specific to this operator class + (optional) + + 7 + + + +
+ + + BRIN indexes have five basic support functions, one of which is optional, + as shown in . Some versions of + the basic functions require additional support functions to be provided. + (For more information see .) + + + + BRIN Support Functions + + + + + + + Function + Description + Support Number + + + + + opcInfo + + return internal information describing the indexed columns' + summary data + + 1 + + + add_value + add a new value to an existing summary index tuple + 2 + + + consistent + determine whether value matches query condition + 3 + + + union + + compute union of two summary tuples + + 4 + + + options + + Defines a set of options that are specific to this operator class + (optional) + + 5 + + + +
+ + + Unlike search operators, support functions return whichever data + type the particular index method expects; for example in the case + of the comparison function for B-trees, a signed integer. The number + and types of the arguments to each support function are likewise + dependent on the index method. For B-tree and hash the comparison and + hashing support functions take the same input data types as do the + operators included in the operator class, but this is not the case for + most GiST, SP-GiST, GIN, and BRIN support functions. + +
+ + + An Example + + + Now that we have seen the ideas, here is the promised example of + creating a new operator class. + (You can find a working copy of this example in + src/tutorial/complex.c and + src/tutorial/complex.sql in the source + distribution.) + The operator class encapsulates + operators that sort complex numbers in absolute value order, so we + choose the name complex_abs_ops. First, we need + a set of operators. The procedure for defining operators was + discussed in . For an operator class on + B-trees, the operators we require are: + + + absolute-value less-than (strategy 1) + absolute-value less-than-or-equal (strategy 2) + absolute-value equal (strategy 3) + absolute-value greater-than-or-equal (strategy 4) + absolute-value greater-than (strategy 5) + + + + + The least error-prone way to define a related set of comparison operators + is to write the B-tree comparison support function first, and then write the + other functions as one-line wrappers around the support function. This + reduces the odds of getting inconsistent results for corner cases. + Following this approach, we first write: + +x*(c)->x + (c)->y*(c)->y) + +static int +complex_abs_cmp_internal(Complex *a, Complex *b) +{ + double amag = Mag(a), + bmag = Mag(b); + + if (amag < bmag) + return -1; + if (amag > bmag) + return 1; + return 0; +} +]]> + + + Now the less-than function looks like: + + + + + The other four functions differ only in how they compare the internal + function's result to zero. + + + + Next we declare the functions and the operators based on the functions + to SQL: + + +CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool + AS 'filename', 'complex_abs_lt' + LANGUAGE C IMMUTABLE STRICT; + +CREATE OPERATOR < ( + leftarg = complex, rightarg = complex, procedure = complex_abs_lt, + commutator = > , negator = >= , + restrict = scalarltsel, join = scalarltjoinsel +); + + It is important to specify the correct commutator and negator operators, + as well as suitable restriction and join selectivity + functions, otherwise the optimizer will be unable to make effective + use of the index. + + + + Other things worth noting are happening here: + + + + + There can only be one operator named, say, = + and taking type complex for both operands. In this + case we don't have any other operator = for + complex, but if we were building a practical data + type we'd probably want = to be the ordinary + equality operation for complex numbers (and not the equality of + the absolute values). In that case, we'd need to use some other + operator name for complex_abs_eq. + + + + + + Although PostgreSQL can cope with + functions having the same SQL name as long as they have different + argument data types, C can only cope with one global function + having a given name. So we shouldn't name the C function + something simple like abs_eq. Usually it's + a good practice to include the data type name in the C function + name, so as not to conflict with functions for other data types. + + + + + + We could have made the SQL name + of the function abs_eq, relying on + PostgreSQL to distinguish it by + argument data types from any other SQL function of the same name. + To keep the example simple, we make the function have the same + names at the C level and SQL level. + + + + + + + The next step is the registration of the support routine required + by B-trees. The example C code that implements this is in the same + file that contains the operator functions. This is how we declare + the function: + + +CREATE FUNCTION complex_abs_cmp(complex, complex) + RETURNS integer + AS 'filename' + LANGUAGE C IMMUTABLE STRICT; + + + + + Now that we have the required operators and support routine, + we can finally create the operator class: + += , + OPERATOR 5 > , + FUNCTION 1 complex_abs_cmp(complex, complex); +]]> + + + + + And we're done! It should now be possible to create + and use B-tree indexes on complex columns. + + + + We could have written the operator entries more verbosely, as in: + + OPERATOR 1 < (complex, complex) , + + but there is no need to do so when the operators take the same data type + we are defining the operator class for. + + + + The above example assumes that you want to make this new operator class the + default B-tree operator class for the complex data type. + If you don't, just leave out the word DEFAULT. + + + + + Operator Classes and Operator Families + + + So far we have implicitly assumed that an operator class deals with + only one data type. While there certainly can be only one data type in + a particular index column, it is often useful to index operations that + compare an indexed column to a value of a different data type. Also, + if there is use for a cross-data-type operator in connection with an + operator class, it is often the case that the other data type has a + related operator class of its own. It is helpful to make the connections + between related classes explicit, because this can aid the planner in + optimizing SQL queries (particularly for B-tree operator classes, since + the planner contains a great deal of knowledge about how to work with them). + + + + To handle these needs, PostgreSQL + uses the concept of an operator + familyoperator family. + An operator family contains one or more operator classes, and can also + contain indexable operators and corresponding support functions that + belong to the family as a whole but not to any single class within the + family. We say that such operators and functions are loose + within the family, as opposed to being bound into a specific class. + Typically each operator class contains single-data-type operators + while cross-data-type operators are loose in the family. + + + + All the operators and functions in an operator family must have compatible + semantics, where the compatibility requirements are set by the index + method. You might therefore wonder why bother to single out particular + subsets of the family as operator classes; and indeed for many purposes + the class divisions are irrelevant and the family is the only interesting + grouping. The reason for defining operator classes is that they specify + how much of the family is needed to support any particular index. + If there is an index using an operator class, then that operator class + cannot be dropped without dropping the index — but other parts of + the operator family, namely other operator classes and loose operators, + could be dropped. Thus, an operator class should be specified to contain + the minimum set of operators and functions that are reasonably needed + to work with an index on a specific data type, and then related but + non-essential operators can be added as loose members of the operator + family. + + + + As an example, PostgreSQL has a built-in + B-tree operator family integer_ops, which includes operator + classes int8_ops, int4_ops, and + int2_ops for indexes on bigint (int8), + integer (int4), and smallint (int2) + columns respectively. The family also contains cross-data-type comparison + operators allowing any two of these types to be compared, so that an index + on one of these types can be searched using a comparison value of another + type. The family could be duplicated by these definitions: + += , + OPERATOR 5 > , + FUNCTION 1 btint8cmp(int8, int8) , + FUNCTION 2 btint8sortsupport(internal) , + FUNCTION 3 in_range(int8, int8, int8, boolean, boolean) , + FUNCTION 4 btequalimage(oid) ; + +CREATE OPERATOR CLASS int4_ops +DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS + -- standard int4 comparisons + OPERATOR 1 < , + OPERATOR 2 <= , + OPERATOR 3 = , + OPERATOR 4 >= , + OPERATOR 5 > , + FUNCTION 1 btint4cmp(int4, int4) , + FUNCTION 2 btint4sortsupport(internal) , + FUNCTION 3 in_range(int4, int4, int4, boolean, boolean) , + FUNCTION 4 btequalimage(oid) ; + +CREATE OPERATOR CLASS int2_ops +DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS + -- standard int2 comparisons + OPERATOR 1 < , + OPERATOR 2 <= , + OPERATOR 3 = , + OPERATOR 4 >= , + OPERATOR 5 > , + FUNCTION 1 btint2cmp(int2, int2) , + FUNCTION 2 btint2sortsupport(internal) , + FUNCTION 3 in_range(int2, int2, int2, boolean, boolean) , + FUNCTION 4 btequalimage(oid) ; + +ALTER OPERATOR FAMILY integer_ops USING btree ADD + -- cross-type comparisons int8 vs int2 + OPERATOR 1 < (int8, int2) , + OPERATOR 2 <= (int8, int2) , + OPERATOR 3 = (int8, int2) , + OPERATOR 4 >= (int8, int2) , + OPERATOR 5 > (int8, int2) , + FUNCTION 1 btint82cmp(int8, int2) , + + -- cross-type comparisons int8 vs int4 + OPERATOR 1 < (int8, int4) , + OPERATOR 2 <= (int8, int4) , + OPERATOR 3 = (int8, int4) , + OPERATOR 4 >= (int8, int4) , + OPERATOR 5 > (int8, int4) , + FUNCTION 1 btint84cmp(int8, int4) , + + -- cross-type comparisons int4 vs int2 + OPERATOR 1 < (int4, int2) , + OPERATOR 2 <= (int4, int2) , + OPERATOR 3 = (int4, int2) , + OPERATOR 4 >= (int4, int2) , + OPERATOR 5 > (int4, int2) , + FUNCTION 1 btint42cmp(int4, int2) , + + -- cross-type comparisons int4 vs int8 + OPERATOR 1 < (int4, int8) , + OPERATOR 2 <= (int4, int8) , + OPERATOR 3 = (int4, int8) , + OPERATOR 4 >= (int4, int8) , + OPERATOR 5 > (int4, int8) , + FUNCTION 1 btint48cmp(int4, int8) , + + -- cross-type comparisons int2 vs int8 + OPERATOR 1 < (int2, int8) , + OPERATOR 2 <= (int2, int8) , + OPERATOR 3 = (int2, int8) , + OPERATOR 4 >= (int2, int8) , + OPERATOR 5 > (int2, int8) , + FUNCTION 1 btint28cmp(int2, int8) , + + -- cross-type comparisons int2 vs int4 + OPERATOR 1 < (int2, int4) , + OPERATOR 2 <= (int2, int4) , + OPERATOR 3 = (int2, int4) , + OPERATOR 4 >= (int2, int4) , + OPERATOR 5 > (int2, int4) , + FUNCTION 1 btint24cmp(int2, int4) , + + -- cross-type in_range functions + FUNCTION 3 in_range(int4, int4, int8, boolean, boolean) , + FUNCTION 3 in_range(int4, int4, int2, boolean, boolean) , + FUNCTION 3 in_range(int2, int2, int8, boolean, boolean) , + FUNCTION 3 in_range(int2, int2, int4, boolean, boolean) ; +]]> + + + Notice that this definition overloads the operator strategy and + support function numbers: each number occurs multiple times within the + family. This is allowed so long as each instance of a + particular number has distinct input data types. The instances that have + both input types equal to an operator class's input type are the + primary operators and support functions for that operator class, + and in most cases should be declared as part of the operator class rather + than as loose members of the family. + + + + In a B-tree operator family, all the operators in the family must sort + compatibly, as is specified in detail in . + For each + operator in the family there must be a support function having the same + two input data types as the operator. It is recommended that a family be + complete, i.e., for each combination of data types, all operators are + included. Each operator class should include just the non-cross-type + operators and support function for its data type. + + + + To build a multiple-data-type hash operator family, compatible hash + support functions must be created for each data type supported by the + family. Here compatibility means that the functions are guaranteed to + return the same hash code for any two values that are considered equal + by the family's equality operators, even when the values are of different + types. This is usually difficult to accomplish when the types have + different physical representations, but it can be done in some cases. + Furthermore, casting a value from one data type represented in the operator + family to another data type also represented in the operator family via + an implicit or binary coercion cast must not change the computed hash value. + Notice that there is only one support function per data type, not one + per equality operator. It is recommended that a family be complete, i.e., + provide an equality operator for each combination of data types. + Each operator class should include just the non-cross-type equality + operator and the support function for its data type. + + + + GiST, SP-GiST, and GIN indexes do not have any explicit notion of + cross-data-type operations. The set of operators supported is just + whatever the primary support functions for a given operator class can + handle. + + + + In BRIN, the requirements depends on the framework that provides the + operator classes. For operator classes based on minmax, + the behavior required is the same as for B-tree operator families: + all the operators in the family must sort compatibly, and casts must + not change the associated sort ordering. + + + + + Prior to PostgreSQL 8.3, there was no concept + of operator families, and so any cross-data-type operators intended to be + used with an index had to be bound directly into the index's operator + class. While this approach still works, it is deprecated because it + makes an index's dependencies too broad, and because the planner can + handle cross-data-type comparisons more effectively when both data types + have operators in the same operator family. + + + + + + System Dependencies on Operator Classes + + + ordering operator + + + + PostgreSQL uses operator classes to infer the + properties of operators in more ways than just whether they can be used + with indexes. Therefore, you might want to create operator classes + even if you have no intention of indexing any columns of your data type. + + + + In particular, there are SQL features such as ORDER BY and + DISTINCT that require comparison and sorting of values. + To implement these features on a user-defined data type, + PostgreSQL looks for the default B-tree operator + class for the data type. The equals member of this operator + class defines the system's notion of equality of values for + GROUP BY and DISTINCT, and the sort ordering + imposed by the operator class defines the default ORDER BY + ordering. + + + + If there is no default B-tree operator class for a data type, the system + will look for a default hash operator class. But since that kind of + operator class only provides equality, it is only able to support grouping + not sorting. + + + + When there is no default operator class for a data type, you will get + errors like could not identify an ordering operator if you + try to use these SQL features with the data type. + + + + + In PostgreSQL versions before 7.4, + sorting and grouping operations would implicitly use operators named + =, <, and >. The new + behavior of relying on default operator classes avoids having to make + any assumption about the behavior of operators with particular names. + + + + + Sorting by a non-default B-tree operator class is possible by specifying + the class's less-than operator in a USING option, + for example + +SELECT * FROM mytable ORDER BY somecol USING ~<~; + + Alternatively, specifying the class's greater-than operator + in USING selects a descending-order sort. + + + + Comparison of arrays of a user-defined type also relies on the semantics + defined by the type's default B-tree operator class. If there is no + default B-tree operator class, but there is a default hash operator class, + then array equality is supported, but not ordering comparisons. + + + + Another SQL feature that requires even more data-type-specific knowledge + is the RANGE offset + PRECEDING/FOLLOWING framing option + for window functions (see ). + For a query such as + +SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) + FROM mytable; + + it is not sufficient to know how to order by x; + the database must also understand how to subtract 5 or + add 10 to the current row's value of x + to identify the bounds of the current window frame. Comparing the + resulting bounds to other rows' values of x is + possible using the comparison operators provided by the B-tree operator + class that defines the ORDER BY ordering — but + addition and subtraction operators are not part of the operator class, so + which ones should be used? Hard-wiring that choice would be undesirable, + because different sort orders (different B-tree operator classes) might + need different behavior. Therefore, a B-tree operator class can specify + an in_range support function that encapsulates the + addition and subtraction behaviors that make sense for its sort order. + It can even provide more than one in_range support function, in case + there is more than one data type that makes sense to use as the offset + in RANGE clauses. + If the B-tree operator class associated with the window's ORDER + BY clause does not have a matching in_range support function, + the RANGE offset + PRECEDING/FOLLOWING + option is not supported. + + + + Another important point is that an equality operator that + appears in a hash operator family is a candidate for hash joins, + hash aggregation, and related optimizations. The hash operator family + is essential here since it identifies the hash function(s) to use. + + + + + Ordering Operators + + + Some index access methods (currently, only GiST and SP-GiST) support the concept of + ordering operators. What we have been discussing so far + are search operators. A search operator is one for which + the index can be searched to find all rows satisfying + WHERE + indexed_column + operator + constant. + Note that nothing is promised about the order in which the matching rows + will be returned. In contrast, an ordering operator does not restrict the + set of rows that can be returned, but instead determines their order. + An ordering operator is one for which the index can be scanned to return + rows in the order represented by + ORDER BY + indexed_column + operator + constant. + The reason for defining ordering operators that way is that it supports + nearest-neighbor searches, if the operator is one that measures distance. + For example, a query like + point '(101,456)' LIMIT 10; +]]> + + finds the ten places closest to a given target point. A GiST index + on the location column can do this efficiently because + <-> is an ordering operator. + + + + While search operators have to return Boolean results, ordering operators + usually return some other type, such as float or numeric for distances. + This type is normally not the same as the data type being indexed. + To avoid hard-wiring assumptions about the behavior of different data + types, the definition of an ordering operator is required to name + a B-tree operator family that specifies the sort ordering of the result + data type. As was stated in the previous section, B-tree operator families + define PostgreSQL's notion of ordering, so + this is a natural representation. Since the point <-> + operator returns float8, it could be specified in an operator + class creation command like this: + (point, point) FOR ORDER BY float_ops +]]> + + where float_ops is the built-in operator family that includes + operations on float8. This declaration states that the index + is able to return rows in order of increasing values of the + <-> operator. + + + + + Special Features of Operator Classes + + + There are two special features of operator classes that we have + not discussed yet, mainly because they are not useful + with the most commonly used index methods. + + + + Normally, declaring an operator as a member of an operator class + (or family) means that the index method can retrieve exactly the set of rows + that satisfy a WHERE condition using the operator. For example: + +SELECT * FROM table WHERE integer_column < 4; + + can be satisfied exactly by a B-tree index on the integer column. + But there are cases where an index is useful as an inexact guide to + the matching rows. For example, if a GiST index stores only bounding boxes + for geometric objects, then it cannot exactly satisfy a WHERE + condition that tests overlap between nonrectangular objects such as + polygons. Yet we could use the index to find objects whose bounding + box overlaps the bounding box of the target object, and then do the + exact overlap test only on the objects found by the index. If this + scenario applies, the index is said to be lossy for the + operator. Lossy index searches are implemented by having the index + method return a recheck flag when a row might or might + not really satisfy the query condition. The core system will then + test the original query condition on the retrieved row to see whether + it should be returned as a valid match. This approach works if + the index is guaranteed to return all the required rows, plus perhaps + some additional rows, which can be eliminated by performing the original + operator invocation. The index methods that support lossy searches + (currently, GiST, SP-GiST and GIN) allow the support functions of individual + operator classes to set the recheck flag, and so this is essentially an + operator-class feature. + + + + Consider again the situation where we are storing in the index only + the bounding box of a complex object such as a polygon. In this + case there's not much value in storing the whole polygon in the index + entry — we might as well store just a simpler object of type + box. This situation is expressed by the STORAGE + option in CREATE OPERATOR CLASS: we'd write something like: + + +CREATE OPERATOR CLASS polygon_ops + DEFAULT FOR TYPE polygon USING gist AS + ... + STORAGE box; + + + At present, only the GiST, SP-GiST, GIN and BRIN index methods support a + STORAGE type that's different from the column data type. + The GiST compress and decompress support + routines must deal with data-type conversion when STORAGE + is used. SP-GiST likewise requires a compress + support function to convert to the storage type, when that is different; + if an SP-GiST opclass also supports retrieving data, the reverse + conversion must be handled by the consistent function. + In GIN, the STORAGE type identifies the type of + the key values, which normally is different from the type + of the indexed column — for example, an operator class for + integer-array columns might have keys that are just integers. The + GIN extractValue and extractQuery support + routines are responsible for extracting keys from indexed values. + BRIN is similar to GIN: the STORAGE type identifies the + type of the stored summary values, and operator classes' support + procedures are responsible for interpreting the summary values + correctly. + + + +
diff --git a/doc/src/sgml/xml2.sgml b/doc/src/sgml/xml2.sgml new file mode 100644 index 000000000000..584bb3e923fa --- /dev/null +++ b/doc/src/sgml/xml2.sgml @@ -0,0 +1,443 @@ + + + + xml2 + + + xml2 + + + + The xml2 module provides XPath querying and + XSLT functionality. + + + + Deprecation Notice + + + From PostgreSQL 8.3 on, there is XML-related + functionality based on the SQL/XML standard in the core server. + That functionality covers XML syntax checking and XPath queries, + which is what this module does, and more, but the API is + not at all compatible. It is planned that this module will be + removed in a future version of PostgreSQL in favor of the newer standard API, so + you are encouraged to try converting your applications. If you + find that some of the functionality of this module is not + available in an adequate form with the newer API, please explain + your issue to pgsql-hackers@lists.postgresql.org so that the deficiency + can be addressed. + + + + + Description of Functions + + + shows the functions provided by this module. + These functions provide straightforward XML parsing and XPath queries. + + + + <filename>xml2</filename> Functions + + + + + Function + + + Description + + + + + + + + xml_valid ( document text ) + boolean + + + Parses the given document and returns true if the + document is well-formed XML. (Note: this is an alias for the standard + PostgreSQL function xml_is_well_formed(). The + name xml_valid() is technically incorrect since validity + and well-formedness have different meanings in XML.) + + + + + + xpath_string ( document text, query text ) + text + + + Evaluates the XPath query on the supplied document, and + casts the result to text. + + + + + + xpath_number ( document text, query text ) + real + + + Evaluates the XPath query on the supplied document, and + casts the result to real. + + + + + + xpath_bool ( document text, query text ) + boolean + + + Evaluates the XPath query on the supplied document, and + casts the result to boolean. + + + + + + xpath_nodeset ( document text, query text, toptag text, itemtag text ) + text + + + Evaluates the query on the document and wraps the result in XML + tags. If the result is multivalued, the output will look like: + +<toptag> +<itemtag>Value 1 which could be an XML fragment</itemtag> +<itemtag>Value 2....</itemtag> +</toptag> + + If either toptag + or itemtag is an empty string, the relevant tag + is omitted. + + + + + + xpath_nodeset ( document text, query text, itemtag text ) + text + + + Like xpath_nodeset(document, query, toptag, itemtag) but result omits toptag. + + + + + + xpath_nodeset ( document text, query text ) + text + + + Like xpath_nodeset(document, query, toptag, itemtag) but result omits both tags. + + + + + + xpath_list ( document text, query text, separator text ) + text + + + Evaluates the query on the document and returns multiple values + separated by the specified separator, for example Value + 1,Value 2,Value 3 if separator + is ,. + + + + + + xpath_list ( document text, query text ) + text + + + This is a wrapper for the above function that uses , + as the separator. + + + + +
+
+ + + <literal>xpath_table</literal> + + + xpath_table + + + +xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record + + + + xpath_table is a table function that evaluates a set of XPath + queries on each of a set of documents and returns the results as a + table. The primary key field from the original document table is returned + as the first column of the result so that the result set + can readily be used in joins. The parameters are described in + . + + + + <function>xpath_table</function> Parameters + + + + + + Parameter + Description + + + + + key + + + the name of the key field — this is just a field to be used as + the first column of the output table, i.e., it identifies the record from + which each output row came (see note below about multiple values) + + + + + document + + + the name of the field containing the XML document + + + + + relation + + + the name of the table or view containing the documents + + + + + xpaths + + + one or more XPath expressions, separated by | + + + + + criteria + + + the contents of the WHERE clause. This cannot be omitted, so use + true or 1=1 if you want to + process all the rows in the relation + + + + + +
+ + + These parameters (except the XPath strings) are just substituted + into a plain SQL SELECT statement, so you have some flexibility — the + statement is + + + + + SELECT <key>, <document> FROM <relation> WHERE <criteria> + + + + + so those parameters can be anything valid in those particular + locations. The result from this SELECT needs to return exactly two + columns (which it will unless you try to list multiple fields for key + or document). Beware that this simplistic approach requires that you + validate any user-supplied values to avoid SQL injection attacks. + + + + The function has to be used in a FROM expression, with an + AS clause to specify the output columns; for example + +SELECT * FROM +xpath_table('article_id', + 'article_xml', + 'articles', + '/article/author|/article/pages|/article/title', + 'date_entered > ''2003-01-01'' ') +AS t(article_id integer, author text, page_count integer, title text); + + The AS clause defines the names and types of the columns in the + output table. The first is the key field and the rest correspond + to the XPath queries. + If there are more XPath queries than result columns, + the extra queries will be ignored. If there are more result columns + than XPath queries, the extra columns will be NULL. + + + + Notice that this example defines the page_count result + column as an integer. The function deals internally with string + representations, so when you say you want an integer in the output, it will + take the string representation of the XPath result and use PostgreSQL input + functions to transform it into an integer (or whatever type the AS + clause requests). An error will result if it can't do this — for + example if the result is empty — so you may wish to just stick to + text as the column type if you think your data has any problems. + + + + The calling SELECT statement doesn't necessarily have to be + just SELECT * — it can reference the output + columns by name or join them to other tables. The function produces a + virtual table with which you can perform any operation you wish (e.g., + aggregation, joining, sorting etc). So we could also have: + +SELECT t.title, p.fullname, p.email +FROM xpath_table('article_id', 'article_xml', 'articles', + '/article/title|/article/author/@id', + 'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ') + AS t(article_id integer, title text, author_id integer), + tblPeopleInfo AS p +WHERE t.author_id = p.person_id; + + as a more complicated example. Of course, you could wrap all + of this in a view for convenience. + + + + Multivalued Results + + + The xpath_table function assumes that the results of each XPath query + might be multivalued, so the number of rows returned by the function + may not be the same as the number of input documents. The first row + returned contains the first result from each query, the second row the + second result from each query. If one of the queries has fewer values + than the others, null values will be returned instead. + + + + In some cases, a user will know that a given XPath query will return + only a single result (perhaps a unique document identifier) — if used + alongside an XPath query returning multiple results, the single-valued + result will appear only on the first row of the result. The solution + to this is to use the key field as part of a join against a simpler + XPath query. As an example: + + +CREATE TABLE test ( + id int PRIMARY KEY, + xml text +); + +INSERT INTO test VALUES (1, '<doc num="C1"> +<line num="L1"><a>1</a><b>2</b><c>3</c></line> +<line num="L2"><a>11</a><b>22</b><c>33</c></line> +</doc>'); + +INSERT INTO test VALUES (2, '<doc num="C2"> +<line num="L1"><a>111</a><b>222</b><c>333</c></line> +<line num="L2"><a>111</a><b>222</b><c>333</c></line> +</doc>'); + +SELECT * FROM + xpath_table('id','xml','test', + '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c', + 'true') + AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int) +WHERE id = 1 ORDER BY doc_num, line_num + + id | doc_num | line_num | val1 | val2 | val3 +----+---------+----------+------+------+------ + 1 | C1 | L1 | 1 | 2 | 3 + 1 | | L2 | 11 | 22 | 33 + + + + + To get doc_num on every line, the solution is to use two invocations + of xpath_table and join the results: + + +SELECT t.*,i.doc_num FROM + xpath_table('id', 'xml', 'test', + '/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c', + 'true') + AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int), + xpath_table('id', 'xml', 'test', '/doc/@num', 'true') + AS i(id int, doc_num varchar(10)) +WHERE i.id=t.id AND i.id=1 +ORDER BY doc_num, line_num; + + id | line_num | val1 | val2 | val3 | doc_num +----+----------+------+------+------+--------- + 1 | L1 | 1 | 2 | 3 | C1 + 1 | L2 | 11 | 22 | 33 | C1 +(2 rows) + + + +
+ + + XSLT Functions + + + The following functions are available if libxslt is installed: + + + + <literal>xslt_process</literal> + + + xslt_process + + + +xslt_process(text document, text stylesheet, text paramlist) returns text + + + + This function applies the XSL stylesheet to the document and returns + the transformed result. The paramlist is a list of parameter + assignments to be used in the transformation, specified in the form + a=1,b=2. Note that the + parameter parsing is very simple-minded: parameter values cannot + contain commas! + + + + There is also a two-parameter version of xslt_process which + does not pass any parameters to the transformation. + + + + + + Author + + + John Gray jgray@azuli.co.uk + + + + Development of this module was sponsored by Torchbox Ltd. (www.torchbox.com). + It has the same BSD license as PostgreSQL. + + + +
diff --git a/doc/src/sgml/xoper.sgml b/doc/src/sgml/xoper.sgml new file mode 100644 index 000000000000..98f4c5c4aa46 --- /dev/null +++ b/doc/src/sgml/xoper.sgml @@ -0,0 +1,486 @@ + + + + User-Defined Operators + + + operator + user-defined + + + + Every operator is syntactic sugar for a call to an + underlying function that does the real work; so you must + first create the underlying function before you can create + the operator. However, an operator is not merely + syntactic sugar, because it carries additional information + that helps the query planner optimize queries that use the + operator. The next section will be devoted to explaining + that additional information. + + + + PostgreSQL supports prefix + and infix operators. Operators can be + overloaded;overloadingoperators + that is, the same operator name can be used for different operators + that have different numbers and types of operands. When a query is + executed, the system determines the operator to call from the + number and types of the provided operands. + + + + Here is an example of creating an operator for adding two complex + numbers. We assume we've already created the definition of type + complex (see ). First we need a + function that does the work, then we can define the operator: + + +CREATE FUNCTION complex_add(complex, complex) + RETURNS complex + AS 'filename', 'complex_add' + LANGUAGE C IMMUTABLE STRICT; + +CREATE OPERATOR + ( + leftarg = complex, + rightarg = complex, + function = complex_add, + commutator = + +); + + + + + Now we could execute a query like this: + + +SELECT (a + b) AS c FROM test_complex; + + c +----------------- + (5.2,6.05) + (133.42,144.95) + + + + + We've shown how to create a binary operator here. To create a prefix + operator, just omit the leftarg. + The function + clause and the argument clauses are the only required items in + CREATE OPERATOR. The commutator + clause shown in the example is an optional hint to the query + optimizer. Further details about commutator and other + optimizer hints appear in the next section. + + + + + Operator Optimization Information + + + optimization information + for operators + + + + A PostgreSQL operator definition can include + several optional clauses that tell the system useful things about how + the operator behaves. These clauses should be provided whenever + appropriate, because they can make for considerable speedups in execution + of queries that use the operator. But if you provide them, you must be + sure that they are right! Incorrect use of an optimization clause can + result in slow queries, subtly wrong output, or other Bad Things. + You can always leave out an optimization clause if you are not sure + about it; the only consequence is that queries might run slower than + they need to. + + + + Additional optimization clauses might be added in future versions of + PostgreSQL. The ones described here are all + the ones that release &version; understands. + + + + It is also possible to attach a planner support function to the function + that underlies an operator, providing another way of telling the system + about the behavior of the operator. + See for more information. + + + + <literal>COMMUTATOR</literal> + + + The COMMUTATOR clause, if provided, names an operator that is the + commutator of the operator being defined. We say that operator A is the + commutator of operator B if (x A y) equals (y B x) for all possible input + values x, y. Notice that B is also the commutator of A. For example, + operators < and > for a particular data type are usually each others' + commutators, and operator + is usually commutative with itself. + But operator - is usually not commutative with anything. + + + + The left operand type of a commutable operator is the same as the + right operand type of its commutator, and vice versa. So the name of + the commutator operator is all that PostgreSQL + needs to be given to look up the commutator, and that's all that needs to + be provided in the COMMUTATOR clause. + + + + It's critical to provide commutator information for operators that + will be used in indexes and join clauses, because this allows the + query optimizer to flip around such a clause to the forms + needed for different plan types. For example, consider a query with + a WHERE clause like tab1.x = tab2.y, where tab1.x + and tab2.y are of a user-defined type, and suppose that + tab2.y is indexed. The optimizer cannot generate an + index scan unless it can determine how to flip the clause around to + tab2.y = tab1.x, because the index-scan machinery expects + to see the indexed column on the left of the operator it is given. + PostgreSQL will not simply + assume that this is a valid transformation — the creator of the + = operator must specify that it is valid, by marking the + operator with commutator information. + + + + When you are defining a self-commutative operator, you just do it. + When you are defining a pair of commutative operators, things are + a little trickier: how can the first one to be defined refer to the + other one, which you haven't defined yet? There are two solutions + to this problem: + + + + + One way is to omit the COMMUTATOR clause in the first operator that + you define, and then provide one in the second operator's definition. + Since PostgreSQL knows that commutative + operators come in pairs, when it sees the second definition it will + automatically go back and fill in the missing COMMUTATOR clause in + the first definition. + + + + + + The other, more straightforward way is just to include COMMUTATOR clauses + in both definitions. When PostgreSQL processes + the first definition and realizes that COMMUTATOR refers to a nonexistent + operator, the system will make a dummy entry for that operator in the + system catalog. This dummy entry will have valid data only + for the operator name, left and right operand types, and result type, + since that's all that PostgreSQL can deduce + at this point. The first operator's catalog entry will link to this + dummy entry. Later, when you define the second operator, the system + updates the dummy entry with the additional information from the second + definition. If you try to use the dummy operator before it's been filled + in, you'll just get an error message. + + + + + + + + <literal>NEGATOR</literal> + + + The NEGATOR clause, if provided, names an operator that is the + negator of the operator being defined. We say that operator A + is the negator of operator B if both return Boolean results and + (x A y) equals NOT (x B y) for all possible inputs x, y. + Notice that B is also the negator of A. + For example, < and >= are a negator pair for most data types. + An operator can never validly be its own negator. + + + + Unlike commutators, a pair of unary operators could validly be marked + as each other's negators; that would mean (A x) equals NOT (B x) + for all x. + + + + An operator's negator must have the same left and/or right operand types + as the operator to be defined, so just as with COMMUTATOR, only the operator + name need be given in the NEGATOR clause. + + + + Providing a negator is very helpful to the query optimizer since + it allows expressions like NOT (x = y) to be simplified into + x <> y. This comes up more often than you might think, because + NOT operations can be inserted as a consequence of other rearrangements. + + + + Pairs of negator operators can be defined using the same methods + explained above for commutator pairs. + + + + + + <literal>RESTRICT</literal> + + + The RESTRICT clause, if provided, names a restriction selectivity + estimation function for the operator. (Note that this is a function + name, not an operator name.) RESTRICT clauses only make sense for + binary operators that return boolean. The idea behind a restriction + selectivity estimator is to guess what fraction of the rows in a + table will satisfy a WHERE-clause condition of the form: + +column OP constant + + for the current operator and a particular constant value. + This assists the optimizer by + giving it some idea of how many rows will be eliminated by WHERE + clauses that have this form. (What happens if the constant is on + the left, you might be wondering? Well, that's one of the things that + COMMUTATOR is for...) + + + + Writing new restriction selectivity estimation functions is far beyond + the scope of this chapter, but fortunately you can usually just use + one of the system's standard estimators for many of your own operators. + These are the standard restriction estimators: + + eqsel for = + neqsel for <> + scalarltsel for < + scalarlesel for <= + scalargtsel for > + scalargesel for >= + + + + + You can frequently get away with using either eqsel or neqsel for + operators that have very high or very low selectivity, even if they + aren't really equality or inequality. For example, the + approximate-equality geometric operators use eqsel on the assumption that + they'll usually only match a small fraction of the entries in a table. + + + + You can use scalarltsel, scalarlesel, + scalargtsel and scalargesel for comparisons on + data types that have some sensible means of being converted into numeric + scalars for range comparisons. If possible, add the data type to those + understood by the function convert_to_scalar() in + src/backend/utils/adt/selfuncs.c. + (Eventually, this function should be replaced by per-data-type functions + identified through a column of the pg_type system catalog; but that hasn't happened + yet.) If you do not do this, things will still work, but the optimizer's + estimates won't be as good as they could be. + + + + Another useful built-in selectivity estimation function + is matchingsel, which will work for almost any + binary operator, if standard MCV and/or histogram statistics are + collected for the input data type(s). Its default estimate is set to + twice the default estimate used in eqsel, making + it most suitable for comparison operators that are somewhat less + strict than equality. (Or you could call the + underlying generic_restriction_selectivity + function, providing a different default estimate.) + + + + There are additional selectivity estimation functions designed for geometric + operators in src/backend/utils/adt/geo_selfuncs.c: areasel, positionsel, + and contsel. At this writing these are just stubs, but you might want + to use them (or even better, improve them) anyway. + + + + + <literal>JOIN</literal> + + + The JOIN clause, if provided, names a join selectivity + estimation function for the operator. (Note that this is a function + name, not an operator name.) JOIN clauses only make sense for + binary operators that return boolean. The idea behind a join + selectivity estimator is to guess what fraction of the rows in a + pair of tables will satisfy a WHERE-clause condition of the form: + +table1.column1 OP table2.column2 + + for the current operator. As with the RESTRICT clause, this helps + the optimizer very substantially by letting it figure out which + of several possible join sequences is likely to take the least work. + + + + As before, this chapter will make no attempt to explain how to write + a join selectivity estimator function, but will just suggest that + you use one of the standard estimators if one is applicable: + + eqjoinsel for = + neqjoinsel for <> + scalarltjoinsel for < + scalarlejoinsel for <= + scalargtjoinsel for > + scalargejoinsel for >= + matchingjoinsel for generic matching operators + areajoinsel for 2D area-based comparisons + positionjoinsel for 2D position-based comparisons + contjoinsel for 2D containment-based comparisons + + + + + + <literal>HASHES</literal> + + + The HASHES clause, if present, tells the system that + it is permissible to use the hash join method for a join based on this + operator. HASHES only makes sense for a binary operator that + returns boolean, and in practice the operator must represent + equality for some data type or pair of data types. + + + + The assumption underlying hash join is that the join operator can + only return true for pairs of left and right values that hash to the + same hash code. If two values get put in different hash buckets, the + join will never compare them at all, implicitly assuming that the + result of the join operator must be false. So it never makes sense + to specify HASHES for operators that do not represent + some form of equality. In most cases it is only practical to support + hashing for operators that take the same data type on both sides. + However, sometimes it is possible to design compatible hash functions + for two or more data types; that is, functions that will generate the + same hash codes for equal values, even though the values + have different representations. For example, it's fairly simple + to arrange this property when hashing integers of different widths. + + + + To be marked HASHES, the join operator must appear + in a hash index operator family. This is not enforced when you create + the operator, since of course the referencing operator family couldn't + exist yet. But attempts to use the operator in hash joins will fail + at run time if no such operator family exists. The system needs the + operator family to find the data-type-specific hash function(s) for the + operator's input data type(s). Of course, you must also create suitable + hash functions before you can create the operator family. + + + + Care should be exercised when preparing a hash function, because there + are machine-dependent ways in which it might fail to do the right thing. + For example, if your data type is a structure in which there might be + uninteresting pad bits, you cannot simply pass the whole structure to + hash_any. (Unless you write your other operators and + functions to ensure that the unused bits are always zero, which is the + recommended strategy.) + Another example is that on machines that meet the IEEE + floating-point standard, negative zero and positive zero are different + values (different bit patterns) but they are defined to compare equal. + If a float value might contain negative zero then extra steps are needed + to ensure it generates the same hash value as positive zero. + + + + A hash-joinable operator must have a commutator (itself if the two + operand data types are the same, or a related equality operator + if they are different) that appears in the same operator family. + If this is not the case, planner errors might occur when the operator + is used. Also, it is a good idea (but not strictly required) for + a hash operator family that supports multiple data types to provide + equality operators for every combination of the data types; this + allows better optimization. + + + + + The function underlying a hash-joinable operator must be marked + immutable or stable. If it is volatile, the system will never + attempt to use the operator for a hash join. + + + + + + If a hash-joinable operator has an underlying function that is marked + strict, the + function must also be complete: that is, it should return true or + false, never null, for any two nonnull inputs. If this rule is + not followed, hash-optimization of IN operations might + generate wrong results. (Specifically, IN might return + false where the correct answer according to the standard would be null; + or it might yield an error complaining that it wasn't prepared for a + null result.) + + + + + + + <literal>MERGES</literal> + + + The MERGES clause, if present, tells the system that + it is permissible to use the merge-join method for a join based on this + operator. MERGES only makes sense for a binary operator that + returns boolean, and in practice the operator must represent + equality for some data type or pair of data types. + + + + Merge join is based on the idea of sorting the left- and right-hand tables + into order and then scanning them in parallel. So, both data types must + be capable of being fully ordered, and the join operator must be one + that can only succeed for pairs of values that fall at the + same place + in the sort order. In practice this means that the join operator must + behave like equality. But it is possible to merge-join two + distinct data types so long as they are logically compatible. For + example, the smallint-versus-integer + equality operator is merge-joinable. + We only need sorting operators that will bring both data types into a + logically compatible sequence. + + + + To be marked MERGES, the join operator must appear + as an equality member of a btree index operator family. + This is not enforced when you create + the operator, since of course the referencing operator family couldn't + exist yet. But the operator will not actually be used for merge joins + unless a matching operator family can be found. The + MERGES flag thus acts as a hint to the planner that + it's worth looking for a matching operator family. + + + + A merge-joinable operator must have a commutator (itself if the two + operand data types are the same, or a related equality operator + if they are different) that appears in the same operator family. + If this is not the case, planner errors might occur when the operator + is used. Also, it is a good idea (but not strictly required) for + a btree operator family that supports multiple data types to provide + equality operators for every combination of the data types; this + allows better optimization. + + + + + The function underlying a merge-joinable operator must be marked + immutable or stable. If it is volatile, the system will never + attempt to use the operator for a merge join. + + + + diff --git a/doc/src/sgml/xplang.sgml b/doc/src/sgml/xplang.sgml new file mode 100644 index 000000000000..31d403c4806b --- /dev/null +++ b/doc/src/sgml/xplang.sgml @@ -0,0 +1,230 @@ + + + + Procedural Languages + + + procedural language + + + + PostgreSQL allows user-defined functions + to be written in other languages besides SQL and C. These other + languages are generically called procedural + languages (PLs). For a function + written in a procedural language, the database server has + no built-in knowledge about how to interpret the function's source + text. Instead, the task is passed to a special handler that knows + the details of the language. The handler could either do all the + work of parsing, syntax analysis, execution, etc. itself, or it + could serve as glue between + PostgreSQL and an existing implementation + of a programming language. The handler itself is a + C language function compiled into a shared object and + loaded on demand, just like any other C function. + + + + There are currently four procedural languages available in the + standard PostgreSQL distribution: + PL/pgSQL (), + PL/Tcl (), + PL/Perl (), and + PL/Python (). + There are additional procedural languages available that are not + included in the core distribution. + has information about finding them. In addition other languages can + be defined by users; the basics of developing a new procedural + language are covered in . + + + + Installing Procedural Languages + + + A procedural language must be installed into each + database where it is to be used. But procedural languages installed in + the database template1 are automatically available in all + subsequently created databases, since their entries in + template1 will be copied by CREATE DATABASE. + So the database administrator can + decide which languages are available in which databases and can make + some languages available by default if desired. + + + + For the languages supplied with the standard distribution, it is + only necessary to execute CREATE EXTENSION + language_name to install the language into the + current database. + The manual procedure described below is only recommended for + installing languages that have not been packaged as extensions. + + + + Manual Procedural Language Installation + + + A procedural language is installed in a database in five steps, + which must be carried out by a database superuser. In most cases + the required SQL commands should be packaged as the installation script + of an extension, so that CREATE EXTENSION can be + used to execute them. + + + + + The shared object for the language handler must be compiled and + installed into an appropriate library directory. This works in the same + way as building and installing modules with regular user-defined C + functions does; see . Often, the language + handler will depend on an external library that provides the actual + programming language engine; if so, that must be installed as well. + + + + + + The handler must be declared with the command + +CREATE FUNCTION handler_function_name() + RETURNS language_handler + AS 'path-to-shared-object' + LANGUAGE C; + + The special return type of language_handler tells + the database system that this function does not return one of + the defined SQL data types and is not directly usable + in SQL statements. + + + + + + Optionally, the language handler can provide an inline + handler function that executes anonymous code blocks + (DO commands) + written in this language. If an inline handler function + is provided by the language, declare it with a command like + +CREATE FUNCTION inline_function_name(internal) + RETURNS void + AS 'path-to-shared-object' + LANGUAGE C; + + + + + + + Optionally, the language handler can provide a validator + function that checks a function definition for correctness without + actually executing it. The validator function is called by + CREATE FUNCTION if it exists. If a validator function + is provided by the language, declare it with a command like + +CREATE FUNCTION validator_function_name(oid) + RETURNS void + AS 'path-to-shared-object' + LANGUAGE C STRICT; + + + + + + + Finally, the PL must be declared with the command + +CREATE TRUSTED LANGUAGE language_name + HANDLER handler_function_name + INLINE inline_function_name + VALIDATOR validator_function_name ; + + The optional key word TRUSTED specifies that + the language does not grant access to data that the user would + not otherwise have. Trusted languages are designed for ordinary + database users (those without superuser privilege) and allows them + to safely create functions and + procedures. Since PL functions are executed inside the database + server, the TRUSTED flag should only be given + for languages that do not allow access to database server + internals or the file system. The languages + PL/pgSQL, + PL/Tcl, and + PL/Perl + are considered trusted; the languages + PL/TclU, + PL/PerlU, and + PL/PythonU + are designed to provide unlimited functionality and should + not be marked trusted. + + + + + + shows how the manual + installation procedure would work with the language + PL/Perl. + + + + Manual Installation of <application>PL/Perl</application> + + + The following command tells the database server where to find the + shared object for the PL/Perl language's call + handler function: + + +CREATE FUNCTION plperl_call_handler() RETURNS language_handler AS + '$libdir/plperl' LANGUAGE C; + + + + + PL/Perl has an inline handler function + and a validator function, so we declare those too: + + +CREATE FUNCTION plperl_inline_handler(internal) RETURNS void AS + '$libdir/plperl' LANGUAGE C STRICT; + +CREATE FUNCTION plperl_validator(oid) RETURNS void AS + '$libdir/plperl' LANGUAGE C STRICT; + + + + + The command: + +CREATE TRUSTED LANGUAGE plperl + HANDLER plperl_call_handler + INLINE plperl_inline_handler + VALIDATOR plperl_validator; + + then defines that the previously declared functions + should be invoked for functions and procedures where the + language attribute is plperl. + + + + + In a default PostgreSQL installation, + the handler for the PL/pgSQL language + is built and installed into the library + directory; furthermore, the PL/pgSQL language + itself is installed in all databases. + If Tcl support is configured in, the handlers for + PL/Tcl and PL/TclU are built and installed + in the library directory, but the language itself is not installed in any + database by default. + Likewise, the PL/Perl and PL/PerlU + handlers are built and installed if Perl support is configured, and the + PL/PythonU handler is installed if Python support is + configured, but these languages are not installed by default. + + + + + diff --git a/gpAux/gpdemo/Makefile b/gpAux/gpdemo/Makefile index 50563dd641a1..776659c57e37 100644 --- a/gpAux/gpdemo/Makefile +++ b/gpAux/gpdemo/Makefile @@ -14,7 +14,7 @@ top_builddir = ../.. # export enable_gpfdist -export with_openssl +export with_ssl PORT_BASE ?= 7000 NUM_PRIMARY_MIRROR_PAIRS ?= 3 diff --git a/gpAux/gpdemo/demo_cluster.sh b/gpAux/gpdemo/demo_cluster.sh index fba4232afb1e..9a076b5c97d2 100755 --- a/gpAux/gpdemo/demo_cluster.sh +++ b/gpAux/gpdemo/demo_cluster.sh @@ -417,7 +417,7 @@ echo "gpinitsystem returned: ${RETURN}" echo "========================================" echo "" -if [ "$enable_gpfdist" = "yes" ] && [ "$with_openssl" = "yes" ]; then +if [ "$enable_gpfdist" = "yes" ] && [ "$with_ssl" = "openssl" ]; then echo "======================================================================" echo "Generating SSL certificates for gpfdists:" echo "======================================================================" diff --git a/gpMgmt/bin/gpload.py b/gpMgmt/bin/gpload.py index 55fe1f78909d..12965d94fe17 100755 --- a/gpMgmt/bin/gpload.py +++ b/gpMgmt/bin/gpload.py @@ -551,6 +551,87 @@ def is_keyword(tab): def escape_string(string): return psycopg2.extensions.QuotedString(string).getquoted()[1:-1].decode() + +class _PGResultAdapter: + """Result shim mimicking the bits of PyGreSQL's query result gpload uses.""" + def __init__(self, rows, description): + self._rows = rows + self._description = description + + def getresult(self): + return self._rows + + def dictresult(self): + cols = [d[0] for d in self._description] + return [dict(zip(cols, row)) for row in self._rows] + + +class _Notice: + def __init__(self, message): + self.message = message + + +class _PGDBAdapter: + """ + Connection shim mimicking the bits of PyGreSQL's pg.DB that gpload uses, + implemented on psycopg2 (gpload was ported off PyGreSQL but the + connection object never was). + """ + def __init__(self, dbname=None, host=None, port=None, user=None, passwd=None): + self._conn = psycopg2.connect(dbname=dbname, host=host, port=port, + user=user, password=passwd) + # pg.DB.query() commits each statement on its own + self._conn.autocommit = True + self._notice_receiver = None + + def _drain_notices(self): + notices = [str(n) for n in self._conn.notices] + del self._conn.notices[:] + return notices + + def _dispatch_notices(self): + # PyGreSQL left unconsumed notices to libpq's default handler, which + # prints them to stderr; the gpload tests expect that output. + if self._notice_receiver is not None: + for n in self._drain_notices(): + self._notice_receiver(_Notice(n)) + else: + for n in self._drain_notices(): + sys.stderr.write(n) + + def query(self, sql): + if isinstance(sql, bytes): + sql = sql.decode('utf-8') + cur = self._conn.cursor() + try: + try: + cur.execute(sql) + except psycopg2.Error as e: + # PyGreSQL surfaced the full server message, severity + # prefix included; psycopg2's str() drops the severity. + if e.pgerror: + raise type(e)(e.pgerror) from None + raise + if cur.description is not None: + return _PGResultAdapter(cur.fetchall(), cur.description) + # DML: PyGreSQL returns the affected row count (as a string) + if cur.rowcount >= 0: + return str(cur.rowcount) + return None + finally: + self._dispatch_notices() + cur.close() + + def notices(self): + return self._drain_notices() + + def set_notice_receiver(self, receiver): + self._notice_receiver = receiver + + def close(self): + self._conn.close() + + def caseInsensitiveDictLookup(key, dictionary): """ Do a case insensitive dictionary lookup. Return the dictionary value if found, @@ -1843,7 +1924,7 @@ def setup_connection(self, recurse = 0): " host=" + str(self.options.h) + " port=" + str(self.options.p) + " database=" + str(self.options.d)) - self.db = pg.DB( dbname=self.options.d + self.db = _PGDBAdapter( dbname=self.options.d , host=self.options.h , port=self.options.p , user=self.options.U @@ -2644,11 +2725,11 @@ def count_errors(self): if self.log_errors and not self.options.D: # make sure we only get errors for our own instance if not self.reuse_tables: - queryStr = "select count(*) from gp_read_error_log('%s')" % pg.escape_string(self.extSchemaTable) + queryStr = "select count(*) from gp_read_error_log('%s')" % escape_string(self.extSchemaTable) results = self.db.query(queryStr).getresult() return (results[0])[0] else: # reuse_tables - queryStr = "select count(*) from gp_read_error_log('%s') where cmdtime > to_timestamp(%s)" % (pg.escape_string(self.extSchemaTable), self.startTimestamp) + queryStr = "select count(*) from gp_read_error_log('%s') where cmdtime > to_timestamp(%s)" % (escape_string(self.extSchemaTable), self.startTimestamp) results = self.db.query(queryStr).getresult() global NUM_WARN_ROWS NUM_WARN_ROWS = (results[0])[0] @@ -2666,7 +2747,7 @@ def report_errors(self): # if reuse_table is set, error message is not deleted. if errors and self.log_errors and self.reuse_tables: self.log(self.WARN, "Please use following query to access the detailed error") - self.log(self.WARN, "select * from gp_read_error_log('{0}') where cmdtime > to_timestamp('{1}')".format(pg.escape_string(self.extSchemaTable), self.startTimestamp)) + self.log(self.WARN, "select * from gp_read_error_log('{0}') where cmdtime > to_timestamp('{1}')".format(escape_string(self.extSchemaTable), self.startTimestamp)) self.exitValue = 1 if errors else 0 diff --git a/gpMgmt/bin/gpload_test/gpload2/init_file b/gpMgmt/bin/gpload_test/gpload2/init_file index df5ab00dbb85..8cc927275c0e 100644 --- a/gpMgmt/bin/gpload_test/gpload2/init_file +++ b/gpMgmt/bin/gpload_test/gpload2/init_file @@ -22,3 +22,9 @@ -- m/cmdtime/ -- s/cmdtime.*$/CONDITION/ -- end_matchsubs +-- start_matchsubs +-- m/connection to server at/ +-- s/connection to server at "[^"]*",/connection to server at "HOST",/ +-- m/no pg_hba.conf entry for host/ +-- s/no pg_hba\.conf entry for host "[^"]*",/no pg_hba.conf entry for host "HOST",/ +-- end_matchsubs diff --git a/gpMgmt/bin/gpload_test/gpload2/query46.ans b/gpMgmt/bin/gpload_test/gpload2/query46.ans index 555c90f1ac1c..edd04a96276a 100644 --- a/gpMgmt/bin/gpload_test/gpload2/query46.ans +++ b/gpMgmt/bin/gpload_test/gpload2/query46.ans @@ -1,16 +1,14 @@ 2020-12-01 15:47:53|INFO|gpload session started 2020-12-01 15:47:53 -2020-12-01 15:47:53|ERROR|could not connect to database: could not connect to server: Connection refused - Is the server running on host "*" and accepting - TCP/IP connections on port 9999? +2020-12-01 15:47:53|ERROR|could not connect to database: connection to server at "HOST", port 9999 failed: Connection refused + Is the server running on that host and accepting TCP/IP connections? . Is the Greenplum Database running on port 9999? 2020-12-01 15:47:53|INFO|rows Inserted = 0 2020-12-01 15:47:53|INFO|rows Updated = 0 2020-12-01 15:47:53|INFO|data formatting errors = 0 2020-12-01 15:47:53|INFO|gpload failed 2020-12-01 15:47:53|INFO|gpload session started 2020-12-01 15:47:53 -2020-12-01 15:47:53|ERROR|could not connect to database: could not connect to server: Connection refused - Is the server running on host "*" and accepting - TCP/IP connections on port 9999? +2020-12-01 15:47:53|ERROR|could not connect to database: connection to server at "HOST", port 9999 failed: Connection refused + Is the server running on that host and accepting TCP/IP connections? . Is the Greenplum Database running on port 9999? 2020-12-01 15:47:53|INFO|rows Inserted = 0 2020-12-01 15:47:53|INFO|rows Updated = 0 diff --git a/gpMgmt/bin/gpload_test/gpload2/query49.ans b/gpMgmt/bin/gpload_test/gpload2/query49.ans index 472405bed197..9bc28bb437e9 100644 --- a/gpMgmt/bin/gpload_test/gpload2/query49.ans +++ b/gpMgmt/bin/gpload_test/gpload2/query49.ans @@ -1,12 +1,12 @@ 2020-12-02 15:03:39|INFO|gpload session started 2020-12-02 15:03:39 -2020-12-02 15:03:39|ERROR|could not connect to database: FATAL: database "notexistdb" does not exist +2020-12-02 15:03:39|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: database "notexistdb" does not exist . Is the Greenplum Database running on port 7000? 2020-12-02 15:03:39|INFO|rows Inserted = 0 2020-12-02 15:03:39|INFO|rows Updated = 0 2020-12-02 15:03:39|INFO|data formatting errors = 0 2020-12-02 15:03:39|INFO|gpload failed 2020-12-02 15:03:39|INFO|gpload session started 2020-12-02 15:03:39 -2020-12-02 15:03:39|ERROR|could not connect to database: FATAL: database "notexistdb" does not exist +2020-12-02 15:03:39|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: database "notexistdb" does not exist . Is the Greenplum Database running on port 7000? 2020-12-02 15:03:39|INFO|rows Inserted = 0 2020-12-02 15:03:39|INFO|rows Updated = 0 diff --git a/gpMgmt/bin/gpload_test/gpload2/query51.ans b/gpMgmt/bin/gpload_test/gpload2/query51.ans index bdbbfb010689..03200f111e1a 100644 --- a/gpMgmt/bin/gpload_test/gpload2/query51.ans +++ b/gpMgmt/bin/gpload_test/gpload2/query51.ans @@ -1,12 +1,12 @@ 2020-12-01 17:16:29|INFO|gpload session started 2020-12-01 17:16:29 -2020-12-01 17:16:29|ERROR|could not connect to database: FATAL: no pg_hba.conf entry for host "*", user "notexistusr", database "reuse_gptest" +2020-12-01 17:16:29|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: no pg_hba.conf entry for host "HOST", user "notexistusr", database "reuse_gptest", no encryption . Is the Greenplum Database running on port 7000? 2020-12-01 17:16:29|INFO|rows Inserted = 0 2020-12-01 17:16:29|INFO|rows Updated = 0 2020-12-01 17:16:29|INFO|data formatting errors = 0 2020-12-01 17:16:29|INFO|gpload failed 2020-12-01 17:16:30|INFO|gpload session started 2020-12-01 17:16:30 -2020-12-01 17:16:30|ERROR|could not connect to database: FATAL: no pg_hba.conf entry for host "*", user "notexistusr", database "reuse_gptest" +2020-12-01 17:16:30|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: no pg_hba.conf entry for host "HOST", user "notexistusr", database "reuse_gptest", no encryption . Is the Greenplum Database running on port 7000? 2020-12-01 17:16:30|INFO|rows Inserted = 0 2020-12-01 17:16:30|INFO|rows Updated = 0 diff --git a/gpMgmt/bin/gpload_test/gpload2/query56.ans b/gpMgmt/bin/gpload_test/gpload2/query56.ans index df5559e7b0c4..090f1fb75c18 100644 --- a/gpMgmt/bin/gpload_test/gpload2/query56.ans +++ b/gpMgmt/bin/gpload_test/gpload2/query56.ans @@ -1,12 +1,12 @@ 2020-12-03 14:46:48|INFO|gpload session started 2020-12-03 14:46:48 -2020-12-03 14:46:48|ERROR|could not connect to database: FATAL: database "notexist" does not exist +2020-12-03 14:46:48|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: database "notexist" does not exist . Is the Greenplum Database running on port 7000? 2020-12-03 14:46:48|INFO|rows Inserted = 0 2020-12-03 14:46:48|INFO|rows Updated = 0 2020-12-03 14:46:48|INFO|data formatting errors = 0 2020-12-03 14:46:48|INFO|gpload failed 2020-12-03 14:46:48|INFO|gpload session started 2020-12-03 14:46:48 -2020-12-03 14:46:48|ERROR|could not connect to database: FATAL: database "notexist" does not exist +2020-12-03 14:46:48|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: database "notexist" does not exist . Is the Greenplum Database running on port 7000? 2020-12-03 14:46:48|INFO|rows Inserted = 0 2020-12-03 14:46:48|INFO|rows Updated = 0 diff --git a/gpMgmt/bin/gpload_test/gpload2/query57.ans b/gpMgmt/bin/gpload_test/gpload2/query57.ans index 99e2a7de29e6..a44e0c895022 100644 --- a/gpMgmt/bin/gpload_test/gpload2/query57.ans +++ b/gpMgmt/bin/gpload_test/gpload2/query57.ans @@ -1,12 +1,12 @@ 2020-12-03 15:02:00|INFO|gpload session started 2020-12-03 15:02:00 -2020-12-03 15:02:00|ERROR|could not connect to database: FATAL: no pg_hba.conf entry for host "*", user "notexist", database "reuse_gptest" +2020-12-03 15:02:00|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: no pg_hba.conf entry for host "HOST", user "notexist", database "reuse_gptest", no encryption . Is the Greenplum Database running on port 7000? 2020-12-03 15:02:00|INFO|rows Inserted = 0 2020-12-03 15:02:00|INFO|rows Updated = 0 2020-12-03 15:02:00|INFO|data formatting errors = 0 2020-12-03 15:02:00|INFO|gpload failed 2020-12-03 15:02:00|INFO|gpload session started 2020-12-03 15:02:00 -2020-12-03 15:02:00|ERROR|could not connect to database: FATAL: no pg_hba.conf entry for host "*", user "notexist", database "reuse_gptest" +2020-12-03 15:02:00|ERROR|could not connect to database: connection to server at "HOST", port 7000 failed: FATAL: no pg_hba.conf entry for host "HOST", user "notexist", database "reuse_gptest", no encryption . Is the Greenplum Database running on port 7000? 2020-12-03 15:02:00|INFO|rows Inserted = 0 2020-12-03 15:02:00|INFO|rows Updated = 0 diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 8275b3298c63..80f5ea15b73f 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -195,7 +195,7 @@ with_perl = @with_perl@ with_python = @with_python@ with_pythonsrc_ext = @with_pythonsrc_ext@ with_tcl = @with_tcl@ -with_openssl = @with_openssl@ +with_ssl = @with_ssl@ with_readline = @with_readline@ with_selinux = @with_selinux@ with_systemd = @with_systemd@ @@ -295,7 +295,8 @@ SUN_STUDIO_CC = @SUN_STUDIO_CC@ CXX = @CXX@ CFLAGS = @CFLAGS@ CFLAGS_SL = @CFLAGS_SL@ -CFLAGS_VECTOR = @CFLAGS_VECTOR@ +CFLAGS_UNROLL_LOOPS = @CFLAGS_UNROLL_LOOPS@ +CFLAGS_VECTORIZE = @CFLAGS_VECTORIZE@ CFLAGS_SSE42 = @CFLAGS_SSE42@ CFLAGS_ARMV8_CRC32C = @CFLAGS_ARMV8_CRC32C@ PERMIT_DECLARATION_AFTER_STATEMENT = @PERMIT_DECLARATION_AFTER_STATEMENT@ @@ -327,7 +328,6 @@ LIBS = @LIBS@ LDAP_LIBS_FE = @LDAP_LIBS_FE@ LDAP_LIBS_BE = @LDAP_LIBS_BE@ UUID_LIBS = @UUID_LIBS@ -UUID_EXTRA_OBJS = @UUID_EXTRA_OBJS@ LLVM_LIBS=@LLVM_LIBS@ LD = @LD@ with_gnu_ld = @with_gnu_ld@ @@ -415,7 +415,7 @@ DOWNLOAD = wget -O $@ --no-use-server-timestamps UNICODE_VERSION = 13.0.0 # Pick a release from here: -CLDR_VERSION = 37 +CLDR_VERSION = 39 # Tree-wide build support diff --git a/src/backend/Makefile b/src/backend/Makefile index 00fb43039250..567f15c23a47 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -2,7 +2,7 @@ # # Makefile for the postgres backend # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/Makefile @@ -202,7 +202,6 @@ distprep: $(MAKE) -C utils distprep $(MAKE) -C utils/adt jsonpath_gram.c jsonpath_scan.c $(MAKE) -C utils/misc guc-file.c - $(MAKE) -C utils/sort qsort_tuple.c ########################################################################## @@ -328,8 +327,7 @@ maintainer-clean: distclean storage/lmgr/lwlocknames.h \ utils/adt/jsonpath_gram.c \ utils/adt/jsonpath_scan.c \ - utils/misc/guc-file.c \ - utils/sort/qsort_tuple.c + utils/misc/guc-file.c ########################################################################## diff --git a/src/backend/access/aocs/aocs_compaction.c b/src/backend/access/aocs/aocs_compaction.c index 2cb52b79eb4d..0977a875ff9c 100644 --- a/src/backend/access/aocs/aocs_compaction.c +++ b/src/backend/access/aocs/aocs_compaction.c @@ -191,7 +191,7 @@ AOCSMoveTuple(TupleTableSlot *slot, /* insert index' tuples if needed */ if (resultRelInfo->ri_NumIndices > 0) { - ExecInsertIndexTuples(slot, estate, false, false, NIL); + ExecInsertIndexTuples(resultRelInfo, slot, estate, false, false, NULL, NIL); ResetPerTupleExprContext(estate); } @@ -263,8 +263,6 @@ AOCSSegmentFileFullCompaction(Relation aorel, resultRelInfo->ri_RelationDesc = aorel; resultRelInfo->ri_TrigDesc = NULL; /* we don't fire triggers */ ExecOpenIndices(resultRelInfo, false); - estate->es_result_relations = resultRelInfo; - estate->es_num_result_relations = 1; estate->es_result_relation_info = resultRelInfo; /* diff --git a/src/backend/access/aocs/aocsam_handler.c b/src/backend/access/aocs/aocsam_handler.c index 685cea869e53..006d57c77484 100644 --- a/src/backend/access/aocs/aocsam_handler.c +++ b/src/backend/access/aocs/aocsam_handler.c @@ -2065,6 +2065,13 @@ aoco_scan_bitmap_next_tuple(TableScanDesc scan, { /* OK to return this tuple */ ExecStoreVirtualTuple(slot); + /* + * GPDB: the fetch fills the data columns but not tableOid; the + * tableoid junk column of multi-relation UPDATE/DELETE reads it, + * and a zero there made the per-row result-relation lookup fall + * through to the wrong table (heap_delete with an AO TID). + */ + slot->tts_tableOid = RelationGetRelid(aocsBitmapScan->rs_base.rs_rd); pgstat_count_heap_fetch(aocsBitmapScan->rs_base.rs_rd); return true; @@ -2157,7 +2164,7 @@ static const TableAmRoutine ao_column_methods = { .tuple_get_latest_tid = aoco_get_latest_tid, .tuple_tid_valid = aoco_tuple_tid_valid, .tuple_satisfies_snapshot = aoco_tuple_satisfies_snapshot, - .compute_xid_horizon_for_tuples = aoco_compute_xid_horizon_for_tuples, + .index_delete_tuples = NULL, .relation_set_new_filenode = aoco_relation_set_new_filenode, .relation_nontransactional_truncate = aoco_relation_nontransactional_truncate, diff --git a/src/backend/access/appendonly/appendonly_compaction.c b/src/backend/access/appendonly/appendonly_compaction.c index a9ca318d06d1..46256cd025e7 100644 --- a/src/backend/access/appendonly/appendonly_compaction.c +++ b/src/backend/access/appendonly/appendonly_compaction.c @@ -301,8 +301,9 @@ AppendOnlyMoveTuple(TupleTableSlot *slot, /* insert index' tuples if needed */ if (resultRelInfo->ri_NumIndices > 0) { - ExecInsertIndexTuples(slot, - estate, + ExecInsertIndexTuples(resultRelInfo, + slot, estate, + false, /* update */ false, /* noDupError */ NULL, /* specConflict */ NIL /* arbiterIndexes */); @@ -444,8 +445,6 @@ AppendOnlySegmentFileFullCompaction(Relation aorel, resultRelInfo->ri_RelationDesc = aorel; resultRelInfo->ri_TrigDesc = NULL; /* we don't fire triggers */ ExecOpenIndices(resultRelInfo, false); - estate->es_result_relations = resultRelInfo; - estate->es_num_result_relations = 1; estate->es_result_relation_info = resultRelInfo; /* diff --git a/src/backend/access/appendonly/appendonlyam_handler.c b/src/backend/access/appendonly/appendonlyam_handler.c index 86daafa05424..1277f5303c97 100644 --- a/src/backend/access/appendonly/appendonlyam_handler.c +++ b/src/backend/access/appendonly/appendonlyam_handler.c @@ -1806,6 +1806,7 @@ appendonly_index_validate_scan(Relation heapRelation, heapRelation, indexInfo->ii_Unique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, + false, indexInfo); state->tups_inserted += 1; @@ -2088,6 +2089,8 @@ appendonly_scan_bitmap_next_tuple(TableScanDesc scan, if(appendonly_fetch(aoscan->aofetch, &aoTid, slot)) { /* OK to return this tuple */ + /* GPDB: see aoco_scan_bitmap_next_tuple -- keep tableOid valid */ + slot->tts_tableOid = RelationGetRelid(aoscan->aos_rd); pgstat_count_heap_fetch(aoscan->aos_rd); return true; @@ -2168,7 +2171,7 @@ static const TableAmRoutine ao_row_methods = { .tuple_get_latest_tid = appendonly_get_latest_tid, .tuple_tid_valid = appendonly_tuple_tid_valid, .tuple_satisfies_snapshot = appendonly_tuple_satisfies_snapshot, - .compute_xid_horizon_for_tuples = appendonly_compute_xid_horizon_for_tuples, + .index_delete_tuples = NULL, .relation_set_new_filenode = appendonly_relation_set_new_filenode, .relation_nontransactional_truncate = appendonly_relation_nontransactional_truncate, diff --git a/src/backend/access/bitmap/bitmap.c b/src/backend/access/bitmap/bitmap.c index c6016fc7e260..aafd2c323ec6 100644 --- a/src/backend/access/bitmap/bitmap.c +++ b/src/backend/access/bitmap/bitmap.c @@ -540,13 +540,21 @@ bmbulkdelete(IndexVacuumInfo *info, void *callback_state) { Relation rel = info->index; + ReindexParams reindex_params = {0}; /* allocate stats if first time through, else re-use existing struct */ if (stats == NULL) stats = (IndexBulkDeleteResult *) - palloc0(sizeof(IndexBulkDeleteResult)); + palloc0(sizeof(IndexBulkDeleteResult)); - reindex_index(RelationGetRelid(rel), true, rel->rd_rel->relpersistence, 0); + /* + * PG14 changed reindex_index()'s last argument from an int options bitmask + * to a ReindexParams pointer, which it dereferences. Pass an empty params + * struct instead of a literal 0 (which became a NULL deref -> SIGSEGV when + * VACUUM reindexed a bitmap index, e.g. "vacuum bm_test"). + */ + reindex_index(RelationGetRelid(rel), true, rel->rd_rel->relpersistence, + &reindex_params); CommandCounterIncrement(); diff --git a/src/backend/access/bitmap/bitmapattutil.c b/src/backend/access/bitmap/bitmapattutil.c index 9ccbf5147263..8fecfd3f44bc 100644 --- a/src/backend/access/bitmap/bitmapattutil.c +++ b/src/backend/access/bitmap/bitmapattutil.c @@ -340,7 +340,7 @@ _bitmap_insert_lov(Relation lovHeap, Relation lovIndex, Datum *datum, memcpy(indexDatum, datum, (tupDesc->natts - 2) * sizeof(Datum)); memcpy(indexNulls, nulls, (tupDesc->natts - 2) * sizeof(bool)); result = index_insert(lovIndex, indexDatum, indexNulls, - &(tuple->t_self), lovHeap, true, NULL); + &(tuple->t_self), lovHeap, true, false, NULL); pfree(indexDatum); pfree(indexNulls); diff --git a/src/backend/access/brin/Makefile b/src/backend/access/brin/Makefile index 468e1e289a15..a386cb71f193 100644 --- a/src/backend/access/brin/Makefile +++ b/src/backend/access/brin/Makefile @@ -14,8 +14,10 @@ include $(top_builddir)/src/Makefile.global OBJS = \ brin.o \ + brin_bloom.o \ brin_inclusion.o \ brin_minmax.o \ + brin_minmax_multi.o \ brin_pageops.o \ brin_revmap.o \ brin_tuple.o \ diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index 58dbc63034d0..03083b47d1dc 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -4,7 +4,7 @@ * * See src/backend/access/brin/README for details. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -38,6 +38,7 @@ #include "storage/freespace.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/datum.h" #include "utils/index_selfuncs.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -85,7 +86,9 @@ static void form_and_insert_tuple(BrinBuildState *state); static void union_tuples(BrinDesc *bdesc, BrinMemTuple *a, BrinTuple *b); static void brin_vacuum_scan(Relation idxrel, BufferAccessStrategy strategy); - +static bool add_values_to_range(Relation idxRel, BrinDesc *bdesc, + BrinMemTuple *dtup, Datum *values, bool *nulls); +static bool check_null_keys(BrinValues *bval, ScanKey *nullkeys, int nnullkeys); /* * BRIN handler function: return IndexAmRoutine with access method parameters @@ -159,6 +162,7 @@ bool brininsert(Relation idxRel, Datum *values, bool *nulls, ItemPointer heaptid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { BlockNumber pagesPerRange; @@ -186,7 +190,6 @@ brininsert(Relation idxRel, Datum *values, bool *nulls, OffsetNumber off; BrinTuple *brtup; BrinMemTuple *dtup; - int keyno; CHECK_FOR_INTERRUPTS(); @@ -250,31 +253,7 @@ brininsert(Relation idxRel, Datum *values, bool *nulls, dtup = brin_deform_tuple(bdesc, brtup, NULL); - /* - * Compare the key values of the new tuple to the stored index values; - * our deformed tuple will get updated if the new tuple doesn't fit - * the original range (note this means we can't break out of the loop - * early). Make a note of whether this happens, so that we know to - * insert the modified tuple later. - */ - for (keyno = 0; keyno < bdesc->bd_tupdesc->natts; keyno++) - { - Datum result; - BrinValues *bval; - FmgrInfo *addValue; - - bval = &dtup->bt_columns[keyno]; - addValue = index_getprocinfo(idxRel, keyno + 1, - BRIN_PROCNUM_ADDVALUE); - result = FunctionCall4Coll(addValue, - idxRel->rd_indcollation[keyno], - PointerGetDatum(bdesc), - PointerGetDatum(bval), - values[keyno], - nulls[keyno]); - /* if that returned true, we need to insert the updated tuple */ - need_insert |= DatumGetBool(result); - } + need_insert = add_values_to_range(idxRel, bdesc, dtup, values, nulls); if (!need_insert) { @@ -467,6 +446,14 @@ bringetbitmap(IndexScanDesc scan, Node **bmNodeP) Size btupsz = 0; int segno; BlockNumber seg_start_blk; + ScanKey **keys, + **nullkeys; + int *nkeys, + *nnullkeys; + int keyno; + char *ptr; + Size len; + char *tmp PG_USED_FOR_ASSERTS_ONLY; opaque = (BrinOpaque *) scan->opaque; bdesc = opaque->bo_bdesc; @@ -514,6 +501,115 @@ bringetbitmap(IndexScanDesc scan, Node **bmNodeP) */ consistentFn = palloc0(sizeof(FmgrInfo) * bdesc->bd_tupdesc->natts); + /* + * Make room for per-attribute lists of scan keys that we'll pass to the + * consistent support procedure. We don't know which attributes have scan + * keys, so we allocate space for all attributes. That may use more memory + * but it's probably cheaper than determining which attributes are used. + * + * We keep null and regular keys separate, so that we can pass just the + * regular keys to the consistent function easily. + * + * To reduce the allocation overhead, we allocate one big chunk and then + * carve it into smaller arrays ourselves. All the pieces have exactly the + * same lifetime, so that's OK. + * + * XXX The widest index can have 32 attributes, so the amount of wasted + * memory is negligible. We could invent a more compact approach (with + * just space for used attributes) but that would make the matching more + * complex so it's not a good trade-off. + */ + len = + MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts) + /* regular keys */ + MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys) * bdesc->bd_tupdesc->natts + + MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts) + + MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts) + /* NULL keys */ + MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys) * bdesc->bd_tupdesc->natts + + MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts); + + ptr = palloc(len); + tmp = ptr; + + keys = (ScanKey **) ptr; + ptr += MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts); + + nullkeys = (ScanKey **) ptr; + ptr += MAXALIGN(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts); + + nkeys = (int *) ptr; + ptr += MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts); + + nnullkeys = (int *) ptr; + ptr += MAXALIGN(sizeof(int) * bdesc->bd_tupdesc->natts); + + for (int i = 0; i < bdesc->bd_tupdesc->natts; i++) + { + keys[i] = (ScanKey *) ptr; + ptr += MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys); + + nullkeys[i] = (ScanKey *) ptr; + ptr += MAXALIGN(sizeof(ScanKey) * scan->numberOfKeys); + } + + Assert(tmp + len == ptr); + + /* zero the number of keys */ + memset(nkeys, 0, sizeof(int) * bdesc->bd_tupdesc->natts); + memset(nnullkeys, 0, sizeof(int) * bdesc->bd_tupdesc->natts); + + /* Preprocess the scan keys - split them into per-attribute arrays. */ + for (keyno = 0; keyno < scan->numberOfKeys; keyno++) + { + ScanKey key = &scan->keyData[keyno]; + AttrNumber keyattno = key->sk_attno; + + /* + * The collation of the scan key must match the collation used in the + * index column (but only if the search is not IS NULL/ IS NOT NULL). + * Otherwise we shouldn't be using this index ... + */ + Assert((key->sk_flags & SK_ISNULL) || + (key->sk_collation == + TupleDescAttr(bdesc->bd_tupdesc, + keyattno - 1)->attcollation)); + + /* + * First time we see this index attribute, so init as needed. + * + * This is a bit of an overkill - we don't know how many scan keys are + * there for this attribute, so we simply allocate the largest number + * possible (as if all keys were for this attribute). This may waste a + * bit of memory, but we only expect small number of scan keys in + * general, so this should be negligible, and repeated repalloc calls + * are not free either. + */ + if (consistentFn[keyattno - 1].fn_oid == InvalidOid) + { + FmgrInfo *tmp; + + /* First time we see this attribute, so no key/null keys. */ + Assert(nkeys[keyattno - 1] == 0); + Assert(nnullkeys[keyattno - 1] == 0); + + tmp = index_getprocinfo(idxRel, keyattno, + BRIN_PROCNUM_CONSISTENT); + fmgr_info_copy(&consistentFn[keyattno - 1], tmp, + CurrentMemoryContext); + } + + /* Add key to the proper per-attribute array. */ + if (key->sk_flags & SK_ISNULL) + { + nullkeys[keyattno - 1][nnullkeys[keyattno - 1]] = key; + nnullkeys[keyattno - 1]++; + } + else + { + keys[keyattno - 1][nkeys[keyattno - 1]] = key; + nkeys[keyattno - 1]++; + } + } + /* allocate an initial in-memory tuple, out of the per-range memcxt */ dtup = brin_new_memtuple(bdesc); @@ -592,7 +688,7 @@ bringetbitmap(IndexScanDesc scan, Node **bmNodeP) } else { - int keyno; + int attno; /* * Compare scan keys with summary values stored for the range. @@ -602,53 +698,116 @@ bringetbitmap(IndexScanDesc scan, Node **bmNodeP) * no keys. */ addrange = true; - for (keyno = 0; keyno < scan->numberOfKeys; keyno++) + for (attno = 1; attno <= bdesc->bd_tupdesc->natts; attno++) { - ScanKey key = &scan->keyData[keyno]; - AttrNumber keyattno = key->sk_attno; - BrinValues *bval = &dtup->bt_columns[keyattno - 1]; + BrinValues *bval; Datum add; + Oid collation; /* - * The collation of the scan key must match the collation - * used in the index column (but only if the search is not - * IS NULL/ IS NOT NULL). Otherwise we shouldn't be using - * this index ... + * skip attributes without any scan keys (both regular and + * IS [NOT] NULL) */ - Assert((key->sk_flags & SK_ISNULL) || - (key->sk_collation == - TupleDescAttr(bdesc->bd_tupdesc, - keyattno - 1)->attcollation)); + if (nkeys[attno - 1] == 0 && nnullkeys[attno - 1] == 0) + continue; - /* First time this column? look up consistent function */ - if (consistentFn[keyattno - 1].fn_oid == InvalidOid) + bval = &dtup->bt_columns[attno - 1]; + + /* + * First check if there are any IS [NOT] NULL scan keys, + * and if we're violating them. In that case we can + * terminate early, without invoking the support function. + * + * As there may be more keys, we can only determine + * mismatch within this loop. + */ + if (bdesc->bd_info[attno - 1]->oi_regular_nulls && + !check_null_keys(bval, nullkeys[attno - 1], + nnullkeys[attno - 1])) { - FmgrInfo *tmp; + /* + * If any of the IS [NOT] NULL keys failed, the page + * range as a whole can't pass. So terminate the loop. + */ + addrange = false; + break; + } - tmp = index_getprocinfo(idxRel, keyattno, - BRIN_PROCNUM_CONSISTENT); - fmgr_info_copy(&consistentFn[keyattno - 1], tmp, - CurrentMemoryContext); + /* + * So either there are no IS [NOT] NULL keys, or all + * passed. If there are no regular scan keys, we're done - + * the page range matches. If there are regular keys, but + * the page range is marked as 'all nulls' it can't + * possibly pass (we're assuming the operators are + * strict). + */ + + /* No regular scan keys - page range as a whole passes. */ + if (!nkeys[attno - 1]) + continue; + + Assert((nkeys[attno - 1] > 0) && + (nkeys[attno - 1] <= scan->numberOfKeys)); + + /* If it is all nulls, it cannot possibly be consistent. */ + if (bval->bv_allnulls) + { + addrange = false; + break; } + /* + * Collation from the first key (has to be the same for + * all keys for the same attribute). + */ + collation = keys[attno - 1][0]->sk_collation; + /* * Check whether the scan key is consistent with the page * range values; if so, have the pages in the range added * to the output bitmap. * - * When there are multiple scan keys, failure to meet the - * criteria for a single one of them is enough to discard - * the range as a whole, so break out of the loop as soon - * as a false return value is obtained. + * The opclass may or may not support processing of + * multiple scan keys. We can determine that based on the + * number of arguments - functions with extra parameter + * (number of scan keys) do support this, otherwise we + * have to simply pass the scan keys one by one. */ - add = FunctionCall3Coll(&consistentFn[keyattno - 1], - key->sk_collation, - PointerGetDatum(bdesc), - PointerGetDatum(bval), - PointerGetDatum(key)); - addrange = DatumGetBool(add); - if (!addrange) - break; + if (consistentFn[attno - 1].fn_nargs >= 4) + { + /* Check all keys at once */ + add = FunctionCall4Coll(&consistentFn[attno - 1], + collation, + PointerGetDatum(bdesc), + PointerGetDatum(bval), + PointerGetDatum(keys[attno - 1]), + Int32GetDatum(nkeys[attno - 1])); + addrange = DatumGetBool(add); + } + else + { + /* + * Check keys one by one + * + * When there are multiple scan keys, failure to meet + * the criteria for a single one of them is enough to + * discard the range as a whole, so break out of the + * loop as soon as a false return value is obtained. + */ + int keyno; + + for (keyno = 0; keyno < nkeys[attno - 1]; keyno++) + { + add = FunctionCall3Coll(&consistentFn[attno - 1], + keys[attno - 1][keyno]->sk_collation, + PointerGetDatum(bdesc), + PointerGetDatum(bval), + PointerGetDatum(keys[attno - 1][keyno])); + addrange = DatumGetBool(add); + if (!addrange) + break; + } + } } } } @@ -659,7 +818,7 @@ bringetbitmap(IndexScanDesc scan, Node **bmNodeP) BlockNumber pageno; for (pageno = heapBlk; - pageno <= heapBlk + opaque->bo_pagesPerRange - 1; + pageno <= Min(nblocks, heapBlk + opaque->bo_pagesPerRange) - 1; pageno++) { MemoryContextSwitchTo(oldcxt); @@ -734,7 +893,6 @@ brinbuildCallback(Relation index, { BrinBuildState *state = (BrinBuildState *) brstate; BlockNumber thisblock; - int i; thisblock = ItemPointerGetBlockNumber(tid); @@ -767,25 +925,8 @@ brinbuildCallback(Relation index, } /* Accumulate the current tuple into the running state */ - for (i = 0; i < state->bs_bdesc->bd_tupdesc->natts; i++) - { - FmgrInfo *addValue; - BrinValues *col; - Form_pg_attribute attr = TupleDescAttr(state->bs_bdesc->bd_tupdesc, i); - - col = &state->bs_dtuple->bt_columns[i]; - addValue = index_getprocinfo(index, i + 1, - BRIN_PROCNUM_ADDVALUE); - - /* - * Update dtuple state, if and as necessary. - */ - FunctionCall4Coll(addValue, - attr->attcollation, - PointerGetDatum(state->bs_bdesc), - PointerGetDatum(col), - values[i], isnull[i]); - } + (void) add_values_to_range(index, state->bs_bdesc, state->bs_dtuple, + values, isnull); } /* @@ -1057,7 +1198,7 @@ brin_summarize_range_internal(PG_FUNCTION_ARGS) if (heapRel == NULL || heapoid != IndexGetRelation(indexoid, false)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("could not open parent table of index %s", + errmsg("could not open parent table of index \"%s\"", RelationGetRelationName(indexRel)))); /* OK, do it */ @@ -1134,7 +1275,7 @@ brin_desummarize_range(PG_FUNCTION_ARGS) if (heapRel == NULL || heapoid != IndexGetRelation(indexoid, false)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("could not open parent table of index %s", + errmsg("could not open parent table of index \"%s\"", RelationGetRelationName(indexRel)))); /* the revmap does the hard work */ @@ -1605,6 +1746,39 @@ union_tuples(BrinDesc *bdesc, BrinMemTuple *a, BrinTuple *b) FmgrInfo *unionFn; BrinValues *col_a = &a->bt_columns[keyno]; BrinValues *col_b = &db->bt_columns[keyno]; + BrinOpcInfo *opcinfo = bdesc->bd_info[keyno]; + + if (opcinfo->oi_regular_nulls) + { + /* Adjust "hasnulls". */ + if (!col_a->bv_hasnulls && col_b->bv_hasnulls) + col_a->bv_hasnulls = true; + + /* If there are no values in B, there's nothing left to do. */ + if (col_b->bv_allnulls) + continue; + + /* + * Adjust "allnulls". If A doesn't have values, just copy the + * values from B into A, and we're done. We cannot run the + * operators in this case, because values in A might contain + * garbage. Note we already established that B contains values. + */ + if (col_a->bv_allnulls) + { + int i; + + col_a->bv_allnulls = false; + + for (i = 0; i < opcinfo->oi_nstored; i++) + col_a->bv_values[i] = + datumCopy(col_b->bv_values[i], + opcinfo->oi_typcache[i]->typbyval, + opcinfo->oi_typcache[i]->typlen); + + continue; + } + } unionFn = index_getprocinfo(bdesc->bd_index, keyno + 1, BRIN_PROCNUM_UNION); @@ -1658,3 +1832,103 @@ brin_vacuum_scan(Relation idxrel, BufferAccessStrategy strategy) */ FreeSpaceMapVacuum(idxrel); } + +static bool +add_values_to_range(Relation idxRel, BrinDesc *bdesc, BrinMemTuple *dtup, + Datum *values, bool *nulls) +{ + int keyno; + bool modified = false; + + /* + * Compare the key values of the new tuple to the stored index values; our + * deformed tuple will get updated if the new tuple doesn't fit the + * original range (note this means we can't break out of the loop early). + * Make a note of whether this happens, so that we know to insert the + * modified tuple later. + */ + for (keyno = 0; keyno < bdesc->bd_tupdesc->natts; keyno++) + { + Datum result; + BrinValues *bval; + FmgrInfo *addValue; + + bval = &dtup->bt_columns[keyno]; + + if (bdesc->bd_info[keyno]->oi_regular_nulls && nulls[keyno]) + { + /* + * If the new value is null, we record that we saw it if it's the + * first one; otherwise, there's nothing to do. + */ + if (!bval->bv_hasnulls) + { + bval->bv_hasnulls = true; + modified = true; + } + + continue; + } + + addValue = index_getprocinfo(idxRel, keyno + 1, + BRIN_PROCNUM_ADDVALUE); + result = FunctionCall4Coll(addValue, + idxRel->rd_indcollation[keyno], + PointerGetDatum(bdesc), + PointerGetDatum(bval), + values[keyno], + nulls[keyno]); + /* if that returned true, we need to insert the updated tuple */ + modified |= DatumGetBool(result); + } + + return modified; +} + +static bool +check_null_keys(BrinValues *bval, ScanKey *nullkeys, int nnullkeys) +{ + int keyno; + + /* + * First check if there are any IS [NOT] NULL scan keys, and if we're + * violating them. + */ + for (keyno = 0; keyno < nnullkeys; keyno++) + { + ScanKey key = nullkeys[keyno]; + + Assert(key->sk_attno == bval->bv_attno); + + /* Handle only IS NULL/IS NOT NULL tests */ + if (!(key->sk_flags & SK_ISNULL)) + continue; + + if (key->sk_flags & SK_SEARCHNULL) + { + /* IS NULL scan key, but range has no NULLs */ + if (!bval->bv_allnulls && !bval->bv_hasnulls) + return false; + } + else if (key->sk_flags & SK_SEARCHNOTNULL) + { + /* + * For IS NOT NULL, we can only skip ranges that are known to have + * only nulls. + */ + if (bval->bv_allnulls) + return false; + } + else + { + /* + * Neither IS NULL nor IS NOT NULL was used; assume all indexable + * operators are strict and thus return false with NULL value in + * the scan key. + */ + return false; + } + } + + return true; +} diff --git a/src/backend/access/brin/brin_bloom.c b/src/backend/access/brin/brin_bloom.c new file mode 100644 index 000000000000..2c8a20aaca64 --- /dev/null +++ b/src/backend/access/brin/brin_bloom.c @@ -0,0 +1,809 @@ +/* + * brin_bloom.c + * Implementation of Bloom opclass for BRIN + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * A BRIN opclass summarizing page range into a bloom filter. + * + * Bloom filters allow efficient testing whether a given page range contains + * a particular value. Therefore, if we summarize each page range into a small + * bloom filter, we can easily (and cheaply) test whether it contains values + * we get later. + * + * The index only supports equality operators, similarly to hash indexes. + * Bloom indexes are however much smaller, and support only bitmap scans. + * + * Note: Don't confuse this with bloom indexes, implemented in a contrib + * module. That extension implements an entirely new AM, building a bloom + * filter on multiple columns in a single row. This opclass works with an + * existing AM (BRIN) and builds bloom filter on a column. + * + * + * values vs. hashes + * ----------------- + * + * The original column values are not used directly, but are first hashed + * using the regular type-specific hash function, producing a uint32 hash. + * And this hash value is then added to the summary - i.e. it's hashed + * again and added to the bloom filter. + * + * This allows the code to treat all data types (byval/byref/...) the same + * way, with only minimal space requirements, because we're working with + * hashes and not the original values. Everything is uint32. + * + * Of course, this assumes the built-in hash function is reasonably good, + * without too many collisions etc. But that does seem to be the case, at + * least based on past experience. After all, the same hash functions are + * used for hash indexes, hash partitioning and so on. + * + * + * hashing scheme + * -------------- + * + * Bloom filters require a number of independent hash functions. There are + * different schemes how to construct them - for example we might use + * hash_uint32_extended with random seeds, but that seems fairly expensive. + * We use a scheme requiring only two functions described in this paper: + * + * Less Hashing, Same Performance:Building a Better Bloom Filter + * Adam Kirsch, Michael Mitzenmacher†, Harvard School of Engineering and + * Applied Sciences, Cambridge, Massachusetts [DOI 10.1002/rsa.20208] + * + * The two hash functions h1 and h2 are calculated using hard-coded seeds, + * and then combined using (h1 + i * h2) to generate the hash functions. + * + * + * sizing the bloom filter + * ----------------------- + * + * Size of a bloom filter depends on the number of distinct values we will + * store in it, and the desired false positive rate. The higher the number + * of distinct values and/or the lower the false positive rate, the larger + * the bloom filter. On the other hand, we want to keep the index as small + * as possible - that's one of the basic advantages of BRIN indexes. + * + * Although the number of distinct elements (in a page range) depends on + * the data, we can consider it fixed. This simplifies the trade-off to + * just false positive rate vs. size. + * + * At the page range level, false positive rate is a probability the bloom + * filter matches a random value. For the whole index (with sufficiently + * many page ranges) it represents the fraction of the index ranges (and + * thus fraction of the table to be scanned) matching the random value. + * + * Furthermore, the size of the bloom filter is subject to implementation + * limits - it has to fit onto a single index page (8kB by default). As + * the bitmap is inherently random (when "full" about half the bits is set + * to 1, randomly), compression can't help very much. + * + * To reduce the size of a filter (to fit to a page), we have to either + * accept higher false positive rate (undesirable), or reduce the number + * of distinct items to be stored in the filter. We can't alter the input + * data, of course, but we may make the BRIN page ranges smaller - instead + * of the default 128 pages (1MB) we may build index with 16-page ranges, + * or something like that. This should reduce the number of distinct values + * in the page range, making the filter smaller (with fixed false positive + * rate). Even for random data sets this should help, as the number of rows + * per heap page is limited (to ~290 with very narrow tables, likely ~20 + * in practice). + * + * Of course, good sizing decisions depend on having the necessary data, + * i.e. number of distinct values in a page range (of a given size) and + * table size (to estimate cost change due to change in false positive + * rate due to having larger index vs. scanning larger indexes). We may + * not have that data - for example when building an index on empty table + * it's not really possible. And for some data we only have estimates for + * the whole table and we can only estimate per-range values (ndistinct). + * + * Another challenge is that while the bloom filter is per-column, it's + * the whole index tuple that has to fit into a page. And for multi-column + * indexes that may include pieces we have no control over (not necessarily + * bloom filters, the other columns may use other BRIN opclasses). So it's + * not entirely clear how to distribute the space between those columns. + * + * The current logic, implemented in brin_bloom_get_ndistinct, attempts to + * make some basic sizing decisions, based on the size of BRIN ranges, and + * the maximum number of rows per range. + * + * + * IDENTIFICATION + * src/backend/access/brin/brin_bloom.c + */ +#include "postgres.h" + +#include "access/genam.h" +#include "access/brin.h" +#include "access/brin_internal.h" +#include "access/brin_page.h" +#include "access/brin_tuple.h" +#include "access/hash.h" +#include "access/htup_details.h" +#include "access/reloptions.h" +#include "access/stratnum.h" +#include "catalog/pg_type.h" +#include "catalog/pg_amop.h" +#include "utils/builtins.h" +#include "utils/datum.h" +#include "utils/lsyscache.h" +#include "utils/rel.h" +#include "utils/syscache.h" + +#include + +#define BloomEqualStrategyNumber 1 + +/* + * Additional SQL level support functions. We only have one, which is + * used to calculate hash of the input value. + * + * Procedure numbers must not use values reserved for BRIN itself; see + * brin_internal.h. + */ +#define BLOOM_MAX_PROCNUMS 1 /* maximum support procs we need */ +#define PROCNUM_HASH 11 /* required */ + +/* + * Subtract this from procnum to obtain index in BloomOpaque arrays + * (Must be equal to minimum of private procnums). + */ +#define PROCNUM_BASE 11 + +/* + * Storage type for BRIN's reloptions. + */ +typedef struct BloomOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + double nDistinctPerRange; /* number of distinct values per range */ + double falsePositiveRate; /* false positive for bloom filter */ +} BloomOptions; + +/* + * The current min value (16) is somewhat arbitrary, but it's based + * on the fact that the filter header is ~20B alone, which is about + * the same as the filter bitmap for 16 distinct items with 1% false + * positive rate. So by allowing lower values we'd not gain much. In + * any case, the min should not be larger than MaxHeapTuplesPerPage + * (~290), which is the theoretical maximum for single-page ranges. + */ +#define BLOOM_MIN_NDISTINCT_PER_RANGE 16 + +/* + * Used to determine number of distinct items, based on the number of rows + * in a page range. The 10% is somewhat similar to what estimate_num_groups + * does, so we use the same factor here. + */ +#define BLOOM_DEFAULT_NDISTINCT_PER_RANGE -0.1 /* 10% of values */ + +/* + * Allowed range and default value for the false positive range. The exact + * values are somewhat arbitrary, but were chosen considering the various + * parameters (size of filter vs. page size, etc.). + * + * The lower the false-positive rate, the more accurate the filter is, but + * it also gets larger - at some point this eliminates the main advantage + * of BRIN indexes, which is the tiny size. At 0.01% the index is about + * 10% of the table (assuming 290 distinct values per 8kB page). + * + * On the other hand, as the false-positive rate increases, larger part of + * the table has to be scanned due to mismatches - at 25% we're probably + * close to sequential scan being cheaper. + */ +#define BLOOM_MIN_FALSE_POSITIVE_RATE 0.0001 /* 0.01% fp rate */ +#define BLOOM_MAX_FALSE_POSITIVE_RATE 0.25 /* 25% fp rate */ +#define BLOOM_DEFAULT_FALSE_POSITIVE_RATE 0.01 /* 1% fp rate */ + +#define BloomGetNDistinctPerRange(opts) \ + ((opts) && (((BloomOptions *) (opts))->nDistinctPerRange != 0) ? \ + (((BloomOptions *) (opts))->nDistinctPerRange) : \ + BLOOM_DEFAULT_NDISTINCT_PER_RANGE) + +#define BloomGetFalsePositiveRate(opts) \ + ((opts) && (((BloomOptions *) (opts))->falsePositiveRate != 0.0) ? \ + (((BloomOptions *) (opts))->falsePositiveRate) : \ + BLOOM_DEFAULT_FALSE_POSITIVE_RATE) + +/* + * And estimate of the largest bloom we can fit onto a page. This is not + * a perfect guarantee, for a couple of reasons. For example, the row may + * be larger because the index has multiple columns. + */ +#define BloomMaxFilterSize \ + MAXALIGN_DOWN(BLCKSZ - \ + (MAXALIGN(SizeOfPageHeaderData + \ + sizeof(ItemIdData)) + \ + MAXALIGN(sizeof(BrinSpecialSpace)) + \ + SizeOfBrinTuple)) + +/* + * Seeds used to calculate two hash functions h1 and h2, which are then used + * to generate k hashes using the (h1 + i * h2) scheme. + */ +#define BLOOM_SEED_1 0x71d924af +#define BLOOM_SEED_2 0xba48b314 + +/* + * Bloom Filter + * + * Represents a bloom filter, built on hashes of the indexed values. That is, + * we compute a uint32 hash of the value, and then store this hash into the + * bloom filter (and compute additional hashes on it). + * + * XXX We could implement "sparse" bloom filters, keeping only the bytes that + * are not entirely 0. But while indexes don't support TOAST, the varlena can + * still be compressed. So this seems unnecessary, because the compression + * should do the same job. + * + * XXX We can also watch the number of bits set in the bloom filter, and then + * stop using it (and not store the bitmap, to save space) when the false + * positive rate gets too high. But even if the false positive rate exceeds the + * desired value, it still can eliminate some page ranges. + */ +typedef struct BloomFilter +{ + /* varlena header (do not touch directly!) */ + int32 vl_len_; + + /* space for various flags (unused for now) */ + uint16 flags; + + /* fields for the HASHED phase */ + uint8 nhashes; /* number of hash functions */ + uint32 nbits; /* number of bits in the bitmap (size) */ + uint32 nbits_set; /* number of bits set to 1 */ + + /* data of the bloom filter */ + char data[FLEXIBLE_ARRAY_MEMBER]; + +} BloomFilter; + + +/* + * bloom_init + * Initialize the Bloom Filter, allocate all the memory. + * + * The filter is initialized with optimal size for ndistinct expected values + * and the requested false positive rate. The filter is stored as varlena. + */ +static BloomFilter * +bloom_init(int ndistinct, double false_positive_rate) +{ + Size len; + BloomFilter *filter; + + int nbits; /* size of filter / number of bits */ + int nbytes; /* size of filter / number of bytes */ + + double k; /* number of hash functions */ + + Assert(ndistinct > 0); + Assert((false_positive_rate >= BLOOM_MIN_FALSE_POSITIVE_RATE) && + (false_positive_rate < BLOOM_MAX_FALSE_POSITIVE_RATE)); + + /* sizing bloom filter: -(n * ln(p)) / (ln(2))^2 */ + nbits = ceil(-(ndistinct * log(false_positive_rate)) / pow(log(2.0), 2)); + + /* round m to whole bytes */ + nbytes = ((nbits + 7) / 8); + nbits = nbytes * 8; + + /* + * Reject filters that are obviously too large to store on a page. + * + * Initially the bloom filter is just zeroes and so very compressible, but + * as we add values it gets more and more random, and so less and less + * compressible. So initially everything fits on the page, but we might + * get surprising failures later - we want to prevent that, so we reject + * bloom filter that are obviously too large. + * + * XXX It's not uncommon to oversize the bloom filter a bit, to defend + * against unexpected data anomalies (parts of table with more distinct + * values per range etc.). But we still need to make sure even the + * oversized filter fits on page, if such need arises. + * + * XXX This check is not perfect, because the index may have multiple + * filters that are small individually, but too large when combined. + */ + if (nbytes > BloomMaxFilterSize) + elog(ERROR, "the bloom filter is too large (%d > %zu)", nbytes, + BloomMaxFilterSize); + + /* + * round(log(2.0) * m / ndistinct), but assume round() may not be + * available on Windows + */ + k = log(2.0) * nbits / ndistinct; + k = (k - floor(k) >= 0.5) ? ceil(k) : floor(k); + + /* + * We allocate the whole filter. Most of it is going to be 0 bits, so the + * varlena is easy to compress. + */ + len = offsetof(BloomFilter, data) + nbytes; + + filter = (BloomFilter *) palloc0(len); + + filter->flags = 0; + filter->nhashes = (int) k; + filter->nbits = nbits; + + SET_VARSIZE(filter, len); + + return filter; +} + + +/* + * bloom_add_value + * Add value to the bloom filter. + */ +static BloomFilter * +bloom_add_value(BloomFilter *filter, uint32 value, bool *updated) +{ + int i; + uint64 h1, + h2; + + /* compute the hashes, used for the bloom filter */ + h1 = hash_bytes_uint32_extended(value, BLOOM_SEED_1) % filter->nbits; + h2 = hash_bytes_uint32_extended(value, BLOOM_SEED_2) % filter->nbits; + + /* compute the requested number of hashes */ + for (i = 0; i < filter->nhashes; i++) + { + /* h1 + h2 + f(i) */ + uint32 h = (h1 + i * h2) % filter->nbits; + uint32 byte = (h / 8); + uint32 bit = (h % 8); + + /* if the bit is not set, set it and remember we did that */ + if (!(filter->data[byte] & (0x01 << bit))) + { + filter->data[byte] |= (0x01 << bit); + filter->nbits_set++; + if (updated) + *updated = true; + } + } + + return filter; +} + + +/* + * bloom_contains_value + * Check if the bloom filter contains a particular value. + */ +static bool +bloom_contains_value(BloomFilter *filter, uint32 value) +{ + int i; + uint64 h1, + h2; + + /* calculate the two hashes */ + h1 = hash_bytes_uint32_extended(value, BLOOM_SEED_1) % filter->nbits; + h2 = hash_bytes_uint32_extended(value, BLOOM_SEED_2) % filter->nbits; + + /* compute the requested number of hashes */ + for (i = 0; i < filter->nhashes; i++) + { + /* h1 + h2 + f(i) */ + uint32 h = (h1 + i * h2) % filter->nbits; + uint32 byte = (h / 8); + uint32 bit = (h % 8); + + /* if the bit is not set, the value is not there */ + if (!(filter->data[byte] & (0x01 << bit))) + return false; + } + + /* all hashes found in bloom filter */ + return true; +} + +typedef struct BloomOpaque +{ + /* + * XXX At this point we only need a single proc (to compute the hash), but + * let's keep the array just like inclusion and minmax opclasses, for + * consistency. We may need additional procs in the future. + */ + FmgrInfo extra_procinfos[BLOOM_MAX_PROCNUMS]; + bool extra_proc_missing[BLOOM_MAX_PROCNUMS]; +} BloomOpaque; + +static FmgrInfo *bloom_get_procinfo(BrinDesc *bdesc, uint16 attno, + uint16 procnum); + + +Datum +brin_bloom_opcinfo(PG_FUNCTION_ARGS) +{ + BrinOpcInfo *result; + + /* + * opaque->strategy_procinfos is initialized lazily; here it is set to + * all-uninitialized by palloc0 which sets fn_oid to InvalidOid. + * + * bloom indexes only store the filter as a single BYTEA column + */ + + result = palloc0(MAXALIGN(SizeofBrinOpcInfo(1)) + + sizeof(BloomOpaque)); + result->oi_nstored = 1; + result->oi_regular_nulls = true; + result->oi_opaque = (BloomOpaque *) + MAXALIGN((char *) result + SizeofBrinOpcInfo(1)); + result->oi_typcache[0] = lookup_type_cache(PG_BRIN_BLOOM_SUMMARYOID, 0); + + PG_RETURN_POINTER(result); +} + +/* + * brin_bloom_get_ndistinct + * Determine the ndistinct value used to size bloom filter. + * + * Adjust the ndistinct value based on the pagesPerRange value. First, + * if it's negative, it's assumed to be relative to maximum number of + * tuples in the range (assuming each page gets MaxHeapTuplesPerPage + * tuples, which is likely a significant over-estimate). We also clamp + * the value, not to over-size the bloom filter unnecessarily. + * + * XXX We can only do this when the pagesPerRange value was supplied. + * If it wasn't, it has to be a read-only access to the index, in which + * case we don't really care. But perhaps we should fall-back to the + * default pagesPerRange value? + * + * XXX We might also fetch info about ndistinct estimate for the column, + * and compute the expected number of distinct values in a range. But + * that may be tricky due to data being sorted in various ways, so it + * seems better to rely on the upper estimate. + * + * XXX We might also calculate a better estimate of rows per BRIN range, + * instead of using MaxHeapTuplesPerPage (which probably produces values + * much higher than reality). + */ +static int +brin_bloom_get_ndistinct(BrinDesc *bdesc, BloomOptions *opts) +{ + double ndistinct; + double maxtuples; + BlockNumber pagesPerRange; + + pagesPerRange = BrinGetPagesPerRange(bdesc->bd_index); + ndistinct = BloomGetNDistinctPerRange(opts); + + Assert(BlockNumberIsValid(pagesPerRange)); + + maxtuples = MaxHeapTuplesPerPage * pagesPerRange; + + /* + * Similarly to n_distinct, negative values are relative - in this case to + * maximum number of tuples in the page range (maxtuples). + */ + if (ndistinct < 0) + ndistinct = (-ndistinct) * maxtuples; + + /* + * Positive values are to be used directly, but we still apply a couple of + * safeties to avoid using unreasonably small bloom filters. + */ + ndistinct = Max(ndistinct, BLOOM_MIN_NDISTINCT_PER_RANGE); + + /* + * And don't use more than the maximum possible number of tuples, in the + * range, which would be entirely wasteful. + */ + ndistinct = Min(ndistinct, maxtuples); + + return (int) ndistinct; +} + +/* + * Examine the given index tuple (which contains partial status of a certain + * page range) by comparing it to the given value that comes from another heap + * tuple. If the new value is outside the bloom filter specified by the + * existing tuple values, update the index tuple and return true. Otherwise, + * return false and do not modify in this case. + */ +Datum +brin_bloom_add_value(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + Datum newval = PG_GETARG_DATUM(2); + bool isnull PG_USED_FOR_ASSERTS_ONLY = PG_GETARG_DATUM(3); + BloomOptions *opts = (BloomOptions *) PG_GET_OPCLASS_OPTIONS(); + Oid colloid = PG_GET_COLLATION(); + FmgrInfo *hashFn; + uint32 hashValue; + bool updated = false; + AttrNumber attno; + BloomFilter *filter; + + Assert(!isnull); + + attno = column->bv_attno; + + /* + * If this is the first non-null value, we need to initialize the bloom + * filter. Otherwise just extract the existing bloom filter from + * BrinValues. + */ + if (column->bv_allnulls) + { + filter = bloom_init(brin_bloom_get_ndistinct(bdesc, opts), + BloomGetFalsePositiveRate(opts)); + column->bv_values[0] = PointerGetDatum(filter); + column->bv_allnulls = false; + updated = true; + } + else + filter = (BloomFilter *) PG_DETOAST_DATUM(column->bv_values[0]); + + /* + * Compute the hash of the new value, using the supplied hash function, + * and then add the hash value to the bloom filter. + */ + hashFn = bloom_get_procinfo(bdesc, attno, PROCNUM_HASH); + + hashValue = DatumGetUInt32(FunctionCall1Coll(hashFn, colloid, newval)); + + filter = bloom_add_value(filter, hashValue, &updated); + + column->bv_values[0] = PointerGetDatum(filter); + + PG_RETURN_BOOL(updated); +} + +/* + * Given an index tuple corresponding to a certain page range and a scan key, + * return whether the scan key is consistent with the index tuple's bloom + * filter. Return true if so, false otherwise. + */ +Datum +brin_bloom_consistent(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + ScanKey *keys = (ScanKey *) PG_GETARG_POINTER(2); + int nkeys = PG_GETARG_INT32(3); + Oid colloid = PG_GET_COLLATION(); + AttrNumber attno; + Datum value; + Datum matches; + FmgrInfo *finfo; + uint32 hashValue; + BloomFilter *filter; + int keyno; + + filter = (BloomFilter *) PG_DETOAST_DATUM(column->bv_values[0]); + + Assert(filter); + + matches = true; + + for (keyno = 0; keyno < nkeys; keyno++) + { + ScanKey key = keys[keyno]; + + /* NULL keys are handled and filtered-out in bringetbitmap */ + Assert(!(key->sk_flags & SK_ISNULL)); + + attno = key->sk_attno; + value = key->sk_argument; + + switch (key->sk_strategy) + { + case BloomEqualStrategyNumber: + + /* + * In the equality case (WHERE col = someval), we want to + * return the current page range if the minimum value in the + * range <= scan key, and the maximum value >= scan key. + */ + finfo = bloom_get_procinfo(bdesc, attno, PROCNUM_HASH); + + hashValue = DatumGetUInt32(FunctionCall1Coll(finfo, colloid, value)); + matches &= bloom_contains_value(filter, hashValue); + + break; + default: + /* shouldn't happen */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + matches = 0; + break; + } + + if (!matches) + break; + } + + PG_RETURN_DATUM(matches); +} + +/* + * Given two BrinValues, update the first of them as a union of the summary + * values contained in both. The second one is untouched. + * + * XXX We assume the bloom filters have the same parameters for now. In the + * future we should have 'can union' function, to decide if we can combine + * two particular bloom filters. + */ +Datum +brin_bloom_union(PG_FUNCTION_ARGS) +{ + int i; + int nbytes; + BrinValues *col_a = (BrinValues *) PG_GETARG_POINTER(1); + BrinValues *col_b = (BrinValues *) PG_GETARG_POINTER(2); + BloomFilter *filter_a; + BloomFilter *filter_b; + + Assert(col_a->bv_attno == col_b->bv_attno); + Assert(!col_a->bv_allnulls && !col_b->bv_allnulls); + + filter_a = (BloomFilter *) PG_DETOAST_DATUM(col_a->bv_values[0]); + filter_b = (BloomFilter *) PG_DETOAST_DATUM(col_b->bv_values[0]); + + /* make sure the filters use the same parameters */ + Assert(filter_a && filter_b); + Assert(filter_a->nbits == filter_b->nbits); + Assert(filter_a->nhashes == filter_b->nhashes); + Assert((filter_a->nbits > 0) && (filter_a->nbits % 8 == 0)); + + nbytes = (filter_a->nbits) / 8; + + /* simply OR the bitmaps */ + for (i = 0; i < nbytes; i++) + filter_a->data[i] |= filter_b->data[i]; + + PG_RETURN_VOID(); +} + +/* + * Cache and return inclusion opclass support procedure + * + * Return the procedure corresponding to the given function support number + * or null if it does not exist. + */ +static FmgrInfo * +bloom_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum) +{ + BloomOpaque *opaque; + uint16 basenum = procnum - PROCNUM_BASE; + + /* + * We cache these in the opaque struct, to avoid repetitive syscache + * lookups. + */ + opaque = (BloomOpaque *) bdesc->bd_info[attno - 1]->oi_opaque; + + /* + * If we already searched for this proc and didn't find it, don't bother + * searching again. + */ + if (opaque->extra_proc_missing[basenum]) + return NULL; + + if (opaque->extra_procinfos[basenum].fn_oid == InvalidOid) + { + if (RegProcedureIsValid(index_getprocid(bdesc->bd_index, attno, + procnum))) + { + fmgr_info_copy(&opaque->extra_procinfos[basenum], + index_getprocinfo(bdesc->bd_index, attno, procnum), + bdesc->bd_context); + } + else + { + opaque->extra_proc_missing[basenum] = true; + return NULL; + } + } + + return &opaque->extra_procinfos[basenum]; +} + +Datum +brin_bloom_options(PG_FUNCTION_ARGS) +{ + local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + + init_local_reloptions(relopts, sizeof(BloomOptions)); + + add_local_real_reloption(relopts, "n_distinct_per_range", + "number of distinct items expected in a BRIN page range", + BLOOM_DEFAULT_NDISTINCT_PER_RANGE, + -1.0, INT_MAX, offsetof(BloomOptions, nDistinctPerRange)); + + add_local_real_reloption(relopts, "false_positive_rate", + "desired false-positive rate for the bloom filters", + BLOOM_DEFAULT_FALSE_POSITIVE_RATE, + BLOOM_MIN_FALSE_POSITIVE_RATE, + BLOOM_MAX_FALSE_POSITIVE_RATE, + offsetof(BloomOptions, falsePositiveRate)); + + PG_RETURN_VOID(); +} + +/* + * brin_bloom_summary_in + * - input routine for type brin_bloom_summary. + * + * brin_bloom_summary is only used internally to represent summaries + * in BRIN bloom indexes, so it has no operations of its own, and we + * disallow input too. + */ +Datum +brin_bloom_summary_in(PG_FUNCTION_ARGS) +{ + /* + * brin_bloom_summary stores the data in binary form and parsing text + * input is not needed, so disallow this. + */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type %s", "pg_brin_bloom_summary"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + + +/* + * brin_bloom_summary_out + * - output routine for type brin_bloom_summary. + * + * BRIN bloom summaries are serialized into a bytea value, but we want + * to output something nicer humans can understand. + */ +Datum +brin_bloom_summary_out(PG_FUNCTION_ARGS) +{ + BloomFilter *filter; + StringInfoData str; + + /* detoast the data to get value with a full 4B header */ + filter = (BloomFilter *) PG_DETOAST_DATUM(PG_GETARG_BYTEA_PP(0)); + + initStringInfo(&str); + appendStringInfoChar(&str, '{'); + + appendStringInfo(&str, "mode: hashed nhashes: %u nbits: %u nbits_set: %u", + filter->nhashes, filter->nbits, filter->nbits_set); + + appendStringInfoChar(&str, '}'); + + PG_RETURN_CSTRING(str.data); +} + +/* + * brin_bloom_summary_recv + * - binary input routine for type brin_bloom_summary. + */ +Datum +brin_bloom_summary_recv(PG_FUNCTION_ARGS) +{ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type %s", "pg_brin_bloom_summary"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + +/* + * brin_bloom_summary_send + * - binary output routine for type brin_bloom_summary. + * + * BRIN bloom summaries are serialized in a bytea value (although the + * type is named differently), so let's just send that. + */ +Datum +brin_bloom_summary_send(PG_FUNCTION_ARGS) +{ + return byteasend(fcinfo); +} diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c index 7e380d66ed57..0b384c0bd1ef 100644 --- a/src/backend/access/brin/brin_inclusion.c +++ b/src/backend/access/brin/brin_inclusion.c @@ -16,7 +16,7 @@ * writing is the INET type, where IPv6 values cannot be merged with IPv4 * values. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -108,6 +108,7 @@ brin_inclusion_opcinfo(PG_FUNCTION_ARGS) */ result = palloc0(MAXALIGN(SizeofBrinOpcInfo(3)) + sizeof(InclusionOpaque)); result->oi_nstored = 3; + result->oi_regular_nulls = true; result->oi_opaque = (InclusionOpaque *) MAXALIGN((char *) result + SizeofBrinOpcInfo(3)); @@ -139,7 +140,7 @@ brin_inclusion_add_value(PG_FUNCTION_ARGS) BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); Datum newval = PG_GETARG_DATUM(2); - bool isnull = PG_GETARG_BOOL(3); + bool isnull PG_USED_FOR_ASSERTS_ONLY = PG_GETARG_BOOL(3); Oid colloid = PG_GET_COLLATION(); FmgrInfo *finfo; Datum result; @@ -147,18 +148,7 @@ brin_inclusion_add_value(PG_FUNCTION_ARGS) AttrNumber attno; Form_pg_attribute attr; - /* - * If the new value is null, we record that we saw it if it's the first - * one; otherwise, there's nothing to do. - */ - if (isnull) - { - if (column->bv_hasnulls) - PG_RETURN_BOOL(false); - - column->bv_hasnulls = true; - PG_RETURN_BOOL(true); - } + Assert(!isnull); attno = column->bv_attno; attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1); @@ -251,6 +241,10 @@ brin_inclusion_add_value(PG_FUNCTION_ARGS) /* * BRIN inclusion consistent function * + * We're no longer dealing with NULL keys in the consistent function, that is + * now handled by the AM code. That means we should not get any all-NULL ranges + * either, because those can't be consistent with regular (not [IS] NULL) keys. + * * All of the strategies are optional. */ Datum @@ -267,35 +261,11 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS) FmgrInfo *finfo; Datum result; - Assert(key->sk_attno == column->bv_attno); - - /* Handle IS NULL/IS NOT NULL tests. */ - if (key->sk_flags & SK_ISNULL) - { - if (key->sk_flags & SK_SEARCHNULL) - { - if (column->bv_allnulls || column->bv_hasnulls) - PG_RETURN_BOOL(true); - PG_RETURN_BOOL(false); - } - - /* - * For IS NOT NULL, we can only skip ranges that are known to have - * only nulls. - */ - if (key->sk_flags & SK_SEARCHNOTNULL) - PG_RETURN_BOOL(!column->bv_allnulls); - - /* - * Neither IS NULL nor IS NOT NULL was used; assume all indexable - * operators are strict and return false. - */ - PG_RETURN_BOOL(false); - } + /* This opclass uses the old signature with only three arguments. */ + Assert(PG_NARGS() == 3); - /* If it is all nulls, it cannot possibly be consistent. */ - if (column->bv_allnulls) - PG_RETURN_BOOL(false); + /* Should not be dealing with all-NULL ranges. */ + Assert(!column->bv_allnulls); /* It has to be checked, if it contains elements that are not mergeable. */ if (DatumGetBool(column->bv_values[INCLUSION_UNMERGEABLE])) @@ -378,7 +348,6 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS) case RTOverlapStrategyNumber: case RTContainsStrategyNumber: - case RTOldContainsStrategyNumber: case RTContainsElemStrategyNumber: case RTSubStrategyNumber: case RTSubEqualStrategyNumber: @@ -399,7 +368,6 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS) */ case RTContainedByStrategyNumber: - case RTOldContainedByStrategyNumber: case RTSuperStrategyNumber: case RTSuperEqualStrategyNumber: finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype, @@ -516,37 +484,11 @@ brin_inclusion_union(PG_FUNCTION_ARGS) Datum result; Assert(col_a->bv_attno == col_b->bv_attno); - - /* Adjust "hasnulls". */ - if (!col_a->bv_hasnulls && col_b->bv_hasnulls) - col_a->bv_hasnulls = true; - - /* If there are no values in B, there's nothing left to do. */ - if (col_b->bv_allnulls) - PG_RETURN_VOID(); + Assert(!col_a->bv_allnulls && !col_b->bv_allnulls); attno = col_a->bv_attno; attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1); - /* - * Adjust "allnulls". If A doesn't have values, just copy the values from - * B into A, and we're done. We cannot run the operators in this case, - * because values in A might contain garbage. Note we already established - * that B contains values. - */ - if (col_a->bv_allnulls) - { - col_a->bv_allnulls = false; - col_a->bv_values[INCLUSION_UNION] = - datumCopy(col_b->bv_values[INCLUSION_UNION], - attr->attbyval, attr->attlen); - col_a->bv_values[INCLUSION_UNMERGEABLE] = - col_b->bv_values[INCLUSION_UNMERGEABLE]; - col_a->bv_values[INCLUSION_CONTAINS_EMPTY] = - col_b->bv_values[INCLUSION_CONTAINS_EMPTY]; - PG_RETURN_VOID(); - } - /* If B includes empty elements, mark A similarly, if needed. */ if (!DatumGetBool(col_a->bv_values[INCLUSION_CONTAINS_EMPTY]) && DatumGetBool(col_b->bv_values[INCLUSION_CONTAINS_EMPTY])) diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c index 4b5d6a721352..798f06c72220 100644 --- a/src/backend/access/brin/brin_minmax.c +++ b/src/backend/access/brin/brin_minmax.c @@ -2,7 +2,7 @@ * brin_minmax.c * Implementation of Min/Max opclass for BRIN * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -46,6 +46,7 @@ brin_minmax_opcinfo(PG_FUNCTION_ARGS) result = palloc0(MAXALIGN(SizeofBrinOpcInfo(2)) + sizeof(MinmaxOpaque)); result->oi_nstored = 2; + result->oi_regular_nulls = true; result->oi_opaque = (MinmaxOpaque *) MAXALIGN((char *) result + SizeofBrinOpcInfo(2)); result->oi_typcache[0] = result->oi_typcache[1] = @@ -67,7 +68,7 @@ brin_minmax_add_value(PG_FUNCTION_ARGS) BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); Datum newval = PG_GETARG_DATUM(2); - bool isnull = PG_GETARG_DATUM(3); + bool isnull PG_USED_FOR_ASSERTS_ONLY = PG_GETARG_DATUM(3); Oid colloid = PG_GET_COLLATION(); FmgrInfo *cmpFn; Datum compar; @@ -75,18 +76,7 @@ brin_minmax_add_value(PG_FUNCTION_ARGS) Form_pg_attribute attr; AttrNumber attno; - /* - * If the new value is null, we record that we saw it if it's the first - * one; otherwise, there's nothing to do. - */ - if (isnull) - { - if (column->bv_hasnulls) - PG_RETURN_BOOL(false); - - column->bv_hasnulls = true; - PG_RETURN_BOOL(true); - } + Assert(!isnull); attno = column->bv_attno; attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1); @@ -140,6 +130,10 @@ brin_minmax_add_value(PG_FUNCTION_ARGS) * Given an index tuple corresponding to a certain page range and a scan key, * return whether the scan key is consistent with the index tuple's min/max * values. Return true if so, false otherwise. + * + * We're no longer dealing with NULL keys in the consistent function, that is + * now handled by the AM code. That means we should not get any all-NULL ranges + * either, because those can't be consistent with regular (not [IS] NULL) keys. */ Datum brin_minmax_consistent(PG_FUNCTION_ARGS) @@ -154,35 +148,11 @@ brin_minmax_consistent(PG_FUNCTION_ARGS) Datum matches; FmgrInfo *finfo; - Assert(key->sk_attno == column->bv_attno); + /* This opclass uses the old signature with only three arguments. */ + Assert(PG_NARGS() == 3); - /* handle IS NULL/IS NOT NULL tests */ - if (key->sk_flags & SK_ISNULL) - { - if (key->sk_flags & SK_SEARCHNULL) - { - if (column->bv_allnulls || column->bv_hasnulls) - PG_RETURN_BOOL(true); - PG_RETURN_BOOL(false); - } - - /* - * For IS NOT NULL, we can only skip ranges that are known to have - * only nulls. - */ - if (key->sk_flags & SK_SEARCHNOTNULL) - PG_RETURN_BOOL(!column->bv_allnulls); - - /* - * Neither IS NULL nor IS NOT NULL was used; assume all indexable - * operators are strict and return false. - */ - PG_RETURN_BOOL(false); - } - - /* if the range is all empty, it cannot possibly be consistent */ - if (column->bv_allnulls) - PG_RETURN_BOOL(false); + /* Should not be dealing with all-NULL ranges. */ + Assert(!column->bv_allnulls); attno = key->sk_attno; subtype = key->sk_subtype; @@ -249,34 +219,11 @@ brin_minmax_union(PG_FUNCTION_ARGS) bool needsadj; Assert(col_a->bv_attno == col_b->bv_attno); - - /* Adjust "hasnulls" */ - if (!col_a->bv_hasnulls && col_b->bv_hasnulls) - col_a->bv_hasnulls = true; - - /* If there are no values in B, there's nothing left to do */ - if (col_b->bv_allnulls) - PG_RETURN_VOID(); + Assert(!col_a->bv_allnulls && !col_b->bv_allnulls); attno = col_a->bv_attno; attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1); - /* - * Adjust "allnulls". If A doesn't have values, just copy the values from - * B into A, and we're done. We cannot run the operators in this case, - * because values in A might contain garbage. Note we already established - * that B contains values. - */ - if (col_a->bv_allnulls) - { - col_a->bv_allnulls = false; - col_a->bv_values[0] = datumCopy(col_b->bv_values[0], - attr->attbyval, attr->attlen); - col_a->bv_values[1] = datumCopy(col_b->bv_values[1], - attr->attbyval, attr->attlen); - PG_RETURN_VOID(); - } - /* Adjust minimum, if B's min is less than A's min */ finfo = minmax_get_strategy_procinfo(bdesc, attno, attr->atttypid, BTLessStrategyNumber); diff --git a/src/backend/access/brin/brin_minmax_multi.c b/src/backend/access/brin/brin_minmax_multi.c new file mode 100644 index 000000000000..e3c98c2ffdac --- /dev/null +++ b/src/backend/access/brin/brin_minmax_multi.c @@ -0,0 +1,3146 @@ +/* + * brin_minmax_multi.c + * Implementation of Multi Min/Max opclass for BRIN + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * Implements a variant of minmax opclass, where the summary is composed of + * multiple smaller intervals. This allows us to handle outliers, which + * usually make the simple minmax opclass inefficient. + * + * Consider for example page range with simple minmax interval [1000,2000], + * and assume a new row gets inserted into the range with value 1000000. + * Due to that the interval gets [1000,1000000]. I.e. the minmax interval + * got 1000x wider and won't be useful to eliminate scan keys between 2001 + * and 1000000. + * + * With minmax-multi opclass, we may have [1000,2000] interval initially, + * but after adding the new row we start tracking it as two interval: + * + * [1000,2000] and [1000000,1000000] + * + * This allows us to still eliminate the page range when the scan keys hit + * the gap between 2000 and 1000000, making it useful in cases when the + * simple minmax opclass gets inefficient. + * + * The number of intervals tracked per page range is somewhat flexible. + * What is restricted is the number of values per page range, and the limit + * is currently 32 (see values_per_range reloption). Collapsed intervals + * (with equal minimum and maximum value) are stored as a single value, + * while regular intervals require two values. + * + * When the number of values gets too high (by adding new values to the + * summary), we merge some of the intervals to free space for more values. + * This is done in a greedy way - we simply pick the two closest intervals, + * merge them, and repeat this until the number of values to store gets + * sufficiently low (below 50% of maximum values), but that is mostly + * arbitrary threshold and may be changed easily). + * + * To pick the closest intervals we use the "distance" support procedure, + * which measures space between two ranges (i.e. the length of an interval). + * The computed value may be an approximation - in the worst case we will + * merge two ranges that are slightly less optimal at that step, but the + * index should still produce correct results. + * + * The compactions (reducing the number of values) is fairly expensive, as + * it requires calling the distance functions, sorting etc. So when building + * the summary, we use a significantly larger buffer, and only enforce the + * exact limit at the very end. This improves performance, and it also helps + * with building better ranges (due to the greedy approach). + * + * + * IDENTIFICATION + * src/backend/access/brin/brin_minmax_multi.c + */ +#include "postgres.h" + +/* needed for PGSQL_AF_INET */ +#include + +#include "access/genam.h" +#include "access/brin.h" +#include "access/brin_internal.h" +#include "access/brin_tuple.h" +#include "access/reloptions.h" +#include "access/stratnum.h" +#include "access/htup_details.h" +#include "catalog/pg_type.h" +#include "catalog/pg_am.h" +#include "catalog/pg_amop.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "utils/date.h" +#include "utils/datum.h" +#include "utils/inet.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/numeric.h" +#include "utils/pg_lsn.h" +#include "utils/rel.h" +#include "utils/syscache.h" +#include "utils/timestamp.h" +#include "utils/uuid.h" + +/* + * Additional SQL level support functions + * + * Procedure numbers must not use values reserved for BRIN itself; see + * brin_internal.h. + */ +#define MINMAX_MAX_PROCNUMS 1 /* maximum support procs we need */ +#define PROCNUM_DISTANCE 11 /* required, distance between values */ + +/* + * Subtract this from procnum to obtain index in MinmaxMultiOpaque arrays + * (Must be equal to minimum of private procnums). + */ +#define PROCNUM_BASE 11 + +/* + * Sizing the insert buffer - we use 10x the number of values specified + * in the reloption, but we cap it to 8192 not to get too large. When + * the buffer gets full, we reduce the number of values by half. + */ +#define MINMAX_BUFFER_FACTOR 10 +#define MINMAX_BUFFER_MIN 256 +#define MINMAX_BUFFER_MAX 8192 +#define MINMAX_BUFFER_LOAD_FACTOR 0.5 + +typedef struct MinmaxMultiOpaque +{ + FmgrInfo extra_procinfos[MINMAX_MAX_PROCNUMS]; + bool extra_proc_missing[MINMAX_MAX_PROCNUMS]; + Oid cached_subtype; + FmgrInfo strategy_procinfos[BTMaxStrategyNumber]; +} MinmaxMultiOpaque; + +/* + * Storage type for BRIN's minmax reloptions + */ +typedef struct MinMaxMultiOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int valuesPerRange; /* number of values per range */ +} MinMaxMultiOptions; + +#define MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE 32 + +#define MinMaxMultiGetValuesPerRange(opts) \ + ((opts) && (((MinMaxMultiOptions *) (opts))->valuesPerRange != 0) ? \ + ((MinMaxMultiOptions *) (opts))->valuesPerRange : \ + MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE) + +#define SAMESIGN(a,b) (((a) < 0) == ((b) < 0)) + +/* + * The summary of minmax-multi indexes has two representations - Ranges for + * convenient processing, and SerializedRanges for storage in bytea value. + * + * The Ranges struct stores the boundary values in a single array, but we + * treat regular and single-point ranges differently to save space. For + * regular ranges (with different boundary values) we have to store both + * values, while for "single-point ranges" we only need to save one value. + * + * The 'values' array stores boundary values for regular ranges first (there + * are 2*nranges values to store), and then the nvalues boundary values for + * single-point ranges. That is, we have (2*nranges + nvalues) boundary + * values in the array. + * + * +---------------------------------+-------------------------------+ + * | ranges (sorted pairs of values) | sorted values (single points) | + * +---------------------------------+-------------------------------+ + * + * This allows us to quickly add new values, and store outliers without + * making the other ranges very wide. + * + * We never store more than maxvalues values (as set by values_per_range + * reloption). If needed we merge some of the ranges. + * + * To minimize palloc overhead, we always allocate the full array with + * space for maxvalues elements. This should be fine as long as the + * maxvalues is reasonably small (64 seems fine), which is the case + * thanks to values_per_range reloption being limited to 256. + */ +typedef struct Ranges +{ + /* Cache information that we need quite often. */ + Oid typid; + Oid colloid; + AttrNumber attno; + FmgrInfo *cmp; + + /* (2*nranges + nvalues) <= maxvalues */ + int nranges; /* number of ranges in the array (stored) */ + int nsorted; /* number of sorted values (ranges + points) */ + int nvalues; /* number of values in the data array (all) */ + int maxvalues; /* maximum number of values (reloption) */ + + /* + * We simply add the values into a large buffer, without any expensive + * steps (sorting, deduplication, ...). The buffer is a multiple of the + * target number of values, so the compaction happens less often, + * amortizing the costs. We keep the actual target and compact to the + * requested number of values at the very end, before serializing to + * on-disk representation. + */ + /* requested number of values */ + int target_maxvalues; + + /* values stored for this range - either raw values, or ranges */ + Datum values[FLEXIBLE_ARRAY_MEMBER]; +} Ranges; + +/* + * On-disk the summary is stored as a bytea value, with a simple header + * with basic metadata, followed by the boundary values. It has a varlena + * header, so can be treated as varlena directly. + * + * See range_serialize/range_deserialize for serialization details. + */ +typedef struct SerializedRanges +{ + /* varlena header (do not touch directly!) */ + int32 vl_len_; + + /* type of values stored in the data array */ + Oid typid; + + /* (2*nranges + nvalues) <= maxvalues */ + int nranges; /* number of ranges in the array (stored) */ + int nvalues; /* number of values in the data array (all) */ + int maxvalues; /* maximum number of values (reloption) */ + + /* contains the actual data */ + char data[FLEXIBLE_ARRAY_MEMBER]; +} SerializedRanges; + +static SerializedRanges *range_serialize(Ranges *range); + +static Ranges *range_deserialize(int maxvalues, SerializedRanges *range); + + +/* + * Used to represent ranges expanded to make merging and combining easier. + * + * Each expanded range is essentially an interval, represented by min/max + * values, along with a flag whether it's a collapsed range (in which case + * the min and max values are equal). We have the flag to handle by-ref + * data types - we can't simply compare the datums, and this saves some + * calls to the type-specific comparator function. + */ +typedef struct ExpandedRange +{ + Datum minval; /* lower boundary */ + Datum maxval; /* upper boundary */ + bool collapsed; /* true if minval==maxval */ +} ExpandedRange; + +/* + * Represents a distance between two ranges (identified by index into + * an array of extended ranges). + */ +typedef struct DistanceValue +{ + int index; + double value; +} DistanceValue; + + +/* Cache for support and strategy procedures. */ + +static FmgrInfo *minmax_multi_get_procinfo(BrinDesc *bdesc, uint16 attno, + uint16 procnum); + +static FmgrInfo *minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, + uint16 attno, Oid subtype, + uint16 strategynum); + +typedef struct compare_context +{ + FmgrInfo *cmpFn; + Oid colloid; +} compare_context; + +static int compare_values(const void *a, const void *b, void *arg); + + +#ifdef USE_ASSERT_CHECKING +/* + * Check that the order of the array values is correct, using the cmp + * function (which should be BTLessStrategyNumber). + */ +static void +AssertArrayOrder(FmgrInfo *cmp, Oid colloid, Datum *values, int nvalues) +{ + int i; + Datum lt; + + for (i = 0; i < (nvalues - 1); i++) + { + lt = FunctionCall2Coll(cmp, colloid, values[i], values[i + 1]); + Assert(DatumGetBool(lt)); + } +} +#endif + +/* + * Comprehensive check of the Ranges structure. + */ +static void +AssertCheckRanges(Ranges *ranges, FmgrInfo *cmpFn, Oid colloid) +{ +#ifdef USE_ASSERT_CHECKING + int i; + + /* some basic sanity checks */ + Assert(ranges->nranges >= 0); + Assert(ranges->nsorted >= 0); + Assert(ranges->nvalues >= ranges->nsorted); + Assert(ranges->maxvalues >= 2 * ranges->nranges + ranges->nvalues); + Assert(ranges->typid != InvalidOid); + + /* + * First the ranges - there are 2*nranges boundary values, and the values + * have to be strictly ordered (equal values would mean the range is + * collapsed, and should be stored as a point). This also guarantees that + * the ranges do not overlap. + */ + AssertArrayOrder(cmpFn, colloid, ranges->values, 2 * ranges->nranges); + + /* then the single-point ranges (with nvalues boundar values ) */ + AssertArrayOrder(cmpFn, colloid, &ranges->values[2 * ranges->nranges], + ranges->nsorted); + + /* + * Check that none of the values are not covered by ranges (both sorted + * and unsorted) + */ + for (i = 0; i < ranges->nvalues; i++) + { + Datum compar; + int start, + end; + Datum minvalue, + maxvalue; + + Datum value = ranges->values[2 * ranges->nranges + i]; + + if (ranges->nranges == 0) + break; + + minvalue = ranges->values[0]; + maxvalue = ranges->values[2 * ranges->nranges - 1]; + + /* + * Is the value smaller than the minval? If yes, we'll recurse to the + * left side of range array. + */ + compar = FunctionCall2Coll(cmpFn, colloid, value, minvalue); + + /* smaller than the smallest value in the first range */ + if (DatumGetBool(compar)) + continue; + + /* + * Is the value greater than the maxval? If yes, we'll recurse to the + * right side of range array. + */ + compar = FunctionCall2Coll(cmpFn, colloid, maxvalue, value); + + /* larger than the largest value in the last range */ + if (DatumGetBool(compar)) + continue; + + start = 0; /* first range */ + end = ranges->nranges - 1; /* last range */ + while (true) + { + int midpoint = (start + end) / 2; + + /* this means we ran out of ranges in the last step */ + if (start > end) + break; + + /* copy the min/max values from the ranges */ + minvalue = ranges->values[2 * midpoint]; + maxvalue = ranges->values[2 * midpoint + 1]; + + /* + * Is the value smaller than the minval? If yes, we'll recurse to + * the left side of range array. + */ + compar = FunctionCall2Coll(cmpFn, colloid, value, minvalue); + + /* smaller than the smallest value in this range */ + if (DatumGetBool(compar)) + { + end = (midpoint - 1); + continue; + } + + /* + * Is the value greater than the minval? If yes, we'll recurse to + * the right side of range array. + */ + compar = FunctionCall2Coll(cmpFn, colloid, maxvalue, value); + + /* larger than the largest value in this range */ + if (DatumGetBool(compar)) + { + start = (midpoint + 1); + continue; + } + + /* hey, we found a matching range */ + Assert(false); + } + } + + /* and values in the unsorted part must not be in sorted part */ + for (i = ranges->nsorted; i < ranges->nvalues; i++) + { + compare_context cxt; + Datum value = ranges->values[2 * ranges->nranges + i]; + + if (ranges->nsorted == 0) + break; + + cxt.colloid = ranges->colloid; + cxt.cmpFn = ranges->cmp; + + Assert(bsearch_arg(&value, &ranges->values[2 * ranges->nranges], + ranges->nsorted, sizeof(Datum), + compare_values, (void *) &cxt) == NULL); + } +#endif +} + +/* + * Check that the expanded ranges (built when reducing the number of ranges + * by combining some of them) are correctly sorted and do not overlap. + */ +static void +AssertCheckExpandedRanges(BrinDesc *bdesc, Oid colloid, AttrNumber attno, + Form_pg_attribute attr, ExpandedRange *ranges, + int nranges) +{ +#ifdef USE_ASSERT_CHECKING + int i; + FmgrInfo *eq; + FmgrInfo *lt; + + eq = minmax_multi_get_strategy_procinfo(bdesc, attno, attr->atttypid, + BTEqualStrategyNumber); + + lt = minmax_multi_get_strategy_procinfo(bdesc, attno, attr->atttypid, + BTLessStrategyNumber); + + /* + * Each range independently should be valid, i.e. that for the boundary + * values (lower <= upper). + */ + for (i = 0; i < nranges; i++) + { + Datum r; + Datum minval = ranges[i].minval; + Datum maxval = ranges[i].maxval; + + if (ranges[i].collapsed) /* collapsed: minval == maxval */ + r = FunctionCall2Coll(eq, colloid, minval, maxval); + else /* non-collapsed: minval < maxval */ + r = FunctionCall2Coll(lt, colloid, minval, maxval); + + Assert(DatumGetBool(r)); + } + + /* + * And the ranges should be ordered and must not overlap, i.e. upper < + * lower for boundaries of consecutive ranges. + */ + for (i = 0; i < nranges - 1; i++) + { + Datum r; + Datum maxval = ranges[i].maxval; + Datum minval = ranges[i + 1].minval; + + r = FunctionCall2Coll(lt, colloid, maxval, minval); + + Assert(DatumGetBool(r)); + } +#endif +} + + +/* + * minmax_multi_init + * Initialize the deserialized range list, allocate all the memory. + * + * This is only in-memory representation of the ranges, so we allocate + * enough space for the maximum number of values (so as not to have to do + * repallocs as the ranges grow). + */ +static Ranges * +minmax_multi_init(int maxvalues) +{ + Size len; + Ranges *ranges; + + Assert(maxvalues > 0); + + len = offsetof(Ranges, values); /* fixed header */ + len += maxvalues * sizeof(Datum); /* Datum values */ + + ranges = (Ranges *) palloc0(len); + + ranges->maxvalues = maxvalues; + + return ranges; +} + + +/* + * range_deduplicate_values + * Deduplicate the part with values in the simple points. + * + * This is meant to be a cheaper way of reducing the size of the ranges. It + * does not touch the ranges, and only sorts the other values - it does not + * call the distance functions, which may be quite expensive, etc. + * + * We do know the values are not duplicate with the ranges, because we check + * that before adding a new value. Same for the sorted part of values. + */ +static void +range_deduplicate_values(Ranges *range) +{ + int i, + n; + int start; + compare_context cxt; + + /* + * If there are no unsorted values, we're done (this probably can't + * happen, as we're adding values to unsorted part). + */ + if (range->nsorted == range->nvalues) + return; + + /* sort the values */ + cxt.colloid = range->colloid; + cxt.cmpFn = range->cmp; + + /* the values start right after the ranges (which are always sorted) */ + start = 2 * range->nranges; + + /* + * XXX This might do a merge sort, to leverage that the first part of the + * array is already sorted. If the sorted part is large, it might be quite + * a bit faster. + */ + qsort_arg(&range->values[start], + range->nvalues, sizeof(Datum), + compare_values, (void *) &cxt); + + n = 1; + for (i = 1; i < range->nvalues; i++) + { + /* same as preceding value, so store it */ + if (compare_values(&range->values[start + i - 1], + &range->values[start + i], + (void *) &cxt) == 0) + continue; + + range->values[start + n] = range->values[start + i]; + + n++; + } + + /* now all the values are sorted */ + range->nvalues = n; + range->nsorted = n; + + AssertCheckRanges(range, range->cmp, range->colloid); +} + + +/* + * range_serialize + * Serialize the in-memory representation into a compact varlena value. + * + * Simply copy the header and then also the individual values, as stored + * in the in-memory value array. + */ +static SerializedRanges * +range_serialize(Ranges *range) +{ + Size len; + int nvalues; + SerializedRanges *serialized; + Oid typid; + int typlen; + bool typbyval; + + int i; + char *ptr; + + /* simple sanity checks */ + Assert(range->nranges >= 0); + Assert(range->nsorted >= 0); + Assert(range->nvalues >= 0); + Assert(range->maxvalues > 0); + Assert(range->target_maxvalues > 0); + + /* at this point the range should be compacted to the target size */ + Assert(2 * range->nranges + range->nvalues <= range->target_maxvalues); + + Assert(range->target_maxvalues <= range->maxvalues); + + /* range boundaries are always sorted */ + Assert(range->nvalues >= range->nsorted); + + /* deduplicate values, if there's unsorted part */ + range_deduplicate_values(range); + + /* see how many Datum values we actually have */ + nvalues = 2 * range->nranges + range->nvalues; + + typid = range->typid; + typbyval = get_typbyval(typid); + typlen = get_typlen(typid); + + /* header is always needed */ + len = offsetof(SerializedRanges, data); + + /* + * The space needed depends on data type - for fixed-length data types + * (by-value and some by-reference) it's pretty simple, just multiply + * (attlen * nvalues) and we're done. For variable-length by-reference + * types we need to actually walk all the values and sum the lengths. + */ + if (typlen == -1) /* varlena */ + { + int i; + + for (i = 0; i < nvalues; i++) + { + len += VARSIZE_ANY(range->values[i]); + } + } + else if (typlen == -2) /* cstring */ + { + int i; + + for (i = 0; i < nvalues; i++) + { + /* don't forget to include the null terminator ;-) */ + len += strlen(DatumGetCString(range->values[i])) + 1; + } + } + else /* fixed-length types (even by-reference) */ + { + Assert(typlen > 0); + len += nvalues * typlen; + } + + /* + * Allocate the serialized object, copy the basic information. The + * serialized object is a varlena, so update the header. + */ + serialized = (SerializedRanges *) palloc0(len); + SET_VARSIZE(serialized, len); + + serialized->typid = typid; + serialized->nranges = range->nranges; + serialized->nvalues = range->nvalues; + serialized->maxvalues = range->target_maxvalues; + + /* + * And now copy also the boundary values (like the length calculation this + * depends on the particular data type). + */ + ptr = serialized->data; /* start of the serialized data */ + + for (i = 0; i < nvalues; i++) + { + if (typbyval) /* simple by-value data types */ + { + Datum tmp; + + /* + * For byval types, we need to copy just the significant bytes - + * we can't use memcpy directly, as that assumes little-endian + * behavior. store_att_byval does almost what we need, but it + * requires a properly aligned buffer - the output buffer does not + * guarantee that. So we simply use a local Datum variable (which + * guarantees proper alignment), and then copy the value from it. + */ + store_att_byval(&tmp, range->values[i], typlen); + + memcpy(ptr, &tmp, typlen); + ptr += typlen; + } + else if (typlen > 0) /* fixed-length by-ref types */ + { + memcpy(ptr, DatumGetPointer(range->values[i]), typlen); + ptr += typlen; + } + else if (typlen == -1) /* varlena */ + { + int tmp = VARSIZE_ANY(DatumGetPointer(range->values[i])); + + memcpy(ptr, DatumGetPointer(range->values[i]), tmp); + ptr += tmp; + } + else if (typlen == -2) /* cstring */ + { + int tmp = strlen(DatumGetCString(range->values[i])) + 1; + + memcpy(ptr, DatumGetCString(range->values[i]), tmp); + ptr += tmp; + } + + /* make sure we haven't overflown the buffer end */ + Assert(ptr <= ((char *) serialized + len)); + } + + /* exact size */ + Assert(ptr == ((char *) serialized + len)); + + return serialized; +} + +/* + * range_deserialize + * Serialize the in-memory representation into a compact varlena value. + * + * Simply copy the header and then also the individual values, as stored + * in the in-memory value array. + */ +static Ranges * +range_deserialize(int maxvalues, SerializedRanges *serialized) +{ + int i, + nvalues; + char *ptr, + *dataptr; + bool typbyval; + int typlen; + Size datalen; + + Ranges *range; + + Assert(serialized->nranges >= 0); + Assert(serialized->nvalues >= 0); + Assert(serialized->maxvalues > 0); + + nvalues = 2 * serialized->nranges + serialized->nvalues; + + Assert(nvalues <= serialized->maxvalues); + Assert(serialized->maxvalues <= maxvalues); + + range = minmax_multi_init(maxvalues); + + /* copy the header info */ + range->nranges = serialized->nranges; + range->nvalues = serialized->nvalues; + range->nsorted = serialized->nvalues; + range->maxvalues = maxvalues; + range->target_maxvalues = serialized->maxvalues; + + range->typid = serialized->typid; + + typbyval = get_typbyval(serialized->typid); + typlen = get_typlen(serialized->typid); + + /* + * And now deconstruct the values into Datum array. We have to copy the + * data because the serialized representation ignores alignment, and we + * don't want to rely on it being kept around anyway. + */ + ptr = serialized->data; + + /* + * We don't want to allocate many pieces, so we just allocate everything + * in one chunk. How much space will we need? + * + * XXX We don't need to copy simple by-value data types. + */ + datalen = 0; + dataptr = NULL; + for (i = 0; (i < nvalues) && (!typbyval); i++) + { + if (typlen > 0) /* fixed-length by-ref types */ + datalen += MAXALIGN(typlen); + else if (typlen == -1) /* varlena */ + { + datalen += MAXALIGN(VARSIZE_ANY(DatumGetPointer(ptr))); + ptr += VARSIZE_ANY(DatumGetPointer(ptr)); + } + else if (typlen == -2) /* cstring */ + { + Size slen = strlen(DatumGetCString(ptr)) + 1; + + datalen += MAXALIGN(slen); + ptr += slen; + } + } + + if (datalen > 0) + dataptr = palloc(datalen); + + /* + * Restore the source pointer (might have been modified when calculating + * the space we need to allocate). + */ + ptr = serialized->data; + + for (i = 0; i < nvalues; i++) + { + if (typbyval) /* simple by-value data types */ + { + Datum v = 0; + + memcpy(&v, ptr, typlen); + + range->values[i] = fetch_att(&v, true, typlen); + ptr += typlen; + } + else if (typlen > 0) /* fixed-length by-ref types */ + { + range->values[i] = PointerGetDatum(dataptr); + + memcpy(dataptr, ptr, typlen); + dataptr += MAXALIGN(typlen); + + ptr += typlen; + } + else if (typlen == -1) /* varlena */ + { + range->values[i] = PointerGetDatum(dataptr); + + memcpy(dataptr, ptr, VARSIZE_ANY(ptr)); + dataptr += MAXALIGN(VARSIZE_ANY(ptr)); + ptr += VARSIZE_ANY(ptr); + } + else if (typlen == -2) /* cstring */ + { + Size slen = strlen(ptr) + 1; + + range->values[i] = PointerGetDatum(dataptr); + + memcpy(dataptr, ptr, slen); + dataptr += MAXALIGN(slen); + ptr += slen; + } + + /* make sure we haven't overflown the buffer end */ + Assert(ptr <= ((char *) serialized + VARSIZE_ANY(serialized))); + } + + /* should have consumed the whole input value exactly */ + Assert(ptr == ((char *) serialized + VARSIZE_ANY(serialized))); + + /* return the deserialized value */ + return range; +} + +/* + * compare_expanded_ranges + * Compare the expanded ranges - first by minimum, then by maximum. + * + * We do guarantee that ranges in a single Ranges object do not overlap, so it + * may seem strange that we don't order just by minimum. But when merging two + * Ranges (which happens in the union function), the ranges may in fact + * overlap. So we do compare both. + */ +static int +compare_expanded_ranges(const void *a, const void *b, void *arg) +{ + ExpandedRange *ra = (ExpandedRange *) a; + ExpandedRange *rb = (ExpandedRange *) b; + Datum r; + + compare_context *cxt = (compare_context *) arg; + + /* first compare minvals */ + r = FunctionCall2Coll(cxt->cmpFn, cxt->colloid, ra->minval, rb->minval); + + if (DatumGetBool(r)) + return -1; + + r = FunctionCall2Coll(cxt->cmpFn, cxt->colloid, rb->minval, ra->minval); + + if (DatumGetBool(r)) + return 1; + + /* then compare maxvals */ + r = FunctionCall2Coll(cxt->cmpFn, cxt->colloid, ra->maxval, rb->maxval); + + if (DatumGetBool(r)) + return -1; + + r = FunctionCall2Coll(cxt->cmpFn, cxt->colloid, rb->maxval, ra->maxval); + + if (DatumGetBool(r)) + return 1; + + return 0; +} + +/* + * compare_values + * Compare the values. + */ +static int +compare_values(const void *a, const void *b, void *arg) +{ + Datum *da = (Datum *) a; + Datum *db = (Datum *) b; + Datum r; + + compare_context *cxt = (compare_context *) arg; + + r = FunctionCall2Coll(cxt->cmpFn, cxt->colloid, *da, *db); + + if (DatumGetBool(r)) + return -1; + + r = FunctionCall2Coll(cxt->cmpFn, cxt->colloid, *db, *da); + + if (DatumGetBool(r)) + return 1; + + return 0; +} + +/* + * Check if the new value matches one of the existing ranges. + */ +static bool +has_matching_range(BrinDesc *bdesc, Oid colloid, Ranges *ranges, + Datum newval, AttrNumber attno, Oid typid) +{ + Datum compar; + + Datum minvalue = ranges->values[0]; + Datum maxvalue = ranges->values[2 * ranges->nranges - 1]; + + FmgrInfo *cmpLessFn; + FmgrInfo *cmpGreaterFn; + + /* binary search on ranges */ + int start, + end; + + if (ranges->nranges == 0) + return false; + + /* + * Otherwise, need to compare the new value with boundaries of all the + * ranges. First check if it's less than the absolute minimum, which is + * the first value in the array. + */ + cmpLessFn = minmax_multi_get_strategy_procinfo(bdesc, attno, typid, + BTLessStrategyNumber); + compar = FunctionCall2Coll(cmpLessFn, colloid, newval, minvalue); + + /* smaller than the smallest value in the range list */ + if (DatumGetBool(compar)) + return false; + + /* + * And now compare it to the existing maximum (last value in the data + * array). But only if we haven't already ruled out a possible match in + * the minvalue check. + */ + cmpGreaterFn = minmax_multi_get_strategy_procinfo(bdesc, attno, typid, + BTGreaterStrategyNumber); + compar = FunctionCall2Coll(cmpGreaterFn, colloid, newval, maxvalue); + + if (DatumGetBool(compar)) + return false; + + /* + * So we know it's in the general min/max, the question is whether it + * falls in one of the ranges or gaps. We'll do a binary search on + * individual ranges - for each range we check equality (value falls into + * the range), and then check ranges either above or below the current + * range. + */ + start = 0; /* first range */ + end = (ranges->nranges - 1); /* last range */ + while (true) + { + int midpoint = (start + end) / 2; + + /* this means we ran out of ranges in the last step */ + if (start > end) + return false; + + /* copy the min/max values from the ranges */ + minvalue = ranges->values[2 * midpoint]; + maxvalue = ranges->values[2 * midpoint + 1]; + + /* + * Is the value smaller than the minval? If yes, we'll recurse to the + * left side of range array. + */ + compar = FunctionCall2Coll(cmpLessFn, colloid, newval, minvalue); + + /* smaller than the smallest value in this range */ + if (DatumGetBool(compar)) + { + end = (midpoint - 1); + continue; + } + + /* + * Is the value greater than the minval? If yes, we'll recurse to the + * right side of range array. + */ + compar = FunctionCall2Coll(cmpGreaterFn, colloid, newval, maxvalue); + + /* larger than the largest value in this range */ + if (DatumGetBool(compar)) + { + start = (midpoint + 1); + continue; + } + + /* hey, we found a matching range */ + return true; + } + + return false; +} + + +/* + * range_contains_value + * See if the new value is already contained in the range list. + * + * We first inspect the list of intervals. We use a small trick - we check + * the value against min/max of the whole range (min of the first interval, + * max of the last one) first, and only inspect the individual intervals if + * this passes. + * + * If the value matches none of the intervals, we check the exact values. + * We simply loop through them and invoke equality operator on them. + * + * The last parameter (full) determines whether we need to search all the + * values, including the unsorted part. With full=false, the unsorted part + * is not searched, which may produce false negatives and duplicate values + * (in the unsorted part only), but when we're building the range that's + * fine - we'll deduplicate before serialization, and it can only happen + * if there already are unsorted values (so it was already modified). + * + * Serialized ranges don't have any unsorted values, so this can't cause + * false negatives during querying. + */ +static bool +range_contains_value(BrinDesc *bdesc, Oid colloid, + AttrNumber attno, Form_pg_attribute attr, + Ranges *ranges, Datum newval, bool full) +{ + int i; + FmgrInfo *cmpEqualFn; + Oid typid = attr->atttypid; + + /* + * First inspect the ranges, if there are any. We first check the whole + * range, and only when there's still a chance of getting a match we + * inspect the individual ranges. + */ + if (has_matching_range(bdesc, colloid, ranges, newval, attno, typid)) + return true; + + cmpEqualFn = minmax_multi_get_strategy_procinfo(bdesc, attno, typid, + BTEqualStrategyNumber); + + /* + * There is no matching range, so let's inspect the sorted values. + * + * We do a sequential search for small numbers of values, and binary + * search once we have more than 16 values. This threshold is somewhat + * arbitrary, as it depends on how expensive the comparison function is. + * + * XXX If we use the threshold here, maybe we should do the same thing in + * has_matching_range? Or maybe we should do the bin search all the time? + * + * XXX We could use the same optimization as for ranges, to check if the + * value is between min/max, to maybe rule out all sorted values without + * having to inspect all of them. + */ + if (ranges->nsorted >= 16) + { + compare_context cxt; + + cxt.colloid = ranges->colloid; + cxt.cmpFn = ranges->cmp; + + if (bsearch_arg(&newval, &ranges->values[2 * ranges->nranges], + ranges->nsorted, sizeof(Datum), + compare_values, (void *) &cxt) != NULL) + return true; + } + else + { + for (i = 2 * ranges->nranges; i < 2 * ranges->nranges + ranges->nsorted; i++) + { + Datum compar; + + compar = FunctionCall2Coll(cmpEqualFn, colloid, newval, ranges->values[i]); + + /* found an exact match */ + if (DatumGetBool(compar)) + return true; + } + } + + /* If not asked to inspect the unsorted part, we're done. */ + if (!full) + return false; + + /* Inspect the unsorted part. */ + for (i = 2 * ranges->nranges + ranges->nsorted; i < 2 * ranges->nranges + ranges->nvalues; i++) + { + Datum compar; + + compar = FunctionCall2Coll(cmpEqualFn, colloid, newval, ranges->values[i]); + + /* found an exact match */ + if (DatumGetBool(compar)) + return true; + } + + /* the value is not covered by this BRIN tuple */ + return false; +} + +/* + * Expand ranges from Ranges into ExpandedRange array. This expects the + * eranges to be pre-allocated and with the correct size - there needs to be + * (nranges + nvalues) elements. + * + * The order of expanded ranges is arbitrary. We do expand the ranges first, + * and this part is sorted. But then we expand the values, and this part may + * be unsorted. + */ +static void +fill_expanded_ranges(ExpandedRange *eranges, int neranges, Ranges *ranges) +{ + int idx; + int i; + + /* Check that the output array has the right size. */ + Assert(neranges == (ranges->nranges + ranges->nvalues)); + + idx = 0; + for (i = 0; i < ranges->nranges; i++) + { + eranges[idx].minval = ranges->values[2 * i]; + eranges[idx].maxval = ranges->values[2 * i + 1]; + eranges[idx].collapsed = false; + idx++; + + Assert(idx <= neranges); + } + + for (i = 0; i < ranges->nvalues; i++) + { + eranges[idx].minval = ranges->values[2 * ranges->nranges + i]; + eranges[idx].maxval = ranges->values[2 * ranges->nranges + i]; + eranges[idx].collapsed = true; + idx++; + + Assert(idx <= neranges); + } + + /* Did we produce the expected number of elements? */ + Assert(idx == neranges); + + return; +} + +/* + * Sort and deduplicate expanded ranges. + * + * The ranges may be deduplicated - we're simply appending values, without + * checking for duplicates etc. So maybe the deduplication will reduce the + * number of ranges enough, and we won't have to compute the distances etc. + * + * Returns the number of expanded ranges. + */ +static int +sort_expanded_ranges(FmgrInfo *cmp, Oid colloid, + ExpandedRange *eranges, int neranges) +{ + int n; + int i; + compare_context cxt; + + Assert(neranges > 0); + + /* sort the values */ + cxt.colloid = colloid; + cxt.cmpFn = cmp; + + /* + * XXX We do qsort on all the values, but we could also leverage the fact + * that some of the input data is already sorted (all the ranges and maybe + * some of the points) and do merge sort. + */ + qsort_arg(eranges, neranges, sizeof(ExpandedRange), + compare_expanded_ranges, (void *) &cxt); + + /* + * Deduplicate the ranges - simply compare each range to the preceding + * one, and skip the duplicate ones. + */ + n = 1; + for (i = 1; i < neranges; i++) + { + /* if the current range is equal to the preceding one, do nothing */ + if (!compare_expanded_ranges(&eranges[i - 1], &eranges[i], (void *) &cxt)) + continue; + + /* otherwise, copy it to n-th place (if not already there) */ + if (i != n) + memcpy(&eranges[n], &eranges[i], sizeof(ExpandedRange)); + + n++; + } + + Assert((n > 0) && (n <= neranges)); + + return n; +} + +/* + * When combining multiple Range values (in union function), some of the + * ranges may overlap. We simply merge the overlapping ranges to fix that. + * + * XXX This assumes the expanded ranges were previously sorted (by minval + * and then maxval). We leverage this when detecting overlap. + */ +static int +merge_overlapping_ranges(FmgrInfo *cmp, Oid colloid, + ExpandedRange *eranges, int neranges) +{ + int idx; + + /* Merge ranges (idx) and (idx+1) if they overlap. */ + idx = 0; + while (idx < (neranges - 1)) + { + Datum r; + + /* + * comparing [?,maxval] vs. [minval,?] - the ranges overlap if (minval + * < maxval) + */ + r = FunctionCall2Coll(cmp, colloid, + eranges[idx].maxval, + eranges[idx + 1].minval); + + /* + * Nope, maxval < minval, so no overlap. And we know the ranges are + * ordered, so there are no more overlaps, because all the remaining + * ranges have greater or equal minval. + */ + if (DatumGetBool(r)) + { + /* proceed to the next range */ + idx += 1; + continue; + } + + /* + * So ranges 'idx' and 'idx+1' do overlap, but we don't know if + * 'idx+1' is contained in 'idx', or if they overlap only partially. + * So compare the upper bounds and keep the larger one. + */ + r = FunctionCall2Coll(cmp, colloid, + eranges[idx].maxval, + eranges[idx + 1].maxval); + + if (DatumGetBool(r)) + eranges[idx].maxval = eranges[idx + 1].maxval; + + /* + * The range certainly is no longer collapsed (irrespectively of the + * previous state). + */ + eranges[idx].collapsed = false; + + /* + * Now get rid of the (idx+1) range entirely by shifting the remaining + * ranges by 1. There are neranges elements, and we need to move + * elements from (idx+2). That means the number of elements to move is + * [ncranges - (idx+2)]. + */ + memmove(&eranges[idx + 1], &eranges[idx + 2], + (neranges - (idx + 2)) * sizeof(ExpandedRange)); + + /* + * Decrease the number of ranges, and repeat (with the same range, as + * it might overlap with additional ranges thanks to the merge). + */ + neranges--; + } + + return neranges; +} + +/* + * Simple comparator for distance values, comparing the double value. + * This is intentionally sorting the distances in descending order, i.e. + * the longer gaps will be at the front. + */ +static int +compare_distances(const void *a, const void *b) +{ + DistanceValue *da = (DistanceValue *) a; + DistanceValue *db = (DistanceValue *) b; + + if (da->value < db->value) + return 1; + else if (da->value > db->value) + return -1; + + return 0; +} + +/* + * Given an array of expanded ranges, compute size of the gaps between each + * range. For neranges there are (neranges-1) gaps. + * + * We simply call the "distance" function to compute the (max-min) for pairs + * of consecutive ranges. The function may be fairly expensive, so we do that + * just once (and then use it to pick as many ranges to merge as possible). + * + * See reduce_expanded_ranges for details. + */ +static DistanceValue * +build_distances(FmgrInfo *distanceFn, Oid colloid, + ExpandedRange *eranges, int neranges) +{ + int i; + int ndistances; + DistanceValue *distances; + + Assert(neranges >= 2); + + ndistances = (neranges - 1); + distances = (DistanceValue *) palloc0(sizeof(DistanceValue) * ndistances); + + /* + * Walk through the ranges once and compute the distance between the + * ranges so that we can sort them once. + */ + for (i = 0; i < ndistances; i++) + { + Datum a1, + a2, + r; + + a1 = eranges[i].maxval; + a2 = eranges[i + 1].minval; + + /* compute length of the gap (between max/min) */ + r = FunctionCall2Coll(distanceFn, colloid, a1, a2); + + /* remember the index of the gap the distance is for */ + distances[i].index = i; + distances[i].value = DatumGetFloat8(r); + } + + /* + * Sort the distances in descending order, so that the longest gaps are at + * the front. + */ + pg_qsort(distances, ndistances, sizeof(DistanceValue), compare_distances); + + return distances; +} + +/* + * Builds expanded ranges for the existing ranges (and single-point ranges), + * and also the new value (which did not fit into the array). This expanded + * representation makes the processing a bit easier, as it allows handling + * ranges and points the same way. + * + * We sort and deduplicate the expanded ranges - this is necessary, because + * the points may be unsorted. And moreover the two parts (ranges and + * points) are sorted on their own. + */ +static ExpandedRange * +build_expanded_ranges(FmgrInfo *cmp, Oid colloid, Ranges *ranges, + int *nranges) +{ + int neranges; + ExpandedRange *eranges; + + /* both ranges and points are expanded into a separate element */ + neranges = ranges->nranges + ranges->nvalues; + + eranges = (ExpandedRange *) palloc0(neranges * sizeof(ExpandedRange)); + + /* fill the expanded ranges */ + fill_expanded_ranges(eranges, neranges, ranges); + + /* sort and deduplicate the expanded ranges */ + neranges = sort_expanded_ranges(cmp, colloid, eranges, neranges); + + /* remember how many ranges we built */ + *nranges = neranges; + + return eranges; +} + +#ifdef USE_ASSERT_CHECKING +/* + * Counts boundary values needed to store the ranges. Each single-point + * range is stored using a single value, each regular range needs two. + */ +static int +count_values(ExpandedRange *cranges, int ncranges) +{ + int i; + int count; + + count = 0; + for (i = 0; i < ncranges; i++) + { + if (cranges[i].collapsed) + count += 1; + else + count += 2; + } + + return count; +} +#endif + +/* + * reduce_expanded_ranges + * reduce the ranges until the number of values is low enough + * + * Combines ranges until the number of boundary values drops below the + * threshold specified by max_values. This happens by merging enough + * ranges by the distance between them. + * + * Returns the number of result ranges. + * + * We simply use the global min/max and then add boundaries for enough + * largest gaps. Each gap adds 2 values, so we simply use (target/2-1) + * distances. Then we simply sort all the values - each two values are + * a boundary of a range (possibly collapsed). + * + * XXX Some of the ranges may be collapsed (i.e. the min/max values are + * equal), but we ignore that for now. We could repeat the process, + * adding a couple more gaps recursively. + * + * XXX The ranges to merge are selected solely using the distance. But + * that may not be the best strategy, for example when multiple gaps + * are of equal (or very similar) length. + * + * Consider for example points 1, 2, 3, .., 64, which have gaps of the + * same length 1 of course. In that case, we tend to pick the first + * gap of that length, which leads to this: + * + * step 1: [1, 2], 3, 4, 5, .., 64 + * step 2: [1, 3], 4, 5, .., 64 + * step 3: [1, 4], 5, .., 64 + * ... + * + * So in the end we'll have one "large" range and multiple small points. + * That may be fine, but it seems a bit strange and non-optimal. Maybe + * we should consider other things when picking ranges to merge - e.g. + * length of the ranges? Or perhaps randomize the choice of ranges, with + * probability inversely proportional to the distance (the gap lengths + * may be very close, but not exactly the same). + * + * XXX Or maybe we could just handle this by using random value as a + * tie-break, or by adding random noise to the actual distance. + */ +static int +reduce_expanded_ranges(ExpandedRange *eranges, int neranges, + DistanceValue *distances, int max_values, + FmgrInfo *cmp, Oid colloid) +{ + int i; + int nvalues; + Datum *values; + + compare_context cxt; + + /* total number of gaps between ranges */ + int ndistances = (neranges - 1); + + /* number of gaps to keep */ + int keep = (max_values / 2 - 1); + + /* + * Maybe we have a sufficiently low number of ranges already? + * + * XXX This should happen before we actually do the expensive stuff like + * sorting, so maybe this should be just an assert. + */ + if (keep >= ndistances) + return neranges; + + /* sort the values */ + cxt.colloid = colloid; + cxt.cmpFn = cmp; + + /* allocate space for the boundary values */ + nvalues = 0; + values = (Datum *) palloc(sizeof(Datum) * max_values); + + /* add the global min/max values, from the first/last range */ + values[nvalues++] = eranges[0].minval; + values[nvalues++] = eranges[neranges - 1].maxval; + + /* add boundary values for enough gaps */ + for (i = 0; i < keep; i++) + { + /* index of the gap between (index) and (index+1) ranges */ + int index = distances[i].index; + + Assert((index >= 0) && ((index + 1) < neranges)); + + /* add max from the preceding range, minval from the next one */ + values[nvalues++] = eranges[index].maxval; + values[nvalues++] = eranges[index + 1].minval; + + Assert(nvalues <= max_values); + } + + /* We should have an even number of range values. */ + Assert(nvalues % 2 == 0); + + /* + * Sort the values using the comparator function, and form ranges from the + * sorted result. + */ + qsort_arg(values, nvalues, sizeof(Datum), + compare_values, (void *) &cxt); + + /* We have nvalues boundary values, which means nvalues/2 ranges. */ + for (i = 0; i < (nvalues / 2); i++) + { + eranges[i].minval = values[2 * i]; + eranges[i].maxval = values[2 * i + 1]; + + /* if the boundary values are the same, it's a collapsed range */ + eranges[i].collapsed = (compare_values(&values[2 * i], + &values[2 * i + 1], + &cxt) == 0); + } + + return (nvalues / 2); +} + +/* + * Store the boundary values from ExpandedRanges back into 'ranges' (using + * only the minimal number of values needed). + */ +static void +store_expanded_ranges(Ranges *ranges, ExpandedRange *eranges, int neranges) +{ + int i; + int idx = 0; + + /* first copy in the regular ranges */ + ranges->nranges = 0; + for (i = 0; i < neranges; i++) + { + if (!eranges[i].collapsed) + { + ranges->values[idx++] = eranges[i].minval; + ranges->values[idx++] = eranges[i].maxval; + ranges->nranges++; + } + } + + /* now copy in the collapsed ones */ + ranges->nvalues = 0; + for (i = 0; i < neranges; i++) + { + if (eranges[i].collapsed) + { + ranges->values[idx++] = eranges[i].minval; + ranges->nvalues++; + } + } + + /* all the values are sorted */ + ranges->nsorted = ranges->nvalues; + + Assert(count_values(eranges, neranges) == 2 * ranges->nranges + ranges->nvalues); + Assert(2 * ranges->nranges + ranges->nvalues <= ranges->maxvalues); +} + + +/* + * Consider freeing space in the ranges. Checks if there's space for at least + * one new value, and performs compaction if needed. + * + * Returns true if the value was actually modified. + */ +static bool +ensure_free_space_in_buffer(BrinDesc *bdesc, Oid colloid, + AttrNumber attno, Form_pg_attribute attr, + Ranges *range) +{ + MemoryContext ctx; + MemoryContext oldctx; + + FmgrInfo *cmpFn, + *distanceFn; + + /* expanded ranges */ + ExpandedRange *eranges; + int neranges; + DistanceValue *distances; + + /* + * If there is free space in the buffer, we're done without having to + * modify anything. + */ + if (2 * range->nranges + range->nvalues < range->maxvalues) + return false; + + /* we'll certainly need the comparator, so just look it up now */ + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, attr->atttypid, + BTLessStrategyNumber); + + /* deduplicate values, if there's an unsorted part */ + range_deduplicate_values(range); + + /* + * Did we reduce enough free space by just the deduplication? + * + * We don't simply check against range->maxvalues again. The deduplication + * might have freed very little space (e.g. just one value), forcing us to + * do deduplication very often. In that case, it's better to do the + * compaction and reduce more space. + */ + if (2 * range->nranges + range->nvalues <= range->maxvalues * MINMAX_BUFFER_LOAD_FACTOR) + return true; + + /* + * We need to combine some of the existing ranges, to reduce the number of + * values we have to store. + * + * The distanceFn calls (which may internally call e.g. numeric_le) may + * allocate quite a bit of memory, and we must not leak it (we might have + * to do this repeatedly, even for a single BRIN page range). Otherwise + * we'd have problems e.g. when building new indexes. So we use a memory + * context and make sure we free the memory at the end (so if we call the + * distance function many times, it might be an issue, but meh). + */ + ctx = AllocSetContextCreate(CurrentMemoryContext, + "minmax-multi context", + ALLOCSET_DEFAULT_SIZES); + + oldctx = MemoryContextSwitchTo(ctx); + + /* build the expanded ranges */ + eranges = build_expanded_ranges(cmpFn, colloid, range, &neranges); + + /* and we'll also need the 'distance' procedure */ + distanceFn = minmax_multi_get_procinfo(bdesc, attno, PROCNUM_DISTANCE); + + /* build array of gap distances and sort them in ascending order */ + distances = build_distances(distanceFn, colloid, eranges, neranges); + + /* + * Combine ranges until we release at least 50% of the space. This + * threshold is somewhat arbitrary, perhaps needs tuning. We must not use + * too low or high value. + */ + neranges = reduce_expanded_ranges(eranges, neranges, distances, + range->maxvalues * MINMAX_BUFFER_LOAD_FACTOR, + cmpFn, colloid); + + /* Make sure we've sufficiently reduced the number of ranges. */ + Assert(count_values(eranges, neranges) <= range->maxvalues * MINMAX_BUFFER_LOAD_FACTOR); + + /* decompose the expanded ranges into regular ranges and single values */ + store_expanded_ranges(range, eranges, neranges); + + MemoryContextSwitchTo(oldctx); + MemoryContextDelete(ctx); + + /* Did we break the ranges somehow? */ + AssertCheckRanges(range, cmpFn, colloid); + + return true; +} + +/* + * range_add_value + * Add the new value to the minmax-multi range. + */ +static bool +range_add_value(BrinDesc *bdesc, Oid colloid, + AttrNumber attno, Form_pg_attribute attr, + Ranges *ranges, Datum newval) +{ + FmgrInfo *cmpFn; + bool modified = false; + + /* we'll certainly need the comparator, so just look it up now */ + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, attr->atttypid, + BTLessStrategyNumber); + + /* comprehensive checks of the input ranges */ + AssertCheckRanges(ranges, cmpFn, colloid); + + /* + * Make sure there's enough free space in the buffer. We only trigger this + * when the buffer is full, which means it had to be modified as we size + * it to be larger than what is stored on disk. + * + * This needs to happen before we check if the value is contained in the + * range, because the value might be in the unsorted part, and we don't + * check that in range_contains_value. The deduplication would then move + * it to the sorted part, and we'd add the value too, which violates the + * rule that we never have duplicates with the ranges or sorted values. + * + * We might also deduplicate and recheck if the value is contained, but + * that seems like overkill. We'd need to deduplicate anyway, so why not + * do it now. + */ + modified = ensure_free_space_in_buffer(bdesc, colloid, + attno, attr, ranges); + + /* + * Bail out if the value already is covered by the range. + * + * We could also add values until we hit values_per_range, and then do the + * deduplication in a batch, hoping for better efficiency. But that would + * mean we actually modify the range every time, which means having to + * serialize the value, which does palloc, walks the values, copies them, + * etc. Not exactly cheap. + * + * So instead we do the check, which should be fairly cheap - assuming the + * comparator function is not very expensive. + * + * This also implies the values array can't contain duplicate values. + */ + if (range_contains_value(bdesc, colloid, attno, attr, ranges, newval, false)) + return modified; + + /* Make a copy of the value, if needed. */ + newval = datumCopy(newval, attr->attbyval, attr->attlen); + + /* + * If there's space in the values array, copy it in and we're done. + * + * We do want to keep the values sorted (to speed up searches), so we do a + * simple insertion sort. We could do something more elaborate, e.g. by + * sorting the values only now and then, but for small counts (e.g. when + * maxvalues is 64) this should be fine. + */ + ranges->values[2 * ranges->nranges + ranges->nvalues] = newval; + ranges->nvalues++; + + /* If we added the first value, we can consider it as sorted. */ + if (ranges->nvalues == 1) + ranges->nsorted = 1; + + /* + * Check we haven't broken the ordering of boundary values (checks both + * parts, but that doesn't hurt). + */ + AssertCheckRanges(ranges, cmpFn, colloid); + + /* Check the range contains the value we just added. */ + Assert(range_contains_value(bdesc, colloid, attno, attr, ranges, newval, true)); + + /* yep, we've modified the range */ + return true; +} + +/* + * Generate range representation of data collected during "batch mode". + * This is similar to reduce_expanded_ranges, except that we can't assume + * the values are sorted and there may be duplicate values. + */ +static void +compactify_ranges(BrinDesc *bdesc, Ranges *ranges, int max_values) +{ + FmgrInfo *cmpFn, + *distanceFn; + + /* expanded ranges */ + ExpandedRange *eranges; + int neranges; + DistanceValue *distances; + + MemoryContext ctx; + MemoryContext oldctx; + + /* + * Do we need to actually compactify anything? + * + * There are two reasons why compaction may be needed - firstly, there may + * be too many values, or some of the values may be unsorted. + */ + if ((ranges->nranges * 2 + ranges->nvalues <= max_values) && + (ranges->nsorted == ranges->nvalues)) + return; + + /* we'll certainly need the comparator, so just look it up now */ + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, ranges->attno, ranges->typid, + BTLessStrategyNumber); + + /* and we'll also need the 'distance' procedure */ + distanceFn = minmax_multi_get_procinfo(bdesc, ranges->attno, PROCNUM_DISTANCE); + + /* + * The distanceFn calls (which may internally call e.g. numeric_le) may + * allocate quite a bit of memory, and we must not leak it. Otherwise, + * we'd have problems e.g. when building indexes. So we create a local + * memory context and make sure we free the memory before leaving this + * function (not after every call). + */ + ctx = AllocSetContextCreate(CurrentMemoryContext, + "minmax-multi context", + ALLOCSET_DEFAULT_SIZES); + + oldctx = MemoryContextSwitchTo(ctx); + + /* build the expanded ranges */ + eranges = build_expanded_ranges(cmpFn, ranges->colloid, ranges, &neranges); + + /* build array of gap distances and sort them in ascending order */ + distances = build_distances(distanceFn, ranges->colloid, + eranges, neranges); + + /* + * Combine ranges until we get below max_values. We don't use any scale + * factor, because this is used during serialization, and we don't expect + * more tuples to be inserted anytime soon. + */ + neranges = reduce_expanded_ranges(eranges, neranges, distances, + max_values, cmpFn, ranges->colloid); + + Assert(count_values(eranges, neranges) <= max_values); + + /* transform back into regular ranges and single values */ + store_expanded_ranges(ranges, eranges, neranges); + + /* check all the range invariants */ + AssertCheckRanges(ranges, cmpFn, ranges->colloid); + + MemoryContextSwitchTo(oldctx); + MemoryContextDelete(ctx); +} + +Datum +brin_minmax_multi_opcinfo(PG_FUNCTION_ARGS) +{ + BrinOpcInfo *result; + + /* + * opaque->strategy_procinfos is initialized lazily; here it is set to + * all-uninitialized by palloc0 which sets fn_oid to InvalidOid. + */ + + result = palloc0(MAXALIGN(SizeofBrinOpcInfo(1)) + + sizeof(MinmaxMultiOpaque)); + result->oi_nstored = 1; + result->oi_regular_nulls = true; + result->oi_opaque = (MinmaxMultiOpaque *) + MAXALIGN((char *) result + SizeofBrinOpcInfo(1)); + result->oi_typcache[0] = lookup_type_cache(PG_BRIN_MINMAX_MULTI_SUMMARYOID, 0); + + PG_RETURN_POINTER(result); +} + +/* + * Compute the distance between two float4 values (plain subtraction). + */ +Datum +brin_minmax_multi_distance_float4(PG_FUNCTION_ARGS) +{ + float a1 = PG_GETARG_FLOAT4(0); + float a2 = PG_GETARG_FLOAT4(1); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(a1 <= a2); + + PG_RETURN_FLOAT8((double) a2 - (double) a1); +} + +/* + * Compute the distance between two float8 values (plain subtraction). + */ +Datum +brin_minmax_multi_distance_float8(PG_FUNCTION_ARGS) +{ + double a1 = PG_GETARG_FLOAT8(0); + double a2 = PG_GETARG_FLOAT8(1); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(a1 <= a2); + + PG_RETURN_FLOAT8(a2 - a1); +} + +/* + * Compute the distance between two int2 values (plain subtraction). + */ +Datum +brin_minmax_multi_distance_int2(PG_FUNCTION_ARGS) +{ + int16 a1 = PG_GETARG_INT16(0); + int16 a2 = PG_GETARG_INT16(1); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(a1 <= a2); + + PG_RETURN_FLOAT8((double) a2 - (double) a1); +} + +/* + * Compute the distance between two int4 values (plain subtraction). + */ +Datum +brin_minmax_multi_distance_int4(PG_FUNCTION_ARGS) +{ + int32 a1 = PG_GETARG_INT32(0); + int32 a2 = PG_GETARG_INT32(1); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(a1 <= a2); + + PG_RETURN_FLOAT8((double) a2 - (double) a1); +} + +/* + * Compute the distance between two int8 values (plain subtraction). + */ +Datum +brin_minmax_multi_distance_int8(PG_FUNCTION_ARGS) +{ + int64 a1 = PG_GETARG_INT64(0); + int64 a2 = PG_GETARG_INT64(1); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(a1 <= a2); + + PG_RETURN_FLOAT8((double) a2 - (double) a1); +} + +/* + * Compute the distance between two tid values (by mapping them to float8 and + * then subtracting them). + */ +Datum +brin_minmax_multi_distance_tid(PG_FUNCTION_ARGS) +{ + double da1, + da2; + + ItemPointer pa1 = (ItemPointer) PG_GETARG_DATUM(0); + ItemPointer pa2 = (ItemPointer) PG_GETARG_DATUM(1); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(ItemPointerCompare(pa1, pa2) <= 0); + + /* + * We use the no-check variants here, because user-supplied values may + * have (ip_posid == 0). See ItemPointerCompare. + */ + da1 = ItemPointerGetBlockNumberNoCheck(pa1) * MaxHeapTuplesPerPage + + ItemPointerGetOffsetNumberNoCheck(pa1); + + da2 = ItemPointerGetBlockNumberNoCheck(pa2) * MaxHeapTuplesPerPage + + ItemPointerGetOffsetNumberNoCheck(pa2); + + PG_RETURN_FLOAT8(da2 - da1); +} + +/* + * Compute the distance between two numeric values (plain subtraction). + */ +Datum +brin_minmax_multi_distance_numeric(PG_FUNCTION_ARGS) +{ + Datum d; + Datum a1 = PG_GETARG_DATUM(0); + Datum a2 = PG_GETARG_DATUM(1); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(DatumGetBool(DirectFunctionCall2(numeric_le, a1, a2))); + + d = DirectFunctionCall2(numeric_sub, a2, a1); /* a2 - a1 */ + + PG_RETURN_FLOAT8(DirectFunctionCall1(numeric_float8, d)); +} + +/* + * Compute the approximate distance between two UUID values. + * + * XXX We do not need a perfectly accurate value, so we approximate the + * deltas (which would have to be 128-bit integers) with a 64-bit float. + * The small inaccuracies do not matter in practice, in the worst case + * we'll decide to merge ranges that are not the closest ones. + */ +Datum +brin_minmax_multi_distance_uuid(PG_FUNCTION_ARGS) +{ + int i; + float8 delta = 0; + + Datum a1 = PG_GETARG_DATUM(0); + Datum a2 = PG_GETARG_DATUM(1); + + pg_uuid_t *u1 = DatumGetUUIDP(a1); + pg_uuid_t *u2 = DatumGetUUIDP(a2); + + /* + * We know the values are range boundaries, but the range may be collapsed + * (i.e. single points), with equal values. + */ + Assert(DatumGetBool(DirectFunctionCall2(uuid_le, a1, a2))); + + /* compute approximate delta as a double precision value */ + for (i = UUID_LEN - 1; i >= 0; i--) + { + delta += (int) u2->data[i] - (int) u1->data[i]; + delta /= 256; + } + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the approximate distance between two dates. + */ +Datum +brin_minmax_multi_distance_date(PG_FUNCTION_ARGS) +{ + DateADT dateVal1 = PG_GETARG_DATEADT(0); + DateADT dateVal2 = PG_GETARG_DATEADT(1); + + if (DATE_NOT_FINITE(dateVal1) || DATE_NOT_FINITE(dateVal2)) + PG_RETURN_FLOAT8(0); + + PG_RETURN_FLOAT8(dateVal1 - dateVal2); +} + +/* + * Compute the approximate distance between two time (without tz) values. + * + * TimeADT is just an int64, so we simply subtract the values directly. + */ +Datum +brin_minmax_multi_distance_time(PG_FUNCTION_ARGS) +{ + float8 delta = 0; + + TimeADT ta = PG_GETARG_TIMEADT(0); + TimeADT tb = PG_GETARG_TIMEADT(1); + + delta = (tb - ta); + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the approximate distance between two timetz values. + * + * Simply subtracts the TimeADT (int64) values embedded in TimeTzADT. + */ +Datum +brin_minmax_multi_distance_timetz(PG_FUNCTION_ARGS) +{ + float8 delta = 0; + + TimeTzADT *ta = PG_GETARG_TIMETZADT_P(0); + TimeTzADT *tb = PG_GETARG_TIMETZADT_P(1); + + delta = (tb->time - ta->time) + (tb->zone - ta->zone) * USECS_PER_SEC; + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the distance between two timestamp values. + */ +Datum +brin_minmax_multi_distance_timestamp(PG_FUNCTION_ARGS) +{ + float8 delta = 0; + + Timestamp dt1 = PG_GETARG_TIMESTAMP(0); + Timestamp dt2 = PG_GETARG_TIMESTAMP(1); + + if (TIMESTAMP_NOT_FINITE(dt1) || TIMESTAMP_NOT_FINITE(dt2)) + PG_RETURN_FLOAT8(0); + + delta = dt2 - dt1; + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the distance between two interval values. + */ +Datum +brin_minmax_multi_distance_interval(PG_FUNCTION_ARGS) +{ + float8 delta = 0; + + Interval *ia = PG_GETARG_INTERVAL_P(0); + Interval *ib = PG_GETARG_INTERVAL_P(1); + Interval *result; + + int64 dayfraction; + int64 days; + + result = (Interval *) palloc(sizeof(Interval)); + + result->month = ib->month - ia->month; + /* overflow check copied from int4mi */ + if (!SAMESIGN(ib->month, ia->month) && + !SAMESIGN(result->month, ib->month)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("interval out of range"))); + + result->day = ib->day - ia->day; + if (!SAMESIGN(ib->day, ia->day) && + !SAMESIGN(result->day, ib->day)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("interval out of range"))); + + result->time = ib->time - ia->time; + if (!SAMESIGN(ib->time, ia->time) && + !SAMESIGN(result->time, ib->time)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("interval out of range"))); + + /* + * Delta is (fractional) number of days between the intervals. Assume + * months have 30 days for consistency with interval_cmp_internal. We + * don't need to be exact, in the worst case we'll build a bit less + * efficient ranges. But we should not contradict interval_cmp. + */ + dayfraction = result->time % USECS_PER_DAY; + days = result->time / USECS_PER_DAY; + days += result->month * INT64CONST(30); + days += result->day; + + /* convert to double precision */ + delta = (double) days + dayfraction / (double) USECS_PER_DAY; + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the distance between two pg_lsn values. + * + * LSN is just an int64 encoding position in the stream, so just subtract + * those int64 values directly. + */ +Datum +brin_minmax_multi_distance_pg_lsn(PG_FUNCTION_ARGS) +{ + float8 delta = 0; + + XLogRecPtr lsna = PG_GETARG_LSN(0); + XLogRecPtr lsnb = PG_GETARG_LSN(1); + + delta = (lsnb - lsna); + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the distance between two macaddr values. + * + * mac addresses are treated as 6 unsigned chars, so do the same thing we + * already do for UUID values. + */ +Datum +brin_minmax_multi_distance_macaddr(PG_FUNCTION_ARGS) +{ + float8 delta; + + macaddr *a = PG_GETARG_MACADDR_P(0); + macaddr *b = PG_GETARG_MACADDR_P(1); + + delta = ((float8) b->f - (float8) a->f); + delta /= 256; + + delta += ((float8) b->e - (float8) a->e); + delta /= 256; + + delta += ((float8) b->d - (float8) a->d); + delta /= 256; + + delta += ((float8) b->c - (float8) a->c); + delta /= 256; + + delta += ((float8) b->b - (float8) a->b); + delta /= 256; + + delta += ((float8) b->a - (float8) a->a); + delta /= 256; + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the distance between two macaddr8 values. + * + * macaddr8 addresses are 8 unsigned chars, so do the same thing we + * already do for UUID values. + */ +Datum +brin_minmax_multi_distance_macaddr8(PG_FUNCTION_ARGS) +{ + float8 delta; + + macaddr8 *a = PG_GETARG_MACADDR8_P(0); + macaddr8 *b = PG_GETARG_MACADDR8_P(1); + + delta = ((float8) b->h - (float8) a->h); + delta /= 256; + + delta += ((float8) b->g - (float8) a->g); + delta /= 256; + + delta += ((float8) b->f - (float8) a->f); + delta /= 256; + + delta += ((float8) b->e - (float8) a->e); + delta /= 256; + + delta += ((float8) b->d - (float8) a->d); + delta /= 256; + + delta += ((float8) b->c - (float8) a->c); + delta /= 256; + + delta += ((float8) b->b - (float8) a->b); + delta /= 256; + + delta += ((float8) b->a - (float8) a->a); + delta /= 256; + + Assert(delta >= 0); + + PG_RETURN_FLOAT8(delta); +} + +/* + * Compute the distance between two inet values. + * + * The distance is defined as the difference between 32-bit/128-bit values, + * depending on the IP version. The distance is computed by subtracting + * the bytes and normalizing it to [0,1] range for each IP family. + * Addresses from different families are considered to be in maximum + * distance, which is 1.0. + * + * XXX Does this need to consider the mask (bits)? For now, it's ignored. + */ +Datum +brin_minmax_multi_distance_inet(PG_FUNCTION_ARGS) +{ + float8 delta; + int i; + int len; + unsigned char *addra, + *addrb; + + inet *ipa = PG_GETARG_INET_PP(0); + inet *ipb = PG_GETARG_INET_PP(1); + + int lena, + lenb; + + /* + * If the addresses are from different families, consider them to be in + * maximal possible distance (which is 1.0). + */ + if (ip_family(ipa) != ip_family(ipb)) + PG_RETURN_FLOAT8(1.0); + + addra = (unsigned char *) palloc(ip_addrsize(ipa)); + memcpy(addra, ip_addr(ipa), ip_addrsize(ipa)); + + addrb = (unsigned char *) palloc(ip_addrsize(ipb)); + memcpy(addrb, ip_addr(ipb), ip_addrsize(ipb)); + + /* + * The length is calculated from the mask length, because we sort the + * addresses by first address in the range, so A.B.C.D/24 < A.B.C.1 (the + * first range starts at A.B.C.0, which is before A.B.C.1). We don't want + * to produce a negative delta in this case, so we just cut the extra + * bytes. + * + * XXX Maybe this should be a bit more careful and cut the bits, not just + * whole bytes. + */ + lena = ip_bits(ipa); + lenb = ip_bits(ipb); + + len = ip_addrsize(ipa); + + /* apply the network mask to both addresses */ + for (i = 0; i < len; i++) + { + unsigned char mask; + int nbits; + + nbits = lena - (i * 8); + if (nbits < 8) + { + mask = (0xFF << (8 - nbits)); + addra[i] = (addra[i] & mask); + } + + nbits = lenb - (i * 8); + if (nbits < 8) + { + mask = (0xFF << (8 - nbits)); + addrb[i] = (addrb[i] & mask); + } + } + + /* Calculate the difference between the addresses. */ + delta = 0; + for (i = len - 1; i >= 0; i--) + { + unsigned char a = addra[i]; + unsigned char b = addrb[i]; + + delta += (float8) b - (float8) a; + delta /= 256; + } + + Assert((delta >= 0) && (delta <= 1)); + + pfree(addra); + pfree(addrb); + + PG_RETURN_FLOAT8(delta); +} + +static void +brin_minmax_multi_serialize(BrinDesc *bdesc, Datum src, Datum *dst) +{ + Ranges *ranges = (Ranges *) DatumGetPointer(src); + SerializedRanges *s; + + /* + * In batch mode, we need to compress the accumulated values to the + * actually requested number of values/ranges. + */ + compactify_ranges(bdesc, ranges, ranges->target_maxvalues); + + /* At this point everything has to be fully sorted. */ + Assert(ranges->nsorted == ranges->nvalues); + + s = range_serialize(ranges); + dst[0] = PointerGetDatum(s); +} + +static int +brin_minmax_multi_get_values(BrinDesc *bdesc, MinMaxMultiOptions *opts) +{ + return MinMaxMultiGetValuesPerRange(opts); +} + +/* + * Examine the given index tuple (which contains the partial status of a + * certain page range) by comparing it to the given value that comes from + * another heap tuple. If the new value is outside the min/max range + * specified by the existing tuple values, update the index tuple and return + * true. Otherwise, return false and do not modify in this case. + */ +Datum +brin_minmax_multi_add_value(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + Datum newval = PG_GETARG_DATUM(2); + bool isnull PG_USED_FOR_ASSERTS_ONLY = PG_GETARG_DATUM(3); + MinMaxMultiOptions *opts = (MinMaxMultiOptions *) PG_GET_OPCLASS_OPTIONS(); + Oid colloid = PG_GET_COLLATION(); + bool modified = false; + Form_pg_attribute attr; + AttrNumber attno; + Ranges *ranges; + SerializedRanges *serialized = NULL; + + Assert(!isnull); + + attno = column->bv_attno; + attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1); + + /* use the already deserialized value, if possible */ + ranges = (Ranges *) DatumGetPointer(column->bv_mem_value); + + /* + * If this is the first non-null value, we need to initialize the range + * list. Otherwise, just extract the existing range list from BrinValues. + * + * When starting with an empty range, we assume this is a batch mode and + * we use a larger buffer. The buffer size is derived from the BRIN range + * size, number of rows per page, with some sensible min/max values. A + * small buffer would be bad for performance, but a large buffer might + * require a lot of memory (because of keeping all the values). + */ + if (column->bv_allnulls) + { + MemoryContext oldctx; + + int target_maxvalues; + int maxvalues; + BlockNumber pagesPerRange = BrinGetPagesPerRange(bdesc->bd_index); + + /* what was specified as a reloption? */ + target_maxvalues = brin_minmax_multi_get_values(bdesc, opts); + + /* + * Determine the insert buffer size - we use 10x the target, capped to + * the maximum number of values in the heap range. This is more than + * enough, considering the actual number of rows per page is likely + * much lower, but meh. + */ + maxvalues = Min(target_maxvalues * MINMAX_BUFFER_FACTOR, + MaxHeapTuplesPerPage * pagesPerRange); + + /* but always at least the original value */ + maxvalues = Max(maxvalues, target_maxvalues); + + /* always cap by MIN/MAX */ + maxvalues = Max(maxvalues, MINMAX_BUFFER_MIN); + maxvalues = Min(maxvalues, MINMAX_BUFFER_MAX); + + oldctx = MemoryContextSwitchTo(column->bv_context); + ranges = minmax_multi_init(maxvalues); + ranges->attno = attno; + ranges->colloid = colloid; + ranges->typid = attr->atttypid; + ranges->target_maxvalues = target_maxvalues; + + /* we'll certainly need the comparator, so just look it up now */ + ranges->cmp = minmax_multi_get_strategy_procinfo(bdesc, attno, attr->atttypid, + BTLessStrategyNumber); + + MemoryContextSwitchTo(oldctx); + + column->bv_allnulls = false; + modified = true; + + column->bv_mem_value = PointerGetDatum(ranges); + column->bv_serialize = brin_minmax_multi_serialize; + } + else if (!ranges) + { + MemoryContext oldctx; + + int maxvalues; + BlockNumber pagesPerRange = BrinGetPagesPerRange(bdesc->bd_index); + + oldctx = MemoryContextSwitchTo(column->bv_context); + + serialized = (SerializedRanges *) PG_DETOAST_DATUM(column->bv_values[0]); + + /* + * Determine the insert buffer size - we use 10x the target, capped to + * the maximum number of values in the heap range. This is more than + * enough, considering the actual number of rows per page is likely + * much lower, but meh. + */ + maxvalues = Min(serialized->maxvalues * MINMAX_BUFFER_FACTOR, + MaxHeapTuplesPerPage * pagesPerRange); + + /* but always at least the original value */ + maxvalues = Max(maxvalues, serialized->maxvalues); + + /* always cap by MIN/MAX */ + maxvalues = Max(maxvalues, MINMAX_BUFFER_MIN); + maxvalues = Min(maxvalues, MINMAX_BUFFER_MAX); + + ranges = range_deserialize(maxvalues, serialized); + + ranges->attno = attno; + ranges->colloid = colloid; + ranges->typid = attr->atttypid; + + /* we'll certainly need the comparator, so just look it up now */ + ranges->cmp = minmax_multi_get_strategy_procinfo(bdesc, attno, attr->atttypid, + BTLessStrategyNumber); + + column->bv_mem_value = PointerGetDatum(ranges); + column->bv_serialize = brin_minmax_multi_serialize; + + MemoryContextSwitchTo(oldctx); + } + + /* + * Try to add the new value to the range. We need to update the modified + * flag, so that we serialize the updated summary later. + */ + modified |= range_add_value(bdesc, colloid, attno, attr, ranges, newval); + + + PG_RETURN_BOOL(modified); +} + +/* + * Given an index tuple corresponding to a certain page range and a scan key, + * return whether the scan key is consistent with the index tuple's min/max + * values. Return true if so, false otherwise. + */ +Datum +brin_minmax_multi_consistent(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + ScanKey *keys = (ScanKey *) PG_GETARG_POINTER(2); + int nkeys = PG_GETARG_INT32(3); + + Oid colloid = PG_GET_COLLATION(), + subtype; + AttrNumber attno; + Datum value; + FmgrInfo *finfo; + SerializedRanges *serialized; + Ranges *ranges; + int keyno; + int rangeno; + int i; + + attno = column->bv_attno; + + serialized = (SerializedRanges *) PG_DETOAST_DATUM(column->bv_values[0]); + ranges = range_deserialize(serialized->maxvalues, serialized); + + /* inspect the ranges, and for each one evaluate the scan keys */ + for (rangeno = 0; rangeno < ranges->nranges; rangeno++) + { + Datum minval = ranges->values[2 * rangeno]; + Datum maxval = ranges->values[2 * rangeno + 1]; + + /* assume the range is matching, and we'll try to prove otherwise */ + bool matching = true; + + for (keyno = 0; keyno < nkeys; keyno++) + { + Datum matches; + ScanKey key = keys[keyno]; + + /* NULL keys are handled and filtered-out in bringetbitmap */ + Assert(!(key->sk_flags & SK_ISNULL)); + + attno = key->sk_attno; + subtype = key->sk_subtype; + value = key->sk_argument; + switch (key->sk_strategy) + { + case BTLessStrategyNumber: + case BTLessEqualStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* first value from the array */ + matches = FunctionCall2Coll(finfo, colloid, minval, value); + break; + + case BTEqualStrategyNumber: + { + Datum compar; + FmgrInfo *cmpFn; + + /* by default this range does not match */ + matches = false; + + /* + * Otherwise, need to compare the new value with + * boundaries of all the ranges. First check if it's + * less than the absolute minimum, which is the first + * value in the array. + */ + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTGreaterStrategyNumber); + compar = FunctionCall2Coll(cmpFn, colloid, minval, value); + + /* smaller than the smallest value in this range */ + if (DatumGetBool(compar)) + break; + + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + BTLessStrategyNumber); + compar = FunctionCall2Coll(cmpFn, colloid, maxval, value); + + /* larger than the largest value in this range */ + if (DatumGetBool(compar)) + break; + + /* + * We haven't managed to eliminate this range, so + * consider it matching. + */ + matches = true; + + break; + } + case BTGreaterEqualStrategyNumber: + case BTGreaterStrategyNumber: + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + /* last value from the array */ + matches = FunctionCall2Coll(finfo, colloid, maxval, value); + break; + + default: + /* shouldn't happen */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + matches = 0; + break; + } + + /* the range has to match all the scan keys */ + matching &= DatumGetBool(matches); + + /* once we find a non-matching key, we're done */ + if (!matching) + break; + } + + /* + * have we found a range matching all scan keys? if yes, we're done + */ + if (matching) + PG_RETURN_DATUM(BoolGetDatum(true)); + } + + /* + * And now inspect the values. We don't bother with doing a binary search + * here, because we're dealing with serialized / fully compacted ranges, + * so there should be only very few values. + */ + for (i = 0; i < ranges->nvalues; i++) + { + Datum val = ranges->values[2 * ranges->nranges + i]; + + /* assume the range is matching, and we'll try to prove otherwise */ + bool matching = true; + + for (keyno = 0; keyno < nkeys; keyno++) + { + Datum matches; + ScanKey key = keys[keyno]; + + /* we've already dealt with NULL keys at the beginning */ + if (key->sk_flags & SK_ISNULL) + continue; + + attno = key->sk_attno; + subtype = key->sk_subtype; + value = key->sk_argument; + switch (key->sk_strategy) + { + case BTLessStrategyNumber: + case BTLessEqualStrategyNumber: + case BTEqualStrategyNumber: + case BTGreaterEqualStrategyNumber: + case BTGreaterStrategyNumber: + + finfo = minmax_multi_get_strategy_procinfo(bdesc, attno, subtype, + key->sk_strategy); + matches = FunctionCall2Coll(finfo, colloid, val, value); + break; + + default: + /* shouldn't happen */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + matches = 0; + break; + } + + /* the range has to match all the scan keys */ + matching &= DatumGetBool(matches); + + /* once we find a non-matching key, we're done */ + if (!matching) + break; + } + + /* have we found a range matching all scan keys? if yes, we're done */ + if (matching) + PG_RETURN_DATUM(BoolGetDatum(true)); + } + + PG_RETURN_DATUM(BoolGetDatum(false)); +} + +/* + * Given two BrinValues, update the first of them as a union of the summary + * values contained in both. The second one is untouched. + */ +Datum +brin_minmax_multi_union(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *col_a = (BrinValues *) PG_GETARG_POINTER(1); + BrinValues *col_b = (BrinValues *) PG_GETARG_POINTER(2); + + Oid colloid = PG_GET_COLLATION(); + SerializedRanges *serialized_a; + SerializedRanges *serialized_b; + Ranges *ranges_a; + Ranges *ranges_b; + AttrNumber attno; + Form_pg_attribute attr; + ExpandedRange *eranges; + int neranges; + FmgrInfo *cmpFn, + *distanceFn; + DistanceValue *distances; + MemoryContext ctx; + MemoryContext oldctx; + + Assert(col_a->bv_attno == col_b->bv_attno); + Assert(!col_a->bv_allnulls && !col_b->bv_allnulls); + + attno = col_a->bv_attno; + attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1); + + serialized_a = (SerializedRanges *) PG_DETOAST_DATUM(col_a->bv_values[0]); + serialized_b = (SerializedRanges *) PG_DETOAST_DATUM(col_b->bv_values[0]); + + ranges_a = range_deserialize(serialized_a->maxvalues, serialized_a); + ranges_b = range_deserialize(serialized_b->maxvalues, serialized_b); + + /* make sure neither of the ranges is NULL */ + Assert(ranges_a && ranges_b); + + neranges = (ranges_a->nranges + ranges_a->nvalues) + + (ranges_b->nranges + ranges_b->nvalues); + + /* + * The distanceFn calls (which may internally call e.g. numeric_le) may + * allocate quite a bit of memory, and we must not leak it. Otherwise, + * we'd have problems e.g. when building indexes. So we create a local + * memory context and make sure we free the memory before leaving this + * function (not after every call). + */ + ctx = AllocSetContextCreate(CurrentMemoryContext, + "minmax-multi context", + ALLOCSET_DEFAULT_SIZES); + + oldctx = MemoryContextSwitchTo(ctx); + + /* allocate and fill */ + eranges = (ExpandedRange *) palloc0(neranges * sizeof(ExpandedRange)); + + /* fill the expanded ranges with entries for the first range */ + fill_expanded_ranges(eranges, ranges_a->nranges + ranges_a->nvalues, + ranges_a); + + /* and now add combine ranges for the second range */ + fill_expanded_ranges(&eranges[ranges_a->nranges + ranges_a->nvalues], + ranges_b->nranges + ranges_b->nvalues, + ranges_b); + + cmpFn = minmax_multi_get_strategy_procinfo(bdesc, attno, attr->atttypid, + BTLessStrategyNumber); + + /* sort the expanded ranges */ + neranges = sort_expanded_ranges(cmpFn, colloid, eranges, neranges); + + /* + * We've loaded two different lists of expanded ranges, so some of them + * may be overlapping. So walk through them and merge them. + */ + neranges = merge_overlapping_ranges(cmpFn, colloid, eranges, neranges); + + /* check that the combine ranges are correct (no overlaps, ordering) */ + AssertCheckExpandedRanges(bdesc, colloid, attno, attr, eranges, neranges); + + /* + * If needed, reduce some of the ranges. + * + * XXX This may be fairly expensive, so maybe we should do it only when + * it's actually needed (when we have too many ranges). + */ + + /* build array of gap distances and sort them in ascending order */ + distanceFn = minmax_multi_get_procinfo(bdesc, attno, PROCNUM_DISTANCE); + distances = build_distances(distanceFn, colloid, eranges, neranges); + + /* + * See how many values would be needed to store the current ranges, and if + * needed combine as many of them to get below the threshold. The + * collapsed ranges will be stored as a single value. + * + * XXX This does not apply the load factor, as we don't expect to add more + * values to the range, so we prefer to keep as many ranges as possible. + * + * XXX Can the maxvalues be different in the two ranges? Perhaps we should + * use maximum of those? + */ + neranges = reduce_expanded_ranges(eranges, neranges, distances, + ranges_a->maxvalues, + cmpFn, colloid); + + /* update the first range summary */ + store_expanded_ranges(ranges_a, eranges, neranges); + + MemoryContextSwitchTo(oldctx); + MemoryContextDelete(ctx); + + /* cleanup and update the serialized value */ + pfree(serialized_a); + col_a->bv_values[0] = PointerGetDatum(range_serialize(ranges_a)); + + PG_RETURN_VOID(); +} + +/* + * Cache and return minmax multi opclass support procedure + * + * Return the procedure corresponding to the given function support number + * or null if it does not exist. + */ +static FmgrInfo * +minmax_multi_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 procnum) +{ + MinmaxMultiOpaque *opaque; + uint16 basenum = procnum - PROCNUM_BASE; + + /* + * We cache these in the opaque struct, to avoid repetitive syscache + * lookups. + */ + opaque = (MinmaxMultiOpaque *) bdesc->bd_info[attno - 1]->oi_opaque; + + /* + * If we already searched for this proc and didn't find it, don't bother + * searching again. + */ + if (opaque->extra_proc_missing[basenum]) + return NULL; + + if (opaque->extra_procinfos[basenum].fn_oid == InvalidOid) + { + if (RegProcedureIsValid(index_getprocid(bdesc->bd_index, attno, + procnum))) + { + fmgr_info_copy(&opaque->extra_procinfos[basenum], + index_getprocinfo(bdesc->bd_index, attno, procnum), + bdesc->bd_context); + } + else + { + opaque->extra_proc_missing[basenum] = true; + return NULL; + } + } + + return &opaque->extra_procinfos[basenum]; +} + +/* + * Cache and return the procedure for the given strategy. + * + * Note: this function mirrors minmax_multi_get_strategy_procinfo; see notes + * there. If changes are made here, see that function too. + */ +static FmgrInfo * +minmax_multi_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, Oid subtype, + uint16 strategynum) +{ + MinmaxMultiOpaque *opaque; + + Assert(strategynum >= 1 && + strategynum <= BTMaxStrategyNumber); + + opaque = (MinmaxMultiOpaque *) bdesc->bd_info[attno - 1]->oi_opaque; + + /* + * We cache the procedures for the previous subtype in the opaque struct, + * to avoid repetitive syscache lookups. If the subtype changed, + * invalidate all the cached entries. + */ + if (opaque->cached_subtype != subtype) + { + uint16 i; + + for (i = 1; i <= BTMaxStrategyNumber; i++) + opaque->strategy_procinfos[i - 1].fn_oid = InvalidOid; + opaque->cached_subtype = subtype; + } + + if (opaque->strategy_procinfos[strategynum - 1].fn_oid == InvalidOid) + { + Form_pg_attribute attr; + HeapTuple tuple; + Oid opfamily, + oprid; + bool isNull; + + opfamily = bdesc->bd_index->rd_opfamily[attno - 1]; + attr = TupleDescAttr(bdesc->bd_tupdesc, attno - 1); + tuple = SearchSysCache4(AMOPSTRATEGY, ObjectIdGetDatum(opfamily), + ObjectIdGetDatum(attr->atttypid), + ObjectIdGetDatum(subtype), + Int16GetDatum(strategynum)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "missing operator %d(%u,%u) in opfamily %u", + strategynum, attr->atttypid, subtype, opfamily); + + oprid = DatumGetObjectId(SysCacheGetAttr(AMOPSTRATEGY, tuple, + Anum_pg_amop_amopopr, &isNull)); + ReleaseSysCache(tuple); + Assert(!isNull && RegProcedureIsValid(oprid)); + + fmgr_info_cxt(get_opcode(oprid), + &opaque->strategy_procinfos[strategynum - 1], + bdesc->bd_context); + } + + return &opaque->strategy_procinfos[strategynum - 1]; +} + +Datum +brin_minmax_multi_options(PG_FUNCTION_ARGS) +{ + local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + + init_local_reloptions(relopts, sizeof(MinMaxMultiOptions)); + + add_local_int_reloption(relopts, "values_per_range", "desc", + MINMAX_MULTI_DEFAULT_VALUES_PER_PAGE, 8, 256, + offsetof(MinMaxMultiOptions, valuesPerRange)); + + PG_RETURN_VOID(); +} + +/* + * brin_minmax_multi_summary_in + * - input routine for type brin_minmax_multi_summary. + * + * brin_minmax_multi_summary is only used internally to represent summaries + * in BRIN minmax-multi indexes, so it has no operations of its own, and we + * disallow input too. + */ +Datum +brin_minmax_multi_summary_in(PG_FUNCTION_ARGS) +{ + /* + * brin_minmax_multi_summary stores the data in binary form and parsing + * text input is not needed, so disallow this. + */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type %s", "brin_minmax_multi_summary"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + + +/* + * brin_minmax_multi_summary_out + * - output routine for type brin_minmax_multi_summary. + * + * BRIN minmax-multi summaries are serialized into a bytea value, but we + * want to output something nicer humans can understand. + */ +Datum +brin_minmax_multi_summary_out(PG_FUNCTION_ARGS) +{ + int i; + int idx; + SerializedRanges *ranges; + Ranges *ranges_deserialized; + StringInfoData str; + bool isvarlena; + Oid outfunc; + FmgrInfo fmgrinfo; + ArrayBuildState *astate_values = NULL; + + initStringInfo(&str); + appendStringInfoChar(&str, '{'); + + /* + * Detoast to get value with full 4B header (can't be stored in a toast + * table, but can use 1B header). + */ + ranges = (SerializedRanges *) PG_DETOAST_DATUM(PG_GETARG_BYTEA_PP(0)); + + /* lookup output func for the type */ + getTypeOutputInfo(ranges->typid, &outfunc, &isvarlena); + fmgr_info(outfunc, &fmgrinfo); + + /* deserialize the range info easy-to-process pieces */ + ranges_deserialized = range_deserialize(ranges->maxvalues, ranges); + + appendStringInfo(&str, "nranges: %u nvalues: %u maxvalues: %u", + ranges_deserialized->nranges, + ranges_deserialized->nvalues, + ranges_deserialized->maxvalues); + + /* serialize ranges */ + idx = 0; + for (i = 0; i < ranges_deserialized->nranges; i++) + { + char *a, + *b; + text *c; + StringInfoData str; + + initStringInfo(&str); + + a = OutputFunctionCall(&fmgrinfo, ranges_deserialized->values[idx++]); + b = OutputFunctionCall(&fmgrinfo, ranges_deserialized->values[idx++]); + + appendStringInfo(&str, "%s ... %s", a, b); + + c = cstring_to_text(str.data); + + astate_values = accumArrayResult(astate_values, + PointerGetDatum(c), + false, + TEXTOID, + CurrentMemoryContext); + } + + if (ranges_deserialized->nranges > 0) + { + Oid typoutput; + bool typIsVarlena; + Datum val; + char *extval; + + getTypeOutputInfo(ANYARRAYOID, &typoutput, &typIsVarlena); + + val = PointerGetDatum(makeArrayResult(astate_values, CurrentMemoryContext)); + + extval = OidOutputFunctionCall(typoutput, val); + + appendStringInfo(&str, " ranges: %s", extval); + } + + /* serialize individual values */ + astate_values = NULL; + + for (i = 0; i < ranges_deserialized->nvalues; i++) + { + Datum a; + text *b; + StringInfoData str; + + initStringInfo(&str); + + a = FunctionCall1(&fmgrinfo, ranges_deserialized->values[idx++]); + + appendStringInfoString(&str, DatumGetCString(a)); + + b = cstring_to_text(str.data); + + astate_values = accumArrayResult(astate_values, + PointerGetDatum(b), + false, + TEXTOID, + CurrentMemoryContext); + } + + if (ranges_deserialized->nvalues > 0) + { + Oid typoutput; + bool typIsVarlena; + Datum val; + char *extval; + + getTypeOutputInfo(ANYARRAYOID, &typoutput, &typIsVarlena); + + val = PointerGetDatum(makeArrayResult(astate_values, CurrentMemoryContext)); + + extval = OidOutputFunctionCall(typoutput, val); + + appendStringInfo(&str, " values: %s", extval); + } + + + appendStringInfoChar(&str, '}'); + + PG_RETURN_CSTRING(str.data); +} + +/* + * brin_minmax_multi_summary_recv + * - binary input routine for type brin_minmax_multi_summary. + */ +Datum +brin_minmax_multi_summary_recv(PG_FUNCTION_ARGS) +{ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type %s", "brin_minmax_multi_summary"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + +/* + * brin_minmax_multi_summary_send + * - binary output routine for type brin_minmax_multi_summary. + * + * BRIN minmax-multi summaries are serialized in a bytea value (although + * the type is named differently), so let's just send that. + */ +Datum +brin_minmax_multi_summary_send(PG_FUNCTION_ARGS) +{ + return byteasend(fcinfo); +} diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c index 5d85c179b400..566967a5834f 100644 --- a/src/backend/access/brin/brin_pageops.c +++ b/src/backend/access/brin/brin_pageops.c @@ -2,7 +2,7 @@ * brin_pageops.c * Page-handling routines for BRIN indexes * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/brin/brin_revmap.c b/src/backend/access/brin/brin_revmap.c index a8e9d0f0b18e..ece5a53107b6 100644 --- a/src/backend/access/brin/brin_revmap.c +++ b/src/backend/access/brin/brin_revmap.c @@ -12,7 +12,7 @@ * the metapage. When the revmap needs to be expanded, all tuples on the * regular BRIN page at that block (if any) are moved out of the way. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -368,6 +368,7 @@ brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk) regBuf = ReadBuffer(idxrel, ItemPointerGetBlockNumber(iptr)); LockBuffer(regBuf, BUFFER_LOCK_EXCLUSIVE); regPg = BufferGetPage(regBuf); + /* * We're only removing data, not reading it, so there's no need to * TestForOldSnapshot here. diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c index 6cb7c26b39f2..09e563b1f082 100644 --- a/src/backend/access/brin/brin_tuple.c +++ b/src/backend/access/brin/brin_tuple.c @@ -23,7 +23,7 @@ * Note the size of the null bitmask may not be the same as that of the * datum array. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,12 +32,23 @@ #include "postgres.h" #include "access/brin_tuple.h" +#include "access/detoast.h" +#include "access/heaptoast.h" #include "access/htup_details.h" +#include "access/toast_internals.h" #include "access/tupdesc.h" #include "access/tupmacs.h" #include "utils/datum.h" #include "utils/memutils.h" + +/* + * This enables de-toasting of index entries. Needed until VACUUM is + * smart enough to rebuild indexes from scratch. + */ +#define TOAST_INDEX_HACK + + static inline void brin_deconstruct_tuple(BrinDesc *brdesc, char *tp, bits8 *nullbits, bool nulls, Datum *values, bool *allnulls, bool *hasnulls); @@ -99,6 +110,12 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple, Size len, hoff, data_len; + int i; + +#ifdef TOAST_INDEX_HACK + Datum *untoasted_values; + int nuntoasted = 0; +#endif Assert(brdesc->bd_totalstored > 0); @@ -107,6 +124,10 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple, phony_nullbitmap = (bits8 *) palloc(sizeof(bits8) * BITMAPLEN(brdesc->bd_totalstored)); +#ifdef TOAST_INDEX_HACK + untoasted_values = (Datum *) palloc(sizeof(Datum) * brdesc->bd_totalstored); +#endif + /* * Set up the values/nulls arrays for heap_fill_tuple */ @@ -138,10 +159,108 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple, if (tuple->bt_columns[keyno].bv_hasnulls) anynulls = true; + /* If needed, serialize the values before forming the on-disk tuple. */ + if (tuple->bt_columns[keyno].bv_serialize) + { + tuple->bt_columns[keyno].bv_serialize(brdesc, + tuple->bt_columns[keyno].bv_mem_value, + tuple->bt_columns[keyno].bv_values); + } + + /* + * Now obtain the values of each stored datum. Note that some values + * might be toasted, and we cannot rely on the original heap values + * sticking around forever, so we must detoast them. Also try to + * compress them. + */ for (datumno = 0; datumno < brdesc->bd_info[keyno]->oi_nstored; datumno++) - values[idxattno++] = tuple->bt_columns[keyno].bv_values[datumno]; + { + Datum value = tuple->bt_columns[keyno].bv_values[datumno]; + +#ifdef TOAST_INDEX_HACK + + /* We must look at the stored type, not at the index descriptor. */ + TypeCacheEntry *atttype = brdesc->bd_info[keyno]->oi_typcache[datumno]; + + /* Do we need to free the value at the end? */ + bool free_value = false; + + /* For non-varlena types we don't need to do anything special */ + if (atttype->typlen != -1) + { + values[idxattno++] = value; + continue; + } + + /* + * Do nothing if value is not of varlena type. We don't need to + * care about NULL values here, thanks to bv_allnulls above. + * + * If value is stored EXTERNAL, must fetch it so we are not + * depending on outside storage. + * + * XXX Is this actually true? Could it be that the summary is NULL + * even for range with non-NULL data? E.g. degenerate bloom filter + * may be thrown away, etc. + */ + if (VARATT_IS_EXTERNAL(DatumGetPointer(value))) + { + value = PointerGetDatum(detoast_external_attr((struct varlena *) + DatumGetPointer(value))); + free_value = true; + } + + /* + * If value is above size target, and is of a compressible + * datatype, try to compress it in-line. + */ + if (!VARATT_IS_EXTENDED(DatumGetPointer(value)) && + VARSIZE(DatumGetPointer(value)) > TOAST_INDEX_TARGET && + (atttype->typstorage == TYPSTORAGE_EXTENDED || + atttype->typstorage == TYPSTORAGE_MAIN)) + { + Datum cvalue; + char compression; + Form_pg_attribute att = TupleDescAttr(brdesc->bd_tupdesc, + keyno); + + /* + * If the BRIN summary and indexed attribute use the same data + * type and it has a valid compression method, we can use the + * same compression method. Otherwise we have to use the + * default method. + */ + if (att->atttypid == atttype->type_id) + compression = att->attcompression; + else + compression = InvalidCompressionMethod; + + cvalue = toast_compress_datum(value, compression); + + if (DatumGetPointer(cvalue) != NULL) + { + /* successful compression */ + if (free_value) + pfree(DatumGetPointer(value)); + + value = cvalue; + free_value = true; + } + } + + /* + * If we untoasted / compressed the value, we need to free it + * after forming the index tuple. + */ + if (free_value) + untoasted_values[nuntoasted++] = value; + +#endif + + values[idxattno++] = value; + } } /* Assert we did not overrun temp arrays */ @@ -193,6 +312,11 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple, pfree(nulls); pfree(phony_nullbitmap); +#ifdef TOAST_INDEX_HACK + for (i = 0; i < nuntoasted; i++) + pfree(DatumGetPointer(untoasted_values[i])); +#endif + /* * Now fill in the real null bitmasks. allnulls first. */ @@ -243,7 +367,6 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple, *bitP |= bitmask; } - bitP = ((bits8 *) (rettuple + SizeOfBrinTuple)) - 1; } if (tuple->bt_placeholder) @@ -392,13 +515,15 @@ brin_memtuple_initialize(BrinMemTuple *dtuple, BrinDesc *brdesc) sizeof(BrinValues) * brdesc->bd_tupdesc->natts); for (i = 0; i < brdesc->bd_tupdesc->natts; i++) { - dtuple->bt_columns[i].bv_allnulls = true; - dtuple->bt_columns[i].bv_hasnulls = false; - dtuple->bt_columns[i].bv_attno = i + 1; dtuple->bt_columns[i].bv_allnulls = true; dtuple->bt_columns[i].bv_hasnulls = false; dtuple->bt_columns[i].bv_values = (Datum *) currdatum; + + dtuple->bt_columns[i].bv_mem_value = PointerGetDatum(NULL); + dtuple->bt_columns[i].bv_serialize = NULL; + dtuple->bt_columns[i].bv_context = dtuple->bt_context; + currdatum += sizeof(Datum) * brdesc->bd_info[i]->oi_nstored; } @@ -478,6 +603,10 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple, BrinMemTuple *dMemtuple) dtup->bt_columns[keyno].bv_hasnulls = hasnulls[keyno]; dtup->bt_columns[keyno].bv_allnulls = false; + + dtup->bt_columns[keyno].bv_mem_value = PointerGetDatum(NULL); + dtup->bt_columns[keyno].bv_serialize = NULL; + dtup->bt_columns[keyno].bv_context = dtup->bt_context; } MemoryContextSwitchTo(oldcxt); diff --git a/src/backend/access/brin/brin_validate.c b/src/backend/access/brin/brin_validate.c index fb0615463e0f..11835d85cd45 100644 --- a/src/backend/access/brin/brin_validate.c +++ b/src/backend/access/brin/brin_validate.c @@ -3,7 +3,7 @@ * brin_validate.c * Opclass validator for BRIN. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -97,8 +97,8 @@ brinvalidate(Oid opclassoid) break; case BRIN_PROCNUM_CONSISTENT: ok = check_amproc_signature(procform->amproc, BOOLOID, true, - 3, 3, INTERNALOID, INTERNALOID, - INTERNALOID); + 3, 4, INTERNALOID, INTERNALOID, + INTERNALOID, INT4OID); break; case BRIN_PROCNUM_UNION: ok = check_amproc_signature(procform->amproc, BOOLOID, true, diff --git a/src/backend/access/brin/brin_xlog.c b/src/backend/access/brin/brin_xlog.c index b13bf4ca13f4..3623e50600cb 100644 --- a/src/backend/access/brin/brin_xlog.c +++ b/src/backend/access/brin/brin_xlog.c @@ -2,7 +2,7 @@ * brin_xlog.c * XLog replay routines for BRIN indexes * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/common/Makefile b/src/backend/access/common/Makefile index eb34e111c4fa..3899202df6ed 100644 --- a/src/backend/access/common/Makefile +++ b/src/backend/access/common/Makefile @@ -25,6 +25,7 @@ OBJS = \ scankey.o \ session.o \ syncscan.o \ + toast_compression.o \ toast_internals.o \ tupconvert.o \ tupdesc.o diff --git a/src/backend/access/common/attmap.c b/src/backend/access/common/attmap.c index 2cd16d7eafb1..32405f861063 100644 --- a/src/backend/access/common/attmap.c +++ b/src/backend/access/common/attmap.c @@ -10,7 +10,7 @@ * columns in a different order, taking into account dropped columns. * They are also used by the tuple conversion routines in tupconvert.c. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/common/bufmask.c b/src/backend/access/common/bufmask.c index 4bdb1848ad24..003a0befb25d 100644 --- a/src/backend/access/common/bufmask.c +++ b/src/backend/access/common/bufmask.c @@ -5,7 +5,7 @@ * in a page which can be different when the WAL is generated * and when the WAL is applied. * - * Portions Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2021, PostgreSQL Global Development Group * * Contains common routines required for masking a page. * diff --git a/src/backend/access/common/detoast.c b/src/backend/access/common/detoast.c index 372fa83fcc7b..8617645eea73 100644 --- a/src/backend/access/common/detoast.c +++ b/src/backend/access/common/detoast.c @@ -3,7 +3,7 @@ * detoast.c * Retrieve compressed or external variable size attributes. * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/access/common/detoast.c @@ -18,6 +18,7 @@ #include "access/table.h" #include "access/tableam.h" #include "access/toast_internals.h" +#include "common/int.h" #include "common/pg_lzcompress.h" #include "utils/expandeddatum.h" #include "utils/rel.h" @@ -133,7 +134,7 @@ varattrib_untoast_len(Datum d) if (VARATT_IS_COMPRESSED(attr)) { - len = TOAST_COMPRESS_RAWSIZE(attr); + len = TOAST_COMPRESS_EXTSIZE(attr); } else if (VARATT_IS_SHORT(attr)) { @@ -305,7 +306,8 @@ detoast_attr(struct varlena *attr) * Public entry point to get back part of a toasted value * from compression or external storage. * - * Note: When slicelength is negative, return suffix of the value. + * sliceoffset is where to start (zero or more) + * If slicelength < 0, return everything beyond sliceoffset * ---------- */ struct varlena * @@ -315,8 +317,21 @@ detoast_attr_slice(struct varlena *attr, struct varlena *preslice; struct varlena *result; char *attrdata; + int32 slicelimit; int32 attrsize; + if (sliceoffset < 0) + elog(ERROR, "invalid sliceoffset: %d", sliceoffset); + + /* + * Compute slicelimit = offset + length, or -1 if we must fetch all of the + * value. In case of integer overflow, we must fetch all. + */ + if (slicelength < 0) + slicelimit = -1; + else if (pg_add_s32_overflow(sliceoffset, slicelength, &slicelimit)) + slicelength = slicelimit = -1; + if (VARATT_IS_EXTERNAL_ONDISK(attr)) { struct varatt_external toast_pointer; @@ -332,16 +347,22 @@ detoast_attr_slice(struct varlena *attr, * at least the requested part (when a prefix is requested). * Otherwise, just fetch all slices. */ - if (slicelength > 0 && sliceoffset >= 0) + if (slicelimit >= 0) { - int32 max_size; + int32 max_size = VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer); /* * Determine maximum amount of compressed data needed for a prefix * of a given length (after decompression). + * + * At least for now, if it's LZ4 data, we'll have to fetch the + * whole thing, because there doesn't seem to be an API call to + * determine how much compressed data we need to be sure of being + * able to decompress the required slice. */ - max_size = pglz_maximum_compressed_size(sliceoffset + slicelength, - toast_pointer.va_extsize); + if (VARATT_EXTERNAL_GET_COMPRESS_METHOD(toast_pointer) == + TOAST_PGLZ_COMPRESSION_ID) + max_size = pglz_maximum_compressed_size(slicelimit, max_size); /* * Fetch enough compressed slices (compressed marker will get set @@ -379,8 +400,8 @@ detoast_attr_slice(struct varlena *attr, struct varlena *tmp = preslice; /* Decompress enough to encompass the slice and the offset */ - if (slicelength > 0 && sliceoffset >= 0) - preslice = toast_decompress_datum_slice(tmp, slicelength + sliceoffset); + if (slicelimit >= 0) + preslice = toast_decompress_datum_slice(tmp, slicelimit); else preslice = toast_decompress_datum(tmp); @@ -406,8 +427,7 @@ detoast_attr_slice(struct varlena *attr, sliceoffset = 0; slicelength = 0; } - - if (((sliceoffset + slicelength) > attrsize) || slicelength < 0) + else if (slicelength < 0 || slicelimit > attrsize) slicelength = attrsize - sliceoffset; result = (struct varlena *) palloc(slicelength + VARHDRSZ); @@ -442,7 +462,7 @@ toast_fetch_datum(struct varlena *attr) /* Must copy to access aligned fields */ VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - attrsize = toast_pointer.va_extsize; + attrsize = VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer); result = (struct varlena *) palloc(attrsize + VARHDRSZ); @@ -503,7 +523,7 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset, */ Assert(!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) || 0 == sliceoffset); - attrsize = toast_pointer.va_extsize; + attrsize = VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer); if (sliceoffset >= attrsize) { @@ -513,12 +533,17 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset, /* * When fetching a prefix of a compressed external datum, account for the - * rawsize tracking amount of raw data, which is stored at the beginning - * as an int32 value). + * space required by va_tcinfo, which is stored at the beginning as an + * int32 value. */ if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) && slicelength > 0) slicelength = slicelength + sizeof(int32); + /* + * Adjust length request if needed. (Note: our sole caller, + * detoast_attr_slice, protects us against sliceoffset + slicelength + * overflowing.) + */ if (((sliceoffset + slicelength) > attrsize) || slicelength < 0) slicelength = attrsize - sliceoffset; @@ -554,21 +579,25 @@ toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset, static struct varlena * toast_decompress_datum(struct varlena *attr) { - struct varlena *result; + ToastCompressionId cmid; Assert(VARATT_IS_COMPRESSED(attr)); - result = (struct varlena *) - palloc(TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ); - SET_VARSIZE(result, TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ); - - if (pglz_decompress(TOAST_COMPRESS_RAWDATA(attr), - TOAST_COMPRESS_SIZE(attr), - VARDATA(result), - TOAST_COMPRESS_RAWSIZE(attr), true) < 0) - elog(ERROR, "compressed data is corrupted"); - - return result; + /* + * Fetch the compression method id stored in the compression header and + * decompress the data using the appropriate decompression routine. + */ + cmid = TOAST_COMPRESS_METHOD(attr); + switch (cmid) + { + case TOAST_PGLZ_COMPRESSION_ID: + return pglz_decompress_datum(attr); + case TOAST_LZ4_COMPRESSION_ID: + return lz4_decompress_datum(attr); + default: + elog(ERROR, "invalid compression method id %d", cmid); + return NULL; /* keep compiler quiet */ + } } @@ -582,22 +611,36 @@ toast_decompress_datum(struct varlena *attr) static struct varlena * toast_decompress_datum_slice(struct varlena *attr, int32 slicelength) { - struct varlena *result; - int32 rawsize; + ToastCompressionId cmid; Assert(VARATT_IS_COMPRESSED(attr)); - result = (struct varlena *) palloc(slicelength + VARHDRSZ); - - rawsize = pglz_decompress(TOAST_COMPRESS_RAWDATA(attr), - VARSIZE(attr) - TOAST_COMPRESS_HDRSZ, - VARDATA(result), - slicelength, false); - if (rawsize < 0) - elog(ERROR, "compressed data is corrupted"); + /* + * Some callers may pass a slicelength that's more than the actual + * decompressed size. If so, just decompress normally. This avoids + * possibly allocating a larger-than-necessary result object, and may be + * faster and/or more robust as well. Notably, some versions of liblz4 + * have been seen to give wrong results if passed an output size that is + * more than the data's true decompressed size. + */ + if ((uint32) slicelength >= TOAST_COMPRESS_EXTSIZE(attr)) + return toast_decompress_datum(attr); - SET_VARSIZE(result, rawsize + VARHDRSZ); - return result; + /* + * Fetch the compression method id stored in the compression header and + * decompress the data slice using the appropriate decompression routine. + */ + cmid = TOAST_COMPRESS_METHOD(attr); + switch (cmid) + { + case TOAST_PGLZ_COMPRESSION_ID: + return pglz_decompress_datum_slice(attr, slicelength); + case TOAST_LZ4_COMPRESSION_ID: + return lz4_decompress_datum_slice(attr, slicelength); + default: + elog(ERROR, "invalid compression method id %d", cmid); + return NULL; /* keep compiler quiet */ + } } /* ---------- @@ -639,7 +682,7 @@ toast_raw_datum_size(Datum value) else if (VARATT_IS_COMPRESSED(attr)) { /* here, va_rawsize is just the payload size */ - result = VARRAWSIZE_4B_C(attr) + VARHDRSZ; + result = VARDATA_COMPRESSED_GET_EXTSIZE(attr) + VARHDRSZ; } else if (VARATT_IS_SHORT(attr)) { @@ -679,7 +722,7 @@ toast_datum_size(Datum value) struct varatt_external toast_pointer; VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - result = toast_pointer.va_extsize; + result = VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer); } else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) { diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index eb9a8a43c264..1bf115c0f932 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -47,7 +47,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -747,11 +747,11 @@ heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest) } /* - * Expand a tuple which has less attributes than required. For each attribute + * Expand a tuple which has fewer attributes than required. For each attribute * not present in the sourceTuple, if there is a missing value that will be * used. Otherwise the attribute will be set to NULL. * - * The source tuple must have less attributes than the required number. + * The source tuple must have fewer attributes than the required number. * * Only one of targetHeapTuple and targetMinimalTuple may be supplied. The * other argument must be NULL. @@ -764,7 +764,7 @@ expand_tuple(HeapTuple *targetHeapTuple, { AttrMissing *attrmiss = NULL; int attnum; - int firstmissingnum = 0; + int firstmissingnum; bool hasNulls = HeapTupleHasNulls(sourceTuple); HeapTupleHeader targetTHeader; HeapTupleHeader sourceTHeader = sourceTuple->t_data; diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c index 634016b9b7c0..8df882da7a78 100644 --- a/src/backend/access/common/indextuple.c +++ b/src/backend/access/common/indextuple.c @@ -4,7 +4,7 @@ * This file contains index tuple accessor and mutator routines, * as well as various tuple utilities. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -103,7 +103,10 @@ index_form_tuple(TupleDesc tupleDescriptor, (att->attstorage == TYPSTORAGE_EXTENDED || att->attstorage == TYPSTORAGE_MAIN)) { - Datum cvalue = toast_compress_datum(untoasted_values[i]); + Datum cvalue; + + cvalue = toast_compress_datum(untoasted_values[i], + att->attcompression); if (DatumGetPointer(cvalue) != NULL) { @@ -434,22 +437,37 @@ void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull) { - int hasnulls = IndexTupleHasNulls(tup); - int natts = tupleDescriptor->natts; /* number of atts to extract */ - int attnum; char *tp; /* ptr to tuple data */ - int off; /* offset in tuple data */ bits8 *bp; /* ptr to null bitmap in tuple */ - bool slow = false; /* can we use/set attcacheoff? */ - - /* Assert to protect callers who allocate fixed-size arrays */ - Assert(natts <= INDEX_MAX_KEYS); /* XXX "knows" t_bits are just after fixed tuple header! */ bp = (bits8 *) ((char *) tup + sizeof(IndexTupleData)); tp = (char *) tup + IndexInfoFindDataOffset(tup->t_info); - off = 0; + + index_deform_tuple_internal(tupleDescriptor, values, isnull, + tp, bp, IndexTupleHasNulls(tup)); +} + +/* + * Convert an index tuple into Datum/isnull arrays, + * without assuming any specific layout of the index tuple header. + * + * Caller must supply pointer to data area, pointer to nulls bitmap + * (which can be NULL if !hasnulls), and hasnulls flag. + */ +void +index_deform_tuple_internal(TupleDesc tupleDescriptor, + Datum *values, bool *isnull, + char *tp, bits8 *bp, int hasnulls) +{ + int natts = tupleDescriptor->natts; /* number of atts to extract */ + int attnum; + int off = 0; /* offset in tuple data */ + bool slow = false; /* can we use/set attcacheoff? */ + + /* Assert to protect callers who allocate fixed-size arrays */ + Assert(natts <= INDEX_MAX_KEYS); for (attnum = 0; attnum < natts; attnum++) { diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c index df27700df92a..93c3c4f66a83 100644 --- a/src/backend/access/common/printsimple.c +++ b/src/backend/access/common/printsimple.c @@ -8,7 +8,7 @@ * doesn't handle standalone backends or protocol versions other than * 3.0, because we don't need such handling for current applications. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c index bcfa918712a1..c744d0b8358f 100644 --- a/src/backend/access/common/printtup.c +++ b/src/backend/access/common/printtup.c @@ -5,7 +5,7 @@ * clients and standalone backends are supported here). * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -27,16 +27,9 @@ static void printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo); static bool printtup(TupleTableSlot *slot, DestReceiver *self); -static bool printtup_20(TupleTableSlot *slot, DestReceiver *self); -static bool printtup_internal_20(TupleTableSlot *slot, DestReceiver *self); static void printtup_shutdown(DestReceiver *self); static void printtup_destroy(DestReceiver *self); -static void SendRowDescriptionCols_2(StringInfo buf, TupleDesc typeinfo, - List *targetlist, int16 *formats); -static void SendRowDescriptionCols_3(StringInfo buf, TupleDesc typeinfo, - List *targetlist, int16 *formats); - /* ---------------------------------------------------------------- * printtup / debugtup support * ---------------------------------------------------------------- @@ -112,19 +105,6 @@ SetRemoteDestReceiverParams(DestReceiver *self, Portal portal) myState->pub.mydest == DestRemoteExecute); myState->portal = portal; - - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - { - /* - * In protocol 2.0 the Bind message does not exist, so there is no way - * for the columns to have different print formats; it's sufficient to - * look at the first one. - */ - if (portal->formats && portal->formats[0] != 0) - myState->pub.receiveSlot = printtup_internal_20; - else - myState->pub.receiveSlot = printtup_20; - } } static void @@ -149,21 +129,6 @@ printtup_startup(DestReceiver *self, int operation pg_attribute_unused(), TupleD "printtup", ALLOCSET_DEFAULT_SIZES); - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - { - /* - * Send portal name to frontend (obsolete cruft, gone in proto 3.0) - * - * If portal name not specified, use "blank" portal. - */ - const char *portalName = portal->name; - - if (portalName == NULL || portalName[0] == '\0') - portalName = "blank"; - - pq_puttextmessage('P', portalName); - } - /* * If we are supposed to emit row descriptions, then send the tuple * descriptor of the tuples. @@ -202,31 +167,14 @@ SendRowDescriptionMessage(StringInfo buf, TupleDesc typeinfo, List *targetlist, int16 *formats) { int natts = typeinfo->natts; - int proto = PG_PROTOCOL_MAJOR(FrontendProtocol); + int i; + ListCell *tlist_item = list_head(targetlist); /* tuple descriptor message type */ pq_beginmessage_reuse(buf, 'T'); /* # of attrs in tuples */ pq_sendint16(buf, natts); - if (proto >= 3) - SendRowDescriptionCols_3(buf, typeinfo, targetlist, formats); - else - SendRowDescriptionCols_2(buf, typeinfo, targetlist, formats); - - pq_endmessage_reuse(buf); -} - -/* - * Send description for each column when using v3+ protocol - */ -static void -SendRowDescriptionCols_3(StringInfo buf, TupleDesc typeinfo, List *targetlist, int16 *formats) -{ - int natts = typeinfo->natts; - int i; - ListCell *tlist_item = list_head(targetlist); - /* * Preallocate memory for the entire message to be sent. That allows to * use the significantly faster inline pqformat.h functions and to avoid @@ -291,33 +239,8 @@ SendRowDescriptionCols_3(StringInfo buf, TupleDesc typeinfo, List *targetlist, i pq_writeint32(buf, atttypmod); pq_writeint16(buf, format); } -} -/* - * Send description for each column when using v2 protocol - */ -static void -SendRowDescriptionCols_2(StringInfo buf, TupleDesc typeinfo, List *targetlist, int16 *formats) -{ - int natts = typeinfo->natts; - int i; - - for (i = 0; i < natts; ++i) - { - Form_pg_attribute att = TupleDescAttr(typeinfo, i); - Oid atttypid = att->atttypid; - int32 atttypmod = att->atttypmod; - - /* If column is a domain, send the base type and typmod instead */ - atttypid = getBaseTypeAndTypmod(atttypid, &atttypmod); - - pq_sendstring(buf, NameStr(att->attname)); - /* column ID only info appears in protocol 3.0 and up */ - pq_sendint32(buf, atttypid); - pq_sendint16(buf, att->attlen); - pq_sendint32(buf, atttypmod); - /* format info only appears in protocol 3.0 and up */ - } + pq_endmessage_reuse(buf); } /* @@ -371,7 +294,7 @@ printtup_prepare_info(DR_printtup *myState, TupleDesc typeinfo, int numAttrs) } /* ---------------- - * printtup --- print a tuple in protocol 3.0 + * printtup --- send a tuple to the client * ---------------- */ static bool diff --git a/src/backend/access/common/relation.c b/src/backend/access/common/relation.c index 57b25f759ede..167110f45fc0 100644 --- a/src/backend/access/common/relation.c +++ b/src/backend/access/common/relation.c @@ -3,7 +3,7 @@ * relation.c * Generic relation related routines. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 3ba2f74e4674..dbdfef9b3729 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -3,7 +3,7 @@ * reloptions.c * Core support for relation options (pg_class.reloptions) * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -115,7 +115,7 @@ static relopt_bool boolRelOpts[] = { "autovacuum_enabled", "Enables autovacuum in this relation", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + RELOPT_KIND_HEAP | RELOPT_KIND_TOAST | RELOPT_KIND_PARTITIONED, ShareUpdateExclusiveLock }, true @@ -147,15 +147,6 @@ static relopt_bool boolRelOpts[] = }, false }, - { - { - "vacuum_index_cleanup", - "Enables index vacuuming and index cleanup", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, - ShareUpdateExclusiveLock - }, - true - }, { { "vacuum_truncate", @@ -253,7 +244,7 @@ static relopt_int intRelOpts[] = { "autovacuum_analyze_threshold", "Minimum number of tuple inserts, updates or deletes prior to analyze", - RELOPT_KIND_HEAP, + RELOPT_KIND_HEAP | RELOPT_KIND_PARTITIONED, ShareUpdateExclusiveLock }, -1, 0, INT_MAX @@ -427,7 +418,7 @@ static relopt_real realRelOpts[] = { "autovacuum_analyze_scale_factor", "Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples", - RELOPT_KIND_HEAP, + RELOPT_KIND_HEAP | RELOPT_KIND_PARTITIONED, ShareUpdateExclusiveLock }, -1, 0.0, 100.0 @@ -471,7 +462,7 @@ static relopt_real realRelOpts[] = { { "vacuum_cleanup_index_scale_factor", - "Number of tuple inserts prior to index cleanup as a fraction of reltuples.", + "Deprecated B-Tree parameter.", RELOPT_KIND_BTREE, ShareUpdateExclusiveLock }, @@ -481,6 +472,21 @@ static relopt_real realRelOpts[] = {{NULL}} }; +/* values from StdRdOptIndexCleanup */ +relopt_enum_elt_def StdRdOptIndexCleanupValues[] = +{ + {"auto", STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO}, + {"on", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, + {"off", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, + {"true", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, + {"false", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, + {"yes", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, + {"no", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, + {"1", STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON}, + {"0", STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF}, + {(const char *) NULL} /* list terminator */ +}; + /* values from GistOptBufferingMode */ relopt_enum_elt_def gistBufferingOptValues[] = { @@ -501,6 +507,17 @@ relopt_enum_elt_def viewCheckOptValues[] = static relopt_enum enumRelOpts[] = { + { + { + "vacuum_index_cleanup", + "Controls index vacuuming and index cleanup", + RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + ShareUpdateExclusiveLock + }, + StdRdOptIndexCleanupValues, + STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO, + gettext_noop("Valid values are \"on\", \"off\", and \"auto\".") + }, { { "buffering", @@ -1988,8 +2005,12 @@ bytea * partitioned_table_reloptions(Datum reloptions, bool validate) { /* - * GPDB: we maintain reloptions for partition roots to support reloption - * inheritance and hierarchy wide ALTER TABLE SET(). + * GPDB: unlike upstream, a partitioned root accepts the full set of + * heap options (fillfactor, analyze_hll_non_part_table, ...). The + * root has no storage that would use them, but GPDB's partition DDL + * stores them on the root and propagates them to newly created + * children, and pre-PG14 GPDB (inheritance-based partitioning, where + * the root was a plain table) always allowed this. */ return default_reloptions(reloptions, validate, RELOPT_KIND_HEAP); } diff --git a/src/backend/access/common/reloptions_gp.c b/src/backend/access/common/reloptions_gp.c index 1e3cba7b58c3..0f5ebf483708 100644 --- a/src/backend/access/common/reloptions_gp.c +++ b/src/backend/access/common/reloptions_gp.c @@ -1446,7 +1446,7 @@ validateColumnStorageEncodingClauses(List *aocoColumnEncoding, memset(&cacheInfo, 0, sizeof(cacheInfo)); cacheInfo.keysize = NAMEDATALEN; cacheInfo.entrysize = sizeof(*ce); - cacheFlags = HASH_ELEM; + cacheFlags = HASH_ELEM | HASH_STRINGS; ht = hash_create("column info cache", list_length(tableElts), diff --git a/src/backend/access/common/scankey.c b/src/backend/access/common/scankey.c index 3c4bd53f3f86..bf33c50d959a 100644 --- a/src/backend/access/common/scankey.c +++ b/src/backend/access/common/scankey.c @@ -3,7 +3,7 @@ * scankey.c * scan key support code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/common/session.c b/src/backend/access/common/session.c index 0ec61d48a2d1..61b3206befb9 100644 --- a/src/backend/access/common/session.c +++ b/src/backend/access/common/session.c @@ -12,7 +12,7 @@ * Currently this infrastructure is used to share: * - typemod registry for ephemeral row-types, i.e. BlessTupleDesc etc. * - * Portions Copyright (c) 2017-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2021, PostgreSQL Global Development Group * * src/backend/access/common/session.c * diff --git a/src/backend/access/common/syncscan.c b/src/backend/access/common/syncscan.c index c1ce156902be..b7a28af4ad82 100644 --- a/src/backend/access/common/syncscan.c +++ b/src/backend/access/common/syncscan.c @@ -36,7 +36,7 @@ * ss_report_location - update current scan location * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/common/toast_compression.c b/src/backend/access/common/toast_compression.c new file mode 100644 index 000000000000..845618349fe0 --- /dev/null +++ b/src/backend/access/common/toast_compression.c @@ -0,0 +1,318 @@ +/*------------------------------------------------------------------------- + * + * toast_compression.c + * Functions for toast compression. + * + * Copyright (c) 2021, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/access/common/toast_compression.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#ifdef USE_LZ4 +#include +#endif + +#include "access/detoast.h" +#include "access/toast_compression.h" +#include "common/pg_lzcompress.h" +#include "fmgr.h" +#include "utils/builtins.h" + +/* GUC */ +int default_toast_compression = TOAST_PGLZ_COMPRESSION; + +#define NO_LZ4_SUPPORT() \ + ereport(ERROR, \ + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ + errmsg("compression method lz4 not supported"), \ + errdetail("This functionality requires the server to be built with lz4 support."), \ + errhint("You need to rebuild PostgreSQL using %s.", "--with-lz4"))) + +/* + * Compress a varlena using PGLZ. + * + * Returns the compressed varlena, or NULL if compression fails. + */ +struct varlena * +pglz_compress_datum(const struct varlena *value) +{ + int32 valsize, + len; + struct varlena *tmp = NULL; + + valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value)); + + /* + * No point in wasting a palloc cycle if value size is outside the allowed + * range for compression. + */ + if (valsize < PGLZ_strategy_default->min_input_size || + valsize > PGLZ_strategy_default->max_input_size) + return NULL; + + /* + * Figure out the maximum possible size of the pglz output, add the bytes + * that will be needed for varlena overhead, and allocate that amount. + */ + tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) + + VARHDRSZ_COMPRESSED); + + len = pglz_compress(VARDATA_ANY(value), + valsize, + (char *) tmp + VARHDRSZ_COMPRESSED, + NULL); + if (len < 0) + { + pfree(tmp); + return NULL; + } + + SET_VARSIZE_COMPRESSED(tmp, len + VARHDRSZ_COMPRESSED); + + return tmp; +} + +/* + * Decompress a varlena that was compressed using PGLZ. + */ +struct varlena * +pglz_decompress_datum(const struct varlena *value) +{ + struct varlena *result; + int32 rawsize; + + /* allocate memory for the uncompressed data */ + result = (struct varlena *) palloc(VARDATA_COMPRESSED_GET_EXTSIZE(value) + VARHDRSZ); + + /* decompress the data */ + rawsize = pglz_decompress((char *) value + VARHDRSZ_COMPRESSED, + VARSIZE(value) - VARHDRSZ_COMPRESSED, + VARDATA(result), + VARDATA_COMPRESSED_GET_EXTSIZE(value), true); + if (rawsize < 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("compressed pglz data is corrupt"))); + + SET_VARSIZE(result, rawsize + VARHDRSZ); + + return result; +} + +/* + * Decompress part of a varlena that was compressed using PGLZ. + */ +struct varlena * +pglz_decompress_datum_slice(const struct varlena *value, + int32 slicelength) +{ + struct varlena *result; + int32 rawsize; + + /* allocate memory for the uncompressed data */ + result = (struct varlena *) palloc(slicelength + VARHDRSZ); + + /* decompress the data */ + rawsize = pglz_decompress((char *) value + VARHDRSZ_COMPRESSED, + VARSIZE(value) - VARHDRSZ_COMPRESSED, + VARDATA(result), + slicelength, false); + if (rawsize < 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("compressed pglz data is corrupt"))); + + SET_VARSIZE(result, rawsize + VARHDRSZ); + + return result; +} + +/* + * Compress a varlena using LZ4. + * + * Returns the compressed varlena, or NULL if compression fails. + */ +struct varlena * +lz4_compress_datum(const struct varlena *value) +{ +#ifndef USE_LZ4 + NO_LZ4_SUPPORT(); + return NULL; /* keep compiler quiet */ +#else + int32 valsize; + int32 len; + int32 max_size; + struct varlena *tmp = NULL; + + valsize = VARSIZE_ANY_EXHDR(value); + + /* + * Figure out the maximum possible size of the LZ4 output, add the bytes + * that will be needed for varlena overhead, and allocate that amount. + */ + max_size = LZ4_compressBound(valsize); + tmp = (struct varlena *) palloc(max_size + VARHDRSZ_COMPRESSED); + + len = LZ4_compress_default(VARDATA_ANY(value), + (char *) tmp + VARHDRSZ_COMPRESSED, + valsize, max_size); + if (len <= 0) + elog(ERROR, "lz4 compression failed"); + + /* data is incompressible so just free the memory and return NULL */ + if (len > valsize) + { + pfree(tmp); + return NULL; + } + + SET_VARSIZE_COMPRESSED(tmp, len + VARHDRSZ_COMPRESSED); + + return tmp; +#endif +} + +/* + * Decompress a varlena that was compressed using LZ4. + */ +struct varlena * +lz4_decompress_datum(const struct varlena *value) +{ +#ifndef USE_LZ4 + NO_LZ4_SUPPORT(); + return NULL; /* keep compiler quiet */ +#else + int32 rawsize; + struct varlena *result; + + /* allocate memory for the uncompressed data */ + result = (struct varlena *) palloc(VARDATA_COMPRESSED_GET_EXTSIZE(value) + VARHDRSZ); + + /* decompress the data */ + rawsize = LZ4_decompress_safe((char *) value + VARHDRSZ_COMPRESSED, + VARDATA(result), + VARSIZE(value) - VARHDRSZ_COMPRESSED, + VARDATA_COMPRESSED_GET_EXTSIZE(value)); + if (rawsize < 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("compressed lz4 data is corrupt"))); + + + SET_VARSIZE(result, rawsize + VARHDRSZ); + + return result; +#endif +} + +/* + * Decompress part of a varlena that was compressed using LZ4. + */ +struct varlena * +lz4_decompress_datum_slice(const struct varlena *value, int32 slicelength) +{ +#ifndef USE_LZ4 + NO_LZ4_SUPPORT(); + return NULL; /* keep compiler quiet */ +#else + int32 rawsize; + struct varlena *result; + + /* slice decompression not supported prior to 1.8.3 */ + if (LZ4_versionNumber() < 10803) + return lz4_decompress_datum(value); + + /* allocate memory for the uncompressed data */ + result = (struct varlena *) palloc(slicelength + VARHDRSZ); + + /* decompress the data */ + rawsize = LZ4_decompress_safe_partial((char *) value + VARHDRSZ_COMPRESSED, + VARDATA(result), + VARSIZE(value) - VARHDRSZ_COMPRESSED, + slicelength, + slicelength); + if (rawsize < 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("compressed lz4 data is corrupt"))); + + SET_VARSIZE(result, rawsize + VARHDRSZ); + + return result; +#endif +} + +/* + * Extract compression ID from a varlena. + * + * Returns TOAST_INVALID_COMPRESSION_ID if the varlena is not compressed. + */ +ToastCompressionId +toast_get_compression_id(struct varlena *attr) +{ + ToastCompressionId cmid = TOAST_INVALID_COMPRESSION_ID; + + /* + * If it is stored externally then fetch the compression method id from + * the external toast pointer. If compressed inline, fetch it from the + * toast compression header. + */ + if (VARATT_IS_EXTERNAL_ONDISK(attr)) + { + struct varatt_external toast_pointer; + + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) + cmid = VARATT_EXTERNAL_GET_COMPRESS_METHOD(toast_pointer); + } + else if (VARATT_IS_COMPRESSED(attr)) + cmid = VARDATA_COMPRESSED_GET_COMPRESS_METHOD(attr); + + return cmid; +} + +/* + * CompressionNameToMethod - Get compression method from compression name + * + * Search in the available built-in methods. If the compression not found + * in the built-in methods then return InvalidCompressionMethod. + */ +char +CompressionNameToMethod(const char *compression) +{ + if (strcmp(compression, "pglz") == 0) + return TOAST_PGLZ_COMPRESSION; + else if (strcmp(compression, "lz4") == 0) + { +#ifndef USE_LZ4 + NO_LZ4_SUPPORT(); +#endif + return TOAST_LZ4_COMPRESSION; + } + + return InvalidCompressionMethod; +} + +/* + * GetCompressionMethodName - Get compression method name + */ +const char * +GetCompressionMethodName(char method) +{ + switch (method) + { + case TOAST_PGLZ_COMPRESSION: + return "pglz"; + case TOAST_LZ4_COMPRESSION: + return "lz4"; + default: + elog(ERROR, "invalid compression method %c", method); + return NULL; /* keep compiler quiet */ + } +} diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c index 9884ee8d3827..d8c1f9c180d3 100644 --- a/src/backend/access/common/toast_internals.c +++ b/src/backend/access/common/toast_internals.c @@ -3,7 +3,7 @@ * toast_internals.c * Functions for internal use by the TOAST system. * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/access/common/toast_internals.c @@ -47,46 +47,56 @@ static bool toastid_valueid_exists(Oid toastrelid, Oid valueid); * ---------- */ Datum -toast_compress_datum(Datum value) +toast_compress_datum(Datum value, char cmethod) { - struct varlena *tmp; - int32 valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value)); - int32 len; + struct varlena *tmp = NULL; + int32 valsize; + ToastCompressionId cmid = TOAST_INVALID_COMPRESSION_ID; Assert(!VARATT_IS_EXTERNAL(DatumGetPointer(value))); Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); + valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value)); + + /* If the compression method is not valid, use the current default */ + if (!CompressionMethodIsValid(cmethod)) + cmethod = default_toast_compression; + /* - * No point in wasting a palloc cycle if value size is out of the allowed - * range for compression + * Call appropriate compression routine for the compression method. */ - if (valsize < PGLZ_strategy_default->min_input_size || - valsize > PGLZ_strategy_default->max_input_size) - return PointerGetDatum(NULL); + switch (cmethod) + { + case TOAST_PGLZ_COMPRESSION: + tmp = pglz_compress_datum((const struct varlena *) value); + cmid = TOAST_PGLZ_COMPRESSION_ID; + break; + case TOAST_LZ4_COMPRESSION: + tmp = lz4_compress_datum((const struct varlena *) value); + cmid = TOAST_LZ4_COMPRESSION_ID; + break; + default: + elog(ERROR, "invalid compression method %c", cmethod); + } - tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) + - TOAST_COMPRESS_HDRSZ); + if (tmp == NULL) + return PointerGetDatum(NULL); /* - * We recheck the actual size even if pglz_compress() reports success, - * because it might be satisfied with having saved as little as one byte - * in the compressed data --- which could turn into a net loss once you - * consider header and alignment padding. Worst case, the compressed - * format might require three padding bytes (plus header, which is - * included in VARSIZE(tmp)), whereas the uncompressed format would take - * only one header byte and no padding if the value is short enough. So - * we insist on a savings of more than 2 bytes to ensure we have a gain. + * We recheck the actual size even if compression reports success, because + * it might be satisfied with having saved as little as one byte in the + * compressed data --- which could turn into a net loss once you consider + * header and alignment padding. Worst case, the compressed format might + * require three padding bytes (plus header, which is included in + * VARSIZE(tmp)), whereas the uncompressed format would take only one + * header byte and no padding if the value is short enough. So we insist + * on a savings of more than 2 bytes to ensure we have a gain. */ - len = pglz_compress(VARDATA_ANY(DatumGetPointer(value)), - valsize, - TOAST_COMPRESS_RAWDATA(tmp), - PGLZ_strategy_default); - if (len >= 0 && - len + TOAST_COMPRESS_HDRSZ < valsize - 2) + if (VARSIZE(tmp) < valsize - 2) { - TOAST_COMPRESS_SET_RAWSIZE(tmp, valsize); - SET_VARSIZE_COMPRESSED(tmp, len + TOAST_COMPRESS_HDRSZ); /* successful compression */ + Assert(cmid != TOAST_INVALID_COMPRESSION_ID); + TOAST_COMPRESS_SET_SIZE_AND_COMPRESS_METHOD(tmp, valsize, cmid); return PointerGetDatum(tmp); } else @@ -158,27 +168,32 @@ toast_save_datum(Relation rel, Datum value, &num_indexes); /* - * Get the data pointer and length, and compute va_rawsize and va_extsize. + * Get the data pointer and length, and compute va_rawsize and va_extinfo. * * va_rawsize is the size of the equivalent fully uncompressed datum, so * we have to adjust for short headers. * - * va_extsize is the actual size of the data payload in the toast records. + * va_extinfo stored the actual size of the data payload in the toast + * records and the compression method in first 2 bits if data is + * compressed. */ if (VARATT_IS_SHORT(dval)) { data_p = VARDATA_SHORT(dval); data_todo = VARSIZE_SHORT(dval) - VARHDRSZ_SHORT; toast_pointer.va_rawsize = data_todo + VARHDRSZ; /* as if not short */ - toast_pointer.va_extsize = data_todo; + toast_pointer.va_extinfo = data_todo; } else if (VARATT_IS_COMPRESSED(dval)) { data_p = VARDATA(dval); data_todo = VARSIZE(dval) - VARHDRSZ; /* rawsize in a compressed datum is just the size of the payload */ - toast_pointer.va_rawsize = VARRAWSIZE_4B_C(dval) + VARHDRSZ; - toast_pointer.va_extsize = data_todo; + toast_pointer.va_rawsize = VARDATA_COMPRESSED_GET_EXTSIZE(dval) + VARHDRSZ; + + /* set external size and compression method */ + VARATT_EXTERNAL_SET_SIZE_AND_COMPRESS_METHOD(toast_pointer, data_todo, + VARDATA_COMPRESSED_GET_COMPRESS_METHOD(dval)); /* Assert that the numbers look like it's compressed */ Assert(VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)); } @@ -187,7 +202,7 @@ toast_save_datum(Relation rel, Datum value, data_p = VARDATA(dval); data_todo = VARSIZE(dval) - VARHDRSZ; toast_pointer.va_rawsize = VARSIZE(dval); - toast_pointer.va_extsize = data_todo; + toast_pointer.va_extinfo = data_todo; } /* @@ -288,17 +303,17 @@ toast_save_datum(Relation rel, Datum value, { Assert(VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)); elog(DEBUG4, - "saved toast datum, original varsize %ud rawsize %ud new extsize %ud rawsize %uld\n", - VARSIZE(value), VARRAWSIZE_4B_C(value) + VARHDRSZ, - toast_pointer.va_extsize, toast_pointer.va_rawsize); + "saved toast datum, original varsize %ud new extinfo %u rawsize %ud\n", + VARSIZE(value), + toast_pointer.va_extinfo, toast_pointer.va_rawsize); } else { Assert(!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)); elog(DEBUG4, - "saved toast datum, original varsize %ud new extsize %ud rawsize %ud\n", + "saved toast datum, original varsize %ud new extinfo %u rawsize %ud\n", VARSIZE(value), - toast_pointer.va_extsize, toast_pointer.va_rawsize); + toast_pointer.va_extinfo, toast_pointer.va_rawsize); } #endif @@ -379,7 +394,7 @@ toast_save_datum(Relation rel, Datum value, toastrel, toastidxs[i]->rd_index->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, - NULL); + false, NULL); } /* @@ -676,8 +691,21 @@ init_toast_snapshot(Snapshot toast_snapshot) { Snapshot snapshot = GetOldestSnapshot(); + /* + * GetOldestSnapshot returns NULL if the session has no active snapshots. + * We can get that if, for example, a procedure fetches a toasted value + * into a local variable, commits, and then tries to detoast the value. + * Such coding is unsafe, because once we commit there is nothing to + * prevent the toast data from being deleted. Detoasting *must* happen in + * the same transaction that originally fetched the toast pointer. Hence, + * rather than trying to band-aid over the problem, throw an error. (This + * is not very much protection, because in many scenarios the procedure + * would have already created a new transaction snapshot, preventing us + * from detecting the problem. But it's better than nothing, and for sure + * we shouldn't expend code on masking the problem more.) + */ if (snapshot == NULL) - elog(ERROR, "no known snapshots"); + elog(ERROR, "cannot fetch toast data without an active snapshot"); InitToastSnapshot(*toast_snapshot, snapshot->lsn, snapshot->whenTaken); } diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c index 3cb0cbefaa36..64f54393f353 100644 --- a/src/backend/access/common/tupconvert.c +++ b/src/backend/access/common/tupconvert.c @@ -7,7 +7,7 @@ * equivalent but might have columns in a different order or different sets of * dropped columns. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -226,6 +226,57 @@ execute_attr_map_slot(AttrMap *attrMap, return out_slot; } +/* + * Perform conversion of bitmap of columns according to the map. + * + * The input and output bitmaps are offset by + * FirstLowInvalidHeapAttributeNumber to accommodate system cols, like the + * column-bitmaps in RangeTblEntry. + */ +Bitmapset * +execute_attr_map_cols(AttrMap *attrMap, Bitmapset *in_cols) +{ + Bitmapset *out_cols; + int out_attnum; + + /* fast path for the common trivial case */ + if (in_cols == NULL) + return NULL; + + /* + * For each output column, check which input column it corresponds to. + */ + out_cols = NULL; + + for (out_attnum = FirstLowInvalidHeapAttributeNumber; + out_attnum <= attrMap->maplen; + out_attnum++) + { + int in_attnum; + + if (out_attnum < 0) + { + /* System column. No mapping. */ + in_attnum = out_attnum; + } + else if (out_attnum == 0) + continue; + else + { + /* normal user column */ + in_attnum = attrMap->attnums[out_attnum - 1]; + + if (in_attnum == 0) + continue; + } + + if (bms_is_member(in_attnum - FirstLowInvalidHeapAttributeNumber, in_cols)) + out_cols = bms_add_member(out_cols, out_attnum - FirstLowInvalidHeapAttributeNumber); + } + + return out_cols; +} + /* * Free a TupleConversionMap structure. */ diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index efd22f1a4357..abd471e98dea 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -3,7 +3,7 @@ * tupdesc.c * POSTGRES tuple descriptor support code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,6 +20,7 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/toast_compression.h" #include "access/tupdesc_details.h" #include "catalog/pg_collation.h" #include "catalog/pg_type.h" @@ -173,10 +174,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) cpy->defval = (AttrDefault *) palloc(cpy->num_defval * sizeof(AttrDefault)); memcpy(cpy->defval, constr->defval, cpy->num_defval * sizeof(AttrDefault)); for (i = cpy->num_defval - 1; i >= 0; i--) - { - if (constr->defval[i].adbin) - cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin); - } + cpy->defval[i].adbin = pstrdup(constr->defval[i].adbin); } if (constr->missing) @@ -202,10 +200,8 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) memcpy(cpy->check, constr->check, cpy->num_check * sizeof(ConstrCheck)); for (i = cpy->num_check - 1; i >= 0; i--) { - if (constr->check[i].ccname) - cpy->check[i].ccname = pstrdup(constr->check[i].ccname); - if (constr->check[i].ccbin) - cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin); + cpy->check[i].ccname = pstrdup(constr->check[i].ccname); + cpy->check[i].ccbin = pstrdup(constr->check[i].ccbin); cpy->check[i].ccvalid = constr->check[i].ccvalid; cpy->check[i].ccnoinherit = constr->check[i].ccnoinherit; } @@ -327,10 +323,7 @@ FreeTupleDesc(TupleDesc tupdesc) AttrDefault *attrdef = tupdesc->constr->defval; for (i = tupdesc->constr->num_defval - 1; i >= 0; i--) - { - if (attrdef[i].adbin) - pfree(attrdef[i].adbin); - } + pfree(attrdef[i].adbin); pfree(attrdef); } if (tupdesc->constr->missing) @@ -351,10 +344,8 @@ FreeTupleDesc(TupleDesc tupdesc) for (i = tupdesc->constr->num_check - 1; i >= 0; i--) { - if (check[i].ccname) - pfree(check[i].ccname); - if (check[i].ccbin) - pfree(check[i].ccbin); + pfree(check[i].ccname); + pfree(check[i].ccbin); } pfree(check); } @@ -411,7 +402,6 @@ bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2, bool strict) { int i, - j, n; if (tupdesc1->natts != tupdesc2->natts) @@ -434,7 +424,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2, bool strict) * general it seems safer to check them always. * * attcacheoff must NOT be checked since it's possibly not set in both - * copies. + * copies. We also intentionally ignore atthasmissing, since that's + * not very relevant in tupdescs, which lack the attmissingval field. */ if (strcmp(NameStr(attr1->attname), NameStr(attr2->attname)) != 0) return false; @@ -450,31 +441,29 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2, bool strict) return false; if (attr1->attbyval != attr2->attbyval) return false; + if (attr1->attalign != attr2->attalign) + return false; if (attr1->attstorage != attr2->attstorage) return false; - if (attr1->attalign != attr2->attalign) + if (attr1->attcompression != attr2->attcompression) return false; - - if (strict) - { - if (attr1->attnotnull != attr2->attnotnull) - return false; - if (attr1->atthasdef != attr2->atthasdef) - return false; - if (attr1->attidentity != attr2->attidentity) - return false; - if (attr1->attgenerated != attr2->attgenerated) - return false; - if (attr1->attisdropped != attr2->attisdropped) - return false; - if (attr1->attislocal != attr2->attislocal) - return false; - if (attr1->attinhcount != attr2->attinhcount) - return false; - if (attr1->attcollation != attr2->attcollation) - return false; - /* attacl and attoptions are not even present... */ - } + if (attr1->attnotnull != attr2->attnotnull) + return false; + if (attr1->atthasdef != attr2->atthasdef) + return false; + if (attr1->attidentity != attr2->attidentity) + return false; + if (attr1->attgenerated != attr2->attgenerated) + return false; + if (attr1->attisdropped != attr2->attisdropped) + return false; + if (attr1->attislocal != attr2->attislocal) + return false; + if (attr1->attinhcount != attr2->attinhcount) + return false; + if (attr1->attcollation != attr2->attcollation) + return false; + /* variable-length fields are not even present... */ } if (!strict) @@ -494,22 +483,13 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2, bool strict) n = constr1->num_defval; if (n != (int) constr2->num_defval) return false; + /* We assume here that both AttrDefault arrays are in adnum order */ for (i = 0; i < n; i++) { AttrDefault *defval1 = constr1->defval + i; - AttrDefault *defval2 = constr2->defval; - - /* - * We can't assume that the items are always read from the system - * catalogs in the same order; so use the adnum field to identify - * the matching item to compare. - */ - for (j = 0; j < n; defval2++, j++) - { - if (defval1->adnum == defval2->adnum) - break; - } - if (j >= n) + AttrDefault *defval2 = constr2->defval + i; + + if (defval1->adnum != defval2->adnum) return false; if (strcmp(defval1->adbin, defval2->adbin) != 0) return false; @@ -540,25 +520,21 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2, bool strict) n = constr1->num_check; if (n != (int) constr2->num_check) return false; + + /* + * Similarly, we rely here on the ConstrCheck entries being sorted by + * name. If there are duplicate names, the outcome of the comparison + * is uncertain, but that should not happen. + */ for (i = 0; i < n; i++) { ConstrCheck *check1 = constr1->check + i; - ConstrCheck *check2 = constr2->check; - - /* - * Similarly, don't assume that the checks are always read in the - * same order; match them up by name and contents. (The name - * *should* be unique, but...) - */ - for (j = 0; j < n; check2++, j++) - { - if (strcmp(check1->ccname, check2->ccname) == 0 && - strcmp(check1->ccbin, check2->ccbin) == 0 && - check1->ccvalid == check2->ccvalid && - check1->ccnoinherit == check2->ccnoinherit) - break; - } - if (j >= n) + ConstrCheck *check2 = constr2->check + i; + + if (!(strcmp(check1->ccname, check2->ccname) == 0 && + strcmp(check1->ccbin, check2->ccbin) == 0 && + check1->ccvalid == check2->ccvalid && + check1->ccnoinherit == check2->ccnoinherit)) return false; } } @@ -669,6 +645,7 @@ TupleDescInitEntry(TupleDesc desc, att->attbyval = typeForm->typbyval; att->attalign = typeForm->typalign; att->attstorage = typeForm->typstorage; + att->attcompression = InvalidCompressionMethod; att->attcollation = typeForm->typcollation; ReleaseSysCache(tuple); @@ -734,6 +711,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, att->attbyval = false; att->attalign = TYPALIGN_INT; att->attstorage = TYPSTORAGE_EXTENDED; + att->attcompression = InvalidCompressionMethod; att->attcollation = DEFAULT_COLLATION_OID; break; @@ -742,6 +720,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, att->attbyval = true; att->attalign = TYPALIGN_CHAR; att->attstorage = TYPSTORAGE_PLAIN; + att->attcompression = InvalidCompressionMethod; att->attcollation = InvalidOid; break; @@ -750,6 +729,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, att->attbyval = true; att->attalign = TYPALIGN_INT; att->attstorage = TYPSTORAGE_PLAIN; + att->attcompression = InvalidCompressionMethod; att->attcollation = InvalidOid; break; @@ -758,6 +738,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, att->attbyval = FLOAT8PASSBYVAL; att->attalign = TYPALIGN_DOUBLE; att->attstorage = TYPSTORAGE_PLAIN; + att->attcompression = InvalidCompressionMethod; att->attcollation = InvalidOid; break; diff --git a/src/backend/access/gin/README b/src/backend/access/gin/README index 125a82219b9e..41d4e1e8a093 100644 --- a/src/backend/access/gin/README +++ b/src/backend/access/gin/README @@ -413,7 +413,7 @@ leftmost leaf of the tree. Deletion algorithm keeps exclusive locks on left siblings of pages comprising currently investigated path. Thus, if current page is to be removed, all required pages to remove both downlink and rightlink are already locked. That -evades potential right to left page locking order, which could deadlock with +avoids potential right to left page locking order, which could deadlock with concurrent stepping right. A search concurrent to page deletion might already have read a pointer to the diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c index 3a6d54b38ce1..bf73e32932e0 100644 --- a/src/backend/access/gin/ginarrayproc.c +++ b/src/backend/access/gin/ginarrayproc.c @@ -4,7 +4,7 @@ * support functions for GIN's indexing of any array * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c index 8d08b05f5156..482cf10877cd 100644 --- a/src/backend/access/gin/ginbtree.c +++ b/src/backend/access/gin/ginbtree.c @@ -4,7 +4,7 @@ * page utilities routines for the postgres inverted index access method. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -241,7 +241,6 @@ ginFindParents(GinBtree btree, GinBtreeStack *stack) blkno = root->blkno; buffer = root->buffer; - offset = InvalidOffsetNumber; ptr = (GinBtreeStack *) palloc(sizeof(GinBtreeStack)); diff --git a/src/backend/access/gin/ginbulk.c b/src/backend/access/gin/ginbulk.c index 9008c125fe99..4c5067ccf96e 100644 --- a/src/backend/access/gin/ginbulk.c +++ b/src/backend/access/gin/ginbulk.c @@ -4,7 +4,7 @@ * routines for fast build of inverted index * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c index 45ddd5fc991d..c101cbc0e30b 100644 --- a/src/backend/access/gin/gindatapage.c +++ b/src/backend/access/gin/gindatapage.c @@ -4,7 +4,7 @@ * routines for handling GIN posting tree pages. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginentrypage.c b/src/backend/access/gin/ginentrypage.c index 21f549b60e84..224fe666e103 100644 --- a/src/backend/access/gin/ginentrypage.c +++ b/src/backend/access/gin/ginentrypage.c @@ -4,7 +4,7 @@ * routines for handling GIN entry tree pages. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index 2e41b34d8d51..e0d99409461c 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -7,7 +7,7 @@ * transfer pending entries into the regular index structure. This * wins because bulk insertion is much more efficient than retail. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index 4b36f927c03c..653aa506f059 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -4,7 +4,7 @@ * fetch tuples from a GIN scan. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -264,24 +264,28 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack, /* Search forward to re-find idatum */ for (;;) { - Datum newDatum; - GinNullCategory newCategory; - if (moveRightIfItNeeded(btree, stack, snapshot) == false) - elog(ERROR, "lost saved point in index"); /* must not happen !!! */ + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("failed to re-find tuple within index \"%s\"", + RelationGetRelationName(btree->index)))); page = BufferGetPage(stack->buffer); itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, stack->off)); - if (gintuple_get_attrnum(btree->ginstate, itup) != attnum) - elog(ERROR, "lost saved point in index"); /* must not happen !!! */ - newDatum = gintuple_get_key(btree->ginstate, itup, - &newCategory); + if (gintuple_get_attrnum(btree->ginstate, itup) == attnum) + { + Datum newDatum; + GinNullCategory newCategory; + + newDatum = gintuple_get_key(btree->ginstate, itup, + &newCategory); - if (ginCompareEntries(btree->ginstate, attnum, - newDatum, newCategory, - idatum, icategory) == 0) - break; /* Found! */ + if (ginCompareEntries(btree->ginstate, attnum, + newDatum, newCategory, + idatum, icategory) == 0) + break; /* Found! */ + } stack->off++; } diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index 77433dc8a41e..0e8672c9e90c 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -4,7 +4,7 @@ * insert routines for the postgres inverted index access method. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -488,6 +488,7 @@ bool gininsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { GinState *ginstate = (GinState *) indexInfo->ii_AmCache; diff --git a/src/backend/access/gin/ginlogic.c b/src/backend/access/gin/ginlogic.c index bcbc26efdb67..6bf3288f5b9e 100644 --- a/src/backend/access/gin/ginlogic.c +++ b/src/backend/access/gin/ginlogic.c @@ -24,7 +24,7 @@ * is used for.) * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c index 221859bb5f2f..863f5fe976f9 100644 --- a/src/backend/access/gin/ginpostinglist.c +++ b/src/backend/access/gin/ginpostinglist.c @@ -4,7 +4,7 @@ * routines for dealing with posting lists. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c index 0a685bdbfc65..55e2d49fd722 100644 --- a/src/backend/access/gin/ginscan.c +++ b/src/backend/access/gin/ginscan.c @@ -4,7 +4,7 @@ * routines to manage scans of inverted index relations * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index ef9b56fd363a..cdd626ff0a44 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -4,7 +4,7 @@ * Utility routines for the Postgres inverted index access method. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -348,7 +348,6 @@ GinInitPage(Page page, uint32 f, Size pageSize) PageInit(page, pageSize, sizeof(GinPageOpaqueData)); opaque = GinPageGetOpaque(page); - memset(opaque, 0, sizeof(GinPageOpaqueData)); opaque->flags = f; opaque->rightlink = InvalidBlockNumber; } diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index 9cd6638df621..a276eb020b5d 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -4,7 +4,7 @@ * delete & vacuum routines for the postgres GIN * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -189,7 +189,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn * address. */ GinPageSetDeleted(page); - GinPageSetDeleteXid(page, ReadNewTransactionId()); + GinPageSetDeleteXid(page, ReadNextTransactionId()); MarkBufferDirty(pBuffer); MarkBufferDirty(lBuffer); @@ -231,6 +231,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn END_CRIT_SECTION(); + gvs->result->pages_newly_deleted++; gvs->result->pages_deleted++; } @@ -727,7 +728,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) * entries. This is bogus if the index is partial, but it's real hard to * tell how many distinct heap entries are referenced by a GIN index. */ - stats->num_index_tuples = info->num_heap_tuples; + stats->num_index_tuples = Max(info->num_heap_tuples, 0); stats->estimated_count = info->estimated_count; /* diff --git a/src/backend/access/gin/ginvalidate.c b/src/backend/access/gin/ginvalidate.c index 60ce1ae10663..d2510daadb38 100644 --- a/src/backend/access/gin/ginvalidate.c +++ b/src/backend/access/gin/ginvalidate.c @@ -3,7 +3,7 @@ * ginvalidate.c * Opclass validator for GIN. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c index 9f8640565bf9..09ce4d6a5ba5 100644 --- a/src/backend/access/gin/ginxlog.c +++ b/src/backend/access/gin/ginxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for inverted index. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gist/README b/src/backend/access/gist/README index fffdfff6e17a..25cab0047b65 100644 --- a/src/backend/access/gist/README +++ b/src/backend/access/gist/README @@ -10,6 +10,7 @@ GiST stands for Generalized Search Tree. It was introduced in the seminal paper Jeffrey F. Naughton, Avi Pfeffer: http://www.sai.msu.su/~megera/postgres/gist/papers/gist.ps + https://dsf.berkeley.edu/papers/sigmod97-gist.pdf and implemented by J. Hellerstein and P. Aoki in an early version of PostgreSQL (more details are available from The GiST Indexing Project @@ -92,10 +93,10 @@ index child page to be split between the time we make a queue entry for it (while visiting its parent page) and the time we actually reach and scan the child page. To avoid missing the entries that were moved to the right sibling, we detect whether a split has occurred by comparing the child -page's NSN to the LSN that the parent had when visited. If it did, the -sibling page is immediately added to the front of the queue, ensuring that -its items will be scanned in the same order as if they were still on the -original child page. +page's NSN (node sequence number, a special-purpose LSN) to the LSN that +the parent had when visited. If it did, the sibling page is immediately +added to the front of the queue, ensuring that its items will be scanned +in the same order as if they were still on the original child page. As is usual in Postgres, the search algorithm only guarantees to find index entries that existed before the scan started; index entries added during diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 2d6566e7304e..3e021ac25276 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -4,7 +4,7 @@ * interface routines for the postgres GiST index access method. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -156,6 +156,7 @@ bool gistinsert(Relation r, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { GISTSTATE *giststate = (GISTSTATE *) indexInfo->ii_AmCache; @@ -247,6 +248,9 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, if (GistFollowRight(page)) elog(ERROR, "concurrent GiST page split was incomplete"); + /* should never try to insert to a deleted page */ + Assert(!GistPageIsDeleted(page)); + *splitinfo = NIL; /* @@ -862,7 +866,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, */ } else if ((GistFollowRight(stack->page) || - stack->parent->lsn < GistPageGetNSN(stack->page)) && + stack->parent->lsn < GistPageGetNSN(stack->page)) || GistPageIsDeleted(stack->page)) { /* @@ -1167,8 +1171,9 @@ gistfixsplit(GISTInsertState *state, GISTSTATE *giststate) Page page; List *splitinfo = NIL; - elog(LOG, "fixing incomplete split in index \"%s\", block %u", - RelationGetRelationName(state->r), stack->blkno); + ereport(LOG, + (errmsg("fixing incomplete split in index \"%s\", block %u", + RelationGetRelationName(state->r), stack->blkno))); Assert(GistFollowRight(stack->page)); Assert(OffsetNumberIsValid(stack->downlinkoffnum)); @@ -1640,7 +1645,6 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel) int ndeletable = 0; OffsetNumber offnum, maxoff; - TransactionId latestRemovedXid = InvalidTransactionId; Assert(GistPageIsLeaf(page)); @@ -1659,13 +1663,15 @@ gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel) deletable[ndeletable++] = offnum; } - if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) - latestRemovedXid = - index_compute_xid_horizon_for_tuples(rel, heapRel, buffer, - deletable, ndeletable); - if (ndeletable > 0) { + TransactionId latestRemovedXid = InvalidTransactionId; + + if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) + latestRemovedXid = + index_compute_xid_horizon_for_tuples(rel, heapRel, buffer, + deletable, ndeletable); + START_CRIT_SECTION(); PageIndexMultiDelete(page, deletable, ndeletable); diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 671b5e9186ff..f46a42197c97 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -3,8 +3,26 @@ * gistbuild.c * build algorithm for GiST indexes implementation. * + * There are two different strategies: * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * 1. Sort all input tuples, pack them into GiST leaf pages in the sorted + * order, and create downlinks and internal pages as we go. This builds + * the index from the bottom up, similar to how B-tree index build + * works. + * + * 2. Start with an empty index, and insert all tuples one by one. + * + * The sorted method is used if the operator classes for all columns have + * a 'sortsupport' defined. Otherwise, we resort to the second strategy. + * + * The second strategy can optionally use buffers at different levels of + * the tree to reduce I/O, see "Buffering build algorithm" in the README + * for a more detailed explanation. It initially calls insert over and + * over, but switches to the buffered algorithm after a certain number of + * tuples (unless buffering mode is disabled). + * + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,6 +46,7 @@ #include "storage/smgr.h" #include "utils/memutils.h" #include "utils/rel.h" +#include "utils/tuplesort.h" /* Step of index tuples for check whether to switch to buffering build mode */ #define BUFFERING_MODE_SWITCH_CHECK_STEP 256 @@ -40,8 +59,14 @@ */ #define BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET 4096 +/* + * Strategy used to build the index. It can change between the + * GIST_BUFFERING_* modes on the fly, but if the Sorted method is used, + * that needs to be decided up-front and cannot be changed afterwards. + */ typedef enum { + GIST_SORTED_BUILD, /* bottom-up build by sorting */ GIST_BUFFERING_DISABLED, /* in regular build mode and aren't going to * switch */ GIST_BUFFERING_AUTO, /* in regular build mode, but will switch to @@ -51,7 +76,7 @@ typedef enum * before switching to the buffering build * mode */ GIST_BUFFERING_ACTIVE /* in buffering build mode */ -} GistBufferingMode; +} GistBuildMode; /* Working state for gistbuild and its callback */ typedef struct @@ -60,23 +85,58 @@ typedef struct Relation heaprel; GISTSTATE *giststate; - int64 indtuples; /* number of tuples indexed */ - int64 indtuplesSize; /* total size of all indexed tuples */ - Size freespace; /* amount of free space to leave on pages */ + GistBuildMode buildMode; + + int64 indtuples; /* number of tuples indexed */ + /* * Extra data structures used during a buffering build. 'gfbb' contains * information related to managing the build buffers. 'parentMap' is a * lookup table of the parent of each internal page. */ + int64 indtuplesSize; /* total size of all indexed tuples */ GISTBuildBuffers *gfbb; HTAB *parentMap; - GistBufferingMode bufferingMode; + /* + * Extra data structures used during a sorting build. + */ + Tuplesortstate *sortstate; /* state data for tuplesort.c */ + + BlockNumber pages_allocated; + BlockNumber pages_written; + + int ready_num_pages; + BlockNumber ready_blknos[XLR_MAX_BLOCK_ID]; + Page ready_pages[XLR_MAX_BLOCK_ID]; } GISTBuildState; +/* + * In sorted build, we use a stack of these structs, one for each level, + * to hold an in-memory buffer of the rightmost page at the level. When the + * page fills up, it is written out and a new page is allocated. + */ +typedef struct GistSortedBuildPageState +{ + Page page; + struct GistSortedBuildPageState *parent; /* Upper level, if any */ +} GistSortedBuildPageState; + /* prototypes for private functions */ + +static void gistSortedBuildCallback(Relation index, ItemPointer tid, + Datum *values, bool *isnull, + bool tupleIsAlive, void *state); +static void gist_indexsortbuild(GISTBuildState *state); +static void gist_indexsortbuild_pagestate_add(GISTBuildState *state, + GistSortedBuildPageState *pagestate, + IndexTuple itup); +static void gist_indexsortbuild_pagestate_flush(GISTBuildState *state, + GistSortedBuildPageState *pagestate); +static void gist_indexsortbuild_flush_ready_pages(GISTBuildState *state); + static void gistInitBuffering(GISTBuildState *buildstate); static int calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep); static void gistBuildCallback(Relation index, @@ -107,10 +167,9 @@ static void gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, static void gistMemorizeAllDownlinks(GISTBuildState *buildstate, Buffer parent); static BlockNumber gistGetParent(GISTBuildState *buildstate, BlockNumber child); + /* - * Main entry point to GiST index build. Initially calls insert over and over, - * but switches to more efficient buffering build algorithm after a certain - * number of tuples (unless buffering mode is disabled). + * Main entry point to GiST index build. */ IndexBuildResult * gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) @@ -118,124 +177,425 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) IndexBuildResult *result; double reltuples; GISTBuildState buildstate; - Buffer buffer; - Page page; MemoryContext oldcxt = CurrentMemoryContext; int fillfactor; + Oid SortSupportFnOids[INDEX_MAX_KEYS]; + GiSTOptions *options = (GiSTOptions *) index->rd_options; + + /* + * We expect to be called exactly once for any index relation. If that's + * not the case, big trouble's what we have. + */ + if (RelationGetNumberOfBlocks(index) != 0) + elog(ERROR, "index \"%s\" already contains data", + RelationGetRelationName(index)); buildstate.indexrel = index; buildstate.heaprel = heap; + buildstate.sortstate = NULL; + buildstate.giststate = initGISTstate(index); - if (index->rd_options) - { - /* Get buffering mode from the options string */ - GiSTOptions *options = (GiSTOptions *) index->rd_options; + /* + * Create a temporary memory context that is reset once for each tuple + * processed. (Note: we don't bother to make this a child of the + * giststate's scanCxt, so we have to delete it separately at the end.) + */ + buildstate.giststate->tempCxt = createTempGistContext(); + /* + * Choose build strategy. First check whether the user specified to use + * buffering mode. (The use-case for that in the field is somewhat + * questionable perhaps, but it's important for testing purposes.) + */ + if (options) + { if (options->buffering_mode == GIST_OPTION_BUFFERING_ON) - buildstate.bufferingMode = GIST_BUFFERING_STATS; + buildstate.buildMode = GIST_BUFFERING_STATS; else if (options->buffering_mode == GIST_OPTION_BUFFERING_OFF) - buildstate.bufferingMode = GIST_BUFFERING_DISABLED; - else - buildstate.bufferingMode = GIST_BUFFERING_AUTO; - - fillfactor = options->fillfactor; + buildstate.buildMode = GIST_BUFFERING_DISABLED; + else /* must be "auto" */ + buildstate.buildMode = GIST_BUFFERING_AUTO; } else { - /* - * By default, switch to buffering mode when the index grows too large - * to fit in cache. - */ - buildstate.bufferingMode = GIST_BUFFERING_AUTO; - fillfactor = GIST_DEFAULT_FILLFACTOR; + buildstate.buildMode = GIST_BUFFERING_AUTO; + } + + /* + * Unless buffering mode was forced, see if we can use sorting instead. + */ + if (buildstate.buildMode != GIST_BUFFERING_STATS) + { + bool hasallsortsupports = true; + int keyscount = IndexRelationGetNumberOfKeyAttributes(index); + + for (int i = 0; i < keyscount; i++) + { + SortSupportFnOids[i] = index_getprocid(index, i + 1, + GIST_SORTSUPPORT_PROC); + if (!OidIsValid(SortSupportFnOids[i])) + { + hasallsortsupports = false; + break; + } + } + if (hasallsortsupports) + buildstate.buildMode = GIST_SORTED_BUILD; } - /* Calculate target amount of free space to leave on pages */ + + /* + * Calculate target amount of free space to leave on pages. + */ + fillfactor = options ? options->fillfactor : GIST_DEFAULT_FILLFACTOR; buildstate.freespace = BLCKSZ * (100 - fillfactor) / 100; /* - * We expect to be called exactly once for any index relation. If that's - * not the case, big trouble's what we have. + * Build the index using the chosen strategy. */ - if (RelationGetNumberOfBlocks(index) != 0) - elog(ERROR, "index \"%s\" already contains data", - RelationGetRelationName(index)); + buildstate.indtuples = 0; + buildstate.indtuplesSize = 0; - /* no locking is needed */ - buildstate.giststate = initGISTstate(index); + if (buildstate.buildMode == GIST_SORTED_BUILD) + { + /* + * Sort all data, build the index from bottom up. + */ + buildstate.sortstate = tuplesort_begin_index_gist(heap, + index, + maintenance_work_mem, + NULL, + false); + + /* Scan the table, adding all tuples to the tuplesort */ + reltuples = table_index_build_scan(heap, index, indexInfo, true, true, + gistSortedBuildCallback, + (void *) &buildstate, NULL); + + /* + * Perform the sort and build index pages. + */ + tuplesort_performsort(buildstate.sortstate); + + gist_indexsortbuild(&buildstate); + + tuplesort_end(buildstate.sortstate); + } + else + { + /* + * Initialize an empty index and insert all tuples, possibly using + * buffers on intermediate levels. + */ + Buffer buffer; + Page page; + + /* initialize the root page */ + buffer = gistNewBuffer(index); + Assert(BufferGetBlockNumber(buffer) == GIST_ROOT_BLKNO); + page = BufferGetPage(buffer); + + START_CRIT_SECTION(); + + GISTInitBuffer(buffer, F_LEAF); + + MarkBufferDirty(buffer); + PageSetLSN(page, GistBuildLSN); + + UnlockReleaseBuffer(buffer); + + END_CRIT_SECTION(); + + /* Scan the table, inserting all the tuples to the index. */ + reltuples = table_index_build_scan(heap, index, indexInfo, true, true, + gistBuildCallback, + (void *) &buildstate, NULL); + + /* + * If buffering was used, flush out all the tuples that are still in + * the buffers. + */ + if (buildstate.buildMode == GIST_BUFFERING_ACTIVE) + { + elog(DEBUG1, "all tuples processed, emptying buffers"); + gistEmptyAllBuffers(&buildstate); + gistFreeBuildBuffers(buildstate.gfbb); + } + + /* + * We didn't write WAL records as we built the index, so if + * WAL-logging is required, write all pages to the WAL now. + */ + if (RelationNeedsWAL(index)) + { + log_newpage_range(index, MAIN_FORKNUM, + 0, RelationGetNumberOfBlocks(index), + true); + } + } + + /* okay, all heap tuples are indexed */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(buildstate.giststate->tempCxt); + + freeGISTstate(buildstate.giststate); /* - * Create a temporary memory context that is reset once for each tuple - * processed. (Note: we don't bother to make this a child of the - * giststate's scanCxt, so we have to delete it separately at the end.) + * Return statistics */ - buildstate.giststate->tempCxt = createTempGistContext(); + result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); - /* initialize the root page */ - buffer = gistNewBuffer(index); - Assert(BufferGetBlockNumber(buffer) == GIST_ROOT_BLKNO); - page = BufferGetPage(buffer); + result->heap_tuples = reltuples; + result->index_tuples = (double) buildstate.indtuples; + + return result; +} + +/*------------------------------------------------------------------------- + * Routines for sorted build + *------------------------------------------------------------------------- + */ + +/* + * Per-tuple callback for table_index_build_scan. + */ +static void +gistSortedBuildCallback(Relation index, + ItemPointer tid, + Datum *values, + bool *isnull, + bool tupleIsAlive, + void *state) +{ + GISTBuildState *buildstate = (GISTBuildState *) state; + MemoryContext oldCtx; + Datum compressed_values[INDEX_MAX_KEYS]; - START_CRIT_SECTION(); + oldCtx = MemoryContextSwitchTo(buildstate->giststate->tempCxt); - GISTInitBuffer(buffer, F_LEAF); + /* Form an index tuple and point it at the heap tuple */ + gistCompressValues(buildstate->giststate, index, + values, isnull, + true, compressed_values); - MarkBufferDirty(buffer); - PageSetLSN(page, GistBuildLSN); + tuplesort_putindextuplevalues(buildstate->sortstate, + buildstate->indexrel, + tid, + compressed_values, isnull); - UnlockReleaseBuffer(buffer); + MemoryContextSwitchTo(oldCtx); + MemoryContextReset(buildstate->giststate->tempCxt); - END_CRIT_SECTION(); + /* Update tuple count. */ + buildstate->indtuples += 1; +} - /* build the index */ - buildstate.indtuples = 0; - buildstate.indtuplesSize = 0; +/* + * Build GiST index from bottom up from pre-sorted tuples. + */ +static void +gist_indexsortbuild(GISTBuildState *state) +{ + IndexTuple itup; + GistSortedBuildPageState *leafstate; + GistSortedBuildPageState *pagestate; + Page page; + + state->pages_allocated = 0; + state->pages_written = 0; + state->ready_num_pages = 0; /* - * Do the heap scan. + * Write an empty page as a placeholder for the root page. It will be + * replaced with the real root page at the end. */ - reltuples = table_index_build_scan(heap, index, indexInfo, true, true, - gistBuildCallback, - (void *) &buildstate, NULL); + page = palloc0(BLCKSZ); + RelationOpenSmgr(state->indexrel); + smgrextend(state->indexrel->rd_smgr, MAIN_FORKNUM, GIST_ROOT_BLKNO, + page, true); + state->pages_allocated++; + state->pages_written++; + + /* Allocate a temporary buffer for the first leaf page. */ + leafstate = palloc(sizeof(GistSortedBuildPageState)); + leafstate->page = page; + leafstate->parent = NULL; + gistinitpage(page, F_LEAF); /* - * If buffering was used, flush out all the tuples that are still in the - * buffers. + * Fill index pages with tuples in the sorted order. */ - if (buildstate.bufferingMode == GIST_BUFFERING_ACTIVE) + while ((itup = tuplesort_getindextuple(state->sortstate, true)) != NULL) { - elog(DEBUG1, "all tuples processed, emptying buffers"); - gistEmptyAllBuffers(&buildstate); - gistFreeBuildBuffers(buildstate.gfbb); + gist_indexsortbuild_pagestate_add(state, leafstate, itup); + MemoryContextReset(state->giststate->tempCxt); } - /* okay, all heap tuples are indexed */ - MemoryContextSwitchTo(oldcxt); - MemoryContextDelete(buildstate.giststate->tempCxt); + /* + * Write out the partially full non-root pages. + * + * Keep in mind that flush can build a new root. + */ + pagestate = leafstate; + while (pagestate->parent != NULL) + { + GistSortedBuildPageState *parent; - freeGISTstate(buildstate.giststate); + gist_indexsortbuild_pagestate_flush(state, pagestate); + parent = pagestate->parent; + pfree(pagestate->page); + pfree(pagestate); + pagestate = parent; + } + + gist_indexsortbuild_flush_ready_pages(state); + + /* Write out the root */ + RelationOpenSmgr(state->indexrel); + PageSetLSN(pagestate->page, GistBuildLSN); + PageSetChecksumInplace(pagestate->page, GIST_ROOT_BLKNO); + smgrwrite(state->indexrel->rd_smgr, MAIN_FORKNUM, GIST_ROOT_BLKNO, + pagestate->page, true); + if (RelationNeedsWAL(state->indexrel)) + log_newpage(&state->indexrel->rd_node, MAIN_FORKNUM, GIST_ROOT_BLKNO, + pagestate->page, true); + + pfree(pagestate->page); + pfree(pagestate); +} + +/* + * Add tuple to a page. If the pages is full, write it out and re-initialize + * a new page first. + */ +static void +gist_indexsortbuild_pagestate_add(GISTBuildState *state, + GistSortedBuildPageState *pagestate, + IndexTuple itup) +{ + Size sizeNeeded; + + /* Does the tuple fit? If not, flush */ + sizeNeeded = IndexTupleSize(itup) + sizeof(ItemIdData) + state->freespace; + if (PageGetFreeSpace(pagestate->page) < sizeNeeded) + gist_indexsortbuild_pagestate_flush(state, pagestate); + + gistfillbuffer(pagestate->page, &itup, 1, InvalidOffsetNumber); +} + +static void +gist_indexsortbuild_pagestate_flush(GISTBuildState *state, + GistSortedBuildPageState *pagestate) +{ + GistSortedBuildPageState *parent; + IndexTuple *itvec; + IndexTuple union_tuple; + int vect_len; + bool isleaf; + BlockNumber blkno; + MemoryContext oldCtx; + + /* check once per page */ + CHECK_FOR_INTERRUPTS(); + + if (state->ready_num_pages == XLR_MAX_BLOCK_ID) + gist_indexsortbuild_flush_ready_pages(state); + + /* + * The page is now complete. Assign a block number to it, and add it to + * the list of finished pages. (We don't write it out immediately, because + * we want to WAL-log the pages in batches.) + */ + blkno = state->pages_allocated++; + state->ready_blknos[state->ready_num_pages] = blkno; + state->ready_pages[state->ready_num_pages] = pagestate->page; + state->ready_num_pages++; + + isleaf = GistPageIsLeaf(pagestate->page); + + /* + * Form a downlink tuple to represent all the tuples on the page. + */ + oldCtx = MemoryContextSwitchTo(state->giststate->tempCxt); + itvec = gistextractpage(pagestate->page, &vect_len); + union_tuple = gistunion(state->indexrel, itvec, vect_len, + state->giststate); + ItemPointerSetBlockNumber(&(union_tuple->t_tid), blkno); + MemoryContextSwitchTo(oldCtx); /* - * We didn't write WAL records as we built the index, so if WAL-logging is - * required, write all pages to the WAL now. + * Insert the downlink to the parent page. If this was the root, create a + * new page as the parent, which becomes the new root. */ - if (RelationNeedsWAL(index)) + parent = pagestate->parent; + if (parent == NULL) { - log_newpage_range(index, MAIN_FORKNUM, - 0, RelationGetNumberOfBlocks(index), - true); + parent = palloc(sizeof(GistSortedBuildPageState)); + parent->page = (Page) palloc(BLCKSZ); + parent->parent = NULL; + gistinitpage(parent->page, 0); + + pagestate->parent = parent; } + gist_indexsortbuild_pagestate_add(state, parent, union_tuple); + + /* Re-initialize the page buffer for next page on this level. */ + pagestate->page = palloc(BLCKSZ); + gistinitpage(pagestate->page, isleaf ? F_LEAF : 0); /* - * Return statistics + * Set the right link to point to the previous page. This is just for + * debugging purposes: GiST only follows the right link if a page is split + * concurrently to a scan, and that cannot happen during index build. + * + * It's a bit counterintuitive that we set the right link on the new page + * to point to the previous page, and not the other way round. But GiST + * pages are not ordered like B-tree pages are, so as long as the + * right-links form a chain through all the pages in the same level, the + * order doesn't matter. */ - result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + GistPageGetOpaque(pagestate->page)->rightlink = blkno; +} - result->heap_tuples = reltuples; - result->index_tuples = (double) buildstate.indtuples; +static void +gist_indexsortbuild_flush_ready_pages(GISTBuildState *state) +{ + if (state->ready_num_pages == 0) + return; - return result; + RelationOpenSmgr(state->indexrel); + + for (int i = 0; i < state->ready_num_pages; i++) + { + Page page = state->ready_pages[i]; + BlockNumber blkno = state->ready_blknos[i]; + + /* Currently, the blocks must be buffered in order. */ + if (blkno != state->pages_written) + elog(ERROR, "unexpected block number to flush GiST sorting build"); + + PageSetLSN(page, GistBuildLSN); + PageSetChecksumInplace(page, blkno); + smgrextend(state->indexrel->rd_smgr, MAIN_FORKNUM, blkno, page, true); + + state->pages_written++; + } + + if (RelationNeedsWAL(state->indexrel)) + log_newpages(&state->indexrel->rd_node, MAIN_FORKNUM, state->ready_num_pages, + state->ready_blknos, state->ready_pages, true); + + for (int i = 0; i < state->ready_num_pages; i++) + pfree(state->ready_pages[i]); + + state->ready_num_pages = 0; } + +/*------------------------------------------------------------------------- + * Routines for non-sorted build + *------------------------------------------------------------------------- + */ + /* * Attempt to switch to buffering mode. * @@ -375,7 +735,7 @@ gistInitBuffering(GISTBuildState *buildstate) if (levelStep <= 0) { elog(DEBUG1, "failed to switch to buffered GiST build"); - buildstate->bufferingMode = GIST_BUFFERING_DISABLED; + buildstate->buildMode = GIST_BUFFERING_DISABLED; return; } @@ -392,7 +752,7 @@ gistInitBuffering(GISTBuildState *buildstate) gistInitParentMap(buildstate); - buildstate->bufferingMode = GIST_BUFFERING_ACTIVE; + buildstate->buildMode = GIST_BUFFERING_ACTIVE; elog(DEBUG1, "switched to buffered GiST build; level step = %d, pagesPerBuffer = %d", levelStep, pagesPerBuffer); @@ -453,10 +813,12 @@ gistBuildCallback(Relation index, oldCtx = MemoryContextSwitchTo(buildstate->giststate->tempCxt); /* form an index tuple and point it at the heap tuple */ - itup = gistFormTuple(buildstate->giststate, index, values, isnull, true); + itup = gistFormTuple(buildstate->giststate, index, + values, isnull, + true); itup->t_tid = *tid; - if (buildstate->bufferingMode == GIST_BUFFERING_ACTIVE) + if (buildstate->buildMode == GIST_BUFFERING_ACTIVE) { /* We have buffers, so use them. */ gistBufferingBuildInsert(buildstate, itup); @@ -478,7 +840,7 @@ gistBuildCallback(Relation index, MemoryContextSwitchTo(oldCtx); MemoryContextReset(buildstate->giststate->tempCxt); - if (buildstate->bufferingMode == GIST_BUFFERING_ACTIVE && + if (buildstate->buildMode == GIST_BUFFERING_ACTIVE && buildstate->indtuples % BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET == 0) { /* Adjust the target buffer size now */ @@ -491,12 +853,15 @@ gistBuildCallback(Relation index, * and switch to buffering mode if it has. * * To avoid excessive calls to smgrnblocks(), only check this every - * BUFFERING_MODE_SWITCH_CHECK_STEP index tuples + * BUFFERING_MODE_SWITCH_CHECK_STEP index tuples. + * + * In 'stats' state, switch as soon as we have seen enough tuples to have + * some idea of the average tuple size. */ - if ((buildstate->bufferingMode == GIST_BUFFERING_AUTO && + if ((buildstate->buildMode == GIST_BUFFERING_AUTO && buildstate->indtuples % BUFFERING_MODE_SWITCH_CHECK_STEP == 0 && effective_cache_size < smgrnblocks(index->rd_smgr, MAIN_FORKNUM)) || - (buildstate->bufferingMode == GIST_BUFFERING_STATS && + (buildstate->buildMode == GIST_BUFFERING_STATS && buildstate->indtuples >= BUFFERING_MODE_TUPLE_SIZE_STATS_TARGET)) { /* @@ -847,7 +1212,7 @@ gistBufferingFindCorrectParent(GISTBuildState *buildstate, * number. */ if (*parentblkno == InvalidBlockNumber) - elog(ERROR, "no parent buffer provided of child %d", childblkno); + elog(ERROR, "no parent buffer provided of child %u", childblkno); parent = *parentblkno; } @@ -1180,7 +1545,7 @@ gistGetParent(GISTBuildState *buildstate, BlockNumber child) HASH_FIND, &found); if (!found) - elog(ERROR, "could not find parent of block %d in lookup table", child); + elog(ERROR, "could not find parent of block %u in lookup table", child); return entry->parentblkno; } diff --git a/src/backend/access/gist/gistbuildbuffers.c b/src/backend/access/gist/gistbuildbuffers.c index fc84a12eb94f..9c18c7681343 100644 --- a/src/backend/access/gist/gistbuildbuffers.c +++ b/src/backend/access/gist/gistbuildbuffers.c @@ -4,7 +4,7 @@ * node buffer management functions for GiST buffering build algorithm. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -76,7 +76,6 @@ gistInitBuildBuffers(int pagesPerBuffer, int levelStep, int maxLevel) * nodeBuffersTab hash is association between index blocks and it's * buffers. */ - memset(&hashCtl, 0, sizeof(hashCtl)); hashCtl.keysize = sizeof(BlockNumber); hashCtl.entrysize = sizeof(GISTNodeBuffer); hashCtl.hcxt = CurrentMemoryContext; @@ -666,7 +665,7 @@ gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, zero_penalty = true; /* Loop over index attributes. */ - for (j = 0; j < r->rd_att->natts; j++) + for (j = 0; j < IndexRelationGetNumberOfKeyAttributes(r); j++) { float usize; @@ -692,7 +691,7 @@ gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, GISTSTATE *giststate, which = i; best_penalty[j] = usize; - if (j < r->rd_att->natts - 1) + if (j < IndexRelationGetNumberOfKeyAttributes(r) - 1) best_penalty[j + 1] = -1; } else if (best_penalty[j] == usize) diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index dc21ddbb43d9..234f2ea4cdbe 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -4,7 +4,7 @@ * fetch tuples from a GiST scan. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c index 9ace64c3c4a9..d474612b77d1 100644 --- a/src/backend/access/gist/gistproc.c +++ b/src/backend/access/gist/gistproc.c @@ -7,7 +7,7 @@ * This gives R-tree behavior, with Guttman's poly-time split algorithm. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,6 +24,7 @@ #include "utils/builtins.h" #include "utils/float.h" #include "utils/geo_decls.h" +#include "utils/sortsupport.h" static bool gist_box_leaf_consistent(BOX *key, BOX *query, @@ -31,6 +32,15 @@ static bool gist_box_leaf_consistent(BOX *key, BOX *query, static bool rtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy); +static uint64 point_zorder_internal(float4 x, float4 y); +static uint64 part_bits32_by2(uint32 x); +static uint32 ieee_float32_to_uint32(float f); +static int gist_bbox_zorder_cmp(Datum a, Datum b, SortSupport ssup); +static Datum gist_bbox_zorder_abbrev_convert(Datum original, SortSupport ssup); +static int gist_bbox_zorder_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup); +static bool gist_bbox_zorder_abbrev_abort(int memtupcount, SortSupport ssup); + + /* Minimum accepted ratio of split */ #define LIMIT_RATIO 0.3 @@ -897,13 +907,11 @@ gist_box_leaf_consistent(BOX *key, BOX *query, StrategyNumber strategy) PointerGetDatum(query))); break; case RTContainsStrategyNumber: - case RTOldContainsStrategyNumber: retval = DatumGetBool(DirectFunctionCall2(box_contain, PointerGetDatum(key), PointerGetDatum(query))); break; case RTContainedByStrategyNumber: - case RTOldContainedByStrategyNumber: retval = DatumGetBool(DirectFunctionCall2(box_contained, PointerGetDatum(key), PointerGetDatum(query))); @@ -980,13 +988,11 @@ rtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy) break; case RTSameStrategyNumber: case RTContainsStrategyNumber: - case RTOldContainsStrategyNumber: retval = DatumGetBool(DirectFunctionCall2(box_contain, PointerGetDatum(key), PointerGetDatum(query))); break; case RTContainedByStrategyNumber: - case RTOldContainedByStrategyNumber: retval = DatumGetBool(DirectFunctionCall2(box_overlap, PointerGetDatum(key), PointerGetDatum(query))); @@ -1335,8 +1341,18 @@ gist_point_consistent(PG_FUNCTION_ARGS) StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); bool *recheck = (bool *) PG_GETARG_POINTER(4); bool result; - StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; + StrategyNumber strategyGroup; + + /* + * We have to remap these strategy numbers to get this klugy + * classification logic to work. + */ + if (strategy == RTOldBelowStrategyNumber) + strategy = RTBelowStrategyNumber; + else if (strategy == RTOldAboveStrategyNumber) + strategy = RTAboveStrategyNumber; + strategyGroup = strategy / GeoStrategyNumberOffset; switch (strategyGroup) { case PointStrategyNumberGroup: @@ -1540,3 +1556,222 @@ gist_poly_distance(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(distance); } + +/* + * Z-order routines for fast index build + */ + +/* + * Compute Z-value of a point + * + * Z-order (also known as Morton Code) maps a two-dimensional point to a + * single integer, in a way that preserves locality. Points that are close in + * the two-dimensional space are mapped to integer that are not far from each + * other. We do that by interleaving the bits in the X and Y components. + * + * Morton Code is normally defined only for integers, but the X and Y values + * of a point are floating point. We expect floats to be in IEEE format. + */ +static uint64 +point_zorder_internal(float4 x, float4 y) +{ + uint32 ix = ieee_float32_to_uint32(x); + uint32 iy = ieee_float32_to_uint32(y); + + /* Interleave the bits */ + return part_bits32_by2(ix) | (part_bits32_by2(iy) << 1); +} + +/* Interleave 32 bits with zeroes */ +static uint64 +part_bits32_by2(uint32 x) +{ + uint64 n = x; + + n = (n | (n << 16)) & UINT64CONST(0x0000FFFF0000FFFF); + n = (n | (n << 8)) & UINT64CONST(0x00FF00FF00FF00FF); + n = (n | (n << 4)) & UINT64CONST(0x0F0F0F0F0F0F0F0F); + n = (n | (n << 2)) & UINT64CONST(0x3333333333333333); + n = (n | (n << 1)) & UINT64CONST(0x5555555555555555); + + return n; +} + +/* + * Convert a 32-bit IEEE float to uint32 in a way that preserves the ordering + */ +static uint32 +ieee_float32_to_uint32(float f) +{ + /*---- + * + * IEEE 754 floating point format + * ------------------------------ + * + * IEEE 754 floating point numbers have this format: + * + * exponent (8 bits) + * | + * s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm + * | | + * sign mantissa (23 bits) + * + * Infinity has all bits in the exponent set and the mantissa is all + * zeros. Negative infinity is the same but with the sign bit set. + * + * NaNs are represented with all bits in the exponent set, and the least + * significant bit in the mantissa also set. The rest of the mantissa bits + * can be used to distinguish different kinds of NaNs. + * + * The IEEE format has the nice property that when you take the bit + * representation and interpret it as an integer, the order is preserved, + * except for the sign. That holds for the +-Infinity values too. + * + * Mapping to uint32 + * ----------------- + * + * In order to have a smooth transition from negative to positive numbers, + * we map floats to unsigned integers like this: + * + * x < 0 to range 0-7FFFFFFF + * x = 0 to value 8000000 (both positive and negative zero) + * x > 0 to range 8000001-FFFFFFFF + * + * We don't care to distinguish different kind of NaNs, so they are all + * mapped to the same arbitrary value, FFFFFFFF. Because of the IEEE bit + * representation of NaNs, there aren't any non-NaN values that would be + * mapped to FFFFFFFF. In fact, there is a range of unused values on both + * ends of the uint32 space. + */ + if (isnan(f)) + return 0xFFFFFFFF; + else + { + union + { + float f; + uint32 i; + } u; + + u.f = f; + + /* Check the sign bit */ + if ((u.i & 0x80000000) != 0) + { + /* + * Map the negative value to range 0-7FFFFFFF. This flips the sign + * bit to 0 in the same instruction. + */ + Assert(f <= 0); /* can be -0 */ + u.i ^= 0xFFFFFFFF; + } + else + { + /* Map the positive value (or 0) to range 80000000-FFFFFFFF */ + u.i |= 0x80000000; + } + + return u.i; + } +} + +/* + * Compare the Z-order of points + */ +static int +gist_bbox_zorder_cmp(Datum a, Datum b, SortSupport ssup) +{ + Point *p1 = &(DatumGetBoxP(a)->low); + Point *p2 = &(DatumGetBoxP(b)->low); + uint64 z1; + uint64 z2; + + /* + * Do a quick check for equality first. It's not clear if this is worth it + * in general, but certainly is when used as tie-breaker with abbreviated + * keys, + */ + if (p1->x == p2->x && p1->y == p2->y) + return 0; + + z1 = point_zorder_internal(p1->x, p1->y); + z2 = point_zorder_internal(p2->x, p2->y); + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * Abbreviated version of Z-order comparison + * + * The abbreviated format is a Z-order value computed from the two 32-bit + * floats. If SIZEOF_DATUM == 8, the 64-bit Z-order value fits fully in the + * abbreviated Datum, otherwise use its most significant bits. + */ +static Datum +gist_bbox_zorder_abbrev_convert(Datum original, SortSupport ssup) +{ + Point *p = &(DatumGetBoxP(original)->low); + uint64 z; + + z = point_zorder_internal(p->x, p->y); + +#if SIZEOF_DATUM == 8 + return (Datum) z; +#else + return (Datum) (z >> 32); +#endif +} + +static int +gist_bbox_zorder_cmp_abbrev(Datum z1, Datum z2, SortSupport ssup) +{ + /* + * Compare the pre-computed Z-orders as unsigned integers. Datum is a + * typedef for 'uintptr_t', so no casting is required. + */ + if (z1 > z2) + return 1; + else if (z1 < z2) + return -1; + else + return 0; +} + +/* + * We never consider aborting the abbreviation. + * + * On 64-bit systems, the abbreviation is not lossy so it is always + * worthwhile. (Perhaps it's not on 32-bit systems, but we don't bother + * with logic to decide.) + */ +static bool +gist_bbox_zorder_abbrev_abort(int memtupcount, SortSupport ssup) +{ + return false; +} + +/* + * Sort support routine for fast GiST index build by sorting. + */ +Datum +gist_point_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + if (ssup->abbreviate) + { + ssup->comparator = gist_bbox_zorder_cmp_abbrev; + ssup->abbrev_converter = gist_bbox_zorder_abbrev_convert; + ssup->abbrev_abort = gist_bbox_zorder_abbrev_abort; + ssup->abbrev_full_comparator = gist_bbox_zorder_cmp; + } + else + { + ssup->comparator = gist_bbox_zorder_cmp; + } + PG_RETURN_VOID(); +} diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index b8aa77f70fea..61e92cf0f5df 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -4,7 +4,7 @@ * routines to manage scans on GiST index relations * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gist/gistsplit.c b/src/backend/access/gist/gistsplit.c index e17d03c14a35..b6be21c515eb 100644 --- a/src/backend/access/gist/gistsplit.c +++ b/src/backend/access/gist/gistsplit.c @@ -15,7 +15,7 @@ * gistSplitByKey() is the entry point to this file. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index bfda7fbe3d58..43ba03b6eb97 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -4,7 +4,7 @@ * utilities routines for the postgres GiST index access method. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,7 +32,6 @@ void gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off) { - OffsetNumber l = InvalidOffsetNumber; int i; if (off == InvalidOffsetNumber) @@ -42,6 +41,7 @@ gistfillbuffer(Page page, IndexTuple *itup, int len, OffsetNumber off) for (i = 0; i < len; i++) { Size sz = IndexTupleSize(itup[i]); + OffsetNumber l; l = PageAddItem(page, (Item) itup[i], sz, off, false, false); if (l == InvalidOffsetNumber) @@ -572,12 +572,31 @@ gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, IndexTuple gistFormTuple(GISTSTATE *giststate, Relation r, - Datum attdata[], bool isnull[], bool isleaf) + Datum *attdata, bool *isnull, bool isleaf) { Datum compatt[INDEX_MAX_KEYS]; - int i; IndexTuple res; + gistCompressValues(giststate, r, attdata, isnull, isleaf, compatt); + + res = index_form_tuple(isleaf ? giststate->leafTupdesc : + giststate->nonLeafTupdesc, + compatt, isnull); + + /* + * The offset number on tuples on internal pages is unused. For historical + * reasons, it is set to 0xffff. + */ + ItemPointerSetOffsetNumber(&(res->t_tid), 0xffff); + return res; +} + +void +gistCompressValues(GISTSTATE *giststate, Relation r, + Datum *attdata, bool *isnull, bool isleaf, Datum *compatt) +{ + int i; + /* * Call the compress method on each attribute. */ @@ -617,17 +636,6 @@ gistFormTuple(GISTSTATE *giststate, Relation r, compatt[i] = attdata[i]; } } - - res = index_form_tuple(isleaf ? giststate->leafTupdesc : - giststate->nonLeafTupdesc, - compatt, isnull); - - /* - * The offset number on tuples on internal pages is unused. For historical - * reasons, it is set to 0xffff. - */ - ItemPointerSetOffsetNumber(&(res->t_tid), 0xffff); - return res; } /* @@ -745,24 +753,30 @@ gistpenalty(GISTSTATE *giststate, int attno, * Initialize a new index page */ void -GISTInitBuffer(Buffer b, uint32 f) +gistinitpage(Page page, uint32 f) { GISTPageOpaque opaque; - Page page; - Size pageSize; - pageSize = BufferGetPageSize(b); - page = BufferGetPage(b); - PageInit(page, pageSize, sizeof(GISTPageOpaqueData)); + PageInit(page, BLCKSZ, sizeof(GISTPageOpaqueData)); opaque = GistPageGetOpaque(page); - /* page was already zeroed by PageInit, so this is not needed: */ - /* memset(&(opaque->nsn), 0, sizeof(GistNSN)); */ opaque->rightlink = InvalidBlockNumber; opaque->flags = f; opaque->gist_page_id = GIST_PAGE_ID; } +/* + * Initialize a new index buffer + */ +void +GISTInitBuffer(Buffer b, uint32 f) +{ + Page page; + + page = BufferGetPage(b); + gistinitpage(page, f); +} + /* * Verify that a freshly-read page looks sane. */ @@ -897,7 +911,7 @@ gistPageRecyclable(Page page) */ FullTransactionId deletexid_full = GistPageGetDeleteXid(page); - return GlobalVisIsRemovableFullXid(NULL, deletexid_full); + return GlobalVisCheckRemovableFullXid(NULL, deletexid_full); } return false; } @@ -1019,7 +1033,7 @@ gistGetFakeLSN(Relation rel) return counter++; } - else if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT) + else if (RelationIsPermanent(rel)) { /* * WAL-logging on this relation will start after commit, so its LSNs diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index a9c616c77245..0663193531a7 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -4,7 +4,7 @@ * vacuuming routines for the postgres GiST index access method. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -133,9 +133,21 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, MemoryContext oldctx; /* - * Reset counts that will be incremented during the scan; needed in case - * of multiple scans during a single VACUUM command. + * Reset fields that track information about the entire index now. This + * avoids double-counting in the case where a single VACUUM command + * requires multiple scans of the index. + * + * Avoid resetting the tuples_removed and pages_newly_deleted fields here, + * since they track information about the VACUUM command, and so must last + * across each call to gistvacuumscan(). + * + * (Note that pages_free is treated as state about the whole index, not + * the current VACUUM. This is appropriate because RecordFreeIndexPage() + * calls are idempotent, and get repeated for the same deleted pages in + * some scenarios. The point for us is to track the number of recyclable + * pages in the index at the end of the VACUUM command.) */ + stats->num_pages = 0; stats->estimated_count = false; stats->num_index_tuples = 0; stats->pages_deleted = 0; @@ -281,8 +293,8 @@ gistvacuumpage(GistVacState *vstate, BlockNumber blkno, BlockNumber orig_blkno) { /* Okay to recycle this page */ RecordFreeIndexPage(rel, blkno); - vstate->stats->pages_free++; vstate->stats->pages_deleted++; + vstate->stats->pages_free++; } else if (GistPageIsDeleted(page)) { @@ -546,9 +558,6 @@ gistvacuum_delete_empty_pages(IndexVacuumInfo *info, GistVacState *vstate) ReleaseBuffer(buffer); - /* update stats */ - vstate->stats->pages_removed += deleted; - /* * We can stop the scan as soon as we have seen the downlinks, even if * we were not able to remove them all. @@ -639,6 +648,7 @@ gistdeletepage(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* mark the page as deleted */ MarkBufferDirty(leafBuffer); GistPageSetDeleted(leafPage, txid); + stats->pages_newly_deleted++; stats->pages_deleted++; /* remove the downlink from the parent */ diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c index 2b9ab693be18..b885fa2b256b 100644 --- a/src/backend/access/gist/gistvalidate.c +++ b/src/backend/access/gist/gistvalidate.c @@ -3,7 +3,7 @@ * gistvalidate.c * Opclass validator for GiST. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -143,6 +143,10 @@ gistvalidate(Oid opclassoid) case GIST_OPTIONS_PROC: ok = check_amoptsproc_signature(procform->amproc); break; + case GIST_SORTSUPPORT_PROC: + ok = check_amproc_signature(procform->amproc, VOIDOID, true, + 1, 1, INTERNALOID); + break; default: ereport(INFO, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), @@ -263,7 +267,7 @@ gistvalidate(Oid opclassoid) continue; /* got it */ if (i == GIST_DISTANCE_PROC || i == GIST_FETCH_PROC || i == GIST_COMPRESS_PROC || i == GIST_DECOMPRESS_PROC || - i == GIST_OPTIONS_PROC) + i == GIST_OPTIONS_PROC || i == GIST_SORTSUPPORT_PROC) continue; /* optional methods */ ereport(INFO, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), @@ -334,6 +338,7 @@ gistadjustmembers(Oid opfamilyoid, case GIST_DISTANCE_PROC: case GIST_FETCH_PROC: case GIST_OPTIONS_PROC: + case GIST_SORTSUPPORT_PROC: /* Optional, so force it to be a soft family dependency */ op->ref_is_hard = false; op->ref_is_family = true; diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c index dcd28f678b3d..6464cb9281b9 100644 --- a/src/backend/access/gist/gistxlog.c +++ b/src/backend/access/gist/gistxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for GiST. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -184,10 +184,10 @@ gistRedoDeleteRecord(XLogReaderState *record) * * GiST delete records can conflict with standby queries. You might think * that vacuum records would conflict as well, but we've handled that - * already. XLOG_HEAP2_CLEANUP_INFO records provide the highest xid - * cleaned by the vacuum of the heap and so we can resolve any conflicts - * just once when that arrives. After that we know that no conflicts - * exist from individual gist vacuum records on that index. + * already. XLOG_HEAP2_PRUNE records provide the highest xid cleaned by + * the vacuum of the heap and so we can resolve any conflicts just once + * when that arrives. After that we know that no conflicts exist from + * individual gist vacuum records on that index. */ if (InHotStandby) { @@ -388,35 +388,14 @@ gistRedoPageReuse(XLogReaderState *record) * pages in the index via the FSM. That's all they do though. * * latestRemovedXid was the page's deleteXid. The - * GlobalVisIsRemovableFullXid(deleteXid) test in gistPageRecyclable() + * GlobalVisCheckRemovableFullXid(deleteXid) test in gistPageRecyclable() * conceptually mirrors the PGPROC->xmin > limitXmin test in * GetConflictingVirtualXIDs(). Consequently, one XID value achieves the * same exclusion effect on primary and standby. */ if (InHotStandby) - { - FullTransactionId latestRemovedFullXid = xlrec->latestRemovedFullXid; - FullTransactionId nextXid = ReadNextFullTransactionId(); - uint64 diff; - - /* - * ResolveRecoveryConflictWithSnapshot operates on 32-bit - * TransactionIds, so truncate the logged FullTransactionId. If the - * logged value is very old, so that XID wrap-around already happened - * on it, there can't be any snapshots that still see it. - */ - nextXid = ReadNextFullTransactionId(); - diff = U64FromFullTransactionId(nextXid) - - U64FromFullTransactionId(latestRemovedFullXid); - if (diff < MaxTransactionId / 2) - { - TransactionId latestRemovedXid; - - latestRemovedXid = XidFromFullTransactionId(latestRemovedFullXid); - ResolveRecoveryConflictWithSnapshot(latestRemovedXid, - xlrec->node); - } - } + ResolveRecoveryConflictWithSnapshotFullXid(xlrec->latestRemovedFullXid, + xlrec->node); } void diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 9e8121a628fd..d152d793e7f7 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -3,7 +3,7 @@ * hash.c * Implementation of Margo Seltzer's Hashing package for postgres. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -247,6 +247,7 @@ bool hashinsert(Relation rel, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { Datum index_values[1]; diff --git a/src/backend/access/hash/hash_xlog.c b/src/backend/access/hash/hash_xlog.c index 3c606776624a..af35a991fc30 100644 --- a/src/backend/access/hash/hash_xlog.c +++ b/src/backend/access/hash/hash_xlog.c @@ -4,7 +4,7 @@ * WAL replay logic for hash index. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -992,10 +992,10 @@ hash_xlog_vacuum_one_page(XLogReaderState *record) * Hash index records that are marked as LP_DEAD and being removed during * hash index tuple insertion can conflict with standby queries. You might * think that vacuum records would conflict as well, but we've handled - * that already. XLOG_HEAP2_CLEANUP_INFO records provide the highest xid - * cleaned by the vacuum of the heap and so we can resolve any conflicts - * just once when that arrives. After that we know that no conflicts - * exist from individual hash index vacuum records on that index. + * that already. XLOG_HEAP2_PRUNE records provide the highest xid cleaned + * by the vacuum of the heap and so we can resolve any conflicts just once + * when that arrives. After that we know that no conflicts exist from + * individual hash index vacuum records on that index. */ if (InHotStandby) { diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index a8498226e32d..db20d9d1c145 100644 --- a/src/backend/access/hash/hashfunc.c +++ b/src/backend/access/hash/hashfunc.c @@ -3,7 +3,7 @@ * hashfunc.c * Support functions for hash access method. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c index 2ebe671967ba..d254a00b6ac3 100644 --- a/src/backend/access/hash/hashinsert.c +++ b/src/backend/access/hash/hashinsert.c @@ -3,7 +3,7 @@ * hashinsert.c * Item insertion in hash tables for Postgres. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/hash/hashovfl.c b/src/backend/access/hash/hashovfl.c index cbd2cf9e4892..30572408fc17 100644 --- a/src/backend/access/hash/hashovfl.c +++ b/src/backend/access/hash/hashovfl.c @@ -3,7 +3,7 @@ * hashovfl.c * Overflow page management code for the Postgres hash access method * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c index a664ecf494a6..49a986778768 100644 --- a/src/backend/access/hash/hashpage.c +++ b/src/backend/access/hash/hashpage.c @@ -3,7 +3,7 @@ * hashpage.c * Hash table page management code for the Postgres hash access method * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1363,7 +1363,6 @@ _hash_finish_split(Relation rel, Buffer metabuf, Buffer obuf, Bucket obucket, bool found; /* Initialize hash tables used to track TIDs */ - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(ItemPointerData); hash_ctl.entrysize = sizeof(ItemPointerData); hash_ctl.hcxt = CurrentMemoryContext; diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c index 995498e48da1..2ffa28e8f771 100644 --- a/src/backend/access/hash/hashsearch.c +++ b/src/backend/access/hash/hashsearch.c @@ -3,7 +3,7 @@ * hashsearch.c * search code for postgres hash tables * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/hash/hashsort.c b/src/backend/access/hash/hashsort.c index 2c7b5857b530..3ce42483ed19 100644 --- a/src/backend/access/hash/hashsort.c +++ b/src/backend/access/hash/hashsort.c @@ -14,7 +14,7 @@ * plenty of locality of access. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c index eb510be3324c..519872850e0b 100644 --- a/src/backend/access/hash/hashutil.c +++ b/src/backend/access/hash/hashutil.c @@ -3,7 +3,7 @@ * hashutil.c * Utility code for Postgres hash implementation. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/hash/hashvalidate.c b/src/backend/access/hash/hashvalidate.c index 0fe97e8276b6..1e343df0afc5 100644 --- a/src/backend/access/hash/hashvalidate.c +++ b/src/backend/access/hash/hashvalidate.c @@ -3,7 +3,7 @@ * hashvalidate.c * Opclass validator for hash. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -312,7 +312,7 @@ check_hash_func_signature(Oid funcid, int16 amprocnum, Oid argtype) * that are different from but physically compatible with the opclass * datatype. In some of these cases, even a "binary coercible" check * fails because there's no relevant cast. For the moment, fix it by - * having a whitelist of allowed cases. Test the specific function + * having a list of allowed cases. Test the specific function * identity, not just its input type, because hashvarlena() takes * INTERNAL and allowing any such function seems too scary. */ diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index d03ddf6cdcc8..6441e8baf0e4 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -146,9 +146,10 @@ The following infomask bits are applicable: FOR UPDATE; this is implemented by the HEAP_KEYS_UPDATED bit. - HEAP_KEYS_UPDATED - This bit lives in t_infomask2. If set, indicates that the XMAX updated - this tuple and changed the key values, or it deleted the tuple. - It's set regardless of whether the XMAX is a TransactionId or a MultiXactId. + This bit lives in t_infomask2. If set, indicates that the operation(s) done + by the XMAX compromise the tuple key, such as a SELECT FOR UPDATE, an UPDATE + that modifies the columns of the key, or a DELETE. It's set regardless of + whether the XMAX is a TransactionId or a MultiXactId. We currently never set the HEAP_XMAX_COMMITTED when the HEAP_XMAX_IS_MULTI bit is set. diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 144d5797f6fd..6fa7e82b2920 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -3,7 +3,7 @@ * heapam.c * heap access method code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -55,6 +55,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" +#include "port/pg_bitutils.h" #include "storage/bufmgr.h" #include "storage/freespace.h" #include "storage/lmgr.h" @@ -112,6 +113,8 @@ static void MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 in int *remaining); static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, Relation rel, int *remaining); +static void index_delete_sort(TM_IndexDeleteOp *delstate); +static int bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate); static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup); static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_changed, bool *copy); @@ -176,18 +179,33 @@ static const struct #ifdef USE_PREFETCH /* - * heap_compute_xid_horizon_for_tuples and xid_horizon_prefetch_buffer use - * this structure to coordinate prefetching activity. + * heap_index_delete_tuples and index_delete_prefetch_buffer use this + * structure to coordinate prefetching activity */ typedef struct { BlockNumber cur_hblkno; int next_item; - int nitems; - ItemPointerData *tids; -} XidHorizonPrefetchState; + int ndeltids; + TM_IndexDelete *deltids; +} IndexDeletePrefetchState; #endif +/* heap_index_delete_tuples bottom-up index deletion costing constants */ +#define BOTTOMUP_MAX_NBLOCKS 6 +#define BOTTOMUP_TOLERANCE_NBLOCKS 3 + +/* + * heap_index_delete_tuples uses this when determining which heap blocks it + * must visit to help its bottom-up index deletion caller + */ +typedef struct IndexDeleteCounts +{ + int16 npromisingtids; /* Number of "promising" TIDs in group */ + int16 ntids; /* Number of TIDs in group */ + int16 ifirsttid; /* Offset to group's first deltid */ +} IndexDeleteCounts; + /* * This table maps tuple lock strength values for each particular * MultiXactStatus value. @@ -429,11 +447,11 @@ heapgetpage(TableScanDesc sscan, BlockNumber page) * transactions on the primary might still be invisible to a read-only * transaction in the standby. We partly handle this problem by tracking * the minimum xmin of visible tuples as the cut-off XID while marking a - * page all-visible on the primary and WAL log that along with the visibility - * map SET operation. In hot standby, we wait for (or abort) all - * transactions that can potentially may not see one or more tuples on the - * page. That's how index-only scans work fine in hot standby. A crucial - * difference between index-only scans and heap scans is that the + * page all-visible on the primary and WAL log that along with the + * visibility map SET operation. In hot standby, we wait for (or abort) + * all transactions that can potentially may not see one or more tuples on + * the page. That's how index-only scans work fine in hot standby. A + * crucial difference between index-only scans and heap scans is that the * index-only scan completely relies on the visibility map where as heap * scan looks at the page-level PD_ALL_VISIBLE flag. We are not sure if * the page-level flag can be trusted in the same way, because it might @@ -575,7 +593,7 @@ heapgettup(HeapScanDesc scan, ParallelBlockTableScanDesc pbscan = (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; ParallelBlockTableScanWorker pbscanwork = - (ParallelBlockTableScanWorker) scan->rs_base.rs_private; + scan->rs_parallelworkerdata; table_block_parallelscan_startblock_init(scan->rs_base.rs_rd, pbscanwork, pbscan); @@ -638,8 +656,14 @@ heapgettup(HeapScanDesc scan, * forward scanners. */ scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; - /* start from last page of the scan */ - if (scan->rs_startblock > 0) + + /* + * Start from last page of the scan. Ensure we take into account + * rs_numblocks if it's been adjusted by heap_setscanlimits(). + */ + if (scan->rs_numblocks != InvalidBlockNumber) + page = (scan->rs_startblock + scan->rs_numblocks - 1) % scan->rs_nblocks; + else if (scan->rs_startblock > 0) page = scan->rs_startblock - 1; else page = scan->rs_nblocks - 1; @@ -664,8 +688,15 @@ heapgettup(HeapScanDesc scan, } else { + /* + * The previous returned tuple may have been vacuumed since the + * previous scan when we use a non-MVCC snapshot, so we must + * re-establish the lineoff <= PageGetMaxOffsetNumber(dp) + * invariant + */ lineoff = /* previous offnum */ - OffsetNumberPrev(ItemPointerGetOffsetNumber(&(tuple->t_self))); + Min(lines, + OffsetNumberPrev(ItemPointerGetOffsetNumber(&(tuple->t_self)))); } /* page and lineoff now reference the physically previous tid */ @@ -709,6 +740,13 @@ heapgettup(HeapScanDesc scan, { CHECK_FOR_INTERRUPTS(); + /* + * Only continue scanning the page while we have lines left. + * + * Note that this protects us from accessing line pointers past + * PageGetMaxOffsetNumber(); both for forward scans when we resume the + * table scan, and for when we start scanning a new page. + */ while (linesleft > 0) { if (ItemIdIsNormal(lpp)) @@ -780,7 +818,7 @@ heapgettup(HeapScanDesc scan, ParallelBlockTableScanDesc pbscan = (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; ParallelBlockTableScanWorker pbscanwork = - (ParallelBlockTableScanWorker) scan->rs_base.rs_private; + scan->rs_parallelworkerdata; page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd, pbscanwork, pbscan); @@ -896,7 +934,7 @@ heapgettup_pagemode(HeapScanDesc scan, ParallelBlockTableScanDesc pbscan = (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; ParallelBlockTableScanWorker pbscanwork = - (ParallelBlockTableScanWorker) scan->rs_base.rs_private; + scan->rs_parallelworkerdata; table_block_parallelscan_startblock_init(scan->rs_base.rs_rd, pbscanwork, pbscan); @@ -956,8 +994,14 @@ heapgettup_pagemode(HeapScanDesc scan, * forward scanners. */ scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; - /* start from last page of the scan */ - if (scan->rs_startblock > 0) + + /* + * Start from last page of the scan. Ensure we take into account + * rs_numblocks if it's been adjusted by heap_setscanlimits(). + */ + if (scan->rs_numblocks != InvalidBlockNumber) + page = (scan->rs_startblock + scan->rs_numblocks - 1) % scan->rs_nblocks; + else if (scan->rs_startblock > 0) page = scan->rs_startblock - 1; else page = scan->rs_nblocks - 1; @@ -1085,7 +1129,7 @@ heapgettup_pagemode(HeapScanDesc scan, ParallelBlockTableScanDesc pbscan = (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; ParallelBlockTableScanWorker pbscanwork = - (ParallelBlockTableScanWorker) scan->rs_base.rs_private; + scan->rs_parallelworkerdata; page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd, pbscanwork, pbscan); @@ -1220,8 +1264,6 @@ heap_beginscan(Relation relation, Snapshot snapshot, scan->rs_base.rs_nkeys = nkeys; scan->rs_base.rs_flags = flags; scan->rs_base.rs_parallel = parallel_scan; - scan->rs_base.rs_private = - palloc(sizeof(ParallelBlockTableScanWorkerData)); scan->rs_strategy = NULL; /* set in initscan */ /* @@ -1257,6 +1299,15 @@ heap_beginscan(Relation relation, Snapshot snapshot, /* we only need to set this up once */ scan->rs_ctup.t_tableOid = RelationGetRelid(relation); + /* + * Allocate memory to keep track of page allocation for parallel workers + * when doing a parallel scan. + */ + if (parallel_scan != NULL) + scan->rs_parallelworkerdata = palloc(sizeof(ParallelBlockTableScanWorkerData)); + else + scan->rs_parallelworkerdata = NULL; + /* * we do this here instead of in initscan() because heap_rescan also calls * initscan() and we don't want to allocate memory again @@ -1332,6 +1383,9 @@ heap_endscan(TableScanDesc sscan) if (scan->rs_strategy != NULL) FreeAccessStrategy(scan->rs_strategy); + if (scan->rs_parallelworkerdata != NULL) + pfree(scan->rs_parallelworkerdata); + if (scan->rs_base.rs_flags & SO_TEMP_SNAPSHOT) UnregisterSnapshot(scan->rs_base.rs_snapshot); @@ -1417,6 +1471,153 @@ heap_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *s return true; } +void +heap_set_tidrange(TableScanDesc sscan, ItemPointer mintid, + ItemPointer maxtid) +{ + HeapScanDesc scan = (HeapScanDesc) sscan; + BlockNumber startBlk; + BlockNumber numBlks; + ItemPointerData highestItem; + ItemPointerData lowestItem; + + /* + * For relations without any pages, we can simply leave the TID range + * unset. There will be no tuples to scan, therefore no tuples outside + * the given TID range. + */ + if (scan->rs_nblocks == 0) + return; + + /* + * Set up some ItemPointers which point to the first and last possible + * tuples in the heap. + */ + ItemPointerSet(&highestItem, scan->rs_nblocks - 1, MaxOffsetNumber); + ItemPointerSet(&lowestItem, 0, FirstOffsetNumber); + + /* + * If the given maximum TID is below the highest possible TID in the + * relation, then restrict the range to that, otherwise we scan to the end + * of the relation. + */ + if (ItemPointerCompare(maxtid, &highestItem) < 0) + ItemPointerCopy(maxtid, &highestItem); + + /* + * If the given minimum TID is above the lowest possible TID in the + * relation, then restrict the range to only scan for TIDs above that. + */ + if (ItemPointerCompare(mintid, &lowestItem) > 0) + ItemPointerCopy(mintid, &lowestItem); + + /* + * Check for an empty range and protect from would be negative results + * from the numBlks calculation below. + */ + if (ItemPointerCompare(&highestItem, &lowestItem) < 0) + { + /* Set an empty range of blocks to scan */ + heap_setscanlimits(sscan, 0, 0); + return; + } + + /* + * Calculate the first block and the number of blocks we must scan. We + * could be more aggressive here and perform some more validation to try + * and further narrow the scope of blocks to scan by checking if the + * lowerItem has an offset above MaxOffsetNumber. In this case, we could + * advance startBlk by one. Likewise, if highestItem has an offset of 0 + * we could scan one fewer blocks. However, such an optimization does not + * seem worth troubling over, currently. + */ + startBlk = ItemPointerGetBlockNumberNoCheck(&lowestItem); + + numBlks = ItemPointerGetBlockNumberNoCheck(&highestItem) - + ItemPointerGetBlockNumberNoCheck(&lowestItem) + 1; + + /* Set the start block and number of blocks to scan */ + heap_setscanlimits(sscan, startBlk, numBlks); + + /* Finally, set the TID range in sscan */ + ItemPointerCopy(&lowestItem, &sscan->rs_mintid); + ItemPointerCopy(&highestItem, &sscan->rs_maxtid); +} + +bool +heap_getnextslot_tidrange(TableScanDesc sscan, ScanDirection direction, + TupleTableSlot *slot) +{ + HeapScanDesc scan = (HeapScanDesc) sscan; + ItemPointer mintid = &sscan->rs_mintid; + ItemPointer maxtid = &sscan->rs_maxtid; + + /* Note: no locking manipulations needed */ + for (;;) + { + if (sscan->rs_flags & SO_ALLOW_PAGEMODE) + heapgettup_pagemode(scan, direction, sscan->rs_nkeys, sscan->rs_key); + else + heapgettup(scan, direction, sscan->rs_nkeys, sscan->rs_key); + + if (scan->rs_ctup.t_data == NULL) + { + ExecClearTuple(slot); + return false; + } + + /* + * heap_set_tidrange will have used heap_setscanlimits to limit the + * range of pages we scan to only ones that can contain the TID range + * we're scanning for. Here we must filter out any tuples from these + * pages that are outwith that range. + */ + if (ItemPointerCompare(&scan->rs_ctup.t_self, mintid) < 0) + { + ExecClearTuple(slot); + + /* + * When scanning backwards, the TIDs will be in descending order. + * Future tuples in this direction will be lower still, so we can + * just return false to indicate there will be no more tuples. + */ + if (ScanDirectionIsBackward(direction)) + return false; + + continue; + } + + /* + * Likewise for the final page, we must filter out TIDs greater than + * maxtid. + */ + if (ItemPointerCompare(&scan->rs_ctup.t_self, maxtid) > 0) + { + ExecClearTuple(slot); + + /* + * When scanning forward, the TIDs will be in ascending order. + * Future tuples in this direction will be higher still, so we can + * just return false to indicate there will be no more tuples. + */ + if (ScanDirectionIsForward(direction)) + return false; + continue; + } + + break; + } + + /* + * if we get here it means we have a new current scan tuple, so point to + * the proper return buffer and return the tuple. + */ + pgstat_count_heap_getnext(scan->rs_base.rs_rd); + + ExecStoreBufferHeapTuple(&scan->rs_ctup, slot, scan->rs_cbuf); + return true; +} + /* * heap_fetch - retrieve tuple with given tid * @@ -1930,6 +2131,10 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, RelationGetRelationName(relation)); #endif + /* Cheap, simplistic check that the tuple matches the rel's rowtype. */ + Assert(HeapTupleHeaderGetNatts(tup->t_data) <= + RelationGetNumberOfAttributes(relation)); + /* * Fill in tuple header fields and toast the tuple if necessary. * @@ -2002,7 +2207,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, int bufflags = 0; /* - * If this is a catalog, we need to transmit combocids to properly + * If this is a catalog, we need to transmit combo CIDs to properly * decode, so log that as well. */ if (RelationIsAccessibleInLogicalDecoding(relation)) @@ -2116,12 +2321,10 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, CommandId cid, int options, bool isFrozen) { /* - * Parallel operations are required to be strictly read-only in a parallel - * worker. Parallel inserts are not safe even in the leader in the - * general case, because group locking means that heavyweight locks for - * relation extension or GIN page locks will not conflict between members - * of a lock group, but we don't prohibit that case here because there are - * useful special cases that we can safely allow, such as CREATE TABLE AS. + * To allow parallel inserts, we need to ensure that they are safe to be + * performed in workers. We have the infrastructure to allow parallel + * inserts in general except for the cases where inserts generate a new + * CommandId (eg. inserts into a table having a foreign key column). */ if (IsParallelWorker()) ereport(ERROR, @@ -2161,7 +2364,7 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, } /* - * heap_multi_insert - insert multiple tuple into a heap + * heap_multi_insert - insert multiple tuples into a heap * * This is like heap_insert(), but inserts multiple tuples in one operation. * That's faster than calling heap_insert() in a loop, because when multiple @@ -2182,6 +2385,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, int ndone; PGAlignedBlock scratch; Page page; + Buffer vmbuffer = InvalidBuffer; bool needwal; Size saveFreeSpace; bool need_tuple_data = RelationIsLogicallyLogged(relation); @@ -2236,8 +2440,9 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, while (ndone < ntuples) { Buffer buffer; - Buffer vmbuffer = InvalidBuffer; + bool starting_with_empty_page; bool all_visible_cleared = false; + bool all_frozen_set = false; int nthispage; CHECK_FOR_INTERRUPTS(); @@ -2245,12 +2450,20 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, /* * Find buffer where at least the next tuple will fit. If the page is * all-visible, this will also pin the requisite visibility map page. + * + * Also pin visibility map page if COPY FREEZE inserts tuples into an + * empty page. See all_frozen_set below. */ buffer = RelationGetBufferForTuple(relation, heaptuples[ndone]->t_len, InvalidBuffer, options, bistate, &vmbuffer, NULL); page = BufferGetPage(buffer); + starting_with_empty_page = PageGetMaxOffsetNumber(page) == 0; + + if (starting_with_empty_page && (options & HEAP_INSERT_FROZEN)) + all_frozen_set = true; + /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); @@ -2261,7 +2474,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, RelationPutHeapTuple(relation, buffer, heaptuples[ndone], false); /* - * For logical decoding we need combocids to properly decode the + * For logical decoding we need combo CIDs to properly decode the * catalog. */ if (needwal && need_cids) @@ -2277,14 +2490,21 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, RelationPutHeapTuple(relation, buffer, heaptup, false); /* - * For logical decoding we need combocids to properly decode the + * For logical decoding we need combo CIDs to properly decode the * catalog. */ if (needwal && need_cids) log_heap_new_cid(relation, heaptup); } - if (PageIsAllVisible(page)) + /* + * If the page is all visible, need to clear that, unless we're only + * going to add further frozen rows to it. + * + * If we're only adding already frozen rows to a previously empty + * page, mark it as all-visible. + */ + if (PageIsAllVisible(page) && !(options & HEAP_INSERT_FROZEN)) { all_visible_cleared = true; PageClearAllVisible(page); @@ -2292,6 +2512,8 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, BufferGetBlockNumber(buffer), vmbuffer, VISIBILITYMAP_VALID_BITS); } + else if (all_frozen_set) + PageSetAllVisible(page); /* * XXX Should we set PageSetPrunable on this page ? See heap_insert() @@ -2315,8 +2537,7 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, * If the page was previously empty, we can reinit the page * instead of restoring the whole thing. */ - init = (ItemPointerGetOffsetNumber(&(heaptuples[ndone]->t_self)) == FirstOffsetNumber && - PageGetMaxOffsetNumber(page) == FirstOffsetNumber + nthispage - 1); + init = starting_with_empty_page; /* allocate xl_heap_multi_insert struct from the scratch area */ xlrec = (xl_heap_multi_insert *) scratchptr; @@ -2334,7 +2555,15 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, /* the rest of the scratch space is used for tuple data */ tupledata = scratchptr; - xlrec->flags = all_visible_cleared ? XLH_INSERT_ALL_VISIBLE_CLEARED : 0; + /* check that the mutually exclusive flags are not both set */ + Assert(!(all_visible_cleared && all_frozen_set)); + + xlrec->flags = 0; + if (all_visible_cleared) + xlrec->flags = XLH_INSERT_ALL_VISIBLE_CLEARED; + if (all_frozen_set) + xlrec->flags = XLH_INSERT_ALL_FROZEN_SET; + xlrec->ntuples = nthispage; /* @@ -2408,13 +2637,40 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, END_CRIT_SECTION(); - UnlockReleaseBuffer(buffer); - if (vmbuffer != InvalidBuffer) - ReleaseBuffer(vmbuffer); + /* + * If we've frozen everything on the page, update the visibilitymap. + * We're already holding pin on the vmbuffer. + */ + if (all_frozen_set) + { + Assert(PageIsAllVisible(page)); + Assert(visibilitymap_pin_ok(BufferGetBlockNumber(buffer), vmbuffer)); + + /* + * It's fine to use InvalidTransactionId here - this is only used + * when HEAP_INSERT_FROZEN is specified, which intentionally + * violates visibility rules. + */ + visibilitymap_set(relation, BufferGetBlockNumber(buffer), buffer, + InvalidXLogRecPtr, vmbuffer, + InvalidTransactionId, + VISIBILITYMAP_ALL_VISIBLE | VISIBILITYMAP_ALL_FROZEN); + } + UnlockReleaseBuffer(buffer); ndone += nthispage; + + /* + * NB: Only release vmbuffer after inserting all tuples - it's fairly + * likely that we'll insert into subsequent heap pages that are likely + * to use the same vm page. + */ } + /* We're done with inserting all tuples, so release the last vmbuffer. */ + if (vmbuffer != InvalidBuffer) + ReleaseBuffer(vmbuffer); + /* * We're done with the actual inserts. Check for conflicts again, to * ensure that all rw-conflicts in to these inserts are detected. Without @@ -2534,7 +2790,7 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) * * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, * t_xmax (resolving a possible MultiXact, if necessary), and t_cmax (the last - * only for TM_SelfModified, since we cannot obtain cmax from a combocid + * only for TM_SelfModified, since we cannot obtain cmax from a combo CID * generated by another transaction). */ TM_Result @@ -2564,8 +2820,8 @@ heap_delete(Relation relation, ItemPointer tid, gp_expand_protect_catalog_changes(relation); /* - * Forbid this during a parallel operation, lest it allocate a combocid. - * Other workers might need that combocid for visibility checks, and we + * Forbid this during a parallel operation, lest it allocate a combo CID. + * Other workers might need that combo CID for visibility checks, and we * have no provision for broadcasting it to them. */ if (IsInParallelMode()) @@ -2719,8 +2975,7 @@ heap_delete(Relation relation, ItemPointer tid, HEAP_XMAX_IS_LOCKED_ONLY(tp.t_data->t_infomask) || HeapTupleHeaderIsOnlyLocked(tp.t_data)) result = TM_Ok; - else if (!ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid) || - HeapTupleHeaderIndicatesMovedPartitions(tp.t_data)) + else if (!ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid)) result = TM_Updated; else result = TM_Deleted; @@ -2767,7 +3022,7 @@ heap_delete(Relation relation, ItemPointer tid, */ CheckForSerializableConflictIn(relation, tid, BufferGetBlockNumber(buffer)); - /* replace cid with a combo cid if necessary */ + /* replace cid with a combo CID if necessary */ HeapTupleHeaderAdjustCmax(tp.t_data, &cid, &iscombo); /* @@ -2839,7 +3094,10 @@ heap_delete(Relation relation, ItemPointer tid, xl_heap_header xlhdr; XLogRecPtr recptr; - /* For logical decode we need combocids to properly decode the catalog */ + /* + * For logical decode we need combo CIDs to properly decode the + * catalog + */ if (RelationIsAccessibleInLogicalDecoding(relation)) log_heap_new_cid(relation, &tp); @@ -2987,7 +3245,7 @@ simple_heap_delete(Relation relation, ItemPointer tid) * * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, * t_xmax (resolving a possible MultiXact, if necessary), and t_cmax (the last - * only for TM_SelfModified, since we cannot obtain cmax from a combocid + * only for TM_SelfModified, since we cannot obtain cmax from a combo CID * generated by another transaction). */ static TM_Result @@ -3036,10 +3294,13 @@ heap_update_internal(Relation relation, ItemPointer otid, HeapTuple newtup, Assert(ItemPointerIsValid(otid)); gp_expand_protect_catalog_changes(relation); + /* Cheap, simplistic check that the tuple matches the rel's rowtype. */ + Assert(HeapTupleHeaderGetNatts(newtup->t_data) <= + RelationGetNumberOfAttributes(relation)); /* - * Forbid this during a parallel operation, lest it allocate a combocid. - * Other workers might need that combocid for visibility checks, and we + * Forbid this during a parallel operation, lest it allocate a combo CID. + * Other workers might need that combo CID for visibility checks, and we * have no provision for broadcasting it to them. */ if (IsInParallelMode()) @@ -3351,8 +3612,7 @@ heap_update_internal(Relation relation, ItemPointer otid, HeapTuple newtup, if (can_continue) result = TM_Ok; - else if (!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid) || - HeapTupleHeaderIndicatesMovedPartitions(oldtup.t_data)) + else if (!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid)) result = TM_Updated; else result = TM_Deleted; @@ -3479,7 +3739,7 @@ heap_update_internal(Relation relation, ItemPointer otid, HeapTuple newtup, HeapTupleHeaderSetXmax(newtup->t_data, xmax_new_tuple); /* - * Replace cid with a combo cid if necessary. Note that we already put + * Replace cid with a combo CID if necessary. Note that we already put * the plain cid into the new tuple. */ HeapTupleHeaderAdjustCmax(oldtup.t_data, &cid, &iscombo); @@ -3568,7 +3828,7 @@ heap_update_internal(Relation relation, ItemPointer otid, HeapTuple newtup, * overhead would be unchanged, that doesn't seem necessarily * worthwhile. */ - if (PageIsAllVisible(BufferGetPage(buffer)) && + if (PageIsAllVisible(page) && visibilitymap_clear(relation, block, vmbuffer, VISIBILITYMAP_ALL_FROZEN)) cleared_all_frozen = true; @@ -3632,36 +3892,46 @@ heap_update_internal(Relation relation, ItemPointer otid, HeapTuple newtup, * first". To implement this, we must do RelationGetBufferForTuple * while not holding the lock on the old page, and we must rely on it * to get the locks on both pages in the correct order. + * + * Another consideration is that we need visibility map page pin(s) if + * we will have to clear the all-visible flag on either page. If we + * call RelationGetBufferForTuple, we rely on it to acquire any such + * pins; but if we don't, we have to handle that here. Hence we need + * a loop. */ - if (newtupsize > pagefree) - { - /* Assume there's no chance to put heaptup on same page. */ - newbuf = RelationGetBufferForTuple(relation, heaptup->t_len, - buffer, 0, NULL, - &vmbuffer_new, &vmbuffer); - } - else + for (;;) { + if (newtupsize > pagefree) + { + /* It doesn't fit, must use RelationGetBufferForTuple. */ + newbuf = RelationGetBufferForTuple(relation, heaptup->t_len, + buffer, 0, NULL, + &vmbuffer_new, &vmbuffer); + /* We're all done. */ + break; + } + /* Acquire VM page pin if needed and we don't have it. */ + if (vmbuffer == InvalidBuffer && PageIsAllVisible(page)) + visibilitymap_pin(relation, block, &vmbuffer); /* Re-acquire the lock on the old tuple's page. */ LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); /* Re-check using the up-to-date free space */ pagefree = PageGetHeapFreeSpace(page); - if (newtupsize > pagefree) + if (newtupsize > pagefree || + (vmbuffer == InvalidBuffer && PageIsAllVisible(page))) { /* - * Rats, it doesn't fit anymore. We must now unlock and - * relock to avoid deadlock. Fortunately, this path should - * seldom be taken. + * Rats, it doesn't fit anymore, or somebody just now set the + * all-visible flag. We must now unlock and loop to avoid + * deadlock. Fortunately, this path should seldom be taken. */ LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - newbuf = RelationGetBufferForTuple(relation, heaptup->t_len, - buffer, 0, NULL, - &vmbuffer_new, &vmbuffer); } else { - /* OK, it fits here, so we're done. */ + /* We're all done. */ newbuf = buffer; + break; } } } @@ -3686,7 +3956,8 @@ heap_update_internal(Relation relation, ItemPointer otid, HeapTuple newtup, * will include checking the relation level, there is no benefit to a * separate check for the new tuple. */ - CheckForSerializableConflictIn(relation, otid, BufferGetBlockNumber(buffer)); + CheckForSerializableConflictIn(relation, &oldtup.t_self, + BufferGetBlockNumber(buffer)); /* * At this point newbuf and buffer are both pinned and locked, and newbuf @@ -3797,7 +4068,7 @@ heap_update_internal(Relation relation, ItemPointer otid, HeapTuple newtup, XLogRecPtr recptr; /* - * For logical decoding we need combocids to properly decode the + * For logical decoding we need combo CIDs to properly decode the * catalog. */ if (RelationIsAccessibleInLogicalDecoding(relation)) @@ -4081,7 +4352,7 @@ get_mxact_status_for_lock(LockTupleMode mode, bool is_update) * In the failure cases other than TM_Invisible, the routine fills * *tmfd with the tuple's t_ctid, t_xmax (resolving a possible MultiXact, * if necessary), and t_cmax (the last only for TM_SelfModified, - * since we cannot obtain cmax from a combocid generated by another + * since we cannot obtain cmax from a combo CID generated by another * transaction). * See comments for struct TM_FailureData for additional info. * @@ -4603,8 +4874,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_data->t_infomask) || HeapTupleHeaderIsOnlyLocked(tuple->t_data)) result = TM_Ok; - else if (!ItemPointerEquals(&tuple->t_self, &tuple->t_data->t_ctid) || - HeapTupleHeaderIndicatesMovedPartitions(tuple->t_data)) + else if (!ItemPointerEquals(&tuple->t_self, &tuple->t_data->t_ctid)) result = TM_Updated; else result = TM_Deleted; @@ -5177,8 +5447,7 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, LOCKMODE_from_mxstatus(wantedstatus))) { /* bummer */ - if (!ItemPointerEquals(&tup->t_self, &tup->t_data->t_ctid) || - HeapTupleHeaderIndicatesMovedPartitions(tup->t_data)) + if (!ItemPointerEquals(&tup->t_self, &tup->t_data->t_ctid)) return TM_Updated; else return TM_Deleted; @@ -5725,7 +5994,7 @@ heap_abort_speculative(Relation relation, ItemPointer tid) /* * No need to check for serializable conflicts here. There is never a - * need for a combocid, either. No need to extract replica identity, or + * need for a combo CID, either. No need to extract replica identity, or * do anything special with infomask bits. */ @@ -5828,6 +6097,10 @@ heap_abort_speculative(Relation relation, ItemPointer tid) * * tuple is an in-memory tuple structure containing the data to be written * over the target tuple. Also, tuple->t_self identifies the target tuple. + * + * Note that the tuple updated here had better not come directly from the + * syscache if the relation has a toast relation as this tuple could + * include toast values that have been expanded, causing a failure here. */ void heap_inplace_update(Relation relation, HeapTuple tuple) @@ -5841,10 +6114,10 @@ heap_inplace_update(Relation relation, HeapTuple tuple) uint32 newlen; /* - * For now, parallel operations are required to be strictly read-only. - * Unlike a regular update, this should never create a combo CID, so it - * might be possible to relax this restriction, but not without more - * thought and testing. It's not clear that it would be useful, anyway. + * For now, we don't allow parallel updates. Unlike a regular update, + * this should never create a combo CID, so it might be possible to relax + * this restriction, but not without more thought and testing. It's not + * clear that it would be useful, anyway. */ if (IsInParallelMode()) ereport(ERROR, @@ -7051,28 +7324,31 @@ HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple, #ifdef USE_PREFETCH /* - * Helper function for heap_compute_xid_horizon_for_tuples. Issue prefetch - * requests for the number of buffers indicated by prefetch_count. The - * prefetch_state keeps track of all the buffers that we can prefetch and - * which ones have already been prefetched; each call to this function picks - * up where the previous call left off. + * Helper function for heap_index_delete_tuples. Issues prefetch requests for + * prefetch_count buffers. The prefetch_state keeps track of all the buffers + * we can prefetch, and which have already been prefetched; each call to this + * function picks up where the previous call left off. + * + * Note: we expect the deltids array to be sorted in an order that groups TIDs + * by heap block, with all TIDs for each block appearing together in exactly + * one group. */ static void -xid_horizon_prefetch_buffer(Relation rel, - XidHorizonPrefetchState *prefetch_state, - int prefetch_count) +index_delete_prefetch_buffer(Relation rel, + IndexDeletePrefetchState *prefetch_state, + int prefetch_count) { BlockNumber cur_hblkno = prefetch_state->cur_hblkno; int count = 0; int i; - int nitems = prefetch_state->nitems; - ItemPointerData *tids = prefetch_state->tids; + int ndeltids = prefetch_state->ndeltids; + TM_IndexDelete *deltids = prefetch_state->deltids; for (i = prefetch_state->next_item; - i < nitems && count < prefetch_count; + i < ndeltids && count < prefetch_count; i++) { - ItemPointer htid = &tids[i]; + ItemPointer htid = &deltids[i].tid; if (cur_hblkno == InvalidBlockNumber || ItemPointerGetBlockNumber(htid) != cur_hblkno) @@ -7093,52 +7369,67 @@ xid_horizon_prefetch_buffer(Relation rel, #endif /* - * Get the latestRemovedXid from the heap pages pointed at by the index - * tuples being deleted. + * heapam implementation of tableam's index_delete_tuples interface. * - * We used to do this during recovery rather than on the primary, but that - * approach now appears inferior. It meant that the primary could generate - * a lot of work for the standby without any back-pressure to slow down the - * primary, and it required the standby to have reached consistency, whereas - * we want to have correct information available even before that point. + * This helper function is called by index AMs during index tuple deletion. + * See tableam header comments for an explanation of the interface implemented + * here and a general theory of operation. Note that each call here is either + * a simple index deletion call, or a bottom-up index deletion call. * * It's possible for this to generate a fair amount of I/O, since we may be * deleting hundreds of tuples from a single index block. To amortize that * cost to some degree, this uses prefetching and combines repeat accesses to - * the same block. + * the same heap block. */ TransactionId -heap_compute_xid_horizon_for_tuples(Relation rel, - ItemPointerData *tids, - int nitems) +heap_index_delete_tuples(Relation rel, TM_IndexDeleteOp *delstate) { + /* Initial assumption is that earlier pruning took care of conflict */ TransactionId latestRemovedXid = InvalidTransactionId; - BlockNumber hblkno; + BlockNumber blkno = InvalidBlockNumber; Buffer buf = InvalidBuffer; - Page hpage; + Page page = NULL; + OffsetNumber maxoff = InvalidOffsetNumber; + TransactionId priorXmax; #ifdef USE_PREFETCH - XidHorizonPrefetchState prefetch_state; + IndexDeletePrefetchState prefetch_state; int prefetch_distance; #endif + SnapshotData SnapshotNonVacuumable; + int finalndeltids = 0, + nblocksaccessed = 0; + + /* State that's only used in bottom-up index deletion case */ + int nblocksfavorable = 0; + int curtargetfreespace = delstate->bottomupfreespace, + lastfreespace = 0, + actualfreespace = 0; + bool bottomup_final_block = false; + + InitNonVacuumableSnapshot(SnapshotNonVacuumable, GlobalVisTestFor(rel)); + + /* Sort caller's deltids array by TID for further processing */ + index_delete_sort(delstate); /* - * Sort to avoid repeated lookups for the same page, and to make it more - * likely to access items in an efficient order. In particular, this - * ensures that if there are multiple pointers to the same page, they all - * get processed looking up and locking the page just once. + * Bottom-up case: resort deltids array in an order attuned to where the + * greatest number of promising TIDs are to be found, and determine how + * many blocks from the start of sorted array should be considered + * favorable. This will also shrink the deltids array in order to + * eliminate completely unfavorable blocks up front. */ - qsort((void *) tids, nitems, sizeof(ItemPointerData), - (int (*) (const void *, const void *)) ItemPointerCompare); + if (delstate->bottomup) + nblocksfavorable = bottomup_sort_and_shrink(delstate); #ifdef USE_PREFETCH /* Initialize prefetch state. */ prefetch_state.cur_hblkno = InvalidBlockNumber; prefetch_state.next_item = 0; - prefetch_state.nitems = nitems; - prefetch_state.tids = tids; + prefetch_state.ndeltids = delstate->ndeltids; + prefetch_state.deltids = delstate->deltids; /* - * Compute the prefetch distance that we will attempt to maintain. + * Determine the prefetch distance that we will attempt to maintain. * * Since the caller holds a buffer lock somewhere in rel, we'd better make * sure that isn't a catalog relation before we call code that does @@ -7150,36 +7441,111 @@ heap_compute_xid_horizon_for_tuples(Relation rel, prefetch_distance = get_tablespace_maintenance_io_concurrency(rel->rd_rel->reltablespace); + /* Cap initial prefetch distance for bottom-up deletion caller */ + if (delstate->bottomup) + { + Assert(nblocksfavorable >= 1); + Assert(nblocksfavorable <= BOTTOMUP_MAX_NBLOCKS); + prefetch_distance = Min(prefetch_distance, nblocksfavorable); + } + /* Start prefetching. */ - xid_horizon_prefetch_buffer(rel, &prefetch_state, prefetch_distance); + index_delete_prefetch_buffer(rel, &prefetch_state, prefetch_distance); #endif - /* Iterate over all tids, and check their horizon */ - hblkno = InvalidBlockNumber; - hpage = NULL; - for (int i = 0; i < nitems; i++) + /* Iterate over deltids, determine which to delete, check their horizon */ + Assert(delstate->ndeltids > 0); + for (int i = 0; i < delstate->ndeltids; i++) { - ItemPointer htid = &tids[i]; - ItemId hitemid; - OffsetNumber hoffnum; + TM_IndexDelete *ideltid = &delstate->deltids[i]; + TM_IndexStatus *istatus = delstate->status + ideltid->id; + ItemPointer htid = &ideltid->tid; + OffsetNumber offnum; /* - * Read heap buffer, but avoid refetching if it's the same block as - * required for the last tid. + * Read buffer, and perform required extra steps each time a new block + * is encountered. Avoid refetching if it's the same block as the one + * from the last htid. */ - if (hblkno == InvalidBlockNumber || - ItemPointerGetBlockNumber(htid) != hblkno) + if (blkno == InvalidBlockNumber || + ItemPointerGetBlockNumber(htid) != blkno) { - /* release old buffer */ - if (BufferIsValid(buf)) + /* + * Consider giving up early for bottom-up index deletion caller + * first. (Only prefetch next-next block afterwards, when it + * becomes clear that we're at least going to access the next + * block in line.) + * + * Sometimes the first block frees so much space for bottom-up + * caller that the deletion process can end without accessing any + * more blocks. It is usually necessary to access 2 or 3 blocks + * per bottom-up deletion operation, though. + */ + if (delstate->bottomup) { - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buf); + /* + * We often allow caller to delete a few additional items + * whose entries we reached after the point that space target + * from caller was satisfied. The cost of accessing the page + * was already paid at that point, so it made sense to finish + * it off. When that happened, we finalize everything here + * (by finishing off the whole bottom-up deletion operation + * without needlessly paying the cost of accessing any more + * blocks). + */ + if (bottomup_final_block) + break; + + /* + * Give up when we didn't enable our caller to free any + * additional space as a result of processing the page that we + * just finished up with. This rule is the main way in which + * we keep the cost of bottom-up deletion under control. + */ + if (nblocksaccessed >= 1 && actualfreespace == lastfreespace) + break; + lastfreespace = actualfreespace; /* for next time */ + + /* + * Deletion operation (which is bottom-up) will definitely + * access the next block in line. Prepare for that now. + * + * Decay target free space so that we don't hang on for too + * long with a marginal case. (Space target is only truly + * helpful when it allows us to recognize that we don't need + * to access more than 1 or 2 blocks to satisfy caller due to + * agreeable workload characteristics.) + * + * We are a bit more patient when we encounter contiguous + * blocks, though: these are treated as favorable blocks. The + * decay process is only applied when the next block in line + * is not a favorable/contiguous block. This is not an + * exception to the general rule; we still insist on finding + * at least one deletable item per block accessed. See + * bottomup_nblocksfavorable() for full details of the theory + * behind favorable blocks and heap block locality in general. + * + * Note: The first block in line is always treated as a + * favorable block, so the earliest possible point that the + * decay can be applied is just before we access the second + * block in line. The Assert() verifies this for us. + */ + Assert(nblocksaccessed > 0 || nblocksfavorable > 0); + if (nblocksfavorable > 0) + nblocksfavorable--; + else + curtargetfreespace /= 2; } - hblkno = ItemPointerGetBlockNumber(htid); + /* release old buffer */ + if (BufferIsValid(buf)) + UnlockReleaseBuffer(buf); - buf = ReadBuffer(rel, hblkno); + blkno = ItemPointerGetBlockNumber(htid); + buf = ReadBuffer(rel, blkno); + nblocksaccessed++; + Assert(!delstate->bottomup || + nblocksaccessed <= BOTTOMUP_MAX_NBLOCKS); #ifdef USE_PREFETCH @@ -7187,152 +7553,492 @@ heap_compute_xid_horizon_for_tuples(Relation rel, * To maintain the prefetch distance, prefetch one more page for * each page we read. */ - xid_horizon_prefetch_buffer(rel, &prefetch_state, 1); + index_delete_prefetch_buffer(rel, &prefetch_state, 1); #endif - hpage = BufferGetPage(buf); - LockBuffer(buf, BUFFER_LOCK_SHARE); - } - hoffnum = ItemPointerGetOffsetNumber(htid); - hitemid = PageGetItemId(hpage, hoffnum); + page = BufferGetPage(buf); + maxoff = PageGetMaxOffsetNumber(page); + } - /* - * Follow any redirections until we find something useful. - */ - while (ItemIdIsRedirected(hitemid)) + if (istatus->knowndeletable) + Assert(!delstate->bottomup && !istatus->promising); + else { - hoffnum = ItemIdGetRedirect(hitemid); - hitemid = PageGetItemId(hpage, hoffnum); - CHECK_FOR_INTERRUPTS(); + ItemPointerData tmp = *htid; + HeapTupleData heapTuple; + + /* Are any tuples from this HOT chain non-vacuumable? */ + if (heap_hot_search_buffer(&tmp, rel, buf, &SnapshotNonVacuumable, + &heapTuple, NULL, true)) + continue; /* can't delete entry */ + + /* Caller will delete, since whole HOT chain is vacuumable */ + istatus->knowndeletable = true; + + /* Maintain index free space info for bottom-up deletion case */ + if (delstate->bottomup) + { + Assert(istatus->freespace > 0); + actualfreespace += istatus->freespace; + if (actualfreespace >= curtargetfreespace) + bottomup_final_block = true; + } } /* - * If the heap item has storage, then read the header and use that to - * set latestRemovedXid. - * - * Some LP_DEAD items may not be accessible, so we ignore them. + * Maintain latestRemovedXid value for deletion operation as a whole + * by advancing current value using heap tuple headers. This is + * loosely based on the logic for pruning a HOT chain. */ - if (ItemIdHasStorage(hitemid)) + offnum = ItemPointerGetOffsetNumber(htid); + priorXmax = InvalidTransactionId; /* cannot check first XMIN */ + for (;;) { - HeapTupleHeader htuphdr; + ItemId lp; + HeapTupleHeader htup; - htuphdr = (HeapTupleHeader) PageGetItem(hpage, hitemid); + /* Some sanity checks */ + if (offnum < FirstOffsetNumber || offnum > maxoff) + { + Assert(false); + break; + } + + lp = PageGetItemId(page, offnum); + if (ItemIdIsRedirected(lp)) + { + offnum = ItemIdGetRedirect(lp); + continue; + } + + /* + * We'll often encounter LP_DEAD line pointers (especially with an + * entry marked knowndeletable by our caller up front). No heap + * tuple headers get examined for an htid that leads us to an + * LP_DEAD item. This is okay because the earlier pruning + * operation that made the line pointer LP_DEAD in the first place + * must have considered the original tuple header as part of + * generating its own latestRemovedXid value. + * + * Relying on XLOG_HEAP2_PRUNE records like this is the same + * strategy that index vacuuming uses in all cases. Index VACUUM + * WAL records don't even have a latestRemovedXid field of their + * own for this reason. + */ + if (!ItemIdIsNormal(lp)) + break; + + htup = (HeapTupleHeader) PageGetItem(page, lp); + + /* + * Check the tuple XMIN against prior XMAX, if any + */ + if (TransactionIdIsValid(priorXmax) && + !TransactionIdEquals(HeapTupleHeaderGetXmin(htup), priorXmax)) + break; + + HeapTupleHeaderAdvanceLatestRemovedXid(htup, &latestRemovedXid); - HeapTupleHeaderAdvanceLatestRemovedXid(htuphdr, &latestRemovedXid); - } - else if (ItemIdIsDead(hitemid)) - { /* - * Conjecture: if hitemid is dead then it had xids before the xids - * marked on LP_NORMAL items. So we just ignore this item and move - * onto the next, for the purposes of calculating - * latestRemovedXid. + * If the tuple is not HOT-updated, then we are at the end of this + * HOT-chain. No need to visit later tuples from the same update + * chain (they get their own index entries) -- just move on to + * next htid from index AM caller. */ + if (!HeapTupleHeaderIsHotUpdated(htup)) + break; + + /* Advance to next HOT chain member */ + Assert(ItemPointerGetBlockNumber(&htup->t_ctid) == blkno); + offnum = ItemPointerGetOffsetNumber(&htup->t_ctid); + priorXmax = HeapTupleHeaderGetUpdateXid(htup); } - else - Assert(!ItemIdIsUsed(hitemid)); + /* Enable further/final shrinking of deltids for caller */ + finalndeltids = i + 1; } - if (BufferIsValid(buf)) - { - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buf); - } + UnlockReleaseBuffer(buf); /* - * If all heap tuples were LP_DEAD then we will be returning - * InvalidTransactionId here, which avoids conflicts. This matches - * existing logic which assumes that LP_DEAD tuples must already be older - * than the latestRemovedXid on the cleanup record that set them as - * LP_DEAD, hence must already have generated a conflict. + * Shrink deltids array to exclude non-deletable entries at the end. This + * is not just a minor optimization. Final deltids array size might be + * zero for a bottom-up caller. Index AM is explicitly allowed to rely on + * ndeltids being zero in all cases with zero total deletable entries. */ + Assert(finalndeltids > 0 || delstate->bottomup); + delstate->ndeltids = finalndeltids; return latestRemovedXid; } /* - * Perform XLogInsert to register a heap cleanup info message. These - * messages are sent once per VACUUM and are required because - * of the phasing of removal operations during a lazy VACUUM. - * see comments for vacuum_log_cleanup_info(). + * Specialized inlineable comparison function for index_delete_sort() */ -XLogRecPtr -log_heap_cleanup_info(RelFileNode rnode, TransactionId latestRemovedXid) +static inline int +index_delete_sort_cmp(TM_IndexDelete *deltid1, TM_IndexDelete *deltid2) { - xl_heap_cleanup_info xlrec; - XLogRecPtr recptr; + ItemPointer tid1 = &deltid1->tid; + ItemPointer tid2 = &deltid2->tid; - xlrec.node = rnode; - xlrec.latestRemovedXid = latestRemovedXid; + { + BlockNumber blk1 = ItemPointerGetBlockNumber(tid1); + BlockNumber blk2 = ItemPointerGetBlockNumber(tid2); - XLogBeginInsert(); - XLogRegisterData((char *) &xlrec, SizeOfHeapCleanupInfo); + if (blk1 != blk2) + return (blk1 < blk2) ? -1 : 1; + } + { + OffsetNumber pos1 = ItemPointerGetOffsetNumber(tid1); + OffsetNumber pos2 = ItemPointerGetOffsetNumber(tid2); - recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_CLEANUP_INFO); + if (pos1 != pos2) + return (pos1 < pos2) ? -1 : 1; + } - return recptr; + pg_unreachable(); + + return 0; +} + +/* + * Sort deltids array from delstate by TID. This prepares it for further + * processing by heap_index_delete_tuples(). + * + * This operation becomes a noticeable consumer of CPU cycles with some + * workloads, so we go to the trouble of specialization/micro optimization. + * We use shellsort for this because it's easy to specialize, compiles to + * relatively few instructions, and is adaptive to presorted inputs/subsets + * (which are typical here). + */ +static void +index_delete_sort(TM_IndexDeleteOp *delstate) +{ + TM_IndexDelete *deltids = delstate->deltids; + int ndeltids = delstate->ndeltids; + int low = 0; + + /* + * Shellsort gap sequence (taken from Sedgewick-Incerpi paper). + * + * This implementation is fast with array sizes up to ~4500. This covers + * all supported BLCKSZ values. + */ + const int gaps[9] = {1968, 861, 336, 112, 48, 21, 7, 3, 1}; + + /* Think carefully before changing anything here -- keep swaps cheap */ + StaticAssertStmt(sizeof(TM_IndexDelete) <= 8, + "element size exceeds 8 bytes"); + + for (int g = 0; g < lengthof(gaps); g++) + { + for (int hi = gaps[g], i = low + hi; i < ndeltids; i++) + { + TM_IndexDelete d = deltids[i]; + int j = i; + + while (j >= hi && index_delete_sort_cmp(&deltids[j - hi], &d) >= 0) + { + deltids[j] = deltids[j - hi]; + j -= hi; + } + deltids[j] = d; + } + } } /* - * Perform XLogInsert for a heap-clean operation. Caller must already - * have modified the buffer and marked it dirty. + * Returns how many blocks should be considered favorable/contiguous for a + * bottom-up index deletion pass. This is a number of heap blocks that starts + * from and includes the first block in line. + * + * There is always at least one favorable block during bottom-up index + * deletion. In the worst case (i.e. with totally random heap blocks) the + * first block in line (the only favorable block) can be thought of as a + * degenerate array of contiguous blocks that consists of a single block. + * heap_index_delete_tuples() will expect this. + * + * Caller passes blockgroups, a description of the final order that deltids + * will be sorted in for heap_index_delete_tuples() bottom-up index deletion + * processing. Note that deltids need not actually be sorted just yet (caller + * only passes deltids to us so that we can interpret blockgroups). * - * Note: prior to Postgres 8.3, the entries in the nowunused[] array were - * zero-based tuple indexes. Now they are one-based like other uses - * of OffsetNumber. + * You might guess that the existence of contiguous blocks cannot matter much, + * since in general the main factor that determines which blocks we visit is + * the number of promising TIDs, which is a fixed hint from the index AM. + * We're not really targeting the general case, though -- the actual goal is + * to adapt our behavior to a wide variety of naturally occurring conditions. + * The effects of most of the heuristics we apply are only noticeable in the + * aggregate, over time and across many _related_ bottom-up index deletion + * passes. * - * We also include latestRemovedXid, which is the greatest XID present in - * the removed tuples. That allows recovery processing to cancel or wait - * for long standby queries that can still see these tuples. + * Deeming certain blocks favorable allows heapam to recognize and adapt to + * workloads where heap blocks visited during bottom-up index deletion can be + * accessed contiguously, in the sense that each newly visited block is the + * neighbor of the block that bottom-up deletion just finished processing (or + * close enough to it). It will likely be cheaper to access more favorable + * blocks sooner rather than later (e.g. in this pass, not across a series of + * related bottom-up passes). Either way it is probably only a matter of time + * (or a matter of further correlated version churn) before all blocks that + * appear together as a single large batch of favorable blocks get accessed by + * _some_ bottom-up pass. Large batches of favorable blocks tend to either + * appear almost constantly or not even once (it all depends on per-index + * workload characteristics). + * + * Note that the blockgroups sort order applies a power-of-two bucketing + * scheme that creates opportunities for contiguous groups of blocks to get + * batched together, at least with workloads that are naturally amenable to + * being driven by heap block locality. This doesn't just enhance the spatial + * locality of bottom-up heap block processing in the obvious way. It also + * enables temporal locality of access, since sorting by heap block number + * naturally tends to make the bottom-up processing order deterministic. + * + * Consider the following example to get a sense of how temporal locality + * might matter: There is a heap relation with several indexes, each of which + * is low to medium cardinality. It is subject to constant non-HOT updates. + * The updates are skewed (in one part of the primary key, perhaps). None of + * the indexes are logically modified by the UPDATE statements (if they were + * then bottom-up index deletion would not be triggered in the first place). + * Naturally, each new round of index tuples (for each heap tuple that gets a + * heap_update() call) will have the same heap TID in each and every index. + * Since these indexes are low cardinality and never get logically modified, + * heapam processing during bottom-up deletion passes will access heap blocks + * in approximately sequential order. Temporal locality of access occurs due + * to bottom-up deletion passes behaving very similarly across each of the + * indexes at any given moment. This keeps the number of buffer misses needed + * to visit heap blocks to a minimum. */ -XLogRecPtr -log_heap_clean(Relation reln, Buffer buffer, - OffsetNumber *redirected, int nredirected, - OffsetNumber *nowdead, int ndead, - OffsetNumber *nowunused, int nunused, - TransactionId latestRemovedXid) +static int +bottomup_nblocksfavorable(IndexDeleteCounts *blockgroups, int nblockgroups, + TM_IndexDelete *deltids) { - xl_heap_clean xlrec; - XLogRecPtr recptr; + int64 lastblock = -1; + int nblocksfavorable = 0; - /* Caller should not call me on a non-WAL-logged relation */ - Assert(RelationNeedsWAL(reln)); + Assert(nblockgroups >= 1); + Assert(nblockgroups <= BOTTOMUP_MAX_NBLOCKS); - xlrec.latestRemovedXid = latestRemovedXid; - xlrec.nredirected = nredirected; - xlrec.ndead = ndead; + /* + * We tolerate heap blocks that will be accessed only slightly out of + * physical order. Small blips occur when a pair of almost-contiguous + * blocks happen to fall into different buckets (perhaps due only to a + * small difference in npromisingtids that the bucketing scheme didn't + * quite manage to ignore). We effectively ignore these blips by applying + * a small tolerance. The precise tolerance we use is a little arbitrary, + * but it works well enough in practice. + */ + for (int b = 0; b < nblockgroups; b++) + { + IndexDeleteCounts *group = blockgroups + b; + TM_IndexDelete *firstdtid = deltids + group->ifirsttid; + BlockNumber block = ItemPointerGetBlockNumber(&firstdtid->tid); - XLogBeginInsert(); - XLogRegisterData((char *) &xlrec, SizeOfHeapClean); + if (lastblock != -1 && + ((int64) block < lastblock - BOTTOMUP_TOLERANCE_NBLOCKS || + (int64) block > lastblock + BOTTOMUP_TOLERANCE_NBLOCKS)) + break; - XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + nblocksfavorable++; + lastblock = block; + } + + /* Always indicate that there is at least 1 favorable block */ + Assert(nblocksfavorable >= 1); + + return nblocksfavorable; +} + +/* + * qsort comparison function for bottomup_sort_and_shrink() + */ +static int +bottomup_sort_and_shrink_cmp(const void *arg1, const void *arg2) +{ + const IndexDeleteCounts *group1 = (const IndexDeleteCounts *) arg1; + const IndexDeleteCounts *group2 = (const IndexDeleteCounts *) arg2; /* - * The OffsetNumber arrays are not actually in the buffer, but we pretend - * that they are. When XLogInsert stores the whole buffer, the offset - * arrays need not be stored too. Note that even if all three arrays are - * empty, we want to expose the buffer as a candidate for whole-page - * storage, since this record type implies a defragmentation operation - * even if no line pointers changed state. + * Most significant field is npromisingtids (which we invert the order of + * so as to sort in desc order). + * + * Caller should have already normalized npromisingtids fields into + * power-of-two values (buckets). */ - if (nredirected > 0) - XLogRegisterBufData(0, (char *) redirected, - nredirected * sizeof(OffsetNumber) * 2); + if (group1->npromisingtids > group2->npromisingtids) + return -1; + if (group1->npromisingtids < group2->npromisingtids) + return 1; - if (ndead > 0) - XLogRegisterBufData(0, (char *) nowdead, - ndead * sizeof(OffsetNumber)); + /* + * Tiebreak: desc ntids sort order. + * + * We cannot expect power-of-two values for ntids fields. We should + * behave as if they were already rounded up for us instead. + */ + if (group1->ntids != group2->ntids) + { + uint32 ntids1 = pg_nextpower2_32((uint32) group1->ntids); + uint32 ntids2 = pg_nextpower2_32((uint32) group2->ntids); - if (nunused > 0) - XLogRegisterBufData(0, (char *) nowunused, - nunused * sizeof(OffsetNumber)); + if (ntids1 > ntids2) + return -1; + if (ntids1 < ntids2) + return 1; + } - recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_CLEAN); + /* + * Tiebreak: asc offset-into-deltids-for-block (offset to first TID for + * block in deltids array) order. + * + * This is equivalent to sorting in ascending heap block number order + * (among otherwise equal subsets of the array). This approach allows us + * to avoid accessing the out-of-line TID. (We rely on the assumption + * that the deltids array was sorted in ascending heap TID order when + * these offsets to the first TID from each heap block group were formed.) + */ + if (group1->ifirsttid > group2->ifirsttid) + return 1; + if (group1->ifirsttid < group2->ifirsttid) + return -1; - return recptr; + pg_unreachable(); + + return 0; +} + +/* + * heap_index_delete_tuples() helper function for bottom-up deletion callers. + * + * Sorts deltids array in the order needed for useful processing by bottom-up + * deletion. The array should already be sorted in TID order when we're + * called. The sort process groups heap TIDs from deltids into heap block + * groupings. Earlier/more-promising groups/blocks are usually those that are + * known to have the most "promising" TIDs. + * + * Sets new size of deltids array (ndeltids) in state. deltids will only have + * TIDs from the BOTTOMUP_MAX_NBLOCKS most promising heap blocks when we + * return. This often means that deltids will be shrunk to a small fraction + * of its original size (we eliminate many heap blocks from consideration for + * caller up front). + * + * Returns the number of "favorable" blocks. See bottomup_nblocksfavorable() + * for a definition and full details. + */ +static int +bottomup_sort_and_shrink(TM_IndexDeleteOp *delstate) +{ + IndexDeleteCounts *blockgroups; + TM_IndexDelete *reordereddeltids; + BlockNumber curblock = InvalidBlockNumber; + int nblockgroups = 0; + int ncopied = 0; + int nblocksfavorable = 0; + + Assert(delstate->bottomup); + Assert(delstate->ndeltids > 0); + + /* Calculate per-heap-block count of TIDs */ + blockgroups = palloc(sizeof(IndexDeleteCounts) * delstate->ndeltids); + for (int i = 0; i < delstate->ndeltids; i++) + { + TM_IndexDelete *ideltid = &delstate->deltids[i]; + TM_IndexStatus *istatus = delstate->status + ideltid->id; + ItemPointer htid = &ideltid->tid; + bool promising = istatus->promising; + + if (curblock != ItemPointerGetBlockNumber(htid)) + { + /* New block group */ + nblockgroups++; + + Assert(curblock < ItemPointerGetBlockNumber(htid) || + !BlockNumberIsValid(curblock)); + + curblock = ItemPointerGetBlockNumber(htid); + blockgroups[nblockgroups - 1].ifirsttid = i; + blockgroups[nblockgroups - 1].ntids = 1; + blockgroups[nblockgroups - 1].npromisingtids = 0; + } + else + { + blockgroups[nblockgroups - 1].ntids++; + } + + if (promising) + blockgroups[nblockgroups - 1].npromisingtids++; + } + + /* + * We're about ready to sort block groups to determine the optimal order + * for visiting heap blocks. But before we do, round the number of + * promising tuples for each block group up to the next power-of-two, + * unless it is very low (less than 4), in which case we round up to 4. + * npromisingtids is far too noisy to trust when choosing between a pair + * of block groups that both have very low values. + * + * This scheme divides heap blocks/block groups into buckets. Each bucket + * contains blocks that have _approximately_ the same number of promising + * TIDs as each other. The goal is to ignore relatively small differences + * in the total number of promising entries, so that the whole process can + * give a little weight to heapam factors (like heap block locality) + * instead. This isn't a trade-off, really -- we have nothing to lose. It + * would be foolish to interpret small differences in npromisingtids + * values as anything more than noise. + * + * We tiebreak on nhtids when sorting block group subsets that have the + * same npromisingtids, but this has the same issues as npromisingtids, + * and so nhtids is subject to the same power-of-two bucketing scheme. The + * only reason that we don't fix nhtids in the same way here too is that + * we'll need accurate nhtids values after the sort. We handle nhtids + * bucketization dynamically instead (in the sort comparator). + * + * See bottomup_nblocksfavorable() for a full explanation of when and how + * heap locality/favorable blocks can significantly influence when and how + * heap blocks are accessed. + */ + for (int b = 0; b < nblockgroups; b++) + { + IndexDeleteCounts *group = blockgroups + b; + + /* Better off falling back on nhtids with low npromisingtids */ + if (group->npromisingtids <= 4) + group->npromisingtids = 4; + else + group->npromisingtids = + pg_nextpower2_32((uint32) group->npromisingtids); + } + + /* Sort groups and rearrange caller's deltids array */ + qsort(blockgroups, nblockgroups, sizeof(IndexDeleteCounts), + bottomup_sort_and_shrink_cmp); + reordereddeltids = palloc(delstate->ndeltids * sizeof(TM_IndexDelete)); + + nblockgroups = Min(BOTTOMUP_MAX_NBLOCKS, nblockgroups); + /* Determine number of favorable blocks at the start of final deltids */ + nblocksfavorable = bottomup_nblocksfavorable(blockgroups, nblockgroups, + delstate->deltids); + + for (int b = 0; b < nblockgroups; b++) + { + IndexDeleteCounts *group = blockgroups + b; + TM_IndexDelete *firstdtid = delstate->deltids + group->ifirsttid; + + memcpy(reordereddeltids + ncopied, firstdtid, + sizeof(TM_IndexDelete) * group->ntids); + ncopied += group->ntids; + } + + /* Copy final grouped and sorted TIDs back into start of caller's array */ + memcpy(delstate->deltids, reordereddeltids, + sizeof(TM_IndexDelete) * ncopied); + delstate->ndeltids = ncopied; + + pfree(reordereddeltids); + pfree(blockgroups); + + return nblocksfavorable; } /* @@ -7651,7 +8357,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) /* * If the tuple got inserted & deleted in the same TX we definitely have a - * combocid, set cmin and cmax. + * combo CID, set cmin and cmax. */ if (hdr->t_infomask & HEAP_COMBOCID) { @@ -7661,7 +8367,7 @@ log_heap_new_cid(Relation relation, HeapTuple tup) xlrec.cmax = HeapTupleHeaderGetCmax(hdr); xlrec.combocid = HeapTupleHeaderGetRawCommandId(hdr); } - /* No combocid, so only cmin or cmax can be set by this TX */ + /* No combo CID, so only cmin or cmax can be set by this TX */ else { /* @@ -7806,34 +8512,15 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, } /* - * Handles CLEANUP_INFO - */ -static void -heap_xlog_cleanup_info(XLogReaderState *record) -{ - xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) XLogRecGetData(record); - - if (InHotStandby) - ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid, xlrec->node); - - /* - * Actual operation is a no-op. Record type exists to provide a means for - * conflict processing to occur before we begin index vacuum actions. see - * vacuumlazy.c and also comments in btvacuumpage() - */ - - /* Backup blocks are not used in cleanup_info records */ - Assert(!XLogRecHasAnyBlockRefs(record)); -} - -/* - * Handles XLOG_HEAP2_CLEAN record type + * Handles XLOG_HEAP2_PRUNE record type. + * + * Acquires a super-exclusive lock. */ static void -heap_xlog_clean(XLogReaderState *record) +heap_xlog_prune(XLogReaderState *record) { XLogRecPtr lsn = record->EndRecPtr; - xl_heap_clean *xlrec = (xl_heap_clean *) XLogRecGetData(record); + xl_heap_prune *xlrec = (xl_heap_prune *) XLogRecGetData(record); Buffer buffer; RelFileNode rnode; BlockNumber blkno; @@ -7844,12 +8531,8 @@ heap_xlog_clean(XLogReaderState *record) /* * We're about to remove tuples. In Hot Standby mode, ensure that there's * no queries running for which the removed tuples are still visible. - * - * Not all HEAP2_CLEAN records remove tuples with xids, so we only want to - * conflict on the records that cause MVCC failures for user queries. If - * latestRemovedXid is invalid, skip conflict processing. */ - if (InHotStandby && TransactionIdIsValid(xlrec->latestRemovedXid)) + if (InHotStandby) ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid, rnode); /* @@ -7902,7 +8585,7 @@ heap_xlog_clean(XLogReaderState *record) UnlockReleaseBuffer(buffer); /* - * After cleaning records from a page, it's useful to update the FSM + * After pruning records from a page, it's useful to update the FSM * about it, as it may cause the page become target for insertions * later even if vacuum decides not to visit it (which is possible if * gets marked all-visible.) @@ -7914,6 +8597,78 @@ heap_xlog_clean(XLogReaderState *record) } } +/* + * Handles XLOG_HEAP2_VACUUM record type. + * + * Acquires an exclusive lock only. + */ +static void +heap_xlog_vacuum(XLogReaderState *record) +{ + XLogRecPtr lsn = record->EndRecPtr; + xl_heap_vacuum *xlrec = (xl_heap_vacuum *) XLogRecGetData(record); + Buffer buffer; + BlockNumber blkno; + XLogRedoAction action; + + /* + * If we have a full-page image, restore it (without using a cleanup lock) + * and we're done. + */ + action = XLogReadBufferForRedoExtended(record, 0, RBM_NORMAL, false, + &buffer); + if (action == BLK_NEEDS_REDO) + { + Page page = (Page) BufferGetPage(buffer); + OffsetNumber *nowunused; + Size datalen; + OffsetNumber *offnum; + + nowunused = (OffsetNumber *) XLogRecGetBlockData(record, 0, &datalen); + + /* Shouldn't be a record unless there's something to do */ + Assert(xlrec->nunused > 0); + + /* Update all now-unused line pointers */ + offnum = nowunused; + for (int i = 0; i < xlrec->nunused; i++) + { + OffsetNumber off = *offnum++; + ItemId lp = PageGetItemId(page, off); + + Assert(ItemIdIsDead(lp) && !ItemIdHasStorage(lp)); + ItemIdSetUnused(lp); + } + + /* Attempt to truncate line pointer array now */ + PageTruncateLinePointerArray(page); + + PageSetLSN(page, lsn); + MarkBufferDirty(buffer); + } + + if (BufferIsValid(buffer)) + { + Size freespace = PageGetHeapFreeSpace(BufferGetPage(buffer)); + RelFileNode rnode; + + XLogRecGetBlockTag(record, 0, &rnode, NULL, &blkno); + + UnlockReleaseBuffer(buffer); + + /* + * After vacuuming LP_DEAD items from a page, it's useful to update + * the FSM about it, as it may cause the page become target for + * insertions later even if vacuum decides not to visit it (which is + * possible if gets marked all-visible.) + * + * Do this regardless of a full-page image being applied, since the + * FSM data is not in the page anyway. + */ + XLogRecordPageWithFreeSpace(rnode, blkno, freespace); + } +} + /* * Replay XLOG_HEAP2_VISIBLE record. * @@ -8318,6 +9073,10 @@ heap_xlog_insert(XLogReaderState *record) if (xlrec->flags & XLH_INSERT_ALL_VISIBLE_CLEARED) PageClearAllVisible(page); + /* XLH_INSERT_ALL_FROZEN_SET implies that all tuples are visible */ + if (xlrec->flags & XLH_INSERT_ALL_FROZEN_SET) + PageSetAllVisible(page); + MarkBufferDirty(buffer); } if (BufferIsValid(buffer)) @@ -8368,6 +9127,10 @@ heap_xlog_multi_insert(XLogReaderState *record) XLogRecGetBlockTag(record, 0, &rnode, NULL, &blkno); + /* check that the mutually exclusive flags are not both set */ + Assert(!((xlrec->flags & XLH_INSERT_ALL_VISIBLE_CLEARED) && + (xlrec->flags & XLH_INSERT_ALL_FROZEN_SET))); + /* * The visibility map may need to be fixed even if the heap page is * already up-to-date. @@ -8457,6 +9220,10 @@ heap_xlog_multi_insert(XLogReaderState *record) if (xlrec->flags & XLH_INSERT_ALL_VISIBLE_CLEARED) PageClearAllVisible(page); + /* XLH_INSERT_ALL_FROZEN_SET implies that all tuples are visible */ + if (xlrec->flags & XLH_INSERT_ALL_FROZEN_SET) + PageSetAllVisible(page); + MarkBufferDirty(buffer); } if (BufferIsValid(buffer)) @@ -9011,15 +9778,15 @@ heap2_redo(XLogReaderState *record) switch (info & XLOG_HEAP_OPMASK) { - case XLOG_HEAP2_CLEAN: - heap_xlog_clean(record); + case XLOG_HEAP2_PRUNE: + heap_xlog_prune(record); + break; + case XLOG_HEAP2_VACUUM: + heap_xlog_vacuum(record); break; case XLOG_HEAP2_FREEZE_PAGE: heap_xlog_freeze_page(record); break; - case XLOG_HEAP2_CLEANUP_INFO: - heap_xlog_cleanup_info(record); - break; case XLOG_HEAP2_VISIBLE: heap_xlog_visible(record); break; diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c index 98a1cf352d7d..19f701c863e7 100644 --- a/src/backend/access/heap/heapam_handler.c +++ b/src/backend/access/heap/heapam_handler.c @@ -3,7 +3,7 @@ * heapam_handler.c * heap table access method code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -691,7 +691,7 @@ heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode) * WAL log creation if the relation is persistent, or this is the * init fork of an unlogged relation. */ - if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT || + if (RelationIsPermanent(rel) || (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && forkNum == INIT_FORKNUM)) log_smgrcreate(newrnode, forkNum, SMGR_MD); @@ -729,6 +729,7 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, Datum *values; bool *isnull; BufferHeapTupleTableSlot *hslot; + BlockNumber prev_cblock = InvalidBlockNumber; /* Remember if it's a system catalog */ is_system_catalog = IsSystemRelation(OldHeap); @@ -824,14 +825,38 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, else { if (!table_scan_getnextslot(tableScan, ForwardScanDirection, slot)) + { + /* + * If the last pages of the scan were empty, we would go to + * the next phase while heap_blks_scanned != heap_blks_total. + * Instead, to ensure that heap_blks_scanned is equivalent to + * total_heap_blks after the table scan phase, this parameter + * is manually updated to the correct value when the table + * scan finishes. + */ + pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_BLKS_SCANNED, + heapScan->rs_nblocks); break; + } /* * In scan-and-sort mode and also VACUUM FULL, set heap blocks * scanned + * + * Note that heapScan may start at an offset and wrap around, i.e. + * rs_startblock may be >0, and rs_cblock may end with a number + * below rs_startblock. To prevent showing this wraparound to the + * user, we offset rs_cblock by rs_startblock (modulo rs_nblocks). */ - pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_BLKS_SCANNED, - heapScan->rs_cblock + 1); + if (prev_cblock != heapScan->rs_cblock) + { + pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_BLKS_SCANNED, + (heapScan->rs_cblock + + heapScan->rs_nblocks - + heapScan->rs_startblock + ) % heapScan->rs_nblocks + 1); + prev_cblock = heapScan->rs_cblock; + } } tuple = ExecFetchSlotHeapTuple(slot, false, NULL); @@ -1665,13 +1690,13 @@ heapam_index_build_range_scan(Relation heapRelation, offnum = ItemPointerGetOffsetNumber(&heapTuple->t_self); /* - * If a HOT tuple points to a root that we don't know - * about, obtain root items afresh. If that still fails, - * report it as corruption. + * If a HOT tuple points to a root that we don't know about, + * obtain root items afresh. If that still fails, report it as + * corruption. */ if (root_offsets[offnum - 1] == InvalidOffsetNumber) { - Page page = BufferGetPage(hscan->rs_cbuf); + Page page = BufferGetPage(hscan->rs_cbuf); LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); heap_get_root_tuples(page, root_offsets); @@ -1964,6 +1989,7 @@ heapam_index_validate_scan(Relation heapRelation, heapRelation, indexInfo->ii_Unique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, + false, indexInfo); state->tups_inserted += 1; @@ -2550,6 +2576,9 @@ static const TableAmRoutine heapam_methods = { .scan_rescan = heap_rescan, .scan_getnextslot = heap_getnextslot, + .scan_set_tidrange = heap_set_tidrange, + .scan_getnextslot_tidrange = heap_getnextslot_tidrange, + .parallelscan_estimate = table_block_parallelscan_estimate, .parallelscan_initialize = table_block_parallelscan_initialize, .parallelscan_reinitialize = table_block_parallelscan_reinitialize, @@ -2574,13 +2603,13 @@ static const TableAmRoutine heapam_methods = { .tuple_get_latest_tid = heap_get_latest_tid, .tuple_tid_valid = heapam_tuple_tid_valid, .tuple_satisfies_snapshot = heapam_tuple_satisfies_snapshot, - .compute_xid_horizon_for_tuples = heap_compute_xid_horizon_for_tuples, + .index_delete_tuples = heap_index_delete_tuples, .relation_set_new_filenode = heapam_relation_set_new_filenode, .relation_nontransactional_truncate = heapam_relation_nontransactional_truncate, .relation_copy_data = heapam_relation_copy_data, .relation_copy_for_cluster = heapam_relation_copy_for_cluster, - .relation_vacuum = lazy_vacuum_rel_heap, + .relation_vacuum = heap_vacuum_rel, .scan_analyze_next_block = heapam_scan_analyze_next_block, .scan_analyze_next_tuple = heapam_scan_analyze_next_tuple, .index_build_range_scan = heapam_index_build_range_scan, diff --git a/src/backend/access/heap/heapam_visibility.c b/src/backend/access/heap/heapam_visibility.c index c2068fe67f27..b846af60f4f5 100644 --- a/src/backend/access/heap/heapam_visibility.c +++ b/src/backend/access/heap/heapam_visibility.c @@ -52,7 +52,7 @@ * HeapTupleSatisfiesAny() * all tuples are visible * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -689,8 +689,7 @@ HeapTupleSatisfiesUpdate(Relation relation, HeapTuple htup, CommandId curcid, { if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) return TM_Ok; - if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid) || - HeapTupleHeaderIndicatesMovedPartitions(tuple)) + if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid)) return TM_Updated; /* updated by other */ else return TM_Deleted; /* deleted by other */ @@ -735,8 +734,7 @@ HeapTupleSatisfiesUpdate(Relation relation, HeapTuple htup, CommandId curcid, if (TransactionIdDidCommit(xmax)) { - if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid) || - HeapTupleHeaderIndicatesMovedPartitions(tuple)) + if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid)) return TM_Updated; else return TM_Deleted; @@ -796,8 +794,7 @@ HeapTupleSatisfiesUpdate(Relation relation, HeapTuple htup, CommandId curcid, SetHintBits(tuple, buffer, relation, HEAP_XMAX_COMMITTED, HeapTupleHeaderGetRawXmax(tuple)); - if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid) || - HeapTupleHeaderIndicatesMovedPartitions(tuple)) + if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid)) return TM_Updated; /* updated by other */ else return TM_Deleted; /* deleted by other */ @@ -1753,29 +1750,29 @@ HeapTupleSatisfiesHistoricMVCC(Relation relation, HeapTuple htup, Snapshot snaps /* * another transaction might have (tried to) delete this tuple or - * cmin/cmax was stored in a combocid. So we need to lookup the actual - * values externally. + * cmin/cmax was stored in a combo CID. So we need to lookup the + * actual values externally. */ resolved = ResolveCminCmaxDuringDecoding(HistoricSnapshotGetTupleCids(), snapshot, htup, buffer, &cmin, &cmax); /* - * If we haven't resolved the combocid to cmin/cmax, that means we - * have not decoded the combocid yet. That means the cmin is + * If we haven't resolved the combo CID to cmin/cmax, that means we + * have not decoded the combo CID yet. That means the cmin is * definitely in the future, and we're not supposed to see the tuple * yet. * * XXX This only applies to decoding of in-progress transactions. In * regular logical decoding we only execute this code at commit time, - * at which point we should have seen all relevant combocids. So + * at which point we should have seen all relevant combo CIDs. So * ideally, we should error out in this case but in practice, this * won't happen. If we are too worried about this then we can add an * elog inside ResolveCminCmaxDuringDecoding. * - * XXX For the streaming case, we can track the largest combocid - * assigned, and error out based on this (when unable to resolve - * combocid below that observed maximum value). + * XXX For the streaming case, we can track the largest combo CID + * assigned, and error out based on this (when unable to resolve combo + * CID below that observed maximum value). */ if (!resolved) return false; @@ -1849,21 +1846,21 @@ HeapTupleSatisfiesHistoricMVCC(Relation relation, HeapTuple htup, Snapshot snaps &cmin, &cmax); /* - * If we haven't resolved the combocid to cmin/cmax, that means we - * have not decoded the combocid yet. That means the cmax is + * If we haven't resolved the combo CID to cmin/cmax, that means we + * have not decoded the combo CID yet. That means the cmax is * definitely in the future, and we're still supposed to see the * tuple. * * XXX This only applies to decoding of in-progress transactions. In * regular logical decoding we only execute this code at commit time, - * at which point we should have seen all relevant combocids. So + * at which point we should have seen all relevant combo CIDs. So * ideally, we should error out in this case but in practice, this * won't happen. If we are too worried about this then we can add an * elog inside ResolveCminCmaxDuringDecoding. * - * XXX For the streaming case, we can track the largest combocid - * assigned, and error out based on this (when unable to resolve - * combocid below that observed maximum value). + * XXX For the streaming case, we can track the largest combo CID + * assigned, and error out based on this (when unable to resolve combo + * CID below that observed maximum value). */ if (!resolved || cmax == InvalidCommandId) return true; diff --git a/src/backend/access/heap/heaptoast.c b/src/backend/access/heap/heaptoast.c index 7fec54db88db..c373d633aff4 100644 --- a/src/backend/access/heap/heaptoast.c +++ b/src/backend/access/heap/heaptoast.c @@ -4,7 +4,7 @@ * Heap-specific definitions for external and compressed storage * of variable size attributes. * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index 6e8bc1e9dc3d..c3bd9a68974e 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -3,7 +3,7 @@ * hio.c * POSTGRES heap access method input/output code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -47,6 +47,15 @@ RelationPutHeapTuple(Relation relation pg_attribute_unused(), */ Assert(!token || HeapTupleHeaderIsSpeculative(tuple->t_data)); + /* + * Do not allow tuples with invalid combinations of hint bits to be placed + * on a page. This combination is detected as corruption by the + * contrib/amcheck logic, so if you disable this assertion, make + * corresponding changes there. + */ + Assert(!((tuple->t_data->t_infomask & HEAP_XMAX_COMMITTED) && + (tuple->t_data->t_infomask & HEAP_XMAX_IS_MULTI))); + /* Add the tuple to the page */ pageHeader = BufferGetPage(buffer); @@ -284,9 +293,13 @@ RelationAddExtraBlocks(Relation relation, BulkInsertState bistate) * happen if space is freed in that page after heap_update finds there's not * enough there). In that case, the page will be pinned and locked only once. * - * For the vmbuffer and vmbuffer_other arguments, we avoid deadlock by - * locking them only after locking the corresponding heap page, and taking - * no further lwlocks while they are locked. + * We also handle the possibility that the all-visible flag will need to be + * cleared on one or both pages. If so, pin on the associated visibility map + * page must be acquired before acquiring buffer lock(s), to avoid possibly + * doing I/O while holding buffer locks. The pins are passed back to the + * caller using the input-output arguments vmbuffer and vmbuffer_other. + * Note that in some cases the caller might have already acquired such pins, + * which is indicated by these arguments not being InvalidBuffer on entry. * * We normally use FSM to help us find free space. However, * if HEAP_INSERT_SKIP_FSM is specified, we just append a new empty page to @@ -308,10 +321,10 @@ RelationAddExtraBlocks(Relation relation, BulkInsertState bistate) * BULKWRITE buffer selection strategy object to the buffer manager. * Passing NULL for bistate selects the default behavior. * - * We always try to avoid filling existing pages further than the fillfactor. - * This is OK since this routine is not consulted when updating a tuple and - * keeping it on the same page, which is the scenario fillfactor is meant - * to reserve space for. + * We don't fill existing pages further than the fillfactor, except for large + * tuples in nearly-empty pages. This is OK since this routine is not + * consulted when updating a tuple and keeping it on the same page, which is + * the scenario fillfactor is meant to reserve space for. * * ereport(ERROR) is allowed here, so this routine *must* be called * before any (unlogged) changes are made in buffer pool. @@ -325,8 +338,10 @@ RelationGetBufferForTuple(Relation relation, Size len, bool use_fsm = !(options & HEAP_INSERT_SKIP_FSM); Buffer buffer = InvalidBuffer; Page page; - Size pageFreeSpace = 0, - saveFreeSpace = 0; + Size nearlyEmptyFreeSpace, + pageFreeSpace = 0, + saveFreeSpace = 0, + targetFreeSpace = 0; BlockNumber targetBlock, otherBlock; bool needLock; @@ -349,6 +364,19 @@ RelationGetBufferForTuple(Relation relation, Size len, saveFreeSpace = RelationGetTargetPageFreeSpace(relation, HEAP_DEFAULT_FILLFACTOR); + /* + * Since pages without tuples can still have line pointers, we consider + * pages "empty" when the unavailable space is slight. This threshold is + * somewhat arbitrary, but it should prevent most unnecessary relation + * extensions while inserting large tuples into low-fillfactor tables. + */ + nearlyEmptyFreeSpace = MaxHeapTupleSize - + (MaxHeapTuplesPerPage / 8 * sizeof(ItemIdData)); + if (len + saveFreeSpace > nearlyEmptyFreeSpace) + targetFreeSpace = Max(len, nearlyEmptyFreeSpace); + else + targetFreeSpace = len + saveFreeSpace; + if (otherBuffer != InvalidBuffer) otherBlock = BufferGetBlockNumber(otherBuffer); else @@ -367,13 +395,7 @@ RelationGetBufferForTuple(Relation relation, Size len, * When use_fsm is false, we either put the tuple onto the existing target * page or extend the relation. */ - if (len + saveFreeSpace > MaxHeapTupleSize) - { - /* can't fit, don't bother asking FSM */ - targetBlock = InvalidBlockNumber; - use_fsm = false; - } - else if (bistate && bistate->current_buf != InvalidBuffer) + if (bistate && bistate->current_buf != InvalidBuffer) targetBlock = BufferGetBlockNumber(bistate->current_buf); else targetBlock = RelationGetTargetBlock(relation); @@ -384,20 +406,20 @@ RelationGetBufferForTuple(Relation relation, Size len, * We have no cached target page, so ask the FSM for an initial * target. */ - targetBlock = GetPageWithFreeSpace(relation, len + saveFreeSpace); + targetBlock = GetPageWithFreeSpace(relation, targetFreeSpace); + } - /* - * If the FSM knows nothing of the rel, try the last page before we - * give up and extend. This avoids one-tuple-per-page syndrome during - * bootstrapping or in a recently-started system. - */ - if (targetBlock == InvalidBlockNumber) - { - BlockNumber nblocks = RelationGetNumberOfBlocks(relation); + /* + * If the FSM knows nothing of the rel, try the last page before we give + * up and extend. This avoids one-tuple-per-page syndrome during + * bootstrapping or in a recently-started system. + */ + if (targetBlock == InvalidBlockNumber) + { + BlockNumber nblocks = RelationGetNumberOfBlocks(relation); - if (nblocks > 0) - targetBlock = nblocks - 1; - } + if (nblocks > 0) + targetBlock = nblocks - 1; } loop: @@ -422,6 +444,14 @@ RelationGetBufferForTuple(Relation relation, Size len, buffer = ReadBufferBI(relation, targetBlock, RBM_NORMAL, bistate); if (PageIsAllVisible(BufferGetPage(buffer))) visibilitymap_pin(relation, targetBlock, vmbuffer); + + /* + * If the page is empty, pin vmbuffer to set all_frozen bit later. + */ + if ((options & HEAP_INSERT_FROZEN) && + (PageGetMaxOffsetNumber(BufferGetPage(buffer)) == 0)) + visibilitymap_pin(relation, targetBlock, vmbuffer); + LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); } else if (otherBlock == targetBlock) @@ -500,7 +530,7 @@ RelationGetBufferForTuple(Relation relation, Size len, } pageFreeSpace = PageGetHeapFreeSpace(page); - if (len + saveFreeSpace <= pageFreeSpace) + if (targetFreeSpace <= pageFreeSpace) { /* use this page as future insert target, too */ RelationSetTargetBlock(relation, targetBlock); @@ -533,7 +563,7 @@ RelationGetBufferForTuple(Relation relation, Size len, targetBlock = RecordAndGetPageWithFreeSpace(relation, targetBlock, pageFreeSpace, - len + saveFreeSpace); + targetFreeSpace); } /* @@ -565,7 +595,7 @@ RelationGetBufferForTuple(Relation relation, Size len, * Check if some other backend has extended a block for us while * we were waiting on the lock. */ - targetBlock = GetPageWithFreeSpace(relation, len + saveFreeSpace); + targetBlock = GetPageWithFreeSpace(relation, targetFreeSpace); /* * If some other waiter has already extended the relation, we @@ -608,6 +638,15 @@ RelationGetBufferForTuple(Relation relation, Size len, PageInit(page, BufferGetPageSize(buffer), 0); MarkBufferDirty(buffer); + /* + * The page is empty, pin vmbuffer to set all_frozen bit. + */ + if (options & HEAP_INSERT_FROZEN) + { + Assert(PageGetMaxOffsetNumber(BufferGetPage(buffer)) == 0); + visibilitymap_pin(relation, BufferGetBlockNumber(buffer), vmbuffer); + } + /* * Release the file-extension lock; it's now OK for someone else to extend * the relation some more. @@ -631,6 +670,8 @@ RelationGetBufferForTuple(Relation relation, Size len, if (otherBuffer != InvalidBuffer) { Assert(otherBuffer != buffer); + targetBlock = BufferGetBlockNumber(buffer); + Assert(targetBlock > otherBlock); if (unlikely(!ConditionalLockBuffer(otherBuffer))) { @@ -639,10 +680,16 @@ RelationGetBufferForTuple(Relation relation, Size len, LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); /* - * Because the buffer was unlocked for a while, it's possible, - * although unlikely, that the page was filled. If so, just retry - * from start. + * Because the buffers were unlocked for a while, it's possible, + * although unlikely, that an all-visible flag became set or that + * somebody used up the available space in the new page. We can + * use GetVisibilityMapPins to deal with the first case. In the + * second case, just retry from start. */ + GetVisibilityMapPins(relation, otherBuffer, buffer, + otherBlock, targetBlock, vmbuffer_other, + vmbuffer); + if (len > PageGetHeapFreeSpace(page)) { LockBuffer(otherBuffer, BUFFER_LOCK_UNLOCK); diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index 5b446218cfeb..98cc9d116a12 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -3,7 +3,7 @@ * pruneheap.c * heap page pruning and HOT-chain management code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -95,8 +95,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer) /* * We can't write WAL in recovery mode, so there's no point trying to - * clean the page. The primary will likely issue a cleaning WAL record soon - * anyway, so this is no particular loss. + * clean the page. The primary will likely issue a cleaning WAL record + * soon anyway, so this is no particular loss. */ if (RecoveryInProgress()) return; @@ -182,13 +182,10 @@ heap_page_prune_opt(Relation relation, Buffer buffer) */ if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree) { - TransactionId ignore = InvalidTransactionId; /* return value not - * needed */ - /* OK to prune */ (void) heap_page_prune(relation, buffer, vistest, limited_xmin, limited_ts, - true, &ignore); + true, NULL); } /* And release buffer lock */ @@ -213,15 +210,18 @@ heap_page_prune_opt(Relation relation, Buffer buffer) * send its own new total to pgstats, and we don't want this delta applied * on top of that.) * - * Returns the number of tuples deleted from the page and sets - * latestRemovedXid. + * off_loc is the offset location required by the caller to use in error + * callback. + * + * Returns the number of tuples deleted from the page during this call. */ int heap_page_prune(Relation relation, Buffer buffer, GlobalVisState *vistest, TransactionId old_snap_xmin, TimestampTz old_snap_ts, - bool report_stats, TransactionId *latestRemovedXid) + bool report_stats, + OffsetNumber *off_loc) { int ndeleted = 0; Page page = BufferGetPage(buffer); @@ -246,7 +246,7 @@ heap_page_prune(Relation relation, Buffer buffer, prstate.old_snap_xmin = old_snap_xmin; prstate.old_snap_ts = old_snap_ts; prstate.old_snap_used = false; - prstate.latestRemovedXid = *latestRemovedXid; + prstate.latestRemovedXid = InvalidTransactionId; prstate.nredirected = prstate.ndead = prstate.nunused = 0; memset(prstate.marked, 0, sizeof(prstate.marked)); @@ -262,6 +262,13 @@ heap_page_prune(Relation relation, Buffer buffer, if (prstate.marked[offnum]) continue; + /* + * Set the offset number so that we can display it along with any + * error that occurred while processing this tuple. + */ + if (off_loc) + *off_loc = offnum; + /* Nothing to do if slot is empty or already dead */ itemid = PageGetItemId(page, offnum); if (!ItemIdIsUsed(itemid) || ItemIdIsDead(itemid)) @@ -271,6 +278,10 @@ heap_page_prune(Relation relation, Buffer buffer, ndeleted += heap_prune_chain(buffer, offnum, &prstate); } + /* Clear the offset information once we have processed the given page. */ + if (off_loc) + *off_loc = InvalidOffsetNumber; + /* Any error while applying the changes is critical */ START_CRIT_SECTION(); @@ -302,17 +313,41 @@ heap_page_prune(Relation relation, Buffer buffer, MarkBufferDirty(buffer); /* - * Emit a WAL XLOG_HEAP2_CLEAN record showing what we did + * Emit a WAL XLOG_HEAP2_PRUNE record showing what we did */ if (RelationNeedsWAL(relation)) { + xl_heap_prune xlrec; XLogRecPtr recptr; - recptr = log_heap_clean(relation, buffer, - prstate.redirected, prstate.nredirected, - prstate.nowdead, prstate.ndead, - prstate.nowunused, prstate.nunused, - prstate.latestRemovedXid); + xlrec.latestRemovedXid = prstate.latestRemovedXid; + xlrec.nredirected = prstate.nredirected; + xlrec.ndead = prstate.ndead; + + XLogBeginInsert(); + XLogRegisterData((char *) &xlrec, SizeOfHeapPrune); + + XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + + /* + * The OffsetNumber arrays are not actually in the buffer, but we + * pretend that they are. When XLogInsert stores the whole + * buffer, the offset arrays need not be stored too. + */ + if (prstate.nredirected > 0) + XLogRegisterBufData(0, (char *) prstate.redirected, + prstate.nredirected * + sizeof(OffsetNumber) * 2); + + if (prstate.ndead > 0) + XLogRegisterBufData(0, (char *) prstate.nowdead, + prstate.ndead * sizeof(OffsetNumber)); + + if (prstate.nunused > 0) + XLogRegisterBufData(0, (char *) prstate.nowunused, + prstate.nunused * sizeof(OffsetNumber)); + + recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_PRUNE); PageSetLSN(BufferGetPage(buffer), recptr); } @@ -347,8 +382,6 @@ heap_page_prune(Relation relation, Buffer buffer, if (report_stats && ndeleted > prstate.ndead) pgstat_update_heap_dead_tuples(relation, ndeleted - prstate.ndead); - *latestRemovedXid = prstate.latestRemovedXid; - /* * XXX Should we update the FSM information of this page ? * @@ -370,7 +403,7 @@ heap_page_prune(Relation relation, Buffer buffer, /* - * Perform visiblity checks for heap pruning. + * Perform visibility checks for heap pruning. * * This is more complicated than just using GlobalVisTestIsRemovableXid() * because of old_snapshot_threshold. We only want to increase the threshold @@ -793,12 +826,8 @@ heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum) /* * Perform the actual page changes needed by heap_page_prune. - * It is expected that the caller has suitable pin and lock on the - * buffer, and is inside a critical section. - * - * This is split out because it is also used by heap_xlog_clean() - * to replay the WAL record when needed after a crash. Note that the - * arguments are identical to those of log_heap_clean(). + * It is expected that the caller has a super-exclusive lock on the + * buffer. */ void heap_page_prune_execute(Buffer buffer, @@ -810,6 +839,9 @@ heap_page_prune_execute(Buffer buffer, OffsetNumber *offnum; int i; + /* Shouldn't be called unless there's something to do */ + Assert(nredirected > 0 || ndead > 0 || nunused > 0); + /* Update all redirected line pointers */ offnum = redirected; for (i = 0; i < nredirected; i++) @@ -930,6 +962,10 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets) */ for (;;) { + /* Sanity check */ + if (nextoffnum < FirstOffsetNumber || nextoffnum > maxoff) + break; + lp = PageGetItemId(page, nextoffnum); /* Check for broken chains */ diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c index 3639a165dbe0..fbe87715e952 100644 --- a/src/backend/access/heap/rewriteheap.c +++ b/src/backend/access/heap/rewriteheap.c @@ -92,7 +92,7 @@ * heap's TOAST table will go through the normal bufmgr. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION @@ -266,7 +266,6 @@ begin_heap_rewrite(Relation old_heap, Relation new_heap, TransactionId oldest_xm state->rs_cxt = rw_cxt; /* Initialize hash tables used to track update chains */ - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(TidHashKey); hash_ctl.entrysize = sizeof(UnresolvedTupData); hash_ctl.hcxt = state->rs_cxt; @@ -324,10 +323,10 @@ end_heap_rewrite(RewriteState state) state->rs_blockno, state->rs_buffer, true); - RelationOpenSmgr(state->rs_new_rel); PageSetChecksumInplace(state->rs_buffer, state->rs_blockno); + RelationOpenSmgr(state->rs_new_rel); smgrextend(state->rs_new_rel->rd_smgr, MAIN_FORKNUM, state->rs_blockno, (char *) state->rs_buffer, true); } @@ -340,7 +339,11 @@ end_heap_rewrite(RewriteState state) * wrote before the checkpoint. */ if (RelationNeedsWAL(state->rs_new_rel)) + { + /* for an empty table, this could be first smgr access */ + RelationOpenSmgr(state->rs_new_rel); smgrimmedsync(state->rs_new_rel->rd_smgr, MAIN_FORKNUM); + } logical_end_heap_rewrite(state); @@ -674,7 +677,11 @@ raw_heap_insert(RewriteState state, HeapTuple tup) if (len + saveFreeSpace > pageFreeSpace) { - /* Doesn't fit, so write out the existing page */ + /* + * Doesn't fit, so write out the existing page. It always + * contains a tuple. Hence, unlike RelationGetBufferForTuple(), + * enforce saveFreeSpace unconditionally. + */ /* XLOG stuff */ if (RelationNeedsWAL(state->rs_new_rel)) @@ -828,7 +835,6 @@ logical_begin_heap_rewrite(RewriteState state) state->rs_begin_lsn = GetXLogInsertRecPtr(); state->rs_num_rewrite_mappings = 0; - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(TransactionId); hash_ctl.entrysize = sizeof(RewriteMappingFile); hash_ctl.hcxt = state->rs_cxt; @@ -1003,8 +1009,7 @@ logical_rewrite_log_mapping(RewriteState state, TransactionId xid, snprintf(path, MAXPGPATH, "pg_logical/mappings/" LOGICAL_REWRITE_FORMAT, dboid, relid, - (uint32) (state->rs_begin_lsn >> 32), - (uint32) state->rs_begin_lsn, + LSN_FORMAT_ARGS(state->rs_begin_lsn), xid, GetCurrentTransactionId()); dlist_init(&src->mappings); @@ -1126,8 +1131,7 @@ heap_xlog_logical_rewrite(XLogReaderState *r) snprintf(path, MAXPGPATH, "pg_logical/mappings/" LOGICAL_REWRITE_FORMAT, xlrec->mapped_db, xlrec->mapped_rel, - (uint32) (xlrec->start_lsn >> 32), - (uint32) xlrec->start_lsn, + LSN_FORMAT_ARGS(xlrec->start_lsn), xlrec->mapped_xid, XLogRecGetXid(r)); fd = OpenTransientFile(path, @@ -1262,8 +1266,8 @@ CheckPointLogicalRewriteHeap(void) /* * The file cannot vanish due to concurrency since this function - * is the only one removing logical mappings and it's run while - * CheckpointLock is held exclusively. + * is the only one removing logical mappings and only one + * checkpoint can be in progress at a time. */ if (fd < 0) ereport(ERROR, diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 8391274302d7..f6a688029ef7 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -37,7 +37,7 @@ * parallel mode we update the index statistics after exiting from the * parallel mode. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -67,6 +67,7 @@ #include "access/visibilitymap.h" #include "access/xact.h" #include "access/xlog.h" +#include "catalog/index.h" #include "catalog/storage.h" #include "commands/dbcommands.h" #include "commands/progress.h" @@ -116,6 +117,18 @@ #define VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL 50 /* ms */ #define VACUUM_TRUNCATE_LOCK_TIMEOUT 5000 /* ms */ +/* + * Threshold that controls whether we bypass index vacuuming and heap + * vacuuming as an optimization + */ +#define BYPASS_THRESHOLD_PAGES 0.02 /* i.e. 2% of rel_pages */ + +/* + * Perform a failsafe check every 4GB during the heap scan, approximately + */ +#define FAILSAFE_EVERY_PAGES \ + ((BlockNumber) (((uint64) 4 * 1024 * 1024 * 1024) / BLCKSZ)) + /* * When a table has no indexes, vacuum the FSM after every 8GB, approximately * (it won't be exact because we only vacuum FSM after processing a heap page @@ -159,7 +172,7 @@ * Macro to check if we are in a parallel vacuum. If true, we are in the * parallel mode and the DSM segment is initialized. */ -#define ParallelVacuumIsActive(lps) PointerIsValid(lps) +#define ParallelVacuumIsActive(vacrel) ((vacrel)->lps != NULL) /* Phases of vacuum during which we report error context. */ typedef enum @@ -222,7 +235,8 @@ typedef struct LVShared * live tuples in the index vacuum case or the new live tuples in the * index cleanup case. * - * estimated_count is true if reltuples is an estimated value. + * estimated_count is true if reltuples is an estimated value. (Note that + * reltuples could be -1 in this case, indicating we have no idea.) */ double reltuples; bool estimated_count; @@ -276,7 +290,7 @@ typedef struct LVShared typedef struct LVSharedIndStats { bool updated; /* are the stats updated? */ - IndexBulkDeleteResult stats; + IndexBulkDeleteResult istat; } LVSharedIndStats; /* Struct for maintaining a parallel vacuum state. */ @@ -302,116 +316,173 @@ typedef struct LVParallelState int nindexes_parallel_condcleanup; } LVParallelState; -typedef struct LVRelStats +typedef struct LVRelState { + /* Target heap relation and its indexes */ + Relation rel; + Relation *indrels; + int nindexes; + + /* Wraparound failsafe has been triggered? */ + bool failsafe_active; + /* Consider index vacuuming bypass optimization? */ + bool consider_bypass_optimization; + + /* Doing index vacuuming, index cleanup, rel truncation? */ + bool do_index_vacuuming; + bool do_index_cleanup; + bool do_rel_truncate; + + /* Buffer access strategy and parallel state */ + BufferAccessStrategy bstrategy; + LVParallelState *lps; + + /* Statistics from pg_class when we start out */ + BlockNumber old_rel_pages; /* previous value of pg_class.relpages */ + double old_live_tuples; /* previous value of pg_class.reltuples */ + /* rel's initial relfrozenxid and relminmxid */ + TransactionId relfrozenxid; + MultiXactId relminmxid; + + /* VACUUM operation's cutoff for pruning */ + TransactionId OldestXmin; + /* VACUUM operation's cutoff for freezing XIDs and MultiXactIds */ + TransactionId FreezeLimit; + MultiXactId MultiXactCutoff; + + /* Error reporting state */ char *relnamespace; char *relname; - /* useindex = true means two-pass strategy; false means one-pass */ - bool useindex; - /* Overall statistics about rel */ - BlockNumber old_rel_pages; /* previous value of pg_class.relpages */ + char *indname; + BlockNumber blkno; /* used only for heap operations */ + OffsetNumber offnum; /* used only for heap operations */ + VacErrPhase phase; + + /* + * State managed by lazy_scan_heap() follows + */ + LVDeadTuples *dead_tuples; /* items to vacuum from indexes */ BlockNumber rel_pages; /* total number of pages */ BlockNumber scanned_pages; /* number of pages we examined */ - BlockNumber pinskipped_pages; /* # of pages we skipped due to a pin */ + BlockNumber pinskipped_pages; /* # of pages skipped due to a pin */ BlockNumber frozenskipped_pages; /* # of frozen pages we skipped */ BlockNumber tupcount_pages; /* pages whose tuples we counted */ - double old_live_tuples; /* previous value of pg_class.reltuples */ + BlockNumber pages_removed; /* pages remove by truncation */ + BlockNumber lpdead_item_pages; /* # pages with LP_DEAD items */ + BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */ + + /* Statistics output by us, for table */ double new_rel_tuples; /* new estimated total # of tuples */ double new_live_tuples; /* new estimated total # of live tuples */ - double new_dead_tuples; /* new estimated total # of dead tuples */ - BlockNumber pages_removed; - double tuples_deleted; - BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */ - LVDeadTuples *dead_tuples; + /* Statistics output by index AMs */ + IndexBulkDeleteResult **indstats; + + /* Instrumentation counters */ int num_index_scans; - TransactionId latestRemovedXid; - bool lock_waiter_detected; + int64 tuples_deleted; /* # deleted from table */ + int64 lpdead_items; /* # deleted from indexes */ + int64 new_dead_tuples; /* new estimated total # of dead items in + * table */ + int64 num_tuples; /* total number of nonremovable tuples */ + int64 live_tuples; /* live tuples (reltuples estimate) */ +} LVRelState; - /* Used for error callback */ - char *indname; - BlockNumber blkno; /* used only for heap operations */ - VacErrPhase phase; -} LVRelStats; +/* + * State returned by lazy_scan_prune() + */ +typedef struct LVPagePruneState +{ + bool hastup; /* Page is truncatable? */ + bool has_lpdead_items; /* includes existing LP_DEAD items */ + + /* + * State describes the proper VM bit states to set for the page following + * pruning and freezing. all_visible implies !has_lpdead_items, but don't + * trust all_frozen result unless all_visible is also set to true. + */ + bool all_visible; /* Every item visible to all? */ + bool all_frozen; /* provided all_visible is also true */ + TransactionId visibility_cutoff_xid; /* For recovery conflicts */ +} LVPagePruneState; /* Struct for saving and restoring vacuum error information. */ typedef struct LVSavedErrInfo { BlockNumber blkno; + OffsetNumber offnum; VacErrPhase phase; } LVSavedErrInfo; -/* A few variables that don't seem worth passing around as parameters */ +/* elevel controls whole VACUUM's verbosity */ static int elevel = -1; -static TransactionId OldestXmin; -static TransactionId FreezeLimit; -static MultiXactId MultiXactCutoff; - -static BufferAccessStrategy vac_strategy; - /* non-export function prototypes */ -static void lazy_scan_heap(Relation onerel, VacuumParams *params, - LVRelStats *vacrelstats, Relation *Irel, int nindexes, +static void lazy_scan_heap(LVRelState *vacrel, VacuumParams *params, bool aggressive); -static void lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats); -static bool lazy_check_needs_freeze(Buffer buf, bool *hastup); -static void lazy_vacuum_all_indexes(Relation onerel, Relation *Irel, - IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes); -static void lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats, - LVDeadTuples *dead_tuples, double reltuples, LVRelStats *vacrelstats); -static void lazy_cleanup_index(Relation indrel, - IndexBulkDeleteResult **stats, - double reltuples, bool estimated_count, LVRelStats *vacrelstats); -static int lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, - int tupindex, LVRelStats *vacrelstats, Buffer *vmbuffer); -static bool should_attempt_truncation(VacuumParams *params, - LVRelStats *vacrelstats); -static void lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats); -static BlockNumber count_nondeletable_pages(Relation onerel, - LVRelStats *vacrelstats); -static void lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks); -static void lazy_record_dead_tuple(LVDeadTuples *dead_tuples, - ItemPointer itemptr); +static void lazy_scan_prune(LVRelState *vacrel, Buffer buf, + BlockNumber blkno, Page page, + GlobalVisState *vistest, + LVPagePruneState *prunestate); +static void lazy_vacuum(LVRelState *vacrel); +static bool lazy_vacuum_all_indexes(LVRelState *vacrel); +static void lazy_vacuum_heap_rel(LVRelState *vacrel); +static int lazy_vacuum_heap_page(LVRelState *vacrel, BlockNumber blkno, + Buffer buffer, int tupindex, Buffer *vmbuffer); +static bool lazy_check_needs_freeze(Buffer buf, bool *hastup, + LVRelState *vacrel); +static bool lazy_check_wraparound_failsafe(LVRelState *vacrel); +static void do_parallel_lazy_vacuum_all_indexes(LVRelState *vacrel); +static void do_parallel_lazy_cleanup_all_indexes(LVRelState *vacrel); +static void do_parallel_vacuum_or_cleanup(LVRelState *vacrel, int nworkers); +static void do_parallel_processing(LVRelState *vacrel, + LVShared *lvshared); +static void do_serial_processing_for_unsafe_indexes(LVRelState *vacrel, + LVShared *lvshared); +static IndexBulkDeleteResult *parallel_process_one_index(Relation indrel, + IndexBulkDeleteResult *istat, + LVShared *lvshared, + LVSharedIndStats *shared_indstats, + LVRelState *vacrel); +static void lazy_cleanup_all_indexes(LVRelState *vacrel); +static IndexBulkDeleteResult *lazy_vacuum_one_index(Relation indrel, + IndexBulkDeleteResult *istat, + double reltuples, + LVRelState *vacrel); +static IndexBulkDeleteResult *lazy_cleanup_one_index(Relation indrel, + IndexBulkDeleteResult *istat, + double reltuples, + bool estimated_count, + LVRelState *vacrel); +static bool should_attempt_truncation(LVRelState *vacrel); +static void lazy_truncate_heap(LVRelState *vacrel); +static BlockNumber count_nondeletable_pages(LVRelState *vacrel, + bool *lock_waiter_detected); +static long compute_max_dead_tuples(BlockNumber relblocks, bool hasindex); +static void lazy_space_alloc(LVRelState *vacrel, int nworkers, + BlockNumber relblocks); +static void lazy_space_free(LVRelState *vacrel); static bool lazy_tid_reaped(ItemPointer itemptr, void *state); static int vac_cmp_itemptr(const void *left, const void *right); -static bool heap_page_is_all_visible(Relation rel, Buffer buf, +static bool heap_page_is_all_visible(LVRelState *vacrel, Buffer buf, TransactionId *visibility_cutoff_xid, bool *all_frozen); -static void lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes); -static void parallel_vacuum_index(Relation *Irel, IndexBulkDeleteResult **stats, - LVShared *lvshared, LVDeadTuples *dead_tuples, - int nindexes, LVRelStats *vacrelstats); -static void vacuum_indexes_leader(Relation *Irel, IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes); -static void vacuum_one_index(Relation indrel, IndexBulkDeleteResult **stats, - LVShared *lvshared, LVSharedIndStats *shared_indstats, - LVDeadTuples *dead_tuples, LVRelStats *vacrelstats); -static void lazy_cleanup_all_indexes(Relation *Irel, IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes); -static long compute_max_dead_tuples(BlockNumber relblocks, bool hasindex); -static int compute_parallel_vacuum_workers(Relation *Irel, int nindexes, int nrequested, +static int compute_parallel_vacuum_workers(LVRelState *vacrel, + int nrequested, bool *can_parallel_vacuum); -static void prepare_index_statistics(LVShared *lvshared, bool *can_parallel_vacuum, - int nindexes); -static void update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats, - int nindexes); -static LVParallelState *begin_parallel_vacuum(Oid relid, Relation *Irel, - LVRelStats *vacrelstats, BlockNumber nblocks, - int nindexes, int nrequested); -static void end_parallel_vacuum(IndexBulkDeleteResult **stats, - LVParallelState *lps, int nindexes); -static LVSharedIndStats *get_indstats(LVShared *lvshared, int n); -static bool skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared); +static void update_index_statistics(LVRelState *vacrel); +static LVParallelState *begin_parallel_vacuum(LVRelState *vacrel, + BlockNumber nblocks, + int nrequested); +static void end_parallel_vacuum(LVRelState *vacrel); +static LVSharedIndStats *parallel_stats_for_idx(LVShared *lvshared, int getidx); +static bool parallel_processing_is_safe(Relation indrel, LVShared *lvshared); static void vacuum_error_callback(void *arg); -static void update_vacuum_error_info(LVRelStats *errinfo, LVSavedErrInfo *saved_err_info, - int phase, BlockNumber blkno); -static void restore_vacuum_error_info(LVRelStats *errinfo, const LVSavedErrInfo *saved_err_info); +static void update_vacuum_error_info(LVRelState *vacrel, + LVSavedErrInfo *saved_vacrel, + int phase, BlockNumber blkno, + OffsetNumber offnum); +static void restore_vacuum_error_info(LVRelState *vacrel, + const LVSavedErrInfo *saved_vacrel); /* * lazy_vacuum_rel_heap() -- perform VACUUM for one heap relation @@ -423,12 +494,10 @@ static void restore_vacuum_error_info(LVRelStats *errinfo, const LVSavedErrInfo * and locked the relation. */ void -lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, +heap_vacuum_rel(Relation rel, VacuumParams *params, BufferAccessStrategy bstrategy) { - LVRelStats *vacrelstats; - Relation *Irel; - int nindexes; + LVRelState *vacrel; PGRUsage ru0; TimestampTz starttime = 0; WalUsage walusage_start = pgWalUsage; @@ -439,6 +508,7 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, write_rate; bool aggressive; /* should we scan all unfrozen pages? */ bool scanned_all_unfrozen; /* actually scanned all such pages? */ + char **indnames = NULL; TransactionId xidFullScanLimit; MultiXactId mxactFullScanLimit; BlockNumber new_rel_pages; @@ -447,20 +517,22 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, TransactionId new_frozen_xid; MultiXactId new_min_multi; ErrorContextCallback errcallback; - - Assert(params != NULL); - Assert(params->index_cleanup != VACOPT_TERNARY_DEFAULT); - Assert(params->truncate != VACOPT_TERNARY_DEFAULT); - - /* not every AM requires these to be valid, but heap does */ - Assert(TransactionIdIsNormal(onerel->rd_rel->relfrozenxid)); - Assert(MultiXactIdIsValid(onerel->rd_rel->relminmxid)); + PgStat_Counter startreadtime = 0; + PgStat_Counter startwritetime = 0; + TransactionId OldestXmin; + TransactionId FreezeLimit; + MultiXactId MultiXactCutoff; /* measure elapsed time iff autovacuum logging requires it */ if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0) { pg_rusage_init(&ru0); starttime = GetCurrentTimestamp(); + if (track_io_timing) + { + startreadtime = pgStatBlockReadTime; + startwritetime = pgStatBlockWriteTime; + } } if (params->options & VACOPT_VERBOSE) @@ -472,17 +544,9 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, elevel = DEBUG2; /* vacuum and analyze messages aren't interesting from the QD */ pgstat_progress_start_command(PROGRESS_COMMAND_VACUUM, - RelationGetRelid(onerel)); - - vac_strategy = bstrategy; - - /* - * MPP-23647. Update xid limits for heap as well as appendonly - * relations. This allows setting relfrozenxid to correct value - * for an appendonly (AO/CO) table. - */ + RelationGetRelid(rel)); - vacuum_set_xid_limits(onerel, + vacuum_set_xid_limits(rel, params->freeze_min_age, params->freeze_table_age, params->multixact_freeze_min_age, @@ -496,29 +560,79 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, * table's minimum MultiXactId is older than or equal to the requested * mxid full-table scan limit; or if DISABLE_PAGE_SKIPPING was specified. */ - aggressive = TransactionIdPrecedesOrEquals(onerel->rd_rel->relfrozenxid, + aggressive = TransactionIdPrecedesOrEquals(rel->rd_rel->relfrozenxid, xidFullScanLimit); - aggressive |= MultiXactIdPrecedesOrEquals(onerel->rd_rel->relminmxid, + aggressive |= MultiXactIdPrecedesOrEquals(rel->rd_rel->relminmxid, mxactFullScanLimit); if (params->options & VACOPT_DISABLE_PAGE_SKIPPING) aggressive = true; - vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats)); + vacrel = (LVRelState *) palloc0(sizeof(LVRelState)); + + /* Set up high level stuff about rel */ + vacrel->rel = rel; + vac_open_indexes(vacrel->rel, RowExclusiveLock, &vacrel->nindexes, + &vacrel->indrels); + vacrel->failsafe_active = false; + vacrel->consider_bypass_optimization = true; - vacrelstats->relnamespace = get_namespace_name(RelationGetNamespace(onerel)); - vacrelstats->relname = pstrdup(RelationGetRelationName(onerel)); - vacrelstats->indname = NULL; - vacrelstats->phase = VACUUM_ERRCB_PHASE_UNKNOWN; - vacrelstats->old_rel_pages = onerel->rd_rel->relpages; - vacrelstats->old_live_tuples = onerel->rd_rel->reltuples; - vacrelstats->num_index_scans = 0; - vacrelstats->pages_removed = 0; - vacrelstats->lock_waiter_detected = false; + /* + * The index_cleanup param either disables index vacuuming and cleanup or + * forces it to go ahead when we would otherwise apply the index bypass + * optimization. The default is 'auto', which leaves the final decision + * up to lazy_vacuum(). + * + * The truncate param allows user to avoid attempting relation truncation, + * though it can't force truncation to happen. + */ + Assert(params->index_cleanup != VACOPTVALUE_UNSPECIFIED); + Assert(params->truncate != VACOPTVALUE_UNSPECIFIED && + params->truncate != VACOPTVALUE_AUTO); + vacrel->do_index_vacuuming = true; + vacrel->do_index_cleanup = true; + vacrel->do_rel_truncate = (params->truncate != VACOPTVALUE_DISABLED); + if (params->index_cleanup == VACOPTVALUE_DISABLED) + { + /* Force disable index vacuuming up-front */ + vacrel->do_index_vacuuming = false; + vacrel->do_index_cleanup = false; + } + else if (params->index_cleanup == VACOPTVALUE_ENABLED) + { + /* Force index vacuuming. Note that failsafe can still bypass. */ + vacrel->consider_bypass_optimization = false; + } + else + { + /* Default/auto, make all decisions dynamically */ + Assert(params->index_cleanup == VACOPTVALUE_AUTO); + } - /* Open all indexes of the relation */ - vac_open_indexes(onerel, RowExclusiveLock, &nindexes, &Irel); - vacrelstats->useindex = (nindexes > 0 && - params->index_cleanup == VACOPT_TERNARY_ENABLED); + vacrel->bstrategy = bstrategy; + vacrel->old_rel_pages = rel->rd_rel->relpages; + vacrel->old_live_tuples = rel->rd_rel->reltuples; + vacrel->relfrozenxid = rel->rd_rel->relfrozenxid; + vacrel->relminmxid = rel->rd_rel->relminmxid; + + /* Set cutoffs for entire VACUUM */ + vacrel->OldestXmin = OldestXmin; + vacrel->FreezeLimit = FreezeLimit; + vacrel->MultiXactCutoff = MultiXactCutoff; + + vacrel->relnamespace = get_namespace_name(RelationGetNamespace(rel)); + vacrel->relname = pstrdup(RelationGetRelationName(rel)); + vacrel->indname = NULL; + vacrel->phase = VACUUM_ERRCB_PHASE_UNKNOWN; + + /* Save index names iff autovacuum logging requires it */ + if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0 && + vacrel->nindexes > 0) + { + indnames = palloc(sizeof(char *) * vacrel->nindexes); + for (int i = 0; i < vacrel->nindexes; i++) + indnames[i] = + pstrdup(RelationGetRelationName(vacrel->indrels[i])); + } /* * Setup error traceback support for ereport(). The idea is to set up an @@ -532,15 +646,15 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, * information is restored at the end of those phases. */ errcallback.callback = vacuum_error_callback; - errcallback.arg = vacrelstats; + errcallback.arg = vacrel; errcallback.previous = error_context_stack; error_context_stack = &errcallback; /* Do the vacuuming */ - lazy_scan_heap(onerel, params, vacrelstats, Irel, nindexes, aggressive); + lazy_scan_heap(vacrel, params, aggressive); /* Done with indexes */ - vac_close_indexes(nindexes, Irel, NoLock); + vac_close_indexes(vacrel->nindexes, vacrel->indrels, NoLock); /* * Compute whether we actually scanned the all unfrozen pages. If we did, @@ -549,8 +663,8 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, * NB: We need to check this before truncating the relation, because that * will change ->rel_pages. */ - if ((vacrelstats->scanned_pages + vacrelstats->frozenskipped_pages) - < vacrelstats->rel_pages) + if ((vacrel->scanned_pages + vacrel->frozenskipped_pages) + < vacrel->rel_pages) { Assert(!aggressive); scanned_all_unfrozen = false; @@ -561,16 +675,17 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, /* * Optionally truncate the relation. */ - if (should_attempt_truncation(params, vacrelstats)) + if (should_attempt_truncation(vacrel)) { /* * Update error traceback information. This is the last phase during * which we add context information to errors, so we don't need to * revert to the previous phase. */ - update_vacuum_error_info(vacrelstats, NULL, VACUUM_ERRCB_PHASE_TRUNCATE, - vacrelstats->nonempty_pages); - lazy_truncate_heap(onerel, vacrelstats); + update_vacuum_error_info(vacrel, NULL, VACUUM_ERRCB_PHASE_TRUNCATE, + vacrel->nonempty_pages, + InvalidOffsetNumber); + lazy_truncate_heap(vacrel); } /* Pop the error context stack */ @@ -583,54 +698,51 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, /* * Update statistics in pg_class. * - * A corner case here is that if we scanned no pages at all because every - * page is all-visible, we should not update relpages/reltuples, because - * we have no new information to contribute. In particular this keeps us - * from replacing relpages=reltuples=0 (which means "unknown tuple - * density") with nonzero relpages and reltuples=0 (which means "zero - * tuple density") unless there's some actual evidence for the latter. + * In principle new_live_tuples could be -1 indicating that we (still) + * don't know the tuple count. In practice that probably can't happen, + * since we'd surely have scanned some pages if the table is new and + * nonempty. * - * It's important that we use tupcount_pages and not scanned_pages for the - * check described above; scanned_pages counts pages where we could not - * get cleanup lock, and which were processed only for frozenxid purposes. - * - * We do update relallvisible even in the corner case, since if the table - * is all-visible we'd definitely like to know that. But clamp the value - * to be not more than what we're setting relpages to. + * For safety, clamp relallvisible to be not more than what we're setting + * relpages to. * * Also, don't change relfrozenxid/relminmxid if we skipped any pages, * since then we don't know for certain that all tuples have a newer xmin. */ - new_rel_pages = vacrelstats->rel_pages; - new_live_tuples = vacrelstats->new_live_tuples; - if (vacrelstats->tupcount_pages == 0 && new_rel_pages > 0) - { - new_rel_pages = vacrelstats->old_rel_pages; - new_live_tuples = vacrelstats->old_live_tuples; - } + new_rel_pages = vacrel->rel_pages; + new_live_tuples = vacrel->new_live_tuples; - visibilitymap_count(onerel, &new_rel_allvisible, NULL); + visibilitymap_count(rel, &new_rel_allvisible, NULL); if (new_rel_allvisible > new_rel_pages) new_rel_allvisible = new_rel_pages; new_frozen_xid = scanned_all_unfrozen ? FreezeLimit : InvalidTransactionId; new_min_multi = scanned_all_unfrozen ? MultiXactCutoff : InvalidMultiXactId; - vac_update_relstats(onerel, + vac_update_relstats(rel, new_rel_pages, new_live_tuples, new_rel_allvisible, - nindexes > 0, + vacrel->nindexes > 0, new_frozen_xid, new_min_multi, false, true /* isvacuum */); - /* report results to the stats collector, too */ - pgstat_report_vacuum(RelationGetRelid(onerel), - onerel->rd_rel->relisshared, - new_live_tuples, - vacrelstats->new_dead_tuples); + /* + * Report results to the stats collector, too. + * + * Deliberately avoid telling the stats collector about LP_DEAD items that + * remain in the table due to VACUUM bypassing index and heap vacuuming. + * ANALYZE will consider the remaining LP_DEAD items to be dead tuples. It + * seems like a good idea to err on the side of not vacuuming again too + * soon in cases where the failsafe prevented significant amounts of heap + * vacuuming. + */ + pgstat_report_vacuum(RelationGetRelid(rel), + rel->rd_rel->relisshared, + Max(new_live_tuples, 0), + vacrel->new_dead_tuples); pgstat_progress_end_command(); /* and log the action if appropriate */ @@ -667,6 +779,12 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, initStringInfo(&buf); if (params->is_wraparound) { + /* + * While it's possible for a VACUUM to be both is_wraparound + * and !aggressive, that's just a corner-case -- is_wraparound + * implies aggressive. Produce distinct output for the corner + * case all the same, just in case. + */ if (aggressive) msgfmt = _("automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n"); else @@ -681,73 +799,103 @@ lazy_vacuum_rel_heap(Relation onerel, VacuumParams *params, } appendStringInfo(&buf, msgfmt, get_database_name(MyDatabaseId), - vacrelstats->relnamespace, - vacrelstats->relname, - vacrelstats->num_index_scans); + vacrel->relnamespace, + vacrel->relname, + vacrel->num_index_scans); appendStringInfo(&buf, _("pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n"), - vacrelstats->pages_removed, - vacrelstats->rel_pages, - vacrelstats->pinskipped_pages, - vacrelstats->frozenskipped_pages); + vacrel->pages_removed, + vacrel->rel_pages, + vacrel->pinskipped_pages, + vacrel->frozenskipped_pages); appendStringInfo(&buf, - _("tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n"), - vacrelstats->tuples_deleted, - vacrelstats->new_rel_tuples, - vacrelstats->new_dead_tuples, + _("tuples: %lld removed, %lld remain, %lld are dead but not yet removable, oldest xmin: %u\n"), + (long long) vacrel->tuples_deleted, + (long long) vacrel->new_rel_tuples, + (long long) vacrel->new_dead_tuples, OldestXmin); appendStringInfo(&buf, _("buffer usage: %lld hits, %lld misses, %lld dirtied\n"), (long long) VacuumPageHit, (long long) VacuumPageMiss, (long long) VacuumPageDirty); + if (vacrel->rel_pages > 0) + { + BlockNumber orig_rel_pages; + + if (vacrel->do_index_vacuuming) + { + msgfmt = _(" %u pages from table (%.2f%% of total) had %lld dead item identifiers removed\n"); + + if (vacrel->nindexes == 0 || vacrel->num_index_scans == 0) + appendStringInfoString(&buf, _("index scan not needed:")); + else + appendStringInfoString(&buf, _("index scan needed:")); + } + else + { + msgfmt = _(" %u pages from table (%.2f%% of total) have %lld dead item identifiers\n"); + + if (!vacrel->failsafe_active) + appendStringInfoString(&buf, _("index scan bypassed:")); + else + appendStringInfoString(&buf, _("index scan bypassed by failsafe:")); + } + orig_rel_pages = vacrel->rel_pages + vacrel->pages_removed; + appendStringInfo(&buf, msgfmt, + vacrel->lpdead_item_pages, + 100.0 * vacrel->lpdead_item_pages / orig_rel_pages, + (long long) vacrel->lpdead_items); + } + for (int i = 0; i < vacrel->nindexes; i++) + { + IndexBulkDeleteResult *istat = vacrel->indstats[i]; + + if (!istat) + continue; + + appendStringInfo(&buf, + _("index \"%s\": pages: %u in total, %u newly deleted, %u currently deleted, %u reusable\n"), + indnames[i], + istat->num_pages, + istat->pages_newly_deleted, + istat->pages_deleted, + istat->pages_free); + } appendStringInfo(&buf, _("avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n"), read_rate, write_rate); + if (track_io_timing) + { + appendStringInfoString(&buf, _("I/O Timings:")); + if (pgStatBlockReadTime - startreadtime > 0) + appendStringInfo(&buf, _(" read=%.3f"), + (double) (pgStatBlockReadTime - startreadtime) / 1000); + if (pgStatBlockWriteTime - startwritetime > 0) + appendStringInfo(&buf, _(" write=%.3f"), + (double) (pgStatBlockWriteTime - startwritetime) / 1000); + appendStringInfoChar(&buf, '\n'); + } appendStringInfo(&buf, _("system usage: %s\n"), pg_rusage_show(&ru0)); appendStringInfo(&buf, - _("WAL usage: %ld records, %ld full page images, " - UINT64_FORMAT " bytes"), - walusage.wal_records, - walusage.wal_fpi, - walusage.wal_bytes); + _("WAL usage: %lld records, %lld full page images, %llu bytes"), + (long long) walusage.wal_records, + (long long) walusage.wal_fpi, + (unsigned long long) walusage.wal_bytes); ereport(LOG, (errmsg_internal("%s", buf.data))); pfree(buf.data); } } -} -/* - * For Hot Standby we need to know the highest transaction id that will - * be removed by any change. VACUUM proceeds in a number of passes so - * we need to consider how each pass operates. The first phase runs - * heap_page_prune(), which can issue XLOG_HEAP2_CLEAN records as it - * progresses - these will have a latestRemovedXid on each record. - * In some cases this removes all of the tuples to be removed, though - * often we have dead tuples with index pointers so we must remember them - * for removal in phase 3. Index records for those rows are removed - * in phase 2 and index blocks do not have MVCC information attached. - * So before we can allow removal of any index tuples we need to issue - * a WAL record containing the latestRemovedXid of rows that will be - * removed in phase three. This allows recovery queries to block at the - * correct place, i.e. before phase two, rather than during phase three - * which would be after the rows have become inaccessible. - */ -static void -vacuum_log_cleanup_info(Relation rel, LVRelStats *vacrelstats) -{ - /* - * Skip this for relations for which no WAL is to be written, or if we're - * not trying to support archive recovery. - */ - if (!RelationNeedsWAL(rel) || !XLogIsNeeded()) - return; + /* Cleanup index statistics and index names */ + for (int i = 0; i < vacrel->nindexes; i++) + { + if (vacrel->indstats[i]) + pfree(vacrel->indstats[i]); - /* - * No need to write the record at all unless it contains a valid value - */ - if (TransactionIdIsValid(vacrelstats->latestRemovedXid)) - (void) log_heap_cleanup_info(rel->rd_node, vacrelstats->latestRemovedXid); + if (indnames && indnames[i]) + pfree(indnames[i]); + } } /* @@ -758,9 +906,9 @@ vacuum_log_cleanup_info(Relation rel, LVRelStats *vacrelstats) * page, and set commit status bits (see heap_page_prune). It also builds * lists of dead tuples and pages with free space, calculates statistics * on the number of live tuples in the heap, and marks pages as - * all-visible if appropriate. When done, or when we run low on space for - * dead-tuple TIDs, invoke vacuuming of indexes and call lazy_vacuum_heap - * to reclaim dead line pointers. + * all-visible if appropriate. When done, or when we run low on space + * for dead-tuple TIDs, invoke lazy_vacuum to vacuum indexes and vacuum + * heap relation during its own second pass over the heap. * * If the table has at least two indexes, we execute both index vacuum * and index cleanup with parallel workers unless parallel vacuum is @@ -779,31 +927,17 @@ vacuum_log_cleanup_info(Relation rel, LVRelStats *vacrelstats) * reference them have been killed. */ static void -lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, - Relation *Irel, int nindexes, bool aggressive) +lazy_scan_heap(LVRelState *vacrel, VacuumParams *params, bool aggressive) { - LVParallelState *lps = NULL; LVDeadTuples *dead_tuples; BlockNumber nblocks, - blkno; - HeapTupleData tuple; - TransactionId relfrozenxid = onerel->rd_rel->relfrozenxid; - TransactionId relminmxid = onerel->rd_rel->relminmxid; - BlockNumber empty_pages, - vacuumed_pages, + blkno, + next_unskippable_block, + next_failsafe_block, next_fsm_block_to_vacuum; - double num_tuples, /* total number of nonremovable tuples */ - live_tuples, /* live tuples (reltuples estimate) */ - tups_vacuumed, /* tuples cleaned up by vacuum */ - nkeep, /* dead-but-not-removable tuples */ - nunused; /* unused line pointers */ - IndexBulkDeleteResult **indstats; - int i; PGRUsage ru0; Buffer vmbuffer = InvalidBuffer; - BlockNumber next_unskippable_block; bool skipping_blocks; - xl_heap_freeze_tuple *frozen; StringInfoData buf; const int initprog_index[] = { PROGRESS_VACUUM_PHASE, @@ -818,67 +952,53 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, if (aggressive) ereport(elevel, (errmsg("aggressively vacuuming \"%s.%s\"", - vacrelstats->relnamespace, - vacrelstats->relname))); + vacrel->relnamespace, + vacrel->relname))); else ereport(elevel, (errmsg("vacuuming \"%s.%s\"", - vacrelstats->relnamespace, - vacrelstats->relname))); - - empty_pages = vacuumed_pages = 0; - next_fsm_block_to_vacuum = (BlockNumber) 0; - num_tuples = live_tuples = tups_vacuumed = nkeep = nunused = 0; - - indstats = (IndexBulkDeleteResult **) - palloc0(nindexes * sizeof(IndexBulkDeleteResult *)); + vacrel->relnamespace, + vacrel->relname))); - nblocks = RelationGetNumberOfBlocks(onerel); - vacrelstats->rel_pages = nblocks; - vacrelstats->scanned_pages = 0; - vacrelstats->tupcount_pages = 0; - vacrelstats->nonempty_pages = 0; - vacrelstats->latestRemovedXid = InvalidTransactionId; - - vistest = GlobalVisTestFor(onerel); + nblocks = RelationGetNumberOfBlocks(vacrel->rel); + next_unskippable_block = 0; + next_failsafe_block = 0; + next_fsm_block_to_vacuum = 0; + vacrel->rel_pages = nblocks; + vacrel->scanned_pages = 0; + vacrel->pinskipped_pages = 0; + vacrel->frozenskipped_pages = 0; + vacrel->tupcount_pages = 0; + vacrel->pages_removed = 0; + vacrel->lpdead_item_pages = 0; + vacrel->nonempty_pages = 0; + + /* Initialize instrumentation counters */ + vacrel->num_index_scans = 0; + vacrel->tuples_deleted = 0; + vacrel->lpdead_items = 0; + vacrel->new_dead_tuples = 0; + vacrel->num_tuples = 0; + vacrel->live_tuples = 0; + + vistest = GlobalVisTestFor(vacrel->rel); + + vacrel->indstats = (IndexBulkDeleteResult **) + palloc0(vacrel->nindexes * sizeof(IndexBulkDeleteResult *)); /* - * Initialize state for a parallel vacuum. As of now, only one worker can - * be used for an index, so we invoke parallelism only if there are at - * least two indexes on a table. + * Before beginning scan, check if it's already necessary to apply + * failsafe */ - if (params->nworkers >= 0 && vacrelstats->useindex && nindexes > 1) - { - /* - * Since parallel workers cannot access data in temporary tables, we - * can't perform parallel vacuum on them. - */ - if (RelationUsesLocalBuffers(onerel)) - { - /* - * Give warning only if the user explicitly tries to perform a - * parallel vacuum on the temporary table. - */ - if (params->nworkers > 0) - ereport(WARNING, - (errmsg("disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel", - vacrelstats->relname))); - } - else - lps = begin_parallel_vacuum(RelationGetRelid(onerel), Irel, - vacrelstats, nblocks, nindexes, - params->nworkers); - } + lazy_check_wraparound_failsafe(vacrel); /* - * Allocate the space for dead tuples in case parallel vacuum is not - * initialized. + * Allocate the space for dead tuples. Note that this handles parallel + * VACUUM initialization as part of allocating shared memory space used + * for dead_tuples. */ - if (!ParallelVacuumIsActive(lps)) - lazy_space_alloc(vacrelstats, nblocks); - - dead_tuples = vacrelstats->dead_tuples; - frozen = palloc(sizeof(xl_heap_freeze_tuple) * MaxHeapTuplesPerPage); + lazy_space_alloc(vacrel, params->nworkers, nblocks); + dead_tuples = vacrel->dead_tuples; /* Report that we're scanning the heap, advertising total # of blocks */ initprog_val[0] = PROGRESS_VACUUM_PHASE_SCAN_HEAP; @@ -930,14 +1050,14 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * the last page. This is worth avoiding mainly because such a lock must * be replayed on any hot standby, where it can be disruptive. */ - next_unskippable_block = 0; if ((params->options & VACOPT_DISABLE_PAGE_SKIPPING) == 0) { while (next_unskippable_block < nblocks) { uint8 vmstatus; - vmstatus = visibilitymap_get_status(onerel, next_unskippable_block, + vmstatus = visibilitymap_get_status(vacrel->rel, + next_unskippable_block, &vmbuffer); if (aggressive) { @@ -963,27 +1083,20 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, { Buffer buf; Page page; - OffsetNumber offnum, - maxoff; - bool tupgone, - hastup; - int prev_dead_count; - int nfrozen; - Size freespace; bool all_visible_according_to_vm = false; - bool all_visible; - bool all_frozen = true; /* provided all_visible is also true */ - bool has_dead_tuples; - TransactionId visibility_cutoff_xid = InvalidTransactionId; + LVPagePruneState prunestate; - /* see note above about forcing scanning of last page */ + /* + * Consider need to skip blocks. See note above about forcing + * scanning of last page. + */ #define FORCE_CHECK_PAGE() \ - (blkno == nblocks - 1 && should_attempt_truncation(params, vacrelstats)) + (blkno == nblocks - 1 && should_attempt_truncation(vacrel)) pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno); - update_vacuum_error_info(vacrelstats, NULL, VACUUM_ERRCB_PHASE_SCAN_HEAP, - blkno); + update_vacuum_error_info(vacrel, NULL, VACUUM_ERRCB_PHASE_SCAN_HEAP, + blkno, InvalidOffsetNumber); if (blkno == next_unskippable_block) { @@ -995,7 +1108,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, { uint8 vmskipflags; - vmskipflags = visibilitymap_get_status(onerel, + vmskipflags = visibilitymap_get_status(vacrel->rel, next_unskippable_block, &vmbuffer); if (aggressive) @@ -1027,7 +1140,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * it's not all-visible. But in an aggressive vacuum we know only * that it's not all-frozen, so it might still be all-visible. */ - if (aggressive && VM_ALL_VISIBLE(onerel, blkno, &vmbuffer)) + if (aggressive && VM_ALL_VISIBLE(vacrel->rel, blkno, &vmbuffer)) all_visible_according_to_vm = true; } else @@ -1051,8 +1164,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * know whether it was all-frozen, so we have to recheck; but * in this case an approximate answer is OK. */ - if (aggressive || VM_ALL_FROZEN(onerel, blkno, &vmbuffer)) - vacrelstats->frozenskipped_pages++; + if (aggressive || VM_ALL_FROZEN(vacrel->rel, blkno, &vmbuffer)) + vacrel->frozenskipped_pages++; continue; } all_visible_according_to_vm = true; @@ -1061,8 +1174,25 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, vacuum_delay_point(); /* - * If we are close to overrunning the available space for dead-tuple - * TIDs, pause and do a cycle of vacuuming before we tackle this page. + * Regularly check if wraparound failsafe should trigger. + * + * There is a similar check inside lazy_vacuum_all_indexes(), but + * relfrozenxid might start to look dangerously old before we reach + * that point. This check also provides failsafe coverage for the + * one-pass strategy, and the two-pass strategy with the index_cleanup + * param set to 'off'. + */ + if (blkno - next_failsafe_block >= FAILSAFE_EVERY_PAGES) + { + lazy_check_wraparound_failsafe(vacrel); + next_failsafe_block = blkno; + } + + /* + * Consider if we definitely have enough space to process TIDs on page + * already. If we are close to overrunning the available space for + * dead-tuple TIDs, pause and do a cycle of vacuuming before we tackle + * this page. */ if ((dead_tuples->max_tuples - dead_tuples->num_tuples) < MaxHeapTuplesPerPage && dead_tuples->num_tuples > 0) @@ -1079,25 +1209,16 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, vmbuffer = InvalidBuffer; } - /* Work on all the indexes, then the heap */ - lazy_vacuum_all_indexes(onerel, Irel, indstats, - vacrelstats, lps, nindexes); - - /* Remove tuples from heap */ - lazy_vacuum_heap(onerel, vacrelstats); - - /* - * Forget the now-vacuumed tuples, and press on, but be careful - * not to reset latestRemovedXid since we want that value to be - * valid. - */ - dead_tuples->num_tuples = 0; + /* Remove the collected garbage tuples from table and indexes */ + vacrel->consider_bypass_optimization = false; + lazy_vacuum(vacrel); /* * Vacuum the Free Space Map to make newly-freed space visible on * upper-level FSM pages. Note we have not yet processed blkno. */ - FreeSpaceMapVacuumRange(onerel, next_fsm_block_to_vacuum, blkno); + FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum, + blkno); next_fsm_block_to_vacuum = blkno; /* Report that we are once again scanning the heap */ @@ -1106,22 +1227,28 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, } /* + * Set up visibility map page as needed. + * * Pin the visibility map page in case we need to mark the page * all-visible. In most cases this will be very cheap, because we'll * already have the correct page pinned anyway. However, it's * possible that (a) next_unskippable_block is covered by a different * VM page than the current block or (b) we released our pin and did a * cycle of index vacuuming. - * */ - visibilitymap_pin(onerel, blkno, &vmbuffer); + visibilitymap_pin(vacrel->rel, blkno, &vmbuffer); - buf = ReadBufferExtended(onerel, MAIN_FORKNUM, blkno, - RBM_NORMAL, vac_strategy); + buf = ReadBufferExtended(vacrel->rel, MAIN_FORKNUM, blkno, + RBM_NORMAL, vacrel->bstrategy); - /* We need buffer cleanup lock so that we can prune HOT chains. */ + /* + * We need buffer cleanup lock so that we can prune HOT chains and + * defragment the page. + */ if (!ConditionalLockBufferForCleanup(buf)) { + bool hastup; + /* * If we're not performing an aggressive scan to guard against XID * wraparound, and we don't want to forcibly check the page, then @@ -1131,7 +1258,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, if (!aggressive && !FORCE_CHECK_PAGE()) { ReleaseBuffer(buf); - vacrelstats->pinskipped_pages++; + vacrel->pinskipped_pages++; continue; } @@ -1152,13 +1279,13 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * to use lazy_check_needs_freeze() for both situations, though. */ LockBuffer(buf, BUFFER_LOCK_SHARE); - if (!lazy_check_needs_freeze(buf, &hastup)) + if (!lazy_check_needs_freeze(buf, &hastup, vacrel)) { UnlockReleaseBuffer(buf); - vacrelstats->scanned_pages++; - vacrelstats->pinskipped_pages++; + vacrel->scanned_pages++; + vacrel->pinskipped_pages++; if (hastup) - vacrelstats->nonempty_pages = blkno + 1; + vacrel->nonempty_pages = blkno + 1; continue; } if (!aggressive) @@ -1168,9 +1295,9 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * to claiming that the page contains no freezable tuples. */ UnlockReleaseBuffer(buf); - vacrelstats->pinskipped_pages++; + vacrel->pinskipped_pages++; if (hastup) - vacrelstats->nonempty_pages = blkno + 1; + vacrel->nonempty_pages = blkno + 1; continue; } LockBuffer(buf, BUFFER_LOCK_UNLOCK); @@ -1178,8 +1305,18 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, /* drop through to normal processing */ } - vacrelstats->scanned_pages++; - vacrelstats->tupcount_pages++; + /* + * By here we definitely have enough dead_tuples space for whatever + * LP_DEAD tids are on this page, we have the visibility map page set + * up in case we need to set this page's all_visible/all_frozen bit, + * and we have a super-exclusive lock. Any tuples on this page are + * now sure to be "counted" by this VACUUM. + * + * One last piece of preamble needs to take place before we can prune: + * we need to consider new and empty pages. + */ + vacrel->scanned_pages++; + vacrel->tupcount_pages++; page = BufferGetPage(buf); @@ -1206,22 +1343,18 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, */ UnlockReleaseBuffer(buf); - empty_pages++; - - if (GetRecordedFreeSpace(onerel, blkno) == 0) + if (GetRecordedFreeSpace(vacrel->rel, blkno) == 0) { - Size freespace; + Size freespace = BLCKSZ - SizeOfPageHeaderData; - freespace = BufferGetPageSize(buf) - SizeOfPageHeaderData; - RecordPageWithFreeSpace(onerel, blkno, freespace); + RecordPageWithFreeSpace(vacrel->rel, blkno, freespace); } continue; } if (PageIsEmpty(page)) { - empty_pages++; - freespace = PageGetHeapFreeSpace(page); + Size freespace = PageGetHeapFreeSpace(page); /* * Empty pages are always all-visible and all-frozen (note that @@ -1244,347 +1377,105 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * page has been previously WAL-logged, and if not, do that * now. */ - if (RelationNeedsWAL(onerel) && + if (RelationNeedsWAL(vacrel->rel) && PageGetLSN(page) == InvalidXLogRecPtr) log_newpage_buffer(buf, true); PageSetAllVisible(page); - visibilitymap_set(onerel, blkno, buf, InvalidXLogRecPtr, + visibilitymap_set(vacrel->rel, blkno, buf, InvalidXLogRecPtr, vmbuffer, InvalidTransactionId, VISIBILITYMAP_ALL_VISIBLE | VISIBILITYMAP_ALL_FROZEN); END_CRIT_SECTION(); } UnlockReleaseBuffer(buf); - RecordPageWithFreeSpace(onerel, blkno, freespace); + RecordPageWithFreeSpace(vacrel->rel, blkno, freespace); continue; } /* - * Prune all HOT-update chains in this page. + * Prune and freeze tuples. * - * We count tuples removed by the pruning step as removed by VACUUM. - */ - tups_vacuumed += heap_page_prune(onerel, buf, vistest, false, - InvalidTransactionId, 0, - &vacrelstats->latestRemovedXid); - - /* - * Now scan the page to collect vacuumable items and check for tuples - * requiring freezing. - */ - all_visible = true; - has_dead_tuples = false; - nfrozen = 0; - hastup = false; - prev_dead_count = dead_tuples->num_tuples; - maxoff = PageGetMaxOffsetNumber(page); - - /* - * Note: If you change anything in the loop below, also look at - * heap_page_is_all_visible to see if that needs to be changed. + * Accumulates details of remaining LP_DEAD line pointers on page in + * dead tuple list. This includes LP_DEAD line pointers that we + * pruned ourselves, as well as existing LP_DEAD line pointers that + * were pruned some time earlier. Also considers freezing XIDs in the + * tuple headers of remaining items with storage. */ - for (offnum = FirstOffsetNumber; - offnum <= maxoff; - offnum = OffsetNumberNext(offnum)) - { - ItemId itemid; - - itemid = PageGetItemId(page, offnum); - - /* Unused items require no processing, but we count 'em */ - if (!ItemIdIsUsed(itemid)) - { - nunused += 1; - continue; - } - - /* Redirect items mustn't be touched */ - if (ItemIdIsRedirected(itemid)) - { - hastup = true; /* this page won't be truncatable */ - continue; - } - - ItemPointerSet(&(tuple.t_self), blkno, offnum); - - /* - * DEAD line pointers are to be vacuumed normally; but we don't - * count them in tups_vacuumed, else we'd be double-counting (at - * least in the common case where heap_page_prune() just freed up - * a non-HOT tuple). - */ - if (ItemIdIsDead(itemid)) - { - lazy_record_dead_tuple(dead_tuples, &(tuple.t_self)); - all_visible = false; - continue; - } - - Assert(ItemIdIsNormal(itemid)); + lazy_scan_prune(vacrel, buf, blkno, page, vistest, &prunestate); - tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid); - tuple.t_len = ItemIdGetLength(itemid); - tuple.t_tableOid = RelationGetRelid(onerel); + Assert(!prunestate.all_visible || !prunestate.has_lpdead_items); - tupgone = false; + /* Remember the location of the last page with nonremovable tuples */ + if (prunestate.hastup) + vacrel->nonempty_pages = blkno + 1; + if (vacrel->nindexes == 0) + { /* - * The criteria for counting a tuple as live in this block need to - * match what analyze.c's acquire_sample_rows() does, otherwise - * VACUUM and ANALYZE may produce wildly different reltuples - * values, e.g. when there are many recently-dead tuples. + * Consider the need to do page-at-a-time heap vacuuming when + * using the one-pass strategy now. * - * The logic here is a bit simpler than acquire_sample_rows(), as - * VACUUM can't run inside a transaction block, which makes some - * cases impossible (e.g. in-progress insert from the same - * transaction). + * The one-pass strategy will never call lazy_vacuum(). The steps + * performed here can be thought of as the one-pass equivalent of + * a call to lazy_vacuum(). */ - switch (HeapTupleSatisfiesVacuum(onerel, &tuple, OldestXmin, buf)) + if (prunestate.has_lpdead_items) { - case HEAPTUPLE_DEAD: - - /* - * Ordinarily, DEAD tuples would have been removed by - * heap_page_prune(), but it's possible that the tuple - * state changed since heap_page_prune() looked. In - * particular an INSERT_IN_PROGRESS tuple could have - * changed to DEAD if the inserter aborted. So this - * cannot be considered an error condition. - * - * If the tuple is HOT-updated then it must only be - * removed by a prune operation; so we keep it just as if - * it were RECENTLY_DEAD. Also, if it's a heap-only - * tuple, we choose to keep it, because it'll be a lot - * cheaper to get rid of it in the next pruning pass than - * to treat it like an indexed tuple. Finally, if index - * cleanup is disabled, the second heap pass will not - * execute, and the tuple will not get removed, so we must - * treat it like any other dead tuple that we choose to - * keep. - * - * If this were to happen for a tuple that actually needed - * to be deleted, we'd be in trouble, because it'd - * possibly leave a tuple below the relation's xmin - * horizon alive. heap_prepare_freeze_tuple() is prepared - * to detect that case and abort the transaction, - * preventing corruption. - */ - if (HeapTupleIsHotUpdated(&tuple) || - HeapTupleIsHeapOnly(&tuple) || - params->index_cleanup == VACOPT_TERNARY_DISABLED) - nkeep += 1; - else - tupgone = true; /* we can delete the tuple */ - all_visible = false; - break; - case HEAPTUPLE_LIVE: - - /* - * Count it as live. Not only is this natural, but it's - * also what acquire_sample_rows() does. - */ - live_tuples += 1; - - /* - * Is the tuple definitely visible to all transactions? - * - * NB: Like with per-tuple hint bits, we can't set the - * PD_ALL_VISIBLE flag if the inserter committed - * asynchronously. See SetHintBits for more info. Check - * that the tuple is hinted xmin-committed because of - * that. - */ - if (all_visible) - { - TransactionId xmin; - - if (!HeapTupleHeaderXminCommitted(tuple.t_data)) - { - all_visible = false; - break; - } - - /* - * The inserter definitely committed. But is it old - * enough that everyone sees it as committed? - */ - xmin = HeapTupleHeaderGetXmin(tuple.t_data); - if (!TransactionIdPrecedes(xmin, OldestXmin)) - { - all_visible = false; - break; - } - - /* Track newest xmin on page. */ - if (TransactionIdFollows(xmin, visibility_cutoff_xid)) - visibility_cutoff_xid = xmin; - } - break; - case HEAPTUPLE_RECENTLY_DEAD: - - /* - * If tuple is recently deleted then we must not remove it - * from relation. - */ - nkeep += 1; - all_visible = false; - break; - case HEAPTUPLE_INSERT_IN_PROGRESS: - - /* - * This is an expected case during concurrent vacuum. - * - * We do not count these rows as live, because we expect - * the inserting transaction to update the counters at - * commit, and we assume that will happen only after we - * report our results. This assumption is a bit shaky, - * but it is what acquire_sample_rows() does, so be - * consistent. - */ - all_visible = false; - break; - case HEAPTUPLE_DELETE_IN_PROGRESS: - /* This is an expected case during concurrent vacuum */ - all_visible = false; - - /* - * Count such rows as live. As above, we assume the - * deleting transaction will commit and update the - * counters after we report. - */ - live_tuples += 1; - break; - default: - elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); - break; - } + Size freespace; - if (tupgone) - { - lazy_record_dead_tuple(dead_tuples, &(tuple.t_self)); - HeapTupleHeaderAdvanceLatestRemovedXid(tuple.t_data, - &vacrelstats->latestRemovedXid); - tups_vacuumed += 1; - has_dead_tuples = true; - } - else - { - bool tuple_totally_frozen; + lazy_vacuum_heap_page(vacrel, blkno, buf, 0, &vmbuffer); - num_tuples += 1; - hastup = true; + /* Forget the now-vacuumed tuples */ + dead_tuples->num_tuples = 0; /* - * Each non-removable tuple must be checked to see if it needs - * freezing. Note we already have exclusive buffer lock. + * Periodically perform FSM vacuuming to make newly-freed + * space visible on upper FSM pages. Note we have not yet + * performed FSM processing for blkno. */ - if (heap_prepare_freeze_tuple(tuple.t_data, - relfrozenxid, relminmxid, - FreezeLimit, MultiXactCutoff, - &frozen[nfrozen], - &tuple_totally_frozen)) - frozen[nfrozen++].offset = offnum; - - if (!tuple_totally_frozen) - all_frozen = false; - } - } /* scan along page */ - - /* - * If we froze any tuples, mark the buffer dirty, and write a WAL - * record recording the changes. We must log the changes to be - * crash-safe against future truncation of CLOG. - */ - if (nfrozen > 0) - { - START_CRIT_SECTION(); - - MarkBufferDirty(buf); - - /* execute collected freezes */ - for (i = 0; i < nfrozen; i++) - { - ItemId itemid; - HeapTupleHeader htup; - - itemid = PageGetItemId(page, frozen[i].offset); - htup = (HeapTupleHeader) PageGetItem(page, itemid); - - heap_execute_freeze_tuple(htup, &frozen[i]); - } + if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES) + { + FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum, + blkno); + next_fsm_block_to_vacuum = blkno; + } - /* Now WAL-log freezing if necessary */ - if (RelationNeedsWAL(onerel)) - { - XLogRecPtr recptr; + /* + * Now perform FSM processing for blkno, and move on to next + * page. + * + * Our call to lazy_vacuum_heap_page() will have considered if + * it's possible to set all_visible/all_frozen independently + * of lazy_scan_prune(). Note that prunestate was invalidated + * by lazy_vacuum_heap_page() call. + */ + freespace = PageGetHeapFreeSpace(page); - recptr = log_heap_freeze(onerel, buf, FreezeLimit, - frozen, nfrozen); - PageSetLSN(page, recptr); + UnlockReleaseBuffer(buf); + RecordPageWithFreeSpace(vacrel->rel, blkno, freespace); + continue; } - END_CRIT_SECTION(); + /* + * There was no call to lazy_vacuum_heap_page() because pruning + * didn't encounter/create any LP_DEAD items that needed to be + * vacuumed. Prune state has not been invalidated, so proceed + * with prunestate-driven visibility map and FSM steps (just like + * the two-pass strategy). + */ + Assert(dead_tuples->num_tuples == 0); } /* - * If there are no indexes we can vacuum the page right now instead of - * doing a second scan. Also we don't do that but forget dead tuples - * when index cleanup is disabled. + * Handle setting visibility map bit based on what the VM said about + * the page before pruning started, and using prunestate */ - if (!vacrelstats->useindex && dead_tuples->num_tuples > 0) - { - if (nindexes == 0) - { - /* Remove tuples from heap if the table has no index */ - lazy_vacuum_page(onerel, blkno, buf, 0, vacrelstats, &vmbuffer); - vacuumed_pages++; - has_dead_tuples = false; - } - else - { - /* - * Here, we have indexes but index cleanup is disabled. - * Instead of vacuuming the dead tuples on the heap, we just - * forget them. - * - * Note that vacrelstats->dead_tuples could have tuples which - * became dead after HOT-pruning but are not marked dead yet. - * We do not process them because it's a very rare condition, - * and the next vacuum will process them anyway. - */ - Assert(params->index_cleanup == VACOPT_TERNARY_DISABLED); - } - - /* - * Forget the now-vacuumed tuples, and press on, but be careful - * not to reset latestRemovedXid since we want that value to be - * valid. - */ - dead_tuples->num_tuples = 0; - - /* - * Periodically do incremental FSM vacuuming to make newly-freed - * space visible on upper FSM pages. Note: although we've cleaned - * the current block, we haven't yet updated its FSM entry (that - * happens further down), so passing end == blkno is correct. - */ - if (blkno - next_fsm_block_to_vacuum >= VACUUM_FSM_EVERY_PAGES) - { - FreeSpaceMapVacuumRange(onerel, next_fsm_block_to_vacuum, - blkno); - next_fsm_block_to_vacuum = blkno; - } - } - - freespace = PageGetHeapFreeSpace(page); - - /* mark page all-visible, if appropriate */ - if (all_visible && !all_visible_according_to_vm) + if (!all_visible_according_to_vm && prunestate.all_visible) { uint8 flags = VISIBILITYMAP_ALL_VISIBLE; - if (all_frozen) + if (prunestate.all_frozen) flags |= VISIBILITYMAP_ALL_FROZEN; /* @@ -1602,8 +1493,9 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, */ PageSetAllVisible(page); MarkBufferDirty(buf); - visibilitymap_set(onerel, blkno, buf, InvalidXLogRecPtr, - vmbuffer, visibility_cutoff_xid, flags); + visibilitymap_set(vacrel->rel, blkno, buf, InvalidXLogRecPtr, + vmbuffer, prunestate.visibility_cutoff_xid, + flags); } /* @@ -1614,11 +1506,11 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * that something bad has happened. */ else if (all_visible_according_to_vm && !PageIsAllVisible(page) - && VM_ALL_VISIBLE(onerel, blkno, &vmbuffer)) + && VM_ALL_VISIBLE(vacrel->rel, blkno, &vmbuffer)) { elog(WARNING, "page is not marked all-visible but visibility map bit is set in relation \"%s\" page %u", - vacrelstats->relname, blkno); - visibilitymap_clear(onerel, blkno, vmbuffer, + vacrel->relname, blkno); + visibilitymap_clear(vacrel->rel, blkno, vmbuffer, VISIBILITYMAP_VALID_BITS); } @@ -1637,13 +1529,13 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * There should never be dead tuples on a page with PD_ALL_VISIBLE * set, however. */ - else if (PageIsAllVisible(page) && has_dead_tuples) + else if (prunestate.has_lpdead_items && PageIsAllVisible(page)) { elog(WARNING, "page containing dead tuples is marked as all-visible in relation \"%s\" page %u", - vacrelstats->relname, blkno); + vacrel->relname, blkno); PageClearAllVisible(page); MarkBufferDirty(buf); - visibilitymap_clear(onerel, blkno, vmbuffer, + visibilitymap_clear(vacrel->rel, blkno, vmbuffer, VISIBILITYMAP_VALID_BITS); } @@ -1652,57 +1544,73 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, * mark it as all-frozen. Note that all_frozen is only valid if * all_visible is true, so we must check both. */ - else if (all_visible_according_to_vm && all_visible && all_frozen && - !VM_ALL_FROZEN(onerel, blkno, &vmbuffer)) + else if (all_visible_according_to_vm && prunestate.all_visible && + prunestate.all_frozen && + !VM_ALL_FROZEN(vacrel->rel, blkno, &vmbuffer)) { /* * We can pass InvalidTransactionId as the cutoff XID here, * because setting the all-frozen bit doesn't cause recovery * conflicts. */ - visibilitymap_set(onerel, blkno, buf, InvalidXLogRecPtr, + visibilitymap_set(vacrel->rel, blkno, buf, InvalidXLogRecPtr, vmbuffer, InvalidTransactionId, VISIBILITYMAP_ALL_FROZEN); } - UnlockReleaseBuffer(buf); - - /* Remember the location of the last page with nonremovable tuples */ - if (hastup) - vacrelstats->nonempty_pages = blkno + 1; - /* - * If we remembered any tuples for deletion, then the page will be - * visited again by lazy_vacuum_heap, which will compute and record - * its post-compaction free space. If not, then we're done with this - * page, so remember its free space as-is. (This path will always be - * taken if there are no indexes.) + * Final steps for block: drop super-exclusive lock, record free space + * in the FSM */ - if (dead_tuples->num_tuples == prev_dead_count) - RecordPageWithFreeSpace(onerel, blkno, freespace); + if (prunestate.has_lpdead_items && vacrel->do_index_vacuuming) + { + /* + * Wait until lazy_vacuum_heap_rel() to save free space. This + * doesn't just save us some cycles; it also allows us to record + * any additional free space that lazy_vacuum_heap_page() will + * make available in cases where it's possible to truncate the + * page's line pointer array. + * + * Note: It's not in fact 100% certain that we really will call + * lazy_vacuum_heap_rel() -- lazy_vacuum() might yet opt to skip + * index vacuuming (and so must skip heap vacuuming). This is + * deemed okay because it only happens in emergencies, or when + * there is very little free space anyway. (Besides, we start + * recording free space in the FSM once index vacuuming has been + * abandoned.) + * + * Note: The one-pass (no indexes) case is only supposed to make + * it this far when there were no LP_DEAD items during pruning. + */ + Assert(vacrel->nindexes > 0); + UnlockReleaseBuffer(buf); + } + else + { + Size freespace = PageGetHeapFreeSpace(page); - if (RelationNeedsWAL(onerel)) - wait_to_avoid_large_repl_lag(); + UnlockReleaseBuffer(buf); + RecordPageWithFreeSpace(vacrel->rel, blkno, freespace); + } } - /* report that everything is scanned and vacuumed */ + /* report that everything is now scanned */ pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno); - pfree(frozen); - - /* save stats for use later */ - vacrelstats->tuples_deleted = tups_vacuumed; - vacrelstats->new_dead_tuples = nkeep; + /* Clear the block number information */ + vacrel->blkno = InvalidBlockNumber; /* now we can compute the new value for pg_class.reltuples */ - vacrelstats->new_live_tuples = vac_estimate_reltuples(onerel, - nblocks, - vacrelstats->tupcount_pages, - live_tuples); + vacrel->new_live_tuples = vac_estimate_reltuples(vacrel->rel, nblocks, + vacrel->tupcount_pages, + vacrel->live_tuples); - /* also compute total number of surviving heap entries */ - vacrelstats->new_rel_tuples = - vacrelstats->new_live_tuples + vacrelstats->new_dead_tuples; + /* + * Also compute the total number of surviving heap entries. In the + * (unlikely) scenario that new_live_tuples is -1, take it as zero. + */ + vacrel->new_rel_tuples = + Max(vacrel->new_live_tuples, 0) + vacrel->new_dead_tuples; /* * Release any remaining pin on visibility map page. @@ -1714,167 +1622,746 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, } /* If any tuples need to be deleted, perform final vacuum cycle */ - /* XXX put a threshold on min number of tuples here? */ if (dead_tuples->num_tuples > 0) - { - /* Work on all the indexes, and then the heap */ - lazy_vacuum_all_indexes(onerel, Irel, indstats, vacrelstats, - lps, nindexes); - - /* Remove tuples from heap */ - lazy_vacuum_heap(onerel, vacrelstats); - } + lazy_vacuum(vacrel); /* * Vacuum the remainder of the Free Space Map. We must do this whether or - * not there were indexes. + * not there were indexes, and whether or not we bypassed index vacuuming. */ if (blkno > next_fsm_block_to_vacuum) - FreeSpaceMapVacuumRange(onerel, next_fsm_block_to_vacuum, blkno); + FreeSpaceMapVacuumRange(vacrel->rel, next_fsm_block_to_vacuum, blkno); /* report all blocks vacuumed */ pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_VACUUMED, blkno); /* Do post-vacuum cleanup */ - if (vacrelstats->useindex) - lazy_cleanup_all_indexes(Irel, indstats, vacrelstats, lps, nindexes); + if (vacrel->nindexes > 0 && vacrel->do_index_cleanup) + lazy_cleanup_all_indexes(vacrel); /* - * End parallel mode before updating index statistics as we cannot write - * during parallel mode. + * Free resources managed by lazy_space_alloc(). (We must end parallel + * mode/free shared memory before updating index statistics. We cannot + * write while in parallel mode.) */ - if (ParallelVacuumIsActive(lps)) - end_parallel_vacuum(indstats, lps, nindexes); + lazy_space_free(vacrel); /* Update index statistics */ - update_index_statistics(Irel, indstats, nindexes); + if (vacrel->nindexes > 0 && vacrel->do_index_cleanup) + update_index_statistics(vacrel); - /* If no indexes, make log report that lazy_vacuum_heap would've made */ - if (vacuumed_pages) + /* + * If table has no indexes and at least one heap pages was vacuumed, make + * log report that lazy_vacuum_heap_rel would've made had there been + * indexes (having indexes implies using the two pass strategy). + * + * We deliberately don't do this in the case where there are indexes but + * index vacuuming was bypassed. We make a similar report at the point + * that index vacuuming is bypassed, but that's actually quite different + * in one important sense: it shows information about work we _haven't_ + * done. + * + * log_autovacuum output does things differently; it consistently presents + * information about LP_DEAD items for the VACUUM as a whole. We always + * report on each round of index and heap vacuuming separately, though. + */ + if (vacrel->nindexes == 0 && vacrel->lpdead_item_pages > 0) ereport(elevel, - (errmsg("\"%s\": removed %.0f row versions in %u pages", - vacrelstats->relname, - tups_vacuumed, vacuumed_pages))); + (errmsg("\"%s\": removed %lld dead item identifiers in %u pages", + vacrel->relname, (long long) vacrel->lpdead_items, + vacrel->lpdead_item_pages))); + + initStringInfo(&buf); + appendStringInfo(&buf, + _("%lld dead row versions cannot be removed yet, oldest xmin: %u\n"), + (long long) vacrel->new_dead_tuples, vacrel->OldestXmin); + appendStringInfo(&buf, ngettext("%u page removed.\n", + "%u pages removed.\n", + vacrel->pages_removed), + vacrel->pages_removed); + appendStringInfo(&buf, ngettext("Skipped %u page due to buffer pins, ", + "Skipped %u pages due to buffer pins, ", + vacrel->pinskipped_pages), + vacrel->pinskipped_pages); + appendStringInfo(&buf, ngettext("%u frozen page.\n", + "%u frozen pages.\n", + vacrel->frozenskipped_pages), + vacrel->frozenskipped_pages); + appendStringInfo(&buf, _("%s."), pg_rusage_show(&ru0)); + + ereport(elevel, + (errmsg("\"%s\": found %lld removable, %lld nonremovable row versions in %u out of %u pages", + vacrel->relname, + (long long) vacrel->tuples_deleted, + (long long) vacrel->num_tuples, vacrel->scanned_pages, + nblocks), + errdetail_internal("%s", buf.data))); + pfree(buf.data); +} + +/* + * lazy_scan_prune() -- lazy_scan_heap() pruning and freezing. + * + * Caller must hold pin and buffer cleanup lock on the buffer. + * + * Prior to PostgreSQL 14 there were very rare cases where heap_page_prune() + * was allowed to disagree with our HeapTupleSatisfiesVacuum() call about + * whether or not a tuple should be considered DEAD. This happened when an + * inserting transaction concurrently aborted (after our heap_page_prune() + * call, before our HeapTupleSatisfiesVacuum() call). There was rather a lot + * of complexity just so we could deal with tuples that were DEAD to VACUUM, + * but nevertheless were left with storage after pruning. + * + * The approach we take now is to restart pruning when the race condition is + * detected. This allows heap_page_prune() to prune the tuples inserted by + * the now-aborted transaction. This is a little crude, but it guarantees + * that any items that make it into the dead_tuples array are simple LP_DEAD + * line pointers, and that every remaining item with tuple storage is + * considered as a candidate for freezing. + */ +static void +lazy_scan_prune(LVRelState *vacrel, + Buffer buf, + BlockNumber blkno, + Page page, + GlobalVisState *vistest, + LVPagePruneState *prunestate) +{ + Relation rel = vacrel->rel; + OffsetNumber offnum, + maxoff; + ItemId itemid; + HeapTupleData tuple; + HTSV_Result res; + int tuples_deleted, + lpdead_items, + new_dead_tuples, + num_tuples, + live_tuples; + int nfrozen; + OffsetNumber deadoffsets[MaxHeapTuplesPerPage]; + xl_heap_freeze_tuple frozen[MaxHeapTuplesPerPage]; + + maxoff = PageGetMaxOffsetNumber(page); + +retry: + + /* Initialize (or reset) page-level counters */ + tuples_deleted = 0; + lpdead_items = 0; + new_dead_tuples = 0; + num_tuples = 0; + live_tuples = 0; + + /* + * Prune all HOT-update chains in this page. + * + * We count tuples removed by the pruning step as tuples_deleted. Its + * final value can be thought of as the number of tuples that have been + * deleted from the table. It should not be confused with lpdead_items; + * lpdead_items's final value can be thought of as the number of tuples + * that were deleted from indexes. + */ + tuples_deleted = heap_page_prune(rel, buf, vistest, + InvalidTransactionId, 0, false, + &vacrel->offnum); + + /* + * Now scan the page to collect LP_DEAD items and check for tuples + * requiring freezing among remaining tuples with storage + */ + prunestate->hastup = false; + prunestate->has_lpdead_items = false; + prunestate->all_visible = true; + prunestate->all_frozen = true; + prunestate->visibility_cutoff_xid = InvalidTransactionId; + nfrozen = 0; + + for (offnum = FirstOffsetNumber; + offnum <= maxoff; + offnum = OffsetNumberNext(offnum)) + { + bool tuple_totally_frozen; + + /* + * Set the offset number so that we can display it along with any + * error that occurred while processing this tuple. + */ + vacrel->offnum = offnum; + itemid = PageGetItemId(page, offnum); + + if (!ItemIdIsUsed(itemid)) + continue; + + /* Redirect items mustn't be touched */ + if (ItemIdIsRedirected(itemid)) + { + prunestate->hastup = true; /* page won't be truncatable */ + continue; + } + + /* + * LP_DEAD items are processed outside of the loop. + * + * Note that we deliberately don't set hastup=true in the case of an + * LP_DEAD item here, which is not how lazy_check_needs_freeze() or + * count_nondeletable_pages() do it -- they only consider pages empty + * when they only have LP_UNUSED items, which is important for + * correctness. + * + * Our assumption is that any LP_DEAD items we encounter here will + * become LP_UNUSED inside lazy_vacuum_heap_page() before we actually + * call count_nondeletable_pages(). In any case our opinion of + * whether or not a page 'hastup' (which is how our caller sets its + * vacrel->nonempty_pages value) is inherently race-prone. It must be + * treated as advisory/unreliable, so we might as well be slightly + * optimistic. + */ + if (ItemIdIsDead(itemid)) + { + deadoffsets[lpdead_items++] = offnum; + prunestate->all_visible = false; + prunestate->has_lpdead_items = true; + continue; + } + + Assert(ItemIdIsNormal(itemid)); + + ItemPointerSet(&(tuple.t_self), blkno, offnum); + tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid); + tuple.t_len = ItemIdGetLength(itemid); + tuple.t_tableOid = RelationGetRelid(rel); + + /* + * DEAD tuples are almost always pruned into LP_DEAD line pointers by + * heap_page_prune(), but it's possible that the tuple state changed + * since heap_page_prune() looked. Handle that here by restarting. + * (See comments at the top of function for a full explanation.) + */ + res = HeapTupleSatisfiesVacuum(rel, &tuple, vacrel->OldestXmin, buf); + + if (unlikely(res == HEAPTUPLE_DEAD)) + goto retry; + + /* + * The criteria for counting a tuple as live in this block need to + * match what analyze.c's acquire_sample_rows() does, otherwise VACUUM + * and ANALYZE may produce wildly different reltuples values, e.g. + * when there are many recently-dead tuples. + * + * The logic here is a bit simpler than acquire_sample_rows(), as + * VACUUM can't run inside a transaction block, which makes some cases + * impossible (e.g. in-progress insert from the same transaction). + * + * We treat LP_DEAD items a little differently, too -- we don't count + * them as dead_tuples at all (we only consider new_dead_tuples). The + * outcome is no different because we assume that any LP_DEAD items we + * encounter here will become LP_UNUSED inside lazy_vacuum_heap_page() + * before we report anything to the stats collector. (Cases where we + * bypass index vacuuming will violate our assumption, but the overall + * impact of that should be negligible.) + */ + switch (res) + { + case HEAPTUPLE_LIVE: + + /* + * Count it as live. Not only is this natural, but it's also + * what acquire_sample_rows() does. + */ + live_tuples++; + + /* + * Is the tuple definitely visible to all transactions? + * + * NB: Like with per-tuple hint bits, we can't set the + * PD_ALL_VISIBLE flag if the inserter committed + * asynchronously. See SetHintBits for more info. Check that + * the tuple is hinted xmin-committed because of that. + */ + if (prunestate->all_visible) + { + TransactionId xmin; + + if (!HeapTupleHeaderXminCommitted(tuple.t_data)) + { + prunestate->all_visible = false; + break; + } + + /* + * The inserter definitely committed. But is it old enough + * that everyone sees it as committed? + */ + xmin = HeapTupleHeaderGetXmin(tuple.t_data); + if (!TransactionIdPrecedes(xmin, vacrel->OldestXmin)) + { + prunestate->all_visible = false; + break; + } + + /* Track newest xmin on page. */ + if (TransactionIdFollows(xmin, prunestate->visibility_cutoff_xid)) + prunestate->visibility_cutoff_xid = xmin; + } + break; + case HEAPTUPLE_RECENTLY_DEAD: + + /* + * If tuple is recently deleted then we must not remove it + * from relation. (We only remove items that are LP_DEAD from + * pruning.) + */ + new_dead_tuples++; + prunestate->all_visible = false; + break; + case HEAPTUPLE_INSERT_IN_PROGRESS: + + /* + * We do not count these rows as live, because we expect the + * inserting transaction to update the counters at commit, and + * we assume that will happen only after we report our + * results. This assumption is a bit shaky, but it is what + * acquire_sample_rows() does, so be consistent. + */ + prunestate->all_visible = false; + break; + case HEAPTUPLE_DELETE_IN_PROGRESS: + /* This is an expected case during concurrent vacuum */ + prunestate->all_visible = false; + + /* + * Count such rows as live. As above, we assume the deleting + * transaction will commit and update the counters after we + * report. + */ + live_tuples++; + break; + default: + elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); + break; + } + + /* + * Non-removable tuple (i.e. tuple with storage). + * + * Check tuple left behind after pruning to see if needs to be frozen + * now. + */ + num_tuples++; + prunestate->hastup = true; + if (heap_prepare_freeze_tuple(tuple.t_data, + vacrel->relfrozenxid, + vacrel->relminmxid, + vacrel->FreezeLimit, + vacrel->MultiXactCutoff, + &frozen[nfrozen], + &tuple_totally_frozen)) + { + /* Will execute freeze below */ + frozen[nfrozen++].offset = offnum; + } + + /* + * If tuple is not frozen (and not about to become frozen) then caller + * had better not go on to set this page's VM bit + */ + if (!tuple_totally_frozen) + prunestate->all_frozen = false; + } + + /* + * We have now divided every item on the page into either an LP_DEAD item + * that will need to be vacuumed in indexes later, or a LP_NORMAL tuple + * that remains and needs to be considered for freezing now (LP_UNUSED and + * LP_REDIRECT items also remain, but are of no further interest to us). + */ + vacrel->offnum = InvalidOffsetNumber; + + /* + * Consider the need to freeze any items with tuple storage from the page + * first (arbitrary) + */ + if (nfrozen > 0) + { + Assert(prunestate->hastup); + + /* + * At least one tuple with storage needs to be frozen -- execute that + * now. + * + * If we need to freeze any tuples we'll mark the buffer dirty, and + * write a WAL record recording the changes. We must log the changes + * to be crash-safe against future truncation of CLOG. + */ + START_CRIT_SECTION(); + + MarkBufferDirty(buf); + + /* execute collected freezes */ + for (int i = 0; i < nfrozen; i++) + { + HeapTupleHeader htup; + + itemid = PageGetItemId(page, frozen[i].offset); + htup = (HeapTupleHeader) PageGetItem(page, itemid); + + heap_execute_freeze_tuple(htup, &frozen[i]); + } + + /* Now WAL-log freezing if necessary */ + if (RelationNeedsWAL(vacrel->rel)) + { + XLogRecPtr recptr; + + recptr = log_heap_freeze(vacrel->rel, buf, vacrel->FreezeLimit, + frozen, nfrozen); + PageSetLSN(page, recptr); + } + + END_CRIT_SECTION(); + } + + /* + * The second pass over the heap can also set visibility map bits, using + * the same approach. This is important when the table frequently has a + * few old LP_DEAD items on each page by the time we get to it (typically + * because past opportunistic pruning operations freed some non-HOT + * tuples). + * + * VACUUM will call heap_page_is_all_visible() during the second pass over + * the heap to determine all_visible and all_frozen for the page -- this + * is a specialized version of the logic from this function. Now that + * we've finished pruning and freezing, make sure that we're in total + * agreement with heap_page_is_all_visible() using an assertion. + */ +#ifdef USE_ASSERT_CHECKING + /* Note that all_frozen value does not matter when !all_visible */ + if (prunestate->all_visible) + { + TransactionId cutoff; + bool all_frozen; + + if (!heap_page_is_all_visible(vacrel, buf, &cutoff, &all_frozen)) + Assert(false); + + Assert(lpdead_items == 0); + Assert(prunestate->all_frozen == all_frozen); + + /* + * It's possible that we froze tuples and made the page's XID cutoff + * (for recovery conflict purposes) FrozenTransactionId. This is okay + * because visibility_cutoff_xid will be logged by our caller in a + * moment. + */ + Assert(cutoff == FrozenTransactionId || + cutoff == prunestate->visibility_cutoff_xid); + } +#endif + + /* + * Now save details of the LP_DEAD items from the page in the dead_tuples + * array. Also record that page has dead items in per-page prunestate. + */ + if (lpdead_items > 0) + { + LVDeadTuples *dead_tuples = vacrel->dead_tuples; + ItemPointerData tmp; + + Assert(!prunestate->all_visible); + Assert(prunestate->has_lpdead_items); + + vacrel->lpdead_item_pages++; + + ItemPointerSetBlockNumber(&tmp, blkno); + + for (int i = 0; i < lpdead_items; i++) + { + ItemPointerSetOffsetNumber(&tmp, deadoffsets[i]); + dead_tuples->itemptrs[dead_tuples->num_tuples++] = tmp; + } + + Assert(dead_tuples->num_tuples <= dead_tuples->max_tuples); + pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES, + dead_tuples->num_tuples); + } + + /* Finally, add page-local counts to whole-VACUUM counts */ + vacrel->tuples_deleted += tuples_deleted; + vacrel->lpdead_items += lpdead_items; + vacrel->new_dead_tuples += new_dead_tuples; + vacrel->num_tuples += num_tuples; + vacrel->live_tuples += live_tuples; +} + +/* + * Remove the collected garbage tuples from the table and its indexes. + * + * We may choose to bypass index vacuuming at this point, though only when the + * ongoing VACUUM operation will definitely only have one index scan/round of + * index vacuuming. Caller indicates whether or not this is such a VACUUM + * operation using 'onecall' argument. + * + * In rare emergencies, the ongoing VACUUM operation can be made to skip both + * index vacuuming and index cleanup at the point we're called. This avoids + * having the whole system refuse to allocate further XIDs/MultiXactIds due to + * wraparound. + */ +static void +lazy_vacuum(LVRelState *vacrel) +{ + bool bypass; + + /* Should not end up here with no indexes */ + Assert(vacrel->nindexes > 0); + Assert(!IsParallelWorker()); + Assert(vacrel->lpdead_item_pages > 0); + + if (!vacrel->do_index_vacuuming) + { + Assert(!vacrel->do_index_cleanup); + vacrel->dead_tuples->num_tuples = 0; + return; + } + + /* + * Consider bypassing index vacuuming (and heap vacuuming) entirely. + * + * We currently only do this in cases where the number of LP_DEAD items + * for the entire VACUUM operation is close to zero. This avoids sharp + * discontinuities in the duration and overhead of successive VACUUM + * operations that run against the same table with a fixed workload. + * Ideally, successive VACUUM operations will behave as if there are + * exactly zero LP_DEAD items in cases where there are close to zero. + * + * This is likely to be helpful with a table that is continually affected + * by UPDATEs that can mostly apply the HOT optimization, but occasionally + * have small aberrations that lead to just a few heap pages retaining + * only one or two LP_DEAD items. This is pretty common; even when the + * DBA goes out of their way to make UPDATEs use HOT, it is practically + * impossible to predict whether HOT will be applied in 100% of cases. + * It's far easier to ensure that 99%+ of all UPDATEs against a table use + * HOT through careful tuning. + */ + bypass = false; + if (vacrel->consider_bypass_optimization && vacrel->rel_pages > 0) + { + BlockNumber threshold; + + Assert(vacrel->num_index_scans == 0); + Assert(vacrel->lpdead_items == vacrel->dead_tuples->num_tuples); + Assert(vacrel->do_index_vacuuming); + Assert(vacrel->do_index_cleanup); + + /* + * This crossover point at which we'll start to do index vacuuming is + * expressed as a percentage of the total number of heap pages in the + * table that are known to have at least one LP_DEAD item. This is + * much more important than the total number of LP_DEAD items, since + * it's a proxy for the number of heap pages whose visibility map bits + * cannot be set on account of bypassing index and heap vacuuming. + * + * We apply one further precautionary test: the space currently used + * to store the TIDs (TIDs that now all point to LP_DEAD items) must + * not exceed 32MB. This limits the risk that we will bypass index + * vacuuming again and again until eventually there is a VACUUM whose + * dead_tuples space is not CPU cache resident. + * + * We don't take any special steps to remember the LP_DEAD items (such + * as counting them in new_dead_tuples report to the stats collector) + * when the optimization is applied. Though the accounting used in + * analyze.c's acquire_sample_rows() will recognize the same LP_DEAD + * items as dead rows in its own stats collector report, that's okay. + * The discrepancy should be negligible. If this optimization is ever + * expanded to cover more cases then this may need to be reconsidered. + */ + threshold = (double) vacrel->rel_pages * BYPASS_THRESHOLD_PAGES; + bypass = (vacrel->lpdead_item_pages < threshold && + vacrel->lpdead_items < MAXDEADTUPLES(32L * 1024L * 1024L)); + } + + if (bypass) + { + /* + * There are almost zero TIDs. Behave as if there were precisely + * zero: bypass index vacuuming, but do index cleanup. + * + * We expect that the ongoing VACUUM operation will finish very + * quickly, so there is no point in considering speeding up as a + * failsafe against wraparound failure. (Index cleanup is expected to + * finish very quickly in cases where there were no ambulkdelete() + * calls.) + */ + vacrel->do_index_vacuuming = false; + ereport(elevel, + (errmsg("\"%s\": index scan bypassed: %u pages from table (%.2f%% of total) have %lld dead item identifiers", + vacrel->relname, vacrel->lpdead_item_pages, + 100.0 * vacrel->lpdead_item_pages / vacrel->rel_pages, + (long long) vacrel->lpdead_items))); + } + else if (lazy_vacuum_all_indexes(vacrel)) + { + /* + * We successfully completed a round of index vacuuming. Do related + * heap vacuuming now. + */ + lazy_vacuum_heap_rel(vacrel); + } + else + { + /* + * Failsafe case. + * + * we attempted index vacuuming, but didn't finish a full round/full + * index scan. This happens when relfrozenxid or relminmxid is too + * far in the past. + * + * From this point on the VACUUM operation will do no further index + * vacuuming or heap vacuuming. This VACUUM operation won't end up + * back here again. + */ + Assert(vacrel->failsafe_active); + } /* - * This is pretty messy, but we split it up so that we can skip emitting - * individual parts of the message when not applicable. + * Forget the LP_DEAD items that we just vacuumed (or just decided to not + * vacuum) */ - initStringInfo(&buf); - appendStringInfo(&buf, - _("%.0f dead row versions cannot be removed yet, oldest xmin: %u\n"), - nkeep, OldestXmin); - appendStringInfo(&buf, _("There were %.0f unused item identifiers.\n"), - nunused); - appendStringInfo(&buf, ngettext("Skipped %u page due to buffer pins, ", - "Skipped %u pages due to buffer pins, ", - vacrelstats->pinskipped_pages), - vacrelstats->pinskipped_pages); - appendStringInfo(&buf, ngettext("%u frozen page.\n", - "%u frozen pages.\n", - vacrelstats->frozenskipped_pages), - vacrelstats->frozenskipped_pages); - appendStringInfo(&buf, ngettext("%u page is entirely empty.\n", - "%u pages are entirely empty.\n", - empty_pages), - empty_pages); - appendStringInfo(&buf, _("%s."), pg_rusage_show(&ru0)); - - ereport(elevel, - (errmsg("\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages", - vacrelstats->relname, - tups_vacuumed, num_tuples, - vacrelstats->scanned_pages, nblocks), - errdetail_internal("%s", buf.data))); - pfree(buf.data); + vacrel->dead_tuples->num_tuples = 0; } /* - * lazy_vacuum_all_indexes() -- vacuum all indexes of relation. + * lazy_vacuum_all_indexes() -- Main entry for index vacuuming * - * We process the indexes serially unless we are doing parallel vacuum. + * Returns true in the common case when all indexes were successfully + * vacuumed. Returns false in rare cases where we determined that the ongoing + * VACUUM operation is at risk of taking too long to finish, leading to + * wraparound failure. */ -static void -lazy_vacuum_all_indexes(Relation onerel, Relation *Irel, - IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes) +static bool +lazy_vacuum_all_indexes(LVRelState *vacrel) { - Assert(!IsParallelWorker()); - Assert(nindexes > 0); + bool allindexes = true; - /* Log cleanup info before we touch indexes */ - vacuum_log_cleanup_info(onerel, vacrelstats); + Assert(!IsParallelWorker()); + Assert(vacrel->nindexes > 0); + Assert(vacrel->do_index_vacuuming); + Assert(vacrel->do_index_cleanup); + Assert(TransactionIdIsNormal(vacrel->relfrozenxid)); + Assert(MultiXactIdIsValid(vacrel->relminmxid)); + + /* Precheck for XID wraparound emergencies */ + if (lazy_check_wraparound_failsafe(vacrel)) + { + /* Wraparound emergency -- don't even start an index scan */ + return false; + } /* Report that we are now vacuuming indexes */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_VACUUM_INDEX); - /* Perform index vacuuming with parallel workers for parallel vacuum. */ - if (ParallelVacuumIsActive(lps)) + if (!ParallelVacuumIsActive(vacrel)) { - /* Tell parallel workers to do index vacuuming */ - lps->lvshared->for_cleanup = false; - lps->lvshared->first_time = false; + for (int idx = 0; idx < vacrel->nindexes; idx++) + { + Relation indrel = vacrel->indrels[idx]; + IndexBulkDeleteResult *istat = vacrel->indstats[idx]; - /* - * We can only provide an approximate value of num_heap_tuples in - * vacuum cases. - */ - lps->lvshared->reltuples = vacrelstats->old_live_tuples; - lps->lvshared->estimated_count = true; + vacrel->indstats[idx] = + lazy_vacuum_one_index(indrel, istat, vacrel->old_live_tuples, + vacrel); - lazy_parallel_vacuum_indexes(Irel, stats, vacrelstats, lps, nindexes); + if (lazy_check_wraparound_failsafe(vacrel)) + { + /* Wraparound emergency -- end current index scan */ + allindexes = false; + break; + } + } } else { - int idx; + /* Outsource everything to parallel variant */ + do_parallel_lazy_vacuum_all_indexes(vacrel); - for (idx = 0; idx < nindexes; idx++) - lazy_vacuum_index(Irel[idx], &stats[idx], vacrelstats->dead_tuples, - vacrelstats->old_live_tuples, vacrelstats); + /* + * Do a postcheck to consider applying wraparound failsafe now. Note + * that parallel VACUUM only gets the precheck and this postcheck. + */ + if (lazy_check_wraparound_failsafe(vacrel)) + allindexes = false; } - /* Increase and report the number of index scans */ - vacrelstats->num_index_scans++; + /* + * We delete all LP_DEAD items from the first heap pass in all indexes on + * each call here (except calls where we choose to do the failsafe). This + * makes the next call to lazy_vacuum_heap_rel() safe (except in the event + * of the failsafe triggering, which prevents the next call from taking + * place). + */ + Assert(vacrel->num_index_scans > 0 || + vacrel->dead_tuples->num_tuples == vacrel->lpdead_items); + Assert(allindexes || vacrel->failsafe_active); + + /* + * Increase and report the number of index scans. + * + * We deliberately include the case where we started a round of bulk + * deletes that we weren't able to finish due to the failsafe triggering. + */ + vacrel->num_index_scans++; pgstat_progress_update_param(PROGRESS_VACUUM_NUM_INDEX_VACUUMS, - vacrelstats->num_index_scans); -} + vacrel->num_index_scans); + return allindexes; +} /* - * lazy_vacuum_heap() -- second pass over the heap + * lazy_vacuum_heap_rel() -- second pass over the heap for two pass strategy + * + * This routine marks LP_DEAD items in vacrel->dead_tuples array as LP_UNUSED. + * Pages that never had lazy_scan_prune record LP_DEAD items are not visited + * at all. * - * This routine marks dead tuples as unused and compacts out free - * space on their pages. Pages not having dead tuples recorded from - * lazy_scan_heap are not visited at all. + * We may also be able to truncate the line pointer array of the heap pages we + * visit. If there is a contiguous group of LP_UNUSED items at the end of the + * array, it can be reclaimed as free space. These LP_UNUSED items usually + * start out as LP_DEAD items recorded by lazy_scan_prune (we set items from + * each page to LP_UNUSED, and then consider if it's possible to truncate the + * page's line pointer array). * - * Note: the reason for doing this as a second pass is we cannot remove - * the tuples until we've removed their index entries, and we want to - * process index entry removal in batches as large as possible. + * Note: the reason for doing this as a second pass is we cannot remove the + * tuples until we've removed their index entries, and we want to process + * index entry removal in batches as large as possible. */ static void -lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats) +lazy_vacuum_heap_rel(LVRelState *vacrel) { int tupindex; - int npages; + BlockNumber vacuumed_pages; PGRUsage ru0; Buffer vmbuffer = InvalidBuffer; LVSavedErrInfo saved_err_info; + Assert(vacrel->do_index_vacuuming); + Assert(vacrel->do_index_cleanup); + Assert(vacrel->num_index_scans > 0); + /* Report that we are now vacuuming the heap */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_VACUUM_HEAP); /* Update error traceback information */ - update_vacuum_error_info(vacrelstats, &saved_err_info, VACUUM_ERRCB_PHASE_VACUUM_HEAP, - InvalidBlockNumber); + update_vacuum_error_info(vacrel, &saved_err_info, + VACUUM_ERRCB_PHASE_VACUUM_HEAP, + InvalidBlockNumber, InvalidOffsetNumber); pg_rusage_init(&ru0); - npages = 0; + vacuumed_pages = 0; tupindex = 0; - while (tupindex < vacrelstats->dead_tuples->num_tuples) + while (tupindex < vacrel->dead_tuples->num_tuples) { BlockNumber tblk; Buffer buf; @@ -1883,71 +2370,87 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats) vacuum_delay_point(); - tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]); - vacrelstats->blkno = tblk; - buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL, - vac_strategy); - if (!ConditionalLockBufferForCleanup(buf)) - { - ReleaseBuffer(buf); - ++tupindex; - continue; - } - tupindex = lazy_vacuum_page(onerel, tblk, buf, tupindex, vacrelstats, - &vmbuffer); + tblk = ItemPointerGetBlockNumber(&vacrel->dead_tuples->itemptrs[tupindex]); + vacrel->blkno = tblk; + buf = ReadBufferExtended(vacrel->rel, MAIN_FORKNUM, tblk, RBM_NORMAL, + vacrel->bstrategy); + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + tupindex = lazy_vacuum_heap_page(vacrel, tblk, buf, tupindex, + &vmbuffer); - /* Now that we've compacted the page, record its available space */ + /* Now that we've vacuumed the page, record its available space */ page = BufferGetPage(buf); freespace = PageGetHeapFreeSpace(page); UnlockReleaseBuffer(buf); - RecordPageWithFreeSpace(onerel, tblk, freespace); - npages++; + RecordPageWithFreeSpace(vacrel->rel, tblk, freespace); + vacuumed_pages++; } + /* Clear the block number information */ + vacrel->blkno = InvalidBlockNumber; + if (BufferIsValid(vmbuffer)) { ReleaseBuffer(vmbuffer); vmbuffer = InvalidBuffer; } + /* + * We set all LP_DEAD items from the first heap pass to LP_UNUSED during + * the second heap pass. No more, no less. + */ + Assert(vacrel->num_index_scans > 1 || + (tupindex == vacrel->lpdead_items && + vacuumed_pages == vacrel->lpdead_item_pages)); + ereport(elevel, - (errmsg("\"%s\": removed %d row versions in %d pages", - vacrelstats->relname, - tupindex, npages), + (errmsg("\"%s\": removed %d dead item identifiers in %u pages", + vacrel->relname, tupindex, vacuumed_pages), errdetail_internal("%s", pg_rusage_show(&ru0)))); /* Revert to the previous phase information for error traceback */ - restore_vacuum_error_info(vacrelstats, &saved_err_info); + restore_vacuum_error_info(vacrel, &saved_err_info); } /* - * lazy_vacuum_page() -- free dead tuples on a page - * and repair its fragmentation. + * lazy_vacuum_heap_page() -- free page's LP_DEAD items listed in the + * vacrel->dead_tuples array. * - * Caller must hold pin and buffer cleanup lock on the buffer. + * Caller must have an exclusive buffer lock on the buffer (though a + * super-exclusive lock is also acceptable). * - * tupindex is the index in vacrelstats->dead_tuples of the first dead - * tuple for this page. We assume the rest follow sequentially. - * The return value is the first tupindex after the tuples of this page. + * tupindex is the index in vacrel->dead_tuples of the first dead tuple for + * this page. We assume the rest follow sequentially. The return value is + * the first tupindex after the tuples of this page. + * + * Prior to PostgreSQL 14 there were rare cases where this routine had to set + * tuples with storage to unused. These days it is strictly responsible for + * marking LP_DEAD stub line pointers as unused. This only happens for those + * LP_DEAD items on the page that were determined to be LP_DEAD items back + * when the same page was visited by lazy_scan_prune() (i.e. those whose TID + * was recorded in the dead_tuples array). */ static int -lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, - int tupindex, LVRelStats *vacrelstats, Buffer *vmbuffer) +lazy_vacuum_heap_page(LVRelState *vacrel, BlockNumber blkno, Buffer buffer, + int tupindex, Buffer *vmbuffer) { - LVDeadTuples *dead_tuples = vacrelstats->dead_tuples; + LVDeadTuples *dead_tuples = vacrel->dead_tuples; Page page = BufferGetPage(buffer); - OffsetNumber unused[MaxOffsetNumber]; + OffsetNumber unused[MaxHeapTuplesPerPage]; int uncnt = 0; TransactionId visibility_cutoff_xid; bool all_frozen; LVSavedErrInfo saved_err_info; + Assert(vacrel->nindexes == 0 || vacrel->do_index_vacuuming); + pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_VACUUMED, blkno); /* Update error traceback information */ - update_vacuum_error_info(vacrelstats, &saved_err_info, VACUUM_ERRCB_PHASE_VACUUM_HEAP, - blkno); + update_vacuum_error_info(vacrel, &saved_err_info, + VACUUM_ERRCB_PHASE_VACUUM_HEAP, blkno, + InvalidOffsetNumber); START_CRIT_SECTION(); @@ -1962,11 +2465,16 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, break; /* past end of tuples for this block */ toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]); itemid = PageGetItemId(page, toff); + + Assert(ItemIdIsDead(itemid) && !ItemIdHasStorage(itemid)); ItemIdSetUnused(itemid); unused[uncnt++] = toff; } - PageRepairFragmentation(page); + Assert(uncnt > 0); + + /* Attempt to truncate line pointer array now */ + PageTruncateLinePointerArray(page); /* * Mark buffer dirty before we write WAL. @@ -1974,14 +2482,21 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, MarkBufferDirty(buffer); /* XLOG stuff */ - if (RelationNeedsWAL(onerel)) + if (RelationNeedsWAL(vacrel->rel)) { + xl_heap_vacuum xlrec; XLogRecPtr recptr; - recptr = log_heap_clean(onerel, buffer, - NULL, 0, NULL, 0, - unused, uncnt, - vacrelstats->latestRemovedXid); + xlrec.nunused = uncnt; + + XLogBeginInsert(); + XLogRegisterData((char *) &xlrec, SizeOfHeapVacuum); + + XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + XLogRegisterBufData(0, (char *) unused, uncnt * sizeof(OffsetNumber)); + + recptr = XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_VACUUM); + PageSetLSN(page, recptr); } @@ -1994,12 +2509,12 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, END_CRIT_SECTION(); /* - * Now that we have removed the dead tuples from the page, once again + * Now that we have removed the LD_DEAD items from the page, once again * check if the page has become all-visible. The page is already marked * dirty, exclusively locked, and, if needed, a full page image has been - * emitted in the log_heap_clean() above. + * emitted. */ - if (heap_page_is_all_visible(onerel, buffer, &visibility_cutoff_xid, + if (heap_page_is_all_visible(vacrel, buffer, &visibility_cutoff_xid, &all_frozen)) PageSetAllVisible(page); @@ -2010,8 +2525,9 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, */ if (PageIsAllVisible(page)) { - uint8 vm_status = visibilitymap_get_status(onerel, blkno, vmbuffer); uint8 flags = 0; + uint8 vm_status = visibilitymap_get_status(vacrel->rel, + blkno, vmbuffer); /* Set the VM all-frozen bit to flag, if needed */ if ((vm_status & VISIBILITYMAP_ALL_VISIBLE) == 0) @@ -2021,12 +2537,12 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, Assert(BufferIsValid(*vmbuffer)); if (flags != 0) - visibilitymap_set(onerel, blkno, buffer, InvalidXLogRecPtr, + visibilitymap_set(vacrel->rel, blkno, buffer, InvalidXLogRecPtr, *vmbuffer, visibility_cutoff_xid, flags); } /* Revert to the previous phase information for error traceback */ - restore_vacuum_error_info(vacrelstats, &saved_err_info); + restore_vacuum_error_info(vacrel, &saved_err_info); return tupindex; } @@ -2038,7 +2554,7 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, * Also returns a flag indicating whether page contains any tuples at all. */ static bool -lazy_check_needs_freeze(Buffer buf, bool *hastup) +lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelState *vacrel) { Page page = BufferGetPage(buf); OffsetNumber offnum, @@ -2063,6 +2579,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup) { ItemId itemid; + /* + * Set the offset number so that we can display it along with any + * error that occurred while processing this tuple. + */ + vacrel->offnum = offnum; itemid = PageGetItemId(page, offnum); /* this should match hastup test in count_nondeletable_pages() */ @@ -2075,14 +2596,123 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup) tupleheader = (HeapTupleHeader) PageGetItem(page, itemid); - if (heap_tuple_needs_freeze(tupleheader, FreezeLimit, - MultiXactCutoff, buf)) - return true; + if (heap_tuple_needs_freeze(tupleheader, vacrel->FreezeLimit, + vacrel->MultiXactCutoff, buf)) + break; } /* scan along page */ + /* Clear the offset information once we have processed the given page. */ + vacrel->offnum = InvalidOffsetNumber; + + return (offnum <= maxoff); +} + +/* + * Trigger the failsafe to avoid wraparound failure when vacrel table has a + * relfrozenxid and/or relminmxid that is dangerously far in the past. + * Triggering the failsafe makes the ongoing VACUUM bypass any further index + * vacuuming and heap vacuuming. Truncating the heap is also bypassed. + * + * Any remaining work (work that VACUUM cannot just bypass) is typically sped + * up when the failsafe triggers. VACUUM stops applying any cost-based delay + * that it started out with. + * + * Returns true when failsafe has been triggered. + */ +static bool +lazy_check_wraparound_failsafe(LVRelState *vacrel) +{ + /* Don't warn more than once per VACUUM */ + if (vacrel->failsafe_active) + return true; + + if (unlikely(vacuum_xid_failsafe_check(vacrel->relfrozenxid, + vacrel->relminmxid))) + { + vacrel->failsafe_active = true; + + /* Disable index vacuuming, index cleanup, and heap rel truncation */ + vacrel->do_index_vacuuming = false; + vacrel->do_index_cleanup = false; + vacrel->do_rel_truncate = false; + + ereport(WARNING, + (errmsg("bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans", + get_database_name(MyDatabaseId), + vacrel->relnamespace, + vacrel->relname, + vacrel->num_index_scans), + errdetail("table's relfrozenxid or relminmxid is too far in the past"), + errhint("Consider increasing configuration parameter \"maintenance_work_mem\" or \"autovacuum_work_mem\".\n" + "You might also need to consider other ways for VACUUM to keep up with the allocation of transaction IDs."))); + + /* Stop applying cost limits from this point on */ + VacuumCostActive = false; + VacuumCostBalance = 0; + + return true; + } + return false; } +/* + * Perform lazy_vacuum_all_indexes() steps in parallel + */ +static void +do_parallel_lazy_vacuum_all_indexes(LVRelState *vacrel) +{ + /* Tell parallel workers to do index vacuuming */ + vacrel->lps->lvshared->for_cleanup = false; + vacrel->lps->lvshared->first_time = false; + + /* + * We can only provide an approximate value of num_heap_tuples in vacuum + * cases. + */ + vacrel->lps->lvshared->reltuples = vacrel->old_live_tuples; + vacrel->lps->lvshared->estimated_count = true; + + do_parallel_vacuum_or_cleanup(vacrel, + vacrel->lps->nindexes_parallel_bulkdel); +} + +/* + * Perform lazy_cleanup_all_indexes() steps in parallel + */ +static void +do_parallel_lazy_cleanup_all_indexes(LVRelState *vacrel) +{ + int nworkers; + + /* + * If parallel vacuum is active we perform index cleanup with parallel + * workers. + * + * Tell parallel workers to do index cleanup. + */ + vacrel->lps->lvshared->for_cleanup = true; + vacrel->lps->lvshared->first_time = (vacrel->num_index_scans == 0); + + /* + * Now we can provide a better estimate of total number of surviving + * tuples (we assume indexes are more interested in that than in the + * number of nominally live tuples). + */ + vacrel->lps->lvshared->reltuples = vacrel->new_rel_tuples; + vacrel->lps->lvshared->estimated_count = + (vacrel->tupcount_pages < vacrel->rel_pages); + + /* Determine the number of parallel workers to launch */ + if (vacrel->lps->lvshared->first_time) + nworkers = vacrel->lps->nindexes_parallel_cleanup + + vacrel->lps->nindexes_parallel_condcleanup; + else + nworkers = vacrel->lps->nindexes_parallel_cleanup; + + do_parallel_vacuum_or_cleanup(vacrel, nworkers); +} + /* * Perform index vacuum or index cleanup with parallel workers. This function * must be used by the parallel vacuum leader process. The caller must set @@ -2090,27 +2720,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup) * cleanup. */ static void -lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes) +do_parallel_vacuum_or_cleanup(LVRelState *vacrel, int nworkers) { - int nworkers; + LVParallelState *lps = vacrel->lps; Assert(!IsParallelWorker()); - Assert(ParallelVacuumIsActive(lps)); - Assert(nindexes > 0); - - /* Determine the number of parallel workers to launch */ - if (lps->lvshared->for_cleanup) - { - if (lps->lvshared->first_time) - nworkers = lps->nindexes_parallel_cleanup + - lps->nindexes_parallel_condcleanup; - else - nworkers = lps->nindexes_parallel_cleanup; - } - else - nworkers = lps->nindexes_parallel_bulkdel; + Assert(ParallelVacuumIsActive(vacrel)); + Assert(vacrel->nindexes > 0); /* The leader process will participate */ nworkers--; @@ -2125,7 +2741,7 @@ lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, /* Setup the shared cost-based vacuum delay and launch workers */ if (nworkers > 0) { - if (vacrelstats->num_index_scans > 0) + if (vacrel->num_index_scans > 0) { /* Reset the parallel index processing counter */ pg_atomic_write_u32(&(lps->lvshared->idx), 0); @@ -2180,14 +2796,13 @@ lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, } /* Process the indexes that can be processed by only leader process */ - vacuum_indexes_leader(Irel, stats, vacrelstats, lps, nindexes); + do_serial_processing_for_unsafe_indexes(vacrel, lps->lvshared); /* * Join as a parallel worker. The leader process alone processes all the * indexes in the case where no workers are launched. */ - parallel_vacuum_index(Irel, stats, lps->lvshared, - vacrelstats->dead_tuples, nindexes, vacrelstats); + do_parallel_processing(vacrel, lps->lvshared); /* * Next, accumulate buffer and WAL usage. (This must wait for the workers @@ -2195,12 +2810,10 @@ lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, */ if (nworkers > 0) { - int i; - /* Wait for all vacuum workers to finish */ WaitForParallelWorkersToFinish(lps->pcxt); - for (i = 0; i < lps->pcxt->nworkers_launched; i++) + for (int i = 0; i < lps->pcxt->nworkers_launched; i++) InstrAccumParallelQuery(&lps->buffer_usage[i], &lps->wal_usage[i]); } @@ -2220,9 +2833,7 @@ lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, * vacuum worker processes to process the indexes in parallel. */ static void -parallel_vacuum_index(Relation *Irel, IndexBulkDeleteResult **stats, - LVShared *lvshared, LVDeadTuples *dead_tuples, - int nindexes, LVRelStats *vacrelstats) +do_parallel_processing(LVRelState *vacrel, LVShared *lvshared) { /* * Increment the active worker count if we are able to launch any worker. @@ -2234,29 +2845,39 @@ parallel_vacuum_index(Relation *Irel, IndexBulkDeleteResult **stats, for (;;) { int idx; - LVSharedIndStats *shared_indstats; + LVSharedIndStats *shared_istat; + Relation indrel; + IndexBulkDeleteResult *istat; /* Get an index number to process */ idx = pg_atomic_fetch_add_u32(&(lvshared->idx), 1); /* Done for all indexes? */ - if (idx >= nindexes) + if (idx >= vacrel->nindexes) break; /* Get the index statistics of this index from DSM */ - shared_indstats = get_indstats(lvshared, idx); + shared_istat = parallel_stats_for_idx(lvshared, idx); + + /* Skip indexes not participating in parallelism */ + if (shared_istat == NULL) + continue; + + indrel = vacrel->indrels[idx]; /* - * Skip processing indexes that don't participate in parallel - * operation + * Skip processing indexes that are unsafe for workers (these are + * processed in do_serial_processing_for_unsafe_indexes() by leader) */ - if (shared_indstats == NULL || - skip_parallel_vacuum_index(Irel[idx], lvshared)) + if (!parallel_processing_is_safe(indrel, lvshared)) continue; /* Do vacuum or cleanup of the index */ - vacuum_one_index(Irel[idx], &(stats[idx]), lvshared, shared_indstats, - dead_tuples, vacrelstats); + istat = (vacrel->indstats[idx]); + vacrel->indstats[idx] = parallel_process_one_index(indrel, istat, + lvshared, + shared_istat, + vacrel); } /* @@ -2272,12 +2893,8 @@ parallel_vacuum_index(Relation *Irel, IndexBulkDeleteResult **stats, * because these indexes don't support parallel operation at that phase. */ static void -vacuum_indexes_leader(Relation *Irel, IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes) +do_serial_processing_for_unsafe_indexes(LVRelState *vacrel, LVShared *lvshared) { - int i; - Assert(!IsParallelWorker()); /* @@ -2286,18 +2903,32 @@ vacuum_indexes_leader(Relation *Irel, IndexBulkDeleteResult **stats, if (VacuumActiveNWorkers) pg_atomic_add_fetch_u32(VacuumActiveNWorkers, 1); - for (i = 0; i < nindexes; i++) + for (int idx = 0; idx < vacrel->nindexes; idx++) { - LVSharedIndStats *shared_indstats; + LVSharedIndStats *shared_istat; + Relation indrel; + IndexBulkDeleteResult *istat; + + shared_istat = parallel_stats_for_idx(lvshared, idx); - shared_indstats = get_indstats(lps->lvshared, i); + /* Skip already-complete indexes */ + if (shared_istat != NULL) + continue; + + indrel = vacrel->indrels[idx]; + + /* + * We're only here for the unsafe indexes + */ + if (parallel_processing_is_safe(indrel, lvshared)) + continue; - /* Process the indexes skipped by parallel workers */ - if (shared_indstats == NULL || - skip_parallel_vacuum_index(Irel[i], lps->lvshared)) - vacuum_one_index(Irel[i], &(stats[i]), lps->lvshared, - shared_indstats, vacrelstats->dead_tuples, - vacrelstats); + /* Do vacuum or cleanup of the index */ + istat = (vacrel->indstats[idx]); + vacrel->indstats[idx] = parallel_process_one_index(indrel, istat, + lvshared, + shared_istat, + vacrel); } /* @@ -2314,33 +2945,29 @@ vacuum_indexes_leader(Relation *Irel, IndexBulkDeleteResult **stats, * statistics returned from ambulkdelete and amvacuumcleanup to the DSM * segment. */ -static void -vacuum_one_index(Relation indrel, IndexBulkDeleteResult **stats, - LVShared *lvshared, LVSharedIndStats *shared_indstats, - LVDeadTuples *dead_tuples, LVRelStats *vacrelstats) +static IndexBulkDeleteResult * +parallel_process_one_index(Relation indrel, + IndexBulkDeleteResult *istat, + LVShared *lvshared, + LVSharedIndStats *shared_istat, + LVRelState *vacrel) { - IndexBulkDeleteResult *bulkdelete_res = NULL; + IndexBulkDeleteResult *istat_res; - if (shared_indstats) - { - /* Get the space for IndexBulkDeleteResult */ - bulkdelete_res = &(shared_indstats->stats); - - /* - * Update the pointer to the corresponding bulk-deletion result if - * someone has already updated it. - */ - if (shared_indstats->updated && *stats == NULL) - *stats = bulkdelete_res; - } + /* + * Update the pointer to the corresponding bulk-deletion result if someone + * has already updated it + */ + if (shared_istat && shared_istat->updated && istat == NULL) + istat = &shared_istat->istat; /* Do vacuum or cleanup of the index */ if (lvshared->for_cleanup) - lazy_cleanup_index(indrel, stats, lvshared->reltuples, - lvshared->estimated_count, vacrelstats); + istat_res = lazy_cleanup_one_index(indrel, istat, lvshared->reltuples, + lvshared->estimated_count, vacrel); else - lazy_vacuum_index(indrel, stats, dead_tuples, - lvshared->reltuples, vacrelstats); + istat_res = lazy_vacuum_one_index(indrel, istat, lvshared->reltuples, + vacrel); /* * Copy the index bulk-deletion result returned from ambulkdelete and @@ -2354,87 +2981,73 @@ vacuum_one_index(Relation indrel, IndexBulkDeleteResult **stats, * Since all vacuum workers write the bulk-deletion result at different * slots we can write them without locking. */ - if (shared_indstats && !shared_indstats->updated && *stats != NULL) + if (shared_istat && !shared_istat->updated && istat_res != NULL) { - memcpy(bulkdelete_res, *stats, sizeof(IndexBulkDeleteResult)); - shared_indstats->updated = true; + memcpy(&shared_istat->istat, istat_res, sizeof(IndexBulkDeleteResult)); + shared_istat->updated = true; - /* - * Now that stats[idx] points to the DSM segment, we don't need the - * locally allocated results. - */ - pfree(*stats); - *stats = bulkdelete_res; + /* Free the locally-allocated bulk-deletion result */ + pfree(istat_res); + + /* return the pointer to the result from shared memory */ + return &shared_istat->istat; } + + return istat_res; } /* * lazy_cleanup_all_indexes() -- cleanup all indexes of relation. - * - * Cleanup indexes. We process the indexes serially unless we are doing - * parallel vacuum. */ static void -lazy_cleanup_all_indexes(Relation *Irel, IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats, LVParallelState *lps, - int nindexes) +lazy_cleanup_all_indexes(LVRelState *vacrel) { - int idx; - Assert(!IsParallelWorker()); - Assert(nindexes > 0); + Assert(vacrel->nindexes > 0); /* Report that we are now cleaning up indexes */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_INDEX_CLEANUP); - /* - * If parallel vacuum is active we perform index cleanup with parallel - * workers. - */ - if (ParallelVacuumIsActive(lps)) + if (!ParallelVacuumIsActive(vacrel)) { - /* Tell parallel workers to do index cleanup */ - lps->lvshared->for_cleanup = true; - lps->lvshared->first_time = - (vacrelstats->num_index_scans == 0); + double reltuples = vacrel->new_rel_tuples; + bool estimated_count = + vacrel->tupcount_pages < vacrel->rel_pages; - /* - * Now we can provide a better estimate of total number of surviving - * tuples (we assume indexes are more interested in that than in the - * number of nominally live tuples). - */ - lps->lvshared->reltuples = vacrelstats->new_rel_tuples; - lps->lvshared->estimated_count = - (vacrelstats->tupcount_pages < vacrelstats->rel_pages); + for (int idx = 0; idx < vacrel->nindexes; idx++) + { + Relation indrel = vacrel->indrels[idx]; + IndexBulkDeleteResult *istat = vacrel->indstats[idx]; - lazy_parallel_vacuum_indexes(Irel, stats, vacrelstats, lps, nindexes); + vacrel->indstats[idx] = + lazy_cleanup_one_index(indrel, istat, reltuples, + estimated_count, vacrel); + } } else { - for (idx = 0; idx < nindexes; idx++) - lazy_cleanup_index(Irel[idx], &stats[idx], - vacrelstats->new_rel_tuples, - vacrelstats->tupcount_pages < vacrelstats->rel_pages, - vacrelstats); + /* Outsource everything to parallel variant */ + do_parallel_lazy_cleanup_all_indexes(vacrel); } } /* - * lazy_vacuum_index() -- vacuum one index relation. + * lazy_vacuum_one_index() -- vacuum index relation. * * Delete all the index entries pointing to tuples listed in * dead_tuples, and update running statistics. * * reltuples is the number of heap tuples to be passed to the - * bulkdelete callback. + * bulkdelete callback. It's always assumed to be estimated. + * + * Returns bulk delete stats derived from input stats */ -static void -lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats, - LVDeadTuples *dead_tuples, double reltuples, LVRelStats *vacrelstats) +static IndexBulkDeleteResult * +lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat, + double reltuples, LVRelState *vacrel) { IndexVacuumInfo ivinfo; - const char *msg; PGRUsage ru0; LVSavedErrInfo saved_err_info; @@ -2446,7 +3059,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats, ivinfo.estimated_count = true; ivinfo.message_level = elevel; ivinfo.num_heap_tuples = reltuples; - ivinfo.strategy = vac_strategy; + ivinfo.strategy = vacrel->bstrategy; /* * Update error traceback information. @@ -2454,46 +3067,43 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats, * The index name is saved during this phase and restored immediately * after this phase. See vacuum_error_callback. */ - Assert(vacrelstats->indname == NULL); - vacrelstats->indname = pstrdup(RelationGetRelationName(indrel)); - update_vacuum_error_info(vacrelstats, &saved_err_info, + Assert(vacrel->indname == NULL); + vacrel->indname = pstrdup(RelationGetRelationName(indrel)); + update_vacuum_error_info(vacrel, &saved_err_info, VACUUM_ERRCB_PHASE_VACUUM_INDEX, - InvalidBlockNumber); + InvalidBlockNumber, InvalidOffsetNumber); /* Do bulk deletion */ - *stats = index_bulk_delete(&ivinfo, *stats, - lazy_tid_reaped, (void *) dead_tuples); - - if (IsParallelWorker()) - msg = gettext_noop("scanned index \"%s\" to remove %d row versions by parallel vacuum worker"); - else - msg = gettext_noop("scanned index \"%s\" to remove %d row versions"); + istat = index_bulk_delete(&ivinfo, istat, lazy_tid_reaped, + (void *) vacrel->dead_tuples); ereport(elevel, - (errmsg(msg, - vacrelstats->indname, - dead_tuples->num_tuples), + (errmsg("scanned index \"%s\" to remove %d row versions", + vacrel->indname, vacrel->dead_tuples->num_tuples), errdetail_internal("%s", pg_rusage_show(&ru0)))); /* Revert to the previous phase information for error traceback */ - restore_vacuum_error_info(vacrelstats, &saved_err_info); - pfree(vacrelstats->indname); - vacrelstats->indname = NULL; + restore_vacuum_error_info(vacrel, &saved_err_info); + pfree(vacrel->indname); + vacrel->indname = NULL; + + return istat; } /* - * lazy_cleanup_index() -- do post-vacuum cleanup for one index relation. + * lazy_cleanup_one_index() -- do post-vacuum cleanup for index relation. * * reltuples is the number of heap tuples and estimated_count is true * if reltuples is an estimated value. + * + * Returns bulk delete stats derived from input stats */ -static void -lazy_cleanup_index(Relation indrel, - IndexBulkDeleteResult **stats, - double reltuples, bool estimated_count, LVRelStats *vacrelstats) +static IndexBulkDeleteResult * +lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat, + double reltuples, bool estimated_count, + LVRelState *vacrel) { IndexVacuumInfo ivinfo; - const char *msg; PGRUsage ru0; LVSavedErrInfo saved_err_info; @@ -2506,7 +3116,7 @@ lazy_cleanup_index(Relation indrel, ivinfo.message_level = elevel; ivinfo.num_heap_tuples = reltuples; - ivinfo.strategy = vac_strategy; + ivinfo.strategy = vacrel->bstrategy; /* * Update error traceback information. @@ -2514,38 +3124,37 @@ lazy_cleanup_index(Relation indrel, * The index name is saved during this phase and restored immediately * after this phase. See vacuum_error_callback. */ - Assert(vacrelstats->indname == NULL); - vacrelstats->indname = pstrdup(RelationGetRelationName(indrel)); - update_vacuum_error_info(vacrelstats, &saved_err_info, + Assert(vacrel->indname == NULL); + vacrel->indname = pstrdup(RelationGetRelationName(indrel)); + update_vacuum_error_info(vacrel, &saved_err_info, VACUUM_ERRCB_PHASE_INDEX_CLEANUP, - InvalidBlockNumber); - - *stats = index_vacuum_cleanup(&ivinfo, *stats); + InvalidBlockNumber, InvalidOffsetNumber); - /* Revert back to the old phase information for error traceback */ - restore_vacuum_error_info(vacrelstats, &saved_err_info); - pfree(vacrelstats->indname); - vacrelstats->indname = NULL; + istat = index_vacuum_cleanup(&ivinfo, istat); - if (!(*stats)) - return; + if (istat) + { + ereport(elevel, + (errmsg("index \"%s\" now contains %.0f row versions in %u pages", + RelationGetRelationName(indrel), + (istat)->num_index_tuples, + (istat)->num_pages), + errdetail("%.0f index row versions were removed.\n" + "%u index pages were newly deleted.\n" + "%u index pages are currently deleted, of which %u are currently reusable.\n" + "%s.", + (istat)->tuples_removed, + (istat)->pages_newly_deleted, + (istat)->pages_deleted, (istat)->pages_free, + pg_rusage_show(&ru0)))); + } - if (IsParallelWorker()) - msg = gettext_noop("index \"%s\" now contains %.0f row versions in %u pages as reported by parallel vacuum worker"); - else - msg = gettext_noop("index \"%s\" now contains %.0f row versions in %u pages"); + /* Revert to the previous phase information for error traceback */ + restore_vacuum_error_info(vacrel, &saved_err_info); + pfree(vacrel->indname); + vacrel->indname = NULL; - ereport(elevel, - (errmsg(msg, - RelationGetRelationName(indrel), - (*stats)->num_index_tuples, - (*stats)->num_pages), - errdetail("%.0f index row versions were removed.\n" - "%u index pages have been deleted, %u are currently reusable.\n" - "%s.", - (*stats)->tuples_removed, - (*stats)->pages_deleted, (*stats)->pages_free, - pg_rusage_show(&ru0)))); + return istat; } /* @@ -2554,31 +3163,33 @@ lazy_cleanup_index(Relation indrel, * Don't even think about it unless we have a shot at releasing a goodly * number of pages. Otherwise, the time taken isn't worth it. * + * Also don't attempt it if wraparound failsafe is in effect. It's hard to + * predict how long lazy_truncate_heap will take. Don't take any chances. + * There is very little chance of truncation working out when the failsafe is + * in effect in any case. lazy_scan_prune makes the optimistic assumption + * that any LP_DEAD items it encounters will always be LP_UNUSED by the time + * we're called. + * * Also don't attempt it if we are doing early pruning/vacuuming, because a * scan which cannot find a truncated heap page cannot determine that the - * snapshot is too old to read that page. We might be able to get away with - * truncating all except one of the pages, setting its LSN to (at least) the - * maximum of the truncated range if we also treated an index leaf tuple - * pointing to a missing heap page as something to trigger the "snapshot too - * old" error, but that seems fragile and seems like it deserves its own patch - * if we consider it. + * snapshot is too old to read that page. * * This is split out so that we can test whether truncation is going to be * called for before we actually do it. If you change the logic here, be * careful to depend only on fields that lazy_scan_heap updates on-the-fly. */ static bool -should_attempt_truncation(VacuumParams *params, LVRelStats *vacrelstats) +should_attempt_truncation(LVRelState *vacrel) { BlockNumber possibly_freeable; - if (params->truncate == VACOPT_TERNARY_DISABLED) + if (!vacrel->do_rel_truncate || vacrel->failsafe_active) return false; - possibly_freeable = vacrelstats->rel_pages - vacrelstats->nonempty_pages; + possibly_freeable = vacrel->rel_pages - vacrel->nonempty_pages; if (possibly_freeable > 0 && (possibly_freeable >= REL_TRUNCATE_MINIMUM || - possibly_freeable >= vacrelstats->rel_pages / REL_TRUNCATE_FRACTION) && + possibly_freeable >= vacrel->rel_pages / REL_TRUNCATE_FRACTION) && old_snapshot_threshold < 0) return true; else @@ -2589,10 +3200,11 @@ should_attempt_truncation(VacuumParams *params, LVRelStats *vacrelstats) * lazy_truncate_heap - try to truncate off any empty pages at the end */ static void -lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats) +lazy_truncate_heap(LVRelState *vacrel) { - BlockNumber old_rel_pages = vacrelstats->rel_pages; + BlockNumber old_rel_pages = vacrel->rel_pages; BlockNumber new_rel_pages; + bool lock_waiter_detected; int lock_retry; /* Report that we are now truncating */ @@ -2615,11 +3227,11 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats) * (which is quite possible considering we already hold a lower-grade * lock). */ - vacrelstats->lock_waiter_detected = false; + lock_waiter_detected = false; lock_retry = 0; while (true) { - if (ConditionalLockRelation(onerel, AccessExclusiveLock)) + if (ConditionalLockRelation(vacrel->rel, AccessExclusiveLock)) break; /* @@ -2635,10 +3247,9 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats) * We failed to establish the lock in the specified number of * retries. This means we give up truncating. */ - vacrelstats->lock_waiter_detected = true; ereport(elevel, (errmsg("\"%s\": stopping truncate due to conflicting lock request", - vacrelstats->relname))); + vacrel->relname))); return; } @@ -2650,17 +3261,17 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats) * whilst we were vacuuming with non-exclusive lock. If so, give up; * the newly added pages presumably contain non-deletable tuples. */ - new_rel_pages = RelationGetNumberOfBlocks(onerel); + new_rel_pages = RelationGetNumberOfBlocks(vacrel->rel); if (new_rel_pages != old_rel_pages) { /* - * Note: we intentionally don't update vacrelstats->rel_pages with - * the new rel size here. If we did, it would amount to assuming - * that the new pages are empty, which is unlikely. Leaving the - * numbers alone amounts to assuming that the new pages have the - * same tuple density as existing ones, which is less unlikely. + * Note: we intentionally don't update vacrel->rel_pages with the + * new rel size here. If we did, it would amount to assuming that + * the new pages are empty, which is unlikely. Leaving the numbers + * alone amounts to assuming that the new pages have the same + * tuple density as existing ones, which is less unlikely. */ - UnlockRelation(onerel, AccessExclusiveLock); + UnlockRelation(vacrel->rel, AccessExclusiveLock); return; } @@ -2670,20 +3281,20 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats) * other backends could have added tuples to these pages whilst we * were vacuuming. */ - new_rel_pages = count_nondeletable_pages(onerel, vacrelstats); - vacrelstats->blkno = new_rel_pages; + new_rel_pages = count_nondeletable_pages(vacrel, &lock_waiter_detected); + vacrel->blkno = new_rel_pages; if (new_rel_pages >= old_rel_pages) { /* can't do anything after all */ - UnlockRelation(onerel, AccessExclusiveLock); + UnlockRelation(vacrel->rel, AccessExclusiveLock); return; } /* * Okay to truncate. */ - RelationTruncate(onerel, new_rel_pages); + RelationTruncate(vacrel->rel, new_rel_pages); /* * We can release the exclusive lock as soon as we have truncated. @@ -2692,25 +3303,24 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats) * that should happen as part of standard invalidation processing once * they acquire lock on the relation. */ - UnlockRelation(onerel, AccessExclusiveLock); + UnlockRelation(vacrel->rel, AccessExclusiveLock); /* * Update statistics. Here, it *is* correct to adjust rel_pages * without also touching reltuples, since the tuple count wasn't * changed by the truncation. */ - vacrelstats->pages_removed += old_rel_pages - new_rel_pages; - vacrelstats->rel_pages = new_rel_pages; + vacrel->pages_removed += old_rel_pages - new_rel_pages; + vacrel->rel_pages = new_rel_pages; ereport(elevel, (errmsg("\"%s\": truncated %u to %u pages", - vacrelstats->relname, + vacrel->relname, old_rel_pages, new_rel_pages), errdetail_internal("%s", pg_rusage_show(&ru0)))); old_rel_pages = new_rel_pages; - } while (new_rel_pages > vacrelstats->nonempty_pages && - vacrelstats->lock_waiter_detected); + } while (new_rel_pages > vacrel->nonempty_pages && lock_waiter_detected); } @@ -2720,7 +3330,7 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats) * Returns number of nondeletable pages (last nonempty page + 1). */ static BlockNumber -count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) +count_nondeletable_pages(LVRelState *vacrel, bool *lock_waiter_detected) { BlockNumber blkno; BlockNumber prefetchedUntil; @@ -2735,11 +3345,11 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) * unsigned.) To make the scan faster, we prefetch a few blocks at a time * in forward direction, so that OS-level readahead can kick in. */ - blkno = vacrelstats->rel_pages; + blkno = vacrel->rel_pages; StaticAssertStmt((PREFETCH_SIZE & (PREFETCH_SIZE - 1)) == 0, "prefetch size must be power of 2"); prefetchedUntil = InvalidBlockNumber; - while (blkno > vacrelstats->nonempty_pages) + while (blkno > vacrel->nonempty_pages) { Buffer buf; Page page; @@ -2766,13 +3376,13 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) if ((INSTR_TIME_GET_MICROSEC(elapsed) / 1000) >= VACUUM_TRUNCATE_LOCK_CHECK_INTERVAL) { - if (LockHasWaitersRelation(onerel, AccessExclusiveLock)) + if (LockHasWaitersRelation(vacrel->rel, AccessExclusiveLock)) { ereport(elevel, (errmsg("\"%s\": suspending truncate due to conflicting lock request", - vacrelstats->relname))); + vacrel->relname))); - vacrelstats->lock_waiter_detected = true; + *lock_waiter_detected = true; return blkno; } starttime = currenttime; @@ -2797,14 +3407,14 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) prefetchStart = blkno & ~(PREFETCH_SIZE - 1); for (pblkno = prefetchStart; pblkno <= blkno; pblkno++) { - PrefetchBuffer(onerel, MAIN_FORKNUM, pblkno); + PrefetchBuffer(vacrel->rel, MAIN_FORKNUM, pblkno); CHECK_FOR_INTERRUPTS(); } prefetchedUntil = prefetchStart; } - buf = ReadBufferExtended(onerel, MAIN_FORKNUM, blkno, - RBM_NORMAL, vac_strategy); + buf = ReadBufferExtended(vacrel->rel, MAIN_FORKNUM, blkno, RBM_NORMAL, + vacrel->bstrategy); /* In this phase we only need shared access to the buffer */ LockBuffer(buf, BUFFER_LOCK_SHARE); @@ -2829,9 +3439,8 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) /* * Note: any non-unused item should be taken as a reason to keep - * this page. We formerly thought that DEAD tuples could be - * thrown away, but that's not so, because we'd not have cleaned - * out their index entries. + * this page. Even an LP_DEAD item makes truncation unsafe, since + * we must not have cleaned out its index entries. */ if (ItemIdIsUsed(itemid)) { @@ -2852,21 +3461,21 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) * pages still are; we need not bother to look at the last known-nonempty * page. */ - return vacrelstats->nonempty_pages; + return vacrel->nonempty_pages; } /* * Return the maximum number of dead tuples we can record. */ static long -compute_max_dead_tuples(BlockNumber relblocks, bool useindex) +compute_max_dead_tuples(BlockNumber relblocks, bool hasindex) { long maxtuples; int vac_work_mem = IsAutoVacuumWorkerProcess() && autovacuum_work_mem != -1 ? autovacuum_work_mem : maintenance_work_mem; - if (useindex) + if (hasindex) { maxtuples = MAXDEADTUPLES(vac_work_mem * 1024L); maxtuples = Min(maxtuples, INT_MAX); @@ -2891,38 +3500,64 @@ compute_max_dead_tuples(BlockNumber relblocks, bool useindex) * See the comments at the head of this file for rationale. */ static void -lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks) +lazy_space_alloc(LVRelState *vacrel, int nworkers, BlockNumber nblocks) { - LVDeadTuples *dead_tuples = NULL; + LVDeadTuples *dead_tuples; long maxtuples; - maxtuples = compute_max_dead_tuples(relblocks, vacrelstats->useindex); + /* + * Initialize state for a parallel vacuum. As of now, only one worker can + * be used for an index, so we invoke parallelism only if there are at + * least two indexes on a table. + */ + if (nworkers >= 0 && vacrel->nindexes > 1 && vacrel->do_index_vacuuming) + { + /* + * Since parallel workers cannot access data in temporary tables, we + * can't perform parallel vacuum on them. + */ + if (RelationUsesLocalBuffers(vacrel->rel)) + { + /* + * Give warning only if the user explicitly tries to perform a + * parallel vacuum on the temporary table. + */ + if (nworkers > 0) + ereport(WARNING, + (errmsg("disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel", + vacrel->relname))); + } + else + vacrel->lps = begin_parallel_vacuum(vacrel, nblocks, nworkers); + + /* If parallel mode started, we're done */ + if (ParallelVacuumIsActive(vacrel)) + return; + } + + maxtuples = compute_max_dead_tuples(nblocks, vacrel->nindexes > 0); dead_tuples = (LVDeadTuples *) palloc(SizeOfDeadTuples(maxtuples)); dead_tuples->num_tuples = 0; dead_tuples->max_tuples = (int) maxtuples; - vacrelstats->dead_tuples = dead_tuples; + vacrel->dead_tuples = dead_tuples; } /* - * lazy_record_dead_tuple - remember one deletable tuple + * lazy_space_free - free space allocated in lazy_space_alloc */ static void -lazy_record_dead_tuple(LVDeadTuples *dead_tuples, ItemPointer itemptr) +lazy_space_free(LVRelState *vacrel) { + if (!ParallelVacuumIsActive(vacrel)) + return; + /* - * The array shouldn't overflow under normal behavior, but perhaps it - * could if we are given a really small maintenance_work_mem. In that - * case, just forget the last few tuples (we'll get 'em next time). + * End parallel mode before updating index statistics as we cannot write + * during parallel mode. */ - if (dead_tuples->num_tuples < dead_tuples->max_tuples) - { - dead_tuples->itemptrs[dead_tuples->num_tuples] = *itemptr; - dead_tuples->num_tuples++; - pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES, - dead_tuples->num_tuples); - } + end_parallel_vacuum(vacrel); } /* @@ -2936,8 +3571,24 @@ static bool lazy_tid_reaped(ItemPointer itemptr, void *state) { LVDeadTuples *dead_tuples = (LVDeadTuples *) state; + int64 litem, + ritem, + item; ItemPointer res; + litem = itemptr_encode(&dead_tuples->itemptrs[0]); + ritem = itemptr_encode(&dead_tuples->itemptrs[dead_tuples->num_tuples - 1]); + item = itemptr_encode(itemptr); + + /* + * Doing a simple bound check before bsearch() is useful to avoid the + * extra cost of bsearch(), especially if dead tuples on the heap are + * concentrated in a certain range. Since this function is called for + * every index tuple, it pays to be really fast. + */ + if (item < litem || item > ritem) + return false; + res = (ItemPointer) bsearch((void *) itemptr, (void *) dead_tuples->itemptrs, dead_tuples->num_tuples, @@ -2984,7 +3635,7 @@ vac_cmp_itemptr(const void *left, const void *right) * on this page is frozen. */ static bool -heap_page_is_all_visible(Relation rel, Buffer buf, +heap_page_is_all_visible(LVRelState *vacrel, Buffer buf, TransactionId *visibility_cutoff_xid, bool *all_frozen) { @@ -3009,6 +3660,11 @@ heap_page_is_all_visible(Relation rel, Buffer buf, ItemId itemid; HeapTupleData tuple; + /* + * Set the offset number so that we can display it along with any + * error that occurred while processing this tuple. + */ + vacrel->offnum = offnum; itemid = PageGetItemId(page, offnum); /* Unused or redirect line pointers are of no interest */ @@ -3032,9 +3688,9 @@ heap_page_is_all_visible(Relation rel, Buffer buf, tuple.t_data = (HeapTupleHeader) PageGetItem(page, itemid); tuple.t_len = ItemIdGetLength(itemid); - tuple.t_tableOid = RelationGetRelid(rel); + tuple.t_tableOid = RelationGetRelid(vacrel->rel); - switch (HeapTupleSatisfiesVacuum(rel, &tuple, OldestXmin, buf)) + switch (HeapTupleSatisfiesVacuum(vacrel->rel, &tuple, vacrel->OldestXmin, buf)) { case HEAPTUPLE_LIVE: { @@ -3053,7 +3709,7 @@ heap_page_is_all_visible(Relation rel, Buffer buf, * that everyone sees it as committed? */ xmin = HeapTupleHeaderGetXmin(tuple.t_data); - if (!TransactionIdPrecedes(xmin, OldestXmin)) + if (!TransactionIdPrecedes(xmin, vacrel->OldestXmin)) { all_visible = false; *all_frozen = false; @@ -3086,6 +3742,9 @@ heap_page_is_all_visible(Relation rel, Buffer buf, } } /* scan along page */ + /* Clear the offset information once we have processed the given page. */ + vacrel->offnum = InvalidOffsetNumber; + return all_visible; } @@ -3103,14 +3762,13 @@ heap_page_is_all_visible(Relation rel, Buffer buf, * vacuum. */ static int -compute_parallel_vacuum_workers(Relation *Irel, int nindexes, int nrequested, +compute_parallel_vacuum_workers(LVRelState *vacrel, int nrequested, bool *can_parallel_vacuum) { int nindexes_parallel = 0; int nindexes_parallel_bulkdel = 0; int nindexes_parallel_cleanup = 0; int parallel_workers; - int i; /* * We don't allow performing parallel operation in standalone backend or @@ -3122,15 +3780,16 @@ compute_parallel_vacuum_workers(Relation *Irel, int nindexes, int nrequested, /* * Compute the number of indexes that can participate in parallel vacuum. */ - for (i = 0; i < nindexes; i++) + for (int idx = 0; idx < vacrel->nindexes; idx++) { - uint8 vacoptions = Irel[i]->rd_indam->amparallelvacuumoptions; + Relation indrel = vacrel->indrels[idx]; + uint8 vacoptions = indrel->rd_indam->amparallelvacuumoptions; if (vacoptions == VACUUM_OPTION_NO_PARALLEL || - RelationGetNumberOfBlocks(Irel[i]) < min_parallel_index_scan_size) + RelationGetNumberOfBlocks(indrel) < min_parallel_index_scan_size) continue; - can_parallel_vacuum[i] = true; + can_parallel_vacuum[idx] = true; if ((vacoptions & VACUUM_OPTION_PARALLEL_BULKDEL) != 0) nindexes_parallel_bulkdel++; @@ -3159,59 +3818,36 @@ compute_parallel_vacuum_workers(Relation *Irel, int nindexes, int nrequested, return parallel_workers; } -/* - * Initialize variables for shared index statistics, set NULL bitmap and the - * size of stats for each index. - */ -static void -prepare_index_statistics(LVShared *lvshared, bool *can_parallel_vacuum, - int nindexes) -{ - int i; - - /* Currently, we don't support parallel vacuum for autovacuum */ - Assert(!IsAutoVacuumWorkerProcess()); - - /* Set NULL for all indexes */ - memset(lvshared->bitmap, 0x00, BITMAPLEN(nindexes)); - - for (i = 0; i < nindexes; i++) - { - if (!can_parallel_vacuum[i]) - continue; - - /* Set NOT NULL as this index does support parallelism */ - lvshared->bitmap[i >> 3] |= 1 << (i & 0x07); - } -} - /* * Update index statistics in pg_class if the statistics are accurate. */ static void -update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats, - int nindexes) +update_index_statistics(LVRelState *vacrel) { - int i; + Relation *indrels = vacrel->indrels; + int nindexes = vacrel->nindexes; + IndexBulkDeleteResult **indstats = vacrel->indstats; Assert(!IsInParallelMode()); - for (i = 0; i < nindexes; i++) + for (int idx = 0; idx < nindexes; idx++) { - if (stats[i] == NULL || stats[i]->estimated_count) + Relation indrel = indrels[idx]; + IndexBulkDeleteResult *istat = indstats[idx]; + + if (istat == NULL || istat->estimated_count) continue; /* Update index statistics */ - vac_update_relstats(Irel[i], - stats[i]->num_pages, - stats[i]->num_index_tuples, + vac_update_relstats(indrel, + istat->num_pages, + istat->num_index_tuples, 0, false, InvalidTransactionId, InvalidMultiXactId, false, - true /* isvacuum */); - pfree(stats[i]); + true); } } @@ -3221,10 +3857,12 @@ update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats, * create a parallel context, and then initialize the DSM segment. */ static LVParallelState * -begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, - BlockNumber nblocks, int nindexes, int nrequested) +begin_parallel_vacuum(LVRelState *vacrel, BlockNumber nblocks, + int nrequested) { LVParallelState *lps = NULL; + Relation *indrels = vacrel->indrels; + int nindexes = vacrel->nindexes; ParallelContext *pcxt; LVShared *shared; LVDeadTuples *dead_tuples; @@ -3232,13 +3870,11 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, WalUsage *wal_usage; bool *can_parallel_vacuum; long maxtuples; - char *sharedquery; Size est_shared; Size est_deadtuples; int nindexes_mwm = 0; int parallel_workers = 0; int querylen; - int i; /* * A parallel vacuum must be requested and there must be indexes on the @@ -3251,7 +3887,7 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, * Compute the number of parallel vacuum workers to launch */ can_parallel_vacuum = (bool *) palloc0(sizeof(bool) * nindexes); - parallel_workers = compute_parallel_vacuum_workers(Irel, nindexes, + parallel_workers = compute_parallel_vacuum_workers(vacrel, nrequested, can_parallel_vacuum); @@ -3272,9 +3908,10 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, /* Estimate size for shared information -- PARALLEL_VACUUM_KEY_SHARED */ est_shared = MAXALIGN(add_size(SizeOfLVShared, BITMAPLEN(nindexes))); - for (i = 0; i < nindexes; i++) + for (int idx = 0; idx < nindexes; idx++) { - uint8 vacoptions = Irel[i]->rd_indam->amparallelvacuumoptions; + Relation indrel = indrels[idx]; + uint8 vacoptions = indrel->rd_indam->amparallelvacuumoptions; /* * Cleanup option should be either disabled, always performing in @@ -3285,10 +3922,10 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, Assert(vacoptions <= VACUUM_OPTION_MAX_VALID_VALUE); /* Skip indexes that don't participate in parallel vacuum */ - if (!can_parallel_vacuum[i]) + if (!can_parallel_vacuum[idx]) continue; - if (Irel[i]->rd_indam->amusemaintenanceworkmem) + if (indrel->rd_indam->amusemaintenanceworkmem) nindexes_mwm++; est_shared = add_size(est_shared, sizeof(LVSharedIndStats)); @@ -3329,16 +3966,21 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, shm_toc_estimate_keys(&pcxt->estimator, 1); /* Finally, estimate PARALLEL_VACUUM_KEY_QUERY_TEXT space */ - querylen = strlen(debug_query_string); - shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); - shm_toc_estimate_keys(&pcxt->estimator, 1); + if (debug_query_string) + { + querylen = strlen(debug_query_string); + shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); + shm_toc_estimate_keys(&pcxt->estimator, 1); + } + else + querylen = 0; /* keep compiler quiet */ InitializeParallelDSM(pcxt); /* Prepare shared information */ shared = (LVShared *) shm_toc_allocate(pcxt->toc, est_shared); MemSet(shared, 0, est_shared); - shared->relid = relid; + shared->relid = RelationGetRelid(vacrel->rel); shared->elevel = elevel; shared->maintenance_work_mem_worker = (nindexes_mwm > 0) ? @@ -3349,7 +3991,20 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, pg_atomic_init_u32(&(shared->active_nworkers), 0); pg_atomic_init_u32(&(shared->idx), 0); shared->offset = MAXALIGN(add_size(SizeOfLVShared, BITMAPLEN(nindexes))); - prepare_index_statistics(shared, can_parallel_vacuum, nindexes); + + /* + * Initialize variables for shared index statistics, set NULL bitmap and + * the size of stats for each index. + */ + memset(shared->bitmap, 0x00, BITMAPLEN(nindexes)); + for (int idx = 0; idx < nindexes; idx++) + { + if (!can_parallel_vacuum[idx]) + continue; + + /* Set NOT NULL as this index does support parallelism */ + shared->bitmap[idx >> 3] |= 1 << (idx & 0x07); + } shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_SHARED, shared); lps->lvshared = shared; @@ -3360,7 +4015,7 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, dead_tuples->num_tuples = 0; MemSet(dead_tuples->itemptrs, 0, sizeof(ItemPointerData) * maxtuples); shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_DEAD_TUPLES, dead_tuples); - vacrelstats->dead_tuples = dead_tuples; + vacrel->dead_tuples = dead_tuples; /* * Allocate space for each worker's BufferUsage and WalUsage; no need to @@ -3376,10 +4031,16 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, lps->wal_usage = wal_usage; /* Store query string for workers */ - sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); - memcpy(sharedquery, debug_query_string, querylen + 1); - sharedquery[querylen] = '\0'; - shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_QUERY_TEXT, sharedquery); + if (debug_query_string) + { + char *sharedquery; + + sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); + memcpy(sharedquery, debug_query_string, querylen + 1); + sharedquery[querylen] = '\0'; + shm_toc_insert(pcxt->toc, + PARALLEL_VACUUM_KEY_QUERY_TEXT, sharedquery); + } pfree(can_parallel_vacuum); return lps; @@ -3395,32 +4056,35 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, * context, but that won't be safe (see ExitParallelMode). */ static void -end_parallel_vacuum(IndexBulkDeleteResult **stats, LVParallelState *lps, - int nindexes) +end_parallel_vacuum(LVRelState *vacrel) { - int i; + IndexBulkDeleteResult **indstats = vacrel->indstats; + LVParallelState *lps = vacrel->lps; + int nindexes = vacrel->nindexes; Assert(!IsParallelWorker()); /* Copy the updated statistics */ - for (i = 0; i < nindexes; i++) + for (int idx = 0; idx < nindexes; idx++) { - LVSharedIndStats *indstats = get_indstats(lps->lvshared, i); + LVSharedIndStats *shared_istat; + + shared_istat = parallel_stats_for_idx(lps->lvshared, idx); /* * Skip unused slot. The statistics of this index are already stored * in local memory. */ - if (indstats == NULL) + if (shared_istat == NULL) continue; - if (indstats->updated) + if (shared_istat->updated) { - stats[i] = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); - memcpy(stats[i], &(indstats->stats), sizeof(IndexBulkDeleteResult)); + indstats[idx] = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + memcpy(indstats[idx], &(shared_istat->istat), sizeof(IndexBulkDeleteResult)); } else - stats[i] = NULL; + indstats[idx] = NULL; } DestroyParallelContext(lps->pcxt); @@ -3428,23 +4092,24 @@ end_parallel_vacuum(IndexBulkDeleteResult **stats, LVParallelState *lps, /* Deactivate parallel vacuum */ pfree(lps); - lps = NULL; + vacrel->lps = NULL; } -/* Return the Nth index statistics or NULL */ +/* + * Return shared memory statistics for index at offset 'getidx', if any + */ static LVSharedIndStats * -get_indstats(LVShared *lvshared, int n) +parallel_stats_for_idx(LVShared *lvshared, int getidx) { - int i; char *p; - if (IndStatsIsNull(lvshared, n)) + if (IndStatsIsNull(lvshared, getidx)) return NULL; p = (char *) GetSharedIndStats(lvshared); - for (i = 0; i < n; i++) + for (int idx = 0; idx < getidx; idx++) { - if (IndStatsIsNull(lvshared, i)) + if (IndStatsIsNull(lvshared, idx)) continue; p += sizeof(LVSharedIndStats); @@ -3454,11 +4119,11 @@ get_indstats(LVShared *lvshared, int n) } /* - * Returns true, if the given index can't participate in parallel index vacuum - * or parallel index cleanup, false, otherwise. + * Returns false, if the given index can't participate in parallel index + * vacuum or parallel index cleanup */ static bool -skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared) +parallel_processing_is_safe(Relation indrel, LVShared *lvshared) { uint8 vacoptions = indrel->rd_indam->amparallelvacuumoptions; @@ -3480,15 +4145,15 @@ skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared) */ if (!lvshared->first_time && ((vacoptions & VACUUM_OPTION_PARALLEL_COND_CLEANUP) != 0)) - return true; + return false; } else if ((vacoptions & VACUUM_OPTION_PARALLEL_BULKDEL) == 0) { /* Skip if the index does not support parallel bulk deletion */ - return true; + return false; } - return false; + return true; } /* @@ -3500,7 +4165,7 @@ skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared) void parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) { - Relation onerel; + Relation rel; Relation *indrels; LVShared *lvshared; LVDeadTuples *dead_tuples; @@ -3508,20 +4173,20 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) WalUsage *wal_usage; int nindexes; char *sharedquery; - IndexBulkDeleteResult **stats; - LVRelStats vacrelstats; + LVRelState vacrel; ErrorContextCallback errcallback; lvshared = (LVShared *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_SHARED, false); elevel = lvshared->elevel; - ereport(DEBUG1, - (errmsg("starting parallel vacuum worker for %s", - lvshared->for_cleanup ? "cleanup" : "bulk delete"))); + if (lvshared->for_cleanup) + elog(DEBUG1, "starting parallel vacuum worker for cleanup"); + else + elog(DEBUG1, "starting parallel vacuum worker for bulk delete"); /* Set debug_query_string for individual workers */ - sharedquery = shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_QUERY_TEXT, false); + sharedquery = shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_QUERY_TEXT, true); debug_query_string = sharedquery; pgstat_report_activity(STATE_RUNNING, debug_query_string); @@ -3530,13 +4195,13 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) * okay because the lock mode does not conflict among the parallel * workers. */ - onerel = table_open(lvshared->relid, ShareUpdateExclusiveLock); + rel = table_open(lvshared->relid, ShareUpdateExclusiveLock); /* * Open all indexes. indrels are sorted in order by OID, which should be * matched to the leader's one. */ - vac_open_indexes(onerel, RowExclusiveLock, &nindexes, &indrels); + vac_open_indexes(rel, RowExclusiveLock, &nindexes, &indrels); Assert(nindexes > 0); /* Set dead tuple space */ @@ -3554,24 +4219,29 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) VacuumSharedCostBalance = &(lvshared->cost_balance); VacuumActiveNWorkers = &(lvshared->active_nworkers); - stats = (IndexBulkDeleteResult **) + vacrel.rel = rel; + vacrel.indrels = indrels; + vacrel.nindexes = nindexes; + /* Each parallel VACUUM worker gets its own access strategy */ + vacrel.bstrategy = GetAccessStrategy(BAS_VACUUM); + vacrel.indstats = (IndexBulkDeleteResult **) palloc0(nindexes * sizeof(IndexBulkDeleteResult *)); if (lvshared->maintenance_work_mem_worker > 0) maintenance_work_mem = lvshared->maintenance_work_mem_worker; /* - * Initialize vacrelstats for use as error callback arg by parallel - * worker. + * Initialize vacrel for use as error callback arg by parallel worker. */ - vacrelstats.relnamespace = get_namespace_name(RelationGetNamespace(onerel)); - vacrelstats.relname = pstrdup(RelationGetRelationName(onerel)); - vacrelstats.indname = NULL; - vacrelstats.phase = VACUUM_ERRCB_PHASE_UNKNOWN; /* Not yet processing */ + vacrel.relnamespace = get_namespace_name(RelationGetNamespace(rel)); + vacrel.relname = pstrdup(RelationGetRelationName(rel)); + vacrel.indname = NULL; + vacrel.phase = VACUUM_ERRCB_PHASE_UNKNOWN; /* Not yet processing */ + vacrel.dead_tuples = dead_tuples; /* Setup error traceback support for ereport() */ errcallback.callback = vacuum_error_callback; - errcallback.arg = &vacrelstats; + errcallback.arg = &vacrel; errcallback.previous = error_context_stack; error_context_stack = &errcallback; @@ -3579,8 +4249,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) InstrStartParallelQuery(); /* Process indexes to perform vacuum/cleanup */ - parallel_vacuum_index(indrels, stats, lvshared, dead_tuples, nindexes, - &vacrelstats); + do_parallel_processing(&vacrel, lvshared); /* Report buffer/WAL usage during parallel execution */ buffer_usage = shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_BUFFER_USAGE, false); @@ -3592,8 +4261,9 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) error_context_stack = errcallback.previous; vac_close_indexes(nindexes, indrels, RowExclusiveLock); - table_close(onerel, ShareUpdateExclusiveLock); - pfree(stats); + table_close(rel, ShareUpdateExclusiveLock); + FreeAccessStrategy(vacrel.bstrategy); + pfree(vacrel.indstats); } /* @@ -3602,20 +4272,38 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) static void vacuum_error_callback(void *arg) { - LVRelStats *errinfo = arg; + LVRelState *errinfo = arg; switch (errinfo->phase) { case VACUUM_ERRCB_PHASE_SCAN_HEAP: if (BlockNumberIsValid(errinfo->blkno)) - errcontext("while scanning block %u of relation \"%s.%s\"", - errinfo->blkno, errinfo->relnamespace, errinfo->relname); + { + if (OffsetNumberIsValid(errinfo->offnum)) + errcontext("while scanning block %u and offset %u of relation \"%s.%s\"", + errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname); + else + errcontext("while scanning block %u of relation \"%s.%s\"", + errinfo->blkno, errinfo->relnamespace, errinfo->relname); + } + else + errcontext("while scanning relation \"%s.%s\"", + errinfo->relnamespace, errinfo->relname); break; case VACUUM_ERRCB_PHASE_VACUUM_HEAP: if (BlockNumberIsValid(errinfo->blkno)) - errcontext("while vacuuming block %u of relation \"%s.%s\"", - errinfo->blkno, errinfo->relnamespace, errinfo->relname); + { + if (OffsetNumberIsValid(errinfo->offnum)) + errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"", + errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname); + else + errcontext("while vacuuming block %u of relation \"%s.%s\"", + errinfo->blkno, errinfo->relnamespace, errinfo->relname); + } + else + errcontext("while vacuuming relation \"%s.%s\"", + errinfo->relnamespace, errinfo->relname); break; case VACUUM_ERRCB_PHASE_VACUUM_INDEX: @@ -3646,25 +4334,29 @@ vacuum_error_callback(void *arg) * the current information which can be later restored via restore_vacuum_error_info. */ static void -update_vacuum_error_info(LVRelStats *errinfo, LVSavedErrInfo *saved_err_info, int phase, - BlockNumber blkno) +update_vacuum_error_info(LVRelState *vacrel, LVSavedErrInfo *saved_vacrel, + int phase, BlockNumber blkno, OffsetNumber offnum) { - if (saved_err_info) + if (saved_vacrel) { - saved_err_info->blkno = errinfo->blkno; - saved_err_info->phase = errinfo->phase; + saved_vacrel->offnum = vacrel->offnum; + saved_vacrel->blkno = vacrel->blkno; + saved_vacrel->phase = vacrel->phase; } - errinfo->blkno = blkno; - errinfo->phase = phase; + vacrel->blkno = blkno; + vacrel->offnum = offnum; + vacrel->phase = phase; } /* * Restores the vacuum information saved via a prior call to update_vacuum_error_info. */ static void -restore_vacuum_error_info(LVRelStats *errinfo, const LVSavedErrInfo *saved_err_info) +restore_vacuum_error_info(LVRelState *vacrel, + const LVSavedErrInfo *saved_vacrel) { - errinfo->blkno = saved_err_info->blkno; - errinfo->phase = saved_err_info->phase; + vacrel->blkno = saved_vacrel->blkno; + vacrel->offnum = saved_vacrel->offnum; + vacrel->phase = saved_vacrel->phase; } diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c index b1072183bcd6..e198df65d827 100644 --- a/src/backend/access/heap/visibilitymap.c +++ b/src/backend/access/heap/visibilitymap.c @@ -3,7 +3,7 @@ * visibilitymap.c * bitmap for tracking visibility of heap tuples * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/index/amapi.c b/src/backend/access/index/amapi.c index 4e3d7b030ebd..d30bc435146d 100644 --- a/src/backend/access/index/amapi.c +++ b/src/backend/access/index/amapi.c @@ -3,7 +3,7 @@ * amapi.c * Support routines for API for Postgres index access methods. * - * Copyright (c) 2015-2020, PostgreSQL Global Development Group + * Copyright (c) 2015-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/access/index/amvalidate.c b/src/backend/access/index/amvalidate.c index b58c34aa5f2f..9dd0ae663ba1 100644 --- a/src/backend/access/index/amvalidate.c +++ b/src/backend/access/index/amvalidate.c @@ -4,7 +4,7 @@ * Support routines for index access methods' amvalidate and * amadjustmembers functions. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index e3164e674a7b..b93288a6fe61 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -3,7 +3,7 @@ * genam.c * general index access method routines * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -276,11 +276,18 @@ BuildIndexValueDescription(Relation indexRelation, /* * Get the latestRemovedXid from the table entries pointed at by the index - * tuples being deleted. - * - * Note: index access methods that don't consistently use the standard - * IndexTuple + heap TID item pointer representation will need to provide - * their own version of this function. + * tuples being deleted using an AM-generic approach. + * + * This is a table_index_delete_tuples() shim used by index AMs that have + * simple requirements. These callers only need to consult the tableam to get + * a latestRemovedXid value, and only expect to delete tuples that are already + * known deletable. When a latestRemovedXid value isn't needed in index AM's + * deletion WAL record, it is safe for it to skip calling here entirely. + * + * We assume that caller index AM uses the standard IndexTuple representation, + * with table TIDs stored in the t_tid field. We also expect (and assert) + * that the line pointers on page for 'itemnos' offsets are already marked + * LP_DEAD. */ TransactionId index_compute_xid_horizon_for_tuples(Relation irel, @@ -289,12 +296,19 @@ index_compute_xid_horizon_for_tuples(Relation irel, OffsetNumber *itemnos, int nitems) { - ItemPointerData *ttids = - (ItemPointerData *) palloc(sizeof(ItemPointerData) * nitems); + TM_IndexDeleteOp delstate; TransactionId latestRemovedXid = InvalidTransactionId; Page ipage = BufferGetPage(ibuf); IndexTuple itup; + Assert(nitems > 0); + + delstate.bottomup = false; + delstate.bottomupfreespace = 0; + delstate.ndeltids = 0; + delstate.deltids = palloc(nitems * sizeof(TM_IndexDelete)); + delstate.status = palloc(nitems * sizeof(TM_IndexStatus)); + /* identify what the index tuples about to be deleted point to */ for (int i = 0; i < nitems; i++) { @@ -303,14 +317,26 @@ index_compute_xid_horizon_for_tuples(Relation irel, iitemid = PageGetItemId(ipage, itemnos[i]); itup = (IndexTuple) PageGetItem(ipage, iitemid); - ItemPointerCopy(&itup->t_tid, &ttids[i]); + Assert(ItemIdIsDead(iitemid)); + + ItemPointerCopy(&itup->t_tid, &delstate.deltids[i].tid); + delstate.deltids[i].id = delstate.ndeltids; + delstate.status[i].idxoffnum = InvalidOffsetNumber; /* unused */ + delstate.status[i].knowndeletable = true; /* LP_DEAD-marked */ + delstate.status[i].promising = false; /* unused */ + delstate.status[i].freespace = 0; /* unused */ + + delstate.ndeltids++; } /* determine the actual xid horizon */ - latestRemovedXid = - table_compute_xid_horizon_for_tuples(hrel, ttids, nitems); + latestRemovedXid = table_index_delete_tuples(hrel, &delstate); + + /* assert tableam agrees that all items are deletable */ + Assert(delstate.ndeltids == nitems); - pfree(ttids); + pfree(delstate.deltids); + pfree(delstate.status); return latestRemovedXid; } @@ -586,8 +612,8 @@ systable_endscan(SysScanDesc sysscan) UnregisterSnapshot(sysscan->snapshot); /* - * Reset the bsysscan flag at the end of the systable scan. See - * detailed comments in xact.c where these variables are declared. + * Reset the bsysscan flag at the end of the systable scan. See detailed + * comments in xact.c where these variables are declared. */ if (TransactionIdIsValid(CheckXidAlive)) bsysscan = false; @@ -607,7 +633,7 @@ systable_endscan(SysScanDesc sysscan) * Currently we do not support non-index-based scans here. (In principle * we could do a heapscan and sort, but the uses are in places that * probably don't need to still work with corrupted catalog indexes.) - * For the moment, therefore, these functions are merely the thinnest of + * For the moment, therefore, these functions are merely the thinest of * wrappers around index_beginscan/index_getnext_slot. The main reason for * their existence is to centralize possible future support of lossy operators * in catalog scans. diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index e78dbf8df6f1..1007cc336569 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -3,7 +3,7 @@ * indexam.c * general index access method routines * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -96,14 +96,14 @@ #define CHECK_REL_PROCEDURE(pname) \ do { \ if (indexRelation->rd_indam->pname == NULL) \ - elog(ERROR, "function %s is not defined for index %s", \ + elog(ERROR, "function \"%s\" is not defined for index \"%s\"", \ CppAsString(pname), RelationGetRelationName(indexRelation)); \ } while(0) #define CHECK_SCAN_PROCEDURE(pname) \ do { \ if (scan->indexRelation->rd_indam->pname == NULL) \ - elog(ERROR, "function %s is not defined for index %s", \ + elog(ERROR, "function \"%s\" is not defined for index \"%s\"", \ CppAsString(pname), RelationGetRelationName(scan->indexRelation)); \ } while(0) @@ -182,6 +182,7 @@ index_insert(Relation indexRelation, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { RELATION_CHECKS; @@ -194,7 +195,8 @@ index_insert(Relation indexRelation, return indexRelation->rd_indam->aminsert(indexRelation, values, isnull, heap_t_ctid, heapRelation, - checkUnique, indexInfo); + checkUnique, indexUnchanged, + indexInfo); } /* @@ -716,7 +718,7 @@ index_getbitmap(IndexScanDesc scan, Node **bitmapP) */ IndexBulkDeleteResult * index_bulk_delete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, + IndexBulkDeleteResult *istat, IndexBulkDeleteCallback callback, void *callback_state) { @@ -725,7 +727,7 @@ index_bulk_delete(IndexVacuumInfo *info, RELATION_CHECKS; CHECK_REL_PROCEDURE(ambulkdelete); - return indexRelation->rd_indam->ambulkdelete(info, stats, + return indexRelation->rd_indam->ambulkdelete(info, istat, callback, callback_state); } @@ -737,14 +739,14 @@ index_bulk_delete(IndexVacuumInfo *info, */ IndexBulkDeleteResult * index_vacuum_cleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats) + IndexBulkDeleteResult *istat) { Relation indexRelation = info->index; RELATION_CHECKS; CHECK_REL_PROCEDURE(amvacuumcleanup); - return indexRelation->rd_indam->amvacuumcleanup(info, stats); + return indexRelation->rd_indam->amvacuumcleanup(info, istat); } /* ---------------- diff --git a/src/backend/access/nbtree/README b/src/backend/access/nbtree/README index 9692e4cdf644..bfe33b6b431a 100644 --- a/src/backend/access/nbtree/README +++ b/src/backend/access/nbtree/README @@ -82,8 +82,8 @@ page.) A backwards scan has one additional bit of complexity: after following the left-link we must account for the possibility that the left sibling page got split before we could read it. So, we have to move right until we find a page whose right-link matches the page we -came from. (Actually, it's even harder than that; see deletion discussion -below.) +came from. (Actually, it's even harder than that; see page deletion +discussion below.) Page read locks are held only for as long as a scan is examining a page. To minimize lock/unlock traffic, an index scan always searches a leaf page @@ -163,16 +163,16 @@ pages (though suffix truncation is also considered). Note we must include the incoming item in this calculation, otherwise it is possible to find that the incoming item doesn't fit on the split page where it needs to go! -The Deletion Algorithm ----------------------- +Deleting index tuples during VACUUM +----------------------------------- Before deleting a leaf item, we get a super-exclusive lock on the target page, so that no other backend has a pin on the page when the deletion starts. This is not necessary for correctness in terms of the btree index operations themselves; as explained above, index scans logically stop "between" pages and so can't lose their place. The reason we do it is to -provide an interlock between non-full VACUUM and indexscans. Since VACUUM -deletes index entries before reclaiming heap tuple line pointers, the +provide an interlock between VACUUM and indexscans. Since VACUUM deletes +index entries before reclaiming heap tuple line pointers, the super-exclusive lock guarantees that VACUUM can't reclaim for re-use a line pointer that an indexscanning process might be about to visit. This guarantee works only for simple indexscans that visit the heap in sync @@ -202,7 +202,8 @@ from the page have been processed. This guarantees that the btbulkdelete call cannot return while any indexscan is still holding a copy of a deleted index tuple if the scan could be confused by that. Note that this requirement does not say that btbulkdelete must visit the pages in any -particular order. (See also on-the-fly deletion, below.) +particular order. (See also simple deletion and bottom-up deletion, +below.) There is no such interlocking for deletion of items in internal pages, since backends keep no lock nor pin on a page they have descended past. @@ -213,8 +214,36 @@ page). Since we hold a lock on the lower page (per L&Y) until we have re-found the parent item that links to it, we can be assured that the parent item does still exist and can't have been deleted. -Page Deletion -------------- +VACUUM's linear scan, concurrent page splits +-------------------------------------------- + +VACUUM accesses the index by doing a linear scan to search for deletable +TIDs, while considering the possibility of deleting empty pages in +passing. This is in physical/block order, not logical/keyspace order. +The tricky part of this is avoiding missing any deletable tuples in the +presence of concurrent page splits: a page split could easily move some +tuples from a page not yet passed over by the sequential scan to a +lower-numbered page already passed over. + +To implement this, we provide a "vacuum cycle ID" mechanism that makes it +possible to determine whether a page has been split since the current +btbulkdelete cycle started. If btbulkdelete finds a page that has been +split since it started, and has a right-link pointing to a lower page +number, then it temporarily suspends its sequential scan and visits that +page instead. It must continue to follow right-links and vacuum dead +tuples until reaching a page that either hasn't been split since +btbulkdelete started, or is above the location of the outer sequential +scan. Then it can resume the sequential scan. This ensures that all +tuples are visited. It may be that some tuples are visited twice, but +that has no worse effect than an inaccurate index tuple count (and we +can't guarantee an accurate count anyway in the face of concurrent +activity). Note that this still works if the has-been-recently-split test +has a small probability of false positives, so long as it never gives a +false negative. This makes it possible to implement the test with a small +counter value stored on each index page. + +Deleting entire pages during VACUUM +----------------------------------- We consider deleting an entire page from the btree only when it's become completely empty of items. (Merging partly-full pages would allow better @@ -300,19 +329,26 @@ down in the chain. This is repeated until there are no internal pages left in the chain. Finally, the half-dead leaf page itself is unlinked from its siblings. -A deleted page cannot be reclaimed immediately, since there may be other +A deleted page cannot be recycled immediately, since there may be other processes waiting to reference it (ie, search processes that just left the parent, or scans moving right or left from one of the siblings). These -processes must observe that the page is marked dead and recover -accordingly. Searches and forward scans simply follow the right-link -until they find a non-dead page --- this will be where the deleted page's -key-space moved to. +processes must be able to observe a deleted page for some time after the +deletion operation, in order to be able to at least recover from it (they +recover by moving right, as with concurrent page splits). Searchers never +have to worry about concurrent page recycling. + +See "Placing deleted pages in the FSM" section below for a description of +when and how deleted pages become safe for VACUUM to make recyclable. + +Page deletion and backwards scans +--------------------------------- Moving left in a backward scan is complicated because we must consider the possibility that the left sibling was just split (meaning we must find the rightmost page derived from the left sibling), plus the possibility that the page we were just on has now been deleted and hence isn't in the sibling chain at all anymore. So the move-left algorithm becomes: + 0. Remember the page we are on as the "original page". 1. Follow the original page's left-link (we're done if this is zero). 2. If the current page is live and its right-link matches the "original @@ -329,31 +365,15 @@ sibling chain at all anymore. So the move-left algorithm becomes: current left-link). If it is dead, move right until a non-dead page is found (there must be one, since rightmost pages are never deleted), mark that as the new "original page", and return to step 1. + This algorithm is correct because the live page found by step 4 will have the same left keyspace boundary as the page we started from. Therefore, when we ultimately exit, it must be on a page whose right keyspace boundary matches the left boundary of where we started --- which is what we need to be sure we don't miss or re-scan any items. -A deleted page can only be reclaimed once there is no scan or search that -has a reference to it; until then, it must stay in place with its -right-link undisturbed. We implement this by waiting until all active -snapshots and registered snapshots as of the deletion are gone; which is -overly strong, but is simple to implement within Postgres. When marked -dead, a deleted page is labeled with the next-transaction counter value. -VACUUM can reclaim the page for re-use when this transaction number is -guaranteed to be "visible to everyone". As collateral damage, this -implementation also waits for running XIDs with no snapshots and for -snapshots taken until the next transaction to allocate an XID commits. - -Reclaiming a page doesn't actually change its state on disk --- we simply -record it in the shared-memory free space map, from which it will be -handed out the next time a new page is needed for a page split. The -deleted page's contents will be overwritten by the split operation. -(Note: if we find a deleted page with an extremely old transaction -number, it'd be worthwhile to re-mark it with FrozenTransactionId so that -a later xid wraparound can't cause us to think the page is unreclaimable. -But in more normal situations this would be a waste of a disk write.) +Page deletion and tree height +----------------------------- Because we never delete the rightmost page of any level (and in particular never delete the root), it's impossible for the height of the tree to @@ -373,32 +393,65 @@ as part of the atomic update for the delete (either way, the metapage has to be the last page locked in the update to avoid deadlock risks). This avoids race conditions if two such operations are executing concurrently. -VACUUM needs to do a linear scan of an index to search for deleted pages -that can be reclaimed because they are older than all open transactions. -For efficiency's sake, we'd like to use the same linear scan to search for -deletable tuples. Before Postgres 8.2, btbulkdelete scanned the leaf pages -in index order, but it is possible to visit them in physical order instead. -The tricky part of this is to avoid missing any deletable tuples in the -presence of concurrent page splits: a page split could easily move some -tuples from a page not yet passed over by the sequential scan to a -lower-numbered page already passed over. (This wasn't a concern for the -index-order scan, because splits always split right.) To implement this, -we provide a "vacuum cycle ID" mechanism that makes it possible to -determine whether a page has been split since the current btbulkdelete -cycle started. If btbulkdelete finds a page that has been split since -it started, and has a right-link pointing to a lower page number, then -it temporarily suspends its sequential scan and visits that page instead. -It must continue to follow right-links and vacuum dead tuples until -reaching a page that either hasn't been split since btbulkdelete started, -or is above the location of the outer sequential scan. Then it can resume -the sequential scan. This ensures that all tuples are visited. It may be -that some tuples are visited twice, but that has no worse effect than an -inaccurate index tuple count (and we can't guarantee an accurate count -anyway in the face of concurrent activity). Note that this still works -if the has-been-recently-split test has a small probability of false -positives, so long as it never gives a false negative. This makes it -possible to implement the test with a small counter value stored on each -index page. +Placing deleted pages in the FSM +-------------------------------- + +Recycling a page is decoupled from page deletion. A deleted page can only +be put in the FSM to be recycled once there is no possible scan or search +that has a reference to it; until then, it must stay in place with its +sibling links undisturbed, as a tombstone that allows concurrent searches +to detect and then recover from concurrent deletions (which are rather +like concurrent page splits to searchers). This design is an +implementation of what Lanin and Shasha call "the drain technique". + +We implement the technique by waiting until all active snapshots and +registered snapshots as of the page deletion are gone; which is overly +strong, but is simple to implement within Postgres. When marked fully +dead, a deleted page is labeled with the next-transaction counter value. +VACUUM can reclaim the page for re-use when the stored XID is guaranteed +to be "visible to everyone". As collateral damage, we wait for snapshots +taken until the next transaction to allocate an XID commits. We also wait +for running XIDs with no snapshots. + +Prior to PostgreSQL 14, VACUUM would only place _old_ deleted pages that +it encounters during its linear scan (pages deleted by a previous VACUUM +operation) in the FSM. Newly deleted pages were never placed in the FSM, +because that was assumed to _always_ be unsafe. That assumption was +unnecessarily pessimistic in practice, though -- it often doesn't take +very long for newly deleted pages to become safe to place in the FSM. +There is no truly principled way to predict when deleted pages will become +safe to place in the FSM for recycling -- it might become safe almost +immediately (long before the current VACUUM completes), or it might not +even be safe by the time the next VACUUM takes place. Recycle safety is +purely a question of maintaining the consistency (or at least the apparent +consistency) of a physical data structure. The state within the backend +running VACUUM is simply not relevant. + +PostgreSQL 14 added the ability for VACUUM to consider if it's possible to +recycle newly deleted pages at the end of the full index scan where the +page deletion took place. It is convenient to check if it's safe at that +point. This does require that VACUUM keep around a little bookkeeping +information about newly deleted pages, but that's very cheap. Using +in-memory state for this avoids the need to revisit newly deleted pages a +second time later on -- we can just use safexid values from the local +bookkeeping state to determine recycle safety in a deferred fashion. + +The need for additional FSM indirection after a page deletion operation +takes place is a natural consequence of the highly permissive rules for +index scans with Lehman and Yao's design. In general an index scan +doesn't have to hold a lock or even a pin on any page when it descends the +tree (nothing that you'd usually think of as an interlock is held "between +levels"). At the same time, index scans cannot be allowed to land on a +truly unrelated page due to concurrent recycling (not to be confused with +concurrent deletion), because that results in wrong answers to queries. +Simpler approaches to page deletion that don't need to defer recycling are +possible, but none seem compatible with Lehman and Yao's design. + +Placing an already-deleted page in the FSM to be recycled when needed +doesn't actually change the state of the page. The page will be changed +whenever it is subsequently taken from the FSM for reuse. The deleted +page's contents will be overwritten by the split operation (it will become +the new right sibling page). Fastpath For Index Insertion ---------------------------- @@ -419,8 +472,8 @@ without a backend's cached page also being detected as invalidated, but only when we happen to recycle a block that once again gets recycled as the rightmost leaf page. -On-the-Fly Deletion Of Index Tuples ------------------------------------ +Simple deletion +--------------- If a process visits a heap tuple and finds that it's dead and removable (ie, dead to all open transactions, not only that process), then we can @@ -429,26 +482,32 @@ allowing subsequent index scans to skip visiting the heap tuple. The "known dead" marking works by setting the index item's lp_flags state to LP_DEAD. This is currently only done in plain indexscans, not bitmap scans, because only plain scans visit the heap and index "in sync" and so -there's not a convenient way to do it for bitmap scans. +there's not a convenient way to do it for bitmap scans. Note also that +LP_DEAD bits are often set when checking a unique index for conflicts on +insert (this is simpler because it takes place when we hold an exclusive +lock on the leaf page). -Once an index tuple has been marked LP_DEAD it can actually be removed +Once an index tuple has been marked LP_DEAD it can actually be deleted from the index immediately; since index scans only stop "between" pages, no scan can lose its place from such a deletion. We separate the steps because we allow LP_DEAD to be set with only a share lock (it's exactly like a hint bit for a heap tuple), but physically removing tuples requires -exclusive lock. In the current code we try to remove LP_DEAD tuples when -we are otherwise faced with having to split a page to do an insertion (and -hence have exclusive lock on it already). Deduplication can also prevent -a page split, but removing LP_DEAD tuples is the preferred approach. -(Note that posting list tuples can only have their LP_DEAD bit set when -every table TID within the posting list is known dead.) - -This leaves the index in a state where it has no entry for a dead tuple -that still exists in the heap. This is not a problem for the current -implementation of VACUUM, but it could be a problem for anything that -explicitly tries to find index entries for dead tuples. (However, the -same situation is created by REINDEX, since it doesn't enter dead -tuples into the index.) +exclusive lock. Also, delaying the deletion often allows us to pick up +extra index tuples that weren't initially safe for index scans to mark +LP_DEAD. We do this with index tuples whose TIDs point to the same table +blocks as an LP_DEAD-marked tuple. They're practically free to check in +passing, and have a pretty good chance of being safe to delete due to +various locality effects. + +We only try to delete LP_DEAD tuples (and nearby tuples) when we are +otherwise faced with having to split a page to do an insertion (and hence +have exclusive lock on it already). Deduplication and bottom-up index +deletion can also prevent a page split, but simple deletion is always our +preferred approach. (Note that posting list tuples can only have their +LP_DEAD bit set when every table TID within the posting list is known +dead. This isn't much of a problem in practice because LP_DEAD bits are +just a starting point for simple deletion -- we still manage to perform +granular deletes of posting list TIDs quite often.) It's sufficient to have an exclusive lock on the index page, not a super-exclusive lock, to do deletion of LP_DEAD items. It might seem @@ -456,12 +515,79 @@ that this breaks the interlock between VACUUM and indexscans, but that is not so: as long as an indexscanning process has a pin on the page where the index item used to be, VACUUM cannot complete its btbulkdelete scan and so cannot remove the heap tuple. This is another reason why -btbulkdelete has to get a super-exclusive lock on every leaf page, not -only the ones where it actually sees items to delete. So that we can -handle the cases where we attempt LP_DEAD flagging for a page after we -have released its pin, we remember the LSN of the index page when we read -the index tuples from it; we do not attempt to flag index tuples as dead -if the we didn't hold the pin the entire time and the LSN has changed. +btbulkdelete has to get a super-exclusive lock on every leaf page, not only +the ones where it actually sees items to delete. + +LP_DEAD setting by index scans cannot be sure that a TID whose index tuple +it had planned on LP_DEAD-setting has not been recycled by VACUUM if it +drops its pin in the meantime. It must conservatively also remember the +LSN of the page, and only act to set LP_DEAD bits when the LSN has not +changed at all. (Avoiding dropping the pin entirely also makes it safe, of +course.) + +Bottom-Up deletion +------------------ + +We attempt to delete whatever duplicates happen to be present on the page +when the duplicates are suspected to be caused by version churn from +successive UPDATEs. This only happens when we receive an executor hint +indicating that optimizations like heapam's HOT have not worked out for +the index -- the incoming tuple must be a logically unchanged duplicate +which is needed for MVCC purposes, suggesting that that might well be the +dominant source of new index tuples on the leaf page in question. (Also, +bottom-up deletion is triggered within unique indexes in cases with +continual INSERT and DELETE related churn, since that is easy to detect +without any external hint.) + +Simple deletion will already have failed to prevent a page split when a +bottom-up deletion pass takes place (often because no LP_DEAD bits were +ever set on the page). The two mechanisms have closely related +implementations. The same WAL records are used for each operation, and +the same tableam infrastructure is used to determine what TIDs/tuples are +actually safe to delete. The implementations only differ in how they pick +TIDs to consider for deletion, and whether or not the tableam will give up +before accessing all table blocks (bottom-up deletion lives with the +uncertainty of its success by keeping the cost of failure low). Even +still, the two mechanisms are clearly distinct at the conceptual level. + +Bottom-up index deletion is driven entirely by heuristics (whereas simple +deletion is guaranteed to delete at least those index tuples that are +already LP_DEAD marked -- there must be at least one). We have no +certainty that we'll find even one index tuple to delete. That's why we +closely cooperate with the tableam to keep the costs it pays in balance +with the benefits we receive. The interface that we use for this is +described in detail in access/tableam.h. + +Bottom-up index deletion can be thought of as a backstop mechanism against +unnecessary version-driven page splits. It is based in part on an idea +from generational garbage collection: the "generational hypothesis". This +is the empirical observation that "most objects die young". Within +nbtree, new index tuples often quickly appear in the same place, and then +quickly become garbage. There can be intense concentrations of garbage in +relatively few leaf pages with certain workloads (or there could be in +earlier versions of PostgreSQL without bottom-up index deletion, at +least). See doc/src/sgml/btree.sgml for a high-level description of the +design principles behind bottom-up index deletion in nbtree, including +details of how it complements VACUUM. + +We expect to find a reasonably large number of tuples that are safe to +delete within each bottom-up pass. If we don't then we won't need to +consider the question of bottom-up deletion for the same leaf page for +quite a while (usually because the page splits, which resolves the +situation for the time being). We expect to perform regular bottom-up +deletion operations against pages that are at constant risk of unnecessary +page splits caused only by version churn. When the mechanism works well +we'll constantly be "on the verge" of having version-churn-driven page +splits, but never actually have even one. + +Our duplicate heuristics work well despite being fairly simple. +Unnecessary page splits only occur when there are truly pathological +levels of version churn (in theory a small amount of version churn could +make a page split occur earlier than strictly necessary, but that's pretty +harmless). We don't have to understand the underlying workload; we only +have to understand the general nature of the pathology that we target. +Version churn is easy to spot when it is truly pathological. Affected +leaf pages are fairly homogeneous. WAL Considerations ------------------ @@ -761,9 +887,10 @@ into a single physical tuple with a posting list (a simple array of heap TIDs with the standard item pointer format). Deduplication is always applied lazily, at the point where it would otherwise be necessary to perform a page split. It occurs only when LP_DEAD items have been -removed, as our last line of defense against splitting a leaf page. We -can set the LP_DEAD bit with posting list tuples, though only when all -TIDs are known dead. +removed, as our last line of defense against splitting a leaf page +(bottom-up index deletion may be attempted first, as our second last line +of defense). We can set the LP_DEAD bit with posting list tuples, though +only when all TIDs are known dead. Our lazy approach to deduplication allows the page space accounting used during page splits to have absolutely minimal special case logic for @@ -782,7 +909,10 @@ page space accounting (see later section), so it's not clear how compression could be integrated with nbtree. Besides, posting list compression does not offer a compelling trade-off for nbtree, since in general nbtree is optimized for consistent performance with many -concurrent readers and writers. +concurrent readers and writers. Compression would also make the deletion +of a subset of TIDs from a posting list slow and complicated, which would +be a big problem for workloads that depend heavily on bottom-up index +deletion. A major goal of our lazy approach to deduplication is to limit the performance impact of deduplication with random updates. Even concurrent @@ -820,6 +950,16 @@ delay a split that is probably inevitable anyway. This allows us to avoid the overhead of attempting to deduplicate with unique indexes that always have few or no duplicates. +Note: Avoiding "unnecessary" page splits driven by version churn is also +the goal of bottom-up index deletion, which was added to PostgreSQL 14. +Bottom-up index deletion is now the preferred way to deal with this +problem (with all kinds of indexes, though especially with unique +indexes). Still, deduplication can sometimes augment bottom-up index +deletion. When deletion cannot free tuples (due to an old snapshot +holding up cleanup), falling back on deduplication provides additional +capacity. Delaying the page split by deduplicating can allow a future +bottom-up deletion pass of the same page to succeed. + Posting list splits ------------------- diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c index fdaa7a335fb9..7ac73cb8c2d5 100644 --- a/src/backend/access/nbtree/nbtcompare.c +++ b/src/backend/access/nbtree/nbtcompare.c @@ -3,7 +3,7 @@ * nbtcompare.c * Comparison functions for btree access method. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/nbtree/nbtdedup.c b/src/backend/access/nbtree/nbtdedup.c index f6be865b17e3..271994b08df1 100644 --- a/src/backend/access/nbtree/nbtdedup.c +++ b/src/backend/access/nbtree/nbtdedup.c @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * nbtdedup.c - * Deduplicate items in Postgres btrees. + * Deduplicate or bottom-up delete items in Postgres btrees. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,6 +19,8 @@ #include "miscadmin.h" #include "utils/rel.h" +static void _bt_bottomupdel_finish_pending(Page page, BTDedupState state, + TM_IndexDeleteOp *delstate); static bool _bt_do_singleval(Relation rel, Page page, BTDedupState state, OffsetNumber minoff, IndexTuple newitem); static void _bt_singleval_fillfactor(Page page, BTDedupState state, @@ -28,9 +30,7 @@ static bool _bt_posting_valid(IndexTuple posting); #endif /* - * Deduplicate items on a leaf page. The page will have to be split by caller - * if we cannot successfully free at least newitemsz (we also need space for - * newitem's line pointer, which isn't included in caller's newitemsz). + * Perform a deduplication pass. * * The general approach taken here is to perform as much deduplication as * possible to free as much space as possible. Note, however, that "single @@ -43,76 +43,32 @@ static bool _bt_posting_valid(IndexTuple posting); * handle those if and when the anticipated right half page gets its own * deduplication pass, following further inserts of duplicates.) * - * This function should be called during insertion, when the page doesn't have - * enough space to fit an incoming newitem. If the BTP_HAS_GARBAGE page flag - * was set, caller should have removed any LP_DEAD items by calling - * _bt_vacuum_one_page() before calling here. We may still have to kill - * LP_DEAD items here when the page's BTP_HAS_GARBAGE hint is falsely unset, - * but that should be rare. Also, _bt_vacuum_one_page() won't unset the - * BTP_HAS_GARBAGE flag when it finds no LP_DEAD items, so a successful - * deduplication pass will always clear it, just to keep things tidy. + * The page will have to be split if we cannot successfully free at least + * newitemsz (we also need space for newitem's line pointer, which isn't + * included in caller's newitemsz). + * + * Note: Caller should have already deleted all existing items with their + * LP_DEAD bits set. */ void -_bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, - IndexTuple newitem, Size newitemsz, bool checkingunique) +_bt_dedup_pass(Relation rel, Buffer buf, Relation heapRel, IndexTuple newitem, + Size newitemsz, bool checkingunique) { OffsetNumber offnum, minoff, maxoff; Page page = BufferGetPage(buf); - BTPageOpaque opaque; + BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); Page newpage; - OffsetNumber deletable[MaxIndexTuplesPerPage]; BTDedupState state; - int ndeletable = 0; Size pagesaving = 0; bool singlevalstrat = false; int nkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); - /* - * We can't assume that there are no LP_DEAD items. For one thing, VACUUM - * will clear the BTP_HAS_GARBAGE hint without reliably removing items - * that are marked LP_DEAD. We don't want to unnecessarily unset LP_DEAD - * bits when deduplicating items. Allowing it would be correct, though - * wasteful. - */ - opaque = (BTPageOpaque) PageGetSpecialPointer(page); - minoff = P_FIRSTDATAKEY(opaque); - maxoff = PageGetMaxOffsetNumber(page); - for (offnum = minoff; - offnum <= maxoff; - offnum = OffsetNumberNext(offnum)) - { - ItemId itemid = PageGetItemId(page, offnum); - - if (ItemIdIsDead(itemid)) - deletable[ndeletable++] = offnum; - } - - if (ndeletable > 0) - { - _bt_delitems_delete(rel, buf, deletable, ndeletable, heapRel); - - /* - * Return when a split will be avoided. This is equivalent to - * avoiding a split using the usual _bt_vacuum_one_page() path. - */ - if (PageGetFreeSpace(page) >= newitemsz) - return; - - /* - * Reconsider number of items on page, in case _bt_delitems_delete() - * managed to delete an item or two - */ - minoff = P_FIRSTDATAKEY(opaque); - maxoff = PageGetMaxOffsetNumber(page); - } - /* Passed-in newitemsz is MAXALIGNED but does not include line pointer */ newitemsz += sizeof(ItemIdData); /* - * By here, it's clear that deduplication will definitely be attempted. * Initialize deduplication state. * * It would be possible for maxpostingsize (limit on posting list tuple @@ -138,6 +94,9 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, /* nintervals should be initialized to zero */ state->nintervals = 0; + minoff = P_FIRSTDATAKEY(opaque); + maxoff = PageGetMaxOffsetNumber(page); + /* Determine if "single value" strategy should be used */ if (!checkingunique) singlevalstrat = _bt_do_singleval(rel, page, state, minoff, newitem); @@ -259,10 +218,9 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, /* * By here, it's clear that deduplication will definitely go ahead. * - * Clear the BTP_HAS_GARBAGE page flag in the unlikely event that it is - * still falsely set, just to keep things tidy. (We can't rely on - * _bt_vacuum_one_page() having done this already, and we can't rely on a - * page split or VACUUM getting to it in the near future.) + * Clear the BTP_HAS_GARBAGE page flag. The index must be a heapkeyspace + * index, and as such we'll never pay attention to BTP_HAS_GARBAGE anyway. + * But keep things tidy. */ if (P_HAS_GARBAGE(opaque)) { @@ -311,6 +269,147 @@ _bt_dedup_one_page(Relation rel, Buffer buf, Relation heapRel, pfree(state); } +/* + * Perform bottom-up index deletion pass. + * + * See if duplicate index tuples (plus certain nearby tuples) are eligible to + * be deleted via bottom-up index deletion. The high level goal here is to + * entirely prevent "unnecessary" page splits caused by MVCC version churn + * from UPDATEs (when the UPDATEs don't logically modify any of the columns + * covered by the 'rel' index). This is qualitative, not quantitative -- we + * do not particularly care about once-off opportunities to delete many index + * tuples together. + * + * See nbtree/README for details on the design of nbtree bottom-up deletion. + * See access/tableam.h for a description of how we're expected to cooperate + * with the tableam. + * + * Returns true on success, in which case caller can assume page split will be + * avoided for a reasonable amount of time. Returns false when caller should + * deduplicate the page (if possible at all). + * + * Note: Occasionally we return true despite failing to delete enough items to + * avoid a split. This makes caller skip deduplication and go split the page + * right away. Our return value is always just advisory information. + * + * Note: Caller should have already deleted all existing items with their + * LP_DEAD bits set. + */ +bool +_bt_bottomupdel_pass(Relation rel, Buffer buf, Relation heapRel, + Size newitemsz) +{ + OffsetNumber offnum, + minoff, + maxoff; + Page page = BufferGetPage(buf); + BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); + BTDedupState state; + TM_IndexDeleteOp delstate; + bool neverdedup; + int nkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); + + /* Passed-in newitemsz is MAXALIGNED but does not include line pointer */ + newitemsz += sizeof(ItemIdData); + + /* Initialize deduplication state */ + state = (BTDedupState) palloc(sizeof(BTDedupStateData)); + state->deduplicate = true; + state->nmaxitems = 0; + state->maxpostingsize = BLCKSZ; /* We're not really deduplicating */ + state->base = NULL; + state->baseoff = InvalidOffsetNumber; + state->basetupsize = 0; + state->htids = palloc(state->maxpostingsize); + state->nhtids = 0; + state->nitems = 0; + state->phystupsize = 0; + state->nintervals = 0; + + /* + * Initialize tableam state that describes bottom-up index deletion + * operation. + * + * We'll go on to ask the tableam to search for TIDs whose index tuples we + * can safely delete. The tableam will search until our leaf page space + * target is satisfied, or until the cost of continuing with the tableam + * operation seems too high. It focuses its efforts on TIDs associated + * with duplicate index tuples that we mark "promising". + * + * This space target is a little arbitrary. The tableam must be able to + * keep the costs and benefits in balance. We provide the tableam with + * exhaustive information about what might work, without directly + * concerning ourselves with avoiding work during the tableam call. Our + * role in costing the bottom-up deletion process is strictly advisory. + */ + delstate.bottomup = true; + delstate.bottomupfreespace = Max(BLCKSZ / 16, newitemsz); + delstate.ndeltids = 0; + delstate.deltids = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexDelete)); + delstate.status = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexStatus)); + + minoff = P_FIRSTDATAKEY(opaque); + maxoff = PageGetMaxOffsetNumber(page); + for (offnum = minoff; + offnum <= maxoff; + offnum = OffsetNumberNext(offnum)) + { + ItemId itemid = PageGetItemId(page, offnum); + IndexTuple itup = (IndexTuple) PageGetItem(page, itemid); + + Assert(!ItemIdIsDead(itemid)); + + if (offnum == minoff) + { + /* itup starts first pending interval */ + _bt_dedup_start_pending(state, itup, offnum); + } + else if (_bt_keep_natts_fast(rel, state->base, itup) > nkeyatts && + _bt_dedup_save_htid(state, itup)) + { + /* Tuple is equal; just added its TIDs to pending interval */ + } + else + { + /* Finalize interval -- move its TIDs to delete state */ + _bt_bottomupdel_finish_pending(page, state, &delstate); + + /* itup starts new pending interval */ + _bt_dedup_start_pending(state, itup, offnum); + } + } + /* Finalize final interval -- move its TIDs to delete state */ + _bt_bottomupdel_finish_pending(page, state, &delstate); + + /* + * We don't give up now in the event of having few (or even zero) + * promising tuples for the tableam because it's not up to us as the index + * AM to manage costs (note that the tableam might have heuristics of its + * own that work out what to do). We should at least avoid having our + * caller do a useless deduplication pass after we return in the event of + * zero promising tuples, though. + */ + neverdedup = false; + if (state->nintervals == 0) + neverdedup = true; + + pfree(state->htids); + pfree(state); + + /* Ask tableam which TIDs are deletable, then physically delete them */ + _bt_delitems_delete_check(rel, buf, heapRel, &delstate); + + pfree(delstate.deltids); + pfree(delstate.status); + + /* Report "success" to caller unconditionally to avoid deduplication */ + if (neverdedup) + return true; + + /* Don't dedup when we won't end up back here any time soon anyway */ + return PageGetExactFreeSpace(page) >= Max(BLCKSZ / 24, newitemsz); +} + /* * Create a new pending posting list tuple based on caller's base tuple. * @@ -496,6 +595,150 @@ _bt_dedup_finish_pending(Page newpage, BTDedupState state) return spacesaving; } +/* + * Finalize interval during bottom-up index deletion. + * + * During a bottom-up pass we expect that TIDs will be recorded in dedup state + * first, and then get moved over to delstate (in variable-sized batches) by + * calling here. Call here happens when the number of TIDs in a dedup + * interval is known, and interval gets finalized (i.e. when caller sees next + * tuple on the page is not a duplicate, or when caller runs out of tuples to + * process from leaf page). + * + * This is where bottom-up deletion determines and remembers which entries are + * duplicates. This will be important information to the tableam delete + * infrastructure later on. Plain index tuple duplicates are marked + * "promising" here, per tableam contract. + * + * Our approach to marking entries whose TIDs come from posting lists is more + * complicated. Posting lists can only be formed by a deduplication pass (or + * during an index build), so recent version churn affecting the pointed-to + * logical rows is not particularly likely. We may still give a weak signal + * about posting list tuples' entries (by marking just one of its TIDs/entries + * promising), though this is only a possibility in the event of further + * duplicate index tuples in final interval that covers posting list tuple (as + * in the plain tuple case). A weak signal/hint will be useful to the tableam + * when it has no stronger signal to go with for the deletion operation as a + * whole. + * + * The heuristics we use work well in practice because we only need to give + * the tableam the right _general_ idea about where to look. Garbage tends to + * naturally get concentrated in relatively few table blocks with workloads + * that bottom-up deletion targets. The tableam cannot possibly rank all + * available table blocks sensibly based on the hints we provide, but that's + * okay -- only the extremes matter. The tableam just needs to be able to + * predict which few table blocks will have the most tuples that are safe to + * delete for each deletion operation, with low variance across related + * deletion operations. + */ +static void +_bt_bottomupdel_finish_pending(Page page, BTDedupState state, + TM_IndexDeleteOp *delstate) +{ + bool dupinterval = (state->nitems > 1); + + Assert(state->nitems > 0); + Assert(state->nitems <= state->nhtids); + Assert(state->intervals[state->nintervals].baseoff == state->baseoff); + + for (int i = 0; i < state->nitems; i++) + { + OffsetNumber offnum = state->baseoff + i; + ItemId itemid = PageGetItemId(page, offnum); + IndexTuple itup = (IndexTuple) PageGetItem(page, itemid); + TM_IndexDelete *ideltid = &delstate->deltids[delstate->ndeltids]; + TM_IndexStatus *istatus = &delstate->status[delstate->ndeltids]; + + if (!BTreeTupleIsPosting(itup)) + { + /* Simple case: A plain non-pivot tuple */ + ideltid->tid = itup->t_tid; + ideltid->id = delstate->ndeltids; + istatus->idxoffnum = offnum; + istatus->knowndeletable = false; /* for now */ + istatus->promising = dupinterval; /* simple rule */ + istatus->freespace = ItemIdGetLength(itemid) + sizeof(ItemIdData); + + delstate->ndeltids++; + } + else + { + /* + * Complicated case: A posting list tuple. + * + * We make the conservative assumption that there can only be at + * most one affected logical row per posting list tuple. There + * will be at most one promising entry in deltids to represent + * this presumed lone logical row. Note that this isn't even + * considered unless the posting list tuple is also in an interval + * of duplicates -- this complicated rule is just a variant of the + * simple rule used to decide if plain index tuples are promising. + */ + int nitem = BTreeTupleGetNPosting(itup); + bool firstpromising = false; + bool lastpromising = false; + + Assert(_bt_posting_valid(itup)); + + if (dupinterval) + { + /* + * Complicated rule: either the first or last TID in the + * posting list gets marked promising (if any at all) + */ + BlockNumber minblocklist, + midblocklist, + maxblocklist; + ItemPointer mintid, + midtid, + maxtid; + + mintid = BTreeTupleGetHeapTID(itup); + midtid = BTreeTupleGetPostingN(itup, nitem / 2); + maxtid = BTreeTupleGetMaxHeapTID(itup); + minblocklist = ItemPointerGetBlockNumber(mintid); + midblocklist = ItemPointerGetBlockNumber(midtid); + maxblocklist = ItemPointerGetBlockNumber(maxtid); + + /* Only entry with predominant table block can be promising */ + firstpromising = (minblocklist == midblocklist); + lastpromising = (!firstpromising && + midblocklist == maxblocklist); + } + + for (int p = 0; p < nitem; p++) + { + ItemPointer htid = BTreeTupleGetPostingN(itup, p); + + ideltid->tid = *htid; + ideltid->id = delstate->ndeltids; + istatus->idxoffnum = offnum; + istatus->knowndeletable = false; /* for now */ + istatus->promising = false; + if ((firstpromising && p == 0) || + (lastpromising && p == nitem - 1)) + istatus->promising = true; + istatus->freespace = sizeof(ItemPointerData); /* at worst */ + + ideltid++; + istatus++; + delstate->ndeltids++; + } + } + } + + if (dupinterval) + { + state->intervals[state->nintervals].nitems = state->nitems; + state->nintervals++; + } + + /* Reset state for next interval */ + state->nhtids = 0; + state->nitems = 0; + state->phystupsize = 0; +} + /* * Determine if page non-pivot tuples (data items) are all duplicates of the * same value -- if they are, deduplication's "single value" strategy should @@ -666,8 +909,8 @@ _bt_form_posting(IndexTuple base, ItemPointer htids, int nhtids) * Generate a replacement tuple by "updating" a posting list tuple so that it * no longer has TIDs that need to be deleted. * - * Used by VACUUM. Caller's vacposting argument points to the existing - * posting list tuple to be updated. + * Used by both VACUUM and index deletion. Caller's vacposting argument + * points to the existing posting list tuple to be updated. * * On return, caller's vacposting argument will point to final "updated" * tuple, which will be palloc()'d in caller's memory context. @@ -781,7 +1024,19 @@ _bt_swap_posting(IndexTuple newitem, IndexTuple oposting, int postingoff) nhtids = BTreeTupleGetNPosting(oposting); Assert(_bt_posting_valid(oposting)); - Assert(postingoff > 0 && postingoff < nhtids); + + /* + * The postingoff argument originated as a _bt_binsrch_posting() return + * value. It will be 0 in the event of corruption that makes a leaf page + * contain a non-pivot tuple that's somehow identical to newitem (no two + * non-pivot tuples should ever have the same TID). This has been known + * to happen in the field from time to time. + * + * Perform a basic sanity check to catch this case now. + */ + if (!(postingoff > 0 && postingoff < nhtids)) + elog(ERROR, "posting list tuple with %d items cannot be split at offset %d", + nhtids, postingoff); /* * Move item pointers in posting list to make a gap for the new item's diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 48406b562539..d3a228c6fc3f 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -3,7 +3,7 @@ * nbtinsert.c * Item insertion in Lehman and Yao btrees for Postgres. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,9 +17,9 @@ #include "access/nbtree.h" #include "access/nbtxlog.h" -#include "access/tableam.h" #include "access/transam.h" #include "access/xloginsert.h" +#include "lib/qunique.h" #include "miscadmin.h" #include "storage/lmgr.h" #include "storage/predicate.h" @@ -41,6 +41,7 @@ static TransactionId _bt_check_unique(Relation rel, BTInsertState insertstate, static OffsetNumber _bt_findinsertloc(Relation rel, BTInsertState insertstate, bool checkingunique, + bool indexUnchanged, BTStack stack, Relation heapRel); static void _bt_stepright(Relation rel, BTInsertState insertstate, BTStack stack); @@ -58,11 +59,22 @@ static Buffer _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, IndexTuple newitem, IndexTuple orignewitem, IndexTuple nposting, uint16 postingoff); static void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, - BTStack stack, bool is_root, bool is_only); + BTStack stack, bool isroot, bool isonly); static Buffer _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf); static inline bool _bt_pgaddtup(Page page, Size itemsize, IndexTuple itup, OffsetNumber itup_off, bool newfirstdataitem); -static void _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel); +static void _bt_delete_or_dedup_one_page(Relation rel, Relation heapRel, + BTInsertState insertstate, + bool simpleonly, bool checkingunique, + bool uniquedup, bool indexUnchanged); +static void _bt_simpledel_pass(Relation rel, Buffer buffer, Relation heapRel, + OffsetNumber *deletable, int ndeletable, + IndexTuple newitem, OffsetNumber minoff, + OffsetNumber maxoff); +static BlockNumber *_bt_deadblocks(Page page, OffsetNumber *deletable, + int ndeletable, IndexTuple newitem, + int *nblocks); +static inline int _bt_blk_cmp(const void *arg1, const void *arg2); /* * _bt_doinsert() -- Handle insertion of a single index tuple in the tree. @@ -76,6 +88,11 @@ static void _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel); * For UNIQUE_CHECK_EXISTING we merely run the duplicate check, and * don't actually insert. * + * indexUnchanged executor hint indicates if itup is from an + * UPDATE that didn't logically change the indexed value, but + * must nevertheless have a new entry to point to a successor + * version. + * * The result value is only significant for UNIQUE_CHECK_PARTIAL: * it must be true if the entry is known unique, else false. * (In the current implementation we'll also return true after a @@ -84,7 +101,8 @@ static void _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel); */ bool _bt_doinsert(Relation rel, IndexTuple itup, - IndexUniqueCheck checkUnique, Relation heapRel) + IndexUniqueCheck checkUnique, bool indexUnchanged, + Relation heapRel) { bool is_unique = false; BTInsertStateData insertstate; @@ -239,7 +257,7 @@ _bt_doinsert(Relation rel, IndexTuple itup, * checkingunique. */ newitemoff = _bt_findinsertloc(rel, &insertstate, checkingunique, - stack, heapRel); + indexUnchanged, stack, heapRel); _bt_insertonpg(rel, itup_key, insertstate.buf, InvalidBuffer, stack, itup, insertstate.itemsz, newitemoff, insertstate.postingoff, false); @@ -310,11 +328,11 @@ _bt_search_insert(Relation rel, BTInsertState insertstate) if (_bt_conditionallockbuf(rel, insertstate->buf)) { Page page; - BTPageOpaque lpageop; + BTPageOpaque opaque; _bt_checkpage(rel, insertstate->buf); page = BufferGetPage(insertstate->buf); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); /* * Check if the page is still the rightmost leaf page and has @@ -324,9 +342,9 @@ _bt_search_insert(Relation rel, BTInsertState insertstate) * scantid to be unset when our caller is a checkingunique * inserter.) */ - if (P_RIGHTMOST(lpageop) && - P_ISLEAF(lpageop) && - !P_IGNORE(lpageop) && + if (P_RIGHTMOST(opaque) && + P_ISLEAF(opaque) && + !P_IGNORE(opaque) && PageGetFreeSpace(page) > insertstate->itemsz && PageGetMaxOffsetNumber(page) >= P_HIKEY && _bt_compare(rel, insertstate->itup_key, page, P_HIKEY) > 0) @@ -394,7 +412,7 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel, { IndexTuple itup = insertstate->itup; IndexTuple curitup = NULL; - ItemId curitemid; + ItemId curitemid = NULL; BTScanInsert itup_key = insertstate->itup_key; SnapshotData SnapshotDirty; OffsetNumber offset; @@ -481,11 +499,7 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel, * items as quickly as we can. We only apply _bt_compare() when * we get to a non-killed item. We could reuse the bounds to * avoid _bt_compare() calls for known equal tuples, but it - * doesn't seem worth it. Workloads with heavy update activity - * tend to have many deduplication passes, so we'll often avoid - * most of those comparisons, too (we call _bt_compare() when the - * posting list tuple is initially encountered, though not when - * processing later TIDs from the same tuple). + * doesn't seem worth it. */ if (!inposting) curitemid = PageGetItemId(page, offset); @@ -778,6 +792,17 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel, * room for the new tuple, this function moves right, trying to find a * legal page that does.) * + * If 'indexUnchanged' is true, this is for an UPDATE that didn't + * logically change the indexed value, but must nevertheless have a new + * entry to point to a successor version. This hint from the executor + * will influence our behavior when the page might have to be split and + * we must consider our options. Bottom-up index deletion can avoid + * pathological version-driven page splits, but we only want to go to the + * trouble of trying it when we already have moderate confidence that + * it's appropriate. The hint should not significantly affect our + * behavior over time unless practically all inserts on to the leaf page + * get the hint. + * * On exit, insertstate buffer contains the chosen insertion page, and * the offset within that page is returned. If _bt_findinsertloc needed * to move right, the lock and pin on the original page are released, and @@ -794,22 +819,23 @@ static OffsetNumber _bt_findinsertloc(Relation rel, BTInsertState insertstate, bool checkingunique, + bool indexUnchanged, BTStack stack, Relation heapRel) { BTScanInsert itup_key = insertstate->itup_key; Page page = BufferGetPage(insertstate->buf); - BTPageOpaque lpageop; + BTPageOpaque opaque; OffsetNumber newitemoff; - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); /* Check 1/3 of a page restriction */ if (unlikely(insertstate->itemsz > BTMaxItemSize(page))) _bt_check_third_page(rel, heapRel, itup_key->heapkeyspace, page, insertstate->itup); - Assert(P_ISLEAF(lpageop) && !P_INCOMPLETE_SPLIT(lpageop)); + Assert(P_ISLEAF(opaque) && !P_INCOMPLETE_SPLIT(opaque)); Assert(!insertstate->bounds_valid || checkingunique); Assert(!itup_key->heapkeyspace || itup_key->scantid != NULL); Assert(itup_key->heapkeyspace || itup_key->scantid == NULL); @@ -818,7 +844,7 @@ _bt_findinsertloc(Relation rel, if (itup_key->heapkeyspace) { /* Keep track of whether checkingunique duplicate seen */ - bool uniquedup = false; + bool uniquedup = indexUnchanged; /* * If we're inserting into a unique index, we may have to walk right @@ -861,52 +887,27 @@ _bt_findinsertloc(Relation rel, break; /* Test '<=', not '!=', since scantid is set now */ - if (P_RIGHTMOST(lpageop) || + if (P_RIGHTMOST(opaque) || _bt_compare(rel, itup_key, page, P_HIKEY) <= 0) break; _bt_stepright(rel, insertstate, stack); /* Update local state after stepping right */ page = BufferGetPage(insertstate->buf); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); /* Assume duplicates (if checkingunique) */ uniquedup = true; } } /* - * If the target page is full, see if we can obtain enough space by - * erasing LP_DEAD items. If that fails to free enough space, see if - * we can avoid a page split by performing a deduplication pass over - * the page. - * - * We only perform a deduplication pass for a checkingunique caller - * when the incoming item is a duplicate of an existing item on the - * leaf page. This heuristic avoids wasting cycles -- we only expect - * to benefit from deduplicating a unique index page when most or all - * recently added items are duplicates. See nbtree/README. + * If the target page cannot fit newitem, try to avoid splitting the + * page on insert by performing deletion or deduplication now */ if (PageGetFreeSpace(page) < insertstate->itemsz) - { - if (P_HAS_GARBAGE(lpageop)) - { - _bt_vacuum_one_page(rel, insertstate->buf, heapRel); - insertstate->bounds_valid = false; - - /* Might as well assume duplicates (if checkingunique) */ - uniquedup = true; - } - - if (itup_key->allequalimage && BTGetDeduplicateItems(rel) && - (!checkingunique || uniquedup) && - PageGetFreeSpace(page) < insertstate->itemsz) - { - _bt_dedup_one_page(rel, insertstate->buf, heapRel, - insertstate->itup, insertstate->itemsz, - checkingunique); - insertstate->bounds_valid = false; - } - } + _bt_delete_or_dedup_one_page(rel, heapRel, insertstate, false, + checkingunique, uniquedup, + indexUnchanged); } else { @@ -944,10 +945,11 @@ _bt_findinsertloc(Relation rel, * Before considering moving right, see if we can obtain enough * space by erasing LP_DEAD items */ - if (P_HAS_GARBAGE(lpageop)) + if (P_HAS_GARBAGE(opaque)) { - _bt_vacuum_one_page(rel, insertstate->buf, heapRel); - insertstate->bounds_valid = false; + /* Perform simple deletion */ + _bt_delete_or_dedup_one_page(rel, heapRel, insertstate, true, + false, false, false); if (PageGetFreeSpace(page) >= insertstate->itemsz) break; /* OK, now we have enough space */ @@ -968,7 +970,7 @@ _bt_findinsertloc(Relation rel, insertstate->stricthigh <= PageGetMaxOffsetNumber(page)) break; - if (P_RIGHTMOST(lpageop) || + if (P_RIGHTMOST(opaque) || _bt_compare(rel, itup_key, page, P_HIKEY) != 0 || random() <= (MAX_RANDOM_VALUE / 100)) break; @@ -976,7 +978,7 @@ _bt_findinsertloc(Relation rel, _bt_stepright(rel, insertstate, stack); /* Update local state after stepping right */ page = BufferGetPage(insertstate->buf); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); } } @@ -984,7 +986,7 @@ _bt_findinsertloc(Relation rel, * We should now be on the correct page. Find the offset within the page * for the new tuple. (Possibly reusing earlier search bounds.) */ - Assert(P_RIGHTMOST(lpageop) || + Assert(P_RIGHTMOST(opaque) || _bt_compare(rel, itup_key, page, P_HIKEY) <= 0); newitemoff = _bt_binsrch_insert(rel, insertstate); @@ -994,17 +996,17 @@ _bt_findinsertloc(Relation rel, /* * There is an overlapping posting list tuple with its LP_DEAD bit * set. We don't want to unnecessarily unset its LP_DEAD bit while - * performing a posting list split, so delete all LP_DEAD items early. - * This is the only case where LP_DEAD deletes happen even though - * there is space for newitem on the page. + * performing a posting list split, so perform simple index tuple + * deletion early. */ - _bt_vacuum_one_page(rel, insertstate->buf, heapRel); + _bt_delete_or_dedup_one_page(rel, heapRel, insertstate, true, + false, false, false); /* * Do new binary search. New insert location cannot overlap with any * posting list now. */ - insertstate->bounds_valid = false; + Assert(!insertstate->bounds_valid); insertstate->postingoff = 0; newitemoff = _bt_binsrch_insert(rel, insertstate); Assert(insertstate->postingoff == 0); @@ -1029,20 +1031,20 @@ static void _bt_stepright(Relation rel, BTInsertState insertstate, BTStack stack) { Page page; - BTPageOpaque lpageop; + BTPageOpaque opaque; Buffer rbuf; BlockNumber rblkno; page = BufferGetPage(insertstate->buf); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); rbuf = InvalidBuffer; - rblkno = lpageop->btpo_next; + rblkno = opaque->btpo_next; for (;;) { rbuf = _bt_relandgetbuf(rel, rbuf, rblkno, BT_WRITE); page = BufferGetPage(rbuf); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); /* * If this page was incompletely split, finish the split now. We do @@ -1050,20 +1052,20 @@ _bt_stepright(Relation rel, BTInsertState insertstate, BTStack stack) * because finishing the split could be a fairly lengthy operation. * But this should happen very seldom. */ - if (P_INCOMPLETE_SPLIT(lpageop)) + if (P_INCOMPLETE_SPLIT(opaque)) { _bt_finish_split(rel, rbuf, stack); rbuf = InvalidBuffer; continue; } - if (!P_IGNORE(lpageop)) + if (!P_IGNORE(opaque)) break; - if (P_RIGHTMOST(lpageop)) + if (P_RIGHTMOST(opaque)) elog(ERROR, "fell off the end of index \"%s\"", RelationGetRelationName(rel)); - rblkno = lpageop->btpo_next; + rblkno = opaque->btpo_next; } /* rbuf locked; unlock buf, update state for caller */ _bt_relbuf(rel, insertstate->buf); @@ -1114,25 +1116,35 @@ _bt_insertonpg(Relation rel, bool split_only_page) { Page page; - BTPageOpaque lpageop; + BTPageOpaque opaque; + bool isleaf, + isroot, + isrightmost, + isonly; IndexTuple oposting = NULL; IndexTuple origitup = NULL; IndexTuple nposting = NULL; page = BufferGetPage(buf); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); + isleaf = P_ISLEAF(opaque); + isroot = P_ISROOT(opaque); + isrightmost = P_RIGHTMOST(opaque); + isonly = P_LEFTMOST(opaque) && P_RIGHTMOST(opaque); /* child buffer must be given iff inserting on an internal page */ - Assert(P_ISLEAF(lpageop) == !BufferIsValid(cbuf)); + Assert(isleaf == !BufferIsValid(cbuf)); /* tuple must have appropriate number of attributes */ - Assert(!P_ISLEAF(lpageop) || + Assert(!isleaf || BTreeTupleGetNAtts(itup, rel) == IndexRelationGetNumberOfAttributes(rel)); - Assert(P_ISLEAF(lpageop) || + Assert(isleaf || BTreeTupleGetNAtts(itup, rel) <= IndexRelationGetNumberOfKeyAttributes(rel)); Assert(!BTreeTupleIsPosting(itup)); Assert(MAXALIGN(IndexTupleSize(itup)) == itemsz); + /* Caller must always finish incomplete split for us */ + Assert(!P_INCOMPLETE_SPLIT(opaque)); /* * Every internal page should have exactly one negative infinity item at @@ -1140,12 +1152,7 @@ _bt_insertonpg(Relation rel, * become negative infinity items through truncation, since they're the * only routines that allocate new internal pages. */ - Assert(P_ISLEAF(lpageop) || newitemoff > P_FIRSTDATAKEY(lpageop)); - - /* The caller should've finished any incomplete splits already. */ - if (P_INCOMPLETE_SPLIT(lpageop)) - elog(ERROR, "cannot insert to incompletely split page %u", - BufferGetBlockNumber(buf)); + Assert(isleaf || newitemoff > P_FIRSTDATAKEY(opaque)); /* * Do we need to split an existing posting list item? @@ -1161,7 +1168,7 @@ _bt_insertonpg(Relation rel, * its post-split version is treated as an extra step in either the * insert or page split critical section. */ - Assert(P_ISLEAF(lpageop) && !ItemIdIsDead(itemid)); + Assert(isleaf && !ItemIdIsDead(itemid)); Assert(itup_key->heapkeyspace && itup_key->allequalimage); oposting = (IndexTuple) PageGetItem(page, itemid); @@ -1184,8 +1191,6 @@ _bt_insertonpg(Relation rel, */ if (PageGetFreeSpace(page) < itemsz) { - bool is_root = P_ISROOT(lpageop); - bool is_only = P_LEFTMOST(lpageop) && P_RIGHTMOST(lpageop); Buffer rbuf; Assert(!split_only_page); @@ -1215,12 +1220,10 @@ _bt_insertonpg(Relation rel, * page. *---------- */ - _bt_insert_parent(rel, buf, rbuf, stack, is_root, is_only); + _bt_insert_parent(rel, buf, rbuf, stack, isroot, isonly); } else { - bool isleaf = P_ISLEAF(lpageop); - bool isrightmost = P_RIGHTMOST(lpageop); Buffer metabuf = InvalidBuffer; Page metapg = NULL; BTMetaPageData *metad = NULL; @@ -1233,7 +1236,7 @@ _bt_insertonpg(Relation rel, * at or above the current page. We can safely acquire a lock on the * metapage here --- see comments for _bt_newroot(). */ - if (split_only_page) + if (unlikely(split_only_page)) { Assert(!isleaf); Assert(BufferIsValid(cbuf)); @@ -1242,7 +1245,7 @@ _bt_insertonpg(Relation rel, metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); - if (metad->btm_fastlevel >= lpageop->btpo.level) + if (metad->btm_fastlevel >= opaque->btpo_level) { /* no update wanted */ _bt_relbuf(rel, metabuf); @@ -1269,7 +1272,7 @@ _bt_insertonpg(Relation rel, if (metad->btm_version < BTREE_NOVAC_VERSION) _bt_upgrademetapage(metapg); metad->btm_fastroot = BufferGetBlockNumber(buf); - metad->btm_fastlevel = lpageop->btpo.level; + metad->btm_fastlevel = opaque->btpo_level; MarkBufferDirty(metabuf); } @@ -1332,9 +1335,7 @@ _bt_insertonpg(Relation rel, xlmeta.level = metad->btm_level; xlmeta.fastroot = metad->btm_fastroot; xlmeta.fastlevel = metad->btm_fastlevel; - xlmeta.oldest_btpo_xact = metad->btm_oldest_btpo_xact; - xlmeta.last_cleanup_num_heap_tuples = - metad->btm_last_cleanup_num_heap_tuples; + xlmeta.last_cleanup_num_delpages = metad->btm_last_cleanup_num_delpages; xlmeta.allequalimage = metad->btm_allequalimage; XLogRegisterBuffer(2, metabuf, @@ -1390,7 +1391,7 @@ _bt_insertonpg(Relation rel, * may be used by a future inserter within _bt_search_insert(). */ blockcache = InvalidBlockNumber; - if (isrightmost && isleaf && !P_ISROOT(lpageop)) + if (isrightmost && isleaf && !isroot) blockcache = BufferGetBlockNumber(buf); /* Release buffer for insertion target block */ @@ -1538,7 +1539,7 @@ _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf, lopaque->btpo_flags |= BTP_INCOMPLETE_SPLIT; lopaque->btpo_prev = oopaque->btpo_prev; /* handle btpo_next after rightpage buffer acquired */ - lopaque->btpo.level = oopaque->btpo.level; + lopaque->btpo_level = oopaque->btpo_level; /* handle btpo_cycleid after rightpage buffer acquired */ /* @@ -1723,7 +1724,7 @@ _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf, ropaque->btpo_flags &= ~(BTP_ROOT | BTP_SPLIT_END | BTP_HAS_GARBAGE); ropaque->btpo_prev = origpagenumber; ropaque->btpo_next = oopaque->btpo_next; - ropaque->btpo.level = oopaque->btpo.level; + ropaque->btpo_level = oopaque->btpo_level; ropaque->btpo_cycleid = lopaque->btpo_cycleid; /* @@ -1951,7 +1952,7 @@ _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf, uint8 xlinfo; XLogRecPtr recptr; - xlrec.level = ropaque->btpo.level; + xlrec.level = ropaque->btpo_level; /* See comments below on newitem, orignewitem, and posting lists */ xlrec.firstrightoff = firstrightoff; xlrec.newitemoff = newitemoff; @@ -2073,16 +2074,16 @@ _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf, * * stack - stack showing how we got here. Will be NULL when splitting true * root, or during concurrent root split, where we can be inefficient - * is_root - we split the true root - * is_only - we split a page alone on its level (might have been fast root) + * isroot - we split the true root + * isonly - we split a page alone on its level (might have been fast root) */ static void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, BTStack stack, - bool is_root, - bool is_only) + bool isroot, + bool isonly) { /* * Here we have to do something Lehman and Yao don't talk about: deal with @@ -2097,12 +2098,12 @@ _bt_insert_parent(Relation rel, * from the root. This is not super-efficient, but it's rare enough not * to matter. */ - if (is_root) + if (isroot) { Buffer rootbuf; Assert(stack == NULL); - Assert(is_only); + Assert(isonly); /* create a new root node and update the metapage */ rootbuf = _bt_newroot(rel, buf, rbuf); /* release the split buffers */ @@ -2122,10 +2123,10 @@ _bt_insert_parent(Relation rel, if (stack == NULL) { - BTPageOpaque lpageop; + BTPageOpaque opaque; elog(DEBUG2, "concurrent ROOT page split"); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); /* * We should never reach here when a leaf page split takes place @@ -2139,12 +2140,11 @@ _bt_insert_parent(Relation rel, * page will split, since it's faster to go through _bt_search() * and get a stack in the usual way. */ - Assert(!(P_ISLEAF(lpageop) && + Assert(!(P_ISLEAF(opaque) && BlockNumberIsValid(RelationGetTargetBlock(rel)))); /* Find the leftmost page at the next level up */ - pbuf = _bt_get_endpoint(rel, lpageop->btpo.level + 1, false, - NULL); + pbuf = _bt_get_endpoint(rel, opaque->btpo_level + 1, false, NULL); /* Set up a phony stack entry pointing there */ stack = &fakestack; stack->bts_blkno = BufferGetBlockNumber(pbuf); @@ -2196,7 +2196,7 @@ _bt_insert_parent(Relation rel, /* Recursively insert into the parent */ _bt_insertonpg(rel, NULL, pbuf, buf, stack->bts_parent, new_item, MAXALIGN(IndexTupleSize(new_item)), - stack->bts_offset + 1, 0, is_only); + stack->bts_offset + 1, 0, isonly); /* be tidy */ pfree(new_item); @@ -2221,8 +2221,8 @@ _bt_finish_split(Relation rel, Buffer lbuf, BTStack stack) Buffer rbuf; Page rpage; BTPageOpaque rpageop; - bool was_root; - bool was_only; + bool wasroot; + bool wasonly; Assert(P_INCOMPLETE_SPLIT(lpageop)); @@ -2243,20 +2243,20 @@ _bt_finish_split(Relation rel, Buffer lbuf, BTStack stack) metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); - was_root = (metad->btm_root == BufferGetBlockNumber(lbuf)); + wasroot = (metad->btm_root == BufferGetBlockNumber(lbuf)); _bt_relbuf(rel, metabuf); } else - was_root = false; + wasroot = false; /* Was this the only page on the level before split? */ - was_only = (P_LEFTMOST(lpageop) && P_RIGHTMOST(rpageop)); + wasonly = (P_LEFTMOST(lpageop) && P_RIGHTMOST(rpageop)); elog(DEBUG1, "finishing incomplete split of %u/%u", BufferGetBlockNumber(lbuf), BufferGetBlockNumber(rbuf)); - _bt_insert_parent(rel, lbuf, rbuf, stack, was_root, was_only); + _bt_insert_parent(rel, lbuf, rbuf, stack, wasroot, wasonly); } /* @@ -2482,15 +2482,15 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage); rootopaque->btpo_prev = rootopaque->btpo_next = P_NONE; rootopaque->btpo_flags = BTP_ROOT; - rootopaque->btpo.level = - ((BTPageOpaque) PageGetSpecialPointer(lpage))->btpo.level + 1; + rootopaque->btpo_level = + ((BTPageOpaque) PageGetSpecialPointer(lpage))->btpo_level + 1; rootopaque->btpo_cycleid = 0; /* update metapage data */ metad->btm_root = rootblknum; - metad->btm_level = rootopaque->btpo.level; + metad->btm_level = rootopaque->btpo_level; metad->btm_fastroot = rootblknum; - metad->btm_fastlevel = rootopaque->btpo.level; + metad->btm_fastlevel = rootopaque->btpo_level; /* * Insert the left page pointer into the new root page. The root page is @@ -2550,8 +2550,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) md.level = metad->btm_level; md.fastroot = rootblknum; md.fastlevel = metad->btm_level; - md.oldest_btpo_xact = metad->btm_oldest_btpo_xact; - md.last_cleanup_num_heap_tuples = metad->btm_last_cleanup_num_heap_tuples; + md.last_cleanup_num_delpages = metad->btm_last_cleanup_num_delpages; md.allequalimage = metad->btm_allequalimage; XLogRegisterBufData(2, (char *) &md, sizeof(xl_btree_metadata)); @@ -2627,28 +2626,69 @@ _bt_pgaddtup(Page page, } /* - * _bt_vacuum_one_page - vacuum just one index page. + * _bt_delete_or_dedup_one_page - Try to avoid a leaf page split. * - * Try to remove LP_DEAD items from the given page. The passed buffer - * must be exclusive-locked, but unlike a real VACUUM, we don't need a - * super-exclusive "cleanup" lock (see nbtree/README). + * There are three operations performed here: simple index deletion, bottom-up + * index deletion, and deduplication. If all three operations fail to free + * enough space for the incoming item then caller will go on to split the + * page. We always consider simple deletion first. If that doesn't work out + * we consider alternatives. Callers that only want us to consider simple + * deletion (without any fallback) ask for that using the 'simpleonly' + * argument. + * + * We usually pick only one alternative "complex" operation when simple + * deletion alone won't prevent a page split. The 'checkingunique', + * 'uniquedup', and 'indexUnchanged' arguments are used for that. + * + * Note: We used to only delete LP_DEAD items when the BTP_HAS_GARBAGE page + * level flag was found set. The flag was useful back when there wasn't + * necessarily one single page for a duplicate tuple to go on (before heap TID + * became a part of the key space in version 4 indexes). But we don't + * actually look at the flag anymore (it's not a gating condition for our + * caller). That would cause us to miss tuples that are safe to delete, + * without getting any benefit in return. We know that the alternative is to + * split the page; scanning the line pointer array in passing won't have + * noticeable overhead. (We still maintain the BTP_HAS_GARBAGE flag despite + * all this because !heapkeyspace indexes must still do a "getting tired" + * linear search, and so are likely to get some benefit from using it as a + * gating condition.) */ static void -_bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel) +_bt_delete_or_dedup_one_page(Relation rel, Relation heapRel, + BTInsertState insertstate, + bool simpleonly, bool checkingunique, + bool uniquedup, bool indexUnchanged) { OffsetNumber deletable[MaxIndexTuplesPerPage]; int ndeletable = 0; OffsetNumber offnum, minoff, maxoff; + Buffer buffer = insertstate->buf; + BTScanInsert itup_key = insertstate->itup_key; Page page = BufferGetPage(buffer); BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); + /* + * GPDB: append-optimized table AMs (AO/AOCS) do not implement + * index_delete_tuples. Both table-AM-assisted index deletion strategies -- + * the simple LP_DEAD pass and the bottom-up pass -- call + * table_index_delete_tuples(), so neither is possible for an index on such + * a table; without this guard the NULL callback is jumped to and the + * backend SIGSEGVs. Fall back to deduplication / a page split instead. + */ + bool tableam_can_delete = + (heapRel->rd_tableam->index_delete_tuples != NULL); Assert(P_ISLEAF(opaque)); + Assert(simpleonly || itup_key->heapkeyspace); + Assert(!simpleonly || (!checkingunique && !uniquedup && !indexUnchanged)); /* * Scan over all items to see which ones need to be deleted according to - * LP_DEAD flags. + * LP_DEAD flags. We'll usually manage to delete a few extra items that + * are not marked LP_DEAD in passing. Often the extra items that actually + * end up getting deleted are items that would have had their LP_DEAD bit + * set before long anyway (if we opted not to include them as extras). */ minoff = P_FIRSTDATAKEY(opaque); maxoff = PageGetMaxOffsetNumber(page); @@ -2662,13 +2702,303 @@ _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel) deletable[ndeletable++] = offnum; } - if (ndeletable > 0) - _bt_delitems_delete(rel, buffer, deletable, ndeletable, heapRel); + if (ndeletable > 0 && tableam_can_delete) + { + _bt_simpledel_pass(rel, buffer, heapRel, deletable, ndeletable, + insertstate->itup, minoff, maxoff); + insertstate->bounds_valid = false; + + /* Return when a page split has already been avoided */ + if (PageGetFreeSpace(page) >= insertstate->itemsz) + return; + + /* Might as well assume duplicates (if checkingunique) */ + uniquedup = true; + } + + /* + * We're done with simple deletion. Return early with callers that only + * call here so that simple deletion can be considered. This includes + * callers that explicitly ask for this and checkingunique callers that + * probably don't have any version churn duplicates on the page. + * + * Note: The page's BTP_HAS_GARBAGE hint flag may still be set when we + * return at this point (or when we go on the try either or both of our + * other strategies and they also fail). We do not bother expending a + * separate write to clear it, however. Caller will definitely clear it + * when it goes on to split the page (note also that the deduplication + * process will clear the flag in passing, just to keep things tidy). + */ + if (simpleonly || (checkingunique && !uniquedup)) + { + Assert(!indexUnchanged); + return; + } + + /* Assume bounds about to be invalidated (this is almost certain now) */ + insertstate->bounds_valid = false; + + /* + * Perform bottom-up index deletion pass when executor hint indicated that + * incoming item is logically unchanged, or for a unique index that is + * known to have physical duplicates for some other reason. (There is a + * large overlap between these two cases for a unique index. It's worth + * having both triggering conditions in order to apply the optimization in + * the event of successive related INSERT and DELETE statements.) + * + * We'll go on to do a deduplication pass when a bottom-up pass fails to + * delete an acceptable amount of free space (a significant fraction of + * the page, or space for the new item, whichever is greater). + * + * Note: Bottom-up index deletion uses the same equality/equivalence + * routines as deduplication internally. However, it does not merge + * together index tuples, so the same correctness considerations do not + * apply. We deliberately omit an index-is-allequalimage test here. + */ + if ((indexUnchanged || uniquedup) && tableam_can_delete && + _bt_bottomupdel_pass(rel, buffer, heapRel, insertstate->itemsz)) + return; + + /* Perform deduplication pass (when enabled and index-is-allequalimage) */ + if (BTGetDeduplicateItems(rel) && itup_key->allequalimage) + _bt_dedup_pass(rel, buffer, heapRel, insertstate->itup, + insertstate->itemsz, checkingunique); +} + +/* + * _bt_simpledel_pass - Simple index tuple deletion pass. + * + * We delete all LP_DEAD-set index tuples on a leaf page. The offset numbers + * of all such tuples are determined by caller (caller passes these to us as + * its 'deletable' argument). + * + * We might also delete extra index tuples that turn out to be safe to delete + * in passing (though they must be cheap to check in passing to begin with). + * There is no certainty that any extra tuples will be deleted, though. The + * high level goal of the approach we take is to get the most out of each call + * here (without noticeably increasing the per-call overhead compared to what + * we need to do just to be able to delete the page's LP_DEAD-marked index + * tuples). + * + * The number of extra index tuples that turn out to be deletable might + * greatly exceed the number of LP_DEAD-marked index tuples due to various + * locality related effects. For example, it's possible that the total number + * of table blocks (pointed to by all TIDs on the leaf page) is naturally + * quite low, in which case we might end up checking if it's possible to + * delete _most_ index tuples on the page (without the tableam needing to + * access additional table blocks). The tableam will sometimes stumble upon + * _many_ extra deletable index tuples in indexes where this pattern is + * common. + * + * See nbtree/README for further details on simple index tuple deletion. + */ +static void +_bt_simpledel_pass(Relation rel, Buffer buffer, Relation heapRel, + OffsetNumber *deletable, int ndeletable, IndexTuple newitem, + OffsetNumber minoff, OffsetNumber maxoff) +{ + Page page = BufferGetPage(buffer); + BlockNumber *deadblocks; + int ndeadblocks; + TM_IndexDeleteOp delstate; + OffsetNumber offnum; + + /* Get array of table blocks pointed to by LP_DEAD-set tuples */ + deadblocks = _bt_deadblocks(page, deletable, ndeletable, newitem, + &ndeadblocks); + + /* Initialize tableam state that describes index deletion operation */ + delstate.bottomup = false; + delstate.bottomupfreespace = 0; + delstate.ndeltids = 0; + delstate.deltids = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexDelete)); + delstate.status = palloc(MaxTIDsPerBTreePage * sizeof(TM_IndexStatus)); + + for (offnum = minoff; + offnum <= maxoff; + offnum = OffsetNumberNext(offnum)) + { + ItemId itemid = PageGetItemId(page, offnum); + IndexTuple itup = (IndexTuple) PageGetItem(page, itemid); + TM_IndexDelete *odeltid = &delstate.deltids[delstate.ndeltids]; + TM_IndexStatus *ostatus = &delstate.status[delstate.ndeltids]; + BlockNumber tidblock; + void *match; + + if (!BTreeTupleIsPosting(itup)) + { + tidblock = ItemPointerGetBlockNumber(&itup->t_tid); + match = bsearch(&tidblock, deadblocks, ndeadblocks, + sizeof(BlockNumber), _bt_blk_cmp); + + if (!match) + { + Assert(!ItemIdIsDead(itemid)); + continue; + } + + /* + * TID's table block is among those pointed to by the TIDs from + * LP_DEAD-bit set tuples on page -- add TID to deltids + */ + odeltid->tid = itup->t_tid; + odeltid->id = delstate.ndeltids; + ostatus->idxoffnum = offnum; + ostatus->knowndeletable = ItemIdIsDead(itemid); + ostatus->promising = false; /* unused */ + ostatus->freespace = 0; /* unused */ + + delstate.ndeltids++; + } + else + { + int nitem = BTreeTupleGetNPosting(itup); + + for (int p = 0; p < nitem; p++) + { + ItemPointer tid = BTreeTupleGetPostingN(itup, p); + + tidblock = ItemPointerGetBlockNumber(tid); + match = bsearch(&tidblock, deadblocks, ndeadblocks, + sizeof(BlockNumber), _bt_blk_cmp); + + if (!match) + { + Assert(!ItemIdIsDead(itemid)); + continue; + } + + /* + * TID's table block is among those pointed to by the TIDs + * from LP_DEAD-bit set tuples on page -- add TID to deltids + */ + odeltid->tid = *tid; + odeltid->id = delstate.ndeltids; + ostatus->idxoffnum = offnum; + ostatus->knowndeletable = ItemIdIsDead(itemid); + ostatus->promising = false; /* unused */ + ostatus->freespace = 0; /* unused */ + + odeltid++; + ostatus++; + delstate.ndeltids++; + } + } + } + + pfree(deadblocks); + + Assert(delstate.ndeltids >= ndeletable); + + /* Physically delete LP_DEAD tuples (plus any delete-safe extra TIDs) */ + _bt_delitems_delete_check(rel, buffer, heapRel, &delstate); + + pfree(delstate.deltids); + pfree(delstate.status); +} + +/* + * _bt_deadblocks() -- Get LP_DEAD related table blocks. + * + * Builds sorted and unique-ified array of table block numbers from index + * tuple TIDs whose line pointers are marked LP_DEAD. Also adds the table + * block from incoming newitem just in case it isn't among the LP_DEAD-related + * table blocks. + * + * Always counting the newitem's table block as an LP_DEAD related block makes + * sense because the cost is consistently low; it is practically certain that + * the table block will not incur a buffer miss in tableam. On the other hand + * the benefit is often quite high. There is a decent chance that there will + * be some deletable items from this block, since in general most garbage + * tuples became garbage in the recent past (in many cases this won't be the + * first logical row that core code added to/modified in table block + * recently). + * + * Returns final array, and sets *nblocks to its final size for caller. + */ +static BlockNumber * +_bt_deadblocks(Page page, OffsetNumber *deletable, int ndeletable, + IndexTuple newitem, int *nblocks) +{ + int spacentids, + ntids; + BlockNumber *tidblocks; /* - * Note: if we didn't find any LP_DEAD items, then the page's - * BTP_HAS_GARBAGE hint bit is falsely set. We do not bother expending a - * separate write to clear it, however. We will clear it when we split - * the page, or when deduplication runs. + * Accumulate each TID's block in array whose initial size has space for + * one table block per LP_DEAD-set tuple (plus space for the newitem table + * block). Array will only need to grow when there are LP_DEAD-marked + * posting list tuples (which is not that common). */ + spacentids = ndeletable + 1; + ntids = 0; + tidblocks = (BlockNumber *) palloc(sizeof(BlockNumber) * spacentids); + + /* + * First add the table block for the incoming newitem. This is the one + * case where simple deletion can visit a table block that doesn't have + * any known deletable items. + */ + Assert(!BTreeTupleIsPosting(newitem) && !BTreeTupleIsPivot(newitem)); + tidblocks[ntids++] = ItemPointerGetBlockNumber(&newitem->t_tid); + + for (int i = 0; i < ndeletable; i++) + { + ItemId itemid = PageGetItemId(page, deletable[i]); + IndexTuple itup = (IndexTuple) PageGetItem(page, itemid); + + Assert(ItemIdIsDead(itemid)); + + if (!BTreeTupleIsPosting(itup)) + { + if (ntids + 1 > spacentids) + { + spacentids *= 2; + tidblocks = (BlockNumber *) + repalloc(tidblocks, sizeof(BlockNumber) * spacentids); + } + + tidblocks[ntids++] = ItemPointerGetBlockNumber(&itup->t_tid); + } + else + { + int nposting = BTreeTupleGetNPosting(itup); + + if (ntids + nposting > spacentids) + { + spacentids = Max(spacentids * 2, ntids + nposting); + tidblocks = (BlockNumber *) + repalloc(tidblocks, sizeof(BlockNumber) * spacentids); + } + + for (int j = 0; j < nposting; j++) + { + ItemPointer tid = BTreeTupleGetPostingN(itup, j); + + tidblocks[ntids++] = ItemPointerGetBlockNumber(tid); + } + } + } + + qsort(tidblocks, ntids, sizeof(BlockNumber), _bt_blk_cmp); + *nblocks = qunique(tidblocks, ntids, sizeof(BlockNumber), _bt_blk_cmp); + + return tidblocks; +} + +/* + * _bt_blk_cmp() -- qsort comparison function for _bt_simpledel_pass + */ +static inline int +_bt_blk_cmp(const void *arg1, const void *arg2) +{ + BlockNumber b1 = *((BlockNumber *) arg1); + BlockNumber b2 = *((BlockNumber *) arg2); + + if (b1 < b2) + return -1; + else if (b1 > b2) + return 1; + + return 0; } diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index 7f392480ac0f..ebec8fa5b896 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -4,7 +4,7 @@ * BTree-specific page management code for the Postgres btree access * method. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,27 +32,35 @@ #include "storage/indexfsm.h" #include "storage/lmgr.h" #include "storage/predicate.h" +#include "storage/procarray.h" #include "utils/memdebug.h" +#include "utils/memutils.h" #include "utils/snapmgr.h" static BTMetaPageData *_bt_getmeta(Relation rel, Buffer metabuf); static void _bt_log_reuse_page(Relation rel, BlockNumber blkno, - TransactionId latestRemovedXid); -static TransactionId _bt_xid_horizon(Relation rel, Relation heapRel, Page page, - OffsetNumber *deletable, int ndeletable); + FullTransactionId safexid); +static void _bt_delitems_delete(Relation rel, Buffer buf, + TransactionId latestRemovedXid, + OffsetNumber *deletable, int ndeletable, + BTVacuumPosting *updatable, int nupdatable); +static char *_bt_delitems_update(BTVacuumPosting *updatable, int nupdatable, + OffsetNumber *updatedoffsets, + Size *updatedbuflen, bool needswal); static bool _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack); static bool _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, bool *rightsib_empty, - TransactionId *oldestBtpoXact, - uint32 *ndeleted); + BTVacState *vstate); static bool _bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack, Buffer *subtreeparent, OffsetNumber *poffset, BlockNumber *topparent, BlockNumber *topparentrightsib); +static void _bt_pendingfsm_add(BTVacState *vstate, BlockNumber target, + FullTransactionId safexid); /* * _bt_initmetapage() -- Fill a page buffer with a correct metapage image @@ -73,7 +81,7 @@ _bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level, metad->btm_level = level; metad->btm_fastroot = rootbknum; metad->btm_fastlevel = level; - metad->btm_oldest_btpo_xact = InvalidTransactionId; + metad->btm_last_cleanup_num_delpages = 0; metad->btm_last_cleanup_num_heap_tuples = -1.0; metad->btm_allequalimage = allequalimage; @@ -113,7 +121,7 @@ _bt_upgrademetapage(Page page) /* Set version number and fill extra fields added into version 3 */ metad->btm_version = BTREE_NOVAC_VERSION; - metad->btm_oldest_btpo_xact = InvalidTransactionId; + metad->btm_last_cleanup_num_delpages = 0; metad->btm_last_cleanup_num_heap_tuples = -1.0; /* Only a REINDEX can set this field */ Assert(!metad->btm_allequalimage); @@ -164,36 +172,98 @@ _bt_getmeta(Relation rel, Buffer metabuf) } /* - * _bt_update_meta_cleanup_info() -- Update cleanup-related information in - * the metapage. + * _bt_vacuum_needs_cleanup() -- Checks if index needs cleanup * - * This routine checks if provided cleanup-related information is matching - * to those written in the metapage. On mismatch, metapage is overwritten. + * Called by btvacuumcleanup when btbulkdelete was never called because no + * index tuples needed to be deleted. */ -void -_bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, - float8 numHeapTuples) +bool +_bt_vacuum_needs_cleanup(Relation rel) { Buffer metabuf; Page metapg; BTMetaPageData *metad; - bool needsRewrite = false; - XLogRecPtr recptr; + uint32 btm_version; + BlockNumber prev_num_delpages; - /* read the metapage and check if it needs rewrite */ + /* + * Copy details from metapage to local variables quickly. + * + * Note that we deliberately avoid using cached version of metapage here. + */ metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); + btm_version = metad->btm_version; - /* outdated version of metapage always needs rewrite */ - if (metad->btm_version < BTREE_NOVAC_VERSION) - needsRewrite = true; - else if (metad->btm_oldest_btpo_xact != oldestBtpoXact || - metad->btm_last_cleanup_num_heap_tuples != numHeapTuples) - needsRewrite = true; + if (btm_version < BTREE_NOVAC_VERSION) + { + /* + * Metapage needs to be dynamically upgraded to store fields that are + * only present when btm_version >= BTREE_NOVAC_VERSION + */ + _bt_relbuf(rel, metabuf); + return true; + } - if (!needsRewrite) + prev_num_delpages = metad->btm_last_cleanup_num_delpages; + _bt_relbuf(rel, metabuf); + + /* + * Trigger cleanup in rare cases where prev_num_delpages exceeds 5% of the + * total size of the index. We can reasonably expect (though are not + * guaranteed) to be able to recycle this many pages if we decide to do a + * btvacuumscan call during the ongoing btvacuumcleanup. For further + * details see the nbtree/README section on placing deleted pages in the + * FSM. + */ + if (prev_num_delpages > 0 && + prev_num_delpages > RelationGetNumberOfBlocks(rel) / 20) + return true; + + return false; +} + +/* + * _bt_set_cleanup_info() -- Update metapage for btvacuumcleanup. + * + * Called at the end of btvacuumcleanup, when num_delpages value has been + * finalized. + */ +void +_bt_set_cleanup_info(Relation rel, BlockNumber num_delpages) +{ + Buffer metabuf; + Page metapg; + BTMetaPageData *metad; + + /* + * On-disk compatibility note: The btm_last_cleanup_num_delpages metapage + * field started out as a TransactionId field called btm_oldest_btpo_xact. + * Both "versions" are just uint32 fields. It was convenient to repurpose + * the field when we began to use 64-bit XIDs in deleted pages. + * + * It's possible that a pg_upgrade'd database will contain an XID value in + * what is now recognized as the metapage's btm_last_cleanup_num_delpages + * field. _bt_vacuum_needs_cleanup() may even believe that this value + * indicates that there are lots of pages that it needs to recycle, when + * in reality there are only one or two. The worst that can happen is + * that there will be a call to btvacuumscan a little earlier, which will + * set btm_last_cleanup_num_delpages to a sane value when we're called. + * + * Note also that the metapage's btm_last_cleanup_num_heap_tuples field is + * no longer used as of PostgreSQL 14. We set it to -1.0 on rewrite, just + * to be consistent. + */ + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); + metapg = BufferGetPage(metabuf); + metad = BTPageGetMeta(metapg); + + /* Don't miss chance to upgrade index/metapage when BTREE_MIN_VERSION */ + if (metad->btm_version >= BTREE_NOVAC_VERSION && + metad->btm_last_cleanup_num_delpages == num_delpages) { + /* Usually means index continues to have num_delpages of 0 */ _bt_relbuf(rel, metabuf); return; } @@ -209,14 +279,15 @@ _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, _bt_upgrademetapage(metapg); /* update cleanup-related information */ - metad->btm_oldest_btpo_xact = oldestBtpoXact; - metad->btm_last_cleanup_num_heap_tuples = numHeapTuples; + metad->btm_last_cleanup_num_delpages = num_delpages; + metad->btm_last_cleanup_num_heap_tuples = -1.0; MarkBufferDirty(metabuf); /* write wal record if needed */ if (RelationNeedsWAL(rel)) { xl_btree_metadata md; + XLogRecPtr recptr; XLogBeginInsert(); XLogRegisterBuffer(0, metabuf, REGBUF_WILL_INIT | REGBUF_STANDARD); @@ -227,8 +298,7 @@ _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, md.level = metad->btm_level; md.fastroot = metad->btm_fastroot; md.fastlevel = metad->btm_fastlevel; - md.oldest_btpo_xact = oldestBtpoXact; - md.last_cleanup_num_heap_tuples = numHeapTuples; + md.last_cleanup_num_delpages = num_delpages; md.allequalimage = metad->btm_allequalimage; XLogRegisterBufData(0, (char *) &md, sizeof(xl_btree_metadata)); @@ -239,6 +309,7 @@ _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, } END_CRIT_SECTION(); + _bt_relbuf(rel, metabuf); } @@ -311,7 +382,7 @@ _bt_getroot(Relation rel, int access) * because that's not set in a "fast root". */ if (!P_IGNORE(rootopaque) && - rootopaque->btpo.level == rootlevel && + rootopaque->btpo_level == rootlevel && P_LEFTMOST(rootopaque) && P_RIGHTMOST(rootopaque)) { @@ -372,7 +443,7 @@ _bt_getroot(Relation rel, int access) rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage); rootopaque->btpo_prev = rootopaque->btpo_next = P_NONE; rootopaque->btpo_flags = (BTP_LEAF | BTP_ROOT); - rootopaque->btpo.level = 0; + rootopaque->btpo_level = 0; rootopaque->btpo_cycleid = 0; /* Get raw page pointer for metapage */ metapg = BufferGetPage(metabuf); @@ -388,7 +459,7 @@ _bt_getroot(Relation rel, int access) metad->btm_level = 0; metad->btm_fastroot = rootblkno; metad->btm_fastlevel = 0; - metad->btm_oldest_btpo_xact = InvalidTransactionId; + metad->btm_last_cleanup_num_delpages = 0; metad->btm_last_cleanup_num_heap_tuples = -1.0; MarkBufferDirty(rootbuf); @@ -411,8 +482,7 @@ _bt_getroot(Relation rel, int access) md.level = 0; md.fastroot = rootblkno; md.fastlevel = 0; - md.oldest_btpo_xact = InvalidTransactionId; - md.last_cleanup_num_heap_tuples = -1.0; + md.last_cleanup_num_delpages = 0; md.allequalimage = metad->btm_allequalimage; XLogRegisterBufData(2, (char *) &md, sizeof(xl_btree_metadata)); @@ -476,11 +546,10 @@ _bt_getroot(Relation rel, int access) rootblkno = rootopaque->btpo_next; } - /* Note: can't check btpo.level on deleted pages */ - if (rootopaque->btpo.level != rootlevel) + if (rootopaque->btpo_level != rootlevel) elog(ERROR, "root page %u of index \"%s\" has level %u, expected %u", rootblkno, RelationGetRelationName(rel), - rootopaque->btpo.level, rootlevel); + rootopaque->btpo_level, rootlevel); } /* @@ -580,11 +649,10 @@ _bt_gettrueroot(Relation rel) rootblkno = rootopaque->btpo_next; } - /* Note: can't check btpo.level on deleted pages */ - if (rootopaque->btpo.level != rootlevel) + if (rootopaque->btpo_level != rootlevel) elog(ERROR, "root page %u of index \"%s\" has level %u, expected %u", rootblkno, RelationGetRelationName(rel), - rootopaque->btpo.level, rootlevel); + rootopaque->btpo_level, rootlevel); return rootbuf; } @@ -757,7 +825,7 @@ _bt_checkpage(Relation rel, Buffer buf) * Log the reuse of a page from the FSM. */ static void -_bt_log_reuse_page(Relation rel, BlockNumber blkno, TransactionId latestRemovedXid) +_bt_log_reuse_page(Relation rel, BlockNumber blkno, FullTransactionId safexid) { xl_btree_reuse_page xlrec_reuse; @@ -770,7 +838,7 @@ _bt_log_reuse_page(Relation rel, BlockNumber blkno, TransactionId latestRemovedX /* XLOG stuff */ xlrec_reuse.node = rel->rd_node; xlrec_reuse.block = blkno; - xlrec_reuse.latestRemovedXid = latestRemovedXid; + xlrec_reuse.latestRemovedFullXid = safexid; XLogBeginInsert(); XLogRegisterData((char *) &xlrec_reuse, SizeOfBtreeReusePage); @@ -851,26 +919,34 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access) if (_bt_conditionallockbuf(rel, buf)) { page = BufferGetPage(buf); - if (_bt_page_recyclable(page)) + + /* + * It's possible to find an all-zeroes page in an index. For + * example, a backend might successfully extend the relation + * one page and then crash before it is able to make a WAL + * entry for adding the page. If we find a zeroed page then + * reclaim it immediately. + */ + if (PageIsNew(page)) + { + /* Okay to use page. Initialize and return it. */ + _bt_pageinit(page, BufferGetPageSize(buf)); + return buf; + } + + if (BTPageIsRecyclable(page)) { /* * If we are generating WAL for Hot Standby then create a * WAL record that will allow us to conflict with queries * running on standby, in case they have snapshots older - * than btpo.xact. This can only apply if the page does - * have a valid btpo.xact value, ie not if it's new. (We - * must check that because an all-zero page has no special - * space.) + * than safexid value */ - if (XLogStandbyInfoActive() && RelationNeedsWAL(rel) && - !PageIsNew(page)) - { - BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); - - _bt_log_reuse_page(rel, blkno, opaque->btpo.xact); - } + if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) + _bt_log_reuse_page(rel, blkno, + BTPageGetDeleteXid(page)); - /* Okay to use page. Re-initialize and return it */ + /* Okay to use page. Re-initialize and return it. */ _bt_pageinit(page, BufferGetPageSize(buf)); return buf; } @@ -978,22 +1054,22 @@ _bt_lockbuf(Relation rel, Buffer buf, int access) LockBuffer(buf, access); /* - * It doesn't matter that _bt_unlockbuf() won't get called in the - * event of an nbtree error (e.g. a unique violation error). That - * won't cause Valgrind false positives. + * It doesn't matter that _bt_unlockbuf() won't get called in the event of + * an nbtree error (e.g. a unique violation error). That won't cause + * Valgrind false positives. * - * The nbtree client requests are superimposed on top of the - * bufmgr.c buffer pin client requests. In the event of an nbtree - * error the buffer will certainly get marked as defined when the - * backend once again acquires its first pin on the buffer. (Of - * course, if the backend never touches the buffer again then it - * doesn't matter that it remains non-accessible to Valgrind.) + * The nbtree client requests are superimposed on top of the bufmgr.c + * buffer pin client requests. In the event of an nbtree error the buffer + * will certainly get marked as defined when the backend once again + * acquires its first pin on the buffer. (Of course, if the backend never + * touches the buffer again then it doesn't matter that it remains + * non-accessible to Valgrind.) * - * Note: When an IndexTuple C pointer gets computed using an - * ItemId read from a page while a lock was held, the C pointer - * becomes unsafe to dereference forever as soon as the lock is - * released. Valgrind can only detect cases where the pointer - * gets dereferenced with no _current_ lock/pin held, though. + * Note: When an IndexTuple C pointer gets computed using an ItemId read + * from a page while a lock was held, the C pointer becomes unsafe to + * dereference forever as soon as the lock is released. Valgrind can only + * detect cases where the pointer gets dereferenced with no _current_ + * lock/pin held, though. */ if (!RelationUsesLocalBuffers(rel)) VALGRIND_MAKE_MEM_DEFINED(BufferGetPage(buf), BLCKSZ); @@ -1068,40 +1144,6 @@ _bt_pageinit(Page page, Size size) PageInit(page, size, sizeof(BTPageOpaqueData)); } -/* - * _bt_page_recyclable() -- Is an existing page recyclable? - * - * This exists to make sure _bt_getbuf and btvacuumscan have the same - * policy about whether a page is safe to re-use. But note that _bt_getbuf - * knows enough to distinguish the PageIsNew condition from the other one. - * At some point it might be appropriate to redesign this to have a three-way - * result value. - */ -bool -_bt_page_recyclable(Page page) -{ - BTPageOpaque opaque; - - /* - * It's possible to find an all-zeroes page in an index --- for example, a - * backend might successfully extend the relation one page and then crash - * before it is able to make a WAL entry for adding the page. If we find a - * zeroed page then reclaim it. - */ - if (PageIsNew(page)) - return true; - - /* - * Otherwise, recycle if deleted and too old to have any processes - * interested in it. - */ - opaque = (BTPageOpaque) PageGetSpecialPointer(page); - if (P_ISDELETED(opaque) && - GlobalVisCheckRemovableXid(NULL, opaque->btpo.xact)) - return true; - return false; -} - /* * Delete item(s) from a btree leaf page during VACUUM. * @@ -1110,15 +1152,16 @@ _bt_page_recyclable(Page page) * sorted in ascending order. * * Routine deals with deleting TIDs when some (but not all) of the heap TIDs - * in an existing posting list item are to be removed by VACUUM. This works - * by updating/overwriting an existing item with caller's new version of the - * item (a version that lacks the TIDs that are to be deleted). + * in an existing posting list item are to be removed. This works by + * updating/overwriting an existing item with caller's new version of the item + * (a version that lacks the TIDs that are to be deleted). * * We record VACUUMs and b-tree deletes differently in WAL. Deletes must - * generate their own latestRemovedXid by accessing the heap directly, whereas - * VACUUMs rely on the initial heap scan taking care of it indirectly. Also, - * only VACUUM can perform granular deletes of individual TIDs in posting list - * tuples. + * generate their own latestRemovedXid by accessing the table directly, + * whereas VACUUMs rely on the initial VACUUM table scan performing + * WAL-logging that takes care of the issue for the table's indexes + * indirectly. Also, we remove the VACUUM cycle ID from pages, which b-tree + * deletes don't do. */ void _bt_delitems_vacuum(Relation rel, Buffer buf, @@ -1127,7 +1170,7 @@ _bt_delitems_vacuum(Relation rel, Buffer buf, { Page page = BufferGetPage(buf); BTPageOpaque opaque; - Size itemsz; + bool needswal = RelationNeedsWAL(rel); char *updatedbuf = NULL; Size updatedbuflen = 0; OffsetNumber updatedoffsets[MaxIndexTuplesPerPage]; @@ -1135,45 +1178,11 @@ _bt_delitems_vacuum(Relation rel, Buffer buf, /* Shouldn't be called unless there's something to do */ Assert(ndeletable > 0 || nupdatable > 0); - for (int i = 0; i < nupdatable; i++) - { - /* Replace work area IndexTuple with updated version */ - _bt_update_posting(updatable[i]); - - /* Maintain array of updatable page offsets for WAL record */ - updatedoffsets[i] = updatable[i]->updatedoffset; - } - - /* XLOG stuff -- allocate and fill buffer before critical section */ - if (nupdatable > 0 && RelationNeedsWAL(rel)) - { - Size offset = 0; - - for (int i = 0; i < nupdatable; i++) - { - BTVacuumPosting vacposting = updatable[i]; - - itemsz = SizeOfBtreeUpdate + - vacposting->ndeletedtids * sizeof(uint16); - updatedbuflen += itemsz; - } - - updatedbuf = palloc(updatedbuflen); - for (int i = 0; i < nupdatable; i++) - { - BTVacuumPosting vacposting = updatable[i]; - xl_btree_update update; - - update.ndeletedtids = vacposting->ndeletedtids; - memcpy(updatedbuf + offset, &update.ndeletedtids, - SizeOfBtreeUpdate); - offset += SizeOfBtreeUpdate; - - itemsz = update.ndeletedtids * sizeof(uint16); - memcpy(updatedbuf + offset, vacposting->deletetids, itemsz); - offset += itemsz; - } - } + /* Generate new version of posting lists without deleted TIDs */ + if (nupdatable > 0) + updatedbuf = _bt_delitems_update(updatable, nupdatable, + updatedoffsets, &updatedbuflen, + needswal); /* No ereport(ERROR) until changes are logged */ START_CRIT_SECTION(); @@ -1187,13 +1196,14 @@ _bt_delitems_vacuum(Relation rel, Buffer buf, * array of offset numbers. * * PageIndexTupleOverwrite() won't unset each item's LP_DEAD bit when it - * happens to already be set. Although we unset the BTP_HAS_GARBAGE page - * level flag, unsetting individual LP_DEAD bits should still be avoided. + * happens to already be set. It's important that we not interfere with + * _bt_delitems_delete(). */ for (int i = 0; i < nupdatable; i++) { OffsetNumber updatedoffset = updatedoffsets[i]; IndexTuple itup; + Size itemsz; itup = updatable[i]->itup; itemsz = MAXALIGN(IndexTupleSize(itup)); @@ -1215,27 +1225,19 @@ _bt_delitems_vacuum(Relation rel, Buffer buf, opaque->btpo_cycleid = 0; /* - * Mark the page as not containing any LP_DEAD items. This is not - * certainly true (there might be some that have recently been marked, but - * weren't targeted by VACUUM's heap scan), but it will be true often - * enough. VACUUM does not delete items purely because they have their - * LP_DEAD bit set, since doing so would necessitate explicitly logging a - * latestRemovedXid cutoff (this is how _bt_delitems_delete works). + * Clear the BTP_HAS_GARBAGE page flag. * - * The consequences of falsely unsetting BTP_HAS_GARBAGE should be fairly - * limited, since we never falsely unset an LP_DEAD bit. Workloads that - * are particularly dependent on LP_DEAD bits being set quickly will - * usually manage to set the BTP_HAS_GARBAGE flag before the page fills up - * again anyway. Furthermore, attempting a deduplication pass will remove - * all LP_DEAD items, regardless of whether the BTP_HAS_GARBAGE hint bit - * is set or not. + * This flag indicates the presence of LP_DEAD items on the page (though + * not reliably). Note that we only rely on it with pg_upgrade'd + * !heapkeyspace indexes. That's why clearing it here won't usually + * interfere with _bt_delitems_delete(). */ opaque->btpo_flags &= ~BTP_HAS_GARBAGE; MarkBufferDirty(buf); /* XLOG stuff */ - if (RelationNeedsWAL(rel)) + if (needswal) { XLogRecPtr recptr; xl_btree_vacuum xlrec_vacuum; @@ -1268,7 +1270,7 @@ _bt_delitems_vacuum(Relation rel, Buffer buf, /* can't leak memory here */ if (updatedbuf != NULL) pfree(updatedbuf); - /* free tuples generated by calling _bt_update_posting() */ + /* free tuples allocated within _bt_delitems_update() */ for (int i = 0; i < nupdatable; i++) pfree(updatable[i]->itup); } @@ -1277,67 +1279,103 @@ _bt_delitems_vacuum(Relation rel, Buffer buf, * Delete item(s) from a btree leaf page during single-page cleanup. * * This routine assumes that the caller has pinned and write locked the - * buffer. Also, the given deletable array *must* be sorted in ascending - * order. + * buffer. Also, the given deletable and updatable arrays *must* be sorted in + * ascending order. + * + * Routine deals with deleting TIDs when some (but not all) of the heap TIDs + * in an existing posting list item are to be removed. This works by + * updating/overwriting an existing item with caller's new version of the item + * (a version that lacks the TIDs that are to be deleted). * * This is nearly the same as _bt_delitems_vacuum as far as what it does to - * the page, but it needs to generate its own latestRemovedXid by accessing - * the heap. This is used by the REDO routine to generate recovery conflicts. - * Also, it doesn't handle posting list tuples unless the entire tuple can be - * deleted as a whole (since there is only one LP_DEAD bit per line pointer). + * the page, but it needs its own latestRemovedXid from caller (caller gets + * this from tableam). This is used by the REDO routine to generate recovery + * conflicts. The other difference is that only _bt_delitems_vacuum will + * clear page's VACUUM cycle ID. */ -void -_bt_delitems_delete(Relation rel, Buffer buf, +static void +_bt_delitems_delete(Relation rel, Buffer buf, TransactionId latestRemovedXid, OffsetNumber *deletable, int ndeletable, - Relation heapRel) + BTVacuumPosting *updatable, int nupdatable) { Page page = BufferGetPage(buf); BTPageOpaque opaque; - TransactionId latestRemovedXid = InvalidTransactionId; + bool needswal = RelationNeedsWAL(rel); + char *updatedbuf = NULL; + Size updatedbuflen = 0; + OffsetNumber updatedoffsets[MaxIndexTuplesPerPage]; /* Shouldn't be called unless there's something to do */ - Assert(ndeletable > 0); + Assert(ndeletable > 0 || nupdatable > 0); - if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) - latestRemovedXid = - _bt_xid_horizon(rel, heapRel, page, deletable, ndeletable); + /* Generate new versions of posting lists without deleted TIDs */ + if (nupdatable > 0) + updatedbuf = _bt_delitems_update(updatable, nupdatable, + updatedoffsets, &updatedbuflen, + needswal); /* No ereport(ERROR) until changes are logged */ START_CRIT_SECTION(); - /* Fix the page */ - PageIndexMultiDelete(page, deletable, ndeletable); + /* Handle updates and deletes just like _bt_delitems_vacuum */ + for (int i = 0; i < nupdatable; i++) + { + OffsetNumber updatedoffset = updatedoffsets[i]; + IndexTuple itup; + Size itemsz; + + itup = updatable[i]->itup; + itemsz = MAXALIGN(IndexTupleSize(itup)); + if (!PageIndexTupleOverwrite(page, updatedoffset, (Item) itup, + itemsz)) + elog(PANIC, "failed to update partially dead item in block %u of index \"%s\"", + BufferGetBlockNumber(buf), RelationGetRelationName(rel)); + } + + if (ndeletable > 0) + PageIndexMultiDelete(page, deletable, ndeletable); /* - * Unlike _bt_delitems_vacuum, we *must not* clear the vacuum cycle ID, - * because this is not called by VACUUM. Just clear the BTP_HAS_GARBAGE - * page flag, since we deleted all items with their LP_DEAD bit set. + * Unlike _bt_delitems_vacuum, we *must not* clear the vacuum cycle ID at + * this point. The VACUUM command alone controls vacuum cycle IDs. */ opaque = (BTPageOpaque) PageGetSpecialPointer(page); + + /* + * Clear the BTP_HAS_GARBAGE page flag. + * + * This flag indicates the presence of LP_DEAD items on the page (though + * not reliably). Note that we only rely on it with pg_upgrade'd + * !heapkeyspace indexes. + */ opaque->btpo_flags &= ~BTP_HAS_GARBAGE; MarkBufferDirty(buf); /* XLOG stuff */ - if (RelationNeedsWAL(rel)) + if (needswal) { XLogRecPtr recptr; xl_btree_delete xlrec_delete; xlrec_delete.latestRemovedXid = latestRemovedXid; xlrec_delete.ndeleted = ndeletable; + xlrec_delete.nupdated = nupdatable; XLogBeginInsert(); XLogRegisterBuffer(0, buf, REGBUF_STANDARD); XLogRegisterData((char *) &xlrec_delete, SizeOfBtreeDelete); - /* - * The deletable array is not in the buffer, but pretend that it is. - * When XLogInsert stores the whole buffer, the array need not be - * stored too. - */ - XLogRegisterBufData(0, (char *) deletable, - ndeletable * sizeof(OffsetNumber)); + if (ndeletable > 0) + XLogRegisterBufData(0, (char *) deletable, + ndeletable * sizeof(OffsetNumber)); + + if (nupdatable > 0) + { + XLogRegisterBufData(0, (char *) updatedoffsets, + nupdatable * sizeof(OffsetNumber)); + XLogRegisterBufData(0, updatedbuf, updatedbuflen); + } recptr = XLogInsert(RM_BTREE_ID, XLOG_BTREE_DELETE); @@ -1345,83 +1383,313 @@ _bt_delitems_delete(Relation rel, Buffer buf, } END_CRIT_SECTION(); + + /* can't leak memory here */ + if (updatedbuf != NULL) + pfree(updatedbuf); + /* free tuples allocated within _bt_delitems_update() */ + for (int i = 0; i < nupdatable; i++) + pfree(updatable[i]->itup); } /* - * Get the latestRemovedXid from the table entries pointed to by the non-pivot - * tuples being deleted. + * Set up state needed to delete TIDs from posting list tuples via "updating" + * the tuple. Performs steps common to both _bt_delitems_vacuum and + * _bt_delitems_delete. These steps must take place before each function's + * critical section begins. + * + * updatable and nupdatable are inputs, though note that we will use + * _bt_update_posting() to replace the original itup with a pointer to a final + * version in palloc()'d memory. Caller should free the tuples when its done. * - * This is a specialized version of index_compute_xid_horizon_for_tuples(). - * It's needed because btree tuples don't always store table TID using the - * standard index tuple header field. + * The first nupdatable entries from updatedoffsets are set to the page offset + * number for posting list tuples that caller updates. This is mostly useful + * because caller may need to WAL-log the page offsets (though we always do + * this for caller out of convenience). + * + * Returns buffer consisting of an array of xl_btree_update structs that + * describe the steps we perform here for caller (though only when needswal is + * true). Also sets *updatedbuflen to the final size of the buffer. This + * buffer is used by caller when WAL logging is required. */ -static TransactionId -_bt_xid_horizon(Relation rel, Relation heapRel, Page page, - OffsetNumber *deletable, int ndeletable) +static char * +_bt_delitems_update(BTVacuumPosting *updatable, int nupdatable, + OffsetNumber *updatedoffsets, Size *updatedbuflen, + bool needswal) { - TransactionId latestRemovedXid = InvalidTransactionId; - int spacenhtids; - int nhtids; - ItemPointer htids; - - /* Array will grow iff there are posting list tuples to consider */ - spacenhtids = ndeletable; - nhtids = 0; - htids = (ItemPointer) palloc(sizeof(ItemPointerData) * spacenhtids); - for (int i = 0; i < ndeletable; i++) + char *updatedbuf = NULL; + Size buflen = 0; + + /* Shouldn't be called unless there's something to do */ + Assert(nupdatable > 0); + + for (int i = 0; i < nupdatable; i++) { - ItemId itemid; - IndexTuple itup; + BTVacuumPosting vacposting = updatable[i]; + Size itemsz; - itemid = PageGetItemId(page, deletable[i]); - itup = (IndexTuple) PageGetItem(page, itemid); + /* Replace work area IndexTuple with updated version */ + _bt_update_posting(vacposting); - Assert(ItemIdIsDead(itemid)); - Assert(!BTreeTupleIsPivot(itup)); + /* Keep track of size of xl_btree_update for updatedbuf in passing */ + itemsz = SizeOfBtreeUpdate + vacposting->ndeletedtids * sizeof(uint16); + buflen += itemsz; - if (!BTreeTupleIsPosting(itup)) + /* Build updatedoffsets buffer in passing */ + updatedoffsets[i] = vacposting->updatedoffset; + } + + /* XLOG stuff */ + if (needswal) + { + Size offset = 0; + + /* Allocate, set final size for caller */ + updatedbuf = palloc(buflen); + *updatedbuflen = buflen; + for (int i = 0; i < nupdatable; i++) { - if (nhtids + 1 > spacenhtids) - { - spacenhtids *= 2; - htids = (ItemPointer) - repalloc(htids, sizeof(ItemPointerData) * spacenhtids); - } + BTVacuumPosting vacposting = updatable[i]; + Size itemsz; + xl_btree_update update; - Assert(ItemPointerIsValid(&itup->t_tid)); - ItemPointerCopy(&itup->t_tid, &htids[nhtids]); - nhtids++; + update.ndeletedtids = vacposting->ndeletedtids; + memcpy(updatedbuf + offset, &update.ndeletedtids, + SizeOfBtreeUpdate); + offset += SizeOfBtreeUpdate; + + itemsz = update.ndeletedtids * sizeof(uint16); + memcpy(updatedbuf + offset, vacposting->deletetids, itemsz); + offset += itemsz; } - else + } + + return updatedbuf; +} + +/* + * Comparator used by _bt_delitems_delete_check() to restore deltids array + * back to its original leaf-page-wise sort order + */ +static int +_bt_delitems_cmp(const void *a, const void *b) +{ + TM_IndexDelete *indexdelete1 = (TM_IndexDelete *) a; + TM_IndexDelete *indexdelete2 = (TM_IndexDelete *) b; + + if (indexdelete1->id > indexdelete2->id) + return 1; + if (indexdelete1->id < indexdelete2->id) + return -1; + + Assert(false); + + return 0; +} + +/* + * Try to delete item(s) from a btree leaf page during single-page cleanup. + * + * nbtree interface to table_index_delete_tuples(). Deletes a subset of index + * tuples from caller's deltids array: those whose TIDs are found safe to + * delete by the tableam (or already marked LP_DEAD in index, and so already + * known to be deletable by our simple index deletion caller). We physically + * delete index tuples from buf leaf page last of all (for index tuples where + * that is known to be safe following our table_index_delete_tuples() call). + * + * Simple index deletion caller only includes TIDs from index tuples marked + * LP_DEAD, as well as extra TIDs it found on the same leaf page that can be + * included without increasing the total number of distinct table blocks for + * the deletion operation as a whole. This approach often allows us to delete + * some extra index tuples that were practically free for tableam to check in + * passing (when they actually turn out to be safe to delete). It probably + * only makes sense for the tableam to go ahead with these extra checks when + * it is block-oriented (otherwise the checks probably won't be practically + * free, which we rely on). The tableam interface requires the tableam side + * to handle the problem, though, so this is okay (we as an index AM are free + * to make the simplifying assumption that all tableams must be block-based). + * + * Bottom-up index deletion caller provides all the TIDs from the leaf page, + * without expecting that tableam will check most of them. The tableam has + * considerable discretion around which entries/blocks it checks. Our role in + * costing the bottom-up deletion operation is strictly advisory. + * + * Note: Caller must have added deltids entries (i.e. entries that go in + * delstate's main array) in leaf-page-wise order: page offset number order, + * TID order among entries taken from the same posting list tuple (tiebreak on + * TID). This order is convenient to work with here. + * + * Note: We also rely on the id field of each deltids element "capturing" this + * original leaf-page-wise order. That is, we expect to be able to get back + * to the original leaf-page-wise order just by sorting deltids on the id + * field (tableam will sort deltids for its own reasons, so we'll need to put + * it back in leaf-page-wise order afterwards). + */ +void +_bt_delitems_delete_check(Relation rel, Buffer buf, Relation heapRel, + TM_IndexDeleteOp *delstate) +{ + Page page = BufferGetPage(buf); + TransactionId latestRemovedXid; + OffsetNumber postingidxoffnum = InvalidOffsetNumber; + int ndeletable = 0, + nupdatable = 0; + OffsetNumber deletable[MaxIndexTuplesPerPage]; + BTVacuumPosting updatable[MaxIndexTuplesPerPage]; + + /* Use tableam interface to determine which tuples to delete first */ + latestRemovedXid = table_index_delete_tuples(heapRel, delstate); + + /* Should not WAL-log latestRemovedXid unless it's required */ + if (!XLogStandbyInfoActive() || !RelationNeedsWAL(rel)) + latestRemovedXid = InvalidTransactionId; + + /* + * Construct a leaf-page-wise description of what _bt_delitems_delete() + * needs to do to physically delete index tuples from the page. + * + * Must sort deltids array to restore leaf-page-wise order (original order + * before call to tableam). This is the order that the loop expects. + * + * Note that deltids array might be a lot smaller now. It might even have + * no entries at all (with bottom-up deletion caller), in which case there + * is nothing left to do. + */ + qsort(delstate->deltids, delstate->ndeltids, sizeof(TM_IndexDelete), + _bt_delitems_cmp); + if (delstate->ndeltids == 0) + { + Assert(delstate->bottomup); + return; + } + + /* We definitely have to delete at least one index tuple (or one TID) */ + for (int i = 0; i < delstate->ndeltids; i++) + { + TM_IndexStatus *dstatus = delstate->status + delstate->deltids[i].id; + OffsetNumber idxoffnum = dstatus->idxoffnum; + ItemId itemid = PageGetItemId(page, idxoffnum); + IndexTuple itup = (IndexTuple) PageGetItem(page, itemid); + int nestedi, + nitem; + BTVacuumPosting vacposting; + + Assert(OffsetNumberIsValid(idxoffnum)); + + if (idxoffnum == postingidxoffnum) + { + /* + * This deltid entry is a TID from a posting list tuple that has + * already been completely processed + */ + Assert(BTreeTupleIsPosting(itup)); + Assert(ItemPointerCompare(BTreeTupleGetHeapTID(itup), + &delstate->deltids[i].tid) < 0); + Assert(ItemPointerCompare(BTreeTupleGetMaxHeapTID(itup), + &delstate->deltids[i].tid) >= 0); + continue; + } + + if (!BTreeTupleIsPosting(itup)) { - int nposting = BTreeTupleGetNPosting(itup); + /* Plain non-pivot tuple */ + Assert(ItemPointerEquals(&itup->t_tid, &delstate->deltids[i].tid)); + if (dstatus->knowndeletable) + deletable[ndeletable++] = idxoffnum; + continue; + } - if (nhtids + nposting > spacenhtids) + /* + * itup is a posting list tuple whose lowest deltids entry (which may + * or may not be for the first TID from itup) is considered here now. + * We should process all of the deltids entries for the posting list + * together now, though (not just the lowest). Remember to skip over + * later itup-related entries during later iterations of outermost + * loop. + */ + postingidxoffnum = idxoffnum; /* Remember work in outermost loop */ + nestedi = i; /* Initialize for first itup deltids entry */ + vacposting = NULL; /* Describes final action for itup */ + nitem = BTreeTupleGetNPosting(itup); + for (int p = 0; p < nitem; p++) + { + ItemPointer ptid = BTreeTupleGetPostingN(itup, p); + int ptidcmp = -1; + + /* + * This nested loop reuses work across ptid TIDs taken from itup. + * We take advantage of the fact that both itup's TIDs and deltids + * entries (within a single itup/posting list grouping) must both + * be in ascending TID order. + */ + for (; nestedi < delstate->ndeltids; nestedi++) { - spacenhtids = Max(spacenhtids * 2, nhtids + nposting); - htids = (ItemPointer) - repalloc(htids, sizeof(ItemPointerData) * spacenhtids); + TM_IndexDelete *tcdeltid = &delstate->deltids[nestedi]; + TM_IndexStatus *tdstatus = (delstate->status + tcdeltid->id); + + /* Stop once we get past all itup related deltids entries */ + Assert(tdstatus->idxoffnum >= idxoffnum); + if (tdstatus->idxoffnum != idxoffnum) + break; + + /* Skip past non-deletable itup related entries up front */ + if (!tdstatus->knowndeletable) + continue; + + /* Entry is first partial ptid match (or an exact match)? */ + ptidcmp = ItemPointerCompare(&tcdeltid->tid, ptid); + if (ptidcmp >= 0) + { + /* Greater than or equal (partial or exact) match... */ + break; + } } - for (int j = 0; j < nposting; j++) - { - ItemPointer htid = BTreeTupleGetPostingN(itup, j); + /* ...exact ptid match to a deletable deltids entry? */ + if (ptidcmp != 0) + continue; - Assert(ItemPointerIsValid(htid)); - ItemPointerCopy(htid, &htids[nhtids]); - nhtids++; + /* Exact match for deletable deltids entry -- ptid gets deleted */ + if (vacposting == NULL) + { + vacposting = palloc(offsetof(BTVacuumPostingData, deletetids) + + nitem * sizeof(uint16)); + vacposting->itup = itup; + vacposting->updatedoffset = idxoffnum; + vacposting->ndeletedtids = 0; } + vacposting->deletetids[vacposting->ndeletedtids++] = p; } - } - Assert(nhtids >= ndeletable); + /* Final decision on itup, a posting list tuple */ - latestRemovedXid = - table_compute_xid_horizon_for_tuples(heapRel, htids, nhtids); + if (vacposting == NULL) + { + /* No TIDs to delete from itup -- do nothing */ + } + else if (vacposting->ndeletedtids == nitem) + { + /* Straight delete of itup (to delete all TIDs) */ + deletable[ndeletable++] = idxoffnum; + /* Turns out we won't need granular information */ + pfree(vacposting); + } + else + { + /* Delete some (but not all) TIDs from itup */ + Assert(vacposting->ndeletedtids > 0 && + vacposting->ndeletedtids < nitem); + updatable[nupdatable++] = vacposting; + } + } - pfree(htids); + /* Physically delete tuples (or TIDs) using deletable (or updatable) */ + _bt_delitems_delete(rel, buf, latestRemovedXid, deletable, ndeletable, + updatable, nupdatable); - return latestRemovedXid; + /* be tidy */ + for (int i = 0; i < nupdatable; i++) + pfree(updatable[i]); } /* @@ -1531,24 +1799,22 @@ _bt_rightsib_halfdeadflag(Relation rel, BlockNumber leafrightsib) * should never pass a buffer containing an existing deleted page here. The * lock and pin on caller's buffer will be dropped before we return. * - * Returns the number of pages successfully deleted (zero if page cannot - * be deleted now; could be more than one if parent or right sibling pages - * were deleted too). Note that this does not include pages that we delete - * that the btvacuumscan scan has yet to reach; they'll get counted later - * instead. - * - * Maintains *oldestBtpoXact for any pages that get deleted. Caller is - * responsible for maintaining *oldestBtpoXact in the case of pages that were - * deleted by a previous VACUUM. + * Maintains bulk delete stats for caller, which are taken from vstate. We + * need to cooperate closely with caller here so that whole VACUUM operation + * reliably avoids any double counting of subsidiary-to-leafbuf pages that we + * delete in passing. If such pages happen to be from a block number that is + * ahead of the current scanblkno position, then caller is expected to count + * them directly later on. It's simpler for us to understand caller's + * requirements than it would be for caller to understand when or how a + * deleted page became deleted after the fact. * * NOTE: this leaks memory. Rather than trying to clean up everything * carefully, it's better to run it in a temp context that can be reset * frequently. */ -uint32 -_bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) +void +_bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate) { - uint32 ndeleted = 0; BlockNumber rightsib; bool rightsib_empty; Page page; @@ -1556,7 +1822,8 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) /* * Save original leafbuf block number from caller. Only deleted blocks - * that are <= scanblkno get counted in ndeleted return value. + * that are <= scanblkno are added to bulk delete stat's pages_deleted + * count. */ BlockNumber scanblkno = BufferGetBlockNumber(leafbuf); @@ -1618,7 +1885,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) RelationGetRelationName(rel)))); _bt_relbuf(rel, leafbuf); - return ndeleted; + return; } /* @@ -1648,7 +1915,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) Assert(!P_ISHALFDEAD(opaque)); _bt_relbuf(rel, leafbuf); - return ndeleted; + return; } /* @@ -1697,8 +1964,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) if (_bt_leftsib_splitflag(rel, leftsib, leafblkno)) { ReleaseBuffer(leafbuf); - Assert(ndeleted == 0); - return ndeleted; + return; } /* we need an insertion scan key for the search, so build one */ @@ -1739,7 +2005,7 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) if (!_bt_mark_page_halfdead(rel, leafbuf, stack)) { _bt_relbuf(rel, leafbuf); - return ndeleted; + return; } } @@ -1747,9 +2013,6 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) * Then unlink it from its siblings. Each call to * _bt_unlink_halfdead_page unlinks the topmost page from the subtree, * making it shallower. Iterate until the leafbuf page is deleted. - * - * _bt_unlink_halfdead_page should never fail, since we established - * that deletion is generally safe in _bt_mark_page_halfdead. */ rightsib_empty = false; Assert(P_ISLEAF(opaque) && P_ISHALFDEAD(opaque)); @@ -1757,17 +2020,22 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) { /* Check for interrupts in _bt_unlink_halfdead_page */ if (!_bt_unlink_halfdead_page(rel, leafbuf, scanblkno, - &rightsib_empty, oldestBtpoXact, - &ndeleted)) + &rightsib_empty, vstate)) { - /* _bt_unlink_halfdead_page failed, released buffer */ - return ndeleted; + /* + * _bt_unlink_halfdead_page should never fail, since we + * established that deletion is generally safe in + * _bt_mark_page_halfdead -- index must be corrupt. + * + * Note that _bt_unlink_halfdead_page already released the + * lock and pin on leafbuf for us. + */ + Assert(false); + return; } } Assert(P_ISLEAF(opaque) && P_ISDELETED(opaque)); - Assert(TransactionIdFollowsOrEquals(opaque->btpo.xact, - *oldestBtpoXact)); rightsib = opaque->btpo_next; @@ -1799,8 +2067,6 @@ _bt_pagedel(Relation rel, Buffer leafbuf, TransactionId *oldestBtpoXact) leafbuf = _bt_getbuf(rel, rightsib, BT_WRITE); } - - return ndeleted; } /* @@ -2028,12 +2294,6 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) * containing leafbuf. (We always set *rightsib_empty for caller, just to be * consistent.) * - * We maintain *oldestBtpoXact for pages that are deleted by the current - * VACUUM operation here. This must be handled here because we conservatively - * assume that there needs to be a new call to ReadNewTransactionId() each - * time a page gets deleted. See comments about the underlying assumption - * below. - * * Must hold pin and lock on leafbuf at entry (read or write doesn't matter). * On success exit, we'll be holding pin and write lock. On failure exit, * we'll release both pin and lock before returning (we define it that way @@ -2041,10 +2301,10 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) */ static bool _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, - bool *rightsib_empty, TransactionId *oldestBtpoXact, - uint32 *ndeleted) + bool *rightsib_empty, BTVacState *vstate) { BlockNumber leafblkno = BufferGetBlockNumber(leafbuf); + IndexBulkDeleteResult *stats = vstate->stats; BlockNumber leafleftsib; BlockNumber leafrightsib; BlockNumber target; @@ -2058,12 +2318,12 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, BTMetaPageData *metad = NULL; ItemId itemid; Page page; - PageHeader header; BTPageOpaque opaque; + FullTransactionId safexid; bool rightsib_is_rightmost; - int targetlevel; + uint32 targetlevel; IndexTuple leafhikey; - BlockNumber nextchild; + BlockNumber leaftopparent; page = BufferGetPage(leafbuf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); @@ -2107,7 +2367,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, page = BufferGetPage(buf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); leftsib = opaque->btpo_prev; - targetlevel = opaque->btpo.level; + targetlevel = opaque->btpo_level; Assert(targetlevel > 0); /* @@ -2124,11 +2384,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, * So, first lock the leaf page, if it's not the target. Then find and * write-lock the current left sibling of the target page. The sibling * that was current a moment ago could have split, so we may have to move - * right. This search could fail if either the sibling or the target page - * was deleted by someone else meanwhile; if so, give up. (Right now, - * that should never happen, since page deletion is only done in VACUUM - * and there shouldn't be multiple VACUUMs concurrently on the same - * table.) + * right. */ if (target != leafblkno) _bt_lockbuf(rel, leafbuf, BT_WRITE); @@ -2139,22 +2395,26 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, opaque = (BTPageOpaque) PageGetSpecialPointer(page); while (P_ISDELETED(opaque) || opaque->btpo_next != target) { - /* step right one page */ - leftsib = opaque->btpo_next; - _bt_relbuf(rel, lbuf); + bool leftsibvalid = true; /* - * It'd be good to check for interrupts here, but it's not easy to - * do so because a lock is always held. This block isn't - * frequently reached, so hopefully the consequences of not - * checking interrupts aren't too bad. + * Before we follow the link from the page that was the left + * sibling mere moments ago, validate its right link. This + * reduces the opportunities for loop to fail to ever make any + * progress in the presence of index corruption. + * + * Note: we rely on the assumption that there can only be one + * vacuum process running at a time (against the same index). */ + if (P_RIGHTMOST(opaque) || P_ISDELETED(opaque) || + leftsib == opaque->btpo_next) + leftsibvalid = false; + + leftsib = opaque->btpo_next; + _bt_relbuf(rel, lbuf); - if (leftsib == P_NONE) + if (!leftsibvalid) { - elog(LOG, "no left sibling (concurrent deletion?) of block %u in \"%s\"", - target, - RelationGetRelationName(rel)); if (target != leafblkno) { /* we have only a pin on target, but pin+lock on leafbuf */ @@ -2166,8 +2426,20 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, /* we have only a pin on leafbuf */ ReleaseBuffer(leafbuf); } + + ereport(LOG, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("valid left sibling for deletion target could not be located: " + "left sibling %u of target %u with leafblkno %u and scanblkno %u in index \"%s\"", + leftsib, target, leafblkno, scanblkno, + RelationGetRelationName(rel)))); + return false; } + + CHECK_FOR_INTERRUPTS(); + + /* step right one page */ lbuf = _bt_getbuf(rel, leftsib, BT_WRITE); page = BufferGetPage(lbuf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); @@ -2176,11 +2448,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, else lbuf = InvalidBuffer; - /* - * Next write-lock the target page itself. It's okay to take a write lock - * rather than a superexclusive lock, since no scan will stop on an empty - * page. - */ + /* Next write-lock the target page itself */ _bt_lockbuf(rel, buf, BT_WRITE); page = BufferGetPage(buf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); @@ -2191,37 +2459,47 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, * only one vacuum process running at a time. */ if (P_RIGHTMOST(opaque) || P_ISROOT(opaque) || P_ISDELETED(opaque)) - elog(ERROR, "half-dead page changed status unexpectedly in block %u of index \"%s\"", + elog(ERROR, "target page changed status unexpectedly in block %u of index \"%s\"", target, RelationGetRelationName(rel)); if (opaque->btpo_prev != leftsib) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg_internal("left link changed unexpectedly in block %u of index \"%s\"", - target, RelationGetRelationName(rel)))); + errmsg_internal("target page left link unexpectedly changed from %u to %u in block %u of index \"%s\"", + leftsib, opaque->btpo_prev, target, + RelationGetRelationName(rel)))); if (target == leafblkno) { if (P_FIRSTDATAKEY(opaque) <= PageGetMaxOffsetNumber(page) || !P_ISLEAF(opaque) || !P_ISHALFDEAD(opaque)) - elog(ERROR, "half-dead page changed status unexpectedly in block %u of index \"%s\"", + elog(ERROR, "target leaf page changed status unexpectedly in block %u of index \"%s\"", target, RelationGetRelationName(rel)); - nextchild = InvalidBlockNumber; + + /* Leaf page is also target page: don't set leaftopparent */ + leaftopparent = InvalidBlockNumber; } else { + IndexTuple finaldataitem; + if (P_FIRSTDATAKEY(opaque) != PageGetMaxOffsetNumber(page) || P_ISLEAF(opaque)) - elog(ERROR, "half-dead page changed status unexpectedly in block %u of index \"%s\"", - target, RelationGetRelationName(rel)); + elog(ERROR, "target internal page on level %u changed status unexpectedly in block %u of index \"%s\"", + targetlevel, target, RelationGetRelationName(rel)); - /* Remember the next non-leaf child down in the subtree */ + /* Target is internal: set leaftopparent for next call here... */ itemid = PageGetItemId(page, P_FIRSTDATAKEY(opaque)); - nextchild = BTreeTupleGetDownLink((IndexTuple) PageGetItem(page, itemid)); - if (nextchild == leafblkno) - nextchild = InvalidBlockNumber; + finaldataitem = (IndexTuple) PageGetItem(page, itemid); + leaftopparent = BTreeTupleGetDownLink(finaldataitem); + /* ...except when it would be a redundant pointer-to-self */ + if (leaftopparent == leafblkno) + leaftopparent = InvalidBlockNumber; } + /* No leaftopparent for level 0 (leaf page) or level 1 target */ + Assert(!BlockNumberIsValid(leaftopparent) || targetlevel > 1); + /* * And next write-lock the (current) right sibling. */ @@ -2309,13 +2587,13 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, * no lock was held. */ if (target != leafblkno) - BTreeTupleSetTopParent(leafhikey, nextchild); + BTreeTupleSetTopParent(leafhikey, leaftopparent); /* * Mark the page itself deleted. It can be recycled when all current * transactions are gone. Storing GetTopTransactionId() would work, but * we're in VACUUM and would not otherwise have an XID. Having already - * updated links to the target, ReadNewTransactionId() suffices as an + * updated links to the target, ReadNextFullTransactionId() suffices as an * upper bound. Any scan having retained a now-stale link is advertising * in its PGPROC an xmin less than or equal to the value we read here. It * will continue to do so, holding back the xmin horizon, for the duration @@ -2324,17 +2602,14 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, page = BufferGetPage(buf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); Assert(P_ISHALFDEAD(opaque) || !P_ISLEAF(opaque)); - opaque->btpo_flags &= ~BTP_HALF_DEAD; - opaque->btpo_flags |= BTP_DELETED; - opaque->btpo.xact = ReadNewTransactionId(); /* - * Remove the remaining tuples on the page. This keeps things simple for - * WAL consistency checking. + * Store upper bound XID that's used to determine when deleted page is no + * longer needed as a tombstone */ - header = (PageHeader) page; - header->pd_lower = SizeOfPageHeaderData; - header->pd_upper = header->pd_special; + safexid = ReadNextFullTransactionId(); + BTPageSetDeleted(page, safexid); + opaque->btpo_cycleid = 0; /* And update the metapage, if needed */ if (BufferIsValid(metabuf)) @@ -2372,15 +2647,16 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, if (target != leafblkno) XLogRegisterBuffer(3, leafbuf, REGBUF_WILL_INIT); - /* information on the unlinked block */ + /* information stored on the target/to-be-unlinked block */ xlrec.leftsib = leftsib; xlrec.rightsib = rightsib; - xlrec.btpo_xact = opaque->btpo.xact; + xlrec.level = targetlevel; + xlrec.safexid = safexid; /* information needed to recreate the leaf block (if not the target) */ xlrec.leafleftsib = leafleftsib; xlrec.leafrightsib = leafrightsib; - xlrec.topparent = nextchild; + xlrec.leaftopparent = leaftopparent; XLogRegisterData((char *) &xlrec, SizeOfBtreeUnlinkPage); @@ -2394,8 +2670,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, xlmeta.level = metad->btm_level; xlmeta.fastroot = metad->btm_fastroot; xlmeta.fastlevel = metad->btm_fastlevel; - xlmeta.oldest_btpo_xact = metad->btm_oldest_btpo_xact; - xlmeta.last_cleanup_num_heap_tuples = metad->btm_last_cleanup_num_heap_tuples; + xlmeta.last_cleanup_num_delpages = metad->btm_last_cleanup_num_delpages; xlmeta.allequalimage = metad->btm_allequalimage; XLogRegisterBufData(4, (char *) &xlmeta, sizeof(xl_btree_metadata)); @@ -2437,21 +2712,30 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, BlockNumber scanblkno, _bt_relbuf(rel, lbuf); _bt_relbuf(rel, rbuf); - if (!TransactionIdIsValid(*oldestBtpoXact) || - TransactionIdPrecedes(opaque->btpo.xact, *oldestBtpoXact)) - *oldestBtpoXact = opaque->btpo.xact; + /* If the target is not leafbuf, we're done with it now -- release it */ + if (target != leafblkno) + _bt_relbuf(rel, buf); /* - * If btvacuumscan won't revisit this page in a future btvacuumpage call - * and count it as deleted then, we count it as deleted by current - * btvacuumpage call + * Maintain pages_newly_deleted, which is simply the number of pages + * deleted by the ongoing VACUUM operation. + * + * Maintain pages_deleted in a way that takes into account how + * btvacuumpage() will count deleted pages that have yet to become + * scanblkno -- only count page when it's not going to get that treatment + * later on. */ + stats->pages_newly_deleted++; if (target <= scanblkno) - (*ndeleted)++; + stats->pages_deleted++; - /* If the target is not leafbuf, we're done with it now -- release it */ - if (target != leafblkno) - _bt_relbuf(rel, buf); + /* + * Remember information about the target page (now a newly deleted page) + * in dedicated vstate space for later. The page will be considered as a + * candidate to place in the FSM at the end of the current btvacuumscan() + * call. + */ + _bt_pendingfsm_add(vstate, target, safexid); return true; } @@ -2507,10 +2791,26 @@ _bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack, */ pbuf = _bt_getstackbuf(rel, stack, child); if (pbuf == InvalidBuffer) - ereport(ERROR, + { + /* + * Failed to "re-find" a pivot tuple whose downlink matched our child + * block number on the parent level -- the index must be corrupt. + * Don't even try to delete the leafbuf subtree. Just report the + * issue and press on with vacuuming the index. + * + * Note: _bt_getstackbuf() recovers from concurrent page splits that + * take place on the parent level. Its approach is a near-exhaustive + * linear search. This also gives it a surprisingly good chance of + * recovering in the event of a buggy or inconsistent opclass. But we + * don't rely on that here. + */ + ereport(LOG, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg_internal("failed to re-find parent key in index \"%s\" for deletion target page %u", RelationGetRelationName(rel), child))); + return false; + } + parent = stack->bts_blkno; parentoffset = stack->bts_offset; @@ -2597,3 +2897,177 @@ _bt_lock_subtree_parent(Relation rel, BlockNumber child, BTStack stack, subtreeparent, poffset, topparent, topparentrightsib); } + +/* + * Initialize local memory state used by VACUUM for _bt_pendingfsm_finalize + * optimization. + * + * Called at the start of a btvacuumscan(). Caller's cleanuponly argument + * indicates if ongoing VACUUM has not (and will not) call btbulkdelete(). + * + * We expect to allocate memory inside VACUUM's top-level memory context here. + * The working buffer is subject to a limit based on work_mem. Our strategy + * when the array can no longer grow within the bounds of that limit is to + * stop saving additional newly deleted pages, while proceeding as usual with + * the pages that we can fit. + */ +void +_bt_pendingfsm_init(Relation rel, BTVacState *vstate, bool cleanuponly) +{ + int64 maxbufsize; + + /* + * Don't bother with optimization in cleanup-only case -- we don't expect + * any newly deleted pages. Besides, cleanup-only calls to btvacuumscan() + * can only take place because this optimization didn't work out during + * the last VACUUM. + */ + if (cleanuponly) + return; + + /* + * Cap maximum size of array so that we always respect work_mem. Avoid + * int overflow here. + */ + vstate->bufsize = 256; + maxbufsize = (work_mem * 1024L) / sizeof(BTPendingFSM); + maxbufsize = Min(maxbufsize, INT_MAX); + maxbufsize = Min(maxbufsize, MaxAllocSize / sizeof(BTPendingFSM)); + /* Stay sane with small work_mem */ + maxbufsize = Max(maxbufsize, vstate->bufsize); + vstate->maxbufsize = maxbufsize; + + /* Allocate buffer, indicate that there are currently 0 pending pages */ + vstate->pendingpages = palloc(sizeof(BTPendingFSM) * vstate->bufsize); + vstate->npendingpages = 0; +} + +/* + * Place any newly deleted pages (i.e. pages that _bt_pagedel() deleted during + * the ongoing VACUUM operation) into the free space map -- though only when + * it is actually safe to do so by now. + * + * Called at the end of a btvacuumscan(), just before free space map vacuuming + * takes place. + * + * Frees memory allocated by _bt_pendingfsm_init(), if any. + */ +void +_bt_pendingfsm_finalize(Relation rel, BTVacState *vstate) +{ + IndexBulkDeleteResult *stats = vstate->stats; + + Assert(stats->pages_newly_deleted >= vstate->npendingpages); + + if (vstate->npendingpages == 0) + { + /* Just free memory when nothing to do */ + if (vstate->pendingpages) + pfree(vstate->pendingpages); + + return; + } + +#ifdef DEBUG_BTREE_PENDING_FSM + + /* + * Debugging aid: Sleep for 5 seconds to greatly increase the chances of + * placing pending pages in the FSM. Note that the optimization will + * never be effective without some other backend concurrently consuming an + * XID. + */ + pg_usleep(5000000L); +#endif + + /* + * Recompute VACUUM XID boundaries. + * + * We don't actually care about the oldest non-removable XID. Computing + * the oldest such XID has a useful side-effect that we rely on: it + * forcibly updates the XID horizon state for this backend. This step is + * essential; GlobalVisCheckRemovableFullXid() will not reliably recognize + * that it is now safe to recycle newly deleted pages without this step. + */ + GetOldestNonRemovableTransactionId(NULL); + + for (int i = 0; i < vstate->npendingpages; i++) + { + BlockNumber target = vstate->pendingpages[i].target; + FullTransactionId safexid = vstate->pendingpages[i].safexid; + + /* + * Do the equivalent of checking BTPageIsRecyclable(), but without + * accessing the page again a second time. + * + * Give up on finding the first non-recyclable page -- all later pages + * must be non-recyclable too, since _bt_pendingfsm_add() adds pages + * to the array in safexid order. + */ + if (!GlobalVisCheckRemovableFullXid(NULL, safexid)) + break; + + RecordFreeIndexPage(rel, target); + stats->pages_free++; + } + + pfree(vstate->pendingpages); +} + +/* + * Maintain array of pages that were deleted during current btvacuumscan() + * call, for use in _bt_pendingfsm_finalize() + */ +static void +_bt_pendingfsm_add(BTVacState *vstate, + BlockNumber target, + FullTransactionId safexid) +{ + Assert(vstate->npendingpages <= vstate->bufsize); + Assert(vstate->bufsize <= vstate->maxbufsize); + +#ifdef USE_ASSERT_CHECKING + + /* + * Verify an assumption made by _bt_pendingfsm_finalize(): pages from the + * array will always be in safexid order (since that is the order that we + * save them in here) + */ + if (vstate->npendingpages > 0) + { + FullTransactionId lastsafexid = + vstate->pendingpages[vstate->npendingpages - 1].safexid; + + Assert(FullTransactionIdFollowsOrEquals(safexid, lastsafexid)); + } +#endif + + /* + * If temp buffer reaches maxbufsize/work_mem capacity then we discard + * information about this page. + * + * Note that this also covers the case where we opted to not use the + * optimization in _bt_pendingfsm_init(). + */ + if (vstate->npendingpages == vstate->maxbufsize) + return; + + /* Consider enlarging buffer */ + if (vstate->npendingpages == vstate->bufsize) + { + int newbufsize = vstate->bufsize * 2; + + /* Respect work_mem */ + if (newbufsize > vstate->maxbufsize) + newbufsize = vstate->maxbufsize; + + vstate->bufsize = newbufsize; + vstate->pendingpages = + repalloc(vstate->pendingpages, + sizeof(BTPendingFSM) * vstate->bufsize); + } + + /* Save metadata for newly deleted page */ + vstate->pendingpages[vstate->npendingpages].target = target; + vstate->pendingpages[vstate->npendingpages].safexid = safexid; + vstate->npendingpages++; +} diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 1d6cd53f0d53..a37fc8cc0496 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -8,7 +8,7 @@ * This file contains only the public interface routines. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -42,19 +42,6 @@ #include "catalog/pg_namespace.h" -/* Working state needed by btvacuumpage */ -typedef struct -{ - IndexVacuumInfo *info; - IndexBulkDeleteResult *stats; - IndexBulkDeleteCallback callback; - void *callback_state; - BTCycleId cycleid; - BlockNumber totFreePages; /* true total # of free pages */ - TransactionId oldestBtpoXact; - MemoryContext pagedelcontext; -} BTVacState; - /* * BTPARALLEL_NOT_INITIALIZED indicates that the scan has not started. * @@ -271,6 +258,7 @@ bool btinsert(Relation rel, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { bool result; @@ -288,7 +276,7 @@ btinsert(Relation rel, Datum *values, bool *isnull, itup = index_form_tuple(RelationGetDescr(rel), values, isnull); itup->t_tid = *ht_ctid; - result = _bt_doinsert(rel, itup, checkUnique, heapRel); + result = _bt_doinsert(rel, itup, checkUnique, indexUnchanged, heapRel); pfree(itup); @@ -538,8 +526,7 @@ btrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, } /* - * Reset the scan keys. Note that keys ordering stuff moved to _bt_first. - * - vadim 05/05/97 + * Reset the scan keys */ if (scankey && scan->numberOfKeys > 0) memmove(scan->keyData, @@ -894,76 +881,6 @@ _bt_parallel_advance_array_keys(IndexScanDesc scan) * btvacuumscan (i.e. there will be no btvacuumscan call for this index at * all). Otherwise, a cleanup-only btvacuumscan call is required. */ -static bool -_bt_vacuum_needs_cleanup(IndexVacuumInfo *info) -{ - Buffer metabuf; - Page metapg; - BTMetaPageData *metad; - bool result = false; - - /* Return true directly on QE for stats collection from QD. */ - if (gp_vacuum_needs_update_stats()) - return true; - - metabuf = _bt_getbuf(info->index, BTREE_METAPAGE, BT_READ); - metapg = BufferGetPage(metabuf); - metad = BTPageGetMeta(metapg); - - /* - * XXX: If IndexVacuumInfo contained the heap relation, we could be more - * aggressive about vacuuming non catalog relations by passing the table - * to GlobalVisCheckRemovableXid(). - */ - - if (metad->btm_version < BTREE_NOVAC_VERSION) - { - /* - * Do cleanup if metapage needs upgrade, because we don't have - * cleanup-related meta-information yet. - */ - result = true; - } - else if (TransactionIdIsValid(metad->btm_oldest_btpo_xact) && - GlobalVisCheckRemovableXid(NULL, metad->btm_oldest_btpo_xact)) - { - /* - * If any oldest btpo.xact from a previously deleted page in the index - * is visible to everyone, then at least one deleted page can be - * recycled -- don't skip cleanup. - */ - result = true; - } - else - { - BTOptions *relopts; - float8 cleanup_scale_factor; - float8 prev_num_heap_tuples; - - /* - * If table receives enough insertions and no cleanup was performed, - * then index would appear have stale statistics. If scale factor is - * set, we avoid that by performing cleanup if the number of inserted - * tuples exceeds vacuum_cleanup_index_scale_factor fraction of - * original tuples count. - */ - relopts = (BTOptions *) info->index->rd_options; - cleanup_scale_factor = (relopts && - relopts->vacuum_cleanup_index_scale_factor >= 0) - ? relopts->vacuum_cleanup_index_scale_factor - : vacuum_cleanup_index_scale_factor; - prev_num_heap_tuples = metad->btm_last_cleanup_num_heap_tuples; - - if (cleanup_scale_factor <= 0 || - prev_num_heap_tuples <= 0 || - (info->num_heap_tuples - prev_num_heap_tuples) / - prev_num_heap_tuples >= cleanup_scale_factor) - result = true; - } - - _bt_relbuf(info->index, metabuf); - return result; -} /* * Bulk deletion of all index entries pointing to a set of heap tuples. @@ -1005,30 +922,64 @@ btbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteResult * btvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { + BlockNumber num_delpages; + /* No-op in ANALYZE ONLY mode */ if (info->analyze_only) return stats; /* - * If btbulkdelete was called, we need not do anything, just return the - * stats from the latest btbulkdelete call. If it wasn't called, we might - * still need to do a pass over the index, to recycle any newly-recyclable - * pages or to obtain index statistics. _bt_vacuum_needs_cleanup - * determines if either are needed. + * If btbulkdelete was called, we need not do anything (we just maintain + * the information used within _bt_vacuum_needs_cleanup() by calling + * _bt_set_cleanup_info() below). * - * Since we aren't going to actually delete any leaf items, there's no - * need to go through all the vacuum-cycle-ID pushups. + * If btbulkdelete was _not_ called, then we have a choice to make: we + * must decide whether or not a btvacuumscan() call is needed now (i.e. + * whether the ongoing VACUUM operation can entirely avoid a physical scan + * of the index). A call to _bt_vacuum_needs_cleanup() decides it for us + * now. */ if (stats == NULL) { - /* Check if we need a cleanup */ - if (!_bt_vacuum_needs_cleanup(info)) + /* Check if VACUUM operation can entirely avoid btvacuumscan() call */ + if (!_bt_vacuum_needs_cleanup(info->index)) return NULL; + /* + * Since we aren't going to actually delete any leaf items, there's no + * need to go through all the vacuum-cycle-ID pushups here. + * + * Posting list tuples are a source of inaccuracy for cleanup-only + * scans. btvacuumscan() will assume that the number of index tuples + * from each page can be used as num_index_tuples, even though + * num_index_tuples is supposed to represent the number of TIDs in the + * index. This naive approach can underestimate the number of tuples + * in the index significantly. + * + * We handle the problem by making num_index_tuples an estimate in + * cleanup-only case. + */ stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); btvacuumscan(info, stats, NULL, NULL, 0); + stats->estimated_count = true; } + /* + * Maintain num_delpages value in metapage for _bt_vacuum_needs_cleanup(). + * + * num_delpages is the number of deleted pages now in the index that were + * not safe to place in the FSM to be recycled just yet. num_delpages is + * greater than 0 only when _bt_pagedel() actually deleted pages during + * our call to btvacuumscan(). Even then, _bt_pendingfsm_finalize() must + * have failed to place any newly deleted pages in the FSM just moments + * ago. (Actually, there are edge cases where recycling of the current + * VACUUM's newly deleted pages does not even become safe by the time the + * next VACUUM comes around. See nbtree/README.) + */ + Assert(stats->pages_deleted >= stats->pages_free); + num_delpages = stats->pages_deleted - stats->pages_free; + _bt_set_cleanup_info(info->index, num_delpages); + /* * It's quite possible for us to be fooled by concurrent page splits into * double-counting some index tuples, so disbelieve any total that exceeds @@ -1052,8 +1003,6 @@ btvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) * deleted, and looking for old deleted pages that can be recycled. Both * btbulkdelete and btvacuumcleanup invoke this (the latter only if no * btbulkdelete call occurred and _bt_vacuum_needs_cleanup returned true). - * Note that this is also where the metadata used by _bt_vacuum_needs_cleanup - * is maintained. * * The caller is responsible for initially allocating/zeroing a stats struct * and for obtaining a vacuum cycle ID if necessary. @@ -1070,12 +1019,24 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, bool needLock; /* - * Reset counts that will be incremented during the scan; needed in case - * of multiple scans during a single VACUUM command + * Reset fields that track information about the entire index now. This + * avoids double-counting in the case where a single VACUUM command + * requires multiple scans of the index. + * + * Avoid resetting the tuples_removed and pages_newly_deleted fields here, + * since they track information about the VACUUM command, and so must last + * across each call to btvacuumscan(). + * + * (Note that pages_free is treated as state about the whole index, not + * the current VACUUM. This is appropriate because RecordFreeIndexPage() + * calls are idempotent, and get repeated for the same deleted pages in + * some scenarios. The point for us is to track the number of recyclable + * pages in the index at the end of the VACUUM command.) */ - stats->estimated_count = false; + stats->num_pages = 0; stats->num_index_tuples = 0; stats->pages_deleted = 0; + stats->pages_free = 0; /* Set up info to pass down to btvacuumpage */ vstate.info = info; @@ -1083,14 +1044,20 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, vstate.callback = callback; vstate.callback_state = callback_state; vstate.cycleid = cycleid; - vstate.totFreePages = 0; - vstate.oldestBtpoXact = InvalidTransactionId; /* Create a temporary memory context to run _bt_pagedel in */ vstate.pagedelcontext = AllocSetContextCreate(CurrentMemoryContext, "_bt_pagedel", ALLOCSET_DEFAULT_SIZES); + /* Initialize vstate fields used by _bt_pendingfsm_finalize */ + vstate.bufsize = 0; + vstate.maxbufsize = 0; + vstate.pendingpages = NULL; + vstate.npendingpages = 0; + /* Consider applying _bt_pendingfsm_finalize optimization */ + _bt_pendingfsm_init(rel, &vstate, (callback == NULL)); + /* * The outer loop iterates over all index pages except the metapage, in * physical order (we hope the kernel will cooperate in providing @@ -1143,41 +1110,23 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, } } + /* Set statistics num_pages field to final size of index */ + stats->num_pages = num_pages; + MemoryContextDelete(vstate.pagedelcontext); /* - * If we found any recyclable pages (and recorded them in the FSM), then - * forcibly update the upper-level FSM pages to ensure that searchers can - * find them. It's possible that the pages were also found during - * previous scans and so this is a waste of time, but it's cheap enough - * relative to scanning the index that it shouldn't matter much, and - * making sure that free pages are available sooner not later seems - * worthwhile. + * If there were any calls to _bt_pagedel() during scan of the index then + * see if any of the resulting pages can be placed in the FSM now. When + * it's not safe we'll have to leave it up to a future VACUUM operation. * - * Note that if no recyclable pages exist, we don't bother vacuuming the - * FSM at all. + * Finally, if we placed any pages in the FSM (either just now or during + * the scan), forcibly update the upper-level FSM pages to ensure that + * searchers can find them. */ - if (vstate.totFreePages > 0) + _bt_pendingfsm_finalize(rel, &vstate); + if (stats->pages_free > 0) IndexFreeSpaceMapVacuum(rel); - - /* - * Maintain the oldest btpo.xact and a count of the current number of heap - * tuples in the metapage (for the benefit of _bt_vacuum_needs_cleanup). - * - * The page with the oldest btpo.xact is typically a page deleted by this - * VACUUM operation, since pages deleted by a previous VACUUM operation - * tend to be placed in the FSM (by the current VACUUM operation) -- such - * pages are not candidates to be the oldest btpo.xact. (Note that pages - * placed in the FSM are reported as deleted pages in the bulk delete - * statistics, despite not counting as deleted pages for the purposes of - * determining the oldest btpo.xact.) - */ - _bt_update_meta_cleanup_info(rel, vstate.oldestBtpoXact, - info->num_heap_tuples); - - /* update statistics */ - stats->num_pages = num_pages; - stats->pages_free = vstate.totFreePages; } /* @@ -1283,13 +1232,12 @@ btvacuumpage(BTVacState *vstate, BlockNumber scanblkno) } } - /* Page is valid, see what to do with it */ - if (_bt_page_recyclable(page)) + if (!opaque || BTPageIsRecyclable(page)) { /* Okay to recycle this page (which could be leaf or internal) */ RecordFreeIndexPage(rel, blkno); - vstate->totFreePages++; stats->pages_deleted++; + stats->pages_free++; } else if (P_ISDELETED(opaque)) { @@ -1298,19 +1246,16 @@ btvacuumpage(BTVacState *vstate, BlockNumber scanblkno) * recycle yet. */ stats->pages_deleted++; - - /* Maintain the oldest btpo.xact */ - if (!TransactionIdIsValid(vstate->oldestBtpoXact) || - TransactionIdPrecedes(opaque->btpo.xact, vstate->oldestBtpoXact)) - vstate->oldestBtpoXact = opaque->btpo.xact; } else if (P_ISHALFDEAD(opaque)) { + /* Half-dead leaf page (from interrupted VACUUM) -- finish deleting */ + attempt_pagedel = true; + /* - * Half-dead leaf page. Try to delete now. Might update - * oldestBtpoXact and pages_deleted below. + * _bt_pagedel() will increment both pages_newly_deleted and + * pages_deleted stats in all cases (barring corruption) */ - attempt_pagedel = true; } else if (P_ISLEAF(opaque)) { @@ -1377,10 +1322,10 @@ btvacuumpage(BTVacState *vstate, BlockNumber scanblkno) * as long as the callback function only considers whether the * index tuple refers to pre-cutoff heap tuples that were * certainly already pruned away during VACUUM's initial heap - * scan by the time we get here. (XLOG_HEAP2_CLEANUP_INFO + * scan by the time we get here. (heapam's XLOG_HEAP2_PRUNE * records produce conflicts using a latestRemovedXid value - * for the entire VACUUM, so there is no need to produce our - * own conflict now.) + * for the pointed-to heap tuples, so there is no need to + * produce our own conflict now.) * * Backends with snapshots acquired after a VACUUM starts but * before it finishes could have visibility cutoff with a @@ -1495,14 +1440,21 @@ btvacuumpage(BTVacState *vstate, BlockNumber scanblkno) * separate live tuples). We don't delete when backtracking, though, * since that would require teaching _bt_pagedel() about backtracking * (doesn't seem worth adding more complexity to deal with that). + * + * We don't count the number of live TIDs during cleanup-only calls to + * btvacuumscan (i.e. when callback is not set). We count the number + * of index tuples directly instead. This avoids the expense of + * directly examining all of the tuples on each page. VACUUM will + * treat num_index_tuples as an estimate in cleanup-only case, so it + * doesn't matter that this underestimates num_index_tuples + * significantly in some cases. */ if (minoff > maxoff) attempt_pagedel = (blkno == scanblkno); - else if (callback == NULL) - /* GPDB_13_MERGE_FIXME: Commit 02c9386 has alternative fix */ - stats->num_index_tuples += maxoff - minoff + 1; - else + else if (callback) stats->num_index_tuples += nhtidslive; + else + stats->num_index_tuples += maxoff - minoff + 1; Assert(!attempt_pagedel || nhtidslive == 0); } @@ -1516,12 +1468,12 @@ btvacuumpage(BTVacState *vstate, BlockNumber scanblkno) oldcontext = MemoryContextSwitchTo(vstate->pagedelcontext); /* - * We trust the _bt_pagedel return value because it does not include - * any page that a future call here from btvacuumscan is expected to - * count. There will be no double-counting. + * _bt_pagedel maintains the bulk delete stats on our behalf; + * pages_newly_deleted and pages_deleted are likely to be incremented + * during call */ Assert(blkno == scanblkno); - stats->pages_deleted += _bt_pagedel(rel, buf, &vstate->oldestBtpoXact); + _bt_pagedel(rel, buf, vstate); MemoryContextSwitchTo(oldcontext); /* pagedel released buffer, so we shouldn't */ diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 28dc196b55e3..d1177d8772ce 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -4,7 +4,7 @@ * Search code for postgres btrees. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -169,7 +169,7 @@ _bt_search(Relation rel, BTScanInsert key, Buffer *bufP, int access, * we're on the level 1 and asked to lock leaf page in write mode, * then lock next page in write mode, because it must be a leaf. */ - if (opaque->btpo.level == 1 && access == BT_WRITE) + if (opaque->btpo_level == 1 && access == BT_WRITE) page_access = BT_WRITE; /* drop the read lock on the page, then acquire one on its child */ @@ -860,7 +860,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) ScanKeyData notnullkeys[INDEX_MAX_KEYS]; int keysCount = 0; int i; - bool status = true; + bool status; StrategyNumber strat_total; BTScanPosItem *currItem; BlockNumber blkno; @@ -880,7 +880,11 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) * never be satisfied (eg, x == 1 AND x > 2). */ if (!so->qual_ok) + { + /* Notify any other workers that we're done with this scan key. */ + _bt_parallel_done(scan); return false; + } /* * For parallel scans, get the starting page from shared state. If the @@ -1858,7 +1862,7 @@ _bt_steppage(IndexScanDesc scan, ScanDirection dir) { BTScanOpaque so = (BTScanOpaque) scan->opaque; BlockNumber blkno = InvalidBlockNumber; - bool status = true; + bool status; Assert(BTScanPosIsValid(so->currPos)); @@ -1967,7 +1971,7 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir) Relation rel; Page page; BTPageOpaque opaque; - bool status = true; + bool status; rel = scan->indexRelation; @@ -2337,9 +2341,9 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost, } /* Done? */ - if (opaque->btpo.level == level) + if (opaque->btpo_level == level) break; - if (opaque->btpo.level < level) + if (opaque->btpo_level < level) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg_internal("btree level %u not found in index \"%s\"", diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index ec856c45b543..f87d6880a68c 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -34,7 +34,7 @@ * This code isn't concerned about the FSM at all. The caller is responsible * for initializing that. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -49,7 +49,6 @@ #include "access/parallel.h" #include "access/relscan.h" #include "access/table.h" -#include "access/tableam.h" #include "access/xact.h" #include "access/xlog.h" #include "access/xloginsert.h" @@ -487,17 +486,17 @@ _bt_spools_heapscan(Relation heap, Relation index, BTBuildState *buildstate, * values set by table_index_build_scan */ { - const int index[] = { + const int progress_index[] = { PROGRESS_CREATEIDX_TUPLES_TOTAL, PROGRESS_SCAN_BLOCKS_TOTAL, PROGRESS_SCAN_BLOCKS_DONE }; - const int64 val[] = { + const int64 progress_vals[] = { buildstate->indtuples, 0, 0 }; - pgstat_progress_update_multi_param(3, index, val); + pgstat_progress_update_multi_param(3, progress_index, progress_vals); } /* okay, all heap tuples are spooled */ @@ -548,6 +547,7 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2) } #endif /* BTREE_BUILD_STATS */ + /* Execute the sort */ pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_BTREE_PHASE_PERFORMSORT_1); tuplesort_performsort(btspool->sortstate); @@ -621,7 +621,7 @@ _bt_blnewpage(uint32 level) /* Initialize BT opaque state */ opaque = (BTPageOpaque) PageGetSpecialPointer(page); opaque->btpo_prev = opaque->btpo_next = P_NONE; - opaque->btpo.level = level; + opaque->btpo_level = level; opaque->btpo_flags = (level > 0) ? 0 : BTP_LEAF; opaque->btpo_cycleid = 0; @@ -1466,7 +1466,6 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) WalUsage *walusage; BufferUsage *bufferusage; bool leaderparticipates = true; - char *sharedquery; int querylen; #ifdef DISABLE_LEADER_PARTICIPATION @@ -1533,9 +1532,14 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) shm_toc_estimate_keys(&pcxt->estimator, 1); /* Finally, estimate PARALLEL_KEY_QUERY_TEXT space */ - querylen = strlen(debug_query_string); - shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); - shm_toc_estimate_keys(&pcxt->estimator, 1); + if (debug_query_string) + { + querylen = strlen(debug_query_string); + shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); + shm_toc_estimate_keys(&pcxt->estimator, 1); + } + else + querylen = 0; /* keep compiler quiet */ /* Everyone's had a chance to ask for space, so now create the DSM */ InitializeParallelDSM(pcxt); @@ -1599,9 +1603,14 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) } /* Store query string for workers */ - sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); - memcpy(sharedquery, debug_query_string, querylen + 1); - shm_toc_insert(pcxt->toc, PARALLEL_KEY_QUERY_TEXT, sharedquery); + if (debug_query_string) + { + char *sharedquery; + + sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); + memcpy(sharedquery, debug_query_string, querylen + 1); + shm_toc_insert(pcxt->toc, PARALLEL_KEY_QUERY_TEXT, sharedquery); + } /* * Allocate space for each worker's WalUsage and BufferUsage; no need to @@ -1806,7 +1815,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc) #endif /* BTREE_BUILD_STATS */ /* Set debug_query_string for individual workers first */ - sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, false); + sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, true); debug_query_string = sharedquery; /* Report the query string from leader */ @@ -1963,16 +1972,18 @@ _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2, true, progress, _bt_build_callback, (void *) &buildstate, scan); - /* - * Execute this worker's part of the sort. - * - * Unlike leader and serial cases, we cannot avoid calling - * tuplesort_performsort() for spool2 if it ends up containing no dead - * tuples (this is disallowed for workers by tuplesort). - */ + /* Execute this worker's part of the sort */ + if (progress) + pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, + PROGRESS_BTREE_PHASE_PERFORMSORT_1); tuplesort_performsort(btspool->sortstate); if (btspool2) + { + if (progress) + pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, + PROGRESS_BTREE_PHASE_PERFORMSORT_2); tuplesort_performsort(btspool2->sortstate); + } /* * Done. Record ambuild statistics, and whether we encountered a broken diff --git a/src/backend/access/nbtree/nbtsplitloc.c b/src/backend/access/nbtree/nbtsplitloc.c index ef6dd1cf1920..3485e93ef647 100644 --- a/src/backend/access/nbtree/nbtsplitloc.c +++ b/src/backend/access/nbtree/nbtsplitloc.c @@ -3,7 +3,7 @@ * nbtsplitloc.c * Choose split point code for Postgres btree implementation. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index ee9beca91c6d..733a97a76dfc 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -3,7 +3,7 @@ * nbtutils.c * Utility code for Postgres btree implementation. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1877,7 +1877,8 @@ _bt_killitems(IndexScanDesc scan) * Since this can be redone later if needed, mark as dirty hint. * * Whenever we mark anything LP_DEAD, we also set the page's - * BTP_HAS_GARBAGE flag, which is likewise just a hint. + * BTP_HAS_GARBAGE flag, which is likewise just a hint. (Note that we + * only rely on the page-level flag in !heapkeyspace indexes.) */ if (killedsomething) { diff --git a/src/backend/access/nbtree/nbtvalidate.c b/src/backend/access/nbtree/nbtvalidate.c index 0b81f5a84e16..3a7f3bbfbd9a 100644 --- a/src/backend/access/nbtree/nbtvalidate.c +++ b/src/backend/access/nbtree/nbtvalidate.c @@ -3,7 +3,7 @@ * nbtvalidate.c * Opclass validator for btree. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c index 8e98c9a63a51..3f35df08796f 100644 --- a/src/backend/access/nbtree/nbtxlog.c +++ b/src/backend/access/nbtree/nbtxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for btrees. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -114,8 +114,8 @@ _bt_restore_meta(XLogReaderState *record, uint8 block_id) md->btm_fastlevel = xlrec->fastlevel; /* Cannot log BTREE_MIN_VERSION index metapage without upgrade */ Assert(md->btm_version >= BTREE_NOVAC_VERSION); - md->btm_oldest_btpo_xact = xlrec->oldest_btpo_xact; - md->btm_last_cleanup_num_heap_tuples = xlrec->last_cleanup_num_heap_tuples; + md->btm_last_cleanup_num_delpages = xlrec->last_cleanup_num_delpages; + md->btm_last_cleanup_num_heap_tuples = -1.0; md->btm_allequalimage = xlrec->allequalimage; pageop = (BTPageOpaque) PageGetSpecialPointer(metapg); @@ -299,7 +299,7 @@ btree_xlog_split(bool newitemonleft, XLogReaderState *record) ropaque->btpo_prev = origpagenumber; ropaque->btpo_next = spagenumber; - ropaque->btpo.level = xlrec->level; + ropaque->btpo_level = xlrec->level; ropaque->btpo_flags = isleaf ? BTP_LEAF : 0; ropaque->btpo_cycleid = 0; @@ -558,6 +558,47 @@ btree_xlog_dedup(XLogReaderState *record) UnlockReleaseBuffer(buf); } +static void +btree_xlog_updates(Page page, OffsetNumber *updatedoffsets, + xl_btree_update *updates, int nupdated) +{ + BTVacuumPosting vacposting; + IndexTuple origtuple; + ItemId itemid; + Size itemsz; + + for (int i = 0; i < nupdated; i++) + { + itemid = PageGetItemId(page, updatedoffsets[i]); + origtuple = (IndexTuple) PageGetItem(page, itemid); + + vacposting = palloc(offsetof(BTVacuumPostingData, deletetids) + + updates->ndeletedtids * sizeof(uint16)); + vacposting->updatedoffset = updatedoffsets[i]; + vacposting->itup = origtuple; + vacposting->ndeletedtids = updates->ndeletedtids; + memcpy(vacposting->deletetids, + (char *) updates + SizeOfBtreeUpdate, + updates->ndeletedtids * sizeof(uint16)); + + _bt_update_posting(vacposting); + + /* Overwrite updated version of tuple */ + itemsz = MAXALIGN(IndexTupleSize(vacposting->itup)); + if (!PageIndexTupleOverwrite(page, updatedoffsets[i], + (Item) vacposting->itup, itemsz)) + elog(PANIC, "failed to update partially dead item"); + + pfree(vacposting->itup); + pfree(vacposting); + + /* advance to next xl_btree_update from array */ + updates = (xl_btree_update *) + ((char *) updates + SizeOfBtreeUpdate + + updates->ndeletedtids * sizeof(uint16)); + } +} + static void btree_xlog_vacuum(XLogReaderState *record) { @@ -591,41 +632,7 @@ btree_xlog_vacuum(XLogReaderState *record) xlrec->nupdated * sizeof(OffsetNumber)); - for (int i = 0; i < xlrec->nupdated; i++) - { - BTVacuumPosting vacposting; - IndexTuple origtuple; - ItemId itemid; - Size itemsz; - - itemid = PageGetItemId(page, updatedoffsets[i]); - origtuple = (IndexTuple) PageGetItem(page, itemid); - - vacposting = palloc(offsetof(BTVacuumPostingData, deletetids) + - updates->ndeletedtids * sizeof(uint16)); - vacposting->updatedoffset = updatedoffsets[i]; - vacposting->itup = origtuple; - vacposting->ndeletedtids = updates->ndeletedtids; - memcpy(vacposting->deletetids, - (char *) updates + SizeOfBtreeUpdate, - updates->ndeletedtids * sizeof(uint16)); - - _bt_update_posting(vacposting); - - /* Overwrite updated version of tuple */ - itemsz = MAXALIGN(IndexTupleSize(vacposting->itup)); - if (!PageIndexTupleOverwrite(page, updatedoffsets[i], - (Item) vacposting->itup, itemsz)) - elog(PANIC, "failed to update partially dead item"); - - pfree(vacposting->itup); - pfree(vacposting); - - /* advance to next xl_btree_update from array */ - updates = (xl_btree_update *) - ((char *) updates + SizeOfBtreeUpdate + - updates->ndeletedtids * sizeof(uint16)); - } + btree_xlog_updates(page, updatedoffsets, updates, xlrec->nupdated); } if (xlrec->ndeleted > 0) @@ -677,7 +684,22 @@ btree_xlog_delete(XLogReaderState *record) page = (Page) BufferGetPage(buffer); - PageIndexMultiDelete(page, (OffsetNumber *) ptr, xlrec->ndeleted); + if (xlrec->nupdated > 0) + { + OffsetNumber *updatedoffsets; + xl_btree_update *updates; + + updatedoffsets = (OffsetNumber *) + (ptr + xlrec->ndeleted * sizeof(OffsetNumber)); + updates = (xl_btree_update *) ((char *) updatedoffsets + + xlrec->nupdated * + sizeof(OffsetNumber)); + + btree_xlog_updates(page, updatedoffsets, updates, xlrec->nupdated); + } + + if (xlrec->ndeleted > 0) + PageIndexMultiDelete(page, (OffsetNumber *) ptr, xlrec->ndeleted); /* Mark the page as not containing any LP_DEAD items */ opaque = (BTPageOpaque) PageGetSpecialPointer(page); @@ -753,7 +775,7 @@ btree_xlog_mark_page_halfdead(uint8 info, XLogReaderState *record) pageop->btpo_prev = xlrec->leftblk; pageop->btpo_next = xlrec->rightblk; - pageop->btpo.level = 0; + pageop->btpo_level = 0; pageop->btpo_flags = BTP_HALF_DEAD | BTP_LEAF; pageop->btpo_cycleid = 0; @@ -782,6 +804,9 @@ btree_xlog_unlink_page(uint8 info, XLogReaderState *record) xl_btree_unlink_page *xlrec = (xl_btree_unlink_page *) XLogRecGetData(record); BlockNumber leftsib; BlockNumber rightsib; + uint32 level; + bool isleaf; + FullTransactionId safexid; Buffer leftbuf; Buffer target; Buffer rightbuf; @@ -790,6 +815,12 @@ btree_xlog_unlink_page(uint8 info, XLogReaderState *record) leftsib = xlrec->leftsib; rightsib = xlrec->rightsib; + level = xlrec->level; + isleaf = (level == 0); + safexid = xlrec->safexid; + + /* No leaftopparent for level 0 (leaf page) or level 1 target */ + Assert(!BlockNumberIsValid(xlrec->leaftopparent) || level > 1); /* * In normal operation, we would lock all the pages this WAL record @@ -824,8 +855,10 @@ btree_xlog_unlink_page(uint8 info, XLogReaderState *record) pageop->btpo_prev = leftsib; pageop->btpo_next = rightsib; - pageop->btpo.xact = xlrec->btpo_xact; - pageop->btpo_flags = BTP_DELETED; + pageop->btpo_level = level; + BTPageSetDeleted(page, safexid); + if (isleaf) + pageop->btpo_flags |= BTP_LEAF; pageop->btpo_cycleid = 0; PageSetLSN(page, lsn); @@ -867,8 +900,10 @@ btree_xlog_unlink_page(uint8 info, XLogReaderState *record) * top parent link when deleting leafbuf because it's the last page * we'll delete in the subtree undergoing deletion. */ - Buffer leafbuf; - IndexTupleData trunctuple; + Buffer leafbuf; + IndexTupleData trunctuple; + + Assert(!isleaf); leafbuf = XLogInitBufferForRedo(record, 3); page = (Page) BufferGetPage(leafbuf); @@ -879,13 +914,13 @@ btree_xlog_unlink_page(uint8 info, XLogReaderState *record) pageop->btpo_flags = BTP_HALF_DEAD | BTP_LEAF; pageop->btpo_prev = xlrec->leafleftsib; pageop->btpo_next = xlrec->leafrightsib; - pageop->btpo.level = 0; + pageop->btpo_level = 0; pageop->btpo_cycleid = 0; /* Add a dummy hikey item */ MemSet(&trunctuple, 0, sizeof(IndexTupleData)); trunctuple.t_info = sizeof(IndexTupleData); - BTreeTupleSetTopParent(&trunctuple, xlrec->topparent); + BTreeTupleSetTopParent(&trunctuple, xlrec->leaftopparent); if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY, false, false) == InvalidOffsetNumber) @@ -920,7 +955,7 @@ btree_xlog_newroot(XLogReaderState *record) pageop->btpo_flags = BTP_ROOT; pageop->btpo_prev = pageop->btpo_next = P_NONE; - pageop->btpo.level = xlrec->level; + pageop->btpo_level = xlrec->level; if (xlrec->level == 0) pageop->btpo_flags |= BTP_LEAF; pageop->btpo_cycleid = 0; @@ -941,26 +976,40 @@ btree_xlog_newroot(XLogReaderState *record) _bt_restore_meta(record, 2); } +/* + * In general VACUUM must defer recycling as a way of avoiding certain race + * conditions. Deleted pages contain a safexid value that is used by VACUUM + * to determine whether or not it's safe to place a page that was deleted by + * VACUUM earlier into the FSM now. See nbtree/README. + * + * As far as any backend operating during original execution is concerned, the + * FSM is a cache of recycle-safe pages; the mere presence of the page in the + * FSM indicates that the page must already be safe to recycle (actually, + * _bt_getbuf() verifies it's safe using BTPageIsRecyclable(), but that's just + * because it would be unwise to completely trust the FSM, given its current + * limitations). + * + * This isn't sufficient to prevent similar concurrent recycling race + * conditions during Hot Standby, though. For that we need to log a + * xl_btree_reuse_page record at the point that a page is actually recycled + * and reused for an entirely unrelated page inside _bt_split(). These + * records include the same safexid value from the original deleted page, + * stored in the record's latestRemovedFullXid field. + * + * The GlobalVisCheckRemovableFullXid() test in BTPageIsRecyclable() is used + * to determine if it's safe to recycle a page. This mirrors our own test: + * the PGPROC->xmin > limitXmin test inside GetConflictingVirtualXIDs(). + * Consequently, one XID value achieves the same exclusion effect on primary + * and standby. + */ static void btree_xlog_reuse_page(XLogReaderState *record) { xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) XLogRecGetData(record); - /* - * Btree reuse_page records exist to provide a conflict point when we - * reuse pages in the index via the FSM. That's all they do though. - * - * latestRemovedXid was the page's btpo.xact. The - * GlobalVisCheckRemovableXid test in _bt_page_recyclable() conceptually - * mirrors the pgxact->xmin > limitXmin test in - * GetConflictingVirtualXIDs(). Consequently, one XID value achieves the - * same exclusion effect on primary and standby. - */ if (InHotStandby) - { - ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid, - xlrec->node); - } + ResolveRecoveryConflictWithSnapshotFullXid(xlrec->latestRemovedFullXid, + xlrec->node); } void @@ -1065,7 +1114,8 @@ btree_mask(char *pagedata, BlockNumber blkno) /* * BTP_HAS_GARBAGE is just an un-logged hint bit. So, mask it. See - * _bt_killitems(), _bt_check_unique() for details. + * _bt_delete_or_dedup_one_page(), _bt_killitems(), and _bt_check_unique() + * for details. */ maskopaq->btpo_flags &= ~BTP_HAS_GARBAGE; diff --git a/src/backend/access/rmgrdesc/brindesc.c b/src/backend/access/rmgrdesc/brindesc.c index 0dc56e554961..b6265a49bc06 100644 --- a/src/backend/access/rmgrdesc/brindesc.c +++ b/src/backend/access/rmgrdesc/brindesc.c @@ -3,7 +3,7 @@ * brindesc.c * rmgr descriptor routines for BRIN indexes * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/clogdesc.c b/src/backend/access/rmgrdesc/clogdesc.c index fb510e4cd191..b12f43a1bba2 100644 --- a/src/backend/access/rmgrdesc/clogdesc.c +++ b/src/backend/access/rmgrdesc/clogdesc.c @@ -3,7 +3,7 @@ * clogdesc.c * rmgr descriptor routines for access/transam/clog.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/committsdesc.c b/src/backend/access/rmgrdesc/committsdesc.c index c8bdae761abc..26bad44b964a 100644 --- a/src/backend/access/rmgrdesc/committsdesc.c +++ b/src/backend/access/rmgrdesc/committsdesc.c @@ -3,7 +3,7 @@ * committsdesc.c * rmgr descriptor routines for access/transam/commit_ts.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -38,31 +38,6 @@ commit_ts_desc(StringInfo buf, XLogReaderState *record) appendStringInfo(buf, "pageno %d, oldestXid %u", trunc->pageno, trunc->oldestXid); } - else if (info == COMMIT_TS_SETTS) - { - xl_commit_ts_set *xlrec = (xl_commit_ts_set *) rec; - int nsubxids; - - appendStringInfo(buf, "set %s/%d for: %u", - timestamptz_to_str(xlrec->timestamp), - xlrec->nodeid, - xlrec->mainxid); - nsubxids = ((XLogRecGetDataLen(record) - SizeOfCommitTsSet) / - sizeof(TransactionId)); - if (nsubxids > 0) - { - int i; - TransactionId *subxids; - - subxids = palloc(sizeof(TransactionId) * nsubxids); - memcpy(subxids, - XLogRecGetData(record) + SizeOfCommitTsSet, - sizeof(TransactionId) * nsubxids); - for (i = 0; i < nsubxids; i++) - appendStringInfo(buf, ", %u", subxids[i]); - pfree(subxids); - } - } } const char * @@ -74,8 +49,6 @@ commit_ts_identify(uint8 info) return "ZEROPAGE"; case COMMIT_TS_TRUNCATE: return "TRUNCATE"; - case COMMIT_TS_SETTS: - return "SETTS"; default: return NULL; } diff --git a/src/backend/access/rmgrdesc/dbasedesc.c b/src/backend/access/rmgrdesc/dbasedesc.c index d82484b9db40..26609845aac6 100644 --- a/src/backend/access/rmgrdesc/dbasedesc.c +++ b/src/backend/access/rmgrdesc/dbasedesc.c @@ -3,7 +3,7 @@ * dbasedesc.c * rmgr descriptor routines for commands/dbcommands.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -37,7 +37,7 @@ dbase_desc(StringInfo buf, XLogReaderState *record) xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec; int i; - appendStringInfo(buf, "dir"); + appendStringInfoString(buf, "dir"); for (i = 0; i < xlrec->ntablespaces; i++) appendStringInfo(buf, " %u/%u", xlrec->tablespace_ids[i], xlrec->db_id); diff --git a/src/backend/access/rmgrdesc/genericdesc.c b/src/backend/access/rmgrdesc/genericdesc.c index f0fd4286195e..7242d0d21417 100644 --- a/src/backend/access/rmgrdesc/genericdesc.c +++ b/src/backend/access/rmgrdesc/genericdesc.c @@ -4,7 +4,7 @@ * rmgr descriptor routines for access/transam/generic_xlog.c * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/rmgrdesc/genericdesc.c diff --git a/src/backend/access/rmgrdesc/gindesc.c b/src/backend/access/rmgrdesc/gindesc.c index 9ab0d8e1f7e7..ee9e69cdd094 100644 --- a/src/backend/access/rmgrdesc/gindesc.c +++ b/src/backend/access/rmgrdesc/gindesc.c @@ -3,7 +3,7 @@ * gindesc.c * rmgr descriptor routines for access/transam/gin/ginxlog.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/gistdesc.c b/src/backend/access/rmgrdesc/gistdesc.c index de309fb1227e..8ae31126ebf9 100644 --- a/src/backend/access/rmgrdesc/gistdesc.c +++ b/src/backend/access/rmgrdesc/gistdesc.c @@ -3,7 +3,7 @@ * gistdesc.c * rmgr descriptor routines for access/gist/gistxlog.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/hashdesc.c b/src/backend/access/rmgrdesc/hashdesc.c index f7728850419c..90ccea08e2c4 100644 --- a/src/backend/access/rmgrdesc/hashdesc.c +++ b/src/backend/access/rmgrdesc/hashdesc.c @@ -3,7 +3,7 @@ * hashdesc.c * rmgr descriptor routines for access/hash/hash.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -113,7 +113,7 @@ hash_desc(StringInfo buf, XLogReaderState *record) { xl_hash_vacuum_one_page *xlrec = (xl_hash_vacuum_one_page *) rec; - appendStringInfo(buf, "ntuples %d, latest removed xid %u", + appendStringInfo(buf, "ntuples %d, latestRemovedXid %u", xlrec->ntuples, xlrec->latestRemovedXid); break; diff --git a/src/backend/access/rmgrdesc/heapdesc.c b/src/backend/access/rmgrdesc/heapdesc.c index c241ec1836b5..1a5b8f7902e8 100644 --- a/src/backend/access/rmgrdesc/heapdesc.c +++ b/src/backend/access/rmgrdesc/heapdesc.c @@ -3,7 +3,7 @@ * heapdesc.c * rmgr descriptor routines for access/heap/heapam.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -122,11 +122,20 @@ heap2_desc(StringInfo buf, XLogReaderState *record) uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK; info &= XLOG_HEAP_OPMASK; - if (info == XLOG_HEAP2_CLEAN) + if (info == XLOG_HEAP2_PRUNE) { - xl_heap_clean *xlrec = (xl_heap_clean *) rec; + xl_heap_prune *xlrec = (xl_heap_prune *) rec; - appendStringInfo(buf, "remxid %u", xlrec->latestRemovedXid); + appendStringInfo(buf, "latestRemovedXid %u nredirected %u ndead %u", + xlrec->latestRemovedXid, + xlrec->nredirected, + xlrec->ndead); + } + else if (info == XLOG_HEAP2_VACUUM) + { + xl_heap_vacuum *xlrec = (xl_heap_vacuum *) rec; + + appendStringInfo(buf, "nunused %u", xlrec->nunused); } else if (info == XLOG_HEAP2_FREEZE_PAGE) { @@ -135,12 +144,6 @@ heap2_desc(StringInfo buf, XLogReaderState *record) appendStringInfo(buf, "cutoff xid %u ntuples %u", xlrec->cutoff_xid, xlrec->ntuples); } - else if (info == XLOG_HEAP2_CLEANUP_INFO) - { - xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec; - - appendStringInfo(buf, "remxid %u", xlrec->latestRemovedXid); - } else if (info == XLOG_HEAP2_VISIBLE) { xl_heap_visible *xlrec = (xl_heap_visible *) rec; @@ -230,15 +233,15 @@ heap2_identify(uint8 info) switch (info & ~XLR_INFO_MASK) { - case XLOG_HEAP2_CLEAN: - id = "CLEAN"; + case XLOG_HEAP2_PRUNE: + id = "PRUNE"; + break; + case XLOG_HEAP2_VACUUM: + id = "VACUUM"; break; case XLOG_HEAP2_FREEZE_PAGE: id = "FREEZE_PAGE"; break; - case XLOG_HEAP2_CLEANUP_INFO: - id = "CLEANUP_INFO"; - break; case XLOG_HEAP2_VISIBLE: id = "VISIBLE"; break; diff --git a/src/backend/access/rmgrdesc/logicalmsgdesc.c b/src/backend/access/rmgrdesc/logicalmsgdesc.c index bff298c9287f..d64ce2e7eff2 100644 --- a/src/backend/access/rmgrdesc/logicalmsgdesc.c +++ b/src/backend/access/rmgrdesc/logicalmsgdesc.c @@ -3,7 +3,7 @@ * logicalmsgdesc.c * rmgr descriptor routines for replication/logical/message.c * - * Portions Copyright (c) 2015-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2015-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -24,10 +24,21 @@ logicalmsg_desc(StringInfo buf, XLogReaderState *record) if (info == XLOG_LOGICAL_MESSAGE) { xl_logical_message *xlrec = (xl_logical_message *) rec; + char *prefix = xlrec->message; + char *message = xlrec->message + xlrec->prefix_size; + char *sep = ""; - appendStringInfo(buf, "%s message size %zu bytes", - xlrec->transactional ? "transactional" : "nontransactional", - xlrec->message_size); + Assert(prefix[xlrec->prefix_size] != '\0'); + + appendStringInfo(buf, "%s, prefix \"%s\"; payload (%zu bytes): ", + xlrec->transactional ? "transactional" : "non-transactional", + prefix, xlrec->message_size); + /* Write message payload as a series of hex bytes */ + for (int cnt = 0; cnt < xlrec->message_size; cnt++) + { + appendStringInfo(buf, "%s%02X", sep, (unsigned char) message[cnt]); + sep = " "; + } } } diff --git a/src/backend/access/rmgrdesc/mxactdesc.c b/src/backend/access/rmgrdesc/mxactdesc.c index 4dd6d7d1f4f1..8c37690e659d 100644 --- a/src/backend/access/rmgrdesc/mxactdesc.c +++ b/src/backend/access/rmgrdesc/mxactdesc.c @@ -3,7 +3,7 @@ * mxactdesc.c * rmgr descriptor routines for access/transam/multixact.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/nbtdesc.c b/src/backend/access/rmgrdesc/nbtdesc.c index 2b07e887cfdf..e8b0b98372f3 100644 --- a/src/backend/access/rmgrdesc/nbtdesc.c +++ b/src/backend/access/rmgrdesc/nbtdesc.c @@ -3,7 +3,7 @@ * nbtdesc.c * rmgr descriptor routines for access/nbtree/nbtxlog.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -130,9 +130,8 @@ btree_desc(StringInfo buf, XLogReaderState *record) { xl_btree_delete *xlrec = (xl_btree_delete *) rec; - appendStringInfo(buf, "latestRemovedXid %u; ndeleted %u", - xlrec->latestRemovedXid, xlrec->ndeleted); - out_delete(buf, record); + appendStringInfo(buf, "latestRemovedXid %u; ndeleted %u; nupdated %u", + xlrec->latestRemovedXid, xlrec->ndeleted, xlrec->nupdated); break; } case XLOG_BTREE_MARK_PAGE_HALFDEAD: @@ -148,12 +147,13 @@ btree_desc(StringInfo buf, XLogReaderState *record) { xl_btree_unlink_page *xlrec = (xl_btree_unlink_page *) rec; - appendStringInfo(buf, "left %u; right %u; btpo_xact %u; ", - xlrec->leftsib, xlrec->rightsib, - xlrec->btpo_xact); - appendStringInfo(buf, "leafleft %u; leafright %u; topparent %u", + appendStringInfo(buf, "left %u; right %u; level %u; safexid %u:%u; ", + xlrec->leftsib, xlrec->rightsib, xlrec->level, + EpochFromFullTransactionId(xlrec->safexid), + XidFromFullTransactionId(xlrec->safexid)); + appendStringInfo(buf, "leafleft %u; leafright %u; leaftopparent %u", xlrec->leafleftsib, xlrec->leafrightsib, - xlrec->topparent); + xlrec->leaftopparent); break; } case XLOG_BTREE_NEWROOT: @@ -167,9 +167,11 @@ btree_desc(StringInfo buf, XLogReaderState *record) { xl_btree_reuse_page *xlrec = (xl_btree_reuse_page *) rec; - appendStringInfo(buf, "rel %u/%u/%u; latestRemovedXid %u", + appendStringInfo(buf, "rel %u/%u/%u; latestRemovedXid %u:%u", xlrec->node.spcNode, xlrec->node.dbNode, - xlrec->node.relNode, xlrec->latestRemovedXid); + xlrec->node.relNode, + EpochFromFullTransactionId(xlrec->latestRemovedFullXid), + XidFromFullTransactionId(xlrec->latestRemovedFullXid)); break; } case XLOG_BTREE_META_CLEANUP: @@ -178,9 +180,8 @@ btree_desc(StringInfo buf, XLogReaderState *record) xlrec = (xl_btree_metadata *) XLogRecGetBlockData(record, 0, NULL); - appendStringInfo(buf, "oldest_btpo_xact %u; last_cleanup_num_heap_tuples: %f", - xlrec->oldest_btpo_xact, - xlrec->last_cleanup_num_heap_tuples); + appendStringInfo(buf, "last_cleanup_num_delpages %u", + xlrec->last_cleanup_num_delpages); break; } } diff --git a/src/backend/access/rmgrdesc/relmapdesc.c b/src/backend/access/rmgrdesc/relmapdesc.c index 8a8d59495675..2f9d4f54ba8b 100644 --- a/src/backend/access/rmgrdesc/relmapdesc.c +++ b/src/backend/access/rmgrdesc/relmapdesc.c @@ -3,7 +3,7 @@ * relmapdesc.c * rmgr descriptor routines for utils/cache/relmapper.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/replorigindesc.c b/src/backend/access/rmgrdesc/replorigindesc.c index 19e14f910baf..1f314c4771a2 100644 --- a/src/backend/access/rmgrdesc/replorigindesc.c +++ b/src/backend/access/rmgrdesc/replorigindesc.c @@ -3,7 +3,7 @@ * replorigindesc.c * rmgr descriptor routines for replication/logical/origin.c * - * Portions Copyright (c) 2015-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2015-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -31,8 +31,7 @@ replorigin_desc(StringInfo buf, XLogReaderState *record) appendStringInfo(buf, "set %u; lsn %X/%X; force: %d", xlrec->node_id, - (uint32) (xlrec->remote_lsn >> 32), - (uint32) xlrec->remote_lsn, + LSN_FORMAT_ARGS(xlrec->remote_lsn), xlrec->force); break; } diff --git a/src/backend/access/rmgrdesc/seqdesc.c b/src/backend/access/rmgrdesc/seqdesc.c index 1cb1e91a3e95..0bd294687b73 100644 --- a/src/backend/access/rmgrdesc/seqdesc.c +++ b/src/backend/access/rmgrdesc/seqdesc.c @@ -3,7 +3,7 @@ * seqdesc.c * rmgr descriptor routines for commands/sequence.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/smgrdesc.c b/src/backend/access/rmgrdesc/smgrdesc.c index 367327a94793..e58025d3b0d6 100644 --- a/src/backend/access/rmgrdesc/smgrdesc.c +++ b/src/backend/access/rmgrdesc/smgrdesc.c @@ -3,7 +3,7 @@ * smgrdesc.c * rmgr descriptor routines for catalog/storage.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/spgdesc.c b/src/backend/access/rmgrdesc/spgdesc.c index a5478e3fb45f..0fefe386b8eb 100644 --- a/src/backend/access/rmgrdesc/spgdesc.c +++ b/src/backend/access/rmgrdesc/spgdesc.c @@ -3,7 +3,7 @@ * spgdesc.c * rmgr descriptor routines for access/spgist/spgxlog.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,10 +28,9 @@ spg_desc(StringInfo buf, XLogReaderState *record) { spgxlogAddLeaf *xlrec = (spgxlogAddLeaf *) rec; - appendStringInfoString(buf, "add leaf to page"); - appendStringInfo(buf, "; off %u; headoff %u; parentoff %u", + appendStringInfo(buf, "off: %u, headoff: %u, parentoff: %u, nodeI: %u", xlrec->offnumLeaf, xlrec->offnumHeadLeaf, - xlrec->offnumParent); + xlrec->offnumParent, xlrec->nodeI); if (xlrec->newPage) appendStringInfoString(buf, " (newpage)"); if (xlrec->storesNulls) @@ -39,42 +38,91 @@ spg_desc(StringInfo buf, XLogReaderState *record) } break; case XLOG_SPGIST_MOVE_LEAFS: - appendStringInfo(buf, "%u leafs", - ((spgxlogMoveLeafs *) rec)->nMoves); + { + spgxlogMoveLeafs *xlrec = (spgxlogMoveLeafs *) rec; + + appendStringInfo(buf, "nmoves: %u, parentoff: %u, nodeI: %u", + xlrec->nMoves, + xlrec->offnumParent, xlrec->nodeI); + if (xlrec->newPage) + appendStringInfoString(buf, " (newpage)"); + if (xlrec->replaceDead) + appendStringInfoString(buf, " (replacedead)"); + if (xlrec->storesNulls) + appendStringInfoString(buf, " (nulls)"); + } break; case XLOG_SPGIST_ADD_NODE: - appendStringInfo(buf, "off %u", - ((spgxlogAddNode *) rec)->offnum); + { + spgxlogAddNode *xlrec = (spgxlogAddNode *) rec; + + appendStringInfo(buf, "off: %u, newoff: %u, parentBlk: %d, " + "parentoff: %u, nodeI: %u", + xlrec->offnum, + xlrec->offnumNew, + xlrec->parentBlk, + xlrec->offnumParent, + xlrec->nodeI); + if (xlrec->newPage) + appendStringInfoString(buf, " (newpage)"); + } break; case XLOG_SPGIST_SPLIT_TUPLE: - appendStringInfo(buf, "prefix off: %u, postfix off: %u (same %d, new %d)", - ((spgxlogSplitTuple *) rec)->offnumPrefix, - ((spgxlogSplitTuple *) rec)->offnumPostfix, - ((spgxlogSplitTuple *) rec)->postfixBlkSame, - ((spgxlogSplitTuple *) rec)->newPage - ); + { + spgxlogSplitTuple *xlrec = (spgxlogSplitTuple *) rec; + + appendStringInfo(buf, "prefixoff: %u, postfixoff: %u", + xlrec->offnumPrefix, + xlrec->offnumPostfix); + if (xlrec->newPage) + appendStringInfoString(buf, " (newpage)"); + if (xlrec->postfixBlkSame) + appendStringInfoString(buf, " (same)"); + } break; case XLOG_SPGIST_PICKSPLIT: { spgxlogPickSplit *xlrec = (spgxlogPickSplit *) rec; - appendStringInfo(buf, "ndel %u; nins %u", - xlrec->nDelete, xlrec->nInsert); + appendStringInfo(buf, "ndelete: %u, ninsert: %u, inneroff: %u, " + "parentoff: %u, nodeI: %u", + xlrec->nDelete, xlrec->nInsert, + xlrec->offnumInner, + xlrec->offnumParent, xlrec->nodeI); if (xlrec->innerIsParent) appendStringInfoString(buf, " (innerIsParent)"); + if (xlrec->storesNulls) + appendStringInfoString(buf, " (nulls)"); if (xlrec->isRootSplit) appendStringInfoString(buf, " (isRootSplit)"); } break; case XLOG_SPGIST_VACUUM_LEAF: - /* no further information */ + { + spgxlogVacuumLeaf *xlrec = (spgxlogVacuumLeaf *) rec; + + appendStringInfo(buf, "ndead: %u, nplaceholder: %u, nmove: %u, nchain: %u", + xlrec->nDead, xlrec->nPlaceholder, + xlrec->nMove, xlrec->nChain); + } break; case XLOG_SPGIST_VACUUM_ROOT: - /* no further information */ + { + spgxlogVacuumRoot *xlrec = (spgxlogVacuumRoot *) rec; + + appendStringInfo(buf, "ndelete: %u", + xlrec->nDelete); + } break; case XLOG_SPGIST_VACUUM_REDIRECT: - appendStringInfo(buf, "newest XID %u", - ((spgxlogVacuumRedirect *) rec)->newestRedirectXid); + { + spgxlogVacuumRedirect *xlrec = (spgxlogVacuumRedirect *) rec; + + appendStringInfo(buf, "ntoplaceholder: %u, firstplaceholder: %u, newestredirectxid: %u", + xlrec->nToPlaceholder, + xlrec->firstPlaceholder, + xlrec->newestRedirectXid); + } break; } } diff --git a/src/backend/access/rmgrdesc/standbydesc.c b/src/backend/access/rmgrdesc/standbydesc.c index 1ce266401463..01ee7ac6d2ca 100644 --- a/src/backend/access/rmgrdesc/standbydesc.c +++ b/src/backend/access/rmgrdesc/standbydesc.c @@ -3,7 +3,7 @@ * standbydesc.c * rmgr descriptor routines for storage/ipc/standby.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/tblspcdesc.c b/src/backend/access/rmgrdesc/tblspcdesc.c index 2cd361b2c002..cb356eaa48f1 100644 --- a/src/backend/access/rmgrdesc/tblspcdesc.c +++ b/src/backend/access/rmgrdesc/tblspcdesc.c @@ -3,7 +3,7 @@ * tblspcdesc.c * rmgr descriptor routines for commands/tablespace.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/xactdesc.c b/src/backend/access/rmgrdesc/xactdesc.c index bc7e2d91c197..68286d090b5e 100644 --- a/src/backend/access/rmgrdesc/xactdesc.c +++ b/src/backend/access/rmgrdesc/xactdesc.c @@ -3,7 +3,7 @@ * xactdesc.c * rmgr descriptor routines for access/transam/xact.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -368,8 +368,7 @@ xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, RepOriginId { appendStringInfo(buf, "; origin: node %u, lsn %X/%X, at %s", origin_id, - (uint32) (parsed.origin_lsn >> 32), - (uint32) parsed.origin_lsn, + LSN_FORMAT_ARGS(parsed.origin_lsn), timestamptz_to_str(parsed.origin_timestamp)); } diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c index 08d2f60eaafa..8cab12b2ecb1 100644 --- a/src/backend/access/rmgrdesc/xlogdesc.c +++ b/src/backend/access/rmgrdesc/xlogdesc.c @@ -3,7 +3,7 @@ * xlogdesc.c * rmgr descriptor routines for access/transam/xlog.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -86,7 +86,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record) "oldest xid %u in DB %u; oldest multi %u in DB %u; " "oldest/newest commit timestamp xid: %u/%u; " "oldest running xid %u; %s", - (uint32) (checkpoint->redo >> 32), (uint32) checkpoint->redo, + LSN_FORMAT_ARGS(checkpoint->redo), checkpoint->ThisTimeLineID, checkpoint->PrevTimeLineID, checkpoint->fullPageWrites ? "true" : "false", @@ -153,8 +153,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record) XLogRecPtr startpoint; memcpy(&startpoint, rec, sizeof(XLogRecPtr)); - appendStringInfo(buf, "%X/%X", - (uint32) (startpoint >> 32), (uint32) startpoint); + appendStringInfo(buf, "%X/%X", LSN_FORMAT_ARGS(startpoint)); } else if (info == XLOG_PARAMETER_CHANGE) { diff --git a/src/backend/access/spgist/README b/src/backend/access/spgist/README index b55b07383206..7117e02c7703 100644 --- a/src/backend/access/spgist/README +++ b/src/backend/access/spgist/README @@ -56,7 +56,7 @@ list and there is no free space on page, then SP-GiST creates a new inner tuple and distributes leaf tuples into a set of lists on, perhaps, several pages. -Inner tuple consists of: +An inner tuple consists of: optional prefix value - all successors must be consistent with it. Example: @@ -67,14 +67,26 @@ Inner tuple consists of: list of nodes, where node is a (label, pointer) pair. Example of a label: a single character for radix tree -Leaf tuple consists of: +A leaf tuple consists of: a leaf value Example: radix tree - the rest of string (postfix) quad and k-d tree - the point itself - ItemPointer to the heap + ItemPointer to the corresponding heap tuple + nextOffset number of next leaf tuple in a chain on a leaf page + + optional nulls bitmask + optional INCLUDE-column values + +For compatibility with pre-v14 indexes, a leaf tuple has a nulls bitmask +only if there are null values (among the leaf value and the INCLUDE values) +*and* there is at least one INCLUDE column. The null-ness of the leaf +value can be inferred from whether the tuple is on a "nulls page" (see below) +so it is not necessary to represent it explicitly. But we include it anyway +in a bitmask used with INCLUDE values, so that standard tuple deconstruction +code can be used. NULLS HANDLING diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c index 934d65b89f2d..70557bcf3d0a 100644 --- a/src/backend/access/spgist/spgdoinsert.c +++ b/src/backend/access/spgist/spgdoinsert.c @@ -4,7 +4,7 @@ * implementation of insert algorithm * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -220,7 +220,7 @@ addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple, SpGistBlockIsRoot(current->blkno)) { /* Tuple is not part of a chain */ - leafTuple->nextOffset = InvalidOffsetNumber; + SGLT_SET_NEXTOFFSET(leafTuple, InvalidOffsetNumber); current->offnum = SpGistPageAddNewItem(state, current->page, (Item) leafTuple, leafTuple->size, NULL, false); @@ -253,7 +253,7 @@ addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple, PageGetItemId(current->page, current->offnum)); if (head->tupstate == SPGIST_LIVE) { - leafTuple->nextOffset = head->nextOffset; + SGLT_SET_NEXTOFFSET(leafTuple, SGLT_GET_NEXTOFFSET(head)); offnum = SpGistPageAddNewItem(state, current->page, (Item) leafTuple, leafTuple->size, NULL, false); @@ -264,14 +264,14 @@ addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple, */ head = (SpGistLeafTuple) PageGetItem(current->page, PageGetItemId(current->page, current->offnum)); - head->nextOffset = offnum; + SGLT_SET_NEXTOFFSET(head, offnum); xlrec.offnumLeaf = offnum; xlrec.offnumHeadLeaf = current->offnum; } else if (head->tupstate == SPGIST_DEAD) { - leafTuple->nextOffset = InvalidOffsetNumber; + SGLT_SET_NEXTOFFSET(leafTuple, InvalidOffsetNumber); PageIndexTupleDelete(current->page, current->offnum); if (PageAddItem(current->page, (Item) leafTuple, leafTuple->size, @@ -362,13 +362,13 @@ checkSplitConditions(Relation index, SpGistState *state, { /* We could see a DEAD tuple as first/only chain item */ Assert(i == current->offnum); - Assert(it->nextOffset == InvalidOffsetNumber); + Assert(SGLT_GET_NEXTOFFSET(it) == InvalidOffsetNumber); /* Don't count it in result, because it won't go to other page */ } else elog(ERROR, "unexpected SPGiST tuple state: %d", it->tupstate); - i = it->nextOffset; + i = SGLT_GET_NEXTOFFSET(it); } *nToSplit = n; @@ -437,7 +437,7 @@ moveLeafs(Relation index, SpGistState *state, { /* We could see a DEAD tuple as first/only chain item */ Assert(i == current->offnum); - Assert(it->nextOffset == InvalidOffsetNumber); + Assert(SGLT_GET_NEXTOFFSET(it) == InvalidOffsetNumber); /* We don't want to move it, so don't count it in size */ toDelete[nDelete] = i; nDelete++; @@ -446,7 +446,7 @@ moveLeafs(Relation index, SpGistState *state, else elog(ERROR, "unexpected SPGiST tuple state: %d", it->tupstate); - i = it->nextOffset; + i = SGLT_GET_NEXTOFFSET(it); } /* Find a leaf page that will hold them */ @@ -475,7 +475,7 @@ moveLeafs(Relation index, SpGistState *state, * don't care). We're modifying the tuple on the source page * here, but it's okay since we're about to delete it. */ - it->nextOffset = r; + SGLT_SET_NEXTOFFSET(it, r); r = SpGistPageAddNewItem(state, npage, (Item) it, it->size, &startOffset, false); @@ -490,7 +490,7 @@ moveLeafs(Relation index, SpGistState *state, } /* add the new tuple as well */ - newLeafTuple->nextOffset = r; + SGLT_SET_NEXTOFFSET(newLeafTuple, r); r = SpGistPageAddNewItem(state, npage, (Item) newLeafTuple, newLeafTuple->size, &startOffset, false); @@ -669,7 +669,8 @@ checkAllTheSame(spgPickSplitIn *in, spgPickSplitOut *out, bool tooBig, * will eventually terminate if lack of balance is the issue. If the tuple * is too big, we assume that repeated picksplit operations will eventually * make it small enough by repeated prefix-stripping. A broken opclass could - * make this an infinite loop, though. + * make this an infinite loop, though, so spgdoinsert() checks that the + * leaf datums get smaller each time. */ static bool doPickSplit(Relation index, SpGistState *state, @@ -690,14 +691,16 @@ doPickSplit(Relation index, SpGistState *state, *nodes; Buffer newInnerBuffer, newLeafBuffer; - ItemPointerData *heapPtrs; uint8 *leafPageSelect; int *leafSizes; OffsetNumber *toDelete; OffsetNumber *toInsert; OffsetNumber redirectTuplePos = InvalidOffsetNumber; OffsetNumber startOffsets[2]; + SpGistLeafTuple *oldLeafs; SpGistLeafTuple *newLeafs; + Datum leafDatums[INDEX_MAX_KEYS]; + bool leafIsnulls[INDEX_MAX_KEYS]; int spaceToDelete; int currentFreeSpace; int totalLeafSizes; @@ -718,9 +721,9 @@ doPickSplit(Relation index, SpGistState *state, max = PageGetMaxOffsetNumber(current->page); n = max + 1; in.datums = (Datum *) palloc(sizeof(Datum) * n); - heapPtrs = (ItemPointerData *) palloc(sizeof(ItemPointerData) * n); toDelete = (OffsetNumber *) palloc(sizeof(OffsetNumber) * n); toInsert = (OffsetNumber *) palloc(sizeof(OffsetNumber) * n); + oldLeafs = (SpGistLeafTuple *) palloc(sizeof(SpGistLeafTuple) * n); newLeafs = (SpGistLeafTuple *) palloc(sizeof(SpGistLeafTuple) * n); leafPageSelect = (uint8 *) palloc(sizeof(uint8) * n); @@ -731,13 +734,6 @@ doPickSplit(Relation index, SpGistState *state, * also, count up the amount of space that will be freed from current. * (Note that in the non-root case, we won't actually delete the old * tuples, only replace them with redirects or placeholders.) - * - * Note: the SGLTDATUM calls here are safe even when dealing with a nulls - * page. For a pass-by-value data type we will fetch a word that must - * exist even though it may contain garbage (because of the fact that leaf - * tuples must have size at least SGDTSIZE). For a pass-by-reference type - * we are just computing a pointer that isn't going to get dereferenced. - * So it's not worth guarding the calls with isNulls checks. */ nToInsert = 0; nToDelete = 0; @@ -757,8 +753,9 @@ doPickSplit(Relation index, SpGistState *state, PageGetItemId(current->page, i)); if (it->tupstate == SPGIST_LIVE) { - in.datums[nToInsert] = SGLTDATUM(it, state); - heapPtrs[nToInsert] = it->heapPtr; + in.datums[nToInsert] = + isNulls ? (Datum) 0 : SGLTDATUM(it, state); + oldLeafs[nToInsert] = it; nToInsert++; toDelete[nToDelete] = i; nToDelete++; @@ -782,8 +779,9 @@ doPickSplit(Relation index, SpGistState *state, PageGetItemId(current->page, i)); if (it->tupstate == SPGIST_LIVE) { - in.datums[nToInsert] = SGLTDATUM(it, state); - heapPtrs[nToInsert] = it->heapPtr; + in.datums[nToInsert] = + isNulls ? (Datum) 0 : SGLTDATUM(it, state); + oldLeafs[nToInsert] = it; nToInsert++; toDelete[nToDelete] = i; nToDelete++; @@ -795,7 +793,7 @@ doPickSplit(Relation index, SpGistState *state, { /* We could see a DEAD tuple as first/only chain item */ Assert(i == current->offnum); - Assert(it->nextOffset == InvalidOffsetNumber); + Assert(SGLT_GET_NEXTOFFSET(it) == InvalidOffsetNumber); toDelete[nToDelete] = i; nToDelete++; /* replacing it with redirect will save no space */ @@ -803,7 +801,7 @@ doPickSplit(Relation index, SpGistState *state, else elog(ERROR, "unexpected SPGiST tuple state: %d", it->tupstate); - i = it->nextOffset; + i = SGLT_GET_NEXTOFFSET(it); } } in.nTuples = nToInsert; @@ -814,8 +812,9 @@ doPickSplit(Relation index, SpGistState *state, * space to include it; and in any case it has to be included in the input * for the picksplit function. So don't increment nToInsert yet. */ - in.datums[in.nTuples] = SGLTDATUM(newLeafTuple, state); - heapPtrs[in.nTuples] = newLeafTuple->heapPtr; + in.datums[in.nTuples] = + isNulls ? (Datum) 0 : SGLTDATUM(newLeafTuple, state); + oldLeafs[in.nTuples] = newLeafTuple; in.nTuples++; memset(&out, 0, sizeof(out)); @@ -837,9 +836,19 @@ doPickSplit(Relation index, SpGistState *state, totalLeafSizes = 0; for (i = 0; i < in.nTuples; i++) { - newLeafs[i] = spgFormLeafTuple(state, heapPtrs + i, - out.leafTupleDatums[i], - false); + if (state->leafTupDesc->natts > 1) + spgDeformLeafTuple(oldLeafs[i], + state->leafTupDesc, + leafDatums, + leafIsnulls, + isNulls); + + leafDatums[spgKeyColumn] = out.leafTupleDatums[i]; + leafIsnulls[spgKeyColumn] = false; + + newLeafs[i] = spgFormLeafTuple(state, &oldLeafs[i]->heapPtr, + leafDatums, + leafIsnulls); totalLeafSizes += newLeafs[i]->size + sizeof(ItemIdData); } } @@ -860,9 +869,22 @@ doPickSplit(Relation index, SpGistState *state, totalLeafSizes = 0; for (i = 0; i < in.nTuples; i++) { - newLeafs[i] = spgFormLeafTuple(state, heapPtrs + i, - (Datum) 0, - true); + if (state->leafTupDesc->natts > 1) + spgDeformLeafTuple(oldLeafs[i], + state->leafTupDesc, + leafDatums, + leafIsnulls, + isNulls); + + /* + * Nulls tree can contain only null key values. + */ + leafDatums[spgKeyColumn] = (Datum) 0; + leafIsnulls[spgKeyColumn] = true; + + newLeafs[i] = spgFormLeafTuple(state, &oldLeafs[i]->heapPtr, + leafDatums, + leafIsnulls); totalLeafSizes += newLeafs[i]->size + sizeof(ItemIdData); } } @@ -1196,10 +1218,10 @@ doPickSplit(Relation index, SpGistState *state, if (ItemPointerIsValid(&nodes[n]->t_tid)) { Assert(ItemPointerGetBlockNumber(&nodes[n]->t_tid) == leafBlock); - it->nextOffset = ItemPointerGetOffsetNumber(&nodes[n]->t_tid); + SGLT_SET_NEXTOFFSET(it, ItemPointerGetOffsetNumber(&nodes[n]->t_tid)); } else - it->nextOffset = InvalidOffsetNumber; + SGLT_SET_NEXTOFFSET(it, InvalidOffsetNumber); /* Insert it on page */ newoffset = SpGistPageAddNewItem(state, BufferGetPage(leafBuffer), @@ -1884,16 +1906,21 @@ spgSplitNodeAction(Relation index, SpGistState *state, * Insert one item into the index. * * Returns true on success, false if we failed to complete the insertion - * because of conflict with a concurrent insert. In the latter case, - * caller should re-call spgdoinsert() with the same args. + * (typically because of conflict with a concurrent insert). In the latter + * case, caller should re-call spgdoinsert() with the same args. */ bool spgdoinsert(Relation index, SpGistState *state, - ItemPointer heapPtr, Datum datum, bool isnull) + ItemPointer heapPtr, Datum *datums, bool *isnulls) { + bool result = true; + TupleDesc leafDescriptor = state->leafTupDesc; + bool isnull = isnulls[spgKeyColumn]; int level = 0; - Datum leafDatum; + Datum leafDatums[INDEX_MAX_KEYS]; int leafSize; + int bestLeafSize; + int numNoProgressCycles = 0; SPPageDesc current, parent; FmgrInfo *procinfo = NULL; @@ -1909,8 +1936,8 @@ spgdoinsert(Relation index, SpGistState *state, * Prepare the leaf datum to insert. * * If an optional "compress" method is provided, then call it to form the - * leaf datum from the input datum. Otherwise store the input datum as - * is. Since we don't use index_form_tuple in this AM, we have to make + * leaf key datum from the input datum. Otherwise, store the input datum + * as is. Since we don't use index_form_tuple in this AM, we have to make * sure value to be inserted is not toasted; FormIndexDatum doesn't * guarantee that. But we assume the "compress" method to return an * untoasted value. @@ -1922,36 +1949,52 @@ spgdoinsert(Relation index, SpGistState *state, FmgrInfo *compressProcinfo = NULL; compressProcinfo = index_getprocinfo(index, 1, SPGIST_COMPRESS_PROC); - leafDatum = FunctionCall1Coll(compressProcinfo, - index->rd_indcollation[0], - datum); + leafDatums[spgKeyColumn] = + FunctionCall1Coll(compressProcinfo, + index->rd_indcollation[spgKeyColumn], + datums[spgKeyColumn]); } else { Assert(state->attLeafType.type == state->attType.type); if (state->attType.attlen == -1) - leafDatum = PointerGetDatum(PG_DETOAST_DATUM(datum)); + leafDatums[spgKeyColumn] = + PointerGetDatum(PG_DETOAST_DATUM(datums[spgKeyColumn])); else - leafDatum = datum; + leafDatums[spgKeyColumn] = datums[spgKeyColumn]; } } else - leafDatum = (Datum) 0; + leafDatums[spgKeyColumn] = (Datum) 0; + + /* Likewise, ensure that any INCLUDE values are not toasted */ + for (int i = spgFirstIncludeColumn; i < leafDescriptor->natts; i++) + { + if (!isnulls[i]) + { + if (TupleDescAttr(leafDescriptor, i)->attlen == -1) + leafDatums[i] = PointerGetDatum(PG_DETOAST_DATUM(datums[i])); + else + leafDatums[i] = datums[i]; + } + else + leafDatums[i] = (Datum) 0; + } /* - * Compute space needed for a leaf tuple containing the given datum. - * - * If it isn't gonna fit, and the opclass can't reduce the datum size by - * suffixing, bail out now rather than getting into an endless loop. + * Compute space needed for a leaf tuple containing the given data. */ - if (!isnull) - leafSize = SGLTHDRSZ + sizeof(ItemIdData) + - SpGistGetTypeSize(&state->attLeafType, leafDatum); - else - leafSize = SGDTSIZE + sizeof(ItemIdData); + leafSize = SpGistGetLeafTupleSize(leafDescriptor, leafDatums, isnulls); + /* Account for an item pointer, too */ + leafSize += sizeof(ItemIdData); - if (leafSize > SPGIST_PAGE_CAPACITY && !state->config.longValuesOK) + /* + * If it isn't gonna fit, and the opclass can't reduce the datum size by + * suffixing, bail out now rather than doing a lot of useless work. + */ + if (leafSize > SPGIST_PAGE_CAPACITY && + (isnull || !state->config.longValuesOK)) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("index row size %zu exceeds maximum %zu for index \"%s\"", @@ -1959,6 +2002,7 @@ spgdoinsert(Relation index, SpGistState *state, SPGIST_PAGE_CAPACITY - sizeof(ItemIdData), RelationGetRelationName(index)), errhint("Values larger than a buffer page cannot be indexed."))); + bestLeafSize = leafSize; /* Initialize "current" to the appropriate root page */ current.blkno = isnull ? SPGIST_NULL_BLKNO : SPGIST_ROOT_BLKNO; @@ -1974,6 +2018,14 @@ spgdoinsert(Relation index, SpGistState *state, parent.offnum = InvalidOffsetNumber; parent.node = -1; + /* + * Before entering the loop, try to clear any pending interrupt condition. + * If a query cancel is pending, we might as well accept it now not later; + * while if a non-canceling condition is pending, servicing it here avoids + * having to restart the insertion and redo all the work so far. + */ + CHECK_FOR_INTERRUPTS(); + for (;;) { bool isNew = false; @@ -1981,9 +2033,18 @@ spgdoinsert(Relation index, SpGistState *state, /* * Bail out if query cancel is pending. We must have this somewhere * in the loop since a broken opclass could produce an infinite - * picksplit loop. + * picksplit loop. However, because we'll be holding buffer lock(s) + * after the first iteration, ProcessInterrupts() wouldn't be able to + * throw a cancel error here. Hence, if we see that an interrupt is + * pending, break out of the loop and deal with the situation below. + * Set result = false because we must restart the insertion if the + * interrupt isn't a query-cancel-or-die case. */ - CHECK_FOR_INTERRUPTS(); + if (INTERRUPTS_PENDING_CONDITION()) + { + result = false; + break; + } if (current.blkno == InvalidBlockNumber) { @@ -2048,7 +2109,7 @@ spgdoinsert(Relation index, SpGistState *state, int nToSplit, sizeToSplit; - leafTuple = spgFormLeafTuple(state, heapPtr, leafDatum, isnull); + leafTuple = spgFormLeafTuple(state, heapPtr, leafDatums, isnulls); if (leafTuple->size + sizeof(ItemIdData) <= SpGistPageGetFreeSpace(current.page, 1)) { @@ -2102,16 +2163,20 @@ spgdoinsert(Relation index, SpGistState *state, * spgAddNode and spgSplitTuple cases will loop back to here to * complete the insertion operation. Just in case the choose * function is broken and produces add or split requests - * repeatedly, check for query cancel. + * repeatedly, check for query cancel (see comments above). */ process_inner_tuple: - CHECK_FOR_INTERRUPTS(); + if (INTERRUPTS_PENDING_CONDITION()) + { + result = false; + break; + } innerTuple = (SpGistInnerTuple) PageGetItem(current.page, PageGetItemId(current.page, current.offnum)); - in.datum = datum; - in.leafDatum = leafDatum; + in.datum = datums[spgKeyColumn]; + in.leafDatum = leafDatums[spgKeyColumn]; in.level = level; in.allTheSame = innerTuple->allTheSame; in.hasPrefix = (innerTuple->prefixSize > 0); @@ -2160,9 +2225,58 @@ spgdoinsert(Relation index, SpGistState *state, /* Replace leafDatum and recompute leafSize */ if (!isnull) { - leafDatum = out.result.matchNode.restDatum; - leafSize = SGLTHDRSZ + sizeof(ItemIdData) + - SpGistGetTypeSize(&state->attLeafType, leafDatum); + leafDatums[spgKeyColumn] = out.result.matchNode.restDatum; + leafSize = SpGistGetLeafTupleSize(leafDescriptor, + leafDatums, isnulls); + leafSize += sizeof(ItemIdData); + } + + /* + * Check new tuple size; fail if it can't fit, unless the + * opclass says it can handle the situation by suffixing. + * + * However, the opclass can only shorten the leaf datum, + * which may not be enough to ever make the tuple fit, + * since INCLUDE columns might alone use more than a page. + * Depending on the opclass' behavior, that could lead to + * an infinite loop --- spgtextproc.c, for example, will + * just repeatedly generate an empty-string leaf datum + * once it runs out of data. Actual bugs in opclasses + * might cause infinite looping, too. To detect such a + * loop, check to see if we are making progress by + * reducing the leafSize in each pass. This is a bit + * tricky though. Because of alignment considerations, + * the total tuple size might not decrease on every pass. + * Also, there are edge cases where the choose method + * might seem to not make progress for a cycle or two. + * Somewhat arbitrarily, we allow up to 10 no-progress + * iterations before failing. (This limit should be more + * than MAXALIGN, to accommodate opclasses that trim one + * byte from the leaf datum per pass.) + */ + if (leafSize > SPGIST_PAGE_CAPACITY) + { + bool ok = false; + + if (state->config.longValuesOK && !isnull) + { + if (leafSize < bestLeafSize) + { + ok = true; + bestLeafSize = leafSize; + numNoProgressCycles = 0; + } + else if (++numNoProgressCycles < 10) + ok = true; + } + if (!ok) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("index row size %zu exceeds maximum %zu for index \"%s\"", + leafSize - sizeof(ItemIdData), + SPGIST_PAGE_CAPACITY - sizeof(ItemIdData), + RelationGetRelationName(index)), + errhint("Values larger than a buffer page cannot be indexed."))); } /* @@ -2170,14 +2284,6 @@ spgdoinsert(Relation index, SpGistState *state, * "current" (which might reference an existing child * tuple, or might be invalid to force us to find a new * page for the tuple). - * - * Note: if the opclass sets longValuesOK, we rely on the - * choose function to eventually shorten the leafDatum - * enough to fit on a page. We could add a test here to - * complain if the datum doesn't get visibly shorter each - * time, but that could get in the way of opclasses that - * "simplify" datums in a way that doesn't necessarily - * lead to physical shortening on every cycle. */ break; case spgAddNode: @@ -2228,5 +2334,21 @@ spgdoinsert(Relation index, SpGistState *state, UnlockReleaseBuffer(parent.buffer); } - return true; + /* + * We do not support being called while some outer function is holding a + * buffer lock (or any other reason to postpone query cancels). If that + * were the case, telling the caller to retry would create an infinite + * loop. + */ + Assert(INTERRUPTS_CAN_BE_PROCESSED()); + + /* + * Finally, check for interrupts again. If there was a query cancel, + * ProcessInterrupts() will be able to throw the error here. If it was + * some other kind of interrupt that can just be cleared, return false to + * tell our caller to retry. + */ + CHECK_FOR_INTERRUPTS(); + + return result; } diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c index e4508a2b923a..1af0af7da21f 100644 --- a/src/backend/access/spgist/spginsert.c +++ b/src/backend/access/spgist/spginsert.c @@ -5,7 +5,7 @@ * * All the actual insertion logic is in spgdoinsert.c. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -56,7 +56,7 @@ spgistBuildCallback(Relation index, ItemPointer tid, Datum *values, * any temp data when retrying. */ while (!spgdoinsert(index, &buildstate->spgstate, tid, - *values, *isnull)) + values, isnull)) { MemoryContextReset(buildstate->tmpCtx); } @@ -207,6 +207,7 @@ bool spginsert(Relation index, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, + bool indexUnchanged, IndexInfo *indexInfo) { SpGistState spgstate; @@ -226,7 +227,7 @@ spginsert(Relation index, Datum *values, bool *isnull, * to avoid cumulative memory consumption. That means we also have to * redo initSpGistState(), but it's cheap enough not to matter. */ - while (!spgdoinsert(index, &spgstate, ht_ctid, *values, *isnull)) + while (!spgdoinsert(index, &spgstate, ht_ctid, values, isnull)) { MemoryContextReset(insertCtx); initSpGistState(&spgstate, index); diff --git a/src/backend/access/spgist/spgkdtreeproc.c b/src/backend/access/spgist/spgkdtreeproc.c index bee30153f7de..d9b3f6a0ea7e 100644 --- a/src/backend/access/spgist/spgkdtreeproc.c +++ b/src/backend/access/spgist/spgkdtreeproc.c @@ -4,7 +4,7 @@ * implementation of k-d tree over points for SP-GiST * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -209,10 +209,12 @@ spg_kd_inner_consistent(PG_FUNCTION_ARGS) } break; case RTBelowStrategyNumber: + case RTOldBelowStrategyNumber: if ((in->level % 2) == 0 && FPlt(query->y, coord)) which &= (1 << 1); break; case RTAboveStrategyNumber: + case RTOldAboveStrategyNumber: if ((in->level % 2) == 0 && FPgt(query->y, coord)) which &= (1 << 2); break; diff --git a/src/backend/access/spgist/spgproc.c b/src/backend/access/spgist/spgproc.c index 94454f6b70d4..1bad5d6c06d2 100644 --- a/src/backend/access/spgist/spgproc.c +++ b/src/backend/access/spgist/spgproc.c @@ -4,7 +4,7 @@ * Common supporting procedures for SP-GiST opclasses. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/spgist/spgquadtreeproc.c b/src/backend/access/spgist/spgquadtreeproc.c index b4451cc1aedb..a52d924fdc92 100644 --- a/src/backend/access/spgist/spgquadtreeproc.c +++ b/src/backend/access/spgist/spgquadtreeproc.c @@ -4,7 +4,7 @@ * implementation of quad tree over points for SP-GiST * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -316,10 +316,12 @@ spg_quad_inner_consistent(PG_FUNCTION_ARGS) which &= (1 << getQuadrant(centroid, query)); break; case RTBelowStrategyNumber: + case RTOldBelowStrategyNumber: if (SPTEST(point_above, centroid, query)) which &= (1 << 2) | (1 << 3); break; case RTAboveStrategyNumber: + case RTOldAboveStrategyNumber: if (SPTEST(point_below, centroid, query)) which &= (1 << 1) | (1 << 4); break; @@ -434,9 +436,11 @@ spg_quad_leaf_consistent(PG_FUNCTION_ARGS) res = SPTEST(point_eq, datum, query); break; case RTBelowStrategyNumber: + case RTOldBelowStrategyNumber: res = SPTEST(point_below, datum, query); break; case RTAboveStrategyNumber: + case RTOldAboveStrategyNumber: res = SPTEST(point_above, datum, query); break; case RTContainedByStrategyNumber: diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c index ed80f5dd6342..e4c53c16c178 100644 --- a/src/backend/access/spgist/spgscan.c +++ b/src/backend/access/spgist/spgscan.c @@ -4,7 +4,7 @@ * routines for scanning SP-GiST indexes * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -27,7 +27,8 @@ #include "utils/rel.h" typedef void (*storeRes_func) (SpGistScanOpaque so, ItemPointer heapPtr, - Datum leafValue, bool isNull, bool recheck, + Datum leafValue, bool isNull, + SpGistLeafTuple leafTuple, bool recheck, bool recheckDistances, double *distances); /* @@ -81,10 +82,16 @@ pairingheap_SpGistSearchItem_cmp(const pairingheap_node *a, static void spgFreeSearchItem(SpGistScanOpaque so, SpGistSearchItem *item) { - if (!so->state.attLeafType.attbyval && + /* value is of type attType if isLeaf, else of type attLeafType */ + /* (no, that is not backwards; yes, it's confusing) */ + if (!(item->isLeaf ? so->state.attType.attbyval : + so->state.attLeafType.attbyval) && DatumGetPointer(item->value) != NULL) pfree(DatumGetPointer(item->value)); + if (item->leafTuple) + pfree(item->leafTuple); + if (item->traversalValue) pfree(item->traversalValue); @@ -130,6 +137,7 @@ spgAddStartItem(SpGistScanOpaque so, bool isnull) startEntry->isLeaf = false; startEntry->level = 0; startEntry->value = (Datum) 0; + startEntry->leafTuple = NULL; startEntry->traversalValue = NULL; startEntry->recheck = false; startEntry->recheckDistances = false; @@ -314,8 +322,14 @@ spgbeginscan(Relation rel, int keysz, int orderbysz) "SP-GiST traversal-value context", ALLOCSET_DEFAULT_SIZES); - /* Set up indexTupDesc and xs_hitupdesc in case it's an index-only scan */ - so->indexTupDesc = scan->xs_hitupdesc = RelationGetDescr(rel); + /* + * Set up reconTupDesc and xs_hitupdesc in case it's an index-only scan, + * making sure that the key column is shown as being of type attType. + * (It's rather annoying to do this work when it might be wasted, but for + * most opclasses we can re-use the index reldesc instead of making one.) + */ + so->reconTupDesc = scan->xs_hitupdesc = + getSpGistTupleDesc(rel, &so->state.attType); /* Allocate various arrays needed for order-by scans */ if (scan->numberOfOrderBys > 0) @@ -418,6 +432,10 @@ spgendscan(IndexScanDesc scan) if (so->keyData) pfree(so->keyData); + if (so->state.leafTupDesc && + so->state.leafTupDesc != RelationGetDescr(so->state.index)) + FreeTupleDesc(so->state.leafTupDesc); + if (so->state.deadTupleStorage) pfree(so->state.deadTupleStorage); @@ -438,18 +456,44 @@ spgendscan(IndexScanDesc scan) * Leaf SpGistSearchItem constructor, called in queue context */ static SpGistSearchItem * -spgNewHeapItem(SpGistScanOpaque so, int level, ItemPointer heapPtr, +spgNewHeapItem(SpGistScanOpaque so, int level, SpGistLeafTuple leafTuple, Datum leafValue, bool recheck, bool recheckDistances, bool isnull, double *distances) { SpGistSearchItem *item = spgAllocSearchItem(so, isnull, distances); item->level = level; - item->heapPtr = *heapPtr; - /* copy value to queue cxt out of tmp cxt */ - item->value = isnull ? (Datum) 0 : - datumCopy(leafValue, so->state.attLeafType.attbyval, - so->state.attLeafType.attlen); + item->heapPtr = leafTuple->heapPtr; + + /* + * If we need the reconstructed value, copy it to queue cxt out of tmp + * cxt. Caution: the leaf_consistent method may not have supplied a value + * if we didn't ask it to, and mildly-broken methods might supply one of + * the wrong type. The correct leafValue type is attType not leafType. + */ + if (so->want_itup) + { + item->value = isnull ? (Datum) 0 : + datumCopy(leafValue, so->state.attType.attbyval, + so->state.attType.attlen); + + /* + * If we're going to need to reconstruct INCLUDE attributes, store the + * whole leaf tuple so we can get the INCLUDE attributes out of it. + */ + if (so->state.leafTupDesc->natts > 1) + { + item->leafTuple = palloc(leafTuple->size); + memcpy(item->leafTuple, leafTuple, leafTuple->size); + } + else + item->leafTuple = NULL; + } + else + { + item->value = (Datum) 0; + item->leafTuple = NULL; + } item->traversalValue = NULL; item->isLeaf = true; item->recheck = recheck; @@ -497,6 +541,7 @@ spgLeafTest(SpGistScanOpaque so, SpGistSearchItem *item, in.nkeys = so->numberOfKeys; in.orderbys = so->orderByData; in.norderbys = so->numberOfNonNullOrderBys; + Assert(!item->isLeaf); /* else reconstructedValue would be wrong type */ in.reconstructedValue = item->value; in.traversalValue = item->traversalValue; in.level = item->level; @@ -528,7 +573,7 @@ spgLeafTest(SpGistScanOpaque so, SpGistSearchItem *item, /* the scan is ordered -> add the item to the queue */ MemoryContext oldCxt = MemoryContextSwitchTo(so->traversalCxt); SpGistSearchItem *heapItem = spgNewHeapItem(so, item->level, - &leafTuple->heapPtr, + leafTuple, leafValue, recheck, recheckDistances, @@ -544,7 +589,7 @@ spgLeafTest(SpGistScanOpaque so, SpGistSearchItem *item, /* non-ordered scan, so report the item right away */ Assert(!recheckDistances); storeRes(so, &leafTuple->heapPtr, leafValue, isnull, - recheck, false, NULL); + leafTuple, recheck, false, NULL); *reportedSome = true; } } @@ -563,6 +608,7 @@ spgInitInnerConsistentIn(spgInnerConsistentIn *in, in->orderbys = so->orderByData; in->nkeys = so->numberOfKeys; in->norderbys = so->numberOfNonNullOrderBys; + Assert(!item->isLeaf); /* else reconstructedValue would be wrong type */ in->reconstructedValue = item->value; in->traversalMemoryContext = so->traversalCxt; in->traversalValue = item->traversalValue; @@ -589,12 +635,15 @@ spgMakeInnerItem(SpGistScanOpaque so, : parentItem->level; /* Must copy value out of temp context */ + /* (recall that reconstructed values are of type leafType) */ item->value = out->reconstructedValues ? datumCopy(out->reconstructedValues[i], so->state.attLeafType.attbyval, so->state.attLeafType.attlen) : (Datum) 0; + item->leafTuple = NULL; + /* * Elements of out.traversalValues should be allocated in * in.traversalMemoryContext, which is actually a long lived context of @@ -736,7 +785,7 @@ spgTestLeafTuple(SpGistScanOpaque so, /* dead tuple should be first in chain */ Assert(offset == ItemPointerGetOffsetNumber(&item->heapPtr)); /* No live entries on this page */ - Assert(leafTuple->nextOffset == InvalidOffsetNumber); + Assert(SGLT_GET_NEXTOFFSET(leafTuple) == InvalidOffsetNumber); return SpGistBreakOffsetNumber; } } @@ -750,7 +799,7 @@ spgTestLeafTuple(SpGistScanOpaque so, spgLeafTest(so, item, leafTuple, isnull, reportedSome, storeRes); - return leafTuple->nextOffset; + return SGLT_GET_NEXTOFFSET(leafTuple); } /* @@ -783,7 +832,8 @@ spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex, /* We store heap items in the queue only in case of ordered search */ Assert(so->numberOfNonNullOrderBys > 0); storeRes(so, &item->heapPtr, item->value, item->isNull, - item->recheck, item->recheckDistances, item->distances); + item->leafTuple, item->recheck, + item->recheckDistances, item->distances); reportedSome = true; } else @@ -876,8 +926,9 @@ spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex, /* storeRes subroutine for getbitmap case */ static void storeBitmap(SpGistScanOpaque so, ItemPointer heapPtr, - Datum leafValue, bool isnull, bool recheck, bool recheckDistances, - double *distances) + Datum leafValue, bool isnull, + SpGistLeafTuple leafTuple, bool recheck, + bool recheckDistances, double *distances) { Assert(!recheckDistances && !distances); tbm_add_tuples(so->tbm, heapPtr, 1, recheck); @@ -922,8 +973,9 @@ spggetbitmap(IndexScanDesc scan, Node **bmNodeP) /* storeRes subroutine for gettuple case */ static void storeGettuple(SpGistScanOpaque so, ItemPointer heapPtr, - Datum leafValue, bool isnull, bool recheck, bool recheckDistances, - double *nonNullDistances) + Datum leafValue, bool isnull, + SpGistLeafTuple leafTuple, bool recheck, + bool recheckDistances, double *nonNullDistances) { Assert(so->nPtrs < MaxIndexTuplesPerPage); so->heapPtrs[so->nPtrs] = *heapPtr; @@ -968,9 +1020,20 @@ storeGettuple(SpGistScanOpaque so, ItemPointer heapPtr, * Reconstruct index data. We have to copy the datum out of the temp * context anyway, so we may as well create the tuple here. */ - so->reconTups[so->nPtrs] = heap_form_tuple(so->indexTupDesc, - &leafValue, - &isnull); + Datum leafDatums[INDEX_MAX_KEYS]; + bool leafIsnulls[INDEX_MAX_KEYS]; + + /* We only need to deform the old tuple if it has INCLUDE attributes */ + if (so->state.leafTupDesc->natts > 1) + spgDeformLeafTuple(leafTuple, so->state.leafTupDesc, + leafDatums, leafIsnulls, isnull); + + leafDatums[spgKeyColumn] = leafValue; + leafIsnulls[spgKeyColumn] = isnull; + + so->reconTups[so->nPtrs] = heap_form_tuple(so->reconTupDesc, + leafDatums, + leafIsnulls); } so->nPtrs++; } @@ -1038,6 +1101,10 @@ spgcanreturn(Relation index, int attno) { SpGistCache *cache; + /* INCLUDE attributes can always be fetched for index-only scans */ + if (attno > 1) + return true; + /* We can do it if the opclass config function says so */ cache = spgGetCache(index); diff --git a/src/backend/access/spgist/spgtextproc.c b/src/backend/access/spgist/spgtextproc.c index b5ec81937c4b..f34055533638 100644 --- a/src/backend/access/spgist/spgtextproc.c +++ b/src/backend/access/spgist/spgtextproc.c @@ -29,7 +29,7 @@ * No new entries ever get pushed into a -2-labeled child, either. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index 64d3ba82887b..9ff280a2526b 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -4,7 +4,7 @@ * various support functions for SP-GiST * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,10 +19,12 @@ #include "access/htup_details.h" #include "access/reloptions.h" #include "access/spgist_private.h" +#include "access/toast_compression.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/pg_amop.h" #include "commands/vacuum.h" +#include "nodes/nodeFuncs.h" #include "storage/bufmgr.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" @@ -53,11 +55,11 @@ spghandler(PG_FUNCTION_ARGS) amroutine->amoptionalkey = true; amroutine->amsearcharray = false; amroutine->amsearchnulls = true; - amroutine->amstorage = false; + amroutine->amstorage = true; amroutine->amclusterable = false; amroutine->ampredlocks = false; amroutine->amcanparallel = false; - amroutine->amcaninclude = false; + amroutine->amcaninclude = true; amroutine->amusemaintenanceworkmem = false; amroutine->amparallelvacuumoptions = VACUUM_OPTION_PARALLEL_BULKDEL | VACUUM_OPTION_PARALLEL_COND_CLEANUP; @@ -89,12 +91,83 @@ spghandler(PG_FUNCTION_ARGS) PG_RETURN_POINTER(amroutine); } +/* + * GetIndexInputType + * Determine the nominal input data type for an index column + * + * We define the "nominal" input type as the associated opclass's opcintype, + * or if that is a polymorphic type, the base type of the heap column or + * expression that is the index's input. The reason for preferring the + * opcintype is that non-polymorphic opclasses probably don't want to hear + * about binary-compatible input types. For instance, if a text opclass + * is being used with a varchar heap column, we want to report "text" not + * "varchar". Likewise, opclasses don't want to hear about domain types, + * so if we do consult the actual input type, we make sure to flatten domains. + * + * At some point maybe this should go somewhere else, but it's not clear + * if any other index AMs have a use for it. + */ +static Oid +GetIndexInputType(Relation index, AttrNumber indexcol) +{ + Oid opcintype; + AttrNumber heapcol; + List *indexprs; + ListCell *indexpr_item; + + Assert(index->rd_index != NULL); + Assert(indexcol > 0 && indexcol <= index->rd_index->indnkeyatts); + opcintype = index->rd_opcintype[indexcol - 1]; + if (!IsPolymorphicType(opcintype)) + return opcintype; + heapcol = index->rd_index->indkey.values[indexcol - 1]; + if (heapcol != 0) /* Simple index column? */ + return getBaseType(get_atttype(index->rd_index->indrelid, heapcol)); + + /* + * If the index expressions are already cached, skip calling + * RelationGetIndexExpressions, as it will make a copy which is overkill. + * We're not going to modify the trees, and we're not going to do anything + * that would invalidate the relcache entry before we're done. + */ + if (index->rd_indexprs) + indexprs = index->rd_indexprs; + else + indexprs = RelationGetIndexExpressions(index); + indexpr_item = list_head(indexprs); + for (int i = 1; i <= index->rd_index->indnkeyatts; i++) + { + if (index->rd_index->indkey.values[i - 1] == 0) + { + /* expression column */ + if (indexpr_item == NULL) + elog(ERROR, "wrong number of index expressions"); + if (i == indexcol) + return getBaseType(exprType((Node *) lfirst(indexpr_item))); + indexpr_item = lnext(indexprs, indexpr_item); + } + } + elog(ERROR, "wrong number of index expressions"); + return InvalidOid; /* keep compiler quiet */ +} + /* Fill in a SpGistTypeDesc struct with info about the specified data type */ static void fillTypeDesc(SpGistTypeDesc *desc, Oid type) { + HeapTuple tp; + Form_pg_type typtup; + desc->type = type; - get_typlenbyval(type, &desc->attlen, &desc->attbyval); + tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for type %u", type); + typtup = (Form_pg_type) GETSTRUCT(tp); + desc->attlen = typtup->typlen; + desc->attbyval = typtup->typbyval; + desc->attalign = typtup->typalign; + desc->attstorage = typtup->typstorage; + ReleaseSysCache(tp); } /* @@ -117,30 +190,41 @@ spgGetCache(Relation index) cache = MemoryContextAllocZero(index->rd_indexcxt, sizeof(SpGistCache)); - /* SPGiST doesn't support multi-column indexes */ - Assert(index->rd_att->natts == 1); + /* SPGiST must have one key column and can also have INCLUDE columns */ + Assert(IndexRelationGetNumberOfKeyAttributes(index) == 1); + Assert(IndexRelationGetNumberOfAttributes(index) <= INDEX_MAX_KEYS); /* - * Get the actual data type of the indexed column from the index - * tupdesc. We pass this to the opclass config function so that - * polymorphic opclasses are possible. + * Get the actual (well, nominal) data type of the key column. We + * pass this to the opclass config function so that polymorphic + * opclasses are possible. */ - atttype = TupleDescAttr(index->rd_att, 0)->atttypid; + atttype = GetIndexInputType(index, spgKeyColumn + 1); /* Call the config function to get config info for the opclass */ in.attType = atttype; procinfo = index_getprocinfo(index, 1, SPGIST_CONFIG_PROC); FunctionCall2Coll(procinfo, - index->rd_indcollation[0], + index->rd_indcollation[spgKeyColumn], PointerGetDatum(&in), PointerGetDatum(&cache->config)); + /* + * If leafType isn't specified, use the declared index column type, + * which index.c will have derived from the opclass's opcintype. + * (Although we now make spgvalidate.c warn if these aren't the same, + * old user-defined opclasses may not set the STORAGE parameter + * correctly, so believe leafType if it's given.) + */ + if (!OidIsValid(cache->config.leafType)) + cache->config.leafType = + TupleDescAttr(RelationGetDescr(index), spgKeyColumn)->atttypid; + /* Get the information we need about each relevant datatype */ fillTypeDesc(&cache->attType, atttype); - if (OidIsValid(cache->config.leafType) && - cache->config.leafType != atttype) + if (cache->config.leafType != atttype) { if (!OidIsValid(index_getprocid(index, 1, SPGIST_COMPRESS_PROC))) ereport(ERROR, @@ -151,6 +235,7 @@ spgGetCache(Relation index) } else { + /* Save lookups in this common case */ cache->attLeafType = cache->attType; } @@ -182,12 +267,60 @@ spgGetCache(Relation index) return cache; } +/* + * Compute a tuple descriptor for leaf tuples or index-only-scan result tuples. + * + * We can use the relcache's tupdesc as-is in many cases, and it's always + * OK so far as any INCLUDE columns are concerned. However, the entry for + * the key column has to match leafType in the first case or attType in the + * second case. While the relcache's tupdesc *should* show leafType, this + * might not hold for legacy user-defined opclasses, since before v14 they + * were not allowed to declare their true storage type in CREATE OPCLASS. + * Also, attType can be different from what is in the relcache. + * + * This function gives back either a pointer to the relcache's tupdesc + * if that is suitable, or a palloc'd copy that's been adjusted to match + * the specified key column type. We can avoid doing any catalog lookups + * here by insisting that the caller pass an SpGistTypeDesc not just an OID. + */ +TupleDesc +getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType) +{ + TupleDesc outTupDesc; + Form_pg_attribute att; + + if (keyType->type == + TupleDescAttr(RelationGetDescr(index), spgKeyColumn)->atttypid) + outTupDesc = RelationGetDescr(index); + else + { + outTupDesc = CreateTupleDescCopy(RelationGetDescr(index)); + att = TupleDescAttr(outTupDesc, spgKeyColumn); + /* It's sufficient to update the type-dependent fields of the column */ + att->atttypid = keyType->type; + att->atttypmod = -1; + att->attlen = keyType->attlen; + att->attbyval = keyType->attbyval; + att->attalign = keyType->attalign; + att->attstorage = keyType->attstorage; + /* We shouldn't need to bother with making these valid: */ + att->attcompression = InvalidCompressionMethod; + att->attcollation = InvalidOid; + /* In case we changed typlen, we'd better reset following offsets */ + for (int i = spgFirstIncludeColumn; i < outTupDesc->natts; i++) + TupleDescAttr(outTupDesc, i)->attcacheoff = -1; + } + return outTupDesc; +} + /* Initialize SpGistState for working with the given index */ void initSpGistState(SpGistState *state, Relation index) { SpGistCache *cache; + state->index = index; + /* Get cached static information about index */ cache = spgGetCache(index); @@ -197,6 +330,9 @@ initSpGistState(SpGistState *state, Relation index) state->attPrefixType = cache->attPrefixType; state->attLabelType = cache->attLabelType; + /* Ensure we have a valid descriptor for leaf tuples */ + state->leafTupDesc = getSpGistTupleDesc(state->index, &state->attLeafType); + /* Make workspace for constructing dead tuples */ state->deadTupleStorage = palloc0(SGDTSIZE); @@ -541,9 +677,8 @@ SpGistInitPage(Page page, uint16 f) { SpGistPageOpaque opaque; - PageInit(page, BLCKSZ, MAXALIGN(sizeof(SpGistPageOpaqueData))); + PageInit(page, BLCKSZ, sizeof(SpGistPageOpaqueData)); opaque = SpGistPageGetOpaque(page); - memset(opaque, 0, sizeof(SpGistPageOpaqueData)); opaque->flags = f; opaque->spgist_page_id = SPGIST_PAGE_ID; } @@ -603,13 +738,14 @@ spgoptions(Datum reloptions, bool validate) } /* - * Get the space needed to store a non-null datum of the indicated type. + * Get the space needed to store a non-null datum of the indicated type + * in an inner tuple (that is, as a prefix or node label). * Note the result is already rounded up to a MAXALIGN boundary. - * Also, we follow the SPGiST convention that pass-by-val types are - * just stored in their Datum representation (compare memcpyDatum). + * Here we follow the convention that pass-by-val types are just stored + * in their Datum representation (compare memcpyInnerDatum). */ unsigned int -SpGistGetTypeSize(SpGistTypeDesc *att, Datum datum) +SpGistGetInnerTypeSize(SpGistTypeDesc *att, Datum datum) { unsigned int size; @@ -624,10 +760,10 @@ SpGistGetTypeSize(SpGistTypeDesc *att, Datum datum) } /* - * Copy the given non-null datum to *target + * Copy the given non-null datum to *target, in the inner-tuple case */ static void -memcpyDatum(void *target, SpGistTypeDesc *att, Datum datum) +memcpyInnerDatum(void *target, SpGistTypeDesc *att, Datum datum) { unsigned int size; @@ -643,23 +779,111 @@ memcpyDatum(void *target, SpGistTypeDesc *att, Datum datum) } /* - * Construct a leaf tuple containing the given heap TID and datum value + * Compute space required for a leaf tuple holding the given data. + * + * This must match the size-calculation portion of spgFormLeafTuple. + */ +Size +SpGistGetLeafTupleSize(TupleDesc tupleDescriptor, + Datum *datums, bool *isnulls) +{ + Size size; + Size data_size; + bool needs_null_mask = false; + int natts = tupleDescriptor->natts; + + /* + * Decide whether we need a nulls bitmask. + * + * If there is only a key attribute (natts == 1), never use a bitmask, for + * compatibility with the pre-v14 layout of leaf tuples. Otherwise, we + * need one if any attribute is null. + */ + if (natts > 1) + { + for (int i = 0; i < natts; i++) + { + if (isnulls[i]) + { + needs_null_mask = true; + break; + } + } + } + + /* + * Calculate size of the data part; same as for heap tuples. + */ + data_size = heap_compute_data_size(tupleDescriptor, datums, isnulls); + + /* + * Compute total size. + */ + size = SGLTHDRSZ(needs_null_mask); + size += data_size; + size = MAXALIGN(size); + + /* + * Ensure that we can replace the tuple with a dead tuple later. This test + * is unnecessary when there are any non-null attributes, but be safe. + */ + if (size < SGDTSIZE) + size = SGDTSIZE; + + return size; +} + +/* + * Construct a leaf tuple containing the given heap TID and datum values */ SpGistLeafTuple spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, - Datum datum, bool isnull) + Datum *datums, bool *isnulls) { SpGistLeafTuple tup; - unsigned int size; + TupleDesc tupleDescriptor = state->leafTupDesc; + Size size; + Size hoff; + Size data_size; + bool needs_null_mask = false; + int natts = tupleDescriptor->natts; + char *tp; /* ptr to tuple data */ + uint16 tupmask = 0; /* unused heap_fill_tuple output */ - /* compute space needed (note result is already maxaligned) */ - size = SGLTHDRSZ; - if (!isnull) - size += SpGistGetTypeSize(&state->attLeafType, datum); + /* + * Decide whether we need a nulls bitmask. + * + * If there is only a key attribute (natts == 1), never use a bitmask, for + * compatibility with the pre-v14 layout of leaf tuples. Otherwise, we + * need one if any attribute is null. + */ + if (natts > 1) + { + for (int i = 0; i < natts; i++) + { + if (isnulls[i]) + { + needs_null_mask = true; + break; + } + } + } /* - * Ensure that we can replace the tuple with a dead tuple later. This - * test is unnecessary when !isnull, but let's be safe. + * Calculate size of the data part; same as for heap tuples. + */ + data_size = heap_compute_data_size(tupleDescriptor, datums, isnulls); + + /* + * Compute total size. + */ + hoff = SGLTHDRSZ(needs_null_mask); + size = hoff + data_size; + size = MAXALIGN(size); + + /* + * Ensure that we can replace the tuple with a dead tuple later. This test + * is unnecessary when there are any non-null attributes, but be safe. */ if (size < SGDTSIZE) size = SGDTSIZE; @@ -668,10 +892,29 @@ spgFormLeafTuple(SpGistState *state, ItemPointer heapPtr, tup = (SpGistLeafTuple) palloc0(size); tup->size = size; - tup->nextOffset = InvalidOffsetNumber; + SGLT_SET_NEXTOFFSET(tup, InvalidOffsetNumber); tup->heapPtr = *heapPtr; - if (!isnull) - memcpyDatum(SGLTDATAPTR(tup), &state->attLeafType, datum); + + tp = (char *) tup + hoff; + + if (needs_null_mask) + { + bits8 *bp; /* ptr to null bitmap in tuple */ + + /* Set nullmask presence bit in SpGistLeafTuple header */ + SGLT_SET_HASNULLMASK(tup, true); + /* Fill the data area and null mask */ + bp = (bits8 *) ((char *) tup + sizeof(SpGistLeafTupleData)); + heap_fill_tuple(tupleDescriptor, datums, isnulls, tp, data_size, + &tupmask, bp); + } + else if (natts > 1 || !isnulls[spgKeyColumn]) + { + /* Fill data area only */ + heap_fill_tuple(tupleDescriptor, datums, isnulls, tp, data_size, + &tupmask, (bits8 *) NULL); + } + /* otherwise we have no data, nor a bitmap, to fill */ return tup; } @@ -692,7 +935,7 @@ spgFormNodeTuple(SpGistState *state, Datum label, bool isnull) /* compute space needed (note result is already maxaligned) */ size = SGNTHDRSZ; if (!isnull) - size += SpGistGetTypeSize(&state->attLabelType, label); + size += SpGistGetInnerTypeSize(&state->attLabelType, label); /* * Here we make sure that the size will fit in the field reserved for it @@ -716,7 +959,7 @@ spgFormNodeTuple(SpGistState *state, Datum label, bool isnull) ItemPointerSetInvalid(&tup->t_tid); if (!isnull) - memcpyDatum(SGNTDATAPTR(tup), &state->attLabelType, label); + memcpyInnerDatum(SGNTDATAPTR(tup), &state->attLabelType, label); return tup; } @@ -736,7 +979,7 @@ spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix, /* Compute size needed */ if (hasPrefix) - prefixSize = SpGistGetTypeSize(&state->attPrefixType, prefix); + prefixSize = SpGistGetInnerTypeSize(&state->attPrefixType, prefix); else prefixSize = 0; @@ -781,7 +1024,7 @@ spgFormInnerTuple(SpGistState *state, bool hasPrefix, Datum prefix, tup->size = size; if (hasPrefix) - memcpyDatum(SGITDATAPTR(tup), &state->attPrefixType, prefix); + memcpyInnerDatum(SGITDATAPTR(tup), &state->attPrefixType, prefix); ptr = (char *) SGITNODEPTR(tup); @@ -815,7 +1058,7 @@ spgFormDeadTuple(SpGistState *state, int tupstate, tuple->tupstate = tupstate; tuple->size = SGDTSIZE; - tuple->nextOffset = InvalidOffsetNumber; + SGLT_SET_NEXTOFFSET(tuple, InvalidOffsetNumber); if (tupstate == SPGIST_REDIRECT) { @@ -832,6 +1075,52 @@ spgFormDeadTuple(SpGistState *state, int tupstate, return tuple; } +/* + * Convert an SPGiST leaf tuple into Datum/isnull arrays. + * + * The caller must allocate sufficient storage for the output arrays. + * (INDEX_MAX_KEYS entries should be enough.) + */ +void +spgDeformLeafTuple(SpGistLeafTuple tup, TupleDesc tupleDescriptor, + Datum *datums, bool *isnulls, bool keyColumnIsNull) +{ + bool hasNullsMask = SGLT_GET_HASNULLMASK(tup); + char *tp; /* ptr to tuple data */ + bits8 *bp; /* ptr to null bitmap in tuple */ + + if (keyColumnIsNull && tupleDescriptor->natts == 1) + { + /* + * Trivial case: there is only the key attribute and we're in a nulls + * tree. The hasNullsMask bit in the tuple header should not be set + * (and thus we can't use index_deform_tuple_internal), but + * nonetheless the result is NULL. + * + * Note: currently this is dead code, because noplace calls this when + * there is only the key attribute. But we should cover the case. + */ + Assert(!hasNullsMask); + + datums[spgKeyColumn] = (Datum) 0; + isnulls[spgKeyColumn] = true; + return; + } + + tp = (char *) tup + SGLTHDRSZ(hasNullsMask); + bp = (bits8 *) ((char *) tup + sizeof(SpGistLeafTupleData)); + + index_deform_tuple_internal(tupleDescriptor, + datums, isnulls, + tp, bp, hasNullsMask); + + /* + * Key column isnull value from the tuple should be consistent with + * keyColumnIsNull flag from the caller. + */ + Assert(keyColumnIsNull == isnulls[spgKeyColumn]); +} + /* * Extract the label datums of the nodes within innerTuple * diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c index e1c58933f979..76fb0374c42a 100644 --- a/src/backend/access/spgist/spgvacuum.c +++ b/src/backend/access/spgist/spgvacuum.c @@ -4,7 +4,7 @@ * vacuum for SP-GiST * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -168,23 +168,23 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer, } /* Form predecessor map, too */ - if (lt->nextOffset != InvalidOffsetNumber) + if (SGLT_GET_NEXTOFFSET(lt) != InvalidOffsetNumber) { /* paranoia about corrupted chain links */ - if (lt->nextOffset < FirstOffsetNumber || - lt->nextOffset > max || - predecessor[lt->nextOffset] != InvalidOffsetNumber) + if (SGLT_GET_NEXTOFFSET(lt) < FirstOffsetNumber || + SGLT_GET_NEXTOFFSET(lt) > max || + predecessor[SGLT_GET_NEXTOFFSET(lt)] != InvalidOffsetNumber) elog(ERROR, "inconsistent tuple chain links in page %u of index \"%s\"", BufferGetBlockNumber(buffer), RelationGetRelationName(index)); - predecessor[lt->nextOffset] = i; + predecessor[SGLT_GET_NEXTOFFSET(lt)] = i; } } else if (lt->tupstate == SPGIST_REDIRECT) { SpGistDeadTuple dt = (SpGistDeadTuple) lt; - Assert(dt->nextOffset == InvalidOffsetNumber); + Assert(SGLT_GET_NEXTOFFSET(dt) == InvalidOffsetNumber); Assert(ItemPointerIsValid(&dt->pointer)); /* @@ -201,7 +201,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer, } else { - Assert(lt->nextOffset == InvalidOffsetNumber); + Assert(SGLT_GET_NEXTOFFSET(lt) == InvalidOffsetNumber); } } @@ -250,7 +250,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer, prevLive = deletable[i] ? InvalidOffsetNumber : i; /* scan down the chain ... */ - j = head->nextOffset; + j = SGLT_GET_NEXTOFFSET(head); while (j != InvalidOffsetNumber) { SpGistLeafTuple lt; @@ -301,7 +301,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer, interveningDeletable = false; } - j = lt->nextOffset; + j = SGLT_GET_NEXTOFFSET(lt); } if (prevLive == InvalidOffsetNumber) @@ -366,7 +366,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer, lt = (SpGistLeafTuple) PageGetItem(page, PageGetItemId(page, chainSrc[i])); Assert(lt->tupstate == SPGIST_LIVE); - lt->nextOffset = chainDest[i]; + SGLT_SET_NEXTOFFSET(lt, chainDest[i]); } MarkBufferDirty(buffer); @@ -891,6 +891,7 @@ spgvacuumscan(spgBulkDeleteState *bds) /* Report final stats */ bds->stats->num_pages = num_pages; + bds->stats->pages_newly_deleted = bds->stats->pages_deleted; bds->stats->pages_free = bds->stats->pages_deleted; } diff --git a/src/backend/access/spgist/spgvalidate.c b/src/backend/access/spgist/spgvalidate.c index d4f5841e2656..472a28b8080e 100644 --- a/src/backend/access/spgist/spgvalidate.c +++ b/src/backend/access/spgist/spgvalidate.c @@ -3,7 +3,7 @@ * spgvalidate.c * Opclass validator for SP-GiST. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -43,6 +43,7 @@ spgvalidate(Oid opclassoid) Form_pg_opclass classform; Oid opfamilyoid; Oid opcintype; + Oid opckeytype; char *opclassname; HeapTuple familytup; Form_pg_opfamily familyform; @@ -57,6 +58,7 @@ spgvalidate(Oid opclassoid) spgConfigOut configOut; Oid configOutLefttype = InvalidOid; Oid configOutRighttype = InvalidOid; + Oid configOutLeafType = InvalidOid; /* Fetch opclass information */ classtup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassoid)); @@ -66,6 +68,7 @@ spgvalidate(Oid opclassoid) opfamilyoid = classform->opcfamily; opcintype = classform->opcintype; + opckeytype = classform->opckeytype; opclassname = NameStr(classform->opcname); /* Fetch opfamily information */ @@ -118,13 +121,31 @@ spgvalidate(Oid opclassoid) configOutLefttype = procform->amproclefttype; configOutRighttype = procform->amprocrighttype; + /* Default leaf type is opckeytype or input type */ + if (OidIsValid(opckeytype)) + configOutLeafType = opckeytype; + else + configOutLeafType = procform->amproclefttype; + + /* If some other leaf datum type is specified, warn */ + if (OidIsValid(configOut.leafType) && + configOutLeafType != configOut.leafType) + { + ereport(INFO, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("SP-GiST leaf data type %s does not match declared type %s", + format_type_be(configOut.leafType), + format_type_be(configOutLeafType)))); + result = false; + configOutLeafType = configOut.leafType; + } + /* * When leaf and attribute types are the same, compress * function is not required and we set corresponding bit in * functionset for later group consistency check. */ - if (!OidIsValid(configOut.leafType) || - configOut.leafType == configIn.attType) + if (configOutLeafType == configIn.attType) { foreach(lc, grouplist) { @@ -156,7 +177,7 @@ spgvalidate(Oid opclassoid) ok = false; else ok = check_amproc_signature(procform->amproc, - configOut.leafType, true, + configOutLeafType, true, 1, 1, procform->amproclefttype); break; case SPGIST_OPTIONS_PROC: diff --git a/src/backend/access/spgist/spgxlog.c b/src/backend/access/spgist/spgxlog.c index 999d0ca15d56..3dfd2aa317b5 100644 --- a/src/backend/access/spgist/spgxlog.c +++ b/src/backend/access/spgist/spgxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for SP-GiST * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -122,8 +122,8 @@ spgRedoAddLeaf(XLogReaderState *record) head = (SpGistLeafTuple) PageGetItem(page, PageGetItemId(page, xldata->offnumHeadLeaf)); - Assert(head->nextOffset == leafTupleHdr.nextOffset); - head->nextOffset = xldata->offnumLeaf; + Assert(SGLT_GET_NEXTOFFSET(head) == SGLT_GET_NEXTOFFSET(&leafTupleHdr)); + SGLT_SET_NEXTOFFSET(head, xldata->offnumLeaf); } } else @@ -822,7 +822,7 @@ spgRedoVacuumLeaf(XLogReaderState *record) lt = (SpGistLeafTuple) PageGetItem(page, PageGetItemId(page, chainSrc[i])); Assert(lt->tupstate == SPGIST_LIVE); - lt->nextOffset = chainDest[i]; + SGLT_SET_NEXTOFFSET(lt, chainDest[i]); } PageSetLSN(page, lsn); diff --git a/src/backend/access/table/table.c b/src/backend/access/table/table.c index 19d0c2c76b7f..ba39b6a47369 100644 --- a/src/backend/access/table/table.c +++ b/src/backend/access/table/table.c @@ -3,7 +3,7 @@ * table.c * Generic routines for table related code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -62,6 +62,40 @@ table_open(Oid relationId, LOCKMODE lockmode) return r; } + +/* ---------------- + * try_table_open - open a table relation by relation OID + * + * Same as table_open, except return NULL instead of failing + * if the relation does not exist. + * ---------------- + */ +Relation +try_table_open(Oid relationId, LOCKMODE lockmode, bool noWait) +{ + Relation r; + + r = try_relation_open(relationId, lockmode, noWait); + + /* leave if table does not exist */ + if (!r) + return NULL; + + if (r->rd_rel->relkind == RELKIND_INDEX || + r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an index", + RelationGetRelationName(r)))); + else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a composite type", + RelationGetRelationName(r)))); + + return r; +} + /* ---------------- * table_openrv - open a table relation specified * by a RangeVar node @@ -125,36 +159,6 @@ table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, return r; } -/* ---------------- - * try_table_open - open a heap relation by relation OID - * - * As above, but relation return NULL for relation-not-found - * ---------------- - */ -Relation -try_table_open(Oid relationId, LOCKMODE lockmode, bool noWait) -{ - Relation r; - - r = try_relation_open(relationId, lockmode, noWait); - - if (!RelationIsValid(r)) - return NULL; - - if (r->rd_rel->relkind == RELKIND_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - - return r; -} - /* ---------------- * table_close - close a table * diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index f10f8941e3f2..f3291b90feff 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -3,7 +3,7 @@ * tableam.c * Table access method routines too big to be inline functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -709,18 +709,14 @@ table_block_relation_estimate_size(Relation rel, int32 *attr_widths, * doesn't happen instantaneously, and it won't happen at all for cases * such as temporary tables.) * - * We approximate "never vacuumed" by "has relpages = 0", which means this - * will also fire on genuinely empty relations. Not great, but - * fortunately that's a seldom-seen case in the real world, and it - * shouldn't degrade the quality of the plan too much anyway to err in - * this direction. + * We test "never vacuumed" by seeing whether reltuples < 0. * * If the table has inheritance children, we don't apply this heuristic. * Totally empty parent tables are quite common, so we should be willing * to believe that they are empty. */ if (curpages < 10 && - relpages == 0 && + reltuples < 0 && !rel->rd_rel->relhassubclass) curpages = 10; @@ -735,17 +731,17 @@ table_block_relation_estimate_size(Relation rel, int32 *attr_widths, } /* estimate number of tuples from previous tuple density */ - if (relpages > 0) + if (reltuples >= 0 && relpages > 0) density = reltuples / (double) relpages; else { /* - * When we have no data because the relation was truncated, estimate - * tuple width from attribute datatypes. We assume here that the - * pages are completely full, which is OK for tables (since they've - * presumably not been VACUUMed yet) but is probably an overestimate - * for indexes. Fortunately get_relation_info() can clamp the - * overestimate to the parent table's size. + * When we have no data because the relation was never yet vacuumed, + * estimate tuple width from attribute datatypes. We assume here that + * the pages are completely full, which is OK for tables but is + * probably an overestimate for indexes. Fortunately + * get_relation_info() can clamp the overestimate to the parent + * table's size. * * Note: this code intentionally disregards alignment considerations, * because (a) that would be gilding the lily considering how crude diff --git a/src/backend/access/table/tableamapi.c b/src/backend/access/table/tableamapi.c index 58de0743ba05..325ecdc12291 100644 --- a/src/backend/access/table/tableamapi.c +++ b/src/backend/access/table/tableamapi.c @@ -3,7 +3,7 @@ * tableamapi.c * Support routines for API for Postgres table access methods * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/table/tableamapi.c @@ -66,7 +66,7 @@ GetTableAmRoutine(Oid amhandler) Assert(routine->tuple_tid_valid != NULL); Assert(routine->tuple_get_latest_tid != NULL); Assert(routine->tuple_satisfies_snapshot != NULL); - Assert(routine->compute_xid_horizon_for_tuples != NULL); + Assert(routine->index_delete_tuples != NULL); Assert(routine->tuple_insert != NULL); diff --git a/src/backend/access/table/toast_helper.c b/src/backend/access/table/toast_helper.c index 4ff465c43a60..23aaff669aa9 100644 --- a/src/backend/access/table/toast_helper.c +++ b/src/backend/access/table/toast_helper.c @@ -4,7 +4,7 @@ * Helper functions for table AMs implementing compressed or * out-of-line storage of varlena attributes. * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/access/table/toast_helper.c @@ -54,6 +54,7 @@ toast_tuple_init(ToastTupleContext *ttc) ttc->ttc_attr[i].tai_colflags = 0; ttc->ttc_attr[i].tai_oldexternal = NULL; + ttc->ttc_attr[i].tai_compression = att->attcompression; if (ttc->ttc_oldvalues != NULL) { @@ -226,9 +227,11 @@ void toast_tuple_try_compression(ToastTupleContext *ttc, int attribute) { Datum *value = &ttc->ttc_values[attribute]; - Datum new_value = toast_compress_datum(*value); + Datum new_value; ToastAttrInfo *attr = &ttc->ttc_attr[attribute]; + new_value = toast_compress_datum(*value, attr->tai_compression); + if (DatumGetPointer(new_value) != NULL) { /* successful compression */ diff --git a/src/backend/access/tablesample/bernoulli.c b/src/backend/access/tablesample/bernoulli.c index fb4ff5abcdc0..f5456923da61 100644 --- a/src/backend/access/tablesample/bernoulli.c +++ b/src/backend/access/tablesample/bernoulli.c @@ -13,7 +13,7 @@ * cutoff value computed from the selection probability by BeginSampleScan. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/tablesample/system.c b/src/backend/access/tablesample/system.c index 70a5bf2ac4a6..361c217ac9ba 100644 --- a/src/backend/access/tablesample/system.c +++ b/src/backend/access/tablesample/system.c @@ -13,7 +13,7 @@ * cutoff value computed from the selection probability by BeginSampleScan. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/tablesample/tablesample.c b/src/backend/access/tablesample/tablesample.c index f0e2f7be4410..02f2a95e84f1 100644 --- a/src/backend/access/tablesample/tablesample.c +++ b/src/backend/access/tablesample/tablesample.c @@ -3,7 +3,7 @@ * tablesample.c * Support functions for TABLESAMPLE feature * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 8f41e4f34e71..32928c98f0eb 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -23,7 +23,7 @@ * for aborts (whether sync or async), since the post-crash assumption would * be that such transactions failed anyway. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/clog.c @@ -42,6 +42,7 @@ #include "pg_trace.h" #include "pgstat.h" #include "storage/proc.h" +#include "storage/sync.h" /* * Defines for CLOG page sizes. A page is the same BLCKSZ as is used @@ -450,7 +451,12 @@ TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, if (nextidx != INVALID_PGPROCNO && ProcGlobal->allProcs[nextidx].clogGroupMemberPage != proc->clogGroupMemberPage) { + /* + * Ensure that this proc is not a member of any clog group that + * needs an XID status update. + */ proc->clogGroupMember = false; + pg_atomic_write_u32(&proc->clogGroupNext, INVALID_PGPROCNO); return false; } @@ -801,7 +807,9 @@ CLOGShmemInit(void) { XactCtl->PagePrecedes = CLOGPagePrecedes; SimpleLruInit(XactCtl, "Xact", CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE, - XactSLRULock, "pg_xact", LWTRANCHE_XACT_BUFFER); + XactSLRULock, "pg_xact", LWTRANCHE_XACT_BUFFER, + SYNC_HANDLER_CLOG); + SlruPagePrecedesUnitTests(XactCtl, CLOG_XACTS_PER_PAGE); } /* @@ -880,11 +888,6 @@ TrimCLOG(void) LWLockAcquire(XactSLRULock, LW_EXCLUSIVE); - /* - * Re-Initialize our idea of the latest page number. - */ - XactCtl->shared->latest_page_number = pageno; - /* * Zero out the remainder of the current clog page. Under normal * circumstances it should be zeroes already, but it seems at least @@ -918,41 +921,19 @@ TrimCLOG(void) LWLockRelease(XactSLRULock); } -/* - * This must be called ONCE during postmaster or standalone-backend shutdown - */ -void -ShutdownCLOG(void) -{ - /* Flush dirty CLOG pages to disk */ - TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(false); - SimpleLruFlush(XactCtl, false); - - /* - * fsync pg_xact to ensure that any files flushed previously are durably - * on disk. - */ - fsync_fname("pg_xact", true); - - TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(false); -} - /* * Perform a checkpoint --- either during shutdown, or on-the-fly */ void CheckPointCLOG(void) { - /* Flush dirty CLOG pages to disk */ - TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true); - SimpleLruFlush(XactCtl, true); - /* - * fsync pg_xact to ensure that any files flushed previously are durably - * on disk. + * Write dirty CLOG pages to disk. This may result in sync requests + * queued for later handling by ProcessSyncRequests(), as part of the + * checkpoint. */ - fsync_fname("pg_xact", true); - + TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true); + SimpleLruWriteAll(XactCtl, true); TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(true); } @@ -1042,13 +1023,22 @@ TruncateCLOG(TransactionId oldestXact, Oid oldestxid_datoid) /* - * Decide which of two CLOG page numbers is "older" for truncation purposes. + * Decide whether a CLOG page number is "older" for truncation purposes. * * We need to use comparison of TransactionIds here in order to do the right - * thing with wraparound XID arithmetic. However, if we are asked about - * page number zero, we don't want to hand InvalidTransactionId to - * TransactionIdPrecedes: it'll get weird about permanent xact IDs. So, - * offset both xids by FirstNormalTransactionId to avoid that. + * thing with wraparound XID arithmetic. However, TransactionIdPrecedes() + * would get weird about permanent xact IDs. So, offset both such that xid1, + * xid2, and xid2 + CLOG_XACTS_PER_PAGE - 1 are all normal XIDs; this offset + * is relevant to page 0 and to the page preceding page 0. + * + * The page containing oldestXact-2^31 is the important edge case. The + * portion of that page equaling or following oldestXact-2^31 is expendable, + * but the portion preceding oldestXact-2^31 is not. When oldestXact-2^31 is + * the first XID of a page and segment, the entire page and segment is + * expendable, and we could truncate the segment. Recognizing that case would + * require making oldestXact, not just the page containing oldestXact, + * available to this callback. The benefit would be rare and small, so we + * don't optimize that edge case. */ static bool CLOGPagePrecedes(int page1, int page2) @@ -1057,11 +1047,12 @@ CLOGPagePrecedes(int page1, int page2) TransactionId xid2; xid1 = ((TransactionId) page1) * CLOG_XACTS_PER_PAGE; - xid1 += FirstNormalTransactionId; + xid1 += FirstNormalTransactionId + 1; xid2 = ((TransactionId) page2) * CLOG_XACTS_PER_PAGE; - xid2 += FirstNormalTransactionId; + xid2 += FirstNormalTransactionId + 1; - return TransactionIdPrecedes(xid1, xid2); + return (TransactionIdPrecedes(xid1, xid2) && + TransactionIdPrecedes(xid1, xid2 + CLOG_XACTS_PER_PAGE - 1)); } @@ -1130,12 +1121,6 @@ clog_redo(XLogReaderState *record) memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_clog_truncate)); - /* - * During XLOG replay, latest_page_number isn't set up yet; insert a - * suitable value to bypass the sanity test in SimpleLruTruncate. - */ - XactCtl->shared->latest_page_number = xlrec.pageno; - AdvanceOldestClogXid(xlrec.oldestXact); SimpleLruTruncate(XactCtl, xlrec.pageno); @@ -1143,3 +1128,12 @@ clog_redo(XLogReaderState *record) else elog(PANIC, "clog_redo: unknown op code %u", info); } + +/* + * Entrypoint for sync.c to sync clog files. + */ +int +clogsyncfiletag(const FileTag *ftag, char *path) +{ + return SlruSyncFileTag(XactCtl, ftag, path); +} diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c index 5244b06a2b65..0985fa155cae 100644 --- a/src/backend/access/transam/commit_ts.c +++ b/src/backend/access/transam/commit_ts.c @@ -15,7 +15,7 @@ * re-perform the status update on redo; so we need make no additional XLOG * entry here. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/commit_ts.c @@ -114,9 +114,6 @@ static void ActivateCommitTs(void); static void DeactivateCommitTs(void); static void WriteZeroPageXlogRec(int pageno); static void WriteTruncateXlogRec(int pageno, TransactionId oldestXid); -static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids, - TransactionId *subxids, TimestampTz timestamp, - RepOriginId nodeid); /* * TransactionTreeSetCommitTsData @@ -133,18 +130,11 @@ static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids, * permanent) so we need to keep the information about them here. If the * subtrans implementation changes in the future, we might want to revisit the * decision of storing timestamp info for each subxid. - * - * The write_xlog parameter tells us whether to include an XLog record of this - * or not. Normally, this is called from transaction commit routines (both - * normal and prepared) and the information will be stored in the transaction - * commit XLog record, and so they should pass "false" for this. The XLog redo - * code should use "false" here as well. Other callers probably want to pass - * true, so that the given values persist in case of crashes. */ void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, - RepOriginId nodeid, bool write_xlog) + RepOriginId nodeid) { int i; TransactionId headxid; @@ -161,13 +151,6 @@ TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, if (!commitTsShared->commitTsActive) return; - /* - * Comply with the WAL-before-data rule: if caller specified it wants this - * value to be recorded in WAL, do so before touching the data. - */ - if (write_xlog) - WriteSetTimestampXlogRec(xid, nsubxids, subxids, timestamp, nodeid); - /* * Figure out the latest Xid in this batch: either the last subxid if * there's any, otherwise the parent xid. @@ -404,7 +387,7 @@ error_commit_ts_disabled(void) Datum pg_xact_commit_timestamp(PG_FUNCTION_ARGS) { - TransactionId xid = PG_GETARG_UINT32(0); + TransactionId xid = PG_GETARG_TRANSACTIONID(0); TimestampTz ts; bool found; @@ -481,7 +464,7 @@ pg_last_committed_xact(PG_FUNCTION_ARGS) Datum pg_xact_commit_timestamp_origin(PG_FUNCTION_ARGS) { - TransactionId xid = PG_GETARG_UINT32(0); + TransactionId xid = PG_GETARG_TRANSACTIONID(0); RepOriginId nodeid; TimestampTz ts; Datum values[2]; @@ -555,7 +538,9 @@ CommitTsShmemInit(void) CommitTsCtl->PagePrecedes = CommitTsPagePrecedes; SimpleLruInit(CommitTsCtl, "CommitTs", CommitTsShmemBuffers(), 0, CommitTsSLRULock, "pg_commit_ts", - LWTRANCHE_COMMITTS_BUFFER); + LWTRANCHE_COMMITTS_BUFFER, + SYNC_HANDLER_COMMIT_TS); + SlruPagePrecedesUnitTests(CommitTsCtl, COMMIT_TS_XACTS_PER_PAGE); commitTsShared = ShmemInitStruct("CommitTs shared", sizeof(CommitTimestampShared), @@ -731,7 +716,7 @@ ActivateCommitTs(void) if (ShmemVariableCache->oldestCommitTsXid == InvalidTransactionId) { ShmemVariableCache->oldestCommitTsXid = - ShmemVariableCache->newestCommitTsXid = ReadNewTransactionId(); + ShmemVariableCache->newestCommitTsXid = ReadNextTransactionId(); } LWLockRelease(CommitTsLock); @@ -798,36 +783,18 @@ DeactivateCommitTs(void) LWLockRelease(CommitTsSLRULock); } -/* - * This must be called ONCE during postmaster or standalone-backend shutdown - */ -void -ShutdownCommitTs(void) -{ - /* Flush dirty CommitTs pages to disk */ - SimpleLruFlush(CommitTsCtl, false); - - /* - * fsync pg_commit_ts to ensure that any files flushed previously are - * durably on disk. - */ - fsync_fname("pg_commit_ts", true); -} - /* * Perform a checkpoint --- either during shutdown, or on-the-fly */ void CheckPointCommitTs(void) { - /* Flush dirty CommitTs pages to disk */ - SimpleLruFlush(CommitTsCtl, true); - /* - * fsync pg_commit_ts to ensure that any files flushed previously are - * durably on disk. + * Write dirty CommitTs pages to disk. This may result in sync requests + * queued for later handling by ProcessSyncRequests(), as part of the + * checkpoint. */ - fsync_fname("pg_commit_ts", true); + SimpleLruWriteAll(CommitTsCtl, true); } /* @@ -944,14 +911,27 @@ AdvanceOldestCommitTsXid(TransactionId oldestXact) /* - * Decide which of two commitTS page numbers is "older" for truncation - * purposes. + * Decide whether a commitTS page number is "older" for truncation purposes. + * Analogous to CLOGPagePrecedes(). * - * We need to use comparison of TransactionIds here in order to do the right - * thing with wraparound XID arithmetic. However, if we are asked about - * page number zero, we don't want to hand InvalidTransactionId to - * TransactionIdPrecedes: it'll get weird about permanent xact IDs. So, - * offset both xids by FirstNormalTransactionId to avoid that. + * At default BLCKSZ, (1 << 31) % COMMIT_TS_XACTS_PER_PAGE == 128. This + * introduces differences compared to CLOG and the other SLRUs having (1 << + * 31) % per_page == 0. This function never tests exactly + * TransactionIdPrecedes(x-2^31, x). When the system reaches xidStopLimit, + * there are two possible counts of page boundaries between oldestXact and the + * latest XID assigned, depending on whether oldestXact is within the first + * 128 entries of its page. Since this function doesn't know the location of + * oldestXact within page2, it returns false for one page that actually is + * expendable. This is a wider (yet still negligible) version of the + * truncation opportunity that CLOGPagePrecedes() cannot recognize. + * + * For the sake of a worked example, number entries with decimal values such + * that page1==1 entries range from 1.0 to 1.999. Let N+0.15 be the number of + * pages that 2^31 entries will span (N is an integer). If oldestXact=N+2.1, + * then the final safe XID assignment leaves newestXact=1.95. We keep page 2, + * because entry=2.85 is the border that toggles whether entries precede the + * last entry of the oldestXact page. While page 2 is expendable at + * oldestXact=N+2.1, it would be precious at oldestXact=N+2.9. */ static bool CommitTsPagePrecedes(int page1, int page2) @@ -960,11 +940,12 @@ CommitTsPagePrecedes(int page1, int page2) TransactionId xid2; xid1 = ((TransactionId) page1) * COMMIT_TS_XACTS_PER_PAGE; - xid1 += FirstNormalTransactionId; + xid1 += FirstNormalTransactionId + 1; xid2 = ((TransactionId) page2) * COMMIT_TS_XACTS_PER_PAGE; - xid2 += FirstNormalTransactionId; + xid2 += FirstNormalTransactionId + 1; - return TransactionIdPrecedes(xid1, xid2); + return (TransactionIdPrecedes(xid1, xid2) && + TransactionIdPrecedes(xid1, xid2 + COMMIT_TS_XACTS_PER_PAGE - 1)); } @@ -995,28 +976,6 @@ WriteTruncateXlogRec(int pageno, TransactionId oldestXid) (void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_TRUNCATE); } -/* - * Write a SETTS xlog record - */ -static void -WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids, - TransactionId *subxids, TimestampTz timestamp, - RepOriginId nodeid) -{ - xl_commit_ts_set record; - - record.timestamp = timestamp; - record.nodeid = nodeid; - record.mainxid = mainxid; - - XLogBeginInsert(); - XLogRegisterData((char *) &record, - offsetof(xl_commit_ts_set, mainxid) + - sizeof(TransactionId)); - XLogRegisterData((char *) subxids, nsubxids * sizeof(TransactionId)); - XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_SETTS); -} - /* * CommitTS resource manager's routines */ @@ -1057,29 +1016,15 @@ commit_ts_redo(XLogReaderState *record) SimpleLruTruncate(CommitTsCtl, trunc->pageno); } - else if (info == COMMIT_TS_SETTS) - { - xl_commit_ts_set *setts = (xl_commit_ts_set *) XLogRecGetData(record); - int nsubxids; - TransactionId *subxids; - - nsubxids = ((XLogRecGetDataLen(record) - SizeOfCommitTsSet) / - sizeof(TransactionId)); - if (nsubxids > 0) - { - subxids = palloc(sizeof(TransactionId) * nsubxids); - memcpy(subxids, - XLogRecGetData(record) + SizeOfCommitTsSet, - sizeof(TransactionId) * nsubxids); - } - else - subxids = NULL; - - TransactionTreeSetCommitTsData(setts->mainxid, nsubxids, subxids, - setts->timestamp, setts->nodeid, true); - if (subxids) - pfree(subxids); - } else elog(PANIC, "commit_ts_redo: unknown op code %u", info); } + +/* + * Entrypoint for sync.c to sync commit_ts files. + */ +int +committssyncfiletag(const FileTag *ftag, char *path) +{ + return SlruSyncFileTag(CommitTsCtl, ftag, path); +} diff --git a/src/backend/access/transam/distributedlog.c b/src/backend/access/transam/distributedlog.c index 6d083c30a75b..97ee20be076e 100644 --- a/src/backend/access/transam/distributedlog.c +++ b/src/backend/access/transam/distributedlog.c @@ -661,7 +661,8 @@ DistributedLog_ShmemInit(void) DistributedLogCtl->PagePrecedes = DistributedLog_PagePrecedes; SimpleLruInit(DistributedLogCtl, "DistributedLogCtl", DistributedLog_ShmemBuffers(), 0, DistributedLogControlLock, "pg_distributedlog", - LWTRANCHE_DISTRIBUTEDLOG_BUFFERS); + LWTRANCHE_DISTRIBUTEDLOG_BUFFERS, + SYNC_HANDLER_NONE); /* Create or attach to the shared structure */ DistributedLogShared = @@ -849,7 +850,7 @@ DistributedLog_Shutdown(void) "DistributedLog_Shutdown"); /* Flush dirty DistributedLog pages to disk */ - SimpleLruFlush(DistributedLogCtl, false); + SimpleLruWriteAll(DistributedLogCtl, false); } /* @@ -865,7 +866,7 @@ DistributedLog_CheckPoint(void) "DistributedLog_CheckPoint"); /* Flush dirty DistributedLog pages to disk */ - SimpleLruFlush(DistributedLogCtl, true); + SimpleLruWriteAll(DistributedLogCtl, true); } diff --git a/src/backend/access/transam/generic_xlog.c b/src/backend/access/transam/generic_xlog.c index 5164a1c2f30d..63301a1ab168 100644 --- a/src/backend/access/transam/generic_xlog.c +++ b/src/backend/access/transam/generic_xlog.c @@ -4,7 +4,7 @@ * Implementation of generic xlog records. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/generic_xlog.c diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 125af0163d37..2dae76c1efa7 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -59,7 +59,7 @@ * counter does not fall within the wraparound horizon considering the global * minimum value. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/multixact.c @@ -734,6 +734,25 @@ ReadNextMultiXactId(void) return mxid; } +/* + * ReadMultiXactIdRange + * Get the range of IDs that may still be referenced by a relation. + */ +void +ReadMultiXactIdRange(MultiXactId *oldest, MultiXactId *next) +{ + LWLockAcquire(MultiXactGenLock, LW_SHARED); + *oldest = MultiXactState->oldestMultiXactId; + *next = MultiXactState->nextMXact; + LWLockRelease(MultiXactGenLock); + + if (*oldest < FirstMultiXactId) + *oldest = FirstMultiXactId; + if (*next < FirstMultiXactId) + *next = FirstMultiXactId; +} + + /* * MultiXactIdCreateFromMembers * Make a new MultiXactId from the specified set of members @@ -1221,7 +1240,10 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, debug_elog3(DEBUG2, "GetMembers: asked for %u", multi); if (!MultiXactIdIsValid(multi) || from_pgupgrade) + { + *members = NULL; return -1; + } /* See if the MultiXactId is in the local cache */ length = mXactCacheGetById(multi, members); @@ -1272,13 +1294,10 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, LWLockRelease(MultiXactGenLock); if (MultiXactIdPrecedes(multi, oldestMXact)) - { ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("MultiXactId %u does no longer exist -- apparent wraparound", multi))); - return -1; - } if (!MultiXactIdPrecedes(multi, nextMXact)) ereport(ERROR, @@ -1378,7 +1397,6 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, LWLockRelease(MultiXactOffsetSLRULock); ptr = (MultiXactMember *) palloc(length * sizeof(MultiXactMember)); - *members = ptr; /* Now get the members themselves. */ LWLockAcquire(MultiXactMemberSLRULock, LW_EXCLUSIVE); @@ -1423,6 +1441,9 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, LWLockRelease(MultiXactMemberSLRULock); + /* A multixid with zero members should not happen */ + Assert(truelength > 0); + /* * Copy the result into the local cache. */ @@ -1430,6 +1451,7 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, debug_elog3(DEBUG2, "GetMembers: no cache for %s", mxid_to_string(multi, truelength, ptr)); + *members = ptr; return truelength; } @@ -1530,7 +1552,6 @@ mXactCacheGetById(MultiXactId multi, MultiXactMember **members) size = sizeof(MultiXactMember) * entry->nmembers; ptr = (MultiXactMember *) palloc(size); - *members = ptr; memcpy(ptr, entry->members, size); @@ -1546,6 +1567,7 @@ mXactCacheGetById(MultiXactId multi, MultiXactMember **members) */ dlist_move_head(&MXactCache, iter.cur); + *members = ptr; return entry->nmembers; } } @@ -1741,7 +1763,7 @@ PostPrepare_MultiXact(TransactionId xid) OldestVisibleMXactId[MyBackendId] = InvalidMultiXactId; /* - * Discard the local MultiXactId cache like in AtEOX_MultiXact + * Discard the local MultiXactId cache like in AtEOXact_MultiXact. */ MXactContext = NULL; dlist_init(&MXactCache); @@ -1771,7 +1793,7 @@ multixact_twophase_recover(TransactionId xid, uint16 info, /* * multixact_twophase_postcommit - * Similar to AtEOX_MultiXact but for COMMIT PREPARED + * Similar to AtEOXact_MultiXact but for COMMIT PREPARED */ void multixact_twophase_postcommit(TransactionId xid, uint16 info, @@ -1830,11 +1852,15 @@ MultiXactShmemInit(void) SimpleLruInit(MultiXactOffsetCtl, "MultiXactOffset", NUM_MULTIXACTOFFSET_BUFFERS, 0, MultiXactOffsetSLRULock, "pg_multixact/offsets", - LWTRANCHE_MULTIXACTOFFSET_BUFFER); + LWTRANCHE_MULTIXACTOFFSET_BUFFER, + SYNC_HANDLER_MULTIXACT_OFFSET); + SlruPagePrecedesUnitTests(MultiXactOffsetCtl, MULTIXACT_OFFSETS_PER_PAGE); SimpleLruInit(MultiXactMemberCtl, "MultiXactMember", NUM_MULTIXACTMEMBER_BUFFERS, 0, MultiXactMemberSLRULock, "pg_multixact/members", - LWTRANCHE_MULTIXACTMEMBER_BUFFER); + LWTRANCHE_MULTIXACTMEMBER_BUFFER, + SYNC_HANDLER_MULTIXACT_MEMBER); + /* doesn't call SimpleLruTruncate() or meet criteria for unit tests */ /* Initialize our shared state struct */ MultiXactState = ShmemInitStruct("Shared MultiXact State", @@ -2107,8 +2133,8 @@ ShutdownMultiXact(void) { /* Flush dirty MultiXact pages to disk */ TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START(false); - SimpleLruFlush(MultiXactOffsetCtl, false); - SimpleLruFlush(MultiXactMemberCtl, false); + SimpleLruWriteAll(MultiXactOffsetCtl, false); + SimpleLruWriteAll(MultiXactMemberCtl, false); TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(false); } @@ -2143,9 +2169,13 @@ CheckPointMultiXact(void) { TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START(true); - /* Flush dirty MultiXact pages to disk */ - SimpleLruFlush(MultiXactOffsetCtl, true); - SimpleLruFlush(MultiXactMemberCtl, true); + /* + * Write dirty MultiXact pages to disk. This may result in sync requests + * queued for later handling by ProcessSyncRequests(), as part of the + * checkpoint. + */ + SimpleLruWriteAll(MultiXactOffsetCtl, true); + SimpleLruWriteAll(MultiXactMemberCtl, true); TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(true); } @@ -2263,8 +2293,8 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, /* Log the info */ ereport(DEBUG1, - (errmsg("MultiXactId wrap limit is %u, limited by database with OID %u", - multiWrapLimit, oldest_datoid))); + (errmsg_internal("MultiXactId wrap limit is %u, limited by database with OID %u", + multiWrapLimit, oldest_datoid))); /* * Computing the actual limits is only possible once the data directory is @@ -2597,8 +2627,8 @@ SetOffsetVacuumLimit(bool is_startup) if (oldestOffsetKnown) ereport(DEBUG1, - (errmsg("oldest MultiXactId member is at offset %u", - oldestOffset))); + (errmsg_internal("oldest MultiXactId member is at offset %u", + oldestOffset))); else ereport(LOG, (errmsg("MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk", @@ -2626,8 +2656,8 @@ SetOffsetVacuumLimit(bool is_startup) (errmsg("MultiXact member wraparound protections are now enabled"))); ereport(DEBUG1, - (errmsg("MultiXact member stop limit is now %u based on MultiXact %u", - offsetStopLimit, oldestMultiXactId))); + (errmsg_internal("MultiXact member stop limit is now %u based on MultiXact %u", + offsetStopLimit, oldestMultiXactId))); } else if (prevOldestOffsetKnown) { @@ -2728,14 +2758,10 @@ find_multixact_start(MultiXactId multi, MultiXactOffset *result) entryno = MultiXactIdToOffsetEntry(multi); /* - * Flush out dirty data, so PhysicalPageExists can work correctly. - * SimpleLruFlush() is a pretty big hammer for that. Alternatively we - * could add an in-memory version of page exists, but find_multixact_start - * is called infrequently, and it doesn't seem bad to flush buffers to - * disk before truncation. + * Write out dirty data, so PhysicalPageExists can work correctly. */ - SimpleLruFlush(MultiXactOffsetCtl, true); - SimpleLruFlush(MultiXactMemberCtl, true); + SimpleLruWriteAll(MultiXactOffsetCtl, true); + SimpleLruWriteAll(MultiXactMemberCtl, true); if (!SimpleLruDoesPhysicalPageExist(MultiXactOffsetCtl, pageno)) return false; @@ -2974,6 +3000,14 @@ TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB) * truncate the members SLRU. So we first scan the directory to determine * the earliest offsets page number that we can read without error. * + * When nextMXact is less than one segment away from multiWrapLimit, + * SlruScanDirCbFindEarliest can find some early segment other than the + * actual earliest. (MultiXactOffsetPagePrecedes(EARLIEST, LATEST) + * returns false, because not all pairs of entries have the same answer.) + * That can also arise when an earlier truncation attempt failed unlink() + * or returned early from this function. The only consequence is + * returning early, which wastes space that we could have liberated. + * * NB: It's also possible that the page that oldestMulti is on has already * been truncated away, and we crashed before updating oldestMulti. */ @@ -3088,15 +3122,11 @@ TruncateMultiXact(MultiXactId newOldestMulti, Oid newOldestMultiDB) } /* - * Decide which of two MultiXactOffset page numbers is "older" for truncation - * purposes. + * Decide whether a MultiXactOffset page number is "older" for truncation + * purposes. Analogous to CLOGPagePrecedes(). * - * We need to use comparison of MultiXactId here in order to do the right - * thing with wraparound. However, if we are asked about page number zero, we - * don't want to hand InvalidMultiXactId to MultiXactIdPrecedes: it'll get - * weird. So, offset both multis by FirstMultiXactId to avoid that. - * (Actually, the current implementation doesn't do anything weird with - * InvalidMultiXactId, but there's no harm in leaving this code like this.) + * Offsetting the values is optional, because MultiXactIdPrecedes() has + * translational symmetry. */ static bool MultiXactOffsetPagePrecedes(int page1, int page2) @@ -3105,15 +3135,17 @@ MultiXactOffsetPagePrecedes(int page1, int page2) MultiXactId multi2; multi1 = ((MultiXactId) page1) * MULTIXACT_OFFSETS_PER_PAGE; - multi1 += FirstMultiXactId; + multi1 += FirstMultiXactId + 1; multi2 = ((MultiXactId) page2) * MULTIXACT_OFFSETS_PER_PAGE; - multi2 += FirstMultiXactId; + multi2 += FirstMultiXactId + 1; - return MultiXactIdPrecedes(multi1, multi2); + return (MultiXactIdPrecedes(multi1, multi2) && + MultiXactIdPrecedes(multi1, + multi2 + MULTIXACT_OFFSETS_PER_PAGE - 1)); } /* - * Decide which of two MultiXactMember page numbers is "older" for truncation + * Decide whether a MultiXactMember page number is "older" for truncation * purposes. There is no "invalid offset number" so use the numbers verbatim. */ static bool @@ -3125,7 +3157,9 @@ MultiXactMemberPagePrecedes(int page1, int page2) offset1 = ((MultiXactOffset) page1) * MULTIXACT_MEMBERS_PER_PAGE; offset2 = ((MultiXactOffset) page2) * MULTIXACT_MEMBERS_PER_PAGE; - return MultiXactOffsetPrecedes(offset1, offset2); + return (MultiXactOffsetPrecedes(offset1, offset2) && + MultiXactOffsetPrecedes(offset1, + offset2 + MULTIXACT_MEMBERS_PER_PAGE - 1)); } /* @@ -3265,9 +3299,9 @@ multixact_redo(XLogReaderState *record) xlrec->moff + xlrec->nmembers); /* - * Make sure nextXid is beyond any XID mentioned in the record. - * This should be unnecessary, since any XID found here ought to have - * other evidence in the XLOG, but let's be safe. + * Make sure nextXid is beyond any XID mentioned in the record. This + * should be unnecessary, since any XID found here ought to have other + * evidence in the XLOG, but let's be safe. */ max_xid = XLogRecGetXid(record); for (i = 0; i < xlrec->nmembers; i++) @@ -3331,7 +3365,7 @@ pg_get_multixact_members(PG_FUNCTION_ARGS) int nmembers; int iter; } mxact; - MultiXactId mxid = PG_GETARG_UINT32(0); + MultiXactId mxid = PG_GETARG_TRANSACTIONID(0); mxact *multi; FuncCallContext *funccxt; @@ -3386,3 +3420,21 @@ pg_get_multixact_members(PG_FUNCTION_ARGS) SRF_RETURN_DONE(funccxt); } + +/* + * Entrypoint for sync.c to sync offsets files. + */ +int +multixactoffsetssyncfiletag(const FileTag *ftag, char *path) +{ + return SlruSyncFileTag(MultiXactOffsetCtl, ftag, path); +} + +/* + * Entrypoint for sync.c to sync members files. + */ +int +multixactmemberssyncfiletag(const FileTag *ftag, char *path) +{ + return SlruSyncFileTag(MultiXactMemberCtl, ftag, path); +} diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index b0426960c786..3550ef13baa4 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -3,7 +3,7 @@ * parallel.c * Infrastructure for launching parallel workers * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -75,7 +75,7 @@ #define PARALLEL_KEY_PENDING_SYNCS UINT64CONST(0xFFFFFFFFFFFF000B) #define PARALLEL_KEY_REINDEX_STATE UINT64CONST(0xFFFFFFFFFFFF000C) #define PARALLEL_KEY_RELMAPPER_STATE UINT64CONST(0xFFFFFFFFFFFF000D) -#define PARALLEL_KEY_ENUMBLACKLIST UINT64CONST(0xFFFFFFFFFFFF000E) +#define PARALLEL_KEY_UNCOMMITTEDENUMS UINT64CONST(0xFFFFFFFFFFFF000E) /* Fixed-size parallel state. */ typedef struct FixedParallelState @@ -211,7 +211,7 @@ InitializeParallelDSM(ParallelContext *pcxt) Size pendingsyncslen = 0; Size reindexlen = 0; Size relmapperlen = 0; - Size enumblacklistlen = 0; + Size uncommittedenumslen = 0; Size segsize = 0; int i; FixedParallelState *fps; @@ -267,8 +267,8 @@ InitializeParallelDSM(ParallelContext *pcxt) shm_toc_estimate_chunk(&pcxt->estimator, reindexlen); relmapperlen = EstimateRelationMapSpace(); shm_toc_estimate_chunk(&pcxt->estimator, relmapperlen); - enumblacklistlen = EstimateEnumBlacklistSpace(); - shm_toc_estimate_chunk(&pcxt->estimator, enumblacklistlen); + uncommittedenumslen = EstimateUncommittedEnumsSpace(); + shm_toc_estimate_chunk(&pcxt->estimator, uncommittedenumslen); /* If you add more chunks here, you probably need to add keys. */ shm_toc_estimate_keys(&pcxt->estimator, 11); @@ -348,7 +348,7 @@ InitializeParallelDSM(ParallelContext *pcxt) char *error_queue_space; char *session_dsm_handle_space; char *entrypointstate; - char *enumblacklistspace; + char *uncommittedenumsspace; Size lnamelen; /* Serialize shared libraries we have loaded. */ @@ -404,11 +404,12 @@ InitializeParallelDSM(ParallelContext *pcxt) shm_toc_insert(pcxt->toc, PARALLEL_KEY_RELMAPPER_STATE, relmapperspace); - /* Serialize enum blacklist state. */ - enumblacklistspace = shm_toc_allocate(pcxt->toc, enumblacklistlen); - SerializeEnumBlacklist(enumblacklistspace, enumblacklistlen); - shm_toc_insert(pcxt->toc, PARALLEL_KEY_ENUMBLACKLIST, - enumblacklistspace); + /* Serialize uncommitted enum state. */ + uncommittedenumsspace = shm_toc_allocate(pcxt->toc, + uncommittedenumslen); + SerializeUncommittedEnums(uncommittedenumsspace, uncommittedenumslen); + shm_toc_insert(pcxt->toc, PARALLEL_KEY_UNCOMMITTEDENUMS, + uncommittedenumsspace); /* Allocate space for worker information. */ pcxt->worker = palloc0(sizeof(ParallelWorkerInfo) * pcxt->nworkers); @@ -1257,7 +1258,7 @@ ParallelWorkerMain(Datum main_arg) char *pendingsyncsspace; char *reindexspace; char *relmapperspace; - char *enumblacklistspace; + char *uncommittedenumsspace; StringInfoData msgbuf; char *session_dsm_handle_space; @@ -1449,10 +1450,10 @@ ParallelWorkerMain(Datum main_arg) relmapperspace = shm_toc_lookup(toc, PARALLEL_KEY_RELMAPPER_STATE, false); RestoreRelationMap(relmapperspace); - /* Restore enum blacklist. */ - enumblacklistspace = shm_toc_lookup(toc, PARALLEL_KEY_ENUMBLACKLIST, - false); - RestoreEnumBlacklist(enumblacklistspace); + /* Restore uncommitted enums. */ + uncommittedenumsspace = shm_toc_lookup(toc, PARALLEL_KEY_UNCOMMITTEDENUMS, + false); + RestoreUncommittedEnums(uncommittedenumsspace); /* Attach to the leader's serializable transaction, if SERIALIZABLE. */ AttachSerializableXact(fps->serializable_xact_handle); diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c index c96ce6245aab..a1950fd0944a 100644 --- a/src/backend/access/transam/slru.c +++ b/src/backend/access/transam/slru.c @@ -38,7 +38,7 @@ * by re-setting the page's page_dirty flag. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/slru.c @@ -63,22 +63,33 @@ snprintf(path, MAXPGPATH, "%s/%04X", (ctl)->Dir, seg) /* - * During SimpleLruFlush(), we will usually not need to write/fsync more - * than one or two physical files, but we may need to write several pages - * per file. We can consolidate the I/O requests by leaving files open - * until control returns to SimpleLruFlush(). This data structure remembers - * which files are open. + * During SimpleLruWriteAll(), we will usually not need to write more than one + * or two physical files, but we may need to write several pages per file. We + * can consolidate the I/O requests by leaving files open until control returns + * to SimpleLruWriteAll(). This data structure remembers which files are open. */ -#define MAX_FLUSH_BUFFERS 16 +#define MAX_WRITEALL_BUFFERS 16 -typedef struct SlruFlushData +typedef struct SlruWriteAllData { int num_files; /* # files actually open */ - int fd[MAX_FLUSH_BUFFERS]; /* their FD's */ - int segno[MAX_FLUSH_BUFFERS]; /* their log seg#s */ -} SlruFlushData; + int fd[MAX_WRITEALL_BUFFERS]; /* their FD's */ + int segno[MAX_WRITEALL_BUFFERS]; /* their log seg#s */ +} SlruWriteAllData; -typedef struct SlruFlushData *SlruFlush; +typedef struct SlruWriteAllData *SlruWriteAll; + +/* + * Populate a file tag describing a segment file. We only use the segment + * number, since we can derive everything else we need by having separate + * sync handler functions for clog, multixact etc. + */ +#define INIT_SLRUFILETAG(a,xx_handler,xx_segno) \ +( \ + memset(&(a), 0, sizeof(FileTag)), \ + (a).handler = (xx_handler), \ + (a).segno = (xx_segno) \ +) /* * Macro to mark a buffer slot "most recently used". Note multiple evaluation @@ -125,16 +136,16 @@ static int slru_errno; static void SimpleLruZeroLSNs(SlruCtl ctl, int slotno); static void SimpleLruWaitIO(SlruCtl ctl, int slotno); -static void SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata); +static void SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata); static bool SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno); static bool SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, - SlruFlush fdata); + SlruWriteAll fdata); static void SlruReportIOError(SlruCtl ctl, int pageno, TransactionId xid); static int SlruSelectLRUPage(SlruCtl ctl, int pageno); static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data); -static void SlruInternalDeleteSegment(SlruCtl ctl, char *filename); +static void SlruInternalDeleteSegment(SlruCtl ctl, int segno); /* * Initialization of shared memory @@ -173,7 +184,8 @@ SimpleLruShmemSize(int nslots, int nlsns) */ void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, - LWLock *ctllock, const char *subdir, int tranche_id) + LWLock *ctllock, const char *subdir, int tranche_id, + SyncRequestHandler sync_handler) { SlruShared shared; bool found; @@ -251,7 +263,7 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, * assume caller set PagePrecedes. */ ctl->shared = shared; - ctl->do_fsync = true; /* default behavior */ + ctl->sync_handler = sync_handler; strlcpy(ctl->Dir, subdir, sizeof(ctl->Dir)); } @@ -523,7 +535,7 @@ SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid) * Control lock must be held at entry, and will be held at exit. */ static void -SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata) +SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata) { SlruShared shared = ctl->shared; int pageno = shared->page_number[slotno]; @@ -587,6 +599,10 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata) /* Now it's okay to ereport if we failed */ if (!ok) SlruReportIOError(ctl, pageno, InvalidTransactionId); + + /* If part of a checkpoint, count this as a buffer written. */ + if (fdata) + CheckpointStats.ckpt_bufs_written++; } /* @@ -730,13 +746,13 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno) * * For now, assume it's not worth keeping a file pointer open across * independent read/write operations. We do batch operations during - * SimpleLruFlush, though. + * SimpleLruWriteAll, though. * * fdata is NULL for a standalone write, pointer to open-file info during - * SimpleLruFlush. + * SimpleLruWriteAll. */ static bool -SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata) +SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruWriteAll fdata) { SlruShared shared = ctl->shared; int segno = pageno / SLRU_PAGES_PER_SEGMENT; @@ -791,7 +807,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata) } /* - * During a Flush, we may already have the desired file open. + * During a WriteAll, we may already have the desired file open. */ if (fdata) { @@ -837,7 +853,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata) if (fdata) { - if (fdata->num_files < MAX_FLUSH_BUFFERS) + if (fdata->num_files < MAX_WRITEALL_BUFFERS) { fdata->fd[fdata->num_files] = fd; fdata->segno[fdata->num_files] = segno; @@ -870,23 +886,31 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata) } pgstat_report_wait_end(); - /* - * If not part of Flush, need to fsync now. We assume this happens - * infrequently enough that it's not a performance issue. - */ - if (!fdata) + /* Queue up a sync request for the checkpointer. */ + if (ctl->sync_handler != SYNC_HANDLER_NONE) { - pgstat_report_wait_start(WAIT_EVENT_SLRU_SYNC); - if (ctl->do_fsync && pg_fsync(fd) != 0) + FileTag tag; + + INIT_SLRUFILETAG(tag, ctl->sync_handler, segno); + if (!RegisterSyncRequest(&tag, SYNC_REQUEST, false)) { + /* No space to enqueue sync request. Do it synchronously. */ + pgstat_report_wait_start(WAIT_EVENT_SLRU_SYNC); + if (pg_fsync(fd) != 0) + { + pgstat_report_wait_end(); + slru_errcause = SLRU_FSYNC_FAILED; + slru_errno = errno; + CloseTransientFile(fd); + return false; + } pgstat_report_wait_end(); - slru_errcause = SLRU_FSYNC_FAILED; - slru_errno = errno; - CloseTransientFile(fd); - return false; } - pgstat_report_wait_end(); + } + /* Close file, unless part of flush request. */ + if (!fdata) + { if (CloseTransientFile(fd) != 0) { slru_errcause = SLRU_CLOSE_FAILED; @@ -1122,13 +1146,16 @@ SlruSelectLRUPage(SlruCtl ctl, int pageno) } /* - * Flush dirty pages to disk during checkpoint or database shutdown + * Write dirty pages to disk during checkpoint or database shutdown. Flushing + * is deferred until the next call to ProcessSyncRequests(), though we do fsync + * the containing directory here to make sure that newly created directory + * entries are on disk. */ void -SimpleLruFlush(SlruCtl ctl, bool allow_redirtied) +SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied) { SlruShared shared = ctl->shared; - SlruFlushData fdata; + SlruWriteAllData fdata; int slotno; int pageno = 0; int i; @@ -1162,21 +1189,11 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied) LWLockRelease(shared->ControlLock); /* - * Now fsync and close any files that were open + * Now close any files that were open */ ok = true; for (i = 0; i < fdata.num_files; i++) { - pgstat_report_wait_start(WAIT_EVENT_SLRU_FLUSH_SYNC); - if (ctl->do_fsync && pg_fsync(fdata.fd[i]) != 0) - { - slru_errcause = SLRU_FSYNC_FAILED; - slru_errno = errno; - pageno = fdata.segno[i] * SLRU_PAGES_PER_SEGMENT; - ok = false; - } - pgstat_report_wait_end(); - if (CloseTransientFile(fdata.fd[i]) != 0) { slru_errcause = SLRU_CLOSE_FAILED; @@ -1187,6 +1204,10 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied) } if (!ok) SlruReportIOError(ctl, pageno, InvalidTransactionId); + + /* Ensure that directory entries for new files are on disk. */ + if (ctl->sync_handler != SYNC_HANDLER_NONE) + fsync_fname(ctl->Dir, true); } /* @@ -1209,11 +1230,6 @@ SimpleLruTruncate_internal(SlruCtl ctl, int cutoffPage, bool lockHeld) /* update the stats counter of truncates */ pgstat_count_slru_truncate(shared->slru_stats_idx); - /* - * The cutoff point is the start of the segment containing cutoffPage. - */ - cutoffPage -= cutoffPage % SLRU_PAGES_PER_SEGMENT; - /* * Scan shared memory and remove any pages preceding the cutoff page, to * ensure we won't rewrite them later. (Since this is normally called in @@ -1227,9 +1243,7 @@ restart:; /* * While we are holding the lock, make an important safety check: the - * planned cutoff point must be <= the current endpoint page. Otherwise we - * have already wrapped around, and proceeding with the truncation would - * risk removing the current segment. + * current endpoint page must not be eligible for removal. */ if (ctl->PagePrecedes(shared->latest_page_number, cutoffPage)) { @@ -1263,8 +1277,11 @@ restart:; * Hmm, we have (or may have) I/O operations acting on the page, so * we've got to wait for them to finish and then start again. This is * the same logic as in SlruSelectLRUPage. (XXX if page is dirty, - * wouldn't it be OK to just discard it without writing it? For now, - * keep the logic the same as it was.) + * wouldn't it be OK to just discard it without writing it? + * SlruMayDeleteSegment() uses a stricter qualification, so we might + * not delete this page in the end; even if we don't delete it, we + * won't have cause to read its data again. For now, keep the logic + * the same as it was.) */ if (shared->page_status[slotno] == SLRU_PAGE_VALID) SlruInternalWritePage(ctl, slotno, NULL); @@ -1292,19 +1309,28 @@ SimpleLruTruncateWithLock(SlruCtl ctl, int cutoffPage) } /* - * Delete an individual SLRU segment, identified by the filename. + * Delete an individual SLRU segment. * * NB: This does not touch the SLRU buffers themselves, callers have to ensure * they either can't yet contain anything, or have already been cleaned out. */ static void -SlruInternalDeleteSegment(SlruCtl ctl, char *filename) +SlruInternalDeleteSegment(SlruCtl ctl, int segno) { char path[MAXPGPATH]; - snprintf(path, MAXPGPATH, "%s/%s", ctl->Dir, filename); - ereport(DEBUG2, - (errmsg("removing file \"%s\"", path))); + /* Forget any fsync requests queued for this segment. */ + if (ctl->sync_handler != SYNC_HANDLER_NONE) + { + FileTag tag; + + INIT_SLRUFILETAG(tag, ctl->sync_handler, segno); + RegisterSyncRequest(&tag, SYNC_FORGET_REQUEST, true); + } + + /* Unlink the file. */ + SlruFileName(ctl, path, segno); + ereport(DEBUG2, (errmsg_internal("removing file \"%s\"", path))); unlink(path); } @@ -1316,7 +1342,6 @@ SlruDeleteSegment(SlruCtl ctl, int segno) { SlruShared shared = ctl->shared; int slotno; - char path[MAXPGPATH]; bool did_write; /* Clean out any possibly existing references to the segment. */ @@ -1358,27 +1383,139 @@ SlruDeleteSegment(SlruCtl ctl, int segno) if (did_write) goto restart; - snprintf(path, MAXPGPATH, "%s/%04X", ctl->Dir, segno); - ereport(DEBUG2, - (errmsg("removing file \"%s\"", path))); - unlink(path); + SlruInternalDeleteSegment(ctl, segno); LWLockRelease(shared->ControlLock); } +/* + * Determine whether a segment is okay to delete. + * + * segpage is the first page of the segment, and cutoffPage is the oldest (in + * PagePrecedes order) page in the SLRU containing still-useful data. Since + * every core PagePrecedes callback implements "wrap around", check the + * segment's first and last pages: + * + * first=cutoff: no; cutoff falls inside this segment + * first>=cutoff && last=cutoff && last>=cutoff: no; every page of this segment is too young + */ +static bool +SlruMayDeleteSegment(SlruCtl ctl, int segpage, int cutoffPage) +{ + int seg_last_page = segpage + SLRU_PAGES_PER_SEGMENT - 1; + + Assert(segpage % SLRU_PAGES_PER_SEGMENT == 0); + + return (ctl->PagePrecedes(segpage, cutoffPage) && + ctl->PagePrecedes(seg_last_page, cutoffPage)); +} + +#ifdef USE_ASSERT_CHECKING +static void +SlruPagePrecedesTestOffset(SlruCtl ctl, int per_page, uint32 offset) +{ + TransactionId lhs, + rhs; + int newestPage, + oldestPage; + TransactionId newestXact, + oldestXact; + + /* + * Compare an XID pair having undefined order (see RFC 1982), a pair at + * "opposite ends" of the XID space. TransactionIdPrecedes() treats each + * as preceding the other. If RHS is oldestXact, LHS is the first XID we + * must not assign. + */ + lhs = per_page + offset; /* skip first page to avoid non-normal XIDs */ + rhs = lhs + (1U << 31); + Assert(TransactionIdPrecedes(lhs, rhs)); + Assert(TransactionIdPrecedes(rhs, lhs)); + Assert(!TransactionIdPrecedes(lhs - 1, rhs)); + Assert(TransactionIdPrecedes(rhs, lhs - 1)); + Assert(TransactionIdPrecedes(lhs + 1, rhs)); + Assert(!TransactionIdPrecedes(rhs, lhs + 1)); + Assert(!TransactionIdFollowsOrEquals(lhs, rhs)); + Assert(!TransactionIdFollowsOrEquals(rhs, lhs)); + Assert(!ctl->PagePrecedes(lhs / per_page, lhs / per_page)); + Assert(!ctl->PagePrecedes(lhs / per_page, rhs / per_page)); + Assert(!ctl->PagePrecedes(rhs / per_page, lhs / per_page)); + Assert(!ctl->PagePrecedes((lhs - per_page) / per_page, rhs / per_page)); + Assert(ctl->PagePrecedes(rhs / per_page, (lhs - 3 * per_page) / per_page)); + Assert(ctl->PagePrecedes(rhs / per_page, (lhs - 2 * per_page) / per_page)); + Assert(ctl->PagePrecedes(rhs / per_page, (lhs - 1 * per_page) / per_page) + || (1U << 31) % per_page != 0); /* See CommitTsPagePrecedes() */ + Assert(ctl->PagePrecedes((lhs + 1 * per_page) / per_page, rhs / per_page) + || (1U << 31) % per_page != 0); + Assert(ctl->PagePrecedes((lhs + 2 * per_page) / per_page, rhs / per_page)); + Assert(ctl->PagePrecedes((lhs + 3 * per_page) / per_page, rhs / per_page)); + Assert(!ctl->PagePrecedes(rhs / per_page, (lhs + per_page) / per_page)); + + /* + * GetNewTransactionId() has assigned the last XID it can safely use, and + * that XID is in the *LAST* page of the second segment. We must not + * delete that segment. + */ + newestPage = 2 * SLRU_PAGES_PER_SEGMENT - 1; + newestXact = newestPage * per_page + offset; + Assert(newestXact / per_page == newestPage); + oldestXact = newestXact + 1; + oldestXact -= 1U << 31; + oldestPage = oldestXact / per_page; + Assert(!SlruMayDeleteSegment(ctl, + (newestPage - + newestPage % SLRU_PAGES_PER_SEGMENT), + oldestPage)); + + /* + * GetNewTransactionId() has assigned the last XID it can safely use, and + * that XID is in the *FIRST* page of the second segment. We must not + * delete that segment. + */ + newestPage = SLRU_PAGES_PER_SEGMENT; + newestXact = newestPage * per_page + offset; + Assert(newestXact / per_page == newestPage); + oldestXact = newestXact + 1; + oldestXact -= 1U << 31; + oldestPage = oldestXact / per_page; + Assert(!SlruMayDeleteSegment(ctl, + (newestPage - + newestPage % SLRU_PAGES_PER_SEGMENT), + oldestPage)); +} + +/* + * Unit-test a PagePrecedes function. + * + * This assumes every uint32 >= FirstNormalTransactionId is a valid key. It + * assumes each value occupies a contiguous, fixed-size region of SLRU bytes. + * (MultiXactMemberCtl separates flags from XIDs. AsyncCtl has + * variable-length entries, no keys, and no random access. These unit tests + * do not apply to them.) + */ +void +SlruPagePrecedesUnitTests(SlruCtl ctl, int per_page) +{ + /* Test first, middle and last entries of a page. */ + SlruPagePrecedesTestOffset(ctl, per_page, 0); + SlruPagePrecedesTestOffset(ctl, per_page, per_page / 2); + SlruPagePrecedesTestOffset(ctl, per_page, per_page - 1); +} +#endif + /* * SlruScanDirectory callback - * This callback reports true if there's any segment prior to the one - * containing the page passed as "data". + * This callback reports true if there's any segment wholly prior to the + * one containing the page passed as "data". */ bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, int segpage, void *data) { int cutoffPage = *(int *) data; - cutoffPage -= cutoffPage % SLRU_PAGES_PER_SEGMENT; - - if (ctl->PagePrecedes(segpage, cutoffPage)) + if (SlruMayDeleteSegment(ctl, segpage, cutoffPage)) return true; /* found one; don't iterate any more */ return false; /* keep going */ @@ -1393,8 +1530,8 @@ SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data) { int cutoffPage = *(int *) data; - if (ctl->PagePrecedes(segpage, cutoffPage)) - SlruInternalDeleteSegment(ctl, filename); + if (SlruMayDeleteSegment(ctl, segpage, cutoffPage)) + SlruInternalDeleteSegment(ctl, segpage / SLRU_PAGES_PER_SEGMENT); return false; /* keep going */ } @@ -1406,7 +1543,7 @@ SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data) bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, void *data) { - SlruInternalDeleteSegment(ctl, filename); + SlruInternalDeleteSegment(ctl, segpage / SLRU_PAGES_PER_SEGMENT); return false; /* keep going */ } @@ -1459,3 +1596,31 @@ SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data) return retval; } + +/* + * Individual SLRUs (clog, ...) have to provide a sync.c handler function so + * that they can provide the correct "SlruCtl" (otherwise we don't know how to + * build the path), but they just forward to this common implementation that + * performs the fsync. + */ +int +SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path) +{ + int fd; + int save_errno; + int result; + + SlruFileName(ctl, path, ftag->segno); + + fd = OpenTransientFile(path, O_RDWR | PG_BINARY); + if (fd < 0) + return -1; + + result = pg_fsync(fd); + save_errno = errno; + + CloseTransientFile(fd); + + errno = save_errno; + return result; +} diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c index 6e7f6f2c9aeb..5339eeaa1c0c 100644 --- a/src/backend/access/transam/subtrans.c +++ b/src/backend/access/transam/subtrans.c @@ -19,7 +19,7 @@ * data across crashes. During database startup, we simply force the * currently-active page of SUBTRANS to zeroes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/subtrans.c @@ -197,9 +197,8 @@ SUBTRANSShmemInit(void) SubTransCtl->PagePrecedes = SubTransPagePrecedes; SimpleLruInit(SubTransCtl, "Subtrans", NUM_SUBTRANS_BUFFERS, 0, SubtransSLRULock, "pg_subtrans", - LWTRANCHE_SUBTRANS_BUFFER); - /* Override default assumption that writes should be fsync'd */ - SubTransCtl->do_fsync = false; + LWTRANCHE_SUBTRANS_BUFFER, SYNC_HANDLER_NONE); + SlruPagePrecedesUnitTests(SubTransCtl, SUBTRANS_XACTS_PER_PAGE); } /* @@ -286,23 +285,6 @@ StartupSUBTRANS(TransactionId oldestActiveXID) LWLockRelease(SubtransSLRULock); } -/* - * This must be called ONCE during postmaster or standalone-backend shutdown - */ -void -ShutdownSUBTRANS(void) -{ - /* - * Flush dirty SUBTRANS pages to disk - * - * This is not actually necessary from a correctness point of view. We do - * it merely as a debugging aid. - */ - TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(false); - SimpleLruFlush(SubTransCtl, false); - TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(false); -} - /* * Perform a checkpoint --- either during shutdown, or on-the-fly */ @@ -310,14 +292,14 @@ void CheckPointSUBTRANS(void) { /* - * Flush dirty SUBTRANS pages to disk + * Write dirty SUBTRANS pages to disk * * This is not actually necessary from a correctness point of view. We do * it merely to improve the odds that writing of dirty pages is done by * the checkpoint process and not by backends. */ TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true); - SimpleLruFlush(SubTransCtl, true); + SimpleLruWriteAll(SubTransCtl, true); TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true); } @@ -380,13 +362,8 @@ TruncateSUBTRANS(TransactionId oldestXact) /* - * Decide which of two SUBTRANS page numbers is "older" for truncation purposes. - * - * We need to use comparison of TransactionIds here in order to do the right - * thing with wraparound XID arithmetic. However, if we are asked about - * page number zero, we don't want to hand InvalidTransactionId to - * TransactionIdPrecedes: it'll get weird about permanent xact IDs. So, - * offset both xids by FirstNormalTransactionId to avoid that. + * Decide whether a SUBTRANS page number is "older" for truncation purposes. + * Analogous to CLOGPagePrecedes(). */ static bool SubTransPagePrecedes(int page1, int page2) @@ -394,10 +371,11 @@ SubTransPagePrecedes(int page1, int page2) TransactionId xid1; TransactionId xid2; - xid1 = ((uint32) page1) * SUBTRANS_XACTS_PER_PAGE; - xid1 += FirstNormalTransactionId; - xid2 = ((uint32) page2) * SUBTRANS_XACTS_PER_PAGE; - xid2 += FirstNormalTransactionId; + xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE; + xid1 += FirstNormalTransactionId + 1; + xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE; + xid2 += FirstNormalTransactionId + 1; - return TransactionIdPrecedes(xid1, xid2); + return (TransactionIdPrecedes(xid1, xid2) && + TransactionIdPrecedes(xid1, xid2 + SUBTRANS_XACTS_PER_PAGE - 1)); } diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c index e6a29d9a9b7f..8d0903c1756a 100644 --- a/src/backend/access/transam/timeline.c +++ b/src/backend/access/transam/timeline.c @@ -21,7 +21,7 @@ * The fields are separated by tabs. Lines beginning with # are comments, and * are ignored. Empty lines are also ignored. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/timeline.c @@ -402,7 +402,7 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, "%s%u\t%X/%X\t%s\n", (srcfd < 0) ? "" : "\n", parentTLI, - (uint32) (switchpoint >> 32), (uint32) (switchpoint), + LSN_FORMAT_ARGS(switchpoint), reason); nbytes = strlen(buffer); diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c index 83923ed846d8..1c881550b65a 100644 --- a/src/backend/access/transam/transam.c +++ b/src/backend/access/transam/transam.c @@ -3,7 +3,7 @@ * transam.c * postgres transaction (commit) log interface routines * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index c9411a4277c7..8de8a71f6cbf 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -3,7 +3,7 @@ * twophase.c * Two-phase commit support functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -480,7 +480,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid, proc->xid = xid; Assert(proc->xmin == InvalidTransactionId); proc->delayChkpt = false; - proc->vacuumFlags = 0; + proc->statusFlags = 0; proc->pid = 0; proc->backendId = InvalidBackendId; proc->databaseId = databaseid; @@ -495,6 +495,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid, proc->localDistribXactData = *localDistribXactRef; + pg_atomic_init_u64(&proc->waitStart, 0); for (i = 0; i < NUM_LOCK_PARTITIONS; i++) SHMQueueInit(&(proc->myProcLocks[i])); /* subxid data must be filled later by GXactLoadSubxactData */ @@ -1186,9 +1187,9 @@ EndPrepare(GlobalTransaction gxact) gxact->prepare_start_lsn = ProcLastRecPtr; /* - * Mark the prepared transaction as valid. As soon as xact.c marks - * MyProc as not running our XID (which it will do immediately after - * this function returns), others can commit/rollback the xact. + * Mark the prepared transaction as valid. As soon as xact.c marks MyProc + * as not running our XID (which it will do immediately after this + * function returns), others can commit/rollback the xact. * * NB: a side effect of this is to make a dummy ProcArray entry for the * prepared XID. This must happen before we clear the XID from MyProc / @@ -1300,10 +1301,10 @@ ReadTwoPhaseFile(TransactionId xid, bool missing_ok) stat.st_size > MaxAllocSize) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg_plural("incorrect size of file \"%s\": %zu byte", - "incorrect size of file \"%s\": %zu bytes", - (Size) stat.st_size, path, - (Size) stat.st_size))); + errmsg_plural("incorrect size of file \"%s\": %lld byte", + "incorrect size of file \"%s\": %lld bytes", + (long long int) stat.st_size, path, + (long long int) stat.st_size))); crc_offset = stat.st_size - sizeof(pg_crc32c); if (crc_offset != MAXALIGN(crc_offset)) @@ -1327,8 +1328,8 @@ ReadTwoPhaseFile(TransactionId xid, bool missing_ok) errmsg("could not read file \"%s\": %m", path))); else ereport(ERROR, - (errmsg("could not read file \"%s\": read %d of %zu", - path, r, (Size) stat.st_size))); + (errmsg("could not read file \"%s\": read %d of %lld", + path, r, (long long int) stat.st_size))); } pgstat_report_wait_end(); @@ -1411,16 +1412,14 @@ XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read two-phase state from WAL at %X/%X", - (uint32) (lsn >> 32), - (uint32) lsn))); + LSN_FORMAT_ARGS(lsn)))); if (XLogRecGetRmid(xlogreader) != RM_XACT_ID || (XLogRecGetInfo(xlogreader) & XLOG_XACT_OPMASK) != XLOG_XACT_PREPARE) ereport(ERROR, (errcode_for_file_access(), errmsg("expected two-phase state data is not present in WAL at %X/%X", - (uint32) (lsn >> 32), - (uint32) lsn))); + LSN_FORMAT_ARGS(lsn)))); if (len != NULL) *len = XLogRecGetDataLen(xlogreader); @@ -2407,7 +2406,7 @@ RecordTransactionCommitPrepared(TransactionId xid, TransactionTreeSetCommitTsData(xid, nchildren, children, replorigin_session_origin_timestamp, - replorigin_session_origin, false); + replorigin_session_origin); /* * We don't currently try to sleep before flush here ... nor is there any @@ -2462,6 +2461,14 @@ RecordTransactionAbortPrepared(TransactionId xid, const char *gid) { XLogRecPtr recptr; + bool replorigin; + + /* + * Are we using the replication origins feature? Or, in other words, are + * we replaying remote actions? + */ + replorigin = (replorigin_session_origin != InvalidRepOriginId && + replorigin_session_origin != DoNotReplicateId); /* * Catch the scenario where we aborted partway through @@ -2488,6 +2495,11 @@ RecordTransactionAbortPrepared(TransactionId xid, MyXactFlags | XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xid, gid); + if (replorigin) + /* Move LSNs forward for this replication origin */ + replorigin_session_advance(replorigin_session_origin_lsn, + XactLastRecEnd); + /* Always flush, since we're about to remove the 2PC state file */ XLogFlush(recptr); diff --git a/src/backend/access/transam/twophase_rmgr.c b/src/backend/access/transam/twophase_rmgr.c index 3a6a2d1fafd2..1fd785567cc8 100644 --- a/src/backend/access/transam/twophase_rmgr.c +++ b/src/backend/access/transam/twophase_rmgr.c @@ -3,7 +3,7 @@ * twophase_rmgr.c * Two-phase-commit resource managers tables * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 315eefbefd2d..b231c73635f4 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -3,7 +3,7 @@ * varsup.c * postgres OID & XID variables support routines * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/access/transam/varsup.c @@ -199,10 +199,10 @@ GetNewTransactionId(bool isSubXact) DistributedLog_Extend(xid); /* - * Now advance the nextXid counter. This must not happen until after - * we have successfully completed ExtendCLOG() --- if that routine fails, - * we want the next incoming transaction to try it again. We cannot - * assign more XIDs until there is CLOG space for them. + * Now advance the nextXid counter. This must not happen until after we + * have successfully completed ExtendCLOG() --- if that routine fails, we + * want the next incoming transaction to try it again. We cannot assign + * more XIDs until there is CLOG space for them. */ FullTransactionIdAdvance(&ShmemVariableCache->nextXid); @@ -240,8 +240,8 @@ GetNewTransactionId(bool isSubXact) * latestCompletedXid is present in the ProcArray, which is essential for * correct OldestXmin tracking; see src/backend/access/transam/README. * - * Note that readers of ProcGlobal->xids/PGPROC->xid should be careful - * to fetch the value for each proc only once, rather than assume they can + * Note that readers of ProcGlobal->xids/PGPROC->xid should be careful to + * fetch the value for each proc only once, rather than assume they can * read a value multiple times and get the same answer each time. Note we * are assuming that TransactionId and int fetch/store are atomic. * @@ -333,9 +333,9 @@ AdvanceNextFullTransactionIdPastXid(TransactionId xid) uint32 epoch; /* - * It is safe to read nextXid without a lock, because this is only - * called from the startup process or single-process mode, meaning that no - * other process can modify it. + * It is safe to read nextXid without a lock, because this is only called + * from the startup process or single-process mode, meaning that no other + * process can modify it. */ Assert(AmStartupProcess() || !IsUnderPostmaster); @@ -483,8 +483,8 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) /* Log the info */ ereport(DEBUG1, - (errmsg("transaction ID wrap limit is %u, limited by database with OID %u", - xidWrapLimit, oldest_datoid))); + (errmsg_internal("transaction ID wrap limit is %u, limited by database with OID %u", + xidWrapLimit, oldest_datoid))); /* * If past the autovacuum force point, immediately signal an autovac @@ -811,8 +811,8 @@ AssertTransactionIdInAllowableRange(TransactionId xid) * We can't acquire XidGenLock, as this may be called with XidGenLock * already held (or with other locks that don't allow XidGenLock to be * nested). That's ok for our purposes though, since we already rely on - * 32bit reads to be atomic. While nextXid is 64 bit, we only look at - * the lower 32bit, so a skewed read doesn't hurt. + * 32bit reads to be atomic. While nextXid is 64 bit, we only look at the + * lower 32bit, so a skewed read doesn't hurt. * * There's no increased danger of falling outside [oldest, next] by * accessing them without a lock. xid needs to have been created with diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 6039ba163571..04453bf02411 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -5,7 +5,7 @@ * * See src/backend/access/transam/README for more information. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -656,7 +656,7 @@ GetStableLatestTransactionId(void) lxid = MyProc->lxid; stablexid = GetTopTransactionIdIfAny(); if (!TransactionIdIsValid(stablexid)) - stablexid = ReadNewTransactionId(); + stablexid = ReadNextTransactionId(); } Assert(TransactionIdIsValid(stablexid)); @@ -1681,7 +1681,7 @@ RecordTransactionCommit(void) TransactionTreeSetCommitTsData(xid, nchildren, children, replorigin_session_origin_timestamp, - replorigin_session_origin, false); + replorigin_session_origin); } #ifdef IMPLEMENT_ASYNC_COMMIT @@ -3217,15 +3217,6 @@ PrepareTransaction(void) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot PREPARE a transaction that has exported snapshots"))); - /* - * Don't allow PREPARE but for transaction that has/might kill logical - * replication workers. - */ - if (XactManipulatesLogicalReplicationWorkers()) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot PREPARE a transaction that has manipulated logical replication workers"))); - /* Prevent cancel/die interrupt while cleaning up */ HOLD_INTERRUPTS(); @@ -4075,6 +4066,13 @@ CommitTransactionCommand(void) Assert(s->parent == NULL); CommitTransaction(); s->blockState = TBLOCK_DEFAULT; + if (s->chain) + { + StartTransaction(); + s->blockState = TBLOCK_INPROGRESS; + s->chain = false; + RestoreTransactionCharacteristics(); + } } else if (s->blockState == TBLOCK_PREPARE) { @@ -6074,7 +6072,6 @@ CommitSubTransaction(void) AtEOSubXact_HashTables(true, s->nestingLevel); AtEOSubXact_PgStat(true, s->nestingLevel); AtSubCommit_Snapshot(s->nestingLevel); - AtEOSubXact_ApplyLauncher(true, s->nestingLevel); /* * We need to restore the upper transaction's read-only state, in case the @@ -6236,7 +6233,6 @@ AbortSubTransaction(void) AtEOSubXact_HashTables(false, s->nestingLevel); AtEOSubXact_PgStat(false, s->nestingLevel); AtSubAbort_Snapshot(s->nestingLevel); - AtEOSubXact_ApplyLauncher(false, s->nestingLevel); } /* @@ -6556,7 +6552,7 @@ static void ShowTransactionState(const char *str) { /* skip work if message will definitely not be printed */ - if (log_min_messages <= DEBUG5 || client_min_messages <= DEBUG5) + if (message_level_is_interesting(DEBUG5)) ShowTransactionStateRec(str, CurrentTransactionState); } @@ -6583,7 +6579,6 @@ ShowTransactionStateRec(const char *str, TransactionState s) if (s->parent) ShowTransactionStateRec(str, s->parent); - /* use ereport to suppress computation if msg will not be printed */ ereport(DEBUG5, (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s", str, s->nestingLevel, @@ -7048,10 +7043,12 @@ XactLogAbortRecord(TimestampTz abort_time, xl_dbinfo.tsId = MyDatabaseTableSpace; } - /* dump transaction origin information only for abort prepared */ + /* + * Dump transaction origin information only for abort prepared. We need + * this during recovery to update the replication origin progress. + */ if ((replorigin_session_origin != InvalidRepOriginId) && - TransactionIdIsValid(twophase_xid) && - XLogLogicalInfoActive()) + TransactionIdIsValid(twophase_xid)) { xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN; @@ -7158,7 +7155,7 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, /* Set the transaction commit timestamp and metadata */ TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts, - commit_time, origin_id, false); + commit_time, origin_id); if (standbyState == STANDBY_DISABLED) { @@ -7299,7 +7296,8 @@ xact_redo_distributed_commit(xl_xact_parsed_commit *parsed, } static void -xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) +xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, + XLogRecPtr lsn, RepOriginId origin_id) { TransactionId max_xid; @@ -7348,6 +7346,13 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts); } + if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN) + { + /* recover apply progress */ + replorigin_advance(origin_id, parsed->origin_lsn, lsn, + false /* backward */ , false /* WAL */ ); + } + /* Make sure files supposed to be dropped are dropped */ DropRelationFiles(parsed->xnodes, parsed->nrels, true); DropDatabaseDirectories(parsed->deldbs, parsed->ndeldbs, true); @@ -7391,7 +7396,8 @@ xact_redo(XLogReaderState *record) xl_xact_parsed_abort parsed; ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed); - xact_redo_abort(&parsed, XLogRecGetXid(record)); + xact_redo_abort(&parsed, XLogRecGetXid(record), + record->EndRecPtr, XLogRecGetOrigin(record)); } else if (info == XLOG_XACT_ABORT_PREPARED) { @@ -7399,7 +7405,8 @@ xact_redo(XLogReaderState *record) xl_xact_parsed_abort parsed; ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed); - xact_redo_abort(&parsed, parsed.twophase_xid); + xact_redo_abort(&parsed, parsed.twophase_xid, + record->EndRecPtr, XLogRecGetOrigin(record)); /* Delete TwoPhaseState gxact entry and/or 2PC file. */ LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE); diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index ed7556f537b1..81be97051ee0 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4,7 +4,7 @@ * PostgreSQL write-ahead log manager * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlog.c @@ -48,6 +48,7 @@ #include "pg_trace.h" #include "pgstat.h" #include "port/atomics.h" +#include "port/pg_iovec.h" #include "postmaster/bgwriter.h" #include "postmaster/startup.h" #include "postmaster/walwriter.h" @@ -76,6 +77,7 @@ #include "utils/memutils.h" #include "utils/ps_status.h" #include "utils/relmapper.h" +#include "utils/pg_rusage.h" #include "utils/snapmgr.h" #include "utils/timestamp.h" @@ -121,6 +123,7 @@ int CommitDelay = 0; /* precommit delay in microseconds */ int CommitSiblings = 5; /* # concurrent xacts needed to sleep */ int wal_retrieve_retry_interval = 5000; int max_slot_wal_keep_size_mb = -1; +bool track_wal_io_timing = false; /* GPDB specific */ bool gp_pause_on_restore_point_replay = false; @@ -462,10 +465,6 @@ static XLogRecPtr RedoStartLSN = InvalidXLogRecPtr; * ControlFileLock: must be held to read/update control file or create * new log file. * - * CheckpointLock: must be held to do a checkpoint or restartpoint (ensures - * only one checkpointer at a time; currently, with all checkpoints done by - * the checkpointer, this is just pro forma). - * *---------- */ @@ -714,6 +713,16 @@ typedef struct XLogCtlData * recoveryWakeupLatch is used to wake up the startup process to continue * WAL replay, if it is waiting for WAL to arrive or failover trigger file * to appear. + * + * Note that the startup process also uses another latch, its procLatch, + * to wait for recovery conflict. If we get rid of recoveryWakeupLatch for + * signaling the startup process in favor of using its procLatch, which + * comports better with possible generic signal handlers using that latch. + * But we should not do that because the startup process doesn't assume + * that it's waken up by walreceiver process or SIGHUP signal handler + * while it's waiting for recovery conflict. The separate latches, + * recoveryWakeupLatch and procLatch, should be used for inter-process + * communication for WAL replay and recovery conflict, respectively. */ Latch recoveryWakeupLatch; @@ -747,8 +756,9 @@ typedef struct XLogCtlData * only relevant for replication or archive recovery */ TimestampTz currentChunkStartTime; - /* Are we requested to pause recovery? */ - bool recoveryPause; + /* Recovery pause state */ + RecoveryPauseState recoveryPauseState; + ConditionVariable recoveryNotPausedCV; /* * lastFpwDisableRecPtr points to the start of the last replayed @@ -833,11 +843,9 @@ static XLogSegNo openLogSegNo = 0; /* * These variables are used similarly to the ones above, but for reading - * the XLOG. Note, however, that readOff generally represents the offset - * of the page just read, not the seek position of the FD itself, which - * will be just past that page. readLen indicates how much of the current - * page has been read into readBuf, and readSource indicates where we got - * the currently open file from. + * the XLOG. readOff is the offset of the page just read, readLen + * indicates how much of it has been read into readBuf, and readSource + * indicates where we got the currently open file from. * Note: we could use Reserve/ReleaseExternalFD to track consumption of * this FD too; but it doesn't currently seem worthwhile, since the XLOG is * not read by general-purpose sessions. @@ -920,6 +928,7 @@ static void validateRecoveryParameters(void); static void exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog); static bool recoveryStopsBefore(XLogReaderState *record); static bool recoveryStopsAfter(XLogReaderState *record); +static void ConfirmRecoveryPaused(void); static void recoveryPausesHere(bool endOfRecovery); static bool recoveryApplyDelay(XLogReaderState *record); static void SetLatestXTime(TimestampTz xtime); @@ -955,7 +964,8 @@ static void XLogFileClose(void); static void PreallocXlogFiles(XLogRecPtr endptr); static void RemoveTempXlogFiles(void); static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr); -static void RemoveXlogFile(const char *segname, XLogRecPtr lastredoptr, XLogRecPtr endptr); +static void RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo, + XLogSegNo *endlogSegNo); static void UpdateLastRemovedPtr(char *filename); static void ValidateXLOGDirectoryStructure(void); static void CleanupBackupHistory(void); @@ -976,6 +986,7 @@ static bool CheckForStandbyTrigger(void); #ifdef WAL_DEBUG static void xlog_outrec(StringInfo buf, XLogReaderState *record); #endif +static void xlog_block_info(StringInfo buf, XLogReaderState *record); static void xlog_outdesc(StringInfo buf, XLogReaderState *record); static void pg_start_backup_callback(int code, Datum arg); static void pg_stop_backup_callback(int code, Datum arg); @@ -1250,9 +1261,7 @@ XLogInsertRecord(XLogRecData *rdata, oldCxt = MemoryContextSwitchTo(walDebugCxt); initStringInfo(&buf); - appendStringInfo(&buf, "INSERT @ %X/%X, LSN %X/%X: ", - (uint32) (StartPos >> 32), (uint32) StartPos, - (uint32) (EndPos >> 32), (uint32) EndPos); + appendStringInfo(&buf, "INSERT @ %X/%X: ", LSN_FORMAT_ARGS(EndPos)); /* * We have to piece together the WAL record data from the XLogRecData @@ -1851,9 +1860,9 @@ WaitXLogInsertionsToFinish(XLogRecPtr upto) */ if (upto > reservedUpto) { - elog(LOG, "request to flush past end of generated WAL; request %X/%X, currpos %X/%X", - (uint32) (upto >> 32), (uint32) upto, - (uint32) (reservedUpto >> 32), (uint32) reservedUpto); + ereport(LOG, + (errmsg("request to flush past end of generated WAL; request %X/%X, current position %X/%X", + LSN_FORMAT_ARGS(upto), LSN_FORMAT_ARGS(reservedUpto)))); upto = reservedUpto; } @@ -2004,7 +2013,7 @@ GetXLogBuffer(XLogRecPtr ptr) if (expectedEndPtr != endptr) elog(PANIC, "could not find WAL buffer for %X/%X", - (uint32) (ptr >> 32), (uint32) ptr); + LSN_FORMAT_ARGS(ptr)); } else { @@ -2236,6 +2245,7 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic) WriteRqst.Flush = 0; XLogWrite(WriteRqst, false); LWLockRelease(WALWriteLock); + WalStats.m_wal_buffers_full++; TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE(); } /* Re-acquire WALBufMappingLock and retry */ @@ -2332,7 +2342,7 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic) if (XLOG_DEBUG && npages > 0) { elog(DEBUG1, "initialized %d pages, up to %X/%X", - npages, (uint32) (NewPageEndPtr >> 32), (uint32) NewPageEndPtr); + npages, LSN_FORMAT_ARGS(NewPageEndPtr)); } #endif } @@ -2513,9 +2523,8 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) if (LogwrtResult.Write >= EndPtr) elog(PANIC, "xlog write request %X/%X is past end of log %X/%X", - (uint32) (LogwrtResult.Write >> 32), - (uint32) LogwrtResult.Write, - (uint32) (EndPtr >> 32), (uint32) EndPtr); + LSN_FORMAT_ARGS(LogwrtResult.Write), + LSN_FORMAT_ARGS(EndPtr)); /* Advance LogwrtResult.Write to end of current buffer page */ LogwrtResult.Write = EndPtr; @@ -2578,6 +2587,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) Size nbytes; Size nleft; int written; + instr_time start; /* OK to write the page(s) */ from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ; @@ -2586,9 +2596,30 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) do { errno = 0; + + /* Measure I/O timing to write WAL data */ + if (track_wal_io_timing) + INSTR_TIME_SET_CURRENT(start); + pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE); written = pg_pwrite(openLogFile, from, nleft, startoffset); pgstat_report_wait_end(); + + /* + * Increment the I/O timing and the number of times WAL data + * were written out to disk. + */ + if (track_wal_io_timing) + { + instr_time duration; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + WalStats.m_wal_write_time += INSTR_TIME_GET_MICROSEC(duration); + } + + WalStats.m_wal_write++; + if (written <= 0) { char xlogfname[MAXFNAMELEN]; @@ -2865,9 +2896,7 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force) if (!force && newMinRecoveryPoint < lsn) elog(WARNING, "xlog min recovery request %X/%X is past current point %X/%X", - (uint32) (lsn >> 32), (uint32) lsn, - (uint32) (newMinRecoveryPoint >> 32), - (uint32) newMinRecoveryPoint); + LSN_FORMAT_ARGS(lsn), LSN_FORMAT_ARGS(newMinRecoveryPoint)); /* update control file */ if (ControlFile->minRecoveryPoint < newMinRecoveryPoint) @@ -2879,10 +2908,9 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force) minRecoveryPointTLI = newMinRecoveryPointTLI; ereport(DEBUG2, - (errmsg("updated min recovery point to %X/%X on timeline %u", - (uint32) (minRecoveryPoint >> 32), - (uint32) minRecoveryPoint, - newMinRecoveryPointTLI))); + (errmsg_internal("updated min recovery point to %X/%X on timeline %u", + LSN_FORMAT_ARGS(minRecoveryPoint), + newMinRecoveryPointTLI))); } } LWLockRelease(ControlFileLock); @@ -2920,9 +2948,9 @@ XLogFlush(XLogRecPtr record) #ifdef WAL_DEBUG if (XLOG_DEBUG) elog(LOG, "xlog flush request %X/%X; write %X/%X; flush %X/%X", - (uint32) (record >> 32), (uint32) record, - (uint32) (LogwrtResult.Write >> 32), (uint32) LogwrtResult.Write, - (uint32) (LogwrtResult.Flush >> 32), (uint32) LogwrtResult.Flush); + LSN_FORMAT_ARGS(record), + LSN_FORMAT_ARGS(LogwrtResult.Write), + LSN_FORMAT_ARGS(LogwrtResult.Flush)); #endif START_CRIT_SECTION(); @@ -3055,8 +3083,8 @@ XLogFlush(XLogRecPtr record) if (LogwrtResult.Flush < record) elog(ERROR, "xlog flush request %X/%X is not satisfied --- flushed only to %X/%X", - (uint32) (record >> 32), (uint32) record, - (uint32) (LogwrtResult.Flush >> 32), (uint32) LogwrtResult.Flush); + LSN_FORMAT_ARGS(record), + LSN_FORMAT_ARGS(LogwrtResult.Flush)); } /* @@ -3171,10 +3199,10 @@ XLogBackgroundFlush(void) #ifdef WAL_DEBUG if (XLOG_DEBUG) elog(LOG, "xlog bg flush request write %X/%X; flush: %X/%X, current is write %X/%X; flush %X/%X", - (uint32) (WriteRqst.Write >> 32), (uint32) WriteRqst.Write, - (uint32) (WriteRqst.Flush >> 32), (uint32) WriteRqst.Flush, - (uint32) (LogwrtResult.Write >> 32), (uint32) LogwrtResult.Write, - (uint32) (LogwrtResult.Flush >> 32), (uint32) LogwrtResult.Flush); + LSN_FORMAT_ARGS(WriteRqst.Write), + LSN_FORMAT_ARGS(WriteRqst.Flush), + LSN_FORMAT_ARGS(LogwrtResult.Write), + LSN_FORMAT_ARGS(LogwrtResult.Flush)); #endif START_CRIT_SECTION(); @@ -3310,7 +3338,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) XLogSegNo installed_segno; XLogSegNo max_segno; int fd; - int nbytes; int save_errno; XLogFilePath(path, ThisTimeLineID, logsegno, wal_segment_size); @@ -3357,6 +3384,9 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) save_errno = 0; if (wal_init_zero) { + struct iovec iov[PG_IOV_MAX]; + int blocks; + /* * Zero-fill the file. With this setting, we do this the hard way to * ensure that all the file space has really been allocated. On @@ -3366,15 +3396,28 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) * indirect blocks are down on disk. Therefore, fdatasync(2) or * O_DSYNC will be sufficient to sync future writes to the log file. */ - for (nbytes = 0; nbytes < wal_segment_size; nbytes += XLOG_BLCKSZ) + + /* Prepare to write out a lot of copies of our zero buffer at once. */ + for (int i = 0; i < lengthof(iov); ++i) { - errno = 0; - if (write(fd, zbuffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ) + iov[i].iov_base = zbuffer.data; + iov[i].iov_len = XLOG_BLCKSZ; + } + + /* Loop, writing as many blocks as we can for each system call. */ + blocks = wal_segment_size / XLOG_BLCKSZ; + for (int i = 0; i < blocks;) + { + int iovcnt = Min(blocks - i, lengthof(iov)); + off_t offset = i * XLOG_BLCKSZ; + + if (pg_pwritev_with_retry(fd, iov, iovcnt, offset) < 0) { - /* if write didn't set errno, assume no disk space */ - save_errno = errno ? errno : ENOSPC; + save_errno = errno; break; } + + i += iovcnt; } } else @@ -3822,8 +3865,8 @@ XLogFileReadAnyTLI(XLogSegNo segno, int emode, XLogSource source) * however, unless we actually find a valid segment. That way if there is * neither a timeline history file nor a WAL segment in the archive, and * streaming replication is set up, we'll read the timeline history file - * streamed from the primary when we start streaming, instead of recovering - * with a dummy history generated here. + * streamed from the primary when we start streaming, instead of + * recovering with a dummy history generated here. */ if (expectedTLEs) tles = expectedTLEs; @@ -4079,6 +4122,12 @@ RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr) DIR *xldir; struct dirent *xlde; char lastoff[MAXFNAMELEN]; + XLogSegNo endlogSegNo; + XLogSegNo recycleSegNo; + + /* Initialize info about where to try to recycle to */ + XLByteToSeg(endptr, endlogSegNo, wal_segment_size); + recycleSegNo = XLOGfileslop(lastredoptr); /* * Construct a filename of the last segment to be kept. The timeline ID @@ -4117,7 +4166,7 @@ RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr) /* Update the last removed location in shared memory first */ UpdateLastRemovedPtr(xlde->d_name); - RemoveXlogFile(xlde->d_name, lastredoptr, endptr); + RemoveXlogFile(xlde->d_name, recycleSegNo, &endlogSegNo); } } } @@ -4147,13 +4196,21 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI) struct dirent *xlde; char switchseg[MAXFNAMELEN]; XLogSegNo endLogSegNo; + XLogSegNo switchLogSegNo; + XLogSegNo recycleSegNo; - XLByteToPrevSeg(switchpoint, endLogSegNo, wal_segment_size); + /* + * Initialize info about where to begin the work. This will recycle, + * somewhat arbitrarily, 10 future segments. + */ + XLByteToPrevSeg(switchpoint, switchLogSegNo, wal_segment_size); + XLByteToSeg(switchpoint, endLogSegNo, wal_segment_size); + recycleSegNo = endLogSegNo + 10; /* * Construct a filename of the last segment to be kept. */ - XLogFileName(switchseg, newTLI, endLogSegNo, wal_segment_size); + XLogFileName(switchseg, newTLI, switchLogSegNo, wal_segment_size); elog(DEBUG2, "attempting to remove WAL segments newer than log file %s", switchseg); @@ -4181,7 +4238,7 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI) * - but seems safer to let them be archived and removed later. */ if (!XLogArchiveIsReady(xlde->d_name)) - RemoveXlogFile(xlde->d_name, InvalidXLogRecPtr, switchpoint); + RemoveXlogFile(xlde->d_name, recycleSegNo, &endLogSegNo); } } @@ -4191,56 +4248,42 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI) /* * Recycle or remove a log file that's no longer needed. * - * endptr is current (or recent) end of xlog, and lastredoptr is the - * redo pointer of the last checkpoint. These are used to determine - * whether we want to recycle rather than delete no-longer-wanted log files. - * If lastredoptr is not known, pass invalid, and the function will recycle, - * somewhat arbitrarily, 10 future segments. + * segname is the name of the segment to recycle or remove. recycleSegNo + * is the segment number to recycle up to. endlogSegNo is the segment + * number of the current (or recent) end of WAL. + * + * endlogSegNo gets incremented if the segment is recycled so as it is not + * checked again with future callers of this function. */ static void -RemoveXlogFile(const char *segname, XLogRecPtr lastredoptr, XLogRecPtr endptr) +RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo, + XLogSegNo *endlogSegNo) { char path[MAXPGPATH]; #ifdef WIN32 char newpath[MAXPGPATH]; #endif struct stat statbuf; - XLogSegNo endlogSegNo; - XLogSegNo recycleSegNo; - - if (wal_recycle) - { - /* - * Initialize info about where to try to recycle to. - */ - XLByteToSeg(endptr, endlogSegNo, wal_segment_size); - if (lastredoptr == InvalidXLogRecPtr) - recycleSegNo = endlogSegNo + 10; - else - recycleSegNo = XLOGfileslop(lastredoptr); - } - else - recycleSegNo = 0; /* keep compiler quiet */ snprintf(path, MAXPGPATH, XLOGDIR "/%s", segname); /* * Before deleting the file, see if it can be recycled as a future log - * segment. Only recycle normal files, pg_standby for example can create + * segment. Only recycle normal files, because we don't want to recycle * symbolic links pointing to a separate archive directory. */ if (wal_recycle && - endlogSegNo <= recycleSegNo && + *endlogSegNo <= recycleSegNo && lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) && - InstallXLogFileSegment(&endlogSegNo, path, + InstallXLogFileSegment(endlogSegNo, path, true, recycleSegNo, true)) { ereport(DEBUG2, - (errmsg("recycled write-ahead log file \"%s\"", - segname))); + (errmsg_internal("recycled write-ahead log file \"%s\"", + segname))); CheckpointStats.ckpt_segs_recycled++; /* Needn't recheck that slot on future iterations */ - endlogSegNo++; + (*endlogSegNo)++; } else { @@ -4248,8 +4291,8 @@ RemoveXlogFile(const char *segname, XLogRecPtr lastredoptr, XLogRecPtr endptr) int rc; ereport(DEBUG2, - (errmsg("removing write-ahead log file \"%s\"", - segname))); + (errmsg_internal("removing write-ahead log file \"%s\"", + segname))); #ifdef WIN32 @@ -4600,7 +4643,7 @@ rescanLatestTimeLine(void) (errmsg("new timeline %u forked off current database system timeline %u before current recovery point %X/%X", newtarget, ThisTimeLineID, - (uint32) (EndRecPtr >> 32), (uint32) EndRecPtr))); + LSN_FORMAT_ARGS(EndRecPtr)))); return false; } @@ -5250,6 +5293,7 @@ XLOGShmemInit(void) SpinLockInit(&XLogCtl->info_lck); SpinLockInit(&XLogCtl->ulsn_lck); InitSharedLatch(&XLogCtl->recoveryWakeupLatch); + ConditionVariableInit(&XLogCtl->recoveryNotPausedCV); } /* @@ -5810,8 +5854,7 @@ recoveryStopsBefore(XLogReaderState *record) recoveryStopName[0] = '\0'; ereport(LOG, (errmsg("recovery stopping before WAL location (LSN) \"%X/%X\"", - (uint32) (recoveryStopLSN >> 32), - (uint32) recoveryStopLSN))); + LSN_FORMAT_ARGS(recoveryStopLSN)))); return true; } @@ -5975,8 +6018,7 @@ recoveryStopsAfter(XLogReaderState *record) recoveryStopName[0] = '\0'; ereport(LOG, (errmsg("recovery stopping after WAL location (LSN) \"%X/%X\"", - (uint32) (recoveryStopLSN >> 32), - (uint32) recoveryStopLSN))); + LSN_FORMAT_ARGS(recoveryStopLSN)))); return true; } @@ -6078,15 +6120,11 @@ recoveryStopsAfter(XLogReaderState *record) } /* - * Wait until shared recoveryPause flag is cleared. + * Wait until shared recoveryPauseState is set to RECOVERY_NOT_PAUSED. * * endOfRecovery is true if the recovery target is reached and * the paused state starts at the end of recovery because of * recovery_target_action=pause, and false otherwise. - * - * XXX Could also be done with shared latch, avoiding the pg_usleep loop. - * Probably not worth the trouble though. This state shouldn't be one that - * anyone cares about server power consumption in. */ static void recoveryPausesHere(bool endOfRecovery) @@ -6108,34 +6146,80 @@ recoveryPausesHere(bool endOfRecovery) (errmsg("recovery has paused"), errhint("Execute pg_wal_replay_resume() to continue."))); - while (RecoveryIsPaused()) + /* loop until recoveryPauseState is set to RECOVERY_NOT_PAUSED */ + while (GetRecoveryPauseState() != RECOVERY_NOT_PAUSED) { HandleStartupProcInterrupts(); if (CheckForStandbyTrigger()) return; - pgstat_report_wait_start(WAIT_EVENT_RECOVERY_PAUSE); - pg_usleep(1000000L); /* 1000 ms */ - pgstat_report_wait_end(); + + /* + * If recovery pause is requested then set it paused. While we are in + * the loop, user might resume and pause again so set this every time. + */ + ConfirmRecoveryPaused(); + + /* + * We wait on a condition variable that will wake us as soon as the + * pause ends, but we use a timeout so we can check the above exit + * condition periodically too. + */ + ConditionVariableTimedSleep(&XLogCtl->recoveryNotPausedCV, 1000, + WAIT_EVENT_RECOVERY_PAUSE); } + ConditionVariableCancelSleep(); } -bool -RecoveryIsPaused(void) +/* + * Get the current state of the recovery pause request. + */ +RecoveryPauseState +GetRecoveryPauseState(void) { - bool recoveryPause; + RecoveryPauseState state; SpinLockAcquire(&XLogCtl->info_lck); - recoveryPause = XLogCtl->recoveryPause; + state = XLogCtl->recoveryPauseState; SpinLockRelease(&XLogCtl->info_lck); - return recoveryPause; + return state; } +/* + * Set the recovery pause state. + * + * If recovery pause is requested then sets the recovery pause state to + * 'pause requested' if it is not already 'paused'. Otherwise, sets it + * to 'not paused' to resume the recovery. The recovery pause will be + * confirmed by the ConfirmRecoveryPaused. + */ void SetRecoveryPause(bool recoveryPause) { SpinLockAcquire(&XLogCtl->info_lck); - XLogCtl->recoveryPause = recoveryPause; + + if (!recoveryPause) + XLogCtl->recoveryPauseState = RECOVERY_NOT_PAUSED; + else if (XLogCtl->recoveryPauseState == RECOVERY_NOT_PAUSED) + XLogCtl->recoveryPauseState = RECOVERY_PAUSE_REQUESTED; + + SpinLockRelease(&XLogCtl->info_lck); + + if (!recoveryPause) + ConditionVariableBroadcast(&XLogCtl->recoveryNotPausedCV); +} + +/* + * Confirm the recovery pause by setting the recovery pause state to + * RECOVERY_PAUSED. + */ +static void +ConfirmRecoveryPaused(void) +{ + /* If recovery pause is requested then set it paused */ + SpinLockAcquire(&XLogCtl->info_lck); + if (XLogCtl->recoveryPauseState == RECOVERY_PAUSE_REQUESTED) + XLogCtl->recoveryPauseState = RECOVERY_PAUSED; SpinLockRelease(&XLogCtl->info_lck); } @@ -6158,8 +6242,7 @@ recoveryApplyDelay(XLogReaderState *record) uint8 xact_info; TimestampTz xtime; TimestampTz delayUntil; - long secs; - int microsecs; + long msecs; /* nothing to do if no delay configured */ if (recovery_min_apply_delay <= 0) @@ -6200,8 +6283,8 @@ recoveryApplyDelay(XLogReaderState *record) * Exit without arming the latch if it's already past time to apply this * record */ - TimestampDifference(GetCurrentTimestamp(), delayUntil, &secs, µsecs); - if (secs <= 0 && microsecs <= 0) + msecs = TimestampDifferenceMilliseconds(GetCurrentTimestamp(), delayUntil); + if (msecs <= 0) return false; while (true) @@ -6217,22 +6300,17 @@ recoveryApplyDelay(XLogReaderState *record) /* * Wait for difference between GetCurrentTimestamp() and delayUntil */ - TimestampDifference(GetCurrentTimestamp(), delayUntil, - &secs, µsecs); + msecs = TimestampDifferenceMilliseconds(GetCurrentTimestamp(), + delayUntil); - /* - * NB: We're ignoring waits below recovery_min_apply_delay's - * resolution. - */ - if (secs <= 0 && microsecs / 1000 <= 0) + if (msecs <= 0) break; - elog(DEBUG2, "recovery apply delay %ld seconds, %d milliseconds", - secs, microsecs / 1000); + elog(DEBUG2, "recovery apply delay %ld milliseconds", msecs); (void) WaitLatch(&XLogCtl->recoveryWakeupLatch, WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, - secs * 1000L + microsecs / 1000, + msecs, WAIT_EVENT_RECOVERY_APPLY_DELAY); } return true; @@ -6465,16 +6543,82 @@ GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream) * Note that text field supplied is a parameter name and does not require * translation */ -#define RecoveryRequiresIntParameter(param_name, currValue, minValue) \ -do { \ - if ((currValue) < (minValue)) \ - ereport(ERROR, \ - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \ - errmsg("hot standby is not possible because %s = %d is a lower setting than on the primary server (its value was %d)", \ - param_name, \ - currValue, \ - minValue))); \ -} while(0) +static void +RecoveryRequiresIntParameter(const char *param_name, int currValue, int minValue) +{ + if (currValue < minValue) + { + if (LocalHotStandbyActive) + { + bool warned_for_promote = false; + + ereport(WARNING, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("hot standby is not possible because of insufficient parameter settings"), + errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.", + param_name, + currValue, + minValue))); + + SetRecoveryPause(true); + + ereport(LOG, + (errmsg("recovery has paused"), + errdetail("If recovery is unpaused, the server will shut down."), + errhint("You can then restart the server after making the necessary configuration changes."))); + + while (GetRecoveryPauseState() != RECOVERY_NOT_PAUSED) + { + HandleStartupProcInterrupts(); + + if (CheckForStandbyTrigger()) + { + if (!warned_for_promote) + ereport(WARNING, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("promotion is not possible because of insufficient parameter settings"), + + /* + * Repeat the detail from above so it's easy to find + * in the log. + */ + errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.", + param_name, + currValue, + minValue), + errhint("Restart the server after making the necessary configuration changes."))); + warned_for_promote = true; + } + + /* + * If recovery pause is requested then set it paused. While + * we are in the loop, user might resume and pause again so + * set this every time. + */ + ConfirmRecoveryPaused(); + + /* + * We wait on a condition variable that will wake us as soon + * as the pause ends, but we use a timeout so we can check the + * above conditions periodically too. + */ + ConditionVariableTimedSleep(&XLogCtl->recoveryNotPausedCV, 1000, + WAIT_EVENT_RECOVERY_PAUSE); + } + ConditionVariableCancelSleep(); + } + + ereport(FATAL, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("recovery aborted because of insufficient parameter settings"), + /* Repeat the detail from above so it's easy to find in the log. */ + errdetail("%s = %d is a lower setting than on the primary server, where its value was %d.", + param_name, + currValue, + minValue), + errhint("You can restart the server after making the necessary configuration changes."))); + } +} /* * Check to see if required parameters are set high enough on this server @@ -6493,9 +6637,10 @@ CheckRequiredParameterValues(void) */ if (ArchiveRecoveryRequested && ControlFile->wal_level == WAL_LEVEL_MINIMAL) { - ereport(WARNING, - (errmsg("WAL was generated with wal_level=minimal, data may be missing"), - errhint("This happens if you temporarily set wal_level=minimal without taking a new base backup."))); + ereport(FATAL, + (errmsg("WAL was generated with wal_level=minimal, cannot continue recovering"), + errdetail("This happens if you temporarily set wal_level=minimal on the server."), + errhint("Use a backup taken after setting wal_level to higher than minimal."))); } /* @@ -6504,11 +6649,6 @@ CheckRequiredParameterValues(void) */ if (ArchiveRecoveryRequested && EnableHotStandby) { - if (ControlFile->wal_level < WAL_LEVEL_REPLICA) - ereport(ERROR, - (errmsg("hot standby is not possible because wal_level was not set to \"replica\" or higher on the primary server"), - errhint("Either set wal_level to \"replica\" on the primary, or turn off hot_standby here."))); - /* We ignore autovacuum_max_workers when we make this test. */ RecoveryRequiresIntParameter("max_connections", MaxConnections, @@ -6719,8 +6859,7 @@ StartupXLOG(void) else if (recoveryTarget == RECOVERY_TARGET_LSN) ereport(LOG, (errmsg("starting point-in-time recovery to WAL location (LSN) \"%X/%X\"", - (uint32) (recoveryTargetLSN >> 32), - (uint32) recoveryTargetLSN))); + LSN_FORMAT_ARGS(recoveryTargetLSN)))); else if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE) ereport(LOG, (errmsg("starting point-in-time recovery to earliest consistent point"))); @@ -6785,8 +6924,8 @@ StartupXLOG(void) memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint)); wasShutdown = ((record->xl_info & ~XLR_INFO_MASK) == XLOG_CHECKPOINT_SHUTDOWN); ereport(DEBUG1, - (errmsg("checkpoint record is at %X/%X", - (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc))); + (errmsg_internal("checkpoint record is at %X/%X", + LSN_FORMAT_ARGS(checkPointLoc)))); InRecovery = true; /* force recovery even if SHUTDOWNED */ /* @@ -6918,8 +7057,8 @@ StartupXLOG(void) if (record != NULL) { ereport(DEBUG1, - (errmsg("checkpoint record is at %X/%X", - (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc))); + (errmsg_internal("checkpoint record is at %X/%X", + LSN_FORMAT_ARGS(checkPointLoc)))); } else { @@ -6982,11 +7121,9 @@ StartupXLOG(void) (errmsg("requested timeline %u is not a child of this server's history", recoveryTargetTLI), errdetail("Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X.", - (uint32) (ControlFile->checkPoint >> 32), - (uint32) ControlFile->checkPoint, + LSN_FORMAT_ARGS(ControlFile->checkPoint), ControlFile->checkPointCopy.ThisTimeLineID, - (uint32) (switchpoint >> 32), - (uint32) switchpoint))); + LSN_FORMAT_ARGS(switchpoint)))); } /* @@ -6999,15 +7136,14 @@ StartupXLOG(void) ereport(FATAL, (errmsg("requested timeline %u does not contain minimum recovery point %X/%X on timeline %u", recoveryTargetTLI, - (uint32) (ControlFile->minRecoveryPoint >> 32), - (uint32) ControlFile->minRecoveryPoint, + LSN_FORMAT_ARGS(ControlFile->minRecoveryPoint), ControlFile->minRecoveryPointTLI))); LastRec = RecPtr = checkPointLoc; ereport(DEBUG1, (errmsg_internal("redo record is at %X/%X; shutdown %s", - (uint32) (checkPoint.redo >> 32), (uint32) checkPoint.redo, + LSN_FORMAT_ARGS(checkPoint.redo), wasShutdown ? "true" : "false"))); ereport(DEBUG1, (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %u; next relfilenode: %u", @@ -7061,6 +7197,12 @@ StartupXLOG(void) */ StartupReorderBuffer(); + /* + * Startup CLOG. This must be done after ShmemVariableCache->nextXid has + * been initialized and before we accept connections or begin WAL replay. + */ + StartupCLOG(); + /* * Startup MultiXact. We need to do this early to be able to replay * truncations. @@ -7104,11 +7246,11 @@ StartupXLOG(void) * ourselves - the history file of the recovery target timeline covers all * the previous timelines in the history too - a cascading standby server * might be interested in them. Or, if you archive the WAL from this - * server to a different archive than the primary, it'd be good for all the - * history files to get archived there after failover, so that you can use - * one of the old timelines as a PITR target. Timeline history files are - * small, so it's better to copy them unnecessarily than not copy them and - * regret later. + * server to a different archive than the primary, it'd be good for all + * the history files to get archived there after failover, so that you can + * use one of the old timelines as a PITR target. Timeline history files + * are small, so it's better to copy them unnecessarily than not copy them + * and regret later. */ restoreTimeLineHistoryFiles(ThisTimeLineID, recoveryTargetTLI); @@ -7325,7 +7467,7 @@ StartupXLOG(void) int nxids; ereport(DEBUG1, - (errmsg("initializing for hot standby"))); + (errmsg_internal("initializing for hot standby"))); InitRecoveryTransactionEnvironment(); @@ -7339,11 +7481,10 @@ StartupXLOG(void) ProcArrayInitRecovery(XidFromFullTransactionId(ShmemVariableCache->nextXid)); /* - * Startup commit log and subtrans only. MultiXact and commit - * timestamp have already been started up and other SLRUs are not - * maintained during recovery and need not be started yet. + * Startup subtrans only. CLOG, MultiXact and commit timestamp + * have already been started up and other SLRUs are not maintained + * during recovery and need not be started yet. */ - StartupCLOG(); StartupSUBTRANS(oldestActiveXID); /* * Do not initialize DistributedLog subsystem. Hot standby / @@ -7413,7 +7554,7 @@ StartupXLOG(void) XLogCtl->lastReplayedTLI = XLogCtl->replayEndTLI; XLogCtl->recoveryLastXTime = 0; XLogCtl->currentChunkStartTime = 0; - XLogCtl->recoveryPause = false; + XLogCtl->recoveryPauseState = RECOVERY_NOT_PAUSED; SpinLockRelease(&XLogCtl->info_lck); /* Also ensure XLogReceiptTime has a sane value */ @@ -7465,12 +7606,15 @@ StartupXLOG(void) { ErrorContextCallback errcallback; TimestampTz xtime; + PGRUsage ru0; + + pg_rusage_init(&ru0); InRedo = true; ereport(LOG, (errmsg("redo starts at %X/%X", - (uint32) (ReadRecPtr >> 32), (uint32) ReadRecPtr))); + LSN_FORMAT_ARGS(ReadRecPtr)))); /* * main redo apply loop @@ -7488,8 +7632,8 @@ StartupXLOG(void) initStringInfo(&buf); appendStringInfo(&buf, "REDO @ %X/%X; LSN %X/%X: ", - (uint32) (ReadRecPtr >> 32), (uint32) ReadRecPtr, - (uint32) (EndRecPtr >> 32), (uint32) EndRecPtr); + LSN_FORMAT_ARGS(ReadRecPtr), + LSN_FORMAT_ARGS(EndRecPtr)); xlog_outrec(&buf, xlogreader); appendStringInfoString(&buf, " - "); xlog_outdesc(&buf, xlogreader); @@ -7514,7 +7658,8 @@ StartupXLOG(void) * otherwise would is a minor issue, so it doesn't seem worth * adding another spinlock cycle to prevent that. */ - if (((volatile XLogCtlData *) XLogCtl)->recoveryPause) + if (((volatile XLogCtlData *) XLogCtl)->recoveryPauseState != + RECOVERY_NOT_PAUSED) recoveryPausesHere(false); /* @@ -7539,7 +7684,8 @@ StartupXLOG(void) * here otherwise pausing during the delay-wait wouldn't * work. */ - if (((volatile XLogCtlData *) XLogCtl)->recoveryPause) + if (((volatile XLogCtlData *) XLogCtl)->recoveryPauseState != + RECOVERY_NOT_PAUSED) recoveryPausesHere(false); } @@ -7550,8 +7696,7 @@ StartupXLOG(void) error_context_stack = &errcallback; /* - * ShmemVariableCache->nextXid must be beyond record's - * xid. + * ShmemVariableCache->nextXid must be beyond record's xid. */ AdvanceNextFullTransactionIdPastXid(record->xl_xid); @@ -7756,8 +7901,9 @@ StartupXLOG(void) } ereport(LOG, - (errmsg("redo done at %X/%X", - (uint32) (ReadRecPtr >> 32), (uint32) ReadRecPtr))); + (errmsg("redo done at %X/%X system usage: %s", + LSN_FORMAT_ARGS(ReadRecPtr), + pg_rusage_show(&ru0)))); xtime = GetLatestXTime(); if (xtime) ereport(LOG, @@ -7933,8 +8079,7 @@ StartupXLOG(void) snprintf(reason, sizeof(reason), "%s LSN %X/%X\n", recoveryStopAfter ? "after" : "before", - (uint32) (recoveryStopLSN >> 32), - (uint32) recoveryStopLSN); + LSN_FORMAT_ARGS(recoveryStopLSN)); else if (recoveryTarget == RECOVERY_TARGET_NAME) snprintf(reason, sizeof(reason), "at restore point \"%s\"", @@ -8236,8 +8381,8 @@ StartupXLOG(void) LWLockRelease(ProcArrayLock); /* - * Start up the commit log and subtrans, if not already done for hot - * standby. (commit timestamps are started below, if necessary.) + * Start up subtrans, if not already done for hot standby. (commit + * timestamps are started below, if necessary.) */ if (standbyState == STANDBY_DISABLED) { @@ -8291,17 +8436,16 @@ StartupXLOG(void) * All done with end-of-recovery actions. * * Now allow backends to write WAL and update the control file status in - * consequence. The boolean flag allowing backends to write WAL is - * updated while holding ControlFileLock to prevent other backends to look - * at an inconsistent state of the control file in shared memory. There - * is still a small window during which backends can write WAL and the - * control file is still referring to a system not in DB_IN_PRODUCTION + * consequence. SharedRecoveryState, that controls if backends can write + * WAL, is updated while holding ControlFileLock to prevent other backends + * to look at an inconsistent state of the control file in shared memory. + * There is still a small window during which backends can write WAL and + * the control file is still referring to a system not in DB_IN_PRODUCTION * state while looking at the on-disk control file. * - * Also, although the boolean flag to allow WAL is probably atomic in - * itself, we use the info_lck here to ensure that there are no race - * conditions concerning visibility of other recent updates to shared - * memory. + * Also, we use info_lck to update SharedRecoveryState to ensure that + * there are no race conditions concerning visibility of other recent + * updates to shared memory. */ LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->state = DB_IN_PRODUCTION; @@ -8331,10 +8475,10 @@ StartupXLOG(void) UpdateCatalogForStandbyPromotion(); /* - * If this was a promotion, request an (online) checkpoint now. This - * isn't required for consistency, but the last restartpoint might be far - * back, and in case of a crash, recovering from it might take a longer - * than is appropriate now that we're not in standby mode anymore. + * If this was a promotion, request an (online) checkpoint now. This isn't + * required for consistency, but the last restartpoint might be far back, + * and in case of a crash, recovering from it might take a longer than is + * appropriate now that we're not in standby mode anymore. */ if (promoted) RequestCheckpoint(CHECKPOINT_FORCE); @@ -8416,8 +8560,7 @@ CheckRecoveryConsistency(void) reachedConsistency = true; ereport(LOG, (errmsg("consistent recovery state reached at %X/%X", - (uint32) (lastReplayedEndRecPtr >> 32), - (uint32) lastReplayedEndRecPtr))); + LSN_FORMAT_ARGS(lastReplayedEndRecPtr)))); } /* @@ -8959,10 +9102,6 @@ ShutdownXLOG(int code pg_attribute_unused() , Datum arg pg_attribute_unused() ) CreateCheckPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE); } - ShutdownCLOG(); - ShutdownCommitTs(); - ShutdownSUBTRANS(); - ShutdownMultiXact(); DistributedLog_Shutdown(); } @@ -8972,16 +9111,30 @@ ShutdownXLOG(int code pg_attribute_unused() , Datum arg pg_attribute_unused() ) static void LogCheckpointStart(int flags, bool restartpoint) { - elog(LOG, "%s starting:%s%s%s%s%s%s%s%s", - restartpoint ? "restartpoint" : "checkpoint", - (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "", - (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "", - (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "", - (flags & CHECKPOINT_FORCE) ? " force" : "", - (flags & CHECKPOINT_WAIT) ? " wait" : "", - (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "", - (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "", - (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : ""); + if (restartpoint) + ereport(LOG, + /* translator: the placeholders show checkpoint options */ + (errmsg("restartpoint starting:%s%s%s%s%s%s%s%s", + (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "", + (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "", + (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "", + (flags & CHECKPOINT_FORCE) ? " force" : "", + (flags & CHECKPOINT_WAIT) ? " wait" : "", + (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "", + (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "", + (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : ""))); + else + ereport(LOG, + /* translator: the placeholders show checkpoint options */ + (errmsg("checkpoint starting:%s%s%s%s%s%s%s%s", + (flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "", + (flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "", + (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "", + (flags & CHECKPOINT_FORCE) ? " force" : "", + (flags & CHECKPOINT_WAIT) ? " wait" : "", + (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "", + (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "", + (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : ""))); } /* @@ -8990,33 +9143,24 @@ LogCheckpointStart(int flags, bool restartpoint) static void LogCheckpointEnd(bool restartpoint) { - long write_secs, - sync_secs, - total_secs, - longest_secs, - average_secs; - int write_usecs, - sync_usecs, - total_usecs, - longest_usecs, - average_usecs; + long write_msecs, + sync_msecs, + total_msecs, + longest_msecs, + average_msecs; uint64 average_sync_time; CheckpointStats.ckpt_end_t = GetCurrentTimestamp(); - TimestampDifference(CheckpointStats.ckpt_write_t, - CheckpointStats.ckpt_sync_t, - &write_secs, &write_usecs); + write_msecs = TimestampDifferenceMilliseconds(CheckpointStats.ckpt_write_t, + CheckpointStats.ckpt_sync_t); - TimestampDifference(CheckpointStats.ckpt_sync_t, - CheckpointStats.ckpt_sync_end_t, - &sync_secs, &sync_usecs); + sync_msecs = TimestampDifferenceMilliseconds(CheckpointStats.ckpt_sync_t, + CheckpointStats.ckpt_sync_end_t); /* Accumulate checkpoint timing summary data, in milliseconds. */ - BgWriterStats.m_checkpoint_write_time += - write_secs * 1000 + write_usecs / 1000; - BgWriterStats.m_checkpoint_sync_time += - sync_secs * 1000 + sync_usecs / 1000; + BgWriterStats.m_checkpoint_write_time += write_msecs; + BgWriterStats.m_checkpoint_sync_time += sync_msecs; /* * All of the published timing statistics are accounted for. Only @@ -9025,45 +9169,61 @@ LogCheckpointEnd(bool restartpoint) if (!log_checkpoints) return; - TimestampDifference(CheckpointStats.ckpt_start_t, - CheckpointStats.ckpt_end_t, - &total_secs, &total_usecs); + total_msecs = TimestampDifferenceMilliseconds(CheckpointStats.ckpt_start_t, + CheckpointStats.ckpt_end_t); /* * Timing values returned from CheckpointStats are in microseconds. - * Convert to the second plus microsecond form that TimestampDifference - * returns for homogeneous printing. + * Convert to milliseconds for consistent printing. */ - longest_secs = (long) (CheckpointStats.ckpt_longest_sync / 1000000); - longest_usecs = CheckpointStats.ckpt_longest_sync - - (uint64) longest_secs * 1000000; + longest_msecs = (long) ((CheckpointStats.ckpt_longest_sync + 999) / 1000); average_sync_time = 0; if (CheckpointStats.ckpt_sync_rels > 0) average_sync_time = CheckpointStats.ckpt_agg_sync_time / CheckpointStats.ckpt_sync_rels; - average_secs = (long) (average_sync_time / 1000000); - average_usecs = average_sync_time - (uint64) average_secs * 1000000; - - elog(LOG, "%s complete: wrote %d buffers (%.1f%%); " - "%d WAL file(s) added, %d removed, %d recycled; " - "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; " - "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; " - "distance=%d kB, estimate=%d kB", - restartpoint ? "restartpoint" : "checkpoint", - CheckpointStats.ckpt_bufs_written, - (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers, - CheckpointStats.ckpt_segs_added, - CheckpointStats.ckpt_segs_removed, - CheckpointStats.ckpt_segs_recycled, - write_secs, write_usecs / 1000, - sync_secs, sync_usecs / 1000, - total_secs, total_usecs / 1000, - CheckpointStats.ckpt_sync_rels, - longest_secs, longest_usecs / 1000, - average_secs, average_usecs / 1000, - (int) (PrevCheckPointDistance / 1024.0), - (int) (CheckPointDistanceEstimate / 1024.0)); + average_msecs = (long) ((average_sync_time + 999) / 1000); + + if (restartpoint) + ereport(LOG, + (errmsg("restartpoint complete: wrote %d buffers (%.1f%%); " + "%d WAL file(s) added, %d removed, %d recycled; " + "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; " + "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; " + "distance=%d kB, estimate=%d kB", + CheckpointStats.ckpt_bufs_written, + (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers, + CheckpointStats.ckpt_segs_added, + CheckpointStats.ckpt_segs_removed, + CheckpointStats.ckpt_segs_recycled, + write_msecs / 1000, (int) (write_msecs % 1000), + sync_msecs / 1000, (int) (sync_msecs % 1000), + total_msecs / 1000, (int) (total_msecs % 1000), + CheckpointStats.ckpt_sync_rels, + longest_msecs / 1000, (int) (longest_msecs % 1000), + average_msecs / 1000, (int) (average_msecs % 1000), + (int) (PrevCheckPointDistance / 1024.0), + (int) (CheckPointDistanceEstimate / 1024.0)))); + else + ereport(LOG, + (errmsg("checkpoint complete: wrote %d buffers (%.1f%%); " + "%d WAL file(s) added, %d removed, %d recycled; " + "write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; " + "sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; " + "distance=%d kB, estimate=%d kB", + CheckpointStats.ckpt_bufs_written, + (double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers, + CheckpointStats.ckpt_segs_added, + CheckpointStats.ckpt_segs_removed, + CheckpointStats.ckpt_segs_recycled, + write_msecs / 1000, (int) (write_msecs % 1000), + sync_msecs / 1000, (int) (sync_msecs % 1000), + total_msecs / 1000, (int) (total_msecs % 1000), + CheckpointStats.ckpt_sync_rels, + longest_msecs / 1000, (int) (longest_msecs % 1000), + average_msecs / 1000, (int) (average_msecs % 1000), + (int) (PrevCheckPointDistance / 1024.0), + (int) (CheckPointDistanceEstimate / 1024.0)))); } /* @@ -9105,6 +9265,39 @@ UpdateCheckPointDistanceEstimate(uint64 nbytes) (0.90 * CheckPointDistanceEstimate + 0.10 * (double) nbytes); } +/* + * Update the ps display for a process running a checkpoint. Note that + * this routine should not do any allocations so as it can be called + * from a critical section. + */ +static void +update_checkpoint_display(int flags, bool restartpoint, bool reset) +{ + /* + * The status is reported only for end-of-recovery and shutdown + * checkpoints or shutdown restartpoints. Updating the ps display is + * useful in those situations as it may not be possible to rely on + * pg_stat_activity to see the status of the checkpointer or the startup + * process. + */ + if ((flags & (CHECKPOINT_END_OF_RECOVERY | CHECKPOINT_IS_SHUTDOWN)) == 0) + return; + + if (reset) + set_ps_display(""); + else + { + char activitymsg[128]; + + snprintf(activitymsg, sizeof(activitymsg), "performing %s%s%s", + (flags & CHECKPOINT_END_OF_RECOVERY) ? "end-of-recovery " : "", + (flags & CHECKPOINT_IS_SHUTDOWN) ? "shutdown " : "", + restartpoint ? "restartpoint" : "checkpoint"); + set_ps_display(activitymsg); + } +} + + /* * Perform a checkpoint --- either during shutdown, or on-the-fly * @@ -9183,14 +9376,6 @@ CreateCheckPoint(int flags) */ InitXLogInsert(); - /* - * Acquire CheckpointLock to ensure only one checkpoint happens at a time. - * (This is just pro forma, since in the present system structure there is - * only one process that is allowed to issue checkpoints at any given - * time.) - */ - LWLockAcquire(CheckpointLock, LW_EXCLUSIVE); - /* * Prepare to accumulate statistics. * @@ -9260,10 +9445,9 @@ CreateCheckPoint(int flags) if (last_important_lsn == ControlFile->checkPoint) { WALInsertLockRelease(); - LWLockRelease(CheckpointLock); END_CRIT_SECTION(); ereport(DEBUG1, - (errmsg("checkpoint skipped because system is idle"))); + (errmsg_internal("checkpoint skipped because system is idle"))); return; } } @@ -9334,6 +9518,9 @@ CreateCheckPoint(int flags) if (log_checkpoints) LogCheckpointStart(flags, false); + /* Update the process title */ + update_checkpoint_display(flags, false, false); + TRACE_POSTGRESQL_CHECKPOINT_START(flags); /* @@ -9622,20 +9809,20 @@ CreateCheckPoint(int flags) /* Real work is done, but log and update stats before releasing lock. */ LogCheckpointEnd(false); + /* Reset the process title */ + update_checkpoint_display(flags, false, true); + TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written, NBuffers, CheckpointStats.ckpt_segs_added, CheckpointStats.ckpt_segs_removed, CheckpointStats.ckpt_segs_recycled); - - LWLockRelease(CheckpointLock); } /* * Mark the end of recovery in WAL though without running a full checkpoint. * We can expect that a restartpoint is likely to be in progress as we - * do this, though we are unwilling to wait for it to complete. So be - * careful to avoid taking the CheckpointLock anywhere here. + * do this, though we are unwilling to wait for it to complete. * * CreateRestartPoint() allows for the case where recovery may end before * the restartpoint completes so there is no concern of concurrent behaviour. @@ -9739,18 +9926,30 @@ CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn) static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags) { + CheckPointRelationMap(); + CheckPointReplicationSlots(); + CheckPointSnapBuild(); + CheckPointLogicalRewriteHeap(); + CheckPointReplicationOrigin(); + + /* Write out all dirty data in SLRUs and the main buffer pool */ + TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags); + CheckpointStats.ckpt_write_t = GetCurrentTimestamp(); CheckPointCLOG(); CheckPointCommitTs(); CheckPointSUBTRANS(); CheckPointMultiXact(); DistributedLog_CheckPoint(); CheckPointPredicate(); - CheckPointRelationMap(); - CheckPointReplicationSlots(); - CheckPointSnapBuild(); - CheckPointLogicalRewriteHeap(); - CheckPointBuffers(flags); /* performs all required fsyncs */ - CheckPointReplicationOrigin(); + CheckPointBuffers(flags); + + /* Perform all queued up fsyncs */ + TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START(); + CheckpointStats.ckpt_sync_t = GetCurrentTimestamp(); + ProcessSyncRequests(); + CheckpointStats.ckpt_sync_end_t = GetCurrentTimestamp(); + TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE(); + /* We deliberately delay 2PC checkpointing as long as possible */ CheckPointTwoPhase(checkPointRedo); } @@ -9780,8 +9979,7 @@ RecoveryRestartPoint(const CheckPoint *checkPoint) elog(trace_recovery(DEBUG2), "could not record restart point at %X/%X because there " "are unresolved references to invalid pages", - (uint32) (checkPoint->redo >> 32), - (uint32) checkPoint->redo); + LSN_FORMAT_ARGS(checkPoint->redo)); return; } @@ -9821,12 +10019,6 @@ CreateRestartPoint(int flags) XLogSegNo _logSegNo; TimestampTz xtime; - /* - * Acquire CheckpointLock to ensure only one restartpoint or checkpoint - * happens at a time. - */ - LWLockAcquire(CheckpointLock, LW_EXCLUSIVE); - /* Get a local copy of the last safe checkpoint record. */ SpinLockAcquire(&XLogCtl->info_lck); lastCheckPointRecPtr = XLogCtl->lastCheckPointRecPtr; @@ -9841,8 +10033,7 @@ CreateRestartPoint(int flags) if (!RecoveryInProgress()) { ereport(DEBUG2, - (errmsg("skipping restartpoint, recovery has already ended"))); - LWLockRelease(CheckpointLock); + (errmsg_internal("skipping restartpoint, recovery has already ended"))); return false; } @@ -9864,9 +10055,8 @@ CreateRestartPoint(int flags) lastCheckPoint.redo <= ControlFile->checkPointCopy.redo) { ereport(DEBUG2, - (errmsg("skipping restartpoint, already performed at %X/%X", - (uint32) (lastCheckPoint.redo >> 32), - (uint32) lastCheckPoint.redo))); + (errmsg_internal("skipping restartpoint, already performed at %X/%X", + LSN_FORMAT_ARGS(lastCheckPoint.redo)))); UpdateMinRecoveryPoint(InvalidXLogRecPtr, true); if (flags & CHECKPOINT_IS_SHUTDOWN) @@ -9877,7 +10067,6 @@ CreateRestartPoint(int flags) UpdateControlFile(); LWLockRelease(ControlFileLock); } - LWLockRelease(CheckpointLock); return false; } @@ -9912,6 +10101,9 @@ CreateRestartPoint(int flags) if (log_checkpoints) LogCheckpointStart(flags, true); + /* Update the process title */ + update_checkpoint_display(flags, true, false); + CheckPointGuts(lastCheckPoint.redo, flags); SIMPLE_FAULT_INJECTOR("restartpoint_guts"); @@ -10032,15 +10224,16 @@ CreateRestartPoint(int flags) /* Real work is done, but log and update before releasing lock. */ LogCheckpointEnd(true); + /* Reset the process title */ + update_checkpoint_display(flags, true, true); + xtime = GetLatestXTime(); ereport((log_checkpoints ? LOG : DEBUG2), (errmsg("recovery restart point at %X/%X", - (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo), + LSN_FORMAT_ARGS(lastCheckPoint.redo)), xtime ? errdetail("Last completed transaction was at log time %s.", timestamptz_to_str(xtime)) : 0)); - LWLockRelease(CheckpointLock); - /* * Finally, execute archive_cleanup_command, if any. */ @@ -10344,7 +10537,7 @@ XLogRestorePoint(const char *rpName) ereport(LOG, (errmsg("restore point \"%s\" created at %X/%X", - rpName, (uint32) (RecPtr >> 32), (uint32) RecPtr))); + rpName, LSN_FORMAT_ARGS(RecPtr)))); return RecPtr; } @@ -10515,8 +10708,7 @@ checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI) ereport(PANIC, (errmsg("unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u", newTLI, - (uint32) (minRecoveryPoint >> 32), - (uint32) minRecoveryPoint, + LSN_FORMAT_ARGS(minRecoveryPoint), minRecoveryPointTLI))); /* Looks good */ @@ -10947,16 +11139,26 @@ VerifyOverwriteContrecord(xl_overwrite_contrecord *xlrec, XLogReaderState *state static void xlog_outrec(StringInfo buf, XLogReaderState *record) { - int block_id; - appendStringInfo(buf, "prev %X/%X; xid %u", - (uint32) (XLogRecGetPrev(record) >> 32), - (uint32) XLogRecGetPrev(record), + LSN_FORMAT_ARGS(XLogRecGetPrev(record)), XLogRecGetXid(record)); appendStringInfo(buf, "; len %u", XLogRecGetDataLen(record)); + xlog_block_info(buf, record); +} +#endif /* WAL_DEBUG */ + +/* + * Returns a string giving information about all the blocks in an + * XLogRecord. + */ +static void +xlog_block_info(StringInfo buf, XLogReaderState *record) +{ + int block_id; + /* decode block references */ for (block_id = 0; block_id <= record->max_block_id; block_id++) { @@ -10983,7 +11185,6 @@ xlog_outrec(StringInfo buf, XLogReaderState *record) appendStringInfoString(buf, " FPW"); } } -#endif /* WAL_DEBUG */ /* * Returns a string describing an XLogRecord, consisting of its identity @@ -11033,7 +11234,7 @@ get_sync_bit(int method) * * Never use O_DIRECT in walreceiver process for similar reasons; the WAL * written by walreceiver is normally read by the startup process soon - * after its written. Also, walreceiver performs unaligned writes, which + * after it's written. Also, walreceiver performs unaligned writes, which * don't work with O_DIRECT, so it is required for correctness too. */ if (!XLogIsNeeded() && !AmWalReceiverProcess()) @@ -11115,6 +11316,20 @@ void issue_xlog_fsync(int fd, XLogSegNo segno) { char *msg = NULL; + instr_time start; + + /* + * Quick exit if fsync is disabled or write() has already synced the WAL + * file. + */ + if (!enableFsync || + sync_method == SYNC_METHOD_OPEN || + sync_method == SYNC_METHOD_OPEN_DSYNC) + return; + + /* Measure I/O timing to sync the WAL file */ + if (track_wal_io_timing) + INSTR_TIME_SET_CURRENT(start); pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC); switch (sync_method) @@ -11137,7 +11352,8 @@ issue_xlog_fsync(int fd, XLogSegNo segno) #endif case SYNC_METHOD_OPEN: case SYNC_METHOD_OPEN_DSYNC: - /* write synced it already */ + /* not reachable */ + Assert(false); break; default: elog(PANIC, "unrecognized wal_sync_method: %d", sync_method); @@ -11159,6 +11375,20 @@ issue_xlog_fsync(int fd, XLogSegNo segno) } pgstat_report_wait_end(); + + /* + * Increment the I/O timing and the number of times WAL files were synced. + */ + if (track_wal_io_timing) + { + instr_time duration; + + INSTR_TIME_SET_CURRENT(duration); + INSTR_TIME_SUBTRACT(duration, start); + WalStats.m_wal_sync_time += INSTR_TIME_GET_MICROSEC(duration); + } + + WalStats.m_wal_sync++; } /* @@ -11182,19 +11412,17 @@ issue_xlog_fsync(int fd, XLogSegNo segno) * active at the same time, and they don't conflict with an exclusive backup * either. * - * tablespaces is required only when this function is called while - * the streaming base backup requested by pg_basebackup is running. - * NULL should be specified otherwise. + * labelfile and tblspcmapfile must be passed as NULL when starting an + * exclusive backup, and as initially-empty StringInfos for a non-exclusive + * backup. + * + * If "tablespaces" isn't NULL, it receives a list of tablespaceinfo structs + * describing the cluster's tablespaces. * * tblspcmapfile is required mainly for tar format in windows as native windows * utilities are not able to create symlinks while extracting files from tar. * However for consistency, the same is used for all platforms. * - * needtblspcmapfile is true for the cases (exclusive backup and for - * non-exclusive backup only when tar format is used for taking backup) - * when backup needs to generate tablespace_map file, it is used to - * embed escape character before newline character in tablespace path. - * * Returns the minimum WAL location that must be present to restore from this * backup, and the corresponding timeline ID in *starttli_p. * @@ -11207,7 +11435,7 @@ issue_xlog_fsync(int fd, XLogSegNo segno) XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, StringInfo labelfile, List **tablespaces, - StringInfo tblspcmapfile, bool needtblspcmapfile) + StringInfo tblspcmapfile) { bool exclusive = (labelfile == NULL); bool backup_started_in_recovery = false; @@ -11420,9 +11648,10 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, XLogFileName(xlogfilename, starttli, _logSegNo, wal_segment_size); /* - * Construct tablespace_map file + * Construct tablespace_map file. If caller isn't interested in this, + * we make a local StringInfo. */ - if (exclusive) + if (tblspcmapfile == NULL) tblspcmapfile = makeStringInfo(); datadirpathlen = strlen(DataDir); @@ -11435,11 +11664,11 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, char linkpath[MAXPGPATH]; char *relpath = NULL; int rllen; - StringInfoData buflinkpath; - char *s = linkpath; + StringInfoData escapedpath; + char *s; - /* Skip special stuff */ - if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) + /* Skip anything that doesn't look like a tablespace */ + if (strspn(de->d_name, "0123456789") != strlen(de->d_name)) continue; snprintf(fullpath, sizeof(fullpath), "pg_tblspc/%s", de->d_name); @@ -11463,18 +11692,15 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, linkpath[rllen] = '\0'; /* - * Add the escape character '\\' before newline in a string to - * ensure that we can distinguish between the newline in the - * tablespace path and end of line while reading tablespace_map - * file during archive recovery. + * Build a backslash-escaped version of the link path to include + * in the tablespace map file. */ - initStringInfo(&buflinkpath); - - while (*s) + initStringInfo(&escapedpath); + for (s = linkpath; *s; s++) { - if ((*s == '\n' || *s == '\r') && needtblspcmapfile) - appendStringInfoChar(&buflinkpath, '\\'); - appendStringInfoChar(&buflinkpath, *s++); + if (*s == '\n' || *s == '\r' || *s == '\\') + appendStringInfoChar(&escapedpath, '\\'); + appendStringInfoChar(&escapedpath, *s); } /* @@ -11489,16 +11715,17 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, ti = palloc(sizeof(tablespaceinfo)); ti->oid = pstrdup(de->d_name); - ti->path = pstrdup(buflinkpath.data); + ti->path = pstrdup(linkpath); ti->rpath = relpath ? pstrdup(relpath) : NULL; ti->size = -1; if (tablespaces) *tablespaces = lappend(*tablespaces, ti); - appendStringInfo(tblspcmapfile, "%s %s\n", ti->oid, ti->path); + appendStringInfo(tblspcmapfile, "%s %s\n", + ti->oid, escapedpath.data); - pfree(buflinkpath.data); + pfree(escapedpath.data); #else /* @@ -11514,9 +11741,10 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, FreeDir(tblspcdir); /* - * Construct backup label file + * Construct backup label file. If caller isn't interested in this, + * we make a local StringInfo. */ - if (exclusive) + if (labelfile == NULL) labelfile = makeStringInfo(); /* Use the log timezone here, not the session timezone */ @@ -11525,9 +11753,9 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, "%Y-%m-%d %H:%M:%S %Z", pg_localtime(&stamp_time, log_timezone)); appendStringInfo(labelfile, "START WAL LOCATION: %X/%X (file %s)\n", - (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename); + LSN_FORMAT_ARGS(startpoint), xlogfilename); appendStringInfo(labelfile, "CHECKPOINT LOCATION: %X/%X\n", - (uint32) (checkpointloc >> 32), (uint32) checkpointloc); + LSN_FORMAT_ARGS(checkpointloc)); appendStringInfo(labelfile, "BACKUP METHOD: %s\n", exclusive ? "pg_start_backup" : "streamed"); appendStringInfo(labelfile, "BACKUP FROM: %s\n", @@ -12018,9 +12246,9 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) errmsg("could not create file \"%s\": %m", histfilepath))); fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n", - (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename); + LSN_FORMAT_ARGS(startpoint), startxlogfilename); fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n", - (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename); + LSN_FORMAT_ARGS(stoppoint), stopxlogfilename); /* * Transfer remaining lines including label and start timeline to @@ -12341,13 +12569,13 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, */ if (fscanf(lfp, "START TIME: %127[^\n]\n", backuptime) == 1) ereport(DEBUG1, - (errmsg("backup time %s in file \"%s\"", - backuptime, BACKUP_LABEL_FILE))); + (errmsg_internal("backup time %s in file \"%s\"", + backuptime, BACKUP_LABEL_FILE))); if (fscanf(lfp, "LABEL: %1023[^\n]\n", backuplabel) == 1) ereport(DEBUG1, - (errmsg("backup label %s in file \"%s\"", - backuplabel, BACKUP_LABEL_FILE))); + (errmsg_internal("backup label %s in file \"%s\"", + backuplabel, BACKUP_LABEL_FILE))); /* * START TIMELINE is new as of 11. Its parsing is not mandatory, still use @@ -12363,8 +12591,8 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, tli_from_file, tli_from_walseg))); ereport(DEBUG1, - (errmsg("backup timeline %u in file \"%s\"", - tli_from_file, BACKUP_LABEL_FILE))); + (errmsg_internal("backup timeline %u in file \"%s\"", + tli_from_file, BACKUP_LABEL_FILE))); } if (ferror(lfp) || FreeFile(lfp)) @@ -12383,22 +12611,20 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, * recovering from a backup dump file, and we therefore need to create symlinks * as per the information present in tablespace_map file. * - * Returns true if a tablespace_map file was found (and fills the link - * information for all the tablespace links present in file); returns false - * if not. + * Returns true if a tablespace_map file was found (and fills *tablespaces + * with a tablespaceinfo struct for each tablespace listed in the file); + * returns false if not. */ static bool read_tablespace_map(List **tablespaces) { tablespaceinfo *ti; FILE *lfp; - char tbsoid[MAXPGPATH]; - char *tbslinkpath; char str[MAXPGPATH]; int ch, - prev_ch = -1, - i = 0, + i, n; + bool was_backslash; /* * See if tablespace_map file is present @@ -12417,38 +12643,55 @@ read_tablespace_map(List **tablespaces) /* * Read and parse the link name and path lines from tablespace_map file * (this code is pretty crude, but we are not expecting any variability in - * the file format). While taking backup we embed escape character '\\' - * before newline in tablespace path, so that during reading of - * tablespace_map file, we could distinguish newline in tablespace path - * and end of line. Now while reading tablespace_map file, remove the - * escape character that has been added in tablespace path during backup. + * the file format). De-escape any backslashes that were inserted. */ + i = 0; + was_backslash = false; while ((ch = fgetc(lfp)) != EOF) { - if ((ch == '\n' || ch == '\r') && prev_ch != '\\') + if (!was_backslash && (ch == '\n' || ch == '\r')) { + if (i == 0) + continue; /* \r immediately followed by \n */ + + /* + * The de-escaped line should contain an OID followed by exactly + * one space followed by a path. The path might start with + * spaces, so don't be too liberal about parsing. + */ str[i] = '\0'; - if (sscanf(str, "%s %n", tbsoid, &n) != 1) + n = 0; + while (str[n] && str[n] != ' ') + n++; + if (n < 1 || n >= i - 1) ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", TABLESPACE_MAP))); - tbslinkpath = str + n; - i = 0; - - ti = palloc(sizeof(tablespaceinfo)); - ti->oid = pstrdup(tbsoid); - ti->path = pstrdup(tbslinkpath); + str[n++] = '\0'; + ti = palloc0(sizeof(tablespaceinfo)); + ti->oid = pstrdup(str); + ti->path = pstrdup(str + n); *tablespaces = lappend(*tablespaces, ti); + + i = 0; continue; } - else if ((ch == '\n' || ch == '\r') && prev_ch == '\\') - str[i - 1] = ch; + else if (!was_backslash && ch == '\\') + was_backslash = true; else - str[i++] = ch; - prev_ch = ch; + { + if (i < sizeof(str) - 1) + str[i++] = ch; + was_backslash = false; + } } + if (i != 0 || was_backslash) /* last line not terminated? */ + ereport(FATAL, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("invalid data in file \"%s\"", TABLESPACE_MAP))); + if (ferror(lfp) || FreeFile(lfp)) ereport(FATAL, (errcode_for_file_access(), @@ -12469,11 +12712,11 @@ rm_redo_error_callback(void *arg) initStringInfo(&buf); xlog_outdesc(&buf, record); + xlog_block_info(&buf, record); /* translator: %s is a WAL record description */ errcontext("WAL redo at %X/%X for %s", - (uint32) (record->ReadRecPtr >> 32), - (uint32) record->ReadRecPtr, + LSN_FORMAT_ARGS(record->ReadRecPtr), buf.data); pfree(buf.data); @@ -12665,8 +12908,8 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, Assert(readFile != -1); /* - * If the current segment is being streamed from the primary, calculate how - * much of the current page we have received already. We know the + * If the current segment is being streamed from the primary, calculate + * how much of the current page we have received already. We know the * requested record has been received, but this is for the benefit of * future calls, to allow quick exit at the top of this function. */ @@ -12727,12 +12970,13 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, * and replay reaches a record that's split across two WAL segments. The * first page is only available locally, in pg_wal, because it's already * been recycled on the primary. The second page, however, is not present - * in pg_wal, and we should stream it from the primary. There is a recycled - * WAL segment present in pg_wal, with garbage contents, however. We would - * read the first page from the local WAL segment, but when reading the - * second page, we would read the bogus, recycled, WAL segment. If we - * didn't catch that case here, we would never recover, because - * ReadRecord() would retry reading the whole record from the beginning. + * in pg_wal, and we should stream it from the primary. There is a + * recycled WAL segment present in pg_wal, with garbage contents, however. + * We would read the first page from the local WAL segment, but when + * reading the second page, we would read the bogus, recycled, WAL + * segment. If we didn't catch that case here, we would never recover, + * because ReadRecord() would retry reading the whole record from the + * beginning. * * Of course, this only catches errors in the page header, which is what * happens in the case of a recycled WAL segment. Other kinds of errors or @@ -12887,15 +13131,15 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, * Failure while streaming. Most likely, we got here * because streaming replication was terminated, or * promotion was triggered. But we also get here if we - * find an invalid record in the WAL streamed from the primary, - * in which case something is seriously wrong. There's - * little chance that the problem will just go away, but - * PANIC is not good for availability either, especially - * in hot standby mode. So, we treat that the same as - * disconnection, and retry from archive/pg_wal again. The - * WAL in the archive should be identical to what was - * streamed, so it's unlikely that it helps, but one can - * hope... + * find an invalid record in the WAL streamed from the + * primary, in which case something is seriously wrong. + * There's little chance that the problem will just go + * away, but PANIC is not good for availability either, + * especially in hot standby mode. So, we treat that the + * same as disconnection, and retry from archive/pg_wal + * again. The WAL in the archive should be identical to + * what was streamed, so it's unlikely that it helps, but + * one can hope... */ /* @@ -12937,13 +13181,10 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, if (!TimestampDifferenceExceeds(last_fail_time, now, wal_retrieve_retry_interval)) { - long secs, - wait_time; - int usecs; + long wait_time; - TimestampDifference(last_fail_time, now, &secs, &usecs); wait_time = wal_retrieve_retry_interval - - (secs * 1000 + usecs / 1000); + TimestampDifferenceMilliseconds(last_fail_time, now); (void) WaitLatch(&XLogCtl->recoveryWakeupLatch, WL_LATCH_SET | WL_TIMEOUT | @@ -12952,6 +13193,9 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL); ResetLatch(&XLogCtl->recoveryWakeupLatch); now = GetCurrentTimestamp(); + + /* Handle interrupt signals of startup process */ + HandleStartupProcInterrupts(); } last_fail_time = now; currentSource = XLOG_FROM_ARCHIVE; @@ -13083,8 +13327,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, if (curFileTLI > 0 && tli < curFileTLI) elog(ERROR, "according to history file, WAL location %X/%X belongs to timeline %u, but previous recovered WAL file came from timeline %u", - (uint32) (tliRecPtr >> 32), - (uint32) tliRecPtr, + LSN_FORMAT_ARGS(tliRecPtr), tli, curFileTLI); } curFileTLI = tli; @@ -13154,11 +13397,19 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, * pg_wal by now. Use XLOG_FROM_STREAM so that source * info is set correctly and XLogReceiptTime isn't * changed. + * + * NB: We must set readTimeLineHistory based on + * recoveryTargetTLI, not receiveTLI. Normally they'll + * be the same, but if recovery_target_timeline is + * 'latest' and archiving is configured, then it's + * possible that we managed to retrieve one or more + * new timeline history files from the archive, + * updating recoveryTargetTLI. */ if (readFile < 0) { if (!expectedTLEs) - expectedTLEs = readTimeLineHistory(receiveTLI); + expectedTLEs = readTimeLineHistory(recoveryTargetTLI); readFile = XLogFileRead(readSegNo, PANIC, receiveTLI, XLOG_FROM_STREAM, false); @@ -13228,6 +13479,14 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, elog(ERROR, "unexpected WAL source %d", currentSource); } + /* + * Check for recovery pause here so that we can confirm more quickly + * that a requested pause has actually taken effect. + */ + if (((volatile XLogCtlData *) XLogCtl)->recoveryPauseState != + RECOVERY_NOT_PAUSED) + recoveryPausesHere(false); + /* * This possibly-long loop needs to handle interrupts of startup * process. @@ -13248,7 +13507,7 @@ StartupRequestWalReceiverRestart(void) if (currentSource == XLOG_FROM_STREAM && WalRcvRunning()) { ereport(LOG, - (errmsg("wal receiver process shutdown requested"))); + (errmsg("WAL receiver process shutdown requested"))); pendingWalRcvRestart = true; } @@ -13318,6 +13577,14 @@ SetPromoteIsTriggered(void) XLogCtl->SharedPromoteIsTriggered = true; SpinLockRelease(&XLogCtl->info_lck); + /* + * Mark the recovery pause state as 'not paused' because the paused state + * ends and promotion continues if a promotion is triggered while recovery + * is paused. Otherwise pg_get_wal_replay_pause_state() can mistakenly + * return 'paused' while a promotion is ongoing. + */ + SetRecoveryPause(false); + LocalPromoteIsTriggered = true; } diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c index 03911190335c..8ecdd69756fb 100644 --- a/src/backend/access/transam/xlogarchive.c +++ b/src/backend/access/transam/xlogarchive.c @@ -4,7 +4,7 @@ * Functions for archiving WAL files and restoring from the archive. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlogarchive.c @@ -25,11 +25,11 @@ #include "common/archive.h" #include "miscadmin.h" #include "postmaster/startup.h" +#include "postmaster/pgarch.h" #include "replication/walsender.h" #include "storage/fd.h" #include "storage/ipc.h" #include "storage/lwlock.h" -#include "storage/pmsignal.h" /* * GPDB specific imports: @@ -208,10 +208,10 @@ RestoreArchivedFile(char *path, const char *xlogfname, else elevel = FATAL; ereport(elevel, - (errmsg("archive file \"%s\" has wrong size: %lu instead of %lu", + (errmsg("archive file \"%s\" has wrong size: %lld instead of %lld", xlogfname, - (unsigned long) stat_buf.st_size, - (unsigned long) expectedSize))); + (long long int) stat_buf.st_size, + (long long int) expectedSize))); return false; } else @@ -226,11 +226,12 @@ RestoreArchivedFile(char *path, const char *xlogfname, else { /* stat failed */ - if (errno != ENOENT) - ereport(FATAL, - (errcode_for_file_access(), - errmsg("could not stat file \"%s\": %m", - xlogpath))); + int elevel = (errno == ENOENT) ? LOG : FATAL; + + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", xlogpath), + errdetail("restore_command returned a zero exit status, but stat() failed."))); } } @@ -505,7 +506,7 @@ XLogArchiveNotify(const char *xlog) /* Notify archiver that it's got something to do */ if (IsUnderPostmaster) - SendPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER); + PgArchWakeup(); } /* diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c index 85d0c8e407ae..cde6603fab16 100644 --- a/src/backend/access/transam/xlogfuncs.c +++ b/src/backend/access/transam/xlogfuncs.c @@ -7,7 +7,7 @@ * This file contains WAL control and information functions. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlogfuncs.c @@ -83,7 +83,7 @@ pg_start_backup(PG_FUNCTION_ARGS) if (exclusive) { startpoint = do_pg_start_backup(backupidstr, fast, NULL, NULL, - NULL, NULL, true); + NULL, NULL); } else { @@ -101,7 +101,7 @@ pg_start_backup(PG_FUNCTION_ARGS) register_persistent_abort_backup_handler(); startpoint = do_pg_start_backup(backupidstr, fast, NULL, label_file, - NULL, tblspc_map_file, true); + NULL, tblspc_map_file); } PG_RETURN_LSN(startpoint); @@ -531,7 +531,7 @@ pg_walfile_name(PG_FUNCTION_ARGS) } /* - * pg_wal_replay_pause - pause recovery now + * pg_wal_replay_pause - Request to pause recovery * * Permission checking for this function is managed through the normal * GRANT system. @@ -554,6 +554,9 @@ pg_wal_replay_pause(PG_FUNCTION_ARGS) SetRecoveryPause(true); + /* wake up the recovery process so that it can process the pause request */ + WakeupRecovery(); + PG_RETURN_VOID(); } @@ -596,7 +599,45 @@ pg_is_wal_replay_paused(PG_FUNCTION_ARGS) errmsg("recovery is not in progress"), errhint("Recovery control functions can only be executed during recovery."))); - PG_RETURN_BOOL(RecoveryIsPaused()); + PG_RETURN_BOOL(GetRecoveryPauseState() != RECOVERY_NOT_PAUSED); +} + +/* + * pg_get_wal_replay_pause_state - Returns the recovery pause state. + * + * Returned values: + * + * 'not paused' - if pause is not requested + * 'pause requested' - if pause is requested but recovery is not yet paused + * 'paused' - if recovery is paused + */ +Datum +pg_get_wal_replay_pause_state(PG_FUNCTION_ARGS) +{ + char *statestr = NULL; + + if (!RecoveryInProgress()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("recovery is not in progress"), + errhint("Recovery control functions can only be executed during recovery."))); + + /* get the recovery pause state */ + switch (GetRecoveryPauseState()) + { + case RECOVERY_NOT_PAUSED: + statestr = "not paused"; + break; + case RECOVERY_PAUSE_REQUESTED: + statestr = "pause requested"; + break; + case RECOVERY_PAUSED: + statestr = "paused"; + break; + } + + Assert(statestr != NULL); + PG_RETURN_TEXT_P(cstring_to_text(statestr)); } /* @@ -795,6 +836,9 @@ pg_promote(PG_FUNCTION_ARGS) } ereport(WARNING, - (errmsg("server did not promote within %d seconds", wait_seconds))); + (errmsg_plural("server did not promote within %d second", + "server did not promote within %d seconds", + wait_seconds, + wait_seconds))); PG_RETURN_BOOL(false); } diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index a01b6d4c564e..58daef513990 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -9,7 +9,7 @@ * of XLogRecData structs by a call to XLogRecordAssemble(). See * access/transam/README for details. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xloginsert.c @@ -1059,6 +1059,63 @@ log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, return recptr; } +/* + * Like log_newpage(), but allows logging multiple pages in one operation. + * It is more efficient than calling log_newpage() for each page separately, + * because we can write multiple pages in a single WAL record. + */ +void +log_newpages(RelFileNode *rnode, ForkNumber forkNum, int num_pages, + BlockNumber *blknos, Page *pages, bool page_std) +{ + int flags; + XLogRecPtr recptr; + int i; + int j; + + flags = REGBUF_FORCE_IMAGE; + if (page_std) + flags |= REGBUF_STANDARD; + + /* + * Iterate over all the pages. They are collected into batches of + * XLR_MAX_BLOCK_ID pages, and a single WAL-record is written for each + * batch. + */ + XLogEnsureRecordSpace(XLR_MAX_BLOCK_ID - 1, 0); + + i = 0; + while (i < num_pages) + { + int batch_start = i; + int nbatch; + + XLogBeginInsert(); + + nbatch = 0; + while (nbatch < XLR_MAX_BLOCK_ID && i < num_pages) + { + XLogRegisterBlock(nbatch, rnode, forkNum, blknos[i], pages[i], flags); + i++; + nbatch++; + } + + recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI); + + for (j = batch_start; j < i; j++) + { + /* + * The page may be uninitialized. If so, we can't set the LSN + * because that would corrupt the page. + */ + if (!PageIsNew(pages[j])) + { + PageSetLSN(pages[j], recptr); + } + } + } +} + /* * Write a WAL record containing a full image of a page. * diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 97fe3595df1c..2b3d2e20d4b6 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -3,7 +3,7 @@ * xlogreader.c * Generic XLog reading facility * - * Portions Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/access/transam/xlogreader.c @@ -360,7 +360,7 @@ XLogReadRecord(XLogReaderState *state, char **errormsg) else if (targetRecOff < pageHeaderSize) { report_invalid_record(state, "invalid record offset at %X/%X", - (uint32) (RecPtr >> 32), (uint32) RecPtr); + LSN_FORMAT_ARGS(RecPtr)); goto err; } @@ -368,7 +368,7 @@ XLogReadRecord(XLogReaderState *state, char **errormsg) targetRecOff == pageHeaderSize) { report_invalid_record(state, "contrecord is requested by %X/%X", - (uint32) (RecPtr >> 32), (uint32) RecPtr); + LSN_FORMAT_ARGS(RecPtr)); goto err; } @@ -409,7 +409,7 @@ XLogReadRecord(XLogReaderState *state, char **errormsg) { report_invalid_record(state, "invalid record length at %X/%X: wanted %u, got %u", - (uint32) (RecPtr >> 32), (uint32) RecPtr, + LSN_FORMAT_ARGS(RecPtr), (uint32) SizeOfXLogRecord, total_len); goto err; } @@ -435,8 +435,7 @@ XLogReadRecord(XLogReaderState *state, char **errormsg) { /* We treat this as a "bogus data" condition */ report_invalid_record(state, "record length %u at %X/%X too long", - total_len, - (uint32) (RecPtr >> 32), (uint32) RecPtr); + total_len, LSN_FORMAT_ARGS(RecPtr)); goto err; } @@ -484,7 +483,7 @@ XLogReadRecord(XLogReaderState *state, char **errormsg) { report_invalid_record(state, "there is no contrecord flag at %X/%X", - (uint32) (RecPtr >> 32), (uint32) RecPtr); + LSN_FORMAT_ARGS(RecPtr)); goto err; } @@ -496,9 +495,10 @@ XLogReadRecord(XLogReaderState *state, char **errormsg) total_len != (pageHeader->xlp_rem_len + gotlen)) { report_invalid_record(state, - "invalid contrecord length %u at %X/%X", + "invalid contrecord length %u (expected %lld) at %X/%X", pageHeader->xlp_rem_len, - (uint32) (RecPtr >> 32), (uint32) RecPtr); + ((long long) total_len) - gotlen, + LSN_FORMAT_ARGS(RecPtr)); goto err; } @@ -739,7 +739,7 @@ ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, { report_invalid_record(state, "invalid record length at %X/%X: wanted %u, got %u", - (uint32) (RecPtr >> 32), (uint32) RecPtr, + LSN_FORMAT_ARGS(RecPtr), (uint32) SizeOfXLogRecord, record->xl_tot_len); return false; } @@ -747,8 +747,7 @@ ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, { report_invalid_record(state, "invalid resource manager ID %u at %X/%X", - record->xl_rmid, (uint32) (RecPtr >> 32), - (uint32) RecPtr); + record->xl_rmid, LSN_FORMAT_ARGS(RecPtr)); return false; } if (randAccess) @@ -761,9 +760,8 @@ ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, { report_invalid_record(state, "record with incorrect prev-link %X/%X at %X/%X", - (uint32) (record->xl_prev >> 32), - (uint32) record->xl_prev, - (uint32) (RecPtr >> 32), (uint32) RecPtr); + LSN_FORMAT_ARGS(record->xl_prev), + LSN_FORMAT_ARGS(RecPtr)); return false; } } @@ -778,9 +776,8 @@ ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, { report_invalid_record(state, "record with incorrect prev-link %X/%X at %X/%X", - (uint32) (record->xl_prev >> 32), - (uint32) record->xl_prev, - (uint32) (RecPtr >> 32), (uint32) RecPtr); + LSN_FORMAT_ARGS(record->xl_prev), + LSN_FORMAT_ARGS(RecPtr)); return false; } } @@ -815,7 +812,7 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr) { report_invalid_record(state, "incorrect resource manager data checksum in record at %X/%X", - (uint32) (recptr >> 32), (uint32) recptr); + LSN_FORMAT_ARGS(recptr)); return false; } @@ -926,7 +923,7 @@ XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, report_invalid_record(state, "unexpected pageaddr %X/%X in log segment %s, offset %u", - (uint32) (hdr->xlp_pageaddr >> 32), (uint32) hdr->xlp_pageaddr, + LSN_FORMAT_ARGS(hdr->xlp_pageaddr), fname, offset); return false; @@ -1303,8 +1300,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) report_invalid_record(state, "out-of-order block_id %u at %X/%X", block_id, - (uint32) (state->ReadRecPtr >> 32), - (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } state->max_block_id = block_id; @@ -1325,7 +1321,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) { report_invalid_record(state, "BKPBLOCK_HAS_DATA set, but no data included at %X/%X", - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } if (!blk->has_data && blk->data_len != 0) @@ -1333,7 +1329,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) report_invalid_record(state, "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X", (unsigned int) blk->data_len, - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } datatotal += blk->data_len; @@ -1371,7 +1367,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) (unsigned int) blk->hole_offset, (unsigned int) blk->hole_length, (unsigned int) blk->bimg_len, - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } @@ -1386,7 +1382,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X", (unsigned int) blk->hole_offset, (unsigned int) blk->hole_length, - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } @@ -1400,7 +1396,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) report_invalid_record(state, "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X", (unsigned int) blk->bimg_len, - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } @@ -1415,7 +1411,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) report_invalid_record(state, "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X", (unsigned int) blk->data_len, - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } } @@ -1430,7 +1426,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) { report_invalid_record(state, "BKPBLOCK_SAME_REL set but no previous rel at %X/%X", - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } @@ -1442,9 +1438,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) { report_invalid_record(state, "invalid block_id %u at %X/%X", - block_id, - (uint32) (state->ReadRecPtr >> 32), - (uint32) state->ReadRecPtr); + block_id, LSN_FORMAT_ARGS(state->ReadRecPtr)); goto err; } } @@ -1531,7 +1525,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg) shortdata_err: report_invalid_record(state, "record with invalid length at %X/%X", - (uint32) (state->ReadRecPtr >> 32), (uint32) state->ReadRecPtr); + LSN_FORMAT_ARGS(state->ReadRecPtr)); err: *errormsg = state->errormsg_buf; @@ -1596,7 +1590,7 @@ XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len) /* * Restore a full-page image from a backup block attached to an XLOG record. * - * Returns the buffer number containing the page. + * Returns true if a full-page image is restored. */ bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) @@ -1621,11 +1615,9 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) BLCKSZ - bkpb->hole_length, errormessage)) { - report_invalid_record(record, "invalid compressed image at %X/%X, block %d (%s)", - (uint32) (record->ReadRecPtr >> 32), - (uint32) record->ReadRecPtr, - block_id, - errormessage); + report_invalid_record(record, "invalid compressed image at %X/%X, block %d", + LSN_FORMAT_ARGS(record->ReadRecPtr), + block_id); return false; } ptr = tmp.data; diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index 48f758ce26ba..3b7529f2f53b 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -10,7 +10,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlogutils.c @@ -107,7 +107,7 @@ log_invalid_page(RelFileNode node, ForkNumber forkno, BlockNumber blkno, * tracing of the cause (note the elog context mechanism will tell us * something about the XLOG record that generated the reference). */ - if (log_min_messages <= DEBUG1 || client_min_messages <= DEBUG1) + if (message_level_is_interesting(DEBUG1)) report_invalid_page(DEBUG1, node, forkno, blkno, present); if (invalid_page_tab == NULL) @@ -115,7 +115,6 @@ log_invalid_page(RelFileNode node, ForkNumber forkno, BlockNumber blkno, /* create hash table when first needed */ HASHCTL ctl; - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(xl_invalid_page_key); ctl.entrysize = sizeof(xl_invalid_page); @@ -161,7 +160,7 @@ forget_invalid_pages(RelFileNode node, ForkNumber forkno, BlockNumber minblkno) hentry->key.forkno == forkno && hentry->key.blkno >= minblkno) { - if (log_min_messages <= DEBUG2 || client_min_messages <= DEBUG2) + if (message_level_is_interesting(DEBUG2)) { char *path = relpathperm(hentry->key.node, forkno); @@ -194,7 +193,7 @@ forget_invalid_pages_db(Oid dbid) { if (hentry->key.node.dbNode == dbid) { - if (log_min_messages <= DEBUG2 || client_min_messages <= DEBUG2) + if (message_level_is_interesting(DEBUG2)) { char *path = relpathperm(hentry->key.node, hentry->key.forkno); @@ -436,8 +435,7 @@ XLogReadBufferForRedoExtended(XLogReaderState *record, * NB: A redo function should normally not call this directly. To get a page * to modify, use XLogReadBufferForRedoExtended instead. It is important that * all pages modified by a WAL record are registered in the WAL records, or - * they will be invisible to tools that that need to know which pages are - * modified. + * they will be invisible to tools that need to know which pages are modified. */ Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, @@ -797,8 +795,7 @@ XLogReadDetermineTimeline(XLogReaderState *state, XLogRecPtr wantPage, uint32 wa elog(DEBUG3, "switched to timeline %u valid until %X/%X", state->currTLI, - (uint32) (state->currTLIValidUntil >> 32), - (uint32) (state->currTLIValidUntil)); + LSN_FORMAT_ARGS(state->currTLIValidUntil)); } } diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 2802c1629c28..939ec61d82c3 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -6,7 +6,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,16 +20,10 @@ #include -#include "access/attnum.h" -#include "access/htup.h" -#include "access/itup.h" -#include "access/tupdesc.h" #include "bootstrap/bootstrap.h" -#include "catalog/catalog.h" #include "catalog/heap.h" #include "catalog/namespace.h" #include "catalog/pg_am.h" -#include "catalog/pg_attribute.h" #include "catalog/pg_authid.h" #include "catalog/pg_auth_members.h" #include "catalog/pg_class.h" @@ -40,20 +34,7 @@ #include "commands/defrem.h" #include "miscadmin.h" #include "nodes/makefuncs.h" -#include "nodes/nodes.h" -#include "nodes/parsenodes.h" -#include "nodes/pg_list.h" -#include "nodes/primnodes.h" -#include "rewrite/prs2lock.h" -#include "storage/block.h" -#include "storage/fd.h" -#include "storage/ipc.h" -#include "storage/itemptr.h" -#include "storage/off.h" -#include "storage/smgr.h" -#include "tcop/dest.h" #include "utils/memutils.h" -#include "utils/rel.h" /* diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l index 94fd2c902614..ae307cf21162 100644 --- a/src/backend/bootstrap/bootscanner.l +++ b/src/backend/bootstrap/bootscanner.l @@ -4,7 +4,7 @@ * bootscanner.l * a lexical scanner for the bootstrap parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,25 +15,8 @@ */ #include "postgres.h" -#include "access/attnum.h" -#include "access/htup.h" -#include "access/itup.h" -#include "access/tupdesc.h" #include "bootstrap/bootstrap.h" -#include "catalog/pg_am.h" -#include "catalog/pg_attribute.h" -#include "catalog/pg_class.h" -#include "nodes/nodes.h" -#include "nodes/parsenodes.h" -#include "nodes/pg_list.h" -#include "nodes/primnodes.h" -#include "parser/scansup.h" -#include "rewrite/prs2lock.h" -#include "storage/block.h" -#include "storage/fd.h" -#include "storage/itemptr.h" -#include "storage/off.h" -#include "utils/rel.h" +#include "utils/guc.h" #define unify_version(a,b,c) ((a<<16)+(b<<8)+c) @@ -87,7 +70,7 @@ static int yyline = 1; /* line number for error reporting */ id [-A-Za-z0-9_]+ -sid \"([^\"])*\" +sid \'([^']|\'\')*\' /* * Keyword tokens return the keyword text (as a constant string) in yylval.kw, @@ -126,7 +109,7 @@ _null_ { return NULLVAL; } [\n] { yyline++; } [\r\t ] ; -^\#[^\n]* ; /* drop everything after "#" for comments */ +^\#[^\n]* ; /* drop everything after "#" for comments */ declare { yylval.kw = "declare"; return XDECLARE; } build { yylval.kw = "build"; return XBUILD; } @@ -141,14 +124,12 @@ NOT { yylval.kw = "NOT"; return XNOT; } NULL { yylval.kw = "NULL"; return XNULL; } {id} { - yylval.str = scanstr(yytext); + yylval.str = pstrdup(yytext); return ID; } {sid} { - /* leading and trailing quotes are not passed to scanstr */ - yytext[strlen(yytext) - 1] = '\0'; - yylval.str = scanstr(yytext+1); - yytext[strlen(yytext)] = '"'; /* restore yytext */ + /* strip quotes and escapes */ + yylval.str = DeescapeQuotedString(yytext); return ID; } diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 3f85f5ed6508..499a5fb705b8 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -4,7 +4,7 @@ * routines to support running postgres in 'bootstrap' mode * bootstrap mode is used to create the initial template database * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -21,6 +21,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/tableam.h" +#include "access/toast_compression.h" #include "access/xact.h" #include "access/xlog_internal.h" #include "bootstrap/bootstrap.h" @@ -55,14 +56,12 @@ uint32 bootstrap_data_checksum_version = 0; /* No checksum */ -#define ALLOC(t, c) \ - ((t *) MemoryContextAllocZero(TopMemoryContext, (unsigned)(c) * sizeof(t))) - static void CheckerModeMain(void); static void BootstrapModeMain(void); static void bootstrap_signals(void); static void ShutdownAuxiliaryProcess(int code, Datum arg); static Form_pg_attribute AllocateAttribute(void); +static void populate_typ_list(void); static Oid gettype(char *type); static void cleanup(void); @@ -137,7 +136,7 @@ static const struct typinfo TypInfo[] = { F_XIDIN, F_XIDOUT}, {"cid", CIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid, F_CIDIN, F_CIDOUT}, - {"pg_node_tree", PGNODETREEOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID, + {"pg_node_tree", PG_NODE_TREEOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID, F_PG_NODE_TREE_IN, F_PG_NODE_TREE_OUT}, {"int2vector", INT2VECTOROID, INT2OID, -1, false, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid, F_INT2VECTORIN, F_INT2VECTOROUT}, @@ -163,7 +162,7 @@ struct typmap FormData_pg_type am_typ; }; -static struct typmap **Typ = NULL; +static List *Typ = NIL; /* List of struct typmap* */ static struct typmap *Ap = NULL; static Datum values[MAXATTR]; /* current row's attribute values */ @@ -321,6 +320,9 @@ AuxiliaryProcessMain(int argc, char *argv[]) case StartupProcess: MyBackendType = B_STARTUP; break; + case ArchiverProcess: + MyBackendType = B_ARCHIVER; + break; case BgWriterProcess: MyBackendType = B_BG_WRITER; break; @@ -413,8 +415,11 @@ AuxiliaryProcessMain(int argc, char *argv[]) */ CreateAuxProcessResourceOwner(); - /* Initialize backend status information */ + /* Initialize statistics reporting */ pgstat_initialize(); + + /* Initialize backend status information */ + pgstat_beinit(); pgstat_bestart(); /* register a before-shutdown callback for LWLock cleanup */ @@ -447,30 +452,29 @@ AuxiliaryProcessMain(int argc, char *argv[]) proc_exit(1); /* should never return */ case StartupProcess: - /* don't set signals, startup process has its own agenda */ StartupProcessMain(); - proc_exit(1); /* should never return */ + proc_exit(1); + + case ArchiverProcess: + PgArchiverMain(); + proc_exit(1); case BgWriterProcess: - /* don't set signals, bgwriter has its own agenda */ BackgroundWriterMain(); - proc_exit(1); /* should never return */ + proc_exit(1); case CheckpointerProcess: - /* don't set signals, checkpointer has its own agenda */ CheckpointerMain(); - proc_exit(1); /* should never return */ + proc_exit(1); case WalWriterProcess: - /* don't set signals, walwriter has its own agenda */ InitXLOGAccess(); WalWriterMain(); - proc_exit(1); /* should never return */ + proc_exit(1); case WalReceiverProcess: - /* don't set signals, walreceiver has its own agenda */ WalReceiverMain(); - proc_exit(1); /* should never return */ + proc_exit(1); default: elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType); @@ -591,46 +595,24 @@ ShutdownAuxiliaryProcess(int code, Datum arg) /* ---------------- * boot_openrel + * + * Execute BKI OPEN command. * ---------------- */ void boot_openrel(char *relname) { int i; - struct typmap **app; - Relation rel; - TableScanDesc scan; - HeapTuple tup; if (strlen(relname) >= NAMEDATALEN) relname[NAMEDATALEN - 1] = '\0'; - if (Typ == NULL) - { - /* We can now load the pg_type data */ - rel = table_open(TypeRelationId, NoLock); - scan = table_beginscan_catalog(rel, 0, NULL); - i = 0; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) - ++i; - table_endscan(scan); - app = Typ = ALLOC(struct typmap *, i + 1); - while (i-- > 0) - *app++ = ALLOC(struct typmap, 1); - *app = NULL; - scan = table_beginscan_catalog(rel, 0, NULL); - app = Typ; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - (*app)->am_oid = ((Form_pg_type) GETSTRUCT(tup))->oid; - memcpy((char *) &(*app)->am_typ, - (char *) GETSTRUCT(tup), - sizeof((*app)->am_typ)); - app++; - } - table_endscan(scan); - table_close(rel, NoLock); - } + /* + * pg_type must be filled before any OPEN command is executed, hence we + * can now populate Typ if we haven't yet. + */ + if (Typ == NIL) + populate_typ_list(); if (boot_reldesc != NULL) closerel(NULL); @@ -720,13 +702,14 @@ DefineAttr(char *name, char *type, int attnum, int nullness) typeoid = gettype(type); - if (Typ != NULL) + if (Typ != NIL) { attrtypes[attnum]->atttypid = Ap->am_oid; attrtypes[attnum]->attlen = Ap->am_typ.typlen; attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; - attrtypes[attnum]->attstorage = Ap->am_typ.typstorage; attrtypes[attnum]->attalign = Ap->am_typ.typalign; + attrtypes[attnum]->attstorage = Ap->am_typ.typstorage; + attrtypes[attnum]->attcompression = InvalidCompressionMethod; attrtypes[attnum]->attcollation = Ap->am_typ.typcollation; /* if an array type, assume 1-dimensional attribute */ if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0) @@ -739,8 +722,9 @@ DefineAttr(char *name, char *type, int attnum, int nullness) attrtypes[attnum]->atttypid = TypInfo[typeoid].oid; attrtypes[attnum]->attlen = TypInfo[typeoid].len; attrtypes[attnum]->attbyval = TypInfo[typeoid].byval; - attrtypes[attnum]->attstorage = TypInfo[typeoid].storage; attrtypes[attnum]->attalign = TypInfo[typeoid].align; + attrtypes[attnum]->attstorage = TypInfo[typeoid].storage; + attrtypes[attnum]->attcompression = InvalidCompressionMethod; attrtypes[attnum]->attcollation = TypInfo[typeoid].collation; /* if an array type, assume 1-dimensional attribute */ if (TypInfo[typeoid].elem != InvalidOid && @@ -897,66 +881,106 @@ cleanup(void) closerel(NULL); } +/* ---------------- + * populate_typ_list + * + * Load the Typ list by reading pg_type. + * ---------------- + */ +static void +populate_typ_list(void) +{ + Relation rel; + TableScanDesc scan; + HeapTuple tup; + MemoryContext old; + + Assert(Typ == NIL); + + rel = table_open(TypeRelationId, NoLock); + scan = table_beginscan_catalog(rel, 0, NULL); + old = MemoryContextSwitchTo(TopMemoryContext); + while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + Form_pg_type typForm = (Form_pg_type) GETSTRUCT(tup); + struct typmap *newtyp; + + newtyp = (struct typmap *) palloc(sizeof(struct typmap)); + Typ = lappend(Typ, newtyp); + + newtyp->am_oid = typForm->oid; + memcpy(&newtyp->am_typ, typForm, sizeof(newtyp->am_typ)); + } + MemoryContextSwitchTo(old); + table_endscan(scan); + table_close(rel, NoLock); +} + /* ---------------- * gettype * * NB: this is really ugly; it will return an integer index into TypInfo[], * and not an OID at all, until the first reference to a type not known in - * TypInfo[]. At that point it will read and cache pg_type in the Typ array, + * TypInfo[]. At that point it will read and cache pg_type in Typ, * and subsequently return a real OID (and set the global pointer Ap to * point at the found row in Typ). So caller must check whether Typ is - * still NULL to determine what the return value is! + * still NIL to determine what the return value is! * ---------------- */ static Oid gettype(char *type) { - int i; - Relation rel; - TableScanDesc scan; - HeapTuple tup; - struct typmap **app; - - if (Typ != NULL) + if (Typ != NIL) { - for (app = Typ; *app != NULL; app++) + ListCell *lc; + + foreach(lc, Typ) { - if (strncmp(NameStr((*app)->am_typ.typname), type, NAMEDATALEN) == 0) + struct typmap *app = lfirst(lc); + + if (strncmp(NameStr(app->am_typ.typname), type, NAMEDATALEN) == 0) { - Ap = *app; - return (*app)->am_oid; + Ap = app; + return app->am_oid; + } + } + + /* + * The type wasn't known; reload the pg_type contents and check again + * to handle composite types, added since last populating the list. + */ + + list_free_deep(Typ); + Typ = NIL; + populate_typ_list(); + + /* + * Calling gettype would result in infinite recursion for types + * missing in pg_type, so just repeat the lookup. + */ + foreach(lc, Typ) + { + struct typmap *app = lfirst(lc); + + if (strncmp(NameStr(app->am_typ.typname), type, NAMEDATALEN) == 0) + { + Ap = app; + return app->am_oid; } } } else { + int i; + for (i = 0; i < n_types; i++) { if (strncmp(type, TypInfo[i].name, NAMEDATALEN) == 0) return i; } + /* Not in TypInfo, so we'd better be able to read pg_type now */ elog(DEBUG4, "external type: %s", type); - rel = table_open(TypeRelationId, NoLock); - scan = table_beginscan_catalog(rel, 0, NULL); - i = 0; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) - ++i; - table_endscan(scan); - app = Typ = ALLOC(struct typmap *, i + 1); - while (i-- > 0) - *app++ = ALLOC(struct typmap, 1); - *app = NULL; - scan = table_beginscan_catalog(rel, 0, NULL); - app = Typ; - while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - (*app)->am_oid = ((Form_pg_type) GETSTRUCT(tup))->oid; - memmove((char *) &(*app++)->am_typ, - (char *) GETSTRUCT(tup), - sizeof((*app)->am_typ)); - } - table_endscan(scan); - table_close(rel, NoLock); + populate_typ_list(); return gettype(type); } elog(ERROR, "unrecognized type \"%s\"", type); @@ -984,17 +1008,20 @@ boot_get_type_io_data(Oid typid, Oid *typinput, Oid *typoutput) { - if (Typ != NULL) + if (Typ != NIL) { /* We have the boot-time contents of pg_type, so use it */ - struct typmap **app; - struct typmap *ap; - - app = Typ; - while (*app && (*app)->am_oid != typid) - ++app; - ap = *app; - if (ap == NULL) + struct typmap *ap = NULL; + ListCell *lc; + + foreach(lc, Typ) + { + ap = lfirst(lc); + if (ap->am_oid == typid) + break; + } + + if (!ap || ap->am_oid != typid) elog(ERROR, "type OID %u not found in Typ list", typid); *typlen = ap->am_typ.typlen; diff --git a/src/backend/catalog/.gitignore b/src/backend/catalog/.gitignore index 93ab5ebef91a..2d43e2533c12 100644 --- a/src/backend/catalog/.gitignore +++ b/src/backend/catalog/.gitignore @@ -1,6 +1,8 @@ /postgres.bki /cdb_init.sql /schemapg.h +/system_fk_info.h +/system_constraints.sql /pg_*_d.h /gp_*_d.h /bki-stamp diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm index 77982df2e8fc..da8a2745272d 100644 --- a/src/backend/catalog/Catalog.pm +++ b/src/backend/catalog/Catalog.pm @@ -4,7 +4,7 @@ # Perl module that extracts info from catalog files into Perl # data structures # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/catalog/Catalog.pm @@ -94,14 +94,29 @@ sub ParseHeader push @{ $catalog{toasting} }, { parent_table => $1, toast_oid => $2, toast_index_oid => $3 }; } - elsif (/^DECLARE_(UNIQUE_)?INDEX\(\s*(\w+),\s*(\d+),\s*(.+)\)/) + elsif ( + /^DECLARE_(UNIQUE_)?INDEX(_PKEY)?\(\s*(\w+),\s*(\d+),\s*(.+)\)/) { push @{ $catalog{indexing} }, { is_unique => $1 ? 1 : 0, - index_name => $2, - index_oid => $3, - index_decl => $4 + is_pkey => $2 ? 1 : 0, + index_name => $3, + index_oid => $4, + index_decl => $5 + }; + } + elsif ( + /^DECLARE_(ARRAY_)?FOREIGN_KEY(_OPT)?\(\s*\(([^)]+)\),\s*(\w+),\s*\(([^)]+)\)\)/ + ) + { + push @{ $catalog{foreign_keys} }, + { + is_array => $1 ? 1 : 0, + is_opt => $2 ? 1 : 0, + fk_cols => $3, + pk_table => $4, + pk_cols => $5 }; } elsif (/^CATALOG\((\w+),(\d+),(\w+)\)/) @@ -196,9 +211,22 @@ sub ParseHeader { $column{array_default} = $1; } - elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/) + elsif ($attopt =~ /BKI_LOOKUP(_OPT)?\((\w+)\)/) { - $column{lookup} = $1; + $column{lookup} = $2; + $column{lookup_opt} = $1 ? 1 : 0; + # BKI_LOOKUP implicitly makes an FK reference + push @{ $catalog{foreign_keys} }, + { + is_array => + ($atttype eq 'oidvector' || $atttype eq '_oid') + ? 1 + : 0, + is_opt => $column{lookup_opt}, + fk_cols => $attname, + pk_table => $column{lookup}, + pk_cols => 'oid' + }; } else { diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index 801a0638dc53..8a121c9e6513 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -68,8 +68,8 @@ CATALOG_HEADERS := \ pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \ pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_language.h pg_largeobject_metadata.h pg_largeobject.h pg_aggregate.h \ - pg_statistic_ext.h pg_statistic_ext_data.h \ - pg_statistic.h pg_rewrite.h pg_trigger.h pg_event_trigger.h pg_description.h \ + pg_statistic.h pg_statistic_ext.h pg_statistic_ext_data.h \ + pg_rewrite.h pg_trigger.h pg_event_trigger.h pg_description.h \ pg_cast.h pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \ pg_database.h pg_db_role_setting.h pg_tablespace.h \ pg_authid.h pg_auth_members.h pg_shdepend.h pg_shdescription.h \ @@ -94,7 +94,7 @@ CATALOG_HEADERS := \ pg_sequence.h pg_publication.h pg_publication_rel.h pg_subscription.h \ pg_subscription_rel.h gp_partition_template.h -GENERATED_HEADERS := $(CATALOG_HEADERS:%.h=%_d.h) schemapg.h +GENERATED_HEADERS := $(CATALOG_HEADERS:%.h=%_d.h) schemapg.h system_fk_info.h # In the list of headers used to assemble postgres.bki, indexing.h needs # be last, and toasting.h just before it. This ensures we don't try to @@ -162,6 +162,7 @@ $(top_builddir)/src/include/catalog/header-stamp: bki-stamp .PHONY: install-data install-data: bki-stamp installdirs $(INSTALL_DATA) $(call vpathsearch,postgres.bki) '$(DESTDIR)$(datadir)/postgres.bki' + $(INSTALL_DATA) $(srcdir)/system_functions.sql '$(DESTDIR)$(datadir)/system_functions.sql' $(INSTALL_DATA) $(srcdir)/system_views.sql '$(DESTDIR)$(datadir)/system_views.sql' $(INSTALL_DATA) $(srcdir)/information_schema.sql '$(DESTDIR)$(datadir)/information_schema.sql' $(INSTALL_DATA) $(call vpathsearch,cdb_schema.sql) '$(DESTDIR)$(datadir)/cdb_init.d/cdb_schema.sql' @@ -174,7 +175,7 @@ installdirs: .PHONY: uninstall-data uninstall-data: - rm -f $(addprefix '$(DESTDIR)$(datadir)'/, postgres.bki system_views.sql information_schema.sql cdb_init.d/cdb_schema.sql sql_features.txt) + rm -f $(addprefix '$(DESTDIR)$(datadir)'/, postgres.bki system_functions.sql system_views.sql information_schema.sql cdb_init.d/cdb_schema.sql sql_features.txt) # postgres.bki and the generated headers are in the distribution tarball, # so they are not cleaned here. diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index e46b7d781628..dac2d23f6cc5 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -3,7 +3,7 @@ * aclchk.c * Routines to check access control permissions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -390,6 +390,22 @@ ExecuteGrantStmt(GrantStmt *stmt) const char *errormsg; AclMode all_privileges; + if (stmt->grantor) + { + Oid grantor; + + grantor = get_rolespec_oid(stmt->grantor, false); + + /* + * Currently, this clause is only for SQL compatibility, not very + * interesting otherwise. + */ + if (grantor != GetUserId()) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("grantor must be current user"))); + } + /* * Turn the regular GrantStmt into the InternalGrant form. */ @@ -1492,6 +1508,9 @@ SetDefaultACL(InternalDefaultACL *iacls) ReleaseSysCache(tuple); table_close(rel, RowExclusiveLock); + + /* prevent error when processing duplicate objects */ + CommandCounterIncrement(); } @@ -3292,7 +3311,7 @@ ExecGrant_Type(InternalGrant *istmt) pg_type_tuple = (Form_pg_type) GETSTRUCT(tuple); - if (pg_type_tuple->typelem != 0 && pg_type_tuple->typlen == -1) + if (IsTrueArrayType(pg_type_tuple)) ereport(ERROR, (errcode(ERRCODE_INVALID_GRANT_OPERATION), errmsg("cannot set privileges of array types"), @@ -4041,6 +4060,20 @@ pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, Oid roleid, AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how) +{ + return pg_attribute_aclmask_ext(table_oid, attnum, roleid, + mask, how, NULL); +} + +/* + * Exported routine for examining a user's privileges for a column + * + * Does the bulk of the work for pg_attribute_aclmask(), and allows other + * callers to avoid the missing attribute ERROR when is_missing is non-NULL. + */ +AclMode +pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, + AclMode mask, AclMaskHow how, bool *is_missing) { AclMode result; HeapTuple classTuple; @@ -4059,18 +4092,38 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, ObjectIdGetDatum(table_oid), Int16GetDatum(attnum)); if (!HeapTupleIsValid(attTuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("attribute %d of relation with OID %u does not exist", - attnum, table_oid))); + { + if (is_missing != NULL) + { + /* return "no privileges" instead of throwing an error */ + *is_missing = true; + return 0; + } + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("attribute %d of relation with OID %u does not exist", + attnum, table_oid))); + } + attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple); - /* Throw error on dropped columns, too */ + /* Check dropped columns, too */ if (attributeForm->attisdropped) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("attribute %d of relation with OID %u does not exist", - attnum, table_oid))); + { + if (is_missing != NULL) + { + /* return "no privileges" instead of throwing an error */ + *is_missing = true; + ReleaseSysCache(attTuple); + return 0; + } + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("attribute %d of relation with OID %u does not exist", + attnum, table_oid))); + } aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl, &isNull); @@ -4126,6 +4179,19 @@ pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how) +{ + return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL); +} + +/* + * Exported routine for examining a user's privileges for a table + * + * Does the bulk of the work for pg_class_aclmask(), and allows other + * callers to avoid the missing relation ERROR when is_missing is non-NULL. + */ +AclMode +pg_class_aclmask_ext(Oid table_oid, Oid roleid, AclMode mask, + AclMaskHow how, bool *is_missing) { AclMode result; HeapTuple tuple; @@ -4140,10 +4206,20 @@ pg_class_aclmask(Oid table_oid, Oid roleid, */ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid)); if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("relation with OID %u does not exist", - table_oid))); + { + if (is_missing != NULL) + { + /* return "no privileges" instead of throwing an error */ + *is_missing = true; + return 0; + } + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("relation with OID %u does not exist", + table_oid))); + } + classForm = (Form_pg_class) GETSTRUCT(tuple); /* @@ -4204,6 +4280,27 @@ pg_class_aclmask(Oid table_oid, Oid roleid, ReleaseSysCache(tuple); + /* + * Check if ACL_SELECT is being checked and, if so, and not set already as + * part of the result, then check if the user is a member of the + * pg_read_all_data role, which allows read access to all relations. + */ + if (mask & ACL_SELECT && !(result & ACL_SELECT) && + has_privs_of_role(roleid, ROLE_PG_READ_ALL_DATA)) + result |= ACL_SELECT; + + /* + * Check if ACL_INSERT, ACL_UPDATE, or ACL_DELETE is being checked and, if + * so, and not set already as part of the result, then check if the user + * is a member of the pg_write_all_data role, which allows + * INSERT/UPDATE/DELETE access to all relations (except system catalogs, + * which requires superuser, see above). + */ + if (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE) && + !(result & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) && + has_privs_of_role(roleid, ROLE_PG_WRITE_ALL_DATA)) + result |= (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)); + return result; } @@ -4530,6 +4627,16 @@ pg_namespace_aclmask(Oid nsp_oid, Oid roleid, ReleaseSysCache(tuple); + /* + * Check if ACL_USAGE is being checked and, if so, and not set already as + * part of the result, then check if the user is a member of the + * pg_read_all_data or pg_write_all_data roles, which allow usage access + * to all schemas. + */ + if (mask & ACL_USAGE && !(result & ACL_USAGE) && + (has_privs_of_role(roleid, ROLE_PG_READ_ALL_DATA) || + has_privs_of_role(roleid, ROLE_PG_WRITE_ALL_DATA))) + result |= ACL_USAGE; return result; } @@ -4747,7 +4854,7 @@ pg_type_aclmask(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how) * "True" array types don't manage permissions of their own; consult the * element type instead. */ - if (OidIsValid(typeForm->typelem) && typeForm->typlen == -1) + if (IsTrueArrayType(typeForm)) { Oid elttype_oid = typeForm->typelem; @@ -4882,7 +4989,22 @@ AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode) { - if (pg_attribute_aclmask(table_oid, attnum, roleid, mode, ACLMASK_ANY) != 0) + return pg_attribute_aclcheck_ext(table_oid, attnum, roleid, mode, NULL); +} + + +/* + * Exported routine for checking a user's access privileges to a column + * + * Does the bulk of the work for pg_attribute_aclcheck(), and allows other + * callers to avoid the missing attribute ERROR when is_missing is non-NULL. + */ +AclResult +pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, + Oid roleid, AclMode mode, bool *is_missing) +{ + if (pg_attribute_aclmask_ext(table_oid, attnum, roleid, mode, + ACLMASK_ANY, is_missing) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; @@ -4995,7 +5117,21 @@ pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode) { - if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0) + return pg_class_aclcheck_ext(table_oid, roleid, mode, NULL); +} + +/* + * Exported routine for checking a user's access privileges to a table + * + * Does the bulk of the work for pg_class_aclcheck(), and allows other + * callers to avoid the missing relation ERROR when is_missing is non-NULL. + */ +AclResult +pg_class_aclcheck_ext(Oid table_oid, Oid roleid, + AclMode mode, bool *is_missing) +{ + if (pg_class_aclmask_ext(table_oid, roleid, mode, + ACLMASK_ANY, is_missing) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 8a03dc23630a..605e7b63d624 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -5,7 +5,7 @@ * bits of hard-wired knowledge * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -130,6 +130,13 @@ aorelpathbackend(RelFileNode node, BackendId backend, int32 segno) return fullpath; } +/* + * Parameters to determine when to emit a log message in + * GetNewOidWithIndex() + */ +#define GETNEWOID_LOG_THRESHOLD 1000000 +#define GETNEWOID_LOG_MAX_INTERVAL 128000000 + /* * IsSystemRelation * True iff the relation is either a system catalog or a toast table. @@ -399,6 +406,7 @@ IsSharedRelation(Oid relationId) return true; /* These are their indexes (see indexing.h) */ + /* These are their indexes */ if (relationId == AuthIdRolnameIndexId || relationId == AuthIdOidIndexId || relationId == AuthMemRoleMemIndexId || @@ -444,6 +452,7 @@ IsSharedRelation(Oid relationId) } /* These are their toast tables and toast indexes (see toasting.h) */ + /* These are their toast tables and toast indexes */ if (relationId == PgAuthidToastTable || relationId == PgAuthidToastIndex || relationId == PgDatabaseToastTable || @@ -551,6 +560,8 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) SysScanDesc scan; ScanKeyData key; bool collides; + uint64 retries = 0; + uint64 retries_before_log = GETNEWOID_LOG_THRESHOLD; /* Only system relations are supported */ Assert(IsSystemRelation(relation)); @@ -590,6 +601,37 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) collides = true; systable_endscan(scan); + + /* + * Log that we iterate more than GETNEWOID_LOG_THRESHOLD but have not + * yet found OID unused in the relation. Then repeat logging with + * exponentially increasing intervals until we iterate more than + * GETNEWOID_LOG_MAX_INTERVAL. Finally repeat logging every + * GETNEWOID_LOG_MAX_INTERVAL unless an unused OID is found. This + * logic is necessary not to fill up the server log with the similar + * messages. + */ + if (retries >= retries_before_log) + { + ereport(LOG, + (errmsg("still searching for an unused OID in relation \"%s\"", + RelationGetRelationName(relation)), + errdetail_plural("OID candidates have been checked %llu time, but no unused OID has been found yet.", + "OID candidates have been checked %llu times, but no unused OID has been found yet.", + retries, + (unsigned long long) retries))); + + /* + * Double the number of retries to do before logging next until it + * reaches GETNEWOID_LOG_MAX_INTERVAL. + */ + if (retries_before_log * 2 <= GETNEWOID_LOG_MAX_INTERVAL) + retries_before_log *= 2; + else + retries_before_log += GETNEWOID_LOG_MAX_INTERVAL; + } + + retries++; } while (collides); /* @@ -604,6 +646,19 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) elog(PANIC, "allocated OID %u for relation \"%s\" in segment", newOid, RelationGetRelationName(relation)); + /* + * If at least one log message is emitted, also log the completion of OID + * assignment. + */ + if (retries > GETNEWOID_LOG_THRESHOLD) + { + ereport(LOG, + (errmsg_plural("new OID has been assigned in relation \"%s\" after %llu retry", + "new OID has been assigned in relation \"%s\" after %llu retries", + retries, + RelationGetRelationName(relation), (unsigned long long) retries))); + } + return newOid; } diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 6455e634ffe0..02f1c1808b76 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -4,7 +4,7 @@ * Routines to support inter-object dependencies. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -1093,15 +1093,9 @@ reportDependentObjects(const ObjectAddresses *targetObjects, * If no error is to be thrown, and the msglevel is too low to be shown to * either client or server log, there's no need to do any of the rest of * the work. - * - * Note: this code doesn't know all there is to be known about elog - * levels, but it works for NOTICE and DEBUG2, which are the only values - * msglevel can currently have. We also assume we are running in a normal - * operating environment. */ if (behavior == DROP_CASCADE && - msglevel < client_min_messages && - (msglevel < log_min_messages || log_min_messages == LOG)) + !message_level_is_interesting(msglevel)) return; /* @@ -1151,8 +1145,8 @@ reportDependentObjects(const ObjectAddresses *targetObjects, * log_min_messages are different. */ ereport(DEBUG2, - (errmsg("drop auto-cascades to %s", - objDesc))); + (errmsg_internal("drop auto-cascades to %s", + objDesc))); } else if (behavior == DROP_RESTRICT) { @@ -2012,6 +2006,22 @@ find_expr_references_walker(Node *node, context->addrs); /* fall through to examine arguments */ } + else if (IsA(node, SubscriptingRef)) + { + SubscriptingRef *sbsref = (SubscriptingRef *) node; + + /* + * The refexpr should provide adequate dependency on refcontainertype, + * and that type in turn depends on refelemtype. However, a custom + * subscripting handler might set refrestype to something different + * from either of those, in which case we'd better record it. + */ + if (sbsref->refrestype != sbsref->refcontainertype && + sbsref->refrestype != sbsref->refelemtype) + add_object_address(OCLASS_TYPE, sbsref->refrestype, 0, + context->addrs); + /* fall through to examine arguments */ + } else if (IsA(node, SubPlan)) { /* Extra work needed here if we ever need this case */ @@ -2191,6 +2201,21 @@ find_expr_references_walker(Node *node, context->addrs); /* fall through to examine substructure */ } + else if (IsA(node, CTECycleClause)) + { + CTECycleClause *cc = (CTECycleClause *) node; + + if (OidIsValid(cc->cycle_mark_type)) + add_object_address(OCLASS_TYPE, cc->cycle_mark_type, 0, + context->addrs); + if (OidIsValid(cc->cycle_mark_collation)) + add_object_address(OCLASS_COLLATION, cc->cycle_mark_collation, 0, + context->addrs); + if (OidIsValid(cc->cycle_mark_neop)) + add_object_address(OCLASS_OPERATOR, cc->cycle_mark_neop, 0, + context->addrs); + /* fall through to examine substructure */ + } else if (IsA(node, Query)) { /* Recurse into RTE subquery or not-yet-planned sublink subquery */ diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index eb7a640728a3..9862b53db94f 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -6,7 +6,7 @@ # headers from specially formatted header files and data files. # postgres.bki is used to initialize the postgres template database. # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/catalog/genbki.pl @@ -55,6 +55,7 @@ my @toast_decls; my @index_decls; my %oidcounts; +my @system_constraints; foreach my $header (@ARGV) { @@ -137,6 +138,17 @@ $index->{index_name}, $index->{index_oid}, $index->{index_decl}; $oidcounts{ $index->{index_oid} }++; + + if ($index->{is_unique}) + { + $index->{index_decl} =~ /on (\w+) using/; + my $tblname = $1; + push @system_constraints, + sprintf "ALTER TABLE %s ADD %s USING INDEX %s;", + $tblname, + $index->{is_pkey} ? "PRIMARY KEY" : "UNIQUE", + $index->{index_name}; + } } } @@ -155,15 +167,17 @@ die "found $found duplicate OID(s) in catalog data\n" if $found; -# Oids not specified in the input files are automatically assigned, +# OIDs not specified in the input files are automatically assigned, # starting at FirstGenbkiObjectId, extending up to FirstBootstrapObjectId. +# We allow such OIDs to be assigned independently within each catalog. my $FirstGenbkiObjectId = Catalog::FindDefinedSymbol('catalog/pg_magic_oid.h', $include_path, 'FirstGenbkiObjectId'); my $FirstBootstrapObjectId = Catalog::FindDefinedSymbol('catalog/pg_magic_oid.h', $include_path, 'FirstBootstrapObjectId'); -my $GenbkiNextOid = $FirstGenbkiObjectId; +# Hash of next available OID, indexed by catalog name. +my %GenbkiNextOids; # Fetch some special data that we will substitute into the output file. @@ -172,15 +186,12 @@ # within a given Postgres release, such as fixed OIDs. Do not substitute # anything that could depend on platform or configuration. (The right place # to handle those sorts of things is in initdb.c's bootstrap_template1().) -my $BOOTSTRAP_SUPERUSERID = - Catalog::FindDefinedSymbolFromData($catalog_data{pg_authid}, - 'BOOTSTRAP_SUPERUSERID'); my $C_COLLATION_OID = Catalog::FindDefinedSymbolFromData($catalog_data{pg_collation}, 'C_COLLATION_OID'); -my $PG_CATALOG_NAMESPACE = - Catalog::FindDefinedSymbolFromData($catalog_data{pg_namespace}, - 'PG_CATALOG_NAMESPACE'); +my $BOOTSTRAP_SUPERUSERID = + Catalog::FindDefinedSymbolFromData($catalog_data{pg_authid}, + 'BOOTSTRAP_SUPERUSERID'); # Fill in pg_class.relnatts by looking at the referenced catalog's schema. @@ -201,6 +212,13 @@ $amoids{ $row->{amname} } = $row->{oid}; } +# role OID lookup +my %authidoids; +foreach my $row (@{ $catalog_data{pg_authid} }) +{ + $authidoids{ $row->{rolname} } = $row->{oid}; +} + # class (relation) OID lookup (note this only covers bootstrap catalogs!) my %classoids; foreach my $row (@{ $catalog_data{pg_class} }) @@ -222,6 +240,13 @@ $langoids{ $row->{lanname} } = $row->{oid}; } +# namespace (schema) OID lookup +my %namespaceoids; +foreach my $row (@{ $catalog_data{pg_namespace} }) +{ + $namespaceoids{ $row->{nspname} } = $row->{oid}; +} + # opclass OID lookup my %opcoids; foreach my $row (@{ $catalog_data{pg_opclass} }) @@ -257,8 +282,7 @@ # other (auto-generated) entries in pg_class, pg_amop and pg_amproc. if (!($row->{oid})) { - $row->{oid} = $GenbkiNextOid; - $GenbkiNextOid++; + $row->{oid} = assign_next_oid('pg_opfamily'); } $opfoids{$key} = $row->{oid}; @@ -375,9 +399,11 @@ # Map lookup name to the corresponding hash table. my %lookup_kind = ( pg_am => \%amoids, + pg_authid => \%authidoids, pg_class => \%classoids, pg_collation => \%collationoids, pg_language => \%langoids, + pg_namespace => \%namespaceoids, pg_opclass => \%opcoids, pg_operator => \%operoids, pg_opfamily => \%opfoids, @@ -399,6 +425,12 @@ my $schemafile = $output_path . 'schemapg.h'; open my $schemapg, '>', $schemafile . $tmpext or die "can't open $schemafile$tmpext: $!"; +my $fk_info_file = $output_path . 'system_fk_info.h'; +open my $fk_info, '>', $fk_info_file . $tmpext + or die "can't open $fk_info_file$tmpext: $!"; +my $constraints_file = $output_path . 'system_constraints.sql'; +open my $constraints, '>', $constraints_file . $tmpext + or die "can't open $constraints_file$tmpext: $!"; # Generate postgres.bki and pg_*_d.h headers. @@ -426,7 +458,7 @@ * %s_d.h * Macro definitions for %s * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -546,14 +578,13 @@ # Assign oid if oid column exists and no explicit assignment in row if ($attname eq "oid" and not defined $bki_values{$attname}) { - $bki_values{$attname} = $GenbkiNextOid; - $GenbkiNextOid++; + $bki_values{$attname} = assign_next_oid($catname); } - # Substitute constant values we acquired above. - # (It's intentional that this can apply to parts of a field). - $bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g; - $bki_values{$attname} =~ s/\bPGNSP\b/$PG_CATALOG_NAMESPACE/g; + # GPDB: substitute the PGUID token with the bootstrap superuser + # OID (used by GPDB-only catalogs such as pg_compression.compowner). + $bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g + if defined $bki_values{$attname}; # Replace OID synonyms with OIDs per the appropriate lookup rule. # @@ -561,7 +592,8 @@ # each element of the array as per the lookup rule. if ($column->{lookup}) { - my $lookup = $lookup_kind{ $column->{lookup} }; + my $lookup = $lookup_kind{ $column->{lookup} }; + my $lookup_opt = $column->{lookup_opt}; my @lookupnames; my @lookupoids; @@ -571,8 +603,9 @@ if ($atttype eq 'oidvector') { @lookupnames = split /\s+/, $bki_values{$attname}; - @lookupoids = lookup_oids($lookup, $catname, \%bki_values, - @lookupnames); + @lookupoids = + lookup_oids($lookup, $catname, $attname, $lookup_opt, + \%bki_values, @lookupnames); $bki_values{$attname} = join(' ', @lookupoids); } elsif ($atttype eq '_oid') @@ -582,8 +615,8 @@ $bki_values{$attname} =~ s/[{}]//g; @lookupnames = split /,/, $bki_values{$attname}; @lookupoids = - lookup_oids($lookup, $catname, \%bki_values, - @lookupnames); + lookup_oids($lookup, $catname, $attname, + $lookup_opt, \%bki_values, @lookupnames); $bki_values{$attname} = sprintf "{%s}", join(',', @lookupoids); } @@ -591,17 +624,22 @@ else { $lookupnames[0] = $bki_values{$attname}; - @lookupoids = lookup_oids($lookup, $catname, \%bki_values, - @lookupnames); + @lookupoids = + lookup_oids($lookup, $catname, $attname, $lookup_opt, + \%bki_values, @lookupnames); $bki_values{$attname} = $lookupoids[0]; } } } # Special hack to generate OID symbols for pg_type entries - # that lack one. - if ($catname eq 'pg_type' and !exists $bki_values{oid_symbol}) + if ($catname eq 'pg_type') { + die sprintf + "custom OID symbols are not allowed for pg_type entries: '%s'", + $bki_values{oid_symbol} + if defined $bki_values{oid_symbol}; + my $symbol = form_pg_type_symbol($bki_values{typname}); $bki_values{oid_symbol} = $symbol if defined $symbol; @@ -613,6 +651,13 @@ # Emit OID symbol if (defined $bki_values{oid_symbol}) { + # OID symbols for builtin functions are handled automatically + # by utils/Gen_fmgrtab.pl + die sprintf + "custom OID symbols are not allowed for pg_proc entries: '%s'", + $bki_values{oid_symbol} + if $catname eq 'pg_proc'; + printf $def "#define %s %s\n", $bki_values{oid_symbol}, $bki_values{oid}; } @@ -643,11 +688,13 @@ # last command in the BKI file: build the indexes declared above print $bki "build indices\n"; -# check that we didn't overrun available OIDs -die - "genbki OID counter reached $GenbkiNextOid, overrunning FirstBootstrapObjectId\n" - if $GenbkiNextOid > $FirstBootstrapObjectId; +# Now generate system_constraints.sql +foreach my $c (@system_constraints) +{ + # leave blank lines to localize any bootstrap error messages better + print $constraints $c, "\n\n"; +} # Now generate schemapg.h @@ -658,7 +705,7 @@ * schemapg.h * Schema_pg_xxx macros for use by relcache.c * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -685,13 +732,79 @@ # Closing boilerplate for schemapg.h print $schemapg "\n#endif\t\t\t\t\t\t\t/* SCHEMAPG_H */\n"; +# Now generate system_fk_info.h + +# Opening boilerplate for system_fk_info.h +print $fk_info <{foreign_keys} }) + { + my $pktabname = $fkinfo->{pk_table}; + + # We use BKI_LOOKUP for encodings, but there's no real catalog there + next if $pktabname eq 'encoding'; + + printf $fk_info + "\t{ /* %s */ %s, /* %s */ %s, \"{%s}\", \"{%s}\", %s, %s},\n", + $catname, $catalog->{relation_oid}, + $pktabname, $catalogs{$pktabname}->{relation_oid}, + $fkinfo->{fk_cols}, + $fkinfo->{pk_cols}, + ($fkinfo->{is_array} ? "true" : "false"), + ($fkinfo->{is_opt} ? "true" : "false"); + } +} + +# Closing boilerplate for system_fk_info.h +print $fk_info "};\n\n#endif\t\t\t\t\t\t\t/* SYSTEM_FK_INFO_H */\n"; + # We're done emitting data close $bki; close $schemapg; +close $fk_info; +close $constraints; # Finally, rename the completed files into place. -Catalog::RenameTempFile($bkifile, $tmpext); -Catalog::RenameTempFile($schemafile, $tmpext); +Catalog::RenameTempFile($bkifile, $tmpext); +Catalog::RenameTempFile($schemafile, $tmpext); +Catalog::RenameTempFile($fk_info_file, $tmpext); +Catalog::RenameTempFile($constraints_file, $tmpext); exit 0; @@ -796,11 +909,12 @@ sub morph_row_for_pgattr # Copy the type data from pg_type, and add some type-dependent items my $type = $types{$atttype}; - $row->{atttypid} = $type->{oid}; - $row->{attlen} = $type->{typlen}; - $row->{attbyval} = $type->{typbyval}; - $row->{attstorage} = $type->{typstorage}; - $row->{attalign} = $type->{typalign}; + $row->{atttypid} = $type->{oid}; + $row->{attlen} = $type->{typlen}; + $row->{attbyval} = $type->{typbyval}; + $row->{attalign} = $type->{typalign}; + $row->{attstorage} = $type->{typstorage}; + $row->{attcompression} = '\0'; # set attndims if it's an array type $row->{attndims} = $type->{typcategory} eq 'A' ? '1' : '0'; @@ -857,17 +971,15 @@ sub print_bki_insert # since that represents a NUL char in C code. $bki_value = '' if $bki_value eq '\0'; - # Handle single quotes by doubling them, and double quotes by - # converting them to octal escapes, because that's what the + # Handle single quotes by doubling them, because that's what the # bootstrap scanner requires. We do not process backslashes # specially; this allows escape-string-style backslash escapes # to be used in catalog data. $bki_value =~ s/'/''/g; - $bki_value =~ s/"/\\042/g; # Quote value if needed. We need not quote values that satisfy # the "id" pattern in bootscanner.l, currently "[-A-Za-z0-9_]+". - $bki_value = sprintf(qq'"%s"', $bki_value) + $bki_value = sprintf("'%s'", $bki_value) if length($bki_value) == 0 or $bki_value =~ /[^-A-Za-z0-9_]/; @@ -928,7 +1040,8 @@ sub morph_row_for_schemapg # within this genbki.pl run.) sub lookup_oids { - my ($lookup, $catname, $bki_values, @lookupnames) = @_; + my ($lookup, $catname, $attname, $lookup_opt, $bki_values, @lookupnames) + = @_; my @lookupoids; foreach my $lookupname (@lookupnames) @@ -941,10 +1054,19 @@ sub lookup_oids else { push @lookupoids, $lookupname; - warn sprintf - "unresolved OID reference \"%s\" in %s.dat line %s\n", - $lookupname, $catname, $bki_values->{line_number} - if $lookupname ne '-' and $lookupname ne '0'; + if ($lookupname eq '-' or $lookupname eq '0') + { + warn sprintf + "invalid zero OID reference in %s.dat field %s line %s\n", + $catname, $attname, $bki_values->{line_number} + if !$lookup_opt; + } + else + { + warn sprintf + "unresolved OID reference \"%s\" in %s.dat field %s line %s\n", + $lookupname, $catname, $attname, $bki_values->{line_number}; + } } } return @lookupoids; @@ -972,6 +1094,25 @@ sub form_pg_type_symbol return $name . $arraystr . 'OID'; } +# Assign an unused OID within the specified catalog. +sub assign_next_oid +{ + my $catname = shift; + + # Initialize, if no previous request for this catalog. + $GenbkiNextOids{$catname} = $FirstGenbkiObjectId + if !defined($GenbkiNextOids{$catname}); + + my $result = $GenbkiNextOids{$catname}++; + + # Check that we didn't overrun available OIDs + die + "genbki OID counter for $catname reached $result, overrunning FirstBootstrapObjectId\n" + if $result >= $FirstBootstrapObjectId; + + return $result; +} + sub usage { die <natts, - (MAX_PGATTRIBUTE_INSERT_BYTES / sizeof(FormData_pg_attribute))); + (MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_attribute))); slot = palloc(sizeof(TupleTableSlot *) * nslots); for (int i = 0; i < nslots; i++) slot[i] = MakeSingleTupleTableSlot(td, &TTSOpsHeapTuple); @@ -1112,8 +1117,9 @@ InsertPgAttributeTuples(Relation pg_attribute_rel, slot[slotCount]->tts_values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1); slot[slotCount]->tts_values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(attrs->atttypmod); slot[slotCount]->tts_values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(attrs->attbyval); - slot[slotCount]->tts_values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(attrs->attstorage); slot[slotCount]->tts_values[Anum_pg_attribute_attalign - 1] = CharGetDatum(attrs->attalign); + slot[slotCount]->tts_values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(attrs->attstorage); + slot[slotCount]->tts_values[Anum_pg_attribute_attcompression - 1] = CharGetDatum(attrs->attcompression); slot[slotCount]->tts_values[Anum_pg_attribute_attnotnull - 1] = BoolGetDatum(attrs->attnotnull); slot[slotCount]->tts_values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(attrs->atthasdef); slot[slotCount]->tts_values[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(attrs->atthasmissing); @@ -1355,7 +1361,7 @@ AddNewRelationTuple(Relation pg_class_desc, case RELKIND_AOVISIMAP: /* The relation is real, but as yet empty */ new_rel_reltup->relpages = 0; - new_rel_reltup->reltuples = 0; + new_rel_reltup->reltuples = -1; new_rel_reltup->relallvisible = 0; break; case RELKIND_SEQUENCE: @@ -1367,7 +1373,7 @@ AddNewRelationTuple(Relation pg_class_desc, default: /* Views, etc, have no disk storage */ new_rel_reltup->relpages = 0; - new_rel_reltup->reltuples = 0; + new_rel_reltup->reltuples = -1; new_rel_reltup->relallvisible = 0; break; } @@ -1427,6 +1433,7 @@ AddNewRelationType(const char *typeName, InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ InvalidOid, /* analyze procedure - default */ + InvalidOid, /* subscript procedure - none */ InvalidOid, /* array element type - irrelevant */ false, /* this is not an array type */ new_array_type, /* array type if any */ @@ -1455,6 +1462,7 @@ AddNewRelationType(const char *typeName, * reltypeid: OID to assign to rel's rowtype, or InvalidOid to select one * reloftypeid: if a typed table, OID of underlying type; else InvalidOid * ownerid: OID of new rel's owner + * accessmtd: OID of new rel's access method * tupdesc: tuple descriptor (source of column definitions) * cooked_constraints: list of precooked check constraints and defaults * relkind: relkind for new rel @@ -1506,7 +1514,7 @@ heap_create_with_catalog(const char *relname, Acl *relacl; Oid existing_relid; Oid old_type_oid; - Oid new_type_oid; + Oid new_type_oid = InvalidOid; TransactionId relfrozenxid; MultiXactId relminmxid; @@ -1712,6 +1720,7 @@ heap_create_with_catalog(const char *relname, InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ F_ARRAY_TYPANALYZE, /* array analyze procedure */ + F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */ new_type_oid, /* array element type - the rowtype */ true, /* yes, this is an array type */ InvalidOid, /* this has no array type */ @@ -1804,15 +1813,9 @@ heap_create_with_catalog(const char *relname, { ObjectAddress myself, referenced; + ObjectAddresses *addrs; - myself.classId = RelationRelationId; - myself.objectId = relid; - myself.objectSubId = 0; - - referenced.classId = NamespaceRelationId; - referenced.objectId = relnamespace; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(myself, RelationRelationId, relid); recordDependencyOnOwner(RelationRelationId, relid, ownerid); @@ -1820,12 +1823,15 @@ heap_create_with_catalog(const char *relname, recordDependencyOnCurrentExtension(&myself, false); + addrs = new_object_addresses(); + + ObjectAddressSet(referenced, NamespaceRelationId, relnamespace); + add_exact_object_address(&referenced, addrs); + if (reloftypeid) { - referenced.classId = TypeRelationId; - referenced.objectId = reloftypeid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, TypeRelationId, reloftypeid); + add_exact_object_address(&referenced, addrs); } /* @@ -1840,11 +1846,12 @@ heap_create_with_catalog(const char *relname, relkind == RELKIND_MATVIEW || relkind == RELKIND_PARTITIONED_TABLE) { - referenced.classId = AccessMethodRelationId; - referenced.objectId = accessmtd; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, AccessMethodRelationId, accessmtd); + add_exact_object_address(&referenced, addrs); } + + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); } /* Post creation hook for new relation */ @@ -2370,7 +2377,12 @@ heap_drop_with_catalog(Oid relid) elog(ERROR, "cache lookup failed for relation %u", relid); if (((Form_pg_class) GETSTRUCT(tuple))->relispartition) { - parentOid = get_partition_parent(relid); + /* + * We have to lock the parent if the partition is being detached, + * because it's possible that some query still has a partition + * descriptor that includes this partition. + */ + parentOid = get_partition_parent(relid, true); LockRelationOid(parentOid, AccessExclusiveLock); /* @@ -2647,6 +2659,13 @@ SetAttrMissing(Oid relid, char *attname, char *value) /* lock the table the attribute belongs to */ tablerel = table_open(relid, AccessExclusiveLock); + /* Don't do anything unless it's a plain table */ + if (tablerel->rd_rel->relkind != RELKIND_RELATION) + { + table_close(tablerel, AccessExclusiveLock); + return; + } + /* Lock the attribute row and get the data */ attrrel = table_open(AttributeRelationId, RowExclusiveLock); atttup = SearchSysCacheAttName(relid, attname); @@ -2785,39 +2804,52 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, valuesAtt[Anum_pg_attribute_atthasdef - 1] = true; replacesAtt[Anum_pg_attribute_atthasdef - 1] = true; - if (add_column_mode && !attgenerated && cookedMissingVal && *cookedMissingVal) - { - missingval = *missingval_p; - missingIsNull = *missingIsNull_p; - } - else if (add_column_mode && !attgenerated) + if (rel->rd_rel->relkind == RELKIND_RELATION && add_column_mode && + !attgenerated) { - expr2 = expression_planner(expr2); - estate = CreateExecutorState(); - exprState = ExecPrepareExpr(expr2, estate); - econtext = GetPerTupleExprContext(estate); - - missingval = ExecEvalExpr(exprState, econtext, - &missingIsNull); - - FreeExecutorState(estate); - - defAttStruct = TupleDescAttr(rel->rd_att, attnum - 1); - - if (missingIsNull) + if (*cookedMissingVal && Gp_role == GP_ROLE_EXECUTE) { - /* if the default evaluates to NULL, just store a NULL array */ - missingval = (Datum) 0; + /* + * GPDB: a QE executing a dispatched ALTER ... ADD COLUMN + * must reuse the missing value the QD evaluated (already + * wrapped in a one-element array), not evaluate the + * expression again: stable functions like now() would + * yield a different attmissingval on every segment. The + * QD itself always evaluates (per relation); the cooked + * flag can be carried over from a sibling partition there. + */ + missingval = *missingval_p; + missingIsNull = *missingIsNull_p; } else { - /* otherwise make a one-element array of the value */ - missingval = PointerGetDatum(construct_array(&missingval, - 1, - defAttStruct->atttypid, - defAttStruct->attlen, - defAttStruct->attbyval, - defAttStruct->attalign)); + expr2 = expression_planner(expr2); + estate = CreateExecutorState(); + exprState = ExecPrepareExpr(expr2, estate); + econtext = GetPerTupleExprContext(estate); + + missingval = ExecEvalExpr(exprState, econtext, + &missingIsNull); + + FreeExecutorState(estate); + + defAttStruct = TupleDescAttr(rel->rd_att, attnum - 1); + + if (missingIsNull) + { + /* if the default evaluates to NULL, store a NULL array */ + missingval = (Datum) 0; + } + else + { + /* otherwise make a one-element array of the value */ + missingval = PointerGetDatum(construct_array(&missingval, + 1, + defAttStruct->atttypid, + defAttStruct->attlen, + defAttStruct->attbyval, + defAttStruct->attalign)); + } } } if (add_column_mode && !attgenerated) @@ -2828,9 +2860,21 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, replacesAtt[Anum_pg_attribute_attmissingval - 1] = true; nullsAtt[Anum_pg_attribute_attmissingval - 1] = missingIsNull; - *cookedMissingVal = true; - *missingval_p = missingval; - *missingIsNull_p = missingIsNull; + /* + * GPDB: only claim a cooked value when the block above really + * computed (or consumed) one. For relkinds that store no + * missing value (e.g. a partitioned root) missingval still + * holds the "null" initializers; flagging those as cooked + * poisons the ColumnDef written back for dispatch, and QEs + * would skip evaluation and store no missing value for any + * partition child (mixed-AM ADD COLUMN: heap child all-NULL). + */ + if (rel->rd_rel->relkind == RELKIND_RELATION) + { + *cookedMissingVal = true; + *missingval_p = missingval; + *missingIsNull_p = missingIsNull; + } } atttup = heap_modify_tuple(atttup, RelationGetDescr(attrrel), valuesAtt, nullsAtt, replacesAtt); @@ -3075,10 +3119,12 @@ StoreConstraints(Relation rel, List *cooked_constraints, bool is_internal) * Returns a list of CookedConstraint nodes that shows the cooked form of * the default and constraint expressions added to the relation. * - * NB: caller should have opened rel with AccessExclusiveLock, and should - * hold that lock till end of transaction. Also, we assume the caller has - * done a CommandCounterIncrement if necessary to make the relation's catalog - * tuples visible. + * NB: caller should have opened rel with some self-conflicting lock mode, + * and should hold that lock till end of transaction; for normal cases that'll + * be AccessExclusiveLock, but if caller knows that the constraint is already + * enforced by some other means, it can be ShareUpdateExclusiveLock. Also, we + * assume the caller has done a CommandCounterIncrement if necessary to make + * the relation's catalog tuples visible. */ List * AddRelationNewConstraints(Relation rel, @@ -3535,15 +3581,26 @@ check_nested_generated_walker(Node *node, void *context) AttrNumber attnum; relid = rt_fetch(var->varno, pstate->p_rtable)->relid; + if (!OidIsValid(relid)) + return false; /* XXX shouldn't we raise an error? */ + attnum = var->varattno; - if (OidIsValid(relid) && AttributeNumberIsValid(attnum) && get_attgenerated(relid, attnum)) + if (attnum > 0 && get_attgenerated(relid, attnum)) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("cannot use generated column \"%s\" in column generation expression", get_attname(relid, attnum, false)), errdetail("A generated column cannot reference another generated column."), parser_errposition(pstate, var->location))); + /* A whole-row Var is necessarily self-referential, so forbid it */ + if (attnum == 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot use whole-row variable in column generation expression"), + errdetail("This would cause the generated column to depend on its own value."), + parser_errposition(pstate, var->location))); + /* System columns were already checked in the parser */ return false; } @@ -3680,6 +3737,47 @@ cookConstraint(ParseState *pstate, return expr; } +/* + * CopyStatistics --- copy entries in pg_statistic from one rel to another + */ +void +CopyStatistics(Oid fromrelid, Oid torelid) +{ + HeapTuple tup; + SysScanDesc scan; + ScanKeyData key[1]; + Relation statrel; + + statrel = table_open(StatisticRelationId, RowExclusiveLock); + + /* Now search for stat records */ + ScanKeyInit(&key[0], + Anum_pg_statistic_starelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(fromrelid)); + + scan = systable_beginscan(statrel, StatisticRelidAttnumInhIndexId, + true, NULL, 1, key); + + while (HeapTupleIsValid((tup = systable_getnext(scan)))) + { + Form_pg_statistic statform; + + /* make a modifiable copy */ + tup = heap_copytuple(tup); + statform = (Form_pg_statistic) GETSTRUCT(tup); + + /* update the copy of the tuple and insert it */ + statform->starelid = torelid; + CatalogTupleInsert(statrel, tup); + + heap_freetuple(tup); + } + + systable_endscan(scan); + + table_close(statrel, RowExclusiveLock); +} /* * RemoveStatistics --- remove entries in pg_statistic for a rel or column @@ -3971,7 +4069,7 @@ List * heap_truncate_find_FKs(List *relationIds) { List *result = NIL; - List *oids = list_copy(relationIds); + List *oids; List *parent_cons; ListCell *cell; ScanKeyData key; @@ -4115,6 +4213,7 @@ StorePartitionKey(Relation rel, bool nulls[Natts_pg_partitioned_table]; ObjectAddress myself; ObjectAddress referenced; + ObjectAddresses *addrs; Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); @@ -4158,31 +4257,27 @@ StorePartitionKey(Relation rel, table_close(pg_partitioned_table, RowExclusiveLock); /* Mark this relation as dependent on a few things as follows */ - myself.classId = RelationRelationId; - myself.objectId = RelationGetRelid(rel); - myself.objectSubId = 0; + addrs = new_object_addresses(); + ObjectAddressSet(myself, RelationRelationId, RelationGetRelid(rel)); /* Operator class and collation per key column */ for (i = 0; i < partnatts; i++) { - referenced.classId = OperatorClassRelationId; - referenced.objectId = partopclass[i]; - referenced.objectSubId = 0; - - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, OperatorClassRelationId, partopclass[i]); + add_exact_object_address(&referenced, addrs); /* The default collation is pinned, so don't bother recording it */ if (OidIsValid(partcollation[i]) && partcollation[i] != DEFAULT_COLLATION_OID) { - referenced.classId = CollationRelationId; - referenced.objectId = partcollation[i]; - referenced.objectSubId = 0; - - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, CollationRelationId, partcollation[i]); + add_exact_object_address(&referenced, addrs); } } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + /* * The partitioning columns are made internally dependent on the table, * because we cannot drop any of them without dropping the whole table. @@ -4194,10 +4289,8 @@ StorePartitionKey(Relation rel, if (partattrs[i] == 0) continue; /* ignore expressions here */ - referenced.classId = RelationRelationId; - referenced.objectId = RelationGetRelid(rel); - referenced.objectSubId = partattrs[i]; - + ObjectAddressSubSet(referenced, RelationRelationId, + RelationGetRelid(rel), partattrs[i]); recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL); } @@ -4322,7 +4415,8 @@ StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound) * relcache entry for that partition every time a partition is added or * removed. */ - defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(parent)); + defaultPartOid = + get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, true)); if (OidIsValid(defaultPartOid)) CacheInvalidateRelcacheByRelid(defaultPartOid); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index b1963461c8f3..39739ebfa34f 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,6 +32,7 @@ #include "access/relscan.h" #include "access/sysattr.h" #include "access/tableam.h" +#include "access/toast_compression.h" #include "access/transam.h" #include "access/visibilitymap.h" #include "access/xact.h" @@ -62,6 +63,7 @@ #include "commands/event_trigger.h" #include "commands/progress.h" #include "commands/tablecmds.h" +#include "commands/tablespace.h" #include "commands/trigger.h" #include "executor/executor.h" #include "miscadmin.h" @@ -392,8 +394,9 @@ ConstructTupleDescriptor(Relation heapRelation, to->attndims = from->attndims; to->atttypmod = from->atttypmod; to->attbyval = from->attbyval; - to->attstorage = from->attstorage; to->attalign = from->attalign; + to->attstorage = from->attstorage; + to->attcompression = from->attcompression; } else { @@ -419,10 +422,19 @@ ConstructTupleDescriptor(Relation heapRelation, */ to->atttypid = keyType; to->attlen = typeTup->typlen; + to->atttypmod = exprTypmod(indexkey); to->attbyval = typeTup->typbyval; - to->attstorage = typeTup->typstorage; to->attalign = typeTup->typalign; - to->atttypmod = exprTypmod(indexkey); + to->attstorage = typeTup->typstorage; + + /* + * For expression columns, set attcompression invalid, since + * there's no table column from which to copy the value. Whenever + * we actually need to compress a value, we'll use whatever the + * current value of default_toast_compression is at that point in + * time. + */ + to->attcompression = InvalidCompressionMethod; ReleaseSysCache(tuple); @@ -501,6 +513,8 @@ ConstructTupleDescriptor(Relation heapRelation, to->attbyval = typeTup->typbyval; to->attalign = typeTup->typalign; to->attstorage = typeTup->typstorage; + /* As above, use the default compression method in this case */ + to->attcompression = InvalidCompressionMethod; ReleaseSysCache(tuple); } @@ -1095,6 +1109,7 @@ index_create(Relation heapRelation, { ObjectAddress myself, referenced; + ObjectAddresses *addrs; ObjectAddressSet(myself, RelationRelationId, indexRelationId); @@ -1131,6 +1146,8 @@ index_create(Relation heapRelation, { bool have_simple_col = false; + addrs = new_object_addresses(); + /* Create auto dependencies on simply-referenced columns */ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) { @@ -1139,7 +1156,7 @@ index_create(Relation heapRelation, ObjectAddressSubSet(referenced, RelationRelationId, heapRelationId, indexInfo->ii_IndexAttrNumbers[i]); - recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + add_exact_object_address(&referenced, addrs); have_simple_col = true; } } @@ -1154,8 +1171,11 @@ index_create(Relation heapRelation, { ObjectAddressSet(referenced, RelationRelationId, heapRelationId); - recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); + add_exact_object_address(&referenced, addrs); } + + record_object_address_dependencies(&myself, addrs, DEPENDENCY_AUTO); + free_object_addresses(addrs); } /* @@ -1173,7 +1193,11 @@ index_create(Relation heapRelation, recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); } + /* placeholder for normal dependencies */ + addrs = new_object_addresses(); + /* Store dependency on collations */ + /* The default collation is pinned, so don't bother recording it */ for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++) { @@ -1182,7 +1206,7 @@ index_create(Relation heapRelation, { ObjectAddressSet(referenced, CollationRelationId, collationObjectId[i]); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } } @@ -1190,9 +1214,12 @@ index_create(Relation heapRelation, for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++) { ObjectAddressSet(referenced, OperatorClassRelationId, classObjectId[i]); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + /* Store dependencies on anything mentioned in index expressions */ if (indexInfo->ii_Expressions) { @@ -1294,9 +1321,12 @@ index_create(Relation heapRelation, * Create concurrently an index based on the definition of the one provided by * caller. The index is inserted into catalogs and needs to be built later * on. This is called during concurrent reindex processing. + * + * "tablespaceOid" is the tablespace to use for this index. */ Oid -index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char *newName) +index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, + Oid tablespaceOid, const char *newName) { Relation indexRelation; IndexInfo *oldInfo, @@ -1426,7 +1456,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char newInfo, indexColNames, indexRelation->rd_rel->relam, - indexRelation->rd_rel->reltablespace, + tablespaceOid, indexRelation->rd_indcollation, indclass->values, indcoloptions->values, @@ -1588,7 +1618,6 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) /* Preserve indisreplident in the new index */ newIndexForm->indisreplident = oldIndexForm->indisreplident; - oldIndexForm->indisreplident = false; /* Preserve indisclustered in the new index */ newIndexForm->indisclustered = oldIndexForm->indisclustered; @@ -1600,6 +1629,7 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) newIndexForm->indisvalid = true; oldIndexForm->indisvalid = false; oldIndexForm->indisclustered = false; + oldIndexForm->indisreplident = false; CatalogTupleUpdate(pg_index, &oldIndexTuple->t_self, oldIndexTuple); CatalogTupleUpdate(pg_index, &newIndexTuple->t_self, newIndexTuple); @@ -1731,7 +1761,7 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) List *ancestors = get_partition_ancestors(oldIndexId); Oid parentIndexRelid = linitial_oid(ancestors); - DeleteInheritsTuple(oldIndexId, parentIndexRelid); + DeleteInheritsTuple(oldIndexId, parentIndexRelid, false, NULL); StoreSingleInheritance(newIndexId, parentIndexRelid, 1); list_free(ancestors); @@ -1773,6 +1803,65 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) } } + /* Copy data of pg_statistic from the old index to the new one */ + CopyStatistics(oldIndexId, newIndexId); + + /* Copy pg_attribute.attstattarget for each index attribute */ + { + HeapTuple attrTuple; + Relation pg_attribute; + SysScanDesc scan; + ScanKeyData key[1]; + + pg_attribute = table_open(AttributeRelationId, RowExclusiveLock); + ScanKeyInit(&key[0], + Anum_pg_attribute_attrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(newIndexId)); + scan = systable_beginscan(pg_attribute, AttributeRelidNumIndexId, + true, NULL, 1, key); + + while (HeapTupleIsValid((attrTuple = systable_getnext(scan)))) + { + Form_pg_attribute att = (Form_pg_attribute) GETSTRUCT(attrTuple); + Datum repl_val[Natts_pg_attribute]; + bool repl_null[Natts_pg_attribute]; + bool repl_repl[Natts_pg_attribute]; + int attstattarget; + HeapTuple newTuple; + + /* Ignore dropped columns */ + if (att->attisdropped) + continue; + + /* + * Get attstattarget from the old index and refresh the new value. + */ + attstattarget = get_attstattarget(oldIndexId, att->attnum); + + /* no need for a refresh if both match */ + if (attstattarget == att->attstattarget) + continue; + + memset(repl_val, 0, sizeof(repl_val)); + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); + + repl_repl[Anum_pg_attribute_attstattarget - 1] = true; + repl_val[Anum_pg_attribute_attstattarget - 1] = Int32GetDatum(attstattarget); + + newTuple = heap_modify_tuple(attrTuple, + RelationGetDescr(pg_attribute), + repl_val, repl_null, repl_repl); + CatalogTupleUpdate(pg_attribute, &newTuple->t_self, newTuple); + + heap_freetuple(newTuple); + } + + systable_endscan(scan); + table_close(pg_attribute, RowExclusiveLock); + } + /* Close relations */ table_close(pg_class, RowExclusiveLock); table_close(pg_index, RowExclusiveLock); @@ -1986,9 +2075,10 @@ index_constraint_create(Relation heapRelation, */ if (deferrable) { - CreateTrigStmt *trigger; + CreateTrigStmt *trigger = makeNode(CreateTrigStmt); - trigger = makeNode(CreateTrigStmt); + trigger->replace = false; + trigger->isconstraint = true; trigger->trigname = (constraintType == CONSTRAINT_PRIMARY) ? "PK_ConstraintTrigger" : "Unique_ConstraintTrigger"; @@ -2000,7 +2090,7 @@ index_constraint_create(Relation heapRelation, trigger->events = TRIGGER_TYPE_INSERT | TRIGGER_TYPE_UPDATE; trigger->columns = NIL; trigger->whenClause = NULL; - trigger->isconstraint = true; + trigger->transitionRels = NIL; trigger->deferrable = true; trigger->initdeferred = initdeferred; trigger->constrrel = NULL; @@ -2317,7 +2407,7 @@ index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode) /* * fix INHERITS relation */ - DeleteInheritsTuple(indexId, InvalidOid); + DeleteInheritsTuple(indexId, InvalidOid, false, NULL); /* MPP-6929: metadata tracking */ MetaTrackDropObject(RelationRelationId, @@ -2803,6 +2893,15 @@ index_update_stats(Relation rel, /* Should this be a more comprehensive test? */ Assert(rd_rel->relkind != RELKIND_PARTITIONED_INDEX); + /* + * As a special hack, if we are dealing with an empty table and the + * existing reltuples is -1, we leave that alone. This ensures that + * creating an index as part of CREATE TABLE doesn't cause the table to + * prematurely look like it's been vacuumed. + */ + if (reltuples == 0 && rd_rel->reltuples < 0) + reltuples = -1; + /* Apply required updates, if any, to copied tuple */ dirty = false; @@ -2924,17 +3023,15 @@ index_build(Relation heapRelation, if (indexInfo->ii_ParallelWorkers == 0) ereport(DEBUG1, - (errmsg("building index \"%s\" on table \"%s\" serially", - RelationGetRelationName(indexRelation), - RelationGetRelationName(heapRelation)))); + (errmsg_internal("building index \"%s\" on table \"%s\" serially", + RelationGetRelationName(indexRelation), + RelationGetRelationName(heapRelation)))); else ereport(DEBUG1, - (errmsg_plural("building index \"%s\" on table \"%s\" with request for %d parallel worker", - "building index \"%s\" on table \"%s\" with request for %d parallel workers", - indexInfo->ii_ParallelWorkers, - RelationGetRelationName(indexRelation), - RelationGetRelationName(heapRelation), - indexInfo->ii_ParallelWorkers))); + (errmsg_internal("building index \"%s\" on table \"%s\" with request for %d parallel workers", + RelationGetRelationName(indexRelation), + RelationGetRelationName(heapRelation), + indexInfo->ii_ParallelWorkers))); /* * Switch to the table owner's userid, so that any index functions are run @@ -2948,7 +3045,7 @@ index_build(Relation heapRelation, /* Set up initial progress report status */ { - const int index[] = { + const int progress_index[] = { PROGRESS_CREATEIDX_PHASE, PROGRESS_CREATEIDX_SUBPHASE, PROGRESS_CREATEIDX_TUPLES_DONE, @@ -2956,13 +3053,13 @@ index_build(Relation heapRelation, PROGRESS_SCAN_BLOCKS_DONE, PROGRESS_SCAN_BLOCKS_TOTAL }; - const int64 val[] = { + const int64 progress_vals[] = { PROGRESS_CREATEIDX_PHASE_BUILD, PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE, 0, 0, 0, 0 }; - pgstat_progress_update_multi_param(6, index, val); + pgstat_progress_update_multi_param(6, progress_index, progress_vals); } /* @@ -3254,19 +3351,19 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) int save_nestlevel; { - const int index[] = { + const int progress_index[] = { PROGRESS_CREATEIDX_PHASE, PROGRESS_CREATEIDX_TUPLES_DONE, PROGRESS_CREATEIDX_TUPLES_TOTAL, PROGRESS_SCAN_BLOCKS_DONE, PROGRESS_SCAN_BLOCKS_TOTAL }; - const int64 val[] = { + const int64 progress_vals[] = { PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN, 0, 0, 0, 0 }; - pgstat_progress_update_multi_param(5, index, val); + pgstat_progress_update_multi_param(5, progress_index, progress_vals); } /* Open and lock the parent heap relation */ @@ -3323,17 +3420,17 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) /* Execute the sort */ { - const int index[] = { + const int progress_index[] = { PROGRESS_CREATEIDX_PHASE, PROGRESS_SCAN_BLOCKS_DONE, PROGRESS_SCAN_BLOCKS_TOTAL }; - const int64 val[] = { + const int64 progress_vals[] = { PROGRESS_CREATEIDX_PHASE_VALIDATE_SORT, 0, 0 }; - pgstat_progress_update_multi_param(3, index, val); + pgstat_progress_update_multi_param(3, progress_index, progress_vals); } tuplesort_performsort(state.tuplesort); @@ -3384,18 +3481,10 @@ validate_index_callback(ItemPointer itemptr, void *opaque) * index_set_state_flags - adjust pg_index state flags * * This is used during CREATE/DROP INDEX CONCURRENTLY to adjust the pg_index - * flags that denote the index's state. Because the update is not - * transactional and will not roll back on error, this must only be used as - * the last step in a transaction that has not made any transactional catalog - * updates! + * flags that denote the index's state. * - * Note that heap_inplace_update does send a cache inval message for the + * Note that CatalogTupleUpdate() sends a cache invalidation message for the * tuple, so other sessions will hear about the update as soon as we commit. - * - * NB: In releases prior to PostgreSQL 9.4, the use of a non-transactional - * update here would have been unsafe; now that MVCC rules apply even for - * system catalog scans, we could potentially use a transactional update here - * instead. */ void index_set_state_flags(Oid indexId, IndexStateFlagsAction action) @@ -3404,9 +3493,6 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action) HeapTuple indexTuple; Form_pg_index indexForm; - /* Assert that current xact hasn't done any transactional updates */ - Assert(GetTopTransactionIdIfAny() == InvalidTransactionId); - /* Open pg_index and fetch a writable copy of the index's tuple */ pg_index = table_open(IndexRelationId, RowExclusiveLock); @@ -3445,10 +3531,13 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action) * CONCURRENTLY that failed partway through.) * * Note: the CLUSTER logic assumes that indisclustered cannot be - * set on any invalid index, so clear that flag too. + * set on any invalid index, so clear that flag too. Similarly, + * ALTER TABLE assumes that indisreplident cannot be set for + * invalid indexes. */ indexForm->indisvalid = false; indexForm->indisclustered = false; + indexForm->indisreplident = false; break; case INDEX_DROP_SET_DEAD: @@ -3460,13 +3549,15 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action) * the index at all. */ Assert(!indexForm->indisvalid); + Assert(!indexForm->indisclustered); + Assert(!indexForm->indisreplident); indexForm->indisready = false; indexForm->indislive = false; break; } - /* ... and write it back in-place */ - heap_inplace_update(pg_index, indexTuple); + /* ... and update it */ + CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple); table_close(pg_index, RowExclusiveLock); } @@ -3503,7 +3594,7 @@ IndexGetRelation(Oid indexId, bool missing_ok) */ void reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, - int options) + ReindexParams *params) { Relation iRel, heapRelation; @@ -3512,7 +3603,8 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, Oid namespaceId; volatile bool skipped_constraint = false; PGRUsage ru0; - bool progress = (options & REINDEXOPT_REPORT_PROGRESS) != 0; + bool progress = ((params->options & REINDEXOPT_REPORT_PROGRESS) != 0); + bool set_tablespace = false; pg_rusage_init(&ru0); @@ -3522,17 +3614,35 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, * Open and lock the parent heap relation. ShareLock is sufficient since * we only need to be sure no schema or data changes are going on. */ - heapId = IndexGetRelation(indexId, false); - heapRelation = table_open(heapId, ShareLock); + heapId = IndexGetRelation(indexId, + (params->options & REINDEXOPT_MISSING_OK) != 0); + /* if relation is missing, leave */ + if (!OidIsValid(heapId)) + return; + + if ((params->options & REINDEXOPT_MISSING_OK) != 0) + heapRelation = try_table_open(heapId, ShareLock, false); + else + heapRelation = table_open(heapId, ShareLock); + + /* if relation is gone, leave */ + if (!heapRelation) + return; if (progress) { + const int progress_cols[] = { + PROGRESS_CREATEIDX_COMMAND, + PROGRESS_CREATEIDX_INDEX_OID + }; + const int64 progress_vals[] = { + PROGRESS_CREATEIDX_COMMAND_REINDEX, + indexId + }; + pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, heapId); - pgstat_progress_update_param(PROGRESS_CREATEIDX_COMMAND, - PROGRESS_CREATEIDX_COMMAND_REINDEX); - pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, - indexId); + pgstat_progress_update_multi_param(2, progress_cols, progress_vals); } namespaceId = RelationGetNamespace(heapRelation); @@ -3586,12 +3696,50 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, if (Gp_role == GP_ROLE_DISPATCH && RelationIsMapped(heapRelation)) PreventInTransactionBlock(true, "REINDEX of a catalog table"); + /* + * System relations cannot be moved even if allow_system_table_mods is + * enabled to keep things consistent with the concurrent case where all + * the indexes of a relation are processed in series, including indexes of + * toast relations. + * + * Note that this check is not part of CheckRelationTableSpaceMove() as it + * gets used for ALTER TABLE SET TABLESPACE that could cascade across + * toast relations. + */ + if (OidIsValid(params->tablespaceOid) && + IsSystemRelation(iRel)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot move system relation \"%s\"", + RelationGetRelationName(iRel)))); + + /* Check if the tablespace of this index needs to be changed */ + if (OidIsValid(params->tablespaceOid) && + CheckRelationTableSpaceMove(iRel, params->tablespaceOid)) + set_tablespace = true; + /* * Also check for active uses of the index in the current transaction; we * don't want to reindex underneath an open indexscan. */ CheckTableNotInUse(iRel, "REINDEX INDEX"); + /* Set new tablespace, if requested */ + if (set_tablespace) + { + /* Update its pg_class row */ + SetRelationTableSpace(iRel, params->tablespaceOid, InvalidOid); + + /* + * Schedule unlinking of the old index storage at transaction commit. + */ + RelationDropStorage(iRel); + RelationAssumeNewRelfilenode(iRel); + + /* Make sure the reltablespace change is visible */ + CommandCounterIncrement(); + } + /* * All predicate locks on the index are about to be made invalid. Promote * them to relation locks on the heap. @@ -3742,7 +3890,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, } /* Log what we did */ - if (options & REINDEXOPT_VERBOSE) + if ((params->options & REINDEXOPT_VERBOSE) != 0) ereport(INFO, (errmsg("index \"%s\" was reindexed", get_rel_name(indexId)), @@ -3795,7 +3943,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, * index rebuild. */ bool -reindex_relation(Oid relid, int flags, int options) +reindex_relation(Oid relid, int flags, ReindexParams *params) { Relation rel; Oid toast_relid; @@ -3814,7 +3962,14 @@ reindex_relation(Oid relid, int flags, int options) * to prevent schema and data changes in it. The lock level used here * should match ReindexTable(). */ - rel = table_open(relid, ShareLock); + if ((params->options & REINDEXOPT_MISSING_OK) != 0) + rel = try_table_open(relid, ShareLock, false); + else + rel = table_open(relid, ShareLock); + + /* if relation is gone, leave */ + if (!rel) + return false; /* * Partitioned tables should never get processed here, as they have no @@ -3883,7 +4038,7 @@ reindex_relation(Oid relid, int flags, int options) } reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS), - persistence, options); + persistence, params); CommandCounterIncrement(); @@ -3910,7 +4065,19 @@ reindex_relation(Oid relid, int flags, int options) * still hold the lock on the main table. */ if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid)) - result |= reindex_relation(toast_relid, flags, options); + { + /* + * Note that this should fail if the toast relation is missing, so + * reset REINDEXOPT_MISSING_OK. Even if a new tablespace is set for + * the parent relation, the indexes on its toast table are not moved. + * This rule is enforced by setting tablespaceOid to InvalidOid. + */ + ReindexParams newparams = *params; + + newparams.options &= ~(REINDEXOPT_MISSING_OK); + newparams.tablespaceOid = InvalidOid; + result |= reindex_relation(toast_relid, flags, &newparams); + } /* Obtain the aoseg_relid and aoblkdir_relid if the relation is an AO table. */ if ((flags & REINDEX_REL_PROCESS_TOAST) && relIsAO) @@ -3924,21 +4091,21 @@ reindex_relation(Oid relid, int flags, int options) * still hold the lock on the master table. */ if (OidIsValid(aoseg_relid)) - result |= reindex_relation(aoseg_relid, 0, options); + result |= reindex_relation(aoseg_relid, 0, params); /* * If an AO rel has a secondary block directory rel, reindex that too while we * still hold the lock on the master table. */ if (OidIsValid(aoblkdir_relid)) - result |= reindex_relation(aoblkdir_relid, 0, options); + result |= reindex_relation(aoblkdir_relid, 0, params); /* * If an AO rel has a secondary visibility map rel, reindex that too while we * still hold the lock on the master table. */ if (OidIsValid(aovisimap_relid)) - result |= reindex_relation(aovisimap_relid, 0, options); + result |= reindex_relation(aovisimap_relid, 0, params); return result; } diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index acf52c4625fe..9871fc668d81 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -4,7 +4,7 @@ * This file contains routines to support indexes defined on system * catalogs. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -163,6 +163,7 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) heapRelation, index->rd_index->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, + false, indexInfo); } @@ -210,7 +211,6 @@ CatalogTupleCheckConstraints(Relation heapRel, HeapTuple tup) * CatalogTupleInsert - do heap and indexing work for a new catalog tuple * * Insert the tuple data in "tup" into the specified catalog relation. - * The Oid of the inserted tuple is returned. * * This is a convenience routine for the common case of inserting a single * tuple in a system catalog; it inserts a new heap tuple, keeping indexes diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index 5ab47e774316..11d9dd60c208 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -2,7 +2,7 @@ * SQL Information Schema * as defined in ISO/IEC 9075-11:2016 * - * Copyright (c) 2003-2020, PostgreSQL Global Development Group + * Copyright (c) 2003-2021, PostgreSQL Global Development Group * * src/backend/catalog/information_schema.sql * @@ -43,7 +43,8 @@ SET search_path TO information_schema; CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int) RETURNS SETOF RECORD LANGUAGE sql STRICT IMMUTABLE PARALLEL SAFE - AS 'select $1[s], s - pg_catalog.array_lower($1,1) + 1 + AS 'select $1[s], + s operator(pg_catalog.-) pg_catalog.array_lower($1,1) operator(pg_catalog.+) 1 from pg_catalog.generate_series(pg_catalog.array_lower($1,1), pg_catalog.array_upper($1,1), 1) as g(s)'; @@ -52,28 +53,26 @@ CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int) * column's position in the index (NULL if not there) */ CREATE FUNCTION _pg_index_position(oid, smallint) RETURNS int LANGUAGE sql STRICT STABLE - AS $$ +BEGIN ATOMIC SELECT (ss.a).n FROM (SELECT information_schema._pg_expandarray(indkey) AS a FROM pg_catalog.pg_index WHERE indexrelid = $1) ss WHERE (ss.a).x = $2; -$$; +END; CREATE FUNCTION _pg_truetypid(pg_attribute, pg_type) RETURNS oid LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END$$; +RETURN CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END; CREATE FUNCTION _pg_truetypmod(pg_attribute, pg_type) RETURNS int4 LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END$$; +RETURN CASE WHEN $2.typtype = 'd' THEN $2.typtypmod ELSE $1.atttypmod END; -- these functions encapsulate knowledge about the encoding of typmod: @@ -82,8 +81,7 @@ CREATE FUNCTION _pg_char_max_length(typid oid, typmod int4) RETURNS integer IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $2 = -1 /* default typmod */ THEN null WHEN $1 IN (1042, 1043) /* char, varchar */ @@ -91,15 +89,14 @@ $$SELECT WHEN $1 IN (1560, 1562) /* bit, varbit */ THEN $2 ELSE null - END$$; + END; CREATE FUNCTION _pg_char_octet_length(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (25, 1042, 1043) /* text, char, varchar */ THEN CASE WHEN $2 = -1 /* default typmod */ THEN CAST(2^30 AS integer) @@ -107,15 +104,14 @@ $$SELECT pg_catalog.pg_encoding_max_length((SELECT encoding FROM pg_catalog.pg_database WHERE datname = pg_catalog.current_database())) END ELSE null - END$$; + END; CREATE FUNCTION _pg_numeric_precision(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE $1 WHEN 21 /*int2*/ THEN 16 WHEN 23 /*int4*/ THEN 32 @@ -128,27 +124,25 @@ $$SELECT WHEN 700 /*float4*/ THEN 24 /*FLT_MANT_DIG*/ WHEN 701 /*float8*/ THEN 53 /*DBL_MANT_DIG*/ ELSE null - END$$; + END; CREATE FUNCTION _pg_numeric_precision_radix(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (21, 23, 20, 700, 701) THEN 2 WHEN $1 IN (1700) THEN 10 ELSE null - END$$; + END; CREATE FUNCTION _pg_numeric_scale(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (21, 23, 20) THEN 0 WHEN $1 IN (1700) THEN CASE WHEN $2 = -1 @@ -156,15 +150,14 @@ $$SELECT ELSE ($2 - 4) & 65535 END ELSE null - END$$; + END; CREATE FUNCTION _pg_datetime_precision(typid oid, typmod int4) RETURNS integer LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (1082) /* date */ THEN 0 WHEN $1 IN (1083, 1114, 1184, 1266) /* time, timestamp, same + tz */ @@ -172,19 +165,18 @@ $$SELECT WHEN $1 IN (1186) /* interval */ THEN CASE WHEN $2 < 0 OR $2 & 65535 = 65535 THEN 6 ELSE $2 & 65535 END ELSE null - END$$; + END; CREATE FUNCTION _pg_interval_type(typid oid, mod int4) RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE RETURNS NULL ON NULL INPUT - AS -$$SELECT +RETURN CASE WHEN $1 IN (1186) /* interval */ THEN pg_catalog.upper(substring(pg_catalog.format_type($1, $2) similar 'interval[()0-9]* #"%#"' escape '#')) ELSE null - END$$; + END; -- 5.2 INFORMATION_SCHEMA_CATALOG_NAME view appears later. @@ -255,7 +247,14 @@ CREATE VIEW applicable_roles AS SELECT CAST(a.rolname AS sql_identifier) AS grantee, CAST(b.rolname AS sql_identifier) AS role_name, CAST(CASE WHEN m.admin_option THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable - FROM pg_auth_members m + FROM (SELECT member, roleid, admin_option FROM pg_auth_members + -- This UNION could be UNION ALL, but UNION works even if we start + -- to allow explicit pg_database_owner membership. + UNION + SELECT datdba, pg_authid.oid, false + FROM pg_database, pg_authid + WHERE datname = current_database() AND rolname = 'pg_database_owner' + ) m JOIN pg_authid a ON (m.member = a.oid) JOIN pg_authid b ON (m.roleid = b.oid) WHERE pg_has_role(a.oid, 'USAGE'); @@ -407,7 +406,8 @@ GRANT SELECT ON character_sets TO PUBLIC; */ CREATE VIEW check_constraint_routine_usage AS - SELECT CAST(current_database() AS sql_identifier) AS constraint_catalog, + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS constraint_catalog, CAST(nc.nspname AS sql_identifier) AS constraint_schema, CAST(c.conname AS sql_identifier) AS constraint_name, CAST(current_database() AS sql_identifier) AS specific_catalog, @@ -506,7 +506,8 @@ GRANT SELECT ON collation_character_set_applicability TO PUBLIC; */ CREATE VIEW column_column_usage AS - SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS table_catalog, CAST(n.nspname AS sql_identifier) AS table_schema, CAST(c.relname AS sql_identifier) AS table_name, CAST(ac.attname AS sql_identifier) AS column_name, @@ -1325,7 +1326,34 @@ GRANT SELECT ON role_column_grants TO PUBLIC; * ROUTINE_COLUMN_USAGE view */ --- not tracked by PostgreSQL +CREATE VIEW routine_column_usage AS + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS specific_catalog, + CAST(np.nspname AS sql_identifier) AS specific_schema, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, + CAST(current_database() AS sql_identifier) AS routine_catalog, + CAST(np.nspname AS sql_identifier) AS routine_schema, + CAST(p.proname AS sql_identifier) AS routine_name, + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nt.nspname AS sql_identifier) AS table_schema, + CAST(t.relname AS sql_identifier) AS table_name, + CAST(a.attname AS sql_identifier) AS column_name + + FROM pg_namespace np, pg_proc p, pg_depend d, + pg_class t, pg_namespace nt, pg_attribute a + + WHERE np.oid = p.pronamespace + AND p.oid = d.objid + AND d.classid = 'pg_catalog.pg_proc'::regclass + AND d.refobjid = t.oid + AND d.refclassid = 'pg_catalog.pg_class'::regclass + AND t.relnamespace = nt.oid + AND t.relkind IN ('r', 'v', 'f', 'p') + AND t.oid = a.attrelid + AND d.refobjsubid = a.attnum + AND pg_has_role(t.relowner, 'USAGE'); + +GRANT SELECT ON routine_column_usage TO PUBLIC; /* @@ -1408,7 +1436,28 @@ GRANT SELECT ON role_routine_grants TO PUBLIC; * ROUTINE_ROUTINE_USAGE view */ --- not tracked by PostgreSQL +CREATE VIEW routine_routine_usage AS + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS specific_catalog, + CAST(np.nspname AS sql_identifier) AS specific_schema, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, + CAST(current_database() AS sql_identifier) AS routine_catalog, + CAST(np1.nspname AS sql_identifier) AS routine_schema, + CAST(nameconcatoid(p1.proname, p1.oid) AS sql_identifier) AS routine_name + + FROM pg_namespace np, pg_proc p, pg_depend d, + pg_proc p1, pg_namespace np1 + + WHERE np.oid = p.pronamespace + AND p.oid = d.objid + AND d.classid = 'pg_catalog.pg_proc'::regclass + AND d.refobjid = p1.oid + AND d.refclassid = 'pg_catalog.pg_proc'::regclass + AND p1.pronamespace = np1.oid + AND p.prokind IN ('f', 'p') AND p1.prokind IN ('f', 'p') + AND pg_has_role(p1.proowner, 'USAGE'); + +GRANT SELECT ON routine_routine_usage TO PUBLIC; /* @@ -1416,7 +1465,31 @@ GRANT SELECT ON role_routine_grants TO PUBLIC; * ROUTINE_SEQUENCE_USAGE view */ --- not tracked by PostgreSQL +CREATE VIEW routine_sequence_usage AS + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS specific_catalog, + CAST(np.nspname AS sql_identifier) AS specific_schema, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, + CAST(current_database() AS sql_identifier) AS routine_catalog, + CAST(np.nspname AS sql_identifier) AS routine_schema, + CAST(p.proname AS sql_identifier) AS routine_name, + CAST(current_database() AS sql_identifier) AS sequence_catalog, + CAST(ns.nspname AS sql_identifier) AS sequence_schema, + CAST(s.relname AS sql_identifier) AS sequence_name + + FROM pg_namespace np, pg_proc p, pg_depend d, + pg_class s, pg_namespace ns + + WHERE np.oid = p.pronamespace + AND p.oid = d.objid + AND d.classid = 'pg_catalog.pg_proc'::regclass + AND d.refobjid = s.oid + AND d.refclassid = 'pg_catalog.pg_class'::regclass + AND s.relnamespace = ns.oid + AND s.relkind = 'S' + AND pg_has_role(s.relowner, 'USAGE'); + +GRANT SELECT ON routine_sequence_usage TO PUBLIC; /* @@ -1424,7 +1497,31 @@ GRANT SELECT ON role_routine_grants TO PUBLIC; * ROUTINE_TABLE_USAGE view */ --- not tracked by PostgreSQL +CREATE VIEW routine_table_usage AS + SELECT DISTINCT + CAST(current_database() AS sql_identifier) AS specific_catalog, + CAST(np.nspname AS sql_identifier) AS specific_schema, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, + CAST(current_database() AS sql_identifier) AS routine_catalog, + CAST(np.nspname AS sql_identifier) AS routine_schema, + CAST(p.proname AS sql_identifier) AS routine_name, + CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(nt.nspname AS sql_identifier) AS table_schema, + CAST(t.relname AS sql_identifier) AS table_name + + FROM pg_namespace np, pg_proc p, pg_depend d, + pg_class t, pg_namespace nt + + WHERE np.oid = p.pronamespace + AND p.oid = d.objid + AND d.classid = 'pg_catalog.pg_proc'::regclass + AND d.refobjid = t.oid + AND d.refclassid = 'pg_catalog.pg_class'::regclass + AND t.relnamespace = nt.oid + AND t.relkind IN ('r', 'v', 'f', 'p') + AND pg_has_role(t.relowner, 'USAGE'); + +GRANT SELECT ON routine_table_usage TO PUBLIC; /* diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 62b9892ffbb7..b14467078bfe 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -9,7 +9,7 @@ * and implementing search-path-controlled searches. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -219,6 +219,7 @@ static void RemoveSchemaById(Oid schemaOid); static void RemoveTempRelationsCallback(int code, Datum arg); static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue); static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, + bool include_out_arguments, int pronargs, int **argnumbers); static bool TempNamespaceValid(bool error_if_removed); @@ -925,6 +926,12 @@ TypeIsVisible(Oid typid) * of additional args (which can be retrieved from the function's * proargdefaults entry). * + * If include_out_arguments is true, then OUT-mode arguments are considered to + * be included in the argument list. Their types are included in the returned + * arrays, and argnumbers are indexes in proallargtypes not proargtypes. + * We also set nominalnargs to be the length of proallargtypes not proargtypes. + * Otherwise OUT-mode arguments are ignored. + * * It is not possible for nvargs and ndargs to both be nonzero in the same * list entry, since default insertion allows matches to functions with more * than nargs arguments while the variadic transformation requires the same @@ -935,7 +942,8 @@ TypeIsVisible(Oid typid) * first any positional arguments, then the named arguments, then defaulted * arguments (if needed and allowed by expand_defaults). The argnumbers[] * array can be used to map this back to the catalog information. - * argnumbers[k] is set to the proargtypes index of the k'th call argument. + * argnumbers[k] is set to the proargtypes or proallargtypes index of the + * k'th call argument. * * We search a single namespace if the function name is qualified, else * all namespaces in the search path. In the multiple-namespace case, @@ -959,13 +967,13 @@ TypeIsVisible(Oid typid) * such an entry it should react as though the call were ambiguous. * * If missing_ok is true, an empty list (NULL) is returned if the name was - * schema- qualified with a schema that does not exist. Likewise if no + * schema-qualified with a schema that does not exist. Likewise if no * candidate is found for other reasons. */ FuncCandidateList FuncnameGetCandidates(List *names, int nargs, List *argnames, bool expand_variadic, bool expand_defaults, - bool missing_ok) + bool include_out_arguments, bool missing_ok) { FuncCandidateList resultList = NULL; bool any_special = false; @@ -1002,6 +1010,7 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, { HeapTuple proctup = &catlist->members[i]->tuple; Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup); + Oid *proargtypes = procform->proargtypes.values; int pronargs = procform->pronargs; int effective_nargs; int pathpos = 0; @@ -1036,6 +1045,35 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, continue; /* proc is not in search path */ } + /* + * If we are asked to match to OUT arguments, then use the + * proallargtypes array (which includes those); otherwise use + * proargtypes (which doesn't). Of course, if proallargtypes is null, + * we always use proargtypes. + */ + if (include_out_arguments) + { + Datum proallargtypes; + bool isNull; + + proallargtypes = SysCacheGetAttr(PROCNAMEARGSNSP, proctup, + Anum_pg_proc_proallargtypes, + &isNull); + if (!isNull) + { + ArrayType *arr = DatumGetArrayTypeP(proallargtypes); + + pronargs = ARR_DIMS(arr)[0]; + if (ARR_NDIM(arr) != 1 || + pronargs < 0 || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != OIDOID) + elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls"); + Assert(pronargs >= procform->pronargs); + proargtypes = (Oid *) ARR_DATA_PTR(arr); + } + } + if (argnames != NIL) { /* @@ -1071,6 +1109,7 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, /* Check for argument name match, generate positional mapping */ if (!MatchNamedCall(proctup, nargs, argnames, + include_out_arguments, pronargs, &argnumbers)) continue; @@ -1129,12 +1168,12 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, effective_nargs * sizeof(Oid)); newResult->pathpos = pathpos; newResult->oid = procform->oid; + newResult->nominalnargs = pronargs; newResult->nargs = effective_nargs; newResult->argnumbers = argnumbers; if (argnumbers) { /* Re-order the argument types into call's logical order */ - Oid *proargtypes = procform->proargtypes.values; int i; for (i = 0; i < pronargs; i++) @@ -1143,8 +1182,7 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, else { /* Simple positional case, just copy proargtypes as-is */ - memcpy(newResult->args, procform->proargtypes.values, - pronargs * sizeof(Oid)); + memcpy(newResult->args, proargtypes, pronargs * sizeof(Oid)); } if (variadic) { @@ -1317,6 +1355,10 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, * the function, in positions after the last positional argument, and there * are defaults for all unsupplied arguments. * + * If include_out_arguments is true, we are treating OUT arguments as + * included in the argument list. pronargs is the number of arguments + * we're considering (the length of either proargtypes or proallargtypes). + * * The number of positional arguments is nargs - list_length(argnames). * Note caller has already done basic checks on argument count. * @@ -1327,10 +1369,10 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, */ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, + bool include_out_arguments, int pronargs, int **argnumbers) { Form_pg_proc procform = (Form_pg_proc) GETSTRUCT(proctup); - int pronargs = procform->pronargs; int numposargs = nargs - list_length(argnames); int pronallargs; Oid *p_argtypes; @@ -1357,6 +1399,8 @@ MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, &p_argtypes, &p_argnames, &p_argmodes); Assert(p_argnames != NULL); + Assert(include_out_arguments ? (pronargs == pronallargs) : (pronargs <= pronallargs)); + /* initialize state for matching */ *argnumbers = (int *) palloc(pronargs * sizeof(int)); memset(arggiven, false, pronargs * sizeof(bool)); @@ -1379,8 +1423,9 @@ MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, found = false; for (i = 0; i < pronallargs; i++) { - /* consider only input parameters */ - if (p_argmodes && + /* consider only input params, except with include_out_arguments */ + if (!include_out_arguments && + p_argmodes && (p_argmodes[i] != FUNC_PARAM_IN && p_argmodes[i] != FUNC_PARAM_INOUT && p_argmodes[i] != FUNC_PARAM_VARIADIC)) @@ -1395,7 +1440,7 @@ MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, found = true; break; } - /* increase pp only for input parameters */ + /* increase pp only for considered parameters */ pp++; } /* if name isn't in proargnames, fail */ @@ -1472,7 +1517,7 @@ FunctionIsVisible(Oid funcid) visible = false; clist = FuncnameGetCandidates(list_make1(makeString(proname)), - nargs, NIL, false, false, false); + nargs, NIL, false, false, false, false); for (; clist; clist = clist->next) { @@ -1497,8 +1542,7 @@ FunctionIsVisible(Oid funcid) * Given a possibly-qualified operator name and exact input datatypes, * look up the operator. Returns InvalidOid if not found. * - * Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for - * a postfix op. + * Pass oprleft = InvalidOid for a prefix op. * * If the operator name is not schema-qualified, it is sought in the current * namespace search path. If the name is schema-qualified and the given @@ -1604,8 +1648,8 @@ OpernameGetOprid(List *names, Oid oprleft, Oid oprright) * namespace case, we arrange for entries in earlier namespaces to mask * identical entries in later namespaces. * - * The returned items always have two args[] entries --- one or the other - * will be InvalidOid for a prefix or postfix oprkind. nargs is 2, too. + * The returned items always have two args[] entries --- the first will be + * InvalidOid for a prefix oprkind. nargs is always 2, too. */ FuncCandidateList OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok) @@ -1746,6 +1790,7 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok) newResult->pathpos = pathpos; newResult->oid = operform->oid; + newResult->nominalnargs = 2; newResult->nargs = 2; newResult->nvargs = 0; newResult->ndargs = 0; @@ -3942,7 +3987,7 @@ recomputeNamespacePath(void) /* * We want to detect the case where the effective value of the base search * path variables didn't change. As long as we're doing so, we can avoid - * copying the OID list unncessarily. + * copying the OID list unnecessarily. */ if (baseCreationNamespace == firstNS && baseTempCreationPending == temp_missing && @@ -4307,9 +4352,18 @@ ResetTempNamespace(void) /* * MPP-19973: The shmem exit callback to remove a temp * namespace is registered. We need to remove it here as the - * namespace has already been reseted. + * namespace has already been reseted. + * + * Use the non-throwing variant: this is reached during gang-loss + * recovery, where the callback may not be the latest before_shmem_exit + * entry, or may never have been registered (temp namespace created but + * not yet committed). In PG14 the plain cancel_before_shmem_exit() would + * raise an error in those cases, which -- thrown from AbortTransaction() + * via ResetAllGangs() -- escalates to a coordinator PANIC. Leaving the + * callback registered is harmless: RemoveTempRelationsCallback() no-ops + * once myTempNamespace is reset just below. */ - cancel_before_shmem_exit(RemoveTempRelationsCallback, 0); + cancel_before_shmem_exit_if_latest(RemoveTempRelationsCallback, 0); myTempNamespace = InvalidOid; myTempToastNamespace = InvalidOid; diff --git a/src/backend/catalog/objectaccess.c b/src/backend/catalog/objectaccess.c index 17d7c56198a9..4aa445a077ef 100644 --- a/src/backend/catalog/objectaccess.c +++ b/src/backend/catalog/objectaccess.c @@ -3,7 +3,7 @@ * objectaccess.c * functions for object_access_hook on various events * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------- diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index c02b05a76258..effbbb96a814 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -3,7 +3,7 @@ * objectaddress.c * functions for working with ObjectAddresses * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -102,7 +102,8 @@ */ typedef struct { - const char *class_descr; /* string describing the catalog, for internal error messages */ + const char *class_descr; /* string describing the catalog, for internal + * error messages */ Oid class_oid; /* oid of catalog */ Oid oid_index_oid; /* oid of index on system oid column */ int oid_catcache_id; /* id of catcache on system oid column */ @@ -594,7 +595,7 @@ static const ObjectPropertyType ObjectProperty[] = true }, { - "extented statistics", + "extended statistics", StatisticExtRelationId, StatisticExtOidIndexId, STATEXTOID, @@ -1545,7 +1546,7 @@ get_object_address_attribute(ObjectType objtype, List *object, ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("column name must be qualified"))); - attname = strVal(lfirst(list_tail(object))); + attname = strVal(llast(object)); relname = list_truncate(list_copy(object), list_length(object) - 1); /* XXX no missing_ok support here */ relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode); @@ -2921,6 +2922,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) char *attname = get_attname(object->objectId, object->objectSubId, missing_ok); + if (!attname) break; @@ -2938,6 +2940,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) bits16 flags = FORMAT_PROC_INVALID_AS_NULL; char *proname = format_procedure_extended(object->objectId, flags); + if (proname == NULL) break; @@ -2950,6 +2953,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) bits16 flags = FORMAT_TYPE_INVALID_AS_NULL; char *typname = format_type_extended(object->objectId, -1, flags); + if (typname == NULL) break; @@ -3911,6 +3915,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) { char *pubname = get_publication_name(object->objectId, missing_ok); + if (pubname) appendStringInfo(&buffer, _("publication %s"), pubname); break; @@ -3951,6 +3956,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) { char *subname = get_subscription_name(object->objectId, missing_ok); + if (subname) appendStringInfo(&buffer, _("subscription %s"), subname); break; @@ -4336,7 +4342,7 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS) tupdesc = BlessTupleDesc(tupdesc); - /* object type */ + /* object type, which can never be NULL */ values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true)); nulls[0] = false; @@ -4552,9 +4558,8 @@ getObjectTypeDescription(const ObjectAddress *object, bool missing_ok) */ } - /* an empty string is equivalent to no object found */ - if (buffer.len == 0) - return NULL; + /* the result can never be empty */ + Assert(buffer.len > 0); return buffer.data; } @@ -4776,6 +4781,7 @@ getObjectIdentityParts(const ObjectAddress *object, bits16 flags = FORMAT_PROC_FORCE_QUALIFY | FORMAT_PROC_INVALID_AS_NULL; char *proname = format_procedure_extended(object->objectId, flags); + if (proname == NULL) break; @@ -5025,6 +5031,7 @@ getObjectIdentityParts(const ObjectAddress *object, bits16 flags = FORMAT_OPERATOR_FORCE_QUALIFY | FORMAT_OPERATOR_INVALID_AS_NULL; char *oprname = format_operator_extended(object->objectId, flags); + if (oprname == NULL) break; @@ -5675,10 +5682,7 @@ getObjectIdentityParts(const ObjectAddress *object, { HeapTuple tup; Form_pg_event_trigger trigForm; - - /* no objname support here */ - if (objname) - *objname = NIL; + char *evtname; tup = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(object->objectId)); @@ -5690,8 +5694,10 @@ getObjectIdentityParts(const ObjectAddress *object, break; } trigForm = (Form_pg_event_trigger) GETSTRUCT(tup); - appendStringInfoString(&buffer, - quote_identifier(NameStr(trigForm->evtname))); + evtname = pstrdup(NameStr(trigForm->evtname)); + appendStringInfoString(&buffer, quote_identifier(evtname)); + if (objname) + *objname = list_make1(evtname); ReleaseSysCache(tup); break; } diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index 239ac017fa69..790f4ccb9277 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -3,7 +3,7 @@ * partition.c * Partitioning related data structures and functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,7 +32,8 @@ #include "utils/rel.h" #include "utils/syscache.h" -static Oid get_partition_parent_worker(Relation inhRel, Oid relid); +static Oid get_partition_parent_worker(Relation inhRel, Oid relid, + bool *detach_pending); static void get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors); @@ -42,23 +43,32 @@ static void get_partition_ancestors_worker(Relation inhRel, Oid relid, * * Returns inheritance parent of a partition by scanning pg_inherits * + * If the partition is in the process of being detached, an error is thrown, + * unless even_if_detached is passed as true. + * * Note: Because this function assumes that the relation whose OID is passed * as an argument will have precisely one parent, it should only be called * when it is known that the relation is a partition. */ Oid -get_partition_parent(Oid relid) +get_partition_parent(Oid relid, bool even_if_detached) { Relation catalogRelation; Oid result; + bool detach_pending; catalogRelation = table_open(InheritsRelationId, AccessShareLock); - result = get_partition_parent_worker(catalogRelation, relid); + result = get_partition_parent_worker(catalogRelation, relid, + &detach_pending); if (!OidIsValid(result)) elog(ERROR, "could not find tuple for parent of relation %u", relid); + if (detach_pending && !even_if_detached) + elog(ERROR, "relation %u has no parent because it's being detached", + relid); + table_close(catalogRelation, AccessShareLock); return result; @@ -68,15 +78,20 @@ get_partition_parent(Oid relid) * get_partition_parent_worker * Scan the pg_inherits relation to return the OID of the parent of the * given relation + * + * If the partition is being detached, *detach_pending is set true (but the + * original parent is still returned.) */ static Oid -get_partition_parent_worker(Relation inhRel, Oid relid) +get_partition_parent_worker(Relation inhRel, Oid relid, bool *detach_pending) { SysScanDesc scan; ScanKeyData key[2]; Oid result = InvalidOid; HeapTuple tuple; + *detach_pending = false; + ScanKeyInit(&key[0], Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -93,6 +108,9 @@ get_partition_parent_worker(Relation inhRel, Oid relid) { Form_pg_inherits form = (Form_pg_inherits) GETSTRUCT(tuple); + /* Let caller know of partition being detached */ + if (form->inhdetachpending) + *detach_pending = true; result = form->inhparent; } @@ -134,10 +152,14 @@ static void get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors) { Oid parentOid; + bool detach_pending; - /* Recursion ends at the topmost level, ie., when there's no parent */ - parentOid = get_partition_parent_worker(inhRel, relid); - if (parentOid == InvalidOid) + /* + * Recursion ends at the topmost level, ie., when there's no parent; also + * when the partition is being detached. + */ + parentOid = get_partition_parent_worker(inhRel, relid, &detach_pending); + if (parentOid == InvalidOid || detach_pending) return; *ancestors = lappend_oid(*ancestors, parentOid); @@ -170,13 +192,14 @@ index_get_partition(Relation partition, Oid indexId) ReleaseSysCache(tup); if (!ispartition) continue; - if (get_partition_parent(lfirst_oid(l)) == indexId) + if (get_partition_parent(partIdx, false) == indexId) { list_free(idxlist); return partIdx; } } + list_free(idxlist); return InvalidOid; } diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 2d3c7ea14c3e..56fe3b879c7f 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -3,7 +3,7 @@ * pg_aggregate.c * routines to support manipulation of the pg_aggregate relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -106,6 +106,7 @@ AggregateCreate(const char *aggName, int i; ObjectAddress myself, referenced; + ObjectAddresses *addrs; AclResult aclresult; /* sanity checks (caller should have caught these) */ @@ -565,8 +566,8 @@ AggregateCreate(const char *aggName, ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("moving-aggregate implementation returns type %s, but plain implementation returns type %s", - format_type_be(aggmTransType), - format_type_be(aggTransType)))); + format_type_be(rettype), + format_type_be(finaltype)))); } /* handle sortop, if supplied */ @@ -620,9 +621,10 @@ AggregateCreate(const char *aggName, GetUserId(), /* proowner */ INTERNALlanguageId, /* languageObjectId */ InvalidOid, /* no validator */ - InvalidOid, /* no describe function */ - "aggregate_dummy", /* placeholder proc */ + InvalidOid, /* no describe function */ + "aggregate_dummy", /* placeholder (no such proc) */ NULL, /* probin */ + NULL, /* prosqlbody */ PROKIND_AGGREGATE, false, /* security invoker (currently not * definable for agg) */ @@ -745,66 +747,70 @@ AggregateCreate(const char *aggName, * way. */ + addrs = new_object_addresses(); + /* Depends on transition function */ ObjectAddressSet(referenced, ProcedureRelationId, transfn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); /* Depends on final function, if any */ if (OidIsValid(finalfn)) { ObjectAddressSet(referenced, ProcedureRelationId, finalfn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Depends on combine function, if any */ if (OidIsValid(combinefn)) { ObjectAddressSet(referenced, ProcedureRelationId, combinefn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Depends on serialization function, if any */ if (OidIsValid(serialfn)) { ObjectAddressSet(referenced, ProcedureRelationId, serialfn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Depends on deserialization function, if any */ if (OidIsValid(deserialfn)) { ObjectAddressSet(referenced, ProcedureRelationId, deserialfn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Depends on forward transition function, if any */ if (OidIsValid(mtransfn)) { ObjectAddressSet(referenced, ProcedureRelationId, mtransfn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Depends on inverse transition function, if any */ if (OidIsValid(minvtransfn)) { ObjectAddressSet(referenced, ProcedureRelationId, minvtransfn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Depends on final function, if any */ if (OidIsValid(mfinalfn)) { ObjectAddressSet(referenced, ProcedureRelationId, mfinalfn); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Depends on sort operator, if any */ if (OidIsValid(sortop)) { ObjectAddressSet(referenced, OperatorRelationId, sortop); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); return myself; } @@ -844,7 +850,7 @@ lookup_agg_function(List *fnName, * the function. */ fdresult = func_get_detail(fnName, NIL, NIL, - nargs, input_types, false, false, + nargs, input_types, false, false, false, &fnOid, rettype, &retset, &nvargs, &vatype, &true_oid_array, NULL); diff --git a/src/backend/catalog/pg_cast.c b/src/backend/catalog/pg_cast.c index 6f020975a40c..5bd2c52a0e7f 100644 --- a/src/backend/catalog/pg_cast.c +++ b/src/backend/catalog/pg_cast.c @@ -3,7 +3,7 @@ * pg_cast.c * routines to support manipulation of the pg_cast relation * - * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -54,6 +54,7 @@ CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, char castcontext, bool nulls[Natts_pg_cast]; ObjectAddress myself, referenced; + ObjectAddresses *addrs; relation = table_open(CastRelationId, RowExclusiveLock); @@ -88,32 +89,29 @@ CastCreate(Oid sourcetypeid, Oid targettypeid, Oid funcid, char castcontext, CatalogTupleInsert(relation, tuple); + addrs = new_object_addresses(); + /* make dependency entries */ - myself.classId = CastRelationId; - myself.objectId = castid; - myself.objectSubId = 0; + ObjectAddressSet(myself, CastRelationId, castid); /* dependency on source type */ - referenced.classId = TypeRelationId; - referenced.objectId = sourcetypeid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, behavior); + ObjectAddressSet(referenced, TypeRelationId, sourcetypeid); + add_exact_object_address(&referenced, addrs); /* dependency on target type */ - referenced.classId = TypeRelationId; - referenced.objectId = targettypeid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, behavior); + ObjectAddressSet(referenced, TypeRelationId, targettypeid); + add_exact_object_address(&referenced, addrs); /* dependency on function */ if (OidIsValid(funcid)) { - referenced.classId = ProcedureRelationId; - referenced.objectId = funcid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, behavior); + ObjectAddressSet(referenced, ProcedureRelationId, funcid); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, behavior); + free_object_addresses(addrs); + /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, false); diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c index c67cd43b1104..5739d27c050d 100644 --- a/src/backend/catalog/pg_collation.c +++ b/src/backend/catalog/pg_collation.c @@ -3,7 +3,7 @@ * pg_collation.c * routines to support manipulation of the pg_collation relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 9df0435cb626..7ff9b1de3b1c 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -3,7 +3,7 @@ * pg_constraint.c * routines to support manipulation of the pg_constraint relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -93,6 +93,8 @@ CreateConstraintEntry(const char *constraintName, NameData cname; int i; ObjectAddress conobject; + ObjectAddresses *addrs_auto; + ObjectAddresses *addrs_normal; conDesc = table_open(ConstraintRelationId, RowExclusiveLock); @@ -230,6 +232,9 @@ CreateConstraintEntry(const char *constraintName, table_close(conDesc, RowExclusiveLock); + /* Handle set of auto dependencies */ + addrs_auto = new_object_addresses(); + if (OidIsValid(relId)) { /* @@ -244,13 +249,13 @@ CreateConstraintEntry(const char *constraintName, { ObjectAddressSubSet(relobject, RelationRelationId, relId, constraintKey[i]); - recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO); + add_exact_object_address(&relobject, addrs_auto); } } else { ObjectAddressSet(relobject, RelationRelationId, relId); - recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO); + add_exact_object_address(&relobject, addrs_auto); } } @@ -262,9 +267,16 @@ CreateConstraintEntry(const char *constraintName, ObjectAddress domobject; ObjectAddressSet(domobject, TypeRelationId, domainId); - recordDependencyOn(&conobject, &domobject, DEPENDENCY_AUTO); + add_exact_object_address(&domobject, addrs_auto); } + record_object_address_dependencies(&conobject, addrs_auto, + DEPENDENCY_AUTO); + free_object_addresses(addrs_auto); + + /* Handle set of normal dependencies */ + addrs_normal = new_object_addresses(); + if (OidIsValid(foreignRelId)) { /* @@ -279,13 +291,13 @@ CreateConstraintEntry(const char *constraintName, { ObjectAddressSubSet(relobject, RelationRelationId, foreignRelId, foreignKey[i]); - recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL); + add_exact_object_address(&relobject, addrs_normal); } } else { ObjectAddressSet(relobject, RelationRelationId, foreignRelId); - recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL); + add_exact_object_address(&relobject, addrs_normal); } } @@ -300,7 +312,7 @@ CreateConstraintEntry(const char *constraintName, ObjectAddress relobject; ObjectAddressSet(relobject, RelationRelationId, indexRelId); - recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL); + add_exact_object_address(&relobject, addrs_normal); } if (foreignNKeys > 0) @@ -319,20 +331,24 @@ CreateConstraintEntry(const char *constraintName, for (i = 0; i < foreignNKeys; i++) { oprobject.objectId = pfEqOp[i]; - recordDependencyOn(&conobject, &oprobject, DEPENDENCY_NORMAL); + add_exact_object_address(&oprobject, addrs_normal); if (ppEqOp[i] != pfEqOp[i]) { oprobject.objectId = ppEqOp[i]; - recordDependencyOn(&conobject, &oprobject, DEPENDENCY_NORMAL); + add_exact_object_address(&oprobject, addrs_normal); } if (ffEqOp[i] != pfEqOp[i]) { oprobject.objectId = ffEqOp[i]; - recordDependencyOn(&conobject, &oprobject, DEPENDENCY_NORMAL); + add_exact_object_address(&oprobject, addrs_normal); } } } + record_object_address_dependencies(&conobject, addrs_normal, + DEPENDENCY_NORMAL); + free_object_addresses(addrs_normal); + /* * We don't bother to register dependencies on the exclusion operators of * an exclusion constraint. We assume they are members of the opclass diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index d1b616740bf6..d51be8290181 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -3,7 +3,7 @@ * pg_conversion.c * routines to support manipulation of the pg_conversion relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c index 8887ab3f4e1c..d08229f73380 100644 --- a/src/backend/catalog/pg_db_role_setting.c +++ b/src/backend/catalog/pg_db_role_setting.c @@ -2,7 +2,7 @@ * pg_db_role_setting.c * Routines to support manipulation of the pg_db_role_setting relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c index 2655f73eaed4..62cbf7a5ba07 100644 --- a/src/backend/catalog/pg_depend.c +++ b/src/backend/catalog/pg_depend.c @@ -3,7 +3,7 @@ * pg_depend.c * routines to support manipulation of the pg_depend relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -59,10 +59,11 @@ recordMultipleDependencies(const ObjectAddress *depender, { Relation dependDesc; CatalogIndexState indstate; - HeapTuple tup; - int i; - bool nulls[Natts_pg_depend]; - Datum values[Natts_pg_depend]; + TupleTableSlot **slot; + int i, + max_slots, + slot_init_count, + slot_stored_count; if (nreferenced <= 0) return; /* nothing to do */ @@ -76,11 +77,21 @@ recordMultipleDependencies(const ObjectAddress *depender, dependDesc = table_open(DependRelationId, RowExclusiveLock); + /* + * Allocate the slots to use, but delay costly initialization until we + * know that they will be used. + */ + max_slots = Min(nreferenced, + MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_depend)); + slot = palloc(sizeof(TupleTableSlot *) * max_slots); + /* Don't open indexes unless we need to make an update */ indstate = NULL; - memset(nulls, false, sizeof(nulls)); - + /* number of slots currently storing tuples */ + slot_stored_count = 0; + /* number of slots currently initialized */ + slot_init_count = 0; for (i = 0; i < nreferenced; i++, referenced++) { /* @@ -88,38 +99,69 @@ recordMultipleDependencies(const ObjectAddress *depender, * need to record dependencies on it. This saves lots of space in * pg_depend, so it's worth the time taken to check. */ - if (!isObjectPinned(referenced, dependDesc)) - { - /* - * Record the Dependency. Note we don't bother to check for - * duplicate dependencies; there's no harm in them. - */ - values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId); - values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId); - values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId); - - values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId); - values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId); - values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId); + if (isObjectPinned(referenced, dependDesc)) + continue; - values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior); + if (slot_init_count < max_slots) + { + slot[slot_stored_count] = MakeSingleTupleTableSlot(RelationGetDescr(dependDesc), + &TTSOpsHeapTuple); + slot_init_count++; + } - tup = heap_form_tuple(dependDesc->rd_att, values, nulls); + ExecClearTuple(slot[slot_stored_count]); + /* + * Record the dependency. Note we don't bother to check for duplicate + * dependencies; there's no harm in them. + */ + slot[slot_stored_count]->tts_values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId); + slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId); + slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId); + slot[slot_stored_count]->tts_values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior); + slot[slot_stored_count]->tts_values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId); + slot[slot_stored_count]->tts_values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId); + slot[slot_stored_count]->tts_values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId); + + memset(slot[slot_stored_count]->tts_isnull, false, + slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool)); + + ExecStoreVirtualTuple(slot[slot_stored_count]); + slot_stored_count++; + + /* If slots are full, insert a batch of tuples */ + if (slot_stored_count == max_slots) + { /* fetch index info only when we know we need it */ if (indstate == NULL) indstate = CatalogOpenIndexes(dependDesc); - CatalogTupleInsertWithInfo(dependDesc, tup, indstate); - - heap_freetuple(tup); + CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count, + indstate); + slot_stored_count = 0; } } + /* Insert any tuples left in the buffer */ + if (slot_stored_count > 0) + { + /* fetch index info only when we know we need it */ + if (indstate == NULL) + indstate = CatalogOpenIndexes(dependDesc); + + CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count, + indstate); + } + if (indstate != NULL) CatalogCloseIndexes(indstate); table_close(dependDesc, RowExclusiveLock); + + /* Drop only the number of slots used */ + for (i = 0; i < slot_init_count; i++) + ExecDropSingleTupleTableSlot(slot[i]); + pfree(slot); } /* @@ -542,7 +584,7 @@ changeDependenciesOf(Oid classId, Oid oldObjectId, while (HeapTupleIsValid((tup = systable_getnext(scan)))) { - Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup); + Form_pg_depend depform; /* make a modifiable copy */ tup = heap_copytuple(tup); @@ -625,12 +667,12 @@ changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, while (HeapTupleIsValid((tup = systable_getnext(scan)))) { - Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup); - if (newIsPinned) CatalogTupleDelete(depRel, &tup->t_self); else { + Form_pg_depend depform; + /* make a modifiable copy */ tup = heap_copytuple(tup); depform = (Form_pg_depend) GETSTRUCT(tup); @@ -950,75 +992,6 @@ getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok) return linitial_oid(seqlist); } -/* - * get_constraint_index - * Given the OID of a unique, primary-key, or exclusion constraint, - * return the OID of the underlying index. - * - * Return InvalidOid if the index couldn't be found; this suggests the - * given OID is bogus, but we leave it to caller to decide what to do. - */ -Oid -get_constraint_index(Oid constraintId) -{ - Oid indexId = InvalidOid; - Relation depRel; - ScanKeyData key[3]; - SysScanDesc scan; - HeapTuple tup; - - /* Search the dependency table for the dependent index */ - depRel = table_open(DependRelationId, AccessShareLock); - - ScanKeyInit(&key[0], - Anum_pg_depend_refclassid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(ConstraintRelationId)); - ScanKeyInit(&key[1], - Anum_pg_depend_refobjid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(constraintId)); - ScanKeyInit(&key[2], - Anum_pg_depend_refobjsubid, - BTEqualStrategyNumber, F_INT4EQ, - Int32GetDatum(0)); - - scan = systable_beginscan(depRel, DependReferenceIndexId, true, - NULL, 3, key); - - while (HeapTupleIsValid(tup = systable_getnext(scan))) - { - Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup); - - /* - * We assume any internal dependency of an index on the constraint - * must be what we are looking for. - */ - if (deprec->classid == RelationRelationId && - deprec->objsubid == 0 && - deprec->deptype == DEPENDENCY_INTERNAL) - { - char relkind = get_rel_relkind(deprec->objid); - - /* - * This is pure paranoia; there shouldn't be any other relkinds - * dependent on a constraint. - */ - if (relkind != RELKIND_INDEX && - relkind != RELKIND_PARTITIONED_INDEX) - continue; - - indexId = deprec->objid; - break; - } - } - - systable_endscan(scan); - table_close(depRel, AccessShareLock); - - return indexId; -} - /* * get_index_constraint * Given the OID of an index, return the OID of the owning unique, diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index 34403eda2426..c17975e4a924 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -3,7 +3,7 @@ * pg_enum.c * routines to support manipulation of the pg_enum relation * - * Copyright (c) 2006-2020, PostgreSQL Global Development Group + * Copyright (c) 2006-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -44,10 +44,11 @@ Oid binary_upgrade_next_pg_enum_oid = InvalidOid; * committed; otherwise, they might get into indexes where we can't clean * them up, and then if the transaction rolls back we have a broken index. * (See comments for check_safe_enum_use() in enum.c.) Values created by - * EnumValuesCreate are *not* blacklisted; we assume those are created during - * CREATE TYPE, so they can't go away unless the enum type itself does. + * EnumValuesCreate are *not* entered into the table; we assume those are + * created during CREATE TYPE, so they can't go away unless the enum type + * itself does. */ -static HTAB *enum_blacklist = NULL; +static HTAB *uncommitted_enums = NULL; static void RenumberEnumType(Relation pg_enum, HeapTuple *existing, int nelems); static int sort_order_cmp(const void *p1, const void *p2); @@ -146,7 +147,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("invalid enum label \"%s\"", lab), - errdetail("Labels must be %d characters or less.", + errdetail("Labels must be %d bytes or less.", NAMEDATALEN - 1))); values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(oids[elemno]); @@ -202,21 +203,20 @@ EnumValuesDelete(Oid enumTypeOid) } /* - * Initialize the enum blacklist for this transaction. + * Initialize the uncommitted enum table for this transaction. */ static void -init_enum_blacklist(void) +init_uncommitted_enums(void) { HASHCTL hash_ctl; - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(Oid); hash_ctl.hcxt = TopTransactionContext; - enum_blacklist = hash_create("Enum value blacklist", - 32, - &hash_ctl, - HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + uncommitted_enums = hash_create("Uncommitted enums", + 32, + &hash_ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); } /* @@ -249,7 +249,7 @@ AddEnumLabel(Oid enumTypeOid, ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("invalid enum label \"%s\"", newVal), - errdetail("Labels must be %d characters or less.", + errdetail("Labels must be %d bytes or less.", NAMEDATALEN - 1))); /* @@ -501,12 +501,12 @@ AddEnumLabel(Oid enumTypeOid, table_close(pg_enum, RowExclusiveLock); - /* Set up the blacklist hash if not already done in this transaction */ - if (enum_blacklist == NULL) - init_enum_blacklist(); + /* Set up the uncommitted enum table if not already done in this tx */ + if (uncommitted_enums == NULL) + init_uncommitted_enums(); - /* Add the new value to the blacklist */ - (void) hash_search(enum_blacklist, &newOid, HASH_ENTER, NULL); + /* Add the new value to the table */ + (void) hash_search(uncommitted_enums, &newOid, HASH_ENTER, NULL); } @@ -533,7 +533,7 @@ RenameEnumLabel(Oid enumTypeOid, ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("invalid enum label \"%s\"", newVal), - errdetail("Labels must be %d characters or less.", + errdetail("Labels must be %d bytes or less.", NAMEDATALEN - 1))); /* @@ -595,19 +595,19 @@ RenameEnumLabel(Oid enumTypeOid, /* - * Test if the given enum value is on the blacklist + * Test if the given enum value is in the table of uncommitted enums. */ bool -EnumBlacklisted(Oid enum_id) +EnumUncommitted(Oid enum_id) { bool found; - /* If we've made no blacklist table, all values are safe */ - if (enum_blacklist == NULL) + /* If we've made no uncommitted table, all values are safe */ + if (uncommitted_enums == NULL) return false; /* Else, is it in the table? */ - (void) hash_search(enum_blacklist, &enum_id, HASH_FIND, &found); + (void) hash_search(uncommitted_enums, &enum_id, HASH_FIND, &found); return found; } @@ -619,11 +619,11 @@ void AtEOXact_Enum(void) { /* - * Reset the blacklist table, as all our enum values are now committed. + * Reset the uncommitted table, as all our enum values are now committed. * The memory will go away automatically when TopTransactionContext is * freed; it's sufficient to clear our pointer. */ - enum_blacklist = NULL; + uncommitted_enums = NULL; } @@ -702,12 +702,12 @@ sort_order_cmp(const void *p1, const void *p2) } Size -EstimateEnumBlacklistSpace(void) +EstimateUncommittedEnumsSpace(void) { size_t entries; - if (enum_blacklist) - entries = hash_get_num_entries(enum_blacklist); + if (uncommitted_enums) + entries = hash_get_num_entries(uncommitted_enums); else entries = 0; @@ -716,7 +716,7 @@ EstimateEnumBlacklistSpace(void) } void -SerializeEnumBlacklist(void *space, Size size) +SerializeUncommittedEnums(void *space, Size size) { Oid *serialized = (Oid *) space; @@ -724,15 +724,15 @@ SerializeEnumBlacklist(void *space, Size size) * Make sure the hash table hasn't changed in size since the caller * reserved the space. */ - Assert(size == EstimateEnumBlacklistSpace()); + Assert(size == EstimateUncommittedEnumsSpace()); /* Write out all the values from the hash table, if there is one. */ - if (enum_blacklist) + if (uncommitted_enums) { HASH_SEQ_STATUS status; Oid *value; - hash_seq_init(&status, enum_blacklist); + hash_seq_init(&status, uncommitted_enums); while ((value = (Oid *) hash_seq_search(&status))) *serialized++ = *value; } @@ -748,11 +748,11 @@ SerializeEnumBlacklist(void *space, Size size) } void -RestoreEnumBlacklist(void *space) +RestoreUncommittedEnums(void *space) { Oid *serialized = (Oid *) space; - Assert(!enum_blacklist); + Assert(!uncommitted_enums); /* * As a special case, if the list is empty then don't even bother to @@ -763,9 +763,9 @@ RestoreEnumBlacklist(void *space) return; /* Read all the values into a new hash table. */ - init_enum_blacklist(); + init_uncommitted_enums(); do { - hash_search(enum_blacklist, serialized++, HASH_ENTER, NULL); + hash_search(uncommitted_enums, serialized++, HASH_ENTER, NULL); } while (OidIsValid(*serialized)); } diff --git a/src/backend/catalog/pg_extprotocol.c b/src/backend/catalog/pg_extprotocol.c index 5605cee03bba..c67ac9ba5c7f 100644 --- a/src/backend/catalog/pg_extprotocol.c +++ b/src/backend/catalog/pg_extprotocol.c @@ -215,7 +215,7 @@ ValidateProtocolFunction(List *fnName, ExtPtcFuncType fntype) * the function. */ fdresult = func_get_detail(fnName, NIL, NIL, - nargs, inputTypes, false, false, + nargs, inputTypes, false, false, false, &fnOid, &actual_rettype, &retset, &nvargs, &vatype, &true_oid_array, NULL); diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c index 2c4c6445e919..24d1d78a7aae 100644 --- a/src/backend/catalog/pg_inherits.c +++ b/src/backend/catalog/pg_inherits.c @@ -3,12 +3,12 @@ * pg_inherits.c * routines to support manipulation of the pg_inherits relation * - * Note: currently, this module only contains inquiry functions; the actual - * creation and deletion of pg_inherits entries is done in tablecmds.c. + * Note: currently, this module mostly contains inquiry functions; actual + * creation and deletion of pg_inherits entries is mostly done in tablecmds.c. * Perhaps someday that code should be moved here, but it'd have to be * disentangled from other stuff such as pg_depend updates. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -30,6 +30,7 @@ #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/snapmgr.h" #include "utils/syscache.h" /* @@ -51,9 +52,38 @@ typedef struct SeenRelsEntry * given rel; caller should already have locked it). If lockmode is NoLock * then no locks are acquired, but caller must beware of race conditions * against possible DROPs of child relations. + * + * Partitions marked as being detached are omitted; see + * find_inheritance_children_extended for details. */ List * find_inheritance_children(Oid parentrelId, LOCKMODE lockmode) +{ + return find_inheritance_children_extended(parentrelId, true, lockmode, + NULL, NULL); +} + +/* + * find_inheritance_children_extended + * + * As find_inheritance_children, with more options regarding detached + * partitions. + * + * If a partition's pg_inherits row is marked "detach pending", + * *detached_exist (if not null) is set true. + * + * If omit_detached is true and there is an active snapshot (not the same as + * the catalog snapshot used to scan pg_inherits!) and a pg_inherits tuple + * marked "detach pending" is visible to that snapshot, then that partition is + * omitted from the output list. This makes partitions invisible depending on + * whether the transaction that marked those partitions as detached appears + * committed to the active snapshot. In addition, *detached_xmin (if not null) + * is set to the xmin of the row of the detached partition. + */ +List * +find_inheritance_children_extended(Oid parentrelId, bool omit_detached, + LOCKMODE lockmode, bool *detached_exist, + TransactionId *detached_xmin) { List *list = NIL; Relation relation; @@ -92,6 +122,64 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode) while ((inheritsTuple = systable_getnext(scan)) != NULL) { + /* + * Cope with partitions concurrently being detached. When we see a + * partition marked "detach pending", we omit it from the returned set + * of visible partitions if caller requested that and the tuple's xmin + * does not appear in progress to the active snapshot. (If there's no + * active snapshot set, that means we're not running a user query, so + * it's OK to always include detached partitions in that case; if the + * xmin is still running to the active snapshot, then the partition + * has not been detached yet and so we include it.) + * + * The reason for this hack is that we want to avoid seeing the + * partition as alive in RI queries during REPEATABLE READ or + * SERIALIZABLE transactions: such queries use a different snapshot + * than the one used by regular (user) queries. + */ + if (((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhdetachpending) + { + if (detached_exist) + *detached_exist = true; + + if (omit_detached && ActiveSnapshotSet()) + { + TransactionId xmin; + Snapshot snap; + + xmin = HeapTupleHeaderGetXmin(inheritsTuple->t_data); + snap = GetActiveSnapshot(); + + if (XidInMVCCSnapshot(xmin, snap, false, NULL) == XID_NOT_IN_SNAPSHOT) + { + if (detached_xmin) + { + /* + * Two detached partitions should not occur (see + * checks in MarkInheritDetached), but if they do, + * track the newer of the two. Make sure to warn the + * user, so that they can clean up. Since this is + * just a cross-check against potentially corrupt + * catalogs, we don't make it a full-fledged error + * message. + */ + if (*detached_xmin != InvalidTransactionId) + { + elog(WARNING, "more than one partition pending detach found for table with OID %u", + parentrelId); + if (TransactionIdFollows(xmin, *detached_xmin)) + *detached_xmin = xmin; + } + else + *detached_xmin = xmin; + } + + /* Don't add the partition to the output list */ + continue; + } + } + } + inhrelid = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhrelid; if (numoids >= maxoids) { @@ -189,6 +277,9 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode) * given rel; caller should already have locked it). If lockmode is NoLock * then no locks are acquired, but caller must beware of race conditions * against possible DROPs of child relations. + * + * NB - No current callers of this routine are interested in children being + * concurrently detached, so there's no provision to include them. */ List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents) @@ -200,7 +291,6 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents) *rel_numparents; ListCell *l; - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(SeenRelsEntry); ctl.hcxt = CurrentMemoryContext; @@ -307,9 +397,11 @@ has_subclass(Oid relationId) } /* - * has_superclass - does this relation inherit from another? The caller - * should hold a lock on the given relation so that it can't be concurrently - * added to or removed from an inheritance hierarchy. + * has_superclass - does this relation inherit from another? + * + * Unlike has_subclass, this can be relied on to give an accurate answer. + * However, the caller must hold a lock on the given relation so that it + * can't be concurrently added to or removed from an inheritance hierarchy. */ bool has_superclass(Oid relationId) @@ -458,6 +550,7 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber) values[Anum_pg_inherits_inhrelid - 1] = ObjectIdGetDatum(relationId); values[Anum_pg_inherits_inhparent - 1] = ObjectIdGetDatum(parentOid); values[Anum_pg_inherits_inhseqno - 1] = Int32GetDatum(seqNumber); + values[Anum_pg_inherits_inhdetachpending - 1] = BoolGetDatum(false); memset(nulls, 0, sizeof(nulls)); @@ -477,10 +570,17 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber) * as InvalidOid, in which case all tuples matching inhrelid are deleted; * otherwise only delete tuples with the specified inhparent. * + * expect_detach_pending is the expected state of the inhdetachpending flag. + * If the catalog row does not match that state, an error is raised. + * + * childname is the partition name, if a table; pass NULL for regular + * inheritance or when working with other relation kinds. + * * Returns whether at least one row was deleted. */ bool -DeleteInheritsTuple(Oid inhrelid, Oid inhparent) +DeleteInheritsTuple(Oid inhrelid, Oid inhparent, bool expect_detach_pending, + const char *childname) { bool found = false; Relation catalogRelation; @@ -507,6 +607,29 @@ DeleteInheritsTuple(Oid inhrelid, Oid inhparent) parent = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhparent; if (!OidIsValid(inhparent) || parent == inhparent) { + bool detach_pending; + + detach_pending = + ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhdetachpending; + + /* + * Raise error depending on state. This should only happen for + * partitions, but we have no way to cross-check. + */ + if (detach_pending && !expect_detach_pending) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot detach partition \"%s\"", + childname ? childname : "unknown relation"), + errdetail("The partition is being detached concurrently or has an unfinished detach."), + errhint("Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation."))); + if (!detach_pending && expect_detach_pending) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot complete detaching partition \"%s\"", + childname ? childname : "unknown relation"), + errdetail("There's no pending concurrent detach."))); + CatalogTupleDelete(catalogRelation, &inheritsTuple->t_self); found = true; } @@ -518,3 +641,46 @@ DeleteInheritsTuple(Oid inhrelid, Oid inhparent) return found; } + +/* + * Return whether the pg_inherits tuple for a partition has the "detach + * pending" flag set. + */ +bool +PartitionHasPendingDetach(Oid partoid) +{ + Relation catalogRelation; + ScanKeyData key; + SysScanDesc scan; + HeapTuple inheritsTuple; + + /* We don't have a good way to verify it is in fact a partition */ + + /* + * Find the pg_inherits entry by inhrelid. (There should only be one.) + */ + catalogRelation = table_open(InheritsRelationId, RowExclusiveLock); + ScanKeyInit(&key, + Anum_pg_inherits_inhrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(partoid)); + scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, + true, NULL, 1, &key); + + while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan))) + { + bool detached; + + detached = + ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhdetachpending; + + /* Done */ + systable_endscan(scan); + table_close(catalogRelation, RowExclusiveLock); + + return detached; + } + + elog(ERROR, "relation %u is not a partition", partoid); + return false; /* keep compiler quiet */ +} diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c index ae9365e3a033..047bc6883cdd 100644 --- a/src/backend/catalog/pg_largeobject.c +++ b/src/backend/catalog/pg_largeobject.c @@ -3,7 +3,7 @@ * pg_largeobject.c * routines to support manipulation of the pg_largeobject relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c index d41196c70e48..eef2b44dcfe9 100644 --- a/src/backend/catalog/pg_namespace.c +++ b/src/backend/catalog/pg_namespace.c @@ -3,7 +3,7 @@ * pg_namespace.c * routines to support manipulation of the pg_namespace relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -109,7 +109,7 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp) /* dependency on owner */ recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId); - /* dependences on roles mentioned in default ACL */ + /* dependencies on roles mentioned in default ACL */ recordDependencyOnNewAcl(NamespaceRelationId, nspoid, 0, ownerId, nspacl); /* dependency on extension ... but not for magic temp schemas */ diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index a65e9a49226f..45d3b279f6ff 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -3,7 +3,7 @@ * pg_operator.c * routines to support manipulation of the pg_operator relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -250,7 +250,7 @@ OperatorShellMake(const char *operatorName, values[Anum_pg_operator_oprname - 1] = NameGetDatum(&oname); values[Anum_pg_operator_oprnamespace - 1] = ObjectIdGetDatum(operatorNamespace); values[Anum_pg_operator_oprowner - 1] = ObjectIdGetDatum(GetUserId()); - values[Anum_pg_operator_oprkind - 1] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); + values[Anum_pg_operator_oprkind - 1] = CharGetDatum(leftTypeId ? 'b' : 'l'); values[Anum_pg_operator_oprcanmerge - 1] = BoolGetDatum(false); values[Anum_pg_operator_oprcanhash - 1] = BoolGetDatum(false); values[Anum_pg_operator_oprleft - 1] = ObjectIdGetDatum(leftTypeId); @@ -499,7 +499,7 @@ OperatorCreate(const char *operatorName, values[Anum_pg_operator_oprname - 1] = NameGetDatum(&oname); values[Anum_pg_operator_oprnamespace - 1] = ObjectIdGetDatum(operatorNamespace); values[Anum_pg_operator_oprowner - 1] = ObjectIdGetDatum(GetUserId()); - values[Anum_pg_operator_oprkind - 1] = CharGetDatum(leftTypeId ? (rightTypeId ? 'b' : 'r') : 'l'); + values[Anum_pg_operator_oprkind - 1] = CharGetDatum(leftTypeId ? 'b' : 'l'); values[Anum_pg_operator_oprcanmerge - 1] = BoolGetDatum(canMerge); values[Anum_pg_operator_oprcanhash - 1] = BoolGetDatum(canHash); values[Anum_pg_operator_oprleft - 1] = ObjectIdGetDatum(leftTypeId); @@ -782,6 +782,7 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate) Form_pg_operator oper = (Form_pg_operator) GETSTRUCT(tuple); ObjectAddress myself, referenced; + ObjectAddresses *addrs; ObjectAddressSet(myself, OperatorRelationId, oper->oid); @@ -795,32 +796,34 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate) deleteSharedDependencyRecordsFor(myself.classId, myself.objectId, 0); } + addrs = new_object_addresses(); + /* Dependency on namespace */ if (OidIsValid(oper->oprnamespace)) { ObjectAddressSet(referenced, NamespaceRelationId, oper->oprnamespace); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Dependency on left type */ if (OidIsValid(oper->oprleft)) { ObjectAddressSet(referenced, TypeRelationId, oper->oprleft); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Dependency on right type */ if (OidIsValid(oper->oprright)) { ObjectAddressSet(referenced, TypeRelationId, oper->oprright); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Dependency on result type */ if (OidIsValid(oper->oprresult)) { ObjectAddressSet(referenced, TypeRelationId, oper->oprresult); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* @@ -836,23 +839,26 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate) if (OidIsValid(oper->oprcode)) { ObjectAddressSet(referenced, ProcedureRelationId, oper->oprcode); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Dependency on restriction selectivity function */ if (OidIsValid(oper->oprrest)) { ObjectAddressSet(referenced, ProcedureRelationId, oper->oprrest); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* Dependency on join selectivity function */ if (OidIsValid(oper->oprjoin)) { ObjectAddressSet(referenced, ProcedureRelationId, oper->oprjoin); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + /* Dependency on owner */ recordDependencyOnOwner(OperatorRelationId, oper->oid, oper->oprowner); diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index ed80f447a179..29cb6dff0c1b 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -3,7 +3,7 @@ * pg_proc.c * routines to support manipulation of the pg_proc relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -38,6 +38,7 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" +#include "parser/analyze.h" #include "parser/parse_coerce.h" #include "parser/parse_type.h" #include "tcop/pquery.h" @@ -85,6 +86,7 @@ ProcedureCreate(const char *procedureName, Oid describeFuncOid, const char *prosrc, const char *probin, + Node *prosqlbody, char prokind, bool security_definer, bool isLeakProof, @@ -125,6 +127,7 @@ ProcedureCreate(const char *procedureName, char *detailmsg; int i; Oid trfid; + ObjectAddresses *addrs; /* * sanity checks @@ -259,6 +262,9 @@ ProcedureCreate(const char *procedureName, elog(ERROR, "variadic parameter must be last"); break; case PROARGMODE_OUT: + if (OidIsValid(variadicType) && prokind == PROKIND_PROCEDURE) + elog(ERROR, "variadic parameter must be last"); + break; case PROARGMODE_TABLE: /* okay */ break; @@ -346,6 +352,10 @@ ProcedureCreate(const char *procedureName, values[Anum_pg_proc_probin - 1] = CStringGetTextDatum(probin); else nulls[Anum_pg_proc_probin - 1] = true; + if (prosqlbody) + values[Anum_pg_proc_prosqlbody - 1] = CStringGetTextDatum(nodeToString(prosqlbody)); + else + nulls[Anum_pg_proc_prosqlbody - 1] = true; if (proconfig != PointerGetDatum(NULL)) values[Anum_pg_proc_proconfig - 1] = proconfig; else @@ -650,19 +660,21 @@ ProcedureCreate(const char *procedureName, deleteProcCallbacks(retval); } + addrs = new_object_addresses(); + ObjectAddressSet(myself, ProcedureRelationId, retval); /* dependency on namespace */ ObjectAddressSet(referenced, NamespaceRelationId, procNamespace); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); /* dependency on implementation language */ ObjectAddressSet(referenced, LanguageRelationId, languageObjectId); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); /* dependency on return type */ ObjectAddressSet(referenced, TypeRelationId, returnType); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); /* dependency on describe function */ if (OidIsValid(describeFuncOid)) @@ -678,35 +690,42 @@ ProcedureCreate(const char *procedureName, if ((trfid = get_transform_oid(returnType, languageObjectId, true))) { ObjectAddressSet(referenced, TransformRelationId, trfid); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } /* dependency on parameter types */ for (i = 0; i < allParamCount; i++) { ObjectAddressSet(referenced, TypeRelationId, allParams[i]); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); /* dependency on transform used by parameter type, if any */ if ((trfid = get_transform_oid(allParams[i], languageObjectId, true))) { ObjectAddressSet(referenced, TransformRelationId, trfid); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } } - /* dependency on parameter default expressions */ - if (parameterDefaults) - recordDependencyOnExpr(&myself, (Node *) parameterDefaults, - NIL, DEPENDENCY_NORMAL); - /* dependency on support function, if any */ if (OidIsValid(prosupport)) { ObjectAddressSet(referenced, ProcedureRelationId, prosupport); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + + /* dependency on SQL routine body */ + if (languageObjectId == SQLlanguageId && prosqlbody) + recordDependencyOnExpr(&myself, prosqlbody, NIL, DEPENDENCY_NORMAL); + + /* dependency on parameter default expressions */ + if (parameterDefaults) + recordDependencyOnExpr(&myself, (Node *) parameterDefaults, + NIL, DEPENDENCY_NORMAL); + /* dependency on owner */ if (!is_update) recordDependencyOnOwner(ProcedureRelationId, retval, proowner); @@ -942,44 +961,63 @@ fmgr_sql_validator(PG_FUNCTION_ARGS) sqlerrcontext.previous = error_context_stack; error_context_stack = &sqlerrcontext; - /* - * We can't do full prechecking of the function definition if there - * are any polymorphic input types, because actual datatypes of - * expression results will be unresolvable. The check will be done at - * runtime instead. - * - * We can run the text through the raw parser though; this will at - * least catch silly syntactic errors. - */ - raw_parsetree_list = pg_parse_query(prosrc); + /* If we have prosqlbody, pay attention to that not prosrc */ + tmp = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_prosqlbody, &isnull); + if (!isnull) + { + Node *n; - if (!haspolyarg) + n = stringToNode(TextDatumGetCString(tmp)); + if (IsA(n, List)) + querytree_list = castNode(List, n); + else + querytree_list = list_make1(list_make1(n)); + } + else { /* - * OK to do full precheck: analyze and rewrite the queries, then - * verify the result type. + * We can't do full prechecking of the function definition if + * there are any polymorphic input types, because actual datatypes + * of expression results will be unresolvable. The check will be + * done at runtime instead. + * + * We can run the text through the raw parser though; this will at + * least catch silly syntactic errors. */ - SQLFunctionParseInfoPtr pinfo; - Oid rettype; - TupleDesc rettupdesc; - - /* But first, set up parameter information */ - pinfo = prepare_sql_fn_parse_info(tuple, NULL, InvalidOid); - + raw_parsetree_list = pg_parse_query(prosrc); querytree_list = NIL; - foreach(lc, raw_parsetree_list) + + if (!haspolyarg) { - RawStmt *parsetree = lfirst_node(RawStmt, lc); - List *querytree_sublist; - - querytree_sublist = pg_analyze_and_rewrite_params(parsetree, - prosrc, - (ParserSetupHook) sql_fn_parser_setup, - pinfo, - NULL); - querytree_list = list_concat(querytree_list, + /* + * OK to do full precheck: analyze and rewrite the queries, + * then verify the result type. + */ + SQLFunctionParseInfoPtr pinfo; + + /* But first, set up parameter information */ + pinfo = prepare_sql_fn_parse_info(tuple, NULL, InvalidOid); + + foreach(lc, raw_parsetree_list) + { + RawStmt *parsetree = lfirst_node(RawStmt, lc); + List *querytree_sublist; + + querytree_sublist = pg_analyze_and_rewrite_params(parsetree, + prosrc, + (ParserSetupHook) sql_fn_parser_setup, + pinfo, + NULL); + querytree_list = lappend(querytree_list, querytree_sublist); + } } + } + + if (!haspolyarg) + { + Oid rettype; + TupleDesc rettupdesc; check_sql_fn_statements(querytree_list); diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index 164d1a4d1269..0d9f176fb37e 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -3,7 +3,7 @@ * pg_publication.c * publication C API manipulation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -69,7 +69,7 @@ check_publication_add_relation(Relation targetrel) errdetail("System tables cannot be added to publications."))); /* UNLOGGED and TEMP relations cannot be part of publication. */ - if (!RelationNeedsWAL(targetrel)) + if (!RelationIsPermanent(targetrel)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("table \"%s\" cannot be replicated", diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c index b5bc36c2bd6b..839b65eb797d 100644 --- a/src/backend/catalog/pg_range.c +++ b/src/backend/catalog/pg_range.c @@ -3,7 +3,7 @@ * pg_range.c * routines to support manipulation of the pg_range relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,7 +35,7 @@ void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, Oid rangeSubOpclass, RegProcedure rangeCanonical, - RegProcedure rangeSubDiff) + RegProcedure rangeSubDiff, Oid multirangeTypeOid) { Relation pg_range; Datum values[Natts_pg_range]; @@ -43,6 +43,8 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, HeapTuple tup; ObjectAddress myself; ObjectAddress referenced; + ObjectAddress referencing; + ObjectAddresses *addrs; pg_range = table_open(RangeRelationId, RowExclusiveLock); @@ -54,6 +56,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, values[Anum_pg_range_rngsubopc - 1] = ObjectIdGetDatum(rangeSubOpclass); values[Anum_pg_range_rngcanonical - 1] = ObjectIdGetDatum(rangeCanonical); values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff); + values[Anum_pg_range_rngmultitypid - 1] = ObjectIdGetDatum(multirangeTypeOid); tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls); @@ -61,45 +64,43 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, heap_freetuple(tup); /* record type's dependencies on range-related items */ + addrs = new_object_addresses(); - myself.classId = TypeRelationId; - myself.objectId = rangeTypeOid; - myself.objectSubId = 0; + ObjectAddressSet(myself, TypeRelationId, rangeTypeOid); - referenced.classId = TypeRelationId; - referenced.objectId = rangeSubType; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, TypeRelationId, rangeSubType); + add_exact_object_address(&referenced, addrs); - referenced.classId = OperatorClassRelationId; - referenced.objectId = rangeSubOpclass; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, OperatorClassRelationId, rangeSubOpclass); + add_exact_object_address(&referenced, addrs); if (OidIsValid(rangeCollation)) { - referenced.classId = CollationRelationId; - referenced.objectId = rangeCollation; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, CollationRelationId, rangeCollation); + add_exact_object_address(&referenced, addrs); } if (OidIsValid(rangeCanonical)) { - referenced.classId = ProcedureRelationId; - referenced.objectId = rangeCanonical; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, ProcedureRelationId, rangeCanonical); + add_exact_object_address(&referenced, addrs); } if (OidIsValid(rangeSubDiff)) { - referenced.classId = ProcedureRelationId; - referenced.objectId = rangeSubDiff; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, ProcedureRelationId, rangeSubDiff); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + + /* record multirange type's dependency on the range type */ + referencing.classId = TypeRelationId; + referencing.objectId = multirangeTypeOid; + referencing.objectSubId = 0; + recordDependencyOn(&referencing, &myself, DEPENDENCY_INTERNAL); + table_close(pg_range, RowExclusiveLock); } diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c index 30b234e90e12..420ad965653e 100644 --- a/src/backend/catalog/pg_shdepend.c +++ b/src/backend/catalog/pg_shdepend.c @@ -3,7 +3,7 @@ * pg_shdepend.c * routines to support manipulation of the pg_shdepend relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -59,6 +59,7 @@ #include "commands/schemacmds.h" #include "commands/subscriptioncmds.h" #include "commands/tablecmds.h" +#include "commands/tablespace.h" #include "commands/typecmds.h" #include "miscadmin.h" #include "storage/lmgr.h" @@ -186,11 +187,14 @@ recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner) * * There must be no more than one existing entry for the given dependent * object and dependency type! So in practice this can only be used for - * updating SHARED_DEPENDENCY_OWNER entries, which should have that property. + * updating SHARED_DEPENDENCY_OWNER and SHARED_DEPENDENCY_TABLESPACE + * entries, which should have that property. * * If there is no previous entry, we assume it was referencing a PINned * object, so we create a new entry. If the new referenced object is * PINned, we don't create an entry (and drop the old one, if any). + * (For tablespaces, we don't record dependencies in certain cases, so + * there are other possible reasons for entries to be missing.) * * sdepRel must be the pg_shdepend relation, already opened and suitably * locked. @@ -344,6 +348,58 @@ changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId) table_close(sdepRel, RowExclusiveLock); } +/* + * recordDependencyOnTablespace + * + * A convenient wrapper of recordSharedDependencyOn -- register the specified + * tablespace as default for the given object. + * + * Note: it's the caller's responsibility to ensure that there isn't a + * tablespace entry for the object already. + */ +void +recordDependencyOnTablespace(Oid classId, Oid objectId, Oid tablespace) +{ + ObjectAddress myself, + referenced; + + ObjectAddressSet(myself, classId, objectId); + ObjectAddressSet(referenced, TableSpaceRelationId, tablespace); + + recordSharedDependencyOn(&myself, &referenced, + SHARED_DEPENDENCY_TABLESPACE); +} + +/* + * changeDependencyOnTablespace + * + * Update the shared dependencies to account for the new tablespace. + * + * Note: we don't need an objsubid argument because only whole objects + * have tablespaces. + */ +void +changeDependencyOnTablespace(Oid classId, Oid objectId, Oid newTablespaceId) +{ + Relation sdepRel; + + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); + + if (newTablespaceId != DEFAULTTABLESPACE_OID && + newTablespaceId != InvalidOid) + shdepChangeDep(sdepRel, + classId, objectId, 0, + TableSpaceRelationId, newTablespaceId, + SHARED_DEPENDENCY_TABLESPACE); + else + shdepDropDependency(sdepRel, + classId, objectId, 0, true, + InvalidOid, InvalidOid, + SHARED_DEPENDENCY_INVALID); + + table_close(sdepRel, RowExclusiveLock); +} + /* * getOidListDiff * Helper for updateAclDependencies. @@ -786,12 +842,6 @@ checkSharedDependencies(Oid classId, Oid objectId, } -/* - * Cap the maximum amount of bytes allocated for copyTemplateDependencies() - * slots. - */ -#define MAX_PGSHDEPEND_INSERT_BYTES 65535 - /* * copyTemplateDependencies * @@ -806,21 +856,20 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId) ScanKeyData key[1]; SysScanDesc scan; HeapTuple tup; - int slotCount; CatalogIndexState indstate; TupleTableSlot **slot; - int nslots, - max_slots; - bool slot_init = true; + int max_slots, + slot_init_count, + slot_stored_count; sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); sdepDesc = RelationGetDescr(sdepRel); /* - * Allocate the slots to use, but delay initialization until we know that - * they will be used. + * Allocate the slots to use, but delay costly initialization until we + * know that they will be used. */ - max_slots = MAX_PGSHDEPEND_INSERT_BYTES / sizeof(FormData_pg_shdepend); + max_slots = MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_shdepend); slot = palloc(sizeof(TupleTableSlot *) * max_slots); indstate = CatalogOpenIndexes(sdepRel); @@ -834,6 +883,11 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId) scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true, NULL, 1, key); + /* number of slots currently storing tuples */ + slot_stored_count = 0; + /* number of slots currently initialized */ + slot_init_count = 0; + /* * Copy the entries of the original database, changing the database Id to * that of the new database. Note that because we are not copying rows @@ -841,41 +895,42 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId) * copy the ownership dependency of the template database itself; this is * what we want. */ - slotCount = 0; while (HeapTupleIsValid(tup = systable_getnext(scan))) { Form_pg_shdepend shdep; - if (slot_init) - slot[slotCount] = MakeSingleTupleTableSlot(sdepDesc, &TTSOpsHeapTuple); + if (slot_init_count < max_slots) + { + slot[slot_stored_count] = MakeSingleTupleTableSlot(sdepDesc, &TTSOpsHeapTuple); + slot_init_count++; + } - ExecClearTuple(slot[slotCount]); + ExecClearTuple(slot[slot_stored_count]); shdep = (Form_pg_shdepend) GETSTRUCT(tup); - slot[slotCount]->tts_values[Anum_pg_shdepend_dbid] = ObjectIdGetDatum(newDbId); - slot[slotCount]->tts_values[Anum_pg_shdepend_classid] = shdep->classid; - slot[slotCount]->tts_values[Anum_pg_shdepend_objid] = shdep->objid; - slot[slotCount]->tts_values[Anum_pg_shdepend_objsubid] = shdep->objsubid; - slot[slotCount]->tts_values[Anum_pg_shdepend_refclassid] = shdep->refclassid; - slot[slotCount]->tts_values[Anum_pg_shdepend_refobjid] = shdep->refobjid; - slot[slotCount]->tts_values[Anum_pg_shdepend_deptype] = shdep->deptype; + slot[slot_stored_count]->tts_values[Anum_pg_shdepend_dbid] = ObjectIdGetDatum(newDbId); + slot[slot_stored_count]->tts_values[Anum_pg_shdepend_classid] = shdep->classid; + slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objid] = shdep->objid; + slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objsubid] = shdep->objsubid; + slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refclassid] = shdep->refclassid; + slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refobjid] = shdep->refobjid; + slot[slot_stored_count]->tts_values[Anum_pg_shdepend_deptype] = shdep->deptype; - ExecStoreVirtualTuple(slot[slotCount]); - slotCount++; + ExecStoreVirtualTuple(slot[slot_stored_count]); + slot_stored_count++; /* If slots are full, insert a batch of tuples */ - if (slotCount == max_slots) + if (slot_stored_count == max_slots) { - CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slotCount, indstate); - slotCount = 0; - slot_init = false; + CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate); + slot_stored_count = 0; } } /* Insert any tuples left in the buffer */ - if (slotCount > 0) - CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slotCount, indstate); + if (slot_stored_count > 0) + CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate); systable_endscan(scan); @@ -883,8 +938,7 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId) table_close(sdepRel, RowExclusiveLock); /* Drop only the number of slots used */ - nslots = slot_init ? slotCount : max_slots; - for (int i = 0; i < nslots; i++) + for (int i = 0; i < slot_init_count; i++) ExecDropSingleTupleTableSlot(slot[i]); pfree(slot); } @@ -1123,13 +1177,6 @@ shdepLockAndCheckObject(Oid classId, Oid objectId) objectId))); break; - /* - * Currently, this routine need not support any other shared - * object types besides roles. If we wanted to record explicit - * dependencies on databases or tablespaces, we'd need code along - * these lines: - */ -#ifdef NOT_USED case TableSpaceRelationId: { /* For lack of a syscache on pg_tablespace, do this: */ @@ -1143,7 +1190,6 @@ shdepLockAndCheckObject(Oid classId, Oid objectId) pfree(tablespace); break; } -#endif case DatabaseRelationId: { @@ -1203,6 +1249,8 @@ storeObjectDescription(StringInfo descs, appendStringInfo(descs, _("privileges for %s"), objdesc); else if (deptype == SHARED_DEPENDENCY_POLICY) appendStringInfo(descs, _("target of %s"), objdesc); + else if (deptype == SHARED_DEPENDENCY_TABLESPACE) + appendStringInfo(descs, _("tablespace for %s"), objdesc); else elog(ERROR, "unrecognized dependency type: %d", (int) deptype); diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c index 90bf5cf0c6de..29fc4218cd4b 100644 --- a/src/backend/catalog/pg_subscription.c +++ b/src/backend/catalog/pg_subscription.c @@ -3,7 +3,7 @@ * pg_subscription.c * replication subscriptions * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -29,6 +29,7 @@ #include "utils/array.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/lsyscache.h" #include "utils/pg_lsn.h" #include "utils/rel.h" #include "utils/syscache.h" @@ -66,6 +67,7 @@ GetSubscription(Oid subid, bool missing_ok) sub->owner = subform->subowner; sub->enabled = subform->subenabled; sub->binary = subform->subbinary; + sub->stream = subform->substream; /* Get conninfo */ datum = SysCacheGetAttr(SUBSCRIPTIONOID, @@ -327,18 +329,21 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state, /* * Get state of subscription table. * - * Returns SUBREL_STATE_UNKNOWN when not found and missing_ok is true. + * Returns SUBREL_STATE_UNKNOWN when the table is not in the subscription. */ char -GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn, - bool missing_ok) +GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn) { - Relation rel; HeapTuple tup; char substate; bool isnull; Datum d; + Relation rel; + /* + * This is to avoid the race condition with AlterSubscription which tries + * to remove this relstate. + */ rel = table_open(SubscriptionRelRelationId, AccessShareLock); /* Try finding the mapping. */ @@ -348,22 +353,15 @@ GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn, if (!HeapTupleIsValid(tup)) { - if (missing_ok) - { - table_close(rel, AccessShareLock); - *sublsn = InvalidXLogRecPtr; - return SUBREL_STATE_UNKNOWN; - } - - elog(ERROR, "subscription table %u in subscription %u does not exist", - relid, subid); + table_close(rel, AccessShareLock); + *sublsn = InvalidXLogRecPtr; + return SUBREL_STATE_UNKNOWN; } /* Get the state. */ - d = SysCacheGetAttr(SUBSCRIPTIONRELMAP, tup, - Anum_pg_subscription_rel_srsubstate, &isnull); - Assert(!isnull); - substate = DatumGetChar(d); + substate = ((Form_pg_subscription_rel) GETSTRUCT(tup))->srsubstate; + + /* Get the LSN */ d = SysCacheGetAttr(SUBSCRIPTIONRELMAP, tup, Anum_pg_subscription_rel_srsublsn, &isnull); if (isnull) @@ -373,6 +371,7 @@ GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn, /* Cleanup */ ReleaseSysCache(tup); + table_close(rel, AccessShareLock); return substate; @@ -415,6 +414,35 @@ RemoveSubscriptionRel(Oid subid, Oid relid) scan = table_beginscan_catalog(rel, nkeys, skey); while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) { + Form_pg_subscription_rel subrel; + + subrel = (Form_pg_subscription_rel) GETSTRUCT(tup); + + /* + * We don't allow to drop the relation mapping when the table + * synchronization is in progress unless the caller updates the + * corresponding subscription as well. This is to ensure that we don't + * leave tablesync slots or origins in the system when the + * corresponding table is dropped. + */ + if (!OidIsValid(subid) && subrel->srsubstate != SUBREL_STATE_READY) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not drop relation mapping for subscription \"%s\"", + get_subscription_name(subrel->srsubid, false)), + errdetail("Table synchronization for relation \"%s\" is in progress and is in state \"%c\".", + get_rel_name(relid), subrel->srsubstate), + + /* + * translator: first %s is a SQL ALTER command and second %s is a + * SQL DROP command + */ + errhint("Use %s to enable subscription if not already enabled or use %s to drop the subscription.", + "ALTER SUBSCRIPTION ... ENABLE", + "DROP SUBSCRIPTION ..."))); + } + CatalogTupleDelete(rel, &tup->t_self); } table_endscan(scan); @@ -434,19 +462,18 @@ GetSubscriptionRelations(Oid subid) List *res = NIL; Relation rel; HeapTuple tup; - int nkeys = 0; - ScanKeyData skey[2]; + ScanKeyData skey[1]; SysScanDesc scan; rel = table_open(SubscriptionRelRelationId, AccessShareLock); - ScanKeyInit(&skey[nkeys++], + ScanKeyInit(&skey[0], Anum_pg_subscription_rel_srsubid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(subid)); scan = systable_beginscan(rel, InvalidOid, false, - NULL, nkeys, skey); + NULL, 1, skey); while (HeapTupleIsValid(tup = systable_getnext(scan))) { diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index f58898ebc408..80cb57f6f005 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -3,7 +3,7 @@ * pg_type.c * routines to support manipulation of the pg_type relation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -31,6 +31,7 @@ #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "commands/typecmds.h" +#include "mb/pg_wchar.h" #include "miscadmin.h" #include "parser/scansup.h" #include "parser/parse_type.h" @@ -202,6 +203,11 @@ update_type_encoding(Oid typid, Datum typoptions) table_close(pgtypeenc, NoLock); } +static char *makeUniqueTypeName(const char *typeName, Oid typeNamespace, + bool tryOriginal); + +/* Potentially set by pg_upgrade_support functions */ +Oid binary_upgrade_next_pg_type_oid = InvalidOid; /* ---------------------------------------------------------------- * TypeShellMake @@ -266,6 +272,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) values[Anum_pg_type_typisdefined - 1] = BoolGetDatum(false); values[Anum_pg_type_typdelim - 1] = CharGetDatum(DEFAULT_TYPDELIM); values[Anum_pg_type_typrelid - 1] = ObjectIdGetDatum(InvalidOid); + values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(InvalidOid); values[Anum_pg_type_typelem - 1] = ObjectIdGetDatum(InvalidOid); values[Anum_pg_type_typarray - 1] = ObjectIdGetDatum(InvalidOid); values[Anum_pg_type_typinput - 1] = ObjectIdGetDatum(F_SHELL_IN); @@ -358,11 +365,12 @@ TypeCreate(Oid newTypeOid, Oid typmodinProcedure, Oid typmodoutProcedure, Oid analyzeProcedure, + Oid subscriptProcedure, Oid elementType, bool isImplicitArray, Oid arrayType, Oid baseType, - const char *defaultTypeValue, /* human readable rep */ + const char *defaultTypeValue, /* human-readable rep */ char *defaultTypeBin, /* cooked rep */ bool passedByValue, char alignment, @@ -507,6 +515,7 @@ TypeCreate(Oid newTypeOid, values[Anum_pg_type_typisdefined - 1] = BoolGetDatum(true); values[Anum_pg_type_typdelim - 1] = CharGetDatum(typDelim); values[Anum_pg_type_typrelid - 1] = ObjectIdGetDatum(relationOid); + values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(subscriptProcedure); values[Anum_pg_type_typelem - 1] = ObjectIdGetDatum(elementType); values[Anum_pg_type_typarray - 1] = ObjectIdGetDatum(arrayType); values[Anum_pg_type_typinput - 1] = ObjectIdGetDatum(inputProcedure); @@ -694,6 +703,7 @@ GenerateTypeDependencies(HeapTuple typeTuple, bool isNull; ObjectAddress myself, referenced; + ObjectAddresses *addrs_normal; /* Extract defaultExpr if caller didn't pass it */ if (defaultExpr == NULL) @@ -727,6 +737,10 @@ GenerateTypeDependencies(HeapTuple typeTuple, * Skip these for a dependent type, since it will have such dependencies * indirectly through its depended-on type or relation. */ + + /* placeholder for all normal dependencies */ + addrs_normal = new_object_addresses(); + if (!isDependentType) { ObjectAddressSet(referenced, NamespaceRelationId, @@ -742,49 +756,80 @@ GenerateTypeDependencies(HeapTuple typeTuple, recordDependencyOnCurrentExtension(&myself, rebuild); } - /* Normal dependencies on the I/O functions */ + /* Normal dependencies on the I/O and support functions */ if (OidIsValid(typeForm->typinput)) { ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typinput); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs_normal); } if (OidIsValid(typeForm->typoutput)) { ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typoutput); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs_normal); } if (OidIsValid(typeForm->typreceive)) { ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typreceive); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs_normal); } if (OidIsValid(typeForm->typsend)) { ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typsend); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs_normal); } if (OidIsValid(typeForm->typmodin)) { ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typmodin); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs_normal); } if (OidIsValid(typeForm->typmodout)) { ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typmodout); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs_normal); } if (OidIsValid(typeForm->typanalyze)) { ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typanalyze); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs_normal); + } + + if (OidIsValid(typeForm->typsubscript)) + { + ObjectAddressSet(referenced, ProcedureRelationId, typeForm->typsubscript); + add_exact_object_address(&referenced, addrs_normal); + } + + /* Normal dependency from a domain to its base type. */ + if (OidIsValid(typeForm->typbasetype)) + { + ObjectAddressSet(referenced, TypeRelationId, typeForm->typbasetype); + add_exact_object_address(&referenced, addrs_normal); + } + + /* + * Normal dependency from a domain to its collation. We know the default + * collation is pinned, so don't bother recording it. + */ + if (OidIsValid(typeForm->typcollation) && + typeForm->typcollation != DEFAULT_COLLATION_OID) + { + ObjectAddressSet(referenced, CollationRelationId, typeForm->typcollation); + add_exact_object_address(&referenced, addrs_normal); } + record_object_address_dependencies(&myself, addrs_normal, DEPENDENCY_NORMAL); + free_object_addresses(addrs_normal); + + /* Normal dependency on the default expression. */ + if (defaultExpr) + recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL); + /* * If the type is a rowtype for a relation, mark it as internally * dependent on the relation, *unless* it is a stand-alone composite type @@ -815,26 +860,6 @@ GenerateTypeDependencies(HeapTuple typeTuple, recordDependencyOn(&myself, &referenced, isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL); } - - /* Normal dependency from a domain to its base type. */ - if (OidIsValid(typeForm->typbasetype)) - { - ObjectAddressSet(referenced, TypeRelationId, typeForm->typbasetype); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); - } - - /* Normal dependency from a domain to its collation. */ - /* We know the default collation is pinned, so don't bother recording it */ - if (OidIsValid(typeForm->typcollation) && - typeForm->typcollation != DEFAULT_COLLATION_OID) - { - ObjectAddressSet(referenced, CollationRelationId, typeForm->typcollation); - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); - } - - /* Normal dependency on the default expression. */ - if (defaultExpr) - recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL); } /* @@ -924,31 +949,10 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace) char * makeArrayTypeName(const char *typeName, Oid typeNamespace) { - char *arr = (char *) palloc(NAMEDATALEN); - int namelen = strlen(typeName); - int i; + char *arr; - /* - * The idea is to prepend underscores as needed until we make a name that - * doesn't collide with anything... - */ - for (i = 1; i < NAMEDATALEN - 1; i++) - { - arr[i - 1] = '_'; - if (i + namelen < NAMEDATALEN) - strcpy(arr + i, typeName); - else - { - memcpy(arr + i, typeName, NAMEDATALEN - i); - truncate_identifier(arr, NAMEDATALEN, false); - } - if (!SearchSysCacheExists2(TYPENAMENSP, - CStringGetDatum(arr), - ObjectIdGetDatum(typeNamespace))) - break; - } - - if (i >= NAMEDATALEN - 1) + arr = makeUniqueTypeName(typeName, typeNamespace, false); + if (arr == NULL) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("could not form array type name for type \"%s\"", @@ -1020,3 +1024,89 @@ moveArrayTypeName(Oid typeOid, const char *typeName, Oid typeNamespace) return true; } + +/* + * makeMultirangeTypeName + * - given a range type name, make a multirange type name for it + * + * caller is responsible for pfreeing the result + */ +char * +makeMultirangeTypeName(const char *rangeTypeName, Oid typeNamespace) +{ + char *buf; + char *rangestr; + + /* + * If the range type name contains "range" then change that to + * "multirange". Otherwise add "_multirange" to the end. + */ + rangestr = strstr(rangeTypeName, "range"); + if (rangestr) + { + char *prefix = pnstrdup(rangeTypeName, rangestr - rangeTypeName); + + buf = psprintf("%s%s%s", prefix, "multi", rangestr); + } + else + buf = psprintf("%s_multirange", pnstrdup(rangeTypeName, NAMEDATALEN - 12)); + + /* clip it at NAMEDATALEN-1 bytes */ + buf[pg_mbcliplen(buf, strlen(buf), NAMEDATALEN - 1)] = '\0'; + + if (SearchSysCacheExists2(TYPENAMENSP, + CStringGetDatum(buf), + ObjectIdGetDatum(typeNamespace))) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("type \"%s\" already exists", buf), + errdetail("Failed while creating a multirange type for type \"%s\".", rangeTypeName), + errhint("You can manually specify a multirange type name using the \"multirange_type_name\" attribute"))); + + return pstrdup(buf); +} + +/* + * makeUniqueTypeName + * Generate a unique name for a prospective new type + * + * Given a typeName, return a new palloc'ed name by prepending underscores + * until a non-conflicting name results. + * + * If tryOriginal, first try with zero underscores. + */ +static char * +makeUniqueTypeName(const char *typeName, Oid typeNamespace, bool tryOriginal) +{ + int i; + int namelen; + char dest[NAMEDATALEN]; + + Assert(strlen(typeName) <= NAMEDATALEN - 1); + + if (tryOriginal && + !SearchSysCacheExists2(TYPENAMENSP, + CStringGetDatum(typeName), + ObjectIdGetDatum(typeNamespace))) + return pstrdup(typeName); + + /* + * The idea is to prepend underscores as needed until we make a name that + * doesn't collide with anything ... + */ + namelen = strlen(typeName); + for (i = 1; i < NAMEDATALEN - 1; i++) + { + dest[i - 1] = '_'; + strlcpy(dest + i, typeName, NAMEDATALEN - i); + if (namelen + i >= NAMEDATALEN) + truncate_identifier(dest, NAMEDATALEN, false); + + if (!SearchSysCacheExists2(TYPENAMENSP, + CStringGetDatum(dest), + ObjectIdGetDatum(typeNamespace))) + return pstrdup(dest); + } + + return NULL; +} diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt index e128b66a3de9..8a1b88f1bf0b 100644 --- a/src/backend/catalog/sql_features.txt +++ b/src/backend/catalog/sql_features.txt @@ -243,7 +243,7 @@ F312 MERGE statement NO consider INSERT ... ON CONFLICT DO UPDATE F313 Enhanced MERGE statement NO F314 MERGE statement with DELETE branch NO F321 User authorization YES -F341 Usage tables NO no ROUTINE_*_USAGE tables +F341 Usage tables YES F361 Subprogram support YES F381 Extended schema manipulation YES F381 Extended schema manipulation 01 ALTER TABLE statement: ALTER COLUMN clause YES @@ -264,7 +264,7 @@ F401 Extended joined table 02 FULL OUTER JOIN YES F401 Extended joined table 04 CROSS JOIN YES F402 Named column joins for LOBs, arrays, and multisets YES F403 Partitioned joined tables NO -F404 Range variable for common column names NO +F404 Range variable for common column names YES F411 Time zone specification YES differences regarding literal interpretation F421 National character YES F431 Read-only scrollable cursors YES forward scroll only @@ -373,7 +373,7 @@ S096 Optional array bounds YES S097 Array element assignment NO S098 ARRAY_AGG YES S111 ONLY in query expressions YES -S151 Type predicate NO +S151 Type predicate NO see pg_typeof() S161 Subtype treatment NO S162 Subtype treatment for references NO S201 SQL-invoked routines on arrays YES @@ -398,7 +398,7 @@ S301 Enhanced UNNEST YES S401 Distinct types based on array types NO S402 Distinct types based on distinct types NO S403 ARRAY_MAX_CARDINALITY NO -S404 TRIM_ARRAY NO +S404 TRIM_ARRAY YES T011 Timestamp in Information Schema NO T021 BINARY and VARBINARY data types NO T022 Advanced support for BINARY and VARBINARY data types NO @@ -425,6 +425,7 @@ T121 WITH (excluding RECURSIVE) in query expression YES T122 WITH (excluding RECURSIVE) in subquery YES T131 Recursive query YES T132 Recursive query in subquery YES +T133 Enhanced cycle mark values YES SQL:202x draft T141 SIMILAR predicate YES T151 DISTINCT predicate YES T152 DISTINCT predicate with negation YES @@ -449,9 +450,9 @@ T211 Basic trigger capability 05 Ability to specify a search condition that must T211 Basic trigger capability 06 Support for run-time rules for the interaction of triggers and constraints NO T211 Basic trigger capability 07 TRIGGER privilege YES T211 Basic trigger capability 08 Multiple triggers for the same event are executed in the order in which they were created in the catalog NO intentionally omitted -T212 Enhanced trigger capability NO -T213 INSTEAD OF triggers NO -T231 Sensitive cursors YES +T212 Enhanced trigger capability YES +T213 INSTEAD OF triggers YES +T231 Sensitive cursors NO T241 START TRANSACTION statement YES T251 SET TRANSACTION statement: LOCAL option NO T261 Chained transactions YES @@ -475,13 +476,13 @@ T324 Explicit security for SQL routines NO T325 Qualified SQL parameter references YES T326 Table functions NO T331 Basic roles YES -T332 Extended roles NO mostly supported +T332 Extended roles YES T341 Overloading of SQL-invoked functions and procedures YES T351 Bracketed SQL comments (/*...*/ comments) YES T431 Extended grouping capabilities YES T432 Nested and concatenated GROUPING SETS YES T433 Multiargument GROUPING function YES -T434 GROUP BY DISTINCT NO +T434 GROUP BY DISTINCT YES T441 ABS and MOD functions YES T461 Symmetric BETWEEN predicate YES T471 Result sets return value NO diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index 12a89829d7e4..b321c9ff3359 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -3,7 +3,7 @@ * storage.c * code to create and destroy physical storage for relations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -449,7 +449,8 @@ RelationCopyStorage(SMgrRelation src, SMgrRelation dst, smgrread(src, forkNum, blkno, buf.data); - if (!PageIsVerified(page, blkno)) + if (!PageIsVerifiedExtended(page, blkno, + PIV_LOG_WARNING | PIV_REPORT_STAT)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("invalid page in block %u of relation %s", @@ -608,7 +609,6 @@ smgrDoPendingDeletes(bool isCommit) PendingRelDelete *prev; PendingRelDelete *next; int nrels = 0, - i = 0, maxrels = 0; SMgrRelation *srels = NULL; @@ -664,7 +664,7 @@ smgrDoPendingDeletes(bool isCommit) { smgrdounlinkall(srels, nrels, false); - for (i = 0; i < nrels; i++) + for (int i = 0; i < nrels; i++) smgrclose(srels[i]); pfree(srels); diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql new file mode 100644 index 000000000000..a416e94d3717 --- /dev/null +++ b/src/backend/catalog/system_functions.sql @@ -0,0 +1,720 @@ +/* + * PostgreSQL System Functions + * + * Copyright (c) 1996-2021, PostgreSQL Global Development Group + * + * src/backend/catalog/system_functions.sql + * + * This file redefines certain built-in functions that it's impractical + * to fully define in pg_proc.dat. In most cases that's because they use + * SQL-standard function bodies and/or default expressions. The node + * tree representations of those are too unreadable, platform-dependent, + * and changeable to want to deal with them manually. Hence, we put stub + * definitions of such functions into pg_proc.dat and then replace them + * here. The stub definitions would be unnecessary were it not that we'd + * like these functions to have stable OIDs, the same as other built-in + * functions. + * + * This file also takes care of adjusting privileges for those functions + * that should not have the default public-EXECUTE privileges. (However, + * a small number of functions that exist mainly to underlie system views + * are dealt with in system_views.sql, instead.) + * + * Note: this file is read in single-user -j mode, which means that the + * command terminator is semicolon-newline-newline; whenever the backend + * sees that, it stops and executes what it's got. If you write a lot of + * statements without empty lines between, they'll all get quoted to you + * in any error message about one of them, so don't do that. Also, you + * cannot write a semicolon immediately followed by an empty line in a + * string literal (including a function body!) or a multiline comment. + */ + + +CREATE OR REPLACE FUNCTION lpad(text, integer) + RETURNS text + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN lpad($1, $2, ' '); + +CREATE OR REPLACE FUNCTION rpad(text, integer) + RETURNS text + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN rpad($1, $2, ' '); + +CREATE OR REPLACE FUNCTION "substring"(text, text, text) + RETURNS text + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN substring($1, similar_to_escape($2, $3)); + +CREATE OR REPLACE FUNCTION bit_length(bit) + RETURNS integer + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN length($1); + +CREATE OR REPLACE FUNCTION bit_length(bytea) + RETURNS integer + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN octet_length($1) * 8; + +CREATE OR REPLACE FUNCTION bit_length(text) + RETURNS integer + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN octet_length($1) * 8; + +CREATE OR REPLACE FUNCTION log(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN log(10, $1); + +CREATE OR REPLACE FUNCTION log10(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN log(10, $1); + +CREATE OR REPLACE FUNCTION round(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN round($1, 0); + +CREATE OR REPLACE FUNCTION trunc(numeric) + RETURNS numeric + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN trunc($1, 0); + +CREATE OR REPLACE FUNCTION numeric_pl_pg_lsn(numeric, pg_lsn) + RETURNS pg_lsn + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION path_contain_pt(path, point) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN on_ppath($2, $1); + +CREATE OR REPLACE FUNCTION polygon(circle) + RETURNS polygon + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN polygon(12, $1); + +CREATE OR REPLACE FUNCTION age(timestamptz) + RETURNS interval + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN age(cast(current_date as timestamptz), $1); + +CREATE OR REPLACE FUNCTION age(timestamp) + RETURNS interval + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN age(cast(current_date as timestamp), $1); + +CREATE OR REPLACE FUNCTION date_part(text, date) + RETURNS double precision + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN date_part($1, cast($2 as timestamp)); + +CREATE OR REPLACE FUNCTION timestamptz(date, time) + RETURNS timestamptz + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN cast(($1 + $2) as timestamptz); + +CREATE OR REPLACE FUNCTION timedate_pl(time, date) + RETURNS timestamp + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION timetzdate_pl(timetz, date) + RETURNS timestamptz + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_time(interval, time) + RETURNS time + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_date(interval, date) + RETURNS timestamp + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_timetz(interval, timetz) + RETURNS timetz + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_timestamp(interval, timestamp) + RETURNS timestamp + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION interval_pl_timestamptz(interval, timestamptz) + RETURNS timestamptz + LANGUAGE sql + STABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION integer_pl_date(integer, date) + RETURNS date + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION "overlaps"(timestamptz, timestamptz, + timestamptz, interval) + RETURNS boolean + LANGUAGE sql + STABLE PARALLEL SAFE COST 1 +RETURN ($1, $2) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamptz, interval, + timestamptz, interval) + RETURNS boolean + LANGUAGE sql + STABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamptz, interval, + timestamptz, timestamptz) + RETURNS boolean + LANGUAGE sql + STABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, $4); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamp, timestamp, + timestamp, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, $2) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamp, interval, + timestamp, timestamp) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, $4); + +CREATE OR REPLACE FUNCTION "overlaps"(timestamp, interval, + timestamp, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(time, interval, + time, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(time, time, + time, interval) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, $2) overlaps ($3, ($3 + $4)); + +CREATE OR REPLACE FUNCTION "overlaps"(time, interval, + time, time) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE COST 1 +RETURN ($1, ($1 + $2)) overlaps ($3, $4); + +CREATE OR REPLACE FUNCTION int8pl_inet(bigint, inet) + RETURNS inet + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN $2 + $1; + +CREATE OR REPLACE FUNCTION xpath(text, xml) + RETURNS xml[] + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN xpath($1, $2, '{}'::text[]); + +CREATE OR REPLACE FUNCTION xpath_exists(text, xml) + RETURNS boolean + LANGUAGE sql + IMMUTABLE PARALLEL SAFE STRICT COST 1 +RETURN xpath_exists($1, $2, '{}'::text[]); + +CREATE OR REPLACE FUNCTION pg_sleep_for(interval) + RETURNS void + LANGUAGE sql + PARALLEL SAFE STRICT COST 1 +RETURN pg_sleep(extract(epoch from clock_timestamp() + $1) - + extract(epoch from clock_timestamp())); + +CREATE OR REPLACE FUNCTION pg_sleep_until(timestamptz) + RETURNS void + LANGUAGE sql + PARALLEL SAFE STRICT COST 1 +RETURN pg_sleep(extract(epoch from $1) - + extract(epoch from clock_timestamp())); + +CREATE OR REPLACE FUNCTION pg_relation_size(regclass) + RETURNS bigint + LANGUAGE sql + PARALLEL SAFE STRICT COST 1 +RETURN pg_relation_size($1, 'main'); + +CREATE OR REPLACE FUNCTION obj_description(oid, name) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_description + where objoid = $1 and + classoid = (select oid from pg_class where relname = $2 and + relnamespace = 'pg_catalog'::regnamespace) and + objsubid = 0; +END; + +CREATE OR REPLACE FUNCTION shobj_description(oid, name) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_shdescription + where objoid = $1 and + classoid = (select oid from pg_class where relname = $2 and + relnamespace = 'pg_catalog'::regnamespace); +END; + +CREATE OR REPLACE FUNCTION obj_description(oid) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_description where objoid = $1 and objsubid = 0; +END; + +CREATE OR REPLACE FUNCTION col_description(oid, integer) + RETURNS text + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select description from pg_description + where objoid = $1 and classoid = 'pg_class'::regclass and objsubid = $2; +END; + +CREATE OR REPLACE FUNCTION ts_debug(config regconfig, document text, + OUT alias text, + OUT description text, + OUT token text, + OUT dictionaries regdictionary[], + OUT dictionary regdictionary, + OUT lexemes text[]) + RETURNS SETOF record + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC +select + tt.alias AS alias, + tt.description AS description, + parse.token AS token, + ARRAY ( SELECT m.mapdict::regdictionary + FROM pg_ts_config_map AS m + WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid + ORDER BY m.mapseqno ) + AS dictionaries, + ( SELECT mapdict::regdictionary + FROM pg_ts_config_map AS m + WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid + ORDER BY ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno + LIMIT 1 + ) AS dictionary, + ( SELECT ts_lexize(mapdict, parse.token) + FROM pg_ts_config_map AS m + WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid + ORDER BY ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno + LIMIT 1 + ) AS lexemes +FROM ts_parse( + (SELECT cfgparser FROM pg_ts_config WHERE oid = $1 ), $2 + ) AS parse, + ts_token_type( + (SELECT cfgparser FROM pg_ts_config WHERE oid = $1 ) + ) AS tt +WHERE tt.tokid = parse.tokid; +END; + +CREATE OR REPLACE FUNCTION ts_debug(document text, + OUT alias text, + OUT description text, + OUT token text, + OUT dictionaries regdictionary[], + OUT dictionary regdictionary, + OUT lexemes text[]) + RETURNS SETOF record + LANGUAGE sql + STABLE PARALLEL SAFE STRICT +BEGIN ATOMIC + SELECT * FROM ts_debug(get_current_ts_config(), $1); +END; + +CREATE OR REPLACE FUNCTION + pg_start_backup(label text, fast boolean DEFAULT false, exclusive boolean DEFAULT true) + RETURNS pg_lsn STRICT VOLATILE LANGUAGE internal AS 'pg_start_backup' + PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION pg_stop_backup ( + exclusive boolean, wait_for_archive boolean DEFAULT true, + OUT lsn pg_lsn, OUT labelfile text, OUT spcmapfile text) + RETURNS SETOF record STRICT VOLATILE LANGUAGE internal as 'pg_stop_backup_v2' + PARALLEL RESTRICTED; + +CREATE OR REPLACE FUNCTION + pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60) + RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_promote' + PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION + pg_terminate_backend(pid integer, timeout int8 DEFAULT 0) + RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_terminate_backend' + PARALLEL SAFE; + +-- legacy definition for compatibility with 9.3 +CREATE OR REPLACE FUNCTION + json_populate_record(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) + RETURNS anyelement LANGUAGE internal STABLE AS 'json_populate_record' PARALLEL SAFE; + +-- legacy definition for compatibility with 9.3 +CREATE OR REPLACE FUNCTION + json_populate_recordset(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) + RETURNS SETOF anyelement LANGUAGE internal STABLE ROWS 100 AS 'json_populate_recordset' PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION pg_logical_slot_get_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data text) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_get_changes'; + +CREATE OR REPLACE FUNCTION pg_logical_slot_peek_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data text) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_peek_changes'; + +CREATE OR REPLACE FUNCTION pg_logical_slot_get_binary_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data bytea) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_get_binary_changes'; + +CREATE OR REPLACE FUNCTION pg_logical_slot_peek_binary_changes( + IN slot_name name, IN upto_lsn pg_lsn, IN upto_nchanges int, VARIADIC options text[] DEFAULT '{}', + OUT lsn pg_lsn, OUT xid xid, OUT data bytea) +RETURNS SETOF RECORD +LANGUAGE INTERNAL +VOLATILE ROWS 1000 COST 1000 +AS 'pg_logical_slot_peek_binary_changes'; + +CREATE OR REPLACE FUNCTION pg_create_physical_replication_slot( + IN slot_name name, IN immediately_reserve boolean DEFAULT false, + IN temporary boolean DEFAULT false, + OUT slot_name name, OUT lsn pg_lsn) +RETURNS RECORD +LANGUAGE INTERNAL +STRICT VOLATILE +AS 'pg_create_physical_replication_slot'; + +CREATE OR REPLACE FUNCTION pg_create_logical_replication_slot( + IN slot_name name, IN plugin name, + IN temporary boolean DEFAULT false, + IN twophase boolean DEFAULT false, + OUT slot_name name, OUT lsn pg_lsn) +RETURNS RECORD +LANGUAGE INTERNAL +STRICT VOLATILE +AS 'pg_create_logical_replication_slot'; + +CREATE OR REPLACE FUNCTION + make_interval(years int4 DEFAULT 0, months int4 DEFAULT 0, weeks int4 DEFAULT 0, + days int4 DEFAULT 0, hours int4 DEFAULT 0, mins int4 DEFAULT 0, + secs double precision DEFAULT 0.0) +RETURNS interval +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'make_interval'; + +CREATE OR REPLACE FUNCTION + jsonb_set(jsonb_in jsonb, path text[] , replacement jsonb, + create_if_missing boolean DEFAULT true) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_set'; + +CREATE OR REPLACE FUNCTION + jsonb_set_lax(jsonb_in jsonb, path text[] , replacement jsonb, + create_if_missing boolean DEFAULT true, + null_value_treatment text DEFAULT 'use_json_null') +RETURNS jsonb +LANGUAGE INTERNAL +CALLED ON NULL INPUT IMMUTABLE PARALLEL SAFE +AS 'jsonb_set_lax'; + +CREATE OR REPLACE FUNCTION + parse_ident(str text, strict boolean DEFAULT true) +RETURNS text[] +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'parse_ident'; + +CREATE OR REPLACE FUNCTION + jsonb_insert(jsonb_in jsonb, path text[] , replacement jsonb, + insert_after boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_insert'; + +CREATE OR REPLACE FUNCTION + jsonb_path_exists(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_exists'; + +CREATE OR REPLACE FUNCTION + jsonb_path_match(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_match'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS SETOF jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_array(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query_array'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_first(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query_first'; + +CREATE OR REPLACE FUNCTION + jsonb_path_exists_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_exists_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_match_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_match_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS SETOF jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_array_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_array_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_first_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_first_tz'; + +-- default normalization form is NFC, per SQL standard +CREATE OR REPLACE FUNCTION + "normalize"(text, text DEFAULT 'NFC') +RETURNS text +LANGUAGE internal +STRICT IMMUTABLE PARALLEL SAFE +AS 'unicode_normalize_func'; + +CREATE OR REPLACE FUNCTION + is_normalized(text, text DEFAULT 'NFC') +RETURNS boolean +LANGUAGE internal +STRICT IMMUTABLE PARALLEL SAFE +AS 'unicode_is_normalized'; + +-- +-- The default permissions for functions mean that anyone can execute them. +-- A number of functions shouldn't be executable by just anyone, but rather +-- than use explicit 'superuser()' checks in those functions, we use the GRANT +-- system to REVOKE access to those functions at initdb time. Administrators +-- can later change who can access these functions, or leave them as only +-- available to superuser / cluster owner, if they choose. +-- + +REVOKE EXECUTE ON FUNCTION pg_start_backup(text, boolean, boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stop_backup() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stop_backup(boolean, boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_create_restore_point(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_switch_wal() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_wal_replay_pause() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_wal_replay_resume() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_reload_conf() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_current_logfile() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_current_logfile(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_promote(boolean, integer) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_reset() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_reset_shared(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_reset_slru(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_table_counters(oid) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_function_counters(oid) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_reset_replication_slot(text) FROM public; + +REVOKE EXECUTE ON FUNCTION lo_import(text) FROM public; + +REVOKE EXECUTE ON FUNCTION lo_import(text, oid) FROM public; + +REVOKE EXECUTE ON FUNCTION lo_export(oid, text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_logdir() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_waldir() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_archive_statusdir() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir(oid) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint,boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_advance(text, pg_lsn) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_create(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_drop(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_oid(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_progress(text, boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_is_setup() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_progress(boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_reset() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_setup(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_reset() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_setup(pg_lsn, timestamp with time zone) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_show_replication_origin_status() FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_file(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_stat_file(text,boolean) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_dir(text) FROM public; + +REVOKE EXECUTE ON FUNCTION pg_ls_dir(text,boolean,boolean) FROM public; + +-- +-- We also set up some things as accessible to standard roles. +-- + +GRANT EXECUTE ON FUNCTION pg_ls_logdir() TO pg_monitor; + +GRANT EXECUTE ON FUNCTION pg_ls_waldir() TO pg_monitor; + +GRANT EXECUTE ON FUNCTION pg_ls_archive_statusdir() TO pg_monitor; + +GRANT EXECUTE ON FUNCTION pg_ls_tmpdir() TO pg_monitor; + +GRANT EXECUTE ON FUNCTION pg_ls_tmpdir(oid) TO pg_monitor; + +GRANT pg_read_all_settings TO pg_monitor; + +GRANT pg_read_all_stats TO pg_monitor; + +GRANT pg_stat_scan_tables TO pg_monitor; diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 134e3edd6805..c1506956b472 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -3,7 +3,7 @@ * * Portions Copyright (c) 2006-2010, Greenplum inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Copyright (c) 1996-2021, PostgreSQL Global Development Group * * src/backend/catalog/system_views.sql * @@ -54,7 +54,7 @@ CREATE VIEW pg_shadow AS ON (pg_authid.oid = setrole AND setdatabase = 0) WHERE rolcanlogin; -REVOKE ALL on pg_shadow FROM public; +REVOKE ALL ON pg_shadow FROM public; CREATE VIEW pg_group AS SELECT @@ -171,7 +171,7 @@ CREATE VIEW pg_indexes AS LEFT JOIN pg_tablespace T ON (T.oid = I.reltablespace) WHERE C.relkind IN ('r', 'm', 'p') AND I.relkind IN ('i', 'I'); -CREATE OR REPLACE VIEW pg_sequences AS +CREATE VIEW pg_sequences AS SELECT N.nspname AS schemaname, C.relname AS sequencename, @@ -258,7 +258,7 @@ CREATE VIEW pg_stats WITH (security_barrier) AS AND has_column_privilege(c.oid, a.attnum, 'select') AND (c.relrowsecurity = false OR NOT row_security_active(c.oid)); -REVOKE ALL on pg_statistic FROM public; +REVOKE ALL ON pg_statistic FROM public; CREATE VIEW pg_stats_ext WITH (security_barrier) AS SELECT cn.nspname AS schemaname, @@ -271,6 +271,7 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS JOIN pg_attribute a ON (a.attrelid = s.stxrelid AND a.attnum = k) ) AS attnames, + pg_get_statisticsobjdef_expressions(s.oid) as exprs, s.stxkind AS kinds, sd.stxdndistinct AS n_distinct, sd.stxddependencies AS dependencies, @@ -297,8 +298,76 @@ CREATE VIEW pg_stats_ext WITH (security_barrier) AS WHERE NOT has_column_privilege(c.oid, a.attnum, 'select') ) AND (c.relrowsecurity = false OR NOT row_security_active(c.oid)); +CREATE VIEW pg_stats_ext_exprs WITH (security_barrier) AS + SELECT cn.nspname AS schemaname, + c.relname AS tablename, + sn.nspname AS statistics_schemaname, + s.stxname AS statistics_name, + pg_get_userbyid(s.stxowner) AS statistics_owner, + stat.expr, + (stat.a).stanullfrac AS null_frac, + (stat.a).stawidth AS avg_width, + (stat.a).stadistinct AS n_distinct, + (CASE + WHEN (stat.a).stakind1 = 1 THEN (stat.a).stavalues1 + WHEN (stat.a).stakind2 = 1 THEN (stat.a).stavalues2 + WHEN (stat.a).stakind3 = 1 THEN (stat.a).stavalues3 + WHEN (stat.a).stakind4 = 1 THEN (stat.a).stavalues4 + WHEN (stat.a).stakind5 = 1 THEN (stat.a).stavalues5 + END) AS most_common_vals, + (CASE + WHEN (stat.a).stakind1 = 1 THEN (stat.a).stanumbers1 + WHEN (stat.a).stakind2 = 1 THEN (stat.a).stanumbers2 + WHEN (stat.a).stakind3 = 1 THEN (stat.a).stanumbers3 + WHEN (stat.a).stakind4 = 1 THEN (stat.a).stanumbers4 + WHEN (stat.a).stakind5 = 1 THEN (stat.a).stanumbers5 + END) AS most_common_freqs, + (CASE + WHEN (stat.a).stakind1 = 2 THEN (stat.a).stavalues1 + WHEN (stat.a).stakind2 = 2 THEN (stat.a).stavalues2 + WHEN (stat.a).stakind3 = 2 THEN (stat.a).stavalues3 + WHEN (stat.a).stakind4 = 2 THEN (stat.a).stavalues4 + WHEN (stat.a).stakind5 = 2 THEN (stat.a).stavalues5 + END) AS histogram_bounds, + (CASE + WHEN (stat.a).stakind1 = 3 THEN (stat.a).stanumbers1[1] + WHEN (stat.a).stakind2 = 3 THEN (stat.a).stanumbers2[1] + WHEN (stat.a).stakind3 = 3 THEN (stat.a).stanumbers3[1] + WHEN (stat.a).stakind4 = 3 THEN (stat.a).stanumbers4[1] + WHEN (stat.a).stakind5 = 3 THEN (stat.a).stanumbers5[1] + END) correlation, + (CASE + WHEN (stat.a).stakind1 = 4 THEN (stat.a).stavalues1 + WHEN (stat.a).stakind2 = 4 THEN (stat.a).stavalues2 + WHEN (stat.a).stakind3 = 4 THEN (stat.a).stavalues3 + WHEN (stat.a).stakind4 = 4 THEN (stat.a).stavalues4 + WHEN (stat.a).stakind5 = 4 THEN (stat.a).stavalues5 + END) AS most_common_elems, + (CASE + WHEN (stat.a).stakind1 = 4 THEN (stat.a).stanumbers1 + WHEN (stat.a).stakind2 = 4 THEN (stat.a).stanumbers2 + WHEN (stat.a).stakind3 = 4 THEN (stat.a).stanumbers3 + WHEN (stat.a).stakind4 = 4 THEN (stat.a).stanumbers4 + WHEN (stat.a).stakind5 = 4 THEN (stat.a).stanumbers5 + END) AS most_common_elem_freqs, + (CASE + WHEN (stat.a).stakind1 = 5 THEN (stat.a).stanumbers1 + WHEN (stat.a).stakind2 = 5 THEN (stat.a).stanumbers2 + WHEN (stat.a).stakind3 = 5 THEN (stat.a).stanumbers3 + WHEN (stat.a).stakind4 = 5 THEN (stat.a).stanumbers4 + WHEN (stat.a).stakind5 = 5 THEN (stat.a).stanumbers5 + END) AS elem_count_histogram + FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid) + LEFT JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid) + LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace) + LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace) + JOIN LATERAL ( + SELECT unnest(pg_get_statisticsobjdef_expressions(s.oid)) AS expr, + unnest(sd.stxdexpr)::pg_statistic AS a + ) stat ON (stat.expr IS NOT NULL); + -- unprivileged users may read pg_statistic_ext but not pg_statistic_ext_data -REVOKE ALL on pg_statistic_ext_data FROM public; +REVOKE ALL ON pg_statistic_ext_data FROM public; CREATE VIEW pg_publication_tables AS SELECT @@ -534,13 +603,13 @@ GRANT SELECT, UPDATE ON pg_settings TO PUBLIC; CREATE VIEW pg_file_settings AS SELECT * FROM pg_show_all_file_settings() AS A; -REVOKE ALL on pg_file_settings FROM PUBLIC; +REVOKE ALL ON pg_file_settings FROM PUBLIC; REVOKE EXECUTE ON FUNCTION pg_show_all_file_settings() FROM PUBLIC; CREATE VIEW pg_hba_file_rules AS SELECT * FROM pg_hba_file_rules() AS A; -REVOKE ALL on pg_hba_file_rules FROM PUBLIC; +REVOKE ALL ON pg_hba_file_rules FROM PUBLIC; REVOKE EXECUTE ON FUNCTION pg_hba_file_rules() FROM PUBLIC; CREATE VIEW pg_timezone_abbrevs AS @@ -552,7 +621,7 @@ CREATE VIEW pg_timezone_names AS CREATE VIEW pg_config AS SELECT * FROM pg_config(); -REVOKE ALL on pg_config FROM PUBLIC; +REVOKE ALL ON pg_config FROM PUBLIC; REVOKE EXECUTE ON FUNCTION pg_config() FROM PUBLIC; CREATE VIEW pg_shmem_allocations AS @@ -564,6 +633,9 @@ REVOKE EXECUTE ON FUNCTION pg_get_shmem_allocations() FROM PUBLIC; CREATE VIEW pg_backend_memory_contexts AS SELECT * FROM pg_get_backend_memory_contexts(); +REVOKE ALL ON pg_backend_memory_contexts FROM PUBLIC; +REVOKE EXECUTE ON FUNCTION pg_get_backend_memory_contexts() FROM PUBLIC; + -- Statistics views CREATE VIEW pg_stat_all_tables_internal AS @@ -595,7 +667,7 @@ CREATE VIEW pg_stat_all_tables_internal AS FROM pg_class C LEFT JOIN pg_index I ON C.oid = I.indrelid LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE C.relkind IN ('r', 't', 'm') + WHERE C.relkind IN ('r', 't', 'm', 'p') GROUP BY C.oid, N.nspname, C.relname; -- Gather data from segments on user tables, and use data on coordinator on system tables. @@ -683,7 +755,7 @@ CREATE VIEW pg_stat_xact_all_tables AS FROM pg_class C LEFT JOIN pg_index I ON C.oid = I.indrelid LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE C.relkind IN ('r', 't', 'm') + WHERE C.relkind IN ('r', 't', 'm', 'p') GROUP BY C.oid, N.nspname, C.relname; CREATE VIEW pg_stat_sys_tables AS @@ -875,6 +947,7 @@ CREATE VIEW pg_stat_activity AS S.state, S.backend_xid, s.backend_xmin, + S.query_id, S.query, S.backend_type, @@ -1022,7 +1095,6 @@ CREATE VIEW pg_stat_ssl AS S.sslversion AS version, S.sslcipher AS cipher, S.sslbits AS bits, - S.sslcompression AS compression, S.ssl_client_dn AS client_dn, S.ssl_client_serial AS client_serial, S.ssl_issuer_dn AS issuer_dn @@ -1053,10 +1125,27 @@ CREATE VIEW pg_replication_slots AS L.restart_lsn, L.confirmed_flush_lsn, L.wal_status, - L.safe_wal_size + L.safe_wal_size, + L.two_phase FROM pg_get_replication_slots() AS L LEFT JOIN pg_database D ON (L.datoid = D.oid); +CREATE VIEW pg_stat_replication_slots AS + SELECT + s.slot_name, + s.spill_txns, + s.spill_count, + s.spill_bytes, + s.stream_txns, + s.stream_count, + s.stream_bytes, + s.total_txns, + s.total_bytes, + s.stats_reset + FROM pg_replication_slots as r, + LATERAL pg_stat_get_replication_slot(slot_name) as s + WHERE r.datoid IS NOT NULL; -- excluding physical slots + CREATE VIEW pg_stat_database AS SELECT D.oid AS datid, @@ -1083,6 +1172,13 @@ CREATE VIEW pg_stat_database AS pg_stat_get_db_checksum_last_failure(D.oid) AS checksum_last_failure, pg_stat_get_db_blk_read_time(D.oid) AS blk_read_time, pg_stat_get_db_blk_write_time(D.oid) AS blk_write_time, + pg_stat_get_db_session_time(D.oid) AS session_time, + pg_stat_get_db_active_time(D.oid) AS active_time, + pg_stat_get_db_idle_in_transaction_time(D.oid) AS idle_in_transaction_time, + pg_stat_get_db_sessions(D.oid) AS sessions, + pg_stat_get_db_sessions_abandoned(D.oid) AS sessions_abandoned, + pg_stat_get_db_sessions_fatal(D.oid) AS sessions_fatal, + pg_stat_get_db_sessions_killed(D.oid) AS sessions_killed, pg_stat_get_db_stat_reset_time(D.oid) AS stats_reset FROM ( SELECT 0 AS oid, NULL::name AS datname @@ -1363,6 +1459,19 @@ CREATE VIEW pg_stat_bgwriter AS pg_stat_get_buf_alloc() AS buffers_alloc, pg_stat_get_bgwriter_stat_reset_time() AS stats_reset; +CREATE VIEW pg_stat_wal AS + SELECT + w.wal_records, + w.wal_fpi, + w.wal_bytes, + w.wal_buffers_full, + w.wal_write, + w.wal_sync, + w.wal_write_time, + w.wal_sync_time, + w.stats_reset + FROM pg_stat_get_wal() w; + CREATE VIEW pg_stat_progress_analyze AS SELECT S.pid AS pid, S.datid AS datid, D.datname AS datname, @@ -1480,6 +1589,26 @@ CREATE VIEW pg_stat_progress_basebackup AS S.param5 AS tablespaces_streamed FROM pg_stat_get_progress_info('BASEBACKUP') AS S; + +CREATE VIEW pg_stat_progress_copy AS + SELECT + S.pid AS pid, S.datid AS datid, D.datname AS datname, + S.relid AS relid, + CASE S.param5 WHEN 1 THEN 'COPY FROM' + WHEN 2 THEN 'COPY TO' + END AS command, + CASE S.param6 WHEN 1 THEN 'FILE' + WHEN 2 THEN 'PROGRAM' + WHEN 3 THEN 'PIPE' + WHEN 4 THEN 'CALLBACK' + END AS "type", + S.param1 AS bytes_processed, + S.param2 AS bytes_total, + S.param3 AS tuples_processed, + S.param4 AS tuples_excluded + FROM pg_stat_get_progress_info('COPY') AS S + LEFT JOIN pg_database D ON S.datid = D.oid; + CREATE VIEW pg_user_mappings AS SELECT U.oid AS umid, @@ -1502,7 +1631,7 @@ CREATE VIEW pg_user_mappings AS JOIN pg_foreign_server S ON (U.umserver = S.oid) LEFT JOIN pg_authid A ON (A.oid = U.umuser); -REVOKE ALL on pg_user_mapping FROM public; +REVOKE ALL ON pg_user_mapping FROM public; CREATE VIEW pg_replication_origin_status AS SELECT * @@ -1510,9 +1639,10 @@ CREATE VIEW pg_replication_origin_status AS REVOKE ALL ON pg_replication_origin_status FROM public; --- All columns of pg_subscription except subconninfo are readable. +-- All columns of pg_subscription except subconninfo are publicly readable. REVOKE ALL ON pg_subscription FROM public; -GRANT SELECT (subdbid, subname, subowner, subenabled, subbinary, subslotname, subpublications) +GRANT SELECT (oid, subdbid, subname, subowner, subenabled, subbinary, + substream, subslotname, subsynccommit, subpublications) ON pg_subscription TO public; @@ -1522,68 +1652,6 @@ GRANT SELECT (subdbid, subname, subowner, subenabled, subbinary, subslotname, su -- a separate "system_functions.sql" file. -- --- Tsearch debug function. Defined here because it'd be pretty unwieldy --- to put it into pg_proc.h - -CREATE FUNCTION ts_debug(IN config regconfig, IN document text, - OUT alias text, - OUT description text, - OUT token text, - OUT dictionaries regdictionary[], - OUT dictionary regdictionary, - OUT lexemes text[]) -RETURNS SETOF record AS -$$ -SELECT - tt.alias AS alias, - tt.description AS description, - parse.token AS token, - ARRAY ( SELECT m.mapdict::pg_catalog.regdictionary - FROM pg_catalog.pg_ts_config_map AS m - WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY m.mapseqno ) - AS dictionaries, - ( SELECT mapdict::pg_catalog.regdictionary - FROM pg_catalog.pg_ts_config_map AS m - WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno - LIMIT 1 - ) AS dictionary, - ( SELECT pg_catalog.ts_lexize(mapdict, parse.token) - FROM pg_catalog.pg_ts_config_map AS m - WHERE m.mapcfg = $1 AND m.maptokentype = parse.tokid - ORDER BY pg_catalog.ts_lexize(mapdict, parse.token) IS NULL, m.mapseqno - LIMIT 1 - ) AS lexemes -FROM pg_catalog.ts_parse( - (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ), $2 - ) AS parse, - pg_catalog.ts_token_type( - (SELECT cfgparser FROM pg_catalog.pg_ts_config WHERE oid = $1 ) - ) AS tt -WHERE tt.tokid = parse.tokid -$$ -LANGUAGE SQL STRICT STABLE PARALLEL SAFE; - -COMMENT ON FUNCTION ts_debug(regconfig,text) IS - 'debug function for text search configuration'; - -CREATE FUNCTION ts_debug(IN document text, - OUT alias text, - OUT description text, - OUT token text, - OUT dictionaries regdictionary[], - OUT dictionary regdictionary, - OUT lexemes text[]) -RETURNS SETOF record AS -$$ - SELECT * FROM pg_catalog.ts_debug( pg_catalog.get_current_ts_config(), $1); -$$ -LANGUAGE SQL STRICT STABLE PARALLEL SAFE; - -COMMENT ON FUNCTION ts_debug(text) IS - 'debug function for current text search configuration'; - -- -- Redeclare built-in functions that need default values attached to their -- arguments. It's impractical to set those up directly in pg_proc.h because diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 85cb551a0e96..d3fe5884b65d 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -4,7 +4,7 @@ * This file contains routines to support creation of toast tables * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -15,6 +15,7 @@ #include "postgres.h" #include "access/heapam.h" +#include "access/toast_compression.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" #include "catalog/catalog.h" @@ -238,6 +239,20 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, TupleDescAttr(tupdesc, 1)->attstorage = TYPSTORAGE_PLAIN; TupleDescAttr(tupdesc, 2)->attstorage = TYPSTORAGE_PLAIN; + /* Toast field should not be compressed */ + TupleDescAttr(tupdesc, 0)->attcompression = InvalidCompressionMethod; + TupleDescAttr(tupdesc, 1)->attcompression = InvalidCompressionMethod; + TupleDescAttr(tupdesc, 2)->attcompression = InvalidCompressionMethod; + + /* + * Toast tables for regular relations go in pg_toast; those for temp + * relations go into the per-backend temp-toast-table namespace. + */ + if (isTempOrTempToastNamespace(rel->rd_rel->relnamespace)) + namespaceid = GetTempToastNamespace(); + else + namespaceid = PG_TOAST_NAMESPACE; + /* Toast table is shared if and only if its parent is. */ shared_relation = rel->rd_rel->relisshared; @@ -358,9 +373,8 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, table_close(class_rel, RowExclusiveLock); /* - * Register dependency from the toast table to the main, so that the - * toast table will be deleted if the main is. Skip this in bootstrap - * mode. + * Register dependency from the toast table to the main, so that the toast + * table will be deleted if the main is. Skip this in bootstrap mode. */ if (!IsBootstrapProcessingMode()) { @@ -403,9 +417,9 @@ needs_toast_table(Relation rel) /* * Ignore attempts to create toast tables on catalog tables after initdb. - * Which catalogs get toast tables is explicitly chosen in - * catalog/toasting.h. (We could get here via some ALTER TABLE command if - * the catalog doesn't have a toast table.) + * Which catalogs get toast tables is explicitly chosen in catalog/pg_*.h. + * (We could get here via some ALTER TABLE command if the catalog doesn't + * have a toast table.) */ if (IsCatalogRelation(rel) && !IsBootstrapProcessingMode()) return false; diff --git a/src/backend/cdb/cdbdtxrecovery.c b/src/backend/cdb/cdbdtxrecovery.c index d94a14253616..8244d64d015d 100644 --- a/src/backend/cdb/cdbdtxrecovery.c +++ b/src/backend/cdb/cdbdtxrecovery.c @@ -324,7 +324,7 @@ gatherRMInDoubtTransactions(int prepared_seconds, bool raiseError) hctl.keysize = TMGIDSIZE; /* GID */ hctl.entrysize = sizeof(InDoubtDtx); - htab = hash_create("InDoubtDtxHash", 10, &hctl, HASH_ELEM); + htab = hash_create("InDoubtDtxHash", 10, &hctl, HASH_ELEM | HASH_STRINGS); if (htab == NULL) ereport(FATAL, diff --git a/src/backend/cdb/cdbgroupingpaths.c b/src/backend/cdb/cdbgroupingpaths.c index 9ffd084afb96..366cfe6cce7e 100644 --- a/src/backend/cdb/cdbgroupingpaths.c +++ b/src/backend/cdb/cdbgroupingpaths.c @@ -62,6 +62,7 @@ #include "optimizer/cost.h" #include "optimizer/optimizer.h" #include "optimizer/pathnode.h" +#include "optimizer/prep.h" #include "optimizer/paths.h" #include "optimizer/tlist.h" #include "parser/parse_clause.h" @@ -1551,8 +1552,7 @@ add_multi_dqas_hash_agg_path(PlannerInfo *root, info->dqa_expr_lst); AggClauseCosts DedupCost = {}; - get_agg_clause_costs(root, (Node *) info->tup_split_target->exprs, - AGGSPLIT_SIMPLE, + get_agg_clause_costs(root, AGGSPLIT_SIMPLE, &DedupCost); if (gp_enable_dqa_pruning) @@ -2148,11 +2148,20 @@ fetch_multi_dqas_info(PlannerInfo *root, dNumDistinctGroups += estimate_num_groups(root, this_dqa_group_exprs, num_total_input_rows, - NULL); + NULL, NULL); } - /* assign an agg_expr_id value to aggref*/ + /* + * Assign the agg_expr_id value to both stage instances of this + * aggregate. The guarded (TupleSplit-consuming) stage reads it to + * match split tuples against its transition (see + * ExecBuildAggTrans); assigning only one instance left the partial + * stage at 0, so every guard compared the AggExprId column against + * -1 and no transition ever advanced: all multi-DQA aggregates + * returned NULL/0. + */ aggref->agg_expr_id = agg_expr_id; + aggref_final->agg_expr_id = agg_expr_id; /* rid of filter in aggref */ aggref->aggfilter = NULL; @@ -2183,6 +2192,42 @@ fetch_multi_dqas_info(PlannerInfo *root, info->partial_target= ctx->partial_grouping_target; info->final_target = ctx->target; + + /* + * The loop above stamped agg_expr_id on the Aggref instances of the + * cost lists, but the partial stage's targetlist holds separate + * flat-copies made by make_partial_grouping_target() before any ids + * existed. The guarded (TupleSplit-consuming) stage is built from + * exactly those copies, so without this propagation every guard + * compared the AggExprId column against -1 and all multi-DQA + * aggregates returned NULL/0. Propagate by aggno, which is shared + * across stage instances of the same aggregate. + */ + { + ListCell *lc_t; + + foreach(lc_t, info->partial_target->exprs) + { + Expr *expr = (Expr *) lfirst(lc_t); + ListCell *lc_a; + + if (!IsA(expr, Aggref)) + continue; + forboth(lc_a, ctx->agg_partial_costs->distinctAggrefs, + lc, ctx->agg_final_costs->distinctAggrefs) + { + Aggref *stamped = (Aggref *) lfirst(lc_a); + Aggref *stamped_final = (Aggref *) lfirst(lc); + + if (stamped->aggno == ((Aggref *) expr)->aggno) + { + ((Aggref *) expr)->agg_expr_id = + Max(stamped->agg_expr_id, stamped_final->agg_expr_id); + break; + } + } + } + } } /* @@ -2277,7 +2322,7 @@ fetch_single_dqa_info(PlannerInfo *root, info->dNumDistinctGroups = estimate_num_groups(root, dqa_group_exprs, num_total_input_rows, - NULL); + NULL, NULL); } /* diff --git a/src/backend/cdb/cdbmutate.c b/src/backend/cdb/cdbmutate.c index 0562007cdbc4..6633142e75bf 100644 --- a/src/backend/cdb/cdbmutate.c +++ b/src/backend/cdb/cdbmutate.c @@ -391,11 +391,10 @@ shareinput_walker(SHAREINPUT_MUTATOR f, Node *node, PlannerInfo *root) } else if (IsA(node, ModifyTable)) { - ListCell *cell; ModifyTable *mt = (ModifyTable *) node; - foreach(cell, mt->plans) - shareinput_walker(f, (Node *) lfirst(cell), root); + if (mt->plan.lefttree) + shareinput_walker(f, (Node *) mt->plan.lefttree, root); } else if (IsA(node, SubqueryScan)) { @@ -1133,7 +1132,7 @@ makeSegmentFilterExpr(int segid) make_opclause(Int4EqualOperator, BOOLOID, false, /* opretset */ - (Expr *) makeFuncExpr(F_MPP_EXECUTION_SEGMENT, + (Expr *) makeFuncExpr(F_GP_EXECUTION_SEGMENT, INT4OID, NIL, /* args */ InvalidOid, @@ -1603,8 +1602,8 @@ pre_dispatch_function_evaluation_mutator(Node *node, * xlog which will also flush any xlog writes that the sequence * server might do. */ - if (funcid == F_NEXTVAL_OID || funcid == F_CURRVAL_OID || - funcid == F_SETVAL_OID) + if (funcid == F_NEXTVAL || funcid == F_CURRVAL || + funcid == F_SETVAL_REGCLASS_INT8) { ExecutorMarkTransactionUsesSequences(); is_seq_func = true; diff --git a/src/backend/cdb/cdbpath.c b/src/backend/cdb/cdbpath.c index edb1da78e134..c8268a74f2f3 100644 --- a/src/backend/cdb/cdbpath.c +++ b/src/backend/cdb/cdbpath.c @@ -579,7 +579,7 @@ cdbpath_create_motion_path(PlannerInfo *root, */ if (CdbPathLocus_IsOuterQuery(locus)) { - return (Path *) create_material_path(root, subpath->parent, + return (Path *) create_material_path(subpath->parent, &pathnode->path); } diff --git a/src/backend/cdb/cdbplan.c b/src/backend/cdb/cdbplan.c index d38052183a6e..64b0def5bdd4 100644 --- a/src/backend/cdb/cdbplan.c +++ b/src/backend/cdb/cdbplan.c @@ -202,7 +202,6 @@ plan_tree_mutator(Node *node, FLATCOPY(newmt, mt, ModifyTable); PLANMUTATE(newmt, mt); - MUTATE(newmt->plans, mt->plans, List *); MUTATE(newmt->onConflictSet, mt->onConflictSet, List *); MUTATE(newmt->onConflictWhere, mt->onConflictWhere , Node *); MUTATE(newmt->withCheckOptionLists, mt->withCheckOptionLists, List *); diff --git a/src/backend/cdb/cdbsubselect.c b/src/backend/cdb/cdbsubselect.c index 34f679c948fb..2c74a44971a8 100644 --- a/src/backend/cdb/cdbsubselect.c +++ b/src/backend/cdb/cdbsubselect.c @@ -701,7 +701,7 @@ safe_to_convert_NOTIN(SubLink *sublink, Relids available_rels) } /* Left-hand expressions must contain some Vars of the current */ - left_varnos = pull_varnos(sublink->testexpr); + left_varnos = pull_varnos(NULL, sublink->testexpr); if (bms_is_empty(left_varnos)) return false; diff --git a/src/backend/cdb/cdbutil.c b/src/backend/cdb/cdbutil.c index d14d669f15c4..6a942926a30c 100644 --- a/src/backend/cdb/cdbutil.c +++ b/src/backend/cdb/cdbutil.c @@ -1203,7 +1203,7 @@ getDnsCachedAddress(char *name, int port, int elevel, bool use_cache) hash_ctl.entrysize = sizeof(SegIpEntry); segment_ip_cache_htab = hash_create("segment_dns_cache", - 256, &hash_ctl, HASH_ELEM); + 256, &hash_ctl, HASH_ELEM | HASH_STRINGS); } else { @@ -1417,7 +1417,7 @@ hostPrimaryCountHashTableInit(void) info.keysize = MAXHOSTNAMELEN; info.entrysize = sizeof(HostPrimaryCountEntry); - return hash_create("HostSegs", 32, &info, HASH_ELEM); + return hash_create("HostSegs", 32, &info, HASH_ELEM | HASH_STRINGS); } /* diff --git a/src/backend/cdb/dispatcher/cdbdisp_async.c b/src/backend/cdb/dispatcher/cdbdisp_async.c index 0c2f01ba37a0..01a3a1acd43a 100644 --- a/src/backend/cdb/dispatcher/cdbdisp_async.c +++ b/src/backend/cdb/dispatcher/cdbdisp_async.c @@ -25,6 +25,7 @@ #include "pgstat.h" #include "storage/ipc.h" /* For proc_exit_inprogress */ +#include "storage/latch.h" #include "tcop/tcopprot.h" #include "cdb/cdbdisp.h" #include "cdb/cdbdisp_async.h" @@ -1040,7 +1041,7 @@ checkSegmentAlive(CdbDispatchCmdAsync *pParms) static inline void send_sequence_response(PGconn *conn, Oid oid, int64 last, int64 cached, int64 increment, bool overflow, bool error) { - if (pqPutMsgStart(SEQ_NEXTVAL_QUERY_RESPONSE, false, conn) < 0) + if (pqPutMsgStart(SEQ_NEXTVAL_QUERY_RESPONSE, conn) < 0) elog(ERROR, "Failed to send sequence response: %s", PQerrorMessage(conn)); pqPutInt(oid, 4, conn); pqPutInt(last >> 32, 4, conn); diff --git a/src/backend/cdb/dispatcher/cdbdispatchresult.c b/src/backend/cdb/dispatcher/cdbdispatchresult.c index 37fead289819..85aee8d72bb3 100644 --- a/src/backend/cdb/dispatcher/cdbdispatchresult.c +++ b/src/backend/cdb/dispatcher/cdbdispatchresult.c @@ -505,9 +505,21 @@ cdbdisp_dumpDispatchResult(CdbDispatchResult *dispatchResult) { if (errstart(ERROR, TEXTDOMAIN)) { + MemoryContext oldcontext; + errcode(ERRCODE_GP_INTERCONNECTION_ERROR); errmsg("%s", dispatchResult->error_message->data); + /* + * errfinish_and_return -> CopyErrorData asserts we are not in + * ErrorContext (it palloc's the returned ErrorData in the current + * context). Switch to TopTransactionContext like cdbdisp_get_PQerror + * does, so a dispatch/interconnect error can be reported without + * crashing. + */ + Assert(TopTransactionContext); + oldcontext = MemoryContextSwitchTo(TopTransactionContext); errdata = errfinish_and_return(__FILE__, __LINE__, PG_FUNCNAME_MACRO); + MemoryContextSwitchTo(oldcontext); } else pg_unreachable(); diff --git a/src/backend/cdb/dispatcher/cdbgang_async.c b/src/backend/cdb/dispatcher/cdbgang_async.c index d370aef1fac8..6b828c73bcc1 100644 --- a/src/backend/cdb/dispatcher/cdbgang_async.c +++ b/src/backend/cdb/dispatcher/cdbgang_async.c @@ -24,6 +24,7 @@ #include "access/xact.h" #include "storage/ipc.h" /* For proc_exit_inprogress */ +#include "storage/latch.h" #include "pgstat.h" #include "tcop/tcopprot.h" #include "libpq-fe.h" diff --git a/src/backend/cdb/dispatcher/cdbpq.c b/src/backend/cdb/dispatcher/cdbpq.c index 7e9829484622..aebc0cfbfd87 100644 --- a/src/backend/cdb/dispatcher/cdbpq.c +++ b/src/backend/cdb/dispatcher/cdbpq.c @@ -8,7 +8,7 @@ PQsendGpQuery_shared(PGconn *conn, char *shared_query, int query_len, bool nonbl { int ret; - if (!PQsendQueryStart(conn)) + if (!PQsendQueryStart(conn, true)) return 0; if (!shared_query) @@ -38,8 +38,45 @@ PQsendGpQuery_shared(PGconn *conn, char *shared_query, int query_len, bool nonbl conn->outMsgEnd = query_len; conn->outCount = query_len; - /* remember we are using simple query protocol */ - conn->queryclass = PGQUERY_SIMPLE; + /* + * Register this command in libpq's command queue (added in PG14), marking + * it as a row-returning simple query. Without a queue entry, + * getRowDescriptions() in fe-protocol3.c builds a PGRES_COMMAND_OK result + * instead of PGRES_TUPLES_OK, and every DataRow that a dispatched query + * returns (e.g. pg_highest_oid() OID sync, indcheckxmin sync, ANALYZE + * sampling) is rejected with "server sent data (D message) without prior + * row description (T message)", surfacing on the QD as "no primary message + * received". This inlines pqAllocCmdQueueEntry()/pqAppendCmdQueueEntry(), + * which are static in fe-exec.c. + */ + { + PGcmdQueueEntry *entry; + + if (conn->cmd_queue_recycle == NULL) + { + entry = (PGcmdQueueEntry *) malloc(sizeof(PGcmdQueueEntry)); + if (entry == NULL) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("out of memory\n")); + return 0; + } + } + else + { + entry = conn->cmd_queue_recycle; + conn->cmd_queue_recycle = entry->next; + } + entry->next = NULL; + entry->query = NULL; + entry->queryclass = PGQUERY_SIMPLE; + + if (conn->cmd_queue_head == NULL) + conn->cmd_queue_head = entry; + else + conn->cmd_queue_tail->next = entry; + conn->cmd_queue_tail = entry; + } /* * Give the data a push. In nonblock mode, don't complain if we're unable diff --git a/src/backend/cdb/endpoint/cdbendpointutils.c b/src/backend/cdb/endpoint/cdbendpointutils.c index 8731836a4661..7060c42efa3f 100644 --- a/src/backend/cdb/endpoint/cdbendpointutils.c +++ b/src/backend/cdb/endpoint/cdbendpointutils.c @@ -13,6 +13,7 @@ #include "postgres.h" +#include "common/hex.h" #include "funcapi.h" #include "libpq-fe.h" #include "utils/builtins.h" @@ -56,7 +57,7 @@ void endpoint_token_str2arr(const char *tokenStr, int8 *token) { if (strlen(tokenStr) == ENDPOINT_TOKEN_STR_LEN) - hex_decode(tokenStr, ENDPOINT_TOKEN_STR_LEN, (char *) token); + pg_hex_decode(tokenStr, ENDPOINT_TOKEN_STR_LEN, (char *) token, ENDPOINT_TOKEN_ARR_LEN); else ereport(FATAL, (errcode(ERRCODE_INVALID_PASSWORD), errmsg("retrieve auth token is invalid"))); @@ -69,7 +70,7 @@ endpoint_token_str2arr(const char *tokenStr, int8 *token) void endpoint_token_arr2str(const int8 *token, char *tokenStr) { - hex_encode((const char *) token, ENDPOINT_TOKEN_ARR_LEN, tokenStr); + pg_hex_encode((const char *) token, ENDPOINT_TOKEN_ARR_LEN, tokenStr, ENDPOINT_TOKEN_STR_LEN + 1); tokenStr[ENDPOINT_TOKEN_STR_LEN] = 0; } diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile index 2607912d5cfb..f4f3c4f2e56a 100644 --- a/src/backend/commands/Makefile +++ b/src/backend/commands/Makefile @@ -27,6 +27,9 @@ OBJS = \ constraint.o \ conversioncmds.o \ copy.o \ + copyfrom.o \ + copyfromparse.o \ + copyto.o \ createas.o \ dbcommands.o \ define.o \ diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 4f6d9628db78..1251965631eb 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -4,7 +4,7 @@ * * Routines for aggregate-manipulation commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -329,9 +329,11 @@ DefineAggregate(ParseState *pstate, InvalidOid, OBJECT_AGGREGATE, ¶meterTypes, + NULL, &allParameterTypes, ¶meterModes, ¶meterNames, + NULL, ¶meterDefaults, &variadicArgType, &requiredResultType); diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 4b942de66b46..193db503967e 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -3,7 +3,7 @@ * alter.c * Drivers for generic alter commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c index 98f81db78caf..c61ba6c34bb4 100644 --- a/src/backend/commands/amcmds.c +++ b/src/backend/commands/amcmds.c @@ -3,7 +3,7 @@ * amcmds.c * Routines for SQL commands that manipulate access methods. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -200,7 +200,7 @@ get_am_oid(const char *amname, bool missing_ok) } /* - * get_am_name - given an access method OID name and type, look up its name. + * get_am_name - given an access method OID, look up its name. */ char * get_am_name(Oid amOid) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 8ad77d793573..0e240fc532d3 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -53,7 +53,7 @@ * * TODO: explain how this works. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -113,6 +113,7 @@ #include "utils/pg_rusage.h" #include "utils/sampling.h" #include "utils/sortsupport.h" +#include "utils/spccache.h" #include "utils/syscache.h" #include "utils/timestamp.h" @@ -479,6 +480,11 @@ do_analyze_rel(Relation onerel, VacuumParams *params, Bitmapset **colLargeRowIndexes; double *colLargeRowLength; bool sample_needed; + int64 AnalyzePageHit = VacuumPageHit; + int64 AnalyzePageMiss = VacuumPageMiss; + int64 AnalyzePageDirty = VacuumPageDirty; + PgStat_Counter startreadtime = 0; + PgStat_Counter startwritetime = 0; if (inh) ereport(elevel, @@ -513,8 +519,14 @@ do_analyze_rel(Relation onerel, VacuumParams *params, /* measure elapsed time iff autovacuum logging requires it */ if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0) { + if (track_io_timing) + { + startreadtime = pgStatBlockReadTime; + startwritetime = pgStatBlockWriteTime; + } + pg_rusage_init(&ru0); - if (params->log_min_duration > 0) + if (params->log_min_duration >= 0) starttime = GetCurrentTimestamp(); } @@ -972,6 +984,12 @@ do_analyze_rel(Relation onerel, VacuumParams *params, * needs to be the count of all pages marked all visible across the all the * QEs. We need to gather this information from the segments and then update * it here. + * We assume that VACUUM hasn't set pg_class.reltuples already, even + * during a VACUUM ANALYZE. Although VACUUM often updates pg_class, + * exceptions exist. A "VACUUM (ANALYZE, INDEX_CLEANUP OFF)" command will + * never update pg_class entries for index relations. It's also possible + * that an individual index's pg_class entry won't be updated during + * VACUUM if the index AM returns NULL from its amvacuumcleanup() routine. */ if (!inh) { @@ -982,6 +1000,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params, else visibilitymap_count(onerel, &relallvisible, NULL); + /* Update pg_class for table relation */ vac_update_relstats(onerel, relpages, totalrows, @@ -990,16 +1009,9 @@ do_analyze_rel(Relation onerel, VacuumParams *params, InvalidTransactionId, InvalidMultiXactId, in_outer_xact, - false /* isVacuum */); - } + false); - /* - * Same for indexes. Vacuum always scans all indexes, so if we're part of - * VACUUM ANALYZE, don't overwrite the accurate count already inserted by - * VACUUM. - */ - if (!inh && !(params->options & VACOPT_VACUUM)) - { + /* Same for indexes */ for (ind = 0; ind < nindexes; ind++) { AnlIndexData *thisdata = &indexdata[ind]; @@ -1041,19 +1053,56 @@ do_analyze_rel(Relation onerel, VacuumParams *params, false /* isVacuum */); } } + else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + /* + * Partitioned tables don't have storage, so we don't set any fields + * in their pg_class entries except for reltuples, which is necessary + * for auto-analyze to work properly. + */ + vac_update_relstats(onerel, -1, totalrows, + 0, false, InvalidTransactionId, + InvalidMultiXactId, + in_outer_xact, + false); + } /* - * Report ANALYZE to the stats collector, too. However, if doing - * inherited stats we shouldn't report, because the stats collector only - * tracks per-table stats. Reset the changes_since_analyze counter only - * if we analyzed all columns; otherwise, there is still work for - * auto-analyze to do. + * Now report ANALYZE to the stats collector. For regular tables, we do + * it only if not doing inherited stats. For partitioned tables, we only + * do it for inherited stats. (We're never called for not-inherited stats + * on partitioned tables anyway.) + * + * Reset the changes_since_analyze counter only if we analyzed all + * columns; otherwise, there is still work for auto-analyze to do. */ - if (!inh) + if (!inh || onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) pgstat_report_analyze(onerel, totalrows, totaldeadrows, (va_cols == NIL)); - /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */ + /* + * If this is a manual analyze of all columns of a permanent leaf + * partition, and not doing inherited stats, also let the collector know + * about the ancestor tables of this partition. Autovacuum does the + * equivalent of this at the start of its run, so there's no reason to do + * it there. + */ + if (!inh && !IsAutoVacuumWorkerProcess() && + (va_cols == NIL) && + onerel->rd_rel->relispartition && + onerel->rd_rel->relkind == RELKIND_RELATION && + onerel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT) + { + pgstat_report_anl_ancestors(RelationGetRelid(onerel)); + } + + /* + * If this isn't part of VACUUM ANALYZE, let index AMs do cleanup. + * + * Note that most index AMs perform a no-op as a matter of policy for + * amvacuumcleanup() when called in ANALYZE-only mode. The only exception + * among core index AMs is GIN/ginvacuumcleanup(). + */ if (!(params->options & VACOPT_VACUUM)) { for (ind = 0; ind < nindexes; ind++) @@ -1081,15 +1130,90 @@ do_analyze_rel(Relation onerel, VacuumParams *params, /* Log the action if appropriate */ if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0) { + TimestampTz endtime = GetCurrentTimestamp(); + if (params->log_min_duration == 0 || - TimestampDifferenceExceeds(starttime, GetCurrentTimestamp(), + TimestampDifferenceExceeds(starttime, endtime, params->log_min_duration)) + { + long delay_in_ms; + double read_rate = 0; + double write_rate = 0; + StringInfoData buf; + + /* + * Calculate the difference in the Page Hit/Miss/Dirty that + * happened as part of the analyze by subtracting out the + * pre-analyze values which we saved above. + */ + AnalyzePageHit = VacuumPageHit - AnalyzePageHit; + AnalyzePageMiss = VacuumPageMiss - AnalyzePageMiss; + AnalyzePageDirty = VacuumPageDirty - AnalyzePageDirty; + + /* + * We do not expect an analyze to take > 25 days and it simplifies + * things a bit to use TimestampDifferenceMilliseconds. + */ + delay_in_ms = TimestampDifferenceMilliseconds(starttime, endtime); + + /* + * Note that we are reporting these read/write rates in the same + * manner as VACUUM does, which means that while the 'average read + * rate' here actually corresponds to page misses and resulting + * reads which are also picked up by track_io_timing, if enabled, + * the 'average write rate' is actually talking about the rate of + * pages being dirtied, not being written out, so it's typical to + * have a non-zero 'avg write rate' while I/O Timings only reports + * reads. + * + * It's not clear that an ANALYZE will ever result in + * FlushBuffer() being called, but we track and support reporting + * on I/O write time in case that changes as it's practically free + * to do so anyway. + */ + + if (delay_in_ms > 0) + { + read_rate = (double) BLCKSZ * AnalyzePageMiss / (1024 * 1024) / + (delay_in_ms / 1000.0); + write_rate = (double) BLCKSZ * AnalyzePageDirty / (1024 * 1024) / + (delay_in_ms / 1000.0); + } + + /* + * We split this up so we don't emit empty I/O timing values when + * track_io_timing isn't enabled. + */ + + initStringInfo(&buf); + appendStringInfo(&buf, _("automatic analyze of table \"%s.%s.%s\"\n"), + get_database_name(MyDatabaseId), + get_namespace_name(RelationGetNamespace(onerel)), + RelationGetRelationName(onerel)); + appendStringInfo(&buf, _("buffer usage: %lld hits, %lld misses, %lld dirtied\n"), + (long long) AnalyzePageHit, + (long long) AnalyzePageMiss, + (long long) AnalyzePageDirty); + appendStringInfo(&buf, _("avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n"), + read_rate, write_rate); + if (track_io_timing) + { + appendStringInfoString(&buf, _("I/O Timings:")); + if (pgStatBlockReadTime - startreadtime > 0) + appendStringInfo(&buf, _(" read=%.3f"), + (double) (pgStatBlockReadTime - startreadtime) / 1000); + if (pgStatBlockWriteTime - startwritetime > 0) + appendStringInfo(&buf, _(" write=%.3f"), + (double) (pgStatBlockWriteTime - startwritetime) / 1000); + appendStringInfoChar(&buf, '\n'); + } + appendStringInfo(&buf, _("system usage: %s"), pg_rusage_show(&ru0)); + ereport(LOG, - (errmsg("automatic analyze of table \"%s.%s.%s\" system usage: %s", - get_database_name(MyDatabaseId), - get_namespace_name(RelationGetNamespace(onerel)), - RelationGetRelationName(onerel), - pg_rusage_show(&ru0)))); + (errmsg_internal("%s", buf.data))); + + pfree(buf.data); + } } /* Roll back any GUC changes executed by index functions */ @@ -1447,6 +1571,7 @@ acquire_sample_rows(Relation onerel, int elevel, double liverows = 0; /* # live rows seen */ double deadrows = 0; /* # dead rows seen */ double rowstoskip = -1; /* -1 means not set yet */ + long randseed; /* Seed for block sampler(s) */ BlockNumber totalblocks; TransactionId OldestXmin; BlockSamplerData bs; @@ -1455,6 +1580,10 @@ acquire_sample_rows(Relation onerel, int elevel, TableScanDesc scan; BlockNumber nblocks; BlockNumber blksdone = 0; +#ifdef USE_PREFETCH + int prefetch_maximum = 0; /* blocks to prefetch if enabled */ + BlockSamplerData prefetch_bs; +#endif Assert(targrows > 0); @@ -1498,7 +1627,25 @@ acquire_sample_rows(Relation onerel, int elevel, OldestXmin = GetOldestNonRemovableTransactionId(onerel); /* Prepare for sampling block numbers */ - nblocks = BlockSampler_Init(&bs, totalblocks, targrows, random()); + randseed = random(); + nblocks = BlockSampler_Init(&bs, totalblocks, targrows, randseed); + +#ifdef USE_PREFETCH + prefetch_maximum = get_tablespace_io_concurrency(onerel->rd_rel->reltablespace); + + /* + * GPDB: for AO/AOCS the sampled "block numbers" are logical row + * numbers (see above), not buffer-manager blocks; prefetching them + * through PrefetchBuffer() would drive md into the append-optimized + * segment files and fail ("previous segment is only 0 blocks"). + */ + if (RelationIsAppendOptimized(onerel)) + prefetch_maximum = 0; + + /* Create another BlockSampler, using the same seed, for prefetching */ + if (prefetch_maximum) + (void) BlockSampler_Init(&prefetch_bs, totalblocks, targrows, randseed); +#endif /* Report sampling block numbers */ pgstat_progress_update_param(PROGRESS_ANALYZE_BLOCKS_TOTAL, @@ -1510,14 +1657,69 @@ acquire_sample_rows(Relation onerel, int elevel, scan = table_beginscan_analyze(onerel); slot = table_slot_create(onerel, NULL); +#ifdef USE_PREFETCH + + /* + * If we are doing prefetching, then go ahead and tell the kernel about + * the first set of pages we are going to want. This also moves our + * iterator out ahead of the main one being used, where we will keep it so + * that we're always pre-fetching out prefetch_maximum number of blocks + * ahead. + */ + if (prefetch_maximum) + { + for (int i = 0; i < prefetch_maximum; i++) + { + BlockNumber prefetch_block; + + if (!BlockSampler_HasMore(&prefetch_bs)) + break; + + prefetch_block = BlockSampler_Next(&prefetch_bs); + PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, prefetch_block); + } + } +#endif + /* Outer loop over blocks to sample */ while (BlockSampler_HasMore(&bs)) { + bool block_accepted; BlockNumber targblock = BlockSampler_Next(&bs); +#ifdef USE_PREFETCH + BlockNumber prefetch_targblock = InvalidBlockNumber; + + /* + * Make sure that every time the main BlockSampler is moved forward + * that our prefetch BlockSampler also gets moved forward, so that we + * always stay out ahead. + */ + if (prefetch_maximum && BlockSampler_HasMore(&prefetch_bs)) + prefetch_targblock = BlockSampler_Next(&prefetch_bs); +#endif vacuum_delay_point(); - if (!table_scan_analyze_next_block(scan, targblock, vac_strategy)) + block_accepted = table_scan_analyze_next_block(scan, targblock, vac_strategy); + +#ifdef USE_PREFETCH + + /* + * When pre-fetching, after we get a block, tell the kernel about the + * next one we will want, if there's any left. + * + * We want to do this even if the table_scan_analyze_next_block() call + * above decides against analyzing the block it picked. + */ + if (prefetch_maximum && prefetch_targblock != InvalidBlockNumber) + PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, prefetch_targblock); +#endif + + /* + * Don't analyze if table_scan_analyze_next_block() indicated this + * block is unsuitable for analyzing. + */ + if (!block_accepted) continue; while (table_scan_analyze_next_tuple(scan, OldestXmin, &liverows, &deadrows, slot)) diff --git a/src/backend/commands/analyzefuncs.c b/src/backend/commands/analyzefuncs.c index 6a4cdb545fef..817336e0e336 100644 --- a/src/backend/commands/analyzefuncs.c +++ b/src/backend/commands/analyzefuncs.c @@ -131,8 +131,8 @@ gp_acquire_sample_rows(PG_FUNCTION_ARGS) params.multixact_freeze_table_age = -1; params.is_wraparound = false; params.log_min_duration = -1; - params.index_cleanup = VACOPT_TERNARY_DEFAULT; - params.truncate = VACOPT_TERNARY_DEFAULT; + params.index_cleanup = VACOPTVALUE_UNSPECIFIED; + params.truncate = VACOPTVALUE_UNSPECIFIED; this_rangevar = makeRangeVar(get_namespace_name(onerel->rd_rel->relnamespace), pstrdup(RelationGetRelationName(onerel)), @@ -342,7 +342,7 @@ gp_acquire_sample_rows_col_type(Oid typid) */ return OIDOID; - case PGNODETREEOID: + case PG_NODE_TREEOID: /* * Input function of pg_node_tree doesn't allow loading * back values. Treat it as text. diff --git a/src/backend/commands/analyzeutils.c b/src/backend/commands/analyzeutils.c index 0246037277b8..d9f7a4a717b8 100644 --- a/src/backend/commands/analyzeutils.c +++ b/src/backend/commands/analyzeutils.c @@ -85,6 +85,18 @@ get_rel_reltuples(Oid relid) ReleaseSysCache(tp); } + /* + * Since PG 14, reltuples == -1 means the relation has never been + * vacuumed or analyzed. The GPDB stats-merging code that uses this + * helper predates that and expects the pre-14 value of 0: e.g. + * leaf_parts_analyzed() would otherwise mistake a never-analyzed + * partition for an analyzed non-empty one (and the root itself for a + * non-empty relation missing pg_statistic rows), disabling the leaf + * stats merge. + */ + if (relTuples < 0) + relTuples = 0; + return relTuples; } diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index b63f56d5c76a..906ca985d480 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -3,7 +3,7 @@ * async.c * Asynchronous notification: NOTIFY, LISTEN, UNLISTEN * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -255,7 +255,7 @@ typedef struct QueueBackendStatus * When holding NotifyQueueLock in EXCLUSIVE mode, backends can inspect the * entries of other backends and also change the head pointer. When holding * both NotifyQueueLock and NotifyQueueTailLock in EXCLUSIVE mode, backends - * can change the tail pointer. + * can change the tail pointers. * * NotifySLRULock is used as the control lock for the pg_notify SLRU buffers. * In order to avoid deadlocks, whenever we need multiple locks, we first get @@ -276,6 +276,8 @@ typedef struct AsyncQueueControl QueuePosition head; /* head points to the next free location */ QueuePosition tail; /* tail must be <= the queue position of every * listening backend */ + int stopPage; /* oldest unrecycled page; must be <= + * tail.page */ BackendId firstListener; /* id of first listener, or InvalidBackendId */ TimestampTz lastQueueFillWarn; /* time of last queue-full msg */ QueueBackendStatus backend[FLEXIBLE_ARRAY_MEMBER]; @@ -286,6 +288,7 @@ static AsyncQueueControl *asyncQueueControl; #define QUEUE_HEAD (asyncQueueControl->head) #define QUEUE_TAIL (asyncQueueControl->tail) +#define QUEUE_STOP_PAGE (asyncQueueControl->stopPage) #define QUEUE_FIRST_LISTENER (asyncQueueControl->firstListener) #define QUEUE_BACKEND_PID(i) (asyncQueueControl->backend[i].pid) #define QUEUE_BACKEND_DBOID(i) (asyncQueueControl->backend[i].dboid) @@ -487,7 +490,12 @@ asyncQueuePageDiff(int p, int q) return diff; } -/* Is p < q, accounting for wraparound? */ +/* + * Is p < q, accounting for wraparound? + * + * Since asyncQueueIsFull() blocks creation of a page that could precede any + * extant page, we need not assess entries within a page. + */ static bool asyncQueuePagePrecedes(int p, int q) { @@ -537,6 +545,7 @@ AsyncShmemInit(void) /* First time through, so initialize it */ SET_QUEUE_POS(QUEUE_HEAD, 0, 0); SET_QUEUE_POS(QUEUE_TAIL, 0, 0); + QUEUE_STOP_PAGE = 0; QUEUE_FIRST_LISTENER = InvalidBackendId; asyncQueueControl->lastQueueFillWarn = 0; /* zero'th entry won't be used, but let's initialize it anyway */ @@ -554,9 +563,8 @@ AsyncShmemInit(void) */ NotifyCtl->PagePrecedes = asyncQueuePagePrecedes; SimpleLruInit(NotifyCtl, "Notify", NUM_NOTIFY_BUFFERS, 0, - NotifySLRULock, "pg_notify", LWTRANCHE_NOTIFY_BUFFER); - /* Override default assumption that writes should be fsync'd */ - NotifyCtl->do_fsync = false; + NotifySLRULock, "pg_notify", LWTRANCHE_NOTIFY_BUFFER, + SYNC_HANDLER_NONE); if (!found) { @@ -1349,8 +1357,8 @@ asyncQueueIsFull(void) * logically precedes the current global tail pointer, ie, the head * pointer would wrap around compared to the tail. We cannot create such * a head page for fear of confusing slru.c. For safety we round the tail - * pointer back to a segment boundary (compare the truncation logic in - * asyncQueueAdvanceTail). + * pointer back to a segment boundary (truncation logic in + * asyncQueueAdvanceTail does not do this, so doing it here is optional). * * Note that this test is *not* dependent on how much space there is on * the current head page. This is necessary because asyncQueueAddEntries @@ -1359,7 +1367,7 @@ asyncQueueIsFull(void) nexthead = QUEUE_POS_PAGE(QUEUE_HEAD) + 1; if (nexthead > QUEUE_MAX_PAGE) nexthead = 0; /* wrap around */ - boundary = QUEUE_POS_PAGE(QUEUE_TAIL); + boundary = QUEUE_STOP_PAGE; boundary -= boundary % SLRU_PAGES_PER_SEGMENT; return asyncQueuePagePrecedes(nexthead, boundary); } @@ -1573,6 +1581,11 @@ pg_notification_queue_usage(PG_FUNCTION_ARGS) * Return the fraction of the queue that is currently occupied. * * The caller must hold NotifyQueueLock in (at least) shared mode. + * + * Note: we measure the distance to the logical tail page, not the physical + * tail page. In some sense that's wrong, but the relative position of the + * physical tail is affected by details such as SLRU segment boundaries, + * so that a result based on that is unpleasantly unstable. */ static double asyncQueueUsage(void) @@ -1918,7 +1931,6 @@ static void asyncQueueReadAllNotifications(void) { volatile QueuePosition pos; - QueuePosition oldpos; QueuePosition head; Snapshot snapshot; @@ -1933,7 +1945,7 @@ asyncQueueReadAllNotifications(void) LWLockAcquire(NotifyQueueLock, LW_SHARED); /* Assert checks that we have a valid state entry */ Assert(MyProcPid == QUEUE_BACKEND_PID(MyBackendId)); - pos = oldpos = QUEUE_BACKEND_POS(MyBackendId); + pos = QUEUE_BACKEND_POS(MyBackendId); head = QUEUE_HEAD; LWLockRelease(NotifyQueueLock); @@ -2180,7 +2192,23 @@ asyncQueueAdvanceTail(void) /* Restrict task to one backend per cluster; see SimpleLruTruncate(). */ LWLockAcquire(NotifyQueueTailLock, LW_EXCLUSIVE); - /* Compute the new tail. */ + /* + * Compute the new tail. Pre-v13, it's essential that QUEUE_TAIL be exact + * (ie, exactly match at least one backend's queue position), so it must + * be updated atomically with the actual computation. Since v13, we could + * get away with not doing it like that, but it seems prudent to keep it + * so. + * + * Also, because incoming backends will scan forward from QUEUE_TAIL, that + * must be advanced before we can truncate any data. Thus, QUEUE_TAIL is + * the logical tail, while QUEUE_STOP_PAGE is the physical tail, or oldest + * un-truncated page. When QUEUE_STOP_PAGE != QUEUE_POS_PAGE(QUEUE_TAIL), + * there are pages we can truncate but haven't yet finished doing so. + * + * For concurrency's sake, we don't want to hold NotifyQueueLock while + * performing SimpleLruTruncate. This is OK because no backend will try + * to access the pages we are in the midst of truncating. + */ LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE); min = QUEUE_HEAD; for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i)) @@ -2188,7 +2216,8 @@ asyncQueueAdvanceTail(void) Assert(QUEUE_BACKEND_PID(i) != InvalidPid); min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i)); } - oldtailpage = QUEUE_POS_PAGE(QUEUE_TAIL); + QUEUE_TAIL = min; + oldtailpage = QUEUE_STOP_PAGE; LWLockRelease(NotifyQueueLock); /* @@ -2207,16 +2236,16 @@ asyncQueueAdvanceTail(void) * release the lock again. */ SimpleLruTruncate(NotifyCtl, newtailpage); - } - /* - * Advertise the new tail. This changes asyncQueueIsFull()'s verdict for - * the segment immediately prior to the new tail, allowing fresh data into - * that segment. - */ - LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE); - QUEUE_TAIL = min; - LWLockRelease(NotifyQueueLock); + /* + * Update QUEUE_STOP_PAGE. This changes asyncQueueIsFull()'s verdict + * for the segment immediately prior to the old tail, allowing fresh + * data into that segment. + */ + LWLockAcquire(NotifyQueueLock, LW_EXCLUSIVE); + QUEUE_STOP_PAGE = newtailpage; + LWLockRelease(NotifyQueueLock); + } LWLockRelease(NotifyQueueTailLock); } @@ -2288,8 +2317,7 @@ NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid) pq_beginmessage(&buf, 'A'); pq_sendint32(&buf, srcPid); pq_sendstring(&buf, channel); - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - pq_sendstring(&buf, payload); + pq_sendstring(&buf, payload); pq_endmessage(&buf); /* @@ -2357,7 +2385,6 @@ AddEventToPendingNotifies(Notification *n) ListCell *l; /* Create the hash table */ - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Notification *); hash_ctl.entrysize = sizeof(NotificationHash); hash_ctl.hash = notification_hash; diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 11d7ee15c41a..d9ae4f4bc66e 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -8,7 +8,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * @@ -43,6 +43,7 @@ #include "catalog/pg_type.h" #include "catalog/toasting.h" #include "commands/cluster.h" +#include "commands/defrem.h" #include "commands/progress.h" #include "commands/tablecmds.h" #include "commands/vacuum.h" @@ -116,8 +117,29 @@ static List *get_tables_to_cluster(MemoryContext cluster_context); *--------------------------------------------------------------------------- */ void -cluster(ClusterStmt *stmt, bool isTopLevel) +cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel) { + ListCell *lc; + ClusterParams params = {0}; + bool verbose = false; + + /* Parse option list */ + foreach(lc, stmt->params) + { + DefElem *opt = (DefElem *) lfirst(lc); + + if (strcmp(opt->defname, "verbose") == 0) + verbose = defGetBoolean(opt); + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized CLUSTER option \"%s\"", + opt->defname), + parser_errposition(pstate, opt->location))); + } + + params.options = (verbose ? CLUOPT_VERBOSE : 0); + if (stmt->relation != NULL) { /* This is the single-relation case. */ @@ -187,7 +209,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel) table_close(rel, NoLock); /* Do the job. */ - cluster_rel(tableOid, indexOid, stmt->options, true /* printError */); + cluster_rel(tableOid, indexOid, ¶ms); if (Gp_role == GP_ROLE_DISPATCH) { @@ -240,17 +262,18 @@ cluster(ClusterStmt *stmt, bool isTopLevel) { RelToCluster *rvtc = (RelToCluster *) lfirst(rv); bool dispatch; + ClusterParams cluster_params = params; /* Start a new transaction for each relation. */ StartTransactionCommand(); /* functions in indexes may want a snapshot set */ PushActiveSnapshot(GetTransactionSnapshot()); /* Do the job. */ - dispatch = cluster_rel(rvtc->tableOid, rvtc->indexOid, - stmt->options | CLUOPT_RECHECK, - false /* printError */); + cluster_params.options |= CLUOPT_RECHECK; + cluster_rel(rvtc->tableOid, rvtc->indexOid, + &cluster_params); - if (Gp_role == GP_ROLE_DISPATCH && dispatch) + if (Gp_role == GP_ROLE_DISPATCH) { stmt->relation = makeNode(RangeVar); stmt->relation->schemaname = get_namespace_name(get_rel_namespace(rvtc->tableOid)); @@ -295,12 +318,12 @@ cluster(ClusterStmt *stmt, bool isTopLevel) * this function errors out when the relation is an AO table. Otherwise, this * functions prints out a warning message when the relation is an AO table. */ -bool -cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) +void +cluster_rel(Oid tableOid, Oid indexOid, ClusterParams *params) { Relation OldHeap; - bool verbose = ((options & CLUOPT_VERBOSE) != 0); - bool recheck = ((options & CLUOPT_RECHECK) != 0); + bool verbose = ((params->options & CLUOPT_VERBOSE) != 0); + bool recheck = ((params->options & CLUOPT_RECHECK) != 0); /* Check for user-requested abort. */ CHECK_FOR_INTERRUPTS(); @@ -325,7 +348,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) if (!OldHeap) { pgstat_progress_end_command(); - return false; + return; } /* @@ -343,7 +366,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) { relation_close(OldHeap, AccessExclusiveLock); pgstat_progress_end_command(); - return false; + return; } /* @@ -358,7 +381,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) { relation_close(OldHeap, AccessExclusiveLock); pgstat_progress_end_command(); - return false; + return; } if (OidIsValid(indexOid)) @@ -370,7 +393,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) { relation_close(OldHeap, AccessExclusiveLock); pgstat_progress_end_command(); - return false; + return; } /* @@ -380,7 +403,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) { relation_close(OldHeap, AccessExclusiveLock); pgstat_progress_end_command(); - return false; + return; } } } @@ -434,7 +457,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) { relation_close(OldHeap, AccessExclusiveLock); pgstat_progress_end_command(); - return false; + return; } /* @@ -451,7 +474,7 @@ cluster_rel(Oid tableOid, Oid indexOid, int options, bool printError) /* NB: rebuild_relation does table_close() on OldHeap */ pgstat_progress_end_command(); - return true; + return; } /* @@ -1617,6 +1640,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, ObjectAddress object; Oid mapped_tables[4]; int reindex_flags; + ReindexParams reindex_params = {0}; int i; /* Report that we are now swapping relation files */ @@ -1678,14 +1702,14 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, PROGRESS_CLUSTER_PHASE_REBUILD_INDEX); - reindex_relation(OIDOldHeap, reindex_flags, 0); + reindex_relation(OIDOldHeap, reindex_flags, &reindex_params); /* Report that we are now doing clean up */ pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, PROGRESS_CLUSTER_PHASE_FINAL_CLEANUP); /* - * If the relation being rebuild is pg_class, swap_relation_files() + * If the relation being rebuilt is pg_class, swap_relation_files() * couldn't update pg_class's own pg_class entry (check comments in * swap_relation_files()), thus relfrozenxid was not updated. That's * annoying because a potential reason for doing a VACUUM FULL is a diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 6d4765aa76c2..e917f01fe914 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -3,7 +3,7 @@ * collationcmds.c * collation-related commands support code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -27,6 +27,7 @@ #include "commands/comment.h" #include "commands/dbcommands.h" #include "commands/defrem.h" +#include "common/string.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "utils/acl.h" @@ -407,23 +408,6 @@ pg_collation_actual_version(PG_FUNCTION_ARGS) #define READ_LOCALE_A_OUTPUT #endif -#if defined(READ_LOCALE_A_OUTPUT) || defined(USE_ICU) -/* - * Check a string to see if it is pure ASCII - */ -static bool -is_all_ascii(const char *str) -{ - while (*str) - { - if (IS_HIGHBIT_SET(*str)) - return false; - str++; - } - return true; -} -#endif /* READ_LOCALE_A_OUTPUT || USE_ICU */ - #ifdef READ_LOCALE_A_OUTPUT /* * "Normalize" a libc locale name, stripping off encoding tags such as @@ -522,7 +506,7 @@ get_icu_language_tag(const char *localename) UErrorCode status; status = U_ZERO_ERROR; - uloc_toLanguageTag(localename, buf, sizeof(buf), TRUE, &status); + uloc_toLanguageTag(localename, buf, sizeof(buf), true, &status); if (U_FAILURE(status)) ereport(ERROR, (errmsg("could not convert locale name \"%s\" to language tag: %s", @@ -553,7 +537,7 @@ get_icu_locale_comment(const char *localename) if (U_FAILURE(status)) return NULL; /* no good reason to raise an error */ - /* Check for non-ASCII comment (can't use is_all_ascii for this) */ + /* Check for non-ASCII comment (can't use pg_is_ascii for this) */ for (i = 0; i < len_uchar; i++) { if (displayname[i] > 127) @@ -580,9 +564,6 @@ pg_import_system_collations(PG_FUNCTION_ARGS) Oid nspid = PG_GETARG_OID(0); int ncreated = 0; - /* silence compiler warning if we have no locale implementation at all */ - (void) nspid; - if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), @@ -591,6 +572,10 @@ pg_import_system_collations(PG_FUNCTION_ARGS) if (Gp_role != GP_ROLE_DISPATCH) ereport(ERROR, (errmsg("must be dispatcher to import system collations"))); + if (!SearchSysCacheExists1(NAMESPACEOID, ObjectIdGetDatum(nspid))) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_SCHEMA), + errmsg("schema with OID %u does not exist", nspid))); /* Load collations known to libc, using "locale -a" to enumerate them */ #ifdef READ_LOCALE_A_OUTPUT @@ -638,7 +623,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS) * interpret the non-ASCII characters. We can't do much with * those, so we filter them out. */ - if (!is_all_ascii(localebuf)) + if (!pg_is_ascii(localebuf)) { elog(DEBUG1, "locale name has non-ASCII characters, skipped: \"%s\"", localebuf); continue; @@ -764,7 +749,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS) * We use uloc_countAvailable()/uloc_getAvailable() rather than * ucol_countAvailable()/ucol_getAvailable(). The former returns a full * set of language+region combinations, whereas the latter only returns - * language+region combinations of they are distinct from the language's + * language+region combinations if they are distinct from the language's * base collation. So there might not be a de-DE or en-GB, which would be * confusing. */ @@ -796,7 +781,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS) * Be paranoid about not allowing any non-ASCII strings into * pg_collation */ - if (!is_all_ascii(langtag) || !is_all_ascii(collcollate)) + if (!pg_is_ascii(langtag) || !pg_is_ascii(collcollate)) continue; collid = CollationCreate(psprintf("%s-x-icu", langtag), diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 9f2cb01398b7..50b96977d02c 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -4,7 +4,7 @@ * * PostgreSQL object comments utility code. * - * Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/commands/comment.c diff --git a/src/backend/commands/constraint.c b/src/backend/commands/constraint.c index fc19307bf2fb..d0063164a7e4 100644 --- a/src/backend/commands/constraint.c +++ b/src/backend/commands/constraint.c @@ -3,7 +3,7 @@ * constraint.c * PostgreSQL CONSTRAINT support code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -175,7 +175,7 @@ unique_key_recheck(PG_FUNCTION_ARGS) */ index_insert(indexRel, values, isnull, &checktid, trigdata->tg_relation, UNIQUE_CHECK_EXISTING, - indexInfo); + false, indexInfo); } else { diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c index 0b0cfeb01a2d..138098bcf8c7 100644 --- a/src/backend/commands/conversioncmds.c +++ b/src/backend/commands/conversioncmds.c @@ -3,7 +3,7 @@ * conversioncmds.c * conversion creation command support code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -49,8 +49,9 @@ CreateConversionCommand(CreateConversionStmt *stmt) const char *from_encoding_name = stmt->for_encoding_name; const char *to_encoding_name = stmt->to_encoding_name; List *func_name = stmt->func_name; - static const Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID}; + static const Oid funcargs[] = {INT4OID, INT4OID, CSTRINGOID, INTERNALOID, INT4OID, BOOLOID}; char result[1]; + Datum funcresult; /* Convert list of names to a name and namespace */ namespaceId = QualifiedNameGetCreationNamespace(stmt->conversion_name, @@ -96,12 +97,12 @@ CreateConversionCommand(CreateConversionStmt *stmt) funcoid = LookupFuncName(func_name, sizeof(funcargs) / sizeof(Oid), funcargs, false); - /* Check it returns VOID, else it's probably the wrong function */ - if (get_func_rettype(funcoid) != VOIDOID) + /* Check it returns int4, else it's probably the wrong function */ + if (get_func_rettype(funcoid) != INT4OID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("encoding conversion function %s must return type %s", - NameListToString(func_name), "void"))); + NameListToString(func_name), "integer"))); /* Check we have EXECUTE rights for the function */ aclresult = pg_proc_aclcheck(funcoid, GetUserId(), ACL_EXECUTE); @@ -115,12 +116,23 @@ CreateConversionCommand(CreateConversionStmt *stmt) * string; the conversion function should throw an error if it can't * perform the requested conversion. */ - OidFunctionCall5(funcoid, - Int32GetDatum(from_encoding), - Int32GetDatum(to_encoding), - CStringGetDatum(""), - CStringGetDatum(result), - Int32GetDatum(0)); + funcresult = OidFunctionCall6(funcoid, + Int32GetDatum(from_encoding), + Int32GetDatum(to_encoding), + CStringGetDatum(""), + CStringGetDatum(result), + Int32GetDatum(0), + BoolGetDatum(false)); + + /* + * The function should return 0 for empty input. Might as well check that, + * too. + */ + if (DatumGetInt32(funcresult) != 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("encoding conversion function %s returned incorrect result for empty input", + NameListToString(func_name)))); /* * All seem ok, go ahead (possible failure would be a duplicate conversion diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 93853224bb05..5409a6b1669d 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,151 +16,91 @@ */ #include "postgres.h" -#include "libpq-int.h" - #include #include #include +#include "libpq-int.h" + #include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" -#include "access/tableam.h" +#include "access/table.h" #include "access/xact.h" -#include "access/xlog.h" -#include "catalog/dependency.h" +#include "catalog/catalog.h" +#include "catalog/namespace.h" #include "catalog/pg_authid.h" #include "catalog/pg_type.h" +#include "cdb/cdbappendonlyam.h" +#include "cdb/cdbaocsam.h" +#include "cdb/cdbconn.h" +#include "cdb/cdbcopy.h" +#include "cdb/cdbdisp_query.h" +#include "cdb/cdbdispatchresult.h" +#include "cdb/cdbsreh.h" +#include "cdb/cdbvars.h" #include "commands/copy.h" +#include "commands/copyfrom_internal.h" +#include "libpq/libpq.h" +#include "libpq/pqformat.h" #include "commands/defrem.h" #include "commands/trigger.h" #include "executor/execPartition.h" #include "executor/executor.h" #include "executor/nodeModifyTable.h" -#include "executor/tuptable.h" #include "foreign/fdwapi.h" -#include "libpq/libpq.h" -#include "libpq/pqformat.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "optimizer/optimizer.h" #include "parser/parse_coerce.h" +#include "postmaster/autostats.h" #include "parser/parse_collate.h" #include "parser/parse_expr.h" #include "parser/parse_relation.h" -#include "port/pg_bswap.h" #include "rewrite/rewriteHandler.h" #include "storage/fd.h" #include "storage/execute_pipe.h" #include "tcop/tcopprot.h" +#include "access/url.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/memutils.h" -#include "utils/partcache.h" -#include "utils/portal.h" #include "utils/rel.h" -#include "utils/rls.h" -#include "utils/snapmgr.h" - -#include "access/external.h" -#include "access/url.h" -#include "catalog/catalog.h" -#include "catalog/namespace.h" -#include "catalog/pg_extprotocol.h" -#include "cdb/cdbappendonlyam.h" -#include "cdb/cdbaocsam.h" -#include "cdb/cdbconn.h" -#include "cdb/cdbcopy.h" -#include "cdb/cdbdisp_query.h" -#include "cdb/cdbdispatchresult.h" -#include "cdb/cdbsreh.h" -#include "cdb/cdbvars.h" -#include "commands/queue.h" -#include "nodes/makefuncs.h" -#include "postmaster/autostats.h" #include "utils/metrics_utils.h" -#include "utils/resscheduler.h" +#include "utils/rls.h" #include "utils/string_utils.h" -#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7')) -#define OCTVALUE(c) ((c) - '0') - /* - * Represents the heap insert method to be used during COPY FROM. - */ -typedef enum CopyInsertMethod -{ - CIM_SINGLE, /* use table_tuple_insert or fdw routine */ - CIM_MULTI, /* always use table_multi_insert */ - CIM_MULTI_CONDITIONAL /* use table_multi_insert only if valid */ -} CopyInsertMethod; - -/* - * No more than this many tuples per CopyMultiInsertBuffer + * The following macros aid in major refactoring of data processing code (in + * CopyFrom(+Dispatch)). We use macros because in some cases the code must be in + * line in order to work (for example elog_dismiss() in PG_CATCH) while in + * other cases we'd like to inline the code for performance reasons. * - * Caution: Don't make this too big, as we could end up with this many - * CopyMultiInsertBuffer items stored in CopyMultiInsertInfo's - * multiInsertBuffers list. Increasing this can cause quadratic growth in - * memory requirements during copies into partitioned tables with a large - * number of partitions. - */ -#define MAX_BUFFERED_TUPLES 1000 - -/* - * Flush buffers if there are >= this many bytes, as counted by the input - * size, of tuples stored. + * NOTE that an almost identical set of macros exists in fileam.c. If you make + * changes here you may want to consider taking a look there as well. + * ========================================================================== */ -#define MAX_BUFFERED_BYTES 65535 - -/* Trim the list of buffers back down to this number after flushing */ -#define MAX_PARTITION_BUFFERS 32 -/* Stores multi-insert data related to a single relation in CopyFrom. */ -typedef struct CopyMultiInsertBuffer -{ - TupleTableSlot *slots[MAX_BUFFERED_TUPLES]; /* Array to store tuples */ - ResultRelInfo *resultRelInfo; /* ResultRelInfo for 'relid' */ - BulkInsertState bistate; /* BulkInsertState for this rel */ - int nused; /* number of 'slots' containing tuples */ - uint64 linenos[MAX_BUFFERED_TUPLES]; /* Line # of tuple in copy - * stream */ -} CopyMultiInsertBuffer; +#define RESET_LINEBUF \ +cstate->line_buf.len = 0; \ +cstate->line_buf.data[0] = '\0'; \ +cstate->line_buf.cursor = 0; -/* - * Stores one or many CopyMultiInsertBuffers and details about the size and - * number of tuples which are stored in them. This allows multiple buffers to - * exist at once when COPYing into a partitioned table. - */ -typedef struct CopyMultiInsertInfo -{ - List *multiInsertBuffers; /* List of tracked CopyMultiInsertBuffers */ - int bufferedTuples; /* number of tuples buffered over all buffers */ - int bufferedBytes; /* number of bytes from all buffered tuples */ - CopyState cstate; /* Copy state for this CopyMultiInsertInfo */ - EState *estate; /* Executor state used for COPY */ - CommandId mycid; /* Command Id used for COPY */ - int ti_options; /* table insert options */ -} CopyMultiInsertInfo; +#define RESET_ATTRBUF \ +cstate->attribute_buf.len = 0; \ +cstate->attribute_buf.data[0] = '\0'; \ +cstate->attribute_buf.cursor = 0; +#define RESET_LINEBUF_WITH_LINENO \ +line_buf_with_lineno.len = 0; \ +line_buf_with_lineno.data[0] = '\0'; \ +line_buf_with_lineno.cursor = 0; -/* - * These macros centralize code used to process line_buf and raw_buf buffers. - * They are macros because they often do continue/break control and to avoid - * function call overhead in tight COPY loops. - * - * We must use "if (1)" because the usual "do {...} while(0)" wrapper would - * prevent the continue/break processing from working. We end the "if (1)" - * with "else ((void) 0)" to ensure the "if" does not unintentionally match - * any "else" in the calling code, and to avoid any compiler warnings about - * empty statements. See http://www.cit.gu.edu.au/~anthony/info/C/C.macros. - */ +#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7')) +#define OCTVALUE(c) ((c) - '0') -/* - * This keeps the character read at the top of the loop in the buffer - * even if there is more than one read-ahead. - */ #define IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(extralen) \ if (1) \ { \ @@ -172,7 +112,6 @@ if (1) \ } \ } else ((void) 0) -/* This consumes the remainder of the buffer and breaks */ #define IF_NEED_REFILL_AND_EOF_BREAK(extralen) \ if (1) \ { \ @@ -186,10 +125,6 @@ if (1) \ } \ } else ((void) 0) -/* - * Transfer any approved data to line_buf; must do this to be sure - * there is some room in raw_buf. - */ #define REFILL_LINEBUF \ if (1) \ { \ @@ -202,7 +137,6 @@ if (1) \ } \ } else ((void) 0) -/* Undo any read-ahead and jump out of the block. */ #define NO_END_OF_COPY_GOTO \ if (1) \ { \ @@ -210,107 +144,6 @@ if (1) \ goto not_end_of_copy; \ } else ((void) 0) -static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"; - - -/* non-export function prototypes */ -static void EndCopy(CopyState cstate); -static CopyState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query, - Oid queryRelId, const char *filename, bool is_program, - List *attnamelist, List *options); -static void EndCopyTo(CopyState cstate, uint64 *processed); -static uint64 DoCopyTo(CopyState cstate); -static uint64 CopyToDispatch(CopyState cstate); -static uint64 CopyTo(CopyState cstate); -static uint64 CopyDispatchOnSegment(CopyState cstate, const CopyStmt *stmt); -static uint64 CopyToQueryOnSegment(CopyState cstate); -static bool CopyReadLine(CopyState cstate); -static bool CopyReadLineText(CopyState cstate); -static int CopyReadAttributesText(CopyState cstate, int stop_processing_at_field); -static int CopyReadAttributesCSV(CopyState cstate, int stop_processing_at_field); -static Datum CopyReadBinaryAttribute(CopyState cstate, FmgrInfo *flinfo, - Oid typioparam, int32 typmod, - bool *isnull); -static void CopyAttributeOutText(CopyState cstate, char *string); -static void CopyAttributeOutCSV(CopyState cstate, char *string, - bool use_quote, bool single_attr); - -/* Low-level communications functions */ -static void SendCopyBegin(CopyState cstate); -static void ReceiveCopyBegin(CopyState cstate); -static void SendCopyEnd(CopyState cstate); -static void CopySendData(CopyState cstate, const void *databuf, int datasize); -static void CopySendString(CopyState cstate, const char *str); -static void CopySendChar(CopyState cstate, char c); -static int CopyGetData(CopyState cstate, void *databuf, int datasize); -static void CopySendInt32(CopyState cstate, int32 val); -static bool CopyGetInt32(CopyState cstate, int32 *val); -static void CopySendInt16(CopyState cstate, int16 val); -static bool CopyGetInt16(CopyState cstate, int16 *val); -static bool CopyLoadRawBuf(CopyState cstate); -static int CopyReadBinaryData(CopyState cstate, char *dest, int nbytes); - -static void SendCopyFromForwardedTuple(CopyState cstate, - CdbCopy *cdbCopy, - bool toAll, - int target_seg, - Relation rel, - int64 lineno, - char *line, - int line_len, - Datum *values, - bool *nulls); -static void SendCopyFromForwardedHeader(CopyState cstate, CdbCopy *cdbCopy); -static void SendCopyFromForwardedError(CopyState cstate, CdbCopy *cdbCopy, char *errmsg); - -static bool NextCopyFromDispatch(CopyState cstate, ExprContext *econtext, - Datum *values, bool *nulls); -static bool NextCopyFromExecute(CopyState cstate, ExprContext *econtext, Datum *values, bool *nulls); -static bool NextCopyFromRawFieldsX(CopyState cstate, char ***fields, int *nfields, - int stop_processing_at_field); -static bool NextCopyFromX(CopyState cstate, ExprContext *econtext, - Datum *values, bool *nulls); -static void HandleCopyError(CopyState cstate); -static void HandleQDErrorFrame(CopyState cstate, char *p, int len); - -static void setEncodingConversionProc(CopyState cstate, int encoding, bool iswritable); - -static GpDistributionData *InitDistributionData(CopyState cstate, EState *estate); -static void FreeDistributionData(GpDistributionData *distData); -static void InitCopyFromDispatchSplit(CopyState cstate, GpDistributionData *distData, EState *estate); -static unsigned int GetTargetSeg(GpDistributionData *distData, TupleTableSlot *slot); -static ProgramPipes *open_program_pipes(char *command, bool forwrite); -static void close_program_pipes(CopyState cstate, bool ifThrow); -CopyIntoClause* -MakeCopyIntoClause(CopyStmt *stmt); -static List *parse_joined_option_list(char *str, char *delimiter); - -/* ========================================================================== - * The following macros aid in major refactoring of data processing code (in - * CopyFrom(+Dispatch)). We use macros because in some cases the code must be in - * line in order to work (for example elog_dismiss() in PG_CATCH) while in - * other cases we'd like to inline the code for performance reasons. - * - * NOTE that an almost identical set of macros exists in fileam.c. If you make - * changes here you may want to consider taking a look there as well. - * ========================================================================== - */ - -#define RESET_LINEBUF \ -cstate->line_buf.len = 0; \ -cstate->line_buf.data[0] = '\0'; \ -cstate->line_buf.cursor = 0; - -#define RESET_ATTRBUF \ -cstate->attribute_buf.len = 0; \ -cstate->attribute_buf.data[0] = '\0'; \ -cstate->attribute_buf.cursor = 0; - -#define RESET_LINEBUF_WITH_LINENO \ -line_buf_with_lineno.len = 0; \ -line_buf_with_lineno.data[0] = '\0'; \ -line_buf_with_lineno.cursor = 0; - static volatile CopyState glob_cstate = NULL; @@ -357,6 +190,79 @@ extern bool Test_copy_qd_qe_split; * just collects and forwards them to the client. The QD doesn't need to parse * the rows at all. */ +#define MAX_BUFFERED_TUPLES 1000 +#define MAX_BUFFERED_BYTES 65535 +#define MAX_PARTITION_BUFFERS 32 + +typedef struct CopyMultiInsertBuffer +{ + TupleTableSlot *slots[MAX_BUFFERED_TUPLES]; + ResultRelInfo *resultRelInfo; + BulkInsertState bistate; + int nused; + uint64 linenos[MAX_BUFFERED_TUPLES]; +} CopyMultiInsertBuffer; + +typedef struct CopyMultiInsertInfo +{ + List *multiInsertBuffers; + int bufferedTuples; + int bufferedBytes; + CopyState cstate; + EState *estate; + CommandId mycid; + int ti_options; +} CopyMultiInsertInfo; + +static void close_program_pipes(CopyState cstate, bool ifThrow); +static int CopyReadBinaryData(CopyState cstate, char *dest, int nbytes); +static bool CopyReadLine(CopyState cstate); +static bool CopyReadLineText(CopyState cstate); +static bool NextCopyFromRawFieldsX(CopyState cstate, char ***fields, int *nfields, + int stop_processing_at_field); +static bool NextCopyFromX(CopyState cstate, ExprContext *econtext, + Datum *values, bool *nulls); +static bool NextCopyFromDispatch(CopyState cstate, ExprContext *econtext, + Datum *values, bool *nulls); +static bool NextCopyFromExecute(CopyState cstate, ExprContext *econtext, + Datum *values, bool *nulls); +static void HandleQDErrorFrame(CopyState cstate, char *p, int len); +static void SendCopyFromForwardedError(CopyState cstate, CdbCopy *cdbCopy, char *errormsg); +static void SendCopyFromForwardedHeader(CopyState cstate, CdbCopy *cdbCopy); +static void SendCopyFromForwardedTuple(CopyState cstate, + CdbCopy *cdbCopy, + bool toAll, + int target_seg, + Relation rel, + int64 lineno, + char *line, + int line_len, + Datum *values, + bool *nulls); +static int CopyReadAttributesText(CopyState cstate, int stop_processing_at_field); +static int CopyReadAttributesCSV(CopyState cstate, int stop_processing_at_field); +static void FreeDistributionData(GpDistributionData *distData); +static void InitCopyFromDispatchSplit(CopyState cstate, GpDistributionData *distData, + EState *estate); +static void HandleCopyError(CopyState cstate); +static uint64 CopyDispatchOnSegment(CopyState cstate, const CopyStmt *stmt); +static uint64 CopyToDispatch(CopyState cstate); +static uint64 CopyToQueryOnSegment(CopyState cstate); +static uint64 CopyTo(CopyState cstate); +static void CopyAttributeOutText(CopyState cstate, char *string); +static void CopyAttributeOutCSV(CopyState cstate, char *string, + bool use_quote, bool single_attr); +static void setEncodingConversionProc(CopyState cstate, int encoding, bool iswritable); +static CopyIntoClause *MakeCopyIntoClause(CopyStmt *stmt); +static Datum CopyReadBinaryAttribute(CopyState cstate, FmgrInfo *flinfo, + Oid typioparam, int32 typmod, bool *isnull); +static GpDistributionData *InitDistributionData(CopyState cstate, EState *estate); +static unsigned int GetTargetSeg(GpDistributionData *distData, TupleTableSlot *slot); +static ProgramPipes *open_program_pipes(char *command, bool forwrite); +static List *parse_joined_option_list(char *str, char *delimiter); + + +static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"; static const char QDtoQESignature[] = "PGCOPY-QD-TO-QE\n\377\r\n"; /* Header contains information that applies to all the rows that follow. */ @@ -442,68 +348,36 @@ typedef struct static void SendCopyBegin(CopyState cstate) { - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - { - /* new way */ - StringInfoData buf; - int natts = list_length(cstate->attnumlist); - int16 format = (cstate->binary ? 1 : 0); - int i; + StringInfoData buf; + int natts = list_length(cstate->attnumlist); + int16 format = (cstate->binary ? 1 : 0); + int i; - pq_beginmessage(&buf, 'H'); - pq_sendbyte(&buf, format); /* overall format */ - pq_sendint16(&buf, natts); - for (i = 0; i < natts; i++) - pq_sendint16(&buf, format); /* per-column formats */ - pq_endmessage(&buf); - cstate->copy_dest = COPY_NEW_FE; - } - else - { - /* old way */ - if (cstate->binary) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("COPY BINARY is not supported to stdout or from stdin"))); - pq_putemptymessage('H'); - /* grottiness needed for old COPY OUT protocol */ - pq_startcopyout(); - cstate->copy_dest = COPY_OLD_FE; - } + pq_beginmessage(&buf, 'H'); + pq_sendbyte(&buf, format); /* overall format */ + pq_sendint16(&buf, natts); + for (i = 0; i < natts; i++) + pq_sendint16(&buf, format); /* per-column formats */ + pq_endmessage(&buf); + cstate->copy_dest = COPY_FRONTEND; } -static void +void ReceiveCopyBegin(CopyState cstate) { - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - { - /* new way */ - StringInfoData buf; - int natts = list_length(cstate->attnumlist); - int16 format = (cstate->binary ? 1 : 0); - int i; + StringInfoData buf; + int natts = list_length(cstate->attnumlist); + int16 format = (cstate->binary ? 1 : 0); + int i; - pq_beginmessage(&buf, 'G'); - pq_sendbyte(&buf, format); /* overall format */ - pq_sendint16(&buf, natts); - for (i = 0; i < natts; i++) - pq_sendint16(&buf, format); /* per-column formats */ - pq_endmessage(&buf); - cstate->copy_dest = COPY_NEW_FE; - cstate->fe_msgbuf = makeStringInfo(); - } - else - { - /* old way */ - if (cstate->binary) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("COPY BINARY is not supported to stdout or from stdin"))); - pq_putemptymessage('G'); - /* any error in old protocol will make us lose sync */ - pq_startmsgread(); - cstate->copy_dest = COPY_OLD_FE; - } + pq_beginmessage(&buf, 'G'); + pq_sendbyte(&buf, format); /* overall format */ + pq_sendint16(&buf, natts); + for (i = 0; i < natts; i++) + pq_sendint16(&buf, format); /* per-column formats */ + pq_endmessage(&buf); + cstate->copy_dest = COPY_FRONTEND; + cstate->fe_msgbuf = makeStringInfo(); /* We *must* flush here to ensure FE knows it can send. */ pq_flush(); } @@ -511,20 +385,10 @@ ReceiveCopyBegin(CopyState cstate) static void SendCopyEnd(CopyState cstate) { - if (cstate->copy_dest == COPY_NEW_FE) - { - /* Shouldn't have any unsent data */ - Assert(cstate->fe_msgbuf->len == 0); - /* Send Copy Done message */ - pq_putemptymessage('c'); - } - else - { - CopySendData(cstate, "\\.", 2); - /* Need to flush out the trailer (this also appends a newline) */ - CopySendEndOfRow(cstate); - pq_endcopyout(false); - } + /* Shouldn't have any unsent data */ + Assert(cstate->fe_msgbuf->len == 0); + /* Send Copy Done message */ + pq_putemptymessage('c'); } /*---------- @@ -611,20 +475,7 @@ CopySendEndOfRow(CopyState cstate) errmsg("could not write to COPY file: %m"))); } break; - case COPY_OLD_FE: - /* The FE/BE protocol uses \n as newline for all platforms */ - if (!cstate->binary) - CopySendChar(cstate, '\n'); - - if (pq_putbytes(fe_msgbuf->data, fe_msgbuf->len)) - { - /* no hope of recovering connection sync, so FATAL */ - ereport(FATAL, - (errcode(ERRCODE_CONNECTION_FAILURE), - errmsg("connection lost during COPY to stdout"))); - } - break; - case COPY_NEW_FE: + case COPY_FRONTEND: /* The FE/BE protocol uses \n as newline for all platforms */ if (!cstate->binary) CopySendChar(cstate, '\n'); @@ -693,18 +544,7 @@ CopyToDispatchFlush(CopyState cstate) errmsg("could not write to COPY file: %m"))); } break; - case COPY_OLD_FE: - - if (pq_putbytes(fe_msgbuf->data, fe_msgbuf->len)) - { - /* no hope of recovering connection sync, so FATAL */ - ereport(FATAL, - (errcode(ERRCODE_CONNECTION_FAILURE), - errmsg("connection lost during COPY to stdout"))); - } - break; - case COPY_NEW_FE: - + case COPY_FRONTEND: /* Dump the accumulated row as one CopyData message */ (void) pq_putmessage('d', fe_msgbuf->data, fe_msgbuf->len); break; @@ -764,18 +604,7 @@ CopyGetData(CopyState cstate, void *databuf, int datasize) errmsg("could not read from COPY file: %m"))); } break; - case COPY_OLD_FE: - if (pq_getbytes((char *) databuf, datasize)) - { - /* Only a \. terminator is legal EOF in old protocol */ - ereport(ERROR, - (errcode(ERRCODE_CONNECTION_FAILURE), - errmsg("unexpected EOF on client connection with an open transaction"))); - } - bytesread += datasize; /* update the count of bytes that were - * read so far */ - break; - case COPY_NEW_FE: + case COPY_FRONTEND: while (datasize > 0 && !cstate->reached_eof) { int avail; @@ -992,7 +821,6 @@ CopyReadBinaryData(CopyState cstate, char *dest, int nbytes) return copied_bytes; } - /* * DoCopy executes the SQL COPY statement * @@ -1055,7 +883,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, { if (stmt->is_program) { - if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_EXECUTE_SERVER_PROGRAM)) + if (!is_member_of_role(GetUserId(), ROLE_PG_EXECUTE_SERVER_PROGRAM)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program"), @@ -1064,14 +892,14 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, } else { - if (is_from && !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_SERVER_FILES)) + if (is_from && !is_member_of_role(GetUserId(), ROLE_PG_READ_SERVER_FILES)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or a member of the pg_read_server_files role to COPY from a file"), errhint("Anyone can COPY to stdout or from stdin. " "psql's \\copy command also works for anyone."))); - if (!is_from && !is_member_of_role(GetUserId(), DEFAULT_ROLE_WRITE_SERVER_FILES)) + if (!is_from && !is_member_of_role(GetUserId(), ROLE_PG_WRITE_SERVER_FILES)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or a member of the pg_write_server_files role to COPY to a file"), @@ -1282,6 +1110,8 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, if (is_from) { + CopyState cstate; + Assert(rel); if (stmt->sreh && Gp_role != GP_ROLE_EXECUTE && !rel->rd_cdbpolicy) @@ -1356,6 +1186,13 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, PG_RE_THROW(); } PG_END_TRY(); + + /* + * GPDB: this call was lost in the PG14 merge; without it the input + * file descriptor (and the copy context) leaked on every COPY FROM + * '', drawing "N temporary files and directories not closed + * at end-of-transaction" warnings at commit. + */ EndCopyFrom(cstate); } else @@ -1417,14 +1254,13 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, * Process the statement option list for COPY. * * Scan the options list (a list of DefElem) and transpose the information - * into cstate, applying appropriate error checking. + * into *opts_out, applying appropriate error checking. * - * cstate is assumed to be filled with zeroes initially. + * If 'opts_out' is not NULL, it is assumed to be filled with zeroes initially. * * This is exported so that external users of the COPY API can sanity-check - * a list of options. In that usage, cstate should be passed as NULL - * (since external users don't know sizeof(CopyStateData)) and the collected - * data is just leaked until CurrentMemoryContext is reset. + * a list of options. In that usage, 'opts_out' can be passed as NULL and + * the collected data is just leaked until CurrentMemoryContext is reset. * * Note that additional checking, such as whether column names listed in FORCE * QUOTE actually exist, has to be applied later. This just checks for @@ -1432,16 +1268,22 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, */ void ProcessCopyOptions(ParseState *pstate, - CopyState cstate, + CopyFormatOptions *opts_out, bool is_from, List *options) { + CopyState cstate = opts_out; bool format_specified = false; + bool freeze_specified = false; + bool header_specified = false; ListCell *option; /* Support external use for option sanity checking */ - if (cstate == NULL) - cstate = (CopyStateData *) palloc0(sizeof(CopyStateData)); + if (opts_out == NULL) + { + opts_out = (CopyFormatOptions *) palloc0(sizeof(CopyFormatOptions)); + cstate = opts_out; + } cstate->escape_off = false; cstate->skip_foreign_partitions = false; @@ -1469,9 +1311,9 @@ ProcessCopyOptions(ParseState *pstate, if (strcmp(fmt, "text") == 0) /* default format */ ; else if (strcmp(fmt, "csv") == 0) - cstate->csv_mode = true; + opts_out->csv_mode = true; else if (strcmp(fmt, "binary") == 0) - cstate->binary = true; + opts_out->binary = true; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1480,16 +1322,17 @@ ProcessCopyOptions(ParseState *pstate, } else if (strcmp(defel->defname, "freeze") == 0) { - if (cstate->freeze) + if (freeze_specified) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); - cstate->freeze = defGetBoolean(defel); + freeze_specified = true; + opts_out->freeze = defGetBoolean(defel); } else if (strcmp(defel->defname, "delimiter") == 0) { - if (cstate->delim) + if (opts_out->delim) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), @@ -1501,7 +1344,7 @@ ProcessCopyOptions(ParseState *pstate, } else if (strcmp(defel->defname, "null") == 0) { - if (cstate->null_print) + if (opts_out->null_print) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), @@ -1519,40 +1362,41 @@ ProcessCopyOptions(ParseState *pstate, } else if (strcmp(defel->defname, "header") == 0) { - if (cstate->header_line) + if (header_specified) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); - cstate->header_line = defGetBoolean(defel); + header_specified = true; + opts_out->header_line = defGetBoolean(defel); } else if (strcmp(defel->defname, "quote") == 0) { - if (cstate->quote) + if (opts_out->quote) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); - cstate->quote = defGetString(defel); + opts_out->quote = defGetString(defel); } else if (strcmp(defel->defname, "escape") == 0) { - if (cstate->escape) + if (opts_out->escape) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); - cstate->escape = defGetString(defel); + opts_out->escape = defGetString(defel); } else if (strcmp(defel->defname, "force_quote") == 0) { - if (cstate->force_quote || cstate->force_quote_all) + if (opts_out->force_quote || opts_out->force_quote_all) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); if (defel->arg && IsA(defel->arg, A_Star)) - cstate->force_quote_all = true; + opts_out->force_quote_all = true; else if (defel->arg && IsA(defel->arg, List)) cstate->force_quote = castNode(List, defel->arg); else if (defel->arg && IsA(defel->arg, String)) @@ -1574,7 +1418,7 @@ ProcessCopyOptions(ParseState *pstate, } else if (strcmp(defel->defname, "force_not_null") == 0) { - if (cstate->force_notnull) + if (opts_out->force_notnull) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), @@ -1595,12 +1439,12 @@ ProcessCopyOptions(ParseState *pstate, } else if (strcmp(defel->defname, "force_null") == 0) { - if (cstate->force_null) + if (opts_out->force_null) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); if (defel->arg && IsA(defel->arg, List)) - cstate->force_null = castNode(List, defel->arg); + opts_out->force_null = castNode(List, defel->arg); else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1615,14 +1459,14 @@ ProcessCopyOptions(ParseState *pstate, * named columns to binary form, storing the rest as NULLs. It's * allowed for the column list to be NIL. */ - if (cstate->convert_selectively) + if (opts_out->convert_selectively) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); - cstate->convert_selectively = true; + opts_out->convert_selectively = true; if (defel->arg == NULL || IsA(defel->arg, List)) - cstate->convert_select = castNode(List, defel->arg); + opts_out->convert_select = castNode(List, defel->arg); else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1632,13 +1476,13 @@ ProcessCopyOptions(ParseState *pstate, } else if (strcmp(defel->defname, "encoding") == 0) { - if (cstate->file_encoding >= 0) + if (opts_out->file_encoding >= 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"), parser_errposition(pstate, defel->location))); - cstate->file_encoding = pg_char_to_encoding(defGetString(defel)); - if (cstate->file_encoding < 0) + opts_out->file_encoding = pg_char_to_encoding(defGetString(defel)); + if (opts_out->file_encoding < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("argument to option \"%s\" must be a valid encoding name", @@ -1703,12 +1547,12 @@ ProcessCopyOptions(ParseState *pstate, * Check for incompatible options (must do these two before inserting * defaults) */ - if (cstate->binary && cstate->delim) + if (opts_out->binary && opts_out->delim) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("COPY cannot specify DELIMITER in BINARY mode"))); - if (cstate->binary && cstate->null_print) + if (opts_out->binary && opts_out->null_print) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("COPY cannot specify NULL in BINARY mode"))); @@ -1716,19 +1560,19 @@ ProcessCopyOptions(ParseState *pstate, cstate->eol_type = EOL_UNKNOWN; /* Set defaults for omitted options */ - if (!cstate->delim) - cstate->delim = cstate->csv_mode ? "," : "\t"; + if (!opts_out->delim) + opts_out->delim = opts_out->csv_mode ? "," : "\t"; - if (!cstate->null_print) - cstate->null_print = cstate->csv_mode ? "" : "\\N"; - cstate->null_print_len = strlen(cstate->null_print); + if (!opts_out->null_print) + opts_out->null_print = opts_out->csv_mode ? "" : "\\N"; + opts_out->null_print_len = strlen(opts_out->null_print); - if (cstate->csv_mode) + if (opts_out->csv_mode) { - if (!cstate->quote) - cstate->quote = "\""; - if (!cstate->escape) - cstate->escape = cstate->quote; + if (!opts_out->quote) + opts_out->quote = "\""; + if (!opts_out->escape) + opts_out->escape = opts_out->quote; } if (!cstate->csv_mode && !cstate->escape) @@ -1744,14 +1588,14 @@ ProcessCopyOptions(ParseState *pstate, #endif /* Disallow end-of-line characters */ - if (strchr(cstate->delim, '\r') != NULL || - strchr(cstate->delim, '\n') != NULL) + if (strchr(opts_out->delim, '\r') != NULL || + strchr(opts_out->delim, '\n') != NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY delimiter cannot be newline or carriage return"))); - if (strchr(cstate->null_print, '\r') != NULL || - strchr(cstate->null_print, '\n') != NULL) + if (strchr(opts_out->null_print, '\r') != NULL || + strchr(opts_out->null_print, '\n') != NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("COPY null representation cannot use newline or carriage return"))); @@ -1784,12 +1628,12 @@ ProcessCopyOptions(ParseState *pstate, errmsg("COPY cannot specify HEADER in BINARY mode"))); /* Check quote */ - if (!cstate->csv_mode && cstate->quote != NULL) + if (!opts_out->csv_mode && opts_out->quote != NULL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY quote available only in CSV mode"))); - if (cstate->csv_mode && strlen(cstate->quote) != 1) + if (opts_out->csv_mode && strlen(opts_out->quote) != 1) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY quote must be a single one-byte character"))); @@ -1821,32 +1665,32 @@ ProcessCopyOptions(ParseState *pstate, } /* Check force_quote */ - if (!cstate->csv_mode && (cstate->force_quote || cstate->force_quote_all)) + if (!opts_out->csv_mode && (opts_out->force_quote || opts_out->force_quote_all)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY force quote available only in CSV mode"))); - if ((cstate->force_quote || cstate->force_quote_all) && is_from) + if ((opts_out->force_quote || opts_out->force_quote_all) && is_from) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY force quote only available using COPY TO"))); /* Check force_notnull */ - if (!cstate->csv_mode && cstate->force_notnull != NIL) + if (!opts_out->csv_mode && opts_out->force_notnull != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY force not null available only in CSV mode"))); - if (cstate->force_notnull != NIL && !is_from) + if (opts_out->force_notnull != NIL && !is_from) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY force not null only available using COPY FROM"))); /* Check force_null */ - if (!cstate->csv_mode && cstate->force_null != NIL) + if (!opts_out->csv_mode && opts_out->force_null != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY force null available only in CSV mode"))); - if (cstate->force_null != NIL && !is_from) + if (opts_out->force_null != NIL && !is_from) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("COPY force null only available using COPY FROM"))); @@ -1858,8 +1702,8 @@ ProcessCopyOptions(ParseState *pstate, errmsg("COPY delimiter must not appear in the NULL specification"))); /* Don't allow the CSV quote char to appear in the null string. */ - if (cstate->csv_mode && - strchr(cstate->null_print, cstate->quote[0]) != NULL) + if (opts_out->csv_mode && + strchr(opts_out->null_print, opts_out->quote[0]) != NULL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("CSV quote character must not appear in the NULL specification"))); @@ -2405,7 +2249,7 @@ EndCopy(CopyState cstate) pfree(cstate); } -CopyIntoClause* +static CopyIntoClause* MakeCopyIntoClause(CopyStmt *stmt) { CopyIntoClause *copyIntoClause; @@ -2574,7 +2418,7 @@ BeginCopyToOnSegment(QueryDesc *queryDesc) /* * Setup CopyState to read tuples from a table or a query for COPY TO. */ -static CopyState +CopyState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query, @@ -2779,7 +2623,7 @@ BeginCopyToForeignTable(Relation forrel, List *options) * This intermediate routine exists mainly to localize the effects of setjmp * so we don't need to plaster a lot of variables with "volatile". */ -static uint64 +uint64 DoCopyTo(CopyState cstate) { bool pipe = (cstate->filename == NULL); @@ -2830,7 +2674,6 @@ DoCopyTo(CopyState cstate) if (Gp_role == GP_ROLE_EXECUTE && cstate->on_segment) cstate->copy_dest = COPY_NEW_FE; - pq_endcopyout(true); PG_RE_THROW(); } PG_END_TRY(); @@ -2859,7 +2702,7 @@ void EndCopyToOnSegment(CopyState cstate) /* * Clean up storage and release resources for COPY TO. */ -static void +void EndCopyTo(CopyState cstate, uint64 *processed) { if (cstate->queryDesc != NULL) @@ -3599,8 +3442,8 @@ CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, cstate->cur_lineno = buffer->linenos[i]; recheckIndexes = - ExecInsertIndexTuples(buffer->slots[i], estate, false, NULL, - NIL); + ExecInsertIndexTuples(resultRelInfo, buffer->slots[i], estate, + false, false, NULL, NIL); ExecARInsertTriggers(estate, resultRelInfo, slots[i], recheckIndexes, cstate->transition_capture); @@ -3922,8 +3765,6 @@ CopyFrom(CopyState cstate) ExecOpenIndices(resultRelInfo, false); - estate->es_result_relations = resultRelInfo; - estate->es_num_result_relations = 1; estate->es_result_relation_info = resultRelInfo; ExecInitRangeTable(estate, cstate->range_table); @@ -3936,7 +3777,18 @@ CopyFrom(CopyState cstate) mtstate->ps.plan = NULL; mtstate->ps.state = estate; mtstate->operation = CMD_INSERT; - mtstate->resultRelInfo = estate->es_result_relations; + mtstate->mt_nrels = 1; + /* + * GPDB: point resultRelInfo at our single target relation (treated as a + * one-element array), and set rootResultRelInfo too. ExecFindPartition() + * -> ExecInitPartitionInfo() dereferences mtstate->resultRelInfo[0] and + * mtstate->rootResultRelInfo for COPY into a partitioned table. This path + * uses InitResultRelInfo() directly rather than ExecInitResultRelation(), + * so estate->es_result_relations is never populated (NULL); using it here + * crashed partition routing. Mirrors the setup in copyfrom.c's CopyFrom(). + */ + mtstate->resultRelInfo = resultRelInfo; + mtstate->rootResultRelInfo = resultRelInfo; if (resultRelInfo->ri_FdwRoutine != NULL && resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL) @@ -3964,7 +3816,7 @@ CopyFrom(CopyState cstate) * CopyFrom tuple routing. */ if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - proute = ExecSetupPartitionTupleRouting(estate, NULL, cstate->rel); + proute = ExecSetupPartitionTupleRouting(estate, cstate->rel); if (cstate->whereClause) cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause), @@ -4394,23 +4246,11 @@ CopyFrom(CopyState cstate) { if (has_before_insert_row_trig) { - /* - * If there are any BEFORE triggers on the partition, - * we'll have to be ready to convert their result back to - * tuplestore format. - */ cstate->transition_capture->tcs_original_insert_tuple = NULL; - cstate->transition_capture->tcs_map = - resultRelInfo->ri_PartitionInfo->pi_PartitionToRootMap; } else { - /* - * Otherwise, just remember the original unconverted - * tuple, to avoid a needless round trip conversion. - */ cstate->transition_capture->tcs_original_insert_tuple = myslot; - cstate->transition_capture->tcs_map = NULL; } } @@ -4418,7 +4258,7 @@ CopyFrom(CopyState cstate) * We might need to convert from the root rowtype to the partition * rowtype. */ - map = resultRelInfo->ri_PartitionInfo->pi_RootToPartitionMap; + map = resultRelInfo->ri_RootToPartitionMap; if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert) { /* non batch insert */ @@ -4426,7 +4266,7 @@ CopyFrom(CopyState cstate) { TupleTableSlot *new_slot; - new_slot = resultRelInfo->ri_PartitionInfo->pi_PartitionTupleSlot; + new_slot = resultRelInfo->ri_PartitionTupleSlot; myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot); } } @@ -4518,7 +4358,7 @@ CopyFrom(CopyState cstate) /* Compute stored generated columns */ if (resultRelInfo->ri_RelationDesc->rd_att->constr && resultRelInfo->ri_RelationDesc->rd_att->constr->has_generated_stored) - ExecComputeStoredGenerated(estate, myslot, CMD_INSERT); + ExecComputeStoredGenerated(resultRelInfo, estate, myslot, CMD_INSERT); /* * If the target is a plain table, check the constraints of @@ -4534,7 +4374,7 @@ CopyFrom(CopyState cstate) * we don't need to if there's no BR trigger defined on the * partition. */ - if (resultRelInfo->ri_PartitionCheck && + if (resultRelInfo->ri_RelationDesc->rd_rel->relispartition && (proute == NULL || has_before_insert_row_trig)) ExecPartitionCheck(resultRelInfo, myslot, estate, true); @@ -4589,9 +4429,11 @@ CopyFrom(CopyState cstate) myslot, mycid, ti_options, bistate); if (resultRelInfo->ri_NumIndices > 0) - recheckIndexes = ExecInsertIndexTuples(myslot, + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, + myslot, estate, false, + false, NULL, NIL); } @@ -4729,11 +4571,16 @@ CopyFrom(CopyState cstate) if (proute) ExecCleanupTupleRouting(mtstate, proute); - /* Close any trigger target relations */ - ExecCleanUpTriggerState(estate); - FreeDistributionData(distData); + /* + * Close any relations opened by ExecGetTriggerResultRel() while firing + * the queued AFTER triggers above. (PG14 dropped the implicit close + * that ExecCleanUpTriggerState() used to do; copyfrom.c does the same.) + */ + ExecCloseResultRelations(estate); + ExecCloseRangeTableRelations(estate); + FreeExecutorState(estate); return processed; @@ -5255,7 +5102,7 @@ HandleCopyError(CopyState cstate) * 'values' and 'nulls' arrays must be the same length as columns of the * relation passed to BeginCopyFrom. This function fills the arrays. */ -bool +static bool NextCopyFromX(CopyState cstate, ExprContext *econtext, Datum *values, bool *nulls) { diff --git a/src/backend/commands/copyfrom.c b/src/backend/commands/copyfrom.c new file mode 100644 index 000000000000..d5abc8300b1a --- /dev/null +++ b/src/backend/commands/copyfrom.c @@ -0,0 +1,1596 @@ +/*------------------------------------------------------------------------- + * + * copyfrom.c + * COPY FROM file/program/client + * + * This file contains routines needed to efficiently load tuples into a + * table. That includes looking up the correct partition, firing triggers, + * calling the table AM function to insert the data, and updating indexes. + * Reading data from the input file or client and parsing it into Datums + * is handled in copyfromparse.c. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/commands/copyfrom.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include +#include +#include + +#include "access/heapam.h" +#include "access/htup_details.h" +#include "access/tableam.h" +#include "access/xact.h" +#include "access/xlog.h" +#include "catalog/namespace.h" +#include "commands/copy.h" +#include "commands/copyfrom_internal.h" +#include "commands/progress.h" +#include "commands/trigger.h" +#include "executor/execPartition.h" +#include "executor/executor.h" +#include "executor/nodeModifyTable.h" +#include "executor/tuptable.h" +#include "foreign/fdwapi.h" +#include "libpq/libpq.h" +#include "libpq/pqformat.h" +#include "miscadmin.h" +#include "optimizer/optimizer.h" +#include "pgstat.h" +#include "rewrite/rewriteHandler.h" +#include "storage/fd.h" +#include "tcop/tcopprot.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/portal.h" +#include "utils/rel.h" +#include "utils/snapmgr.h" + +/* + * No more than this many tuples per CopyMultiInsertBuffer + * + * Caution: Don't make this too big, as we could end up with this many + * CopyMultiInsertBuffer items stored in CopyMultiInsertInfo's + * multiInsertBuffers list. Increasing this can cause quadratic growth in + * memory requirements during copies into partitioned tables with a large + * number of partitions. + */ +#define MAX_BUFFERED_TUPLES 1000 + +/* + * Flush buffers if there are >= this many bytes, as counted by the input + * size, of tuples stored. + */ +#define MAX_BUFFERED_BYTES 65535 + +/* Trim the list of buffers back down to this number after flushing */ +#define MAX_PARTITION_BUFFERS 32 + +/* Stores multi-insert data related to a single relation in CopyFrom. */ +typedef struct CopyMultiInsertBuffer +{ + TupleTableSlot *slots[MAX_BUFFERED_TUPLES]; /* Array to store tuples */ + ResultRelInfo *resultRelInfo; /* ResultRelInfo for 'relid' */ + BulkInsertState bistate; /* BulkInsertState for this rel */ + int nused; /* number of 'slots' containing tuples */ + uint64 linenos[MAX_BUFFERED_TUPLES]; /* Line # of tuple in copy + * stream */ +} CopyMultiInsertBuffer; + +/* + * Stores one or many CopyMultiInsertBuffers and details about the size and + * number of tuples which are stored in them. This allows multiple buffers to + * exist at once when COPYing into a partitioned table. + */ +typedef struct CopyMultiInsertInfo +{ + List *multiInsertBuffers; /* List of tracked CopyMultiInsertBuffers */ + int bufferedTuples; /* number of tuples buffered over all buffers */ + int bufferedBytes; /* number of bytes from all buffered tuples */ + CopyFromState cstate; /* Copy state for this CopyMultiInsertInfo */ + EState *estate; /* Executor state used for COPY */ + CommandId mycid; /* Command Id used for COPY */ + int ti_options; /* table insert options */ +} CopyMultiInsertInfo; + + +/* non-export function prototypes */ +/* limit_printout_length declared extern in copy.h, defined in copy.c */ + +static void ClosePipeFromProgram(CopyFromState cstate); + +#if 0 /* GPDB: CopyFromErrorCallback is in copy.c using CopyState */ +/* + * error context callback for COPY FROM + * + * The argument for the error context must be CopyFromState. + */ +void +CopyFromErrorCallback(void *arg) +{ + CopyFromState cstate = (CopyFromState) arg; + char curlineno_str[32]; + + snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT, + cstate->cur_lineno); + + if (cstate->opts.binary) + { + /* can't usefully display the data */ + if (cstate->cur_attname) + errcontext("COPY %s, line %s, column %s", + cstate->cur_relname, curlineno_str, + cstate->cur_attname); + else + errcontext("COPY %s, line %s", + cstate->cur_relname, curlineno_str); + } + else + { + if (cstate->cur_attname && cstate->cur_attval) + { + /* error is relevant to a particular column */ + char *attval; + + attval = limit_printout_length(cstate->cur_attval); + errcontext("COPY %s, line %s, column %s: \"%s\"", + cstate->cur_relname, curlineno_str, + cstate->cur_attname, attval); + pfree(attval); + } + else if (cstate->cur_attname) + { + /* error is relevant to a particular column, value is NULL */ + errcontext("COPY %s, line %s, column %s: null input", + cstate->cur_relname, curlineno_str, + cstate->cur_attname); + } + else + { + /* + * Error is relevant to a particular line. + * + * If line_buf still contains the correct line, print it. + */ + if (cstate->line_buf_valid) + { + char *lineval; + + lineval = limit_printout_length(cstate->line_buf.data); + errcontext("COPY %s, line %s: \"%s\"", + cstate->cur_relname, curlineno_str, lineval); + pfree(lineval); + } + else + { + errcontext("COPY %s, line %s", + cstate->cur_relname, curlineno_str); + } + } + } +} +#endif /* GPDB: CopyFromErrorCallback */ + +/* + * Allocate memory and initialize a new CopyMultiInsertBuffer for this + * ResultRelInfo. + */ +static CopyMultiInsertBuffer * +CopyMultiInsertBufferInit(ResultRelInfo *rri) +{ + CopyMultiInsertBuffer *buffer; + + buffer = (CopyMultiInsertBuffer *) palloc(sizeof(CopyMultiInsertBuffer)); + memset(buffer->slots, 0, sizeof(TupleTableSlot *) * MAX_BUFFERED_TUPLES); + buffer->resultRelInfo = rri; + buffer->bistate = GetBulkInsertState(); + buffer->nused = 0; + + return buffer; +} + +/* + * Make a new buffer for this ResultRelInfo. + */ +static inline void +CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo, + ResultRelInfo *rri) +{ + CopyMultiInsertBuffer *buffer; + + buffer = CopyMultiInsertBufferInit(rri); + + /* Setup back-link so we can easily find this buffer again */ + rri->ri_CopyMultiInsertBuffer = buffer; + /* Record that we're tracking this buffer */ + miinfo->multiInsertBuffers = lappend(miinfo->multiInsertBuffers, buffer); +} + +/* + * Initialize an already allocated CopyMultiInsertInfo. + * + * If rri is a non-partitioned table then a CopyMultiInsertBuffer is set up + * for that table. + */ +static void +CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, + CopyFromState cstate, EState *estate, CommandId mycid, + int ti_options) +{ + miinfo->multiInsertBuffers = NIL; + miinfo->bufferedTuples = 0; + miinfo->bufferedBytes = 0; + miinfo->cstate = cstate; + miinfo->estate = estate; + miinfo->mycid = mycid; + miinfo->ti_options = ti_options; + + /* + * Only setup the buffer when not dealing with a partitioned table. + * Buffers for partitioned tables will just be setup when we need to send + * tuples their way for the first time. + */ + if (rri->ri_RelationDesc->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) + CopyMultiInsertInfoSetupBuffer(miinfo, rri); +} + +/* + * Returns true if the buffers are full + */ +static inline bool +CopyMultiInsertInfoIsFull(CopyMultiInsertInfo *miinfo) +{ + if (miinfo->bufferedTuples >= MAX_BUFFERED_TUPLES || + miinfo->bufferedBytes >= MAX_BUFFERED_BYTES) + return true; + return false; +} + +/* + * Returns true if we have no buffered tuples + */ +static inline bool +CopyMultiInsertInfoIsEmpty(CopyMultiInsertInfo *miinfo) +{ + return miinfo->bufferedTuples == 0; +} + +/* + * Write the tuples stored in 'buffer' out to the table. + */ +static inline void +CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, + CopyMultiInsertBuffer *buffer) +{ + MemoryContext oldcontext; + int i; + uint64 save_cur_lineno; + CopyFromState cstate = miinfo->cstate; + EState *estate = miinfo->estate; + CommandId mycid = miinfo->mycid; + int ti_options = miinfo->ti_options; + bool line_buf_valid = cstate->line_buf_valid; + int nused = buffer->nused; + ResultRelInfo *resultRelInfo = buffer->resultRelInfo; + TupleTableSlot **slots = buffer->slots; + + /* + * Print error context information correctly, if one of the operations + * below fail. + */ + cstate->line_buf_valid = false; + save_cur_lineno = cstate->cur_lineno; + + /* + * table_multi_insert may leak memory, so switch to short-lived memory + * context before calling it. + */ + oldcontext = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); + table_multi_insert(resultRelInfo->ri_RelationDesc, + slots, + nused, + mycid, + ti_options, + buffer->bistate); + MemoryContextSwitchTo(oldcontext); + + for (i = 0; i < nused; i++) + { + /* + * If there are any indexes, update them for all the inserted tuples, + * and run AFTER ROW INSERT triggers. + */ + if (resultRelInfo->ri_NumIndices > 0) + { + List *recheckIndexes; + + cstate->cur_lineno = buffer->linenos[i]; + recheckIndexes = + ExecInsertIndexTuples(resultRelInfo, + buffer->slots[i], estate, false, false, + NULL, NIL); + ExecARInsertTriggers(estate, resultRelInfo, + slots[i], recheckIndexes, + cstate->transition_capture); + list_free(recheckIndexes); + } + + /* + * There's no indexes, but see if we need to run AFTER ROW INSERT + * triggers anyway. + */ + else if (resultRelInfo->ri_TrigDesc != NULL && + (resultRelInfo->ri_TrigDesc->trig_insert_after_row || + resultRelInfo->ri_TrigDesc->trig_insert_new_table)) + { + cstate->cur_lineno = buffer->linenos[i]; + ExecARInsertTriggers(estate, resultRelInfo, + slots[i], NIL, cstate->transition_capture); + } + + ExecClearTuple(slots[i]); + } + + /* Mark that all slots are free */ + buffer->nused = 0; + + /* reset cur_lineno and line_buf_valid to what they were */ + cstate->line_buf_valid = line_buf_valid; + cstate->cur_lineno = save_cur_lineno; +} + +/* + * Drop used slots and free member for this buffer. + * + * The buffer must be flushed before cleanup. + */ +static inline void +CopyMultiInsertBufferCleanup(CopyMultiInsertInfo *miinfo, + CopyMultiInsertBuffer *buffer) +{ + int i; + + /* Ensure buffer was flushed */ + Assert(buffer->nused == 0); + + /* Remove back-link to ourself */ + buffer->resultRelInfo->ri_CopyMultiInsertBuffer = NULL; + + FreeBulkInsertState(buffer->bistate); + + /* Since we only create slots on demand, just drop the non-null ones. */ + for (i = 0; i < MAX_BUFFERED_TUPLES && buffer->slots[i] != NULL; i++) + ExecDropSingleTupleTableSlot(buffer->slots[i]); + + table_finish_bulk_insert(buffer->resultRelInfo->ri_RelationDesc, + miinfo->ti_options); + + pfree(buffer); +} + +/* + * Write out all stored tuples in all buffers out to the tables. + * + * Once flushed we also trim the tracked buffers list down to size by removing + * the buffers created earliest first. + * + * Callers should pass 'curr_rri' as the ResultRelInfo that's currently being + * used. When cleaning up old buffers we'll never remove the one for + * 'curr_rri'. + */ +static inline void +CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri) +{ + ListCell *lc; + + foreach(lc, miinfo->multiInsertBuffers) + { + CopyMultiInsertBuffer *buffer = (CopyMultiInsertBuffer *) lfirst(lc); + + CopyMultiInsertBufferFlush(miinfo, buffer); + } + + miinfo->bufferedTuples = 0; + miinfo->bufferedBytes = 0; + + /* + * Trim the list of tracked buffers down if it exceeds the limit. Here we + * remove buffers starting with the ones we created first. It seems less + * likely that these older ones will be needed than the ones that were + * just created. + */ + while (list_length(miinfo->multiInsertBuffers) > MAX_PARTITION_BUFFERS) + { + CopyMultiInsertBuffer *buffer; + + buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers); + + /* + * We never want to remove the buffer that's currently being used, so + * if we happen to find that then move it to the end of the list. + */ + if (buffer->resultRelInfo == curr_rri) + { + miinfo->multiInsertBuffers = list_delete_first(miinfo->multiInsertBuffers); + miinfo->multiInsertBuffers = lappend(miinfo->multiInsertBuffers, buffer); + buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers); + } + + CopyMultiInsertBufferCleanup(miinfo, buffer); + miinfo->multiInsertBuffers = list_delete_first(miinfo->multiInsertBuffers); + } +} + +/* + * Cleanup allocated buffers and free memory + */ +static inline void +CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo) +{ + ListCell *lc; + + foreach(lc, miinfo->multiInsertBuffers) + CopyMultiInsertBufferCleanup(miinfo, lfirst(lc)); + + list_free(miinfo->multiInsertBuffers); +} + +/* + * Get the next TupleTableSlot that the next tuple should be stored in. + * + * Callers must ensure that the buffer is not full. + * + * Note: 'miinfo' is unused but has been included for consistency with the + * other functions in this area. + */ +static inline TupleTableSlot * +CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, + ResultRelInfo *rri) +{ + CopyMultiInsertBuffer *buffer = rri->ri_CopyMultiInsertBuffer; + int nused = buffer->nused; + + Assert(buffer != NULL); + Assert(nused < MAX_BUFFERED_TUPLES); + + if (buffer->slots[nused] == NULL) + buffer->slots[nused] = table_slot_create(rri->ri_RelationDesc, NULL); + return buffer->slots[nused]; +} + +/* + * Record the previously reserved TupleTableSlot that was reserved by + * CopyMultiInsertInfoNextFreeSlot as being consumed. + */ +static inline void +CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, + TupleTableSlot *slot, int tuplen, uint64 lineno) +{ + CopyMultiInsertBuffer *buffer = rri->ri_CopyMultiInsertBuffer; + + Assert(buffer != NULL); + Assert(slot == buffer->slots[buffer->nused]); + + /* Store the line number so we can properly report any errors later */ + buffer->linenos[buffer->nused] = lineno; + + /* Record this slot as being used */ + buffer->nused++; + + /* Update how many tuples are stored and their size */ + miinfo->bufferedTuples++; + miinfo->bufferedBytes += tuplen; +} + +/* + * GPDB: CopyFrom, BeginCopyFrom, EndCopyFrom are in copy.c with + * GPDB-specific dispatch logic. Skip PG14 versions here. + */ +#if 0 +/* + * Copy FROM file to relation. + */ +uint64 +CopyFrom(CopyFromState cstate) +{ + ResultRelInfo *resultRelInfo; + ResultRelInfo *target_resultRelInfo; + ResultRelInfo *prevResultRelInfo = NULL; + EState *estate = CreateExecutorState(); /* for ExecConstraints() */ + ModifyTableState *mtstate; + ExprContext *econtext; + TupleTableSlot *singleslot = NULL; + MemoryContext oldcontext = CurrentMemoryContext; + + PartitionTupleRouting *proute = NULL; + ErrorContextCallback errcallback; + CommandId mycid = GetCurrentCommandId(true); + int ti_options = 0; /* start with default options for insert */ + BulkInsertState bistate = NULL; + CopyInsertMethod insertMethod; + CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */ + int64 processed = 0; + int64 excluded = 0; + bool has_before_insert_row_trig; + bool has_instead_insert_row_trig; + bool leafpart_use_multi_insert = false; + + Assert(cstate->rel); + Assert(list_length(cstate->range_table) == 1); + + /* + * The target must be a plain, foreign, or partitioned relation, or have + * an INSTEAD OF INSERT row trigger. (Currently, such triggers are only + * allowed on views, so we only hint about them in the view case.) + */ + if (cstate->rel->rd_rel->relkind != RELKIND_RELATION && + cstate->rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE && + cstate->rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE && + !(cstate->rel->trigdesc && + cstate->rel->trigdesc->trig_insert_instead_row)) + { + if (cstate->rel->rd_rel->relkind == RELKIND_VIEW) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy to view \"%s\"", + RelationGetRelationName(cstate->rel)), + errhint("To enable copying to a view, provide an INSTEAD OF INSERT trigger."))); + else if (cstate->rel->rd_rel->relkind == RELKIND_MATVIEW) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy to materialized view \"%s\"", + RelationGetRelationName(cstate->rel)))); + else if (cstate->rel->rd_rel->relkind == RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy to sequence \"%s\"", + RelationGetRelationName(cstate->rel)))); + else + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy to non-table relation \"%s\"", + RelationGetRelationName(cstate->rel)))); + } + + /* + * If the target file is new-in-transaction, we assume that checking FSM + * for free space is a waste of time. This could possibly be wrong, but + * it's unlikely. + */ + if (RELKIND_HAS_STORAGE(cstate->rel->rd_rel->relkind) && + (cstate->rel->rd_createSubid != InvalidSubTransactionId || + cstate->rel->rd_firstRelfilenodeSubid != InvalidSubTransactionId)) + ti_options |= TABLE_INSERT_SKIP_FSM; + + /* + * Optimize if new relfilenode was created in this subxact or one of its + * committed children and we won't see those rows later as part of an + * earlier scan or command. The subxact test ensures that if this subxact + * aborts then the frozen rows won't be visible after xact cleanup. Note + * that the stronger test of exactly which subtransaction created it is + * crucial for correctness of this optimization. The test for an earlier + * scan or command tolerates false negatives. FREEZE causes other sessions + * to see rows they would not see under MVCC, and a false negative merely + * spreads that anomaly to the current session. + */ + if (cstate->opts.freeze) + { + /* + * We currently disallow COPY FREEZE on partitioned tables. The + * reason for this is that we've simply not yet opened the partitions + * to determine if the optimization can be applied to them. We could + * go and open them all here, but doing so may be quite a costly + * overhead for small copies. In any case, we may just end up routing + * tuples to a small number of partitions. It seems better just to + * raise an ERROR for partitioned tables. + */ + if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot perform COPY FREEZE on a partitioned table"))); + } + + /* + * Tolerate one registration for the benefit of FirstXactSnapshot. + * Scan-bearing queries generally create at least two registrations, + * though relying on that is fragile, as is ignoring ActiveSnapshot. + * Clear CatalogSnapshot to avoid counting its registration. We'll + * still detect ongoing catalog scans, each of which separately + * registers the snapshot it uses. + */ + InvalidateCatalogSnapshot(); + if (!ThereAreNoPriorRegisteredSnapshots() || !ThereAreNoReadyPortals()) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TRANSACTION_STATE), + errmsg("cannot perform COPY FREEZE because of prior transaction activity"))); + + if (cstate->rel->rd_createSubid != GetCurrentSubTransactionId() && + cstate->rel->rd_newRelfilenodeSubid != GetCurrentSubTransactionId()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction"))); + + ti_options |= TABLE_INSERT_FROZEN; + } + + /* + * We need a ResultRelInfo so we can use the regular executor's + * index-entry-making machinery. (There used to be a huge amount of code + * here that basically duplicated execUtils.c ...) + */ + ExecInitRangeTable(estate, cstate->range_table); + resultRelInfo = target_resultRelInfo = makeNode(ResultRelInfo); + ExecInitResultRelation(estate, resultRelInfo, 1); + + /* Verify the named relation is a valid target for INSERT */ + CheckValidResultRel(resultRelInfo, CMD_INSERT); + + ExecOpenIndices(resultRelInfo, false); + + /* + * Set up a ModifyTableState so we can let FDW(s) init themselves for + * foreign-table result relation(s). + */ + mtstate = makeNode(ModifyTableState); + mtstate->ps.plan = NULL; + mtstate->ps.state = estate; + mtstate->operation = CMD_INSERT; + mtstate->mt_nrels = 1; + mtstate->resultRelInfo = resultRelInfo; + mtstate->rootResultRelInfo = resultRelInfo; + + if (resultRelInfo->ri_FdwRoutine != NULL && + resultRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL) + resultRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate, + resultRelInfo); + + /* Prepare to catch AFTER triggers. */ + AfterTriggerBeginQuery(); + + /* + * If there are any triggers with transition tables on the named relation, + * we need to be prepared to capture transition tuples. + * + * Because partition tuple routing would like to know about whether + * transition capture is active, we also set it in mtstate, which is + * passed to ExecFindPartition() below. + */ + cstate->transition_capture = mtstate->mt_transition_capture = + MakeTransitionCaptureState(cstate->rel->trigdesc, + RelationGetRelid(cstate->rel), + CMD_INSERT); + + /* + * If the named relation is a partitioned table, initialize state for + * CopyFrom tuple routing. + */ + if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + proute = ExecSetupPartitionTupleRouting(estate, cstate->rel); + + if (cstate->whereClause) + cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause), + &mtstate->ps); + + /* + * It's generally more efficient to prepare a bunch of tuples for + * insertion, and insert them in one table_multi_insert() call, than call + * table_tuple_insert() separately for every tuple. However, there are a + * number of reasons why we might not be able to do this. These are + * explained below. + */ + if (resultRelInfo->ri_TrigDesc != NULL && + (resultRelInfo->ri_TrigDesc->trig_insert_before_row || + resultRelInfo->ri_TrigDesc->trig_insert_instead_row)) + { + /* + * Can't support multi-inserts when there are any BEFORE/INSTEAD OF + * triggers on the table. Such triggers might query the table we're + * inserting into and act differently if the tuples that have already + * been processed and prepared for insertion are not there. + */ + insertMethod = CIM_SINGLE; + } + else if (proute != NULL && resultRelInfo->ri_TrigDesc != NULL && + resultRelInfo->ri_TrigDesc->trig_insert_new_table) + { + /* + * For partitioned tables we can't support multi-inserts when there + * are any statement level insert triggers. It might be possible to + * allow partitioned tables with such triggers in the future, but for + * now, CopyMultiInsertInfoFlush expects that any before row insert + * and statement level insert triggers are on the same relation. + */ + insertMethod = CIM_SINGLE; + } + else if (resultRelInfo->ri_FdwRoutine != NULL || + cstate->volatile_defexprs) + { + /* + * Can't support multi-inserts to foreign tables or if there are any + * volatile default expressions in the table. Similarly to the + * trigger case above, such expressions may query the table we're + * inserting into. + * + * Note: It does not matter if any partitions have any volatile + * default expressions as we use the defaults from the target of the + * COPY command. + */ + insertMethod = CIM_SINGLE; + } + else if (contain_volatile_functions(cstate->whereClause)) + { + /* + * Can't support multi-inserts if there are any volatile function + * expressions in WHERE clause. Similarly to the trigger case above, + * such expressions may query the table we're inserting into. + */ + insertMethod = CIM_SINGLE; + } + else + { + /* + * For partitioned tables, we may still be able to perform bulk + * inserts. However, the possibility of this depends on which types + * of triggers exist on the partition. We must disable bulk inserts + * if the partition is a foreign table or it has any before row insert + * or insert instead triggers (same as we checked above for the parent + * table). Since the partition's resultRelInfos are initialized only + * when we actually need to insert the first tuple into them, we must + * have the intermediate insert method of CIM_MULTI_CONDITIONAL to + * flag that we must later determine if we can use bulk-inserts for + * the partition being inserted into. + */ + if (proute) + insertMethod = CIM_MULTI_CONDITIONAL; + else + insertMethod = CIM_MULTI; + + CopyMultiInsertInfoInit(&multiInsertInfo, resultRelInfo, cstate, + estate, mycid, ti_options); + } + + /* + * If not using batch mode (which allocates slots as needed) set up a + * tuple slot too. When inserting into a partitioned table, we also need + * one, even if we might batch insert, to read the tuple in the root + * partition's form. + */ + if (insertMethod == CIM_SINGLE || insertMethod == CIM_MULTI_CONDITIONAL) + { + singleslot = table_slot_create(resultRelInfo->ri_RelationDesc, + &estate->es_tupleTable); + bistate = GetBulkInsertState(); + } + + has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_before_row); + + has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_instead_row); + + /* + * Check BEFORE STATEMENT insertion triggers. It's debatable whether we + * should do this for COPY, since it's not really an "INSERT" statement as + * such. However, executing these triggers maintains consistency with the + * EACH ROW triggers that we already fire on COPY. + */ + ExecBSInsertTriggers(estate, resultRelInfo); + + econtext = GetPerTupleExprContext(estate); + + /* Set up callback to identify error line number */ + errcallback.callback = CopyFromErrorCallback; + errcallback.arg = (void *) cstate; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + + for (;;) + { + TupleTableSlot *myslot; + bool skip_tuple; + + CHECK_FOR_INTERRUPTS(); + + /* + * Reset the per-tuple exprcontext. We do this after every tuple, to + * clean-up after expression evaluations etc. + */ + ResetPerTupleExprContext(estate); + + /* select slot to (initially) load row into */ + if (insertMethod == CIM_SINGLE || proute) + { + myslot = singleslot; + Assert(myslot != NULL); + } + else + { + Assert(resultRelInfo == target_resultRelInfo); + Assert(insertMethod == CIM_MULTI); + + myslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo, + resultRelInfo); + } + + /* + * Switch to per-tuple context before calling NextCopyFrom, which does + * evaluate default expressions etc. and requires per-tuple context. + */ + MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); + + ExecClearTuple(myslot); + + /* Directly store the values/nulls array in the slot */ + if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull)) + break; + + ExecStoreVirtualTuple(myslot); + + /* + * Constraints and where clause might reference the tableoid column, + * so (re-)initialize tts_tableOid before evaluating them. + */ + myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc); + + /* Triggers and stuff need to be invoked in query context. */ + MemoryContextSwitchTo(oldcontext); + + if (cstate->whereClause) + { + econtext->ecxt_scantuple = myslot; + /* Skip items that don't match COPY's WHERE clause */ + if (!ExecQual(cstate->qualexpr, econtext)) + { + /* + * Report that this tuple was filtered out by the WHERE + * clause. + */ + pgstat_progress_update_param(PROGRESS_COPY_TUPLES_EXCLUDED, + ++excluded); + continue; + } + } + + /* Determine the partition to insert the tuple into */ + if (proute) + { + TupleConversionMap *map; + + /* + * Attempt to find a partition suitable for this tuple. + * ExecFindPartition() will raise an error if none can be found or + * if the found partition is not suitable for INSERTs. + */ + resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo, + proute, myslot, estate); + + if (prevResultRelInfo != resultRelInfo) + { + /* Determine which triggers exist on this partition */ + has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_before_row); + + has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_instead_row); + + /* + * Disable multi-inserts when the partition has BEFORE/INSTEAD + * OF triggers, or if the partition is a foreign partition. + */ + leafpart_use_multi_insert = insertMethod == CIM_MULTI_CONDITIONAL && + !has_before_insert_row_trig && + !has_instead_insert_row_trig && + resultRelInfo->ri_FdwRoutine == NULL; + + /* Set the multi-insert buffer to use for this partition. */ + if (leafpart_use_multi_insert) + { + if (resultRelInfo->ri_CopyMultiInsertBuffer == NULL) + CopyMultiInsertInfoSetupBuffer(&multiInsertInfo, + resultRelInfo); + } + else if (insertMethod == CIM_MULTI_CONDITIONAL && + !CopyMultiInsertInfoIsEmpty(&multiInsertInfo)) + { + /* + * Flush pending inserts if this partition can't use + * batching, so rows are visible to triggers etc. + */ + CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo); + } + + if (bistate != NULL) + ReleaseBulkInsertStatePin(bistate); + prevResultRelInfo = resultRelInfo; + } + + /* + * If we're capturing transition tuples, we might need to convert + * from the partition rowtype to root rowtype. But if there are no + * BEFORE triggers on the partition that could change the tuple, + * we can just remember the original unconverted tuple to avoid a + * needless round trip conversion. + */ + if (cstate->transition_capture != NULL) + cstate->transition_capture->tcs_original_insert_tuple = + !has_before_insert_row_trig ? myslot : NULL; + + /* + * We might need to convert from the root rowtype to the partition + * rowtype. + */ + map = resultRelInfo->ri_RootToPartitionMap; + if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert) + { + /* non batch insert */ + if (map != NULL) + { + TupleTableSlot *new_slot; + + new_slot = resultRelInfo->ri_PartitionTupleSlot; + myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot); + } + } + else + { + /* + * Prepare to queue up tuple for later batch insert into + * current partition. + */ + TupleTableSlot *batchslot; + + /* no other path available for partitioned table */ + Assert(insertMethod == CIM_MULTI_CONDITIONAL); + + batchslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo, + resultRelInfo); + + if (map != NULL) + myslot = execute_attr_map_slot(map->attrMap, myslot, + batchslot); + else + { + /* + * This looks more expensive than it is (Believe me, I + * optimized it away. Twice.). The input is in virtual + * form, and we'll materialize the slot below - for most + * slot types the copy performs the work materialization + * would later require anyway. + */ + ExecCopySlot(batchslot, myslot); + myslot = batchslot; + } + } + + /* ensure that triggers etc see the right relation */ + myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + } + + skip_tuple = false; + + /* BEFORE ROW INSERT Triggers */ + if (has_before_insert_row_trig) + { + if (!ExecBRInsertTriggers(estate, resultRelInfo, myslot)) + skip_tuple = true; /* "do nothing" */ + } + + if (!skip_tuple) + { + /* + * If there is an INSTEAD OF INSERT ROW trigger, let it handle the + * tuple. Otherwise, proceed with inserting the tuple into the + * table or foreign table. + */ + if (has_instead_insert_row_trig) + { + ExecIRInsertTriggers(estate, resultRelInfo, myslot); + } + else + { + /* Compute stored generated columns */ + if (resultRelInfo->ri_RelationDesc->rd_att->constr && + resultRelInfo->ri_RelationDesc->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(resultRelInfo, estate, myslot, + CMD_INSERT); + + /* + * If the target is a plain table, check the constraints of + * the tuple. + */ + if (resultRelInfo->ri_FdwRoutine == NULL && + resultRelInfo->ri_RelationDesc->rd_att->constr) + ExecConstraints(resultRelInfo, myslot, estate); + + /* + * Also check the tuple against the partition constraint, if + * there is one; except that if we got here via tuple-routing, + * we don't need to if there's no BR trigger defined on the + * partition. + */ + if (resultRelInfo->ri_RelationDesc->rd_rel->relispartition && + (proute == NULL || has_before_insert_row_trig)) + ExecPartitionCheck(resultRelInfo, myslot, estate, true); + + /* Store the slot in the multi-insert buffer, when enabled. */ + if (insertMethod == CIM_MULTI || leafpart_use_multi_insert) + { + /* + * The slot previously might point into the per-tuple + * context. For batching it needs to be longer lived. + */ + ExecMaterializeSlot(myslot); + + /* Add this tuple to the tuple buffer */ + CopyMultiInsertInfoStore(&multiInsertInfo, + resultRelInfo, myslot, + cstate->line_buf.len, + cstate->cur_lineno); + + /* + * If enough inserts have queued up, then flush all + * buffers out to their tables. + */ + if (CopyMultiInsertInfoIsFull(&multiInsertInfo)) + CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo); + } + else + { + List *recheckIndexes = NIL; + + /* OK, store the tuple */ + if (resultRelInfo->ri_FdwRoutine != NULL) + { + myslot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate, + resultRelInfo, + myslot, + NULL); + + if (myslot == NULL) /* "do nothing" */ + continue; /* next tuple please */ + + /* + * AFTER ROW Triggers might reference the tableoid + * column, so (re-)initialize tts_tableOid before + * evaluating them. + */ + myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + } + else + { + /* OK, store the tuple and create index entries for it */ + table_tuple_insert(resultRelInfo->ri_RelationDesc, + myslot, mycid, ti_options, bistate); + + if (resultRelInfo->ri_NumIndices > 0) + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, + myslot, + estate, + false, + false, + NULL, + NIL); + } + + /* AFTER ROW INSERT Triggers */ + ExecARInsertTriggers(estate, resultRelInfo, myslot, + recheckIndexes, cstate->transition_capture); + + list_free(recheckIndexes); + } + } + + /* + * We count only tuples not suppressed by a BEFORE INSERT trigger + * or FDW; this is the same definition used by nodeModifyTable.c + * for counting tuples inserted by an INSERT command. Update + * progress of the COPY command as well. + */ + pgstat_progress_update_param(PROGRESS_COPY_TUPLES_PROCESSED, + ++processed); + } + } + + /* Flush any remaining buffered tuples */ + if (insertMethod != CIM_SINGLE) + { + if (!CopyMultiInsertInfoIsEmpty(&multiInsertInfo)) + CopyMultiInsertInfoFlush(&multiInsertInfo, NULL); + } + + /* Done, clean up */ + error_context_stack = errcallback.previous; + + if (bistate != NULL) + FreeBulkInsertState(bistate); + + MemoryContextSwitchTo(oldcontext); + + /* Execute AFTER STATEMENT insertion triggers */ + ExecASInsertTriggers(estate, target_resultRelInfo, cstate->transition_capture); + + /* Handle queued AFTER triggers */ + AfterTriggerEndQuery(estate); + + ExecResetTupleTable(estate->es_tupleTable, false); + + /* Allow the FDW to shut down */ + if (target_resultRelInfo->ri_FdwRoutine != NULL && + target_resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL) + target_resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate, + target_resultRelInfo); + + /* Tear down the multi-insert buffer data */ + if (insertMethod != CIM_SINGLE) + CopyMultiInsertInfoCleanup(&multiInsertInfo); + + /* Close all the partitioned tables, leaf partitions, and their indices */ + if (proute) + ExecCleanupTupleRouting(mtstate, proute); + + /* Close the result relations, including any trigger target relations */ + ExecCloseResultRelations(estate); + ExecCloseRangeTableRelations(estate); + + FreeExecutorState(estate); + + return processed; +} + +/* + * Setup to read tuples from a file for COPY FROM. + * + * 'rel': Used as a template for the tuples + * 'whereClause': WHERE clause from the COPY FROM command + * 'filename': Name of server-local file to read, NULL for STDIN + * 'is_program': true if 'filename' is program to execute + * 'data_source_cb': callback that provides the input data + * 'attnamelist': List of char *, columns to include. NIL selects all cols. + * 'options': List of DefElem. See copy_opt_item in gram.y for selections. + * + * Returns a CopyFromState, to be passed to NextCopyFrom and related functions. + */ +CopyFromState +BeginCopyFrom(ParseState *pstate, + Relation rel, + Node *whereClause, + const char *filename, + bool is_program, + copy_data_source_cb data_source_cb, + List *attnamelist, + List *options) +{ + CopyFromState cstate; + bool pipe = (filename == NULL); + TupleDesc tupDesc; + AttrNumber num_phys_attrs, + num_defaults; + FmgrInfo *in_functions; + Oid *typioparams; + int attnum; + Oid in_func_oid; + int *defmap; + ExprState **defexprs; + MemoryContext oldcontext; + bool volatile_defexprs; + const int progress_cols[] = { + PROGRESS_COPY_COMMAND, + PROGRESS_COPY_TYPE, + PROGRESS_COPY_BYTES_TOTAL + }; + int64 progress_vals[] = { + PROGRESS_COPY_COMMAND_FROM, + 0, + 0 + }; + + /* Allocate workspace and zero all fields */ + cstate = (CopyFromStateData *) palloc0(sizeof(CopyFromStateData)); + + /* + * We allocate everything used by a cstate in a new memory context. This + * avoids memory leaks during repeated use of COPY in a query. + */ + cstate->copycontext = AllocSetContextCreate(CurrentMemoryContext, + "COPY", + ALLOCSET_DEFAULT_SIZES); + + oldcontext = MemoryContextSwitchTo(cstate->copycontext); + + /* Extract options from the statement node tree */ + ProcessCopyOptions(pstate, &cstate->opts, true /* is_from */ , options); + + /* Process the target relation */ + cstate->rel = rel; + + tupDesc = RelationGetDescr(cstate->rel); + + /* process commmon options or initialization */ + + /* Generate or convert list of attributes to process */ + cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist); + + num_phys_attrs = tupDesc->natts; + + /* Convert FORCE_NOT_NULL name list to per-column flags, check validity */ + cstate->opts.force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool)); + if (cstate->opts.force_notnull) + { + List *attnums; + ListCell *cur; + + attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_notnull); + + foreach(cur, attnums) + { + int attnum = lfirst_int(cur); + Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1); + + if (!list_member_int(cstate->attnumlist, attnum)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg("FORCE_NOT_NULL column \"%s\" not referenced by COPY", + NameStr(attr->attname)))); + cstate->opts.force_notnull_flags[attnum - 1] = true; + } + } + + /* Convert FORCE_NULL name list to per-column flags, check validity */ + cstate->opts.force_null_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool)); + if (cstate->opts.force_null) + { + List *attnums; + ListCell *cur; + + attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_null); + + foreach(cur, attnums) + { + int attnum = lfirst_int(cur); + Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1); + + if (!list_member_int(cstate->attnumlist, attnum)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg("FORCE_NULL column \"%s\" not referenced by COPY", + NameStr(attr->attname)))); + cstate->opts.force_null_flags[attnum - 1] = true; + } + } + + /* Convert convert_selectively name list to per-column flags */ + if (cstate->opts.convert_selectively) + { + List *attnums; + ListCell *cur; + + cstate->convert_select_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool)); + + attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.convert_select); + + foreach(cur, attnums) + { + int attnum = lfirst_int(cur); + Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1); + + if (!list_member_int(cstate->attnumlist, attnum)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg_internal("selected column \"%s\" not referenced by COPY", + NameStr(attr->attname)))); + cstate->convert_select_flags[attnum - 1] = true; + } + } + + /* Use client encoding when ENCODING option is not specified. */ + if (cstate->opts.file_encoding < 0) + cstate->file_encoding = pg_get_client_encoding(); + else + cstate->file_encoding = cstate->opts.file_encoding; + + /* + * Look up encoding conversion function. + */ + if (cstate->file_encoding == GetDatabaseEncoding() || + cstate->file_encoding == PG_SQL_ASCII || + GetDatabaseEncoding() == PG_SQL_ASCII) + { + cstate->need_transcoding = false; + } + else + { + cstate->need_transcoding = true; + cstate->conversion_proc = FindDefaultConversionProc(cstate->file_encoding, + GetDatabaseEncoding()); + } + + cstate->copy_src = COPY_FILE; /* default */ + + cstate->whereClause = whereClause; + + MemoryContextSwitchTo(oldcontext); + + oldcontext = MemoryContextSwitchTo(cstate->copycontext); + + /* Initialize state variables */ + cstate->eol_type = EOL_UNKNOWN; + cstate->cur_relname = RelationGetRelationName(cstate->rel); + cstate->cur_lineno = 0; + cstate->cur_attname = NULL; + cstate->cur_attval = NULL; + + /* + * Allocate buffers for the input pipeline. + * + * attribute_buf and raw_buf are used in both text and binary modes, but + * input_buf and line_buf only in text mode. + */ + cstate->raw_buf = palloc(RAW_BUF_SIZE + 1); + cstate->raw_buf_index = cstate->raw_buf_len = 0; + cstate->raw_reached_eof = false; + + if (!cstate->opts.binary) + { + /* + * If encoding conversion is needed, we need another buffer to hold + * the converted input data. Otherwise, we can just point input_buf + * to the same buffer as raw_buf. + */ + if (cstate->need_transcoding) + { + cstate->input_buf = (char *) palloc(INPUT_BUF_SIZE + 1); + cstate->input_buf_index = cstate->input_buf_len = 0; + } + else + cstate->input_buf = cstate->raw_buf; + cstate->input_reached_eof = false; + + initStringInfo(&cstate->line_buf); + } + + initStringInfo(&cstate->attribute_buf); + + /* Assign range table, we'll need it in CopyFrom. */ + if (pstate) + cstate->range_table = pstate->p_rtable; + + tupDesc = RelationGetDescr(cstate->rel); + num_phys_attrs = tupDesc->natts; + num_defaults = 0; + volatile_defexprs = false; + + /* + * Pick up the required catalog information for each attribute in the + * relation, including the input function, the element type (to pass to + * the input function), and info about defaults and constraints. (Which + * input function we use depends on text/binary format choice.) + */ + in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo)); + typioparams = (Oid *) palloc(num_phys_attrs * sizeof(Oid)); + defmap = (int *) palloc(num_phys_attrs * sizeof(int)); + defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *)); + + for (attnum = 1; attnum <= num_phys_attrs; attnum++) + { + Form_pg_attribute att = TupleDescAttr(tupDesc, attnum - 1); + + /* We don't need info for dropped attributes */ + if (att->attisdropped) + continue; + + /* Fetch the input function and typioparam info */ + if (cstate->opts.binary) + getTypeBinaryInputInfo(att->atttypid, + &in_func_oid, &typioparams[attnum - 1]); + else + getTypeInputInfo(att->atttypid, + &in_func_oid, &typioparams[attnum - 1]); + fmgr_info(in_func_oid, &in_functions[attnum - 1]); + + /* Get default info if needed */ + if (!list_member_int(cstate->attnumlist, attnum) && !att->attgenerated) + { + /* attribute is NOT to be copied from input */ + /* use default value if one exists */ + Expr *defexpr = (Expr *) build_column_default(cstate->rel, + attnum); + + if (defexpr != NULL) + { + /* Run the expression through planner */ + defexpr = expression_planner(defexpr); + + /* Initialize executable expression in copycontext */ + defexprs[num_defaults] = ExecInitExpr(defexpr, NULL); + defmap[num_defaults] = attnum - 1; + num_defaults++; + + /* + * If a default expression looks at the table being loaded, + * then it could give the wrong answer when using + * multi-insert. Since database access can be dynamic this is + * hard to test for exactly, so we use the much wider test of + * whether the default expression is volatile. We allow for + * the special case of when the default expression is the + * nextval() of a sequence which in this specific case is + * known to be safe for use with the multi-insert + * optimization. Hence we use this special case function + * checker rather than the standard check for + * contain_volatile_functions(). + */ + if (!volatile_defexprs) + volatile_defexprs = contain_volatile_functions_not_nextval((Node *) defexpr); + } + } + } + + + /* initialize progress */ + pgstat_progress_start_command(PROGRESS_COMMAND_COPY, + cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid); + cstate->bytes_processed = 0; + + /* We keep those variables in cstate. */ + cstate->in_functions = in_functions; + cstate->typioparams = typioparams; + cstate->defmap = defmap; + cstate->defexprs = defexprs; + cstate->volatile_defexprs = volatile_defexprs; + cstate->num_defaults = num_defaults; + cstate->is_program = is_program; + + if (data_source_cb) + { + progress_vals[1] = PROGRESS_COPY_TYPE_CALLBACK; + cstate->copy_src = COPY_CALLBACK; + cstate->data_source_cb = data_source_cb; + } + else if (pipe) + { + progress_vals[1] = PROGRESS_COPY_TYPE_PIPE; + Assert(!is_program); /* the grammar does not allow this */ + if (whereToSendOutput == DestRemote) + ReceiveCopyBegin(cstate); + else + cstate->copy_file = stdin; + } + else + { + cstate->filename = pstrdup(filename); + + if (cstate->is_program) + { + progress_vals[1] = PROGRESS_COPY_TYPE_PROGRAM; + cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_R); + if (cstate->copy_file == NULL) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not execute command \"%s\": %m", + cstate->filename))); + } + else + { + struct stat st; + + progress_vals[1] = PROGRESS_COPY_TYPE_FILE; + cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_R); + if (cstate->copy_file == NULL) + { + /* copy errno because ereport subfunctions might change it */ + int save_errno = errno; + + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\" for reading: %m", + cstate->filename), + (save_errno == ENOENT || save_errno == EACCES) ? + errhint("COPY FROM instructs the PostgreSQL server process to read a file. " + "You may want a client-side facility such as psql's \\copy.") : 0)); + } + + if (fstat(fileno(cstate->copy_file), &st)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", + cstate->filename))); + + if (S_ISDIR(st.st_mode)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a directory", cstate->filename))); + + progress_vals[2] = st.st_size; + } + } + + pgstat_progress_update_multi_param(3, progress_cols, progress_vals); + + if (cstate->opts.binary) + { + /* Read and verify binary header */ + ReceiveCopyBinaryHeader(cstate); + } + + /* create workspace for CopyReadAttributes results */ + if (!cstate->opts.binary) + { + AttrNumber attr_count = list_length(cstate->attnumlist); + + cstate->max_fields = attr_count; + cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *)); + } + + MemoryContextSwitchTo(oldcontext); + + return cstate; +} + +/* + * Clean up storage and release resources for COPY FROM. + */ +void +EndCopyFrom(CopyFromState cstate) +{ + /* No COPY FROM related resources except memory. */ + if (cstate->is_program) + { + ClosePipeFromProgram(cstate); + } + else + { + if (cstate->filename != NULL && FreeFile(cstate->copy_file)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + cstate->filename))); + } + + pgstat_progress_end_command(); + + MemoryContextDelete(cstate->copycontext); + pfree(cstate); +} + +/* + * Closes the pipe from an external program, checking the pclose() return code. + */ +static void +ClosePipeFromProgram(CopyFromState cstate) +{ + int pclose_rc; + + Assert(cstate->is_program); + + pclose_rc = ClosePipeStream(cstate->copy_file); + if (pclose_rc == -1) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close pipe to external command: %m"))); + else if (pclose_rc != 0) + { + /* + * If we ended a COPY FROM PROGRAM before reaching EOF, then it's + * expectable for the called program to fail with SIGPIPE, and we + * should not report that as an error. Otherwise, SIGPIPE indicates a + * problem. + */ + if (!cstate->raw_reached_eof && + wait_result_is_signal(pclose_rc, SIGPIPE)) + return; + + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), + errmsg("program \"%s\" failed", + cstate->filename), + errdetail_internal("%s", wait_result_to_str(pclose_rc)))); + } +} +#endif diff --git a/src/backend/commands/copyfromparse.c b/src/backend/commands/copyfromparse.c new file mode 100644 index 000000000000..d4496f6473db --- /dev/null +++ b/src/backend/commands/copyfromparse.c @@ -0,0 +1,1882 @@ +/*------------------------------------------------------------------------- + * + * copyfromparse.c + * Parse CSV/text/binary format for COPY FROM. + * + * This file contains routines to parse the text, CSV and binary input + * formats. The main entry point is NextCopyFrom(), which parses the + * next input line and returns it as Datums. + * + * In text/CSV mode, the parsing happens in multiple stages: + * + * [data source] --> raw_buf --> input_buf --> line_buf --> attribute_buf + * 1. 2. 3. 4. + * + * 1. CopyLoadRawBuf() reads raw data from the input file or client, and + * places it into 'raw_buf'. + * + * 2. CopyConvertBuf() calls the encoding conversion function to convert + * the data in 'raw_buf' from client to server encoding, placing the + * converted result in 'input_buf'. + * + * 3. CopyReadLine() parses the data in 'input_buf', one line at a time. + * It is responsible for finding the next newline marker, taking quote and + * escape characters into account according to the COPY options. The line + * is copied into 'line_buf', with quotes and escape characters still + * intact. + * + * 4. CopyReadAttributesText/CSV() function takes the input line from + * 'line_buf', and splits it into fields, unescaping the data as required. + * The fields are stored in 'attribute_buf', and 'raw_fields' array holds + * pointers to each field. + * + * If encoding conversion is not required, a shortcut is taken in step 2 to + * avoid copying the data unnecessarily. The 'input_buf' pointer is set to + * point directly to 'raw_buf', so that CopyLoadRawBuf() loads the raw data + * directly into 'input_buf'. CopyConvertBuf() then merely validates that + * the data is valid in the current encoding. + * + * In binary mode, the pipeline is much simpler. Input is loaded into + * into 'raw_buf', and encoding conversion is done in the datatype-specific + * receive functions, if required. 'input_buf' and 'line_buf' are not used, + * but 'attribute_buf' is used as a temporary buffer to hold one attribute's + * data when it's passed the receive function. + * + * 'raw_buf' is always 64 kB in size (RAW_BUF_SIZE). 'input_buf' is also + * 64 kB (INPUT_BUF_SIZE), if encoding conversion is required. 'line_buf' + * and 'attribute_buf' are expanded on demand, to hold the longest line + * encountered so far. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/commands/copyfromparse.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include +#include +#include + +#include "commands/copy.h" +#include "commands/copyfrom_internal.h" +#include "commands/progress.h" +#include "executor/executor.h" +#include "libpq/libpq.h" +#include "libpq/pqformat.h" +#include "mb/pg_wchar.h" +#include "miscadmin.h" +#include "pgstat.h" +#include "port/pg_bswap.h" +#include "utils/memutils.h" +#include "utils/rel.h" + +#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7')) +#define OCTVALUE(c) ((c) - '0') + +/* + * These macros centralize code used to process line_buf and input_buf buffers. + * They are macros because they often do continue/break control and to avoid + * function call overhead in tight COPY loops. + * + * We must use "if (1)" because the usual "do {...} while(0)" wrapper would + * prevent the continue/break processing from working. We end the "if (1)" + * with "else ((void) 0)" to ensure the "if" does not unintentionally match + * any "else" in the calling code, and to avoid any compiler warnings about + * empty statements. See http://www.cit.gu.edu.au/~anthony/info/C/C.macros. + */ + +/* + * This keeps the character read at the top of the loop in the buffer + * even if there is more than one read-ahead. + */ +#define IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(extralen) \ +if (1) \ +{ \ + if (input_buf_ptr + (extralen) >= copy_buf_len && !hit_eof) \ + { \ + input_buf_ptr = prev_raw_ptr; /* undo fetch */ \ + need_data = true; \ + continue; \ + } \ +} else ((void) 0) + +/* This consumes the remainder of the buffer and breaks */ +#define IF_NEED_REFILL_AND_EOF_BREAK(extralen) \ +if (1) \ +{ \ + if (input_buf_ptr + (extralen) >= copy_buf_len && hit_eof) \ + { \ + if (extralen) \ + input_buf_ptr = copy_buf_len; /* consume the partial character */ \ + /* backslash just before EOF, treat as data char */ \ + result = true; \ + break; \ + } \ +} else ((void) 0) + +/* + * Transfer any approved data to line_buf; must do this to be sure + * there is some room in input_buf. + */ +#define REFILL_LINEBUF \ +if (1) \ +{ \ + if (input_buf_ptr > cstate->input_buf_index) \ + { \ + appendBinaryStringInfo(&cstate->line_buf, \ + cstate->input_buf + cstate->input_buf_index, \ + input_buf_ptr - cstate->input_buf_index); \ + cstate->input_buf_index = input_buf_ptr; \ + } \ +} else ((void) 0) + +/* Undo any read-ahead and jump out of the block. */ +#define NO_END_OF_COPY_GOTO \ +if (1) \ +{ \ + input_buf_ptr = prev_raw_ptr + 1; \ + goto not_end_of_copy; \ +} else ((void) 0) + +/* NOTE: there's a copy of this in copyto.c */ +static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"; + + +/* non-export function prototypes */ +static bool CopyReadLine(CopyFromState cstate); +static bool CopyReadLineText(CopyFromState cstate); +static int CopyReadAttributesText(CopyFromState cstate); +static int CopyReadAttributesCSV(CopyFromState cstate); +static Datum CopyReadBinaryAttribute(CopyFromState cstate, FmgrInfo *flinfo, + Oid typioparam, int32 typmod, + bool *isnull); + + +/* Low-level communications functions */ +static int CopyGetData(CopyFromState cstate, void *databuf, + int minread, int maxread); +static inline bool CopyGetInt32(CopyFromState cstate, int32 *val); +static inline bool CopyGetInt16(CopyFromState cstate, int16 *val); +static void CopyLoadInputBuf(CopyFromState cstate); +static int CopyReadBinaryData(CopyFromState cstate, char *dest, int nbytes); + +#if 0 /* GPDB: ReceiveCopyBegin is in copy.c using CopyState */ +void +ReceiveCopyBegin(CopyFromState cstate) +{ + StringInfoData buf; + int natts = list_length(cstate->attnumlist); + int16 format = (cstate->opts.binary ? 1 : 0); + int i; + + pq_beginmessage(&buf, 'G'); + pq_sendbyte(&buf, format); /* overall format */ + pq_sendint16(&buf, natts); + for (i = 0; i < natts; i++) + pq_sendint16(&buf, format); /* per-column formats */ + pq_endmessage(&buf); + cstate->copy_src = COPY_FRONTEND; + cstate->fe_msgbuf = makeStringInfo(); + /* We *must* flush here to ensure FE knows it can send. */ + pq_flush(); +} +#endif + +void +ReceiveCopyBinaryHeader(CopyFromState cstate) +{ + char readSig[11]; + int32 tmp; + + /* Signature */ + if (CopyReadBinaryData(cstate, readSig, 11) != 11 || + memcmp(readSig, BinarySignature, 11) != 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("COPY file signature not recognized"))); + /* Flags field */ + if (!CopyGetInt32(cstate, &tmp)) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("invalid COPY file header (missing flags)"))); + if ((tmp & (1 << 16)) != 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("invalid COPY file header (WITH OIDS)"))); + tmp &= ~(1 << 16); + if ((tmp >> 16) != 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("unrecognized critical flags in COPY file header"))); + /* Header extension length */ + if (!CopyGetInt32(cstate, &tmp) || + tmp < 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("invalid COPY file header (missing length)"))); + /* Skip extension header, if present */ + while (tmp-- > 0) + { + if (CopyReadBinaryData(cstate, readSig, 1) != 1) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("invalid COPY file header (wrong length)"))); + } +} + +/* + * CopyGetData reads data from the source (file or frontend) + * + * We attempt to read at least minread, and at most maxread, bytes from + * the source. The actual number of bytes read is returned; if this is + * less than minread, EOF was detected. + * + * Note: when copying from the frontend, we expect a proper EOF mark per + * protocol; if the frontend simply drops the connection, we raise error. + * It seems unwise to allow the COPY IN to complete normally in that case. + * + * NB: no data conversion is applied here. + */ +static int +CopyGetData(CopyFromState cstate, void *databuf, int minread, int maxread) +{ + int bytesread = 0; + + switch (cstate->copy_src) + { + case COPY_FILE: + bytesread = fread(databuf, 1, maxread, cstate->copy_file); + if (ferror(cstate->copy_file)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read from COPY file: %m"))); + if (bytesread == 0) + cstate->raw_reached_eof = true; + break; + case COPY_FRONTEND: + while (maxread > 0 && bytesread < minread && !cstate->raw_reached_eof) + { + int avail; + + while (cstate->fe_msgbuf->cursor >= cstate->fe_msgbuf->len) + { + /* Try to receive another message */ + int mtype; + int maxmsglen; + + readmessage: + HOLD_CANCEL_INTERRUPTS(); + pq_startmsgread(); + mtype = pq_getbyte(); + if (mtype == EOF) + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("unexpected EOF on client connection with an open transaction"))); + /* Validate message type and set packet size limit */ + switch (mtype) + { + case 'd': /* CopyData */ + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; + break; + case 'c': /* CopyDone */ + case 'f': /* CopyFail */ + case 'H': /* Flush */ + case 'S': /* Sync */ + maxmsglen = PQ_SMALL_MESSAGE_LIMIT; + break; + default: + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("unexpected message type 0x%02X during COPY from stdin", + mtype))); + maxmsglen = 0; /* keep compiler quiet */ + break; + } + /* Now collect the message body */ + if (pq_getmessage(cstate->fe_msgbuf, maxmsglen)) + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("unexpected EOF on client connection with an open transaction"))); + RESUME_CANCEL_INTERRUPTS(); + /* ... and process it */ + switch (mtype) + { + case 'd': /* CopyData */ + break; + case 'c': /* CopyDone */ + /* COPY IN correctly terminated by frontend */ + cstate->raw_reached_eof = true; + return bytesread; + case 'f': /* CopyFail */ + ereport(ERROR, + (errcode(ERRCODE_QUERY_CANCELED), + errmsg("COPY from stdin failed: %s", + pq_getmsgstring(cstate->fe_msgbuf)))); + break; + case 'H': /* Flush */ + case 'S': /* Sync */ + + /* + * Ignore Flush/Sync for the convenience of client + * libraries (such as libpq) that may send those + * without noticing that the command they just + * sent was COPY. + */ + goto readmessage; + default: + Assert(false); /* NOT REACHED */ + } + } + avail = cstate->fe_msgbuf->len - cstate->fe_msgbuf->cursor; + if (avail > maxread) + avail = maxread; + pq_copymsgbytes(cstate->fe_msgbuf, databuf, avail); + databuf = (void *) ((char *) databuf + avail); + maxread -= avail; + bytesread += avail; + } + break; + case COPY_CALLBACK: + bytesread = cstate->data_source_cb(databuf, minread, maxread, + NULL); + break; + } + + return bytesread; +} + + +/* + * These functions do apply some data conversion + */ + +/* + * CopyGetInt32 reads an int32 that appears in network byte order + * + * Returns true if OK, false if EOF + */ +static inline bool +CopyGetInt32(CopyFromState cstate, int32 *val) +{ + uint32 buf; + + if (CopyReadBinaryData(cstate, (char *) &buf, sizeof(buf)) != sizeof(buf)) + { + *val = 0; /* suppress compiler warning */ + return false; + } + *val = (int32) pg_ntoh32(buf); + return true; +} + +/* + * CopyGetInt16 reads an int16 that appears in network byte order + */ +static inline bool +CopyGetInt16(CopyFromState cstate, int16 *val) +{ + uint16 buf; + + if (CopyReadBinaryData(cstate, (char *) &buf, sizeof(buf)) != sizeof(buf)) + { + *val = 0; /* suppress compiler warning */ + return false; + } + *val = (int16) pg_ntoh16(buf); + return true; +} + + +/* + * Perform encoding conversion on data in 'raw_buf', writing the converted + * data into 'input_buf'. + * + * On entry, there must be some data to convert in 'raw_buf'. + */ +static void +CopyConvertBuf(CopyFromState cstate) +{ + /* + * If the file and server encoding are the same, no encoding conversion is + * required. However, we still need to verify that the input is valid for + * the encoding. + */ + if (!cstate->need_transcoding) + { + /* + * When conversion is not required, input_buf and raw_buf are the + * same. raw_buf_len is the total number of bytes in the buffer, and + * input_buf_len tracks how many of those bytes have already been + * verified. + */ + int preverifiedlen = cstate->input_buf_len; + int unverifiedlen = cstate->raw_buf_len - cstate->input_buf_len; + int nverified; + + if (unverifiedlen == 0) + { + /* + * If no more raw data is coming, report the EOF to the caller. + */ + if (cstate->raw_reached_eof) + cstate->input_reached_eof = true; + return; + } + + /* + * Verify the new data, including any residual unverified bytes from + * previous round. + */ + nverified = pg_encoding_verifymbstr(cstate->file_encoding, + cstate->raw_buf + preverifiedlen, + unverifiedlen); + if (nverified == 0) + { + /* + * Could not verify anything. + * + * If there is no more raw input data coming, it means that there + * was an incomplete multi-byte sequence at the end. Also, if + * there's "enough" input left, we should be able to verify at + * least one character, and a failure to do so means that we've + * hit an invalid byte sequence. + */ + if (cstate->raw_reached_eof || unverifiedlen >= pg_database_encoding_max_length()) + cstate->input_reached_error = true; + return; + } + cstate->input_buf_len += nverified; + } + else + { + /* + * Encoding conversion is needed. + */ + int nbytes; + unsigned char *src; + int srclen; + unsigned char *dst; + int dstlen; + int convertedlen; + + if (RAW_BUF_BYTES(cstate) == 0) + { + /* + * If no more raw data is coming, report the EOF to the caller. + */ + if (cstate->raw_reached_eof) + cstate->input_reached_eof = true; + return; + } + + /* + * First, copy down any unprocessed data. + */ + nbytes = INPUT_BUF_BYTES(cstate); + if (nbytes > 0 && cstate->input_buf_index > 0) + memmove(cstate->input_buf, cstate->input_buf + cstate->input_buf_index, + nbytes); + cstate->input_buf_index = 0; + cstate->input_buf_len = nbytes; + cstate->input_buf[nbytes] = '\0'; + + src = (unsigned char *) cstate->raw_buf + cstate->raw_buf_index; + srclen = cstate->raw_buf_len - cstate->raw_buf_index; + dst = (unsigned char *) cstate->input_buf + cstate->input_buf_len; + dstlen = INPUT_BUF_SIZE - cstate->input_buf_len + 1; + + /* + * Do the conversion. This might stop short, if there is an invalid + * byte sequence in the input. We'll convert as much as we can in + * that case. + * + * Note: Even if we hit an invalid byte sequence, we don't report the + * error until all the valid bytes have been consumed. The input + * might contain an end-of-input marker (\.), and we don't want to + * report an error if the invalid byte sequence is after the + * end-of-input marker. We might unnecessarily convert some data + * after the end-of-input marker as long as it's valid for the + * encoding, but that's harmless. + */ + convertedlen = pg_do_encoding_conversion_buf(cstate->conversion_proc, + cstate->file_encoding, + GetDatabaseEncoding(), + src, srclen, + dst, dstlen, + true); + if (convertedlen == 0) + { + /* + * Could not convert anything. If there is no more raw input data + * coming, it means that there was an incomplete multi-byte + * sequence at the end. Also, if there is plenty of input left, + * we should be able to convert at least one character, so a + * failure to do so must mean that we've hit a byte sequence + * that's invalid. + */ + if (cstate->raw_reached_eof || srclen >= MAX_CONVERSION_INPUT_LENGTH) + cstate->input_reached_error = true; + return; + } + cstate->raw_buf_index += convertedlen; + cstate->input_buf_len += strlen((char *) dst); + } +} + +/* + * Report an encoding or conversion error. + */ +static void +CopyConversionError(CopyFromState cstate) +{ + Assert(cstate->raw_buf_len > 0); + Assert(cstate->input_reached_error); + + if (!cstate->need_transcoding) + { + /* + * Everything up to input_buf_len was successfully verified, and + * input_buf_len points to the invalid or incomplete character. + */ + report_invalid_encoding(cstate->file_encoding, + cstate->raw_buf + cstate->input_buf_len, + cstate->raw_buf_len - cstate->input_buf_len); + } + else + { + /* + * raw_buf_index points to the invalid or untranslatable character. We + * let the conversion routine report the error, because it can provide + * a more specific error message than we could here. An earlier call + * to the conversion routine in CopyConvertBuf() detected that there + * is an error, now we call the conversion routine again with + * noError=false, to have it throw the error. + */ + unsigned char *src; + int srclen; + unsigned char *dst; + int dstlen; + + src = (unsigned char *) cstate->raw_buf + cstate->raw_buf_index; + srclen = cstate->raw_buf_len - cstate->raw_buf_index; + dst = (unsigned char *) cstate->input_buf + cstate->input_buf_len; + dstlen = INPUT_BUF_SIZE - cstate->input_buf_len + 1; + + (void) pg_do_encoding_conversion_buf(cstate->conversion_proc, + cstate->file_encoding, + GetDatabaseEncoding(), + src, srclen, + dst, dstlen, + false); + + /* + * The conversion routine should have reported an error, so this + * should not be reached. + */ + elog(ERROR, "encoding conversion failed without error"); + } +} + +/* + * Load more data from data source to raw_buf. + * + * If RAW_BUF_BYTES(cstate) > 0, the unprocessed bytes are moved to the + * beginning of the buffer, and we load new data after that. + */ +static void +CopyLoadRawBuf(CopyFromState cstate) +{ + int nbytes; + int inbytes; + + /* + * In text mode, if encoding conversion is not required, raw_buf and + * input_buf point to the same buffer. Their len/index better agree, too. + */ + if (cstate->raw_buf == cstate->input_buf) + { + Assert(!cstate->need_transcoding); + Assert(cstate->raw_buf_index == cstate->input_buf_index); + Assert(cstate->input_buf_len <= cstate->raw_buf_len); + } + + /* + * Copy down the unprocessed data if any. + */ + nbytes = RAW_BUF_BYTES(cstate); + if (nbytes > 0 && cstate->raw_buf_index > 0) + memmove(cstate->raw_buf, cstate->raw_buf + cstate->raw_buf_index, + nbytes); + cstate->raw_buf_len -= cstate->raw_buf_index; + cstate->raw_buf_index = 0; + + /* + * If raw_buf and input_buf are in fact the same buffer, adjust the + * input_buf variables, too. + */ + if (cstate->raw_buf == cstate->input_buf) + { + cstate->input_buf_len -= cstate->input_buf_index; + cstate->input_buf_index = 0; + } + + /* Load more data */ + inbytes = CopyGetData(cstate, cstate->raw_buf + cstate->raw_buf_len, + 1, RAW_BUF_SIZE - cstate->raw_buf_len); + nbytes += inbytes; + cstate->raw_buf[nbytes] = '\0'; + cstate->raw_buf_len = nbytes; + + cstate->bytes_processed += inbytes; + pgstat_progress_update_param(PROGRESS_COPY_BYTES_PROCESSED, cstate->bytes_processed); + + if (inbytes == 0) + cstate->raw_reached_eof = true; +} + +/* + * CopyLoadInputBuf loads some more data into input_buf + * + * On return, at least one more input character is loaded into + * input_buf, or input_reached_eof is set. + * + * If INPUT_BUF_BYTES(cstate) > 0, the unprocessed bytes are moved to the start + * of the buffer and then we load more data after that. + */ +static void +CopyLoadInputBuf(CopyFromState cstate) +{ + int nbytes = INPUT_BUF_BYTES(cstate); + + /* + * The caller has updated input_buf_index to indicate how much of the + * input has been consumed and isn't needed anymore. If input_buf is the + * same physical area as raw_buf, update raw_buf_index accordingly. + */ + if (cstate->raw_buf == cstate->input_buf) + { + Assert(!cstate->need_transcoding); + Assert(cstate->input_buf_index >= cstate->raw_buf_index); + cstate->raw_buf_index = cstate->input_buf_index; + } + + for (;;) + { + /* If we now have some unconverted data, try to convert it */ + CopyConvertBuf(cstate); + + /* If we now have some more input bytes ready, return them */ + if (INPUT_BUF_BYTES(cstate) > nbytes) + return; + + /* + * If we reached an invalid byte sequence, or we're at an incomplete + * multi-byte character but there is no more raw input data, report + * conversion error. + */ + if (cstate->input_reached_error) + CopyConversionError(cstate); + + /* no more input, and everything has been converted */ + if (cstate->input_reached_eof) + break; + + /* Try to load more raw data */ + Assert(!cstate->raw_reached_eof); + CopyLoadRawBuf(cstate); + } +} + +/* + * CopyReadBinaryData + * + * Reads up to 'nbytes' bytes from cstate->copy_file via cstate->raw_buf + * and writes them to 'dest'. Returns the number of bytes read (which + * would be less than 'nbytes' only if we reach EOF). + */ +static int +CopyReadBinaryData(CopyFromState cstate, char *dest, int nbytes) +{ + int copied_bytes = 0; + + if (RAW_BUF_BYTES(cstate) >= nbytes) + { + /* Enough bytes are present in the buffer. */ + memcpy(dest, cstate->raw_buf + cstate->raw_buf_index, nbytes); + cstate->raw_buf_index += nbytes; + copied_bytes = nbytes; + } + else + { + /* + * Not enough bytes in the buffer, so must read from the file. Need + * to loop since 'nbytes' could be larger than the buffer size. + */ + do + { + int copy_bytes; + + /* Load more data if buffer is empty. */ + if (RAW_BUF_BYTES(cstate) == 0) + { + CopyLoadRawBuf(cstate); + if (cstate->raw_reached_eof) + break; /* EOF */ + } + + /* Transfer some bytes. */ + copy_bytes = Min(nbytes - copied_bytes, RAW_BUF_BYTES(cstate)); + memcpy(dest, cstate->raw_buf + cstate->raw_buf_index, copy_bytes); + cstate->raw_buf_index += copy_bytes; + dest += copy_bytes; + copied_bytes += copy_bytes; + } while (copied_bytes < nbytes); + } + + return copied_bytes; +} + +#if 0 /* GPDB: NextCopyFromRawFields and NextCopyFrom are in copy.c using CopyState */ +/* + * Read raw fields in the next line for COPY FROM in text or csv mode. + * Return false if no more lines. + * + * An internal temporary buffer is returned via 'fields'. It is valid until + * the next call of the function. Since the function returns all raw fields + * in the input file, 'nfields' could be different from the number of columns + * in the relation. + * + * NOTE: force_not_null option are not applied to the returned fields. + */ +bool +NextCopyFromRawFields(CopyFromState cstate, char ***fields, int *nfields) +{ + int fldct; + bool done; + + /* only available for text or csv input */ + Assert(!cstate->opts.binary); + + /* on input just throw the header line away */ + if (cstate->cur_lineno == 0 && cstate->opts.header_line) + { + cstate->cur_lineno++; + if (CopyReadLine(cstate)) + return false; /* done */ + } + + cstate->cur_lineno++; + + /* Actually read the line into memory here */ + done = CopyReadLine(cstate); + + /* + * EOF at start of line means we're done. If we see EOF after some + * characters, we act as though it was newline followed by EOF, ie, + * process the line and then exit loop on next iteration. + */ + if (done && cstate->line_buf.len == 0) + return false; + + /* Parse the line into de-escaped field values */ + if (cstate->opts.csv_mode) + fldct = CopyReadAttributesCSV(cstate); + else + fldct = CopyReadAttributesText(cstate); + + *fields = cstate->raw_fields; + *nfields = fldct; + return true; +} + +/* + * Read next tuple from file for COPY FROM. Return false if no more tuples. + * + * 'econtext' is used to evaluate default expression for each columns not + * read from the file. It can be NULL when no default values are used, i.e. + * when all columns are read from the file. + * + * 'values' and 'nulls' arrays must be the same length as columns of the + * relation passed to BeginCopyFrom. This function fills the arrays. + */ +bool +NextCopyFrom(CopyFromState cstate, ExprContext *econtext, + Datum *values, bool *nulls) +{ + TupleDesc tupDesc; + AttrNumber num_phys_attrs, + attr_count, + num_defaults = cstate->num_defaults; + FmgrInfo *in_functions = cstate->in_functions; + Oid *typioparams = cstate->typioparams; + int i; + int *defmap = cstate->defmap; + ExprState **defexprs = cstate->defexprs; + + tupDesc = RelationGetDescr(cstate->rel); + num_phys_attrs = tupDesc->natts; + attr_count = list_length(cstate->attnumlist); + + /* Initialize all values for row to NULL */ + MemSet(values, 0, num_phys_attrs * sizeof(Datum)); + MemSet(nulls, true, num_phys_attrs * sizeof(bool)); + + if (!cstate->opts.binary) + { + char **field_strings; + ListCell *cur; + int fldct; + int fieldno; + char *string; + + /* read raw fields in the next line */ + if (!NextCopyFromRawFields(cstate, &field_strings, &fldct)) + return false; + + /* check for overflowing fields */ + if (attr_count > 0 && fldct > attr_count) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("extra data after last expected column"))); + + fieldno = 0; + + /* Loop to read the user attributes on the line. */ + foreach(cur, cstate->attnumlist) + { + int attnum = lfirst_int(cur); + int m = attnum - 1; + Form_pg_attribute att = TupleDescAttr(tupDesc, m); + + if (fieldno >= fldct) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("missing data for column \"%s\"", + NameStr(att->attname)))); + string = field_strings[fieldno++]; + + if (cstate->convert_select_flags && + !cstate->convert_select_flags[m]) + { + /* ignore input field, leaving column as NULL */ + continue; + } + + if (cstate->opts.csv_mode) + { + if (string == NULL && + cstate->opts.force_notnull_flags[m]) + { + /* + * FORCE_NOT_NULL option is set and column is NULL - + * convert it to the NULL string. + */ + string = cstate->opts.null_print; + } + else if (string != NULL && cstate->opts.force_null_flags[m] + && strcmp(string, cstate->opts.null_print) == 0) + { + /* + * FORCE_NULL option is set and column matches the NULL + * string. It must have been quoted, or otherwise the + * string would already have been set to NULL. Convert it + * to NULL as specified. + */ + string = NULL; + } + } + + cstate->cur_attname = NameStr(att->attname); + cstate->cur_attval = string; + values[m] = InputFunctionCall(&in_functions[m], + string, + typioparams[m], + att->atttypmod); + if (string != NULL) + nulls[m] = false; + cstate->cur_attname = NULL; + cstate->cur_attval = NULL; + } + + Assert(fieldno == attr_count); + } + else + { + /* binary */ + int16 fld_count; + ListCell *cur; + + cstate->cur_lineno++; + + if (!CopyGetInt16(cstate, &fld_count)) + { + /* EOF detected (end of file, or protocol-level EOF) */ + return false; + } + + if (fld_count == -1) + { + /* + * Received EOF marker. Wait for the protocol-level EOF, and + * complain if it doesn't come immediately. In COPY FROM STDIN, + * this ensures that we correctly handle CopyFail, if client + * chooses to send that now. When copying from file, we could + * ignore the rest of the file like in text mode, but we choose to + * be consistent with the COPY FROM STDIN case. + */ + char dummy; + + if (CopyReadBinaryData(cstate, &dummy, 1) > 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("received copy data after EOF marker"))); + return false; + } + + if (fld_count != attr_count) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("row field count is %d, expected %d", + (int) fld_count, attr_count))); + + foreach(cur, cstate->attnumlist) + { + int attnum = lfirst_int(cur); + int m = attnum - 1; + Form_pg_attribute att = TupleDescAttr(tupDesc, m); + + cstate->cur_attname = NameStr(att->attname); + values[m] = CopyReadBinaryAttribute(cstate, + &in_functions[m], + typioparams[m], + att->atttypmod, + &nulls[m]); + cstate->cur_attname = NULL; + } + } + + /* + * Now compute and insert any defaults available for the columns not + * provided by the input data. Anything not processed here or above will + * remain NULL. + */ + for (i = 0; i < num_defaults; i++) + { + /* + * The caller must supply econtext and have switched into the + * per-tuple memory context in it. + */ + Assert(econtext != NULL); + Assert(CurrentMemoryContext == econtext->ecxt_per_tuple_memory); + + values[defmap[i]] = ExecEvalExpr(defexprs[i], econtext, + &nulls[defmap[i]]); + } + + return true; +} +#endif /* GPDB: NextCopyFromRawFields/NextCopyFrom */ + +/* + * Read the next input line and stash it in line_buf. + * + * Result is true if read was terminated by EOF, false if terminated + * by newline. The terminating newline or EOF marker is not included + * in the final value of line_buf. + */ +static bool +CopyReadLine(CopyFromState cstate) +{ + bool result; + + resetStringInfo(&cstate->line_buf); + cstate->line_buf_valid = false; + + /* Parse data and transfer into line_buf */ + result = CopyReadLineText(cstate); + + if (result) + { + /* + * Reached EOF. In protocol version 3, we should ignore anything + * after \. up to the protocol end of copy data. (XXX maybe better + * not to treat \. as special?) + */ + if (cstate->copy_src == COPY_FRONTEND) + { + int inbytes; + + do + { + inbytes = CopyGetData(cstate, cstate->input_buf, + 1, INPUT_BUF_SIZE); + } while (inbytes > 0); + cstate->input_buf_index = 0; + cstate->input_buf_len = 0; + cstate->raw_buf_index = 0; + cstate->raw_buf_len = 0; + } + } + else + { + /* + * If we didn't hit EOF, then we must have transferred the EOL marker + * to line_buf along with the data. Get rid of it. + */ + switch (cstate->eol_type) + { + case EOL_NL: + Assert(cstate->line_buf.len >= 1); + Assert(cstate->line_buf.data[cstate->line_buf.len - 1] == '\n'); + cstate->line_buf.len--; + cstate->line_buf.data[cstate->line_buf.len] = '\0'; + break; + case EOL_CR: + Assert(cstate->line_buf.len >= 1); + Assert(cstate->line_buf.data[cstate->line_buf.len - 1] == '\r'); + cstate->line_buf.len--; + cstate->line_buf.data[cstate->line_buf.len] = '\0'; + break; + case EOL_CRNL: + Assert(cstate->line_buf.len >= 2); + Assert(cstate->line_buf.data[cstate->line_buf.len - 2] == '\r'); + Assert(cstate->line_buf.data[cstate->line_buf.len - 1] == '\n'); + cstate->line_buf.len -= 2; + cstate->line_buf.data[cstate->line_buf.len] = '\0'; + break; + case EOL_UNKNOWN: + /* shouldn't get here */ + Assert(false); + break; + } + } + + /* Now it's safe to use the buffer in error messages */ + cstate->line_buf_valid = true; + + return result; +} + +/* + * CopyReadLineText - inner loop of CopyReadLine for text mode + */ +static bool +CopyReadLineText(CopyFromState cstate) +{ + char *copy_input_buf; + int input_buf_ptr; + int copy_buf_len; + bool need_data = false; + bool hit_eof = false; + bool result = false; + + /* CSV variables */ + bool first_char_in_line = true; + bool in_quote = false, + last_was_esc = false; + char quotec = '\0'; + char escapec = '\0'; + + if (cstate->opts.csv_mode) + { + quotec = cstate->opts.quote[0]; + escapec = cstate->opts.escape[0]; + /* ignore special escape processing if it's the same as quotec */ + if (quotec == escapec) + escapec = '\0'; + } + + /* + * The objective of this loop is to transfer the entire next input line + * into line_buf. Hence, we only care for detecting newlines (\r and/or + * \n) and the end-of-copy marker (\.). + * + * In CSV mode, \r and \n inside a quoted field are just part of the data + * value and are put in line_buf. We keep just enough state to know if we + * are currently in a quoted field or not. + * + * These four characters, and the CSV escape and quote characters, are + * assumed the same in frontend and backend encodings. + * + * The input has already been converted to the database encoding. All + * supported server encodings have the property that all bytes in a + * multi-byte sequence have the high bit set, so a multibyte character + * cannot contain any newline or escape characters embedded in the + * multibyte sequence. Therefore, we can process the input byte-by-byte, + * regardless of the encoding. + * + * For speed, we try to move data from input_buf to line_buf in chunks + * rather than one character at a time. input_buf_ptr points to the next + * character to examine; any characters from input_buf_index to + * input_buf_ptr have been determined to be part of the line, but not yet + * transferred to line_buf. + * + * For a little extra speed within the loop, we copy input_buf and + * input_buf_len into local variables. + */ + copy_input_buf = cstate->input_buf; + input_buf_ptr = cstate->input_buf_index; + copy_buf_len = cstate->input_buf_len; + + for (;;) + { + int prev_raw_ptr; + char c; + + /* + * Load more data if needed. Ideally we would just force four bytes + * of read-ahead and avoid the many calls to + * IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(), but the COPY_OLD_FE protocol + * does not allow us to read too far ahead or we might read into the + * next data, so we read-ahead only as far we know we can. One + * optimization would be to read-ahead four byte here if + * cstate->copy_src != COPY_OLD_FE, but it hardly seems worth it, + * considering the size of the buffer. + */ + if (input_buf_ptr >= copy_buf_len || need_data) + { + REFILL_LINEBUF; + + CopyLoadInputBuf(cstate); + /* update our local variables */ + hit_eof = cstate->input_reached_eof; + input_buf_ptr = cstate->input_buf_index; + copy_buf_len = cstate->input_buf_len; + + /* + * If we are completely out of data, break out of the loop, + * reporting EOF. + */ + if (INPUT_BUF_BYTES(cstate) <= 0) + { + result = true; + break; + } + need_data = false; + } + + /* OK to fetch a character */ + prev_raw_ptr = input_buf_ptr; + c = copy_input_buf[input_buf_ptr++]; + + if (cstate->opts.csv_mode) + { + /* + * If character is '\\' or '\r', we may need to look ahead below. + * Force fetch of the next character if we don't already have it. + * We need to do this before changing CSV state, in case one of + * these characters is also the quote or escape character. + * + * Note: old-protocol does not like forced prefetch, but it's OK + * here since we cannot validly be at EOF. + */ + if (c == '\\' || c == '\r') + { + IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0); + } + + /* + * Dealing with quotes and escapes here is mildly tricky. If the + * quote char is also the escape char, there's no problem - we + * just use the char as a toggle. If they are different, we need + * to ensure that we only take account of an escape inside a + * quoted field and immediately preceding a quote char, and not + * the second in an escape-escape sequence. + */ + if (in_quote && c == escapec) + last_was_esc = !last_was_esc; + if (c == quotec && !last_was_esc) + in_quote = !in_quote; + if (c != escapec) + last_was_esc = false; + + /* + * Updating the line count for embedded CR and/or LF chars is + * necessarily a little fragile - this test is probably about the + * best we can do. (XXX it's arguable whether we should do this + * at all --- is cur_lineno a physical or logical count?) + */ + if (in_quote && c == (cstate->eol_type == EOL_NL ? '\n' : '\r')) + cstate->cur_lineno++; + } + + /* Process \r */ + if (c == '\r' && (!cstate->opts.csv_mode || !in_quote)) + { + /* Check for \r\n on first line, _and_ handle \r\n. */ + if (cstate->eol_type == EOL_UNKNOWN || + cstate->eol_type == EOL_CRNL) + { + /* + * If need more data, go back to loop top to load it. + * + * Note that if we are at EOF, c will wind up as '\0' because + * of the guaranteed pad of input_buf. + */ + IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0); + + /* get next char */ + c = copy_input_buf[input_buf_ptr]; + + if (c == '\n') + { + input_buf_ptr++; /* eat newline */ + cstate->eol_type = EOL_CRNL; /* in case not set yet */ + } + else + { + /* found \r, but no \n */ + if (cstate->eol_type == EOL_CRNL) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + !cstate->opts.csv_mode ? + errmsg("literal carriage return found in data") : + errmsg("unquoted carriage return found in data"), + !cstate->opts.csv_mode ? + errhint("Use \"\\r\" to represent carriage return.") : + errhint("Use quoted CSV field to represent carriage return."))); + + /* + * if we got here, it is the first line and we didn't find + * \n, so don't consume the peeked character + */ + cstate->eol_type = EOL_CR; + } + } + else if (cstate->eol_type == EOL_NL) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + !cstate->opts.csv_mode ? + errmsg("literal carriage return found in data") : + errmsg("unquoted carriage return found in data"), + !cstate->opts.csv_mode ? + errhint("Use \"\\r\" to represent carriage return.") : + errhint("Use quoted CSV field to represent carriage return."))); + /* If reach here, we have found the line terminator */ + break; + } + + /* Process \n */ + if (c == '\n' && (!cstate->opts.csv_mode || !in_quote)) + { + if (cstate->eol_type == EOL_CR || cstate->eol_type == EOL_CRNL) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + !cstate->opts.csv_mode ? + errmsg("literal newline found in data") : + errmsg("unquoted newline found in data"), + !cstate->opts.csv_mode ? + errhint("Use \"\\n\" to represent newline.") : + errhint("Use quoted CSV field to represent newline."))); + cstate->eol_type = EOL_NL; /* in case not set yet */ + /* If reach here, we have found the line terminator */ + break; + } + + /* + * In CSV mode, we only recognize \. alone on a line. This is because + * \. is a valid CSV data value. + */ + if (c == '\\' && (!cstate->opts.csv_mode || first_char_in_line)) + { + char c2; + + IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0); + IF_NEED_REFILL_AND_EOF_BREAK(0); + + /* ----- + * get next character + * Note: we do not change c so if it isn't \., we can fall + * through and continue processing. + * ----- + */ + c2 = copy_input_buf[input_buf_ptr]; + + if (c2 == '.') + { + input_buf_ptr++; /* consume the '.' */ + + /* + * Note: if we loop back for more data here, it does not + * matter that the CSV state change checks are re-executed; we + * will come back here with no important state changed. + */ + if (cstate->eol_type == EOL_CRNL) + { + /* Get the next character */ + IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0); + /* if hit_eof, c2 will become '\0' */ + c2 = copy_input_buf[input_buf_ptr++]; + + if (c2 == '\n') + { + if (!cstate->opts.csv_mode) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("end-of-copy marker does not match previous newline style"))); + else + NO_END_OF_COPY_GOTO; + } + else if (c2 != '\r') + { + if (!cstate->opts.csv_mode) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("end-of-copy marker corrupt"))); + else + NO_END_OF_COPY_GOTO; + } + } + + /* Get the next character */ + IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(0); + /* if hit_eof, c2 will become '\0' */ + c2 = copy_input_buf[input_buf_ptr++]; + + if (c2 != '\r' && c2 != '\n') + { + if (!cstate->opts.csv_mode) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("end-of-copy marker corrupt"))); + else + NO_END_OF_COPY_GOTO; + } + + if ((cstate->eol_type == EOL_NL && c2 != '\n') || + (cstate->eol_type == EOL_CRNL && c2 != '\n') || + (cstate->eol_type == EOL_CR && c2 != '\r')) + { + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("end-of-copy marker does not match previous newline style"))); + } + + /* + * Transfer only the data before the \. into line_buf, then + * discard the data and the \. sequence. + */ + if (prev_raw_ptr > cstate->input_buf_index) + appendBinaryStringInfo(&cstate->line_buf, + cstate->input_buf + cstate->input_buf_index, + prev_raw_ptr - cstate->input_buf_index); + cstate->input_buf_index = input_buf_ptr; + result = true; /* report EOF */ + break; + } + else if (!cstate->opts.csv_mode) + { + /* + * If we are here, it means we found a backslash followed by + * something other than a period. In non-CSV mode, anything + * after a backslash is special, so we skip over that second + * character too. If we didn't do that \\. would be + * considered an eof-of copy, while in non-CSV mode it is a + * literal backslash followed by a period. In CSV mode, + * backslashes are not special, so we want to process the + * character after the backslash just like a normal character, + * so we don't increment in those cases. + */ + input_buf_ptr++; + } + } + + /* + * This label is for CSV cases where \. appears at the start of a + * line, but there is more text after it, meaning it was a data value. + * We are more strict for \. in CSV mode because \. could be a data + * value, while in non-CSV mode, \. cannot be a data value. + */ +not_end_of_copy: + first_char_in_line = false; + } /* end of outer loop */ + + /* + * Transfer any still-uncopied data to line_buf. + */ + REFILL_LINEBUF; + + return result; +} + +/* + * Return decimal value for a hexadecimal digit + */ +static int +GetDecimalFromHex(char hex) +{ + if (isdigit((unsigned char) hex)) + return hex - '0'; + else + return tolower((unsigned char) hex) - 'a' + 10; +} + +/* + * Parse the current line into separate attributes (fields), + * performing de-escaping as needed. + * + * The input is in line_buf. We use attribute_buf to hold the result + * strings. cstate->raw_fields[k] is set to point to the k'th attribute + * string, or NULL when the input matches the null marker string. + * This array is expanded as necessary. + * + * (Note that the caller cannot check for nulls since the returned + * string would be the post-de-escaping equivalent, which may look + * the same as some valid data string.) + * + * delim is the column delimiter string (must be just one byte for now). + * null_print is the null marker string. Note that this is compared to + * the pre-de-escaped input string. + * + * The return value is the number of fields actually read. + */ +static int +CopyReadAttributesText(CopyFromState cstate) +{ + char delimc = cstate->opts.delim[0]; + int fieldno; + char *output_ptr; + char *cur_ptr; + char *line_end_ptr; + + /* + * We need a special case for zero-column tables: check that the input + * line is empty, and return. + */ + if (cstate->max_fields <= 0) + { + if (cstate->line_buf.len != 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("extra data after last expected column"))); + return 0; + } + + resetStringInfo(&cstate->attribute_buf); + + /* + * The de-escaped attributes will certainly not be longer than the input + * data line, so we can just force attribute_buf to be large enough and + * then transfer data without any checks for enough space. We need to do + * it this way because enlarging attribute_buf mid-stream would invalidate + * pointers already stored into cstate->raw_fields[]. + */ + if (cstate->attribute_buf.maxlen <= cstate->line_buf.len) + enlargeStringInfo(&cstate->attribute_buf, cstate->line_buf.len); + output_ptr = cstate->attribute_buf.data; + + /* set pointer variables for loop */ + cur_ptr = cstate->line_buf.data; + line_end_ptr = cstate->line_buf.data + cstate->line_buf.len; + + /* Outer loop iterates over fields */ + fieldno = 0; + for (;;) + { + bool found_delim = false; + char *start_ptr; + char *end_ptr; + int input_len; + bool saw_non_ascii = false; + + /* Make sure there is enough space for the next value */ + if (fieldno >= cstate->max_fields) + { + cstate->max_fields *= 2; + cstate->raw_fields = + repalloc(cstate->raw_fields, cstate->max_fields * sizeof(char *)); + } + + /* Remember start of field on both input and output sides */ + start_ptr = cur_ptr; + cstate->raw_fields[fieldno] = output_ptr; + + /* + * Scan data for field. + * + * Note that in this loop, we are scanning to locate the end of field + * and also speculatively performing de-escaping. Once we find the + * end-of-field, we can match the raw field contents against the null + * marker string. Only after that comparison fails do we know that + * de-escaping is actually the right thing to do; therefore we *must + * not* throw any syntax errors before we've done the null-marker + * check. + */ + for (;;) + { + char c; + + end_ptr = cur_ptr; + if (cur_ptr >= line_end_ptr) + break; + c = *cur_ptr++; + if (c == delimc) + { + found_delim = true; + break; + } + if (c == '\\') + { + if (cur_ptr >= line_end_ptr) + break; + c = *cur_ptr++; + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + /* handle \013 */ + int val; + + val = OCTVALUE(c); + if (cur_ptr < line_end_ptr) + { + c = *cur_ptr; + if (ISOCTAL(c)) + { + cur_ptr++; + val = (val << 3) + OCTVALUE(c); + if (cur_ptr < line_end_ptr) + { + c = *cur_ptr; + if (ISOCTAL(c)) + { + cur_ptr++; + val = (val << 3) + OCTVALUE(c); + } + } + } + } + c = val & 0377; + if (c == '\0' || IS_HIGHBIT_SET(c)) + saw_non_ascii = true; + } + break; + case 'x': + /* Handle \x3F */ + if (cur_ptr < line_end_ptr) + { + char hexchar = *cur_ptr; + + if (isxdigit((unsigned char) hexchar)) + { + int val = GetDecimalFromHex(hexchar); + + cur_ptr++; + if (cur_ptr < line_end_ptr) + { + hexchar = *cur_ptr; + if (isxdigit((unsigned char) hexchar)) + { + cur_ptr++; + val = (val << 4) + GetDecimalFromHex(hexchar); + } + } + c = val & 0xff; + if (c == '\0' || IS_HIGHBIT_SET(c)) + saw_non_ascii = true; + } + } + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + + /* + * in all other cases, take the char after '\' + * literally + */ + } + } + + /* Add c to output string */ + *output_ptr++ = c; + } + + /* Check whether raw input matched null marker */ + input_len = end_ptr - start_ptr; + if (input_len == cstate->opts.null_print_len && + strncmp(start_ptr, cstate->opts.null_print, input_len) == 0) + cstate->raw_fields[fieldno] = NULL; + else + { + /* + * At this point we know the field is supposed to contain data. + * + * If we de-escaped any non-7-bit-ASCII chars, make sure the + * resulting string is valid data for the db encoding. + */ + if (saw_non_ascii) + { + char *fld = cstate->raw_fields[fieldno]; + + pg_verifymbstr(fld, output_ptr - fld, false); + } + } + + /* Terminate attribute value in output area */ + *output_ptr++ = '\0'; + + fieldno++; + /* Done if we hit EOL instead of a delim */ + if (!found_delim) + break; + } + + /* Clean up state of attribute_buf */ + output_ptr--; + Assert(*output_ptr == '\0'); + cstate->attribute_buf.len = (output_ptr - cstate->attribute_buf.data); + + return fieldno; +} + +/* + * Parse the current line into separate attributes (fields), + * performing de-escaping as needed. This has exactly the same API as + * CopyReadAttributesText, except we parse the fields according to + * "standard" (i.e. common) CSV usage. + */ +static int +CopyReadAttributesCSV(CopyFromState cstate) +{ + char delimc = cstate->opts.delim[0]; + char quotec = cstate->opts.quote[0]; + char escapec = cstate->opts.escape[0]; + int fieldno; + char *output_ptr; + char *cur_ptr; + char *line_end_ptr; + + /* + * We need a special case for zero-column tables: check that the input + * line is empty, and return. + */ + if (cstate->max_fields <= 0) + { + if (cstate->line_buf.len != 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("extra data after last expected column"))); + return 0; + } + + resetStringInfo(&cstate->attribute_buf); + + /* + * The de-escaped attributes will certainly not be longer than the input + * data line, so we can just force attribute_buf to be large enough and + * then transfer data without any checks for enough space. We need to do + * it this way because enlarging attribute_buf mid-stream would invalidate + * pointers already stored into cstate->raw_fields[]. + */ + if (cstate->attribute_buf.maxlen <= cstate->line_buf.len) + enlargeStringInfo(&cstate->attribute_buf, cstate->line_buf.len); + output_ptr = cstate->attribute_buf.data; + + /* set pointer variables for loop */ + cur_ptr = cstate->line_buf.data; + line_end_ptr = cstate->line_buf.data + cstate->line_buf.len; + + /* Outer loop iterates over fields */ + fieldno = 0; + for (;;) + { + bool found_delim = false; + bool saw_quote = false; + char *start_ptr; + char *end_ptr; + int input_len; + + /* Make sure there is enough space for the next value */ + if (fieldno >= cstate->max_fields) + { + cstate->max_fields *= 2; + cstate->raw_fields = + repalloc(cstate->raw_fields, cstate->max_fields * sizeof(char *)); + } + + /* Remember start of field on both input and output sides */ + start_ptr = cur_ptr; + cstate->raw_fields[fieldno] = output_ptr; + + /* + * Scan data for field, + * + * The loop starts in "not quote" mode and then toggles between that + * and "in quote" mode. The loop exits normally if it is in "not + * quote" mode and a delimiter or line end is seen. + */ + for (;;) + { + char c; + + /* Not in quote */ + for (;;) + { + end_ptr = cur_ptr; + if (cur_ptr >= line_end_ptr) + goto endfield; + c = *cur_ptr++; + /* unquoted field delimiter */ + if (c == delimc) + { + found_delim = true; + goto endfield; + } + /* start of quoted field (or part of field) */ + if (c == quotec) + { + saw_quote = true; + break; + } + /* Add c to output string */ + *output_ptr++ = c; + } + + /* In quote */ + for (;;) + { + end_ptr = cur_ptr; + if (cur_ptr >= line_end_ptr) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("unterminated CSV quoted field"))); + + c = *cur_ptr++; + + /* escape within a quoted field */ + if (c == escapec) + { + /* + * peek at the next char if available, and escape it if it + * is an escape char or a quote char + */ + if (cur_ptr < line_end_ptr) + { + char nextc = *cur_ptr; + + if (nextc == escapec || nextc == quotec) + { + *output_ptr++ = nextc; + cur_ptr++; + continue; + } + } + } + + /* + * end of quoted field. Must do this test after testing for + * escape in case quote char and escape char are the same + * (which is the common case). + */ + if (c == quotec) + break; + + /* Add c to output string */ + *output_ptr++ = c; + } + } +endfield: + + /* Terminate attribute value in output area */ + *output_ptr++ = '\0'; + + /* Check whether raw input matched null marker */ + input_len = end_ptr - start_ptr; + if (!saw_quote && input_len == cstate->opts.null_print_len && + strncmp(start_ptr, cstate->opts.null_print, input_len) == 0) + cstate->raw_fields[fieldno] = NULL; + + fieldno++; + /* Done if we hit EOL instead of a delim */ + if (!found_delim) + break; + } + + /* Clean up state of attribute_buf */ + output_ptr--; + Assert(*output_ptr == '\0'); + cstate->attribute_buf.len = (output_ptr - cstate->attribute_buf.data); + + return fieldno; +} + + +/* + * Read a binary attribute + */ +static Datum +CopyReadBinaryAttribute(CopyFromState cstate, FmgrInfo *flinfo, + Oid typioparam, int32 typmod, + bool *isnull) +{ + int32 fld_size; + Datum result; + + if (!CopyGetInt32(cstate, &fld_size)) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("unexpected EOF in COPY data"))); + if (fld_size == -1) + { + *isnull = true; + return ReceiveFunctionCall(flinfo, NULL, typioparam, typmod); + } + if (fld_size < 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("invalid field size"))); + + /* reset attribute_buf to empty, and load raw data in it */ + resetStringInfo(&cstate->attribute_buf); + + enlargeStringInfo(&cstate->attribute_buf, fld_size); + if (CopyReadBinaryData(cstate, cstate->attribute_buf.data, + fld_size) != fld_size) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("unexpected EOF in COPY data"))); + + cstate->attribute_buf.len = fld_size; + cstate->attribute_buf.data[fld_size] = '\0'; + + /* Call the column type's binary input converter */ + result = ReceiveFunctionCall(flinfo, &cstate->attribute_buf, + typioparam, typmod); + + /* Trouble if it didn't eat the whole buffer */ + if (cstate->attribute_buf.cursor != cstate->attribute_buf.len) + ereport(ERROR, + (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), + errmsg("incorrect binary data format"))); + + *isnull = false; + return result; +} diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c new file mode 100644 index 000000000000..3dd5746be40a --- /dev/null +++ b/src/backend/commands/copyto.c @@ -0,0 +1,1318 @@ +/*------------------------------------------------------------------------- + * + * copyto.c + * COPY
TO file/program/client + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/commands/copyto.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include +#include +#include + +#include "access/heapam.h" +#include "access/htup_details.h" +#include "access/tableam.h" +#include "access/xact.h" +#include "access/xlog.h" +#include "commands/copy.h" +#include "commands/progress.h" +#include "executor/execdesc.h" +#include "executor/executor.h" +#include "executor/tuptable.h" +#include "libpq/libpq.h" +#include "libpq/pqformat.h" +#include "mb/pg_wchar.h" +#include "miscadmin.h" +#include "optimizer/optimizer.h" +#include "pgstat.h" +#include "rewrite/rewriteHandler.h" +#include "storage/fd.h" +#include "tcop/tcopprot.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/partcache.h" +#include "utils/rel.h" +#include "utils/snapmgr.h" + +/* + * GPDB: All COPY TO functionality is in copy.c using the monolithic CopyState. + * The PG14 CopyToState-based functions here are disabled to avoid type conflicts. + */ +#if 0 + +/* + * Represents the different dest cases we need to worry about at + * the bottom level + */ +typedef enum CopyDest +{ + COPY_FILE, /* to file (or a piped program) */ + COPY_FRONTEND, /* to frontend */ +} CopyDest; + +/* + * This struct contains all the state variables used throughout a COPY TO + * operation. + * + * Multi-byte encodings: all supported client-side encodings encode multi-byte + * characters by having the first byte's high bit set. Subsequent bytes of the + * character can have the high bit not set. When scanning data in such an + * encoding to look for a match to a single-byte (ie ASCII) character, we must + * use the full pg_encoding_mblen() machinery to skip over multibyte + * characters, else we might find a false match to a trailing byte. In + * supported server encodings, there is no possibility of a false match, and + * it's faster to make useless comparisons to trailing bytes than it is to + * invoke pg_encoding_mblen() to skip over them. encoding_embeds_ascii is true + * when we have to do it the hard way. + */ +typedef struct CopyToStateData +{ + /* low-level state data */ + CopyDest copy_dest; /* type of copy source/destination */ + FILE *copy_file; /* used if copy_dest == COPY_FILE */ + StringInfo fe_msgbuf; /* used for all dests during COPY TO */ + + int file_encoding; /* file or remote side's character encoding */ + bool need_transcoding; /* file encoding diff from server? */ + bool encoding_embeds_ascii; /* ASCII can be non-first byte? */ + + /* parameters from the COPY command */ + Relation rel; /* relation to copy to */ + QueryDesc *queryDesc; /* executable query to copy from */ + List *attnumlist; /* integer list of attnums to copy */ + char *filename; /* filename, or NULL for STDOUT */ + bool is_program; /* is 'filename' a program to popen? */ + + CopyFormatOptions opts; + Node *whereClause; /* WHERE condition (or NULL) */ + + /* + * Working state + */ + MemoryContext copycontext; /* per-copy execution context */ + + FmgrInfo *out_functions; /* lookup info for output functions */ + MemoryContext rowcontext; /* per-row evaluation context */ + uint64 bytes_processed; /* number of bytes processed so far */ + +} CopyToStateData; + +/* DestReceiver for COPY (query) TO */ +typedef struct +{ + DestReceiver pub; /* publicly-known function pointers */ + CopyToState cstate; /* CopyToStateData for the command */ + uint64 processed; /* # of tuples processed */ +} DR_copy; + +/* NOTE: there's a copy of this in copyfromparse.c */ +static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"; + + +/* non-export function prototypes */ +static void EndCopy(CopyToState cstate); +static void ClosePipeToProgram(CopyToState cstate); +static void CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot); +static void CopyAttributeOutText(CopyToState cstate, char *string); +static void CopyAttributeOutCSV(CopyToState cstate, char *string, + bool use_quote, bool single_attr); + +/* Low-level communications functions */ +static void SendCopyBegin(CopyToState cstate); +static void SendCopyEnd(CopyToState cstate); +static void CopySendData(CopyToState cstate, const void *databuf, int datasize); +static void CopySendString(CopyToState cstate, const char *str); +static void CopySendChar(CopyToState cstate, char c); +static void CopySendEndOfRow(CopyToState cstate); +static void CopySendInt32(CopyToState cstate, int32 val); +static void CopySendInt16(CopyToState cstate, int16 val); + + +/* + * Send copy start/stop messages for frontend copies. These have changed + * in past protocol redesigns. + */ +static void +SendCopyBegin(CopyToState cstate) +{ + StringInfoData buf; + int natts = list_length(cstate->attnumlist); + int16 format = (cstate->opts.binary ? 1 : 0); + int i; + + pq_beginmessage(&buf, 'H'); + pq_sendbyte(&buf, format); /* overall format */ + pq_sendint16(&buf, natts); + for (i = 0; i < natts; i++) + pq_sendint16(&buf, format); /* per-column formats */ + pq_endmessage(&buf); + cstate->copy_dest = COPY_FRONTEND; +} + +static void +SendCopyEnd(CopyToState cstate) +{ + /* Shouldn't have any unsent data */ + Assert(cstate->fe_msgbuf->len == 0); + /* Send Copy Done message */ + pq_putemptymessage('c'); +} + +/*---------- + * CopySendData sends output data to the destination (file or frontend) + * CopySendString does the same for null-terminated strings + * CopySendChar does the same for single characters + * CopySendEndOfRow does the appropriate thing at end of each data row + * (data is not actually flushed except by CopySendEndOfRow) + * + * NB: no data conversion is applied by these functions + *---------- + */ +static void +CopySendData(CopyToState cstate, const void *databuf, int datasize) +{ + appendBinaryStringInfo(cstate->fe_msgbuf, databuf, datasize); +} + +static void +CopySendString(CopyToState cstate, const char *str) +{ + appendBinaryStringInfo(cstate->fe_msgbuf, str, strlen(str)); +} + +static void +CopySendChar(CopyToState cstate, char c) +{ + appendStringInfoCharMacro(cstate->fe_msgbuf, c); +} + +static void +CopySendEndOfRow(CopyToState cstate) +{ + StringInfo fe_msgbuf = cstate->fe_msgbuf; + + switch (cstate->copy_dest) + { + case COPY_FILE: + if (!cstate->opts.binary) + { + /* Default line termination depends on platform */ +#ifndef WIN32 + CopySendChar(cstate, '\n'); +#else + CopySendString(cstate, "\r\n"); +#endif + } + + if (fwrite(fe_msgbuf->data, fe_msgbuf->len, 1, + cstate->copy_file) != 1 || + ferror(cstate->copy_file)) + { + if (cstate->is_program) + { + if (errno == EPIPE) + { + /* + * The pipe will be closed automatically on error at + * the end of transaction, but we might get a better + * error message from the subprocess' exit code than + * just "Broken Pipe" + */ + ClosePipeToProgram(cstate); + + /* + * If ClosePipeToProgram() didn't throw an error, the + * program terminated normally, but closed the pipe + * first. Restore errno, and throw an error. + */ + errno = EPIPE; + } + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not write to COPY program: %m"))); + } + else + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not write to COPY file: %m"))); + } + break; + case COPY_FRONTEND: + /* The FE/BE protocol uses \n as newline for all platforms */ + if (!cstate->opts.binary) + CopySendChar(cstate, '\n'); + + /* Dump the accumulated row as one CopyData message */ + (void) pq_putmessage('d', fe_msgbuf->data, fe_msgbuf->len); + break; + } + + /* Update the progress */ + cstate->bytes_processed += fe_msgbuf->len; + pgstat_progress_update_param(PROGRESS_COPY_BYTES_PROCESSED, cstate->bytes_processed); + + resetStringInfo(fe_msgbuf); +} + +/* + * These functions do apply some data conversion + */ + +/* + * CopySendInt32 sends an int32 in network byte order + */ +static inline void +CopySendInt32(CopyToState cstate, int32 val) +{ + uint32 buf; + + buf = pg_hton32((uint32) val); + CopySendData(cstate, &buf, sizeof(buf)); +} + +/* + * CopySendInt16 sends an int16 in network byte order + */ +static inline void +CopySendInt16(CopyToState cstate, int16 val) +{ + uint16 buf; + + buf = pg_hton16((uint16) val); + CopySendData(cstate, &buf, sizeof(buf)); +} + +/* + * Closes the pipe to an external program, checking the pclose() return code. + */ +static void +ClosePipeToProgram(CopyToState cstate) +{ + int pclose_rc; + + Assert(cstate->is_program); + + pclose_rc = ClosePipeStream(cstate->copy_file); + if (pclose_rc == -1) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close pipe to external command: %m"))); + else if (pclose_rc != 0) + { + ereport(ERROR, + (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), + errmsg("program \"%s\" failed", + cstate->filename), + errdetail_internal("%s", wait_result_to_str(pclose_rc)))); + } +} + +/* + * Release resources allocated in a cstate for COPY TO/FROM. + */ +static void +EndCopy(CopyToState cstate) +{ + if (cstate->is_program) + { + ClosePipeToProgram(cstate); + } + else + { + if (cstate->filename != NULL && FreeFile(cstate->copy_file)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + cstate->filename))); + } + + pgstat_progress_end_command(); + + MemoryContextDelete(cstate->copycontext); + pfree(cstate); +} + +/* + * Setup CopyToState to read tuples from a table or a query for COPY TO. + */ +CopyToState +BeginCopyTo(ParseState *pstate, + Relation rel, + RawStmt *raw_query, + Oid queryRelId, + const char *filename, + bool is_program, + List *attnamelist, + List *options) +{ + CopyToState cstate; + bool pipe = (filename == NULL); + TupleDesc tupDesc; + int num_phys_attrs; + MemoryContext oldcontext; + const int progress_cols[] = { + PROGRESS_COPY_COMMAND, + PROGRESS_COPY_TYPE + }; + int64 progress_vals[] = { + PROGRESS_COPY_COMMAND_TO, + 0 + }; + + if (rel != NULL && rel->rd_rel->relkind != RELKIND_RELATION) + { + if (rel->rd_rel->relkind == RELKIND_VIEW) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy from view \"%s\"", + RelationGetRelationName(rel)), + errhint("Try the COPY (SELECT ...) TO variant."))); + else if (rel->rd_rel->relkind == RELKIND_MATVIEW) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy from materialized view \"%s\"", + RelationGetRelationName(rel)), + errhint("Try the COPY (SELECT ...) TO variant."))); + else if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy from foreign table \"%s\"", + RelationGetRelationName(rel)), + errhint("Try the COPY (SELECT ...) TO variant."))); + else if (rel->rd_rel->relkind == RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy from sequence \"%s\"", + RelationGetRelationName(rel)))); + else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy from partitioned table \"%s\"", + RelationGetRelationName(rel)), + errhint("Try the COPY (SELECT ...) TO variant."))); + else + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot copy from non-table relation \"%s\"", + RelationGetRelationName(rel)))); + } + + + /* Allocate workspace and zero all fields */ + cstate = (CopyToStateData *) palloc0(sizeof(CopyToStateData)); + + /* + * We allocate everything used by a cstate in a new memory context. This + * avoids memory leaks during repeated use of COPY in a query. + */ + cstate->copycontext = AllocSetContextCreate(CurrentMemoryContext, + "COPY", + ALLOCSET_DEFAULT_SIZES); + + oldcontext = MemoryContextSwitchTo(cstate->copycontext); + + /* Extract options from the statement node tree */ + ProcessCopyOptions(pstate, &cstate->opts, false /* is_from */ , options); + + /* Process the source/target relation or query */ + if (rel) + { + Assert(!raw_query); + + cstate->rel = rel; + + tupDesc = RelationGetDescr(cstate->rel); + } + else + { + List *rewritten; + Query *query; + PlannedStmt *plan; + DestReceiver *dest; + + cstate->rel = NULL; + + /* + * Run parse analysis and rewrite. Note this also acquires sufficient + * locks on the source table(s). + */ + rewritten = pg_analyze_and_rewrite(raw_query, + pstate->p_sourcetext, NULL, 0, + NULL); + + /* check that we got back something we can work with */ + if (rewritten == NIL) + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("DO INSTEAD NOTHING rules are not supported for COPY"))); + } + else if (list_length(rewritten) > 1) + { + ListCell *lc; + + /* examine queries to determine which error message to issue */ + foreach(lc, rewritten) + { + Query *q = lfirst_node(Query, lc); + + if (q->querySource == QSRC_QUAL_INSTEAD_RULE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("conditional DO INSTEAD rules are not supported for COPY"))); + if (q->querySource == QSRC_NON_INSTEAD_RULE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("DO ALSO rules are not supported for the COPY"))); + } + + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("multi-statement DO INSTEAD rules are not supported for COPY"))); + } + + query = linitial_node(Query, rewritten); + + /* The grammar allows SELECT INTO, but we don't support that */ + if (query->utilityStmt != NULL && + IsA(query->utilityStmt, CreateTableAsStmt)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("COPY (SELECT INTO) is not supported"))); + + Assert(query->utilityStmt == NULL); + + /* + * Similarly the grammar doesn't enforce the presence of a RETURNING + * clause, but this is required here. + */ + if (query->commandType != CMD_SELECT && + query->returningList == NIL) + { + Assert(query->commandType == CMD_INSERT || + query->commandType == CMD_UPDATE || + query->commandType == CMD_DELETE); + + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("COPY query must have a RETURNING clause"))); + } + + /* plan the query */ + plan = pg_plan_query(query, pstate->p_sourcetext, + CURSOR_OPT_PARALLEL_OK, NULL); + + /* + * With row-level security and a user using "COPY relation TO", we + * have to convert the "COPY relation TO" to a query-based COPY (eg: + * "COPY (SELECT * FROM relation) TO"), to allow the rewriter to add + * in any RLS clauses. + * + * When this happens, we are passed in the relid of the originally + * found relation (which we have locked). As the planner will look up + * the relation again, we double-check here to make sure it found the + * same one that we have locked. + */ + if (queryRelId != InvalidOid) + { + /* + * Note that with RLS involved there may be multiple relations, + * and while the one we need is almost certainly first, we don't + * make any guarantees of that in the planner, so check the whole + * list and make sure we find the original relation. + */ + if (!list_member_oid(plan->relationOids, queryRelId)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("relation referenced by COPY statement has changed"))); + } + + /* + * Use a snapshot with an updated command ID to ensure this query sees + * results of any previously executed queries. + */ + PushCopiedSnapshot(GetActiveSnapshot()); + UpdateActiveSnapshotCommandId(); + + /* Create dest receiver for COPY OUT */ + dest = CreateDestReceiver(DestCopyOut); + ((DR_copy *) dest)->cstate = cstate; + + /* Create a QueryDesc requesting no output */ + cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext, + GetActiveSnapshot(), + InvalidSnapshot, + dest, NULL, NULL, 0); + + /* + * Call ExecutorStart to prepare the plan for execution. + * + * ExecutorStart computes a result tupdesc for us + */ + ExecutorStart(cstate->queryDesc, 0); + + tupDesc = cstate->queryDesc->tupDesc; + } + + /* Generate or convert list of attributes to process */ + cstate->attnumlist = CopyGetAttnums(tupDesc, cstate->rel, attnamelist); + + num_phys_attrs = tupDesc->natts; + + /* Convert FORCE_QUOTE name list to per-column flags, check validity */ + cstate->opts.force_quote_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool)); + if (cstate->opts.force_quote_all) + { + int i; + + for (i = 0; i < num_phys_attrs; i++) + cstate->opts.force_quote_flags[i] = true; + } + else if (cstate->opts.force_quote) + { + List *attnums; + ListCell *cur; + + attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_quote); + + foreach(cur, attnums) + { + int attnum = lfirst_int(cur); + Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1); + + if (!list_member_int(cstate->attnumlist, attnum)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg("FORCE_QUOTE column \"%s\" not referenced by COPY", + NameStr(attr->attname)))); + cstate->opts.force_quote_flags[attnum - 1] = true; + } + } + + /* Convert FORCE_NOT_NULL name list to per-column flags, check validity */ + cstate->opts.force_notnull_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool)); + if (cstate->opts.force_notnull) + { + List *attnums; + ListCell *cur; + + attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_notnull); + + foreach(cur, attnums) + { + int attnum = lfirst_int(cur); + Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1); + + if (!list_member_int(cstate->attnumlist, attnum)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg("FORCE_NOT_NULL column \"%s\" not referenced by COPY", + NameStr(attr->attname)))); + cstate->opts.force_notnull_flags[attnum - 1] = true; + } + } + + /* Convert FORCE_NULL name list to per-column flags, check validity */ + cstate->opts.force_null_flags = (bool *) palloc0(num_phys_attrs * sizeof(bool)); + if (cstate->opts.force_null) + { + List *attnums; + ListCell *cur; + + attnums = CopyGetAttnums(tupDesc, cstate->rel, cstate->opts.force_null); + + foreach(cur, attnums) + { + int attnum = lfirst_int(cur); + Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1); + + if (!list_member_int(cstate->attnumlist, attnum)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg("FORCE_NULL column \"%s\" not referenced by COPY", + NameStr(attr->attname)))); + cstate->opts.force_null_flags[attnum - 1] = true; + } + } + + /* Use client encoding when ENCODING option is not specified. */ + if (cstate->opts.file_encoding < 0) + cstate->file_encoding = pg_get_client_encoding(); + else + cstate->file_encoding = cstate->opts.file_encoding; + + /* + * Set up encoding conversion info. Even if the file and server encodings + * are the same, we must apply pg_any_to_server() to validate data in + * multibyte encodings. + */ + cstate->need_transcoding = + (cstate->file_encoding != GetDatabaseEncoding() || + pg_database_encoding_max_length() > 1); + /* See Multibyte encoding comment above */ + cstate->encoding_embeds_ascii = PG_ENCODING_IS_CLIENT_ONLY(cstate->file_encoding); + + cstate->copy_dest = COPY_FILE; /* default */ + + MemoryContextSwitchTo(oldcontext); + + if (pipe) + { + progress_vals[1] = PROGRESS_COPY_TYPE_PIPE; + + Assert(!is_program); /* the grammar does not allow this */ + if (whereToSendOutput != DestRemote) + cstate->copy_file = stdout; + } + else + { + cstate->filename = pstrdup(filename); + cstate->is_program = is_program; + + if (is_program) + { + progress_vals[1] = PROGRESS_COPY_TYPE_PROGRAM; + cstate->copy_file = OpenPipeStream(cstate->filename, PG_BINARY_W); + if (cstate->copy_file == NULL) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not execute command \"%s\": %m", + cstate->filename))); + } + else + { + mode_t oumask; /* Pre-existing umask value */ + struct stat st; + + progress_vals[1] = PROGRESS_COPY_TYPE_FILE; + + /* + * Prevent write to relative path ... too easy to shoot oneself in + * the foot by overwriting a database file ... + */ + if (!is_absolute_path(filename)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_NAME), + errmsg("relative path not allowed for COPY to file"))); + + oumask = umask(S_IWGRP | S_IWOTH); + PG_TRY(); + { + cstate->copy_file = AllocateFile(cstate->filename, PG_BINARY_W); + } + PG_FINALLY(); + { + umask(oumask); + } + PG_END_TRY(); + if (cstate->copy_file == NULL) + { + /* copy errno because ereport subfunctions might change it */ + int save_errno = errno; + + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\" for writing: %m", + cstate->filename), + (save_errno == ENOENT || save_errno == EACCES) ? + errhint("COPY TO instructs the PostgreSQL server process to write a file. " + "You may want a client-side facility such as psql's \\copy.") : 0)); + } + + if (fstat(fileno(cstate->copy_file), &st)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", + cstate->filename))); + + if (S_ISDIR(st.st_mode)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a directory", cstate->filename))); + } + } + + /* initialize progress */ + pgstat_progress_start_command(PROGRESS_COMMAND_COPY, + cstate->rel ? RelationGetRelid(cstate->rel) : InvalidOid); + pgstat_progress_update_multi_param(2, progress_cols, progress_vals); + + cstate->bytes_processed = 0; + + MemoryContextSwitchTo(oldcontext); + + return cstate; +} + +/* + * Clean up storage and release resources for COPY TO. + */ +void +EndCopyTo(CopyToState cstate) +{ + if (cstate->queryDesc != NULL) + { + /* Close down the query and free resources. */ + ExecutorFinish(cstate->queryDesc); + ExecutorEnd(cstate->queryDesc); + FreeQueryDesc(cstate->queryDesc); + PopActiveSnapshot(); + } + + /* Clean up storage */ + EndCopy(cstate); +} + +/* + * Copy from relation or query TO file. + */ +uint64 +DoCopyTo(CopyToState cstate) +{ + bool pipe = (cstate->filename == NULL); + bool fe_copy = (pipe && whereToSendOutput == DestRemote); + TupleDesc tupDesc; + int num_phys_attrs; + ListCell *cur; + uint64 processed; + + if (fe_copy) + SendCopyBegin(cstate); + + if (cstate->rel) + tupDesc = RelationGetDescr(cstate->rel); + else + tupDesc = cstate->queryDesc->tupDesc; + num_phys_attrs = tupDesc->natts; + cstate->opts.null_print_client = cstate->opts.null_print; /* default */ + + /* We use fe_msgbuf as a per-row buffer regardless of copy_dest */ + cstate->fe_msgbuf = makeStringInfo(); + + /* Get info about the columns we need to process. */ + cstate->out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo)); + foreach(cur, cstate->attnumlist) + { + int attnum = lfirst_int(cur); + Oid out_func_oid; + bool isvarlena; + Form_pg_attribute attr = TupleDescAttr(tupDesc, attnum - 1); + + if (cstate->opts.binary) + getTypeBinaryOutputInfo(attr->atttypid, + &out_func_oid, + &isvarlena); + else + getTypeOutputInfo(attr->atttypid, + &out_func_oid, + &isvarlena); + fmgr_info(out_func_oid, &cstate->out_functions[attnum - 1]); + } + + /* + * Create a temporary memory context that we can reset once per row to + * recover palloc'd memory. This avoids any problems with leaks inside + * datatype output routines, and should be faster than retail pfree's + * anyway. (We don't need a whole econtext as CopyFrom does.) + */ + cstate->rowcontext = AllocSetContextCreate(CurrentMemoryContext, + "COPY TO", + ALLOCSET_DEFAULT_SIZES); + + if (cstate->opts.binary) + { + /* Generate header for a binary copy */ + int32 tmp; + + /* Signature */ + CopySendData(cstate, BinarySignature, 11); + /* Flags field */ + tmp = 0; + CopySendInt32(cstate, tmp); + /* No header extension */ + tmp = 0; + CopySendInt32(cstate, tmp); + } + else + { + /* + * For non-binary copy, we need to convert null_print to file + * encoding, because it will be sent directly with CopySendString. + */ + if (cstate->need_transcoding) + cstate->opts.null_print_client = pg_server_to_any(cstate->opts.null_print, + cstate->opts.null_print_len, + cstate->file_encoding); + + /* if a header has been requested send the line */ + if (cstate->opts.header_line) + { + bool hdr_delim = false; + + foreach(cur, cstate->attnumlist) + { + int attnum = lfirst_int(cur); + char *colname; + + if (hdr_delim) + CopySendChar(cstate, cstate->opts.delim[0]); + hdr_delim = true; + + colname = NameStr(TupleDescAttr(tupDesc, attnum - 1)->attname); + + CopyAttributeOutCSV(cstate, colname, false, + list_length(cstate->attnumlist) == 1); + } + + CopySendEndOfRow(cstate); + } + } + + if (cstate->rel) + { + TupleTableSlot *slot; + TableScanDesc scandesc; + + scandesc = table_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL); + slot = table_slot_create(cstate->rel, NULL); + + processed = 0; + while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot)) + { + CHECK_FOR_INTERRUPTS(); + + /* Deconstruct the tuple ... */ + slot_getallattrs(slot); + + /* Format and send the data */ + CopyOneRowTo(cstate, slot); + + /* + * Increment the number of processed tuples, and report the + * progress. + */ + pgstat_progress_update_param(PROGRESS_COPY_TUPLES_PROCESSED, + ++processed); + } + + ExecDropSingleTupleTableSlot(slot); + table_endscan(scandesc); + } + else + { + /* run the plan --- the dest receiver will send tuples */ + ExecutorRun(cstate->queryDesc, ForwardScanDirection, 0L, true); + processed = ((DR_copy *) cstate->queryDesc->dest)->processed; + } + + if (cstate->opts.binary) + { + /* Generate trailer for a binary copy */ + CopySendInt16(cstate, -1); + /* Need to flush out the trailer */ + CopySendEndOfRow(cstate); + } + + MemoryContextDelete(cstate->rowcontext); + + if (fe_copy) + SendCopyEnd(cstate); + + return processed; +} + +/* + * Emit one row during DoCopyTo(). + */ +static void +CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot) +{ + bool need_delim = false; + FmgrInfo *out_functions = cstate->out_functions; + MemoryContext oldcontext; + ListCell *cur; + char *string; + + MemoryContextReset(cstate->rowcontext); + oldcontext = MemoryContextSwitchTo(cstate->rowcontext); + + if (cstate->opts.binary) + { + /* Binary per-tuple header */ + CopySendInt16(cstate, list_length(cstate->attnumlist)); + } + + /* Make sure the tuple is fully deconstructed */ + slot_getallattrs(slot); + + foreach(cur, cstate->attnumlist) + { + int attnum = lfirst_int(cur); + Datum value = slot->tts_values[attnum - 1]; + bool isnull = slot->tts_isnull[attnum - 1]; + + if (!cstate->opts.binary) + { + if (need_delim) + CopySendChar(cstate, cstate->opts.delim[0]); + need_delim = true; + } + + if (isnull) + { + if (!cstate->opts.binary) + CopySendString(cstate, cstate->opts.null_print_client); + else + CopySendInt32(cstate, -1); + } + else + { + if (!cstate->opts.binary) + { + string = OutputFunctionCall(&out_functions[attnum - 1], + value); + if (cstate->opts.csv_mode) + CopyAttributeOutCSV(cstate, string, + cstate->opts.force_quote_flags[attnum - 1], + list_length(cstate->attnumlist) == 1); + else + CopyAttributeOutText(cstate, string); + } + else + { + bytea *outputbytes; + + outputbytes = SendFunctionCall(&out_functions[attnum - 1], + value); + CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ); + CopySendData(cstate, VARDATA(outputbytes), + VARSIZE(outputbytes) - VARHDRSZ); + } + } + } + + CopySendEndOfRow(cstate); + + MemoryContextSwitchTo(oldcontext); +} + +/* + * Send text representation of one attribute, with conversion and escaping + */ +#define DUMPSOFAR() \ + do { \ + if (ptr > start) \ + CopySendData(cstate, start, ptr - start); \ + } while (0) + +static void +CopyAttributeOutText(CopyToState cstate, char *string) +{ + char *ptr; + char *start; + char c; + char delimc = cstate->opts.delim[0]; + + if (cstate->need_transcoding) + ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding); + else + ptr = string; + + /* + * We have to grovel through the string searching for control characters + * and instances of the delimiter character. In most cases, though, these + * are infrequent. To avoid overhead from calling CopySendData once per + * character, we dump out all characters between escaped characters in a + * single call. The loop invariant is that the data from "start" to "ptr" + * can be sent literally, but hasn't yet been. + * + * We can skip pg_encoding_mblen() overhead when encoding is safe, because + * in valid backend encodings, extra bytes of a multibyte character never + * look like ASCII. This loop is sufficiently performance-critical that + * it's worth making two copies of it to get the IS_HIGHBIT_SET() test out + * of the normal safe-encoding path. + */ + if (cstate->encoding_embeds_ascii) + { + start = ptr; + while ((c = *ptr) != '\0') + { + if ((unsigned char) c < (unsigned char) 0x20) + { + /* + * \r and \n must be escaped, the others are traditional. We + * prefer to dump these using the C-like notation, rather than + * a backslash and the literal character, because it makes the + * dump file a bit more proof against Microsoftish data + * mangling. + */ + switch (c) + { + case '\b': + c = 'b'; + break; + case '\f': + c = 'f'; + break; + case '\n': + c = 'n'; + break; + case '\r': + c = 'r'; + break; + case '\t': + c = 't'; + break; + case '\v': + c = 'v'; + break; + default: + /* If it's the delimiter, must backslash it */ + if (c == delimc) + break; + /* All ASCII control chars are length 1 */ + ptr++; + continue; /* fall to end of loop */ + } + /* if we get here, we need to convert the control char */ + DUMPSOFAR(); + CopySendChar(cstate, '\\'); + CopySendChar(cstate, c); + start = ++ptr; /* do not include char in next run */ + } + else if (c == '\\' || c == delimc) + { + DUMPSOFAR(); + CopySendChar(cstate, '\\'); + start = ptr++; /* we include char in next run */ + } + else if (IS_HIGHBIT_SET(c)) + ptr += pg_encoding_mblen(cstate->file_encoding, ptr); + else + ptr++; + } + } + else + { + start = ptr; + while ((c = *ptr) != '\0') + { + if ((unsigned char) c < (unsigned char) 0x20) + { + /* + * \r and \n must be escaped, the others are traditional. We + * prefer to dump these using the C-like notation, rather than + * a backslash and the literal character, because it makes the + * dump file a bit more proof against Microsoftish data + * mangling. + */ + switch (c) + { + case '\b': + c = 'b'; + break; + case '\f': + c = 'f'; + break; + case '\n': + c = 'n'; + break; + case '\r': + c = 'r'; + break; + case '\t': + c = 't'; + break; + case '\v': + c = 'v'; + break; + default: + /* If it's the delimiter, must backslash it */ + if (c == delimc) + break; + /* All ASCII control chars are length 1 */ + ptr++; + continue; /* fall to end of loop */ + } + /* if we get here, we need to convert the control char */ + DUMPSOFAR(); + CopySendChar(cstate, '\\'); + CopySendChar(cstate, c); + start = ++ptr; /* do not include char in next run */ + } + else if (c == '\\' || c == delimc) + { + DUMPSOFAR(); + CopySendChar(cstate, '\\'); + start = ptr++; /* we include char in next run */ + } + else + ptr++; + } + } + + DUMPSOFAR(); +} + +/* + * Send text representation of one attribute, with conversion and + * CSV-style escaping + */ +static void +CopyAttributeOutCSV(CopyToState cstate, char *string, + bool use_quote, bool single_attr) +{ + char *ptr; + char *start; + char c; + char delimc = cstate->opts.delim[0]; + char quotec = cstate->opts.quote[0]; + char escapec = cstate->opts.escape[0]; + + /* force quoting if it matches null_print (before conversion!) */ + if (!use_quote && strcmp(string, cstate->opts.null_print) == 0) + use_quote = true; + + if (cstate->need_transcoding) + ptr = pg_server_to_any(string, strlen(string), cstate->file_encoding); + else + ptr = string; + + /* + * Make a preliminary pass to discover if it needs quoting + */ + if (!use_quote) + { + /* + * Because '\.' can be a data value, quote it if it appears alone on a + * line so it is not interpreted as the end-of-data marker. + */ + if (single_attr && strcmp(ptr, "\\.") == 0) + use_quote = true; + else + { + char *tptr = ptr; + + while ((c = *tptr) != '\0') + { + if (c == delimc || c == quotec || c == '\n' || c == '\r') + { + use_quote = true; + break; + } + if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii) + tptr += pg_encoding_mblen(cstate->file_encoding, tptr); + else + tptr++; + } + } + } + + if (use_quote) + { + CopySendChar(cstate, quotec); + + /* + * We adopt the same optimization strategy as in CopyAttributeOutText + */ + start = ptr; + while ((c = *ptr) != '\0') + { + if (c == quotec || c == escapec) + { + DUMPSOFAR(); + CopySendChar(cstate, escapec); + start = ptr; /* we include char in next run */ + } + if (IS_HIGHBIT_SET(c) && cstate->encoding_embeds_ascii) + ptr += pg_encoding_mblen(cstate->file_encoding, ptr); + else + ptr++; + } + DUMPSOFAR(); + + CopySendChar(cstate, quotec); + } + else + { + /* If it doesn't need quoting, we can just dump it as-is */ + CopySendString(cstate, ptr); + } +} + +/* + * copy_dest_startup --- executor startup + */ +static void +copy_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo) +{ + /* no-op */ +} + +/* + * copy_dest_receive --- receive one tuple + */ +static bool +copy_dest_receive(TupleTableSlot *slot, DestReceiver *self) +{ + DR_copy *myState = (DR_copy *) self; + CopyToState cstate = myState->cstate; + + /* Send the data */ + CopyOneRowTo(cstate, slot); + + /* Increment the number of processed tuples, and report the progress */ + pgstat_progress_update_param(PROGRESS_COPY_TUPLES_PROCESSED, + ++myState->processed); + + return true; +} + +/* + * copy_dest_shutdown --- executor end + */ +static void +copy_dest_shutdown(DestReceiver *self) +{ + /* no-op */ +} + +/* + * copy_dest_destroy --- release DestReceiver object + */ +static void +copy_dest_destroy(DestReceiver *self) +{ + pfree(self); +} + +/* + * CreateCopyDestReceiver -- create a suitable DestReceiver object + */ +DestReceiver * +CreateCopyDestReceiver(void) +{ + DR_copy *self = (DR_copy *) palloc(sizeof(DR_copy)); + + self->pub.receiveSlot = copy_dest_receive; + self->pub.rStartup = copy_dest_startup; + self->pub.rShutdown = copy_dest_shutdown; + self->pub.rDestroy = copy_dest_destroy; + self->pub.mydest = DestCopyOut; + + self->cstate = NULL; /* will be set later */ + self->processed = 0; + + return (DestReceiver *) self; +} + +#endif /* GPDB: disabled copyto.c */ diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index cba6b3d86977..10e82c11736c 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -13,7 +13,7 @@ * we must return a tuples-processed count in the QueryCompletion. (We no * longer do that for CTAS ... WITH NO DATA, however.) * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -310,33 +310,10 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, Assert(Gp_role != GP_ROLE_EXECUTE); - if (stmt->if_not_exists) - { - Oid nspid; - Oid oldrelid; - - nspid = RangeVarGetCreationNamespace(into->rel); + /* Check if the relation exists or not */ + if (CreateTableAsRelExists(stmt)) + return InvalidObjectAddress; - oldrelid = get_relname_relid(into->rel->relname, nspid); - if (OidIsValid(oldrelid)) - { - /* - * The relation exists and IF NOT EXISTS has been specified. - * - * If we are in an extension script, insist that the pre-existing - * object be a member of the extension, to avoid security risks. - */ - ObjectAddressSet(address, RelationRelationId, oldrelid); - checkMembershipInCurrentExtension(&address); - - /* OK to skip */ - ereport(NOTICE, - (errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" already exists, skipping", - into->rel->relname))); - return InvalidObjectAddress; - } - } /* * Create the tuple receiver object and insert info it will need */ @@ -382,14 +359,8 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, * rewriter. We do not do AcquireRewriteLocks: we assume the query * either came straight from the parser, or suitable locks were * acquired by plancache.c. - * - * Because the rewriter and planner tend to scribble on the input, we - * make a preliminary copy of the source querytree. This prevents - * problems in the case that CTAS is in a portal or plpgsql function - * and is executed repeatedly. (See also the same hack in EXPLAIN and - * PREPARE.) */ - rewritten = QueryRewrite(copyObject(query)); + rewritten = QueryRewrite(query); /* SELECT should never rewrite to more or less than one SELECT query */ if (list_length(rewritten) != 1) @@ -519,6 +490,41 @@ GetIntoRelEFlags(IntoClause *intoClause) return flags; } +/* + * CreateTableAsRelExists --- check existence of relation for CreateTableAsStmt + * + * Utility wrapper checking if the relation pending for creation in this + * CreateTableAsStmt query already exists or not. Returns true if the + * relation exists, otherwise false. + */ +bool +CreateTableAsRelExists(CreateTableAsStmt *ctas) +{ + Oid nspid; + IntoClause *into = ctas->into; + + nspid = RangeVarGetCreationNamespace(into->rel); + + if (get_relname_relid(into->rel->relname, nspid)) + { + if (!ctas->if_not_exists) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_TABLE), + errmsg("relation \"%s\" already exists", + into->rel->relname))); + + /* The relation exists and IF NOT EXISTS has been specified */ + ereport(NOTICE, + (errcode(ERRCODE_DUPLICATE_TABLE), + errmsg("relation \"%s\" already exists, skipping", + into->rel->relname))); + return true; + } + + /* Relation does not exist, it can be created */ + return false; +} + /* * CreateIntoRelDestReceiver -- create a suitable DestReceiver object * @@ -569,11 +575,9 @@ intorel_initplan(struct QueryDesc *queryDesc, int eflags) /* Get 'into' from the dispatched plan */ IntoClause *into = queryDesc->plannedstmt->intoClause; bool is_matview; - char relkind; List *attrList; ObjectAddress intoRelationAddr; Relation intoRelationDesc; - RangeTblEntry *rte; ListCell *lc; int attnum; TupleDesc typeinfo = queryDesc->tupDesc; @@ -585,7 +589,6 @@ intorel_initplan(struct QueryDesc *queryDesc, int eflags) /* This code supports both CREATE TABLE AS and CREATE MATERIALIZED VIEW */ is_matview = (into->viewQuery != NULL); - relkind = is_matview ? RELKIND_MATVIEW : RELKIND_RELATION; /* * Build column definitions using "pre-cooked" type and collation info. If @@ -652,25 +655,6 @@ intorel_initplan(struct QueryDesc *queryDesc, int eflags) */ intoRelationDesc = table_open(intoRelationAddr.objectId, AccessExclusiveLock); - /* - * Check INSERT permission on the constructed table. - * - * XXX: It would arguably make sense to skip this check if into->skipData - * is true. - */ - rte = makeNode(RangeTblEntry); - rte->rtekind = RTE_RELATION; - rte->relid = intoRelationAddr.objectId; - rte->relkind = relkind; - rte->rellockmode = RowExclusiveLock; - rte->requiredPerms = ACL_INSERT; - - for (attnum = 1; attnum <= intoRelationDesc->rd_att->natts; attnum++) - rte->insertedCols = bms_add_member(rte->insertedCols, - attnum - FirstLowInvalidHeapAttributeNumber); - - ExecCheckRTPerms(list_make1(rte), true); - /* * Make sure the constructed table does not have RLS enabled. * @@ -698,11 +682,26 @@ intorel_initplan(struct QueryDesc *queryDesc, int eflags) if (queryDesc->dest->mydest != DestIntoRel) queryDesc->dest = CreateIntoRelDestReceiver(into); myState = (DR_intorel *) queryDesc->dest; + /* + * Ensure myState->into is set: callers such as ALTER TABLE ... SET + * DISTRIBUTED BY build the receiver with the generic + * CreateDestReceiver(DestIntoRel), which leaves into NULL; intorel_receive + * and intorel_shutdown dereference it. + */ + myState->into = into; myState->rel = intoRelationDesc; myState->reladdr = intoRelationAddr; myState->output_cid = GetCurrentCommandId(true); myState->ti_options = TABLE_INSERT_SKIP_FSM; - myState->bistate = GetBulkInsertState(); + + /* + * If WITH NO DATA is specified, there is no need to set up the state for + * bulk inserts as there are no tuples to insert. + */ + if (!into->skipData) + myState->bistate = GetBulkInsertState(); + else + myState->bistate = NULL; /* * Valid smgr_targblock implies something already wrote to the relation. @@ -719,20 +718,23 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self) { DR_intorel *myState = (DR_intorel *) self; - /* - * Note that the input slot might not be of the type of the target - * relation. That's supported by table_tuple_insert(), but slightly less - * efficient than inserting with the right slot - but the alternative - * would be to copy into a slot of the right type, which would not be - * cheap either. This also doesn't allow accessing per-AM data (say a - * tuple's xmin), but since we don't do that here... - */ - - table_tuple_insert(myState->rel, - slot, - myState->output_cid, - myState->ti_options, - myState->bistate); + /* Nothing to insert if WITH NO DATA is specified. */ + if (!myState->into->skipData) + { + /* + * Note that the input slot might not be of the type of the target + * relation. That's supported by table_tuple_insert(), but slightly + * less efficient than inserting with the right slot - but the + * alternative would be to copy into a slot of the right type, which + * would not be cheap either. This also doesn't allow accessing per-AM + * data (say a tuple's xmin), but since we don't do that here... + */ + table_tuple_insert(myState->rel, + slot, + myState->output_cid, + myState->ti_options, + myState->bistate); + } /* We know this is a newly created relation, so there are no indexes */ @@ -746,14 +748,13 @@ static void intorel_shutdown(DestReceiver *self) { DR_intorel *myState = (DR_intorel *) self; - Relation into_rel = myState->rel; - - if (into_rel == NULL) - return; + IntoClause *into = myState->into; - FreeBulkInsertState(myState->bistate); - - table_finish_bulk_insert(myState->rel, myState->ti_options); + if (!into->skipData) + { + FreeBulkInsertState(myState->bistate); + table_finish_bulk_insert(myState->rel, myState->ti_options); + } if (myState->rel->rd_tableam) table_dml_finish(myState->rel); diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 218dd27b4151..1e14a0d894f7 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -10,7 +10,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 3a2aff79c284..84487b7d4b42 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -4,7 +4,7 @@ * Support routines for various kinds of object creation. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/commands/discard.c b/src/backend/commands/discard.c index a7a7816d1217..2ac91f3b3fd4 100644 --- a/src/backend/commands/discard.c +++ b/src/backend/commands/discard.c @@ -3,7 +3,7 @@ * discard.c * The implementation of the DISCARD command * - * Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index 5cd994a2f0c4..a6ddfa17b392 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -3,7 +3,7 @@ * dropcmds.c * handle various "DROP" operations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index 28bfaa3ad359..1cf37d5aa39f 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -3,7 +3,7 @@ * event_trigger.c * PostgreSQL EVENT TRIGGER support code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -177,7 +177,7 @@ CreateEventTrigger(CreateEventTrigStmt *stmt) /* Find and validate the trigger function. */ funcoid = LookupFuncName(stmt->funcname, 0, NULL, false); funcrettype = get_func_rettype(funcoid); - if (funcrettype != EVTTRIGGEROID) + if (funcrettype != EVENT_TRIGGEROID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("function %s must return type %s", @@ -1654,9 +1654,15 @@ EventTriggerAlterTableEnd(void) /* If no subcommands, don't collect */ if (list_length(currentEventTriggerState->currentCommand->d.alterTable.subcmds) != 0) { + MemoryContext oldcxt; + + oldcxt = MemoryContextSwitchTo(currentEventTriggerState->cxt); + currentEventTriggerState->commandList = lappend(currentEventTriggerState->commandList, currentEventTriggerState->currentCommand); + + MemoryContextSwitchTo(oldcxt); } else pfree(currentEventTriggerState->currentCommand); @@ -1938,8 +1944,19 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS) else if (cmd->type == SCT_AlterTSConfig) addr = cmd->d.atscfg.address; - type = getObjectTypeDescription(&addr, false); - identity = getObjectIdentity(&addr, false); + /* + * If an object was dropped in the same command we may end + * up in a situation where we generated a message but can + * no longer look for the object information, so skip it + * rather than failing. This can happen for example with + * some subcommand combinations of ALTER TABLE. + */ + identity = getObjectIdentity(&addr, true); + if (identity == NULL) + continue; + + /* The type can never be NULL. */ + type = getObjectTypeDescription(&addr, true); /* * Obtain schema name, if any ("pg_temp" if a temp diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 1c54abe7903f..63cc007faca9 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION @@ -30,6 +30,7 @@ #include "nodes/extensible.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "parser/analyze.h" #include "parser/parsetree.h" #include "rewrite/rewriteHandler.h" #include "storage/bufmgr.h" @@ -132,6 +133,8 @@ static void show_windowagg_keys(WindowAggState *waggstate, List *ancestors, Expl static void show_incremental_sort_info(IncrementalSortState *incrsortstate, ExplainState *es); static void show_hash_info(HashState *hashstate, ExplainState *es); +static void show_resultcache_info(ResultCacheState *rcstate, List *ancestors, + ExplainState *es); static void show_hashagg_info(AggState *hashstate, ExplainState *es); static void show_tidbitmap_info(BitmapHeapScanState *planstate, ExplainState *es); @@ -141,7 +144,8 @@ static void show_foreignscan_info(ForeignScanState *fsstate, ExplainState *es); static void show_eval_params(Bitmapset *bms_params, ExplainState *es); static void show_join_pruning_info(List *join_prune_ids, ExplainState *es); static const char *explain_get_index_name(Oid indexId); -static void show_buffer_usage(ExplainState *es, const BufferUsage *usage); +static void show_buffer_usage(ExplainState *es, const BufferUsage *usage, + bool planning); static void show_wal_usage(ExplainState *es, const WalUsage *usage); static void ExplainIndexScanDetails(Oid indexid, ScanDirection indexorderdir, ExplainState *es); @@ -193,6 +197,8 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, { ExplainState *es = NewExplainState(); TupOutputState *tstate; + JumbleState *jstate = NULL; + Query *query; List *rewritten; ListCell *lc; bool timing_set = false; @@ -256,11 +262,6 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, parser_errposition(pstate, opt->location))); } - if (es->buffers && !es->analyze) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("EXPLAIN option BUFFERS requires ANALYZE"))); - if (es->wal && !es->analyze) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -280,20 +281,20 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, if (explain_memory_verbosity >= EXPLAIN_MEMORY_VERBOSITY_DETAIL) es->memory_detail = true; + query = castNode(Query, stmt->query); + if (IsQueryIdEnabled()) + jstate = JumbleQuery(query, pstate->p_sourcetext); + + if (post_parse_analyze_hook) + (*post_parse_analyze_hook) (pstate, query, jstate); /* * Parse analysis was done already, but we still have to run the rule * rewriter. We do not do AcquireRewriteLocks: we assume the query either * came straight from the parser, or suitable locks were acquired by * plancache.c. - * - * Because the rewriter and planner tend to scribble on the input, we make - * a preliminary copy of the source querytree. This prevents problems in - * the case that the EXPLAIN is in a portal or plpgsql function and is - * executed repeatedly. (See also the same hack in DECLARE CURSOR and - * PREPARE.) XXX FIXME someday. */ - rewritten = QueryRewrite(castNode(Query, copyObject(stmt->query))); + rewritten = QueryRewrite(castNode(Query, stmt->query)); /* emit opening boilerplate */ ExplainBeginOutput(es); @@ -513,7 +514,8 @@ ExplainOneQuery(Query *query, int cursorOptions, * "into" is NULL unless we are explaining the contents of a CreateTableAsStmt. * * This is exported because it's called back from prepare.c in the - * EXPLAIN EXECUTE case. + * EXPLAIN EXECUTE case. In that case, we'll be dealing with a statement + * that's in the plan cache, so we have to ensure we don't modify it. */ void ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es, @@ -527,12 +529,27 @@ ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es, { /* * We have to rewrite the contained SELECT and then pass it back to - * ExplainOneQuery. It's probably not really necessary to copy the - * contained parsetree another time, but let's be safe. + * ExplainOneQuery. Copy to be safe in the EXPLAIN EXECUTE case. */ CreateTableAsStmt *ctas = (CreateTableAsStmt *) utilityStmt; List *rewritten; + /* + * Check if the relation exists or not. This is done at this stage to + * avoid query planning or execution. + */ + if (CreateTableAsRelExists(ctas)) + { + if (ctas->objtype == OBJECT_TABLE) + ExplainDummyGroup("CREATE TABLE AS", NULL, es); + else if (ctas->objtype == OBJECT_MATVIEW) + ExplainDummyGroup("CREATE MATERIALIZED VIEW", NULL, es); + else + elog(ERROR, "unexpected object type: %d", + (int) ctas->objtype); + return; + } + rewritten = QueryRewrite(castNode(Query, copyObject(ctas->query))); Assert(list_length(rewritten) == 1); ExplainOneQuery(linitial_node(Query, rewritten), @@ -724,8 +741,21 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, if (cursorOptions & CURSOR_OPT_PARALLEL_RETRIEVE) ExplainParallelRetrieveCursor(es, queryDesc); - if (es->summary && (planduration || bufusage)) + if (es->verbose && plannedstmt->queryId != UINT64CONST(0)) + { + char buf[MAXINT8LEN + 1]; + + pg_lltoa(plannedstmt->queryId, buf); + ExplainPropertyText("Query Identifier", buf, es); + } + + /* Show buffer usage in planning */ + if (bufusage) + { ExplainOpenGroup("Planning", "Planning", true, es); + show_buffer_usage(es, bufusage, true); + ExplainCloseGroup("Planning", "Planning", true, es); + } if (es->summary && planduration) { @@ -738,19 +768,6 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, if (es->slicetable) ExplainPrintSliceTable(es, queryDesc); - /* Show buffer usage */ - if (es->summary && bufusage) - { - if (es->format == EXPLAIN_FORMAT_TEXT) - es->indent++; - show_buffer_usage(es, bufusage); - if (es->format == EXPLAIN_FORMAT_TEXT) - es->indent--; - } - - if (es->summary && (planduration || bufusage)) - ExplainCloseGroup("Planning", "Planning", true, es); - /* Print info about runtime of triggers */ if (es->analyze) ExplainPrintTriggers(es, queryDesc); @@ -1077,27 +1094,24 @@ ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc) { ResultRelInfo *rInfo; bool show_relname; - int numrels = queryDesc->estate->es_num_result_relations; - int numrootrels = queryDesc->estate->es_num_root_result_relations; + List *resultrels; List *routerels; List *targrels; - int nr; ListCell *l; + resultrels = queryDesc->estate->es_opened_result_relations; routerels = queryDesc->estate->es_tuple_routing_result_relations; targrels = queryDesc->estate->es_trig_target_relations; ExplainOpenGroup("Triggers", "Triggers", false, es); - show_relname = (numrels > 1 || numrootrels > 0 || + show_relname = (list_length(resultrels) > 1 || routerels != NIL || targrels != NIL); - rInfo = queryDesc->estate->es_result_relations; - for (nr = 0; nr < numrels; rInfo++, nr++) - report_triggers(rInfo, show_relname, es); - - rInfo = queryDesc->estate->es_root_result_relations; - for (nr = 0; nr < numrootrels; rInfo++, nr++) + foreach(l, resultrels) + { + rInfo = (ResultRelInfo *) lfirst(l); report_triggers(rInfo, show_relname, es); + } foreach(l, routerels) { @@ -1416,6 +1430,7 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used) case T_BitmapHeapScan: case T_DynamicBitmapHeapScan: case T_TidScan: + case T_TidRangeScan: case T_SubqueryScan: case T_FunctionScan: case T_TableFuncScan: @@ -1642,6 +1657,9 @@ ExplainNode(PlanState *planstate, List *ancestors, case T_TidScan: pname = sname = "Tid Scan"; break; + case T_TidRangeScan: + pname = sname = "Tid Range Scan"; + break; case T_SubqueryScan: pname = sname = "Subquery Scan"; break; @@ -1702,6 +1720,9 @@ ExplainNode(PlanState *planstate, List *ancestors, case T_Material: pname = sname = "Materialize"; break; + case T_ResultCache: + pname = sname = "Result Cache"; + break; case T_Sort: pname = sname = "Sort"; break; @@ -1882,6 +1903,8 @@ ExplainNode(PlanState *planstate, List *ancestors, } if (plan->parallel_aware) appendStringInfoString(es->str, "Parallel "); + if (plan->async_capable) + appendStringInfoString(es->str, "Async "); appendStringInfoString(es->str, pname); /* @@ -1918,6 +1941,7 @@ ExplainNode(PlanState *planstate, List *ancestors, show_dispatch_info(es->currentSlice, es, plan); ExplainPropertyBool("Parallel Aware", plan->parallel_aware, es); + ExplainPropertyBool("Async Capable", plan->async_capable, es); } switch (nodeTag(plan)) @@ -1928,6 +1952,7 @@ ExplainNode(PlanState *planstate, List *ancestors, case T_BitmapHeapScan: case T_DynamicBitmapHeapScan: case T_TidScan: + case T_TidRangeScan: case T_SubqueryScan: case T_FunctionScan: case T_TableFunctionScan: @@ -2181,9 +2206,9 @@ ExplainNode(PlanState *planstate, List *ancestors, { if (es->timing) { - ExplainPropertyFloat("Actual Startup Time", "s", startup_ms, + ExplainPropertyFloat("Actual Startup Time", "ms", startup_ms, 3, es); - ExplainPropertyFloat("Actual Total Time", "s", total_ms, + ExplainPropertyFloat("Actual Total Time", "ms", total_ms, 3, es); } ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es); @@ -2500,6 +2525,23 @@ ExplainNode(PlanState *planstate, List *ancestors, planstate, es); } break; + case T_TidRangeScan: + { + /* + * The tidrangequals list has AND semantics, so be sure to + * show it as an AND condition. + */ + List *tidquals = ((TidRangeScan *) plan)->tidrangequals; + + if (list_length(tidquals) > 1) + tidquals = list_make1(make_andclause(tidquals)); + show_scan_qual(tidquals, "TID Cond", planstate, ancestors, es); + show_scan_qual(plan->qual, "Filter", planstate, ancestors, es); + if (plan->qual) + show_instrumentation_count("Rows Removed by Filter", 1, + planstate, es); + } + break; case T_ForeignScan: show_scan_qual(plan->qual, "Filter", planstate, ancestors, es); if (plan->qual) @@ -2659,6 +2701,10 @@ ExplainNode(PlanState *planstate, List *ancestors, case T_Append: show_join_pruning_info(((Append *) plan)->join_prune_paramids, es); break; + case T_ResultCache: + show_resultcache_info(castNode(ResultCacheState, planstate), + ancestors, es); + break; default: break; } @@ -2689,7 +2735,7 @@ ExplainNode(PlanState *planstate, List *ancestors, /* Show buffer/WAL usage */ if (es->buffers && planstate->instrument) - show_buffer_usage(es, &planstate->instrument->bufusage); + show_buffer_usage(es, &planstate->instrument->bufusage, false); if (es->wal && planstate->instrument) show_wal_usage(es, &planstate->instrument->walusage); @@ -2708,7 +2754,7 @@ ExplainNode(PlanState *planstate, List *ancestors, ExplainOpenWorker(n, es); if (es->buffers) - show_buffer_usage(es, &instrument->bufusage); + show_buffer_usage(es, &instrument->bufusage, false); if (es->wal) show_wal_usage(es, &instrument->walusage); ExplainCloseWorker(n, es); @@ -2748,7 +2794,6 @@ ExplainNode(PlanState *planstate, List *ancestors, haschildren = planstate->initPlan || outerPlanState(planstate) || innerPlanState(planstate) || - IsA(plan, ModifyTable) || IsA(plan, Append) || IsA(plan, MergeAppend) || IsA(plan, Sequence) || @@ -2791,11 +2836,6 @@ ExplainNode(PlanState *planstate, List *ancestors, /* special child plans */ switch (nodeTag(plan)) { - case T_ModifyTable: - ExplainMemberNodes(((ModifyTableState *) planstate)->mt_plans, - ((ModifyTableState *) planstate)->mt_nplans, - ancestors, es); - break; case T_Append: ExplainMemberNodes(((AppendState *) planstate)->appendplans, ((AppendState *) planstate)->as_nplans, @@ -3605,14 +3645,14 @@ show_incremental_sort_group_info(IncrementalSortGroupInfo *groupInfo, groupInfo->groupCount); /* plural/singular based on methodNames size */ if (list_length(methodNames) > 1) - appendStringInfo(es->str, "s: "); + appendStringInfoString(es->str, "s: "); else - appendStringInfo(es->str, ": "); + appendStringInfoString(es->str, ": "); foreach(methodCell, methodNames) { - appendStringInfo(es->str, "%s", (char *) methodCell->ptr_value); + appendStringInfoString(es->str, (char *) methodCell->ptr_value); if (foreach_current_index(methodCell) < list_length(methodNames) - 1) - appendStringInfo(es->str, ", "); + appendStringInfoString(es->str, ", "); } if (groupInfo->maxMemorySpaceUsed > 0) @@ -3664,7 +3704,7 @@ show_incremental_sort_group_info(IncrementalSortGroupInfo *groupInfo, ExplainPropertyInteger("Peak Sort Space Used", "kB", groupInfo->maxMemorySpaceUsed, es); - ExplainCloseGroup("Sort Spaces", memoryName.data, true, es); + ExplainCloseGroup("Sort Space", memoryName.data, true, es); } if (groupInfo->maxDiskSpaceUsed > 0) { @@ -3681,7 +3721,7 @@ show_incremental_sort_group_info(IncrementalSortGroupInfo *groupInfo, ExplainPropertyInteger("Peak Sort Space Used", "kB", groupInfo->maxDiskSpaceUsed, es); - ExplainCloseGroup("Sort Spaces", diskName.data, true, es); + ExplainCloseGroup("Sort Space", diskName.data, true, es); } ExplainCloseGroup("Incremental Sort Groups", groupName.data, true, es); @@ -3719,11 +3759,11 @@ show_incremental_sort_info(IncrementalSortState *incrsortstate, if (prefixsortGroupInfo->groupCount > 0) { if (es->format == EXPLAIN_FORMAT_TEXT) - appendStringInfo(es->str, "\n"); + appendStringInfoChar(es->str, '\n'); show_incremental_sort_group_info(prefixsortGroupInfo, "Pre-sorted", true, es); } if (es->format == EXPLAIN_FORMAT_TEXT) - appendStringInfo(es->str, "\n"); + appendStringInfoChar(es->str, '\n'); } if (incrsortstate->shared_info != NULL) @@ -3762,11 +3802,11 @@ show_incremental_sort_info(IncrementalSortState *incrsortstate, if (prefixsortGroupInfo->groupCount > 0) { if (es->format == EXPLAIN_FORMAT_TEXT) - appendStringInfo(es->str, "\n"); + appendStringInfoChar(es->str, '\n'); show_incremental_sort_group_info(prefixsortGroupInfo, "Pre-sorted", true, es); } if (es->format == EXPLAIN_FORMAT_TEXT) - appendStringInfo(es->str, "\n"); + appendStringInfoChar(es->str, '\n'); if (es->workers_state) ExplainCloseWorker(n, es); @@ -3865,6 +3905,148 @@ show_hash_info(HashState *hashstate, ExplainState *es) } } +/* + * Show information on result cache hits/misses/evictions and memory usage. + */ +static void +show_resultcache_info(ResultCacheState *rcstate, List *ancestors, + ExplainState *es) +{ + Plan *plan = ((PlanState *) rcstate)->plan; + ListCell *lc; + List *context; + StringInfoData keystr; + char *seperator = ""; + bool useprefix; + int64 memPeakKb; + + initStringInfo(&keystr); + + /* + * It's hard to imagine having a result cache with fewer than 2 RTEs, but + * let's just keep the same useprefix logic as elsewhere in this file. + */ + useprefix = list_length(es->rtable) > 1 || es->verbose; + + /* Set up deparsing context */ + context = set_deparse_context_plan(es->deparse_cxt, + plan, + ancestors); + + foreach(lc, ((ResultCache *) plan)->param_exprs) + { + Node *expr = (Node *) lfirst(lc); + + appendStringInfoString(&keystr, seperator); + + appendStringInfoString(&keystr, deparse_expression(expr, context, + useprefix, false)); + seperator = ", "; + } + + if (es->format != EXPLAIN_FORMAT_TEXT) + { + ExplainPropertyText("Cache Key", keystr.data, es); + } + else + { + ExplainIndentText(es); + appendStringInfo(es->str, "Cache Key: %s\n", keystr.data); + } + + pfree(keystr.data); + + if (!es->analyze) + return; + + if (rcstate->stats.cache_misses > 0) + { + /* + * mem_peak is only set when we freed memory, so we must use mem_used + * when mem_peak is 0. + */ + if (rcstate->stats.mem_peak > 0) + memPeakKb = (rcstate->stats.mem_peak + 1023) / 1024; + else + memPeakKb = (rcstate->mem_used + 1023) / 1024; + + if (es->format != EXPLAIN_FORMAT_TEXT) + { + ExplainPropertyInteger("Cache Hits", NULL, rcstate->stats.cache_hits, es); + ExplainPropertyInteger("Cache Misses", NULL, rcstate->stats.cache_misses, es); + ExplainPropertyInteger("Cache Evictions", NULL, rcstate->stats.cache_evictions, es); + ExplainPropertyInteger("Cache Overflows", NULL, rcstate->stats.cache_overflows, es); + ExplainPropertyInteger("Peak Memory Usage", "kB", memPeakKb, es); + } + else + { + ExplainIndentText(es); + appendStringInfo(es->str, + "Hits: " UINT64_FORMAT " Misses: " UINT64_FORMAT " Evictions: " UINT64_FORMAT " Overflows: " UINT64_FORMAT " Memory Usage: " INT64_FORMAT "kB\n", + rcstate->stats.cache_hits, + rcstate->stats.cache_misses, + rcstate->stats.cache_evictions, + rcstate->stats.cache_overflows, + memPeakKb); + } + } + + if (rcstate->shared_info == NULL) + return; + + /* Show details from parallel workers */ + for (int n = 0; n < rcstate->shared_info->num_workers; n++) + { + ResultCacheInstrumentation *si; + + si = &rcstate->shared_info->sinstrument[n]; + + /* + * Skip workers that didn't do any work. We needn't bother checking + * for cache hits as a miss will always occur before a cache hit. + */ + if (si->cache_misses == 0) + continue; + + if (es->workers_state) + ExplainOpenWorker(n, es); + + /* + * Since the worker's ResultCacheState.mem_used field is unavailable + * to us, ExecEndResultCache will have set the + * ResultCacheInstrumentation.mem_peak field for us. No need to do + * the zero checks like we did for the serial case above. + */ + memPeakKb = (si->mem_peak + 1023) / 1024; + + if (es->format == EXPLAIN_FORMAT_TEXT) + { + ExplainIndentText(es); + appendStringInfo(es->str, + "Hits: " UINT64_FORMAT " Misses: " UINT64_FORMAT " Evictions: " UINT64_FORMAT " Overflows: " UINT64_FORMAT " Memory Usage: " INT64_FORMAT "kB\n", + si->cache_hits, si->cache_misses, + si->cache_evictions, si->cache_overflows, + memPeakKb); + } + else + { + ExplainPropertyInteger("Cache Hits", NULL, + si->cache_hits, es); + ExplainPropertyInteger("Cache Misses", NULL, + si->cache_misses, es); + ExplainPropertyInteger("Cache Evictions", NULL, + si->cache_evictions, es); + ExplainPropertyInteger("Cache Overflows", NULL, + si->cache_overflows, es); + ExplainPropertyInteger("Peak Memory Usage", "kB", memPeakKb, + es); + } + + if (es->workers_state) + ExplainCloseWorker(n, es); + } +} + /* * Show information on hash aggregate memory usage and batches. */ @@ -3931,7 +4113,7 @@ show_hashagg_info(AggState *aggstate, ExplainState *es) if (aggstate->hash_batches_used > 1) { appendStringInfo(es->str, " Disk Usage: " UINT64_FORMAT "kB", - aggstate->hash_disk_used); + aggstate->hash_disk_used); } } @@ -4144,7 +4326,7 @@ explain_get_index_name(Oid indexId) * Show buffer usage details. */ static void -show_buffer_usage(ExplainState *es, const BufferUsage *usage) +show_buffer_usage(ExplainState *es, const BufferUsage *usage, bool planning) { if (es->format == EXPLAIN_FORMAT_TEXT) { @@ -4160,6 +4342,15 @@ show_buffer_usage(ExplainState *es, const BufferUsage *usage) usage->temp_blks_written > 0); bool has_timing = (!INSTR_TIME_IS_ZERO(usage->blk_read_time) || !INSTR_TIME_IS_ZERO(usage->blk_write_time)); + bool show_planning = (planning && (has_shared || + has_local || has_temp || has_timing)); + + if (show_planning) + { + ExplainIndentText(es); + appendStringInfoString(es->str, "Planning:\n"); + es->indent++; + } /* Show only positive counter values. */ if (has_shared || has_local || has_temp) @@ -4171,17 +4362,17 @@ show_buffer_usage(ExplainState *es, const BufferUsage *usage) { appendStringInfoString(es->str, " shared"); if (usage->shared_blks_hit > 0) - appendStringInfo(es->str, " hit=%ld", - usage->shared_blks_hit); + appendStringInfo(es->str, " hit=%lld", + (long long) usage->shared_blks_hit); if (usage->shared_blks_read > 0) - appendStringInfo(es->str, " read=%ld", - usage->shared_blks_read); + appendStringInfo(es->str, " read=%lld", + (long long) usage->shared_blks_read); if (usage->shared_blks_dirtied > 0) - appendStringInfo(es->str, " dirtied=%ld", - usage->shared_blks_dirtied); + appendStringInfo(es->str, " dirtied=%lld", + (long long) usage->shared_blks_dirtied); if (usage->shared_blks_written > 0) - appendStringInfo(es->str, " written=%ld", - usage->shared_blks_written); + appendStringInfo(es->str, " written=%lld", + (long long) usage->shared_blks_written); if (has_local || has_temp) appendStringInfoChar(es->str, ','); } @@ -4189,17 +4380,17 @@ show_buffer_usage(ExplainState *es, const BufferUsage *usage) { appendStringInfoString(es->str, " local"); if (usage->local_blks_hit > 0) - appendStringInfo(es->str, " hit=%ld", - usage->local_blks_hit); + appendStringInfo(es->str, " hit=%lld", + (long long) usage->local_blks_hit); if (usage->local_blks_read > 0) - appendStringInfo(es->str, " read=%ld", - usage->local_blks_read); + appendStringInfo(es->str, " read=%lld", + (long long) usage->local_blks_read); if (usage->local_blks_dirtied > 0) - appendStringInfo(es->str, " dirtied=%ld", - usage->local_blks_dirtied); + appendStringInfo(es->str, " dirtied=%lld", + (long long) usage->local_blks_dirtied); if (usage->local_blks_written > 0) - appendStringInfo(es->str, " written=%ld", - usage->local_blks_written); + appendStringInfo(es->str, " written=%lld", + (long long) usage->local_blks_written); if (has_temp) appendStringInfoChar(es->str, ','); } @@ -4207,11 +4398,11 @@ show_buffer_usage(ExplainState *es, const BufferUsage *usage) { appendStringInfoString(es->str, " temp"); if (usage->temp_blks_read > 0) - appendStringInfo(es->str, " read=%ld", - usage->temp_blks_read); + appendStringInfo(es->str, " read=%lld", + (long long) usage->temp_blks_read); if (usage->temp_blks_written > 0) - appendStringInfo(es->str, " written=%ld", - usage->temp_blks_written); + appendStringInfo(es->str, " written=%lld", + (long long) usage->temp_blks_written); } appendStringInfoChar(es->str, '\n'); } @@ -4229,6 +4420,9 @@ show_buffer_usage(ExplainState *es, const BufferUsage *usage) INSTR_TIME_GET_MILLISEC(usage->blk_write_time)); appendStringInfoChar(es->str, '\n'); } + + if (show_planning) + es->indent--; } else { @@ -4280,11 +4474,11 @@ show_wal_usage(ExplainState *es, const WalUsage *usage) appendStringInfoString(es->str, "WAL:"); if (usage->wal_records > 0) - appendStringInfo(es->str, " records=%ld", - usage->wal_records); + appendStringInfo(es->str, " records=%lld", + (long long) usage->wal_records); if (usage->wal_fpi > 0) - appendStringInfo(es->str, " fpi=%ld", - usage->wal_fpi); + appendStringInfo(es->str, " fpi=%lld", + (long long) usage->wal_fpi); if (usage->wal_bytes > 0) appendStringInfo(es->str, " bytes=" UINT64_FORMAT, usage->wal_bytes); @@ -4392,6 +4586,7 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es) case T_BitmapHeapScan: case T_DynamicBitmapHeapScan: case T_TidScan: + case T_TidRangeScan: case T_ForeignScan: case T_CustomScan: case T_ModifyTable: @@ -4564,14 +4759,14 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, } /* Should we explicitly label target relations? */ - labeltargets = (mtstate->mt_nplans > 1 || - (mtstate->mt_nplans == 1 && - mtstate->resultRelInfo->ri_RangeTableIndex != node->nominalRelation)); + labeltargets = (mtstate->mt_nrels > 1 || + (mtstate->mt_nrels == 1 && + mtstate->resultRelInfo[0].ri_RangeTableIndex != node->nominalRelation)); if (labeltargets) ExplainOpenGroup("Target Tables", "Target Tables", false, es); - for (j = 0; j < mtstate->mt_nplans; j++) + for (j = 0; j < mtstate->mt_nrels; j++) { ResultRelInfo *resultRelInfo = mtstate->resultRelInfo + j; FdwRoutine *fdwroutine = resultRelInfo->ri_FdwRoutine; @@ -4666,10 +4861,10 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, double insert_path; double other_path; - InstrEndLoop(mtstate->mt_plans[0]->instrument); + InstrEndLoop(outerPlanState(mtstate)->instrument); /* count the number of source rows */ - total = mtstate->mt_plans[0]->instrument->ntuples; + total = outerPlanState(mtstate)->instrument->ntuples; other_path = mtstate->ps.instrument->ntuples2; insert_path = total - other_path; @@ -4685,7 +4880,7 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, } /* - * Explain the constituent plans of a ModifyTable, Append, MergeAppend, + * Explain the constituent plans of an Append, MergeAppend, * BitmapAnd, or BitmapOr node. * * The ancestors list should already contain the immediate parent of these diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 8b785a06ee3d..0db2a8ae61b1 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -12,7 +12,7 @@ * postgresql.conf. An extension also has an installation script file, * containing SQL commands to create the extension's objects. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -688,7 +688,7 @@ read_extension_script_file(const ExtensionControlFile *control, src_encoding = control->encoding; /* make sure that source string is valid in the expected encoding */ - pg_verify_mbstr_len(src_encoding, src_str, len, false); + (void) pg_verify_mbstr(src_encoding, src_str, len, false); /* * Convert the encoding to the database encoding. read_whole_file @@ -792,6 +792,7 @@ execute_sql_string(const char *sql) ProcessUtility(stmt, sql, + false, PROCESS_UTILITY_QUERY, NULL, NULL, @@ -3491,8 +3492,8 @@ ExecAlterExtensionContentsStmt_internal(AlterExtensionContentsStmt *stmt, case OBJECT_SUBSCRIPTION: case OBJECT_TABLESPACE: ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot add an object of this type to an extension"))); + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot add an object of this type to an extension"))); break; default: /* OK */ diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 4c323dba3c1c..af98b7be1928 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -3,7 +3,7 @@ * foreigncmds.c * foreign-data wrapper/server creation/manipulation commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -1658,8 +1658,7 @@ ImportForeignSchema(ImportForeignSchemaStmt *stmt) pstmt->stmt_len = rs->stmt_len; /* Execute statement */ - ProcessUtility(pstmt, - cmd, + ProcessUtility(pstmt, cmd, false, PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, None_Receiver, NULL); diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index a0a168c64041..e7dab3824f39 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -5,7 +5,7 @@ * Routines for CREATE and DROP FUNCTION commands and CREATE and DROP * CAST commands. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -55,15 +55,19 @@ #include "commands/proclang.h" #include "executor/execdesc.h" #include "executor/executor.h" +#include "executor/functions.h" #include "funcapi.h" #include "miscadmin.h" #include "optimizer/optimizer.h" +#include "parser/analyze.h" #include "parser/parse_coerce.h" #include "parser/parse_collate.h" #include "parser/parse_expr.h" #include "parser/parse_func.h" #include "parser/parse_type.h" #include "pgstat.h" +#include "tcop/pquery.h" +#include "tcop/utility.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/faultinjector.h" @@ -186,16 +190,16 @@ compute_return_type(TypeName *returnType, Oid languageOid, } /* - * Interpret the function parameter list of a CREATE FUNCTION or - * CREATE AGGREGATE statement. + * Interpret the function parameter list of a CREATE FUNCTION, + * CREATE PROCEDURE, or CREATE AGGREGATE statement. * * Input parameters: * parameters: list of FunctionParameter structs * languageOid: OID of function language (InvalidOid if it's CREATE AGGREGATE) - * objtype: needed only to determine error handling and required result type + * objtype: identifies type of object being created * * Results are stored into output parameters. parameterTypes must always - * be created, but the other arrays are set to NULL if not needed. + * be created, but the other arrays/lists can be NULL pointers if not needed. * variadicArgType is set to the variadic array type if there's a VARIADIC * parameter (there can be only one); or to InvalidOid if not. * requiredResultType is set to InvalidOid if there are no OUT parameters, @@ -207,9 +211,11 @@ interpret_function_parameter_list(ParseState *pstate, Oid languageOid, ObjectType objtype, oidvector **parameterTypes, + List **parameterTypes_list, ArrayType **allParameterTypes, ArrayType **parameterModes, ArrayType **parameterNames, + List **inParameterNames_list, List **parameterDefaults, Oid *variadicArgType, Oid *requiredResultType) @@ -247,11 +253,16 @@ interpret_function_parameter_list(ParseState *pstate, { FunctionParameter *fp = (FunctionParameter *) lfirst(x); TypeName *t = fp->argType; + FunctionParameterMode fpmode = fp->mode; bool isinput = false; Oid toid; Type typtup; AclResult aclresult; + /* For our purposes here, a defaulted mode spec is identical to IN */ + if (fpmode == FUNC_PARAM_DEFAULT) + fpmode = FUNC_PARAM_IN; + typtup = LookupTypeName(NULL, t, NULL, false); if (typtup) { @@ -307,17 +318,8 @@ interpret_function_parameter_list(ParseState *pstate, errmsg("functions cannot accept set arguments"))); } - if (objtype == OBJECT_PROCEDURE) - { - if (fp->mode == FUNC_PARAM_OUT) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("procedures cannot have OUT arguments"), - errhint("INOUT arguments are permitted."))); - } - /* handle input parameters */ - if (fp->mode != FUNC_PARAM_OUT && fp->mode != FUNC_PARAM_TABLE) + if (fpmode != FUNC_PARAM_OUT && fpmode != FUNC_PARAM_TABLE) { /* other input parameters can't follow a VARIADIC parameter */ if (varCount > 0) @@ -330,10 +332,12 @@ interpret_function_parameter_list(ParseState *pstate, /* Keep track of the number of anytable arguments */ if (toid == ANYTABLEOID) multisetCount++; + if (parameterTypes_list) + *parameterTypes_list = lappend_oid(*parameterTypes_list, toid); } /* handle output parameters */ - if (fp->mode != FUNC_PARAM_IN && fp->mode != FUNC_PARAM_VARIADIC) + if (fpmode != FUNC_PARAM_IN && fpmode != FUNC_PARAM_VARIADIC) { if (toid == ANYTABLEOID) ereport(ERROR, @@ -341,13 +345,25 @@ interpret_function_parameter_list(ParseState *pstate, errmsg("functions cannot return \"anytable\" arguments"))); if (objtype == OBJECT_PROCEDURE) + { + /* + * We disallow OUT-after-VARIADIC only for procedures. While + * such a case causes no confusion in ordinary function calls, + * it would cause confusion in a CALL statement. + */ + if (varCount > 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("VARIADIC parameter must be the last parameter"))); + /* Procedures with output parameters always return RECORD */ *requiredResultType = RECORDOID; + } else if (outCount == 0) /* save first output param's type */ *requiredResultType = toid; outCount++; } - if (fp->mode == FUNC_PARAM_VARIADIC) + if (fpmode == FUNC_PARAM_VARIADIC) { *variadicArgType = toid; varCount++; @@ -372,7 +388,7 @@ interpret_function_parameter_list(ParseState *pstate, allTypes[i] = ObjectIdGetDatum(toid); - paramModes[i] = CharGetDatum(fp->mode); + paramModes[i] = CharGetDatum(fpmode); if (fp->name && fp->name[0]) { @@ -387,19 +403,24 @@ interpret_function_parameter_list(ParseState *pstate, foreach(px, parameters) { FunctionParameter *prevfp = (FunctionParameter *) lfirst(px); + FunctionParameterMode prevfpmode; if (prevfp == fp) break; + /* as above, default mode is IN */ + prevfpmode = prevfp->mode; + if (prevfpmode == FUNC_PARAM_DEFAULT) + prevfpmode = FUNC_PARAM_IN; /* pure in doesn't conflict with pure out */ - if ((fp->mode == FUNC_PARAM_IN || - fp->mode == FUNC_PARAM_VARIADIC) && - (prevfp->mode == FUNC_PARAM_OUT || - prevfp->mode == FUNC_PARAM_TABLE)) + if ((fpmode == FUNC_PARAM_IN || + fpmode == FUNC_PARAM_VARIADIC) && + (prevfpmode == FUNC_PARAM_OUT || + prevfpmode == FUNC_PARAM_TABLE)) continue; - if ((prevfp->mode == FUNC_PARAM_IN || - prevfp->mode == FUNC_PARAM_VARIADIC) && - (fp->mode == FUNC_PARAM_OUT || - fp->mode == FUNC_PARAM_TABLE)) + if ((prevfpmode == FUNC_PARAM_IN || + prevfpmode == FUNC_PARAM_VARIADIC) && + (fpmode == FUNC_PARAM_OUT || + fpmode == FUNC_PARAM_TABLE)) continue; if (prevfp->name && prevfp->name[0] && strcmp(prevfp->name, fp->name) == 0) @@ -413,6 +434,9 @@ interpret_function_parameter_list(ParseState *pstate, have_names = true; } + if (inParameterNames_list) + *inParameterNames_list = lappend(*inParameterNames_list, makeString(fp->name ? fp->name : pstrdup(""))); + if (fp->defexpr) { Node *def; @@ -465,6 +489,16 @@ interpret_function_parameter_list(ParseState *pstate, ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("input parameters after one with a default value must also have defaults"))); + + /* + * For procedures, we also can't allow OUT parameters after one + * with a default, because the same sort of confusion arises in a + * CALL statement. + */ + if (objtype == OBJECT_PROCEDURE && have_defaults) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("procedure OUT parameters cannot appear after one with a default value"))); } i++; @@ -983,28 +1017,10 @@ compute_function_attributes(ParseState *pstate, defel->defname); } - /* process required items */ if (as_item) *as = (List *) as_item->arg; - else - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("no function body specified"))); - *as = NIL; /* keep compiler quiet */ - } - if (language_item) *language = strVal(language_item->arg); - else - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("no language specified"))); - *language = NULL; /* keep compiler quiet */ - } - - /* process optional items */ if (transform_item) *transform = transform_item->arg; if (windowfunc_item) @@ -1059,10 +1075,28 @@ compute_function_attributes(ParseState *pstate, */ static void interpret_AS_clause(Oid languageOid, const char *languageName, - char *funcname, List *as, - char **prosrc_str_p, char **probin_str_p) + char *funcname, List *as, Node *sql_body_in, + List *parameterTypes, List *inParameterNames, + char **prosrc_str_p, char **probin_str_p, + Node **sql_body_out, + const char *queryString) { - Assert(as != NIL); + if (!sql_body_in && !as) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("no function body specified"))); + + if (sql_body_in && as) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("duplicate function body specified"))); + + if (sql_body_in && languageOid != SQLlanguageId) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("inline SQL function body only valid for language SQL"))); + + *sql_body_out = NULL; if (languageOid == ClanguageId) { @@ -1084,6 +1118,88 @@ interpret_AS_clause(Oid languageOid, const char *languageName, *prosrc_str_p = funcname; } } + else if (sql_body_in) + { + SQLFunctionParseInfoPtr pinfo; + + pinfo = (SQLFunctionParseInfoPtr) palloc0(sizeof(SQLFunctionParseInfo)); + + pinfo->fname = funcname; + pinfo->nargs = list_length(parameterTypes); + pinfo->argtypes = (Oid *) palloc(pinfo->nargs * sizeof(Oid)); + pinfo->argnames = (char **) palloc(pinfo->nargs * sizeof(char *)); + for (int i = 0; i < list_length(parameterTypes); i++) + { + char *s = strVal(list_nth(inParameterNames, i)); + + pinfo->argtypes[i] = list_nth_oid(parameterTypes, i); + if (IsPolymorphicType(pinfo->argtypes[i])) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("SQL function with unquoted function body cannot have polymorphic arguments"))); + + if (s[0] != '\0') + pinfo->argnames[i] = s; + else + pinfo->argnames[i] = NULL; + } + + if (IsA(sql_body_in, List)) + { + List *stmts = linitial_node(List, castNode(List, sql_body_in)); + ListCell *lc; + List *transformed_stmts = NIL; + + foreach(lc, stmts) + { + Node *stmt = lfirst(lc); + Query *q; + ParseState *pstate = make_parsestate(NULL); + + pstate->p_sourcetext = queryString; + sql_fn_parser_setup(pstate, pinfo); + q = transformStmt(pstate, stmt); + if (q->commandType == CMD_UTILITY) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("%s is not yet supported in unquoted SQL function body", + GetCommandTagName(CreateCommandTag(q->utilityStmt)))); + transformed_stmts = lappend(transformed_stmts, q); + free_parsestate(pstate); + } + + *sql_body_out = (Node *) list_make1(transformed_stmts); + } + else + { + Query *q; + ParseState *pstate = make_parsestate(NULL); + + pstate->p_sourcetext = queryString; + sql_fn_parser_setup(pstate, pinfo); + q = transformStmt(pstate, sql_body_in); + if (q->commandType == CMD_UTILITY) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("%s is not yet supported in unquoted SQL function body", + GetCommandTagName(CreateCommandTag(q->utilityStmt)))); + free_parsestate(pstate); + + *sql_body_out = (Node *) q; + } + + /* + * We must put something in prosrc. For the moment, just record an + * empty string. It might be useful to store the original text of the + * CREATE FUNCTION statement --- but to make actual use of that in + * error reports, we'd also have to adjust readfuncs.c to not throw + * away node location fields when reading prosqlbody. + */ + *prosrc_str_p = pstrdup(""); + + /* But we definitely don't need probin. */ + *probin_str_p = NULL; + } else { /* Everything else wants the given string in prosrc. */ @@ -1200,10 +1316,11 @@ validate_describe_callback(List *describeQualName, fdResult = func_get_detail(describeQualName, NIL, /* argument expressions */ NIL, /* argument names */ - nargs, + nargs, inputTypeOids, false, /* expand_variadic */ false, /* expand_defaults */ + false, /* include_out_arguments */ &describeFuncOid, &describeReturnTypeOid, &describeReturnsSet, @@ -1257,8 +1374,19 @@ validate_describe_callback(List *describeQualName, ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) { + /* + * GPDB: parse analysis of a SQL-standard body (BEGIN ATOMIC / RETURN) + * below scribbles on stmt->sql_body (transformStmt is destructive on + * raw trees: e.g. a SubLink's subselect is replaced by the transformed + * Query, which a QE's own parse analysis then rejects with "unexpected + * non-SELECT command in SubLink"). Snapshot the statement now and + * dispatch the pristine copy. + */ + CreateFunctionStmt *dispatchStmt = (Gp_role == GP_ROLE_DISPATCH) ? + copyObject(stmt) : NULL; char *probin_str; char *prosrc_str; + Node *prosqlbody; Oid prorettype; bool returnsSet; char *language; @@ -1269,9 +1397,11 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) Oid namespaceId; AclResult aclresult; oidvector *parameterTypes; + List *parameterTypes_list = NIL; ArrayType *allParameterTypes; ArrayType *parameterModes; ArrayType *parameterNames; + List *inParameterNames_list = NIL; List *parameterDefaults; Oid variadicArgType; List *trftypes_list = NIL; @@ -1308,6 +1438,8 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) get_namespace_name(namespaceId)); /* Set default attributes */ + as_clause = NIL; + language = NULL; isWindowFunc = false; isStrict = false; security = false; @@ -1333,6 +1465,16 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) &describeQualName, &dataAccess, &execLocation); + if (!language) + { + if (stmt->sql_body) + language = "sql"; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("no language specified"))); + } + /* Look up the language and validate permissions */ languageTuple = SearchSysCache1(LANGNAME, PointerGetDatum(language)); if (!HeapTupleIsValid(languageTuple)) @@ -1384,7 +1526,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) /* * Only superuser is allowed to create leakproof functions because * leakproof functions can see tuples which have not yet been filtered out - * by security barrier views or row level security policies. + * by security barrier views or row-level security policies. */ if (isLeakProof && !superuser()) ereport(ERROR, @@ -1417,9 +1559,11 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) languageOid, stmt->is_procedure ? OBJECT_PROCEDURE : OBJECT_FUNCTION, ¶meterTypes, + ¶meterTypes_list, &allParameterTypes, ¶meterModes, ¶meterNames, + &inParameterNames_list, ¶meterDefaults, &variadicArgType, &requiredResultType); @@ -1478,15 +1622,17 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) trftypes = NULL; } - interpret_AS_clause(languageOid, language, funcname, as_clause, - &prosrc_str, &probin_str); - - /* double check that we really have a function body */ - /* prosrc_str doesn't point to a palloc()'d string in interpret_AS_clause() */ - if (prosrc_str == NULL) - prosrc_str = ""; + interpret_AS_clause(languageOid, language, funcname, as_clause, stmt->sql_body, + parameterTypes_list, inParameterNames_list, + &prosrc_str, &probin_str, &prosqlbody, + pstate->p_sourcetext); - /* Handle the describe callback, if any */ + /* + * GPDB: handle the WITH (describe = ...) callback, if any. The PG14 + * merge kept the option parsing and the pg_proc_callback machinery but + * lost this call, so the callback was silently never registered and + * dynamically-typed table functions demanded explicit column lists. + */ if (describeQualName != NIL) describeFuncOid = validate_describe_callback(describeQualName, prorettype, @@ -1533,6 +1679,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) describeFuncOid, prosrc_str, /* converted to text later */ probin_str, /* converted to text later */ + prosqlbody, stmt->is_procedure ? PROKIND_PROCEDURE : (isWindowFunc ? PROKIND_WINDOW : PROKIND_FUNCTION), security, isLeakProof, @@ -1554,7 +1701,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) if (Gp_role == GP_ROLE_DISPATCH) { - CdbDispatchUtilityStatement((Node *) stmt, + CdbDispatchUtilityStatement((Node *) dispatchStmt, DF_CANCEL_ON_ERROR| DF_WITH_SNAPSHOT| DF_NEED_TWO_PHASE, @@ -2094,6 +2241,7 @@ CreateCast(CreateCastStmt *stmt) case COERCION_ASSIGNMENT: castcontext = COERCION_CODE_ASSIGNMENT; break; + /* COERCION_PLPGSQL is intentionally not covered here */ case COERCION_EXPLICIT: castcontext = COERCION_CODE_EXPLICIT; break; @@ -2169,6 +2317,7 @@ CreateTransform(CreateTransformStmt *stmt) Relation relation; ObjectAddress myself, referenced; + ObjectAddresses *addrs; bool is_replace; /* @@ -2310,39 +2459,34 @@ CreateTransform(CreateTransformStmt *stmt) if (is_replace) deleteDependencyRecordsFor(TransformRelationId, transformid, true); + addrs = new_object_addresses(); + /* make dependency entries */ - myself.classId = TransformRelationId; - myself.objectId = transformid; - myself.objectSubId = 0; + ObjectAddressSet(myself, TransformRelationId, transformid); /* dependency on language */ - referenced.classId = LanguageRelationId; - referenced.objectId = langid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, LanguageRelationId, langid); + add_exact_object_address(&referenced, addrs); /* dependency on type */ - referenced.classId = TypeRelationId; - referenced.objectId = typeid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, TypeRelationId, typeid); + add_exact_object_address(&referenced, addrs); /* dependencies on functions */ if (OidIsValid(fromsqlfuncid)) { - referenced.classId = ProcedureRelationId; - referenced.objectId = fromsqlfuncid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, ProcedureRelationId, fromsqlfuncid); + add_exact_object_address(&referenced, addrs); } if (OidIsValid(tosqlfuncid)) { - referenced.classId = ProcedureRelationId; - referenced.objectId = tosqlfuncid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, ProcedureRelationId, tosqlfuncid); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, is_replace); @@ -2624,27 +2768,10 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver if (((Form_pg_proc) GETSTRUCT(tp))->prosecdef) callcontext->atomic = true; - /* - * Expand named arguments, defaults, etc. We do not want to scribble on - * the passed-in CallStmt parse tree, so first flat-copy fexpr, allowing - * us to replace its args field. (Note that expand_function_arguments - * will not modify any of the passed-in data structure.) - */ - { - FuncExpr *nexpr = makeNode(FuncExpr); - - memcpy(nexpr, fexpr, sizeof(FuncExpr)); - fexpr = nexpr; - } - - fexpr->args = expand_function_arguments(fexpr->args, - fexpr->funcresulttype, - tp); - nargs = list_length(fexpr->args); - ReleaseSysCache(tp); /* safety check; see ExecInitFunc() */ + nargs = list_length(fexpr->args); if (nargs > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), @@ -2710,6 +2837,20 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver if (fcinfo->isnull) elog(ERROR, "procedure returned null record"); + /* + * Ensure there's an active snapshot whilst we execute whatever's + * involved here. Note that this is *not* sufficient to make the + * world safe for TOAST pointers to be included in the returned data: + * the referenced data could have gone away while we didn't hold a + * snapshot. Hence, it's incumbent on PLs that can do COMMIT/ROLLBACK + * to not return TOAST pointers, unless those pointers were fetched + * after the last COMMIT/ROLLBACK in the procedure. + * + * XXX that is a really nasty, hard-to-test requirement. Is there a + * way to remove it? + */ + EnsurePortalSnapshotExists(); + td = DatumGetHeapTupleHeader(retval); tupType = HeapTupleHeaderGetTypeId(td); tupTypmod = HeapTupleHeaderGetTypMod(td); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index d5f064fb1e7f..c22fa0d82a00 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -83,6 +83,7 @@ #include "utils/faultinjector.h" /* non-export function prototypes */ +static bool CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts); static void CheckPredicate(Expr *predicate); static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *typeOidP, @@ -96,22 +97,31 @@ static void ComputeIndexAttrs(IndexInfo *indexInfo, bool amcanorder, bool isconstraint); static char *ChooseIndexNameAddition(List *colnames); +List *ChooseIndexColumnNames(List *indexElems); +static void ReindexIndex(ReindexStmt *stmt, ReindexParams *params, + bool isTopLevel); static void RangeVarCallbackForReindexIndex(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg); -static bool ReindexRelationConcurrently(Oid relationOid, int options); - -static void ReindexPartitions(Oid relid, int options, bool concurrent, bool isTopLevel); -static void ReindexMultipleInternal(List *relids, int options, bool concurrent); +static Oid ReindexTable(ReindexStmt *stmt, ReindexParams *params, + bool isTopLevel); +static void ReindexMultipleTables(const char *objectName, + ReindexObjectType objectKind, ReindexParams *params); static void reindex_error_callback(void *args); +static void ReindexPartitions(Oid relid, ReindexParams *params, + bool isTopLevel); +static void ReindexMultipleInternal(List *relids, + ReindexParams *params); +static bool ReindexRelationConcurrently(Oid relationOid, + ReindexParams *params); static void update_relispartition(Oid relationId, bool newval); -static bool CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts); +static inline void set_indexsafe_procflags(void); /* * callback argument type for RangeVarCallbackForReindexIndex() */ struct ReindexIndexCallbackState { - bool concurrent; /* flag from statement */ + ReindexParams params; /* options from statement */ Oid locked_table_oid; /* tracks previously locked table */ }; @@ -483,7 +493,10 @@ CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts) * lazy VACUUMs, because they won't be fazed by missing index entries * either. (Manual ANALYZEs, however, can't be excluded because they * might be within transactions that are going to do arbitrary operations - * later.) + * later.) Processes running CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY + * on indexes that are neither expressional nor partial are also safe to + * ignore, since we know that those processes won't examine any data + * outside the table they're indexing. * * Also, GetCurrentVirtualXIDs never reports our own vxid, so we need not * check for that. @@ -496,7 +509,7 @@ CompareOpclassOptions(Datum *opts1, Datum *opts2, int natts) * GetCurrentVirtualXIDs. If, during any iteration, a particular vxid * doesn't show up in the output, we know we can forget about it. */ -static void +void WaitForOlderSnapshots(TransactionId limitXmin, bool progress) { int n_old_snapshots; @@ -504,7 +517,8 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress) VirtualTransactionId *old_snapshots; old_snapshots = GetCurrentVirtualXIDs(limitXmin, true, false, - PROC_IS_AUTOVACUUM | PROC_IN_VACUUM, + PROC_IS_AUTOVACUUM | PROC_IN_VACUUM + | PROC_IN_SAFE_IC, &n_old_snapshots); if (progress) pgstat_progress_update_param(PROGRESS_WAITFOR_TOTAL, n_old_snapshots); @@ -524,7 +538,8 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress) newer_snapshots = GetCurrentVirtualXIDs(limitXmin, true, false, - PROC_IS_AUTOVACUUM | PROC_IN_VACUUM, + PROC_IS_AUTOVACUUM | PROC_IN_VACUUM + | PROC_IN_SAFE_IC, &n_newer_snapshots); for (j = i; j < n_old_snapshots; j++) { @@ -621,6 +636,7 @@ DefineIndex(Oid relationId, bool amcanorder; amoptions_function amoptions; bool partitioned; + bool safe_index; Datum reloptions; int16 *coloptions; IndexInfo *indexInfo; @@ -722,7 +738,7 @@ DefineIndex(Oid relationId, stmt->indexIncludingParams); numberOfAttributes = list_length(allIndexParams); - if (numberOfAttributes <= 0) + if (numberOfKeyAttributes <= 0) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("must specify at least one column"))); @@ -995,7 +1011,7 @@ DefineIndex(Oid relationId, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support included columns", accessMethodName))); - if (numberOfAttributes > 1 && !amRoutine->amcanmulticol) + if (numberOfKeyAttributes > 1 && !amRoutine->amcanmulticol) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support multicolumn indexes", @@ -1234,8 +1250,7 @@ DefineIndex(Oid relationId, key->partattrs[i] - 1); ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("insufficient columns in %s constraint definition", - constraint_type), + errmsg("unique constraint on partitioned table must include all partitioning columns"), errdetail("%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key.", constraint_type, RelationGetRelationName(rel), NameStr(att->attname)))); @@ -1280,6 +1295,10 @@ DefineIndex(Oid relationId, } } + /* Is index safe for others to ignore? See set_indexsafe_procflags() */ + safe_index = indexInfo->ii_Expressions == NIL && + indexInfo->ii_Predicate == NIL; + /* * Report index creation if appropriate (delay this till after most of the * error checks) @@ -1301,10 +1320,10 @@ DefineIndex(Oid relationId, } ereport(DEBUG1, - (errmsg("%s %s will create implicit index \"%s\" for table \"%s\"", - is_alter_table ? "ALTER TABLE / ADD" : "CREATE TABLE /", - constraint_type, - indexRelationName, RelationGetRelationName(rel)))); + (errmsg_internal("%s %s will create implicit index \"%s\" for table \"%s\"", + is_alter_table ? "ALTER TABLE / ADD" : "CREATE TABLE /", + constraint_type, + indexRelationName, RelationGetRelationName(rel)))); } if (shouldDispatch) @@ -1358,7 +1377,7 @@ DefineIndex(Oid relationId, */ if (partitioned && stmt->relation && !stmt->relation->inh) { - PartitionDesc pd = RelationGetPartitionDesc(rel); + PartitionDesc pd = RelationGetPartitionDesc(rel, true); if (pd->nparts != 0) flags |= INDEX_CREATE_INVALID; @@ -1418,15 +1437,17 @@ DefineIndex(Oid relationId, if (partitioned) { + PartitionDesc partdesc; + /* * Unless caller specified to skip this step (via ONLY), process each * partition to make sure they all contain a corresponding index. * * If we're called internally (no stmt->relation), recurse always. */ - if (!stmt->relation || stmt->relation->inh) + partdesc = RelationGetPartitionDesc(rel, true); + if ((!stmt->relation || stmt->relation->inh) && partdesc->nparts > 0) { - PartitionDesc partdesc = RelationGetPartitionDesc(rel); int nparts = partdesc->nparts; Oid *part_oids = palloc(sizeof(Oid) * nparts); bool invalidate_parent = false; @@ -1743,11 +1764,26 @@ DefineIndex(Oid relationId, StartTransactionCommand(); + /* Tell concurrent index builds to ignore us, if index qualifies */ + if (safe_index) + set_indexsafe_procflags(); + /* - * The index is now visible, so we can report the OID. + * The index is now visible, so we can report the OID. While on it, + * include the report for the beginning of phase 2. */ - pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, - indexRelationId); + { + const int progress_cols[] = { + PROGRESS_CREATEIDX_INDEX_OID, + PROGRESS_CREATEIDX_PHASE + }; + const int64 progress_vals[] = { + indexRelationId, + PROGRESS_CREATEIDX_PHASE_WAIT_1 + }; + + pgstat_progress_update_multi_param(2, progress_cols, progress_vals); + } /* * Phase 2 of concurrent index build (see comments for validate_index() @@ -1765,8 +1801,6 @@ DefineIndex(Oid relationId, * exclusive lock on our table. The lock code will detect deadlock and * error out properly. */ - pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, - PROGRESS_CREATEIDX_PHASE_WAIT_1); WaitForLockers(heaplocktag, ShareLock, true); /* @@ -1802,6 +1836,10 @@ DefineIndex(Oid relationId, CommitTransactionCommand(); StartTransactionCommand(); + /* Tell concurrent index builds to ignore us, if index qualifies */ + if (safe_index) + set_indexsafe_procflags(); + /* * Phase 3 of concurrent index build * @@ -1858,6 +1896,10 @@ DefineIndex(Oid relationId, CommitTransactionCommand(); StartTransactionCommand(); + /* Tell concurrent index builds to ignore us, if index qualifies */ + if (safe_index) + set_indexsafe_procflags(); + /* We should now definitely not be advertising any xmin. */ Assert(MyProc->xmin == InvalidTransactionId); @@ -2754,16 +2796,113 @@ ChooseIndexColumnNames(List *indexElems) return result; } +/* + * ExecReindex + * + * Primary entry point for manual REINDEX commands. This is mainly a + * preparation wrapper for the real operations that will happen in + * each subroutine of REINDEX. + */ +void +ExecReindex(ParseState *pstate, ReindexStmt *stmt, bool isTopLevel) +{ + ReindexParams params = {0}; + ListCell *lc; + bool concurrently = false; + bool verbose = false; + char *tablespacename = NULL; + + /* Parse option list */ + foreach(lc, stmt->params) + { + DefElem *opt = (DefElem *) lfirst(lc); + + if (strcmp(opt->defname, "verbose") == 0) + verbose = defGetBoolean(opt); + else if (strcmp(opt->defname, "concurrently") == 0) + concurrently = defGetBoolean(opt); + else if (strcmp(opt->defname, "tablespace") == 0) + tablespacename = defGetString(opt); + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized REINDEX option \"%s\"", + opt->defname), + parser_errposition(pstate, opt->location))); + } + + if (concurrently) + PreventInTransactionBlock(isTopLevel, + "REINDEX CONCURRENTLY"); + + params.options = + (verbose ? REINDEXOPT_VERBOSE : 0) | + (concurrently ? REINDEXOPT_CONCURRENTLY : 0); + + /* + * Assign the tablespace OID to move indexes to, with InvalidOid to do + * nothing. + */ + if (tablespacename != NULL) + { + params.tablespaceOid = get_tablespace_oid(tablespacename, false); + + /* Check permissions except when moving to database's default */ + if (OidIsValid(params.tablespaceOid) && + params.tablespaceOid != MyDatabaseTableSpace) + { + AclResult aclresult; + + aclresult = pg_tablespace_aclcheck(params.tablespaceOid, + GetUserId(), ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_TABLESPACE, + get_tablespace_name(params.tablespaceOid)); + } + } + else + params.tablespaceOid = InvalidOid; + + switch (stmt->kind) + { + case REINDEX_OBJECT_INDEX: + ReindexIndex(stmt, ¶ms, isTopLevel); + break; + case REINDEX_OBJECT_TABLE: + ReindexTable(stmt, ¶ms, isTopLevel); + break; + case REINDEX_OBJECT_SCHEMA: + case REINDEX_OBJECT_SYSTEM: + case REINDEX_OBJECT_DATABASE: + + /* + * This cannot run inside a user transaction block; if we were + * inside a transaction, then its commit- and + * start-transaction-command calls would not have the intended + * effect! + */ + PreventInTransactionBlock(isTopLevel, + (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" : + (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" : + "REINDEX DATABASE"); + ReindexMultipleTables(stmt->name, stmt->kind, ¶ms); + break; + default: + elog(ERROR, "unrecognized object type: %d", + (int) stmt->kind); + break; + } +} + /* * ReindexIndex * Recreate a specific index. */ -void -ReindexIndex(ReindexStmt *stmt, bool isTopLevel) +static void +ReindexIndex(ReindexStmt *stmt, ReindexParams *params, bool isTopLevel) { RangeVar *indexRelation = stmt->relation; - int options = stmt->options; - bool concurrent = stmt->concurrent; + bool concurrent = (params->options & REINDEXOPT_CONCURRENTLY) != 0; struct ReindexIndexCallbackState state; Oid indOid; char persistence; @@ -2783,7 +2922,7 @@ ReindexIndex(ReindexStmt *stmt, bool isTopLevel) Assert(get_rel_relkind(stmt->relid) == RELKIND_INDEX); - reindex_index(stmt->relid, false, persistence, options); + reindex_index(stmt->relid, false, persistence, params); return; } @@ -2797,10 +2936,11 @@ ReindexIndex(ReindexStmt *stmt, bool isTopLevel) * upgrade the lock, but that's OK, because other sessions can't hold * locks on our temporary table. */ - state.concurrent = concurrent; + state.params = *params; state.locked_table_oid = InvalidOid; indOid = RangeVarGetRelidExtended(indexRelation, - concurrent ? ShareUpdateExclusiveLock : AccessExclusiveLock, + (params->options & REINDEXOPT_CONCURRENTLY) != 0 ? + ShareUpdateExclusiveLock : AccessExclusiveLock, 0, RangeVarCallbackForReindexIndex, &state); @@ -2813,15 +2953,6 @@ ReindexIndex(ReindexStmt *stmt, bool isTopLevel) relkind = get_rel_relkind(indOid); - if (relkind == RELKIND_PARTITIONED_INDEX) - ReindexPartitions(indOid, options, concurrent, isTopLevel); - else if (concurrent && - persistence != RELPERSISTENCE_TEMP) - ReindexRelationConcurrently(indOid, options); - else - reindex_index(indOid, false, persistence, - options | REINDEXOPT_REPORT_PROGRESS); - /* * Reindex on partitioned index will do the reindex for each index in * it's own transaction, so dispatch the statement under ReindexPartitions. @@ -2833,8 +2964,6 @@ ReindexIndex(ReindexStmt *stmt, bool isTopLevel) qestmt = makeNode(ReindexStmt); qestmt->kind = REINDEX_OBJECT_INDEX; qestmt->relation = NULL; - qestmt->options = options; - qestmt->concurrent = concurrent; qestmt->relid = indOid; CdbDispatchUtilityStatement((Node *) qestmt, @@ -2843,6 +2972,43 @@ ReindexIndex(ReindexStmt *stmt, bool isTopLevel) GetAssignedOidsForDispatch(), NULL); } + + /* + * GPDB: REINDEX CONCURRENTLY is not supported on the coordinator -- the + * rebuilt index gets a new OID on the QD while the segments keep the + * original OID, corrupting the catalog (and the transient OIDs aren't + * dispatched). Fall back to a normal reindex with a NOTICE; a partitioned + * index then reindexes each child non-concurrently via ReindexPartitions. + * Single-node utility mode keeps the working concurrent path. + */ + if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && + Gp_role == GP_ROLE_DISPATCH && + persistence != RELPERSISTENCE_TEMP) + { + /* keep upstream's refusal for system catalogs */ + if (IsCatalogRelationOid(IndexGetRelation(indOid, false))) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex system catalogs concurrently"))); + + ereport(NOTICE, + (errmsg("concurrent reindex of \"%s\" is not supported in Greenplum, reindexing non-concurrently instead", + get_rel_name(indOid)))); + params->options &= ~REINDEXOPT_CONCURRENTLY; + } + + if (relkind == RELKIND_PARTITIONED_INDEX) + ReindexPartitions(indOid, params, isTopLevel); + else if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && + persistence != RELPERSISTENCE_TEMP) + ReindexRelationConcurrently(indOid, params); + else + { + ReindexParams newparams = *params; + + newparams.options |= REINDEXOPT_REPORT_PROGRESS; + reindex_index(indOid, false, persistence, &newparams); + } } /* @@ -2863,7 +3029,8 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, * non-concurrent case and table locks used by index_concurrently_*() for * concurrent case. */ - table_lockmode = state->concurrent ? ShareUpdateExclusiveLock : ShareLock; + table_lockmode = (state->params.options & REINDEXOPT_CONCURRENTLY) != 0 ? + ShareUpdateExclusiveLock : ShareLock; /* * If we previously locked some other index's heap, and the name we're @@ -2919,12 +3086,11 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, * ReindexTable * Recreate all indexes of a table (and of its toast table, if any) */ -Oid -ReindexTable(ReindexStmt *stmt, bool isTopLevel) +static Oid +ReindexTable(ReindexStmt *stmt, ReindexParams *params, bool isTopLevel) { RangeVar *relation = stmt->relation; - int options = stmt->options; - bool concurrent = stmt->concurrent; + bool concurrent = (params->options & REINDEXOPT_CONCURRENTLY) != 0; Oid heapOid; bool result; @@ -2938,7 +3104,7 @@ ReindexTable(ReindexStmt *stmt, bool isTopLevel) reindex_relation(stmt->relid, REINDEX_REL_PROCESS_TOAST | REINDEX_REL_CHECK_CONSTRAINTS, - options); + params); return stmt->relid; } @@ -2951,16 +3117,42 @@ ReindexTable(ReindexStmt *stmt, bool isTopLevel) * locks on our temporary table. */ heapOid = RangeVarGetRelidExtended(relation, - concurrent ? ShareUpdateExclusiveLock : ShareLock, + (params->options & REINDEXOPT_CONCURRENTLY) != 0 ? + ShareUpdateExclusiveLock : ShareLock, 0, RangeVarCallbackOwnsTable, NULL); + /* + * GPDB: REINDEX CONCURRENTLY is not supported on the coordinator -- + * ReindexRelationConcurrently() rebuilds each index under a new OID on the + * QD while the segments keep the original OID, corrupting the catalog (and + * the transient OIDs aren't dispatched). Fall back to a normal reindex with + * a NOTICE; a partitioned table then reindexes each child non-concurrently + * via ReindexPartitions. Single-node utility mode keeps the working + * concurrent path. + */ + if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && + Gp_role == GP_ROLE_DISPATCH && + get_rel_persistence(heapOid) != RELPERSISTENCE_TEMP) + { + /* keep upstream's refusal for system catalogs */ + if (IsCatalogRelationOid(heapOid)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex system catalogs concurrently"))); + + ereport(NOTICE, + (errmsg("concurrent reindex of \"%s\" is not supported in Greenplum, reindexing non-concurrently instead", + relation->relname))); + params->options &= ~REINDEXOPT_CONCURRENTLY; + } + if (get_rel_relkind(heapOid) == RELKIND_PARTITIONED_TABLE) - ReindexPartitions(heapOid, options, concurrent, isTopLevel); - else if (concurrent && + ReindexPartitions(heapOid, params, isTopLevel); + else if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && get_rel_persistence(heapOid) != RELPERSISTENCE_TEMP) { - result = ReindexRelationConcurrently(heapOid, options); + result = ReindexRelationConcurrently(heapOid, params); if (!result) ereport(NOTICE, @@ -2969,10 +3161,13 @@ ReindexTable(ReindexStmt *stmt, bool isTopLevel) } else { + ReindexParams newparams = *params; + + newparams.options |= REINDEXOPT_REPORT_PROGRESS; result = reindex_relation(heapOid, REINDEX_REL_PROCESS_TOAST | REINDEX_REL_CHECK_CONSTRAINTS, - options | REINDEXOPT_REPORT_PROGRESS); + &newparams); if (!result) ereport(NOTICE, (errmsg("table \"%s\" has no indexes to reindex", @@ -2990,8 +3185,6 @@ ReindexTable(ReindexStmt *stmt, bool isTopLevel) qestmt = makeNode(ReindexStmt); qestmt->kind = REINDEX_OBJECT_TABLE; qestmt->relation = NULL; - qestmt->options = options; - qestmt->concurrent = concurrent; qestmt->relid = heapOid; CdbDispatchUtilityStatement((Node *) qestmt, @@ -3012,9 +3205,9 @@ ReindexTable(ReindexStmt *stmt, bool isTopLevel) * separate transaction, so we can release the lock on it right away. * That means this must not be called within a user transaction block! */ -void +static void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, - int options, bool concurrent) + ReindexParams *params) { Oid objectOid; Relation relationRelation; @@ -3026,6 +3219,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, List *relids = NIL; int num_keys; bool concurrent_warning = false; + bool tablespace_warning = false; Assert(Gp_role != GP_ROLE_EXECUTE); AssertArg(objectName); @@ -3033,7 +3227,8 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, objectKind == REINDEX_OBJECT_SYSTEM || objectKind == REINDEX_OBJECT_DATABASE); - if (objectKind == REINDEX_OBJECT_SYSTEM && concurrent) + if (objectKind == REINDEX_OBJECT_SYSTEM && + (params->options & REINDEXOPT_CONCURRENTLY) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot reindex system catalogs concurrently"))); @@ -3143,7 +3338,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, * Skip system tables, since index_create() would reject indexing them * concurrently (and it would likely fail if we tried). */ - if (concurrent && + if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && IsCatalogRelationOid(relid)) { if (!concurrent_warning) @@ -3154,6 +3349,40 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, continue; } + /* + * If a new tablespace is set, check if this relation has to be + * skipped. + */ + if (OidIsValid(params->tablespaceOid)) + { + bool skip_rel = false; + + /* + * Mapped relations cannot be moved to different tablespaces (in + * particular this eliminates all shared catalogs.). + */ + if (RELKIND_HAS_STORAGE(classtuple->relkind) && + !OidIsValid(classtuple->relfilenode)) + skip_rel = true; + + /* + * A system relation is always skipped, even with + * allow_system_table_mods enabled. + */ + if (IsSystemClass(relid, classtuple)) + skip_rel = true; + + if (skip_rel) + { + if (!tablespace_warning) + ereport(WARNING, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("cannot move system relations, skipping all"))); + tablespace_warning = true; + continue; + } + } + /* Save the list of relation OIDs in private context */ old = MemoryContextSwitchTo(private_context); @@ -3178,7 +3407,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, * Process each relation listed in a separate transaction. Note that this * commits and then starts a new transaction immediately. */ - ReindexMultipleInternal(relids, options, concurrent); + ReindexMultipleInternal(relids, params); MemoryContextDelete(private_context); } @@ -3209,7 +3438,7 @@ reindex_error_callback(void *arg) * by the caller. */ static void -ReindexPartitions(Oid relid, int options, bool concurrent, bool isTopLevel) +ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel) { List *partitions = NIL; char relkind = get_rel_relkind(relid); @@ -3286,7 +3515,7 @@ ReindexPartitions(Oid relid, int options, bool concurrent, bool isTopLevel) * Process each partition listed in a separate transaction. Note that * this commits and then starts a new transaction immediately. */ - ReindexMultipleInternal(partitions, options, concurrent); + ReindexMultipleInternal(partitions, params); /* * Clean up working storage --- note we must do this after @@ -3304,10 +3533,21 @@ ReindexPartitions(Oid relid, int options, bool concurrent, bool isTopLevel) * and starts a new transaction when finished. */ static void -ReindexMultipleInternal(List *relids, int options, bool concurrent) +ReindexMultipleInternal(List *relids, ReindexParams *params) { ListCell *l; + /* + * GPDB: REINDEX CONCURRENTLY is not supported on the coordinator (see + * ReindexTable); fall back to a normal reindex. REINDEX TABLE/INDEX already + * cleared this (and emitted the NOTICE) before reaching here via + * ReindexPartitions; this also covers REINDEX DATABASE/SCHEMA, which reaches + * ReindexMultipleInternal() directly. + */ + if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && + Gp_role == GP_ROLE_DISPATCH) + params->options &= ~REINDEXOPT_CONCURRENTLY; + PopActiveSnapshot(); CommitTransactionCommand(); @@ -3335,7 +3575,7 @@ ReindexMultipleInternal(List *relids, int options, bool concurrent) relkind = get_rel_relkind(relid); relpersistence = get_rel_persistence(relid); - lockmode = concurrent ? ShareUpdateExclusiveLock : + lockmode = (params->options & REINDEXOPT_CONCURRENTLY) != 0 ? ShareUpdateExclusiveLock : (relkind == RELKIND_INDEX ? AccessExclusiveLock : ShareLock); /* * If the relation is index, lock the table first to prevent dead lock. @@ -3362,6 +3602,26 @@ ReindexMultipleInternal(List *relids, int options, bool concurrent) CommitTransactionCommand(); continue; } + /* + * Check permissions except when moving to database's default if a new + * tablespace is chosen. Note that this check also happens in + * ExecReindex(), but we do an extra check here as this runs across + * multiple transactions. + */ + if (OidIsValid(params->tablespaceOid) && + params->tablespaceOid != MyDatabaseTableSpace) + { + AclResult aclresult; + + aclresult = pg_tablespace_aclcheck(params->tablespaceOid, + GetUserId(), ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_TABLESPACE, + get_tablespace_name(params->tablespaceOid)); + } + + relkind = get_rel_relkind(relid); + relpersistence = get_rel_persistence(relid); /* * Partitioned tables and indexes can never be processed directly, and @@ -3370,28 +3630,43 @@ ReindexMultipleInternal(List *relids, int options, bool concurrent) Assert(relkind != RELKIND_PARTITIONED_INDEX && relkind != RELKIND_PARTITIONED_TABLE); - if (concurrent && + if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 && relpersistence != RELPERSISTENCE_TEMP) { - result = ReindexRelationConcurrently(relid, options); + ReindexParams newparams = *params; + + newparams.options |= REINDEXOPT_MISSING_OK; + (void) ReindexRelationConcurrently(relid, &newparams); /* ReindexRelationConcurrently() does the verbose output */ } else if (relkind == RELKIND_INDEX) { - reindex_index(relid, false, relpersistence, - options); + ReindexParams newparams = *params; + + newparams.options |= + REINDEXOPT_REPORT_PROGRESS | REINDEXOPT_MISSING_OK; + reindex_index(relid, false, relpersistence, &newparams); PopActiveSnapshot(); /* reindex_index() does the verbose output */ + + /* + * The existence re-check after locking above guarantees the index + * was still there, so it has been rebuilt and the QEs must follow. + */ result = true; } else { + ReindexParams newparams = *params; + + newparams.options |= + REINDEXOPT_REPORT_PROGRESS | REINDEXOPT_MISSING_OK; result = reindex_relation(relid, REINDEX_REL_PROCESS_TOAST | REINDEX_REL_CHECK_CONSTRAINTS, - options | REINDEXOPT_REPORT_PROGRESS); + &newparams); - if (result && (options & REINDEXOPT_VERBOSE)) + if (result && (params->options & REINDEXOPT_VERBOSE) != 0) ereport(INFO, (errmsg("table \"%s.%s\" was reindexed", get_namespace_name(get_rel_namespace(relid)), @@ -3410,8 +3685,6 @@ ReindexMultipleInternal(List *relids, int options, bool concurrent) stmt->kind = relkind == RELKIND_INDEX ? REINDEX_OBJECT_INDEX : REINDEX_OBJECT_TABLE; stmt->relation = NULL; - stmt->options = options; - stmt->concurrent = concurrent; stmt->relid = relid; PushActiveSnapshot(GetTransactionSnapshot()); @@ -3454,8 +3727,15 @@ ReindexMultipleInternal(List *relids, int options, bool concurrent) * anyway, and a non-concurrent reindex is more efficient. */ static bool -ReindexRelationConcurrently(Oid relationOid, int options) +ReindexRelationConcurrently(Oid relationOid, ReindexParams *params) { + typedef struct ReindexIndexInfo + { + Oid indexId; + Oid tableId; + Oid amId; + bool safe; /* for set_indexsafe_procflags */ + } ReindexIndexInfo; List *heapRelationIds = NIL; List *indexIds = NIL; List *newIndexIds = NIL; @@ -3469,6 +3749,13 @@ ReindexRelationConcurrently(Oid relationOid, int options) char *relationName = NULL; char *relationNamespace = NULL; PGRUsage ru0; + const int progress_index[] = { + PROGRESS_CREATEIDX_COMMAND, + PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_INDEX_OID, + PROGRESS_CREATEIDX_ACCESS_METHOD_OID + }; + int64 progress_vals[4]; /* * Create a memory context that will survive forced transaction commits we @@ -3480,7 +3767,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) "ReindexConcurrent", ALLOCSET_SMALL_SIZES); - if (options & REINDEXOPT_VERBOSE) + if ((params->options & REINDEXOPT_VERBOSE) != 0) { /* Save data needed by REINDEX VERBOSE in private context */ oldcontext = MemoryContextSwitchTo(private_context); @@ -3525,7 +3812,24 @@ ReindexRelationConcurrently(Oid relationOid, int options) errmsg("cannot reindex system catalogs concurrently"))); /* Open relation to get its indexes */ - heapRelation = table_open(relationOid, ShareUpdateExclusiveLock); + if ((params->options & REINDEXOPT_MISSING_OK) != 0) + { + heapRelation = try_table_open(relationOid, + ShareUpdateExclusiveLock, false); + /* leave if relation does not exist */ + if (!heapRelation) + break; + } + else + heapRelation = table_open(relationOid, + ShareUpdateExclusiveLock); + + if (OidIsValid(params->tablespaceOid) && + IsSystemRelation(heapRelation)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot move system relation \"%s\"", + RelationGetRelationName(heapRelation)))); /* Add all the valid indexes of relation to list */ foreach(lc, RelationGetIndexList(heapRelation)) @@ -3548,10 +3852,16 @@ ReindexRelationConcurrently(Oid relationOid, int options) get_rel_name(cellOid)))); else { + ReindexIndexInfo *idx; + /* Save the list of relation OIDs in private context */ oldcontext = MemoryContextSwitchTo(private_context); - indexIds = lappend_oid(indexIds, cellOid); + idx = palloc(sizeof(ReindexIndexInfo)); + idx->indexId = cellOid; + /* other fields set later */ + + indexIds = lappend(indexIds, idx); MemoryContextSwitchTo(oldcontext); } @@ -3588,13 +3898,18 @@ ReindexRelationConcurrently(Oid relationOid, int options) get_rel_name(cellOid)))); else { + ReindexIndexInfo *idx; + /* * Save the list of relation OIDs in private * context */ oldcontext = MemoryContextSwitchTo(private_context); - indexIds = lappend_oid(indexIds, cellOid); + idx = palloc(sizeof(ReindexIndexInfo)); + idx->indexId = cellOid; + indexIds = lappend(indexIds, idx); + /* other fields set later */ MemoryContextSwitchTo(oldcontext); } @@ -3610,7 +3925,14 @@ ReindexRelationConcurrently(Oid relationOid, int options) } case RELKIND_INDEX: { - Oid heapId = IndexGetRelation(relationOid, false); + Oid heapId = IndexGetRelation(relationOid, + (params->options & REINDEXOPT_MISSING_OK) != 0); + Relation heapRelation; + ReindexIndexInfo *idx; + + /* if relation is missing, leave */ + if (!OidIsValid(heapId)) + break; if (IsCatalogRelationOid(heapId)) ereport(ERROR, @@ -3619,13 +3941,41 @@ ReindexRelationConcurrently(Oid relationOid, int options) /* * Don't allow reindex for an invalid index on TOAST table, as - * if rebuilt it would not be possible to drop it. + * if rebuilt it would not be possible to drop it. Match + * error message in reindex_index(). */ if (IsToastNamespace(get_rel_namespace(relationOid)) && !get_index_isvalid(relationOid)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot reindex invalid index on TOAST table concurrently"))); + errmsg("cannot reindex invalid index on TOAST table"))); + + /* + * Check if parent relation can be locked and if it exists, + * this needs to be done at this stage as the list of indexes + * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK + * should not be used once all the session locks are taken. + */ + if ((params->options & REINDEXOPT_MISSING_OK) != 0) + { + heapRelation = try_table_open(heapId, + ShareUpdateExclusiveLock, false); + /* leave if relation does not exist */ + if (!heapRelation) + break; + } + else + heapRelation = table_open(heapId, + ShareUpdateExclusiveLock); + + if (OidIsValid(params->tablespaceOid) && + IsSystemRelation(heapRelation)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot move system relation \"%s\"", + get_rel_name(relationOid)))); + + table_close(heapRelation, NoLock); /* Save the list of relation OIDs in private context */ oldcontext = MemoryContextSwitchTo(private_context); @@ -3637,7 +3987,10 @@ ReindexRelationConcurrently(Oid relationOid, int options) * Save the list of relation OIDs in private context. Note * that invalid indexes are allowed here. */ - indexIds = lappend_oid(indexIds, relationOid); + idx = palloc(sizeof(ReindexIndexInfo)); + idx->indexId = relationOid; + indexIds = lappend(indexIds, idx); + /* other fields set later */ MemoryContextSwitchTo(oldcontext); break; @@ -3653,13 +4006,26 @@ ReindexRelationConcurrently(Oid relationOid, int options) break; } - /* Definitely no indexes, so leave */ + /* + * Definitely no indexes, so leave. Any checks based on + * REINDEXOPT_MISSING_OK should be done only while the list of indexes to + * work on is built as the session locks taken before this transaction + * commits will make sure that they cannot be dropped by a concurrent + * session until this operation completes. + */ if (indexIds == NIL) { PopActiveSnapshot(); return false; } + /* It's not a shared catalog, so refuse to move it to shared tablespace */ + if (params->tablespaceOid == GLOBALTABLESPACE_OID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot move non-shared relation to tablespace \"%s\"", + get_tablespace_name(params->tablespaceOid)))); + Assert(heapRelationIds != NIL); /*----- @@ -3690,40 +4056,56 @@ ReindexRelationConcurrently(Oid relationOid, int options) foreach(lc, indexIds) { char *concurrentName; - Oid indexId = lfirst_oid(lc); + ReindexIndexInfo *idx = lfirst(lc); + ReindexIndexInfo *newidx; Oid newIndexId; Relation indexRel; Relation heapRel; Relation newIndexRel; LockRelId *lockrelid; + Oid tablespaceid; - indexRel = index_open(indexId, ShareUpdateExclusiveLock); + indexRel = index_open(idx->indexId, ShareUpdateExclusiveLock); heapRel = table_open(indexRel->rd_index->indrelid, ShareUpdateExclusiveLock); + /* determine safety of this index for set_indexsafe_procflags */ + idx->safe = (indexRel->rd_indexprs == NIL && + indexRel->rd_indpred == NIL); + idx->tableId = RelationGetRelid(heapRel); + idx->amId = indexRel->rd_rel->relam; + /* This function shouldn't be called for temporary relations. */ if (indexRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) elog(ERROR, "cannot reindex a temporary table concurrently"); pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, - RelationGetRelid(heapRel)); - pgstat_progress_update_param(PROGRESS_CREATEIDX_COMMAND, - PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY); - pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, - indexId); - pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID, - indexRel->rd_rel->relam); + idx->tableId); + + progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY; + progress_vals[1] = 0; /* initializing */ + progress_vals[2] = idx->indexId; + progress_vals[3] = idx->amId; + pgstat_progress_update_multi_param(4, progress_index, progress_vals); /* Choose a temporary relation name for the new index */ - concurrentName = ChooseRelationName(get_rel_name(indexId), + concurrentName = ChooseRelationName(get_rel_name(idx->indexId), NULL, "ccnew", get_rel_namespace(indexRel->rd_index->indrelid), false); + /* Choose the new tablespace, indexes of toast tables are not moved */ + if (OidIsValid(params->tablespaceOid) && + heapRel->rd_rel->relkind != RELKIND_TOASTVALUE) + tablespaceid = params->tablespaceOid; + else + tablespaceid = indexRel->rd_rel->reltablespace; + /* Create new index definition based on given index */ newIndexId = index_concurrently_create_copy(heapRel, - indexId, + idx->indexId, + tablespaceid, concurrentName); /* @@ -3737,7 +4119,13 @@ ReindexRelationConcurrently(Oid relationOid, int options) */ oldcontext = MemoryContextSwitchTo(private_context); - newIndexIds = lappend_oid(newIndexIds, newIndexId); + newidx = palloc(sizeof(ReindexIndexInfo)); + newidx->indexId = newIndexId; + newidx->safe = idx->safe; + newidx->tableId = idx->tableId; + newidx->amId = idx->amId; + + newIndexIds = lappend(newIndexIds, newidx); /* * Save lockrelid to protect each relation from drop then close @@ -3801,6 +4189,11 @@ ReindexRelationConcurrently(Oid relationOid, int options) CommitTransactionCommand(); StartTransactionCommand(); + /* + * Because we don't take a snapshot in this transaction, there's no need + * to set the PROC_IN_SAFE_IC flag here. + */ + /* * Phase 2 of REINDEX CONCURRENTLY * @@ -3816,12 +4209,9 @@ ReindexRelationConcurrently(Oid relationOid, int options) WaitForLockersMultiple(lockTags, ShareLock, true); CommitTransactionCommand(); - forboth(lc, indexIds, lc2, newIndexIds) + foreach(lc, newIndexIds) { - Relation indexRel; - Oid oldIndexId = lfirst_oid(lc); - Oid newIndexId = lfirst_oid(lc2); - Oid heapId; + ReindexIndexInfo *newidx = lfirst(lc); /* Start new transaction for this index's concurrent build */ StartTransactionCommand(); @@ -3833,25 +4223,38 @@ ReindexRelationConcurrently(Oid relationOid, int options) */ CHECK_FOR_INTERRUPTS(); + /* Tell concurrent indexing to ignore us, if index qualifies */ + if (newidx->safe) + set_indexsafe_procflags(); + /* Set ActiveSnapshot since functions in the indexes may need it */ PushActiveSnapshot(GetTransactionSnapshot()); /* - * Index relation has been closed by previous commit, so reopen it to - * get its information. + * Update progress for the index to build, with the correct parent + * table involved. */ - indexRel = index_open(oldIndexId, ShareUpdateExclusiveLock); - heapId = indexRel->rd_index->indrelid; - index_close(indexRel, NoLock); + pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, newidx->tableId); + progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY; + progress_vals[1] = PROGRESS_CREATEIDX_PHASE_BUILD; + progress_vals[2] = newidx->indexId; + progress_vals[3] = newidx->amId; + pgstat_progress_update_multi_param(4, progress_index, progress_vals); /* Perform concurrent build of new index */ - index_concurrently_build(heapId, newIndexId); + index_concurrently_build(newidx->tableId, newidx->indexId); PopActiveSnapshot(); CommitTransactionCommand(); } + StartTransactionCommand(); + /* + * Because we don't take a snapshot or Xid in this transaction, there's no + * need to set the PROC_IN_SAFE_IC flag here. + */ + /* * Phase 3 of REINDEX CONCURRENTLY * @@ -3867,8 +4270,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) foreach(lc, newIndexIds) { - Oid newIndexId = lfirst_oid(lc); - Oid heapId; + ReindexIndexInfo *newidx = lfirst(lc); TransactionId limitXmin; Snapshot snapshot; @@ -3881,7 +4283,9 @@ ReindexRelationConcurrently(Oid relationOid, int options) */ CHECK_FOR_INTERRUPTS(); - heapId = IndexGetRelation(newIndexId, false); + /* Tell concurrent indexing to ignore us, if index qualifies */ + if (newidx->safe) + set_indexsafe_procflags(); /* * Take the "reference snapshot" that will be used by validate_index() @@ -3890,7 +4294,19 @@ ReindexRelationConcurrently(Oid relationOid, int options) snapshot = RegisterSnapshot(GetTransactionSnapshot()); PushActiveSnapshot(snapshot); - validate_index(heapId, newIndexId, snapshot); + /* + * Update progress for the index to build, with the correct parent + * table involved. + */ + pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, + newidx->tableId); + progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY; + progress_vals[1] = PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN; + progress_vals[2] = newidx->indexId; + progress_vals[3] = newidx->amId; + pgstat_progress_update_multi_param(4, progress_index, progress_vals); + + validate_index(newidx->tableId, newidx->indexId, snapshot); /* * We can now do away with our active snapshot, we still need to save @@ -3914,6 +4330,9 @@ ReindexRelationConcurrently(Oid relationOid, int options) * interesting tuples. But since it might not contain tuples deleted * just before the reference snap was taken, we have to wait out any * transactions that might have older snapshots. + * + * Because we don't take a snapshot or Xid in this transaction, + * there's no need to set the PROC_IN_SAFE_IC flag here. */ pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, PROGRESS_CREATEIDX_PHASE_WAIT_3); @@ -3935,12 +4354,18 @@ ReindexRelationConcurrently(Oid relationOid, int options) StartTransactionCommand(); + /* + * Because this transaction only does catalog manipulations and doesn't do + * any index operations, we can set the PROC_IN_SAFE_IC flag here + * unconditionally. + */ + set_indexsafe_procflags(); + forboth(lc, indexIds, lc2, newIndexIds) { + ReindexIndexInfo *oldidx = lfirst(lc); + ReindexIndexInfo *newidx = lfirst(lc2); char *oldName; - Oid oldIndexId = lfirst_oid(lc); - Oid newIndexId = lfirst_oid(lc2); - Oid heapId; /* * Check for user-requested abort. This is inside a transaction so as @@ -3949,27 +4374,25 @@ ReindexRelationConcurrently(Oid relationOid, int options) */ CHECK_FOR_INTERRUPTS(); - heapId = IndexGetRelation(oldIndexId, false); - /* Choose a relation name for old index */ - oldName = ChooseRelationName(get_rel_name(oldIndexId), + oldName = ChooseRelationName(get_rel_name(oldidx->indexId), NULL, "ccold", - get_rel_namespace(heapId), + get_rel_namespace(oldidx->tableId), false); /* * Swap old index with the new one. This also marks the new one as * valid and the old one as not valid. */ - index_concurrently_swap(newIndexId, oldIndexId, oldName); + index_concurrently_swap(newidx->indexId, oldidx->indexId, oldName); /* * Invalidate the relcache for the table, so that after this commit * all sessions will refresh any cached plans that might reference the * index. */ - CacheInvalidateRelcacheByRelid(heapId); + CacheInvalidateRelcacheByRelid(oldidx->tableId); /* * CCI here so that subsequent iterations see the oldName in the @@ -3985,6 +4408,12 @@ ReindexRelationConcurrently(Oid relationOid, int options) CommitTransactionCommand(); StartTransactionCommand(); + /* + * While we could set PROC_IN_SAFE_IC if all indexes qualified, there's no + * real need for that, because we only acquire an Xid after the wait is + * done, and that lasts for a very short period. + */ + /* * Phase 5 of REINDEX CONCURRENTLY * @@ -3999,8 +4428,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) foreach(lc, indexIds) { - Oid oldIndexId = lfirst_oid(lc); - Oid heapId; + ReindexIndexInfo *oldidx = lfirst(lc); /* * Check for user-requested abort. This is inside a transaction so as @@ -4009,14 +4437,19 @@ ReindexRelationConcurrently(Oid relationOid, int options) */ CHECK_FOR_INTERRUPTS(); - heapId = IndexGetRelation(oldIndexId, false); - index_concurrently_set_dead(heapId, oldIndexId); + index_concurrently_set_dead(oldidx->tableId, oldidx->indexId); } /* Commit this transaction to make the updates visible. */ CommitTransactionCommand(); StartTransactionCommand(); + /* + * While we could set PROC_IN_SAFE_IC if all indexes qualified, there's no + * real need for that, because we only acquire an Xid after the wait is + * done, and that lasts for a very short period. + */ + /* * Phase 6 of REINDEX CONCURRENTLY * @@ -4024,7 +4457,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) */ pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, - PROGRESS_CREATEIDX_PHASE_WAIT_4); + PROGRESS_CREATEIDX_PHASE_WAIT_5); WaitForLockersMultiple(lockTags, AccessExclusiveLock, true); PushActiveSnapshot(GetTransactionSnapshot()); @@ -4034,11 +4467,11 @@ ReindexRelationConcurrently(Oid relationOid, int options) foreach(lc, indexIds) { - Oid oldIndexId = lfirst_oid(lc); + ReindexIndexInfo *idx = lfirst(lc); ObjectAddress object; object.classId = RelationRelationId; - object.objectId = oldIndexId; + object.objectId = idx->indexId; object.objectSubId = 0; add_exact_object_address(&object, objects); @@ -4069,7 +4502,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) StartTransactionCommand(); /* Log what we did */ - if (options & REINDEXOPT_VERBOSE) + if ((params->options & REINDEXOPT_VERBOSE) != 0) { if (relkind == RELKIND_INDEX) ereport(INFO, @@ -4081,7 +4514,8 @@ ReindexRelationConcurrently(Oid relationOid, int options) { foreach(lc, newIndexIds) { - Oid indOid = lfirst_oid(lc); + ReindexIndexInfo *idx = lfirst(lc); + Oid indOid = idx->indexId; ereport(INFO, (errmsg("index \"%s.%s\" was reindexed", @@ -4153,23 +4587,7 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid) } else { - Datum values[Natts_pg_inherits]; - bool isnull[Natts_pg_inherits]; - - /* - * No pg_inherits row exists, and we want a parent for this index, - * so insert it. - */ - values[Anum_pg_inherits_inhrelid - 1] = ObjectIdGetDatum(partRelid); - values[Anum_pg_inherits_inhparent - 1] = - ObjectIdGetDatum(parentOid); - values[Anum_pg_inherits_inhseqno - 1] = Int32GetDatum(1); - memset(isnull, false, sizeof(isnull)); - - tuple = heap_form_tuple(RelationGetDescr(pg_inherits), - values, isnull); - CatalogTupleInsert(pg_inherits, tuple); - + StoreSingleInheritance(partRelid, parentOid, 1); fix_dependencies = true; } } @@ -4272,3 +4690,37 @@ update_relispartition(Oid relationId, bool newval) heap_freetuple(tup); table_close(classRel, RowExclusiveLock); } + +/* + * Set the PROC_IN_SAFE_IC flag in MyProc->statusFlags. + * + * When doing concurrent index builds, we can set this flag + * to tell other processes concurrently running CREATE + * INDEX CONCURRENTLY or REINDEX CONCURRENTLY to ignore us when + * doing their waits for concurrent snapshots. On one hand it + * avoids pointlessly waiting for a process that's not interesting + * anyway; but more importantly it avoids deadlocks in some cases. + * + * This can be done safely only for indexes that don't execute any + * expressions that could access other tables, so index must not be + * expressional nor partial. Caller is responsible for only calling + * this routine when that assumption holds true. + * + * (The flag is reset automatically at transaction end, so it must be + * set for each transaction.) + */ +static inline void +set_indexsafe_procflags(void) +{ + /* + * This should only be called before installing xid or xmin in MyProc; + * otherwise, concurrent processes could see an Xmin that moves backwards. + */ + Assert(MyProc->xid == InvalidTransactionId && + MyProc->xmin == InvalidTransactionId); + + LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); + MyProc->statusFlags |= PROC_IN_SAFE_IC; + ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; + LWLockRelease(ProcArrayLock); +} diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c index 2accc484daf1..bed4f71e2059 100644 --- a/src/backend/commands/lockcmds.c +++ b/src/backend/commands/lockcmds.c @@ -3,7 +3,7 @@ * lockcmds.c * LOCK command support code * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -34,7 +34,8 @@ static void LockTableRecurse(Oid reloid, LOCKMODE lockmode, bool nowait); static AclResult LockTableAclCheck(Oid relid, LOCKMODE lockmode, Oid userid); static void RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, Oid oldrelid, void *arg); -static void LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views); +static void LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, + List *ancestor_views); /* * LOCK TABLE @@ -245,12 +246,12 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context) relkind != RELKIND_VIEW) continue; - /* Check infinite recursion in the view definition. */ + /* + * We might be dealing with a self-referential view. If so, we + * can just stop recursing, since we already locked it. + */ if (list_member_oid(context->ancestor_views, relid)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("infinite recursion detected in rules for relation \"%s\"", - get_rel_name(relid)))); + continue; /* Check permissions with the view owner's privilege. */ aclresult = LockTableAclCheck(relid, context->lockmode, context->viewowner); @@ -267,7 +268,8 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context) relname))); if (relkind == RELKIND_VIEW) - LockViewRecurse(relid, context->lockmode, context->nowait, context->ancestor_views); + LockViewRecurse(relid, context->lockmode, context->nowait, + context->ancestor_views); else if (rte->inh) LockTableRecurse(relid, context->lockmode, context->nowait); } @@ -284,13 +286,14 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context) } static void -LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views) +LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, + List *ancestor_views) { LockViewRecurse_context context; - Relation view; Query *viewquery; + /* caller has already locked the view */ view = table_open(reloid, NoLock); viewquery = get_view_query(view); @@ -302,7 +305,7 @@ LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views LockViewRecurse_walker((Node *) viewquery, &context); - (void) list_delete_last(context.ancestor_views); + context.ancestor_views = list_delete_last(context.ancestor_views); table_close(view, NoLock); } diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index 62c1722247ec..799af70a0ced 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -3,7 +3,7 @@ * matview.c * materialized view support * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -407,6 +407,17 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, ObjectAddressSet(address, RelationRelationId, matviewOid); + /* + * Save the rowcount so that pg_stat_statements can track the total number + * of rows processed by REFRESH MATERIALIZED VIEW command. Note that we + * still don't display the rowcount in the command completion tag output, + * i.e., the display_rowcount flag of CMDTAG_REFRESH_MATERIALIZED_VIEW + * command tag is left false in cmdtaglist.h. Otherwise, the change of + * completion tag output might break applications using it. + */ + if (qc) + SetQueryCompletion(qc, CMDTAG_REFRESH_MATERIALIZED_VIEW, processed); + return address; } @@ -460,7 +471,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query, CHECK_FOR_INTERRUPTS(); /* Plan the query which will generate data for the refresh. */ - plan = pg_plan_query(query, queryString, 0, NULL); + plan = pg_plan_query(query, queryString, CURSOR_OPT_PARALLEL_OK, NULL); plan->refreshClause = refreshClause; @@ -796,13 +807,13 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, */ resetStringInfo(&querybuf); appendStringInfo(&querybuf, - "SELECT newdata FROM %s newdata " - "WHERE newdata IS NOT NULL AND EXISTS " - "(SELECT 1 FROM %s newdata2 WHERE newdata2 IS NOT NULL " - "AND newdata2 OPERATOR(pg_catalog.*=) newdata " - "AND newdata2.ctid OPERATOR(pg_catalog.<>) " - "newdata.ctid and newdata2.gp_segment_id = " - "newdata.gp_segment_id)", + "SELECT _$newdata FROM %s _$newdata " + "WHERE _$newdata IS NOT NULL AND EXISTS " + "(SELECT 1 FROM %s _$newdata2 WHERE _$newdata2 IS NOT NULL " + "AND _$newdata2 OPERATOR(pg_catalog.*=) _$newdata " + "AND (_$newdata2.ctid OPERATOR(pg_catalog.<>) " + "_$newdata.ctid OR _$newdata2.gp_segment_id " + "OPERATOR(pg_catalog.<>) _$newdata.gp_segment_id))", tempname, tempname); if (SPI_execute(querybuf.data, false, 1) != SPI_OK_SELECT) elog(ERROR, "SPI_exec failed: %s", querybuf.data); @@ -833,10 +844,19 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, /* Start building the query for creating the diff table. */ resetStringInfo(&querybuf); + /* + * GPDB: unlike upstream, store the new data as expanded columns rather + * than a whole-row record: an anonymous record's typmod is not + * registered on other nodes, so reading the record column back from + * the distributed temp table fails with "record type has not been + * registered". Unmatched-side discrimination works off tid alone + * (matched rows are filtered out by the WHERE clause below). + */ appendStringInfo(&querybuf, "CREATE TEMP TABLE %s AS " - "SELECT mv.ctid AS tid, mv.gp_segment_id as sid, newdata.* " - "FROM %s mv FULL JOIN %s newdata ON (", + "SELECT _$mv.ctid AS tid, " + "_$mv.gp_segment_id AS sid, _$newdata.* " + "FROM %s _$mv FULL JOIN %s _$newdata ON (", diffname, matviewname, tempname); /* @@ -931,9 +951,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, if (foundUniqueIndex) appendStringInfoString(&querybuf, " AND "); - leftop = quote_qualified_identifier("newdata", - NameStr(newattr->attname)); - rightop = quote_qualified_identifier("mv", + leftop = quote_qualified_identifier("_$newdata", + NameStr(attr->attname)); + rightop = quote_qualified_identifier("_$mv", NameStr(attr->attname)); generate_operator_clause(&querybuf, @@ -963,10 +983,9 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, appendStringInfoString(&querybuf, - " AND newdata.* OPERATOR(pg_catalog.*=) mv.*) " - "WHERE newdata.* IS NULL OR mv.* IS NULL " - "ORDER BY tid "); - appendStringInfoString(&querybuf, distributed); + " AND _$newdata OPERATOR(pg_catalog.*=) _$mv) " + "WHERE _$newdata IS NULL OR _$mv IS NULL " + "ORDER BY tid"); /* Create the temporary "diff" table. */ if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY) @@ -991,10 +1010,11 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, /* Deletes must come before inserts; do them first. */ resetStringInfo(&querybuf); appendStringInfo(&querybuf, - "DELETE FROM %s mv WHERE ctid OPERATOR(pg_catalog.=) ANY " - "(SELECT diff.tid FROM %s diff " - "WHERE diff.tid = mv.ctid and diff.sid = mv.gp_segment_id and" - " diff.tid IS NOT NULL)", + "DELETE FROM %s _$mv WHERE EXISTS " + "(SELECT 1 FROM %s _$diff " + "WHERE _$diff.tid IS NOT NULL " + "AND _$diff.tid OPERATOR(pg_catalog.=) _$mv.ctid " + "AND _$diff.sid OPERATOR(pg_catalog.=) _$mv.gp_segment_id)", matviewname, diffname); if (SPI_exec(querybuf.data, 0) != SPI_OK_DELETE) elog(ERROR, "SPI_exec failed: %s", querybuf.data); @@ -1005,13 +1025,12 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, for (int i = 0; i < newHeapDesc->natts; ++i) { Form_pg_attribute attr = TupleDescAttr(newHeapDesc, i); - if (i == newHeapDesc->natts - 1) - appendStringInfo(&querybuf, " %s", NameStr(attr->attname)); - else - appendStringInfo(&querybuf, " %s,", NameStr(attr->attname)); + + appendStringInfo(&querybuf, "%s %s", (i == 0) ? "" : ",", + quote_identifier(NameStr(attr->attname))); } appendStringInfo(&querybuf, - " FROM %s diff WHERE tid IS NULL", + " FROM %s _$diff WHERE tid IS NULL", diffname); if (SPI_exec(querybuf.data, 0) != SPI_OK_INSERT) elog(ERROR, "SPI_exec failed: %s", querybuf.data); diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index 97e4a0fbe7e7..8454cc9d8148 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -4,7 +4,7 @@ * * Routines for opclass (and opfamily) manipulation commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1248,14 +1248,14 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid, (OidIsValid(member->righttype) && member->righttype != typeoid)) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("associated data types for opclass options parsing functions must match opclass input type"))); + errmsg("associated data types for operator class options parsing functions must match opclass input type"))); } else { if (member->lefttype != member->righttype) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("left and right associated data types for opclass options parsing functions must match"))); + errmsg("left and right associated data types for operator class options parsing functions must match"))); } if (procform->prorettype != VOIDOID || @@ -1263,8 +1263,8 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid, procform->proargtypes.values[0] != INTERNALOID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("invalid opclass options parsing function"), - errhint("Valid signature of opclass options parsing function is '%s'.", + errmsg("invalid operator class options parsing function"), + errhint("Valid signature of operator class options parsing function is %s.", "(internal) RETURNS void"))); } diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 220f073e2cff..166c48220baf 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -4,7 +4,7 @@ * * Routines for operator manipulation commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -184,10 +184,22 @@ DefineOperator(List *names, List *parameters) if (typeName2) typeId2 = typenameTypeId(NULL, typeName2); + /* + * If only the right argument is missing, the user is likely trying to + * create a postfix operator, so give them a hint about why that does not + * work. But if both arguments are missing, do not mention postfix + * operators, as the user most likely simply neglected to mention the + * arguments. + */ if (!OidIsValid(typeId1) && !OidIsValid(typeId2)) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("at least one of leftarg or rightarg must be specified"))); + errmsg("operator argument types must be specified"))); + if (!OidIsValid(typeId2)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("operator right argument type must be specified"), + errdetail("Postfix operators are not supported."))); if (typeName1) { @@ -286,7 +298,7 @@ DefineOperator(List *names, List *parameters) } /* - * Look up a restriction estimator function ny name, and verify that it has + * Look up a restriction estimator function by name, and verify that it has * the correct signature and we have the permissions to attach it to an * operator. */ @@ -321,7 +333,7 @@ ValidateRestrictionEstimator(List *restrictionName) } /* - * Look up a join estimator function ny name, and verify that it has the + * Look up a join estimator function by name, and verify that it has the * correct signature and we have the permissions to attach it to an * operator. */ diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index a6ebb56b1353..c468cbd16a64 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -3,7 +3,7 @@ * policy.c * Commands for manipulating policies. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/commands/policy.c @@ -18,6 +18,7 @@ #include "access/relation.h" #include "access/sysattr.h" #include "access/table.h" +#include "access/xact.h" #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" @@ -192,159 +193,139 @@ policy_role_list_to_array(List *roles, int *num_roles) /* * Load row security policy from the catalog, and store it in * the relation's relcache entry. + * + * Note that caller should have verified that pg_class.relrowsecurity + * is true for this relation. */ void RelationBuildRowSecurity(Relation relation) { MemoryContext rscxt; MemoryContext oldcxt = CurrentMemoryContext; - RowSecurityDesc *volatile rsdesc = NULL; + RowSecurityDesc *rsdesc; + Relation catalog; + ScanKeyData skey; + SysScanDesc sscan; + HeapTuple tuple; /* * Create a memory context to hold everything associated with this * relation's row security policy. This makes it easy to clean up during - * a relcache flush. + * a relcache flush. However, to cover the possibility of an error + * partway through, we don't make the context long-lived till we're done. */ - rscxt = AllocSetContextCreate(CacheMemoryContext, + rscxt = AllocSetContextCreate(CurrentMemoryContext, "row security descriptor", ALLOCSET_SMALL_SIZES); + MemoryContextCopyAndSetIdentifier(rscxt, + RelationGetRelationName(relation)); + + rsdesc = MemoryContextAllocZero(rscxt, sizeof(RowSecurityDesc)); + rsdesc->rscxt = rscxt; /* - * Since rscxt lives under CacheMemoryContext, it is long-lived. Use a - * PG_TRY block to ensure it'll get freed if we fail partway through. + * Now scan pg_policy for RLS policies associated with this relation. + * Because we use the index on (polrelid, polname), we should consistently + * visit the rel's policies in name order, at least when system indexes + * aren't disabled. This simplifies equalRSDesc(). */ - PG_TRY(); - { - Relation catalog; - ScanKeyData skey; - SysScanDesc sscan; - HeapTuple tuple; - - MemoryContextCopyAndSetIdentifier(rscxt, - RelationGetRelationName(relation)); + catalog = table_open(PolicyRelationId, AccessShareLock); - rsdesc = MemoryContextAllocZero(rscxt, sizeof(RowSecurityDesc)); - rsdesc->rscxt = rscxt; + ScanKeyInit(&skey, + Anum_pg_policy_polrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(relation))); - catalog = table_open(PolicyRelationId, AccessShareLock); + sscan = systable_beginscan(catalog, PolicyPolrelidPolnameIndexId, true, + NULL, 1, &skey); - ScanKeyInit(&skey, - Anum_pg_policy_polrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(relation))); + while (HeapTupleIsValid(tuple = systable_getnext(sscan))) + { + Form_pg_policy policy_form = (Form_pg_policy) GETSTRUCT(tuple); + RowSecurityPolicy *policy; + Datum datum; + bool isnull; + char *str_value; - sscan = systable_beginscan(catalog, PolicyPolrelidPolnameIndexId, true, - NULL, 1, &skey); + policy = MemoryContextAllocZero(rscxt, sizeof(RowSecurityPolicy)); /* - * Loop through the row level security policies for this relation, if - * any. + * Note: we must be sure that pass-by-reference data gets copied into + * rscxt. We avoid making that context current over wider spans than + * we have to, though. */ - while (HeapTupleIsValid(tuple = systable_getnext(sscan))) - { - Datum value_datum; - char cmd_value; - bool permissive_value; - Datum roles_datum; - char *qual_value; - Expr *qual_expr; - char *with_check_value; - Expr *with_check_qual; - char *policy_name_value; - bool isnull; - RowSecurityPolicy *policy; - - /* - * Note: all the pass-by-reference data we collect here is either - * still stored in the tuple, or constructed in the caller's - * short-lived memory context. We must copy it into rscxt - * explicitly below. - */ - - /* Get policy command */ - value_datum = heap_getattr(tuple, Anum_pg_policy_polcmd, - RelationGetDescr(catalog), &isnull); - Assert(!isnull); - cmd_value = DatumGetChar(value_datum); - - /* Get policy permissive or restrictive */ - value_datum = heap_getattr(tuple, Anum_pg_policy_polpermissive, - RelationGetDescr(catalog), &isnull); - Assert(!isnull); - permissive_value = DatumGetBool(value_datum); - - /* Get policy name */ - value_datum = heap_getattr(tuple, Anum_pg_policy_polname, - RelationGetDescr(catalog), &isnull); - Assert(!isnull); - policy_name_value = NameStr(*(DatumGetName(value_datum))); - - /* Get policy roles */ - roles_datum = heap_getattr(tuple, Anum_pg_policy_polroles, - RelationGetDescr(catalog), &isnull); - /* shouldn't be null, but initdb doesn't mark it so, so check */ - if (isnull) - elog(ERROR, "unexpected null value in pg_policy.polroles"); - - /* Get policy qual */ - value_datum = heap_getattr(tuple, Anum_pg_policy_polqual, - RelationGetDescr(catalog), &isnull); - if (!isnull) - { - qual_value = TextDatumGetCString(value_datum); - qual_expr = (Expr *) stringToNode(qual_value); - } - else - qual_expr = NULL; - /* Get WITH CHECK qual */ - value_datum = heap_getattr(tuple, Anum_pg_policy_polwithcheck, - RelationGetDescr(catalog), &isnull); - if (!isnull) - { - with_check_value = TextDatumGetCString(value_datum); - with_check_qual = (Expr *) stringToNode(with_check_value); - } - else - with_check_qual = NULL; + /* Get policy command */ + policy->polcmd = policy_form->polcmd; - /* Now copy everything into the cache context */ - MemoryContextSwitchTo(rscxt); + /* Get policy, permissive or restrictive */ + policy->permissive = policy_form->polpermissive; - policy = palloc0(sizeof(RowSecurityPolicy)); - policy->policy_name = pstrdup(policy_name_value); - policy->polcmd = cmd_value; - policy->permissive = permissive_value; - policy->roles = DatumGetArrayTypePCopy(roles_datum); - policy->qual = copyObject(qual_expr); - policy->with_check_qual = copyObject(with_check_qual); - policy->hassublinks = checkExprHasSubLink((Node *) qual_expr) || - checkExprHasSubLink((Node *) with_check_qual); + /* Get policy name */ + policy->policy_name = + MemoryContextStrdup(rscxt, NameStr(policy_form->polname)); - rsdesc->policies = lcons(policy, rsdesc->policies); + /* Get policy roles */ + datum = heap_getattr(tuple, Anum_pg_policy_polroles, + RelationGetDescr(catalog), &isnull); + /* shouldn't be null, but let's check for luck */ + if (isnull) + elog(ERROR, "unexpected null value in pg_policy.polroles"); + MemoryContextSwitchTo(rscxt); + policy->roles = DatumGetArrayTypePCopy(datum); + MemoryContextSwitchTo(oldcxt); + /* Get policy qual */ + datum = heap_getattr(tuple, Anum_pg_policy_polqual, + RelationGetDescr(catalog), &isnull); + if (!isnull) + { + str_value = TextDatumGetCString(datum); + MemoryContextSwitchTo(rscxt); + policy->qual = (Expr *) stringToNode(str_value); MemoryContextSwitchTo(oldcxt); + pfree(str_value); + } + else + policy->qual = NULL; - /* clean up some (not all) of the junk ... */ - if (qual_expr != NULL) - pfree(qual_expr); - if (with_check_qual != NULL) - pfree(with_check_qual); + /* Get WITH CHECK qual */ + datum = heap_getattr(tuple, Anum_pg_policy_polwithcheck, + RelationGetDescr(catalog), &isnull); + if (!isnull) + { + str_value = TextDatumGetCString(datum); + MemoryContextSwitchTo(rscxt); + policy->with_check_qual = (Expr *) stringToNode(str_value); + MemoryContextSwitchTo(oldcxt); + pfree(str_value); } + else + policy->with_check_qual = NULL; - systable_endscan(sscan); - table_close(catalog, AccessShareLock); - } - PG_CATCH(); - { - /* Delete rscxt, first making sure it isn't active */ + /* We want to cache whether there are SubLinks in these expressions */ + policy->hassublinks = checkExprHasSubLink((Node *) policy->qual) || + checkExprHasSubLink((Node *) policy->with_check_qual); + + /* + * Add this object to list. For historical reasons, the list is built + * in reverse order. + */ + MemoryContextSwitchTo(rscxt); + rsdesc->policies = lcons(policy, rsdesc->policies); MemoryContextSwitchTo(oldcxt); - MemoryContextDelete(rscxt); - PG_RE_THROW(); } - PG_END_TRY(); - /* Success --- attach the policy descriptor to the relcache entry */ + systable_endscan(sscan); + table_close(catalog, AccessShareLock); + + /* + * Success. Reparent the descriptor's memory context under + * CacheMemoryContext so that it will live indefinitely, then attach the + * policy descriptor to the relcache entry. + */ + MemoryContextSetParent(rscxt, CacheMemoryContext); + relation->rd_rsdesc = rsdesc; } @@ -428,13 +409,12 @@ RemovePolicyById(Oid policy_id) /* * RemoveRoleFromObjectPolicy - - * remove a role from a policy by its OID. If the role is not a member of - * the policy then an error is raised. False is returned to indicate that - * the role could not be removed due to being the only role on the policy - * and therefore the entire policy should be removed. + * remove a role from a policy's applicable-roles list. * - * Note that a warning will be thrown and true will be returned on a - * permission error, as the policy should not be removed in that case. + * Returns true if the role was successfully removed from the policy. + * Returns false if the role was not removed because it would have left + * polroles empty (which is disallowed, though perhaps it should not be). + * On false return, the caller should instead drop the policy altogether. * * roleid - the oid of the role to remove * classid - should always be PolicyRelationId @@ -448,12 +428,15 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) ScanKeyData skey[1]; HeapTuple tuple; Oid relid; - Relation rel; ArrayType *policy_roles; - int num_roles; Datum roles_datum; + Oid *roles; + int num_roles; + Datum *role_oids; bool attr_isnull; - bool noperm = true; + bool keep_policy = true; + int i, + j; Assert(classid == PolicyRelationId); @@ -476,26 +459,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) if (!HeapTupleIsValid(tuple)) elog(ERROR, "could not find tuple for policy %u", policy_id); - /* - * Open and exclusive-lock the relation the policy belongs to. - */ + /* Identify rel the policy belongs to */ relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid; - rel = relation_open(relid, AccessExclusiveLock); - - if (rel->rd_rel->relkind != RELKIND_RELATION && - rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table", - RelationGetRelationName(rel)))); - - if (!allowSystemTableMods && IsSystemRelation(rel)) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); - /* Get the current set of roles */ roles_datum = heap_getattr(tuple, Anum_pg_policy_polroles, @@ -505,45 +471,31 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) Assert(!attr_isnull); policy_roles = DatumGetArrayTypePCopy(roles_datum); - - /* We should be removing exactly one entry from the roles array */ - num_roles = ARR_DIMS(policy_roles)[0] - 1; - - Assert(num_roles >= 0); - - /* Must own relation. */ - if (pg_class_ownercheck(relid, GetUserId())) - noperm = false; /* user is allowed to modify this policy */ - else - ereport(WARNING, - (errcode(ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED), - errmsg("role \"%s\" could not be removed from policy \"%s\" on \"%s\"", - GetUserNameFromId(roleid, false), - NameStr(((Form_pg_policy) GETSTRUCT(tuple))->polname), - RelationGetRelationName(rel)))); + roles = (Oid *) ARR_DATA_PTR(policy_roles); + num_roles = ARR_DIMS(policy_roles)[0]; /* - * If multiple roles exist on this policy, then remove the one we were - * asked to and leave the rest. + * Rebuild the polroles array, without any mentions of the target role. + * Ordinarily there'd be exactly one, but we must cope with duplicate + * mentions, since CREATE/ALTER POLICY historically have allowed that. */ - if (!noperm && num_roles > 0) + role_oids = (Datum *) palloc(num_roles * sizeof(Datum)); + for (i = 0, j = 0; i < num_roles; i++) + { + if (roles[i] != roleid) + role_oids[j++] = ObjectIdGetDatum(roles[i]); + } + num_roles = j; + + /* If any roles remain, update the policy entry. */ + if (num_roles > 0) { - int i, - j; - Oid *roles = (Oid *) ARR_DATA_PTR(policy_roles); - Datum *role_oids; - char *qual_value; - Node *qual_expr; - List *qual_parse_rtable = NIL; - char *with_check_value; - Node *with_check_qual; - List *with_check_parse_rtable = NIL; + ArrayType *role_ids; Datum values[Natts_pg_policy]; bool isnull[Natts_pg_policy]; bool replaces[Natts_pg_policy]; - Datum value_datum; - ArrayType *role_ids; HeapTuple new_tuple; + HeapTuple reltup; ObjectAddress target; ObjectAddress myself; @@ -552,71 +504,6 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) memset(replaces, 0, sizeof(replaces)); memset(isnull, 0, sizeof(isnull)); - /* - * All of the dependencies will be removed from the policy and then - * re-added. In order to get them correct, we need to extract out the - * expressions in the policy and construct a parsestate just enough to - * build the range table(s) to then pass to recordDependencyOnExpr(). - */ - - /* Get policy qual, to update dependencies */ - value_datum = heap_getattr(tuple, Anum_pg_policy_polqual, - RelationGetDescr(pg_policy_rel), &attr_isnull); - if (!attr_isnull) - { - ParseState *qual_pstate; - - /* parsestate is built just to build the range table */ - qual_pstate = make_parsestate(NULL); - - qual_value = TextDatumGetCString(value_datum); - qual_expr = stringToNode(qual_value); - - /* Add this rel to the parsestate's rangetable, for dependencies */ - (void) addRangeTableEntryForRelation(qual_pstate, rel, - AccessShareLock, - NULL, false, false); - - qual_parse_rtable = qual_pstate->p_rtable; - free_parsestate(qual_pstate); - } - else - qual_expr = NULL; - - /* Get WITH CHECK qual, to update dependencies */ - value_datum = heap_getattr(tuple, Anum_pg_policy_polwithcheck, - RelationGetDescr(pg_policy_rel), &attr_isnull); - if (!attr_isnull) - { - ParseState *with_check_pstate; - - /* parsestate is built just to build the range table */ - with_check_pstate = make_parsestate(NULL); - - with_check_value = TextDatumGetCString(value_datum); - with_check_qual = stringToNode(with_check_value); - - /* Add this rel to the parsestate's rangetable, for dependencies */ - (void) addRangeTableEntryForRelation(with_check_pstate, rel, - AccessShareLock, - NULL, false, false); - - with_check_parse_rtable = with_check_pstate->p_rtable; - free_parsestate(with_check_pstate); - } - else - with_check_qual = NULL; - - /* Rebuild the roles array to then update the pg_policy tuple with */ - role_oids = (Datum *) palloc(num_roles * sizeof(Datum)); - for (i = 0, j = 0; i < ARR_DIMS(policy_roles)[0]; i++) - /* Copy over all of the roles which are not the one being removed */ - if (roles[i] != roleid) - role_oids[j++] = ObjectIdGetDatum(roles[i]); - - /* We should have only removed the one role */ - Assert(j == num_roles); - /* This is the array for the new tuple */ role_ids = construct_array(role_oids, num_roles, OIDOID, sizeof(Oid), true, TYPALIGN_INT); @@ -629,33 +516,14 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) values, isnull, replaces); CatalogTupleUpdate(pg_policy_rel, &new_tuple->t_self, new_tuple); - /* Remove all old dependencies. */ - deleteDependencyRecordsFor(PolicyRelationId, policy_id, false); - - /* Record the new set of dependencies */ - target.classId = RelationRelationId; - target.objectId = relid; - target.objectSubId = 0; + /* Remove all the old shared dependencies (roles) */ + deleteSharedDependencyRecordsFor(PolicyRelationId, policy_id, 0); + /* Record the new shared dependencies (roles) */ myself.classId = PolicyRelationId; myself.objectId = policy_id; myself.objectSubId = 0; - recordDependencyOn(&myself, &target, DEPENDENCY_AUTO); - - if (qual_expr) - recordDependencyOnExpr(&myself, qual_expr, qual_parse_rtable, - DEPENDENCY_NORMAL); - - if (with_check_qual) - recordDependencyOnExpr(&myself, with_check_qual, - with_check_parse_rtable, - DEPENDENCY_NORMAL); - - /* Remove all the old shared dependencies (roles) */ - deleteSharedDependencyRecordsFor(PolicyRelationId, policy_id, 0); - - /* Record the new shared dependencies (roles) */ target.classId = AuthIdRelationId; target.objectSubId = 0; for (i = 0; i < num_roles; i++) @@ -671,18 +539,33 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) heap_freetuple(new_tuple); - /* Invalidate Relation Cache */ - CacheInvalidateRelcache(rel); + /* Make updates visible */ + CommandCounterIncrement(); + + /* + * Invalidate relcache entry for rel the policy belongs to, to force + * redoing any dependent plans. In case of a race condition where the + * rel was just dropped, we need do nothing. + */ + reltup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); + if (HeapTupleIsValid(reltup)) + { + CacheInvalidateRelcacheByTuple(reltup); + ReleaseSysCache(reltup); + } + } + else + { + /* No roles would remain, so drop the policy instead. */ + keep_policy = false; } /* Clean up. */ systable_endscan(sscan); - relation_close(rel, NoLock); - table_close(pg_policy_rel, RowExclusiveLock); - return (noperm || num_roles > 0); + return keep_policy; } /* @@ -694,6 +577,14 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) ObjectAddress CreatePolicy(CreatePolicyStmt *stmt) { + /* + * GPDB: dispatch a pristine copy of the statement. Transforming the + * quals below replaces SubLink.subselect with the transformed Query + * in place, and a QE re-transforming that fails with "unexpected + * non-SELECT command in SubLink". + */ + CreatePolicyStmt *dispatchStmt = + (Gp_role == GP_ROLE_DISPATCH) ? copyObject(stmt) : NULL; Relation pg_policy_rel; Oid policy_id; Relation target_table; @@ -772,12 +663,12 @@ CreatePolicy(CreatePolicyStmt *stmt) addNSItemToQuery(with_check_pstate, nsitem, false, true, true); qual = transformWhereClause(qual_pstate, - copyObject(stmt->qual), + stmt->qual, EXPR_KIND_POLICY, "POLICY"); with_check_qual = transformWhereClause(with_check_pstate, - copyObject(stmt->with_check), + stmt->with_check, EXPR_KIND_POLICY, "POLICY"); @@ -887,7 +778,7 @@ CreatePolicy(CreatePolicyStmt *stmt) { Assert(stmt->type == T_CreatePolicyStmt); Assert(stmt->type < 1000); - CdbDispatchUtilityStatement((Node *) stmt, + CdbDispatchUtilityStatement((Node *) dispatchStmt, DF_CANCEL_ON_ERROR| DF_WITH_SNAPSHOT| DF_NEED_TWO_PHASE, @@ -910,6 +801,9 @@ CreatePolicy(CreatePolicyStmt *stmt) ObjectAddress AlterPolicy(AlterPolicyStmt *stmt) { + /* GPDB: see CreatePolicy; dispatch an untransformed copy */ + AlterPolicyStmt *dispatchStmt = + (Gp_role == GP_ROLE_DISPATCH) ? copyObject(stmt) : NULL; Relation pg_policy_rel; Oid policy_id; Relation target_table; @@ -963,7 +857,7 @@ AlterPolicy(AlterPolicyStmt *stmt) addNSItemToQuery(qual_pstate, nsitem, false, true, true); - qual = transformWhereClause(qual_pstate, copyObject(stmt->qual), + qual = transformWhereClause(qual_pstate, stmt->qual, EXPR_KIND_POLICY, "POLICY"); @@ -987,7 +881,7 @@ AlterPolicy(AlterPolicyStmt *stmt) addNSItemToQuery(with_check_pstate, nsitem, false, true, true); with_check_qual = transformWhereClause(with_check_pstate, - copyObject(stmt->with_check), + stmt->with_check, EXPR_KIND_POLICY, "POLICY"); @@ -1233,7 +1127,7 @@ AlterPolicy(AlterPolicyStmt *stmt) { Assert(stmt->type == T_AlterPolicyStmt); Assert(stmt->type < 1000); - CdbDispatchUtilityStatement((Node *) stmt, + CdbDispatchUtilityStatement((Node *) dispatchStmt, DF_CANCEL_ON_ERROR| DF_WITH_SNAPSHOT| DF_NEED_TWO_PHASE, diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index 421527c0ab81..b4b676d6386d 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -11,7 +11,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,6 +29,7 @@ #include "commands/portalcmds.h" #include "executor/executor.h" #include "executor/tstoreReceiver.h" +#include "miscadmin.h" #include "rewrite/rewriteHandler.h" #include "miscadmin.h" #include "port/atomics.h" @@ -87,14 +88,8 @@ PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo pa * rewriter. We do not do AcquireRewriteLocks: we assume the query either * came straight from the parser, or suitable locks were acquired by * plancache.c. - * - * Because the rewriter and planner tend to scribble on the input, we make - * a preliminary copy of the source querytree. This prevents problems in - * the case that the DECLARE CURSOR is in a portal or plpgsql function and - * is executed repeatedly. (See also the same hack in EXPLAIN and - * PREPARE.) XXX FIXME someday. */ - rewritten = QueryRewrite((Query *) copyObject(query)); + rewritten = QueryRewrite(query); /* SELECT should never rewrite to more or less than one query */ if (list_length(rewritten) != 1) @@ -479,8 +474,11 @@ PersistHoldablePortal(Portal portal) PushActiveSnapshot(queryDesc->snapshot); /* - * Rewind the executor: we need to store the entire result set in the - * tuplestore, so that subsequent backward FETCHs can be processed. + * If the portal is marked scrollable, we need to store the entire + * result set in the tuplestore, so that subsequent backward FETCHs + * can be processed. Otherwise, store only the not-yet-fetched rows. + * (The latter is not only more efficient, but avoids semantic + * problems if the query's output isn't stable.) */ /* * We don't allow scanning backwards in MPP! skip this call and @@ -488,6 +486,17 @@ PersistHoldablePortal(Portal portal) */ if (Gp_role == GP_ROLE_UTILITY) ExecutorRewind(queryDesc); + if (portal->cursorOptions & CURSOR_OPT_SCROLL) + { + ExecutorRewind(queryDesc); + } + else + { + /* We must reset the cursor state as though at start of query */ + portal->atStart = true; + portal->atEnd = false; + portal->portalPos = 0; + } /* * Change the destination to output to the tuplestore. Note we tell diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c index 79227165b9ef..7e76c1396abf 100644 --- a/src/backend/commands/prepare.c +++ b/src/backend/commands/prepare.c @@ -7,7 +7,7 @@ * accessed via the extended FE/BE query protocol. * * - * Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Copyright (c) 2002-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/commands/prepare.c @@ -79,12 +79,9 @@ PrepareQuery(ParseState *pstate, PrepareStmt *stmt, /* * Need to wrap the contained statement in a RawStmt node to pass it to * parse analysis. - * - * Because parse analysis scribbles on the raw querytree, we must make a - * copy to ensure we don't modify the passed-in tree. FIXME someday. */ rawstmt = makeNode(RawStmt); - rawstmt->stmt = (Node *) copyObject(stmt->query); + rawstmt->stmt = stmt->query; rawstmt->stmt_location = stmt_location; rawstmt->stmt_len = stmt_len; @@ -239,14 +236,30 @@ ExecuteQuery(ParseState *pstate, entry->plansource->query_string); /* Replan if needed, and increment plan refcount for portal */ - cplan = GetCachedPlan(entry->plansource, paramLI, false, NULL, intoClause); + cplan = GetCachedPlan(entry->plansource, paramLI, NULL, NULL, intoClause); plan_list = cplan->stmt_list; /* - * For CREATE TABLE / AS EXECUTE, we must make a copy of the stored query - * so that we can modify its destination (yech, but this has always been - * ugly). For regular EXECUTE we can just use the cached query, since the - * executor is read-only. + * DO NOT add any logic that could possibly throw an error between + * GetCachedPlan and PortalDefineQuery, or you'll leak the plan refcount. + */ + PortalDefineQuery(portal, + NULL, + query_string, + entry->plansource->sourceTag, + entry->plansource->commandTag, + plan_list, + cplan); + + /* + * For CREATE TABLE ... AS EXECUTE, we must verify that the prepared + * statement is one that produces tuples. Currently we insist that it be + * a plain old SELECT. In future we might consider supporting other + * things such as INSERT ... RETURNING, but there are a couple of issues + * to be settled first, notably how WITH NO DATA should be handled in such + * a case (do we really want to suppress execution?) and how to pass down + * the OID-determining eflags (PortalStart won't handle them in such a + * case, and for that matter it's not clear the executor will either). * * In GPDB, we use the current parameter values in the planning, because * that potentially gives a better plan. It also means that we have to @@ -295,16 +308,10 @@ ExecuteQuery(ParseState *pstate, count = FETCH_ALL; } - PortalDefineQuery(portal, - NULL, - query_string, - entry->plansource->sourceTag, - entry->plansource->commandTag, - plan_list, - cplan); - /* - * Run the portal as appropriate. + * Run the portal as appropriate. (Note: PortalDefineQuery was already + * called above, right after GetCachedPlan; the GPDB into-clause handling + * mutates the plan in place, so it needs no second PortalDefineQuery.) */ PortalStart(portal, paramLI, eflags, GetActiveSnapshot(), NULL); @@ -426,15 +433,13 @@ InitQueryHashTable(void) { HASHCTL hash_ctl; - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); - hash_ctl.keysize = NAMEDATALEN; hash_ctl.entrysize = sizeof(PreparedStatement); prepared_queries = hash_create("Prepared Queries", 32, &hash_ctl, - HASH_ELEM); + HASH_ELEM | HASH_STRINGS); } /* @@ -698,7 +703,8 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, } /* Replan if needed, and acquire a transient refcount */ - cplan = GetCachedPlan(entry->plansource, paramLI, true, queryEnv, into); + cplan = GetCachedPlan(entry->plansource, paramLI, + CurrentResourceOwner, queryEnv, into); INSTR_TIME_SET_CURRENT(planduration); INSTR_TIME_SUBTRACT(planduration, planstart); @@ -718,8 +724,28 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, PlannedStmt *pstmt = lfirst_node(PlannedStmt, p); if (pstmt->commandType != CMD_UTILITY) + { + /* + * GPDB: CREATE TABLE AS / SELECT INTO ... EXECUTE creates the + * target relation in intorel_initplan(), which is driven off + * PlannedStmt->intoClause (see execMain.c). Unlike the + * freshly-planned path (ExplainOneQuery), the cached plan reached + * here does not carry the IntoClause, so without it intorel_initplan + * is skipped, the DestReceiver's rel stays NULL and the executor + * SIGSEGVs in intorel_startup_dummy. Set the IntoClause -- on a + * copy, since the PlannedStmt belongs to the shared cached plan and + * a stale IntoClause would make a later plain EXECUTE create a + * table. + */ + if (into != NULL) + { + pstmt = copyObject(pstmt); + pstmt->intoClause = copyObject(into); + } + ExplainOnePlan(pstmt, into, es, query_string, paramLI, queryEnv, &planduration, (es->buffers ? &bufusage : NULL), 0); + } else ExplainOneUtility(pstmt->utilityStmt, into, es, query_string, paramLI, queryEnv); @@ -734,7 +760,7 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, if (estate) FreeExecutorState(estate); - ReleaseCachedPlan(cplan, true); + ReleaseCachedPlan(cplan, CurrentResourceOwner); } /* diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 2730e8203fc3..3c0e0b662ca0 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -3,7 +3,7 @@ * proclang.c * PostgreSQL LANGUAGE support code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -61,6 +61,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) bool is_update; ObjectAddress myself, referenced; + ObjectAddresses *addrs; /* * Check permission @@ -191,30 +192,29 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, is_update); + addrs = new_object_addresses(); + /* dependency on the PL handler function */ - referenced.classId = ProcedureRelationId; - referenced.objectId = handlerOid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, ProcedureRelationId, handlerOid); + add_exact_object_address(&referenced, addrs); /* dependency on the inline handler function, if any */ if (OidIsValid(inlineOid)) { - referenced.classId = ProcedureRelationId; - referenced.objectId = inlineOid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, ProcedureRelationId, inlineOid); + add_exact_object_address(&referenced, addrs); } /* dependency on the validator function, if any */ if (OidIsValid(valOid)) { - referenced.classId = ProcedureRelationId; - referenced.objectId = valOid; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, ProcedureRelationId, valOid); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + /* Post creation hook for new procedural language */ InvokeObjectPostCreateHook(LanguageRelationId, myself.objectId, 0); diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 880439392ff9..db833b0ed585 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -3,7 +3,7 @@ * publicationcmds.c * publication manipulation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/commands/resgroupcmds.c b/src/backend/commands/resgroupcmds.c index 59ce708f14ef..969ade9d90c0 100644 --- a/src/backend/commands/resgroupcmds.c +++ b/src/backend/commands/resgroupcmds.c @@ -1586,12 +1586,18 @@ checkCpuSetByRole(const char *cpuset) { char **arraycpuset = (char **)palloc0(sizeof(char *) * CpuSetArrayLength); char *copycpuset = (char *)palloc0(sizeof(char) * MaxCpuSetLength); + + if (strlen(cpuset) >= MaxCpuSetLength) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("the length of cpuset reached the upper limit %d", + MaxCpuSetLength))); strcpy(copycpuset, cpuset); int cnt = 0; - for (int i = 0; i < sizeof(cpuset); i++) + for (const char *p = cpuset; *p != '\0'; p++) { - if (cpuset[i] == ';') + if (*p == ';') cnt++; } diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index 7b7012dd8240..d0f66d5a3ade 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -265,6 +265,7 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString, /* do this step */ ProcessUtility(wrapper, queryString, + false, PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c index 69f007cc0705..788a1b110efc 100644 --- a/src/backend/commands/seclabel.c +++ b/src/backend/commands/seclabel.c @@ -3,7 +3,7 @@ * seclabel.c * routines to support security label feature. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------- diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 552450122c8f..17803f31f1a1 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -687,6 +687,14 @@ nextval_qd(Oid relid, int64 *plast, int64 *pcached, int64 *pincrement, bool *po *pcached = last_used_seq->cached; *pincrement = last_used_seq->increment; *poverflow = !last_used_seq->last_valid; + + /* + * The whole window [last, cached] now belongs to the requesting QE. + * Mark the QD's local cache exhausted, or a subsequent local nextval() + * would hand out values from inside the granted range and produce + * duplicate sequence values (sequence_gp's check_no_duplicates case). + */ + last_used_seq->last = last_used_seq->cached; } int64 @@ -1240,8 +1248,7 @@ create_seq_hashtable(void) { HASHCTL ctl; - memset(&ctl, 0, sizeof(ctl)); - ctl.keysize = sizeof(struct SeqTableKey); + ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(SeqTableData); seqhashtab = hash_create("Sequence values", 16, &ctl, @@ -1842,7 +1849,7 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity) /* Separate relname and attr name */ relname = list_truncate(list_copy(owned_by), nnames - 1); - attrname = strVal(lfirst(list_tail(owned_by))); + attrname = strVal(llast(owned_by)); /* Open and lock rel to ensure it won't go away meanwhile */ rel = makeRangeVarFromNameList(relname); diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c index f3912e48ef7b..d420e704202e 100644 --- a/src/backend/commands/statscmds.c +++ b/src/backend/commands/statscmds.c @@ -3,7 +3,7 @@ * statscmds.c * Commands for creating and altering extended statistics objects * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,6 +29,8 @@ #include "commands/comment.h" #include "commands/defrem.h" #include "miscadmin.h" +#include "nodes/nodeFuncs.h" +#include "optimizer/optimizer.h" #include "statistics/statistics.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -62,7 +64,8 @@ ObjectAddress CreateStatistics(CreateStatsStmt *stmt) { int16 attnums[STATS_MAX_DIMENSIONS]; - int numcols = 0; + int nattnums = 0; + int numcols; char *namestr; NameData stxname; Oid statoid; @@ -74,21 +77,25 @@ CreateStatistics(CreateStatsStmt *stmt) Datum datavalues[Natts_pg_statistic_ext_data]; bool datanulls[Natts_pg_statistic_ext_data]; int2vector *stxkeys; + List *stxexprs = NIL; + Datum exprsDatum; Relation statrel; Relation datarel; Relation rel = NULL; Oid relid; ObjectAddress parentobject, myself; - Datum types[3]; /* one for each possible type of statistic */ + Datum types[4]; /* one for each possible type of statistic */ int ntypes; ArrayType *stxkind; bool build_ndistinct; bool build_dependencies; bool build_mcv; + bool build_expressions; bool requested_type = false; int i; ListCell *cell; + ListCell *cell2; Assert(IsA(stmt, CreateStatsStmt)); @@ -135,6 +142,13 @@ CreateStatistics(CreateStatsStmt *stmt) if (!pg_class_ownercheck(RelationGetRelid(rel), stxowner)) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); + + /* Creating statistics on system catalogs is not allowed */ + if (!allowSystemTableMods && IsSystemRelation(rel)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission denied: \"%s\" is a system catalog", + RelationGetRelationName(rel)))); } Assert(rel); @@ -187,101 +201,113 @@ CreateStatistics(CreateStatsStmt *stmt) } /* - * Currently, we only allow simple column references in the expression - * list. That will change someday, and again the grammar already supports - * it so we have to enforce restrictions here. For now, we can convert - * the expression list to a simple array of attnums. While at it, enforce - * some constraints. + * Make sure no more than STATS_MAX_DIMENSIONS columns are used. There + * might be duplicates and so on, but we'll deal with those later. + */ + numcols = list_length(stmt->exprs); + if (numcols > STATS_MAX_DIMENSIONS) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_COLUMNS), + errmsg("cannot have more than %d columns in statistics", + STATS_MAX_DIMENSIONS))); + + /* + * Convert the expression list to a simple array of attnums, but also keep + * a list of more complex expressions. While at it, enforce some + * constraints. + * + * XXX We do only the bare minimum to separate simple attribute and + * complex expressions - for example "(a)" will be treated as a complex + * expression. No matter how elaborate the check is, there'll always be a + * way around it, if the user is determined (consider e.g. "(a+0)"), so + * it's not worth protecting against it. */ foreach(cell, stmt->exprs) { - Node *expr = (Node *) lfirst(cell); - ColumnRef *cref; - char *attname; - HeapTuple atttuple; - Form_pg_attribute attForm; - TypeCacheEntry *type; - - if (!IsA(expr, ColumnRef)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("only simple column references are allowed in CREATE STATISTICS"))); - cref = (ColumnRef *) expr; + StatsElem *selem = lfirst_node(StatsElem, cell); - if (list_length(cref->fields) != 1) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("only simple column references are allowed in CREATE STATISTICS"))); - attname = strVal((Value *) linitial(cref->fields)); - - atttuple = SearchSysCacheAttName(relid, attname); - if (!HeapTupleIsValid(atttuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" does not exist", - attname))); - attForm = (Form_pg_attribute) GETSTRUCT(atttuple); - - /* Disallow use of system attributes in extended stats */ - if (attForm->attnum <= 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("statistics creation on system columns is not supported"))); - - /* Disallow data types without a less-than operator */ - type = lookup_type_cache(attForm->atttypid, TYPECACHE_LT_OPR); - if (type->lt_opr == InvalidOid) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("column \"%s\" cannot be used in statistics because its type %s has no default btree operator class", - attname, format_type_be(attForm->atttypid)))); + if (selem->name) /* column reference */ + { + char *attname; + HeapTuple atttuple; + Form_pg_attribute attForm; + TypeCacheEntry *type; + + attname = selem->name; + + atttuple = SearchSysCacheAttName(relid, attname); + if (!HeapTupleIsValid(atttuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" does not exist", + attname))); + attForm = (Form_pg_attribute) GETSTRUCT(atttuple); + + /* Disallow use of system attributes in extended stats */ + if (attForm->attnum <= 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("statistics creation on system columns is not supported"))); + + /* Disallow data types without a less-than operator */ + type = lookup_type_cache(attForm->atttypid, TYPECACHE_LT_OPR); + if (type->lt_opr == InvalidOid) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("column \"%s\" cannot be used in statistics because its type %s has no default btree operator class", + attname, format_type_be(attForm->atttypid)))); + + attnums[nattnums] = attForm->attnum; + nattnums++; + ReleaseSysCache(atttuple); + } + else /* expression */ + { + Node *expr = selem->expr; + Oid atttype; + TypeCacheEntry *type; - /* Make sure no more than STATS_MAX_DIMENSIONS columns are used */ - if (numcols >= STATS_MAX_DIMENSIONS) - ereport(ERROR, - (errcode(ERRCODE_TOO_MANY_COLUMNS), - errmsg("cannot have more than %d columns in statistics", - STATS_MAX_DIMENSIONS))); + Assert(expr != NULL); - attnums[numcols] = attForm->attnum; - numcols++; - ReleaseSysCache(atttuple); + /* + * Disallow data types without a less-than operator. + * + * We ignore this for statistics on a single expression, in which + * case we'll build the regular statistics only (and that code can + * deal with such data types). + */ + if (list_length(stmt->exprs) > 1) + { + atttype = exprType(expr); + type = lookup_type_cache(atttype, TYPECACHE_LT_OPR); + if (type->lt_opr == InvalidOid) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("expression cannot be used in multivariate statistics because its type %s has no default btree operator class", + format_type_be(atttype)))); + } + + stxexprs = lappend(stxexprs, expr); + } } /* - * Check that at least two columns were specified in the statement. The - * upper bound was already checked in the loop above. - */ - if (numcols < 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("extended statistics require at least 2 columns"))); - - /* - * Sort the attnums, which makes detecting duplicates somewhat easier, and - * it does not hurt (it does not affect the efficiency, unlike for - * indexes, for example). - */ - qsort(attnums, numcols, sizeof(int16), compare_int16); - - /* - * Check for duplicates in the list of columns. The attnums are sorted so - * just check consecutive elements. + * Parse the statistics kinds. + * + * First check that if this is the case with a single expression, there + * are no statistics kinds specified (we don't allow that for the simple + * CREATE STATISTICS form). */ - for (i = 1; i < numcols; i++) + if ((list_length(stmt->exprs) == 1) && (list_length(stxexprs) == 1)) { - if (attnums[i] == attnums[i - 1]) + /* statistics kinds not specified */ + if (list_length(stmt->stat_types) > 0) ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_COLUMN), - errmsg("duplicate column name in statistics definition"))); + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("when building statistics on a single expression, statistics kinds may not be specified"))); } - /* Form an int2vector representation of the sorted column list */ - stxkeys = buildint2vector(attnums, numcols); - - /* - * Parse the statistics kinds. - */ + /* OK, let's check that we recognize the statistics kinds. */ build_ndistinct = false; build_dependencies = false; build_mcv = false; @@ -310,14 +336,91 @@ CreateStatistics(CreateStatsStmt *stmt) errmsg("unrecognized statistics kind \"%s\"", type))); } - /* If no statistic type was specified, build them all. */ - if (!requested_type) + + /* + * If no statistic type was specified, build them all (but only when the + * statistics is defined on more than one column/expression). + */ + if ((!requested_type) && (numcols >= 2)) { build_ndistinct = true; build_dependencies = true; build_mcv = true; } + /* + * When there are non-trivial expressions, build the expression stats + * automatically. This allows calculating good estimates for stats that + * consider per-clause estimates (e.g. functional dependencies). + */ + build_expressions = (list_length(stxexprs) > 0); + + /* + * Check that at least two columns were specified in the statement, or + * that we're building statistics on a single expression. + */ + if ((numcols < 2) && (list_length(stxexprs) != 1)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("extended statistics require at least 2 columns"))); + + /* + * Sort the attnums, which makes detecting duplicates somewhat easier, and + * it does not hurt (it does not matter for the contents, unlike for + * indexes, for example). + */ + qsort(attnums, nattnums, sizeof(int16), compare_int16); + + /* + * Check for duplicates in the list of columns. The attnums are sorted so + * just check consecutive elements. + */ + for (i = 1; i < nattnums; i++) + { + if (attnums[i] == attnums[i - 1]) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_COLUMN), + errmsg("duplicate column name in statistics definition"))); + } + + /* + * Check for duplicate expressions. We do two loops, counting the + * occurrences of each expression. This is O(N^2) but we only allow small + * number of expressions and it's not executed often. + * + * XXX We don't cross-check attributes and expressions, because it does + * not seem worth it. In principle we could check that expressions don't + * contain trivial attribute references like "(a)", but the reasoning is + * similar to why we don't bother with extracting columns from + * expressions. It's either expensive or very easy to defeat for + * determined user, and there's no risk if we allow such statistics (the + * statistics is useless, but harmless). + */ + foreach(cell, stxexprs) + { + Node *expr1 = (Node *) lfirst(cell); + int cnt = 0; + + foreach(cell2, stxexprs) + { + Node *expr2 = (Node *) lfirst(cell2); + + if (equal(expr1, expr2)) + cnt += 1; + } + + /* every expression should find at least itself */ + Assert(cnt >= 1); + + if (cnt > 1) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_COLUMN), + errmsg("duplicate expression in statistics definition"))); + } + + /* Form an int2vector representation of the sorted column list */ + stxkeys = buildint2vector(attnums, nattnums); + /* construct the char array of enabled statistic types */ ntypes = 0; if (build_ndistinct) @@ -326,9 +429,23 @@ CreateStatistics(CreateStatsStmt *stmt) types[ntypes++] = CharGetDatum(STATS_EXT_DEPENDENCIES); if (build_mcv) types[ntypes++] = CharGetDatum(STATS_EXT_MCV); + if (build_expressions) + types[ntypes++] = CharGetDatum(STATS_EXT_EXPRESSIONS); Assert(ntypes > 0 && ntypes <= lengthof(types)); stxkind = construct_array(types, ntypes, CHAROID, 1, true, TYPALIGN_CHAR); + /* convert the expressions (if any) to a text datum */ + if (stxexprs != NIL) + { + char *exprsString; + + exprsString = nodeToString(stxexprs); + exprsDatum = CStringGetTextDatum(exprsString); + pfree(exprsString); + } + else + exprsDatum = (Datum) 0; + statrel = table_open(StatisticExtRelationId, RowExclusiveLock); /* @@ -348,6 +465,10 @@ CreateStatistics(CreateStatsStmt *stmt) values[Anum_pg_statistic_ext_stxkeys - 1] = PointerGetDatum(stxkeys); values[Anum_pg_statistic_ext_stxkind - 1] = PointerGetDatum(stxkind); + values[Anum_pg_statistic_ext_stxexprs - 1] = exprsDatum; + if (exprsDatum == (Datum) 0) + nulls[Anum_pg_statistic_ext_stxexprs - 1] = true; + /* insert it into pg_statistic_ext */ htup = heap_form_tuple(statrel->rd_att, values, nulls); CatalogTupleInsert(statrel, htup); @@ -370,6 +491,7 @@ CreateStatistics(CreateStatsStmt *stmt) datanulls[Anum_pg_statistic_ext_data_stxdndistinct - 1] = true; datanulls[Anum_pg_statistic_ext_data_stxddependencies - 1] = true; datanulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; + datanulls[Anum_pg_statistic_ext_data_stxdexpr - 1] = true; /* insert it into pg_statistic_ext_data */ htup = heap_form_tuple(datarel->rd_att, datavalues, datanulls); @@ -393,12 +515,41 @@ CreateStatistics(CreateStatsStmt *stmt) */ ObjectAddressSet(myself, StatisticExtRelationId, statoid); - for (i = 0; i < numcols; i++) + /* add dependencies for plain column references */ + for (i = 0; i < nattnums; i++) { ObjectAddressSubSet(parentobject, RelationRelationId, relid, attnums[i]); recordDependencyOn(&myself, &parentobject, DEPENDENCY_AUTO); } + /* + * If there are no dependencies on a column, give the statistics an auto + * dependency on the whole table. In most cases, this will be redundant, + * but it might not be if the statistics expressions contain no Vars + * (which might seem strange but possible). This is consistent with what + * we do for indexes in index_create. + * + * XXX We intentionally don't consider the expressions before adding this + * dependency, because recordDependencyOnSingleRelExpr may not create any + * dependencies for whole-row Vars. + */ + if (!nattnums) + { + ObjectAddressSet(parentobject, RelationRelationId, relid); + recordDependencyOn(&myself, &parentobject, DEPENDENCY_AUTO); + } + + /* + * Store dependencies on anything mentioned in statistics expressions, + * just like we do for index expressions. + */ + if (stxexprs) + recordDependencyOnSingleRelExpr(&myself, + (Node *) stxexprs, + relid, + DEPENDENCY_NORMAL, + DEPENDENCY_AUTO, false); + /* * Also add dependencies on namespace and owner. These are required * because the stats object might have a different namespace and/or owner @@ -579,87 +730,6 @@ RemoveStatisticsById(Oid statsOid) table_close(relation, RowExclusiveLock); } -/* - * Update a statistics object for ALTER COLUMN TYPE on a source column. - * - * This could throw an error if the type change can't be supported. - * If it can be supported, but the stats must be recomputed, a likely choice - * would be to set the relevant column(s) of the pg_statistic_ext_data tuple - * to null until the next ANALYZE. (Note that the type change hasn't actually - * happened yet, so one option that's *not* on the table is to recompute - * immediately.) - * - * For both ndistinct and functional-dependencies stats, the on-disk - * representation is independent of the source column data types, and it is - * plausible to assume that the old statistic values will still be good for - * the new column contents. (Obviously, if the ALTER COLUMN TYPE has a USING - * expression that substantially alters the semantic meaning of the column - * values, this assumption could fail. But that seems like a corner case - * that doesn't justify zapping the stats in common cases.) - * - * For MCV lists that's not the case, as those statistics store the datums - * internally. In this case we simply reset the statistics value to NULL. - * - * Note that "type change" includes collation change, which means we can rely - * on the MCV list being consistent with the collation info in pg_attribute - * during estimation. - */ -void -UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum, - Oid oldColumnType, Oid newColumnType) -{ - HeapTuple stup, - oldtup; - - Relation rel; - - Datum values[Natts_pg_statistic_ext_data]; - bool nulls[Natts_pg_statistic_ext_data]; - bool replaces[Natts_pg_statistic_ext_data]; - - oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid)); - if (!HeapTupleIsValid(oldtup)) - elog(ERROR, "cache lookup failed for statistics object %u", statsOid); - - /* - * When none of the defined statistics types contain datum values from the - * table's columns then there's no need to reset the stats. Functional - * dependencies and ndistinct stats should still hold true. - */ - if (!statext_is_kind_built(oldtup, STATS_EXT_MCV)) - { - ReleaseSysCache(oldtup); - return; - } - - /* - * OK, we need to reset some statistics. So let's build the new tuple, - * replacing the affected statistics types with NULL. - */ - memset(nulls, 0, Natts_pg_statistic_ext_data * sizeof(bool)); - memset(replaces, 0, Natts_pg_statistic_ext_data * sizeof(bool)); - memset(values, 0, Natts_pg_statistic_ext_data * sizeof(Datum)); - - replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; - nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; - - rel = table_open(StatisticExtDataRelationId, RowExclusiveLock); - - /* replace the old tuple */ - stup = heap_modify_tuple(oldtup, - RelationGetDescr(rel), - values, - nulls, - replaces); - - ReleaseSysCache(oldtup); - CatalogTupleUpdate(rel, &stup->t_self, stup); - - heap_freetuple(stup); - - table_close(rel, RowExclusiveLock); -} - /* * Select a nonconflicting name for a new statistics. * @@ -728,18 +798,27 @@ ChooseExtendedStatisticNameAddition(List *exprs) buf[0] = '\0'; foreach(lc, exprs) { - ColumnRef *cref = (ColumnRef *) lfirst(lc); + StatsElem *selem = (StatsElem *) lfirst(lc); const char *name; /* It should be one of these, but just skip if it happens not to be */ - if (!IsA(cref, ColumnRef)) + if (!IsA(selem, StatsElem)) continue; - name = strVal((Value *) linitial(cref->fields)); + name = selem->name; if (buflen > 0) buf[buflen++] = '_'; /* insert _ between names */ + /* + * We use fixed 'expr' for expressions, which have empty column names. + * For indexes this is handled in ChooseIndexColumnNames, but we have + * no such function for stats and it does not seem worth adding. If a + * better name is needed, the user can specify it explicitly. + */ + if (!name) + name = "expr"; + /* * At this point we have buflen <= NAMEDATALEN. name should be less * than NAMEDATALEN already, but use strlcpy for paranoia. @@ -751,3 +830,29 @@ ChooseExtendedStatisticNameAddition(List *exprs) } return pstrdup(buf); } + +/* + * StatisticsGetRelation: given a statistics's relation OID, get the OID of + * the relation it is an statistics on. Uses the system cache. + */ +Oid +StatisticsGetRelation(Oid statId, bool missing_ok) +{ + HeapTuple tuple; + Form_pg_statistic_ext stx; + Oid result; + + tuple = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statId)); + if (!HeapTupleIsValid(tuple)) + { + if (missing_ok) + return InvalidOid; + elog(ERROR, "cache lookup failed for statistics object %u", statId); + } + stx = (Form_pg_statistic_ext) GETSTRUCT(tuple); + Assert(stx->oid == statId); + + result = stx->stxrelid; + ReleaseSysCache(tuple); + return result; +} diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index 8ac4ab4ee66d..7a7f44e18bee 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -3,7 +3,7 @@ * subscriptioncmds.c * subscription catalog manipulation functions * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -34,6 +34,7 @@ #include "nodes/makefuncs.h" #include "replication/logicallauncher.h" #include "replication/origin.h" +#include "replication/slot.h" #include "replication/walreceiver.h" #include "replication/walsender.h" #include "replication/worker_internal.h" @@ -51,6 +52,10 @@ #include "cdb/cdbvars.h" static List *fetch_table_list(WalReceiverConn *wrconn, List *publications); +static void check_duplicates_in_publist(List *publist, Datum *datums); +static List *merge_publications(List *oldpublist, List *newpublist, bool addpub, const char *subname); +static void ReportSlotConnectionError(List *rstates, Oid subid, char *slotname, char *err); + /* * Common option parsing function for CREATE and ALTER SUBSCRIPTION commands. @@ -68,7 +73,8 @@ parse_subscription_options(List *options, bool *copy_data, char **synchronous_commit, bool *refresh, - bool *binary_given, bool *binary) + bool *binary_given, bool *binary, + bool *streaming_given, bool *streaming) { ListCell *lc; bool connect_given = false; @@ -104,6 +110,11 @@ parse_subscription_options(List *options, *binary_given = false; *binary = false; } + if (streaming) + { + *streaming_given = false; + *streaming = false; + } /* Parse options */ foreach(lc, options) @@ -199,6 +210,16 @@ parse_subscription_options(List *options, *binary_given = true; *binary = defGetBoolean(defel); } + else if (strcmp(defel->defname, "streaming") == 0 && streaming) + { + if (*streaming_given) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + + *streaming_given = true; + *streaming = defGetBoolean(defel); + } else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -279,8 +300,6 @@ publicationListToArray(List *publist) { ArrayType *arr; Datum *datums; - int j = 0; - ListCell *cell; MemoryContext memcxt; MemoryContext oldcxt; @@ -292,28 +311,7 @@ publicationListToArray(List *publist) datums = (Datum *) palloc(sizeof(Datum) * list_length(publist)); - foreach(cell, publist) - { - char *name = strVal(lfirst(cell)); - ListCell *pcell; - - /* Check for duplicates. */ - foreach(pcell, publist) - { - char *pname = strVal(lfirst(pcell)); - - if (pcell == cell) - break; - - if (strcmp(name, pname) == 0) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("publication name \"%s\" used more than once", - pname))); - } - - datums[j++] = CStringGetTextDatum(name); - } + check_duplicates_in_publist(publist, datums); MemoryContextSwitchTo(oldcxt); @@ -342,6 +340,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) bool enabled_given; bool enabled; bool copy_data; + bool streaming; + bool streaming_given; char *synchronous_commit; char *conninfo; char *slotname; @@ -365,7 +365,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) ©_data, &synchronous_commit, NULL, /* no "refresh" */ - &binary_given, &binary); + &binary_given, &binary, + &streaming_given, &streaming); /* * Since creating a replication slot is not transactional, rolling back @@ -439,6 +440,7 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) values[Anum_pg_subscription_subowner - 1] = ObjectIdGetDatum(owner); values[Anum_pg_subscription_subenabled - 1] = BoolGetDatum(enabled); values[Anum_pg_subscription_subbinary - 1] = BoolGetDatum(binary); + values[Anum_pg_subscription_substream - 1] = BoolGetDatum(streaming); values[Anum_pg_subscription_subconninfo - 1] = CStringGetTextDatum(conninfo); if (slotname) @@ -478,7 +480,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) wrconn = walrcv_connect(conninfo, true, stmt->subname, &err); if (!wrconn) ereport(ERROR, - (errmsg("could not connect to the publisher: %s", err))); + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not connect to the publisher: %s", err))); PG_TRY(); { @@ -574,6 +577,15 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data) Oid *pubrel_local_oids; ListCell *lc; int off; + int remove_rel_len; + Relation rel = NULL; + typedef struct SubRemoveRels + { + Oid relid; + char state; + } SubRemoveRels; + SubRemoveRels *sub_remove_rels; + WalReceiverConn *wrconn; /* Load the library providing us libpq calls. */ /* @@ -588,99 +600,193 @@ AlterSubscription_refresh(Subscription *sub, bool copy_data) wrconn = walrcv_connect(sub->conninfo, true, sub->name, &err); if (!wrconn) ereport(ERROR, - (errmsg("could not connect to the publisher: %s", err))); + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not connect to the publisher: %s", err))); - /* Get the table list from publisher. */ - pubrel_names = fetch_table_list(wrconn, sub->publications); - - /* We are done with the remote side, close connection. */ - walrcv_disconnect(wrconn); - - /* Get local table list. */ - subrel_states = GetSubscriptionRelations(sub->oid); - - /* - * Build qsorted array of local table oids for faster lookup. This can - * potentially contain all tables in the database so speed of lookup is - * important. - */ - subrel_local_oids = palloc(list_length(subrel_states) * sizeof(Oid)); - off = 0; - foreach(lc, subrel_states) + PG_TRY(); { - SubscriptionRelState *relstate = (SubscriptionRelState *) lfirst(lc); + /* Get the table list from publisher. */ + pubrel_names = fetch_table_list(wrconn, sub->publications); + + /* Get local table list. */ + subrel_states = GetSubscriptionRelations(sub->oid); + + /* + * Build qsorted array of local table oids for faster lookup. This can + * potentially contain all tables in the database so speed of lookup + * is important. + */ + subrel_local_oids = palloc(list_length(subrel_states) * sizeof(Oid)); + off = 0; + foreach(lc, subrel_states) + { + SubscriptionRelState *relstate = (SubscriptionRelState *) lfirst(lc); - subrel_local_oids[off++] = relstate->relid; - } - qsort(subrel_local_oids, list_length(subrel_states), - sizeof(Oid), oid_cmp); + subrel_local_oids[off++] = relstate->relid; + } + qsort(subrel_local_oids, list_length(subrel_states), + sizeof(Oid), oid_cmp); + + /* + * Rels that we want to remove from subscription and drop any slots + * and origins corresponding to them. + */ + sub_remove_rels = palloc(list_length(subrel_states) * sizeof(SubRemoveRels)); + + /* + * Walk over the remote tables and try to match them to locally known + * tables. If the table is not known locally create a new state for + * it. + * + * Also builds array of local oids of remote tables for the next step. + */ + off = 0; + pubrel_local_oids = palloc(list_length(pubrel_names) * sizeof(Oid)); + + foreach(lc, pubrel_names) + { + RangeVar *rv = (RangeVar *) lfirst(lc); + Oid relid; - /* - * Walk over the remote tables and try to match them to locally known - * tables. If the table is not known locally create a new state for it. - * - * Also builds array of local oids of remote tables for the next step. - */ - off = 0; - pubrel_local_oids = palloc(list_length(pubrel_names) * sizeof(Oid)); + relid = RangeVarGetRelid(rv, AccessShareLock, false); - foreach(lc, pubrel_names) - { - RangeVar *rv = (RangeVar *) lfirst(lc); - Oid relid; + /* Check for supported relkind. */ + CheckSubscriptionRelkind(get_rel_relkind(relid), + rv->schemaname, rv->relname); - relid = RangeVarGetRelid(rv, AccessShareLock, false); + pubrel_local_oids[off++] = relid; - /* Check for supported relkind. */ - CheckSubscriptionRelkind(get_rel_relkind(relid), - rv->schemaname, rv->relname); + if (!bsearch(&relid, subrel_local_oids, + list_length(subrel_states), sizeof(Oid), oid_cmp)) + { + AddSubscriptionRelState(sub->oid, relid, + copy_data ? SUBREL_STATE_INIT : SUBREL_STATE_READY, + InvalidXLogRecPtr); + ereport(DEBUG1, + (errmsg_internal("table \"%s.%s\" added to subscription \"%s\"", + rv->schemaname, rv->relname, sub->name))); + } + } - pubrel_local_oids[off++] = relid; + /* + * Next remove state for tables we should not care about anymore using + * the data we collected above + */ + qsort(pubrel_local_oids, list_length(pubrel_names), + sizeof(Oid), oid_cmp); - if (!bsearch(&relid, subrel_local_oids, - list_length(subrel_states), sizeof(Oid), oid_cmp)) + remove_rel_len = 0; + for (off = 0; off < list_length(subrel_states); off++) { - AddSubscriptionRelState(sub->oid, relid, - copy_data ? SUBREL_STATE_INIT : SUBREL_STATE_READY, - InvalidXLogRecPtr); - ereport(DEBUG1, - (errmsg("table \"%s.%s\" added to subscription \"%s\"", - rv->schemaname, rv->relname, sub->name))); - } - } + Oid relid = subrel_local_oids[off]; - /* - * Next remove state for tables we should not care about anymore using the - * data we collected above - */ - qsort(pubrel_local_oids, list_length(pubrel_names), - sizeof(Oid), oid_cmp); + if (!bsearch(&relid, pubrel_local_oids, + list_length(pubrel_names), sizeof(Oid), oid_cmp)) + { + char state; + XLogRecPtr statelsn; + + /* + * Lock pg_subscription_rel with AccessExclusiveLock to + * prevent any race conditions with the apply worker + * re-launching workers at the same time this code is trying + * to remove those tables. + * + * Even if new worker for this particular rel is restarted it + * won't be able to make any progress as we hold exclusive + * lock on subscription_rel till the transaction end. It will + * simply exit as there is no corresponding rel entry. + * + * This locking also ensures that the state of rels won't + * change till we are done with this refresh operation. + */ + if (!rel) + rel = table_open(SubscriptionRelRelationId, AccessExclusiveLock); + + /* Last known rel state. */ + state = GetSubscriptionRelState(sub->oid, relid, &statelsn); + + sub_remove_rels[remove_rel_len].relid = relid; + sub_remove_rels[remove_rel_len++].state = state; + + RemoveSubscriptionRel(sub->oid, relid); + + logicalrep_worker_stop(sub->oid, relid); + + /* + * For READY state, we would have already dropped the + * tablesync origin. + */ + if (state != SUBREL_STATE_READY) + { + char originname[NAMEDATALEN]; + + /* + * Drop the tablesync's origin tracking if exists. + * + * It is possible that the origin is not yet created for + * tablesync worker, this can happen for the states before + * SUBREL_STATE_FINISHEDCOPY. The apply worker can also + * concurrently try to drop the origin and by this time + * the origin might be already removed. For these reasons, + * passing missing_ok = true. + */ + ReplicationOriginNameForTablesync(sub->oid, relid, originname, + sizeof(originname)); + replorigin_drop_by_name(originname, true, false); + } - for (off = 0; off < list_length(subrel_states); off++) - { - Oid relid = subrel_local_oids[off]; + ereport(DEBUG1, + (errmsg_internal("table \"%s.%s\" removed from subscription \"%s\"", + get_namespace_name(get_rel_namespace(relid)), + get_rel_name(relid), + sub->name))); + } + } - if (!bsearch(&relid, pubrel_local_oids, - list_length(pubrel_names), sizeof(Oid), oid_cmp)) + /* + * Drop the tablesync slots associated with removed tables. This has + * to be at the end because otherwise if there is an error while doing + * the database operations we won't be able to rollback dropped slots. + */ + for (off = 0; off < remove_rel_len; off++) { - RemoveSubscriptionRel(sub->oid, relid); - - logicalrep_worker_stop_at_commit(sub->oid, relid); - - ereport(DEBUG1, - (errmsg("table \"%s.%s\" removed from subscription \"%s\"", - get_namespace_name(get_rel_namespace(relid)), - get_rel_name(relid), - sub->name))); + if (sub_remove_rels[off].state != SUBREL_STATE_READY && + sub_remove_rels[off].state != SUBREL_STATE_SYNCDONE) + { + char syncslotname[NAMEDATALEN] = {0}; + + /* + * For READY/SYNCDONE states we know the tablesync slot has + * already been dropped by the tablesync worker. + * + * For other states, there is no certainty, maybe the slot + * does not exist yet. Also, if we fail after removing some of + * the slots, next time, it will again try to drop already + * dropped slots and fail. For these reasons, we allow + * missing_ok = true for the drop. + */ + ReplicationSlotNameForTablesync(sub->oid, sub_remove_rels[off].relid, + syncslotname, sizeof(syncslotname)); + ReplicationSlotDropAtPubNode(wrconn, syncslotname, true); + } } } + PG_FINALLY(); + { + walrcv_disconnect(wrconn); + } + PG_END_TRY(); + + if (rel) + table_close(rel, NoLock); } /* * Alter the existing subscription. */ ObjectAddress -AlterSubscription(AlterSubscriptionStmt *stmt) +AlterSubscription(AlterSubscriptionStmt *stmt, bool isTopLevel) { Relation rel; ObjectAddress myself; @@ -732,6 +838,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt) char *synchronous_commit; bool binary_given; bool binary; + bool streaming_given; + bool streaming; parse_subscription_options(stmt->options, NULL, /* no "connect" */ @@ -741,13 +849,14 @@ AlterSubscription(AlterSubscriptionStmt *stmt) NULL, /* no "copy_data" */ &synchronous_commit, NULL, /* no "refresh" */ - &binary_given, &binary); + &binary_given, &binary, + &streaming_given, &streaming); if (slotname_given) { if (sub->enabled && !slotname) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot set %s for enabled subscription", "slot_name = NONE"))); @@ -773,6 +882,13 @@ AlterSubscription(AlterSubscriptionStmt *stmt) replaces[Anum_pg_subscription_subbinary - 1] = true; } + if (streaming_given) + { + values[Anum_pg_subscription_substream - 1] = + BoolGetDatum(streaming); + replaces[Anum_pg_subscription_substream - 1] = true; + } + update_tuple = true; break; } @@ -790,12 +906,13 @@ AlterSubscription(AlterSubscriptionStmt *stmt) NULL, /* no "copy_data" */ NULL, /* no "synchronous_commit" */ NULL, /* no "refresh" */ - NULL, NULL); /* no "binary" */ + NULL, NULL, /* no "binary" */ + NULL, NULL); /* no streaming */ Assert(enabled_given); if (!sub->slotname && enabled) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot enable subscription that does not have a slot name"))); values[Anum_pg_subscription_subenabled - 1] = @@ -827,7 +944,7 @@ AlterSubscription(AlterSubscriptionStmt *stmt) update_tuple = true; break; - case ALTER_SUBSCRIPTION_PUBLICATION: + case ALTER_SUBSCRIPTION_SET_PUBLICATION: { bool copy_data; bool refresh; @@ -840,8 +957,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt) ©_data, NULL, /* no "synchronous_commit" */ &refresh, - NULL, NULL); /* no "binary" */ - + NULL, NULL, /* no "binary" */ + NULL, NULL); /* no "streaming" */ values[Anum_pg_subscription_subpublications - 1] = publicationListToArray(stmt->publication); replaces[Anum_pg_subscription_subpublications - 1] = true; @@ -853,10 +970,12 @@ AlterSubscription(AlterSubscriptionStmt *stmt) { if (!sub->enabled) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions"), errhint("Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)."))); + PreventInTransactionBlock(isTopLevel, "ALTER SUBSCRIPTION with refresh"); + /* Make sure refresh sees the new list of publications. */ sub->publications = stmt->publication; @@ -866,13 +985,61 @@ AlterSubscription(AlterSubscriptionStmt *stmt) break; } + case ALTER_SUBSCRIPTION_ADD_PUBLICATION: + case ALTER_SUBSCRIPTION_DROP_PUBLICATION: + { + bool isadd = stmt->kind == ALTER_SUBSCRIPTION_ADD_PUBLICATION; + bool copy_data = false; + bool refresh; + List *publist; + + parse_subscription_options(stmt->options, + NULL, /* no "connect" */ + NULL, NULL, /* no "enabled" */ + NULL, /* no "create_slot" */ + NULL, NULL, /* no "slot_name" */ + isadd ? ©_data : NULL, /* for drop, no + * "copy_data" */ + NULL, /* no "synchronous_commit" */ + &refresh, + NULL, NULL, /* no "binary" */ + NULL, NULL); /* no "streaming" */ + + publist = merge_publications(sub->publications, stmt->publication, isadd, stmt->subname); + + values[Anum_pg_subscription_subpublications - 1] = + publicationListToArray(publist); + replaces[Anum_pg_subscription_subpublications - 1] = true; + + update_tuple = true; + + /* Refresh if user asked us to. */ + if (refresh) + { + if (!sub->enabled) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions"), + errhint("Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)."))); + + PreventInTransactionBlock(isTopLevel, "ALTER SUBSCRIPTION with refresh"); + + /* Only refresh the added/dropped list of publications. */ + sub->publications = stmt->publication; + + AlterSubscription_refresh(sub, copy_data); + } + + break; + } + case ALTER_SUBSCRIPTION_REFRESH: { bool copy_data; if (!sub->enabled) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions"))); parse_subscription_options(stmt->options, @@ -883,7 +1050,10 @@ AlterSubscription(AlterSubscriptionStmt *stmt) ©_data, NULL, /* no "synchronous_commit" */ NULL, /* no "refresh" */ - NULL, NULL); /* no "binary" */ + NULL, NULL, /* no "binary" */ + NULL, NULL); /* no "streaming" */ + + PreventInTransactionBlock(isTopLevel, "ALTER SUBSCRIPTION ... REFRESH"); AlterSubscription_refresh(sub, copy_data); @@ -950,10 +1120,9 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) ListCell *lc; char originname[NAMEDATALEN]; char *err = NULL; - RepOriginId originid; - WalReceiverConn *wrconn = NULL; - StringInfoData cmd; + WalReceiverConn *wrconn; Form_pg_subscription form; + List *rstates; /* * Lock pg_subscription with AccessExclusiveLock to ensure that the @@ -1066,6 +1235,37 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) } list_free(subworkers); + /* + * Cleanup of tablesync replication origins. + * + * Any READY-state relations would already have dealt with clean-ups. + * + * Note that the state can't change because we have already stopped both + * the apply and tablesync workers and they can't restart because of + * exclusive lock on the subscription. + */ + rstates = GetSubscriptionNotReadyRelations(subid); + foreach(lc, rstates) + { + SubscriptionRelState *rstate = (SubscriptionRelState *) lfirst(lc); + Oid relid = rstate->relid; + + /* Only cleanup resources of tablesync workers */ + if (!OidIsValid(relid)) + continue; + + /* + * Drop the tablesync's origin tracking if exists. + * + * It is possible that the origin is not yet created for tablesync + * worker so passing missing_ok = true. This can happen for the states + * before SUBREL_STATE_FINISHEDCOPY. + */ + ReplicationOriginNameForTablesync(subid, relid, originname, + sizeof(originname)); + replorigin_drop_by_name(originname, true, false); + } + /* Clean up dependencies */ deleteSharedDependencyRecordsFor(SubscriptionRelationId, subid, 0); @@ -1074,9 +1274,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) /* Remove the origin tracking if exists. */ snprintf(originname, sizeof(originname), "pg_%u", subid); - originid = replorigin_by_name(originname, true); - if (originid != InvalidRepOriginId) - replorigin_drop(originid, false); + replorigin_drop_by_name(originname, true, false); if (Gp_role == GP_ROLE_DISPATCH) { @@ -1096,15 +1294,22 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) * If there is no slot associated with the subscription, we can finish * here. */ - if (!slotname) + if (!slotname && rstates == NIL) { table_close(rel, NoLock); return; } /* - * Otherwise drop the replication slot at the publisher node using the - * replication connection. + * Try to acquire the connection necessary for dropping slots. + * + * Note: If the slotname is NONE/NULL then we allow the command to finish + * and users need to manually cleanup the apply and tablesync worker slots + * later. + * + * This has to be at the end because otherwise if there is an error while + * doing the database operations we won't be able to rollback dropped + * slot. */ /* * In GPDB, we build libpqwalreceiver functions, as well as a copy of @@ -1114,18 +1319,92 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) if (!WalReceiverFunctions) libpqwalreceiver_PG_init(); - initStringInfo(&cmd); - appendStringInfo(&cmd, "DROP_REPLICATION_SLOT %s WAIT", quote_identifier(slotname)); - wrconn = walrcv_connect(conninfo, true, subname, &err); if (wrconn == NULL) - ereport(ERROR, - (errmsg("could not connect to publisher when attempting to " - "drop the replication slot \"%s\"", slotname), - errdetail("The error was: %s", err), - /* translator: %s is an SQL ALTER command */ - errhint("Use %s to disassociate the subscription from the slot.", - "ALTER SUBSCRIPTION ... SET (slot_name = NONE)"))); + { + if (!slotname) + { + /* be tidy */ + list_free(rstates); + table_close(rel, NoLock); + return; + } + else + { + ReportSlotConnectionError(rstates, subid, slotname, err); + } + } + + PG_TRY(); + { + foreach(lc, rstates) + { + SubscriptionRelState *rstate = (SubscriptionRelState *) lfirst(lc); + Oid relid = rstate->relid; + + /* Only cleanup resources of tablesync workers */ + if (!OidIsValid(relid)) + continue; + + /* + * Drop the tablesync slots associated with removed tables. + * + * For SYNCDONE/READY states, the tablesync slot is known to have + * already been dropped by the tablesync worker. + * + * For other states, there is no certainty, maybe the slot does + * not exist yet. Also, if we fail after removing some of the + * slots, next time, it will again try to drop already dropped + * slots and fail. For these reasons, we allow missing_ok = true + * for the drop. + */ + if (rstate->state != SUBREL_STATE_SYNCDONE) + { + char syncslotname[NAMEDATALEN] = {0}; + + ReplicationSlotNameForTablesync(subid, relid, syncslotname, + sizeof(syncslotname)); + ReplicationSlotDropAtPubNode(wrconn, syncslotname, true); + } + } + + list_free(rstates); + + /* + * If there is a slot associated with the subscription, then drop the + * replication slot at the publisher. + */ + if (slotname) + ReplicationSlotDropAtPubNode(wrconn, slotname, false); + + } + PG_FINALLY(); + { + walrcv_disconnect(wrconn); + } + PG_END_TRY(); + + table_close(rel, NoLock); +} + +/* + * Drop the replication slot at the publisher node using the replication + * connection. + * + * missing_ok - if true then only issue a LOG message if the slot doesn't + * exist. + */ +void +ReplicationSlotDropAtPubNode(WalReceiverConn *wrconn, char *slotname, bool missing_ok) +{ + StringInfoData cmd; + + Assert(wrconn); + + load_file("libpqwalreceiver", false); + + initStringInfo(&cmd); + appendStringInfo(&cmd, "DROP_REPLICATION_SLOT %s WAIT", quote_identifier(slotname)); PG_TRY(); { @@ -1133,27 +1412,38 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) res = walrcv_exec(wrconn, cmd.data, 0, NULL); - if (res->status != WALRCV_OK_COMMAND) - ereport(ERROR, - (errmsg("could not drop the replication slot \"%s\" on publisher", - slotname), - errdetail("The error was: %s", res->err))); - else + if (res->status == WALRCV_OK_COMMAND) + { + /* NOTICE. Success. */ ereport(NOTICE, (errmsg("dropped replication slot \"%s\" on publisher", slotname))); + } + else if (res->status == WALRCV_ERROR && + missing_ok && + res->sqlstate == ERRCODE_UNDEFINED_OBJECT) + { + /* LOG. Error, but missing_ok = true. */ + ereport(LOG, + (errmsg("could not drop replication slot \"%s\" on publisher: %s", + slotname, res->err))); + } + else + { + /* ERROR. */ + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not drop replication slot \"%s\" on publisher: %s", + slotname, res->err))); + } walrcv_clear_result(res); } PG_FINALLY(); { - walrcv_disconnect(wrconn); + pfree(cmd.data); } PG_END_TRY(); - - pfree(cmd.data); - - table_close(rel, NoLock); } /* @@ -1294,7 +1584,8 @@ fetch_table_list(WalReceiverConn *wrconn, List *publications) if (res->status != WALRCV_OK_TUPLES) ereport(ERROR, - (errmsg("could not receive list of replicated tables from the publisher: %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not receive list of replicated tables from the publisher: %s", res->err))); /* Process tables. */ @@ -1311,7 +1602,7 @@ fetch_table_list(WalReceiverConn *wrconn, List *publications) relname = TextDatumGetCString(slot_getattr(slot, 2, &isnull)); Assert(!isnull); - rv = makeRangeVar(pstrdup(nspname), pstrdup(relname), -1); + rv = makeRangeVar(nspname, relname, -1); tablelist = lappend(tablelist, rv); ExecClearTuple(slot); @@ -1322,3 +1613,146 @@ fetch_table_list(WalReceiverConn *wrconn, List *publications) return tablelist; } + +/* + * This is to report the connection failure while dropping replication slots. + * Here, we report the WARNING for all tablesync slots so that user can drop + * them manually, if required. + */ +static void +ReportSlotConnectionError(List *rstates, Oid subid, char *slotname, char *err) +{ + ListCell *lc; + + foreach(lc, rstates) + { + SubscriptionRelState *rstate = (SubscriptionRelState *) lfirst(lc); + Oid relid = rstate->relid; + + /* Only cleanup resources of tablesync workers */ + if (!OidIsValid(relid)) + continue; + + /* + * Caller needs to ensure that relstate doesn't change underneath us. + * See DropSubscription where we get the relstates. + */ + if (rstate->state != SUBREL_STATE_SYNCDONE) + { + char syncslotname[NAMEDATALEN] = {0}; + + ReplicationSlotNameForTablesync(subid, relid, syncslotname, + sizeof(syncslotname)); + elog(WARNING, "could not drop tablesync replication slot \"%s\"", + syncslotname); + } + } + + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not connect to publisher when attempting to " + "drop replication slot \"%s\": %s", slotname, err), + /* translator: %s is an SQL ALTER command */ + errhint("Use %s to disassociate the subscription from the slot.", + "ALTER SUBSCRIPTION ... SET (slot_name = NONE)"))); +} + +/* + * Check for duplicates in the given list of publications and error out if + * found one. Add publications to datums as text datums, if datums is not + * NULL. + */ +static void +check_duplicates_in_publist(List *publist, Datum *datums) +{ + ListCell *cell; + int j = 0; + + foreach(cell, publist) + { + char *name = strVal(lfirst(cell)); + ListCell *pcell; + + foreach(pcell, publist) + { + char *pname = strVal(lfirst(pcell)); + + if (pcell == cell) + break; + + if (strcmp(name, pname) == 0) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("publication name \"%s\" used more than once", + pname))); + } + + if (datums) + datums[j++] = CStringGetTextDatum(name); + } +} + +/* + * Merge current subscription's publications and user-specified publications + * from ADD/DROP PUBLICATIONS. + * + * If addpub is true, we will add the list of publications into oldpublist. + * Otherwise, we will delete the list of publications from oldpublist. The + * returned list is a copy, oldpublist itself is not changed. + * + * subname is the subscription name, for error messages. + */ +static List * +merge_publications(List *oldpublist, List *newpublist, bool addpub, const char *subname) +{ + ListCell *lc; + + oldpublist = list_copy(oldpublist); + + check_duplicates_in_publist(newpublist, NULL); + + foreach(lc, newpublist) + { + char *name = strVal(lfirst(lc)); + ListCell *lc2; + bool found = false; + + foreach(lc2, oldpublist) + { + char *pubname = strVal(lfirst(lc2)); + + if (strcmp(name, pubname) == 0) + { + found = true; + if (addpub) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("publication \"%s\" is already in subscription \"%s\"", + name, subname))); + else + oldpublist = foreach_delete_current(oldpublist, lc2); + + break; + } + } + + if (addpub && !found) + oldpublist = lappend(oldpublist, makeString(name)); + else if (!addpub && !found) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("publication \"%s\" is not in subscription \"%s\"", + name, subname))); + } + + /* + * XXX Probably no strong reason for this, but for now it's to make ALTER + * SUBSCRIPTION ... DROP PUBLICATION consistent with SET PUBLICATION. + */ + if (!oldpublist) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot drop all the publications from a subscription"))); + + return oldpublist; +} diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index de6f9993d85d..cd7b51846126 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,13 +26,12 @@ #include "access/relscan.h" #include "access/sysattr.h" #include "access/tableam.h" +#include "access/toast_compression.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/catalog.h" -#include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/index.h" -#include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/objectaccess.h" #include "catalog/partition.h" @@ -48,6 +47,7 @@ #include "catalog/pg_opclass.h" #include "catalog/pg_proc_d.h" #include "catalog/pg_tablespace.h" +#include "catalog/pg_statistic_ext.h" #include "catalog/pg_trigger.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" @@ -74,6 +74,7 @@ #include "commands/user.h" #include "executor/executor.h" #include "executor/instrument.h" +#include "foreign/fdwapi.h" #include "foreign/foreign.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -163,6 +164,27 @@ static List *on_commits = NIL; * In GPDB, these are in nodes/altertablenodes.h */ +#define AT_PASS_UNSET -1 /* UNSET will cause ERROR */ +#define AT_PASS_DROP 0 /* DROP (all flavors) */ +#define AT_PASS_ALTER_TYPE 1 /* ALTER COLUMN TYPE */ +#define AT_PASS_OLD_INDEX 2 /* re-add existing indexes */ +#define AT_PASS_OLD_CONSTR 3 /* re-add existing constraints */ +/* We could support a RENAME COLUMN pass here, but not currently used */ +#define AT_PASS_ADD_COL 4 /* ADD COLUMN */ +#define AT_PASS_ADD_CONSTR 5 /* ADD constraints (initial examination) */ +#define AT_PASS_COL_ATTRS 6 /* set column attributes, eg NOT NULL */ +#define AT_PASS_ADD_INDEXCONSTR 7 /* ADD index-based constraints */ +#define AT_PASS_ADD_INDEX 8 /* ADD indexes */ +#define AT_PASS_ADD_OTHERCONSTR 9 /* ADD other constraints, defaults */ +#define AT_PASS_MISC 10 /* other stuff */ +#define AT_NUM_PASSES 11 + +/* + * In GPDB, AlteredTableInfo, NewConstraint, and NewColumnValue are defined + * in nodes/altertablenodes.h (included above) because they need to be + * serializable Nodes for dispatch to QE segments. + */ + /* * Error-reporting support for RemoveRelations */ @@ -257,6 +279,20 @@ struct DropRelationCallbackState #define ATT_FOREIGN_TABLE 0x0020 #define ATT_PARTITIONED_INDEX 0x0040 +/* + * ForeignTruncateInfo + * + * Information related to truncation of foreign tables. This is used for + * the elements in a hash table. It uses the server OID as lookup key, + * and includes a per-server list of all foreign tables involved in the + * truncation. + */ +typedef struct ForeignTruncateInfo +{ + Oid serverid; + List *rels; +} ForeignTruncateInfo; + /* * Partition tables are expected to be dropped when the parent partitioned * table gets dropped. Hence for partitioning we use AUTO dependency. @@ -268,6 +304,7 @@ struct DropRelationCallbackState static void truncate_check_rel(Oid relid, Form_pg_class reltuple); static void truncate_check_perms(Oid relid, Form_pg_class reltuple); static void truncate_check_activity(Relation rel); +static void truncate_update_partedrel_stats(List *parted_rels); static void RangeVarCallbackForTruncate(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg); static List *MergeAttributes(List *schema, List *supers, char relpersistence, @@ -288,6 +325,9 @@ static void AlterSeqNamespaces(Relation classRel, Relation rel, LOCKMODE lockmode); static ObjectAddress ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, bool recurse, bool recursing, LOCKMODE lockmode); +static bool ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel, + Relation rel, HeapTuple contuple, List **otherrelids, + LOCKMODE lockmode); static ObjectAddress ATExecValidateConstraint(List **wqueue, Relation rel, char *constrName, bool recurse, bool recursing, LOCKMODE lockmode); @@ -314,7 +354,7 @@ static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, AlterTableUtilityContext *context); static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, AlterTableUtilityContext *context); -static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, +static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, AlterTableCmd *cmd, LOCKMODE lockmode, int cur_pass, AlterTableUtilityContext *context); static AlterTableCmd *ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab, @@ -372,12 +412,14 @@ static bool ConstraintImpliedByRelConstraint(Relation scanrel, List *testConstraint, List *provenConstraint); static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName, Node *newDefault, LOCKMODE lockmode); +static ObjectAddress ATExecCookedColumnDefault(Relation rel, AttrNumber attnum, + Node *newDefault); static ObjectAddress ATExecAddIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmode); static ObjectAddress ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmode); static ObjectAddress ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE lockmode); -static void ATPrepDropExpression(Relation rel, AlterTableCmd *cmd, bool recursing); +static void ATPrepDropExpression(Relation rel, AlterTableCmd *cmd, bool recurse, bool recursing, LOCKMODE lockmode); static ObjectAddress ATExecDropExpression(Relation rel, const char *colName, bool missing_ok, LOCKMODE lockmode); static ObjectAddress ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newValue, LOCKMODE lockmode); @@ -395,6 +437,8 @@ static ObjectAddress ATExecDropColumn(List **wqueue, Relation rel, const char *c ObjectAddresses *addrs); static ObjectAddress ATExecAddIndex(AlteredTableInfo *tab, Relation rel, IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode); +static ObjectAddress ATExecAddStatistics(AlteredTableInfo *tab, Relation rel, + CreateStatsStmt *stmt, bool is_rebuild, LOCKMODE lockmode); static ObjectAddress ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, Constraint *newConstraint, bool recurse, bool is_readd, @@ -408,7 +452,7 @@ static ObjectAddress ATAddCheckConstraint(List **wqueue, bool recurse, bool recursing, bool is_readd, LOCKMODE lockmode); static ObjectAddress ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, - Relation rel, Constraint *fkconstraint, Oid parentConstr, + Relation rel, Constraint *fkconstraint, bool recurse, bool recursing, LOCKMODE lockmode); static ObjectAddress addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, @@ -451,6 +495,7 @@ static ObjectAddress ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd, LOCKMODE lockmode); static void RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab); static void RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab); +static void RememberStatisticsForRebuilding(Oid indoid, AlteredTableInfo *tab); static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode); static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, @@ -495,9 +540,10 @@ static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKM static void ATExecDropOf(Relation rel, LOCKMODE lockmode); static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode); static void ATExecGenericOptions(Relation rel, List *options); -static void ATExecEnableRowSecurity(Relation rel); -static void ATExecDisableRowSecurity(Relation rel); +static void ATExecSetRowSecurity(Relation rel, bool rls); static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls); +static ObjectAddress ATExecSetCompression(AlteredTableInfo *tab, Relation rel, + const char *column, Node *newValue, LOCKMODE lockmode); static void index_copy_data(Relation rel, RelFileNode newrnode); static const char *storage_name(char c); @@ -517,16 +563,24 @@ static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partsp static void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs, List **partexprs, Oid *partopclass, Oid *partcollation, char strategy); static void CreateInheritance(Relation child_rel, Relation parent_rel); -static void RemoveInheritance(Relation child_rel, Relation parent_rel); +static void RemoveInheritance(Relation child_rel, Relation parent_rel, + bool allow_detached); static ObjectAddress ATExecAttachPartition(List **wqueue, Relation rel, - PartitionCmd *cmd); + PartitionCmd *cmd, + AlterTableUtilityContext *context); static void AttachPartitionEnsureIndexes(Relation rel, Relation attachrel); static void QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, List *partConstraint, bool validate_default); static void CloneRowTriggersToPartition(Relation parent, Relation partition); +static void DetachAddConstraintIfNeeded(List **wqueue, Relation partRel); static void DropClonedTriggersFromPartition(Oid partitionId); -static ObjectAddress ATExecDetachPartition(Relation rel, RangeVar *name); +static ObjectAddress ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, + Relation rel, RangeVar *name, + bool concurrent); +static void DetachPartitionFinalize(Relation rel, Relation partRel, + bool concurrent, Oid defaultPartOid); +static ObjectAddress ATExecDetachPartitionFinalize(Relation rel, RangeVar *name); static ObjectAddress ATExecAttachPartitionIdx(List **wqueue, Relation rel, RangeVar *name); static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl); @@ -534,6 +588,7 @@ static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx, Relation partitionTbl); static List *GetParentedForeignKeyRefs(Relation partition); static void ATDetachCheckNoForeignKeyRefs(Relation partition); +static char GetAttributeCompression(Oid atttypid, char *compression); static RangeVar *make_temp_table_name(Relation rel, BackendId id); static bool prebuild_temp_table(Relation rel, RangeVar *tmpname, DistributedBy *distro, @@ -1008,6 +1063,10 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, if (colDef->generated) attr->attgenerated = colDef->generated; + + if (colDef->compression) + attr->attcompression = GetAttributeCompression(attr->atttypid, + colDef->compression); } /* @@ -1248,7 +1307,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, * lock the partition so as to avoid a deadlock. */ defaultPartOid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(parent)); + get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, + true)); if (OidIsValid(defaultPartOid)) defaultRel = table_open(defaultPartOid, AccessExclusiveLock); @@ -1271,7 +1331,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, * Check first that the new partition's bound is valid and does not * overlap with any of existing partitions of the parent. */ - check_new_partition_bound(relname, parent, bound); + check_new_partition_bound(relname, parent, bound, pstate); /* * If the default partition exists, its partition constraints will @@ -1784,6 +1844,16 @@ RemoveRelations(DropStmt *drop) (void) find_all_inheritors(state.heapOid, state.heap_lockmode, NULL); + /* + * Concurrent index drop cannot be used with partitioned indexes, + * either. + */ + if ((flags & PERFORM_DELETION_CONCURRENTLY) != 0 && + get_rel_relkind(relOid) == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot drop partitioned index \"%s\" concurrently", + rel->relname))); /* OK, we're ready to delete this one */ obj.classId = RelationRelationId; @@ -1984,7 +2054,7 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid, */ if (is_partition && relOid != oldRelOid) { - state->partParentOid = get_partition_parent(relOid); + state->partParentOid = get_partition_parent(relOid, true); if (OidIsValid(state->partParentOid)) LockRelationOid(state->partParentOid, AccessExclusiveLock); } @@ -1996,7 +2066,10 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid, * * This is a multi-relation truncate. We first open and grab exclusive * lock on all relations involved, checking permissions and otherwise - * verifying that the relation is OK for truncation. In CASCADE mode, + * verifying that the relation is OK for truncation. Note that if relations + * are foreign tables, at this stage, we have not yet checked that their + * foreign data in external data sources are OK for truncation. These are + * checked when foreign data are actually truncated later. In CASCADE mode, * relations having FK references to the targeted relations are automatically * added to the group; in RESTRICT mode, we check that all FK references are * internal to the group that's being truncated. Finally all the relations @@ -2025,15 +2098,12 @@ ExecuteTruncate(TruncateStmt *stmt) 0, RangeVarCallbackForTruncate, NULL); - /* open the relation, we already hold a lock on it */ - rel = table_open(myrelid, NoLock); - /* don't throw error for "TRUNCATE foo, foo" */ if (list_member_oid(relids, myrelid)) - { - table_close(rel, lockmode); continue; - } + + /* open the relation, we already hold a lock on it */ + rel = table_open(myrelid, NoLock); /* * RangeVarGetRelidExtended() has done most checks with its callback, @@ -2043,6 +2113,7 @@ ExecuteTruncate(TruncateStmt *stmt) rels = lappend(rels, rel); relids = lappend_oid(relids, myrelid); + /* Log this relation only if needed for logical decoding */ if (RelationIsLogicallyLogged(rel)) relids_logged = lappend_oid(relids_logged, myrelid); @@ -2090,6 +2161,7 @@ ExecuteTruncate(TruncateStmt *stmt) rels = lappend(rels, rel); relids = lappend_oid(relids, childrelid); + /* Log this relation only if needed for logical decoding */ if (RelationIsLogicallyLogged(rel)) relids_logged = lappend_oid(relids_logged, childrelid); @@ -2128,11 +2200,16 @@ ExecuteTruncate(TruncateStmt *stmt) * this information handy in this form. */ void -ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, - DropBehavior behavior, bool restart_seqs, TruncateStmt *stmt) +ExecuteTruncateGuts(List *explicit_rels, + List *relids, + List *relids_logged, + DropBehavior behavior, bool restart_seqs, + TruncateStmt *stmt) { List *rels; List *seq_relids = NIL; + List *parted_rels = NIL; + HTAB *ft_htab = NULL; EState *estate; ResultRelInfo *resultRelInfos; ResultRelInfo *resultRelInfo; @@ -2241,6 +2318,11 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, /* * To fire triggers, we'll need an EState as well as a ResultRelInfo for * each relation. We don't need to call ExecOpenIndices, though. + * + * We put the ResultRelInfos in the es_opened_result_relations list, even + * though we don't have a range table and don't populate the + * es_result_relations array. That's a bit bogus, but it's enough to make + * ExecGetTriggerResultRel() find them. */ estate = CreateExecutorState(); resultRelInfos = (ResultRelInfo *) @@ -2255,10 +2337,10 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, 0, /* dummy rangetable index */ NULL, 0); + estate->es_opened_result_relations = + lappend(estate->es_opened_result_relations, resultRelInfo); resultRelInfo++; } - estate->es_result_relations = resultRelInfos; - estate->es_num_result_relations = list_length(rels); /* * Process all BEFORE STATEMENT TRUNCATE triggers before we begin @@ -2269,7 +2351,6 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, resultRelInfo = resultRelInfos; foreach(cell, rels) { - estate->es_result_relation_info = resultRelInfo; ExecBSTruncateTriggers(estate, resultRelInfo); resultRelInfo++; } @@ -2283,9 +2364,60 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, { Relation rel = (Relation) lfirst(cell); - /* Skip partitioned tables as there is nothing to do */ + /* + * Save OID of partitioned tables for later; nothing else to do for + * them here. + */ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + parted_rels = lappend_oid(parted_rels, RelationGetRelid(rel)); + continue; + } + + /* + * Build the lists of foreign tables belonging to each foreign server + * and pass each list to the foreign data wrapper's callback function, + * so that each server can truncate its all foreign tables in bulk. + * Each list is saved as a single entry in a hash table that uses the + * server OID as lookup key. + */ + if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + { + Oid serverid = GetForeignServerIdByRelId(RelationGetRelid(rel)); + bool found; + ForeignTruncateInfo *ft_info; + + /* First time through, initialize hashtable for foreign tables */ + if (!ft_htab) + { + HASHCTL hctl; + + memset(&hctl, 0, sizeof(HASHCTL)); + hctl.keysize = sizeof(Oid); + hctl.entrysize = sizeof(ForeignTruncateInfo); + hctl.hcxt = CurrentMemoryContext; + + ft_htab = hash_create("TRUNCATE for Foreign Tables", + 32, /* start small and extend */ + &hctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + } + + /* Find or create cached entry for the foreign table */ + ft_info = hash_search(ft_htab, &serverid, HASH_ENTER, &found); + if (!found) + { + ft_info->serverid = serverid; + ft_info->rels = NIL; + } + + /* + * Save the foreign table in the entry of the server that the + * foreign table belongs to. + */ + ft_info->rels = lappend(ft_info->rels, rel); continue; + } /* * Normally, we need a transaction-safe truncation here. However, if @@ -2304,6 +2436,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, { Oid heap_relid; Oid toast_relid; + ReindexParams reindex_params = {0}; /* * This effectively deletes all rows in the table, and may be done @@ -2346,7 +2479,8 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, /* * Reconstruct the indexes to match, and we're done. */ - reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST, 0); + reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST, + &reindex_params); } pgstat_count_truncate(rel); @@ -2381,6 +2515,35 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, } } + /* Now go through the hash table, and truncate foreign tables */ + if (ft_htab) + { + ForeignTruncateInfo *ft_info; + HASH_SEQ_STATUS seq; + + hash_seq_init(&seq, ft_htab); + + PG_TRY(); + { + while ((ft_info = hash_seq_search(&seq)) != NULL) + { + FdwRoutine *routine = GetFdwRoutineByServerId(ft_info->serverid); + + /* truncate_check_rel() has checked that already */ + Assert(routine->ExecForeignTruncate != NULL); + + routine->ExecForeignTruncate(ft_info->rels, + behavior, + restart_seqs); + } + } + PG_FINALLY(); + { + hash_destroy(ft_htab); + } + PG_END_TRY(); + } + /* * Restart owned sequences if we were asked to. */ @@ -2391,6 +2554,9 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, ResetSequence(seq_relid); } + /* Reset partitioned tables' pg_class.reltuples */ + truncate_update_partedrel_stats(parted_rels); + /* * Write a WAL record to allow this set of actions to be logically * decoded. @@ -2433,7 +2599,6 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, resultRelInfo = resultRelInfos; foreach(cell, rels) { - estate->es_result_relation_info = resultRelInfo; ExecASTruncateTriggers(estate, resultRelInfo); resultRelInfo++; } @@ -2467,9 +2632,10 @@ truncate_check_rel(Oid relid, Form_pg_class reltuple) char *relname = NameStr(reltuple->relname); /* - * Only allow truncate on regular tables and partitioned tables (although, - * the latter are only being included here for the following checks; no - * physical truncation will occur in their case.) + * Only allow truncate on regular tables, foreign tables using foreign + * data wrappers supporting TRUNCATE and partitioned tables (although, the + * latter are only being included here for the following checks; no + * physical truncation will occur in their case.). */ if (reltuple->relkind != RELKIND_RELATION && reltuple->relkind != RELKIND_PARTITIONED_TABLE && @@ -2477,6 +2643,19 @@ truncate_check_rel(Oid relid, Form_pg_class reltuple) reltuple->relkind != RELKIND_AOSEGMENTS && reltuple->relkind != RELKIND_AOBLOCKDIR && reltuple->relkind != RELKIND_AOVISIMAP))) + if (reltuple->relkind == RELKIND_FOREIGN_TABLE) + { + Oid serverid = GetForeignServerIdByRelId(relid); + FdwRoutine *fdwroutine = GetFdwRoutineByServerId(serverid); + + if (!fdwroutine->ExecForeignTruncate) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot truncate foreign table \"%s\"", + relname))); + } + else if (reltuple->relkind != RELKIND_RELATION && + reltuple->relkind != RELKIND_PARTITIONED_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a table", relname))); @@ -2530,6 +2709,40 @@ truncate_check_activity(Relation rel) CheckTableNotInUse(rel, "TRUNCATE"); } +/* + * Update pg_class.reltuples for all the given partitioned tables to 0. + */ +static void +truncate_update_partedrel_stats(List *parted_rels) +{ + Relation pg_class; + ListCell *lc; + + pg_class = table_open(RelationRelationId, RowExclusiveLock); + + foreach(lc, parted_rels) + { + Oid relid = lfirst_oid(lc); + HeapTuple tuple; + Form_pg_class rd_rel; + + tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "could not find tuple for relation %u", relid); + rd_rel = (Form_pg_class) GETSTRUCT(tuple); + if (rd_rel->reltuples != (float4) 0) + { + rd_rel->reltuples = (float4) 0; + + heap_inplace_update(pg_class, tuple); + } + + heap_freetuple(tuple); + } + + table_close(pg_class, RowExclusiveLock); +} + /* * storage_name * returns the name corresponding to a typstorage/attstorage enum value @@ -2560,8 +2773,8 @@ storage_name(char c) * 'schema' is the column/attribute definition for the table. (It's a list * of ColumnDef's.) It is destructively changed. * 'supers' is a list of OIDs of parent relations, already locked by caller. - * 'relpersistence' is a persistence type of the table. - * 'is_partition' tells if the table is a partition + * 'relpersistence' is the persistence type of the table. + * 'is_partition' tells if the table is a partition. * * Output arguments: * 'supconstr' receives a list of constraints belonging to the parents, @@ -2724,7 +2937,11 @@ MergeAttributes(List *schema, List *supers, char relpersistence, TupleDesc tupleDesc; TupleConstr *constr; AttrMap *newattmap; + List *inherited_defaults; + List *cols_with_defaults; AttrNumber parent_attno; + ListCell *lc1; + ListCell *lc2; /* caller already got lock */ relation = table_open(parent, NoLock); @@ -2815,6 +3032,9 @@ MergeAttributes(List *schema, List *supers, char relpersistence, */ newattmap = make_attrmap(tupleDesc->natts); + /* We can't process inherited defaults until newattmap is complete. */ + inherited_defaults = cols_with_defaults = NIL; + for (parent_attno = 1; parent_attno <= tupleDesc->natts; parent_attno++) { @@ -2870,7 +3090,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, get_collation_name(defCollId), get_collation_name(attribute->attcollation)))); - /* Copy storage parameter */ + /* Copy/check storage parameter */ if (def->storage == 0) def->storage = attribute->attstorage; else if (def->storage != attribute->attstorage) @@ -2882,6 +3102,22 @@ MergeAttributes(List *schema, List *supers, char relpersistence, storage_name(def->storage), storage_name(attribute->attstorage)))); + /* Copy/check compression parameter */ + if (CompressionMethodIsValid(attribute->attcompression)) + { + const char *compression = + GetCompressionMethodName(attribute->attcompression); + + if (def->compression == NULL) + def->compression = pstrdup(compression); + else if (strcmp(def->compression, compression) != 0) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("column \"%s\" has a compression method conflict", + attributeName), + errdetail("%s versus %s", def->compression, compression))); + } + def->inhcount++; /* Merge of NOT NULL constraints = OR 'em together */ def->is_not_null |= attribute->attnotnull; @@ -2916,50 +3152,94 @@ MergeAttributes(List *schema, List *supers, char relpersistence, def->collOid = attribute->attcollation; def->constraints = NIL; def->location = -1; + if (CompressionMethodIsValid(attribute->attcompression)) + def->compression = + pstrdup(GetCompressionMethodName(attribute->attcompression)); + else + def->compression = NULL; inhSchema = lappend(inhSchema, def); newattmap->attnums[parent_attno - 1] = ++child_attno; } /* - * Copy default if any + * Locate default if any */ if (attribute->atthasdef) { Node *this_default = NULL; - AttrDefault *attrdef; - int i; /* Find default in constraint structure */ - Assert(constr != NULL); - attrdef = constr->defval; - for (i = 0; i < constr->num_defval; i++) + if (constr != NULL) { - if (attrdef[i].adnum == parent_attno) + AttrDefault *attrdef = constr->defval; + + for (int i = 0; i < constr->num_defval; i++) { - this_default = stringToNode(attrdef[i].adbin); - break; + if (attrdef[i].adnum == parent_attno) + { + this_default = stringToNode(attrdef[i].adbin); + break; + } } } - Assert(this_default != NULL); + if (this_default == NULL) + elog(ERROR, "default expression not found for attribute %d of relation \"%s\"", + parent_attno, RelationGetRelationName(relation)); /* - * If default expr could contain any vars, we'd need to fix - * 'em, but it can't; so default is ready to apply to child. - * - * If we already had a default from some prior parent, check - * to see if they are the same. If so, no problem; if not, - * mark the column as having a bogus default. Below, we will - * complain if the bogus default isn't overridden by the child - * schema. + * If it's a GENERATED default, it might contain Vars that + * need to be mapped to the inherited column(s)' new numbers. + * We can't do that till newattmap is ready, so just remember + * all the inherited default expressions for the moment. */ - Assert(def->raw_default == NULL); - if (def->cooked_default == NULL) - def->cooked_default = this_default; - else if (!equal(def->cooked_default, this_default)) - { - def->cooked_default = &bogus_marker; - have_bogus_defaults = true; - } + inherited_defaults = lappend(inherited_defaults, this_default); + cols_with_defaults = lappend(cols_with_defaults, def); + } + } + + /* + * Now process any inherited default expressions, adjusting attnos + * using the completed newattmap map. + */ + forboth(lc1, inherited_defaults, lc2, cols_with_defaults) + { + Node *this_default = (Node *) lfirst(lc1); + ColumnDef *def = (ColumnDef *) lfirst(lc2); + bool found_whole_row; + + /* Adjust Vars to match new table's column numbering */ + this_default = map_variable_attnos(this_default, + 1, 0, + newattmap, + InvalidOid, &found_whole_row); + + /* + * For the moment we have to reject whole-row variables. We could + * convert them, if we knew the new table's rowtype OID, but that + * hasn't been assigned yet. (A variable could only appear in a + * generation expression, so the error message is correct.) + */ + if (found_whole_row) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert whole-row table reference"), + errdetail("Generation expression for column \"%s\" contains a whole-row reference to table \"%s\".", + def->colname, + RelationGetRelationName(relation)))); + + /* + * If we already had a default from some prior parent, check to + * see if they are the same. If so, no problem; if not, mark the + * column as having a bogus default. Below, we will complain if + * the bogus default isn't overridden by the child schema. + */ + Assert(def->raw_default == NULL); + if (def->cooked_default == NULL) + def->cooked_default = this_default; + else if (!equal(def->cooked_default, this_default)) + { + def->cooked_default = &bogus_marker; + have_bogus_defaults = true; } } @@ -3125,6 +3405,19 @@ MergeAttributes(List *schema, List *supers, char relpersistence, storage_name(def->storage), storage_name(newdef->storage)))); + /* Copy compression parameter */ + if (def->compression == NULL) + def->compression = newdef->compression; + else if (newdef->compression != NULL) + { + if (strcmp(def->compression, newdef->compression) != 0) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("column \"%s\" has a compression method conflict", + attributeName), + errdetail("%s versus %s", def->compression, newdef->compression))); + } + /* Mark the column as locally defined */ def->is_local = true; /* Merge of NOT NULL constraints = OR 'em together */ @@ -3178,7 +3471,6 @@ MergeAttributes(List *schema, List *supers, char relpersistence, def->raw_default = newdef->raw_default; def->cooked_default = newdef->cooked_default; } - } else { @@ -3487,6 +3779,112 @@ SetRelationHasSubclass(Oid relationId, bool relhassubclass) table_close(relationRelation, RowExclusiveLock); } +/* + * CheckRelationTableSpaceMove + * Check if relation can be moved to new tablespace. + * + * NOTE: The caller must hold AccessExclusiveLock on the relation. + * + * Returns true if the relation can be moved to the new tablespace; raises + * an error if it is not possible to do the move; returns false if the move + * would have no effect. + */ +bool +CheckRelationTableSpaceMove(Relation rel, Oid newTableSpaceId) +{ + Oid oldTableSpaceId; + + /* + * No work if no change in tablespace. Note that MyDatabaseTableSpace is + * stored as 0. + */ + oldTableSpaceId = rel->rd_rel->reltablespace; + if (newTableSpaceId == oldTableSpaceId || + (newTableSpaceId == MyDatabaseTableSpace && oldTableSpaceId == 0)) + return false; + + /* + * We cannot support moving mapped relations into different tablespaces. + * (In particular this eliminates all shared catalogs.) + */ + if (RelationIsMapped(rel)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot move system relation \"%s\"", + RelationGetRelationName(rel)))); + + /* Cannot move a non-shared relation into pg_global */ + if (newTableSpaceId == GLOBALTABLESPACE_OID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("only shared relations can be placed in pg_global tablespace"))); + + /* + * Do not allow moving temp tables of other backends ... their local + * buffer manager is not going to cope. + */ + if (RELATION_IS_OTHER_TEMP(rel)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot move temporary tables of other sessions"))); + + return true; +} + +/* + * SetRelationTableSpace + * Set new reltablespace and relfilenode in pg_class entry. + * + * newTableSpaceId is the new tablespace for the relation, and + * newRelFileNode its new filenode. If newRelFileNode is InvalidOid, + * this field is not updated. + * + * NOTE: The caller must hold AccessExclusiveLock on the relation. + * + * The caller of this routine had better check if a relation can be + * moved to this new tablespace by calling CheckRelationTableSpaceMove() + * first, and is responsible for making the change visible with + * CommandCounterIncrement(). + */ +void +SetRelationTableSpace(Relation rel, + Oid newTableSpaceId, + Oid newRelFileNode) +{ + Relation pg_class; + HeapTuple tuple; + Form_pg_class rd_rel; + Oid reloid = RelationGetRelid(rel); + + Assert(CheckRelationTableSpaceMove(rel, newTableSpaceId)); + + /* Get a modifiable copy of the relation's pg_class row. */ + pg_class = table_open(RelationRelationId, RowExclusiveLock); + + tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", reloid); + rd_rel = (Form_pg_class) GETSTRUCT(tuple); + + /* Update the pg_class row. */ + rd_rel->reltablespace = (newTableSpaceId == MyDatabaseTableSpace) ? + InvalidOid : newTableSpaceId; + if (OidIsValid(newRelFileNode)) + rd_rel->relfilenode = newRelFileNode; + CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + + /* + * Record dependency on tablespace. This is only required for relations + * that have no physical storage. + */ + if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) + changeDependencyOnTablespace(RelationRelationId, reloid, + rd_rel->reltablespace); + + heap_freetuple(tuple); + table_close(pg_class, RowExclusiveLock); +} + /* * renameatt_check - basic sanity checks before attribute rename */ @@ -4278,6 +4676,17 @@ strip_gpdb_part_commands(List *cmds) case AT_PartExchange: case AT_PartSetTemplate: break; + + /* + * Extended statistics objects exist only on the QD (CREATE + * STATISTICS is not dispatched), so the AT_ReAddStatistics + * subcommand that ALTER COLUMN TYPE generates to rebuild them + * must not be dispatched either: the QEs have no statistics + * object to rebuild, and executing it there would allocate a + * pg_statistic_ext OID outside the QD's OID dispatch. + */ + case AT_ReAddStatistics: + break; default: newcmds = lappend(newcmds, cmd); break; @@ -4479,6 +4888,7 @@ AlterTableGetLockLevel(List *cmds) * Theoretically, these could be ShareRowExclusiveLock. */ case AT_ColumnDefault: + case AT_CookedColumnDefault: case AT_AlterConstraint: case AT_AddIndex: /* from ADD CONSTRAINT */ case AT_AddIndexConstraint: @@ -4492,6 +4902,7 @@ AlterTableGetLockLevel(List *cmds) case AT_DropIdentity: case AT_SetIdentity: case AT_DropExpression: + case AT_SetCompression: cmd_lockmode = AccessExclusiveLock; break; @@ -4612,7 +5023,14 @@ AlterTableGetLockLevel(List *cmds) break; case AT_DetachPartition: - cmd_lockmode = AccessExclusiveLock; + if (((PartitionCmd *) cmd->def)->concurrent) + cmd_lockmode = ShareUpdateExclusiveLock; + else + cmd_lockmode = AccessExclusiveLock; + break; + + case AT_DetachPartitionFinalize: + cmd_lockmode = ShareUpdateExclusiveLock; break; case AT_CheckNotNull: @@ -4773,12 +5191,24 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, /* Find or create work queue entry for this table */ tab = ATGetQueueEntry(wqueue, rel); + /* + * Disallow any ALTER TABLE other than ALTER TABLE DETACH FINALIZE on + * partitions that are pending detach. + */ + if (rel->rd_rel->relispartition && + cmd->subtype != AT_DetachPartitionFinalize && + PartitionHasPendingDetach(RelationGetRelid(rel))) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot alter partition \"%s\" with an incomplete detach", + RelationGetRelationName(rel)), + errhint("Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation.")); + /* * Copy the original subcommand for each table. This avoids conflicts * when different child tables need to make different parse * transformations (for example, the same column may have different column - * numbers in different children). It also ensures that we don't corrupt - * the original parse tree, in case it is saved in plancache. + * numbers in different children). */ if (recursing) cmd = copyObject(cmd); @@ -4825,6 +5255,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, /* No command-specific prep needed */ pass = cmd->def ? AT_PASS_ADD_OTHERCONSTR : AT_PASS_DROP; break; + case AT_CookedColumnDefault: /* add a pre-cooked default */ + /* This is currently used only in CREATE TABLE */ + /* (so the permission check really isn't necessary) */ + ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); + /* This command never recurses */ + pass = AT_PASS_ADD_OTHERCONSTR; + break; case AT_AddIdentity: ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE); /* This command never recurses */ @@ -4863,7 +5300,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, case AT_DropExpression: /* ALTER COLUMN DROP EXPRESSION */ ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode, context); - ATPrepDropExpression(rel, cmd, recursing); + ATPrepDropExpression(rel, cmd, recurse, recursing, lockmode); pass = AT_PASS_DROP; break; case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */ @@ -4884,6 +5321,12 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, /* No command-specific prep needed */ pass = AT_PASS_MISC; break; + case AT_SetCompression: /* ALTER COLUMN SET COMPRESSION */ + ATSimplePermissions(rel, ATT_TABLE | ATT_MATVIEW); + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; + break; case AT_DropColumn: /* DROP COLUMN */ case AT_DropColumnRecurse: ATSimplePermissions(rel, @@ -5060,7 +5503,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, if (rel->rd_rel->relispartition) { /* We can only set policy of child table to the same with parent table */ - Oid parent_oid = get_partition_parent(RelationGetRelid(rel)); + Oid parent_oid = get_partition_parent(RelationGetRelid(rel), false); /* Use AccessShareLock to allow set distributed in parallel */ Relation parent_rel = relation_open(parent_oid, AccessShareLock); if (!GpPolicyEqualByName(RelationGetDescr(rel), policy, @@ -5179,6 +5622,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, break; case AT_AlterConstraint: /* ALTER CONSTRAINT */ ATSimplePermissions(rel, ATT_TABLE); + /* Recursion occurs during execution phase */ pass = AT_PASS_MISC; break; case AT_ValidateConstraint: /* VALIDATE CONSTRAINT */ @@ -5247,6 +5691,7 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, case AT_PartTruncate: case AT_PartExchange: case AT_PartSetTemplate: + case AT_DetachPartitionFinalize: ATSimplePermissions(rel, ATT_TABLE); /* No command-specific prep needed */ pass = AT_PASS_MISC; @@ -5292,19 +5737,20 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, { AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab); List *subcmds = tab->subcmds[pass]; - Relation rel; ListCell *lcmd; if (subcmds == NIL) continue; /* - * Appropriate lock was obtained by phase 1, needn't get it again + * Open the relation and store it in tab. This allows subroutines + * close and reopen, if necessary. Appropriate lock was obtained + * by phase 1, needn't get it again. */ - rel = relation_open(tab->relid, NoLock); + tab->rel = relation_open(tab->relid, NoLock); foreach(lcmd, subcmds) - ATExecCmd(wqueue, tab, rel, + ATExecCmd(wqueue, tab, castNode(AlterTableCmd, lfirst(lcmd)), lockmode, pass, context); @@ -5316,7 +5762,11 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, if (pass == AT_PASS_ALTER_TYPE) ATPostAlterTypeCleanup(wqueue, tab, lockmode); - relation_close(rel, NoLock); + if (tab->rel) + { + relation_close(tab->rel, NoLock); + tab->rel = NULL; + } } } @@ -5346,11 +5796,12 @@ ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode, * behavior from Postgres upstream. */ static void -ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, +ATExecCmd(List **wqueue, AlteredTableInfo *tab, AlterTableCmd *cmd, LOCKMODE lockmode, int cur_pass, AlterTableUtilityContext *context) { ObjectAddress address = InvalidObjectAddress; + Relation rel = tab->rel; if (Gp_role == GP_ROLE_EXECUTE) { @@ -5388,6 +5839,9 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */ address = ATExecColumnDefault(rel, cmd->name, cmd->def, lockmode); break; + case AT_CookedColumnDefault: /* add a pre-cooked default */ + address = ATExecCookedColumnDefault(rel, cmd->num, cmd->def); + break; case AT_AddIdentity: cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode, cur_pass, context, &cmd->execStmts); @@ -5427,6 +5881,10 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_SetStorage: /* ALTER COLUMN SET STORAGE */ address = ATExecSetStorage(rel, cmd->name, cmd->def, lockmode); break; + case AT_SetCompression: + address = ATExecSetCompression(tab, rel, cmd->name, cmd->def, + lockmode); + break; case AT_DropColumn: /* DROP COLUMN */ address = ATExecDropColumn(wqueue, rel, cmd->name, cmd->behavior, false, false, @@ -5447,10 +5905,15 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, address = ATExecAddIndex(tab, rel, (IndexStmt *) cmd->def, true, lockmode); break; + case AT_ReAddStatistics: /* ADD STATISTICS */ + address = ATExecAddStatistics(tab, rel, (CreateStatsStmt *) cmd->def, + true, lockmode); + break; case AT_AddConstraint: /* ADD CONSTRAINT */ cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode, cur_pass, context, &cmd->execStmts); /* Might not have gotten AddConstraint back from parse transform */ + /* Depending on constraint type, might be no more work to do now */ if (cmd != NULL) address = ATExecAddConstraint(wqueue, tab, rel, @@ -5461,6 +5924,7 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, true, lockmode, cur_pass, context, &cmd->execStmts); /* Might not have gotten AddConstraint back from parse transform */ + /* Depending on constraint type, might be no more work to do now */ if (cmd != NULL) address = ATExecAddConstraint(wqueue, tab, rel, @@ -5658,10 +6122,10 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, ATExecReplicaIdentity(rel, (ReplicaIdentityStmt *) cmd->def, lockmode); break; case AT_EnableRowSecurity: - ATExecEnableRowSecurity(rel); + ATExecSetRowSecurity(rel, true); break; case AT_DisableRowSecurity: - ATExecDisableRowSecurity(rel); + ATExecSetRowSecurity(rel, false); break; case AT_ForceRowSecurity: ATExecForceNoForceRowSecurity(rel, true); @@ -5686,7 +6150,8 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, cur_pass, context, &cmd->execStmts); Assert(cmd != NULL); if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def); + ATExecAttachPartition(wqueue, rel, (PartitionCmd *) cmd->def, + context); else ATExecAttachPartitionIdx(wqueue, rel, ((PartitionCmd *) cmd->def)->name); @@ -5697,7 +6162,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, Assert(cmd != NULL); /* ATPrepCmd ensures it must be a table */ Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - ATExecDetachPartition(rel, ((PartitionCmd *) cmd->def)->name); + ATExecDetachPartition(wqueue, tab, rel, + ((PartitionCmd *) cmd->def)->name, + ((PartitionCmd *) cmd->def)->concurrent); + break; + case AT_DetachPartitionFinalize: + ATExecDetachPartitionFinalize(rel, ((PartitionCmd *) cmd->def)->name); break; default: /* oops */ elog(ERROR, "unrecognized alter table type: %d", @@ -5794,11 +6264,19 @@ ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, foreach(lc, atstmt->cmds) { AlterTableCmd *cmd2 = lfirst_node(AlterTableCmd, lc); + int pass; - if (newcmd == NULL && - (cmd->subtype == cmd2->subtype || - (cmd->subtype == AT_AddConstraintRecurse && - cmd2->subtype == AT_AddConstraint))) + /* + * This switch need only cover the subcommand types that can be added + * by parse_utilcmd.c; otherwise, we'll use the default strategy of + * executing the subcommand immediately, as a substitute for the + * original subcommand. (Note, however, that this does cause + * AT_AddConstraint subcommands to be rescheduled into later passes, + * which is important for index and foreign key constraints.) + * + * We assume we needn't do any phase-1 checks for added subcommands. + */ + switch (cmd2->subtype) { /* Found the transformed version of our subcommand */ cmd2->subtype = cmd->subtype; /* copy recursion flag */ @@ -5810,66 +6288,75 @@ ATParseTransformCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, */ if (Gp_role == GP_ROLE_DISPATCH) cmd->def = newcmd->def; + break; + case AT_SetNotNull: + /* Need command-specific recursion decision */ + ATPrepSetNotNull(wqueue, rel, cmd2, + recurse, false, + lockmode, context); + pass = AT_PASS_COL_ATTRS; + break; + case AT_AddIndex: + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_ADD_INDEX; + break; + case AT_AddIndexConstraint: + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_ADD_INDEXCONSTR; + break; + case AT_AddConstraint: + /* Recursion occurs during execution phase */ + if (recurse) + cmd2->subtype = AT_AddConstraintRecurse; + switch (castNode(Constraint, cmd2->def)->contype) + { + case CONSTR_PRIMARY: + case CONSTR_UNIQUE: + case CONSTR_EXCLUSION: + pass = AT_PASS_ADD_INDEXCONSTR; + break; + default: + pass = AT_PASS_ADD_OTHERCONSTR; + break; + } + break; + case AT_AlterColumnGenericOptions: + /* This command never recurses */ + /* No command-specific prep needed */ + pass = AT_PASS_MISC; + break; + default: + pass = cur_pass; + break; + } + + if (pass < cur_pass) + { + /* Cannot schedule into a pass we already finished */ + elog(ERROR, "ALTER TABLE scheduling failure: too late for pass %d", + pass); + } + else if (pass > cur_pass) + { + /* OK, queue it up for later */ + tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd2); } else { - int pass; - /* - * Schedule added subcommand appropriately. We assume we needn't - * do any phase-1 checks for it. This switch only has to cover - * the subcommand types that can be added by parse_utilcmd.c. + * We should see at most one subcommand for the current pass, + * which is the transformed version of the original subcommand. */ - switch (cmd2->subtype) + if (newcmd == NULL && cmd->subtype == cmd2->subtype) { - case AT_SetNotNull: - /* Need command-specific recursion decision */ - ATPrepSetNotNull(wqueue, rel, cmd2, - recurse, false, - lockmode, context); - pass = AT_PASS_COL_ATTRS; - break; - case AT_AddIndex: - /* This command never recurses */ - /* No command-specific prep needed */ - pass = AT_PASS_ADD_INDEX; - break; - case AT_AddIndexConstraint: - /* This command never recurses */ - /* No command-specific prep needed */ - pass = AT_PASS_ADD_INDEXCONSTR; - break; - case AT_AddConstraint: - /* Recursion occurs during execution phase */ - if (recurse) - cmd2->subtype = AT_AddConstraintRecurse; - switch (castNode(Constraint, cmd2->def)->contype) - { - case CONSTR_PRIMARY: - case CONSTR_UNIQUE: - case CONSTR_EXCLUSION: - pass = AT_PASS_ADD_INDEXCONSTR; - break; - default: - pass = AT_PASS_ADD_OTHERCONSTR; - break; - } - break; - case AT_AlterColumnGenericOptions: - /* This command never recurses */ - /* No command-specific prep needed */ - pass = AT_PASS_MISC; - break; - default: - elog(ERROR, "unexpected AlterTableType: %d", - (int) cmd2->subtype); - pass = AT_PASS_UNSET; - break; + /* Found the transformed version of our subcommand */ + newcmd = cmd2; } - /* Must be for a later pass than we're currently doing */ - if (pass <= cur_pass) - elog(ERROR, "ALTER TABLE scheduling failure"); - tab->subcmds[pass] = lappend(tab->subcmds[pass], cmd2); + else + elog(ERROR, "ALTER TABLE scheduling failure: bogus item for pass %d", + pass); } } @@ -6749,12 +7236,12 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) if (newrel) ereport(DEBUG1, - (errmsg("rewriting table \"%s\"", - RelationGetRelationName(oldrel)))); + (errmsg_internal("rewriting table \"%s\"", + RelationGetRelationName(oldrel)))); else ereport(DEBUG1, - (errmsg("verifying table \"%s\"", - RelationGetRelationName(oldrel)))); + (errmsg_internal("verifying table \"%s\"", + RelationGetRelationName(oldrel)))); if (newrel) { @@ -6848,6 +7335,14 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) foreach(lc, dropped_attrs) newslot->tts_isnull[lfirst_int(lc)] = true; + /* + * Constraints and GENERATED expressions might reference the + * tableoid column, so fill tts_tableOid with the desired + * value. (We must do this each time, because it gets + * overwritten with newrel's OID during storing.) + */ + newslot->tts_tableOid = RelationGetRelid(oldrel); + /* * Process supplied expressions to replace selected columns. * @@ -6891,11 +7386,6 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) &newslot->tts_isnull[ex->attnum - 1]); } - /* - * Constraints might reference the tableoid column, so - * initialize t_tableOid before evaluating them. - */ - newslot->tts_tableOid = RelationGetRelid(oldrel); insertslot = newslot; } else @@ -7026,6 +7516,7 @@ ATGetQueueEntry(List **wqueue, Relation rel) */ tab = (AlteredTableInfo *) palloc0(sizeof(AlteredTableInfo)); tab->relid = relid; + tab->rel = NULL; /* set later */ tab->relkind = rel->rd_rel->relkind; tab->oldDesc = CreateTupleDescCopyConstr(RelationGetDescr(rel)); tab->newAccessMethod = InvalidOid; @@ -7184,14 +7675,10 @@ ATSimpleRecursion(List **wqueue, Relation rel, AlterTableUtilityContext *context) { /* - * Propagate to children if desired. Only plain tables, foreign tables - * and partitioned tables have children, so no need to search for other - * relkinds. + * Propagate to children, if desired and if there are (or might be) any + * children. */ - if (recurse && - (rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE || - rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)) + if (recurse && rel->rd_rel->relhassubclass) { Oid relid = RelationGetRelid(rel); ListCell *child; @@ -7253,7 +7740,7 @@ ATCheckPartitionsNotInUse(Relation rel, LOCKMODE lockmode) inh = find_all_inheritors(RelationGetRelid(rel), lockmode, NULL); /* first element is the parent rel; must ignore it */ - for_each_cell(cell, inh, list_second_cell(inh)) + for_each_from(cell, inh, 1) { Relation childrel; @@ -7720,12 +8207,14 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, attribute.atttypid = typeOid; attribute.attstattarget = (newattnum > 0) ? -1 : 0; attribute.attlen = tform->typlen; - attribute.atttypmod = typmod; attribute.attnum = newattnum; - attribute.attbyval = tform->typbyval; attribute.attndims = list_length(colDef->typeName->arrayBounds); - attribute.attstorage = tform->typstorage; + attribute.atttypmod = typmod; + attribute.attbyval = tform->typbyval; attribute.attalign = tform->typalign; + attribute.attstorage = tform->typstorage; + attribute.attcompression = GetAttributeCompression(typeOid, + colDef->compression); attribute.attnotnull = colDef->is_not_null; attribute.atthasdef = false; attribute.atthasmissing = false; @@ -7735,6 +8224,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, attribute.attislocal = colDef->is_local; attribute.attinhcount = colDef->inhcount; attribute.attcollation = collOid; + /* attribute.attacl is handled by InsertPgAttributeTuples() */ ReleaseSysCache(typeTuple); @@ -7795,10 +8285,26 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, false, true, false, NULL); - /* copy back the cooked attmissingval for dispatch */ + /* + * Copy back the cooked attmissingval for dispatch -- and for the + * sibling partitions processed after this one, which seed their + * rawEnt from the shared ColumnDef so that every relation stores + * the same evaluated value (think DEFAULT now()). The datum was + * built in a per-child context, so make a durable copy; a dangling + * pointer here gave the next sibling a garbage missing value + * (mixed-AM partitioned ADD COLUMN in alter_table_aocs2). + */ colDef->hasCookedMissingVal = rawEnt->hasCookedMissingVal; - colDef->missingVal = rawEnt->missingVal; colDef->missingIsNull = rawEnt->missingIsNull; + if (rawEnt->hasCookedMissingVal && !rawEnt->missingIsNull) + { + MemoryContext oldcxt = MemoryContextSwitchTo(CurTransactionContext); + + colDef->missingVal = datumCopy(rawEnt->missingVal, false, -1); + MemoryContextSwitchTo(oldcxt); + } + else + colDef->missingVal = rawEnt->missingVal; /* Make the additional catalog changes visible */ CommandCounterIncrement(); @@ -8010,7 +8516,8 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, * routines, we have to do this one level of recursion at a time; we can't * use find_all_inheritors to do it in one pass. */ - children = find_inheritance_children(RelationGetRelid(rel), lockmode); + children = + find_inheritance_children(RelationGetRelid(rel), lockmode); /* * If we are told not to recurse, there had better not be any child @@ -8267,7 +8774,7 @@ ATPrepDropNotNull(Relation rel, bool recurse, bool recursing) */ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - PartitionDesc partdesc = RelationGetPartitionDesc(rel); + PartitionDesc partdesc = RelationGetPartitionDesc(rel, true); Assert(partdesc != NULL); if (partdesc->nparts > 0 && !recurse && !recursing) @@ -8366,7 +8873,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) /* If rel is partition, shouldn't drop NOT NULL if parent has the same */ if (rel->rd_rel->relispartition) { - Oid parentId = get_partition_parent(RelationGetRelid(rel)); + Oid parentId = get_partition_parent(RelationGetRelid(rel), false); Relation parent = table_open(parentId, AccessShareLock); TupleDesc tupDesc = RelationGetDescr(parent); AttrNumber parent_attnum; @@ -8428,6 +8935,41 @@ ATPrepSetNotNull(List **wqueue, Relation rel, if (recursing) return; + /* + * If the target column is already marked NOT NULL, we can skip recursing + * to children, because their columns should already be marked NOT NULL as + * well. But there's no point in checking here unless the relation has + * some children; else we can just wait till execution to check. (If it + * does have children, however, this can save taking per-child locks + * unnecessarily. This greatly improves concurrency in some parallel + * restore scenarios.) + * + * Unfortunately, we can only apply this optimization to partitioned + * tables, because traditional inheritance doesn't enforce that child + * columns be NOT NULL when their parent is. (That's a bug that should + * get fixed someday.) + */ + if (rel->rd_rel->relhassubclass && + rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + HeapTuple tuple; + bool attnotnull; + + tuple = SearchSysCacheAttName(RelationGetRelid(rel), cmd->name); + + /* Might as well throw the error now, if name is bad */ + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + cmd->name, RelationGetRelationName(rel)))); + + attnotnull = ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull; + ReleaseSysCache(tuple); + if (attnotnull) + return; + } + /* * If we have ALTER TABLE ONLY ... SET NOT NULL on a partitioned table, * apply ALTER TABLE ... CHECK NOT NULL to every child. Otherwise, use @@ -8594,8 +9136,8 @@ NotNullImpliedByRelConstraints(Relation rel, Form_pg_attribute attr) if (ConstraintImpliedByRelConstraint(rel, list_make1(nnulltest), NIL)) { ereport(DEBUG1, - (errmsg("existing constraints on column \"%s\".\"%s\" are sufficient to prove that it does not contain nulls", - RelationGetRelationName(rel), NameStr(attr->attname)))); + (errmsg_internal("existing constraints on column \"%s.%s\" are sufficient to prove that it does not contain nulls", + RelationGetRelationName(rel), NameStr(attr->attname)))); return true; } @@ -8692,6 +9234,35 @@ ATExecColumnDefault(Relation rel, const char *colName, return address; } +/* + * Add a pre-cooked default expression. + * + * Return the address of the affected column. + */ +static ObjectAddress +ATExecCookedColumnDefault(Relation rel, AttrNumber attnum, + Node *newDefault) +{ + ObjectAddress address; + + /* We assume no checking is required */ + + /* + * Remove any old default for the column. We use RESTRICT here for + * safety, but at present we do not expect anything to depend on the + * default. (In ordinary cases, there could not be a default in place + * anyway, but it's possible when combining LIKE with inheritance.) + */ + RemoveAttrDefault(RelationGetRelid(rel), attnum, DROP_RESTRICT, false, + true); + + (void) StoreAttrDefault(rel, attnum, newDefault, false, NULL, NULL, true, false); + + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); + return address; +} + /* * ALTER TABLE ALTER COLUMN ADD IDENTITY * @@ -8926,8 +9497,24 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE * ALTER TABLE ALTER COLUMN DROP EXPRESSION */ static void -ATPrepDropExpression(Relation rel, AlterTableCmd *cmd, bool recursing) +ATPrepDropExpression(Relation rel, AlterTableCmd *cmd, bool recurse, bool recursing, LOCKMODE lockmode) { + /* + * Reject ONLY if there are child tables. We could implement this, but it + * is a bit complicated. GENERATED clauses must be attached to the column + * definition and cannot be added later like DEFAULT, so if a child table + * has a generation expression that the parent does not have, the child + * column will necessarily be an attlocal column. So to implement ONLY + * here, we'd need extra code to update attislocal of the direct child + * tables, somewhat similar to how DROP COLUMN does it, so that the + * resulting state can be properly dumped and restored. + */ + if (!recurse && + find_inheritance_children(RelationGetRelid(rel), lockmode)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ALTER TABLE / DROP EXPRESSION must be applied to child tables too"))); + /* * Cannot drop generation expression from inherited columns. */ @@ -9263,6 +9850,70 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, return address; } +/* + * Helper function for ATExecSetStorage and ATExecSetCompression + * + * Set the attstorage and/or attcompression fields for index columns + * associated with the specified table column. + */ +static void +SetIndexStorageProperties(Relation rel, Relation attrelation, + AttrNumber attnum, + bool setstorage, char newstorage, + bool setcompression, char newcompression, + LOCKMODE lockmode) +{ + ListCell *lc; + + foreach(lc, RelationGetIndexList(rel)) + { + Oid indexoid = lfirst_oid(lc); + Relation indrel; + AttrNumber indattnum = 0; + HeapTuple tuple; + + indrel = index_open(indexoid, lockmode); + + for (int i = 0; i < indrel->rd_index->indnatts; i++) + { + if (indrel->rd_index->indkey.values[i] == attnum) + { + indattnum = i + 1; + break; + } + } + + if (indattnum == 0) + { + index_close(indrel, lockmode); + continue; + } + + tuple = SearchSysCacheCopyAttNum(RelationGetRelid(indrel), indattnum); + + if (HeapTupleIsValid(tuple)) + { + Form_pg_attribute attrtuple = (Form_pg_attribute) GETSTRUCT(tuple); + + if (setstorage) + attrtuple->attstorage = newstorage; + + if (setcompression) + attrtuple->attcompression = newcompression; + + CatalogTupleUpdate(attrelation, &tuple->t_self, tuple); + + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + attrtuple->attnum); + + heap_freetuple(tuple); + } + + index_close(indrel, lockmode); + } +} + /* * ALTER TABLE ALTER COLUMN SET STORAGE * @@ -9278,7 +9929,6 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc Form_pg_attribute attrtuple; AttrNumber attnum; ObjectAddress address; - ListCell *lc; Assert(IsA(newValue, String)); storagemode = strVal(newValue); @@ -9342,47 +9992,10 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc * Apply the change to indexes as well (only for simple index columns, * matching behavior of index.c ConstructTupleDescriptor()). */ - foreach(lc, RelationGetIndexList(rel)) - { - Oid indexoid = lfirst_oid(lc); - Relation indrel; - AttrNumber indattnum = 0; - - indrel = index_open(indexoid, lockmode); - - for (int i = 0; i < indrel->rd_index->indnatts; i++) - { - if (indrel->rd_index->indkey.values[i] == attnum) - { - indattnum = i + 1; - break; - } - } - - if (indattnum == 0) - { - index_close(indrel, lockmode); - continue; - } - - tuple = SearchSysCacheCopyAttNum(RelationGetRelid(indrel), indattnum); - - if (HeapTupleIsValid(tuple)) - { - attrtuple = (Form_pg_attribute) GETSTRUCT(tuple); - attrtuple->attstorage = newstorage; - - CatalogTupleUpdate(attrelation, &tuple->t_self, tuple); - - InvokeObjectPostAlterHook(RelationRelationId, - RelationGetRelid(rel), - attrtuple->attnum); - - heap_freetuple(tuple); - } - - index_close(indrel, lockmode); - } + SetIndexStorageProperties(rel, attrelation, attnum, + true, newstorage, + false, 0, + lockmode); table_close(attrelation, RowExclusiveLock); @@ -9557,7 +10170,8 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, * routines, we have to do this one level of recursion at a time; we can't * use find_all_inheritors to do it in one pass. */ - children = find_inheritance_children(RelationGetRelid(rel), lockmode); + children = + find_inheritance_children(RelationGetRelid(rel), lockmode); if (children) { @@ -9737,6 +10351,29 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel, return address; } +/* + * ALTER TABLE ADD STATISTICS + * + * This is no such command in the grammar, but we use this internally to add + * AT_ReAddStatistics subcommands to rebuild extended statistics after a table + * column type change. + */ +static ObjectAddress +ATExecAddStatistics(AlteredTableInfo *tab, Relation rel, + CreateStatsStmt *stmt, bool is_rebuild, LOCKMODE lockmode) +{ + ObjectAddress address; + + Assert(IsA(stmt, CreateStatsStmt)); + + /* The CreateStatsStmt has already been through transformStatsStmt */ + Assert(stmt->transformed); + + address = CreateStatistics(stmt); + + return address; +} + /* * ALTER TABLE ADD CONSTRAINT USING INDEX * @@ -9883,7 +10520,7 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, NIL); address = ATAddForeignKeyConstraint(wqueue, tab, rel, - newConstraint, InvalidOid, + newConstraint, recurse, false, lockmode); break; @@ -10045,7 +10682,8 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * routines, we have to do this one level of recursion at a time; we can't * use find_all_inheritors to do it in one pass. */ - children = find_inheritance_children(RelationGetRelid(rel), lockmode); + children = + find_inheritance_children(RelationGetRelid(rel), lockmode); /* * If we are told not to recurse, there had better not be any child tables; @@ -10099,7 +10737,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, */ static ObjectAddress ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, - Constraint *fkconstraint, Oid parentConstr, + Constraint *fkconstraint, bool recurse, bool recursing, LOCKMODE lockmode) { Relation pkrel; @@ -10183,13 +10821,13 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, switch (rel->rd_rel->relpersistence) { case RELPERSISTENCE_PERMANENT: - if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT) + if (!RelationIsPermanent(pkrel)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("constraints on permanent tables may reference only permanent tables"))); break; case RELPERSISTENCE_UNLOGGED: - if (pkrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT + if (!RelationIsPermanent(pkrel) && pkrel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), @@ -10672,7 +11310,7 @@ addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel, */ if (pkrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - PartitionDesc pd = RelationGetPartitionDesc(pkrel); + PartitionDesc pd = RelationGetPartitionDesc(pkrel, true); for (int i = 0; i < pd->nparts; i++) { @@ -10806,7 +11444,7 @@ addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint, Relation rel, } else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - PartitionDesc pd = RelationGetPartitionDesc(rel); + PartitionDesc pd = RelationGetPartitionDesc(rel, true); /* * Recurse to take appropriate action on each partition; either we @@ -11477,28 +12115,29 @@ tryAttachPartitionForeignKey(ForeignKeyCacheInfo *fk, * Update the attributes of a constraint. * * Currently only works for Foreign Key constraints. - * Foreign keys do not inherit, so we purposely ignore the - * recursion bit here, but we keep the API the same for when - * other constraint types are supported. * * If the constraint is modified, returns its address; otherwise, return * InvalidObjectAddress. */ static ObjectAddress -ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, - bool recurse, bool recursing, LOCKMODE lockmode) +ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, bool recurse, + bool recursing, LOCKMODE lockmode) { Constraint *cmdcon; Relation conrel; + Relation tgrel; SysScanDesc scan; ScanKeyData skey[3]; HeapTuple contuple; Form_pg_constraint currcon; ObjectAddress address; + List *otherrelids = NIL; + ListCell *lc; cmdcon = castNode(Constraint, cmd->def); conrel = table_open(ConstraintRelationId, RowExclusiveLock); + tgrel = table_open(TriggerRelationId, RowExclusiveLock); /* * Find and check the target constraint @@ -11532,21 +12171,120 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, errmsg("constraint \"%s\" of relation \"%s\" is not a foreign key constraint", cmdcon->conname, RelationGetRelationName(rel)))); + /* + * If it's not the topmost constraint, raise an error. + * + * Altering a non-topmost constraint leaves some triggers untouched, since + * they are not directly connected to this constraint; also, pg_dump would + * ignore the deferrability status of the individual constraint, since it + * only dumps topmost constraints. Avoid these problems by refusing this + * operation and telling the user to alter the parent constraint instead. + */ + if (OidIsValid(currcon->conparentid)) + { + HeapTuple tp; + Oid parent = currcon->conparentid; + char *ancestorname = NULL; + char *ancestortable = NULL; + + /* Loop to find the topmost constraint */ + while (HeapTupleIsValid(tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(parent)))) + { + Form_pg_constraint contup = (Form_pg_constraint) GETSTRUCT(tp); + + /* If no parent, this is the constraint we want */ + if (!OidIsValid(contup->conparentid)) + { + ancestorname = pstrdup(NameStr(contup->conname)); + ancestortable = get_rel_name(contup->conrelid); + ReleaseSysCache(tp); + break; + } + + parent = contup->conparentid; + ReleaseSysCache(tp); + } + + ereport(ERROR, + (errmsg("cannot alter constraint \"%s\" on relation \"%s\"", + cmdcon->conname, RelationGetRelationName(rel)), + ancestorname && ancestortable ? + errdetail("Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\".", + cmdcon->conname, ancestorname, ancestortable) : 0, + errhint("You may alter the constraint it derives from, instead."))); + } + + /* + * Do the actual catalog work. We can skip changing if already in the + * desired state, but not if a partitioned table: partitions need to be + * processed regardless, in case they had the constraint locally changed. + */ + address = InvalidObjectAddress; + if (currcon->condeferrable != cmdcon->deferrable || + currcon->condeferred != cmdcon->initdeferred || + rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + if (ATExecAlterConstrRecurse(cmdcon, conrel, tgrel, rel, contuple, + &otherrelids, lockmode)) + ObjectAddressSet(address, ConstraintRelationId, currcon->oid); + } + + /* + * ATExecConstrRecurse already invalidated relcache for the relations + * having the constraint itself; here we also invalidate for relations + * that have any triggers that are part of the constraint. + */ + foreach(lc, otherrelids) + CacheInvalidateRelcacheByRelid(lfirst_oid(lc)); + + systable_endscan(scan); + + table_close(tgrel, RowExclusiveLock); + table_close(conrel, RowExclusiveLock); + + return address; +} + +/* + * Recursive subroutine of ATExecAlterConstraint. Returns true if the + * constraint is altered. + * + * *otherrelids is appended OIDs of relations containing affected triggers. + * + * Note that we must recurse even when the values are correct, in case + * indirect descendants have had their constraints altered locally. + * (This could be avoided if we forbade altering constraints in partitions + * but existing releases don't do that.) + */ +static bool +ATExecAlterConstrRecurse(Constraint *cmdcon, Relation conrel, Relation tgrel, + Relation rel, HeapTuple contuple, List **otherrelids, + LOCKMODE lockmode) +{ + Form_pg_constraint currcon; + Oid conoid; + Oid refrelid; + bool changed = false; + + currcon = (Form_pg_constraint) GETSTRUCT(contuple); + conoid = currcon->oid; + refrelid = currcon->confrelid; + + /* + * Update pg_constraint with the flags from cmdcon. + * + * If called to modify a constraint that's already in the desired state, + * silently do nothing. + */ if (currcon->condeferrable != cmdcon->deferrable || currcon->condeferred != cmdcon->initdeferred) { HeapTuple copyTuple; - HeapTuple tgtuple; Form_pg_constraint copy_con; - List *otherrelids = NIL; + HeapTuple tgtuple; ScanKeyData tgkey; SysScanDesc tgscan; - Relation tgrel; - ListCell *lc; - /* - * Now update the catalog, while we have the door open. - */ copyTuple = heap_copytuple(contuple); copy_con = (Form_pg_constraint) GETSTRUCT(copyTuple); copy_con->condeferrable = cmdcon->deferrable; @@ -11554,28 +12292,29 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, CatalogTupleUpdate(conrel, ©Tuple->t_self, copyTuple); InvokeObjectPostAlterHook(ConstraintRelationId, - currcon->oid, 0); + conoid, 0); heap_freetuple(copyTuple); + changed = true; + + /* Make new constraint flags visible to others */ + CacheInvalidateRelcache(rel); /* * Now we need to update the multiple entries in pg_trigger that * implement the constraint. */ - tgrel = table_open(TriggerRelationId, RowExclusiveLock); - ScanKeyInit(&tgkey, Anum_pg_trigger_tgconstraint, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(currcon->oid)); - + ObjectIdGetDatum(conoid)); tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true, NULL, 1, &tgkey); - while (HeapTupleIsValid(tgtuple = systable_getnext(tgscan))) { Form_pg_trigger tgform = (Form_pg_trigger) GETSTRUCT(tgtuple); Form_pg_trigger copy_tg; + HeapTuple copyTuple; /* * Remember OIDs of other relation(s) involved in FK constraint. @@ -11584,8 +12323,8 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, * change, but let's be conservative.) */ if (tgform->tgrelid != RelationGetRelid(rel)) - otherrelids = list_append_unique_oid(otherrelids, - tgform->tgrelid); + *otherrelids = list_append_unique_oid(*otherrelids, + tgform->tgrelid); /* * Update deferrability of RI_FKey_noaction_del, @@ -11606,37 +12345,52 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, copy_tg->tginitdeferred = cmdcon->initdeferred; CatalogTupleUpdate(tgrel, ©Tuple->t_self, copyTuple); - InvokeObjectPostAlterHook(TriggerRelationId, currcon->oid, 0); + InvokeObjectPostAlterHook(TriggerRelationId, tgform->oid, 0); heap_freetuple(copyTuple); } systable_endscan(tgscan); + } + + /* + * If the table at either end of the constraint is partitioned, we need to + * recurse and handle every constraint that is a child of this one. + * + * (This assumes that the recurse flag is forcibly set for partitioned + * tables, and not set for legacy inheritance, though we don't check for + * that here.) + */ + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE || + get_rel_relkind(refrelid) == RELKIND_PARTITIONED_TABLE) + { + ScanKeyData pkey; + SysScanDesc pscan; + HeapTuple childtup; - table_close(tgrel, RowExclusiveLock); + ScanKeyInit(&pkey, + Anum_pg_constraint_conparentid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(conoid)); - /* - * Invalidate relcache so that others see the new attributes. We must - * inval both the named rel and any others having relevant triggers. - * (At present there should always be exactly one other rel, but - * there's no need to hard-wire such an assumption here.) - */ - CacheInvalidateRelcache(rel); - foreach(lc, otherrelids) + pscan = systable_beginscan(conrel, ConstraintParentIndexId, + true, NULL, 1, &pkey); + + while (HeapTupleIsValid(childtup = systable_getnext(pscan))) { - CacheInvalidateRelcacheByRelid(lfirst_oid(lc)); - } + Form_pg_constraint childcon = (Form_pg_constraint) GETSTRUCT(childtup); + Relation childrel; - ObjectAddressSet(address, ConstraintRelationId, currcon->oid); - } - else - address = InvalidObjectAddress; - - systable_endscan(scan); + childrel = table_open(childcon->conrelid, lockmode); + ATExecAlterConstrRecurse(cmdcon, conrel, tgrel, childrel, childtup, + otherrelids, lockmode); + table_close(childrel, NoLock); + } - table_close(conrel, RowExclusiveLock); + systable_endscan(pscan); + } - return address; + return changed; } /* @@ -12194,7 +12948,7 @@ validateForeignKeyConstraint(char *conname, MemoryContext perTupCxt; ereport(DEBUG1, - (errmsg("validating foreign key constraint \"%s\"", conname))); + (errmsg_internal("validating foreign key constraint \"%s\"", conname))); /* Greenplum Database: Ignore foreign keys for now, with a warning. */ if (Gp_role == GP_ROLE_DISPATCH || Gp_role == GP_ROLE_UTILITY) @@ -12292,10 +13046,10 @@ CreateFKCheckTrigger(Oid myRelOid, Oid refRelOid, Constraint *fkconstraint, * and "RI_ConstraintTrigger_c_NNNN" for the check triggers. */ fk_trigger = makeNode(CreateTrigStmt); + fk_trigger->replace = false; + fk_trigger->isconstraint = true; fk_trigger->trigname = "RI_ConstraintTrigger_c"; fk_trigger->relation = NULL; - fk_trigger->row = true; - fk_trigger->timing = TRIGGER_TYPE_AFTER; /* Either ON INSERT or ON UPDATE */ if (on_insert) @@ -12309,14 +13063,15 @@ CreateFKCheckTrigger(Oid myRelOid, Oid refRelOid, Constraint *fkconstraint, fk_trigger->events = TRIGGER_TYPE_UPDATE; } + fk_trigger->args = NIL; + fk_trigger->row = true; + fk_trigger->timing = TRIGGER_TYPE_AFTER; fk_trigger->columns = NIL; - fk_trigger->transitionRels = NIL; fk_trigger->whenClause = NULL; - fk_trigger->isconstraint = true; + fk_trigger->transitionRels = NIL; fk_trigger->deferrable = fkconstraint->deferrable; fk_trigger->initdeferred = fkconstraint->initdeferred; fk_trigger->constrrel = NULL; - fk_trigger->args = NIL; (void) CreateTrigger(fk_trigger, NULL, myRelOid, refRelOid, constraintOid, indexOid, InvalidOid, InvalidOid, NULL, true, false); @@ -12351,15 +13106,17 @@ createForeignKeyActionTriggers(Relation rel, Oid refRelOid, Constraint *fkconstr * DELETE action on the referenced table. */ fk_trigger = makeNode(CreateTrigStmt); + fk_trigger->replace = false; + fk_trigger->isconstraint = true; fk_trigger->trigname = "RI_ConstraintTrigger_a"; fk_trigger->relation = NULL; + fk_trigger->args = NIL; fk_trigger->row = true; fk_trigger->timing = TRIGGER_TYPE_AFTER; fk_trigger->events = TRIGGER_TYPE_DELETE; fk_trigger->columns = NIL; - fk_trigger->transitionRels = NIL; fk_trigger->whenClause = NULL; - fk_trigger->isconstraint = true; + fk_trigger->transitionRels = NIL; fk_trigger->constrrel = NULL; switch (fkconstraint->fk_del_action) { @@ -12393,7 +13150,6 @@ createForeignKeyActionTriggers(Relation rel, Oid refRelOid, Constraint *fkconstr (int) fkconstraint->fk_del_action); break; } - fk_trigger->args = NIL; (void) CreateTrigger(fk_trigger, NULL, refRelOid, RelationGetRelid(rel), constraintOid, @@ -12407,15 +13163,17 @@ createForeignKeyActionTriggers(Relation rel, Oid refRelOid, Constraint *fkconstr * UPDATE action on the referenced table. */ fk_trigger = makeNode(CreateTrigStmt); + fk_trigger->replace = false; + fk_trigger->isconstraint = true; fk_trigger->trigname = "RI_ConstraintTrigger_a"; fk_trigger->relation = NULL; + fk_trigger->args = NIL; fk_trigger->row = true; fk_trigger->timing = TRIGGER_TYPE_AFTER; fk_trigger->events = TRIGGER_TYPE_UPDATE; fk_trigger->columns = NIL; - fk_trigger->transitionRels = NIL; fk_trigger->whenClause = NULL; - fk_trigger->isconstraint = true; + fk_trigger->transitionRels = NIL; fk_trigger->constrrel = NULL; switch (fkconstraint->fk_upd_action) { @@ -12449,7 +13207,6 @@ createForeignKeyActionTriggers(Relation rel, Oid refRelOid, Constraint *fkconstr (int) fkconstraint->fk_upd_action); break; } - fk_trigger->args = NIL; (void) CreateTrigger(fk_trigger, NULL, refRelOid, RelationGetRelid(rel), constraintOid, @@ -13435,9 +14192,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, * Give the extended-stats machinery a chance to fix anything * that this column type change would break. */ - UpdateStatisticsForTypeChange(foundObject.objectId, - RelationGetRelid(rel), attnum, - attTup->atttypid, targettype); + RememberStatisticsForRebuilding(foundObject.objectId, tab); break; case OCLASS_PROC: @@ -13619,6 +14374,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, attTup->attbyval = tform->typbyval; attTup->attalign = tform->typalign; attTup->attstorage = tform->typstorage; + attTup->attcompression = InvalidCompressionMethod; ReleaseSysCache(typeTuple); @@ -13828,6 +14584,32 @@ RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab) } } +/* + * Subroutine for ATExecAlterColumnType: remember that a statistics object + * needs to be rebuilt (which we might already know). + */ +static void +RememberStatisticsForRebuilding(Oid stxoid, AlteredTableInfo *tab) +{ + /* + * This de-duplication check is critical for two independent reasons: we + * mustn't try to recreate the same statistics object twice, and if the + * statistics depends on more than one column whose type is to be altered, + * we must capture its definition string before applying any of the type + * changes. ruleutils.c will get confused if we ask again later. + */ + if (!list_member_oid(tab->changedStatisticsOids, stxoid)) + { + /* OK, capture the index's existing definition string */ + char *defstring = pg_get_statisticsobjdef_string(stxoid); + + tab->changedStatisticsOids = lappend_oid(tab->changedStatisticsOids, + stxoid); + tab->changedStatisticsDefs = lappend(tab->changedStatisticsDefs, + defstring); + } +} + /* * Cleanup after we've finished all the ALTER TYPE operations for a * particular relation. We have to drop and recreate all the indexes @@ -13948,6 +14730,22 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) add_exact_object_address(&obj, objects); } + /* add dependencies for new statistics */ + forboth(oid_item, tab->changedStatisticsOids, + def_item, tab->changedStatisticsDefs) + { + Oid oldId = lfirst_oid(oid_item); + Oid relid; + + relid = StatisticsGetRelation(oldId, false); + ATPostAlterTypeParse(oldId, relid, InvalidOid, + (char *) lfirst(def_item), + wqueue, lockmode, tab->rewrite); + + ObjectAddressSet(obj, StatisticExtRelationId, oldId); + add_exact_object_address(&obj, objects); + } + /* * Queue up command to restore replica identity index marking */ @@ -13996,9 +14794,9 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) } /* - * Parse the previously-saved definition string for a constraint or index - * against the newly-established column data type(s), and queue up the - * resulting command parsetrees for execution. + * Parse the previously-saved definition string for a constraint, index or + * statistics object against the newly-established column data type(s), and + * queue up the resulting command parsetrees for execution. * * This might fail if, for example, you have a WHERE clause that uses an * operator that's not available for the new column type. @@ -14025,7 +14823,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, * parse_analyze() or the rewriter, but instead we need to pass them * through parse_utilcmd.c to make them ready for execution. */ - raw_parsetree_list = raw_parser(cmd); + raw_parsetree_list = raw_parser(cmd, RAW_PARSE_DEFAULT); querytree_list = NIL; foreach(list_item, raw_parsetree_list) { @@ -14051,6 +14849,11 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, querytree_list = lappend(querytree_list, stmt); querytree_list = list_concat(querytree_list, afterStmts); } + else if (IsA(stmt, CreateStatsStmt)) + querytree_list = lappend(querytree_list, + transformStatsStmt(oldRelId, + (CreateStatsStmt *) stmt, + cmd)); else querytree_list = lappend(querytree_list, stmt); } @@ -14189,6 +14992,20 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, elog(ERROR, "unexpected statement subtype: %d", (int) stmt->subtype); } + else if (IsA(stm, CreateStatsStmt)) + { + CreateStatsStmt *stmt = (CreateStatsStmt *) stm; + AlterTableCmd *newcmd; + + /* keep the statistics object's comment */ + stmt->stxcomment = GetComment(oldId, StatisticExtRelationId, 0); + + newcmd = makeNode(AlterTableCmd); + newcmd->subtype = AT_ReAddStatistics; + newcmd->def = (Node *) stmt; + tab->subcmds[AT_PASS_MISC] = + lappend(tab->subcmds[AT_PASS_MISC], newcmd); + } else elog(ERROR, "unexpected statement type: %d", (int) nodeTag(stm)); @@ -15243,8 +16060,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) { - Relation rel; - Oid oldTableSpace; + Relation rel; Oid reltoastrelid; Oid relaosegrelid = InvalidOid; Oid relaoblkdirrelid = InvalidOid; @@ -15255,9 +16071,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) Oid relbmidxid = InvalidOid; Oid newrelfilenode; RelFileNode newrnode; - Relation pg_class; - HeapTuple tuple; - Form_pg_class rd_rel; List *reltoastidxids = NIL; ListCell *lc; @@ -15266,45 +16079,15 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) */ rel = relation_open(tableOid, lockmode); - /* - * No work if no change in tablespace. - */ - oldTableSpace = rel->rd_rel->reltablespace; - if (newTableSpace == oldTableSpace || - (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0)) + /* Check first if relation can be moved to new tablespace */ + if (!CheckRelationTableSpaceMove(rel, newTableSpace)) { InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), 0); - relation_close(rel, NoLock); return; } - /* - * We cannot support moving mapped relations into different tablespaces. - * (In particular this eliminates all shared catalogs.) - */ - if (RelationIsMapped(rel)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot move system relation \"%s\"", - RelationGetRelationName(rel)))); - - /* Can't move a non-shared relation into pg_global */ - if (newTableSpace == GLOBALTABLESPACE_OID) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("only shared relations can be placed in pg_global tablespace"))); - - /* - * Don't allow moving temp tables of other backends ... their local buffer - * manager is not going to cope. - */ - if (RELATION_IS_OTHER_TEMP(rel)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot move temporary tables of other sessions"))); - reltoastrelid = rel->rd_rel->reltoastrelid; /* Fetch the list of indexes on toast relation if necessary */ if (OidIsValid(reltoastrelid)) @@ -15326,14 +16109,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) if (RelationIsBitmapIndex(rel)) GetBitmapIndexAuxOids(rel, &relbmrelid, &relbmidxid); - /* Get a modifiable copy of the relation's pg_class row */ - pg_class = table_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(tableOid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", tableOid); - rd_rel = (Form_pg_class) GETSTRUCT(tuple); - /* * Relfilenodes are not unique in databases across tablespaces, so we need * to allocate a new one in the new tablespace. @@ -15367,18 +16142,13 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) * * NB: This wouldn't work if ATExecSetTableSpace() were allowed to be * executed on pg_class or its indexes (the above copy wouldn't contain - * the updated pg_class entry), but that's forbidden above. + * the updated pg_class entry), but that's forbidden with + * CheckRelationTableSpaceMove(). */ - rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace; - rd_rel->relfilenode = newrelfilenode; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + SetRelationTableSpace(rel, newTableSpace, newrelfilenode); InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), 0); - heap_freetuple(tuple); - - table_close(pg_class, RowExclusiveLock); - RelationAssumeNewRelfilenode(rel); /* MPP-6929: metadata tracking */ @@ -15494,52 +16264,25 @@ ATExecSetAccessMethodNoStorage(Relation rel, Oid newAccessMethod) static void ATExecSetTableSpaceNoStorage(Relation rel, Oid newTableSpace) { - HeapTuple tuple; - Oid oldTableSpace; - Relation pg_class; - Form_pg_class rd_rel; - Oid reloid = RelationGetRelid(rel); - /* * Shouldn't be called on relations having storage; these are processed in * phase 3. */ Assert(!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)); - /* Can't allow a non-shared relation in pg_global */ - if (newTableSpace == GLOBALTABLESPACE_OID) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("only shared relations can be placed in pg_global tablespace"))); - - /* - * No work if no change in tablespace. - */ - oldTableSpace = rel->rd_rel->reltablespace; - if (newTableSpace == oldTableSpace || - (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0)) + /* check if relation can be moved to its new tablespace */ + if (!CheckRelationTableSpaceMove(rel, newTableSpace)) { - InvokeObjectPostAlterHook(RelationRelationId, reloid, 0); + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + 0); return; } - /* Get a modifiable copy of the relation's pg_class row */ - pg_class = table_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", reloid); - rd_rel = (Form_pg_class) GETSTRUCT(tuple); - - /* update the pg_class row */ - rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - - InvokeObjectPostAlterHook(RelationRelationId, reloid, 0); - - heap_freetuple(tuple); + /* Update can be done, so change reltablespace */ + SetRelationTableSpace(rel, newTableSpace, InvalidOid); - table_close(pg_class, RowExclusiveLock); + InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), 0); /* Make sure the reltablespace change is visible */ CommandCounterIncrement(); @@ -15773,7 +16516,7 @@ index_copy_data(Relation rel, RelFileNode newrnode) * WAL log creation if the relation is persistent, or this is the * init fork of an unlogged relation. */ - if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT || + if (RelationIsPermanent(rel) || (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && forkNum == INIT_FORKNUM)) log_smgrcreate(&newrnode, forkNum, smgr_which); @@ -16179,6 +16922,66 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel) errmsg("column \"%s\" in child table must be marked NOT NULL", attributeName))); + /* + * If parent column is generated, child column must be, too. + */ + if (attribute->attgenerated && !childatt->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("column \"%s\" in child table must be a generated column", + attributeName))); + + /* + * Check that both generation expressions match. + * + * The test we apply is to see whether they reverse-compile to the + * same source string. This insulates us from issues like whether + * attributes have the same physical column numbers in parent and + * child relations. (See also constraints_equivalent().) + */ + if (attribute->attgenerated && childatt->attgenerated) + { + TupleConstr *child_constr = child_rel->rd_att->constr; + TupleConstr *parent_constr = parent_rel->rd_att->constr; + char *child_expr = NULL; + char *parent_expr = NULL; + + Assert(child_constr != NULL); + Assert(parent_constr != NULL); + + for (int i = 0; i < child_constr->num_defval; i++) + { + if (child_constr->defval[i].adnum == childatt->attnum) + { + child_expr = + TextDatumGetCString(DirectFunctionCall2(pg_get_expr, + CStringGetTextDatum(child_constr->defval[i].adbin), + ObjectIdGetDatum(child_rel->rd_id))); + break; + } + } + Assert(child_expr != NULL); + + for (int i = 0; i < parent_constr->num_defval; i++) + { + if (parent_constr->defval[i].adnum == attribute->attnum) + { + parent_expr = + TextDatumGetCString(DirectFunctionCall2(pg_get_expr, + CStringGetTextDatum(parent_constr->defval[i].adbin), + ObjectIdGetDatum(parent_rel->rd_id))); + break; + } + } + Assert(parent_expr != NULL); + + if (strcmp(child_expr, parent_expr) != 0) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("column \"%s\" in child table has a conflicting generation expression", + attributeName))); + } + /* * OK, bump the child column's inheritance count. (If we fail * later on, this change will just roll back.) @@ -16382,7 +17185,7 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) */ /* Off to RemoveInheritance() where most of the work happens */ - RemoveInheritance(rel, parent_rel); + RemoveInheritance(rel, parent_rel, false); ObjectAddressSet(address, RelationRelationId, RelationGetRelid(parent_rel)); @@ -16402,12 +17205,86 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) return address; } +/* + * MarkInheritDetached + * + * Set inhdetachpending for a partition, for ATExecDetachPartition + * in concurrent mode. While at it, verify that no other partition is + * already pending detach. + */ +static void +MarkInheritDetached(Relation child_rel, Relation parent_rel) +{ + Relation catalogRelation; + SysScanDesc scan; + ScanKeyData key; + HeapTuple inheritsTuple; + bool found = false; + + Assert(child_rel->rd_rel->relkind == RELKIND_RELATION || + child_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); + Assert(parent_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); + + /* + * Find pg_inherits entries by inhparent. (We need to scan them all in + * order to verify that no other partition is pending detach.) + */ + catalogRelation = table_open(InheritsRelationId, RowExclusiveLock); + ScanKeyInit(&key, + Anum_pg_inherits_inhparent, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(parent_rel))); + scan = systable_beginscan(catalogRelation, InheritsParentIndexId, + true, NULL, 1, &key); + + while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan))) + { + Form_pg_inherits inhForm; + + inhForm = (Form_pg_inherits) GETSTRUCT(inheritsTuple); + if (inhForm->inhdetachpending) + ereport(ERROR, + errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("partition \"%s\" already pending detach in partitioned table \"%s.%s\"", + get_rel_name(inhForm->inhrelid), + get_namespace_name(parent_rel->rd_rel->relnamespace), + RelationGetRelationName(parent_rel)), + errhint("Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation.")); + + if (inhForm->inhrelid == RelationGetRelid(child_rel)) + { + HeapTuple newtup; + + newtup = heap_copytuple(inheritsTuple); + ((Form_pg_inherits) GETSTRUCT(newtup))->inhdetachpending = true; + + CatalogTupleUpdate(catalogRelation, + &inheritsTuple->t_self, + newtup); + found = true; + heap_freetuple(newtup); + /* keep looking, to ensure we catch others pending detach */ + } + } + + /* Done */ + systable_endscan(scan); + table_close(catalogRelation, RowExclusiveLock); + + if (!found) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("relation \"%s\" is not a partition of relation \"%s\"", + RelationGetRelationName(child_rel), + RelationGetRelationName(parent_rel)))); +} + /* * RemoveInheritance * * Drop a parent from the child's parents. This just adjusts the attinhcount * and attislocal of the columns and removes the pg_inherit and pg_depend - * entries. + * entries. expect_detached is passed down to DeleteInheritsTuple, q.v.. * * If attinhcount goes to 0 then attislocal gets set to true. If it goes back * up attislocal stays true, which means if a child is ever removed from a @@ -16421,7 +17298,7 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) * Common to ATExecDropInherit() and ATExecDetachPartition(). */ static void -RemoveInheritance(Relation child_rel, Relation parent_rel) +RemoveInheritance(Relation child_rel, Relation parent_rel, bool expect_detached) { Relation catalogRelation; SysScanDesc scan; @@ -16437,7 +17314,9 @@ RemoveInheritance(Relation child_rel, Relation parent_rel) child_is_partition = true; found = DeleteInheritsTuple(RelationGetRelid(child_rel), - RelationGetRelid(parent_rel)); + RelationGetRelid(parent_rel), + expect_detached, + RelationGetRelationName(child_rel)); if (!found) { if (child_is_partition) @@ -17109,6 +17988,7 @@ prebuild_temp_table(Relation rel, RangeVar *tmpname, DistributedBy *distro, ProcessUtility(pstmt, synthetic_sql, + false, PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, @@ -17559,7 +18439,7 @@ ATExecExpandTableCTAS(AlterTableCmd *rootCmd, Relation rel, AlterTableCmd *cmd) CommandCounterIncrement(); /* now, reindex */ - reindex_relation(relid, 0, 0); + reindex_relation(relid, 0, &(ReindexParams) {0}); /* Step (h) Drop the table */ { @@ -18113,7 +18993,7 @@ ATExecSetDistributedBy(Relation rel, Node *node, AlterTableCmd *cmd) CommandCounterIncrement(); /* now, reindex */ - reindex_relation(tarrelid, 0, 0); + reindex_relation(tarrelid, 0, &(ReindexParams) {0}); } /* Step (g) */ @@ -18616,30 +19496,7 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode * ALTER TABLE ENABLE/DISABLE ROW LEVEL SECURITY */ static void -ATExecEnableRowSecurity(Relation rel) -{ - Relation pg_class; - Oid relid; - HeapTuple tuple; - - relid = RelationGetRelid(rel); - - pg_class = table_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); - - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", relid); - - ((Form_pg_class) GETSTRUCT(tuple))->relrowsecurity = true; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - - table_close(pg_class, RowExclusiveLock); - heap_freetuple(tuple); -} - -static void -ATExecDisableRowSecurity(Relation rel) +ATExecSetRowSecurity(Relation rel, bool rls) { Relation pg_class; Oid relid; @@ -18655,7 +19512,7 @@ ATExecDisableRowSecurity(Relation rel) if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", relid); - ((Form_pg_class) GETSTRUCT(tuple))->relrowsecurity = false; + ((Form_pg_class) GETSTRUCT(tuple))->relrowsecurity = rls; CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); table_close(pg_class, RowExclusiveLock); @@ -18767,29 +19624,106 @@ ATExecGenericOptions(Relation rel, List *options) } /* - * Preparation phase for SET LOGGED/UNLOGGED - * - * This verifies that we're not trying to change a temp table. Also, - * existing foreign key constraints are checked to avoid ending up with - * permanent tables referencing unlogged tables. + * ALTER TABLE ALTER COLUMN SET COMPRESSION * - * Return value is false if the operation is a no-op (in which case the - * checks are skipped), otherwise true. + * Return value is the address of the modified column */ -static bool -ATPrepChangePersistence(Relation rel, bool toLogged) +static ObjectAddress +ATExecSetCompression(AlteredTableInfo *tab, + Relation rel, + const char *column, + Node *newValue, + LOCKMODE lockmode) { - Relation pg_constraint; + Relation attrel; HeapTuple tuple; - SysScanDesc scan; - ScanKeyData skey[1]; + Form_pg_attribute atttableform; + AttrNumber attnum; + char *compression; + char cmethod; + ObjectAddress address; + + Assert(IsA(newValue, String)); + compression = strVal(newValue); + + attrel = table_open(AttributeRelationId, RowExclusiveLock); + + /* copy the cache entry so we can scribble on it below */ + tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), column); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + column, RelationGetRelationName(rel)))); + + /* prevent them from altering a system attribute */ + atttableform = (Form_pg_attribute) GETSTRUCT(tuple); + attnum = atttableform->attnum; + if (attnum <= 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot alter system column \"%s\"", column))); /* - * Disallow changing status for a temp table. Also verify whether we can - * get away with doing nothing; in such cases we don't need to run the - * checks below, either. + * Check that column type is compressible, then get the attribute + * compression method code */ - switch (rel->rd_rel->relpersistence) + cmethod = GetAttributeCompression(atttableform->atttypid, compression); + + /* update pg_attribute entry */ + atttableform->attcompression = cmethod; + CatalogTupleUpdate(attrel, &tuple->t_self, tuple); + + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + attnum); + + /* + * Apply the change to indexes as well (only for simple index columns, + * matching behavior of index.c ConstructTupleDescriptor()). + */ + SetIndexStorageProperties(rel, attrel, attnum, + false, 0, + true, cmethod, + lockmode); + + heap_freetuple(tuple); + + table_close(attrel, RowExclusiveLock); + + /* make changes visible */ + CommandCounterIncrement(); + + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); + return address; +} + + +/* + * Preparation phase for SET LOGGED/UNLOGGED + * + * This verifies that we're not trying to change a temp table. Also, + * existing foreign key constraints are checked to avoid ending up with + * permanent tables referencing unlogged tables. + * + * Return value is false if the operation is a no-op (in which case the + * checks are skipped), otherwise true. + */ +static bool +ATPrepChangePersistence(Relation rel, bool toLogged) +{ + Relation pg_constraint; + HeapTuple tuple; + SysScanDesc scan; + ScanKeyData skey[1]; + + /* + * Disallow changing status for a temp table. Also verify whether we can + * get away with doing nothing; in such cases we don't need to run the + * checks below, either. + */ + switch (rel->rd_rel->relpersistence) { case RELPERSISTENCE_TEMP: ereport(ERROR, @@ -18862,7 +19796,7 @@ ATPrepChangePersistence(Relation rel, bool toLogged) if (toLogged) { - if (foreignrel->rd_rel->relpersistence != RELPERSISTENCE_PERMANENT) + if (!RelationIsPermanent(foreignrel)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("could not change table \"%s\" to logged because it references unlogged table \"%s\"", @@ -18872,7 +19806,7 @@ ATPrepChangePersistence(Relation rel, bool toLogged) } else { - if (foreignrel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT) + if (RelationIsPermanent(foreignrel)) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("could not change table \"%s\" to unlogged because it references logged table \"%s\"", @@ -20117,12 +21051,12 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, { if (!validate_default) ereport(DEBUG1, - (errmsg("partition constraint for table \"%s\" is implied by existing constraints", - RelationGetRelationName(scanrel)))); + (errmsg_internal("partition constraint for table \"%s\" is implied by existing constraints", + RelationGetRelationName(scanrel)))); else ereport(DEBUG1, - (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", - RelationGetRelationName(scanrel)))); + (errmsg_internal("updated partition constraint for default partition \"%s\" is implied by existing constraints", + RelationGetRelationName(scanrel)))); return; } @@ -20156,7 +21090,7 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, } else if (scanrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - PartitionDesc partdesc = RelationGetPartitionDesc(scanrel); + PartitionDesc partdesc = RelationGetPartitionDesc(scanrel, true); int i; for (i = 0; i < partdesc->nparts; i++) @@ -20191,7 +21125,8 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, * Return the address of the newly attached partition. */ static ObjectAddress -ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) +ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd, + AlterTableUtilityContext *context) { Relation attachrel, catalog; @@ -20206,13 +21141,16 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) const char *trigger_name; Oid defaultPartOid; List *partBoundConstraint; + ParseState *pstate = make_parsestate(NULL); + + pstate->p_sourcetext = context->queryString; /* * We must lock the default partition if one exists, because attaching a * new partition will change its partition constraint. */ defaultPartOid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(rel)); + get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true)); if (OidIsValid(defaultPartOid)) LockRelationOid(defaultPartOid, AccessExclusiveLock); @@ -20389,7 +21327,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) * error. */ check_new_partition_bound(RelationGetRelationName(attachrel), rel, - cmd->bound); + cmd->bound, pstate); /* OK to create inheritance. Rest of the checks performed there */ CreateInheritance(attachrel, rel); @@ -20553,7 +21491,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) errmsg("cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"", RelationGetRelationName(attachrel), RelationGetRelationName(rel)), - errdetail("Table \"%s\" contains unique indexes.", + errdetail("Partitioned table \"%s\" contains unique indexes.", RelationGetRelationName(rel)))); index_close(idxRel, AccessShareLock); } @@ -20791,6 +21729,8 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) } trigStmt = makeNode(CreateTrigStmt); + trigStmt->replace = false; + trigStmt->isconstraint = OidIsValid(trigForm->tgconstraint); trigStmt->trigname = NameStr(trigForm->tgname); trigStmt->relation = NULL; trigStmt->funcname = NULL; /* passed separately */ @@ -20800,7 +21740,6 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) trigStmt->events = trigForm->tgtype & TRIGGER_TYPE_EVENT_MASK; trigStmt->columns = cols; trigStmt->whenClause = NULL; /* passed separately */ - trigStmt->isconstraint = OidIsValid(trigForm->tgconstraint); trigStmt->transitionRels = NIL; /* not supported at present */ trigStmt->deferrable = trigForm->tgdeferrable; trigStmt->initdeferred = trigForm->tginitdeferred; @@ -20825,105 +21764,213 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) * ALTER TABLE DETACH PARTITION * * Return the address of the relation that is no longer a partition of rel. + * + * If concurrent mode is requested, we run in two transactions. A side- + * effect is that this command cannot run in a multi-part ALTER TABLE. + * Currently, that's enforced by the grammar. + * + * The strategy for concurrency is to first modify the partition's + * pg_inherit catalog row to make it visible to everyone that the + * partition is detached, lock the partition against writes, and commit + * the transaction; anyone who requests the partition descriptor from + * that point onwards has to ignore such a partition. In a second + * transaction, we wait until all transactions that could have seen the + * partition as attached are gone, then we remove the rest of partition + * metadata (pg_inherits and pg_class.relpartbounds). */ static ObjectAddress -ATExecDetachPartition(Relation rel, RangeVar *name) +ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, + RangeVar *name, bool concurrent) { - Relation partRel, - classRel; - HeapTuple tuple, - newtuple; - Datum new_val[Natts_pg_class]; - bool new_null[Natts_pg_class], - new_repl[Natts_pg_class]; + Relation partRel; ObjectAddress address; Oid defaultPartOid; - List *indexes; - List *fks; - ListCell *cell; /* * We must lock the default partition, because detaching this partition * will change its partition constraint. */ defaultPartOid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(rel)); + get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true)); if (OidIsValid(defaultPartOid)) + { + /* + * Concurrent detaching when a default partition exists is not + * supported. The main problem is that the default partition + * constraint would change. And there's a definitional problem: what + * should happen to the tuples that are being inserted that belong to + * the partition being detached? Putting them on the partition being + * detached would be wrong, since they'd become "lost" after the but + * we cannot put them in the default partition either until we alter + * its partition constraint. + * + * I think we could solve this problem if we effected the constraint + * change before committing the first transaction. But the lock would + * have to remain AEL and it would cause concurrent query planning to + * be blocked, so changing it that way would be even worse. + */ + if (concurrent) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot detach partitions concurrently when a default partition exists"))); LockRelationOid(defaultPartOid, AccessExclusiveLock); + } - partRel = table_openrv(name, ShareUpdateExclusiveLock); + /* + * In concurrent mode, the partition is locked with share-update-exclusive + * in the first transaction. This allows concurrent transactions to be + * doing DML to the partition. + */ + partRel = table_openrv(name, concurrent ? ShareUpdateExclusiveLock : + AccessExclusiveLock); - /* Ensure that foreign keys still hold after this detach */ + /* + * Check inheritance conditions and either delete the pg_inherits row (in + * non-concurrent mode) or just set the inhdetachpending flag. + */ + if (!concurrent) + RemoveInheritance(partRel, rel, false); + else + MarkInheritDetached(partRel, rel); + + /* + * Ensure that foreign keys still hold after this detach. This keeps + * locks on the referencing tables, which prevents concurrent transactions + * from adding rows that we wouldn't see. For this to work in concurrent + * mode, it is critical that the partition appears as no longer attached + * for the RI queries as soon as the first transaction commits. + */ ATDetachCheckNoForeignKeyRefs(partRel); - /* All inheritance related checks are performed within the function */ - RemoveInheritance(partRel, rel); + /* + * Concurrent mode has to work harder; first we add a new constraint to + * the partition that matches the partition constraint. Then we close our + * existing transaction, and in a new one wait for all processes to catch + * up on the catalog updates we've done so far; at that point we can + * complete the operation. + */ + if (concurrent) + { + Oid partrelid, + parentrelid; + LOCKTAG tag; + char *parentrelname; + char *partrelname; - /* Update pg_class tuple */ - classRel = table_open(RelationRelationId, RowExclusiveLock); - tuple = SearchSysCacheCopy1(RELOID, - ObjectIdGetDatum(RelationGetRelid(partRel))); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", - RelationGetRelid(partRel)); - Assert(((Form_pg_class) GETSTRUCT(tuple))->relispartition); + /* + * Add a new constraint to the partition being detached, which + * supplants the partition constraint (unless there is one already). + */ + DetachAddConstraintIfNeeded(wqueue, partRel); - /* Clear relpartbound and reset relispartition */ - memset(new_val, 0, sizeof(new_val)); - memset(new_null, false, sizeof(new_null)); - memset(new_repl, false, sizeof(new_repl)); - new_val[Anum_pg_class_relpartbound - 1] = (Datum) 0; - new_null[Anum_pg_class_relpartbound - 1] = true; - new_repl[Anum_pg_class_relpartbound - 1] = true; - newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel), - new_val, new_null, new_repl); + /* + * We're almost done now; the only traces that remain are the + * pg_inherits tuple and the partition's relpartbounds. Before we can + * remove those, we need to wait until all transactions that know that + * this is a partition are gone. + */ - ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = false; - CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple); - heap_freetuple(newtuple); + /* + * Remember relation OIDs to re-acquire them later; and relation names + * too, for error messages if something is dropped in between. + */ + partrelid = RelationGetRelid(partRel); + parentrelid = RelationGetRelid(rel); + parentrelname = MemoryContextStrdup(PortalContext, + RelationGetRelationName(rel)); + partrelname = MemoryContextStrdup(PortalContext, + RelationGetRelationName(partRel)); + + /* Invalidate relcache entries for the parent -- must be before close */ + CacheInvalidateRelcache(rel); + + table_close(partRel, NoLock); + table_close(rel, NoLock); + tab->rel = NULL; + + /* Make updated catalog entry visible */ + PopActiveSnapshot(); + CommitTransactionCommand(); + + StartTransactionCommand(); - if (OidIsValid(defaultPartOid)) - { /* - * If the relation being detached is the default partition itself, - * remove it from the parent's pg_partitioned_table entry. + * Now wait. This ensures that all queries that were planned + * including the partition are finished before we remove the rest of + * catalog entries. We don't need or indeed want to acquire this + * lock, though -- that would block later queries. * - * If not, we must invalidate default partition's relcache entry, as - * in StorePartitionBound: its partition constraint depends on every - * other partition's partition constraint. + * We don't need to concern ourselves with waiting for a lock on the + * partition itself, since we will acquire AccessExclusiveLock below. */ - if (RelationGetRelid(partRel) == defaultPartOid) - update_default_partition_oid(RelationGetRelid(rel), InvalidOid); - else - CacheInvalidateRelcacheByRelid(defaultPartOid); + SET_LOCKTAG_RELATION(tag, MyDatabaseId, parentrelid); + WaitForLockersMultiple(list_make1(&tag), AccessExclusiveLock, false); + + /* + * Now acquire locks in both relations again. Note they may have been + * removed in the meantime, so care is required. + */ + rel = try_relation_open(parentrelid, ShareUpdateExclusiveLock, false); + partRel = try_relation_open(partrelid, AccessExclusiveLock, false); + + /* If the relations aren't there, something bad happened; bail out */ + if (rel == NULL) + { + if (partRel != NULL) /* shouldn't happen */ + elog(WARNING, "dangling partition \"%s\" remains, can't fix", + partrelname); + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("partitioned table \"%s\" was removed concurrently", + parentrelname))); + } + if (partRel == NULL) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("partition \"%s\" was removed concurrently", partrelname))); + + tab->rel = rel; } - /* detach indexes too */ - indexes = RelationGetIndexList(partRel); - foreach(cell, indexes) - { - Oid idxid = lfirst_oid(cell); - Relation idx; - Oid constrOid; + /* Do the final part of detaching */ + DetachPartitionFinalize(rel, partRel, concurrent, defaultPartOid); - if (!has_superclass(idxid)) - continue; + ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partRel)); - Assert((IndexGetRelation(get_partition_parent(idxid), false) == - RelationGetRelid(rel))); + /* keep our lock until commit */ + table_close(partRel, NoLock); - idx = index_open(idxid, AccessExclusiveLock); - IndexSetParentIndex(idx, InvalidOid); + return address; +} - /* If there's a constraint associated with the index, detach it too */ - constrOid = get_relation_idx_constraint_oid(RelationGetRelid(partRel), - idxid); - if (OidIsValid(constrOid)) - ConstraintSetParentConstraint(constrOid, InvalidOid, InvalidOid); +/* + * Second part of ALTER TABLE .. DETACH. + * + * This is separate so that it can be run independently when the second + * transaction of the concurrent algorithm fails (crash or abort). + */ +static void +DetachPartitionFinalize(Relation rel, Relation partRel, bool concurrent, + Oid defaultPartOid) +{ + Relation classRel; + List *fks; + ListCell *cell; + List *indexes; + Datum new_val[Natts_pg_class]; + bool new_null[Natts_pg_class], + new_repl[Natts_pg_class]; + HeapTuple tuple, + newtuple; - index_close(idx, NoLock); + if (concurrent) + { + /* + * We can remove the pg_inherits row now. (In the non-concurrent case, + * this was already done). + */ + RemoveInheritance(partRel, rel, true); } - table_close(classRel, RowExclusiveLock); /* Drop any triggers that were cloned on creation/attach. */ DropClonedTriggersFromPartition(RelationGetRelid(partRel)); @@ -20996,7 +22043,72 @@ ATExecDetachPartition(Relation rel, RangeVar *name) ObjectAddressSet(constraint, ConstraintRelationId, constrOid); performDeletion(&constraint, DROP_RESTRICT, 0); } - CommandCounterIncrement(); + + /* Now we can detach indexes */ + indexes = RelationGetIndexList(partRel); + foreach(cell, indexes) + { + Oid idxid = lfirst_oid(cell); + Relation idx; + Oid constrOid; + + if (!has_superclass(idxid)) + continue; + + Assert((IndexGetRelation(get_partition_parent(idxid, false), false) == + RelationGetRelid(rel))); + + idx = index_open(idxid, AccessExclusiveLock); + IndexSetParentIndex(idx, InvalidOid); + + /* If there's a constraint associated with the index, detach it too */ + constrOid = get_relation_idx_constraint_oid(RelationGetRelid(partRel), + idxid); + if (OidIsValid(constrOid)) + ConstraintSetParentConstraint(constrOid, InvalidOid, InvalidOid); + + index_close(idx, NoLock); + } + + /* Update pg_class tuple */ + classRel = table_open(RelationRelationId, RowExclusiveLock); + tuple = SearchSysCacheCopy1(RELOID, + ObjectIdGetDatum(RelationGetRelid(partRel))); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", + RelationGetRelid(partRel)); + Assert(((Form_pg_class) GETSTRUCT(tuple))->relispartition); + + /* Clear relpartbound and reset relispartition */ + memset(new_val, 0, sizeof(new_val)); + memset(new_null, false, sizeof(new_null)); + memset(new_repl, false, sizeof(new_repl)); + new_val[Anum_pg_class_relpartbound - 1] = (Datum) 0; + new_null[Anum_pg_class_relpartbound - 1] = true; + new_repl[Anum_pg_class_relpartbound - 1] = true; + newtuple = heap_modify_tuple(tuple, RelationGetDescr(classRel), + new_val, new_null, new_repl); + + ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = false; + CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple); + heap_freetuple(newtuple); + table_close(classRel, RowExclusiveLock); + + if (OidIsValid(defaultPartOid)) + { + /* + * If the relation being detached is the default partition itself, + * remove it from the parent's pg_partitioned_table entry. + * + * If not, we must invalidate default partition's relcache entry, as + * in StorePartitionBound: its partition constraint depends on every + * other partition's partition constraint. + */ + if (RelationGetRelid(partRel) == defaultPartOid) + update_default_partition_oid(RelationGetRelid(rel), InvalidOid); + else + CacheInvalidateRelcacheByRelid(defaultPartOid); + } /* * Invalidate the parent's relcache so that the partition is no longer @@ -21004,20 +22116,96 @@ ATExecDetachPartition(Relation rel, RangeVar *name) */ CacheInvalidateRelcache(rel); - /* MPP-6929: metadata tracking */ - MetaTrackUpdObject(RelationRelationId, - RelationGetRelid(partRel), - GetUserId(), - "PARTITION", "DETACH"); + /* + * MPP-6929: metadata tracking. This is the spot both the plain DETACH + * and DETACH CONCURRENTLY('s FINALIZE) pass through; tracking only in + * ATExecDetachPartitionFinalize left plain DETACH unlogged, so + * pg_stat_last_operation kept reporting the partition's original + * ATTACH. + */ + if (Gp_role == GP_ROLE_DISPATCH) + MetaTrackUpdObject(RelationRelationId, + RelationGetRelid(partRel), + GetUserId(), + "PARTITION", "DETACH"); +} + +/* + * ALTER TABLE ... DETACH PARTITION ... FINALIZE + * + * To use when a DETACH PARTITION command previously did not run to + * completion; this completes the detaching process. + */ +static ObjectAddress +ATExecDetachPartitionFinalize(Relation rel, RangeVar *name) +{ + Relation partRel; + ObjectAddress address; + Snapshot snap = GetActiveSnapshot(); + + partRel = table_openrv(name, AccessExclusiveLock); + + /* + * Wait until existing snapshots are gone. This is important if the + * second transaction of DETACH PARTITION CONCURRENTLY is canceled: the + * user could immediately run DETACH FINALIZE without actually waiting for + * existing transactions. We must not complete the detach action until + * all such queries are complete (otherwise we would present them with an + * inconsistent view of catalogs). + */ + WaitForOlderSnapshots(snap->xmin, false); + + DetachPartitionFinalize(rel, partRel, true, InvalidOid); ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partRel)); - /* keep our lock until commit */ table_close(partRel, NoLock); return address; } +/* + * DetachAddConstraintIfNeeded + * Subroutine for ATExecDetachPartition. Create a constraint that + * takes the place of the partition constraint, but avoid creating + * a dupe if an constraint already exists which implies the needed + * constraint. + */ +static void +DetachAddConstraintIfNeeded(List **wqueue, Relation partRel) +{ + List *constraintExpr; + + constraintExpr = RelationGetPartitionQual(partRel); + constraintExpr = (List *) eval_const_expressions(NULL, (Node *) constraintExpr); + + /* + * Avoid adding a new constraint if the needed constraint is implied by an + * existing constraint + */ + if (!PartConstraintImpliedByRelConstraint(partRel, constraintExpr)) + { + AlteredTableInfo *tab; + Constraint *n; + + tab = ATGetQueueEntry(wqueue, partRel); + + /* Add constraint on partition, equivalent to the partition constraint */ + n = makeNode(Constraint); + n->contype = CONSTR_CHECK; + n->conname = NULL; + n->location = -1; + n->is_no_inherit = false; + n->raw_expr = NULL; + n->cooked_expr = nodeToString(make_ands_explicit(constraintExpr)); + n->initially_valid = true; + n->skip_validation = true; + /* It's a re-add, since it nominally already exists */ + ATAddCheckConstraint(wqueue, tab, partRel, n, + true, false, true, ShareUpdateExclusiveLock); + } +} + /* * DropClonedTriggersFromPartition * subroutine for ATExecDetachPartition to remove any triggers that were @@ -21185,7 +22373,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) /* Silently do nothing if already in the right state */ currParent = partIdx->rd_rel->relispartition ? - get_partition_parent(partIdxId) : InvalidOid; + get_partition_parent(partIdxId, false) : InvalidOid; if (currParent != RelationGetRelid(parentIdx)) { IndexInfo *childInfo; @@ -21213,7 +22401,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) RelationGetRelationName(partIdx)))); /* Make sure it indexes a partition of the other index's table */ - partDesc = RelationGetPartitionDesc(parentTbl); + partDesc = RelationGetPartitionDesc(parentTbl, true); found = false; for (i = 0; i < partDesc->nparts; i++) { @@ -21367,7 +22555,7 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) * If we found as many inherited indexes as the partitioned table has * partitions, we're good; update pg_index to set indisvalid. */ - if (tuples == RelationGetPartitionDesc(partedTbl)->nparts) + if (tuples == RelationGetPartitionDesc(partedTbl, true)->nparts) { Relation idxRel; HeapTuple newtup; @@ -21397,8 +22585,8 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) /* make sure we see the validation we just did */ CommandCounterIncrement(); - parentIdxId = get_partition_parent(RelationGetRelid(partedIdx)); - parentTblId = get_partition_parent(RelationGetRelid(partedTbl)); + parentIdxId = get_partition_parent(RelationGetRelid(partedIdx), false); + parentTblId = get_partition_parent(RelationGetRelid(partedTbl), false); parentIdx = relation_open(parentIdxId, AccessExclusiveLock); parentTbl = relation_open(parentTblId, AccessExclusiveLock); Assert(!parentIdx->rd_index->indisvalid); @@ -21513,3 +22701,41 @@ ATDetachCheckNoForeignKeyRefs(Relation partition) table_close(rel, NoLock); } } + +/* + * resolve column compression specification to compression method. + */ +static char +GetAttributeCompression(Oid atttypid, char *compression) +{ + char cmethod; + + if (compression == NULL || strcmp(compression, "default") == 0) + return InvalidCompressionMethod; + + /* + * To specify a nondefault method, the column data type must be toastable. + * Note this says nothing about whether the column's attstorage setting + * permits compression; we intentionally allow attstorage and + * attcompression to be independent. But with a non-toastable type, + * attstorage could not be set to a value that would permit compression. + * + * We don't actually need to enforce this, since nothing bad would happen + * if attcompression were non-default; it would never be consulted. But + * it seems more user-friendly to complain about a certainly-useless + * attempt to set the property. + */ + if (!TypeIsToastable(atttypid)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("column data type %s does not support compression", + format_type_be(atttypid)))); + + cmethod = CompressionNameToMethod(compression); + if (!CompressionMethodIsValid(cmethod)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid compression method \"%s\"", compression))); + + return cmethod; +} diff --git a/src/backend/commands/tablecmds_gp.c b/src/backend/commands/tablecmds_gp.c index 8472d582319d..d0c412e71392 100644 --- a/src/backend/commands/tablecmds_gp.c +++ b/src/backend/commands/tablecmds_gp.c @@ -136,7 +136,7 @@ GpFindTargetPartition(Relation parent, GpAlterPartitionId *partid, case AT_AP_IDDefault: /* Find default partition */ target_relid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(parent)); + get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, false)); if (!OidIsValid(target_relid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -183,7 +183,7 @@ GpFindTargetPartition(Relation parent, GpAlterPartitionId *partid, if (partRel->rd_rel->relispartition) { bool found = false; - PartitionDesc partdesc = RelationGetPartitionDesc(parent); + PartitionDesc partdesc = RelationGetPartitionDesc(parent, false); target_relid = RelationGetRelid(partRel); table_close(partRel, AccessShareLock); /* @@ -221,7 +221,7 @@ GpFindTargetPartition(Relation parent, GpAlterPartitionId *partid, { Datum values[PARTITION_MAX_KEYS]; bool isnull[PARTITION_MAX_KEYS]; - PartitionDesc partdesc = RelationGetPartitionDesc(parent); + PartitionDesc partdesc = RelationGetPartitionDesc(parent, false); int partidx; FormPartitionKeyDatumFromExpr(parent, partid->partiddef, values, isnull); @@ -239,7 +239,7 @@ GpFindTargetPartition(Relation parent, GpAlterPartitionId *partid, } if (partdesc->oids[partidx] == - get_default_oid_from_partdesc(RelationGetPartitionDesc(parent))) + get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, false))) { ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -616,7 +616,7 @@ AtExecGPSplitPartition(Relation rel, AlterTableCmd *cmd) Assert(OidIsValid(partrelid)); partrel = table_open(partrelid, AccessShareLock); - if (partrelid == get_default_oid_from_partdesc(RelationGetPartitionDesc(rel))) + if (partrelid == get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, false))) defaultpartname = pstrdup(RelationGetRelationName(partrel)); else defaultpartname = NULL; @@ -1015,6 +1015,7 @@ AtExecGPSplitPartition(Relation rel, AlterTableCmd *cmd) pstmt->stmt_len = 0; ProcessUtility(pstmt, synthetic_sql, + false, PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, @@ -1206,7 +1207,7 @@ ATExecGPPartCmds(Relation origrel, AlterTableCmd *cmd) Oid firstchildoid; Assert(temprel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - partdesc = RelationGetPartitionDesc(temprel); + partdesc = RelationGetPartitionDesc(temprel, false); if (partdesc->nparts == 0) ereport(ERROR, @@ -1271,7 +1272,7 @@ ATExecGPPartCmds(Relation origrel, AlterTableCmd *cmd) break; partrel = table_open(partrelid, AccessShareLock); - partdesc = RelationGetPartitionDesc(rel); + partdesc = RelationGetPartitionDesc(rel, false); /* * If two drop partition cmds are specified in same alter table stmt, @@ -1346,7 +1347,7 @@ ATExecGPPartCmds(Relation origrel, AlterTableCmd *cmd) { Relation firstrel; Oid firstchildoid; - PartitionDesc partdesc = RelationGetPartitionDesc(rel); + PartitionDesc partdesc = RelationGetPartitionDesc(rel, false); if (partdesc->nparts == 0) ereport(ERROR, @@ -1360,13 +1361,13 @@ ATExecGPPartCmds(Relation origrel, AlterTableCmd *cmd) (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("level %d is not partitioned and hence can't set subpartition template for the same", level))); - if (RelationGetPartitionDesc(firstrel)->nparts == 0) + if (RelationGetPartitionDesc(firstrel, false)->nparts == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("GPDB SET SUBPARTITION TEMPLATE syntax needs at least one sibling to exist"))); /* if this is not leaf level partition then sub-partition must exist for next level */ - if (!RelationGetPartitionDesc(firstrel)->is_leaf[0]) + if (!RelationGetPartitionDesc(firstrel, false)->is_leaf[0]) { if (GetGpPartitionTemplate(topParentrelid, level + 1) == NULL) { @@ -1474,6 +1475,7 @@ ATExecGPPartCmds(Relation origrel, AlterTableCmd *cmd) pstmt->stmt_len = 0; ProcessUtility(pstmt, synthetic_sql, + false, PROCESS_UTILITY_SUBCOMMAND, NULL, NULL, diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 008214df4ecc..277cdfcd2e2c 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -43,7 +43,7 @@ * * Portions Copyright (c) 2005-2010 Greenplum Inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -619,6 +619,8 @@ DropTableSpace(DropTableSpaceStmt *stmt) Form_pg_tablespace spcform; ScanKeyData entry[1]; Oid tablespaceoid; + char *detail; + char *detail_log; /* * Find the target tuple @@ -667,6 +669,16 @@ DropTableSpace(DropTableSpaceStmt *stmt) aclcheck_error(ACLCHECK_NO_PRIV, OBJECT_TABLESPACE, tablespacename); + /* Check for pg_shdepend entries depending on this tablespace */ + if (checkSharedDependencies(TableSpaceRelationId, tablespaceoid, + &detail, &detail_log)) + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("tablespace \"%s\" cannot be dropped because some objects depend on it", + tablespacename), + errdetail_internal("%s", detail), + errdetail_log("%s", detail_log))); + /* DROP hook for the tablespace being removed */ InvokeObjectDropHook(TableSpaceRelationId, tablespaceoid, 0); @@ -785,15 +797,34 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) /* * Attempt to coerce target directory to safe permissions. If this fails, * it doesn't exist or has the wrong owner. + * + * During WAL replay the location may legitimately be gone: the + * tablespace was dropped later in the WAL and its directory removed + * (regression tests do exactly this), or a mirror was rewound to before + * the CREATE. Erroring would kill the startup process and leave the + * mirror unrecoverable, so recreate the directory and press on, in the + * spirit of TablespaceCreateDbspace(). */ if (chmod(location, pg_dir_create_mode) != 0) { - if (errno == ENOENT) + if (errno == ENOENT && InRecovery) + { + char *locbuf = pstrdup(location); + + ereport(LOG, + (errmsg("creating missing directory \"%s\" for tablespace %u during replay", + location, tablespaceoid))); + if (pg_mkdir_p(locbuf, pg_dir_create_mode) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not create directory \"%s\": %m", + location))); + pfree(locbuf); + } + else if (errno == ENOENT) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FILE), - errmsg("directory \"%s\" does not exist", location), - InRecovery ? errhint("Create this directory for the tablespace before " - "restarting the server.") : 0)); + errmsg("directory \"%s\" does not exist", location))); else ereport(ERROR, (errcode_for_file_access(), @@ -1170,7 +1201,13 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo) } else { - if(directory_is_empty(link_target_dir) && rmdir(link_target_dir) < 0) + /* + * In redo this must not ERROR: ReadDir's failure would kill the + * startup process over disk space we merely failed to release + * (e.g. the directory vanished after the access() check above). + */ + if(directory_is_empty_ext(link_target_dir, redo ? LOG : ERROR) && + rmdir(link_target_dir) < 0) ereport(redo ? LOG : ERROR, (errcode_for_file_access(), errmsg("could not remove directory \"%s\": %m", @@ -1237,13 +1274,25 @@ destroy_tablespace_directories(Oid tablespaceoid, bool redo) */ bool directory_is_empty(const char *path) +{ + return directory_is_empty_ext(path, ERROR); +} + +/* + * As above, but report problems reading the directory at the caller's + * chosen elevel. WAL replay must use something weaker than ERROR, which + * the startup process would escalate to FATAL; an unreadable or vanished + * directory then counts as empty and the caller's rmdir reports the rest. + */ +bool +directory_is_empty_ext(const char *path, int elevel) { DIR *dirdesc; struct dirent *de; dirdesc = AllocateDir(path); - while ((de = ReadDir(dirdesc, path)) != NULL) + while ((de = ReadDirExtended(dirdesc, path, elevel)) != NULL) { if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) @@ -1252,7 +1301,8 @@ directory_is_empty(const char *path) return false; } - FreeDir(dirdesc); + if (dirdesc) + FreeDir(dirdesc); return true; } diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 176a434e8d5d..88bde2f8222b 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -3,7 +3,7 @@ * trigger.c * PostgreSQL TRIGGERs support code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -35,6 +35,7 @@ #include "commands/defrem.h" #include "commands/trigger.h" #include "executor/executor.h" +#include "executor/execPartition.h" #include "miscadmin.h" #include "nodes/execnodes.h" #include "nodes/bitmapset.h" @@ -73,16 +74,6 @@ int SessionReplicationRole = SESSION_REPLICATION_ROLE_ORIGIN; /* How many levels deep into trigger execution are we? */ static int MyTriggerDepth = 0; -/* - * Note that similar macros also exist in executor/execMain.c. There does not - * appear to be any good header to put them into, given the structures that - * they use, so we let them be duplicated. Be sure to update all if one needs - * to be changed, however. - */ -#define GetAllUpdatedColumns(relinfo, estate) \ - (bms_union(exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols, \ - exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols)) - /* Local function prototypes */ static void SetTriggerFlags(TriggerDesc *trigdesc, Trigger *trigger); static bool GetTupleForTrigger(EState *estate, @@ -155,7 +146,9 @@ static bool before_stmt_triggers_fired(Oid relid, CmdType cmdType); * * When called on partitioned tables, this function recurses to create the * trigger on all the partitions, except if isInternal is true, in which - * case caller is expected to execute recursion on its own. + * case caller is expected to execute recursion on its own. in_partition + * indicates such a recursive call; outside callers should pass "false" + * (but see CloneRowTriggersToPartition). */ ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString, @@ -174,12 +167,10 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, Relation rel; AclResult aclresult; Relation tgrel; - SysScanDesc tgscan; - ScanKeyData key; Relation pgrel; - HeapTuple tuple; + HeapTuple tuple = NULL; Oid funcrettype; - Oid trigoid; + Oid trigoid = InvalidOid; char internaltrigname[NAMEDATALEN]; char *trigname; Oid constrrelid = InvalidOid; @@ -188,6 +179,9 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, char *oldtablename = NULL; char *newtablename = NULL; bool partition_recurse; + bool trigger_exists = false; + Oid existing_constraint_oid = InvalidOid; + bool existing_isInternal = false; if (OidIsValid(relOid)) rel = table_open(relOid, ShareRowExclusiveLock); @@ -715,6 +709,117 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, errmsg("ON DELETE triggers are not supported on append-only tables"))); } + /* + * Scan pg_trigger to see if there is already a trigger of the same name. + * Skip this for internally generated triggers, since we'll modify the + * name to be unique below. + * + * NOTE that this is cool only because we have ShareRowExclusiveLock on + * the relation, so the trigger set won't be changing underneath us. + */ + tgrel = table_open(TriggerRelationId, RowExclusiveLock); + if (!isInternal) + { + ScanKeyData skeys[2]; + SysScanDesc tgscan; + + ScanKeyInit(&skeys[0], + Anum_pg_trigger_tgrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel))); + + ScanKeyInit(&skeys[1], + Anum_pg_trigger_tgname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(stmt->trigname)); + + tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true, + NULL, 2, skeys); + + /* There should be at most one matching tuple */ + if (HeapTupleIsValid(tuple = systable_getnext(tgscan))) + { + Form_pg_trigger oldtrigger = (Form_pg_trigger) GETSTRUCT(tuple); + + trigoid = oldtrigger->oid; + existing_constraint_oid = oldtrigger->tgconstraint; + existing_isInternal = oldtrigger->tgisinternal; + trigger_exists = true; + /* copy the tuple to use in CatalogTupleUpdate() */ + tuple = heap_copytuple(tuple); + } + systable_endscan(tgscan); + } + + if (!trigger_exists) + { + /* + * Generate the OID for the new trigger. + * + * For RI constraint triggers, the trigger's name is derived from + * the trigger OID. That creates a chicken-and-egg problem with the + * usual GPDB OID dispatching mechanism. In a QE, we cannot look up + * the trigger OID to use by trigger name, because the trigger name + * is derived from the OID. To work around that, we use more fields + * as the key. For a user-defined trigger, tgrelid and the trigger + * name should be enough. For internal triggers, we use the name + * prefix together with constraint OID and function OID. That + * should be unique: there should be no need to have more than one + * internal trigger with the same function for one constraint. + */ + trigoid = GetNewOidForTrigger(tgrel, TriggerOidIndexId, + Anum_pg_trigger_oid, + RelationGetRelid(rel), + stmt->trigname, + constraintOid, + funcoid); + } + else + { + /* + * If OR REPLACE was specified, we'll replace the old trigger; + * otherwise complain about the duplicate name. + */ + if (!stmt->replace) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("trigger \"%s\" for relation \"%s\" already exists", + stmt->trigname, RelationGetRelationName(rel)))); + + /* + * An internal trigger cannot be replaced by a user-defined trigger. + * However, skip this test when in_partition, because then we're + * recursing from a partitioned table and the check was made at the + * parent level. Child triggers will always be marked "internal" (so + * this test does protect us from the user trying to replace a child + * trigger directly). + */ + if (existing_isInternal && !isInternal && !in_partition) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("trigger \"%s\" for relation \"%s\" is an internal trigger", + stmt->trigname, RelationGetRelationName(rel)))); + + /* + * It is not allowed to replace with a constraint trigger; gram.y + * should have enforced this already. + */ + Assert(!stmt->isconstraint); + + /* + * It is not allowed to replace an existing constraint trigger, + * either. (The reason for these restrictions is partly that it seems + * difficult to deal with pending trigger events in such cases, and + * partly that the command might imply changing the constraint's + * properties as well, which doesn't seem nice.) + */ + if (OidIsValid(existing_constraint_oid)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("trigger \"%s\" for relation \"%s\" is a constraint trigger", + stmt->trigname, RelationGetRelationName(rel)))); + } + /* * If it's a user-entered CREATE CONSTRAINT TRIGGER command, make a * corresponding pg_constraint entry. @@ -754,31 +859,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, isInternal); /* is_internal */ } - /* - * Generate the trigger's OID now, so that we can use it in the name if - * needed. - */ - tgrel = table_open(TriggerRelationId, RowExclusiveLock); - - /* - * For RI constraint triggers, the trigger's name is derived from the - * trigger OID. That creates a chicken-and-egg problem with the usual - * GPDB OID dispatching mechanism. In a QE, we cannot look up the - * trigger OID to use by trigger name, because the trigger name is - * derived from the OID. To work around that, we use more fields as - * the key. For a user-defined trigger, tgrelid and the trigger name - * should be enough. For internal triggers, we use the name prefix - * together with constraint OID and function OID. That should be - * unique: there should be no need to have more than one internal trigger - * with same function for one constraint. - */ - trigoid = GetNewOidForTrigger(tgrel, TriggerOidIndexId, - Anum_pg_trigger_oid, - RelationGetRelid(rel), - stmt->trigname, - constraintOid, - funcoid); - /* * If trigger is internally generated, modify the provided trigger name to * ensure uniqueness by appending the trigger OID. (Callers will usually @@ -796,37 +876,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, trigname = stmt->trigname; } - /* - * Scan pg_trigger for existing triggers on relation. We do this only to - * give a nice error message if there's already a trigger of the same - * name. (The unique index on tgrelid/tgname would complain anyway.) We - * can skip this for internally generated triggers, since the name - * modification above should be sufficient. - * - * NOTE that this is cool only because we have ShareRowExclusiveLock on - * the relation, so the trigger set won't be changing underneath us. - */ - if (!isInternal) - { - ScanKeyInit(&key, - Anum_pg_trigger_tgrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(rel))); - tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true, - NULL, 1, &key); - while (HeapTupleIsValid(tuple = systable_getnext(tgscan))) - { - Form_pg_trigger pg_trigger = (Form_pg_trigger) GETSTRUCT(tuple); - - if (namestrcmp(&(pg_trigger->tgname), trigname) == 0) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("trigger \"%s\" for relation \"%s\" already exists", - trigname, RelationGetRelationName(rel)))); - } - systable_endscan(tgscan); - } - /* * Build the new pg_trigger tuple. * @@ -975,14 +1024,24 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, else nulls[Anum_pg_trigger_tgnewtable - 1] = true; - tuple = heap_form_tuple(tgrel->rd_att, values, nulls); - /* - * Insert tuple into pg_trigger. + * Insert or replace tuple in pg_trigger. */ - CatalogTupleInsert(tgrel, tuple); + if (!trigger_exists) + { + tuple = heap_form_tuple(tgrel->rd_att, values, nulls); + CatalogTupleInsert(tgrel, tuple); + } + else + { + HeapTuple newtup; - heap_freetuple(tuple); + newtup = heap_form_tuple(tgrel->rd_att, values, nulls); + CatalogTupleUpdate(tgrel, &tuple->t_self, newtup); + heap_freetuple(newtup); + } + + heap_freetuple(tuple); /* free either original or new tuple */ table_close(tgrel, RowExclusiveLock); pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1])); @@ -1017,6 +1076,13 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, heap_freetuple(tuple); table_close(pgrel, RowExclusiveLock); + /* + * If we're replacing a trigger, flush all the old dependencies before + * recording new ones. + */ + if (trigger_exists) + deleteDependencyRecordsFor(TriggerRelationId, trigoid, true); + /* * Record dependencies for trigger. Always place a normal dependency on * the function. @@ -1120,7 +1186,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, */ if (partition_recurse) { - PartitionDesc partdesc = RelationGetPartitionDesc(rel); + PartitionDesc partdesc = RelationGetPartitionDesc(rel, true); List *idxs = NIL; List *childTbls = NIL; ListCell *l; @@ -2563,11 +2629,12 @@ ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; - TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo); if ((trigdesc && trigdesc->trig_delete_after_row) || (transition_capture && transition_capture->tcs_delete_old_table)) { + TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo); + Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid)); if (fdw_trigtuple == NULL) GetTupleForTrigger(estate, @@ -2659,7 +2726,10 @@ ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo) CMD_UPDATE)) return; - updatedCols = GetAllUpdatedColumns(relinfo, estate); + /* statement-level triggers operate on the parent table */ + Assert(relinfo->ri_RootResultRelInfo == NULL); + + updatedCols = ExecGetAllUpdatedCols(relinfo, estate); LocTriggerData.type = T_TriggerData; LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE | @@ -2700,10 +2770,13 @@ ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo, { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; + /* statement-level triggers operate on the parent table */ + Assert(relinfo->ri_RootResultRelInfo == NULL); + if (trigdesc && trigdesc->trig_update_after_statement) AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE, false, NULL, NULL, NIL, - GetAllUpdatedColumns(relinfo, estate), + ExecGetAllUpdatedCols(relinfo, estate), transition_capture); } @@ -2741,20 +2814,22 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, /* * In READ COMMITTED isolation level it's possible that target tuple * was changed due to concurrent update. In that case we have a raw - * subplan output tuple in epqslot_candidate, and need to run it - * through the junk filter to produce an insertable tuple. + * subplan output tuple in epqslot_candidate, and need to form a new + * insertable tuple using ExecGetUpdateNewTuple to replace the one we + * received in newslot. Neither we nor our callers have any further + * interest in the passed-in tuple, so it's okay to overwrite newslot + * with the newer data. * - * Caution: more than likely, the passed-in slot is the same as the - * junkfilter's output slot, so we are clobbering the original value - * of slottuple by doing the filtering. This is OK since neither we - * nor our caller have any more interest in the prior contents of that - * slot. + * (Typically, newslot was also generated by ExecGetUpdateNewTuple, so + * that epqslot_clean will be that same slot and the copy step below + * is not needed.) */ if (epqslot_candidate != NULL) { TupleTableSlot *epqslot_clean; - epqslot_clean = ExecFilterJunk(relinfo->ri_junkFilter, epqslot_candidate); + epqslot_clean = ExecGetUpdateNewTuple(relinfo, epqslot_candidate, + oldslot); if (newslot != epqslot_clean) ExecCopySlot(newslot, epqslot_clean); @@ -2773,7 +2848,7 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, TRIGGER_EVENT_ROW | TRIGGER_EVENT_BEFORE; LocTriggerData.tg_relation = relinfo->ri_RelationDesc; - updatedCols = GetAllUpdatedColumns(relinfo, estate); + updatedCols = ExecGetAllUpdatedCols(relinfo, estate); LocTriggerData.tg_updatedcols = updatedCols; for (i = 0; i < trigdesc->numtriggers; i++) { @@ -2815,16 +2890,6 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, { ExecForceStoreHeapTuple(newtuple, newslot, false); - if (trigger->tgisclone && - !ExecPartitionCheck(relinfo, newslot, estate, false)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("moving row to another partition during a BEFORE trigger is not supported"), - errdetail("Before executing trigger \"%s\", the row was to be in partition \"%s.%s\".", - trigger->tgname, - get_namespace_name(RelationGetNamespace(relinfo->ri_RelationDesc)), - RelationGetRelationName(relinfo->ri_RelationDesc)))); - /* * If the tuple returned by the trigger / being stored, is the old * row version, and the heap tuple passed to the trigger was @@ -2856,9 +2921,6 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; - TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo); - - ExecClearTuple(oldslot); if ((trigdesc && trigdesc->trig_update_after_row) || (transition_capture && @@ -2871,6 +2933,8 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, * separately for DELETE and INSERT to capture transition table rows. * In such case, either old tuple or new tuple can be NULL. */ + TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo); + if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid)) GetTupleForTrigger(estate, NULL, @@ -2881,10 +2945,12 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, NULL); else if (fdw_trigtuple != NULL) ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false); + else + ExecClearTuple(oldslot); AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE, true, oldslot, newslot, recheckIndexes, - GetAllUpdatedColumns(relinfo, estate), + ExecGetAllUpdatedCols(relinfo, estate), transition_capture); } } @@ -3019,6 +3085,9 @@ ExecASTruncateTriggers(EState *estate, ResultRelInfo *relinfo) } +/* + * Fetch tuple into "oldslot", dealing with locking and EPQ if necessary + */ static bool GetTupleForTrigger(EState *estate, EPQState *epqstate, @@ -3573,6 +3642,8 @@ static void AfterTriggerExecute(EState *estate, TupleTableSlot *trig_tuple_slot2); static AfterTriggersTableData *GetAfterTriggersTableData(Oid relid, CmdType cmdType); +static TupleTableSlot *GetAfterTriggersStoreSlot(AfterTriggersTableData *table, + TupleDesc tupdesc); static void AfterTriggerFreeQuery(AfterTriggersQueryData *qs); static SetConstraintState SetConstraintStateCreate(int numalloc); static SetConstraintState SetConstraintStateCopy(SetConstraintState state); @@ -4252,6 +4323,8 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, { rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid); rel = rInfo->ri_RelationDesc; + /* Catch calls with insufficient relcache refcounting */ + Assert(!RelationHasReferenceCountZero(rel)); trigdesc = rInfo->ri_TrigDesc; finfo = rInfo->ri_TrigFunctions; instr = rInfo->ri_TrigInstrument; @@ -4321,7 +4394,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, if (local_estate) { - ExecCleanUpTriggerState(estate); + ExecCloseResultRelations(estate); ExecResetTupleTable(estate->es_tupleTable, false); FreeExecutorState(estate); } @@ -4375,6 +4448,31 @@ GetAfterTriggersTableData(Oid relid, CmdType cmdType) return table; } +/* + * Returns a TupleTableSlot suitable for holding the tuples to be put + * into AfterTriggersTableData's transition table tuplestores. + */ +static TupleTableSlot * +GetAfterTriggersStoreSlot(AfterTriggersTableData *table, + TupleDesc tupdesc) +{ + /* Create it if not already done. */ + if (!table->storeslot) + { + MemoryContext oldcxt; + + /* + * We only need this slot only until AfterTriggerEndQuery, but making + * it last till end-of-subxact is good enough. It'll be freed by + * AfterTriggerFreeQuery(). + */ + oldcxt = MemoryContextSwitchTo(CurTransactionContext); + table->storeslot = MakeSingleTupleTableSlot(tupdesc, &TTSOpsVirtual); + MemoryContextSwitchTo(oldcxt); + } + + return table->storeslot; +} /* * MakeTransitionCaptureState @@ -4386,9 +4484,10 @@ GetAfterTriggersTableData(Oid relid, CmdType cmdType) * If there are no triggers in 'trigdesc' that request relevant transition * tables, then return NULL. * - * The resulting object can be passed to the ExecAR* functions. The caller - * should set tcs_map or tcs_original_insert_tuple as appropriate when dealing - * with child tables. + * The resulting object can be passed to the ExecAR* functions. When + * dealing with child tables, the caller can set tcs_original_insert_tuple + * to avoid having to reconstruct the original tuple in the root table's + * format. * * Note that we copy the flags from a parent table into this struct (rather * than subsequently using the relation's TriggerDesc directly) so that we can @@ -4663,6 +4762,8 @@ AfterTriggerFreeQuery(AfterTriggersQueryData *qs) table->new_tuplestore = NULL; if (ts) tuplestore_end(ts); + if (table->storeslot) + ExecDropSingleTupleTableSlot(table->storeslot); } /* @@ -5499,7 +5600,7 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, if (row_trigger && transition_capture != NULL) { TupleTableSlot *original_insert_tuple = transition_capture->tcs_original_insert_tuple; - TupleConversionMap *map = transition_capture->tcs_map; + TupleConversionMap *map = ExecGetChildToRootMap(relinfo); bool delete_old_table = transition_capture->tcs_delete_old_table; bool update_old_table = transition_capture->tcs_update_old_table; bool update_new_table = transition_capture->tcs_update_new_table; @@ -5528,17 +5629,10 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, if (map != NULL) { + AfterTriggersTableData *table = transition_capture->tcs_private; TupleTableSlot *storeslot; - storeslot = transition_capture->tcs_private->storeslot; - if (!storeslot) - { - storeslot = ExecAllocTableSlot(&estate->es_tupleTable, - map->outdesc, - &TTSOpsVirtual); - transition_capture->tcs_private->storeslot = storeslot; - } - + storeslot = GetAfterTriggersStoreSlot(table, map->outdesc); execute_attr_map_slot(map->attrMap, oldslot, storeslot); tuplestore_puttupleslot(old_tuplestore, storeslot); } @@ -5558,18 +5652,10 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, original_insert_tuple); else if (map != NULL) { + AfterTriggersTableData *table = transition_capture->tcs_private; TupleTableSlot *storeslot; - storeslot = transition_capture->tcs_private->storeslot; - - if (!storeslot) - { - storeslot = ExecAllocTableSlot(&estate->es_tupleTable, - map->outdesc, - &TTSOpsVirtual); - transition_capture->tcs_private->storeslot = storeslot; - } - + storeslot = GetAfterTriggersStoreSlot(table, map->outdesc); execute_attr_map_slot(map->attrMap, newslot, storeslot); tuplestore_puttupleslot(new_tuplestore, storeslot); } diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index 421fb1bbe6f4..171d31e4691e 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -4,7 +4,7 @@ * * Routines for tsearch manipulation commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -136,42 +136,41 @@ makeParserDependencies(HeapTuple tuple) Form_pg_ts_parser prs = (Form_pg_ts_parser) GETSTRUCT(tuple); ObjectAddress myself, referenced; + ObjectAddresses *addrs; - myself.classId = TSParserRelationId; - myself.objectId = prs->oid; - myself.objectSubId = 0; - - /* dependency on namespace */ - referenced.classId = NamespaceRelationId; - referenced.objectId = prs->prsnamespace; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(myself, TSParserRelationId, prs->oid); /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, false); - /* dependencies on functions */ - referenced.classId = ProcedureRelationId; - referenced.objectSubId = 0; + addrs = new_object_addresses(); - referenced.objectId = prs->prsstart; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + /* dependency on namespace */ + ObjectAddressSet(referenced, NamespaceRelationId, prs->prsnamespace); + add_exact_object_address(&referenced, addrs); + + /* dependencies on functions */ + ObjectAddressSet(referenced, ProcedureRelationId, prs->prsstart); + add_exact_object_address(&referenced, addrs); referenced.objectId = prs->prstoken; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); referenced.objectId = prs->prsend; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); referenced.objectId = prs->prslextype; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); if (OidIsValid(prs->prsheadline)) { referenced.objectId = prs->prsheadline; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + return myself; } @@ -326,16 +325,9 @@ makeDictionaryDependencies(HeapTuple tuple) Form_pg_ts_dict dict = (Form_pg_ts_dict) GETSTRUCT(tuple); ObjectAddress myself, referenced; + ObjectAddresses *addrs; - myself.classId = TSDictionaryRelationId; - myself.objectId = dict->oid; - myself.objectSubId = 0; - - /* dependency on namespace */ - referenced.classId = NamespaceRelationId; - referenced.objectId = dict->dictnamespace; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(myself, TSDictionaryRelationId, dict->oid); /* dependency on owner */ recordDependencyOnOwner(myself.classId, myself.objectId, dict->dictowner); @@ -343,11 +335,18 @@ makeDictionaryDependencies(HeapTuple tuple) /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, false); + addrs = new_object_addresses(); + + /* dependency on namespace */ + ObjectAddressSet(referenced, NamespaceRelationId, dict->dictnamespace); + add_exact_object_address(&referenced, addrs); + /* dependency on template */ - referenced.classId = TSTemplateRelationId; - referenced.objectId = dict->dicttemplate; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(referenced, TSTemplateRelationId, dict->dicttemplate); + add_exact_object_address(&referenced, addrs); + + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); return myself; } @@ -696,33 +695,32 @@ makeTSTemplateDependencies(HeapTuple tuple) Form_pg_ts_template tmpl = (Form_pg_ts_template) GETSTRUCT(tuple); ObjectAddress myself, referenced; + ObjectAddresses *addrs; - myself.classId = TSTemplateRelationId; - myself.objectId = tmpl->oid; - myself.objectSubId = 0; - - /* dependency on namespace */ - referenced.classId = NamespaceRelationId; - referenced.objectId = tmpl->tmplnamespace; - referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + ObjectAddressSet(myself, TSTemplateRelationId, tmpl->oid); /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, false); - /* dependencies on functions */ - referenced.classId = ProcedureRelationId; - referenced.objectSubId = 0; + addrs = new_object_addresses(); - referenced.objectId = tmpl->tmpllexize; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + /* dependency on namespace */ + ObjectAddressSet(referenced, NamespaceRelationId, tmpl->tmplnamespace); + add_exact_object_address(&referenced, addrs); + + /* dependencies on functions */ + ObjectAddressSet(referenced, ProcedureRelationId, tmpl->tmpllexize); + add_exact_object_address(&referenced, addrs); if (OidIsValid(tmpl->tmplinit)) { referenced.objectId = tmpl->tmplinit; - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + add_exact_object_address(&referenced, addrs); } + record_object_address_dependencies(&myself, addrs, DEPENDENCY_NORMAL); + free_object_addresses(addrs); + return myself; } diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index b11521d72d99..ea1afddbe197 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -3,7 +3,7 @@ * typecmds.c * Routines for SQL commands that manipulate types (and domains). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -102,6 +102,7 @@ typedef struct bool updateTypmodin; bool updateTypmodout; bool updateAnalyze; + bool updateSubscript; /* New values for relevant attributes */ char storage; Oid receiveOid; @@ -109,13 +110,19 @@ typedef struct Oid typmodinOid; Oid typmodoutOid; Oid analyzeOid; + Oid subscriptOid; } AlterTypeRecurseParams; /* Potentially set by pg_upgrade_support functions */ Oid binary_upgrade_next_array_pg_type_oid = InvalidOid; +Oid binary_upgrade_next_mrng_pg_type_oid = InvalidOid; +Oid binary_upgrade_next_mrng_array_pg_type_oid = InvalidOid; static void makeRangeConstructors(const char *name, Oid namespace, Oid rangeOid, Oid subtype); +static void makeMultirangeConstructors(const char *name, Oid namespace, + Oid multirangeOid, Oid rangeOid, + Oid rangeArrayOid, Oid *castFuncOid); static Oid findTypeInputFunction(List *procname, Oid typeOid); static Oid findTypeOutputFunction(List *procname, Oid typeOid); static Oid findTypeReceiveFunction(List *procname, Oid typeOid); @@ -123,6 +130,7 @@ static Oid findTypeSendFunction(List *procname, Oid typeOid); static Oid findTypeTypmodinFunction(List *procname); static Oid findTypeTypmodoutFunction(List *procname); static Oid findTypeAnalyzeFunction(List *procname, Oid typeOid); +static Oid findTypeSubscriptingFunction(List *procname, Oid typeOid); static Oid findRangeSubOpclass(List *opcname, Oid subtype); static Oid findRangeCanonicalFunction(List *procname, Oid typeOid); static Oid findRangeSubtypeDiffFunction(List *procname, Oid subtype); @@ -157,6 +165,7 @@ DefineType(ParseState *pstate, List *names, List *parameters) List *typmodinName = NIL; List *typmodoutName = NIL; List *analyzeName = NIL; + List *subscriptName = NIL; char category = TYPCATEGORY_USER; bool preferred = false; char delimiter = DEFAULT_TYPDELIM; @@ -175,6 +184,7 @@ DefineType(ParseState *pstate, List *names, List *parameters) DefElem *typmodinNameEl = NULL; DefElem *typmodoutNameEl = NULL; DefElem *analyzeNameEl = NULL; + DefElem *subscriptNameEl = NULL; DefElem *categoryEl = NULL; DefElem *preferredEl = NULL; DefElem *delimiterEl = NULL; @@ -191,6 +201,7 @@ DefineType(ParseState *pstate, List *names, List *parameters) Oid typmodinOid = InvalidOid; Oid typmodoutOid = InvalidOid; Oid analyzeOid = InvalidOid; + Oid subscriptOid = InvalidOid; char *array_type; Oid array_oid; Oid typoid; @@ -315,6 +326,8 @@ DefineType(ParseState *pstate, List *names, List *parameters) else if (strcmp(defel->defname, "analyze") == 0 || strcmp(defel->defname, "analyse") == 0) defelp = &analyzeNameEl; + else if (strcmp(defel->defname, "subscript") == 0) + defelp = &subscriptNameEl; else if (strcmp(defel->defname, "category") == 0) defelp = &categoryEl; else if (strcmp(defel->defname, "preferred") == 0) @@ -399,6 +412,8 @@ DefineType(ParseState *pstate, List *names, List *parameters) typmodoutName = defGetQualifiedName(typmodoutNameEl); if (analyzeNameEl) analyzeName = defGetQualifiedName(analyzeNameEl); + if (subscriptNameEl) + subscriptName = defGetQualifiedName(subscriptNameEl); if (categoryEl) { char *p = defGetString(categoryEl); @@ -530,6 +545,24 @@ DefineType(ParseState *pstate, List *names, List *parameters) if (analyzeName) analyzeOid = findTypeAnalyzeFunction(analyzeName, typoid); + /* + * Likewise look up the subscripting procedure if any. If it is not + * specified, but a typelem is specified, allow that if + * raw_array_subscript_handler can be used. (This is for backwards + * compatibility; maybe someday we should throw an error instead.) + */ + if (subscriptName) + subscriptOid = findTypeSubscriptingFunction(subscriptName, typoid); + else if (OidIsValid(elemType)) + { + if (internalLength > 0 && !byValue && get_typlen(elemType) > 0) + subscriptOid = F_RAW_ARRAY_SUBSCRIPT_HANDLER; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("element type cannot be specified without a valid subscripting procedure"))); + } + /* * Check permissions on functions. We choose to require the creator/owner * of a type to also own the underlying functions. Since creating a type @@ -564,6 +597,9 @@ DefineType(ParseState *pstate, List *names, List *parameters) if (analyzeOid && !pg_proc_ownercheck(analyzeOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, NameListToString(analyzeName)); + if (subscriptOid && !pg_proc_ownercheck(subscriptOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, + NameListToString(subscriptName)); #endif /* @@ -600,8 +636,9 @@ DefineType(ParseState *pstate, List *names, List *parameters) typmodinOid, /* typmodin procedure */ typmodoutOid, /* typmodout procedure */ analyzeOid, /* analyze procedure */ + subscriptOid, /* subscript procedure */ elemType, /* element type ID */ - false, /* this is not an array type */ + false, /* this is not an implicit array type */ array_oid, /* array type we are about to create */ InvalidOid, /* base type ID (only for domains) */ defaultValue, /* default type value */ @@ -644,6 +681,7 @@ DefineType(ParseState *pstate, List *names, List *parameters) typmodinOid, /* typmodin procedure */ typmodoutOid, /* typmodout procedure */ F_ARRAY_TYPANALYZE, /* analyze procedure */ + F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */ typoid, /* element type ID */ true, /* yes this is an array type */ InvalidOid, /* no further array type */ @@ -815,7 +853,8 @@ DefineDomain(CreateDomainStmt *stmt) typtype != TYPTYPE_COMPOSITE && typtype != TYPTYPE_DOMAIN && typtype != TYPTYPE_ENUM && - typtype != TYPTYPE_RANGE) + typtype != TYPTYPE_RANGE && + typtype != TYPTYPE_MULTIRANGE) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("\"%s\" is not a valid base type for a domain", @@ -876,6 +915,12 @@ DefineDomain(CreateDomainStmt *stmt) /* Analysis function */ analyzeProcedure = baseType->typanalyze; + /* + * Domains don't need a subscript procedure, since they are not + * subscriptable on their own. If the base type is subscriptable, the + * parser will reduce the type to the base type before subscripting. + */ + /* Inherited default value */ datum = SysCacheGetAttr(TYPEOID, typeTup, Anum_pg_type_typdefault, &isnull); @@ -1072,6 +1117,7 @@ DefineDomain(CreateDomainStmt *stmt) InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ analyzeProcedure, /* analyze procedure */ + InvalidOid, /* subscript procedure - none */ InvalidOid, /* no array element type */ false, /* this isn't an array */ domainArrayOid, /* array type we are about to create */ @@ -1111,6 +1157,7 @@ DefineDomain(CreateDomainStmt *stmt) InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ F_ARRAY_TYPANALYZE, /* analyze procedure */ + F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */ address.objectId, /* element type ID */ true, /* yes this is an array type */ InvalidOid, /* no further array type */ @@ -1237,6 +1284,7 @@ DefineEnum(CreateEnumStmt *stmt) InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ InvalidOid, /* analyze procedure - default */ + InvalidOid, /* subscript procedure - none */ InvalidOid, /* element type ID */ false, /* this is not an array type */ enumArrayOid, /* array type we are about to create */ @@ -1275,6 +1323,7 @@ DefineEnum(CreateEnumStmt *stmt) InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ F_ARRAY_TYPANALYZE, /* analyze procedure */ + F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */ enumTypeAddr.objectId, /* element type ID */ true, /* yes this is an array type */ InvalidOid, /* no further array type */ @@ -1383,6 +1432,11 @@ checkEnumOwner(HeapTuple tup) /* * DefineRange * Registers a new range type. + * + * Perhaps it might be worthwhile to set pg_type.typelem to the base type, + * and likewise on multiranges to set it to the range type. But having a + * non-zero typelem is treated elsewhere as a synonym for being an array, + * and users might have queries with that same assumption. */ ObjectAddress DefineRange(CreateRangeStmt *stmt) @@ -1391,7 +1445,13 @@ DefineRange(CreateRangeStmt *stmt) Oid typeNamespace; Oid typoid; char *rangeArrayName; + char *multirangeTypeName = NULL; + char *multirangeArrayName; + Oid multirangeNamespace = InvalidOid; + bool multirangeNameAutoGenerated = false; Oid rangeArrayOid; + Oid multirangeOid; + Oid multirangeArrayOid; Oid rangeSubtype = InvalidOid; List *rangeSubOpclassName = NIL; List *rangeCollationName = NIL; @@ -1408,6 +1468,8 @@ DefineRange(CreateRangeStmt *stmt) AclResult aclresult; ListCell *lc; ObjectAddress address; + ObjectAddress mltrngaddress PG_USED_FOR_ASSERTS_ONLY; + Oid castFuncOid; /* Convert list of names to a name and namespace */ typeNamespace = QualifiedNameGetCreationNamespace(stmt->typeName, @@ -1491,6 +1553,16 @@ DefineRange(CreateRangeStmt *stmt) errmsg("conflicting or redundant options"))); rangeSubtypeDiffName = defGetQualifiedName(defel); } + else if (strcmp(defel->defname, "multirange_type_name") == 0) + { + if (multirangeTypeName != NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + /* we can look up the subtype name immediately */ + multirangeNamespace = QualifiedNameGetCreationNamespace(defGetQualifiedName(defel), + &multirangeTypeName); + } else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -1556,9 +1628,28 @@ DefineRange(CreateRangeStmt *stmt) /* alignment must be TYPALIGN_INT or TYPALIGN_DOUBLE for ranges */ alignment = (subtypalign == TYPALIGN_DOUBLE) ? TYPALIGN_DOUBLE : TYPALIGN_INT; - /* Allocate OID for array type */ + /* + * GPDB: the multirange and multirange-array type OIDs must be pre-assigned + * on the QD keyed by (name, namespace) and dispatched to the segments, so + * resolve the auto-generated multirange name here, before OID assignment, + * rather than just before TypeCreate as upstream does. The probed names + * do not collide with the types being created, so computing them earlier + * yields identical names. + */ + if (multirangeTypeName == NULL) + { + multirangeNamespace = typeNamespace; + multirangeTypeName = makeMultirangeTypeName(typeName, multirangeNamespace); + multirangeNameAutoGenerated = true; + } + multirangeArrayName = makeArrayTypeName(multirangeTypeName, multirangeNamespace); + + /* Allocate OID for array type, its multirange, and its multirange array */ rangeArrayName = makeArrayTypeName(typeName, typeNamespace); rangeArrayOid = AssignTypeArrayOid(rangeArrayName, typeNamespace); + multirangeOid = AssignTypeMultirangeOid(multirangeTypeName, multirangeNamespace); + multirangeArrayOid = AssignTypeMultirangeArrayOid(multirangeArrayName, + multirangeNamespace); /* Create the pg_type entry */ address = @@ -1580,6 +1671,7 @@ DefineRange(CreateRangeStmt *stmt) InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ F_RANGE_TYPANALYZE, /* analyze procedure */ + InvalidOid, /* subscript procedure - none */ InvalidOid, /* element type ID - none */ false, /* this is not an array type */ rangeArrayOid, /* array type we are about to create */ @@ -1596,9 +1688,73 @@ DefineRange(CreateRangeStmt *stmt) Assert(typoid == InvalidOid || typoid == address.objectId); typoid = address.objectId; + /* + * Create the multirange that goes with it. The name was resolved above + * (GPDB pre-assigns its OID before this point). For a user-specified + * multirange name, check whether it already exists. + */ + if (!multirangeNameAutoGenerated) + { + Oid old_typoid; + + /* + * Look to see if multirange type already exists. + */ + old_typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, + CStringGetDatum(multirangeTypeName), + ObjectIdGetDatum(multirangeNamespace)); + + /* + * If it's not a shell, see if it's an autogenerated array type, and + * if so rename it out of the way. + */ + if (OidIsValid(old_typoid) && get_typisdefined(old_typoid)) + { + if (!moveArrayTypeName(old_typoid, multirangeTypeName, multirangeNamespace)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("type \"%s\" already exists", multirangeTypeName))); + } + } + + mltrngaddress = + TypeCreate(multirangeOid, /* force assignment of this type OID */ + multirangeTypeName, /* type name */ + multirangeNamespace, /* namespace */ + InvalidOid, /* relation oid (n/a here) */ + 0, /* relation kind (ditto) */ + GetUserId(), /* owner's ID */ + -1, /* internal size (always varlena) */ + TYPTYPE_MULTIRANGE, /* type-type (multirange type) */ + TYPCATEGORY_RANGE, /* type-category (range type) */ + false, /* multirange types are never preferred */ + DEFAULT_TYPDELIM, /* array element delimiter */ + F_MULTIRANGE_IN, /* input procedure */ + F_MULTIRANGE_OUT, /* output procedure */ + F_MULTIRANGE_RECV, /* receive procedure */ + F_MULTIRANGE_SEND, /* send procedure */ + InvalidOid, /* typmodin procedure - none */ + InvalidOid, /* typmodout procedure - none */ + F_MULTIRANGE_TYPANALYZE, /* analyze procedure */ + InvalidOid, /* subscript procedure - none */ + InvalidOid, /* element type ID - none */ + false, /* this is not an array type */ + multirangeArrayOid, /* array type we are about to create */ + InvalidOid, /* base type ID (only for domains) */ + NULL, /* never a default type value */ + NULL, /* no binary form available either */ + false, /* never passed by value */ + alignment, /* alignment */ + 'x', /* TOAST strategy (always extended) */ + -1, /* typMod (Domains only) */ + 0, /* Array dimensions of typbasetype */ + false, /* Type NOT NULL */ + InvalidOid); /* type's collation (ranges never have one) */ + Assert(multirangeOid == mltrngaddress.objectId); + /* Create the entry in pg_range */ RangeCreate(typoid, rangeSubtype, rangeCollation, rangeSubOpclass, - rangeCanonical, rangeSubtypeDiff); + rangeCanonical, rangeSubtypeDiff, multirangeOid); /* * Create the array type that goes with it. @@ -1621,6 +1777,7 @@ DefineRange(CreateRangeStmt *stmt) InvalidOid, /* typmodin procedure - none */ InvalidOid, /* typmodout procedure - none */ F_ARRAY_TYPANALYZE, /* analyze procedure */ + F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */ typoid, /* element type ID */ true, /* yes this is an array type */ InvalidOid, /* no further array type */ @@ -1637,8 +1794,52 @@ DefineRange(CreateRangeStmt *stmt) pfree(rangeArrayName); + /* Create the multirange's array type (name resolved above) */ + + TypeCreate(multirangeArrayOid, /* force assignment of this type OID */ + multirangeArrayName, /* type name */ + multirangeNamespace, /* namespace */ + InvalidOid, /* relation oid (n/a here) */ + 0, /* relation kind (ditto) */ + GetUserId(), /* owner's ID */ + -1, /* internal size (always varlena) */ + TYPTYPE_BASE, /* type-type (base type) */ + TYPCATEGORY_ARRAY, /* type-category (array) */ + false, /* array types are never preferred */ + DEFAULT_TYPDELIM, /* array element delimiter */ + F_ARRAY_IN, /* input procedure */ + F_ARRAY_OUT, /* output procedure */ + F_ARRAY_RECV, /* receive procedure */ + F_ARRAY_SEND, /* send procedure */ + InvalidOid, /* typmodin procedure - none */ + InvalidOid, /* typmodout procedure - none */ + F_ARRAY_TYPANALYZE, /* analyze procedure */ + F_ARRAY_SUBSCRIPT_HANDLER, /* array subscript procedure */ + multirangeOid, /* element type ID */ + true, /* yes this is an array type */ + InvalidOid, /* no further array type */ + InvalidOid, /* base type ID */ + NULL, /* never a default type value */ + NULL, /* binary default isn't sent either */ + false, /* never passed by value */ + alignment, /* alignment - same as range's */ + 'x', /* ARRAY is always toastable */ + -1, /* typMod (Domains only) */ + 0, /* Array dimensions of typbasetype */ + false, /* Type NOT NULL */ + InvalidOid); /* typcollation */ + /* And create the constructor functions for this range type */ makeRangeConstructors(typeName, typeNamespace, typoid, rangeSubtype); + makeMultirangeConstructors(multirangeTypeName, typeNamespace, + multirangeOid, typoid, rangeArrayOid, + &castFuncOid); + + /* Create cast from the range type to its multirange type */ + CastCreate(typoid, multirangeOid, castFuncOid, 'e', 'f', DEPENDENCY_INTERNAL); + + pfree(multirangeTypeName); + pfree(multirangeArrayName); if (Gp_role == GP_ROLE_DISPATCH) CdbDispatchUtilityStatement((Node *) stmt, @@ -1699,6 +1900,7 @@ makeRangeConstructors(const char *name, Oid namespace, InvalidOid, prosrc[i], /* prosrc */ NULL, /* probin */ + NULL, /* prosqlbody */ PROKIND_FUNCTION, false, /* security_definer */ false, /* leakproof */ @@ -1727,9 +1929,164 @@ makeRangeConstructors(const char *name, Oid namespace, } } +/* + * We make a separate multirange constructor for each range type + * so its name can include the base type, like range constructors do. + * If we had an anyrangearray polymorphic type we could use it here, + * but since each type has its own constructor name there's no need. + * + * Sets castFuncOid to the oid of the new constructor that can be used + * to cast from a range to a multirange. + */ +static void +makeMultirangeConstructors(const char *name, Oid namespace, + Oid multirangeOid, Oid rangeOid, Oid rangeArrayOid, + Oid *castFuncOid) +{ + ObjectAddress myself, + referenced; + oidvector *argtypes; + Datum allParamTypes; + ArrayType *allParameterTypes; + Datum paramModes; + ArrayType *parameterModes; + + referenced.classId = TypeRelationId; + referenced.objectId = multirangeOid; + referenced.objectSubId = 0; + + /* 0-arg constructor - for empty multiranges */ + argtypes = buildoidvector(NULL, 0); + myself = ProcedureCreate(name, /* name: same as multirange type */ + namespace, + false, /* replace */ + false, /* returns set */ + multirangeOid, /* return type */ + BOOTSTRAP_SUPERUSERID, /* proowner */ + INTERNALlanguageId, /* language */ + F_FMGR_INTERNAL_VALIDATOR, + InvalidOid, /* describeFuncOid */ + "multirange_constructor0", /* prosrc */ + NULL, /* probin */ + NULL, /* prosqlbody */ + PROKIND_FUNCTION, + false, /* security_definer */ + false, /* leakproof */ + true, /* isStrict */ + PROVOLATILE_IMMUTABLE, /* volatility */ + PROPARALLEL_SAFE, /* parallel safety */ + argtypes, /* parameterTypes */ + PointerGetDatum(NULL), /* allParameterTypes */ + PointerGetDatum(NULL), /* parameterModes */ + PointerGetDatum(NULL), /* parameterNames */ + NIL, /* parameterDefaults */ + PointerGetDatum(NULL), /* trftypes */ + PointerGetDatum(NULL), /* proconfig */ + InvalidOid, /* prosupport */ + 1.0, /* procost */ + 0.0, /* prorows */ + PRODATAACCESS_NONE, /* prodataaccess */ + PROEXECLOCATION_ANY); /* proexeclocation */ + + /* + * Make the constructor internally-dependent on the multirange type so + * that they go away silently when the type is dropped. Note that pg_dump + * depends on this choice to avoid dumping the constructors. + */ + recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + pfree(argtypes); + + /* + * 1-arg constructor - for casts + * + * In theory we shouldn't need both this and the vararg (n-arg) + * constructor, but having a separate 1-arg function lets us define casts + * against it. + */ + argtypes = buildoidvector(&rangeOid, 1); + myself = ProcedureCreate(name, /* name: same as multirange type */ + namespace, + false, /* replace */ + false, /* returns set */ + multirangeOid, /* return type */ + BOOTSTRAP_SUPERUSERID, /* proowner */ + INTERNALlanguageId, /* language */ + F_FMGR_INTERNAL_VALIDATOR, + InvalidOid, /* describeFuncOid */ + "multirange_constructor1", /* prosrc */ + NULL, /* probin */ + NULL, /* prosqlbody */ + PROKIND_FUNCTION, + false, /* security_definer */ + false, /* leakproof */ + true, /* isStrict */ + PROVOLATILE_IMMUTABLE, /* volatility */ + PROPARALLEL_SAFE, /* parallel safety */ + argtypes, /* parameterTypes */ + PointerGetDatum(NULL), /* allParameterTypes */ + PointerGetDatum(NULL), /* parameterModes */ + PointerGetDatum(NULL), /* parameterNames */ + NIL, /* parameterDefaults */ + PointerGetDatum(NULL), /* trftypes */ + PointerGetDatum(NULL), /* proconfig */ + InvalidOid, /* prosupport */ + 1.0, /* procost */ + 0.0, /* prorows */ + PRODATAACCESS_NONE, + PROEXECLOCATION_ANY); + /* ditto */ + recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + pfree(argtypes); + *castFuncOid = myself.objectId; + + /* n-arg constructor - vararg */ + argtypes = buildoidvector(&rangeArrayOid, 1); + allParamTypes = ObjectIdGetDatum(rangeArrayOid); + allParameterTypes = construct_array(&allParamTypes, + 1, OIDOID, + sizeof(Oid), true, 'i'); + paramModes = CharGetDatum(FUNC_PARAM_VARIADIC); + parameterModes = construct_array(¶mModes, 1, CHAROID, + 1, true, 'c'); + myself = ProcedureCreate(name, /* name: same as multirange type */ + namespace, + false, /* replace */ + false, /* returns set */ + multirangeOid, /* return type */ + BOOTSTRAP_SUPERUSERID, /* proowner */ + INTERNALlanguageId, /* language */ + F_FMGR_INTERNAL_VALIDATOR, + InvalidOid, /* describeFuncOid */ + "multirange_constructor2", /* prosrc */ + NULL, /* probin */ + NULL, /* prosqlbody */ + PROKIND_FUNCTION, + false, /* security_definer */ + false, /* leakproof */ + true, /* isStrict */ + PROVOLATILE_IMMUTABLE, /* volatility */ + PROPARALLEL_SAFE, /* parallel safety */ + argtypes, /* parameterTypes */ + PointerGetDatum(allParameterTypes), /* allParameterTypes */ + PointerGetDatum(parameterModes), /* parameterModes */ + PointerGetDatum(NULL), /* parameterNames */ + NIL, /* parameterDefaults */ + PointerGetDatum(NULL), /* trftypes */ + PointerGetDatum(NULL), /* proconfig */ + InvalidOid, /* prosupport */ + 1.0, /* procost */ + 0.0, /* prorows */ + PRODATAACCESS_NONE, + PROEXECLOCATION_ANY); + /* ditto */ + recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + pfree(argtypes); + pfree(allParameterTypes); + pfree(parameterModes); +} /* - * Find suitable I/O functions for a type. + * Find suitable I/O and other support functions for a type. * * typeOid is the type's OID (which will already exist, if only as a shell * type). @@ -2017,6 +2374,45 @@ findTypeAnalyzeFunction(List *procname, Oid typeOid) return procOid; } +static Oid +findTypeSubscriptingFunction(List *procname, Oid typeOid) +{ + Oid argList[1]; + Oid procOid; + + /* + * Subscripting support functions always take one INTERNAL argument and + * return INTERNAL. (The argument is not used, but we must have it to + * maintain type safety.) + */ + argList[0] = INTERNALOID; + + procOid = LookupFuncName(procname, 1, argList, true); + if (!OidIsValid(procOid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("function %s does not exist", + func_signature_string(procname, 1, NIL, argList)))); + + if (get_func_rettype(procOid) != INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("type subscripting function %s must return type %s", + NameListToString(procname), "internal"))); + + /* + * We disallow array_subscript_handler() from being selected explicitly, + * since that must only be applied to autogenerated array types. + */ + if (procOid == F_ARRAY_SUBSCRIPT_HANDLER) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("user-defined types cannot use subscripting function %s", + NameListToString(procname)))); + + return procOid; +} + /* * Find suitable support functions and opclasses for a range type. */ @@ -2170,6 +2566,81 @@ AssignTypeArrayOid(char *arrayTypeName, Oid typeNamespace) return type_array_oid; } +/* + * AssignTypeMultirangeOid + * + * Pre-assign the range type's multirange OID for use in pg_type.oid + */ +Oid +AssignTypeMultirangeOid(char *multirangeTypeName, Oid typeNamespace) +{ + Oid type_multirange_oid; + + /* Use binary-upgrade override for pg_type.oid? */ + if (IsBinaryUpgrade) + { + if (!OidIsValid(binary_upgrade_next_mrng_pg_type_oid)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("pg_type multirange OID value not set when in binary upgrade mode"))); + + type_multirange_oid = binary_upgrade_next_mrng_pg_type_oid; + binary_upgrade_next_mrng_pg_type_oid = InvalidOid; + } + else + { + Relation pg_type = table_open(TypeRelationId, AccessShareLock); + + /* + * GPDB: use the OID-dispatch-aware allocator so the segments reuse the + * OID pre-assigned on the QD (keyed by name+namespace), as for the + * range and array types. + */ + type_multirange_oid = GetNewOidForType(pg_type, TypeOidIndexId, + Anum_pg_type_oid, + multirangeTypeName, typeNamespace); + table_close(pg_type, AccessShareLock); + } + + return type_multirange_oid; +} + +/* + * AssignTypeMultirangeArrayOid + * + * Pre-assign the range type's multirange array OID for use in pg_type.typarray + */ +Oid +AssignTypeMultirangeArrayOid(char *multirangeArrayName, Oid typeNamespace) +{ + Oid type_multirange_array_oid; + + /* Use binary-upgrade override for pg_type.oid? */ + if (IsBinaryUpgrade) + { + if (!OidIsValid(binary_upgrade_next_mrng_array_pg_type_oid)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("pg_type multirange array OID value not set when in binary upgrade mode"))); + + type_multirange_array_oid = binary_upgrade_next_mrng_array_pg_type_oid; + binary_upgrade_next_mrng_array_pg_type_oid = InvalidOid; + } + else + { + Relation pg_type = table_open(TypeRelationId, AccessShareLock); + + /* GPDB: OID-dispatch-aware allocation, see AssignTypeMultirangeOid(). */ + type_multirange_array_oid = GetNewOidForType(pg_type, TypeOidIndexId, + Anum_pg_type_oid, + multirangeArrayName, + typeNamespace); + table_close(pg_type, AccessShareLock); + } + + return type_multirange_array_oid; +} + /*------------------------------------------------------------------- * DefineCompositeType @@ -3334,8 +3805,7 @@ RenameType(RenameStmt *stmt) errhint("Use ALTER TABLE instead."))); /* don't allow direct alteration of array types, either */ - if (OidIsValid(typTup->typelem) && - get_array_type(typTup->typelem) == typeOid) + if (IsTrueArrayType(typTup)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot alter array type %s", @@ -3416,8 +3886,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) errhint("Use ALTER TABLE instead."))); /* don't allow direct alteration of array types, either */ - if (OidIsValid(typTup->typelem) && - get_array_type(typTup->typelem) == typeOid) + if (IsTrueArrayType(typTup)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot alter array type %s", @@ -3965,6 +4434,18 @@ AlterType(AlterTypeStmt *stmt) /* Replacing an analyze function requires superuser. */ requireSuper = true; } + else if (strcmp(defel->defname, "subscript") == 0) + { + if (defel->arg != NULL) + atparams.subscriptOid = + findTypeSubscriptingFunction(defGetQualifiedName(defel), + typeOid); + else + atparams.subscriptOid = InvalidOid; /* NONE, remove function */ + atparams.updateSubscript = true; + /* Replacing a subscript function requires superuser. */ + requireSuper = true; + } /* * The rest of the options that CREATE accepts cannot be changed. @@ -4029,8 +4510,7 @@ AlterType(AlterTypeStmt *stmt) /* * For the same reasons, don't allow direct alteration of array types. */ - if (OidIsValid(typForm->typelem) && - get_array_type(typForm->typelem) == typeOid) + if (IsTrueArrayType(typForm)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is not a base type", @@ -4044,6 +4524,18 @@ AlterType(AlterTypeStmt *stmt) table_close(catalog, RowExclusiveLock); + /* + * The pg_type changes (e.g. typsubscript) are consulted directly by the + * QEs at executor startup, so the segments' copies must be updated too. + */ + if (Gp_role == GP_ROLE_DISPATCH) + CdbDispatchUtilityStatement((Node *) stmt, + DF_CANCEL_ON_ERROR| + DF_WITH_SNAPSHOT| + DF_NEED_TWO_PHASE, + NIL, + NULL); + ObjectAddressSet(address, TypeRelationId, typeOid); return address; @@ -4123,6 +4615,11 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray, replaces[Anum_pg_type_typanalyze - 1] = true; values[Anum_pg_type_typanalyze - 1] = ObjectIdGetDatum(atparams->analyzeOid); } + if (atparams->updateSubscript) + { + replaces[Anum_pg_type_typsubscript - 1] = true; + values[Anum_pg_type_typsubscript - 1] = ObjectIdGetDatum(atparams->subscriptOid); + } newtup = heap_modify_tuple(tup, RelationGetDescr(catalog), values, nulls, replaces); @@ -4179,6 +4676,7 @@ AlterTypeRecurse(Oid typeOid, bool isImplicitArray, atparams->updateReceive = false; /* domains use F_DOMAIN_RECV */ atparams->updateTypmodin = false; /* domains don't have typmods */ atparams->updateTypmodout = false; + atparams->updateSubscript = false; /* domains don't have subscriptors */ /* Skip the scan if nothing remains to be done */ if (!(atparams->updateStorage || diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 1b70ecd536de..ad89c9ed7e11 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/commands/user.c @@ -395,7 +395,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to change bypassrls attribute"))); + errmsg("must be superuser to create bypassrls users"))); } else { @@ -1018,8 +1018,10 @@ AlterRole(AlterRoleStmt *stmt) roleid = authform->oid; /* - * To mess with a superuser you gotta be superuser; else you need - * createrole, or just want to change your own password + * To mess with a superuser or replication role in any way you gotta be + * superuser. We also insist on superuser to change the BYPASSRLS + * property. Otherwise, if you don't have createrole, you're only allowed + * to change your own password. */ bWas_super = ((Form_pg_authid) GETSTRUCT(tuple))->rolsuper; @@ -1029,16 +1031,16 @@ AlterRole(AlterRoleStmt *stmt) if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to alter superusers"))); + errmsg("must be superuser to alter superuser roles or change superuser attribute"))); } else if (authform->rolreplication || isreplication >= 0) { if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to alter replication users"))); + errmsg("must be superuser to alter replication roles or change replication attribute"))); } - else if (authform->rolbypassrls || bypassrls >= 0) + else if (bypassrls >= 0) { if (!superuser()) ereport(ERROR, @@ -1047,11 +1049,11 @@ AlterRole(AlterRoleStmt *stmt) } else if (!have_createrole_privilege()) { + /* We already checked issuper, isreplication, and bypassrls */ if (!(inherit < 0 && createrole < 0 && createdb < 0 && canlogin < 0 && - isreplication < 0 && !dconnlimit && !rolemembers && !validUntil && @@ -2079,6 +2081,18 @@ AddRoleMems(const char *rolename, Oid roleid, rolename))); } + /* + * The charter of pg_database_owner is to have exactly one, implicit, + * situation-dependent member. There's no technical need for this + * restriction. (One could lift it and take the further step of making + * pg_database_ownercheck() equivalent to has_privs_of_role(roleid, + * ROLE_PG_DATABASE_OWNER), in which case explicit, situation-independent + * members could act as the owner of any database.) + */ + if (roleid == ROLE_PG_DATABASE_OWNER) + ereport(ERROR, + errmsg("role \"%s\" cannot have explicit members", rolename)); + /* * The role membership grantor of record has little significance at * present. Nonetheless, inasmuch as users might look to it for a crude @@ -2107,6 +2121,30 @@ AddRoleMems(const char *rolename, Oid roleid, bool new_record_nulls[Natts_pg_auth_members]; bool new_record_repl[Natts_pg_auth_members]; + /* + * pg_database_owner is never a role member. Lifting this restriction + * would require a policy decision about membership loops. One could + * prevent loops, which would include making "ALTER DATABASE x OWNER + * TO proposed_datdba" fail if is_member_of_role(pg_database_owner, + * proposed_datdba). Hence, gaining a membership could reduce what a + * role could do. Alternately, one could allow these memberships to + * complete loops. A role could then have actual WITH ADMIN OPTION on + * itself, prompting a decision about is_admin_of_role() treatment of + * the case. + * + * Lifting this restriction also has policy implications for ownership + * of shared objects (databases and tablespaces). We allow such + * ownership, but we might find cause to ban it in the future. + * Designing such a ban would more troublesome if the design had to + * address pg_database_owner being a member of role FOO that owns a + * shared object. (The effect of such ownership is that any owner of + * another database can act as the owner of affected shared objects.) + */ + if (memberid == ROLE_PG_DATABASE_OWNER) + ereport(ERROR, + errmsg("role \"%s\" cannot be a member of any role", + get_rolespec_name(memberRole))); + /* * Refuse creation of membership loops, including the trivial case * where a role is made a member of itself. We do this by checking to diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 2b03ac8ea0e9..02b7a860491d 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -86,6 +86,8 @@ int vacuum_freeze_min_age; int vacuum_freeze_table_age; int vacuum_multixact_freeze_min_age; int vacuum_multixact_freeze_table_age; +int vacuum_failsafe_age; +int vacuum_multixact_failsafe_age; /* A few variables that don't seem worth passing around as parameters */ @@ -111,7 +113,7 @@ static void vac_truncate_clog(TransactionId frozenXID, static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, bool recursing); static double compute_parallel_delay(void); -static VacOptTernaryValue get_vacopt_ternary_value(DefElem *def); +static VacOptValue get_vacoptval_from_boolean(DefElem *def); static void dispatchVacuum(VacuumParams *params, Oid relid, VacuumStatsContext *ctx); @@ -139,11 +141,12 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel, bool auto_s bool rootonly = false; bool fullscan = false; int ao_phase = 0; + bool process_toast = true; ListCell *lc; - /* Set default value */ - params.index_cleanup = VACOPT_TERNARY_DEFAULT; - params.truncate = VACOPT_TERNARY_DEFAULT; + /* index_cleanup and truncate values unspecified for now */ + params.index_cleanup = VACOPTVALUE_UNSPECIFIED; + params.truncate = VACOPTVALUE_UNSPECIFIED; /* By default parallel vacuum is enabled */ /* VACUUM option "parallel" not supported in GPDB */ @@ -179,9 +182,25 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel, bool auto_s else if (strcmp(opt->defname, "disable_page_skipping") == 0) disable_page_skipping = defGetBoolean(opt); else if (strcmp(opt->defname, "index_cleanup") == 0) - params.index_cleanup = get_vacopt_ternary_value(opt); + { + /* Interpret no string as the default, which is 'auto' */ + if (!opt->arg) + params.index_cleanup = VACOPTVALUE_AUTO; + else + { + char *sval = defGetString(opt); + + /* Try matching on 'auto' string, or fall back on boolean */ + if (pg_strcasecmp(sval, "auto") == 0) + params.index_cleanup = VACOPTVALUE_AUTO; + else + params.index_cleanup = get_vacoptval_from_boolean(opt); + } + } + else if (strcmp(opt->defname, "process_toast") == 0) + process_toast = defGetBoolean(opt); else if (strcmp(opt->defname, "truncate") == 0) - params.truncate = get_vacopt_ternary_value(opt); + params.truncate = get_vacoptval_from_boolean(opt); else if (Gp_role == GP_ROLE_EXECUTE && strcmp(opt->defname, "ao_phase") == 0) { ao_phase = defGetInt32(opt); @@ -213,7 +232,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel, bool auto_s if (nworkers < 0 || nworkers > MAX_PARALLEL_WORKER_LIMIT) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("parallel vacuum degree must be between 0 and %d", + errmsg("parallel workers for vacuum must be between 0 and %d", MAX_PARALLEL_WORKER_LIMIT), parser_errposition(pstate, opt->location))); @@ -245,7 +264,8 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel, bool auto_s (analyze ? VACOPT_ANALYZE : 0) | (freeze ? VACOPT_FREEZE : 0) | (full ? VACOPT_FULL : 0) | - (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0); + (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0) | + (process_toast ? VACOPT_PROCESS_TOAST : 0); if (rootonly) params.options |= VACOPT_ROOTONLY; @@ -257,7 +277,6 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel, bool auto_s Assert(params.options & (VACOPT_VACUUM | VACOPT_ANALYZE)); Assert((params.options & VACOPT_VACUUM) || !(params.options & (VACOPT_FULL | VACOPT_FREEZE))); - Assert(!(params.options & VACOPT_SKIPTOAST)); if ((params.options & VACOPT_FULL) && params.nworkers > 0) ereport(ERROR, @@ -392,6 +411,13 @@ vacuum(List *relations, VacuumParams *params, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL"))); + /* sanity check for PROCESS_TOAST */ + if ((params->options & VACOPT_FULL) != 0 && + (params->options & VACOPT_PROCESS_TOAST) == 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("PROCESS_TOAST required with VACUUM FULL"))); + /* * Send info about dead objects to the statistics collector, unless we are * in autovacuum --- autovacuum.c does this for itself. @@ -631,7 +657,7 @@ vacuum(List *relations, VacuumParams *params, * ANALYZE. */ bool -vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options) +vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, bits32 options) { char *relname; @@ -705,10 +731,10 @@ vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options) * or locked, a log is emitted if possible. */ Relation -vacuum_open_relation(Oid relid, RangeVar *relation, int options, +vacuum_open_relation(Oid relid, RangeVar *relation, bits32 options, bool verbose, LOCKMODE lmode) { - Relation onerel; + Relation rel; bool rel_lock = true; int elevel; @@ -724,18 +750,18 @@ vacuum_open_relation(Oid relid, RangeVar *relation, int options, * in non-blocking mode, before calling try_relation_open(). */ if (!(options & VACOPT_SKIP_LOCKED)) - onerel = try_relation_open(relid, lmode, false); + rel = try_relation_open(relid, lmode, false); else if (ConditionalLockRelationOid(relid, lmode)) - onerel = try_relation_open(relid, NoLock, false); + rel = try_relation_open(relid, NoLock, false); else { - onerel = NULL; + rel = NULL; rel_lock = false; } /* if relation is opened, leave */ - if (onerel) - return onerel; + if (rel) + return rel; /* * Relation could not be opened, hence generate if possible a log @@ -1049,7 +1075,7 @@ expand_vacuum_rel(VacuumRelation *vrel, int options) Oid parent_relid; int elevel = ((options & VACOPT_VERBOSE) ? LOG : DEBUG2); - parent_relid = get_partition_parent(child_relid); + parent_relid = get_partition_parent(child_relid, false); /* * Only ANALYZE the parent if the stats can be updated by merging @@ -1147,6 +1173,8 @@ get_all_vacuum_rels(int options) /* * vacuum_set_xid_limits() -- compute oldestXmin and freeze cutoff points * + * Input parameters are the target relation, applicable freeze age settings. + * * The output parameters are: * - oldestXmin is the cutoff value used to distinguish whether tuples are * DEAD or RECENTLY_DEAD (see HeapTupleSatisfiesVacuum). @@ -1202,12 +1230,13 @@ vacuum_set_xid_limits(Relation rel, TransactionId limit_xmin; TimestampTz limit_ts; - if (TransactionIdLimitedForOldSnapshots(*oldestXmin, rel, &limit_xmin, &limit_ts)) + if (TransactionIdLimitedForOldSnapshots(*oldestXmin, rel, + &limit_xmin, &limit_ts)) { /* * TODO: We should only set the threshold if we are pruning on the - * basis of the increased limits. Not as crucial here as it is for - * opportunistic pruning (which often happens at a much higher + * basis of the increased limits. Not as crucial here as it is + * for opportunistic pruning (which often happens at a much higher * frequency), but would still be a significant improvement. */ SetOldSnapshotThresholdTimestamp(limit_ts, limit_xmin); @@ -1241,7 +1270,7 @@ vacuum_set_xid_limits(Relation rel, * autovacuum_freeze_max_age / 2 XIDs old), complain and force a minimum * freeze age of zero. */ - safeLimit = ReadNewTransactionId() - autovacuum_freeze_max_age; + safeLimit = ReadNextTransactionId() - autovacuum_freeze_max_age; if (!TransactionIdIsNormal(safeLimit)) safeLimit = FirstNormalTransactionId; @@ -1324,7 +1353,7 @@ vacuum_set_xid_limits(Relation rel, * Compute XID limit causing a full-table vacuum, being careful not to * generate a "permanent" XID. */ - limit = ReadNewTransactionId() - freezetable; + limit = ReadNextTransactionId() - freezetable; if (!TransactionIdIsNormal(limit)) limit = FirstNormalTransactionId; @@ -1361,6 +1390,62 @@ vacuum_set_xid_limits(Relation rel, } } +/* + * vacuum_xid_failsafe_check() -- Used by VACUUM's wraparound failsafe + * mechanism to determine if its table's relfrozenxid and relminmxid are now + * dangerously far in the past. + * + * Input parameters are the target relation's relfrozenxid and relminmxid. + * + * When we return true, VACUUM caller triggers the failsafe. + */ +bool +vacuum_xid_failsafe_check(TransactionId relfrozenxid, MultiXactId relminmxid) +{ + TransactionId xid_skip_limit; + MultiXactId multi_skip_limit; + int skip_index_vacuum; + + Assert(TransactionIdIsNormal(relfrozenxid)); + Assert(MultiXactIdIsValid(relminmxid)); + + /* + * Determine the index skipping age to use. In any case no less than + * autovacuum_freeze_max_age * 1.05. + */ + skip_index_vacuum = Max(vacuum_failsafe_age, autovacuum_freeze_max_age * 1.05); + + xid_skip_limit = ReadNextTransactionId() - skip_index_vacuum; + if (!TransactionIdIsNormal(xid_skip_limit)) + xid_skip_limit = FirstNormalTransactionId; + + if (TransactionIdPrecedes(relfrozenxid, xid_skip_limit)) + { + /* The table's relfrozenxid is too old */ + return true; + } + + /* + * Similar to above, determine the index skipping age to use for + * multixact. In any case no less than autovacuum_multixact_freeze_max_age * + * 1.05. + */ + skip_index_vacuum = Max(vacuum_multixact_failsafe_age, + autovacuum_multixact_freeze_max_age * 1.05); + + multi_skip_limit = ReadNextMultiXactId() - skip_index_vacuum; + if (multi_skip_limit < FirstMultiXactId) + multi_skip_limit = FirstMultiXactId; + + if (MultiXactIdPrecedes(relminmxid, multi_skip_limit)) + { + /* The table's relminmxid is too old */ + return true; + } + + return false; +} + /* * vac_estimate_reltuples() -- estimate the new value for pg_class.reltuples * @@ -1368,8 +1453,8 @@ vacuum_set_xid_limits(Relation rel, * live tuples seen; but if we did not, we should not blindly extrapolate * from that number, since VACUUM may have scanned a quite nonrandom * subset of the table. When we have only partial information, we take - * the old value of pg_class.reltuples as a measurement of the - * tuple density in the unscanned pages. + * the old value of pg_class.reltuples/pg_class.relpages as a measurement + * of the tuple density in the unscanned pages. * * Note: scanned_tuples should count only *live* tuples, since * pg_class.reltuples is defined that way. @@ -1392,18 +1477,16 @@ vac_estimate_reltuples(Relation relation, /* * If scanned_pages is zero but total_pages isn't, keep the existing value - * of reltuples. (Note: callers should avoid updating the pg_class - * statistics in this situation, since no new information has been - * provided.) + * of reltuples. (Note: we might be returning -1 in this case.) */ if (scanned_pages == 0) return old_rel_tuples; /* - * If old value of relpages is zero, old density is indeterminate; we - * can't do much except scale up scanned_tuples to match total_pages. + * If old density is unknown, we can't do much except scale up + * scanned_tuples to match total_pages. */ - if (old_rel_pages == 0) + if (old_rel_tuples < 0 || old_rel_pages == 0) return floor((scanned_tuples / scanned_pages) * total_pages + 0.5); /* @@ -1619,7 +1702,7 @@ vac_update_relstats(Relation relation, TransactionIdIsValid(pgcform->relfrozenxid) && pgcform->relfrozenxid != frozenxid && (TransactionIdPrecedes(pgcform->relfrozenxid, frozenxid) || - TransactionIdPrecedes(ReadNewTransactionId(), + TransactionIdPrecedes(ReadNextTransactionId(), pgcform->relfrozenxid))) { pgcform->relfrozenxid = frozenxid; @@ -1694,7 +1777,9 @@ fetch_database_tuple(Relation relation, Oid dbOid) void vac_update_datfrozenxid(void) { + HeapTuple tuple; HeapTuple cached_tuple; + Form_pg_database dbform; Form_pg_database cached_dbform; Relation relation; SysScanDesc scan; @@ -1705,6 +1790,7 @@ vac_update_datfrozenxid(void) MultiXactId lastSaneMinMulti; bool bogus = false; bool dirty = false; + ScanKeyData key[1]; /* * Restrict this task to one backend per database. This avoids race @@ -1740,7 +1826,7 @@ vac_update_datfrozenxid(void) * validly see during the scan. These are conservative values, but it's * not really worth trying to be more exact. */ - lastSaneFrozenXid = ReadNewTransactionId(); + lastSaneFrozenXid = ReadNextTransactionId(); lastSaneMinMulti = ReadNextMultiXactId(); /* @@ -1832,6 +1918,26 @@ vac_update_datfrozenxid(void) /* Now fetch the pg_database tuple we need to update. */ relation = table_open(DatabaseRelationId, RowExclusiveLock); + /* + * Get the pg_database tuple to scribble on. Note that this does not + * directly rely on the syscache to avoid issues with flattened toast + * values for the in-place update. + */ + ScanKeyInit(&key[0], + Anum_pg_database_oid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(MyDatabaseId)); + + scan = systable_beginscan(relation, DatabaseOidIndexId, true, + NULL, 1, key); + tuple = systable_getnext(scan); + tuple = heap_copytuple(tuple); + systable_endscan(scan); + + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "could not find tuple for database %u", MyDatabaseId); + + dbform = (Form_pg_database) GETSTRUCT(tuple); cached_tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId)); cached_dbform = (Form_pg_database) GETSTRUCT(cached_tuple); @@ -1919,7 +2025,7 @@ vac_truncate_clog(TransactionId frozenXID, TransactionId lastSaneFrozenXid, MultiXactId lastSaneMinMulti) { - TransactionId nextXID = ReadNewTransactionId(); + TransactionId nextXID = ReadNextTransactionId(); Relation relation; TableScanDesc scan; HeapTuple tuple; @@ -2069,8 +2175,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, bool recursing) { LOCKMODE lmode; - Relation onerel; - LockRelId onerelid; + Relation rel; + LockRelId lockrelid; Oid toast_relid; Oid aoseg_relid = InvalidOid; Oid aoblkdir_relid = InvalidOid; @@ -2090,13 +2196,6 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, /* Begin a transaction for vacuuming this relation */ StartTransactionCommand(); - /* - * Need to acquire a snapshot to prevent pg_subtrans from being truncated, - * cutoff xids in local memory wrapping around, and to have updated xmin - * horizons. - */ - PushActiveSnapshot(GetTransactionSnapshot()); - if (!(params->options & VACOPT_FULL)) { /* @@ -2122,18 +2221,27 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * Note: these flags remain set until CommitTransaction or * AbortTransaction. We don't want to clear them until we reset * MyProc->xid/xmin, otherwise GetOldestNonRemovableTransactionId() - * might appear to go backwards, which is probably Not Good. + * might appear to go backwards, which is probably Not Good. (We also + * set PROC_IN_VACUUM *before* taking our own snapshot, so that our + * xmin doesn't become visible ahead of setting the flag.) */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); -#if 0 /* Upstream code not applicable to GPDB */ - MyProc->vacuumFlags |= PROC_IN_VACUUM; +#if 0 /* Upstream code not applicable to GPDB, see comment above */ + MyProc->statusFlags |= PROC_IN_VACUUM; #endif if (params->is_wraparound) - MyProc->vacuumFlags |= PROC_VACUUM_FOR_WRAPAROUND; - ProcGlobal->vacuumFlags[MyProc->pgxactoff] = MyProc->vacuumFlags; + MyProc->statusFlags |= PROC_VACUUM_FOR_WRAPAROUND; + ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; LWLockRelease(ProcArrayLock); } + /* + * Need to acquire a snapshot to prevent pg_subtrans from being truncated, + * cutoff xids in local memory wrapping around, and to have updated xmin + * horizons. + */ + PushActiveSnapshot(GetTransactionSnapshot()); + /* * Check for user-requested abort. Note we want this to be inside a * transaction, so xact.c doesn't issue useless WARNING. @@ -2158,11 +2266,11 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, AccessExclusiveLock : ShareUpdateExclusiveLock; /* open the relation and get the appropriate lock on it */ - onerel = vacuum_open_relation(relid, relation, params->options, - params->log_min_duration >= 0, lmode); + rel = vacuum_open_relation(relid, relation, params->options, + params->log_min_duration >= 0, lmode); /* leave if relation could not be opened or locked */ - if (!onerel) + if (!rel) { PopActiveSnapshot(); CommitTransactionCommand(); @@ -2177,11 +2285,11 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * changed in-between. Make sure to only generate logs for VACUUM in this * case. */ - if (!vacuum_is_relation_owner(RelationGetRelid(onerel), - onerel->rd_rel, + if (!vacuum_is_relation_owner(RelationGetRelid(rel), + rel->rd_rel, params->options & VACOPT_VACUUM)) { - relation_close(onerel, lmode); + relation_close(rel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); return false; @@ -2189,19 +2297,25 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, /* * Check that it's of a vacuumable relkind. - */ - if (onerel->rd_rel->relkind != RELKIND_RELATION && - onerel->rd_rel->relkind != RELKIND_MATVIEW && - onerel->rd_rel->relkind != RELKIND_TOASTVALUE && - onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE && - onerel->rd_rel->relkind != RELKIND_AOSEGMENTS && - onerel->rd_rel->relkind != RELKIND_AOBLOCKDIR && - onerel->rd_rel->relkind != RELKIND_AOVISIMAP) + * + * GPDB: append-optimized auxiliary relations (segment map, block + * directory, visibility map) are heap-storage catalogs that must stay + * vacuumable; the PG14 merge dropped them from this list, so VACUUM of + * an AO table warned and skipped its aux tables, which then never + * shrank under VACUUM FULL. + */ + if (rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_MATVIEW && + rel->rd_rel->relkind != RELKIND_TOASTVALUE && + rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE && + rel->rd_rel->relkind != RELKIND_AOSEGMENTS && + rel->rd_rel->relkind != RELKIND_AOBLOCKDIR && + rel->rd_rel->relkind != RELKIND_AOVISIMAP) { ereport(WARNING, (errmsg("skipping \"%s\" --- cannot vacuum non-tables or special system tables", - RelationGetRelationName(onerel)))); - relation_close(onerel, lmode); + RelationGetRelationName(rel)))); + relation_close(rel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); return false; @@ -2214,9 +2328,9 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * warning here; it would just lead to chatter during a database-wide * VACUUM.) */ - if (RELATION_IS_OTHER_TEMP(onerel)) + if (RELATION_IS_OTHER_TEMP(rel)) { - relation_close(onerel, lmode); + relation_close(rel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); return false; @@ -2227,9 +2341,9 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * useful work is on their child partitions, which have been queued up for * us separately. */ - if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - relation_close(onerel, lmode); + relation_close(rel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); /* It's OK to proceed with ANALYZE on this table */ @@ -2246,27 +2360,46 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * because the lock manager knows that both lock requests are from the * same process. */ - onerelid = onerel->rd_lockInfo.lockRelId; - LockRelationIdForSession(&onerelid, lmode); + lockrelid = rel->rd_lockInfo.lockRelId; + LockRelationIdForSession(&lockrelid, lmode); - /* Set index cleanup option based on reloptions if not yet */ - if (params->index_cleanup == VACOPT_TERNARY_DEFAULT) + /* + * Set index_cleanup option based on index_cleanup reloption if it wasn't + * specified in VACUUM command, or when running in an autovacuum worker + */ + if (params->index_cleanup == VACOPTVALUE_UNSPECIFIED) { - if (onerel->rd_options == NULL || - ((StdRdOptions *) onerel->rd_options)->vacuum_index_cleanup) - params->index_cleanup = VACOPT_TERNARY_ENABLED; + StdRdOptIndexCleanup vacuum_index_cleanup; + + if (rel->rd_options == NULL) + vacuum_index_cleanup = STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO; + else + vacuum_index_cleanup = + ((StdRdOptions *) rel->rd_options)->vacuum_index_cleanup; + + if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO) + params->index_cleanup = VACOPTVALUE_AUTO; + else if (vacuum_index_cleanup == STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON) + params->index_cleanup = VACOPTVALUE_ENABLED; else - params->index_cleanup = VACOPT_TERNARY_DISABLED; + { + Assert(vacuum_index_cleanup == + STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF); + params->index_cleanup = VACOPTVALUE_DISABLED; + } } - /* Set truncate option based on reloptions if not yet */ - if (params->truncate == VACOPT_TERNARY_DEFAULT) + /* + * Set truncate option based on truncate reloption if it wasn't specified + * in VACUUM command, or when running in an autovacuum worker + */ + if (params->truncate == VACOPTVALUE_UNSPECIFIED) { - if (onerel->rd_options == NULL || - ((StdRdOptions *) onerel->rd_options)->vacuum_truncate) - params->truncate = VACOPT_TERNARY_ENABLED; + if (rel->rd_options == NULL || + ((StdRdOptions *) rel->rd_options)->vacuum_truncate) + params->truncate = VACOPTVALUE_ENABLED; else - params->truncate = VACOPT_TERNARY_DISABLED; + params->truncate = VACOPTVALUE_DISABLED; } /* @@ -2276,14 +2409,15 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * * GPDB: Also remember the AO segment relations for later. */ - if (!(params->options & VACOPT_SKIPTOAST) && !(params->options & VACOPT_FULL)) - toast_relid = onerel->rd_rel->reltoastrelid; + if ((params->options & VACOPT_PROCESS_TOAST) != 0 && + (params->options & VACOPT_FULL) == 0) + toast_relid = rel->rd_rel->reltoastrelid; else toast_relid = InvalidOid; - if (RelationIsAppendOptimized(onerel)) + if (RelationIsAppendOptimized(rel)) { - GetAppendOnlyEntryAuxOids(RelationGetRelid(onerel), NULL, + GetAppendOnlyEntryAuxOids(RelationGetRelid(rel), NULL, &aoseg_relid, &aoblkdir_relid, NULL, &aovisimap_relid, NULL); @@ -2299,25 +2433,25 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * Note we choose to treat permissions failure as a WARNING and keep * trying to vacuum the rest of the DB --- is this appropriate? */ - if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) || - (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared))) + if (!(pg_class_ownercheck(RelationGetRelid(rel), GetUserId()) || + (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !rel->rd_rel->relisshared))) { if (Gp_role != GP_ROLE_EXECUTE) { - if (onerel->rd_rel->relisshared) + if (rel->rd_rel->relisshared) ereport(WARNING, (errmsg("skipping \"%s\" --- only superuser can vacuum it", - RelationGetRelationName(onerel)))); - else if (onerel->rd_rel->relnamespace == PG_CATALOG_NAMESPACE) + RelationGetRelationName(rel)))); + else if (rel->rd_rel->relnamespace == PG_CATALOG_NAMESPACE) ereport(WARNING, (errmsg("skipping \"%s\" --- only superuser or database owner can vacuum it", - RelationGetRelationName(onerel)))); + RelationGetRelationName(rel)))); else ereport(WARNING, (errmsg("skipping \"%s\" --- only table or database owner can vacuum it", - RelationGetRelationName(onerel)))); + RelationGetRelationName(rel)))); } - relation_close(onerel, lmode); + relation_close(rel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); return false; @@ -2328,18 +2462,18 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * get_rel_oids() but seems safer to check after we've locked the * relation. */ - if ((onerel->rd_rel->relkind != RELKIND_RELATION && - onerel->rd_rel->relkind != RELKIND_MATVIEW && - onerel->rd_rel->relkind != RELKIND_TOASTVALUE && - onerel->rd_rel->relkind != RELKIND_AOSEGMENTS && - onerel->rd_rel->relkind != RELKIND_AOBLOCKDIR && - onerel->rd_rel->relkind != RELKIND_AOVISIMAP) - || onerel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + if ((rel->rd_rel->relkind != RELKIND_RELATION && + rel->rd_rel->relkind != RELKIND_MATVIEW && + rel->rd_rel->relkind != RELKIND_TOASTVALUE && + rel->rd_rel->relkind != RELKIND_AOSEGMENTS && + rel->rd_rel->relkind != RELKIND_AOBLOCKDIR && + rel->rd_rel->relkind != RELKIND_AOVISIMAP) + || rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) { ereport(WARNING, (errmsg("skipping \"%s\" --- cannot vacuum non-tables, external tables, foreign tables or special system tables", - RelationGetRelationName(onerel)))); - relation_close(onerel, lmode); + RelationGetRelationName(rel)))); + relation_close(rel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); return false; @@ -2352,7 +2486,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, "compaction_before_cleanup_phase", DDLNotSpecified, "", // databaseName - RelationGetRelationName(onerel)); // tableName + RelationGetRelationName(rel)); // tableName } #endif @@ -2363,16 +2497,16 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * warning here; it would just lead to chatter during a database-wide * VACUUM.) */ - if (RELATION_IS_OTHER_TEMP(onerel)) + if (RELATION_IS_OTHER_TEMP(rel)) { - relation_close(onerel, lmode); + relation_close(rel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); return false; } - is_appendoptimized = RelationIsAppendOptimized(onerel); - is_toast = (onerel->rd_rel->relkind == RELKIND_TOASTVALUE); + is_appendoptimized = RelationIsAppendOptimized(rel); + is_toast = (rel->rd_rel->relkind == RELKIND_TOASTVALUE); if (ao_vacuum_phase && !(is_appendoptimized || is_toast)) { @@ -2387,8 +2521,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * can dispatch it. */ MemoryContext oldcontext = MemoryContextSwitchTo(vac_context); - this_rangevar = makeRangeVar(get_namespace_name(onerel->rd_rel->relnamespace), - pstrdup(RelationGetRelationName(onerel)), + this_rangevar = makeRangeVar(get_namespace_name(rel->rd_rel->relnamespace), + pstrdup(RelationGetRelationName(rel)), -1); MemoryContextSwitchTo(oldcontext); @@ -2398,7 +2532,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, * arrange to make GUC variable changes local to this command. */ GetUserIdAndSecContext(&save_userid, &save_sec_context); - SetUserIdAndSecContext(onerel->rd_rel->relowner, + SetUserIdAndSecContext(rel->rd_rel->relowner, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); @@ -2413,7 +2547,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, bool has_bitmap = false; Relation *i_rel = NULL; - vac_open_indexes(onerel, AccessShareLock, &nindexes, &i_rel); + vac_open_indexes(rel, AccessShareLock, &nindexes, &i_rel); if (i_rel != NULL) { for (i = 0; i < nindexes; i++) @@ -2428,25 +2562,25 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, vac_close_indexes(nindexes, i_rel, AccessShareLock); if (has_bitmap) - LockRelation(onerel, ShareLock); + LockRelation(rel, ShareLock); } if (!is_appendoptimized && (params->options & VACOPT_FULL)) { - int cluster_options = 0; + ClusterParams cluster_params = {0}; /* close relation before vacuuming, but hold lock until commit */ - relation_close(onerel, NoLock); - onerel = NULL; + relation_close(rel, NoLock); + rel = NULL; if ((params->options & VACOPT_VERBOSE) != 0) - cluster_options |= CLUOPT_VERBOSE; + cluster_params.options |= CLUOPT_VERBOSE; /* VACUUM FULL is now a variant of CLUSTER; see cluster.c */ - cluster_rel(relid, InvalidOid, cluster_options, true); + cluster_rel(relid, InvalidOid, &cluster_params); } - else /* Heap vacuum or AO/CO vacuum in specific phase */ - table_relation_vacuum(onerel, params, vac_strategy); + else + table_relation_vacuum(rel, params, vac_strategy); /* Roll back any GUC changes executed by index functions */ AtEOXact_GUC(false, save_nestlevel); @@ -2455,8 +2589,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, SetUserIdAndSecContext(save_userid, save_sec_context); /* all done with this class, but hold lock until commit */ - if (onerel) - relation_close(onerel, NoLock); + if (rel) + relation_close(rel, NoLock); /* * Complete the transaction and free all temporary memory used. @@ -2587,7 +2721,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, /* * Now release the session-level lock on the main table. */ - UnlockRelationIdForSession(&onerelid, lmode); + UnlockRelationIdForSession(&lockrelid, lmode); /* Report that we really did it. */ return true; @@ -2696,9 +2830,11 @@ vacuum_delay_point(void) if (msec > VacuumCostDelay * 4) msec = VacuumCostDelay * 4; - pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY); - pg_usleep((long) (msec * 1000)); - pgstat_report_wait_end(); + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + msec, + WAIT_EVENT_VACUUM_DELAY); + ResetLatch(MyLatch); VacuumCostBalance = 0; @@ -2773,13 +2909,13 @@ compute_parallel_delay(void) /* * A wrapper function of defGetBoolean(). * - * This function returns VACOPT_TERNARY_ENABLED and VACOPT_TERNARY_DISABLED - * instead of true and false. + * This function returns VACOPTVALUE_ENABLED and VACOPTVALUE_DISABLED instead + * of true and false. */ -static VacOptTernaryValue -get_vacopt_ternary_value(DefElem *def) +static VacOptValue +get_vacoptval_from_boolean(DefElem *def) { - return defGetBoolean(def) ? VACOPT_TERNARY_ENABLED : VACOPT_TERNARY_DISABLED; + return defGetBoolean(def) ? VACOPTVALUE_ENABLED : VACOPTVALUE_DISABLED; } @@ -2865,17 +3001,24 @@ vacuum_params_to_options_list(VacuumParams *params) options = lappend(options, makeDefElem("skip_locked", (Node *) makeInteger(1), -1)); optmask &= ~VACOPT_SKIP_LOCKED; } - if (optmask & VACOPT_SKIPTOAST) - { - options = lappend(options, makeDefElem("skip_toast", (Node *) makeInteger(1), -1)); - optmask &= ~VACOPT_SKIPTOAST; - } if (optmask & VACOPT_DISABLE_PAGE_SKIPPING) { options = lappend(options, makeDefElem("disable_page_skipping", (Node *) makeInteger(1), -1)); optmask &= ~VACOPT_DISABLE_PAGE_SKIPPING; } + /* + * VACOPT_PROCESS_TOAST (new in PG14) is set by default, unlike the boolean + * options above. Always dispatch its value -- not just when set -- so the + * segments process or skip TOAST tables exactly as the coordinator decided; + * omitting it would let a segment fall back to its own default (on) and + * disagree with a "VACUUM (PROCESS_TOAST off)". + */ + options = lappend(options, makeDefElem("process_toast", + (Node *) makeInteger((optmask & VACOPT_PROCESS_TOAST) ? 1 : 0), + -1)); + optmask &= ~VACOPT_PROCESS_TOAST; + if (optmask & VACUUM_AO_PHASE_MASK) { options = lappend(options, makeDefElem("ao_phase", @@ -2908,19 +3051,22 @@ vacuum_params_to_options_list(VacuumParams *params) * vacuum request to QEs as distributed transaction) for GPDB7. * See more details in the head comments of autovacuum.c. */ - if (params->truncate == VACOPT_TERNARY_DISABLED) + /* + * truncate and index_cleanup are tri-state in PG14 (VACOPTVALUE_UNSPECIFIED + * / AUTO / DISABLED / ENABLED). Only dispatch an explicit DISABLED/ENABLED + * choice; for UNSPECIFIED or AUTO (the default for a plain VACUUM) emit + * nothing and let each segment apply its own default, which resolves to the + * same behaviour. (Previously this errored out for the AUTO default.) + */ + if (params->truncate == VACOPTVALUE_DISABLED) options = lappend(options, makeDefElem("truncate", (Node *) makeInteger(0), -1)); - else if (params->truncate == VACOPT_TERNARY_ENABLED) + else if (params->truncate == VACOPTVALUE_ENABLED) options = lappend(options, makeDefElem("truncate", (Node *) makeInteger(1), -1)); - else - elog(ERROR, "unexpected VACUUM 'truncate' option '%d'", (int) params->truncate); - if (params->index_cleanup == VACOPT_TERNARY_DISABLED) + if (params->index_cleanup == VACOPTVALUE_DISABLED) options = lappend(options, makeDefElem("index_cleanup", (Node *) makeInteger(0), -1)); - else if (params->index_cleanup == VACOPT_TERNARY_ENABLED) + else if (params->index_cleanup == VACOPTVALUE_ENABLED) options = lappend(options, makeDefElem("index_cleanup", (Node *) makeInteger(1), -1)); - else - elog(ERROR, "unexpected VACUUM 'index_cleanup' option '%d'", (int) params->index_cleanup); return options; } @@ -3122,11 +3268,11 @@ vac_send_relstats_to_qd(Relation relation, } bool -vacuumStatement_IsTemporary(Relation onerel) +vacuumStatement_IsTemporary(Relation rel) { bool bTemp = false; /* MPP-7576: don't track internal namespace tables */ - switch (RelationGetNamespace(onerel)) + switch (RelationGetNamespace(rel)) { case PG_CATALOG_NAMESPACE: /* MPP-7773: don't track objects in system namespace @@ -3149,7 +3295,7 @@ vacuumStatement_IsTemporary(Relation onerel) * temporary namespace */ if (!bTemp) - bTemp = isAnyTempNamespace(RelationGetNamespace(onerel)); + bTemp = isAnyTempNamespace(RelationGetNamespace(rel)); return bTemp; } diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 8edf7955cedf..2dba6bfbff69 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -4,7 +4,7 @@ * Routines for handling specialized SET variables. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -804,6 +804,17 @@ check_session_authorization(char **newval, void **extra, GucSource source) roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval)); if (!HeapTupleIsValid(roleTup)) { + /* + * When source == PGC_S_TEST, we don't throw a hard error for a + * nonexistent user name, only a NOTICE. See comments in guc.h. + */ + if (source == PGC_S_TEST) + { + ereport(NOTICE, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", *newval))); + return true; + } GUC_check_errmsg("role \"%s\" does not exist", *newval); return false; } @@ -874,10 +885,23 @@ check_role(char **newval, void **extra, GucSource source) return false; } + /* + * When source == PGC_S_TEST, we don't throw a hard error for a + * nonexistent user name or insufficient privileges, only a NOTICE. + * See comments in guc.h. + */ + /* Look up the username */ roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(*newval)); if (!HeapTupleIsValid(roleTup)) { + if (source == PGC_S_TEST) + { + ereport(NOTICE, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("role \"%s\" does not exist", *newval))); + return true; + } GUC_check_errmsg("role \"%s\" does not exist", *newval); return false; } @@ -896,6 +920,14 @@ check_role(char **newval, void **extra, GucSource source) if (!InitializingParallelWorker && !is_member_of_role(GetSessionUserId(), roleid)) { + if (source == PGC_S_TEST) + { + ereport(NOTICE, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("permission will be denied to set role \"%s\"", + *newval))); + return true; + } GUC_check_errcode(ERRCODE_INSUFFICIENT_PRIVILEGE); GUC_check_errmsg("permission denied to set role \"%s\"", *newval); diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index da68b2d0f430..c98b2045d533 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -454,10 +454,10 @@ DefineView(ViewStmt *stmt, const char *queryString, */ if (Gp_role != GP_ROLE_EXECUTE) { - rawstmt = makeNode(RawStmt); - rawstmt->stmt = (Node *) copyObject(stmt->query); - rawstmt->stmt_location = stmt_location; - rawstmt->stmt_len = stmt_len; + rawstmt = makeNode(RawStmt); + rawstmt->stmt = stmt->query; + rawstmt->stmt_location = stmt_location; + rawstmt->stmt_len = stmt_len; viewParse = parse_analyze(rawstmt, queryString, NULL, 0, NULL); } diff --git a/src/backend/executor/Makefile b/src/backend/executor/Makefile index 442f7c621352..26fc24ee0cd4 100644 --- a/src/backend/executor/Makefile +++ b/src/backend/executor/Makefile @@ -16,6 +16,7 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) OBJS = \ execAmi.o \ + execAsync.o \ execCurrent.o \ execExpr.o \ execExprInterp.o \ @@ -61,6 +62,7 @@ OBJS = \ nodeProjectSet.o \ nodeRecursiveunion.o \ nodeResult.o \ + nodeResultCache.o \ nodeSamplescan.o \ nodeSeqscan.o \ nodeSetOp.o \ @@ -68,6 +70,7 @@ OBJS = \ nodeSubplan.o \ nodeSubqueryscan.o \ nodeTableFuncscan.o \ + nodeTidrangescan.o \ nodeTidscan.o \ nodeUnique.o \ nodeValuesscan.o \ diff --git a/src/backend/executor/README b/src/backend/executor/README index 18b2ac186595..bf5e70860d5a 100644 --- a/src/backend/executor/README +++ b/src/backend/executor/README @@ -32,10 +32,14 @@ includes a RETURNING clause, the ModifyTable node delivers the computed RETURNING rows as output, otherwise it returns nothing. Handling INSERT is pretty straightforward: the tuples returned from the plan tree below ModifyTable are inserted into the correct result relation. For UPDATE, -the plan tree returns the computed tuples to be updated, plus a "junk" -(hidden) CTID column identifying which table row is to be replaced by each -one. For DELETE, the plan tree need only deliver a CTID column, and the -ModifyTable node visits each of those rows and marks the row deleted. +the plan tree returns the new values of the updated columns, plus "junk" +(hidden) column(s) identifying which table row is to be updated. The +ModifyTable node must fetch that row to extract values for the unchanged +columns, combine the values into a new row, and apply the update. (For a +heap table, the row-identity junk column is a CTID, but other things may +be used for other table types.) For DELETE, the plan tree need only deliver +junk row-identity column(s), and the ModifyTable node visits each of those +rows and marks the row deleted. XXX a great deal more documentation needs to be written here... @@ -359,3 +363,43 @@ query returning the same set of scan tuples multiple times. Likewise, SRFs are disallowed in an UPDATE's targetlist. There, they would have the effect of the same row being updated multiple times, which is not very useful --- and updates after the first would have no effect anyway. + + +Asynchronous Execution +---------------------- + +In cases where a node is waiting on an event external to the database system, +such as a ForeignScan awaiting network I/O, it's desirable for the node to +indicate that it cannot return any tuple immediately but may be able to do so +at a later time. A process which discovers this type of situation can always +handle it simply by blocking, but this may waste time that could be spent +executing some other part of the plan tree where progress could be made +immediately. This is particularly likely to occur when the plan tree contains +an Append node. Asynchronous execution runs multiple parts of an Append node +concurrently rather than serially to improve performance. + +For asynchronous execution, an Append node must first request a tuple from an +async-capable child node using ExecAsyncRequest. Next, it must execute the +asynchronous event loop using ExecAppendAsyncEventWait. Eventually, when a +child node to which an asynchronous request has been made produces a tuple, +the Append node will receive it from the event loop via ExecAsyncResponse. In +the current implementation of asynchronous execution, the only node type that +requests tuples from an async-capable child node is an Append, while the only +node type that might be async-capable is a ForeignScan. + +Typically, the ExecAsyncResponse callback is the only one required for nodes +that wish to request tuples asynchronously. On the other hand, async-capable +nodes generally need to implement three methods: + +1. When an asynchronous request is made, the node's ExecAsyncRequest callback + will be invoked; it should use ExecAsyncRequestPending to indicate that the + request is pending for a callback described below. Alternatively, it can + instead use ExecAsyncRequestDone if a result is available immediately. + +2. When the event loop wishes to wait or poll for file descriptor events, the + node's ExecAsyncConfigureWait callback will be invoked to configure the + file descriptor event for which the node wishes to wait. + +3. When the file descriptor becomes ready, the node's ExecAsyncNotify callback + will be invoked; like #1, it should use ExecAsyncRequestPending for another + callback or ExecAsyncRequestDone to return a result immediately. diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index fc4391850fb3..cf051fd3d16b 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -3,7 +3,7 @@ * execAmi.c * miscellaneous executor access method routines * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/executor/execAmi.c @@ -47,6 +47,7 @@ #include "executor/nodeProjectSet.h" #include "executor/nodeRecursiveunion.h" #include "executor/nodeResult.h" +#include "executor/nodeResultCache.h" #include "executor/nodeSamplescan.h" #include "executor/nodeSeqscan.h" #include "executor/nodeSetOp.h" @@ -54,6 +55,7 @@ #include "executor/nodeSubplan.h" #include "executor/nodeSubqueryscan.h" #include "executor/nodeTableFuncscan.h" +#include "executor/nodeTidrangescan.h" #include "executor/nodeTidscan.h" #include "executor/nodeTupleSplit.h" #include "executor/nodeUnique.h" @@ -247,6 +249,10 @@ ExecReScan(PlanState *node) ExecReScanTidScan((TidScanState *) node); break; + case T_TidRangeScanState: + ExecReScanTidRangeScan((TidRangeScanState *) node); + break; + case T_SubqueryScanState: ExecReScanSubqueryScan((SubqueryScanState *) node); break; @@ -307,6 +313,10 @@ ExecReScan(PlanState *node) ExecReScanMaterial((MaterialState *) node); break; + case T_ResultCacheState: + ExecReScanResultCache((ResultCacheState *) node); + break; + case T_SortState: ExecReScanSort((SortState *) node); break; @@ -519,6 +529,12 @@ ExecSupportsMarkRestore(Path *pathnode) { case T_IndexScan: case T_IndexOnlyScan: + + /* + * Not all index types support mark/restore. + */ + return castNode(IndexPath, pathnode)->indexinfo->amcanmarkpos; + case T_Material: case T_Sort: case T_ShareInputScan: @@ -624,6 +640,10 @@ ExecSupportsBackwardScan(Plan *node) { ListCell *l; + /* With async, tuples may be interleaved, so can't back up. */ + if (((Append *) node)->nasyncplans > 0) + return false; + foreach(l, ((Append *) node)->appendplans) { if (!ExecSupportsBackwardScan((Plan *) lfirst(l))) @@ -635,6 +655,7 @@ ExecSupportsBackwardScan(Plan *node) case T_SeqScan: case T_TidScan: + case T_TidRangeScan: case T_FunctionScan: case T_ValuesScan: case T_CteScan: diff --git a/src/backend/executor/execAsync.c b/src/backend/executor/execAsync.c new file mode 100644 index 000000000000..94a284a31e15 --- /dev/null +++ b/src/backend/executor/execAsync.c @@ -0,0 +1,154 @@ +/*------------------------------------------------------------------------- + * + * execAsync.c + * Support routines for asynchronous execution + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/executor/execAsync.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "executor/execAsync.h" +#include "executor/executor.h" +#include "executor/nodeAppend.h" +#include "executor/nodeForeignscan.h" + +/* + * Asynchronously request a tuple from a designed async-capable node. + */ +void +ExecAsyncRequest(AsyncRequest *areq) +{ + if (areq->requestee->chgParam != NULL) /* something changed? */ + ExecReScan(areq->requestee); /* let ReScan handle this */ + + /* must provide our own instrumentation support */ + if (areq->requestee->instrument) + InstrStartNode(areq->requestee->instrument); + + switch (nodeTag(areq->requestee)) + { + case T_ForeignScanState: + ExecAsyncForeignScanRequest(areq); + break; + default: + /* If the node doesn't support async, caller messed up. */ + elog(ERROR, "unrecognized node type: %d", + (int) nodeTag(areq->requestee)); + } + + ExecAsyncResponse(areq); + + /* must provide our own instrumentation support */ + if (areq->requestee->instrument) + InstrStopNode(areq->requestee->instrument, + TupIsNull(areq->result) ? 0.0 : 1.0); +} + +/* + * Give the asynchronous node a chance to configure the file descriptor event + * for which it wishes to wait. We expect the node-type specific callback to + * make a single call of the following form: + * + * AddWaitEventToSet(set, WL_SOCKET_READABLE, fd, NULL, areq); + */ +void +ExecAsyncConfigureWait(AsyncRequest *areq) +{ + /* must provide our own instrumentation support */ + if (areq->requestee->instrument) + InstrStartNode(areq->requestee->instrument); + + switch (nodeTag(areq->requestee)) + { + case T_ForeignScanState: + ExecAsyncForeignScanConfigureWait(areq); + break; + default: + /* If the node doesn't support async, caller messed up. */ + elog(ERROR, "unrecognized node type: %d", + (int) nodeTag(areq->requestee)); + } + + /* must provide our own instrumentation support */ + if (areq->requestee->instrument) + InstrStopNode(areq->requestee->instrument, 0.0); +} + +/* + * Call the asynchronous node back when a relevant event has occurred. + */ +void +ExecAsyncNotify(AsyncRequest *areq) +{ + /* must provide our own instrumentation support */ + if (areq->requestee->instrument) + InstrStartNode(areq->requestee->instrument); + + switch (nodeTag(areq->requestee)) + { + case T_ForeignScanState: + ExecAsyncForeignScanNotify(areq); + break; + default: + /* If the node doesn't support async, caller messed up. */ + elog(ERROR, "unrecognized node type: %d", + (int) nodeTag(areq->requestee)); + } + + ExecAsyncResponse(areq); + + /* must provide our own instrumentation support */ + if (areq->requestee->instrument) + InstrStopNode(areq->requestee->instrument, + TupIsNull(areq->result) ? 0.0 : 1.0); +} + +/* + * Call the requestor back when an asynchronous node has produced a result. + */ +void +ExecAsyncResponse(AsyncRequest *areq) +{ + switch (nodeTag(areq->requestor)) + { + case T_AppendState: + ExecAsyncAppendResponse(areq); + break; + default: + /* If the node doesn't support async, caller messed up. */ + elog(ERROR, "unrecognized node type: %d", + (int) nodeTag(areq->requestor)); + } +} + +/* + * A requestee node should call this function to deliver the tuple to its + * requestor node. The requestee node can call this from its ExecAsyncRequest + * or ExecAsyncNotify callback. + */ +void +ExecAsyncRequestDone(AsyncRequest *areq, TupleTableSlot *result) +{ + areq->request_complete = true; + areq->result = result; +} + +/* + * A requestee node should call this function to indicate that it is pending + * for a callback. The requestee node can call this from its ExecAsyncRequest + * or ExecAsyncNotify callback. + */ +void +ExecAsyncRequestPending(AsyncRequest *areq) +{ + areq->callback_pending = true; + areq->request_complete = false; + areq->result = NULL; +} diff --git a/src/backend/executor/execCurrent.c b/src/backend/executor/execCurrent.c index 17507033a2b2..7f83c59c711c 100644 --- a/src/backend/executor/execCurrent.c +++ b/src/backend/executor/execCurrent.c @@ -3,7 +3,7 @@ * execCurrent.c * executor support for WHERE CURRENT OF cursor * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/executor/execCurrent.c @@ -543,6 +543,10 @@ fetch_cursor_param_value(ExprContext *econtext, int paramId) * Search through a PlanState tree for a scan node on the specified table. * Return NULL if not found or multiple candidates. * + * CAUTION: this function is not charged simply with finding some candidate + * scan, but with ensuring that that scan returned the plan tree's current + * output row. That's why we must reject multiple-match cases. + * * If a candidate is found, set *pending_rescan to true if that candidate * or any node above it has a pending rescan action, i.e. chgParam != NULL. * That indicates that we shouldn't consider the node to be positioned on a @@ -560,28 +564,55 @@ search_plan_tree(PlanState *node, Oid table_oid, return NULL; switch (nodeTag(node)) { - /* - * Relation scan nodes can all be treated alike - */ + /* + * Relation scan nodes can all be treated alike: check to see if + * they are scanning the specified table. + * + * ForeignScan and CustomScan might not have a currentRelation, in + * which case we just ignore them. (We dare not descend to any + * child plan nodes they might have, since we do not know the + * relationship of such a node's current output tuple to the + * children's current outputs.) + */ case T_SeqScanState: case T_SampleScanState: case T_IndexScanState: case T_IndexOnlyScanState: case T_BitmapHeapScanState: case T_TidScanState: + case T_TidRangeScanState: case T_ForeignScanState: case T_CustomScanState: { ScanState *sstate = (ScanState *) node; - if (RelationGetRelid(sstate->ss_currentRelation) == table_oid) + if (sstate->ss_currentRelation && + RelationGetRelid(sstate->ss_currentRelation) == table_oid) result = sstate; break; } /* - * For Append, we must look through the members; watch out for - * multiple matches (possible if it was from UNION ALL) + * For Append, we can check each input node. It is safe to + * descend to the inputs because only the input that resulted in + * the Append's current output node could be positioned on a tuple + * at all; the other inputs are either at EOF or not yet started. + * Hence, if the desired table is scanned by some + * currently-inactive input node, we will find that node but then + * our caller will realize that it didn't emit the tuple of + * interest. + * + * We do need to watch out for multiple matches (possible if + * Append was from UNION ALL rather than an inheritance tree). + * + * Note: we can NOT descend through MergeAppend similarly, since + * its inputs are likely all active, and we don't know which one + * returned the current output tuple. (Perhaps that could be + * fixed if we were to let this code know more about MergeAppend's + * internal state, but it does not seem worth the trouble. Users + * should not expect plans for ORDER BY queries to be considered + * simply-updatable, since they won't be if the sorting is + * implemented by a Sort node.) */ case T_AppendState: { @@ -603,29 +634,6 @@ search_plan_tree(PlanState *node, Oid table_oid, break; } - /* - * Similarly for MergeAppend - */ - case T_MergeAppendState: - { - MergeAppendState *mstate = (MergeAppendState *) node; - int i; - - for (i = 0; i < mstate->ms_nplans; i++) - { - ScanState *elem = search_plan_tree(mstate->mergeplans[i], - table_oid, - pending_rescan); - - if (!elem) - continue; - if (result) - return NULL; /* multiple matches */ - result = elem; - } - break; - } - /* * Result and Limit can be descended through (these are safe * because they always return their input's current row) diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index 2b6e1c856e6d..18dbaf9b1cbd 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -19,7 +19,7 @@ * and "Expression Evaluation" sections. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -40,6 +40,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "nodes/subscripting.h" #include "optimizer/optimizer.h" #include "pgstat.h" #include "utils/acl.h" @@ -109,8 +110,7 @@ static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, * the same as the per-query context of the associated ExprContext. * * Any Aggref, WindowFunc, or SubPlan nodes found in the tree are added to - * the lists of such nodes held by the parent PlanState (or more accurately, - * the AggrefExprState etc. nodes created for them are added). + * the lists of such nodes held by the parent PlanState. * * Note: there is no ExecEndExpr function; we assume that any resource * cleanup needed will be handled by just releasing the memory context @@ -487,6 +487,260 @@ ExecBuildProjectionInfo(List *targetList, return projInfo; } +/* + * ExecBuildUpdateProjection + * + * Build a ProjectionInfo node for constructing a new tuple during UPDATE. + * The projection will be executed in the given econtext and the result will + * be stored into the given tuple slot. (Caller must have ensured that tuple + * slot has a descriptor matching the target rel!) + * + * When evalTargetList is false, targetList contains the UPDATE ... SET + * expressions that have already been computed by a subplan node; the values + * from this tlist are assumed to be available in the "outer" tuple slot. + * When evalTargetList is true, targetList contains the UPDATE ... SET + * expressions that must be computed (which could contain references to + * the outer, inner, or scan tuple slots). + * + * In either case, targetColnos contains a list of the target column numbers + * corresponding to the non-resjunk entries of targetList. The tlist values + * are assigned into these columns of the result tuple slot. Target columns + * not listed in targetColnos are filled from the UPDATE's old tuple, which + * is assumed to be available in the "scan" tuple slot. + * + * targetList can also contain resjunk columns. These must be evaluated + * if evalTargetList is true, but their values are discarded. + * + * relDesc must describe the relation we intend to update. + * + * This is basically a specialized variant of ExecBuildProjectionInfo. + * However, it also performs sanity checks equivalent to ExecCheckPlanOutput. + * Since we never make a normal tlist equivalent to the whole + * tuple-to-be-assigned, there is no convenient way to apply + * ExecCheckPlanOutput, so we must do our safety checks here. + */ +ProjectionInfo * +ExecBuildUpdateProjection(List *targetList, + bool evalTargetList, + List *targetColnos, + TupleDesc relDesc, + ExprContext *econtext, + TupleTableSlot *slot, + PlanState *parent) +{ + ProjectionInfo *projInfo = makeNode(ProjectionInfo); + ExprState *state; + int nAssignableCols; + bool sawJunk; + Bitmapset *assignedCols; + LastAttnumInfo deform = {0, 0, 0}; + ExprEvalStep scratch = {0}; + int outerattnum; + ListCell *lc, + *lc2; + + projInfo->pi_exprContext = econtext; + /* We embed ExprState into ProjectionInfo instead of doing extra palloc */ + projInfo->pi_state.tag = T_ExprState; + state = &projInfo->pi_state; + if (evalTargetList) + state->expr = (Expr *) targetList; + else + state->expr = NULL; /* not used */ + state->parent = parent; + state->ext_params = NULL; + + state->resultslot = slot; + + /* + * Examine the targetList to see how many non-junk columns there are, and + * to verify that the non-junk columns come before the junk ones. + */ + nAssignableCols = 0; + sawJunk = false; + foreach(lc, targetList) + { + TargetEntry *tle = lfirst_node(TargetEntry, lc); + + if (tle->resjunk) + sawJunk = true; + else + { + if (sawJunk) + elog(ERROR, "subplan target list is out of order"); + nAssignableCols++; + } + } + + /* We should have one targetColnos entry per non-junk column */ + if (nAssignableCols != list_length(targetColnos)) + elog(ERROR, "targetColnos does not match subplan target list"); + + /* + * Build a bitmapset of the columns in targetColnos. (We could just use + * list_member_int() tests, but that risks O(N^2) behavior with many + * columns.) + */ + assignedCols = NULL; + foreach(lc, targetColnos) + { + AttrNumber targetattnum = lfirst_int(lc); + + assignedCols = bms_add_member(assignedCols, targetattnum); + } + + /* + * We need to insert EEOP_*_FETCHSOME steps to ensure the input tuples are + * sufficiently deconstructed. The scan tuple must be deconstructed at + * least as far as the last old column we need. + */ + for (int attnum = relDesc->natts; attnum > 0; attnum--) + { + Form_pg_attribute attr = TupleDescAttr(relDesc, attnum - 1); + + if (attr->attisdropped) + continue; + if (bms_is_member(attnum, assignedCols)) + continue; + deform.last_scan = attnum; + break; + } + + /* + * If we're actually evaluating the tlist, incorporate its input + * requirements too; otherwise, we'll just need to fetch the appropriate + * number of columns of the "outer" tuple. + */ + if (evalTargetList) + get_last_attnums_walker((Node *) targetList, &deform); + else + deform.last_outer = nAssignableCols; + + ExecPushExprSlots(state, &deform); + + /* + * Now generate code to evaluate the tlist's assignable expressions or + * fetch them from the outer tuple, incidentally validating that they'll + * be of the right data type. The checks above ensure that the forboth() + * will iterate over exactly the non-junk columns. + */ + outerattnum = 0; + forboth(lc, targetList, lc2, targetColnos) + { + TargetEntry *tle = lfirst_node(TargetEntry, lc); + AttrNumber targetattnum = lfirst_int(lc2); + Form_pg_attribute attr; + + Assert(!tle->resjunk); + + /* + * Apply sanity checks comparable to ExecCheckPlanOutput(). + */ + if (targetattnum <= 0 || targetattnum > relDesc->natts) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("table row type and query-specified row type do not match"), + errdetail("Query has too many columns."))); + attr = TupleDescAttr(relDesc, targetattnum - 1); + + if (attr->attisdropped) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("table row type and query-specified row type do not match"), + errdetail("Query provides a value for a dropped column at ordinal position %d.", + targetattnum))); + if (exprType((Node *) tle->expr) != attr->atttypid) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("table row type and query-specified row type do not match"), + errdetail("Table has type %s at ordinal position %d, but query expects %s.", + format_type_be(attr->atttypid), + targetattnum, + format_type_be(exprType((Node *) tle->expr))))); + + /* OK, generate code to perform the assignment. */ + if (evalTargetList) + { + /* + * We must evaluate the TLE's expression and assign it. We do not + * bother jumping through hoops for "safe" Vars like + * ExecBuildProjectionInfo does; this is a relatively less-used + * path and it doesn't seem worth expending code for that. + */ + ExecInitExprRec(tle->expr, state, + &state->resvalue, &state->resnull); + /* Needn't worry about read-only-ness here, either. */ + scratch.opcode = EEOP_ASSIGN_TMP; + scratch.d.assign_tmp.resultnum = targetattnum - 1; + ExprEvalPushStep(state, &scratch); + } + else + { + /* Just assign from the outer tuple. */ + scratch.opcode = EEOP_ASSIGN_OUTER_VAR; + scratch.d.assign_var.attnum = outerattnum; + scratch.d.assign_var.resultnum = targetattnum - 1; + ExprEvalPushStep(state, &scratch); + } + outerattnum++; + } + + /* + * If we're evaluating the tlist, must evaluate any resjunk columns too. + * (This matters for things like MULTIEXPR_SUBLINK SubPlans.) + */ + if (evalTargetList) + { + for_each_cell(lc, targetList, lc) + { + TargetEntry *tle = lfirst_node(TargetEntry, lc); + + Assert(tle->resjunk); + ExecInitExprRec(tle->expr, state, + &state->resvalue, &state->resnull); + } + } + + /* + * Now generate code to copy over any old columns that were not assigned + * to, and to ensure that dropped columns are set to NULL. + */ + for (int attnum = 1; attnum <= relDesc->natts; attnum++) + { + Form_pg_attribute attr = TupleDescAttr(relDesc, attnum - 1); + + if (attr->attisdropped) + { + /* Put a null into the ExprState's resvalue/resnull ... */ + scratch.opcode = EEOP_CONST; + scratch.resvalue = &state->resvalue; + scratch.resnull = &state->resnull; + scratch.d.constval.value = (Datum) 0; + scratch.d.constval.isnull = true; + ExprEvalPushStep(state, &scratch); + /* ... then assign it to the result slot */ + scratch.opcode = EEOP_ASSIGN_TMP; + scratch.d.assign_tmp.resultnum = attnum - 1; + ExprEvalPushStep(state, &scratch); + } + else if (!bms_is_member(attnum, assignedCols)) + { + /* Certainly the right type, so needn't check */ + scratch.opcode = EEOP_ASSIGN_SCAN_VAR; + scratch.d.assign_var.attnum = attnum - 1; + scratch.d.assign_var.resultnum = attnum - 1; + ExprEvalPushStep(state, &scratch); + } + } + + scratch.opcode = EEOP_DONE; + ExprEvalPushStep(state, &scratch); + + ExecReadyExpr(state); + + return projInfo; +} + /* * ExecPrepareExpr --- initialize for expression execution outside a normal * Plan tree context. @@ -789,18 +1043,15 @@ ExecInitExprRec(Expr *node, ExprState *state, case T_Aggref: { Aggref *aggref = (Aggref *) node; - AggrefExprState *astate = makeNode(AggrefExprState); scratch.opcode = EEOP_AGGREF; - scratch.d.aggref.astate = astate; - astate->aggref = aggref; + scratch.d.aggref.aggno = aggref->aggno; if (state->parent && IsA(state->parent, AggState)) { AggState *aggstate = (AggState *) state->parent; - aggstate->aggs = lappend(aggstate->aggs, astate); - aggstate->numaggs++; + aggstate->aggs = lappend(aggstate->aggs, aggref); } else { @@ -1020,6 +1271,8 @@ ExecInitExprRec(Expr *node, ExprState *state, FmgrInfo *finfo; FunctionCallInfo fcinfo; AclResult aclresult; + FmgrInfo *hash_finfo; + FunctionCallInfo hash_fcinfo; Assert(list_length(opexpr->args) == 2); scalararg = (Expr *) linitial(opexpr->args); @@ -1038,6 +1291,16 @@ ExecInitExprRec(Expr *node, ExprState *state, if (ExecInitScalarArrayOpFastPath(&scratch, opexpr, state, resv, resnull)) break; + if (OidIsValid(opexpr->hashfuncid)) + { + aclresult = pg_proc_aclcheck(opexpr->hashfuncid, + GetUserId(), + ACL_EXECUTE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_FUNCTION, + get_func_name(opexpr->hashfuncid)); + InvokeFunctionExecuteHook(opexpr->hashfuncid); + } /* Set up the primary fmgr lookup information */ finfo = palloc0(sizeof(FmgrInfo)); @@ -1047,26 +1310,76 @@ ExecInitExprRec(Expr *node, ExprState *state, InitFunctionCallInfoData(*fcinfo, finfo, 2, opexpr->inputcollid, NULL, NULL); - /* Evaluate scalar directly into left function argument */ - ExecInitExprRec(scalararg, state, - &fcinfo->args[0].value, &fcinfo->args[0].isnull); - /* - * Evaluate array argument into our return value. There's no - * danger in that, because the return value is guaranteed to - * be overwritten by EEOP_SCALARARRAYOP, and will not be - * passed to any other expression. + * If hashfuncid is set, we create a EEOP_HASHED_SCALARARRAYOP + * step instead of a EEOP_SCALARARRAYOP. This provides much + * faster lookup performance than the normal linear search + * when the number of items in the array is anything but very + * small. */ - ExecInitExprRec(arrayarg, state, resv, resnull); - - /* And perform the operation */ - scratch.opcode = EEOP_SCALARARRAYOP; - scratch.d.scalararrayop.element_type = InvalidOid; - scratch.d.scalararrayop.useOr = opexpr->useOr; - scratch.d.scalararrayop.finfo = finfo; - scratch.d.scalararrayop.fcinfo_data = fcinfo; - scratch.d.scalararrayop.fn_addr = finfo->fn_addr; - ExprEvalPushStep(state, &scratch); + if (OidIsValid(opexpr->hashfuncid)) + { + hash_finfo = palloc0(sizeof(FmgrInfo)); + hash_fcinfo = palloc0(SizeForFunctionCallInfo(1)); + fmgr_info(opexpr->hashfuncid, hash_finfo); + fmgr_info_set_expr((Node *) node, hash_finfo); + InitFunctionCallInfoData(*hash_fcinfo, hash_finfo, + 1, opexpr->inputcollid, NULL, + NULL); + + scratch.d.hashedscalararrayop.hash_finfo = hash_finfo; + scratch.d.hashedscalararrayop.hash_fcinfo_data = hash_fcinfo; + scratch.d.hashedscalararrayop.hash_fn_addr = hash_finfo->fn_addr; + + /* Evaluate scalar directly into left function argument */ + ExecInitExprRec(scalararg, state, + &fcinfo->args[0].value, &fcinfo->args[0].isnull); + + /* + * Evaluate array argument into our return value. There's + * no danger in that, because the return value is + * guaranteed to be overwritten by + * EEOP_HASHED_SCALARARRAYOP, and will not be passed to + * any other expression. + */ + ExecInitExprRec(arrayarg, state, resv, resnull); + + /* And perform the operation */ + scratch.opcode = EEOP_HASHED_SCALARARRAYOP; + scratch.d.hashedscalararrayop.finfo = finfo; + scratch.d.hashedscalararrayop.fcinfo_data = fcinfo; + scratch.d.hashedscalararrayop.fn_addr = finfo->fn_addr; + + scratch.d.hashedscalararrayop.hash_finfo = hash_finfo; + scratch.d.hashedscalararrayop.hash_fcinfo_data = hash_fcinfo; + scratch.d.hashedscalararrayop.hash_fn_addr = hash_finfo->fn_addr; + + ExprEvalPushStep(state, &scratch); + } + else + { + /* Evaluate scalar directly into left function argument */ + ExecInitExprRec(scalararg, state, + &fcinfo->args[0].value, + &fcinfo->args[0].isnull); + + /* + * Evaluate array argument into our return value. There's + * no danger in that, because the return value is + * guaranteed to be overwritten by EEOP_SCALARARRAYOP, and + * will not be passed to any other expression. + */ + ExecInitExprRec(arrayarg, state, resv, resnull); + + /* And perform the operation */ + scratch.opcode = EEOP_SCALARARRAYOP; + scratch.d.scalararrayop.element_type = InvalidOid; + scratch.d.scalararrayop.useOr = opexpr->useOr; + scratch.d.scalararrayop.finfo = finfo; + scratch.d.scalararrayop.fcinfo_data = fcinfo; + scratch.d.scalararrayop.fn_addr = finfo->fn_addr; + ExprEvalPushStep(state, &scratch); + } break; } @@ -1177,23 +1490,6 @@ ExecInitExprRec(Expr *node, ExprState *state, break; } - case T_AlternativeSubPlan: - { - AlternativeSubPlan *asplan = (AlternativeSubPlan *) node; - AlternativeSubPlanState *asstate; - - if (!state->parent) - elog(ERROR, "AlternativeSubPlan found with no parent plan"); - - asstate = ExecInitAlternativeSubPlan(asplan, state->parent); - - scratch.opcode = EEOP_ALTERNATIVE_SUBPLAN; - scratch.d.alternative_subplan.asstate = asstate; - - ExprEvalPushStep(state, &scratch); - break; - } - case T_FieldSelect: { FieldSelect *fselect = (FieldSelect *) node; @@ -1205,7 +1501,7 @@ ExecInitExprRec(Expr *node, ExprState *state, scratch.opcode = EEOP_FIELDSELECT; scratch.d.fieldselect.fieldnum = fselect->fieldnum; scratch.d.fieldselect.resulttype = fselect->resulttype; - scratch.d.fieldselect.argdesc = NULL; + scratch.d.fieldselect.rowcache.cacheptr = NULL; ExprEvalPushStep(state, &scratch); break; @@ -1215,7 +1511,7 @@ ExecInitExprRec(Expr *node, ExprState *state, { FieldStore *fstore = (FieldStore *) node; TupleDesc tupDesc; - TupleDesc *descp; + ExprEvalRowtypeCache *rowcachep; Datum *values; bool *nulls; int ncolumns; @@ -1231,9 +1527,9 @@ ExecInitExprRec(Expr *node, ExprState *state, values = (Datum *) palloc(sizeof(Datum) * ncolumns); nulls = (bool *) palloc(sizeof(bool) * ncolumns); - /* create workspace for runtime tupdesc cache */ - descp = (TupleDesc *) palloc(sizeof(TupleDesc)); - *descp = NULL; + /* create shared composite-type-lookup cache struct */ + rowcachep = palloc(sizeof(ExprEvalRowtypeCache)); + rowcachep->cacheptr = NULL; /* emit code to evaluate the composite input value */ ExecInitExprRec(fstore->arg, state, resv, resnull); @@ -1241,7 +1537,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* next, deform the input tuple into our workspace */ scratch.opcode = EEOP_FIELDSTORE_DEFORM; scratch.d.fieldstore.fstore = fstore; - scratch.d.fieldstore.argdesc = descp; + scratch.d.fieldstore.rowcache = rowcachep; scratch.d.fieldstore.values = values; scratch.d.fieldstore.nulls = nulls; scratch.d.fieldstore.ncolumns = ncolumns; @@ -1299,7 +1595,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* finally, form result tuple */ scratch.opcode = EEOP_FIELDSTORE_FORM; scratch.d.fieldstore.fstore = fstore; - scratch.d.fieldstore.argdesc = descp; + scratch.d.fieldstore.rowcache = rowcachep; scratch.d.fieldstore.values = values; scratch.d.fieldstore.nulls = nulls; scratch.d.fieldstore.ncolumns = ncolumns; @@ -1445,17 +1741,24 @@ ExecInitExprRec(Expr *node, ExprState *state, case T_ConvertRowtypeExpr: { ConvertRowtypeExpr *convert = (ConvertRowtypeExpr *) node; + ExprEvalRowtypeCache *rowcachep; + + /* cache structs must be out-of-line for space reasons */ + rowcachep = palloc(2 * sizeof(ExprEvalRowtypeCache)); + rowcachep[0].cacheptr = NULL; + rowcachep[1].cacheptr = NULL; /* evaluate argument into step's result area */ ExecInitExprRec(convert->arg, state, resv, resnull); /* and push conversion step */ scratch.opcode = EEOP_CONVERT_ROWTYPE; - scratch.d.convert_rowtype.convert = convert; - scratch.d.convert_rowtype.indesc = NULL; - scratch.d.convert_rowtype.outdesc = NULL; + scratch.d.convert_rowtype.inputtype = + exprType((Node *) convert->arg); + scratch.d.convert_rowtype.outputtype = convert->resulttype; + scratch.d.convert_rowtype.incache = &rowcachep[0]; + scratch.d.convert_rowtype.outcache = &rowcachep[1]; scratch.d.convert_rowtype.map = NULL; - scratch.d.convert_rowtype.initialized = false; ExprEvalPushStep(state, &scratch); break; @@ -2080,7 +2383,7 @@ ExecInitExprRec(Expr *node, ExprState *state, (int) ntest->nulltesttype); } /* initialize cache in case it's a row test */ - scratch.d.nulltest_row.argdesc = NULL; + scratch.d.nulltest_row.rowcache.cacheptr = NULL; /* first evaluate argument into result variable */ ExecInitExprRec(ntest->arg, state, @@ -2617,19 +2920,59 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, ExprState *state, Datum *resv, bool *resnull) { bool isAssignment = (sbsref->refassgnexpr != NULL); - SubscriptingRefState *sbsrefstate = palloc0(sizeof(SubscriptingRefState)); + int nupper = list_length(sbsref->refupperindexpr); + int nlower = list_length(sbsref->reflowerindexpr); + const SubscriptRoutines *sbsroutines; + SubscriptingRefState *sbsrefstate; + SubscriptExecSteps methods; + char *ptr; List *adjust_jumps = NIL; ListCell *lc; int i; + /* Look up the subscripting support methods */ + sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, NULL); + if (!sbsroutines) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cannot subscript type %s because it does not support subscripting", + format_type_be(sbsref->refcontainertype)), + state->parent ? + executor_errposition(state->parent->state, + exprLocation((Node *) sbsref)) : 0)); + + /* Allocate sbsrefstate, with enough space for per-subscript arrays too */ + sbsrefstate = palloc0(MAXALIGN(sizeof(SubscriptingRefState)) + + (nupper + nlower) * (sizeof(Datum) + + 2 * sizeof(bool))); + /* Fill constant fields of SubscriptingRefState */ sbsrefstate->isassignment = isAssignment; - sbsrefstate->refelemtype = sbsref->refelemtype; - sbsrefstate->refattrlength = get_typlen(sbsref->refcontainertype); - get_typlenbyvalalign(sbsref->refelemtype, - &sbsrefstate->refelemlength, - &sbsrefstate->refelembyval, - &sbsrefstate->refelemalign); + sbsrefstate->numupper = nupper; + sbsrefstate->numlower = nlower; + /* Set up per-subscript arrays */ + ptr = ((char *) sbsrefstate) + MAXALIGN(sizeof(SubscriptingRefState)); + sbsrefstate->upperindex = (Datum *) ptr; + ptr += nupper * sizeof(Datum); + sbsrefstate->lowerindex = (Datum *) ptr; + ptr += nlower * sizeof(Datum); + sbsrefstate->upperprovided = (bool *) ptr; + ptr += nupper * sizeof(bool); + sbsrefstate->lowerprovided = (bool *) ptr; + ptr += nlower * sizeof(bool); + sbsrefstate->upperindexnull = (bool *) ptr; + ptr += nupper * sizeof(bool); + sbsrefstate->lowerindexnull = (bool *) ptr; + /* ptr += nlower * sizeof(bool); */ + + /* + * Let the container-type-specific code have a chance. It must fill the + * "methods" struct with function pointers for us to possibly use in + * execution steps below; and it can optionally set up some data pointed + * to by the workspace field. + */ + memset(&methods, 0, sizeof(methods)); + sbsroutines->exec_setup(sbsref, sbsrefstate, &methods); /* * Evaluate array input. It's safe to do so into resv/resnull, because we @@ -2640,11 +2983,11 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, ExecInitExprRec(sbsref->refexpr, state, resv, resnull); /* - * If refexpr yields NULL, and it's a fetch, then result is NULL. We can - * implement this with just JUMP_IF_NULL, since we evaluated the array - * into the desired target location. + * If refexpr yields NULL, and the operation should be strict, then result + * is NULL. We can implement this with just JUMP_IF_NULL, since we + * evaluated the array into the desired target location. */ - if (!isAssignment) + if (!isAssignment && sbsroutines->fetch_strict) { scratch->opcode = EEOP_JUMP_IF_NULL; scratch->d.jump.jumpdone = -1; /* adjust later */ @@ -2653,19 +2996,6 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, state->steps_len - 1); } - /* Verify subscript list lengths are within limit */ - if (list_length(sbsref->refupperindexpr) > MAXDIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", - list_length(sbsref->refupperindexpr), MAXDIM))); - - if (list_length(sbsref->reflowerindexpr) > MAXDIM) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", - list_length(sbsref->reflowerindexpr), MAXDIM))); - /* Evaluate upper subscripts */ i = 0; foreach(lc, sbsref->refupperindexpr) @@ -2676,28 +3006,18 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, if (!e) { sbsrefstate->upperprovided[i] = false; - i++; - continue; + sbsrefstate->upperindexnull[i] = true; + } + else + { + sbsrefstate->upperprovided[i] = true; + /* Each subscript is evaluated into appropriate array entry */ + ExecInitExprRec(e, state, + &sbsrefstate->upperindex[i], + &sbsrefstate->upperindexnull[i]); } - - sbsrefstate->upperprovided[i] = true; - - /* Each subscript is evaluated into subscriptvalue/subscriptnull */ - ExecInitExprRec(e, state, - &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull); - - /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */ - scratch->opcode = EEOP_SBSREF_SUBSCRIPT; - scratch->d.sbsref_subscript.state = sbsrefstate; - scratch->d.sbsref_subscript.off = i; - scratch->d.sbsref_subscript.isupper = true; - scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */ - ExprEvalPushStep(state, scratch); - adjust_jumps = lappend_int(adjust_jumps, - state->steps_len - 1); i++; } - sbsrefstate->numupper = i; /* Evaluate lower subscripts similarly */ i = 0; @@ -2709,39 +3029,43 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, if (!e) { sbsrefstate->lowerprovided[i] = false; - i++; - continue; + sbsrefstate->lowerindexnull[i] = true; } + else + { + sbsrefstate->lowerprovided[i] = true; + /* Each subscript is evaluated into appropriate array entry */ + ExecInitExprRec(e, state, + &sbsrefstate->lowerindex[i], + &sbsrefstate->lowerindexnull[i]); + } + i++; + } - sbsrefstate->lowerprovided[i] = true; - - /* Each subscript is evaluated into subscriptvalue/subscriptnull */ - ExecInitExprRec(e, state, - &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull); - - /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */ - scratch->opcode = EEOP_SBSREF_SUBSCRIPT; + /* SBSREF_SUBSCRIPTS checks and converts all the subscripts at once */ + if (methods.sbs_check_subscripts) + { + scratch->opcode = EEOP_SBSREF_SUBSCRIPTS; + scratch->d.sbsref_subscript.subscriptfunc = methods.sbs_check_subscripts; scratch->d.sbsref_subscript.state = sbsrefstate; - scratch->d.sbsref_subscript.off = i; - scratch->d.sbsref_subscript.isupper = false; scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */ ExprEvalPushStep(state, scratch); adjust_jumps = lappend_int(adjust_jumps, state->steps_len - 1); - i++; } - sbsrefstate->numlower = i; - - /* Should be impossible if parser is sane, but check anyway: */ - if (sbsrefstate->numlower != 0 && - sbsrefstate->numupper != sbsrefstate->numlower) - elog(ERROR, "upper and lower index lists are not same length"); if (isAssignment) { Datum *save_innermost_caseval; bool *save_innermost_casenull; + /* Check for unimplemented methods */ + if (!methods.sbs_assign) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("type %s does not support subscripted assignment", + format_type_be(sbsref->refcontainertype)))); + /* * We might have a nested-assignment situation, in which the * refassgnexpr is itself a FieldStore or SubscriptingRef that needs @@ -2758,7 +3082,13 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, */ if (isAssignmentIndirectionExpr(sbsref->refassgnexpr)) { + if (!methods.sbs_fetch_old) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("type %s does not support subscripted assignment", + format_type_be(sbsref->refcontainertype)))); scratch->opcode = EEOP_SBSREF_OLD; + scratch->d.sbsref.subscriptfunc = methods.sbs_fetch_old; scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); } @@ -2778,17 +3108,17 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, /* and perform the assignment */ scratch->opcode = EEOP_SBSREF_ASSIGN; + scratch->d.sbsref.subscriptfunc = methods.sbs_assign; scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); - } else { /* array fetch is much simpler */ scratch->opcode = EEOP_SBSREF_FETCH; + scratch->d.sbsref.subscriptfunc = methods.sbs_fetch; scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); - } /* adjust jump targets */ @@ -2796,7 +3126,7 @@ ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, { ExprEvalStep *as = &state->steps[lfirst_int(lc)]; - if (as->opcode == EEOP_SBSREF_SUBSCRIPT) + if (as->opcode == EEOP_SBSREF_SUBSCRIPTS) { Assert(as->d.sbsref_subscript.jumpdone == -1); as->d.sbsref_subscript.jumpdone = state->steps_len; @@ -3373,8 +3703,10 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, scratch.resnull = &trans_fcinfo->args[argno + 1].isnull; ExprEvalPushStep(state, &scratch); - adjust_bailout = lappend_int(adjust_bailout, - state->steps_len - 1); + /* don't add an adjustment unless the function is strict */ + if (pertrans->deserialfn.fn_strict) + adjust_bailout = lappend_int(adjust_bailout, + state->steps_len - 1); /* restore normal settings of scratch fields */ scratch.resvalue = &state->resvalue; @@ -3596,7 +3928,7 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate, * * For ordered aggregates: * - * Only need to choose between the faster path for a single orderred + * Only need to choose between the faster path for a single ordered * column, and the one between multiple columns. Checking strictness etc * is done when finalizing the aggregate. See * process_ordered_aggregate_{single, multi} and @@ -3942,3 +4274,137 @@ ExecEvalFunctionArgToConst(FuncExpr *fexpr, int argno, bool *isnull) return result->constvalue; } + +/* + * Build equality expression that can be evaluated using ExecQual(), returning + * true if the expression context's inner/outer tuples are equal. Datums in + * the inner/outer slots are assumed to be in the same order and quantity as + * the 'eqfunctions' parameter. NULLs are treated as equal. + * + * desc: tuple descriptor of the to-be-compared tuples + * lops: the slot ops for the inner tuple slots + * rops: the slot ops for the outer tuple slots + * eqFunctions: array of function oids of the equality functions to use + * this must be the same length as the 'param_exprs' list. + * collations: collation Oids to use for equality comparison. Must be the + * same length as the 'param_exprs' list. + * parent: parent executor node + */ +ExprState * +ExecBuildParamSetEqual(TupleDesc desc, + const TupleTableSlotOps *lops, + const TupleTableSlotOps *rops, + const Oid *eqfunctions, + const Oid *collations, + const List *param_exprs, + PlanState *parent) +{ + ExprState *state = makeNode(ExprState); + ExprEvalStep scratch = {0}; + int maxatt = list_length(param_exprs); + List *adjust_jumps = NIL; + ListCell *lc; + + state->expr = NULL; + state->flags = EEO_FLAG_IS_QUAL; + state->parent = parent; + + scratch.resvalue = &state->resvalue; + scratch.resnull = &state->resnull; + + /* push deform steps */ + scratch.opcode = EEOP_INNER_FETCHSOME; + scratch.d.fetch.last_var = maxatt; + scratch.d.fetch.fixed = false; + scratch.d.fetch.known_desc = desc; + scratch.d.fetch.kind = lops; + if (ExecComputeSlotInfo(state, &scratch)) + ExprEvalPushStep(state, &scratch); + + scratch.opcode = EEOP_OUTER_FETCHSOME; + scratch.d.fetch.last_var = maxatt; + scratch.d.fetch.fixed = false; + scratch.d.fetch.known_desc = desc; + scratch.d.fetch.kind = rops; + if (ExecComputeSlotInfo(state, &scratch)) + ExprEvalPushStep(state, &scratch); + + for (int attno = 0; attno < maxatt; attno++) + { + Form_pg_attribute att = TupleDescAttr(desc, attno); + Oid foid = eqfunctions[attno]; + Oid collid = collations[attno]; + FmgrInfo *finfo; + FunctionCallInfo fcinfo; + AclResult aclresult; + + /* Check permission to call function */ + aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid)); + + InvokeFunctionExecuteHook(foid); + + /* Set up the primary fmgr lookup information */ + finfo = palloc0(sizeof(FmgrInfo)); + fcinfo = palloc0(SizeForFunctionCallInfo(2)); + fmgr_info(foid, finfo); + fmgr_info_set_expr(NULL, finfo); + InitFunctionCallInfoData(*fcinfo, finfo, 2, + collid, NULL, NULL); + + /* left arg */ + scratch.opcode = EEOP_INNER_VAR; + scratch.d.var.attnum = attno; + scratch.d.var.vartype = att->atttypid; + scratch.resvalue = &fcinfo->args[0].value; + scratch.resnull = &fcinfo->args[0].isnull; + ExprEvalPushStep(state, &scratch); + + /* right arg */ + scratch.opcode = EEOP_OUTER_VAR; + scratch.d.var.attnum = attno; + scratch.d.var.vartype = att->atttypid; + scratch.resvalue = &fcinfo->args[1].value; + scratch.resnull = &fcinfo->args[1].isnull; + ExprEvalPushStep(state, &scratch); + + /* evaluate distinctness */ + scratch.opcode = EEOP_NOT_DISTINCT; + scratch.d.func.finfo = finfo; + scratch.d.func.fcinfo_data = fcinfo; + scratch.d.func.fn_addr = finfo->fn_addr; + scratch.d.func.nargs = 2; + scratch.resvalue = &state->resvalue; + scratch.resnull = &state->resnull; + ExprEvalPushStep(state, &scratch); + + /* then emit EEOP_QUAL to detect if result is false (or null) */ + scratch.opcode = EEOP_QUAL; + scratch.d.qualexpr.jumpdone = -1; + scratch.resvalue = &state->resvalue; + scratch.resnull = &state->resnull; + ExprEvalPushStep(state, &scratch); + adjust_jumps = lappend_int(adjust_jumps, + state->steps_len - 1); + } + + /* adjust jump targets */ + foreach(lc, adjust_jumps) + { + ExprEvalStep *as = &state->steps[lfirst_int(lc)]; + + Assert(as->opcode == EEOP_QUAL); + Assert(as->d.qualexpr.jumpdone == -1); + as->d.qualexpr.jumpdone = state->steps_len; + } + + scratch.resvalue = NULL; + scratch.resnull = NULL; + scratch.opcode = EEOP_DONE; + ExprEvalPushStep(state, &scratch); + + ExecReadyExpr(state); + + return state; +} diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 096e3001a2c9..5c478bffd115 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -46,7 +46,7 @@ * exported rather than being "static" in this file.) * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -148,8 +148,8 @@ static void ExecInitInterpreter(void); static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype); static void CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot); static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, - TupleDesc *cache_field, ExprContext *econtext); -static void ShutdownTupleDescRef(Datum arg); + ExprEvalRowtypeCache *rowcache, + bool *changed); static void ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op, ExprContext *econtext, bool checkisnull); @@ -181,6 +181,51 @@ static pg_attribute_always_inline void ExecAggPlainTransByRef(AggState *aggstate ExprContext *aggcontext, int setno); +/* + * ScalarArrayOpExprHashEntry + * Hash table entry type used during EEOP_HASHED_SCALARARRAYOP + */ +typedef struct ScalarArrayOpExprHashEntry +{ + Datum key; + uint32 status; /* hash status */ + uint32 hash; /* hash value (cached) */ +} ScalarArrayOpExprHashEntry; + +#define SH_PREFIX saophash +#define SH_ELEMENT_TYPE ScalarArrayOpExprHashEntry +#define SH_KEY_TYPE Datum +#define SH_SCOPE static inline +#define SH_DECLARE +#include "lib/simplehash.h" + +static bool saop_hash_element_match(struct saophash_hash *tb, Datum key1, + Datum key2); +static uint32 saop_element_hash(struct saophash_hash *tb, Datum key); + +/* + * ScalarArrayOpExprHashTable + * Hash table for EEOP_HASHED_SCALARARRAYOP + */ +typedef struct ScalarArrayOpExprHashTable +{ + saophash_hash *hashtab; /* underlying hash table */ + struct ExprEvalStep *op; +} ScalarArrayOpExprHashTable; + +/* Define parameters for ScalarArrayOpExpr hash table code generation. */ +#define SH_PREFIX saophash +#define SH_ELEMENT_TYPE ScalarArrayOpExprHashEntry +#define SH_KEY_TYPE Datum +#define SH_KEY key +#define SH_HASH_KEY(tb, key) saop_element_hash(tb, key) +#define SH_EQUAL(tb, a, b) saop_hash_element_match(tb, a, b) +#define SH_SCOPE static inline +#define SH_STORE_HASH +#define SH_GET_HASH(tb, a) a->hash +#define SH_DEFINE +#include "lib/simplehash.h" + /* * Prepare ExprState for interpreted execution. */ @@ -420,7 +465,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_FIELDSELECT, &&CASE_EEOP_FIELDSTORE_DEFORM, &&CASE_EEOP_FIELDSTORE_FORM, - &&CASE_EEOP_SBSREF_SUBSCRIPT, + &&CASE_EEOP_SBSREF_SUBSCRIPTS, &&CASE_EEOP_SBSREF_OLD, &&CASE_EEOP_SBSREF_ASSIGN, &&CASE_EEOP_SBSREF_FETCH, @@ -431,6 +476,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_SCALARARRAYOP, &&CASE_EEOP_SCALARARRAYOP_FAST_INT, &&CASE_EEOP_SCALARARRAYOP_FAST_STR, + &&CASE_EEOP_HASHED_SCALARARRAYOP, &&CASE_EEOP_XMLEXPR, &&CASE_EEOP_AGGREF, &&CASE_EEOP_GROUPING_FUNC, @@ -440,7 +486,6 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_ROWIDEXPR, &&CASE_EEOP_WINDOW_FUNC, &&CASE_EEOP_SUBPLAN, - &&CASE_EEOP_ALTERNATIVE_SUBPLAN, &&CASE_EEOP_AGG_STRICT_DESERIALIZE, &&CASE_EEOP_AGG_DESERIALIZE, &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS, @@ -590,6 +635,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) * care of at compilation time. But see EEOP_INNER_VAR comments. */ Assert(attnum >= 0 && attnum < innerslot->tts_nvalid); + Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); resultslot->tts_values[resultnum] = innerslot->tts_values[attnum]; resultslot->tts_isnull[resultnum] = innerslot->tts_isnull[attnum]; @@ -606,6 +652,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) * care of at compilation time. But see EEOP_INNER_VAR comments. */ Assert(attnum >= 0 && attnum < outerslot->tts_nvalid); + Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); resultslot->tts_values[resultnum] = outerslot->tts_values[attnum]; resultslot->tts_isnull[resultnum] = outerslot->tts_isnull[attnum]; @@ -622,6 +669,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) * care of at compilation time. But see EEOP_INNER_VAR comments. */ Assert(attnum >= 0 && attnum < scanslot->tts_nvalid); + Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); resultslot->tts_values[resultnum] = scanslot->tts_values[attnum]; resultslot->tts_isnull[resultnum] = scanslot->tts_isnull[attnum]; @@ -632,6 +680,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) { int resultnum = op->d.assign_tmp.resultnum; + Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); resultslot->tts_values[resultnum] = state->resvalue; resultslot->tts_isnull[resultnum] = state->resnull; @@ -642,6 +691,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) { int resultnum = op->d.assign_tmp.resultnum; + Assert(resultnum >= 0 && resultnum < resultslot->tts_tupleDescriptor->natts); resultslot->tts_isnull[resultnum] = state->resnull; if (!resultslot->tts_isnull[resultnum]) resultslot->tts_values[resultnum] = @@ -1406,12 +1456,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } - EEO_CASE(EEOP_SBSREF_SUBSCRIPT) + EEO_CASE(EEOP_SBSREF_SUBSCRIPTS) { - /* Process an array subscript */ - - /* too complex for an inline implementation */ - if (ExecEvalSubscriptingRef(state, op)) + /* Precheck SubscriptingRef subscript(s) */ + if (op->d.sbsref_subscript.subscriptfunc(state, op, econtext)) { EEO_NEXT(); } @@ -1423,37 +1471,11 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) } EEO_CASE(EEOP_SBSREF_OLD) + EEO_CASE(EEOP_SBSREF_ASSIGN) + EEO_CASE(EEOP_SBSREF_FETCH) { - /* - * Fetch the old value in an sbsref assignment, in case it's - * referenced (via a CaseTestExpr) inside the assignment - * expression. - */ - - /* too complex for an inline implementation */ - ExecEvalSubscriptingRefOld(state, op); - - EEO_NEXT(); - } - - /* - * Perform SubscriptingRef assignment - */ - EEO_CASE(EEOP_SBSREF_ASSIGN) - { - /* too complex for an inline implementation */ - ExecEvalSubscriptingRefAssign(state, op); - - EEO_NEXT(); - } - - /* - * Fetch subset of an array. - */ - EEO_CASE(EEOP_SBSREF_FETCH) - { - /* too complex for an inline implementation */ - ExecEvalSubscriptingRefFetch(state, op); + /* Perform a SubscriptingRef fetch or assignment */ + op->d.sbsref.subscriptfunc(state, op, econtext); EEO_NEXT(); } @@ -1490,6 +1512,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } + EEO_CASE(EEOP_HASHED_SCALARARRAYOP) + { + /* too complex for an inline implementation */ + ExecEvalHashedScalarArrayOp(state, op, econtext); + + EEO_NEXT(); + } + EEO_CASE(EEOP_DOMAIN_NOTNULL) { /* too complex for an inline implementation */ @@ -1520,12 +1550,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) * Returns a Datum whose value is the precomputed aggregate value * found in the given expression context. */ - AggrefExprState *aggref = op->d.aggref.astate; + int aggno = op->d.aggref.aggno; Assert(econtext->ecxt_aggvalues != NULL); - *op->resvalue = econtext->ecxt_aggvalues[aggref->aggno]; - *op->resnull = econtext->ecxt_aggnulls[aggref->aggno]; + *op->resvalue = econtext->ecxt_aggvalues[aggno]; + *op->resnull = econtext->ecxt_aggnulls[aggno]; EEO_NEXT(); } @@ -1601,14 +1631,6 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } - EEO_CASE(EEOP_ALTERNATIVE_SUBPLAN) - { - /* too complex for an inline implementation */ - ExecEvalAlternativeSubPlan(state, op, econtext); - - EEO_NEXT(); - } - /* evaluate a strict aggregate deserialization function */ EEO_CASE(EEOP_AGG_STRICT_DESERIALIZE) { @@ -2016,56 +2038,78 @@ CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot) * get_cached_rowtype: utility function to lookup a rowtype tupdesc * * type_id, typmod: identity of the rowtype - * cache_field: where to cache the TupleDesc pointer in expression state node - * (field must be initialized to NULL) - * econtext: expression context we are executing in + * rowcache: space for caching identity info + * (rowcache->cacheptr must be initialized to NULL) + * changed: if not NULL, *changed is set to true on any update * - * NOTE: because the shutdown callback will be called during plan rescan, - * must be prepared to re-do this during any node execution; cannot call - * just once during expression initialization. + * The returned TupleDesc is not guaranteed pinned; caller must pin it + * to use it across any operation that might incur cache invalidation. + * (The TupleDesc is always refcounted, so just use IncrTupleDescRefCount.) + * + * NOTE: because composite types can change contents, we must be prepared + * to re-do this during any node execution; cannot call just once during + * expression initialization. */ static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, - TupleDesc *cache_field, ExprContext *econtext) + ExprEvalRowtypeCache *rowcache, + bool *changed) { - TupleDesc tupDesc = *cache_field; - - /* Do lookup if no cached value or if requested type changed */ - if (tupDesc == NULL || - type_id != tupDesc->tdtypeid || - typmod != tupDesc->tdtypmod) + if (type_id != RECORDOID) { - tupDesc = lookup_rowtype_tupdesc(type_id, typmod); + /* + * It's a named composite type, so use the regular typcache. Do a + * lookup first time through, or if the composite type changed. Note: + * "tupdesc_id == 0" may look redundant, but it protects against the + * admittedly-theoretical possibility that type_id was RECORDOID the + * last time through, so that the cacheptr isn't TypeCacheEntry *. + */ + TypeCacheEntry *typentry = (TypeCacheEntry *) rowcache->cacheptr; - if (*cache_field) - { - /* Release old tupdesc; but callback is already registered */ - ReleaseTupleDesc(*cache_field); - } - else + if (unlikely(typentry == NULL || + rowcache->tupdesc_id == 0 || + typentry->tupDesc_identifier != rowcache->tupdesc_id)) { - /* Need to register shutdown callback to release tupdesc */ - RegisterExprContextCallback(econtext, - ShutdownTupleDescRef, - PointerGetDatum(cache_field)); - } - *cache_field = tupDesc; + typentry = lookup_type_cache(type_id, TYPECACHE_TUPDESC); + if (typentry->tupDesc == NULL) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("type %s is not composite", + format_type_be(type_id)))); + rowcache->cacheptr = (void *) typentry; + rowcache->tupdesc_id = typentry->tupDesc_identifier; + if (changed) + *changed = true; + } + return typentry->tupDesc; + } + else + { + /* + * A RECORD type, once registered, doesn't change for the life of the + * backend. So we don't need a typcache entry as such, which is good + * because there isn't one. It's possible that the caller is asking + * about a different type than before, though. + */ + TupleDesc tupDesc = (TupleDesc) rowcache->cacheptr; + + if (unlikely(tupDesc == NULL || + rowcache->tupdesc_id != 0 || + type_id != tupDesc->tdtypeid || + typmod != tupDesc->tdtypmod)) + { + tupDesc = lookup_rowtype_tupdesc(type_id, typmod); + /* Drop pin acquired by lookup_rowtype_tupdesc */ + ReleaseTupleDesc(tupDesc); + rowcache->cacheptr = (void *) tupDesc; + rowcache->tupdesc_id = 0; /* not a valid value for non-RECORD */ + if (changed) + *changed = true; + } + return tupDesc; } - return tupDesc; } -/* - * Callback function to release a tupdesc refcount at econtext shutdown - */ -static void -ShutdownTupleDescRef(Datum arg) -{ - TupleDesc *cache_field = (TupleDesc *) DatumGetPointer(arg); - - if (*cache_field) - ReleaseTupleDesc(*cache_field); - *cache_field = NULL; -} /* * Fast-path functions, for very simple expressions @@ -2126,8 +2170,10 @@ ExecJustAssignVarImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull) * * Since we use slot_getattr(), we don't need to implement the FETCHSOME * step explicitly, and we also needn't Assert that the attnum is in range - * --- slot_getattr() will take care of any problems. + * --- slot_getattr() will take care of any problems. Nonetheless, check + * that resultnum is in range. */ + Assert(resultnum >= 0 && resultnum < outslot->tts_tupleDescriptor->natts); outslot->tts_values[resultnum] = slot_getattr(inslot, attnum, &outslot->tts_isnull[resultnum]); return 0; @@ -2259,6 +2305,7 @@ ExecJustAssignVarVirtImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull Assert(TTS_IS_VIRTUAL(inslot)); Assert(TTS_FIXED(inslot)); Assert(attnum >= 0 && attnum < inslot->tts_nvalid); + Assert(resultnum >= 0 && resultnum < outslot->tts_tupleDescriptor->natts); outslot->tts_values[resultnum] = inslot->tts_values[attnum]; outslot->tts_isnull[resultnum] = inslot->tts_isnull[attnum]; @@ -2686,8 +2733,7 @@ ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op, /* Lookup tupdesc if first time through or if type changes */ tupDesc = get_cached_rowtype(tupType, tupTypmod, - &op->d.nulltest_row.argdesc, - econtext); + &op->d.nulltest_row.rowcache, NULL); /* * heap_attisnull needs a HeapTuple not a bare HeapTupleHeader. @@ -2893,6 +2939,10 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op) lbs[i] = elem_lbs[i - 1]; } + /* check for subscript overflow */ + (void) ArrayGetNItems(ndims, dims); + ArrayCheckBounds(ndims, dims, lbs); + if (havenulls) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems); @@ -3120,8 +3170,7 @@ ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, ExprContext *econtext) /* Lookup tupdesc if first time through or if type changes */ tupDesc = get_cached_rowtype(tupType, tupTypmod, - &op->d.fieldselect.argdesc, - econtext); + &op->d.fieldselect.rowcache, NULL); /* * Find field's attr record. Note we don't support system columns @@ -3179,9 +3228,9 @@ ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, ExprContext *econte { TupleDesc tupDesc; - /* Lookup tupdesc if first time through or after rescan */ + /* Lookup tupdesc if first time through or if type changes */ tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1, - op->d.fieldstore.argdesc, econtext); + op->d.fieldstore.rowcache, NULL); /* Check that current tupdesc doesn't have more fields than we allocated */ if (unlikely(tupDesc->natts > op->d.fieldstore.ncolumns)) @@ -3223,10 +3272,14 @@ ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, ExprContext *econte void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext) { + TupleDesc tupDesc; HeapTuple tuple; - /* argdesc should already be valid from the DeForm step */ - tuple = heap_form_tuple(*op->d.fieldstore.argdesc, + /* Lookup tupdesc (should be valid already) */ + tupDesc = get_cached_rowtype(op->d.fieldstore.fstore->resulttype, -1, + op->d.fieldstore.rowcache, NULL); + + tuple = heap_form_tuple(tupDesc, op->d.fieldstore.values, op->d.fieldstore.nulls); @@ -3234,200 +3287,6 @@ ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext *op->resnull = false; } -/* - * Process a subscript in a SubscriptingRef expression. - * - * If subscript is NULL, throw error in assignment case, or in fetch case - * set result to NULL and return false (instructing caller to skip the rest - * of the SubscriptingRef sequence). - * - * Subscript expression result is in subscriptvalue/subscriptnull. - * On success, integer subscript value has been saved in upperindex[] or - * lowerindex[] for use later. - */ -bool -ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op) -{ - SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state; - int *indexes; - int off; - - /* If any index expr yields NULL, result is NULL or error */ - if (sbsrefstate->subscriptnull) - { - if (sbsrefstate->isassignment) - ereport(ERROR, - (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), - errmsg("array subscript in assignment must not be null"))); - *op->resnull = true; - return false; - } - - /* Convert datum to int, save in appropriate place */ - if (op->d.sbsref_subscript.isupper) - indexes = sbsrefstate->upperindex; - else - indexes = sbsrefstate->lowerindex; - off = op->d.sbsref_subscript.off; - - indexes[off] = DatumGetInt32(sbsrefstate->subscriptvalue); - - return true; -} - -/* - * Evaluate SubscriptingRef fetch. - * - * Source container is in step's result variable. - */ -void -ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op) -{ - SubscriptingRefState *sbsrefstate = op->d.sbsref.state; - - /* Should not get here if source container (or any subscript) is null */ - Assert(!(*op->resnull)); - - if (sbsrefstate->numlower == 0) - { - /* Scalar case */ - *op->resvalue = array_get_element(*op->resvalue, - sbsrefstate->numupper, - sbsrefstate->upperindex, - sbsrefstate->refattrlength, - sbsrefstate->refelemlength, - sbsrefstate->refelembyval, - sbsrefstate->refelemalign, - op->resnull); - } - else - { - /* Slice case */ - *op->resvalue = array_get_slice(*op->resvalue, - sbsrefstate->numupper, - sbsrefstate->upperindex, - sbsrefstate->lowerindex, - sbsrefstate->upperprovided, - sbsrefstate->lowerprovided, - sbsrefstate->refattrlength, - sbsrefstate->refelemlength, - sbsrefstate->refelembyval, - sbsrefstate->refelemalign); - } -} - -/* - * Compute old container element/slice value for a SubscriptingRef assignment - * expression. Will only be generated if the new-value subexpression - * contains SubscriptingRef or FieldStore. The value is stored into the - * SubscriptingRefState's prevvalue/prevnull fields. - */ -void -ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op) -{ - SubscriptingRefState *sbsrefstate = op->d.sbsref.state; - - if (*op->resnull) - { - /* whole array is null, so any element or slice is too */ - sbsrefstate->prevvalue = (Datum) 0; - sbsrefstate->prevnull = true; - } - else if (sbsrefstate->numlower == 0) - { - /* Scalar case */ - sbsrefstate->prevvalue = array_get_element(*op->resvalue, - sbsrefstate->numupper, - sbsrefstate->upperindex, - sbsrefstate->refattrlength, - sbsrefstate->refelemlength, - sbsrefstate->refelembyval, - sbsrefstate->refelemalign, - &sbsrefstate->prevnull); - } - else - { - /* Slice case */ - /* this is currently unreachable */ - sbsrefstate->prevvalue = array_get_slice(*op->resvalue, - sbsrefstate->numupper, - sbsrefstate->upperindex, - sbsrefstate->lowerindex, - sbsrefstate->upperprovided, - sbsrefstate->lowerprovided, - sbsrefstate->refattrlength, - sbsrefstate->refelemlength, - sbsrefstate->refelembyval, - sbsrefstate->refelemalign); - sbsrefstate->prevnull = false; - } -} - -/* - * Evaluate SubscriptingRef assignment. - * - * Input container (possibly null) is in result area, replacement value is in - * SubscriptingRefState's replacevalue/replacenull. - */ -void -ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op) -{ - SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state; - - /* - * For an assignment to a fixed-length container type, both the original - * container and the value to be assigned into it must be non-NULL, else - * we punt and return the original container. - */ - if (sbsrefstate->refattrlength > 0) - { - if (*op->resnull || sbsrefstate->replacenull) - return; - } - - /* - * For assignment to varlena arrays, we handle a NULL original array by - * substituting an empty (zero-dimensional) array; insertion of the new - * element will result in a singleton array value. It does not matter - * whether the new element is NULL. - */ - if (*op->resnull) - { - *op->resvalue = PointerGetDatum(construct_empty_array(sbsrefstate->refelemtype)); - *op->resnull = false; - } - - if (sbsrefstate->numlower == 0) - { - /* Scalar case */ - *op->resvalue = array_set_element(*op->resvalue, - sbsrefstate->numupper, - sbsrefstate->upperindex, - sbsrefstate->replacevalue, - sbsrefstate->replacenull, - sbsrefstate->refattrlength, - sbsrefstate->refelemlength, - sbsrefstate->refelembyval, - sbsrefstate->refelemalign); - } - else - { - /* Slice case */ - *op->resvalue = array_set_slice(*op->resvalue, - sbsrefstate->numupper, - sbsrefstate->upperindex, - sbsrefstate->lowerindex, - sbsrefstate->upperprovided, - sbsrefstate->lowerprovided, - sbsrefstate->replacevalue, - sbsrefstate->replacenull, - sbsrefstate->refattrlength, - sbsrefstate->refelemlength, - sbsrefstate->refelembyval, - sbsrefstate->refelemalign); - } -} - /* * Evaluate a rowtype coercion operation. * This may require rearranging field positions. @@ -3437,13 +3296,13 @@ ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op) void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext) { - ConvertRowtypeExpr *convert = op->d.convert_rowtype.convert; HeapTuple result; Datum tupDatum; HeapTupleHeader tuple; HeapTupleData tmptup; TupleDesc indesc, outdesc; + bool changed = false; /* NULL in -> NULL out */ if (*op->resnull) @@ -3452,24 +3311,19 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext tupDatum = *op->resvalue; tuple = DatumGetHeapTupleHeader(tupDatum); - /* Lookup tupdescs if first time through or after rescan */ - if (op->d.convert_rowtype.indesc == NULL) - { - get_cached_rowtype(exprType((Node *) convert->arg), -1, - &op->d.convert_rowtype.indesc, - econtext); - op->d.convert_rowtype.initialized = false; - } - if (op->d.convert_rowtype.outdesc == NULL) - { - get_cached_rowtype(convert->resulttype, -1, - &op->d.convert_rowtype.outdesc, - econtext); - op->d.convert_rowtype.initialized = false; - } - - indesc = op->d.convert_rowtype.indesc; - outdesc = op->d.convert_rowtype.outdesc; + /* + * Lookup tupdescs if first time through or if type changes. We'd better + * pin them since type conversion functions could do catalog lookups and + * hence cause cache invalidation. + */ + indesc = get_cached_rowtype(op->d.convert_rowtype.inputtype, -1, + op->d.convert_rowtype.incache, + &changed); + IncrTupleDescRefCount(indesc); + outdesc = get_cached_rowtype(op->d.convert_rowtype.outputtype, -1, + op->d.convert_rowtype.outcache, + &changed); + IncrTupleDescRefCount(outdesc); /* * We used to be able to assert that incoming tuples are marked with @@ -3480,8 +3334,8 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext Assert(HeapTupleHeaderGetTypeId(tuple) == indesc->tdtypeid || HeapTupleHeaderGetTypeId(tuple) == RECORDOID); - /* if first time through, initialize conversion map */ - if (!op->d.convert_rowtype.initialized) + /* if first time through, or after change, initialize conversion map */ + if (changed) { MemoryContext old_cxt; @@ -3490,7 +3344,6 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext /* prepare map from old to new attribute numbers */ op->d.convert_rowtype.map = convert_tuples_by_name(indesc, outdesc); - op->d.convert_rowtype.initialized = true; MemoryContextSwitchTo(old_cxt); } @@ -3520,6 +3373,9 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext */ *op->resvalue = heap_copy_tuple_as_datum(&tmptup, outdesc); } + + DecrTupleDescRefCount(indesc); + DecrTupleDescRefCount(outdesc); } /* @@ -3799,6 +3655,214 @@ ExecEvalScalarArrayOpFastStr(ExprState *state, ExprEvalStep *op) *op->resnull = false; } +/* + * Hash function for scalar array hash op elements. + * + * We use the element type's default hash opclass, and the column collation + * if the type is collation-sensitive. + */ +static uint32 +saop_element_hash(struct saophash_hash *tb, Datum key) +{ + ScalarArrayOpExprHashTable *elements_tab = (ScalarArrayOpExprHashTable *) tb->private_data; + FunctionCallInfo fcinfo = elements_tab->op->d.hashedscalararrayop.hash_fcinfo_data; + Datum hash; + + fcinfo->args[0].value = key; + fcinfo->args[0].isnull = false; + + hash = elements_tab->op->d.hashedscalararrayop.hash_fn_addr(fcinfo); + + return DatumGetUInt32(hash); +} + +/* + * Matching function for scalar array hash op elements, to be used in hashtable + * lookups. + */ +static bool +saop_hash_element_match(struct saophash_hash *tb, Datum key1, Datum key2) +{ + Datum result; + + ScalarArrayOpExprHashTable *elements_tab = (ScalarArrayOpExprHashTable *) tb->private_data; + FunctionCallInfo fcinfo = elements_tab->op->d.hashedscalararrayop.fcinfo_data; + + fcinfo->args[0].value = key1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = key2; + fcinfo->args[1].isnull = false; + + result = elements_tab->op->d.hashedscalararrayop.fn_addr(fcinfo); + + return DatumGetBool(result); +} + +/* + * Evaluate "scalar op ANY (const array)". + * + * Similar to ExecEvalScalarArrayOp, but optimized for faster repeat lookups + * by building a hashtable on the first lookup. This hashtable will be reused + * by subsequent lookups. Unlike ExecEvalScalarArrayOp, this version only + * supports OR semantics. + * + * Source array is in our result area, scalar arg is already evaluated into + * fcinfo->args[0]. + * + * The operator always yields boolean. + */ +void +ExecEvalHashedScalarArrayOp(ExprState *state, ExprEvalStep *op, ExprContext *econtext) +{ + ScalarArrayOpExprHashTable *elements_tab = op->d.hashedscalararrayop.elements_tab; + FunctionCallInfo fcinfo = op->d.hashedscalararrayop.fcinfo_data; + bool strictfunc = op->d.hashedscalararrayop.finfo->fn_strict; + Datum scalar = fcinfo->args[0].value; + bool scalar_isnull = fcinfo->args[0].isnull; + Datum result; + bool resultnull; + bool hashfound; + + /* We don't setup a hashed scalar array op if the array const is null. */ + Assert(!*op->resnull); + + /* + * If the scalar is NULL, and the function is strict, return NULL; no + * point in executing the search. + */ + if (fcinfo->args[0].isnull && strictfunc) + { + *op->resnull = true; + return; + } + + /* Build the hash table on first evaluation */ + if (elements_tab == NULL) + { + int16 typlen; + bool typbyval; + char typalign; + int nitems; + bool has_nulls = false; + char *s; + bits8 *bitmap; + int bitmask; + MemoryContext oldcontext; + ArrayType *arr; + + arr = DatumGetArrayTypeP(*op->resvalue); + nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)); + + get_typlenbyvalalign(ARR_ELEMTYPE(arr), + &typlen, + &typbyval, + &typalign); + + oldcontext = MemoryContextSwitchTo(econtext->ecxt_per_query_memory); + + elements_tab = (ScalarArrayOpExprHashTable *) + palloc(sizeof(ScalarArrayOpExprHashTable)); + op->d.hashedscalararrayop.elements_tab = elements_tab; + elements_tab->op = op; + + /* + * Create the hash table sizing it according to the number of elements + * in the array. This does assume that the array has no duplicates. + * If the array happens to contain many duplicate values then it'll + * just mean that we sized the table a bit on the large side. + */ + elements_tab->hashtab = saophash_create(CurrentMemoryContext, nitems, + elements_tab); + + MemoryContextSwitchTo(oldcontext); + + s = (char *) ARR_DATA_PTR(arr); + bitmap = ARR_NULLBITMAP(arr); + bitmask = 1; + for (int i = 0; i < nitems; i++) + { + /* Get array element, checking for NULL. */ + if (bitmap && (*bitmap & bitmask) == 0) + { + has_nulls = true; + } + else + { + Datum element; + + element = fetch_att(s, typbyval, typlen); + s = att_addlength_pointer(s, typlen, s); + s = (char *) att_align_nominal(s, typalign); + + saophash_insert(elements_tab->hashtab, element, &hashfound); + } + + /* Advance bitmap pointer if any. */ + if (bitmap) + { + bitmask <<= 1; + if (bitmask == 0x100) + { + bitmap++; + bitmask = 1; + } + } + } + + /* + * Remember if we had any nulls so that we know if we need to execute + * non-strict functions with a null lhs value if no match is found. + */ + op->d.hashedscalararrayop.has_nulls = has_nulls; + } + + /* Check the hash to see if we have a match. */ + hashfound = NULL != saophash_lookup(elements_tab->hashtab, scalar); + + result = BoolGetDatum(hashfound); + resultnull = false; + + /* + * If we didn't find a match in the array, we still might need to handle + * the possibility of null values. We didn't put any NULLs into the + * hashtable, but instead marked if we found any when building the table + * in has_nulls. + */ + if (!DatumGetBool(result) && op->d.hashedscalararrayop.has_nulls) + { + if (strictfunc) + { + + /* + * We have nulls in the array so a non-null lhs and no match must + * yield NULL. + */ + result = (Datum) 0; + resultnull = true; + } + else + { + /* + * Execute function will null rhs just once. + * + * The hash lookup path will have scribbled on the lhs argument so + * we need to set it up also (even though we entered this function + * with it already set). + */ + fcinfo->args[0].value = scalar; + fcinfo->args[0].isnull = scalar_isnull; + fcinfo->args[1].value = (Datum) 0; + fcinfo->args[1].isnull = true; + + result = op->d.hashedscalararrayop.fn_addr(fcinfo); + resultnull = fcinfo->isnull; + } + } + + *op->resvalue = result; + *op->resnull = resultnull; +} + /* * Evaluate a NOT NULL domain constraint. */ @@ -4091,20 +4155,6 @@ ExecEvalSubPlan(ExprState *state, ExprEvalStep *op, ExprContext *econtext) *op->resvalue = ExecSubPlan(sstate, econtext, op->resnull); } -/* - * Hand off evaluation of an alternative subplan to nodeSubplan.c - */ -void -ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op, ExprContext *econtext) -{ - AlternativeSubPlanState *asstate = op->d.alternative_subplan.asstate; - - /* could potentially be nested, so make sure there's enough stack */ - check_stack_depth(); - - *op->resvalue = ExecAlternativeSubPlan(asstate, econtext, op->resnull); -} - /* * Evaluate a wholerow Var expression. * diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c index 9965760a4164..e2c3e0ab3a10 100644 --- a/src/backend/executor/execGrouping.c +++ b/src/backend/executor/execGrouping.c @@ -3,7 +3,7 @@ * execGrouping.c * executor utility routines for grouping, hashing, and aggregation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c index 658c658a0439..07f65545a807 100644 --- a/src/backend/executor/execIndexing.c +++ b/src/backend/executor/execIndexing.c @@ -95,7 +95,7 @@ * with the higher XID backs out. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -136,6 +136,11 @@ static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, static bool index_recheck_constraint(Relation index, Oid *constr_procs, Datum *existing_values, bool *existing_isnull, Datum *new_values); +static bool index_unchanged_by_update(ResultRelInfo *resultRelInfo, + EState *estate, IndexInfo *indexInfo, + Relation indexRelation); +static bool index_expression_changed_walker(Node *node, + Bitmapset *allUpdatedCols); /* ---------------------------------------------------------------- * ExecOpenIndices @@ -254,6 +259,16 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo) * into all the relations indexing the result relation * when a heap tuple is inserted into the result relation. * + * When 'update' is true, executor is performing an UPDATE + * that could not use an optimization like heapam's HOT (in + * more general terms a call to table_tuple_update() took + * place and set 'update_indexes' to true). Receiving this + * hint makes us consider if we should pass down the + * 'indexUnchanged' hint in turn. That's something that we + * figure out for each index_insert() call iff 'update' is + * true. (When 'update' is false we already know not to pass + * the hint to any index.) + * * Unique and exclusion constraints are enforced at the same * time. This returns a list of index OIDs for any unique or * exclusion constraints that are deferred and that had @@ -274,15 +289,16 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo) * ---------------------------------------------------------------- */ List * -ExecInsertIndexTuples(TupleTableSlot *slot, +ExecInsertIndexTuples(ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, EState *estate, + bool update, bool noDupErr, bool *specConflict, List *arbiterIndexes) { ItemPointer tupleid = &slot->tts_tid; List *result = NIL; - ResultRelInfo *resultRelInfo; int i; int numIndices; RelationPtr relationDescs; @@ -297,7 +313,6 @@ ExecInsertIndexTuples(TupleTableSlot *slot, /* * Get information from the result relation info structure. */ - resultRelInfo = estate->es_result_relation_info; numIndices = resultRelInfo->ri_NumIndices; relationDescs = resultRelInfo->ri_IndexRelationDescs; indexInfoArray = resultRelInfo->ri_IndexRelationInfo; @@ -324,6 +339,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot, IndexInfo *indexInfo; bool applyNoDupErr; IndexUniqueCheck checkUnique; + bool indexUnchanged; bool satisfiesConstraint; if (indexRelation == NULL) @@ -394,6 +410,16 @@ ExecInsertIndexTuples(TupleTableSlot *slot, else checkUnique = UNIQUE_CHECK_PARTIAL; + /* + * There's definitely going to be an index_insert() call for this + * index. If we're being called as part of an UPDATE statement, + * consider if the 'indexUnchanged' = true hint should be passed. + */ + indexUnchanged = update && index_unchanged_by_update(resultRelInfo, + estate, + indexInfo, + indexRelation); + satisfiesConstraint = index_insert(indexRelation, /* index relation */ values, /* array of index Datums */ @@ -401,6 +427,7 @@ ExecInsertIndexTuples(TupleTableSlot *slot, tupleid, /* tid of heap tuple */ heapRelation, /* heap relation */ checkUnique, /* type of uniqueness check to do */ + indexUnchanged, /* UPDATE without logical change? */ indexInfo); /* index AM may need this */ /* @@ -483,11 +510,10 @@ ExecInsertIndexTuples(TupleTableSlot *slot, * ---------------------------------------------------------------- */ bool -ExecCheckIndexConstraints(TupleTableSlot *slot, +ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, ItemPointer conflictTid, List *arbiterIndexes) { - ResultRelInfo *resultRelInfo; int i; int numIndices; RelationPtr relationDescs; @@ -505,7 +531,6 @@ ExecCheckIndexConstraints(TupleTableSlot *slot, /* * Get information from the result relation info structure. */ - resultRelInfo = estate->es_result_relation_info; numIndices = resultRelInfo->ri_NumIndices; relationDescs = resultRelInfo->ri_IndexRelationDescs; indexInfoArray = resultRelInfo->ri_IndexRelationInfo; @@ -906,3 +931,122 @@ index_recheck_constraint(Relation index, Oid *constr_procs, return true; } + +/* + * Check if ExecInsertIndexTuples() should pass indexUnchanged hint. + * + * When the executor performs an UPDATE that requires a new round of index + * tuples, determine if we should pass 'indexUnchanged' = true hint for one + * single index. + */ +static bool +index_unchanged_by_update(ResultRelInfo *resultRelInfo, EState *estate, + IndexInfo *indexInfo, Relation indexRelation) +{ + Bitmapset *updatedCols = ExecGetUpdatedCols(resultRelInfo, estate); + Bitmapset *extraUpdatedCols = ExecGetExtraUpdatedCols(resultRelInfo, estate); + Bitmapset *allUpdatedCols; + bool hasexpression = false; + List *idxExprs; + + /* + * Check for indexed attribute overlap with updated columns. + * + * Only do this for key columns. A change to a non-key column within an + * INCLUDE index should not be counted here. Non-key column values are + * opaque payload state to the index AM, a little like an extra table TID. + */ + for (int attr = 0; attr < indexInfo->ii_NumIndexKeyAttrs; attr++) + { + int keycol = indexInfo->ii_IndexAttrNumbers[attr]; + + if (keycol <= 0) + { + /* + * Skip expressions for now, but remember to deal with them later + * on + */ + hasexpression = true; + continue; + } + + if (bms_is_member(keycol - FirstLowInvalidHeapAttributeNumber, + updatedCols) || + bms_is_member(keycol - FirstLowInvalidHeapAttributeNumber, + extraUpdatedCols)) + { + /* Changed key column -- don't hint for this index */ + return false; + } + } + + /* + * When we get this far and index has no expressions, return true so that + * index_insert() call will go on to pass 'indexUnchanged' = true hint. + * + * The _absence_ of an indexed key attribute that overlaps with updated + * attributes (in addition to the total absence of indexed expressions) + * shows that the index as a whole is logically unchanged by UPDATE. + */ + if (!hasexpression) + return true; + + /* + * Need to pass only one bms to expression_tree_walker helper function. + * Avoid allocating memory in common case where there are no extra cols. + */ + if (!extraUpdatedCols) + allUpdatedCols = updatedCols; + else + allUpdatedCols = bms_union(updatedCols, extraUpdatedCols); + + /* + * We have to work slightly harder in the event of indexed expressions, + * but the principle is the same as before: try to find columns (Vars, + * actually) that overlap with known-updated columns. + * + * If we find any matching Vars, don't pass hint for index. Otherwise + * pass hint. + */ + idxExprs = RelationGetIndexExpressions(indexRelation); + hasexpression = index_expression_changed_walker((Node *) idxExprs, + allUpdatedCols); + list_free(idxExprs); + if (extraUpdatedCols) + bms_free(allUpdatedCols); + + if (hasexpression) + return false; + + return true; +} + +/* + * Indexed expression helper for index_unchanged_by_update(). + * + * Returns true when Var that appears within allUpdatedCols located. + */ +static bool +index_expression_changed_walker(Node *node, Bitmapset *allUpdatedCols) +{ + if (node == NULL) + return false; + + if (IsA(node, Var)) + { + Var *var = (Var *) node; + + if (bms_is_member(var->varattno - FirstLowInvalidHeapAttributeNumber, + allUpdatedCols)) + { + /* Var was updated -- indicates that we should not hint */ + return true; + } + + /* Still haven't found a reason to not pass the hint */ + return false; + } + + return expression_tree_walker(node, index_expression_changed_walker, + (void *) allUpdatedCols); +} diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c index 40d700dd9e23..9741897e8386 100644 --- a/src/backend/executor/execJunk.c +++ b/src/backend/executor/execJunk.c @@ -3,7 +3,7 @@ * execJunk.c * Junk attribute support stuff.... * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -54,7 +54,7 @@ * * The source targetlist is passed in. The output tuple descriptor is * built from the non-junk tlist entries. - * An optional resultSlot can be passed as well. + * An optional resultSlot can be passed as well; otherwise, we create one. */ JunkFilter * ExecInitJunkFilter(List *targetList, TupleTableSlot *slot) @@ -63,8 +63,6 @@ ExecInitJunkFilter(List *targetList, TupleTableSlot *slot) TupleDesc cleanTupType; int cleanLength; AttrNumber *cleanMap; - ListCell *t; - AttrNumber cleanResno; /* * Compute the tuple descriptor for the cleaned tuple. @@ -92,18 +90,22 @@ ExecInitJunkFilter(List *targetList, TupleTableSlot *slot) cleanLength = cleanTupType->natts; if (cleanLength > 0) { + AttrNumber cleanResno; + ListCell *t; + cleanMap = (AttrNumber *) palloc(cleanLength * sizeof(AttrNumber)); - cleanResno = 1; + cleanResno = 0; foreach(t, targetList) { TargetEntry *tle = lfirst(t); if (!tle->resjunk) { - cleanMap[cleanResno - 1] = tle->resno; + cleanMap[cleanResno] = tle->resno; cleanResno++; } } + Assert(cleanResno == cleanLength); } else cleanMap = NULL; @@ -236,22 +238,6 @@ ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName) return InvalidAttrNumber; } -/* - * ExecGetJunkAttribute - * - * Given a junk filter's input tuple (slot) and a junk attribute's number - * previously found by ExecFindJunkAttribute, extract & return the value and - * isNull flag of the attribute. - */ -Datum -ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, - bool *isNull) -{ - Assert(attno > 0); - - return slot_getattr(slot, attno, isNull); -} - /* * ExecFilterJunk * diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index a764c06e3b64..7953f9759c28 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -28,7 +28,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -61,6 +61,7 @@ #include "storage/lmgr.h" #include "tcop/utility.h" #include "utils/acl.h" +#include "utils/backend_status.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/partcache.h" @@ -196,6 +197,14 @@ static void AdjustReplicatedTableCounts(EState *estate); void ExecutorStart(QueryDesc *queryDesc, int eflags) { + /* + * In some cases (e.g. an EXECUTE statement) a query execution will skip + * parse analysis, which means that the query_id won't be reported. Note + * that it's harmless to report the query_id multiple time, as the call + * will be ignored if the top level query_id has already been reported. + */ + pgstat_report_query_id(queryDesc->plannedstmt->queryId, false); + if (ExecutorStart_hook) (*ExecutorStart_hook) (queryDesc, eflags); else @@ -334,7 +343,7 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags) * planned to non-temporary tables. EXPLAIN is considered read-only. * * Don't allow writes in parallel mode. Supporting UPDATE and DELETE - * would require (a) storing the combocid hash in shared memory, rather + * would require (a) storing the combo CID hash in shared memory, rather * than synchronizing it just once at the start of parallelism, and (b) an * alternative to heap_update()'s reliance on xmax for mutual exclusion. * INSERT may have no such troubles, but we forbid it to simplify the @@ -380,6 +389,8 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags) palloc0(nParamExec * sizeof(ParamExecData)); } + /* We now require all callers to provide sourceText */ + Assert(queryDesc->sourceText != NULL); estate->es_sourceText = queryDesc->sourceText; /* @@ -450,15 +461,21 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags) sliceTable = InitSliceTable(estate, queryDesc->plannedstmt); estate->es_sliceTable = sliceTable; + /* + * Always set up a QueryDispatchDesc on the QD, even for a QD-only plan + * (no gang, no Motion). CREATE TABLE AS / SELECT INTO stash the + * CreateStmt in ddesc (create_ctas_internal) regardless of whether the + * SELECT itself dispatches, so a missing ddesc would crash there. + */ + if (queryDesc->ddesc == NULL) + { + queryDesc->ddesc = makeNode(QueryDispatchDesc); + queryDesc->ddesc->useChangedAOOpts = true; + } + if (sliceTable->slices[0].gangType != GANGTYPE_UNALLOCATED || sliceTable->hasMotions) { - if (queryDesc->ddesc == NULL) - { - queryDesc->ddesc = makeNode(QueryDispatchDesc);; - queryDesc->ddesc->useChangedAOOpts = true; - } - /* Pass EXPLAIN ANALYZE flag to qExecs. */ estate->es_sliceTable->instrument_options = queryDesc->instrument_options; @@ -1352,7 +1369,7 @@ ExecutorRewind(QueryDesc *queryDesc) * Returns true if permissions are adequate. Otherwise, throws an appropriate * error if ereport_on_violation is true, or simply returns false otherwise. * - * Note that this does NOT address row level security policies (aka: RLS). If + * Note that this does NOT address row-level security policies (aka: RLS). If * rows will be returned to the user as a result of this permission check * passing, then RLS also needs to be consulted (and check_enable_rls()). * @@ -1716,83 +1733,10 @@ InitPlan(QueryDesc *queryDesc, int eflags) * the actual updating, since it's where we learn things, such as if the row needs to * contain OIDs or not. */ - if (plannedstmt->resultRelations) - { - List *resultRelations = plannedstmt->resultRelations; - int numResultRelations = list_length(resultRelations); - ResultRelInfo *resultRelInfos; - ResultRelInfo *resultRelInfo; - - resultRelInfos = (ResultRelInfo *) - palloc(numResultRelations * sizeof(ResultRelInfo)); - resultRelInfo = resultRelInfos; - foreach(l, plannedstmt->resultRelations) - { - Index resultRelationIndex = lfirst_int(l); - Relation resultRelation; - - resultRelation = ExecGetRangeTableRelation(estate, - resultRelationIndex); - InitResultRelInfo(resultRelInfo, - resultRelation, - resultRelationIndex, - NULL, - estate->es_instrument); - resultRelInfo++; - } - estate->es_result_relations = resultRelInfos; - estate->es_num_result_relations = numResultRelations; - - /* es_result_relation_info is NULL except when within ModifyTable */ - estate->es_result_relation_info = NULL; - - /* - * In the partitioned result relation case, also build ResultRelInfos - * for all the partitioned table roots, because we will need them to - * fire statement-level triggers, if any. - */ - if (plannedstmt->rootResultRelations) - { - int num_roots = list_length(plannedstmt->rootResultRelations); - - resultRelInfos = (ResultRelInfo *) - palloc(num_roots * sizeof(ResultRelInfo)); - resultRelInfo = resultRelInfos; - foreach(l, plannedstmt->rootResultRelations) - { - Index resultRelIndex = lfirst_int(l); - Relation resultRelDesc; - - resultRelDesc = ExecGetRangeTableRelation(estate, - resultRelIndex); - InitResultRelInfo(resultRelInfo, - resultRelDesc, - resultRelIndex, - NULL, - estate->es_instrument); - resultRelInfo++; - } - - estate->es_root_result_relations = resultRelInfos; - estate->es_num_root_result_relations = num_roots; - } - else - { - estate->es_root_result_relations = NULL; - estate->es_num_root_result_relations = 0; - } - } - else - { - /* - * if no result relation, then set state appropriately - */ - estate->es_result_relations = NULL; - estate->es_num_result_relations = 0; - estate->es_result_relation_info = NULL; - estate->es_root_result_relations = NULL; - estate->es_num_root_result_relations = 0; - } + /* + * In PG14, result relations are initialized lazily via + * ExecGetResultRelation() in execUtils.c. + */ /* * Next, build the ExecRowMark array from the PlanRowMark(s), if any. @@ -2309,11 +2253,9 @@ void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, - Relation partition_root, + ResultRelInfo *partition_root_rri, int instrument_options) { - List *partition_check = NIL; - MemSet(resultRelInfo, 0, sizeof(ResultRelInfo)); resultRelInfo->type = T_ResultRelInfo; resultRelInfo->ri_RangeTableIndex = resultRelationIndex; @@ -2332,7 +2274,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_TrigWhenExprs = (ExprState **) palloc0(n * sizeof(ExprState *)); if (instrument_options) - resultRelInfo->ri_TrigInstrument = InstrAlloc(n, instrument_options); + resultRelInfo->ri_TrigInstrument = InstrAlloc(n, instrument_options, false); } else { @@ -2346,6 +2288,11 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_FdwRoutine = NULL; /* The following fields are set later if needed */ + resultRelInfo->ri_RowIdAttNo = 0; + resultRelInfo->ri_projectNew = NULL; + resultRelInfo->ri_newTupleSlot = NULL; + resultRelInfo->ri_oldTupleSlot = NULL; + resultRelInfo->ri_projectNewInfoValid = false; resultRelInfo->ri_FdwState = NULL; resultRelInfo->ri_usesFdwDirectModify = false; resultRelInfo->ri_ConstraintExprs = NULL; @@ -2353,6 +2300,9 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_junkFilter = NULL; resultRelInfo->ri_segid_attno = InvalidAttrNumber; resultRelInfo->ri_action_attno = InvalidAttrNumber; + resultRelInfo->ri_wholerow_attno = InvalidAttrNumber; + resultRelInfo->ri_inhNewSlot = NULL; + resultRelInfo->ri_inhRootMap = NULL; resultRelInfo->ri_projectReturning = NULL; resultRelInfo->ri_onConflictArbiterIndexes = NIL; resultRelInfo->ri_onConflict = NULL; @@ -2361,23 +2311,17 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_TrigNewSlot = NULL; /* - * Partition constraint, which also includes the partition constraint of - * all the ancestors that are partitions. Note that it will be checked - * even in the case of tuple-routing where this table is the target leaf - * partition, if there any BR triggers defined on the table. Although - * tuple-routing implicitly preserves the partition constraint of the - * target partition for a given row, the BR triggers may change the row - * such that the constraint is no longer satisfied, which we must fail for - * by checking it explicitly. - * - * If this is a partitioned table, the partition constraint (if any) of a - * given row will be checked just before performing tuple-routing. + * Only ExecInitPartitionInfo() and ExecInitPartitionDispatchInfo() pass + * non-NULL partition_root_rri. For child relations that are part of the + * initial query rather than being dynamically added by tuple routing, + * this field is filled in ExecInitModifyTable(). */ - partition_check = RelationGetPartitionQual(resultRelationDesc); - - resultRelInfo->ri_PartitionCheck = partition_check; - resultRelInfo->ri_PartitionRoot = partition_root; - resultRelInfo->ri_PartitionInfo = NULL; /* may be set later */ + resultRelInfo->ri_RootResultRelInfo = partition_root_rri; + resultRelInfo->ri_RootToPartitionMap = NULL; /* set by + * ExecInitRoutingInfo */ + resultRelInfo->ri_PartitionTupleSlot = NULL; /* ditto */ + resultRelInfo->ri_ChildToRootMap = NULL; + resultRelInfo->ri_ChildToRootMapValid = false; resultRelInfo->ri_CopyMultiInsertBuffer = NULL; } @@ -2387,8 +2331,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, * * Most of the time, triggers are fired on one of the result relations of the * query, and so we can just return a member of the es_result_relations array, - * or the es_root_result_relations array (if any), or the - * es_tuple_routing_result_relations list (if any). (Note: in self-join + * or the es_tuple_routing_result_relations list (if any). (Note: in self-join * situations there might be multiple members with the same OID; if so it * doesn't matter which one we pick.) * @@ -2405,35 +2348,21 @@ ResultRelInfo * ExecGetTriggerResultRel(EState *estate, Oid relid) { ResultRelInfo *rInfo; - int nr; ListCell *l; Relation rel; MemoryContext oldcontext; - /* First, search through the query result relations */ - rInfo = estate->es_result_relations; - nr = estate->es_num_result_relations; - while (nr > 0) + /* Search through the query result relations */ + foreach(l, estate->es_opened_result_relations) { + rInfo = lfirst(l); if (RelationGetRelid(rInfo->ri_RelationDesc) == relid) return rInfo; - rInfo++; - nr--; - } - /* Second, search through the root result relations, if any */ - rInfo = estate->es_root_result_relations; - nr = estate->es_num_root_result_relations; - while (nr > 0) - { - if (RelationGetRelid(rInfo->ri_RelationDesc) == relid) - return rInfo; - rInfo++; - nr--; } /* - * Third, search through the result relations that were created during - * tuple routing, if any. + * Search through the result relations that were created during tuple + * routing, if any. */ foreach(l, estate->es_tuple_routing_result_relations) { @@ -2481,35 +2410,6 @@ ExecGetTriggerResultRel(EState *estate, Oid relid) return rInfo; } -/* - * Close any relations that have been opened by ExecGetTriggerResultRel(). - */ -void -ExecCleanUpTriggerState(EState *estate) -{ - ListCell *l; - - foreach(l, estate->es_trig_target_relations) - { - ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l); - - /* - * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we - * might be issuing a duplicate close against a Relation opened by - * ExecGetRangeTableRelation. - */ - Assert(resultRelInfo->ri_RangeTableIndex == 0); - - /* - * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for - * these rels, we needn't call ExecCloseIndices either. - */ - Assert(resultRelInfo->ri_NumIndices == 0); - - table_close(resultRelInfo->ri_RelationDesc, NoLock); - } -} - /* ---------------------------------------------------------------- * ExecPostprocessPlan * @@ -2565,9 +2465,6 @@ ExecPostprocessPlan(EState *estate) void ExecEndPlan(PlanState *planstate, EState *estate) { - ResultRelInfo *resultRelInfo; - Index num_relations; - Index i; ListCell *l; /* @@ -2600,29 +2497,69 @@ ExecEndPlan(PlanState *planstate, EState *estate) AdjustReplicatedTableCounts(estate); /* - * close indexes of result relation(s) if any. (Rels themselves get - * closed next.) + * Close any Relations that have been opened for range table entries or + * result relations. */ - resultRelInfo = estate->es_result_relations; - for (i = 0; i < estate->es_num_result_relations; i++) + ExecCloseResultRelations(estate); + ExecCloseRangeTableRelations(estate); +} + +/* + * Close any relations that have been opened for ResultRelInfos. + */ +void +ExecCloseResultRelations(EState *estate) +{ + ListCell *l; + + /* + * close indexes of result relation(s) if any. (Rels themselves are + * closed in ExecCloseRangeTableRelations()) + */ + foreach(l, estate->es_opened_result_relations) { + ResultRelInfo *resultRelInfo = lfirst(l); + ExecCloseIndices(resultRelInfo); - resultRelInfo++; } - /* - * close whatever rangetable Relations have been opened. We do not - * release any locks we might hold on those rels. - */ - num_relations = estate->es_range_table_size; - for (i = 0; i < num_relations; i++) + /* Close any relations that have been opened by ExecGetTriggerResultRel(). */ + foreach(l, estate->es_trig_target_relations) + { + ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l); + + /* + * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we + * might be issuing a duplicate close against a Relation opened by + * ExecGetRangeTableRelation. + */ + Assert(resultRelInfo->ri_RangeTableIndex == 0); + + /* + * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for + * these rels, we needn't call ExecCloseIndices either. + */ + Assert(resultRelInfo->ri_NumIndices == 0); + + table_close(resultRelInfo->ri_RelationDesc, NoLock); + } +} + +/* + * Close all relations opened by ExecGetRangeTableRelation(). + * + * We do not release any locks we might hold on those rels. + */ +void +ExecCloseRangeTableRelations(EState *estate) +{ + int i; + + for (i = 0; i < estate->es_range_table_size; i++) { if (estate->es_relations[i]) table_close(estate->es_relations[i], NoLock); } - - /* likewise close any trigger target relations */ - ExecCleanUpTriggerState(estate); } /* ---------------------------------------------------------------- @@ -2813,6 +2750,15 @@ ExecRelCheck(ResultRelInfo *resultRelInfo, MemoryContext oldContext; int i; + /* + * CheckConstraintFetch let this pass with only a warning, but now we + * should fail rather than possibly failing to enforce an important + * constraint. + */ + if (ncheck != rel->rd_rel->relchecks) + elog(ERROR, "%d pg_constraint record(s) missing for relation \"%s\"", + rel->rd_rel->relchecks - ncheck, RelationGetRelationName(rel)); + /* * If first time through for this result relation, build expression * nodetrees for rel's constraint expressions. Keep them in the per-query @@ -2865,7 +2811,7 @@ ExecRelCheck(ResultRelInfo *resultRelInfo, * ExecPartitionCheck --- check that tuple meets the partition constraint. * * Returns true if it meets the partition constraint. If the constraint - * fails and we're asked to emit to error, do so and don't return; otherwise + * fails and we're asked to emit an error, do so and don't return; otherwise * return false. */ bool @@ -2877,14 +2823,22 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, /* * If first time through, build expression state tree for the partition - * check expression. Keep it in the per-query memory context so they'll - * survive throughout the query. + * check expression. (In the corner case where the partition check + * expression is empty, ie there's a default partition and nothing else, + * we'll be fooled into executing this code each time through. But it's + * pretty darn cheap in that case, so we don't worry about it.) */ if (resultRelInfo->ri_PartitionCheckExpr == NULL) { - List *qual = resultRelInfo->ri_PartitionCheck; + /* + * Ensure that the qual tree and prepared expression are in the + * query-lifespan context. + */ + MemoryContext oldcxt = MemoryContextSwitchTo(estate->es_query_cxt); + List *qual = RelationGetPartitionQual(resultRelInfo->ri_RelationDesc); resultRelInfo->ri_PartitionCheckExpr = ExecPrepareCheck(qual, estate); + MemoryContextSwitchTo(oldcxt); } /* @@ -2929,13 +2883,14 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, * back to the root table's rowtype so that val_desc in the error message * matches the input tuple. */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; TupleDesc old_tupdesc; AttrMap *map; - root_relid = RelationGetRelid(resultRelInfo->ri_PartitionRoot); - tupdesc = RelationGetDescr(resultRelInfo->ri_PartitionRoot); + root_relid = RelationGetRelid(rootrel->ri_RelationDesc); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); /* a reverse map */ @@ -2948,16 +2903,17 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); } else { root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc); tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); } - modifiedCols = bms_union(GetInsertedColumns(resultRelInfo, estate), - GetUpdatedColumns(resultRelInfo, estate)); - val_desc = ExecBuildSlotValueDescription(root_relid, slot, tupdesc, @@ -2990,12 +2946,10 @@ ExecConstraints(ResultRelInfo *resultRelInfo, TupleDesc tupdesc = RelationGetDescr(rel); TupleConstr *constr = tupdesc->constr; Bitmapset *modifiedCols; - Bitmapset *insertedCols; - Bitmapset *updatedCols; - Assert(constr || resultRelInfo->ri_PartitionCheck); + Assert(constr); /* we should not be called otherwise */ - if (constr && constr->has_not_null) + if (constr->has_not_null) { int natts = tupdesc->natts; int attrChk; @@ -3017,12 +2971,12 @@ ExecConstraints(ResultRelInfo *resultRelInfo, * rowtype so that val_desc shown error message matches the * input tuple. */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; AttrMap *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(orig_tupdesc, tupdesc); @@ -3034,11 +2988,13 @@ ExecConstraints(ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); + rel = rootrel->ri_RelationDesc; } - - insertedCols = GetInsertedColumns(resultRelInfo, estate); - updatedCols = GetUpdatedColumns(resultRelInfo, estate); - modifiedCols = bms_union(insertedCols, updatedCols); + else + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel), slot, tupdesc, @@ -3056,7 +3012,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo, } } - if (constr && constr->num_check > 0) + if (rel->rd_rel->relchecks > 0) { const char *failed; @@ -3066,13 +3022,13 @@ ExecConstraints(ResultRelInfo *resultRelInfo, Relation orig_rel = rel; /* See the comment above. */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; TupleDesc old_tupdesc = RelationGetDescr(rel); AttrMap *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc); @@ -3084,11 +3040,13 @@ ExecConstraints(ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); + rel = rootrel->ri_RelationDesc; } - - insertedCols = GetInsertedColumns(resultRelInfo, estate); - updatedCols = GetUpdatedColumns(resultRelInfo, estate); - modifiedCols = bms_union(insertedCols, updatedCols); + else + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel), slot, tupdesc, @@ -3110,7 +3068,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo, * * Note that this needs to be called multiple times to ensure that all kinds of * WITH CHECK OPTIONs are handled (both those from views which have the WITH - * CHECK OPTION set and from row level security policies). See ExecInsert() + * CHECK OPTION set and from row-level security policies). See ExecInsert() * and ExecUpdate(). */ void @@ -3157,8 +3115,6 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, { char *val_desc; Bitmapset *modifiedCols; - Bitmapset *insertedCols; - Bitmapset *updatedCols; switch (wco->kind) { @@ -3173,13 +3129,13 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, */ case WCO_VIEW_CHECK: /* See the comment in ExecConstraints(). */ - if (resultRelInfo->ri_PartitionRoot) + if (resultRelInfo->ri_RootResultRelInfo) { + ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo; TupleDesc old_tupdesc = RelationGetDescr(rel); AttrMap *map; - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + tupdesc = RelationGetDescr(rootrel->ri_RelationDesc); /* a reverse map */ map = build_attrmap_by_name_if_req(old_tupdesc, tupdesc); @@ -3191,11 +3147,14 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, if (map != NULL) slot = execute_attr_map_slot(map, slot, MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); - } - insertedCols = GetInsertedColumns(resultRelInfo, estate); - updatedCols = GetUpdatedColumns(resultRelInfo, estate); - modifiedCols = bms_union(insertedCols, updatedCols); + modifiedCols = bms_union(ExecGetInsertedCols(rootrel, estate), + ExecGetUpdatedCols(rootrel, estate)); + rel = rootrel->ri_RelationDesc; + } + else + modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfo, estate), + ExecGetUpdatedCols(resultRelInfo, estate)); val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel), slot, tupdesc, @@ -3409,7 +3368,7 @@ ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo) * been modified, then we can use a weaker lock, allowing for better * concurrency. */ - updatedCols = GetAllUpdatedColumns(relinfo, estate); + updatedCols = ExecGetAllUpdatedCols(relinfo, estate); keyCols = RelationGetIndexAttrBitmap(relinfo->ri_RelationDesc, INDEX_ATTR_BITMAP_KEY); @@ -3607,7 +3566,8 @@ EvalPlanQualInit(EPQState *epqstate, EState *parentestate, /* * EvalPlanQualSetPlan -- set or change subplan of an EPQState. * - * We need this so that ModifyTable can deal with multiple subplans. + * We used to need this so that ModifyTable could deal with multiple subplans. + * It could now be refactored out of existence. */ void EvalPlanQualSetPlan(EPQState *epqstate, Plan *subplan, List *auxrowmarks) @@ -3858,17 +3818,9 @@ EvalPlanQualStart(EPQState *epqstate, Plan *planTree) /* * Child EPQ EStates share the parent's copy of unchanging state such as - * the snapshot, rangetable, result-rel info, and external Param info. - * They need their own copies of local state, including a tuple table, - * es_param_exec_vals, etc. - * - * The ResultRelInfo array management is trickier than it looks. We - * create fresh arrays for the child but copy all the content from the - * parent. This is because it's okay for the child to share any - * per-relation state the parent has already created --- but if the child - * sets up any ResultRelInfo fields, such as its own junkfilter, that - * state must *not* propagate back to the parent. (For one thing, the - * pointed-to data is in a memory context that won't last long enough.) + * the snapshot, rangetable, and external Param info. They need their own + * copies of local state, including a tuple table, es_param_exec_vals, + * result-rel info, etc. */ rcestate->es_direction = ForwardScanDirection; rcestate->es_snapshot = parentestate->es_snapshot; @@ -3881,31 +3833,12 @@ EvalPlanQualStart(EPQState *epqstate, Plan *planTree) rcestate->es_plannedstmt = parentestate->es_plannedstmt; rcestate->es_junkFilter = parentestate->es_junkFilter; rcestate->es_output_cid = parentestate->es_output_cid; - if (parentestate->es_num_result_relations > 0) - { - int numResultRelations = parentestate->es_num_result_relations; - int numRootResultRels = parentestate->es_num_root_result_relations; - ResultRelInfo *resultRelInfos; - - resultRelInfos = (ResultRelInfo *) - palloc(numResultRelations * sizeof(ResultRelInfo)); - memcpy(resultRelInfos, parentestate->es_result_relations, - numResultRelations * sizeof(ResultRelInfo)); - rcestate->es_result_relations = resultRelInfos; - rcestate->es_num_result_relations = numResultRelations; - - /* Also transfer partitioned root result relations. */ - if (numRootResultRels > 0) - { - resultRelInfos = (ResultRelInfo *) - palloc(numRootResultRels * sizeof(ResultRelInfo)); - memcpy(resultRelInfos, parentestate->es_root_result_relations, - numRootResultRels * sizeof(ResultRelInfo)); - rcestate->es_root_result_relations = resultRelInfos; - rcestate->es_num_root_result_relations = numRootResultRels; - } - } - /* es_result_relation_info must NOT be copied */ + + /* + * ResultRelInfos needed by subplans are initialized from scratch when the + * subplans themselves are initialized. + */ + rcestate->es_result_relations = NULL; /* es_trig_target_relations must NOT be copied */ rcestate->es_top_eflags = parentestate->es_top_eflags; rcestate->es_instrument = parentestate->es_instrument; @@ -4014,8 +3947,9 @@ EvalPlanQualStart(EPQState *epqstate, Plan *planTree) * This is a cut-down version of ExecutorEnd(); basically we want to do most * of the normal cleanup, but *not* close result relations (which we are * just sharing from the outer query). We do, however, have to close any - * trigger target relations that got opened, since those are not shared. - * (There probably shouldn't be any of the latter, but just in case...) + * result and trigger target relations that got opened, since those are not + * shared. (There probably shouldn't be any of the latter, but just in + * case...) */ void EvalPlanQualEnd(EPQState *epqstate) @@ -4057,8 +3991,8 @@ EvalPlanQualEnd(EPQState *epqstate) /* throw away the per-estate tuple table, some node may have used it */ ExecResetTupleTable(estate->es_tupleTable, false); - /* close any trigger target relations attached to this EState */ - ExecCleanUpTriggerState(estate); + /* Close any result and trigger target relations attached to this EState */ + ExecCloseResultRelations(estate); MemoryContextSwitchTo(oldcontext); @@ -4142,6 +4076,7 @@ static void AdjustReplicatedTableCounts(EState *estate) { int i; + ListCell *l; ResultRelInfo *resultRelInfo; bool containReplicatedTable = false; int numsegments = 1; @@ -4150,9 +4085,9 @@ AdjustReplicatedTableCounts(EState *estate) return; /* check if result_relations contain replicated table*/ - for (i = 0; i < estate->es_num_result_relations; i++) + foreach(l, estate->es_opened_result_relations) { - resultRelInfo = estate->es_result_relations + i; + resultRelInfo = lfirst(l); if (!resultRelInfo->ri_RelationDesc->rd_cdbpolicy) continue; diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c index 6f14136eef25..671346e180f3 100644 --- a/src/backend/executor/execParallel.c +++ b/src/backend/executor/execParallel.c @@ -3,7 +3,7 @@ * execParallel.c * Support routines for parallel execution. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * This file contains routines that are intended to support setting up, @@ -35,6 +35,7 @@ #include "executor/nodeIncrementalSort.h" #include "executor/nodeIndexonlyscan.h" #include "executor/nodeIndexscan.h" +#include "executor/nodeResultCache.h" #include "executor/nodeSeqscan.h" #include "executor/nodeSort.h" #include "executor/nodeSubplan.h" @@ -174,7 +175,7 @@ ExecSerializePlan(Plan *plan, EState *estate) */ pstmt = makeNode(PlannedStmt); pstmt->commandType = CMD_SELECT; - pstmt->queryId = UINT64CONST(0); + pstmt->queryId = pgstat_get_my_query_id(); pstmt->hasReturning = false; pstmt->hasModifyingCTE = false; pstmt->canSetTag = true; @@ -184,7 +185,6 @@ ExecSerializePlan(Plan *plan, EState *estate) pstmt->planTree = plan; pstmt->rtable = estate->es_range_table; pstmt->resultRelations = NIL; - pstmt->rootResultRelations = NIL; pstmt->appendRelations = NIL; /* @@ -293,6 +293,10 @@ ExecParallelEstimate(PlanState *planstate, ExecParallelEstimateContext *e) /* even when not parallel-aware, for EXPLAIN ANALYZE */ ExecAggEstimate((AggState *) planstate, e->pcxt); break; + case T_ResultCacheState: + /* even when not parallel-aware, for EXPLAIN ANALYZE */ + ExecResultCacheEstimate((ResultCacheState *) planstate, e->pcxt); + break; default: break; } @@ -516,6 +520,10 @@ ExecParallelInitializeDSM(PlanState *planstate, /* even when not parallel-aware, for EXPLAIN ANALYZE */ ExecAggInitializeDSM((AggState *) planstate, d->pcxt); break; + case T_ResultCacheState: + /* even when not parallel-aware, for EXPLAIN ANALYZE */ + ExecResultCacheInitializeDSM((ResultCacheState *) planstate, d->pcxt); + break; default: break; } @@ -992,6 +1000,7 @@ ExecParallelReInitializeDSM(PlanState *planstate, case T_HashState: case T_SortState: case T_IncrementalSortState: + case T_ResultCacheState: /* these nodes have DSM state, but no reinitialization is required */ break; @@ -1061,6 +1070,9 @@ ExecParallelRetrieveInstrumentation(PlanState *planstate, case T_AggState: ExecAggRetrieveInstrumentation((AggState *) planstate); break; + case T_ResultCacheState: + ExecResultCacheRetrieveInstrumentation((ResultCacheState *) planstate); + break; default: break; } @@ -1353,6 +1365,11 @@ ExecParallelInitializeWorker(PlanState *planstate, ParallelWorkerContext *pwcxt) /* even when not parallel-aware, for EXPLAIN ANALYZE */ ExecAggInitializeWorker((AggState *) planstate, pwcxt); break; + case T_ResultCacheState: + /* even when not parallel-aware, for EXPLAIN ANALYZE */ + ExecResultCacheInitializeWorker((ResultCacheState *) planstate, + pwcxt); + break; default: break; } @@ -1407,7 +1424,7 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc) /* Setting debug_query_string for individual workers */ debug_query_string = queryDesc->sourceText; - /* Report workers' query for monitoring purposes */ + /* Report workers' query and queryId for monitoring purposes */ pgstat_report_activity(STATE_RUNNING, debug_query_string); /* Attach to the dynamic shared memory area. */ diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 767f54368125..b260f277e66d 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -3,7 +3,7 @@ * execPartition.c * Support routines for partitioning. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -53,6 +53,11 @@ * PartitionDispatchData->indexes for details on how this array is * indexed. * + * nonleaf_partitions + * Array of 'max_dispatch' elements containing pointers to fake + * ResultRelInfo objects for nonleaf partitions, useful for checking + * the partition constraint. + * * num_dispatch * The current number of items stored in the 'partition_dispatch_info' * array. Also serves as the index of the next free array element for @@ -63,11 +68,17 @@ * * partitions * Array of 'max_partitions' elements containing a pointer to a - * ResultRelInfo for every leaf partitions touched by tuple routing. + * ResultRelInfo for every leaf partition touched by tuple routing. * Some of these are pointers to ResultRelInfos which are borrowed out of - * 'subplan_resultrel_htab'. The remainder have been built especially - * for tuple routing. See comment for PartitionDispatchData->indexes for - * details on how this array is indexed. + * the owning ModifyTableState node. The remainder have been built + * especially for tuple routing. See comment for + * PartitionDispatchData->indexes for details on how this array is + * indexed. + * + * is_borrowed_rel + * Array of 'max_partitions' booleans recording whether a given entry + * in 'partitions' is a ResultRelInfo pointer borrowed from the owning + * ModifyTableState node, rather than being built here. * * num_partitions * The current number of items stored in the 'partitions' array. Also @@ -77,12 +88,6 @@ * max_partitions * The current allocated size of the 'partitions' array. * - * subplan_resultrel_htab - * Hash table to store subplan ResultRelInfos by Oid. This is used to - * cache ResultRelInfos from subplans of an UPDATE ModifyTable node; - * NULL in other cases. Some of these may be useful for tuple routing - * to save having to build duplicates. - * * memcxt * Memory context used to allocate subsidiary structs. *----------------------- @@ -91,12 +96,13 @@ struct PartitionTupleRouting { Relation partition_root; PartitionDispatch *partition_dispatch_info; + ResultRelInfo **nonleaf_partitions; int num_dispatch; int max_dispatch; ResultRelInfo **partitions; + bool *is_borrowed_rel; int num_partitions; int max_partitions; - HTAB *subplan_resultrel_htab; MemoryContext memcxt; }; @@ -149,16 +155,7 @@ typedef struct PartitionDispatchData int indexes[FLEXIBLE_ARRAY_MEMBER]; } PartitionDispatchData; -/* struct to hold result relations coming from UPDATE subplans */ -typedef struct SubplanResultRelHashElem -{ - Oid relid; /* hash key -- must be first */ - ResultRelInfo *rri; -} SubplanResultRelHashElem; - -static void ExecHashSubPlanResultRelsByOid(ModifyTableState *mtstate, - PartitionTupleRouting *proute); static ResultRelInfo *ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, PartitionDispatch dispatch, @@ -169,10 +166,12 @@ static void ExecInitRoutingInfo(ModifyTableState *mtstate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *partRelInfo, - int partidx); + int partidx, + bool is_borrowed_rel); static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, PartitionTupleRouting *proute, - Oid partoid, PartitionDispatch parent_pd, int partidx); + Oid partoid, PartitionDispatch parent_pd, + int partidx, ResultRelInfo *rootResultRelInfo); static void FormPartitionKeyDatum(PartitionDispatch pd, TupleTableSlot *slot, EState *estate, @@ -183,7 +182,7 @@ static char *ExecBuildSlotPartitionKeyDescription(Relation rel, Datum *values, bool *isnull, int maxfieldlen); -static List *adjust_partition_tlist(List *tlist, TupleConversionMap *map); +static List *adjust_partition_colnos(List *colnos, ResultRelInfo *leaf_part_rri); static void ExecInitPruningContext(PartitionPruneContext *context, List *pruning_steps, PartitionDesc partdesc, @@ -209,11 +208,9 @@ static void find_matching_subplans_recurse(PartitionPruningData *prunedata, * it should be estate->es_query_cxt. */ PartitionTupleRouting * -ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, - Relation rel) +ExecSetupPartitionTupleRouting(EState *estate, Relation rel) { PartitionTupleRouting *proute; - ModifyTable *node = mtstate ? (ModifyTable *) mtstate->ps.plan : NULL; /* * Here we attempt to expend as little effort as possible in setting up @@ -233,18 +230,7 @@ ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, * partitioned table. */ ExecInitPartitionDispatchInfo(estate, proute, RelationGetRelid(rel), - NULL, 0); - - /* - * If performing an UPDATE with tuple routing, we can reuse partition - * sub-plan result rels. We build a hash table to map the OIDs of - * partitions present in mtstate->resultRelInfo to their ResultRelInfos. - * Every time a tuple is routed to a partition that we've yet to set the - * ResultRelInfo for, before we go to the trouble of making one, we check - * for a pre-made one in the hash table. - */ - if (node && node->operation == CMD_UPDATE) - ExecHashSubPlanResultRelsByOid(mtstate, proute); + NULL, 0, NULL); return proute; } @@ -256,7 +242,7 @@ ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, * If the partition's ResultRelInfo does not yet exist in 'proute' then we set * one up or reuse one from mtstate's resultRelInfo array. When reusing a * ResultRelInfo from the mtstate we verify that the relation is a valid - * target for INSERTs and then set up a PartitionRoutingInfo for it. + * target for INSERTs and initialize tuple routing information. * * rootResultRelInfo is the relation named in the query. * @@ -281,9 +267,11 @@ ExecFindPartition(ModifyTableState *mtstate, PartitionDispatch dispatch; PartitionDesc partdesc; ExprContext *ecxt = GetPerTupleExprContext(estate); - TupleTableSlot *ecxt_scantuple_old = ecxt->ecxt_scantuple; + TupleTableSlot *ecxt_scantuple_saved = ecxt->ecxt_scantuple; + TupleTableSlot *rootslot = slot; TupleTableSlot *myslot = NULL; MemoryContext oldcxt; + ResultRelInfo *rri = NULL; /* use per-tuple context here to avoid leaking memory */ oldcxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); @@ -292,32 +280,21 @@ ExecFindPartition(ModifyTableState *mtstate, * First check the root table's partition constraint, if any. No point in * routing the tuple if it doesn't belong in the root table itself. */ - if (rootResultRelInfo->ri_PartitionCheck) + if (rootResultRelInfo->ri_RelationDesc->rd_rel->relispartition) ExecPartitionCheck(rootResultRelInfo, slot, estate, true); /* start with the root partitioned table */ dispatch = pd[0]; - while (true) + while (dispatch != NULL) { - AttrMap *map = dispatch->tupmap; int partidx = -1; + bool is_leaf; CHECK_FOR_INTERRUPTS(); rel = dispatch->reldesc; partdesc = dispatch->partdesc; - /* - * Convert the tuple to this parent's layout, if different from the - * current relation. - */ - myslot = dispatch->tupslot; - if (myslot != NULL) - { - Assert(map != NULL); - slot = execute_attr_map_slot(map, slot, myslot); - } - /* * Extract partition key from tuple. Expression evaluation machinery * that FormPartitionKeyDatum() invokes expects ecxt_scantuple to @@ -357,13 +334,12 @@ ExecFindPartition(ModifyTableState *mtstate, errtable(rel))); } - if (partdesc->is_leaf[partidx]) + is_leaf = partdesc->is_leaf[partidx]; + if (is_leaf) { - ResultRelInfo *rri; - /* - * Look to see if we've already got a ResultRelInfo for this - * partition. + * We've reached the leaf -- hurray, we're done. Look to see if + * we've already got a ResultRelInfo for this partition. */ if (likely(dispatch->indexes[partidx] >= 0)) { @@ -373,48 +349,38 @@ ExecFindPartition(ModifyTableState *mtstate, } else { - bool found = false; - /* - * We have not yet set up a ResultRelInfo for this partition, - * but if we have a subplan hash table, we might have one - * there. If not, we'll have to create one. + * If the partition is known in the owning ModifyTableState + * node, we can re-use that ResultRelInfo instead of creating + * a new one with ExecInitPartitionInfo(). */ - if (proute->subplan_resultrel_htab) + rri = ExecLookupResultRelByOid(mtstate, + partdesc->oids[partidx], + true, false); + if (rri) { - Oid partoid = partdesc->oids[partidx]; - SubplanResultRelHashElem *elem; - - elem = hash_search(proute->subplan_resultrel_htab, - &partoid, HASH_FIND, NULL); - if (elem) - { - found = true; - rri = elem->rri; - - /* Verify this ResultRelInfo allows INSERTs */ - CheckValidResultRel(rri, CMD_INSERT); + /* Verify this ResultRelInfo allows INSERTs */ + CheckValidResultRel(rri, CMD_INSERT); - /* Set up the PartitionRoutingInfo for it */ - ExecInitRoutingInfo(mtstate, estate, proute, dispatch, - rri, partidx); - } + /* + * Initialize information needed to insert this and + * subsequent tuples routed to this partition. + */ + ExecInitRoutingInfo(mtstate, estate, proute, dispatch, + rri, partidx, true); } - - /* We need to create a new one. */ - if (!found) + else + { + /* We need to create a new one. */ rri = ExecInitPartitionInfo(mtstate, estate, proute, dispatch, rootResultRelInfo, partidx); + } } + Assert(rri != NULL); - /* Release the tuple in the lowest parent's dedicated slot. */ - if (slot == myslot) - ExecClearTuple(myslot); - - MemoryContextSwitchTo(oldcxt); - ecxt->ecxt_scantuple = ecxt_scantuple_old; - return rri; + /* Signal to terminate the loop */ + dispatch = NULL; } else { @@ -426,6 +392,8 @@ ExecFindPartition(ModifyTableState *mtstate, /* Already built. */ Assert(dispatch->indexes[partidx] < proute->num_dispatch); + rri = proute->nonleaf_partitions[dispatch->indexes[partidx]]; + /* * Move down to the next partition level and search again * until we find a leaf partition that matches this tuple @@ -441,61 +409,80 @@ ExecFindPartition(ModifyTableState *mtstate, * Create the new PartitionDispatch. We pass the current one * in as the parent PartitionDispatch */ - subdispatch = ExecInitPartitionDispatchInfo(mtstate->ps.state, + subdispatch = ExecInitPartitionDispatchInfo(estate, proute, partdesc->oids[partidx], - dispatch, partidx); + dispatch, partidx, + mtstate->rootResultRelInfo); Assert(dispatch->indexes[partidx] >= 0 && dispatch->indexes[partidx] < proute->num_dispatch); + + rri = proute->nonleaf_partitions[dispatch->indexes[partidx]]; dispatch = subdispatch; } - } - } -} - -/* - * ExecHashSubPlanResultRelsByOid - * Build a hash table to allow fast lookups of subplan ResultRelInfos by - * partition Oid. We also populate the subplan ResultRelInfo with an - * ri_PartitionRoot. - */ -static void -ExecHashSubPlanResultRelsByOid(ModifyTableState *mtstate, - PartitionTupleRouting *proute) -{ - HASHCTL ctl; - HTAB *htab; - int i; - - memset(&ctl, 0, sizeof(ctl)); - ctl.keysize = sizeof(Oid); - ctl.entrysize = sizeof(SubplanResultRelHashElem); - ctl.hcxt = CurrentMemoryContext; - htab = hash_create("PartitionTupleRouting table", mtstate->mt_nplans, - &ctl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); - proute->subplan_resultrel_htab = htab; + /* + * Convert the tuple to the new parent's layout, if different from + * the previous parent. + */ + if (dispatch->tupslot) + { + AttrMap *map = dispatch->tupmap; + TupleTableSlot *tempslot = myslot; - /* Hash all subplans by their Oid */ - for (i = 0; i < mtstate->mt_nplans; i++) - { - ResultRelInfo *rri = &mtstate->resultRelInfo[i]; - bool found; - Oid partoid = RelationGetRelid(rri->ri_RelationDesc); - SubplanResultRelHashElem *elem; + myslot = dispatch->tupslot; + slot = execute_attr_map_slot(map, slot, myslot); - elem = (SubplanResultRelHashElem *) - hash_search(htab, &partoid, HASH_ENTER, &found); - Assert(!found); - elem->rri = rri; + if (tempslot != NULL) + ExecClearTuple(tempslot); + } + } /* - * This is required in order to convert the partition's tuple to be - * compatible with the root partitioned table's tuple descriptor. When - * generating the per-subplan result rels, this was not set. + * If this partition is the default one, we must check its partition + * constraint now, which may have changed concurrently due to + * partitions being added to the parent. + * + * (We do this here, and do not rely on ExecInsert doing it, because + * we don't want to miss doing it for non-leaf partitions.) */ - rri->ri_PartitionRoot = proute->partition_root; + if (partidx == partdesc->boundinfo->default_index) + { + /* + * The tuple must match the partition's layout for the constraint + * expression to be evaluated successfully. If the partition is + * sub-partitioned, that would already be the case due to the code + * above, but for a leaf partition the tuple still matches the + * parent's layout. + * + * Note that we have a map to convert from root to current + * partition, but not from immediate parent to current partition. + * So if we have to convert, do it from the root slot; if not, use + * the root slot as-is. + */ + if (is_leaf) + { + TupleConversionMap *map = rri->ri_RootToPartitionMap; + + if (map) + slot = execute_attr_map_slot(map->attrMap, rootslot, + rri->ri_PartitionTupleSlot); + else + slot = rootslot; + } + + ExecPartitionCheck(rri, slot, estate, true); + } } + + /* Release the tuple in the lowest parent's dedicated slot. */ + if (myslot != NULL) + ExecClearTuple(myslot); + /* and restore ecxt's scantuple */ + ecxt->ecxt_scantuple = ecxt_scantuple_saved; + MemoryContextSwitchTo(oldcxt); + + return rri; } /* @@ -514,8 +501,9 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, int partidx) { ModifyTable *node = (ModifyTable *) mtstate->ps.plan; - Relation rootrel = rootResultRelInfo->ri_RelationDesc, - partrel; + Oid partOid = dispatch->partdesc->oids[partidx]; + Relation partrel; + int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; Relation firstResultRel = mtstate->resultRelInfo[0].ri_RelationDesc; ResultRelInfo *leaf_part_rri; MemoryContext oldcxt; @@ -524,13 +512,13 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, oldcxt = MemoryContextSwitchTo(proute->memcxt); - partrel = table_open(dispatch->partdesc->oids[partidx], RowExclusiveLock); + partrel = table_open(partOid, RowExclusiveLock); leaf_part_rri = makeNode(ResultRelInfo); InitResultRelInfo(leaf_part_rri, partrel, - node ? node->rootRelation : 1, - rootrel, + 0, + rootResultRelInfo, estate->es_instrument); /* @@ -557,14 +545,13 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, * didn't build the withCheckOptionList for partitions within the planner, * but simple translation of varattnos will suffice. This only occurs for * the INSERT case or in the case of UPDATE tuple routing where we didn't - * find a result rel to reuse in ExecSetupPartitionTupleRouting(). + * find a result rel to reuse. */ if (node && node->withCheckOptionLists != NIL) { List *wcoList; List *wcoExprs = NIL; ListCell *ll; - int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; /* * In the case of INSERT on a partitioned table, there is only one @@ -573,10 +560,10 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, */ Assert((node->operation == CMD_INSERT && list_length(node->withCheckOptionLists) == 1 && - list_length(node->plans) == 1) || + list_length(node->resultRelations) == 1) || (node->operation == CMD_UPDATE && list_length(node->withCheckOptionLists) == - list_length(node->plans))); + list_length(node->resultRelations))); /* * Use the WCO list of the first plan as a reference to calculate @@ -621,22 +608,21 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, * build the returningList for partitions within the planner, but simple * translation of varattnos will suffice. This only occurs for the INSERT * case or in the case of UPDATE tuple routing where we didn't find a - * result rel to reuse in ExecSetupPartitionTupleRouting(). + * result rel to reuse. */ if (node && node->returningLists != NIL) { TupleTableSlot *slot; ExprContext *econtext; List *returningList; - int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; /* See the comment above for WCO lists. */ Assert((node->operation == CMD_INSERT && list_length(node->returningLists) == 1 && - list_length(node->plans) == 1) || + list_length(node->resultRelations) == 1) || (node->operation == CMD_UPDATE && list_length(node->returningLists) == - list_length(node->plans))); + list_length(node->resultRelations))); /* * Use the RETURNING list of the first plan as a reference to @@ -680,14 +666,13 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, /* Set up information needed for routing tuples to the partition. */ ExecInitRoutingInfo(mtstate, estate, proute, dispatch, - leaf_part_rri, partidx); + leaf_part_rri, partidx, false); /* * If there is an ON CONFLICT clause, initialize state for it. */ if (node && node->onConflictAction != ONCONFLICT_NONE) { - int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; TupleDesc partrelDesc = RelationGetDescr(partrel); ExprContext *econtext = mtstate->ps.ps_ExprContext; ListCell *lc; @@ -736,21 +721,22 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, */ if (node->onConflictAction == ONCONFLICT_UPDATE) { + OnConflictSetState *onconfl = makeNode(OnConflictSetState); TupleConversionMap *map; - map = leaf_part_rri->ri_PartitionInfo->pi_RootToPartitionMap; + map = leaf_part_rri->ri_RootToPartitionMap; Assert(node->onConflictSet != NIL); Assert(rootResultRelInfo->ri_onConflict != NULL); - leaf_part_rri->ri_onConflict = makeNode(OnConflictSetState); + leaf_part_rri->ri_onConflict = onconfl; /* * Need a separate existing slot for each partition, as the * partition could be of a different AM, even if the tuple * descriptors match. */ - leaf_part_rri->ri_onConflict->oc_Existing = + onconfl->oc_Existing = table_slot_create(leaf_part_rri->ri_RelationDesc, &mtstate->ps.state->es_tupleTable); @@ -770,17 +756,17 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, * Projections and where clauses themselves don't store state * / are independent of the underlying storage. */ - leaf_part_rri->ri_onConflict->oc_ProjSlot = + onconfl->oc_ProjSlot = rootResultRelInfo->ri_onConflict->oc_ProjSlot; - leaf_part_rri->ri_onConflict->oc_ProjInfo = + onconfl->oc_ProjInfo = rootResultRelInfo->ri_onConflict->oc_ProjInfo; - leaf_part_rri->ri_onConflict->oc_WhereClause = + onconfl->oc_WhereClause = rootResultRelInfo->ri_onConflict->oc_WhereClause; } else { List *onconflset; - TupleDesc tupDesc; + List *onconflcols; bool found_whole_row; /* @@ -790,7 +776,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, * pseudo-relation (INNER_VAR), and second to handle the main * target relation (firstVarno). */ - onconflset = (List *) copyObject((Node *) node->onConflictSet); + onconflset = copyObject(node->onConflictSet); if (part_attmap == NULL) part_attmap = build_attrmap_by_name(RelationGetDescr(partrel), @@ -810,20 +796,24 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, &found_whole_row); /* We ignore the value of found_whole_row. */ - /* Finally, adjust this tlist to match the partition. */ - onconflset = adjust_partition_tlist(onconflset, map); + /* Finally, adjust the target colnos to match the partition. */ + onconflcols = adjust_partition_colnos(node->onConflictCols, + leaf_part_rri); /* create the tuple slot for the UPDATE SET projection */ - tupDesc = ExecTypeFromTL(onconflset); - leaf_part_rri->ri_onConflict->oc_ProjSlot = - ExecInitExtraTupleSlot(mtstate->ps.state, tupDesc, - &TTSOpsVirtual); + onconfl->oc_ProjSlot = + table_slot_create(partrel, + &mtstate->ps.state->es_tupleTable); /* build UPDATE SET projection state */ - leaf_part_rri->ri_onConflict->oc_ProjInfo = - ExecBuildProjectionInfo(onconflset, econtext, - leaf_part_rri->ri_onConflict->oc_ProjSlot, - &mtstate->ps, partrelDesc); + onconfl->oc_ProjInfo = + ExecBuildUpdateProjection(onconflset, + true, + onconflcols, + partrelDesc, + econtext, + onconfl->oc_ProjSlot, + &mtstate->ps); /* * If there is a WHERE clause, initialize state where it will @@ -850,7 +840,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, RelationGetForm(partrel)->reltype, &found_whole_row); /* We ignore the value of found_whole_row. */ - leaf_part_rri->ri_onConflict->oc_WhereClause = + onconfl->oc_WhereClause = ExecInitQual((List *) clause, &mtstate->ps); } } @@ -890,22 +880,21 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *partRelInfo, - int partidx) + int partidx, + bool is_borrowed_rel) { + ResultRelInfo *rootRelInfo = partRelInfo->ri_RootResultRelInfo; MemoryContext oldcxt; - PartitionRoutingInfo *partrouteinfo; int rri_index; oldcxt = MemoryContextSwitchTo(proute->memcxt); - partrouteinfo = palloc(sizeof(PartitionRoutingInfo)); - /* * Set up a tuple conversion map to convert a tuple routed to the * partition from the parent's type to the partition's. */ - partrouteinfo->pi_RootToPartitionMap = - convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot), + partRelInfo->ri_RootToPartitionMap = + convert_tuples_by_name(RelationGetDescr(rootRelInfo->ri_RelationDesc), RelationGetDescr(partRelInfo->ri_RelationDesc)); /* @@ -914,7 +903,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, * for various operations that are applied to tuples after routing, such * as checking constraints. */ - if (partrouteinfo->pi_RootToPartitionMap != NULL) + if (partRelInfo->ri_RootToPartitionMap != NULL) { Relation partrel = partRelInfo->ri_RelationDesc; @@ -923,25 +912,11 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, * partition's TupleDesc; TupleDesc reference will be released at the * end of the command. */ - partrouteinfo->pi_PartitionTupleSlot = + partRelInfo->ri_PartitionTupleSlot = table_slot_create(partrel, &estate->es_tupleTable); } else - partrouteinfo->pi_PartitionTupleSlot = NULL; - - /* - * Also, if transition capture is required, store a map to convert tuples - * from partition's rowtype to the root partition table's. - */ - if (mtstate && - (mtstate->mt_transition_capture || mtstate->mt_oc_transition_capture)) - { - partrouteinfo->pi_PartitionToRootMap = - convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_RelationDesc), - RelationGetDescr(partRelInfo->ri_PartitionRoot)); - } - else - partrouteinfo->pi_PartitionToRootMap = NULL; + partRelInfo->ri_PartitionTupleSlot = NULL; /* * If the partition is a foreign table, let the FDW init itself for @@ -951,7 +926,24 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, partRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL) partRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate, partRelInfo); - partRelInfo->ri_PartitionInfo = partrouteinfo; + /* + * Determine if the FDW supports batch insert and determine the batch size + * (a FDW may support batching, but it may be disabled for the + * server/table or for this particular query). + * + * If the FDW does not support batching, we set the batch size to 1. + */ + if (mtstate->operation == CMD_INSERT && + partRelInfo->ri_FdwRoutine != NULL && + partRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize && + partRelInfo->ri_FdwRoutine->ExecForeignBatchInsert) + partRelInfo->ri_BatchSize = + partRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize(partRelInfo); + else + partRelInfo->ri_BatchSize = 1; + + Assert(partRelInfo->ri_BatchSize >= 1); + partRelInfo->ri_CopyMultiInsertBuffer = NULL; /* @@ -969,6 +961,8 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, proute->max_partitions = 8; proute->partitions = (ResultRelInfo **) palloc(sizeof(ResultRelInfo *) * proute->max_partitions); + proute->is_borrowed_rel = (bool *) + palloc(sizeof(bool) * proute->max_partitions); } else { @@ -976,10 +970,14 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, proute->partitions = (ResultRelInfo **) repalloc(proute->partitions, sizeof(ResultRelInfo *) * proute->max_partitions); + proute->is_borrowed_rel = (bool *) + repalloc(proute->is_borrowed_rel, sizeof(bool) * + proute->max_partitions); } } proute->partitions[rri_index] = partRelInfo; + proute->is_borrowed_rel[rri_index] = is_borrowed_rel; dispatch->indexes[partidx] = rri_index; MemoryContextSwitchTo(oldcxt); @@ -997,7 +995,8 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, PartitionTupleRouting *proute, Oid partoid, - PartitionDispatch parent_pd, int partidx) + PartitionDispatch parent_pd, int partidx, + ResultRelInfo *rootResultRelInfo) { Relation rel; PartitionDesc partdesc; @@ -1005,9 +1004,18 @@ ExecInitPartitionDispatchInfo(EState *estate, int dispatchidx; MemoryContext oldcxt; + /* + * For data modification, it is better that executor does not include + * partitions being detached, except when running in snapshot-isolation + * mode. This means that a read-committed transaction immediately gets a + * "no partition for tuple" error when a tuple is inserted into a + * partition that's being detached concurrently, but a transaction in + * repeatable-read mode can still use such a partition. + */ if (estate->es_partition_directory == NULL) estate->es_partition_directory = - CreatePartitionDirectory(estate->es_query_cxt); + CreatePartitionDirectory(estate->es_query_cxt, + !IsolationUsesXactSnapshot()); oldcxt = MemoryContextSwitchTo(proute->memcxt); @@ -1070,6 +1078,8 @@ ExecInitPartitionDispatchInfo(EState *estate, proute->max_dispatch = 4; proute->partition_dispatch_info = (PartitionDispatch *) palloc(sizeof(PartitionDispatch) * proute->max_dispatch); + proute->nonleaf_partitions = (ResultRelInfo **) + palloc(sizeof(ResultRelInfo *) * proute->max_dispatch); } else { @@ -1077,10 +1087,28 @@ ExecInitPartitionDispatchInfo(EState *estate, proute->partition_dispatch_info = (PartitionDispatch *) repalloc(proute->partition_dispatch_info, sizeof(PartitionDispatch) * proute->max_dispatch); + proute->nonleaf_partitions = (ResultRelInfo **) + repalloc(proute->nonleaf_partitions, + sizeof(ResultRelInfo *) * proute->max_dispatch); } } proute->partition_dispatch_info[dispatchidx] = pd; + /* + * If setting up a PartitionDispatch for a sub-partitioned table, we may + * also need a minimally valid ResultRelInfo for checking the partition + * constraint later; set that up now. + */ + if (parent_pd) + { + ResultRelInfo *rri = makeNode(ResultRelInfo); + + InitResultRelInfo(rri, rel, 0, rootResultRelInfo, 0); + proute->nonleaf_partitions[dispatchidx] = rri; + } + else + proute->nonleaf_partitions[dispatchidx] = NULL; + /* * Finally, if setting up a PartitionDispatch for a sub-partitioned table, * install a downlink in the parent to allow quick descent. @@ -1106,7 +1134,6 @@ void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute) { - HTAB *htab = proute->subplan_resultrel_htab; int i; /* @@ -1137,20 +1164,11 @@ ExecCleanupTupleRouting(ModifyTableState *mtstate, resultRelInfo); /* - * Check if this result rel is one belonging to the node's subplans, - * if so, let ExecEndPlan() clean it up. + * Close it if it's not one of the result relations borrowed from the + * owning ModifyTableState; those will be closed by ExecEndPlan(). */ - if (htab) - { - Oid partoid; - bool found; - - partoid = RelationGetRelid(resultRelInfo->ri_RelationDesc); - - (void) hash_search(htab, &partoid, HASH_FIND, &found); - if (found) - continue; - } + if (proute->is_borrowed_rel[i]) + continue; if (resultRelInfo->ri_RelationDesc->rd_tableam) table_dml_finish(resultRelInfo->ri_RelationDesc); @@ -1249,16 +1267,14 @@ get_partition_for_tuple(PartitionKey key, PartitionDesc partdesc, Datum *values, { case PARTITION_STRATEGY_HASH: { - int greatest_modulus; uint64 rowHash; - greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); rowHash = compute_partition_hash_value(key->partnatts, key->partsupfunc, key->partcollation, values, isnull); - part_index = boundinfo->indexes[rowHash % greatest_modulus]; + part_index = boundinfo->indexes[rowHash % boundinfo->nindexes]; } break; @@ -1424,71 +1440,35 @@ ExecBuildSlotPartitionKeyDescription(Relation rel, } /* - * adjust_partition_tlist - * Adjust the targetlist entries for a given partition to account for - * attribute differences between parent and the partition - * - * The expressions have already been fixed, but here we fix the list to make - * target resnos match the partition's attribute numbers. This results in a - * copy of the original target list in which the entries appear in resno - * order, including both the existing entries (that may have their resno - * changed in-place) and the newly added entries for columns that don't exist - * in the parent. - * - * Scribbles on the input tlist, so callers must make sure to make a copy - * before passing it to us. + * adjust_partition_colnos + * Adjust the list of UPDATE target column numbers to account for + * attribute differences between the parent and the partition. */ static List * -adjust_partition_tlist(List *tlist, TupleConversionMap *map) +adjust_partition_colnos(List *colnos, ResultRelInfo *leaf_part_rri) { - List *new_tlist = NIL; - TupleDesc tupdesc = map->outdesc; - AttrMap *attrMap = map->attrMap; - AttrNumber attrno; - - Assert(tupdesc->natts == attrMap->maplen); - for (attrno = 1; attrno <= tupdesc->natts; attrno++) - { - Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1); - TargetEntry *tle; - - if (attrMap->attnums[attrno - 1] != InvalidAttrNumber) - { - Assert(!att_tup->attisdropped); - - /* - * Use the corresponding entry from the parent's tlist, adjusting - * the resno the match the partition's attno. - */ - tle = (TargetEntry *) list_nth(tlist, attrMap->attnums[attrno - 1] - 1); - tle->resno = attrno; - } - else - { - Const *expr; + List *new_colnos = NIL; + TupleConversionMap *map = ExecGetChildToRootMap(leaf_part_rri); + AttrMap *attrMap; + ListCell *lc; - /* - * For a dropped attribute in the partition, generate a dummy - * entry with resno matching the partition's attno. - */ - Assert(att_tup->attisdropped); - expr = makeConst(INT4OID, - -1, - InvalidOid, - sizeof(int32), - (Datum) 0, - true, /* isnull */ - true /* byval */ ); - tle = makeTargetEntry((Expr *) expr, - attrno, - pstrdup(NameStr(att_tup->attname)), - false); - } + Assert(map != NULL); /* else we shouldn't be here */ + attrMap = map->attrMap; - new_tlist = lappend(new_tlist, tle); + foreach(lc, colnos) + { + AttrNumber parentattrno = lfirst_int(lc); + + if (parentattrno <= 0 || + parentattrno > attrMap->maplen || + attrMap->attnums[parentattrno - 1] == 0) + elog(ERROR, "unexpected attno %d in target column list", + parentattrno); + new_colnos = lappend_int(new_colnos, + attrMap->attnums[parentattrno - 1]); } - return new_tlist; + return new_colnos; } /*------------------------------------------------------------------------- @@ -1571,9 +1551,10 @@ ExecCreatePartitionPruneState(PlanState *planstate, ListCell *lc; int i; + /* For data reading, executor always omits detached partitions */ if (estate->es_partition_directory == NULL) estate->es_partition_directory = - CreatePartitionDirectory(estate->es_query_cxt); + CreatePartitionDirectory(estate->es_query_cxt, false); n_part_hierarchies = list_length(partitionpruneinfo->prune_infos); Assert(n_part_hierarchies > 0); @@ -1639,9 +1620,12 @@ ExecCreatePartitionPruneState(PlanState *planstate, partrel); /* - * Initialize the subplan_map and subpart_map. Since detaching a - * partition requires AccessExclusiveLock, no partitions can have - * disappeared, nor can the bounds for any partition have changed. + * Initialize the subplan_map and subpart_map. + * + * Because we request detached partitions to be included, and + * detaching waits for old transactions, it is safe to assume that + * no partitions have disappeared since this query was planned. + * * However, new partitions may have been added. */ Assert(partdesc->nparts >= pinfo->nparts); diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 8fda7481720a..cad3aef35661 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -9,7 +9,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -105,6 +105,7 @@ #include "executor/nodeProjectSet.h" #include "executor/nodeRecursiveunion.h" #include "executor/nodeResult.h" +#include "executor/nodeResultCache.h" #include "executor/nodeSamplescan.h" #include "executor/nodeSeqscan.h" #include "executor/nodeSetOp.h" @@ -112,6 +113,7 @@ #include "executor/nodeSubplan.h" #include "executor/nodeSubqueryscan.h" #include "executor/nodeTableFuncscan.h" +#include "executor/nodeTidrangescan.h" #include "executor/nodeTidscan.h" #include "executor/nodeTupleSplit.h" #include "executor/nodeUnique.h" @@ -328,6 +330,11 @@ ExecInitNode(Plan *node, EState *estate, int eflags) estate, eflags); break; + case T_TidRangeScan: + result = (PlanState *) ExecInitTidRangeScan((TidRangeScan *) node, + estate, eflags); + break; + case T_SubqueryScan: result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node, estate, eflags); @@ -427,6 +434,11 @@ ExecInitNode(Plan *node, EState *estate, int eflags) break; #ifdef NOT_USED /* Group nodes are not used in GPDB */ + case T_ResultCache: + result = (PlanState *) ExecInitResultCache((ResultCache *) node, + estate, eflags); + break; + case T_Group: result = (PlanState *) ExecInitGroup((Group *) node, estate, eflags); @@ -883,6 +895,10 @@ ExecEndNode(PlanState *node) ExecEndTidScan((TidScanState *) node); break; + case T_TidRangeScanState: + ExecEndTidRangeScan((TidRangeScanState *) node); + break; + case T_SubqueryScanState: ExecEndSubqueryScan((SubqueryScanState *) node); break; @@ -961,6 +977,10 @@ ExecEndNode(PlanState *node) break; #ifdef NOT_USED /* GroupState nodes are not used in GPDB */ + case T_ResultCacheState: + ExecEndResultCache((ResultCacheState *) node); + break; + case T_GroupState: ExecEndGroup((GroupState *) node); break; @@ -1211,10 +1231,7 @@ planstate_walk_kids(PlanState *planstate, case T_ModifyTableState: { - ModifyTableState *mts = (ModifyTableState *) planstate; - - v = planstate_walk_array(mts->mt_plans, mts->mt_nplans, walker, context, flags); - Assert(!planstate->lefttree && !planstate->righttree); + v = planstate_walk_node_extended(planstate->lefttree, walker, context, flags); break; } diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index 69d100ddc9d9..f9277c1d80d9 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -3,7 +3,7 @@ * execReplication.c * miscellaneous executor routines for logical replication * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -404,10 +404,10 @@ RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, * Caller is responsible for opening the indexes. */ void -ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot) +ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo, + EState *estate, TupleTableSlot *slot) { bool skip_tuple = false; - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; Relation rel = resultRelInfo->ri_RelationDesc; /* For now we support only tables. */ @@ -430,20 +430,22 @@ ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot) /* Compute stored generated columns */ if (rel->rd_att->constr && rel->rd_att->constr->has_generated_stored) - ExecComputeStoredGenerated(estate, slot, CMD_INSERT); + ExecComputeStoredGenerated(resultRelInfo, estate, slot, + CMD_INSERT); /* Check the constraints of the tuple */ if (rel->rd_att->constr) ExecConstraints(resultRelInfo, slot, estate); - if (resultRelInfo->ri_PartitionCheck) + if (rel->rd_rel->relispartition) ExecPartitionCheck(resultRelInfo, slot, estate, true); /* OK, store the tuple and create index entries for it */ simple_table_tuple_insert(resultRelInfo->ri_RelationDesc, slot); if (resultRelInfo->ri_NumIndices > 0) - recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, - NIL); + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, + slot, estate, false, false, + NULL, NIL); /* AFTER ROW INSERT Triggers */ ExecARInsertTriggers(estate, resultRelInfo, slot, @@ -466,11 +468,11 @@ ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot) * Caller is responsible for opening the indexes. */ void -ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, +ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo, + EState *estate, EPQState *epqstate, TupleTableSlot *searchslot, TupleTableSlot *slot) { bool skip_tuple = false; - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; Relation rel = resultRelInfo->ri_RelationDesc; ItemPointer tid = &(searchslot->tts_tid); @@ -496,20 +498,22 @@ ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, /* Compute stored generated columns */ if (rel->rd_att->constr && rel->rd_att->constr->has_generated_stored) - ExecComputeStoredGenerated(estate, slot, CMD_UPDATE); + ExecComputeStoredGenerated(resultRelInfo, estate, slot, + CMD_UPDATE); /* Check the constraints of the tuple */ if (rel->rd_att->constr) ExecConstraints(resultRelInfo, slot, estate); - if (resultRelInfo->ri_PartitionCheck) + if (rel->rd_rel->relispartition) ExecPartitionCheck(resultRelInfo, slot, estate, true); simple_table_tuple_update(rel, tid, slot, estate->es_snapshot, &update_indexes); if (resultRelInfo->ri_NumIndices > 0 && update_indexes) - recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, - NIL); + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, + slot, estate, true, false, + NULL, NIL); /* AFTER ROW UPDATE Triggers */ ExecARUpdateTriggers(estate, resultRelInfo, @@ -527,11 +531,11 @@ ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, * Caller is responsible for opening the indexes. */ void -ExecSimpleRelationDelete(EState *estate, EPQState *epqstate, +ExecSimpleRelationDelete(ResultRelInfo *resultRelInfo, + EState *estate, EPQState *epqstate, TupleTableSlot *searchslot) { bool skip_tuple = false; - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; Relation rel = resultRelInfo->ri_RelationDesc; ItemPointer tid = &searchslot->tts_tid; diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c index fa2ac8a18173..4f6723db9986 100644 --- a/src/backend/executor/execSRF.c +++ b/src/backend/executor/execSRF.c @@ -7,7 +7,7 @@ * common code for calling set-returning functions according to the * ReturnSetInfo API. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -357,11 +357,21 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, */ if (rsinfo.isDone != ExprMultipleResult) break; + + /* + * Check that set-returning functions were properly declared. + * (Note: for historical reasons, we don't complain if a non-SRF + * returns ExprEndResult; that's treated as returning NULL.) + */ + if (!returnsSet) + ereport(ERROR, + (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED), + errmsg("table-function protocol for value-per-call mode was not followed"))); } else if (rsinfo.returnMode == SFRM_Materialize) { /* check we're on the same page as the function author */ - if (!first_time || rsinfo.isDone != ExprSingleResult) + if (!first_time || rsinfo.isDone != ExprSingleResult || !returnsSet) ereport(ERROR, (errcode(ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED), errmsg("table-function protocol for materialize mode was not followed"))); diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c index a8149589ced4..fb10cccdc314 100644 --- a/src/backend/executor/execScan.c +++ b/src/backend/executor/execScan.c @@ -7,7 +7,7 @@ * stuff - checking the qualification and projecting the tuple * appropriately. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index f336528cbde2..9a6011506270 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -46,7 +46,7 @@ * to avoid physically constructing projection tuples in many cases. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -124,9 +124,8 @@ tts_virtual_clear(TupleTableSlot *slot) } /* - * Attribute values are readily available in tts_values and tts_isnull array - * in a VirtualTupleTableSlot. So there should be no need to call either of the - * following two functions. + * VirtualTupleTableSlots always have fully populated tts_values and + * tts_isnull arrays. So this function should never be called. */ static void tts_virtual_getsomeattrs(TupleTableSlot *slot, int natts) @@ -134,6 +133,11 @@ tts_virtual_getsomeattrs(TupleTableSlot *slot, int natts) elog(ERROR, "getsomeattrs is not required to be called on a virtual tuple table slot"); } +/* + * VirtualTupleTableSlots never provide system attributes (except those + * handled generically, such as tableoid). We generally shouldn't get + * here, but provide a user-friendly message if we do. + */ static Datum tts_virtual_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) { @@ -150,6 +154,11 @@ tts_virtual_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) } elog(ERROR, "virtual tuple table slot does not have system attributes"); + Assert(!TTS_EMPTY(slot)); + + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot retrieve a system column in this context"))); return 0; /* silence compiler warnings */ } @@ -349,6 +358,15 @@ tts_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) Assert(!TTS_EMPTY(slot)); + /* + * In some code paths it's possible to get here with a non-materialized + * slot, in which case we can't retrieve system columns. + */ + if (!hslot->tuple) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot retrieve a system column in this context"))); + return heap_getsysattr(hslot->tuple, attnum, slot->tts_tupleDescriptor, isnull); } @@ -511,7 +529,11 @@ tts_minimal_getsomeattrs(TupleTableSlot *slot, int natts) static Datum tts_minimal_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) { - elog(ERROR, "minimal tuple table slot does not have system attributes"); + Assert(!TTS_EMPTY(slot)); + + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot retrieve a system column in this context"))); return 0; /* silence compiler warnings */ } @@ -695,6 +717,15 @@ tts_buffer_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) Assert(!TTS_EMPTY(slot)); + /* + * In some code paths it's possible to get here with a non-materialized + * slot, in which case we can't retrieve system columns. + */ + if (!bslot->base.tuple) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot retrieve a system column in this context"))); + return heap_getsysattr(bslot->base.tuple, attnum, slot->tts_tupleDescriptor, isnull); } diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index d708f70db9b7..721fc8b0fb6a 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -59,6 +59,7 @@ #include "executor/execdebug.h" #include "executor/execUtils.h" #include "executor/executor.h" +#include "executor/execPartition.h" #include "jit/jit.h" #include "mb/pg_wchar.h" #include "miscadmin.h" @@ -157,14 +158,8 @@ CreateExecutorState(void) estate->es_output_cid = (CommandId) 0; estate->es_result_relations = NULL; - estate->es_num_result_relations = 0; - estate->es_result_relation_info = NULL; - - estate->es_root_result_relations = NULL; - estate->es_num_root_result_relations = 0; - + estate->es_opened_result_relations = NIL; estate->es_tuple_routing_result_relations = NIL; - estate->es_trig_target_relations = NIL; estate->es_param_list_info = NULL; @@ -765,16 +760,7 @@ ExecCreateScanSlotFromOuterPlan(EState *estate, bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid) { - ResultRelInfo *resultRelInfos; - int i; - - resultRelInfos = estate->es_result_relations; - for (i = 0; i < estate->es_num_result_relations; i++) - { - if (resultRelInfos[i].ri_RangeTableIndex == scanrelid) - return true; - } - return false; + return list_member_int(estate->es_plannedstmt->resultRelations, scanrelid); } /* ---------------------------------------------------------------- @@ -833,9 +819,10 @@ ExecInitRangeTable(EState *estate, List *rangeTable) palloc0(estate->es_range_table_size * sizeof(Relation)); /* - * es_rowmarks is also parallel to the es_range_table, but it's allocated - * only if needed. + * es_result_relations and es_rowmarks are also parallel to + * es_range_table, but are allocated only if needed. */ + estate->es_result_relations = NULL; estate->es_rowmarks = NULL; } @@ -891,6 +878,40 @@ ExecGetRangeTableRelation(EState *estate, Index rti) return rel; } +/* + * ExecInitResultRelation + * Open relation given by the passed-in RT index and fill its + * ResultRelInfo node + * + * Here, we also save the ResultRelInfo in estate->es_result_relations array + * such that it can be accessed later using the RT index. + */ +void +ExecInitResultRelation(EState *estate, ResultRelInfo *resultRelInfo, + Index rti) +{ + Relation resultRelationDesc; + + resultRelationDesc = ExecGetRangeTableRelation(estate, rti); + InitResultRelInfo(resultRelInfo, + resultRelationDesc, + rti, + NULL, + estate->es_instrument); + + if (estate->es_result_relations == NULL) + estate->es_result_relations = (ResultRelInfo **) + palloc0(estate->es_range_table_size * sizeof(ResultRelInfo *)); + estate->es_result_relations[rti - 1] = resultRelInfo; + + /* + * Saving in the list allows to avoid needlessly traversing the whole + * array when only a few of its entries are possibly non-NULL. + */ + estate->es_opened_result_relations = + lappend(estate->es_opened_result_relations, resultRelInfo); +} + /* * UpdateChangedParamSet * Add changed parameters to a plan node's chgParam set @@ -2366,3 +2387,128 @@ change_varattnos_of_a_varno(Node *node, const AttrMap *newattno, Index varno) (void) change_varattnos_varno_walker(node, &attrMapCxt); } + +/* + * Return the map needed to convert given child result relation's tuples to + * the rowtype of the query's main target ("root") relation. Note that a + * NULL result is valid and means that no conversion is needed. + */ +TupleConversionMap * +ExecGetChildToRootMap(ResultRelInfo *resultRelInfo) +{ + /* If we didn't already do so, compute the map for this child. */ + if (!resultRelInfo->ri_ChildToRootMapValid) + { + ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo; + + if (rootRelInfo) + resultRelInfo->ri_ChildToRootMap = + convert_tuples_by_name(RelationGetDescr(resultRelInfo->ri_RelationDesc), + RelationGetDescr(rootRelInfo->ri_RelationDesc)); + else /* this isn't a child result rel */ + resultRelInfo->ri_ChildToRootMap = NULL; + + resultRelInfo->ri_ChildToRootMapValid = true; + } + + return resultRelInfo->ri_ChildToRootMap; +} + +/* Return a bitmap representing columns being inserted */ +Bitmapset * +ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate) +{ + /* + * The columns are stored in the range table entry. If this ResultRelInfo + * represents a partition routing target, and doesn't have an entry of its + * own in the range table, fetch the parent's RTE and map the columns to + * the order they are in the partition. + */ + if (relinfo->ri_RangeTableIndex != 0) + { + RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); + + return rte->insertedCols; + } + else if (relinfo->ri_RootResultRelInfo) + { + ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; + RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + + if (relinfo->ri_RootToPartitionMap != NULL) + return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, + rte->insertedCols); + else + return rte->insertedCols; + } + else + { + /* + * The relation isn't in the range table and it isn't a partition + * routing target. This ResultRelInfo must've been created only for + * firing triggers and the relation is not being inserted into. (See + * ExecGetTriggerResultRel.) + */ + return NULL; + } +} + +/* Return a bitmap representing columns being updated */ +Bitmapset * +ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate) +{ + /* see ExecGetInsertedCols() */ + if (relinfo->ri_RangeTableIndex != 0) + { + RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); + + return rte->updatedCols; + } + else if (relinfo->ri_RootResultRelInfo) + { + ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; + RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + + if (relinfo->ri_RootToPartitionMap != NULL) + return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, + rte->updatedCols); + else + return rte->updatedCols; + } + else + return NULL; +} + +/* Return a bitmap representing generated columns being updated */ +Bitmapset * +ExecGetExtraUpdatedCols(ResultRelInfo *relinfo, EState *estate) +{ + /* see ExecGetInsertedCols() */ + if (relinfo->ri_RangeTableIndex != 0) + { + RangeTblEntry *rte = exec_rt_fetch(relinfo->ri_RangeTableIndex, estate); + + return rte->extraUpdatedCols; + } + else if (relinfo->ri_RootResultRelInfo) + { + ResultRelInfo *rootRelInfo = relinfo->ri_RootResultRelInfo; + RangeTblEntry *rte = exec_rt_fetch(rootRelInfo->ri_RangeTableIndex, estate); + + if (relinfo->ri_RootToPartitionMap != NULL) + return execute_attr_map_cols(relinfo->ri_RootToPartitionMap->attrMap, + rte->extraUpdatedCols); + else + return rte->extraUpdatedCols; + } + else + return NULL; +} + +/* Return columns being updated, including generated columns */ +Bitmapset * +ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate) +{ + return bms_union(ExecGetUpdatedCols(relinfo, estate), + ExecGetExtraUpdatedCols(relinfo, estate)); +} diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 163d06e9bc20..fcf4256ac4eb 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -3,7 +3,7 @@ * functions.c * Execution of SQL-language functions * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,6 +28,7 @@ #include "parser/parse_coerce.h" #include "parser/parse_collate.h" #include "parser/parse_func.h" +#include "rewrite/rewriteHandler.h" #include "storage/proc.h" #include "tcop/utility.h" #include "utils/builtins.h" @@ -139,21 +140,6 @@ typedef struct typedef SQLFunctionCache *SQLFunctionCachePtr; -/* - * Data structure needed by the parser callback hooks to resolve parameter - * references during parsing of a SQL function's body. This is separate from - * SQLFunctionCache since we sometimes do parsing separately from execution. - */ -typedef struct SQLFunctionParseInfo -{ - char *fname; /* function's name */ - int nargs; /* number of input arguments */ - Oid *argtypes; /* resolved types of input arguments */ - char **argnames; /* names of input arguments; NULL if none */ - /* Note that argnames[i] can be NULL, if some args are unnamed */ - Oid collation; /* function's input collation, if known */ -} SQLFunctionParseInfo; - /* non-export function prototypes */ static Node *sql_fn_param_ref(ParseState *pstate, ParamRef *pref); @@ -621,13 +607,13 @@ init_execution_state(List *queryTree_list, ((CopyStmt *) stmt->utilityStmt)->filename == NULL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot COPY to/from client in a SQL function"))); + errmsg("cannot COPY to/from client in an SQL function"))); if (IsA(stmt->utilityStmt, TransactionStmt)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), /* translator: %s is a SQL statement name */ - errmsg("%s is not allowed in a SQL function", + errmsg("%s is not allowed in an SQL function", CreateCommandName(stmt->utilityStmt)))); } @@ -702,9 +688,7 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK) HeapTuple procedureTuple; Form_pg_proc procedureStruct; SQLFunctionCachePtr fcache; - List *raw_parsetree_list; List *queryTree_list; - List *flat_query_list; List *resulttlist; ListCell *lc; Datum tmp; @@ -782,40 +766,67 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK) elog(ERROR, "null prosrc for function %u", foid); fcache->src = TextDatumGetCString(tmp); + /* If we have prosqlbody, pay attention to that not prosrc. */ + tmp = SysCacheGetAttr(PROCOID, + procedureTuple, + Anum_pg_proc_prosqlbody, + &isNull); + /* * Parse and rewrite the queries in the function text. Use sublists to - * keep track of the original query boundaries. But we also build a - * "flat" list of the rewritten queries to pass to check_sql_fn_retval. - * This is because the last canSetTag query determines the result type - * independently of query boundaries --- and it might not be in the last - * sublist, for example if the last query rewrites to DO INSTEAD NOTHING. - * (It might not be unreasonable to throw an error in such a case, but - * this is the historical behavior and it doesn't seem worth changing.) + * keep track of the original query boundaries. * * Note: since parsing and planning is done in fcontext, we will generate * a lot of cruft that lives as long as the fcache does. This is annoying * but we'll not worry about it until the module is rewritten to use * plancache.c. */ - raw_parsetree_list = pg_parse_query(fcache->src); - queryTree_list = NIL; - flat_query_list = NIL; - foreach(lc, raw_parsetree_list) + if (!isNull) { - RawStmt *parsetree = lfirst_node(RawStmt, lc); - List *queryTree_sublist; - - queryTree_sublist = pg_analyze_and_rewrite_params(parsetree, - fcache->src, - (ParserSetupHook) sql_fn_parser_setup, - fcache->pinfo, - NULL); - queryTree_list = lappend(queryTree_list, queryTree_sublist); - flat_query_list = list_concat(flat_query_list, queryTree_sublist); + Node *n; + List *stored_query_list; + + n = stringToNode(TextDatumGetCString(tmp)); + if (IsA(n, List)) + stored_query_list = linitial_node(List, castNode(List, n)); + else + stored_query_list = list_make1(n); + + foreach(lc, stored_query_list) + { + Query *parsetree = lfirst_node(Query, lc); + List *queryTree_sublist; + + AcquireRewriteLocks(parsetree, true, false); + queryTree_sublist = pg_rewrite_query(parsetree); + queryTree_list = lappend(queryTree_list, queryTree_sublist); + } } + else + { + List *raw_parsetree_list; - check_sql_fn_statements(flat_query_list); + raw_parsetree_list = pg_parse_query(fcache->src); + + foreach(lc, raw_parsetree_list) + { + RawStmt *parsetree = lfirst_node(RawStmt, lc); + List *queryTree_sublist; + + queryTree_sublist = pg_analyze_and_rewrite_params(parsetree, + fcache->src, + (ParserSetupHook) sql_fn_parser_setup, + fcache->pinfo, + NULL); + queryTree_list = lappend(queryTree_list, queryTree_sublist); + } + } + + /* + * Check that there are no statements we don't want to allow. + */ + check_sql_fn_statements(queryTree_list); /* * If we have only SELECT statements with no FROM clauses, we should @@ -855,7 +866,7 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK) * the rowtype column into multiple columns, since we have no way to * notify the caller that it should do that.) */ - fcache->returnsTuple = check_sql_fn_retval(flat_query_list, + fcache->returnsTuple = check_sql_fn_retval(queryTree_list, rettype, rettupdesc, false, @@ -1001,6 +1012,7 @@ postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache) { ProcessUtility(es->qd->plannedstmt, fcache->src, + false, PROCESS_UTILITY_QUERY, es->qd->params, es->qd->queryEnv, @@ -1653,41 +1665,33 @@ ShutdownSQLFunction(Datum arg) * is not acceptable. */ void -check_sql_fn_statements(List *queryTreeList) +check_sql_fn_statements(List *queryTreeLists) { ListCell *lc; - foreach(lc, queryTreeList) + /* We are given a list of sublists of Queries */ + foreach(lc, queryTreeLists) { - Query *query = lfirst_node(Query, lc); + List *sublist = lfirst_node(List, lc); + ListCell *lc2; - /* - * Disallow procedures with output arguments. The current - * implementation would just throw the output values away, unless the - * statement is the last one. Per SQL standard, we should assign the - * output values by name. By disallowing this here, we preserve an - * opportunity for future improvement. - */ - if (query->commandType == CMD_UTILITY && - IsA(query->utilityStmt, CallStmt)) + foreach(lc2, sublist) { - CallStmt *stmt = castNode(CallStmt, query->utilityStmt); - HeapTuple tuple; - int numargs; - Oid *argtypes; - char **argnames; - char *argmodes; - int i; - - tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(stmt->funcexpr->funcid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for function %u", stmt->funcexpr->funcid); - numargs = get_func_arg_info(tuple, &argtypes, &argnames, &argmodes); - ReleaseSysCache(tuple); - - for (i = 0; i < numargs; i++) + Query *query = lfirst_node(Query, lc2); + + /* + * Disallow calling procedures with output arguments. The current + * implementation would just throw the output values away, unless + * the statement is the last one. Per SQL standard, we should + * assign the output values by name. By disallowing this here, we + * preserve an opportunity for future improvement. + */ + if (query->commandType == CMD_UTILITY && + IsA(query->utilityStmt, CallStmt)) { - if (argmodes && (argmodes[i] == PROARGMODE_INOUT || argmodes[i] == PROARGMODE_OUT)) + CallStmt *stmt = (CallStmt *) query->utilityStmt; + + if (stmt->outargs != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("calling procedures with output arguments is not supported in SQL functions"))); @@ -1697,7 +1701,8 @@ check_sql_fn_statements(List *queryTreeList) } /* - * check_sql_fn_retval() -- check return value of a list of sql parse trees. + * check_sql_fn_retval() + * Check return value of a list of lists of sql parse trees. * * The return value of a sql function is the value returned by the last * canSetTag query in the function. We do some ad-hoc type checking and @@ -1735,7 +1740,7 @@ check_sql_fn_statements(List *queryTreeList) * function is defined to return VOID then *resultTargetList is set to NIL. */ bool -check_sql_fn_retval(List *queryTreeList, +check_sql_fn_retval(List *queryTreeLists, Oid rettype, TupleDesc rettupdesc, bool insertDroppedCols, List **resultTargetList) @@ -1762,20 +1767,30 @@ check_sql_fn_retval(List *queryTreeList, return false; /* - * Find the last canSetTag query in the list. This isn't necessarily the - * last parsetree, because rule rewriting can insert queries after what - * the user wrote. + * Find the last canSetTag query in the function body (which is presented + * to us as a list of sublists of Query nodes). This isn't necessarily + * the last parsetree, because rule rewriting can insert queries after + * what the user wrote. Note that it might not even be in the last + * sublist, for example if the last query rewrites to DO INSTEAD NOTHING. + * (It might not be unreasonable to throw an error in such a case, but + * this is the historical behavior and it doesn't seem worth changing.) */ parse = NULL; parse_cell = NULL; - foreach(lc, queryTreeList) + foreach(lc, queryTreeLists) { - Query *q = lfirst_node(Query, lc); + List *sublist = lfirst_node(List, lc); + ListCell *lc2; - if (q->canSetTag) + foreach(lc2, sublist) { - parse = q; - parse_cell = lc; + Query *q = lfirst_node(Query, lc2); + + if (q->canSetTag) + { + parse = q; + parse_cell = lc2; + } } } @@ -1838,7 +1853,8 @@ check_sql_fn_retval(List *queryTreeList, if (fn_typtype == TYPTYPE_BASE || fn_typtype == TYPTYPE_DOMAIN || fn_typtype == TYPTYPE_ENUM || - fn_typtype == TYPTYPE_RANGE) + fn_typtype == TYPTYPE_RANGE || + fn_typtype == TYPTYPE_MULTIRANGE) { /* * For scalar-type returns, the target list must have exactly one diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c index da7abf1cc43a..73d562da6b6c 100644 --- a/src/backend/executor/instrument.c +++ b/src/backend/executor/instrument.c @@ -49,7 +49,7 @@ static InstrumentationResownerSet *slotsOccupied = NULL; /* Allocate new instrumentation structure(s) */ Instrumentation * -InstrAlloc(int n, int instrument_options) +InstrAlloc(int n, int instrument_options, bool async_mode) { Instrumentation *instr; @@ -68,7 +68,7 @@ InstrAlloc(int n, int instrument_options) instr[i].need_bufusage = need_buffers; instr[i].need_walusage = need_wal; instr[i].need_timer = need_timer; - instr[i].need_cdb = need_cdb; + instr[i].async_mode = async_mode; } } @@ -103,8 +103,9 @@ InstrStartNode(Instrumentation *instr) /* Exit from a plan node */ void -InstrStopNode(Instrumentation *instr, uint64 nTuples) +InstrStopNode(Instrumentation *instr, double nTuples) { + double save_tuplecount = instr->tuplecount; instr_time endtime; instr_time starttime; @@ -142,6 +143,23 @@ InstrStopNode(Instrumentation *instr, uint64 nTuples) /* CDB: save this start time as the first start */ instr->firststart = starttime; } + else + { + /* + * In async mode, if the plan node hadn't emitted any tuples before, + * this might be the first tuple + */ + if (instr->async_mode && save_tuplecount < 1.0) + instr->firsttuple = INSTR_TIME_GET_DOUBLE(instr->counter); + } +} + +/* Update tuple count */ +void +InstrUpdateTupleCount(Instrumentation *instr, double nTuples) +{ + /* count the returned tuples */ + instr->tuplecount += nTuples; } /* Finish a run cycle for a plan node */ @@ -375,7 +393,7 @@ GpInstrAlloc(const Plan *node, int instrument_options) instr = pickInstrFromShmem(node, instrument_options); if (instr == NULL) - instr = InstrAlloc(1, instrument_options); + instr = InstrAlloc(1, instrument_options, false); return instr; } diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 24a388950ada..ed3df11d6d56 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -234,7 +234,7 @@ * * Portions Copyright (c) 2007-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -368,7 +368,7 @@ typedef struct HashAggSpill int64 *ntuples; /* number of tuples in each partition */ uint32 mask; /* mask to find partition from hash value */ int shift; /* after masking, shift by this amount */ - hyperLogLogState *hll_card; /* cardinality estimate for contents */ + hyperLogLogState *hll_card; /* cardinality estimate for contents */ } HashAggSpill; /* @@ -393,9 +393,9 @@ typedef struct HashAggBatch /* used to find referenced colnos */ typedef struct FindColsContext { - bool is_aggref; /* is under an aggref */ - Bitmapset *aggregated; /* column references under an aggref */ - Bitmapset *unaggregated; /* other column references */ + bool is_aggref; /* is under an aggref */ + Bitmapset *aggregated; /* column references under an aggref */ + Bitmapset *unaggregated; /* other column references */ } FindColsContext; static void select_current_set(AggState *aggstate, int setno, bool is_hash); @@ -486,14 +486,6 @@ static void build_pertrans_for_aggref(AggStatePerTrans pertrans, Oid aggserialfn, Oid aggdeserialfn, Datum initValue, bool initValueIsNull, Oid *inputTypes, int numArguments); -static int find_compatible_peragg(Aggref *newagg, AggState *aggstate, - int lastaggno, List **same_input_transnos); -static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg, - bool shareable, - Oid aggtransfn, Oid aggtranstype, - Oid aggserialfn, Oid aggdeserialfn, - Datum initValue, bool initValueIsNull, - List *transnos); static void ExecEagerFreeAgg(AggState *node); @@ -1414,7 +1406,7 @@ finalize_aggregates(AggState *aggstate, pergroupstate = &pergroup[transno]; - if (DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit)) + if (DO_AGGSPLIT_SKIPFINAL(peragg->aggref->aggsplit)) finalize_partialaggregate(aggstate, peragg, pergroupstate, &aggvalues[aggno], &aggnulls[aggno]); else @@ -1451,22 +1443,28 @@ project_aggregates(AggState *aggstate) } /* - * Walk tlist and qual to find referenced colnos, dividing them into + * Find input-tuple columns that are needed, dividing them into * aggregated and unaggregated sets. */ static void find_cols(AggState *aggstate, Bitmapset **aggregated, Bitmapset **unaggregated) { - Agg *agg = (Agg *) aggstate->ss.ps.plan; + Agg *agg = (Agg *) aggstate->ss.ps.plan; FindColsContext context; context.is_aggref = false; context.aggregated = NULL; context.unaggregated = NULL; + /* Examine tlist and quals */ (void) find_cols_walker((Node *) agg->plan.targetlist, &context); (void) find_cols_walker((Node *) agg->plan.qual, &context); + /* In some cases, grouping columns will not appear in the tlist */ + for (int i = 0; i < agg->numCols; i++) + context.unaggregated = bms_add_member(context.unaggregated, + agg->grpColIdx[i]); + *aggregated = context.aggregated; *unaggregated = context.unaggregated; } @@ -1633,7 +1631,8 @@ find_hash_columns(AggState *aggstate) for (int i = 0; i < scanDesc->natts; i++) { - int colno = i + 1; + int colno = i + 1; + if (bms_is_member(colno, aggstate->colnos_needed)) aggstate->max_colno_needed = colno; else @@ -1810,9 +1809,15 @@ hashagg_recompile_expressions(AggState *aggstate, bool minslot, bool nullcheck) const TupleTableSlotOps *outerops = aggstate->ss.ps.outerops; bool outerfixed = aggstate->ss.ps.outeropsfixed; bool dohash = true; - bool dosort; + bool dosort = false; - dosort = aggstate->aggstrategy == AGG_MIXED ? true : false; + /* + * If minslot is true, that means we are processing a spilled batch + * (inside agg_refill_hash_table()), and we must not advance the + * sorted grouping sets. + */ + if (aggstate->aggstrategy == AGG_MIXED && !minslot) + dosort = true; /* temporarily change the outerops while compiling the expression */ if (minslot) @@ -2145,8 +2150,7 @@ initialize_hash_entry(AggState *aggstate, TupleHashTable hashtable, } /* - * Look up hash entries for the current tuple in all hashed grouping sets, - * returning an array of pergroup pointers suitable for advance_aggregates. + * Look up hash entries for the current tuple in all hashed grouping sets. * * Be aware that lookup_hash_entry can reset the tmpcontext. * @@ -2688,11 +2692,15 @@ agg_refill_hash_table(AggState *aggstate) batch->used_bits, &aggstate->hash_mem_limit, &aggstate->hash_ngroups_limit, NULL); - /* there could be residual pergroup pointers; clear them */ - for (int setoff = 0; - setoff < aggstate->maxsets + aggstate->num_hashes; - setoff++) - aggstate->all_pergroups[setoff] = NULL; + /* + * Each batch only processes one grouping set; set the rest to NULL so + * that advance_aggregates() knows to ignore them. We don't touch + * pergroups for sorted grouping sets here, because they will be needed if + * we rescan later. The expressions for sorted grouping sets will not be + * evaluated after we recompile anyway. + */ + MemSet(aggstate->hash_pergroup, 0, + sizeof(AggStatePerGroup) * aggstate->num_hashes); /* free memory and reset hash tables */ ReScanExprContext(aggstate->hashcontext); @@ -2726,8 +2734,6 @@ agg_refill_hash_table(AggState *aggstate) */ hashagg_recompile_expressions(aggstate, true, true); - LogicalTapeRewindForRead(tapeinfo->tapeset, batch->input_tapenum, - HASHAGG_READ_BUFFER_SIZE); for (;;) { TupleTableSlot *spillslot = aggstate->hash_spill_rslot; @@ -2793,8 +2799,8 @@ agg_refill_hash_table(AggState *aggstate) if (spill_initialized) { - hash_agg_update_metrics(aggstate, true, spill.npartitions); hashagg_spill_finish(aggstate, &spill, batch->setno); + hash_agg_update_metrics(aggstate, true, spill.npartitions); } else hash_agg_update_metrics(aggstate, true, 0); @@ -2969,7 +2975,7 @@ hashagg_tapeinfo_init(AggState *aggstate) HashTapeInfo *tapeinfo = palloc(sizeof(HashTapeInfo)); int init_tapes = 16; /* expanded dynamically */ - tapeinfo->tapeset = LogicalTapeSetCreate(init_tapes, NULL, NULL, -1); + tapeinfo->tapeset = LogicalTapeSetCreate(init_tapes, true, NULL, NULL, -1); tapeinfo->ntapes = init_tapes; tapeinfo->nfreetapes = init_tapes; tapeinfo->freetapes_alloc = init_tapes; @@ -3025,6 +3031,7 @@ hashagg_tapeinfo_assign(HashTapeInfo *tapeinfo, int *partitions, static void hashagg_tapeinfo_release(HashTapeInfo *tapeinfo, int tapenum) { + /* rewinding frees the buffer while not in use */ LogicalTapeRewindForWrite(tapeinfo->tapeset, tapenum); if (tapeinfo->freetapes_alloc == tapeinfo->nfreetapes) { @@ -3254,9 +3261,10 @@ hashagg_spill_finish(AggState *aggstate, HashAggSpill *spill, int setno) for (i = 0; i < spill->npartitions; i++) { - int tapenum = spill->partitions[i]; - HashAggBatch *new_batch; - double cardinality; + LogicalTapeSet *tapeset = aggstate->hash_tapeinfo->tapeset; + int tapenum = spill->partitions[i]; + HashAggBatch *new_batch; + double cardinality; /* if the partition is empty, don't create a new batch of work */ if (spill->ntuples[i] == 0) @@ -3265,9 +3273,13 @@ hashagg_spill_finish(AggState *aggstate, HashAggSpill *spill, int setno) cardinality = estimateHyperLogLog(&spill->hll_card[i]); freeHyperLogLog(&spill->hll_card[i]); - new_batch = hashagg_batch_new(aggstate->hash_tapeinfo->tapeset, - tapenum, setno, spill->ntuples[i], - cardinality, used_bits); + /* rewinding frees the buffer while not in use */ + LogicalTapeRewindForRead(tapeset, tapenum, + HASHAGG_READ_BUFFER_SIZE); + + new_batch = hashagg_batch_new(tapeset, tapenum, setno, + spill->ntuples[i], cardinality, + used_bits); aggstate->hash_batches = lcons(new_batch, aggstate->hash_batches); aggstate->hash_batches_used++; } @@ -3332,6 +3344,89 @@ hashagg_reset_spill_state(AggState *aggstate) * * ----------------- */ +typedef struct +{ + List *aggno_map; /* i-th member: old aggno that became i */ + List *transno_map; +} AggRenumberContext; + +static bool +agg_renumber_walker(Node *node, AggRenumberContext *cxt) +{ + if (node == NULL) + return false; + if (IsA(node, Aggref)) + { + Aggref *aggref = (Aggref *) node; + int newno; + ListCell *lc; + + newno = 0; + foreach(lc, cxt->aggno_map) + { + if (lfirst_int(lc) == aggref->aggno) + break; + newno++; + } + if (lc == NULL) + cxt->aggno_map = lappend_int(cxt->aggno_map, aggref->aggno); + aggref->aggno = newno; + + newno = 0; + foreach(lc, cxt->transno_map) + { + if (lfirst_int(lc) == aggref->aggtransno) + break; + newno++; + } + if (lc == NULL) + cxt->transno_map = lappend_int(cxt->transno_map, aggref->aggtransno); + aggref->aggtransno = newno; + + /* aggregates can't be nested; no need to recurse into args */ + return false; + } + return expression_tree_walker(node, agg_renumber_walker, (void *) cxt); +} + +/* + * GPDB: renumber this Agg node's aggregates densely from zero. + * + * preprocess_aggrefs() numbers aggregates across the whole query, but + * multi-stage and DQA plans (and ORCA translations) can place a subset of + * them in a given Agg node. ExecInitAgg sizes its per-agg and per-trans + * arrays as max(aggno)+1 and the expression compiler bakes the numbers + * into EEOP_AGG_* steps, so a sparse numbering leaves uninitialized slots + * that ExecBuildAggTrans dereferences. Renumbering keeps equal numbers + * equal (preserving transition-state sharing) and is idempotent, so + * re-initializing a cached plan is safe. It must run before any + * expression of this node is compiled. + */ +static void +agg_renumber_aggrefs(Agg *node) +{ + AggRenumberContext cxt; + ListCell *lc; + + cxt.aggno_map = NIL; + cxt.transno_map = NIL; + + agg_renumber_walker((Node *) node->plan.targetlist, &cxt); + agg_renumber_walker((Node *) node->plan.qual, &cxt); + + /* grouping-sets chain nodes share this node's numbering space */ + foreach(lc, node->chain) + { + Agg *chainnode = lfirst_node(Agg, lc); + + agg_renumber_walker((Node *) chainnode->plan.targetlist, &cxt); + agg_renumber_walker((Node *) chainnode->plan.qual, &cxt); + } + + list_free(cxt.aggno_map); + list_free(cxt.transno_map); +} + AggState * ExecInitAgg(Agg *node, EState *estate, int eflags) { @@ -3342,9 +3437,11 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) Plan *outerPlan; ExprContext *econtext; TupleDesc scanDesc; - int numaggs, - transno, - aggno; + int max_aggno; + int max_transno; + int numaggrefs; + int numaggs; + int numtrans; int phase; int phaseidx; ListCell *l; @@ -3361,6 +3458,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); + /* GPDB: compact aggno/aggtransno before any expression is compiled */ + agg_renumber_aggrefs(node); + /* * create state structure */ @@ -3530,9 +3630,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) * semantics, and it's forbidden by the spec. Because it is true, we * don't need to worry about evaluating the aggs in any particular order. * - * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState - * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs - * in the targetlist are found during ExecAssignProjectionInfo, below. + * Note: execExpr.c finds Aggrefs for us, and adds them to aggstate->aggs. + * Aggrefs in the qual are found here; Aggrefs in the targetlist are found + * during ExecAssignProjectionInfo, above. */ aggstate->ss.ps.qual = ExecInitQual(node->plan.qual, (PlanState *) aggstate); @@ -3540,8 +3640,18 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* * We should now have found all Aggrefs in the targetlist and quals. */ - numaggs = aggstate->numaggs; - Assert(numaggs == list_length(aggstate->aggs)); + numaggrefs = list_length(aggstate->aggs); + max_aggno = -1; + max_transno = -1; + foreach(l, aggstate->aggs) + { + Aggref *aggref = (Aggref *) lfirst(l); + + max_aggno = Max(max_aggno, aggref->aggno); + max_transno = Max(max_transno, aggref->aggtransno); + } + numaggs = max_aggno + 1; + numtrans = max_transno + 1; /* * For each phase, prepare grouping set data and fmgr lookup data for @@ -3731,7 +3841,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) econtext->ecxt_aggnulls = (bool *) palloc0(sizeof(bool) * numaggs); peraggs = (AggStatePerAgg) palloc0(sizeof(AggStatePerAggData) * numaggs); - pertransstates = (AggStatePerTrans) palloc0(sizeof(AggStatePerTransData) * numaggs); + pertransstates = (AggStatePerTrans) palloc0(sizeof(AggStatePerTransData) * numtrans); aggstate->peragg = peraggs; aggstate->pertrans = pertransstates; @@ -3822,90 +3932,39 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) select_current_set(aggstate, 0, false); } - /* ----------------- + /* * Perform lookups of aggregate function info, and initialize the * unchanging fields of the per-agg and per-trans data. - * - * We try to optimize by detecting duplicate aggregate functions so that - * their state and final values are re-used, rather than needlessly being - * re-calculated independently. We also detect aggregates that are not - * the same, but which can share the same transition state. - * - * Scenarios: - * - * 1. Identical aggregate function calls appear in the query: - * - * SELECT SUM(x) FROM ... HAVING SUM(x) > 0 - * - * Since these aggregates are identical, we only need to calculate - * the value once. Both aggregates will share the same 'aggno' value. - * - * 2. Two different aggregate functions appear in the query, but the - * aggregates have the same arguments, transition functions and - * initial values (and, presumably, different final functions): - * - * SELECT AVG(x), STDDEV(x) FROM ... - * - * In this case we must create a new peragg for the varying aggregate, - * and we need to call the final functions separately, but we need - * only run the transition function once. (This requires that the - * final functions be nondestructive of the transition state, but - * that's required anyway for other reasons.) - * - * For either of these optimizations to be valid, all aggregate properties - * used in the transition phase must be the same, including any modifiers - * such as ORDER BY, DISTINCT and FILTER, and the arguments mustn't - * contain any volatile functions. - * ----------------- */ - aggno = -1; - transno = -1; foreach(l, aggstate->aggs) { - AggrefExprState *aggrefstate = (AggrefExprState *) lfirst(l); - Aggref *aggref = aggrefstate->aggref; + Aggref *aggref = lfirst(l); AggStatePerAgg peragg; AggStatePerTrans pertrans; - int existing_aggno; - int existing_transno; - List *same_input_transnos; Oid inputTypes[FUNC_MAX_ARGS]; int numArguments; int numDirectArgs; HeapTuple aggTuple; Form_pg_aggregate aggform; AclResult aclresult; - Oid transfn_oid, - finalfn_oid; - bool shareable; + Oid finalfn_oid; Oid serialfn_oid, deserialfn_oid; + Oid aggOwner; Expr *finalfnexpr; Oid aggtranstype; - Datum textInitVal; - Datum initValue; - bool initValueIsNull; /* Planner should have assigned aggregate to correct level */ Assert(aggref->agglevelsup == 0); - /* 1. Check for already processed aggs which can be re-used */ - existing_aggno = find_compatible_peragg(aggref, aggstate, aggno, - &same_input_transnos); - if (existing_aggno != -1) - { - /* - * Existing compatible agg found. so just point the Aggref to the - * same per-agg struct. - */ - aggrefstate->aggno = existing_aggno; + peragg = &peraggs[aggref->aggno]; + + /* Check if we initialized the state for this aggregate already. */ + if (peragg->aggref != NULL) continue; - } - /* Mark Aggref state node with assigned index in the result array */ - peragg = &peraggs[++aggno]; peragg->aggref = aggref; - aggrefstate->aggno = aggno; + peragg->transno = aggref->aggtransno; /* Fetch the pg_aggregate row */ aggTuple = SearchSysCache1(AGGFNOID, @@ -3927,36 +3986,12 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) aggtranstype = aggref->aggtranstype; Assert(OidIsValid(aggtranstype)); - /* - * If this aggregation is performing state combines, then instead of - * using the transition function, we'll use the combine function - */ - if (DO_AGGSPLIT_COMBINE(aggref->aggsplit)) - { - transfn_oid = aggform->aggcombinefn; - - /* If not set then the planner messed up */ - if (!OidIsValid(transfn_oid)) - elog(ERROR, "combinefn not set for aggregate function"); - } - else - transfn_oid = aggform->aggtransfn; - /* Final function only required if we're finalizing the aggregates */ if (DO_AGGSPLIT_SKIPFINAL(aggref->aggsplit)) peragg->finalfn_oid = finalfn_oid = InvalidOid; else peragg->finalfn_oid = finalfn_oid = aggform->aggfinalfn; - /* - * If finalfn is marked read-write, we can't share transition states; - * but it is okay to share states for AGGMODIFY_SHAREABLE aggs. Also, - * if we're not executing the finalfn here, we can share regardless. - */ - shareable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE) || - (finalfn_oid == InvalidOid); - peragg->shareable = shareable; - serialfn_oid = InvalidOid; deserialfn_oid = InvalidOid; @@ -3996,7 +4031,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* Check that aggregate owner has permission to call component fns */ { HeapTuple procTuple; - Oid aggOwner; procTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(aggref->aggfnoid)); @@ -4006,12 +4040,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) aggOwner = ((Form_pg_proc) GETSTRUCT(procTuple))->proowner; ReleaseSysCache(procTuple); - aclresult = pg_proc_aclcheck(transfn_oid, aggOwner, - ACL_EXECUTE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, OBJECT_FUNCTION, - get_func_name(transfn_oid)); - InvokeFunctionExecuteHook(transfn_oid); if (OidIsValid(finalfn_oid)) { aclresult = pg_proc_aclcheck(finalfn_oid, aggOwner, @@ -4084,51 +4112,68 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) &peragg->resulttypeByVal); /* - * initval is potentially null, so don't try to access it as a struct - * field. Must do it the hard way with SysCacheGetAttr. - */ - textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple, - Anum_pg_aggregate_agginitval, - &initValueIsNull); - if (initValueIsNull) - initValue = (Datum) 0; - else - initValue = GetAggInitVal(textInitVal, aggtranstype); - - /* - * 2. Build working state for invoking the transition function, or - * look up previously initialized working state, if we can share it. - * - * find_compatible_peragg() already collected a list of shareable - * per-Trans's with the same inputs. Check if any of them have the - * same transition function and initial value. + * Build working state for invoking the transition function, if we + * haven't done it already. */ - existing_transno = find_compatible_pertrans(aggstate, aggref, - shareable, - transfn_oid, aggtranstype, - serialfn_oid, deserialfn_oid, - initValue, initValueIsNull, - same_input_transnos); - if (existing_transno != -1) + pertrans = &pertransstates[aggref->aggtransno]; + if (pertrans->aggref == NULL) { + Datum textInitVal; + Datum initValue; + bool initValueIsNull; + Oid transfn_oid; + /* - * Existing compatible trans found, so just point the 'peragg' to - * the same per-trans struct, and mark the trans state as shared. + * If this aggregation is performing state combines, then instead + * of using the transition function, we'll use the combine + * function. + * + * GPDB: check the aggref, not the node. ORCA can put aggregates + * of different stages into one Agg node (e.g. a finalize-stage + * sum next to a single-stage count over deduplicated input); the + * serial/deserial/final function choices above are already + * per-aggref, and picking the plain transition function for a + * combining aggregate feeds it the serialized state of the + * stage below (the CTE-sharing DQA queries summed raw datums). */ - pertrans = &pertransstates[existing_transno]; - pertrans->aggshared = true; - peragg->transno = existing_transno; - } - else - { - pertrans = &pertransstates[++transno]; + if (DO_AGGSPLIT_COMBINE(aggref->aggsplit)) + { + transfn_oid = aggform->aggcombinefn; + + /* If not set then the planner messed up */ + if (!OidIsValid(transfn_oid)) + elog(ERROR, "combinefn not set for aggregate function"); + } + else + transfn_oid = aggform->aggtransfn; + + aclresult = pg_proc_aclcheck(transfn_oid, aggOwner, + ACL_EXECUTE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, OBJECT_FUNCTION, + get_func_name(transfn_oid)); + InvokeFunctionExecuteHook(transfn_oid); + + /* + * initval is potentially null, so don't try to access it as a + * struct field. Must do it the hard way with SysCacheGetAttr. + */ + textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple, + Anum_pg_aggregate_agginitval, + &initValueIsNull); + if (initValueIsNull) + initValue = (Datum) 0; + else + initValue = GetAggInitVal(textInitVal, aggtranstype); + build_pertrans_for_aggref(pertrans, aggstate, estate, aggref, transfn_oid, aggtranstype, serialfn_oid, deserialfn_oid, initValue, initValueIsNull, inputTypes, numArguments); - peragg->transno = transno; } + else + pertrans->aggshared = true; ReleaseSysCache(aggTuple); } @@ -4136,8 +4181,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) * Update aggstate->numaggs to be the number of unique aggregates found. * Also set numstates to the number of unique transition states found. */ - aggstate->numaggs = aggno + 1; - aggstate->numtrans = transno + 1; + aggstate->numaggs = numaggs; + aggstate->numtrans = numtrans; /* * Last, check whether any more aggregates got added onto the node while @@ -4149,7 +4194,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) * need to work hard on a helpful error message; but we defend against it * here anyway, just to be sure.) */ - if (numaggs != list_length(aggstate->aggs)) + if (numaggrefs != list_length(aggstate->aggs)) ereport(ERROR, (errcode(ERRCODE_GROUPING_ERROR), errmsg("aggregate function calls cannot be nested"))); @@ -4548,147 +4593,6 @@ GetAggInitVal(Datum textInitVal, Oid transtype) return initVal; } -/* - * find_compatible_peragg - search for a previously initialized per-Agg struct - * - * Searches the previously looked at aggregates to find one which is compatible - * with this one, with the same input parameters. If no compatible aggregate - * can be found, returns -1. - * - * As a side-effect, this also collects a list of existing, shareable per-Trans - * structs with matching inputs. If no identical Aggref is found, the list is - * passed later to find_compatible_pertrans, to see if we can at least reuse - * the state value of another aggregate. - */ -static int -find_compatible_peragg(Aggref *newagg, AggState *aggstate, - int lastaggno, List **same_input_transnos) -{ - int aggno; - AggStatePerAgg peraggs; - - *same_input_transnos = NIL; - - /* we mustn't reuse the aggref if it contains volatile function calls */ - if (contain_volatile_functions((Node *) newagg)) - return -1; - - peraggs = aggstate->peragg; - - /* - * Search through the list of already seen aggregates. If we find an - * existing identical aggregate call, then we can re-use that one. While - * searching, we'll also collect a list of Aggrefs with the same input - * parameters. If no matching Aggref is found, the caller can potentially - * still re-use the transition state of one of them. (At this stage we - * just compare the parsetrees; whether different aggregates share the - * same transition function will be checked later.) - */ - for (aggno = 0; aggno <= lastaggno; aggno++) - { - AggStatePerAgg peragg; - Aggref *existingRef; - - peragg = &peraggs[aggno]; - existingRef = peragg->aggref; - - /* all of the following must be the same or it's no match */ - if (newagg->inputcollid != existingRef->inputcollid || - newagg->aggtranstype != existingRef->aggtranstype || - newagg->aggstar != existingRef->aggstar || - newagg->aggvariadic != existingRef->aggvariadic || - newagg->aggkind != existingRef->aggkind || - !equal(newagg->args, existingRef->args) || - !equal(newagg->aggorder, existingRef->aggorder) || - !equal(newagg->aggdistinct, existingRef->aggdistinct) || - !equal(newagg->aggfilter, existingRef->aggfilter)) - continue; - - /* if it's the same aggregate function then report exact match */ - if (newagg->aggfnoid == existingRef->aggfnoid && - newagg->aggtype == existingRef->aggtype && - newagg->aggcollid == existingRef->aggcollid && - equal(newagg->aggdirectargs, existingRef->aggdirectargs)) - { - list_free(*same_input_transnos); - *same_input_transnos = NIL; - return aggno; - } - - /* - * Not identical, but it had the same inputs. If the final function - * permits sharing, return its transno to the caller, in case we can - * re-use its per-trans state. (If there's already sharing going on, - * we might report a transno more than once. find_compatible_pertrans - * is cheap enough that it's not worth spending cycles to avoid that.) - */ - if (peragg->shareable) - *same_input_transnos = lappend_int(*same_input_transnos, - peragg->transno); - } - - return -1; -} - -/* - * find_compatible_pertrans - search for a previously initialized per-Trans - * struct - * - * Searches the list of transnos for a per-Trans struct with the same - * transition function and initial condition. (The inputs have already been - * verified to match.) - */ -static int -find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool shareable, - Oid aggtransfn, Oid aggtranstype, - Oid aggserialfn, Oid aggdeserialfn, - Datum initValue, bool initValueIsNull, - List *transnos) -{ - ListCell *lc; - - /* If this aggregate can't share transition states, give up */ - if (!shareable) - return -1; - - foreach(lc, transnos) - { - int transno = lfirst_int(lc); - AggStatePerTrans pertrans = &aggstate->pertrans[transno]; - - /* - * if the transfns or transition state types are not the same then the - * state can't be shared. - */ - if (aggtransfn != pertrans->transfn_oid || - aggtranstype != pertrans->aggtranstype) - continue; - - /* - * The serialization and deserialization functions must match, if - * present, as we're unable to share the trans state for aggregates - * which will serialize or deserialize into different formats. - * Remember that these will be InvalidOid if they're not required for - * this agg node. - */ - if (aggserialfn != pertrans->serialfn_oid || - aggdeserialfn != pertrans->deserialfn_oid) - continue; - - /* - * Check that the initial condition matches, too. - */ - if (initValueIsNull && pertrans->initValueIsNull) - return transno; - - if (!initValueIsNull && !pertrans->initValueIsNull && - datumIsEqual(initValue, pertrans->initValue, - pertrans->transtypeByVal, pertrans->transtypeLen)) - return transno; - } - return -1; -} - void ExecEndAgg(AggState *node) { diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index 10085581c9d8..123911ecbf4a 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -3,7 +3,7 @@ * nodeAppend.c * routines to handle append nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -57,10 +57,13 @@ #include "postgres.h" +#include "executor/execAsync.h" #include "executor/execdebug.h" #include "executor/execPartition.h" #include "executor/nodeAppend.h" #include "miscadmin.h" +#include "pgstat.h" +#include "storage/latch.h" /* Shared state for parallel-aware Append. */ struct ParallelAppendState @@ -78,12 +81,18 @@ struct ParallelAppendState }; #define INVALID_SUBPLAN_INDEX -1 +#define EVENT_BUFFER_SIZE 16 static TupleTableSlot *ExecAppend(PlanState *pstate); static bool choose_next_subplan_locally(AppendState *node); static bool choose_next_subplan_for_leader(AppendState *node); static bool choose_next_subplan_for_worker(AppendState *node); static void mark_invalid_subplans_as_finished(AppendState *node); +static void ExecAppendAsyncBegin(AppendState *node); +static bool ExecAppendAsyncGetNext(AppendState *node, TupleTableSlot **result); +static bool ExecAppendAsyncRequest(AppendState *node, TupleTableSlot **result); +static void ExecAppendAsyncEventWait(AppendState *node); +static void classify_matching_subplans(AppendState *node); /* ---------------------------------------------------------------- * ExecInitAppend @@ -102,7 +111,9 @@ ExecInitAppend(Append *node, EState *estate, int eflags) AppendState *appendstate = makeNode(AppendState); PlanState **appendplanstates; Bitmapset *validsubplans; + Bitmapset *asyncplans; int nplans; + int nasyncplans; int firstvalid; int i, j; @@ -119,6 +130,8 @@ ExecInitAppend(Append *node, EState *estate, int eflags) /* Let choose_next_subplan_* function handle setting the first subplan */ appendstate->as_whichplan = INVALID_SUBPLAN_INDEX; + appendstate->as_syncdone = false; + appendstate->as_begun = false; /* If run-time partition pruning is enabled, then set that up now */ if (node->part_prune_info != NULL) @@ -194,12 +207,25 @@ ExecInitAppend(Append *node, EState *estate, int eflags) * While at it, find out the first valid partial plan. */ j = 0; + asyncplans = NULL; + nasyncplans = 0; firstvalid = nplans; i = -1; while ((i = bms_next_member(validsubplans, i)) >= 0) { Plan *initNode = (Plan *) list_nth(node->appendplans, i); + /* + * Record async subplans. When executing EvalPlanQual, we treat them + * as sync ones; don't do this when initializing an EvalPlanQual plan + * tree. + */ + if (initNode->async_capable && estate->es_epq_active == NULL) + { + asyncplans = bms_add_member(asyncplans, j); + nasyncplans++; + } + /* * Record the lowest appendplans index which is a valid partial plan. */ @@ -213,6 +239,45 @@ ExecInitAppend(Append *node, EState *estate, int eflags) appendstate->appendplans = appendplanstates; appendstate->as_nplans = nplans; + /* Initialize async state */ + appendstate->as_asyncplans = asyncplans; + appendstate->as_nasyncplans = nasyncplans; + appendstate->as_asyncrequests = NULL; + appendstate->as_asyncresults = NULL; + appendstate->as_nasyncresults = 0; + appendstate->as_nasyncremain = 0; + appendstate->as_needrequest = NULL; + appendstate->as_eventset = NULL; + appendstate->as_valid_asyncplans = NULL; + + if (nasyncplans > 0) + { + appendstate->as_asyncrequests = (AsyncRequest **) + palloc0(nplans * sizeof(AsyncRequest *)); + + i = -1; + while ((i = bms_next_member(asyncplans, i)) >= 0) + { + AsyncRequest *areq; + + areq = palloc(sizeof(AsyncRequest)); + areq->requestor = (PlanState *) appendstate; + areq->requestee = appendplanstates[i]; + areq->request_index = i; + areq->callback_pending = false; + areq->request_complete = false; + areq->result = NULL; + + appendstate->as_asyncrequests[i] = areq; + } + + appendstate->as_asyncresults = (TupleTableSlot **) + palloc0(nasyncplans * sizeof(TupleTableSlot *)); + + if (appendstate->as_valid_subplans != NULL) + classify_matching_subplans(appendstate); + } + /* * Miscellaneous initialization */ @@ -235,31 +300,59 @@ static TupleTableSlot * ExecAppend(PlanState *pstate) { AppendState *node = castNode(AppendState, pstate); + TupleTableSlot *result; - if (node->as_whichplan < 0) + /* + * If this is the first call after Init or ReScan, we need to do the + * initialization work. + */ + if (!node->as_begun) { + Assert(node->as_whichplan == INVALID_SUBPLAN_INDEX); + Assert(!node->as_syncdone); + /* Nothing to do if there are no subplans */ if (node->as_nplans == 0) return ExecClearTuple(node->ps.ps_ResultTupleSlot); + /* If there are any async subplans, begin executing them. */ + if (node->as_nasyncplans > 0) + ExecAppendAsyncBegin(node); + /* - * If no subplan has been chosen, we must choose one before + * If no sync subplan has been chosen, we must choose one before * proceeding. */ - if (node->as_whichplan == INVALID_SUBPLAN_INDEX && - !node->choose_next_subplan(node)) + if (!node->choose_next_subplan(node) && node->as_nasyncremain == 0) return ExecClearTuple(node->ps.ps_ResultTupleSlot); + + Assert(node->as_syncdone || + (node->as_whichplan >= 0 && + node->as_whichplan < node->as_nplans)); + + /* And we're initialized. */ + node->as_begun = true; } for (;;) { PlanState *subnode; - TupleTableSlot *result; CHECK_FOR_INTERRUPTS(); /* - * figure out which subplan we are currently processing + * try to get a tuple from an async subplan if any + */ + if (node->as_syncdone || !bms_is_empty(node->as_needrequest)) + { + if (ExecAppendAsyncGetNext(node, &result)) + return result; + Assert(!node->as_syncdone); + Assert(bms_is_empty(node->as_needrequest)); + } + + /* + * figure out which sync subplan we are currently processing */ Assert(node->as_whichplan >= 0 && node->as_whichplan < node->as_nplans); subnode = node->appendplans[node->as_whichplan]; @@ -279,8 +372,16 @@ ExecAppend(PlanState *pstate) return result; } - /* choose new subplan; if none, we're done */ - if (!node->choose_next_subplan(node)) + /* + * wait or poll for async events if any. We do this before checking + * for the end of iteration, because it might drain the remaining + * async subplans. + */ + if (node->as_nasyncremain > 0) + ExecAppendAsyncEventWait(node); + + /* choose new sync subplan; if no sync/async subplans, we're done */ + if (!node->choose_next_subplan(node) && node->as_nasyncremain == 0) return ExecClearTuple(node->ps.ps_ResultTupleSlot); } } @@ -319,6 +420,7 @@ ExecEndAppend(AppendState *node) void ExecReScanAppend(AppendState *node) { + int nasyncplans = node->as_nasyncplans; int i; /* @@ -332,6 +434,11 @@ ExecReScanAppend(AppendState *node) { bms_free(node->as_valid_subplans); node->as_valid_subplans = NULL; + if (nasyncplans > 0) + { + bms_free(node->as_valid_asyncplans); + node->as_valid_asyncplans = NULL; + } } for (i = 0; i < node->as_nplans; i++) @@ -347,14 +454,35 @@ ExecReScanAppend(AppendState *node) /* * If chgParam of subnode is not null then plan will be re-scanned by - * first ExecProcNode. + * first ExecProcNode or by first ExecAsyncRequest. */ if (subnode->chgParam == NULL) ExecReScan(subnode); } + /* Reset async state */ + if (nasyncplans > 0) + { + i = -1; + while ((i = bms_next_member(node->as_asyncplans, i)) >= 0) + { + AsyncRequest *areq = node->as_asyncrequests[i]; + + areq->callback_pending = false; + areq->request_complete = false; + areq->result = NULL; + } + + node->as_nasyncresults = 0; + node->as_nasyncremain = 0; + bms_free(node->as_needrequest); + node->as_needrequest = NULL; + } + /* Let choose_next_subplan_* function handle setting the first subplan */ node->as_whichplan = INVALID_SUBPLAN_INDEX; + node->as_syncdone = false; + node->as_begun = false; } /* ---------------------------------------------------------------- @@ -435,7 +563,7 @@ ExecAppendInitializeWorker(AppendState *node, ParallelWorkerContext *pwcxt) /* ---------------------------------------------------------------- * choose_next_subplan_locally * - * Choose next subplan for a non-parallel-aware Append, + * Choose next sync subplan for a non-parallel-aware Append, * returning false if there are no more. * ---------------------------------------------------------------- */ @@ -448,19 +576,27 @@ choose_next_subplan_locally(AppendState *node) /* We should never be called when there are no subplans */ Assert(node->as_nplans > 0); + /* Nothing to do if syncdone */ + if (node->as_syncdone) + return false; + /* * If first call then have the bms member function choose the first valid - * subplan by initializing whichplan to -1. If there happen to be no - * valid subplans then the bms member function will handle that by + * sync subplan by initializing whichplan to -1. If there happen to be no + * valid sync subplans then the bms member function will handle that by * returning a negative number which will allow us to exit returning a * false value. */ if (whichplan == INVALID_SUBPLAN_INDEX) { - if (node->as_valid_subplans == NULL) + if (node->as_nasyncplans > 0) + { + /* We'd have filled as_valid_subplans already */ + Assert(node->as_valid_subplans); + } + else if (node->as_valid_subplans == NULL) { Append *plan = (Append *) node->ps.plan; - node->as_valid_subplans = ExecFindMatchingSubPlans(node->as_prune_state, node->ps.state, @@ -480,7 +616,12 @@ choose_next_subplan_locally(AppendState *node) nextplan = bms_prev_member(node->as_valid_subplans, whichplan); if (nextplan < 0) + { + /* Set as_syncdone if in async mode */ + if (node->as_nasyncplans > 0) + node->as_syncdone = true; return false; + } node->as_whichplan = nextplan; @@ -733,6 +874,330 @@ mark_invalid_subplans_as_finished(AppendState *node) } } +/* ---------------------------------------------------------------- + * Asynchronous Append Support + * ---------------------------------------------------------------- + */ + +/* ---------------------------------------------------------------- + * ExecAppendAsyncBegin + * + * Begin executing designed async-capable subplans. + * ---------------------------------------------------------------- + */ +static void +ExecAppendAsyncBegin(AppendState *node) +{ + int i; + + /* Backward scan is not supported by async-aware Appends. */ + Assert(ScanDirectionIsForward(node->ps.state->es_direction)); + + /* We should never be called when there are no subplans */ + Assert(node->as_nplans > 0); + + /* We should never be called when there are no async subplans. */ + Assert(node->as_nasyncplans > 0); + + /* If we've yet to determine the valid subplans then do so now. */ + if (node->as_valid_subplans == NULL) + { + Append *plan = (Append *) node->ps.plan; + node->as_valid_subplans = + ExecFindMatchingSubPlans(node->as_prune_state, + node->ps.state, + list_length(plan->appendplans), + plan->join_prune_paramids); + + classify_matching_subplans(node); + } + + /* Initialize state variables. */ + node->as_syncdone = bms_is_empty(node->as_valid_subplans); + node->as_nasyncremain = bms_num_members(node->as_valid_asyncplans); + + /* Nothing to do if there are no valid async subplans. */ + if (node->as_nasyncremain == 0) + return; + + /* Make a request for each of the valid async subplans. */ + i = -1; + while ((i = bms_next_member(node->as_valid_asyncplans, i)) >= 0) + { + AsyncRequest *areq = node->as_asyncrequests[i]; + + Assert(areq->request_index == i); + Assert(!areq->callback_pending); + + /* Do the actual work. */ + ExecAsyncRequest(areq); + } +} + +/* ---------------------------------------------------------------- + * ExecAppendAsyncGetNext + * + * Get the next tuple from any of the asynchronous subplans. + * ---------------------------------------------------------------- + */ +static bool +ExecAppendAsyncGetNext(AppendState *node, TupleTableSlot **result) +{ + *result = NULL; + + /* We should never be called when there are no valid async subplans. */ + Assert(node->as_nasyncremain > 0); + + /* Request a tuple asynchronously. */ + if (ExecAppendAsyncRequest(node, result)) + return true; + + while (node->as_nasyncremain > 0) + { + CHECK_FOR_INTERRUPTS(); + + /* Wait or poll for async events. */ + ExecAppendAsyncEventWait(node); + + /* Request a tuple asynchronously. */ + if (ExecAppendAsyncRequest(node, result)) + return true; + + /* Break from loop if there's any sync subplan that isn't complete. */ + if (!node->as_syncdone) + break; + } + + /* + * If all sync subplans are complete, we're totally done scanning the + * given node. Otherwise, we're done with the asynchronous stuff but must + * continue scanning the sync subplans. + */ + if (node->as_syncdone) + { + Assert(node->as_nasyncremain == 0); + *result = ExecClearTuple(node->ps.ps_ResultTupleSlot); + return true; + } + + return false; +} + +/* ---------------------------------------------------------------- + * ExecAppendAsyncRequest + * + * Request a tuple asynchronously. + * ---------------------------------------------------------------- + */ +static bool +ExecAppendAsyncRequest(AppendState *node, TupleTableSlot **result) +{ + Bitmapset *needrequest; + int i; + + /* Nothing to do if there are no async subplans needing a new request. */ + if (bms_is_empty(node->as_needrequest)) + { + Assert(node->as_nasyncresults == 0); + return false; + } + + /* + * If there are any asynchronously-generated results that have not yet + * been returned, we have nothing to do; just return one of them. + */ + if (node->as_nasyncresults > 0) + { + --node->as_nasyncresults; + *result = node->as_asyncresults[node->as_nasyncresults]; + return true; + } + + /* Make a new request for each of the async subplans that need it. */ + needrequest = node->as_needrequest; + node->as_needrequest = NULL; + i = -1; + while ((i = bms_next_member(needrequest, i)) >= 0) + { + AsyncRequest *areq = node->as_asyncrequests[i]; + + /* Do the actual work. */ + ExecAsyncRequest(areq); + } + bms_free(needrequest); + + /* Return one of the asynchronously-generated results if any. */ + if (node->as_nasyncresults > 0) + { + --node->as_nasyncresults; + *result = node->as_asyncresults[node->as_nasyncresults]; + return true; + } + + return false; +} + +/* ---------------------------------------------------------------- + * ExecAppendAsyncEventWait + * + * Wait or poll for file descriptor events and fire callbacks. + * ---------------------------------------------------------------- + */ +static void +ExecAppendAsyncEventWait(AppendState *node) +{ + int nevents = node->as_nasyncplans + 1; + long timeout = node->as_syncdone ? -1 : 0; + WaitEvent occurred_event[EVENT_BUFFER_SIZE]; + int noccurred; + int i; + + /* We should never be called when there are no valid async subplans. */ + Assert(node->as_nasyncremain > 0); + + node->as_eventset = CreateWaitEventSet(CurrentMemoryContext, nevents); + AddWaitEventToSet(node->as_eventset, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET, + NULL, NULL); + + /* Give each waiting subplan a chance to add an event. */ + i = -1; + while ((i = bms_next_member(node->as_asyncplans, i)) >= 0) + { + AsyncRequest *areq = node->as_asyncrequests[i]; + + if (areq->callback_pending) + ExecAsyncConfigureWait(areq); + } + + /* We wait on at most EVENT_BUFFER_SIZE events. */ + if (nevents > EVENT_BUFFER_SIZE) + nevents = EVENT_BUFFER_SIZE; + + /* + * If the timeout is -1, wait until at least one event occurs. If the + * timeout is 0, poll for events, but do not wait at all. + */ + noccurred = WaitEventSetWait(node->as_eventset, timeout, occurred_event, + nevents, WAIT_EVENT_APPEND_READY); + FreeWaitEventSet(node->as_eventset); + node->as_eventset = NULL; + if (noccurred == 0) + return; + + /* Deliver notifications. */ + for (i = 0; i < noccurred; i++) + { + WaitEvent *w = &occurred_event[i]; + + /* + * Each waiting subplan should have registered its wait event with + * user_data pointing back to its AsyncRequest. + */ + if ((w->events & WL_SOCKET_READABLE) != 0) + { + AsyncRequest *areq = (AsyncRequest *) w->user_data; + + /* + * Mark it as no longer needing a callback. We must do this + * before dispatching the callback in case the callback resets the + * flag. + */ + Assert(areq->callback_pending); + areq->callback_pending = false; + + /* Do the actual work. */ + ExecAsyncNotify(areq); + } + } +} + +/* ---------------------------------------------------------------- + * ExecAsyncAppendResponse + * + * Receive a response from an asynchronous request we made. + * ---------------------------------------------------------------- + */ +void +ExecAsyncAppendResponse(AsyncRequest *areq) +{ + AppendState *node = (AppendState *) areq->requestor; + TupleTableSlot *slot = areq->result; + + /* The result should be a TupleTableSlot or NULL. */ + Assert(slot == NULL || IsA(slot, TupleTableSlot)); + + /* Nothing to do if the request is pending. */ + if (!areq->request_complete) + { + /* The request would have been pending for a callback. */ + Assert(areq->callback_pending); + return; + } + + /* If the result is NULL or an empty slot, there's nothing more to do. */ + if (TupIsNull(slot)) + { + /* The ending subplan wouldn't have been pending for a callback. */ + Assert(!areq->callback_pending); + --node->as_nasyncremain; + return; + } + + /* Save result so we can return it. */ + Assert(node->as_nasyncresults < node->as_nasyncplans); + node->as_asyncresults[node->as_nasyncresults++] = slot; + + /* + * Mark the subplan that returned a result as ready for a new request. We + * don't launch another one here immediately because it might complete. + */ + node->as_needrequest = bms_add_member(node->as_needrequest, + areq->request_index); +} + +/* ---------------------------------------------------------------- + * classify_matching_subplans + * + * Classify the node's as_valid_subplans into sync ones and + * async ones, adjust it to contain sync ones only, and save + * async ones in the node's as_valid_asyncplans. + * ---------------------------------------------------------------- + */ +static void +classify_matching_subplans(AppendState *node) +{ + Bitmapset *valid_asyncplans; + + Assert(node->as_valid_asyncplans == NULL); + + /* Nothing to do if there are no valid subplans. */ + if (bms_is_empty(node->as_valid_subplans)) + { + node->as_syncdone = true; + node->as_nasyncremain = 0; + return; + } + + /* Nothing to do if there are no valid async subplans. */ + if (!bms_overlap(node->as_valid_subplans, node->as_asyncplans)) + { + node->as_nasyncremain = 0; + return; + } + + /* Get valid async subplans. */ + valid_asyncplans = bms_copy(node->as_asyncplans); + valid_asyncplans = bms_int_members(valid_asyncplans, + node->as_valid_subplans); + + /* Adjust the valid subplans to contain sync subplans only. */ + node->as_valid_subplans = bms_del_members(node->as_valid_subplans, + valid_asyncplans); + + /* Save valid async subplans. */ + node->as_valid_asyncplans = valid_asyncplans; +} + void ExecSquelchAppend(AppendState *node) { diff --git a/src/backend/executor/nodeBitmapAnd.c b/src/backend/executor/nodeBitmapAnd.c index e4fa9fbb00c9..4b99086091c8 100644 --- a/src/backend/executor/nodeBitmapAnd.c +++ b/src/backend/executor/nodeBitmapAnd.c @@ -3,7 +3,7 @@ * nodeBitmapAnd.c * routines to handle BitmapAnd nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 52bf52440e54..d6d53e3c599d 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -20,7 +20,7 @@ * * This can also be used in "Dynamic" mode. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2008-2009, Greenplum Inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c index b7f0cc57629d..d399e6c77e4d 100644 --- a/src/backend/executor/nodeBitmapIndexscan.c +++ b/src/backend/executor/nodeBitmapIndexscan.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2007-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeBitmapOr.c b/src/backend/executor/nodeBitmapOr.c index b6785e7e1c2c..e07568720109 100644 --- a/src/backend/executor/nodeBitmapOr.c +++ b/src/backend/executor/nodeBitmapOr.c @@ -3,7 +3,7 @@ * nodeBitmapOr.c * routines to handle BitmapOr nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeCtescan.c b/src/backend/executor/nodeCtescan.c index ac45f3380d43..8daa698d89dd 100644 --- a/src/backend/executor/nodeCtescan.c +++ b/src/backend/executor/nodeCtescan.c @@ -3,7 +3,7 @@ * nodeCtescan.c * routines to handle CteScan nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c index cfa9e46e55f1..c82060e6d1a8 100644 --- a/src/backend/executor/nodeCustom.c +++ b/src/backend/executor/nodeCustom.c @@ -3,7 +3,7 @@ * nodeCustom.c * Routines to handle execution of custom scan node * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------ diff --git a/src/backend/executor/nodeDynamicBitmapIndexscan.c b/src/backend/executor/nodeDynamicBitmapIndexscan.c index 3721afb8455f..5777e64331c2 100644 --- a/src/backend/executor/nodeDynamicBitmapIndexscan.c +++ b/src/backend/executor/nodeDynamicBitmapIndexscan.c @@ -156,7 +156,7 @@ beginCurrentBitmapIndexScan(DynamicBitmapIndexScanState *node, EState *estate, if (!OidIsValid(node->columnLayoutOid)) { /* Very first partition */ - node->columnLayoutOid = get_partition_parent(tableOid); + node->columnLayoutOid = get_partition_parent(tableOid, false); } BitmapIndexScan_ReMapColumns(dbiScan, node->columnLayoutOid, tableOid); node->columnLayoutOid = tableOid; diff --git a/src/backend/executor/nodeDynamicIndexscan.c b/src/backend/executor/nodeDynamicIndexscan.c index b255cb4ee7fd..bce06c17c53f 100644 --- a/src/backend/executor/nodeDynamicIndexscan.c +++ b/src/backend/executor/nodeDynamicIndexscan.c @@ -159,7 +159,7 @@ beginCurrentIndexScan(DynamicIndexScanState *node, EState *estate, { /* Very first partition */ // Just get the direct parent, we don't support multi-level partitioning - node->columnLayoutOid = get_partition_parent(tableOid); + node->columnLayoutOid = get_partition_parent(tableOid, false); } DynamicIndexScan_ReMapColumns(dynamicIndexScan, tableOid, node->columnLayoutOid); diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index 513471ab9b90..9dc38d47ea78 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -3,7 +3,7 @@ * nodeForeignscan.c * Routines to support scans of foreign tables * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -209,12 +209,26 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) scanstate->fdw_recheck_quals = ExecInitQual(node->fdw_recheck_quals, (PlanState *) scanstate); + /* + * Determine whether to scan the foreign relation asynchronously or not; + * this has to be kept in sync with the code in ExecInitAppend(). + */ + scanstate->ss.ps.async_capable = (((Plan *) node)->async_capable && + estate->es_epq_active == NULL); + /* * Initialize FDW-related state. */ scanstate->fdwroutine = fdwroutine; scanstate->fdw_state = NULL; + /* + * For the FDW's convenience, look up the modification target relation's. + * ResultRelInfo. + */ + if (node->resultRelation > 0) + scanstate->resultRelInfo = estate->es_result_relations[node->resultRelation - 1]; + /* Initialize any outer plan. */ if (outerPlan(node)) outerPlanState(scanstate) = @@ -384,3 +398,51 @@ ExecShutdownForeignScan(ForeignScanState *node) if (fdwroutine->ShutdownForeignScan) fdwroutine->ShutdownForeignScan(node); } + +/* ---------------------------------------------------------------- + * ExecAsyncForeignScanRequest + * + * Asynchronously request a tuple from a designed async-capable node + * ---------------------------------------------------------------- + */ +void +ExecAsyncForeignScanRequest(AsyncRequest *areq) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + FdwRoutine *fdwroutine = node->fdwroutine; + + Assert(fdwroutine->ForeignAsyncRequest != NULL); + fdwroutine->ForeignAsyncRequest(areq); +} + +/* ---------------------------------------------------------------- + * ExecAsyncForeignScanConfigureWait + * + * In async mode, configure for a wait + * ---------------------------------------------------------------- + */ +void +ExecAsyncForeignScanConfigureWait(AsyncRequest *areq) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + FdwRoutine *fdwroutine = node->fdwroutine; + + Assert(fdwroutine->ForeignAsyncConfigureWait != NULL); + fdwroutine->ForeignAsyncConfigureWait(areq); +} + +/* ---------------------------------------------------------------- + * ExecAsyncForeignScanNotify + * + * Callback invoked when a relevant event has occurred + * ---------------------------------------------------------------- + */ +void +ExecAsyncForeignScanNotify(AsyncRequest *areq) +{ + ForeignScanState *node = (ForeignScanState *) areq->requestee; + FdwRoutine *fdwroutine = node->fdwroutine; + + Assert(fdwroutine->ForeignAsyncNotify != NULL); + fdwroutine->ForeignAsyncNotify(areq); +} diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c index 8dd018323408..484ad01198b4 100644 --- a/src/backend/executor/nodeFunctionscan.c +++ b/src/backend/executor/nodeFunctionscan.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c index a01b46af1480..734142b7b16f 100644 --- a/src/backend/executor/nodeGather.c +++ b/src/backend/executor/nodeGather.c @@ -3,7 +3,7 @@ * nodeGather.c * Support routines for scanning a plan via multiple workers. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * A Gather executor launches parallel workers to run multiple copies of a @@ -266,7 +266,7 @@ gather_getnext(GatherState *gatherstate) PlanState *outerPlan = outerPlanState(gatherstate); TupleTableSlot *outerTupleSlot; TupleTableSlot *fslot = gatherstate->funnel_slot; - MinimalTuple tup; + MinimalTuple tup; while (gatherstate->nreaders > 0 || gatherstate->need_to_scan_locally) { @@ -278,7 +278,7 @@ gather_getnext(GatherState *gatherstate) if (HeapTupleIsValid(tup)) { - ExecStoreMinimalTuple(tup, /* tuple to store */ + ExecStoreMinimalTuple(tup, /* tuple to store */ fslot, /* slot to store the tuple */ false); /* don't pfree tuple */ return fslot; diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c index 47129344f327..03f02a19aabe 100644 --- a/src/backend/executor/nodeGatherMerge.c +++ b/src/backend/executor/nodeGatherMerge.c @@ -3,7 +3,7 @@ * nodeGatherMerge.c * Scan a plan in multiple workers, and do order-preserving merge. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -700,9 +700,9 @@ gather_merge_readnext(GatherMergeState *gm_state, int reader, bool nowait) Assert(tup); /* Build the TupleTableSlot for the given tuple */ - ExecStoreMinimalTuple(tup, /* tuple to store */ - gm_state->gm_slots[reader], /* slot in which to store - * the tuple */ + ExecStoreMinimalTuple(tup, /* tuple to store */ + gm_state->gm_slots[reader], /* slot in which to + * store the tuple */ true); /* pfree tuple when done with it */ return true; diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c index c9a846df660a..1721b2aae48b 100644 --- a/src/backend/executor/nodeGroup.c +++ b/src/backend/executor/nodeGroup.c @@ -3,7 +3,7 @@ * nodeGroup.c * Routines to handle group nodes (used for queries with GROUP BY clause). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index 4160144ed7fc..77ec87fe0915 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index a962f3574235..b1a1d27ee9e5 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeIncrementalSort.c b/src/backend/executor/nodeIncrementalSort.c index 6c0d24ee25a5..934426a66798 100644 --- a/src/backend/executor/nodeIncrementalSort.c +++ b/src/backend/executor/nodeIncrementalSort.c @@ -3,7 +3,7 @@ * nodeIncrementalSort.c * Routines to handle incremental sorting of relations. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -288,9 +288,7 @@ switchToPresortedPrefixMode(PlanState *pstate) { IncrementalSortState *node = castNode(IncrementalSortState, pstate); ScanDirection dir; - int64 nTuples = 0; - bool lastTuple = false; - bool firstTuple = true; + int64 nTuples; TupleDesc tupDesc; PlanState *outerNode; IncrementalSort *plannode = castNode(IncrementalSort, node->ss.ps.plan); @@ -333,7 +331,7 @@ switchToPresortedPrefixMode(PlanState *pstate) */ if (node->bounded) { - SO1_printf("Setting bound on presorted prefix tuplesort to: %ld\n", + SO1_printf("Setting bound on presorted prefix tuplesort to: " INT64_FORMAT "\n", node->bound - node->bound_Done); tuplesort_set_bound(node->prefixsort_state, node->bound - node->bound_Done); @@ -343,20 +341,16 @@ switchToPresortedPrefixMode(PlanState *pstate) * Copy as many tuples as we can (i.e., in the same prefix key group) from * the full sort state to the prefix sort state. */ - for (;;) + for (nTuples = 0; nTuples < node->n_fullsort_remaining; nTuples++) { - lastTuple = node->n_fullsort_remaining - nTuples == 1; - /* * When we encounter multiple prefix key groups inside the full sort * tuplesort we have to carry over the last read tuple into the next * batch. */ - if (firstTuple && !TupIsNull(node->transfer_tuple)) + if (nTuples == 0 && !TupIsNull(node->transfer_tuple)) { tuplesort_puttupleslot(node->prefixsort_state, node->transfer_tuple); - nTuples++; - /* The carried over tuple is our new group pivot tuple. */ ExecCopySlot(node->group_pivot, node->transfer_tuple); } @@ -376,7 +370,6 @@ switchToPresortedPrefixMode(PlanState *pstate) if (isCurrentGroup(node, node->group_pivot, node->transfer_tuple)) { tuplesort_puttupleslot(node->prefixsort_state, node->transfer_tuple); - nTuples++; } else { @@ -394,21 +387,11 @@ switchToPresortedPrefixMode(PlanState *pstate) * current prefix key group. */ ExecClearTuple(node->group_pivot); + + /* Break out of for-loop early */ break; } } - - firstTuple = false; - - /* - * If we've copied all of the tuples from the full sort state into the - * prefix sort state, then we don't actually know that we've yet found - * the last tuple in that prefix key group until we check the next - * tuple from the outer plan node, so we retain the current group - * pivot tuple prefix key group comparison. - */ - if (lastTuple) - break; } /* @@ -417,18 +400,19 @@ switchToPresortedPrefixMode(PlanState *pstate) * remaining in the large single prefix key group we think we've * encountered. */ - SO1_printf("Moving %ld tuples to presorted prefix tuplesort\n", nTuples); + SO1_printf("Moving " INT64_FORMAT " tuples to presorted prefix tuplesort\n", nTuples); node->n_fullsort_remaining -= nTuples; - SO1_printf("Setting n_fullsort_remaining to %ld\n", node->n_fullsort_remaining); + SO1_printf("Setting n_fullsort_remaining to " INT64_FORMAT "\n", node->n_fullsort_remaining); - if (lastTuple) + if (node->n_fullsort_remaining == 0) { /* - * We've confirmed that all tuples remaining in the full sort batch is - * in the same prefix key group and moved all of those tuples into the - * presorted prefix tuplesort. Now we can save our pivot comparison - * tuple and continue fetching tuples from the outer execution node to - * load into the presorted prefix tuplesort. + * We've found that all tuples remaining in the full sort batch are in + * the same prefix key group and moved all of those tuples into the + * presorted prefix tuplesort. We don't know that we've yet found the + * last tuple in the current prefix key group, so save our pivot + * comparison tuple and continue fetching tuples from the outer + * execution node to load into the presorted prefix tuplesort. */ ExecCopySlot(node->group_pivot, node->transfer_tuple); SO_printf("Setting execution_status to INCSORT_LOADPREFIXSORT (switchToPresortedPrefixMode)\n"); @@ -449,7 +433,7 @@ switchToPresortedPrefixMode(PlanState *pstate) * out all of those tuples, and then come back around to find another * batch. */ - SO1_printf("Sorting presorted prefix tuplesort with %ld tuples\n", nTuples); + SO1_printf("Sorting presorted prefix tuplesort with " INT64_FORMAT " tuples\n", nTuples); tuplesort_performsort(node->prefixsort_state); INSTRUMENT_SORT_GROUP(node, prefixsort); @@ -462,7 +446,7 @@ switchToPresortedPrefixMode(PlanState *pstate) * - n), so store the current number of processed tuples for use * in configuring sorting bound. */ - SO2_printf("Changing bound_Done from %ld to %ld\n", + SO2_printf("Changing bound_Done from " INT64_FORMAT " to " INT64_FORMAT "\n", Min(node->bound, node->bound_Done + nTuples), node->bound_Done); node->bound_Done = Min(node->bound, node->bound_Done + nTuples); } @@ -574,7 +558,7 @@ ExecIncrementalSort(PlanState *pstate) * need to re-execute the prefix mode transition function to pull * out the next prefix key group. */ - SO1_printf("Re-calling switchToPresortedPrefixMode() because n_fullsort_remaining is > 0 (%ld)\n", + SO1_printf("Re-calling switchToPresortedPrefixMode() because n_fullsort_remaining is > 0 (" INT64_FORMAT ")\n", node->n_fullsort_remaining); switchToPresortedPrefixMode(pstate); } @@ -677,9 +661,9 @@ ExecIncrementalSort(PlanState *pstate) /* * We're in full sort mode accumulating a minimum number of tuples * and not checking for prefix key equality yet, so we can't - * assume the group pivot tuple will reamin the same -- unless + * assume the group pivot tuple will remain the same -- unless * we're using a minimum group size of 1, in which case the pivot - * is obviously still the pviot. + * is obviously still the pivot. */ if (nTuples != minGroupSize) ExecClearTuple(node->group_pivot); @@ -707,7 +691,7 @@ ExecIncrementalSort(PlanState *pstate) */ node->outerNodeDone = true; - SO1_printf("Sorting fullsort with %ld tuples\n", nTuples); + SO1_printf("Sorting fullsort with " INT64_FORMAT " tuples\n", nTuples); tuplesort_performsort(fullsort_state); INSTRUMENT_SORT_GROUP(node, fullsort); @@ -776,7 +760,7 @@ ExecIncrementalSort(PlanState *pstate) * current number of processed tuples for later use * configuring the sort state's bound. */ - SO2_printf("Changing bound_Done from %ld to %ld\n", + SO2_printf("Changing bound_Done from " INT64_FORMAT " to " INT64_FORMAT "\n", node->bound_Done, Min(node->bound, node->bound_Done + nTuples)); node->bound_Done = Min(node->bound, node->bound_Done + nTuples); @@ -787,7 +771,7 @@ ExecIncrementalSort(PlanState *pstate) * sort and transition modes to reading out the sorted * tuples. */ - SO1_printf("Sorting fullsort tuplesort with %ld tuples\n", + SO1_printf("Sorting fullsort tuplesort with " INT64_FORMAT " tuples\n", nTuples); tuplesort_performsort(fullsort_state); @@ -828,7 +812,7 @@ ExecIncrementalSort(PlanState *pstate) * on FIFO retrieval semantics when transferring them to the * presorted prefix tuplesort. */ - SO1_printf("Sorting fullsort tuplesort with %ld tuples\n", nTuples); + SO1_printf("Sorting fullsort tuplesort with " INT64_FORMAT " tuples\n", nTuples); tuplesort_performsort(fullsort_state); INSTRUMENT_SORT_GROUP(node, fullsort); @@ -847,12 +831,12 @@ ExecIncrementalSort(PlanState *pstate) { int64 currentBound = node->bound - node->bound_Done; - SO2_printf("Read %ld tuples, but setting to %ld because we used bounded sort\n", + SO2_printf("Read " INT64_FORMAT " tuples, but setting to " INT64_FORMAT " because we used bounded sort\n", nTuples, Min(currentBound, nTuples)); nTuples = Min(currentBound, nTuples); } - SO1_printf("Setting n_fullsort_remaining to %ld and calling switchToPresortedPrefixMode()\n", + SO1_printf("Setting n_fullsort_remaining to " INT64_FORMAT " and calling switchToPresortedPrefixMode()\n", nTuples); /* @@ -942,7 +926,7 @@ ExecIncrementalSort(PlanState *pstate) * Perform the sort and begin returning the tuples to the parent plan * node. */ - SO1_printf("Sorting presorted prefix tuplesort with >= %ld tuples\n", nTuples); + SO1_printf("Sorting presorted prefix tuplesort with " INT64_FORMAT " tuples\n", nTuples); tuplesort_performsort(node->prefixsort_state); INSTRUMENT_SORT_GROUP(node, prefixsort); @@ -958,7 +942,7 @@ ExecIncrementalSort(PlanState *pstate) * - n), so store the current number of processed tuples for use * in configuring sorting bound. */ - SO2_printf("Changing bound_Done from %ld to %ld\n", + SO2_printf("Changing bound_Done from " INT64_FORMAT " to " INT64_FORMAT "\n", node->bound_Done, Min(node->bound, node->bound_Done + nTuples)); node->bound_Done = Min(node->bound, node->bound_Done + nTuples); @@ -1097,7 +1081,7 @@ ExecEndIncrementalSort(IncrementalSortState *node) ExecClearTuple(node->ss.ss_ScanTupleSlot); /* must drop pointer to sort result tuple */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); - /* must drop stanalone tuple slots from outer node */ + /* must drop standalone tuple slots from outer node */ ExecDropSingleTupleTableSlot(node->group_pivot); ExecDropSingleTupleTableSlot(node->transfer_tuple); @@ -1178,8 +1162,8 @@ ExecReScanIncrementalSort(IncrementalSortState *node) } /* - * If chgParam of subnode is not null, theni the plan will be re-scanned - * by the first ExecProcNode. + * If chgParam of subnode is not null, then the plan will be re-scanned by + * the first ExecProcNode. */ if (outerPlan->chgParam == NULL) ExecReScan(outerPlan); diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index 5617ac29e74c..0754e28a9aac 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -3,7 +3,7 @@ * nodeIndexonlyscan.c * Routines to support index-only scans * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index c1f0157f34e5..9ede950ce8ad 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -3,7 +3,7 @@ * nodeIndexscan.c * Routines to support indexed scans of relations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c index 95c5185aef64..00a2066c523d 100644 --- a/src/backend/executor/nodeLimit.c +++ b/src/backend/executor/nodeLimit.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -108,7 +108,7 @@ ExecLimit_guts(PlanState *pstate) } /* - * Tuple at limit is needed for comparation in subsequent + * Tuple at limit is needed for comparison in subsequent * execution to detect ties. */ if (node->limitOption == LIMIT_OPTION_WITH_TIES && diff --git a/src/backend/executor/nodeLockRows.c b/src/backend/executor/nodeLockRows.c index 56de0f8a7f77..c019f87b4849 100644 --- a/src/backend/executor/nodeLockRows.c +++ b/src/backend/executor/nodeLockRows.c @@ -3,7 +3,7 @@ * nodeLockRows.c * Routines to handle FOR UPDATE/FOR SHARE row locking * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -59,7 +59,11 @@ ExecLockRows(PlanState *pstate) slot = ExecProcNode(outerPlan); if (TupIsNull(slot)) + { + /* Release any resources held by EPQ mechanism before exiting */ + EvalPlanQualEnd(&node->lr_epqstate); return NULL; + } /* We don't need EvalPlanQual unless we get updated tuple version(s) */ epq_needed = false; @@ -386,6 +390,7 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags) void ExecEndLockRows(LockRowsState *node) { + /* We may have shut down EPQ already, but no harm in another call */ EvalPlanQualEnd(&node->lr_epqstate); ExecEndNode(outerPlanState(node)); } diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c index 15cad3679c10..a37f48266cb3 100644 --- a/src/backend/executor/nodeMaterial.c +++ b/src/backend/executor/nodeMaterial.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index 851bf314f3bd..83984ba7e3c5 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -3,7 +3,7 @@ * nodeMergeAppend.c * routines to handle MergeAppend nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index 0f38c2f5a646..59a58e165dab 100644 --- a/src/backend/executor/nodeMergejoin.c +++ b/src/backend/executor/nodeMergejoin.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 84c66d8bcc90..6d6e8f40cfb8 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -3,7 +3,7 @@ * nodeModifyTable.c * routines to handle ModifyTable nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,14 +19,10 @@ * ExecReScanModifyTable - rescan the ModifyTable node * * NOTES - * Each ModifyTable node contains a list of one or more subplans, - * much like an Append node. There is one subplan per result relation. - * The key reason for this is that in an inherited UPDATE command, each - * result relation could have a different schema (more or different - * columns) requiring a different plan tree to produce it. In an - * inherited DELETE, all the subplans should produce the same output - * rowtype, but we might still find that different plans are appropriate - * for different child relations. + * The ModifyTable node receives input from its outerPlan, which is + * the data to insert for INSERT cases, or the changed columns' new + * values plus row-locating info for UPDATE cases, or just the + * row-locating info for DELETE cases. * * If the query specifies RETURNING, then the ModifyTable returns a * RETURNING tuple after completing each row insert, update, or delete. @@ -68,6 +64,19 @@ #include "utils/snapmgr.h" +typedef struct MTTargetRelLookup +{ + Oid relationOid; /* hash key, must be first */ + int relationIndex; /* rel's index in resultRelInfo[] array */ +} MTTargetRelLookup; + +static void ExecBatchInsert(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo, + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int numSlots, + EState *estate, + bool canSetTag); static bool ExecOnConflictUpdate(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo, ItemPointer conflictTid, @@ -80,14 +89,11 @@ static TupleTableSlot *ExecPrepareTupleRouting(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, ResultRelInfo *targetRelInfo, - TupleTableSlot *slot); -static ResultRelInfo *getTargetResultRelInfo(ModifyTableState *node); -static void ExecSetupChildParentMapForSubplan(ModifyTableState *mtstate); -static TupleConversionMap *tupconv_map_for_subplan(ModifyTableState *node, - int whichplan); + TupleTableSlot *slot, + ResultRelInfo **partRelInfo); /* - * Verify that the tuples to be produced by INSERT or UPDATE match the + * Verify that the tuples to be produced by INSERT match the * target relation's rowtype * * We do this to guard against stale plans. If plan invalidation is @@ -97,6 +103,9 @@ static TupleConversionMap *tupconv_map_for_subplan(ModifyTableState *node, * * The plan output is represented by its targetlist, because that makes * handling the dropped-column case easier. + * + * We used to use this for UPDATE as well, but now the equivalent checks + * are done in ExecBuildUpdateProjection. */ static void ExecCheckPlanOutput(Relation resultRel, List *targetList) @@ -110,8 +119,7 @@ ExecCheckPlanOutput(Relation resultRel, List *targetList) TargetEntry *tle = (TargetEntry *) lfirst(lc); Form_pg_attribute attr; - if (tle->resjunk) - continue; /* ignore junk tlist items */ + Assert(!tle->resjunk); /* caller removed junk items already */ if (attno >= resultDesc->natts) ereport(ERROR, @@ -261,9 +269,10 @@ ExecCheckTIDVisible(EState *estate, * Compute stored generated columns for a tuple */ void -ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot, CmdType cmdtype) +ExecComputeStoredGenerated(ResultRelInfo *resultRelInfo, + EState *estate, TupleTableSlot *slot, + CmdType cmdtype) { - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; Relation rel = resultRelInfo->ri_RelationDesc; TupleDesc tupdesc = RelationGetDescr(rel); int natts = tupdesc->natts; @@ -301,7 +310,7 @@ ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot, CmdType cmdtype if (cmdtype == CMD_UPDATE && !(rel->trigdesc && rel->trigdesc->trig_update_before_row) && !bms_is_member(i + 1 - FirstLowInvalidHeapAttributeNumber, - exec_rt_fetch(resultRelInfo->ri_RangeTableIndex, estate)->extraUpdatedCols)) + ExecGetExtraUpdatedCols(resultRelInfo, estate))) { resultRelInfo->ri_GeneratedExprs[i] = NULL; continue; @@ -377,11 +386,217 @@ ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot, CmdType cmdtype MemoryContextSwitchTo(oldContext); } +/* + * ExecInitInsertProjection + * Do one-time initialization of projection data for INSERT tuples. + * + * INSERT queries may need a projection to filter out junk attrs in the tlist. + * + * This is also a convenient place to verify that the + * output of an INSERT matches the target table. + */ +static void +ExecInitInsertProjection(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo) +{ + ModifyTable *node = (ModifyTable *) mtstate->ps.plan; + Plan *subplan = outerPlan(node); + EState *estate = mtstate->ps.state; + List *insertTargetList = NIL; + bool need_projection = false; + ListCell *l; + + /* Extract non-junk columns of the subplan's result tlist. */ + foreach(l, subplan->targetlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(l); + + if (!tle->resjunk) + insertTargetList = lappend(insertTargetList, tle); + else + need_projection = true; + } + + /* + * The junk-free list must produce a tuple suitable for the result + * relation. + */ + ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc, insertTargetList); + + /* We'll need a slot matching the table's format. */ + resultRelInfo->ri_newTupleSlot = + table_slot_create(resultRelInfo->ri_RelationDesc, + &estate->es_tupleTable); + + /* Build ProjectionInfo if needed (it probably isn't). */ + if (need_projection) + { + TupleDesc relDesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); + + /* need an expression context to do the projection */ + if (mtstate->ps.ps_ExprContext == NULL) + ExecAssignExprContext(estate, &mtstate->ps); + + resultRelInfo->ri_projectNew = + ExecBuildProjectionInfo(insertTargetList, + mtstate->ps.ps_ExprContext, + resultRelInfo->ri_newTupleSlot, + &mtstate->ps, + relDesc); + } + + resultRelInfo->ri_projectNewInfoValid = true; +} + +/* + * ExecInitUpdateProjection + * Do one-time initialization of projection data for UPDATE tuples. + * + * UPDATE always needs a projection, because (1) there's always some junk + * attrs, and (2) we may need to merge values of not-updated columns from + * the old tuple into the final tuple. In UPDATE, the tuple arriving from + * the subplan contains only new values for the changed columns, plus row + * identity info in the junk attrs. + * + * This is "one-time" for any given result rel, but we might touch more than + * one result rel in the course of an inherited UPDATE, and each one needs + * its own projection due to possible column order variation. + * + * This is also a convenient place to verify that the output of an UPDATE + * matches the target table (ExecBuildUpdateProjection does that). + */ +static void +ExecInitUpdateProjection(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo) +{ + ModifyTable *node = (ModifyTable *) mtstate->ps.plan; + Plan *subplan = outerPlan(node); + EState *estate = mtstate->ps.state; + TupleDesc relDesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); + int whichrel; + List *updateColnos; + + /* + * Usually, mt_lastResultIndex matches the target rel. If it happens not + * to, we can get the index the hard way with an integer division. + */ + whichrel = mtstate->mt_lastResultIndex; + if (resultRelInfo != mtstate->resultRelInfo + whichrel) + { + whichrel = resultRelInfo - mtstate->resultRelInfo; + Assert(whichrel >= 0 && whichrel < mtstate->mt_nrels); + } + + updateColnos = (List *) list_nth(node->updateColnosLists, whichrel); + + /* + * For UPDATE, we use the old tuple to fill up missing values in the tuple + * produced by the subplan to get the new tuple. We need two slots, both + * matching the table's desired format. + */ + resultRelInfo->ri_oldTupleSlot = + table_slot_create(resultRelInfo->ri_RelationDesc, + &estate->es_tupleTable); + resultRelInfo->ri_newTupleSlot = + table_slot_create(resultRelInfo->ri_RelationDesc, + &estate->es_tupleTable); + + /* need an expression context to do the projection */ + if (mtstate->ps.ps_ExprContext == NULL) + ExecAssignExprContext(estate, &mtstate->ps); + + resultRelInfo->ri_projectNew = + ExecBuildUpdateProjection(subplan->targetlist, + false, /* subplan did the evaluation */ + updateColnos, + relDesc, + mtstate->ps.ps_ExprContext, + resultRelInfo->ri_newTupleSlot, + &mtstate->ps); + + resultRelInfo->ri_projectNewInfoValid = true; +} + +/* + * ExecGetInsertNewTuple + * This prepares a "new" tuple ready to be inserted into given result + * relation, by removing any junk columns of the plan's output tuple + * and (if necessary) coercing the tuple to the right tuple format. + */ +static TupleTableSlot * +ExecGetInsertNewTuple(ResultRelInfo *relinfo, + TupleTableSlot *planSlot) +{ + ProjectionInfo *newProj = relinfo->ri_projectNew; + ExprContext *econtext; + + /* + * If there's no projection to be done, just make sure the slot is of the + * right type for the target rel. If the planSlot is the right type we + * can use it as-is, else copy the data into ri_newTupleSlot. + */ + if (newProj == NULL) + { + if (relinfo->ri_newTupleSlot->tts_ops != planSlot->tts_ops) + { + ExecCopySlot(relinfo->ri_newTupleSlot, planSlot); + return relinfo->ri_newTupleSlot; + } + else + return planSlot; + } + + /* + * Else project; since the projection output slot is ri_newTupleSlot, this + * will also fix any slot-type problem. + * + * Note: currently, this is dead code, because INSERT cases don't receive + * any junk columns so there's never a projection to be done. + */ + econtext = newProj->pi_exprContext; + econtext->ecxt_outertuple = planSlot; + return ExecProject(newProj); +} + +/* + * ExecGetUpdateNewTuple + * This prepares a "new" tuple by combining an UPDATE subplan's output + * tuple (which contains values of changed columns) with unchanged + * columns taken from the old tuple. + * + * The subplan tuple might also contain junk columns, which are ignored. + * Note that the projection also ensures we have a slot of the right type. + */ +TupleTableSlot * +ExecGetUpdateNewTuple(ResultRelInfo *relinfo, + TupleTableSlot *planSlot, + TupleTableSlot *oldSlot) +{ + ProjectionInfo *newProj = relinfo->ri_projectNew; + ExprContext *econtext; + + /* Use a few extra Asserts to protect against outside callers */ + Assert(relinfo->ri_projectNewInfoValid); + Assert(planSlot != NULL && !TTS_EMPTY(planSlot)); + Assert(oldSlot != NULL && !TTS_EMPTY(oldSlot)); + + econtext = newProj->pi_exprContext; + econtext->ecxt_outertuple = planSlot; + econtext->ecxt_scantuple = oldSlot; + return ExecProject(newProj); +} + + /* ---------------------------------------------------------------- * ExecInsert * * For INSERT, we have to insert the tuple into the target relation - * and insert appropriate tuples into the index relations. + * (or partition thereof) and insert appropriate tuples into the index + * relations. + * + * slot contains the new tuple value to be stored. + * planSlot is the output of the ModifyTable's subplan; we use it + * to access "junk" columns that are not going to be stored. * * Returns RETURNING result if any, otherwise NULL. * @@ -396,31 +611,54 @@ ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot, CmdType cmdtype * there is a preceding SplitUpdate node. 'splitUpdate' is true in * that case. * + * This may change the currently active tuple conversion map in + * mtstate->mt_transition_capture, so the callers must take care to + * save the previous value to avoid losing track of it. * ---------------------------------------------------------------- */ static TupleTableSlot * ExecInsert(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo, TupleTableSlot *slot, TupleTableSlot *planSlot, EState *estate, bool canSetTag, bool splitUpdate) { - ResultRelInfo *resultRelInfo; Relation resultRelationDesc; List *recheckIndexes = NIL; TupleTableSlot *result = NULL; TransitionCaptureState *ar_insert_trig_tcs; ModifyTable *node = (ModifyTable *) mtstate->ps.plan; OnConflictAction onconflict = node->onConflictAction; + PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; + MemoryContext oldContext; + + /* + * If the input result relation is a partitioned table, find the leaf + * partition to insert the tuple into. + */ + if (proute) + { + ResultRelInfo *partRelInfo; + + slot = ExecPrepareTupleRouting(mtstate, estate, proute, + resultRelInfo, slot, + &partRelInfo); + resultRelInfo = partRelInfo; + } ExecMaterializeSlot(slot); + resultRelationDesc = resultRelInfo->ri_RelationDesc; + /* - * get information on the (current) result relation + * Open the table's indexes, if we have not done so already, so that we + * can add new index entries for the inserted tuple. */ - resultRelInfo = estate->es_result_relation_info; - resultRelationDesc = resultRelInfo->ri_RelationDesc; + if (resultRelationDesc->rd_rel->relhasindex && + resultRelInfo->ri_IndexRelationDescs == NULL) + ExecOpenIndices(resultRelInfo, onconflict != ONCONFLICT_NONE); /* * BEFORE ROW INSERT Triggers. @@ -453,12 +691,85 @@ ExecInsert(ModifyTableState *mtstate, } else if (resultRelInfo->ri_FdwRoutine) { + /* + * GENERATED expressions might reference the tableoid column, so + * (re-)initialize tts_tableOid before evaluating them. + */ + slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + /* * Compute stored generated columns */ if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_generated_stored) - ExecComputeStoredGenerated(estate, slot, CMD_INSERT); + ExecComputeStoredGenerated(resultRelInfo, estate, slot, + CMD_INSERT); + + /* + * If the FDW supports batching, and batching is requested, accumulate + * rows and insert them in batches. Otherwise use the per-row inserts. + */ + if (resultRelInfo->ri_BatchSize > 1) + { + /* + * If a certain number of tuples have already been accumulated, or + * a tuple has come for a different relation than that for the + * accumulated tuples, perform the batch insert + */ + if (resultRelInfo->ri_NumSlots == resultRelInfo->ri_BatchSize) + { + ExecBatchInsert(mtstate, resultRelInfo, + resultRelInfo->ri_Slots, + resultRelInfo->ri_PlanSlots, + resultRelInfo->ri_NumSlots, + estate, canSetTag); + resultRelInfo->ri_NumSlots = 0; + } + + oldContext = MemoryContextSwitchTo(estate->es_query_cxt); + + if (resultRelInfo->ri_Slots == NULL) + { + resultRelInfo->ri_Slots = palloc(sizeof(TupleTableSlot *) * + resultRelInfo->ri_BatchSize); + resultRelInfo->ri_PlanSlots = palloc(sizeof(TupleTableSlot *) * + resultRelInfo->ri_BatchSize); + } + + /* + * Initialize the batch slots. We don't know how many slots will + * be needed, so we initialize them as the batch grows, and we + * keep them across batches. To mitigate an inefficiency in how + * resource owner handles objects with many references (as with + * many slots all referencing the same tuple descriptor) we copy + * the tuple descriptor for each slot. + */ + if (resultRelInfo->ri_NumSlots >= resultRelInfo->ri_NumSlotsInitialized) + { + TupleDesc tdesc = CreateTupleDescCopy(slot->tts_tupleDescriptor); + + resultRelInfo->ri_Slots[resultRelInfo->ri_NumSlots] = + MakeSingleTupleTableSlot(tdesc, slot->tts_ops); + + resultRelInfo->ri_PlanSlots[resultRelInfo->ri_NumSlots] = + MakeSingleTupleTableSlot(tdesc, planSlot->tts_ops); + + /* remember how many batch slots we initialized */ + resultRelInfo->ri_NumSlotsInitialized++; + } + + ExecCopySlot(resultRelInfo->ri_Slots[resultRelInfo->ri_NumSlots], + slot); + + ExecCopySlot(resultRelInfo->ri_PlanSlots[resultRelInfo->ri_NumSlots], + planSlot); + + resultRelInfo->ri_NumSlots++; + + MemoryContextSwitchTo(oldContext); + + return NULL; + } /* * insert into foreign table: let the FDW do it @@ -474,7 +785,7 @@ ExecInsert(ModifyTableState *mtstate, /* * AFTER ROW Triggers or RETURNING expressions might reference the * tableoid column, so (re-)initialize tts_tableOid before evaluating - * them. + * them. (This covers the case where the FDW replaced the slot.) */ slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); } @@ -483,8 +794,8 @@ ExecInsert(ModifyTableState *mtstate, WCOKind wco_kind; /* - * Constraints might reference the tableoid column, so (re-)initialize - * tts_tableOid before evaluating them. + * Constraints and GENERATED expressions might reference the tableoid + * column, so (re-)initialize tts_tableOid before evaluating them. */ slot->tts_tableOid = RelationGetRelid(resultRelationDesc); @@ -493,7 +804,8 @@ ExecInsert(ModifyTableState *mtstate, */ if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_generated_stored) - ExecComputeStoredGenerated(estate, slot, CMD_INSERT); + ExecComputeStoredGenerated(resultRelInfo, estate, slot, + CMD_INSERT); /* * Check any RLS WITH CHECK policies. @@ -525,8 +837,8 @@ ExecInsert(ModifyTableState *mtstate, * one; except that if we got here via tuple-routing, we don't need to * if there's no BR trigger defined on the partition. */ - if (resultRelInfo->ri_PartitionCheck && - (resultRelInfo->ri_PartitionRoot == NULL || + if (resultRelationDesc->rd_rel->relispartition && + (resultRelInfo->ri_RootResultRelInfo == NULL || (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_insert_before_row))) ExecPartitionCheck(resultRelInfo, slot, estate, true); @@ -555,8 +867,8 @@ ExecInsert(ModifyTableState *mtstate, */ vlock: specConflict = false; - if (!ExecCheckIndexConstraints(slot, estate, &conflictTid, - arbiterIndexes)) + if (!ExecCheckIndexConstraints(resultRelInfo, slot, estate, + &conflictTid, arbiterIndexes)) { /* committed conflict tuple found */ if (onconflict == ONCONFLICT_UPDATE) @@ -616,7 +928,8 @@ ExecInsert(ModifyTableState *mtstate, specToken); /* insert index entries for tuple */ - recheckIndexes = ExecInsertIndexTuples(slot, estate, true, + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, + slot, estate, false, true, &specConflict, arbiterIndexes); @@ -655,15 +968,13 @@ ExecInsert(ModifyTableState *mtstate, /* insert index entries for tuple */ if (resultRelInfo->ri_NumIndices > 0) - recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, - NIL); + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, + slot, estate, false, + false, NULL, NIL); } } if (canSetTag) - { (estate->es_processed)++; - setLastTid(&slot->tts_tid); - } /* * If this insert is the result of a partition key update that moved the @@ -723,6 +1034,64 @@ ExecInsert(ModifyTableState *mtstate, return result; } +/* ---------------------------------------------------------------- + * ExecBatchInsert + * + * Insert multiple tuples in an efficient way. + * Currently, this handles inserting into a foreign table without + * RETURNING clause. + * ---------------------------------------------------------------- + */ +static void +ExecBatchInsert(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo, + TupleTableSlot **slots, + TupleTableSlot **planSlots, + int numSlots, + EState *estate, + bool canSetTag) +{ + int i; + int numInserted = numSlots; + TupleTableSlot *slot = NULL; + TupleTableSlot **rslots; + + /* + * insert into foreign table: let the FDW do it + */ + rslots = resultRelInfo->ri_FdwRoutine->ExecForeignBatchInsert(estate, + resultRelInfo, + slots, + planSlots, + &numInserted); + + for (i = 0; i < numInserted; i++) + { + slot = rslots[i]; + + /* + * AFTER ROW Triggers or RETURNING expressions might reference the + * tableoid column, so (re-)initialize tts_tableOid before evaluating + * them. + */ + slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + + /* AFTER ROW INSERT Triggers */ + ExecARInsertTriggers(estate, resultRelInfo, slot, NIL, + mtstate->mt_transition_capture); + + /* + * Check any WITH CHECK OPTION constraints from parent views. See the + * comment in ExecInsert. + */ + if (resultRelInfo->ri_WithCheckOptions != NIL) + ExecWithCheckOptions(WCO_VIEW_CHECK, resultRelInfo, slot, estate); + } + + if (canSetTag && numInserted > 0) + estate->es_processed += numInserted; +} + /* ---------------------------------------------------------------- * ExecDelete * @@ -750,6 +1119,7 @@ ExecInsert(ModifyTableState *mtstate, */ static TupleTableSlot * ExecDelete(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo, ItemPointer tupleid, int32 segid, HeapTuple oldtuple, @@ -763,8 +1133,7 @@ ExecDelete(ModifyTableState *mtstate, bool *tupleDeleted, TupleTableSlot **epqreturnslot) { - ResultRelInfo *resultRelInfo; - Relation resultRelationDesc; + Relation resultRelationDesc = resultRelInfo->ri_RelationDesc; TM_Result result; TM_FailureData tmfd; TupleTableSlot *slot = NULL; @@ -788,10 +1157,12 @@ ExecDelete(ModifyTableState *mtstate, segid); /* - * get information on the (current) result relation + * In PG14 the executor passes the target ResultRelInfo down as a + * parameter; es_result_relation_info is no longer set up before the + * ModifyTable per-tuple switch dispatches here, so reading it would yield + * NULL on the first tuple. Use the parameter (already captured into + * resultRelInfo/resultRelationDesc above), matching ExecInsert/ExecUpdate. */ - resultRelInfo = estate->es_result_relation_info; - resultRelationDesc = resultRelInfo->ri_RelationDesc; /* BEFORE ROW DELETE Triggers */ /* @@ -1145,6 +1516,169 @@ ldelete:; return NULL; } +/* + * ExecCrossPartitionUpdate --- Move an updated tuple to another partition. + * + * This works by first deleting the old tuple from the current partition, + * followed by inserting the new tuple into the root parent table, that is, + * mtstate->rootResultRelInfo. It will be re-routed from there to the + * correct partition. + * + * Returns true if the tuple has been successfully moved, or if it's found + * that the tuple was concurrently deleted so there's nothing more to do + * for the caller. + * + * False is returned if the tuple we're trying to move is found to have been + * concurrently updated. In that case, the caller must to check if the + * updated tuple that's returned in *retry_slot still needs to be re-routed, + * and call this function again or perform a regular update accordingly. + */ +static bool +ExecCrossPartitionUpdate(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo, + ItemPointer tupleid, HeapTuple oldtuple, + TupleTableSlot *slot, TupleTableSlot *planSlot, + EPQState *epqstate, int32 segid, bool canSetTag, + TupleTableSlot **retry_slot, + TupleTableSlot **inserted_tuple) +{ + EState *estate = mtstate->ps.state; + TupleConversionMap *tupconv_map; + bool tuple_deleted; + TupleTableSlot *epqslot = NULL; + + *inserted_tuple = NULL; + *retry_slot = NULL; + + /* + * Disallow an INSERT ON CONFLICT DO UPDATE that causes the original row + * to migrate to a different partition. Maybe this can be implemented + * some day, but it seems a fringe feature with little redeeming value. + */ + if (((ModifyTable *) mtstate->ps.plan)->onConflictAction == ONCONFLICT_UPDATE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("invalid ON UPDATE specification"), + errdetail("The result tuple would appear in a different partition than the original tuple."))); + + /* + * When an UPDATE is run directly on a leaf partition, simply fail with a + * partition constraint violation error. + */ + if (resultRelInfo == mtstate->rootResultRelInfo) + ExecPartitionCheckEmitError(resultRelInfo, slot, estate); + + /* Initialize tuple routing info if not already done. */ + if (mtstate->mt_partition_tuple_routing == NULL) + { + Relation rootRel = mtstate->rootResultRelInfo->ri_RelationDesc; + MemoryContext oldcxt; + + /* Things built here have to last for the query duration. */ + oldcxt = MemoryContextSwitchTo(estate->es_query_cxt); + + mtstate->mt_partition_tuple_routing = + ExecSetupPartitionTupleRouting(estate, rootRel); + + /* + * Before a partition's tuple can be re-routed, it must first be + * converted to the root's format, so we'll need a slot for storing + * such tuples. + */ + Assert(mtstate->mt_root_tuple_slot == NULL); + mtstate->mt_root_tuple_slot = table_slot_create(rootRel, NULL); + + MemoryContextSwitchTo(oldcxt); + } + + /* + * Row movement, part 1. Delete the tuple, but skip RETURNING processing. + * We want to return rows from INSERT. + */ + ExecDelete(mtstate, resultRelInfo, tupleid, segid, oldtuple, planSlot, + epqstate, estate, + false, /* processReturning */ + false, /* canSetTag */ + true, /* changingPart */ + false, /* splitUpdate */ + &tuple_deleted, &epqslot); + + /* + * For some reason if DELETE didn't happen (e.g. trigger prevented it, or + * it was already deleted by self, or it was concurrently deleted by + * another transaction), then we should skip the insert as well; + * otherwise, an UPDATE could cause an increase in the total number of + * rows across all partitions, which is clearly wrong. + * + * For a normal UPDATE, the case where the tuple has been the subject of a + * concurrent UPDATE or DELETE would be handled by the EvalPlanQual + * machinery, but for an UPDATE that we've translated into a DELETE from + * this partition and an INSERT into some other partition, that's not + * available, because CTID chains can't span relation boundaries. We + * mimic the semantics to a limited extent by skipping the INSERT if the + * DELETE fails to find a tuple. This ensures that two concurrent + * attempts to UPDATE the same tuple at the same time can't turn one tuple + * into two, and that an UPDATE of a just-deleted tuple can't resurrect + * it. + */ + if (!tuple_deleted) + { + /* + * epqslot will be typically NULL. But when ExecDelete() finds that + * another transaction has concurrently updated the same row, it + * re-fetches the row, skips the delete, and epqslot is set to the + * re-fetched tuple slot. In that case, we need to do all the checks + * again. + */ + if (TupIsNull(epqslot)) + return true; + else + { + /* Fetch the most recent version of old tuple. */ + TupleTableSlot *oldSlot; + + /* ... but first, make sure ri_oldTupleSlot is initialized. */ + if (unlikely(!resultRelInfo->ri_projectNewInfoValid)) + ExecInitUpdateProjection(mtstate, resultRelInfo); + oldSlot = resultRelInfo->ri_oldTupleSlot; + if (!table_tuple_fetch_row_version(resultRelInfo->ri_RelationDesc, + tupleid, + SnapshotAny, + oldSlot)) + elog(ERROR, "failed to fetch tuple being updated"); + *retry_slot = ExecGetUpdateNewTuple(resultRelInfo, epqslot, + oldSlot); + return false; + } + } + + /* + * resultRelInfo is one of the per-relation resultRelInfos. So we should + * convert the tuple into root's tuple descriptor if needed, since + * ExecInsert() starts the search from root. + */ + tupconv_map = ExecGetChildToRootMap(resultRelInfo); + if (tupconv_map != NULL) + slot = execute_attr_map_slot(tupconv_map->attrMap, + slot, + mtstate->mt_root_tuple_slot); + + /* Tuple routing starts from the root table. */ + *inserted_tuple = ExecInsert(mtstate, mtstate->rootResultRelInfo, slot, + planSlot, estate, canSetTag, + false /* splitUpdate */); + + /* + * Reset the transition state that may possibly have been written by + * INSERT. + */ + if (mtstate->mt_transition_capture) + mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL; + + /* We're done moving. */ + return true; +} + /* ---------------------------------------------------------------- * ExecUpdate * @@ -1164,11 +1698,17 @@ ldelete:; * foreign table triggers; it is NULL when the foreign table has * no relevant triggers. * + * slot contains the new tuple value to be stored. + * planSlot is the output of the ModifyTable's subplan; we use it + * to access values from other input tables (for RETURNING), + * row-ID junk columns, etc. + * * Returns RETURNING result if any, otherwise NULL. * ---------------------------------------------------------------- */ static TupleTableSlot * ExecUpdate(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo, ItemPointer tupleid, HeapTuple oldtuple, TupleTableSlot *slot, @@ -1178,12 +1718,10 @@ ExecUpdate(ModifyTableState *mtstate, EState *estate, bool canSetTag) { - ResultRelInfo *resultRelInfo; - Relation resultRelationDesc; + Relation resultRelationDesc = resultRelInfo->ri_RelationDesc; TM_Result result; TM_FailureData tmfd; List *recheckIndexes = NIL; - TupleConversionMap *saved_tcs_map = NULL; /* * abort the operation if not running transactions @@ -1208,10 +1746,12 @@ ExecUpdate(ModifyTableState *mtstate, ExecMaterializeSlot(slot); /* - * get information on the (current) result relation + * Open the table's indexes, if we have not done so already, so that we + * can add new index entries for the updated tuple. */ - resultRelInfo = estate->es_result_relation_info; - resultRelationDesc = resultRelInfo->ri_RelationDesc; + if (resultRelationDesc->rd_rel->relhasindex && + resultRelInfo->ri_IndexRelationDescs == NULL) + ExecOpenIndices(resultRelInfo, false); /* BEFORE ROW UPDATE Triggers */ if (resultRelInfo->ri_TrigDesc && @@ -1232,12 +1772,19 @@ ExecUpdate(ModifyTableState *mtstate, } else if (resultRelInfo->ri_FdwRoutine) { + /* + * GENERATED expressions might reference the tableoid column, so + * (re-)initialize tts_tableOid before evaluating them. + */ + slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + /* * Compute stored generated columns */ if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_generated_stored) - ExecComputeStoredGenerated(estate, slot, CMD_UPDATE); + ExecComputeStoredGenerated(resultRelInfo, estate, slot, + CMD_UPDATE); /* * update in foreign table: let the FDW do it @@ -1253,7 +1800,7 @@ ExecUpdate(ModifyTableState *mtstate, /* * AFTER ROW Triggers or RETURNING expressions might reference the * tableoid column, so (re-)initialize tts_tableOid before evaluating - * them. + * them. (This covers the case where the FDW replaced the slot.) */ slot->tts_tableOid = RelationGetRelid(resultRelationDesc); } @@ -1264,8 +1811,8 @@ ExecUpdate(ModifyTableState *mtstate, bool update_indexes; /* - * Constraints might reference the tableoid column, so (re-)initialize - * tts_tableOid before evaluating them. + * Constraints and GENERATED expressions might reference the tableoid + * column, so (re-)initialize tts_tableOid before evaluating them. */ slot->tts_tableOid = RelationGetRelid(resultRelationDesc); @@ -1274,7 +1821,8 @@ ExecUpdate(ModifyTableState *mtstate, */ if (resultRelationDesc->rd_att->constr && resultRelationDesc->rd_att->constr->has_generated_stored) - ExecComputeStoredGenerated(estate, slot, CMD_UPDATE); + ExecComputeStoredGenerated(resultRelInfo, estate, slot, + CMD_UPDATE); /* * Check any RLS UPDATE WITH CHECK policies @@ -1298,7 +1846,7 @@ lreplace:; * row. So skip the WCO checks if the partition constraint fails. */ partition_constraint_failed = - resultRelInfo->ri_PartitionCheck && + resultRelationDesc->rd_rel->relispartition && !ExecPartitionCheck(resultRelInfo, slot, estate, false); if (!partition_constraint_failed && @@ -1318,128 +1866,29 @@ lreplace:; */ if (partition_constraint_failed) { - bool tuple_deleted; - TupleTableSlot *ret_slot; - TupleTableSlot *epqslot = NULL; - PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; - int map_index; - TupleConversionMap *tupconv_map; - - /* - * Disallow an INSERT ON CONFLICT DO UPDATE that causes the - * original row to migrate to a different partition. Maybe this - * can be implemented some day, but it seems a fringe feature with - * little redeeming value. - */ - if (((ModifyTable *) mtstate->ps.plan)->onConflictAction == ONCONFLICT_UPDATE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("invalid ON UPDATE specification"), - errdetail("The result tuple would appear in a different partition than the original tuple."))); - - /* - * When an UPDATE is run on a leaf partition, we will not have - * partition tuple routing set up. In that case, fail with - * partition constraint violation error. - */ - if (proute == NULL) - ExecPartitionCheckEmitError(resultRelInfo, slot, estate); - - /* - * Row movement, part 1. Delete the tuple, but skip RETURNING - * processing. We want to return rows from INSERT. - */ - ExecDelete(mtstate, tupleid, segid, oldtuple, planSlot, epqstate, - estate, false, false /* canSetTag */ , - true /* changingPart */ , - false /* splitUpdate */ , - &tuple_deleted, &epqslot); + TupleTableSlot *inserted_tuple, + *retry_slot; + bool retry; /* - * For some reason if DELETE didn't happen (e.g. trigger prevented - * it, or it was already deleted by self, or it was concurrently - * deleted by another transaction), then we should skip the insert - * as well; otherwise, an UPDATE could cause an increase in the - * total number of rows across all partitions, which is clearly - * wrong. - * - * For a normal UPDATE, the case where the tuple has been the - * subject of a concurrent UPDATE or DELETE would be handled by - * the EvalPlanQual machinery, but for an UPDATE that we've - * translated into a DELETE from this partition and an INSERT into - * some other partition, that's not available, because CTID chains - * can't span relation boundaries. We mimic the semantics to a - * limited extent by skipping the INSERT if the DELETE fails to - * find a tuple. This ensures that two concurrent attempts to - * UPDATE the same tuple at the same time can't turn one tuple - * into two, and that an UPDATE of a just-deleted tuple can't - * resurrect it. + * ExecCrossPartitionUpdate will first DELETE the row from the + * partition it's currently in and then insert it back into the + * root table, which will re-route it to the correct partition. + * The first part may have to be repeated if it is detected that + * the tuple we're trying to move has been concurrently updated. */ - if (!tuple_deleted) + retry = !ExecCrossPartitionUpdate(mtstate, resultRelInfo, tupleid, + oldtuple, slot, planSlot, + epqstate, segid, canSetTag, + &retry_slot, &inserted_tuple); + if (retry) { - /* - * epqslot will be typically NULL. But when ExecDelete() - * finds that another transaction has concurrently updated the - * same row, it re-fetches the row, skips the delete, and - * epqslot is set to the re-fetched tuple slot. In that case, - * we need to do all the checks again. - */ - if (TupIsNull(epqslot)) - return NULL; - else - { - slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); - goto lreplace; - } + slot = retry_slot; + goto lreplace; } - /* - * Updates set the transition capture map only when a new subplan - * is chosen. But for inserts, it is set for each row. So after - * INSERT, we need to revert back to the map created for UPDATE; - * otherwise the next UPDATE will incorrectly use the one created - * for INSERT. So first save the one created for UPDATE. - */ - if (mtstate->mt_transition_capture) - saved_tcs_map = mtstate->mt_transition_capture->tcs_map; - - /* - * resultRelInfo is one of the per-subplan resultRelInfos. So we - * should convert the tuple into root's tuple descriptor, since - * ExecInsert() starts the search from root. The tuple conversion - * map list is in the order of mtstate->resultRelInfo[], so to - * retrieve the one for this resultRel, we need to know the - * position of the resultRel in mtstate->resultRelInfo[]. - */ - map_index = resultRelInfo - mtstate->resultRelInfo; - Assert(map_index >= 0 && map_index < mtstate->mt_nplans); - tupconv_map = tupconv_map_for_subplan(mtstate, map_index); - if (tupconv_map != NULL) - slot = execute_attr_map_slot(tupconv_map->attrMap, - slot, - mtstate->mt_root_tuple_slot); - - /* - * Prepare for tuple routing, making it look like we're inserting - * into the root. - */ - Assert(mtstate->rootResultRelInfo != NULL); - slot = ExecPrepareTupleRouting(mtstate, estate, proute, - mtstate->rootResultRelInfo, slot); - - ret_slot = ExecInsert(mtstate, slot, planSlot, - estate, canSetTag, false /* splitUpdate */); - - /* Revert ExecPrepareTupleRouting's node change. */ - estate->es_result_relation_info = resultRelInfo; - if (mtstate->mt_transition_capture) - { - mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL; - mtstate->mt_transition_capture->tcs_map = saved_tcs_map; - } - - return ret_slot; - } + return inserted_tuple; + } /* * Check the constraints of the tuple. We've already checked the @@ -1516,6 +1965,7 @@ lreplace:; { TupleTableSlot *inputslot; TupleTableSlot *epqslot; + TupleTableSlot *oldSlot; if (IsolationUsesXactSnapshot()) ereport(ERROR, @@ -1549,7 +1999,19 @@ lreplace:; /* Tuple not passing quals anymore, exiting... */ return NULL; - slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); + /* Make sure ri_oldTupleSlot is initialized. */ + if (unlikely(!resultRelInfo->ri_projectNewInfoValid)) + ExecInitUpdateProjection(mtstate, resultRelInfo); + + /* Fetch the most recent version of old tuple. */ + oldSlot = resultRelInfo->ri_oldTupleSlot; + if (!table_tuple_fetch_row_version(resultRelationDesc, + tupleid, + SnapshotAny, + oldSlot)) + elog(ERROR, "failed to fetch tuple being updated"); + slot = ExecGetUpdateNewTuple(resultRelInfo, + epqslot, oldSlot); goto lreplace; case TM_Deleted: @@ -1602,7 +2064,9 @@ lreplace:; /* insert index entries for tuple if necessary */ if (resultRelInfo->ri_NumIndices > 0 && update_indexes) - recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, NIL); + recheckIndexes = ExecInsertIndexTuples(resultRelInfo, + slot, estate, true, false, + NULL, NIL); } if (canSetTag) (estate->es_processed)++; @@ -1637,6 +2101,133 @@ lreplace:; return NULL; } +/* + * Does an inheritance child's column layout match the root's? + * + * The SplitUpdate subplan emits new tuples in the root relation's layout; + * re-inserting one into a child without tuple routing is only sound when + * the child's attributes line up one-to-one with the root's. + */ +static bool +inh_child_layout_matches_root(ResultRelInfo *childInfo, ResultRelInfo *rootInfo) +{ + TupleDesc cdesc = RelationGetDescr(childInfo->ri_RelationDesc); + TupleDesc rdesc = RelationGetDescr(rootInfo->ri_RelationDesc); + + if (cdesc->natts != rdesc->natts) + return false; + + for (int i = 0; i < cdesc->natts; i++) + { + Form_pg_attribute catt = TupleDescAttr(cdesc, i); + Form_pg_attribute ratt = TupleDescAttr(rdesc, i); + + if (catt->attisdropped != ratt->attisdropped) + return false; + if (catt->attisdropped) + continue; + if (strcmp(NameStr(catt->attname), NameStr(ratt->attname)) != 0 || + catt->atttypid != ratt->atttypid || + catt->atttypmod != ratt->atttypmod) + return false; + } + + return true; +} + +/* + * Rebuild the complete new tuple of an inheritance child for the INSERT + * half of a split update. + * + * The subplan emits the new tuple in the root relation's column layout, + * which loses child-only columns. The "wholerow" junk column carries the + * old child tuple; start from it and overlay the root-layout new values, + * matching columns by name. + */ +static TupleTableSlot * +ExecInhRebuildNewTuple(ModifyTableState *mtstate, + ResultRelInfo *resultRelInfo, + TupleTableSlot *planSlot) +{ + EState *estate = mtstate->ps.state; + Relation rel = resultRelInfo->ri_RelationDesc; + TupleDesc cdesc = RelationGetDescr(rel); + TupleTableSlot *newslot; + AttrNumber *map; + Datum wrdatum; + bool isNull; + HeapTupleHeader wrheader; + HeapTupleData wrtuple; + + if (!AttributeNumberIsValid(resultRelInfo->ri_wholerow_attno)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("UPDATE of a distribution key column on inheritance parent \"%s\" is not supported because child table \"%s\" has a different column layout", + RelationGetRelationName(mtstate->rootResultRelInfo->ri_RelationDesc), + RelationGetRelationName(rel)))); + + /* First time through for this child: build slot and column map */ + if (resultRelInfo->ri_inhNewSlot == NULL) + { + MemoryContext oldcxt = MemoryContextSwitchTo(estate->es_query_cxt); + TupleDesc rdesc = RelationGetDescr(mtstate->rootResultRelInfo->ri_RelationDesc); + + resultRelInfo->ri_inhNewSlot = + ExecAllocTableSlot(&estate->es_tupleTable, cdesc, &TTSOpsVirtual); + + map = (AttrNumber *) palloc0(cdesc->natts * sizeof(AttrNumber)); + for (int i = 0; i < cdesc->natts; i++) + { + Form_pg_attribute catt = TupleDescAttr(cdesc, i); + + if (catt->attisdropped) + continue; + for (int j = 0; j < rdesc->natts; j++) + { + Form_pg_attribute ratt = TupleDescAttr(rdesc, j); + + if (!ratt->attisdropped && + strcmp(NameStr(catt->attname), NameStr(ratt->attname)) == 0) + { + map[i] = j + 1; + break; + } + } + } + resultRelInfo->ri_inhRootMap = map; + MemoryContextSwitchTo(oldcxt); + } + newslot = resultRelInfo->ri_inhNewSlot; + map = resultRelInfo->ri_inhRootMap; + + wrdatum = ExecGetJunkAttribute(planSlot, resultRelInfo->ri_wholerow_attno, + &isNull); + if (isNull) + elog(ERROR, "wholerow is NULL"); + + wrheader = DatumGetHeapTupleHeader(wrdatum); + wrtuple.t_len = HeapTupleHeaderGetDatumLength(wrheader); + ItemPointerSetInvalid(&wrtuple.t_self); + wrtuple.t_tableOid = InvalidOid; + wrtuple.t_data = wrheader; + + ExecClearTuple(newslot); + heap_deform_tuple(&wrtuple, cdesc, newslot->tts_values, newslot->tts_isnull); + + /* overlay the new values that exist in the root layout */ + slot_getallattrs(planSlot); + for (int i = 0; i < cdesc->natts; i++) + { + if (map[i] > 0) + { + newslot->tts_values[i] = planSlot->tts_values[map[i] - 1]; + newslot->tts_isnull[i] = planSlot->tts_isnull[map[i] - 1]; + } + } + + return ExecStoreVirtualTuple(newslot); +} + /* * Insert the new tuple version of a Split Update * @@ -1653,10 +2244,6 @@ ExecSplitUpdate_Insert(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo; Relation resultRelationDesc; bool partition_constraint_failed; - TupleConversionMap *saved_tcs_map = NULL; - PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; - int map_index; - TupleConversionMap *tupconv_map; /* * get information on the (current) result relation @@ -1675,7 +2262,7 @@ ExecSplitUpdate_Insert(ModifyTableState *mtstate, * row. So skip the WCO checks if the partition constraint fails. */ partition_constraint_failed = - resultRelInfo->ri_PartitionCheck && + resultRelationDesc->rd_rel->relispartition && !ExecPartitionCheck(resultRelInfo, slot, estate, false); if (!partition_constraint_failed && @@ -1689,69 +2276,18 @@ ExecSplitUpdate_Insert(ModifyTableState *mtstate, resultRelInfo, slot, estate); } - /* - * Updates set the transition capture map only when a new subplan - * is chosen. But for inserts, it is set for each row. So after - * INSERT, we need to revert back to the map created for UPDATE; - * otherwise the next UPDATE will incorrectly use the one created - * for INSERT. So first save the one created for UPDATE. - */ - if (mtstate->mt_transition_capture) - saved_tcs_map = mtstate->mt_transition_capture->tcs_map; - if (partition_constraint_failed) { - /* - * When an UPDATE is run on a leaf partition, we will not have - * partition tuple routing set up. In that case, fail with - * partition constraint violation error. - */ + PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; + if (proute == NULL) ExecPartitionCheckEmitError(resultRelInfo, slot, estate); - - /* - * resultRelInfo is one of the per-subplan resultRelInfos. So we - * should convert the tuple into root's tuple descriptor, since - * ExecInsert() starts the search from root. The tuple conversion - * map list is in the order of mtstate->resultRelInfo[], so to - * retrieve the one for this resultRel, we need to know the - * position of the resultRel in mtstate->resultRelInfo[]. - */ - map_index = resultRelInfo - mtstate->resultRelInfo; - Assert(map_index >= 0 && map_index < mtstate->mt_nplans); - tupconv_map = tupconv_map_for_subplan(mtstate, map_index); - if (tupconv_map != NULL) - slot = execute_attr_map_slot(tupconv_map->attrMap, - slot, - mtstate->mt_root_tuple_slot); - - /* - * Prepare for tuple routing, making it look like we're inserting - * into the root. - */ - Assert(mtstate->rootResultRelInfo != NULL); - slot = ExecPrepareTupleRouting(mtstate, estate, proute, - mtstate->rootResultRelInfo, slot); - - slot = ExecInsert(mtstate, slot, planSlot, - estate, mtstate->canSetTag, - true /* splitUpdate */); - - /* Revert ExecPrepareTupleRouting's node change. */ - estate->es_result_relation_info = resultRelInfo; - if (mtstate->mt_transition_capture) - { - mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL; - mtstate->mt_transition_capture->tcs_map = saved_tcs_map; - } - } - else - { - slot = ExecInsert(mtstate, slot, planSlot, - estate, mtstate->canSetTag, - true /* splitUpdate */); } + slot = ExecInsert(mtstate, resultRelInfo, slot, planSlot, + estate, mtstate->canSetTag, + true /* splitUpdate */); + return slot; } @@ -1960,7 +2496,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, */ /* Execute UPDATE with projection */ - *returning = ExecUpdate(mtstate, conflictTid, NULL, + *returning = ExecUpdate(mtstate, resultRelInfo, conflictTid, NULL, resultRelInfo->ri_onConflict->oc_ProjSlot, planSlot, GpIdentity.segindex, @@ -1984,15 +2520,7 @@ static void fireBSTriggers(ModifyTableState *node) { ModifyTable *plan = (ModifyTable *) node->ps.plan; - ResultRelInfo *resultRelInfo = node->resultRelInfo; - - /* - * If the node modifies a partitioned table, we must fire its triggers. - * Note that in that case, node->resultRelInfo points to the first leaf - * partition, not the root table. - */ - if (node->rootResultRelInfo != NULL) - resultRelInfo = node->rootResultRelInfo; + ResultRelInfo *resultRelInfo = node->rootResultRelInfo; switch (node->operation) { @@ -2014,28 +2542,6 @@ fireBSTriggers(ModifyTableState *node) } } -/* - * Return the target rel ResultRelInfo. - * - * This relation is the same as : - * - the relation for which we will fire AFTER STATEMENT triggers. - * - the relation into whose tuple format all captured transition tuples must - * be converted. - * - the root partitioned table. - */ -static ResultRelInfo * -getTargetResultRelInfo(ModifyTableState *node) -{ - /* - * Note that if the node modifies a partitioned table, node->resultRelInfo - * points to the first leaf partition, not the root table. - */ - if (node->rootResultRelInfo != NULL) - return node->rootResultRelInfo; - else - return node->resultRelInfo; -} - /* * Process AFTER EACH STATEMENT triggers */ @@ -2043,7 +2549,7 @@ static void fireASTriggers(ModifyTableState *node) { ModifyTable *plan = (ModifyTable *) node->ps.plan; - ResultRelInfo *resultRelInfo = getTargetResultRelInfo(node); + ResultRelInfo *resultRelInfo = node->rootResultRelInfo; switch (node->operation) { @@ -2077,7 +2583,7 @@ static void ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) { ModifyTable *plan = (ModifyTable *) mtstate->ps.plan; - ResultRelInfo *targetRelInfo = getTargetResultRelInfo(mtstate); + ResultRelInfo *targetRelInfo = mtstate->rootResultRelInfo; /* Check for transition tables on the directly targeted relation. */ mtstate->mt_transition_capture = @@ -2090,50 +2596,27 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) MakeTransitionCaptureState(targetRelInfo->ri_TrigDesc, RelationGetRelid(targetRelInfo->ri_RelationDesc), CMD_UPDATE); - - /* - * If we found that we need to collect transition tuples then we may also - * need tuple conversion maps for any children that have TupleDescs that - * aren't compatible with the tuplestores. (We can share these maps - * between the regular and ON CONFLICT cases.) - */ - if (mtstate->mt_transition_capture != NULL || - mtstate->mt_oc_transition_capture != NULL) - { - ExecSetupChildParentMapForSubplan(mtstate); - - /* - * Install the conversion map for the first plan for UPDATE and DELETE - * operations. It will be advanced each time we switch to the next - * plan. (INSERT operations set it every time, so we need not update - * mtstate->mt_oc_transition_capture here.) - */ - if (mtstate->mt_transition_capture && mtstate->operation != CMD_INSERT) - mtstate->mt_transition_capture->tcs_map = - tupconv_map_for_subplan(mtstate, 0); - } } /* * ExecPrepareTupleRouting --- prepare for routing one tuple * * Determine the partition in which the tuple in slot is to be inserted, - * and modify mtstate and estate to prepare for it. + * and return its ResultRelInfo in *partRelInfo. The return value is + * a slot holding the tuple of the partition rowtype. * - * Caller must revert the estate changes after executing the insertion! - * In mtstate, transition capture changes may also need to be reverted. - * - * Returns a slot holding the tuple of the partition rowtype. + * This also sets the transition table information in mtstate based on the + * selected partition. */ static TupleTableSlot * ExecPrepareTupleRouting(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, ResultRelInfo *targetRelInfo, - TupleTableSlot *slot) + TupleTableSlot *slot, + ResultRelInfo **partRelInfo) { ResultRelInfo *partrel; - PartitionRoutingInfo *partrouteinfo; TupleConversionMap *map; /* @@ -2144,113 +2627,40 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate, * UPDATE to another partition becomes a DELETE+INSERT. */ partrel = ExecFindPartition(mtstate, targetRelInfo, proute, slot, estate); - partrouteinfo = partrel->ri_PartitionInfo; - Assert(partrouteinfo != NULL); - - /* - * Make it look like we are inserting into the partition. - */ - estate->es_result_relation_info = partrel; /* * If we're capturing transition tuples, we might need to convert from the - * partition rowtype to root partitioned table's rowtype. + * partition rowtype to root partitioned table's rowtype. But if there + * are no BEFORE triggers on the partition that could change the tuple, we + * can just remember the original unconverted tuple to avoid a needless + * round trip conversion. */ if (mtstate->mt_transition_capture != NULL) { - if (partrel->ri_TrigDesc && - partrel->ri_TrigDesc->trig_insert_before_row) - { - /* - * If there are any BEFORE triggers on the partition, we'll have - * to be ready to convert their result back to tuplestore format. - */ - mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL; - mtstate->mt_transition_capture->tcs_map = - partrouteinfo->pi_PartitionToRootMap; - } - else - { - /* - * Otherwise, just remember the original unconverted tuple, to - * avoid a needless round trip conversion. - */ - mtstate->mt_transition_capture->tcs_original_insert_tuple = slot; - mtstate->mt_transition_capture->tcs_map = NULL; - } - } - if (mtstate->mt_oc_transition_capture != NULL) - { - mtstate->mt_oc_transition_capture->tcs_map = - partrouteinfo->pi_PartitionToRootMap; + bool has_before_insert_row_trig; + + has_before_insert_row_trig = (partrel->ri_TrigDesc && + partrel->ri_TrigDesc->trig_insert_before_row); + + mtstate->mt_transition_capture->tcs_original_insert_tuple = + !has_before_insert_row_trig ? slot : NULL; } /* * Convert the tuple, if necessary. */ - map = partrouteinfo->pi_RootToPartitionMap; + map = partrel->ri_RootToPartitionMap; if (map != NULL) { - TupleTableSlot *new_slot = partrouteinfo->pi_PartitionTupleSlot; + TupleTableSlot *new_slot = partrel->ri_PartitionTupleSlot; slot = execute_attr_map_slot(map->attrMap, slot, new_slot); } + *partRelInfo = partrel; return slot; } -/* - * Initialize the child-to-root tuple conversion map array for UPDATE subplans. - * - * This map array is required to convert the tuple from the subplan result rel - * to the target table descriptor. This requirement arises for two independent - * scenarios: - * 1. For update-tuple-routing. - * 2. For capturing tuples in transition tables. - */ -static void -ExecSetupChildParentMapForSubplan(ModifyTableState *mtstate) -{ - ResultRelInfo *targetRelInfo = getTargetResultRelInfo(mtstate); - ResultRelInfo *resultRelInfos = mtstate->resultRelInfo; - TupleDesc outdesc; - int numResultRelInfos = mtstate->mt_nplans; - int i; - - /* - * Build array of conversion maps from each child's TupleDesc to the one - * used in the target relation. The map pointers may be NULL when no - * conversion is necessary, which is hopefully a common case. - */ - - /* Get tuple descriptor of the target rel. */ - outdesc = RelationGetDescr(targetRelInfo->ri_RelationDesc); - - mtstate->mt_per_subplan_tupconv_maps = (TupleConversionMap **) - palloc(sizeof(TupleConversionMap *) * numResultRelInfos); - - for (i = 0; i < numResultRelInfos; ++i) - { - mtstate->mt_per_subplan_tupconv_maps[i] = - convert_tuples_by_name(RelationGetDescr(resultRelInfos[i].ri_RelationDesc), - outdesc); - } -} - -/* - * For a given subplan index, get the tuple conversion map. - */ -static TupleConversionMap * -tupconv_map_for_subplan(ModifyTableState *mtstate, int whichplan) -{ - /* If nobody else set the per-subplan array of maps, do so ourselves. */ - if (mtstate->mt_per_subplan_tupconv_maps == NULL) - ExecSetupChildParentMapForSubplan(mtstate); - - Assert(whichplan >= 0 && whichplan < mtstate->mt_nplans); - return mtstate->mt_per_subplan_tupconv_maps[whichplan]; -} - /* ---------------------------------------------------------------- * ExecModifyTable * @@ -2262,21 +2672,23 @@ static TupleTableSlot * ExecModifyTable(PlanState *pstate) { ModifyTableState *node = castNode(ModifyTableState, pstate); - PartitionTupleRouting *proute = node->mt_partition_tuple_routing; EState *estate = node->ps.state; CmdType operation = node->operation; - ResultRelInfo *saved_resultRelInfo; ResultRelInfo *resultRelInfo; PlanState *subplanstate; JunkFilter *junkfilter; - AttrNumber action_attno; - AttrNumber segid_attno; + AttrNumber action_attno = InvalidAttrNumber; + AttrNumber segid_attno = InvalidAttrNumber; TupleTableSlot *slot; TupleTableSlot *planSlot; + TupleTableSlot *oldSlot; ItemPointer tupleid; ItemPointerData tuple_ctid; HeapTupleData oldtupdata; HeapTuple oldtuple; + PartitionTupleRouting *proute = node->mt_partition_tuple_routing; + List *relinfos = NIL; + ListCell *lc; CHECK_FOR_INTERRUPTS(); @@ -2328,25 +2740,14 @@ ExecModifyTable(PlanState *pstate) } /* Preload local variables */ - resultRelInfo = node->resultRelInfo + node->mt_whichplan; - subplanstate = node->mt_plans[node->mt_whichplan]; + resultRelInfo = node->resultRelInfo + node->mt_lastResultIndex; + subplanstate = outerPlanState(node); junkfilter = resultRelInfo->ri_junkFilter; action_attno = resultRelInfo->ri_action_attno; segid_attno = resultRelInfo->ri_segid_attno; /* - * es_result_relation_info must point to the currently active result - * relation while we are within this ModifyTable node. Even though - * ModifyTable nodes can't be nested statically, they can be nested - * dynamically (since our subplan could include a reference to a modifying - * CTE). So we have to save and restore the caller's value. - */ - saved_resultRelInfo = estate->es_result_relation_info; - - estate->es_result_relation_info = resultRelInfo; - - /* - * Fetch rows from subplan(s), and execute the required table modification + * Fetch rows from subplan, and execute the required table modification * for each row. */ for (;;) @@ -2369,44 +2770,31 @@ ExecModifyTable(PlanState *pstate) planSlot = ExecProcNode(subplanstate); + /* No more tuples to process? */ if (TupIsNull(planSlot)) - { - /* advance to next subplan if any */ - node->mt_whichplan++; - if (node->mt_whichplan < node->mt_nplans) - { - estate->es_result_relation_info = estate->es_result_relations + node->mt_whichplan; - resultRelInfo = estate->es_result_relation_info; - subplanstate = node->mt_plans[node->mt_whichplan]; - junkfilter = estate->es_result_relation_info->ri_junkFilter; - action_attno = estate->es_result_relation_info->ri_action_attno; - segid_attno = estate->es_result_relation_info->ri_segid_attno; - EvalPlanQualSetPlan(&node->mt_epqstate, subplanstate->plan, - node->mt_arowmarks[node->mt_whichplan]); - /* Prepare to convert transition tuples from this child. */ - if (node->mt_transition_capture != NULL) - { - node->mt_transition_capture->tcs_map = - tupconv_map_for_subplan(node, node->mt_whichplan); - } - if (node->mt_oc_transition_capture != NULL) - { - node->mt_oc_transition_capture->tcs_map = - tupconv_map_for_subplan(node, node->mt_whichplan); - } - continue; - } - else - break; - } + break; /* - * Ensure input tuple is the right format for the target relation. + * When there are multiple result relations, each tuple contains a + * junk column that gives the OID of the rel from which it came. + * Extract it and select the correct result relation. */ - if (node->mt_scans[node->mt_whichplan]->tts_ops != planSlot->tts_ops) + if (AttributeNumberIsValid(node->mt_resultOidAttno)) { - ExecCopySlot(node->mt_scans[node->mt_whichplan], planSlot); - planSlot = node->mt_scans[node->mt_whichplan]; + Datum datum; + bool isNull; + Oid resultoid; + + datum = ExecGetJunkAttribute(planSlot, node->mt_resultOidAttno, + &isNull); + if (isNull) + elog(ERROR, "tableoid is NULL"); + resultoid = DatumGetObjectId(datum); + + /* If it's not the same as last time, we need to locate the rel */ + if (resultoid != node->mt_lastResultOid) + resultRelInfo = ExecLookupResultRelByOid(node, resultoid, + false, true); } /* @@ -2425,7 +2813,6 @@ ExecModifyTable(PlanState *pstate) */ slot = ExecProcessReturning(resultRelInfo, NULL, planSlot); - estate->es_result_relation_info = saved_resultRelInfo; return slot; } @@ -2437,160 +2824,278 @@ ExecModifyTable(PlanState *pstate) tupleid = NULL; oldtuple = NULL; - if (junkfilter != NULL) + + /* + * For UPDATE/DELETE, fetch the row identity info for the tuple to be + * updated/deleted. For a heap relation, that's a TID; otherwise we + * may have a wholerow junk attr that carries the old tuple in toto. + * Keep this in step with the part of ExecInitModifyTable that sets up + * ri_RowIdAttNo. + */ + if (operation == CMD_UPDATE || operation == CMD_DELETE) { + char relkind; + Datum datum; + bool isNull; + + relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind; + if (relkind == RELKIND_RELATION || + relkind == RELKIND_MATVIEW || + relkind == RELKIND_PARTITIONED_TABLE || + IsAppendonlyMetadataRelkind(relkind)) + { + /* ri_RowIdAttNo refers to a ctid attribute */ + Assert(AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo)); + datum = ExecGetJunkAttribute(slot, + resultRelInfo->ri_RowIdAttNo, + &isNull); + /* shouldn't ever get a null result... */ + if (isNull) + elog(ERROR, "ctid is NULL"); + + tupleid = (ItemPointer) DatumGetPointer(datum); + tuple_ctid = *tupleid; /* be sure we don't free ctid!! */ + tupleid = &tuple_ctid; + } + /* - * extract the 'ctid' or 'wholerow' junk attribute. + * Use the wholerow attribute, when available, to reconstruct the + * old relation tuple. */ - if (operation == CMD_UPDATE || operation == CMD_DELETE) + else if (AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo)) { - char relkind; - Datum datum; - bool isNull; - - relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind; - if (relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW || - relkind == RELKIND_PARTITIONED_TABLE || - IsAppendonlyMetadataRelkind(relkind)) - { - datum = ExecGetJunkAttribute(slot, - junkfilter->jf_junkAttNo, - &isNull); - /* shouldn't ever get a null result... */ - if (isNull) - elog(ERROR, "ctid is NULL"); - - tupleid = (ItemPointer) DatumGetPointer(datum); - tuple_ctid = *tupleid; /* be sure we don't free ctid!! */ - tupleid = &tuple_ctid; - } - - /* - * Use the wholerow attribute, when available, to reconstruct - * the old relation tuple. - * - * Foreign table updates have a wholerow attribute when the - * relation has a row-level trigger. Note that the wholerow - * attribute does not carry system columns. Foreign table - * triggers miss seeing those, except that we know enough here - * to set t_tableOid. Quite separately from this, the FDW may - * fetch its own junk attrs to identify the row. - * - * Other relevant relkinds, currently limited to views, always - * have a wholerow attribute. - */ - else if (AttributeNumberIsValid(junkfilter->jf_junkAttNo)) - { - datum = ExecGetJunkAttribute(slot, - junkfilter->jf_junkAttNo, - &isNull); - /* shouldn't ever get a null result... */ - if (isNull) - elog(ERROR, "wholerow is NULL"); - - oldtupdata.t_data = DatumGetHeapTupleHeader(datum); - oldtupdata.t_len = - HeapTupleHeaderGetDatumLength(oldtupdata.t_data); - ItemPointerSetInvalid(&(oldtupdata.t_self)); - /* Historically, view triggers see invalid t_tableOid. */ - oldtupdata.t_tableOid = - (relkind == RELKIND_VIEW) ? InvalidOid : - RelationGetRelid(resultRelInfo->ri_RelationDesc); - oldtuple = &oldtupdata; - } - else - Assert(relkind == RELKIND_FOREIGN_TABLE); - - /* - * Extract GPDB-specific junk attributes. - */ - if (AttributeNumberIsValid(segid_attno)) - { - datum = ExecGetJunkAttribute(slot, - segid_attno, - &isNull); - /* shouldn't ever get a null result... */ - if (isNull) - elog(ERROR, "gp_segment_id is NULL"); - - segid = DatumGetInt32(datum); - } - if (AttributeNumberIsValid(action_attno)) - { - datum = ExecGetJunkAttribute(slot, - action_attno, - &isNull); - /* shouldn't ever get a null result... */ - if (isNull) - elog(ERROR, "action is NULL"); - - action = DatumGetInt32(datum); - } + datum = ExecGetJunkAttribute(slot, + resultRelInfo->ri_RowIdAttNo, + &isNull); + /* shouldn't ever get a null result... */ + if (isNull) + elog(ERROR, "wholerow is NULL"); + + oldtupdata.t_data = DatumGetHeapTupleHeader(datum); + oldtupdata.t_len = + HeapTupleHeaderGetDatumLength(oldtupdata.t_data); + ItemPointerSetInvalid(&(oldtupdata.t_self)); + /* Historically, view triggers see invalid t_tableOid. */ + oldtupdata.t_tableOid = + (relkind == RELKIND_VIEW) ? InvalidOid : + RelationGetRelid(resultRelInfo->ri_RelationDesc); + oldtuple = &oldtupdata; + } + else + { + /* Only foreign tables are allowed to omit a row-ID attr */ + Assert(relkind == RELKIND_FOREIGN_TABLE); } /* - * apply the junkfilter if needed. + * Extract GPDB-specific junk attributes. */ - if (operation != CMD_DELETE) - slot = ExecFilterJunk(junkfilter, slot); + if (AttributeNumberIsValid(segid_attno)) + { + datum = ExecGetJunkAttribute(slot, + segid_attno, + &isNull); + /* shouldn't ever get a null result... */ + if (isNull) + elog(ERROR, "gp_segment_id is NULL"); + + segid = DatumGetInt32(datum); + } + if (AttributeNumberIsValid(action_attno)) + { + datum = ExecGetJunkAttribute(slot, + action_attno, + &isNull); + /* shouldn't ever get a null result... */ + if (isNull) + elog(ERROR, "action is NULL"); + + action = DatumGetInt32(datum); + } } switch (operation) { case CMD_INSERT: - /* Prepare for tuple routing if needed. */ - if (proute) - slot = ExecPrepareTupleRouting(node, estate, proute, - resultRelInfo, slot); - slot = ExecInsert(node, slot, planSlot, - estate, node->canSetTag, false /* splitUpdate */); - /* Revert ExecPrepareTupleRouting's state change. */ - if (proute) - estate->es_result_relation_info = resultRelInfo; + /* Initialize projection info if first time for this table */ + if (unlikely(!resultRelInfo->ri_projectNewInfoValid)) + ExecInitInsertProjection(node, resultRelInfo); + slot = ExecGetInsertNewTuple(resultRelInfo, planSlot); + slot = ExecInsert(node, resultRelInfo, slot, planSlot, + estate, node->canSetTag, + false /* splitUpdate */); break; case CMD_UPDATE: - /* Prepare for tuple routing if needed. */ - if (castNode(ModifyTable, node->ps.plan)->forceTupleRouting) - slot = ExecPrepareTupleRouting(node, estate, proute, - resultRelInfo, slot); - if (!AttributeNumberIsValid(action_attno)) + /* + * GPDB: A Split Update is delivered as a stream of separate + * DELETE and INSERT action rows, tagged by the DMLActionExpr + * junk column (action_attno). It is used when an UPDATE may + * change a distribution key column, so the modified tuple can + * belong on a different segment: an Explicit Motion re-routes + * each row, and here we replay it as a delete of the old tuple + * plus an insert of the new one rather than an in-place update. + */ + if (AttributeNumberIsValid(action_attno)) { - /* normal non-split UPDATE */ - slot = ExecUpdate(node, tupleid, oldtuple, slot, planSlot, - segid, - &node->mt_epqstate, estate, node->canSetTag); + if (action == DML_INSERT) + { + /* + * Insert the new tuple version. + * + * GPDB: the SplitUpdate produces the new tuple in the + * root (nominal) target relation's column layout, which + * can differ from the source leaf partition's physical + * column order. For a partitioned target, project and + * insert via the root result relation so the projection + * matches the subplan output; ExecInsert() then routes + * the row to the correct leaf (converting the layout as + * needed) and enforces the partition constraint. + * + * For old-style inheritance there is no tuple routing: + * the new tuple version must go back into the relation + * the row came from -- the per-row result relation + * selected by the tableoid junk column. That only + * works when the child's column layout matches the + * root's; child columns that don't exist in the root + * are not carried in the Motion stream at all, so we + * must error out rather than insert a mangled row. + * For a plain (non-inherited) target rootResultRelInfo + * is the result relation itself. + */ + ResultRelInfo *insertRelInfo; + bool rebuildFromOld = false; + + if (node->rootResultRelInfo->ri_RelationDesc->rd_rel->relkind == + RELKIND_PARTITIONED_TABLE) + insertRelInfo = node->rootResultRelInfo; + else + { + insertRelInfo = resultRelInfo; + rebuildFromOld = + (insertRelInfo != node->rootResultRelInfo && + !inh_child_layout_matches_root(insertRelInfo, + node->rootResultRelInfo)); + } + + if (rebuildFromOld) + slot = ExecInhRebuildNewTuple(node, insertRelInfo, + planSlot); + else + { + if (unlikely(!insertRelInfo->ri_projectNewInfoValid)) + ExecInitInsertProjection(node, insertRelInfo); + slot = ExecGetInsertNewTuple(insertRelInfo, planSlot); + } + estate->es_result_relation_info = insertRelInfo; + slot = ExecSplitUpdate_Insert(node, slot, planSlot, + estate, node->canSetTag); + } + else + { + /* + * Delete the old tuple version. Don't count it in the + * command tag: the matching INSERT action row is what + * represents this logical UPDATE, so only that side sets + * the tag (otherwise each updated row is counted twice). + */ + Assert(action == DML_DELETE); + slot = ExecDelete(node, resultRelInfo, tupleid, segid, + oldtuple, planSlot, &node->mt_epqstate, + estate, + false, /* processReturning */ + false, /* canSetTag */ + false, /* changingPart */ + true, /* splitUpdate */ + NULL, NULL); + } + break; } - else if (DML_INSERT == action) + + /* Initialize projection info if first time for this table */ + if (unlikely(!resultRelInfo->ri_projectNewInfoValid)) + ExecInitUpdateProjection(node, resultRelInfo); + + /* + * Make the new tuple by combining plan's output tuple with + * the old tuple being updated. + */ + oldSlot = resultRelInfo->ri_oldTupleSlot; + if (oldtuple != NULL) { - slot = ExecSplitUpdate_Insert(node, slot, planSlot, - estate, node->canSetTag); + /* Use the wholerow junk attr as the old tuple. */ + ExecForceStoreHeapTuple(oldtuple, oldSlot, false); } - else /* DML_DELETE */ + else if (RelationIsAppendOptimized(resultRelInfo->ri_RelationDesc)) { - slot = ExecDelete(node, tupleid, segid, oldtuple, planSlot, - &node->mt_epqstate, estate, - false, - false /* canSetTag */, - true /* changingPart */ , - true /* splitUpdate */ , - NULL, NULL); + /* + * GPDB: append-optimized tables cannot fetch the old tuple + * by TID (appendonly_fetch_row_version is unsupported). + * Their UPDATE plan supplies the full new tuple -- + * preprocess_targetlist() expanded the targetlist to every + * column -- so usually no old-tuple merge is required. + * + * The exception is an old-style inheritance child with + * columns the (nominal) root doesn't have: those are not + * in the expanded targetlist, so the update projection + * reads them from the old tuple. The planner ships the + * old tuple in the "wholerow" junk column for AO + * inheritance updates; restore it into the old slot. + */ + if (AttributeNumberIsValid(resultRelInfo->ri_wholerow_attno)) + { + Datum wrdatum; + bool wrisnull; + HeapTupleHeader wrheader; + HeapTupleData wrtuple; + + wrdatum = ExecGetJunkAttribute(planSlot, + resultRelInfo->ri_wholerow_attno, + &wrisnull); + if (wrisnull) + elog(ERROR, "wholerow is NULL"); + wrheader = DatumGetHeapTupleHeader(wrdatum); + wrtuple.t_len = HeapTupleHeaderGetDatumLength(wrheader); + ItemPointerSetInvalid(&wrtuple.t_self); + wrtuple.t_tableOid = InvalidOid; + wrtuple.t_data = wrheader; + + ExecClearTuple(oldSlot); + heap_deform_tuple(&wrtuple, + RelationGetDescr(resultRelInfo->ri_RelationDesc), + oldSlot->tts_values, + oldSlot->tts_isnull); + ExecStoreVirtualTuple(oldSlot); + } + else + ExecClearTuple(oldSlot); + } + else + { + /* Fetch the most recent version of old tuple. */ + Relation relation = resultRelInfo->ri_RelationDesc; + + Assert(tupleid != NULL); + if (!table_tuple_fetch_row_version(relation, tupleid, + SnapshotAny, + oldSlot)) + elog(ERROR, "failed to fetch tuple being updated"); } - /* Revert ExecPrepareTupleRouting's state change. */ - if (castNode(ModifyTable, node->ps.plan)->forceTupleRouting) - estate->es_result_relation_info = resultRelInfo; + slot = ExecGetUpdateNewTuple(resultRelInfo, planSlot, + oldSlot); + + /* Now apply the update. */ + slot = ExecUpdate(node, resultRelInfo, tupleid, oldtuple, slot, + planSlot, segid, &node->mt_epqstate, estate, + node->canSetTag); break; case CMD_DELETE: - if (castNode(ModifyTable, node->ps.plan)->forceTupleRouting) - planSlot = ExecPrepareTupleRouting(node, estate, proute, - resultRelInfo, slot); - slot = ExecDelete(node, tupleid, segid, oldtuple, planSlot, - &node->mt_epqstate, estate, - true, node->canSetTag, - false /* changingPart */ , - false /* splitUpdate */ , + slot = ExecDelete(node, resultRelInfo, tupleid, segid, oldtuple, + planSlot, &node->mt_epqstate, estate, + true, /* processReturning */ + node->canSetTag, + false, /* changingPart */ + false, /* splitUpdate */ NULL, NULL); - if (castNode(ModifyTable, node->ps.plan)->forceTupleRouting) - estate->es_result_relation_info = resultRelInfo; break; default: elog(ERROR, "unknown operation"); @@ -2611,14 +3116,27 @@ ExecModifyTable(PlanState *pstate) * the work on next call. */ if (slot) - { - estate->es_result_relation_info = saved_resultRelInfo; return slot; - } } - /* Restore es_result_relation_info before exiting */ - estate->es_result_relation_info = saved_resultRelInfo; + /* + * Insert remaining tuples for batch insert. + */ + if (proute) + relinfos = estate->es_tuple_routing_result_relations; + else + relinfos = estate->es_opened_result_relations; + + foreach(lc, relinfos) + { + resultRelInfo = lfirst(lc); + if (resultRelInfo->ri_NumSlots > 0) + ExecBatchInsert(node, resultRelInfo, + resultRelInfo->ri_Slots, + resultRelInfo->ri_PlanSlots, + resultRelInfo->ri_NumSlots, + estate, node->canSetTag); + } /* * We're done, but fire AFTER STATEMENT triggers before exiting. @@ -2632,6 +3150,61 @@ ExecModifyTable(PlanState *pstate) return NULL; } +/* + * ExecLookupResultRelByOid + * If the table with given OID is among the result relations to be + * updated by the given ModifyTable node, return its ResultRelInfo. + * + * If not found, return NULL if missing_ok, else raise error. + * + * If update_cache is true, then upon successful lookup, update the node's + * one-element cache. ONLY ExecModifyTable may pass true for this. + */ +ResultRelInfo * +ExecLookupResultRelByOid(ModifyTableState *node, Oid resultoid, + bool missing_ok, bool update_cache) +{ + if (node->mt_resultOidHash) + { + /* Use the pre-built hash table to locate the rel */ + MTTargetRelLookup *mtlookup; + + mtlookup = (MTTargetRelLookup *) + hash_search(node->mt_resultOidHash, &resultoid, HASH_FIND, NULL); + if (mtlookup) + { + if (update_cache) + { + node->mt_lastResultOid = resultoid; + node->mt_lastResultIndex = mtlookup->relationIndex; + } + return node->resultRelInfo + mtlookup->relationIndex; + } + } + else + { + /* With few target rels, just search the ResultRelInfo array */ + for (int ndx = 0; ndx < node->mt_nrels; ndx++) + { + ResultRelInfo *rInfo = node->resultRelInfo + ndx; + + if (RelationGetRelid(rInfo->ri_RelationDesc) == resultoid) + { + if (update_cache) + { + node->mt_lastResultOid = resultoid; + node->mt_lastResultIndex = ndx; + } + return rInfo; + } + } + } + + if (!missing_ok) + elog(ERROR, "incorrect result relation OID %u", resultoid); + return NULL; +} + /* ---------------------------------------------------------------- * ExecInitModifyTable * ---------------------------------------------------------------- @@ -2640,15 +3213,14 @@ ModifyTableState * ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) { ModifyTableState *mtstate; + Plan *subplan = outerPlan(node); CmdType operation = node->operation; - int nplans = list_length(node->plans); - ResultRelInfo *saved_resultRelInfo; + int nrels = list_length(node->resultRelations); ResultRelInfo *resultRelInfo; - Plan *subplan; + List *arowmarks; ListCell *l; int i; Relation rel; - bool update_tuple_routing_needed = node->partColsUpdated; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -2665,27 +3237,46 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate->canSetTag = node->canSetTag; mtstate->mt_done = false; - mtstate->mt_plans = (PlanState **) palloc0(sizeof(PlanState *) * nplans); - mtstate->resultRelInfo = estate->es_result_relations + node->resultRelIndex; - mtstate->mt_scans = (TupleTableSlot **) palloc0(sizeof(TupleTableSlot *) * nplans); + mtstate->mt_nrels = nrels; + mtstate->resultRelInfo = (ResultRelInfo *) + palloc(nrels * sizeof(ResultRelInfo)); - /* If modifying a partitioned table, initialize the root table info */ - if (node->rootResultRelIndex >= 0) - mtstate->rootResultRelInfo = estate->es_root_result_relations + - node->rootResultRelIndex; - - mtstate->mt_arowmarks = (List **) palloc0(sizeof(List *) * nplans); - mtstate->mt_nplans = nplans; + /*---------- + * Resolve the target relation. This is the same as: + * + * - the relation for which we will fire FOR STATEMENT triggers, + * - the relation into whose tuple format all captured transition tuples + * must be converted, and + * - the root partitioned table used for tuple routing. + * + * If it's a partitioned table, the root partition doesn't appear + * elsewhere in the plan and its RT index is given explicitly in + * node->rootRelation. Otherwise (i.e. table inheritance) the target + * relation is the first relation in the node->resultRelations list. + *---------- + */ + if (node->rootRelation > 0) + { + mtstate->rootResultRelInfo = makeNode(ResultRelInfo); + ExecInitResultRelation(estate, mtstate->rootResultRelInfo, + node->rootRelation); + } + else + { + mtstate->rootResultRelInfo = mtstate->resultRelInfo; + ExecInitResultRelation(estate, mtstate->resultRelInfo, + linitial_int(node->resultRelations)); + } /* set up epqstate with dummy subplan data for the moment */ EvalPlanQualInit(&mtstate->mt_epqstate, estate, NULL, NIL, node->epqParam); if (CMD_UPDATE == operation) { - mtstate->mt_isSplitUpdates = (bool *) palloc0(nplans * sizeof(bool)); + mtstate->mt_isSplitUpdates = (bool *) palloc0(nrels * sizeof(bool)); if (node->isSplitUpdates) { - if (list_length(node->isSplitUpdates) != nplans) + if (list_length(node->isSplitUpdates) != nrels) elog(ERROR, "ModifyTable node is missing is-split-update information"); i = 0; @@ -2699,22 +3290,36 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate->fireBSTriggers = true; /* - * call ExecInitNode on each of the plans to be executed and save the - * results into the array "mt_plans". This is also a convenient place to - * verify that the proposed target relations are valid and open their - * indexes for insertion of new index entries. Note we *must* set - * estate->es_result_relation_info correctly while we initialize each - * sub-plan; external modules such as FDWs may depend on that (see - * contrib/postgres_fdw/postgres_fdw.c: postgresBeginDirectModify() as one - * example). + * Build state for collecting transition tuples. This requires having a + * valid trigger query context, so skip it in explain-only mode. */ - saved_resultRelInfo = estate->es_result_relation_info; + if (!(eflags & EXEC_FLAG_EXPLAIN_ONLY)) + ExecSetupTransitionCaptureState(mtstate, estate); + /* + * Open all the result relations and initialize the ResultRelInfo structs. + * (But root relation was initialized above, if it's part of the array.) + * We must do this before initializing the subplan, because direct-modify + * FDWs expect their ResultRelInfos to be available. + */ resultRelInfo = mtstate->resultRelInfo; i = 0; - foreach(l, node->plans) + foreach(l, node->resultRelations) { - subplan = (Plan *) lfirst(l); + Index resultRelation = lfirst_int(l); + + if (resultRelInfo != mtstate->rootResultRelInfo) + { + ExecInitResultRelation(estate, resultRelInfo, resultRelation); + + /* + * For child result relations, store the root result relation + * pointer. We do so for the convenience of places that want to + * look at the query's original target relation but don't have the + * mtstate handy. + */ + resultRelInfo->ri_RootResultRelInfo = mtstate->rootResultRelInfo; + } /* Initialize the usesFdwDirectModify flag */ resultRelInfo->ri_usesFdwDirectModify = bms_is_member(i, @@ -2726,8 +3331,11 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) CheckValidResultRel(resultRelInfo, operation); /* - * GPDB: We don't support SERIALIZABLE transaction isolation for - * UPDATES/DELETES on AO/CO tables. + * GPDB: We don't support SERIALIZABLE/REPEATABLE READ transaction + * isolation for UPDATE/DELETE on AO/CO tables: the visibility map + * machinery cannot honor a fixed transaction snapshot. This check + * was lost in the PG14 nodeModifyTable rework (it replaced the + * deep checks removed in 13c98bed10c). */ if (IsolationUsesXactSnapshot() && RelationIsAppendOptimized(resultRelInfo->ri_RelationDesc)) @@ -2735,51 +3343,36 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) if (operation == CMD_UPDATE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("updates on append-only tables are not " - "supported in serializable transactions"))); + errmsg("updates on append-only tables are not " + "supported in serializable transactions"))); else if (operation == CMD_DELETE) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("deletes on append-only tables are not " - "supported in serializable transactions"))); + errmsg("deletes on append-only tables are not " + "supported in serializable transactions"))); } - /* - * If there are indices on the result relation, open them and save - * descriptors in the result relation info, so that we can add new - * index entries for the tuples we add/update. We need not do this - * for a DELETE, however, since deletion doesn't affect indexes. Also, - * inside an EvalPlanQual operation, the indexes might be open - * already, since we share the resultrel state with the original - * query. - */ - if (resultRelInfo->ri_RelationDesc->rd_rel->relhasindex && - operation != CMD_DELETE && - resultRelInfo->ri_IndexRelationDescs == NULL) - ExecOpenIndices(resultRelInfo, - node->onConflictAction != ONCONFLICT_NONE); + resultRelInfo++; + i++; + } - /* - * If this is an UPDATE and a BEFORE UPDATE trigger is present, the - * trigger itself might modify the partition-key values. So arrange - * for tuple routing. - */ - if (resultRelInfo->ri_TrigDesc && - resultRelInfo->ri_TrigDesc->trig_update_before_row && - operation == CMD_UPDATE) - update_tuple_routing_needed = true; + /* + * Now we may initialize the subplan. + */ + outerPlanState(mtstate) = ExecInitNode(subplan, estate, eflags); - /* Now init the plan for this result rel */ - estate->es_result_relation_info = resultRelInfo; - mtstate->mt_plans[i] = ExecInitNode(subplan, estate, eflags); - mtstate->mt_scans[i] = - ExecInitExtraTupleSlot(mtstate->ps.state, ExecGetResultType(mtstate->mt_plans[i]), - table_slot_callbacks(resultRelInfo->ri_RelationDesc)); + /* + * Do additional per-result-relation initialization. + */ + for (i = 0; i < nrels; i++) + { + resultRelInfo = &mtstate->resultRelInfo[i]; if (resultRelInfo->ri_RelationDesc->rd_tableam) table_dml_init(resultRelInfo->ri_RelationDesc); /* Also let FDWs init themselves for foreign-table result rels */ + /* Let FDWs init themselves for foreign-table result rels */ if (!resultRelInfo->ri_usesFdwDirectModify && resultRelInfo->ri_FdwRoutine != NULL && resultRelInfo->ri_FdwRoutine->BeginForeignModify != NULL) @@ -2793,14 +3386,77 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) eflags); } - resultRelInfo++; - i++; - } + /* + * For UPDATE/DELETE, find the appropriate junk attr now, either a + * 'ctid' or 'wholerow' attribute depending on relkind. For foreign + * tables, the FDW might have created additional junk attr(s), but + * those are no concern of ours. + */ + if (operation == CMD_UPDATE || operation == CMD_DELETE) + { + char relkind; + + relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind; + if (relkind == RELKIND_RELATION || + relkind == RELKIND_MATVIEW || + relkind == RELKIND_PARTITIONED_TABLE || + IsAppendonlyMetadataRelkind(relkind)) + { + resultRelInfo->ri_RowIdAttNo = + ExecFindJunkAttributeInTlist(subplan->targetlist, "ctid"); + if (!AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo)) + elog(ERROR, "could not find junk ctid column"); + } + else if (relkind == RELKIND_FOREIGN_TABLE) + { + /* + * When there is a row-level trigger, there should be a + * wholerow attribute. We also require it to be present in + * UPDATE, so we can get the values of unchanged columns. + */ + resultRelInfo->ri_RowIdAttNo = + ExecFindJunkAttributeInTlist(subplan->targetlist, + "wholerow"); + if (mtstate->operation == CMD_UPDATE && + !AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo)) + elog(ERROR, "could not find junk wholerow column"); + } + else + { + /* Other valid target relkinds must provide wholerow */ + resultRelInfo->ri_RowIdAttNo = + ExecFindJunkAttributeInTlist(subplan->targetlist, + "wholerow"); + if (!AttributeNumberIsValid(resultRelInfo->ri_RowIdAttNo)) + elog(ERROR, "could not find junk wholerow column"); + } - estate->es_result_relation_info = saved_resultRelInfo; + /* + * GPDB: locate the junk columns added for MPP UPDATE/DELETE. + * "gp_segment_id" identifies the segment a row lives on (added by + * the row-identity machinery and routed by the Explicit Motion); + * "DMLAction" is present only when the plan contains a SplitUpdate + * and tags each row as a DELETE or INSERT action. When + * ri_action_attno is valid, ExecModifyTable replays the UPDATE as + * delete+insert instead of an in-place update. + */ + resultRelInfo->ri_segid_attno = + ExecFindJunkAttributeInTlist(subplan->targetlist, + "gp_segment_id"); + resultRelInfo->ri_action_attno = + ExecFindJunkAttributeInTlist(subplan->targetlist, + "DMLAction"); - /* Get the target relation */ - rel = (getTargetResultRelInfo(mtstate))->ri_RelationDesc; + /* + * "wholerow" carries the old child tuple for split updates on + * old-style inheritance; see ExecInhRebuildNewTuple(). (For + * foreign tables ri_RowIdAttNo found it above already.) + */ + resultRelInfo->ri_wholerow_attno = + ExecFindJunkAttributeInTlist(subplan->targetlist, + "wholerow"); + } + } /* * GPDB dynamic scan nodes optimize memory usage by avoiding the need to @@ -2818,52 +3474,47 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * causes the tuple to be routed, then we must perform tuple routing a * second time. */ - if (node->forceTupleRouting) - update_tuple_routing_needed = true; - /* * If it's not a partitioned table after all, UPDATE tuple routing should * not be attempted. + * If this is an inherited update/delete, there will be a junk attribute + * named "tableoid" present in the subplan's targetlist. It will be used + * to identify the result relation for a given tuple to be + * updated/deleted. */ - if (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) - update_tuple_routing_needed = false; + mtstate->mt_resultOidAttno = + ExecFindJunkAttributeInTlist(subplan->targetlist, "tableoid"); + Assert(AttributeNumberIsValid(mtstate->mt_resultOidAttno) || nrels == 1); + mtstate->mt_lastResultOid = InvalidOid; /* force lookup at first tuple */ + mtstate->mt_lastResultIndex = 0; /* must be zero if no such attr */ + + /* Get the root target relation */ + rel = mtstate->rootResultRelInfo->ri_RelationDesc; /* - * Build state for tuple routing if it's an INSERT or if it's an UPDATE of - * partition key. + * Build state for tuple routing if it's a partitioned INSERT. An UPDATE + * might need this too, but only if it actually moves tuples between + * partitions; in that case setup is normally done by + * ExecCrossPartitionUpdate. + * + * GPDB: a SplitUpdate replays the UPDATE as a DELETE of the old tuple plus + * an INSERT of the new one (used when an UPDATE may change a distribution + * key). The new tuple is produced in the root/nominal layout, so it must + * be routed to -- and converted for -- the correct leaf partition just like + * a partitioned INSERT. Set up routing up front when any target is a split + * update. */ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE && - (operation == CMD_INSERT || update_tuple_routing_needed)) + (operation == CMD_INSERT || + (operation == CMD_UPDATE && + list_member_int(node->isSplitUpdates, true)))) mtstate->mt_partition_tuple_routing = - ExecSetupPartitionTupleRouting(estate, mtstate, rel); - - /* - * Build state for collecting transition tuples. This requires having a - * valid trigger query context, so skip it in explain-only mode. - */ - if (!(eflags & EXEC_FLAG_EXPLAIN_ONLY)) - ExecSetupTransitionCaptureState(mtstate, estate); - - /* - * Construct mapping from each of the per-subplan partition attnos to the - * root attno. This is required when during update row movement the tuple - * descriptor of a source partition does not match the root partitioned - * table descriptor. In such a case we need to convert tuples to the root - * tuple descriptor, because the search for destination partition starts - * from the root. We'll also need a slot to store these converted tuples. - * We can skip this setup if it's not a partition key update. - */ - if (update_tuple_routing_needed) - { - ExecSetupChildParentMapForSubplan(mtstate); - mtstate->mt_root_tuple_slot = table_slot_create(rel, NULL); - } + ExecSetupPartitionTupleRouting(estate, rel); /* * Initialize any WITH CHECK OPTION constraints if needed. */ resultRelInfo = mtstate->resultRelInfo; - i = 0; foreach(l, node->withCheckOptionLists) { List *wcoList = (List *) lfirst(l); @@ -2882,7 +3533,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) resultRelInfo->ri_WithCheckOptions = wcoList; resultRelInfo->ri_WithCheckOptionExprs = wcoExprs; resultRelInfo++; - i++; } /* @@ -2938,7 +3588,11 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) /* Set the list of arbiter indexes if needed for ON CONFLICT */ resultRelInfo = mtstate->resultRelInfo; if (node->onConflictAction != ONCONFLICT_NONE) + { + /* insert may only have one relation, inheritance is not expanded */ + Assert(nrels == 1); resultRelInfo->ri_onConflictArbiterIndexes = node->arbiterIndexes; + } /* * If needed, Initialize target list, projection and qual for ON CONFLICT @@ -2946,12 +3600,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) */ if (node->onConflictAction == ONCONFLICT_UPDATE) { + OnConflictSetState *onconfl = makeNode(OnConflictSetState); ExprContext *econtext; TupleDesc relationDesc; - TupleDesc tupDesc; - - /* insert may only have one plan, inheritance is not expanded */ - Assert(nplans == 1); /* already exists if created by RETURNING processing above */ if (mtstate->ps.ps_ExprContext == NULL) @@ -2961,10 +3612,10 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) relationDesc = resultRelInfo->ri_RelationDesc->rd_att; /* create state for DO UPDATE SET operation */ - resultRelInfo->ri_onConflict = makeNode(OnConflictSetState); + resultRelInfo->ri_onConflict = onconfl; /* initialize slot for the existing tuple */ - resultRelInfo->ri_onConflict->oc_Existing = + onconfl->oc_Existing = table_slot_create(resultRelInfo->ri_RelationDesc, &mtstate->ps.state->es_tupleTable); @@ -2974,17 +3625,19 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * into the table, and for RETURNING processing - which may access * system attributes. */ - tupDesc = ExecTypeFromTL((List *) node->onConflictSet); - resultRelInfo->ri_onConflict->oc_ProjSlot = - ExecInitExtraTupleSlot(mtstate->ps.state, tupDesc, - table_slot_callbacks(resultRelInfo->ri_RelationDesc)); + onconfl->oc_ProjSlot = + table_slot_create(resultRelInfo->ri_RelationDesc, + &mtstate->ps.state->es_tupleTable); /* build UPDATE SET projection state */ - resultRelInfo->ri_onConflict->oc_ProjInfo = - ExecBuildProjectionInfo(node->onConflictSet, econtext, - resultRelInfo->ri_onConflict->oc_ProjSlot, - &mtstate->ps, - relationDesc); + onconfl->oc_ProjInfo = + ExecBuildUpdateProjection(node->onConflictSet, + true, + node->onConflictCols, + relationDesc, + econtext, + onconfl->oc_ProjSlot, + &mtstate->ps); /* initialize state to evaluate the WHERE clause, if any */ if (node->onConflictWhere) @@ -2993,7 +3646,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) qualexpr = ExecInitQual((List *) node->onConflictWhere, &mtstate->ps); - resultRelInfo->ri_onConflict->oc_WhereClause = qualexpr; + onconfl->oc_WhereClause = qualexpr; } } @@ -3003,10 +3656,12 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * EvalPlanQual mechanism needs to be told about them. Locate the * relevant ExecRowMarks. */ + arowmarks = NIL; foreach(l, node->rowMarks) { PlanRowMark *rc = lfirst_node(PlanRowMark, l); ExecRowMark *erm; + ExecAuxRowMark *aerm; /* ignore "parent" rowmarks; they are irrelevant at runtime */ if (rc->isParent) @@ -3036,139 +3691,80 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) } /* find ExecRowMark (same for all subplans) */ + /* Find ExecRowMark and build ExecAuxRowMark */ erm = ExecFindRowMark(estate, rc->rti, false); - - /* build ExecAuxRowMark for each subplan */ - for (i = 0; i < nplans; i++) - { - ExecAuxRowMark *aerm; - - subplan = mtstate->mt_plans[i]->plan; - aerm = ExecBuildAuxRowMark(erm, subplan->targetlist); - mtstate->mt_arowmarks[i] = lappend(mtstate->mt_arowmarks[i], aerm); - } + aerm = ExecBuildAuxRowMark(erm, subplan->targetlist); + arowmarks = lappend(arowmarks, aerm); } - /* select first subplan */ - mtstate->mt_whichplan = 0; - subplan = (Plan *) linitial(node->plans); - EvalPlanQualSetPlan(&mtstate->mt_epqstate, subplan, - mtstate->mt_arowmarks[0]); + EvalPlanQualSetPlan(&mtstate->mt_epqstate, subplan, arowmarks); /* - * Initialize the junk filter(s) if needed. INSERT queries need a filter - * if there are any junk attrs in the tlist. UPDATE and DELETE always - * need a filter, since there's always at least one junk attribute present - * --- no need to look first. Typically, this will be a 'ctid' or - * 'wholerow' attribute, but in the case of a foreign data wrapper it - * might be a set of junk attributes sufficient to identify the remote - * row. + * If there are a lot of result relations, use a hash table to speed the + * lookups. If there are not a lot, a simple linear search is faster. * - * If there are multiple result relations, each one needs its own junk - * filter. Note multiple rels are only possible for UPDATE/DELETE, so we - * can't be fooled by some needing a filter and some not. - * - * This section of code is also a convenient place to verify that the - * output of an INSERT or UPDATE matches the target table(s). + * It's not clear where the threshold is, but try 64 for starters. In a + * debugging build, use a small threshold so that we get some test + * coverage of both code paths. */ +#ifdef USE_ASSERT_CHECKING +#define MT_NRELS_HASH 4 +#else +#define MT_NRELS_HASH 64 +#endif + if (nrels >= MT_NRELS_HASH) { - bool junk_filter_needed = false; - - switch (operation) + HASHCTL hash_ctl; + + hash_ctl.keysize = sizeof(Oid); + hash_ctl.entrysize = sizeof(MTTargetRelLookup); + hash_ctl.hcxt = CurrentMemoryContext; + mtstate->mt_resultOidHash = + hash_create("ModifyTable target hash", + nrels, &hash_ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + for (i = 0; i < nrels; i++) { - case CMD_INSERT: - foreach(l, subplan->targetlist) - { - TargetEntry *tle = (TargetEntry *) lfirst(l); - - if (tle->resjunk) - { - junk_filter_needed = true; - break; - } - } - break; - case CMD_UPDATE: - case CMD_DELETE: - junk_filter_needed = true; - break; - default: - elog(ERROR, "unknown operation"); - break; + Oid hashkey; + MTTargetRelLookup *mtlookup; + bool found; + + resultRelInfo = &mtstate->resultRelInfo[i]; + hashkey = RelationGetRelid(resultRelInfo->ri_RelationDesc); + mtlookup = (MTTargetRelLookup *) + hash_search(mtstate->mt_resultOidHash, &hashkey, + HASH_ENTER, &found); + Assert(!found); + mtlookup->relationIndex = i; } + } + else + mtstate->mt_resultOidHash = NULL; - if (junk_filter_needed) + /* + * Determine if the FDW supports batch insert and determine the batch size + * (a FDW may support batching, but it may be disabled for the + * server/table). + * + * We only do this for INSERT, so that for UPDATE/DELETE the batch size + * remains set to 0. + */ + if (operation == CMD_INSERT) + { + /* insert may only have one relation, inheritance is not expanded */ + Assert(nrels == 1); + resultRelInfo = mtstate->resultRelInfo; + if (!resultRelInfo->ri_usesFdwDirectModify && + resultRelInfo->ri_FdwRoutine != NULL && + resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize && + resultRelInfo->ri_FdwRoutine->ExecForeignBatchInsert) { - resultRelInfo = mtstate->resultRelInfo; - for (i = 0; i < nplans; i++) - { - JunkFilter *j; - TupleTableSlot *junkresslot; - - subplan = mtstate->mt_plans[i]->plan; - if (operation == CMD_INSERT || operation == CMD_UPDATE) - ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc, - subplan->targetlist); - - junkresslot = - ExecInitExtraTupleSlot(estate, NULL, - table_slot_callbacks(resultRelInfo->ri_RelationDesc)); - j = ExecInitJunkFilter(subplan->targetlist, - junkresslot); - - if (operation == CMD_UPDATE || operation == CMD_DELETE) - { - /* For UPDATE/DELETE, find the appropriate junk attr now */ - char relkind; - - relkind = resultRelInfo->ri_RelationDesc->rd_rel->relkind; - if (relkind == RELKIND_RELATION || - relkind == RELKIND_MATVIEW || - relkind == RELKIND_PARTITIONED_TABLE || - IsAppendonlyMetadataRelkind(relkind)) - { - j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid"); - if (!AttributeNumberIsValid(j->jf_junkAttNo)) - elog(ERROR, "could not find junk ctid column"); - - /* Extra GPDB junk columns */ - resultRelInfo->ri_segid_attno = ExecFindJunkAttribute(j, "gp_segment_id"); - if (!AttributeNumberIsValid(resultRelInfo->ri_segid_attno)) - elog(ERROR, "could not find junk gp_segment_id column"); - - if (operation == CMD_UPDATE && mtstate->mt_isSplitUpdates[i]) - { - resultRelInfo->ri_action_attno = ExecFindJunkAttribute(j, "DMLAction"); - if (!AttributeNumberIsValid(resultRelInfo->ri_action_attno)) - elog(ERROR, "could not find junk action column"); - } - } - else if (relkind == RELKIND_FOREIGN_TABLE) - { - /* - * When there is a row-level trigger, there should be - * a wholerow attribute. - */ - j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow"); - } - else - { - j->jf_junkAttNo = ExecFindJunkAttribute(j, "wholerow"); - if (!AttributeNumberIsValid(j->jf_junkAttNo)) - elog(ERROR, "could not find junk wholerow column"); - } - } - - resultRelInfo->ri_junkFilter = j; - resultRelInfo++; - } + resultRelInfo->ri_BatchSize = + resultRelInfo->ri_FdwRoutine->GetForeignModifyBatchSize(resultRelInfo); + Assert(resultRelInfo->ri_BatchSize >= 1); } else - { - if (operation == CMD_INSERT) - ExecCheckPlanOutput(mtstate->resultRelInfo->ri_RelationDesc, - subplan->targetlist); - } + resultRelInfo->ri_BatchSize = 1; } /* @@ -3211,17 +3807,37 @@ ExecEndModifyTable(ModifyTableState *node) /* * Allow any FDWs to shut down */ - for (i = 0; i < node->mt_nplans; i++) + for (i = 0; i < node->mt_nrels; i++) { + int j; ResultRelInfo *resultRelInfo = node->resultRelInfo + i; + /* + * Let the table AM tear down any per-DML backend-local state set up by + * table_dml_init() in ExecInitModifyTable(). For append-optimized + * tables this finishes the insert descriptor, which flushes the segment + * file, updates pg_aoseg row counts and releases the metadata snapshot; + * skipping it loses all inserted rows and leaks the snapshot. + */ + if (resultRelInfo->ri_RelationDesc->rd_tableam) + table_dml_finish(resultRelInfo->ri_RelationDesc); + if (!resultRelInfo->ri_usesFdwDirectModify && resultRelInfo->ri_FdwRoutine != NULL && resultRelInfo->ri_FdwRoutine->EndForeignModify != NULL) resultRelInfo->ri_FdwRoutine->EndForeignModify(node->ps.state, resultRelInfo); - if (resultRelInfo->ri_RelationDesc->rd_tableam) - table_dml_finish(resultRelInfo->ri_RelationDesc); + + /* + * Cleanup the initialized batch slots. This only matters for FDWs + * with batching, but the other cases will have ri_NumSlotsInitialized + * == 0. + */ + for (j = 0; j < resultRelInfo->ri_NumSlotsInitialized; j++) + { + ExecDropSingleTupleTableSlot(resultRelInfo->ri_Slots[j]); + ExecDropSingleTupleTableSlot(resultRelInfo->ri_PlanSlots[j]); + } } /* @@ -3253,10 +3869,9 @@ ExecEndModifyTable(ModifyTableState *node) EvalPlanQualEnd(&node->mt_epqstate); /* - * shut down subplans + * shut down subplan */ - for (i = 0; i < node->mt_nplans; i++) - ExecEndNode(node->mt_plans[i]); + ExecEndNode(outerPlanState(node)); } void diff --git a/src/backend/executor/nodeNamedtuplestorescan.c b/src/backend/executor/nodeNamedtuplestorescan.c index 3135c7a27e18..c0d1069f5985 100644 --- a/src/backend/executor/nodeNamedtuplestorescan.c +++ b/src/backend/executor/nodeNamedtuplestorescan.c @@ -3,7 +3,7 @@ * nodeNamedtuplestorescan.c * routines to handle NamedTuplestoreScan nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c index 42ca3aaf3868..a6f56940e95c 100644 --- a/src/backend/executor/nodeNestloop.c +++ b/src/backend/executor/nodeNestloop.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeProjectSet.c b/src/backend/executor/nodeProjectSet.c index e8da6eaec914..07be814d7b52 100644 --- a/src/backend/executor/nodeProjectSet.c +++ b/src/backend/executor/nodeProjectSet.c @@ -11,7 +11,7 @@ * can't be inside more-complex expressions. If that'd otherwise be * the case, the planner adds additional ProjectSet nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/executor/nodeRecursiveunion.c b/src/backend/executor/nodeRecursiveunion.c index 22f251f8747b..316bb86e43ec 100644 --- a/src/backend/executor/nodeRecursiveunion.c +++ b/src/backend/executor/nodeRecursiveunion.c @@ -7,7 +7,7 @@ * already seen. The hash key is computed from the grouping columns. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c index afdef282e684..7c47903573a1 100644 --- a/src/backend/executor/nodeResult.c +++ b/src/backend/executor/nodeResult.c @@ -36,7 +36,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/executor/nodeResultCache.c b/src/backend/executor/nodeResultCache.c new file mode 100644 index 000000000000..471900346f11 --- /dev/null +++ b/src/backend/executor/nodeResultCache.c @@ -0,0 +1,1127 @@ +/*------------------------------------------------------------------------- + * + * nodeResultCache.c + * Routines to handle caching of results from parameterized nodes + * + * Portions Copyright (c) 2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/executor/nodeResultCache.c + * + * ResultCache nodes are intended to sit above parameterized nodes in the plan + * tree in order to cache results from them. The intention here is that a + * repeat scan with a parameter value that has already been seen by the node + * can fetch tuples from the cache rather than having to re-scan the outer + * node all over again. The query planner may choose to make use of one of + * these when it thinks rescans for previously seen values are likely enough + * to warrant adding the additional node. + * + * The method of cache we use is a hash table. When the cache fills, we never + * spill tuples to disk, instead, we choose to evict the least recently used + * cache entry from the cache. We remember the least recently used entry by + * always pushing new entries and entries we look for onto the tail of a + * doubly linked list. This means that older items always bubble to the top + * of this LRU list. + * + * Sometimes our callers won't run their scans to completion. For example a + * semi-join only needs to run until it finds a matching tuple, and once it + * does, the join operator skips to the next outer tuple and does not execute + * the inner side again on that scan. Because of this, we must keep track of + * when a cache entry is complete, and by default, we know it is when we run + * out of tuples to read during the scan. However, there are cases where we + * can mark the cache entry as complete without exhausting the scan of all + * tuples. One case is unique joins, where the join operator knows that there + * will only be at most one match for any given outer tuple. In order to + * support such cases we allow the "singlerow" option to be set for the cache. + * This option marks the cache entry as complete after we read the first tuple + * from the subnode. + * + * It's possible when we're filling the cache for a given set of parameters + * that we're unable to free enough memory to store any more tuples. If this + * happens then we'll have already evicted all other cache entries. When + * caching another tuple would cause us to exceed our memory budget, we must + * free the entry that we're currently populating and move the state machine + * into RC_CACHE_BYPASS_MODE. This means that we'll not attempt to cache any + * further tuples for this particular scan. We don't have the memory for it. + * The state machine will be reset again on the next rescan. If the memory + * requirements to cache the next parameter's tuples are less demanding, then + * that may allow us to start putting useful entries back into the cache + * again. + * + * + * INTERFACE ROUTINES + * ExecResultCache - lookup cache, exec subplan when not found + * ExecInitResultCache - initialize node and subnodes + * ExecEndResultCache - shutdown node and subnodes + * ExecReScanResultCache - rescan the result cache + * + * ExecResultCacheEstimate estimates DSM space needed for parallel plan + * ExecResultCacheInitializeDSM initialize DSM for parallel plan + * ExecResultCacheInitializeWorker attach to DSM info in parallel worker + * ExecResultCacheRetrieveInstrumentation get instrumentation from worker + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "common/hashfn.h" +#include "executor/executor.h" +#include "executor/nodeResultCache.h" +#include "lib/ilist.h" +#include "miscadmin.h" +#include "utils/lsyscache.h" + +/* States of the ExecResultCache state machine */ +#define RC_CACHE_LOOKUP 1 /* Attempt to perform a cache lookup */ +#define RC_CACHE_FETCH_NEXT_TUPLE 2 /* Get another tuple from the cache */ +#define RC_FILLING_CACHE 3 /* Read outer node to fill cache */ +#define RC_CACHE_BYPASS_MODE 4 /* Bypass mode. Just read from our + * subplan without caching anything */ +#define RC_END_OF_SCAN 5 /* Ready for rescan */ + + +/* Helper macros for memory accounting */ +#define EMPTY_ENTRY_MEMORY_BYTES(e) (sizeof(ResultCacheEntry) + \ + sizeof(ResultCacheKey) + \ + (e)->key->params->t_len); +#define CACHE_TUPLE_BYTES(t) (sizeof(ResultCacheTuple) + \ + (t)->mintuple->t_len) + + /* ResultCacheTuple Stores an individually cached tuple */ +typedef struct ResultCacheTuple +{ + MinimalTuple mintuple; /* Cached tuple */ + struct ResultCacheTuple *next; /* The next tuple with the same parameter + * values or NULL if it's the last one */ +} ResultCacheTuple; + +/* + * ResultCacheKey + * The hash table key for cached entries plus the LRU list link + */ +typedef struct ResultCacheKey +{ + MinimalTuple params; + dlist_node lru_node; /* Pointer to next/prev key in LRU list */ +} ResultCacheKey; + +/* + * ResultCacheEntry + * The data struct that the cache hash table stores + */ +typedef struct ResultCacheEntry +{ + ResultCacheKey *key; /* Hash key for hash table lookups */ + ResultCacheTuple *tuplehead; /* Pointer to the first tuple or NULL if + * no tuples are cached for this entry */ + uint32 hash; /* Hash value (cached) */ + char status; /* Hash status */ + bool complete; /* Did we read the outer plan to completion? */ +} ResultCacheEntry; + + +#define SH_PREFIX resultcache +#define SH_ELEMENT_TYPE ResultCacheEntry +#define SH_KEY_TYPE ResultCacheKey * +#define SH_SCOPE static inline +#define SH_DECLARE +#include "lib/simplehash.h" + +static uint32 ResultCacheHash_hash(struct resultcache_hash *tb, + const ResultCacheKey *key); +static int ResultCacheHash_equal(struct resultcache_hash *tb, + const ResultCacheKey *params1, + const ResultCacheKey *params2); + +#define SH_PREFIX resultcache +#define SH_ELEMENT_TYPE ResultCacheEntry +#define SH_KEY_TYPE ResultCacheKey * +#define SH_KEY key +#define SH_HASH_KEY(tb, key) ResultCacheHash_hash(tb, key) +#define SH_EQUAL(tb, a, b) (ResultCacheHash_equal(tb, a, b) == 0) +#define SH_SCOPE static inline +#define SH_STORE_HASH +#define SH_GET_HASH(tb, a) a->hash +#define SH_DEFINE +#include "lib/simplehash.h" + +/* + * ResultCacheHash_hash + * Hash function for simplehash hashtable. 'key' is unused here as we + * require that all table lookups first populate the ResultCacheState's + * probeslot with the key values to be looked up. + */ +static uint32 +ResultCacheHash_hash(struct resultcache_hash *tb, const ResultCacheKey *key) +{ + ResultCacheState *rcstate = (ResultCacheState *) tb->private_data; + TupleTableSlot *pslot = rcstate->probeslot; + uint32 hashkey = 0; + int numkeys = rcstate->nkeys; + FmgrInfo *hashfunctions = rcstate->hashfunctions; + Oid *collations = rcstate->collations; + + for (int i = 0; i < numkeys; i++) + { + /* rotate hashkey left 1 bit at each step */ + hashkey = (hashkey << 1) | ((hashkey & 0x80000000) ? 1 : 0); + + if (!pslot->tts_isnull[i]) /* treat nulls as having hash key 0 */ + { + uint32 hkey; + + hkey = DatumGetUInt32(FunctionCall1Coll(&hashfunctions[i], + collations[i], pslot->tts_values[i])); + hashkey ^= hkey; + } + } + + return murmurhash32(hashkey); +} + +/* + * ResultCacheHash_equal + * Equality function for confirming hash value matches during a hash + * table lookup. 'key2' is never used. Instead the ResultCacheState's + * probeslot is always populated with details of what's being looked up. + */ +static int +ResultCacheHash_equal(struct resultcache_hash *tb, const ResultCacheKey *key1, + const ResultCacheKey *key2) +{ + ResultCacheState *rcstate = (ResultCacheState *) tb->private_data; + ExprContext *econtext = rcstate->ss.ps.ps_ExprContext; + TupleTableSlot *tslot = rcstate->tableslot; + TupleTableSlot *pslot = rcstate->probeslot; + + /* probeslot should have already been prepared by prepare_probe_slot() */ + + ExecStoreMinimalTuple(key1->params, tslot, false); + + econtext->ecxt_innertuple = tslot; + econtext->ecxt_outertuple = pslot; + return !ExecQualAndReset(rcstate->cache_eq_expr, econtext); +} + +/* + * Initialize the hash table to empty. + */ +static void +build_hash_table(ResultCacheState *rcstate, uint32 size) +{ + /* Make a guess at a good size when we're not given a valid size. */ + if (size == 0) + size = 1024; + + /* resultcache_create will convert the size to a power of 2 */ + rcstate->hashtable = resultcache_create(rcstate->tableContext, size, + rcstate); +} + +/* + * prepare_probe_slot + * Populate rcstate's probeslot with the values from the tuple stored + * in 'key'. If 'key' is NULL, then perform the population by evaluating + * rcstate's param_exprs. + */ +static inline void +prepare_probe_slot(ResultCacheState *rcstate, ResultCacheKey *key) +{ + TupleTableSlot *pslot = rcstate->probeslot; + TupleTableSlot *tslot = rcstate->tableslot; + int numKeys = rcstate->nkeys; + + ExecClearTuple(pslot); + + if (key == NULL) + { + /* Set the probeslot's values based on the current parameter values */ + for (int i = 0; i < numKeys; i++) + pslot->tts_values[i] = ExecEvalExpr(rcstate->param_exprs[i], + rcstate->ss.ps.ps_ExprContext, + &pslot->tts_isnull[i]); + } + else + { + /* Process the key's MinimalTuple and store the values in probeslot */ + ExecStoreMinimalTuple(key->params, tslot, false); + slot_getallattrs(tslot); + memcpy(pslot->tts_values, tslot->tts_values, sizeof(Datum) * numKeys); + memcpy(pslot->tts_isnull, tslot->tts_isnull, sizeof(bool) * numKeys); + } + + ExecStoreVirtualTuple(pslot); +} + +/* + * entry_purge_tuples + * Remove all tuples from the cache entry pointed to by 'entry'. This + * leaves an empty cache entry. Also, update the memory accounting to + * reflect the removal of the tuples. + */ +static inline void +entry_purge_tuples(ResultCacheState *rcstate, ResultCacheEntry *entry) +{ + ResultCacheTuple *tuple = entry->tuplehead; + uint64 freed_mem = 0; + + while (tuple != NULL) + { + ResultCacheTuple *next = tuple->next; + + freed_mem += CACHE_TUPLE_BYTES(tuple); + + /* Free memory used for this tuple */ + pfree(tuple->mintuple); + pfree(tuple); + + tuple = next; + } + + entry->complete = false; + entry->tuplehead = NULL; + + /* Update the memory accounting */ + rcstate->mem_used -= freed_mem; +} + +/* + * remove_cache_entry + * Remove 'entry' from the cache and free memory used by it. + */ +static void +remove_cache_entry(ResultCacheState *rcstate, ResultCacheEntry *entry) +{ + ResultCacheKey *key = entry->key; + + dlist_delete(&entry->key->lru_node); + + /* Remove all of the tuples from this entry */ + entry_purge_tuples(rcstate, entry); + + /* + * Update memory accounting. entry_purge_tuples should have already + * subtracted the memory used for each cached tuple. Here we just update + * the amount used by the entry itself. + */ + rcstate->mem_used -= EMPTY_ENTRY_MEMORY_BYTES(entry); + + /* Remove the entry from the cache */ + resultcache_delete_item(rcstate->hashtable, entry); + + pfree(key->params); + pfree(key); +} + +/* + * cache_reduce_memory + * Evict older and less recently used items from the cache in order to + * reduce the memory consumption back to something below the + * ResultCacheState's mem_limit. + * + * 'specialkey', if not NULL, causes the function to return false if the entry + * which the key belongs to is removed from the cache. + */ +static bool +cache_reduce_memory(ResultCacheState *rcstate, ResultCacheKey *specialkey) +{ + bool specialkey_intact = true; /* for now */ + dlist_mutable_iter iter; + uint64 evictions = 0; + + /* Update peak memory usage */ + if (rcstate->mem_used > rcstate->stats.mem_peak) + rcstate->stats.mem_peak = rcstate->mem_used; + + /* We expect only to be called when we've gone over budget on memory */ + Assert(rcstate->mem_used > rcstate->mem_limit); + + /* Start the eviction process starting at the head of the LRU list. */ + dlist_foreach_modify(iter, &rcstate->lru_list) + { + ResultCacheKey *key = dlist_container(ResultCacheKey, lru_node, + iter.cur); + ResultCacheEntry *entry; + + /* + * Populate the hash probe slot in preparation for looking up this LRU + * entry. + */ + prepare_probe_slot(rcstate, key); + + /* + * Ideally the LRU list pointers would be stored in the entry itself + * rather than in the key. Unfortunately, we can't do that as the + * simplehash.h code may resize the table and allocate new memory for + * entries which would result in those pointers pointing to the old + * buckets. However, it's fine to use the key to store this as that's + * only referenced by a pointer in the entry, which of course follows + * the entry whenever the hash table is resized. Since we only have a + * pointer to the key here, we must perform a hash table lookup to + * find the entry that the key belongs to. + */ + entry = resultcache_lookup(rcstate->hashtable, NULL); + + /* A good spot to check for corruption of the table and LRU list. */ + Assert(entry != NULL); + Assert(entry->key == key); + + /* + * If we're being called to free memory while the cache is being + * populated with new tuples, then we'd better take some care as we + * could end up freeing the entry which 'specialkey' belongs to. + * Generally callers will pass 'specialkey' as the key for the cache + * entry which is currently being populated, so we must set + * 'specialkey_intact' to false to inform the caller the specialkey + * entry has been removed. + */ + if (key == specialkey) + specialkey_intact = false; + + /* + * Finally remove the entry. This will remove from the LRU list too. + */ + remove_cache_entry(rcstate, entry); + + evictions++; + + /* Exit if we've freed enough memory */ + if (rcstate->mem_used <= rcstate->mem_limit) + break; + } + + rcstate->stats.cache_evictions += evictions; /* Update Stats */ + + return specialkey_intact; +} + +/* + * cache_lookup + * Perform a lookup to see if we've already cached results based on the + * scan's current parameters. If we find an existing entry we move it to + * the end of the LRU list, set *found to true then return it. If we + * don't find an entry then we create a new one and add it to the end of + * the LRU list. We also update cache memory accounting and remove older + * entries if we go over the memory budget. If we managed to free enough + * memory we return the new entry, else we return NULL. + * + * Callers can assume we'll never return NULL when *found is true. + */ +static ResultCacheEntry * +cache_lookup(ResultCacheState *rcstate, bool *found) +{ + ResultCacheKey *key; + ResultCacheEntry *entry; + MemoryContext oldcontext; + + /* prepare the probe slot with the current scan parameters */ + prepare_probe_slot(rcstate, NULL); + + /* + * Add the new entry to the cache. No need to pass a valid key since the + * hash function uses rcstate's probeslot, which we populated above. + */ + entry = resultcache_insert(rcstate->hashtable, NULL, found); + + if (*found) + { + /* + * Move existing entry to the tail of the LRU list to mark it as the + * most recently used item. + */ + dlist_move_tail(&rcstate->lru_list, &entry->key->lru_node); + + return entry; + } + + oldcontext = MemoryContextSwitchTo(rcstate->tableContext); + + /* Allocate a new key */ + entry->key = key = (ResultCacheKey *) palloc(sizeof(ResultCacheKey)); + key->params = ExecCopySlotMinimalTuple(rcstate->probeslot); + + /* Update the total cache memory utilization */ + rcstate->mem_used += EMPTY_ENTRY_MEMORY_BYTES(entry); + + /* Initialize this entry */ + entry->complete = false; + entry->tuplehead = NULL; + + /* + * Since this is the most recently used entry, push this entry onto the + * end of the LRU list. + */ + dlist_push_tail(&rcstate->lru_list, &entry->key->lru_node); + + rcstate->last_tuple = NULL; + + MemoryContextSwitchTo(oldcontext); + + /* + * If we've gone over our memory budget, then we'll free up some space in + * the cache. + */ + if (rcstate->mem_used > rcstate->mem_limit) + { + /* + * Try to free up some memory. It's highly unlikely that we'll fail + * to do so here since the entry we've just added is yet to contain + * any tuples and we're able to remove any other entry to reduce the + * memory consumption. + */ + if (unlikely(!cache_reduce_memory(rcstate, key))) + return NULL; + + /* + * The process of removing entries from the cache may have caused the + * code in simplehash.h to shuffle elements to earlier buckets in the + * hash table. If it has, we'll need to find the entry again by + * performing a lookup. Fortunately, we can detect if this has + * happened by seeing if the entry is still in use and that the key + * pointer matches our expected key. + */ + if (entry->status != resultcache_SH_IN_USE || entry->key != key) + { + /* + * We need to repopulate the probeslot as lookups performed during + * the cache evictions above will have stored some other key. + */ + prepare_probe_slot(rcstate, key); + + /* Re-find the newly added entry */ + entry = resultcache_lookup(rcstate->hashtable, NULL); + Assert(entry != NULL); + } + } + + return entry; +} + +/* + * cache_store_tuple + * Add the tuple stored in 'slot' to the rcstate's current cache entry. + * The cache entry must have already been made with cache_lookup(). + * rcstate's last_tuple field must point to the tail of rcstate->entry's + * list of tuples. + */ +static bool +cache_store_tuple(ResultCacheState *rcstate, TupleTableSlot *slot) +{ + ResultCacheTuple *tuple; + ResultCacheEntry *entry = rcstate->entry; + MemoryContext oldcontext; + + Assert(slot != NULL); + Assert(entry != NULL); + + oldcontext = MemoryContextSwitchTo(rcstate->tableContext); + + tuple = (ResultCacheTuple *) palloc(sizeof(ResultCacheTuple)); + tuple->mintuple = ExecCopySlotMinimalTuple(slot); + tuple->next = NULL; + + /* Account for the memory we just consumed */ + rcstate->mem_used += CACHE_TUPLE_BYTES(tuple); + + if (entry->tuplehead == NULL) + { + /* + * This is the first tuple for this entry, so just point the list head + * to it. + */ + entry->tuplehead = tuple; + } + else + { + /* push this tuple onto the tail of the list */ + rcstate->last_tuple->next = tuple; + } + + rcstate->last_tuple = tuple; + MemoryContextSwitchTo(oldcontext); + + /* + * If we've gone over our memory budget then free up some space in the + * cache. + */ + if (rcstate->mem_used > rcstate->mem_limit) + { + ResultCacheKey *key = entry->key; + + if (!cache_reduce_memory(rcstate, key)) + return false; + + /* + * The process of removing entries from the cache may have caused the + * code in simplehash.h to shuffle elements to earlier buckets in the + * hash table. If it has, we'll need to find the entry again by + * performing a lookup. Fortunately, we can detect if this has + * happened by seeing if the entry is still in use and that the key + * pointer matches our expected key. + */ + if (entry->status != resultcache_SH_IN_USE || entry->key != key) + { + /* + * We need to repopulate the probeslot as lookups performed during + * the cache evictions above will have stored some other key. + */ + prepare_probe_slot(rcstate, key); + + /* Re-find the entry */ + rcstate->entry = entry = resultcache_lookup(rcstate->hashtable, + NULL); + Assert(entry != NULL); + } + } + + return true; +} + +static TupleTableSlot * +ExecResultCache(PlanState *pstate) +{ + ResultCacheState *node = castNode(ResultCacheState, pstate); + PlanState *outerNode; + TupleTableSlot *slot; + + switch (node->rc_status) + { + case RC_CACHE_LOOKUP: + { + ResultCacheEntry *entry; + TupleTableSlot *outerslot; + bool found; + + Assert(node->entry == NULL); + + /* + * We're only ever in this state for the first call of the + * scan. Here we have a look to see if we've already seen the + * current parameters before and if we have already cached a + * complete set of records that the outer plan will return for + * these parameters. + * + * When we find a valid cache entry, we'll return the first + * tuple from it. If not found, we'll create a cache entry and + * then try to fetch a tuple from the outer scan. If we find + * one there, we'll try to cache it. + */ + + /* see if we've got anything cached for the current parameters */ + entry = cache_lookup(node, &found); + + if (found && entry->complete) + { + node->stats.cache_hits += 1; /* stats update */ + + /* + * Set last_tuple and entry so that the state + * RC_CACHE_FETCH_NEXT_TUPLE can easily find the next + * tuple for these parameters. + */ + node->last_tuple = entry->tuplehead; + node->entry = entry; + + /* Fetch the first cached tuple, if there is one */ + if (entry->tuplehead) + { + node->rc_status = RC_CACHE_FETCH_NEXT_TUPLE; + + slot = node->ss.ps.ps_ResultTupleSlot; + ExecStoreMinimalTuple(entry->tuplehead->mintuple, + slot, false); + + return slot; + } + + /* The cache entry is void of any tuples. */ + node->rc_status = RC_END_OF_SCAN; + return NULL; + } + + /* Handle cache miss */ + node->stats.cache_misses += 1; /* stats update */ + + if (found) + { + /* + * A cache entry was found, but the scan for that entry + * did not run to completion. We'll just remove all + * tuples and start again. It might be tempting to + * continue where we left off, but there's no guarantee + * the outer node will produce the tuples in the same + * order as it did last time. + */ + entry_purge_tuples(node, entry); + } + + /* Scan the outer node for a tuple to cache */ + outerNode = outerPlanState(node); + outerslot = ExecProcNode(outerNode); + if (TupIsNull(outerslot)) + { + /* + * cache_lookup may have returned NULL due to failure to + * free enough cache space, so ensure we don't do anything + * here that assumes it worked. There's no need to go into + * bypass mode here as we're setting rc_status to end of + * scan. + */ + if (likely(entry)) + entry->complete = true; + + node->rc_status = RC_END_OF_SCAN; + return NULL; + } + + node->entry = entry; + + /* + * If we failed to create the entry or failed to store the + * tuple in the entry, then go into bypass mode. + */ + if (unlikely(entry == NULL || + !cache_store_tuple(node, outerslot))) + { + node->stats.cache_overflows += 1; /* stats update */ + + node->rc_status = RC_CACHE_BYPASS_MODE; + + /* + * No need to clear out last_tuple as we'll stay in bypass + * mode until the end of the scan. + */ + } + else + { + /* + * If we only expect a single row from this scan then we + * can mark that we're not expecting more. This allows + * cache lookups to work even when the scan has not been + * executed to completion. + */ + entry->complete = node->singlerow; + node->rc_status = RC_FILLING_CACHE; + } + + slot = node->ss.ps.ps_ResultTupleSlot; + ExecCopySlot(slot, outerslot); + return slot; + } + + case RC_CACHE_FETCH_NEXT_TUPLE: + { + /* We shouldn't be in this state if these are not set */ + Assert(node->entry != NULL); + Assert(node->last_tuple != NULL); + + /* Skip to the next tuple to output */ + node->last_tuple = node->last_tuple->next; + + /* No more tuples in the cache */ + if (node->last_tuple == NULL) + { + node->rc_status = RC_END_OF_SCAN; + return NULL; + } + + slot = node->ss.ps.ps_ResultTupleSlot; + ExecStoreMinimalTuple(node->last_tuple->mintuple, slot, + false); + + return slot; + } + + case RC_FILLING_CACHE: + { + TupleTableSlot *outerslot; + ResultCacheEntry *entry = node->entry; + + /* entry should already have been set by RC_CACHE_LOOKUP */ + Assert(entry != NULL); + + /* + * When in the RC_FILLING_CACHE state, we've just had a cache + * miss and are populating the cache with the current scan + * tuples. + */ + outerNode = outerPlanState(node); + outerslot = ExecProcNode(outerNode); + if (TupIsNull(outerslot)) + { + /* No more tuples. Mark it as complete */ + entry->complete = true; + node->rc_status = RC_END_OF_SCAN; + return NULL; + } + + /* + * Validate if the planner properly set the singlerow flag. It + * should only set that if each cache entry can, at most, + * return 1 row. + */ + if (unlikely(entry->complete)) + elog(ERROR, "cache entry already complete"); + + /* Record the tuple in the current cache entry */ + if (unlikely(!cache_store_tuple(node, outerslot))) + { + /* Couldn't store it? Handle overflow */ + node->stats.cache_overflows += 1; /* stats update */ + + node->rc_status = RC_CACHE_BYPASS_MODE; + + /* + * No need to clear out entry or last_tuple as we'll stay + * in bypass mode until the end of the scan. + */ + } + + slot = node->ss.ps.ps_ResultTupleSlot; + ExecCopySlot(slot, outerslot); + return slot; + } + + case RC_CACHE_BYPASS_MODE: + { + TupleTableSlot *outerslot; + + /* + * When in bypass mode we just continue to read tuples without + * caching. We need to wait until the next rescan before we + * can come out of this mode. + */ + outerNode = outerPlanState(node); + outerslot = ExecProcNode(outerNode); + if (TupIsNull(outerslot)) + { + node->rc_status = RC_END_OF_SCAN; + return NULL; + } + + slot = node->ss.ps.ps_ResultTupleSlot; + ExecCopySlot(slot, outerslot); + return slot; + } + + case RC_END_OF_SCAN: + + /* + * We've already returned NULL for this scan, but just in case + * something calls us again by mistake. + */ + return NULL; + + default: + elog(ERROR, "unrecognized resultcache state: %d", + (int) node->rc_status); + return NULL; + } /* switch */ +} + +ResultCacheState * +ExecInitResultCache(ResultCache *node, EState *estate, int eflags) +{ + ResultCacheState *rcstate = makeNode(ResultCacheState); + Plan *outerNode; + int i; + int nkeys; + Oid *eqfuncoids; + + /* check for unsupported flags */ + Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); + + rcstate->ss.ps.plan = (Plan *) node; + rcstate->ss.ps.state = estate; + rcstate->ss.ps.ExecProcNode = ExecResultCache; + + /* + * Miscellaneous initialization + * + * create expression context for node + */ + ExecAssignExprContext(estate, &rcstate->ss.ps); + + outerNode = outerPlan(node); + outerPlanState(rcstate) = ExecInitNode(outerNode, estate, eflags); + + /* + * Initialize return slot and type. No need to initialize projection info + * because this node doesn't do projections. + */ + ExecInitResultTupleSlotTL(&rcstate->ss.ps, &TTSOpsMinimalTuple); + rcstate->ss.ps.ps_ProjInfo = NULL; + + /* + * Initialize scan slot and type. + */ + ExecCreateScanSlotFromOuterPlan(estate, &rcstate->ss, &TTSOpsMinimalTuple); + + /* + * Set the state machine to lookup the cache. We won't find anything + * until we cache something, but this saves a special case to create the + * first entry. + */ + rcstate->rc_status = RC_CACHE_LOOKUP; + + rcstate->nkeys = nkeys = node->numKeys; + rcstate->hashkeydesc = ExecTypeFromExprList(node->param_exprs); + rcstate->tableslot = MakeSingleTupleTableSlot(rcstate->hashkeydesc, + &TTSOpsMinimalTuple); + rcstate->probeslot = MakeSingleTupleTableSlot(rcstate->hashkeydesc, + &TTSOpsVirtual); + + rcstate->param_exprs = (ExprState **) palloc(nkeys * sizeof(ExprState *)); + rcstate->collations = node->collations; /* Just point directly to the plan + * data */ + rcstate->hashfunctions = (FmgrInfo *) palloc(nkeys * sizeof(FmgrInfo)); + + eqfuncoids = palloc(nkeys * sizeof(Oid)); + + for (i = 0; i < nkeys; i++) + { + Oid hashop = node->hashOperators[i]; + Oid left_hashfn; + Oid right_hashfn; + Expr *param_expr = (Expr *) list_nth(node->param_exprs, i); + + if (!get_op_hash_functions(hashop, &left_hashfn, &right_hashfn)) + elog(ERROR, "could not find hash function for hash operator %u", + hashop); + + fmgr_info(left_hashfn, &rcstate->hashfunctions[i]); + + rcstate->param_exprs[i] = ExecInitExpr(param_expr, (PlanState *) rcstate); + eqfuncoids[i] = get_opcode(hashop); + } + + rcstate->cache_eq_expr = ExecBuildParamSetEqual(rcstate->hashkeydesc, + &TTSOpsMinimalTuple, + &TTSOpsVirtual, + eqfuncoids, + node->collations, + node->param_exprs, + (PlanState *) rcstate); + + pfree(eqfuncoids); + rcstate->mem_used = 0; + + /* Limit the total memory consumed by the cache to this */ + rcstate->mem_limit = get_hash_mem() * 1024L; + + /* A memory context dedicated for the cache */ + rcstate->tableContext = AllocSetContextCreate(CurrentMemoryContext, + "ResultCacheHashTable", + ALLOCSET_DEFAULT_SIZES); + + dlist_init(&rcstate->lru_list); + rcstate->last_tuple = NULL; + rcstate->entry = NULL; + + /* + * Mark if we can assume the cache entry is completed after we get the + * first record for it. Some callers might not call us again after + * getting the first match. e.g. A join operator performing a unique join + * is able to skip to the next outer tuple after getting the first + * matching inner tuple. In this case, the cache entry is complete after + * getting the first tuple. This allows us to mark it as so. + */ + rcstate->singlerow = node->singlerow; + + /* Zero the statistics counters */ + memset(&rcstate->stats, 0, sizeof(ResultCacheInstrumentation)); + + /* Allocate and set up the actual cache */ + build_hash_table(rcstate, node->est_entries); + + return rcstate; +} + +void +ExecEndResultCache(ResultCacheState *node) +{ +#ifdef USE_ASSERT_CHECKING + /* Validate the memory accounting code is correct in assert builds. */ + { + int count; + uint64 mem = 0; + resultcache_iterator i; + ResultCacheEntry *entry; + + resultcache_start_iterate(node->hashtable, &i); + + count = 0; + while ((entry = resultcache_iterate(node->hashtable, &i)) != NULL) + { + ResultCacheTuple *tuple = entry->tuplehead; + + mem += EMPTY_ENTRY_MEMORY_BYTES(entry); + while (tuple != NULL) + { + mem += CACHE_TUPLE_BYTES(tuple); + tuple = tuple->next; + } + count++; + } + + Assert(count == node->hashtable->members); + Assert(mem == node->mem_used); + } +#endif + + /* + * When ending a parallel worker, copy the statistics gathered by the + * worker back into shared memory so that it can be picked up by the main + * process to report in EXPLAIN ANALYZE. + */ + if (node->shared_info != NULL && IsParallelWorker()) + { + ResultCacheInstrumentation *si; + + /* Make mem_peak available for EXPLAIN */ + if (node->stats.mem_peak == 0) + node->stats.mem_peak = node->mem_used; + + Assert(ParallelWorkerNumber <= node->shared_info->num_workers); + si = &node->shared_info->sinstrument[ParallelWorkerNumber]; + memcpy(si, &node->stats, sizeof(ResultCacheInstrumentation)); + } + + /* Remove the cache context */ + MemoryContextDelete(node->tableContext); + + ExecClearTuple(node->ss.ss_ScanTupleSlot); + /* must drop pointer to cache result tuple */ + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + + /* + * free exprcontext + */ + ExecFreeExprContext(&node->ss.ps); + + /* + * shut down the subplan + */ + ExecEndNode(outerPlanState(node)); +} + +void +ExecReScanResultCache(ResultCacheState *node) +{ + PlanState *outerPlan = outerPlanState(node); + + /* Mark that we must lookup the cache for a new set of parameters */ + node->rc_status = RC_CACHE_LOOKUP; + + /* nullify pointers used for the last scan */ + node->entry = NULL; + node->last_tuple = NULL; + + /* + * if chgParam of subnode is not null then plan will be re-scanned by + * first ExecProcNode. + */ + if (outerPlan->chgParam == NULL) + ExecReScan(outerPlan); + +} + +/* + * ExecEstimateCacheEntryOverheadBytes + * For use in the query planner to help it estimate the amount of memory + * required to store a single entry in the cache. + */ +double +ExecEstimateCacheEntryOverheadBytes(double ntuples) +{ + return sizeof(ResultCacheEntry) + sizeof(ResultCacheKey) + + sizeof(ResultCacheTuple) * ntuples; +} + +/* ---------------------------------------------------------------- + * Parallel Query Support + * ---------------------------------------------------------------- + */ + + /* ---------------------------------------------------------------- + * ExecResultCacheEstimate + * + * Estimate space required to propagate result cache statistics. + * ---------------------------------------------------------------- + */ +void +ExecResultCacheEstimate(ResultCacheState *node, ParallelContext *pcxt) +{ + Size size; + + /* don't need this if not instrumenting or no workers */ + if (!node->ss.ps.instrument || pcxt->nworkers == 0) + return; + + size = mul_size(pcxt->nworkers, sizeof(ResultCacheInstrumentation)); + size = add_size(size, offsetof(SharedResultCacheInfo, sinstrument)); + shm_toc_estimate_chunk(&pcxt->estimator, size); + shm_toc_estimate_keys(&pcxt->estimator, 1); +} + +/* ---------------------------------------------------------------- + * ExecResultCacheInitializeDSM + * + * Initialize DSM space for result cache statistics. + * ---------------------------------------------------------------- + */ +void +ExecResultCacheInitializeDSM(ResultCacheState *node, ParallelContext *pcxt) +{ + Size size; + + /* don't need this if not instrumenting or no workers */ + if (!node->ss.ps.instrument || pcxt->nworkers == 0) + return; + + size = offsetof(SharedResultCacheInfo, sinstrument) + + pcxt->nworkers * sizeof(ResultCacheInstrumentation); + node->shared_info = shm_toc_allocate(pcxt->toc, size); + /* ensure any unfilled slots will contain zeroes */ + memset(node->shared_info, 0, size); + node->shared_info->num_workers = pcxt->nworkers; + shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, + node->shared_info); +} + +/* ---------------------------------------------------------------- + * ExecResultCacheInitializeWorker + * + * Attach worker to DSM space for result cache statistics. + * ---------------------------------------------------------------- + */ +void +ExecResultCacheInitializeWorker(ResultCacheState *node, ParallelWorkerContext *pwcxt) +{ + node->shared_info = + shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, true); +} + +/* ---------------------------------------------------------------- + * ExecResultCacheRetrieveInstrumentation + * + * Transfer result cache statistics from DSM to private memory. + * ---------------------------------------------------------------- + */ +void +ExecResultCacheRetrieveInstrumentation(ResultCacheState *node) +{ + Size size; + SharedResultCacheInfo *si; + + if (node->shared_info == NULL) + return; + + size = offsetof(SharedResultCacheInfo, sinstrument) + + node->shared_info->num_workers * sizeof(ResultCacheInstrumentation); + si = palloc(size); + memcpy(si, node->shared_info, size); + node->shared_info = si; +} diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c index 4732c926f7ba..44232d50d0a3 100644 --- a/src/backend/executor/nodeSamplescan.c +++ b/src/backend/executor/nodeSamplescan.c @@ -3,7 +3,7 @@ * nodeSamplescan.c * Support routines for sample scans of relations (table sampling). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index efa9a5281ae9..70232ab10ed9 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -3,7 +3,7 @@ * nodeSeqscan.c * Support routines for sequential scans of relations. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeSetOp.c b/src/backend/executor/nodeSetOp.c index 8d4ccff19cc6..aad7ac0ea2a5 100644 --- a/src/backend/executor/nodeSetOp.c +++ b/src/backend/executor/nodeSetOp.c @@ -32,7 +32,7 @@ * input group. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c index d2586348ccf8..d49c1d01c2e7 100644 --- a/src/backend/executor/nodeSort.c +++ b/src/backend/executor/nodeSort.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2007-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index c92e26c5ac45..ad5fdf51b297 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -13,7 +13,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -816,7 +816,15 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) sstate->planstate = (PlanState *) list_nth(estate->es_subplanstates, subplan->plan_id - 1); - /* ... and to its parent's state */ + /* + * This check can fail if the planner mistakenly puts a parallel-unsafe + * subplan into a parallelized subquery; see ExecSerializePlan. + */ + if (sstate->planstate == NULL) + elog(ERROR, "subplan \"%s\" was not initialized", + subplan->plan_name); + + /* Link to parent's state, too */ sstate->parent = parent; /* Initialize subexpressions */ @@ -1533,83 +1541,3 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent) parent->chgParam = bms_add_member(parent->chgParam, paramid); } } - - -/* - * ExecInitAlternativeSubPlan - * - * Initialize for execution of one of a set of alternative subplans. - */ -AlternativeSubPlanState * -ExecInitAlternativeSubPlan(AlternativeSubPlan *asplan, PlanState *parent) -{ - AlternativeSubPlanState *asstate = makeNode(AlternativeSubPlanState); - double num_calls; - SubPlan *subplan1; - SubPlan *subplan2; - Cost cost1; - Cost cost2; - ListCell *lc; - - asstate->subplan = asplan; - - /* - * Initialize subplans. (Can we get away with only initializing the one - * we're going to use?) - */ - foreach(lc, asplan->subplans) - { - SubPlan *sp = lfirst_node(SubPlan, lc); - SubPlanState *sps = ExecInitSubPlan(sp, parent); - - asstate->subplans = lappend(asstate->subplans, sps); - parent->subPlan = lappend(parent->subPlan, sps); - } - - /* - * Select the one to be used. For this, we need an estimate of the number - * of executions of the subplan. We use the number of output rows - * expected from the parent plan node. This is a good estimate if we are - * in the parent's targetlist, and an underestimate (but probably not by - * more than a factor of 2) if we are in the qual. - */ - num_calls = parent->plan->plan_rows; - - /* - * The planner saved enough info so that we don't have to work very hard - * to estimate the total cost, given the number-of-calls estimate. - */ - Assert(list_length(asplan->subplans) == 2); - subplan1 = (SubPlan *) linitial(asplan->subplans); - subplan2 = (SubPlan *) lsecond(asplan->subplans); - - cost1 = subplan1->startup_cost + num_calls * subplan1->per_call_cost; - cost2 = subplan2->startup_cost + num_calls * subplan2->per_call_cost; - - if (cost1 < cost2) - asstate->active = 0; - else - asstate->active = 1; - - return asstate; -} - -/* - * ExecAlternativeSubPlan - * - * Execute one of a set of alternative subplans. - * - * Note: in future we might consider changing to different subplans on the - * fly, in case the original rowcount estimate turns out to be way off. - */ -Datum -ExecAlternativeSubPlan(AlternativeSubPlanState *node, - ExprContext *econtext, - bool *isNull) -{ - /* Just pass control to the active subplan */ - SubPlanState *activesp = list_nth_node(SubPlanState, - node->subplans, node->active); - - return ExecSubPlan(activesp, econtext, isNull); -} diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c index 7dbf5aa0663e..47c6ca8f7ac8 100644 --- a/src/backend/executor/nodeSubqueryscan.c +++ b/src/backend/executor/nodeSubqueryscan.c @@ -9,7 +9,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeTableFuncscan.c b/src/backend/executor/nodeTableFuncscan.c index 06437a469148..4d7eca4acedf 100644 --- a/src/backend/executor/nodeTableFuncscan.c +++ b/src/backend/executor/nodeTableFuncscan.c @@ -3,7 +3,7 @@ * nodeTableFuncscan.c * Support routines for scanning RangeTableFunc (XMLTABLE like functions). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeTidrangescan.c b/src/backend/executor/nodeTidrangescan.c new file mode 100644 index 000000000000..2b0d205d7dda --- /dev/null +++ b/src/backend/executor/nodeTidrangescan.c @@ -0,0 +1,413 @@ +/*------------------------------------------------------------------------- + * + * nodeTidrangescan.c + * Routines to support TID range scans of relations + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/executor/nodeTidrangescan.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/relscan.h" +#include "access/sysattr.h" +#include "access/tableam.h" +#include "catalog/pg_operator.h" +#include "executor/execdebug.h" +#include "executor/nodeTidrangescan.h" +#include "nodes/nodeFuncs.h" +#include "storage/bufmgr.h" +#include "utils/rel.h" + + +#define IsCTIDVar(node) \ + ((node) != NULL && \ + IsA((node), Var) && \ + ((Var *) (node))->varattno == SelfItemPointerAttributeNumber && \ + ((Var *) (node))->varlevelsup == 0) + +typedef enum +{ + TIDEXPR_UPPER_BOUND, + TIDEXPR_LOWER_BOUND +} TidExprType; + +/* Upper or lower range bound for scan */ +typedef struct TidOpExpr +{ + TidExprType exprtype; /* type of op; lower or upper */ + ExprState *exprstate; /* ExprState for a TID-yielding subexpr */ + bool inclusive; /* whether op is inclusive */ +} TidOpExpr; + +/* + * For the given 'expr', build and return an appropriate TidOpExpr taking into + * account the expr's operator and operand order. + */ +static TidOpExpr * +MakeTidOpExpr(OpExpr *expr, TidRangeScanState *tidstate) +{ + Node *arg1 = get_leftop((Expr *) expr); + Node *arg2 = get_rightop((Expr *) expr); + ExprState *exprstate = NULL; + bool invert = false; + TidOpExpr *tidopexpr; + + if (IsCTIDVar(arg1)) + exprstate = ExecInitExpr((Expr *) arg2, &tidstate->ss.ps); + else if (IsCTIDVar(arg2)) + { + exprstate = ExecInitExpr((Expr *) arg1, &tidstate->ss.ps); + invert = true; + } + else + elog(ERROR, "could not identify CTID variable"); + + tidopexpr = (TidOpExpr *) palloc(sizeof(TidOpExpr)); + tidopexpr->inclusive = false; /* for now */ + + switch (expr->opno) + { + case TIDLessEqOperator: + tidopexpr->inclusive = true; + /* fall through */ + case TIDLessOperator: + tidopexpr->exprtype = invert ? TIDEXPR_LOWER_BOUND : TIDEXPR_UPPER_BOUND; + break; + case TIDGreaterEqOperator: + tidopexpr->inclusive = true; + /* fall through */ + case TIDGreaterOperator: + tidopexpr->exprtype = invert ? TIDEXPR_UPPER_BOUND : TIDEXPR_LOWER_BOUND; + break; + default: + elog(ERROR, "could not identify CTID operator"); + } + + tidopexpr->exprstate = exprstate; + + return tidopexpr; +} + +/* + * Extract the qual subexpressions that yield TIDs to search for, + * and compile them into ExprStates if they're ordinary expressions. + */ +static void +TidExprListCreate(TidRangeScanState *tidrangestate) +{ + TidRangeScan *node = (TidRangeScan *) tidrangestate->ss.ps.plan; + List *tidexprs = NIL; + ListCell *l; + + foreach(l, node->tidrangequals) + { + OpExpr *opexpr = lfirst(l); + TidOpExpr *tidopexpr; + + if (!IsA(opexpr, OpExpr)) + elog(ERROR, "could not identify CTID expression"); + + tidopexpr = MakeTidOpExpr(opexpr, tidrangestate); + tidexprs = lappend(tidexprs, tidopexpr); + } + + tidrangestate->trss_tidexprs = tidexprs; +} + +/* ---------------------------------------------------------------- + * TidRangeEval + * + * Compute and set node's block and offset range to scan by evaluating + * the trss_tidexprs. Returns false if we detect the range cannot + * contain any tuples. Returns true if it's possible for the range to + * contain tuples. + * ---------------------------------------------------------------- + */ +static bool +TidRangeEval(TidRangeScanState *node) +{ + ExprContext *econtext = node->ss.ps.ps_ExprContext; + ItemPointerData lowerBound; + ItemPointerData upperBound; + ListCell *l; + + /* + * Set the upper and lower bounds to the absolute limits of the range of + * the ItemPointer type. Below we'll try to narrow this range on either + * side by looking at the TidOpExprs. + */ + ItemPointerSet(&lowerBound, 0, 0); + ItemPointerSet(&upperBound, InvalidBlockNumber, PG_UINT16_MAX); + + foreach(l, node->trss_tidexprs) + { + TidOpExpr *tidopexpr = (TidOpExpr *) lfirst(l); + ItemPointer itemptr; + bool isNull; + + /* Evaluate this bound. */ + itemptr = (ItemPointer) + DatumGetPointer(ExecEvalExprSwitchContext(tidopexpr->exprstate, + econtext, + &isNull)); + + /* If the bound is NULL, *nothing* matches the qual. */ + if (isNull) + return false; + + if (tidopexpr->exprtype == TIDEXPR_LOWER_BOUND) + { + ItemPointerData lb; + + ItemPointerCopy(itemptr, &lb); + + /* + * Normalize non-inclusive ranges to become inclusive. The + * resulting ItemPointer here may not be a valid item pointer. + */ + if (!tidopexpr->inclusive) + ItemPointerInc(&lb); + + /* Check if we can narrow the range using this qual */ + if (ItemPointerCompare(&lb, &lowerBound) > 0) + ItemPointerCopy(&lb, &lowerBound); + } + + else if (tidopexpr->exprtype == TIDEXPR_UPPER_BOUND) + { + ItemPointerData ub; + + ItemPointerCopy(itemptr, &ub); + + /* + * Normalize non-inclusive ranges to become inclusive. The + * resulting ItemPointer here may not be a valid item pointer. + */ + if (!tidopexpr->inclusive) + ItemPointerDec(&ub); + + /* Check if we can narrow the range using this qual */ + if (ItemPointerCompare(&ub, &upperBound) < 0) + ItemPointerCopy(&ub, &upperBound); + } + } + + ItemPointerCopy(&lowerBound, &node->trss_mintid); + ItemPointerCopy(&upperBound, &node->trss_maxtid); + + return true; +} + +/* ---------------------------------------------------------------- + * TidRangeNext + * + * Retrieve a tuple from the TidRangeScan node's currentRelation + * using the TIDs in the TidRangeScanState information. + * + * ---------------------------------------------------------------- + */ +static TupleTableSlot * +TidRangeNext(TidRangeScanState *node) +{ + TableScanDesc scandesc; + EState *estate; + ScanDirection direction; + TupleTableSlot *slot; + + /* + * extract necessary information from TID scan node + */ + scandesc = node->ss.ss_currentScanDesc; + estate = node->ss.ps.state; + slot = node->ss.ss_ScanTupleSlot; + direction = estate->es_direction; + + if (!node->trss_inScan) + { + /* First time through, compute TID range to scan */ + if (!TidRangeEval(node)) + return NULL; + + if (scandesc == NULL) + { + scandesc = table_beginscan_tidrange(node->ss.ss_currentRelation, + estate->es_snapshot, + &node->trss_mintid, + &node->trss_maxtid); + node->ss.ss_currentScanDesc = scandesc; + } + else + { + /* rescan with the updated TID range */ + table_rescan_tidrange(scandesc, &node->trss_mintid, + &node->trss_maxtid); + } + + node->trss_inScan = true; + } + + /* Fetch the next tuple. */ + if (!table_scan_getnextslot_tidrange(scandesc, direction, slot)) + { + node->trss_inScan = false; + ExecClearTuple(slot); + } + + return slot; +} + +/* + * TidRangeRecheck -- access method routine to recheck a tuple in EvalPlanQual + */ +static bool +TidRangeRecheck(TidRangeScanState *node, TupleTableSlot *slot) +{ + return true; +} + +/* ---------------------------------------------------------------- + * ExecTidRangeScan(node) + * + * Scans the relation using tids and returns the next qualifying tuple. + * We call the ExecScan() routine and pass it the appropriate + * access method functions. + * + * Conditions: + * -- the "cursor" maintained by the AMI is positioned at the tuple + * returned previously. + * + * Initial States: + * -- the relation indicated is opened for TID range scanning. + * ---------------------------------------------------------------- + */ +static TupleTableSlot * +ExecTidRangeScan(PlanState *pstate) +{ + TidRangeScanState *node = castNode(TidRangeScanState, pstate); + + return ExecScan(&node->ss, + (ExecScanAccessMtd) TidRangeNext, + (ExecScanRecheckMtd) TidRangeRecheck); +} + +/* ---------------------------------------------------------------- + * ExecReScanTidRangeScan(node) + * ---------------------------------------------------------------- + */ +void +ExecReScanTidRangeScan(TidRangeScanState *node) +{ + /* mark scan as not in progress, and tid range list as not computed yet */ + node->trss_inScan = false; + + /* + * We must wait until TidRangeNext before calling table_rescan_tidrange. + */ + ExecScanReScan(&node->ss); +} + +/* ---------------------------------------------------------------- + * ExecEndTidRangeScan + * + * Releases any storage allocated through C routines. + * Returns nothing. + * ---------------------------------------------------------------- + */ +void +ExecEndTidRangeScan(TidRangeScanState *node) +{ + TableScanDesc scan = node->ss.ss_currentScanDesc; + + if (scan != NULL) + table_endscan(scan); + + /* + * Free the exprcontext + */ + ExecFreeExprContext(&node->ss.ps); + + /* + * clear out tuple table slots + */ + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + ExecClearTuple(node->ss.ss_ScanTupleSlot); +} + +/* ---------------------------------------------------------------- + * ExecInitTidRangeScan + * + * Initializes the tid range scan's state information, creates + * scan keys, and opens the scan relation. + * + * Parameters: + * node: TidRangeScan node produced by the planner. + * estate: the execution state initialized in InitPlan. + * ---------------------------------------------------------------- + */ +TidRangeScanState * +ExecInitTidRangeScan(TidRangeScan *node, EState *estate, int eflags) +{ + TidRangeScanState *tidrangestate; + Relation currentRelation; + + /* + * create state structure + */ + tidrangestate = makeNode(TidRangeScanState); + tidrangestate->ss.ps.plan = (Plan *) node; + tidrangestate->ss.ps.state = estate; + tidrangestate->ss.ps.ExecProcNode = ExecTidRangeScan; + + /* + * Miscellaneous initialization + * + * create expression context for node + */ + ExecAssignExprContext(estate, &tidrangestate->ss.ps); + + /* + * mark scan as not in progress, and TID range as not computed yet + */ + tidrangestate->trss_inScan = false; + + /* + * open the scan relation + */ + currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); + + tidrangestate->ss.ss_currentRelation = currentRelation; + tidrangestate->ss.ss_currentScanDesc = NULL; /* no table scan here */ + + /* + * get the scan type from the relation descriptor. + */ + ExecInitScanTupleSlot(estate, &tidrangestate->ss, + RelationGetDescr(currentRelation), + table_slot_callbacks(currentRelation)); + + /* + * Initialize result type and projection. + */ + ExecInitResultTypeTL(&tidrangestate->ss.ps); + ExecAssignScanProjectionInfo(&tidrangestate->ss); + + /* + * initialize child expressions + */ + tidrangestate->ss.ps.qual = + ExecInitQual(node->scan.plan.qual, (PlanState *) tidrangestate); + + TidExprListCreate(tidrangestate); + + /* + * all done. + */ + return tidrangestate; +} diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c index 3aaf3a90fd3f..a5b27aecf546 100644 --- a/src/backend/executor/nodeTidscan.c +++ b/src/backend/executor/nodeTidscan.c @@ -3,7 +3,7 @@ * nodeTidscan.c * Routines to support direct tid scans of relations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c index 79e60d37aa5f..d8ff45abaf20 100644 --- a/src/backend/executor/nodeUnique.c +++ b/src/backend/executor/nodeUnique.c @@ -11,7 +11,7 @@ * (It's debatable whether the savings justifies carrying two plan node * types, though.) * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeValuesscan.c b/src/backend/executor/nodeValuesscan.c index 1090b3602570..350821c23bb4 100644 --- a/src/backend/executor/nodeValuesscan.c +++ b/src/backend/executor/nodeValuesscan.c @@ -6,7 +6,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index af68ee07e8ce..6a626f1de771 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -23,7 +23,7 @@ * aggregate function over all rows in the current row's window frame. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -2801,11 +2801,6 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) perfuncstate->wfuncstate = wfuncstate; perfuncstate->wfunc = wfunc; perfuncstate->numArguments = list_length(wfuncstate->args); - - fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo, - econtext->ecxt_per_query_memory); - fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo); - perfuncstate->winCollation = wfunc->inputcollid; get_typlenbyval(wfunc->wintype, @@ -2834,6 +2829,11 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) winobj->argstates = wfuncstate->args; winobj->localmem = NULL; perfuncstate->winobj = winobj; + + /* It's a real window function, so set up to call it. */ + fmgr_info_cxt(wfunc->winfnoid, &perfuncstate->flinfo, + econtext->ecxt_per_query_memory); + fmgr_info_set_expr((Node *) wfunc, &perfuncstate->flinfo); } } diff --git a/src/backend/executor/nodeWorktablescan.c b/src/backend/executor/nodeWorktablescan.c index f8291357d288..c179e213836e 100644 --- a/src/backend/executor/nodeWorktablescan.c +++ b/src/backend/executor/nodeWorktablescan.c @@ -3,7 +3,7 @@ * nodeWorktablescan.c * routines to handle WorkTableScan nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index d1be9410f086..5402a9e8b393 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -3,7 +3,7 @@ * spi.c * Server Programming Interface * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -64,6 +64,12 @@ static _SPI_connection *_SPI_current = NULL; static int _SPI_stack_depth = 0; /* allocated size of _SPI_stack */ static int _SPI_connected = -1; /* current stack index */ +typedef struct SPICallbackArg +{ + const char *query; + RawParseMode mode; +} SPICallbackArg; + static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, ParamListInfo paramLI, bool read_only); @@ -73,8 +79,10 @@ static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan); static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, - bool read_only, bool fire_triggers, uint64 tcount, - DestReceiver *caller_dest); + bool read_only, bool allow_nonatomic, + bool fire_triggers, uint64 tcount, + DestReceiver *caller_dest, + ResourceOwner plan_owner); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, Datum *Values, const char *Nulls); @@ -273,12 +281,8 @@ _SPI_commit(bool chain) /* Start the actual commit */ _SPI_current->internal_xact = true; - /* - * Before committing, pop all active snapshots to avoid error about - * "snapshot %p still active". - */ - while (ActiveSnapshotSet()) - PopActiveSnapshot(); + /* Release snapshots associated with portals */ + ForgetPortalSnapshots(); if (chain) SaveTransactionCharacteristics(); @@ -335,6 +339,9 @@ _SPI_rollback(bool chain) /* Start the actual rollback */ _SPI_current->internal_xact = true; + /* Release snapshots associated with portals */ + ForgetPortalSnapshots(); + if (chain) SaveTransactionCharacteristics(); @@ -529,13 +536,16 @@ SPI_execute(const char *src, bool read_only, int64 tcount) memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; + plan.parse_mode = RAW_PARSE_DEFAULT; plan.cursor_options = CURSOR_OPT_PARALLEL_OK; _SPI_prepare_oneshot_plan(src, &plan); res = _SPI_execute_plan(&plan, NULL, InvalidSnapshot, InvalidSnapshot, - read_only, true, tcount, NULL); + read_only, false, + true, tcount, + NULL, NULL); _SPI_end_call(true); return res; @@ -548,6 +558,43 @@ SPI_exec(const char *src, int64 tcount) return SPI_execute(src, false, tcount); } +/* Parse, plan, and execute a query string, with extensible options */ +int +SPI_execute_extended(const char *src, + const SPIExecuteOptions *options) +{ + int res; + _SPI_plan plan; + + if (src == NULL || options == NULL) + return SPI_ERROR_ARGUMENT; + + res = _SPI_begin_call(true); + if (res < 0) + return res; + + memset(&plan, 0, sizeof(_SPI_plan)); + plan.magic = _SPI_PLAN_MAGIC; + plan.parse_mode = RAW_PARSE_DEFAULT; + plan.cursor_options = CURSOR_OPT_PARALLEL_OK; + if (options->params) + { + plan.parserSetup = options->params->parserSetup; + plan.parserSetupArg = options->params->parserSetupArg; + } + + _SPI_prepare_oneshot_plan(src, &plan); + + res = _SPI_execute_plan(&plan, options->params, + InvalidSnapshot, InvalidSnapshot, + options->read_only, options->allow_nonatomic, + true, options->tcount, + options->dest, options->owner); + + _SPI_end_call(true); + return res; +} + /* Execute a previously prepared plan */ int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, @@ -569,7 +616,9 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, _SPI_convert_params(plan->nargs, plan->argtypes, Values, Nulls), InvalidSnapshot, InvalidSnapshot, - read_only, true, tcount, NULL); + read_only, false, + true, tcount, + NULL, NULL); _SPI_end_call(true); return res; @@ -584,37 +633,32 @@ SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, int64 tcount) /* Execute a previously prepared plan */ int -SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, - bool read_only, long tcount) +SPI_execute_plan_extended(SPIPlanPtr plan, + const SPIExecuteOptions *options) { int res; - if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || tcount < 0) + if (plan == NULL || plan->magic != _SPI_PLAN_MAGIC || options == NULL) return SPI_ERROR_ARGUMENT; res = _SPI_begin_call(true); if (res < 0) return res; - res = _SPI_execute_plan(plan, params, + res = _SPI_execute_plan(plan, options->params, InvalidSnapshot, InvalidSnapshot, - read_only, true, tcount, NULL); + options->read_only, options->allow_nonatomic, + true, options->tcount, + options->dest, options->owner); _SPI_end_call(true); return res; } -/* - * Execute a previously prepared plan. If dest isn't NULL, we send result - * tuples to the caller-supplied DestReceiver rather than through the usual - * SPI output arrangements. If dest is NULL this is equivalent to - * SPI_execute_plan_with_paramlist. - */ +/* Execute a previously prepared plan */ int -SPI_execute_plan_with_receiver(SPIPlanPtr plan, - ParamListInfo params, - bool read_only, long tcount, - DestReceiver *dest) +SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params, + bool read_only, long tcount) { int res; @@ -627,7 +671,9 @@ SPI_execute_plan_with_receiver(SPIPlanPtr plan, res = _SPI_execute_plan(plan, params, InvalidSnapshot, InvalidSnapshot, - read_only, true, tcount, dest); + read_only, false, + true, tcount, + NULL, NULL); _SPI_end_call(true); return res; @@ -668,7 +714,9 @@ SPI_execute_snapshot(SPIPlanPtr plan, _SPI_convert_params(plan->nargs, plan->argtypes, Values, Nulls), snapshot, crosscheck_snapshot, - read_only, fire_triggers, tcount, NULL); + read_only, false, + fire_triggers, tcount, + NULL, NULL); _SPI_end_call(true); return res; @@ -702,6 +750,7 @@ SPI_execute_with_args(const char *src, memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; + plan.parse_mode = RAW_PARSE_DEFAULT; plan.cursor_options = CURSOR_OPT_PARALLEL_OK; plan.nargs = nargs; plan.argtypes = argtypes; @@ -724,50 +773,9 @@ SPI_execute_with_args(const char *src, res = _SPI_execute_plan(&plan, paramLI, InvalidSnapshot, InvalidSnapshot, - read_only, true, tcount, NULL); - - _SPI_end_call(true); - return res; -} - -/* - * SPI_execute_with_receiver -- plan and execute a query with arguments - * - * This is the same as SPI_execute_with_args except that parameters are - * supplied through a ParamListInfo, and (if dest isn't NULL) we send - * result tuples to the caller-supplied DestReceiver rather than through - * the usual SPI output arrangements. - */ -int -SPI_execute_with_receiver(const char *src, - ParamListInfo params, - bool read_only, long tcount, - DestReceiver *dest) -{ - int res; - _SPI_plan plan; - - if (src == NULL || tcount < 0) - return SPI_ERROR_ARGUMENT; - - res = _SPI_begin_call(true); - if (res < 0) - return res; - - memset(&plan, 0, sizeof(_SPI_plan)); - plan.magic = _SPI_PLAN_MAGIC; - plan.cursor_options = CURSOR_OPT_PARALLEL_OK; - if (params) - { - plan.parserSetup = params->parserSetup; - plan.parserSetupArg = params->parserSetupArg; - } - - _SPI_prepare_oneshot_plan(src, &plan); - - res = _SPI_execute_plan(&plan, params, - InvalidSnapshot, InvalidSnapshot, - read_only, true, tcount, dest); + read_only, false, + true, tcount, + NULL, NULL); _SPI_end_call(true); return res; @@ -798,6 +806,7 @@ SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes, memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; + plan.parse_mode = RAW_PARSE_DEFAULT; plan.cursor_options = cursorOptions; plan.nargs = nargs; plan.argtypes = argtypes; @@ -814,6 +823,42 @@ SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes, return result; } +SPIPlanPtr +SPI_prepare_extended(const char *src, + const SPIPrepareOptions *options) +{ + _SPI_plan plan; + SPIPlanPtr result; + + if (src == NULL || options == NULL) + { + SPI_result = SPI_ERROR_ARGUMENT; + return NULL; + } + + SPI_result = _SPI_begin_call(true); + if (SPI_result < 0) + return NULL; + + memset(&plan, 0, sizeof(_SPI_plan)); + plan.magic = _SPI_PLAN_MAGIC; + plan.parse_mode = options->parseMode; + plan.cursor_options = options->cursorOptions; + plan.nargs = 0; + plan.argtypes = NULL; + plan.parserSetup = options->parserSetup; + plan.parserSetupArg = options->parserSetupArg; + + _SPI_prepare_plan(src, &plan); + + /* copy plan to procedure context */ + result = _SPI_make_plan_non_temp(&plan); + + _SPI_end_call(true); + + return result; +} + SPIPlanPtr SPI_prepare_params(const char *src, ParserSetupHook parserSetup, @@ -835,6 +880,7 @@ SPI_prepare_params(const char *src, memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; + plan.parse_mode = RAW_PARSE_DEFAULT; plan.cursor_options = cursorOptions; plan.nargs = 0; plan.argtypes = NULL; @@ -1370,6 +1416,7 @@ SPI_cursor_open_with_args(const char *name, memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; + plan.parse_mode = RAW_PARSE_DEFAULT; plan.cursor_options = cursorOptions; plan.nargs = nargs; plan.argtypes = argtypes; @@ -1415,42 +1462,38 @@ SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, return SPI_cursor_open_internal(name, plan, params, read_only); } -/* - * SPI_cursor_parse_open_with_paramlist() - * - * Same as SPI_cursor_open_with_args except that parameters (if any) are passed - * as a ParamListInfo, which supports dynamic parameter set determination - */ +/* Parse a query and open it as a cursor */ Portal -SPI_cursor_parse_open_with_paramlist(const char *name, - const char *src, - ParamListInfo params, - bool read_only, int cursorOptions) +SPI_cursor_parse_open(const char *name, + const char *src, + const SPIParseOpenOptions *options) { Portal result; _SPI_plan plan; - if (src == NULL) - elog(ERROR, "SPI_cursor_parse_open_with_paramlist called with invalid arguments"); + if (src == NULL || options == NULL) + elog(ERROR, "SPI_cursor_parse_open called with invalid arguments"); SPI_result = _SPI_begin_call(true); if (SPI_result < 0) - elog(ERROR, "SPI_cursor_parse_open_with_paramlist called while not connected"); + elog(ERROR, "SPI_cursor_parse_open called while not connected"); memset(&plan, 0, sizeof(_SPI_plan)); plan.magic = _SPI_PLAN_MAGIC; - plan.cursor_options = cursorOptions; - if (params) + plan.parse_mode = RAW_PARSE_DEFAULT; + plan.cursor_options = options->cursorOptions; + if (options->params) { - plan.parserSetup = params->parserSetup; - plan.parserSetupArg = params->parserSetupArg; + plan.parserSetup = options->params->parserSetup; + plan.parserSetupArg = options->params->parserSetupArg; } _SPI_prepare_plan(src, &plan); /* We needn't copy the plan; SPI_cursor_open_internal will do so */ - result = SPI_cursor_open_internal(name, &plan, params, read_only); + result = SPI_cursor_open_internal(name, &plan, + options->params, options->read_only); /* And clean up */ _SPI_end_call(true); @@ -1476,6 +1519,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, Snapshot snapshot; MemoryContext oldcontext; Portal portal; + SPICallbackArg spicallbackarg; ErrorContextCallback spierrcontext; /* @@ -1530,8 +1574,10 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, * Setup error traceback support for ereport(), in case GetCachedPlan * throws an error. */ + spicallbackarg.query = plansource->query_string; + spicallbackarg.mode = plan->parse_mode; spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = unconstify(char *, plansource->query_string); + spierrcontext.arg = &spicallbackarg; spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; @@ -1542,7 +1588,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, */ /* Replan if needed, and increment plan refcount for portal */ - cplan = GetCachedPlan(plansource, paramLI, false, _SPI_current->queryEnv, NULL); + cplan = GetCachedPlan(plansource, paramLI, NULL, _SPI_current->queryEnv, NULL); stmt_list = cplan->stmt_list; /* GPDB: Mark all queries as SPI inner queries for extension usage */ @@ -1564,7 +1610,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, oldcontext = MemoryContextSwitchTo(portal->portalContext); stmt_list = copyObject(stmt_list); MemoryContextSwitchTo(oldcontext); - ReleaseCachedPlan(cplan, false); + ReleaseCachedPlan(cplan, NULL); cplan = NULL; /* portal shouldn't depend on cplan */ } @@ -1962,7 +2008,10 @@ SPI_plan_get_plan_sources(SPIPlanPtr plan) /* * SPI_plan_get_cached_plan --- get a SPI plan's generic CachedPlan, * if the SPI plan contains exactly one CachedPlanSource. If not, - * return NULL. Caller is responsible for doing ReleaseCachedPlan(). + * return NULL. + * + * The plan's refcount is incremented (and logged in CurrentResourceOwner, + * if it's a saved plan). Caller is responsible for doing ReleaseCachedPlan. * * This is exported so that PL/pgSQL can use it (this beats letting PL/pgSQL * look directly into the SPIPlan for itself). It's not documented in @@ -1973,6 +2022,7 @@ SPI_plan_get_cached_plan(SPIPlanPtr plan) { CachedPlanSource *plansource; CachedPlan *cplan; + SPICallbackArg spicallbackarg; ErrorContextCallback spierrcontext; Assert(plan->magic == _SPI_PLAN_MAGIC); @@ -1987,13 +2037,16 @@ SPI_plan_get_cached_plan(SPIPlanPtr plan) plansource = (CachedPlanSource *) linitial(plan->plancache_list); /* Setup error traceback support for ereport() */ + spicallbackarg.query = plansource->query_string; + spicallbackarg.mode = plan->parse_mode; spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = unconstify(char *, plansource->query_string); + spierrcontext.arg = &spicallbackarg; spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; /* Get the generic plan for the query */ - cplan = GetCachedPlan(plansource, NULL, plan->saved, + cplan = GetCachedPlan(plansource, NULL, + plan->saved ? CurrentResourceOwner : NULL, _SPI_current->queryEnv, NULL); Assert(cplan == plansource->gplan); @@ -2107,7 +2160,8 @@ spi_printtup(TupleTableSlot *slot, DestReceiver *self) * Parse and analyze a querystring. * * At entry, plan->argtypes and plan->nargs (or alternatively plan->parserSetup - * and plan->parserSetupArg) must be valid, as must plan->cursor_options. + * and plan->parserSetupArg) must be valid, as must plan->parse_mode and + * plan->cursor_options. * * Results are stored into *plan (specifically, plan->plancache_list). * Note that the result data is all in CurrentMemoryContext or child contexts @@ -2121,20 +2175,23 @@ _SPI_prepare_plan(const char *src, SPIPlanPtr plan) List *raw_parsetree_list; List *plancache_list; ListCell *list_item; + SPICallbackArg spicallbackarg; ErrorContextCallback spierrcontext; /* * Setup error traceback support for ereport() */ + spicallbackarg.query = src; + spicallbackarg.mode = plan->parse_mode; spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = unconstify(char *, src); + spierrcontext.arg = &spicallbackarg; spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; /* * Parse the request string into a list of raw parse trees. */ - raw_parsetree_list = pg_parse_query(src); + raw_parsetree_list = raw_parser(src, plan->parse_mode); /* * Do parse analysis and rule rewrite for each raw parsetree, storing the @@ -2242,20 +2299,23 @@ _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan) List *raw_parsetree_list; List *plancache_list; ListCell *list_item; + SPICallbackArg spicallbackarg; ErrorContextCallback spierrcontext; /* * Setup error traceback support for ereport() */ + spicallbackarg.query = src; + spicallbackarg.mode = plan->parse_mode; spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = unconstify(char *, src); + spierrcontext.arg = &spicallbackarg; spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; /* * Parse the request string into a list of raw parse trees. */ - raw_parsetree_list = pg_parse_query(src); + raw_parsetree_list = raw_parser(src, plan->parse_mode); /* * Construct plancache entries, but don't do parse analysis yet. @@ -2290,22 +2350,27 @@ _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan) * behavior of taking a new snapshot for each query. * crosscheck_snapshot: for RI use, all others pass InvalidSnapshot * read_only: true for read-only execution (no CommandCounterIncrement) + * allow_nonatomic: true to allow nonatomic CALL/DO execution * fire_triggers: true to fire AFTER triggers at end of query (normal case); * false means any AFTER triggers are postponed to end of outer query * tcount: execution tuple-count limit, or 0 for none * caller_dest: DestReceiver to receive output, or NULL for normal SPI output + * plan_owner: ResourceOwner that will be used to hold refcount on plan; + * if NULL, CurrentResourceOwner is used (ignored for non-saved plan) */ static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, Snapshot snapshot, Snapshot crosscheck_snapshot, - bool read_only, bool fire_triggers, uint64 tcount, - DestReceiver *caller_dest) + bool read_only, bool allow_nonatomic, + bool fire_triggers, uint64 tcount, + DestReceiver *caller_dest, ResourceOwner plan_owner) { int my_res = 0; uint64 my_processed = 0; SPITupleTable *my_tuptable = NULL; int res = 0; bool pushed_active_snap = false; + SPICallbackArg spicallbackarg; ErrorContextCallback spierrcontext; CachedPlan *cplan = NULL; ListCell *lc1; @@ -2313,8 +2378,10 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* * Setup error traceback support for ereport() */ + spicallbackarg.query = NULL; /* we'll fill this below */ + spicallbackarg.mode = plan->parse_mode; spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = NULL; /* we'll fill this below */ + spierrcontext.arg = &spicallbackarg; spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; @@ -2337,11 +2404,12 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, * In the first two cases, we can just push the snap onto the stack once * for the whole plan list. * - * But if the plan has no_snapshots set to true, then don't manage - * snapshots at all. The caller should then take care of that. + * Note that snapshot != InvalidSnapshot implies an atomic execution + * context. */ - if (snapshot != InvalidSnapshot && !plan->no_snapshots) + if (snapshot != InvalidSnapshot) { + Assert(!allow_nonatomic); if (read_only) { PushActiveSnapshot(snapshot); @@ -2355,13 +2423,22 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, } } + /* + * Ensure that we have a resource owner if plan is saved, and not if it + * isn't. + */ + if (!plan->saved) + plan_owner = NULL; + else if (plan_owner == NULL) + plan_owner = CurrentResourceOwner; + foreach(lc1, plan->plancache_list) { CachedPlanSource *plansource = (CachedPlanSource *) lfirst(lc1); List *stmt_list; ListCell *lc2; - spierrcontext.arg = unconstify(char *, plansource->query_string); + spicallbackarg.query = plansource->query_string; /* * If this is a one-shot plan, we still need to do parse analysis. @@ -2424,21 +2501,47 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* * Replan if needed, and increment plan refcount. If it's a saved - * plan, the refcount must be backed by the CurrentResourceOwner. + * plan, the refcount must be backed by the plan_owner. */ - cplan = GetCachedPlan(plansource, paramLI, plan->saved, _SPI_current->queryEnv, NULL); + cplan = GetCachedPlan(plansource, paramLI, + plan_owner, _SPI_current->queryEnv, NULL); + stmt_list = cplan->stmt_list; /* - * In the default non-read-only case, get a new snapshot, replacing - * any that we pushed in a previous cycle. + * If we weren't given a specific snapshot to use, and the statement + * list requires a snapshot, set that up. */ - if (snapshot == InvalidSnapshot && !read_only && !plan->no_snapshots) + if (snapshot == InvalidSnapshot && + (list_length(stmt_list) > 1 || + (list_length(stmt_list) == 1 && + PlannedStmtRequiresSnapshot(linitial_node(PlannedStmt, + stmt_list))))) { - if (pushed_active_snap) - PopActiveSnapshot(); - PushActiveSnapshot(GetTransactionSnapshot()); - pushed_active_snap = true; + /* + * First, ensure there's a Portal-level snapshot. This back-fills + * the snapshot stack in case the previous operation was a COMMIT + * or ROLLBACK inside a procedure or DO block. (We can't put back + * the Portal snapshot any sooner, or we'd break cases like doing + * SET or LOCK just after COMMIT.) It's enough to check once per + * statement list, since COMMIT/ROLLBACK/CALL/DO can't appear + * within a multi-statement list. + */ + EnsurePortalSnapshotExists(); + + /* + * In the default non-read-only case, get a new per-statement-list + * snapshot, replacing any that we pushed in a previous cycle. + * Skip it when doing non-atomic execution, though (we rely + * entirely on the Portal snapshot in that case). + */ + if (!read_only && !allow_nonatomic) + { + if (pushed_active_snap) + PopActiveSnapshot(); + PushActiveSnapshot(GetTransactionSnapshot()); + pushed_active_snap = true; + } } foreach(lc2, stmt_list) @@ -2459,6 +2562,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* GPDB: Mark all queries as SPI inner query for extension usage */ stmt->metricsQueryType = SPI_INNER_QUERY; + /* Check for unsupported cases. */ if (stmt->utilityStmt) { if (IsA(stmt->utilityStmt, CopyStmt)) @@ -2487,9 +2591,10 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* * If not read-only mode, advance the command counter before each - * command and update the snapshot. + * command and update the snapshot. (But skip it if the snapshot + * isn't under our control.) */ - if (!read_only && !plan->no_snapshots) + if (!read_only && pushed_active_snap) { CommandCounterIncrement(); UpdateActiveSnapshotCommandId(); @@ -2537,13 +2642,11 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, QueryCompletion qc; /* - * If the SPI context is atomic, or we are asked to manage - * snapshots, then we are in an atomic execution context. - * Conversely, to propagate a nonatomic execution context, the - * caller must be in a nonatomic SPI context and manage - * snapshots itself. + * If the SPI context is atomic, or we were not told to allow + * nonatomic operations, tell ProcessUtility this is an atomic + * execution context. */ - if (_SPI_current->atomic || !plan->no_snapshots) + if (_SPI_current->atomic || !allow_nonatomic) context = PROCESS_UTILITY_QUERY; else context = PROCESS_UTILITY_QUERY_NONATOMIC; @@ -2551,6 +2654,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, InitializeQueryCompletion(&qc); ProcessUtility(stmt, plansource->query_string, + true, /* protect plancache's node tree */ context, paramLI, _SPI_current->queryEnv, @@ -2630,7 +2734,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, } /* Done with this plan, so release refcount */ - ReleaseCachedPlan(cplan, plan->saved); + ReleaseCachedPlan(cplan, plan_owner); cplan = NULL; /* @@ -2650,7 +2754,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* We no longer need the cached plan refcount, if any */ if (cplan) - ReleaseCachedPlan(cplan, plan->saved); + ReleaseCachedPlan(cplan, plan_owner); /* * Pop the error context stack @@ -2910,7 +3014,8 @@ _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount) static void _SPI_error_callback(void *arg) { - const char *query = (const char *) arg; + SPICallbackArg *carg = (SPICallbackArg *) arg; + const char *query = carg->query; int syntaxerrposition; if (query == NULL) /* in case arg wasn't set yet */ @@ -2928,7 +3033,23 @@ _SPI_error_callback(void *arg) internalerrquery(query); } else - errcontext("SQL statement \"%s\"", query); + { + /* Use the parse mode to decide how to describe the query */ + switch (carg->mode) + { + case RAW_PARSE_PLPGSQL_EXPR: + errcontext("SQL expression \"%s\"", query); + break; + case RAW_PARSE_PLPGSQL_ASSIGN1: + case RAW_PARSE_PLPGSQL_ASSIGN2: + case RAW_PARSE_PLPGSQL_ASSIGN3: + errcontext("PL/pgSQL assignment \"%s\"", query); + break; + default: + errcontext("SQL statement \"%s\"", query); + break; + } + } } /* @@ -3099,6 +3220,7 @@ _SPI_make_plan_non_temp(SPIPlanPtr plan) newplan = (SPIPlanPtr) palloc0(sizeof(_SPI_plan)); newplan->magic = _SPI_PLAN_MAGIC; newplan->plancxt = plancxt; + newplan->parse_mode = plan->parse_mode; newplan->cursor_options = plan->cursor_options; newplan->nargs = plan->nargs; if (plan->nargs > 0) @@ -3163,6 +3285,7 @@ _SPI_save_plan(SPIPlanPtr plan) newplan = (SPIPlanPtr) palloc0(sizeof(_SPI_plan)); newplan->magic = _SPI_PLAN_MAGIC; newplan->plancxt = plancxt; + newplan->parse_mode = plan->parse_mode; newplan->cursor_options = plan->cursor_options; newplan->nargs = plan->nargs; if (plan->nargs > 0) diff --git a/src/backend/executor/tqueue.c b/src/backend/executor/tqueue.c index 850c5166188b..4bb5f1730c00 100644 --- a/src/backend/executor/tqueue.c +++ b/src/backend/executor/tqueue.c @@ -8,7 +8,7 @@ * * A TupleQueueReader reads tuples from a shm_mq and returns the tuples. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c index 7fd3452ef68d..7211dd2e8bc6 100644 --- a/src/backend/executor/tstoreReceiver.c +++ b/src/backend/executor/tstoreReceiver.c @@ -11,7 +11,7 @@ * Also optionally, we can apply a tuple conversion map before storing. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index 2fb27a7877c8..b8dc873e6251 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -3,7 +3,7 @@ * foreign.c * support for foreign-data wrappers, servers and user mappings. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/foreign/foreign.c @@ -667,7 +667,7 @@ deflist_to_tuplestore(ReturnSetInfo *rsinfo, List *options) nulls[0] = false; if (def->arg) { - values[1] = CStringGetTextDatum(((Value *) (def->arg))->val.str); + values[1] = CStringGetTextDatum(strVal(def->arg)); nulls[1] = false; } else diff --git a/src/backend/fts/fts.c b/src/backend/fts/fts.c index e20eb2d53c74..29e7a2996b6d 100644 --- a/src/backend/fts/fts.c +++ b/src/backend/fts/fts.c @@ -18,6 +18,10 @@ */ #include "postgres.h" +#ifndef USE_INTERNAL_FTS +#define USE_INTERNAL_FTS +#endif + #include /* These are always necessary for a bgworker */ diff --git a/src/backend/fts/ftsmessagehandler.c b/src/backend/fts/ftsmessagehandler.c index b3b42070139c..a8cb9afa4a39 100644 --- a/src/backend/fts/ftsmessagehandler.c +++ b/src/backend/fts/ftsmessagehandler.c @@ -342,7 +342,7 @@ CreateReplicationSlotOnPromote(const char *name) if (MyReplicationSlot == NULL) { ereport(LOG, (errmsg("creating replication slot %s", name))); - ReplicationSlotCreate(name, false, RS_PERSISTENT); + ReplicationSlotCreate(name, false, RS_PERSISTENT, false); } else ereport(LOG, (errmsg("replication slot %s exists", name))); diff --git a/src/backend/fts/test/ftsmessagehandler_test.c b/src/backend/fts/test/ftsmessagehandler_test.c index 5133132e0bcd..95ce90284a2a 100644 --- a/src/backend/fts/test/ftsmessagehandler_test.c +++ b/src/backend/fts/test/ftsmessagehandler_test.c @@ -171,6 +171,7 @@ test_HandleFtsWalRepPromoteMirror(void **state) expect_value(ReplicationSlotCreate, name, INTERNAL_WAL_REPLICATION_SLOT_NAME); expect_value(ReplicationSlotCreate, db_specific, false); expect_value(ReplicationSlotCreate, persistency, RS_PERSISTENT); + expect_value(ReplicationSlotCreate, two_phase, false); will_be_called_with_sideeffect(ReplicationSlotCreate, set_replication_slot, &ReplicationSlotCtl); diff --git a/src/backend/gpopt/gpdbwrappers.cpp b/src/backend/gpopt/gpdbwrappers.cpp index a6ee4403cebb..7de3bd1d8c85 100644 --- a/src/backend/gpopt/gpdbwrappers.cpp +++ b/src/backend/gpopt/gpdbwrappers.cpp @@ -526,17 +526,17 @@ gpdb::IsFuncAllowedForPartitionSelection(Oid funcid) // For range partition selection, the logic in ORCA checks on bounds of the partition ranges. // Hence these must be increasing functions. case F_TIMESTAMP_DATE: // date(timestamp) -> date - case F_DTOI4: // int4(float8) -> int4 - case F_FTOI4: // int4(float4) -> int4 - case F_INT82: // int2(int8) -> int2 - case F_INT84: // int4(int8) -> int4 - case F_I4TOI2: // int2(int4) -> int2 - case F_FTOI8: // int8(float4) -> int8 - case F_FTOI2: // int2(float4) -> int2 - case F_FLOAT4_NUMERIC: // numeric(float4) -> numeric - case F_DTOI8: // int8(float8) -> int8 - case F_DTOI2: // int2(float4) -> int2 - case F_DTOF: // float4(float8) -> float4 + case F_INT4_FLOAT8: // int4(float8) -> int4 + case F_INT4_FLOAT4: // int4(float4) -> int4 + case F_INT2_INT8: // int2(int8) -> int2 + case F_INT4_INT8: // int4(int8) -> int4 + case F_INT2_INT4: // int2(int4) -> int2 + case F_INT8_FLOAT4: // int8(float4) -> int8 + case F_INT2_FLOAT4: // int2(float4) -> int2 + case F_NUMERIC_FLOAT4: // numeric(float4) -> numeric + case F_INT8_FLOAT8: // int8(float8) -> int8 + case F_INT2_FLOAT8: // int2(float4) -> int2 + case F_FLOAT4_FLOAT8: // float4(float8) -> float4 case F_FLOAT8_NUMERIC: // numeric(float8) -> numeric case F_NUMERIC_INT8: // int8(numeric) -> int8 case F_NUMERIC_INT2: // int2(numeric) -> int2 @@ -568,11 +568,11 @@ gpdb::IsFuncNDVPreserving(Oid funcid) switch (funcid) { // for now, these are the functions we consider for this optimization - case F_LOWER: - case F_LTRIM1: - case F_BTRIM1: - case F_RTRIM1: - case F_UPPER: + case F_LOWER_TEXT: + case F_LTRIM_TEXT: + case F_BTRIM_TEXT: + case F_RTRIM_TEXT: + case F_UPPER_TEXT: return true; default: return false; @@ -2581,7 +2581,7 @@ gpdb::GPDBRelationGetPartitionDesc(Relation rel) { GP_WRAP_START; { - return RelationGetPartitionDesc(rel); + return RelationGetPartitionDesc(rel, false); } GP_WRAP_END; } diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp index 679562ee4735..fc2bff5465ea 100644 --- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp +++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp @@ -2760,6 +2760,45 @@ CTranslatorDXLToPlStmt::TranslateDXLAgg( agg->numGroups = std::max(1L, (long) std::min(agg->plan.plan_rows, (double) LONG_MAX)); + + // PG14: the executor reads each aggregate's result from + // aggvalues[aggref->aggno] and its transition state from + // pertrans[aggref->aggtransno]. The Postgres planner assigns these in + // preprocess_aggrefs(), which ORCA plans never pass through; left at + // their MakeNode default of 0, all aggregates in this node would share + // the first one's transition state and result. Number them densely + // here (gaps would leave uninitialized per-agg slots), keeping the + // number of an instance referenced more than once, and not attempting + // upstream's shared-state optimization. + { + List *aggref_list = gpdb::ListConcat( + gpdb::ExtractNodesExpression((Node *) plan->targetlist, T_Aggref, + false /*descendIntoSubqueries*/), + gpdb::ExtractNodesExpression((Node *) plan->qual, T_Aggref, + false /*descendIntoSubqueries*/)); + ListCell *lc_aggref; + int next_aggno = 0; + + foreach (lc_aggref, aggref_list) + { + Aggref *aggref = (Aggref *) lfirst(lc_aggref); + + aggref->aggno = -1; + aggref->aggtransno = -1; + } + foreach (lc_aggref, aggref_list) + { + Aggref *aggref = (Aggref *) lfirst(lc_aggref); + + if (aggref->aggno == -1) + { + aggref->aggno = next_aggno; + aggref->aggtransno = next_aggno; + next_aggno++; + } + } + } + SetParamIds(plan); // cleanup @@ -4342,10 +4381,31 @@ CTranslatorDXLToPlStmt::TranslateDXLDml( nullptr, // translate context for the base table child_contexts, output_context); - // pad child plan's target list with NULLs for dropped columns for all DML operator types - List *target_list_with_dropped_cols = - CreateTargetListWithNullsForDroppedCols(dml_target_list, md_rel); - dml_target_list = target_list_with_dropped_cols; + // PG14 FIXME: a Split Update's insert half writes misaligned values on + // tables with dropped columns (the padded row no longer matches what + // ExecInsert expects), silently corrupting data. Fall back to the + // Postgres planner, which handles it correctly. + if (CMD_UPDATE == m_cmd_type && isSplit && md_rel->HasDroppedColumns()) + { + GPOS_RAISE( + gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion, + GPOS_WSZ_LIT("split UPDATE on a table with dropped columns")); + } + + // Pad the child plan's target list with NULLs for dropped columns. An + // INSERT and a Split Update (delete+insert) need the full physical row. + // A plain UPDATE must NOT be padded: PG14's ExecBuildUpdateProjection() + // pairs each non-junk subplan column with an updateColnosLists entry + // and rejects assignments to dropped columns, so its subplan emits the + // live columns only and the executor nulls the dropped ones itself. + BOOL pad_dropped_cols = !(CMD_UPDATE == m_cmd_type && !isSplit); + List *target_list_with_dropped_cols = dml_target_list; + if (pad_dropped_cols) + { + target_list_with_dropped_cols = + CreateTargetListWithNullsForDroppedCols(dml_target_list, md_rel); + dml_target_list = target_list_with_dropped_cols; + } // Add junk columns to the target list for the 'action', 'ctid', // 'gp_segment_id'. The ModifyTable node will find these based @@ -4388,9 +4448,8 @@ CTranslatorDXLToPlStmt::TranslateDXLDml( dml->canSetTag = true; // FIXME dml->nominalRelation = index; dml->resultRelations = ListMake1Int(index); - dml->resultRelIndex = list_length(m_result_rel_list) - 1; dml->rootRelation = md_rel->IsPartitioned() ? index : 0; - dml->plans = ListMake1(child_plan); + dml->plan.lefttree = child_plan; dml->fdwPrivLists = ListMake1(NIL); @@ -4398,6 +4457,34 @@ CTranslatorDXLToPlStmt::TranslateDXLDml( if (m_cmd_type == CMD_UPDATE) { dml->isSplitUpdates = ListMake1Int((int) isSplit); + + // PG14: ModifyTable uses updateColnosLists to map each non-junk + // column produced by the subplan to its target-table attribute + // number (see ExecInitUpdateProjection / ExecBuildUpdateProjection). + // Unlike the Postgres planner, which emits only the SET columns, + // ORCA emits a full new tuple in physical column order, so the + // mapping is each table column's attribute number -- skipping + // dropped columns when the target list was not padded for them + // (plain update), keeping them when it was (split update; the + // projection is never built there). One entry per result relation. + List *update_colnos = NIL; + const ULONG num_of_rel_cols = md_rel->ColumnCount(); + + for (ULONG ul = 0; ul < num_of_rel_cols; ul++) + { + const IMDColumn *md_col = md_rel->GetMdCol(ul); + + if (md_col->IsSystemColumn()) + { + continue; + } + if (md_col->IsDropped() && !pad_dropped_cols) + { + continue; + } + update_colnos = gpdb::LAppendInt(update_colnos, md_col->AttrNum()); + } + dml->updateColnosLists = ListMake1(update_colnos); } plan->targetlist = NIL; diff --git a/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp b/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp index 5671a18ae7af..4212b0940974 100644 --- a/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp +++ b/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp @@ -2130,6 +2130,12 @@ CTranslatorDXLToScalar::TranslateDXLScalarArrayRefToScalar( CMDIdGPDB::CastMdid(dxlop->ArrayTypeMDid())->Oid(); array_ref->refelemtype = CMDIdGPDB::CastMdid(dxlop->ElementTypeMDid())->Oid(); + // PG14: exprType() of a SubscriptingRef is refrestype; left unset it + // breaks everything above this node with "cache lookup failed for + // type 0". The DXL operator carries the result type computed from the + // original node (element type for a single-element fetch, container + // type for slices and assignments). + array_ref->refrestype = CMDIdGPDB::CastMdid(dxlop->ReturnTypeMDid())->Oid(); // GPDB_91_MERGE_FIXME: collation array_ref->refcollid = gpdb::TypeCollation(array_ref->refelemtype); array_ref->reftypmod = dxlop->TypeModifier(); diff --git a/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp b/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp index ecfb92029227..a45802d35b3f 100644 --- a/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp +++ b/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp @@ -1179,6 +1179,18 @@ CTranslatorQueryToDXL::TranslateDeleteQueryToDXL() &m_context->m_has_distributed_tables); const IMDRelation *md_rel = m_md_accessor->RetrieveRel(table_descr->MDId()); + if (md_rel->IsPartitioned()) + { + // PG14 FIXME: ORCA targets the partition root through a dynamic + // scan and relied on ModifyTable.forceTupleRouting to route each + // tuple to its leaf; the PG14 executor rework dropped that path, + // so the DML would touch the storage-less root ("could not open + // file"). Fall back to the Postgres planner until per-tuple + // routing is reimplemented on the PG14 executor model. + GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiQuery2DXLUnsupportedFeature, + GPOS_WSZ_LIT("DELETE on partitioned tables")); + } + // make note of the operator classes used in the distribution key NoteDistributionPolicyOpclasses(rte); @@ -1239,6 +1251,16 @@ CTranslatorQueryToDXL::TranslateUpdateQueryToDXL() &m_context->m_has_distributed_tables); const IMDRelation *md_rel = m_md_accessor->RetrieveRel(table_descr->MDId()); + if (md_rel->IsPartitioned()) + { + // PG14 FIXME: see TranslateDeleteQueryToDXL; in-place UPDATEs on a + // partition root need per-tuple routing the PG14 executor rework + // dropped (split updates route their INSERT half, but ORCA emits + // in-place plans when the distribution key is unchanged). + GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiQuery2DXLUnsupportedFeature, + GPOS_WSZ_LIT("UPDATE on partitioned tables")); + } + if (!optimizer_enable_dml_constraints && CTranslatorUtils::RelHasConstraints(md_rel)) { diff --git a/src/backend/gpopt/utils/COptTasks.cpp b/src/backend/gpopt/utils/COptTasks.cpp index a8fcd23a98d4..c3af62f9af24 100644 --- a/src/backend/gpopt/utils/COptTasks.cpp +++ b/src/backend/gpopt/utils/COptTasks.cpp @@ -384,7 +384,7 @@ COptTasks::CreateOptimizerConfig(CMemoryPool *mp, ICostModel *cost_model) * enforce them ourselves in the executor */ push_group_by_below_setop_threshold, xform_bind_threshold, skew_factor), - GPOS_NEW(mp) CWindowOids(OID(F_WINDOW_ROW_NUMBER), OID(F_WINDOW_RANK))); + GPOS_NEW(mp) CWindowOids(OID(F_ROW_NUMBER), OID(F_RANK_))); } //--------------------------------------------------------------------------- diff --git a/src/backend/gporca/libgpos/include/gpos/task/CWorker.h b/src/backend/gporca/libgpos/include/gpos/task/CWorker.h index 04a0a950e623..fdf17fef1bc3 100644 --- a/src/backend/gporca/libgpos/include/gpos/task/CWorker.h +++ b/src/backend/gporca/libgpos/include/gpos/task/CWorker.h @@ -35,11 +35,16 @@ class CTask; class CWorker : public IWorker { friend class CAutoTaskProxy; + friend class CWorkerPoolManager; private: // current task CTask *m_task; + // GPDB: worker registered before this one (nested gpos_exec); the + // single-slot pool restores it when this worker unregisters + CWorker *m_previous_worker{nullptr}; + // available stack ULONG m_stack_size; diff --git a/src/backend/gporca/libgpos/include/gpos/task/ITask.h b/src/backend/gporca/libgpos/include/gpos/task/ITask.h index 5302d8d77bd4..134e1b79686e 100644 --- a/src/backend/gporca/libgpos/include/gpos/task/ITask.h +++ b/src/backend/gporca/libgpos/include/gpos/task/ITask.h @@ -16,9 +16,18 @@ #include "gpos/types.h" // trace flag macro definitions -#define GPOS_FTRACE(x) ITask::Self()->IsTraceSet(x) -#define GPOS_SET_TRACE(x) (void) ITask::Self()->SetTrace(x, true /*value*/) -#define GPOS_UNSET_TRACE(x) (void) ITask::Self()->SetTrace(x, false /*value*/) +// GPDB: tolerate execution outside a task (e.g. metadata objects +// constructed from a relcache invalidation callback): no task means no +// trace flags are set. An unguarded Self()->IsTraceSet() here was a hard +// coordinator SIGSEGV (see CMDTypeInt4GPDB's GPOS_FTRACE uses). +#define GPOS_FTRACE(x) \ + (NULL != gpos::ITask::Self() && gpos::ITask::Self()->IsTraceSet(x)) +#define GPOS_SET_TRACE(x) \ + ((void) (NULL != gpos::ITask::Self() && \ + (gpos::ITask::Self()->SetTrace(x, true /*value*/), true))) +#define GPOS_UNSET_TRACE(x) \ + ((void) (NULL != gpos::ITask::Self() && \ + (gpos::ITask::Self()->SetTrace(x, false /*value*/), true))) namespace gpos { diff --git a/src/backend/gporca/libgpos/src/task/CAutoTraceFlag.cpp b/src/backend/gporca/libgpos/src/task/CAutoTraceFlag.cpp index 71d62012ae45..0b03812e94d1 100644 --- a/src/backend/gporca/libgpos/src/task/CAutoTraceFlag.cpp +++ b/src/backend/gporca/libgpos/src/task/CAutoTraceFlag.cpp @@ -28,8 +28,12 @@ using namespace gpos; CAutoTraceFlag::CAutoTraceFlag(ULONG trace, BOOL orig) : m_trace(trace), m_orig(false) { - GPOS_ASSERT(nullptr != ITask::Self()); - m_orig = ITask::Self()->SetTrace(m_trace, orig); + // GPDB: tolerate running without a task; this happens while an + // optimizer-fallback exception unwinds, after the worker has been + // removed from the pool. Dereferencing the NULL task here crashed + // the coordinator (custom partition opclass INSERT path). + if (nullptr != ITask::Self()) + m_orig = ITask::Self()->SetTrace(m_trace, orig); } @@ -43,10 +47,9 @@ CAutoTraceFlag::CAutoTraceFlag(ULONG trace, BOOL orig) //--------------------------------------------------------------------------- CAutoTraceFlag::~CAutoTraceFlag() { - GPOS_ASSERT(nullptr != ITask::Self()); - - // reset original value - ITask::Self()->SetTrace(m_trace, m_orig); + // reset original value; see ctor for the no-task case + if (nullptr != ITask::Self()) + ITask::Self()->SetTrace(m_trace, m_orig); } diff --git a/src/backend/gporca/libgpos/src/task/CWorker.cpp b/src/backend/gporca/libgpos/src/task/CWorker.cpp index 2313c52ea828..a2fc59a82e74 100644 --- a/src/backend/gporca/libgpos/src/task/CWorker.cpp +++ b/src/backend/gporca/libgpos/src/task/CWorker.cpp @@ -36,9 +36,8 @@ CWorker::CWorker(ULONG stack_size, ULONG_PTR stack_start) GPOS_ASSERT(stack_size >= 2 * 1024 && "Worker has to have at least 2KB stack"); - // register worker - GPOS_ASSERT(nullptr == Self() && "Found registered worker!"); - + // register worker; one may already be registered when gpos_exec + // re-enters (see CWorkerPoolManager::RegisterWorker) CWorkerPoolManager::WorkerPoolManager()->RegisterWorker(this); GPOS_ASSERT(this == CWorkerPoolManager::WorkerPoolManager()->Self()); } diff --git a/src/backend/gporca/libgpos/src/task/CWorkerPoolManager.cpp b/src/backend/gporca/libgpos/src/task/CWorkerPoolManager.cpp index 753367e4c56f..6d35ed72fee7 100644 --- a/src/backend/gporca/libgpos/src/task/CWorkerPoolManager.cpp +++ b/src/backend/gporca/libgpos/src/task/CWorkerPoolManager.cpp @@ -139,7 +139,17 @@ void CWorkerPoolManager::RegisterWorker(CWorker *worker) { GPOS_ASSERT(nullptr != worker); - GPOS_ASSERT(nullptr == m_single_worker); + + /* + * GPDB: gpos_exec can re-enter (e.g. retrieving metadata of a SQL + * function used by a partition opclass plans the function body, which + * may invoke the optimizer again). The pool has a single slot, so an + * inner worker used to clobber it, and the inner worker's removal left + * the OUTER task without a worker: ITask::Self() returned NULL + * mid-task and the coordinator crashed on the next trace-flag or + * error-context access. Keep a save/restore chain instead. + */ + worker->m_previous_worker = m_single_worker; m_single_worker = worker; } @@ -155,7 +165,11 @@ CWorkerPoolManager::RegisterWorker(CWorker *worker) void CWorkerPoolManager::RemoveWorker() { - m_single_worker = nullptr; + /* restore the worker of an enclosing gpos_exec, if any */ + if (nullptr != m_single_worker) + m_single_worker = m_single_worker->m_previous_worker; + else + m_single_worker = nullptr; } diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c index 705ae2a17c9a..3dc8b4d88c86 100644 --- a/src/backend/jit/jit.c +++ b/src/backend/jit/jit.c @@ -8,7 +8,7 @@ * should end up here. * * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/jit/jit.c diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index 8b85fd434b99..429de19bf1ae 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -3,7 +3,7 @@ * llvmjit.c * Core part of the LLVM JIT provider. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/jit/llvm/llvmjit.c @@ -367,6 +367,47 @@ llvm_get_function(LLVMJitContext *context, const char *funcname) return NULL; } +/* + * Return type of a variable in llvmjit_types.c. This is useful to keep types + * in sync between plain C and JIT related code. + */ +LLVMTypeRef +llvm_pg_var_type(const char *varname) +{ + LLVMValueRef v_srcvar; + LLVMTypeRef typ; + + /* this'll return a *pointer* to the global */ + v_srcvar = LLVMGetNamedGlobal(llvm_types_module, varname); + if (!v_srcvar) + elog(ERROR, "variable %s not in llvmjit_types.c", varname); + + /* look at the contained type */ + typ = LLVMTypeOf(v_srcvar); + Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMPointerTypeKind); + typ = LLVMGetElementType(typ); + Assert(typ != NULL); + + return typ; +} + +/* + * Return function type of a variable in llvmjit_types.c. This is useful to + * keep function types in sync between C and JITed code. + */ +LLVMTypeRef +llvm_pg_var_func_type(const char *varname) +{ + LLVMTypeRef typ = llvm_pg_var_type(varname); + + /* look at the contained type */ + Assert(LLVMGetTypeKind(typ) == LLVMPointerTypeKind); + typ = LLVMGetElementType(typ); + Assert(typ != NULL && LLVMGetTypeKind(typ) == LLVMFunctionTypeKind); + + return typ; +} + /* * Return declaration for a function referenced in llvmjit_types.c, adding it * to the module if necessary. @@ -727,10 +768,10 @@ llvm_compile_module(LLVMJitContext *context) MemoryContextSwitchTo(oldcontext); ereport(DEBUG1, - (errmsg("time to inline: %.3fs, opt: %.3fs, emit: %.3fs", - INSTR_TIME_GET_DOUBLE(context->base.instr.inlining_counter), - INSTR_TIME_GET_DOUBLE(context->base.instr.optimization_counter), - INSTR_TIME_GET_DOUBLE(context->base.instr.emission_counter)), + (errmsg_internal("time to inline: %.3fs, opt: %.3fs, emit: %.3fs", + INSTR_TIME_GET_DOUBLE(context->base.instr.inlining_counter), + INSTR_TIME_GET_DOUBLE(context->base.instr.optimization_counter), + INSTR_TIME_GET_DOUBLE(context->base.instr.emission_counter)), errhidestmt(true), errhidecontext(true))); } @@ -921,6 +962,49 @@ load_type(LLVMModuleRef mod, const char *name) typ = LLVMGetElementType(typ); Assert(typ != NULL); return typ; +#if LLVM_VERSION_MAJOR > 11 + { + if (llvm_opt3_orc) + { + LLVMOrcDisposeLLJIT(llvm_opt3_orc); + llvm_opt3_orc = NULL; + } + if (llvm_opt0_orc) + { + LLVMOrcDisposeLLJIT(llvm_opt0_orc); + llvm_opt0_orc = NULL; + } + if (llvm_ts_context) + { + LLVMOrcDisposeThreadSafeContext(llvm_ts_context); + llvm_ts_context = NULL; + } + } +#else /* LLVM_VERSION_MAJOR > 11 */ + { + /* unregister profiling support, needs to be flushed to be useful */ + + if (llvm_opt3_orc) + { +#if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF + if (jit_profiling_support) + LLVMOrcUnregisterPerf(llvm_opt3_orc); +#endif + LLVMOrcDisposeInstance(llvm_opt3_orc); + llvm_opt3_orc = NULL; + } + + if (llvm_opt0_orc) + { +#if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF + if (jit_profiling_support) + LLVMOrcUnregisterPerf(llvm_opt0_orc); +#endif + LLVMOrcDisposeInstance(llvm_opt0_orc); + llvm_opt0_orc = NULL; + } + } +#endif /* LLVM_VERSION_MAJOR > 11 */ } /* helper for llvm_create_types, returning a function's return type */ @@ -984,24 +1068,24 @@ llvm_create_types(void) llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module)); llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module)); - TypeSizeT = load_type(llvm_types_module, "TypeSizeT"); + TypeSizeT = llvm_pg_var_type("TypeSizeT"); TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool"); - TypeStorageBool = load_type(llvm_types_module, "TypeStorageBool"); - TypePGFunction = load_type(llvm_types_module, "TypePGFunction"); - StructNullableDatum = load_type(llvm_types_module, "StructNullableDatum"); - StructExprContext = load_type(llvm_types_module, "StructExprContext"); - StructExprEvalStep = load_type(llvm_types_module, "StructExprEvalStep"); - StructExprState = load_type(llvm_types_module, "StructExprState"); - StructFunctionCallInfoData = load_type(llvm_types_module, "StructFunctionCallInfoData"); - StructMemoryContextData = load_type(llvm_types_module, "StructMemoryContextData"); - StructTupleTableSlot = load_type(llvm_types_module, "StructTupleTableSlot"); - StructHeapTupleTableSlot = load_type(llvm_types_module, "StructHeapTupleTableSlot"); - StructMinimalTupleTableSlot = load_type(llvm_types_module, "StructMinimalTupleTableSlot"); - StructHeapTupleData = load_type(llvm_types_module, "StructHeapTupleData"); - StructTupleDescData = load_type(llvm_types_module, "StructTupleDescData"); - StructAggState = load_type(llvm_types_module, "StructAggState"); - StructAggStatePerGroupData = load_type(llvm_types_module, "StructAggStatePerGroupData"); - StructAggStatePerTransData = load_type(llvm_types_module, "StructAggStatePerTransData"); + TypeStorageBool = llvm_pg_var_type("TypeStorageBool"); + TypePGFunction = llvm_pg_var_type("TypePGFunction"); + StructNullableDatum = llvm_pg_var_type("StructNullableDatum"); + StructExprContext = llvm_pg_var_type("StructExprContext"); + StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep"); + StructExprState = llvm_pg_var_type("StructExprState"); + StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData"); + StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData"); + StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot"); + StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot"); + StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot"); + StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData"); + StructTupleDescData = llvm_pg_var_type("StructTupleDescData"); + StructAggState = llvm_pg_var_type("StructAggState"); + StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData"); + StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData"); AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate"); } @@ -1087,7 +1171,7 @@ llvm_resolve_symbol(const char *symname, void *ctx) static LLVMErrorRef llvm_resolve_symbols(LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx, - LLVMOrcLookupStateRef *LookupState, LLVMOrcLookupKind Kind, + LLVMOrcLookupStateRef * LookupState, LLVMOrcLookupKind Kind, LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags, LLVMOrcCLookupSet LookupSet, size_t LookupSetSize) { diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c index 58415c416fe6..c094c63fbceb 100644 --- a/src/backend/jit/llvm/llvmjit_deform.c +++ b/src/backend/jit/llvm/llvmjit_deform.c @@ -7,7 +7,7 @@ * knowledge of the tuple descriptor. Fixed column widths, NOT NULLness, etc * can be taken advantage of. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/jit/llvm/llvmjit_error.cpp b/src/backend/jit/llvm/llvmjit_error.cpp index 2182a03c9137..903b5716977e 100644 --- a/src/backend/jit/llvm/llvmjit_error.cpp +++ b/src/backend/jit/llvm/llvmjit_error.cpp @@ -6,7 +6,7 @@ * Unfortunately neither (re)setting the C++ new handler, nor the LLVM OOM * handler are exposed to C. Therefore this file wraps the necessary code. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/jit/llvm/llvmjit_error.cpp diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c index d92cfc619c96..f897ebde1641 100644 --- a/src/backend/jit/llvm/llvmjit_expr.c +++ b/src/backend/jit/llvm/llvmjit_expr.c @@ -3,7 +3,7 @@ * llvmjit_expr.c * JIT compile expressions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -61,7 +61,7 @@ static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname, LLVMValueRef v_state, ExprEvalStep *op, - int natts, LLVMValueRef v_args[]); + int natts, LLVMValueRef *v_args); static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod); /* macro making it easier to call ExecEval* functions */ @@ -84,7 +84,6 @@ llvm_compile_expr(ExprState *state) LLVMBuilderRef b; LLVMModuleRef mod; - LLVMTypeRef eval_sig; LLVMValueRef eval_fn; LLVMBasicBlockRef entry; LLVMBasicBlockRef *opblocks; @@ -149,19 +148,9 @@ llvm_compile_expr(ExprState *state) funcname = llvm_expand_funcname(context, "evalexpr"); - /* Create the signature and function */ - { - LLVMTypeRef param_types[3]; - - param_types[0] = l_ptr(StructExprState); /* state */ - param_types[1] = l_ptr(StructExprContext); /* econtext */ - param_types[2] = l_ptr(TypeStorageBool); /* isnull */ - - eval_sig = LLVMFunctionType(TypeSizeT, - param_types, lengthof(param_types), - false); - } - eval_fn = LLVMAddFunction(mod, funcname, eval_sig); + /* create function */ + eval_fn = LLVMAddFunction(mod, funcname, + llvm_pg_var_func_type("TypeExprStateEvalFunc")); LLVMSetLinkage(eval_fn, LLVMExternalLinkage); LLVMSetVisibility(eval_fn, LLVMDefaultVisibility); llvm_copy_attributes(AttributeTemplate, eval_fn); @@ -1086,24 +1075,16 @@ llvm_compile_expr(ExprState *state) case EEOP_PARAM_CALLBACK: { - LLVMTypeRef param_types[3]; - LLVMValueRef v_params[3]; LLVMTypeRef v_functype; LLVMValueRef v_func; + LLVMValueRef v_params[3]; - param_types[0] = l_ptr(StructExprState); - param_types[1] = l_ptr(TypeSizeT); - param_types[2] = l_ptr(StructExprContext); - - v_functype = LLVMFunctionType(LLVMVoidType(), - param_types, - lengthof(param_types), - false); + v_functype = llvm_pg_var_func_type("TypeExecEvalSubroutine"); v_func = l_ptr_const(op->d.cparam.paramfunc, - l_ptr(v_functype)); + LLVMPointerType(v_functype, 0)); v_params[0] = v_state; - v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT)); + v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); v_params[2] = v_econtext; LLVMBuildCall(b, v_func, @@ -1113,23 +1094,56 @@ llvm_compile_expr(ExprState *state) break; } - case EEOP_SBSREF_OLD: - build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld", - v_state, op); - LLVMBuildBr(b, opblocks[opno + 1]); - break; + case EEOP_SBSREF_SUBSCRIPTS: + { + int jumpdone = op->d.sbsref_subscript.jumpdone; + LLVMTypeRef v_functype; + LLVMValueRef v_func; + LLVMValueRef v_params[3]; + LLVMValueRef v_ret; - case EEOP_SBSREF_ASSIGN: - build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign", - v_state, op); - LLVMBuildBr(b, opblocks[opno + 1]); - break; + v_functype = llvm_pg_var_func_type("TypeExecEvalBoolSubroutine"); + v_func = l_ptr_const(op->d.sbsref_subscript.subscriptfunc, + LLVMPointerType(v_functype, 0)); + + v_params[0] = v_state; + v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); + v_params[2] = v_econtext; + v_ret = LLVMBuildCall(b, + v_func, + v_params, lengthof(v_params), ""); + v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); + LLVMBuildCondBr(b, + LLVMBuildICmp(b, LLVMIntEQ, v_ret, + l_sbool_const(1), ""), + opblocks[opno + 1], + opblocks[jumpdone]); + break; + } + + case EEOP_SBSREF_OLD: + case EEOP_SBSREF_ASSIGN: case EEOP_SBSREF_FETCH: - build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch", - v_state, op); - LLVMBuildBr(b, opblocks[opno + 1]); - break; + { + LLVMTypeRef v_functype; + LLVMValueRef v_func; + LLVMValueRef v_params[3]; + + v_functype = llvm_pg_var_func_type("TypeExecEvalSubroutine"); + v_func = l_ptr_const(op->d.sbsref.subscriptfunc, + LLVMPointerType(v_functype, 0)); + + v_params[0] = v_state; + v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); + v_params[2] = v_econtext; + LLVMBuildCall(b, + v_func, + v_params, lengthof(v_params), ""); + + LLVMBuildBr(b, opblocks[opno + 1]); + break; + } case EEOP_CASE_TESTVAL: { @@ -1744,23 +1758,6 @@ llvm_compile_expr(ExprState *state) LLVMBuildBr(b, opblocks[opno + 1]); break; - case EEOP_SBSREF_SUBSCRIPT: - { - int jumpdone = op->d.sbsref_subscript.jumpdone; - LLVMValueRef v_ret; - - v_ret = build_EvalXFunc(b, mod, "ExecEvalSubscriptingRef", - v_state, op); - v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); - - LLVMBuildCondBr(b, - LLVMBuildICmp(b, LLVMIntEQ, v_ret, - l_sbool_const(1), ""), - opblocks[opno + 1], - opblocks[jumpdone]); - break; - } - case EEOP_DOMAIN_TESTVAL: { LLVMBasicBlockRef b_avail, @@ -1851,6 +1848,12 @@ llvm_compile_expr(ExprState *state) LLVMBuildBr(b, opblocks[opno + 1]); break; + case EEOP_HASHED_SCALARARRAYOP: + build_EvalXFunc(b, mod, "ExecEvalHashedScalarArrayOp", + v_state, op, v_econtext); + LLVMBuildBr(b, opblocks[opno + 1]); + break; + case EEOP_XMLEXPR: build_EvalXFunc(b, mod, "ExecEvalXmlExpr", v_state, op); @@ -1859,20 +1862,11 @@ llvm_compile_expr(ExprState *state) case EEOP_AGGREF: { - AggrefExprState *aggref = op->d.aggref.astate; - LLVMValueRef v_aggnop; LLVMValueRef v_aggno; LLVMValueRef value, isnull; - /* - * At this point aggref->aggno is not yet set (it's set up - * in ExecInitAgg() after initializing the expression). So - * load it from memory each time round. - */ - v_aggnop = l_ptr_const(&aggref->aggno, - l_ptr(LLVMInt32Type())); - v_aggno = LLVMBuildLoad(b, v_aggnop, "v_aggno"); + v_aggno = l_int32_const(op->d.aggref.aggno); /* load agg value / null */ value = l_load_gep1(b, v_aggvalues, v_aggno, "aggvalue"); @@ -2009,12 +2003,6 @@ llvm_compile_expr(ExprState *state) LLVMBuildBr(b, opblocks[opno + 1]); break; - case EEOP_ALTERNATIVE_SUBPLAN: - build_EvalXFunc(b, mod, "ExecEvalAlternativeSubPlan", - v_state, op, v_econtext); - LLVMBuildBr(b, opblocks[opno + 1]); - break; - case EEOP_AGG_STRICT_DESERIALIZE: case EEOP_AGG_DESERIALIZE: { @@ -2564,7 +2552,7 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname, LLVMValueRef v_state, ExprEvalStep *op, - int nargs, LLVMValueRef v_args[]) + int nargs, LLVMValueRef *v_args) { LLVMValueRef v_fn = llvm_pg_func(mod, funcname); LLVMValueRef *params; diff --git a/src/backend/jit/llvm/llvmjit_inline.cpp b/src/backend/jit/llvm/llvmjit_inline.cpp index 01168cab41b4..9bb4b672a736 100644 --- a/src/backend/jit/llvm/llvmjit_inline.cpp +++ b/src/backend/jit/llvm/llvmjit_inline.cpp @@ -11,7 +11,7 @@ * so for all external functions, all the referenced functions (and * prerequisites) will be imported. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/llvmjit/llvmjit_inline.cpp diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c index 61825881dfe1..e7e28d3c5a2b 100644 --- a/src/backend/jit/llvm/llvmjit_types.c +++ b/src/backend/jit/llvm/llvmjit_types.c @@ -16,7 +16,7 @@ * bitcode. * * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/jit/llvm/llvmjit_types.c @@ -48,6 +48,9 @@ PGFunction TypePGFunction; size_t TypeSizeT; bool TypeStorageBool; +ExprStateEvalFunc TypeExprStateEvalFunc; +ExecEvalSubroutine TypeExecEvalSubroutine; +ExecEvalBoolSubroutine TypeExecEvalBoolSubroutine; NullableDatum StructNullableDatum; AggState StructAggState; @@ -102,7 +105,6 @@ void *referenced_functions[] = ExecAggTransReparent, ExecEvalAggOrderedTransDatum, ExecEvalAggOrderedTransTuple, - ExecEvalAlternativeSubPlan, ExecEvalArrayCoerce, ExecEvalArrayExpr, ExecEvalConstraintCheck, @@ -126,11 +128,8 @@ void *referenced_functions[] = ExecEvalScalarArrayOp, ExecEvalScalarArrayOpFastInt, ExecEvalScalarArrayOpFastStr, + ExecEvalHashedScalarArrayOp, ExecEvalSubPlan, - ExecEvalSubscriptingRef, - ExecEvalSubscriptingRefAssign, - ExecEvalSubscriptingRefFetch, - ExecEvalSubscriptingRefOld, ExecEvalSysVar, ExecEvalWholeRowVar, ExecEvalXmlExpr, diff --git a/src/backend/jit/llvm/llvmjit_wrap.cpp b/src/backend/jit/llvm/llvmjit_wrap.cpp index 37c006a1ff50..692483d3b938 100644 --- a/src/backend/jit/llvm/llvmjit_wrap.cpp +++ b/src/backend/jit/llvm/llvmjit_wrap.cpp @@ -3,7 +3,7 @@ * llvmjit_wrap.cpp * Parts of the LLVM interface not (yet) exposed to C. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/llvm/llvmjit_wrap.cpp diff --git a/src/backend/lib/binaryheap.c b/src/backend/lib/binaryheap.c index a1b4f62a71e1..d54e24529919 100644 --- a/src/backend/lib/binaryheap.c +++ b/src/backend/lib/binaryheap.c @@ -3,7 +3,7 @@ * binaryheap.c * A simple binary heap implementation * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/binaryheap.c diff --git a/src/backend/lib/bipartite_match.c b/src/backend/lib/bipartite_match.c index 9372c0c83a1e..baa1c139100b 100644 --- a/src/backend/lib/bipartite_match.c +++ b/src/backend/lib/bipartite_match.c @@ -7,7 +7,7 @@ * * https://en.wikipedia.org/w/index.php?title=Hopcroft%E2%80%93Karp_algorithm&oldid=593898016 * - * Copyright (c) 2015-2020, PostgreSQL Global Development Group + * Copyright (c) 2015-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/bipartite_match.c diff --git a/src/backend/lib/bloomfilter.c b/src/backend/lib/bloomfilter.c index f040e83c0162..daf2c40ebf54 100644 --- a/src/backend/lib/bloomfilter.c +++ b/src/backend/lib/bloomfilter.c @@ -24,7 +24,7 @@ * caller many authoritative lookups, such as expensive probes of a much larger * on-disk structure. * - * Copyright (c) 2018-2020, PostgreSQL Global Development Group + * Copyright (c) 2018-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/bloomfilter.c diff --git a/src/backend/lib/dshash.c b/src/backend/lib/dshash.c index 78ccf03217fe..88ca9d62aab9 100644 --- a/src/backend/lib/dshash.c +++ b/src/backend/lib/dshash.c @@ -20,7 +20,7 @@ * Future versions may support iterators and incremental resizing; for now * the implementation is minimalist. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -375,7 +375,7 @@ dshash_get_hash_table_handle(dshash_table *hash_table) * the caller must take care to ensure that the entry is not left corrupted. * The lock mode is either shared or exclusive depending on 'exclusive'. * - * The caller must not lock a lock already. + * The caller must not hold a lock already. * * Note that the lock held is in fact an LWLock, so interrupts will be held on * return from this function, and not resumed until dshash_release_lock is diff --git a/src/backend/lib/hyperloglog.c b/src/backend/lib/hyperloglog.c index 351fed8186fb..f4e02410adb9 100644 --- a/src/backend/lib/hyperloglog.c +++ b/src/backend/lib/hyperloglog.c @@ -3,7 +3,7 @@ * hyperloglog.c * HyperLogLog cardinality estimator * - * Portions Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2014-2021, PostgreSQL Global Development Group * * Based on Hideaki Ohno's C++ implementation. This is probably not ideally * suited to estimating the cardinality of very large sets; in particular, we diff --git a/src/backend/lib/ilist.c b/src/backend/lib/ilist.c index 9b02d5460760..e9a07c14f7b5 100644 --- a/src/backend/lib/ilist.c +++ b/src/backend/lib/ilist.c @@ -3,7 +3,7 @@ * ilist.c * support for integrated/inline doubly- and singly- linked lists * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/lib/integerset.c b/src/backend/lib/integerset.c index 069a35fb23cd..278a91bdbf82 100644 --- a/src/backend/lib/integerset.c +++ b/src/backend/lib/integerset.c @@ -61,7 +61,7 @@ * (https://doi.org/10.1002/spe.948) * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/lib/knapsack.c b/src/backend/lib/knapsack.c index 8ab734b445df..50c84b4aed18 100644 --- a/src/backend/lib/knapsack.c +++ b/src/backend/lib/knapsack.c @@ -15,7 +15,7 @@ * allows approximate solutions in polynomial time (the general case of the * exact problem is NP-hard). * - * Copyright (c) 2017-2020, PostgreSQL Global Development Group + * Copyright (c) 2017-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/knapsack.c diff --git a/src/backend/lib/pairingheap.c b/src/backend/lib/pairingheap.c index 1e45729fc750..bed3d2efb499 100644 --- a/src/backend/lib/pairingheap.c +++ b/src/backend/lib/pairingheap.c @@ -14,7 +14,7 @@ * The pairing heap: a new form of self-adjusting heap. * Algorithmica 1, 1 (January 1986), pages 111-129. DOI: 10.1007/BF01840439 * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/pairingheap.c diff --git a/src/backend/lib/rbtree.c b/src/backend/lib/rbtree.c index 28681b8f6118..536df1f7715b 100644 --- a/src/backend/lib/rbtree.c +++ b/src/backend/lib/rbtree.c @@ -17,7 +17,7 @@ * longest path from root to leaf is only about twice as long as the shortest, * so lookups are guaranteed to run in O(lg n) time. * - * Copyright (c) 2009-2020, PostgreSQL Global Development Group + * Copyright (c) 2009-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/rbtree.c diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile index 8b97b21479df..c8d107a92b34 100644 --- a/src/backend/libpq/Makefile +++ b/src/backend/libpq/Makefile @@ -29,7 +29,7 @@ OBJS = \ pqmq.o \ pqsignal.o -ifeq ($(with_openssl),yes) +ifeq ($(with_ssl),openssl) OBJS += be-secure-openssl.o endif @@ -39,12 +39,12 @@ endif # Greenplum objects follow OBJS += fe-protocol3.o fe-connect.o \ - fe-exec.o pqexpbuffer.o fe-auth.o fe-misc.o fe-protocol2.o fe-secure.o \ + fe-exec.o pqexpbuffer.o fe-auth.o fe-misc.o fe-secure.o fe-trace.o \ fe-auth-scram.o \ $(filter getpeereid.o, $(LIBOBJS)) # Greenplum OpenSSL objects follow -ifeq ($(with_openssl),yes) +ifeq ($(with_ssl),openssl) OBJS += fe-secure-common.o fe-secure-openssl.o endif @@ -53,7 +53,7 @@ ifeq ($(with_gssapi),yes) OBJS += fe-gssapi-common.o fe-secure-gssapi.o endif -fe-protocol3.c fe-connect.c fe-exec.c pqexpbuffer.c fe-auth.c fe-auth-scram.c fe-misc.c fe-protocol2.c fe-secure.c fe-secure-openssl.c fe-secure-common.c fe-secure-gssapi.c fe-gssapi-common.c: % : $(top_srcdir)/src/interfaces/libpq/% +fe-protocol3.c fe-connect.c fe-exec.c pqexpbuffer.c fe-auth.c fe-auth-scram.c fe-misc.c fe-secure.c fe-secure-openssl.c fe-secure-common.c fe-secure-gssapi.c fe-gssapi-common.c fe-trace.c: % : $(top_srcdir)/src/interfaces/libpq/% rm -f $@ && $(LN_S) $< . getpeereid.c: % : $(top_srcdir)/src/port/% @@ -67,7 +67,7 @@ $(top_builddir)/src/port/pg_config_paths.h: clean distclean: clean-symlinks clean-symlinks: - rm -f fe-protocol3.c fe-connect.c fe-exec.c pqexpbuffer.c fe-auth.c fe-auth-scram.c fe-misc.c fe-protocol2.c fe-secure.c fe-secure-openssl.c fe-secure-common.c fe-secure-gssapi.c fe-gssapi-common.c + rm -f fe-protocol3.c fe-connect.c fe-exec.c pqexpbuffer.c fe-auth.c fe-auth-scram.c fe-misc.c fe-secure.c fe-secure-openssl.c fe-secure-common.c fe-secure-gssapi.c fe-gssapi-common.c fe-trace.c rm -f getpeereid.c include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index 5214d328656f..f9e1026a12c0 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -80,7 +80,7 @@ * general, after logging in, but let's do what we can here. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/auth-scram.c @@ -95,6 +95,7 @@ #include "catalog/pg_authid.h" #include "catalog/pg_control.h" #include "common/base64.h" +#include "common/hmac.h" #include "common/saslprep.h" #include "common/scram-common.h" #include "common/sha2.h" @@ -527,8 +528,12 @@ scram_verify_plain_password(const char *username, const char *password, password = prep_password; /* Compute Server Key based on the user-supplied plaintext password */ - scram_SaltedPassword(password, salt, saltlen, iterations, salted_password); - scram_ServerKey(salted_password, computed_key); + if (scram_SaltedPassword(password, salt, saltlen, iterations, + salted_password) < 0 || + scram_ServerKey(salted_password, computed_key) < 0) + { + elog(ERROR, "could not compute server key"); + } if (prep_password) pfree(prep_password); @@ -651,8 +656,17 @@ mock_scram_secret(const char *username, int *iterations, char **salt, char *encoded_salt; int encoded_len; - /* Generate deterministic salt */ + /* + * Generate deterministic salt. + * + * Note that we cannot reveal any information to an attacker here so the + * error messages need to remain generic. This should never fail anyway + * as the salt generated for mock authentication uses the cluster's nonce + * value. + */ raw_salt = scram_mock_salt(username); + if (raw_salt == NULL) + elog(ERROR, "could not encode salt"); encoded_len = pg_b64_enc_len(SCRAM_DEFAULT_SALT_LEN); /* don't forget the zero-terminator */ @@ -660,12 +674,6 @@ mock_scram_secret(const char *username, int *iterations, char **salt, encoded_len = pg_b64_encode(raw_salt, SCRAM_DEFAULT_SALT_LEN, encoded_salt, encoded_len); - /* - * Note that we cannot reveal any information to an attacker here so the - * error message needs to remain generic. This should never fail anyway - * as the salt generated for mock authentication uses the cluster's nonce - * value. - */ if (encoded_len < 0) elog(ERROR, "could not encode salt"); encoded_salt[encoded_len] = '\0'; @@ -1084,7 +1092,8 @@ verify_final_nonce(scram_state *state) /* * Verify the client proof contained in the last message received from - * client in an exchange. + * client in an exchange. Returns true if the verification is a success, + * or false for a failure. */ static bool verify_client_proof(scram_state *state) @@ -1092,30 +1101,40 @@ verify_client_proof(scram_state *state) uint8 ClientSignature[SCRAM_KEY_LEN]; uint8 ClientKey[SCRAM_KEY_LEN]; uint8 client_StoredKey[SCRAM_KEY_LEN]; - scram_HMAC_ctx ctx; + pg_hmac_ctx *ctx = pg_hmac_create(PG_SHA256); int i; - /* calculate ClientSignature */ - scram_HMAC_init(&ctx, state->StoredKey, SCRAM_KEY_LEN); - scram_HMAC_update(&ctx, - state->client_first_message_bare, - strlen(state->client_first_message_bare)); - scram_HMAC_update(&ctx, ",", 1); - scram_HMAC_update(&ctx, - state->server_first_message, - strlen(state->server_first_message)); - scram_HMAC_update(&ctx, ",", 1); - scram_HMAC_update(&ctx, - state->client_final_message_without_proof, - strlen(state->client_final_message_without_proof)); - scram_HMAC_final(ClientSignature, &ctx); + /* + * Calculate ClientSignature. Note that we don't log directly a failure + * here even when processing the calculations as this could involve a mock + * authentication. + */ + if (pg_hmac_init(ctx, state->StoredKey, SCRAM_KEY_LEN) < 0 || + pg_hmac_update(ctx, + (uint8 *) state->client_first_message_bare, + strlen(state->client_first_message_bare)) < 0 || + pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || + pg_hmac_update(ctx, + (uint8 *) state->server_first_message, + strlen(state->server_first_message)) < 0 || + pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || + pg_hmac_update(ctx, + (uint8 *) state->client_final_message_without_proof, + strlen(state->client_final_message_without_proof)) < 0 || + pg_hmac_final(ctx, ClientSignature, sizeof(ClientSignature)) < 0) + { + elog(ERROR, "could not calculate client signature"); + } + + pg_hmac_free(ctx); /* Extract the ClientKey that the client calculated from the proof */ for (i = 0; i < SCRAM_KEY_LEN; i++) ClientKey[i] = state->ClientProof[i] ^ ClientSignature[i]; /* Hash it one more time, and compare with StoredKey */ - scram_H(ClientKey, SCRAM_KEY_LEN, client_StoredKey); + if (scram_H(ClientKey, SCRAM_KEY_LEN, client_StoredKey) < 0) + elog(ERROR, "could not hash stored key"); if (memcmp(client_StoredKey, state->StoredKey, SCRAM_KEY_LEN) != 0) return false; @@ -1343,22 +1362,27 @@ build_server_final_message(scram_state *state) uint8 ServerSignature[SCRAM_KEY_LEN]; char *server_signature_base64; int siglen; - scram_HMAC_ctx ctx; + pg_hmac_ctx *ctx = pg_hmac_create(PG_SHA256); /* calculate ServerSignature */ - scram_HMAC_init(&ctx, state->ServerKey, SCRAM_KEY_LEN); - scram_HMAC_update(&ctx, - state->client_first_message_bare, - strlen(state->client_first_message_bare)); - scram_HMAC_update(&ctx, ",", 1); - scram_HMAC_update(&ctx, - state->server_first_message, - strlen(state->server_first_message)); - scram_HMAC_update(&ctx, ",", 1); - scram_HMAC_update(&ctx, - state->client_final_message_without_proof, - strlen(state->client_final_message_without_proof)); - scram_HMAC_final(ServerSignature, &ctx); + if (pg_hmac_init(ctx, state->ServerKey, SCRAM_KEY_LEN) < 0 || + pg_hmac_update(ctx, + (uint8 *) state->client_first_message_bare, + strlen(state->client_first_message_bare)) < 0 || + pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || + pg_hmac_update(ctx, + (uint8 *) state->server_first_message, + strlen(state->server_first_message)) < 0 || + pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || + pg_hmac_update(ctx, + (uint8 *) state->client_final_message_without_proof, + strlen(state->client_final_message_without_proof)) < 0 || + pg_hmac_final(ctx, ServerSignature, sizeof(ServerSignature)) < 0) + { + elog(ERROR, "could not calculate server signature"); + } + + pg_hmac_free(ctx); siglen = pg_b64_enc_len(SCRAM_KEY_LEN); /* don't forget the zero-terminator */ @@ -1388,28 +1412,34 @@ build_server_final_message(scram_state *state) /* * Deterministically generate salt for mock authentication, using a SHA256 * hash based on the username and a cluster-level secret key. Returns a - * pointer to a static buffer of size SCRAM_DEFAULT_SALT_LEN. + * pointer to a static buffer of size SCRAM_DEFAULT_SALT_LEN, or NULL. */ static char * scram_mock_salt(const char *username) { - pg_sha256_ctx ctx; + pg_cryptohash_ctx *ctx; static uint8 sha_digest[PG_SHA256_DIGEST_LENGTH]; char *mock_auth_nonce = GetMockAuthenticationNonce(); /* * Generate salt using a SHA256 hash of the username and the cluster's * mock authentication nonce. (This works as long as the salt length is - * not larger the SHA256 digest length. If the salt is smaller, the caller - * will just ignore the extra data.) + * not larger than the SHA256 digest length. If the salt is smaller, the + * caller will just ignore the extra data.) */ StaticAssertStmt(PG_SHA256_DIGEST_LENGTH >= SCRAM_DEFAULT_SALT_LEN, "salt length greater than SHA256 digest length"); - pg_sha256_init(&ctx); - pg_sha256_update(&ctx, (uint8 *) username, strlen(username)); - pg_sha256_update(&ctx, (uint8 *) mock_auth_nonce, MOCK_AUTH_NONCE_LEN); - pg_sha256_final(&ctx, sha_digest); + ctx = pg_cryptohash_create(PG_SHA256); + if (pg_cryptohash_init(ctx) < 0 || + pg_cryptohash_update(ctx, (uint8 *) username, strlen(username)) < 0 || + pg_cryptohash_update(ctx, (uint8 *) mock_auth_nonce, MOCK_AUTH_NONCE_LEN) < 0 || + pg_cryptohash_final(ctx, sha_digest, sizeof(sha_digest)) < 0) + { + pg_cryptohash_free(ctx); + return NULL; + } + pg_cryptohash_free(ctx); return (char *) sha_digest; } diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index fbe0b255089e..266c617016fb 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -3,7 +3,7 @@ * auth.c * Routines to handle network authentication * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -34,8 +34,10 @@ #include "libpq/scram.h" #include "miscadmin.h" #include "port/pg_bswap.h" +#include "postmaster/postmaster.h" #include "replication/walsender.h" #include "storage/ipc.h" +#include "utils/guc.h" #include "utils/memutils.h" #include "utils/timestamp.h" @@ -70,6 +72,7 @@ static void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, int extralen); static void auth_failed(Port *port, int status, char *logdetail); static char *recv_password_packet(Port *port); +static void set_authn_id(Port *port, const char *id); /*---------------------------------------------------------------- @@ -231,6 +234,7 @@ static int PerformRadiusTransaction(const char *server, const char *secret, cons /* * Maximum accepted size of GSS and SSPI authentication tokens. + * We also use this as a limit on ordinary password packet lengths. * * Kerberos tickets are usually quite small, but the TGTs issued by Windows * domain controllers include an authorization field known as the Privilege @@ -623,6 +627,51 @@ is_internal_gpdb_conn(Port *port) } +/* + * Sets the authenticated identity for the current user. The provided string + * will be copied into the TopMemoryContext. The ID will be logged if + * log_connections is enabled. + * + * Auth methods should call this routine exactly once, as soon as the user is + * successfully authenticated, even if they have reasons to know that + * authorization will fail later. + * + * The provided string will be copied into TopMemoryContext, to match the + * lifetime of the Port, so it is safe to pass a string that is managed by an + * external library. + */ +static void +set_authn_id(Port *port, const char *id) +{ + Assert(id); + + if (port->authn_id) + { + /* + * An existing authn_id should never be overwritten; that means two + * authentication providers are fighting (or one is fighting itself). + * Don't leak any authn details to the client, but don't let the + * connection continue, either. + */ + ereport(FATAL, + (errmsg("connection was re-authenticated"), + errdetail_log("previous ID: \"%s\"; new ID: \"%s\"", + port->authn_id, id))); + } + + port->authn_id = MemoryContextStrdup(TopMemoryContext, id); + + if (Log_connections) + { + ereport(LOG, + errmsg("connection authenticated: identity=\"%s\" method=%s " + "(%s:%d)", + port->authn_id, hba_authname(port->hba->auth_method), HbaFileName, + port->hba->linenumber)); + } +} + + /* * Client authentication starts here. If there is an error, this * function does not return and the backend process is terminated. @@ -693,17 +742,6 @@ ClientAuthentication(Port *port) errmsg("connection requires a valid client certificate"))); } -#ifdef ENABLE_GSS - if (port->gss->enc && port->hba->auth_method != uaReject && - port->hba->auth_method != uaImplicitReject && - port->hba->auth_method != uaTrust && - port->hba->auth_method != uaGSS) - { - ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), - errmsg("GSSAPI encryption can only be used with gss, trust, or reject authentication methods"))); - } -#endif - /* * Now proceed to do the actual authentication check */ @@ -723,44 +761,37 @@ ClientAuthentication(Port *port) */ { char hostinfo[NI_MAXHOST]; + const char *encryption_state; pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, hostinfo, sizeof(hostinfo), NULL, 0, NI_NUMERICHOST); - if (am_walsender) - { + encryption_state = +#ifdef ENABLE_GSS + (port->gss && port->gss->enc) ? _("GSS encryption") : +#endif #ifdef USE_SSL + port->ssl_in_use ? _("SSL encryption") : +#endif + _("no encryption"); + + if (am_walsender && !am_db_walsender) ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), + /* translator: last %s describes encryption state */ errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s", hostinfo, port->user_name, - port->ssl_in_use ? _("SSL on") : _("SSL off")))); -#else - ereport(FATAL, - (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), - errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"", - hostinfo, port->user_name))); -#endif - } + encryption_state))); else - { -#ifdef USE_SSL ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), + /* translator: last %s describes encryption state */ errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s", hostinfo, port->user_name, port->database_name, - port->ssl_in_use ? _("SSL on") : _("SSL off")))); -#else - ereport(FATAL, - (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), - errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"", - hostinfo, port->user_name, - port->database_name))); -#endif - } + encryption_state))); break; } @@ -776,12 +807,22 @@ ClientAuthentication(Port *port) */ { char hostinfo[NI_MAXHOST]; + const char *encryption_state; pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, hostinfo, sizeof(hostinfo), NULL, 0, NI_NUMERICHOST); + encryption_state = +#ifdef ENABLE_GSS + (port->gss && port->gss->enc) ? _("GSS encryption") : +#endif +#ifdef USE_SSL + port->ssl_in_use ? _("SSL encryption") : +#endif + _("no encryption"); + #define HOSTNAME_LOOKUP_DETAIL(port) \ (port->remote_hostname ? \ (port->remote_hostname_resolv == +1 ? \ @@ -803,42 +844,23 @@ ClientAuthentication(Port *port) gai_strerror(port->remote_hostname_errcode)) : \ 0)) - if (am_walsender) - { -#ifdef USE_SSL + if (am_walsender && !am_db_walsender) ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), + /* translator: last %s describes encryption state */ errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s", hostinfo, port->user_name, - port->ssl_in_use ? _("SSL on") : _("SSL off")), - HOSTNAME_LOOKUP_DETAIL(port))); -#else - ereport(FATAL, - (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), - errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"", - hostinfo, port->user_name), + encryption_state), HOSTNAME_LOOKUP_DETAIL(port))); -#endif - } else - { -#ifdef USE_SSL ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), + /* translator: last %s describes encryption state */ errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s", hostinfo, port->user_name, port->database_name, - port->ssl_in_use ? _("SSL on") : _("SSL off")), - HOSTNAME_LOOKUP_DETAIL(port))); -#else - ereport(FATAL, - (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), - errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"", - hostinfo, port->user_name, - port->database_name), + encryption_state), HOSTNAME_LOOKUP_DETAIL(port))); -#endif - } break; } @@ -852,7 +874,17 @@ ClientAuthentication(Port *port) port->user_name))); } + /* We might or might not have the gss workspace already */ + if (port->gss == NULL) + port->gss = (pg_gssinfo *) + MemoryContextAllocZero(TopMemoryContext, + sizeof(pg_gssinfo)); port->gss->auth = true; + + /* + * If GSS state was set up while enabling encryption, we can just + * check the client's principal. Otherwise, ask for it. + */ if (port->gss->enc) status = pg_GSS_checkauth(port); else @@ -867,6 +899,10 @@ ClientAuthentication(Port *port) case uaSSPI: #ifdef ENABLE_SSPI + if (port->gss == NULL) + port->gss = (pg_gssinfo *) + MemoryContextAllocZero(TopMemoryContext, + sizeof(pg_gssinfo)); sendAuthRequest(port, AUTH_REQ_SSPI, NULL, 0); status = pg_SSPI_recvauth(port); #else @@ -997,39 +1033,29 @@ static char * recv_password_packet(Port *port) { StringInfoData buf; + int mtype; pq_startmsgread(); - if (PG_PROTOCOL_MAJOR(port->proto) >= 3) - { - /* Expect 'p' message type */ - int mtype; - mtype = pq_getbyte(); - if (mtype != 'p') - { - /* - * If the client just disconnects without offering a password, - * don't make a log entry. This is legal per protocol spec and in - * fact commonly done by psql, so complaining just clutters the - * log. - */ - if (mtype != EOF) - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("expected password response, got message type %d", - mtype))); - return NULL; /* EOF or bad message type */ - } - } - else + /* Expect 'p' message type */ + mtype = pq_getbyte(); + if (mtype != 'p') { - /* For pre-3.0 clients, avoid log entry if they just disconnect */ - if (pq_peekbyte() == EOF) - return NULL; /* EOF */ + /* + * If the client just disconnects without offering a password, don't + * make a log entry. This is legal per protocol spec and in fact + * commonly done by psql, so complaining just clutters the log. + */ + if (mtype != EOF) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("expected password response, got message type %d", + mtype))); + return NULL; /* EOF or bad message type */ } initStringInfo(&buf); - if (pq_getmessage(&buf, 1000)) /* receive password */ + if (pq_getmessage(&buf, PG_MAX_AUTH_TOKEN_LENGTH)) /* receive password */ { /* EOF - pq_getmessage already logged a suitable message */ pfree(buf.data); @@ -1110,6 +1136,9 @@ CheckPasswordAuth(Port *port, char **logdetail) pfree(shadow_pass); pfree(passwd); + if (result == STATUS_OK) + set_authn_id(port, port->user_name); + return result; } @@ -1169,6 +1198,10 @@ CheckPWChallengeAuth(Port *port, char **logdetail) Assert(auth_result != STATUS_OK); return STATUS_ERROR; } + + if (auth_result == STATUS_OK) + set_authn_id(port, port->user_name); + return auth_result; } @@ -1223,19 +1256,6 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) int result; bool initial; - /* - * SASL auth is not supported for protocol versions before 3, because it - * relies on the overall message length word to determine the SASL payload - * size in AuthenticationSASLContinue and PasswordMessage messages. (We - * used to have a hard rule that protocol messages must be parsable - * without relying on the length word, but we hardly care about older - * protocol version anymore.) - */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - ereport(FATAL, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("SASL authentication is not supported in protocol version 2"))); - /* * Send the SASL authentication request to user. It includes the list of * authentication mechanisms that are supported. @@ -1427,41 +1447,17 @@ pg_GSS_recvauth(Port *port) gss_buffer_desc gbuf; /* - * GSS auth is not supported for protocol versions before 3, because it - * relies on the overall message length word to determine the GSS payload - * size in AuthenticationGSSContinue and PasswordMessage messages. (This - * is, in fact, a design error in our GSS support, because protocol - * messages are supposed to be parsable without relying on the length - * word; but it's not worth changing it now.) + * Use the configured keytab, if there is one. Unfortunately, Heimdal + * doesn't support the cred store extensions, so use the env var. */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - ereport(FATAL, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("GSSAPI is not supported in protocol version 2"))); - - if (pg_krb_server_keyfile && strlen(pg_krb_server_keyfile) > 0) + if (pg_krb_server_keyfile != NULL && pg_krb_server_keyfile[0] != '\0') { - /* - * Set default Kerberos keytab file for the Krb5 mechanism. - * - * setenv("KRB5_KTNAME", pg_krb_server_keyfile, 0); except setenv() - * not always available. - */ - if (getenv("KRB5_KTNAME") == NULL) + if (setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1) != 0) { - size_t kt_len = strlen(pg_krb_server_keyfile) + 14; - char *kt_path = malloc(kt_len); - - if (!kt_path || - snprintf(kt_path, kt_len, "KRB5_KTNAME=%s", - pg_krb_server_keyfile) != kt_len - 2 || - putenv(kt_path) != 0) - { - ereport(LOG, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - return STATUS_ERROR; - } + /* The only likely failure cause is OOM, so use that errcode */ + ereport(FATAL, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("could not set environment: %m"))); } } @@ -1557,9 +1553,9 @@ pg_GSS_recvauth(Port *port) if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) { gss_delete_sec_context(&lmin_s, &port->gss->ctx, GSS_C_NO_BUFFER); - pg_GSS_error_be(ERROR, - _("accepting GSS security context failed"), + pg_GSS_error_be(_("accepting GSS security context failed"), maj_stat, min_stat); + return STATUS_ERROR; } if (maj_stat == GSS_S_CONTINUE_NEEDED) @@ -1589,6 +1585,7 @@ pg_GSS_checkauth(Port *port) min_stat, lmin_s; gss_buffer_desc gbuf; + char *princ; /* * Get the name of the user that authenticated, and compare it to the pg @@ -1596,22 +1593,38 @@ pg_GSS_checkauth(Port *port) */ maj_stat = gss_display_name(&min_stat, port->gss->name, &gbuf, NULL); if (maj_stat != GSS_S_COMPLETE) - pg_GSS_error_be(ERROR, - _("retrieving GSS user name failed"), + { + pg_GSS_error_be(_("retrieving GSS user name failed"), maj_stat, min_stat); + return STATUS_ERROR; + } + + /* + * gbuf.value might not be null-terminated, so turn it into a regular + * null-terminated string. + */ + princ = palloc(gbuf.length + 1); + memcpy(princ, gbuf.value, gbuf.length); + princ[gbuf.length] = '\0'; + gss_release_buffer(&lmin_s, &gbuf); /* * Copy the original name of the authenticated principal into our backend * memory for display later. + * + * This is also our authenticated identity. Set it now, rather than + * waiting for the usermap check below, because authentication has already + * succeeded and we want the log file to reflect that. */ - port->gss->princ = MemoryContextStrdup(TopMemoryContext, gbuf.value); + port->gss->princ = MemoryContextStrdup(TopMemoryContext, princ); + set_authn_id(port, princ); /* * Split the username at the realm separator */ - if (strchr(gbuf.value, '@')) + if (strchr(princ, '@')) { - char *cp = strchr(gbuf.value, '@'); + char *cp = strchr(princ, '@'); /* * If we are not going to include the realm in the username that is @@ -1638,7 +1651,7 @@ pg_GSS_checkauth(Port *port) elog(DEBUG2, "GSSAPI realm (%s) and configured realm (%s) don't match", cp, port->hba->krb_realm); - gss_release_buffer(&lmin_s, &gbuf); + pfree(princ); return STATUS_ERROR; } } @@ -1647,15 +1660,14 @@ pg_GSS_checkauth(Port *port) { elog(DEBUG2, "GSSAPI did not return realm but realm matching was requested"); - - gss_release_buffer(&lmin_s, &gbuf); + pfree(princ); return STATUS_ERROR; } - ret = check_usermap(port->hba->usermap, port->user_name, gbuf.value, + ret = check_usermap(port->hba->usermap, port->user_name, princ, pg_krb_caseins_users); - gss_release_buffer(&lmin_s, &gbuf); + pfree(princ); return ret; } @@ -1714,22 +1726,10 @@ pg_SSPI_recvauth(Port *port) DWORD domainnamesize = sizeof(domainname); SID_NAME_USE accountnameuse; HMODULE secur32; + char *authn_id; QUERY_SECURITY_CONTEXT_TOKEN_FN _QuerySecurityContextToken; - /* - * SSPI auth is not supported for protocol versions before 3, because it - * relies on the overall message length word to determine the SSPI payload - * size in AuthenticationGSSContinue and PasswordMessage messages. (This - * is, in fact, a design error in our SSPI support, because protocol - * messages are supposed to be parsable without relying on the length - * word; but it's not worth changing it now.) - */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - ereport(FATAL, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("SSPI is not supported in protocol version 2"))); - /* * Acquire a handle to the server credentials. */ @@ -1893,7 +1893,7 @@ pg_SSPI_recvauth(Port *port) (errmsg("could not load library \"%s\": error code %lu", "SECUR32.DLL", GetLastError()))); - _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN) + _QuerySecurityContextToken = (QUERY_SECURITY_CONTEXT_TOKEN_FN) (pg_funcptr_t) GetProcAddress(secur32, "QuerySecurityContextToken"); if (_QuerySecurityContextToken == NULL) { @@ -1956,6 +1956,26 @@ pg_SSPI_recvauth(Port *port) return status; } + /* + * We have all of the information necessary to construct the authenticated + * identity. Set it now, rather than waiting for check_usermap below, + * because authentication has already succeeded and we want the log file + * to reflect that. + */ + if (port->hba->compat_realm) + { + /* SAM-compatible format. */ + authn_id = psprintf("%s\\%s", domainname, accountname); + } + else + { + /* Kerberos principal format. */ + authn_id = psprintf("%s@%s", accountname, domainname); + } + + set_authn_id(port, authn_id); + pfree(authn_id); + /* * Compare realm/domain if requested. In SSPI, always compare case * insensitive. @@ -2343,8 +2363,15 @@ ident_inet(hbaPort *port) pg_freeaddrinfo_all(local_addr.addr.ss_family, la); if (ident_return) - /* Success! Check the usermap */ + { + /* + * Success! Store the identity, then check the usermap. Note that + * setting the authenticated identity is done before checking the + * usermap, because at this point authentication has succeeded. + */ + set_authn_id(port, ident_user); return check_usermap(port->hba->usermap, port->user_name, ident_user, false); + } return STATUS_ERROR; } @@ -2368,7 +2395,6 @@ auth_peer(hbaPort *port) gid_t gid; #ifndef WIN32 struct passwd *pw; - char *peer_user; int ret; #endif @@ -2400,8 +2426,12 @@ auth_peer(hbaPort *port) return STATUS_ERROR; } - /* Make a copy of static getpw*() result area. */ - peer_user = pstrdup(pw->pw_name); + /* + * Make a copy of static getpw*() result area; this is our authenticated + * identity. Set it before calling check_usermap, because authentication + * has already succeeded and we want the log file to reflect that. + */ + set_authn_id(port, pw->pw_name); /* * GPDB: check for port->hba == NULL here, because auth_peer is used @@ -2409,9 +2439,7 @@ auth_peer(hbaPort *port) * from internal_client_authentication(). */ ret = check_usermap(port->hba ? port->hba->usermap : NULL, port->user_name, - peer_user, false); - - pfree(peer_user); + port->authn_id, false); return ret; #else @@ -2509,9 +2537,10 @@ pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, reply[i].resp_retcode = PAM_SUCCESS; break; default: - elog(LOG, "unsupported PAM conversation %d/\"%s\"", - msg[i]->msg_style, - msg[i]->msg ? msg[i]->msg : "(none)"); + ereport(LOG, + (errmsg("unsupported PAM conversation %d/\"%s\"", + msg[i]->msg_style, + msg[i]->msg ? msg[i]->msg : "(none)"))); goto fail; } } @@ -2667,6 +2696,9 @@ CheckPAMAuth(Port *port, const char *user, const char *password) pam_passwd = NULL; /* Unset pam_passwd */ + if (retval == PAM_SUCCESS) + set_authn_id(port, user); + return (retval == PAM_SUCCESS ? STATUS_OK : STATUS_ERROR); } #endif /* USE_PAM */ @@ -2702,6 +2734,7 @@ CheckBSDAuth(Port *port, char *user) if (!retval) return STATUS_ERROR; + set_authn_id(port, user); return STATUS_OK; } #endif /* USE_BSD_AUTH */ @@ -2900,7 +2933,7 @@ InitializeLDAPConnection(Port *port, LDAP **ldap) ldap_unbind(*ldap); return STATUS_ERROR; } - _ldap_start_tls_sA = (__ldap_start_tls_sA) GetProcAddress(ldaphandle, "ldap_start_tls_sA"); + _ldap_start_tls_sA = (__ldap_start_tls_sA) (pg_funcptr_t) GetProcAddress(ldaphandle, "ldap_start_tls_sA"); if (_ldap_start_tls_sA == NULL) { ereport(LOG, @@ -3207,6 +3240,9 @@ CheckLDAPAuth(Port *port) return STATUS_ERROR; } + /* Save the original bind DN as the authenticated identity. */ + set_authn_id(port, fulluser); + ldap_unbind(ldap); pfree(passwd); pfree(fulluser); @@ -3246,12 +3282,23 @@ static int CheckCertAuth(Port *port) { int status_check_usermap = STATUS_ERROR; + char *peer_username = NULL; Assert(port->ssl); + /* select the correct field to compare */ + switch (port->hba->clientcertname) + { + case clientCertDN: + peer_username = port->peer_dn; + break; + case clientCertCN: + peer_username = port->peer_cn; + } + /* Make sure we have received a username in the certificate */ - if (port->peer_cn == NULL || - strlen(port->peer_cn) <= 0) + if (peer_username == NULL || + strlen(peer_username) <= 0) { ereport(LOG, (errmsg("certificate authentication failed for user \"%s\": client certificate contains no user name", @@ -3259,8 +3306,32 @@ CheckCertAuth(Port *port) return STATUS_ERROR; } - /* Just pass the certificate cn to the usermap check */ - status_check_usermap = check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false); + if (port->hba->auth_method == uaCert) + { + /* + * For cert auth, the client's Subject DN is always our authenticated + * identity, even if we're only using its CN for authorization. Set + * it now, rather than waiting for check_usermap() below, because + * authentication has already succeeded and we want the log file to + * reflect that. + */ + if (!port->peer_dn) + { + /* + * This should not happen as both peer_dn and peer_cn should be + * set in this context. + */ + ereport(LOG, + (errmsg("certificate authentication failed for user \"%s\": unable to retrieve subject DN", + port->user_name))); + return STATUS_ERROR; + } + + set_authn_id(port, port->peer_dn); + } + + /* Just pass the certificate cn/dn to the usermap check */ + status_check_usermap = check_usermap(port->hba->usermap, port->user_name, peer_username, false); if (status_check_usermap != STATUS_OK) { /* @@ -3270,9 +3341,18 @@ CheckCertAuth(Port *port) */ if (port->hba->clientcert == clientCertFull && port->hba->auth_method != uaCert) { - ereport(LOG, - (errmsg("certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch", - port->user_name))); + switch (port->hba->clientcertname) + { + case clientCertDN: + ereport(LOG, + (errmsg("certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch", + port->user_name))); + break; + case clientCertCN: + ereport(LOG, + (errmsg("certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch", + port->user_name))); + } } } return status_check_usermap; @@ -3421,6 +3501,8 @@ CheckRADIUSAuth(Port *port) */ if (ret == STATUS_OK) { + set_authn_id(port, port->user_name); + pfree(passwd); return STATUS_OK; } diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index 5af4bc2161f9..d688904f43c8 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -3,7 +3,7 @@ * be-fsstubs.c * Builtin functions for open/close/read/write operations on large objects * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/libpq/be-gssapi-common.c b/src/backend/libpq/be-gssapi-common.c index b320f81606e9..b30611f90bf5 100644 --- a/src/backend/libpq/be-gssapi-common.c +++ b/src/backend/libpq/be-gssapi-common.c @@ -3,7 +3,7 @@ * be-gssapi-common.c * Common code for GSSAPI authentication and encryption * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,8 +17,9 @@ #include "libpq/be-gssapi-common.h" /* - * Helper function for getting all strings of a GSSAPI error (of specified - * stat). Call once for GSS_CODE and once for MECH_CODE. + * Fetch all errors of a specific type and append to "s" (buffer of size len). + * If we obtain more than one string, separate them with spaces. + * Call once for GSS_CODE and once for MECH_CODE. */ static void pg_GSS_error_int(char *s, size_t len, OM_uint32 stat, int type) @@ -28,35 +29,54 @@ pg_GSS_error_int(char *s, size_t len, OM_uint32 stat, int type) OM_uint32 lmin_s, msg_ctx = 0; - gmsg.value = NULL; - gmsg.length = 0; - do { - gss_display_status(&lmin_s, stat, type, - GSS_C_NO_OID, &msg_ctx, &gmsg); - strlcpy(s + i, gmsg.value, len - i); + if (gss_display_status(&lmin_s, stat, type, GSS_C_NO_OID, + &msg_ctx, &gmsg) != GSS_S_COMPLETE) + break; + if (i > 0) + { + if (i < len) + s[i] = ' '; + i++; + } + if (i < len) + memcpy(s + i, gmsg.value, Min(len - i, gmsg.length)); i += gmsg.length; gss_release_buffer(&lmin_s, &gmsg); } - while (msg_ctx && i < len); + while (msg_ctx); - if (msg_ctx || i == len) - ereport(WARNING, - (errmsg_internal("incomplete GSS error report"))); + /* add nul termination */ + if (i < len) + s[i] = '\0'; + else + { + elog(COMMERROR, "incomplete GSS error report"); + s[len - 1] = '\0'; + } } /* - * Fetch and report all error messages from GSSAPI. To avoid allocation, - * total error size is capped (at 128 bytes for each of major and minor). No - * known mechanisms will produce error messages beyond this cap. + * Report the GSSAPI error described by maj_stat/min_stat. + * + * errmsg should be an already-translated primary error message. + * The GSSAPI info is appended as errdetail. + * + * The error is always reported with elevel COMMERROR; we daren't try to + * send it to the client, as that'd likely lead to infinite recursion + * when elog.c tries to write to the client. + * + * To avoid memory allocation, total error size is capped (at 128 bytes for + * each of major and minor). No known mechanisms will produce error messages + * beyond this cap. */ /* * In GPDB backend, we also link with fe-gssapi-common.o, which contains * this same function. Rename it with a "_be" suffix here to avoid linker error. */ void -pg_GSS_error_be(int severity, const char *errmsg, +pg_GSS_error_be(const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat) { char msg_major[128], @@ -72,7 +92,7 @@ pg_GSS_error_be(int severity, const char *errmsg, * errmsg_internal, since translation of the first part must be done * before calling this function anyway. */ - ereport(severity, + ereport(COMMERROR, (errmsg_internal("%s", errmsg), errdetail_internal("%s: %s", msg_major, msg_minor))); } diff --git a/src/backend/libpq/be-secure-common.c b/src/backend/libpq/be-secure-common.c index 94cdf4c8874d..a212308666a9 100644 --- a/src/backend/libpq/be-secure-common.c +++ b/src/backend/libpq/be-secure-common.c @@ -8,7 +8,7 @@ * communications code calls, this file contains support routines that are * used by the library-specific implementations such as be-secure-openssl.c. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/libpq/be-secure-gssapi.c b/src/backend/libpq/be-secure-gssapi.c index a42783926928..7ba04d53b461 100644 --- a/src/backend/libpq/be-secure-gssapi.c +++ b/src/backend/libpq/be-secure-gssapi.c @@ -3,7 +3,7 @@ * be-secure-gssapi.c * GSSAPI encryption support * - * Portions Copyright (c) 2018-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2018-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/libpq/be-secure-gssapi.c @@ -21,6 +21,7 @@ #include "libpq/pqformat.h" #include "miscadmin.h" #include "pgstat.h" +#include "utils/memutils.h" /* @@ -81,10 +82,14 @@ static uint32 PqGSSMaxPktSize; /* Maximum size we can encrypt and fit the * transport negotiation is complete). * * On success, returns the number of data bytes consumed (possibly less than - * len). On failure, returns -1 with errno set appropriately. (For fatal - * errors, we may just elog and exit, if errno wouldn't be sufficient to - * describe the error.) For retryable errors, caller should call again - * (passing the same data) once the socket is ready. + * len). On failure, returns -1 with errno set appropriately. For retryable + * errors, caller should call again (passing the same data) once the socket + * is ready. + * + * Dealing with fatal errors here is a bit tricky: we can't invoke elog(FATAL) + * since it would try to write to the client, probably resulting in infinite + * recursion. Instead, use elog(COMMERROR) to log extra info about the + * failure if necessary, and then return an errno indicating connection loss. */ ssize_t be_gssapi_write(Port *port, void *ptr, size_t len) @@ -108,8 +113,11 @@ be_gssapi_write(Port *port, void *ptr, size_t len) * again, so if it offers a len less than that, something is wrong. */ if (len < PqGSSSendConsumed) - elog(FATAL, "GSSAPI caller failed to retransmit all data needing to be retried"); - + { + elog(COMMERROR, "GSSAPI caller failed to retransmit all data needing to be retried"); + errno = ECONNRESET; + return -1; + } /* Discount whatever source data we already encrypted. */ bytes_to_encrypt = len - PqGSSSendConsumed; bytes_encrypted = PqGSSSendConsumed; @@ -192,24 +200,34 @@ be_gssapi_write(Port *port, void *ptr, size_t len) major = gss_wrap(&minor, gctx, 1, GSS_C_QOP_DEFAULT, &input, &conf_state, &output); if (major != GSS_S_COMPLETE) - pg_GSS_error_be(FATAL, gettext_noop("GSSAPI wrap error"), major, minor); - + { + pg_GSS_error_be(_("GSSAPI wrap error"), major, minor); + errno = ECONNRESET; + return -1; + } if (conf_state == 0) - ereport(FATAL, + { + ereport(COMMERROR, (errmsg("outgoing GSSAPI message would not use confidentiality"))); - + errno = ECONNRESET; + return -1; + } if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)) - ereport(FATAL, + { + ereport(COMMERROR, (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)", (size_t) output.length, PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)))); + errno = ECONNRESET; + return -1; + } bytes_encrypted += input.length; bytes_to_encrypt -= input.length; PqGSSSendConsumed += input.length; /* 4 network-order bytes of length, then payload */ - netlen = htonl(output.length); + netlen = pg_hton32(output.length); memcpy(PqGSSSendBuffer + PqGSSSendLength, &netlen, sizeof(uint32)); PqGSSSendLength += sizeof(uint32); @@ -234,9 +252,11 @@ be_gssapi_write(Port *port, void *ptr, size_t len) * transport negotiation is complete). * * Returns the number of data bytes read, or on failure, returns -1 - * with errno set appropriately. (For fatal errors, we may just elog and - * exit, if errno wouldn't be sufficient to describe the error.) For - * retryable errors, caller should call again once the socket is ready. + * with errno set appropriately. For retryable errors, caller should call + * again once the socket is ready. + * + * We treat fatal errors the same as in be_gssapi_write(), even though the + * argument about infinite recursion doesn't apply here. */ ssize_t be_gssapi_read(Port *port, void *ptr, size_t len) @@ -323,13 +343,17 @@ be_gssapi_read(Port *port, void *ptr, size_t len) } /* Decode the packet length and check for overlength packet */ - input.length = ntohl(*(uint32 *) PqGSSRecvBuffer); + input.length = pg_ntoh32(*(uint32 *) PqGSSRecvBuffer); if (input.length > PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)) - ereport(FATAL, + { + ereport(COMMERROR, (errmsg("oversize GSSAPI packet sent by the client (%zu > %zu)", (size_t) input.length, PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)))); + errno = ECONNRESET; + return -1; + } /* * Read as much of the packet as we are able to on this call into @@ -361,12 +385,18 @@ be_gssapi_read(Port *port, void *ptr, size_t len) major = gss_unwrap(&minor, gctx, &input, &output, &conf_state, NULL); if (major != GSS_S_COMPLETE) - pg_GSS_error_be(FATAL, gettext_noop("GSSAPI unwrap error"), - major, minor); - + { + pg_GSS_error_be(_("GSSAPI unwrap error"), major, minor); + errno = ECONNRESET; + return -1; + } if (conf_state == 0) - ereport(FATAL, + { + ereport(COMMERROR, (errmsg("incoming GSSAPI message did not use confidentiality"))); + errno = ECONNRESET; + return -1; + } memcpy(PqGSSResultBuffer, output.value, output.length); PqGSSResultLength = output.length; @@ -468,6 +498,12 @@ secure_open_gssapi(Port *port) OM_uint32 major, minor; + /* + * Allocate subsidiary Port data for GSSAPI operations. + */ + port->gss = (pg_gssinfo *) + MemoryContextAllocZero(TopMemoryContext, sizeof(pg_gssinfo)); + /* * Allocate buffers and initialize state variables. By malloc'ing the * buffers at this point, we avoid wasting static data space in processes @@ -489,8 +525,16 @@ secure_open_gssapi(Port *port) * Use the configured keytab, if there is one. Unfortunately, Heimdal * doesn't support the cred store extensions, so use the env var. */ - if (pg_krb_server_keyfile != NULL && strlen(pg_krb_server_keyfile) > 0) - setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1); + if (pg_krb_server_keyfile != NULL && pg_krb_server_keyfile[0] != '\0') + { + if (setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1) != 0) + { + /* The only likely failure cause is OOM, so use that errcode */ + ereport(FATAL, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("could not set environment: %m"))); + } + } while (true) { @@ -509,7 +553,7 @@ secure_open_gssapi(Port *port) /* * Get the length for this packet from the length header. */ - input.length = ntohl(*(uint32 *) PqGSSRecvBuffer); + input.length = pg_ntoh32(*(uint32 *) PqGSSRecvBuffer); /* Done with the length, reset our buffer */ PqGSSRecvLength = 0; @@ -521,10 +565,13 @@ secure_open_gssapi(Port *port) * Verify on our side that the client doesn't do something funny. */ if (input.length > PQ_GSS_RECV_BUFFER_SIZE) - ereport(FATAL, + { + ereport(COMMERROR, (errmsg("oversize GSSAPI packet sent by the client (%zu > %d)", (size_t) input.length, PQ_GSS_RECV_BUFFER_SIZE))); + return -1; + } /* * Get the rest of the packet so we can pass it to GSSAPI to accept @@ -544,7 +591,7 @@ secure_open_gssapi(Port *port) NULL, NULL); if (GSS_ERROR(major)) { - pg_GSS_error_be(ERROR, gettext_noop("could not accept GSSAPI security context"), + pg_GSS_error_be(_("could not accept GSSAPI security context"), major, minor); gss_release_buffer(&minor, &output); return -1; @@ -567,13 +614,17 @@ secure_open_gssapi(Port *port) */ if (output.length > 0) { - uint32 netlen = htonl(output.length); + uint32 netlen = pg_hton32(output.length); if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)) - ereport(FATAL, + { + ereport(COMMERROR, (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)", (size_t) output.length, PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)))); + gss_release_buffer(&minor, &output); + return -1; + } memcpy(PqGSSSendBuffer, (char *) &netlen, sizeof(uint32)); PqGSSSendLength += sizeof(uint32); @@ -634,8 +685,10 @@ secure_open_gssapi(Port *port) &PqGSSMaxPktSize); if (GSS_ERROR(major)) - pg_GSS_error_be(FATAL, gettext_noop("GSSAPI size check error"), - major, minor); + { + pg_GSS_error_be(_("GSSAPI size check error"), major, minor); + return -1; + } port->gss->enc = true; @@ -667,12 +720,13 @@ be_gssapi_get_enc(Port *port) } /* - * Return the GSSAPI principal used for authentication on this connection. + * Return the GSSAPI principal used for authentication on this connection + * (NULL if we did not perform GSSAPI authentication). */ const char * be_gssapi_get_princ(Port *port) { - if (!port || !port->gss->auth) + if (!port || !port->gss) return NULL; return port->gss->princ; diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 8b21ff4065c5..db9580c20df7 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -4,7 +4,7 @@ * functions for OpenSSL support in the backend. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -81,7 +81,6 @@ static const char *ssl_protocol_version_to_string(int v); int be_tls_init(bool isServerStart) { - STACK_OF(X509_NAME) * root_cert_list = NULL; SSL_CTX *context; int ssl_ver_min = -1; int ssl_ver_max = -1; @@ -100,6 +99,10 @@ be_tls_init(bool isServerStart) } /* + * Create a new SSL context into which we'll load all the configuration + * settings. If we fail partway through, we can avoid memory leakage by + * freeing this context; we don't install it as active until the end. + * * We use SSLv23_method() because it can negotiate use of the highest * mutually supported protocol version, while alternatives like * TLSv1_2_method() permit only one specific version. Note that we don't @@ -181,6 +184,7 @@ be_tls_init(bool isServerStart) if (ssl_ver_min == -1) { ereport(isServerStart ? FATAL : LOG, + /*- translator: first %s is a GUC option name, second %s is its value */ (errmsg("\"%s\" setting \"%s\" not supported by this build", "ssl_min_protocol_version", GetConfigOption("ssl_min_protocol_version", @@ -203,6 +207,7 @@ be_tls_init(bool isServerStart) if (ssl_ver_max == -1) { ereport(isServerStart ? FATAL : LOG, + /*- translator: first %s is a GUC option name, second %s is its value */ (errmsg("\"%s\" setting \"%s\" not supported by this build", "ssl_max_protocol_version", GetConfigOption("ssl_max_protocol_version", @@ -243,6 +248,19 @@ be_tls_init(bool isServerStart) /* disallow SSL session caching, too */ SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF); + /* disallow SSL compression */ + SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION); + +#ifdef SSL_OP_NO_RENEGOTIATION + + /* + * Disallow SSL renegotiation, option available since 1.1.0h. This + * concerns only TLSv1.2 and older protocol versions, as TLSv1.3 has no + * support for renegotiation. + */ + SSL_CTX_set_options(context, SSL_OP_NO_RENEGOTIATION); +#endif + /* set up ephemeral DH and ECDH keys */ if (!initialize_dh(context, isServerStart)) goto error; @@ -267,6 +285,8 @@ be_tls_init(bool isServerStart) */ if (ssl_ca_file[0]) { + STACK_OF(X509_NAME) * root_cert_list; + if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 || (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL) { @@ -276,6 +296,25 @@ be_tls_init(bool isServerStart) ssl_ca_file, SSLerrmessage(ERR_get_error())))); goto error; } + + /* + * Tell OpenSSL to send the list of root certs we trust to clients in + * CertificateRequests. This lets a client with a keystore select the + * appropriate client certificate to send to us. Also, this ensures + * that the SSL context will "own" the root_cert_list and remember to + * free it when no longer needed. + */ + SSL_CTX_set_client_CA_list(context, root_cert_list); + + /* + * Always ask for SSL client cert, but don't fail if it's not + * presented. We might fail such connections later, depending on what + * we find in pg_hba.conf. + */ + SSL_CTX_set_verify(context, + (SSL_VERIFY_PEER | + SSL_VERIFY_CLIENT_ONCE), + verify_cb); } /*---------- @@ -283,19 +322,22 @@ be_tls_init(bool isServerStart) * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html *---------- */ - if (ssl_crl_file[0]) + if (ssl_crl_file[0] || ssl_crl_dir[0]) { X509_STORE *cvstore = SSL_CTX_get_cert_store(context); if (cvstore) { /* Set the flags to check against the complete CRL chain */ - if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1) + if (X509_STORE_load_locations(cvstore, + ssl_crl_file[0] ? ssl_crl_file : NULL, + ssl_crl_dir[0] ? ssl_crl_dir : NULL) + == 1) { X509_STORE_set_flags(cvstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); } - else + else if (ssl_crl_dir[0] == 0) { ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), @@ -303,29 +345,26 @@ be_tls_init(bool isServerStart) ssl_crl_file, SSLerrmessage(ERR_get_error())))); goto error; } + else if (ssl_crl_file[0] == 0) + { + ereport(isServerStart ? FATAL : LOG, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("could not load SSL certificate revocation list directory \"%s\": %s", + ssl_crl_dir, SSLerrmessage(ERR_get_error())))); + goto error; + } + else + { + ereport(isServerStart ? FATAL : LOG, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s", + ssl_crl_file, ssl_crl_dir, + SSLerrmessage(ERR_get_error())))); + goto error; + } } } - if (ssl_ca_file[0]) - { - /* - * Always ask for SSL client cert, but don't fail if it's not - * presented. We might fail such connections later, depending on what - * we find in pg_hba.conf. - */ - SSL_CTX_set_verify(context, - (SSL_VERIFY_PEER | - SSL_VERIFY_CLIENT_ONCE), - verify_cb); - - /* - * Tell OpenSSL to send the list of root certs we trust to clients in - * CertificateRequests. This lets a client with a keystore select the - * appropriate client certificate to send to us. - */ - SSL_CTX_set_client_CA_list(context, root_cert_list); - } - /* * Success! Replace any existing SSL_context. */ @@ -344,6 +383,7 @@ be_tls_init(bool isServerStart) return 0; + /* Clean up by releasing working context. */ error: if (context) SSL_CTX_free(context); @@ -379,6 +419,9 @@ be_tls_open_server(Port *port) return -1; } + /* set up debugging/info callback */ + SSL_CTX_set_info_callback(SSL_context, info_cb); + if (!(port->ssl = SSL_new(SSL_context))) { ereport(COMMERROR, @@ -518,22 +561,26 @@ be_tls_open_server(Port *port) /* Get client certificate, if available. */ port->peer = SSL_get_peer_certificate(port->ssl); - /* and extract the Common Name from it. */ + /* and extract the Common Name and Distinguished Name from it. */ port->peer_cn = NULL; + port->peer_dn = NULL; port->peer_cert_valid = false; if (port->peer != NULL) { int len; + X509_NAME *x509name = X509_get_subject_name(port->peer); + char *peer_dn; + BIO *bio = NULL; + BUF_MEM *bio_buf = NULL; - len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer), - NID_commonName, NULL, 0); + len = X509_NAME_get_text_by_NID(x509name, NID_commonName, NULL, 0); if (len != -1) { char *peer_cn; peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1); - r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer), - NID_commonName, peer_cn, len + 1); + r = X509_NAME_get_text_by_NID(x509name, NID_commonName, peer_cn, + len + 1); peer_cn[len] = '\0'; if (r != len) { @@ -557,12 +604,51 @@ be_tls_open_server(Port *port) port->peer_cn = peer_cn; } + + bio = BIO_new(BIO_s_mem()); + if (!bio) + { + pfree(port->peer_cn); + port->peer_cn = NULL; + return -1; + } + + /* + * RFC2253 is the closest thing to an accepted standard format for + * DNs. We have documented how to produce this format from a + * certificate. It uses commas instead of slashes for delimiters, + * which make regular expression matching a bit easier. Also note that + * it prints the Subject fields in reverse order. + */ + X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253); + if (BIO_get_mem_ptr(bio, &bio_buf) <= 0) + { + BIO_free(bio); + pfree(port->peer_cn); + port->peer_cn = NULL; + return -1; + } + peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1); + memcpy(peer_dn, bio_buf->data, bio_buf->length); + len = bio_buf->length; + BIO_free(bio); + peer_dn[len] = '\0'; + if (len != strlen(peer_dn)) + { + ereport(COMMERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("SSL certificate's distinguished name contains embedded null"))); + pfree(peer_dn); + pfree(port->peer_cn); + port->peer_cn = NULL; + return -1; + } + + port->peer_dn = peer_dn; + port->peer_cert_valid = true; } - /* set up debugging/info callback */ - SSL_CTX_set_info_callback(SSL_context, info_cb); - return 0; } @@ -588,6 +674,12 @@ be_tls_close(Port *port) pfree(port->peer_cn); port->peer_cn = NULL; } + + if (port->peer_dn) + { + pfree(port->peer_dn); + port->peer_dn = NULL; + } } ssize_t @@ -892,6 +984,7 @@ load_dh_file(char *filename, bool isServerStart) (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid DH parameters: %s", SSLerrmessage(ERR_get_error())))); + DH_free(dh); return NULL; } if (codes & DH_CHECK_P_NOT_PRIME) @@ -899,6 +992,7 @@ load_dh_file(char *filename, bool isServerStart) ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid DH parameters: p is not prime"))); + DH_free(dh); return NULL; } if ((codes & DH_NOT_SUITABLE_GENERATOR) && @@ -907,6 +1001,7 @@ load_dh_file(char *filename, bool isServerStart) ereport(isServerStart ? FATAL : LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid DH parameters: neither suitable generator or safe prime"))); + DH_free(dh); return NULL; } @@ -997,39 +1092,43 @@ verify_cb(int ok, X509_STORE_CTX *ctx) static void info_cb(const SSL *ssl, int type, int args) { + const char *desc; + + desc = SSL_state_string_long(ssl); + switch (type) { case SSL_CB_HANDSHAKE_START: ereport(DEBUG4, - (errmsg_internal("SSL: handshake start"))); + (errmsg_internal("SSL: handshake start: \"%s\"", desc))); break; case SSL_CB_HANDSHAKE_DONE: ereport(DEBUG4, - (errmsg_internal("SSL: handshake done"))); + (errmsg_internal("SSL: handshake done: \"%s\"", desc))); break; case SSL_CB_ACCEPT_LOOP: ereport(DEBUG4, - (errmsg_internal("SSL: accept loop"))); + (errmsg_internal("SSL: accept loop: \"%s\"", desc))); break; case SSL_CB_ACCEPT_EXIT: ereport(DEBUG4, - (errmsg_internal("SSL: accept exit (%d)", args))); + (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc))); break; case SSL_CB_CONNECT_LOOP: ereport(DEBUG4, - (errmsg_internal("SSL: connect loop"))); + (errmsg_internal("SSL: connect loop: \"%s\"", desc))); break; case SSL_CB_CONNECT_EXIT: ereport(DEBUG4, - (errmsg_internal("SSL: connect exit (%d)", args))); + (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc))); break; case SSL_CB_READ_ALERT: ereport(DEBUG4, - (errmsg_internal("SSL: read alert (0x%04x)", args))); + (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc))); break; case SSL_CB_WRITE_ALERT: ereport(DEBUG4, - (errmsg_internal("SSL: write alert (0x%04x)", args))); + (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc))); break; } } @@ -1156,15 +1255,6 @@ be_tls_get_cipher_bits(Port *port) return 0; } -bool -be_tls_get_compression(Port *port) -{ - if (port->ssl) - return (SSL_get_current_compression(port->ssl) != NULL); - else - return false; -} - const char * be_tls_get_version(Port *port) { @@ -1298,15 +1388,28 @@ X509_NAME_to_cstring(X509_NAME *name) char *dp; char *result; + if (membuf == NULL) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("failed to create BIO"))); + (void) BIO_set_close(membuf, BIO_CLOSE); for (i = 0; i < count; i++) { e = X509_NAME_get_entry(name, i); nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e)); + if (nid == NID_undef) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not get NID for ASN1_OBJECT object"))); v = X509_NAME_ENTRY_get_data(e); field_name = OBJ_nid2sn(nid); - if (!field_name) + if (field_name == NULL) field_name = OBJ_nid2ln(nid); + if (field_name == NULL) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid))); BIO_printf(membuf, "/%s=", field_name); ASN1_STRING_print_ex(membuf, v, ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB) @@ -1322,7 +1425,8 @@ X509_NAME_to_cstring(X509_NAME *name) result = pstrdup(dp); if (dp != sp) pfree(dp); - BIO_free(membuf); + if (BIO_free(membuf) != 1) + elog(ERROR, "could not free OpenSSL BIO structure"); return result; } diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index 2ae507a90255..8ef083200ac2 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -6,7 +6,7 @@ * message integrity and endpoint authentication. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -42,6 +42,7 @@ char *ssl_cert_file; char *ssl_key_file; char *ssl_ca_file; char *ssl_crl_file; +char *ssl_crl_dir; char *ssl_dh_params_file; char *ssl_passphrase_command; bool ssl_passphrase_command_supports_reload; @@ -119,8 +120,9 @@ secure_open_server(Port *port) r = be_tls_open_server(port); ereport(DEBUG2, - (errmsg("SSL connection from \"%s\"", - port->peer_cn ? port->peer_cn : "(anonymous)"))); + (errmsg_internal("SSL connection from DN:\"%s\" CN:\"%s\"", + port->peer_dn ? port->peer_dn : "(anonymous)", + port->peer_cn ? port->peer_cn : "(anonymous)"))); #endif return r; @@ -160,7 +162,7 @@ secure_read(Port *port, void *ptr, size_t len) else #endif #ifdef ENABLE_GSS - if (port->gss->enc) + if (port->gss && port->gss->enc) { n = be_gssapi_read(port, ptr, len); waitfor = WL_SOCKET_READABLE; @@ -179,7 +181,7 @@ secure_read(Port *port, void *ptr, size_t len) Assert(waitfor); - ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL); + ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL); WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1, WAIT_EVENT_CLIENT_READ); @@ -273,7 +275,7 @@ secure_write(Port *port, void *ptr, size_t len) else #endif #ifdef ENABLE_GSS - if (port->gss->enc) + if (port->gss && port->gss->enc) { n = be_gssapi_write(port, ptr, len); waitfor = WL_SOCKET_WRITEABLE; @@ -291,7 +293,7 @@ secure_write(Port *port, void *ptr, size_t len) Assert(waitfor); - ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL); + ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL); WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1, WAIT_EVENT_CLIENT_WRITE); diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 17b91ac9e605..3fcad991a7e6 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -4,7 +4,7 @@ * Functions for dealing with encrypted passwords stored in * pg_authid.rolpassword. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/crypt.c diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 0325c057672f..fb954ca34c71 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -5,7 +5,7 @@ * wherein you authenticate a user by seeing what IP address the system * says he comes from and choosing authentication method based on it). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,6 +29,7 @@ #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/ip.h" +#include "common/string.h" #include "funcapi.h" #include "libpq/ifaddr.h" #include "libpq/libpq.h" @@ -54,7 +55,6 @@ #define MAX_TOKEN 256 -#define MAX_LINE 8192 /* callback data for check_network_callback */ typedef struct check_network_data @@ -144,8 +144,6 @@ static List *tokenize_inc_file(List *tokens, const char *outer_filename, const char *inc_filename, int elevel, char **err_msg); static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg); -static bool verify_option_list_length(List *options, const char *optionname, - List *comparelist, const char *comparename, int line_num); static ArrayType *gethba_options(HbaLine *hba); static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, int lineno, HbaLine *hba, const char *err_msg); @@ -166,11 +164,19 @@ pg_isblank(const char c) /* * Grab one token out of the string pointed to by *lineptr. * - * Tokens are strings of non-blank - * characters bounded by blank characters, commas, beginning of line, and - * end of line. Blank means space or tab. Tokens can be delimited by - * double quotes (this allows the inclusion of blanks, but not newlines). - * Comments (started by an unquoted '#') are skipped. + * Tokens are strings of non-blank characters bounded by blank characters, + * commas, beginning of line, and end of line. Blank means space or tab. + * + * Tokens can be delimited by double quotes (this allows the inclusion of + * blanks or '#', but not newlines). As in SQL, write two double-quotes + * to represent a double quote. + * + * Comments (started by an unquoted '#') are skipped, i.e. the remainder + * of the line is ignored. + * + * (Note that line continuation processing happens before tokenization. + * Thus, if a continuation occurs within quoted text or a comment, the + * quoted text or comment is considered to continue to the next line.) * * The token, if any, is returned at *buf (a buffer of size bufsz), and * *lineptr is advanced past the token. @@ -470,6 +476,7 @@ static MemoryContext tokenize_file(const char *filename, FILE *file, List **tok_lines, int elevel) { int line_number = 1; + StringInfoData buf; MemoryContext linecxt; MemoryContext oldcxt; @@ -478,47 +485,60 @@ tokenize_file(const char *filename, FILE *file, List **tok_lines, int elevel) ALLOCSET_SMALL_SIZES); oldcxt = MemoryContextSwitchTo(linecxt); + initStringInfo(&buf); + *tok_lines = NIL; while (!feof(file) && !ferror(file)) { - char rawline[MAX_LINE]; char *lineptr; List *current_line = NIL; char *err_msg = NULL; + int last_backslash_buflen = 0; + int continuations = 0; - if (!fgets(rawline, sizeof(rawline), file)) + /* Collect the next input line, handling backslash continuations */ + resetStringInfo(&buf); + + while (pg_get_line_append(file, &buf)) { - int save_errno = errno; + /* Strip trailing newline, including \r in case we're on Windows */ + buf.len = pg_strip_crlf(buf.data); + + /* + * Check for backslash continuation. The backslash must be after + * the last place we found a continuation, else two backslashes + * followed by two \n's would behave surprisingly. + */ + if (buf.len > last_backslash_buflen && + buf.data[buf.len - 1] == '\\') + { + /* Continuation, so strip it and keep reading */ + buf.data[--buf.len] = '\0'; + last_backslash_buflen = buf.len; + continuations++; + continue; + } - if (!ferror(file)) - break; /* normal EOF */ + /* Nope, so we have the whole line */ + break; + } + + if (ferror(file)) + { /* I/O error! */ + int save_errno = errno; + ereport(elevel, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", filename))); err_msg = psprintf("could not read file \"%s\": %s", filename, strerror(save_errno)); - rawline[0] = '\0'; - } - if (strlen(rawline) == MAX_LINE - 1) - { - /* Line too long! */ - ereport(elevel, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("authentication file line too long"), - errcontext("line %d of configuration file \"%s\"", - line_number, filename))); - err_msg = "authentication file line too long"; + break; } - /* Strip trailing linebreak from rawline */ - lineptr = rawline + strlen(rawline) - 1; - while (lineptr >= rawline && (*lineptr == '\n' || *lineptr == '\r')) - *lineptr-- = '\0'; - /* Parse fields */ - lineptr = rawline; + lineptr = buf.data; while (*lineptr && err_msg == NULL) { List *current_field; @@ -538,12 +558,12 @@ tokenize_file(const char *filename, FILE *file, List **tok_lines, int elevel) tok_line = (TokenizedLine *) palloc(sizeof(TokenizedLine)); tok_line->fields = current_line; tok_line->line_num = line_number; - tok_line->raw_line = pstrdup(rawline); + tok_line->raw_line = pstrdup(buf.data); tok_line->err_msg = err_msg; *tok_lines = lappend(*tok_lines, tok_line); } - line_number++; + line_number += continuations + 1; } MemoryContextSwitchTo(oldcxt); @@ -835,7 +855,8 @@ check_same_host_or_net(SockAddr *raddr, IPCompareMethod method) errno = 0; if (pg_foreach_ifaddr(check_network_callback, &cn) < 0) { - elog(LOG, "error enumerating network interfaces: %m"); + ereport(LOG, + (errmsg("error enumerating network interfaces: %m"))); return false; } @@ -1018,7 +1039,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) ereport(elevel, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("hostssl record cannot match because SSL is not supported by this build"), - errhint("Compile with --with-openssl to use SSL connections."), + errhint("Compile with --with-ssl to use SSL connections."), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); *err_msg = "hostssl record cannot match because SSL is not supported by this build"; @@ -1166,8 +1187,11 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) ret = pg_getaddrinfo_all(str, NULL, &hints, &gai_result); if (ret == 0 && gai_result) + { memcpy(&parsedline->addr, gai_result->ai_addr, gai_result->ai_addrlen); + parsedline->addrlen = gai_result->ai_addrlen; + } else if (ret == EAI_NONAME) parsedline->hostname = str; else @@ -1216,6 +1240,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) token->string); return NULL; } + parsedline->masklen = parsedline->addrlen; pfree(str); } else if (!parsedline->hostname) @@ -1266,6 +1291,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) memcpy(&parsedline->mask, gai_result->ai_addr, gai_result->ai_addrlen); + parsedline->masklen = gai_result->ai_addrlen; pg_freeaddrinfo_all(hints.ai_family, gai_result); if (parsedline->addr.ss_family != parsedline->mask.ss_family) @@ -1419,19 +1445,6 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) *err_msg = "gssapi authentication is not supported on local sockets"; return NULL; } - if (parsedline->conntype == ctHostGSS && - parsedline->auth_method != uaGSS && - parsedline->auth_method != uaReject && - parsedline->auth_method != uaTrust) - { - ereport(elevel, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("GSSAPI encryption only supports gss, trust, or reject authentication"), - errcontext("line %d of configuration file \"%s\"", - line_num, HbaFileName))); - *err_msg = "GSSAPI encryption only supports gss, trust, or reject authentication"; - return NULL; - } if (parsedline->conntype != ctLocal && parsedline->auth_method == uaPeer) @@ -1607,21 +1620,23 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) if (list_length(parsedline->radiusservers) < 1) { - ereport(LOG, + ereport(elevel, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("list of RADIUS servers cannot be empty"), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); + *err_msg = "list of RADIUS servers cannot be empty"; return NULL; } if (list_length(parsedline->radiussecrets) < 1) { - ereport(LOG, + ereport(elevel, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("list of RADIUS secrets cannot be empty"), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); + *err_msg = "list of RADIUS secrets cannot be empty"; return NULL; } @@ -1630,24 +1645,53 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) * but that's already checked above), 1 (use the same value * everywhere) or the same as the number of servers. */ - if (!verify_option_list_length(parsedline->radiussecrets, - "RADIUS secrets", - parsedline->radiusservers, - "RADIUS servers", - line_num)) + if (!(list_length(parsedline->radiussecrets) == 1 || + list_length(parsedline->radiussecrets) == list_length(parsedline->radiusservers))) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)", + list_length(parsedline->radiussecrets), + list_length(parsedline->radiusservers)), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = psprintf("the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)", + list_length(parsedline->radiussecrets), + list_length(parsedline->radiusservers)); return NULL; - if (!verify_option_list_length(parsedline->radiusports, - "RADIUS ports", - parsedline->radiusservers, - "RADIUS servers", - line_num)) + } + if (!(list_length(parsedline->radiusports) == 0 || + list_length(parsedline->radiusports) == 1 || + list_length(parsedline->radiusports) == list_length(parsedline->radiusservers))) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)", + list_length(parsedline->radiusports), + list_length(parsedline->radiusservers)), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = psprintf("the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)", + list_length(parsedline->radiusports), + list_length(parsedline->radiusservers)); return NULL; - if (!verify_option_list_length(parsedline->radiusidentifiers, - "RADIUS identifiers", - parsedline->radiusservers, - "RADIUS servers", - line_num)) + } + if (!(list_length(parsedline->radiusidentifiers) == 0 || + list_length(parsedline->radiusidentifiers) == 1 || + list_length(parsedline->radiusidentifiers) == list_length(parsedline->radiusservers))) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)", + list_length(parsedline->radiusidentifiers), + list_length(parsedline->radiusservers)), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = psprintf("the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)", + list_length(parsedline->radiusidentifiers), + list_length(parsedline->radiusservers)); return NULL; + } } /* @@ -1662,29 +1706,6 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } -static bool -verify_option_list_length(List *options, const char *optionname, - List *comparelist, const char *comparename, - int line_num) -{ - if (list_length(options) == 0 || - list_length(options) == 1 || - list_length(options) == list_length(comparelist)) - return true; - - ereport(LOG, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("the number of %s (%d) must be 1 or the same as the number of %s (%d)", - optionname, - list_length(options), - comparename, - list_length(comparelist) - ), - errcontext("line %d of configuration file \"%s\"", - line_num, HbaFileName))); - return false; -} - /* * Parse one name-value pair as an authentication option into the given * HbaLine. Return true if we successfully parse the option, false if we @@ -1723,29 +1744,25 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, *err_msg = "clientcert can only be configured for \"hostssl\" rows"; return false; } - if (strcmp(val, "1") == 0 - || strcmp(val, "verify-ca") == 0) - { - hbaline->clientcert = clientCertCA; - } - else if (strcmp(val, "verify-full") == 0) + + if (strcmp(val, "verify-full") == 0) { hbaline->clientcert = clientCertFull; } - else if (strcmp(val, "0") == 0 - || strcmp(val, "no-verify") == 0) + else if (strcmp(val, "verify-ca") == 0) { if (hbaline->auth_method == uaCert) { ereport(elevel, (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("clientcert can not be set to \"no-verify\" when using \"cert\" authentication"), + errmsg("clientcert only accepts \"verify-full\" when using \"cert\" authentication"), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); - *err_msg = "clientcert can not be set to \"no-verify\" when using \"cert\" authentication"; + *err_msg = "clientcert can only be set to \"verify-full\" when using \"cert\" authentication"; return false; } - hbaline->clientcert = clientCertOff; + + hbaline->clientcert = clientCertCA; } else { @@ -1757,6 +1774,37 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, return false; } } + else if (strcmp(name, "clientname") == 0) + { + if (hbaline->conntype != ctHostSSL) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("clientname can only be configured for \"hostssl\" rows"), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "clientname can only be configured for \"hostssl\" rows"; + return false; + } + + if (strcmp(val, "CN") == 0) + { + hbaline->clientcertname = clientCertCN; + } + else if (strcmp(val, "DN") == 0) + { + hbaline->clientcertname = clientCertDN; + } + else + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("invalid value for clientname: \"%s\"", val), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + return false; + } + } else if (strcmp(name, "pamservice") == 0) { REQUIRE_AUTH_OPTION(uaPAM, "pamservice", "pam"); @@ -2125,9 +2173,11 @@ check_hba(hbaPort *port) /* Check GSSAPI state */ #ifdef ENABLE_GSS - if (port->gss->enc && hba->conntype == ctHostNoGSS) + if (port->gss && port->gss->enc && + hba->conntype == ctHostNoGSS) continue; - else if (!port->gss->enc && hba->conntype == ctHostGSS) + else if (!(port->gss && port->gss->enc) && + hba->conntype == ctHostGSS) continue; #else if (hba->conntype == ctHostGSS) @@ -2535,20 +2585,26 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, } else { - if (pg_getnameinfo_all(&hba->addr, sizeof(hba->addr), - buffer, sizeof(buffer), - NULL, 0, - NI_NUMERICHOST) == 0) + /* + * Note: if pg_getnameinfo_all fails, it'll set buffer to + * "???", which we want to return. + */ + if (hba->addrlen > 0) { - clean_ipv6_addr(hba->addr.ss_family, buffer); + if (pg_getnameinfo_all(&hba->addr, hba->addrlen, + buffer, sizeof(buffer), + NULL, 0, + NI_NUMERICHOST) == 0) + clean_ipv6_addr(hba->addr.ss_family, buffer); addrstr = pstrdup(buffer); } - if (pg_getnameinfo_all(&hba->mask, sizeof(hba->mask), - buffer, sizeof(buffer), - NULL, 0, - NI_NUMERICHOST) == 0) + if (hba->masklen > 0) { - clean_ipv6_addr(hba->mask.ss_family, buffer); + if (pg_getnameinfo_all(&hba->mask, hba->masklen, + buffer, sizeof(buffer), + NULL, 0, + NI_NUMERICHOST) == 0) + clean_ipv6_addr(hba->mask.ss_family, buffer); maskstr = pstrdup(buffer); } } @@ -2572,14 +2628,8 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, else nulls[index++] = true; - /* - * Make sure UserAuthName[] tracks additions to the UserAuth enum - */ - StaticAssertStmt(lengthof(UserAuthName) == USER_AUTH_LAST + 1, - "UserAuthName[] must match the UserAuth enum"); - /* auth_method */ - values[index++] = CStringGetTextDatum(UserAuthName[hba->auth_method]); + values[index++] = CStringGetTextDatum(hba_authname(hba->auth_method)); /* options */ options = gethba_options(hba); @@ -3106,3 +3156,22 @@ hba_getauthmethod(hbaPort *port) { check_hba(port); } + + +/* + * Return the name of the auth method in use ("gss", "md5", "trust", etc.). + * + * The return value is statically allocated (see the UserAuthName array) and + * should not be freed. + */ +const char * +hba_authname(UserAuth auth_method) +{ + /* + * Make sure UserAuthName[] tracks additions to the UserAuth enum + */ + StaticAssertStmt(lengthof(UserAuthName) == USER_AUTH_LAST + 1, + "UserAuthName[] must match the UserAuth enum"); + + return UserAuthName[auth_method]; +} diff --git a/src/backend/libpq/ifaddr.c b/src/backend/libpq/ifaddr.c index 82adecbf06f4..75760f3b1c17 100644 --- a/src/backend/libpq/ifaddr.c +++ b/src/backend/libpq/ifaddr.c @@ -3,7 +3,7 @@ * ifaddr.c * IP netmask calculations, and enumerating network interfaces. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample index b4569a79bf5d..9e03d80411f8 100644 --- a/src/backend/libpq/pg_hba.conf.sample +++ b/src/backend/libpq/pg_hba.conf.sample @@ -18,12 +18,13 @@ # # (The uppercase items must be replaced by actual values.) # -# The first field is the connection type: "local" is a Unix-domain -# socket, "host" is either a plain or SSL-encrypted TCP/IP socket, -# "hostssl" is an SSL-encrypted TCP/IP socket, and "hostnossl" is a -# non-SSL TCP/IP socket. Similarly, "hostgssenc" uses a -# GSSAPI-encrypted TCP/IP socket, while "hostnogssenc" uses a -# non-GSSAPI socket. +# The first field is the connection type: +# - "local" is a Unix-domain socket +# - "host" is a TCP/IP socket (encrypted or not) +# - "hostssl" is a TCP/IP socket that is SSL-encrypted +# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted +# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted +# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted # # DATABASE can be "all", "sameuser", "samerole", "replication", a # database name, or a comma-separated list thereof. The "all" diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 4fd4e66c1531..f12e4fe54ba7 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -5,29 +5,19 @@ * * These routines handle the low-level details of communication between * frontend and backend. They just shove data across the communication - * channel, and are ignorant of the semantics of the data --- or would be, - * except for major brain damage in the design of the old COPY OUT protocol. - * Unfortunately, COPY OUT was designed to commandeer the communication - * channel (it just transfers data without wrapping it into messages). - * No other messages can be sent while COPY OUT is in progress; and if the - * copy is aborted by an ereport(ERROR), we need to close out the copy so that - * the frontend gets back into sync. Therefore, these routines have to be - * aware of COPY OUT state. (New COPY-OUT is message-based and does *not* - * set the DoingCopyOut flag.) + * channel, and are ignorant of the semantics of the data. * - * NOTE: generally, it's a bad idea to emit outgoing messages directly with - * pq_putbytes(), especially if the message would require multiple calls - * to send. Instead, use the routines in pqformat.c to construct the message - * in a buffer and then emit it in one call to pq_putmessage. This ensures - * that the channel will not be clogged by an incomplete message if execution - * is aborted by ereport(ERROR) partway through the message. The only - * non-libpq code that should call pq_putbytes directly is old-style COPY OUT. + * To emit an outgoing message, use the routines in pqformat.c to construct + * the message in a buffer and then emit it in one call to pq_putmessage. + * There are no functions to send raw bytes or partial messages; this + * ensures that the channel will not be clogged by an incomplete message if + * execution is aborted by ereport(ERROR) partway through the message. * * At one time, libpq was shared between frontend and backend, but now * the backend's "backend/libpq" is quite separate from "interfaces/libpq". * All that remains is similarities of names to trap the unwary... * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/pqcomm.c @@ -49,20 +39,16 @@ * * low-level I/O: * pq_getbytes - get a known number of bytes from connection - * pq_getstring - get a null terminated string from connection * pq_getmessage - get a message with length word from connection * pq_getbyte - get next byte from connection * pq_peekbyte - peek at next byte from connection - * pq_putbytes - send bytes to connection (not flushed until pq_flush) * pq_flush - flush pending output * pq_flush_if_writable - flush pending output if writable without blocking * pq_getbyte_if_available - get a byte if available without blocking * - * message-level I/O (and old-style-COPY-OUT cruft): + * message-level I/O * pq_putmessage - send a normal message (suppressed in COPY OUT mode) * pq_putmessage_noblock - buffer a normal message (suppressed in COPY OUT) - * pq_startcopyout - inform libpq that a COPY OUT transfer is beginning - * pq_endcopyout - end a COPY OUT transfer * *------------------------ */ @@ -171,7 +157,6 @@ static int PqRecvLength; /* End of data available in PqRecvBuffer */ */ static bool PqCommBusy; /* busy sending data to the client */ static bool PqCommReadingMsg; /* in the middle of reading a message */ -static bool DoingCopyOut; /* in old-protocol COPY OUT processing */ /* Internal functions */ @@ -183,8 +168,6 @@ static int socket_flush_if_writable(void); static bool socket_is_send_pending(void); static int socket_putmessage(char msgtype, const char *s, size_t len); static void socket_putmessage_noblock(char msgtype, const char *s, size_t len); -static void socket_startcopyout(void); -static void socket_endcopyout(bool errorAbort); static int internal_putbytes(const char *s, size_t len); static int internal_flush(void); @@ -199,9 +182,7 @@ static const PQcommMethods PqCommSocketMethods = { socket_flush_if_writable, socket_is_send_pending, socket_putmessage, - socket_putmessage_noblock, - socket_startcopyout, - socket_endcopyout + socket_putmessage_noblock }; const PQcommMethods *PqCommMethods = &PqCommSocketMethods; @@ -216,13 +197,15 @@ WaitEventSet *FeBeWaitSet; void pq_init(void) { + int socket_pos PG_USED_FOR_ASSERTS_ONLY; + int latch_pos PG_USED_FOR_ASSERTS_ONLY; + /* initialize state variables */ PqSendBufferSize = PQ_SEND_BUFFER_SIZE; PqSendBuffer = MemoryContextAlloc(TopMemoryContext, PqSendBufferSize); PqSendPointer = PqSendStart = PqRecvPointer = PqRecvLength = 0; PqCommBusy = false; PqCommReadingMsg = false; - DoingCopyOut = false; /* set up process-exit hook to close the socket */ on_proc_exit(socket_close, 0); @@ -244,10 +227,19 @@ pq_init(void) #endif FeBeWaitSet = CreateWaitEventSet(TopMemoryContext, 3); - AddWaitEventToSet(FeBeWaitSet, WL_SOCKET_WRITEABLE, MyProcPort->sock, + socket_pos = AddWaitEventToSet(FeBeWaitSet, WL_SOCKET_WRITEABLE, + MyProcPort->sock, NULL, NULL); + latch_pos = AddWaitEventToSet(FeBeWaitSet, WL_LATCH_SET, PGINVALID_SOCKET, + MyLatch, NULL); + AddWaitEventToSet(FeBeWaitSet, WL_POSTMASTER_DEATH, PGINVALID_SOCKET, NULL, NULL); - AddWaitEventToSet(FeBeWaitSet, WL_LATCH_SET, -1, MyLatch, NULL); - AddWaitEventToSet(FeBeWaitSet, WL_POSTMASTER_DEATH, -1, NULL, NULL); + + /* + * The event positions match the order we added them, but let's sanity + * check them to be sure. + */ + Assert(socket_pos == FeBeWaitSetSocketPos); + Assert(latch_pos == FeBeWaitSetLatchPos); } /* -------------------------------- @@ -261,8 +253,8 @@ pq_init(void) static void socket_comm_reset(void) { - /* We can abort any old-style COPY OUT, too */ - pq_endcopyout(true); + /* Do not throw away pending data, but do reset the busy flag */ + PqCommBusy = false; } /* -------------------------------- @@ -279,29 +271,26 @@ socket_close(int code, Datum arg) /* Nothing to do in a standalone backend, where MyProcPort is NULL. */ if (MyProcPort != NULL) { -#if defined(ENABLE_GSS) || defined(ENABLE_SSPI) #ifdef ENABLE_GSS - OM_uint32 min_s; - /* * Shutdown GSSAPI layer. This section does nothing when interrupting * BackendInitialize(), because pg_GSS_recvauth() makes first use of * "ctx" and "cred". + * + * Note that we don't bother to free MyProcPort->gss, since we're + * about to exit anyway. */ - if (MyProcPort->gss->ctx != GSS_C_NO_CONTEXT) - gss_delete_sec_context(&min_s, &MyProcPort->gss->ctx, NULL); + if (MyProcPort->gss) + { + OM_uint32 min_s; - if (MyProcPort->gss->cred != GSS_C_NO_CREDENTIAL) - gss_release_cred(&min_s, &MyProcPort->gss->cred); -#endif /* ENABLE_GSS */ + if (MyProcPort->gss->ctx != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&min_s, &MyProcPort->gss->ctx, NULL); - /* - * GSS and SSPI share the port->gss struct. Since nowhere else does a - * postmaster child free this, doing so is safe when interrupting - * BackendInitialize(). - */ - free(MyProcPort->gss); -#endif /* ENABLE_GSS || ENABLE_SSPI */ + if (MyProcPort->gss->cred != GSS_C_NO_CREDENTIAL) + gss_release_cred(&min_s, &MyProcPort->gss->cred); + } +#endif /* ENABLE_GSS */ /* * Cleanly shut down SSL layer. Nowhere else does a postmaster child @@ -536,8 +525,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber, { ereport(LOG, (errcode_for_socket_access(), - /* translator: first %s is IPv4, IPv6, or Unix */ - errmsg("setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m", + /* translator: third %s is IPv4, IPv6, or Unix */ + errmsg("%s(%s) failed for %s address \"%s\": %m", + "setsockopt", "SO_REUSEADDR", familyDesc, addrDesc))); closesocket(fd); continue; @@ -553,8 +543,9 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber, { ereport(LOG, (errcode_for_socket_access(), - /* translator: first %s is IPv4, IPv6, or Unix */ - errmsg("setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m", + /* translator: third %s is IPv4, IPv6, or Unix */ + errmsg("%s(%s) failed for %s address \"%s\": %m", + "setsockopt", "IPV6_V6ONLY", familyDesc, addrDesc))); closesocket(fd); continue; @@ -571,18 +562,20 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber, err = bind(fd, addr->ai_addr, addr->ai_addrlen); if (err < 0) { + int saved_errno = errno; + ereport(LOG, (errcode_for_socket_access(), /* translator: first %s is IPv4, IPv6, or Unix */ errmsg("could not bind %s address \"%s\": %m", familyDesc, addrDesc), - (IS_AF_UNIX(addr->ai_family)) ? - errhint("Is another postmaster already running on port %d?" - " If not, remove socket file \"%s\" and retry.", - (int) portNumber, service) : - errhint("Is another postmaster already running on port %d?" - " If not, wait a few seconds and retry.", - (int) portNumber))); + saved_errno == EADDRINUSE ? + (IS_AF_UNIX(addr->ai_family) ? + errhint("Is another postmaster already running on port %d?", + (int) portNumber) : + errhint("Is another postmaster already running on port %d?" + " If not, wait a few seconds and retry.", + (int) portNumber)) : 0)); closesocket(fd); continue; } @@ -652,6 +645,10 @@ StreamServerPort(int family, const char *hostName, unsigned short portNumber, static int Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath) { + /* no lock file for abstract sockets */ + if (unixSocketPath[0] == '@') + return STATUS_OK; + /* * Grab an interlock file associated with the socket file. * @@ -683,6 +680,10 @@ Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath) static int Setup_AF_UNIX(const char *sock_path) { + /* no file system permissions for abstract sockets */ + if (sock_path[0] == '@') + return STATUS_OK; + /* * Fix socket ownership/permission if requested. Note we must do this * before we listen() to avoid a window where unwanted connections could @@ -781,7 +782,8 @@ StreamConnection(pgsocket server_fd, Port *port) (struct sockaddr *) &port->laddr.addr, &port->laddr.salen) < 0) { - elog(LOG, "getsockname() failed: %m"); + ereport(LOG, + (errmsg("%s() failed: %m", "getsockname"))); return STATUS_ERROR; } @@ -817,7 +819,8 @@ StreamConnection(pgsocket server_fd, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { - elog(LOG, "setsockopt(%s) failed: %m", "TCP_NODELAY"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_NODELAY"))); return STATUS_ERROR; } #endif @@ -825,7 +828,8 @@ StreamConnection(pgsocket server_fd, Port *port) if (setsockopt(port->sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) { - elog(LOG, "setsockopt(%s) failed: %m", "SO_KEEPALIVE"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", "SO_KEEPALIVE"))); return STATUS_ERROR; } @@ -856,7 +860,8 @@ StreamConnection(pgsocket server_fd, Port *port) if (getsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &oldopt, &optlen) < 0) { - elog(LOG, "getsockopt(%s) failed: %m", "SO_SNDBUF"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "getsockopt", "SO_SNDBUF"))); return STATUS_ERROR; } newopt = PQ_SEND_BUFFER_SIZE * 4; @@ -865,7 +870,8 @@ StreamConnection(pgsocket server_fd, Port *port) if (setsockopt(port->sock, SOL_SOCKET, SO_SNDBUF, (char *) &newopt, sizeof(newopt)) < 0) { - elog(LOG, "setsockopt(%s) failed: %m", "SO_SNDBUF"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", "SO_SNDBUF"))); return STATUS_ERROR; } } @@ -1253,58 +1259,6 @@ pq_discardbytes(size_t len) return 0; } -/* -------------------------------- - * pq_getstring - get a null terminated string from connection - * - * The return value is placed in an expansible StringInfo, which has - * already been initialized by the caller. - * - * This is used only for dealing with old-protocol clients. The idea - * is to produce a StringInfo that looks the same as we would get from - * pq_getmessage() with a newer client; we will then process it with - * pq_getmsgstring. Therefore, no character set conversion is done here, - * even though this is presumably useful only for text. - * - * returns 0 if OK, EOF if trouble - * -------------------------------- - */ -int -pq_getstring(StringInfo s) -{ - int i; - - Assert(PqCommReadingMsg); - - resetStringInfo(s); - - /* Read until we get the terminating '\0' */ - for (;;) - { - while (PqRecvPointer >= PqRecvLength) - { - if (pq_recvbuf()) /* If nothing in buffer, then recv some */ - return EOF; /* Failed to recv data */ - } - - for (i = PqRecvPointer; i < PqRecvLength; i++) - { - if (PqRecvBuffer[i] == '\0') - { - /* include the '\0' in the copy */ - appendBinaryStringInfo(s, PqRecvBuffer + PqRecvPointer, - i - PqRecvPointer + 1); - PqRecvPointer = i + 1; /* advance past \0 */ - return 0; - } - } - - /* If we're here we haven't got the \0 in the buffer yet. */ - appendBinaryStringInfo(s, PqRecvBuffer + PqRecvPointer, - PqRecvLength - PqRecvPointer); - PqRecvPointer = PqRecvLength; - } -} - /* -------------------------------- * pq_startmsgread - begin reading a message from the client. @@ -1331,9 +1285,9 @@ pq_startmsgread(void) /* -------------------------------- * pq_endmsgread - finish reading message. * - * This must be called after reading a V2 protocol message with - * pq_getstring() and friends, to indicate that we have read the whole - * message. In V3 protocol, pq_getmessage() does this implicitly. + * This must be called after reading a message with pq_getbytes() + * and friends, to indicate that we have read the whole message. + * pq_getmessage() does this implicitly. * -------------------------------- */ void @@ -1367,10 +1321,16 @@ pq_is_reading_msg(void) * is removed. Also, s->cursor is initialized to zero for convenience * in scanning the message contents. * - * If maxlen is not zero, it is an upper limit on the length of the + * maxlen is the upper limit on the length of the * message we are willing to accept. We abort the connection (by * returning EOF) if client tries to send more than that. * + * GPDB: a maxlen of 0 means "no upper limit" -- used by callers that + * multiplex non-query messages over a libpq connection and read them + * with pq_getmessage(), namely COPY data forwarded QD->QE (copy.c) and + * the nextval-over-NOTIFY response from the QD (sequence.c). Without + * this, every such message is rejected as "invalid message length". + * * returns 0 if OK, EOF if trouble * -------------------------------- */ @@ -1449,28 +1409,6 @@ pq_getmessage(StringInfo s, int maxlen) } -/* -------------------------------- - * pq_putbytes - send bytes to connection (not flushed until pq_flush) - * - * returns 0 if OK, EOF if trouble - * -------------------------------- - */ -int -pq_putbytes(const char *s, size_t len) -{ - int res; - - /* Should only be called by old-style COPY OUT */ - Assert(DoingCopyOut); - /* No-op if reentrant call */ - if (PqCommBusy) - return 0; - PqCommBusy = true; - res = internal_putbytes(s, len); - PqCommBusy = false; - return res; -} - static int internal_putbytes(const char *s, size_t len) { @@ -1636,8 +1574,6 @@ socket_is_send_pending(void) /* -------------------------------- * Message-level I/O routines begin here. - * - * These routines understand about the old-style COPY OUT protocol. * -------------------------------- */ @@ -1645,20 +1581,13 @@ socket_is_send_pending(void) /* -------------------------------- * socket_putmessage - send a normal message (suppressed in COPY OUT mode) * - * If msgtype is not '\0', it is a message type code to place before - * the message body. If msgtype is '\0', then the message has no type - * code (this is only valid in pre-3.0 protocols). - * - * len is the length of the message body data at *s. In protocol 3.0 - * and later, a message length word (equal to len+4 because it counts - * itself too) is inserted by this routine. + * msgtype is a message type code to place before the message body. * - * All normal messages are suppressed while old-style COPY OUT is in - * progress. (In practice only a few notice messages might get emitted - * then; dropping them is annoying, but at least they will still appear - * in the postmaster log.) + * len is the length of the message body data at *s. A message length + * word (equal to len+4 because it counts itself too) is inserted by this + * routine. * - * We also suppress messages generated while pqcomm.c is busy. This + * We suppress messages generated while pqcomm.c is busy. This * avoids any possibility of messages being inserted within other * messages. * @@ -1668,26 +1597,19 @@ socket_is_send_pending(void) static int socket_putmessage(char msgtype, const char *s, size_t len) { - if (DoingCopyOut || PqCommBusy) - { - return EOF; - } - PqCommBusy = true; + uint32 n32; - if (msgtype) - { - if (internal_putbytes(&msgtype, 1)) - goto fail; - } + Assert(msgtype != 0); - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - { - uint32 n32; + if (PqCommBusy) + return 0; + PqCommBusy = true; + if (internal_putbytes(&msgtype, 1)) + goto fail; - n32 = pg_hton32((uint32) (len + 4)); - if (internal_putbytes((char *) &n32, 4)) - goto fail; - } + n32 = pg_hton32((uint32) (len + 4)); + if (internal_putbytes((char *) &n32, 4)) + goto fail; if (internal_putbytes(s, len)) goto fail; @@ -1726,37 +1648,41 @@ socket_putmessage_noblock(char msgtype, const char *s, size_t len) * buffer */ } - /* -------------------------------- - * socket_startcopyout - inform libpq that an old-style COPY OUT transfer - * is beginning - * -------------------------------- - */ -static void -socket_startcopyout(void) -{ - DoingCopyOut = true; -} - -/* -------------------------------- - * socket_endcopyout - end an old-style COPY OUT transfer + * pq_putmessage_v2 - send a message in protocol version 2 + * + * msgtype is a message type code to place before the message body. * - * If errorAbort is indicated, we are aborting a COPY OUT due to an error, - * and must send a terminator line. Since a partial data line might have - * been emitted, send a couple of newlines first (the first one could - * get absorbed by a backslash...) Note that old-style COPY OUT does - * not allow binary transfers, so a textual terminator is always correct. + * We no longer support protocol version 2, but we have kept this + * function so that if a client tries to connect with protocol version 2, + * as a courtesy we can still send the "unsupported protocol version" + * error to the client in the old format. + * + * Like in pq_putmessage(), we suppress messages generated while + * pqcomm.c is busy. + * + * returns 0 if OK, EOF if trouble * -------------------------------- */ -static void -socket_endcopyout(bool errorAbort) +int +pq_putmessage_v2(char msgtype, const char *s, size_t len) { - if (!DoingCopyOut) - return; - if (errorAbort) - pq_putbytes("\n\n\\.\n", 5); - /* in non-error case, copy.c will have emitted the terminator line */ - DoingCopyOut = false; + Assert(msgtype != 0); + + if (PqCommBusy) + return 0; + PqCommBusy = true; + if (internal_putbytes(&msgtype, 1)) + goto fail; + + if (internal_putbytes(s, len)) + goto fail; + PqCommBusy = false; + return 0; + +fail: + PqCommBusy = false; + return EOF; } /* @@ -1796,8 +1722,9 @@ pq_setkeepaliveswin32(Port *port, int idle, int interval) NULL) != 0) { - elog(LOG, "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui", - WSAGetLastError()); + ereport(LOG, + (errmsg("%s(%s) failed: error code %d", + "WSAIoctl", "SIO_KEEPALIVE_VALS", WSAGetLastError()))); return STATUS_ERROR; } if (port->keepalives_idle != idle) @@ -1827,7 +1754,8 @@ pq_getkeepalivesidle(Port *port) (char *) &port->default_keepalives_idle, &size) < 0) { - elog(LOG, "getsockopt(%s) failed: %m", PG_TCP_KEEPALIVE_IDLE_STR); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "getsockopt", PG_TCP_KEEPALIVE_IDLE_STR))); port->default_keepalives_idle = -1; /* don't know */ } #else /* WIN32 */ @@ -1871,7 +1799,8 @@ pq_setkeepalivesidle(int idle, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE, (char *) &idle, sizeof(idle)) < 0) { - elog(LOG, "setsockopt(%s) failed: %m", PG_TCP_KEEPALIVE_IDLE_STR); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", PG_TCP_KEEPALIVE_IDLE_STR))); return STATUS_ERROR; } @@ -1882,7 +1811,8 @@ pq_setkeepalivesidle(int idle, Port *port) #else if (idle != 0) { - elog(LOG, "setting the keepalive idle time is not supported"); + ereport(LOG, + (errmsg("setting the keepalive idle time is not supported"))); return STATUS_ERROR; } #endif @@ -1909,7 +1839,8 @@ pq_getkeepalivesinterval(Port *port) (char *) &port->default_keepalives_interval, &size) < 0) { - elog(LOG, "getsockopt(%s) failed: %m", "TCP_KEEPINTVL"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "getsockopt", "TCP_KEEPINTVL"))); port->default_keepalives_interval = -1; /* don't know */ } #else @@ -1952,7 +1883,8 @@ pq_setkeepalivesinterval(int interval, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPINTVL, (char *) &interval, sizeof(interval)) < 0) { - elog(LOG, "setsockopt(%s) failed: %m", "TCP_KEEPINTVL"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_KEEPINTVL"))); return STATUS_ERROR; } @@ -1963,7 +1895,8 @@ pq_setkeepalivesinterval(int interval, Port *port) #else if (interval != 0) { - elog(LOG, "setsockopt(%s) not supported", "TCP_KEEPINTVL"); + ereport(LOG, + (errmsg("%s(%s) not supported", "setsockopt", "TCP_KEEPINTVL"))); return STATUS_ERROR; } #endif @@ -1989,7 +1922,8 @@ pq_getkeepalivescount(Port *port) (char *) &port->default_keepalives_count, &size) < 0) { - elog(LOG, "getsockopt(%s) failed: %m", "TCP_KEEPCNT"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "getsockopt", "TCP_KEEPCNT"))); port->default_keepalives_count = -1; /* don't know */ } } @@ -2027,7 +1961,8 @@ pq_setkeepalivescount(int count, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, TCP_KEEPCNT, (char *) &count, sizeof(count)) < 0) { - elog(LOG, "setsockopt(%s) failed: %m", "TCP_KEEPCNT"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_KEEPCNT"))); return STATUS_ERROR; } @@ -2035,7 +1970,8 @@ pq_setkeepalivescount(int count, Port *port) #else if (count != 0) { - elog(LOG, "setsockopt(%s) not supported", "TCP_KEEPCNT"); + ereport(LOG, + (errmsg("%s(%s) not supported", "setsockopt", "TCP_KEEPCNT"))); return STATUS_ERROR; } #endif @@ -2061,7 +1997,8 @@ pq_gettcpusertimeout(Port *port) (char *) &port->default_tcp_user_timeout, &size) < 0) { - elog(LOG, "getsockopt(%s) failed: %m", "TCP_USER_TIMEOUT"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "getsockopt", "TCP_USER_TIMEOUT"))); port->default_tcp_user_timeout = -1; /* don't know */ } } @@ -2099,7 +2036,8 @@ pq_settcpusertimeout(int timeout, Port *port) if (setsockopt(port->sock, IPPROTO_TCP, TCP_USER_TIMEOUT, (char *) &timeout, sizeof(timeout)) < 0) { - elog(LOG, "setsockopt(%s) failed: %m", "TCP_USER_TIMEOUT"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", "TCP_USER_TIMEOUT"))); return STATUS_ERROR; } @@ -2107,7 +2045,8 @@ pq_settcpusertimeout(int timeout, Port *port) #else if (timeout != 0) { - elog(LOG, "setsockopt(%s) not supported", "TCP_USER_TIMEOUT"); + ereport(LOG, + (errmsg("%s(%s) not supported", "setsockopt", "TCP_USER_TIMEOUT"))); return STATUS_ERROR; } #endif @@ -2121,33 +2060,21 @@ pq_settcpusertimeout(int timeout, Port *port) bool pq_check_connection(void) { - struct pollfd pollfd; - int rc; - short poll_ev_aux; - #if defined(POLLRDHUP) /* - * POLLRDHUP is a Linux extension to poll(2) to detect sockets closed by the - * other end. - * We don't have a portable way to do that without actually trying to read - * or write data on other systems. We don't want to read because that would - * be confused by pipelined queries and COPY data. Perhaps in future we'll - * try to write a heartbeat message instead. + * POLLRDHUP is a Linux extension to poll(2) to detect sockets closed by + * the other end. We don't have a portable way to do that without + * actually trying to read or write data on other systems. We don't want + * to read because that would be confused by pipelined queries and COPY + * data. Perhaps in future we'll try to write a heartbeat message instead. */ - poll_ev_aux = POLLRDHUP; -#elif defined(__darwin__) - /* - * OSX is able to detect closed sockets via single POSIX-compliant POLLHUP - * option - */ - poll_ev_aux = 0; -#else - return true; -#endif + struct pollfd pollfd; + int rc; pollfd.fd = MyProcPort->sock; - pollfd.events = POLLOUT | POLLIN | poll_ev_aux; + pollfd.events = POLLOUT | POLLIN | POLLRDHUP; + short poll_ev_aux; pollfd.revents = 0; rc = poll(&pollfd, 1, 0); @@ -2159,8 +2086,9 @@ pq_check_connection(void) errmsg("could not poll socket: %m"))); return false; } - else if (rc == 1 && (pollfd.revents & (POLLHUP | poll_ev_aux))) + else if (rc == 1 && (pollfd.revents & (POLLHUP | POLLRDHUP))) return false; +#endif return true; } diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c index 3d928a63fe70..e4b5adf7dd0d 100644 --- a/src/backend/libpq/pqformat.c +++ b/src/backend/libpq/pqformat.c @@ -21,7 +21,7 @@ * are different. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/pqformat.c diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c index f51d935daf83..d1a1f47a7889 100644 --- a/src/backend/libpq/pqmq.c +++ b/src/backend/libpq/pqmq.c @@ -3,7 +3,7 @@ * pqmq.c * Use the frontend/backend protocol for communication over a shm_mq * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/pqmq.c @@ -33,8 +33,6 @@ static int mq_flush_if_writable(void); static bool mq_is_send_pending(void); static int mq_putmessage(char msgtype, const char *s, size_t len); static void mq_putmessage_noblock(char msgtype, const char *s, size_t len); -static void mq_startcopyout(void); -static void mq_endcopyout(bool errorAbort); static const PQcommMethods PqCommMqMethods = { mq_comm_reset, @@ -42,9 +40,7 @@ static const PQcommMethods PqCommMqMethods = { mq_flush_if_writable, mq_is_send_pending, mq_putmessage, - mq_putmessage_noblock, - mq_startcopyout, - mq_endcopyout + mq_putmessage_noblock }; /* @@ -195,18 +191,6 @@ mq_putmessage_noblock(char msgtype, const char *s, size_t len) elog(ERROR, "not currently supported"); } -static void -mq_startcopyout(void) -{ - /* Nothing to do. */ -} - -static void -mq_endcopyout(bool errorAbort) -{ - /* Nothing to do. */ -} - /* * Parse an ErrorResponse or NoticeResponse payload and populate an ErrorData * structure with the results. diff --git a/src/backend/libpq/pqsignal.c b/src/backend/libpq/pqsignal.c index 9289493118f9..dedf3a456d8d 100644 --- a/src/backend/libpq/pqsignal.c +++ b/src/backend/libpq/pqsignal.c @@ -3,7 +3,7 @@ * pqsignal.c * Backend signal(2) support (see also src/port/pqsignal.c) * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,13 +35,15 @@ sigset_t UnBlockSig, * collection; it's essentially BlockSig minus SIGTERM, SIGQUIT, SIGALRM. * * UnBlockSig is the set of signals to block when we don't want to block - * signals (is this ever nonzero??) + * signals. */ void pqinitmask(void) { sigemptyset(&UnBlockSig); + /* Note: InitializeLatchSupport() modifies UnBlockSig. */ + /* First set all signals, then clear some. */ sigfillset(&BlockSig); sigfillset(&StartupBlockSig); diff --git a/src/backend/main/main.c b/src/backend/main/main.c index 128c4313c0bf..ecbb6f874237 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -9,7 +9,7 @@ * proper FooMain() routine for the incarnation. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -335,7 +335,6 @@ help(const char *progname) printf(_(" -l enable SSL connections\n")); #endif printf(_(" -N MAX-CONNECT maximum number of allowed connections\n")); - printf(_(" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n")); printf(_(" -p PORT port number to listen on\n")); printf(_(" -s show statistics after each query\n")); printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n")); diff --git a/src/backend/mock.mk b/src/backend/mock.mk index 442b474e4f5c..1f03663d9371 100644 --- a/src/backend/mock.mk +++ b/src/backend/mock.mk @@ -18,7 +18,22 @@ override CPPFLAGS+= -I$(top_srcdir)/src/backend/libpq \ # TODO: add ldl for quick hack; we need to figure out why # postgres in src/backend/Makefile doesn't need this and -pthread. -MOCK_LIBS := -ldl $(filter-out -ledit, $(LIBS)) $(LDAP_LIBS_BE) $(ICU_LIBS) $(ZSTD_LIBS) +MOCK_LIBS := -ldl $(filter-out -ledit, $(LIBS)) $(LDAP_LIBS_BE) $(ICU_LIBS) $(ZSTD_LIBS) $(UUID_LIBS) + +# The server variants of libpgcommon/libpgport are already part of $(OBJFILES) +# (they sit at the end of objfiles.txt), but they are scanned *before* the mock +# objects in the link line. A mocked backend file can reference a symbol that +# lives only in src/common -- e.g. PG14's fd.c references get_dirent_type(), +# which is defined in common/file_utils.c. That reference only becomes +# unresolved once the linker reaches the mock object, i.e. after the server +# archives have already been scanned, so the symbol would otherwise be resolved +# by the FRONTEND libpgcommon.a in $(LIBS) -- pulling in fe_memutils.o / +# file_utils.o and producing "multiple definition" errors against mcxt.o and +# the mock (palloc, fsync_fname, durable_rename, ...). Re-list the *server* +# archives after the mock objects so such late references resolve against the +# server variant (which omits the FRONTEND-only definitions). +MOCK_SRV_LIBS := $(top_builddir)/src/common/libpgcommon_srv.a \ + $(top_builddir)/src/port/libpgport_srv.a # These files are not linked into test programs. EXCL_OBJS=\ @@ -70,7 +85,6 @@ EXCL_OBJS+=\ src/backend/utils/adt/tsvector_op.o \ src/backend/utils/adt/tsvector_parser.o \ src/backend/utils/adt/txid.o \ - src/backend/utils/adt/uuid.o \ src/backend/tsearch/dict.o \ src/backend/tsearch/dict_ispell.o \ src/backend/tsearch/dict_simple.o \ @@ -121,7 +135,7 @@ WRAP_FUNCS=$(addprefix $(WRAP_FLAGS), \ # The test target depends on $(OBJFILES) which would update files including mocks. %.t: $(OBJFILES) $(CMOCKERY_OBJS) $(MOCK_OBJS) %_test.o - $(CXX) $(CFLAGS) $(LDFLAGS) $(call WRAP_FUNCS, $(top_srcdir)/$(subdir)/test/$*_test.c) $(call BACKEND_OBJS, $(top_srcdir)/$(subdir)/$*.o $(patsubst $(MOCK_DIR)/%_mock.o,$(top_builddir)/src/%.o, $^)) $(filter-out %/objfiles.txt, $^) $(MOCK_LIBS) -o $@ + $(CXX) $(CFLAGS) $(LDFLAGS) $(call WRAP_FUNCS, $(top_srcdir)/$(subdir)/test/$*_test.c) $(call BACKEND_OBJS, $(top_srcdir)/$(subdir)/$*.o $(patsubst $(MOCK_DIR)/%_mock.o,$(top_builddir)/src/%.o, $^)) $(filter-out %/objfiles.txt, $^) $(MOCK_SRV_LIBS) $(MOCK_LIBS) -o $@ # We'd like to call only src/backend, but it seems we should build src/port and # src/timezone before src/backend. This is not the case when main build has finished, diff --git a/src/backend/nls.mk b/src/backend/nls.mk index f2788a076d0d..771b58d4f45b 100644 --- a/src/backend/nls.mk +++ b/src/backend/nls.mk @@ -1,6 +1,6 @@ # src/backend/nls.mk CATALOG_NAME = postgres -AVAIL_LANGUAGES = de es fr id it ja ko pl pt_BR ru sv tr zh_CN +AVAIL_LANGUAGES = de es fr id it ja ko pl pt_BR ru sv tr uk zh_CN GETTEXT_FILES = + gettext-files GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) \ GUC_check_errmsg \ diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c index 97d77c953c87..c2659019cb64 100644 --- a/src/backend/nodes/bitmapset.c +++ b/src/backend/nodes/bitmapset.c @@ -11,7 +11,7 @@ * bms_is_empty() in preference to testing for NULL.) * * - * Copyright (c) 2003-2020, PostgreSQL Global Development Group + * Copyright (c) 2003-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/nodes/bitmapset.c diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 944a78e6c8a4..4b3ed532e856 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -13,7 +13,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -114,7 +114,6 @@ _copyPlannedStmt(const PlannedStmt *from) COPY_NODE_FIELD(planTree); COPY_NODE_FIELD(rtable); COPY_NODE_FIELD(resultRelations); - COPY_NODE_FIELD(rootResultRelations); COPY_NODE_FIELD(appendRelations); COPY_NODE_FIELD(subplans); COPY_POINTER_FIELD(subplan_sliceIds, list_length(from->subplans) * sizeof(int)); @@ -242,6 +241,7 @@ CopyPlanFields(const Plan *from, Plan *newnode) COPY_SCALAR_FIELD(plan_width); COPY_SCALAR_FIELD(parallel_aware); COPY_SCALAR_FIELD(parallel_safe); + COPY_SCALAR_FIELD(async_capable); COPY_SCALAR_FIELD(plan_node_id); COPY_NODE_FIELD(targetlist); COPY_NODE_FIELD(qual); @@ -338,9 +338,7 @@ _copyModifyTable(const ModifyTable *from) COPY_SCALAR_FIELD(rootRelation); COPY_SCALAR_FIELD(partColsUpdated); COPY_NODE_FIELD(resultRelations); - COPY_SCALAR_FIELD(resultRelIndex); - COPY_SCALAR_FIELD(rootResultRelIndex); - COPY_NODE_FIELD(plans); + COPY_NODE_FIELD(updateColnosLists); COPY_NODE_FIELD(withCheckOptionLists); COPY_NODE_FIELD(returningLists); COPY_NODE_FIELD(fdwPrivLists); @@ -350,6 +348,7 @@ _copyModifyTable(const ModifyTable *from) COPY_SCALAR_FIELD(onConflictAction); COPY_NODE_FIELD(arbiterIndexes); COPY_NODE_FIELD(onConflictSet); + COPY_NODE_FIELD(onConflictCols); COPY_NODE_FIELD(onConflictWhere); COPY_SCALAR_FIELD(exclRelRTI); COPY_NODE_FIELD(exclRelTlist); @@ -377,6 +376,7 @@ _copyAppend(const Append *from) */ COPY_BITMAPSET_FIELD(apprelids); COPY_NODE_FIELD(appendplans); + COPY_SCALAR_FIELD(nasyncplans); COPY_SCALAR_FIELD(first_partial_plan); COPY_NODE_FIELD(part_prune_info); COPY_NODE_FIELD(join_prune_paramids); @@ -823,6 +823,27 @@ _copyTidScan(const TidScan *from) return newnode; } +/* + * _copyTidRangeScan + */ +static TidRangeScan * +_copyTidRangeScan(const TidRangeScan *from) +{ + TidRangeScan *newnode = makeNode(TidRangeScan); + + /* + * copy node superclass fields + */ + CopyScanFields((const Scan *) from, (Scan *) newnode); + + /* + * copy remainder of node + */ + COPY_NODE_FIELD(tidrangequals); + + return newnode; +} + /* * _copySubqueryScan */ @@ -1006,6 +1027,7 @@ _copyForeignScan(const ForeignScan *from) * copy remainder of node */ COPY_SCALAR_FIELD(operation); + COPY_SCALAR_FIELD(resultRelation); COPY_SCALAR_FIELD(fs_server); COPY_NODE_FIELD(fdw_exprs); COPY_NODE_FIELD(fdw_private); @@ -1208,6 +1230,33 @@ _copyMaterial(const Material *from) } +/* + * _copyResultCache + */ +static ResultCache * +_copyResultCache(const ResultCache *from) +{ + ResultCache *newnode = makeNode(ResultCache); + + /* + * copy node superclass fields + */ + CopyPlanFields((const Plan *) from, (Plan *) newnode); + + /* + * copy remainder of node + */ + COPY_SCALAR_FIELD(numKeys); + COPY_POINTER_FIELD(hashOperators, sizeof(Oid) * from->numKeys); + COPY_POINTER_FIELD(collations, sizeof(Oid) * from->numKeys); + COPY_NODE_FIELD(param_exprs); + COPY_SCALAR_FIELD(singlerow); + COPY_SCALAR_FIELD(est_entries); + + return newnode; +} + + /* * CopySortFields * @@ -1929,6 +1978,8 @@ _copyAggref(const Aggref *from) COPY_SCALAR_FIELD(aggkind); COPY_SCALAR_FIELD(agglevelsup); COPY_SCALAR_FIELD(aggsplit); + COPY_SCALAR_FIELD(aggno); + COPY_SCALAR_FIELD(aggtransno); COPY_LOCATION_FIELD(location); COPY_SCALAR_FIELD(agg_expr_id); @@ -2012,6 +2063,7 @@ _copySubscriptingRef(const SubscriptingRef *from) COPY_SCALAR_FIELD(refcontainertype); COPY_SCALAR_FIELD(refelemtype); + COPY_SCALAR_FIELD(refrestype); COPY_SCALAR_FIELD(reftypmod); COPY_SCALAR_FIELD(refcollid); COPY_NODE_FIELD(refupperindexpr); @@ -2130,6 +2182,7 @@ _copyScalarArrayOpExpr(const ScalarArrayOpExpr *from) COPY_SCALAR_FIELD(opno); COPY_SCALAR_FIELD(opfuncid); + COPY_SCALAR_FIELD(hashfuncid); COPY_SCALAR_FIELD(useOr); COPY_SCALAR_FIELD(inputcollid); COPY_NODE_FIELD(args); @@ -2676,6 +2729,7 @@ _copyJoinExpr(const JoinExpr *from) COPY_NODE_FIELD(larg); COPY_NODE_FIELD(rarg); COPY_NODE_FIELD(usingClause); + COPY_NODE_FIELD(join_using_alias); COPY_NODE_FIELD(quals); COPY_NODE_FIELD(alias); COPY_SCALAR_FIELD(rtindex); @@ -2808,6 +2862,7 @@ _copyRestrictInfo(const RestrictInfo *from) COPY_SCALAR_FIELD(can_join); COPY_SCALAR_FIELD(pseudoconstant); COPY_SCALAR_FIELD(leakproof); + COPY_SCALAR_FIELD(has_volatile); COPY_SCALAR_FIELD(security_level); COPY_SCALAR_FIELD(contain_outer_query_references); COPY_BITMAPSET_FIELD(clause_relids); @@ -2836,6 +2891,7 @@ _copyRestrictInfo(const RestrictInfo *from) COPY_SCALAR_FIELD(right_bucketsize); COPY_SCALAR_FIELD(left_mcvfreq); COPY_SCALAR_FIELD(right_mcvfreq); + COPY_SCALAR_FIELD(hasheqoperator); return newnode; } @@ -2939,6 +2995,7 @@ _copyRangeTblEntry(const RangeTblEntry *from) COPY_NODE_FIELD(joinaliasvars); COPY_NODE_FIELD(joinleftcols); COPY_NODE_FIELD(joinrightcols); + COPY_NODE_FIELD(join_using_alias); COPY_NODE_FIELD(functions); COPY_SCALAR_FIELD(funcordinality); COPY_NODE_FIELD(tablefunc); @@ -3117,6 +3174,38 @@ _copyOnConflictClause(const OnConflictClause *from) return newnode; } +static CTESearchClause * +_copyCTESearchClause(const CTESearchClause *from) +{ + CTESearchClause *newnode = makeNode(CTESearchClause); + + COPY_NODE_FIELD(search_col_list); + COPY_SCALAR_FIELD(search_breadth_first); + COPY_STRING_FIELD(search_seq_column); + COPY_LOCATION_FIELD(location); + + return newnode; +} + +static CTECycleClause * +_copyCTECycleClause(const CTECycleClause *from) +{ + CTECycleClause *newnode = makeNode(CTECycleClause); + + COPY_NODE_FIELD(cycle_col_list); + COPY_STRING_FIELD(cycle_mark_column); + COPY_NODE_FIELD(cycle_mark_value); + COPY_NODE_FIELD(cycle_mark_default); + COPY_STRING_FIELD(cycle_path_column); + COPY_LOCATION_FIELD(location); + COPY_SCALAR_FIELD(cycle_mark_type); + COPY_SCALAR_FIELD(cycle_mark_typmod); + COPY_SCALAR_FIELD(cycle_mark_collation); + COPY_SCALAR_FIELD(cycle_mark_neop); + + return newnode; +} + static CommonTableExpr * _copyCommonTableExpr(const CommonTableExpr *from) { @@ -3126,6 +3215,8 @@ _copyCommonTableExpr(const CommonTableExpr *from) COPY_NODE_FIELD(aliascolnames); COPY_SCALAR_FIELD(ctematerialized); COPY_NODE_FIELD(ctequery); + COPY_NODE_FIELD(search_clause); + COPY_NODE_FIELD(cycle_clause); COPY_LOCATION_FIELD(location); COPY_SCALAR_FIELD(cterecursive); COPY_SCALAR_FIELD(cterefcount); @@ -3213,11 +3304,12 @@ _copyFuncCall(const FuncCall *from) COPY_NODE_FIELD(args); COPY_NODE_FIELD(agg_order); COPY_NODE_FIELD(agg_filter); + COPY_NODE_FIELD(over); COPY_SCALAR_FIELD(agg_within_group); COPY_SCALAR_FIELD(agg_star); COPY_SCALAR_FIELD(agg_distinct); COPY_SCALAR_FIELD(func_variadic); - COPY_NODE_FIELD(over); + COPY_SCALAR_FIELD(funcformat); COPY_LOCATION_FIELD(location); return newnode; @@ -3453,6 +3545,17 @@ _copyIndexElem(const IndexElem *from) return newnode; } +static StatsElem * +_copyStatsElem(const StatsElem *from) +{ + StatsElem *newnode = makeNode(StatsElem); + + COPY_STRING_FIELD(name); + COPY_NODE_FIELD(expr); + + return newnode; +} + static ColumnDef * _copyColumnDef(const ColumnDef *from) { @@ -3460,6 +3563,7 @@ _copyColumnDef(const ColumnDef *from) COPY_STRING_FIELD(colname); COPY_NODE_FIELD(typeName); + COPY_STRING_FIELD(compression); COPY_SCALAR_FIELD(inhcount); COPY_SCALAR_FIELD(is_local); COPY_SCALAR_FIELD(is_not_null); @@ -3643,6 +3747,7 @@ _copyQuery(const Query *from) COPY_SCALAR_FIELD(hasForUpdate); COPY_SCALAR_FIELD(hasRowSecurity); COPY_SCALAR_FIELD(canOptSelectLockingClause); + COPY_SCALAR_FIELD(isReturn); COPY_NODE_FIELD(cteList); COPY_NODE_FIELD(rtable); COPY_NODE_FIELD(jointree); @@ -3651,6 +3756,7 @@ _copyQuery(const Query *from) COPY_NODE_FIELD(onConflict); COPY_NODE_FIELD(returningList); COPY_NODE_FIELD(groupClause); + COPY_SCALAR_FIELD(groupDistinct); COPY_NODE_FIELD(groupingSets); COPY_NODE_FIELD(havingQual); COPY_NODE_FIELD(windowClause); @@ -3741,6 +3847,7 @@ _copySelectStmt(const SelectStmt *from) COPY_NODE_FIELD(fromClause); COPY_NODE_FIELD(whereClause); COPY_NODE_FIELD(groupClause); + COPY_SCALAR_FIELD(groupDistinct); COPY_NODE_FIELD(havingClause); COPY_NODE_FIELD(windowClause); COPY_NODE_FIELD(valuesLists); @@ -3777,6 +3884,30 @@ _copySetOperationStmt(const SetOperationStmt *from) return newnode; } +static ReturnStmt * +_copyReturnStmt(const ReturnStmt *from) +{ + ReturnStmt *newnode = makeNode(ReturnStmt); + + COPY_NODE_FIELD(returnval); + + return newnode; +} + +static PLAssignStmt * +_copyPLAssignStmt(const PLAssignStmt *from) +{ + PLAssignStmt *newnode = makeNode(PLAssignStmt); + + COPY_STRING_FIELD(name); + COPY_NODE_FIELD(indirection); + COPY_SCALAR_FIELD(nnames); + COPY_NODE_FIELD(val); + COPY_LOCATION_FIELD(location); + + return newnode; +} + static AlterTableStmt * _copyAlterTableStmt(const AlterTableStmt *from) { @@ -3850,6 +3981,7 @@ _copyGrantStmt(const GrantStmt *from) COPY_NODE_FIELD(privileges); COPY_NODE_FIELD(grantees); COPY_SCALAR_FIELD(grant_option); + COPY_NODE_FIELD(grantor); COPY_SCALAR_FIELD(behavior); return newnode; @@ -3862,6 +3994,7 @@ _copyObjectWithArgs(const ObjectWithArgs *from) COPY_NODE_FIELD(objname); COPY_NODE_FIELD(objargs); + COPY_NODE_FIELD(objfuncargs); COPY_SCALAR_FIELD(args_unspecified); return newnode; @@ -3933,6 +4066,7 @@ _copyCallStmt(const CallStmt *from) COPY_NODE_FIELD(funccall); COPY_NODE_FIELD(funcexpr); + COPY_NODE_FIELD(outargs); return newnode; } @@ -3944,7 +4078,7 @@ _copyClusterStmt(const ClusterStmt *from) COPY_NODE_FIELD(relation); COPY_STRING_FIELD(indexname); - COPY_SCALAR_FIELD(options); + COPY_NODE_FIELD(params); return newnode; } @@ -4031,6 +4165,7 @@ _copyTableLikeClause(const TableLikeClause *from) COPY_NODE_FIELD(relation); COPY_SCALAR_FIELD(options); + COPY_SCALAR_FIELD(relationOid); return newnode; } @@ -4203,6 +4338,7 @@ _copyCreateStatsStmt(const CreateStatsStmt *from) COPY_NODE_FIELD(exprs); COPY_NODE_FIELD(relations); COPY_STRING_FIELD(stxcomment); + COPY_SCALAR_FIELD(transformed); COPY_SCALAR_FIELD(if_not_exists); return newnode; @@ -4231,6 +4367,7 @@ _copyCreateFunctionStmt(const CreateFunctionStmt *from) COPY_NODE_FIELD(parameters); COPY_NODE_FIELD(returnType); COPY_NODE_FIELD(options); + COPY_NODE_FIELD(sql_body); return newnode; } @@ -4976,6 +5113,8 @@ _copyCreateTrigStmt(const CreateTrigStmt *from) { CreateTrigStmt *newnode = makeNode(CreateTrigStmt); + COPY_SCALAR_FIELD(replace); + COPY_SCALAR_FIELD(isconstraint); COPY_STRING_FIELD(trigname); COPY_NODE_FIELD(relation); COPY_NODE_FIELD(funcname); @@ -4985,7 +5124,6 @@ _copyCreateTrigStmt(const CreateTrigStmt *from) COPY_SCALAR_FIELD(events); COPY_NODE_FIELD(columns); COPY_NODE_FIELD(whenClause); - COPY_SCALAR_FIELD(isconstraint); COPY_NODE_FIELD(transitionRels); COPY_SCALAR_FIELD(deferrable); COPY_SCALAR_FIELD(initdeferred); @@ -5137,6 +5275,7 @@ _copyReindexStmt(const ReindexStmt *from) COPY_SCALAR_FIELD(relid); COPY_SCALAR_FIELD(options); COPY_SCALAR_FIELD(concurrent); + COPY_NODE_FIELD(params); return newnode; } @@ -5547,6 +5686,7 @@ _copyPartitionCmd(const PartitionCmd *from) COPY_NODE_FIELD(name); COPY_NODE_FIELD(bound); + COPY_SCALAR_FIELD(concurrent); return newnode; } @@ -5932,6 +6072,9 @@ copyObjectImpl(const void *from) case T_TidScan: retval = _copyTidScan(from); break; + case T_TidRangeScan: + retval = _copyTidRangeScan(from); + break; case T_SubqueryScan: retval = _copySubqueryScan(from); break; @@ -5977,6 +6120,9 @@ copyObjectImpl(const void *from) case T_Material: retval = _copyMaterial(from); break; + case T_ResultCache: + retval = _copyResultCache(from); + break; case T_Sort: retval = _copySort(from); break; @@ -6310,6 +6456,12 @@ copyObjectImpl(const void *from) case T_SetOperationStmt: retval = _copySetOperationStmt(from); break; + case T_ReturnStmt: + retval = _copyReturnStmt(from); + break; + case T_PLAssignStmt: + retval = _copyPLAssignStmt(from); + break; case T_AlterTableStmt: retval = _copyAlterTableStmt(from); break; @@ -6745,6 +6897,9 @@ copyObjectImpl(const void *from) case T_IndexElem: retval = _copyIndexElem(from); break; + case T_StatsElem: + retval = _copyStatsElem(from); + break; case T_ColumnDef: retval = _copyColumnDef(from); break; @@ -6799,6 +6954,12 @@ copyObjectImpl(const void *from) case T_OnConflictClause: retval = _copyOnConflictClause(from); break; + case T_CTESearchClause: + retval = _copyCTESearchClause(from); + break; + case T_CTECycleClause: + retval = _copyCTECycleClause(from); + break; case T_CommonTableExpr: retval = _copyCommonTableExpr(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 6b8bad4acffe..90b372cce1b3 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -256,6 +256,8 @@ _equalAggref(const Aggref *a, const Aggref *b) COMPARE_SCALAR_FIELD(aggkind); COMPARE_SCALAR_FIELD(agglevelsup); COMPARE_SCALAR_FIELD(aggsplit); + COMPARE_SCALAR_FIELD(aggno); + COMPARE_SCALAR_FIELD(aggtransno); COMPARE_LOCATION_FIELD(location); return true; @@ -318,6 +320,7 @@ _equalSubscriptingRef(const SubscriptingRef *a, const SubscriptingRef *b) { COMPARE_SCALAR_FIELD(refcontainertype); COMPARE_SCALAR_FIELD(refelemtype); + COMPARE_SCALAR_FIELD(refrestype); COMPARE_SCALAR_FIELD(reftypmod); COMPARE_SCALAR_FIELD(refcollid); COMPARE_NODE_FIELD(refupperindexpr); @@ -449,6 +452,12 @@ _equalScalarArrayOpExpr(const ScalarArrayOpExpr *a, const ScalarArrayOpExpr *b) b->opfuncid != 0) return false; + /* As above, hashfuncid may differ too */ + if (a->hashfuncid != b->hashfuncid && + a->hashfuncid != 0 && + b->hashfuncid != 0) + return false; + COMPARE_SCALAR_FIELD(useOr); COMPARE_SCALAR_FIELD(inputcollid); COMPARE_NODE_FIELD(args); @@ -838,6 +847,7 @@ _equalJoinExpr(const JoinExpr *a, const JoinExpr *b) COMPARE_NODE_FIELD(larg); COMPARE_NODE_FIELD(rarg); COMPARE_NODE_FIELD(usingClause); + COMPARE_NODE_FIELD(join_using_alias); COMPARE_NODE_FIELD(quals); COMPARE_NODE_FIELD(alias); COMPARE_SCALAR_FIELD(rtindex); @@ -1031,6 +1041,7 @@ _equalQuery(const Query *a, const Query *b) COMPARE_SCALAR_FIELD(hasForUpdate); COMPARE_SCALAR_FIELD(hasRowSecurity); COMPARE_SCALAR_FIELD(canOptSelectLockingClause); + COMPARE_SCALAR_FIELD(isReturn); COMPARE_NODE_FIELD(cteList); COMPARE_NODE_FIELD(rtable); COMPARE_NODE_FIELD(jointree); @@ -1039,6 +1050,7 @@ _equalQuery(const Query *a, const Query *b) COMPARE_NODE_FIELD(onConflict); COMPARE_NODE_FIELD(returningList); COMPARE_NODE_FIELD(groupClause); + COMPARE_SCALAR_FIELD(groupDistinct); COMPARE_NODE_FIELD(groupingSets); COMPARE_NODE_FIELD(havingQual); COMPARE_NODE_FIELD(windowClause); @@ -1126,6 +1138,7 @@ _equalSelectStmt(const SelectStmt *a, const SelectStmt *b) COMPARE_NODE_FIELD(fromClause); COMPARE_NODE_FIELD(whereClause); COMPARE_NODE_FIELD(groupClause); + COMPARE_SCALAR_FIELD(groupDistinct); COMPARE_NODE_FIELD(havingClause); COMPARE_NODE_FIELD(windowClause); COMPARE_NODE_FIELD(valuesLists); @@ -1160,6 +1173,26 @@ _equalSetOperationStmt(const SetOperationStmt *a, const SetOperationStmt *b) return true; } +static bool +_equalReturnStmt(const ReturnStmt *a, const ReturnStmt *b) +{ + COMPARE_NODE_FIELD(returnval); + + return true; +} + +static bool +_equalPLAssignStmt(const PLAssignStmt *a, const PLAssignStmt *b) +{ + COMPARE_STRING_FIELD(name); + COMPARE_NODE_FIELD(indirection); + COMPARE_SCALAR_FIELD(nnames); + COMPARE_NODE_FIELD(val); + COMPARE_LOCATION_FIELD(location); + + return true; +} + static bool _equalAlterTableStmt(const AlterTableStmt *a, const AlterTableStmt *b) { @@ -1218,6 +1251,7 @@ _equalGrantStmt(const GrantStmt *a, const GrantStmt *b) COMPARE_NODE_FIELD(privileges); COMPARE_NODE_FIELD(grantees); COMPARE_SCALAR_FIELD(grant_option); + COMPARE_NODE_FIELD(grantor); COMPARE_SCALAR_FIELD(behavior); return true; @@ -1228,6 +1262,7 @@ _equalObjectWithArgs(const ObjectWithArgs *a, const ObjectWithArgs *b) { COMPARE_NODE_FIELD(objname); COMPARE_NODE_FIELD(objargs); + COMPARE_NODE_FIELD(objfuncargs); COMPARE_SCALAR_FIELD(args_unspecified); return true; @@ -1287,6 +1322,7 @@ _equalCallStmt(const CallStmt *a, const CallStmt *b) { COMPARE_NODE_FIELD(funccall); COMPARE_NODE_FIELD(funcexpr); + COMPARE_NODE_FIELD(outargs); return true; } @@ -1296,7 +1332,7 @@ _equalClusterStmt(const ClusterStmt *a, const ClusterStmt *b) { COMPARE_NODE_FIELD(relation); COMPARE_STRING_FIELD(indexname); - COMPARE_SCALAR_FIELD(options); + COMPARE_NODE_FIELD(params); return true; } @@ -1409,6 +1445,7 @@ _equalTableLikeClause(const TableLikeClause *a, const TableLikeClause *b) { COMPARE_NODE_FIELD(relation); COMPARE_SCALAR_FIELD(options); + COMPARE_SCALAR_FIELD(relationOid); return true; } @@ -1530,6 +1567,7 @@ _equalCreateStatsStmt(const CreateStatsStmt *a, const CreateStatsStmt *b) COMPARE_NODE_FIELD(exprs); COMPARE_NODE_FIELD(relations); COMPARE_STRING_FIELD(stxcomment); + COMPARE_SCALAR_FIELD(transformed); COMPARE_SCALAR_FIELD(if_not_exists); return true; @@ -1554,6 +1592,7 @@ _equalCreateFunctionStmt(const CreateFunctionStmt *a, const CreateFunctionStmt * COMPARE_NODE_FIELD(parameters); COMPARE_NODE_FIELD(returnType); COMPARE_NODE_FIELD(options); + COMPARE_NODE_FIELD(sql_body); return true; } @@ -2183,6 +2222,8 @@ _equalCreateAmStmt(const CreateAmStmt *a, const CreateAmStmt *b) static bool _equalCreateTrigStmt(const CreateTrigStmt *a, const CreateTrigStmt *b) { + COMPARE_SCALAR_FIELD(replace); + COMPARE_SCALAR_FIELD(isconstraint); COMPARE_STRING_FIELD(trigname); COMPARE_NODE_FIELD(relation); COMPARE_NODE_FIELD(funcname); @@ -2192,7 +2233,6 @@ _equalCreateTrigStmt(const CreateTrigStmt *a, const CreateTrigStmt *b) COMPARE_SCALAR_FIELD(events); COMPARE_NODE_FIELD(columns); COMPARE_NODE_FIELD(whenClause); - COMPARE_SCALAR_FIELD(isconstraint); COMPARE_NODE_FIELD(transitionRels); COMPARE_SCALAR_FIELD(deferrable); COMPARE_SCALAR_FIELD(initdeferred); @@ -2320,6 +2360,7 @@ _equalReindexStmt(const ReindexStmt *a, const ReindexStmt *b) COMPARE_SCALAR_FIELD(options); COMPARE_SCALAR_FIELD(concurrent); COMPARE_SCALAR_FIELD(relid); + COMPARE_NODE_FIELD(params); return true; } @@ -2614,11 +2655,12 @@ _equalFuncCall(const FuncCall *a, const FuncCall *b) COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(agg_order); COMPARE_NODE_FIELD(agg_filter); + COMPARE_NODE_FIELD(over); COMPARE_SCALAR_FIELD(agg_within_group); COMPARE_SCALAR_FIELD(agg_star); COMPARE_SCALAR_FIELD(agg_distinct); COMPARE_SCALAR_FIELD(func_variadic); - COMPARE_NODE_FIELD(over); + COMPARE_COERCIONFORM_FIELD(funcformat); COMPARE_LOCATION_FIELD(location); return true; @@ -2820,11 +2862,22 @@ _equalIndexElem(const IndexElem *a, const IndexElem *b) return true; } + +static bool +_equalStatsElem(const StatsElem *a, const StatsElem *b) +{ + COMPARE_STRING_FIELD(name); + COMPARE_NODE_FIELD(expr); + + return true; +} + static bool _equalColumnDef(const ColumnDef *a, const ColumnDef *b) { COMPARE_STRING_FIELD(colname); COMPARE_NODE_FIELD(typeName); + COMPARE_STRING_FIELD(compression); COMPARE_SCALAR_FIELD(inhcount); COMPARE_SCALAR_FIELD(is_local); COMPARE_SCALAR_FIELD(is_not_null); @@ -2919,6 +2972,7 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b) COMPARE_NODE_FIELD(joinaliasvars); COMPARE_NODE_FIELD(joinleftcols); COMPARE_NODE_FIELD(joinrightcols); + COMPARE_NODE_FIELD(join_using_alias); COMPARE_NODE_FIELD(functions); COMPARE_SCALAR_FIELD(funcordinality); COMPARE_NODE_FIELD(tablefunc); @@ -3071,6 +3125,34 @@ _equalOnConflictClause(const OnConflictClause *a, const OnConflictClause *b) return true; } +static bool +_equalCTESearchClause(const CTESearchClause *a, const CTESearchClause *b) +{ + COMPARE_NODE_FIELD(search_col_list); + COMPARE_SCALAR_FIELD(search_breadth_first); + COMPARE_STRING_FIELD(search_seq_column); + COMPARE_LOCATION_FIELD(location); + + return true; +} + +static bool +_equalCTECycleClause(const CTECycleClause *a, const CTECycleClause *b) +{ + COMPARE_NODE_FIELD(cycle_col_list); + COMPARE_STRING_FIELD(cycle_mark_column); + COMPARE_NODE_FIELD(cycle_mark_value); + COMPARE_NODE_FIELD(cycle_mark_default); + COMPARE_STRING_FIELD(cycle_path_column); + COMPARE_LOCATION_FIELD(location); + COMPARE_SCALAR_FIELD(cycle_mark_type); + COMPARE_SCALAR_FIELD(cycle_mark_typmod); + COMPARE_SCALAR_FIELD(cycle_mark_collation); + COMPARE_SCALAR_FIELD(cycle_mark_neop); + + return true; +} + static bool _equalCommonTableExpr(const CommonTableExpr *a, const CommonTableExpr *b) { @@ -3078,6 +3160,8 @@ _equalCommonTableExpr(const CommonTableExpr *a, const CommonTableExpr *b) COMPARE_NODE_FIELD(aliascolnames); COMPARE_SCALAR_FIELD(ctematerialized); COMPARE_NODE_FIELD(ctequery); + COMPARE_NODE_FIELD(search_clause); + COMPARE_NODE_FIELD(cycle_clause); COMPARE_LOCATION_FIELD(location); COMPARE_SCALAR_FIELD(cterecursive); COMPARE_SCALAR_FIELD(cterefcount); @@ -3207,6 +3291,7 @@ _equalPartitionCmd(const PartitionCmd *a, const PartitionCmd *b) { COMPARE_NODE_FIELD(name); COMPARE_NODE_FIELD(bound); + COMPARE_SCALAR_FIELD(concurrent); return true; } @@ -3562,6 +3647,12 @@ equal(const void *a, const void *b) case T_SetOperationStmt: retval = _equalSetOperationStmt(a, b); break; + case T_ReturnStmt: + retval = _equalReturnStmt(a, b); + break; + case T_PLAssignStmt: + retval = _equalPLAssignStmt(a, b); + break; case T_AlterTableStmt: retval = _equalAlterTableStmt(a, b); break; @@ -4000,6 +4091,9 @@ equal(const void *a, const void *b) case T_IndexElem: retval = _equalIndexElem(a, b); break; + case T_StatsElem: + retval = _equalStatsElem(a, b); + break; case T_ColumnDef: retval = _equalColumnDef(a, b); break; @@ -4045,6 +4139,12 @@ equal(const void *a, const void *b) case T_OnConflictClause: retval = _equalOnConflictClause(a, b); break; + case T_CTESearchClause: + retval = _equalCTESearchClause(a, b); + break; + case T_CTECycleClause: + retval = _equalCTECycleClause(a, b); + break; case T_CommonTableExpr: retval = _equalCommonTableExpr(a, b); break; diff --git a/src/backend/nodes/extensible.c b/src/backend/nodes/extensible.c index ab04459c55a2..1489df0729a6 100644 --- a/src/backend/nodes/extensible.c +++ b/src/backend/nodes/extensible.c @@ -10,7 +10,7 @@ * and GetExtensibleNodeMethods to get information about a previously * registered type of extensible node. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -47,11 +47,11 @@ RegisterExtensibleNodeEntry(HTAB **p_htable, const char *htable_label, { HASHCTL ctl; - memset(&ctl, 0, sizeof(HASHCTL)); ctl.keysize = EXTNODENAME_MAX_LEN; ctl.entrysize = sizeof(ExtensibleNodeEntry); - *p_htable = hash_create(htable_label, 100, &ctl, HASH_ELEM); + *p_htable = hash_create(htable_label, 100, &ctl, + HASH_ELEM | HASH_STRINGS); } if (strlen(extnodename) >= EXTNODENAME_MAX_LEN) diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index 2482cae220af..05bdef94981c 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -6,7 +6,7 @@ * See comments in pg_list.h. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -277,6 +277,21 @@ list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2, return list; } +List * +list_make5_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3, ListCell datum4, ListCell datum5) +{ + List *list = new_list(t, 5); + + list->elements[0] = datum1; + list->elements[1] = datum2; + list->elements[2] = datum3; + list->elements[3] = datum4; + list->elements[4] = datum5; + check_list_invariants(list); + return list; +} + /* * Make room for a new head cell in the given (non-NIL) list. * @@ -327,7 +342,7 @@ lappend(List *list, void *datum) else new_tail_cell(list); - lfirst(list_tail(list)) = datum; + llast(list) = datum; check_list_invariants(list); return list; } @@ -345,7 +360,7 @@ lappend_int(List *list, int datum) else new_tail_cell(list); - lfirst_int(list_tail(list)) = datum; + llast_int(list) = datum; check_list_invariants(list); return list; } @@ -363,7 +378,7 @@ lappend_oid(List *list, Oid datum) else new_tail_cell(list); - lfirst_oid(list_tail(list)) = datum; + llast_oid(list) = datum; check_list_invariants(list); return list; } @@ -459,7 +474,7 @@ lcons(void *datum, List *list) else new_head_cell(list); - lfirst(list_head(list)) = datum; + linitial(list) = datum; check_list_invariants(list); return list; } @@ -477,7 +492,7 @@ lcons_int(int datum, List *list) else new_head_cell(list); - lfirst_int(list_head(list)) = datum; + linitial_int(list) = datum; check_list_invariants(list); return list; } @@ -495,7 +510,7 @@ lcons_oid(Oid datum, List *list) else new_head_cell(list); - lfirst_oid(list_head(list)) = datum; + linitial_oid(list) = datum; check_list_invariants(list); return list; } @@ -1506,6 +1521,22 @@ list_sort(List *list, list_sort_comparator cmp) qsort(list->elements, len, sizeof(ListCell), (qsort_comparator) cmp); } +/* + * list_sort comparator for sorting a list into ascending int order. + */ +int +list_int_cmp(const ListCell *p1, const ListCell *p2) +{ + int v1 = lfirst_int(p1); + int v2 = lfirst_int(p2); + + if (v1 < v2) + return -1; + if (v1 > v2) + return 1; + return 0; +} + /* * list_sort comparator for sorting a list into ascending OID order. */ diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 14b0160d0cbe..fd867866c5c3 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -4,7 +4,7 @@ * creator functions for various nodes. The functions here are for the * most frequently created nodes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -584,7 +584,7 @@ makeDefElemExtended(char *nameSpace, char *name, Node *arg, * supply. Any non-default parameters have to be inserted by the caller. */ FuncCall * -makeFuncCall(List *name, List *args, int location) +makeFuncCall(List *name, List *args, CoercionForm funcformat, int location) { FuncCall *n = makeNode(FuncCall); @@ -592,11 +592,12 @@ makeFuncCall(List *name, List *args, int location) n->args = args; n->agg_order = NIL; n->agg_filter = NULL; + n->over = NULL; n->agg_within_group = false; n->agg_star = false; n->agg_distinct = false; n->func_variadic = false; - n->over = NULL; + n->funcformat = funcformat; n->location = location; return n; } diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 7d647438bf16..a736bf9da631 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -3,7 +3,7 @@ * nodeFuncs.c * Various general-purpose manipulations of Node trees * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -72,15 +72,7 @@ exprType(const Node *expr) type = ((const WindowFunc *) expr)->wintype; break; case T_SubscriptingRef: - { - const SubscriptingRef *sbsref = (const SubscriptingRef *) expr; - - /* slice and/or store operations yield the container type */ - if (sbsref->reflowerindexpr || sbsref->refassgnexpr) - type = sbsref->refcontainertype; - else - type = sbsref->refelemtype; - } + type = ((const SubscriptingRef *) expr)->refrestype; break; case T_FuncExpr: type = ((const FuncExpr *) expr)->funcresulttype; @@ -305,7 +297,6 @@ exprTypmod(const Node *expr) case T_Param: return ((const Param *) expr)->paramtypmod; case T_SubscriptingRef: - /* typmod is the same for container or element */ return ((const SubscriptingRef *) expr)->reftypmod; case T_FuncExpr: { @@ -460,7 +451,7 @@ exprTypmod(const Node *expr) typmod = exprTypmod((Node *) linitial(cexpr->args)); if (typmod < 0) return -1; /* no point in trying harder */ - for_each_cell(arg, cexpr->args, list_second_cell(cexpr->args)) + for_each_from(arg, cexpr->args, 1) { Node *e = (Node *) lfirst(arg); @@ -488,7 +479,7 @@ exprTypmod(const Node *expr) typmod = exprTypmod((Node *) linitial(mexpr->args)); if (typmod < 0) return -1; /* no point in trying harder */ - for_each_cell(arg, mexpr->args, list_second_cell(mexpr->args)) + for_each_from(arg, mexpr->args, 1) { Node *e = (Node *) lfirst(arg); @@ -836,10 +827,12 @@ exprCollation(const Node *expr) coll = ((const NullIfExpr *) expr)->opcollid; break; case T_ScalarArrayOpExpr: - coll = InvalidOid; /* result is always boolean */ + /* ScalarArrayOpExpr's result is boolean ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_BoolExpr: - coll = InvalidOid; /* result is always boolean */ + /* BoolExpr's result is boolean ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_SubLink: { @@ -861,8 +854,8 @@ exprCollation(const Node *expr) } else { - /* otherwise, result is RECORD or BOOLEAN */ - coll = InvalidOid; + /* otherwise, SubLink's result is RECORD or BOOLEAN */ + coll = InvalidOid; /* ... so it has no collation */ } } break; @@ -879,8 +872,8 @@ exprCollation(const Node *expr) } else { - /* otherwise, result is RECORD or BOOLEAN */ - coll = InvalidOid; + /* otherwise, SubPlan's result is RECORD or BOOLEAN */ + coll = InvalidOid; /* ... so it has no collation */ } } break; @@ -896,7 +889,8 @@ exprCollation(const Node *expr) coll = ((const FieldSelect *) expr)->resultcollid; break; case T_FieldStore: - coll = InvalidOid; /* result is always composite */ + /* FieldStore's result is composite ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_RelabelType: coll = ((const RelabelType *) expr)->resultcollid; @@ -908,7 +902,8 @@ exprCollation(const Node *expr) coll = ((const ArrayCoerceExpr *) expr)->resultcollid; break; case T_ConvertRowtypeExpr: - coll = InvalidOid; /* result is always composite */ + /* ConvertRowtypeExpr's result is composite ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_CollateExpr: coll = ((const CollateExpr *) expr)->collOid; @@ -923,13 +918,15 @@ exprCollation(const Node *expr) coll = ((const ArrayExpr *) expr)->array_collid; break; case T_RowExpr: - coll = InvalidOid; /* result is always composite */ + /* RowExpr's result is composite ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_TableValueExpr: coll = InvalidOid; /* result is always anytable */ break; case T_RowCompareExpr: - coll = InvalidOid; /* result is always boolean */ + /* RowCompareExpr's result is boolean ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_CoalesceExpr: coll = ((const CoalesceExpr *) expr)->coalescecollid; @@ -957,10 +954,12 @@ exprCollation(const Node *expr) coll = InvalidOid; break; case T_NullTest: - coll = InvalidOid; /* result is always boolean */ + /* NullTest's result is boolean ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_BooleanTest: - coll = InvalidOid; /* result is always boolean */ + /* BooleanTest's result is boolean ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_CoerceToDomain: coll = ((const CoerceToDomain *) expr)->resultcollid; @@ -972,10 +971,12 @@ exprCollation(const Node *expr) coll = ((const SetToDefault *) expr)->collation; break; case T_CurrentOfExpr: - coll = InvalidOid; /* result is always boolean */ + /* CurrentOfExpr's result is boolean ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_NextValueExpr: - coll = InvalidOid; /* result is always an integer type */ + /* NextValueExpr's result is an integer type ... */ + coll = InvalidOid; /* ... so it has no collation */ break; case T_InferenceElem: coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr); @@ -1099,10 +1100,12 @@ exprSetCollation(Node *expr, Oid collation) ((NullIfExpr *) expr)->opcollid = collation; break; case T_ScalarArrayOpExpr: - Assert(!OidIsValid(collation)); /* result is always boolean */ + /* ScalarArrayOpExpr's result is boolean ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_BoolExpr: - Assert(!OidIsValid(collation)); /* result is always boolean */ + /* BoolExpr's result is boolean ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_SubLink: #ifdef USE_ASSERT_CHECKING @@ -1134,7 +1137,8 @@ exprSetCollation(Node *expr, Oid collation) ((FieldSelect *) expr)->resultcollid = collation; break; case T_FieldStore: - Assert(!OidIsValid(collation)); /* result is always composite */ + /* FieldStore's result is composite ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_RelabelType: ((RelabelType *) expr)->resultcollid = collation; @@ -1146,7 +1150,8 @@ exprSetCollation(Node *expr, Oid collation) ((ArrayCoerceExpr *) expr)->resultcollid = collation; break; case T_ConvertRowtypeExpr: - Assert(!OidIsValid(collation)); /* result is always composite */ + /* ConvertRowtypeExpr's result is composite ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_CaseExpr: ((CaseExpr *) expr)->casecollid = collation; @@ -1155,13 +1160,15 @@ exprSetCollation(Node *expr, Oid collation) ((ArrayExpr *) expr)->array_collid = collation; break; case T_RowExpr: - Assert(!OidIsValid(collation)); /* result is always composite */ + /* RowExpr's result is composite ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_TableValueExpr: Assert(!OidIsValid(collation)); /* result is always anytable */ break; case T_RowCompareExpr: - Assert(!OidIsValid(collation)); /* result is always boolean */ + /* RowCompareExpr's result is boolean ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_CoalesceExpr: ((CoalesceExpr *) expr)->coalescecollid = collation; @@ -1180,10 +1187,12 @@ exprSetCollation(Node *expr, Oid collation) (collation == InvalidOid)); break; case T_NullTest: - Assert(!OidIsValid(collation)); /* result is always boolean */ + /* NullTest's result is boolean ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_BooleanTest: - Assert(!OidIsValid(collation)); /* result is always boolean */ + /* BooleanTest's result is boolean ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_CoerceToDomain: ((CoerceToDomain *) expr)->resultcollid = collation; @@ -1195,11 +1204,12 @@ exprSetCollation(Node *expr, Oid collation) ((SetToDefault *) expr)->collation = collation; break; case T_CurrentOfExpr: - Assert(!OidIsValid(collation)); /* result is always boolean */ + /* CurrentOfExpr's result is boolean ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; case T_NextValueExpr: - Assert(!OidIsValid(collation)); /* result is always an integer - * type */ + /* NextValueExpr's result is an integer type ... */ + Assert(!OidIsValid(collation)); /* ... so never set a collation */ break; default: @@ -1629,6 +1639,12 @@ exprLocation(const Node *expr) case T_OnConflictClause: loc = ((const OnConflictClause *) expr)->location; break; + case T_CTESearchClause: + loc = ((const CTESearchClause *) expr)->location; + break; + case T_CTECycleClause: + loc = ((const CTECycleClause *) expr)->location; + break; case T_CommonTableExpr: loc = ((const CommonTableExpr *) expr)->location; break; @@ -1976,6 +1992,7 @@ expression_tree_walker(Node *node, case T_DMLActionExpr: case T_AggExprId: case T_RowIdExpr: + case T_CTESearchClause: /* primitive node types with no expression subnodes */ break; case T_WithCheckOption: @@ -2204,6 +2221,30 @@ expression_tree_walker(Node *node, case T_Query: /* Do nothing with a sub-Query, per discussion above */ break; + case T_WindowClause: + { + WindowClause *wc = (WindowClause *) node; + + if (walker(wc->partitionClause, context)) + return true; + if (walker(wc->orderClause, context)) + return true; + if (walker(wc->startOffset, context)) + return true; + if (walker(wc->endOffset, context)) + return true; + } + break; + case T_CTECycleClause: + { + CTECycleClause *cc = (CTECycleClause *) node; + + if (walker(cc->cycle_mark_value, context)) + return true; + if (walker(cc->cycle_mark_default, context)) + return true; + } + break; case T_CommonTableExpr: { CommonTableExpr *cte = (CommonTableExpr *) node; @@ -2212,7 +2253,13 @@ expression_tree_walker(Node *node, * Invoke the walker on the CTE's Query node, so it can * recurse into the sub-query if it wants to. */ - return walker(cte->ctequery, context); + if (walker(cte->ctequery, context)) + return true; + + if (walker(cte->search_clause, context)) + return true; + if (walker(cte->cycle_clause, context)) + return true; } break; case T_List: @@ -2347,24 +2394,6 @@ expression_tree_walker(Node *node, return walker(expr->subquery, context); } break; - case T_WindowClause: - { - WindowClause *wc = (WindowClause *) node; - - if (expression_tree_walker((Node *) wc->partitionClause, walker, - context)) - return true; - if (expression_tree_walker((Node *) wc->orderClause, walker, - context)) - return true; - if (walker((Node *) wc->startOffset, context)) - return true; - if (walker((Node *) wc->endOffset, context)) - return true; - return false; - } - break; - case T_TableSampleClause: { TableSampleClause *tsc = (TableSampleClause *) node; @@ -2786,6 +2815,8 @@ expression_tree_mutator(Node *node, case T_RangeTblRef: case T_String: case T_Null: + case T_SortGroupClause: + case T_CTESearchClause: return (Node *) copyObject(node); case T_WithCheckOption: { @@ -3232,6 +3263,18 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } + break; + case T_CTECycleClause: + { + CTECycleClause *cc = (CTECycleClause *) node; + CTECycleClause *newnode; + + FLATCOPY(newnode, cc, CTECycleClause); + MUTATE(newnode->cycle_mark_value, cc->cycle_mark_value, Node *); + MUTATE(newnode->cycle_mark_default, cc->cycle_mark_default, Node *); + return (Node *) newnode; + } + break; case T_CommonTableExpr: { CommonTableExpr *cte = (CommonTableExpr *) node; @@ -3244,6 +3287,10 @@ expression_tree_mutator(Node *node, * recurse into the sub-query if it wants to. */ MUTATE(newnode->ctequery, cte->ctequery, Node *); + + MUTATE(newnode->search_clause, cte->search_clause, CTESearchClause *); + MUTATE(newnode->cycle_clause, cte->cycle_clause, CTECycleClause *); + return (Node *) newnode; } break; @@ -3422,16 +3469,6 @@ expression_tree_mutator(Node *node, } break; - case T_SortGroupClause: - { - SortGroupClause *sortcl = (SortGroupClause *) node; - SortGroupClause *newnode; - - FLATCOPY(newnode, sortcl, SortGroupClause); - - return (Node *) newnode; - } - break; case T_DMLActionExpr: { DMLActionExpr *action_expr = (DMLActionExpr *) node; @@ -3955,6 +3992,16 @@ raw_expression_tree_walker(Node *node, return true; } break; + case T_PLAssignStmt: + { + PLAssignStmt *stmt = (PLAssignStmt *) node; + + if (walker(stmt->indirection, context)) + return true; + if (walker(stmt->val, context)) + return true; + } + break; case T_A_Expr: { A_Expr *expr = (A_Expr *) node; @@ -4134,6 +4181,8 @@ raw_expression_tree_walker(Node *node, if (walker(coldef->typeName, context)) return true; + if (walker(coldef->compression, context)) + return true; if (walker(coldef->raw_default, context)) return true; if (walker(coldef->collClause, context)) @@ -4189,6 +4238,7 @@ raw_expression_tree_walker(Node *node, } break; case T_CommonTableExpr: + /* search_clause and cycle_clause are not interesting here */ return walker(((CommonTableExpr *) node)->ctequery, context); default: elog(ERROR, "unrecognized node type: %d", @@ -4236,12 +4286,6 @@ planstate_tree_walker(PlanState *planstate, /* special child plans */ switch (nodeTag(plan)) { - case T_ModifyTable: - if (planstate_walk_members(((ModifyTableState *) planstate)->mt_plans, - ((ModifyTableState *) planstate)->mt_nplans, - walker, context)) - return true; - break; case T_Append: if (planstate_walk_members(((AppendState *) planstate)->appendplans, ((AppendState *) planstate)->as_nplans, diff --git a/src/backend/nodes/nodes.c b/src/backend/nodes/nodes.c index e5dcda3f58ca..a292b412f282 100644 --- a/src/backend/nodes/nodes.c +++ b/src/backend/nodes/nodes.c @@ -4,7 +4,7 @@ * support code for nodes (now that we have removed the home-brew * inheritance system, our support code for nodes is much simpler) * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/nodes/outfast.c b/src/backend/nodes/outfast.c index 6e38339fe6a4..bffba2bb5995 100644 --- a/src/backend/nodes/outfast.c +++ b/src/backend/nodes/outfast.c @@ -393,6 +393,7 @@ _outJoinExpr(StringInfo str, JoinExpr *node) WRITE_NODE_FIELD(larg); WRITE_NODE_FIELD(rarg); WRITE_NODE_FIELD(usingClause); + WRITE_NODE_FIELD(join_using_alias); WRITE_NODE_FIELD(quals); WRITE_NODE_FIELD(alias); WRITE_INT_FIELD(rtindex); @@ -558,6 +559,10 @@ _outAExpr(StringInfo str, A_Expr *node) break; case AEXPR_DISTINCT: + WRITE_NODE_FIELD(name); + break; + case AEXPR_NOT_DISTINCT: + WRITE_NODE_FIELD(name); break; case AEXPR_NULLIF: @@ -600,10 +605,6 @@ _outAExpr(StringInfo str, A_Expr *node) WRITE_NODE_FIELD(name); break; - case AEXPR_PAREN: - - break; - default: break; @@ -1356,6 +1357,9 @@ _outNode(StringInfo str, void *obj) case T_CreateFunctionStmt: _outCreateFunctionStmt(str, obj); break; + case T_ReturnStmt: + _outReturnStmt(str, obj); + break; case T_FunctionParameter: _outFunctionParameter(str, obj); break; @@ -1544,6 +1548,21 @@ _outNode(StringInfo str, void *obj) case T_IndexElem: _outIndexElem(str, obj); break; + case T_StatsElem: + _outStatsElem(str, obj); + break; + case T_WindowDef: + _outWindowDef(str, obj); + break; + case T_RangeSubselect: + _outRangeSubselect(str, obj); + break; + case T_InferClause: + _outInferClause(str, obj); + break; + case T_OnConflictClause: + _outOnConflictClause(str, obj); + break; case T_Query: _outQuery(str, obj); break; @@ -1565,6 +1584,12 @@ _outNode(StringInfo str, void *obj) case T_WithClause: _outWithClause(str, obj); break; + case T_CTESearchClause: + _outCTESearchClause(str, obj); + break; + case T_CTECycleClause: + _outCTECycleClause(str, obj); + break; case T_CommonTableExpr: _outCommonTableExpr(str, obj); break; @@ -1736,6 +1761,9 @@ _outNode(StringInfo str, void *obj) case T_AlterTypeStmtSetDefaultEnc: _outAlterTypeStmtSetDefaultEnc(str, obj); break; + case T_AlterTypeStmt: + _outAlterTypeStmt(str, obj); + break; case T_AlterExtensionStmt: _outAlterExtensionStmt(str, obj); break; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 0dcc83160bc0..97c23ef84268 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -351,7 +351,6 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node) WRITE_NODE_FIELD(planTree); WRITE_NODE_FIELD(rtable); WRITE_NODE_FIELD(resultRelations); - WRITE_NODE_FIELD(rootResultRelations); WRITE_NODE_FIELD(appendRelations); WRITE_NODE_FIELD(subplans); WRITE_BITMAPSET_FIELD(rewindPlanIDs); @@ -485,6 +484,7 @@ _outPlanInfo(StringInfo str, const Plan *node) WRITE_INT_FIELD(plan_width); WRITE_BOOL_FIELD(parallel_aware); WRITE_BOOL_FIELD(parallel_safe); + WRITE_BOOL_FIELD(async_capable); WRITE_INT_FIELD(plan_node_id); WRITE_NODE_FIELD(targetlist); WRITE_NODE_FIELD(qual); @@ -574,9 +574,7 @@ _outModifyTable(StringInfo str, const ModifyTable *node) WRITE_UINT_FIELD(rootRelation); WRITE_BOOL_FIELD(partColsUpdated); WRITE_NODE_FIELD(resultRelations); - WRITE_INT_FIELD(resultRelIndex); - WRITE_INT_FIELD(rootResultRelIndex); - WRITE_NODE_FIELD(plans); + WRITE_NODE_FIELD(updateColnosLists); WRITE_NODE_FIELD(withCheckOptionLists); WRITE_NODE_FIELD(returningLists); WRITE_NODE_FIELD(fdwPrivLists); @@ -586,6 +584,7 @@ _outModifyTable(StringInfo str, const ModifyTable *node) WRITE_ENUM_FIELD(onConflictAction, OnConflictAction); WRITE_NODE_FIELD(arbiterIndexes); WRITE_NODE_FIELD(onConflictSet); + WRITE_NODE_FIELD(onConflictCols); WRITE_NODE_FIELD(onConflictWhere); WRITE_UINT_FIELD(exclRelRTI); WRITE_NODE_FIELD(exclRelTlist); @@ -602,6 +601,7 @@ _outAppend(StringInfo str, const Append *node) WRITE_BITMAPSET_FIELD(apprelids); WRITE_NODE_FIELD(appendplans); + WRITE_INT_FIELD(nasyncplans); WRITE_INT_FIELD(first_partial_plan); WRITE_NODE_FIELD(part_prune_info); WRITE_NODE_FIELD(join_prune_paramids); @@ -864,6 +864,16 @@ _outTidScan(StringInfo str, const TidScan *node) WRITE_NODE_FIELD(tidquals); } +static void +_outTidRangeScan(StringInfo str, const TidRangeScan *node) +{ + WRITE_NODE_TYPE("TIDRANGESCAN"); + + _outScanInfo(str, (const Scan *) node); + + WRITE_NODE_FIELD(tidrangequals); +} + static void _outSubqueryScan(StringInfo str, const SubqueryScan *node) { @@ -947,6 +957,7 @@ _outForeignScan(StringInfo str, const ForeignScan *node) _outScanInfo(str, (const Scan *) node); WRITE_ENUM_FIELD(operation, CmdType); + WRITE_UINT_FIELD(resultRelation); WRITE_OID_FIELD(fs_server); WRITE_NODE_FIELD(fdw_exprs); WRITE_NODE_FIELD(fdw_private); @@ -1141,6 +1152,21 @@ _outShareInputScan(StringInfo str, const ShareInputScan *node) _outPlanInfo(str, (Plan *) node); } +static void +_outResultCache(StringInfo str, const ResultCache *node) +{ + WRITE_NODE_TYPE("RESULTCACHE"); + + _outPlanInfo(str, (const Plan *) node); + + WRITE_INT_FIELD(numKeys); + WRITE_OID_ARRAY(hashOperators, node->numKeys); + WRITE_OID_ARRAY(collations, node->numKeys); + WRITE_NODE_FIELD(param_exprs); + WRITE_BOOL_FIELD(singlerow); + WRITE_UINT_FIELD(est_entries); +} + static void _outSortInfo(StringInfo str, const Sort *node) { @@ -1564,6 +1590,8 @@ _outAggref(StringInfo str, const Aggref *node) WRITE_CHAR_FIELD(aggkind); WRITE_UINT_FIELD(agglevelsup); WRITE_ENUM_FIELD(aggsplit, AggSplit); + WRITE_INT_FIELD(aggno); + WRITE_INT_FIELD(aggtransno); WRITE_LOCATION_FIELD(location); WRITE_INT_FIELD(agg_expr_id); } @@ -1622,6 +1650,7 @@ _outSubscriptingRef(StringInfo str, const SubscriptingRef *node) WRITE_OID_FIELD(refcontainertype); WRITE_OID_FIELD(refelemtype); + WRITE_OID_FIELD(refrestype); WRITE_INT_FIELD(reftypmod); WRITE_OID_FIELD(refcollid); WRITE_NODE_FIELD(refupperindexpr); @@ -1710,6 +1739,7 @@ _outScalarArrayOpExpr(StringInfo str, const ScalarArrayOpExpr *node) WRITE_OID_FIELD(opno); WRITE_OID_FIELD(opfuncid); + WRITE_OID_FIELD(hashfuncid); WRITE_BOOL_FIELD(useOr); WRITE_OID_FIELD(inputcollid); WRITE_NODE_FIELD(args); @@ -2120,6 +2150,7 @@ _outJoinExpr(StringInfo str, const JoinExpr *node) WRITE_NODE_FIELD(larg); WRITE_NODE_FIELD(rarg); WRITE_NODE_FIELD(usingClause); + WRITE_NODE_FIELD(join_using_alias); WRITE_NODE_FIELD(quals); WRITE_NODE_FIELD(alias); WRITE_INT_FIELD(rtindex); @@ -2310,6 +2341,16 @@ _outTidPath(StringInfo str, const TidPath *node) WRITE_NODE_FIELD(tidquals); } +static void +_outTidRangePath(StringInfo str, const TidRangePath *node) +{ + WRITE_NODE_TYPE("TIDRANGEPATH"); + + _outPathInfo(str, (const Path *) node); + + WRITE_NODE_FIELD(tidrangequals); +} + static void _outSubqueryScanPath(StringInfo str, const SubqueryScanPath *node) { @@ -2362,7 +2403,6 @@ _outAppendPath(StringInfo str, const AppendPath *node) _outPathInfo(str, (const Path *) node); - WRITE_NODE_FIELD(partitioned_rels); WRITE_NODE_FIELD(subpaths); WRITE_INT_FIELD(first_partial_path); WRITE_FLOAT_FIELD(limit_tuples, "%.0f"); @@ -2375,7 +2415,6 @@ _outMergeAppendPath(StringInfo str, const MergeAppendPath *node) _outPathInfo(str, (const Path *) node); - WRITE_NODE_FIELD(partitioned_rels); WRITE_NODE_FIELD(subpaths); WRITE_FLOAT_FIELD(limit_tuples, "%.0f"); } @@ -2418,6 +2457,21 @@ _outMaterialPath(StringInfo str, const MaterialPath *node) WRITE_NODE_FIELD(subpath); } +static void +_outResultCachePath(StringInfo str, const ResultCachePath *node) +{ + WRITE_NODE_TYPE("RESULTCACHEPATH"); + + _outPathInfo(str, (const Path *) node); + + WRITE_NODE_FIELD(subpath); + WRITE_NODE_FIELD(hash_operators); + WRITE_NODE_FIELD(param_exprs); + WRITE_BOOL_FIELD(singlerow); + WRITE_FLOAT_FIELD(calls, "%.0f"); + WRITE_UINT_FIELD(est_entries); +} + static void _outUniquePath(StringInfo str, const UniquePath *node) { @@ -2464,14 +2518,30 @@ _outProjectSetPath(StringInfo str, const ProjectSetPath *node) WRITE_NODE_FIELD(subpath); } +static void +_outSortPathInfo(StringInfo str, const SortPath *node) +{ + _outPathInfo(str, (const Path *) node); + + WRITE_NODE_FIELD(subpath); +} + static void _outSortPath(StringInfo str, const SortPath *node) { WRITE_NODE_TYPE("SORTPATH"); - _outPathInfo(str, (const Path *) node); + _outSortPathInfo(str, node); +} - WRITE_NODE_FIELD(subpath); +static void +_outIncrementalSortPath(StringInfo str, const IncrementalSortPath *node) +{ + WRITE_NODE_TYPE("INCREMENTALSORTPATH"); + + _outSortPathInfo(str, (const SortPath *) node); + + WRITE_INT_FIELD(nPresortedCols); } static void @@ -2621,14 +2691,14 @@ _outModifyTablePath(StringInfo str, const ModifyTablePath *node) _outPathInfo(str, (const Path *) node); + WRITE_NODE_FIELD(subpath); WRITE_ENUM_FIELD(operation, CmdType); WRITE_BOOL_FIELD(canSetTag); WRITE_UINT_FIELD(nominalRelation); WRITE_UINT_FIELD(rootRelation); WRITE_BOOL_FIELD(partColsUpdated); WRITE_NODE_FIELD(resultRelations); - WRITE_NODE_FIELD(subpaths); - WRITE_NODE_FIELD(subroots); + WRITE_NODE_FIELD(updateColnosLists); WRITE_NODE_FIELD(withCheckOptionLists); WRITE_NODE_FIELD(returningLists); WRITE_NODE_FIELD(rowMarks); @@ -2715,7 +2785,6 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node) WRITE_NODE_FIELD(finalrtable); WRITE_NODE_FIELD(finalrowmarks); WRITE_NODE_FIELD(resultRelations); - WRITE_NODE_FIELD(rootResultRelations); WRITE_NODE_FIELD(appendRelations); WRITE_NODE_FIELD(relationOids); WRITE_NODE_FIELD(invalItems); @@ -2759,7 +2828,10 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node) WRITE_NODE_FIELD(right_join_clauses); WRITE_NODE_FIELD(full_join_clauses); WRITE_NODE_FIELD(join_info_list); + WRITE_BITMAPSET_FIELD(all_result_relids); + WRITE_BITMAPSET_FIELD(leaf_result_relids); WRITE_NODE_FIELD(append_rel_list); + WRITE_NODE_FIELD(row_identity_vars); WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(placeholder_list); WRITE_NODE_FIELD(fkey_list); @@ -2769,16 +2841,17 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node) WRITE_NODE_FIELD(distinct_pathkeys); WRITE_NODE_FIELD(sort_pathkeys); WRITE_NODE_FIELD(processed_tlist); + WRITE_NODE_FIELD(update_colnos); WRITE_NODE_FIELD(minmax_aggs); WRITE_FLOAT_FIELD(total_table_pages, "%.0f"); WRITE_FLOAT_FIELD(tuple_fraction, "%.4f"); WRITE_FLOAT_FIELD(limit_tuples, "%.0f"); WRITE_UINT_FIELD(qual_security_level); - WRITE_ENUM_FIELD(inhTargetKind, InheritanceKind); WRITE_BOOL_FIELD(hasJoinRTEs); WRITE_BOOL_FIELD(hasLateralRTEs); WRITE_BOOL_FIELD(hasHavingQual); WRITE_BOOL_FIELD(hasPseudoConstantQuals); + WRITE_BOOL_FIELD(hasAlternativeSubPlans); WRITE_BOOL_FIELD(hasRecursion); WRITE_INT_FIELD(wt_param_id); WRITE_BITMAPSET_FIELD(curOuterRels); @@ -2826,6 +2899,7 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node) WRITE_NODE_FIELD(subroot); WRITE_NODE_FIELD(subplan_params); WRITE_INT_FIELD(rel_parallel_workers); + WRITE_UINT_FIELD(amflags); WRITE_OID_FIELD(serverid); WRITE_OID_FIELD(userid); WRITE_BOOL_FIELD(useridiscurrent); @@ -2839,7 +2913,6 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node) WRITE_BITMAPSET_FIELD(top_parent_relids); WRITE_BOOL_FIELD(partbounds_merged); WRITE_BITMAPSET_FIELD(all_partrels); - WRITE_NODE_FIELD(partitioned_child_rels); } #endif /* COMPILING_BINARY_FUNCS */ @@ -2884,6 +2957,7 @@ _outForeignKeyOptInfo(StringInfo str, const ForeignKeyOptInfo *node) WRITE_ATTRNUMBER_ARRAY(confkey, node->nkeys); WRITE_OID_ARRAY(conpfeqop, node->nkeys); WRITE_INT_FIELD(nmatched_ec); + WRITE_INT_FIELD(nconst_ec); WRITE_INT_FIELD(nmatched_rcols); WRITE_INT_FIELD(nmatched_ri); /* for compactness, just print the number of matches per column: */ @@ -2984,6 +3058,7 @@ _outPathTarget(StringInfo str, const PathTarget *node) WRITE_FLOAT_FIELD(cost.startup, "%.2f"); WRITE_FLOAT_FIELD(cost.per_tuple, "%.2f"); WRITE_INT_FIELD(width); + WRITE_ENUM_FIELD(has_volatile_expr, VolatileFunctionStatus); } static void @@ -3008,8 +3083,9 @@ _outRestrictInfo(StringInfo str, const RestrictInfo *node) WRITE_BOOL_FIELD(outerjoin_delayed); WRITE_BOOL_FIELD(can_join); WRITE_BOOL_FIELD(pseudoconstant); - WRITE_BOOL_FIELD(leakproof); - WRITE_UINT_FIELD(security_level); + WRITE_BOOL_FIELD(leakproof); + WRITE_ENUM_FIELD(has_volatile, VolatileFunctionStatus); + WRITE_UINT_FIELD(security_level); WRITE_BOOL_FIELD(contain_outer_query_references); WRITE_BITMAPSET_FIELD(clause_relids); WRITE_BITMAPSET_FIELD(required_relids); @@ -3028,6 +3104,7 @@ _outRestrictInfo(StringInfo str, const RestrictInfo *node) WRITE_NODE_FIELD(right_em); WRITE_BOOL_FIELD(outer_is_left); WRITE_OID_FIELD(hashjoinoperator); + WRITE_OID_FIELD(hasheqoperator); } #ifndef COMPILING_BINARY_FUNCS @@ -3089,6 +3166,17 @@ _outAppendRelInfo(StringInfo str, const AppendRelInfo *node) } #ifndef COMPILING_BINARY_FUNCS +static void +_outRowIdentityVarInfo(StringInfo str, const RowIdentityVarInfo *node) +{ + WRITE_NODE_TYPE("ROWIDENTITYVARINFO"); + + WRITE_NODE_FIELD(rowidvar); + WRITE_INT_FIELD(rowidwidth); + WRITE_STRING_FIELD(rowidname); + WRITE_BITMAPSET_FIELD(rowidrels); +} + static void _outPlaceHolderInfo(StringInfo str, const PlaceHolderInfo *node) { @@ -3749,6 +3837,7 @@ _outCreateFunctionStmt(StringInfo str, const CreateFunctionStmt *node) WRITE_NODE_FIELD(parameters); WRITE_NODE_FIELD(returnType); WRITE_NODE_FIELD(options); + WRITE_NODE_FIELD(sql_body); } static void @@ -3942,6 +4031,7 @@ _outCreateStatsStmt(StringInfo str, const CreateStatsStmt *node) WRITE_NODE_FIELD(exprs); WRITE_NODE_FIELD(relations); WRITE_STRING_FIELD(stxcomment); + WRITE_BOOL_FIELD(transformed); WRITE_BOOL_FIELD(if_not_exists); } @@ -4072,6 +4162,7 @@ _outSelectStmt(StringInfo str, const SelectStmt *node) WRITE_NODE_FIELD(fromClause); WRITE_NODE_FIELD(whereClause); WRITE_NODE_FIELD(groupClause); + WRITE_BOOL_FIELD(groupDistinct); WRITE_NODE_FIELD(havingClause); WRITE_NODE_FIELD(windowClause); WRITE_NODE_FIELD(valuesLists); @@ -4097,8 +4188,10 @@ _outInsertStmt(StringInfo str, const InsertStmt *node) WRITE_NODE_FIELD(relation); WRITE_NODE_FIELD(cols); WRITE_NODE_FIELD(selectStmt); + WRITE_NODE_FIELD(onConflictClause); WRITE_NODE_FIELD(returningList); WRITE_NODE_FIELD(withClause); + WRITE_ENUM_FIELD(override, OverridingKind); } static void @@ -4126,6 +4219,26 @@ _outUpdateStmt(StringInfo str, const UpdateStmt *node) WRITE_NODE_FIELD(withClause); } +static void +_outReturnStmt(StringInfo str, const ReturnStmt *node) +{ + WRITE_NODE_TYPE("RETURN"); + + WRITE_NODE_FIELD(returnval); +} + +static void +_outPLAssignStmt(StringInfo str, const PLAssignStmt *node) +{ + WRITE_NODE_TYPE("PLASSIGN"); + + WRITE_STRING_FIELD(name); + WRITE_NODE_FIELD(indirection); + WRITE_INT_FIELD(nnames); + WRITE_NODE_FIELD(val); + WRITE_LOCATION_FIELD(location); +} + static void _outFuncCall(StringInfo str, const FuncCall *node) { @@ -4135,11 +4248,12 @@ _outFuncCall(StringInfo str, const FuncCall *node) WRITE_NODE_FIELD(args); WRITE_NODE_FIELD(agg_order); WRITE_NODE_FIELD(agg_filter); + WRITE_NODE_FIELD(over); WRITE_BOOL_FIELD(agg_within_group); WRITE_BOOL_FIELD(agg_star); WRITE_BOOL_FIELD(agg_distinct); WRITE_BOOL_FIELD(func_variadic); - WRITE_NODE_FIELD(over); + WRITE_ENUM_FIELD(funcformat, CoercionForm); WRITE_LOCATION_FIELD(location); } @@ -4162,6 +4276,7 @@ _outTableLikeClause(StringInfo str, const TableLikeClause *node) WRITE_NODE_FIELD(relation); WRITE_UINT_FIELD(options); + WRITE_OID_FIELD(relationOid); } static void @@ -4208,6 +4323,7 @@ _outColumnDef(StringInfo str, const ColumnDef *node) WRITE_STRING_FIELD(colname); WRITE_NODE_FIELD(typeName); + WRITE_STRING_FIELD(compression); WRITE_INT_FIELD(inhcount); WRITE_BOOL_FIELD(is_local); WRITE_BOOL_FIELD(is_not_null); @@ -4283,6 +4399,15 @@ _outIndexElem(StringInfo str, const IndexElem *node) WRITE_ENUM_FIELD(nulls_ordering, SortByNulls); } +static void +_outStatsElem(StringInfo str, const StatsElem *node) +{ + WRITE_NODE_TYPE("STATSELEM"); + + WRITE_STRING_FIELD(name); + WRITE_NODE_FIELD(expr); +} + static void _outVariableSetStmt(StringInfo str, const VariableSetStmt *node) { @@ -4393,6 +4518,7 @@ _outQuery(StringInfo str, const Query *node) WRITE_BOOL_FIELD(hasForUpdate); WRITE_BOOL_FIELD(hasRowSecurity); WRITE_BOOL_FIELD(canOptSelectLockingClause); + WRITE_BOOL_FIELD(isReturn); WRITE_NODE_FIELD(cteList); WRITE_NODE_FIELD(rtable); WRITE_NODE_FIELD(jointree); @@ -4401,6 +4527,7 @@ _outQuery(StringInfo str, const Query *node) WRITE_NODE_FIELD(onConflict); WRITE_NODE_FIELD(returningList); WRITE_NODE_FIELD(groupClause); + WRITE_BOOL_FIELD(groupDistinct); WRITE_NODE_FIELD(groupingSets); WRITE_NODE_FIELD(havingQual); WRITE_NODE_FIELD(windowClause); @@ -4499,6 +4626,34 @@ _outWithClause(StringInfo str, const WithClause *node) WRITE_LOCATION_FIELD(location); } +static void +_outCTESearchClause(StringInfo str, const CTESearchClause *node) +{ + WRITE_NODE_TYPE("CTESEARCHCLAUSE"); + + WRITE_NODE_FIELD(search_col_list); + WRITE_BOOL_FIELD(search_breadth_first); + WRITE_STRING_FIELD(search_seq_column); + WRITE_LOCATION_FIELD(location); +} + +static void +_outCTECycleClause(StringInfo str, const CTECycleClause *node) +{ + WRITE_NODE_TYPE("CTECYCLECLAUSE"); + + WRITE_NODE_FIELD(cycle_col_list); + WRITE_STRING_FIELD(cycle_mark_column); + WRITE_NODE_FIELD(cycle_mark_value); + WRITE_NODE_FIELD(cycle_mark_default); + WRITE_STRING_FIELD(cycle_path_column); + WRITE_LOCATION_FIELD(location); + WRITE_OID_FIELD(cycle_mark_type); + WRITE_INT_FIELD(cycle_mark_typmod); + WRITE_OID_FIELD(cycle_mark_collation); + WRITE_OID_FIELD(cycle_mark_neop); +} + static void _outCommonTableExpr(StringInfo str, const CommonTableExpr *node) { @@ -4508,6 +4663,8 @@ _outCommonTableExpr(StringInfo str, const CommonTableExpr *node) WRITE_NODE_FIELD(aliascolnames); WRITE_ENUM_FIELD(ctematerialized, CTEMaterialize); WRITE_NODE_FIELD(ctequery); + WRITE_NODE_FIELD(search_clause); + WRITE_NODE_FIELD(cycle_clause); WRITE_LOCATION_FIELD(location); WRITE_BOOL_FIELD(cterecursive); WRITE_INT_FIELD(cterefcount); @@ -4560,6 +4717,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) WRITE_NODE_FIELD(joinaliasvars); WRITE_NODE_FIELD(joinleftcols); WRITE_NODE_FIELD(joinrightcols); + WRITE_NODE_FIELD(join_using_alias); break; case RTE_FUNCTION: WRITE_NODE_FIELD(functions); @@ -4717,9 +4875,6 @@ _outAExpr(StringInfo str, const A_Expr *node) appendStringInfoString(str, " NOT_BETWEEN_SYM "); WRITE_NODE_FIELD(name); break; - case AEXPR_PAREN: - appendStringInfoString(str, " PAREN"); - break; default: appendStringInfoString(str, " ??"); break; @@ -4893,7 +5048,6 @@ _outSortBy(StringInfo str, const SortBy *node) WRITE_LOCATION_FIELD(location); } -#ifndef COMPILING_BINARY_FUNCS static void _outWindowDef(StringInfo str, const WindowDef *node) { @@ -4919,6 +5073,30 @@ _outRangeSubselect(StringInfo str, const RangeSubselect *node) WRITE_NODE_FIELD(alias); } +static void +_outInferClause(StringInfo str, const InferClause *node) +{ + WRITE_NODE_TYPE("INFERCLAUSE"); + + WRITE_NODE_FIELD(indexElems); + WRITE_NODE_FIELD(whereClause); + WRITE_STRING_FIELD(conname); + WRITE_LOCATION_FIELD(location); +} + +static void +_outOnConflictClause(StringInfo str, const OnConflictClause *node) +{ + WRITE_NODE_TYPE("ONCONFLICTCLAUSE"); + + WRITE_ENUM_FIELD(action, OnConflictAction); + WRITE_NODE_FIELD(infer); + WRITE_NODE_FIELD(targetList); + WRITE_NODE_FIELD(whereClause); + WRITE_LOCATION_FIELD(location); +} + +#ifndef COMPILING_BINARY_FUNCS static void _outRangeFunction(StringInfo str, const RangeFunction *node) { @@ -5338,6 +5516,15 @@ _outAlterTypeStmtSetDefaultEnc(StringInfo str, const AlterTypeStmtSetDefaultEnc WRITE_NODE_FIELD(encoding); } +static void +_outAlterTypeStmt(StringInfo str, const AlterTypeStmt *node) +{ + WRITE_NODE_TYPE("ALTERTYPESTMT"); + + WRITE_NODE_FIELD(typeName); + WRITE_NODE_FIELD(options); +} + static void _outAlterExtensionStmt(StringInfo str, const AlterExtensionStmt *node) { @@ -5627,6 +5814,9 @@ outNode(StringInfo str, const void *obj) case T_TidScan: _outTidScan(str, obj); break; + case T_TidRangeScan: + _outTidRangeScan(str, obj); + break; case T_SubqueryScan: _outSubqueryScan(str, obj); break; @@ -5687,6 +5877,9 @@ outNode(StringInfo str, const void *obj) case T_ShareInputScan: _outShareInputScan(str, obj); break; + case T_ResultCache: + _outResultCache(str, obj); + break; case T_Sort: _outSort(str, obj); break; @@ -5927,6 +6120,9 @@ outNode(StringInfo str, const void *obj) case T_TidPath: _outTidPath(str, obj); break; + case T_TidRangePath: + _outTidRangePath(str, obj); + break; case T_SubqueryScanPath: _outSubqueryScanPath(str, obj); break; @@ -5957,6 +6153,9 @@ outNode(StringInfo str, const void *obj) case T_MaterialPath: _outMaterialPath(str, obj); break; + case T_ResultCachePath: + _outResultCachePath(str, obj); + break; case T_UniquePath: _outUniquePath(str, obj); break; @@ -5972,6 +6171,9 @@ outNode(StringInfo str, const void *obj) case T_SortPath: _outSortPath(str, obj); break; + case T_IncrementalSortPath: + _outIncrementalSortPath(str, obj); + break; case T_GroupPath: _outGroupPath(str, obj); break; @@ -6068,6 +6270,9 @@ outNode(StringInfo str, const void *obj) case T_AppendRelInfo: _outAppendRelInfo(str, obj); break; + case T_RowIdentityVarInfo: + _outRowIdentityVarInfo(str, obj); + break; case T_PlaceHolderInfo: _outPlaceHolderInfo(str, obj); break; @@ -6293,6 +6498,12 @@ outNode(StringInfo str, const void *obj) case T_SelectStmt: _outSelectStmt(str, obj); break; + case T_ReturnStmt: + _outReturnStmt(str, obj); + break; + case T_PLAssignStmt: + _outPLAssignStmt(str, obj); + break; case T_InsertStmt: _outInsertStmt(str, obj); break; @@ -6320,6 +6531,9 @@ outNode(StringInfo str, const void *obj) case T_IndexElem: _outIndexElem(str, obj); break; + case T_StatsElem: + _outStatsElem(str, obj); + break; case T_Query: _outQuery(str, obj); break; @@ -6341,6 +6555,12 @@ outNode(StringInfo str, const void *obj) case T_WithClause: _outWithClause(str, obj); break; + case T_CTESearchClause: + _outCTESearchClause(str, obj); + break; + case T_CTECycleClause: + _outCTECycleClause(str, obj); + break; case T_CommonTableExpr: _outCommonTableExpr(str, obj); break; @@ -6398,6 +6618,12 @@ outNode(StringInfo str, const void *obj) case T_RangeSubselect: _outRangeSubselect(str, obj); + break; + case T_InferClause: + _outInferClause(str, obj); + break; + case T_OnConflictClause: + _outOnConflictClause(str, obj); break; case T_RangeFunction: _outRangeFunction(str, obj); @@ -6538,6 +6764,9 @@ outNode(StringInfo str, const void *obj) case T_AlterTypeStmtSetDefaultEnc: _outAlterTypeStmtSetDefaultEnc(str, obj); break; + case T_AlterTypeStmt: + _outAlterTypeStmt(str, obj); + break; case T_AlterExtensionStmt: _outAlterExtensionStmt(str, obj); break; diff --git a/src/backend/nodes/params.c b/src/backend/nodes/params.c index bce0c7e72b2c..45ebff5103e0 100644 --- a/src/backend/nodes/params.c +++ b/src/backend/nodes/params.c @@ -4,7 +4,7 @@ * Support for finding the values associated with Param nodes. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -414,9 +414,9 @@ ParamsErrorCallback(void *arg) return; if (data->portalName && data->portalName[0] != '\0') - errcontext("extended query \"%s\" with parameters: %s", + errcontext("portal \"%s\" with parameters: %s", data->portalName, data->params->paramValuesStr); else - errcontext("extended query with parameters: %s", + errcontext("unnamed portal with parameters: %s", data->params->paramValuesStr); } diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index 6b4c01064f47..81e433cc8035 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -3,7 +3,7 @@ * print.c * various print routines (used mostly for debugging) * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -404,7 +404,6 @@ print_expr(const Node *expr, const List *rtable) } else { - /* we print prefix and postfix ops the same... */ printf("%s ", ((opname != NULL) ? opname : "(invalid operator)")); print_expr(get_leftop((const Expr *) e), rtable); } diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c index 6af7a170948d..101447bbd39d 100644 --- a/src/backend/nodes/read.c +++ b/src/backend/nodes/read.c @@ -6,7 +6,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/nodes/readfast.c b/src/backend/nodes/readfast.c index 586724451084..bf512d828264 100644 --- a/src/backend/nodes/readfast.c +++ b/src/backend/nodes/readfast.c @@ -382,6 +382,7 @@ _readSelectStmt(void) READ_NODE_FIELD(fromClause); READ_NODE_FIELD(whereClause); READ_NODE_FIELD(groupClause); + READ_BOOL_FIELD(groupDistinct); READ_NODE_FIELD(havingClause); READ_NODE_FIELD(windowClause); READ_NODE_FIELD(valuesLists); @@ -400,6 +401,16 @@ _readSelectStmt(void) READ_DONE(); } +static ParamRef * +_readParamRef(void) +{ + READ_LOCALS(ParamRef); + + READ_INT_FIELD(number); + READ_LOCATION_FIELD(location); + READ_DONE(); +} + static InsertStmt * _readInsertStmt(void) { @@ -408,8 +419,10 @@ _readInsertStmt(void) READ_NODE_FIELD(relation); READ_NODE_FIELD(cols); READ_NODE_FIELD(selectStmt); + READ_NODE_FIELD(onConflictClause); READ_NODE_FIELD(returningList); READ_NODE_FIELD(withClause); + READ_ENUM_FIELD(override, OverridingKind); READ_DONE(); } @@ -520,7 +533,7 @@ _readAExpr(void) READ_ENUM_FIELD(kind, A_Expr_Kind); - Assert(local_node->kind <= AEXPR_PAREN); + Assert(local_node->kind <= AEXPR_NOT_BETWEEN_SYM); switch (local_node->kind) { @@ -540,6 +553,10 @@ _readAExpr(void) break; case AEXPR_DISTINCT: + READ_NODE_FIELD(name); + break; + case AEXPR_NOT_DISTINCT: + READ_NODE_FIELD(name); break; case AEXPR_NULLIF: @@ -580,10 +597,6 @@ _readAExpr(void) break; case AEXPR_NOT_BETWEEN_SYM: - READ_NODE_FIELD(name); - break; - case AEXPR_PAREN: - READ_NODE_FIELD(name); break; default: @@ -1554,6 +1567,64 @@ _readLockingClause(void) READ_NODE_FIELD(lockedRels); READ_ENUM_FIELD(strength, LockClauseStrength); + READ_ENUM_FIELD(waitPolicy, LockWaitPolicy); + + READ_DONE(); +} + +static WindowDef * +_readWindowDef(void) +{ + READ_LOCALS(WindowDef); + + READ_STRING_FIELD(name); + READ_STRING_FIELD(refname); + READ_NODE_FIELD(partitionClause); + READ_NODE_FIELD(orderClause); + READ_INT_FIELD(frameOptions); + READ_NODE_FIELD(startOffset); + READ_NODE_FIELD(endOffset); + READ_LOCATION_FIELD(location); + + READ_DONE(); +} + +static RangeFunction * +_readRangeFunction(void) +{ + READ_LOCALS(RangeFunction); + + READ_BOOL_FIELD(lateral); + READ_BOOL_FIELD(ordinality); + READ_BOOL_FIELD(is_rowsfrom); + READ_NODE_FIELD(functions); + READ_NODE_FIELD(alias); + READ_NODE_FIELD(coldeflist); + + READ_DONE(); +} + +static XmlSerialize * +_readXmlSerialize(void) +{ + READ_LOCALS(XmlSerialize); + + READ_ENUM_FIELD(xmloption, XmlOptionType); + READ_NODE_FIELD(expr); + READ_NODE_FIELD(typeName); + READ_LOCATION_FIELD(location); + + READ_DONE(); +} + +static TableLikeClause * +_readTableLikeClause(void) +{ + READ_LOCALS(TableLikeClause); + + READ_NODE_FIELD(relation); + READ_UINT_FIELD(options); + READ_OID_FIELD(relationOid); READ_DONE(); } @@ -2151,6 +2222,12 @@ readNodeBinary(void) case T_CreateFunctionStmt: return_value = _readCreateFunctionStmt(); break; + case T_ReturnStmt: + return_value = _readReturnStmt(); + break; + case T_RawStmt: + return_value = _readRawStmt(); + break; case T_FunctionParameter: return_value = _readFunctionParameter(); break; @@ -2312,6 +2389,9 @@ readNodeBinary(void) case T_InsertStmt: return_value = _readInsertStmt(); break; + case T_ParamRef: + return_value = _readParamRef(); + break; case T_DeleteStmt: return_value = _readDeleteStmt(); break; @@ -2336,6 +2416,12 @@ readNodeBinary(void) case T_IndexElem: return_value = _readIndexElem(); break; + case T_StatsElem: + return_value = _readStatsElem(); + break; + case T_CreateStatsStmt: + return_value = _readCreateStatsStmt(); + break; case T_Query: return_value = _readQuery(); break; @@ -2360,6 +2446,12 @@ readNodeBinary(void) case T_WithClause: return_value = _readWithClause(); break; + case T_CTESearchClause: + return_value = _readCTESearchClause(); + break; + case T_CTECycleClause: + return_value = _readCTECycleClause(); + break; case T_CommonTableExpr: return_value = _readCommonTableExpr(); break; @@ -2483,6 +2575,9 @@ readNodeBinary(void) case T_AlterTypeStmtSetDefaultEnc: return_value = _readAlterTypeStmtSetDefaultEnc(); break; + case T_AlterTypeStmt: + return_value = _readAlterTypeStmt(); + break; case T_AlterExtensionStmt: return_value = _readAlterExtensionStmt(); break; @@ -2576,6 +2671,27 @@ readNodeBinary(void) case T_CreateAmStmt: return_value = _readCreateAmStmt(); break; + case T_WindowDef: + return_value = _readWindowDef(); + break; + case T_RangeSubselect: + return_value = _readRangeSubselect(); + break; + case T_InferClause: + return_value = _readInferClause(); + break; + case T_OnConflictClause: + return_value = _readOnConflictClause(); + break; + case T_RangeFunction: + return_value = _readRangeFunction(); + break; + case T_XmlSerialize: + return_value = _readXmlSerialize(); + break; + case T_TableLikeClause: + return_value = _readTableLikeClause(); + break; case T_LockingClause: return_value = _readLockingClause(); break; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 2a4565786ee9..65aac2fbb35a 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -341,6 +341,7 @@ _readQuery(void) READ_BOOL_FIELD(hasForUpdate); READ_BOOL_FIELD(hasRowSecurity); READ_BOOL_FIELD(canOptSelectLockingClause); + READ_BOOL_FIELD(isReturn); READ_NODE_FIELD(cteList); READ_NODE_FIELD(rtable); READ_NODE_FIELD(jointree); @@ -349,6 +350,7 @@ _readQuery(void) READ_NODE_FIELD(onConflict); READ_NODE_FIELD(returningList); READ_NODE_FIELD(groupClause); + READ_BOOL_FIELD(groupDistinct); READ_NODE_FIELD(groupingSets); READ_NODE_FIELD(havingQual); READ_NODE_FIELD(windowClause); @@ -509,6 +511,44 @@ _readRowMarkClause(void) READ_DONE(); } +/* + * _readCTESearchClause + */ +static CTESearchClause * +_readCTESearchClause(void) +{ + READ_LOCALS(CTESearchClause); + + READ_NODE_FIELD(search_col_list); + READ_BOOL_FIELD(search_breadth_first); + READ_STRING_FIELD(search_seq_column); + READ_LOCATION_FIELD(location); + + READ_DONE(); +} + +/* + * _readCTECycleClause + */ +static CTECycleClause * +_readCTECycleClause(void) +{ + READ_LOCALS(CTECycleClause); + + READ_NODE_FIELD(cycle_col_list); + READ_STRING_FIELD(cycle_mark_column); + READ_NODE_FIELD(cycle_mark_value); + READ_NODE_FIELD(cycle_mark_default); + READ_STRING_FIELD(cycle_path_column); + READ_LOCATION_FIELD(location); + READ_OID_FIELD(cycle_mark_type); + READ_INT_FIELD(cycle_mark_typmod); + READ_OID_FIELD(cycle_mark_collation); + READ_OID_FIELD(cycle_mark_neop); + + READ_DONE(); +} + /* * _readCommonTableExpr */ @@ -521,6 +561,8 @@ _readCommonTableExpr(void) READ_NODE_FIELD(aliascolnames); READ_ENUM_FIELD(ctematerialized, CTEMaterialize); READ_NODE_FIELD(ctequery); + READ_NODE_FIELD(search_clause); + READ_NODE_FIELD(cycle_clause); READ_LOCATION_FIELD(location); READ_BOOL_FIELD(cterecursive); READ_INT_FIELD(cterefcount); @@ -812,6 +854,72 @@ _readIndexElem(void) READ_DONE(); } +static StatsElem * +_readStatsElem(void) +{ + READ_LOCALS(StatsElem); + + READ_STRING_FIELD(name); + READ_NODE_FIELD(expr); + + READ_DONE(); +} + +static CreateStatsStmt * +_readCreateStatsStmt(void) +{ + READ_LOCALS(CreateStatsStmt); + + READ_NODE_FIELD(defnames); + READ_NODE_FIELD(stat_types); + READ_NODE_FIELD(exprs); + READ_NODE_FIELD(relations); + READ_STRING_FIELD(stxcomment); + READ_BOOL_FIELD(transformed); + READ_BOOL_FIELD(if_not_exists); + + READ_DONE(); +} + +static RangeSubselect * +_readRangeSubselect(void) +{ + READ_LOCALS(RangeSubselect); + + READ_BOOL_FIELD(lateral); + READ_NODE_FIELD(subquery); + READ_NODE_FIELD(alias); + + READ_DONE(); +} + +static InferClause * +_readInferClause(void) +{ + READ_LOCALS(InferClause); + + READ_NODE_FIELD(indexElems); + READ_NODE_FIELD(whereClause); + READ_STRING_FIELD(conname); + READ_LOCATION_FIELD(location); + + READ_DONE(); +} + +static OnConflictClause * +_readOnConflictClause(void) +{ + READ_LOCALS(OnConflictClause); + + READ_ENUM_FIELD(action, OnConflictAction); + READ_NODE_FIELD(infer); + READ_NODE_FIELD(targetList); + READ_NODE_FIELD(whereClause); + READ_LOCATION_FIELD(location); + + READ_DONE(); +} + static ReindexStmt * _readReindexStmt(void) { @@ -1163,11 +1271,12 @@ _readFuncCall(void) READ_NODE_FIELD(args); READ_NODE_FIELD(agg_order); READ_NODE_FIELD(agg_filter); + READ_NODE_FIELD(over); READ_BOOL_FIELD(agg_within_group); READ_BOOL_FIELD(agg_star); READ_BOOL_FIELD(agg_distinct); READ_BOOL_FIELD(func_variadic); - READ_NODE_FIELD(over); + READ_ENUM_FIELD(funcformat, CoercionForm); READ_LOCATION_FIELD(location); READ_DONE(); @@ -1271,6 +1380,11 @@ _readAExpr(void) local_node->kind = AEXPR_DISTINCT; READ_NODE_FIELD(name); } + else if (strncmp(token,"NOT_DISTINCT",length)==0) + { + local_node->kind = AEXPR_NOT_DISTINCT; + READ_NODE_FIELD(name); + } else if (strncmp(token,"NULLIF",length)==0) { local_node->kind = AEXPR_NULLIF; @@ -1321,11 +1435,6 @@ _readAExpr(void) local_node->kind = AEXPR_NOT_BETWEEN_SYM; READ_NODE_FIELD(name); } - else if (strncmp(token,"PAREN",length)==0) - { - local_node->kind = AEXPR_PAREN; - READ_NODE_FIELD(name); - } else { elog(ERROR,"Unable to understand A_Expr node %.30s",token); @@ -1381,7 +1490,8 @@ _readAggref(void) READ_CHAR_FIELD(aggkind); READ_UINT_FIELD(agglevelsup); READ_ENUM_FIELD(aggsplit, AggSplit); - + READ_INT_FIELD(aggno); + READ_INT_FIELD(aggtransno); READ_LOCATION_FIELD(location); READ_INT_FIELD(agg_expr_id); @@ -1465,6 +1575,7 @@ _readSubscriptingRef(void) READ_OID_FIELD(refcontainertype); READ_OID_FIELD(refelemtype); + READ_OID_FIELD(refrestype); READ_INT_FIELD(reftypmod); READ_OID_FIELD(refcollid); READ_NODE_FIELD(refupperindexpr); @@ -1585,6 +1696,7 @@ _readScalarArrayOpExpr(void) READ_OID_FIELD(opno); READ_OID_FIELD(opfuncid); + READ_OID_FIELD(hashfuncid); READ_BOOL_FIELD(useOr); READ_OID_FIELD(inputcollid); READ_NODE_FIELD(args); @@ -2114,6 +2226,7 @@ _readJoinExpr(void) READ_NODE_FIELD(larg); READ_NODE_FIELD(rarg); READ_NODE_FIELD(usingClause); + READ_NODE_FIELD(join_using_alias); READ_NODE_FIELD(quals); READ_NODE_FIELD(alias); READ_INT_FIELD(rtindex); @@ -2193,6 +2306,7 @@ _readColumnDef(void) READ_STRING_FIELD(colname); READ_NODE_FIELD(typeName); + READ_STRING_FIELD(compression); READ_INT_FIELD(inhcount); READ_BOOL_FIELD(is_local); READ_BOOL_FIELD(is_not_null); @@ -2317,6 +2431,7 @@ _readRangeTblEntry(void) READ_NODE_FIELD(joinaliasvars); READ_NODE_FIELD(joinleftcols); READ_NODE_FIELD(joinrightcols); + READ_NODE_FIELD(join_using_alias); break; case RTE_FUNCTION: READ_NODE_FIELD(functions); @@ -2476,7 +2591,6 @@ _readPlannedStmt(void) READ_NODE_FIELD(planTree); READ_NODE_FIELD(rtable); READ_NODE_FIELD(resultRelations); - READ_NODE_FIELD(rootResultRelations); READ_NODE_FIELD(appendRelations); READ_NODE_FIELD(subplans); READ_BITMAPSET_FIELD(rewindPlanIDs); @@ -2538,6 +2652,7 @@ ReadCommonPlan(Plan *local_node) READ_INT_FIELD(plan_width); READ_BOOL_FIELD(parallel_aware); READ_BOOL_FIELD(parallel_safe); + READ_BOOL_FIELD(async_capable); READ_INT_FIELD(plan_node_id); READ_NODE_FIELD(targetlist); READ_NODE_FIELD(qual); @@ -2616,9 +2731,7 @@ _readModifyTable(void) READ_UINT_FIELD(rootRelation); READ_BOOL_FIELD(partColsUpdated); READ_NODE_FIELD(resultRelations); - READ_INT_FIELD(resultRelIndex); - READ_INT_FIELD(rootResultRelIndex); - READ_NODE_FIELD(plans); + READ_NODE_FIELD(updateColnosLists); READ_NODE_FIELD(withCheckOptionLists); READ_NODE_FIELD(returningLists); READ_NODE_FIELD(fdwPrivLists); @@ -2628,6 +2741,7 @@ _readModifyTable(void) READ_ENUM_FIELD(onConflictAction, OnConflictAction); READ_NODE_FIELD(arbiterIndexes); READ_NODE_FIELD(onConflictSet); + READ_NODE_FIELD(onConflictCols); READ_NODE_FIELD(onConflictWhere); READ_UINT_FIELD(exclRelRTI); READ_NODE_FIELD(exclRelTlist); @@ -2649,6 +2763,7 @@ _readAppend(void) READ_BITMAPSET_FIELD(apprelids); READ_NODE_FIELD(appendplans); + READ_INT_FIELD(nasyncplans); READ_INT_FIELD(first_partial_plan); READ_NODE_FIELD(part_prune_info); READ_NODE_FIELD(join_prune_paramids); @@ -2938,6 +3053,21 @@ _readTidScan(void) READ_DONE(); } +/* + * _readTidRangeScan + */ +static TidRangeScan * +_readTidRangeScan(void) +{ + READ_LOCALS(TidRangeScan); + + ReadCommonScan(&local_node->scan); + + READ_NODE_FIELD(tidrangequals); + + READ_DONE(); +} + /* * _readSubqueryScan */ @@ -3074,6 +3204,7 @@ _readForeignScan(void) ReadCommonScan(&local_node->scan); READ_ENUM_FIELD(operation, CmdType); + READ_UINT_FIELD(resultRelation); READ_OID_FIELD(fs_server); READ_NODE_FIELD(fdw_exprs); READ_NODE_FIELD(fdw_private); @@ -3228,6 +3359,26 @@ _readMaterial(void) READ_DONE(); } +/* + * _readResultCache + */ +static ResultCache * +_readResultCache(void) +{ + READ_LOCALS(ResultCache); + + ReadCommonPlan(&local_node->plan); + + READ_INT_FIELD(numKeys); + READ_OID_ARRAY(hashOperators, local_node->numKeys); + READ_OID_ARRAY(collations, local_node->numKeys); + READ_NODE_FIELD(param_exprs); + READ_BOOL_FIELD(singlerow); + READ_UINT_FIELD(est_entries); + + READ_DONE(); +} + /* * ReadCommonSort * Assign the basic stuff of all nodes that inherit from Sort @@ -3660,6 +3811,9 @@ _readRestrictInfo(void) READ_BOOL_FIELD(outerjoin_delayed); READ_BOOL_FIELD(can_join); READ_BOOL_FIELD(pseudoconstant); + READ_BOOL_FIELD(leakproof); + READ_ENUM_FIELD(has_volatile, VolatileFunctionStatus); + READ_UINT_FIELD(security_level); READ_BOOL_FIELD(contain_outer_query_references); READ_BITMAPSET_FIELD(clause_relids); READ_BITMAPSET_FIELD(required_relids); @@ -3677,6 +3831,7 @@ _readRestrictInfo(void) READ_NODE_FIELD(right_em); READ_BOOL_FIELD(outer_is_left); READ_OID_FIELD(hashjoinoperator); + READ_OID_FIELD(hasheqoperator); READ_DONE(); } @@ -3875,6 +4030,28 @@ _readAlterDomainStmt(void) } #endif /* COMPILING_BINARY_FUNCS */ +static ReturnStmt * +_readReturnStmt(void) +{ + READ_LOCALS(ReturnStmt); + + READ_NODE_FIELD(returnval); + + READ_DONE(); +} + +static RawStmt * +_readRawStmt(void) +{ + READ_LOCALS(RawStmt); + + READ_NODE_FIELD(stmt); + READ_LOCATION_FIELD(stmt_location); + READ_INT_FIELD(stmt_len); + + READ_DONE(); +} + static CreateFunctionStmt * _readCreateFunctionStmt(void) { @@ -3886,6 +4063,7 @@ _readCreateFunctionStmt(void) READ_NODE_FIELD(parameters); READ_NODE_FIELD(returnType); READ_NODE_FIELD(options); + READ_NODE_FIELD(sql_body); READ_DONE(); } @@ -4337,6 +4515,17 @@ _readAlterTypeStmtSetDefaultEnc(void) READ_DONE(); } +static AlterTypeStmt * +_readAlterTypeStmt(void) +{ + READ_LOCALS(AlterTypeStmt); + + READ_NODE_FIELD(typeName); + READ_NODE_FIELD(options); + + READ_DONE(); +} + static PartitionElem * _readPartitionElem(void) { @@ -4527,6 +4716,10 @@ parseNodeString(void) return_value = _readWindowClause(); else if (MATCH("ROWMARKCLAUSE", 13)) return_value = _readRowMarkClause(); + else if (MATCH("CTESEARCHCLAUSE", 15)) + return_value = _readCTESearchClause(); + else if (MATCH("CTECYCLECLAUSE", 14)) + return_value = _readCTECycleClause(); else if (MATCH("COMMONTABLEEXPR", 15)) return_value = _readCommonTableExpr(); else if (MATCH("SETOPERATIONSTMT", 16)) @@ -4693,6 +4886,8 @@ parseNodeString(void) return_value = _readDynamicBitmapHeapScan(); else if (MATCH("TIDSCAN", 7)) return_value = _readTidScan(); + else if (MATCH("TIDRANGESCAN", 12)) + return_value = _readTidRangeScan(); else if (MATCH("SUBQUERYSCAN", 12)) return_value = _readSubqueryScan(); else if (MATCH("TABLEFUNCTIONSCAN", 17)) @@ -4723,6 +4918,8 @@ parseNodeString(void) return_value = _readHashJoin(); else if (MATCH("MATERIAL", 8)) return_value = _readMaterial(); + else if (MATCH("RESULTCACHE", 11)) + return_value = _readResultCache(); else if (MATCH("SORT", 4)) return_value = _readSort(); else if (MATCH("INCREMENTALSORT", 15)) @@ -4827,6 +5024,8 @@ parseNodeString(void) return_value = _readAlterTableStmt(); else if (MATCHX("ALTERTYPESTMTSETDEFAULTENC")) return_value = _readAlterTypeStmtSetDefaultEnc(); + else if (MATCHX("ALTERTYPESTMT")) + return_value = _readAlterTypeStmt(); else if (MATCHX("CDBPROCESS")) return_value = _readCdbProcess(); else if (MATCHX("CLUSTERSTMT")) @@ -4919,6 +5118,16 @@ parseNodeString(void) return_value = _readIndexElem(); else if (MATCHX("INDEXSTMT")) return_value = _readIndexStmt(); + else if (MATCHX("STATSELEM")) + return_value = _readStatsElem(); + else if (MATCHX("CREATESTATSSTMT")) + return_value = _readCreateStatsStmt(); + else if (MATCHX("RANGESUBSELECT")) + return_value = _readRangeSubselect(); + else if (MATCHX("INFERCLAUSE")) + return_value = _readInferClause(); + else if (MATCHX("ONCONFLICTCLAUSE")) + return_value = _readOnConflictClause(); else if (MATCHX("LOCKSTMT")) return_value = _readLockStmt(); else if (MATCHX("REINDEXSTMT")) diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c index 96ddeb4eb292..60ace9ec2b8e 100644 --- a/src/backend/nodes/tidbitmap.c +++ b/src/backend/nodes/tidbitmap.c @@ -20,7 +20,7 @@ * point, but for now that seems useless complexity. * * - * Copyright (c) 2003-2020, PostgreSQL Global Development Group + * Copyright (c) 2003-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/nodes/tidbitmap.c diff --git a/src/backend/nodes/value.c b/src/backend/nodes/value.c index 45b9b8473e01..15e6d2675218 100644 --- a/src/backend/nodes/value.c +++ b/src/backend/nodes/value.c @@ -4,7 +4,7 @@ * implementation of Value nodes * * - * Copyright (c) 2003-2020, PostgreSQL Global Development Group + * Copyright (c) 2003-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/optimizer/README b/src/backend/optimizer/README index d174b8cb73a8..4aefde8bb18d 100644 --- a/src/backend/optimizer/README +++ b/src/backend/optimizer/README @@ -374,6 +374,7 @@ RelOptInfo - a relation or joined relations IndexPath - index scan BitmapHeapPath - top of a bitmapped index scan TidPath - scan by CTID + TidRangePath - scan a contiguous range of CTIDs SubqueryScanPath - scan a subquery-in-FROM ForeignPath - scan a foreign table, foreign join or foreign upper-relation CustomPath - for custom scan providers @@ -381,12 +382,14 @@ RelOptInfo - a relation or joined relations MergeAppendPath - merge multiple subpaths, preserving their common sort order GroupResultPath - childless Result plan node (used for degenerate grouping) MaterialPath - a Material plan node + ResultCachePath - a result cache plan node for caching tuples from sub-paths UniquePath - remove duplicate rows (either by hashing or sorting) GatherPath - collect the results of parallel workers GatherMergePath - collect parallel results, preserving their common sort order ProjectionPath - a Result plan node with child (used for projection) ProjectSetPath - a ProjectSet plan node applied to some sub-path SortPath - a Sort plan node applied to some sub-path + IncrementalSortPath - an IncrementalSort plan node applied to some sub-path GroupPath - a Group plan node applied to some sub-path UpperUniquePath - a Unique plan node applied to some sub-path AggPath - an Agg plan node applied to some sub-path diff --git a/src/backend/optimizer/geqo/geqo_copy.c b/src/backend/optimizer/geqo/geqo_copy.c new file mode 100644 index 000000000000..4f6226b0287a --- /dev/null +++ b/src/backend/optimizer/geqo/geqo_copy.c @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------ + * + * geqo_copy.c + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/optimizer/geqo/geqo_copy.c + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +/* this is adopted from D. Whitley's Genitor algorithm */ + +/*************************************************************/ +/* */ +/* Copyright (c) 1990 */ +/* Darrell L. Whitley */ +/* Computer Science Department */ +/* Colorado State University */ +/* */ +/* Permission is hereby granted to copy all or any part of */ +/* this program for free distribution. The author's name */ +/* and this copyright notice must be included in any copy. */ +/* */ +/*************************************************************/ + +#include "postgres.h" +#include "optimizer/geqo_copy.h" + +/* geqo_copy + * + * copies one gene to another + * + */ +void +geqo_copy(PlannerInfo *root, Chromosome *chromo1, Chromosome *chromo2, + int string_length) +{ + int i; + + for (i = 0; i < string_length; i++) + chromo1->string[i] = chromo2->string[i]; + + chromo1->worth = chromo2->worth; +} diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c new file mode 100644 index 000000000000..2ecba83490f8 --- /dev/null +++ b/src/backend/optimizer/geqo/geqo_eval.c @@ -0,0 +1,338 @@ +/*------------------------------------------------------------------------ + * + * geqo_eval.c + * Routines to evaluate query trees + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/optimizer/geqo/geqo_eval.c + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +#include "postgres.h" + +#include +#include +#include + +#include "optimizer/geqo.h" +#include "optimizer/joininfo.h" +#include "optimizer/pathnode.h" +#include "optimizer/paths.h" +#include "utils/memutils.h" + + +/* A "clump" of already-joined relations within gimme_tree */ +typedef struct +{ + RelOptInfo *joinrel; /* joinrel for the set of relations */ + int size; /* number of input relations in clump */ +} Clump; + +static List *merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, + int num_gene, bool force); +static bool desirable_join(PlannerInfo *root, + RelOptInfo *outer_rel, RelOptInfo *inner_rel); + + +/* + * geqo_eval + * + * Returns cost of a query tree as an individual of the population. + * + * If no legal join order can be extracted from the proposed tour, + * returns DBL_MAX. + */ +Cost +geqo_eval(PlannerInfo *root, Gene *tour, int num_gene) +{ + MemoryContext mycontext; + MemoryContext oldcxt; + RelOptInfo *joinrel; + Cost fitness; + int savelength; + struct HTAB *savehash; + + /* + * Create a private memory context that will hold all temp storage + * allocated inside gimme_tree(). + * + * Since geqo_eval() will be called many times, we can't afford to let all + * that memory go unreclaimed until end of statement. Note we make the + * temp context a child of the planner's normal context, so that it will + * be freed even if we abort via ereport(ERROR). + */ + mycontext = AllocSetContextCreate(CurrentMemoryContext, + "GEQO", + ALLOCSET_DEFAULT_SIZES); + oldcxt = MemoryContextSwitchTo(mycontext); + + /* + * gimme_tree will add entries to root->join_rel_list, which may or may + * not already contain some entries. The newly added entries will be + * recycled by the MemoryContextDelete below, so we must ensure that the + * list is restored to its former state before exiting. We can do this by + * truncating the list to its original length. NOTE this assumes that any + * added entries are appended at the end! + * + * We also must take care not to mess up the outer join_rel_hash, if there + * is one. We can do this by just temporarily setting the link to NULL. + * (If we are dealing with enough join rels, which we very likely are, a + * new hash table will get built and used locally.) + * + * join_rel_level[] shouldn't be in use, so just Assert it isn't. + */ + savelength = list_length(root->join_rel_list); + savehash = root->join_rel_hash; + Assert(root->join_rel_level == NULL); + + root->join_rel_hash = NULL; + + /* construct the best path for the given combination of relations */ + joinrel = gimme_tree(root, tour, num_gene); + + /* + * compute fitness, if we found a valid join + * + * XXX geqo does not currently support optimization for partial result + * retrieval, nor do we take any cognizance of possible use of + * parameterized paths --- how to fix? + */ + if (joinrel) + { + Path *best_path = joinrel->cheapest_total_path; + + fitness = best_path->total_cost; + } + else + fitness = DBL_MAX; + + /* + * Restore join_rel_list to its former state, and put back original + * hashtable if any. + */ + root->join_rel_list = list_truncate(root->join_rel_list, + savelength); + root->join_rel_hash = savehash; + + /* release all the memory acquired within gimme_tree */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(mycontext); + + return fitness; +} + +/* + * gimme_tree + * Form planner estimates for a join tree constructed in the specified + * order. + * + * 'tour' is the proposed join order, of length 'num_gene' + * + * Returns a new join relation whose cheapest path is the best plan for + * this join order. NB: will return NULL if join order is invalid and + * we can't modify it into a valid order. + * + * The original implementation of this routine always joined in the specified + * order, and so could only build left-sided plans (and right-sided and + * mixtures, as a byproduct of the fact that make_join_rel() is symmetric). + * It could never produce a "bushy" plan. This had a couple of big problems, + * of which the worst was that there are situations involving join order + * restrictions where the only valid plans are bushy. + * + * The present implementation takes the given tour as a guideline, but + * postpones joins that are illegal or seem unsuitable according to some + * heuristic rules. This allows correct bushy plans to be generated at need, + * and as a nice side-effect it seems to materially improve the quality of the + * generated plans. Note however that since it's just a heuristic, it can + * still fail in some cases. (In particular, we might clump together + * relations that actually mustn't be joined yet due to LATERAL restrictions; + * since there's no provision for un-clumping, this must lead to failure.) + */ +RelOptInfo * +gimme_tree(PlannerInfo *root, Gene *tour, int num_gene) +{ + GeqoPrivateData *private = (GeqoPrivateData *) root->join_search_private; + List *clumps; + int rel_count; + + /* + * Sometimes, a relation can't yet be joined to others due to heuristics + * or actual semantic restrictions. We maintain a list of "clumps" of + * successfully joined relations, with larger clumps at the front. Each + * new relation from the tour is added to the first clump it can be joined + * to; if there is none then it becomes a new clump of its own. When we + * enlarge an existing clump we check to see if it can now be merged with + * any other clumps. After the tour is all scanned, we forget about the + * heuristics and try to forcibly join any remaining clumps. If we are + * unable to merge all the clumps into one, fail. + */ + clumps = NIL; + + for (rel_count = 0; rel_count < num_gene; rel_count++) + { + int cur_rel_index; + RelOptInfo *cur_rel; + Clump *cur_clump; + + /* Get the next input relation */ + cur_rel_index = (int) tour[rel_count]; + cur_rel = (RelOptInfo *) list_nth(private->initial_rels, + cur_rel_index - 1); + + /* Make it into a single-rel clump */ + cur_clump = (Clump *) palloc(sizeof(Clump)); + cur_clump->joinrel = cur_rel; + cur_clump->size = 1; + + /* Merge it into the clumps list, using only desirable joins */ + clumps = merge_clump(root, clumps, cur_clump, num_gene, false); + } + + if (list_length(clumps) > 1) + { + /* Force-join the remaining clumps in some legal order */ + List *fclumps; + ListCell *lc; + + fclumps = NIL; + foreach(lc, clumps) + { + Clump *clump = (Clump *) lfirst(lc); + + fclumps = merge_clump(root, fclumps, clump, num_gene, true); + } + clumps = fclumps; + } + + /* Did we succeed in forming a single join relation? */ + if (list_length(clumps) != 1) + return NULL; + + return ((Clump *) linitial(clumps))->joinrel; +} + +/* + * Merge a "clump" into the list of existing clumps for gimme_tree. + * + * We try to merge the clump into some existing clump, and repeat if + * successful. When no more merging is possible, insert the clump + * into the list, preserving the list ordering rule (namely, that + * clumps of larger size appear earlier). + * + * If force is true, merge anywhere a join is legal, even if it causes + * a cartesian join to be performed. When force is false, do only + * "desirable" joins. + */ +static List * +merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, int num_gene, + bool force) +{ + ListCell *lc; + int pos; + + /* Look for a clump that new_clump can join to */ + foreach(lc, clumps) + { + Clump *old_clump = (Clump *) lfirst(lc); + + if (force || + desirable_join(root, old_clump->joinrel, new_clump->joinrel)) + { + RelOptInfo *joinrel; + + /* + * Construct a RelOptInfo representing the join of these two input + * relations. Note that we expect the joinrel not to exist in + * root->join_rel_list yet, and so the paths constructed for it + * will only include the ones we want. + */ + joinrel = make_join_rel(root, + old_clump->joinrel, + new_clump->joinrel); + + /* Keep searching if join order is not valid */ + if (joinrel) + { + /* Create paths for partitionwise joins. */ + generate_partitionwise_join_paths(root, joinrel); + + /* + * Except for the topmost scan/join rel, consider gathering + * partial paths. We'll do the same for the topmost scan/join + * rel once we know the final targetlist (see + * grouping_planner). + */ + if (old_clump->size + new_clump->size < num_gene) + generate_useful_gather_paths(root, joinrel, false); + + /* Find and save the cheapest paths for this joinrel */ + set_cheapest(joinrel); + + /* Absorb new clump into old */ + old_clump->joinrel = joinrel; + old_clump->size += new_clump->size; + pfree(new_clump); + + /* Remove old_clump from list */ + clumps = foreach_delete_current(clumps, lc); + + /* + * Recursively try to merge the enlarged old_clump with + * others. When no further merge is possible, we'll reinsert + * it into the list. + */ + return merge_clump(root, clumps, old_clump, num_gene, force); + } + } + } + + /* + * No merging is possible, so add new_clump as an independent clump, in + * proper order according to size. We can be fast for the common case + * where it has size 1 --- it should always go at the end. + */ + if (clumps == NIL || new_clump->size == 1) + return lappend(clumps, new_clump); + + /* Else search for the place to insert it */ + for (pos = 0; pos < list_length(clumps); pos++) + { + Clump *old_clump = (Clump *) list_nth(clumps, pos); + + if (new_clump->size > old_clump->size) + break; /* new_clump belongs before old_clump */ + } + clumps = list_insert_nth(clumps, pos, new_clump); + + return clumps; +} + +/* + * Heuristics for gimme_tree: do we want to join these two relations? + */ +static bool +desirable_join(PlannerInfo *root, + RelOptInfo *outer_rel, RelOptInfo *inner_rel) +{ + /* + * Join if there is an applicable join clause, or if there is a join order + * restriction forcing these rels to be joined. + */ + if (have_relevant_joinclause(root, outer_rel, inner_rel) || + have_join_order_restriction(root, outer_rel, inner_rel)) + return true; + + /* Otherwise postpone the join till later. */ + return false; +} diff --git a/src/backend/optimizer/geqo/geqo_main.c b/src/backend/optimizer/geqo/geqo_main.c new file mode 100644 index 000000000000..09d9e7d4dd61 --- /dev/null +++ b/src/backend/optimizer/geqo/geqo_main.c @@ -0,0 +1,348 @@ +/*------------------------------------------------------------------------ + * + * geqo_main.c + * solution to the query optimization problem + * by means of a Genetic Algorithm (GA) + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/optimizer/geqo/geqo_main.c + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +/* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */ + +#include "postgres.h" + +#include + +#include "optimizer/geqo_misc.h" +#include "optimizer/geqo_mutation.h" +#include "optimizer/geqo_pool.h" +#include "optimizer/geqo_random.h" +#include "optimizer/geqo_selection.h" + + +/* + * Configuration options + */ +int Geqo_effort; +int Geqo_pool_size; +int Geqo_generations; +double Geqo_selection_bias; +double Geqo_seed; + + +static int gimme_pool_size(int nr_rel); +static int gimme_number_generations(int pool_size); + +/* complain if no recombination mechanism is #define'd */ +#if !defined(ERX) && \ + !defined(PMX) && \ + !defined(CX) && \ + !defined(PX) && \ + !defined(OX1) && \ + !defined(OX2) +#error "must choose one GEQO recombination mechanism in geqo.h" +#endif + + +/* + * geqo + * solution of the query optimization problem + * similar to a constrained Traveling Salesman Problem (TSP) + */ + +RelOptInfo * +geqo(PlannerInfo *root, int number_of_rels, List *initial_rels) +{ + GeqoPrivateData private; + int generation; + Chromosome *momma; + Chromosome *daddy; + Chromosome *kid; + Pool *pool; + int pool_size, + number_generations; + +#ifdef GEQO_DEBUG + int status_interval; +#endif + Gene *best_tour; + RelOptInfo *best_rel; + +#if defined(ERX) + Edge *edge_table; /* list of edges */ + int edge_failures = 0; +#endif +#if defined(CX) || defined(PX) || defined(OX1) || defined(OX2) + City *city_table; /* list of cities */ +#endif +#if defined(CX) + int cycle_diffs = 0; + int mutations = 0; +#endif + +/* set up private information */ + root->join_search_private = (void *) &private; + private.initial_rels = initial_rels; + +/* initialize private number generator */ + geqo_set_seed(root, Geqo_seed); + +/* set GA parameters */ + pool_size = gimme_pool_size(number_of_rels); + number_generations = gimme_number_generations(pool_size); +#ifdef GEQO_DEBUG + status_interval = 10; +#endif + +/* allocate genetic pool memory */ + pool = alloc_pool(root, pool_size, number_of_rels); + +/* random initialization of the pool */ + random_init_pool(root, pool); + +/* sort the pool according to cheapest path as fitness */ + sort_pool(root, pool); /* we have to do it only one time, since all + * kids replace the worst individuals in + * future (-> geqo_pool.c:spread_chromo ) */ + +#ifdef GEQO_DEBUG + elog(DEBUG1, "GEQO selected %d pool entries, best %.2f, worst %.2f", + pool_size, + pool->data[0].worth, + pool->data[pool_size - 1].worth); +#endif + +/* allocate chromosome momma and daddy memory */ + momma = alloc_chromo(root, pool->string_length); + daddy = alloc_chromo(root, pool->string_length); + +#if defined (ERX) +#ifdef GEQO_DEBUG + elog(DEBUG2, "using edge recombination crossover [ERX]"); +#endif +/* allocate edge table memory */ + edge_table = alloc_edge_table(root, pool->string_length); +#elif defined(PMX) +#ifdef GEQO_DEBUG + elog(DEBUG2, "using partially matched crossover [PMX]"); +#endif +/* allocate chromosome kid memory */ + kid = alloc_chromo(root, pool->string_length); +#elif defined(CX) +#ifdef GEQO_DEBUG + elog(DEBUG2, "using cycle crossover [CX]"); +#endif +/* allocate city table memory */ + kid = alloc_chromo(root, pool->string_length); + city_table = alloc_city_table(root, pool->string_length); +#elif defined(PX) +#ifdef GEQO_DEBUG + elog(DEBUG2, "using position crossover [PX]"); +#endif +/* allocate city table memory */ + kid = alloc_chromo(root, pool->string_length); + city_table = alloc_city_table(root, pool->string_length); +#elif defined(OX1) +#ifdef GEQO_DEBUG + elog(DEBUG2, "using order crossover [OX1]"); +#endif +/* allocate city table memory */ + kid = alloc_chromo(root, pool->string_length); + city_table = alloc_city_table(root, pool->string_length); +#elif defined(OX2) +#ifdef GEQO_DEBUG + elog(DEBUG2, "using order crossover [OX2]"); +#endif +/* allocate city table memory */ + kid = alloc_chromo(root, pool->string_length); + city_table = alloc_city_table(root, pool->string_length); +#endif + + +/* my pain main part: */ +/* iterative optimization */ + + for (generation = 0; generation < number_generations; generation++) + { + /* SELECTION: using linear bias function */ + geqo_selection(root, momma, daddy, pool, Geqo_selection_bias); + +#if defined (ERX) + /* EDGE RECOMBINATION CROSSOVER */ + gimme_edge_table(root, momma->string, daddy->string, pool->string_length, edge_table); + + kid = momma; + + /* are there any edge failures ? */ + edge_failures += gimme_tour(root, edge_table, kid->string, pool->string_length); +#elif defined(PMX) + /* PARTIALLY MATCHED CROSSOVER */ + pmx(root, momma->string, daddy->string, kid->string, pool->string_length); +#elif defined(CX) + /* CYCLE CROSSOVER */ + cycle_diffs = cx(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); + /* mutate the child */ + if (cycle_diffs == 0) + { + mutations++; + geqo_mutation(root, kid->string, pool->string_length); + } +#elif defined(PX) + /* POSITION CROSSOVER */ + px(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); +#elif defined(OX1) + /* ORDER CROSSOVER */ + ox1(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); +#elif defined(OX2) + /* ORDER CROSSOVER */ + ox2(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); +#endif + + + /* EVALUATE FITNESS */ + kid->worth = geqo_eval(root, kid->string, pool->string_length); + + /* push the kid into the wilderness of life according to its worth */ + spread_chromo(root, kid, pool); + + +#ifdef GEQO_DEBUG + if (status_interval && !(generation % status_interval)) + print_gen(stdout, pool, generation); +#endif + + } + + +#if defined(ERX) && defined(GEQO_DEBUG) + if (edge_failures != 0) + elog(LOG, "[GEQO] failures: %d, average: %d", + edge_failures, (int) number_generations / edge_failures); + else + elog(LOG, "[GEQO] no edge failures detected"); +#endif + +#if defined(CX) && defined(GEQO_DEBUG) + if (mutations != 0) + elog(LOG, "[GEQO] mutations: %d, generations: %d", + mutations, number_generations); + else + elog(LOG, "[GEQO] no mutations processed"); +#endif + +#ifdef GEQO_DEBUG + print_pool(stdout, pool, 0, pool_size - 1); +#endif + +#ifdef GEQO_DEBUG + elog(DEBUG1, "GEQO best is %.2f after %d generations", + pool->data[0].worth, number_generations); +#endif + + + /* + * got the cheapest query tree processed by geqo; first element of the + * population indicates the best query tree + */ + best_tour = (Gene *) pool->data[0].string; + + best_rel = gimme_tree(root, best_tour, pool->string_length); + + if (best_rel == NULL) + elog(ERROR, "geqo failed to make a valid plan"); + + /* DBG: show the query plan */ +#ifdef NOT_USED + print_plan(best_plan, root); +#endif + + /* ... free memory stuff */ + free_chromo(root, momma); + free_chromo(root, daddy); + +#if defined (ERX) + free_edge_table(root, edge_table); +#elif defined(PMX) + free_chromo(root, kid); +#elif defined(CX) + free_chromo(root, kid); + free_city_table(root, city_table); +#elif defined(PX) + free_chromo(root, kid); + free_city_table(root, city_table); +#elif defined(OX1) + free_chromo(root, kid); + free_city_table(root, city_table); +#elif defined(OX2) + free_chromo(root, kid); + free_city_table(root, city_table); +#endif + + free_pool(root, pool); + + /* ... clear root pointer to our private storage */ + root->join_search_private = NULL; + + return best_rel; +} + + +/* + * Return either configured pool size or a good default + * + * The default is based on query size (no. of relations) = 2^(QS+1), + * but constrained to a range based on the effort value. + */ +static int +gimme_pool_size(int nr_rel) +{ + double size; + int minsize; + int maxsize; + + /* Legal pool size *must* be at least 2, so ignore attempt to select 1 */ + if (Geqo_pool_size >= 2) + return Geqo_pool_size; + + size = pow(2.0, nr_rel + 1.0); + + maxsize = 50 * Geqo_effort; /* 50 to 500 individuals */ + if (size > maxsize) + return maxsize; + + minsize = 10 * Geqo_effort; /* 10 to 100 individuals */ + if (size < minsize) + return minsize; + + return (int) ceil(size); +} + + +/* + * Return either configured number of generations or a good default + * + * The default is the same as the pool size, which allows us to be + * sure that less-fit individuals get pushed out of the breeding + * population before the run finishes. + */ +static int +gimme_number_generations(int pool_size) +{ + if (Geqo_generations > 0) + return Geqo_generations; + + return pool_size; +} diff --git a/src/backend/optimizer/geqo/geqo_misc.c b/src/backend/optimizer/geqo/geqo_misc.c new file mode 100644 index 000000000000..02b5a7015b7f --- /dev/null +++ b/src/backend/optimizer/geqo/geqo_misc.c @@ -0,0 +1,132 @@ +/*------------------------------------------------------------------------ + * + * geqo_misc.c + * misc. printout and debug stuff + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/optimizer/geqo/geqo_misc.c + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +#include "postgres.h" + +#include "optimizer/geqo_misc.h" + + +#ifdef GEQO_DEBUG + + +/* + * avg_pool + */ +static double +avg_pool(Pool *pool) +{ + int i; + double cumulative = 0.0; + + if (pool->size <= 0) + elog(ERROR, "pool_size is zero"); + + /* + * Since the pool may contain multiple occurrences of DBL_MAX, divide by + * pool->size before summing, not after, to avoid overflow. This loses a + * little in speed and accuracy, but this routine is only used for debug + * printouts, so we don't care that much. + */ + for (i = 0; i < pool->size; i++) + cumulative += pool->data[i].worth / pool->size; + + return cumulative; +} + +/* print_pool + */ +void +print_pool(FILE *fp, Pool *pool, int start, int stop) +{ + int i, + j; + + /* be extra careful that start and stop are valid inputs */ + + if (start < 0) + start = 0; + if (stop > pool->size) + stop = pool->size; + + if (start + stop > pool->size) + { + start = 0; + stop = pool->size; + } + + for (i = start; i < stop; i++) + { + fprintf(fp, "%d)\t", i); + for (j = 0; j < pool->string_length; j++) + fprintf(fp, "%d ", pool->data[i].string[j]); + fprintf(fp, "%g\n", pool->data[i].worth); + } + + fflush(fp); +} + +/* print_gen + * + * printout for chromosome: best, worst, mean, average + */ +void +print_gen(FILE *fp, Pool *pool, int generation) +{ + int lowest; + + /* Get index to lowest ranking gene in population. */ + /* Use 2nd to last since last is buffer. */ + lowest = pool->size > 1 ? pool->size - 2 : 0; + + fprintf(fp, + "%5d | Best: %g Worst: %g Mean: %g Avg: %g\n", + generation, + pool->data[0].worth, + pool->data[lowest].worth, + pool->data[pool->size / 2].worth, + avg_pool(pool)); + + fflush(fp); +} + + +void +print_edge_table(FILE *fp, Edge *edge_table, int num_gene) +{ + int i, + j; + + fprintf(fp, "\nEDGE TABLE\n"); + + for (i = 1; i <= num_gene; i++) + { + fprintf(fp, "%d :", i); + for (j = 0; j < edge_table[i].unused_edges; j++) + fprintf(fp, " %d", edge_table[i].edge_list[j]); + fprintf(fp, "\n"); + } + + fprintf(fp, "\n"); + + fflush(fp); +} + +#endif /* GEQO_DEBUG */ diff --git a/src/backend/optimizer/geqo/geqo_pool.c b/src/backend/optimizer/geqo/geqo_pool.c new file mode 100644 index 000000000000..1fc103ba1132 --- /dev/null +++ b/src/backend/optimizer/geqo/geqo_pool.c @@ -0,0 +1,265 @@ +/*------------------------------------------------------------------------ + * + * geqo_pool.c + * Genetic Algorithm (GA) pool stuff + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/optimizer/geqo/geqo_pool.c + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +/* -- parts of this are adapted from D. Whitley's Genitor algorithm -- */ + +#include "postgres.h" + +#include +#include +#include + +#include "optimizer/geqo_copy.h" +#include "optimizer/geqo_pool.h" +#include "optimizer/geqo_recombination.h" + + +static int compare(const void *arg1, const void *arg2); + +/* + * alloc_pool + * allocates memory for GA pool + */ +Pool * +alloc_pool(PlannerInfo *root, int pool_size, int string_length) +{ + Pool *new_pool; + Chromosome *chromo; + int i; + + /* pool */ + new_pool = (Pool *) palloc(sizeof(Pool)); + new_pool->size = (int) pool_size; + new_pool->string_length = (int) string_length; + + /* all chromosome */ + new_pool->data = (Chromosome *) palloc(pool_size * sizeof(Chromosome)); + + /* all gene */ + chromo = (Chromosome *) new_pool->data; /* vector of all chromos */ + for (i = 0; i < pool_size; i++) + chromo[i].string = palloc((string_length + 1) * sizeof(Gene)); + + return new_pool; +} + +/* + * free_pool + * deallocates memory for GA pool + */ +void +free_pool(PlannerInfo *root, Pool *pool) +{ + Chromosome *chromo; + int i; + + /* all gene */ + chromo = (Chromosome *) pool->data; /* vector of all chromos */ + for (i = 0; i < pool->size; i++) + pfree(chromo[i].string); + + /* all chromosome */ + pfree(pool->data); + + /* pool */ + pfree(pool); +} + +/* + * random_init_pool + * initialize genetic pool + */ +void +random_init_pool(PlannerInfo *root, Pool *pool) +{ + Chromosome *chromo = (Chromosome *) pool->data; + int i; + int bad = 0; + + /* + * We immediately discard any invalid individuals (those that geqo_eval + * returns DBL_MAX for), thereby not wasting pool space on them. + * + * If we fail to make any valid individuals after 10000 tries, give up; + * this probably means something is broken, and we shouldn't just let + * ourselves get stuck in an infinite loop. + */ + i = 0; + while (i < pool->size) + { + init_tour(root, chromo[i].string, pool->string_length); + pool->data[i].worth = geqo_eval(root, chromo[i].string, + pool->string_length); + if (pool->data[i].worth < DBL_MAX) + i++; + else + { + bad++; + if (i == 0 && bad >= 10000) + elog(ERROR, "geqo failed to make a valid plan"); + } + } + +#ifdef GEQO_DEBUG + if (bad > 0) + elog(DEBUG1, "%d invalid tours found while selecting %d pool entries", + bad, pool->size); +#endif +} + +/* + * sort_pool + * sorts input pool according to worth, from smallest to largest + * + * maybe you have to change compare() for different ordering ... + */ +void +sort_pool(PlannerInfo *root, Pool *pool) +{ + qsort(pool->data, pool->size, sizeof(Chromosome), compare); +} + +/* + * compare + * qsort comparison function for sort_pool + */ +static int +compare(const void *arg1, const void *arg2) +{ + const Chromosome *chromo1 = (const Chromosome *) arg1; + const Chromosome *chromo2 = (const Chromosome *) arg2; + + if (chromo1->worth == chromo2->worth) + return 0; + else if (chromo1->worth > chromo2->worth) + return 1; + else + return -1; +} + +/* alloc_chromo + * allocates a chromosome and string space + */ +Chromosome * +alloc_chromo(PlannerInfo *root, int string_length) +{ + Chromosome *chromo; + + chromo = (Chromosome *) palloc(sizeof(Chromosome)); + chromo->string = (Gene *) palloc((string_length + 1) * sizeof(Gene)); + + return chromo; +} + +/* free_chromo + * deallocates a chromosome and string space + */ +void +free_chromo(PlannerInfo *root, Chromosome *chromo) +{ + pfree(chromo->string); + pfree(chromo); +} + +/* spread_chromo + * inserts a new chromosome into the pool, displacing worst gene in pool + * assumes best->worst = smallest->largest + */ +void +spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool) +{ + int top, + mid, + bot; + int i, + index; + Chromosome swap_chromo, + tmp_chromo; + + /* new chromo is so bad we can't use it */ + if (chromo->worth > pool->data[pool->size - 1].worth) + return; + + /* do a binary search to find the index of the new chromo */ + + top = 0; + mid = pool->size / 2; + bot = pool->size - 1; + index = -1; + + while (index == -1) + { + /* these 4 cases find a new location */ + + if (chromo->worth <= pool->data[top].worth) + index = top; + else if (chromo->worth == pool->data[mid].worth) + index = mid; + else if (chromo->worth == pool->data[bot].worth) + index = bot; + else if (bot - top <= 1) + index = bot; + + + /* + * these 2 cases move the search indices since a new location has not + * yet been found. + */ + + else if (chromo->worth < pool->data[mid].worth) + { + bot = mid; + mid = top + ((bot - top) / 2); + } + else + { /* (chromo->worth > pool->data[mid].worth) */ + top = mid; + mid = top + ((bot - top) / 2); + } + } /* ... while */ + + /* now we have index for chromo */ + + /* + * move every gene from index on down one position to make room for chromo + */ + + /* + * copy new gene into pool storage; always replace worst gene in pool + */ + + geqo_copy(root, &pool->data[pool->size - 1], chromo, pool->string_length); + + swap_chromo.string = pool->data[pool->size - 1].string; + swap_chromo.worth = pool->data[pool->size - 1].worth; + + for (i = index; i < pool->size; i++) + { + tmp_chromo.string = pool->data[i].string; + tmp_chromo.worth = pool->data[i].worth; + + pool->data[i].string = swap_chromo.string; + pool->data[i].worth = swap_chromo.worth; + + swap_chromo.string = tmp_chromo.string; + swap_chromo.worth = tmp_chromo.worth; + } +} diff --git a/src/backend/optimizer/geqo/geqo_random.c b/src/backend/optimizer/geqo/geqo_random.c new file mode 100644 index 000000000000..f21bc047e68b --- /dev/null +++ b/src/backend/optimizer/geqo/geqo_random.c @@ -0,0 +1,40 @@ +/*------------------------------------------------------------------------ + * + * geqo_random.c + * random number generator + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/optimizer/geqo/geqo_random.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "optimizer/geqo_random.h" + + +void +geqo_set_seed(PlannerInfo *root, double seed) +{ + GeqoPrivateData *private = (GeqoPrivateData *) root->join_search_private; + + /* + * XXX. This seeding algorithm could certainly be improved - but it is not + * critical to do so. + */ + memset(private->random_state, 0, sizeof(private->random_state)); + memcpy(private->random_state, + &seed, + Min(sizeof(private->random_state), sizeof(seed))); +} + +double +geqo_rand(PlannerInfo *root) +{ + GeqoPrivateData *private = (GeqoPrivateData *) root->join_search_private; + + return pg_erand48(private->random_state); +} diff --git a/src/backend/optimizer/geqo/geqo_selection.c b/src/backend/optimizer/geqo/geqo_selection.c new file mode 100644 index 000000000000..66b6c8ae38e4 --- /dev/null +++ b/src/backend/optimizer/geqo/geqo_selection.c @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------------- + * + * geqo_selection.c + * linear selection scheme for the genetic query optimizer + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/optimizer/geqo/geqo_selection.c + * + *------------------------------------------------------------------------- + */ + +/* contributed by: + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + * Martin Utesch * Institute of Automatic Control * + = = University of Mining and Technology = + * utesch@aut.tu-freiberg.de * Freiberg, Germany * + =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*= + */ + +/* this is adopted from D. Whitley's Genitor algorithm */ + +/*************************************************************/ +/* */ +/* Copyright (c) 1990 */ +/* Darrell L. Whitley */ +/* Computer Science Department */ +/* Colorado State University */ +/* */ +/* Permission is hereby granted to copy all or any part of */ +/* this program for free distribution. The author's name */ +/* and this copyright notice must be included in any copy. */ +/* */ +/*************************************************************/ + +#include "postgres.h" + +#include + +#include "optimizer/geqo_copy.h" +#include "optimizer/geqo_random.h" +#include "optimizer/geqo_selection.h" + +static int linear_rand(PlannerInfo *root, int max, double bias); + + +/* + * geqo_selection + * according to bias described by input parameters, + * first and second genes are selected from the pool + */ +void +geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy, + Pool *pool, double bias) +{ + int first, + second; + + first = linear_rand(root, pool->size, bias); + second = linear_rand(root, pool->size, bias); + + /* + * Ensure we have selected different genes, except if pool size is only + * one, when we can't. + * + * This code was observed to hang up in an infinite loop when the + * platform's implementation of erand48() was broken. We now always use + * our own version. + */ + if (pool->size > 1) + { + while (first == second) + second = linear_rand(root, pool->size, bias); + } + + geqo_copy(root, momma, &pool->data[first], pool->string_length); + geqo_copy(root, daddy, &pool->data[second], pool->string_length); +} + +/* + * linear_rand + * generates random integer between 0 and input max number + * using input linear bias + * + * bias is y-intercept of linear distribution + * + * probability distribution function is: f(x) = bias - 2(bias - 1)x + * bias = (prob of first rule) / (prob of middle rule) + */ +static int +linear_rand(PlannerInfo *root, int pool_size, double bias) +{ + double index; /* index between 0 and pool_size */ + double max = (double) pool_size; + + /* + * If geqo_rand() returns exactly 1.0 then we will get exactly max from + * this equation, whereas we need 0 <= index < max. Also it seems + * possible that roundoff error might deliver values slightly outside the + * range; in particular avoid passing a value slightly less than 0 to + * sqrt(). If we get a bad value just try again. + */ + do + { + double sqrtval; + + sqrtval = (bias * bias) - 4.0 * (bias - 1.0) * geqo_rand(root); + if (sqrtval > 0.0) + sqrtval = sqrt(sqrtval); + index = max * (bias - sqrtval) / 2.0 / (bias - 1.0); + } while (index < 0.0 || index >= max); + + return (int) index; +} diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 4dc997c6cb19..e23fb6690f6c 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -111,13 +111,13 @@ static void set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, static bool has_multiple_baserels(PlannerInfo *root); static void generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, List *live_childrels, - List *all_child_pathkeys, - List *partitioned_rels); + List *all_child_pathkeys); static Path *get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer); static void accumulate_append_subpath(Path *path, - List **subpaths, List **special_subpaths); + List **subpaths, + List **special_subpaths); static Path *get_singleton_append_subpath(Path *path); static void set_dummy_rel_pathlist(PlannerInfo *root, RelOptInfo *rel); static void set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, @@ -150,7 +150,8 @@ static void check_output_expressions(Query *subquery, static void compare_tlist_datatypes(List *tlist, List *colTypes, pushdown_safety_info *safetyInfo); static bool targetIsInAllPartitionLists(TargetEntry *tle, Query *query); -static bool qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, +static bool qual_is_pushdown_safe(Query *subquery, Index rti, + RestrictInfo *rinfo, pushdown_safety_info *safetyInfo); static void subquery_push_qual(Query *subquery, RangeTblEntry *rte, Index rti, Node *qual); @@ -636,7 +637,7 @@ bring_to_singleQE(PlannerInfo *root, RelOptInfo *rel) false, target_locus); - path = (Path *) create_material_path(root, rel, path); + path = (Path *) create_material_path(rel, path); } add_path(rel, path); @@ -1142,7 +1143,7 @@ set_tablesample_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry * bms_membership(root->all_baserels) != BMS_SINGLETON) && !(GetTsmRoutine(rte->tablesample->tsmhandler)->repeatable_across_scans)) { - path = (Path *) create_material_path(root, rel, path); + path = (Path *) create_material_path(rel, path); } add_path(rel, path); @@ -1166,7 +1167,11 @@ set_foreign_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) /* ... but do not let it set the rows estimate to zero */ rel->rows = clamp_row_est(rel->rows); - /* also, make sure rel->tuples is not insane relative to rel->rows */ + /* + * Also, make sure rel->tuples is not insane relative to rel->rows. + * Notably, this ensures sanity if pg_class.reltuples contains -1 and the + * FDW doesn't do anything to replace that. + */ rel->tuples = Max(rel->tuples, rel->rows); } @@ -1209,17 +1214,6 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, Assert(IS_SIMPLE_REL(rel)); - /* - * Initialize partitioned_child_rels to contain this RT index. - * - * Note that during the set_append_rel_pathlist() phase, we will bubble up - * the indexes of partitioned relations that appear down in the tree, so - * that when we've created Paths for all the children, the root - * partitioned table's list will contain all such indexes. - */ - if (rte->relkind == RELKIND_PARTITIONED_TABLE) - rel->partitioned_child_rels = list_make1_int(rti); - /* * If this is a partitioned baserel, set the consider_partitionwise_join * flag; currently, we only consider partitionwise joins with the baserel @@ -1409,7 +1403,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, Var *parentvar = (Var *) lfirst(parentvars); Node *childvar = (Node *) lfirst(childvars); - if (IsA(parentvar, Var)) + if (IsA(parentvar, Var) && parentvar->varno == parentRTindex) { int pndx = parentvar->varattno - rel->min_attr; int32 child_width = 0; @@ -1519,12 +1513,6 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, if (IS_DUMMY_REL(childrel)) continue; - /* Bubble up childrel's partitioned children. */ - if (rel->part_scheme) - rel->partitioned_child_rels = - list_concat(rel->partitioned_child_rels, - childrel->partitioned_child_rels); - /* * Child is live, so add it to the live_childrels list for use below. */ @@ -1561,59 +1549,11 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, List *all_child_pathkeys = NIL; List *all_child_outers = NIL; ListCell *l; - List *partitioned_rels = NIL; double partial_rows = -1; /* If appropriate, consider parallel append */ pa_subpaths_valid = enable_parallel_append && rel->consider_parallel; - /* - * AppendPath generated for partitioned tables must record the RT indexes - * of partitioned tables that are direct or indirect children of this - * Append rel. - * - * AppendPath may be for a sub-query RTE (UNION ALL), in which case, 'rel' - * itself does not represent a partitioned relation, but the child sub- - * queries may contain references to partitioned relations. The loop - * below will look for such children and collect them in a list to be - * passed to the path creation function. (This assumes that we don't need - * to look through multiple levels of subquery RTEs; if we ever do, we - * could consider stuffing the list we generate here into sub-query RTE's - * RelOptInfo, just like we do for partitioned rels, which would be used - * when populating our parent rel with paths. For the present, that - * appears to be unnecessary.) - */ - if (rel->part_scheme != NULL) - { - if (IS_SIMPLE_REL(rel)) - partitioned_rels = list_make1(rel->partitioned_child_rels); - else if (IS_JOIN_REL(rel)) - { - int relid = -1; - List *partrels = NIL; - - /* - * For a partitioned joinrel, concatenate the component rels' - * partitioned_child_rels lists. - */ - while ((relid = bms_next_member(rel->relids, relid)) >= 0) - { - RelOptInfo *component; - - Assert(relid >= 1 && relid < root->simple_rel_array_size); - component = root->simple_rel_array[relid]; - Assert(component->part_scheme != NULL); - Assert(list_length(component->partitioned_child_rels) >= 1); - partrels = list_concat(partrels, - component->partitioned_child_rels); - } - - partitioned_rels = list_make1(partrels); - } - - Assert(list_length(partitioned_rels) >= 1); - } - /* * For every non-dummy child, remember the cheapest path. Also, identify * all pathkeys (orderings) and parameterizations (required_outer sets) @@ -1625,14 +1565,6 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, ListCell *lcp; Path *cheapest_partial_path = NULL; - /* - * For UNION ALLs with non-empty partitioned_child_rels, accumulate - * the Lists of child relations. - */ - if (rel->rtekind == RTE_SUBQUERY && childrel->partitioned_child_rels != NIL) - partitioned_rels = lappend(partitioned_rels, - childrel->partitioned_child_rels); - /* * If child has an unparameterized cheapest-total path, add that to * the unparameterized Append path we are constructing for the parent. @@ -1683,7 +1615,6 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, accumulate_append_subpath(cheapest_partial_path, &pa_partial_subpaths, &pa_nonpartial_subpaths); - } else { @@ -1779,7 +1710,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, if (subpaths_valid) add_path(rel, (Path *) create_append_path(root, rel, subpaths, NIL, NIL, NULL, 0, false, - partitioned_rels, -1)); + -1)); /* * Consider an append of unordered, unparameterized partial paths. Make @@ -1822,7 +1753,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, appendpath = create_append_path(root, rel, NIL, partial_subpaths, NIL, NULL, parallel_workers, enable_parallel_append, - partitioned_rels, -1); + -1); /* * Make sure any subsequent partial paths use the same row count @@ -1871,7 +1802,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, appendpath = create_append_path(root, rel, pa_nonpartial_subpaths, pa_partial_subpaths, NIL, NULL, parallel_workers, true, - partitioned_rels, partial_rows); + partial_rows); add_partial_path(rel, (Path *) appendpath); } @@ -1881,8 +1812,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, */ if (subpaths_valid) generate_orderedappend_paths(root, rel, live_childrels, - all_child_pathkeys, - partitioned_rels); + all_child_pathkeys); /* * Build Append paths for each parameterization seen among the child rels. @@ -1933,7 +1863,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, add_path(rel, (Path *) create_append_path(root, rel, subpaths, NIL, NIL, required_outer, 0, false, - partitioned_rels, -1)); + -1)); } /* @@ -1947,23 +1877,20 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, { RelOptInfo *childrel = (RelOptInfo *) linitial(live_childrels); - foreach(l, childrel->partial_pathlist) + /* skip the cheapest partial path, since we already used that above */ + for_each_from(l, childrel->partial_pathlist, 1) { Path *path = (Path *) lfirst(l); AppendPath *appendpath; - /* - * Skip paths with no pathkeys. Also skip the cheapest partial - * path, since we already used that above. - */ - if (path->pathkeys == NIL || - path == linitial(childrel->partial_pathlist)) + /* skip paths with no pathkeys. */ + if (path->pathkeys == NIL) continue; appendpath = create_append_path(root, rel, NIL, list_make1(path), NIL, NULL, path->parallel_workers, true, - partitioned_rels, partial_rows); + partial_rows); add_partial_path(rel, (Path *) appendpath); } } @@ -1999,8 +1926,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, static void generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, List *live_childrels, - List *all_child_pathkeys, - List *partitioned_rels) + List *all_child_pathkeys) { ListCell *lcp; List *partition_pathkeys = NIL; @@ -2166,7 +2092,6 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, NULL, 0, false, - partitioned_rels, -1)); if (startup_neq_total) add_path(rel, (Path *) create_append_path(root, @@ -2177,7 +2102,6 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, NULL, 0, false, - partitioned_rels, -1)); } else @@ -2187,15 +2111,13 @@ generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, rel, startup_subpaths, pathkeys, - NULL, - partitioned_rels)); + NULL)); if (startup_neq_total) add_path(rel, (Path *) create_merge_append_path(root, rel, total_subpaths, pathkeys, - NULL, - partitioned_rels)); + NULL)); } } } @@ -2389,7 +2311,7 @@ set_dummy_rel_pathlist(PlannerInfo *root, RelOptInfo *rel) /* Set up the dummy path */ add_path(rel, (Path *) create_append_path(root, rel, NIL, NIL, NIL, rel->lateral_relids, - 0, false, NIL, -1)); + 0, false, -1)); /* * We set the cheapest-path fields immediately, just in case they were @@ -2440,6 +2362,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, { Query *subquery = rte->subquery; Relids required_outer; + pushdown_safety_info safetyInfo; double tuple_fraction; bool forceDistRand; PlannerConfig *config; @@ -2460,28 +2383,92 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, */ required_outer = rel->lateral_relids; + /* + * Zero out result area for subquery_is_pushdown_safe, so that it can set + * flags as needed while recursing. In particular, we need a workspace + * for keeping track of unsafe-to-reference columns. unsafeColumns[i] + * will be set true if we find that output column i of the subquery is + * unsafe to use in a pushed-down qual. + */ + memset(&safetyInfo, 0, sizeof(safetyInfo)); + safetyInfo.unsafeColumns = (bool *) + palloc0((list_length(subquery->targetList) + 1) * sizeof(bool)); + + /* + * If the subquery has the "security_barrier" flag, it means the subquery + * originated from a view that must enforce row-level security. Then we + * must not push down quals that contain leaky functions. (Ideally this + * would be checked inside subquery_is_pushdown_safe, but since we don't + * currently pass the RTE to that function, we must do it here.) + */ + safetyInfo.unsafeLeaky = rte->security_barrier; + forceDistRand = rte->forceDistRandom; /* CDB: Could be a preplanned subquery from window_planner. */ if (rte->subquery_root == NULL) { /* - * push down quals if possible. Note subquery might be - * different pointer from original one. + * If there are any restriction clauses that have been attached to the + * subquery relation, consider pushing them down to become WHERE or + * HAVING quals of the subquery itself. This transformation is useful + * because it may allow us to generate a better plan for the subquery + * than evaluating all the subquery output rows and then filtering + * them. + * + * There are several cases where we cannot push down clauses. + * Restrictions involving the subquery are checked by + * subquery_is_pushdown_safe(). Restrictions on individual clauses + * are checked by qual_is_pushdown_safe(). Also, we don't want to + * push down pseudoconstant clauses; better to have the gating node + * above the subquery. + * + * Non-pushed-down clauses will get evaluated as qpquals of the + * SubqueryScan node. + * + * XXX Are there any cases where we want to make a policy decision + * not to push down a pushable qual, because it'd result in a worse + * plan? */ - subquery = push_down_restrict(root, rel, rte, rti, subquery); + if (rel->baserestrictinfo != NIL && + subquery_is_pushdown_safe(subquery, subquery, &safetyInfo)) + { + List *upperrestrictlist = NIL; + ListCell *l; + + foreach(l, rel->baserestrictinfo) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); + + if (!rinfo->pseudoconstant && + qual_is_pushdown_safe(subquery, rti, rinfo, &safetyInfo)) + { + Node *clause = (Node *) rinfo->clause; + + /* Push it down */ + subquery_push_qual(subquery, rte, rti, clause); + } + else + { + /* Keep it in the upper query */ + upperrestrictlist = lappend(upperrestrictlist, rinfo); + } + } + rel->baserestrictinfo = upperrestrictlist; + /* We don't bother recomputing baserestrict_min_security */ + } /* - * The upper query might not use all the subquery's output columns; if - * not, we can simplify. + * The upper query might not use all the subquery's output columns; + * if not, we can simplify. */ remove_unused_subquery_outputs(subquery, rel); /* - * We can safely pass the outer tuple_fraction down to the subquery if the - * outer level has no joining, aggregation, or sorting to do. Otherwise - * we'd better tell the subquery to plan for full retrieval. (XXX This - * could probably be made more intelligent ...) + * We can safely pass the outer tuple_fraction down to the subquery + * if the outer level has no joining, aggregation, or sorting to do. + * Otherwise we'd better tell the subquery to plan for full retrieval. + * (XXX This could probably be made more intelligent ...) */ if (subquery->hasAggs || subquery->groupClause || @@ -3210,8 +3197,31 @@ set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) */ required_outer = rel->lateral_relids; - /* Generate appropriate path */ - add_path(rel, create_worktablescan_path(root, rel, ctepath->locus, required_outer)); + /* + * GPDB: pick a truthful locus for the worktable. + * + * The non-recursive term's locus only describes where the *anchor* rows + * are placed. Rows appended by the recursive term stay on whichever + * segment produced them, so a hashed claim is wrong from the second + * iteration on (joins would then colocate against the wrong segment and + * silently lose rows). Declare the worktable Strewn instead: joins + * against it must broadcast or gather the other side, which is correct + * for rows living anywhere. Bottleneck loci (SingleQE/Entry) stay as + * they are: there the whole recursion runs in one process. + */ + { + CdbPathLocus ctelocus; + + if (CdbPathLocus_IsHashed(ctepath->locus) || + CdbPathLocus_IsHashedOJ(ctepath->locus) || + CdbPathLocus_IsStrewn(ctepath->locus)) + CdbPathLocus_MakeStrewn(&ctelocus, + CdbPathLocus_NumSegments(ctepath->locus)); + else + ctelocus = ctepath->locus; + + add_path(rel, create_worktablescan_path(root, rel, ctelocus, required_outer)); + } } /* @@ -3291,6 +3301,9 @@ generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows) * This allows us to do incremental sort on top of an index scan under a gather * merge node, i.e. parallelized. * + * If the require_parallel_safe is true, we also require the expressions to + * be parallel safe (which allows pushing the sort below Gather Merge). + * * XXX At the moment this can only ever return a list with a single element, * because it looks at query_pathkeys only. So we might return the pathkeys * directly, but it seems plausible we'll want to consider other orderings @@ -3298,14 +3311,16 @@ generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows) * merge joins. */ static List * -get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel) +get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel, + bool require_parallel_safe) { List *useful_pathkeys_list = NIL; /* * Considering query_pathkeys is always worth it, because it might allow * us to avoid a total sort when we have a partially presorted path - * available. + * available or to push the total sort into the parallel portion of the + * query. */ if (root->query_pathkeys) { @@ -3318,17 +3333,19 @@ get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel) EquivalenceClass *pathkey_ec = pathkey->pk_eclass; /* - * We can only build an Incremental Sort for pathkeys which - * contain an EC member in the current relation, so ignore any - * suffix of the list as soon as we find a pathkey without an EC - * member the relation. + * We can only build a sort for pathkeys that contain a + * safe-to-compute-early EC member computable from the current + * relation's reltarget, so ignore the remainder of the list as + * soon as we find a pathkey without such a member. + * + * It's still worthwhile to return any prefix of the pathkeys list + * that meets this requirement, as we may be able to do an + * incremental sort. * - * By still returning the prefix of the pathkeys list that does - * meet criteria of EC membership in the current relation, we - * enable not just an incremental sort on the entirety of - * query_pathkeys but also incremental sort below a JOIN. + * If requested, ensure the sort expression is parallel-safe too. */ - if (!find_em_expr_for_rel(pathkey_ec, rel)) + if (!relation_can_be_sorted_early(root, rel, pathkey_ec, + require_parallel_safe)) break; npathkeys++; @@ -3382,13 +3399,14 @@ generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_r generate_gather_paths(root, rel, override_rows); /* consider incremental sort for interesting orderings */ - useful_pathkeys_list = get_useful_pathkeys_for_relation(root, rel); + useful_pathkeys_list = get_useful_pathkeys_for_relation(root, rel, true); /* used for explicit (full) sort paths */ cheapest_partial_path = linitial(rel->partial_pathlist); /* - * Consider incremental sort paths for each interesting ordering. + * Consider sorted paths for each interesting ordering. We generate both + * incremental and full sort. */ foreach(lc, useful_pathkeys_list) { @@ -3402,14 +3420,6 @@ generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_r Path *subpath = (Path *) lfirst(lc2); GatherMergePath *path; - /* - * If the path has no ordering at all, then we can't use either - * incremental sort or rely on implict sorting with a gather - * merge. - */ - if (subpath->pathkeys == NIL) - continue; - is_sorted = pathkeys_count_contained_in(useful_pathkeys, subpath->pathkeys, &presorted_keys); @@ -3655,10 +3665,11 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels) join_search_one_level(root, lev); /* - * Run generate_partitionwise_join_paths() and generate_gather_paths() - * for each just-processed joinrel. We could not do this earlier - * because both regular and partial paths can get added to a - * particular joinrel at multiple times within join_search_one_level. + * Run generate_partitionwise_join_paths() and + * generate_useful_gather_paths() for each just-processed joinrel. We + * could not do this earlier because both regular and partial paths + * can get added to a particular joinrel at multiple times within + * join_search_one_level. * * After that, we're done creating paths for the joinrel, so run * set_cheapest(). @@ -3775,7 +3786,7 @@ push_down_restrict(PlannerInfo *root, RelOptInfo *rel, Node *clause = (Node *) rinfo->clause; if (!rinfo->pseudoconstant && - qual_is_pushdown_safe(subquery, rti, clause, &safetyInfo)) + qual_is_pushdown_safe(subquery, rti, rinfo, &safetyInfo)) { /* Push it down */ subquery_push_qual(subquery, rte, rti, clause); @@ -3830,6 +3841,17 @@ push_down_restrict(PlannerInfo *root, RelOptInfo *rel, * volatile qual could succeed for some SRF output rows and fail for others, * a behavior that cannot occur if it's evaluated before SRF expansion. * + * 6. If the subquery has nonempty grouping sets, we cannot push down any + * quals. The concern here is that a qual referencing a "constant" grouping + * column could get constant-folded, which would be improper because the value + * is potentially nullable by grouping-set expansion. This restriction could + * be removed if we had a parsetree representation that shows that such + * grouping columns are not really constant. (There are other ideas that + * could be used to relax this restriction, but that's the approach most + * likely to get taken in the future. Note that there's not much to be gained + * so long as subquery_planner can't move HAVING clauses to WHERE within such + * a subquery.) + * * In addition, we make several checks on the subquery's output columns to see * if it is safe to reference them in pushed-down quals. If output column k * is found to be unsafe to reference, we set safetyInfo->unsafeColumns[k] @@ -3874,6 +3896,10 @@ subquery_is_pushdown_safe(Query *subquery, Query *topquery, if (subquery->limitOffset != NULL || subquery->limitCount != NULL) return false; + /* Check point 6 */ + if (subquery->groupClause && subquery->groupingSets) + return false; + /* Check points 3, 4, and 5 */ if (subquery->distinctClause || subquery->hasWindowFuncs || @@ -4107,37 +4133,39 @@ targetIsInAllPartitionLists(TargetEntry *tle, Query *query) } /* - * qual_is_pushdown_safe - is a particular qual safe to push down? + * qual_is_pushdown_safe - is a particular rinfo safe to push down? * - * qual is a restriction clause applying to the given subquery (whose RTE + * rinfo is a restriction clause applying to the given subquery (whose RTE * has index rti in the parent query). * * Conditions checked here: * - * 1. The qual must not contain any SubPlans (mainly because I'm not sure - * it will work correctly: SubLinks will already have been transformed into - * SubPlans in the qual, but not in the subquery). Note that SubLinks that - * transform to initplans are safe, and will be accepted here because what - * we'll see in the qual is just a Param referencing the initplan output. + * 1. rinfo's clause must not contain any SubPlans (mainly because it's + * unclear that it will work correctly: SubLinks will already have been + * transformed into SubPlans in the qual, but not in the subquery). Note that + * SubLinks that transform to initplans are safe, and will be accepted here + * because what we'll see in the qual is just a Param referencing the initplan + * output. * - * 2. If unsafeVolatile is set, the qual must not contain any volatile + * 2. If unsafeVolatile is set, rinfo's clause must not contain any volatile * functions. * - * 3. If unsafeLeaky is set, the qual must not contain any leaky functions - * that are passed Var nodes, and therefore might reveal values from the - * subquery as side effects. + * 3. If unsafeLeaky is set, rinfo's clause must not contain any leaky + * functions that are passed Var nodes, and therefore might reveal values from + * the subquery as side effects. * - * 4. The qual must not refer to the whole-row output of the subquery + * 4. rinfo's clause must not refer to the whole-row output of the subquery * (since there is no easy way to name that within the subquery itself). * - * 5. The qual must not refer to any subquery output columns that were + * 5. rinfo's clause must not refer to any subquery output columns that were * found to be unsafe to reference by subquery_is_pushdown_safe(). */ static bool -qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, +qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo, pushdown_safety_info *safetyInfo) { bool safe = true; + Node *qual = (Node *) rinfo->clause; List *vars; ListCell *vl; @@ -4147,7 +4175,7 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, /* Refuse volatile quals if we found they'd be unsafe (point 2) */ if (safetyInfo->unsafeVolatile && - contain_volatile_functions(qual)) + contain_volatile_functions((Node *) rinfo)) return false; /* Refuse leaky quals if told to (point 3) */ @@ -4770,6 +4798,10 @@ print_path(PlannerInfo *root, Path *path, int indent) ptype = "Material"; subpath = ((MaterialPath *) path)->subpath; break; + case T_ResultCachePath: + ptype = "ResultCache"; + subpath = ((ResultCachePath *) path)->subpath; + break; case T_UniquePath: ptype = "Unique"; subpath = ((UniquePath *) path)->subpath; diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c index 1ce4fdf180b5..edc2d9e226a0 100644 --- a/src/backend/optimizer/path/clausesel.c +++ b/src/backend/optimizer/path/clausesel.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -51,6 +51,13 @@ static void addRangeClause(RangeQueryClause **rqlist, Node *clause, bool varonleft, bool isLTsel, Selectivity s2); static RelOptInfo *find_single_rel_for_clauses(PlannerInfo *root, List *clauses); +static Selectivity clauselist_selectivity_or(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + bool use_extended_stats, + bool use_damping); /* cmpSelectivity * comparison function for using qsort on an array of Selectivity entries @@ -89,66 +96,10 @@ cmpSelectivity * * The basic approach is to apply extended statistics first, on as many * clauses as possible, in order to capture cross-column dependencies etc. - * The remaining clauses are then estimated using regular statistics tracked - * for individual columns. This is done by simply passing the clauses to - * clauselist_selectivity_simple. - */ -Selectivity -clauselist_selectivity(PlannerInfo *root, - List *clauses, - int varRelid, - JoinType jointype, - SpecialJoinInfo *sjinfo, - bool use_damping) -{ - Selectivity s1 = 1.0; - RelOptInfo *rel; - Bitmapset *estimatedclauses = NULL; - - /* - * Determine if these clauses reference a single relation. If so, and if - * it has extended statistics, try to apply those. - */ - rel = find_single_rel_for_clauses(root, clauses); - if (rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL) - { - /* - * Estimate as many clauses as possible using extended statistics. - * - * 'estimatedclauses' tracks the 0-based list position index of - * clauses that we've estimated using extended statistics, and that - * should be ignored. - */ - s1 *= statext_clauselist_selectivity(root, clauses, varRelid, - jointype, sjinfo, rel, - &estimatedclauses); - } - - /* - * Apply normal selectivity estimates for the remaining clauses, passing - * 'estimatedclauses' so that it skips already estimated ones. - */ - return s1 * clauselist_selectivity_simple(root, clauses, varRelid, - jointype, sjinfo, - estimatedclauses, - use_damping); -} - -/* - * clauselist_selectivity_simple - - * Compute the selectivity of an implicitly-ANDed list of boolean - * expression clauses. The list can be empty, in which case 1.0 - * must be returned. List elements may be either RestrictInfos - * or bare expression clauses --- the former is preferred since - * it allows caching of results. The estimatedclauses bitmap tracks - * clauses that have already been estimated by other means. - * - * See clause_selectivity() for the meaning of the additional parameters. - * - * Our basic approach is to take the product of the selectivities of the - * subclauses. However, that's only right if the subclauses have independent - * probabilities, and in reality they are often NOT independent. So, - * we want to be smarter where we can. + * The remaining clauses are then estimated by taking the product of their + * selectivities, but that's only right if they have independent + * probabilities, and in reality they are often NOT independent even if they + * only refer to a single column. So, we want to be smarter where we can. * * We also recognize "range queries", such as "x > 34 AND x < 42". Clauses * are recognized as possible range query components if they are restriction @@ -177,16 +128,36 @@ clauselist_selectivity(PlannerInfo *root, * selectivity functions; perhaps some day we can generalize the approach. */ Selectivity -clauselist_selectivity_simple(PlannerInfo *root, - List *clauses, - int varRelid, - JoinType jointype, - SpecialJoinInfo *sjinfo, - Bitmapset *estimatedclauses, - bool use_damping) +clauselist_selectivity(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + bool use_damping) +{ + return clauselist_selectivity_ext(root, clauses, varRelid, + jointype, sjinfo, true, use_damping); +} + +/* + * clauselist_selectivity_ext - + * Extended version of clauselist_selectivity(). If "use_extended_stats" + * is false, all extended statistics will be ignored, and only per-column + * statistics will be used. + */ +Selectivity +clauselist_selectivity_ext(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + bool use_extended_stats, + bool use_damping) { Selectivity s1 = 1.0; Selectivity *rgsel = NULL; + RelOptInfo *rel; + Bitmapset *estimatedclauses = NULL; RangeQueryClause *rqlist = NULL; ListCell *l; int listidx; @@ -198,16 +169,36 @@ clauselist_selectivity_simple(PlannerInfo *root, rgsel = (Selectivity *) palloc(sizeof(Selectivity) * list_length(clauses)); /* - * If there's exactly one clause (and it was not estimated yet), just go - * directly to clause_selectivity(). None of what we might do below is - * relevant. + * If there's exactly one clause, just go directly to + * clause_selectivity_ext(). None of what we might do below is relevant. + */ + if (list_length(clauses) == 1) + return clause_selectivity_ext(root, (Node *) linitial(clauses), + varRelid, jointype, sjinfo, + use_extended_stats, use_damping); + + /* + * Determine if these clauses reference a single relation. If so, and if + * it has extended statistics, try to apply those. */ - if ((list_length(clauses) == 1) && - bms_num_members(estimatedclauses) == 0) - return clause_selectivity(root, (Node *) linitial(clauses), - varRelid, jointype, sjinfo, use_damping); + rel = find_single_rel_for_clauses(root, clauses); + if (use_extended_stats && rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL) + { + /* + * Estimate as many clauses as possible using extended statistics. + * + * 'estimatedclauses' is populated with the 0-based list position + * index of clauses estimated here, and that should be ignored below. + */ + s1 = statext_clauselist_selectivity(root, clauses, varRelid, + jointype, sjinfo, rel, + &estimatedclauses, false); + } /* + * Apply normal selectivity estimates for remaining clauses. We'll be + * careful to skip any clauses which were already estimated above. + * * Anything that doesn't look like a potential rangequery clause gets * multiplied into s1 and forgotten. Anything that does gets inserted into * an rqlist entry. @@ -228,8 +219,9 @@ clauselist_selectivity_simple(PlannerInfo *root, if (bms_is_member(listidx, estimatedclauses)) continue; - /* Always compute the selectivity using clause_selectivity */ - s2 = clause_selectivity(root, clause, varRelid, jointype, sjinfo, use_damping); + /* Compute the selectivity of this clause in isolation */ + s2 = clause_selectivity_ext(root, clause, varRelid, jointype, sjinfo, + use_extended_stats, use_damping); /* * Check for being passed a RestrictInfo. @@ -273,7 +265,7 @@ clauselist_selectivity_simple(PlannerInfo *root, } else { - ok = (NumRelids(clause) == 1) && + ok = (NumRelids(root, clause) == 1) && (is_pseudo_constant_clause(lsecond(expr->args)) || (varonleft = false, is_pseudo_constant_clause(linitial(expr->args)))); @@ -421,6 +413,84 @@ clauselist_selectivity_simple(PlannerInfo *root, return s1; } +/* + * clauselist_selectivity_or - + * Compute the selectivity of an implicitly-ORed list of boolean + * expression clauses. The list can be empty, in which case 0.0 + * must be returned. List elements may be either RestrictInfos + * or bare expression clauses --- the former is preferred since + * it allows caching of results. + * + * See clause_selectivity() for the meaning of the additional parameters. + * + * The basic approach is to apply extended statistics first, on as many + * clauses as possible, in order to capture cross-column dependencies etc. + * The remaining clauses are then estimated as if they were independent. + */ +static Selectivity +clauselist_selectivity_or(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + bool use_extended_stats, + bool use_damping) +{ + Selectivity s1 = 0.0; + RelOptInfo *rel; + Bitmapset *estimatedclauses = NULL; + ListCell *lc; + int listidx; + + /* + * Determine if these clauses reference a single relation. If so, and if + * it has extended statistics, try to apply those. + */ + rel = find_single_rel_for_clauses(root, clauses); + if (use_extended_stats && rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL) + { + /* + * Estimate as many clauses as possible using extended statistics. + * + * 'estimatedclauses' is populated with the 0-based list position + * index of clauses estimated here, and that should be ignored below. + */ + s1 = statext_clauselist_selectivity(root, clauses, varRelid, + jointype, sjinfo, rel, + &estimatedclauses, true); + } + + /* + * Estimate the remaining clauses as if they were independent. + * + * Selectivities for an OR clause are computed as s1+s2 - s1*s2 to account + * for the probable overlap of selected tuple sets. + * + * XXX is this too conservative? + */ + listidx = -1; + foreach(lc, clauses) + { + Selectivity s2; + + listidx++; + + /* + * Skip this clause if it's already been estimated by some other + * statistics above. + */ + if (bms_is_member(listidx, estimatedclauses)) + continue; + + s2 = clause_selectivity_ext(root, (Node *) lfirst(lc), varRelid, + jointype, sjinfo, use_extended_stats, use_damping); + + s1 = s1 + s2 - s1 * s2; + } + + return s1; +} + /* * addRangeClause --- add a new range clause for clauselist_selectivity * @@ -539,7 +609,28 @@ find_single_rel_for_clauses(PlannerInfo *root, List *clauses) * However, currently the extended-stats machinery won't do anything * with non-RestrictInfo clauses anyway, so there's no point in * spending extra cycles; just fail if that's what we have. + * + * An exception to that rule is if we have a bare BoolExpr AND clause. + * We treat this as a special case because the restrictinfo machinery + * doesn't build RestrictInfos on top of AND clauses. */ + if (is_andclause(rinfo)) + { + RelOptInfo *rel; + + rel = find_single_rel_for_clauses(root, + ((BoolExpr *) rinfo)->args); + + if (rel == NULL) + return NULL; + if (lastrelid == 0) + lastrelid = rel->relid; + else if (rel->relid != lastrelid) + return NULL; + + continue; + } + if (!IsA(rinfo, RestrictInfo)) return NULL; @@ -589,7 +680,7 @@ bms_is_subset_singleton(const Bitmapset *s, int x) * restriction or join estimator. Subroutine for clause_selectivity(). */ static inline bool -treat_as_join_clause(Node *clause, RestrictInfo *rinfo, +treat_as_join_clause(PlannerInfo *root, Node *clause, RestrictInfo *rinfo, int varRelid, SpecialJoinInfo *sjinfo) { if (varRelid != 0) @@ -623,7 +714,7 @@ treat_as_join_clause(Node *clause, RestrictInfo *rinfo, if (rinfo) return (bms_membership(rinfo->clause_relids) == BMS_MULTIPLE); else - return (NumRelids(clause) > 1); + return (NumRelids(root, clause) > 1); } } @@ -673,6 +764,25 @@ clause_selectivity(PlannerInfo *root, JoinType jointype, SpecialJoinInfo *sjinfo, bool use_damping) +{ + return clause_selectivity_ext(root, clause, varRelid, + jointype, sjinfo, true, use_damping); +} + +/* + * clause_selectivity_ext - + * Extended version of clause_selectivity(). If "use_extended_stats" is + * false, all extended statistics will be ignored, and only per-column + * statistics will be used. + */ +Selectivity +clause_selectivity_ext(PlannerInfo *root, + Node *clause, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + bool use_extended_stats, + bool use_damping) { Selectivity s1 = 0.5; /* default for any unhandled clause type */ RestrictInfo *rinfo = NULL; @@ -788,52 +898,45 @@ clause_selectivity(PlannerInfo *root, else if (is_notclause(clause)) { /* inverse of the selectivity of the underlying clause */ - s1 = 1.0 - clause_selectivity(root, - (Node *) get_notclausearg((Expr *) clause), - varRelid, - jointype, - sjinfo, - use_damping); + s1 = 1.0 - clause_selectivity_ext(root, + (Node *) get_notclausearg((Expr *) clause), + varRelid, + jointype, + sjinfo, + use_extended_stats, + use_damping); } else if (is_andclause(clause)) { /* share code with clauselist_selectivity() */ - s1 = clauselist_selectivity(root, - ((BoolExpr *) clause)->args, - varRelid, - jointype, - sjinfo, - use_damping); + s1 = clauselist_selectivity_ext(root, + ((BoolExpr *) clause)->args, + varRelid, + jointype, + sjinfo, + use_extended_stats, + use_damping); } else if (is_orclause(clause)) { /* - * Selectivities for an OR clause are computed as s1+s2 - s1*s2 to - * account for the probable overlap of selected tuple sets. - * - * XXX is this too conservative? + * Almost the same thing as clauselist_selectivity, but with the + * clauses connected by OR. */ - ListCell *arg; - - s1 = 0.0; - foreach(arg, ((BoolExpr *) clause)->args) - { - Selectivity s2 = clause_selectivity(root, - (Node *) lfirst(arg), - varRelid, - jointype, - sjinfo, - use_damping); - - s1 = s1 + s2 - s1 * s2; - } + s1 = clauselist_selectivity_or(root, + ((BoolExpr *) clause)->args, + varRelid, + jointype, + sjinfo, + use_extended_stats, + use_damping); } else if (is_opclause(clause) || IsA(clause, DistinctExpr)) { OpExpr *opclause = (OpExpr *) clause; Oid opno = opclause->opno; - if (treat_as_join_clause(clause, rinfo, varRelid, sjinfo)) + if (treat_as_join_clause(root, clause, rinfo, varRelid, sjinfo)) { /* Estimate selectivity for a join clause. */ s1 = join_selectivity(root, opno, @@ -869,7 +972,7 @@ clause_selectivity(PlannerInfo *root, funcclause->funcid, funcclause->args, funcclause->inputcollid, - treat_as_join_clause(clause, rinfo, + treat_as_join_clause(root, clause, rinfo, varRelid, sjinfo), varRelid, jointype, @@ -880,7 +983,7 @@ clause_selectivity(PlannerInfo *root, /* Use node specific selectivity calculation function */ s1 = scalararraysel(root, (ScalarArrayOpExpr *) clause, - treat_as_join_clause(clause, rinfo, + treat_as_join_clause(root, clause, rinfo, varRelid, sjinfo), varRelid, jointype, @@ -927,22 +1030,24 @@ clause_selectivity(PlannerInfo *root, else if (IsA(clause, RelabelType)) { /* Not sure this case is needed, but it can't hurt */ - s1 = clause_selectivity(root, - (Node *) ((RelabelType *) clause)->arg, - varRelid, - jointype, - sjinfo, - use_damping); + s1 = clause_selectivity_ext(root, + (Node *) ((RelabelType *) clause)->arg, + varRelid, + jointype, + sjinfo, + use_extended_stats, + use_damping); } else if (IsA(clause, CoerceToDomain)) { /* Not sure this case is needed, but it can't hurt */ - s1 = clause_selectivity(root, - (Node *) ((CoerceToDomain *) clause)->arg, - varRelid, - jointype, - sjinfo, - use_damping); + s1 = clause_selectivity_ext(root, + (Node *) ((CoerceToDomain *) clause)->arg, + varRelid, + jointype, + sjinfo, + use_extended_stats, + use_damping); } else { diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 1b2e69eb2e08..a5d7348976f0 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -62,7 +62,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -81,6 +81,7 @@ #include "executor/executor.h" #include "executor/nodeAgg.h" #include "executor/nodeHash.h" +#include "executor/nodeResultCache.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" @@ -112,6 +113,13 @@ */ #define APPEND_CPU_COST_MULTIPLIER 0.5 +/* + * Maximum value for row estimates. We cap row estimates to this to help + * ensure that costs based on these estimates remain within the range of what + * double can represent. add_path() wouldn't act sanely given infinite or NaN + * cost values. + */ +#define MAXIMUM_ROWCOUNT 1e100 double seq_page_cost = DEFAULT_SEQ_PAGE_COST; double random_page_cost = DEFAULT_RANDOM_PAGE_COST; @@ -139,6 +147,7 @@ bool enable_hashagg = true; bool enable_groupagg = true; bool enable_nestloop = false; bool enable_material = true; +bool enable_resultcache = true; bool enable_mergejoin = false; bool enable_hashjoin = true; bool enable_gathermerge = true; @@ -147,6 +156,7 @@ bool enable_partitionwise_aggregate = false; bool enable_parallel_append = true; bool enable_parallel_hash = true; bool enable_partition_pruning = true; +bool enable_async_append = true; typedef struct { @@ -1411,6 +1421,101 @@ cost_tidscan(Path *path, PlannerInfo *root, path->total_cost = startup_cost + run_cost; } +/* + * cost_tidrangescan + * Determines and sets the costs of scanning a relation using a range of + * TIDs for 'path' + * + * 'baserel' is the relation to be scanned + * 'tidrangequals' is the list of TID-checkable range quals + * 'param_info' is the ParamPathInfo if this is a parameterized path, else NULL + */ +void +cost_tidrangescan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, List *tidrangequals, + ParamPathInfo *param_info) +{ + Selectivity selectivity; + double pages; + Cost startup_cost = 0; + Cost run_cost = 0; + QualCost qpqual_cost; + Cost cpu_per_tuple; + QualCost tid_qual_cost; + double ntuples; + double nseqpages; + double spc_random_page_cost; + double spc_seq_page_cost; + + /* Should only be applied to base relations */ + Assert(baserel->relid > 0); + Assert(baserel->rtekind == RTE_RELATION); + + /* Mark the path with the correct row estimate */ + if (param_info) + path->rows = param_info->ppi_rows; + else + path->rows = baserel->rows; + + /* Count how many tuples and pages we expect to scan */ + selectivity = clauselist_selectivity(root, tidrangequals, baserel->relid, + JOIN_INNER, NULL, false); + pages = ceil(selectivity * baserel->pages); + + if (pages <= 0.0) + pages = 1.0; + + /* + * The first page in a range requires a random seek, but each subsequent + * page is just a normal sequential page read. NOTE: it's desirable for + * TID Range Scans to cost more than the equivalent Sequential Scans, + * because Seq Scans have some performance advantages such as scan + * synchronization and parallelizability, and we'd prefer one of them to + * be picked unless a TID Range Scan really is better. + */ + ntuples = selectivity * baserel->tuples; + nseqpages = pages - 1.0; + + if (!enable_tidscan) + startup_cost += disable_cost; + + /* + * The TID qual expressions will be computed once, any other baserestrict + * quals once per retrieved tuple. + */ + cost_qual_eval(&tid_qual_cost, tidrangequals, root); + + /* fetch estimated page cost for tablespace containing table */ + get_tablespace_page_costs(baserel->reltablespace, + &spc_random_page_cost, + &spc_seq_page_cost); + + /* disk costs; 1 random page and the remainder as seq pages */ + run_cost += spc_random_page_cost + spc_seq_page_cost * nseqpages; + + /* Add scanning CPU costs */ + get_restriction_qual_cost(root, baserel, param_info, &qpqual_cost); + + /* + * XXX currently we assume TID quals are a subset of qpquals at this + * point; they will be removed (if possible) when we create the plan, so + * we subtract their cost from the total qpqual cost. (If the TID quals + * can't be removed, this is a mistake and we're going to underestimate + * the CPU cost a bit.) + */ + startup_cost += qpqual_cost.startup + tid_qual_cost.per_tuple; + cpu_per_tuple = cpu_tuple_cost + qpqual_cost.per_tuple - + tid_qual_cost.per_tuple; + run_cost += cpu_per_tuple * ntuples; + + /* tlist eval costs are paid per output row, not per tuple scanned */ + startup_cost += path->pathtarget->cost.startup; + run_cost += path->pathtarget->cost.per_tuple * path->rows; + + path->startup_cost = startup_cost; + path->total_cost = startup_cost + run_cost; +} + /* * cost_subqueryscan * Determines and returns the cost of scanning a subquery RTE. @@ -1886,7 +1991,7 @@ cost_tuplesort(Cost *startup_cost, Cost *run_cost, double input_bytes = relation_byte_size(tuples, width); double output_bytes; double output_tuples; - long sort_mem_bytes = (long) global_work_mem(NULL); + long sort_mem_bytes = (long) global_work_mem(); /* * We want to be sure the cost of a sort is never estimated as zero, even @@ -2043,7 +2148,7 @@ cost_incremental_sort(Path *path, * Check if the expression contains Var with "varno 0" so that we * don't call estimate_num_groups in that case. */ - if (bms_is_member(0, pull_varnos((Node *) member->em_expr))) + if (bms_is_member(0, pull_varnos(root, (Node *) member->em_expr))) { unknown_varno = true; break; @@ -2059,7 +2164,8 @@ cost_incremental_sort(Path *path, /* Estimate number of groups with equal presorted keys. */ if (!unknown_varno) - input_groups = estimate_num_groups(root, presortedExprs, input_tuples, NULL); + input_groups = estimate_num_groups(root, presortedExprs, input_tuples, + NULL, NULL); group_tuples = input_tuples / input_groups; group_input_run_cost = input_run_cost / input_groups; @@ -2448,7 +2554,7 @@ cost_merge_append(Path *path, PlannerInfo *root, * occur only on rescan, which is estimated in cost_rescan. */ void -cost_material(Path *path, PlannerInfo *root, +cost_material(Path *path, Cost input_startup_cost, Cost input_total_cost, double tuples, int width) { @@ -2478,7 +2584,7 @@ cost_material(Path *path, PlannerInfo *root, * which isn't exactly accurate but our cost model doesn't allow for * nonuniform costs within the run phase. */ - if (nbytes > global_work_mem(root)) + if (nbytes > global_work_mem()) { double npages = ceil(nbytes / BLCKSZ); @@ -2489,6 +2595,147 @@ cost_material(Path *path, PlannerInfo *root, path->total_cost = startup_cost + run_cost; } +/* + * cost_resultcache_rescan + * Determines the estimated cost of rescanning a ResultCache node. + * + * In order to estimate this, we must gain knowledge of how often we expect to + * be called and how many distinct sets of parameters we are likely to be + * called with. If we expect a good cache hit ratio, then we can set our + * costs to account for that hit ratio, plus a little bit of cost for the + * caching itself. Caching will not work out well if we expect to be called + * with too many distinct parameter values. The worst-case here is that we + * never see any parameter value twice, in which case we'd never get a cache + * hit and caching would be a complete waste of effort. + */ +static void +cost_resultcache_rescan(PlannerInfo *root, ResultCachePath *rcpath, + Cost *rescan_startup_cost, Cost *rescan_total_cost) +{ + EstimationInfo estinfo; + Cost input_startup_cost = rcpath->subpath->startup_cost; + Cost input_total_cost = rcpath->subpath->total_cost; + double tuples = rcpath->subpath->rows; + double calls = rcpath->calls; + int width = rcpath->subpath->pathtarget->width; + + double hash_mem_bytes; + double est_entry_bytes; + double est_cache_entries; + double ndistinct; + double evict_ratio; + double hit_ratio; + Cost startup_cost; + Cost total_cost; + + /* available cache space */ + hash_mem_bytes = get_hash_mem() * 1024L; + + /* + * Set the number of bytes each cache entry should consume in the cache. + * To provide us with better estimations on how many cache entries we can + * store at once, we make a call to the executor here to ask it what + * memory overheads there are for a single cache entry. + * + * XXX we also store the cache key, but that's not accounted for here. + */ + est_entry_bytes = relation_byte_size(tuples, width) + + ExecEstimateCacheEntryOverheadBytes(tuples); + + /* estimate on the upper limit of cache entries we can hold at once */ + est_cache_entries = floor(hash_mem_bytes / est_entry_bytes); + + /* estimate on the distinct number of parameter values */ + ndistinct = estimate_num_groups(root, rcpath->param_exprs, calls, NULL, + &estinfo); + + /* + * When the estimation fell back on using a default value, it's a bit too + * risky to assume that it's ok to use a Result Cache. The use of a + * default could cause us to use a Result Cache when it's really + * inappropriate to do so. If we see that this has been done, then we'll + * assume that every call will have unique parameters, which will almost + * certainly mean a ResultCachePath will never survive add_path(). + */ + if ((estinfo.flags & SELFLAG_USED_DEFAULT) != 0) + ndistinct = calls; + + /* + * Since we've already estimated the maximum number of entries we can + * store at once and know the estimated number of distinct values we'll be + * called with, we'll take this opportunity to set the path's est_entries. + * This will ultimately determine the hash table size that the executor + * will use. If we leave this at zero, the executor will just choose the + * size itself. Really this is not the right place to do this, but it's + * convenient since everything is already calculated. + */ + rcpath->est_entries = Min(Min(ndistinct, est_cache_entries), + PG_UINT32_MAX); + + /* + * When the number of distinct parameter values is above the amount we can + * store in the cache, then we'll have to evict some entries from the + * cache. This is not free. Here we estimate how often we'll incur the + * cost of that eviction. + */ + evict_ratio = 1.0 - Min(est_cache_entries, ndistinct) / ndistinct; + + /* + * In order to estimate how costly a single scan will be, we need to + * attempt to estimate what the cache hit ratio will be. To do that we + * must look at how many scans are estimated in total for this node and + * how many of those scans we expect to get a cache hit. + */ + hit_ratio = 1.0 / ndistinct * Min(est_cache_entries, ndistinct) - + (ndistinct / calls); + + /* Ensure we don't go negative */ + hit_ratio = Max(hit_ratio, 0.0); + + /* + * Set the total_cost accounting for the expected cache hit ratio. We + * also add on a cpu_operator_cost to account for a cache lookup. This + * will happen regardless of whether it's a cache hit or not. + */ + total_cost = input_total_cost * (1.0 - hit_ratio) + cpu_operator_cost; + + /* Now adjust the total cost to account for cache evictions */ + + /* Charge a cpu_tuple_cost for evicting the actual cache entry */ + total_cost += cpu_tuple_cost * evict_ratio; + + /* + * Charge a 10th of cpu_operator_cost to evict every tuple in that entry. + * The per-tuple eviction is really just a pfree, so charging a whole + * cpu_operator_cost seems a little excessive. + */ + total_cost += cpu_operator_cost / 10.0 * evict_ratio * tuples; + + /* + * Now adjust for storing things in the cache, since that's not free + * either. Everything must go in the cache. We don't proportion this + * over any ratio, just apply it once for the scan. We charge a + * cpu_tuple_cost for the creation of the cache entry and also a + * cpu_operator_cost for each tuple we expect to cache. + */ + total_cost += cpu_tuple_cost + cpu_operator_cost * tuples; + + /* + * Getting the first row must be also be proportioned according to the + * expected cache hit ratio. + */ + startup_cost = input_startup_cost * (1.0 - hit_ratio); + + /* + * Additionally we charge a cpu_tuple_cost to account for cache lookups, + * which we'll do regardless of whether it was a cache hit or not. + */ + startup_cost += cpu_tuple_cost; + + *rescan_startup_cost = startup_cost; + *rescan_total_cost = total_cost; +} + /* * cost_agg * Determines and returns the cost of performing an Agg plan node, @@ -2623,6 +2870,7 @@ cost_agg(Path *path, PlannerInfo *root, double pages; double pages_written = 0.0; double pages_read = 0.0; + double spill_cost; double hashentrysize; double nbatches; Size mem_limit; @@ -2635,7 +2883,8 @@ cost_agg(Path *path, PlannerInfo *root, * than or equal to one, all groups are expected to fit in memory; * otherwise we expect to spill. */ - hashentrysize = hash_agg_entry_size(aggcosts->numAggs, input_width, + hashentrysize = hash_agg_entry_size(list_length(root->aggtransinfos), + input_width, aggcosts->transitionSpace); hash_agg_set_limits(NULL, hashentrysize, numGroups, 0, &mem_limit, &ngroups_limit, &num_partitions); @@ -2660,9 +2909,21 @@ cost_agg(Path *path, PlannerInfo *root, pages = relation_byte_size(input_tuples, input_width) / BLCKSZ; pages_written = pages_read = pages * depth; + /* + * HashAgg has somewhat worse IO behavior than Sort on typical + * hardware/OS combinations. Account for this with a generic penalty. + */ + pages_read *= 2.0; + pages_written *= 2.0; + startup_cost += pages_written * random_page_cost; total_cost += pages_written * random_page_cost; total_cost += pages_read * seq_page_cost; + + /* account for CPU cost of spilling a tuple and reading it back */ + spill_cost = depth * input_tuples * 2.0 * cpu_tuple_cost; + startup_cost += spill_cost; + total_cost += spill_cost; } /* @@ -2866,7 +3127,7 @@ cost_shareinputscan(Path *path, PlannerInfo *root, Cost sharecost, path->total_cost = sharecost; /* I/O cost */ - if (nbytes > global_work_mem(root)) + if (nbytes > global_work_mem()) { path->total_cost += seq_page_cost * npages; } @@ -2995,10 +3256,10 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path, double ntuples; double numsegments; - /* Protect some assumptions below that rowcounts aren't zero or NaN */ - if (outer_path_rows <= 0 || isnan(outer_path_rows)) + /* Protect some assumptions below that rowcounts aren't zero */ + if (outer_path_rows <= 0) outer_path_rows = 1; - if (inner_path_rows <= 0 || isnan(inner_path_rows)) + if (inner_path_rows <= 0) inner_path_rows = 1; if (CdbPathLocus_IsPartitioned(path->path.locus)) @@ -3216,10 +3477,10 @@ initial_cost_mergejoin(PlannerInfo *root, JoinCostWorkspace *workspace, innerendsel; Path sort_path; /* dummy for result of cost_sort */ - /* Protect some assumptions below that rowcounts aren't zero or NaN */ - if (outer_path_rows <= 0 || isnan(outer_path_rows)) + /* Protect some assumptions below that rowcounts aren't zero */ + if (outer_path_rows <= 0) outer_path_rows = 1; - if (inner_path_rows <= 0 || isnan(inner_path_rows)) + if (inner_path_rows <= 0) inner_path_rows = 1; /* @@ -3455,8 +3716,8 @@ final_cost_mergejoin(PlannerInfo *root, MergePath *path, double rescanratio; double numsegments; - /* Protect some assumptions below that rowcounts aren't zero or NaN */ - if (inner_path_rows <= 0 || isnan(inner_path_rows)) + /* Protect some assumptions below that rowcounts aren't zero */ + if (inner_path_rows <= 0) inner_path_rows = 1; if (CdbPathLocus_IsPartitioned(path->jpath.path.locus)) @@ -3823,7 +4084,7 @@ initial_cost_hashjoin(PlannerInfo *root, JoinCostWorkspace *workspace, ExecChooseHashTableSize(inner_path_rows_total, inner_path->pathtarget->width, true, /* useskew */ - global_work_mem(root) / 1024L, + global_work_mem() / 1024L, parallel_hash, /* try_combined_hash_mem */ outer_path->parallel_workers, &space_allowed, @@ -4411,6 +4672,11 @@ cost_rescan(PlannerInfo *root, Path *path, *rescan_total_cost = run_cost; } break; + case T_ResultCache: + /* All the hard work is done by cost_resultcache_rescan */ + cost_resultcache_rescan(root, (ResultCachePath *) path, + rescan_startup_cost, rescan_total_cost); + break; default: *rescan_startup_cost = path->startup_cost; *rescan_total_cost = path->total_cost; @@ -4557,21 +4823,50 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) } else if (IsA(node, ScalarArrayOpExpr)) { - /* - * Estimate that the operator will be applied to about half of the - * array elements before the answer is determined. - */ ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node; Node *arraynode = (Node *) lsecond(saop->args); QualCost sacosts; + QualCost hcosts; + int estarraylen = estimate_array_length(arraynode); set_sa_opfuncid(saop); sacosts.startup = sacosts.per_tuple = 0; add_function_cost(context->root, saop->opfuncid, NULL, &sacosts); - context->total.startup += sacosts.startup; - context->total.per_tuple += sacosts.per_tuple * - estimate_array_length(arraynode) * 0.5; + + if (OidIsValid(saop->hashfuncid)) + { + /* Handle costs for hashed ScalarArrayOpExpr */ + hcosts.startup = hcosts.per_tuple = 0; + + add_function_cost(context->root, saop->hashfuncid, NULL, &hcosts); + context->total.startup += sacosts.startup + hcosts.startup; + + /* Estimate the cost of building the hashtable. */ + context->total.startup += estarraylen * hcosts.per_tuple; + + /* + * XXX should we charge a little bit for sacosts.per_tuple when + * building the table, or is it ok to assume there will be zero + * hash collision? + */ + + /* + * Charge for hashtable lookups. Charge a single hash and a + * single comparison. + */ + context->total.per_tuple += hcosts.per_tuple + sacosts.per_tuple; + } + else + { + /* + * Estimate that the operator will be applied to about half of the + * array elements before the answer is determined. + */ + context->total.startup += sacosts.startup; + context->total.per_tuple += sacosts.per_tuple * + estimate_array_length(arraynode) * 0.5; + } } else if (IsA(node, Aggref) || IsA(node, WindowFunc)) @@ -5557,9 +5852,16 @@ get_foreign_key_join_selectivity(PlannerInfo *root, * remove back into the worklist. * * Since the matching clauses are known not outerjoin-delayed, they - * should certainly have appeared in the initial joinclause list. If - * we didn't find them, they must have been matched to, and removed - * by, some other FK in a previous iteration of this loop. (A likely + * would normally have appeared in the initial joinclause list. If we + * didn't find them, there are two possibilities: + * + * 1. If the FK match is based on an EC that is ec_has_const, it won't + * have generated any join clauses at all. We discount such ECs while + * checking to see if we have "all" the clauses. (Below, we'll adjust + * the selectivity estimate for this case.) + * + * 2. The clauses were matched to some other FK in a previous + * iteration of this loop, and thus removed from worklist. (A likely * case is that two FKs are matched to the same EC; there will be only * one EC-derived clause in the initial list, so the first FK will * consume it.) Applying both FKs' selectivity independently risks @@ -5569,8 +5871,9 @@ get_foreign_key_join_selectivity(PlannerInfo *root, * Later we might think of a reasonable way to combine the estimates, * but for now, just punt, since this is a fairly uncommon situation. */ - if (list_length(removedlist) != - (fkinfo->nmatched_ec + fkinfo->nmatched_ri)) + if (removedlist == NIL || + list_length(removedlist) != + (fkinfo->nmatched_ec - fkinfo->nconst_ec + fkinfo->nmatched_ri)) { worklist = list_concat(worklist, removedlist); continue; @@ -5629,9 +5932,49 @@ get_foreign_key_join_selectivity(PlannerInfo *root, fkselec *= 1.0 / ref_tuples; } + + /* + * If any of the FK columns participated in ec_has_const ECs, then + * equivclass.c will have generated "var = const" restrictions for + * each side of the join, thus reducing the sizes of both input + * relations. Taking the fkselec at face value would amount to + * double-counting the selectivity of the constant restriction for the + * referencing Var. Hence, look for the restriction clause(s) that + * were applied to the referencing Var(s), and divide out their + * selectivity to correct for this. + */ + if (fkinfo->nconst_ec > 0) + { + for (int i = 0; i < fkinfo->nkeys; i++) + { + EquivalenceClass *ec = fkinfo->eclass[i]; + + if (ec && ec->ec_has_const) + { + EquivalenceMember *em = fkinfo->fk_eclass_member[i]; + RestrictInfo *rinfo = find_derived_clause_for_ec_member(ec, + em); + + if (rinfo) + { + Selectivity s0; + + s0 = clause_selectivity(root, + (Node *) rinfo, + 0, + jointype, + sjinfo, + false); + if (s0 > 0) + fkselec /= s0; + } + } + } + } } *restrictlist = worklist; + CLAMP_PROBABILITY(fkselec); return fkselec; } @@ -6277,7 +6620,7 @@ int planner_segment_count(GpPolicy *policy) * Output: * total memory in bytes. */ -double global_work_mem(PlannerInfo *root) +double global_work_mem(void) { int segment_count = planner_segment_count(NULL); diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index 3fc0f870a3dd..5681e6f5399c 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -6,7 +6,7 @@ * See src/backend/optimizer/README for discussion of EquivalenceClasses. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -35,6 +35,7 @@ static EquivalenceMember *add_eq_member(EquivalenceClass *ec, Expr *expr, Relids relids, Relids nullable_relids, bool is_child, Oid datatype); +static bool is_exprlist_member(Expr *node, List *exprs); static void generate_base_implied_equalities_const(PlannerInfo *root, EquivalenceClass *ec); static void generate_base_implied_equalities_no_const(PlannerInfo *root, @@ -137,6 +138,7 @@ process_equivalence(PlannerInfo *root, EquivalenceMember *em1, *em2; ListCell *lc1; + int ec2_idx; /* Should not already be marked as having generated an eclass */ Assert(restrictinfo->left_ec == NULL); @@ -195,7 +197,8 @@ process_equivalence(PlannerInfo *root, ntest->location = -1; *p_restrictinfo = - make_restrictinfo((Expr *) ntest, + make_restrictinfo(root, + (Expr *) ntest, restrictinfo->is_pushed_down, restrictinfo->outerjoin_delayed, restrictinfo->pseudoconstant, @@ -258,6 +261,7 @@ process_equivalence(PlannerInfo *root, */ ec1 = ec2 = NULL; em1 = em2 = NULL; + ec2_idx = -1; foreach(lc1, root->eq_classes) { EquivalenceClass *cur_ec = (EquivalenceClass *) lfirst(lc1); @@ -311,6 +315,7 @@ process_equivalence(PlannerInfo *root, equal(item2, cur_em->em_expr)) { ec2 = cur_ec; + ec2_idx = foreach_current_index(lc1); em2 = cur_em; if (ec1) break; @@ -371,7 +376,7 @@ process_equivalence(PlannerInfo *root, ec1->ec_max_security = Max(ec1->ec_max_security, ec2->ec_max_security); ec2->ec_merged = ec1; - root->eq_classes = list_delete_ptr(root->eq_classes, ec2); + root->eq_classes = list_delete_nth_cell(root->eq_classes, ec2_idx); /* just to avoid debugging confusion w/ dangling pointers: */ ec2->ec_members = NIL; ec2->ec_sources = NIL; @@ -634,12 +639,6 @@ get_eclass_for_sort_expr(PlannerInfo *root, */ expr = canonicalize_ec_expression(expr, opcintype, collation); - /* - * Get the precise set of nullable relids appearing in the expression. - */ - expr_relids = pull_varnos((Node *) expr); - nullable_relids = bms_intersect(nullable_relids, expr_relids); - /* * Scan through the existing EquivalenceClasses for a match */ @@ -716,6 +715,12 @@ get_eclass_for_sort_expr(PlannerInfo *root, if (newec->ec_has_volatile && sortref == 0) /* should not happen */ elog(ERROR, "volatile EquivalenceClass has no sortref"); + /* + * Get the precise set of nullable relids appearing in the expression. + */ + expr_relids = pull_varnos(root, (Node *) expr); + nullable_relids = bms_intersect(nullable_relids, expr_relids); + newem = add_eq_member(newec, copyObject(expr), expr_relids, nullable_relids, false, opcintype); @@ -766,6 +771,167 @@ get_eclass_for_sort_expr(PlannerInfo *root, return newec; } +/* + * find_ec_member_matching_expr + * Locate an EquivalenceClass member matching the given expr, if any; + * return NULL if no match. + * + * "Matching" is defined as "equal after stripping RelabelTypes". + * This is used for identifying sort expressions, and we need to allow + * binary-compatible relabeling for some cases involving binary-compatible + * sort operators. + * + * Child EC members are ignored unless they belong to given 'relids'. + */ +EquivalenceMember * +find_ec_member_matching_expr(EquivalenceClass *ec, + Expr *expr, + Relids relids) +{ + ListCell *lc; + + /* We ignore binary-compatible relabeling on both ends */ + while (expr && IsA(expr, RelabelType)) + expr = ((RelabelType *) expr)->arg; + + foreach(lc, ec->ec_members) + { + EquivalenceMember *em = (EquivalenceMember *) lfirst(lc); + Expr *emexpr; + + /* + * We shouldn't be trying to sort by an equivalence class that + * contains a constant, so no need to consider such cases any further. + */ + if (em->em_is_const) + continue; + + /* + * Ignore child members unless they belong to the requested rel. + */ + if (em->em_is_child && + !bms_is_subset(em->em_relids, relids)) + continue; + + /* + * Match if same expression (after stripping relabel). + */ + emexpr = em->em_expr; + while (emexpr && IsA(emexpr, RelabelType)) + emexpr = ((RelabelType *) emexpr)->arg; + + if (equal(emexpr, expr)) + return em; + } + + return NULL; +} + +/* + * find_computable_ec_member + * Locate an EquivalenceClass member that can be computed from the + * expressions appearing in "exprs"; return NULL if no match. + * + * "exprs" can be either a list of bare expression trees, or a list of + * TargetEntry nodes. Either way, it should contain Vars and possibly + * Aggrefs and WindowFuncs, which are matched to the corresponding elements + * of the EquivalenceClass's expressions. + * + * Unlike find_ec_member_matching_expr, there's no special provision here + * for binary-compatible relabeling. This is intentional: if we have to + * compute an expression in this way, setrefs.c is going to insist on exact + * matches of Vars to the source tlist. + * + * Child EC members are ignored unless they belong to given 'relids'. + * Also, non-parallel-safe expressions are ignored if 'require_parallel_safe'. + * + * Note: some callers pass root == NULL for notational reasons. This is OK + * when require_parallel_safe is false. + */ +EquivalenceMember * +find_computable_ec_member(PlannerInfo *root, + EquivalenceClass *ec, + List *exprs, + Relids relids, + bool require_parallel_safe) +{ + ListCell *lc; + + foreach(lc, ec->ec_members) + { + EquivalenceMember *em = (EquivalenceMember *) lfirst(lc); + List *exprvars; + ListCell *lc2; + + /* + * We shouldn't be trying to sort by an equivalence class that + * contains a constant, so no need to consider such cases any further. + */ + if (em->em_is_const) + continue; + + /* + * Ignore child members unless they belong to the requested rel. + */ + if (em->em_is_child && + !bms_is_subset(em->em_relids, relids)) + continue; + + /* + * Match if all Vars and quasi-Vars are available in "exprs". + */ + exprvars = pull_var_clause((Node *) em->em_expr, + PVC_INCLUDE_AGGREGATES | + PVC_INCLUDE_WINDOWFUNCS | + PVC_INCLUDE_PLACEHOLDERS); + foreach(lc2, exprvars) + { + if (!is_exprlist_member(lfirst(lc2), exprs)) + break; + } + list_free(exprvars); + if (lc2) + continue; /* we hit a non-available Var */ + + /* + * If requested, reject expressions that are not parallel-safe. We + * check this last because it's a rather expensive test. + */ + if (require_parallel_safe && + !is_parallel_safe(root, (Node *) em->em_expr)) + continue; + + return em; /* found usable expression */ + } + + return NULL; +} + +/* + * is_exprlist_member + * Subroutine for find_computable_ec_member: is "node" in "exprs"? + * + * Per the requirements of that function, "exprs" might or might not have + * TargetEntry superstructure. + */ +static bool +is_exprlist_member(Expr *node, List *exprs) +{ + ListCell *lc; + + foreach(lc, exprs) + { + Expr *expr = (Expr *) lfirst(lc); + + if (expr && IsA(expr, TargetEntry)) + expr = ((TargetEntry *) expr)->expr; + + if (equal(node, expr)) + return true; + } + return false; +} + /* * Find an equivalence class member expression, all of whose Vars, come from * the indicated relation. @@ -795,6 +961,84 @@ find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel) return NULL; } +/* + * relation_can_be_sorted_early + * Can this relation be sorted on this EC before the final output step? + * + * To succeed, we must find an EC member that prepare_sort_from_pathkeys knows + * how to sort on, given the rel's reltarget as input. There are also a few + * additional constraints based on the fact that the desired sort will be done + * "early", within the scan/join part of the plan. Also, non-parallel-safe + * expressions are ignored if 'require_parallel_safe'. + * + * At some point we might want to return the identified EquivalenceMember, + * but for now, callers only want to know if there is one. + */ +bool +relation_can_be_sorted_early(PlannerInfo *root, RelOptInfo *rel, + EquivalenceClass *ec, bool require_parallel_safe) +{ + PathTarget *target = rel->reltarget; + EquivalenceMember *em; + ListCell *lc; + + /* + * Reject volatile ECs immediately; such sorts must always be postponed. + */ + if (ec->ec_has_volatile) + return false; + + /* + * Try to find an EM directly matching some reltarget member. + */ + foreach(lc, target->exprs) + { + Expr *targetexpr = (Expr *) lfirst(lc); + + em = find_ec_member_matching_expr(ec, targetexpr, rel->relids); + if (!em) + continue; + + /* + * Reject expressions involving set-returning functions, as those + * can't be computed early either. (Note: this test and the following + * one are effectively checking properties of targetexpr, so there's + * no point in asking whether some other EC member would be better.) + */ + if (IS_SRF_CALL((Node *) em->em_expr)) + continue; + + /* + * If requested, reject expressions that are not parallel-safe. We + * check this last because it's a rather expensive test. + */ + if (require_parallel_safe && + !is_parallel_safe(root, (Node *) em->em_expr)) + continue; + + return true; + } + + /* + * Try to find a expression computable from the reltarget. + */ + em = find_computable_ec_member(root, ec, target->exprs, rel->relids, + require_parallel_safe); + if (!em) + return false; + + /* + * Reject expressions involving set-returning functions, as those can't be + * computed early either. (There's no point in looking for another EC + * member in this case; since SRFs can't appear in WHERE, they cannot + * belong to multi-member ECs.) + */ + if (IS_SRF_CALL((Node *) em->em_expr)) + return false; + + return true; +} + /* * generate_base_implied_equalities * Generate any restriction clauses that we can deduce from equivalence @@ -838,10 +1082,8 @@ find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel) * scanning of the quals and before Path construction begins. * * We make no attempt to avoid generating duplicate RestrictInfos here: we - * don't search ec_sources for matches, nor put the created RestrictInfos - * into ec_derives. Doing so would require some slightly ugly changes in - * initsplan.c's API, and there's no real advantage, because the clauses - * generated here can't duplicate anything we will generate for joins anyway. + * don't search ec_sources or ec_derives for matches. It doesn't really + * seem worth the trouble to do so. */ void generate_base_implied_equalities(PlannerInfo *root) @@ -967,6 +1209,7 @@ generate_base_implied_equalities_const(PlannerInfo *root, { EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc); Oid eq_op; + RestrictInfo *rinfo; Assert(!cur_em->em_is_child); /* no children yet */ if (cur_em == const_em) @@ -980,14 +1223,31 @@ generate_base_implied_equalities_const(PlannerInfo *root, ec->ec_broken = true; break; } - process_implied_equality(root, eq_op, ec->ec_collation, - cur_em->em_expr, const_em->em_expr, - bms_copy(ec->ec_relids), - bms_union(cur_em->em_nullable_relids, - const_em->em_nullable_relids), - ec->ec_min_security, - ec->ec_below_outer_join, - cur_em->em_is_const); + rinfo = process_implied_equality(root, eq_op, ec->ec_collation, + cur_em->em_expr, const_em->em_expr, + bms_copy(ec->ec_relids), + bms_union(cur_em->em_nullable_relids, + const_em->em_nullable_relids), + ec->ec_min_security, + ec->ec_below_outer_join, + cur_em->em_is_const); + + /* + * If the clause didn't degenerate to a constant, fill in the correct + * markings for a mergejoinable clause, and save it in ec_derives. (We + * will not re-use such clauses directly, but selectivity estimation + * may consult the list later. Note that this use of ec_derives does + * not overlap with its use for join clauses, since we never generate + * join clauses from an ec_has_const eclass.) + */ + if (rinfo && rinfo->mergeopfamilies) + { + /* it's not redundant, so don't set parent_ec */ + rinfo->left_ec = rinfo->right_ec = ec; + rinfo->left_em = cur_em; + rinfo->right_em = const_em; + ec->ec_derives = lappend(ec->ec_derives, rinfo); + } } } @@ -1026,6 +1286,7 @@ generate_base_implied_equalities_no_const(PlannerInfo *root, { EquivalenceMember *prev_em = prev_ems[relid]; Oid eq_op; + RestrictInfo *rinfo; eq_op = select_equality_operator(ec, prev_em->em_datatype, @@ -1036,14 +1297,29 @@ generate_base_implied_equalities_no_const(PlannerInfo *root, ec->ec_broken = true; break; } - process_implied_equality(root, eq_op, ec->ec_collation, - prev_em->em_expr, cur_em->em_expr, - bms_copy(ec->ec_relids), - bms_union(prev_em->em_nullable_relids, - cur_em->em_nullable_relids), - ec->ec_min_security, - ec->ec_below_outer_join, - false); + rinfo = process_implied_equality(root, eq_op, ec->ec_collation, + prev_em->em_expr, cur_em->em_expr, + bms_copy(ec->ec_relids), + bms_union(prev_em->em_nullable_relids, + cur_em->em_nullable_relids), + ec->ec_min_security, + ec->ec_below_outer_join, + false); + + /* + * If the clause didn't degenerate to a constant, fill in the + * correct markings for a mergejoinable clause. We don't put it + * in ec_derives however; we don't currently need to re-find such + * clauses, and we don't want to clutter that list with non-join + * clauses. + */ + if (rinfo && rinfo->mergeopfamilies) + { + /* it's not redundant, so don't set parent_ec */ + rinfo->left_ec = rinfo->right_ec = ec; + rinfo->left_em = prev_em; + rinfo->right_em = cur_em; + } } prev_ems[relid] = cur_em; } @@ -1172,9 +1448,9 @@ generate_join_implied_equalities(PlannerInfo *root, } /* - * Get all eclasses in common between inner_rel's relids and outer_relids + * Get all eclasses that mention both inner and outer sides of the join */ - matching_ecs = get_common_eclass_indexes(root, inner_rel->relids, + matching_ecs = get_common_eclass_indexes(root, nominal_inner_relids, outer_relids); i = -1; @@ -1594,7 +1870,8 @@ create_join_clause(PlannerInfo *root, */ oldcontext = MemoryContextSwitchTo(root->planner_cxt); - rinfo = build_implied_join_equality(opno, + rinfo = build_implied_join_equality(root, + opno, ec->ec_collation, leftem->em_expr, rightem->em_expr, @@ -1894,7 +2171,8 @@ reconsider_outer_join_clause(PlannerInfo *root, RestrictInfo *rinfo, cur_em->em_datatype); if (!OidIsValid(eq_op)) continue; /* can't generate equality */ - newrinfo = build_implied_join_equality(eq_op, + newrinfo = build_implied_join_equality(root, + eq_op, cur_ec->ec_collation, innervar, cur_em->em_expr, @@ -1965,6 +2243,7 @@ reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo) bool matchleft; bool matchright; ListCell *lc2; + int coal_idx = -1; /* Ignore EC unless it contains pseudoconstants */ if (!cur_ec->ec_has_const) @@ -2009,6 +2288,7 @@ reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo) if (equal(leftvar, cfirst) && equal(rightvar, csecond)) { + coal_idx = foreach_current_index(lc2); match = true; break; } @@ -2037,7 +2317,8 @@ reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo) cur_em->em_datatype); if (OidIsValid(eq_op)) { - newrinfo = build_implied_join_equality(eq_op, + newrinfo = build_implied_join_equality(root, + eq_op, cur_ec->ec_collation, leftvar, cur_em->em_expr, @@ -2052,7 +2333,8 @@ reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo) cur_em->em_datatype); if (OidIsValid(eq_op)) { - newrinfo = build_implied_join_equality(eq_op, + newrinfo = build_implied_join_equality(root, + eq_op, cur_ec->ec_collation, rightvar, cur_em->em_expr, @@ -2073,7 +2355,7 @@ reconsider_full_join_clause(PlannerInfo *root, RestrictInfo *rinfo) */ if (matchleft && matchright) { - cur_ec->ec_members = list_delete_ptr(cur_ec->ec_members, coal_em); + cur_ec->ec_members = list_delete_nth_cell(cur_ec->ec_members, coal_idx); return true; } @@ -2147,6 +2429,10 @@ exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2) * we ignore that fine point here.) This is much like exprs_known_equal, * except that we insist on the comparison operator matching the eclass, so * that the result is definite not approximate. + * + * On success, we also set fkinfo->eclass[colno] to the matching eclass, + * and set fkinfo->fk_eclass_member[colno] to the eclass member for the + * referencing Var. */ EquivalenceClass * match_eclasses_to_foreign_key_col(PlannerInfo *root, @@ -2176,8 +2462,8 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root, { EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, i); - bool item1member = false; - bool item2member = false; + EquivalenceMember *item1_em = NULL; + EquivalenceMember *item2_em = NULL; ListCell *lc2; /* Never match to a volatile EC */ @@ -2202,12 +2488,12 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root, /* Match? */ if (var->varno == var1varno && var->varattno == var1attno) - item1member = true; + item1_em = em; else if (var->varno == var2varno && var->varattno == var2attno) - item2member = true; + item2_em = em; /* Have we found both PK and FK column in this EC? */ - if (item1member && item2member) + if (item1_em && item2_em) { /* * Succeed if eqop matches EC's opfamilies. We could test @@ -2217,7 +2503,11 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root, if (opfamilies == NIL) /* compute if we didn't already */ opfamilies = get_mergejoin_opfamilies(eqop); if (equal(opfamilies, ec->ec_opfamilies)) + { + fkinfo->eclass[colno] = ec; + fkinfo->fk_eclass_member[colno] = item2_em; return ec; + } /* Otherwise, done with this EC, move on to the next */ break; } @@ -2226,6 +2516,37 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root, return NULL; } +/* + * find_derived_clause_for_ec_member + * Search for a previously-derived clause mentioning the given EM. + * + * The eclass should be an ec_has_const EC, of which the EM is a non-const + * member. This should ensure there is just one derived clause mentioning + * the EM (and equating it to a constant). + * Returns NULL if no such clause can be found. + */ +RestrictInfo * +find_derived_clause_for_ec_member(EquivalenceClass *ec, + EquivalenceMember *em) +{ + ListCell *lc; + + Assert(ec->ec_has_const); + Assert(!em->em_is_const); + foreach(lc, ec->ec_derives) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + + /* + * generate_base_implied_equalities_const will have put non-const + * members on the left side of derived clauses. + */ + if (rinfo->left_em == em) + return rinfo; + } + return NULL; +} + /* * add_child_rel_equivalences @@ -2381,6 +2702,7 @@ add_child_join_rel_equivalences(PlannerInfo *root, Relids top_parent_relids = child_joinrel->top_parent_relids; Relids child_relids = child_joinrel->relids; Bitmapset *matching_ecs; + MemoryContext oldcontext; int i; Assert(IS_JOIN_REL(child_joinrel) && IS_JOIN_REL(parent_joinrel)); @@ -2388,6 +2710,16 @@ add_child_join_rel_equivalences(PlannerInfo *root, /* We need consider only ECs that mention the parent joinrel */ matching_ecs = get_eclass_indexes_for_relids(root, top_parent_relids); + /* + * If we're being called during GEQO join planning, we still have to + * create any new EC members in the main planner context, to avoid having + * a corrupt EC data structure after the GEQO context is reset. This is + * problematic since we'll leak memory across repeated GEQO cycles. For + * now, though, bloat is better than crash. If it becomes a real issue + * we'll have to do something to avoid generating duplicate EC members. + */ + oldcontext = MemoryContextSwitchTo(root->planner_cxt); + i = -1; while ((i = bms_next_member(matching_ecs, i)) >= 0) { @@ -2487,6 +2819,8 @@ add_child_join_rel_equivalences(PlannerInfo *root, } } } + + MemoryContextSwitchTo(oldcontext); } diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 535a06b079d2..088e44455afe 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -6,7 +6,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -159,7 +159,8 @@ static IndexClause *match_clause_to_indexcol(PlannerInfo *root, RestrictInfo *rinfo, int indexcol, IndexOptInfo *index); -static IndexClause *match_boolean_index_clause(RestrictInfo *rinfo, +static IndexClause *match_boolean_index_clause(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index); static IndexClause *match_opclause_to_indexcol(PlannerInfo *root, RestrictInfo *rinfo, @@ -175,13 +176,16 @@ static IndexClause *get_index_clause_from_support(PlannerInfo *root, int indexarg, int indexcol, IndexOptInfo *index); -static IndexClause *match_saopclause_to_indexcol(RestrictInfo *rinfo, +static IndexClause *match_saopclause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index); -static IndexClause *match_rowcompare_to_indexcol(RestrictInfo *rinfo, +static IndexClause *match_rowcompare_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index); -static IndexClause *expand_indexqual_rowcompare(RestrictInfo *rinfo, +static IndexClause *expand_indexqual_rowcompare(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index, Oid expr_op, @@ -2009,6 +2013,7 @@ adjust_rowcount_for_semijoins(PlannerInfo *root, nunique = estimate_num_groups(root, sjinfo->semi_rhs_exprs, nraw, + NULL, NULL); if (rowcount > nunique) rowcount = nunique; @@ -2339,7 +2344,7 @@ match_clause_to_indexcol(PlannerInfo *root, opfamily = index->opfamily[indexcol]; if (IsBooleanOpfamily(opfamily)) { - iclause = match_boolean_index_clause(rinfo, indexcol, index); + iclause = match_boolean_index_clause(root, rinfo, indexcol, index); if (iclause) return iclause; } @@ -2359,11 +2364,11 @@ match_clause_to_indexcol(PlannerInfo *root, } else if (IsA(clause, ScalarArrayOpExpr)) { - return match_saopclause_to_indexcol(rinfo, indexcol, index); + return match_saopclause_to_indexcol(root, rinfo, indexcol, index); } else if (IsA(clause, RowCompareExpr)) { - return match_rowcompare_to_indexcol(rinfo, indexcol, index); + return match_rowcompare_to_indexcol(root, rinfo, indexcol, index); } else if (index->amsearchnulls && IsA(clause, NullTest)) { @@ -2402,7 +2407,8 @@ match_clause_to_indexcol(PlannerInfo *root, * index's key, and if so, build a suitable IndexClause. */ static IndexClause * -match_boolean_index_clause(RestrictInfo *rinfo, +match_boolean_index_clause(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index) { @@ -2472,7 +2478,7 @@ match_boolean_index_clause(RestrictInfo *rinfo, IndexClause *iclause = makeNode(IndexClause); iclause->rinfo = rinfo; - iclause->indexquals = list_make1(make_simple_restrictinfo(op)); + iclause->indexquals = list_make1(make_simple_restrictinfo(root, op)); iclause->lossy = false; iclause->indexcol = indexcol; iclause->indexcols = NIL; @@ -2697,7 +2703,8 @@ get_index_clause_from_support(PlannerInfo *root, { Expr *clause = (Expr *) lfirst(lc); - indexquals = lappend(indexquals, make_simple_restrictinfo(clause)); + indexquals = lappend(indexquals, + make_simple_restrictinfo(root, clause)); } iclause->rinfo = rinfo; @@ -2718,7 +2725,8 @@ get_index_clause_from_support(PlannerInfo *root, * which see for comments. */ static IndexClause * -match_saopclause_to_indexcol(RestrictInfo *rinfo, +match_saopclause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index) { @@ -2737,7 +2745,7 @@ match_saopclause_to_indexcol(RestrictInfo *rinfo, return NULL; leftop = (Node *) linitial(saop->args); rightop = (Node *) lsecond(saop->args); - right_relids = pull_varnos(rightop); + right_relids = pull_varnos(root, rightop); expr_op = saop->opno; expr_coll = saop->inputcollid; @@ -2785,7 +2793,8 @@ match_saopclause_to_indexcol(RestrictInfo *rinfo, * is handled by expand_indexqual_rowcompare(). */ static IndexClause * -match_rowcompare_to_indexcol(RestrictInfo *rinfo, +match_rowcompare_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index) { @@ -2830,14 +2839,14 @@ match_rowcompare_to_indexcol(RestrictInfo *rinfo, * These syntactic tests are the same as in match_opclause_to_indexcol() */ if (match_index_to_operand(leftop, indexcol, index) && - !bms_is_member(index_relid, pull_varnos(rightop)) && + !bms_is_member(index_relid, pull_varnos(root, rightop)) && !contain_volatile_functions(rightop)) { /* OK, indexkey is on left */ var_on_left = true; } else if (match_index_to_operand(rightop, indexcol, index) && - !bms_is_member(index_relid, pull_varnos(leftop)) && + !bms_is_member(index_relid, pull_varnos(root, leftop)) && !contain_volatile_functions(leftop)) { /* indexkey is on right, so commute the operator */ @@ -2856,7 +2865,8 @@ match_rowcompare_to_indexcol(RestrictInfo *rinfo, case BTLessEqualStrategyNumber: case BTGreaterEqualStrategyNumber: case BTGreaterStrategyNumber: - return expand_indexqual_rowcompare(rinfo, + return expand_indexqual_rowcompare(root, + rinfo, indexcol, index, expr_op, @@ -2890,7 +2900,8 @@ match_rowcompare_to_indexcol(RestrictInfo *rinfo, * but we split it out for comprehensibility. */ static IndexClause * -expand_indexqual_rowcompare(RestrictInfo *rinfo, +expand_indexqual_rowcompare(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, IndexOptInfo *index, Oid expr_op, @@ -2960,7 +2971,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, if (expr_op == InvalidOid) break; /* operator is not usable */ } - if (bms_is_member(index->rel->relid, pull_varnos(constop))) + if (bms_is_member(index->rel->relid, pull_varnos(root, constop))) break; /* no good, Var on wrong side */ if (contain_volatile_functions(constop)) break; /* no good, volatile comparison value */ @@ -3070,7 +3081,8 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, matching_cols); rc->rargs = list_truncate(copyObject(non_var_args), matching_cols); - iclause->indexquals = list_make1(make_simple_restrictinfo((Expr *) rc)); + iclause->indexquals = list_make1(make_simple_restrictinfo(root, + (Expr *) rc)); } else { @@ -3084,7 +3096,7 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo, copyObject(linitial(non_var_args)), InvalidOid, linitial_oid(clause->inputcollids)); - iclause->indexquals = list_make1(make_simple_restrictinfo(op)); + iclause->indexquals = list_make1(make_simple_restrictinfo(root, op)); } } @@ -3420,7 +3432,7 @@ check_index_predicates(PlannerInfo *root, RelOptInfo *rel) * and pass them through to EvalPlanQual via a side channel; but for now, * we just don't remove implied quals at all for target relations. */ - is_target_rel = (rel->relid == root->parse->resultRelation || + is_target_rel = (bms_is_member(rel->relid, root->all_result_relids) || get_plan_rowmark(root->rowMarks, rel->relid) != NULL); /* @@ -3701,7 +3713,9 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, * specified index column matches a boolean restriction clause. */ bool -indexcol_is_bool_constant_for_query(IndexOptInfo *index, int indexcol) +indexcol_is_bool_constant_for_query(PlannerInfo *root, + IndexOptInfo *index, + int indexcol) { ListCell *lc; @@ -3723,7 +3737,7 @@ indexcol_is_bool_constant_for_query(IndexOptInfo *index, int indexcol) continue; /* See if we can match the clause's expression to the index column */ - if (match_boolean_index_clause(rinfo, indexcol, index)) + if (match_boolean_index_clause(root, rinfo, indexcol, index)) return true; } @@ -3835,10 +3849,10 @@ match_index_to_operand(Node *operand, * index: the index of interest */ bool -is_pseudo_constant_for_index(Node *expr, IndexOptInfo *index) +is_pseudo_constant_for_index(PlannerInfo *root, Node *expr, IndexOptInfo *index) { /* pull_varnos is cheaper than volatility check, so do that first */ - if (bms_is_member(index->rel->relid, pull_varnos(expr))) + if (bms_is_member(index->rel->relid, pull_varnos(root, expr))) return false; /* no good, contains Var of table */ if (contain_volatile_functions(expr)) return false; /* no good, volatile comparison value */ diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index f49ebe141201..72b79afd3297 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,7 +20,9 @@ #include "executor/executor.h" #include "foreign/fdwapi.h" +#include "nodes/nodeFuncs.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" @@ -29,6 +31,7 @@ #include "executor/nodeHash.h" /* ExecHashRowSize() */ #include "cdb/cdbpath.h" /* cdbpath_rows() */ +#include "utils/typcache.h" /* Hook for plugins to get control in add_paths_to_joinrel() */ set_join_pathlist_hook_type set_join_pathlist_hook = NULL; @@ -60,6 +63,9 @@ static void try_partial_mergejoin_path(PlannerInfo *root, static void sort_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra); +static inline bool clause_sides_match_join(RestrictInfo *rinfo, + RelOptInfo *outerrel, + RelOptInfo *innerrel); static void match_unsorted_outer(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra); @@ -201,6 +207,11 @@ add_paths_to_joinrel(PlannerInfo *root, { case JOIN_SEMI: case JOIN_ANTI: + + /* + * XXX it may be worth proving this to allow a ResultCache to be + * considered for Nested Loop Semi/Anti Joins. + */ extra.inner_unique = false; /* well, unproven */ break; case JOIN_UNIQUE_INNER: @@ -399,6 +410,212 @@ allow_star_schema_join(PlannerInfo *root, bms_nonempty_difference(inner_paramrels, outerrelids)); } +/* + * paraminfo_get_equal_hashops + * Determine if param_info and innerrel's lateral_vars can be hashed. + * Returns true the hashing is possible, otherwise return false. + * + * Additionally we also collect the outer exprs and the hash operators for + * each parameter to innerrel. These set in 'param_exprs' and 'operators' + * when we return true. + */ +static bool +paraminfo_get_equal_hashops(PlannerInfo *root, ParamPathInfo *param_info, + RelOptInfo *outerrel, RelOptInfo *innerrel, + List **param_exprs, List **operators) + +{ + ListCell *lc; + + *param_exprs = NIL; + *operators = NIL; + + if (param_info != NULL) + { + List *clauses = param_info->ppi_clauses; + + foreach(lc, clauses) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + OpExpr *opexpr; + Node *expr; + + /* can't use result cache without a valid hash equals operator */ + if (!OidIsValid(rinfo->hasheqoperator) || + !clause_sides_match_join(rinfo, outerrel, innerrel)) + { + list_free(*operators); + list_free(*param_exprs); + return false; + } + + /* + * We already checked that this is an OpExpr with 2 args when + * setting hasheqoperator. + */ + opexpr = (OpExpr *) rinfo->clause; + if (rinfo->outer_is_left) + expr = (Node *) linitial(opexpr->args); + else + expr = (Node *) lsecond(opexpr->args); + + *operators = lappend_oid(*operators, rinfo->hasheqoperator); + *param_exprs = lappend(*param_exprs, expr); + } + } + + /* Now add any lateral vars to the cache key too */ + foreach(lc, innerrel->lateral_vars) + { + Node *expr = (Node *) lfirst(lc); + TypeCacheEntry *typentry; + + /* Reject if there are any volatile functions */ + if (contain_volatile_functions(expr)) + { + list_free(*operators); + list_free(*param_exprs); + return false; + } + + typentry = lookup_type_cache(exprType(expr), + TYPECACHE_HASH_PROC | TYPECACHE_EQ_OPR); + + /* can't use result cache without a valid hash equals operator */ + if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr)) + { + list_free(*operators); + list_free(*param_exprs); + return false; + } + + *operators = lappend_oid(*operators, typentry->eq_opr); + *param_exprs = lappend(*param_exprs, expr); + } + + /* We're okay to use result cache */ + return true; +} + +/* + * get_resultcache_path + * If possible, make and return a Result Cache path atop of 'inner_path'. + * Otherwise return NULL. + */ +static Path * +get_resultcache_path(PlannerInfo *root, RelOptInfo *innerrel, + RelOptInfo *outerrel, Path *inner_path, + Path *outer_path, JoinType jointype, + JoinPathExtraData *extra) +{ + List *param_exprs; + List *hash_operators; + ListCell *lc; + + /* Obviously not if it's disabled */ + if (!enable_resultcache) + return NULL; + + /* + * We can safely not bother with all this unless we expect to perform more + * than one inner scan. The first scan is always going to be a cache + * miss. This would likely fail later anyway based on costs, so this is + * really just to save some wasted effort. + */ + if (outer_path->parent->rows < 2) + return NULL; + + /* + * We can only have a result cache when there's some kind of cache key, + * either parameterized path clauses or lateral Vars. No cache key sounds + * more like something a Materialize node might be more useful for. + */ + if ((inner_path->param_info == NULL || + inner_path->param_info->ppi_clauses == NIL) && + innerrel->lateral_vars == NIL) + return NULL; + + /* + * Currently we don't do this for SEMI and ANTI joins unless they're + * marked as inner_unique. This is because nested loop SEMI/ANTI joins + * don't scan the inner node to completion, which will mean result cache + * cannot mark the cache entry as complete. + * + * XXX Currently we don't attempt to mark SEMI/ANTI joins as inner_unique + * = true. Should we? See add_paths_to_joinrel() + */ + if (!extra->inner_unique && (jointype == JOIN_SEMI || + jointype == JOIN_ANTI)) + return NULL; + + /* + * Result Cache normally marks cache entries as complete when it runs out + * of tuples to read from its subplan. However, with unique joins, Nested + * Loop will skip to the next outer tuple after finding the first matching + * inner tuple. This means that we may not read the inner side of the + * join to completion which leaves no opportunity to mark the cache entry + * as complete. To work around that, when the join is unique we + * automatically mark cache entries as complete after fetching the first + * tuple. This works when the entire join condition is parameterized. + * Otherwise, when the parameterization is only a subset of the join + * condition, we can't be sure which part of it causes the join to be + * unique. This means there are no guarantees that only 1 tuple will be + * read. We cannot mark the cache entry as complete after reading the + * first tuple without that guarantee. This means the scope of Result + * Cache's usefulness is limited to only outer rows that have no join + * partner as this is the only case where Nested Loop would exhaust the + * inner scan of a unique join. Since the scope is limited to that, we + * just don't bother making a result cache path in this case. + * + * Lateral vars needn't be considered here as they're not considered when + * determining if the join is unique. + * + * XXX this could be enabled if the remaining join quals were made part of + * the inner scan's filter instead of the join filter. Maybe it's worth + * considering doing that? + */ + if (extra->inner_unique && + (inner_path->param_info == NULL || + list_length(inner_path->param_info->ppi_clauses) < + list_length(extra->restrictlist))) + return NULL; + + /* + * We can't use a result cache if there are volatile functions in the + * inner rel's target list or restrict list. A cache hit could reduce the + * number of calls to these functions. + */ + if (contain_volatile_functions((Node *) innerrel->reltarget)) + return NULL; + + foreach(lc, innerrel->baserestrictinfo) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + + if (contain_volatile_functions((Node *) rinfo)) + return NULL; + } + + /* Check if we have hash ops for each parameter to the path */ + if (paraminfo_get_equal_hashops(root, + inner_path->param_info, + outerrel, + innerrel, + ¶m_exprs, + &hash_operators)) + { + return (Path *) create_resultcache_path(root, + innerrel, + inner_path, + param_exprs, + hash_operators, + extra->inner_unique, + outer_path->parent->rows); + } + + return NULL; +} + /* * try_nestloop_path * Consider a nestloop join path; if it appears useful, push it into @@ -534,8 +751,8 @@ try_partial_nestloop_path(PlannerInfo *root, /* * If the inner path is parameterized, the parameterization must be fully * satisfied by the proposed outer path. Parameterized partial paths are - * not supported. The caller should already have verified that no - * extra_lateral_rels are required here. + * not supported. The caller should already have verified that no lateral + * rels are required here. */ Assert(bms_is_empty(joinrel->lateral_relids)); if (inner_path->param_info != NULL) @@ -861,8 +1078,8 @@ try_partial_hashjoin_path(PlannerInfo *root, /* * If the inner path is parameterized, the parameterization must be fully * satisfied by the proposed outer path. Parameterized partial paths are - * not supported. The caller should already have verified that no - * extra_lateral_rels are required here. + * not supported. The caller should already have verified that no lateral + * rels are required here. */ Assert(bms_is_empty(joinrel->lateral_relids)); if (inner_path->param_info != NULL) @@ -1072,8 +1289,8 @@ sort_inner_and_outer(PlannerInfo *root, /* Make a pathkey list with this guy first */ if (l != list_head(all_pathkeys)) outerkeys = lcons(front_pathkey, - list_delete_ptr(list_copy(all_pathkeys), - front_pathkey)); + list_delete_nth_cell(list_copy(all_pathkeys), + foreach_current_index(l))); else outerkeys = all_pathkeys; /* no work at first one... */ @@ -1491,7 +1708,7 @@ match_unsorted_outer(PlannerInfo *root, if (enable_material && inner_cheapest_total != NULL && !ExecMaterializesOutput(inner_cheapest_total->pathtype)) matpath = (Path *) - create_material_path(root, innerrel, inner_cheapest_total); + create_material_path(innerrel, inner_cheapest_total); } foreach(lc1, outerrel->pathlist) @@ -1555,6 +1772,7 @@ match_unsorted_outer(PlannerInfo *root, foreach(lc2, innerrel->cheapest_parameterized_paths) { Path *innerpath = (Path *) lfirst(lc2); + Path *rcpath; try_nestloop_path(root, joinrel, @@ -1564,6 +1782,23 @@ match_unsorted_outer(PlannerInfo *root, jointype, save_jointype, extra); + + /* + * Try generating a result cache path and see if that makes + * the nested loop any cheaper. + */ + rcpath = get_resultcache_path(root, innerrel, outerrel, + innerpath, outerpath, jointype, + extra); + if (rcpath != NULL) + try_nestloop_path(root, + joinrel, + outerpath, + rcpath, + merge_pathkeys, + jointype, + save_jointype, + extra); } /* Also consider materialized form of the cheapest inner path */ @@ -1598,7 +1833,7 @@ match_unsorted_outer(PlannerInfo *root, * partial path and the joinrel is parallel-safe. However, we can't * handle JOIN_UNIQUE_OUTER, because the outer path will be partial, and * therefore we won't be able to properly guarantee uniqueness. Nor can - * we handle extra_lateral_rels, since partial paths must not be + * we handle joins needing lateral rels, since partial paths must not be * parameterized. Similarly, we can't handle JOIN_FULL and JOIN_RIGHT, * because they can produce false null extended rows. */ @@ -1719,6 +1954,7 @@ consider_parallel_nestloop(PlannerInfo *root, foreach(lc2, innerrel->cheapest_parameterized_paths) { Path *innerpath = (Path *) lfirst(lc2); + Path *rcpath; /* Can't join to an inner path that is not parallel-safe */ if (!innerpath->parallel_safe) @@ -1742,9 +1978,18 @@ consider_parallel_nestloop(PlannerInfo *root, } try_partial_nestloop_path(root, joinrel, outerpath, innerpath, - pathkeys, jointype, - save_jointype, - extra); + pathkeys, jointype, save_jointype, extra); + + /* + * Try generating a result cache path and see if that makes the + * nested loop any cheaper. + */ + rcpath = get_resultcache_path(root, innerrel, outerrel, + innerpath, outerpath, jointype, + extra); + if (rcpath != NULL) + try_partial_nestloop_path(root, joinrel, outerpath, rcpath, + pathkeys, jointype, save_jointype, extra); } } } diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index 141db34224d5..4a7423dbeaee 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1321,7 +1321,7 @@ mark_dummy_rel(PlannerInfo *root, RelOptInfo *rel) /* Set up the dummy path */ add_path(rel, (Path *) create_append_path(root, rel, NIL, NIL, NIL, rel->lateral_relids, - 0, false, NIL, -1)); + 0, false, -1)); /* Set or update cheapest_total_path */ set_cheapest(rel); diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index 6ba0599eb5ed..a03a8d6e3bf0 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -9,7 +9,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -145,7 +145,7 @@ gen_implied_qual(PlannerInfo *root, if (ctx.numReplacementsDone == 0) return; - new_qualscope = pull_varnos(new_clause); + new_qualscope = pull_varnos(root, new_clause); if (new_qualscope == NULL) return; @@ -171,7 +171,8 @@ gen_implied_qual(PlannerInfo *root, * equivalence class machinery, because it's derived from a clause that * wasn't either. */ - new_rinfo = make_restrictinfo((Expr *) new_clause, + new_rinfo = make_restrictinfo(root, + (Expr *) new_clause, old_rinfo->is_pushed_down, old_rinfo->outerjoin_delayed, old_rinfo->pseudoconstant, @@ -926,7 +927,7 @@ build_index_pathkeys(PlannerInfo *root, * should stop considering index columns; any lower-order sort * keys won't be useful either. */ - if (!indexcol_is_bool_constant_for_query(index, i)) + if (!indexcol_is_bool_constant_for_query(root, index, i)) break; } diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c index 699d9183f638..553628afa4a5 100644 --- a/src/backend/optimizer/path/tidpath.c +++ b/src/backend/optimizer/path/tidpath.c @@ -2,9 +2,9 @@ * * tidpath.c * Routines to determine which TID conditions are usable for scanning - * a given relation, and create TidPaths accordingly. + * a given relation, and create TidPaths and TidRangePaths accordingly. * - * What we are looking for here is WHERE conditions of the form + * For TidPaths, we look for WHERE conditions of the form * "CTID = pseudoconstant", which can be implemented by just fetching * the tuple directly via heap_fetch(). We can also handle OR'd conditions * such as (CTID = const1) OR (CTID = const2), as well as ScalarArrayOpExpr @@ -23,10 +23,13 @@ * a function, but in practice it works better to keep the special node * representation all the way through to execution. * + * Additionally, TidRangePaths may be created for conditions of the form + * "CTID relop pseudoconstant", where relop is one of >,>=,<,<=, and + * AND-clauses composed of such conditions. * * Portions Copyright (c) 2007-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -65,14 +68,14 @@ IsCTIDVar(Var *var, RelOptInfo *rel) /* * Check to see if a RestrictInfo is of the form - * CTID = pseudoconstant + * CTID OP pseudoconstant * or - * pseudoconstant = CTID - * where the CTID Var belongs to relation "rel", and nothing on the - * other side of the clause does. + * pseudoconstant OP CTID + * where OP is a binary operation, the CTID Var belongs to relation "rel", + * and nothing on the other side of the clause does. */ static bool -IsTidEqualClause(RestrictInfo *rinfo, RelOptInfo *rel) +IsBinaryTidClause(RestrictInfo *rinfo, RelOptInfo *rel) { OpExpr *node; Node *arg1, @@ -85,10 +88,9 @@ IsTidEqualClause(RestrictInfo *rinfo, RelOptInfo *rel) return false; node = (OpExpr *) rinfo->clause; - /* Operator must be tideq */ - if (node->opno != TIDEqualOperator) + /* OpExpr must have two arguments */ + if (list_length(node->args) != 2) return false; - Assert(list_length(node->args) == 2); arg1 = linitial(node->args); arg2 = lsecond(node->args); @@ -118,6 +120,50 @@ IsTidEqualClause(RestrictInfo *rinfo, RelOptInfo *rel) return true; /* success */ } +/* + * Check to see if a RestrictInfo is of the form + * CTID = pseudoconstant + * or + * pseudoconstant = CTID + * where the CTID Var belongs to relation "rel", and nothing on the + * other side of the clause does. + */ +static bool +IsTidEqualClause(RestrictInfo *rinfo, RelOptInfo *rel) +{ + if (!IsBinaryTidClause(rinfo, rel)) + return false; + + if (((OpExpr *) rinfo->clause)->opno == TIDEqualOperator) + return true; + + return false; +} + +/* + * Check to see if a RestrictInfo is of the form + * CTID OP pseudoconstant + * or + * pseudoconstant OP CTID + * where OP is a range operator such as <, <=, >, or >=, the CTID Var belongs + * to relation "rel", and nothing on the other side of the clause does. + */ +static bool +IsTidRangeClause(RestrictInfo *rinfo, RelOptInfo *rel) +{ + Oid opno; + + if (!IsBinaryTidClause(rinfo, rel)) + return false; + opno = ((OpExpr *) rinfo->clause)->opno; + + if (opno == TIDLessOperator || opno == TIDLessEqOperator || + opno == TIDGreaterOperator || opno == TIDGreaterEqOperator) + return true; + + return false; +} + /* * Check to see if a RestrictInfo is of the form * CTID = ANY (pseudoconstant_array) @@ -125,7 +171,7 @@ IsTidEqualClause(RestrictInfo *rinfo, RelOptInfo *rel) * other side of the clause does. */ static bool -IsTidEqualAnyClause(RestrictInfo *rinfo, RelOptInfo *rel) +IsTidEqualAnyClause(PlannerInfo *root, RestrictInfo *rinfo, RelOptInfo *rel) { ScalarArrayOpExpr *node; Node *arg1, @@ -150,7 +196,7 @@ IsTidEqualAnyClause(RestrictInfo *rinfo, RelOptInfo *rel) IsCTIDVar((Var *) arg1, rel)) { /* The other argument must be a pseudoconstant */ - if (bms_is_member(rel->relid, pull_varnos(arg2)) || + if (bms_is_member(rel->relid, pull_varnos(root, arg2)) || contain_volatile_functions(arg2)) return false; @@ -192,7 +238,7 @@ IsCurrentOfClause(RestrictInfo *rinfo, RelOptInfo *rel) * (Using a List may seem a bit weird, but it simplifies the caller.) */ static List * -TidQualFromRestrictInfo(RestrictInfo *rinfo, RelOptInfo *rel) +TidQualFromRestrictInfo(PlannerInfo *root, RestrictInfo *rinfo, RelOptInfo *rel) { /* * We may ignore pseudoconstant clauses (they can't contain Vars, so could @@ -212,7 +258,7 @@ TidQualFromRestrictInfo(RestrictInfo *rinfo, RelOptInfo *rel) * Check all base cases. If we get a match, return the clause. */ if (IsTidEqualClause(rinfo, rel) || - IsTidEqualAnyClause(rinfo, rel) || + IsTidEqualAnyClause(root, rinfo, rel) || IsCurrentOfClause(rinfo, rel)) return list_make1(rinfo); @@ -224,12 +270,12 @@ TidQualFromRestrictInfo(RestrictInfo *rinfo, RelOptInfo *rel) * * Returns a List of CTID qual RestrictInfos for the specified rel (with * implicit OR semantics across the list), or NIL if there are no usable - * conditions. + * equality conditions. * * This function is just concerned with handling AND/OR recursion. */ static List * -TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel) +TidQualFromRestrictInfoList(PlannerInfo *root, List *rlist, RelOptInfo *rel) { List *rlst = NIL; ListCell *l; @@ -257,14 +303,14 @@ TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel) List *andargs = ((BoolExpr *) orarg)->args; /* Recurse in case there are sub-ORs */ - sublist = TidQualFromRestrictInfoList(andargs, rel); + sublist = TidQualFromRestrictInfoList(root, andargs, rel); } else { RestrictInfo *rinfo = castNode(RestrictInfo, orarg); Assert(!restriction_is_or_clause(rinfo)); - sublist = TidQualFromRestrictInfo(rinfo, rel); + sublist = TidQualFromRestrictInfo(root, rinfo, rel); } /* @@ -286,7 +332,7 @@ TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel) else { /* Not an OR clause, so handle base cases */ - rlst = TidQualFromRestrictInfo(rinfo, rel); + rlst = TidQualFromRestrictInfo(root, rinfo, rel); } /* @@ -303,6 +349,34 @@ TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel) return rlst; } +/* + * Extract a set of CTID range conditions from implicit-AND List of RestrictInfos + * + * Returns a List of CTID range qual RestrictInfos for the specified rel + * (with implicit AND semantics across the list), or NIL if there are no + * usable range conditions or if the rel's table AM does not support TID range + * scans. + */ +static List * +TidRangeQualFromRestrictInfoList(List *rlist, RelOptInfo *rel) +{ + List *rlst = NIL; + ListCell *l; + + if ((rel->amflags & AMFLAG_HAS_TID_RANGE) == 0) + return NIL; + + foreach(l, rlist) + { + RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); + + if (IsTidRangeClause(rinfo, rel)) + rlst = lappend(rlst, rinfo); + } + + return rlst; +} + /* * Given a list of join clauses involving our rel, create a parameterized * TidPath for each one that is a suitable TidEqual clause. @@ -387,14 +461,15 @@ void create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel) { List *tidquals; + List *tidrangequals; /* * If any suitable quals exist in the rel's baserestrict list, generate a * plain (unparameterized) TidPath with them. */ - tidquals = TidQualFromRestrictInfoList(rel->baserestrictinfo, rel); + tidquals = TidQualFromRestrictInfoList(root, rel->baserestrictinfo, rel); - if (tidquals) + if (tidquals != NIL) { /* * This path uses no join clauses, but it could still have required @@ -406,6 +481,26 @@ create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel) required_outer)); } + /* + * If there are range quals in the baserestrict list, generate a + * TidRangePath. + */ + tidrangequals = TidRangeQualFromRestrictInfoList(rel->baserestrictinfo, + rel); + + if (tidrangequals != NIL) + { + /* + * This path uses no join clauses, but it could still have required + * parameterization due to LATERAL refs in its tlist. + */ + Relids required_outer = rel->lateral_relids; + + add_path(rel, (Path *) create_tidrangescan_path(root, rel, + tidrangequals, + required_outer)); + } + /* * Try to generate parameterized TidPaths using equality clauses extracted * from EquivalenceClasses. (This is important since simple "t1.ctid = diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index 0a6ec9e66f67..9151ab4ba2e2 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -11,7 +11,7 @@ * is that we have to work harder to clean up after ourselves when we modify * the query, since the derived data structures have to be updated too. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -231,7 +231,7 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo) continue; /* it definitely doesn't reference innerrel */ if (bms_is_subset(phinfo->ph_eval_at, innerrel->relids)) return false; /* there isn't any other place to eval PHV */ - if (bms_overlap(pull_varnos((Node *) phinfo->ph_var->phexpr), + if (bms_overlap(pull_varnos(root, (Node *) phinfo->ph_var->phexpr), innerrel->relids)) return false; /* it does reference innerrel */ } @@ -371,7 +371,7 @@ remove_rel_from_query(PlannerInfo *root, int relid, Relids joinrelids) * Likewise remove references from PlaceHolderVar data structures, * removing any no-longer-needed placeholders entirely. * - * Removal is a bit tricker than it might seem: we can remove PHVs that + * Removal is a bit trickier than it might seem: we can remove PHVs that * are used at the target rel and/or in the join qual, but not those that * are used at join partner rels or above the join. It's not that easy to * distinguish PHVs used at partner rels from those used in the join qual, diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 5196148cf3af..c8a479fb4397 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -7,7 +7,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -39,6 +39,7 @@ #include "optimizer/placeholder.h" #include "optimizer/plancat.h" #include "optimizer/planmain.h" +#include "optimizer/prep.h" #include "optimizer/restrictinfo.h" #include "optimizer/subselect.h" #include "optimizer/tlist.h" @@ -108,6 +109,7 @@ static List *get_gating_quals(PlannerInfo *root, List *quals); static Plan *create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, List *gating_quals); static Plan *create_join_plan(PlannerInfo *root, JoinPath *best_path); +static bool is_async_capable_path(Path *path); static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags); static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, @@ -117,9 +119,12 @@ static Result *create_group_result_plan(PlannerInfo *root, static ProjectSet *create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path); static Material *create_material_plan(PlannerInfo *root, MaterialPath *best_path, int flags); +static ResultCache *create_resultcache_plan(PlannerInfo *root, + ResultCachePath *best_path, + int flags); static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags); -static Plan *create_motion_plan(PlannerInfo *root, CdbMotionPath *path); +static Plan *create_motion_plan(PlannerInfo *root, CdbMotionPath *path, int flags); static Plan *create_splitupdate_plan(PlannerInfo *root, SplitUpdatePath *path); static Gather *create_gather_plan(PlannerInfo *root, GatherPath *best_path); static Plan *create_projection_plan(PlannerInfo *root, @@ -160,6 +165,10 @@ static Plan *create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, List **qual, List **indexqual, List **indexECs); static TidScan *create_tidscan_plan(PlannerInfo *root, TidPath *best_path, List *tlist, List *scan_clauses); +static TidRangeScan *create_tidrangescan_plan(PlannerInfo *root, + TidRangePath *best_path, + List *tlist, + List *scan_clauses); static SubqueryScan *create_subqueryscan_plan(PlannerInfo *root, SubqueryScanPath *best_path, List *tlist, List *scan_clauses); @@ -229,6 +238,8 @@ static BitmapHeapScan *make_bitmap_heapscan(List *qptlist, Index scanrelid); static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid, List *tidquals); +static TidRangeScan *make_tidrangescan(List *qptlist, List *qpqual, + Index scanrelid, List *tidrangequals); static SubqueryScan *make_subqueryscan(List *qptlist, List *qpqual, Index scanrelid, @@ -300,11 +311,19 @@ static Plan *prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec, TargetEntry *tle, Relids relids); +static Sort *make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, + Relids relids); static IncrementalSort *make_incrementalsort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids, int nPresortedCols); static Sort *make_sort_from_groupcols(List *groupcls, AttrNumber *grpColIdx, Plan *lefttree); +/* make_material declared in planmain.h */ +static ResultCache *make_resultcache(Plan *lefttree, Oid *hashoperators, + Oid *collations, + List *param_exprs, + bool singlerow, + uint32 est_entries); static WindowAgg *make_windowagg(List *tlist, Index winref, int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations, int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations, @@ -323,11 +342,12 @@ static SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, long numGroups); static LockRows *make_lockrows(Plan *lefttree, List *rowMarks, int epqParam); static ProjectSet *make_project_set(List *tlist, Plan *subplan); -static ModifyTable *make_modifytable(PlannerInfo *root, +static ModifyTable *make_modifytable(PlannerInfo *root, Plan *subplan, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, bool partColsUpdated, - List *resultRelations, List *subplans, List *subroots, + List *resultRelations, + List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *is_split_updates, List *rowMarks, OnConflictExpr *onconflict, int epqParam); @@ -441,6 +461,7 @@ create_plan_recurse(PlannerInfo *root, Path *best_path, int flags) case T_IndexOnlyScan: case T_BitmapHeapScan: case T_TidScan: + case T_TidRangeScan: case T_SubqueryScan: case T_FunctionScan: case T_TableFunctionScan: @@ -502,6 +523,11 @@ create_plan_recurse(PlannerInfo *root, Path *best_path, int flags) (MaterialPath *) best_path, flags); break; + case T_ResultCache: + plan = (Plan *) create_resultcache_plan(root, + (ResultCachePath *) best_path, + flags); + break; case T_Unique: if (IsA(best_path, UpperUniquePath)) { @@ -584,7 +610,7 @@ create_plan_recurse(PlannerInfo *root, Path *best_path, int flags) (GatherMergePath *) best_path); break; case T_Motion: - plan = create_motion_plan(root, (CdbMotionPath *) best_path); + plan = create_motion_plan(root, (CdbMotionPath *) best_path, flags); break; case T_PartitionSelector: plan = create_partition_selector_plan(root, (PartitionSelectorPath *) best_path); @@ -752,6 +778,13 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags) scan_clauses); break; + case T_TidRangeScan: + plan = (Plan *) create_tidrangescan_plan(root, + (TidRangePath *) best_path, + tlist, + scan_clauses); + break; + case T_SubqueryScan: plan = (Plan *) create_subqueryscan_plan(root, (SubqueryScanPath *) best_path, @@ -1188,6 +1221,31 @@ create_join_plan(PlannerInfo *root, JoinPath *best_path) return plan; } +/* + * is_async_capable_path + * Check whether a given Path node is async-capable. + */ +static bool +is_async_capable_path(Path *path) +{ + switch (nodeTag(path)) + { + case T_ForeignPath: + { + FdwRoutine *fdwroutine = path->parent->fdwroutine; + + Assert(fdwroutine != NULL); + if (fdwroutine->IsForeignPathAsyncCapable != NULL && + fdwroutine->IsForeignPathAsyncCapable((ForeignPath *) path)) + return true; + } + break; + default: + break; + } + return false; +} + /* * create_append_plan * Create an Append plan for 'best_path' and (recursively) plans @@ -1205,6 +1263,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) List *pathkeys = best_path->path.pathkeys; List *subplans = NIL; ListCell *subpaths; + int nasyncplans = 0; RelOptInfo *rel = best_path->path.parent; PartitionPruneInfo *partpruneinfo = NULL; int nodenumsortkeys = 0; @@ -1212,6 +1271,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) Oid *nodeSortOperators = NULL; Oid *nodeCollations = NULL; bool *nodeNullsFirst = NULL; + bool consider_async = false; /* * The subpaths list could be empty, if every child was proven empty by @@ -1275,6 +1335,11 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) tlist_was_changed = (orig_tlist_length != list_length(plan->plan.targetlist)); } + /* If appropriate, consider async append */ + consider_async = (enable_async_append && pathkeys == NIL && + !best_path->path.parallel_safe && + list_length(best_path->subpaths) > 1); + /* Build the plan for each child */ foreach(subpaths, best_path->subpaths) { @@ -1342,6 +1407,13 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) } subplans = lappend(subplans, subplan); + + /* Check to see if subplan can be executed asynchronously */ + if (consider_async && is_async_capable_path(subpath)) + { + subplan->async_capable = true; + ++nasyncplans; + } } /* @@ -1349,9 +1421,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) * pruning during execution. Gather information needed by the executor to * do partition pruning. */ - if (enable_partition_pruning && - rel->reloptkind == RELOPT_BASEREL && - best_path->partitioned_rels != NIL) + if (enable_partition_pruning) { List *prunequal; @@ -1372,7 +1442,6 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) partpruneinfo = make_partition_pruneinfo(root, rel, best_path->subpaths, - best_path->partitioned_rels, prunequal); /* @@ -1384,12 +1453,12 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) if (!best_path->path.param_info) { plan->join_prune_paramids = make_partition_join_pruneinfos(root, rel, - best_path->subpaths, - best_path->partitioned_rels); + best_path->subpaths); } } plan->appendplans = subplans; + plan->nasyncplans = nasyncplans; plan->first_partial_plan = best_path->first_partial_path; plan->part_prune_info = partpruneinfo; @@ -1529,9 +1598,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, * pruning during execution. Gather information needed by the executor to * do partition pruning. */ - if (enable_partition_pruning && - rel->reloptkind == RELOPT_BASEREL && - best_path->partitioned_rels != NIL) + if (enable_partition_pruning) { List *prunequal; @@ -1551,7 +1618,6 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, if (prunequal != NIL) partpruneinfo = make_partition_pruneinfo(root, rel, best_path->subpaths, - best_path->partitioned_rels, prunequal); /* @@ -1563,8 +1629,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, if (!best_path->path.param_info) { node->join_prune_paramids = make_partition_join_pruneinfos(root, rel, - best_path->subpaths, - best_path->partitioned_rels); + best_path->subpaths); } } @@ -1667,6 +1732,56 @@ create_material_plan(PlannerInfo *root, MaterialPath *best_path, int flags) return plan; } +/* + * create_resultcache_plan + * Create a ResultCache plan for 'best_path' and (recursively) plans + * for its subpaths. + * + * Returns a Plan node. + */ +static ResultCache * +create_resultcache_plan(PlannerInfo *root, ResultCachePath *best_path, int flags) +{ + ResultCache *plan; + Plan *subplan; + Oid *operators; + Oid *collations; + List *param_exprs = NIL; + ListCell *lc; + ListCell *lc2; + int nkeys; + int i; + + subplan = create_plan_recurse(root, best_path->subpath, + flags | CP_SMALL_TLIST); + + param_exprs = (List *) replace_nestloop_params(root, (Node *) + best_path->param_exprs); + + nkeys = list_length(param_exprs); + Assert(nkeys > 0); + operators = palloc(nkeys * sizeof(Oid)); + collations = palloc(nkeys * sizeof(Oid)); + + i = 0; + forboth(lc, param_exprs, lc2, best_path->hash_operators) + { + Expr *param_expr = (Expr *) lfirst(lc); + Oid opno = lfirst_oid(lc2); + + operators[i] = opno; + collations[i] = exprCollation((Node *) param_expr); + i++; + } + + plan = make_resultcache(subplan, operators, collations, param_exprs, + best_path->singlerow, best_path->est_entries); + + copy_generic_path_info(&plan->plan, (Path *) best_path); + + return plan; +} + /* * create_unique_plan * Create a Unique plan for 'best_path' and (recursively) plans @@ -1969,13 +2084,15 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path) &gm_plan->nullsFirst); - /* Now, insert a Sort node if subplan isn't sufficiently ordered */ + /* + * All gather merge paths should have already guaranteed the necessary + * sort order either by adding an explicit sort node or by using presorted + * input. We can't simply add a sort here on additional pathkeys, because + * we can't guarantee the sort would be safe. For example, expressions may + * be volatile or otherwise parallel unsafe. + */ if (!pathkeys_contained_in(pathkeys, best_path->subpath->pathkeys)) - subplan = (Plan *) make_sort(subplan, gm_plan->numCols, - gm_plan->sortColIdx, - gm_plan->sortOperators, - gm_plan->collations, - gm_plan->nullsFirst); + elog(ERROR, "gather merge input not sufficiently sorted"); /* Now insert the subplan under GatherMerge. */ gm_plan->plan.lefttree = subplan; @@ -2063,6 +2180,7 @@ create_projection_plan(PlannerInfo *root, ProjectionPath *best_path, int flags) */ subplan = create_plan_recurse(root, best_path->subpath, CP_IGNORE_TLIST); + Assert(is_projection_capable_plan(subplan)); tlist = build_path_tlist(root, &best_path->path); } else @@ -2245,7 +2363,7 @@ create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags) flags | CP_SMALL_TLIST); /* - * make_sort_from_pathkeys() indirectly calls find_ec_member_for_tle(), + * make_sort_from_pathkeys indirectly calls find_ec_member_matching_expr, * which will ignore any child EC members that don't belong to the given * relids. Thus, if this sort path is based on a child relation, we must * pass its relids. @@ -2538,12 +2656,7 @@ create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path) /* * During setrefs.c, we'll need the grouping_map to fix up the cols lists * in GroupingFunc nodes. Save it for setrefs.c to use. - * - * This doesn't work if we're in an inheritance subtree (see notes in - * create_modifytable_plan). Fortunately we can't be because there would - * never be grouping in an UPDATE/DELETE; but let's Assert that. */ - Assert(root->inhTargetKind == INHKIND_NONE); Assert(root->grouping_map == NULL); root->grouping_map = grouping_map; root->grouping_map_size = maxref + 1; @@ -2559,7 +2672,7 @@ create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path) { bool is_first_sort = ((RollupData *) linitial(rollups))->is_hashed; - for_each_cell(lc, rollups, list_second_cell(rollups)) + for_each_from(lc, rollups, 1) { RollupData *rollup = lfirst(lc); AttrNumber *new_grpColIdx; @@ -2714,12 +2827,7 @@ create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path) * with InitPlan output params. (We can't just do that locally in the * MinMaxAgg node, because path nodes above here may have Agg references * as well.) Save the mmaggregates list to tell setrefs.c to do that. - * - * This doesn't work if we're in an inheritance subtree (see notes in - * create_modifytable_plan). Fortunately we can't be because there would - * never be aggregates in an UPDATE/DELETE; but let's Assert that. */ - Assert(root->inhTargetKind == INHKIND_NONE); Assert(root->minmax_aggs == NIL); root->minmax_aggs = best_path->mmaggregates; @@ -2963,68 +3071,24 @@ static ModifyTable * create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path) { ModifyTable *plan; - List *subplans = NIL; - ListCell *subpaths, - *subroots; - ListCell *is_split_updates; - - /* Build the plan for each input path */ - forthree(subpaths, best_path->subpaths, - subroots, best_path->subroots, - is_split_updates, best_path->is_split_updates) - { - Path *subpath = (Path *) lfirst(subpaths); - PlannerInfo *subroot = (PlannerInfo *) lfirst(subroots); - bool is_split_update = (bool) lfirst_int(is_split_updates); - Plan *subplan; - RangeTblEntry *rte = planner_rt_fetch(best_path->nominalRelation, root); - PlanSlice *save_curSlice = subroot->curSlice; - - subroot->curSlice = root->curSlice; - - /* Try the Single-Row-Insert optimization first. */ - subplan = cdbpathtoplan_create_sri_plan(rte, subroot, subpath, CP_EXACT_TLIST); - - /* - * In an inherited UPDATE/DELETE, reference the per-child modified - * subroot while creating Plans from Paths for the child rel. This is - * a kluge, but otherwise it's too hard to ensure that Plan creation - * functions (particularly in FDWs) don't depend on the contents of - * "root" matching what they saw at Path creation time. The main - * downside is that creation functions for Plans that might appear - * below a ModifyTable cannot expect to modify the contents of "root" - * and have it "stick" for subsequent processing such as setrefs.c. - * That's not great, but it seems better than the alternative. - */ - if (!subplan) - { - subplan = create_plan_recurse(subroot, subpath, CP_EXACT_TLIST); - - /* - * Transfer resname/resjunk labeling, too, to keep executor happy. - * But not if it's a Split Update. A Split Update contains an extra - * DMLActionExpr column in its target list, so it doesn't match - * subroot->processed_tlist. The code to create the Split Update node - * takes care to label junk columns correctly, instead. - */ - if (!is_split_update) - apply_tlist_labeling(subplan->targetlist, subroot->processed_tlist); - } + Path *subpath = best_path->subpath; + Plan *subplan; - subplans = lappend(subplans, subplan); + /* Subplan must produce exactly the specified tlist */ + subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST); - subroot->curSlice = save_curSlice; - } + /* Transfer resname/resjunk labeling, too, to keep executor happy */ + apply_tlist_labeling(subplan->targetlist, root->processed_tlist); plan = make_modifytable(root, + subplan, best_path->operation, best_path->canSetTag, best_path->nominalRelation, best_path->rootRelation, best_path->partColsUpdated, best_path->resultRelations, - subplans, - best_path->subroots, + best_path->updateColnosLists, best_path->withCheckOptionLists, best_path->returningLists, best_path->is_split_updates, @@ -3140,7 +3204,7 @@ create_limit_plan(PlannerInfo *root, LimitPath *best_path, int flags) * create_motion_plan */ Plan * -create_motion_plan(PlannerInfo *root, CdbMotionPath *path) +create_motion_plan(PlannerInfo *root, CdbMotionPath *path, int flags) { Motion *motion; Path *subpath = path->subpath; @@ -3162,7 +3226,8 @@ create_motion_plan(PlannerInfo *root, CdbMotionPath *path) /* Push the MotionPath's locus down onto subpath. */ subpath->locus = path->path.locus; - subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST); + subplan = create_plan_recurse(root, subpath, + CP_EXACT_TLIST | (flags & CP_LABEL_TLIST)); return subplan; } @@ -3186,7 +3251,8 @@ create_motion_plan(PlannerInfo *root, CdbMotionPath *path) root->curSlice = sendSlice; - subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST); + subplan = create_plan_recurse(root, subpath, + CP_EXACT_TLIST | (flags & CP_LABEL_TLIST)); root->curSlice = save_curSlice; @@ -3323,7 +3389,17 @@ create_splitupdate_plan(PlannerInfo *root, SplitUpdatePath *path) Oid *hashFuncs; int i; - resultRel = relation_open(planner_rt_fetch(path->resultRelation, root)->relid, NoLock); + /* + * GPDB: the subplan's targetlist is labeled with root->processed_tlist + * (below), i.e. it is in the column layout of the *nominal* target + * relation, not of path->resultRelation. For an UPDATE of a partitioned + * table the latter is a leaf partition whose physical column order can + * differ from the parent's, so its descriptor and distribution policy do + * not match the tuples flowing through the SplitUpdate. Use the nominal + * target relation (parse->resultRelation) so that resultDesc/cdbpolicy -- + * and hence insertColIdx and hashAttnos -- line up with the subplan tuples. + */ + resultRel = relation_open(planner_rt_fetch(root->parse->resultRelation, root)->relid, NoLock); resultDesc = RelationGetDescr(resultRel); cdbpolicy = resultRel->rd_cdbpolicy; @@ -4172,6 +4248,71 @@ create_tidscan_plan(PlannerInfo *root, TidPath *best_path, return scan_plan; } +/* + * create_tidrangescan_plan + * Returns a tidrangescan plan for the base relation scanned by 'best_path' + * with restriction clauses 'scan_clauses' and targetlist 'tlist'. + */ +static TidRangeScan * +create_tidrangescan_plan(PlannerInfo *root, TidRangePath *best_path, + List *tlist, List *scan_clauses) +{ + TidRangeScan *scan_plan; + Index scan_relid = best_path->path.parent->relid; + List *tidrangequals = best_path->tidrangequals; + + /* it should be a base rel... */ + Assert(scan_relid > 0); + Assert(best_path->path.parent->rtekind == RTE_RELATION); + + /* + * The qpqual list must contain all restrictions not enforced by the + * tidrangequals list. tidrangequals has AND semantics, so we can simply + * remove any qual that appears in it. + */ + { + List *qpqual = NIL; + ListCell *l; + + foreach(l, scan_clauses) + { + RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); + + if (rinfo->pseudoconstant) + continue; /* we may drop pseudoconstants here */ + if (list_member_ptr(tidrangequals, rinfo)) + continue; /* simple duplicate */ + qpqual = lappend(qpqual, rinfo); + } + scan_clauses = qpqual; + } + + /* Sort clauses into best execution order */ + scan_clauses = order_qual_clauses(root, scan_clauses); + + /* Reduce RestrictInfo lists to bare expressions; ignore pseudoconstants */ + tidrangequals = extract_actual_clauses(tidrangequals, false); + scan_clauses = extract_actual_clauses(scan_clauses, false); + + /* Replace any outer-relation variables with nestloop params */ + if (best_path->path.param_info) + { + tidrangequals = (List *) + replace_nestloop_params(root, (Node *) tidrangequals); + scan_clauses = (List *) + replace_nestloop_params(root, (Node *) scan_clauses); + } + + scan_plan = make_tidrangescan(tlist, + scan_clauses, + scan_relid, + tidrangequals); + + copy_generic_path_info(&scan_plan->scan.plan, &best_path->path); + + return scan_plan; +} + /* * create_subqueryscan_plan * Returns a subqueryscan plan for the base relation scanned by 'best_path' @@ -5011,7 +5152,6 @@ create_nestloop_plan(PlannerInfo *root, /* Set cost data */ cost_material(&matpath, - root, inner_plan->startup_cost, inner_plan->total_cost, inner_plan->plan_rows, @@ -6520,7 +6660,26 @@ make_tidscan(List *qptlist, return node; } -SubqueryScan * +static TidRangeScan * +make_tidrangescan(List *qptlist, + List *qpqual, + Index scanrelid, + List *tidrangequals) +{ + TidRangeScan *node = makeNode(TidRangeScan); + Plan *plan = &node->scan.plan; + + plan->targetlist = qptlist; + plan->qual = qpqual; + plan->lefttree = NULL; + plan->righttree = NULL; + node->scan.scanrelid = scanrelid; + node->tidrangequals = tidrangequals; + + return node; +} + +static SubqueryScan * make_subqueryscan(List *qptlist, List *qpqual, Index scanrelid, @@ -6711,7 +6870,11 @@ make_foreignscan(List *qptlist, plan->lefttree = outer_plan; plan->righttree = NULL; node->scan.scanrelid = scanrelid; + + /* these may be overridden by the FDW's PlanDirectModify callback. */ node->operation = CMD_SELECT; + node->resultRelation = 0; + /* fs_server will be filled in by create_foreignscan_plan */ node->fs_server = InvalidOid; node->fdw_exprs = fdw_exprs; @@ -7127,7 +7290,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, tle = get_tle_by_resno(tlist, reqColIdx[numsortkeys]); if (tle) { - em = find_ec_member_for_tle(ec, tle, relids); + em = find_ec_member_matching_expr(ec, tle->expr, relids); if (em) { /* found expr at right place in tlist */ @@ -7158,7 +7321,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, foreach(j, tlist) { tle = (TargetEntry *) lfirst(j); - em = find_ec_member_for_tle(ec, tle, relids); + em = find_ec_member_matching_expr(ec, tle->expr, relids); if (em) { /* found expr already in tlist */ @@ -7172,56 +7335,12 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, if (!tle) { /* - * No matching tlist item; look for a computable expression. Note - * that we treat Aggrefs as if they were variables; this is - * necessary when attempting to sort the output from an Agg node - * for use in a WindowFunc (since grouping_planner will have - * treated the Aggrefs as variables, too). Likewise, if we find a - * WindowFunc in a sort expression, treat it as a variable. + * No matching tlist item; look for a computable expression. */ - Expr *sortexpr = NULL; - - foreach(j, ec->ec_members) - { - EquivalenceMember *em = (EquivalenceMember *) lfirst(j); - List *exprvars; - ListCell *k; - - /* - * We shouldn't be trying to sort by an equivalence class that - * contains a constant, so no need to consider such cases any - * further. - */ - if (em->em_is_const) - continue; - - /* - * Ignore child members unless they belong to the rel being - * sorted. - */ - if (em->em_is_child && - !bms_is_subset(em->em_relids, relids)) - continue; - - sortexpr = em->em_expr; - exprvars = pull_var_clause((Node *) sortexpr, - PVC_INCLUDE_AGGREGATES | - PVC_INCLUDE_WINDOWFUNCS | - PVC_INCLUDE_PLACEHOLDERS); - foreach(k, exprvars) - { - if (!tlist_member_ignore_relabel(lfirst(k), tlist)) - break; - } - list_free(exprvars); - if (!k) - { - pk_datatype = em->em_datatype; - break; /* found usable expression */ - } - } - if (!j) + em = find_computable_ec_member(NULL, ec, tlist, relids, false); + if (!em) elog(ERROR, "could not find pathkey item to sort"); + pk_datatype = em->em_datatype; /* * Do we need to insert a Result node? @@ -7241,7 +7360,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, /* * Add resjunk entry to input's tlist */ - tle = makeTargetEntry(sortexpr, + tle = makeTargetEntry(copyObject(em->em_expr), list_length(tlist) + 1, NULL, true); @@ -7280,56 +7399,6 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, return lefttree; } -/* - * find_ec_member_for_tle - * Locate an EquivalenceClass member matching the given TLE, if any - * - * Child EC members are ignored unless they belong to given 'relids'. - */ -static EquivalenceMember * -find_ec_member_for_tle(EquivalenceClass *ec, - TargetEntry *tle, - Relids relids) -{ - Expr *tlexpr; - ListCell *lc; - - /* We ignore binary-compatible relabeling on both ends */ - tlexpr = tle->expr; - while (tlexpr && IsA(tlexpr, RelabelType)) - tlexpr = ((RelabelType *) tlexpr)->arg; - - foreach(lc, ec->ec_members) - { - EquivalenceMember *em = (EquivalenceMember *) lfirst(lc); - Expr *emexpr; - - /* - * We shouldn't be trying to sort by an equivalence class that - * contains a constant, so no need to consider such cases any further. - */ - if (em->em_is_const) - continue; - - /* - * Ignore child members unless they belong to the rel being sorted. - */ - if (em->em_is_child && - !bms_is_subset(em->em_relids, relids)) - continue; - - /* Match if same expression (after stripping relabel) */ - emexpr = em->em_expr; - while (emexpr && IsA(emexpr, RelabelType)) - emexpr = ((RelabelType *) emexpr)->arg; - - if (equal(emexpr, tlexpr)) - return em; - } - - return NULL; -} - /* * make_sort_from_pathkeys * Create sort plan to sort according to given pathkeys @@ -7616,7 +7685,6 @@ materialize_finished_plan(PlannerInfo *root, Plan *subplan) /* Set cost data */ cost_material(&matpath, - root, subplan->startup_cost, subplan->total_cost, subplan->plan_rows, @@ -7637,6 +7705,28 @@ materialize_finished_plan(PlannerInfo *root, Plan *subplan) return matplan; } +static ResultCache * +make_resultcache(Plan *lefttree, Oid *hashoperators, Oid *collations, + List *param_exprs, bool singlerow, uint32 est_entries) +{ + ResultCache *node = makeNode(ResultCache); + Plan *plan = &node->plan; + + plan->targetlist = lefttree->targetlist; + plan->qual = NIL; + plan->lefttree = lefttree; + plan->righttree = NULL; + + node->numKeys = list_length(param_exprs); + node->hashOperators = hashoperators; + node->collations = collations; + node->param_exprs = param_exprs; + node->singlerow = singlerow; + node->est_entries = est_entries; + + return node; +} + Agg * make_agg(List *tlist, List *qual, AggStrategy aggstrategy, AggSplit aggsplit, @@ -7853,7 +7943,7 @@ make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols) foreach(j, plan->targetlist) { tle = (TargetEntry *) lfirst(j); - em = find_ec_member_for_tle(ec, tle, NULL); + em = find_ec_member_matching_expr(ec, tle->expr, NULL); if (em) { /* found expr already in tlist */ @@ -8074,11 +8164,12 @@ make_project_set(List *tlist, * Build a ModifyTable plan node */ static ModifyTable * -make_modifytable(PlannerInfo *root, +make_modifytable(PlannerInfo *root, Plan *subplan, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, bool partColsUpdated, - List *resultRelations, List *subplans, List *subroots, + List *resultRelations, + List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *is_split_updates, List *rowMarks, OnConflictExpr *onconflict, int epqParam) @@ -8087,18 +8178,18 @@ make_modifytable(PlannerInfo *root, List *fdw_private_list; Bitmapset *direct_modify_plans; ListCell *lc; - ListCell *lc2; int i; - Assert(list_length(resultRelations) == list_length(subplans)); - Assert(list_length(resultRelations) == list_length(subroots)); + Assert(operation == CMD_UPDATE ? + list_length(resultRelations) == list_length(updateColnosLists) : + updateColnosLists == NIL); Assert(withCheckOptionLists == NIL || list_length(resultRelations) == list_length(withCheckOptionLists)); Assert(returningLists == NIL || list_length(resultRelations) == list_length(returningLists)); Assert(list_length(resultRelations) == list_length(is_split_updates)); - node->plan.lefttree = NULL; + node->plan.lefttree = subplan; node->plan.righttree = NULL; node->plan.qual = NIL; /* setrefs.c will fill in the targetlist, if needed */ @@ -8110,13 +8201,11 @@ make_modifytable(PlannerInfo *root, node->rootRelation = rootRelation; node->partColsUpdated = partColsUpdated; node->resultRelations = resultRelations; - node->resultRelIndex = -1; /* will be set correctly in setrefs.c */ - node->rootResultRelIndex = -1; /* will be set correctly in setrefs.c */ - node->plans = subplans; if (!onconflict) { node->onConflictAction = ONCONFLICT_NONE; node->onConflictSet = NIL; + node->onConflictCols = NIL; node->onConflictWhere = NULL; node->arbiterIndexes = NIL; node->exclRelRTI = 0; @@ -8125,7 +8214,16 @@ make_modifytable(PlannerInfo *root, else { node->onConflictAction = onconflict->action; + + /* + * Here we convert the ON CONFLICT UPDATE tlist, if any, to the + * executor's convention of having consecutive resno's. The actual + * target column numbers are saved in node->onConflictCols. (This + * could be done earlier, but there seems no need to.) + */ node->onConflictSet = onconflict->onConflictSet; + node->onConflictCols = + extract_update_targetlist_colnos(node->onConflictSet, true); node->onConflictWhere = onconflict->onConflictWhere; /* @@ -8139,6 +8237,7 @@ make_modifytable(PlannerInfo *root, node->exclRelRTI = onconflict->exclRelIndex; node->exclRelTlist = onconflict->exclRelTlist; } + node->updateColnosLists = updateColnosLists; node->withCheckOptionLists = withCheckOptionLists; node->returningLists = returningLists; node->rowMarks = rowMarks; @@ -8154,10 +8253,9 @@ make_modifytable(PlannerInfo *root, fdw_private_list = NIL; direct_modify_plans = NULL; i = 0; - forboth(lc, resultRelations, lc2, subroots) + foreach(lc, resultRelations) { Index rti = lfirst_int(lc); - PlannerInfo *subroot = lfirst_node(PlannerInfo, lc2); FdwRoutine *fdwroutine; List *fdw_private; bool direct_modify; @@ -8169,16 +8267,16 @@ make_modifytable(PlannerInfo *root, * so it's not a baserel; and there are also corner cases for * updatable views where the target rel isn't a baserel.) */ - if (rti < subroot->simple_rel_array_size && - subroot->simple_rel_array[rti] != NULL) + if (rti < root->simple_rel_array_size && + root->simple_rel_array[rti] != NULL) { - RelOptInfo *resultRel = subroot->simple_rel_array[rti]; + RelOptInfo *resultRel = root->simple_rel_array[rti]; fdwroutine = resultRel->fdwroutine; } else { - RangeTblEntry *rte = planner_rt_fetch(rti, subroot); + RangeTblEntry *rte = planner_rt_fetch(rti, root); Assert(rte->rtekind == RTE_RELATION); if (rte->relkind == RELKIND_FOREIGN_TABLE) @@ -8201,16 +8299,16 @@ make_modifytable(PlannerInfo *root, fdwroutine->IterateDirectModify != NULL && fdwroutine->EndDirectModify != NULL && withCheckOptionLists == NIL && - !has_row_triggers(subroot, rti, operation) && - !has_stored_generated_columns(subroot, rti)) - direct_modify = fdwroutine->PlanDirectModify(subroot, node, rti, i); + !has_row_triggers(root, rti, operation) && + !has_stored_generated_columns(root, rti)) + direct_modify = fdwroutine->PlanDirectModify(root, node, rti, i); if (direct_modify) direct_modify_plans = bms_add_member(direct_modify_plans, i); if (!direct_modify && fdwroutine != NULL && fdwroutine->PlanForeignModify != NULL) - fdw_private = fdwroutine->PlanForeignModify(subroot, node, rti, i); + fdw_private = fdwroutine->PlanForeignModify(root, node, rti, i); else fdw_private = NIL; fdw_private_list = lappend(fdw_private_list, fdw_private); @@ -8234,6 +8332,7 @@ is_projection_capable_path(Path *path) { case T_Hash: case T_Material: + case T_ResultCache: case T_Sort: case T_IncrementalSort: case T_Unique: @@ -8282,6 +8381,7 @@ is_projection_capable_plan(Plan *plan) { case T_Hash: case T_Material: + case T_ResultCache: case T_Sort: case T_Unique: case T_SetOp: diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 58319a91b4ba..b4db3e2785c8 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,6 +35,7 @@ #include "parser/analyze.h" #include "rewrite/rewriteManip.h" #include "utils/lsyscache.h" +#include "utils/typcache.h" #include "access/heapam.h" #include "cdb/cdbmutate.h" @@ -67,22 +68,24 @@ static SpecialJoinInfo *make_outerjoininfo(PlannerInfo *root, Relids left_rels, Relids right_rels, Relids inner_join_rels, JoinType jointype, List *clause); -static void compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause); +static void compute_semijoin_info(PlannerInfo *root, SpecialJoinInfo *sjinfo, + List *clause); static void distribute_qual_to_rels(PlannerInfo *root, Node *clause, - bool is_deduced, bool below_outer_join, JoinType jointype, Index security_level, Relids qualscope, Relids ojscope, Relids outerjoin_nonnullable, - Relids deduced_nullable_relids, List **postponed_qual_list); static bool check_outerjoin_delay(PlannerInfo *root, Relids *relids_p, Relids *nullable_relids_p, bool is_pushed_down); static bool check_equivalence_delay(PlannerInfo *root, RestrictInfo *restrictinfo); static bool check_redundant_nullability_qual(PlannerInfo *root, Node *clause); +void check_mergejoinable(RestrictInfo *restrictinfo); +void check_hashjoinable(RestrictInfo *restrictinfo); +static void check_resultcacheable(RestrictInfo *restrictinfo); /***************************************************************************** @@ -846,9 +849,9 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, if (bms_is_subset(pq->relids, *qualscope)) distribute_qual_to_rels(root, pq->qual, - false, below_outer_join, JOIN_INNER, + below_outer_join, JOIN_INNER, root->qual_security_level, - *qualscope, NULL, NULL, NULL, + *qualscope, NULL, NULL, NULL); else *postponed_qual_list = lappend(*postponed_qual_list, pq); @@ -862,9 +865,9 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, Node *qual = (Node *) lfirst(l); distribute_qual_to_rels(root, qual, - false, below_outer_join, JOIN_INNER, + below_outer_join, JOIN_INNER, root->qual_security_level, - *qualscope, NULL, NULL, NULL, + *qualscope, NULL, NULL, postponed_qual_list); } } @@ -1054,10 +1057,10 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, Node *qual = (Node *) lfirst(l); distribute_qual_to_rels(root, qual, - false, below_outer_join, j->jointype, + below_outer_join, j->jointype, root->qual_security_level, *qualscope, - ojscope, nonnullable_rels, NULL, + ojscope, nonnullable_rels, postponed_qual_list); } @@ -1156,14 +1159,12 @@ process_security_barrier_quals(PlannerInfo *root, * than being pushed up to top of tree, which we don't want. */ distribute_qual_to_rels(root, qual, - false, below_outer_join, JOIN_INNER, security_level, qualscope, qualscope, NULL, - NULL, NULL); } security_level++; @@ -1247,7 +1248,7 @@ make_outerjoininfo(PlannerInfo *root, /* this always starts out false */ sjinfo->delay_upper_joins = false; - compute_semijoin_info(sjinfo, clause); + compute_semijoin_info(root, sjinfo, clause); /* If it's a full join, no need to be very smart */ if (jointype == JOIN_FULL) @@ -1261,7 +1262,7 @@ make_outerjoininfo(PlannerInfo *root, /* * Retrieve all relids mentioned within the join clause. */ - clause_relids = pull_varnos((Node *) clause); + clause_relids = pull_varnos(root, (Node *) clause); /* * For which relids is the clause strict, ie, it cannot succeed if the @@ -1444,7 +1445,7 @@ make_outerjoininfo(PlannerInfo *root, * SpecialJoinInfo; the rest may not be set yet. */ static void -compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause) +compute_semijoin_info(PlannerInfo *root, SpecialJoinInfo *sjinfo, List *clause) { List *semi_operators; List *semi_rhs_exprs; @@ -1508,7 +1509,7 @@ compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause) list_length(op->args) != 2) { /* No, but does it reference both sides? */ - all_varnos = pull_varnos((Node *) op); + all_varnos = pull_varnos(root, (Node *) op); if (!bms_overlap(all_varnos, sjinfo->syn_righthand) || bms_is_subset(all_varnos, sjinfo->syn_righthand)) { @@ -1529,8 +1530,8 @@ compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause) opno = op->opno; left_expr = linitial(op->args); right_expr = lsecond(op->args); - left_varnos = pull_varnos(left_expr); - right_varnos = pull_varnos(right_expr); + left_varnos = pull_varnos(root, left_expr); + right_varnos = pull_varnos(root, right_expr); all_varnos = bms_union(left_varnos, right_varnos); opinputtype = exprType(left_expr); @@ -1631,7 +1632,6 @@ compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause) * as belonging to a higher join level, just add it to postponed_qual_list. * * 'clause': the qual clause to be distributed - * 'is_deduced': true if the qual came from implied-equality deduction * 'below_outer_join': true if the qual is from a JOIN/ON that is below the * nullable side of a higher-level outer join * 'jointype': type of join the qual is from (JOIN_INNER for a WHERE clause) @@ -1643,8 +1643,6 @@ compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause) * baserels appearing on the outer (nonnullable) side of the join * (for FULL JOIN this includes both sides of the join, and must in fact * equal qualscope) - * 'deduced_nullable_relids': if is_deduced is true, the nullable relids to - * impute to the clause; otherwise NULL * 'postponed_qual_list': list of PostponedQual structs, which we can add * this qual to if it turns out to belong to a higher join level. * Can be NULL if caller knows postponement is impossible. @@ -1653,23 +1651,17 @@ compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause) * 'ojscope' is needed if we decide to force the qual up to the outer-join * level, which will be ojscope not necessarily qualscope. * - * In normal use (when is_deduced is false), at the time this is called, - * root->join_info_list must contain entries for all and only those special - * joins that are syntactically below this qual. But when is_deduced is true, - * we are adding new deduced clauses after completion of deconstruct_jointree, - * so it cannot be assumed that root->join_info_list has anything to do with - * qual placement. + * At the time this is called, root->join_info_list must contain entries for + * all and only those special joins that are syntactically below this qual. */ static void distribute_qual_to_rels(PlannerInfo *root, Node *clause, - bool is_deduced, bool below_outer_join, JoinType jointype, Index security_level, Relids qualscope, Relids ojscope, Relids outerjoin_nonnullable, - Relids deduced_nullable_relids, List **postponed_qual_list) { Relids relids; @@ -1684,7 +1676,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, /* * Retrieve all relids mentioned within the clause. */ - relids = pull_varnos(clause); + relids = pull_varnos(root, clause); /* * In ordinary SQL, a WHERE or JOIN/ON clause can't reference any rels @@ -1703,7 +1695,6 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, Assert(root->hasLateralRTEs); /* shouldn't happen otherwise */ Assert(jointype == JOIN_INNER); /* mustn't postpone past outer join */ - Assert(!is_deduced); /* shouldn't be deduced, either */ pq->qual = clause; pq->relids = relids; *postponed_qual_list = lappend(*postponed_qual_list, pq); @@ -1804,24 +1795,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, * This seems like another reason why it should perhaps be rethought. *---------- */ - if (is_deduced) - { - /* - * If the qual came from implied-equality deduction, it should not be - * outerjoin-delayed, else deducer blew it. But we can't check this - * because the join_info_list may now contain OJs above where the qual - * belongs. For the same reason, we must rely on caller to supply the - * correct nullable_relids set. - */ - Assert(!ojscope); - is_pushed_down = true; - outerjoin_delayed = false; - nullable_relids = deduced_nullable_relids; - /* Don't feed it back for more deductions */ - maybe_equivalence = false; - maybe_outer_join = false; - } - else if (bms_overlap(relids, outerjoin_nonnullable)) + if (bms_overlap(relids, outerjoin_nonnullable)) { /* * The qual is attached to an outer join and mentions (some of the) @@ -1916,7 +1890,8 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, /* * Build the RestrictInfo node itself. */ - restrictinfo = make_restrictinfo((Expr *) clause, + restrictinfo = make_restrictinfo(root, + (Expr *) clause, is_pushed_down, outerjoin_delayed, pseudoconstant, @@ -2351,6 +2326,13 @@ distribute_restrictinfo_to_rels(PlannerInfo *root, */ check_hashjoinable(restrictinfo); + /* + * Likewise, check if the clause is suitable to be used with a + * Result Cache node to cache inner tuples during a parameterized + * nested loop. + */ + check_resultcacheable(restrictinfo); + /* * Add clause to the join lists of all the relevant relations. */ @@ -2391,14 +2373,18 @@ distribute_restrictinfo_to_rels(PlannerInfo *root, * can produce constant TRUE or constant FALSE. (Otherwise it's not, * because the expressions went through eval_const_expressions already.) * + * Returns the generated RestrictInfo, if any. The result will be NULL + * if both_const is true and we successfully reduced the clause to + * constant TRUE. + * * Note: this function will copy item1 and item2, but it is caller's * responsibility to make sure that the Relids parameters are fresh copies * not shared with other uses. * - * This is currently used only when an EquivalenceClass is found to - * contain pseudoconstants. See path/pathkeys.c for more details. + * Note: we do not do initialize_mergeclause_eclasses() here. It is + * caller's responsibility that left_ec/right_ec be set as necessary. */ -void +RestrictInfo * process_implied_equality(PlannerInfo *root, Oid opno, Oid collation, @@ -2410,24 +2396,27 @@ process_implied_equality(PlannerInfo *root, bool below_outer_join, bool both_const) { - Expr *clause; + RestrictInfo *restrictinfo; + Node *clause; + Relids relids; + bool pseudoconstant = false; /* * Build the new clause. Copy to ensure it shares no substructure with * original (this is necessary in case there are subselects in there...) */ - clause = make_opclause(opno, - BOOLOID, /* opresulttype */ - false, /* opretset */ - copyObject(item1), - copyObject(item2), - InvalidOid, - collation); + clause = (Node *) make_opclause(opno, + BOOLOID, /* opresulttype */ + false, /* opretset */ + copyObject(item1), + copyObject(item2), + InvalidOid, + collation); /* If both constant, try to reduce to a boolean constant. */ if (both_const) { - clause = (Expr *) eval_const_expressions(root, (Node *) clause); + clause = eval_const_expressions(root, clause); /* If we produced const TRUE, just drop the clause */ if (clause && IsA(clause, Const)) @@ -2436,25 +2425,107 @@ process_implied_equality(PlannerInfo *root, Assert(cclause->consttype == BOOLOID); if (!cclause->constisnull && DatumGetBool(cclause->constvalue)) - return; + return NULL; } } + /* + * The rest of this is a very cut-down version of distribute_qual_to_rels. + * We can skip most of the work therein, but there are a couple of special + * cases we still have to handle. + * + * Retrieve all relids mentioned within the possibly-simplified clause. + */ + relids = pull_varnos(root, clause); + Assert(bms_is_subset(relids, qualscope)); + + /* + * If the clause is variable-free, our normal heuristic for pushing it + * down to just the mentioned rels doesn't work, because there are none. + * Apply at the given qualscope, or at the top of tree if it's nonvolatile + * (which it very likely is, but we'll check, just to be sure). + */ + if (bms_is_empty(relids)) + { + /* eval at original syntactic level */ + relids = bms_copy(qualscope); + if (!contain_volatile_functions(clause)) + { + /* mark as gating qual */ + pseudoconstant = true; + /* tell createplan.c to check for gating quals */ + root->hasPseudoConstantQuals = true; + /* if not below outer join, push it to top of tree */ + if (!below_outer_join) + { + relids = + get_relids_in_jointree((Node *) root->parse->jointree, + false); + } + } + } + + /* + * Build the RestrictInfo node itself. + */ + restrictinfo = make_restrictinfo(root, + (Expr *) clause, + true, /* is_pushed_down */ + false, /* outerjoin_delayed */ + pseudoconstant, + security_level, + relids, + NULL, /* outer_relids */ + nullable_relids); + + /* + * If it's a join clause, add vars used in the clause to targetlists of + * their relations, so that they will be emitted by the plan nodes that + * scan those relations (else they won't be available at the join node!). + * + * Typically, we'd have already done this when the component expressions + * were first seen by distribute_qual_to_rels; but it is possible that + * some of the Vars could have missed having that done because they only + * appeared in single-relation clauses originally. So do it here for + * safety. + */ + if (bms_membership(relids) == BMS_MULTIPLE) + { + List *vars = pull_var_clause(clause, + PVC_RECURSE_AGGREGATES | + PVC_RECURSE_WINDOWFUNCS | + PVC_INCLUDE_PLACEHOLDERS); + + add_vars_to_targetlist(root, vars, relids, false); + list_free(vars); + } + + /* + * Check mergejoinability. This will usually succeed, since the op came + * from an EquivalenceClass; but we could have reduced the original clause + * to a constant. + */ + check_mergejoinable(restrictinfo); + + /* + * Note we don't do initialize_mergeclause_eclasses(); the caller can + * handle that much more cheaply than we can. It's okay to call + * distribute_restrictinfo_to_rels() before that happens. + */ + /* * Push the new clause into all the appropriate restrictinfo lists. */ - distribute_qual_to_rels(root, (Node *) clause, - true, below_outer_join, JOIN_INNER, - security_level, - qualscope, NULL, NULL, nullable_relids, - NULL); + distribute_restrictinfo_to_rels(root, restrictinfo); + + return restrictinfo; } /* * build_implied_join_equality --- build a RestrictInfo for a derived equality * * This overlaps the functionality of process_implied_equality(), but we - * must return the RestrictInfo, not push it into the joininfo tree. + * must not push the RestrictInfo into the joininfo tree. * * Note: this function will copy item1 and item2, but it is caller's * responsibility to make sure that the Relids parameters are fresh copies @@ -2464,7 +2535,8 @@ process_implied_equality(PlannerInfo *root, * caller's responsibility that left_ec/right_ec be set as necessary. */ RestrictInfo * -build_implied_join_equality(Oid opno, +build_implied_join_equality(PlannerInfo *root, + Oid opno, Oid collation, Expr *item1, Expr *item2, @@ -2490,7 +2562,8 @@ build_implied_join_equality(Oid opno, /* * Build the RestrictInfo node itself. */ - restrictinfo = make_restrictinfo(clause, + restrictinfo = make_restrictinfo(root, + clause, true, /* is_pushed_down */ false, /* outerjoin_delayed */ false, /* pseudoconstant */ @@ -2502,6 +2575,7 @@ build_implied_join_equality(Oid opno, /* Set mergejoinability/hashjoinability flags */ check_mergejoinable(restrictinfo); check_hashjoinable(restrictinfo); + check_resultcacheable(restrictinfo); return restrictinfo; } @@ -2569,18 +2643,19 @@ match_foreign_keys_to_quals(PlannerInfo *root) */ for (colno = 0; colno < fkinfo->nkeys; colno++) { + EquivalenceClass *ec; AttrNumber con_attno, ref_attno; Oid fpeqop; ListCell *lc2; - fkinfo->eclass[colno] = match_eclasses_to_foreign_key_col(root, - fkinfo, - colno); + ec = match_eclasses_to_foreign_key_col(root, fkinfo, colno); /* Don't bother looking for loose quals if we got an EC match */ - if (fkinfo->eclass[colno] != NULL) + if (ec != NULL) { fkinfo->nmatched_ec++; + if (ec->ec_has_const) + fkinfo->nconst_ec++; continue; } @@ -2708,7 +2783,7 @@ check_mergejoinable(RestrictInfo *restrictinfo) leftarg = linitial(((OpExpr *) clause)->args); if (op_mergejoinable(opno, exprType(leftarg)) && - !contain_volatile_functions((Node *) clause)) + !contain_volatile_functions((Node *) restrictinfo)) restrictinfo->mergeopfamilies = get_mergejoin_opfamilies(opno); /* @@ -2758,6 +2833,37 @@ check_hashjoinable(RestrictInfo *restrictinfo) leftarg = linitial(((OpExpr *) clause)->args); if (op_hashjoinable(opno, exprType(leftarg)) && - !contain_volatile_functions((Node *) clause)) + !contain_volatile_functions((Node *) restrictinfo)) restrictinfo->hashjoinoperator = opno; } + +/* + * check_resultcacheable + * If the restrictinfo's clause is suitable to be used for a Result Cache + * node, set the hasheqoperator to the hash equality operator that will be + * needed during caching. + */ +static void +check_resultcacheable(RestrictInfo *restrictinfo) +{ + TypeCacheEntry *typentry; + Expr *clause = restrictinfo->clause; + Node *leftarg; + + if (restrictinfo->pseudoconstant) + return; + if (!is_opclause(clause)) + return; + if (list_length(((OpExpr *) clause)->args) != 2) + return; + + leftarg = linitial(((OpExpr *) clause)->args); + + typentry = lookup_type_cache(exprType(leftarg), TYPECACHE_HASH_PROC | + TYPECACHE_EQ_OPR); + + if (!OidIsValid(typentry->hash_proc) || !OidIsValid(typentry->eq_opr)) + return; + + restrictinfo->hasheqoperator = typentry->eq_opr; +} diff --git a/src/backend/optimizer/plan/joinpartprune.c b/src/backend/optimizer/plan/joinpartprune.c index 71d296b68db5..a9ea585a54fd 100644 --- a/src/backend/optimizer/plan/joinpartprune.c +++ b/src/backend/optimizer/plan/joinpartprune.c @@ -335,7 +335,7 @@ create_partition_selector_plan(PlannerInfo *root, PartitionSelectorPath *best_pa */ List * make_partition_join_pruneinfos(PlannerInfo *root, RelOptInfo *parentrel, - List *subpaths, List *partitioned_rels) + List *subpaths) { PartitionPruneInfo *part_prune_info; List *result = NIL; @@ -367,7 +367,7 @@ make_partition_join_pruneinfos(PlannerInfo *root, RelOptInfo *parentrel, part_prune_info = make_partition_pruneinfo_ext(root, parentrel, - subpaths, partitioned_rels, + subpaths, candidate->joinrestrictinfo, candidate->inner_relids); diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c index 091bdb024d9d..52f03e5ea90b 100644 --- a/src/backend/optimizer/plan/planagg.c +++ b/src/backend/optimizer/plan/planagg.c @@ -19,7 +19,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -55,6 +55,7 @@ #include "cdb/cdbvars.h" static bool find_minmax_aggs_walker(Node *node, List **context); +static bool can_minmax_aggs(PlannerInfo *root, List **context); static bool build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, Oid eqop, Oid sortop, bool nulls_first); static void minmax_qp_callback(PlannerInfo *root, void *extra); @@ -73,7 +74,8 @@ static Oid fetch_agg_sort_op(Oid aggfnoid); * query_planner(), because we generate indexscan paths by cloning the * planner's state and invoking query_planner() on a modified version of * the query parsetree. Thus, all preprocessing needed before query_planner() - * must already be done. + * must already be done. This relies on the list of aggregates in + * root->agginfos, so preprocess_aggrefs() must have been called already, too. */ void preprocess_minmax_aggregates(PlannerInfo *root) @@ -153,9 +155,7 @@ preprocess_minmax_aggregates(PlannerInfo *root) * all are MIN/MAX aggregates. Stop as soon as we find one that isn't. */ aggs_list = NIL; - if (find_minmax_aggs_walker((Node *) root->processed_tlist, &aggs_list)) - return; - if (find_minmax_aggs_walker(parse->havingQual, &aggs_list)) + if (!can_minmax_aggs(root, &aggs_list)) return; /* @@ -240,38 +240,33 @@ preprocess_minmax_aggregates(PlannerInfo *root) } /* - * find_minmax_aggs_walker - * Recursively scan the Aggref nodes in an expression tree, and check - * that each one is a MIN/MAX aggregate. If so, build a list of the + * can_minmax_aggs + * Walk through all the aggregates in the query, and check + * if they are all MIN/MAX aggregates. If so, build a list of the * distinct aggregate calls in the tree. * - * Returns true if a non-MIN/MAX aggregate is found, false otherwise. - * (This seemingly-backward definition is used because expression_tree_walker - * aborts the scan on true return, which is what we want.) - * - * Found aggregates are added to the list at *context; it's up to the caller - * to initialize the list to NIL. + * Returns false if a non-MIN/MAX aggregate is found, true otherwise. * * This does not descend into subqueries, and so should be used only after * reduction of sublinks to subplans. There mustn't be outer-aggregate * references either. */ static bool -find_minmax_aggs_walker(Node *node, List **context) +can_minmax_aggs(PlannerInfo *root, List **context) { - if (node == NULL) - return false; - if (IsA(node, Aggref)) + ListCell *lc; + + foreach(lc, root->agginfos) { - Aggref *aggref = (Aggref *) node; + AggInfo *agginfo = (AggInfo *) lfirst(lc); + Aggref *aggref = agginfo->representative_aggref; Oid aggsortop; TargetEntry *curTarget; MinMaxAggInfo *mminfo; - ListCell *l; Assert(aggref->agglevelsup == 0); if (list_length(aggref->args) != 1) - return true; /* it couldn't be MIN/MAX */ + return false; /* it couldn't be MIN/MAX */ /* * ORDER BY is usually irrelevant for MIN/MAX, but it can change the @@ -287,7 +282,7 @@ find_minmax_aggs_walker(Node *node, List **context) * quickly. */ if (aggref->aggorder != NIL) - return true; + return false; /* note: we do not care if DISTINCT is mentioned ... */ /* @@ -296,30 +291,19 @@ find_minmax_aggs_walker(Node *node, List **context) * now, just punt. */ if (aggref->aggfilter != NULL) - return true; + return false; aggsortop = fetch_agg_sort_op(aggref->aggfnoid); if (!OidIsValid(aggsortop)) - return true; /* not a MIN/MAX aggregate */ + return false; /* not a MIN/MAX aggregate */ curTarget = (TargetEntry *) linitial(aggref->args); if (contain_mutable_functions((Node *) curTarget->expr)) - return true; /* not potentially indexable */ + return false; /* not potentially indexable */ if (type_is_rowtype(exprType((Node *) curTarget->expr))) - return true; /* IS NOT NULL would have weird semantics */ - - /* - * Check whether it's already in the list, and add it if not. - */ - foreach(l, *context) - { - mminfo = (MinMaxAggInfo *) lfirst(l); - if (mminfo->aggfnoid == aggref->aggfnoid && - equal(mminfo->target, curTarget->expr)) - return false; - } + return false; /* IS NOT NULL would have weird semantics */ mminfo = makeNode(MinMaxAggInfo); mminfo->aggfnoid = aggref->aggfnoid; @@ -331,16 +315,8 @@ find_minmax_aggs_walker(Node *node, List **context) mminfo->param = NULL; *context = lappend(*context, mminfo); - - /* - * We need not recurse into the argument, since it can't contain any - * aggregates. - */ - return false; } - Assert(!IsA(node, SubLink)); - return expression_tree_walker(node, find_minmax_aggs_walker, - (void *) context); + return true; } /* @@ -381,6 +357,8 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, subroot->plan_params = NIL; subroot->outer_params = NULL; subroot->init_plans = NIL; + subroot->agginfos = NIL; + subroot->aggtransinfos = NIL; subroot->parse = parse = copyObject(root->parse); IncrementVarSublevelsUp((Node *) parse, 1, 1); diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index b5a1a1e037f0..3010c3c8a7b7 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -11,7 +11,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -295,6 +295,13 @@ query_planner(PlannerInfo *root, */ add_other_rels_to_query(root); + /* + * Distribute any UPDATE/DELETE row identity variables to the target + * relations. This can't be done till we've finished expansion of + * appendrels. + */ + distribute_row_identity_vars(root); + /* * Ready to do the primary planning. */ diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 411354e9eadb..615a1af35146 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,8 +24,11 @@ #include "access/htup_details.h" #include "access/parallel.h" #include "access/sysattr.h" +#include "access/relation.h" #include "access/table.h" #include "access/xact.h" +#include "catalog/pg_am.h" +#include "commands/defrem.h" #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" #include "catalog/pg_proc.h" @@ -64,6 +67,7 @@ #include "rewrite/rewriteManip.h" #include "storage/dsm_impl.h" #include "utils/lsyscache.h" +#include "utils/partcache.h" #include "utils/rel.h" #include "utils/selfuncs.h" #include "utils/syscache.h" @@ -156,9 +160,7 @@ typedef struct /* Local functions */ static Node *preprocess_expression(PlannerInfo *root, Node *expr, int kind); static void preprocess_qual_conditions(PlannerInfo *root, Node *jtnode); -static void inheritance_planner(PlannerInfo *root); -static void grouping_planner(PlannerInfo *root, bool inheritance_update, - double tuple_fraction); +static void grouping_planner(PlannerInfo *root, double tuple_fraction); static grouping_sets_data *preprocess_grouping_sets(PlannerInfo *root); static List *remap_to_groupclause_idx(List *groupClause, List *gsets, int *tleref_to_colnum_map); @@ -179,7 +181,6 @@ static RelOptInfo *create_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, - const AggClauseCosts *agg_costs, grouping_sets_data *gd); static bool is_degenerate_grouping(PlannerInfo *root); static void create_degenerate_grouping_paths(PlannerInfo *root, @@ -255,8 +256,7 @@ static RelOptInfo *create_partial_grouping_paths(PlannerInfo *root, GroupPathExtraData *extra, bool force_rel_creation); static void gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel); -static bool can_partial_agg(PlannerInfo *root, - const AggClauseCosts *agg_costs); +static bool can_partial_agg(PlannerInfo *root); static void apply_scanjoin_target_to_paths(PlannerInfo *root, RelOptInfo *rel, List *scanjoin_targets, @@ -331,6 +331,52 @@ planner(Query *parse, const char *query_string, int cursorOptions, return result; } +/* + * GPDB: does any partitioned table in the query use a non-default operator + * class in its partition key? ORCA's metadata translation does not support + * that and, worse, the exception it raises mid-retrieval leaves the + * optimizer state corrupted enough to crash the coordinator on this and + * subsequent statements. Fall back to this planner up front instead. + */ +static bool +query_has_nondefault_partition_opclass(Query *parse) +{ + ListCell *lc; + + foreach(lc, parse->rtable) + { + RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc); + Relation rel; + PartitionKey key; + bool nondefault = false; + + if (rte->rtekind != RTE_RELATION || + rte->relkind != RELKIND_PARTITIONED_TABLE) + continue; + + /* parser/rewriter already hold a lock on every query relation */ + rel = relation_open(rte->relid, NoLock); + key = RelationGetPartitionKey(rel); + for (int i = 0; i < key->partnatts; i++) + { + Oid am = (key->strategy == PARTITION_STRATEGY_HASH) ? + HASH_AM_OID : BTREE_AM_OID; + Oid defopclass = GetDefaultOpClass(key->parttypid[i], am); + + if (!OidIsValid(defopclass) || + get_opclass_family(defopclass) != key->partopfamily[i]) + { + nondefault = true; + break; + } + } + relation_close(rel, NoLock); + if (nondefault) + return true; + } + return false; +} + PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams) @@ -366,7 +412,8 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, GP_ROLE_DISPATCH == Gp_role && IS_QUERY_DISPATCHER() && (cursorOptions & CURSOR_OPT_SKIP_FOREIGN_PARTITIONS) == 0 && - (cursorOptions & CURSOR_OPT_PARALLEL_RETRIEVE) == 0) + (cursorOptions & CURSOR_OPT_PARALLEL_RETRIEVE) == 0 && + !query_has_nondefault_partition_opclass(parse)) { if (gp_log_optimization_time) INSTR_TIME_SET_CURRENT(starttime); @@ -420,7 +467,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, glob->finalrtable = NIL; glob->finalrowmarks = NIL; glob->resultRelations = NIL; - glob->rootResultRelations = NIL; glob->appendRelations = NIL; glob->relationOids = NIL; glob->invalItems = NIL; @@ -672,7 +718,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, Assert(glob->finalrowmarks == NIL); Assert(glob->resultRelations == NIL); Assert(parse == root->parse); - Assert(glob->rootResultRelations == NIL); Assert(glob->appendRelations == NIL); if (Gp_role == GP_ROLE_DISPATCH) @@ -736,7 +781,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, result->slices = glob->slices; result->rtable = glob->finalrtable; result->resultRelations = glob->resultRelations; - result->rootResultRelations = glob->rootResultRelations; result->appendRelations = glob->appendRelations; result->subplans = glob->subplans; result->subplan_sliceIds = glob->subplan_sliceIds; @@ -838,20 +882,26 @@ subquery_planner(PlannerGlobal *glob, Query *parse, root->list_cteplaninfo = init_list_cteplaninfo(list_length(parse->cteList)); } + root->all_result_relids = + parse->resultRelation ? bms_make_singleton(parse->resultRelation) : NULL; + root->leaf_result_relids = NULL; /* we'll find out leaf-ness later */ root->append_rel_list = NIL; + root->row_identity_vars = NIL; root->rowMarks = NIL; memset(root->upper_rels, 0, sizeof(root->upper_rels)); memset(root->upper_targets, 0, sizeof(root->upper_targets)); root->processed_tlist = NIL; + root->update_colnos = NIL; root->grouping_map = NULL; root->minmax_aggs = NIL; root->qual_security_level = 0; - root->inhTargetKind = INHKIND_NONE; root->upd_del_replicated_table = 0; Assert(config); root->config = config; + root->hasPseudoConstantQuals = false; + root->hasAlternativeSubPlans = false; root->hasRecursion = hasRecursion; if (hasRecursion) root->wt_param_id = assign_special_exec_param(root); @@ -997,6 +1047,19 @@ subquery_planner(PlannerGlobal *glob, Query *parse, list_length(rte->securityQuals)); } + /* + * If we have now verified that the query target relation is + * non-inheriting, mark it as a leaf target. + */ + if (parse->resultRelation) + { + RangeTblEntry *rte = rt_fetch(parse->resultRelation, parse->rtable); + + if (!rte->inh) + root->leaf_result_relids = + bms_make_singleton(parse->resultRelation); + } + /* * Preprocess RowMark information. We need to do this after subquery * pullup, so that all base relations are present. @@ -1010,9 +1073,6 @@ subquery_planner(PlannerGlobal *glob, Query *parse, */ root->hasHavingQual = (parse->havingQual != NULL); - /* Clear this flag; might get set in distribute_qual_to_rels */ - root->hasPseudoConstantQuals = false; - /* * Do expression preprocessing on targetlist and quals, as well as other * random expressions in the querytree. Note that we do not need to @@ -1263,14 +1323,9 @@ subquery_planner(PlannerGlobal *glob, Query *parse, remove_useless_result_rtes(root); /* - * Do the main planning. If we have an inherited target relation, that - * needs special processing, else go straight to grouping_planner. + * Do the main planning. */ - if (parse->resultRelation && - rt_fetch(parse->resultRelation, parse->rtable)->inh) - inheritance_planner(root); - else - grouping_planner(root, false, tuple_fraction); + grouping_planner(root, tuple_fraction); /* * Capture the set of outer-level param IDs we have access to, for use in @@ -1394,6 +1449,16 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind) #endif } + /* + * Check for ANY ScalarArrayOpExpr with Const arrays and set the + * hashfuncid of any that might execute more quickly by using hash lookups + * instead of a linear search. + */ + if (kind == EXPRKIND_QUAL || kind == EXPRKIND_TARGET) + { + convert_saop_to_hashed_saop(expr); + } + /* Expand SubLinks to SubPlans */ if (root->parse->hasSubLinks) expr = SS_process_sublinks(root, expr, (kind == EXPRKIND_QUAL)); @@ -1631,7 +1696,7 @@ inheritance_planner(PlannerInfo *root) Assert(subroot->placeholder_list == NIL); /* Generate Path(s) for accessing this result relation */ - grouping_planner(subroot, true, 0.0 /* retrieve all tuples */ ); + grouping_planner(subroot, 0.0 /* retrieve all tuples */ ); /* Extract the info we need. */ select_rtable = subroot->parse->rtable; @@ -1819,8 +1884,6 @@ inheritance_planner(PlannerInfo *root) * relation_excluded_by_constraints() to treat the result relation as * being an appendrel member. */ - subroot->inhTargetKind = - (rootRelation != 0) ? INHKIND_PARTITIONED : INHKIND_INHERITED; /* * If this child is further partitioned, remember it as a parent. @@ -1900,7 +1963,7 @@ inheritance_planner(PlannerInfo *root) Assert(subroot->placeholder_list == NIL); /* Generate Path(s) for accessing this result relation */ - grouping_planner(subroot, true, 0.0 /* retrieve all tuples */ ); + grouping_planner(subroot, 0.0 /* retrieve all tuples */ ); /* * Select cheapest path in case there's more than one. We always run @@ -2079,13 +2142,13 @@ inheritance_planner(PlannerInfo *root) Path *dummy_path; /* tlist processing never got done, either */ - root->processed_tlist = preprocess_targetlist(root); + preprocess_targetlist(root); final_rel->reltarget = create_pathtarget(root, root->processed_tlist); /* Make a dummy path, cf set_dummy_rel_pathlist() */ - dummy_path = (Path *) create_append_path(NULL, final_rel, NIL, NIL, + dummy_path = (Path *) create_append_path(root, final_rel, NIL, NIL, NIL, NULL, 0, false, - NIL, -1); + -1); /* These lists must be nonempty to make a valid ModifyTable node */ subpaths = list_make1(dummy_path); @@ -2140,14 +2203,14 @@ inheritance_planner(PlannerInfo *root) /* Create Path representing a ModifyTable to do the UPDATE/DELETE work */ add_path(final_rel, (Path *) create_modifytable_path(root, final_rel, + (Path *) linitial(subpaths), parse->commandType, parse->canSetTag, nominalRelation, rootRelation, root->partColsUpdated, resultRelations, - subpaths, - subroots, + NIL, withCheckOptionLists, returningLists, is_split_updates, @@ -2163,11 +2226,6 @@ inheritance_planner(PlannerInfo *root) * This function adds all required top-level processing to the scan/join * Path(s) produced by query_planner. * - * If inheritance_update is true, we're being called from inheritance_planner - * and should not include a ModifyTable step in the resulting Path(s). - * (inheritance_planner will create a single ModifyTable node covering all the - * target tables.) - * * tuple_fraction is the fraction of tuples we expect will be retrieved. * tuple_fraction is interpreted as follows: * 0: expect all tuples to be retrieved (normal case) @@ -2185,8 +2243,7 @@ inheritance_planner(PlannerInfo *root) *-------------------- */ static void -grouping_planner(PlannerInfo *root, bool inheritance_update, - double tuple_fraction) +grouping_planner(PlannerInfo *root, double tuple_fraction) { Query *parse = root->parse; int64 offset_est = 0; @@ -2339,7 +2396,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, bool scanjoin_target_parallel_safe; bool scanjoin_target_same_exprs; bool have_grouping; - AggClauseCosts agg_costs; WindowFuncLists *wflists = NULL; List *activeWindows = NIL; grouping_sets_data *gset_data = NULL; @@ -2367,7 +2423,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, * that we can transfer its decoration (resnames etc) to the topmost * tlist of the finished Plan. This is kept in processed_tlist. */ - root->processed_tlist = preprocess_targetlist(root); + preprocess_targetlist(root); /* * In the top query, determine a locus to indicate where the final @@ -2414,14 +2470,28 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, * purposes since all Paths will get charged the same. But at some * point we might wish to do that detection in the planner, rather * than during executor startup. + * Mark all the aggregates with resolved aggtranstypes, and detect + * aggregates that are duplicates or can share transition state. We + * must do this before slicing and dicing the tlist into various + * pathtargets, else some copies of the Aggref nodes might escape + * being marked. */ - MemSet(&agg_costs, 0, sizeof(AggClauseCosts)); if (parse->hasAggs) { - get_agg_clause_costs(root, (Node *) root->processed_tlist, - AGGSPLIT_SIMPLE, &agg_costs); - get_agg_clause_costs(root, parse->havingQual, AGGSPLIT_SIMPLE, - &agg_costs); + preprocess_aggrefs(root, (Node *) root->processed_tlist); + preprocess_aggrefs(root, (Node *) parse->havingQual); + + /* + * GPDB: a TableValueExpr subquery can SCATTER BY an aggregate + * expression. Its Aggref copy must agree (be equal()) with the + * targetlist instance so the scatter locus and the Motion's + * hash expressions can be matched to the aggregate's output + * column; without numbering it here the comparison fails and + * planning errors with 'could not find hash distribution key + * expressions in target list' (or leaves a raw Aggref in the + * Motion: 'Aggref found in non-Agg plan node'). + */ + preprocess_aggrefs(root, (Node *) parse->scatterClause); } /* @@ -2626,7 +2696,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, current_rel, grouping_target, grouping_target_parallel_safe, - &agg_costs, gset_data); /* Fix things up if grouping_target contains SRFs */ if (parse->hasTargetSRFs) @@ -2940,16 +3009,131 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, } /* - * If this is an INSERT/UPDATE/DELETE, and we're not being called from - * inheritance_planner, add the ModifyTable node. + * If this is an INSERT/UPDATE/DELETE, add the ModifyTable node. */ - if (parse->commandType != CMD_SELECT && !inheritance_update) + if (parse->commandType != CMD_SELECT) { Index rootRelation; - List *withCheckOptionLists; - List *returningLists; + List *resultRelations = NIL; + List *updateColnosLists = NIL; + List *withCheckOptionLists = NIL; + List *returningLists = NIL; + List *is_split_updates = NIL; List *rowMarks; + if (bms_membership(root->all_result_relids) == BMS_MULTIPLE) + { + /* Inherited UPDATE/DELETE */ + RelOptInfo *top_result_rel = find_base_rel(root, + parse->resultRelation); + int resultRelation = -1; + + /* Add only leaf children to ModifyTable. */ + while ((resultRelation = bms_next_member(root->leaf_result_relids, + resultRelation)) >= 0) + { + RelOptInfo *this_result_rel = find_base_rel(root, + resultRelation); + + /* + * Also exclude any leaf rels that have turned dummy since + * being added to the list, for example, by being excluded + * by constraint exclusion. + */ + if (IS_DUMMY_REL(this_result_rel)) + continue; + + /* Build per-target-rel lists needed by ModifyTable */ + resultRelations = lappend_int(resultRelations, + resultRelation); + + /* + * GPDB: one is-split-update flag per result relation. All + * leaf partitions share the parent's distribution policy, + * so the split-update decision (root->is_split_update) is + * uniform across them. This list must stay the same length + * as resultRelations (see make_modifytable() and + * ExecInitModifyTable()). + */ + is_split_updates = lappend_int(is_split_updates, + root->is_split_update); + if (parse->commandType == CMD_UPDATE) + { + List *update_colnos = root->update_colnos; + + if (this_result_rel != top_result_rel) + update_colnos = + adjust_inherited_attnums_multilevel(root, + update_colnos, + this_result_rel->relid, + top_result_rel->relid); + updateColnosLists = lappend(updateColnosLists, + update_colnos); + } + if (parse->withCheckOptions) + { + List *withCheckOptions = parse->withCheckOptions; + + if (this_result_rel != top_result_rel) + withCheckOptions = (List *) + adjust_appendrel_attrs_multilevel(root, + (Node *) withCheckOptions, + this_result_rel->relids, + top_result_rel->relids); + withCheckOptionLists = lappend(withCheckOptionLists, + withCheckOptions); + } + if (parse->returningList) + { + List *returningList = parse->returningList; + + if (this_result_rel != top_result_rel) + returningList = (List *) + adjust_appendrel_attrs_multilevel(root, + (Node *) returningList, + this_result_rel->relids, + top_result_rel->relids); + returningLists = lappend(returningLists, + returningList); + } + } + + if (resultRelations == NIL) + { + /* + * We managed to exclude every child rel, so generate a + * dummy one-relation plan using info for the top target + * rel (even though that may not be a leaf target). + * Although it's clear that no data will be updated or + * deleted, we still need to have a ModifyTable node so + * that any statement triggers will be executed. (This + * could be cleaner if we fixed nodeModifyTable.c to allow + * zero target relations, but that probably wouldn't be a + * net win.) + */ + resultRelations = list_make1_int(parse->resultRelation); + is_split_updates = list_make1_int(root->is_split_update); + if (parse->commandType == CMD_UPDATE) + updateColnosLists = list_make1(root->update_colnos); + if (parse->withCheckOptions) + withCheckOptionLists = list_make1(parse->withCheckOptions); + if (parse->returningList) + returningLists = list_make1(parse->returningList); + } + } + else + { + /* Single-relation INSERT/UPDATE/DELETE. */ + resultRelations = list_make1_int(parse->resultRelation); + is_split_updates = list_make1_int(root->is_split_update); + if (parse->commandType == CMD_UPDATE) + updateColnosLists = list_make1(root->update_colnos); + if (parse->withCheckOptions) + withCheckOptionLists = list_make1(parse->withCheckOptions); + if (parse->returningList) + returningLists = list_make1(parse->returningList); + } + /* * If target is a partition root table, we need to mark the * ModifyTable node appropriately for that. @@ -2960,20 +3144,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, else rootRelation = 0; - /* - * Set up the WITH CHECK OPTION and RETURNING lists-of-lists, if - * needed. - */ - if (parse->withCheckOptions) - withCheckOptionLists = list_make1(parse->withCheckOptions); - else - withCheckOptionLists = NIL; - - if (parse->returningList) - returningLists = list_make1(parse->returningList); - else - returningLists = NIL; - /* * If there was a FOR [KEY] UPDATE/SHARE clause, the LockRows node * will have dealt with fetching non-locked marked rows, else we @@ -2986,17 +3156,17 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, path = (Path *) create_modifytable_path(root, final_rel, + path, parse->commandType, parse->canSetTag, parse->resultRelation, rootRelation, - false, - list_make1_int(parse->resultRelation), - list_make1(path), - list_make1(root), + root->partColsUpdated, + resultRelations, + updateColnosLists, withCheckOptionLists, returningLists, - list_make1_int(root->is_split_update), + is_split_updates, rowMarks, parse->onConflict, assign_special_exec_param(root)); @@ -3061,7 +3231,7 @@ preprocess_grouping_sets(PlannerInfo *root) ListCell *lc_set; grouping_sets_data *gd = palloc0(sizeof(grouping_sets_data)); - parse->groupingSets = expand_grouping_sets(parse->groupingSets, -1); + parse->groupingSets = expand_grouping_sets(parse->groupingSets, parse->groupDistinct, -1); gd->any_hashable = false; gd->unhashable_refs = NULL; @@ -4343,7 +4513,8 @@ get_number_of_groups(PlannerInfo *root, double numGroups = estimate_num_groups(root, groupExprs, path_rows, - &gset); + &gset, + NULL); gs->numGroups = numGroups; rollup->numGroups += numGroups; @@ -4368,7 +4539,8 @@ get_number_of_groups(PlannerInfo *root, double numGroups = estimate_num_groups(root, groupExprs, path_rows, - &gset); + &gset, + NULL); gs->numGroups = numGroups; gd->dNumHashGroups += numGroups; @@ -4384,7 +4556,7 @@ get_number_of_groups(PlannerInfo *root, target_list); dNumGroups = estimate_num_groups(root, groupExprs, path_rows, - NULL); + NULL, NULL); } } else if (parse->groupingSets) @@ -4418,7 +4590,6 @@ get_number_of_groups(PlannerInfo *root, * * input_rel: contains the source-data Paths * target: the pathtarget for the result Paths to compute - * agg_costs: cost info about all aggregates in query (in AGGSPLIT_SIMPLE mode) * gd: grouping sets data including list of grouping sets and their clauses * * Note: all Paths in input_rel are expected to return the target computed @@ -4429,12 +4600,15 @@ create_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, - const AggClauseCosts *agg_costs, grouping_sets_data *gd) { Query *parse = root->parse; RelOptInfo *grouped_rel; RelOptInfo *partially_grouped_rel; + AggClauseCosts agg_costs; + + MemSet(&agg_costs, 0, sizeof(AggClauseCosts)); + get_agg_clause_costs(root, AGGSPLIT_SIMPLE, &agg_costs); /* * Create grouping relation to hold fully aggregated grouping and/or @@ -4490,7 +4664,7 @@ create_grouping_paths(PlannerInfo *root, * the other gating conditions, so we want to do it last. */ if ((parse->groupClause != NIL && - agg_costs->numOrderedAggs == 0 && + root->numOrderedAggs == 0 && (gd ? gd->any_hashable : grouping_is_hashable(parse->groupClause)))) flags |= GROUPING_CAN_USE_HASH; @@ -4499,14 +4673,14 @@ create_grouping_paths(PlannerInfo *root, * even if there are DISTINCT aggs or grouping sets. */ if (parse->groupClause != NIL && - agg_costs->numPureOrderedAggs == 0 && + agg_costs.numPureOrderedAggs == 0 && grouping_is_hashable(parse->groupClause)) flags |= GROUPING_CAN_USE_MPP_HASH; /* * Determine whether partial aggregation is possible. */ - if (can_partial_agg(root, agg_costs)) + if (can_partial_agg(root)) flags |= GROUPING_CAN_PARTIAL_AGG; extra.flags = flags; @@ -4527,7 +4701,7 @@ create_grouping_paths(PlannerInfo *root, extra.patype = PARTITIONWISE_AGGREGATE_NONE; create_ordinary_grouping_paths(root, input_rel, grouped_rel, - agg_costs, gd, &extra, + &agg_costs, gd, &extra, &partially_grouped_rel); } @@ -4655,7 +4829,6 @@ create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, NULL, 0, false, - NIL, -1); } else @@ -4885,7 +5058,8 @@ consider_groupingsets_paths(PlannerInfo *root, if (srd->unhashed_rollup) exclude_groups = srd->unhashed_rollup->numGroups; - hashsize = estimate_hashagg_tablesize(path, + hashsize = estimate_hashagg_tablesize(root, + path, agg_costs, dNumGroups - exclude_groups); @@ -4967,7 +5141,8 @@ consider_groupingsets_paths(PlannerInfo *root, /* * Account first for space needed for groups we can't sort at all. */ - availspace -= estimate_hashagg_tablesize(path, + availspace -= estimate_hashagg_tablesize(root, + path, agg_costs, gd->dNumHashGroups); // FIXME: should we divide dNumHashGroups by numsegments? @@ -5013,13 +5188,14 @@ consider_groupingsets_paths(PlannerInfo *root, * below, must use the same condition. */ i = 0; - for_each_cell(lc, gd->rollups, list_second_cell(gd->rollups)) + for_each_from(lc, gd->rollups, 1) { RollupData *rollup = lfirst_node(RollupData, lc); if (rollup->hashable) { - double sz = estimate_hashagg_tablesize(path, + double sz = estimate_hashagg_tablesize(root, + path, agg_costs, rollup->numGroups); @@ -5047,7 +5223,7 @@ consider_groupingsets_paths(PlannerInfo *root, rollups = list_make1(linitial(gd->rollups)); i = 0; - for_each_cell(lc, gd->rollups, list_second_cell(gd->rollups)) + for_each_from(lc, gd->rollups, 1) { RollupData *rollup = lfirst_node(RollupData, lc); @@ -5165,14 +5341,17 @@ create_window_paths(PlannerInfo *root, /* * Consider computing window functions starting from the existing * cheapest-total path (which will likely require a sort) as well as any - * existing paths that satisfy root->window_pathkeys (which won't). + * existing paths that satisfy or partially satisfy root->window_pathkeys. */ foreach(lc, input_rel->pathlist) { Path *path = (Path *) lfirst(lc); + int presorted_keys; if (path == input_rel->cheapest_total_path || - pathkeys_contained_in(root->window_pathkeys, path->pathkeys)) + pathkeys_count_contained_in(root->window_pathkeys, path->pathkeys, + &presorted_keys) || + presorted_keys > 0) create_one_window_path(root, window_rel, path, @@ -5247,25 +5426,30 @@ create_one_window_path(PlannerInfo *root, { WindowClause *wc = lfirst_node(WindowClause, l); List *window_pathkeys; + int presorted_keys; + bool is_sorted; window_pathkeys = make_pathkeys_for_window(root, wc, root->processed_tlist); + is_sorted = pathkeys_count_contained_in(window_pathkeys, + path->pathkeys, + &presorted_keys); + /* - * Unless the PARTITION BY in the window happens to match the - * current distribution, we need a motion. Each partition - * needs to be handled in the same segment. - * - * If there is no PARTITION BY, then all rows form a single - * partition, so we need to gather all the tuples to a single - * node. But we'll do that after the Sort, so that the Sort - * is parallelized. - * - * This is the same logic that is used for sorted Aggregates. + * GPDB: unless the PARTITION BY happens to match the current + * distribution, we need a motion: each window partition must be + * evaluated within one process, and with no PARTITION BY the whole + * input forms a single partition that must be gathered (a presorted + * per-segment input otherwise computes row_number() etc. per + * segment). This helper adds the required motion *and* the sort + * (merge-receiving presorted streams where possible), the same + * logic used for sorted aggregates; the upstream-only sort logic + * below then sees the input as sorted. */ path = cdb_prepare_path_for_sorted_agg(root, - pathkeys_contained_in(window_pathkeys, path->pathkeys), + is_sorted, window_rel, path, path->pathtarget, @@ -5273,6 +5457,36 @@ create_one_window_path(PlannerInfo *root, -1.0, wc->partitionClause, NIL); + is_sorted = pathkeys_count_contained_in(window_pathkeys, + path->pathkeys, + &presorted_keys); + + /* Sort if necessary */ + if (!is_sorted) + { + /* + * No presorted keys or incremental sort disabled, just perform a + * complete sort. + */ + if (presorted_keys == 0 || !enable_incremental_sort) + path = (Path *) create_sort_path(root, window_rel, + path, + window_pathkeys, + -1.0); + else + { + /* + * Since we have presorted keys and incremental sort is + * enabled, just use incremental sort. + */ + path = (Path *) create_incremental_sort_path(root, + window_rel, + path, + window_pathkeys, + presorted_keys, + -1.0); + } + } if (lnext(activeWindows, l)) { @@ -5380,8 +5594,8 @@ create_distinct_paths(PlannerInfo *root, distinctExprs = get_sortgrouplist_exprs(parse->distinctClause, parse->targetList); numDistinctRowsTotal = estimate_num_groups(root, distinctExprs, - numInputRowsTotal, - NULL); + cheapest_input_path->rows, + NULL, NULL); } /* @@ -5754,7 +5968,7 @@ create_ordered_paths(PlannerInfo *root, foreach(lc, input_rel->partial_pathlist) { Path *input_path = (Path *) lfirst(lc); - Path *sorted_path = input_path; + Path *sorted_path; bool is_sorted; int presorted_keys; double total_groups; @@ -7201,8 +7415,11 @@ plan_create_index_workers(Oid tableOid, Oid indexOid) double reltuples; double allvisfrac; - /* Return immediately when parallelism disabled */ - if (max_parallel_maintenance_workers == 0) + /* + * We don't allow performing parallel operation in standalone backend or + * when parallelism is disabled. + */ + if (!IsUnderPostmaster || max_parallel_maintenance_workers == 0) return 0; /* Set up largely-dummy planner state */ @@ -7807,16 +8024,11 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, /* partial phase */ partial_target_exprs = partially_grouped_target->exprs; - get_agg_clause_costs(root, (Node *) partial_target_exprs, - AGGSPLIT_INITIAL_SERIAL, + get_agg_clause_costs(root, AGGSPLIT_INITIAL_SERIAL, &extra->agg_partial_costs); /* final phase */ - get_agg_clause_costs(root, (Node *) grouped_rel->reltarget->exprs, - AGGSPLIT_FINAL_DESERIAL, - agg_final_costs); - get_agg_clause_costs(root, extra->havingQual, - AGGSPLIT_FINAL_DESERIAL, + get_agg_clause_costs(root, AGGSPLIT_FINAL_DESERIAL, agg_final_costs); } @@ -7955,20 +8167,12 @@ create_partial_grouping_paths(PlannerInfo *root, MemSet(agg_final_costs, 0, sizeof(AggClauseCosts)); if (parse->hasAggs) { - List *partial_target_exprs; - /* partial phase */ - partial_target_exprs = partially_grouped_rel->reltarget->exprs; - get_agg_clause_costs(root, (Node *) partial_target_exprs, - AGGSPLIT_INITIAL_SERIAL, + get_agg_clause_costs(root, AGGSPLIT_INITIAL_SERIAL, agg_partial_costs); /* final phase */ - get_agg_clause_costs(root, (Node *) grouped_rel->reltarget->exprs, - AGGSPLIT_FINAL_DESERIAL, - agg_final_costs); - get_agg_clause_costs(root, extra->havingQual, - AGGSPLIT_FINAL_DESERIAL, + get_agg_clause_costs(root, AGGSPLIT_FINAL_DESERIAL, agg_final_costs); } @@ -8274,14 +8478,14 @@ create_partial_grouping_paths(PlannerInfo *root, * Generate Gather and Gather Merge paths for a grouping relation or partial * grouping relation. * - * generate_gather_paths does most of the work, but we also consider a special - * case: we could try sorting the data by the group_pathkeys and then applying - * Gather Merge. + * generate_useful_gather_paths does most of the work, but we also consider a + * special case: we could try sorting the data by the group_pathkeys and then + * applying Gather Merge. * * NB: This function shouldn't be used for anything other than a grouped or * partially grouped relation not only because of the fact that it explicitly * references group_pathkeys but we pass "true" as the third argument to - * generate_gather_paths(). + * generate_useful_gather_paths(). */ static void gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel) @@ -8372,7 +8576,7 @@ gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel) * Returns true when possible, false otherwise. */ static bool -can_partial_agg(PlannerInfo *root, const AggClauseCosts *agg_costs) +can_partial_agg(PlannerInfo *root) { Query *parse = root->parse; @@ -8389,7 +8593,7 @@ can_partial_agg(PlannerInfo *root, const AggClauseCosts *agg_costs) /* We don't know how to do grouping sets in parallel. */ return false; } - else if (agg_costs->hasNonPartial || agg_costs->hasNonSerial) + else if (root->hasNonPartialAggs || root->hasNonSerialAggs) { /* Insufficient support for partial mode. */ return false; @@ -8441,13 +8645,11 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, * variations. So we drop old paths and thereby force the work to be done * below the Append, except in the case of a non-parallel-safe target. * - * Some care is needed, because we have to allow generate_gather_paths to - * see the old partial paths in the next stanza. Hence, zap the main - * pathlist here, then allow generate_gather_paths to add path(s) to the - * main list, and finally zap the partial pathlist. - * - * GPDB: We cannot do that if this is a correlated subquery, and we need - * to evaluate the correlation qual on top of the Append. + * Some care is needed, because we have to allow + * generate_useful_gather_paths to see the old partial paths in the next + * stanza. Hence, zap the main pathlist here, then allow + * generate_useful_gather_paths to add path(s) to the main list, and + * finally zap the partial pathlist. */ if (rel_is_partitioned && !rel->upperrestrictinfo) rel->pathlist = NIL; diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 8c39f7905c7b..5ba1b17e77b2 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -6,7 +6,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -59,6 +59,7 @@ typedef struct { PlannerInfo *root; int rtoffset; + double num_exec; } fix_scan_expr_context; typedef struct @@ -70,6 +71,7 @@ typedef struct int rtoffset; bool use_outer_tlist_for_matching_nonvars; bool use_inner_tlist_for_matching_nonvars; + double num_exec; } fix_join_expr_context; typedef struct @@ -78,6 +80,7 @@ typedef struct indexed_tlist *subplan_itlist; Index newvarno; int rtoffset; + double num_exec; } fix_upper_expr_context; typedef struct @@ -86,6 +89,25 @@ typedef struct plan_tree_base_prefix base; } cdb_extract_plan_dependencies_context; +/* + * Selecting the best alternative in an AlternativeSubPlan expression requires + * estimating how many times that expression will be evaluated. For an + * expression in a plan node's targetlist, the plan's estimated number of + * output rows is clearly what to use, but for an expression in a qual it's + * far less clear. Since AlternativeSubPlans aren't heavily used, we don't + * want to expend a lot of cycles making such estimates. What we use is twice + * the number of output rows. That's not entirely unfounded: we know that + * clause_selectivity() would fall back to a default selectivity estimate + * of 0.5 for any SubPlan, so if the qual containing the SubPlan is the last + * to be applied (which it likely would be, thanks to order_qual_clauses()), + * this matches what we could have estimated in a far more laborious fashion. + * Obviously there are many other scenarios, but it's probably not worth the + * trouble to try to improve on this estimate, especially not when we don't + * have a better estimate for the selectivity of the SubPlan qual itself. + */ +#define NUM_EXEC_TLIST(parentplan) ((parentplan)->plan_rows) +#define NUM_EXEC_QUAL(parentplan) ((parentplan)->plan_rows * 2.0) + /* * Check if a Const node is a regclass value. We accept plain OID too, * since a regclass Const will get folded to that type if it's an argument @@ -97,8 +119,8 @@ typedef struct (((con)->consttype == REGCLASSOID || (con)->consttype == OIDOID) && \ !(con)->constisnull) -#define fix_scan_list(root, lst, rtoffset) \ - ((List *) fix_scan_expr(root, (Node *) (lst), rtoffset)) +#define fix_scan_list(root, lst, rtoffset, num_exec) \ + ((List *) fix_scan_expr(root, (Node *) (lst), rtoffset, num_exec)) static void add_rtes_to_flat_rtable(PlannerInfo *root, bool recursing); static void flatten_unplanned_rtes(PlannerGlobal *glob, RangeTblEntry *rte); @@ -127,7 +149,8 @@ static Plan *set_mergeappend_references(PlannerInfo *root, int rtoffset); static void set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset); static Relids offset_relid_set(Relids relids, int rtoffset); -static Node *fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset); +static Node *fix_scan_expr(PlannerInfo *root, Node *node, + int rtoffset, double num_exec); static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context); static bool fix_scan_expr_walker(Node *node, fix_scan_expr_context *context); static void set_join_references(PlannerInfo *root, Join *join, int rtoffset); @@ -153,7 +176,8 @@ static List *fix_join_expr(PlannerInfo *root, List *clauses, indexed_tlist *outer_itlist, indexed_tlist *inner_itlist, - Index acceptable_rel, int rtoffset); + Index acceptable_rel, + int rtoffset, double num_exec); static Node *fix_join_expr_mutator(Node *node, fix_join_expr_context *context); static List *fix_hashclauses(PlannerInfo *root, @@ -171,7 +195,7 @@ static Node *fix_upper_expr(PlannerInfo *root, Node *node, indexed_tlist *subplan_itlist, Index newvarno, - int rtoffset); + int rtoffset, double num_exec); static Node *fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context); static List *set_returning_clause_references(PlannerInfo *root, @@ -309,17 +333,20 @@ static void set_plan_references_output_asserts(PlannerGlobal *glob, Plan *plan) * 5. PARAM_MULTIEXPR Params are replaced by regular PARAM_EXEC Params, * now that we have finished planning all MULTIEXPR subplans. * - * 6. We compute regproc OIDs for operators (ie, we look up the function + * 6. AlternativeSubPlan expressions are replaced by just one of their + * alternatives, using an estimate of how many times they'll be executed. + * + * 7. We compute regproc OIDs for operators (ie, we look up the function * that implements each op). * - * 7. We create lists of specific objects that the plan depends on. + * 8. We create lists of specific objects that the plan depends on. * This will be used by plancache.c to drive invalidation of cached plans. * Relation dependencies are represented by OIDs, and everything else by * PlanInvalItems (this distinction is motivated by the shared-inval APIs). * Currently, relations, user-defined functions, and domains are the only * types of objects that are explicitly tracked this way. * - * 8. We assign every plan node in the tree a unique ID. + * 9. We assign every plan node in the tree a unique ID. * * We also perform one final optimization step, which is to delete * SubqueryScan, Append, and MergeAppend plan nodes that aren't doing @@ -563,9 +590,9 @@ flatten_rtes_walker(Node *node, PlannerGlobal *glob) * In the flat rangetable, we zero out substructure pointers that are not * needed by the executor; this reduces the storage space and copying cost * for cached plans. We keep only the ctename, alias and eref Alias fields, - * which are needed by EXPLAIN, and the selectedCols, insertedCols and - * updatedCols bitmaps, which are needed for executor-startup permissions - * checking and for trigger event checking. + * which are needed by EXPLAIN, and the selectedCols, insertedCols, + * updatedCols, and extraUpdatedCols bitmaps, which are needed for + * executor-startup permissions checking and for trigger event checking. */ static void add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte) @@ -582,6 +609,7 @@ add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte) newrte->joinaliasvars = NIL; newrte->joinleftcols = NIL; newrte->joinrightcols = NIL; + newrte->join_using_alias = NULL; newrte->functions = NIL; newrte->tablefunc = NULL; newrte->values_lists = NIL; @@ -653,9 +681,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) #endif splan->plan.targetlist = - fix_scan_list(root, splan->plan.targetlist, rtoffset); + fix_scan_list(root, splan->plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->plan.qual = - fix_scan_list(root, splan->plan.qual, rtoffset); + fix_scan_list(root, splan->plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); } break; case T_SampleScan: @@ -664,11 +694,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); splan->tablesample = (TableSampleClause *) - fix_scan_expr(root, (Node *) splan->tablesample, rtoffset); + fix_scan_expr(root, (Node *) splan->tablesample, + rtoffset, 1); } break; case T_IndexScan: @@ -681,17 +714,23 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); splan->indexqual = - fix_scan_list(root, splan->indexqual, rtoffset); + fix_scan_list(root, splan->indexqual, + rtoffset, 1); splan->indexqualorig = - fix_scan_list(root, splan->indexqualorig, rtoffset); + fix_scan_list(root, splan->indexqualorig, + rtoffset, NUM_EXEC_QUAL(plan)); splan->indexorderby = - fix_scan_list(root, splan->indexorderby, rtoffset); + fix_scan_list(root, splan->indexorderby, + rtoffset, 1); splan->indexorderbyorig = - fix_scan_list(root, splan->indexorderbyorig, rtoffset); + fix_scan_list(root, splan->indexorderbyorig, + rtoffset, NUM_EXEC_QUAL(plan)); } break; case T_IndexOnlyScan: @@ -710,9 +749,10 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) Assert(splan->scan.plan.targetlist == NIL); Assert(splan->scan.plan.qual == NIL); splan->indexqual = - fix_scan_list(root, splan->indexqual, rtoffset); + fix_scan_list(root, splan->indexqual, rtoffset, 1); splan->indexqualorig = - fix_scan_list(root, splan->indexqualorig, rtoffset); + fix_scan_list(root, splan->indexqualorig, + rtoffset, NUM_EXEC_QUAL(plan)); } break; case T_BitmapHeapScan: @@ -725,11 +765,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); splan->bitmapqualorig = - fix_scan_list(root, splan->bitmapqualorig, rtoffset); + fix_scan_list(root, splan->bitmapqualorig, + rtoffset, NUM_EXEC_QUAL(plan)); } break; case T_TidScan: @@ -741,11 +784,30 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); splan->tidquals = - fix_scan_list(root, splan->tidquals, rtoffset); + fix_scan_list(root, splan->tidquals, + rtoffset, 1); + } + break; + case T_TidRangeScan: + { + TidRangeScan *splan = (TidRangeScan *) plan; + + splan->scan.scanrelid += rtoffset; + splan->scan.plan.targetlist = + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); + splan->scan.plan.qual = + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); + splan->tidrangequals = + fix_scan_list(root, splan->tidrangequals, + rtoffset, 1); } break; case T_SubqueryScan: @@ -776,11 +838,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) /* adjust for the new range table offset */ tplan->scan.scanrelid += rtoffset; tplan->scan.plan.targetlist = - fix_scan_list(root, tplan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, tplan->scan.plan.targetlist, rtoffset, 1); tplan->scan.plan.qual = - fix_scan_list(root, tplan->scan.plan.qual, rtoffset); + fix_scan_list(root, tplan->scan.plan.qual, rtoffset, 1); tplan->function = (RangeTblFunction *) - fix_scan_expr(root, (Node *) tplan->function, rtoffset); + fix_scan_expr(root, (Node *) tplan->function, rtoffset, 1); return plan; } @@ -793,11 +855,13 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); splan->functions = - fix_scan_list(root, splan->functions, rtoffset); + fix_scan_list(root, splan->functions, rtoffset, 1); } break; case T_TableFuncScan: @@ -806,11 +870,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); splan->tablefunc = (TableFunc *) - fix_scan_expr(root, (Node *) splan->tablefunc, rtoffset); + fix_scan_expr(root, (Node *) splan->tablefunc, + rtoffset, 1); } break; case T_ValuesScan: @@ -822,11 +889,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); splan->values_lists = - fix_scan_list(root, splan->values_lists, rtoffset); + fix_scan_list(root, splan->values_lists, + rtoffset, 1); } break; case T_CteScan: @@ -835,9 +905,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); } break; case T_NamedTuplestoreScan: @@ -846,9 +918,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); } break; case T_WorkTableScan: @@ -857,9 +931,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->scan.scanrelid += rtoffset; splan->scan.plan.targetlist = - fix_scan_list(root, splan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, splan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->scan.plan.qual = - fix_scan_list(root, splan->scan.plan.qual, rtoffset); + fix_scan_list(root, splan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); } break; case T_ForeignScan: @@ -904,6 +980,22 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) set_hash_references(root, plan, rtoffset); break; + case T_ResultCache: + { + ResultCache *rcplan = (ResultCache *) plan; + + /* + * Result Cache does not evaluate its targetlist. It just + * uses the same targetlist from its outer subnode. + */ + set_dummy_tlist_references(plan, rtoffset); + + rcplan->param_exprs = fix_scan_list(root, rcplan->param_exprs, + rtoffset, + NUM_EXEC_TLIST(plan)); + break; + } + case T_Material: case T_Sort: case T_IncrementalSort: @@ -955,10 +1047,10 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) pinfo->initial_pruning_steps = (List *) fix_upper_expr(root, (Node *) pinfo->initial_pruning_steps, - childplan_itlist, OUTER_VAR, rtoffset); + childplan_itlist, OUTER_VAR, rtoffset, 1); pinfo->exec_pruning_steps = (List *) fix_upper_expr(root, (Node *) pinfo->exec_pruning_steps, - childplan_itlist, OUTER_VAR, rtoffset); + childplan_itlist, OUTER_VAR, rtoffset, 1); } } } @@ -1000,9 +1092,9 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) Assert(splan->plan.qual == NIL); splan->limitOffset = - fix_scan_expr(root, splan->limitOffset, rtoffset); + fix_scan_expr(root, splan->limitOffset, rtoffset, 1); splan->limitCount = - fix_scan_expr(root, splan->limitCount, rtoffset); + fix_scan_expr(root, splan->limitCount, rtoffset, 1); } break; case T_Agg: @@ -1052,7 +1144,7 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) (Node *)dqaExpr->agg_filter, subplan_itlist, OUTER_VAR, - rtoffset); + rtoffset, 1); lfirst(lc) = dqaExpr; } @@ -1074,20 +1166,19 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) * Fix frame edges. PostgreSQL uses fix_scan_expr here, but * in GPDB, we allow the ROWS/RANGE expressions to contain * references to the subplan, so we have to use fix_upper_expr. + * (Using fix_scan_expr leaves a column-valued offset's Vars + * with base-relation varnos instead of OUTER_VAR, so + * compute_start_end_offsets() then evaluates them against the + * wrong slot and the WindowAgg crashes.) */ - if (wplan->startOffset || wplan->endOffset) - { - subplan_itlist = - build_tlist_index(plan->lefttree->targetlist); - - wplan->startOffset = - fix_upper_expr(root, wplan->startOffset, - subplan_itlist, OUTER_VAR, rtoffset); - wplan->endOffset = - fix_upper_expr(root, wplan->endOffset, - subplan_itlist, OUTER_VAR, rtoffset); - pfree(subplan_itlist); - } + subplan_itlist = build_tlist_index(plan->lefttree->targetlist); + wplan->startOffset = + fix_upper_expr(root, wplan->startOffset, subplan_itlist, + OUTER_VAR, rtoffset, 1); + wplan->endOffset = + fix_upper_expr(root, wplan->endOffset, subplan_itlist, + OUTER_VAR, rtoffset, 1); + pfree(subplan_itlist); } break; case T_Result: @@ -1102,14 +1193,39 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) set_upper_references(root, plan, rtoffset); else { + /* + * The tlist of a childless Result could contain + * unresolved ROWID_VAR Vars, in case it's representing a + * target relation which is completely empty because of + * constraint exclusion. Replace any such Vars by null + * constants, as though they'd been resolved for a leaf + * scan node that doesn't support them. We could have + * fix_scan_expr do this, but since the case is only + * expected to occur here, it seems safer to special-case + * it here and keep the assertions that ROWID_VARs + * shouldn't be seen by fix_scan_expr. + */ + foreach(l, splan->plan.targetlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(l); + Var *var = (Var *) tle->expr; + + if (var && IsA(var, Var) && var->varno == ROWID_VAR) + tle->expr = (Expr *) makeNullConst(var->vartype, + var->vartypmod, + var->varcollid); + } + splan->plan.targetlist = - fix_scan_list(root, splan->plan.targetlist, rtoffset); + fix_scan_list(root, splan->plan.targetlist, + rtoffset, NUM_EXEC_TLIST(plan)); splan->plan.qual = - fix_scan_list(root, splan->plan.qual, rtoffset); + fix_scan_list(root, splan->plan.qual, + rtoffset, NUM_EXEC_QUAL(plan)); } /* resconstantqual can't contain any subplan variable refs */ splan->resconstantqual = - fix_scan_expr(root, splan->resconstantqual, rtoffset); + fix_scan_expr(root, splan->resconstantqual, rtoffset, 1); } break; case T_ProjectSet: @@ -1123,28 +1239,26 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) Assert(splan->plan.qual == NIL); splan->withCheckOptionLists = - fix_scan_list(root, splan->withCheckOptionLists, rtoffset); + fix_scan_list(root, splan->withCheckOptionLists, + rtoffset, 1); if (splan->returningLists) { List *newRL = NIL; + Plan *subplan = outerPlan(splan); ListCell *lcrl, - *lcrr, - *lcp; + *lcrr; /* - * Pass each per-subplan returningList through + * Pass each per-resultrel returningList through * set_returning_clause_references(). */ Assert(list_length(splan->returningLists) == list_length(splan->resultRelations)); - Assert(list_length(splan->returningLists) == list_length(splan->plans)); - forthree(lcrl, splan->returningLists, - lcrr, splan->resultRelations, - lcp, splan->plans) + forboth(lcrl, splan->returningLists, + lcrr, splan->resultRelations) { List *rlist = (List *) lfirst(lcrl); Index resultrel = lfirst_int(lcrr); - Plan *subplan = (Plan *) lfirst(lcp); rlist = set_returning_clause_references(root, rlist, @@ -1184,18 +1298,18 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) fix_join_expr(root, splan->onConflictSet, NULL, itlist, linitial_int(splan->resultRelations), - rtoffset); + rtoffset, NUM_EXEC_QUAL(plan)); splan->onConflictWhere = (Node *) fix_join_expr(root, (List *) splan->onConflictWhere, NULL, itlist, linitial_int(splan->resultRelations), - rtoffset); + rtoffset, NUM_EXEC_QUAL(plan)); pfree(itlist); splan->exclRelTlist = - fix_scan_list(root, splan->exclRelTlist, rtoffset); + fix_scan_list(root, splan->exclRelTlist, rtoffset, 1); } splan->nominalRelation += rtoffset; @@ -1214,35 +1328,18 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) rc->rti += rtoffset; rc->prti += rtoffset; } - foreach(l, splan->plans) - { - lfirst(l) = set_plan_refs(root, - (Plan *) lfirst(l), - rtoffset); - } /* * Append this ModifyTable node's final result relation RT - * index(es) to the global list for the plan, and set its - * resultRelIndex to reflect their starting position in the - * global list. + * index(es) to the global list for the plan. */ - splan->resultRelIndex = list_length(root->glob->resultRelations); root->glob->resultRelations = list_concat(root->glob->resultRelations, splan->resultRelations); - - /* - * If the main target relation is a partitioned table, also - * add the partition root's RT index to rootResultRelations, - * and remember its index in that list in rootResultRelIndex. - */ if (splan->rootRelation) { - splan->rootResultRelIndex = - list_length(root->glob->rootResultRelations); - root->glob->rootResultRelations = - lappend_int(root->glob->rootResultRelations, + root->glob->resultRelations = + lappend_int(root->glob->resultRelations, splan->rootRelation); } } @@ -1299,7 +1396,7 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) build_tlist_index(plan->lefttree->targetlist); motion->hashExprs = (List *) - fix_upper_expr(root, (Node*) motion->hashExprs, childplan_itlist, OUTER_VAR, rtoffset); + fix_upper_expr(root, (Node*) motion->hashExprs, childplan_itlist, OUTER_VAR, rtoffset, 1); /* no need to fix targetlist and qual */ Assert(plan->qual == NIL); @@ -1355,21 +1452,24 @@ set_indexonlyscan_references(PlannerInfo *root, (Node *) plan->scan.plan.targetlist, index_itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_TLIST((Plan *) plan)); plan->scan.plan.qual = (List *) fix_upper_expr(root, (Node *) plan->scan.plan.qual, index_itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) plan)); /* indexqual is already transformed to reference index columns */ - plan->indexqual = fix_scan_list(root, plan->indexqual, rtoffset); - /* indexqualorig is already transformed to reference index columns */ - plan->indexqualorig = fix_scan_list(root, plan->indexqualorig, rtoffset); + plan->indexqual = fix_scan_list(root, plan->indexqual, + rtoffset, 1); /* indexorderby is already transformed to reference index columns */ - plan->indexorderby = fix_scan_list(root, plan->indexorderby, rtoffset); + plan->indexorderby = fix_scan_list(root, plan->indexorderby, + rtoffset, 1); /* indextlist must NOT be transformed to reference index columns */ - plan->indextlist = fix_scan_list(root, plan->indextlist, rtoffset); + plan->indextlist = fix_scan_list(root, plan->indextlist, + rtoffset, NUM_EXEC_TLIST((Plan *) plan)); pfree(index_itlist); @@ -1418,9 +1518,11 @@ set_subqueryscan_references(PlannerInfo *root, //Assert(plan->scan.scanrelid <= list_length(glob->finalrtable) && "Scan node's relid is outside the finalrtable!"); plan->scan.plan.targetlist = - fix_scan_list(root, plan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, plan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST((Plan *) plan)); plan->scan.plan.qual = - fix_scan_list(root, plan->scan.plan.qual, rtoffset); + fix_scan_list(root, plan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL((Plan *) plan)); result = (Plan *) plan; } @@ -1538,29 +1640,34 @@ set_foreignscan_references(PlannerInfo *root, (Node *) fscan->scan.plan.targetlist, itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_TLIST((Plan *) fscan)); fscan->scan.plan.qual = (List *) fix_upper_expr(root, (Node *) fscan->scan.plan.qual, itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) fscan)); fscan->fdw_exprs = (List *) fix_upper_expr(root, (Node *) fscan->fdw_exprs, itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) fscan)); fscan->fdw_recheck_quals = (List *) fix_upper_expr(root, (Node *) fscan->fdw_recheck_quals, itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) fscan)); pfree(itlist); /* fdw_scan_tlist itself just needs fix_scan_list() adjustments */ fscan->fdw_scan_tlist = - fix_scan_list(root, fscan->fdw_scan_tlist, rtoffset); + fix_scan_list(root, fscan->fdw_scan_tlist, + rtoffset, NUM_EXEC_TLIST((Plan *) fscan)); } else { @@ -1569,16 +1676,24 @@ set_foreignscan_references(PlannerInfo *root, * way */ fscan->scan.plan.targetlist = - fix_scan_list(root, fscan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, fscan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST((Plan *) fscan)); fscan->scan.plan.qual = - fix_scan_list(root, fscan->scan.plan.qual, rtoffset); + fix_scan_list(root, fscan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL((Plan *) fscan)); fscan->fdw_exprs = - fix_scan_list(root, fscan->fdw_exprs, rtoffset); + fix_scan_list(root, fscan->fdw_exprs, + rtoffset, NUM_EXEC_QUAL((Plan *) fscan)); fscan->fdw_recheck_quals = - fix_scan_list(root, fscan->fdw_recheck_quals, rtoffset); + fix_scan_list(root, fscan->fdw_recheck_quals, + rtoffset, NUM_EXEC_QUAL((Plan *) fscan)); } fscan->fs_relids = offset_relid_set(fscan->fs_relids, rtoffset); + + /* Adjust resultRelation if it's valid */ + if (fscan->resultRelation > 0) + fscan->resultRelation += rtoffset; } /* @@ -1606,33 +1721,40 @@ set_customscan_references(PlannerInfo *root, (Node *) cscan->scan.plan.targetlist, itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_TLIST((Plan *) cscan)); cscan->scan.plan.qual = (List *) fix_upper_expr(root, (Node *) cscan->scan.plan.qual, itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) cscan)); cscan->custom_exprs = (List *) fix_upper_expr(root, (Node *) cscan->custom_exprs, itlist, INDEX_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) cscan)); pfree(itlist); /* custom_scan_tlist itself just needs fix_scan_list() adjustments */ cscan->custom_scan_tlist = - fix_scan_list(root, cscan->custom_scan_tlist, rtoffset); + fix_scan_list(root, cscan->custom_scan_tlist, + rtoffset, NUM_EXEC_TLIST((Plan *) cscan)); } else { /* Adjust tlist, qual, custom_exprs in the standard way */ cscan->scan.plan.targetlist = - fix_scan_list(root, cscan->scan.plan.targetlist, rtoffset); + fix_scan_list(root, cscan->scan.plan.targetlist, + rtoffset, NUM_EXEC_TLIST((Plan *) cscan)); cscan->scan.plan.qual = - fix_scan_list(root, cscan->scan.plan.qual, rtoffset); + fix_scan_list(root, cscan->scan.plan.qual, + rtoffset, NUM_EXEC_QUAL((Plan *) cscan)); cscan->custom_exprs = - fix_scan_list(root, cscan->custom_exprs, rtoffset); + fix_scan_list(root, cscan->custom_exprs, + rtoffset, NUM_EXEC_QUAL((Plan *) cscan)); } /* Adjust child plan-nodes recursively, if needed */ @@ -1794,7 +1916,8 @@ set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset) (Node *) hplan->hashkeys, outer_itlist, OUTER_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL(plan)); /* Hash doesn't project */ set_dummy_tlist_references(plan, rtoffset); @@ -1890,9 +2013,13 @@ fix_expr_common(PlannerInfo *root, Node *node) } else if (IsA(node, ScalarArrayOpExpr)) { - set_sa_opfuncid((ScalarArrayOpExpr *) node); - record_plan_function_dependency(root, - ((ScalarArrayOpExpr *) node)->opfuncid); + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node; + + set_sa_opfuncid(saop); + record_plan_function_dependency(root, saop->opfuncid); + + if (!OidIsValid(saop->hashfuncid)) + record_plan_function_dependency(root, saop->hashfuncid); } else if (IsA(node, Const)) { @@ -1963,6 +2090,69 @@ fix_param_node(PlannerInfo *root, Param *p) return (Node *) copyObject(p); } +/* + * fix_alternative_subplan + * Do set_plan_references processing on an AlternativeSubPlan + * + * Choose one of the alternative implementations and return just that one, + * discarding the rest of the AlternativeSubPlan structure. + * Note: caller must still recurse into the result! + * + * We don't make any attempt to fix up cost estimates in the parent plan + * node or higher-level nodes. However, we do remove the rejected subplan(s) + * from root->glob->subplans, to minimize cycles expended on them later. + */ +static Node * +fix_alternative_subplan(PlannerInfo *root, AlternativeSubPlan *asplan, + double num_exec) +{ + SubPlan *bestplan = NULL; + Cost bestcost = 0; + ListCell *lc; + + /* + * Compute the estimated cost of each subplan assuming num_exec + * executions, and keep the cheapest one. Replace discarded subplans with + * NULL pointers in the global subplans list. In event of exact equality + * of estimates, we prefer the later plan; this is a bit arbitrary, but in + * current usage it biases us to break ties against fast-start subplans. + */ + Assert(asplan->subplans != NIL); + + foreach(lc, asplan->subplans) + { + SubPlan *curplan = (SubPlan *) lfirst(lc); + Cost curcost; + + curcost = curplan->startup_cost + num_exec * curplan->per_call_cost; + if (bestplan == NULL) + { + bestplan = curplan; + bestcost = curcost; + } + else if (curcost <= bestcost) + { + /* drop old bestplan */ + ListCell *lc2 = list_nth_cell(root->glob->subplans, + bestplan->plan_id - 1); + + lfirst(lc2) = NULL; + bestplan = curplan; + bestcost = curcost; + } + else + { + /* drop curplan */ + ListCell *lc2 = list_nth_cell(root->glob->subplans, + curplan->plan_id - 1); + + lfirst(lc2) = NULL; + } + } + + return (Node *) bestplan; +} + /* * fix_scan_expr * Do set_plan_references processing on a scan-level expression @@ -1970,21 +2160,31 @@ fix_param_node(PlannerInfo *root, Param *p) * This consists of incrementing all Vars' varnos by rtoffset, * replacing PARAM_MULTIEXPR Params, expanding PlaceHolderVars, * replacing Aggref nodes that should be replaced by initplan output Params, + * choosing the best implementation for AlternativeSubPlans, * looking up operator opcode info for OpExpr and related nodes, * and adding OIDs from regclass Const nodes into root->glob->relationOids. + * + * 'node': the expression to be modified + * 'rtoffset': how much to increment varnos by + * 'num_exec': estimated number of executions of expression + * + * The expression tree is either copied-and-modified, or modified in-place + * if that seems safe. */ static Node * -fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset) +fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset, double num_exec) { fix_scan_expr_context context; context.root = root; context.rtoffset = rtoffset; + context.num_exec = num_exec; if (rtoffset != 0 || root->multiexpr_params != NIL || root->glob->lastPHId != 0 || - root->minmax_aggs != NIL) + root->minmax_aggs != NIL || + root->hasAlternativeSubPlans) { return fix_scan_expr_mutator(node, &context); } @@ -1995,7 +2195,8 @@ fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset) * are no MULTIEXPR subqueries then we don't need to replace * PARAM_MULTIEXPR Params, and if there are no placeholders anywhere * we won't need to remove them, and if there are no minmax Aggrefs we - * won't need to replace them. Then it's OK to just scribble on the + * won't need to replace them, and if there are no AlternativeSubPlans + * we won't need to remove them. Then it's OK to just scribble on the * input node tree instead of copying (since the only change, filling * in any unset opfuncid fields, is harmless). This saves just enough * cycles to be noticeable on trivial queries. @@ -2017,11 +2218,12 @@ fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context) Assert(var->varlevelsup == 0); /* - * We should not see any Vars marked INNER_VAR or OUTER_VAR. But an - * indexqual expression could contain INDEX_VAR Vars. + * We should not see Vars marked INNER_VAR, OUTER_VAR, or ROWID_VAR. + * But an indexqual expression could contain INDEX_VAR Vars. */ Assert(var->varno != INNER_VAR); Assert(var->varno != OUTER_VAR); + Assert(var->varno != ROWID_VAR); if (!IS_SPECIAL_VARNO(var->varno)) var->varno += context->rtoffset; if (var->varnosyn > 0) @@ -2069,6 +2271,11 @@ fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context) return fix_scan_expr_mutator((Node *) phv->phexpr, context); } + if (IsA(node, AlternativeSubPlan)) + return fix_scan_expr_mutator(fix_alternative_subplan(context->root, + (AlternativeSubPlan *) node, + context->num_exec), + context); fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_scan_expr_mutator, (void *) context); @@ -2079,7 +2286,9 @@ fix_scan_expr_walker(Node *node, fix_scan_expr_context *context) { if (node == NULL) return false; + Assert(!(IsA(node, Var) && ((Var *) node)->varno == ROWID_VAR)); Assert(!IsA(node, PlaceHolderVar)); + Assert(!IsA(node, AlternativeSubPlan)); fix_expr_common(context->root, node); return expression_tree_walker(node, fix_scan_expr_walker, (void *) context); @@ -2116,7 +2325,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) outer_itlist, inner_itlist, (Index) 0, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) join)); /* Now do join-type-specific stuff */ if (IsA(join, NestLoop)) @@ -2132,7 +2342,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) (Node *) nlp->paramval, outer_itlist, OUTER_VAR, - rtoffset); + rtoffset, + NUM_EXEC_TLIST(outer_plan)); /* Check we replaced any PlaceHolderVar with simple Var */ if (!(IsA(nlp->paramval, Var) && nlp->paramval->varno == OUTER_VAR)) @@ -2148,7 +2359,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) outer_itlist, inner_itlist, (Index) 0, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) join)); } else if (IsA(join, HashJoin)) { @@ -2166,7 +2378,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) outer_itlist, inner_itlist, (Index) 0, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) join)); /* * HashJoin's hashkeys are used to look for matching tuples from its * outer plan (not the Hash node!) in the hashtable. @@ -2175,7 +2388,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) (Node *) hj->hashkeys, outer_itlist, OUTER_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) join)); } /* @@ -2214,13 +2428,15 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) outer_itlist, inner_itlist, (Index) 0, - rtoffset); + rtoffset, + NUM_EXEC_TLIST((Plan *) join)); join->plan.qual = fix_join_expr(root, join->plan.qual, outer_itlist, inner_itlist, (Index) 0, - rtoffset); + rtoffset, + NUM_EXEC_QUAL((Plan *) join)); pfree(outer_itlist); pfree(inner_itlist); @@ -2273,14 +2489,16 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset) (Node *) tle->expr, subplan_itlist, OUTER_VAR, - rtoffset); + rtoffset, + NUM_EXEC_TLIST(plan)); } else newexpr = fix_upper_expr(root, (Node *) tle->expr, subplan_itlist, OUTER_VAR, - rtoffset); + rtoffset, + NUM_EXEC_TLIST(plan)); tle = flatCopyTargetEntry(tle); tle->expr = (Expr *) newexpr; output_targetlist = lappend(output_targetlist, tle); @@ -2292,7 +2510,8 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset) (Node *) plan->qual, subplan_itlist, OUTER_VAR, - rtoffset); + rtoffset, + NUM_EXEC_QUAL(plan)); pfree(subplan_itlist); } @@ -2850,6 +3069,7 @@ search_indexed_tlist_for_sortgroupref(Expr *node, * 'acceptable_rel' is either zero or the rangetable index of a relation * whose Vars may appear in the clause without provoking an error * 'rtoffset': how much to increment varnos by + * 'num_exec': estimated number of executions of expression * * Returns the new expression tree. The original clause structure is * not modified. @@ -2860,7 +3080,8 @@ fix_join_expr(PlannerInfo *root, indexed_tlist *outer_itlist, indexed_tlist *inner_itlist, Index acceptable_rel, - int rtoffset) + int rtoffset, + double num_exec) { fix_join_expr_context context; @@ -2872,6 +3093,7 @@ fix_join_expr(PlannerInfo *root, context.use_outer_tlist_for_matching_nonvars = true; context.use_inner_tlist_for_matching_nonvars = true; + context.num_exec = num_exec; return (List *) fix_join_expr_mutator((Node *) clauses, &context); } @@ -3074,6 +3296,11 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) /* Special cases (apply only AFTER failing to match to lower tlist) */ if (IsA(node, Param)) return fix_param_node(context->root, (Param *) node); + if (IsA(node, AlternativeSubPlan)) + return fix_join_expr_mutator(fix_alternative_subplan(context->root, + (AlternativeSubPlan *) node, + context->num_exec), + context); fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_join_expr_mutator, @@ -3105,6 +3332,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) * 'subplan_itlist': indexed target list for subplan (or index) * 'newvarno': varno to use for Vars referencing tlist elements * 'rtoffset': how much to increment varnos by + * 'num_exec': estimated number of executions of expression * * The resulting tree is a copy of the original in which all Var nodes have * varno = newvarno, varattno = resno of corresponding targetlist element. @@ -3115,7 +3343,8 @@ fix_upper_expr(PlannerInfo *root, Node *node, indexed_tlist *subplan_itlist, Index newvarno, - int rtoffset) + int rtoffset, + double num_exec) { fix_upper_expr_context context; @@ -3123,6 +3352,7 @@ fix_upper_expr(PlannerInfo *root, context.subplan_itlist = subplan_itlist; context.newvarno = newvarno; context.rtoffset = rtoffset; + context.num_exec = num_exec; return fix_upper_expr_mutator(node, &context); } @@ -3195,6 +3425,11 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) } /* If no match, just fall through to process it normally */ } + if (IsA(node, AlternativeSubPlan)) + return fix_upper_expr_mutator(fix_alternative_subplan(context->root, + (AlternativeSubPlan *) node, + context->num_exec), + context); fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_upper_expr_mutator, @@ -3259,7 +3494,8 @@ set_returning_clause_references(PlannerInfo *root, itlist, NULL, resultRelation, - rtoffset); + rtoffset, + NUM_EXEC_TLIST(topplan)); pfree(itlist); diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index d69075289810..daae106df0a8 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -8,7 +8,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -87,7 +87,8 @@ static List *generate_subquery_params(PlannerInfo *root, List *tlist, List **paramIds); static Node *convert_testexpr_mutator(Node *node, convert_testexpr_context *context); -static bool subplan_is_hashable(PlannerInfo *root, Plan *plan); +static bool subplan_is_hashable(Plan *plan); +static bool subpath_is_hashable(Path *path); static bool testexpr_is_hashable(Node *testexpr, List *param_ids); static bool test_opexpr_is_hashable(OpExpr *testexpr, List *param_ids); static bool hash_ok_operator(OpExpr *expr); @@ -118,7 +119,7 @@ static Bitmapset *finalize_plan(PlannerInfo *root, static bool finalize_primnode(Node *node, finalize_primnode_context *context); static bool finalize_agg_primnode(Node *node, finalize_primnode_context *context); -extern double global_work_mem(PlannerInfo *root); +extern double global_work_mem(void); static bool contain_outer_selfref_walker(Node *node, Index *depth); /* @@ -442,9 +443,18 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, * likely to be better (it depends on the expected number of executions of * the EXISTS qual, and we are much too early in planning the outer query * to be able to guess that). So we generate both plans, if possible, and - * leave it to the executor to decide which to use. - */ - if (simple_exists && IsA(result, SubPlan)) + * leave it to setrefs.c to decide which to use. + * + * GPDB: In MPP dispatch mode we don't build the hashed alternative. The + * resulting AlternativeSubPlan is not handled by the slice machinery: + * the hashed plan ends up without Flow/slice info ("subplan is missing + * Flow information"), and cdbllize cannot reason about an + * AlternativeSubPlan when pruning unused subplans. The correlated SubPlan + * we already built is correct on its own (its correlation filter is + * applied above the Motion), so we just keep it. The hashed alternative + * is still considered for non-MPP (e.g. utility-mode) planning. + */ + if (simple_exists && IsA(result, SubPlan) && Gp_role != GP_ROLE_DISPATCH) { Node *newtestexpr; List *paramIds; @@ -468,10 +478,12 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, plan_params = root->plan_params; root->plan_params = NIL; - /* Select best Path and turn it into a Plan */ + /* Select best Path */ final_rel = fetch_upper_rel(subroot, UPPERREL_FINAL, NULL); best_path = final_rel->cheapest_total_path; + /* Now we can check if it'll fit in hash_mem */ + if (subpath_is_hashable(best_path)) subroot->curSlice = palloc0(sizeof(PlanSlice)); subroot->curSlice->gangType = GANGTYPE_UNALLOCATED; @@ -481,12 +493,15 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, /* Now we can check if it'll fit in hash_mem */ /* XXX can we check this at the Path stage? */ - if (subplan_is_hashable(root, plan)) + if (subplan_is_hashable(plan)) { SubPlan *hashplan; AlternativeSubPlan *asplan; - /* OK, convert to SubPlan format. */ + /* OK, finish planning the ANY subquery */ + plan = create_plan(subroot, best_path, NULL); + + /* ... and convert to SubPlan format */ hashplan = castNode(SubPlan, build_subplan(root, plan, subroot, plan_params, @@ -498,10 +513,11 @@ make_subplan(PlannerInfo *root, Query *orig_subquery, Assert(hashplan->parParam == NIL); Assert(hashplan->useHashTable); - /* Leave it to the executor to decide which plan to use */ + /* Leave it to setrefs.c to decide which plan to use */ asplan = makeNode(AlternativeSubPlan); asplan->subplans = list_make2(result, hashplan); result = (Node *) asplan; + root->hasAlternativeSubPlans = true; } } } @@ -739,7 +755,7 @@ build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot, */ if (subLinkType == ANY_SUBLINK && splan->parParam == NIL && - subplan_is_hashable(root, plan) && + subplan_is_hashable(plan) && testexpr_is_hashable(splan->testexpr, splan->paramIds)) splan->useHashTable = true; @@ -941,9 +957,12 @@ convert_testexpr_mutator(Node *node, /* * subplan_is_hashable: can we implement an ANY subplan by hashing? + * + * This is not responsible for checking whether the combining testexpr + * is suitable for hashing. We only look at the subquery itself. */ static bool -subplan_is_hashable(PlannerInfo *root, Plan *plan) +subplan_is_hashable(Plan *plan) { double subquery_size; @@ -955,7 +974,32 @@ subplan_is_hashable(PlannerInfo *root, Plan *plan) */ subquery_size = plan->plan_rows * (MAXALIGN(plan->plan_width) + MAXALIGN(SizeofHeapTupleHeader)); - if (subquery_size > global_work_mem(root)) + if (subquery_size > global_work_mem()) + return false; + + return true; +} + +/* + * subpath_is_hashable: can we implement an ANY subplan by hashing? + * + * Identical to subplan_is_hashable, but work from a Path for the subplan. + */ +static bool +subpath_is_hashable(Path *path) +{ + double subquery_size; + int hash_mem = get_hash_mem(); + + /* + * The estimated size of the subquery result must fit in hash_mem. (Note: + * we use heap tuple overhead here even though the tuples will actually be + * stored as MinimalTuples; this provides some fudge factor for hashtable + * overhead.) + */ + subquery_size = path->rows * + (MAXALIGN(path->pathtarget->width) + MAXALIGN(SizeofHeapTupleHeader)); + if (subquery_size > hash_mem * 1024L) return false; return true; @@ -1542,7 +1586,7 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, * else it's not gonna be a join. (Note that it won't have Vars * referring to the subquery, rather Params.) */ - upper_varnos = pull_varnos(sublink->testexpr); + upper_varnos = pull_varnos(root, sublink->testexpr); if (bms_is_empty(upper_varnos)) return NULL; @@ -1605,6 +1649,7 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, result->larg = NULL; /* caller must fill this in */ result->rarg = (Node *) rtr; result->usingClause = NIL; + result->join_using_alias = NULL; result->quals = quals; result->alias = NULL; result->rtindex = 0; @@ -1726,7 +1771,7 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, * The ones <= rtoffset belong to the upper query; the ones > rtoffset do * not. */ - clause_varnos = pull_varnos(whereClause); + clause_varnos = pull_varnos(root, whereClause); upper_varnos = NULL; while ((varno = bms_first_member(clause_varnos)) >= 0) { @@ -1759,6 +1804,7 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, else result->rarg = (Node *) subselect->jointree; result->usingClause = NIL; + result->join_using_alias = NULL; result->quals = whereClause; result->alias = NULL; result->rtindex = 0; /* we don't need an RTE for it */ @@ -2779,6 +2825,12 @@ finalize_plan(PlannerInfo *root, Plan *plan, context.paramids = bms_add_members(context.paramids, scan_params); break; + case T_TidRangeScan: + finalize_primnode((Node *) ((TidRangeScan *) plan)->tidrangequals, + &context); + context.paramids = bms_add_members(context.paramids, scan_params); + break; + case T_SubqueryScan: { SubqueryScan *sscan = (SubqueryScan *) plan; @@ -2961,7 +3013,6 @@ finalize_plan(PlannerInfo *root, Plan *plan, case T_ModifyTable: { ModifyTable *mtplan = (ModifyTable *) plan; - ListCell *l; /* Force descendant scan nodes to reference epqParam */ locally_added_param = mtplan->epqParam; @@ -2976,16 +3027,6 @@ finalize_plan(PlannerInfo *root, Plan *plan, finalize_primnode((Node *) mtplan->onConflictWhere, &context); /* exclRelTlist contains only Vars, doesn't need examination */ - foreach(l, mtplan->plans) - { - context.paramids = - bms_add_members(context.paramids, - finalize_plan(root, - (Plan *) lfirst(l), - gather_param, - valid_params, - scan_params)); - } } break; @@ -3210,6 +3251,11 @@ finalize_plan(PlannerInfo *root, Plan *plan, /* rescan_param does *not* get added to scan_params */ break; + case T_ResultCache: + finalize_primnode((Node *) ((ResultCache *) plan)->param_exprs, + &context); + break; + case T_ProjectSet: case T_Hash: case T_Material: diff --git a/src/backend/optimizer/plan/transform.c b/src/backend/optimizer/plan/transform.c index bedf15703ff7..5f6185e0e7bf 100644 --- a/src/backend/optimizer/plan/transform.c +++ b/src/backend/optimizer/plan/transform.c @@ -213,7 +213,7 @@ is_sirv_funcexpr(FuncExpr *fe) if (fe->funcresulttype == RECORDOID) return false; /* Record types cannot be handled currently */ - if (fe->funcid == F_NEXTVAL_OID || fe->funcid == F_CURRVAL_OID || fe-> funcid == F_SETVAL_OID) + if (fe->funcid == 1574 || fe->funcid == 1575 || fe->funcid == 1576) return false; /* Function cannot be sequence related */ return true; diff --git a/src/backend/optimizer/prep/Makefile b/src/backend/optimizer/prep/Makefile index 5733df45737a..6f8c6c8208b3 100644 --- a/src/backend/optimizer/prep/Makefile +++ b/src/backend/optimizer/prep/Makefile @@ -13,6 +13,7 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = \ + prepagg.o \ prepjointree.o \ prepqual.o \ preptlist.o \ diff --git a/src/backend/optimizer/prep/prepagg.c b/src/backend/optimizer/prep/prepagg.c new file mode 100644 index 000000000000..96ee8077721f --- /dev/null +++ b/src/backend/optimizer/prep/prepagg.c @@ -0,0 +1,727 @@ +/*------------------------------------------------------------------------- + * + * prepagg.c + * Routines to preprocess aggregate function calls + * + * If there are identical aggregate calls in the query, they only need to + * be computed once. Also, some aggregate functions can share the same + * transition state, so that we only need to call the final function for + * them separately. These optimizations are independent of how the + * aggregates are executed. + * + * preprocess_aggrefs() detects those cases, creates AggInfo and + * AggTransInfo structs for each aggregate and transition state that needs + * to be computed, and sets the 'aggno' and 'transno' fields in the Aggrefs + * accordingly. It also resolves polymorphic transition types, and sets + * the 'aggtranstype' fields accordingly. + * + * XXX: The AggInfo and AggTransInfo structs are thrown away after + * planning, so executor startup has to perform some of the same lookups + * of transition functions and initial values that we do here. One day, we + * might want to carry that information to the Agg nodes to save the effort + * at executor startup. The Agg nodes are constructed much later in the + * planning, however, so it's not trivial. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/optimizer/prep/prepagg.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/htup_details.h" +#include "catalog/pg_aggregate.h" +#include "catalog/pg_type.h" +#include "nodes/nodeFuncs.h" +#include "nodes/pathnodes.h" +#include "optimizer/clauses.h" +#include "optimizer/cost.h" +#include "optimizer/optimizer.h" +#include "optimizer/plancat.h" +#include "optimizer/prep.h" +#include "parser/parse_agg.h" +#include "utils/builtins.h" +#include "utils/datum.h" +#include "utils/fmgroids.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/syscache.h" + +static bool preprocess_aggrefs_walker(Node *node, PlannerInfo *root); +static int find_compatible_agg(PlannerInfo *root, Aggref *newagg, + List **same_input_transnos); +static int find_compatible_trans(PlannerInfo *root, Aggref *newagg, + bool shareable, + Oid aggtransfn, Oid aggtranstype, + int transtypeLen, bool transtypeByVal, + Oid aggcombinefn, + Oid aggserialfn, Oid aggdeserialfn, + Datum initValue, bool initValueIsNull, + List *transnos); +static Datum GetAggInitVal(Datum textInitVal, Oid transtype); + +/* ----------------- + * Resolve the transition type of all Aggrefs, and determine which Aggrefs + * can share aggregate or transition state. + * + * Information about the aggregates and transition functions are collected + * in the root->agginfos and root->aggtransinfos lists. The 'aggtranstype', + * 'aggno', and 'aggtransno' fields of each Aggref are filled in. + * + * NOTE: This modifies the Aggrefs in the input expression in-place! + * + * We try to optimize by detecting duplicate aggregate functions so that + * their state and final values are re-used, rather than needlessly being + * re-calculated independently. We also detect aggregates that are not + * the same, but which can share the same transition state. + * + * Scenarios: + * + * 1. Identical aggregate function calls appear in the query: + * + * SELECT SUM(x) FROM ... HAVING SUM(x) > 0 + * + * Since these aggregates are identical, we only need to calculate + * the value once. Both aggregates will share the same 'aggno' value. + * + * 2. Two different aggregate functions appear in the query, but the + * aggregates have the same arguments, transition functions and + * initial values (and, presumably, different final functions): + * + * SELECT AVG(x), STDDEV(x) FROM ... + * + * In this case we must create a new AggInfo for the varying aggregate, + * and we need to call the final functions separately, but we need + * only run the transition function once. (This requires that the + * final functions be nondestructive of the transition state, but + * that's required anyway for other reasons.) + * + * For either of these optimizations to be valid, all aggregate properties + * used in the transition phase must be the same, including any modifiers + * such as ORDER BY, DISTINCT and FILTER, and the arguments mustn't + * contain any volatile functions. + * ----------------- + */ +void +preprocess_aggrefs(PlannerInfo *root, Node *clause) +{ + (void) preprocess_aggrefs_walker(clause, root); +} + +static void +preprocess_aggref(Aggref *aggref, PlannerInfo *root) +{ + HeapTuple aggTuple; + Form_pg_aggregate aggform; + Oid aggtransfn; + Oid aggfinalfn; + Oid aggcombinefn; + Oid aggserialfn; + Oid aggdeserialfn; + Oid aggtranstype; + int32 aggtranstypmod; + int32 aggtransspace; + bool shareable; + int aggno; + int transno; + List *same_input_transnos; + int16 resulttypeLen; + bool resulttypeByVal; + Datum textInitVal; + Datum initValue; + bool initValueIsNull; + bool transtypeByVal; + int16 transtypeLen; + Oid inputTypes[FUNC_MAX_ARGS]; + int numArguments; + + Assert(aggref->agglevelsup == 0); + + /* + * Fetch info about the aggregate from pg_aggregate. Note it's correct to + * ignore the moving-aggregate variant, since what we're concerned with + * here is aggregates not window functions. + */ + aggTuple = SearchSysCache1(AGGFNOID, + ObjectIdGetDatum(aggref->aggfnoid)); + if (!HeapTupleIsValid(aggTuple)) + elog(ERROR, "cache lookup failed for aggregate %u", + aggref->aggfnoid); + aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple); + aggtransfn = aggform->aggtransfn; + aggfinalfn = aggform->aggfinalfn; + aggcombinefn = aggform->aggcombinefn; + aggserialfn = aggform->aggserialfn; + aggdeserialfn = aggform->aggdeserialfn; + aggtranstype = aggform->aggtranstype; + aggtransspace = aggform->aggtransspace; + + /* + * Resolve the possibly-polymorphic aggregate transition type. + */ + + /* extract argument types (ignoring any ORDER BY expressions) */ + numArguments = get_aggregate_argtypes(aggref, inputTypes); + + /* resolve actual type of transition state, if polymorphic */ + aggtranstype = resolve_aggregate_transtype(aggref->aggfnoid, + aggtranstype, + inputTypes, + numArguments); + aggref->aggtranstype = aggtranstype; + + /* + * If transition state is of same type as first aggregated input, assume + * it's the same typmod (same width) as well. This works for cases like + * MAX/MIN and is probably somewhat reasonable otherwise. + */ + aggtranstypmod = -1; + if (aggref->args) + { + TargetEntry *tle = (TargetEntry *) linitial(aggref->args); + + if (aggtranstype == exprType((Node *) tle->expr)) + aggtranstypmod = exprTypmod((Node *) tle->expr); + } + + /* + * If finalfn is marked read-write, we can't share transition states; but + * it is okay to share states for AGGMODIFY_SHAREABLE aggs. + * + * In principle, in a partial aggregate, we could share the transition + * state even if the final function is marked as read-write, because the + * partial aggregate doesn't execute the final function. But it's too + * early to know whether we're going perform a partial aggregate. + */ + shareable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE); + + /* get info about the output value's datatype */ + get_typlenbyval(aggref->aggtype, + &resulttypeLen, + &resulttypeByVal); + + /* get initial value */ + textInitVal = SysCacheGetAttr(AGGFNOID, aggTuple, + Anum_pg_aggregate_agginitval, + &initValueIsNull); + if (initValueIsNull) + initValue = (Datum) 0; + else + initValue = GetAggInitVal(textInitVal, aggtranstype); + + ReleaseSysCache(aggTuple); + + /* + * 1. See if this is identical to another aggregate function call that + * we've seen already. + */ + aggno = find_compatible_agg(root, aggref, &same_input_transnos); + if (aggno != -1) + { + AggInfo *agginfo = list_nth(root->agginfos, aggno); + + transno = agginfo->transno; + } + else + { + AggInfo *agginfo = palloc(sizeof(AggInfo)); + + agginfo->finalfn_oid = aggfinalfn; + agginfo->representative_aggref = aggref; + agginfo->shareable = shareable; + + aggno = list_length(root->agginfos); + root->agginfos = lappend(root->agginfos, agginfo); + + /* + * Count it, and check for cases requiring ordered input. Note that + * ordered-set aggs always have nonempty aggorder. Any ordered-input + * case also defeats partial aggregation. + */ + if (aggref->aggorder != NIL || aggref->aggdistinct != NIL) + { + root->numOrderedAggs++; + root->hasNonPartialAggs = true; + } + + get_typlenbyval(aggtranstype, + &transtypeLen, + &transtypeByVal); + + /* + * 2. See if this aggregate can share transition state with another + * aggregate that we've initialized already. + */ + transno = find_compatible_trans(root, aggref, shareable, + aggtransfn, aggtranstype, + transtypeLen, transtypeByVal, + aggcombinefn, + aggserialfn, aggdeserialfn, + initValue, initValueIsNull, + same_input_transnos); + if (transno == -1) + { + AggTransInfo *transinfo = palloc(sizeof(AggTransInfo)); + + transinfo->args = aggref->args; + transinfo->aggfilter = aggref->aggfilter; + transinfo->transfn_oid = aggtransfn; + transinfo->combinefn_oid = aggcombinefn; + transinfo->serialfn_oid = aggserialfn; + transinfo->deserialfn_oid = aggdeserialfn; + transinfo->aggtranstype = aggtranstype; + transinfo->aggtranstypmod = aggtranstypmod; + transinfo->transtypeLen = transtypeLen; + transinfo->transtypeByVal = transtypeByVal; + transinfo->aggtransspace = aggtransspace; + transinfo->initValue = initValue; + transinfo->initValueIsNull = initValueIsNull; + + transno = list_length(root->aggtransinfos); + root->aggtransinfos = lappend(root->aggtransinfos, transinfo); + + /* + * Check whether partial aggregation is feasible, unless we + * already found out that we can't do it. + */ + if (!root->hasNonPartialAggs) + { + /* + * If there is no combine function, then partial aggregation + * is not possible. + */ + if (!OidIsValid(transinfo->combinefn_oid)) + root->hasNonPartialAggs = true; + + /* + * If we have any aggs with transtype INTERNAL then we must + * check whether they have serialization/deserialization + * functions; if not, we can't serialize partial-aggregation + * results. + */ + else if (transinfo->aggtranstype == INTERNALOID && + (!OidIsValid(transinfo->serialfn_oid) || + !OidIsValid(transinfo->deserialfn_oid))) + root->hasNonSerialAggs = true; + } + } + agginfo->transno = transno; + } + + /* + * Fill in the fields in the Aggref (aggtranstype was set above already) + */ + aggref->aggno = aggno; + aggref->aggtransno = transno; +} + +static bool +preprocess_aggrefs_walker(Node *node, PlannerInfo *root) +{ + if (node == NULL) + return false; + if (IsA(node, Aggref)) + { + Aggref *aggref = (Aggref *) node; + + preprocess_aggref(aggref, root); + + /* + * We assume that the parser checked that there are no aggregates (of + * this level anyway) in the aggregated arguments, direct arguments, + * or filter clause. Hence, we need not recurse into any of them. + */ + return false; + } + Assert(!IsA(node, SubLink)); + return expression_tree_walker(node, preprocess_aggrefs_walker, + (void *) root); +} + + +/* + * find_compatible_agg - search for a previously initialized per-Agg struct + * + * Searches the previously looked at aggregates to find one which is compatible + * with this one, with the same input parameters. If no compatible aggregate + * can be found, returns -1. + * + * As a side-effect, this also collects a list of existing, shareable per-Trans + * structs with matching inputs. If no identical Aggref is found, the list is + * passed later to find_compatible_trans, to see if we can at least reuse + * the state value of another aggregate. + */ +static int +find_compatible_agg(PlannerInfo *root, Aggref *newagg, + List **same_input_transnos) +{ + ListCell *lc; + int aggno; + + *same_input_transnos = NIL; + + /* we mustn't reuse the aggref if it contains volatile function calls */ + if (contain_volatile_functions((Node *) newagg)) + return -1; + + /* + * Search through the list of already seen aggregates. If we find an + * existing identical aggregate call, then we can re-use that one. While + * searching, we'll also collect a list of Aggrefs with the same input + * parameters. If no matching Aggref is found, the caller can potentially + * still re-use the transition state of one of them. (At this stage we + * just compare the parsetrees; whether different aggregates share the + * same transition function will be checked later.) + */ + aggno = -1; + foreach(lc, root->agginfos) + { + AggInfo *agginfo = (AggInfo *) lfirst(lc); + Aggref *existingRef; + + aggno++; + + existingRef = agginfo->representative_aggref; + + /* all of the following must be the same or it's no match */ + if (newagg->inputcollid != existingRef->inputcollid || + newagg->aggtranstype != existingRef->aggtranstype || + newagg->aggstar != existingRef->aggstar || + newagg->aggvariadic != existingRef->aggvariadic || + newagg->aggkind != existingRef->aggkind || + !equal(newagg->args, existingRef->args) || + !equal(newagg->aggorder, existingRef->aggorder) || + !equal(newagg->aggdistinct, existingRef->aggdistinct) || + !equal(newagg->aggfilter, existingRef->aggfilter)) + continue; + + /* if it's the same aggregate function then report exact match */ + if (newagg->aggfnoid == existingRef->aggfnoid && + newagg->aggtype == existingRef->aggtype && + newagg->aggcollid == existingRef->aggcollid && + equal(newagg->aggdirectargs, existingRef->aggdirectargs)) + { + list_free(*same_input_transnos); + *same_input_transnos = NIL; + return aggno; + } + + /* + * Not identical, but it had the same inputs. If the final function + * permits sharing, return its transno to the caller, in case we can + * re-use its per-trans state. (If there's already sharing going on, + * we might report a transno more than once. find_compatible_trans is + * cheap enough that it's not worth spending cycles to avoid that.) + */ + if (agginfo->shareable) + *same_input_transnos = lappend_int(*same_input_transnos, + agginfo->transno); + } + + return -1; +} + +/* + * find_compatible_trans - search for a previously initialized per-Trans + * struct + * + * Searches the list of transnos for a per-Trans struct with the same + * transition function and initial condition. (The inputs have already been + * verified to match.) + */ +static int +find_compatible_trans(PlannerInfo *root, Aggref *newagg, bool shareable, + Oid aggtransfn, Oid aggtranstype, + int transtypeLen, bool transtypeByVal, + Oid aggcombinefn, + Oid aggserialfn, Oid aggdeserialfn, + Datum initValue, bool initValueIsNull, + List *transnos) +{ + ListCell *lc; + + /* If this aggregate can't share transition states, give up */ + if (!shareable) + return -1; + + foreach(lc, transnos) + { + int transno = lfirst_int(lc); + AggTransInfo *pertrans = (AggTransInfo *) list_nth(root->aggtransinfos, transno); + + /* + * if the transfns or transition state types are not the same then the + * state can't be shared. + */ + if (aggtransfn != pertrans->transfn_oid || + aggtranstype != pertrans->aggtranstype) + continue; + + /* + * The serialization and deserialization functions must match, if + * present, as we're unable to share the trans state for aggregates + * which will serialize or deserialize into different formats. + * Remember that these will be InvalidOid if they're not required for + * this agg node. + */ + if (aggserialfn != pertrans->serialfn_oid || + aggdeserialfn != pertrans->deserialfn_oid) + continue; + + /* + * Combine function must also match. We only care about the combine + * function with partial aggregates, but it's too early in the + * planning to know if we will do partial aggregation, so be + * conservative. + */ + if (aggcombinefn != pertrans->combinefn_oid) + continue; + + /* + * Check that the initial condition matches, too. + */ + if (initValueIsNull && pertrans->initValueIsNull) + return transno; + + if (!initValueIsNull && !pertrans->initValueIsNull && + datumIsEqual(initValue, pertrans->initValue, + transtypeByVal, transtypeLen)) + return transno; + } + return -1; +} + +static Datum +GetAggInitVal(Datum textInitVal, Oid transtype) +{ + Oid typinput, + typioparam; + char *strInitVal; + Datum initVal; + + getTypeInputInfo(transtype, &typinput, &typioparam); + strInitVal = TextDatumGetCString(textInitVal); + initVal = OidInputFunctionCall(typinput, strInitVal, + typioparam, -1); + pfree(strInitVal); + return initVal; +} + + +/* + * get_agg_clause_costs + * Recursively find the Aggref nodes in an expression tree, and + * accumulate cost information about them. + * + * 'aggsplit' tells us the expected partial-aggregation mode, which affects + * the cost estimates. + * + * NOTE that the counts/costs are ADDED to those already in *costs ... so + * the caller is responsible for zeroing the struct initially. + * + * We count the nodes, estimate their execution costs, and estimate the total + * space needed for their transition state values if all are evaluated in + * parallel (as would be done in a HashAgg plan). Also, we check whether + * partial aggregation is feasible. See AggClauseCosts for the exact set + * of statistics collected. + * + * In addition, we mark Aggref nodes with the correct aggtranstype, so + * that that doesn't need to be done repeatedly. (That makes this function's + * name a bit of a misnomer.) + * + * This does not descend into subqueries, and so should be used only after + * reduction of sublinks to subplans, or in contexts where it's known there + * are no subqueries. There mustn't be outer-aggregate references either. + */ +void +get_agg_clause_costs(PlannerInfo *root, AggSplit aggsplit, AggClauseCosts *costs) +{ + ListCell *lc; + + foreach(lc, root->aggtransinfos) + { + AggTransInfo *transinfo = (AggTransInfo *) lfirst(lc); + + /* + * GPDB: Record whether any aggregate cannot be combined, or (for an + * INTERNAL transition state) cannot be serialized. The MPP planner + * consults these flags (AggClauseCosts.hasNonCombine / hasNonSerial) + * to decide whether it may split aggregation into multiple stages with + * a Motion in between. Splitting an aggregate that lacks a combine or + * serialization function would reference function OID 0 and fail with + * "cache lookup failed for function 0" (e.g. string_agg). This mirrors + * the root->hasNonPartialAggs / root->hasNonSerialAggs bookkeeping done + * when the transinfos are first built. + */ + if (!OidIsValid(transinfo->combinefn_oid)) + costs->hasNonCombine = true; + else if (transinfo->aggtranstype == INTERNALOID && + (!OidIsValid(transinfo->serialfn_oid) || + !OidIsValid(transinfo->deserialfn_oid))) + costs->hasNonSerial = true; + + /* + * Add the appropriate component function execution costs to + * appropriate totals. + */ + if (DO_AGGSPLIT_COMBINE(aggsplit)) + { + /* charge for combining previously aggregated states */ + add_function_cost(root, transinfo->combinefn_oid, NULL, + &costs->transCost); + } + else + add_function_cost(root, transinfo->transfn_oid, NULL, + &costs->transCost); + if (DO_AGGSPLIT_DESERIALIZE(aggsplit) && + OidIsValid(transinfo->deserialfn_oid)) + add_function_cost(root, transinfo->deserialfn_oid, NULL, + &costs->transCost); + if (DO_AGGSPLIT_SERIALIZE(aggsplit) && + OidIsValid(transinfo->serialfn_oid)) + add_function_cost(root, transinfo->serialfn_oid, NULL, + &costs->finalCost); + + /* + * These costs are incurred only by the initial aggregate node, so we + * mustn't include them again at upper levels. + */ + if (!DO_AGGSPLIT_COMBINE(aggsplit)) + { + /* add the input expressions' cost to per-input-row costs */ + QualCost argcosts; + + cost_qual_eval_node(&argcosts, (Node *) transinfo->args, root); + costs->transCost.startup += argcosts.startup; + costs->transCost.per_tuple += argcosts.per_tuple; + + /* + * Add any filter's cost to per-input-row costs. + * + * XXX Ideally we should reduce input expression costs according + * to filter selectivity, but it's not clear it's worth the + * trouble. + */ + if (transinfo->aggfilter) + { + cost_qual_eval_node(&argcosts, (Node *) transinfo->aggfilter, + root); + costs->transCost.startup += argcosts.startup; + costs->transCost.per_tuple += argcosts.per_tuple; + } + } + + /* + * If the transition type is pass-by-value then it doesn't add + * anything to the required size of the hashtable. If it is + * pass-by-reference then we have to add the estimated size of the + * value itself, plus palloc overhead. + */ + if (!transinfo->transtypeByVal) + { + int32 avgwidth; + + /* Use average width if aggregate definition gave one */ + if (transinfo->aggtransspace > 0) + avgwidth = transinfo->aggtransspace; + else if (transinfo->transfn_oid == F_ARRAY_APPEND) + { + /* + * If the transition function is array_append(), it'll use an + * expanded array as transvalue, which will occupy at least + * ALLOCSET_SMALL_INITSIZE and possibly more. Use that as the + * estimate for lack of a better idea. + */ + avgwidth = ALLOCSET_SMALL_INITSIZE; + } + else + { + avgwidth = get_typavgwidth(transinfo->aggtranstype, transinfo->aggtranstypmod); + } + + avgwidth = MAXALIGN(avgwidth); + costs->transitionSpace += avgwidth + 2 * sizeof(void *); + } + else if (transinfo->aggtranstype == INTERNALOID) + { + /* + * INTERNAL transition type is a special case: although INTERNAL + * is pass-by-value, it's almost certainly being used as a pointer + * to some large data structure. The aggregate definition can + * provide an estimate of the size. If it doesn't, then we assume + * ALLOCSET_DEFAULT_INITSIZE, which is a good guess if the data is + * being kept in a private memory context, as is done by + * array_agg() for instance. + */ + if (transinfo->aggtransspace > 0) + costs->transitionSpace += transinfo->aggtransspace; + else + costs->transitionSpace += ALLOCSET_DEFAULT_INITSIZE; + } + } + + foreach(lc, root->agginfos) + { + AggInfo *agginfo = (AggInfo *) lfirst(lc); + Aggref *aggref = agginfo->representative_aggref; + + /* + * GPDB: Count aggregates that require ordered input. numPureOrderedAggs + * counts those with an explicit ORDER BY / WITHIN GROUP: their result + * depends on the global input order, so they cannot be split into + * multiple aggregation stages with a Motion in between. numOrderedAggs + * additionally includes DISTINCT aggregates (which the MPP planner can + * still multi-stage via the DQA path). The MPP grouping planner relies + * on these counts (cdb_create_multistage_grouping_paths' has_ordered_aggs + * gate, GROUPING_CAN_USE_MPP_HASH); without them an ORDER BY aggregate + * such as array_agg(x ORDER BY x) was wrongly routed into a multi-stage + * plan and failed with "ORDER/GROUP BY expression not found in + * targetlist". + */ + if (aggref->aggorder != NIL || aggref->aggdistinct != NIL) + costs->numOrderedAggs++; + if (aggref->aggorder != NIL) + costs->numPureOrderedAggs++; + + /* + * GPDB: Remember the DISTINCT-qualified aggregates. The MPP grouping + * planner uses this list (cdb_create_multistage_grouping_paths -> + * recognize_dqa_type) to build the specialized DQA multi-stage paths, + * which dedup the DISTINCT argument by adding it to the first-stage + * group key. Without this list the DQA paths are never generated and a + * DISTINCT aggregate falls through to the generic two-stage partial + * aggregation, which cannot partialize a DISTINCT aggregate and crashes + * in finalize_aggregates()/tuplesort_performsort() on the segments. + */ + if (aggref->aggdistinct != NIL) + costs->distinctAggrefs = lappend(costs->distinctAggrefs, aggref); + + /* + * Add the appropriate component function execution costs to + * appropriate totals. + */ + if (!DO_AGGSPLIT_SKIPFINAL(aggsplit) && + OidIsValid(agginfo->finalfn_oid)) + add_function_cost(root, agginfo->finalfn_oid, NULL, + &costs->finalCost); + + /* + * If there are direct arguments, treat their evaluation cost like the + * cost of the finalfn. + */ + if (aggref->aggdirectargs) + { + QualCost argcosts; + + cost_qual_eval_node(&argcosts, (Node *) aggref->aggdirectargs, + root); + costs->finalCost.startup += argcosts.startup; + costs->finalCost.per_tuple += argcosts.per_tuple; + } + } +} diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 51dd538672c3..21bae47e6999 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -16,7 +16,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -88,6 +88,9 @@ static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int childRToffset); static void make_setop_translation_list(Query *query, Index newvarno, AppendRelInfo *appinfo); +bool is_simple_subquery(PlannerInfo *root, Query *subquery, + RangeTblEntry *rte, + JoinExpr *lowest_outer_join); static Node *pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte); static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte); @@ -99,7 +102,8 @@ static bool is_simple_union_all(Query *subquery); static bool is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes); static bool is_safe_append_member(Query *subquery); -static bool jointree_contains_lateral_outer_refs(Node *jtnode, bool restricted, +static bool jointree_contains_lateral_outer_refs(PlannerInfo *root, + Node *jtnode, bool restricted, Relids safe_upper_varnos); static void perform_pullup_replace_vars(PlannerInfo *root, pullup_replace_vars_context *rvcontext, @@ -1085,15 +1089,18 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, subroot->eq_classes = NIL; subroot->ec_merging_done = false; subroot->non_eq_clauses = NIL; + subroot->all_result_relids = NULL; + subroot->leaf_result_relids = NULL; subroot->append_rel_list = NIL; + subroot->row_identity_vars = NIL; subroot->rowMarks = NIL; memset(subroot->upper_rels, 0, sizeof(subroot->upper_rels)); memset(subroot->upper_targets, 0, sizeof(subroot->upper_targets)); subroot->processed_tlist = NIL; + subroot->update_colnos = NIL; subroot->grouping_map = NULL; subroot->minmax_aggs = NIL; subroot->qual_security_level = 0; - subroot->inhTargetKind = INHKIND_NONE; subroot->hasRecursion = false; subroot->wt_param_id = -1; subroot->non_recursive_path = NULL; @@ -1667,7 +1674,8 @@ is_simple_subquery(PlannerInfo *root, Query *subquery, RangeTblEntry *rte, safe_upper_varnos = NULL; /* doesn't matter */ } - if (jointree_contains_lateral_outer_refs((Node *) subquery->jointree, + if (jointree_contains_lateral_outer_refs(root, + (Node *) subquery->jointree, restricted, safe_upper_varnos)) return false; @@ -1686,7 +1694,9 @@ is_simple_subquery(PlannerInfo *root, Query *subquery, RangeTblEntry *rte, */ if (lowest_outer_join != NULL) { - Relids lvarnos = pull_varnos_of_level((Node *) subquery->targetList, 1); + Relids lvarnos = pull_varnos_of_level(root, + (Node *) subquery->targetList, + 1); if (!bms_is_subset(lvarnos, safe_upper_varnos)) return false; @@ -2119,7 +2129,8 @@ is_safe_append_member(Query *subquery) * in safe_upper_varnos. */ static bool -jointree_contains_lateral_outer_refs(Node *jtnode, bool restricted, +jointree_contains_lateral_outer_refs(PlannerInfo *root, Node *jtnode, + bool restricted, Relids safe_upper_varnos) { if (jtnode == NULL) @@ -2134,7 +2145,8 @@ jointree_contains_lateral_outer_refs(Node *jtnode, bool restricted, /* First, recurse to check child joins */ foreach(l, f->fromlist) { - if (jointree_contains_lateral_outer_refs(lfirst(l), + if (jointree_contains_lateral_outer_refs(root, + lfirst(l), restricted, safe_upper_varnos)) return true; @@ -2142,7 +2154,7 @@ jointree_contains_lateral_outer_refs(Node *jtnode, bool restricted, /* Then check the top-level quals */ if (restricted && - !bms_is_subset(pull_varnos_of_level(f->quals, 1), + !bms_is_subset(pull_varnos_of_level(root, f->quals, 1), safe_upper_varnos)) return true; } @@ -2161,18 +2173,20 @@ jointree_contains_lateral_outer_refs(Node *jtnode, bool restricted, } /* Check the child joins */ - if (jointree_contains_lateral_outer_refs(j->larg, + if (jointree_contains_lateral_outer_refs(root, + j->larg, restricted, safe_upper_varnos)) return true; - if (jointree_contains_lateral_outer_refs(j->rarg, + if (jointree_contains_lateral_outer_refs(root, + j->rarg, restricted, safe_upper_varnos)) return true; /* Check the JOIN's qual clauses */ if (restricted && - !bms_is_subset(pull_varnos_of_level(j->quals, 1), + !bms_is_subset(pull_varnos_of_level(root, j->quals, 1), safe_upper_varnos)) return true; } @@ -2599,7 +2613,8 @@ pullup_replace_vars_callback(Var *var, * level-zero var must belong to the subquery. */ if ((rcon->target_rte->lateral ? - bms_overlap(pull_varnos((Node *) newnode), rcon->relids) : + bms_overlap(pull_varnos(rcon->root, (Node *) newnode), + rcon->relids) : contain_vars_of_level((Node *) newnode, 0)) && !contain_nonstrict_functions((Node *) newnode)) { @@ -3038,7 +3053,7 @@ reduce_outer_joins_pass2(Node *jtnode, overlap = list_intersection(local_nonnullable_vars, forced_null_vars); if (overlap != NIL && - bms_overlap(pull_varnos((Node *) overlap), + bms_overlap(pull_varnos(root, (Node *) overlap), right_state->relids)) jointype = JOIN_ANTI; } @@ -3495,6 +3510,7 @@ remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc) subrelids = get_relids_in_jointree(newjtloc, false); Assert(!bms_is_empty(subrelids)); substitute_phv_relids((Node *) root->parse, varno, subrelids); + fix_append_rel_relids(root->append_rel_list, varno, subrelids); } /* diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c index 391bdd659d25..42c3e4dc0464 100644 --- a/src/backend/optimizer/prep/prepqual.c +++ b/src/backend/optimizer/prep/prepqual.c @@ -19,7 +19,7 @@ * tree after local transformations that might introduce nested AND/ORs. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -127,6 +127,7 @@ negate_clause(Node *node) newopexpr->opno = negator; newopexpr->opfuncid = InvalidOid; + newopexpr->hashfuncid = InvalidOid; newopexpr->useOr = !saopexpr->useOr; newopexpr->inputcollid = saopexpr->inputcollid; newopexpr->args = saopexpr->args; diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index b86744ad5586..ff1243b1fa0d 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -3,35 +3,31 @@ * preptlist.c * Routines to preprocess the parse tree target list * - * For INSERT and UPDATE queries, the targetlist must contain an entry for - * each attribute of the target relation in the correct order. For UPDATE and - * DELETE queries, it must also contain junk tlist entries needed to allow the - * executor to identify the rows to be updated or deleted. For all query - * types, we may need to add junk tlist entries for Vars used in the RETURNING - * list and row ID information needed for SELECT FOR UPDATE locking and/or - * EvalPlanQual checking. + * For an INSERT, the targetlist must contain an entry for each attribute of + * the target relation in the correct order. + * + * For an UPDATE, the targetlist just contains the expressions for the new + * column values. + * + * For UPDATE and DELETE queries, the targetlist must also contain "junk" + * tlist entries needed to allow the executor to identify the rows to be + * updated or deleted; for example, the ctid of a heap row. (The planner + * adds these; they're not in what we receive from the planner/rewriter.) + * + * For all query types, there can be additional junk tlist entries, such as + * sort keys, Vars needed for a RETURNING list, and row ID information needed + * for SELECT FOR UPDATE locking and/or EvalPlanQual checking. * * The query rewrite phase also does preprocessing of the targetlist (see * rewriteTargetListIU). The division of labor between here and there is - * partially historical, but it's not entirely arbitrary. In particular, - * consider an UPDATE across an inheritance tree. What rewriteTargetListIU - * does need be done only once (because it depends only on the properties of - * the parent relation). What's done here has to be done over again for each - * child relation, because it depends on the properties of the child, which - * might be of a different relation type, or have more columns and/or a - * different column order than the parent. - * - * The fact that rewriteTargetListIU sorts non-resjunk tlist entries by column - * position, which expand_targetlist depends on, violates the above comment - * because the sorting is only valid for the parent relation. In inherited - * UPDATE cases, adjust_inherited_tlist runs in between to take care of fixing - * the tlists for child tables to keep expand_targetlist happy. We do it like - * that because it's faster in typical non-inherited cases. + * partially historical, but it's not entirely arbitrary. The stuff done + * here is closely connected to physical access to tables, whereas the + * rewriter's work is more concerned with SQL semantics. * * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -42,41 +38,45 @@ #include "postgres.h" -#include "access/sysattr.h" #include "access/table.h" -#include "catalog/pg_type.h" #include "nodes/makefuncs.h" +#include "optimizer/appendinfo.h" #include "optimizer/optimizer.h" #include "optimizer/prep.h" #include "optimizer/tlist.h" #include "parser/parse_coerce.h" #include "parser/parsetree.h" -#include "rewrite/rewriteHandler.h" #include "utils/rel.h" +#include "access/htup_details.h" #include "catalog/gp_distribution_policy.h" /* CDB: POLICYTYPE_PARTITIONED */ #include "catalog/pg_inherits.h" +#include "commands/tablecmds.h" #include "optimizer/plancat.h" #include "parser/parse_relation.h" #include "utils/lsyscache.h" +#include "utils/syscache.h" static List *expand_targetlist(PlannerInfo *root, List *tlist, int command_type, Index result_relation, Relation rel); static List *supplement_simply_updatable_targetlist(PlannerInfo *root, List *range_table, List *tlist); +static List *expand_insert_targetlist(List *tlist, Relation rel); +static bool check_splitupdate(List *tlist, Index result_relation, Relation rel); +static bool rel_has_appendoptimized_partition(Relation rel); /* * preprocess_targetlist * Driver for preprocessing the parse tree targetlist. * - * Returns the new targetlist. - * - * As a side effect, if there's an ON CONFLICT UPDATE clause, its targetlist - * is also preprocessed (and updated in-place). + * The preprocessed targetlist is returned in root->processed_tlist. + * Also, if this is an UPDATE, we return a list of target column numbers + * in root->update_colnos. (Resnos in processed_tlist will be consecutive, + * so do not look at that to find out which columns are targets!) */ -List * +void preprocess_targetlist(PlannerInfo *root) { Query *parse = root->parse; @@ -110,34 +110,155 @@ preprocess_targetlist(PlannerInfo *root) Assert(command_type == CMD_SELECT); /* - * For UPDATE/DELETE, add any junk column(s) needed to allow the executor - * to identify the rows to be updated or deleted. Note that this step - * scribbles on parse->targetList, which is not very desirable, but we - * keep it that way to avoid changing APIs used by FDWs. - */ - if (command_type == CMD_UPDATE || command_type == CMD_DELETE) - rewriteTargetListUD(parse, target_rte, target_relation); - - /* - * for heap_form_tuple to work, the targetlist must match the exact order - * of the attributes. We also need to fill in any missing attributes. -ay - * 10/94 + * In an INSERT, the executor expects the targetlist to match the exact + * order of the target table's attributes, including entries for + * attributes not mentioned in the source query. + * + * In an UPDATE, we don't rearrange the tlist order, but we need to make a + * separate list of the target attribute numbers, in tlist order, and then + * renumber the processed_tlist entries to be consecutive. */ tlist = parse->targetList; - if (command_type == CMD_INSERT || command_type == CMD_UPDATE) + if (command_type == CMD_INSERT) tlist = expand_targetlist(root, tlist, command_type, result_relation, target_relation); + else if (command_type == CMD_UPDATE) + { + /* + * Decide up front whether this UPDATE modifies a distribution key + * column and therefore needs a Split Update (which can move the tuple + * to a different segment). We must know this *before* deciding how to + * shape the targetlist: + * + * - A plain UPDATE keeps only the SET columns; PG14's executor + * (ExecBuildUpdateProjection) fills the unchanged columns from the + * old tuple using ModifyTable.updateColnosLists, which planner.c + * builds from root->update_colnos. So we just record the SET column + * numbers (and renumber the tlist to be consecutive, as upstream). + * + * - A Split Update is executed as delete+insert and needs the full + * new tuple, so we expand the targetlist to every attribute (GPDB's + * expand_targetlist), and must therefore *not* renumber the SET + * resnos beforehand (expand_targetlist matches resno == attno). + */ + root->is_split_update = check_splitupdate(tlist, result_relation, + target_relation); + if (root->is_split_update || + RelationIsAppendOptimized(target_relation) || + rel_has_appendoptimized_partition(target_relation)) + { + /* + * Both a Split Update and an append-optimized UPDATE need the full + * new tuple, so expand the targetlist to every attribute first. A + * Split Update runs as delete+insert; an AO/AOCS UPDATE likewise + * re-inserts the row and cannot fetch the old tuple by TID to fill + * in the unmodified columns (appendonly_fetch_row_version is + * unsupported). + * + * We must take the assign-column list from the *expanded* tlist: + * the plan emits one non-junk column per table attribute, so + * root->update_colnos has to have one entry per column too, + * otherwise ExecBuildUpdateProjection() rejects the plan with + * "targetColnos does not match subplan target list". We must not + * renumber the SET resnos beforehand, because expand_targetlist() + * relies on resno == attno. + */ + tlist = expand_targetlist(root, tlist, command_type, + result_relation, target_relation); + + if (!root->is_split_update) + { + /* + * PG14's ExecBuildUpdateProjection() pairs each non-junk + * tlist entry with its update_colnos target and rejects + * dropped target columns, so strip the NULL placeholders + * expand_targetlist() emitted for them; the executor sets + * dropped columns of the new tuple to NULL itself. A Split + * Update keeps the placeholders: it runs as delete+insert + * and its INSERT half wants the full physical row with + * resno == attno. + */ + TupleDesc tupdesc = RelationGetDescr(target_relation); + List *full_tlist = tlist; + ListCell *lc2; + + tlist = NIL; + foreach(lc2, full_tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc2); + + if (tle->resjunk || + !TupleDescAttr(tupdesc, tle->resno - 1)->attisdropped) + tlist = lappend(tlist, tle); + } + root->update_colnos = + extract_update_targetlist_colnos(tlist, true); + } + else + { + /* + * GPDB: like the branch above, but a Split Update's expanded + * tlist keeps NULL placeholders for dropped columns (its + * INSERT half wants resno == attno). Leave those attnos out + * of update_colnos: translating them to an inheritance child + * has no Var to map to ("attribute N of relation does not + * exist"), and nothing stores dropped columns anyway. + */ + TupleDesc tupdesc = RelationGetDescr(target_relation); + ListCell *lc2; + + root->update_colnos = NIL; + foreach(lc2, tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc2); + + if (!tle->resjunk && + !TupleDescAttr(tupdesc, tle->resno - 1)->attisdropped) + root->update_colnos = + lappend_int(root->update_colnos, tle->resno); + } + } + } + else + root->update_colnos = extract_update_targetlist_colnos(tlist, true); + } /* simply updatable cursors */ if (root->glob->simplyUpdatableRel != InvalidOid) tlist = supplement_simply_updatable_targetlist(root, range_table, tlist); + /* + * For non-inherited UPDATE/DELETE, register any junk column(s) needed to + * allow the executor to identify the rows to be updated or deleted. In + * the inheritance case, we do nothing now, leaving this to be dealt with + * when expand_inherited_rtentry() makes the leaf target relations. (But + * there might not be any leaf target relations, in which case we must do + * this in distribute_row_identity_vars().) + */ + if ((command_type == CMD_UPDATE || command_type == CMD_DELETE) && + !target_rte->inh) + { + /* row-identity logic expects to add stuff to processed_tlist */ + root->processed_tlist = tlist; + add_row_identity_columns(root, result_relation, + target_rte, target_relation); + tlist = root->processed_tlist; + } + /* * Add necessary junk columns for rowmarked rels. These values are needed * for locking of rels selected FOR UPDATE/SHARE, and to do EvalPlanQual * rechecking. See comments for PlanRowMark in plannodes.h. If you * change this stanza, see also expand_inherited_rtentry(), which has to * be able to add on junk columns equivalent to these. + * + * (Someday it might be useful to fold these resjunk columns into the + * row-identity-column management used for UPDATE/DELETE. Today is not + * that day, however. One notable issue is that it seems important that + * the whole-row Vars made here use the real table rowtype, not RECORD, so + * that conversion to/from child relations' rowtypes will happen. Also, + * since these entries don't potentially bloat with more and more child + * relations, there's not really much need for column sharing.) */ foreach(lc, root->rowMarks) { @@ -238,20 +359,161 @@ preprocess_targetlist(PlannerInfo *root) } /* - * If there's an ON CONFLICT UPDATE clause, preprocess its targetlist too - * while we have the relation open. + * NB: unlike PG13, an ON CONFLICT UPDATE clause's targetlist must NOT be + * expanded to full relation width here. PG14's ExecBuildUpdateProjection() + * (called with the SET column numbers in ModifyTable.onConflictCols) copies + * the unchanged columns from the existing tuple itself; expanding the list + * would mark every column as "assigned" and the unchanged columns would be + * projected as NULL instead. */ - if (parse->onConflict) - parse->onConflict->onConflictSet = - expand_targetlist(root, parse->onConflict->onConflictSet, - CMD_UPDATE, - result_relation, - target_relation); + root->processed_tlist = tlist; if (target_relation) table_close(target_relation, NoLock); +} - return tlist; +/* + * extract_update_targetlist_colnos + * Extract a list of the target-table column numbers that + * an UPDATE's targetlist wants to assign to, then renumber. + * + * The convention in the parser and rewriter is that the resnos in an + * UPDATE's non-resjunk TLE entries are the target column numbers + * to assign to. Here, we extract that info into a separate list, and + * then convert the tlist to the sequential-numbering convention that's + * used by all other query types. + * + * This is also applied to the tlist associated with INSERT ... ON CONFLICT + * ... UPDATE, although not till much later in planning. + */ +List * +extract_update_targetlist_colnos(List *tlist, bool reorder_resno) +{ + List *update_colnos = NIL; + AttrNumber nextresno = 1; + ListCell *lc; + + foreach(lc, tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc); + + if (!tle->resjunk) + update_colnos = lappend_int(update_colnos, tle->resno); + /* + * GPDB: a Split Update expands the tlist afterwards (expand_targetlist + * relies on resno == attno), so only renumber when asked to. + */ + if (reorder_resno) + tle->resno = nextresno++; + } + return update_colnos; +} + +/* + * check_splitupdate + * Decide whether an UPDATE needs a Split Update. + * + * A Split Update is required when the UPDATE may change a distribution key + * column: the modified tuple might then belong on a different segment and has + * to be re-routed (executed as a delete + insert). We inspect the + * (not-yet-expanded) UPDATE targetlist -- a SET column whose new value is not + * simply a Var referencing the same attribute of the target relation counts as + * changed. Return true if any distribution key column is changed. The actual + * SplitUpdate node is created later in planning; memorizing the decision in + * root->is_split_update avoids redoing this work. + */ +static bool +check_splitupdate(List *tlist, Index result_relation, Relation rel) +{ + ListCell *lc; + Bitmapset *changed_cols = NULL; + GpPolicy *targetPolicy; + bool key_col_updated = false; + + foreach(lc, tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc); + AttrNumber attrno = tle->resno; + bool col_changed = true; + + if (tle->resjunk) + continue; + + /* + * The column is unchanged if its new value is a Var referring directly + * to the same attribute of the target relation. + */ + if (IsA(tle->expr, Var)) + { + Var *var = (Var *) tle->expr; + + if (var->varno == result_relation && var->varattno == attrno) + col_changed = false; + } + + if (col_changed) + changed_cols = bms_add_member(changed_cols, attrno); + } + + /* Was any distribution key column among the changed columns? */ + targetPolicy = GpPolicyFetch(RelationGetRelid(rel)); + if (targetPolicy->ptype == POLICYTYPE_PARTITIONED) + { + int i; + + for (i = 0; i < targetPolicy->nattrs; i++) + { + if (bms_is_member(targetPolicy->attrs[i], changed_cols)) + { + key_col_updated = true; + break; + } + } + } + + bms_free(changed_cols); + return key_col_updated; +} + +/* + * Does any leaf partition of a partitioned UPDATE target use an + * append-optimized access method? + * + * A partitioned root has no access method of its own, so + * RelationIsAppendOptimized() is always false for it, but the executor + * restriction that forces targetlist expansion -- an AO relation cannot + * fetch the old tuple by TID to fill in unchanged columns, so the plan + * must supply the full new tuple (see ExecModifyTable) -- applies per + * leaf. + */ +static bool +rel_has_appendoptimized_partition(Relation rel) +{ + List *children; + ListCell *lc; + bool result = false; + + if (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) + return false; + + children = find_all_inheritors(RelationGetRelid(rel), AccessShareLock, + NULL); + foreach(lc, children) + { + Oid childrelid = lfirst_oid(lc); + HeapTuple tuple; + + tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(childrelid)); + if (!HeapTupleIsValid(tuple)) + continue; + if (IsAccessMethodAO(((Form_pg_class) GETSTRUCT(tuple))->relam)) + result = true; + ReleaseSysCache(tuple); + if (result) + break; + } + list_free(children); + return result; } @@ -262,10 +524,13 @@ preprocess_targetlist(PlannerInfo *root) *****************************************************************************/ /* - * expand_targetlist + * expand_insert_targetlist * Given a target list as generated by the parser and a result relation, * add targetlist entries for any missing attributes, and ensure the * non-junk attributes appear in proper field order. + * + * Once upon a time we also did more or less this with UPDATE targetlists, + * but now this code is only applied to INSERT targetlists. */ static List * expand_targetlist(PlannerInfo *root, List *tlist, int command_type, @@ -335,15 +600,11 @@ expand_targetlist(PlannerInfo *root, List *tlist, int command_type, /* * Didn't find a matching tlist entry, so make one. * - * For INSERT, generate a NULL constant. (We assume the rewriter - * would have inserted any available default value.) Also, if the - * column isn't dropped, apply any domain constraints that might - * exist --- this is to catch domain NOT NULL. - * - * For UPDATE, generate a Var reference to the existing value of - * the attribute, so that it gets copied to the new tuple. But - * generate a NULL for dropped columns (we want to drop any old - * values). + * INSERTs should insert NULL in this case. (We assume the + * rewriter would have inserted any available non-NULL default + * value.) Also, if the column isn't dropped, apply any domain + * constraints that might exist --- this is to catch domain NOT + * NULL. * * When generating a NULL constant for a dropped column, we label * it INT4 (any other guaranteed-to-exist datatype would do as @@ -359,65 +620,50 @@ expand_targetlist(PlannerInfo *root, List *tlist, int command_type, Oid attcollation = att_tup->attcollation; Node *new_expr; - switch (command_type) + if (att_tup->attisdropped) { - case CMD_INSERT: - if (!att_tup->attisdropped) - { - new_expr = (Node *) makeConst(atttype, - -1, - attcollation, - att_tup->attlen, - (Datum) 0, - true, /* isnull */ - att_tup->attbyval); - new_expr = coerce_to_domain(new_expr, - InvalidOid, -1, - atttype, - COERCION_IMPLICIT, - COERCE_IMPLICIT_CAST, - -1, - false); - } - else - { - /* Insert NULL for dropped column */ - new_expr = (Node *) makeConst(INT4OID, - -1, - InvalidOid, - sizeof(int32), - (Datum) 0, - true, /* isnull */ - true /* byval */ ); - } - break; - case CMD_UPDATE: - if (!att_tup->attisdropped) - { - new_expr = (Node *) makeVar(result_relation, - attrno, - atttype, - atttypmod, - attcollation, - 0); - } - else - { - /* Insert NULL for dropped column */ - new_expr = (Node *) makeConst(INT4OID, - -1, - InvalidOid, - sizeof(int32), - (Datum) 0, - true, /* isnull */ - true /* byval */ ); - } - break; - default: - elog(ERROR, "unrecognized command_type: %d", - (int) command_type); - new_expr = NULL; /* keep compiler quiet */ - break; + /* Insert NULL for dropped column */ + new_expr = (Node *) makeConst(INT4OID, + -1, + InvalidOid, + sizeof(int32), + (Datum) 0, + true, /* isnull */ + true /* byval */ ); + } + else if (command_type == CMD_UPDATE) + { + /* + * GPDB: For a Split Update we expand the UPDATE targetlist to + * cover every column of the relation. A column that the query + * does not SET must keep its old value, so reference the + * corresponding attribute of the target relation. (Substituting + * NULL, as we do for INSERT below, would wrongly blank out the + * unmodified columns of the re-inserted tuple.) + */ + new_expr = (Node *) makeVar(result_relation, + attrno, + atttype, + atttypmod, + attcollation, + 0); + } + else + { + new_expr = (Node *) makeConst(atttype, + -1, + attcollation, + att_tup->attlen, + (Datum) 0, + true, /* isnull */ + att_tup->attbyval); + new_expr = coerce_to_domain(new_expr, + InvalidOid, -1, + atttype, + COERCION_IMPLICIT, + COERCE_IMPLICIT_CAST, + -1, + false); } new_tle = makeTargetEntry((Expr *) new_expr, @@ -472,9 +718,8 @@ expand_targetlist(PlannerInfo *root, List *tlist, int command_type, * The remaining tlist entries should be resjunk; append them all to the * end of the new tlist, making sure they have resnos higher than the last * real attribute. (Note: although the rewriter already did such - * renumbering, we have to do it again here in case we are doing an UPDATE - * in a table with dropped columns, or an inheritance child table with - * extra columns.) + * renumbering, we have to do it again here in case we added NULL entries + * above.) */ while (tlist_item) { diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index b89bc25293ad..d28e8e3f869a 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -19,7 +19,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -357,6 +357,7 @@ recurse_set_operations(Node *setOp, PlannerInfo *root, *pNumGroups = estimate_num_groups(subroot, get_tlist_exprs(subquery->targetList, false), subpath->rows, + NULL, NULL); } } @@ -496,12 +497,24 @@ generate_recursion_path(SetOperationStmt *setOp, PlannerInfo *root, * merge, and things seem to be working with this much simpler thing, but * I'm not sure if the logic is 100% correct now. */ - if (CdbPathLocus_IsSegmentGeneral(lpath->locus)) + if (CdbPathLocus_IsSegmentGeneral(lpath->locus) || + CdbPathLocus_IsGeneral(lpath->locus) || + !setOp->all) { + /* + * GPDB: also force General loci to one segment (otherwise every + * segment would seed its own copy of the worktable and the gathered + * result would be duplicated), and recursive UNION DISTINCT too: + * the RecursiveUnion node deduplicates locally in one process, which + * is only global when the whole recursion runs in one process. + */ CdbPathLocus gather_locus; - CdbPathLocus_MakeSingleQE(&gather_locus, lpath->locus.numsegments); + CdbPathLocus_MakeSingleQE(&gather_locus, + CdbPathLocus_NumSegments(lpath->locus)); lpath = cdbpath_create_motion_path(root, lpath, NIL, false, gather_locus); + if (!lpath) + elog(ERROR, "could not gather non-recursive term of recursive UNION"); } /* The right path will want to look at the left one ... */ @@ -559,6 +572,22 @@ generate_recursion_path(SetOperationStmt *setOp, PlannerInfo *root, /* * And make the plan node. */ + /* + * GPDB: if the recursive term ended up in a single process but the + * anchor is distributed, gather the anchor there too; the + * RecursiveUnion node executes both inputs in one slice. (A motion on + * top of the recursive term itself would be wrong: that side is + * re-executed for every iteration, and Motions cannot be rescanned.) + */ + if (CdbPathLocus_IsBottleneck(rpath->locus) && + !CdbPathLocus_IsBottleneck(lpath->locus)) + { + lpath = cdbpath_create_motion_path(root, lpath, NIL, false, + rpath->locus); + if (!lpath) + elog(ERROR, "could not gather non-recursive term of recursive UNION"); + } + path = (Path *) create_recursiveunion_path(root, result_rel, lpath, @@ -567,6 +596,18 @@ generate_recursion_path(SetOperationStmt *setOp, PlannerInfo *root, groupList, root->wt_param_id, dNumGroups); + + /* + * GPDB: label the result locus. In one process it is just that locus; + * otherwise the anchor rows sit on their hash segments while + * recursively-produced rows sit wherever they were computed, so the + * honest description is Strewn. + */ + if (CdbPathLocus_IsBottleneck(lpath->locus)) + path->locus = lpath->locus; + else + CdbPathLocus_MakeStrewn(&path->locus, + CdbPathLocus_NumSegments(lpath->locus)); path->locus = rpath->locus; add_path(result_rel, path); @@ -661,7 +702,7 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, * Append the child results together. */ path = (Path *) create_append_path(root, result_rel, pathlist, NIL, - NIL, NULL, 0, false, NIL, -1); + NIL, NULL, 0, false, -1); /* * For UNION ALL, we just need the Append path. For UNION, need to add @@ -725,7 +766,7 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, create_append_path(root, result_rel, NIL, partial_pathlist, NIL, NULL, parallel_workers, enable_parallel_append, - NIL, -1); + -1); ppath = (Path *) create_gather_path(root, result_rel, ppath, result_rel->reltarget, NULL, NULL); @@ -887,7 +928,7 @@ generate_nonunion_paths(SetOperationStmt *op, PlannerInfo *root, * Append the child results together. */ path = (Path *) create_append_path(root, result_rel, pathlist, NIL, - NIL, NULL, 0, false, NIL, -1); + NIL, NULL, 0, false, -1); mark_append_locus(path, optype); /* CDB: Mark the plan result locus. */ /* Identify the grouping semantics */ diff --git a/src/backend/optimizer/util/appendinfo.c b/src/backend/optimizer/util/appendinfo.c index a77a029bfc5c..5271677f0708 100644 --- a/src/backend/optimizer/util/appendinfo.c +++ b/src/backend/optimizer/util/appendinfo.c @@ -3,7 +3,7 @@ * appendinfo.c * Routines for mapping between append parent(s) and children * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,9 +15,16 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/table.h" +#include "foreign/fdwapi.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "catalog/gp_distribution_policy.h" +#include "catalog/pg_am_d.h" +#include "catalog/pg_class.h" +#include "catalog/pg_inherits.h" #include "optimizer/appendinfo.h" +#include "optimizer/pathnode.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -37,8 +44,6 @@ static void make_inh_translation_list(Relation oldrelation, AppendRelInfo *appinfo); static Node *adjust_appendrel_attrs_mutator(Node *node, adjust_appendrel_attrs_context *context); -static List *adjust_inherited_tlist(List *tlist, - AppendRelInfo *context); /* @@ -194,7 +199,6 @@ Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos) { - Node *result; adjust_appendrel_attrs_context context; context.root = root; @@ -204,40 +208,10 @@ adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, /* If there's nothing to adjust, don't call this function. */ Assert(nappinfos >= 1 && appinfos != NULL); - /* - * Must be prepared to start with a Query or a bare expression tree. - */ - if (node && IsA(node, Query)) - { - Query *newnode; - int cnt; - - newnode = query_tree_mutator((Query *) node, - adjust_appendrel_attrs_mutator, - (void *) &context, - QTW_IGNORE_RC_SUBQUERIES); - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - if (newnode->resultRelation == appinfo->parent_relid) - { - newnode->resultRelation = appinfo->child_relid; - /* Fix tlist resnos too, if it's inherited UPDATE */ - if (newnode->commandType == CMD_UPDATE) - newnode->targetList = - adjust_inherited_tlist(newnode->targetList, - appinfo); - break; - } - } - - result = (Node *) newnode; - } - else - result = adjust_appendrel_attrs_mutator(node, &context); + /* Should never be translating a Query tree. */ + Assert(node == NULL || !IsA(node, Query)); - return result; + return adjust_appendrel_attrs_mutator(node, &context); } static Node * @@ -343,61 +317,74 @@ adjust_appendrel_attrs_mutator(Node *node, } /* system attributes don't need any other translation */ } - return (Node *) var; - } - if (IsA(node, CurrentOfExpr)) - { - CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node); - - for (cnt = 0; cnt < nappinfos; cnt++) + else if (var->varno == ROWID_VAR) { - AppendRelInfo *appinfo = appinfos[cnt]; + /* + * If it's a ROWID_VAR placeholder, see if we've reached a leaf + * target rel, for which we can translate the Var to a specific + * instantiation. We should never be asked to translate to a set + * of relids containing more than one leaf target rel, so the + * answer will be unique. If we're still considering non-leaf + * inheritance levels, return the ROWID_VAR Var as-is. + */ + Relids leaf_result_relids = context->root->leaf_result_relids; + Index leaf_relid = 0; - if (cexpr->cvarno == appinfo->parent_relid) + for (cnt = 0; cnt < nappinfos; cnt++) { - cexpr->cvarno = appinfo->child_relid; - break; + if (bms_is_member(appinfos[cnt]->child_relid, + leaf_result_relids)) + { + if (leaf_relid) + elog(ERROR, "cannot translate to multiple leaf relids"); + leaf_relid = appinfos[cnt]->child_relid; + } } - } - return (Node *) cexpr; - } - if (IsA(node, RangeTblRef)) - { - RangeTblRef *rtr = (RangeTblRef *) copyObject(node); - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - if (rtr->rtindex == appinfo->parent_relid) + if (leaf_relid) { - rtr->rtindex = appinfo->child_relid; - break; + RowIdentityVarInfo *ridinfo = (RowIdentityVarInfo *) + list_nth(context->root->row_identity_vars, var->varattno - 1); + + if (bms_is_member(leaf_relid, ridinfo->rowidrels)) + { + /* Substitute the Var given in the RowIdentityVarInfo */ + var = copyObject(ridinfo->rowidvar); + /* ... but use the correct relid */ + var->varno = leaf_relid; + /* varnosyn in the RowIdentityVarInfo is probably wrong */ + var->varnosyn = 0; + var->varattnosyn = 0; + } + else + { + /* + * This leaf rel can't return the desired value, so + * substitute a NULL of the correct type. + */ + return (Node *) makeNullConst(var->vartype, + var->vartypmod, + var->varcollid); + } } } - return (Node *) rtr; + return (Node *) var; } - if (IsA(node, JoinExpr)) + if (IsA(node, CurrentOfExpr)) { - /* Copy the JoinExpr node with correct mutation of subnodes */ - JoinExpr *j; - AppendRelInfo *appinfo; - - j = (JoinExpr *) expression_tree_mutator(node, - adjust_appendrel_attrs_mutator, - (void *) context); - /* now fix JoinExpr's rtindex (probably never happens) */ + CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node); + for (cnt = 0; cnt < nappinfos; cnt++) { - appinfo = appinfos[cnt]; + AppendRelInfo *appinfo = appinfos[cnt]; - if (j->rtindex == appinfo->parent_relid) + if (cexpr->cvarno == appinfo->parent_relid) { - j->rtindex = appinfo->child_relid; + cexpr->cvarno = appinfo->child_relid; break; } } - return (Node *) j; + return (Node *) cexpr; } if (IsA(node, PlaceHolderVar)) { @@ -486,6 +473,9 @@ adjust_appendrel_attrs_mutator(Node *node, */ Assert(!IsA(node, SubLink)); Assert(!IsA(node, Query)); + /* We should never see these Query substructures, either. */ + Assert(!IsA(node, RangeTblRef)); + Assert(!IsA(node, JoinExpr)); node = expression_tree_mutator(node, adjust_appendrel_attrs_mutator, (void *) context); @@ -658,100 +648,101 @@ adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, } /* - * Adjust the targetlist entries of an inherited UPDATE operation - * - * The expressions have already been fixed, but we have to make sure that - * the target resnos match the child table (they may not, in the case of - * a column that was added after-the-fact by ALTER TABLE). In some cases - * this can force us to re-order the tlist to preserve resno ordering. - * (We do all this work in special cases so that preptlist.c is fast for - * the typical case.) - * - * The given tlist has already been through expression_tree_mutator; - * therefore the TargetEntry nodes are fresh copies that it's okay to - * scribble on. - * - * Note that this is not needed for INSERT because INSERT isn't inheritable. + * adjust_inherited_attnums + * Translate an integer list of attribute numbers from parent to child. */ -static List * -adjust_inherited_tlist(List *tlist, AppendRelInfo *context) +List * +adjust_inherited_attnums(List *attnums, AppendRelInfo *context) { - bool changed_it = false; - ListCell *tl; - List *new_tlist; - bool more; - int attrno; + List *result = NIL; + ListCell *lc; /* This should only happen for an inheritance case, not UNION ALL */ Assert(OidIsValid(context->parent_reloid)); - /* Scan tlist and update resnos to match attnums of child rel */ - foreach(tl, tlist) + /* Look up each attribute in the AppendRelInfo's translated_vars list */ + foreach(lc, attnums) { - TargetEntry *tle = (TargetEntry *) lfirst(tl); + AttrNumber parentattno = lfirst_int(lc); Var *childvar; - if (tle->resjunk) - continue; /* ignore junk items */ - /* Look up the translation of this column: it must be a Var */ - if (tle->resno <= 0 || - tle->resno > list_length(context->translated_vars)) + if (parentattno <= 0 || + parentattno > list_length(context->translated_vars)) elog(ERROR, "attribute %d of relation \"%s\" does not exist", - tle->resno, get_rel_name(context->parent_reloid)); - childvar = (Var *) list_nth(context->translated_vars, tle->resno - 1); + parentattno, get_rel_name(context->parent_reloid)); + childvar = (Var *) list_nth(context->translated_vars, parentattno - 1); if (childvar == NULL || !IsA(childvar, Var)) elog(ERROR, "attribute %d of relation \"%s\" does not exist", - tle->resno, get_rel_name(context->parent_reloid)); + parentattno, get_rel_name(context->parent_reloid)); - if (tle->resno != childvar->varattno) - { - tle->resno = childvar->varattno; - changed_it = true; - } + result = lappend_int(result, childvar->varattno); } + return result; +} - /* - * If we changed anything, re-sort the tlist by resno, and make sure - * resjunk entries have resnos above the last real resno. The sort - * algorithm is a bit stupid, but for such a seldom-taken path, small is - * probably better than fast. - */ - if (!changed_it) - return tlist; +/* + * adjust_inherited_attnums_multilevel + * As above, but traverse multiple inheritance levels as needed. + */ +List * +adjust_inherited_attnums_multilevel(PlannerInfo *root, List *attnums, + Index child_relid, Index top_parent_relid) +{ + AppendRelInfo *appinfo = root->append_rel_array[child_relid]; - new_tlist = NIL; - more = true; - for (attrno = 1; more; attrno++) - { - more = false; - foreach(tl, tlist) - { - TargetEntry *tle = (TargetEntry *) lfirst(tl); + if (!appinfo) + elog(ERROR, "child rel %d not found in append_rel_array", child_relid); - if (tle->resjunk) - continue; /* ignore junk items */ + /* Recurse if immediate parent is not the top parent. */ + if (appinfo->parent_relid != top_parent_relid) + attnums = adjust_inherited_attnums_multilevel(root, attnums, + appinfo->parent_relid, + top_parent_relid); - if (tle->resno == attrno) - new_tlist = lappend(new_tlist, tle); - else if (tle->resno > attrno) - more = true; - } - } + /* Now translate for this child */ + return adjust_inherited_attnums(attnums, appinfo); +} - foreach(tl, tlist) +/* + * get_translated_update_targetlist + * Get the processed_tlist of an UPDATE query, translated as needed to + * match a child target relation. + * + * Optionally also return the list of target column numbers translated + * to this target relation. (The resnos in processed_tlist MUST NOT be + * relied on for this purpose.) + */ +void +get_translated_update_targetlist(PlannerInfo *root, Index relid, + List **processed_tlist, List **update_colnos) +{ + /* This is pretty meaningless for commands other than UPDATE. */ + Assert(root->parse->commandType == CMD_UPDATE); + if (relid == root->parse->resultRelation) { - TargetEntry *tle = (TargetEntry *) lfirst(tl); - - if (!tle->resjunk) - continue; /* here, ignore non-junk items */ - - tle->resno = attrno; - new_tlist = lappend(new_tlist, tle); - attrno++; + /* + * Non-inheritance case, so it's easy. The caller might be expecting + * a tree it can scribble on, though, so copy. + */ + *processed_tlist = copyObject(root->processed_tlist); + if (update_colnos) + *update_colnos = copyObject(root->update_colnos); + } + else + { + Assert(bms_is_member(relid, root->all_result_relids)); + *processed_tlist = (List *) + adjust_appendrel_attrs_multilevel(root, + (Node *) root->processed_tlist, + bms_make_singleton(relid), + bms_make_singleton(root->parse->resultRelation)); + if (update_colnos) + *update_colnos = + adjust_inherited_attnums_multilevel(root, root->update_colnos, + relid, + root->parse->resultRelation); } - - return new_tlist; } /* @@ -783,3 +774,411 @@ find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos) } return appinfos; } + + +/***************************************************************************** + * + * ROW-IDENTITY VARIABLE MANAGEMENT + * + * This code lacks a good home, perhaps. We choose to keep it here because + * adjust_appendrel_attrs_mutator() is its principal co-conspirator. That + * function does most of what is needed to expand ROWID_VAR Vars into the + * right things. + * + *****************************************************************************/ + +/* + * add_row_identity_var + * Register a row-identity column to be used in UPDATE/DELETE. + * + * The Var must be equal(), aside from varno, to any other row-identity + * column with the same rowid_name. Thus, for example, "wholerow" + * row identities had better use vartype == RECORDOID. + * + * rtindex is currently redundant with rowid_var->varno, but we specify + * it as a separate parameter in case this is ever generalized to support + * non-Var expressions. (We could reasonably handle expressions over + * Vars of the specified rtindex, but for now that seems unnecessary.) + */ +void +add_row_identity_var(PlannerInfo *root, Var *orig_var, + Index rtindex, const char *rowid_name) +{ + TargetEntry *tle; + Var *rowid_var; + RowIdentityVarInfo *ridinfo; + ListCell *lc; + + /* For now, the argument must be just a Var of the given rtindex */ + Assert(IsA(orig_var, Var)); + Assert(orig_var->varno == rtindex); + Assert(orig_var->varlevelsup == 0); + + /* + * If we're doing non-inherited UPDATE/DELETE, there's little need for + * ROWID_VAR shenanigans. Just shove the presented Var into the + * processed_tlist, and we're done. + */ + if (rtindex == root->parse->resultRelation) + { + tle = makeTargetEntry((Expr *) orig_var, + list_length(root->processed_tlist) + 1, + pstrdup(rowid_name), + true); + root->processed_tlist = lappend(root->processed_tlist, tle); + return; + } + + /* + * Otherwise, rtindex should reference a leaf target relation that's being + * added to the query during expand_inherited_rtentry(). + */ + Assert(bms_is_member(rtindex, root->leaf_result_relids)); + Assert(root->append_rel_array[rtindex] != NULL); + + /* + * We have to find a matching RowIdentityVarInfo, or make one if there is + * none. To allow using equal() to match the vars, change the varno to + * ROWID_VAR, leaving all else alone. + */ + rowid_var = copyObject(orig_var); + /* This could eventually become ChangeVarNodes() */ + rowid_var->varno = ROWID_VAR; + + /* Look for an existing row-id column of the same name */ + foreach(lc, root->row_identity_vars) + { + ridinfo = (RowIdentityVarInfo *) lfirst(lc); + if (strcmp(rowid_name, ridinfo->rowidname) != 0) + continue; + if (equal(rowid_var, ridinfo->rowidvar)) + { + /* Found a match; we need only record that rtindex needs it too */ + ridinfo->rowidrels = bms_add_member(ridinfo->rowidrels, rtindex); + return; + } + else + { + /* Ooops, can't handle this */ + elog(ERROR, "conflicting uses of row-identity name \"%s\"", + rowid_name); + } + } + + /* No request yet, so add a new RowIdentityVarInfo */ + ridinfo = makeNode(RowIdentityVarInfo); + ridinfo->rowidvar = copyObject(rowid_var); + /* for the moment, estimate width using just the datatype info */ + ridinfo->rowidwidth = get_typavgwidth(exprType((Node *) rowid_var), + exprTypmod((Node *) rowid_var)); + ridinfo->rowidname = pstrdup(rowid_name); + ridinfo->rowidrels = bms_make_singleton(rtindex); + + root->row_identity_vars = lappend(root->row_identity_vars, ridinfo); + + /* Change rowid_var into a reference to this row_identity_vars entry */ + rowid_var->varattno = list_length(root->row_identity_vars); + + /* Push the ROWID_VAR reference variable into processed_tlist */ + tle = makeTargetEntry((Expr *) rowid_var, + list_length(root->processed_tlist) + 1, + pstrdup(rowid_name), + true); + root->processed_tlist = lappend(root->processed_tlist, tle); +} + +/* + * gp_update_may_move_row + * Does this UPDATE touch a distribution key column of the target, + * i.e. will it be planned as a SplitUpdate? + * + * Only then does the INSERT half of the split need the "wholerow" junk + * column to rebuild child tuples on the receiving segment. + */ +static bool +gp_update_may_move_row(PlannerInfo *root, Oid rootrelid) +{ + GpPolicy *policy = GpPolicyFetch(rootrelid); + bool result = false; + + if (policy && GpPolicyIsHashPartitioned(policy)) + { + ListCell *lc; + + foreach(lc, root->update_colnos) + { + AttrNumber colno = lfirst_int(lc); + + for (int i = 0; i < policy->nattrs; i++) + { + if (policy->attrs[i] == colno) + { + result = true; + break; + } + } + if (result) + break; + } + } + if (policy) + pfree(policy); + return result; +} + +/* + * gp_inh_tree_has_ao + * Is any relation in this inheritance tree append-optimized? + * + * AO relations cannot fetch the old tuple by TID at UPDATE time, so an + * inheritance child with extra columns needs the "wholerow" junk column + * to fill them in (see ExecModifyTable). + */ +static bool +gp_inh_tree_has_ao(Oid rootrelid) +{ + List *inhs; + ListCell *lc; + bool result = false; + + inhs = find_all_inheritors(rootrelid, NoLock, NULL); + foreach(lc, inhs) + { + HeapTuple tp = SearchSysCache1(RELOID, + ObjectIdGetDatum(lfirst_oid(lc))); + Oid relam = InvalidOid; + + if (HeapTupleIsValid(tp)) + { + relam = ((Form_pg_class) GETSTRUCT(tp))->relam; + ReleaseSysCache(tp); + } + if (relam == AO_ROW_TABLE_AM_OID || relam == AO_COLUMN_TABLE_AM_OID) + { + result = true; + break; + } + } + list_free(inhs); + return result; +} + +/* + * add_row_identity_columns + * + * This function adds the row identity columns needed by the core code. + * FDWs might call add_row_identity_var() for themselves to add nonstandard + * columns. (Duplicate requests are fine.) + */ +void +add_row_identity_columns(PlannerInfo *root, Index rtindex, + RangeTblEntry *target_rte, + Relation target_relation) +{ + CmdType commandType = root->parse->commandType; + char relkind = target_relation->rd_rel->relkind; + Var *var; + + Assert(commandType == CMD_UPDATE || commandType == CMD_DELETE); + + if (relkind == RELKIND_RELATION || + relkind == RELKIND_MATVIEW || + relkind == RELKIND_PARTITIONED_TABLE || + relkind == RELKIND_AOSEGMENTS || + relkind == RELKIND_AOBLOCKDIR || + relkind == RELKIND_AOVISIMAP) + { + /* + * GPDB: append-optimized auxiliary relations are heap-storage + * catalogs; UPDATE/DELETE on them identifies rows by ctid like any + * table (the executor groups them with plain relations). Without + * this they fell through with no row identity at all and + * ExecInitModifyTable failed with "could not find junk wholerow + * column" (uao_catalog_tables' maintenance deletes). + */ + /* + * Emit CTID so that executor can find the row to update or delete. + */ + var = makeVar(rtindex, + SelfItemPointerAttributeNumber, + TIDOID, + -1, + InvalidOid, + 0); + add_row_identity_var(root, var, rtindex, "ctid"); + + /* + * GPDB: Also emit gp_segment_id. In an MPP cluster the executor must + * know which segment the target row lives on so that the Explicit + * Motion can route the modified/deleted row back to its home segment + * (see cdbpathtoplan_create_motion_plan()). This mirrors the ctid + * junk column and rides the same ROWID_VAR machinery, so it is shared + * correctly across the leaf relations of an inherited/partitioned + * UPDATE/DELETE. + */ + var = makeVar(rtindex, + GpSegmentIdAttributeNumber, + INT4OID, + -1, + InvalidOid, + 0); + add_row_identity_var(root, var, rtindex, "gp_segment_id"); + + /* + * GPDB: for an UPDATE on an old-style inheritance tree also emit a + * whole-row Var. If the update changes the distribution key it is + * planned as a SplitUpdate, and the INSERT half must rebuild the + * complete new tuple of the source child relation on a different + * segment; child columns that do not exist in the root are not in + * the targetlist, so they can only come from the old tuple. A + * RECORD-type whole-row Var translates to each child's own + * whole-row (no conversion to the root rowtype), preserving them. + * Partitioned tables don't need this: the re-insert goes through + * tuple routing from the root. + */ + if (commandType == CMD_UPDATE && relkind == RELKIND_RELATION) + { + RangeTblEntry *rootRte = planner_rt_fetch(root->parse->resultRelation, + root); + + /* + * Note: this function is called for each leaf target relation + * (from expand_inherited_rtentry()), where target_rte is the + * leaf; whether the UPDATE targets an inheritance tree must be + * read off the query's nominal result relation. + */ + if (rootRte->inh && rootRte->relkind == RELKIND_RELATION && + (gp_update_may_move_row(root, rootRte->relid) || + gp_inh_tree_has_ao(rootRte->relid))) + { + var = makeVar(rtindex, + InvalidAttrNumber, + RECORDOID, + -1, + InvalidOid, + 0); + add_row_identity_var(root, var, rtindex, "wholerow"); + } + } + } + else if (relkind == RELKIND_FOREIGN_TABLE) + { + /* + * Let the foreign table's FDW add whatever junk TLEs it wants. + */ + FdwRoutine *fdwroutine; + + fdwroutine = GetFdwRoutineForRelation(target_relation, false); + + if (fdwroutine->AddForeignUpdateTargets != NULL) + fdwroutine->AddForeignUpdateTargets(root, rtindex, + target_rte, target_relation); + + /* + * For UPDATE, we need to make the FDW fetch unchanged columns by + * asking it to fetch a whole-row Var. That's because the top-level + * targetlist only contains entries for changed columns, but + * ExecUpdate will need to build the complete new tuple. (Actually, + * we only really need this in UPDATEs that are not pushed to the + * remote side, but it's hard to tell if that will be the case at the + * point when this function is called.) + * + * We will also need the whole row if there are any row triggers, so + * that the executor will have the "old" row to pass to the trigger. + * Alas, this misses system columns. + */ + if (commandType == CMD_UPDATE || + (target_relation->trigdesc && + (target_relation->trigdesc->trig_delete_after_row || + target_relation->trigdesc->trig_delete_before_row))) + { + var = makeVar(rtindex, + InvalidAttrNumber, + RECORDOID, + -1, + InvalidOid, + 0); + add_row_identity_var(root, var, rtindex, "wholerow"); + } + } +} + +/* + * distribute_row_identity_vars + * + * After we have finished identifying all the row identity columns + * needed by an inherited UPDATE/DELETE query, make sure that these + * columns will be generated by all the target relations. + * + * This is more or less like what build_base_rel_tlists() does, + * except that it would not understand what to do with ROWID_VAR Vars. + * Since that function runs before inheritance relations are expanded, + * it will never see any such Vars anyway. + */ +void +distribute_row_identity_vars(PlannerInfo *root) +{ + Query *parse = root->parse; + int result_relation = parse->resultRelation; + RangeTblEntry *target_rte; + RelOptInfo *target_rel; + ListCell *lc; + + /* There's nothing to do if this isn't an inherited UPDATE/DELETE. */ + if (parse->commandType != CMD_UPDATE && parse->commandType != CMD_DELETE) + { + Assert(root->row_identity_vars == NIL); + return; + } + target_rte = rt_fetch(result_relation, parse->rtable); + if (!target_rte->inh) + { + Assert(root->row_identity_vars == NIL); + return; + } + + /* + * Ordinarily, we expect that leaf result relation(s) will have added some + * ROWID_VAR Vars to the query. However, it's possible that constraint + * exclusion suppressed every leaf relation. The executor will get upset + * if the plan has no row identity columns at all, even though it will + * certainly process no rows. Handle this edge case by re-opening the top + * result relation and adding the row identity columns it would have used, + * as preprocess_targetlist() would have done if it weren't marked "inh". + * (This is a bit ugly, but it seems better to confine the ugliness and + * extra cycles to this unusual corner case.) We needn't worry about + * fixing the rel's reltarget, as that won't affect the finished plan. + */ + if (root->row_identity_vars == NIL) + { + Relation target_relation; + + target_relation = table_open(target_rte->relid, NoLock); + add_row_identity_columns(root, result_relation, + target_rte, target_relation); + table_close(target_relation, NoLock); + return; + } + + /* + * Dig through the processed_tlist to find the ROWID_VAR reference Vars, + * and forcibly copy them into the reltarget list of the topmost target + * relation. That's sufficient because they'll be copied to the + * individual leaf target rels (with appropriate translation) later, + * during appendrel expansion --- see set_append_rel_size(). + */ + target_rel = find_base_rel(root, result_relation); + + foreach(lc, root->processed_tlist) + { + TargetEntry *tle = lfirst(lc); + Var *var = (Var *) tle->expr; + + if (var && IsA(var, Var) && var->varno == ROWID_VAR) + { + target_rel->reltarget->exprs = + lappend(target_rel->reltarget->exprs, copyObject(var)); + /* reltarget cost and width will be computed later */ + } + } +} diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index ad70005c9dbb..da9e6d51c7a0 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,6 +35,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "nodes/subscripting.h" #include "nodes/supportnodes.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" @@ -56,14 +57,6 @@ #include "utils/syscache.h" #include "utils/typcache.h" - -typedef struct -{ - PlannerInfo *root; - AggSplit aggsplit; - AggClauseCosts *costs; -} get_agg_clause_costs_context; - typedef struct { ParamListInfo boundParams; @@ -105,8 +98,6 @@ typedef struct } max_parallel_hazard_context; static bool contain_agg_clause_walker(Node *node, void *context); -static bool get_agg_clause_costs_walker(Node *node, - get_agg_clause_costs_context *context); static bool find_window_functions_walker(Node *node, WindowFuncLists *lists); static bool contain_subplans_walker(Node *node, void *context); static bool contain_mutable_functions_walker(Node *node, void *context); @@ -122,6 +113,7 @@ static bool contain_leaked_vars_walker(Node *node, void *context); static Relids find_nonnullable_rels_walker(Node *node, bool top_level); static List *find_nonnullable_vars_walker(Node *node, bool top_level); static bool is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK); +static bool convert_saop_to_hashed_saop_walker(Node *node, void *context); static Node *eval_const_expressions_mutator(Node *node, eval_const_expressions_context *context); static bool contain_non_const_walker(Node *node, void *context); @@ -140,10 +132,13 @@ static Expr *simplify_function(Oid funcid, bool funcvariadic, bool process_args, bool allow_non_const, eval_const_expressions_context *context); static bool large_const(Expr *expr, Size max_size); -static List *reorder_function_arguments(List *args, HeapTuple func_tuple); -static List *add_function_defaults(List *args, HeapTuple func_tuple); +static List *reorder_function_arguments(List *args, int pronargs, + HeapTuple func_tuple); +static List *add_function_defaults(List *args, int pronargs, + HeapTuple func_tuple); static List *fetch_function_defaults(HeapTuple func_tuple); static void recheck_cast_function_args(List *args, Oid result_type, + Oid *proargtypes, int pronargs, HeapTuple func_tuple); static Expr *evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, Oid result_collid, Oid input_collid, List *args, @@ -222,315 +217,8 @@ contain_agg_clause_walker(Node *node, void *context) return expression_tree_walker(node, contain_agg_clause_walker, context); } -/* - * get_agg_clause_costs - * Recursively find the Aggref nodes in an expression tree, and - * accumulate cost information about them. - * - * 'aggsplit' tells us the expected partial-aggregation mode, which affects - * the cost estimates. - * - * NOTE that the counts/costs are ADDED to those already in *costs ... so - * the caller is responsible for zeroing the struct initially. - * - * We count the nodes, estimate their execution costs, and estimate the total - * space needed for their transition state values if all are evaluated in - * parallel (as would be done in a HashAgg plan). Also, we check whether - * partial aggregation is feasible. See AggClauseCosts for the exact set - * of statistics collected. - * - * In addition, we mark Aggref nodes with the correct aggtranstype, so - * that that doesn't need to be done repeatedly. (That makes this function's - * name a bit of a misnomer.) - * - * This does not descend into subqueries, and so should be used only after - * reduction of sublinks to subplans, or in contexts where it's known there - * are no subqueries. There mustn't be outer-aggregate references either. - */ -void -get_agg_clause_costs(PlannerInfo *root, Node *clause, AggSplit aggsplit, - AggClauseCosts *costs) -{ - get_agg_clause_costs_context context; - context.root = root; - context.aggsplit = aggsplit; - context.costs = costs; - (void) get_agg_clause_costs_walker(clause, &context); -} - -static bool -get_agg_clause_costs_walker(Node *node, get_agg_clause_costs_context *context) -{ - if (node == NULL) - return false; - if (IsA(node, Aggref)) - { - Aggref *aggref = (Aggref *) node; - AggClauseCosts *costs = context->costs; - HeapTuple aggTuple; - Form_pg_aggregate aggform; - Oid aggtransfn; - Oid aggfinalfn; - Oid aggcombinefn; - Oid aggserialfn; - Oid aggdeserialfn; - Oid aggtranstype; - int32 aggtransspace; - QualCost argcosts; - - Assert(aggref->agglevelsup == 0); - - /* - * Fetch info about aggregate from pg_aggregate. Note it's correct to - * ignore the moving-aggregate variant, since what we're concerned - * with here is aggregates not window functions. - */ - aggTuple = SearchSysCache1(AGGFNOID, - ObjectIdGetDatum(aggref->aggfnoid)); - if (!HeapTupleIsValid(aggTuple)) - elog(ERROR, "cache lookup failed for aggregate %u", - aggref->aggfnoid); - aggform = (Form_pg_aggregate) GETSTRUCT(aggTuple); - aggtransfn = aggform->aggtransfn; - aggfinalfn = aggform->aggfinalfn; - aggcombinefn = aggform->aggcombinefn; - aggserialfn = aggform->aggserialfn; - aggdeserialfn = aggform->aggdeserialfn; - aggtranstype = aggform->aggtranstype; - aggtransspace = aggform->aggtransspace; - ReleaseSysCache(aggTuple); - - /* - * Resolve the possibly-polymorphic aggregate transition type, unless - * already done in a previous pass over the expression. - */ - if (OidIsValid(aggref->aggtranstype)) - aggtranstype = aggref->aggtranstype; - else - { - Oid inputTypes[FUNC_MAX_ARGS]; - int numArguments; - - /* extract argument types (ignoring any ORDER BY expressions) */ - numArguments = get_aggregate_argtypes(aggref, inputTypes); - - /* resolve actual type of transition state, if polymorphic */ - aggtranstype = resolve_aggregate_transtype(aggref->aggfnoid, - aggtranstype, - inputTypes, - numArguments); - aggref->aggtranstype = aggtranstype; - } - - /* - * Count it, and check for cases requiring ordered input. Note that - * ordered-set aggs always have nonempty aggorder. Any ordered-input - * case also defeats partial aggregation. - */ - costs->numAggs++; - if (aggref->aggorder != NIL || aggref->aggdistinct != NIL) - { - costs->numOrderedAggs++; - costs->hasNonPartial = true; - } - - /* - * The PostgreSQL 'numOrderedAggs' field includes DISTINCT aggregates, - * too, but cdbgroup.c handles DISTINCT aggregates differently, and - * needs to know if there are any purely ordered aggs, not counting - * DISTINCT aggs. - */ - if (aggref->aggorder != NIL) - costs->numPureOrderedAggs++; - - if (aggref->aggdistinct != NIL) - costs->distinctAggrefs = lappend(costs->distinctAggrefs, aggref); - - /* - * Check whether partial aggregation is feasible, unless we already - * found out that we can't do it. - * - * In GPDB, we can do two-stage aggregation with DISTINCT-qualified - * aggregates, if the data distribution happens to match the DISTINCT - * expressions. So we keep track whether all aggregates have combine - * functions, even if there are DISTINCT aggregates. hasNonCombine is - * set if there are any aggregates without combine functions, even if - * there are DISTINCT aggregates. - */ - if (!costs->hasNonCombine) - { - /* - * If there is no combine function, then partial aggregation is - * not possible. - */ - if (!OidIsValid(aggcombinefn)) - { - costs->hasNonCombine = true; - costs->hasNonPartial = true; - } - - /* - * If we have any aggs with transtype INTERNAL then we must check - * whether they have serialization/deserialization functions; if - * not, we can't serialize partial-aggregation results. - */ - else if (aggtranstype == INTERNALOID && - (!OidIsValid(aggserialfn) || !OidIsValid(aggdeserialfn))) - costs->hasNonSerial = true; - } - - /* - * Add the appropriate component function execution costs to - * appropriate totals. - */ - if (DO_AGGSPLIT_COMBINE(context->aggsplit)) - { - /* charge for combining previously aggregated states */ - add_function_cost(context->root, aggcombinefn, NULL, - &costs->transCost); - } - else - add_function_cost(context->root, aggtransfn, NULL, - &costs->transCost); - if (DO_AGGSPLIT_DESERIALIZE(context->aggsplit) && - OidIsValid(aggdeserialfn)) - add_function_cost(context->root, aggdeserialfn, NULL, - &costs->transCost); - if (DO_AGGSPLIT_SERIALIZE(context->aggsplit) && - OidIsValid(aggserialfn)) - add_function_cost(context->root, aggserialfn, NULL, - &costs->finalCost); - if (!DO_AGGSPLIT_SKIPFINAL(context->aggsplit) && - OidIsValid(aggfinalfn)) - add_function_cost(context->root, aggfinalfn, NULL, - &costs->finalCost); - - /* - * These costs are incurred only by the initial aggregate node, so we - * mustn't include them again at upper levels. - */ - if (!DO_AGGSPLIT_COMBINE(context->aggsplit)) - { - /* add the input expressions' cost to per-input-row costs */ - cost_qual_eval_node(&argcosts, (Node *) aggref->args, context->root); - costs->transCost.startup += argcosts.startup; - costs->transCost.per_tuple += argcosts.per_tuple; - - /* - * Add any filter's cost to per-input-row costs. - * - * XXX Ideally we should reduce input expression costs according - * to filter selectivity, but it's not clear it's worth the - * trouble. - */ - if (aggref->aggfilter) - { - cost_qual_eval_node(&argcosts, (Node *) aggref->aggfilter, - context->root); - costs->transCost.startup += argcosts.startup; - costs->transCost.per_tuple += argcosts.per_tuple; - } - } - - /* - * If there are direct arguments, treat their evaluation cost like the - * cost of the finalfn. - */ - if (aggref->aggdirectargs) - { - cost_qual_eval_node(&argcosts, (Node *) aggref->aggdirectargs, - context->root); - costs->finalCost.startup += argcosts.startup; - costs->finalCost.per_tuple += argcosts.per_tuple; - } - - /* - * If the transition type is pass-by-value then it doesn't add - * anything to the required size of the hashtable. If it is - * pass-by-reference then we have to add the estimated size of the - * value itself, plus palloc overhead. - */ - if (!get_typbyval(aggtranstype)) - { - int32 avgwidth; - - /* Use average width if aggregate definition gave one */ - if (aggtransspace > 0) - avgwidth = aggtransspace; - else if (aggtransfn == F_ARRAY_APPEND) - { - /* - * If the transition function is array_append(), it'll use an - * expanded array as transvalue, which will occupy at least - * ALLOCSET_SMALL_INITSIZE and possibly more. Use that as the - * estimate for lack of a better idea. - */ - avgwidth = ALLOCSET_SMALL_INITSIZE; - } - else - { - /* - * If transition state is of same type as first aggregated - * input, assume it's the same typmod (same width) as well. - * This works for cases like MAX/MIN and is probably somewhat - * reasonable otherwise. - */ - int32 aggtranstypmod = -1; - - if (aggref->args) - { - TargetEntry *tle = (TargetEntry *) linitial(aggref->args); - - if (aggtranstype == exprType((Node *) tle->expr)) - aggtranstypmod = exprTypmod((Node *) tle->expr); - } - - avgwidth = get_typavgwidth(aggtranstype, aggtranstypmod); - } - - avgwidth = MAXALIGN(avgwidth); - costs->transitionSpace += avgwidth + 2 * sizeof(void *); - } - else if (aggtranstype == INTERNALOID) - { - /* - * INTERNAL transition type is a special case: although INTERNAL - * is pass-by-value, it's almost certainly being used as a pointer - * to some large data structure. The aggregate definition can - * provide an estimate of the size. If it doesn't, then we assume - * ALLOCSET_DEFAULT_INITSIZE, which is a good guess if the data is - * being kept in a private memory context, as is done by - * array_agg() for instance. - */ - if (aggtransspace > 0) - costs->transitionSpace += aggtransspace; - else - costs->transitionSpace += ALLOCSET_DEFAULT_INITSIZE; - } - - /* - * Complain if the aggregate's arguments contain any aggregates; - * nested agg functions are semantically nonsensical. Aggregates in - * the FILTER clause are detected in transformAggregateCall(). - */ - if (contain_agg_clause((Node *) aggref->args) || - contain_agg_clause((Node *) aggref->aggorder)) - ereport(ERROR, - (errcode(ERRCODE_GROUPING_ERROR), - errmsg("aggregate function calls cannot be nested"))); - - /* - * We assume that the parser checked that there are no aggregates (of - * this level anyway) in the aggregated arguments, direct arguments, - * or filter clause. Hence, we need not recurse into any of them. - */ - return false; - } - Assert(!IsA(node, SubLink)); - return expression_tree_walker(node, get_agg_clause_costs_walker, - (void *) context); -} +/* get_agg_clause_costs moved to prepagg.c in PG14 */ /***************************************************************************** @@ -784,6 +472,16 @@ contain_mutable_functions_walker(Node *node, void *context) * subsequent planning need not consider volatility within those, since * the executor won't change its evaluation rules for a SubPlan based on * volatility. + * + * For some node types, for example, RestrictInfo and PathTarget, we cache + * whether we found any volatile functions or not and reuse that value in any + * future checks for that node. All of the logic for determining if the + * cached value should be set to VOLATILITY_NOVOLATILE or VOLATILITY_VOLATILE + * belongs in this function. Any code which makes changes to these nodes + * which could change the outcome this function must set the cached value back + * to VOLATILITY_UNKNOWN. That allows this function to redetermine the + * correct value during the next call, should we need to redetermine if the + * node contains any volatile functions again in the future. */ bool contain_volatile_functions(Node *clause) @@ -825,6 +523,63 @@ contain_volatile_functions_walker(Node *node, void *context) return true; } + if (IsA(node, RestrictInfo)) + { + RestrictInfo *rinfo = (RestrictInfo *) node; + + /* + * For RestrictInfo, check if we've checked the volatility of it + * before. If so, we can just use the cached value and not bother + * checking it again. Otherwise, check it and cache if whether we + * found any volatile functions. + */ + if (rinfo->has_volatile == VOLATILITY_NOVOLATILE) + return false; + else if (rinfo->has_volatile == VOLATILITY_VOLATILE) + return true; + else + { + bool hasvolatile; + + hasvolatile = contain_volatile_functions_walker((Node *) rinfo->clause, + context); + if (hasvolatile) + rinfo->has_volatile = VOLATILITY_VOLATILE; + else + rinfo->has_volatile = VOLATILITY_NOVOLATILE; + + return hasvolatile; + } + } + + if (IsA(node, PathTarget)) + { + PathTarget *target = (PathTarget *) node; + + /* + * We also do caching for PathTarget the same as we do above for + * RestrictInfos. + */ + if (target->has_volatile_expr == VOLATILITY_NOVOLATILE) + return false; + else if (target->has_volatile_expr == VOLATILITY_VOLATILE) + return true; + else + { + bool hasvolatile; + + hasvolatile = contain_volatile_functions_walker((Node *) target->exprs, + context); + + if (hasvolatile) + target->has_volatile_expr = VOLATILITY_VOLATILE; + else + target->has_volatile_expr = VOLATILITY_NOVOLATILE; + + return hasvolatile; + } + } + /* * See notes in contain_mutable_functions_walker about why we treat * MinMaxExpr, XmlExpr, and CoerceToDomain as immutable, while @@ -857,7 +612,7 @@ contain_volatile_functions_not_nextval(Node *clause) static bool contain_volatile_functions_not_nextval_checker(Oid func_id, void *context) { - return (func_id != F_NEXTVAL_OID && + return (func_id != F_NEXTVAL && func_volatile(func_id) == PROVOLATILE_VOLATILE); } @@ -1205,13 +960,16 @@ contain_nonstrict_functions_walker(Node *node, void *context) } if (IsA(node, SubscriptingRef)) { - /* - * subscripting assignment is nonstrict, but subscripting itself is - * strict - */ - if (((SubscriptingRef *) node)->refassgnexpr != NULL) - return true; + SubscriptingRef *sbsref = (SubscriptingRef *) node; + const SubscriptRoutines *sbsroutines; + /* Subscripting assignment is always presumed nonstrict */ + if (sbsref->refassgnexpr != NULL) + return true; + /* Otherwise we must look up the subscripting support methods */ + sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, NULL); + if (!(sbsroutines && sbsroutines->fetch_strict)) + return true; /* else fall through to check args */ } if (IsA(node, DistinctExpr)) @@ -1487,7 +1245,6 @@ contain_leaked_vars_walker(Node *node, void *context) case T_ScalarArrayOpExpr: case T_CoerceViaIO: case T_ArrayCoerceExpr: - case T_SubscriptingRef: /* * If node contains a leaky function call, and there's any Var @@ -1499,6 +1256,26 @@ contain_leaked_vars_walker(Node *node, void *context) return true; break; + case T_SubscriptingRef: + { + SubscriptingRef *sbsref = (SubscriptingRef *) node; + const SubscriptRoutines *sbsroutines; + + /* Consult the subscripting support method info */ + sbsroutines = getSubscriptingRoutines(sbsref->refcontainertype, + NULL); + if (!sbsroutines || + !(sbsref->refassgnexpr != NULL ? + sbsroutines->store_leakproof : + sbsroutines->fetch_leakproof)) + { + /* Node is leaky, so reject if it contains Vars */ + if (contain_var_clause(node)) + return true; + } + } + break; + case T_RowCompareExpr: { /* @@ -2286,9 +2063,9 @@ is_pseudo_constant_clause_relids(Node *clause, Relids relids) * Returns the number of different relations referenced in 'clause'. */ int -NumRelids(Node *clause) +NumRelids(PlannerInfo *root, Node *clause) { - Relids varnos = pull_varnos(clause); + Relids varnos = pull_varnos(root, clause); int result = bms_num_members(varnos); bms_free(varnos); @@ -2535,6 +2312,69 @@ eval_const_expressions(PlannerInfo *root, Node *node) return result; } +#define MIN_ARRAY_SIZE_FOR_HASHED_SAOP 9 +/*-------------------- + * convert_saop_to_hashed_saop + * + * Recursively search 'node' for ScalarArrayOpExprs and fill in the hash + * function for any ScalarArrayOpExpr that looks like it would be useful to + * evaluate using a hash table rather than a linear search. + * + * We'll use a hash table if all of the following conditions are met: + * 1. The 2nd argument of the array contain only Consts. + * 2. useOr is true. + * 3. There's valid hash function for both left and righthand operands and + * these hash functions are the same. + * 4. If the array contains enough elements for us to consider it to be + * worthwhile using a hash table rather than a linear search. + */ +void +convert_saop_to_hashed_saop(Node *node) +{ + (void) convert_saop_to_hashed_saop_walker(node, NULL); +} + +static bool +convert_saop_to_hashed_saop_walker(Node *node, void *context) +{ + if (node == NULL) + return false; + + if (IsA(node, ScalarArrayOpExpr)) + { + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node; + Expr *arrayarg = (Expr *) lsecond(saop->args); + Oid lefthashfunc; + Oid righthashfunc; + + if (saop->useOr && arrayarg && IsA(arrayarg, Const) && + !((Const *) arrayarg)->constisnull && + get_op_hash_functions(saop->opno, &lefthashfunc, &righthashfunc) && + lefthashfunc == righthashfunc) + { + Datum arrdatum = ((Const *) arrayarg)->constvalue; + ArrayType *arr = (ArrayType *) DatumGetPointer(arrdatum); + int nitems; + + /* + * Only fill in the hash functions if the array looks large enough + * for it to be worth hashing instead of doing a linear search. + */ + nitems = ArrayGetNItems(ARR_NDIM(arr), ARR_DIMS(arr)); + + if (nitems >= MIN_ARRAY_SIZE_FOR_HASHED_SAOP) + { + /* Looks good. Fill in the hash functions */ + saop->hashfuncid = lefthashfunc; + } + return true; + } + } + + return expression_tree_walker(node, convert_saop_to_hashed_saop_walker, NULL); +} + + /*-------------------- * estimate_expression_value * @@ -2701,7 +2541,8 @@ eval_const_expressions_mutator(Node *node, if (!HeapTupleIsValid(func_tuple)) elog(ERROR, "cache lookup failed for function %u", funcid); - args = expand_function_arguments(expr->args, expr->wintype, + args = expand_function_arguments(expr->args, + false, expr->wintype, func_tuple); ReleaseSysCache(func_tuple); @@ -2937,6 +2778,36 @@ eval_const_expressions_mutator(Node *node, newexpr->location = expr->location; return (Node *) newexpr; } + case T_NullIfExpr: + { + NullIfExpr *expr; + ListCell *arg; + bool has_nonconst_input = false; + + /* Copy the node and const-simplify its arguments */ + expr = (NullIfExpr *) ece_generic_processing(node); + + /* If either argument is NULL they can't be equal */ + foreach(arg, expr->args) + { + if (!IsA(lfirst(arg), Const)) + has_nonconst_input = true; + else if (((Const *) lfirst(arg))->constisnull) + return (Node *) linitial(expr->args); + } + + /* + * Need to get OID of underlying function before checking if + * the function is OK to evaluate. + */ + set_opfuncid((OpExpr *) expr); + + if (!has_nonconst_input && + ece_function_is_safe(expr->opfuncid, context)) + return ece_evaluate_expr(expr); + + return (Node *) expr; + } case T_ScalarArrayOpExpr: { ScalarArrayOpExpr *saop; @@ -3373,6 +3244,11 @@ eval_const_expressions_mutator(Node *node, * known to be immutable, and for which we need no smarts * beyond "simplify if all inputs are constants". * + * Treating SubscriptingRef this way assumes that subscripting + * fetch and assignment are both immutable. This constrains + * type-specific subscripting implementations; maybe we should + * relax it someday. + * * Treating MinMaxExpr this way amounts to assuming that the * btree comparison function it calls is immutable; see the * reasoning in contain_mutable_functions_walker. @@ -3664,10 +3540,10 @@ eval_const_expressions_mutator(Node *node, { /* * This case could be folded into the generic handling used - * for SubscriptingRef etc. But because the simplification - * logic is so trivial, applying evaluate_expr() to perform it - * would be a heavy overhead. BooleanTest is probably common - * enough to justify keeping this bespoke implementation. + * for ArrayExpr etc. But because the simplification logic is + * so trivial, applying evaluate_expr() to perform it would be + * a heavy overhead. BooleanTest is probably common enough to + * justify keeping this bespoke implementation. */ BooleanTest *btest = (BooleanTest *) node; BooleanTest *newbtest; @@ -4236,7 +4112,7 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, */ if (process_args) { - args = expand_function_arguments(args, result_type, func_tuple); + args = expand_function_arguments(args, false, result_type, func_tuple); args = (List *) expression_tree_mutator((Node *) args, eval_const_expressions_mutator, (void *) context); @@ -4306,6 +4182,15 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, * expand_function_arguments: convert named-notation args to positional args * and/or insert default args, as needed * + * Returns a possibly-transformed version of the args list. + * + * If include_out_arguments is true, then the args list and the result + * include OUT arguments. + * + * The expected result type of the call must be given, for sanity-checking + * purposes. Also, we ask the caller to provide the function's actual + * pg_proc tuple, not just its OID. + * * If we need to change anything, the input argument list is copied, not * modified. * @@ -4314,12 +4199,46 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, * will fall through very quickly if there's nothing to do. */ List * -expand_function_arguments(List *args, Oid result_type, HeapTuple func_tuple) +expand_function_arguments(List *args, bool include_out_arguments, + Oid result_type, HeapTuple func_tuple) { Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); + Oid *proargtypes = funcform->proargtypes.values; + int pronargs = funcform->pronargs; bool has_named_args = false; ListCell *lc; + /* + * If we are asked to match to OUT arguments, then use the proallargtypes + * array (which includes those); otherwise use proargtypes (which + * doesn't). Of course, if proallargtypes is null, we always use + * proargtypes. (Fetching proallargtypes is annoyingly expensive + * considering that we may have nothing to do here, but fortunately the + * common case is include_out_arguments == false.) + */ + if (include_out_arguments) + { + Datum proallargtypes; + bool isNull; + + proallargtypes = SysCacheGetAttr(PROCOID, func_tuple, + Anum_pg_proc_proallargtypes, + &isNull); + if (!isNull) + { + ArrayType *arr = DatumGetArrayTypeP(proallargtypes); + + pronargs = ARR_DIMS(arr)[0]; + if (ARR_NDIM(arr) != 1 || + pronargs < 0 || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != OIDOID) + elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls"); + Assert(pronargs >= funcform->pronargs); + proargtypes = (Oid *) ARR_DATA_PTR(arr); + } + } + /* Do we have any named arguments? */ foreach(lc, args) { @@ -4335,16 +4254,20 @@ expand_function_arguments(List *args, Oid result_type, HeapTuple func_tuple) /* If so, we must apply reorder_function_arguments */ if (has_named_args) { - args = reorder_function_arguments(args, func_tuple); + args = reorder_function_arguments(args, pronargs, func_tuple); /* Recheck argument types and add casts if needed */ - recheck_cast_function_args(args, result_type, func_tuple); + recheck_cast_function_args(args, result_type, + proargtypes, pronargs, + func_tuple); } - else if (list_length(args) < funcform->pronargs) + else if (list_length(args) < pronargs) { /* No named args, but we seem to be short some defaults */ - args = add_function_defaults(args, func_tuple); + args = add_function_defaults(args, pronargs, func_tuple); /* Recheck argument types and add casts if needed */ - recheck_cast_function_args(args, result_type, func_tuple); + recheck_cast_function_args(args, result_type, + proargtypes, pronargs, + func_tuple); } return args; @@ -4357,19 +4280,18 @@ expand_function_arguments(List *args, Oid result_type, HeapTuple func_tuple) * impossible to form a truly valid positional call without that. */ static List * -reorder_function_arguments(List *args, HeapTuple func_tuple) +reorder_function_arguments(List *args, int pronargs, HeapTuple func_tuple) { Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); - int pronargs = funcform->pronargs; int nargsprovided = list_length(args); Node *argarray[FUNC_MAX_ARGS]; ListCell *lc; int i; Assert(nargsprovided <= pronargs); - if (pronargs > FUNC_MAX_ARGS) + if (pronargs < 0 || pronargs > FUNC_MAX_ARGS) elog(ERROR, "too many function arguments"); - MemSet(argarray, 0, pronargs * sizeof(Node *)); + memset(argarray, 0, pronargs * sizeof(Node *)); /* Deconstruct the argument list into an array indexed by argnumber */ i = 0; @@ -4387,6 +4309,7 @@ reorder_function_arguments(List *args, HeapTuple func_tuple) { NamedArgExpr *na = (NamedArgExpr *) arg; + Assert(na->argnumber >= 0 && na->argnumber < pronargs); Assert(argarray[na->argnumber] == NULL); argarray[na->argnumber] = (Node *) na->arg; } @@ -4427,9 +4350,8 @@ reorder_function_arguments(List *args, HeapTuple func_tuple) * and so we know we just need to add defaults at the end. */ static List * -add_function_defaults(List *args, HeapTuple func_tuple) +add_function_defaults(List *args, int pronargs, HeapTuple func_tuple) { - Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); int nargsprovided = list_length(args); List *defaults; int ndelete; @@ -4438,7 +4360,7 @@ add_function_defaults(List *args, HeapTuple func_tuple) defaults = fetch_function_defaults(func_tuple); /* Delete any unused defaults from the list */ - ndelete = nargsprovided + list_length(defaults) - funcform->pronargs; + ndelete = nargsprovided + list_length(defaults) - pronargs; if (ndelete < 0) elog(ERROR, "not enough default arguments"); if (ndelete > 0) @@ -4487,7 +4409,9 @@ fetch_function_defaults(HeapTuple func_tuple) * caller should have already copied the list structure. */ static void -recheck_cast_function_args(List *args, Oid result_type, HeapTuple func_tuple) +recheck_cast_function_args(List *args, Oid result_type, + Oid *proargtypes, int pronargs, + HeapTuple func_tuple) { Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); int nargs; @@ -4503,9 +4427,8 @@ recheck_cast_function_args(List *args, Oid result_type, HeapTuple func_tuple) { actual_arg_types[nargs++] = exprType((Node *) lfirst(lc)); } - Assert(nargs == funcform->pronargs); - memcpy(declared_arg_types, funcform->proargtypes.values, - funcform->pronargs * sizeof(Oid)); + Assert(nargs == pronargs); + memcpy(declared_arg_types, proargtypes, pronargs * sizeof(Oid)); rettype = enforce_generic_type_consistency(actual_arg_types, declared_arg_types, nargs, @@ -4795,6 +4718,22 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid, ALLOCSET_DEFAULT_SIZES); oldcxt = MemoryContextSwitchTo(mycxt); + /* + * We need a dummy FuncExpr node containing the already-simplified + * arguments. (In some cases we don't really need it, but building it is + * cheap enough that it's not worth contortions to avoid.) + */ + fexpr = makeNode(FuncExpr); + fexpr->funcid = funcid; + fexpr->funcresulttype = result_type; + fexpr->funcretset = false; + fexpr->funcvariadic = funcvariadic; + fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */ + fexpr->funccollid = result_collid; /* doesn't matter */ + fexpr->inputcollid = input_collid; + fexpr->args = args; + fexpr->location = -1; + /* Fetch the function body */ tmp = SysCacheGetAttr(PROCOID, func_tuple, @@ -4816,49 +4755,50 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid, sqlerrcontext.previous = error_context_stack; error_context_stack = &sqlerrcontext; - /* - * Set up to handle parameters while parsing the function body. We need a - * dummy FuncExpr node containing the already-simplified arguments to pass - * to prepare_sql_fn_parse_info. (In some cases we don't really need - * that, but for simplicity we always build it.) - */ - fexpr = makeNode(FuncExpr); - fexpr->funcid = funcid; - fexpr->funcresulttype = result_type; - fexpr->funcretset = false; - fexpr->funcvariadic = funcvariadic; - fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */ - fexpr->funccollid = result_collid; /* doesn't matter */ - fexpr->inputcollid = input_collid; - fexpr->args = args; - fexpr->location = -1; - - pinfo = prepare_sql_fn_parse_info(func_tuple, - (Node *) fexpr, - input_collid); + /* If we have prosqlbody, pay attention to that not prosrc */ + tmp = SysCacheGetAttr(PROCOID, + func_tuple, + Anum_pg_proc_prosqlbody, + &isNull); + if (!isNull) + { + Node *n; + List *querytree_list; - /* fexpr also provides a convenient way to resolve a composite result */ - (void) get_expr_result_type((Node *) fexpr, - NULL, - &rettupdesc); + n = stringToNode(TextDatumGetCString(tmp)); + if (IsA(n, List)) + querytree_list = linitial_node(List, castNode(List, n)); + else + querytree_list = list_make1(n); + if (list_length(querytree_list) != 1) + goto fail; + querytree = linitial(querytree_list); + } + else + { + /* Set up to handle parameters while parsing the function body. */ + pinfo = prepare_sql_fn_parse_info(func_tuple, + (Node *) fexpr, + input_collid); - /* - * We just do parsing and parse analysis, not rewriting, because rewriting - * will not affect table-free-SELECT-only queries, which is all that we - * care about. Also, we can punt as soon as we detect more than one - * command in the function body. - */ - raw_parsetree_list = pg_parse_query(src); - if (list_length(raw_parsetree_list) != 1) - goto fail; + /* + * We just do parsing and parse analysis, not rewriting, because + * rewriting will not affect table-free-SELECT-only queries, which is + * all that we care about. Also, we can punt as soon as we detect + * more than one command in the function body. + */ + raw_parsetree_list = pg_parse_query(src); + if (list_length(raw_parsetree_list) != 1) + goto fail; - pstate = make_parsestate(NULL); - pstate->p_sourcetext = src; - sql_fn_parser_setup(pstate, pinfo); + pstate = make_parsestate(NULL); + pstate->p_sourcetext = src; + sql_fn_parser_setup(pstate, pinfo); - querytree = transformTopLevelStmt(pstate, linitial(raw_parsetree_list)); + querytree = transformTopLevelStmt(pstate, linitial(raw_parsetree_list)); - free_parsestate(pstate); + free_parsestate(pstate); + } /* * The single command must be a simple "SELECT expression". @@ -4890,6 +4830,11 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid, list_length(querytree->targetList) != 1) goto fail; + /* If the function result is composite, resolve it */ + (void) get_expr_result_type((Node *) fexpr, + NULL, + &rettupdesc); + /* * Make sure the function (still) returns what it's declared to. This * will raise an error if wrong, but that's okay since the function would @@ -4901,7 +4846,8 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid, * needed; that's probably not important, but let's be careful. */ querytree_list = list_make1(querytree); - if (check_sql_fn_retval(querytree_list, result_type, rettupdesc, + if (check_sql_fn_retval(list_make1(querytree_list), + result_type, rettupdesc, false, NULL)) goto fail; /* reject whole-tuple-result cases */ @@ -5361,14 +5307,57 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) sqlerrcontext.previous = error_context_stack; error_context_stack = &sqlerrcontext; - /* - * Set up to handle parameters while parsing the function body. We can - * use the FuncExpr just created as the input for - * prepare_sql_fn_parse_info. - */ - pinfo = prepare_sql_fn_parse_info(func_tuple, - (Node *) fexpr, - fexpr->inputcollid); + /* If we have prosqlbody, pay attention to that not prosrc */ + tmp = SysCacheGetAttr(PROCOID, + func_tuple, + Anum_pg_proc_prosqlbody, + &isNull); + if (!isNull) + { + Node *n; + + n = stringToNode(TextDatumGetCString(tmp)); + if (IsA(n, List)) + querytree_list = linitial_node(List, castNode(List, n)); + else + querytree_list = list_make1(n); + if (list_length(querytree_list) != 1) + goto fail; + querytree = linitial(querytree_list); + + querytree_list = pg_rewrite_query(querytree); + if (list_length(querytree_list) != 1) + goto fail; + querytree = linitial(querytree_list); + } + else + { + /* + * Set up to handle parameters while parsing the function body. We + * can use the FuncExpr just created as the input for + * prepare_sql_fn_parse_info. + */ + pinfo = prepare_sql_fn_parse_info(func_tuple, + (Node *) fexpr, + fexpr->inputcollid); + + /* + * Parse, analyze, and rewrite (unlike inline_function(), we can't + * skip rewriting here). We can fail as soon as we find more than one + * query, though. + */ + raw_parsetree_list = pg_parse_query(src); + if (list_length(raw_parsetree_list) != 1) + goto fail; + + querytree_list = pg_analyze_and_rewrite_params(linitial(raw_parsetree_list), + src, + (ParserSetupHook) sql_fn_parser_setup, + pinfo, NULL); + if (list_length(querytree_list) != 1) + goto fail; + querytree = linitial(querytree_list); + } /* * Also resolve the actual function result tupdesc, if composite. If the @@ -5382,23 +5371,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) rtfunc->funccoltypmods, rtfunc->funccolcollations); - /* - * Parse, analyze, and rewrite (unlike inline_function(), we can't skip - * rewriting here). We can fail as soon as we find more than one query, - * though. - */ - raw_parsetree_list = pg_parse_query(src); - if (list_length(raw_parsetree_list) != 1) - goto fail; - - querytree_list = pg_analyze_and_rewrite_params(linitial(raw_parsetree_list), - src, - (ParserSetupHook) sql_fn_parser_setup, - pinfo, NULL); - if (list_length(querytree_list) != 1) - goto fail; - querytree = linitial(querytree_list); - /* * The single command must be a plain SELECT. */ @@ -5419,7 +5391,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) * shows it's returning a whole tuple result; otherwise what it's * returning is a single composite column which is not what we need. */ - if (!check_sql_fn_retval(querytree_list, + if (!check_sql_fn_retval(list_make1(querytree_list), fexpr->funcresulttype, rettupdesc, true, NULL) && (functypclass == TYPEFUNC_COMPOSITE || @@ -5431,7 +5403,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) * check_sql_fn_retval might've inserted a projection step, but that's * fine; just make sure we use the upper Query. */ - querytree = linitial(querytree_list); + querytree = linitial_node(Query, querytree_list); /* * Looks good --- substitute parameters into the query. diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c index d07beeb35170..1747cda95c78 100644 --- a/src/backend/optimizer/util/inherit.c +++ b/src/backend/optimizer/util/inherit.c @@ -3,7 +3,7 @@ * inherit.c * Routines to process child relations in inheritance trees * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -219,6 +219,10 @@ expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel, * targetlist and update parent rel's reltarget. This should match what * preprocess_targetlist() would have added if the mark types had been * requested originally. + * + * (Someday it might be useful to fold these resjunk columns into the + * row-identity-column management used for UPDATE/DELETE. Today is not + * that day, however.) */ if (oldrc) { @@ -228,8 +232,25 @@ expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel, char resname[32]; List *newvars = NIL; - /* The old PlanRowMark should already have necessitated adding TID */ - Assert(old_allMarkTypes & ~(1 << ROW_MARK_COPY)); + /* Add TID junk Var if needed, unless we had it already */ + if (new_allMarkTypes & ~(1 << ROW_MARK_COPY) && + !(old_allMarkTypes & ~(1 << ROW_MARK_COPY))) + { + /* Need to fetch TID */ + var = makeVar(oldrc->rti, + SelfItemPointerAttributeNumber, + TIDOID, + -1, + InvalidOid, + 0); + snprintf(resname, sizeof(resname), "ctid%u", oldrc->rowmarkId); + tle = makeTargetEntry((Expr *) var, + list_length(root->processed_tlist) + 1, + pstrdup(resname), + true); + root->processed_tlist = lappend(root->processed_tlist, tle); + newvars = lappend(newvars, var); + } /* Add whole-row junk Var if needed, unless we had it already */ if ((new_allMarkTypes & (1 << ROW_MARK_COPY)) && @@ -607,6 +628,46 @@ expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, root->rowMarks = lappend(root->rowMarks, childrc); } + + /* + * If we are creating a child of the query target relation (only possible + * in UPDATE/DELETE), add it to all_result_relids, as well as + * leaf_result_relids if appropriate, and make sure that we generate + * required row-identity data. + */ + if (bms_is_member(parentRTindex, root->all_result_relids)) + { + /* OK, record the child as a result rel too. */ + root->all_result_relids = bms_add_member(root->all_result_relids, + childRTindex); + + /* Non-leaf partitions don't need any row identity info. */ + if (childrte->relkind != RELKIND_PARTITIONED_TABLE) + { + Var *rrvar; + + root->leaf_result_relids = bms_add_member(root->leaf_result_relids, + childRTindex); + + /* + * If we have any child target relations, assume they all need to + * generate a junk "tableoid" column. (If only one child survives + * pruning, we wouldn't really need this, but it's not worth + * thrashing about to avoid it.) + */ + rrvar = makeVar(childRTindex, + TableOidAttributeNumber, + OIDOID, + -1, + InvalidOid, + 0); + add_row_identity_var(root, rrvar, childRTindex, "tableoid"); + + /* Register any row-identity columns needed by this child. */ + add_row_identity_columns(root, childRTindex, + childrte, childrel); + } + } } /* @@ -770,7 +831,8 @@ apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, } /* reconstitute RestrictInfo with appropriate properties */ childquals = lappend(childquals, - make_restrictinfo((Expr *) onecq, + make_restrictinfo(root, + (Expr *) onecq, rinfo->is_pushed_down, rinfo->outerjoin_delayed, pseudoconstant, @@ -807,7 +869,7 @@ apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, /* not likely that we'd see constants here, so no check */ childquals = lappend(childquals, - make_restrictinfo(qual, + make_restrictinfo(root, qual, true, false, false, security_level, NULL, NULL, NULL)); diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c index ad35f1c4670a..717808b0377c 100644 --- a/src/backend/optimizer/util/joininfo.c +++ b/src/backend/optimizer/util/joininfo.c @@ -3,7 +3,7 @@ * joininfo.c * joininfo list manipulation routines * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c index 7f282984cc04..c444e0e32d18 100644 --- a/src/backend/optimizer/util/orclauses.c +++ b/src/backend/optimizer/util/orclauses.c @@ -3,7 +3,7 @@ * orclauses.c * Routines to extract restriction OR clauses from join OR clauses * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -268,7 +268,8 @@ consider_new_or_clause(PlannerInfo *root, RelOptInfo *rel, * Build a RestrictInfo from the new OR clause. We can assume it's valid * as a base restriction clause. */ - or_rinfo = make_restrictinfo(orclause, + or_rinfo = make_restrictinfo(root, + orclause, true, false, false, diff --git a/src/backend/optimizer/util/paramassign.c b/src/backend/optimizer/util/paramassign.c index 1942a9f78d9c..ac4fde7aa029 100644 --- a/src/backend/optimizer/util/paramassign.c +++ b/src/backend/optimizer/util/paramassign.c @@ -40,7 +40,7 @@ * doesn't really save much executor work anyway. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 769f822d955c..04916c30df2e 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1303,6 +1303,35 @@ create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, List *tidquals, return pathnode; } +/* + * create_tidrangescan_path + * Creates a path corresponding to a scan by a range of TIDs, returning + * the pathnode. + */ +TidRangePath * +create_tidrangescan_path(PlannerInfo *root, RelOptInfo *rel, + List *tidrangequals, Relids required_outer) +{ + TidRangePath *pathnode = makeNode(TidRangePath); + + pathnode->path.pathtype = T_TidRangeScan; + pathnode->path.parent = rel; + pathnode->path.pathtarget = rel->reltarget; + pathnode->path.param_info = get_baserel_parampathinfo(root, rel, + required_outer); + pathnode->path.parallel_aware = false; + pathnode->path.parallel_safe = rel->consider_parallel; + pathnode->path.parallel_workers = 0; + pathnode->path.pathkeys = NIL; /* always unordered */ + + pathnode->tidrangequals = tidrangequals; + + cost_tidrangescan(&pathnode->path, root, rel, tidrangequals, + pathnode->path.param_info); + + return pathnode; +} + /* * create_append_path * Creates a path corresponding to an Append plan, returning the @@ -1317,7 +1346,7 @@ create_append_path(PlannerInfo *root, List *subpaths, List *partial_subpaths, List *pathkeys, Relids required_outer, int parallel_workers, bool parallel_aware, - List *partitioned_rels, double rows) + double rows) { AppendPath *pathnode = makeNode(AppendPath); ListCell *l; @@ -1330,15 +1359,14 @@ create_append_path(PlannerInfo *root, /* * When generating an Append path for a partitioned table, there may be - * parameters that are useful so we can eliminate certain partitions - * during execution. Here we'll go all the way and fully populate the - * parameter info data as we do for normal base relations. However, we - * need only bother doing this for RELOPT_BASEREL rels, as - * RELOPT_OTHER_MEMBER_REL's Append paths are merged into the base rel's - * Append subpaths. It would do no harm to do this, we just avoid it to - * save wasting effort. + * parameterized quals that are useful for run-time pruning. Hence, + * compute path.param_info the same way as for any other baserel, so that + * such quals will be available for make_partition_pruneinfo(). (This + * would not work right for a non-baserel, ie a scan on a non-leaf child + * partition, and it's not necessary anyway in that case. Must skip it if + * we don't have "root", too.) */ - if (partitioned_rels != NIL && root && rel->reloptkind == RELOPT_BASEREL) + if (root && rel->reloptkind == RELOPT_BASEREL && IS_PARTITIONED_REL(rel)) pathnode->path.param_info = get_baserel_parampathinfo(root, rel, required_outer); @@ -1350,7 +1378,6 @@ create_append_path(PlannerInfo *root, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = parallel_workers; pathnode->path.pathkeys = pathkeys; - pathnode->partitioned_rels = list_copy(partitioned_rels); pathnode->path.motionHazard = false; pathnode->path.rescannable = true; @@ -1484,8 +1511,7 @@ create_merge_append_path(PlannerInfo *root, RelOptInfo *rel, List *subpaths, List *pathkeys, - Relids required_outer, - List *partitioned_rels) + Relids required_outer) { MergeAppendPath *pathnode = makeNode(MergeAppendPath); Cost input_startup_cost; @@ -1501,7 +1527,6 @@ create_merge_append_path(PlannerInfo *root, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = pathkeys; - pathnode->partitioned_rels = list_copy(partitioned_rels); pathnode->subpaths = subpaths; /* @@ -1877,7 +1902,8 @@ set_append_path_locus(PlannerInfo *root, Path *pathnode, RelOptInfo *rel, else numsegments = subpath->locus.numsegments; - restrict_info = make_restrictinfo((Expr *) makeSegmentFilterExpr( + restrict_info = make_restrictinfo(root, + (Expr *) makeSegmentFilterExpr( gp_session_id % numsegments), true, /* is_pushed_down */ false, /* outerjoin_delayed */ @@ -1998,7 +2024,7 @@ create_group_result_path(PlannerInfo *root, RelOptInfo *rel, * pathnode. */ MaterialPath * -create_material_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath) +create_material_path(RelOptInfo *rel, Path *subpath) { MaterialPath *pathnode = makeNode(MaterialPath); @@ -2023,7 +2049,6 @@ create_material_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath) pathnode->subpath = subpath; cost_material(&pathnode->path, - root, subpath->startup_cost, subpath->total_cost, subpath->rows, @@ -2032,6 +2057,64 @@ create_material_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath) return pathnode; } +/* + * create_resultcache_path + * Creates a path corresponding to a ResultCache plan, returning the + * pathnode. + */ +ResultCachePath * +create_resultcache_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, + List *param_exprs, List *hash_operators, + bool singlerow, double calls) +{ + ResultCachePath *pathnode = makeNode(ResultCachePath); + + Assert(subpath->parent == rel); + + pathnode->path.pathtype = T_ResultCache; + pathnode->path.parent = rel; + pathnode->path.pathtarget = rel->reltarget; + pathnode->path.param_info = subpath->param_info; + pathnode->path.parallel_aware = false; + pathnode->path.parallel_safe = rel->consider_parallel && + subpath->parallel_safe; + pathnode->path.parallel_workers = subpath->parallel_workers; + pathnode->path.pathkeys = subpath->pathkeys; + pathnode->path.rescannable = subpath->rescannable; + + /* + * GPDB: a Result Cache (Memoize) inherits the distribution (locus) of its + * subpath. Without this the path reaches join-motion planning with an + * uninitialized CdbPathLocus (FailedAssertion cdbpathlocus_is_valid). + */ + pathnode->path.locus = subpath->locus; + + pathnode->subpath = subpath; + pathnode->hash_operators = hash_operators; + pathnode->param_exprs = param_exprs; + pathnode->singlerow = singlerow; + pathnode->calls = calls; + + /* + * For now we set est_entries to 0. cost_resultcache_rescan() does all + * the hard work to determine how many cache entries there are likely to + * be, so it seems best to leave it up to that function to fill this field + * in. If left at 0, the executor will make a guess at a good value. + */ + pathnode->est_entries = 0; + + /* + * Add a small additional charge for caching the first entry. All the + * harder calculations for rescans are performed in + * cost_resultcache_rescan(). + */ + pathnode->path.startup_cost = subpath->startup_cost + cpu_tuple_cost; + pathnode->path.total_cost = subpath->total_cost + cpu_tuple_cost; + pathnode->path.rows = subpath->rows; + + return pathnode; +} + /* * create_unique_path * Creates a path representing elimination of distinct rows from the @@ -2229,6 +2312,7 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, pathnode->path.rows = estimate_num_groups(root, sjinfo->semi_rhs_exprs, rel->rows, + NULL, NULL); numCols = list_length(sjinfo->semi_rhs_exprs); @@ -3606,7 +3690,7 @@ create_nestloop_path(PlannerInfo *root, */ if (!outer_path->rescannable && !bms_is_empty(required_outer)) { - MaterialPath *matouter = create_material_path(root, outer_path->parent, outer_path); + MaterialPath *matouter = create_material_path(outer_path->parent, outer_path); matouter->cdb_shield_child_from_rescans = true; @@ -3623,7 +3707,7 @@ create_nestloop_path(PlannerInfo *root, * NLs potentially rescan the inner; if our inner path * isn't rescannable we have to add a materialize node */ - MaterialPath *matinner = create_material_path(root, inner_path->parent, inner_path); + MaterialPath *matinner = create_material_path(inner_path->parent, inner_path); matinner->cdb_shield_child_from_rescans = true; @@ -4110,7 +4194,33 @@ create_projection_path_with_quals(PlannerInfo *root, bool need_param) { ProjectionPath *pathnode = makeNode(ProjectionPath); - PathTarget *oldtarget = subpath->pathtarget; + PathTarget *oldtarget; + + /* + * We mustn't put a ProjectionPath directly above another; it's useless + * and will confuse create_projection_plan. Rather than making sure all + * callers handle that, let's implement it here, by stripping off any + * ProjectionPath in what we're given. Given this rule, there won't be + * more than one. + */ + if (IsA(subpath, ProjectionPath)) + { + ProjectionPath *subpp = (ProjectionPath *) subpath; + + Assert(subpp->path.parent == rel); + /* + * GPDB: The stripped ProjectionPath may carry restrict clauses (e.g. a + * correlated subquery's param filter applied above a Motion by + * bring_to_outer_query()). Those can only be evaluated by a real Result + * node, so we must not lose them when collapsing the two projections + * into one. Carry them up into the surviving ProjectionPath. + */ + if (subpp->cdb_restrict_clauses) + restrict_clauses = list_concat(list_copy(subpp->cdb_restrict_clauses), + restrict_clauses); + subpath = subpp->subpath; + Assert(!IsA(subpath, ProjectionPath)); + } pathnode->path.pathtype = T_Result; pathnode->path.parent = rel; @@ -4137,11 +4247,17 @@ create_projection_path_with_quals(PlannerInfo *root, * Note: in the latter case, create_projection_plan has to recheck our * conclusion; see comments therein. * - * GPDB: The 'restrict_clauses' is a GPDB addition. If the subpath supports - * Filters, we could push them down too. But currently this is only used on - * top of Material paths, which don't support it, so it doesn't matter. + * GPDB: The 'restrict_clauses' is a GPDB addition, used by + * bring_to_outer_query() to apply a correlated subquery's param filter + * above a Motion. We do not push those Filters down into the subpath here, + * so when restrict_clauses is non-empty we always need a real Result node + * to carry them (create_projection_plan puts them in plan->qual). Eliding + * the Result in that case would silently drop the filter and run the + * subquery uncorrelated, so only take the no-Result shortcut when there are + * no restrict clauses. */ - if (!restrict_clauses && + oldtarget = subpath->pathtarget; + if (restrict_clauses == NIL && (is_projection_capable_path(subpath) || equal(oldtarget->exprs, target->exprs))) { @@ -4361,7 +4477,7 @@ create_set_projection_path(PlannerInfo *root, * 'limit_tuples' is the estimated bound on the number of output tuples, * or -1 if no LIMIT or couldn't estimate */ -SortPath * +IncrementalSortPath * create_incremental_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, @@ -4398,7 +4514,7 @@ create_incremental_sort_path(PlannerInfo *root, sort->nPresortedCols = presorted_keys; - return pathnode; + return sort; } /* @@ -5199,6 +5315,7 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, * Creates a pathnode that represents performing INSERT/UPDATE/DELETE mods * * 'rel' is the parent relation associated with the result + * 'subpath' is a Path producing source data * 'operation' is the operation type * 'canSetTag' is true if we set the command tag/es_processed * 'nominalRelation' is the parent RT index for use of EXPLAIN @@ -5206,8 +5323,8 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, * 'partColsUpdated' is true if any partitioning columns are being updated, * either from the target relation or a descendent partitioned table. * 'resultRelations' is an integer list of actual RT indexes of target rel(s) - * 'subpaths' is a list of Path(s) producing source data (one per rel) - * 'subroots' is a list of PlannerInfo structs (one per rel) + * 'updateColnosLists' is a list of UPDATE target column number lists + * (one sublist per rel); or NIL if not an UPDATE * 'withCheckOptionLists' is a list of WCO lists (one per rel) * 'returningLists' is a list of RETURNING tlists (one per rel) * 'rowMarks' is a list of PlanRowMarks (non-locking only) @@ -5216,22 +5333,23 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, */ ModifyTablePath * create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, + Path *subpath, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, bool partColsUpdated, - List *resultRelations, List *subpaths, - List *subroots, + List *resultRelations, + List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *is_split_updates, List *rowMarks, OnConflictExpr *onconflict, int epqParam) { ModifyTablePath *pathnode = makeNode(ModifyTablePath); - double total_size; - ListCell *lc; + List *subpaths; - Assert(list_length(resultRelations) == list_length(subpaths)); - Assert(list_length(resultRelations) == list_length(subroots)); + Assert(operation == CMD_UPDATE ? + list_length(resultRelations) == list_length(updateColnosLists) : + updateColnosLists == NIL); Assert(withCheckOptionLists == NIL || list_length(resultRelations) == list_length(withCheckOptionLists)); Assert(returningLists == NIL || @@ -5252,12 +5370,23 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, /* * Put Motions on top of the subpaths as needed, and set the locus of the * ModifyTable path itself. + * + * adjust_modifytable_subpaths() wraps each subpath in the Motion required + * to distribute its output according to the target table's policy, writing + * the wrapped paths back into the list. We must keep that list and use the + * wrapped subpath below; otherwise the Motion is discarded and e.g. a + * General-locus source (VALUES, generate_series) is executed on every + * segment, inserting duplicate rows. */ + subpaths = list_make1(subpath); if (Gp_role == GP_ROLE_DISPATCH) + { pathnode->path.locus = adjust_modifytable_subpaths(root, operation, resultRelations, subpaths, is_split_updates); + subpath = (Path *) linitial(subpaths); + } else { /* don't allow split updates in utility mode. */ @@ -5274,6 +5403,7 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, /* * Compute cost & rowcount as sum of subpath costs & rowcounts. + * Compute cost & rowcount as subpath cost & rowcount (if RETURNING) * * Currently, we don't charge anything extra for the actual table * modification work, nor for the WITH CHECK OPTIONS or RETURNING @@ -5282,31 +5412,27 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, * costs to change any higher-level planning choices. But we might want * to make it look better sometime. */ - pathnode->path.startup_cost = 0; - pathnode->path.total_cost = 0; - pathnode->path.rows = 0; - total_size = 0; - foreach(lc, subpaths) + pathnode->path.startup_cost = subpath->startup_cost; + pathnode->path.total_cost = subpath->total_cost; + if (returningLists != NIL) { - Path *subpath = (Path *) lfirst(lc); + pathnode->path.rows = subpath->rows; - if (lc == list_head(subpaths)) /* first node? */ - pathnode->path.startup_cost = subpath->startup_cost; - pathnode->path.total_cost += subpath->total_cost; - pathnode->path.rows += subpath->rows; - total_size += subpath->pathtarget->width * subpath->rows; + /* + * Set width to match the subpath output. XXX this is totally wrong: + * we should return an average of the RETURNING tlist widths. But + * it's what happened historically, and improving it is a task for + * another day. (Again, it's mostly window dressing.) + */ + pathnode->path.pathtarget->width = subpath->pathtarget->width; + } + else + { + pathnode->path.rows = 0; + pathnode->path.pathtarget->width = 0; } - /* - * Set width to the average width of the subpath outputs. XXX this is - * totally wrong: we should report zero if no RETURNING, else an average - * of the RETURNING tlist widths. But it's what happened historically, - * and improving it is a task for another day. - */ - if (pathnode->path.rows > 0) - total_size /= pathnode->path.rows; - pathnode->path.pathtarget->width = rint(total_size); - + pathnode->subpath = subpath; pathnode->operation = operation; pathnode->canSetTag = canSetTag; pathnode->nominalRelation = nominalRelation; @@ -5315,7 +5441,8 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, pathnode->resultRelations = resultRelations; pathnode->is_split_updates = is_split_updates; pathnode->subpaths = subpaths; - pathnode->subroots = subroots; + pathnode->subroots = NIL; + pathnode->updateColnosLists = updateColnosLists; pathnode->withCheckOptionLists = withCheckOptionLists; pathnode->returningLists = returningLists; pathnode->rowMarks = rowMarks; @@ -5710,9 +5837,19 @@ reparameterize_path(PlannerInfo *root, Path *path, apath->path.pathkeys, required_outer, apath->path.parallel_workers, apath->path.parallel_aware, - apath->partitioned_rels, -1); } + case T_ResultCache: + { + ResultCachePath *rcpath = (ResultCachePath *) path; + + return (Path *) create_resultcache_path(root, rel, + rcpath->subpath, + rcpath->param_exprs, + rcpath->hash_operators, + rcpath->singlerow, + rcpath->calls); + } default: break; } @@ -5931,6 +6068,16 @@ do { \ } break; + case T_ResultCachePath: + { + ResultCachePath *rcpath; + + FLAT_COPY_PATH(rcpath, path, ResultCachePath); + REPARAMETERIZE_CHILD_PATH(rcpath->subpath); + new_path = (Path *) rcpath; + } + break; + case T_GatherPath: { GatherPath *gpath; diff --git a/src/backend/optimizer/util/placeholder.c b/src/backend/optimizer/util/placeholder.c index d4d0a9d5167c..22befab5f5d4 100644 --- a/src/backend/optimizer/util/placeholder.c +++ b/src/backend/optimizer/util/placeholder.c @@ -4,7 +4,7 @@ * PlaceHolderVar and PlaceHolderInfo manipulation routines * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -98,7 +98,7 @@ find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv, * ph_eval_at. If no referenced rels are within the syntactic scope, * force evaluation at the syntactic location. */ - rels_used = pull_varnos((Node *) phv->phexpr); + rels_used = pull_varnos(root, (Node *) phv->phexpr); phinfo->ph_lateral = bms_difference(rels_used, phv->phrels); if (bms_is_empty(phinfo->ph_lateral)) phinfo->ph_lateral = NULL; /* make it exactly NULL if empty */ @@ -404,8 +404,10 @@ add_placeholders_to_base_rels(PlannerInfo *root) * and if they contain lateral references, add those references to the * joinrel's direct_lateral_relids. * - * A join rel should emit a PlaceHolderVar if (a) the PHV is needed above - * this join level and (b) the PHV can be computed at or below this level. + * A join rel should emit a PlaceHolderVar if (a) the PHV can be computed + * at or below this join level and (b) the PHV is needed above this level. + * However, condition (a) is sufficient to add to direct_lateral_relids, + * as explained below. */ void add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, @@ -418,11 +420,11 @@ add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, { PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc); - /* Is it still needed above this joinrel? */ - if (bms_nonempty_difference(phinfo->ph_needed, relids)) + /* Is it computable here? */ + if (bms_is_subset(phinfo->ph_eval_at, relids)) { - /* Is it computable here? */ - if (bms_is_subset(phinfo->ph_eval_at, relids)) + /* Is it still needed above this joinrel? */ + if (bms_nonempty_difference(phinfo->ph_needed, relids)) { /* Yup, add it to the output */ joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, @@ -450,12 +452,26 @@ add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, joinrel->reltarget->cost.startup += cost.startup; joinrel->reltarget->cost.per_tuple += cost.per_tuple; } - - /* Adjust joinrel's direct_lateral_relids as needed */ - joinrel->direct_lateral_relids = - bms_add_members(joinrel->direct_lateral_relids, - phinfo->ph_lateral); } + + /* + * Also adjust joinrel's direct_lateral_relids to include the + * PHV's source rel(s). We must do this even if we're not + * actually going to emit the PHV, otherwise join_is_legal() will + * reject valid join orderings. (In principle maybe we could + * instead remove the joinrel's lateral_relids dependency; but + * that's complicated to get right, and cases where we're not + * going to emit the PHV are too rare to justify the work.) + * + * In principle we should only do this if the join doesn't yet + * include the PHV's source rel(s). But our caller + * build_join_rel() will clean things up by removing the join's + * own relids from its direct_lateral_relids, so we needn't + * account for that here. + */ + joinrel->direct_lateral_relids = + bms_add_members(joinrel->direct_lateral_relids, + phinfo->ph_lateral); } } } diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index dc017bca4f60..d9d3ff974582 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -6,7 +6,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,7 +28,6 @@ #include "access/transam.h" #include "access/xlog.h" #include "catalog/catalog.h" -#include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/pg_am.h" #include "catalog/pg_proc.h" @@ -37,6 +36,7 @@ #include "miscadmin.h" #include "commands/tablecmds.h" #include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" #include "nodes/supportnodes.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" @@ -136,7 +136,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, relation = table_open(relationObjectId, NoLock); /* Temporary and unlogged relations are inaccessible during recovery. */ - if (!RelationNeedsWAL(relation) && RecoveryInProgress()) + if (!RelationIsPermanent(relation) && RecoveryInProgress()) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot access temporary or unlogged relations during recovery"))); @@ -298,6 +298,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, info->amhasgettuple = (amroutine->amgettuple != NULL); info->amhasgetbitmap = amroutine->amgetbitmap != NULL && relation->rd_tableam->scan_bitmap_next_block != NULL; + info->amcanmarkpos = (amroutine->ammarkpos != NULL && + amroutine->amrestrpos != NULL); info->amcostestimate = amroutine->amcostestimate; Assert(info->amcostestimate != NULL); @@ -479,6 +481,12 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, /* Collect info about relation's foreign keys, if relevant */ get_relation_foreign_keys(root, rel, relation, inhparent); + /* Collect info about functions implemented by the rel's table AM. */ + if (relation->rd_tableam && + relation->rd_tableam->scan_set_tidrange != NULL && + relation->rd_tableam->scan_getnextslot_tidrange != NULL) + rel->amflags |= AMFLAG_HAS_TID_RANGE; + /* * Collect info about relation's partitioning scheme, if any. Only * inheritance parents may be partitioned. @@ -672,6 +680,17 @@ cdb_estimate_partitioned_numtuples(Relation rel) childtuples = childrel->rd_rel->reltuples; + /* + * Since PG 14, reltuples == -1 means the relation has never been + * vacuumed or analyzed. Treat it like the pre-14 value of 0: without + * this, never-analyzed relations stop counting as empty (and a + * partitioned table would even sum -1 per child), so ORCA derives + * stats for them and issues missing-statistics notices that GPDB 6 + * never issued for such relations. + */ + if (childtuples < 0) + childtuples = 0; + if (gp_enable_relsize_collection && childtuples == 0) { RelOptInfo *dummy_reloptinfo; @@ -794,9 +813,11 @@ get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel, memcpy(info->conpfeqop, cachedfk->conpfeqop, sizeof(info->conpfeqop)); /* zero out fields to be filled by match_foreign_keys_to_quals */ info->nmatched_ec = 0; + info->nconst_ec = 0; info->nmatched_rcols = 0; info->nmatched_ri = 0; memset(info->eclass, 0, sizeof(info->eclass)); + memset(info->fk_eclass_member, 0, sizeof(info->fk_eclass_member)); memset(info->rinfos, 0, sizeof(info->rinfos)); root->fkey_list = lappend(root->fkey_list, info); @@ -1204,11 +1225,6 @@ estimate_rel_size(Relation rel, int32 *attr_widths, /* it has storage, ok to call the smgr */ curpages = RelationGetNumberOfBlocks(rel); - /* coerce values in pg_class to more desirable types */ - relpages = (BlockNumber) rel->rd_rel->relpages; - reltuples = (double) rel->rd_rel->reltuples; - relallvisible = (BlockNumber) rel->rd_rel->relallvisible; - /* report estimated # pages */ *pages = curpages; /* quick exit if rel is clearly empty */ @@ -1218,6 +1234,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths, *allvisfrac = 0; break; } + /* coerce values in pg_class to more desirable types */ relpages = (BlockNumber) rel->rd_rel->relpages; reltuples = (double) rel->rd_rel->reltuples; @@ -1236,12 +1253,12 @@ estimate_rel_size(Relation rel, int32 *attr_widths, } /* estimate number of tuples from previous tuple density */ - if (relpages > 0) + if (reltuples >= 0 && relpages > 0) density = reltuples / (double) relpages; else { /* - * When we have no data because the relation was truncated, + * If we have no data because the relation was never vacuumed, * estimate tuple width from attribute datatypes. We assume * here that the pages are completely full, which is OK for * tables (since they've presumably not been VACUUMed yet) but @@ -1289,6 +1306,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths, break; case RELKIND_FOREIGN_TABLE: /* Just use whatever's in pg_class */ + /* Note that FDW must cope if reltuples is -1! */ *pages = rel->rd_rel->relpages; *tuples = rel->rd_rel->reltuples; *allvisfrac = 0; @@ -1524,6 +1542,7 @@ get_relation_constraints(PlannerInfo *root, static List * get_relation_statistics(RelOptInfo *rel, Relation relation) { + Index varno = rel->relid; List *statoidlist; List *stainfos = NIL; ListCell *l; @@ -1537,6 +1556,7 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) HeapTuple htup; HeapTuple dtup; Bitmapset *keys = NULL; + List *exprs = NIL; int i; htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statOid)); @@ -1556,6 +1576,49 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) for (i = 0; i < staForm->stxkeys.dim1; i++) keys = bms_add_member(keys, staForm->stxkeys.values[i]); + /* + * Preprocess expressions (if any). We read the expressions, run them + * through eval_const_expressions, and fix the varnos. + */ + { + bool isnull; + Datum datum; + + /* decode expression (if any) */ + datum = SysCacheGetAttr(STATEXTOID, htup, + Anum_pg_statistic_ext_stxexprs, &isnull); + + if (!isnull) + { + char *exprsString; + + exprsString = TextDatumGetCString(datum); + exprs = (List *) stringToNode(exprsString); + pfree(exprsString); + + /* + * Run the expressions through eval_const_expressions. This is + * not just an optimization, but is necessary, because the + * planner will be comparing them to similarly-processed qual + * clauses, and may fail to detect valid matches without this. + * We must not use canonicalize_qual, however, since these + * aren't qual expressions. + */ + exprs = (List *) eval_const_expressions(NULL, (Node *) exprs); + + /* May as well fix opfuncids too */ + fix_opfuncids((Node *) exprs); + + /* + * Modify the copies we obtain from the relcache to have the + * correct varno for the parent relation, so that they match + * up correctly against qual clauses. + */ + if (varno != 1) + ChangeVarNodes((Node *) exprs, 1, varno, 0); + } + } + /* add one StatisticExtInfo for each kind built */ if (statext_is_kind_built(dtup, STATS_EXT_NDISTINCT)) { @@ -1565,6 +1628,7 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) info->rel = rel; info->kind = STATS_EXT_NDISTINCT; info->keys = bms_copy(keys); + info->exprs = exprs; stainfos = lappend(stainfos, info); } @@ -1577,6 +1641,7 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) info->rel = rel; info->kind = STATS_EXT_DEPENDENCIES; info->keys = bms_copy(keys); + info->exprs = exprs; stainfos = lappend(stainfos, info); } @@ -1589,6 +1654,20 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) info->rel = rel; info->kind = STATS_EXT_MCV; info->keys = bms_copy(keys); + info->exprs = exprs; + + stainfos = lappend(stainfos, info); + } + + if (statext_is_kind_built(dtup, STATS_EXT_EXPRESSIONS)) + { + StatisticExtInfo *info = makeNode(StatisticExtInfo); + + info->statOid = statOid; + info->rel = rel; + info->kind = STATS_EXT_EXPRESSIONS; + info->keys = bms_copy(keys); + info->exprs = exprs; stainfos = lappend(stainfos, info); } @@ -1669,18 +1748,11 @@ relation_excluded_by_constraints(PlannerInfo *root, /* * When constraint_exclusion is set to 'partition' we only handle - * appendrel members. Normally, they are RELOPT_OTHER_MEMBER_REL - * relations, but we also consider inherited target relations as - * appendrel members for the purposes of constraint exclusion - * (since, indeed, they were appendrel members earlier in - * inheritance_planner). - * - * In both cases, partition pruning was already applied, so there - * is no need to consider the rel's partition constraints here. + * appendrel members. Partition pruning has already been applied, + * so there is no need to consider the rel's partition constraints + * here. */ - if (rel->reloptkind == RELOPT_OTHER_MEMBER_REL || - (rel->relid == root->parse->resultRelation && - root->inhTargetKind != INHKIND_NONE)) + if (rel->reloptkind == RELOPT_OTHER_MEMBER_REL) break; /* appendrel member, so process it */ return false; @@ -1693,9 +1765,7 @@ relation_excluded_by_constraints(PlannerInfo *root, * its partition constraints haven't been considered yet, so * include them in the processing here. */ - if (rel->reloptkind == RELOPT_BASEREL && - !(rel->relid == root->parse->resultRelation && - root->inhTargetKind != INHKIND_NONE)) + if (rel->reloptkind == RELOPT_BASEREL) include_partition = true; break; /* always try to exclude */ } @@ -2387,10 +2457,14 @@ set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel, { PartitionDesc partdesc; - /* Create the PartitionDirectory infrastructure if we didn't already */ + /* + * Create the PartitionDirectory infrastructure if we didn't already. + */ if (root->glob->partition_directory == NULL) + { root->glob->partition_directory = - CreatePartitionDirectory(CurrentMemoryContext); + CreatePartitionDirectory(CurrentMemoryContext, true); + } partdesc = PartitionDirectoryLookup(root->glob->partition_directory, relation); diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c index 60cab386ef34..16e213fabaef 100644 --- a/src/backend/optimizer/util/predtest.c +++ b/src/backend/optimizer/util/predtest.c @@ -4,7 +4,7 @@ * Routines to attempt to prove logical implications between predicate * expressions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1988,7 +1988,6 @@ lookup_proof_cache(Oid pred_op, Oid clause_op, bool refute_it) /* First time through: initialize the hash table */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(OprProofCacheKey); ctl.entrysize = sizeof(OprProofCacheEntry); OprProofCacheHash = hash_create("Btree proof lookup cache", 256, diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 9a682275f4a8..7af1fb8cf904 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -238,6 +238,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->subroot = NULL; rel->subplan_params = NIL; rel->rel_parallel_workers = -1; /* set up in get_relation_info */ + rel->amflags = 0; rel->serverid = InvalidOid; rel->userid = rte->checkAsUser; rel->useridiscurrent = false; @@ -262,7 +263,6 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->all_partrels = NULL; rel->partexprs = NULL; rel->nullable_partexprs = NULL; - rel->partitioned_child_rels = NIL; /* * Pass assorted information down the inheritance hierarchy. @@ -431,7 +431,6 @@ build_join_rel_hash(PlannerInfo *root) ListCell *l; /* Create the hash table */ - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Relids); hash_ctl.entrysize = sizeof(JoinHashEntry); hash_ctl.hash = bitmap_hash; @@ -685,6 +684,7 @@ build_join_rel(PlannerInfo *root, joinrel->subroot = NULL; joinrel->subplan_params = NIL; joinrel->rel_parallel_workers = -1; + joinrel->amflags = 0; joinrel->serverid = InvalidOid; joinrel->userid = InvalidOid; joinrel->useridiscurrent = false; @@ -710,7 +710,6 @@ build_join_rel(PlannerInfo *root, joinrel->all_partrels = NULL; joinrel->partexprs = NULL; joinrel->nullable_partexprs = NULL; - joinrel->partitioned_child_rels = NIL; /* Compute information relevant to the foreign relations. */ set_foreign_rel_properties(joinrel, outer_rel, inner_rel); @@ -874,6 +873,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, joinrel->eclass_indexes = NULL; joinrel->subroot = NULL; joinrel->subplan_params = NIL; + joinrel->amflags = 0; joinrel->serverid = InvalidOid; joinrel->userid = InvalidOid; joinrel->useridiscurrent = false; @@ -895,7 +895,6 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, joinrel->all_partrels = NULL; joinrel->partexprs = NULL; joinrel->nullable_partexprs = NULL; - joinrel->partitioned_child_rels = NIL; joinrel->top_parent_relids = bms_union(outer_rel->top_parent_relids, inner_rel->top_parent_relids); @@ -1023,8 +1022,6 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, foreach(vars, input_rel->reltarget->exprs) { Var *var = (Var *) lfirst(vars); - RelOptInfo *baserel; - int ndx; /* * Ignore PlaceHolderVars in the input tlists; we'll make our own @@ -1042,21 +1039,35 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, elog(ERROR, "unexpected node type in rel targetlist: %d", (int) nodeTag(var)); - /* Get the Var's original base rel */ - baserel = find_base_rel(root, var->varno); - - /* System-defined attribute, whole row, or user-defined attribute */ - Assert(var->varattno >= baserel->min_attr && - var->varattno <= baserel->max_attr); - - /* Is it still needed above this joinrel? */ - ndx = var->varattno - baserel->min_attr; - if (bms_nonempty_difference(baserel->attr_needed[ndx], relids)) + if (var->varno == ROWID_VAR) { - /* Yup, add it to the output */ - joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, var); + /* UPDATE/DELETE row identity vars are always needed */ + RowIdentityVarInfo *ridinfo = (RowIdentityVarInfo *) + list_nth(root->row_identity_vars, var->varattno - 1); + + joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, + var); /* Vars have cost zero, so no need to adjust reltarget->cost */ - joinrel->reltarget->width += baserel->attr_widths[ndx]; + joinrel->reltarget->width += ridinfo->rowidwidth; + } + else + { + RelOptInfo *baserel; + int ndx; + + /* Get the Var's original base rel */ + baserel = find_base_rel(root, var->varno); + + /* Is it still needed above this joinrel? */ + ndx = var->varattno - baserel->min_attr; + if (bms_nonempty_difference(baserel->attr_needed[ndx], relids)) + { + /* Yup, add it to the output */ + joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, + var); + /* Vars have cost zero, so no need to adjust reltarget->cost */ + joinrel->reltarget->width += baserel->attr_widths[ndx]; + } } } } diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index cfce68f1bfd7..1cb5d8a0e43c 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -3,7 +3,7 @@ * restrictinfo.c * RestrictInfo node manipulation routines. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,7 +21,8 @@ #include "optimizer/restrictinfo.h" -static RestrictInfo *make_restrictinfo_internal(Expr *clause, +static RestrictInfo *make_restrictinfo_internal(PlannerInfo *root, + Expr *clause, Expr *orclause, bool is_pushed_down, bool outerjoin_delayed, @@ -30,7 +31,8 @@ static RestrictInfo *make_restrictinfo_internal(Expr *clause, Relids required_relids, Relids outer_relids, Relids nullable_relids); -static Expr *make_sub_restrictinfos(Expr *clause, +static Expr *make_sub_restrictinfos(PlannerInfo *root, + Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, @@ -56,7 +58,8 @@ static Expr *make_sub_restrictinfos(Expr *clause, * later. */ RestrictInfo * -make_restrictinfo(Expr *clause, +make_restrictinfo(PlannerInfo *root, + Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, @@ -70,7 +73,8 @@ make_restrictinfo(Expr *clause, * above each subclause of the top-level AND/OR structure. */ if (is_orclause(clause)) - return (RestrictInfo *) make_sub_restrictinfos(clause, + return (RestrictInfo *) make_sub_restrictinfos(root, + clause, is_pushed_down, outerjoin_delayed, pseudoconstant, @@ -82,7 +86,8 @@ make_restrictinfo(Expr *clause, /* Shouldn't be an AND clause, else AND/OR flattening messed up */ Assert(!is_andclause(clause)); - return make_restrictinfo_internal(clause, + return make_restrictinfo_internal(root, + clause, NULL, is_pushed_down, outerjoin_delayed, @@ -99,7 +104,8 @@ make_restrictinfo(Expr *clause, * Common code for the main entry points and the recursive cases. */ static RestrictInfo * -make_restrictinfo_internal(Expr *clause, +make_restrictinfo_internal(PlannerInfo *root, + Expr *clause, Expr *orclause, bool is_pushed_down, bool outerjoin_delayed, @@ -144,14 +150,21 @@ make_restrictinfo_internal(Expr *clause, else restrictinfo->leakproof = false; /* really, "don't know" */ + /* + * Mark volatility as unknown. The contain_volatile_functions function + * will determine if there are any volatile functions when called for the + * first time with this RestrictInfo. + */ + restrictinfo->has_volatile = VOLATILITY_UNKNOWN; + /* * If it's a binary opclause, set up left/right relids info. In any case * set up the total clause relids info. */ if (is_opclause(clause) && list_length(((OpExpr *) clause)->args) == 2) { - restrictinfo->left_relids = pull_varnos(get_leftop(clause)); - restrictinfo->right_relids = pull_varnos(get_rightop(clause)); + restrictinfo->left_relids = pull_varnos(root, get_leftop(clause)); + restrictinfo->right_relids = pull_varnos(root, get_rightop(clause)); restrictinfo->clause_relids = bms_union(restrictinfo->left_relids, restrictinfo->right_relids); @@ -178,7 +191,7 @@ make_restrictinfo_internal(Expr *clause, restrictinfo->left_relids = NULL; restrictinfo->right_relids = NULL; /* and get the total relid set the hard way */ - restrictinfo->clause_relids = pull_varnos((Node *) clause); + restrictinfo->clause_relids = pull_varnos(root, (Node *) clause); } /* required_relids defaults to clause_relids */ @@ -217,6 +230,8 @@ make_restrictinfo_internal(Expr *clause, restrictinfo->left_mcvfreq = -1; restrictinfo->right_mcvfreq = -1; + restrictinfo->hasheqoperator = InvalidOid; + return restrictinfo; } @@ -238,7 +253,8 @@ make_restrictinfo_internal(Expr *clause, * contained rels. */ static Expr * -make_sub_restrictinfos(Expr *clause, +make_sub_restrictinfos(PlannerInfo *root, + Expr *clause, bool is_pushed_down, bool outerjoin_delayed, bool pseudoconstant, @@ -254,7 +270,8 @@ make_sub_restrictinfos(Expr *clause, foreach(temp, ((BoolExpr *) clause)->args) orlist = lappend(orlist, - make_sub_restrictinfos(lfirst(temp), + make_sub_restrictinfos(root, + lfirst(temp), is_pushed_down, outerjoin_delayed, pseudoconstant, @@ -262,7 +279,8 @@ make_sub_restrictinfos(Expr *clause, NULL, outer_relids, nullable_relids)); - return (Expr *) make_restrictinfo_internal(clause, + return (Expr *) make_restrictinfo_internal(root, + clause, make_orclause(orlist), is_pushed_down, outerjoin_delayed, @@ -279,7 +297,8 @@ make_sub_restrictinfos(Expr *clause, foreach(temp, ((BoolExpr *) clause)->args) andlist = lappend(andlist, - make_sub_restrictinfos(lfirst(temp), + make_sub_restrictinfos(root, + lfirst(temp), is_pushed_down, outerjoin_delayed, pseudoconstant, @@ -290,7 +309,8 @@ make_sub_restrictinfos(Expr *clause, return make_andclause(andlist); } else - return (Expr *) make_restrictinfo_internal(clause, + return (Expr *) make_restrictinfo_internal(root, + clause, NULL, is_pushed_down, outerjoin_delayed, @@ -361,6 +381,7 @@ commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op) result->right_bucketsize = rinfo->left_bucketsize; result->left_mcvfreq = rinfo->right_mcvfreq; result->right_mcvfreq = rinfo->left_mcvfreq; + result->hasheqoperator = InvalidOid; return result; } diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c index 323bba35923b..f32d014fa8a8 100644 --- a/src/backend/optimizer/util/tlist.c +++ b/src/backend/optimizer/util/tlist.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2007-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,11 +32,6 @@ typedef struct maxSortGroupRef_context static bool maxSortGroupRef_walker(Node *node, maxSortGroupRef_context *cxt); -/* Test if an expression node represents a SRF call. Beware multiple eval! */ -#define IS_SRF_CALL(node) \ - ((IsA(node, FuncExpr) && ((FuncExpr *) (node))->funcretset) || \ - (IsA(node, OpExpr) && ((OpExpr *) (node))->opretset)) - /* * Data structures for split_pathtarget_at_srfs(). To preserve the identity * of sortgroupref items even if they are textually equal(), what we track is @@ -843,6 +838,13 @@ make_pathtarget_from_tlist(List *tlist) i++; } + /* + * Mark volatility as unknown. The contain_volatile_functions function + * will determine if there are any volatile functions when called for the + * first time with this PathTarget. + */ + target->has_volatile_expr = VOLATILITY_UNKNOWN; + return target; } @@ -944,6 +946,16 @@ add_column_to_pathtarget(PathTarget *target, Expr *expr, Index sortgroupref) target->sortgrouprefs = (Index *) palloc0(nexprs * sizeof(Index)); target->sortgrouprefs[nexprs - 1] = sortgroupref; } + + /* + * Reset has_volatile_expr to UNKNOWN. We just leave it up to + * contain_volatile_functions to set this properly again. Technically we + * could save some effort here and just check the new Expr, but it seems + * better to keep the logic for setting this flag in one location rather + * than duplicating the logic here. + */ + if (target->has_volatile_expr == VOLATILITY_NOVOLATILE) + target->has_volatile_expr = VOLATILITY_UNKNOWN; } /* diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index 19d40c658ff3..0f7c26553ed3 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -9,7 +9,7 @@ * contains variables. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. @@ -26,6 +26,7 @@ #include "access/sysattr.h" #include "nodes/nodeFuncs.h" #include "optimizer/optimizer.h" +#include "optimizer/placeholder.h" #include "optimizer/prep.h" #include "optimizer/walkers.h" #include "parser/parsetree.h" @@ -36,6 +37,7 @@ typedef struct { Relids varnos; + PlannerInfo *root; int sublevels_up; } pull_varnos_context; @@ -183,9 +185,24 @@ cdb_walk_vars(Node *node, */ Relids -pull_varnos(Node *node) +pull_varnos(PlannerInfo *root, Node *node) { - return pull_varnos_of_level(node, 0); + pull_varnos_context context; + + context.varnos = NULL; + context.root = root; + context.sublevels_up = 0; + + /* + * Must be prepared to start with a Query or a bare expression tree; if + * it's a Query, we don't want to increment sublevels_up. + */ + query_or_expression_tree_walker(node, + pull_varnos_walker, + (void *) &context, + 0); + + return context.varnos; } /* @@ -194,11 +211,12 @@ pull_varnos(Node *node) * Only Vars of the specified level are considered. */ Relids -pull_varnos_of_level(Node *node, int levelsup) +pull_varnos_of_level(PlannerInfo *root, Node *node, int levelsup) { pull_varnos_context context; context.varnos = NULL; + context.root = root; context.sublevels_up = levelsup; /* @@ -236,33 +254,56 @@ pull_varnos_walker(Node *node, pull_varnos_context *context) } if (IsA(node, PlaceHolderVar)) { - /* - * A PlaceHolderVar acts as a variable of its syntactic scope, or - * lower than that if it references only a subset of the rels in its - * syntactic scope. It might also contain lateral references, but we - * should ignore such references when computing the set of varnos in - * an expression tree. Also, if the PHV contains no variables within - * its syntactic scope, it will be forced to be evaluated exactly at - * the syntactic scope, so take that as the relid set. - */ PlaceHolderVar *phv = (PlaceHolderVar *) node; - pull_varnos_context subcontext; - subcontext.varnos = NULL; - subcontext.sublevels_up = context->sublevels_up; - (void) pull_varnos_walker((Node *) phv->phexpr, &subcontext); + /* + * If a PlaceHolderVar is not of the target query level, ignore it, + * instead recursing into its expression to see if it contains any + * vars that are of the target level. + */ if (phv->phlevelsup == context->sublevels_up) { - subcontext.varnos = bms_int_members(subcontext.varnos, - phv->phrels); - if (bms_is_empty(subcontext.varnos)) + /* + * Ideally, the PHV's contribution to context->varnos is its + * ph_eval_at set. However, this code can be invoked before + * that's been computed. If we cannot find a PlaceHolderInfo, + * fall back to the conservative assumption that the PHV will be + * evaluated at its syntactic level (phv->phrels). + * + * There is a second hazard: this code is also used to examine + * qual clauses during deconstruct_jointree, when we may have a + * PlaceHolderInfo but its ph_eval_at value is not yet final, so + * that theoretically we could obtain a relid set that's smaller + * than we'd see later on. That should never happen though, + * because we deconstruct the jointree working upwards. Any outer + * join that forces delay of evaluation of a given qual clause + * will be processed before we examine that clause here, so the + * ph_eval_at value should have been updated to include it. + */ + PlaceHolderInfo *phinfo = NULL; + + if (phv->phlevelsup == 0) + { + ListCell *lc; + + foreach(lc, context->root->placeholder_list) + { + phinfo = (PlaceHolderInfo *) lfirst(lc); + if (phinfo->phid == phv->phid) + break; + phinfo = NULL; + } + } + if (phinfo != NULL) + context->varnos = bms_add_members(context->varnos, + phinfo->ph_eval_at); + else context->varnos = bms_add_members(context->varnos, phv->phrels); + return false; /* don't recurse into expression */ } - context->varnos = bms_join(context->varnos, subcontext.varnos); - return false; } - if (IsA(node, Query)) + else if (IsA(node, Query)) { /* Recurse into RTE subquery or not-yet-planned sublink subquery */ bool result; diff --git a/src/backend/optimizer/util/walkers.c b/src/backend/optimizer/util/walkers.c index e8247bcc128e..d730443778d8 100644 --- a/src/backend/optimizer/util/walkers.c +++ b/src/backend/optimizer/util/walkers.c @@ -502,8 +502,6 @@ plan_tree_walker(Node *node, case T_ModifyTable: if (walk_plan_node_fields((Plan *) node, walker, context)) return true; - if (walker((Node *) ((ModifyTable *) node)->plans, context)) - return true; if (walker((Node *) ((ModifyTable *) node)->withCheckOptionLists, context)) return true; if (walker((Node *) ((ModifyTable *) node)->onConflictSet, context)) diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 5c263161cf94..44afb180d05f 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -16,7 +16,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/parser/analyze.c @@ -28,6 +28,7 @@ #include "access/sysattr.h" #include "catalog/pg_am.h" +#include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -47,10 +48,16 @@ #include "parser/parse_param.h" #include "parser/parse_relation.h" #include "parser/parse_target.h" +#include "parser/parse_type.h" #include "parser/parsetree.h" #include "rewrite/rewriteManip.h" #include "utils/guc.h" +#include "utils/backend_status.h" +#include "utils/builtins.h" +#include "utils/guc.h" +#include "utils/queryjumble.h" #include "utils/rel.h" +#include "utils/syscache.h" #include "cdb/cdbhash.h" #include "cdb/cdbvars.h" @@ -101,10 +108,13 @@ static void coerceSetOpTypes(ParseState *pstate, Node *sop, static void select_setop_types(ParseState *pstate, setop_types_ctx *ctx, SetOperation op, List **selected_types, List **selected_typmods); static void determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist); +static Query *transformReturnStmt(ParseState *pstate, ReturnStmt *stmt); static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); static List *transformReturningList(ParseState *pstate, List *returningList); static List *transformUpdateTargetList(ParseState *pstate, List *targetList); +static Query *transformPLAssignStmt(ParseState *pstate, + PLAssignStmt *stmt); static Query *transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt); static Query *transformExplainStmt(ParseState *pstate, @@ -146,6 +156,7 @@ parse_analyze(RawStmt *parseTree, const char *sourceText, { ParseState *pstate = make_parsestate(NULL); Query *query; + JumbleState *jstate = NULL; Assert(sourceText != NULL); /* required as of 8.4 */ @@ -158,11 +169,16 @@ parse_analyze(RawStmt *parseTree, const char *sourceText, query = transformTopLevelStmt(pstate, parseTree); + if (IsQueryIdEnabled()) + jstate = JumbleQuery(query, sourceText); + if (post_parse_analyze_hook) - (*post_parse_analyze_hook) (pstate, query); + (*post_parse_analyze_hook) (pstate, query, jstate); free_parsestate(pstate); + pgstat_report_query_id(query->queryId, false); + return query; } @@ -179,6 +195,7 @@ parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, { ParseState *pstate = make_parsestate(NULL); Query *query; + JumbleState *jstate = NULL; Assert(sourceText != NULL); /* required as of 8.4 */ @@ -191,11 +208,16 @@ parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, /* make sure all is well with parameter types */ check_variable_parameters(pstate, query); + if (IsQueryIdEnabled()) + jstate = JumbleQuery(query, sourceText); + if (post_parse_analyze_hook) - (*post_parse_analyze_hook) (pstate, query); + (*post_parse_analyze_hook) (pstate, query, jstate); free_parsestate(pstate); + pgstat_report_query_id(query->queryId, false); + return query; } @@ -379,6 +401,15 @@ transformStmt(ParseState *pstate, Node *parseTree) } break; + case T_ReturnStmt: + result = transformReturnStmt(pstate, (ReturnStmt *) parseTree); + break; + + case T_PLAssignStmt: + result = transformPLAssignStmt(pstate, + (PLAssignStmt *) parseTree); + break; + /* * Special cases */ @@ -445,6 +476,7 @@ analyze_requires_snapshot(RawStmt *parseTree) case T_DeleteStmt: case T_UpdateStmt: case T_SelectStmt: + case T_PLAssignStmt: result = true; break; @@ -954,6 +986,18 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) attr_num - FirstLowInvalidHeapAttributeNumber); } + /* + * If we have any clauses yet to process, set the query namespace to + * contain only the target relation, removing any entries added in a + * sub-SELECT or VALUES list. + */ + if (stmt->onConflictClause || stmt->returningList) + { + pstate->p_namespace = NIL; + addNSItemToQuery(pstate, pstate->p_target_nsitem, + false, true, true); + } + /* Process ON CONFLICT, if any. */ if (stmt->onConflictClause) qry->onConflict = transformOnConflictClause(pstate, @@ -977,14 +1021,10 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * RETURNING will work. Also, remove any namespace entries added in a * sub-SELECT or VALUES list. */ + /* Process RETURNING, if any. */ if (stmt->returningList) - { - pstate->p_namespace = NIL; - addNSItemToQuery(pstate, pstate->p_target_nsitem, - false, true, true); qry->returningList = transformReturningList(pstate, stmt->returningList); - } /* done building the range table and jointree */ qry->rtable = pstate->p_rtable; @@ -1112,6 +1152,7 @@ static OnConflictExpr * transformOnConflictClause(ParseState *pstate, OnConflictClause *onConflictClause) { + ParseNamespaceItem *exclNSItem = NULL; List *arbiterElems; Node *arbiterWhere; Oid arbiterConstraint; @@ -1121,16 +1162,16 @@ transformOnConflictClause(ParseState *pstate, List *exclRelTlist = NIL; OnConflictExpr *result; - /* Process the arbiter clause, ON CONFLICT ON (...) */ - transformOnConflictArbiter(pstate, onConflictClause, &arbiterElems, - &arbiterWhere, &arbiterConstraint); - - /* Process DO UPDATE */ + /* + * If this is ON CONFLICT ... UPDATE, first create the range table entry + * for the EXCLUDED pseudo relation, so that that will be present while + * processing arbiter expressions. (You can't actually reference it from + * there, but this provides a useful error message if you try.) + */ if (onConflictClause->action == ONCONFLICT_UPDATE) { Relation targetrel = pstate->p_target_relation; RangeTblEntry *rte = pstate->p_target_nsitem->p_rte; /* GPDB */ - ParseNamespaceItem *exclNSItem; RangeTblEntry *exclRte; /* @@ -1158,6 +1199,11 @@ transformOnConflictClause(ParseState *pstate, exclRte = exclNSItem->p_rte; exclRelIndex = exclNSItem->p_rtindex; + /* + * relkind is set to composite to signal that we're not dealing with + * an actual relation, and no permission checks are required on it. + * (We'll check the actual target relation, instead.) + */ exclRte->relkind = RELKIND_COMPOSITE_TYPE; exclRte->requiredPerms = 0; /* other permissions fields in exclRte are already empty */ @@ -1165,14 +1211,27 @@ transformOnConflictClause(ParseState *pstate, /* Create EXCLUDED rel's targetlist for use by EXPLAIN */ exclRelTlist = BuildOnConflictExcludedTargetlist(targetrel, exclRelIndex); + } + + /* Process the arbiter clause, ON CONFLICT ON (...) */ + transformOnConflictArbiter(pstate, onConflictClause, &arbiterElems, + &arbiterWhere, &arbiterConstraint); + + /* Process DO UPDATE */ + if (onConflictClause->action == ONCONFLICT_UPDATE) + { + /* + * Expressions in the UPDATE targetlist need to be handled like UPDATE + * not INSERT. We don't need to save/restore this because all INSERT + * expressions have been parsed already. + */ + pstate->p_is_insert = false; /* - * Add EXCLUDED and the target RTE to the namespace, so that they can - * be used in the UPDATE subexpressions. + * Add the EXCLUDED pseudo relation to the query namespace, making it + * available in the UPDATE subexpressions. */ addNSItemToQuery(pstate, exclNSItem, false, true, true); - addNSItemToQuery(pstate, pstate->p_target_nsitem, - false, true, true); /* * Now transform the UPDATE subexpressions. @@ -1183,6 +1242,14 @@ transformOnConflictClause(ParseState *pstate, onConflictWhere = transformWhereClause(pstate, onConflictClause->whereClause, EXPR_KIND_WHERE, "WHERE"); + + /* + * Remove the EXCLUDED pseudo relation from the query namespace, since + * it's not supposed to be available in RETURNING. (Maybe someday we + * could allow that, and drop this step.) + */ + Assert((ParseNamespaceItem *) llast(pstate->p_namespace) == exclNSItem); + pstate->p_namespace = list_delete_last(pstate->p_namespace); } /* Finally, build ON CONFLICT DO [NOTHING | UPDATE] expression */ @@ -1388,6 +1455,7 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) qry->sortClause, EXPR_KIND_GROUP_BY, false /* allow SQL92 rules */ ); + qry->groupDistinct = stmt->groupDistinct; /* * SCATTER BY clause on a table function TableValueExpr subquery. @@ -1585,9 +1653,8 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt) for (i = 0; i < sublist_length; i++) { Oid coltype; - int32 coltypmod = -1; + int32 coltypmod; Oid colcoll; - bool first = true; coltype = select_common_type(pstate, colexprs[i], "VALUES", NULL); @@ -1597,19 +1664,9 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt) col = coerce_to_common_type(pstate, col, coltype, "VALUES"); lfirst(lc) = (void *) col; - if (first) - { - coltypmod = exprTypmod(col); - first = false; - } - else - { - /* As soon as we see a non-matching typmod, fall back to -1 */ - if (coltypmod >= 0 && coltypmod != exprTypmod(col)) - coltypmod = -1; - } } + coltypmod = select_common_typmod(pstate, colexprs[i], coltype); colcoll = select_common_collation(pstate, colexprs[i], true); coltypes = lappend_oid(coltypes, coltype); @@ -1637,8 +1694,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt) Node *col = (Node *) lfirst(lc); List *sublist = lfirst(lc2); - /* sublist pointer in exprsLists won't need adjustment */ - (void) lappend(sublist, col); + sublist = lappend(sublist, col); } list_free(colexprs[i]); } @@ -1900,6 +1956,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) NIL, NIL, NULL, + NULL, false); sv_namespace = pstate->p_namespace; @@ -1970,6 +2027,33 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) return qry; } +/* + * Make a SortGroupClause node for a SetOperationStmt's groupClauses + */ +SortGroupClause * +makeSortGroupClauseForSetOp(Oid rescoltype) +{ + SortGroupClause *grpcl = makeNode(SortGroupClause); + Oid sortop; + Oid eqop; + bool hashable; + + /* determine the eqop and optional sortop */ + get_sort_group_operators(rescoltype, + false, true, false, + &sortop, &eqop, NULL, + &hashable); + + /* we don't have a tlist yet, so can't assign sortgrouprefs */ + grpcl->tleSortGroupRef = 0; + grpcl->eqop = eqop; + grpcl->sortop = sortop; + grpcl->nulls_first = false; /* OK with or without sortop */ + grpcl->hashable = hashable; + + return grpcl; +} + /* * transformSetOperationTree * Recursively transform leaves and internal nodes of a set-op tree @@ -2455,40 +2539,18 @@ coerceSetOpTypes(ParseState *pstate, Node *sop, Node *rcolnode = (Node *) rtle->expr; Oid lcoltype = exprType(lcolnode); Oid rcoltype = exprType(rcolnode); - int32 lcoltypmod = exprTypmod(lcolnode); - int32 rcoltypmod = exprTypmod(rcolnode); - Node *bestexpr = NULL; + Node *bestexpr; int bestlocation; Oid rescoltype = pct ? lfirst_oid(pct) : InvalidOid; int32 rescoltypmod = pcm ? lfirst_int(pcm) : -1; Oid rescolcoll; - /* - * If the preprocessed coltype is InvalidOid, we fall back - * to the old style type resolution for backward - * compatibility. See transformSetOperationStmt for the reason. - */ - if (!OidIsValid(rescoltype)) - { - /* select common type, same as CASE et al */ - rescoltype = select_common_type(pstate, - list_make2(lcolnode, rcolnode), - context, - &bestexpr); - bestlocation = exprLocation(bestexpr); - /* if same type and same typmod, use typmod; else default */ - if (lcoltype == rcoltype && lcoltypmod == rcoltypmod) - rescoltypmod = lcoltypmod; - } - else - { - /* - * If we used the preselected type, arbitrarily use the left - * query's expression for error reporting purposes. - */ - bestexpr = lcolnode; - bestlocation = exprLocation(lcolnode); - } + /* select common type, same as CASE et al */ + rescoltype = select_common_type(pstate, + list_make2(lcolnode, rcolnode), + context, + &bestexpr); + bestlocation = exprLocation(bestexpr); /* * Verify the coercions are actually possible. If not, we'd fail @@ -2539,6 +2601,10 @@ coerceSetOpTypes(ParseState *pstate, Node *sop, rtle->expr = (Expr *) rcolnode; } + rescoltypmod = select_common_typmod(pstate, + list_make2(lcolnode, rcolnode), + rescoltype); + /* * Select common collation. A common collation is required for * all set operators except UNION ALL; see SQL:2008 7.13 op != SETOP_UNION || !op->all) { - SortGroupClause *grpcl = makeNode(SortGroupClause); - Oid sortop; - Oid eqop; - bool hashable; ParseCallbackState pcbstate; setup_parser_errposition_callback(&pcbstate, pstate, bestlocation); - /* determine the eqop and optional sortop */ - get_sort_group_operators(rescoltype, - false, true, false, - &sortop, &eqop, NULL, - &hashable); + op->groupClauses = lappend(op->groupClauses, + makeSortGroupClauseForSetOp(rescoltype)); cancel_parser_errposition_callback(&pcbstate); - - /* we don't have a tlist yet, so can't assign sortgrouprefs */ - grpcl->tleSortGroupRef = 0; - grpcl->eqop = eqop; - grpcl->sortop = sortop; - grpcl->nulls_first = false; /* OK with or without sortop */ - grpcl->hashable = hashable; - - op->groupClauses = lappend(op->groupClauses, grpcl); } /* @@ -2675,6 +2725,36 @@ determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist) } +/* + * transformReturnStmt - + * transforms a return statement + */ +static Query * +transformReturnStmt(ParseState *pstate, ReturnStmt *stmt) +{ + Query *qry = makeNode(Query); + + qry->commandType = CMD_SELECT; + qry->isReturn = true; + + qry->targetList = list_make1(makeTargetEntry((Expr *) transformExpr(pstate, stmt->returnval, EXPR_KIND_SELECT_TARGET), + 1, NULL, false)); + + if (pstate->p_resolve_unknowns) + resolveTargetListUnknowns(pstate, qry->targetList); + qry->rtable = pstate->p_rtable; + qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); + qry->hasSubLinks = pstate->p_hasSubLinks; + qry->hasWindowFuncs = pstate->p_hasWindowFuncs; + qry->hasTargetSRFs = pstate->p_hasTargetSRFs; + qry->hasAggs = pstate->p_hasAggs; + + assign_query_collations(pstate, qry); + + return qry; +} + + /* * transformUpdateStmt - * transforms an update statement @@ -2764,7 +2844,6 @@ transformUpdateTargetList(ParseState *pstate, List *origTlist) RangeTblEntry *target_rte; ListCell *orig_tl; ListCell *tl; - TupleDesc tupdesc = pstate->p_target_relation->rd_att; tlist = transformTargetList(pstate, origTlist, EXPR_KIND_UPDATE_SOURCE); @@ -2823,41 +2902,9 @@ transformUpdateTargetList(ParseState *pstate, List *origTlist) if (orig_tl != NULL) elog(ERROR, "UPDATE target count mismatch --- internal error"); - fill_extraUpdatedCols(target_rte, tupdesc); - return tlist; } -/* - * Record in extraUpdatedCols generated columns referencing updated base - * columns. - */ -void -fill_extraUpdatedCols(RangeTblEntry *target_rte, TupleDesc tupdesc) -{ - if (tupdesc->constr && - tupdesc->constr->has_generated_stored) - { - for (int i = 0; i < tupdesc->constr->num_defval; i++) - { - AttrDefault defval = tupdesc->constr->defval[i]; - Node *expr; - Bitmapset *attrs_used = NULL; - - /* skip if not generated column */ - if (!TupleDescAttr(tupdesc, defval.adnum - 1)->attgenerated) - continue; - - expr = stringToNode(defval.adbin); - pull_varattnos(expr, 1, &attrs_used); - - if (bms_overlap(target_rte->updatedCols, attrs_used)) - target_rte->extraUpdatedCols = bms_add_member(target_rte->extraUpdatedCols, - defval.adnum - FirstLowInvalidHeapAttributeNumber); - } - } -} - /* * transformReturningList - * handle a RETURNING clause in INSERT/UPDATE/DELETE @@ -2909,6 +2956,255 @@ transformReturningList(ParseState *pstate, List *returningList) } +/* + * transformPLAssignStmt - + * transform a PL/pgSQL assignment statement + * + * If there is no opt_indirection, the transformed statement looks like + * "SELECT a_expr ...", except the expression has been cast to the type of + * the target. With indirection, it's still a SELECT, but the expression will + * incorporate FieldStore and/or assignment SubscriptingRef nodes to compute a + * new value for a container-type variable represented by the target. The + * expression references the target as the container source. + */ +static Query * +transformPLAssignStmt(ParseState *pstate, PLAssignStmt *stmt) +{ + Query *qry = makeNode(Query); + ColumnRef *cref = makeNode(ColumnRef); + List *indirection = stmt->indirection; + int nnames = stmt->nnames; + SelectStmt *sstmt = stmt->val; + Node *target; + Oid targettype; + int32 targettypmod; + Oid targetcollation; + List *tlist; + TargetEntry *tle; + Oid type_id; + Node *qual; + ListCell *l; + + /* + * First, construct a ColumnRef for the target variable. If the target + * has more than one dotted name, we have to pull the extra names out of + * the indirection list. + */ + cref->fields = list_make1(makeString(stmt->name)); + cref->location = stmt->location; + if (nnames > 1) + { + /* avoid munging the raw parsetree */ + indirection = list_copy(indirection); + while (--nnames > 0 && indirection != NIL) + { + Node *ind = (Node *) linitial(indirection); + + if (!IsA(ind, String)) + elog(ERROR, "invalid name count in PLAssignStmt"); + cref->fields = lappend(cref->fields, ind); + indirection = list_delete_first(indirection); + } + } + + /* + * Transform the target reference. Typically we will get back a Param + * node, but there's no reason to be too picky about its type. + */ + target = transformExpr(pstate, (Node *) cref, + EXPR_KIND_UPDATE_TARGET); + targettype = exprType(target); + targettypmod = exprTypmod(target); + targetcollation = exprCollation(target); + + /* + * The rest mostly matches transformSelectStmt, except that we needn't + * consider WITH or INTO, and we build a targetlist our own way. + */ + qry->commandType = CMD_SELECT; + pstate->p_is_insert = false; + + /* make FOR UPDATE/FOR SHARE info available to addRangeTableEntry */ + pstate->p_locking_clause = sstmt->lockingClause; + + /* make WINDOW info available for window functions, too */ + pstate->p_windowdefs = sstmt->windowClause; + + /* process the FROM clause */ + transformFromClause(pstate, sstmt->fromClause); + + /* initially transform the targetlist as if in SELECT */ + tlist = transformTargetList(pstate, sstmt->targetList, + EXPR_KIND_SELECT_TARGET); + + /* we should have exactly one targetlist item */ + if (list_length(tlist) != 1) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg_plural("assignment source returned %d column", + "assignment source returned %d columns", + list_length(tlist), + list_length(tlist)))); + + tle = linitial_node(TargetEntry, tlist); + + /* + * This next bit is similar to transformAssignedExpr; the key difference + * is we use COERCION_PLPGSQL not COERCION_ASSIGNMENT. + */ + type_id = exprType((Node *) tle->expr); + + pstate->p_expr_kind = EXPR_KIND_UPDATE_TARGET; + + if (indirection) + { + tle->expr = (Expr *) + transformAssignmentIndirection(pstate, + target, + stmt->name, + false, + targettype, + targettypmod, + targetcollation, + indirection, + list_head(indirection), + (Node *) tle->expr, + COERCION_PLPGSQL, + exprLocation(target)); + } + else if (targettype != type_id && + (targettype == RECORDOID || ISCOMPLEX(targettype)) && + (type_id == RECORDOID || ISCOMPLEX(type_id))) + { + /* + * Hack: do not let coerce_to_target_type() deal with inconsistent + * composite types. Just pass the expression result through as-is, + * and let the PL/pgSQL executor do the conversion its way. This is + * rather bogus, but it's needed for backwards compatibility. + */ + } + else + { + /* + * For normal non-qualified target column, do type checking and + * coercion. + */ + Node *orig_expr = (Node *) tle->expr; + + tle->expr = (Expr *) + coerce_to_target_type(pstate, + orig_expr, type_id, + targettype, targettypmod, + COERCION_PLPGSQL, + COERCE_IMPLICIT_CAST, + -1); + /* With COERCION_PLPGSQL, this error is probably unreachable */ + if (tle->expr == NULL) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("variable \"%s\" is of type %s" + " but expression is of type %s", + stmt->name, + format_type_be(targettype), + format_type_be(type_id)), + errhint("You will need to rewrite or cast the expression."), + parser_errposition(pstate, exprLocation(orig_expr)))); + } + + pstate->p_expr_kind = EXPR_KIND_NONE; + + qry->targetList = list_make1(tle); + + /* transform WHERE */ + qual = transformWhereClause(pstate, sstmt->whereClause, + EXPR_KIND_WHERE, "WHERE"); + + /* initial processing of HAVING clause is much like WHERE clause */ + qry->havingQual = transformWhereClause(pstate, sstmt->havingClause, + EXPR_KIND_HAVING, "HAVING"); + + /* + * Transform sorting/grouping stuff. Do ORDER BY first because both + * transformGroupClause and transformDistinctClause need the results. Note + * that these functions can also change the targetList, so it's passed to + * them by reference. + */ + qry->sortClause = transformSortClause(pstate, + sstmt->sortClause, + &qry->targetList, + EXPR_KIND_ORDER_BY, + false /* allow SQL92 rules */ ); + + qry->groupClause = transformGroupClause(pstate, + sstmt->groupClause, + &qry->groupingSets, + &qry->targetList, + qry->sortClause, + EXPR_KIND_GROUP_BY, + false /* allow SQL92 rules */ ); + + if (sstmt->distinctClause == NIL) + { + qry->distinctClause = NIL; + qry->hasDistinctOn = false; + } + else if (linitial(sstmt->distinctClause) == NULL) + { + /* We had SELECT DISTINCT */ + qry->distinctClause = transformDistinctClause(pstate, + &qry->targetList, + qry->sortClause, + false); + qry->hasDistinctOn = false; + } + else + { + /* We had SELECT DISTINCT ON */ + qry->distinctClause = transformDistinctOnClause(pstate, + sstmt->distinctClause, + &qry->targetList, + qry->sortClause); + qry->hasDistinctOn = true; + } + + /* transform LIMIT */ + qry->limitOffset = transformLimitClause(pstate, sstmt->limitOffset, + EXPR_KIND_OFFSET, "OFFSET", + sstmt->limitOption); + qry->limitCount = transformLimitClause(pstate, sstmt->limitCount, + EXPR_KIND_LIMIT, "LIMIT", + sstmt->limitOption); + qry->limitOption = sstmt->limitOption; + + /* transform window clauses after we have seen all window functions */ + qry->windowClause = transformWindowDefinitions(pstate, + pstate->p_windowdefs, + &qry->targetList); + + qry->rtable = pstate->p_rtable; + qry->jointree = makeFromExpr(pstate->p_joinlist, qual); + + qry->hasSubLinks = pstate->p_hasSubLinks; + qry->hasWindowFuncs = pstate->p_hasWindowFuncs; + qry->hasTargetSRFs = pstate->p_hasTargetSRFs; + qry->hasAggs = pstate->p_hasAggs; + + foreach(l, sstmt->lockingClause) + { + transformLockingClause(pstate, qry, + (LockingClause *) lfirst(l), false); + } + + assign_query_collations(pstate, qry); + + /* this must be done after collations, for reliable comparison of exprs */ + if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual) + parseCheckAggregates(pstate, qry); + + return qry; +} + + /* * transformDeclareCursorStmt - * transform a DECLARE CURSOR Statement @@ -2934,7 +3230,17 @@ transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt) (stmt->options & CURSOR_OPT_NO_SCROLL)) ereport(ERROR, (errcode(ERRCODE_INVALID_CURSOR_DEFINITION), - errmsg("cannot specify both SCROLL and NO SCROLL"))); + /* translator: %s is a SQL keyword */ + errmsg("cannot specify both %s and %s", + "SCROLL", "NO SCROLL"))); + + if ((stmt->options & CURSOR_OPT_ASENSITIVE) && + (stmt->options & CURSOR_OPT_INSENSITIVE)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_CURSOR_DEFINITION), + /* translator: %s is a SQL keyword */ + errmsg("cannot specify both %s and %s", + "ASENSITIVE", "INSENSITIVE"))); /* Transform contained query, not allowing SELECT INTO */ query = transformStmt(pstate, stmt->query); @@ -2993,10 +3299,10 @@ transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt) /* FOR UPDATE and INSENSITIVE are not compatible */ if (query->rowMarks != NIL && (stmt->options & CURSOR_OPT_INSENSITIVE)) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errcode(ERRCODE_INVALID_CURSOR_DEFINITION), /*------ translator: %s is a SQL row locking clause such as FOR UPDATE */ - errmsg("DECLARE INSENSITIVE CURSOR ... %s is not supported", + errmsg("DECLARE INSENSITIVE CURSOR ... %s is not valid", LCS_asString(((RowMarkClause *) linitial(query->rowMarks))->strength)), errdetail("Insensitive cursors must be READ ONLY."))); @@ -3128,8 +3434,6 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt) /* * transform a CallStmt - * - * We need to do parse analysis on the procedure call and its arguments. */ static Query * transformCallStmt(ParseState *pstate, CallStmt *stmt) @@ -3137,8 +3441,17 @@ transformCallStmt(ParseState *pstate, CallStmt *stmt) List *targs; ListCell *lc; Node *node; + FuncExpr *fexpr; + HeapTuple proctup; + Datum proargmodes; + bool isNull; + List *outargs = NIL; Query *result; + /* + * First, do standard parse analysis on the procedure call and its + * arguments, allowing us to identify the called procedure. + */ targs = NIL; foreach(lc, stmt->funccall->args) { @@ -3157,8 +3470,85 @@ transformCallStmt(ParseState *pstate, CallStmt *stmt) assign_expr_collations(pstate, node); - stmt->funcexpr = castNode(FuncExpr, node); + fexpr = castNode(FuncExpr, node); + + proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); + if (!HeapTupleIsValid(proctup)) + elog(ERROR, "cache lookup failed for function %u", fexpr->funcid); + + /* + * Expand the argument list to deal with named-argument notation and + * default arguments. For ordinary FuncExprs this'd be done during + * planning, but a CallStmt doesn't go through planning, and there seems + * no good reason not to do it here. + */ + fexpr->args = expand_function_arguments(fexpr->args, + true, + fexpr->funcresulttype, + proctup); + + /* Fetch proargmodes; if it's null, there are no output args */ + proargmodes = SysCacheGetAttr(PROCOID, proctup, + Anum_pg_proc_proargmodes, + &isNull); + if (!isNull) + { + /* + * Split the list into input arguments in fexpr->args and output + * arguments in stmt->outargs. INOUT arguments appear in both lists. + */ + ArrayType *arr; + int numargs; + char *argmodes; + List *inargs; + int i; + + arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */ + numargs = list_length(fexpr->args); + if (ARR_NDIM(arr) != 1 || + ARR_DIMS(arr)[0] != numargs || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != CHAROID) + elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls", + numargs); + argmodes = (char *) ARR_DATA_PTR(arr); + + inargs = NIL; + i = 0; + foreach(lc, fexpr->args) + { + Node *n = lfirst(lc); + + switch (argmodes[i]) + { + case PROARGMODE_IN: + case PROARGMODE_VARIADIC: + inargs = lappend(inargs, n); + break; + case PROARGMODE_OUT: + outargs = lappend(outargs, n); + break; + case PROARGMODE_INOUT: + inargs = lappend(inargs, n); + outargs = lappend(outargs, copyObject(n)); + break; + default: + /* note we don't support PROARGMODE_TABLE */ + elog(ERROR, "invalid argmode %c for procedure", + argmodes[i]); + break; + } + i++; + } + fexpr->args = inargs; + } + + stmt->funcexpr = fexpr; + stmt->outargs = outargs; + ReleaseSysCache(proctup); + + /* represent the command as a utility Query */ result = makeNode(Query); result->commandType = CMD_UTILITY; result->utilityStmt = (Node *) stmt; @@ -3214,7 +3604,7 @@ CheckSelectLocking(Query *qry, LockClauseStrength strength) translator: %s is a SQL row locking clause such as FOR UPDATE */ errmsg("%s is not allowed with DISTINCT clause", LCS_asString(strength)))); - if (qry->groupClause != NIL) + if (qry->groupClause != NIL || qry->groupingSets != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), /*------ diff --git a/src/backend/parser/check_keywords.pl b/src/backend/parser/check_keywords.pl index 702c97bba2aa..598f3d20e357 100644 --- a/src/backend/parser/check_keywords.pl +++ b/src/backend/parser/check_keywords.pl @@ -4,10 +4,10 @@ # Usage: check_keywords.pl gram.y kwlist.h # src/backend/parser/check_keywords.pl -# Copyright (c) 2009-2020, PostgreSQL Global Development Group +# Copyright (c) 2009-2021, PostgreSQL Global Development Group -use warnings; use strict; +use warnings; my $gram_filename = $ARGV[0]; my $kwlist_filename = $ARGV[1]; @@ -21,6 +21,28 @@ sub error return; } +# Check alphabetical order of a set of keyword symbols +# (note these are NOT the actual keyword strings) +sub check_alphabetical_order +{ + my ($listname, $list) = @_; + my $prevkword = ''; + + foreach my $kword (@$list) + { + # Some symbols have a _P suffix. Remove it for the comparison. + my $bare_kword = $kword; + $bare_kword =~ s/_P$//; + if ($bare_kword le $prevkword) + { + error + "'$bare_kword' after '$prevkword' in $listname list is misplaced"; + } + $prevkword = $bare_kword; + } + return; +} + $, = ' '; # set output field separator $\ = "\n"; # set output record separator @@ -33,9 +55,11 @@ sub error open(my $gram, '<', $gram_filename) || die("Could not open : $gram_filename"); my $kcat; +my $in_bare_labels; my $comment; my @arr; my %keywords; +my @bare_label_keywords; line: while (my $S = <$gram>) { @@ -51,7 +75,7 @@ sub error $s = '[/][*]', $S =~ s#$s# /* #g; $s = '[*][/]', $S =~ s#$s# */ #g; - if (!($kcat)) + if (!($kcat) && !($in_bare_labels)) { # Is this the beginning of a keyword list? @@ -63,6 +87,10 @@ sub error next line; } } + + # Is this the beginning of the bare_label_keyword list? + $in_bare_labels = 1 if ($S =~ m/^bare_label_keyword:/); + next line; } @@ -97,7 +125,8 @@ sub error { # end of keyword list - $kcat = ''; + undef $kcat; + undef $in_bare_labels; next; } @@ -107,31 +136,21 @@ sub error } # Put this keyword into the right list - push @{ $keywords{$kcat} }, $arr[$fieldIndexer]; + if ($in_bare_labels) + { + push @bare_label_keywords, $arr[$fieldIndexer]; + } + else + { + push @{ $keywords{$kcat} }, $arr[$fieldIndexer]; + } } } close $gram; # Check that each keyword list is in alphabetical order (just for neatnik-ism) -my ($prevkword, $bare_kword); -foreach my $kcat (keys %keyword_categories) -{ - $prevkword = ''; - - foreach my $kword (@{ $keywords{$kcat} }) - { - - # Some keyword have a _P suffix. Remove it for the comparison. - $bare_kword = $kword; - $bare_kword =~ s/_P$//; - if ($bare_kword le $prevkword) - { - error - "'$bare_kword' after '$prevkword' in $kcat list is misplaced"; - } - $prevkword = $bare_kword; - } -} +check_alphabetical_order($_, $keywords{$_}) for (keys %keyword_categories); +check_alphabetical_order('bare_label_keyword', \@bare_label_keywords); # Transform the keyword lists into hashes. # kwhashes is a hash of hashes, keyed by keyword category id, @@ -147,6 +166,7 @@ sub error $kwhashes{$kcat_id} = $hash; } +my %bare_label_keywords = map { $_ => 1 } @bare_label_keywords; # Now read in kwlist.h @@ -160,11 +180,12 @@ sub error { my ($line) = $_; - if ($line =~ /^PG_KEYWORD\(\"(.*)\", (.*), (.*)\)/) + if ($line =~ /^PG_KEYWORD\(\"(.*)\", (.*), (.*), (.*)\)/) { my ($kwstring) = $1; my ($kwname) = $2; my ($kwcat_id) = $3; + my ($collabel) = $4; # Check that the list is in alphabetical order (critical!) if ($kwstring le $prevkwstring) @@ -197,7 +218,7 @@ sub error "keyword name '$kwname' doesn't match keyword string '$kwstring'"; } - # Check that the keyword is present in the grammar + # Check that the keyword is present in the right category list %kwhash = %{ $kwhashes{$kwcat_id} }; if (!(%kwhash)) @@ -219,6 +240,29 @@ sub error delete $kwhashes{$kwcat_id}->{$kwname}; } } + + # Check that the keyword's collabel property matches gram.y + if ($collabel eq 'BARE_LABEL') + { + unless ($bare_label_keywords{$kwname}) + { + error + "'$kwname' is marked as BARE_LABEL in kwlist.h, but it is missing from gram.y's bare_label_keyword rule"; + } + } + elsif ($collabel eq 'AS_LABEL') + { + if ($bare_label_keywords{$kwname}) + { + error + "'$kwname' is marked as AS_LABEL in kwlist.h, but it is listed in gram.y's bare_label_keyword rule"; + } + } + else + { + error + "'$collabel' not recognized in kwlist.h. Expected either 'BARE_LABEL' or 'AS_LABEL'"; + } } } close $kwlist; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 9b3d2eec1281..f8087f44c56a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -9,6 +9,7 @@ * Portions Copyright (c) 2006-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -62,7 +63,6 @@ #include "nodes/nodeFuncs.h" #include "parser/gramparse.h" #include "parser/parser.h" -#include "parser/parse_expr.h" #include "storage/lmgr.h" #include "utils/date.h" #include "utils/datetime.h" @@ -142,6 +142,13 @@ typedef struct SelectLimit LimitOption limitOption; } SelectLimit; +/* Private struct for the result of group_clause production */ +typedef struct GroupClause +{ + bool distinct; + List *list; +} GroupClause; + /* ConstraintAttributeSpec yields an integer bitmask of these flags: */ #define CAS_NOT_DEFERRABLE 0x01 #define CAS_DEFERRABLE 0x02 @@ -246,6 +253,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ WindowDef *windef; JoinExpr *jexpr; IndexElem *ielem; + StatsElem *selem; Alias *alias; RangeVar *range; IntoClause *into; @@ -265,9 +273,11 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ RoleSpec *rolespec; DistributionKeyElem *dkelem; struct SelectLimit *selectlimit; + SetQuantifier setquantifier; + struct GroupClause *groupclause; } -%type stmt schema_stmt +%type stmt toplevel_stmt schema_stmt routine_body_stmt AlterEventTrigStmt AlterCollationStmt AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterEnumStmt AlterFdwStmt AlterForeignServerStmt AlterGroupStmt @@ -294,9 +304,9 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ GrantStmt GrantRoleStmt ImportForeignSchemaStmt IndexStmt InsertStmt ListenStmt LoadStmt LockStmt NotifyStmt ExplainableStmt PreparableStmt CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt - RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt + RemoveFuncStmt RemoveOperStmt RenameStmt ReturnStmt RevokeStmt RevokeRoleStmt RuleActionStmt RuleActionStmtOrEmpty RuleStmt - SecLabelStmt SelectStmt TransactionStmt TruncateStmt + SecLabelStmt SelectStmt TransactionStmt TransactionStmtLegacy TruncateStmt UnlistenStmt UpdateStmt VacuumStmt VariableResetStmt VariableSetStmt VariableShowStmt ViewStmt CheckPointStmt CreateConversionStmt @@ -319,6 +329,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type select_no_parens select_with_parens select_clause simple_select values_clause + PLpgSQL_Expr PLAssignStmt %type alter_column_default opclass_item opclass_drop alter_using %type add_drop opt_asc_desc opt_nulls_order @@ -351,10 +362,10 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ ext_opt_encoding_item %type opt_lock lock_type cast_context -%type vac_analyze_option_name -%type vac_analyze_option_elem -%type vac_analyze_option_list -%type vac_analyze_option_arg +%type utility_option_name +%type utility_option_elem +%type utility_option_list +%type utility_option_arg %type drop_option %type opt_or_replace opt_no opt_grant_grant_option opt_grant_admin_option @@ -429,29 +440,30 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type vacuum_relation %type opt_select_limit select_limit limit_clause -%type stmtblock stmtmulti +%type parse_toplevel stmtmulti routine_body_stmt_list OptTableElementList TableElementList OptInherit definition OptExtTableElementList ExtTableElementList OptTypedTableElementList TypedTableElementList reloptions opt_reloptions - OptWith distinct_clause opt_all_clause opt_definition func_args func_args_list + OptWith opt_definition func_args func_args_list func_args_with_defaults func_args_with_defaults_list aggr_args aggr_args_list - func_as createfunc_opt_list alterfunc_opt_list + func_as createfunc_opt_list opt_createfunc_opt_list alterfunc_opt_list old_aggr_definition old_aggr_list oper_argtypes RuleActionList RuleActionMulti cdb_string_list opt_column_list columnList opt_name_list exttab_auth_list keyvalue_list - sort_clause opt_sort_clause sortby_list index_params + sort_clause opt_sort_clause sortby_list index_params stats_params opt_include opt_c_include index_including_params name_list role_list from_clause from_list opt_array_bounds qualified_name_list qualified_name_list_with_only any_name any_name_list type_name_list any_operator expr_list attrs + distinct_clause opt_distinct_clause target_list opt_target_list insert_column_list set_target_list set_clause_list set_clause def_list operator_def_list indirection opt_indirection - reloption_list group_clause TriggerFuncArgs opclass_item_list opclass_drop_list + reloption_list TriggerFuncArgs opclass_item_list opclass_drop_list opclass_purpose opt_opfamily transaction_mode_list_or_empty OptTableFuncElementList TableFuncElementList opt_type_modifiers prep_type_clause @@ -462,15 +474,15 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ relation_expr_list dostmt_opt_list transform_element_list transform_type_list TriggerTransitions TriggerReferencing - publication_name_list vacuum_relation_list opt_vacuum_relation_list drop_option_list +%type opt_routine_body +%type group_clause %type group_by_list %type group_by_item empty_grouping_set rollup_clause cube_clause %type grouping_sets_clause %type opt_publication_for_tables publication_for_tables -%type publication_name_item %type table_value_select_clause @@ -498,9 +510,9 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type for_locking_item %type for_locking_clause opt_for_locking_clause for_locking_items %type locked_rels_list -%type all_or_distinct +%type set_quantifier -%type join_outer join_qual +%type join_qual %type join_type %type extract_list overlay_list position_list @@ -516,7 +528,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type copy_from opt_program -%type opt_column event cursor_options opt_hold opt_set_data +%type event cursor_options opt_hold opt_set_data %type object_type_any_name object_type_name object_type_name_on_any_name drop_type_name @@ -544,24 +556,26 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type def_arg columnElem where_clause where_or_current_clause a_expr b_expr c_expr AexprConst indirection_el opt_slice_bound columnref in_expr having_clause func_table xmltable array_expr - ExclusionWhereClause operator_def_arg + OptWhereClause operator_def_arg %type rowsfrom_item rowsfrom_list opt_col_def_list %type opt_ordinality %type ExclusionConstraintList ExclusionConstraintElem -%type func_arg_list +%type func_arg_list func_arg_list_opt %type func_arg_expr %type row explicit_row implicit_row type_list array_expr_list %type case_expr case_arg when_clause when_operand case_default %type when_clause_list %type decode_expr search_result decode_default %type search_result_list +%type opt_search_clause opt_cycle_clause %type sub_type opt_materialized %type NumericOnly %type NumericOnly_list -%type alias_clause opt_alias_clause +%type alias_clause opt_alias_clause opt_alias_clause_for_join_using %type func_alias_clause %type sortby %type index_elem index_elem_options +%type stats_param %type table_ref %type joined_table %type relation_expr @@ -573,13 +587,8 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type generic_option_arg %type generic_option_elem alter_generic_option_elem %type generic_option_list alter_generic_option_list -%type explain_option_name -%type explain_option_arg -%type explain_option_elem -%type explain_option_list %type reindex_target_type reindex_target_multitable -%type reindex_option_list reindex_option_elem %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem @@ -601,20 +610,23 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type RoleId opt_boolean_or_string %type QueueId %type var_list -%type ColId ColLabel ColLabelNoAs var_name type_function_name param_name -%type PartitionIdentKeyword +%type ColId ColLabel ColLabelNoAs BareColLabel +%type PartitionIdentKeyword %type PartitionColId %type NonReservedWord NonReservedWord_or_Sconst -%type createdb_opt_name +%type var_name type_function_name param_name +%type createdb_opt_name plassign_target %type var_value zone_value %type auth_ident RoleSpec opt_granted_by %type unreserved_keyword type_func_name_keyword %type col_name_keyword reserved_keyword %type keywords_ok_in_alias_no_as +%type bare_label_keyword %type TableConstraint TableLikeClause %type TableLikeOptionList TableLikeOption +%type column_compression opt_column_compression %type ColQualList %type ColConstraint ColConstraintElem ConstraintAttr %type key_actions key_delete key_match key_update key_action @@ -692,6 +704,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %type hash_partbound %type hash_partbound_elem + /* * Non-keyword token types. These are hard-wired into the "flex" lexer. * They must be listed first so that their numeric codes do not depend on @@ -719,23 +732,22 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ /* ordinary key words in alphabetical order */ %token ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC - ASSERTION ASSIGNMENT ASYMMETRIC AT ATTACH ATTRIBUTE AUTHORIZATION + ASENSITIVE ASSERTION ASSIGNMENT ASYMMETRIC ATOMIC AT ATTACH ATTRIBUTE AUTHORIZATION BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT - BOOLEAN_P BOTH BY + BOOLEAN_P BOTH BREADTH BY CACHE CALL CALLED CASCADE CASCADED CASE CAST CATALOG_P CHAIN CHAR_P CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE CLUSTER COALESCE COLLATE COLLATION COLUMN COLUMNS COMMENT COMMENTS COMMIT - COMMITTED CONCURRENTLY CONFIGURATION CONFLICT CONNECTION CONSTRAINT - CONCURRENCY - CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE - CROSS CSV CUBE CURRENT_P + COMMITTED COMPRESSION CONCURRENCY CONCURRENTLY CONFIGURATION CONFLICT + CONNECTION CONSTRAINT CONSTRAINTS CONTENT_P CONTINUE_P CONVERSION_P COPY + COST CREATE CROSS CSV CUBE CURRENT_P CURRENT_CATALOG CURRENT_DATE CURRENT_ROLE CURRENT_SCHEMA CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE DATA_P DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS - DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DESC + DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DEPENDS DEPTH DESC DETACH DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP @@ -743,7 +755,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ EXCLUDE EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXPRESSION EXTENSION EXTERNAL EXTRACT - FALSE_P FAMILY FETCH FILTER FIRST_P FLOAT_P FOLLOWING FOR + FALSE_P FAMILY FETCH FILTER FINALIZE FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD FREEZE FROM FULL FUNCTION FUNCTIONS GENERATED GLOBAL GRANT GRANTED GREATEST GROUP_P GROUPING GROUPS @@ -783,7 +795,7 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ RANGE READ REAL REASSIGN RECHECK RECURSIVE REF REFERENCES REFERENCING REFRESH REINDEX RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA - RESET RESTART RESTRICT RETRIEVE RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP + RESET RESTART RESTRICT RETRIEVE RETURN RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP ROUTINE ROUTINES ROW ROWS RULE SAVEPOINT SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES @@ -871,6 +883,19 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %token NOT_LA NULLS_LA WITH_LA %token PARTITION_TAIL +/* + * The grammar likewise thinks these tokens are keywords, but they are never + * generated by the scanner. Rather, they can be injected by parser.c as + * the initial token of the string (using the lookahead-token mechanism + * implemented there). This provides a way to tell the grammar to parse + * something other than the usual list of SQL commands. + */ +%token MODE_TYPE_NAME +%token MODE_PLPGSQL_EXPR +%token MODE_PLPGSQL_ASSIGN1 +%token MODE_PLPGSQL_ASSIGN2 +%token MODE_PLPGSQL_ASSIGN3 + /* Precedence: lowest to highest */ %nonassoc SET /* see relation_expr_opt_alias */ @@ -883,24 +908,16 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ %nonassoc '<' '>' '=' LESS_EQUALS GREATER_EQUALS NOT_EQUALS %nonassoc BETWEEN IN_P LIKE ILIKE SIMILAR NOT_LA %nonassoc ESCAPE /* ESCAPE must be just above LIKE/ILIKE/SIMILAR */ -%left POSTFIXOP /* dummy for postfix Op rules */ /* - * To support target_el without AS, we must give IDENT an explicit priority - * between POSTFIXOP and Op. We can safely assign the same priority to - * various unreserved keywords as needed to resolve ambiguities (this can't - * have any bad effects since obviously the keywords will still behave the - * same as if they weren't keywords). We need to do this: - * for PARTITION, RANGE, ROWS, GROUPS to support opt_existing_window_name; - * for RANGE, ROWS, GROUPS so that they can follow a_expr without creating - * postfix-operator problems; - * for GENERATED so that it can follow b_expr; - * and for NULL so that it can follow b_expr in ColQualList without creating - * postfix-operator problems. + * To support target_el without AS, it used to be necessary to assign IDENT an + * explicit precedence just less than Op. While that's not really necessary + * since we removed postfix operators, it's still helpful to do so because + * there are some other unreserved keywords that need precedence assignments. + * If those keywords have the same precedence as IDENT then they clearly act + * the same as non-keywords, reducing the risk of unwanted precedence effects. * - * To support CUBE and ROLLUP in GROUP BY without reserving them, we give them - * an explicit priority lower than '(', so that a rule with CUBE '(' will shift - * rather than reducing a conflicting rule that takes CUBE as a function name. - * Using the same precedence as IDENT seems right for the reasons given above. + * We need to do this for PARTITION, RANGE, ROWS, and GROUPS to support + * opt_existing_window_name (see comment there). * * The frame_bound productions UNBOUNDED PRECEDING and UNBOUNDED FOLLOWING * are even messier: since UNBOUNDED is an unreserved keyword (per spec!), @@ -910,6 +927,11 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ * appear to cause UNBOUNDED to be treated differently from other unreserved * keywords anywhere else in the grammar, but it's definitely risky. We can * blame any funny behavior of UNBOUNDED on the SQL standard, though. + * + * To support CUBE and ROLLUP in GROUP BY without reserving them, we give them + * an explicit priority lower than '(', so that a rule with CUBE '(' will shift + * rather than reducing a conflicting rule that takes CUBE as a function name. + * Using the same precedence as IDENT seems right for the reasons given above. */ %nonassoc UNBOUNDED /* ideally should have same precedence as IDENT */ %nonassoc IDENT GENERATED NULL_P PARTITION RANGE ROWS GROUPS PRECEDING FOLLOWING CUBE ROLLUP @@ -1240,18 +1262,51 @@ static void check_expressions_in_partition_key(PartitionSpec *spec, core_yyscan_ * left-associativity among the JOIN rules themselves. */ %left JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL -/* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */ -%right PRESERVE STRIP_P %% /* * The target production for the whole parse. + * + * Ordinarily we parse a list of statements, but if we see one of the + * special MODE_XXX symbols as first token, we parse something else. + * The options here correspond to enum RawParseMode, which see for details. */ -stmtblock: stmtmulti +parse_toplevel: + stmtmulti { pg_yyget_extra(yyscanner)->parsetree = $1; } + | MODE_TYPE_NAME Typename + { + pg_yyget_extra(yyscanner)->parsetree = list_make1($2); + } + | MODE_PLPGSQL_EXPR PLpgSQL_Expr + { + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt($2, 0)); + } + | MODE_PLPGSQL_ASSIGN1 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + n->nnames = 1; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, 0)); + } + | MODE_PLPGSQL_ASSIGN2 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + n->nnames = 2; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, 0)); + } + | MODE_PLPGSQL_ASSIGN3 PLAssignStmt + { + PLAssignStmt *n = (PLAssignStmt *) $2; + n->nnames = 3; + pg_yyget_extra(yyscanner)->parsetree = + list_make1(makeRawStmt((Node *) n, 0)); + } ; /* @@ -1264,7 +1319,7 @@ stmtblock: stmtmulti * we'd get -1 for the location in such cases. * We also take care to discard empty statements entirely. */ -stmtmulti: stmtmulti ';' stmt +stmtmulti: stmtmulti ';' toplevel_stmt { if ($1 != NIL) { @@ -1276,7 +1331,7 @@ stmtmulti: stmtmulti ';' stmt else $$ = $1; } - | stmt + | toplevel_stmt { if ($1 != NULL) $$ = list_make1(makeRawStmt($1, 0)); @@ -1285,7 +1340,16 @@ stmtmulti: stmtmulti ';' stmt } ; -stmt : +/* + * toplevel_stmt includes BEGIN and END. stmt does not include them, because + * those words have different meanings in function bodys. + */ +toplevel_stmt: + stmt + | TransactionStmtLegacy + ; + +stmt: AlterEventTrigStmt | AlterCollationStmt | AlterDatabaseStmt @@ -1673,9 +1737,9 @@ CreateRoleStmt: ; -opt_with: WITH {} - | WITH_LA {} - | /*EMPTY*/ {} +opt_with: WITH + | WITH_LA + | /*EMPTY*/ ; /* @@ -2242,7 +2306,7 @@ generic_set: ; set_rest_more: /* Generic SET syntaxes: */ - generic_set {$$ = $1;} + generic_set {$$ = $1;} | var_name FROM CURRENT_P { VariableSetStmt *n = makeNode(VariableSetStmt); @@ -2821,12 +2885,13 @@ partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = $4; + cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; } - /* ALTER TABLE DETACH PARTITION */ - | DETACH PARTITION qualified_name + /* ALTER TABLE DETACH PARTITION [CONCURRENTLY] */ + | DETACH PARTITION qualified_name opt_concurrently { AlterTableCmd *n = makeNode(AlterTableCmd); PartitionCmd *cmd = makeNode(PartitionCmd); @@ -2834,8 +2899,21 @@ partition_cmd: n->subtype = AT_DetachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->concurrent = $4; n->def = (Node *) cmd; + $$ = (Node *) n; + } + | DETACH PARTITION qualified_name FINALIZE + { + AlterTableCmd *n = makeNode(AlterTableCmd); + PartitionCmd *cmd = makeNode(PartitionCmd); + + n->subtype = AT_DetachPartitionFinalize; + cmd->name = $3; + cmd->bound = NULL; + cmd->concurrent = false; + n->def = (Node *) cmd; $$ = (Node *) n; } ; @@ -2850,6 +2928,7 @@ index_partition_cmd: n->subtype = AT_AttachPartition; cmd->name = $3; cmd->bound = NULL; + cmd->concurrent = false; n->def = (Node *) cmd; $$ = (Node *) n; @@ -2999,6 +3078,15 @@ alter_table_cmd: n->def = (Node *) makeString($6); $$ = (Node *)n; } + /* ALTER TABLE ALTER [COLUMN] SET COMPRESSION */ + | ALTER opt_column ColId SET column_compression + { + AlterTableCmd *n = makeNode(AlterTableCmd); + n->subtype = AT_SetCompression; + n->name = $3; + n->def = (Node *) makeString($5); + $$ = (Node *)n; + } /* ALTER TABLE ALTER [COLUMN] ADD GENERATED ... AS IDENTITY ... */ | ALTER opt_column ColId ADD_P GENERATED generated_when AS IDENTITY_P OptParenthesizedSeqOptList { @@ -3141,7 +3229,7 @@ alter_table_cmd: n->missing_ok = false; $$ = (Node *)n; } - /* ALTER TABLE SET WITHOUT OIDS, for backward compat */ + /* ALTER TABLE SET WITHOUT OIDS, for backward compat */ | SET WITHOUT OIDS { AlterTableCmd *n = makeNode(AlterTableCmd); @@ -3164,14 +3252,14 @@ alter_table_cmd: n->name = NULL; $$ = (Node *)n; } - /* ALTER TABLE SET LOGGED */ + /* ALTER TABLE SET LOGGED */ | SET LOGGED { AlterTableCmd *n = makeNode(AlterTableCmd); n->subtype = AT_SetLogged; $$ = (Node *)n; } - /* ALTER TABLE SET UNLOGGED */ + /* ALTER TABLE SET UNLOGGED */ | SET UNLOGGED { AlterTableCmd *n = makeNode(AlterTableCmd); @@ -3424,7 +3512,7 @@ alter_table_cmd: n->def = (Node *)$2; $$ = (Node *)n; } - /* ALTER TABLE REPLICA IDENTITY */ + /* ALTER TABLE REPLICA IDENTITY */ | REPLICA IDENTITY_P replica_identity { AlterTableCmd *n = makeNode(AlterTableCmd); @@ -4505,8 +4593,8 @@ copy_delimiter: ; opt_using: - USING {} - | /*EMPTY*/ {} + USING + | /*EMPTY*/ ; /* new COPY option syntax */ @@ -4851,22 +4939,23 @@ column_reference_storage_directive: } ; -columnDef: ColId Typename create_generic_options ColQualList opt_storage_encoding +columnDef: ColId Typename opt_column_compression create_generic_options ColQualList opt_storage_encoding { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; n->typeName = $2; + n->compression = $3; n->inhcount = 0; n->is_local = true; - n->encoding = $5; + n->encoding = $6; n->is_not_null = false; n->is_from_type = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; n->collOid = InvalidOid; - n->fdwoptions = $3; - SplitColQualList($4, &n->constraints, &n->collClause, + n->fdwoptions = $4; + SplitColQualList($5, &n->constraints, &n->collClause, yyscanner); n->location = @1; $$ = (Node *)n; @@ -4911,6 +5000,16 @@ columnOptions: ColId ColQualList } ; +column_compression: + COMPRESSION ColId { $$ = $2; } + | COMPRESSION DEFAULT { $$ = pstrdup("default"); } + ; + +opt_column_compression: + column_compression { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + ColQualList: ColQualList ColConstraint { $$ = lappend($1, $2); } | /*EMPTY*/ { $$ = NIL; } @@ -5125,6 +5224,7 @@ TableLikeClause: TableLikeClause *n = makeNode(TableLikeClause); n->relation = $2; n->options = $3; + n->relationOid = InvalidOid; $$ = (Node *)n; } ; @@ -5137,6 +5237,7 @@ TableLikeOptionList: TableLikeOption: COMMENTS { $$ = CREATE_TABLE_LIKE_COMMENTS; } + | COMPRESSION { $$ = CREATE_TABLE_LIKE_COMPRESSION; } | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; } | DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS; } | IDENTITY_P { $$ = CREATE_TABLE_LIKE_IDENTITY; } @@ -5240,7 +5341,7 @@ ConstraintElem: $$ = (Node *)n; } | EXCLUDE access_method_clause '(' ExclusionConstraintList ')' - opt_c_include opt_definition OptConsTableSpace ExclusionWhereClause + opt_c_include opt_definition OptConsTableSpace OptWhereClause ConstraintAttributeSpec { Constraint *n = makeNode(Constraint); @@ -5373,7 +5474,7 @@ ExclusionConstraintElem: index_elem WITH any_operator } ; -ExclusionWhereClause: +OptWhereClause: WHERE '(' a_expr ')' { $$ = $3; } | /*EMPTY*/ { $$ = NULL; } ; @@ -6095,7 +6196,7 @@ TabSubPartition: CreateStatsStmt: CREATE STATISTICS any_name - opt_name_list ON expr_list FROM from_list + opt_name_list ON stats_params FROM from_list { CreateStatsStmt *n = makeNode(CreateStatsStmt); n->defnames = $3; @@ -6107,7 +6208,7 @@ CreateStatsStmt: $$ = (Node *)n; } | CREATE STATISTICS IF_P NOT EXISTS any_name - opt_name_list ON expr_list FROM from_list + opt_name_list ON stats_params FROM from_list { CreateStatsStmt *n = makeNode(CreateStatsStmt); n->defnames = $6; @@ -6120,6 +6221,36 @@ CreateStatsStmt: } ; +/* + * Statistics attributes can be either simple column references, or arbitrary + * expressions in parens. For compatibility with index attributes permitted + * in CREATE INDEX, we allow an expression that's just a function call to be + * written without parens. + */ + +stats_params: stats_param { $$ = list_make1($1); } + | stats_params ',' stats_param { $$ = lappend($1, $3); } + ; + +stats_param: ColId + { + $$ = makeNode(StatsElem); + $$->name = $1; + $$->expr = NULL; + } + | func_expr_windowless + { + $$ = makeNode(StatsElem); + $$->name = NULL; + $$->expr = $1; + } + | '(' a_expr ')' + { + $$ = makeNode(StatsElem); + $$->name = NULL; + $$->expr = $2; + } + ; /***************************************************************************** * @@ -6809,8 +6940,8 @@ SeqOptElem: AS SimpleTypename } ; -opt_by: BY {} - | /* empty */ {} +opt_by: BY + | /* EMPTY */ ; NumericOnly: @@ -6896,8 +7027,8 @@ opt_validator: ; opt_procedural: - PROCEDURAL {} - | /*EMPTY*/ {} + PROCEDURAL + | /*EMPTY*/ ; /***************************************************************************** @@ -7493,8 +7624,8 @@ ImportForeignSchemaStmt: ; import_qualification_type: - LIMIT TO { $$ = FDW_IMPORT_SCHEMA_LIMIT_TO; } - | EXCEPT { $$ = FDW_IMPORT_SCHEMA_EXCEPT; } + LIMIT TO { $$ = FDW_IMPORT_SCHEMA_LIMIT_TO; } + | EXCEPT { $$ = FDW_IMPORT_SCHEMA_EXCEPT; } ; import_qualification: @@ -7715,48 +7846,54 @@ am_type: *****************************************************************************/ CreateTrigStmt: - CREATE TRIGGER name TriggerActionTime TriggerEvents ON + CREATE opt_or_replace TRIGGER name TriggerActionTime TriggerEvents ON qualified_name TriggerReferencing TriggerForSpec TriggerWhen EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); - n->trigname = $3; - n->relation = $7; - n->funcname = $13; - n->args = $15; - n->row = $9; - n->timing = $4; - n->events = intVal(linitial($5)); - n->columns = (List *) lsecond($5); - n->whenClause = $10; - n->transitionRels = $8; - n->isconstraint = false; - n->deferrable = false; - n->initdeferred = false; + n->replace = $2; + n->isconstraint = false; + n->trigname = $4; + n->relation = $8; + n->funcname = $14; + n->args = $16; + n->row = $10; + n->timing = $5; + n->events = intVal(linitial($6)); + n->columns = (List *) lsecond($6); + n->whenClause = $11; + n->transitionRels = $9; + n->deferrable = false; + n->initdeferred = false; n->constrrel = NULL; $$ = (Node *)n; } - | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON + | CREATE opt_or_replace CONSTRAINT TRIGGER name AFTER TriggerEvents ON qualified_name OptConstrFromTable ConstraintAttributeSpec FOR EACH ROW TriggerWhen EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); - n->trigname = $4; - n->relation = $8; - n->funcname = $17; - n->args = $19; + n->replace = $2; + if (n->replace) /* not supported, see CreateTrigger */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE OR REPLACE CONSTRAINT TRIGGER is not supported"))); + n->isconstraint = true; + n->trigname = $5; + n->relation = $9; + n->funcname = $18; + n->args = $20; n->row = true; n->timing = TRIGGER_TYPE_AFTER; - n->events = intVal(linitial($6)); - n->columns = (List *) lsecond($6); - n->whenClause = $14; + n->events = intVal(linitial($7)); + n->columns = (List *) lsecond($7); + n->whenClause = $15; n->transitionRels = NIL; - n->isconstraint = true; - processCASbits($10, @10, "TRIGGER", + processCASbits($11, @11, "TRIGGER", &n->deferrable, &n->initdeferred, NULL, NULL, yyscanner); - n->constrrel = $9; + n->constrrel = $10; $$ = (Node *)n; } ; @@ -7861,8 +7998,8 @@ TriggerForSpec: ; TriggerForOptEach: - EACH {} - | /*EMPTY*/ {} + EACH + | /*EMPTY*/ ; TriggerForType: @@ -8329,7 +8466,7 @@ AlterEnumStmt: ; opt_if_not_exists: IF_P NOT EXISTS { $$ = true; } - | /* empty */ { $$ = false; } + | /* EMPTY */ { $$ = false; } ; @@ -9081,7 +9218,7 @@ SecLabelStmt: ; opt_provider: FOR NonReservedWord_or_Sconst { $$ = $2; } - | /* empty */ { $$ = NULL; } + | /* EMPTY */ { $$ = NULL; } ; security_label: Sconst { $$ = $1; } @@ -9239,12 +9376,12 @@ fetch_args: cursor_name } ; -from_in: FROM {} - | IN_P {} +from_in: FROM + | IN_P ; -opt_from_in: from_in {} - | /* EMPTY */ {} +opt_from_in: from_in + | /* EMPTY */ ; @@ -9255,7 +9392,7 @@ opt_from_in: from_in {} *****************************************************************************/ GrantStmt: GRANT privileges ON privilege_target TO grantee_list - opt_grant_grant_option + opt_grant_grant_option opt_granted_by { GrantStmt *n = makeNode(GrantStmt); n->is_grant = true; @@ -9265,13 +9402,14 @@ GrantStmt: GRANT privileges ON privilege_target TO grantee_list n->objects = ($4)->objs; n->grantees = $6; n->grant_option = $7; + n->grantor = $8; $$ = (Node*)n; } ; RevokeStmt: REVOKE privileges ON privilege_target - FROM grantee_list opt_drop_behavior + FROM grantee_list opt_granted_by opt_drop_behavior { GrantStmt *n = makeNode(GrantStmt); n->is_grant = false; @@ -9281,11 +9419,12 @@ RevokeStmt: n->objtype = ($4)->objtype; n->objects = ($4)->objs; n->grantees = $6; - n->behavior = $7; + n->grantor = $7; + n->behavior = $8; $$ = (Node *)n; } | REVOKE GRANT OPTION FOR privileges ON privilege_target - FROM grantee_list opt_drop_behavior + FROM grantee_list opt_granted_by opt_drop_behavior { GrantStmt *n = makeNode(GrantStmt); n->is_grant = false; @@ -9295,7 +9434,8 @@ RevokeStmt: n->objtype = ($7)->objtype; n->objects = ($7)->objs; n->grantees = $9; - n->behavior = $10; + n->grantor = $10; + n->behavior = $11; $$ = (Node *)n; } ; @@ -9898,8 +10038,7 @@ opt_nulls_order: NULLS_LA FIRST_P { $$ = SORTBY_NULLS_FIRST; } CreateFunctionStmt: CREATE opt_or_replace FUNCTION func_name func_args_with_defaults - RETURNS func_return createfunc_opt_list - opt_definition + RETURNS func_return opt_createfunc_opt_list opt_definition opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->is_procedure = false; @@ -9908,12 +10047,13 @@ CreateFunctionStmt: n->parameters = $5; n->returnType = $7; n->options = $8; + /* GPDB: legacy WITH (describe=..., etc.) attribute list */ n->options = list_concat(n->options, $9); + n->sql_body = $10; $$ = (Node *)n; } | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults - RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list - opt_definition + RETURNS TABLE '(' table_func_column_list ')' opt_createfunc_opt_list opt_definition opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->is_procedure = false; @@ -9923,12 +10063,13 @@ CreateFunctionStmt: n->returnType = TableFuncTypeName($9); n->returnType->location = @7; n->options = $11; + /* GPDB: legacy WITH (describe=..., etc.) attribute list */ n->options = list_concat(n->options, $12); + n->sql_body = $13; $$ = (Node *)n; } | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults - createfunc_opt_list - opt_definition + opt_createfunc_opt_list opt_definition opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->is_procedure = false; @@ -9937,11 +10078,13 @@ CreateFunctionStmt: n->parameters = $5; n->returnType = NULL; n->options = $6; + /* GPDB: legacy WITH (describe=..., etc.) attribute list */ n->options = list_concat(n->options, $7); + n->sql_body = $8; $$ = (Node *)n; } | CREATE opt_or_replace PROCEDURE func_name func_args_with_defaults - createfunc_opt_list + opt_createfunc_opt_list opt_routine_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); n->is_procedure = true; @@ -9950,6 +10093,7 @@ CreateFunctionStmt: n->parameters = $5; n->returnType = NULL; n->options = $6; + n->sql_body = $7; $$ = (Node *)n; } ; @@ -9980,6 +10124,7 @@ function_with_argtypes: ObjectWithArgs *n = makeNode(ObjectWithArgs); n->objname = $1; n->objargs = extractArgTypes($2); + n->objfuncargs = $2; $$ = n; } /* @@ -10060,7 +10205,7 @@ func_arg: FunctionParameter *n = makeNode(FunctionParameter); n->name = $1; n->argType = $2; - n->mode = FUNC_PARAM_IN; + n->mode = FUNC_PARAM_DEFAULT; n->defexpr = NULL; $$ = n; } @@ -10078,7 +10223,7 @@ func_arg: FunctionParameter *n = makeNode(FunctionParameter); n->name = NULL; n->argType = $1; - n->mode = FUNC_PARAM_IN; + n->mode = FUNC_PARAM_DEFAULT; n->defexpr = NULL; $$ = n; } @@ -10150,7 +10295,8 @@ func_arg_with_default: /* Aggregate args can be most things that function args can be */ aggr_arg: func_arg { - if (!($1->mode == FUNC_PARAM_IN || + if (!($1->mode == FUNC_PARAM_DEFAULT || + $1->mode == FUNC_PARAM_IN || $1->mode == FUNC_PARAM_VARIADIC)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -10219,6 +10365,7 @@ aggregate_with_argtypes: ObjectWithArgs *n = makeNode(ObjectWithArgs); n->objname = $1; n->objargs = extractAggrArgTypes($2); + n->objfuncargs = (List *) linitial($2); $$ = n; } ; @@ -10229,6 +10376,11 @@ aggregate_with_argtypes_list: { $$ = lappend($1, $3); } ; +opt_createfunc_opt_list: + createfunc_opt_list + | /*EMPTY*/ { $$ = NIL; } + ; + createfunc_opt_list: /* Must be at least one to prevent conflict */ createfunc_opt_item { $$ = list_make1($1); } @@ -10376,6 +10528,55 @@ func_as: Sconst { $$ = list_make1(makeString($1)); } } ; +ReturnStmt: RETURN a_expr + { + ReturnStmt *r = makeNode(ReturnStmt); + r->returnval = (Node *) $2; + $$ = (Node *) r; + } + ; + +opt_routine_body: + ReturnStmt + { + $$ = $1; + } + | BEGIN_P ATOMIC routine_body_stmt_list END_P + { + /* + * A compound statement is stored as a single-item list + * containing the list of statements as its member. That + * way, the parse analysis code can tell apart an empty + * body from no body at all. + */ + $$ = (Node *) list_make1($3); + } + | /*EMPTY*/ + { + $$ = NULL; + } + ; + +routine_body_stmt_list: + routine_body_stmt_list routine_body_stmt ';' + { + /* As in stmtmulti, discard empty statements */ + if ($2 != NULL) + $$ = lappend($1, $2); + else + $$ = $1; + } + | /*EMPTY*/ + { + $$ = NIL; + } + ; + +routine_body_stmt: + stmt + | ReturnStmt + ; + transform_type_list: FOR TYPE_P Typename { $$ = list_make1($3); } | transform_type_list ',' FOR TYPE_P Typename { $$ = lappend($1, $5); } @@ -10775,7 +10976,6 @@ ReindexStmt: { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $2; - n->concurrent = $3; n->relation = $4; n->name = NULL; n->options = 0; @@ -10785,13 +10985,16 @@ ReindexStmt: (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REINDEX CONCURRENTLY is not supported"))); + n->params = NIL; + if ($3) + n->params = lappend(n->params, + makeDefElem("concurrently", NULL, @3)); $$ = (Node *)n; } | REINDEX reindex_target_multitable opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $2; - n->concurrent = $3; n->name = $4; n->relation = NULL; n->options = 0; @@ -10801,13 +11004,16 @@ ReindexStmt: (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REINDEX CONCURRENTLY is not supported"))); + n->params = NIL; + if ($3) + n->params = lappend(n->params, + makeDefElem("concurrently", NULL, @3)); $$ = (Node *)n; } - | REINDEX '(' reindex_option_list ')' reindex_target_type opt_concurrently qualified_name + | REINDEX '(' utility_option_list ')' reindex_target_type opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $5; - n->concurrent = $6; n->relation = $7; n->name = NULL; n->options = $3; @@ -10817,13 +11023,16 @@ ReindexStmt: (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REINDEX CONCURRENTLY is not supported"))); + n->params = $3; + if ($6) + n->params = lappend(n->params, + makeDefElem("concurrently", NULL, @6)); $$ = (Node *)n; } - | REINDEX '(' reindex_option_list ')' reindex_target_multitable opt_concurrently name + | REINDEX '(' utility_option_list ')' reindex_target_multitable opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $5; - n->concurrent = $6; n->name = $7; n->relation = NULL; n->options = $3; @@ -10833,6 +11042,10 @@ ReindexStmt: (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REINDEX CONCURRENTLY is not supported"))); + n->params = $3; + if ($6) + n->params = lappend(n->params, + makeDefElem("concurrently", NULL, @6)); $$ = (Node *)n; } ; @@ -10845,13 +11058,6 @@ reindex_target_multitable: | SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } ; -reindex_option_list: - reindex_option_elem { $$ = $1; } - | reindex_option_list ',' reindex_option_elem { $$ = $1 | $3; } - ; -reindex_option_elem: - VERBOSE { $$ = REINDEXOPT_VERBOSE; } - ; /* * ALTER TYPE ... SET DEFAULT ENCODING @@ -11443,8 +11649,8 @@ RenameStmt: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name } ; -opt_column: COLUMN { $$ = COLUMN; } - | /*EMPTY*/ { $$ = 0; } +opt_column: COLUMN + | /*EMPTY*/ ; opt_set_data: SET DATA_P { $$ = 1; } @@ -12128,7 +12334,7 @@ AlterPublicationStmt: *****************************************************************************/ CreateSubscriptionStmt: - CREATE SUBSCRIPTION name CONNECTION Sconst PUBLICATION publication_name_list opt_definition + CREATE SUBSCRIPTION name CONNECTION Sconst PUBLICATION name_list opt_definition { CreateSubscriptionStmt *n = makeNode(CreateSubscriptionStmt); @@ -12140,20 +12346,6 @@ CreateSubscriptionStmt: } ; -publication_name_list: - publication_name_item - { - $$ = list_make1($1); - } - | publication_name_list ',' publication_name_item - { - $$ = lappend($1, $3); - } - ; - -publication_name_item: - ColLabel { $$ = makeString($1); }; - /***************************************************************************** * * ALTER SUBSCRIPTION name ... @@ -12188,11 +12380,31 @@ AlterSubscriptionStmt: n->options = $6; $$ = (Node *)n; } - | ALTER SUBSCRIPTION name SET PUBLICATION publication_name_list opt_definition + | ALTER SUBSCRIPTION name ADD_P PUBLICATION name_list opt_definition + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + n->kind = ALTER_SUBSCRIPTION_ADD_PUBLICATION; + n->subname = $3; + n->publication = $6; + n->options = $7; + $$ = (Node *)n; + } + | ALTER SUBSCRIPTION name DROP PUBLICATION name_list opt_definition + { + AlterSubscriptionStmt *n = + makeNode(AlterSubscriptionStmt); + n->kind = ALTER_SUBSCRIPTION_DROP_PUBLICATION; + n->subname = $3; + n->publication = $6; + n->options = $7; + $$ = (Node *)n; + } + | ALTER SUBSCRIPTION name SET PUBLICATION name_list opt_definition { AlterSubscriptionStmt *n = makeNode(AlterSubscriptionStmt); - n->kind = ALTER_SUBSCRIPTION_PUBLICATION; + n->kind = ALTER_SUBSCRIPTION_SET_PUBLICATION; n->subname = $3; n->publication = $6; n->options = $7; @@ -12378,13 +12590,6 @@ TransactionStmt: n->chain = $3; $$ = (Node *)n; } - | BEGIN_P opt_transaction transaction_mode_list_or_empty - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_BEGIN; - n->options = $3; - $$ = (Node *)n; - } | START TRANSACTION transaction_mode_list_or_empty { TransactionStmt *n = makeNode(TransactionStmt); @@ -12400,14 +12605,6 @@ TransactionStmt: n->chain = $3; $$ = (Node *)n; } - | END_P opt_transaction opt_transaction_chain - { - TransactionStmt *n = makeNode(TransactionStmt); - n->kind = TRANS_STMT_COMMIT; - n->options = NIL; - n->chain = $3; - $$ = (Node *)n; - } | ROLLBACK opt_transaction opt_transaction_chain { TransactionStmt *n = makeNode(TransactionStmt); @@ -12474,9 +12671,27 @@ TransactionStmt: } ; -opt_transaction: WORK {} - | TRANSACTION {} - | /*EMPTY*/ {} +TransactionStmtLegacy: + BEGIN_P opt_transaction transaction_mode_list_or_empty + { + TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_BEGIN; + n->options = $3; + $$ = (Node *)n; + } + | END_P opt_transaction opt_transaction_chain + { + TransactionStmt *n = makeNode(TransactionStmt); + n->kind = TRANS_STMT_COMMIT; + n->options = NIL; + n->chain = $3; + $$ = (Node *)n; + } + ; + +opt_transaction: WORK + | TRANSACTION + | /*EMPTY*/ ; transaction_mode_item: @@ -12681,8 +12896,8 @@ createdb_opt_name: * Though the equals sign doesn't match other WITH options, pg_dump uses * equals for backward compatibility, and it doesn't seem worth removing it. */ -opt_equal: '=' {} - | /*EMPTY*/ {} +opt_equal: '=' + | /*EMPTY*/ ; @@ -12915,8 +13130,8 @@ AlterDomainStmt: } ; -opt_as: AS {} - | /* EMPTY */ {} +opt_as: AS + | /* EMPTY */ ; @@ -13002,8 +13217,8 @@ AlterTSConfigurationStmt: ; /* Use this if TIME or ORDINALITY after WITH should be taken as an identifier */ -any_with: WITH {} - | WITH_LA {} +any_with: WITH + | WITH_LA ; @@ -13034,6 +13249,7 @@ CreateConversionStmt: * * QUERY: * CLUSTER [VERBOSE] [ USING ] + * CLUSTER [ (options) ] [ USING ] * CLUSTER [VERBOSE] * CLUSTER [VERBOSE] ON (for pre-8.3) * @@ -13045,9 +13261,18 @@ ClusterStmt: ClusterStmt *n = makeNode(ClusterStmt); n->relation = $3; n->indexname = $4; - n->options = 0; + n->params = NIL; if ($2) - n->options |= CLUOPT_VERBOSE; + n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); + $$ = (Node*)n; + } + + | CLUSTER '(' utility_option_list ')' qualified_name cluster_index_specification + { + ClusterStmt *n = makeNode(ClusterStmt); + n->relation = $5; + n->indexname = $6; + n->params = $3; $$ = (Node*)n; } | CLUSTER opt_verbose @@ -13055,9 +13280,9 @@ ClusterStmt: ClusterStmt *n = makeNode(ClusterStmt); n->relation = NULL; n->indexname = NULL; - n->options = 0; + n->params = NIL; if ($2) - n->options |= CLUOPT_VERBOSE; + n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); $$ = (Node*)n; } /* kept for pre-8.3 compatibility */ @@ -13066,9 +13291,9 @@ ClusterStmt: ClusterStmt *n = makeNode(ClusterStmt); n->relation = $5; n->indexname = $3; - n->options = 0; + n->params = NIL; if ($2) - n->options |= CLUOPT_VERBOSE; + n->params = lappend(n->params, makeDefElem("verbose", NULL, @2)); $$ = (Node*)n; } ; @@ -13107,7 +13332,7 @@ VacuumStmt: VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relati n->is_vacuumcmd = true; $$ = (Node *)n; } - | VACUUM '(' vac_analyze_option_list ')' opt_vacuum_relation_list + | VACUUM '(' utility_option_list ')' opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); n->options = $3; @@ -13128,7 +13353,7 @@ AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list n->is_vacuumcmd = false; $$ = (Node *)n; } - | analyze_keyword '(' vac_analyze_option_list ')' opt_vacuum_relation_list + | analyze_keyword '(' utility_option_list ')' opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); n->options = $3; @@ -13191,38 +13416,38 @@ AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list } ; -vac_analyze_option_list: - vac_analyze_option_elem +utility_option_list: + utility_option_elem { $$ = list_make1($1); } - | vac_analyze_option_list ',' vac_analyze_option_elem + | utility_option_list ',' utility_option_elem { $$ = lappend($1, $3); } ; analyze_keyword: - ANALYZE {} - | ANALYSE /* British */ {} + ANALYZE + | ANALYSE /* British */ ; -vac_analyze_option_elem: - vac_analyze_option_name vac_analyze_option_arg +utility_option_elem: + utility_option_name utility_option_arg { $$ = makeDefElem($1, $2, @1); } ; -vac_analyze_option_name: +utility_option_name: NonReservedWord { $$ = $1; } | analyze_keyword { $$ = "analyze"; } ; -vac_analyze_option_arg: +utility_option_arg: opt_boolean_or_string { $$ = (Node *) makeString($1); } - | NumericOnly { $$ = (Node *) $1; } - | /* EMPTY */ { $$ = NULL; } + | NumericOnly { $$ = (Node *) $1; } + | /* EMPTY */ { $$ = NULL; } ; opt_analyze: @@ -13307,7 +13532,7 @@ ExplainStmt: makeDefElem("dxl", NULL, @3)); $$ = (Node *) n; } - | EXPLAIN '(' explain_option_list ')' ExplainableStmt + | EXPLAIN '(' utility_option_list ')' ExplainableStmt { ExplainStmt *n = makeNode(ExplainStmt); n->query = $5; @@ -13339,35 +13564,6 @@ opt_dxl: DXL { $$ = true; } | /*EMPTY*/ { $$ = false; } ; -explain_option_list: - explain_option_elem - { - $$ = list_make1($1); - } - | explain_option_list ',' explain_option_elem - { - $$ = lappend($1, $3); - } - ; - -explain_option_elem: - explain_option_name explain_option_arg - { - $$ = makeDefElem($1, $2, @1); - } - ; - -explain_option_name: - NonReservedWord { $$ = $1; } - | analyze_keyword { $$ = "analyze"; } - ; - -explain_option_arg: - opt_boolean_or_string { $$ = (Node *) makeString($1); } - | NumericOnly { $$ = (Node *) $1; } - | /* EMPTY */ { $$ = NULL; } - ; - /***************************************************************************** * * QUERY: @@ -13846,6 +14042,7 @@ cursor_options: /*EMPTY*/ { $$ = 0; } | cursor_options NO SCROLL { $$ = $1 | CURSOR_OPT_NO_SCROLL; } | cursor_options SCROLL { $$ = $1 | CURSOR_OPT_SCROLL; } | cursor_options BINARY { $$ = $1 | CURSOR_OPT_BINARY; } + | cursor_options ASENSITIVE { $$ = $1 | CURSOR_OPT_ASENSITIVE; } | cursor_options INSENSITIVE { $$ = $1 | CURSOR_OPT_INSENSITIVE; } | cursor_options PARALLEL RETRIEVE { $$ = $1 | CURSOR_OPT_PARALLEL_RETRIEVE; } ; @@ -14011,6 +14208,11 @@ select_clause: * As with select_no_parens, simple_select cannot have outer parentheses, * but can have parenthesized subclauses. * + * It might appear that we could fold the first two alternatives into one + * by using opt_distinct_clause. However, that causes a shift/reduce conflict + * against INSERT ... SELECT ... ON CONFLICT. We avoid the ambiguity by + * requiring SELECT DISTINCT [ON] to be followed by a non-empty target_list. + * * Note that sort clauses cannot be included at this level --- SQL requires * SELECT foo UNION SELECT bar ORDER BY baz * to be parsed as @@ -14035,7 +14237,8 @@ simple_select: n->intoClause = $4; n->fromClause = $5; n->whereClause = $6; - n->groupClause = $7; + n->groupClause = ($7)->list; + n->groupDistinct = ($7)->distinct; n->havingClause = $8; n->windowClause = $9; $$ = (Node *)n; @@ -14050,7 +14253,8 @@ simple_select: n->intoClause = $4; n->fromClause = $5; n->whereClause = $6; - n->groupClause = $7; + n->groupClause = ($7)->list; + n->groupDistinct = ($7)->distinct; n->havingClause = $8; n->windowClause = $9; $$ = (Node *)n; @@ -14075,17 +14279,17 @@ simple_select: n->fromClause = list_make1($2); $$ = (Node *)n; } - | select_clause UNION all_or_distinct select_clause + | select_clause UNION set_quantifier select_clause { - $$ = makeSetOp(SETOP_UNION, $3, $1, $4); + $$ = makeSetOp(SETOP_UNION, $3 == SET_QUANTIFIER_ALL, $1, $4); } - | select_clause INTERSECT all_or_distinct select_clause + | select_clause INTERSECT set_quantifier select_clause { - $$ = makeSetOp(SETOP_INTERSECT, $3, $1, $4); + $$ = makeSetOp(SETOP_INTERSECT, $3 == SET_QUANTIFIER_ALL, $1, $4); } - | select_clause EXCEPT all_or_distinct select_clause + | select_clause EXCEPT set_quantifier select_clause { - $$ = makeSetOp(SETOP_EXCEPT, $3, $1, $4); + $$ = makeSetOp(SETOP_EXCEPT, $3 == SET_QUANTIFIER_ALL, $1, $4); } ; @@ -14095,8 +14299,6 @@ simple_select: * WITH [ RECURSIVE ] [ (,...) ] * AS (query) [ SEARCH or CYCLE clause ] * - * We don't currently support the SEARCH or CYCLE clause. - * * Recognizing WITH_LA here allows a CTE to be named TIME or ORDINALITY. */ with_clause: @@ -14128,13 +14330,15 @@ cte_list: | cte_list ',' common_table_expr { $$ = lappend($1, $3); } ; -common_table_expr: name opt_name_list AS opt_materialized '(' PreparableStmt ')' +common_table_expr: name opt_name_list AS opt_materialized '(' PreparableStmt ')' opt_search_clause opt_cycle_clause { CommonTableExpr *n = makeNode(CommonTableExpr); n->ctename = $1; n->aliascolnames = $2; n->ctematerialized = $4; n->ctequery = $6; + n->search_clause = castNode(CTESearchClause, $8); + n->cycle_clause = castNode(CTECycleClause, $9); n->location = @1; $$ = (Node *) n; } @@ -14146,22 +14350,76 @@ opt_materialized: | /*EMPTY*/ { $$ = CTEMaterializeDefault; } ; -opt_with_clause: - with_clause { $$ = $1; } - | /*EMPTY*/ { $$ = NULL; } +opt_search_clause: + SEARCH DEPTH FIRST_P BY columnList SET ColId + { + CTESearchClause *n = makeNode(CTESearchClause); + n->search_col_list = $5; + n->search_breadth_first = false; + n->search_seq_column = $7; + n->location = @1; + $$ = (Node *) n; + } + | SEARCH BREADTH FIRST_P BY columnList SET ColId + { + CTESearchClause *n = makeNode(CTESearchClause); + n->search_col_list = $5; + n->search_breadth_first = true; + n->search_seq_column = $7; + n->location = @1; + $$ = (Node *) n; + } + | /*EMPTY*/ + { + $$ = NULL; + } ; -into_clause: - INTO OptTempTableName - { - $$ = makeNode(IntoClause); - $$->rel = $2; - $$->colNames = NIL; - $$->options = NIL; - $$->onCommit = ONCOMMIT_NOOP; - $$->tableSpaceName = NULL; - $$->viewQuery = NULL; - $$->skipData = false; +opt_cycle_clause: + CYCLE columnList SET ColId TO AexprConst DEFAULT AexprConst USING ColId + { + CTECycleClause *n = makeNode(CTECycleClause); + n->cycle_col_list = $2; + n->cycle_mark_column = $4; + n->cycle_mark_value = $6; + n->cycle_mark_default = $8; + n->cycle_path_column = $10; + n->location = @1; + $$ = (Node *) n; + } + | CYCLE columnList SET ColId USING ColId + { + CTECycleClause *n = makeNode(CTECycleClause); + n->cycle_col_list = $2; + n->cycle_mark_column = $4; + n->cycle_mark_value = makeBoolAConst(true, -1); + n->cycle_mark_default = makeBoolAConst(false, -1); + n->cycle_path_column = $6; + n->location = @1; + $$ = (Node *) n; + } + | /*EMPTY*/ + { + $$ = NULL; + } + ; + +opt_with_clause: + with_clause { $$ = $1; } + | /*EMPTY*/ { $$ = NULL; } + ; + +into_clause: + INTO OptTempTableName + { + $$ = makeNode(IntoClause); + $$->rel = $2; + $$->colNames = NIL; + $$->options = NIL; + $$->onCommit = ONCOMMIT_NOOP; + $$->tableSpaceName = NULL; + $$->viewQuery = NULL; + $$->skipData = false; } | /*EMPTY*/ { $$ = NULL; } @@ -14225,14 +14483,14 @@ OptTempTableName: } ; -opt_table: TABLE {} - | /*EMPTY*/ {} +opt_table: TABLE + | /*EMPTY*/ ; -all_or_distinct: - ALL { $$ = true; } - | DISTINCT { $$ = false; } - | /*EMPTY*/ { $$ = false; } +set_quantifier: + ALL { $$ = SET_QUANTIFIER_ALL; } + | DISTINCT { $$ = SET_QUANTIFIER_DISTINCT; } + | /*EMPTY*/ { $$ = SET_QUANTIFIER_DEFAULT; } ; /* We use (NIL) as a placeholder to indicate that all target expressions @@ -14244,12 +14502,17 @@ distinct_clause: ; opt_all_clause: - ALL { $$ = NIL;} - | /*EMPTY*/ { $$ = NIL; } + ALL + | /*EMPTY*/ + ; + +opt_distinct_clause: + distinct_clause { $$ = $1; } + | opt_all_clause { $$ = NIL; } ; opt_sort_clause: - sort_clause { $$ = $1;} + sort_clause { $$ = $1; } | /*EMPTY*/ { $$ = NIL; } ; @@ -14453,8 +14716,20 @@ first_or_next: FIRST_P { $$ = 0; } * GroupingSet node of some type. */ group_clause: - GROUP_P BY group_by_list { $$ = $3; } - | /*EMPTY*/ { $$ = NIL; } + GROUP_P BY set_quantifier group_by_list + { + GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + n->distinct = $3 == SET_QUANTIFIER_DISTINCT; + n->list = $4; + $$ = n; + } + | /*EMPTY*/ + { + GroupClause *n = (GroupClause *) palloc(sizeof(GroupClause)); + n->distinct = false; + n->list = NIL; + $$ = n; + } ; group_by_list: @@ -14536,10 +14811,10 @@ for_locking_item: ; for_locking_strength: - FOR UPDATE { $$ = LCS_FORUPDATE; } - | FOR NO KEY UPDATE { $$ = LCS_FORNOKEYUPDATE; } - | FOR SHARE { $$ = LCS_FORSHARE; } - | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; } + FOR UPDATE { $$ = LCS_FORUPDATE; } + | FOR NO KEY UPDATE { $$ = LCS_FORNOKEYUPDATE; } + | FOR SHARE { $$ = LCS_FORSHARE; } + | FOR KEY SHARE { $$ = LCS_FORKEYSHARE; } ; locked_rels_list: @@ -14734,6 +15009,7 @@ joined_table: n->larg = $1; n->rarg = $4; n->usingClause = NIL; + n->join_using_alias = NULL; n->quals = NULL; $$ = n; } @@ -14745,9 +15021,16 @@ joined_table: n->larg = $1; n->rarg = $4; if ($5 != NULL && IsA($5, List)) - n->usingClause = (List *) $5; /* USING clause */ + { + /* USING clause */ + n->usingClause = linitial_node(List, castNode(List, $5)); + n->join_using_alias = lsecond_node(Alias, castNode(List, $5)); + } else - n->quals = $5; /* ON clause */ + { + /* ON clause */ + n->quals = $5; + } $$ = n; } | table_ref JOIN table_ref join_qual @@ -14759,9 +15042,16 @@ joined_table: n->larg = $1; n->rarg = $3; if ($4 != NULL && IsA($4, List)) - n->usingClause = (List *) $4; /* USING clause */ + { + /* USING clause */ + n->usingClause = linitial_node(List, castNode(List, $4)); + n->join_using_alias = lsecond_node(Alias, castNode(List, $4)); + } else - n->quals = $4; /* ON clause */ + { + /* ON clause */ + n->quals = $4; + } $$ = n; } | table_ref NATURAL join_type JOIN table_ref @@ -14772,6 +15062,7 @@ joined_table: n->larg = $1; n->rarg = $5; n->usingClause = NIL; /* figure out which columns later... */ + n->join_using_alias = NULL; n->quals = NULL; /* fill later */ $$ = n; } @@ -14784,6 +15075,7 @@ joined_table: n->larg = $1; n->rarg = $4; n->usingClause = NIL; /* figure out which columns later... */ + n->join_using_alias = NULL; n->quals = NULL; /* fill later */ $$ = n; } @@ -14818,6 +15110,22 @@ opt_alias_clause: alias_clause { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } ; +/* + * The alias clause after JOIN ... USING only accepts the AS ColId spelling, + * per SQL standard. (The grammar could parse the other variants, but they + * don't seem to be useful, and it might lead to parser problems in the + * future.) + */ +opt_alias_clause_for_join_using: + AS ColId + { + $$ = makeNode(Alias); + $$->aliasname = $2; + /* the column name list will be inserted later */ + } + | /*EMPTY*/ { $$ = NULL; } + ; + /* * func_alias_clause can include both an Alias and a coldeflist, so we make it * return a 2-element list that gets disassembled by calling production. @@ -14849,28 +15157,37 @@ func_alias_clause: } ; -join_type: FULL join_outer { $$ = JOIN_FULL; } - | LEFT join_outer { $$ = JOIN_LEFT; } - | RIGHT join_outer { $$ = JOIN_RIGHT; } +join_type: FULL opt_outer { $$ = JOIN_FULL; } + | LEFT opt_outer { $$ = JOIN_LEFT; } + | RIGHT opt_outer { $$ = JOIN_RIGHT; } | INNER_P { $$ = JOIN_INNER; } ; /* OUTER is just noise... */ -join_outer: OUTER_P { $$ = NULL; } - | /*EMPTY*/ { $$ = NULL; } +opt_outer: OUTER_P + | /*EMPTY*/ ; /* JOIN qualification clauses * Possibilities are: - * USING ( column list ) allows only unqualified column names, + * USING ( column list ) [ AS alias ] + * allows only unqualified column names, * which must match between tables. * ON expr allows more general qualifications. * - * We return USING as a List node, while an ON-expr will not be a List. + * We return USING as a two-element List (the first item being a sub-List + * of the common column names, and the second either an Alias item or NULL). + * An ON-expr will not be a List, so it can be told apart that way. */ -join_qual: USING '(' name_list ')' { $$ = (Node *) $3; } - | ON a_expr { $$ = $2; } +join_qual: USING '(' name_list ')' opt_alias_clause_for_join_using + { + $$ = (Node *) list_make2($3, $5); + } + | ON a_expr + { + $$ = $2; + } ; @@ -15732,6 +16049,7 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeFuncCall(SystemFuncName("timezone"), list_make2($5, $1), + COERCE_SQL_SYNTAX, @2); } /* @@ -15776,8 +16094,6 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op a_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); } - | a_expr qual_Op %prec POSTFIXOP - { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); } | a_expr AND a_expr { $$ = makeAndExpr($1, $3, @2); } @@ -15797,6 +16113,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($3, $5), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "~~", $1, (Node *) n, @2); @@ -15810,6 +16127,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($4, $6), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_LIKE, "!~~", $1, (Node *) n, @2); @@ -15823,6 +16141,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($3, $5), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "~~*", $1, (Node *) n, @2); @@ -15836,6 +16155,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make2($4, $6), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_ILIKE, "!~~*", $1, (Node *) n, @2); @@ -15845,6 +16165,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), list_make1($4), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", $1, (Node *) n, @2); @@ -15853,6 +16174,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), list_make2($4, $6), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", $1, (Node *) n, @2); @@ -15861,6 +16183,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), list_make1($5), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", $1, (Node *) n, @2); @@ -15869,6 +16192,7 @@ a_expr: c_expr { $$ = $1; } { FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), list_make2($5, $7), + COERCE_EXPLICIT_CALL, @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", $1, (Node *) n, @2); @@ -15929,6 +16253,7 @@ a_expr: c_expr { $$ = $1; } parser_errposition(@3))); $$ = (Node *) makeFuncCall(SystemFuncName("overlaps"), list_concat($1, $3), + COERCE_SQL_SYNTAX, @2); } | a_expr IS TRUE_P %prec IS @@ -16116,19 +16441,33 @@ a_expr: c_expr { $$ = $1; } } | a_expr IS NORMALIZED %prec IS { - $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"), list_make1($1), @2); + $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make1($1), + COERCE_SQL_SYNTAX, + @2); } | a_expr IS unicode_normal_form NORMALIZED %prec IS { - $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"), list_make2($1, makeStringConst($3, @3)), @2); + $$ = (Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make2($1, makeStringConst($3, @3)), + COERCE_SQL_SYNTAX, + @2); } | a_expr IS NOT NORMALIZED %prec IS { - $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"), list_make1($1), @2), @2); + $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make1($1), + COERCE_SQL_SYNTAX, + @2), + @2); } | a_expr IS NOT unicode_normal_form NORMALIZED %prec IS { - $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"), list_make2($1, makeStringConst($4, @4)), @2), @2); + $$ = makeNotExpr((Node *) makeFuncCall(SystemFuncName("is_normalized"), + list_make2($1, makeStringConst($4, @4)), + COERCE_SQL_SYNTAX, + @2), + @2); } | DEFAULT { @@ -16191,8 +16530,6 @@ b_expr: c_expr { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); } | qual_Op b_expr %prec Op { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); } - | b_expr qual_Op %prec POSTFIXOP - { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); } | b_expr IS DISTINCT FROM b_expr %prec IS { $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2); @@ -16256,28 +16593,6 @@ c_expr: columnref { $$ = $1; } n->indirection = check_indirection($4, yyscanner); $$ = (Node *)n; } - else if (operator_precedence_warning) - { - /* - * If precedence warnings are enabled, insert - * AEXPR_PAREN nodes wrapping all explicitly - * parenthesized subexpressions; this prevents bogus - * warnings from being issued when the ordering has - * been forced by parentheses. Take care that an - * AEXPR_PAREN node has the same exprLocation as its - * child, so as not to cause surprising changes in - * error cursor positioning. - * - * In principle we should not be relying on a GUC to - * decide whether to insert AEXPR_PAREN nodes. - * However, since they have no effect except to - * suppress warnings, it's probably safe enough; and - * we'd just as soon not waste cycles on dummy parse - * nodes if we don't have to. - */ - $$ = (Node *) makeA_Expr(AEXPR_PAREN, NIL, $2, NULL, - exprLocation($2)); - } else $$ = $2; } @@ -16410,31 +16725,41 @@ table_value_select_clause: func_application: func_name '(' ')' { - $$ = (Node *) makeFuncCall($1, NIL, @1); + $$ = (Node *) makeFuncCall($1, NIL, + COERCE_EXPLICIT_CALL, + @1); } | func_name '(' func_arg_list opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, $3, @1); + FuncCall *n = makeFuncCall($1, $3, + COERCE_EXPLICIT_CALL, + @1); n->agg_order = $4; $$ = (Node *)n; } | func_name '(' VARIADIC func_arg_expr opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, list_make1($4), @1); + FuncCall *n = makeFuncCall($1, list_make1($4), + COERCE_EXPLICIT_CALL, + @1); n->func_variadic = true; n->agg_order = $5; $$ = (Node *)n; } | func_name '(' func_arg_list ',' VARIADIC func_arg_expr opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, lappend($3, $6), @1); + FuncCall *n = makeFuncCall($1, lappend($3, $6), + COERCE_EXPLICIT_CALL, + @1); n->func_variadic = true; n->agg_order = $7; $$ = (Node *)n; } | func_name '(' ALL func_arg_list opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, $4, @1); + FuncCall *n = makeFuncCall($1, $4, + COERCE_EXPLICIT_CALL, + @1); n->agg_order = $5; /* Ideally we'd mark the FuncCall node to indicate * "must be an aggregate", but there's no provision @@ -16447,7 +16772,9 @@ func_application: func_name '(' ')' } | func_name '(' DISTINCT func_arg_list opt_sort_clause ')' { - FuncCall *n = makeFuncCall($1, $4, @1); + FuncCall *n = makeFuncCall($1, $4, + COERCE_EXPLICIT_CALL, + @1); n->agg_order = $5; n->agg_distinct = true; $$ = (Node *)n; @@ -16464,7 +16791,9 @@ func_application: func_name '(' ')' * so that later processing can detect what the argument * really was. */ - FuncCall *n = makeFuncCall($1, NIL, @1); + FuncCall *n = makeFuncCall($1, NIL, + COERCE_EXPLICIT_CALL, + @1); n->agg_star = true; $$ = (Node *)n; } @@ -16538,6 +16867,7 @@ func_expr_common_subexpr: { $$ = (Node *) makeFuncCall(SystemFuncName("pg_collation_for"), list_make1($4), + COERCE_SQL_SYNTAX, @1); } | CURRENT_DATE @@ -16604,31 +16934,77 @@ func_expr_common_subexpr: { $$ = makeTypeCast($3, $5, @1); } | EXTRACT '(' extract_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("date_part"), $3, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("extract"), + $3, + COERCE_SQL_SYNTAX, + @1); } | NORMALIZE '(' a_expr ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("normalize"), list_make1($3), @1); + $$ = (Node *) makeFuncCall(SystemFuncName("normalize"), + list_make1($3), + COERCE_SQL_SYNTAX, + @1); } | NORMALIZE '(' a_expr ',' unicode_normal_form ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("normalize"), list_make2($3, makeStringConst($5, @5)), @1); + $$ = (Node *) makeFuncCall(SystemFuncName("normalize"), + list_make2($3, makeStringConst($5, @5)), + COERCE_SQL_SYNTAX, + @1); } | OVERLAY '(' overlay_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("overlay"), $3, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("overlay"), + $3, + COERCE_SQL_SYNTAX, + @1); + } + | OVERLAY '(' func_arg_list_opt ')' + { + /* + * allow functions named overlay() to be called without + * special syntax + */ + $$ = (Node *) makeFuncCall(list_make1(makeString("overlay")), + $3, + COERCE_EXPLICIT_CALL, + @1); } | POSITION '(' position_list ')' { - /* position(A in B) is converted to position(B, A) */ - $$ = (Node *) makeFuncCall(SystemFuncName("position"), $3, @1); + /* + * position(A in B) is converted to position(B, A) + * + * We deliberately don't offer a "plain syntax" option + * for position(), because the reversal of the arguments + * creates too much risk of confusion. + */ + $$ = (Node *) makeFuncCall(SystemFuncName("position"), + $3, + COERCE_SQL_SYNTAX, + @1); } | SUBSTRING '(' substr_list ')' { /* substring(A from B for C) is converted to * substring(A, B, C) - thomas 2000-11-28 */ - $$ = (Node *) makeFuncCall(SystemFuncName("substring"), $3, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("substring"), + $3, + COERCE_SQL_SYNTAX, + @1); + } + | SUBSTRING '(' func_arg_list_opt ')' + { + /* + * allow functions named substring() to be called without + * special syntax + */ + $$ = (Node *) makeFuncCall(list_make1(makeString("substring")), + $3, + COERCE_EXPLICIT_CALL, + @1); } | TREAT '(' a_expr AS Typename ')' { @@ -16641,28 +17017,41 @@ func_expr_common_subexpr: * Convert SystemTypeName() to SystemFuncName() even though * at the moment they result in the same thing. */ - $$ = (Node *) makeFuncCall(SystemFuncName(((Value *)llast($5->names))->val.str), - list_make1($3), - @1); + $$ = (Node *) makeFuncCall(SystemFuncName(strVal(llast($5->names))), + list_make1($3), + COERCE_EXPLICIT_CALL, + @1); } | TRIM '(' BOTH trim_list ')' { /* various trim expressions are defined in SQL * - thomas 1997-07-19 */ - $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), $4, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), + $4, + COERCE_SQL_SYNTAX, + @1); } | TRIM '(' LEADING trim_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("ltrim"), $4, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("ltrim"), + $4, + COERCE_SQL_SYNTAX, + @1); } | TRIM '(' TRAILING trim_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("rtrim"), $4, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("rtrim"), + $4, + COERCE_SQL_SYNTAX, + @1); } | TRIM '(' trim_list ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), $3, @1); + $$ = (Node *) makeFuncCall(SystemFuncName("btrim"), + $3, + COERCE_SQL_SYNTAX, + @1); } | NULLIF '(' a_expr ',' a_expr ')' { @@ -16757,7 +17146,10 @@ func_expr_common_subexpr: { /* xmlexists(A PASSING [BY REF] B [BY REF]) is * converted to xmlexists(A, B)*/ - $$ = (Node *) makeFuncCall(SystemFuncName("xmlexists"), list_make2($3, $4), @1); + $$ = (Node *) makeFuncCall(SystemFuncName("xmlexists"), + list_make2($3, $4), + COERCE_SQL_SYNTAX, + @1); } /* * GPDB: In versions 4.3 of GPDB, we had the xmlexists(text, xml) @@ -17262,6 +17654,10 @@ func_arg_expr: a_expr } ; +func_arg_list_opt: func_arg_list { $$ = $1; } + | /*EMPTY*/ { $$ = NIL; } + ; + type_list: Typename { $$ = list_make1($1); } | type_list ',' Typename { $$ = lappend($1, $3); } ; @@ -17290,7 +17686,6 @@ extract_list: { $$ = list_make2(makeStringConst($1, @1), $3); } - | /*EMPTY*/ { $$ = NIL; } ; /* Allow delimited string Sconst in extract_arg as an SQL extension. @@ -17308,10 +17703,10 @@ extract_arg: ; unicode_normal_form: - NFC { $$ = "nfc"; } - | NFD { $$ = "nfd"; } - | NFKC { $$ = "nfkc"; } - | NFKD { $$ = "nfkd"; } + NFC { $$ = "NFC"; } + | NFD { $$ = "NFD"; } + | NFKC { $$ = "NFKC"; } + | NFKD { $$ = "NFKD"; } ; /* OVERLAY() arguments */ @@ -17331,29 +17726,24 @@ overlay_list: /* position_list uses b_expr not a_expr to avoid conflict with general IN */ position_list: b_expr IN_P b_expr { $$ = list_make2($3, $1); } - | /*EMPTY*/ { $$ = NIL; } ; /* * SUBSTRING() arguments * * Note that SQL:1999 has both - * * text FROM int FOR int - * * and - * * text FROM pattern FOR escape * * In the parser we map them both to a call to the substring() function and * rely on type resolution to pick the right one. * * In SQL:2003, the second variant was changed to - * * text SIMILAR pattern ESCAPE escape - * * We could in theory map that to a different function internally, but - * since we still support the SQL:1999 version, we don't. + * since we still support the SQL:1999 version, we don't. However, + * ruleutils.c will reverse-list the call in the newer style. */ substr_list: a_expr FROM a_expr FOR a_expr @@ -17367,6 +17757,13 @@ substr_list: } | a_expr FROM a_expr { + /* + * Because we aren't restricting data types here, this + * syntax can end up resolving to textregexsubstr(). + * We've historically allowed that to happen, so continue + * to accept it. However, ruleutils.c will reverse-list + * such a call in regular function call syntax. + */ $$ = list_make2($1, $3); } | a_expr FOR a_expr @@ -17390,16 +17787,6 @@ substr_list: { $$ = list_make3($1, $3, $5); } - /* - * We also want to support generic substring functions that - * accept the usual generic list of arguments. - */ - | expr_list - { - $$ = $1; - } - | /*EMPTY*/ - { $$ = NIL; } ; trim_list: a_expr FROM expr_list { $$ = lappend($3, $1); } @@ -17605,15 +17992,7 @@ target_el: a_expr AS ColLabel * modifier suffixes (DAY, MONTH, YEAR, etc) and a few other * obscure cases. */ - | a_expr IDENT - { - $$ = makeNode(ResTarget); - $$->name = $2; - $$->indirection = NIL; - $$->val = (Node *)$1; - $$->location = @1; - } - | a_expr ColLabelNoAs + | a_expr BareColLabel { $$ = makeNode(ResTarget); $$->name = $2; @@ -17884,6 +18263,13 @@ RoleId: RoleSpec "CURRENT_USER"), parser_errposition(@1))); break; + case ROLESPEC_CURRENT_ROLE: + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("%s cannot be used as a role name here", + "CURRENT_ROLE"), + parser_errposition(@1))); + break; } } ; @@ -17915,6 +18301,10 @@ RoleSpec: NonReservedWord } $$ = n; } + | CURRENT_ROLE + { + $$ = makeRoleSpec(ROLESPEC_CURRENT_ROLE, @1); + } | CURRENT_USER { $$ = makeRoleSpec(ROLESPEC_CURRENT_USER, @1); @@ -17931,6 +18321,74 @@ role_list: RoleSpec { $$ = lappend($1, $3); } ; + +/***************************************************************************** + * + * PL/pgSQL extensions + * + * You'd think a PL/pgSQL "expression" should be just an a_expr, but + * historically it can include just about anything that can follow SELECT. + * Therefore the returned struct is a SelectStmt. + *****************************************************************************/ + +PLpgSQL_Expr: opt_distinct_clause opt_target_list + from_clause where_clause + group_clause having_clause window_clause + opt_sort_clause opt_select_limit opt_for_locking_clause + { + SelectStmt *n = makeNode(SelectStmt); + + n->distinctClause = $1; + n->targetList = $2; + n->fromClause = $3; + n->whereClause = $4; + n->groupClause = ($5)->list; + n->groupDistinct = ($5)->distinct; + n->havingClause = $6; + n->windowClause = $7; + n->sortClause = $8; + if ($9) + { + n->limitOffset = $9->limitOffset; + n->limitCount = $9->limitCount; + if (!n->sortClause && + $9->limitOption == LIMIT_OPTION_WITH_TIES) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("WITH TIES cannot be specified without ORDER BY clause"))); + n->limitOption = $9->limitOption; + } + n->lockingClause = $10; + $$ = (Node *) n; + } + ; + +/* + * PL/pgSQL Assignment statement: name opt_indirection := PLpgSQL_Expr + */ + +PLAssignStmt: plassign_target opt_indirection plassign_equals PLpgSQL_Expr + { + PLAssignStmt *n = makeNode(PLAssignStmt); + + n->name = $1; + n->indirection = check_indirection($2, yyscanner); + /* nnames will be filled by calling production */ + n->val = (SelectStmt *) $4; + n->location = @1; + $$ = (Node *) n; + } + ; + +plassign_target: ColId { $$ = $1; } + | PARAM { $$ = psprintf("$%d", $1); } + ; + +plassign_equals: COLON_EQUALS + | '=' + ; + + /* * Name classification hierarchy. * @@ -17974,6 +18432,13 @@ ColLabel: IDENT { $$ = $1; } | reserved_keyword { $$ = pstrdup($1); } ; +/* Bare column label --- names that can be column labels without writing "AS". + * This classification is orthogonal to the other keyword categories. + */ +BareColLabel: IDENT { $$ = $1; } + | bare_label_keyword { $$ = pstrdup($1); } + ; + /* * Keyword category lists. Generally, every keyword present in @@ -18003,14 +18468,17 @@ unreserved_keyword: | ALSO | ALTER | ALWAYS + | ASENSITIVE | ASSERTION | ASSIGNMENT | AT + | ATOMIC | ATTACH | ATTRIBUTE | BACKWARD | BEFORE | BEGIN_P + | BREADTH | BY | CACHE | CALL @@ -18029,6 +18497,7 @@ unreserved_keyword: | COMMENTS | COMMIT | COMMITTED + | COMPRESSION | CONCURRENCY | CONFIGURATION | CONFLICT @@ -18062,6 +18531,7 @@ unreserved_keyword: | DELIMITERS | DENY | DEPENDS + | DEPTH | DETACH | DICTIONARY | DISABLE_P @@ -18094,6 +18564,7 @@ unreserved_keyword: | FIELDS | FILL | FILTER + | FINALIZE | FIRST_P | FORCE | FORMAT @@ -18246,6 +18717,7 @@ unreserved_keyword: | RESTART | RESTRICT | RETRIEVE + | RETURN | RETURNS | REVOKE | ROLE @@ -18846,84 +19318,573 @@ reserved_keyword: | WITH ; -%% - /* - * The signature of this function is required by bison. However, we - * ignore the passed yylloc and instead use the last token position - * available from the scanner. + * While all keywords can be used as column labels when preceded by AS, + * not all of them can be used as a "bare" column label without AS. + * Those that can be used as a bare label must be listed here, + * in addition to appearing in one of the category lists above. + * + * Always add a new keyword to this list if possible. Mark it BARE_LABEL + * in kwlist.h if it is included here, or AS_LABEL if it is not. */ -static void -base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg) -{ - parser_yyerror(msg); -} - -static RawStmt * -makeRawStmt(Node *stmt, int stmt_location) -{ - RawStmt *rs = makeNode(RawStmt); - - rs->stmt = stmt; - rs->stmt_location = stmt_location; - rs->stmt_len = 0; /* might get changed later */ - return rs; -} - -/* Adjust a RawStmt to reflect that it doesn't run to the end of the string */ -static void -updateRawStmtEnd(RawStmt *rs, int end_location) -{ - /* - * If we already set the length, don't change it. This is for situations - * like "select foo ;; select bar" where the same statement will be last - * in the string for more than one semicolon. - */ - if (rs->stmt_len > 0) - return; - - /* OK, update length of RawStmt */ - rs->stmt_len = end_location - rs->stmt_location; -} - -static Node * -makeColumnRef(char *colname, List *indirection, - int location, core_yyscan_t yyscanner) -{ - /* - * Generate a ColumnRef node, with an A_Indirection node added if there - * is any subscripting in the specified indirection list. However, - * any field selection at the start of the indirection list must be - * transposed into the "fields" part of the ColumnRef node. - */ - ColumnRef *c = makeNode(ColumnRef); - int nfields = 0; - ListCell *l; - - c->location = location; - foreach(l, indirection) - { - if (IsA(lfirst(l), A_Indices)) - { - A_Indirection *i = makeNode(A_Indirection); - - if (nfields == 0) - { - /* easy case - all indirection goes to A_Indirection */ - c->fields = list_make1(makeString(colname)); - i->indirection = check_indirection(indirection, yyscanner); - } - else - { - /* got to split the list in two */ - i->indirection = check_indirection(list_copy_tail(indirection, - nfields), - yyscanner); - indirection = list_truncate(indirection, nfields); - c->fields = lcons(makeString(colname), indirection); - } - i->arg = (Node *) c; - return (Node *) i; +bare_label_keyword: + ABORT_P + | ABSOLUTE_P + | ACCESS + | ACTION + | ACTIVE + | ADD_P + | ADMIN + | AFTER + | AGGREGATE + | ALL + | ALSO + | ALTER + | ALWAYS + | ANALYSE + | ANALYZE + | AND + | ANY + | ASC + | ASENSITIVE + | ASSERTION + | ASSIGNMENT + | ASYMMETRIC + | AT + | ATOMIC + | ATTACH + | ATTRIBUTE + | AUTHORIZATION + | BACKWARD + | BEFORE + | BEGIN_P + | BETWEEN + | BIGINT + | BINARY + | BIT + | BOOLEAN_P + | BOTH + | BREADTH + | BY + | CACHE + | CALL + | CALLED + | CASCADE + | CASCADED + | CASE + | CAST + | CATALOG_P + | CHAIN + | CHARACTERISTICS + | CHECK + | CHECKPOINT + | CLASS + | CLOSE + | CLUSTER + | COALESCE + | COLLATE + | COLLATION + | COLUMN + | COLUMNS + | COMMENT + | COMMENTS + | COMMIT + | COMMITTED + | COMPRESSION + | CONCURRENCY + | CONCURRENTLY + | CONFIGURATION + | CONFLICT + | CONNECTION + | CONSTRAINT + | CONSTRAINTS + | CONTAINS + | CONTENT_P + | CONTINUE_P + | CONVERSION_P + | COORDINATOR + | COPY + | COST + | CPUSET + | CPU_RATE_LIMIT + | CREATEEXTTABLE + | CROSS + | CSV + | CUBE + | CURRENT_P + | CURRENT_CATALOG + | CURRENT_DATE + | CURRENT_ROLE + | CURRENT_SCHEMA + | CURRENT_TIME + | CURRENT_TIMESTAMP + | CURRENT_USER + | CURSOR + | CYCLE + | DATA_P + | DATABASE + | DEALLOCATE + | DEC + | DECIMAL_P + | DECLARE + | DECODE + | DEFAULT + | DEFAULTS + | DEFERRABLE + | DEFERRED + | DEFINER + | DELETE_P + | DELIMITER + | DELIMITERS + | DENY + | DEPENDS + | DEPTH + | DESC + | DETACH + | DICTIONARY + | DISABLE_P + | DISCARD + | DISTINCT + | DO + | DOCUMENT_P + | DOMAIN_P + | DOUBLE_P + | DROP + | DXL + | EACH + | ELSE + | ENABLE_P + | ENCODING + | ENCRYPTED + | END_P + | ENDPOINT + | ENUM_P + | ERRORS + | ESCAPE + | EVENT + | EVERY + | EXCHANGE + | EXCLUDE + | EXCLUDING + | EXCLUSIVE + | EXECUTE + | EXISTS + | EXPAND + | EXPLAIN + | EXPRESSION + | EXTENSION + | EXTERNAL + | EXTRACT + | FALSE_P + | FAMILY + | FIELDS + | FILL + | FINALIZE + | FIRST_P + | FLOAT_P + | FOLLOWING + | FORCE + | FOREIGN + | FORMAT + | FORWARD + | FREEZE + | FULL + | FULLSCAN + | FUNCTION + | FUNCTIONS + | GENERATED + | GLOBAL + | GRANTED + | GREATEST + | GROUPING + | GROUPS + | GROUP_ID + | HANDLER + | HASH + | HEADER_P + | HOLD + | HOST + | IDENTITY_P + | IF_P + | IGNORE_P + | ILIKE + | IMMEDIATE + | IMMUTABLE + | IMPLICIT_P + | IMPORT_P + | IN_P + | INCLUDE + | INCLUDING + | INCLUSIVE + | INCREMENT + | INDEX + | INDEXES + | INHERIT + | INHERITS + | INITIALLY + | INITPLAN + | INLINE_P + | INNER_P + | INOUT + | INPUT_P + | INSENSITIVE + | INSERT + | INSTEAD + | INT_P + | INTEGER + | INTERVAL + | INVOKER + | IS + | ISOLATION + | JOIN + | KEY + | LABEL + | LANGUAGE + | LARGE_P + | LAST_P + | LATERAL_P + | LEADING + | LEAKPROOF + | LEAST + | LEFT + | LEVEL + | LIKE + | LIST + | LISTEN + | LOAD + | LOCAL + | LOCALTIME + | LOCALTIMESTAMP + | LOCATION + | LOCK_P + | LOCKED + | LOG_P + | LOGGED + | MAPPING + | MASTER + | MATCH + | MATERIALIZED + | MAXVALUE + | MEDIAN + | MEMORY_LIMIT + | MEMORY_SHARED_QUOTA + | MEMORY_SPILL_RATIO + | METHOD + | MINVALUE + | MISSING + | MODE + | MODIFIES + | MOVE + | NAME_P + | NAMES + | NATIONAL + | NATURAL + | NCHAR + | NEW + | NEWLINE + | NEXT + | NFC + | NFD + | NFKC + | NFKD + | NO + | NOCREATEEXTTABLE + | NONE + | NOOVERCOMMIT + | NORMALIZE + | NORMALIZED + | NOT + | NOTHING + | NOTIFY + | NOWAIT + | NULL_P + | NULLIF + | NULLS_P + | NUMERIC + | OBJECT_P + | OF + | OFF + | OIDS + | OLD + | ONLY + | OPERATOR + | OPTION + | OPTIONS + | OR + | ORDERED + | ORDINALITY + | OTHERS + | OUT_P + | OUTER_P + | OVERCOMMIT + | OVERLAY + | OVERRIDING + | OWNED + | OWNER + | PARALLEL + | PARSER + | PARTIAL + | PARTITIONS + | PASSING + | PASSWORD + | PERCENT + | PERSISTENTLY + | PLACING + | PLANS + | POLICY + | POSITION + | PRECEDING + | PREPARE + | PREPARED + | PRESERVE + | PRIMARY + | PRIOR + | PRIVILEGES + | PROCEDURAL + | PROCEDURE + | PROCEDURES + | PROGRAM + | PROTOCOL + | PUBLICATION + | QUEUE + | QUOTE + | RANDOMLY + | RANGE + | READ + | READABLE + | READS + | REAL + | REASSIGN + | RECHECK + | RECURSIVE + | REF + | REFERENCES + | REFERENCING + | REFRESH + | REINDEX + | REJECT_P + | RELATIVE_P + | RELEASE + | RENAME + | REPEATABLE + | REPLACE + | REPLICA + | REPLICATED + | RESET + | RESOURCE + | RESTART + | RESTRICT + | RETRIEVE + | RETURN + | RETURNS + | REVOKE + | RIGHT + | ROLE + | ROLLBACK + | ROLLUP + | ROOTPARTITION + | ROUTINE + | ROUTINES + | ROW + | ROWS + | RULE + | SAVEPOINT + | SCHEMA + | SCHEMAS + | SCROLL + | SEARCH + | SECURITY + | SEGMENT + | SEGMENTS + | SELECT + | SEQUENCE + | SEQUENCES + | SERIALIZABLE + | SERVER + | SESSION + | SESSION_USER + | SET + | SETOF + | SETS + | SHARE + | SHOW + | SIMILAR + | SIMPLE + | SKIP + | SMALLINT + | SNAPSHOT + | SOME + | SPLIT + | SQL_P + | STABLE + | STANDALONE_P + | START + | STATEMENT + | STATISTICS + | STDIN + | STDOUT + | STORAGE + | STORED + | STRICT_P + | STRIP_P + | SUBPARTITION + | SUBSCRIPTION + | SUBSTRING + | SUPPORT + | SYMMETRIC + | SYSID + | SYSTEM_P + | TABLE + | TABLES + | TABLESAMPLE + | TABLESPACE + | TEMP + | TEMPLATE + | TEMPORARY + | TEXT_P + | THEN + | THRESHOLD + | TIES + | TIME + | TIMESTAMP + | TRAILING + | TRANSACTION + | TRANSFORM + | TREAT + | TRIGGER + | TRIM + | TRUE_P + | TRUNCATE + | TRUSTED + | TYPE_P + | TYPES_P + | UESCAPE + | UNBOUNDED + | UNCOMMITTED + | UNENCRYPTED + | UNIQUE + | UNKNOWN + | UNLISTEN + | UNLOGGED + | UNTIL + | UPDATE + | USER + | USING + | VACUUM + | VALID + | VALIDATE + | VALIDATION + | VALIDATOR + | VALUE_P + | VALUES + | VARCHAR + | VARIADIC + | VERBOSE + | VERSION_P + | VIEW + | VIEWS + | VOLATILE + | WEB + | WHEN + | WHITESPACE_P + | WORK + | WRAPPER + | WRITABLE + | WRITE + | XML_P + | XMLATTRIBUTES + | XMLCONCAT + | XMLELEMENT + | XMLEXISTS + | XMLFOREST + | XMLNAMESPACES + | XMLPARSE + | XMLPI + | XMLROOT + | XMLSERIALIZE + | XMLTABLE + | YES_P + | ZONE + ; + +%% + +/* + * The signature of this function is required by bison. However, we + * ignore the passed yylloc and instead use the last token position + * available from the scanner. + */ +static void +base_yyerror(YYLTYPE *yylloc, core_yyscan_t yyscanner, const char *msg) +{ + parser_yyerror(msg); +} + +static RawStmt * +makeRawStmt(Node *stmt, int stmt_location) +{ + RawStmt *rs = makeNode(RawStmt); + + rs->stmt = stmt; + rs->stmt_location = stmt_location; + rs->stmt_len = 0; /* might get changed later */ + return rs; +} + +/* Adjust a RawStmt to reflect that it doesn't run to the end of the string */ +static void +updateRawStmtEnd(RawStmt *rs, int end_location) +{ + /* + * If we already set the length, don't change it. This is for situations + * like "select foo ;; select bar" where the same statement will be last + * in the string for more than one semicolon. + */ + if (rs->stmt_len > 0) + return; + + /* OK, update length of RawStmt */ + rs->stmt_len = end_location - rs->stmt_location; +} + +static Node * +makeColumnRef(char *colname, List *indirection, + int location, core_yyscan_t yyscanner) +{ + /* + * Generate a ColumnRef node, with an A_Indirection node added if there + * is any subscripting in the specified indirection list. However, + * any field selection at the start of the indirection list must be + * transposed into the "fields" part of the ColumnRef node. + */ + ColumnRef *c = makeNode(ColumnRef); + int nfields = 0; + ListCell *l; + + c->location = location; + foreach(l, indirection) + { + if (IsA(lfirst(l), A_Indices)) + { + A_Indirection *i = makeNode(A_Indirection); + + if (nfields == 0) + { + /* easy case - all indirection goes to A_Indirection */ + c->fields = list_make1(makeString(colname)); + i->indirection = check_indirection(indirection, yyscanner); + } + else + { + /* got to split the list in two */ + i->indirection = check_indirection(list_copy_tail(indirection, + nfields), + yyscanner); + indirection = list_truncate(indirection, nfields); + c->fields = lcons(makeString(colname), indirection); + } + i->arg = (Node *) c; + return (Node *) i; } else if (IsA(lfirst(l), A_Star)) { @@ -19166,7 +20127,7 @@ makeOrderedSetArgs(List *directargs, List *orderedargs, core_yyscan_t yyscanner) { FunctionParameter *lastd = (FunctionParameter *) llast(directargs); - int ndirectargs; + Value *ndirectargs; /* No restriction unless last direct arg is VARIADIC */ if (lastd->mode == FUNC_PARAM_VARIADIC) @@ -19190,10 +20151,10 @@ makeOrderedSetArgs(List *directargs, List *orderedargs, } /* don't merge into the next line, as list_concat changes directargs */ - ndirectargs = list_length(directargs); + ndirectargs = makeInteger(list_length(directargs)); return list_make2(list_concat(directargs, orderedargs), - makeInteger(ndirectargs)); + ndirectargs); } /* insertSelectOptions() @@ -19252,7 +20213,7 @@ insertSelectOptions(SelectStmt *stmt, if (!stmt->sortClause && limitClause->limitOption == LIMIT_OPTION_WITH_TIES) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("WITH TIES options can not be specified without ORDER BY clause"))); + errmsg("WITH TIES cannot be specified without ORDER BY clause"))); stmt->limitOption = limitClause->limitOption; } if (withClause) @@ -19355,16 +20316,10 @@ doNegateFloat(Value *v) static Node * makeAndExpr(Node *lexpr, Node *rexpr, int location) { - Node *lexp = lexpr; - - /* Look through AEXPR_PAREN nodes so they don't affect flattening */ - while (IsA(lexp, A_Expr) && - ((A_Expr *) lexp)->kind == AEXPR_PAREN) - lexp = ((A_Expr *) lexp)->lexpr; /* Flatten "a AND b AND c ..." to a single BoolExpr on sight */ - if (IsA(lexp, BoolExpr)) + if (IsA(lexpr, BoolExpr)) { - BoolExpr *blexpr = (BoolExpr *) lexp; + BoolExpr *blexpr = (BoolExpr *) lexpr; if (blexpr->boolop == AND_EXPR) { @@ -19378,16 +20333,10 @@ makeAndExpr(Node *lexpr, Node *rexpr, int location) static Node * makeOrExpr(Node *lexpr, Node *rexpr, int location) { - Node *lexp = lexpr; - - /* Look through AEXPR_PAREN nodes so they don't affect flattening */ - while (IsA(lexp, A_Expr) && - ((A_Expr *) lexp)->kind == AEXPR_PAREN) - lexp = ((A_Expr *) lexp)->lexpr; /* Flatten "a OR b OR c ..." to a single BoolExpr on sight */ - if (IsA(lexp, BoolExpr)) + if (IsA(lexpr, BoolExpr)) { - BoolExpr *blexpr = (BoolExpr *) lexp; + BoolExpr *blexpr = (BoolExpr *) lexpr; if (blexpr->boolop == OR_EXPR) { @@ -19483,6 +20432,12 @@ mergeTableFuncParameters(List *func_args, List *columns) errmsg("INOUT arguments aren't allowed in TABLE functions"))); break; } + if (p->mode != FUNC_PARAM_DEFAULT && + p->mode != FUNC_PARAM_IN && + p->mode != FUNC_PARAM_VARIADIC) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("OUT and INOUT arguments aren't allowed in TABLE functions"))); } return list_concat(func_args, columns); diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index efb6aa1c46a4..c56850233354 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -3,7 +3,7 @@ * parse_agg.c * handle aggregates in parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -515,6 +515,13 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr) else err = _("grouping operations are not allowed in index predicates"); + break; + case EXPR_KIND_STATS_EXPRESSION: + if (isAgg) + err = _("aggregate functions are not allowed in statistics expressions"); + else + err = _("grouping operations are not allowed in statistics expressions"); + break; case EXPR_KIND_ALTER_COL_TRANSFORM: if (isAgg) @@ -579,6 +586,10 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr) break; + case EXPR_KIND_CYCLE_MARK: + errkind = true; + break; + /* * There is intentionally no default: case here, so that the * compiler will warn if we add a new ParseExprKind without @@ -955,6 +966,9 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, case EXPR_KIND_INDEX_EXPRESSION: err = _("window functions are not allowed in index expressions"); break; + case EXPR_KIND_STATS_EXPRESSION: + err = _("window functions are not allowed in statistics expressions"); + break; case EXPR_KIND_INDEX_PREDICATE: err = _("window functions are not allowed in index predicates"); break; @@ -985,6 +999,9 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, case EXPR_KIND_GENERATED_COLUMN: err = _("window functions are not allowed in column generation expressions"); break; + case EXPR_KIND_CYCLE_MARK: + errkind = true; + break; /* * There is intentionally no default: case here, so that the @@ -1134,7 +1151,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry) * The limit of 4096 is arbitrary and exists simply to avoid resource * issues from pathological constructs. */ - List *gsets = expand_grouping_sets(qry->groupingSets, 4096); + List *gsets = expand_grouping_sets(qry->groupingSets, qry->groupDistinct, 4096); if (!gsets) ereport(ERROR, @@ -1153,7 +1170,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry) if (gset_common) { - for_each_cell(l, gsets, list_second_cell(gsets)) + for_each_from(l, gsets, 1) { gset_common = list_intersection_int(gset_common, lfirst(l)); if (!gset_common) @@ -1808,6 +1825,34 @@ cmp_list_len_asc(const ListCell *a, const ListCell *b) return (la > lb) ? 1 : (la == lb) ? 0 : -1; } +/* list_sort comparator to sort sub-lists by length and contents */ +static int +cmp_list_len_contents_asc(const ListCell *a, const ListCell *b) +{ + int res = cmp_list_len_asc(a, b); + + if (res == 0) + { + List *la = (List *) lfirst(a); + List *lb = (List *) lfirst(b); + ListCell *lca; + ListCell *lcb; + + forboth(lca, la, lcb, lb) + { + int va = lfirst_int(lca); + int vb = lfirst_int(lcb); + + if (va > vb) + return 1; + if (va < vb) + return -1; + } + } + + return res; +} + /* * Expand a groupingSets clause to a flat list of grouping sets. * The returned list is sorted by length, shortest sets first. @@ -1816,7 +1861,7 @@ cmp_list_len_asc(const ListCell *a, const ListCell *b) * some consistency checks. */ List * -expand_grouping_sets(List *groupingSets, int limit) +expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit) { List *expanded_groups = NIL; List *result = NIL; @@ -1854,7 +1899,7 @@ expand_grouping_sets(List *groupingSets, int limit) result = lappend(result, list_union_int(NIL, (List *) lfirst(lc))); } - for_each_cell(lc, expanded_groups, list_second_cell(expanded_groups)) + for_each_from(lc, expanded_groups, 1) { List *p = lfirst(lc); List *new_result = NIL; @@ -1874,8 +1919,31 @@ expand_grouping_sets(List *groupingSets, int limit) result = new_result; } - /* Now sort the lists by length */ - list_sort(result, cmp_list_len_asc); + /* Now sort the lists by length and deduplicate if necessary */ + if (!groupDistinct || list_length(result) < 2) + list_sort(result, cmp_list_len_asc); + else + { + ListCell *cell; + List *prev; + + /* Sort each groupset individually */ + foreach(cell, result) + list_sort(lfirst(cell), list_int_cmp); + + /* Now sort the list of groupsets by length and contents */ + list_sort(result, cmp_list_len_contents_asc); + + /* Finally, remove duplicates */ + prev = linitial(result); + for_each_from(cell, result, 1) + { + if (equal(lfirst(cell), prev)) + result = foreach_delete_current(result, cell); + else + prev = lfirst(cell); + } + } return result; } diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 9ab00b0e66a8..e215abacf69b 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -65,7 +65,6 @@ static int extractRemainingColumns(ParseNamespaceColumn *src_nscolumns, List **res_colnames, List **res_colvars, ParseNamespaceColumn *res_nscolumns); static Node *transformJoinUsingClause(ParseState *pstate, - RangeTblEntry *leftRTE, RangeTblEntry *rightRTE, List *leftVars, List *rightVars); static Node *transformJoinOnClause(ParseState *pstate, JoinExpr *j, List *namespace); @@ -448,7 +447,6 @@ extractRemainingColumns(ParseNamespaceColumn *src_nscolumns, */ static Node * transformJoinUsingClause(ParseState *pstate, - RangeTblEntry *leftRTE, RangeTblEntry *rightRTE, List *leftVars, List *rightVars) { Node *result; @@ -471,8 +469,8 @@ transformJoinUsingClause(ParseState *pstate, A_Expr *e; /* Require read access to the join variables */ - markVarForSelectPriv(pstate, lvar, leftRTE); - markVarForSelectPriv(pstate, rvar, rightRTE); + markVarForSelectPriv(pstate, lvar); + markVarForSelectPriv(pstate, rvar); /* Now create the lvar = rvar join condition */ e = makeSimpleA_Expr(AEXPR_OP, "=", @@ -753,10 +751,10 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r) list_length(fc->args) > 1 && fc->agg_order == NIL && fc->agg_filter == NULL && + fc->over == NULL && !fc->agg_star && !fc->agg_distinct && !fc->func_variadic && - fc->over == NULL && coldeflist == NIL) { ListCell *lc; @@ -770,6 +768,7 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r) newfc = makeFuncCall(SystemFuncName("unnest"), list_make1(arg), + COERCE_EXPLICIT_CALL, fc->location); newfexpr = transformExpr(pstate, (Node *) newfc, @@ -1429,9 +1428,9 @@ transformFromClauseItem(ParseState *pstate, Node *n, * input column numbers more easily. */ l_nscolumns = l_nsitem->p_nscolumns; - l_colnames = l_nsitem->p_rte->eref->colnames; + l_colnames = l_nsitem->p_names->colnames; r_nscolumns = r_nsitem->p_nscolumns; - r_colnames = r_nsitem->p_rte->eref->colnames; + r_colnames = r_nsitem->p_names->colnames; /* * Natural join does not explicitly specify columns; must generate @@ -1477,6 +1476,13 @@ transformFromClauseItem(ParseState *pstate, Node *n, j->usingClause = rlist; } + /* + * If a USING clause alias was specified, save the USING columns as + * its column list. + */ + if (j->join_using_alias) + j->join_using_alias->colnames = j->usingClause; + /* * Now transform the join qualifications, if any. */ @@ -1621,8 +1627,6 @@ transformFromClauseItem(ParseState *pstate, Node *n, } j->quals = transformJoinUsingClause(pstate, - l_nsitem->p_rte, - r_nsitem->p_rte, l_usingvars, r_usingvars); } @@ -1674,6 +1678,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, res_colvars, l_colnos, r_colnos, + j->join_using_alias, j->alias, true); @@ -1683,7 +1688,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, * Now that we know the join RTE's rangetable index, we can fix up the * res_nscolumns data in places where it should contain that. */ - Assert(res_colindex == list_length(nsitem->p_rte->eref->colnames)); + Assert(res_colindex == list_length(nsitem->p_names->colnames)); for (k = 0; k < res_colindex; k++) { ParseNamespaceColumn *nscol = res_nscolumns + k; @@ -1707,6 +1712,30 @@ transformFromClauseItem(ParseState *pstate, Node *n, pstate->p_joinexprs = lappend(pstate->p_joinexprs, j); Assert(list_length(pstate->p_joinexprs) == j->rtindex); + /* + * If the join has a USING alias, build a ParseNamespaceItem for that + * and add it to the list of nsitems in the join's input. + */ + if (j->join_using_alias) + { + ParseNamespaceItem *jnsitem; + + jnsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem)); + jnsitem->p_names = j->join_using_alias; + jnsitem->p_rte = nsitem->p_rte; + jnsitem->p_rtindex = nsitem->p_rtindex; + /* no need to copy the first N columns, just use res_nscolumns */ + jnsitem->p_nscolumns = res_nscolumns; + /* set default visibility flags; might get changed later */ + jnsitem->p_rel_visible = true; + jnsitem->p_cols_visible = true; + jnsitem->p_lateral_only = false; + jnsitem->p_lateral_ok = true; + /* Per SQL, we must check for alias conflicts */ + checkNameSpaceConflicts(pstate, list_make1(jnsitem), my_namespace); + my_namespace = lappend(my_namespace, jnsitem); + } + /* * Prepare returned namespace list. If the JOIN has an alias then it * hides the contained RTEs completely; otherwise, the contained RTEs @@ -1780,24 +1809,13 @@ buildMergedJoinVar(ParseState *pstate, JoinType jointype, *r_node, *res_node; - /* - * Choose output type if input types are dissimilar. - */ - outcoltype = l_colvar->vartype; - outcoltypmod = l_colvar->vartypmod; - if (outcoltype != r_colvar->vartype) - { - outcoltype = select_common_type(pstate, + outcoltype = select_common_type(pstate, + list_make2(l_colvar, r_colvar), + "JOIN/USING", + NULL); + outcoltypmod = select_common_typmod(pstate, list_make2(l_colvar, r_colvar), - "JOIN/USING", - NULL); - outcoltypmod = -1; /* ie, unknown */ - } - else if (outcoltypmod != r_colvar->vartypmod) - { - /* same type, but not same typmod */ - outcoltypmod = -1; /* ie, unknown */ - } + outcoltype); /* * Insert coercion functions if needed. Note that a difference in typmod @@ -1982,7 +2000,7 @@ transformLimitClause(ParseState *pstate, Node *clause, IsA(clause, A_Const) && ((A_Const *) clause)->val.type == T_Null) ereport(ERROR, (errcode(ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE), - errmsg("row count cannot be NULL in FETCH FIRST ... WITH TIES clause"))); + errmsg("row count cannot be null in FETCH FIRST ... WITH TIES clause"))); return qual; } @@ -3511,17 +3529,6 @@ transformOnConflictArbiter(ParseState *pstate, /* ON CONFLICT DO NOTHING does not require an inference clause */ if (infer) { - List *save_namespace; - - /* - * While we process the arbiter expressions, accept only non-qualified - * references to the target table. Hide any other relations. - */ - save_namespace = pstate->p_namespace; - pstate->p_namespace = NIL; - addNSItemToQuery(pstate, pstate->p_target_nsitem, - false, false, true); - if (infer->indexElems) *arbiterExpr = resolve_unique_index_expr(pstate, infer, pstate->p_target_relation); @@ -3534,8 +3541,6 @@ transformOnConflictArbiter(ParseState *pstate, *arbiterWhere = transformExpr(pstate, infer->whereClause, EXPR_KIND_INDEX_PREDICATE); - pstate->p_namespace = save_namespace; - /* * If the arbiter is specified by constraint name, get the constraint * OID and mark the constrained columns as requiring SELECT privilege, diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index d2c8b28e78e0..cc596ce3a9a5 100644 --- a/src/backend/parser/parse_coerce.c +++ b/src/backend/parser/parse_coerce.c @@ -3,7 +3,7 @@ * parse_coerce.c * handle type coercions/conversions for parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,6 +29,7 @@ #include "parser/parse_type.h" #include "utils/builtins.h" #include "utils/datum.h" /* needed for datumIsEqual() */ +#include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/syscache.h" #include "utils/typcache.h" @@ -97,6 +98,7 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, * *must* know that to avoid possibly calling hide_coercion_node on * something that wasn't generated by coerce_type. Note that if there are * multiple stacked CollateExprs, we just discard all but the topmost. + * Also, if the target type isn't collatable, we discard the CollateExpr. */ origexpr = expr; while (expr && IsA(expr, CollateExpr)) @@ -116,7 +118,7 @@ coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, ccontext, cformat, location, (result != expr && !IsA(result, Const) && !IsA(result, Var))); - if (expr != origexpr) + if (expr != origexpr && type_is_collatable(targettype)) { /* Reinstall top CollateExpr */ CollateExpr *coll = (CollateExpr *) origexpr; @@ -192,19 +194,21 @@ coerce_type(ParseState *pstate, Node *node, if (targetTypeId == ANYARRAYOID || targetTypeId == ANYENUMOID || targetTypeId == ANYRANGEOID || + targetTypeId == ANYMULTIRANGEOID || targetTypeId == ANYCOMPATIBLEARRAYOID || - targetTypeId == ANYCOMPATIBLERANGEOID) + targetTypeId == ANYCOMPATIBLERANGEOID || + targetTypeId == ANYCOMPATIBLEMULTIRANGEOID) { /* * Assume can_coerce_type verified that implicit coercion is okay. * * These cases are unlike the ones above because the exposed type of - * the argument must be an actual array, enum, or range type. In - * particular the argument must *not* be an UNKNOWN constant. If it - * is, we just fall through; below, we'll call the pseudotype's input - * function, which will produce an error. Also, if what we have is a - * domain over array, enum, or range, we have to relabel it to its - * base type. + * the argument must be an actual array, enum, range, or multirange + * type. In particular the argument must *not* be an UNKNOWN + * constant. If it is, we just fall through; below, we'll call the + * pseudotype's input function, which will produce an error. Also, if + * what we have is a domain over array, enum, range, or multirange, we + * have to relabel it to its base type. * * Note: currently, we can't actually see a domain-over-enum here, * since the other functions in this file will not match such a @@ -414,20 +418,26 @@ coerce_type(ParseState *pstate, Node *node, { /* * If we have a COLLATE clause, we have to push the coercion - * underneath the COLLATE. This is really ugly, but there is little - * choice because the above hacks on Consts and Params wouldn't happen + * underneath the COLLATE; or discard the COLLATE if the target type + * isn't collatable. This is really ugly, but there is little choice + * because the above hacks on Consts and Params wouldn't happen * otherwise. This kluge has consequences in coerce_to_target_type. */ CollateExpr *coll = (CollateExpr *) node; - CollateExpr *newcoll = makeNode(CollateExpr); - newcoll->arg = (Expr *) - coerce_type(pstate, (Node *) coll->arg, - inputTypeId, targetTypeId, targetTypeMod, - ccontext, cformat, location); - newcoll->collOid = coll->collOid; - newcoll->location = coll->location; - return (Node *) newcoll; + result = coerce_type(pstate, (Node *) coll->arg, + inputTypeId, targetTypeId, targetTypeMod, + ccontext, cformat, location); + if (type_is_collatable(targetTypeId)) + { + CollateExpr *newcoll = makeNode(CollateExpr); + + newcoll->arg = (Expr *) result; + newcoll->collOid = coll->collOid; + newcoll->location = coll->location; + result = (Node *) newcoll; + } + return result; } pathtype = find_coercion_pathway(targetTypeId, inputTypeId, ccontext, &funcId); @@ -1566,6 +1576,43 @@ coerce_to_common_type(ParseState *pstate, Node *node, return node; } +/* + * select_common_typmod() + * Determine the common typmod of a list of input expressions. + * + * common_type is the selected common type of the expressions, typically + * computed using select_common_type(). + */ +int32 +select_common_typmod(ParseState *pstate, List *exprs, Oid common_type) +{ + ListCell *lc; + bool first = true; + int32 result = -1; + + foreach(lc, exprs) + { + Node *expr = (Node *) lfirst(lc); + + /* Types must match */ + if (exprType(expr) != common_type) + return -1; + else if (first) + { + result = exprTypmod(expr); + first = false; + } + else + { + /* As soon as we see a non-matching typmod, fall back to -1 */ + if (result != exprTypmod(expr)) + return -1; + } + } + + return result; +} + /* * check_generic_type_consistency() * Are the actual arguments potentially compatible with a @@ -1576,8 +1623,8 @@ coerce_to_common_type(ParseState *pstate, Node *node, * 1) All arguments declared ANYELEMENT must have the same datatype. * 2) All arguments declared ANYARRAY must have the same datatype, * which must be a varlena array type. - * 3) All arguments declared ANYRANGE must have the same datatype, - * which must be a range type. + * 3) All arguments declared ANYRANGE or ANYMULTIRANGE must be a range or + * multirange type, all derived from the same base datatype. * 4) If there are arguments of more than one of these polymorphic types, * the array element type and/or range subtype must be the same as each * other and the same as the ANYELEMENT type. @@ -1592,8 +1639,8 @@ coerce_to_common_type(ParseState *pstate, Node *node, * to a common supertype (chosen as per select_common_type's rules). * ANYCOMPATIBLENONARRAY works like ANYCOMPATIBLE but also requires the * common supertype to not be an array. If there are ANYCOMPATIBLEARRAY - * or ANYCOMPATIBLERANGE arguments, their element types or subtypes are - * included while making the choice of common supertype. + * or ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE arguments, their element + * types or subtypes are included while making the choice of common supertype. * 8) The resolved type of ANYCOMPATIBLEARRAY arguments will be the array * type over the common supertype (which might not be the same array type * as any of the original arrays). @@ -1601,6 +1648,10 @@ coerce_to_common_type(ParseState *pstate, Node *node, * (after domain flattening), since we have no preference rule that would * let us choose one over another. Furthermore, that range's subtype * must exactly match the common supertype chosen by rule 7. + * 10) All ANYCOMPATIBLEMULTIRANGE arguments must be the exact same multirange + * type (after domain flattening), since we have no preference rule that would + * let us choose one over another. Furthermore, that multirange's range's + * subtype must exactly match the common supertype chosen by rule 7. * * Domains over arrays match ANYARRAY, and are immediately flattened to their * base type. (Thus, for example, we will consider it a match if one ANYARRAY @@ -1609,7 +1660,9 @@ coerce_to_common_type(ParseState *pstate, Node *node, * for ANYCOMPATIBLEARRAY and ANYCOMPATIBLENONARRAY. * * Similarly, domains over ranges match ANYRANGE or ANYCOMPATIBLERANGE, - * and are immediately flattened to their base type. + * and are immediately flattened to their base type, and domains over + * multiranges match ANYMULTIRANGE or ANYCOMPATIBLEMULTIRANGE and are immediately + * flattened to their base type. * * Note that domains aren't currently considered to match ANYENUM, * even if their base type would match. @@ -1627,8 +1680,12 @@ check_generic_type_consistency(const Oid *actual_arg_types, Oid elem_typeid = InvalidOid; Oid array_typeid = InvalidOid; Oid range_typeid = InvalidOid; + Oid multirange_typeid = InvalidOid; Oid anycompatible_range_typeid = InvalidOid; Oid anycompatible_range_typelem = InvalidOid; + Oid anycompatible_multirange_typeid = InvalidOid; + Oid anycompatible_multirange_typelem = InvalidOid; + Oid range_typelem = InvalidOid; bool have_anynonarray = false; bool have_anyenum = false; bool have_anycompatible_nonarray = false; @@ -1677,6 +1734,15 @@ check_generic_type_consistency(const Oid *actual_arg_types, return false; range_typeid = actual_type; } + else if (decl_type == ANYMULTIRANGEOID) + { + if (actual_type == UNKNOWNOID) + continue; + actual_type = getBaseType(actual_type); /* flatten domains */ + if (OidIsValid(multirange_typeid) && actual_type != multirange_typeid) + return false; + multirange_typeid = actual_type; + } else if (decl_type == ANYCOMPATIBLEOID || decl_type == ANYCOMPATIBLENONARRAYOID) { @@ -1721,6 +1787,45 @@ check_generic_type_consistency(const Oid *actual_arg_types, anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem; } } + else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID) + { + if (actual_type == UNKNOWNOID) + continue; + actual_type = getBaseType(actual_type); /* flatten domains */ + if (OidIsValid(anycompatible_multirange_typeid)) + { + /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */ + if (anycompatible_multirange_typeid != actual_type) + return false; + } + else + { + anycompatible_multirange_typeid = actual_type; + anycompatible_multirange_typelem = get_multirange_range(actual_type); + if (!OidIsValid(anycompatible_multirange_typelem)) + return false; /* not a multirange type */ + + if (OidIsValid(anycompatible_range_typeid)) + { + /* + * ANYCOMPATIBLEMULTIRANGE and ANYCOMPATIBLERANGE + * arguments must match + */ + if (anycompatible_range_typeid != anycompatible_multirange_typelem) + return false; + } + else + { + anycompatible_range_typeid = anycompatible_multirange_typelem; + anycompatible_range_typelem = get_range_subtype(anycompatible_range_typeid); + if (!OidIsValid(anycompatible_range_typelem)) + return false; /* not a range type */ + } + /* collect the subtype for common-supertype choice */ + anycompatible_actual_types[n_anycompatible_args++] = + anycompatible_range_typelem; + } + } } /* Get the element type based on the array type, if we have one */ @@ -1767,8 +1872,6 @@ check_generic_type_consistency(const Oid *actual_arg_types, /* Get the element type based on the range type, if we have one */ if (OidIsValid(range_typeid)) { - Oid range_typelem; - range_typelem = get_range_subtype(range_typeid); if (!OidIsValid(range_typelem)) return false; /* should be a range, but isn't */ @@ -1787,6 +1890,45 @@ check_generic_type_consistency(const Oid *actual_arg_types, } } + /* Get the element type based on the multirange type, if we have one */ + if (OidIsValid(multirange_typeid)) + { + Oid multirange_typelem; + + multirange_typelem = get_multirange_range(multirange_typeid); + if (!OidIsValid(multirange_typelem)) + return false; /* should be a multirange, but isn't */ + + if (!OidIsValid(range_typeid)) + { + /* + * If we don't have a range type yet, use the one we just got + */ + range_typeid = multirange_typelem; + range_typelem = get_range_subtype(multirange_typelem); + if (!OidIsValid(range_typelem)) + return false; /* should be a range, but isn't */ + } + else if (multirange_typelem != range_typeid) + { + /* otherwise, they better match */ + return false; + } + + if (!OidIsValid(elem_typeid)) + { + /* + * If we don't have an element type yet, use the one we just got + */ + elem_typeid = range_typelem; + } + else if (range_typelem != elem_typeid) + { + /* otherwise, they better match */ + return false; + } + } + if (have_anynonarray) { /* require the element type to not be an array or domain over array */ @@ -1825,8 +1967,10 @@ check_generic_type_consistency(const Oid *actual_arg_types, } /* - * the anycompatible type must exactly match the range element type, - * if we were able to identify one + * The anycompatible type must exactly match the range element type, + * if we were able to identify one. This checks compatibility for + * anycompatiblemultirange too since that also sets + * anycompatible_range_typelem above. */ if (OidIsValid(anycompatible_range_typelem) && anycompatible_range_typelem != anycompatible_typeid) @@ -1865,21 +2009,27 @@ check_generic_type_consistency(const Oid *actual_arg_types, * argument's actual type as the function's return type. * 2) If return type is ANYARRAY, and any argument is ANYARRAY, use the * argument's actual type as the function's return type. - * 3) Similarly, if return type is ANYRANGE, and any argument is ANYRANGE, - * use the argument's actual type as the function's return type. - * 4) Otherwise, if return type is ANYELEMENT or ANYARRAY, and there is + * 3) Similarly, if return type is ANYRANGE or ANYMULTIRANGE, and any + * argument is ANYRANGE or ANYMULTIRANGE, use that argument's + * actual type, range type or multirange type as the function's return + * type. + * 4) Otherwise, if return type is ANYMULTIRANGE, and any argument is + * ANYMULTIRANGE, use the argument's actual type as the function's return + * type. Or if any argument is ANYRANGE, use its multirange type as the + * function's return type. + * 5) Otherwise, if return type is ANYELEMENT or ANYARRAY, and there is * at least one ANYELEMENT, ANYARRAY, or ANYRANGE input, deduce the * return type from those inputs, or throw error if we can't. - * 5) Otherwise, if return type is ANYRANGE, throw error. (We have no way to - * select a specific range type if the arguments don't include ANYRANGE.) - * 6) ANYENUM is treated the same as ANYELEMENT except that if it is used + * 6) Otherwise, if return type is ANYRANGE or ANYMULTIRANGE, throw error. + * (We have no way to select a specific range type if the arguments don't + * include ANYRANGE.) * (alone or in combination with plain ANYELEMENT), we add the extra * condition that the ANYELEMENT type must be an enum. - * 7) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used, + * 8) ANYNONARRAY is treated the same as ANYELEMENT except that if it is used, * we add the extra condition that the ANYELEMENT type must not be an array. * (This is a no-op if used in combination with ANYARRAY or ANYENUM, but * is an extra restriction if not.) - * 8) ANYCOMPATIBLE, ANYCOMPATIBLEARRAY, ANYCOMPATIBLENONARRAY, and + * 9) ANYCOMPATIBLE, ANYCOMPATIBLEARRAY, ANYCOMPATIBLENONARRAY, and * ANYCOMPATIBLERANGE are handled by resolving the common supertype * of those arguments (or their element types/subtypes, for array and range * inputs), and then coercing all those arguments to the common supertype, @@ -1933,10 +2083,15 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, Oid elem_typeid = InvalidOid; Oid array_typeid = InvalidOid; Oid range_typeid = InvalidOid; + Oid multirange_typeid = InvalidOid; Oid anycompatible_typeid = InvalidOid; Oid anycompatible_array_typeid = InvalidOid; Oid anycompatible_range_typeid = InvalidOid; Oid anycompatible_range_typelem = InvalidOid; + Oid anycompatible_multirange_typeid = InvalidOid; + Oid anycompatible_multirange_typelem = InvalidOid; + Oid range_typelem; + Oid multirange_typelem; bool have_anynonarray = (rettype == ANYNONARRAYOID); bool have_anyenum = (rettype == ANYENUMOID); bool have_anycompatible_nonarray = (rettype == ANYCOMPATIBLENONARRAYOID); @@ -1975,7 +2130,7 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, if (OidIsValid(elem_typeid) && actual_type != elem_typeid) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("arguments declared \"anyelement\" are not all alike"), + errmsg("arguments declared \"%s\" are not all alike", "anyelement"), errdetail("%s versus %s", format_type_be(elem_typeid), format_type_be(actual_type)))); @@ -1995,7 +2150,7 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, if (OidIsValid(array_typeid) && actual_type != array_typeid) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("arguments declared \"anyarray\" are not all alike"), + errmsg("arguments declared \"%s\" are not all alike", "anyarray"), errdetail("%s versus %s", format_type_be(array_typeid), format_type_be(actual_type)))); @@ -2015,12 +2170,32 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, if (OidIsValid(range_typeid) && actual_type != range_typeid) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("arguments declared \"anyrange\" are not all alike"), + errmsg("arguments declared \"%s\" are not all alike", "anyrange"), errdetail("%s versus %s", format_type_be(range_typeid), format_type_be(actual_type)))); range_typeid = actual_type; } + else if (decl_type == ANYMULTIRANGEOID) + { + n_poly_args++; + if (actual_type == UNKNOWNOID) + { + have_poly_unknowns = true; + continue; + } + if (allow_poly && decl_type == actual_type) + continue; /* no new information here */ + actual_type = getBaseType(actual_type); /* flatten domains */ + if (OidIsValid(multirange_typeid) && actual_type != multirange_typeid) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("arguments declared \"%s\" are not all alike", "anymultirange"), + errdetail("%s versus %s", + format_type_be(multirange_typeid), + format_type_be(actual_type)))); + multirange_typeid = actual_type; + } else if (decl_type == ANYCOMPATIBLEOID || decl_type == ANYCOMPATIBLENONARRAYOID) { @@ -2070,7 +2245,7 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, if (anycompatible_range_typeid != actual_type) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("arguments declared \"anycompatiblerange\" are not all alike"), + errmsg("arguments declared \"%s\" are not all alike", "anycompatiblerange"), errdetail("%s versus %s", format_type_be(anycompatible_range_typeid), format_type_be(actual_type)))); @@ -2089,6 +2264,40 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem; } } + else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID) + { + have_poly_anycompatible = true; + if (actual_type == UNKNOWNOID) + continue; + if (allow_poly && decl_type == actual_type) + continue; /* no new information here */ + actual_type = getBaseType(actual_type); /* flatten domains */ + if (OidIsValid(anycompatible_multirange_typeid)) + { + /* All ANYCOMPATIBLEMULTIRANGE arguments must be the same type */ + if (anycompatible_multirange_typeid != actual_type) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("arguments declared \"%s\" are not all alike", "anycompatiblemultirange"), + errdetail("%s versus %s", + format_type_be(anycompatible_multirange_typeid), + format_type_be(actual_type)))); + } + else + { + anycompatible_multirange_typeid = actual_type; + anycompatible_multirange_typelem = get_multirange_range(actual_type); + anycompatible_range_typelem = get_range_subtype(anycompatible_multirange_typelem); + if (!OidIsValid(anycompatible_multirange_typelem)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("argument declared %s is not a multirange type but type %s", + "anycompatiblemultirange", + format_type_be(actual_type)))); + /* collect the subtype for common-supertype choice */ + anycompatible_actual_types[n_anycompatible_args++] = anycompatible_range_typelem; + } + } } /* @@ -2157,8 +2366,6 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, /* Get the element type based on the range type, if we have one */ if (OidIsValid(range_typeid)) { - Oid range_typelem; - range_typelem = get_range_subtype(range_typeid); if (!OidIsValid(range_typelem)) ereport(ERROR, @@ -2187,6 +2394,62 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, format_type_be(elem_typeid)))); } } + else + range_typelem = InvalidOid; + + /* Get the element type based on the multirange type, if we have one */ + if (OidIsValid(multirange_typeid)) + { + multirange_typelem = get_multirange_range(multirange_typeid); + if (!OidIsValid(multirange_typelem)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("argument declared %s is not a multirange type but type %s", + "anymultirange", + format_type_be(multirange_typeid)))); + + if (!OidIsValid(range_typeid)) + { + /* + * If we don't have a range type yet, use the one we just got + */ + range_typeid = multirange_typelem; + range_typelem = get_range_subtype(range_typeid); + } + else if (multirange_typelem != range_typeid) + { + /* otherwise, they better match */ + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("argument declared %s is not consistent with argument declared %s", + "anymultirange", "anyrange"), + errdetail("%s versus %s", + format_type_be(multirange_typeid), + format_type_be(range_typeid)))); + } + + if (!OidIsValid(elem_typeid)) + { + /* + * if we don't have an element type yet, use the one we just + * got + */ + elem_typeid = range_typelem; + } + else if (range_typelem != elem_typeid) + { + /* otherwise, they better match */ + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("argument declared %s is not consistent with argument declared %s", + "anymultirange", "anyelement"), + errdetail("%s versus %s", + format_type_be(multirange_typeid), + format_type_be(elem_typeid)))); + } + } + else + multirange_typelem = InvalidOid; if (!OidIsValid(elem_typeid)) { @@ -2195,12 +2458,13 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, elem_typeid = ANYELEMENTOID; array_typeid = ANYARRAYOID; range_typeid = ANYRANGEOID; + multirange_typeid = ANYMULTIRANGEOID; } else { /* - * Only way to get here is if all the polymorphic args have - * UNKNOWN inputs + * Only way to get here is if all the family-1 polymorphic + * arguments have UNKNOWN inputs. */ ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), @@ -2294,14 +2558,15 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, anycompatible_typeid = ANYCOMPATIBLEOID; anycompatible_array_typeid = ANYCOMPATIBLEARRAYOID; anycompatible_range_typeid = ANYCOMPATIBLERANGEOID; + anycompatible_multirange_typeid = ANYCOMPATIBLEMULTIRANGEOID; } else { /* - * Only way to get here is if all the ANYCOMPATIBLE args have - * UNKNOWN inputs. Resolve to TEXT as select_common_type() - * would do. That doesn't license us to use TEXTRANGE, - * though. + * Only way to get here is if all the family-2 polymorphic + * arguments have UNKNOWN inputs. Resolve to TEXT as + * select_common_type() would do. That doesn't license us to + * use TEXTRANGE, though. */ anycompatible_typeid = TEXTOID; anycompatible_array_typeid = TEXTARRAYOID; @@ -2313,7 +2578,7 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, } } - /* replace polymorphic types by selected types */ + /* replace family-2 polymorphic types by selected types */ for (int j = 0; j < nargs; j++) { Oid decl_type = declared_arg_types[j]; @@ -2325,15 +2590,17 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, declared_arg_types[j] = anycompatible_array_typeid; else if (decl_type == ANYCOMPATIBLERANGEOID) declared_arg_types[j] = anycompatible_range_typeid; + else if (decl_type == ANYCOMPATIBLEMULTIRANGEOID) + declared_arg_types[j] = anycompatible_multirange_typeid; } } /* - * If we had any UNKNOWN inputs for polymorphic arguments, re-scan to - * assign correct types to them. + * If we had any UNKNOWN inputs for family-1 polymorphic arguments, + * re-scan to assign correct types to them. * * Note: we don't have to consider unknown inputs that were matched to - * ANYCOMPATIBLE-family arguments, because we forcibly updated their + * family-2 polymorphic arguments, because we forcibly updated their * declared_arg_types[] positions just above. */ if (have_poly_unknowns) @@ -2375,6 +2642,17 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, } declared_arg_types[j] = range_typeid; } + else if (decl_type == ANYMULTIRANGEOID) + { + if (!OidIsValid(multirange_typeid)) + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("could not find multirange type for data type %s", + format_type_be(elem_typeid)))); + } + declared_arg_types[j] = multirange_typeid; + } } } @@ -2411,6 +2689,22 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, return range_typeid; } + /* if we return ANYMULTIRANGE use the appropriate argument type */ + if (rettype == ANYMULTIRANGEOID) + { + if (!OidIsValid(multirange_typeid)) + { + if (OidIsValid(range_typeid)) + multirange_typeid = get_range_multirange(range_typeid); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("could not find multirange type for data type %s", + format_type_be(elem_typeid)))); + } + return multirange_typeid; + } + /* if we return ANYCOMPATIBLE use the appropriate type */ if (rettype == ANYCOMPATIBLEOID || rettype == ANYCOMPATIBLENONARRAYOID) @@ -2445,6 +2739,17 @@ enforce_generic_type_consistency(const Oid *actual_arg_types, return anycompatible_range_typeid; } + /* if we return ANYCOMPATIBLEMULTIRANGE use the appropriate argument type */ + if (rettype == ANYCOMPATIBLEMULTIRANGEOID) + { + /* this error is unreachable if the function signature is valid: */ + if (!OidIsValid(anycompatible_multirange_typeid)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg_internal("could not identify anycompatiblemultirange type"))); + return anycompatible_multirange_typeid; + } + /* we don't return a generic type; send back the original return type */ return rettype; } @@ -2462,20 +2767,38 @@ check_valid_polymorphic_signature(Oid ret_type, const Oid *declared_arg_types, int nargs) { - if (ret_type == ANYRANGEOID || ret_type == ANYCOMPATIBLERANGEOID) + if (ret_type == ANYRANGEOID || ret_type == ANYMULTIRANGEOID) { /* - * ANYRANGE requires an ANYRANGE input, else we can't tell which of - * several range types with the same element type to use. Likewise - * for ANYCOMPATIBLERANGE. + * ANYRANGE and ANYMULTIRANGE require an ANYRANGE or ANYMULTIRANGE + * input, else we can't tell which of several range types with the + * same element type to use. */ for (int i = 0; i < nargs; i++) { - if (declared_arg_types[i] == ret_type) + if (declared_arg_types[i] == ANYRANGEOID || + declared_arg_types[i] == ANYMULTIRANGEOID) return NULL; /* OK */ } - return psprintf(_("A result of type %s requires at least one input of type %s."), - format_type_be(ret_type), format_type_be(ret_type)); + return psprintf(_("A result of type %s requires at least one input of type anyrange or anymultirange."), + format_type_be(ret_type)); + } + else if (ret_type == ANYCOMPATIBLERANGEOID || ret_type == ANYCOMPATIBLEMULTIRANGEOID) + { + /* + * ANYCOMPATIBLERANGE and ANYCOMPATIBLEMULTIRANGE require an + * ANYCOMPATIBLERANGE or ANYCOMPATIBLEMULTIRANGE input, else we can't + * tell which of several range types with the same element type to + * use. + */ + for (int i = 0; i < nargs; i++) + { + if (declared_arg_types[i] == ANYCOMPATIBLERANGEOID || + declared_arg_types[i] == ANYCOMPATIBLEMULTIRANGEOID) + return NULL; /* OK */ + } + return psprintf(_("A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange."), + format_type_be(ret_type)); } else if (IsPolymorphicTypeFamily1(ret_type)) { @@ -2486,7 +2809,7 @@ check_valid_polymorphic_signature(Oid ret_type, return NULL; /* OK */ } /* Keep this list in sync with IsPolymorphicTypeFamily1! */ - return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange."), + return psprintf(_("A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange."), format_type_be(ret_type)); } else if (IsPolymorphicTypeFamily2(ret_type)) @@ -2638,6 +2961,11 @@ IsBinaryCoercible(Oid srctype, Oid targettype) if (type_is_range(srctype)) return true; + /* Also accept any multirange type as coercible to ANMULTIYRANGE */ + if (targettype == ANYMULTIRANGEOID || targettype == ANYCOMPATIBLEMULTIRANGEOID) + if (type_is_multirange(srctype)) + return true; + /* Also accept any composite type as coercible to RECORD */ if (targettype == RECORDOID) if (ISCOMPLEX(srctype)) @@ -2821,6 +3149,14 @@ find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, } } + /* + * When parsing PL/pgSQL assignments, allow an I/O cast to be used + * whenever no normal coercion is available. + */ + if (result == COERCION_PATH_NONE && + ccontext == COERCION_PLPGSQL) + result = COERCION_PATH_COERCEVIAIO; + return result; } @@ -2861,8 +3197,8 @@ find_typmod_coercion_function(Oid typeId, targetType = typeidType(typeId); typeForm = (Form_pg_type) GETSTRUCT(targetType); - /* Check for a varlena array type */ - if (typeForm->typelem != InvalidOid && typeForm->typlen == -1) + /* Check for a "true" array type */ + if (IsTrueArrayType(typeForm)) { /* Yes, switch our attention to the element type */ typeId = typeForm->typelem; diff --git a/src/backend/parser/parse_collate.c b/src/backend/parser/parse_collate.c index b7b4023d086e..010581789369 100644 --- a/src/backend/parser/parse_collate.c +++ b/src/backend/parser/parse_collate.c @@ -29,7 +29,7 @@ * at runtime. If we knew exactly which functions require collation * information, we could throw those errors at parse time instead. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -673,6 +673,29 @@ assign_collations_walker(Node *node, assign_collations_context *context) &loccontext); } break; + case T_SubscriptingRef: + { + /* + * The subscripts are treated as independent + * expressions not contributing to the node's + * collation. Only the container, and the source + * expression if any, contribute. (This models + * the old behavior, in which the subscripts could + * be counted on to be integers and thus not + * contribute anything.) + */ + SubscriptingRef *sbsref = (SubscriptingRef *) node; + + assign_expr_collations(context->pstate, + (Node *) sbsref->refupperindexpr); + assign_expr_collations(context->pstate, + (Node *) sbsref->reflowerindexpr); + (void) assign_collations_walker((Node *) sbsref->refexpr, + &loccontext); + (void) assign_collations_walker((Node *) sbsref->refassgnexpr, + &loccontext); + } + break; default: /* diff --git a/src/backend/parser/parse_cte.c b/src/backend/parser/parse_cte.c index e02bd2b06623..68cbbc8c1557 100644 --- a/src/backend/parser/parse_cte.c +++ b/src/backend/parser/parse_cte.c @@ -3,7 +3,7 @@ * parse_cte.c * handle CTEs (common table expressions) in parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,9 +19,13 @@ #include "cdb/cdbvars.h" #include "nodes/nodeFuncs.h" #include "parser/analyze.h" +#include "parser/parse_coerce.h" +#include "parser/parse_collate.h" #include "parser/parse_cte.h" +#include "parser/parse_expr.h" #include "utils/builtins.h" #include "utils/lsyscache.h" +#include "utils/typcache.h" /* Enumeration of contexts in which a self-reference is disallowed */ @@ -360,6 +364,195 @@ analyzeCTE(ParseState *pstate, CommonTableExpr *cte) if (lctyp != NULL || lctypmod != NULL || lccoll != NULL) /* shouldn't happen */ elog(ERROR, "wrong number of output columns in WITH"); } + + if (cte->search_clause || cte->cycle_clause) + { + Query *ctequery; + SetOperationStmt *sos; + + if (!cte->cterecursive) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("WITH query is not recursive"), + parser_errposition(pstate, cte->location))); + + /* + * SQL requires a WITH list element (CTE) to be "expandable" in order + * to allow a search or cycle clause. That is a stronger requirement + * than just being recursive. It basically means the query expression + * looks like + * + * non-recursive query UNION [ALL] recursive query + * + * and that the recursive query is not itself a set operation. + * + * As of this writing, most of these criteria are already satisfied by + * all recursive CTEs allowed by PostgreSQL. In the future, if + * further variants recursive CTEs are accepted, there might be + * further checks required here to determine what is "expandable". + */ + + ctequery = castNode(Query, cte->ctequery); + Assert(ctequery->setOperations); + sos = castNode(SetOperationStmt, ctequery->setOperations); + + /* + * This left side check is not required for expandability, but + * rewriteSearchAndCycle() doesn't currently have support for it, so + * we catch it here. + */ + if (!IsA(sos->larg, RangeTblRef)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("with a SEARCH or CYCLE clause, the left side of the UNION must be a SELECT"))); + + if (!IsA(sos->rarg, RangeTblRef)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("with a SEARCH or CYCLE clause, the right side of the UNION must be a SELECT"))); + } + + if (cte->search_clause) + { + ListCell *lc; + List *seen = NIL; + + foreach(lc, cte->search_clause->search_col_list) + { + Value *colname = lfirst(lc); + + if (!list_member(cte->ctecolnames, colname)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("search column \"%s\" not in WITH query column list", + strVal(colname)), + parser_errposition(pstate, cte->search_clause->location))); + + if (list_member(seen, colname)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_COLUMN), + errmsg("search column \"%s\" specified more than once", + strVal(colname)), + parser_errposition(pstate, cte->search_clause->location))); + seen = lappend(seen, colname); + } + + if (list_member(cte->ctecolnames, makeString(cte->search_clause->search_seq_column))) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("search sequence column name \"%s\" already used in WITH query column list", + cte->search_clause->search_seq_column), + parser_errposition(pstate, cte->search_clause->location)); + } + + if (cte->cycle_clause) + { + ListCell *lc; + List *seen = NIL; + TypeCacheEntry *typentry; + Oid op; + + foreach(lc, cte->cycle_clause->cycle_col_list) + { + Value *colname = lfirst(lc); + + if (!list_member(cte->ctecolnames, colname)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cycle column \"%s\" not in WITH query column list", + strVal(colname)), + parser_errposition(pstate, cte->cycle_clause->location))); + + if (list_member(seen, colname)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_COLUMN), + errmsg("cycle column \"%s\" specified more than once", + strVal(colname)), + parser_errposition(pstate, cte->cycle_clause->location))); + seen = lappend(seen, colname); + } + + if (list_member(cte->ctecolnames, makeString(cte->cycle_clause->cycle_mark_column))) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cycle mark column name \"%s\" already used in WITH query column list", + cte->cycle_clause->cycle_mark_column), + parser_errposition(pstate, cte->cycle_clause->location)); + + cte->cycle_clause->cycle_mark_value = transformExpr(pstate, cte->cycle_clause->cycle_mark_value, + EXPR_KIND_CYCLE_MARK); + cte->cycle_clause->cycle_mark_default = transformExpr(pstate, cte->cycle_clause->cycle_mark_default, + EXPR_KIND_CYCLE_MARK); + + if (list_member(cte->ctecolnames, makeString(cte->cycle_clause->cycle_path_column))) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cycle path column name \"%s\" already used in WITH query column list", + cte->cycle_clause->cycle_path_column), + parser_errposition(pstate, cte->cycle_clause->location)); + + if (strcmp(cte->cycle_clause->cycle_mark_column, + cte->cycle_clause->cycle_path_column) == 0) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cycle mark column name and cycle path column name are the same"), + parser_errposition(pstate, cte->cycle_clause->location)); + + cte->cycle_clause->cycle_mark_type = select_common_type(pstate, + list_make2(cte->cycle_clause->cycle_mark_value, + cte->cycle_clause->cycle_mark_default), + "CYCLE", NULL); + cte->cycle_clause->cycle_mark_value = coerce_to_common_type(pstate, + cte->cycle_clause->cycle_mark_value, + cte->cycle_clause->cycle_mark_type, + "CYCLE/SET/TO"); + cte->cycle_clause->cycle_mark_default = coerce_to_common_type(pstate, + cte->cycle_clause->cycle_mark_default, + cte->cycle_clause->cycle_mark_type, + "CYCLE/SET/DEFAULT"); + + cte->cycle_clause->cycle_mark_typmod = select_common_typmod(pstate, + list_make2(cte->cycle_clause->cycle_mark_value, + cte->cycle_clause->cycle_mark_default), + cte->cycle_clause->cycle_mark_type); + + cte->cycle_clause->cycle_mark_collation = select_common_collation(pstate, + list_make2(cte->cycle_clause->cycle_mark_value, + cte->cycle_clause->cycle_mark_default), + true); + + typentry = lookup_type_cache(cte->cycle_clause->cycle_mark_type, TYPECACHE_EQ_OPR); + if (!typentry->eq_opr) + ereport(ERROR, + errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not identify an equality operator for type %s", + format_type_be(cte->cycle_clause->cycle_mark_type))); + op = get_negator(typentry->eq_opr); + if (!op) + ereport(ERROR, + errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not identify an inequality operator for type %s", + format_type_be(cte->cycle_clause->cycle_mark_type))); + + cte->cycle_clause->cycle_mark_neop = op; + } + + if (cte->search_clause && cte->cycle_clause) + { + if (strcmp(cte->search_clause->search_seq_column, + cte->cycle_clause->cycle_mark_column) == 0) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("search sequence column name and cycle mark column name are the same"), + parser_errposition(pstate, cte->search_clause->location)); + + if (strcmp(cte->search_clause->search_seq_column, + cte->cycle_clause->cycle_path_column) == 0) + ereport(ERROR, + errcode(ERRCODE_SYNTAX_ERROR), + errmsg("search sequence column name and cycle path column name are the same"), + parser_errposition(pstate, cte->search_clause->location)); + } } /* @@ -563,15 +756,15 @@ makeDependencyGraphWalker(Node *node, CteState *cstate) * In the non-RECURSIVE case, query names are visible to the * WITH items after them and to the main query. */ - ListCell *cell1; - cstate->innerwiths = lcons(NIL, cstate->innerwiths); - cell1 = list_head(cstate->innerwiths); foreach(lc, stmt->withClause->ctes) { CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc); + ListCell *cell1; (void) makeDependencyGraphWalker(cte->ctequery, cstate); + /* note that recursion could mutate innerwiths list */ + cell1 = list_head(cstate->innerwiths); lfirst(cell1) = lappend((List *) lfirst(cell1), cte); } (void) raw_expression_tree_walker(node, @@ -839,15 +1032,15 @@ checkWellFormedRecursionWalker(Node *node, CteState *cstate) * In the non-RECURSIVE case, query names are visible to the * WITH items after them and to the main query. */ - ListCell *cell1; - cstate->innerwiths = lcons(NIL, cstate->innerwiths); - cell1 = list_head(cstate->innerwiths); foreach(lc, stmt->withClause->ctes) { CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc); + ListCell *cell1; (void) checkWellFormedRecursionWalker(cte->ctequery, cstate); + /* note that recursion could mutate innerwiths list */ + cell1 = list_head(cstate->innerwiths); lfirst(cell1) = lappend((List *) lfirst(cell1), cte); } checkWellFormedSelectStmt(stmt, cstate); diff --git a/src/backend/parser/parse_enr.c b/src/backend/parser/parse_enr.c index 625ded0707a8..8a4071a819a9 100644 --- a/src/backend/parser/parse_enr.c +++ b/src/backend/parser/parse_enr.c @@ -3,7 +3,7 @@ * parse_enr.c * parser support routines dealing with ephemeral named relations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 2403b09f8282..66b5f23c3b94 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -3,7 +3,7 @@ * parse_expr.c * handle expressions in parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -39,53 +39,8 @@ #include "utils/xml.h" /* GUC parameters */ -bool operator_precedence_warning = false; bool Transform_null_equals = false; -/* - * Node-type groups for operator precedence warnings - * We use zero for everything not otherwise classified - */ -#define PREC_GROUP_POSTFIX_IS 1 /* postfix IS tests (NullTest, etc) */ -#define PREC_GROUP_INFIX_IS 2 /* infix IS (IS DISTINCT FROM, etc) */ -#define PREC_GROUP_LESS 3 /* < > */ -#define PREC_GROUP_EQUAL 4 /* = */ -#define PREC_GROUP_LESS_EQUAL 5 /* <= >= <> */ -#define PREC_GROUP_LIKE 6 /* LIKE ILIKE SIMILAR */ -#define PREC_GROUP_BETWEEN 7 /* BETWEEN */ -#define PREC_GROUP_IN 8 /* IN */ -#define PREC_GROUP_NOT_LIKE 9 /* NOT LIKE/ILIKE/SIMILAR */ -#define PREC_GROUP_NOT_BETWEEN 10 /* NOT BETWEEN */ -#define PREC_GROUP_NOT_IN 11 /* NOT IN */ -#define PREC_GROUP_POSTFIX_OP 12 /* generic postfix operators */ -#define PREC_GROUP_INFIX_OP 13 /* generic infix operators */ -#define PREC_GROUP_PREFIX_OP 14 /* generic prefix operators */ - -/* - * Map precedence groupings to old precedence ordering - * - * Old precedence order: - * 1. NOT - * 2. = - * 3. < > - * 4. LIKE ILIKE SIMILAR - * 5. BETWEEN - * 6. IN - * 7. generic postfix Op - * 8. generic Op, including <= => <> - * 9. generic prefix Op - * 10. IS tests (NullTest, BooleanTest, etc) - * - * NOT BETWEEN etc map to BETWEEN etc when considered as being on the left, - * but to NOT when considered as being on the right, because of the buggy - * precedence handling of those productions in the old grammar. - */ -static const int oldprecedence_l[] = { - 0, 10, 10, 3, 2, 8, 4, 5, 6, 4, 5, 6, 7, 8, 9 -}; -static const int oldprecedence_r[] = { - 0, 10, 10, 3, 2, 8, 4, 5, 6, 1, 1, 1, 7, 8, 9 -}; static Node *transformExprRecurse(ParseState *pstate, Node *expr); static Node *transformParamRef(ParseState *pstate, ParamRef *pref); @@ -248,9 +203,6 @@ transformExprRecurse(ParseState *pstate, Node *expr) case AEXPR_NOT_BETWEEN_SYM: result = transformAExprBetween(pstate, a); break; - case AEXPR_PAREN: - result = transformExprRecurse(pstate, a->lexpr); - break; default: elog(ERROR, "unrecognized A_Expr kind: %d", a->kind); result = NULL; /* keep compiler quiet */ @@ -329,11 +281,6 @@ transformExprRecurse(ParseState *pstate, Node *expr) { NullTest *n = (NullTest *) expr; - if (operator_precedence_warning) - emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS", - (Node *) n->arg, NULL, - n->location); - n->arg = (Expr *) transformExprRecurse(pstate, (Node *) n->arg); /* the argument can be any type, so don't coerce it */ n->argisrow = type_is_rowtype(exprType((Node *) n->arg)); @@ -489,10 +436,9 @@ transformIndirection(ParseState *pstate, A_Indirection *ind) result = (Node *) transformContainerSubscripts(pstate, result, exprType(result), - InvalidOid, exprTypmod(result), subscripts, - NULL); + false); subscripts = NIL; newresult = ParseFuncOrColumn(pstate, @@ -512,10 +458,9 @@ transformIndirection(ParseState *pstate, A_Indirection *ind) result = (Node *) transformContainerSubscripts(pstate, result, exprType(result), - InvalidOid, exprTypmod(result), subscripts, - NULL); + false); return result; } @@ -585,6 +530,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref) case EXPR_KIND_FUNCTION_DEFAULT: case EXPR_KIND_INDEX_EXPRESSION: case EXPR_KIND_INDEX_PREDICATE: + case EXPR_KIND_STATS_EXPRESSION: case EXPR_KIND_ALTER_COL_TRANSFORM: case EXPR_KIND_EXECUTE_PARAMETER: case EXPR_KIND_TRIGGER_WHEN: @@ -593,6 +539,7 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref) case EXPR_KIND_COPY_WHERE: case EXPR_KIND_GENERATED_COLUMN: case EXPR_KIND_SCATTER_BY: + case EXPR_KIND_CYCLE_MARK: /* okay */ break; @@ -952,26 +899,6 @@ transformAExprOp(ParseState *pstate, A_Expr *a) Node *rexpr = a->rexpr; Node *result; - if (operator_precedence_warning) - { - int opgroup; - const char *opname; - - opgroup = operator_precedence_group((Node *) a, &opname); - if (opgroup > 0) - emit_precedence_warnings(pstate, opgroup, opname, - lexpr, rexpr, - a->location); - - /* Look through AEXPR_PAREN nodes so they don't affect tests below */ - while (lexpr && IsA(lexpr, A_Expr) && - ((A_Expr *) lexpr)->kind == AEXPR_PAREN) - lexpr = ((A_Expr *) lexpr)->lexpr; - while (rexpr && IsA(rexpr, A_Expr) && - ((A_Expr *) rexpr)->kind == AEXPR_PAREN) - rexpr = ((A_Expr *) rexpr)->lexpr; - } - /* * Special-case "foo = NULL" and "NULL = foo" for compatibility with * standards-broken products (like Microsoft's). Turn these into IS NULL @@ -1049,17 +976,8 @@ transformAExprOp(ParseState *pstate, A_Expr *a) static Node * transformAExprOpAny(ParseState *pstate, A_Expr *a) { - Node *lexpr = a->lexpr; - Node *rexpr = a->rexpr; - - if (operator_precedence_warning) - emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_OP, - strVal(llast(a->name)), - lexpr, NULL, - a->location); - - lexpr = transformExprRecurse(pstate, lexpr); - rexpr = transformExprRecurse(pstate, rexpr); + Node *lexpr = transformExprRecurse(pstate, a->lexpr); + Node *rexpr = transformExprRecurse(pstate, a->rexpr); return (Node *) make_scalar_array_op(pstate, a->name, @@ -1072,17 +990,8 @@ transformAExprOpAny(ParseState *pstate, A_Expr *a) static Node * transformAExprOpAll(ParseState *pstate, A_Expr *a) { - Node *lexpr = a->lexpr; - Node *rexpr = a->rexpr; - - if (operator_precedence_warning) - emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_OP, - strVal(llast(a->name)), - lexpr, NULL, - a->location); - - lexpr = transformExprRecurse(pstate, lexpr); - rexpr = transformExprRecurse(pstate, rexpr); + Node *lexpr = transformExprRecurse(pstate, a->lexpr); + Node *rexpr = transformExprRecurse(pstate, a->rexpr); return (Node *) make_scalar_array_op(pstate, a->name, @@ -1099,11 +1008,6 @@ transformAExprDistinct(ParseState *pstate, A_Expr *a) Node *rexpr = a->rexpr; Node *result; - if (operator_precedence_warning) - emit_precedence_warnings(pstate, PREC_GROUP_INFIX_IS, "IS", - lexpr, rexpr, - a->location); - /* * If either input is an undecorated NULL literal, transform to a NullTest * on the other input. That's simpler to process than a full DistinctExpr, @@ -1190,10 +1094,6 @@ transformAExprNullIf(ParseState *pstate, A_Expr *a) return (Node *) result; } -/* - * Checking an expression for match to a list of type names. Will result - * in a boolean constant node. - */ static Node * transformAExprOf(ParseState *pstate, A_Expr *a) { @@ -1204,11 +1104,6 @@ transformAExprOf(ParseState *pstate, A_Expr *a) rtype; bool matched = false; - if (operator_precedence_warning) - emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS", - lexpr, NULL, - a->location); - lexpr = transformExprRecurse(pstate, lexpr); ltype = exprType(lexpr); @@ -1254,13 +1149,6 @@ transformAExprIn(ParseState *pstate, A_Expr *a) else useOr = true; - if (operator_precedence_warning) - emit_precedence_warnings(pstate, - useOr ? PREC_GROUP_IN : PREC_GROUP_NOT_IN, - "IN", - a->lexpr, NULL, - a->location); - /* * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only * possible if there is a suitable array type available. If not, we fall @@ -1413,22 +1301,6 @@ transformAExprBetween(ParseState *pstate, A_Expr *a) bexpr = (Node *) linitial(args); cexpr = (Node *) lsecond(args); - if (operator_precedence_warning) - { - int opgroup; - const char *opname; - - opgroup = operator_precedence_group((Node *) a, &opname); - emit_precedence_warnings(pstate, opgroup, opname, - aexpr, cexpr, - a->location); - /* We can ignore bexpr thanks to syntactic restrictions */ - /* Wrap subexpressions to prevent extra warnings */ - aexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, aexpr, NULL, -1); - bexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, bexpr, NULL, -1); - cexpr = (Node *) makeA_Expr(AEXPR_PAREN, NIL, cexpr, NULL, -1); - } - /* * Build the equivalent comparison expression. Make copies of * multiply-referenced subexpressions for safety. (XXX this is really @@ -1744,11 +1616,12 @@ transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref) /* * If we're at the last column, delete the RowExpr from * p_multiassign_exprs; we don't need it anymore, and don't want it in - * the finished UPDATE tlist. + * the finished UPDATE tlist. We assume this is still the last entry + * in p_multiassign_exprs. */ if (maref->colno == maref->ncolumns) pstate->p_multiassign_exprs = - list_delete_ptr(pstate->p_multiassign_exprs, tle); + list_delete_last(pstate->p_multiassign_exprs); return result; } @@ -1967,6 +1840,7 @@ transformSubLink(ParseState *pstate, SubLink *sublink) case EXPR_KIND_RETURNING: case EXPR_KIND_VALUES: case EXPR_KIND_VALUES_SINGLE: + case EXPR_KIND_CYCLE_MARK: /* okay */ break; case EXPR_KIND_CHECK_CONSTRAINT: @@ -1983,6 +1857,9 @@ transformSubLink(ParseState *pstate, SubLink *sublink) case EXPR_KIND_INDEX_PREDICATE: err = _("cannot use subquery in index predicate"); break; + case EXPR_KIND_STATS_EXPRESSION: + err = _("cannot use subquery in statistics expression"); + break; case EXPR_KIND_ALTER_COL_TRANSFORM: err = _("cannot use subquery in transform expression"); break; @@ -2085,19 +1962,6 @@ transformSubLink(ParseState *pstate, SubLink *sublink) List *right_list; ListCell *l; - if (operator_precedence_warning) - { - if (sublink->operName == NIL) - emit_precedence_warnings(pstate, PREC_GROUP_IN, "IN", - sublink->testexpr, NULL, - sublink->location); - else - emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_OP, - strVal(llast(sublink->operName)), - sublink->testexpr, NULL, - sublink->location); - } - /* * If the source was "x IN (select)", convert to "x = ANY (select)". */ @@ -2197,11 +2061,6 @@ transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, Node *e = (Node *) lfirst(element); Node *newe; - /* Look through AEXPR_PAREN nodes so they don't affect test below */ - while (e && IsA(e, A_Expr) && - ((A_Expr *) e)->kind == AEXPR_PAREN) - e = ((A_Expr *) e)->lexpr; - /* * If an element is itself an A_ArrayExpr, recurse directly so that we * can pass down any target type we were given. @@ -2569,11 +2428,6 @@ transformXmlExpr(ParseState *pstate, XmlExpr *x) ListCell *lc; int i; - if (operator_precedence_warning && x->op == IS_DOCUMENT) - emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS", - (Node *) linitial(x->args), NULL, - x->location); - newx = makeNode(XmlExpr); newx->op = x->op; if (x->name) @@ -2744,11 +2598,6 @@ transformBooleanTest(ParseState *pstate, BooleanTest *b) { const char *clausename; - if (operator_precedence_warning) - emit_precedence_warnings(pstate, PREC_GROUP_POSTFIX_IS, "IS", - (Node *) b->arg, NULL, - b->location); - switch (b->booltesttype) { case IS_TRUE: @@ -2850,26 +2699,61 @@ static Node * transformWholeRowRef(ParseState *pstate, ParseNamespaceItem *nsitem, int sublevels_up, int location) { - Var *result; - /* - * Build the appropriate referencing node. Note that if the RTE is a - * function returning scalar, we create just a plain reference to the - * function value, not a composite containing a single column. This is - * pretty inconsistent at first sight, but it's what we've done - * historically. One argument for it is that "rel" and "rel.*" mean the - * same thing for composite relations, so why not for scalar functions... + * Build the appropriate referencing node. Normally this can be a + * whole-row Var, but if the nsitem is a JOIN USING alias then it contains + * only a subset of the columns of the underlying join RTE, so that will + * not work. Instead we immediately expand the reference into a RowExpr. + * Since the JOIN USING's common columns are fully determined at this + * point, there seems no harm in expanding it now rather than during + * planning. + * + * Note that if the RTE is a function returning scalar, we create just a + * plain reference to the function value, not a composite containing a + * single column. This is pretty inconsistent at first sight, but it's + * what we've done historically. One argument for it is that "rel" and + * "rel.*" mean the same thing for composite relations, so why not for + * scalar functions... */ - result = makeWholeRowVar(nsitem->p_rte, nsitem->p_rtindex, - sublevels_up, true); + if (nsitem->p_names == nsitem->p_rte->eref) + { + Var *result; - /* location is not filled in by makeWholeRowVar */ - result->location = location; + result = makeWholeRowVar(nsitem->p_rte, nsitem->p_rtindex, + sublevels_up, true); - /* mark relation as requiring whole-row SELECT access */ - markVarForSelectPriv(pstate, result, nsitem->p_rte); + /* location is not filled in by makeWholeRowVar */ + result->location = location; - return (Node *) result; + /* mark relation as requiring whole-row SELECT access */ + markVarForSelectPriv(pstate, result); + + return (Node *) result; + } + else + { + RowExpr *rowexpr; + List *fields; + + /* + * We want only as many columns as are listed in p_names->colnames, + * and we should use those names not whatever possibly-aliased names + * are in the RTE. We needn't worry about marking the RTE for SELECT + * access, as the common columns are surely so marked already. + */ + expandRTE(nsitem->p_rte, nsitem->p_rtindex, + sublevels_up, location, false, + NULL, &fields); + rowexpr = makeNode(RowExpr); + rowexpr->args = list_truncate(fields, + list_length(nsitem->p_names->colnames)); + rowexpr->row_typeid = RECORDOID; + rowexpr->row_format = COERCE_IMPLICIT_CAST; + rowexpr->colnames = copyObject(nsitem->p_names->colnames); + rowexpr->location = location; + + return (Node *) rowexpr; + } } /* @@ -2892,15 +2776,6 @@ transformTypeCast(ParseState *pstate, TypeCast *tc) /* Look up the type name first */ typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod); - /* - * Look through any AEXPR_PAREN nodes that may have been inserted thanks - * to operator_precedence_warning. Otherwise, ARRAY[]::foo[] behaves - * differently from (ARRAY[])::foo[]. - */ - while (arg && IsA(arg, A_Expr) && - ((A_Expr *) arg)->kind == AEXPR_PAREN) - arg = ((A_Expr *) arg)->lexpr; - /* * If the subject of the typecast is an ARRAY[] construct and the target * type is an array type, we invoke transformArrayExpr() directly so that @@ -3307,310 +3182,6 @@ make_nulltest_from_distinct(ParseState *pstate, A_Expr *distincta, Node *arg) return (Node *) nt; } -/* - * Identify node's group for operator precedence warnings - * - * For items in nonzero groups, also return a suitable node name into *nodename - * - * Note: group zero is used for nodes that are higher or lower precedence - * than everything that changed precedence; we need never issue warnings - * related to such nodes. - */ -static int -operator_precedence_group(Node *node, const char **nodename) -{ - int group = 0; - - *nodename = NULL; - if (node == NULL) - return 0; - - if (IsA(node, A_Expr)) - { - A_Expr *aexpr = (A_Expr *) node; - - if (aexpr->kind == AEXPR_OP && - aexpr->lexpr != NULL && - aexpr->rexpr != NULL) - { - /* binary operator */ - if (list_length(aexpr->name) == 1) - { - *nodename = strVal(linitial(aexpr->name)); - /* Ignore if op was always higher priority than IS-tests */ - if (strcmp(*nodename, "+") == 0 || - strcmp(*nodename, "-") == 0 || - strcmp(*nodename, "*") == 0 || - strcmp(*nodename, "/") == 0 || - strcmp(*nodename, "%") == 0 || - strcmp(*nodename, "^") == 0) - group = 0; - else if (strcmp(*nodename, "<") == 0 || - strcmp(*nodename, ">") == 0) - group = PREC_GROUP_LESS; - else if (strcmp(*nodename, "=") == 0) - group = PREC_GROUP_EQUAL; - else if (strcmp(*nodename, "<=") == 0 || - strcmp(*nodename, ">=") == 0 || - strcmp(*nodename, "<>") == 0) - group = PREC_GROUP_LESS_EQUAL; - else - group = PREC_GROUP_INFIX_OP; - } - else - { - /* schema-qualified operator syntax */ - *nodename = "OPERATOR()"; - group = PREC_GROUP_INFIX_OP; - } - } - else if (aexpr->kind == AEXPR_OP && - aexpr->lexpr == NULL && - aexpr->rexpr != NULL) - { - /* prefix operator */ - if (list_length(aexpr->name) == 1) - { - *nodename = strVal(linitial(aexpr->name)); - /* Ignore if op was always higher priority than IS-tests */ - if (strcmp(*nodename, "+") == 0 || - strcmp(*nodename, "-") == 0) - group = 0; - else - group = PREC_GROUP_PREFIX_OP; - } - else - { - /* schema-qualified operator syntax */ - *nodename = "OPERATOR()"; - group = PREC_GROUP_PREFIX_OP; - } - } - else if (aexpr->kind == AEXPR_OP && - aexpr->lexpr != NULL && - aexpr->rexpr == NULL) - { - /* postfix operator */ - if (list_length(aexpr->name) == 1) - { - *nodename = strVal(linitial(aexpr->name)); - group = PREC_GROUP_POSTFIX_OP; - } - else - { - /* schema-qualified operator syntax */ - *nodename = "OPERATOR()"; - group = PREC_GROUP_POSTFIX_OP; - } - } - else if (aexpr->kind == AEXPR_OP_ANY || - aexpr->kind == AEXPR_OP_ALL) - { - *nodename = strVal(llast(aexpr->name)); - group = PREC_GROUP_POSTFIX_OP; - } - else if (aexpr->kind == AEXPR_DISTINCT || - aexpr->kind == AEXPR_NOT_DISTINCT) - { - *nodename = "IS"; - group = PREC_GROUP_INFIX_IS; - } - else if (aexpr->kind == AEXPR_OF) - { - *nodename = "IS"; - group = PREC_GROUP_POSTFIX_IS; - } - else if (aexpr->kind == AEXPR_IN) - { - *nodename = "IN"; - if (strcmp(strVal(linitial(aexpr->name)), "=") == 0) - group = PREC_GROUP_IN; - else - group = PREC_GROUP_NOT_IN; - } - else if (aexpr->kind == AEXPR_LIKE) - { - *nodename = "LIKE"; - if (strcmp(strVal(linitial(aexpr->name)), "~~") == 0) - group = PREC_GROUP_LIKE; - else - group = PREC_GROUP_NOT_LIKE; - } - else if (aexpr->kind == AEXPR_ILIKE) - { - *nodename = "ILIKE"; - if (strcmp(strVal(linitial(aexpr->name)), "~~*") == 0) - group = PREC_GROUP_LIKE; - else - group = PREC_GROUP_NOT_LIKE; - } - else if (aexpr->kind == AEXPR_SIMILAR) - { - *nodename = "SIMILAR"; - if (strcmp(strVal(linitial(aexpr->name)), "~") == 0) - group = PREC_GROUP_LIKE; - else - group = PREC_GROUP_NOT_LIKE; - } - else if (aexpr->kind == AEXPR_BETWEEN || - aexpr->kind == AEXPR_BETWEEN_SYM) - { - Assert(list_length(aexpr->name) == 1); - *nodename = strVal(linitial(aexpr->name)); - group = PREC_GROUP_BETWEEN; - } - else if (aexpr->kind == AEXPR_NOT_BETWEEN || - aexpr->kind == AEXPR_NOT_BETWEEN_SYM) - { - Assert(list_length(aexpr->name) == 1); - *nodename = strVal(linitial(aexpr->name)); - group = PREC_GROUP_NOT_BETWEEN; - } - } - else if (IsA(node, NullTest) || - IsA(node, BooleanTest)) - { - *nodename = "IS"; - group = PREC_GROUP_POSTFIX_IS; - } - else if (IsA(node, XmlExpr)) - { - XmlExpr *x = (XmlExpr *) node; - - if (x->op == IS_DOCUMENT) - { - *nodename = "IS"; - group = PREC_GROUP_POSTFIX_IS; - } - } - else if (IsA(node, SubLink)) - { - SubLink *s = (SubLink *) node; - - if (s->subLinkType == ANY_SUBLINK || - s->subLinkType == ALL_SUBLINK) - { - if (s->operName == NIL) - { - *nodename = "IN"; - group = PREC_GROUP_IN; - } - else - { - *nodename = strVal(llast(s->operName)); - group = PREC_GROUP_POSTFIX_OP; - } - } - } - else if (IsA(node, BoolExpr)) - { - /* - * Must dig into NOTs to see if it's IS NOT DOCUMENT or NOT IN. This - * opens us to possibly misrecognizing, eg, NOT (x IS DOCUMENT) as a - * problematic construct. We can tell the difference by checking - * whether the parse locations of the two nodes are identical. - * - * Note that when we are comparing the child node to its own children, - * we will not know that it was a NOT. Fortunately, that doesn't - * matter for these cases. - */ - BoolExpr *b = (BoolExpr *) node; - - if (b->boolop == NOT_EXPR) - { - Node *child = (Node *) linitial(b->args); - - if (IsA(child, XmlExpr)) - { - XmlExpr *x = (XmlExpr *) child; - - if (x->op == IS_DOCUMENT && - x->location == b->location) - { - *nodename = "IS"; - group = PREC_GROUP_POSTFIX_IS; - } - } - else if (IsA(child, SubLink)) - { - SubLink *s = (SubLink *) child; - - if (s->subLinkType == ANY_SUBLINK && s->operName == NIL && - s->location == b->location) - { - *nodename = "IN"; - group = PREC_GROUP_NOT_IN; - } - } - } - } - return group; -} - -/* - * helper routine for delivering 9.4-to-9.5 operator precedence warnings - * - * opgroup/opname/location represent some parent node - * lchild, rchild are its left and right children (either could be NULL) - * - * This should be called before transforming the child nodes, since if a - * precedence-driven parsing change has occurred in a query that used to work, - * it's quite possible that we'll get a semantic failure while analyzing the - * child expression. We want to produce the warning before that happens. - * In any case, operator_precedence_group() expects untransformed input. - */ -static void -emit_precedence_warnings(ParseState *pstate, - int opgroup, const char *opname, - Node *lchild, Node *rchild, - int location) -{ - int cgroup; - const char *copname; - - Assert(opgroup > 0); - - /* - * Complain if left child, which should be same or higher precedence - * according to current rules, used to be lower precedence. - * - * Exception to precedence rules: if left child is IN or NOT IN or a - * postfix operator, the grouping is syntactically forced regardless of - * precedence. - */ - cgroup = operator_precedence_group(lchild, &copname); - if (cgroup > 0) - { - if (oldprecedence_l[cgroup] < oldprecedence_r[opgroup] && - cgroup != PREC_GROUP_IN && - cgroup != PREC_GROUP_NOT_IN && - cgroup != PREC_GROUP_POSTFIX_OP && - cgroup != PREC_GROUP_POSTFIX_IS) - ereport(WARNING, - (errmsg("operator precedence change: %s is now lower precedence than %s", - opname, copname), - parser_errposition(pstate, location))); - } - - /* - * Complain if right child, which should be higher precedence according to - * current rules, used to be same or lower precedence. - * - * Exception to precedence rules: if right child is a prefix operator, the - * grouping is syntactically forced regardless of precedence. - */ - cgroup = operator_precedence_group(rchild, &copname); - if (cgroup > 0) - { - if (oldprecedence_r[cgroup] <= oldprecedence_l[opgroup] && - cgroup != PREC_GROUP_PREFIX_OP) - ereport(WARNING, - (errmsg("operator precedence change: %s is now lower precedence than %s", - opname, copname), - parser_errposition(pstate, location))); - } -} - /* * Produce a string identifying an expression by kind. * @@ -3685,6 +3256,8 @@ ParseExprKindName(ParseExprKind exprKind) return "index expression"; case EXPR_KIND_INDEX_PREDICATE: return "index predicate"; + case EXPR_KIND_STATS_EXPRESSION: + return "statistics expression"; case EXPR_KIND_ALTER_COL_TRANSFORM: return "USING"; case EXPR_KIND_EXECUTE_PARAMETER: @@ -3703,6 +3276,8 @@ ParseExprKindName(ParseExprKind exprKind) return "GENERATED AS"; case EXPR_KIND_SCATTER_BY: return "SCATTER BY"; + case EXPR_KIND_CYCLE_MARK: + return "CYCLE"; /* * There is intentionally no default: case here, so that the diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 8efe093c691c..08cdaae0c5fc 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -3,7 +3,7 @@ * parse_func.c * handle function calls in parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -49,9 +49,10 @@ static void unify_hypothetical_args(ParseState *pstate, static Oid FuncNameAsType(List *funcname); static Node *ParseComplexProjection(ParseState *pstate, const char *funcname, Node *first_arg, int location); -static Oid LookupFuncNameInternal(List *funcname, int nargs, - const Oid *argtypes, - bool missing_ok, FuncLookupError *lookupError); +static Oid LookupFuncNameInternal(ObjectType objtype, List *funcname, + int nargs, const Oid *argtypes, + bool include_out_arguments, bool missing_ok, + FuncLookupError *lookupError); typedef struct { @@ -90,7 +91,8 @@ checkTableFunctions_walker(Node *node, check_table_func_context *context); * contain any SRF calls, last_srf can just be pstate->p_last_srf. * * proc_call is true if we are considering a CALL statement, so that the - * name must resolve to a procedure name, not anything else. + * name must resolve to a procedure name, not anything else. This flag + * also specifies that the argument list includes any OUT-mode arguments. */ Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, @@ -99,11 +101,12 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool is_column = (fn == NULL); List *agg_order = (fn ? fn->agg_order : NIL); Expr *agg_filter = NULL; + WindowDef *over = (fn ? fn->over : NULL); bool agg_within_group = (fn ? fn->agg_within_group : false); bool agg_star = (fn ? fn->agg_star : false); bool agg_distinct = (fn ? fn->agg_distinct : false); bool func_variadic = (fn ? fn->func_variadic : false); - WindowDef *over = (fn ? fn->over : NULL); + CoercionForm funcformat = (fn ? fn->funcformat : COERCE_EXPLICIT_CALL); bool could_be_projection; Oid rettype; Oid funcid; @@ -270,7 +273,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, fdresult = func_get_detail(funcname, fargs, argnames, nargs, actual_arg_types, - !func_variadic, true, + !func_variadic, true, proc_call, &funcid, &rettype, &retset, &nvargs, &vatype, &declared_arg_types, &argdefaults); @@ -423,9 +426,11 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, func_signature_string(funcname, nargs, argnames, actual_arg_types)), - errhint("There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.", - NameListToString(funcname), - catDirectArgs, numDirectArgs), + errhint_plural("There is an ordered-set aggregate %s, but it requires %d direct argument, not %d.", + "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.", + catDirectArgs, + NameListToString(funcname), + catDirectArgs, numDirectArgs), parser_errposition(pstate, location))); } else @@ -452,9 +457,11 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, func_signature_string(funcname, nargs, argnames, actual_arg_types)), - errhint("There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.", - NameListToString(funcname), - catDirectArgs, numDirectArgs), + errhint_plural("There is an ordered-set aggregate %s, but it requires %d direct argument, not %d.", + "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d.", + catDirectArgs, + NameListToString(funcname), + catDirectArgs, numDirectArgs), parser_errposition(pstate, location))); } else @@ -491,9 +498,11 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, func_signature_string(funcname, nargs, argnames, actual_arg_types)), - errhint("There is an ordered-set aggregate %s, but it requires at least %d direct arguments.", - NameListToString(funcname), - catDirectArgs), + errhint_plural("There is an ordered-set aggregate %s, but it requires at least %d direct argument.", + "There is an ordered-set aggregate %s, but it requires at least %d direct arguments.", + catDirectArgs, + NameListToString(funcname), + catDirectArgs), parser_errposition(pstate, location))); } } @@ -750,7 +759,7 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, funcexpr->funcresulttype = rettype; funcexpr->funcretset = retset; funcexpr->funcvariadic = func_variadic; - funcexpr->funcformat = COERCE_EXPLICIT_CALL; + funcexpr->funcformat = funcformat; /* funccollid and inputcollid will be set by parse_collate.c */ funcexpr->args = fargs; funcexpr->location = location; @@ -775,6 +784,8 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, aggref->aggkind = aggkind; /* agglevelsup will be set by transformAggregateCall */ aggref->aggsplit = AGGSPLIT_SIMPLE; /* planner might change this */ + aggref->aggno = -1; /* planner will set aggno and aggtransno */ + aggref->aggtransno = -1; aggref->location = location; /* @@ -1440,6 +1451,7 @@ func_get_detail(List *funcname, Oid *argtypes, bool expand_variadic, bool expand_defaults, + bool include_out_arguments, Oid *funcid, /* return value */ Oid *rettype, /* return value */ bool *retset, /* return value */ @@ -1464,7 +1476,7 @@ func_get_detail(List *funcname, /* Get list of possible candidates from namespace search */ raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames, expand_variadic, expand_defaults, - false); + include_out_arguments, false); /* * Quickly check if there is an exact match to the input datatypes (there @@ -1712,7 +1724,7 @@ func_get_detail(List *funcname, defargnumbers = bms_add_member(defargnumbers, firstdefarg[i]); newdefaults = NIL; - i = pform->pronargs - pform->pronargdefaults; + i = best_candidate->nominalnargs - pform->pronargdefaults; foreach(lc, defaults) { if (bms_is_member(i, defargnumbers)) @@ -1804,6 +1816,7 @@ unify_hypothetical_args(ParseState *pstate, ListCell *harg = list_nth_cell(fargs, hargpos); ListCell *aarg = list_nth_cell(fargs, aargpos); Oid commontype; + int32 commontypmod; /* A mismatch means AggregateCreate didn't check properly ... */ if (declared_arg_types[hargpos] != declared_arg_types[aargpos]) @@ -1822,6 +1835,9 @@ unify_hypothetical_args(ParseState *pstate, list_make2(lfirst(aarg), lfirst(harg)), "WITHIN GROUP", NULL); + commontypmod = select_common_typmod(pstate, + list_make2(lfirst(aarg), lfirst(harg)), + commontype); /* * Perform the coercions. We don't need to worry about NamedArgExprs @@ -1830,7 +1846,7 @@ unify_hypothetical_args(ParseState *pstate, lfirst(harg) = coerce_type(pstate, (Node *) lfirst(harg), actual_arg_types[hargpos], - commontype, -1, + commontype, commontypmod, COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1); @@ -1838,7 +1854,7 @@ unify_hypothetical_args(ParseState *pstate, lfirst(aarg) = coerce_type(pstate, (Node *) lfirst(aarg), actual_arg_types[aargpos], - commontype, -1, + commontype, commontypmod, COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1); @@ -2082,12 +2098,15 @@ func_signature_string(List *funcname, int nargs, * * Possible errors: * FUNCLOOKUP_NOSUCHFUNC: we can't find a function of this name. - * FUNCLOOKUP_AMBIGUOUS: nargs == -1 and more than one function matches. + * FUNCLOOKUP_AMBIGUOUS: more than one function matches. */ static Oid -LookupFuncNameInternal(List *funcname, int nargs, const Oid *argtypes, - bool missing_ok, FuncLookupError *lookupError) +LookupFuncNameInternal(ObjectType objtype, List *funcname, + int nargs, const Oid *argtypes, + bool include_out_arguments, bool missing_ok, + FuncLookupError *lookupError) { + Oid result = InvalidOid; FuncCandidateList clist; /* NULL argtypes allowed for nullary functions only */ @@ -2096,43 +2115,62 @@ LookupFuncNameInternal(List *funcname, int nargs, const Oid *argtypes, /* Always set *lookupError, to forestall uninitialized-variable warnings */ *lookupError = FUNCLOOKUP_NOSUCHFUNC; + /* Get list of candidate objects */ clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, - missing_ok); + include_out_arguments, missing_ok); - /* - * If no arguments were specified, the name must yield a unique candidate. - */ - if (nargs < 0) + /* Scan list for a match to the arg types (if specified) and the objtype */ + for (; clist != NULL; clist = clist->next) { - if (clist) + /* Check arg type match, if specified */ + if (nargs >= 0) { - /* If there is a second match then it's ambiguous */ - if (clist->next) - { - *lookupError = FUNCLOOKUP_AMBIGUOUS; - return InvalidOid; - } - /* Otherwise return the match */ - return clist->oid; + /* if nargs==0, argtypes can be null; don't pass that to memcmp */ + if (nargs > 0 && + memcmp(argtypes, clist->args, nargs * sizeof(Oid)) != 0) + continue; } - else + + /* Check for duplicates reported by FuncnameGetCandidates */ + if (!OidIsValid(clist->oid)) + { + *lookupError = FUNCLOOKUP_AMBIGUOUS; return InvalidOid; - } + } - /* - * Otherwise, look for a match to the arg types. FuncnameGetCandidates - * has ensured that there's at most one match in the returned list. - */ - while (clist) - { - /* if nargs==0, argtypes can be null; don't pass that to memcmp */ - if (nargs == 0 || - memcmp(argtypes, clist->args, nargs * sizeof(Oid)) == 0) - return clist->oid; - clist = clist->next; + /* Check objtype match, if specified */ + switch (objtype) + { + case OBJECT_FUNCTION: + case OBJECT_AGGREGATE: + /* Ignore procedures */ + if (get_func_prokind(clist->oid) == PROKIND_PROCEDURE) + continue; + break; + case OBJECT_PROCEDURE: + /* Ignore non-procedures */ + if (get_func_prokind(clist->oid) != PROKIND_PROCEDURE) + continue; + break; + case OBJECT_ROUTINE: + /* no restriction */ + break; + default: + Assert(false); + } + + /* Check for multiple matches */ + if (OidIsValid(result)) + { + *lookupError = FUNCLOOKUP_AMBIGUOUS; + return InvalidOid; + } + + /* OK, we have a candidate */ + result = clist->oid; } - return InvalidOid; + return result; } /* @@ -2152,6 +2190,10 @@ LookupFuncNameInternal(List *funcname, int nargs, const Oid *argtypes, * If nargs == -1 and multiple functions are found matching this function name * we will raise an ambiguous-function error, regardless of what missing_ok is * set to. + * + * Only functions will be found; procedures will be ignored even if they + * match the name and argument types. (However, we don't trouble to reject + * aggregates or window functions here.) */ Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok) @@ -2159,7 +2201,9 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok) Oid funcoid; FuncLookupError lookupError; - funcoid = LookupFuncNameInternal(funcname, nargs, argtypes, missing_ok, + funcoid = LookupFuncNameInternal(OBJECT_FUNCTION, + funcname, nargs, argtypes, + false, missing_ok, &lookupError); if (OidIsValid(funcoid)) @@ -2248,10 +2292,14 @@ LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok) FUNC_MAX_ARGS))); } + /* + * First, perform a lookup considering only input arguments (traditional + * Postgres rules). + */ i = 0; foreach(args_item, func->objargs) { - TypeName *t = (TypeName *) lfirst(args_item); + TypeName *t = lfirst_node(TypeName, args_item); argoids[i] = LookupTypeNameOid(NULL, t, missing_ok); if (!OidIsValid(argoids[i])) @@ -2265,9 +2313,83 @@ LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok) */ nargs = func->args_unspecified ? -1 : argcount; - oid = LookupFuncNameInternal(func->objname, nargs, argoids, missing_ok, + /* + * In args_unspecified mode, also tell LookupFuncNameInternal to consider + * the object type, since there seems no reason not to. However, if we + * have an argument list, disable the objtype check, because we'd rather + * complain about "object is of wrong type" than "object doesn't exist". + * (Note that with args, FuncnameGetCandidates will have ensured there's + * only one argtype match, so we're not risking an ambiguity failure via + * this choice.) + */ + oid = LookupFuncNameInternal(func->args_unspecified ? objtype : OBJECT_ROUTINE, + func->objname, nargs, argoids, + false, missing_ok, &lookupError); + /* + * If PROCEDURE or ROUTINE was specified, and we have an argument list + * that contains no parameter mode markers, and we didn't already discover + * that there's ambiguity, perform a lookup considering all arguments. + * (Note: for a zero-argument procedure, or in args_unspecified mode, the + * normal lookup is sufficient; so it's OK to require non-NIL objfuncargs + * to perform this lookup.) + */ + if ((objtype == OBJECT_PROCEDURE || objtype == OBJECT_ROUTINE) && + func->objfuncargs != NIL && + lookupError != FUNCLOOKUP_AMBIGUOUS) + { + bool have_param_mode = false; + + /* + * Check for non-default parameter mode markers. If there are any, + * then the command does not conform to SQL-spec syntax, so we may + * assume that the traditional Postgres lookup method of considering + * only input parameters is sufficient. (Note that because the spec + * doesn't have OUT arguments for functions, we also don't need this + * hack in FUNCTION or AGGREGATE mode.) + */ + foreach(args_item, func->objfuncargs) + { + FunctionParameter *fp = lfirst_node(FunctionParameter, args_item); + + if (fp->mode != FUNC_PARAM_DEFAULT) + { + have_param_mode = true; + break; + } + } + + if (!have_param_mode) + { + Oid poid; + + /* Without mode marks, objargs surely includes all params */ + Assert(list_length(func->objfuncargs) == argcount); + + /* For objtype == OBJECT_PROCEDURE, we can ignore non-procedures */ + poid = LookupFuncNameInternal(objtype, func->objname, + argcount, argoids, + true, missing_ok, + &lookupError); + + /* Combine results, handling ambiguity */ + if (OidIsValid(poid)) + { + if (OidIsValid(oid) && oid != poid) + { + /* oops, we got hits both ways, on different objects */ + oid = InvalidOid; + lookupError = FUNCLOOKUP_AMBIGUOUS; + } + else + oid = poid; + } + else if (lookupError == FUNCLOOKUP_AMBIGUOUS) + oid = InvalidOid; + } + } + if (OidIsValid(oid)) { /* @@ -2276,6 +2398,10 @@ LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok) * we allow the objtype of FUNCTION to include aggregates and window * functions; but we draw the line if the object is a procedure. That * is a new enough feature that this historical rule does not apply. + * + * (This check is partially redundant with the objtype check in + * LookupFuncNameInternal; but not entirely, since we often don't tell + * LookupFuncNameInternal to apply that check at all.) */ switch (objtype) { @@ -2386,28 +2512,32 @@ LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok) (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("function name \"%s\" is not unique", NameListToString(func->objname)), - errhint("Specify the argument list to select the function unambiguously."))); + func->args_unspecified ? + errhint("Specify the argument list to select the function unambiguously.") : 0)); break; case OBJECT_PROCEDURE: ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("procedure name \"%s\" is not unique", NameListToString(func->objname)), - errhint("Specify the argument list to select the procedure unambiguously."))); + func->args_unspecified ? + errhint("Specify the argument list to select the procedure unambiguously.") : 0)); break; case OBJECT_AGGREGATE: ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("aggregate name \"%s\" is not unique", NameListToString(func->objname)), - errhint("Specify the argument list to select the aggregate unambiguously."))); + func->args_unspecified ? + errhint("Specify the argument list to select the aggregate unambiguously.") : 0)); break; case OBJECT_ROUTINE: ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("routine name \"%s\" is not unique", NameListToString(func->objname)), - errhint("Specify the argument list to select the routine unambiguously."))); + func->args_unspecified ? + errhint("Specify the argument list to select the routine unambiguously.") : 0)); break; default: @@ -2549,6 +2679,9 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location) case EXPR_KIND_INDEX_PREDICATE: err = _("set-returning functions are not allowed in index predicates"); break; + case EXPR_KIND_STATS_EXPRESSION: + err = _("set-returning functions are not allowed in statistics expressions"); + break; case EXPR_KIND_ALTER_COL_TRANSFORM: err = _("set-returning functions are not allowed in transform expressions"); break; @@ -2573,6 +2706,9 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location) case EXPR_KIND_GENERATED_COLUMN: err = _("set-returning functions are not allowed in column generation expressions"); break; + case EXPR_KIND_CYCLE_MARK: + errkind = true; + break; case EXPR_KIND_SCATTER_BY: err = _("set-returning functions are not allowed in scatter by expressions"); diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index 8a8e30eb1ce9..6a7d31a18dab 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -3,7 +3,7 @@ * parse_node.c * various routines that make nodes for querytrees * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,6 +20,7 @@ #include "mb/pg_wchar.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "nodes/subscripting.h" #include "parser/parse_coerce.h" #include "parser/parse_expr.h" #include "parser/parse_relation.h" @@ -182,23 +183,16 @@ pcb_error_callback(void *arg) /* * transformContainerType() - * Identify the types involved in a subscripting operation for container + * Identify the actual container type for a subscripting operation. * - * - * On entry, containerType/containerTypmod identify the type of the input value - * to be subscripted (which could be a domain type). These are modified if - * necessary to identify the actual container type and typmod, and the - * container's element type is returned. An error is thrown if the input isn't - * an array type. + * containerType/containerTypmod are modified if necessary to identify + * the actual container type and typmod. This mainly involves smashing + * any domain to its base type, but there are some special considerations. + * Note that caller still needs to check if the result type is a container. */ -Oid +void transformContainerType(Oid *containerType, int32 *containerTypmod) { - Oid origContainerType = *containerType; - Oid elementType; - HeapTuple type_tuple_container; - Form_pg_type type_struct_container; - /* * If the input is a domain, smash to base type, and extract the actual * typmod to be applied to the base type. Subscripting a domain is an @@ -209,35 +203,16 @@ transformContainerType(Oid *containerType, int32 *containerTypmod) *containerType = getBaseTypeAndTypmod(*containerType, containerTypmod); /* - * Here is an array specific code. We treat int2vector and oidvector as - * though they were domains over int2[] and oid[]. This is needed because - * array slicing could create an array that doesn't satisfy the - * dimensionality constraints of the xxxvector type; so we want the result - * of a slice operation to be considered to be of the more general type. + * We treat int2vector and oidvector as though they were domains over + * int2[] and oid[]. This is needed because array slicing could create an + * array that doesn't satisfy the dimensionality constraints of the + * xxxvector type; so we want the result of a slice operation to be + * considered to be of the more general type. */ if (*containerType == INT2VECTOROID) *containerType = INT2ARRAYOID; else if (*containerType == OIDVECTOROID) *containerType = OIDARRAYOID; - - /* Get the type tuple for the container */ - type_tuple_container = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*containerType)); - if (!HeapTupleIsValid(type_tuple_container)) - elog(ERROR, "cache lookup failed for type %u", *containerType); - type_struct_container = (Form_pg_type) GETSTRUCT(type_tuple_container); - - /* needn't check typisdefined since this will fail anyway */ - - elementType = type_struct_container->typelem; - if (elementType == InvalidOid) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("cannot subscript type %s because it is not an array", - format_type_be(origContainerType)))); - - ReleaseSysCache(type_tuple_container); - - return elementType; } /* @@ -249,13 +224,14 @@ transformContainerType(Oid *containerType, int32 *containerTypmod) * an expression that represents the result of extracting a single container * element or a container slice. * - * In a container assignment, we are given a destination container value plus a - * source value that is to be assigned to a single element or a slice of that - * container. We produce an expression that represents the new container value - * with the source data inserted into the right part of the container. + * Container assignments are treated basically the same as container fetches + * here. The caller will modify the result node to insert the source value + * that is to be assigned to the element or slice that a fetch would have + * retrieved. The execution result will be a new container value with + * the source value inserted into the right part of the container. * - * For both cases, if the source container is of a domain-over-array type, - * the result is of the base array type or its element type; essentially, + * For both cases, if the source is of a domain-over-container type, the + * result is the same as if it had been of the container type; essentially, * we must fold a domain to its base type before applying subscripting. * (Note that int2vector and oidvector are treated as domains here.) * @@ -264,48 +240,54 @@ transformContainerType(Oid *containerType, int32 *containerTypmod) * containerType OID of container's datatype (should match type of * containerBase, or be the base type of containerBase's * domain type) - * elementType OID of container's element type (fetch with - * transformContainerType, or pass InvalidOid to do it here) - * containerTypMod typmod for the container (which is also typmod for the - * elements) + * containerTypMod typmod for the container * indirection Untransformed list of subscripts (must not be NIL) - * assignFrom NULL for container fetch, else transformed expression for - * source. + * isAssignment True if this will become a container assignment. */ SubscriptingRef * transformContainerSubscripts(ParseState *pstate, Node *containerBase, Oid containerType, - Oid elementType, int32 containerTypMod, List *indirection, - Node *assignFrom) + bool isAssignment) { + SubscriptingRef *sbsref; + const SubscriptRoutines *sbsroutines; + Oid elementType; bool isSlice = false; - List *upperIndexpr = NIL; - List *lowerIndexpr = NIL; ListCell *idx; - SubscriptingRef *sbsref; /* - * Caller may or may not have bothered to determine elementType. Note - * that if the caller did do so, containerType/containerTypMod must be as - * modified by transformContainerType, ie, smash domain to base type. + * Determine the actual container type, smashing any domain. In the + * assignment case the caller already did this, since it also needs to + * know the actual container type. */ - if (!OidIsValid(elementType)) - elementType = transformContainerType(&containerType, &containerTypMod); + if (!isAssignment) + transformContainerType(&containerType, &containerTypMod); /* + * Verify that the container type is subscriptable, and get its support + * functions and typelem. + */ + sbsroutines = getSubscriptingRoutines(containerType, &elementType); + if (!sbsroutines) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cannot subscript type %s because it does not support subscripting", + format_type_be(containerType)), + parser_errposition(pstate, exprLocation(containerBase)))); + + /* + * Detect whether any of the indirection items are slice specifiers. + * * A list containing only simple subscripts refers to a single container * element. If any of the items are slice specifiers (lower:upper), then - * the subscript expression means a container slice operation. In this - * case, we convert any non-slice items to slices by treating the single - * subscript as the upper bound and supplying an assumed lower bound of 1. - * We have to prescan the list to see if there are any slice items. + * the subscript expression means a container slice operation. */ foreach(idx, indirection) { - A_Indices *ai = (A_Indices *) lfirst(idx); + A_Indices *ai = lfirst_node(A_Indices, idx); if (ai->is_slice) { @@ -314,121 +296,36 @@ transformContainerSubscripts(ParseState *pstate, } } - /* - * Transform the subscript expressions. - */ - foreach(idx, indirection) - { - A_Indices *ai = lfirst_node(A_Indices, idx); - Node *subexpr; - - if (isSlice) - { - if (ai->lidx) - { - subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind); - /* If it's not int4 already, try to coerce */ - subexpr = coerce_to_target_type(pstate, - subexpr, exprType(subexpr), - INT4OID, -1, - COERCION_ASSIGNMENT, - COERCE_IMPLICIT_CAST, - -1); - if (subexpr == NULL) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("array subscript must have type integer"), - parser_errposition(pstate, exprLocation(ai->lidx)))); - } - else if (!ai->is_slice) - { - /* Make a constant 1 */ - subexpr = (Node *) makeConst(INT4OID, - -1, - InvalidOid, - sizeof(int32), - Int32GetDatum(1), - false, - true); /* pass by value */ - } - else - { - /* Slice with omitted lower bound, put NULL into the list */ - subexpr = NULL; - } - lowerIndexpr = lappend(lowerIndexpr, subexpr); - } - else - Assert(ai->lidx == NULL && !ai->is_slice); - - if (ai->uidx) - { - subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind); - /* If it's not int4 already, try to coerce */ - subexpr = coerce_to_target_type(pstate, - subexpr, exprType(subexpr), - INT4OID, -1, - COERCION_ASSIGNMENT, - COERCE_IMPLICIT_CAST, - -1); - if (subexpr == NULL) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("array subscript must have type integer"), - parser_errposition(pstate, exprLocation(ai->uidx)))); - } - else - { - /* Slice with omitted upper bound, put NULL into the list */ - Assert(isSlice && ai->is_slice); - subexpr = NULL; - } - upperIndexpr = lappend(upperIndexpr, subexpr); - } - - /* - * If doing an array store, coerce the source value to the right type. - * (This should agree with the coercion done by transformAssignedExpr.) - */ - if (assignFrom != NULL) - { - Oid typesource = exprType(assignFrom); - Oid typeneeded = isSlice ? containerType : elementType; - Node *newFrom; - - newFrom = coerce_to_target_type(pstate, - assignFrom, typesource, - typeneeded, containerTypMod, - COERCION_ASSIGNMENT, - COERCE_IMPLICIT_CAST, - -1); - if (newFrom == NULL) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("array assignment requires type %s" - " but expression is of type %s", - format_type_be(typeneeded), - format_type_be(typesource)), - errhint("You will need to rewrite or cast the expression."), - parser_errposition(pstate, exprLocation(assignFrom)))); - assignFrom = newFrom; - } - /* * Ready to build the SubscriptingRef node. */ - sbsref = (SubscriptingRef *) makeNode(SubscriptingRef); - if (assignFrom != NULL) - sbsref->refassgnexpr = (Expr *) assignFrom; + sbsref = makeNode(SubscriptingRef); sbsref->refcontainertype = containerType; sbsref->refelemtype = elementType; + /* refrestype is to be set by container-specific logic */ sbsref->reftypmod = containerTypMod; /* refcollid will be set by parse_collate.c */ - sbsref->refupperindexpr = upperIndexpr; - sbsref->reflowerindexpr = lowerIndexpr; + /* refupperindexpr, reflowerindexpr are to be set by container logic */ sbsref->refexpr = (Expr *) containerBase; - sbsref->refassgnexpr = (Expr *) assignFrom; + sbsref->refassgnexpr = NULL; /* caller will fill if it's an assignment */ + + /* + * Call the container-type-specific logic to transform the subscripts and + * determine the subscripting result type. + */ + sbsroutines->transform(sbsref, indirection, pstate, + isSlice, isAssignment); + + /* + * Verify we got a valid type (this defends, for example, against someone + * using array_subscript_handler as typsubscript without setting typelem). + */ + if (!OidIsValid(sbsref->refrestype)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("cannot subscript type %s because it does not support subscripting", + format_type_be(containerType)))); return sbsref; } diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index 2749974f6384..4e4607999036 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -3,7 +3,7 @@ * parse_oper.c * handle operator things for parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -52,7 +52,7 @@ typedef struct OprCacheKey { char oprname[NAMEDATALEN]; Oid left_arg; /* Left input OID, or 0 if prefix op */ - Oid right_arg; /* Right input OID, or 0 if postfix op */ + Oid right_arg; /* Right input OID */ Oid search_path[MAX_CACHED_PATH_LEN]; } OprCacheKey; @@ -88,8 +88,7 @@ static void InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue) * Given a possibly-qualified operator name and exact input datatypes, * look up the operator. * - * Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for - * a postfix op. + * Pass oprleft = InvalidOid for a prefix op. * * If the operator name is not schema-qualified, it is sought in the current * namespace search path. @@ -115,10 +114,16 @@ LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright, if (!OidIsValid(oprleft)) oprkind = 'l'; - else if (!OidIsValid(oprright)) - oprkind = 'r'; - else + else if (OidIsValid(oprright)) oprkind = 'b'; + else + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("postfix operators are not supported"), + parser_errposition(pstate, location))); + oprkind = 0; /* keep compiler quiet */ + } ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), @@ -145,8 +150,8 @@ LookupOperWithArgs(ObjectWithArgs *oper, bool noError) rightoid; Assert(list_length(oper->objargs) == 2); - oprleft = linitial(oper->objargs); - oprright = lsecond(oper->objargs); + oprleft = linitial_node(TypeName, oper->objargs); + oprright = lsecond_node(TypeName, oper->objargs); if (oprleft == NULL) leftoid = InvalidOid; @@ -507,85 +512,6 @@ compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError) } -/* right_oper() -- search for a unary right operator (postfix operator) - * Given operator name and type of arg, return oper struct. - * - * IMPORTANT: the returned operator (if any) is only promised to be - * coercion-compatible with the input datatype. Do not use this if - * you need an exact- or binary-compatible match. - * - * If no matching operator found, return NULL if noError is true, - * raise an error if it is false. pstate and location are used only to report - * the error position; pass NULL/-1 if not available. - * - * NOTE: on success, the returned object is a syscache entry. The caller - * must ReleaseSysCache() the entry when done with it. - */ -Operator -right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location) -{ - Oid operOid; - OprCacheKey key; - bool key_ok; - FuncDetailCode fdresult = FUNCDETAIL_NOTFOUND; - HeapTuple tup = NULL; - - /* - * Try to find the mapping in the lookaside cache. - */ - key_ok = make_oper_cache_key(pstate, &key, op, arg, InvalidOid, location); - - if (key_ok) - { - operOid = find_oper_cache_entry(&key); - if (OidIsValid(operOid)) - { - tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid)); - if (HeapTupleIsValid(tup)) - return (Operator) tup; - } - } - - /* - * First try for an "exact" match. - */ - operOid = OpernameGetOprid(op, arg, InvalidOid); - if (!OidIsValid(operOid)) - { - /* - * Otherwise, search for the most suitable candidate. - */ - FuncCandidateList clist; - - /* Get postfix operators of given name */ - clist = OpernameGetCandidates(op, 'r', false); - - /* No operators found? Then fail... */ - if (clist != NULL) - { - /* - * We must run oper_select_candidate even if only one candidate, - * otherwise we may falsely return a non-type-compatible operator. - */ - fdresult = oper_select_candidate(1, &arg, clist, &operOid); - } - } - - if (OidIsValid(operOid)) - tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid)); - - if (HeapTupleIsValid(tup)) - { - if (key_ok) - make_oper_cache_entry(&key, operOid); - } - else if (!noError) - op_error(pstate, op, 'r', arg, InvalidOid, fdresult, location); - - return (Operator) tup; -} - - /* left_oper() -- search for a unary left operator (prefix operator) * Given operator name and type of arg, return oper struct. * @@ -696,8 +622,7 @@ op_signature_string(List *op, char oprkind, Oid arg1, Oid arg2) appendStringInfoString(&argbuf, NameListToString(op)); - if (oprkind != 'r') - appendStringInfo(&argbuf, " %s", format_type_be(arg2)); + appendStringInfo(&argbuf, " %s", format_type_be(arg2)); return argbuf.data; /* return palloc'd string buffer */ } @@ -758,17 +683,16 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, Oid rettype; OpExpr *result; - /* Select the operator */ + /* Check it's not a postfix operator */ if (rtree == NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("postfix operators are not supported"))); + + /* Select the operator */ + if (ltree == NULL) { - /* right operator */ - ltypeId = exprType(ltree); - rtypeId = InvalidOid; - tup = right_oper(pstate, opname, ltypeId, false, location); - } - else if (ltree == NULL) - { - /* left operator */ + /* prefix operator */ rtypeId = exprType(rtree); ltypeId = InvalidOid; tup = left_oper(pstate, opname, rtypeId, false, location); @@ -795,17 +719,9 @@ make_op(ParseState *pstate, List *opname, Node *ltree, Node *rtree, parser_errposition(pstate, location))); /* Do typecasting and build the expression tree */ - if (rtree == NULL) - { - /* right operator */ - args = list_make1(ltree); - actual_arg_types[0] = ltypeId; - declared_arg_types[0] = opform->oprleft; - nargs = 1; - } - else if (ltree == NULL) + if (ltree == NULL) { - /* left operator */ + /* prefix operator */ args = list_make1(rtree); actual_arg_types[0] = rtypeId; declared_arg_types[0] = opform->oprright; @@ -978,6 +894,7 @@ make_scalar_array_op(ParseState *pstate, List *opname, result = makeNode(ScalarArrayOpExpr); result->opno = oprid(tup); result->opfuncid = opform->oprcode; + result->hashfuncid = InvalidOid; result->useOr = useOr; /* inputcollid will be set by parse_collate.c */ result->args = args; @@ -1083,7 +1000,6 @@ find_oper_cache_entry(OprCacheKey *key) /* First time through: initialize the hash table */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(OprCacheKey); ctl.entrysize = sizeof(OprCacheEntry); OprCacheHash = hash_create("Operator lookup cache", 256, diff --git a/src/backend/parser/parse_param.c b/src/backend/parser/parse_param.c index 17a96abfa8c3..68a553439396 100644 --- a/src/backend/parser/parse_param.c +++ b/src/backend/parser/parse_param.c @@ -12,7 +12,7 @@ * Note that other approaches to parameters are possible using the parser * hooks defined in ParseState. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -163,6 +163,15 @@ variable_paramref_hook(ParseState *pstate, ParamRef *pref) if (*pptype == InvalidOid) *pptype = UNKNOWNOID; + /* + * If the argument is of type void and it's procedure call, interpret it + * as unknown. This allows the JDBC driver to not have to distinguish + * function and procedure calls. See also another component of this hack + * in ParseFuncOrColumn(). + */ + if (*pptype == VOIDOID && pstate->p_expr_kind == EXPR_KIND_CALL_ARGUMENT) + *pptype = UNKNOWNOID; + param = makeNode(Param); param->paramkind = PARAM_EXTERN; param->paramid = paramno; diff --git a/src/backend/parser/parse_partition_gp.c b/src/backend/parser/parse_partition_gp.c index 781d693b41ae..939aa244f5ba 100644 --- a/src/backend/parser/parse_partition_gp.c +++ b/src/backend/parser/parse_partition_gp.c @@ -355,7 +355,7 @@ static void deduceImplicitRangeBounds(ParseState *pstate, Relation parentrel, List *stmts, bool addpartition) { PartitionKey key = RelationGetPartitionKey(parentrel); - PartitionDesc desc = RelationGetPartitionDesc(parentrel); + PartitionDesc desc = RelationGetPartitionDesc(parentrel, true); list_qsort_arg(stmts, qsort_stmt_cmp, key); diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 3de940bf9e59..ea64057eba86 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -69,10 +69,11 @@ static ParseNamespaceItem *scanNameSpaceForRelid(ParseState *pstate, Oid relid, static void check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem, int location); static int scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, + Alias *eref, const char *colname, int location, int fuzzy_rte_penalty, FuzzyAttrMatchState *fuzzystate); -static void markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, +static void markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col); static void expandRelation(Oid relid, Alias *eref, int rtindex, int sublevels_up, @@ -188,7 +189,6 @@ scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location) foreach(l, pstate->p_namespace) { ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(l); - RangeTblEntry *rte = nsitem->p_rte; /* Ignore columns-only items */ if (!nsitem->p_rel_visible) @@ -197,7 +197,7 @@ scanNameSpaceForRefname(ParseState *pstate, const char *refname, int location) if (nsitem->p_lateral_only && !pstate->p_lateral_active) continue; - if (strcmp(rte->eref->aliasname, refname) == 0) + if (strcmp(nsitem->p_names->aliasname, refname) == 0) { if (result) ereport(ERROR, @@ -427,7 +427,7 @@ checkNameSpaceConflicts(ParseState *pstate, List *namespace1, { ParseNamespaceItem *nsitem1 = (ParseNamespaceItem *) lfirst(l1); RangeTblEntry *rte1 = nsitem1->p_rte; - const char *aliasname1 = rte1->eref->aliasname; + const char *aliasname1 = nsitem1->p_names->aliasname; ListCell *l2; if (!nsitem1->p_rel_visible) @@ -437,10 +437,11 @@ checkNameSpaceConflicts(ParseState *pstate, List *namespace1, { ParseNamespaceItem *nsitem2 = (ParseNamespaceItem *) lfirst(l2); RangeTblEntry *rte2 = nsitem2->p_rte; + const char *aliasname2 = nsitem2->p_names->aliasname; if (!nsitem2->p_rel_visible) continue; - if (strcmp(rte2->eref->aliasname, aliasname1) != 0) + if (strcmp(aliasname2, aliasname1) != 0) continue; /* definitely no conflict */ if (rte1->rtekind == RTE_RELATION && rte1->alias == NULL && rte2->rtekind == RTE_RELATION && rte2->alias == NULL && @@ -473,7 +474,7 @@ check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem, { /* SQL:2008 demands this be an error, not an invisible item */ RangeTblEntry *rte = nsitem->p_rte; - char *refname = rte->eref->aliasname; + char *refname = nsitem->p_names->aliasname; ereport(ERROR, (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), @@ -667,8 +668,8 @@ updateFuzzyAttrMatchState(int fuzzy_rte_penalty, * If found, return an appropriate Var node, else return NULL. * If the name proves ambiguous within this nsitem, raise error. * - * Side effect: if we find a match, mark the item's RTE as requiring read - * access for the column. + * Side effect: if we find a match, mark the corresponding RTE as requiring + * read access for the column. */ Node * scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, @@ -679,10 +680,10 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, Var *var; /* - * Scan the RTE's column names (or aliases) for a match. Complain if + * Scan the nsitem's column names (or aliases) for a match. Complain if * multiple matches. */ - attnum = scanRTEForColumn(pstate, rte, + attnum = scanRTEForColumn(pstate, rte, nsitem->p_names, colname, location, 0, NULL); @@ -719,7 +720,7 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" of relation \"%s\" does not exist", colname, - rte->eref->aliasname))); + nsitem->p_names->aliasname))); var = makeVar(nscol->p_varno, nscol->p_varattno, @@ -747,7 +748,7 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, var->location = location; /* Require read access to the column */ - markVarForSelectPriv(pstate, var, rte); + markVarForSelectPriv(pstate, var); return (Node *) var; } @@ -759,6 +760,12 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, * else return InvalidAttrNumber. * If the name proves ambiguous within this RTE, raise error. * + * Actually, we only search the names listed in "eref". This can be either + * rte->eref, in which case we are indeed searching all the column names, + * or for a join it can be rte->join_using_alias, in which case we are only + * considering the common column names (which are the first N columns of the + * join, so everything works). + * * pstate and location are passed only for error-reporting purposes. * * Side effect: if fuzzystate is non-NULL, check non-system columns @@ -772,6 +779,7 @@ scanNSItemForColumn(ParseState *pstate, ParseNamespaceItem *nsitem, */ static int scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, + Alias *eref, const char *colname, int location, int fuzzy_rte_penalty, FuzzyAttrMatchState *fuzzystate) @@ -793,7 +801,7 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, * Callers interested in finding match with shortest distance need to * defend against this directly, though. */ - foreach(c, rte->eref->colnames) + foreach(c, eref->colnames) { const char *attcolname = strVal(lfirst(c)); @@ -995,7 +1003,7 @@ searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colnam * Scan for a matching column; if we find an exact match, we're * done. Otherwise, update fuzzystate. */ - if (scanRTEForColumn(orig_pstate, rte, colname, location, + if (scanRTEForColumn(orig_pstate, rte, rte->eref, colname, location, fuzzy_rte_penalty, fuzzystate) && fuzzy_rte_penalty == 0) { @@ -1015,21 +1023,15 @@ searchRangeTableForCol(ParseState *pstate, const char *alias, const char *colnam /* * markRTEForSelectPriv - * Mark the specified column of an RTE as requiring SELECT privilege + * Mark the specified column of the RTE with index rtindex + * as requiring SELECT privilege * * col == InvalidAttrNumber means a "whole row" reference - * - * External callers should always pass the Var's RTE. Internally, we - * allow NULL to be passed for the RTE and then look it up if needed; - * this takes less code than requiring each internal recursion site - * to perform a lookup. */ static void -markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, - int rtindex, AttrNumber col) +markRTEForSelectPriv(ParseState *pstate, int rtindex, AttrNumber col) { - if (rte == NULL) - rte = rt_fetch(rtindex, pstate->p_rtable); + RangeTblEntry *rte = rt_fetch(rtindex, pstate->p_rtable); if (rte->rtekind == RTE_RELATION) { @@ -1061,13 +1063,13 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, { int varno = ((RangeTblRef *) j->larg)->rtindex; - markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); + markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); } else if (IsA(j->larg, JoinExpr)) { int varno = ((JoinExpr *) j->larg)->rtindex; - markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); + markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); } else elog(ERROR, "unrecognized node type: %d", @@ -1076,13 +1078,13 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, { int varno = ((RangeTblRef *) j->rarg)->rtindex; - markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); + markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); } else if (IsA(j->rarg, JoinExpr)) { int varno = ((JoinExpr *) j->rarg)->rtindex; - markRTEForSelectPriv(pstate, NULL, varno, InvalidAttrNumber); + markRTEForSelectPriv(pstate, varno, InvalidAttrNumber); } else elog(ERROR, "unrecognized node type: %d", @@ -1103,10 +1105,11 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, /* * markVarForSelectPriv - * Mark the RTE referenced by a Var as requiring SELECT privilege + * Mark the RTE referenced by the Var as requiring SELECT privilege + * for the Var's column (the Var could be a whole-row Var, too) */ void -markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte) +markVarForSelectPriv(ParseState *pstate, Var *var) { Index lv; @@ -1114,7 +1117,7 @@ markVarForSelectPriv(ParseState *pstate, Var *var, RangeTblEntry *rte) /* Find the appropriate pstate if it's an uplevel Var */ for (lv = 0; lv < var->varlevelsup; lv++) pstate = pstate->parentParseState; - markRTEForSelectPriv(pstate, rte, var->varno, var->varattno); + markRTEForSelectPriv(pstate, var->varno, var->varattno); } /* @@ -1282,6 +1285,7 @@ buildNSItemFromTupleDesc(RangeTblEntry *rte, Index rtindex, TupleDesc tupdesc) /* ... and build the nsitem */ nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem)); + nsitem->p_names = rte->eref; nsitem->p_rte = rte; nsitem->p_rtindex = rtindex; nsitem->p_nscolumns = nscolumns; @@ -1343,6 +1347,7 @@ buildNSItemFromLists(RangeTblEntry *rte, Index rtindex, /* ... and build the nsitem */ nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem)); + nsitem->p_names = rte->eref; nsitem->p_rte = rte; nsitem->p_rtindex = rtindex; nsitem->p_nscolumns = nscolumns; @@ -1942,16 +1947,46 @@ addRangeTableEntryForFunction(ParseState *pstate, /* * A coldeflist is required if the function returns RECORD and hasn't - * got a predetermined record type, and is prohibited otherwise. + * got a predetermined record type, and is prohibited otherwise. This + * can be a bit confusing, so we expend some effort on delivering a + * relevant error message. */ if (coldeflist != NIL) { - if (functypclass != TYPEFUNC_RECORD) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("a column definition list is only allowed for functions returning \"record\""), - parser_errposition(pstate, - exprLocation((Node *) coldeflist)))); + switch (functypclass) + { + case TYPEFUNC_RECORD: + /* ok */ + break; + case TYPEFUNC_COMPOSITE: + case TYPEFUNC_COMPOSITE_DOMAIN: + + /* + * If the function's raw result type is RECORD, we must + * have resolved it using its OUT parameters. Otherwise, + * it must have a named composite type. + */ + if (exprType(funcexpr) == RECORDOID) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("a column definition list is redundant for a function with OUT parameters"), + parser_errposition(pstate, + exprLocation((Node *) coldeflist)))); + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("a column definition list is redundant for a function returning a named composite type"), + parser_errposition(pstate, + exprLocation((Node *) coldeflist)))); + break; + default: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("a column definition list is only allowed for functions returning \"record\""), + parser_errposition(pstate, + exprLocation((Node *) coldeflist)))); + break; + } } else { @@ -2310,6 +2345,7 @@ addRangeTableEntryForJoin(ParseState *pstate, List *aliasvars, List *leftcols, List *rightcols, + Alias *join_using_alias, Alias *alias, bool inFromCl) { @@ -2338,6 +2374,7 @@ addRangeTableEntryForJoin(ParseState *pstate, rte->joinaliasvars = aliasvars; rte->joinleftcols = leftcols; rte->joinrightcols = rightcols; + rte->join_using_alias = join_using_alias; rte->alias = alias; eref = alias ? copyObject(alias) : makeAlias("unnamed_join", NIL); @@ -2378,6 +2415,7 @@ addRangeTableEntryForJoin(ParseState *pstate, * list --- caller must do that if appropriate. */ nsitem = (ParseNamespaceItem *) palloc(sizeof(ParseNamespaceItem)); + nsitem->p_names = rte->eref; nsitem->p_rte = rte; nsitem->p_rtindex = list_length(pstate->p_rtable); nsitem->p_nscolumns = nscolumns; @@ -2410,6 +2448,8 @@ addRangeTableEntryForCTE(ParseState *pstate, int numaliases; int varattno; ListCell *lc; + int n_dontexpand_columns = 0; + ParseNamespaceItem *psi; Assert(pstate != NULL); @@ -2442,9 +2482,9 @@ addRangeTableEntryForCTE(ParseState *pstate, parser_errposition(pstate, rv->location))); } - rte->coltypes = cte->ctecoltypes; - rte->coltypmods = cte->ctecoltypmods; - rte->colcollations = cte->ctecolcollations; + rte->coltypes = list_copy(cte->ctecoltypes); + rte->coltypmods = list_copy(cte->ctecoltypmods); + rte->colcollations = list_copy(cte->ctecolcollations); rte->alias = alias; if (alias) @@ -2469,6 +2509,34 @@ addRangeTableEntryForCTE(ParseState *pstate, rte->eref = eref; + if (cte->search_clause) + { + rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->search_clause->search_seq_column)); + if (cte->search_clause->search_breadth_first) + rte->coltypes = lappend_oid(rte->coltypes, RECORDOID); + else + rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID); + rte->coltypmods = lappend_int(rte->coltypmods, -1); + rte->colcollations = lappend_oid(rte->colcollations, InvalidOid); + + n_dontexpand_columns += 1; + } + + if (cte->cycle_clause) + { + rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column)); + rte->coltypes = lappend_oid(rte->coltypes, cte->cycle_clause->cycle_mark_type); + rte->coltypmods = lappend_int(rte->coltypmods, cte->cycle_clause->cycle_mark_typmod); + rte->colcollations = lappend_oid(rte->colcollations, cte->cycle_clause->cycle_mark_collation); + + rte->eref->colnames = lappend(rte->eref->colnames, makeString(cte->cycle_clause->cycle_path_column)); + rte->coltypes = lappend_oid(rte->coltypes, RECORDARRAYOID); + rte->coltypmods = lappend_int(rte->coltypmods, -1); + rte->colcollations = lappend_oid(rte->colcollations, InvalidOid); + + n_dontexpand_columns += 2; + } + /* * Set flags and access permissions. * @@ -2496,9 +2564,19 @@ addRangeTableEntryForCTE(ParseState *pstate, * Build a ParseNamespaceItem, but don't add it to the pstate's namespace * list --- caller must do that if appropriate. */ - return buildNSItemFromLists(rte, list_length(pstate->p_rtable), - rte->coltypes, rte->coltypmods, - rte->colcollations); + psi = buildNSItemFromLists(rte, list_length(pstate->p_rtable), + rte->coltypes, rte->coltypmods, + rte->colcollations); + + /* + * The columns added by search and cycle clauses are not included in star + * expansion in queries contained in the CTE. + */ + if (rte->ctelevelsup > 0) + for (int i = 0; i < n_dontexpand_columns; i++) + psi->p_nscolumns[list_length(psi->p_names->colnames) - 1 - i].p_dontexpand = true; + + return psi; } /* @@ -3267,13 +3345,17 @@ expandNSItemVars(ParseNamespaceItem *nsitem, if (colnames) *colnames = NIL; colindex = 0; - foreach(lc, nsitem->p_rte->eref->colnames) + foreach(lc, nsitem->p_names->colnames) { Value *colnameval = (Value *) lfirst(lc); const char *colname = strVal(colnameval); ParseNamespaceColumn *nscol = nsitem->p_nscolumns + colindex; - if (colname[0]) + if (nscol->p_dontexpand) + { + /* skip */ + } + else if (colname[0]) { Var *var; @@ -3326,9 +3408,13 @@ expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem, /* * Require read access to the table. This is normally redundant with the * markVarForSelectPriv calls below, but not if the table has zero - * columns. + * columns. We need not do anything if the nsitem is for a join: its + * component tables will have been marked ACL_SELECT when they were added + * to the rangetable. (This step changes things only for the target + * relation of UPDATE/DELETE, which cannot be under a join.) */ - rte->requiredPerms |= ACL_SELECT; + if (rte->rtekind == RTE_RELATION) + rte->requiredPerms |= ACL_SELECT; forboth(name, names, var, vars) { @@ -3343,7 +3429,7 @@ expandNSItemAttrs(ParseState *pstate, ParseNamespaceItem *nsitem, te_list = lappend(te_list, te); /* Require read access to each column */ - markVarForSelectPriv(pstate, varnode, rte); + markVarForSelectPriv(pstate, varnode); } Assert(name == NULL && var == NULL); /* lists not the same length? */ diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 772f5ebc5627..df208dc1b847 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -3,7 +3,7 @@ * parse_target.c * handle target lists * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -34,17 +34,6 @@ static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle, Var *var, int levelsup); -static Node *transformAssignmentIndirection(ParseState *pstate, - Node *basenode, - const char *targetName, - bool targetIsSubscripting, - Oid targetTypeId, - int32 targetTypMod, - Oid targetCollation, - List *indirection, - ListCell *indirection_cell, - Node *rhs, - int location); static Node *transformAssignmentSubscripts(ParseState *pstate, Node *basenode, const char *targetName, @@ -56,6 +45,7 @@ static Node *transformAssignmentSubscripts(ParseState *pstate, List *indirection, ListCell *next_indirection, Node *rhs, + CoercionContext ccontext, int location); static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref, bool make_target_entry); @@ -411,10 +401,25 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle, { CommonTableExpr *cte = GetCTEForRTE(pstate, rte, netlevelsup); TargetEntry *ste; + List *tl = GetCTETargetList(cte); + int extra_cols = 0; + + /* + * RTE for CTE will already have the search and cycle columns + * added, but the subquery won't, so skip looking those up. + */ + if (cte->search_clause) + extra_cols += 1; + if (cte->cycle_clause) + extra_cols += 2; + if (extra_cols && + attnum > list_length(tl) && + attnum <= list_length(tl) + extra_cols) + break; - ste = get_tle_by_resno(GetCTETargetList(cte), attnum); + ste = get_tle_by_resno(tl, attnum); if (ste == NULL || ste->resjunk) - elog(ERROR, "subquery %s does not have attribute %d", + elog(ERROR, "CTE %s does not have attribute %d", rte->eref->aliasname, attnum); tle->resorigtbl = ste->resorigtbl; tle->resorigcol = ste->resorigcol; @@ -563,6 +568,7 @@ transformAssignedExpr(ParseState *pstate, indirection, list_head(indirection), (Node *) expr, + COERCION_ASSIGNMENT, location); } else @@ -644,15 +650,15 @@ updateTargetListEntry(ParseState *pstate, /* * Process indirection (field selection or subscripting) of the target - * column in INSERT/UPDATE. This routine recurses for multiple levels - * of indirection --- but note that several adjacent A_Indices nodes in - * the indirection list are treated as a single multidimensional subscript + * column in INSERT/UPDATE/assignment. This routine recurses for multiple + * levels of indirection --- but note that several adjacent A_Indices nodes + * in the indirection list are treated as a single multidimensional subscript * operation. * * In the initial call, basenode is a Var for the target column in UPDATE, - * or a null Const of the target's type in INSERT. In recursive calls, - * basenode is NULL, indicating that a substitute node should be consed up if - * needed. + * or a null Const of the target's type in INSERT, or a Param for the target + * variable in PL/pgSQL assignment. In recursive calls, basenode is NULL, + * indicating that a substitute node should be consed up if needed. * * targetName is the name of the field or subfield we're assigning to, and * targetIsSubscripting is true if we're subscripting it. These are just for @@ -669,12 +675,16 @@ updateTargetListEntry(ParseState *pstate, * rhs is the already-transformed value to be assigned; note it has not been * coerced to any particular type. * + * ccontext is the coercion level to use while coercing the rhs. For + * normal statements it'll be COERCION_ASSIGNMENT, but PL/pgSQL uses + * a special value. + * * location is the cursor error position for any errors. (Note: this points * to the head of the target clause, eg "foo" in "foo.bar[baz]". Later we * might want to decorate indirection cells with their own location info, * in which case the location argument could probably be dropped.) */ -static Node * +Node * transformAssignmentIndirection(ParseState *pstate, Node *basenode, const char *targetName, @@ -685,6 +695,7 @@ transformAssignmentIndirection(ParseState *pstate, List *indirection, ListCell *indirection_cell, Node *rhs, + CoercionContext ccontext, int location) { Node *result; @@ -759,6 +770,7 @@ transformAssignmentIndirection(ParseState *pstate, indirection, i, rhs, + ccontext, location); } @@ -809,6 +821,7 @@ transformAssignmentIndirection(ParseState *pstate, indirection, lnext(indirection, i), rhs, + ccontext, location); /* and build a FieldStore node */ @@ -847,6 +860,7 @@ transformAssignmentIndirection(ParseState *pstate, indirection, NULL, rhs, + ccontext, location); } @@ -855,7 +869,7 @@ transformAssignmentIndirection(ParseState *pstate, result = coerce_to_target_type(pstate, rhs, exprType(rhs), targetTypeId, targetTypMod, - COERCION_ASSIGNMENT, + ccontext, COERCE_IMPLICIT_CAST, -1); if (result == NULL) @@ -863,7 +877,7 @@ transformAssignmentIndirection(ParseState *pstate, if (targetIsSubscripting) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("array assignment to \"%s\" requires type %s" + errmsg("subscripted assignment to \"%s\" requires type %s" " but expression is of type %s", targetName, format_type_be(targetTypeId), @@ -900,29 +914,41 @@ transformAssignmentSubscripts(ParseState *pstate, List *indirection, ListCell *next_indirection, Node *rhs, + CoercionContext ccontext, int location) { Node *result; + SubscriptingRef *sbsref; Oid containerType; int32 containerTypMod; - Oid elementTypeId; Oid typeNeeded; + int32 typmodNeeded; Oid collationNeeded; Assert(subscripts != NIL); - /* Identify the actual array type and element type involved */ + /* Identify the actual container type involved */ containerType = targetTypeId; containerTypMod = targetTypMod; - elementTypeId = transformContainerType(&containerType, &containerTypMod); + transformContainerType(&containerType, &containerTypMod); + + /* Process subscripts and identify required type for RHS */ + sbsref = transformContainerSubscripts(pstate, + basenode, + containerType, + containerTypMod, + subscripts, + true); - /* Identify type that RHS must provide */ - typeNeeded = isSlice ? containerType : elementTypeId; + typeNeeded = sbsref->refrestype; + typmodNeeded = sbsref->reftypmod; /* - * container normally has same collation as elements, but there's an - * exception: we might be subscripting a domain over a container type. In - * that case use collation of the base type. + * Container normally has same collation as its elements, but there's an + * exception: we might be subscripting a domain over a container type. In + * that case use collation of the base type. (This is shaky for arbitrary + * subscripting semantics, but it doesn't matter all that much since we + * only use this to label the collation of a possible CaseTestExpr.) */ if (containerType == targetTypeId) collationNeeded = targetCollation; @@ -935,21 +961,23 @@ transformAssignmentSubscripts(ParseState *pstate, targetName, true, typeNeeded, - containerTypMod, + typmodNeeded, collationNeeded, indirection, next_indirection, rhs, + ccontext, location); - /* process subscripts */ - result = (Node *) transformContainerSubscripts(pstate, - basenode, - containerType, - elementTypeId, - containerTypMod, - subscripts, - rhs); + /* + * Insert the already-properly-coerced RHS into the SubscriptingRef. Then + * set refrestype and reftypmod back to the container type's values. + */ + sbsref->refassgnexpr = (Expr *) rhs; + sbsref->refrestype = containerType; + sbsref->reftypmod = containerTypMod; + + result = (Node *) sbsref; /* If target was a domain over container, need to coerce up to the domain */ if (containerType != targetTypeId) @@ -959,7 +987,7 @@ transformAssignmentSubscripts(ParseState *pstate, result = coerce_to_target_type(pstate, result, resulttype, targetTypeId, targetTypMod, - COERCION_ASSIGNMENT, + ccontext, COERCE_IMPLICIT_CAST, -1); /* can fail if we had int2vector/oidvector, but not for true domains */ @@ -1360,16 +1388,20 @@ ExpandSingleTable(ParseState *pstate, ParseNamespaceItem *nsitem, /* * Require read access to the table. This is normally redundant with * the markVarForSelectPriv calls below, but not if the table has zero - * columns. + * columns. We need not do anything if the nsitem is for a join: its + * component tables will have been marked ACL_SELECT when they were + * added to the rangetable. (This step changes things only for the + * target relation of UPDATE/DELETE, which cannot be under a join.) */ - rte->requiredPerms |= ACL_SELECT; + if (rte->rtekind == RTE_RELATION) + rte->requiredPerms |= ACL_SELECT; /* Require read access to each column */ foreach(l, vars) { Var *var = (Var *) lfirst(l); - markVarForSelectPriv(pstate, var, rte); + markVarForSelectPriv(pstate, var); } return vars; @@ -1611,7 +1643,7 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup) ste = get_tle_by_resno(GetCTETargetList(cte), attnum); if (ste == NULL || ste->resjunk) - elog(ERROR, "subquery %s does not have attribute %d", + elog(ERROR, "CTE %s does not have attribute %d", rte->eref->aliasname, attnum); expr = (Node *) ste->expr; if (IsA(expr, Var)) @@ -1763,11 +1795,6 @@ FigureColnameInternal(Node *node, char **name) *name = "nullif"; return 2; } - if (((A_Expr *) node)->kind == AEXPR_PAREN) - { - /* look through dummy parenthesis node */ - return FigureColnameInternal(((A_Expr *) node)->lexpr, name); - } break; case T_TypeCast: strength = FigureColnameInternal(((TypeCast *) node)->arg, diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c index cb6a5365c429..aa64077a713e 100644 --- a/src/backend/parser/parse_type.c +++ b/src/backend/parser/parse_type.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -721,13 +721,6 @@ pts_error_callback(void *arg) const char *str = (const char *) arg; errcontext("invalid type name \"%s\"", str); - - /* - * Currently we just suppress any syntax error position report, rather - * than transforming to an "internal query" error. It's unlikely that a - * type name is complex enough to need positioning. - */ - errposition(0); } /* @@ -739,11 +732,7 @@ pts_error_callback(void *arg) TypeName * typeStringToTypeName(const char *str) { - StringInfoData buf; List *raw_parsetree_list; - SelectStmt *stmt; - ResTarget *restarget; - TypeCast *typecast; TypeName *typeName; ErrorContextCallback ptserrcontext; @@ -751,9 +740,6 @@ typeStringToTypeName(const char *str) if (strspn(str, " \t\n\r\f") == strlen(str)) goto fail; - initStringInfo(&buf); - appendStringInfo(&buf, "SELECT NULL::%s", str); - /* * Setup error traceback support in case of ereport() during parse */ @@ -762,58 +748,18 @@ typeStringToTypeName(const char *str) ptserrcontext.previous = error_context_stack; error_context_stack = &ptserrcontext; - raw_parsetree_list = raw_parser(buf.data); + raw_parsetree_list = raw_parser(str, RAW_PARSE_TYPE_NAME); error_context_stack = ptserrcontext.previous; - /* - * Make sure we got back exactly what we expected and no more; paranoia is - * justified since the string might contain anything. - */ - if (list_length(raw_parsetree_list) != 1) - goto fail; - stmt = (SelectStmt *) linitial_node(RawStmt, raw_parsetree_list)->stmt; - if (stmt == NULL || - !IsA(stmt, SelectStmt) || - stmt->distinctClause != NIL || - stmt->intoClause != NULL || - stmt->fromClause != NIL || - stmt->whereClause != NULL || - stmt->groupClause != NIL || - stmt->havingClause != NULL || - stmt->windowClause != NIL || - stmt->valuesLists != NIL || - stmt->sortClause != NIL || - stmt->limitOffset != NULL || - stmt->limitCount != NULL || - stmt->lockingClause != NIL || - stmt->withClause != NULL || - stmt->op != SETOP_NONE) - goto fail; - if (list_length(stmt->targetList) != 1) - goto fail; - restarget = (ResTarget *) linitial(stmt->targetList); - if (restarget == NULL || - !IsA(restarget, ResTarget) || - restarget->name != NULL || - restarget->indirection != NIL) - goto fail; - typecast = (TypeCast *) restarget->val; - if (typecast == NULL || - !IsA(typecast, TypeCast) || - typecast->arg == NULL || - !IsA(typecast->arg, A_Const)) - goto fail; + /* We should get back exactly one TypeName node. */ + Assert(list_length(raw_parsetree_list) == 1); + typeName = linitial_node(TypeName, raw_parsetree_list); - typeName = typecast->typeName; - if (typeName == NULL || - !IsA(typeName, TypeName)) - goto fail; + /* The grammar allows SETOF in TypeName, but we don't want that here. */ if (typeName->setof) goto fail; - pfree(buf.data); - return typeName; fail: diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index d11711357fb0..631ed453e392 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -11,12 +11,8 @@ * Hence these functions are now called at the start of execution of their * respective utility commands. * - * NOTE: in general we must avoid scribbling on the passed-in raw parse - * tree, since it might be in a plan cache. The simplest solution is - * a quick copyObject() call before manipulating the query tree. * - * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/parser/parse_utilcmd.c @@ -31,6 +27,7 @@ #include "access/relation.h" #include "access/reloptions.h" #include "access/table.h" +#include "access/toast_compression.h" #include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/index.h" @@ -99,6 +96,7 @@ typedef struct List *ixconstraints; /* index-creating constraints */ List *attr_encodings; /* List of ColumnReferenceStorageDirectives */ List *inh_indexes; /* cloned indexes from INCLUDING INDEXES */ + List *likeclauses; /* LIKE clauses that need post-processing */ List *extstats; /* cloned extended statistics */ List *blist; /* "before list" of things to do before * creating the table */ @@ -172,6 +170,9 @@ static DistributedBy *transformDistributedBy(ParseState *pstate, * Returns a List of utility commands to be done in sequence. One of these * will be the transformed CreateStmt, but there may be additional actions * to be done before and after the actual DefineRelation() call. + * In addition to normal utility commands such as AlterTableStmt and + * IndexStmt, the result list may contain TableLikeClause(s), representing + * the need to perform additional parse analysis after DefineRelation(). * * SQL allows constraints to be scattered all over, so thumb through * the columns and collect all constraints into one place. @@ -290,6 +291,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) cxt.fkconstraints = NIL; cxt.ixconstraints = NIL; cxt.inh_indexes = NIL; + cxt.likeclauses = NIL; cxt.extstats = NIL; cxt.attr_encodings = stmt->attr_encodings; cxt.blist = NIL; @@ -372,6 +374,20 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) */ transformIndexConstraints(&cxt); + /* + * Re-consideration of LIKE clauses should happen after creation of + * indexes, but before creation of foreign keys. This order is critical + * because a LIKE clause may attempt to create a primary key. If there's + * also a pkey in the main CREATE TABLE list, creation of that will not + * check for a duplicate at runtime (since index_check_primary_key() + * expects that we rejected dups here). Creation of the LIKE-generated + * pkey behaves like ALTER TABLE ADD, so it will check, but obviously that + * only works if it happens second. On the other hand, we want to make + * pkeys before foreign key constraints, in case the user tries to make a + * self-referential FK. + */ + cxt.alist = list_concat(cxt.alist, cxt.likeclauses); + /* * Postprocess foreign-key constraints. * But don't cascade FK constraints to parts, yet. @@ -399,8 +415,11 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) /* * Postprocess check constraints. + * + * For regular tables all constraints can be marked valid immediately, + * because the table is new therefore empty. Not so for foreign tables. */ - transformCheckConstraints(&cxt, !is_foreign_table ? true : false); + transformCheckConstraints(&cxt, !cxt.isforeign); /* * Postprocess extended statistics. @@ -447,6 +466,7 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column, AlterSeqStmt *altseqstmt; List *attnamelist; bool has_cache_option = false; + int nameEl_idx = -1; /* * Determine namespace and name to use for the sequence. @@ -473,6 +493,7 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); nameEl = defel; + nameEl_idx = foreach_current_index(option); } if (strcmp(defel->defname, "cache") == 0) @@ -495,7 +516,7 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column, } sname = rv->relname; /* Remove the SEQUENCE NAME item from seqoptions */ - seqoptions = list_delete_ptr(seqoptions, nameEl); + seqoptions = list_delete_nth_cell(seqoptions, nameEl_idx); } else { @@ -515,9 +536,9 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column, } ereport(DEBUG1, - (errmsg("%s will create implicit sequence \"%s\" for serial column \"%s.%s\"", - cxt->stmtType, sname, - cxt->relation->relname, column->colname))); + (errmsg_internal("%s will create implicit sequence \"%s\" for serial column \"%s.%s\"", + cxt->stmtType, sname, + cxt->relation->relname, column->colname))); /* * Build a CREATE SEQUENCE command to create the sequence object, and add @@ -701,6 +722,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) castnode->location = -1; funccallnode = makeFuncCall(SystemFuncName("nextval"), list_make1(castnode), + COERCE_EXPLICIT_CALL, -1); constraint = makeNode(Constraint); constraint->contype = CONSTR_DEFAULT; @@ -799,7 +821,17 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) column->identity = constraint->generated_when; saw_identity = true; + + /* An identity column is implicitly NOT NULL */ + if (saw_nullable && !column->is_not_null) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"", + column->colname, cxt->relation->relname), + parser_errposition(cxt->pstate, + constraint->location))); column->is_not_null = true; + saw_nullable = true; break; } @@ -1017,21 +1049,19 @@ transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint) * transformTableLikeClause * * Change the LIKE portion of a CREATE TABLE statement into - * column definitions which recreate the user defined column portions of - * . - * - * GPDB: if forceBareCol is true we disallow inheriting any indexes/constr/defaults. + * column definitions that recreate the user defined column portions of + * . Also, if there are any LIKE options that we can't fully + * process at this point, add the TableLikeClause to cxt->likeclauses, which + * will cause utility.c to call expandTableLikeClause() after the new + * table has been created. */ static void transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_clause, bool forceBareCol, CreateStmt *stmt) { AttrNumber parent_attno; - AttrNumber new_attno; Relation relation; TupleDesc tupleDesc; - TupleConstr *constr; - AttrMap *attmap; AclResult aclresult; char *comment; ParseCallbackState pcbstate; @@ -1051,6 +1081,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("LIKE is not supported for creating foreign tables"))); + /* Open the relation referenced by the LIKE clause */ relation = relation_openrv(table_like_clause->relation, AccessShareLock); if (relation->rd_rel->relkind != RELKIND_RELATION && @@ -1087,37 +1118,46 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla } tupleDesc = RelationGetDescr(relation); - constr = tupleDesc->constr; - - /* - * Initialize column number map for map_variable_attnos(). We need this - * since dropped columns in the source table aren't copied, so the new - * table can have different column numbers. - */ - attmap = make_attrmap(tupleDesc->natts); /* - * We must fill the attmap now so that it can be used to process generated - * column default expressions in the per-column loop below. + * GPDB: LIKE ... INCLUDING STORAGE (and ALL) also carries over the + * source table's access method and reloptions (appendonly orientation, + * blocksize, compression, ...), unless the new table specifies its + * own. This must happen at parse time, before DefineRelation creates + * the table; the PG14 deferred-LIKE rework had dropped it. */ - new_attno = 1; - for (parent_attno = 1; parent_attno <= tupleDesc->natts; - parent_attno++) + if (stmt != NULL && + (table_like_clause->options & CREATE_TABLE_LIKE_STORAGE) && + relation->rd_rel->relkind == RELKIND_RELATION) { - Form_pg_attribute attribute = TupleDescAttr(tupleDesc, - parent_attno - 1); + if (stmt->accessMethod == NULL && + OidIsValid(relation->rd_rel->relam)) + stmt->accessMethod = get_am_name(relation->rd_rel->relam); - /* - * Ignore dropped columns in the parent. attmap entry is left zero. - */ - if (attribute->attisdropped) - continue; + if (stmt->options == NIL) + { + Datum reloptions; + bool isnull; + HeapTuple tuple; - attmap->attnums[parent_attno - 1] = list_length(cxt->columns) + (new_attno++); + tuple = SearchSysCache1(RELOID, + ObjectIdGetDatum(RelationGetRelid(relation))); + if (HeapTupleIsValid(tuple)) + { + reloptions = SysCacheGetAttr(RELOID, tuple, + Anum_pg_class_reloptions, + &isnull); + if (!isnull) + stmt->options = untransformRelOptions(reloptions); + ReleaseSysCache(tuple); + } + } } /* * Insert the copied attributes into the cxt for the new table definition. + * We must do this now so that they appear in the table in the relative + * position where the LIKE clause is, as required by SQL99. */ for (parent_attno = 1; parent_attno <= tupleDesc->natts; parent_attno++) @@ -1161,52 +1201,12 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla cxt->columns = lappend(cxt->columns, def); /* - * Copy default, if present and it should be copied. We have separate - * options for plain default expressions and GENERATED defaults. + * Although we don't transfer the column's default/generation + * expression now, we need to mark it GENERATED if appropriate. */ - if (attribute->atthasdef && - (attribute->attgenerated ? - (table_like_clause->options & CREATE_TABLE_LIKE_GENERATED) : - (table_like_clause->options & CREATE_TABLE_LIKE_DEFAULTS))) - { - Node *this_default = NULL; - AttrDefault *attrdef; - int i; - bool found_whole_row; - - /* Find default in constraint structure */ - Assert(constr != NULL); - attrdef = constr->defval; - for (i = 0; i < constr->num_defval; i++) - { - if (attrdef[i].adnum == parent_attno) - { - this_default = stringToNode(attrdef[i].adbin); - break; - } - } - Assert(this_default != NULL); - - def->cooked_default = map_variable_attnos(this_default, - 1, 0, - attmap, - InvalidOid, &found_whole_row); - - /* - * Prevent this for the same reason as for constraints below. Note - * that defaults cannot contain any vars, so it's OK that the - * error message refers to generated columns. - */ - if (found_whole_row) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert whole-row table reference"), - errdetail("Generation expression for column \"%s\" contains a whole-row reference to table \"%s\".", - attributeName, - RelationGetRelationName(relation)))); - + if (attribute->atthasdef && attribute->attgenerated && + (table_like_clause->options & CREATE_TABLE_LIKE_GENERATED)) def->generated = attribute->attgenerated; - } /* * Copy identity if requested @@ -1236,6 +1236,14 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla else def->storage = 0; + /* Likewise, copy compression if requested */ + if ((table_like_clause->options & CREATE_TABLE_LIKE_COMPRESSION) != 0 + && CompressionMethodIsValid(attribute->attcompression)) + def->compression = + pstrdup(GetCompressionMethodName(attribute->attcompression)); + else + def->compression = NULL; + /* Likewise, copy comment if requested */ if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) && (comment = GetComment(attribute->attrelid, @@ -1254,14 +1262,200 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla } } + /* + * We cannot yet deal with defaults, CHECK constraints, or indexes, since + * we don't yet know what column numbers the copied columns will have in + * the finished table. If any of those options are specified, add the + * LIKE clause to cxt->likeclauses so that expandTableLikeClause will be + * called after we do know that. Also, remember the relation OID so that + * expandTableLikeClause is certain to open the same table. + */ + if (table_like_clause->options & + (CREATE_TABLE_LIKE_DEFAULTS | + CREATE_TABLE_LIKE_GENERATED | + CREATE_TABLE_LIKE_CONSTRAINTS | + CREATE_TABLE_LIKE_INDEXES)) + { + table_like_clause->relationOid = RelationGetRelid(relation); + cxt->likeclauses = lappend(cxt->likeclauses, table_like_clause); + } + + /* + * We may copy extended statistics if requested, since the representation + * of CreateStatsStmt doesn't depend on column numbers. + */ + if (table_like_clause->options & CREATE_TABLE_LIKE_STATISTICS) + { + List *parent_extstats; + ListCell *l; + + parent_extstats = RelationGetStatExtList(relation); + + foreach(l, parent_extstats) + { + Oid parent_stat_oid = lfirst_oid(l); + CreateStatsStmt *stats_stmt; + + stats_stmt = generateClonedExtStatsStmt(cxt->relation, + RelationGetRelid(relation), + parent_stat_oid); + + /* Copy comment on statistics object, if requested */ + if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) + { + comment = GetComment(parent_stat_oid, StatisticExtRelationId, 0); + + /* + * We make use of CreateStatsStmt's stxcomment option, so as + * not to need to know now what name the statistics will have. + */ + stats_stmt->stxcomment = comment; + } + + cxt->extstats = lappend(cxt->extstats, stats_stmt); + } + + list_free(parent_extstats); + } + + /* + * Close the parent rel, but keep our AccessShareLock on it until xact + * commit. That will prevent someone else from deleting or ALTERing the + * parent before we can run expandTableLikeClause. + */ + table_close(relation, NoLock); +} + +/* + * expandTableLikeClause + * + * Process LIKE options that require knowing the final column numbers + * assigned to the new table's columns. This executes after we have + * run DefineRelation for the new table. It returns a list of utility + * commands that should be run to generate indexes etc. + */ +List * +expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause) +{ + List *result = NIL; + List *atsubcmds = NIL; + AttrNumber parent_attno; + Relation relation; + Relation childrel; + TupleDesc tupleDesc; + TupleConstr *constr; + AttrMap *attmap; + char *comment; + + /* + * Open the relation referenced by the LIKE clause. We should still have + * the table lock obtained by transformTableLikeClause (and this'll throw + * an assertion failure if not). Hence, no need to recheck privileges + * etc. We must open the rel by OID not name, to be sure we get the same + * table. + */ + if (!OidIsValid(table_like_clause->relationOid)) + elog(ERROR, "expandTableLikeClause called on untransformed LIKE clause"); + + relation = relation_open(table_like_clause->relationOid, NoLock); + + tupleDesc = RelationGetDescr(relation); + constr = tupleDesc->constr; + + /* + * Open the newly-created child relation; we have lock on that too. + */ + childrel = relation_openrv(heapRel, NoLock); + + /* + * Construct a map from the LIKE relation's attnos to the child rel's. + * This re-checks type match etc, although it shouldn't be possible to + * have a failure since both tables are locked. + */ + attmap = build_attrmap_by_name(RelationGetDescr(childrel), + tupleDesc); + + /* + * Process defaults, if required. + */ + if ((table_like_clause->options & + (CREATE_TABLE_LIKE_DEFAULTS | CREATE_TABLE_LIKE_GENERATED)) && + constr != NULL) + { + for (parent_attno = 1; parent_attno <= tupleDesc->natts; + parent_attno++) + { + Form_pg_attribute attribute = TupleDescAttr(tupleDesc, + parent_attno - 1); + + /* + * Ignore dropped columns in the parent. + */ + if (attribute->attisdropped) + continue; + + /* + * Copy default, if present and it should be copied. We have + * separate options for plain default expressions and GENERATED + * defaults. + */ + if (attribute->atthasdef && + (attribute->attgenerated ? + (table_like_clause->options & CREATE_TABLE_LIKE_GENERATED) : + (table_like_clause->options & CREATE_TABLE_LIKE_DEFAULTS))) + { + Node *this_default = NULL; + AttrDefault *attrdef = constr->defval; + AlterTableCmd *atsubcmd; + bool found_whole_row; + + /* Find default in constraint structure */ + for (int i = 0; i < constr->num_defval; i++) + { + if (attrdef[i].adnum == parent_attno) + { + this_default = stringToNode(attrdef[i].adbin); + break; + } + } + if (this_default == NULL) + elog(ERROR, "default expression not found for attribute %d of relation \"%s\"", + parent_attno, RelationGetRelationName(relation)); + + atsubcmd = makeNode(AlterTableCmd); + atsubcmd->subtype = AT_CookedColumnDefault; + atsubcmd->num = attmap->attnums[parent_attno - 1]; + atsubcmd->def = map_variable_attnos(this_default, + 1, 0, + attmap, + InvalidOid, + &found_whole_row); + + /* + * Prevent this for the same reason as for constraints below. + * Note that defaults cannot contain any vars, so it's OK that + * the error message refers to generated columns. + */ + if (found_whole_row) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert whole-row table reference"), + errdetail("Generation expression for column \"%s\" contains a whole-row reference to table \"%s\".", + NameStr(attribute->attname), + RelationGetRelationName(relation)))); + + atsubcmds = lappend(atsubcmds, atsubcmd); + } + } + } + /* * Copy CHECK constraints if requested, being careful to adjust attribute * numbers so they match the child. */ if ((table_like_clause->options & CREATE_TABLE_LIKE_CONSTRAINTS) && - tupleDesc->constr) + constr != NULL) { - TupleConstr *constr = tupleDesc->constr; int ccnum; for (ccnum = 0; ccnum < constr->num_check; ccnum++) @@ -1269,9 +1463,10 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla char *ccname = constr->check[ccnum].ccname; char *ccbin = constr->check[ccnum].ccbin; bool ccnoinherit = constr->check[ccnum].ccnoinherit; - Constraint *n = makeNode(Constraint); Node *ccbin_node; bool found_whole_row; + Constraint *n; + AlterTableCmd *atsubcmd; ccbin_node = map_variable_attnos(stringToNode(ccbin), 1, 0, @@ -1292,13 +1487,22 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla ccname, RelationGetRelationName(relation)))); + n = makeNode(Constraint); n->contype = CONSTR_CHECK; n->conname = pstrdup(ccname); n->location = -1; n->is_no_inherit = ccnoinherit; n->raw_expr = NULL; n->cooked_expr = nodeToString(ccbin_node); - cxt->ckconstraints = lappend(cxt->ckconstraints, n); + + /* We can skip validation, since the new table should be empty. */ + n->skip_validation = true; + n->initially_valid = true; + + atsubcmd = makeNode(AlterTableCmd); + atsubcmd->subtype = AT_AddConstraint; + atsubcmd->def = (Node *) n; + atsubcmds = lappend(atsubcmds, atsubcmd); /* Copy comment on constraint */ if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) && @@ -1310,18 +1514,34 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla CommentStmt *stmt = makeNode(CommentStmt); stmt->objtype = OBJECT_TABCONSTRAINT; - stmt->object = (Node *) list_make3(makeString(cxt->relation->schemaname), - makeString(cxt->relation->relname), + stmt->object = (Node *) list_make3(makeString(heapRel->schemaname), + makeString(heapRel->relname), makeString(n->conname)); stmt->comment = comment; - cxt->alist = lappend(cxt->alist, stmt); + result = lappend(result, stmt); } } } /* - * Likewise, copy indexes if requested + * If we generated any ALTER TABLE actions above, wrap them into a single + * ALTER TABLE command. Stick it at the front of the result, so it runs + * before any CommentStmts we made above. + */ + if (atsubcmds) + { + AlterTableStmt *atcmd = makeNode(AlterTableStmt); + + atcmd->relation = copyObject(heapRel); + atcmd->cmds = atsubcmds; + atcmd->objtype = OBJECT_TABLE; + atcmd->missing_ok = false; + result = lcons(atcmd, result); + } + + /* + * Process indexes if required. */ if ((table_like_clause->options & CREATE_TABLE_LIKE_INDEXES) && relation->rd_rel->relhasindex) @@ -1340,7 +1560,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla parent_index = index_open(parent_index_oid, AccessShareLock); /* Build CREATE INDEX statement to recreate the parent_index */ - index_stmt = generateClonedIndexStmt(cxt->relation, + index_stmt = generateClonedIndexStmt(heapRel, parent_index, attmap, NULL); @@ -1357,102 +1577,14 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla index_stmt->idxcomment = comment; } - /* Save it in the inh_indexes list for the time being */ - cxt->inh_indexes = lappend(cxt->inh_indexes, index_stmt); + result = lappend(result, index_stmt); index_close(parent_index, AccessShareLock); } } - /* - * GPDB_12_MERGE_FIXME: - * This is wrong and creates unspecified behaviour when multiple like - * clauses are present in the statement. - * - * Try to use a unified interface for encoding handling in a manner - * similar to CREATE/ALTER commands. - */ - /* - * If STORAGE is included, we need to copy over the table storage params - * as well as the attribute encodings. - */ - if (stmt && table_like_clause->options & CREATE_TABLE_LIKE_STORAGE) - { - MemoryContext oldcontext; - /* - * As we are modifying the utility statement we must make sure these - * DefElem allocations can survive outside of this context. - */ - oldcontext = MemoryContextSwitchTo(CurTransactionContext); - - if (RelationIsAppendOptimized(relation)) - { - int32 blocksize; - int32 safefswritersize; - int16 compresslevel; - bool checksum; - NameData compresstype; - - GetAppendOnlyEntryAttributes(relation->rd_id, &blocksize, - &safefswritersize,&compresslevel, - &checksum,&compresstype); - - stmt->accessMethod = get_am_name(relation->rd_rel->relam); - - stmt->options = lappend(stmt->options, - makeDefElem("blocksize", (Node *) makeInteger(blocksize), -1)); - stmt->options = lappend(stmt->options, - makeDefElem("checksum", (Node *) makeInteger(checksum), -1)); - stmt->options = lappend(stmt->options, - makeDefElem("compresslevel", (Node *) makeInteger(compresslevel), -1)); - if (strlen(NameStr(compresstype)) > 0) - stmt->options = lappend(stmt->options, - makeDefElem("compresstype", (Node *) makeString(pstrdup(NameStr(compresstype))), -1)); - } - - /* - * Set the attribute encodings. - */ - cxt->attr_encodings = list_union(cxt->attr_encodings, rel_get_column_encodings(relation)); - MemoryContextSwitchTo(oldcontext); - } - - /* - * Likewise, copy extended statistics if requested - */ - if (table_like_clause->options & CREATE_TABLE_LIKE_STATISTICS) - { - List *parent_extstats; - ListCell *l; - - parent_extstats = RelationGetStatExtList(relation); - - foreach(l, parent_extstats) - { - Oid parent_stat_oid = lfirst_oid(l); - CreateStatsStmt *stats_stmt; - - stats_stmt = generateClonedExtStatsStmt(cxt->relation, - RelationGetRelid(relation), - parent_stat_oid); - - /* Copy comment on statistics object, if requested */ - if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) - { - comment = GetComment(parent_stat_oid, StatisticExtRelationId, 0); - - /* - * We make use of CreateStatsStmt's stxcomment option, so as - * not to need to know now what name the statistics will have. - */ - stats_stmt->stxcomment = comment; - } - - cxt->extstats = lappend(cxt->extstats, stats_stmt); - } - - list_free(parent_extstats); - } + /* Done with child rel */ + table_close(childrel, NoLock); /* * Close the parent rel, but keep our AccessShareLock on it until xact @@ -1460,6 +1592,8 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla * parent before the child is committed. */ table_close(relation, NoLock); + + return result; } static void @@ -1753,7 +1887,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, attmap, InvalidOid, &found_whole_row); - /* As in transformTableLikeClause, reject whole-row variables */ + /* As in expandTableLikeClause, reject whole-row variables */ if (found_whole_row) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -1822,7 +1956,6 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, char *attname; attname = get_attname(indrelid, attnum, false); - keycoltype = get_atttype(indrelid, attnum); iparam->name = attname; iparam->expr = NULL; @@ -1862,7 +1995,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, attmap, InvalidOid, &found_whole_row); - /* As in transformTableLikeClause, reject whole-row variables */ + /* As in expandTableLikeClause, reject whole-row variables */ if (found_whole_row) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -1929,6 +2062,9 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid, stat_types = lappend(stat_types, makeString("dependencies")); else if (enabled[i] == STATS_EXT_MCV) stat_types = lappend(stat_types, makeString("mcv")); + else if (enabled[i] == STATS_EXT_EXPRESSIONS) + /* expression stats are not exposed to users */ + continue; else elog(ERROR, "unrecognized statistics kind %c", enabled[i]); } @@ -1936,14 +2072,47 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid, /* Determine which columns the statistics are on */ for (i = 0; i < statsrec->stxkeys.dim1; i++) { - ColumnRef *cref = makeNode(ColumnRef); + StatsElem *selem = makeNode(StatsElem); AttrNumber attnum = statsrec->stxkeys.values[i]; - cref->fields = list_make1(makeString(get_attname(heapRelid, - attnum, false))); - cref->location = -1; + selem->name = get_attname(heapRelid, attnum, false); + selem->expr = NULL; + + def_names = lappend(def_names, selem); + } + + /* + * Now handle expressions, if there are any. The order (with respect to + * regular attributes) does not really matter for extended stats, so we + * simply append them after simple column references. + * + * XXX Some places during build/estimation treat expressions as if they + * are before attributes, but for the CREATE command that's entirely + * irrelevant. + */ + datum = SysCacheGetAttr(STATEXTOID, ht_stats, + Anum_pg_statistic_ext_stxexprs, &isnull); + + if (!isnull) + { + ListCell *lc; + List *exprs = NIL; + char *exprsString; + + exprsString = TextDatumGetCString(datum); + exprs = (List *) stringToNode(exprsString); + + foreach(lc, exprs) + { + StatsElem *selem = makeNode(StatsElem); - def_names = lappend(def_names, cref); + selem->name = NULL; + selem->expr = (Node *) lfirst(lc); + + def_names = lappend(def_names, selem); + } + + pfree(exprsString); } /* finally, build the output node */ @@ -1953,6 +2122,7 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid, stats->exprs = def_names; stats->relations = list_make1(heapRel); stats->stxcomment = NULL; + stats->transformed = true; /* don't need transformStatsStmt again */ stats->if_not_exists = false; /* Clean up */ @@ -2982,24 +3152,6 @@ transformIndexConstraints(CreateStmtContext *cxt) indexlist = lappend(indexlist, index); } - /* Add in any indexes defined by LIKE ... INCLUDING INDEXES */ - foreach(lc, cxt->inh_indexes) - { - index = (IndexStmt *) lfirst(lc); - - if (index->primary) - { - if (cxt->pkey != NULL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("multiple primary keys for table \"%s\" are not allowed", - cxt->relation->relname))); - cxt->pkey = index; - } - - indexlist = lappend(indexlist, index); - } - /* * Scan the index list and remove any redundant index specifications. This * can happen if, for instance, the user writes UNIQUE PRIMARY KEY. A @@ -3705,7 +3857,7 @@ transformFKConstraints(CreateStmtContext *cxt, * Note: the ADD CONSTRAINT command must also execute after any index * creation commands. Thus, this should run after * transformIndexConstraints, so that the CREATE INDEX commands are - * already in cxt->alist. + * already in cxt->alist. See also the handling of cxt->likeclauses. */ if (!isAddConstraint) { @@ -3754,12 +3906,6 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) if (stmt->transformed) return stmt; - /* - * We must not scribble on the passed-in IndexStmt, so copy it. (This is - * overkill, but easy.) - */ - stmt = copyObject(stmt); - /* Set up pstate */ pstate = make_parsestate(NULL); pstate->p_sourcetext = queryString; @@ -3836,6 +3982,78 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) return stmt; } +/* + * transformStatsStmt - parse analysis for CREATE STATISTICS + * + * To avoid race conditions, it's important that this function rely only on + * the passed-in relid (and not on stmt->relation) to determine the target + * relation. + */ +CreateStatsStmt * +transformStatsStmt(Oid relid, CreateStatsStmt *stmt, const char *queryString) +{ + ParseState *pstate; + ParseNamespaceItem *nsitem; + ListCell *l; + Relation rel; + + /* Nothing to do if statement already transformed. */ + if (stmt->transformed) + return stmt; + + /* Set up pstate */ + pstate = make_parsestate(NULL); + pstate->p_sourcetext = queryString; + + /* + * Put the parent table into the rtable so that the expressions can refer + * to its fields without qualification. Caller is responsible for locking + * relation, but we still need to open it. + */ + rel = relation_open(relid, NoLock); + nsitem = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, + NULL, false, true); + + /* no to join list, yes to namespaces */ + addNSItemToQuery(pstate, nsitem, false, true, true); + + /* take care of any expressions */ + foreach(l, stmt->exprs) + { + StatsElem *selem = (StatsElem *) lfirst(l); + + if (selem->expr) + { + /* Now do parse transformation of the expression */ + selem->expr = transformExpr(pstate, selem->expr, + EXPR_KIND_STATS_EXPRESSION); + + /* We have to fix its collations too */ + assign_expr_collations(pstate, selem->expr); + } + } + + /* + * Check that only the base rel is mentioned. (This should be dead code + * now that add_missing_from is history.) + */ + if (list_length(pstate->p_rtable) != 1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg("statistics expressions can refer only to the table being indexed"))); + + free_parsestate(pstate); + + /* Close relation */ + table_close(rel, NoLock); + + /* Mark statement as successfully transformed */ + stmt->transformed = true; + + return stmt; +} + /* * transformRuleStmt - @@ -3845,9 +4063,6 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) * * actions and whereClause are output parameters that receive the * transformed results. - * - * Note that we must not scribble on the passed-in RuleStmt, so we do - * copyObject() on the actions and WHERE clause. */ void transformRuleStmt(RuleStmt *stmt, const char *queryString, @@ -3922,7 +4137,7 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, /* take care of the where clause */ *whereClause = transformWhereClause(pstate, - (Node *) copyObject(stmt->whereClause), + stmt->whereClause, EXPR_KIND_WHERE, "WHERE"); /* we have to fix its collations too */ @@ -3994,8 +4209,7 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, addNSItemToQuery(sub_pstate, newnsitem, false, true, false); /* Transform the rule action statement */ - top_subqry = transformStmt(sub_pstate, - (Node *) copyObject(action)); + top_subqry = transformStmt(sub_pstate, action); /* * We cannot support utility-statement actions (eg NOTIFY) with @@ -4176,12 +4390,6 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, AlterTableCmd *newcmd; ParseNamespaceItem *nsitem; - /* - * We must not scribble on the passed-in AlterTableStmt, so copy it. (This - * is overkill, but easy.) - */ - stmt = copyObject(stmt); - /* Caller is responsible for locking the relation */ rel = relation_open(relid, NoLock); tupdesc = RelationGetDescr(rel); @@ -4219,6 +4427,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, cxt.ixconstraints = NIL; cxt.inh_indexes = NIL; cxt.attr_encodings = NIL; + cxt.likeclauses = NIL; cxt.extstats = NIL; cxt.blist = NIL; cxt.alist = NIL; @@ -5256,7 +5465,7 @@ validateInfiniteBounds(ParseState *pstate, List *blist) } /* - * Transform one constant in a partition bound spec + * Transform one entry in a partition bound spec, producing a constant. */ Const * transformPartitionBoundValue(ParseState *pstate, Node *val, @@ -5269,50 +5478,17 @@ transformPartitionBoundValue(ParseState *pstate, Node *val, value = transformExpr(pstate, val, EXPR_KIND_PARTITION_BOUND); /* - * Check that the input expression's collation is compatible with one - * specified for the parent's partition key (partcollation). Don't throw - * an error if it's the default collation which we'll replace with the - * parent's collation anyway. + * transformExpr() should have already rejected column references, + * subqueries, aggregates, window functions, and SRFs, based on the + * EXPR_KIND_ of a partition bound expression. */ - if (IsA(value, CollateExpr)) - { - Oid exprCollOid = exprCollation(value); - - /* - * Check we have a collation iff it is a collatable type. The only - * expected failures here are (1) COLLATE applied to a noncollatable - * type, or (2) partition bound expression had an unresolved - * collation. But we might as well code this to be a complete - * consistency check. - */ - if (type_is_collatable(colType)) - { - if (!OidIsValid(exprCollOid)) - ereport(ERROR, - (errcode(ERRCODE_INDETERMINATE_COLLATION), - errmsg("could not determine which collation to use for partition bound expression"), - errhint("Use the COLLATE clause to set the collation explicitly."))); - } - else - { - if (OidIsValid(exprCollOid)) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("collations are not supported by type %s", - format_type_be(colType)))); - } - - if (OidIsValid(exprCollOid) && - exprCollOid != DEFAULT_COLLATION_OID && - exprCollOid != partCollation) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"", - colName, get_collation_name(partCollation)), - parser_errposition(pstate, exprLocation(value)))); - } + Assert(!contain_var_clause(value)); - /* Coerce to correct type */ + /* + * Coerce to the correct type. This might cause an explicit coercion step + * to be added on top of the expression, which must be evaluated before + * returning the result to the caller. + */ value = coerce_to_target_type(pstate, value, exprType(value), colType, @@ -5328,25 +5504,36 @@ transformPartitionBoundValue(ParseState *pstate, Node *val, format_type_be(colType), colName), parser_errposition(pstate, exprLocation(val)))); - /* Simplify the expression, in case we had a coercion */ - if (!IsA(value, Const)) - value = (Node *) expression_planner((Expr *) value); - /* - * transformExpr() should have already rejected column references, - * subqueries, aggregates, window functions, and SRFs, based on the - * EXPR_KIND_ for a default expression. + * Evaluate the expression, if needed, assigning the partition key's data + * type and collation to the resulting Const node. */ - Assert(!contain_var_clause(value)); + if (!IsA(value, Const)) + { + assign_expr_collations(pstate, value); + value = (Node *) expression_planner((Expr *) value); + value = (Node *) evaluate_expr((Expr *) value, colType, colTypmod, + partCollation); + if (!IsA(value, Const)) + elog(ERROR, "could not evaluate partition bound expression"); + } + else + { + /* + * If the expression is already a Const, as is often the case, we can + * skip the rather expensive steps above. But we still have to insert + * the right collation, since coerce_to_target_type doesn't handle + * that. + */ + ((Const *) value)->constcollid = partCollation; + } /* - * Evaluate the expression, assigning the partition key's collation to the - * resulting Const expression. + * Attach original expression's parse location to the Const, so that + * that's what will be reported for any later errors related to this + * partition bound. */ - value = (Node *) evaluate_expr((Expr *) value, colType, colTypmod, - partCollation); - if (!IsA(value, Const)) - elog(ERROR, "could not evaluate partition bound expression"); + ((Const *) value)->location = exprLocation(val); return (Const *) value; } diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c index 9783f95b73a7..11c89cb96f90 100644 --- a/src/backend/parser/parser.c +++ b/src/backend/parser/parser.c @@ -10,7 +10,7 @@ * analyze.c and related files. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -36,11 +36,11 @@ static char *str_udeescape(const char *str, char escape, * raw_parser * Given a query in string form, do lexical and grammatical analysis. * - * Returns a list of raw (un-analyzed) parse trees. The immediate elements - * of the list are always RawStmt nodes. + * Returns a list of raw (un-analyzed) parse trees. The contents of the + * list have the form required by the specified RawParseMode. */ List * -raw_parser(const char *str) +raw_parser(const char *str, RawParseMode mode) { core_yyscan_t yyscanner; base_yy_extra_type yyextra; @@ -75,10 +75,37 @@ raw_parser(const char *str) } PG_END_TRY(); - /* base_yylex() only needs this much initialization */ - yyextra.have_lookahead = false; + /* + * GPDB: initialize the lexical tie-in used to recognize a trailing + * PARTITION BY in CREATE TABLE as the PARTITION_TAIL token (see + * base_yylex()). Without this the stack-garbage value can spuriously + * turn a legitimate PARTITION keyword (e.g. a window "OVER (PARTITION + * BY ...)") into PARTITION_TAIL, yielding "syntax error at or near + * PARTITION". + */ yyextra.tail_partition_magic = false; + /* base_yylex() only needs us to initialize the lookahead token, if any */ + if (mode == RAW_PARSE_DEFAULT) + yyextra.have_lookahead = false; + else + { + /* this array is indexed by RawParseMode enum */ + static const int mode_token[] = { + 0, /* RAW_PARSE_DEFAULT */ + MODE_TYPE_NAME, /* RAW_PARSE_TYPE_NAME */ + MODE_PLPGSQL_EXPR, /* RAW_PARSE_PLPGSQL_EXPR */ + MODE_PLPGSQL_ASSIGN1, /* RAW_PARSE_PLPGSQL_ASSIGN1 */ + MODE_PLPGSQL_ASSIGN2, /* RAW_PARSE_PLPGSQL_ASSIGN2 */ + MODE_PLPGSQL_ASSIGN3 /* RAW_PARSE_PLPGSQL_ASSIGN3 */ + }; + + yyextra.have_lookahead = true; + yyextra.lookahead_token = mode_token[mode]; + yyextra.lookahead_yylloc = 0; + yyextra.lookahead_end = NULL; + } + /* initialize the bison parser */ parser_init(&yyextra); @@ -131,7 +158,8 @@ base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, core_yyscan_t yyscanner) cur_token = yyextra->lookahead_token; lvalp->core_yystype = yyextra->lookahead_yylval; *llocp = yyextra->lookahead_yylloc; - *(yyextra->lookahead_end) = yyextra->lookahead_hold_char; + if (yyextra->lookahead_end) + *(yyextra->lookahead_end) = yyextra->lookahead_hold_char; yyextra->have_lookahead = false; } else diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 50ba68abd4f5..253d3a61192d 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -22,7 +22,7 @@ * Postgres 9.2, this check is made automatically by the Makefile.) * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -73,7 +73,7 @@ bool standard_conforming_strings = true; * callers need to pass it to scanner_init, if they are using the * standard keyword list ScanKeywords. */ -#define PG_KEYWORD(kwname, value, category) value, +#define PG_KEYWORD(kwname, value, category, collabel) value, const uint16 ScanKeywordTokens[] = { #include "parser/kwlist.h" diff --git a/src/backend/parser/scansup.c b/src/backend/parser/scansup.c index cac70d5df7af..f55caccddfda 100644 --- a/src/backend/parser/scansup.c +++ b/src/backend/parser/scansup.c @@ -1,10 +1,9 @@ /*------------------------------------------------------------------------- * * scansup.c - * support routines for the lex/flex scanner, used by both the normal - * backend as well as the bootstrap backend + * scanner support routines used by the core lexer * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,98 +19,6 @@ #include "mb/pg_wchar.h" #include "parser/scansup.h" -/* ---------------- - * scanstr - * - * if the string passed in has escaped codes, map the escape codes to actual - * chars - * - * the string returned is palloc'd and should eventually be pfree'd by the - * caller! - * ---------------- - */ - -char * -scanstr(const char *s) -{ - char *newStr; - int len, - i, - j; - - if (s == NULL || s[0] == '\0') - return pstrdup(""); - - len = strlen(s); - - newStr = palloc(len + 1); /* string cannot get longer */ - - for (i = 0, j = 0; i < len; i++) - { - if (s[i] == '\'') - { - /* - * Note: if scanner is working right, unescaped quotes can only - * appear in pairs, so there should be another character. - */ - i++; - /* The bootstrap parser is not as smart, so check here. */ - Assert(s[i] == '\''); - newStr[j] = s[i]; - } - else if (s[i] == '\\') - { - i++; - switch (s[i]) - { - case 'b': - newStr[j] = '\b'; - break; - case 'f': - newStr[j] = '\f'; - break; - case 'n': - newStr[j] = '\n'; - break; - case 'r': - newStr[j] = '\r'; - break; - case 't': - newStr[j] = '\t'; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - int k; - long octVal = 0; - - for (k = 0; - s[i + k] >= '0' && s[i + k] <= '7' && k < 3; - k++) - octVal = (octVal << 3) + (s[i + k] - '0'); - i += k - 1; - newStr[j] = ((char) octVal); - } - break; - default: - newStr[j] = s[i]; - break; - } /* switch */ - } /* s[i] == '\\' */ - else - newStr[j] = s[i]; - j++; - } - newStr[j] = '\0'; - return newStr; -} - /* * downcase_truncate_identifier() --- do appropriate downcasing and diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index b36de561ff36..e2737335324e 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -3,7 +3,7 @@ * partbounds.c * Support routines for manipulating partition bounds * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -223,8 +223,7 @@ static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, - PartitionRangeBound *probe, bool *is_equal); -static int get_partition_bound_num_indexes(PartitionBoundInfo b); + PartitionRangeBound *probe, int32 *cmpval); static Expr *make_partition_op_expr(PartitionKey key, int keynum, uint16 strategy, Expr *arg1, Expr *arg2); static Oid get_partition_operator(PartitionKey key, int col, @@ -398,6 +397,7 @@ create_hash_bounds(PartitionBoundSpec **boundspecs, int nparts, boundinfo->ndatums = ndatums; boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); + boundinfo->nindexes = greatest_modulus; boundinfo->indexes = (int *) palloc(greatest_modulus * sizeof(int)); for (i = 0; i < greatest_modulus; i++) boundinfo->indexes[i] = -1; @@ -530,6 +530,7 @@ create_list_bounds(PartitionBoundSpec **boundspecs, int nparts, boundinfo->ndatums = ndatums; boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); + boundinfo->nindexes = ndatums; boundinfo->indexes = (int *) palloc(ndatums * sizeof(int)); /* @@ -725,8 +726,9 @@ create_range_bounds(PartitionBoundSpec **boundspecs, int nparts, /* * For range partitioning, an additional value of -1 is stored as the last - * element. + * element of the indexes[] array. */ + boundinfo->nindexes = ndatums + 1; boundinfo->indexes = (int *) palloc((ndatums + 1) * sizeof(int)); for (i = 0; i < ndatums; i++) @@ -807,45 +809,41 @@ partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, if (b1->ndatums != b2->ndatums) return false; + if (b1->nindexes != b2->nindexes) + return false; + if (b1->null_index != b2->null_index) return false; if (b1->default_index != b2->default_index) return false; - if (b1->strategy == PARTITION_STRATEGY_HASH) + /* For all partition strategies, the indexes[] arrays have to match */ + for (i = 0; i < b1->nindexes; i++) { - int greatest_modulus = get_hash_partition_greatest_modulus(b1); - - /* - * If two hash partitioned tables have different greatest moduli, - * their partition schemes don't match. - */ - if (greatest_modulus != get_hash_partition_greatest_modulus(b2)) + if (b1->indexes[i] != b2->indexes[i]) return false; + } + /* Finally, compare the datums[] arrays */ + if (b1->strategy == PARTITION_STRATEGY_HASH) + { /* * We arrange the partitions in the ascending order of their moduli * and remainders. Also every modulus is factor of next larger * modulus. Therefore we can safely store index of a given partition * in indexes array at remainder of that partition. Also entries at * (remainder + N * modulus) positions in indexes array are all same - * for (modulus, remainder) specification for any partition. Thus - * datums array from both the given bounds are same, if and only if - * their indexes array will be same. So, it suffices to compare - * indexes array. - */ - for (i = 0; i < greatest_modulus; i++) - if (b1->indexes[i] != b2->indexes[i]) - return false; - -#ifdef USE_ASSERT_CHECKING - - /* - * Nonetheless make sure that the bounds are indeed same when the + * for (modulus, remainder) specification for any partition. Thus the + * datums arrays from the given bounds are the same, if and only if + * their indexes arrays are the same. So, it suffices to compare the + * indexes arrays. + * + * Nonetheless make sure that the bounds are indeed the same when the * indexes match. Hash partition bound stores modulus and remainder * at b1->datums[i][0] and b1->datums[i][1] position respectively. */ +#ifdef USE_ASSERT_CHECKING for (i = 0; i < b1->ndatums; i++) Assert((b1->datums[i][0] == b2->datums[i][0] && b1->datums[i][1] == b2->datums[i][1])); @@ -891,15 +889,7 @@ partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, parttypbyval[j], parttyplen[j])) return false; } - - if (b1->indexes[i] != b2->indexes[i]) - return false; } - - /* There are ndatums+1 indexes in case of range partitions */ - if (b1->strategy == PARTITION_STRATEGY_RANGE && - b1->indexes[i] != b2->indexes[i]) - return false; } return true; } @@ -920,8 +910,8 @@ partition_bounds_copy(PartitionBoundInfo src, PartitionBoundInfo dest; int i; int ndatums; + int nindexes; int partnatts; - int num_indexes; bool hash_part; int natts; @@ -929,10 +919,9 @@ partition_bounds_copy(PartitionBoundInfo src, dest->strategy = src->strategy; ndatums = dest->ndatums = src->ndatums; + nindexes = dest->nindexes = src->nindexes; partnatts = key->partnatts; - num_indexes = get_partition_bound_num_indexes(src); - /* List partitioned tables have only a single partition key. */ Assert(key->strategy != PARTITION_STRATEGY_LIST || partnatts == 1); @@ -990,8 +979,8 @@ partition_bounds_copy(PartitionBoundInfo src, } } - dest->indexes = (int *) palloc(sizeof(int) * num_indexes); - memcpy(dest->indexes, src->indexes, sizeof(int) * num_indexes); + dest->indexes = (int *) palloc(sizeof(int) * nindexes); + memcpy(dest->indexes, src->indexes, sizeof(int) * nindexes); dest->null_index = src->null_index; dest->default_index = src->default_index; @@ -1020,8 +1009,6 @@ partition_bounds_merge(int partnatts, JoinType jointype, List **outer_parts, List **inner_parts) { - PartitionBoundInfo outer_binfo = outer_rel->boundinfo; - /* * Currently, this function is called only from try_partitionwise_join(), * so the join type should be INNER, LEFT, FULL, SEMI, or ANTI. @@ -1031,10 +1018,10 @@ partition_bounds_merge(int partnatts, jointype == JOIN_ANTI); /* The partitioning strategies should be the same. */ - Assert(outer_binfo->strategy == inner_rel->boundinfo->strategy); + Assert(outer_rel->boundinfo->strategy == inner_rel->boundinfo->strategy); *outer_parts = *inner_parts = NIL; - switch (outer_binfo->strategy) + switch (outer_rel->boundinfo->strategy) { case PARTITION_STRATEGY_HASH: @@ -1075,7 +1062,7 @@ partition_bounds_merge(int partnatts, default: elog(ERROR, "unexpected partition strategy: %d", - (int) outer_binfo->strategy); + (int) outer_rel->boundinfo->strategy); return NULL; /* keep compiler quiet */ } } @@ -1528,7 +1515,7 @@ merge_range_bounds(int partnatts, FmgrInfo *partsupfuncs, &next_index); Assert(merged_index >= 0); - /* Get the range of the merged partition. */ + /* Get the range bounds of the merged partition. */ get_merged_range_bounds(partnatts, partsupfuncs, partcollations, jointype, &outer_lb, &outer_ub, @@ -1785,7 +1772,7 @@ merge_matching_partitions(PartitionMap *outer_map, PartitionMap *inner_map, if (outer_merged_index >= 0 && inner_merged_index >= 0) { /* - * If the mereged partitions are the same, no need to do anything; + * If the merged partitions are the same, no need to do anything; * return the index of the merged partitions. Otherwise, if each of * the given partitions has been merged with a dummy partition on the * other side, re-map them to either of the two merged partitions. @@ -1833,7 +1820,7 @@ merge_matching_partitions(PartitionMap *outer_map, PartitionMap *inner_map, /* * If neither of them has been merged, merge them. Otherwise, if one has - * been merged with a dummy relation on the other side (and the other + * been merged with a dummy partition on the other side (and the other * hasn't yet been merged with anything), re-merge them. Otherwise, they * can't be merged, so return -1. */ @@ -2458,6 +2445,7 @@ build_merged_partition_bounds(char strategy, List *merged_datums, } Assert(list_length(merged_indexes) == ndatums); + merged_bounds->nindexes = ndatums; merged_bounds->indexes = (int *) palloc(sizeof(int) * ndatums); pos = 0; foreach(lc, merged_indexes) @@ -2705,10 +2693,10 @@ add_merged_range_bounds(int partnatts, FmgrInfo *partsupfuncs, prev_ub.lower = false; /* - * We pass to partition_rbound_cmp() lower1 as false to prevent it - * from considering the last upper bound to be smaller than the lower - * bound of the merged partition when the values of the two range - * bounds compare equal. + * We pass lower1 = false to partition_rbound_cmp() to prevent it from + * considering the last upper bound to be smaller than the lower bound + * of the merged partition when the values of the two range bounds + * compare equal. */ cmpval = partition_rbound_cmp(partnatts, partsupfuncs, partcollations, merged_lb->datums, merged_lb->kind, @@ -2807,14 +2795,14 @@ partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts) */ void check_new_partition_bound(char *relname, Relation parent, - PartitionBoundSpec *spec) + PartitionBoundSpec *spec, ParseState *pstate) { PartitionKey key = RelationGetPartitionKey(parent); - PartitionDesc partdesc = RelationGetPartitionDesc(parent); + PartitionDesc partdesc = RelationGetPartitionDesc(parent, false); PartitionBoundInfo boundinfo = partdesc->boundinfo; - ParseState *pstate = make_parsestate(NULL); int with = -1; bool overlap = false; + int overlap_location = -1; if (spec->is_default) { @@ -2844,14 +2832,9 @@ check_new_partition_bound(char *relname, Relation parent, if (partdesc->nparts > 0) { - Datum **datums = boundinfo->datums; - int ndatums = boundinfo->ndatums; int greatest_modulus; int remainder; int offset; - bool valid_modulus = true; - int prev_modulus, /* Previous largest modulus */ - next_modulus; /* Next largest modulus */ /* * Check rule that every modulus must be a factor of the @@ -2861,7 +2844,9 @@ check_new_partition_bound(char *relname, Relation parent, * modulus 15, but you cannot add both a partition with * modulus 10 and a partition with modulus 15, because 10 * is not a factor of 15. - * + */ + + /* * Get the greatest (modulus, remainder) pair contained in * boundinfo->datums that is less than or equal to the * (spec->modulus, spec->remainder) pair. @@ -2871,27 +2856,59 @@ check_new_partition_bound(char *relname, Relation parent, spec->remainder); if (offset < 0) { - next_modulus = DatumGetInt32(datums[0][0]); - valid_modulus = (next_modulus % spec->modulus) == 0; + int next_modulus; + + /* + * All existing moduli are greater or equal, so the + * new one must be a factor of the smallest one, which + * is first in the boundinfo. + */ + next_modulus = DatumGetInt32(boundinfo->datums[0][0]); + if (next_modulus % spec->modulus != 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("every hash partition modulus must be a factor of the next larger modulus"), + errdetail("The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\".", + spec->modulus, next_modulus, + get_rel_name(partdesc->oids[boundinfo->indexes[0]])))); } else { - prev_modulus = DatumGetInt32(datums[offset][0]); - valid_modulus = (spec->modulus % prev_modulus) == 0; + int prev_modulus; + + /* + * We found the largest modulus less than or equal to + * ours. + */ + prev_modulus = DatumGetInt32(boundinfo->datums[offset][0]); + + if (spec->modulus % prev_modulus != 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("every hash partition modulus must be a factor of the next larger modulus"), + errdetail("The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\".", + spec->modulus, + prev_modulus, + get_rel_name(partdesc->oids[boundinfo->indexes[offset]])))); - if (valid_modulus && (offset + 1) < ndatums) + if (offset + 1 < boundinfo->ndatums) { - next_modulus = DatumGetInt32(datums[offset + 1][0]); - valid_modulus = (next_modulus % spec->modulus) == 0; + int next_modulus; + + /* Look at the next higher modulus */ + next_modulus = DatumGetInt32(boundinfo->datums[offset + 1][0]); + + if (next_modulus % spec->modulus != 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("every hash partition modulus must be a factor of the next larger modulus"), + errdetail("The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\".", + spec->modulus, next_modulus, + get_rel_name(partdesc->oids[boundinfo->indexes[offset + 1]])))); } } - if (!valid_modulus) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("every hash partition modulus must be a factor of the next larger modulus"))); - - greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); + greatest_modulus = boundinfo->nindexes; remainder = spec->remainder; /* @@ -2909,6 +2926,7 @@ check_new_partition_bound(char *relname, Relation parent, if (boundinfo->indexes[remainder] != -1) { overlap = true; + overlap_location = spec->location; with = boundinfo->indexes[remainder]; break; } @@ -2938,6 +2956,7 @@ check_new_partition_bound(char *relname, Relation parent, { Const *val = castNode(Const, lfirst(cell)); + overlap_location = val->location; if (!val->constisnull) { int offset; @@ -2971,6 +2990,7 @@ check_new_partition_bound(char *relname, Relation parent, { PartitionRangeBound *lower, *upper; + int cmpval; Assert(spec->strategy == PARTITION_STRATEGY_RANGE); lower = make_one_partition_rbound(key, -1, spec->lowerdatums, true); @@ -2978,12 +2998,22 @@ check_new_partition_bound(char *relname, Relation parent, /* * First check if the resulting range would be empty with - * specified lower and upper bounds + * specified lower and upper bounds. partition_rbound_cmp + * cannot return zero here, since the lower-bound flags are + * different. */ - if (partition_rbound_cmp(key->partnatts, key->partsupfunc, - key->partcollation, lower->datums, - lower->kind, true, upper) >= 0) + cmpval = partition_rbound_cmp(key->partnatts, + key->partsupfunc, + key->partcollation, + lower->datums, lower->kind, + true, upper); + Assert(cmpval != 0); + if (cmpval > 0) { + /* Point to problematic key in the lower datums list. */ + PartitionRangeDatum *datum = list_nth(spec->lowerdatums, + cmpval - 1); + ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("empty range bound specified for partition \"%s\"", @@ -2991,13 +3021,12 @@ check_new_partition_bound(char *relname, Relation parent, errdetail("Specified lower bound %s is greater than or equal to upper bound %s.", get_range_partbound_string(spec->lowerdatums), get_range_partbound_string(spec->upperdatums)), - parser_errposition(pstate, spec->location))); + parser_errposition(pstate, datum->location))); } if (partdesc->nparts > 0) { int offset; - bool equal; Assert(boundinfo && boundinfo->strategy == PARTITION_STRATEGY_RANGE && @@ -3023,7 +3052,7 @@ check_new_partition_bound(char *relname, Relation parent, key->partsupfunc, key->partcollation, boundinfo, lower, - &equal); + &cmpval); if (boundinfo->indexes[offset + 1] < 0) { @@ -3035,7 +3064,6 @@ check_new_partition_bound(char *relname, Relation parent, */ if (offset + 1 < boundinfo->ndatums) { - int32 cmpval; Datum *datums; PartitionRangeDatumKind *kind; bool is_lower; @@ -3051,12 +3079,20 @@ check_new_partition_bound(char *relname, Relation parent, is_lower, upper); if (cmpval < 0) { + /* + * Point to problematic key in the upper + * datums list. + */ + PartitionRangeDatum *datum = + list_nth(spec->upperdatums, Abs(cmpval) - 1); + /* * The new partition overlaps with the * existing partition between offset + 1 and * offset + 2. */ overlap = true; + overlap_location = datum->location; with = boundinfo->indexes[offset + 2]; } } @@ -3067,7 +3103,16 @@ check_new_partition_bound(char *relname, Relation parent, * The new partition overlaps with the existing * partition between offset and offset + 1. */ + PartitionRangeDatum *datum; + + /* + * Point to problematic key in the lower datums list; + * if we have equality, point to the first one. + */ + datum = cmpval == 0 ? linitial(spec->lowerdatums) : + list_nth(spec->lowerdatums, Abs(cmpval) - 1); overlap = true; + overlap_location = datum->location; with = boundinfo->indexes[offset + 1]; } } @@ -3087,7 +3132,7 @@ check_new_partition_bound(char *relname, Relation parent, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("partition \"%s\" would overlap partition \"%s\"", relname, get_rel_name(partdesc->oids[with])), - parser_errposition(pstate, spec->location))); + parser_errposition(pstate, overlap_location))); } } @@ -3129,8 +3174,8 @@ check_default_partition_contents(Relation parent, Relation default_rel, if (PartConstraintImpliedByRelConstraint(default_rel, def_part_constraints)) { ereport(DEBUG1, - (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", - RelationGetRelationName(default_rel)))); + (errmsg_internal("updated partition constraint for default partition \"%s\" is implied by existing constraints", + RelationGetRelationName(default_rel)))); return; } @@ -3180,8 +3225,8 @@ check_default_partition_contents(Relation parent, Relation default_rel, def_part_constraints)) { ereport(DEBUG1, - (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", - RelationGetRelationName(part_rel)))); + (errmsg_internal("updated partition constraint for default partition \"%s\" is implied by existing constraints", + RelationGetRelationName(part_rel)))); table_close(part_rel, NoLock); continue; @@ -3257,18 +3302,15 @@ check_default_partition_contents(Relation parent, Relation default_rel, /* * get_hash_partition_greatest_modulus * - * Returns the greatest modulus of the hash partition bound. The greatest - * modulus will be at the end of the datums array because hash partitions are - * arranged in the ascending order of their moduli and remainders. + * Returns the greatest modulus of the hash partition bound. + * This is no longer used in the core code, but we keep it around + * in case external modules are using it. */ int get_hash_partition_greatest_modulus(PartitionBoundInfo bound) { Assert(bound && bound->strategy == PARTITION_STRATEGY_HASH); - Assert(bound->datums && bound->ndatums > 0); - Assert(DatumGetInt32(bound->datums[bound->ndatums - 1][0]) > 0); - - return DatumGetInt32(bound->datums[bound->ndatums - 1][0]); + return bound->nindexes; } /* @@ -3320,8 +3362,12 @@ make_one_partition_rbound(PartitionKey key, int index, List *datums, bool lower) /* * partition_rbound_cmp * - * Return for two range bounds whether the 1st one (specified in datums1, - * kind1, and lower1) is <, =, or > the bound specified in *b2. + * For two range bounds this decides whether the 1st one (specified by + * datums1, kind1, and lower1) is <, =, or > the bound specified in *b2. + * + * 0 is returned if they are equal, otherwise a non-zero integer whose sign + * indicates the ordering, and whose absolute value gives the 1-based + * partition key number of the first mismatching column. * * partnatts, partsupfunc and partcollation give the number of attributes in the * bounds to be compared, comparison function to be used and the collations of @@ -3340,6 +3386,7 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, Datum *datums1, PartitionRangeDatumKind *kind1, bool lower1, PartitionRangeBound *b2) { + int32 colnum = 0; int32 cmpval = 0; /* placate compiler */ int i; Datum *datums2 = b2->datums; @@ -3348,6 +3395,9 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, for (i = 0; i < partnatts; i++) { + /* Track column number in case we need it for result */ + colnum++; + /* * First, handle cases where the column is unbounded, which should not * invoke the comparison procedure, and should not consider any later @@ -3355,17 +3405,18 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, * compare the same way as the values they represent. */ if (kind1[i] < kind2[i]) - return -1; + return -colnum; else if (kind1[i] > kind2[i]) - return 1; + return colnum; else if (kind1[i] != PARTITION_RANGE_DATUM_VALUE) - + { /* * The column bounds are both MINVALUE or both MAXVALUE. No later * columns should be considered, but we still need to compare * whether they are upper or lower bounds. */ break; + } cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i], partcollation[i], @@ -3384,7 +3435,7 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, if (cmpval == 0 && lower1 != lower2) cmpval = lower1 ? 1 : -1; - return cmpval; + return cmpval == 0 ? 0 : (cmpval < 0 ? -colnum : colnum); } /* @@ -3396,7 +3447,6 @@ partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, * n_tuple_datums, partsupfunc and partcollation give number of attributes in * the bounds to be compared, comparison function to be used and the collations * of attributes resp. - * */ int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, @@ -3489,14 +3539,17 @@ partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, * equal to the given range bound or -1 if all of the range bounds are * greater * - * *is_equal is set to true if the range bound at the returned index is equal - * to the input range bound + * Upon return from this function, *cmpval is set to 0 if the bound at the + * returned index matches the input range bound exactly, otherwise a + * non-zero integer whose sign indicates the ordering, and whose absolute + * value gives the 1-based partition key number of the first mismatching + * column. */ static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, - PartitionRangeBound *probe, bool *is_equal) + PartitionRangeBound *probe, int32 *cmpval) { int lo, hi, @@ -3506,21 +3559,17 @@ partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, hi = boundinfo->ndatums - 1; while (lo < hi) { - int32 cmpval; - mid = (lo + hi + 1) / 2; - cmpval = partition_rbound_cmp(partnatts, partsupfunc, - partcollation, - boundinfo->datums[mid], - boundinfo->kind[mid], - (boundinfo->indexes[mid] == -1), - probe); - if (cmpval <= 0) + *cmpval = partition_rbound_cmp(partnatts, partsupfunc, + partcollation, + boundinfo->datums[mid], + boundinfo->kind[mid], + (boundinfo->indexes[mid] == -1), + probe); + if (*cmpval <= 0) { lo = mid; - *is_equal = (cmpval == 0); - - if (*is_equal) + if (*cmpval == 0) break; } else @@ -3531,7 +3580,7 @@ partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, } /* - * partition_range_bsearch + * partition_range_datum_bsearch * Returns the index of the greatest range bound that is less than or * equal to the given tuple or -1 if all of the range bounds are greater * @@ -3660,49 +3709,9 @@ qsort_partition_rbound_cmp(const void *a, const void *b, void *arg) PartitionRangeBound *b2 = (*(PartitionRangeBound *const *) b); PartitionKey key = (PartitionKey) arg; - return partition_rbound_cmp(key->partnatts, key->partsupfunc, - key->partcollation, b1->datums, b1->kind, - b1->lower, b2); -} - -/* - * get_partition_bound_num_indexes - * - * Returns the number of the entries in the partition bound indexes array. - */ -static int -get_partition_bound_num_indexes(PartitionBoundInfo bound) -{ - int num_indexes; - - Assert(bound); - - switch (bound->strategy) - { - case PARTITION_STRATEGY_HASH: - - /* - * The number of the entries in the indexes array is same as the - * greatest modulus. - */ - num_indexes = get_hash_partition_greatest_modulus(bound); - break; - - case PARTITION_STRATEGY_LIST: - num_indexes = bound->ndatums; - break; - - case PARTITION_STRATEGY_RANGE: - /* Range partitioned table has an extra index. */ - num_indexes = bound->ndatums + 1; - break; - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) bound->strategy); - } - - return num_indexes; + return compare_range_bounds(key->partnatts, key->partsupfunc, + key->partcollation, + b1, b2); } /* @@ -3807,6 +3816,7 @@ make_partition_op_expr(PartitionKey key, int keynum, saopexpr = makeNode(ScalarArrayOpExpr); saopexpr->opno = operoid; saopexpr->opfuncid = get_opcode(operoid); + saopexpr->hashfuncid = InvalidOid; saopexpr->useOr = true; saopexpr->inputcollid = key->partcollation[keynum]; saopexpr->args = list_make2(arg1, arrexpr); @@ -3985,7 +3995,7 @@ get_qual_for_list(Relation parent, PartitionBoundSpec *spec) { int i; int ndatums = 0; - PartitionDesc pdesc = RelationGetPartitionDesc(parent); + PartitionDesc pdesc = RelationGetPartitionDesc(parent, false); PartitionBoundInfo boundinfo = pdesc->boundinfo; if (boundinfo) @@ -4062,7 +4072,7 @@ get_qual_for_list(Relation parent, PartitionBoundSpec *spec) if (!list_has_null) { /* - * Gin up a "col IS NOT NULL" test that will be AND'd with the main + * Gin up a "col IS NOT NULL" test that will be ANDed with the main * expression. This might seem redundant, but the partition routing * machinery needs it. */ @@ -4185,7 +4195,7 @@ get_qual_for_range(Relation parent, PartitionBoundSpec *spec, if (spec->is_default) { List *or_expr_args = NIL; - PartitionDesc pdesc = RelationGetPartitionDesc(parent); + PartitionDesc pdesc = RelationGetPartitionDesc(parent, false); Oid *inhoids = pdesc->oids; int nparts = pdesc->nparts, i; @@ -4260,10 +4270,6 @@ get_qual_for_range(Relation parent, PartitionBoundSpec *spec, return result; } - lower_or_start_datum = list_head(spec->lowerdatums); - upper_or_start_datum = list_head(spec->upperdatums); - num_or_arms = key->partnatts; - /* * If it is the recursive call for default, we skip the get_range_nulltest * to avoid accumulating the NullTest on the same keys for each partition. @@ -4656,6 +4662,8 @@ compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, Oid *partcoll * * Returns true if remainder produced when this computed single hash value is * divided by the given modulus is equal to given remainder, otherwise false. + * NB: it's important that this never return null, as the constraint machinery + * would consider that to be a "pass". * * See get_qual_for_hash() for usage. */ @@ -4680,9 +4688,9 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) ColumnsHashData *my_extra; uint64 rowHash = 0; - /* Return null if the parent OID, modulus, or remainder is NULL. */ + /* Return false if the parent OID, modulus, or remainder is NULL. */ if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) - PG_RETURN_NULL(); + PG_RETURN_BOOL(false); parentId = PG_GETARG_OID(0); modulus = PG_GETARG_INT32(1); remainder = PG_GETARG_INT32(2); @@ -4718,8 +4726,7 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) key = RelationGetPartitionKey(parent); /* Reject parent table that is not hash-partitioned. */ - if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE || - key->strategy != PARTITION_STRATEGY_HASH) + if (key == NULL || key->strategy != PARTITION_STRATEGY_HASH) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("\"%s\" is not a hash partitioned table", @@ -4755,7 +4762,7 @@ satisfies_hash_partition(PG_FUNCTION_ARGS) if (argtype != key->parttypid[j] && !IsBinaryCoercible(argtype, key->parttypid[j])) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"", + errmsg("column %d of the partition key has type %s, but supplied value is of type %s", j + 1, format_type_be(key->parttypid[j]), format_type_be(argtype)))); fmgr_info_copy(&my_extra->partsupfunc[j], diff --git a/src/backend/partitioning/partdesc.c b/src/backend/partitioning/partdesc.c index d21b5ecd238e..a71074639b30 100644 --- a/src/backend/partitioning/partdesc.c +++ b/src/backend/partitioning/partdesc.c @@ -3,7 +3,7 @@ * partdesc.c * Support routines for manipulating partition descriptors * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,7 +17,6 @@ #include "access/genam.h" #include "access/htup_details.h" #include "access/table.h" -#include "catalog/indexing.h" #include "catalog/partition.h" #include "catalog/pg_inherits.h" #include "partitioning/partbounds.h" @@ -38,6 +37,7 @@ typedef struct PartitionDirectoryData { MemoryContext pdir_mcxt; HTAB *pdir_hash; + bool omit_detached; } PartitionDirectoryData; typedef struct PartitionDirectoryEntry @@ -47,12 +47,19 @@ typedef struct PartitionDirectoryEntry PartitionDesc pd; } PartitionDirectoryEntry; -static void RelationBuildPartitionDesc(Relation rel); +static PartitionDesc RelationBuildPartitionDesc(Relation rel, + bool omit_detached); /* * RelationGetPartitionDesc -- get partition descriptor, if relation is partitioned * + * We keep two partdescs in relcache: rd_partdesc includes all partitions + * (even those being concurrently marked detached), while rd_partdesc_nodetach + * omits (some of) those. We store the pg_inherits.xmin value for the latter, + * to determine whether it can be validly reused in each case, since that + * depends on the active snapshot. + * * Note: we arrange for partition descriptors to not get freed until the * relcache entry's refcount goes to zero (see hacks in RelationClose, * RelationClearRelation, and RelationBuildPartitionDesc). Therefore, even @@ -62,15 +69,50 @@ static void RelationBuildPartitionDesc(Relation rel); * that the data doesn't become stale. */ PartitionDesc -RelationGetPartitionDesc(Relation rel) +RelationGetPartitionDesc(Relation rel, bool omit_detached) { - if (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) - return NULL; + Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); + + /* + * If relcache has a partition descriptor, use that. However, we can only + * do so when we are asked to include all partitions including detached; + * and also when we know that there are no detached partitions. + * + * If there is no active snapshot, detached partitions aren't omitted + * either, so we can use the cached descriptor too in that case. + */ + if (likely(rel->rd_partdesc && + (!rel->rd_partdesc->detached_exist || !omit_detached || + !ActiveSnapshotSet()))) + return rel->rd_partdesc; + + /* + * If we're asked to omit detached partitions, we may be able to use a + * cached descriptor too. We determine that based on the pg_inherits.xmin + * that was saved alongside that descriptor: if the xmin that was not in + * progress for that active snapshot is also not in progress for the + * current active snapshot, then we can use use it. Otherwise build one + * from scratch. + */ + if (omit_detached && + rel->rd_partdesc_nodetached && + ActiveSnapshotSet()) + { + Snapshot activesnap; + bool setDistributedSnapshotIgnore = false; + XidInMVCCSnapshotCheckResult snapshotCheckResult; + + Assert(TransactionIdIsValid(rel->rd_partdesc_nodetached_xmin)); + activesnap = GetActiveSnapshot(); - if (unlikely(rel->rd_partdesc == NULL)) - RelationBuildPartitionDesc(rel); + snapshotCheckResult = XidInMVCCSnapshot(rel->rd_partdesc_nodetached_xmin, activesnap, + false, &setDistributedSnapshotIgnore); + + if (snapshotCheckResult != XID_IN_SNAPSHOT) + return rel->rd_partdesc_nodetached; + } - return rel->rd_partdesc; + return RelationBuildPartitionDesc(rel, omit_detached); } /* @@ -87,9 +129,15 @@ RelationGetPartitionDesc(Relation rel) * context the current context except in very brief code sections, out of fear * that some of our callees allocate memory on their own which would be leaked * permanently. + * + * As a special case, partition descriptors that are requested to omit + * partitions being detached (and which contain such partitions) are transient + * and are not associated with the relcache entry. Such descriptors only last + * through the requesting Portal, so we use the corresponding memory context + * for them. */ -static void -RelationBuildPartitionDesc(Relation rel) +static PartitionDesc +RelationBuildPartitionDesc(Relation rel, bool omit_detached) { PartitionDesc partdesc; PartitionBoundInfo boundinfo = NULL; @@ -97,6 +145,9 @@ RelationBuildPartitionDesc(Relation rel) PartitionBoundSpec **boundspecs = NULL; Oid *oids = NULL; bool *is_leaf = NULL; + bool detached_exist; + bool is_omit; + TransactionId detached_xmin; ListCell *cell; int i, nparts; @@ -133,7 +184,13 @@ RelationBuildPartitionDesc(Relation rel) * concurrently, whatever this function returns will be accurate as of * some well-defined point in time. */ - inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock); + detached_exist = false; + detached_xmin = InvalidTransactionId; + inhoids = find_inheritance_children_extended(RelationGetRelid(rel), + omit_detached, NoLock, + &detached_exist, + &detached_xmin); + nparts = list_length(inhoids); /* Allocate working arrays for OIDs, leaf flags, and boundspecs. */ @@ -256,6 +313,7 @@ RelationBuildPartitionDesc(Relation rel) partdesc = (PartitionDescData *) MemoryContextAllocZero(new_pdcxt, sizeof(PartitionDescData)); partdesc->nparts = nparts; + partdesc->detached_exist = detached_exist; /* If there are no partitions, the rest of the partdesc can stay zero */ if (nparts > 0) { @@ -286,25 +344,62 @@ RelationBuildPartitionDesc(Relation rel) } /* - * We have a fully valid partdesc ready to store into the relcache. - * Reparent it so it has the right lifespan. + * Are we working with the partdesc that omits the detached partition, or + * the one that includes it? + * + * Note that if a partition was found by the catalog's scan to have been + * detached, but the pg_inherit tuple saying so was not visible to the + * active snapshot (find_inheritance_children_extended will not have set + * detached_xmin in that case), we consider there to be no "omittable" + * detached partitions. + */ + is_omit = omit_detached && detached_exist && ActiveSnapshotSet() && + TransactionIdIsValid(detached_xmin); + + /* + * We have a fully valid partdesc. Reparent it so that it has the right + * lifespan. */ MemoryContextSetParent(new_pdcxt, CacheMemoryContext); /* - * But first, a kluge: if there's an old rd_pdcxt, it contains an old - * partition descriptor that may still be referenced somewhere. Preserve - * it, while not leaking it, by reattaching it as a child context of the - * new rd_pdcxt. Eventually it will get dropped by either RelationClose - * or RelationClearRelation. + * Store it into relcache. + * + * But first, a kluge: if there's an old context for this type of + * descriptor, it contains an old partition descriptor that may still be + * referenced somewhere. Preserve it, while not leaking it, by + * reattaching it as a child context of the new one. Eventually it will + * get dropped by either RelationClose or RelationClearRelation. (We keep + * the regular partdesc in rd_pdcxt, and the partdesc-excluding- + * detached-partitions in rd_pddcxt.) */ - if (rel->rd_pdcxt != NULL) - MemoryContextSetParent(rel->rd_pdcxt, new_pdcxt); - rel->rd_pdcxt = new_pdcxt; - rel->rd_partdesc = partdesc; - /* Return to caller's context, and blow away the temporary context. */ - MemoryContextSwitchTo(oldcxt); - MemoryContextDelete(rbcontext); + if (is_omit) + { + if (rel->rd_pddcxt != NULL) + MemoryContextSetParent(rel->rd_pddcxt, new_pdcxt); + rel->rd_pddcxt = new_pdcxt; + rel->rd_partdesc_nodetached = partdesc; + + /* + * For partdescs built excluding detached partitions, which we save + * separately, we also record the pg_inherits.xmin of the detached + * partition that was omitted; this informs a future potential user of + * such a cached partdesc to only use it after cross-checking that the + * xmin is indeed visible to the snapshot it is going to be working + * with. + */ + Assert(TransactionIdIsValid(detached_xmin)); + rel->rd_partdesc_nodetached_xmin = detached_xmin; + } + else + { + if (rel->rd_pdcxt != NULL) + MemoryContextSetParent(rel->rd_pdcxt, new_pdcxt); + rel->rd_pdcxt = new_pdcxt; + rel->rd_partdesc = partdesc; + } + + return partdesc; } /* @@ -312,21 +407,22 @@ RelationBuildPartitionDesc(Relation rel) * Create a new partition directory object. */ PartitionDirectory -CreatePartitionDirectory(MemoryContext mcxt) +CreatePartitionDirectory(MemoryContext mcxt, bool omit_detached) { MemoryContext oldcontext = MemoryContextSwitchTo(mcxt); PartitionDirectory pdir; HASHCTL ctl; - MemSet(&ctl, 0, sizeof(HASHCTL)); + pdir = palloc(sizeof(PartitionDirectoryData)); + pdir->pdir_mcxt = mcxt; + ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(PartitionDirectoryEntry); ctl.hcxt = mcxt; - pdir = palloc(sizeof(PartitionDirectoryData)); - pdir->pdir_mcxt = mcxt; pdir->pdir_hash = hash_create("partition directory", 256, &ctl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + pdir->omit_detached = omit_detached; MemoryContextSwitchTo(oldcontext); return pdir; @@ -359,7 +455,7 @@ PartitionDirectoryLookup(PartitionDirectory pdir, Relation rel) */ RelationIncrementReferenceCount(rel); pde->rel = rel; - pde->pd = RelationGetPartitionDesc(rel); + pde->pd = RelationGetPartitionDesc(rel, pdir->omit_detached); Assert(pde->pd != NULL); } return pde->pd; diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index f3b6d3fbe547..84a7f845a76c 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -25,7 +25,7 @@ * * See gen_partprune_steps_internal() for more details on step generation. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -141,11 +141,14 @@ typedef struct PruneStepResult bool scan_null; /* Scan the partition for NULL values? */ } PruneStepResult; + +static List *add_part_relids(List *allpartrelids, Bitmapset *partrelids); static List *make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, + List *prunequal, + Bitmapset *partrelids, int *relid_subplan_map, Relids available_relids, - List *partitioned_rels, List *prunequal, Bitmapset **matchedsubplans); static void gen_partprune_steps(RelOptInfo *rel, List *clauses, Relids available_relids, @@ -159,8 +162,8 @@ static PartitionPruneStep *gen_prune_step_op(GeneratePruningStepsContext *contex static PartitionPruneStep *gen_prune_step_combine(GeneratePruningStepsContext *context, List *source_stepids, PartitionPruneCombineOp combineOp); -static PartitionPruneStep *gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, - List **keyclauses, Bitmapset *nullkeys); +static List *gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, + List **keyclauses, Bitmapset *nullkeys); static PartClauseMatchStatus match_clause_to_partition_key(GeneratePruningStepsContext *context, Expr *clause, Expr *partkey, int partkeyidx, bool *clause_is_not_null, @@ -219,26 +222,16 @@ static bool contain_forbidden_var_clause(Node *node, GeneratePruningStepsContext * * 'parentrel' is the RelOptInfo for an appendrel, and 'subpaths' is the list * of scan paths for its child rels. - * - * 'partitioned_rels' is a List containing Lists of relids of partitioned - * tables (a/k/a non-leaf partitions) that are parents of some of the child - * rels. Here we attempt to populate the PartitionPruneInfo by adding a - * 'prune_infos' item for each sublist in the 'partitioned_rels' list. - * However, some of the sets of partitioned relations may not require any - * run-time pruning. In these cases we'll simply not include a 'prune_infos' - * item for that set and instead we'll add all the subplans which belong to - * that set into the PartitionPruneInfo's 'other_subplans' field. Callers - * will likely never want to prune subplans which are mentioned in this field. - * - * 'prunequal' is a list of potential pruning quals. + * 'prunequal' is a list of potential pruning quals (i.e., restriction + * clauses that are applicable to the appendrel). */ PartitionPruneInfo * make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, - List *subpaths, List *partitioned_rels, + List *subpaths, List *prunequal) { return make_partition_pruneinfo_ext(root, parentrel, - subpaths, partitioned_rels, + subpaths, prunequal, NULL); } @@ -248,53 +241,101 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, */ PartitionPruneInfo * make_partition_pruneinfo_ext(PlannerInfo *root, RelOptInfo *parentrel, - List *subpaths, List *partitioned_rels, + List *subpaths, List *prunequal, Relids available_relids) { PartitionPruneInfo *pruneinfo; Bitmapset *allmatchedsubplans = NULL; + List *allpartrelids; + List *prunerelinfos; int *relid_subplan_map; ListCell *lc; - List *prunerelinfos; int i; /* - * Construct a temporary array to map from planner relids to subplan - * indexes. For convenience, we use 1-based indexes here, so that zero - * can represent an un-filled array entry. + * Scan the subpaths to see which ones are scans of partition child + * relations, and identify their parent partitioned rels. (Note: we must + * restrict the parent partitioned rels to be parentrel or children of + * parentrel, otherwise we couldn't translate prunequal to match.) + * + * Also construct a temporary array to map from partition-child-relation + * relid to the index in 'subpaths' of the scan plan for that partition. + * (Use of "subplan" rather than "subpath" is a bit of a misnomer, but + * we'll let it stand.) For convenience, we use 1-based indexes here, so + * that zero can represent an un-filled array entry. */ + allpartrelids = NIL; relid_subplan_map = palloc0(sizeof(int) * root->simple_rel_array_size); - /* - * relid_subplan_map maps relid of a leaf partition to the index in - * 'subpaths' of the scan plan for that partition. - */ i = 1; foreach(lc, subpaths) { Path *path = (Path *) lfirst(lc); RelOptInfo *pathrel = path->parent; - Assert(IS_SIMPLE_REL(pathrel)); - Assert(pathrel->relid < root->simple_rel_array_size); - /* No duplicates please */ - Assert(relid_subplan_map[pathrel->relid] == 0); + /* We don't consider partitioned joins here */ + if (pathrel->reloptkind == RELOPT_OTHER_MEMBER_REL) + { + RelOptInfo *prel = pathrel; + Bitmapset *partrelids = NULL; - relid_subplan_map[pathrel->relid] = i++; + /* + * Traverse up to the pathrel's topmost partitioned parent, + * collecting parent relids as we go; but stop if we reach + * parentrel. (Normally, a pathrel's topmost partitioned parent + * is either parentrel or a UNION ALL appendrel child of + * parentrel. But when handling partitionwise joins of + * multi-level partitioning trees, we can see an append path whose + * parentrel is an intermediate partitioned table.) + */ + do + { + AppendRelInfo *appinfo; + + Assert(prel->relid < root->simple_rel_array_size); + appinfo = root->append_rel_array[prel->relid]; + prel = find_base_rel(root, appinfo->parent_relid); + if (!IS_PARTITIONED_REL(prel)) + break; /* reached a non-partitioned parent */ + /* accept this level as an interesting parent */ + partrelids = bms_add_member(partrelids, prel->relid); + if (prel == parentrel) + break; /* don't traverse above parentrel */ + } while (prel->reloptkind == RELOPT_OTHER_MEMBER_REL); + + if (partrelids) + { + /* + * Found some relevant parent partitions, which may or may not + * overlap with partition trees we already found. Add new + * information to the allpartrelids list. + */ + allpartrelids = add_part_relids(allpartrelids, partrelids); + /* Also record the subplan in relid_subplan_map[] */ + /* No duplicates please */ + Assert(relid_subplan_map[pathrel->relid] == 0); + relid_subplan_map[pathrel->relid] = i; + } + } + i++; } - /* We now build a PartitionedRelPruneInfo for each partitioned rel. */ + /* + * We now build a PartitionedRelPruneInfo for each topmost partitioned rel + * (omitting any that turn out not to have useful pruning quals). + */ prunerelinfos = NIL; - foreach(lc, partitioned_rels) + foreach(lc, allpartrelids) { - List *rels = (List *) lfirst(lc); + Bitmapset *partrelids = (Bitmapset *) lfirst(lc); List *pinfolist; Bitmapset *matchedsubplans = NULL; pinfolist = make_partitionedrel_pruneinfo(root, parentrel, + prunequal, + partrelids, relid_subplan_map, available_relids, - rels, prunequal, &matchedsubplans); /* When pruning is possible, record the matched subplans */ @@ -320,7 +361,7 @@ make_partition_pruneinfo_ext(PlannerInfo *root, RelOptInfo *parentrel, pruneinfo->prune_infos = prunerelinfos; /* - * Some subplans may not belong to any of the listed partitioned rels. + * Some subplans may not belong to any of the identified partitioned rels. * This can happen for UNION ALL queries which include a non-partitioned * table, or when some of the hierarchies aren't run-time prunable. Build * a bitmapset of the indexes of all such subplans, so that the executor @@ -342,29 +383,87 @@ make_partition_pruneinfo_ext(PlannerInfo *root, RelOptInfo *parentrel, return pruneinfo; } +/* + * add_part_relids + * Add new info to a list of Bitmapsets of partitioned relids. + * + * Within 'allpartrelids', there is one Bitmapset for each topmost parent + * partitioned rel. Each Bitmapset contains the RT indexes of the topmost + * parent as well as its relevant non-leaf child partitions. Since (by + * construction of the rangetable list) parent partitions must have lower + * RT indexes than their children, we can distinguish the topmost parent + * as being the lowest set bit in the Bitmapset. + * + * 'partrelids' contains the RT indexes of a parent partitioned rel, and + * possibly some non-leaf children, that are newly identified as parents of + * some subpath rel passed to make_partition_pruneinfo(). These are added + * to an appropriate member of 'allpartrelids'. + * + * Note that the list contains only RT indexes of partitioned tables that + * are parents of some scan-level relation appearing in the 'subpaths' that + * make_partition_pruneinfo() is dealing with. Also, "topmost" parents are + * not allowed to be higher than the 'parentrel' associated with the append + * path. In this way, we avoid expending cycles on partitioned rels that + * can't contribute useful pruning information for the problem at hand. + * (It is possible for 'parentrel' to be a child partitioned table, and it + * is also possible for scan-level relations to be child partitioned tables + * rather than leaf partitions. Hence we must construct this relation set + * with reference to the particular append path we're dealing with, rather + * than looking at the full partitioning structure represented in the + * RelOptInfos.) + */ +static List * +add_part_relids(List *allpartrelids, Bitmapset *partrelids) +{ + Index targetpart; + ListCell *lc; + + /* We can easily get the lowest set bit this way: */ + targetpart = bms_next_member(partrelids, -1); + Assert(targetpart > 0); + + /* Look for a matching topmost parent */ + foreach(lc, allpartrelids) + { + Bitmapset *currpartrelids = (Bitmapset *) lfirst(lc); + Index currtarget = bms_next_member(currpartrelids, -1); + + if (targetpart == currtarget) + { + /* Found a match, so add any new RT indexes to this hierarchy */ + currpartrelids = bms_add_members(currpartrelids, partrelids); + lfirst(lc) = currpartrelids; + return allpartrelids; + } + } + /* No match, so add the new partition hierarchy to the list */ + return lappend(allpartrelids, partrelids); +} + /* * make_partitionedrel_pruneinfo - * Build a List of PartitionedRelPruneInfos, one for each partitioned - * rel. These can be used in the executor to allow additional partition - * pruning to take place. - * - * Here we generate partition pruning steps for 'prunequal' and also build a - * data structure which allows mapping of partition indexes into 'subpaths' - * indexes. - * - * If no non-Const expressions are being compared to the partition key in any - * of the 'partitioned_rels', then we return NIL to indicate no run-time - * pruning should be performed. Run-time pruning would be useless since the - * pruning done during planning will have pruned everything that can be. - * - * On non-NIL return, 'matchedsubplans' is set to the subplan indexes which - * were matched to this partition hierarchy. + * Build a List of PartitionedRelPruneInfos, one for each interesting + * partitioned rel in a partitioning hierarchy. These can be used in the + * executor to allow additional partition pruning to take place. + * + * parentrel: rel associated with the appendpath being considered + * prunequal: potential pruning quals, represented for parentrel + * partrelids: Set of RT indexes identifying relevant partitioned tables + * within a single partitioning hierarchy + * relid_subplan_map[]: maps child relation relids to subplan indexes + * matchedsubplans: on success, receives the set of subplan indexes which + * were matched to this partition hierarchy + * + * If we cannot find any useful run-time pruning steps, return NIL. + * However, on success, each rel identified in partrelids will have + * an element in the result list, even if some of them are useless. */ static List * make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, + List *prunequal, + Bitmapset *partrelids, int *relid_subplan_map, Relids available_relids, - List *partitioned_rels, List *prunequal, Bitmapset **matchedsubplans) { RelOptInfo *targetpart = NULL; @@ -373,6 +472,7 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, int *relid_subpart_map; Bitmapset *subplansfound = NULL; ListCell *lc; + int rti; int i; /* @@ -386,9 +486,9 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, relid_subpart_map = palloc0(sizeof(int) * root->simple_rel_array_size); i = 1; - foreach(lc, partitioned_rels) + rti = -1; + while ((rti = bms_next_member(partrelids, rti)) > 0) { - Index rti = lfirst_int(lc); RelOptInfo *subpart = find_base_rel(root, rti); PartitionedRelPruneInfo *pinfo; List *partprunequal; @@ -401,14 +501,11 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, * Fill the mapping array. * * relid_subpart_map maps relid of a non-leaf partition to the index - * in 'partitioned_rels' of that rel (which will also be the index in - * the returned PartitionedRelPruneInfo list of the info for that - * partition). We use 1-based indexes here, so that zero can - * represent an un-filled array entry. + * in the returned PartitionedRelPruneInfo list of the info for that + * partition. We use 1-based indexes here, so that zero can represent + * an un-filled array entry. */ Assert(rti < root->simple_rel_array_size); - /* No duplicates please */ - Assert(relid_subpart_map[rti] == 0); relid_subpart_map[rti] = i++; /* @@ -606,6 +703,13 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, present_parts = bms_add_member(present_parts, i); } + /* + * Ensure there were no stray PartitionedRelPruneInfo generated for + * partitioned tables that we have no sub-paths or + * sub-PartitionedRelPruneInfo for. + */ + Assert(!bms_is_empty(present_parts)); + /* Record the maps and other information. */ pinfo->present_parts = present_parts; pinfo->nparts = nparts; @@ -803,7 +907,10 @@ get_matching_partitions(PartitionPruneContext *context, List *pruning_steps) scan_default = final_result->scan_default; while ((i = bms_next_member(final_result->bound_offsets, i)) >= 0) { - int partindex = context->boundinfo->indexes[i]; + int partindex; + + Assert(i < context->boundinfo->nindexes); + partindex = context->boundinfo->indexes[i]; if (partindex < 0) { @@ -845,22 +952,34 @@ get_matching_partitions(PartitionPruneContext *context, List *pruning_steps) /* * gen_partprune_steps_internal - * Processes 'clauses' to generate partition pruning steps. - * - * From OpExpr clauses that are mutually AND'd, we find combinations of those - * that match to the partition key columns and for every such combination, - * we emit a PartitionPruneStepOp containing a vector of expressions whose - * values are used as a look up key to search partitions by comparing the - * values with partition bounds. Relevant details of the operator and a - * vector of (possibly cross-type) comparison functions is also included with - * each step. - * - * For BoolExpr clauses, we recursively generate steps for each argument, and - * return a PartitionPruneStepCombine of their results. - * - * The return value is a list of the steps generated, which are also added to - * the context's steps list. Each step is assigned a step identifier, unique - * even across recursive calls. + * Processes 'clauses' to generate a List of partition pruning steps. We + * return NIL when no steps were generated. + * + * These partition pruning steps come in 2 forms; operator steps and combine + * steps. + * + * Operator steps (PartitionPruneStepOp) contain details of clauses that we + * determined that we can use for partition pruning. These contain details of + * the expression which is being compared to the partition key and the + * comparison function. + * + * Combine steps (PartitionPruneStepCombine) instruct the partition pruning + * code how it should produce a single set of partitions from multiple input + * operator and other combine steps. A PARTPRUNE_COMBINE_INTERSECT type + * combine step will merge its input steps to produce a result which only + * contains the partitions which are present in all of the input operator + * steps. A PARTPRUNE_COMBINE_UNION combine step will produce a result that + * has all of the partitions from each of the input operator steps. + * + * For BoolExpr clauses, each argument is processed recursively. Steps + * generated from processing an OR BoolExpr will be combined using + * PARTPRUNE_COMBINE_UNION. AND BoolExprs get combined using + * PARTPRUNE_COMBINE_INTERSECT. + * + * Otherwise, the list of clauses we receive we assume to be mutually ANDed. + * We generate all of the pruning steps we can based on these clauses and then + * at the end, if we have more than 1 step, we combine each step with a + * PARTPRUNE_COMBINE_INTERSECT combine step. Single steps are returned as-is. * * If we find clauses that are mutually contradictory, or contradictory with * the partitioning constraint, or a pseudoconstant clause that contains @@ -967,11 +1086,16 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, if (argsteps != NIL) { - PartitionPruneStep *step; + /* + * gen_partprune_steps_internal() always adds a single + * combine step when it generates multiple steps, so + * here we can just pay attention to the last one in + * the list. If it just generated one, then the last + * one in the list is still the one we want. + */ + PartitionPruneStep *last = llast(argsteps); - Assert(list_length(argsteps) == 1); - step = (PartitionPruneStep *) linitial(argsteps); - arg_stepids = lappend_int(arg_stepids, step->step_id); + arg_stepids = lappend_int(arg_stepids, last->step_id); } else { @@ -1010,9 +1134,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, else if (is_andclause(clause)) { List *args = ((BoolExpr *) clause)->args; - List *argsteps, - *arg_stepids = NIL; - ListCell *lc1; + List *argsteps; /* * args may itself contain clauses of arbitrary type, so just @@ -1025,21 +1147,16 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, if (context->contradictory) return NIL; - foreach(lc1, argsteps) - { - PartitionPruneStep *step = lfirst(lc1); - - arg_stepids = lappend_int(arg_stepids, step->step_id); - } - - if (arg_stepids != NIL) - { - PartitionPruneStep *step; + /* + * gen_partprune_steps_internal() always adds a single combine + * step when it generates multiple steps, so here we can just + * pay attention to the last one in the list. If it just + * generated one, then the last one in the list is still the + * one we want. + */ + if (argsteps != NIL) + result = lappend(result, llast(argsteps)); - step = gen_prune_step_combine(context, arg_stepids, - PARTPRUNE_COMBINE_INTERSECT); - result = lappend(result, step); - } continue; } @@ -1174,12 +1291,11 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, } else if (generate_opsteps) { - PartitionPruneStep *step; + List *opsteps; /* Strategy 2 */ - step = gen_prune_steps_from_opexps(context, keyclauses, nullkeys); - if (step != NULL) - result = lappend(result, step); + opsteps = gen_prune_steps_from_opexps(context, keyclauses, nullkeys); + result = list_concat(result, opsteps); } else if (bms_num_members(notnullkeys) == part_scheme->partnatts) { @@ -1192,12 +1308,14 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, } /* - * Finally, results from all entries appearing in result should be - * combined using an INTERSECT combine step, if more than one. + * Finally, if there are multiple steps, since the 'clauses' are mutually + * ANDed, add an INTERSECT step to combine the partition sets resulting + * from them and append it to the result list. */ if (list_length(result) > 1) { List *step_ids = NIL; + PartitionPruneStep *final; foreach(lc, result) { @@ -1206,14 +1324,9 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, step_ids = lappend_int(step_ids, step->step_id); } - if (step_ids != NIL) - { - PartitionPruneStep *step; - - step = gen_prune_step_combine(context, step_ids, - PARTPRUNE_COMBINE_INTERSECT); - result = lappend(result, step); - } + final = gen_prune_step_combine(context, step_ids, + PARTPRUNE_COMBINE_INTERSECT); + result = lappend(result, final); } return result; @@ -1277,15 +1390,26 @@ gen_prune_step_combine(GeneratePruningStepsContext *context, /* * gen_prune_steps_from_opexps - * Generate pruning steps based on clauses for partition keys - * - * 'keyclauses' contains one list of clauses per partition key. We check here - * if we have found clauses for a valid subset of the partition key. In some - * cases, (depending on the type of partitioning being used) if we didn't - * find clauses for a given key, we discard clauses that may have been - * found for any subsequent keys; see specific notes below. + * Generate and return a list of PartitionPruneStepOp that are based on + * OpExpr and BooleanTest clauses that have been matched to the partition + * key. + * + * 'keyclauses' is an array of List pointers, indexed by the partition key's + * index. Each List element in the array can contain clauses that match to + * the corresponding partition key column. Partition key columns without any + * matched clauses will have an empty List. + * + * Some partitioning strategies allow pruning to still occur when we only have + * clauses for a prefix of the partition key columns, for example, RANGE + * partitioning. Other strategies, such as HASH partitioning, require clauses + * for all partition key columns. + * + * When we return multiple pruning steps here, it's up to the caller to add a + * relevant "combine" step to combine the returned steps. This is not done + * here as callers may wish to include additional pruning steps before + * combining them all. */ -static PartitionPruneStep * +static List * gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, List **keyclauses, Bitmapset *nullkeys) { @@ -1318,7 +1442,7 @@ gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, */ if (part_scheme->strategy == PARTITION_STRATEGY_HASH && clauselist == NIL && !bms_is_member(i, nullkeys)) - return NULL; + return NIL; foreach(lc, clauselist) { @@ -1649,27 +1773,7 @@ gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, break; } - /* Lastly, add a combine step to mutually AND these op steps, if needed */ - if (list_length(opsteps) > 1) - { - List *opstep_ids = NIL; - - foreach(lc, opsteps) - { - PartitionPruneStep *step = lfirst(lc); - - opstep_ids = lappend_int(opstep_ids, step->step_id); - } - - if (opstep_ids != NIL) - return gen_prune_step_combine(context, opstep_ids, - PARTPRUNE_COMBINE_INTERSECT); - return NULL; - } - else if (opsteps != NIL) - return linitial(opsteps); - - return NULL; + return opsteps; } /* @@ -1703,8 +1807,8 @@ gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, * true otherwise. * * * PARTCLAUSE_MATCH_STEPS if there is a match. - * Output arguments: *clause_steps is set to a list of PartitionPruneStep - * generated for the clause. + * Output arguments: *clause_steps is set to the list of recursively + * generated steps for the clause. * * * PARTCLAUSE_MATCH_CONTRADICT if the clause is self-contradictory, ie * it provably returns FALSE or NULL. @@ -2444,11 +2548,12 @@ get_steps_using_prefix_recurse(GeneratePruningStepsContext *context, */ Assert(list_length(step_exprs) == cur_keyno || !bms_is_empty(step_nullkeys)); + /* * Note also that for hash partitioning, each partition key should * have either equality clauses or an IS NULL clause, so if a - * partition key doesn't have an expression, it would be specified - * in step_nullkeys. + * partition key doesn't have an expression, it would be specified in + * step_nullkeys. */ Assert(context->rel->part_scheme->strategy != PARTITION_STRATEGY_HASH || @@ -2540,20 +2645,19 @@ get_matching_hash_bounds(PartitionPruneContext *context, for (i = 0; i < partnatts; i++) isnull[i] = bms_is_member(i, nullkeys); - greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); rowHash = compute_partition_hash_value(partnatts, partsupfunc, partcollation, values, isnull); + greatest_modulus = boundinfo->nindexes; if (partindices[rowHash % greatest_modulus] >= 0) result->bound_offsets = bms_make_singleton(rowHash % greatest_modulus); } else { - /* Getting here means at least one hash partition exists. */ - Assert(boundinfo->ndatums > 0); + /* Report all valid offsets into the boundinfo->indexes array. */ result->bound_offsets = bms_add_range(NULL, 0, - boundinfo->ndatums - 1); + boundinfo->nindexes - 1); } /* @@ -3145,7 +3249,7 @@ get_matching_range_bounds(PartitionPruneContext *context, /* * If the smallest partition to return has MINVALUE (negative infinity) as * its lower bound, increment it to point to the next finite bound - * (supposedly its upper bound), so that we don't advertently end up + * (supposedly its upper bound), so that we don't inadvertently end up * scanning the default partition. */ if (minoff < boundinfo->ndatums && partindices[minoff] < 0) @@ -3164,7 +3268,7 @@ get_matching_range_bounds(PartitionPruneContext *context, * If the previous greatest partition has MAXVALUE (positive infinity) as * its upper bound (something only possible to do with multi-column range * partitioning), we scan switch to it as the greatest partition to - * return. Again, so that we don't advertently end up scanning the + * return. Again, so that we don't inadvertently end up scanning the * default partition. */ if (maxoff >= 1 && partindices[maxoff] < 0) @@ -3414,30 +3518,20 @@ perform_pruning_combine_step(PartitionPruneContext *context, PartitionPruneStepCombine *cstep, PruneStepResult **step_results) { - ListCell *lc1; - PruneStepResult *result = NULL; + PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); bool firststep; + ListCell *lc1; /* * A combine step without any source steps is an indication to not perform * any partition pruning. Return all datum indexes in that case. */ - result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); - if (list_length(cstep->source_stepids) == 0) + if (cstep->source_stepids == NIL) { PartitionBoundInfo boundinfo = context->boundinfo; - int rangemax; - - /* - * Add all valid offsets into the boundinfo->indexes array. For range - * partitioning, boundinfo->indexes contains (boundinfo->ndatums + 1) - * valid entries; otherwise there are boundinfo->ndatums. - */ - rangemax = context->strategy == PARTITION_STRATEGY_RANGE ? - boundinfo->ndatums : boundinfo->ndatums - 1; result->bound_offsets = - bms_add_range(result->bound_offsets, 0, rangemax); + bms_add_range(NULL, 0, boundinfo->nindexes - 1); result->scan_default = partition_bound_has_default(boundinfo); result->scan_null = partition_bound_accepts_nulls(boundinfo); return result; diff --git a/src/backend/po/de.po b/src/backend/po/de.po new file mode 100644 index 000000000000..6b136250cf55 --- /dev/null +++ b/src/backend/po/de.po @@ -0,0 +1,28538 @@ +# German message translation file for PostgreSQL server +# Peter Eisentraut , 2001 - 2021. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-05 07:40+0000\n" +"PO-Revision-Date: 2021-06-05 22:31+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 +#: ../common/config_info.c:150 ../common/config_info.c:158 +#: ../common/config_info.c:166 ../common/config_info.c:174 +#: ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "nicht aufgezeichnet" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 +#: commands/copyfrom.c:1516 commands/extension.c:3455 utils/adt/genfile.c:128 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 +#: access/transam/timeline.c:143 access/transam/timeline.c:362 +#: access/transam/twophase.c:1271 access/transam/xlog.c:3547 +#: access/transam/xlog.c:4772 access/transam/xlog.c:11338 +#: access/transam/xlog.c:11351 access/transam/xlog.c:11804 +#: access/transam/xlog.c:11884 access/transam/xlog.c:11921 +#: access/transam/xlog.c:11981 access/transam/xlogfuncs.c:703 +#: access/transam/xlogfuncs.c:722 commands/extension.c:3465 libpq/hba.c:534 +#: replication/basebackup.c:2020 replication/logical/origin.c:729 +#: replication/logical/origin.c:765 replication/logical/reorderbuffer.c:4880 +#: replication/logical/snapbuild.c:1733 replication/logical/snapbuild.c:1775 +#: replication/logical/snapbuild.c:1802 replication/slot.c:1658 +#: replication/slot.c:1699 replication/walsender.c:544 +#: storage/file/buffile.c:445 storage/file/copydir.c:195 +#: utils/adt/genfile.c:202 utils/adt/misc.c:859 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "konnte Datei »%s« nicht lesen: %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 +#: access/transam/xlog.c:3552 access/transam/xlog.c:4777 +#: replication/basebackup.c:2024 replication/logical/origin.c:734 +#: replication/logical/origin.c:773 replication/logical/snapbuild.c:1738 +#: replication/logical/snapbuild.c:1780 replication/logical/snapbuild.c:1807 +#: replication/slot.c:1662 replication/slot.c:1703 replication/walsender.c:549 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 +#: ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 +#: access/heap/rewriteheap.c:1185 access/heap/rewriteheap.c:1288 +#: access/transam/timeline.c:392 access/transam/timeline.c:438 +#: access/transam/timeline.c:516 access/transam/twophase.c:1283 +#: access/transam/twophase.c:1680 access/transam/xlog.c:3419 +#: access/transam/xlog.c:3587 access/transam/xlog.c:3592 +#: access/transam/xlog.c:3920 access/transam/xlog.c:4742 +#: access/transam/xlog.c:5667 access/transam/xlogfuncs.c:728 +#: commands/copyfrom.c:1576 commands/copyto.c:328 libpq/be-fsstubs.c:462 +#: libpq/be-fsstubs.c:533 replication/logical/origin.c:667 +#: replication/logical/origin.c:806 replication/logical/reorderbuffer.c:4938 +#: replication/logical/snapbuild.c:1642 replication/logical/snapbuild.c:1815 +#: replication/slot.c:1549 replication/slot.c:1710 replication/walsender.c:559 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:738 +#: storage/file/fd.c:3534 storage/file/fd.c:3637 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schließen: %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "falsche Byte-Reihenfolge" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"möglicherweise falsche Byte-Reihenfolge\n" +"Die Byte-Reihenfolge, die zur Speicherung der Datei pg_control verwendet wurde,\n" +"stimmt möglicherweise nicht mit der von diesem Programm verwendeten überein. In\n" +"diesem Fall wären die Ergebnisse unten falsch und die PostgreSQL-Installation\n" +"wäre inkompatibel mit diesem Datenverzeichnis." + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 +#: ../common/file_utils.c:232 ../common/file_utils.c:291 +#: ../common/file_utils.c:365 access/heap/rewriteheap.c:1271 +#: access/transam/timeline.c:111 access/transam/timeline.c:251 +#: access/transam/timeline.c:348 access/transam/twophase.c:1227 +#: access/transam/xlog.c:3305 access/transam/xlog.c:3461 +#: access/transam/xlog.c:3502 access/transam/xlog.c:3700 +#: access/transam/xlog.c:3785 access/transam/xlog.c:3888 +#: access/transam/xlog.c:4762 access/transam/xlogutils.c:803 +#: postmaster/syslogger.c:1488 replication/basebackup.c:616 +#: replication/basebackup.c:1610 replication/logical/origin.c:719 +#: replication/logical/reorderbuffer.c:3548 +#: replication/logical/reorderbuffer.c:4095 +#: replication/logical/reorderbuffer.c:4860 +#: replication/logical/snapbuild.c:1597 replication/logical/snapbuild.c:1704 +#: replication/slot.c:1630 replication/walsender.c:517 +#: replication/walsender.c:2526 storage/file/copydir.c:161 +#: storage/file/fd.c:713 storage/file/fd.c:3521 storage/file/fd.c:3608 +#: storage/smgr/md.c:502 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1938 +#: utils/init/miscinit.c:1346 utils/init/miscinit.c:1480 +#: utils/init/miscinit.c:1557 utils/misc/guc.c:8604 utils/misc/guc.c:8636 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 +#: access/transam/twophase.c:1653 access/transam/twophase.c:1662 +#: access/transam/xlog.c:11095 access/transam/xlog.c:11133 +#: access/transam/xlog.c:11546 access/transam/xlogfuncs.c:782 +#: postmaster/postmaster.c:5659 postmaster/syslogger.c:1499 +#: postmaster/syslogger.c:1512 utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schreiben: %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 +#: ../common/file_utils.c:303 ../common/file_utils.c:373 +#: access/heap/rewriteheap.c:967 access/heap/rewriteheap.c:1179 +#: access/heap/rewriteheap.c:1282 access/transam/timeline.c:432 +#: access/transam/timeline.c:510 access/transam/twophase.c:1674 +#: access/transam/xlog.c:3412 access/transam/xlog.c:3581 +#: access/transam/xlog.c:4735 access/transam/xlog.c:10586 +#: access/transam/xlog.c:10627 replication/logical/snapbuild.c:1635 +#: replication/slot.c:1535 replication/slot.c:1640 storage/file/fd.c:730 +#: storage/file/fd.c:3629 storage/smgr/md.c:950 storage/smgr/md.c:991 +#: storage/sync/sync.c:417 utils/cache/relmapper.c:885 utils/misc/guc.c:8391 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "konnte Datei »%s« nicht fsyncen: %m" + +#: ../common/cryptohash_openssl.c:104 ../common/exec.c:522 ../common/exec.c:567 +#: ../common/exec.c:659 ../common/hmac_openssl.c:103 ../common/psprintf.c:143 +#: ../common/stringinfo.c:305 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1341 access/transam/xlog.c:6633 +#: lib/dshash.c:246 libpq/auth.c:1482 libpq/auth.c:1550 libpq/auth.c:2108 +#: libpq/be-secure-gssapi.c:520 postmaster/bgworker.c:349 +#: postmaster/bgworker.c:948 postmaster/postmaster.c:2516 +#: postmaster/postmaster.c:4175 postmaster/postmaster.c:4845 +#: postmaster/postmaster.c:5584 postmaster/postmaster.c:5948 +#: replication/libpqwalreceiver/libpqwalreceiver.c:282 +#: replication/logical/logical.c:205 replication/walsender.c:591 +#: storage/buffer/localbuf.c:442 storage/file/fd.c:882 storage/file/fd.c:1352 +#: storage/file/fd.c:1513 storage/file/fd.c:2321 storage/ipc/procarray.c:1388 +#: storage/ipc/procarray.c:2182 storage/ipc/procarray.c:2189 +#: storage/ipc/procarray.c:2678 storage/ipc/procarray.c:3302 +#: utils/adt/cryptohashfuncs.c:46 utils/adt/cryptohashfuncs.c:66 +#: utils/adt/formatting.c:1699 utils/adt/formatting.c:1823 +#: utils/adt/formatting.c:1948 utils/adt/pg_locale.c:450 +#: utils/adt/pg_locale.c:614 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:513 utils/hash/dynahash.c:613 +#: utils/hash/dynahash.c:1116 utils/mb/mbutils.c:401 utils/mb/mbutils.c:429 +#: utils/mb/mbutils.c:814 utils/mb/mbutils.c:841 utils/misc/guc.c:5035 +#: utils/misc/guc.c:5051 utils/misc/guc.c:5064 utils/misc/guc.c:8369 +#: utils/misc/tzparser.c:467 utils/mmgr/aset.c:476 utils/mmgr/dsa.c:701 +#: utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:234 +#: utils/mmgr/mcxt.c:888 utils/mmgr/mcxt.c:924 utils/mmgr/mcxt.c:962 +#: utils/mmgr/mcxt.c:1000 utils/mmgr/mcxt.c:1082 utils/mmgr/mcxt.c:1113 +#: utils/mmgr/mcxt.c:1149 utils/mmgr/mcxt.c:1201 utils/mmgr/mcxt.c:1236 +#: utils/mmgr/mcxt.c:1271 utils/mmgr/slab.c:236 +#, c-format +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: ../common/exec.c:136 ../common/exec.c:253 ../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ungültige Programmdatei »%s«" + +#: ../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "konnte Programmdatei »%s« nicht lesen" + +#: ../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "konnte kein »%s« zum Ausführen finden" + +#: ../common/exec.c:269 ../common/exec.c:308 utils/init/miscinit.c:425 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: ../common/exec.c:286 access/transam/xlog.c:10969 +#: replication/basebackup.c:1428 utils/adt/misc.c:340 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" + +#: ../common/exec.c:409 libpq/pqcomm.c:746 storage/ipc/latch.c:1064 +#: storage/ipc/latch.c:1233 storage/ipc/latch.c:1462 storage/ipc/latch.c:1614 +#: storage/ipc/latch.c:1730 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() fehlgeschlagen: %m" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 +#: ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 +#: ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 +#: utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../common/file_utils.c:87 ../common/file_utils.c:451 +#: ../common/file_utils.c:455 access/transam/twophase.c:1239 +#: access/transam/xlog.c:11071 access/transam/xlog.c:11109 +#: access/transam/xlog.c:11326 access/transam/xlogarchive.c:110 +#: access/transam/xlogarchive.c:227 commands/copyfrom.c:1526 +#: commands/copyto.c:734 commands/extension.c:3444 commands/tablespace.c:807 +#: commands/tablespace.c:898 guc-file.l:1060 replication/basebackup.c:439 +#: replication/basebackup.c:622 replication/basebackup.c:698 +#: replication/logical/snapbuild.c:1514 storage/file/copydir.c:68 +#: storage/file/copydir.c:107 storage/file/fd.c:1863 storage/file/fd.c:1949 +#: storage/file/fd.c:3149 storage/file/fd.c:3353 utils/adt/dbsize.c:70 +#: utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 utils/adt/genfile.c:418 +#: utils/adt/genfile.c:644 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: ../common/file_utils.c:166 ../common/pgfnames.c:48 commands/tablespace.c:730 +#: commands/tablespace.c:740 postmaster/postmaster.c:1515 +#: storage/file/fd.c:2724 storage/file/reinit.c:122 utils/adt/misc.c:262 +#: utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: ../common/file_utils.c:200 ../common/pgfnames.c:69 storage/file/fd.c:2736 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" + +#: ../common/file_utils.c:383 access/transam/xlogarchive.c:412 +#: postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1654 +#: replication/slot.c:668 replication/slot.c:1421 replication/slot.c:1563 +#: storage/file/fd.c:748 storage/file/fd.c:846 utils/time/snapmgr.c:1265 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "konnte Datei »%s« nicht in »%s« umbenennen: %m" + +#: ../common/hex.c:54 +#, c-format +msgid "invalid hexadecimal digit" +msgstr "ungültige hexadezimale Ziffer" + +#: ../common/hex.c:59 +#, c-format +msgid "invalid hexadecimal digit: \"%.*s\"" +msgstr "ungültige hexadezimale Ziffer: »%.*s«" + +#: ../common/hex.c:90 +#, c-format +msgid "overflow of destination buffer in hex encoding" +msgstr "Zielpufferüberlauf bei Hex-Kodierung" + +#: ../common/hex.c:136 ../common/hex.c:141 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "ungültige hexadezimale Daten: ungerade Anzahl Ziffern" + +#: ../common/hex.c:152 +#, c-format +msgid "overflow of destination buffer in hex decoding" +msgstr "Zielpufferüberlauf bei Hex-Dekodierung" + +#: ../common/jsonapi.c:1066 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Escape-Sequenz »\\%s« ist nicht gültig." + +#: ../common/jsonapi.c:1069 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Zeichen mit Wert 0x%02x muss escapt werden." + +#: ../common/jsonapi.c:1072 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Ende der Eingabe erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1075 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Array-Element oder »]« erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1078 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "»,« oder »]« erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1081 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "»:« erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1084 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "JSON-Wert erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1087 +msgid "The input string ended unexpectedly." +msgstr "Die Eingabezeichenkette endete unerwartet." + +#: ../common/jsonapi.c:1089 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Zeichenkette oder »}« erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1092 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "»,« oder »}« erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1095 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Zeichenkette erwartet, aber »%s« gefunden." + +#: ../common/jsonapi.c:1098 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Token »%s« ist ungültig." + +#: ../common/jsonapi.c:1101 jsonpath_scan.l:499 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 kann nicht in »text« umgewandelt werden." + +#: ../common/jsonapi.c:1103 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "Nach »\\u« müssen vier Hexadezimalziffern folgen." + +#: ../common/jsonapi.c:1106 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Unicode-Escape-Werte können nicht für Code-Punkt-Werte über 007F verwendet werden, wenn die Kodierung nicht UTF8 ist." + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:520 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Unicode-High-Surrogate darf nicht auf ein High-Surrogate folgen." + +#: ../common/jsonapi.c:1110 jsonpath_scan.l:531 jsonpath_scan.l:541 +#: jsonpath_scan.l:583 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Unicode-Low-Surrogate muss auf ein High-Surrogate folgen." + +#: ../common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "ungültiger Fork-Name" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Gültige Fork-Namen sind »main«, »fsm«, »vm« und »init«." + +#: ../common/restricted_token.c:64 libpq/auth.c:1512 libpq/auth.c:2544 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "konnte Bibliothek »%s« nicht laden: Fehlercode %lu" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "auf dieser Plattform können keine beschränkten Token erzeugt werden: Fehlercode %lu" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "konnte Prozess-Token nicht öffnen: Fehlercode %lu" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "konnte SIDs nicht erzeugen: Fehlercode %lu" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "konnte beschränktes Token nicht erzeugen: Fehlercode %lu" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" + +#: ../common/rmtree.c:79 replication/basebackup.c:1181 +#: replication/basebackup.c:1357 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "konnte Datei oder Verzeichnis »%s« nicht entfernen: %m" + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "Kann Zeichenkettenpuffer mit %d Bytes nicht um %d Bytes vergrößern." + +#: ../common/stringinfo.c:310 +#, c-format +msgid "" +"out of memory\n" +"\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "" +"Speicher aufgebraucht\n" +"\n" +"Kann Zeichenkettenpuffer mit %d Bytes nicht um %d Bytes vergrößern.\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "konnte effektive Benutzer-ID %ld nicht nachschlagen: %s" + +#: ../common/username.c:45 libpq/auth.c:2044 +msgid "user does not exist" +msgstr "Benutzer existiert nicht" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "Fehler beim Nachschlagen des Benutzernamens: Fehlercode %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "Befehl ist nicht ausführbar" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "Befehl nicht gefunden" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "Kindprozess hat mit Code %d beendet" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "Kindprozess wurde durch Ausnahme 0x%X beendet" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "Kindprozess wurde von Signal %d beendet: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "Kindprozess hat mit unbekanntem Status %d beendet" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "konnte Kodierung für Codeset »%s« nicht bestimmen" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "konnte Kodierung für Locale »%s« nicht bestimmen: Codeset ist »%s«" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "konnte Junction für »%s« nicht erzeugen: %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "konnte Junction für »%s« nicht erzeugen: %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "konnte Junction für »%s« nicht ermitteln: %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "konnte Junction für »%s« nicht ermitteln: %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "konnte Datei »%s« nicht öffnen: %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "Sperrverletzung" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "Zugriffsverletzung (Sharing Violation)" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "Versuche werden für 30 Sekunden wiederholt." + +#: ../port/open.c:129 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "Möglicherweise stört eine Antivirus-, Datensicherungs- oder ähnliche Software das Datenbanksystem." + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "konnte aktuelles Arbeitsverzeichnis nicht ermitteln: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "Betriebssystemfehler %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "konnte SID der Administrators-Gruppe nicht ermitteln: Fehlercode %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "konnte SID der PowerUsers-Gruppe nicht ermitteln: Fehlercode %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "konnte Access-Token-Mitgliedschaft nicht prüfen: Fehlercode %lu\n" + +#: access/brin/brin.c:214 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "Aufforderung für BRIN-Range-Summarization für Index »%s« Seite %u wurde nicht aufgezeichnet" + +#: access/brin/brin.c:1015 access/brin/brin.c:1092 access/gin/ginfast.c:1035 +#: access/transam/xlog.c:10748 access/transam/xlog.c:11277 +#: access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 +#: access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 +#: access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 +#: access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "Wiederherstellung läuft" + +#: access/brin/brin.c:1016 access/brin/brin.c:1093 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Während der Wiederherstellung können keine BRIN-Kontrollfunktionen ausgeführt werden." + +#: access/brin/brin.c:1024 access/brin/brin.c:1101 +#, c-format +msgid "block number out of range: %s" +msgstr "Blocknummer ist außerhalb des gültigen Bereichs: %s" + +#: access/brin/brin.c:1047 access/brin/brin.c:1124 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "»%s« ist kein BRIN-Index" + +#: access/brin/brin.c:1063 access/brin/brin.c:1140 +#, c-format +msgid "could not open parent table of index \"%s\"" +msgstr "konnte Basistabelle von Index »%s« nicht öffnen" + +#: access/brin/brin_bloom.c:751 access/brin/brin_bloom.c:793 +#: access/brin/brin_minmax_multi.c:2986 access/brin/brin_minmax_multi.c:3129 +#: statistics/dependencies.c:651 statistics/dependencies.c:704 +#: statistics/mcv.c:1480 statistics/mcv.c:1511 statistics/mvdistinct.c:343 +#: statistics/mvdistinct.c:396 utils/adt/pseudotypes.c:43 +#: utils/adt/pseudotypes.c:77 utils/adt/pseudotypes.c:252 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "kann keinen Wert vom Typ %s annehmen" + +#: access/brin/brin_minmax_multi.c:2144 access/brin/brin_minmax_multi.c:2151 +#: access/brin/brin_minmax_multi.c:2158 utils/adt/timestamp.c:941 +#: utils/adt/timestamp.c:1515 utils/adt/timestamp.c:1982 +#: utils/adt/timestamp.c:3059 utils/adt/timestamp.c:3064 +#: utils/adt/timestamp.c:3069 utils/adt/timestamp.c:3119 +#: utils/adt/timestamp.c:3126 utils/adt/timestamp.c:3133 +#: utils/adt/timestamp.c:3153 utils/adt/timestamp.c:3160 +#: utils/adt/timestamp.c:3167 utils/adt/timestamp.c:3197 +#: utils/adt/timestamp.c:3205 utils/adt/timestamp.c:3249 +#: utils/adt/timestamp.c:3676 utils/adt/timestamp.c:3801 +#: utils/adt/timestamp.c:4349 +#, c-format +msgid "interval out of range" +msgstr "interval-Wert ist außerhalb des gültigen Bereichs" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 +#: access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1441 access/spgist/spgdoinsert.c:2000 +#: access/spgist/spgdoinsert.c:2275 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "Größe %zu der Indexzeile überschreitet Maximum %zu für Index »%s«" + +#: access/brin/brin_revmap.c:393 access/brin/brin_revmap.c:399 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "verfälschter BRIN-Index: inkonsistente Range-Map" + +#: access/brin/brin_revmap.c:602 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "unerwarteter Seitentyp 0x%04X in BRIN-Index »%s« Block %u" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 +#: access/gist/gistvalidate.c:153 access/hash/hashvalidate.c:139 +#: access/nbtree/nbtvalidate.c:120 access/spgist/spgvalidate.c:189 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Funktion %s mit ungültiger Support-Nummer %d" + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 +#: access/gist/gistvalidate.c:165 access/hash/hashvalidate.c:118 +#: access/nbtree/nbtvalidate.c:132 access/spgist/spgvalidate.c:201 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Funktion %s mit falscher Signatur für Support-Nummer %d" + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 +#: access/gist/gistvalidate.c:185 access/hash/hashvalidate.c:160 +#: access/nbtree/nbtvalidate.c:152 access/spgist/spgvalidate.c:221 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Operator %s mit ungültiger Strategienummer %d" + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 +#: access/hash/hashvalidate.c:173 access/nbtree/nbtvalidate.c:165 +#: access/spgist/spgvalidate.c:237 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält ungültige ORDER-BY-Angabe für Operator %s" + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 +#: access/gist/gistvalidate.c:233 access/hash/hashvalidate.c:186 +#: access/nbtree/nbtvalidate.c:178 access/spgist/spgvalidate.c:253 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Operator %s mit falscher Signatur" + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:226 +#: access/nbtree/nbtvalidate.c:236 access/spgist/spgvalidate.c:280 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlen Operatoren für Typen %s und %s" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlen Support-Funktionen für Typen %s und %s" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:240 +#: access/nbtree/nbtvalidate.c:260 access/spgist/spgvalidate.c:315 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlen Operatoren" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 +#: access/gist/gistvalidate.c:274 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d" + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "Zurückgegebener Typ %1$s stimmt in Spalte %3$d nicht mit erwartetem Typ %2$s überein." + +#: access/common/attmap.c:150 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "Anzahl der zurückgegebenen Spalten (%d) entspricht nicht der erwarteten Spaltenanzahl (%d)." + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "konnte Zeilentyp nicht umwandeln" + +#: access/common/attmap.c:230 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "Attribut »%s« von Typ %s stimmt nicht mit dem entsprechenden Attribut von Typ %s überein." + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "Attribut »%s« von Typ %s existiert nicht in Typ %s." + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "Anzahl der Spalten (%d) überschreitet Maximum (%d)" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "Anzahl der Indexspalten (%d) überschreitet Maximum (%d)" + +#: access/common/indextuple.c:190 access/spgist/spgutils.c:947 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "Indexzeile benötigt %zu Bytes, Maximalgröße ist %zu" + +#: access/common/printtup.c:292 tcop/fastpath.c:106 tcop/fastpath.c:453 +#: tcop/postgres.c:1900 +#, c-format +msgid "unsupported format code: %d" +msgstr "nicht unterstützter Formatcode: %d" + +#: access/common/reloptions.c:506 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Gültige Werte sind »on«, »off« und »auto«." + +#: access/common/reloptions.c:517 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "Gültige Werte sind »local« und »cascaded«." + +#: access/common/reloptions.c:665 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "Wertebereich des Typs für benutzerdefinierte Relationsparameter überschritten" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESET darf keinen Parameterwert enthalten" + +#: access/common/reloptions.c:1240 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "unbekannter Parameter-Namensraum »%s«" + +#: access/common/reloptions.c:1277 utils/misc/guc.c:12514 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "Tabellen mit WITH OIDS werden nicht unterstützt" + +#: access/common/reloptions.c:1447 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "unbekannter Parameter »%s«" + +#: access/common/reloptions.c:1559 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "Parameter »%s« mehrmals angegeben" + +#: access/common/reloptions.c:1575 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "ungültiger Wert für Boole’sche Option »%s«: »%s«" + +#: access/common/reloptions.c:1587 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "ungültiger Wert für ganzzahlige Option »%s«: »%s«" + +#: access/common/reloptions.c:1593 access/common/reloptions.c:1613 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "Wert %s ist außerhalb des gültigen Bereichs für Option »%s«" + +#: access/common/reloptions.c:1595 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Gültige Werte sind zwischen »%d« und »%d«." + +#: access/common/reloptions.c:1607 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "ungültiger Wert für Gleitkommaoption »%s«: »%s«" + +#: access/common/reloptions.c:1615 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Gültige Werte sind zwischen »%f« und »%f«." + +#: access/common/reloptions.c:1637 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "ungültiger Wert für Enum-Option »%s«: »%s«" + +#: access/common/toast_compression.c:32 +#, fuzzy, c-format +#| msgid "unlink not supported with compression" +msgid "unsupported LZ4 compression method" +msgstr "Unlink wird bei Komprimierung nicht unterstützt" + +#: access/common/toast_compression.c:33 +#, c-format +msgid "This functionality requires the server to be built with lz4 support." +msgstr "Diese Funktionalität verlangt, dass der Server mit lz4-Unterstützung gebaut wird." + +#: access/common/toast_compression.c:34 utils/adt/pg_locale.c:1589 +#: utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using %s." +msgstr "Sie müssen PostgreSQL mit %s neu bauen." + +#: access/common/tupdesc.c:825 parser/parse_clause.c:772 +#: parser/parse_relation.c:1838 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "Spalte »%s« kann nicht als SETOF deklariert werden" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "Posting-Liste ist zu lang" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "Reduzieren Sie maintenance_work_mem." + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "GIN-Pending-Liste kann nicht während der Wiederherstellung aufgeräumt werden." + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "»%s« ist kein GIN-Index" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "auf temporäre Indexe anderer Sitzungen kann nicht zugegriffen werden" + +#: access/gin/ginget.c:270 access/nbtree/nbtinsert.c:759 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "konnte Tupel mit Index »%s« nicht erneut finden" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "alte GIN-Indexe unterstützen keine Scans des ganzen Index oder Suchen nach NULL-Werten" + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "Um das zu reparieren, führen Sie REINDEX INDEX \"%s\" aus." + +#: access/gin/ginutil.c:145 executor/execExpr.c:2166 +#: utils/adt/arrayfuncs.c:3818 utils/adt/arrayfuncs.c:6452 +#: utils/adt/rowtypes.c:957 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "konnte keine Vergleichsfunktion für Typ %s ermitteln" + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:102 access/spgist/spgvalidate.c:102 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Support-Funktion %s mit unterschiedlichen linken und rechten Eingabetypen" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d oder %d" + +#: access/gin/ginvalidate.c:333 access/gist/gistvalidate.c:350 +#: access/spgist/spgvalidate.c:387 +#, c-format +msgid "support function number %d is invalid for access method %s" +msgstr "Support-Funktionsnummer %d ist ungültig für Zugriffsmethode %s" + +#: access/gist/gist.c:758 access/gist/gistvacuum.c:420 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "Index »%s« enthält ein inneres Tupel, das als ungültig markiert ist" + +#: access/gist/gist.c:760 access/gist/gistvacuum.c:422 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "Das kommt von einem unvollständigen Page-Split bei der Crash-Recovery vor dem Upgrade auf PostgreSQL 9.1." + +#: access/gist/gist.c:761 access/gist/gistutil.c:801 access/gist/gistutil.c:812 +#: access/gist/gistvacuum.c:423 access/hash/hashutil.c:227 +#: access/hash/hashutil.c:238 access/hash/hashutil.c:250 +#: access/hash/hashutil.c:271 access/nbtree/nbtpage.c:810 +#: access/nbtree/nbtpage.c:821 +#, c-format +msgid "Please REINDEX it." +msgstr "Bitte führen Sie REINDEX für den Index aus." + +#: access/gist/gist.c:1175 +#, c-format +msgid "fixing incomplete split in index \"%s\", block %u" +msgstr "repariere unvollständiges Teilen in Index »%s«, Block %u" + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "Picksplit-Methode für Spalte %d von Index »%s« fehlgeschlagen" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "Der Index ist nicht optimal. Um ihn zu optimieren, kontaktieren Sie einen Entwickler oder versuchen Sie, die Spalte als die zweite im CREATE-INDEX-Befehl zu verwenden." + +#: access/gist/gistutil.c:798 access/hash/hashutil.c:224 +#: access/nbtree/nbtpage.c:807 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "Index »%s« enthält unerwartete Nullseite bei Block %u" + +#: access/gist/gistutil.c:809 access/hash/hashutil.c:235 +#: access/hash/hashutil.c:247 access/nbtree/nbtpage.c:818 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "Index »%s« enthält korrupte Seite bei Block %u" + +#: access/gist/gistvalidate.c:203 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält nicht unterstützte ORDER-BY-Angabe für Operator %s" + +#: access/gist/gistvalidate.c:214 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält ungültige ORDER-BY-Operatorfamilienangabe für Operator %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "konnte die für das Zeichenketten-Hashing zu verwendende Sortierfolge nicht bestimmen" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:713 +#: catalog/heap.c:719 commands/createas.c:206 commands/createas.c:509 +#: commands/indexcmds.c:1869 commands/tablecmds.c:16795 commands/view.c:86 +#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1666 +#: utils/adt/formatting.c:1790 utils/adt/formatting.c:1915 utils/adt/like.c:194 +#: utils/adt/like_support.c:1003 utils/adt/varchar.c:733 +#: utils/adt/varchar.c:994 utils/adt/varchar.c:1054 utils/adt/varlena.c:1524 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Verwenden Sie die COLLATE-Klausel, um die Sortierfolge explizit zu setzen." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "Größe der Indexzeile %zu überschreitet Maximum für Hash-Index %zu" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:2004 +#: access/spgist/spgdoinsert.c:2279 access/spgist/spgutils.c:1008 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Werte, die größer sind als eine Pufferseite, können nicht indiziert werden." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "ungültige Überlaufblocknummer %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "keine Überlaufseiten in Hash-Index »%s« mehr" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "Hash-Indexe unterstützen keine Scans des ganzen Index" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "Index »%s« ist kein Hash-Index" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "Index »%s« hat falsche Hash-Version" + +#: access/hash/hashvalidate.c:198 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion für Operator %s" + +#: access/hash/hashvalidate.c:256 access/nbtree/nbtvalidate.c:276 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlen typübergreifende Operatoren" + +#: access/heap/heapam.c:2260 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "in einem parallelen Arbeitsprozess können keine Tupel eingefügt werden" + +#: access/heap/heapam.c:2731 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "während einer parallelen Operation können keine Tupel gelöscht werden" + +#: access/heap/heapam.c:2777 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "Versuch ein unsichtbares Tupel zu löschen" + +#: access/heap/heapam.c:3209 access/heap/heapam.c:6010 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "während einer parallelen Operation können keine Tupel aktualisiert werden" + +#: access/heap/heapam.c:3342 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "Versuch ein unsichtbares Tupel zu aktualisieren" + +#: access/heap/heapam.c:4663 access/heap/heapam.c:4701 +#: access/heap/heapam.c:4957 access/heap/heapam_handler.c:454 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "konnte Sperre für Zeile in Relation »%s« nicht setzen" + +#: access/heap/heapam_handler.c:403 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "das zu sperrende Tupel wurde schon durch ein gleichzeitiges Update in eine andere Partition verschoben" + +#: access/heap/hio.c:360 access/heap/rewriteheap.c:665 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "Zeile ist zu groß: Größe ist %zu, Maximalgröße ist %zu" + +#: access/heap/rewriteheap.c:927 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "konnte nicht in Datei »%s« schreiben, %d von %d geschrieben: %m" + +#: access/heap/rewriteheap.c:1020 access/heap/rewriteheap.c:1138 +#: access/transam/timeline.c:329 access/transam/timeline.c:485 +#: access/transam/xlog.c:3328 access/transam/xlog.c:3516 +#: access/transam/xlog.c:4714 access/transam/xlog.c:11086 +#: access/transam/xlog.c:11124 access/transam/xlog.c:11529 +#: access/transam/xlogfuncs.c:776 postmaster/postmaster.c:4600 +#: postmaster/postmaster.c:5646 replication/logical/origin.c:587 +#: replication/slot.c:1482 storage/file/copydir.c:167 storage/smgr/md.c:218 +#: utils/time/snapmgr.c:1244 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "konnte Datei »%s« nicht erstellen: %m" + +#: access/heap/rewriteheap.c:1148 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" + +#: access/heap/rewriteheap.c:1166 access/transam/timeline.c:384 +#: access/transam/timeline.c:424 access/transam/timeline.c:502 +#: access/transam/xlog.c:3400 access/transam/xlog.c:3572 +#: access/transam/xlog.c:4726 postmaster/postmaster.c:4610 +#: postmaster/postmaster.c:4620 replication/logical/origin.c:599 +#: replication/logical/origin.c:641 replication/logical/origin.c:660 +#: replication/logical/snapbuild.c:1611 replication/slot.c:1517 +#: storage/file/buffile.c:506 storage/file/copydir.c:207 +#: utils/init/miscinit.c:1421 utils/init/miscinit.c:1432 +#: utils/init/miscinit.c:1440 utils/misc/guc.c:8352 utils/misc/guc.c:8383 +#: utils/misc/guc.c:10292 utils/misc/guc.c:10306 utils/time/snapmgr.c:1249 +#: utils/time/snapmgr.c:1256 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "konnte nicht in Datei »%s« schreiben: %m" + +#: access/heap/rewriteheap.c:1256 access/transam/twophase.c:1613 +#: access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:422 +#: postmaster/postmaster.c:1096 postmaster/syslogger.c:1465 +#: replication/logical/origin.c:575 replication/logical/reorderbuffer.c:4362 +#: replication/logical/snapbuild.c:1556 replication/logical/snapbuild.c:1972 +#: replication/slot.c:1614 storage/file/fd.c:788 storage/file/fd.c:3169 +#: storage/file/fd.c:3231 storage/file/reinit.c:250 storage/ipc/dsm.c:315 +#: storage/smgr/md.c:344 storage/smgr/md.c:394 storage/sync/sync.c:231 +#: utils/time/snapmgr.c:1589 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "konnte Datei »%s« nicht löschen: %m" + +#: access/heap/vacuumlazy.c:745 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisches aggressives Vacuum um Überlauf zu verhindern in der Tabelle »%s.%s.%s«: Index-Scans: %d\n" + +#: access/heap/vacuumlazy.c:747 +#, c-format +msgid "automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisches Vacuum um Überlauf zu verhindern in der Tabelle »%s.%s.%s«: Index-Scans: %d\n" + +#: access/heap/vacuumlazy.c:752 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisches aggressives Vacuum der Tabelle »%s.%s.%s«: Index-Scans: %d\n" + +#: access/heap/vacuumlazy.c:754 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisches Vacuum der Tabelle »%s.%s.%s«: Index-Scans: %d\n" + +#: access/heap/vacuumlazy.c:761 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "Seiten: %u entfernt, %u verbleiben, %u übersprungen wegen Pins, %u übersprungen weil eingefroren\n" + +#: access/heap/vacuumlazy.c:767 +#, c-format +msgid "tuples: %lld removed, %lld remain, %lld are dead but not yet removable, oldest xmin: %u\n" +msgstr "Tupel: %lld entfernt, %lld verbleiben, %lld sind tot aber noch nicht entfernbar, ältestes xmin: %u\n" + +#: access/heap/vacuumlazy.c:773 commands/analyze.c:794 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "Puffer-Verwendung: %lld Treffer, %lld Verfehlen, %lld geändert\n" + +#: access/heap/vacuumlazy.c:783 +#, c-format +msgid " %u pages from table (%.2f%% of total) had %lld dead item identifiers removed\n" +msgstr "" + +#: access/heap/vacuumlazy.c:786 +#, fuzzy +#| msgid "index \"%s\" not found" +msgid "index scan not needed:" +msgstr "Index »%s« nicht gefunden" + +#: access/heap/vacuumlazy.c:788 +#, fuzzy +#| msgid "index \"%s\" was reindexed" +msgid "index scan needed:" +msgstr "Index »%s« wurde neu indiziert" + +#: access/heap/vacuumlazy.c:792 +#, c-format +msgid " %u pages from table (%.2f%% of total) have %lld dead item identifiers\n" +msgstr "" + +#: access/heap/vacuumlazy.c:795 +msgid "index scan bypassed:" +msgstr "" + +#: access/heap/vacuumlazy.c:797 +msgid "index scan bypassed by failsafe:" +msgstr "" + +#: access/heap/vacuumlazy.c:813 +#, c-format +msgid "index \"%s\": pages: %u in total, %u newly deleted, %u currently deleted, %u reusable\n" +msgstr "" + +#: access/heap/vacuumlazy.c:820 commands/analyze.c:798 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "durchschn. Leserate: %.3f MB/s, durchschn. Schreibrate: %.3f MB/s\n" + +#: access/heap/vacuumlazy.c:824 commands/analyze.c:802 +msgid "I/O Timings:" +msgstr "" + +#: access/heap/vacuumlazy.c:826 commands/analyze.c:804 +#, c-format +msgid " read=%.3f" +msgstr "" + +#: access/heap/vacuumlazy.c:829 commands/analyze.c:807 +#, c-format +msgid " write=%.3f" +msgstr "" + +#: access/heap/vacuumlazy.c:833 +#, c-format +msgid "system usage: %s\n" +msgstr "Systembenutzung: %s\n" + +#: access/heap/vacuumlazy.c:835 +#, fuzzy, c-format +#| msgid "WAL usage: %ld records, %ld full page images, %llu bytes" +msgid "WAL usage: %lld records, %lld full page images, %llu bytes" +msgstr "WAL-Benutzung: %ld Einträge, %ld Full Page Images, %llu Bytes" + +#: access/heap/vacuumlazy.c:911 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "aggressives Vacuum von »%s.%s«" + +#: access/heap/vacuumlazy.c:916 commands/cluster.c:898 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "Vacuum von »%s.%s«" + +#: access/heap/vacuumlazy.c:1627 +#, fuzzy, c-format +#| msgid "\"%s\": removed %d row versions in %d pages" +msgid "\"%s\": removed %lld dead item identifiers in %u pages" +msgstr "»%s«: %d Zeilenversionen in %d Seiten entfernt" + +#: access/heap/vacuumlazy.c:1633 +#, c-format +msgid "%lld dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%lld tote Zeilenversionen können noch nicht entfernt werden, ältestes xmin: %u\n" + +#: access/heap/vacuumlazy.c:1635 +#, c-format +msgid "%u page removed.\n" +msgid_plural "%u pages removed.\n" +msgstr[0] "" +msgstr[1] "" + +#: access/heap/vacuumlazy.c:1639 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "%u Seite wegen Buffer-Pins übersprungen, " +msgstr[1] "%u Seiten wegen Buffer-Pins übersprungen, " + +#: access/heap/vacuumlazy.c:1643 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u eingefrorene Seite.\n" +msgstr[1] "%u eingefrorene Seiten.\n" + +#: access/heap/vacuumlazy.c:1647 commands/indexcmds.c:3986 +#: commands/indexcmds.c:4005 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1650 +#, c-format +msgid "\"%s\": found %lld removable, %lld nonremovable row versions in %u out of %u pages" +msgstr "»%s«: %lld entfernbare, %lld nicht entfernbare Zeilenversionen in %u von %u Seiten gefunden" + +#: access/heap/vacuumlazy.c:2155 +#, c-format +msgid "\"%s\": index scan bypassed: %u pages from table (%.2f%% of total) have %lld dead item identifiers" +msgstr "" + +#: access/heap/vacuumlazy.c:2366 +#, fuzzy, c-format +#| msgid "\"%s\": removed %d row versions in %d pages" +msgid "\"%s\": removed %d dead item identifiers in %u pages" +msgstr "»%s«: %d Zeilenversionen in %d Seiten entfernt" + +#: access/heap/vacuumlazy.c:2598 +#, fuzzy, c-format +#| msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgid "bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans" +msgstr "automatisches Vacuum der Tabelle »%s.%s.%s«: Index-Scans: %d\n" + +#: access/heap/vacuumlazy.c:2603 +#, fuzzy, c-format +#| msgid "oldest xmin is far in the past" +msgid "table's relfrozenxid or relminmxid is too far in the past" +msgstr "älteste xmin ist weit in der Vergangenheit" + +#: access/heap/vacuumlazy.c:2604 +#, c-format +msgid "" +"Consider increasing configuration parameter \"maintenance_work_mem\" or \"autovacuum_work_mem\".\n" +"You might also need to consider other ways for VACUUM to keep up with the allocation of transaction IDs." +msgstr "" + +#: access/heap/vacuumlazy.c:2744 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "%d parallelen Vacuum-Worker für Index-Cleanup gestartet (geplant: %d)" +msgstr[1] "%d parallele Vacuum-Worker für Index-Cleanup gestartet (geplant: %d)" + +#: access/heap/vacuumlazy.c:2750 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "%d parallelen Vacuum-Worker für Index-Vacuum gestartet (geplant: %d)" +msgstr[1] "%d parallele Vacuum-Worker für Index-Vacuum gestartet (geplant: %d)" + +#: access/heap/vacuumlazy.c:3039 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "Index »%s« gelesen und %d Zeilenversionen entfernt" + +#: access/heap/vacuumlazy.c:3096 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "Index »%s« enthält %.0f Zeilenversionen in %u Seiten" + +#: access/heap/vacuumlazy.c:3100 +#, fuzzy, c-format +#| msgid "" +#| "%.0f index row versions were removed.\n" +#| "%u index pages have been deleted, %u are currently reusable.\n" +#| "%s." +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages were newly deleted.\n" +"%u index pages are currently deleted, of which %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f Indexzeilenversionen wurde entfernt.\n" +"%u Indexseiten wurden gelöscht, %u sind gegenwärtig wiederverwendbar.\n" +"%s." + +#: access/heap/vacuumlazy.c:3212 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "»%s«: Truncate wird gestoppt wegen Sperrkonflikt" + +#: access/heap/vacuumlazy.c:3278 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "»%s«: von %u auf %u Seiten verkürzt" + +#: access/heap/vacuumlazy.c:3343 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "»%s«: Truncate wird ausgesetzt wegen Sperrkonflikt" + +#: access/heap/vacuumlazy.c:3489 +#, c-format +msgid "disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel" +msgstr "Paralleloption für Vacuum von »%s« wird deaktiviert --- Vacuum in temporären Tabellen kann nicht parallel ausgeführt werden" + +#: access/heap/vacuumlazy.c:4244 +#, fuzzy, c-format +#| msgid "while scanning block %u of relation \"%s.%s\"" +msgid "while scanning block %u and offset %u of relation \"%s.%s\"" +msgstr "beim Scannen von Block %u von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4247 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "beim Scannen von Block %u von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4251 +#, c-format +msgid "while scanning relation \"%s.%s\"" +msgstr "beim Scannen von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4259 +#, fuzzy, c-format +#| msgid "while vacuuming block %u of relation \"%s.%s\"" +msgid "while vacuuming block %u and offset %u of relation \"%s.%s\"" +msgstr "beim Vacuum von Block %u von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4262 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "beim Vacuum von Block %u von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4266 +#, c-format +msgid "while vacuuming relation \"%s.%s\"" +msgstr "beim Vacuum von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4271 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "beim Vacuum von Index »%s« von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4276 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "beim Säubern von Index »%s« von Relation »%s.%s«" + +#: access/heap/vacuumlazy.c:4282 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "beim Trunkieren von Relation »%s.%s« auf %u Blöcke" + +#: access/index/amapi.c:83 commands/amcmds.c:143 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "Zugriffsmethode »%s« ist nicht vom Typ %s" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "Indexzugriffsmethode »%s« hat keinen Handler" + +#: access/index/genam.c:486 +#, c-format +msgid "transaction aborted during system catalog scan" +msgstr "Transaktion während eines Systemkatalog-Scans abgebrochen" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1355 +#: commands/indexcmds.c:2670 commands/tablecmds.c:267 commands/tablecmds.c:291 +#: commands/tablecmds.c:16493 commands/tablecmds.c:18195 +#, c-format +msgid "\"%s\" is not an index" +msgstr "»%s« ist kein Index" + +#: access/index/indexam.c:973 +#, c-format +msgid "operator class %s has no options" +msgstr "Operatorklasse %s hat keine Optionen" + +#: access/nbtree/nbtinsert.c:665 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "doppelter Schlüsselwert verletzt Unique-Constraint »%s«" + +#: access/nbtree/nbtinsert.c:667 +#, c-format +msgid "Key %s already exists." +msgstr "Schlüssel »%s« existiert bereits." + +#: access/nbtree/nbtinsert.c:761 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Das kann daran liegen, dass der Indexausdruck nicht »immutable« ist." + +#: access/nbtree/nbtpage.c:159 access/nbtree/nbtpage.c:608 +#: parser/parse_utilcmd.c:2329 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "Index »%s« ist kein B-Tree" + +#: access/nbtree/nbtpage.c:166 access/nbtree/nbtpage.c:615 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "keine Versionsübereinstimmung in Index »%s«: Dateiversion %d, aktuelle Version %d, kleinste unterstützte Version %d" + +#: access/nbtree/nbtpage.c:1875 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "Index »%s« enthält eine halbtote interne Seite" + +#: access/nbtree/nbtpage.c:1877 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "Die Ursache kann ein unterbrochenes VACUUM in Version 9.3 oder älter vor dem Upgrade sein. Bitte REINDEX durchführen." + +#: access/nbtree/nbtutils.c:2665 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "Größe %zu der Indexzeile überschreitet btree-Version %u Maximum %zu für Index »%s«" + +#: access/nbtree/nbtutils.c:2671 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "Indexzeile verweist auf Tupel (%u,%u) in Relation »%s«." + +#: access/nbtree/nbtutils.c:2675 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"Werte, die größer sind als 1/3 einer Pufferseite, können nicht indiziert werden.\n" +"Erstellen Sie eventuell einen Funktionsindex auf einen MD5-Hash oder verwenden Sie Volltextindizierung." + +#: access/nbtree/nbtvalidate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion für Typen %s und %s" + +#: access/spgist/spgutils.c:232 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "Compress-Methode muss definiert sein, wenn der Leaf-Typ verschieden vom Eingabetyp ist" + +#: access/spgist/spgutils.c:1005 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "innere Tupelgröße %zu überschreitet SP-GiST-Maximum %zu" + +#: access/spgist/spgvalidate.c:136 +#, c-format +msgid "SP-GiST leaf data type %s does not match declared type %s" +msgstr "SP-GiST-Leaf-Datentyp %s stimmt nicht mit deklariertem Typ %s überein" + +#: access/spgist/spgvalidate.c:302 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion %d für Typ %s" + +#: access/table/table.c:49 access/table/table.c:83 access/table/table.c:112 +#: access/table/table.c:145 catalog/aclchk.c:1792 +#, c-format +msgid "\"%s\" is an index" +msgstr "»%s« ist ein Index" + +#: access/table/table.c:54 access/table/table.c:88 access/table/table.c:117 +#: access/table/table.c:150 catalog/aclchk.c:1799 commands/tablecmds.c:13198 +#: commands/tablecmds.c:16502 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "»%s« ist ein zusammengesetzter Typ" + +#: access/table/tableam.c:266 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "tid (%u, %u) ist nicht gültig für Relation »%s«" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "%s kann nicht leer sein." + +#: access/table/tableamapi.c:122 utils/misc/guc.c:12438 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s ist zu lang (maximal %d Zeichen)." + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "Tabellenzugriffsmethode »%s« existiert nicht" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "Tabellenzugriffsmethode »%s« existiert nicht." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "Stichprobenprozentsatz muss zwischen 0 und 100 sein" + +#: access/transam/commit_ts.c:278 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "Commit-Timestamp von Transaktion %u kann nicht abgefragt werden" + +#: access/transam/commit_ts.c:376 +#, c-format +msgid "could not get commit timestamp data" +msgstr "konnte Commit-Timestamp-Daten nicht auslesen" + +#: access/transam/commit_ts.c:378 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the primary server." +msgstr "Stellen Sie sicher, dass der Konfigurationsparameter »%s« auf dem Primärserver gesetzt ist." + +#: access/transam/commit_ts.c:380 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "Stellen Sie sicher, dass der Konfigurationsparameter »%s« gesetzt ist." + +#: access/transam/multixact.c:1021 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "Datenbank nimmt keine Befehle an, die neue MultiXactIds erzeugen, um Datenverlust wegen Transaktionsnummernüberlauf in Datenbank »%s« zu vermeiden" + +#: access/transam/multixact.c:1023 access/transam/multixact.c:1030 +#: access/transam/multixact.c:1054 access/transam/multixact.c:1063 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Führen Sie ein datenbankweites VACUUM in dieser Datenbank aus.\n" +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." + +#: access/transam/multixact.c:1028 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "Datenbank nimmt keine Befehle an, die neue MultiXactIds erzeugen, um Datenverlust wegen Transaktionsnummernüberlauf in Datenbank mit OID %u zu vermeiden" + +#: access/transam/multixact.c:1049 access/transam/multixact.c:2330 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "Datenbank »%s« muss gevacuumt werden, bevor %u weitere MultiXactId aufgebraucht ist" +msgstr[1] "Datenbank »%s« muss gevacuumt werden, bevor %u weitere MultiXactIds aufgebraucht sind" + +#: access/transam/multixact.c:1058 access/transam/multixact.c:2339 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "Datenbank mit OID %u muss gevacuumt werden, bevor %u weitere MultiXactId aufgebraucht ist" +msgstr[1] "Datenbank mit OID %u muss gevacuumt werden, bevor %u weitere MultiXactIds aufgebraucht sind" + +#: access/transam/multixact.c:1119 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "Grenzwert für Multixact-»Members« überschritten" + +#: access/transam/multixact.c:1120 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "Dieser Befehl würde eine Multixact mit %u Mitgliedern erzeugen, aber es ist nur genug Platz für %u Mitglied." +msgstr[1] "Dieser Befehl würde eine Multixact mit %u Mitgliedern erzeugen, aber es ist nur genug Platz für %u Mitglieder." + +#: access/transam/multixact.c:1125 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Führen Sie ein datenbankweites VACUUM in der Datenbank mit OID %u aus, mit reduzierten Einstellungen für vacuum_multixact_freeze_min_age und vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1156 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "Datenbank mit OID %u muss gevacuumt werden, bevor %d weiteres Multixact-Mitglied aufgebraucht ist" +msgstr[1] "Datenbank mit OID %u muss gevacuumt werden, bevor %d weitere Multixact-Mitglieder aufgebraucht sind" + +#: access/transam/multixact.c:1161 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Führen Sie ein datenbankweites VACUUM in dieser Datenbank aus, mit reduzierten Einstellungen für vacuum_multixact_freeze_min_age und vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1298 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "MultiXactId %u existiert nicht mehr -- anscheinender Überlauf" + +#: access/transam/multixact.c:1306 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "MultiXactId %u wurde noch nicht erzeugt -- anscheinender Überlauf" + +#: access/transam/multixact.c:2335 access/transam/multixact.c:2344 +#: access/transam/varsup.c:151 access/transam/varsup.c:158 +#: access/transam/varsup.c:466 access/transam/varsup.c:473 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Um ein Abschalten der Datenbank zu vermeiden, führen Sie ein komplettes VACUUM über diese Datenbank aus.\n" +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." + +#: access/transam/multixact.c:2618 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "MultiXact-Member-Wraparound-Schutz ist deaktiviert, weil die älteste gecheckpointete MultiXact %u nicht auf der Festplatte existiert" + +#: access/transam/multixact.c:2640 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "MultiXact-Member-Wraparound-Schutz ist jetzt aktiviert" + +#: access/transam/multixact.c:3027 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "älteste MultiXact %u nicht gefunden, älteste ist MultiXact %u, Truncate wird ausgelassen" + +#: access/transam/multixact.c:3045 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "kann nicht bis MultiXact %u trunkieren, weil sie nicht auf der Festplatte existiert, Trunkierung wird ausgelassen" + +#: access/transam/multixact.c:3359 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "ungültige MultiXactId: %u" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "Initialisierung von parallelem Arbeitsprozess fehlgeschlagen" + +#: access/transam/parallel.c:708 access/transam/parallel.c:827 +#, c-format +msgid "More details may be available in the server log." +msgstr "Weitere Einzelheiten sind möglicherweise im Serverlog zu finden." + +#: access/transam/parallel.c:888 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "Postmaster beendete während einer parallelen Transaktion" + +#: access/transam/parallel.c:1075 +#, c-format +msgid "lost connection to parallel worker" +msgstr "Verbindung mit parallelem Arbeitsprozess verloren" + +#: access/transam/parallel.c:1141 access/transam/parallel.c:1143 +msgid "parallel worker" +msgstr "paralleler Arbeitsprozess" + +#: access/transam/parallel.c:1294 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "konnte dynamisches Shared-Memory-Segment nicht mappen" + +#: access/transam/parallel.c:1299 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "ungültige magische Zahl in dynamischem Shared-Memory-Segment" + +#: access/transam/slru.c:712 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "Datei »%s« existiert nicht, wird als Nullen eingelesen" + +#: access/transam/slru.c:944 access/transam/slru.c:950 +#: access/transam/slru.c:958 access/transam/slru.c:963 +#: access/transam/slru.c:970 access/transam/slru.c:975 +#: access/transam/slru.c:982 access/transam/slru.c:989 +#, c-format +msgid "could not access status of transaction %u" +msgstr "konnte auf den Status von Transaktion %u nicht zugreifen" + +#: access/transam/slru.c:945 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "Konnte Datei »%s« nicht öffnen: %m." + +#: access/transam/slru.c:951 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "Konnte Positionszeiger in Datei »%s« nicht auf %u setzen: %m." + +#: access/transam/slru.c:959 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "Konnte nicht aus Datei »%s« bei Position %u lesen: %m." + +#: access/transam/slru.c:964 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "Konnte nicht aus Datei »%s« bei Position %u lesen: zu wenige Bytes gelesen." + +#: access/transam/slru.c:971 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "Konnte nicht in Datei »%s« bei Position %u schreiben: %m." + +#: access/transam/slru.c:976 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "Konnte nicht in Datei »%s« bei Position %u schreiben: zu wenige Bytes geschrieben." + +#: access/transam/slru.c:983 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "Konnte Datei »%s« nicht fsyncen: %m." + +#: access/transam/slru.c:990 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "Konnte Datei »%s« nicht schließen: %m." + +#: access/transam/slru.c:1251 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "konnte Verzeichnis »%s« nicht leeren: anscheinender Überlauf" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "Syntaxfehler in History-Datei: %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Eine numerische Zeitleisten-ID wurde erwartet." + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Eine Write-Ahead-Log-Switchpoint-Position wurde erwartet." + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "ungültige Daten in History-Datei: %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Zeitleisten-IDs müssen in aufsteigender Folge sein." + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "ungültige Daten in History-Datei »%s«" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Zeitleisten-IDs müssen kleiner als die Zeitleisten-ID des Kindes sein." + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "angeforderte Zeitleiste %u ist nicht in der History dieses Servers" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "Transaktionsbezeichner »%s« ist zu lang" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "vorbereitete Transaktionen sind abgeschaltet" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "Setzen Sie max_prepared_transactions auf einen Wert höher als null." + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "Transaktionsbezeichner »%s« wird bereits verwendet" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2385 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "maximale Anzahl vorbereiteter Transaktionen erreicht" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2386 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "Erhöhen Sie max_prepared_transactions (aktuell %d)." + +#: access/transam/twophase.c:584 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "vorbereitete Transaktion mit Bezeichner »%s« ist beschäftigt" + +#: access/transam/twophase.c:590 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "keine Berechtigung, um vorbereitete Transaktion abzuschließen" + +#: access/transam/twophase.c:591 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "Sie müssen Superuser oder der Benutzer sein, der die Transaktion vorbereitet hat." + +#: access/transam/twophase.c:602 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "vorbereitete Transaktion gehört zu einer anderen Datenbank" + +#: access/transam/twophase.c:603 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "Verbinden Sie sich mit der Datenbank, wo die Transaktion vorbereitet wurde, um sie zu beenden." + +#: access/transam/twophase.c:618 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "vorbereitete Transaktion mit Bezeichner »%s« existiert nicht" + +#: access/transam/twophase.c:1093 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "maximale Länge der Zweiphasen-Statusdatei überschritten" + +#: access/transam/twophase.c:1247 +#, c-format +msgid "incorrect size of file \"%s\": %lld byte" +msgid_plural "incorrect size of file \"%s\": %lld bytes" +msgstr[0] "falsche Größe von Datei »%s«: %lld Byte" +msgstr[1] "falsche Größe von Datei »%s«: %lld Bytes" + +#: access/transam/twophase.c:1256 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "falsche Ausrichtung des CRC-Offsets für Datei »%s«" + +#: access/transam/twophase.c:1274 +#, c-format +msgid "could not read file \"%s\": read %d of %lld" +msgstr "konnte Datei »%s« nicht lesen: %d von %lld gelesen" + +#: access/transam/twophase.c:1289 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "ungültige magische Zahl in Datei »%s gespeichert«" + +#: access/transam/twophase.c:1295 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "ungültige Größe in Datei »%s« gespeichert" + +#: access/transam/twophase.c:1307 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "berechnete CRC-Prüfsumme stimmt nicht mit dem Wert in Datei »%s« überein" + +#: access/transam/twophase.c:1342 access/transam/xlog.c:6634 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "Fehlgeschlagen beim Anlegen eines WAL-Leseprozessors." + +#: access/transam/twophase.c:1357 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "konnte Zweiphasen-Status nicht aus dem WAL bei %X/%X lesen" + +#: access/transam/twophase.c:1364 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "erwartete Zweiphasen-Status-Daten sind nicht im WAL bei %X/%X vorhanden" + +#: access/transam/twophase.c:1641 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "konnte Datei »%s« nicht neu erzeugen: %m" + +#: access/transam/twophase.c:1768 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "%u Zweiphasen-Statusdatei wurde für eine lange laufende vorbereitete Transaktion geschrieben" +msgstr[1] "%u Zweiphasen-Statusdateien wurden für lange laufende vorbereitete Transaktionen geschrieben" + +#: access/transam/twophase.c:2002 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "Wiederherstellung der vorbereiteten Transaktion %u aus dem Shared Memory" + +#: access/transam/twophase.c:2093 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "entferne abgelaufene Zweiphasen-Statusdatei für Transaktion %u" + +#: access/transam/twophase.c:2100 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "entferne abgelaufenen Zweiphasen-Status aus dem Speicher für Transaktion %u" + +#: access/transam/twophase.c:2113 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "entferne zukünftige Zweiphasen-Statusdatei für Transaktion %u" + +#: access/transam/twophase.c:2120 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "entferne zukünftigen Zweiphasen-Status aus dem Speicher für Transaktion %u" + +#: access/transam/twophase.c:2145 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "verfälschte Zweiphasen-Statusdatei für Transaktion %u" + +#: access/transam/twophase.c:2150 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "verfälschter Zweiphasen-Status im Speicher für Transaktion %u" + +#: access/transam/varsup.c:129 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "Datenbank nimmt keine Befehle an, um Datenverlust wegen Transaktionsnummernüberlauf in Datenbank »%s« zu vermeiden" + +#: access/transam/varsup.c:131 access/transam/varsup.c:138 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Halten Sie den Postmaster an und führen Sie in dieser Datenbank VACUUM im Einzelbenutzermodus aus.\n" +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." + +#: access/transam/varsup.c:136 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "Datenbank nimmt keine Befehle an, um Datenverlust wegen Transaktionsnummernüberlauf in Datenbank mit OID %u zu vermeiden" + +#: access/transam/varsup.c:148 access/transam/varsup.c:463 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "Datenbank »%s« muss innerhalb von %u Transaktionen gevacuumt werden" + +#: access/transam/varsup.c:155 access/transam/varsup.c:470 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "Datenbank mit OID %u muss innerhalb von %u Transaktionen gevacuumt werden" + +#: access/transam/xact.c:1045 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "kann nicht mehr als 2^32-2 Befehle in einer Transaktion ausführen" + +#: access/transam/xact.c:1582 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "maximale Anzahl committeter Subtransaktionen (%d) überschritten" + +#: access/transam/xact.c:2423 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die temporäre Objekte bearbeitet hat" + +#: access/transam/xact.c:2433 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die Snapshots exportiert hat" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3388 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s kann nicht in einem Transaktionsblock laufen" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3398 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s kann nicht in einer Subtransaktion laufen" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3408 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s kann nicht aus einer Funktion ausgeführt werden" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3477 access/transam/xact.c:3783 +#: access/transam/xact.c:3862 access/transam/xact.c:3985 +#: access/transam/xact.c:4136 access/transam/xact.c:4205 +#: access/transam/xact.c:4316 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s kann nur in Transaktionsblöcken verwendet werden" + +#: access/transam/xact.c:3669 +#, c-format +msgid "there is already a transaction in progress" +msgstr "eine Transaktion ist bereits begonnen" + +#: access/transam/xact.c:3788 access/transam/xact.c:3867 +#: access/transam/xact.c:3990 +#, c-format +msgid "there is no transaction in progress" +msgstr "keine Transaktion offen" + +#: access/transam/xact.c:3878 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "während einer parallelen Operation kann nicht committet werden" + +#: access/transam/xact.c:4001 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "während einer parallelen Operation kann nicht abgebrochen werden" + +#: access/transam/xact.c:4100 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "während einer parallelen Operation können keine Sicherungspunkte definiert werden" + +#: access/transam/xact.c:4187 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "während einer parallelen Operation können keine Sicherungspunkte freigegeben werden" + +#: access/transam/xact.c:4197 access/transam/xact.c:4248 +#: access/transam/xact.c:4308 access/transam/xact.c:4357 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "Sicherungspunkt »%s« existiert nicht" + +#: access/transam/xact.c:4254 access/transam/xact.c:4363 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "Sicherungspunkt »%s« existiert nicht innerhalb der aktuellen Sicherungspunktebene" + +#: access/transam/xact.c:4296 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "während einer parallelen Operation kann nicht auf einen Sicherungspunkt zurückgerollt werden" + +#: access/transam/xact.c:4424 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "während einer parallelen Operation können keine Subtransaktionen gestartet werden" + +#: access/transam/xact.c:4492 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "während einer parallelen Operation können keine Subtransaktionen committet werden" + +#: access/transam/xact.c:5133 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "kann nicht mehr als 2^32-1 Subtransaktionen in einer Transaktion haben" + +#: access/transam/xlog.c:1825 +#, c-format +msgid "request to flush past end of generated WAL; request %X/%X, current position %X/%X" +msgstr "" + +#: access/transam/xlog.c:2586 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "konnte nicht in Logdatei %s bei Position %u, Länge %zu schreiben: %m" + +#: access/transam/xlog.c:3988 access/transam/xlogutils.c:798 +#: replication/walsender.c:2520 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "das angeforderte WAL-Segment %s wurde schon entfernt" + +#: access/transam/xlog.c:4263 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "konnte Datei »%s« nicht umbenennen: %m" + +#: access/transam/xlog.c:4305 access/transam/xlog.c:4315 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "benötigtes WAL-Verzeichnis »%s« existiert nicht" + +#: access/transam/xlog.c:4321 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "erzeuge fehlendes WAL-Verzeichnis »%s«" + +#: access/transam/xlog.c:4324 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "konnte fehlendes Verzeichnis »%s« nicht erzeugen: %m" + +#: access/transam/xlog.c:4427 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "unerwartete Zeitleisten-ID %u in Logsegment %s, Offset %u" + +#: access/transam/xlog.c:4565 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "neue Zeitleiste %u ist kein Kind der Datenbanksystemzeitleiste %u" + +#: access/transam/xlog.c:4579 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "neue Zeitleiste %u zweigte von der aktuellen Datenbanksystemzeitleiste %u vor dem aktuellen Wiederherstellungspunkt %X/%X ab" + +#: access/transam/xlog.c:4598 +#, c-format +msgid "new target timeline is %u" +msgstr "neue Zielzeitleiste ist %u" + +#: access/transam/xlog.c:4634 +#, c-format +msgid "could not generate secret authorization token" +msgstr "konnte geheimes Autorisierungstoken nicht erzeugen" + +#: access/transam/xlog.c:4793 access/transam/xlog.c:4802 +#: access/transam/xlog.c:4826 access/transam/xlog.c:4833 +#: access/transam/xlog.c:4840 access/transam/xlog.c:4845 +#: access/transam/xlog.c:4852 access/transam/xlog.c:4859 +#: access/transam/xlog.c:4866 access/transam/xlog.c:4873 +#: access/transam/xlog.c:4880 access/transam/xlog.c:4887 +#: access/transam/xlog.c:4896 access/transam/xlog.c:4903 +#: utils/init/miscinit.c:1578 +#, c-format +msgid "database files are incompatible with server" +msgstr "Datenbankdateien sind inkompatibel mit Server" + +#: access/transam/xlog.c:4794 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "Der Datenbank-Cluster wurde mit PG_CONTROL_VERSION %d (0x%08x) initialisiert, aber der Server wurde mit PG_CONTROL_VERSION %d (0x%08x) kompiliert." + +#: access/transam/xlog.c:4798 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "Das Problem könnte eine falsche Byte-Reihenfolge sein. Es sieht so aus, dass Sie initdb ausführen müssen." + +#: access/transam/xlog.c:4803 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "Der Datenbank-Cluster wurde mit PG_CONTROL_VERSION %d initialisiert, aber der Server wurde mit PG_CONTROL_VERSION %d kompiliert." + +#: access/transam/xlog.c:4806 access/transam/xlog.c:4830 +#: access/transam/xlog.c:4837 access/transam/xlog.c:4842 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Es sieht so aus, dass Sie initdb ausführen müssen." + +#: access/transam/xlog.c:4817 +#, c-format +msgid "incorrect checksum in control file" +msgstr "falsche Prüfsumme in Kontrolldatei" + +#: access/transam/xlog.c:4827 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "Der Datenbank-Cluster wurde mit CATALOG_VERSION_NO %d initialisiert, aber der Server wurde mit CATALOG_VERSION_NO %d kompiliert." + +#: access/transam/xlog.c:4834 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "Der Datenbank-Cluster wurde mit MAXALIGN %d initialisiert, aber der Server wurde mit MAXALIGN %d kompiliert." + +#: access/transam/xlog.c:4841 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "Der Datenbank-Cluster verwendet anscheinend ein anderes Fließkommazahlenformat als das Serverprogramm." + +#: access/transam/xlog.c:4846 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "Der Datenbank-Cluster wurde mit BLCKSZ %d initialisiert, aber der Server wurde mit BLCKSZ %d kompiliert." + +#: access/transam/xlog.c:4849 access/transam/xlog.c:4856 +#: access/transam/xlog.c:4863 access/transam/xlog.c:4870 +#: access/transam/xlog.c:4877 access/transam/xlog.c:4884 +#: access/transam/xlog.c:4891 access/transam/xlog.c:4899 +#: access/transam/xlog.c:4906 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Es sieht so aus, dass Sie neu kompilieren oder initdb ausführen müssen." + +#: access/transam/xlog.c:4853 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "Der Datenbank-Cluster wurde mit RELSEG_SIZE %d initialisiert, aber der Server wurde mit RELSEGSIZE %d kompiliert." + +#: access/transam/xlog.c:4860 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "Der Datenbank-Cluster wurde mit XLOG_BLCKSZ %d initialisiert, aber der Server wurde mit XLOG_BLCKSZ %d kompiliert." + +#: access/transam/xlog.c:4867 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "Der Datenbank-Cluster wurde mit NAMEDATALEN %d initialisiert, aber der Server wurde mit NAMEDATALEN %d kompiliert." + +#: access/transam/xlog.c:4874 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "Der Datenbank-Cluster wurde mit INDEX_MAX_KEYS %d initialisiert, aber der Server wurde mit INDEX_MAX_KEYS %d kompiliert." + +#: access/transam/xlog.c:4881 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "Der Datenbank-Cluster wurde mit TOAST_MAX_CHUNK_SIZE %d initialisiert, aber der Server wurde mit TOAST_MAX_CHUNK_SIZE %d kompiliert." + +#: access/transam/xlog.c:4888 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "Der Datenbank-Cluster wurde mit LOBLKSIZE %d initialisiert, aber der Server wurde mit LOBLKSIZE %d kompiliert." + +#: access/transam/xlog.c:4897 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "Der Datenbank-Cluster wurde ohne USE_FLOAT8_BYVAL initialisiert, aber der Server wurde mit USE_FLOAT8_BYVAL kompiliert." + +#: access/transam/xlog.c:4904 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "Der Datenbank-Cluster wurde mit USE_FLOAT8_BYVAL initialisiert, aber der Server wurde ohne USE_FLOAT8_BYVAL kompiliert." + +#: access/transam/xlog.c:4913 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Byte an" +msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Bytes an" + +#: access/transam/xlog.c:4925 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "»min_wal_size« muss mindestens zweimal so groß wie »wal_segment_size« sein" + +#: access/transam/xlog.c:4929 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "»max_wal_size« muss mindestens zweimal so groß wie »wal_segment_size« sein" + +#: access/transam/xlog.c:5363 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "konnte Bootstrap-Write-Ahead-Log-Datei nicht schreiben: %m" + +#: access/transam/xlog.c:5371 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "konnte Bootstrap-Write-Ahead-Log-Datei nicht fsyncen: %m" + +#: access/transam/xlog.c:5377 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "konnte Bootstrap-Write-Ahead-Log-Datei nicht schließen: %m" + +#: access/transam/xlog.c:5438 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "Verwendung von Recovery-Befehlsdatei »%s« wird nicht unterstützt" + +#: access/transam/xlog.c:5503 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "Standby-Modus wird von Servern im Einzelbenutzermodus nicht unterstützt" + +#: access/transam/xlog.c:5520 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "weder primary_conninfo noch restore_command angegeben" + +#: access/transam/xlog.c:5521 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "Der Datenbankserver prüft das Unterverzeichnis pg_wal regelmäßig auf dort abgelegte Dateien." + +#: access/transam/xlog.c:5529 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "restore_command muss angegeben werden, wenn der Standby-Modus nicht eingeschaltet ist" + +#: access/transam/xlog.c:5567 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "recovery_target_timeline %u existiert nicht" + +#: access/transam/xlog.c:5689 +#, c-format +msgid "archive recovery complete" +msgstr "Wiederherstellung aus Archiv abgeschlossen" + +#: access/transam/xlog.c:5755 access/transam/xlog.c:6026 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "Wiederherstellung beendet nachdem Konsistenz erreicht wurde" + +#: access/transam/xlog.c:5776 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "Wiederherstellung beendet vor WAL-Position (LSN) »%X/%X«" + +#: access/transam/xlog.c:5861 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "Wiederherstellung beendet vor Commit der Transaktion %u, Zeit %s" + +#: access/transam/xlog.c:5868 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "Wiederherstellung beendet vor Abbruch der Transaktion %u, Zeit %s" + +#: access/transam/xlog.c:5921 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "Wiederherstellung beendet bei Restore-Punkt »%s«, Zeit %s" + +#: access/transam/xlog.c:5939 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "Wiederherstellung beendet nach WAL-Position (LSN) »%X/%X«" + +#: access/transam/xlog.c:6006 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "Wiederherstellung beendet nach Commit der Transaktion %u, Zeit %s" + +#: access/transam/xlog.c:6014 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "Wiederherstellung beendet nach Abbruch der Transaktion %u, Zeit %s" + +#: access/transam/xlog.c:6059 +#, c-format +msgid "pausing at the end of recovery" +msgstr "pausiere am Ende der Wiederherstellung" + +#: access/transam/xlog.c:6060 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "Führen Sie pg_wal_replay_resume() aus, um den Server zum Primärserver zu befördern." + +#: access/transam/xlog.c:6063 access/transam/xlog.c:6336 +#, c-format +msgid "recovery has paused" +msgstr "Wiederherstellung wurde pausiert" + +#: access/transam/xlog.c:6064 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Führen Sie pg_wal_replay_resume() aus um fortzusetzen." + +#: access/transam/xlog.c:6327 +#, c-format +msgid "hot standby is not possible because of insufficient parameter settings" +msgstr "Hot Standby ist nicht möglich wegen unzureichender Parametereinstellungen" + +#: access/transam/xlog.c:6328 access/transam/xlog.c:6355 +#: access/transam/xlog.c:6385 +#, c-format +msgid "%s = %d is a lower setting than on the primary server, where its value was %d." +msgstr "%s = %d ist eine niedrigere Einstellung als auf dem Primärserver, wo der Wert %d war." + +#: access/transam/xlog.c:6337 +#, c-format +msgid "If recovery is unpaused, the server will shut down." +msgstr "Wenn die Wiederherstellungspause beendet wird, wird der Server herunterfahren." + +#: access/transam/xlog.c:6338 +#, c-format +msgid "You can then restart the server after making the necessary configuration changes." +msgstr "Sie können den Server dann neu starten, nachdem die nötigen Konfigurationsänderungen getätigt worden sind." + +#: access/transam/xlog.c:6349 +#, c-format +msgid "promotion is not possible because of insufficient parameter settings" +msgstr "Beförderung ist nicht möglich wegen unzureichender Parametereinstellungen" + +#: access/transam/xlog.c:6359 +#, c-format +msgid "Restart the server after making the necessary configuration changes." +msgstr "Starten Sie den Server neu, nachdem die nötigen Konfigurationsänderungen getätigt worden sind." + +#: access/transam/xlog.c:6383 +#, c-format +msgid "recovery aborted because of insufficient parameter settings" +msgstr "Wiederherstellung abgebrochen wegen unzureichender Parametereinstellungen" + +#: access/transam/xlog.c:6389 +#, c-format +msgid "You can restart the server after making the necessary configuration changes." +msgstr "Sie können den Server neu starten, nachdem die nötigen Konfigurationsänderungen getätigt worden sind." + +#: access/transam/xlog.c:6411 +#, c-format +msgid "WAL was generated with wal_level=minimal, cannot continue recovering" +msgstr "WAL wurde mit wal_level=minimal erzeugt, Wiederherstellung kann nicht fortgesetzt werden" + +#: access/transam/xlog.c:6412 +#, c-format +msgid "This happens if you temporarily set wal_level=minimal on the server." +msgstr "Das passiert, wenn auf dem Server vorübergehend wal_level=minimal gesetzt wurde." + +#: access/transam/xlog.c:6413 +#, c-format +msgid "Use a backup taken after setting wal_level to higher than minimal." +msgstr "Verwenden Sie ein Backup, das durchgeführt wurde, nachdem wal_level auf höher als minimal gesetzt wurde." + +#: access/transam/xlog.c:6482 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "Kontrolldatei enthält ungültige Checkpoint-Position" + +#: access/transam/xlog.c:6493 +#, c-format +msgid "database system was shut down at %s" +msgstr "Datenbanksystem wurde am %s heruntergefahren" + +#: access/transam/xlog.c:6499 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "Datenbanksystem wurde während der Wiederherstellung am %s heruntergefahren" + +#: access/transam/xlog.c:6505 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "Datenbanksystem wurde beim Herunterfahren unterbrochen; letzte bekannte Aktion am %s" + +#: access/transam/xlog.c:6511 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "Datenbanksystem wurde während der Wiederherstellung am %s unterbrochen" + +#: access/transam/xlog.c:6513 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "Das bedeutet wahrscheinlich, dass einige Daten verfälscht sind und Sie die letzte Datensicherung zur Wiederherstellung verwenden müssen." + +#: access/transam/xlog.c:6519 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "Datenbanksystem wurde während der Wiederherstellung bei Logzeit %s unterbrochen" + +#: access/transam/xlog.c:6521 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "Wenn dies mehr als einmal vorgekommen ist, dann sind einige Daten möglicherweise verfälscht und Sie müssen ein früheres Wiederherstellungsziel wählen." + +#: access/transam/xlog.c:6527 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "Datenbanksystem wurde unterbrochen; letzte bekannte Aktion am %s" + +#: access/transam/xlog.c:6533 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "Kontrolldatei enthält ungültigen Datenbankclusterstatus" + +#: access/transam/xlog.c:6590 +#, c-format +msgid "entering standby mode" +msgstr "Standby-Modus eingeschaltet" + +#: access/transam/xlog.c:6593 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "starte Point-in-Time-Recovery bis XID %u" + +#: access/transam/xlog.c:6597 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "starte Point-in-Time-Recovery bis %s" + +#: access/transam/xlog.c:6601 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "starte Point-in-Time-Recovery bis »%s«" + +#: access/transam/xlog.c:6605 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "starte Point-in-Time-Recovery bis WAL-Position (LSN) »%X/%X«" + +#: access/transam/xlog.c:6609 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "starte Point-in-Time-Recovery bis zum frühesten konsistenten Punkt" + +#: access/transam/xlog.c:6612 +#, c-format +msgid "starting archive recovery" +msgstr "starte Wiederherstellung aus Archiv" + +#: access/transam/xlog.c:6686 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "konnte die vom Checkpoint-Datensatz referenzierte Redo-Position nicht finden" + +#: access/transam/xlog.c:6687 access/transam/xlog.c:6697 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" +"Wenn Sie gerade ein Backup wiederherstellen, dann erzeugen Sie »%s/recovery.signal« und setzen Sie die notwendigen Recovery-Optionen.\n" +"Wenn Sie gerade kein Backup wiederherstellen, dann versuchen Sie, die Datei »%s/backup_label« zu entfernen.\n" +"Vorsicht: Wenn ein Backup wiederhergestellt wird und »%s/backup_label« gelöscht wird, dann wird das den Cluster verfälschen." + +#: access/transam/xlog.c:6696 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "konnte den nötigen Checkpoint-Datensatz nicht finden" + +#: access/transam/xlog.c:6725 commands/tablespace.c:666 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" + +#: access/transam/xlog.c:6757 access/transam/xlog.c:6763 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "ignoriere Datei »%s«, weil keine Datei »%s« existiert" + +#: access/transam/xlog.c:6759 access/transam/xlog.c:12060 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "Datei »%s« wurde in »%s« umbenannt." + +#: access/transam/xlog.c:6765 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "Konnte Datei »%s« nicht in »%s« umbenennen: %m." + +#: access/transam/xlog.c:6816 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "konnte keinen gültigen Checkpoint-Datensatz finden" + +#: access/transam/xlog.c:6854 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "angeforderte Zeitleiste %u ist kein Kind der History dieses Servers" + +#: access/transam/xlog.c:6856 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "Neuester Checkpoint ist bei %X/%X auf Zeitleiste %u, aber in der History der angeforderten Zeitleiste zweigte der Server von dieser Zeitleiste bei %X/%X ab." + +#: access/transam/xlog.c:6870 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "angeforderte Zeitleiste %u enthält nicht den minimalen Wiederherstellungspunkt %X/%X auf Zeitleiste %u" + +#: access/transam/xlog.c:6900 +#, c-format +msgid "invalid next transaction ID" +msgstr "ungültige nächste Transaktions-ID" + +#: access/transam/xlog.c:7000 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "ungültiges Redo im Checkpoint-Datensatz" + +#: access/transam/xlog.c:7011 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "ungültiger Redo-Datensatz im Shutdown-Checkpoint" + +#: access/transam/xlog.c:7045 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "Datenbanksystem wurde nicht richtig heruntergefahren; automatische Wiederherstellung läuft" + +#: access/transam/xlog.c:7049 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "Wiederherstellung nach Absturz beginnt in Zeitleiste %u und hat Zielzeitleiste %u" + +#: access/transam/xlog.c:7096 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "Daten in backup_label stimmen nicht mit Kontrolldatei überein" + +#: access/transam/xlog.c:7097 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "Das bedeutet, dass die Datensicherung verfälscht ist und Sie eine andere Datensicherung zur Wiederherstellung verwenden werden müssen." + +#: access/transam/xlog.c:7323 +#, c-format +msgid "redo starts at %X/%X" +msgstr "Redo beginnt bei %X/%X" + +#: access/transam/xlog.c:7548 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "angeforderter Recovery-Endpunkt ist vor konsistentem Recovery-Punkt" + +#: access/transam/xlog.c:7586 +#, fuzzy, c-format +#| msgid "redo done at %X/%X" +msgid "redo done at %X/%X system usage: %s" +msgstr "Redo fertig bei %X/%X" + +#: access/transam/xlog.c:7592 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "letzte vollständige Transaktion war bei Logzeit %s" + +#: access/transam/xlog.c:7601 +#, c-format +msgid "redo is not required" +msgstr "Redo nicht nötig" + +#: access/transam/xlog.c:7613 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "Wiederherstellung endete bevor das konfigurierte Wiederherstellungsziel erreicht wurde" + +#: access/transam/xlog.c:7692 access/transam/xlog.c:7696 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "WAL endet vor dem Ende der Online-Sicherung" + +#: access/transam/xlog.c:7693 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "Der komplette WAL, der während der Online-Sicherung erzeugt wurde, muss bei der Wiederherstellung verfügbar sein." + +#: access/transam/xlog.c:7697 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "Die mit pg_start_backup() begonnene Online-Sicherung muss mit pg_stop_backup() beendet werden und der ganze WAL bis zu diesem Punkt muss bei der Wiederherstellung verfügbar sein." + +#: access/transam/xlog.c:7700 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL endet vor einem konsistenten Wiederherstellungspunkt" + +#: access/transam/xlog.c:7735 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "gewählte neue Zeitleisten-ID: %u" + +#: access/transam/xlog.c:8178 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "konsistenter Wiederherstellungszustand erreicht bei %X/%X" + +#: access/transam/xlog.c:8387 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "ungültige primäre Checkpoint-Verknüpfung in Kontrolldatei" + +#: access/transam/xlog.c:8391 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "ungültige Checkpoint-Verknüpfung in backup_label-Datei" + +#: access/transam/xlog.c:8409 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "ungültiger primärer Checkpoint-Datensatz" + +#: access/transam/xlog.c:8413 +#, c-format +msgid "invalid checkpoint record" +msgstr "ungültiger Checkpoint-Datensatz" + +#: access/transam/xlog.c:8424 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "ungültige Resource-Manager-ID im primären Checkpoint-Datensatz" + +#: access/transam/xlog.c:8428 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "ungültige Resource-Manager-ID im Checkpoint-Datensatz" + +#: access/transam/xlog.c:8441 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "ungültige xl_info im primären Checkpoint-Datensatz" + +#: access/transam/xlog.c:8445 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "ungültige xl_info im Checkpoint-Datensatz" + +#: access/transam/xlog.c:8456 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "ungültige Länge des primären Checkpoint-Datensatzes" + +#: access/transam/xlog.c:8460 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "ungültige Länge des Checkpoint-Datensatzes" + +#: access/transam/xlog.c:8641 +#, c-format +msgid "shutting down" +msgstr "fahre herunter" + +#. translator: the placeholders show checkpoint options +#: access/transam/xlog.c:8680 +#, c-format +msgid "restartpoint starting:%s%s%s%s%s%s%s%s" +msgstr "Restart-Punkt beginnt:%s%s%s%s%s%s%s%s" + +#. translator: the placeholders show checkpoint options +#: access/transam/xlog.c:8692 +#, c-format +msgid "checkpoint starting:%s%s%s%s%s%s%s%s" +msgstr "Checkpoint beginnt:%s%s%s%s%s%s%s%s" + +#: access/transam/xlog.c:8752 +#, c-format +msgid "restartpoint complete: wrote %d buffers (%.1f%%); %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB" +msgstr "" + +#: access/transam/xlog.c:8772 +#, c-format +msgid "checkpoint complete: wrote %d buffers (%.1f%%); %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB" +msgstr "" + +#: access/transam/xlog.c:9205 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "gleichzeitige Write-Ahead-Log-Aktivität während das Datenbanksystem herunterfährt" + +#: access/transam/xlog.c:9661 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "Recovery-Restart-Punkt bei %X/%X" + +#: access/transam/xlog.c:9663 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Die letzte vollständige Transaktion war bei Logzeit %s." + +#: access/transam/xlog.c:9903 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "Restore-Punkt »%s« erzeugt bei %X/%X" + +#: access/transam/xlog.c:10048 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "unerwartete vorherige Zeitleisten-ID %u (aktuelle Zeitleisten-ID %u) im Checkpoint-Datensatz" + +#: access/transam/xlog.c:10057 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "unerwartete Zeitleisten-ID %u (nach %u) im Checkpoint-Datensatz" + +#: access/transam/xlog.c:10073 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "unerwartete Zeitleisten-ID %u in Checkpoint-Datensatz, bevor der minimale Wiederherstellungspunkt %X/%X auf Zeitleiste %u erreicht wurde" + +#: access/transam/xlog.c:10148 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "Online-Sicherung wurde storniert, Wiederherstellung kann nicht fortgesetzt werden" + +#: access/transam/xlog.c:10204 access/transam/xlog.c:10260 +#: access/transam/xlog.c:10283 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "unerwartete Zeitleisten-ID %u (sollte %u sein) im Checkpoint-Datensatz" + +#: access/transam/xlog.c:10632 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "konnte Write-Through-Logdatei »%s« nicht fsyncen: %m" + +#: access/transam/xlog.c:10638 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "konnte Datei »%s« nicht fdatasyncen: %m" + +#: access/transam/xlog.c:10749 access/transam/xlog.c:11278 +#: access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 +#: access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 +#: access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "Während der Wiederherstellung können keine WAL-Kontrollfunktionen ausgeführt werden." + +#: access/transam/xlog.c:10758 access/transam/xlog.c:11287 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "WAL-Level nicht ausreichend, um Online-Sicherung durchzuführen" + +#: access/transam/xlog.c:10759 access/transam/xlog.c:11288 +#: access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "wal_level muss beim Serverstart auf »replica« oder »logical« gesetzt werden." + +#: access/transam/xlog.c:10764 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "Backup-Label zu lang (maximal %d Bytes)" + +#: access/transam/xlog.c:10801 access/transam/xlog.c:11077 +#: access/transam/xlog.c:11115 +#, c-format +msgid "a backup is already in progress" +msgstr "ein Backup läuft bereits" + +#: access/transam/xlog.c:10802 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "Führen Sie pg_stop_backup() aus und versuchen Sie es nochmal." + +#: access/transam/xlog.c:10898 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "mit full_page_writes=off erzeugtes WAL wurde seit dem letzten Restart-Punkt zurückgespielt" + +#: access/transam/xlog.c:10900 access/transam/xlog.c:11483 +#, c-format +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the primary, and then try an online backup again." +msgstr "Das bedeutet, dass die aktuelle Datensicherung auf dem Standby-Server verfälscht ist und nicht verwendet werden sollte. Schalten Sie auf dem Primärserver full_page_writes ein, führen Sie dort CHECKPOINT aus und versuchen Sie dann die Online-Sicherung erneut." + +#: access/transam/xlog.c:10976 replication/basebackup.c:1433 +#: utils/adt/misc.c:345 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "Ziel für symbolische Verknüpfung »%s« ist zu lang" + +#: access/transam/xlog.c:11026 commands/tablespace.c:402 +#: commands/tablespace.c:578 replication/basebackup.c:1448 utils/adt/misc.c:353 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "Tablespaces werden auf dieser Plattform nicht unterstützt" + +#: access/transam/xlog.c:11078 access/transam/xlog.c:11116 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "Wenn Sie sicher sind, dass noch kein Backup läuft, entfernen Sie die Datei »%s« und versuchen Sie es noch einmal." + +#: access/transam/xlog.c:11303 +#, c-format +msgid "exclusive backup not in progress" +msgstr "es läuft kein exklusives Backup" + +#: access/transam/xlog.c:11330 +#, c-format +msgid "a backup is not in progress" +msgstr "es läuft kein Backup" + +#: access/transam/xlog.c:11416 access/transam/xlog.c:11429 +#: access/transam/xlog.c:11818 access/transam/xlog.c:11824 +#: access/transam/xlog.c:11872 access/transam/xlog.c:11952 +#: access/transam/xlog.c:11976 access/transam/xlogfuncs.c:733 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "ungültige Daten in Datei »%s«" + +#: access/transam/xlog.c:11433 replication/basebackup.c:1281 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "der Standby-Server wurde während der Online-Sicherung zum Primärserver befördert" + +#: access/transam/xlog.c:11434 replication/basebackup.c:1282 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "Das bedeutet, dass die aktuelle Online-Sicherung verfälscht ist und nicht verwendet werden sollte. Versuchen Sie, eine neue Online-Sicherung durchzuführen." + +#: access/transam/xlog.c:11481 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "mit full_page_writes=off erzeugtes WAL wurde während der Online-Sicherung zurückgespielt" + +#: access/transam/xlog.c:11601 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "Basissicherung beendet, warte bis die benötigten WAL-Segmente archiviert sind" + +#: access/transam/xlog.c:11613 +#, c-format +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "warte immer noch, bis alle benötigten WAL-Segmente archiviert sind (%d Sekunden abgelaufen)" + +#: access/transam/xlog.c:11615 +#, c-format +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "Prüfen Sie, ob das archive_command korrekt ausgeführt wird. Dieser Sicherungsvorgang kann gefahrlos abgebrochen werden, aber die Datenbanksicherung wird ohne die fehlenden WAL-Segmente nicht benutzbar sein." + +#: access/transam/xlog.c:11622 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "alle benötigten WAL-Segmente wurden archiviert" + +#: access/transam/xlog.c:11626 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "WAL-Archivierung ist nicht eingeschaltet; Sie müssen dafür sorgen, dass alle benötigten WAL-Segmente auf andere Art kopiert werden, um die Sicherung abzuschließen" + +#: access/transam/xlog.c:11679 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "Backup wird abgebrochen, weil Backend-Prozess beendete, bevor pg_stop_backup aufgerufen wurde" + +#: access/transam/xlog.c:11873 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "Gelesene Zeitleisten-ID ist %u, aber %u wurde erwartet." + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:12001 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "WAL-Redo bei %X/%X für %s" + +#: access/transam/xlog.c:12049 +#, c-format +msgid "online backup mode was not canceled" +msgstr "Online-Sicherungsmodus wurde nicht storniert" + +#: access/transam/xlog.c:12050 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "Konnte Datei »%s« nicht in »%s« umbenennen: %m." + +#: access/transam/xlog.c:12059 access/transam/xlog.c:12071 +#: access/transam/xlog.c:12081 +#, c-format +msgid "online backup mode canceled" +msgstr "Online-Sicherungsmodus storniert" + +#: access/transam/xlog.c:12072 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "Dateien »%s« und »%s« wurden in »%s« und »%s« umbenannt." + +#: access/transam/xlog.c:12082 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "Datei »%s« wurde in »%s« umbenannt, aber Datei »%s« konnte nicht in »%s« umbenannt werden: %m." + +#: access/transam/xlog.c:12215 access/transam/xlogutils.c:967 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "konnte nicht aus Logsegment %s, Position %u lesen: %m" + +#: access/transam/xlog.c:12221 access/transam/xlogutils.c:974 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "konnte nicht aus Logsegment %s bei Position %u lesen: %d von %zu gelesen" + +#: access/transam/xlog.c:12758 +#, c-format +msgid "WAL receiver process shutdown requested" +msgstr "Herunterfahren des WAL-Receiver-Prozesses verlangt" + +#: access/transam/xlog.c:12853 +#, c-format +msgid "received promote request" +msgstr "Anforderung zum Befördern empfangen" + +#: access/transam/xlog.c:12866 +#, c-format +msgid "promote trigger file found: %s" +msgstr "Promote-Triggerdatei gefunden: %s" + +#: access/transam/xlog.c:12874 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "konnte »stat« für Promote-Triggerdatei »%s« nicht ausführen: %m" + +#: access/transam/xlogarchive.c:205 +#, c-format +msgid "archive file \"%s\" has wrong size: %lld instead of %lld" +msgstr "Archivdatei »%s« hat falsche Größe: %lld statt %lld" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "Logdatei »%s« aus Archiv wiederhergestellt" + +#: access/transam/xlogarchive.c:228 +#, c-format +msgid "restore_command returned a zero exit status, but stat() failed." +msgstr "" + +#: access/transam/xlogarchive.c:260 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "konnte Datei »%s« nicht aus Archiv wiederherstellen: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:369 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s »%s«: %s" + +#: access/transam/xlogarchive.c:479 access/transam/xlogarchive.c:543 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "konnte Archivstatusdatei »%s« nicht erstellen: %m" + +#: access/transam/xlogarchive.c:487 access/transam/xlogarchive.c:551 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "konnte Archivstatusdatei »%s« nicht schreiben: %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "ein Backup läuft bereits in dieser Sitzung" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "es läuft ein nicht-exklusives Backup" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "Meinten Sie pg_stop_backup('f')?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1311 +#: commands/event_trigger.c:1869 commands/extension.c:1944 +#: commands/extension.c:2052 commands/extension.c:2337 commands/prepare.c:712 +#: executor/execExpr.c:2507 executor/execSRF.c:738 executor/functions.c:1058 +#: foreign/foreign.c:520 libpq/hba.c:2718 replication/logical/launcher.c:937 +#: replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1494 +#: replication/slotfuncs.c:255 replication/walsender.c:3291 +#: storage/ipc/shmem.c:554 utils/adt/datetime.c:4812 utils/adt/genfile.c:507 +#: utils/adt/genfile.c:590 utils/adt/jsonfuncs.c:1933 +#: utils/adt/jsonfuncs.c:2045 utils/adt/jsonfuncs.c:2233 +#: utils/adt/jsonfuncs.c:2342 utils/adt/jsonfuncs.c:3803 +#: utils/adt/mcxtfuncs.c:132 utils/adt/misc.c:218 utils/adt/pgstatfuncs.c:477 +#: utils/adt/pgstatfuncs.c:587 utils/adt/pgstatfuncs.c:1887 +#: utils/adt/varlena.c:4832 utils/fmgr/funcapi.c:74 utils/misc/guc.c:9993 +#: utils/mmgr/portalmem.c:1141 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "Funktion mit Mengenergebnis in einem Zusammenhang aufgerufen, der keine Mengenergebnisse verarbeiten kann" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1315 +#: commands/event_trigger.c:1873 commands/extension.c:1948 +#: commands/extension.c:2056 commands/extension.c:2341 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2722 replication/logical/launcher.c:941 +#: replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1498 +#: replication/slotfuncs.c:259 replication/walsender.c:3295 +#: storage/ipc/shmem.c:558 utils/adt/datetime.c:4816 utils/adt/genfile.c:511 +#: utils/adt/genfile.c:594 utils/adt/mcxtfuncs.c:136 utils/adt/misc.c:222 +#: utils/adt/pgstatfuncs.c:481 utils/adt/pgstatfuncs.c:591 +#: utils/adt/pgstatfuncs.c:1891 utils/adt/varlena.c:4836 utils/misc/guc.c:9997 +#: utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1145 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "Materialisierungsmodus wird benötigt, ist aber in diesem Zusammenhang nicht erlaubt" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "es läuft kein nicht-exklusives Backup" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "Meinten Sie pg_stop_backup('t')?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "WAL-Level nicht ausreichend, um Restore-Punkt anzulegen" + +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "Wert zu lang für Restore-Punkt (maximal %d Zeichen)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "%s kann nicht während der Wiederherstellung ausgeführt werden." + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:561 +#: access/transam/xlogfuncs.c:585 access/transam/xlogfuncs.c:608 +#: access/transam/xlogfuncs.c:763 +#, c-format +msgid "recovery is not in progress" +msgstr "Wiederherstellung läuft nicht" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:562 +#: access/transam/xlogfuncs.c:586 access/transam/xlogfuncs.c:609 +#: access/transam/xlogfuncs.c:764 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "Wiederherstellungskontrollfunktionen können nur während der Wiederherstellung ausgeführt werden." + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:567 +#, c-format +msgid "standby promotion is ongoing" +msgstr "Beförderung des Standby läuft" + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:568 +#, c-format +msgid "%s cannot be executed after promotion is triggered." +msgstr "%s kann nicht ausgeführt werden, nachdem eine Beförderung angestoßen wurde." + +#: access/transam/xlogfuncs.c:769 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "»wait_seconds« darf nicht negativ oder null sein" + +#: access/transam/xlogfuncs.c:789 storage/ipc/signalfuncs.c:281 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "konnte Signal nicht an Postmaster senden: %m" + +#: access/transam/xlogfuncs.c:825 +#, c-format +msgid "server did not promote within %d second" +msgid_plural "server did not promote within %d seconds" +msgstr[0] "Befördern des Servers wurde nicht innerhalb von %d Sekunde abgeschlossen" +msgstr[1] "Befördern des Servers wurde nicht innerhalb von %d Sekunden abgeschlossen" + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "ungültiger Datensatz-Offset bei %X/%X" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "Contrecord angefordert von %X/%X" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "ungültige Datensatzlänge bei %X/%X: %u erwartet, %u erhalten" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "Datensatzlänge %u bei %X/%X ist zu lang" + +#: access/transam/xlogreader.c:453 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "keine Contrecord-Flag bei %X/%X" + +#: access/transam/xlogreader.c:466 +#, c-format +msgid "invalid contrecord length %u (expected %lld) at %X/%X" +msgstr "ungültige Contrecord-Länge %u (erwartet %lld) bei %X/%X" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "ungültige Resource-Manager-ID %u bei %X/%X" + +#: access/transam/xlogreader.c:716 access/transam/xlogreader.c:732 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "Datensatz mit falschem Prev-Link %X/%X bei %X/%X" + +#: access/transam/xlogreader.c:768 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "ungültige Resource-Manager-Datenprüfsumme in Datensatz bei %X/%X" + +#: access/transam/xlogreader.c:805 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "ungültige magische Zahl %04X in Logsegment %s, Offset %u" + +#: access/transam/xlogreader.c:819 access/transam/xlogreader.c:860 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ungültige Info-Bits %04X in Logsegment %s, Offset %u" + +#: access/transam/xlogreader.c:834 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Datenbanksystemidentifikator in WAL-Datei ist %llu, Datenbanksystemidentifikator in pg_control ist %llu" + +#: access/transam/xlogreader.c:842 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche Segmentgröße im Seitenkopf" + +#: access/transam/xlogreader.c:848 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche XLOG_BLCKSZ im Seitenkopf" + +#: access/transam/xlogreader.c:879 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "unerwartete Pageaddr %X/%X in Logsegment %s, Offset %u" + +#: access/transam/xlogreader.c:904 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "Zeitleisten-ID %u außer der Reihe (nach %u) in Logsegment %s, Offset %u" + +#: access/transam/xlogreader.c:1249 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %u außer der Reihe bei %X/%X" + +#: access/transam/xlogreader.c:1271 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA gesetzt, aber keine Daten enthalten bei %X/%X" + +#: access/transam/xlogreader.c:1278 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA nicht gesetzt, aber Datenlänge ist %u bei %X/%X" + +#: access/transam/xlogreader.c:1314 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE gesetzt, aber Loch Offset %u Länge %u Block-Abbild-Länge %u bei %X/%X" + +#: access/transam/xlogreader.c:1330 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE nicht gesetzt, aber Loch Offset %u Länge %u bei %X/%X" + +#: access/transam/xlogreader.c:1345 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge %u bei %X/%X" + +#: access/transam/xlogreader.c:1360 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "weder BKPIMAGE_HAS_HOLE noch BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge ist %u bei %X/%X" + +#: access/transam/xlogreader.c:1376 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL gesetzt, aber keine vorangehende Relation bei %X/%X" + +#: access/transam/xlogreader.c:1388 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "ungültige block_id %u bei %X/%X" + +#: access/transam/xlogreader.c:1475 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "Datensatz mit ungültiger Länge bei %X/%X" + +#: access/transam/xlogreader.c:1564 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "ungültiges komprimiertes Abbild bei %X/%X, Block %d" + +#: bootstrap/bootstrap.c:270 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X benötigt eine Zweierpotenz zwischen 1 MB und 1 GB" + +#: bootstrap/bootstrap.c:287 postmaster/postmaster.c:847 tcop/postgres.c:3858 +#, c-format +msgid "--%s requires a value" +msgstr "--%s benötigt einen Wert" + +#: bootstrap/bootstrap.c:292 postmaster/postmaster.c:852 tcop/postgres.c:3863 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s benötigt einen Wert" + +#: bootstrap/bootstrap.c:303 postmaster/postmaster.c:864 +#: postmaster/postmaster.c:877 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: bootstrap/bootstrap.c:312 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: ungültige Kommandozeilenargumente\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "Grant-Optionen können nur Rollen gewährt werden" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "es wurden keine Privilegien für Spalte »%s« von Relation »%s« gewährt" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "es wurden keine Privilegien für »%s« gewährt" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "es wurden nicht alle Priviligien für Spalte »%s« von Relation »%s« gewährt" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "es wurden nicht alle Priviligien für »%s« gewährt" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "es konnten keine Privilegien für Spalte »%s« von Relation »%s« entzogen werden" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "es konnten keine Privilegien für »%s« entzogen werden" + +#: catalog/aclchk.c:342 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "es konnten nicht alle Privilegien für Spalte »%s« von Relation »%s« entzogen werden" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "es konnten nicht alle Privilegien für »%s« entzogen werden" + +#: catalog/aclchk.c:379 +#, fuzzy, c-format +#| msgid "must be superuser" +msgid "grantor must be current user" +msgstr "Berechtigung nur für Superuser" + +#: catalog/aclchk.c:446 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "ungültiger Privilegtyp %s für Relation" + +#: catalog/aclchk.c:450 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "ungültiger Privilegtyp %s für Sequenz" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "ungültiger Privilegtyp %s für Datenbank" + +#: catalog/aclchk.c:458 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "ungültiger Privilegtyp %s für Domäne" + +#: catalog/aclchk.c:462 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "ungültiger Privilegtyp %s für Funktion" + +#: catalog/aclchk.c:466 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "ungültiger Privilegtyp %s für Sprache" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "ungültiger Privilegtyp %s für Large Object" + +#: catalog/aclchk.c:474 catalog/aclchk.c:1013 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "ungültiger Privilegtyp %s für Schema" + +#: catalog/aclchk.c:478 catalog/aclchk.c:1001 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "ungültiger Privilegtyp %s für Prozedur" + +#: catalog/aclchk.c:482 catalog/aclchk.c:1005 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "ungültiger Privilegtyp %s für Routine" + +#: catalog/aclchk.c:486 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "ungültiger Privilegtyp %s für Tablespace" + +#: catalog/aclchk.c:490 catalog/aclchk.c:1009 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "ungültiger Privilegtyp %s für Typ" + +#: catalog/aclchk.c:494 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "ungültiger Privilegtyp %s für Fremddaten-Wrapper" + +#: catalog/aclchk.c:498 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "ungültiger Privilegtyp %s für Fremdserver" + +#: catalog/aclchk.c:537 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "Spaltenprivilegien sind nur für Relation gültig" + +#: catalog/aclchk.c:697 catalog/aclchk.c:4164 catalog/aclchk.c:4985 +#: catalog/objectaddress.c:1060 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "Large Object %u existiert nicht" + +#: catalog/aclchk.c:926 catalog/aclchk.c:935 commands/collationcmds.c:119 +#: commands/copy.c:362 commands/copy.c:382 commands/copy.c:392 +#: commands/copy.c:401 commands/copy.c:410 commands/copy.c:420 +#: commands/copy.c:429 commands/copy.c:438 commands/copy.c:456 +#: commands/copy.c:472 commands/copy.c:492 commands/copy.c:509 +#: commands/dbcommands.c:157 commands/dbcommands.c:166 +#: commands/dbcommands.c:175 commands/dbcommands.c:184 +#: commands/dbcommands.c:193 commands/dbcommands.c:202 +#: commands/dbcommands.c:211 commands/dbcommands.c:220 +#: commands/dbcommands.c:229 commands/dbcommands.c:238 +#: commands/dbcommands.c:260 commands/dbcommands.c:1502 +#: commands/dbcommands.c:1511 commands/dbcommands.c:1520 +#: commands/dbcommands.c:1529 commands/extension.c:1735 +#: commands/extension.c:1745 commands/extension.c:1755 +#: commands/extension.c:3055 commands/foreigncmds.c:539 +#: commands/foreigncmds.c:548 commands/functioncmds.c:579 +#: commands/functioncmds.c:745 commands/functioncmds.c:754 +#: commands/functioncmds.c:763 commands/functioncmds.c:772 +#: commands/functioncmds.c:2069 commands/functioncmds.c:2077 +#: commands/publicationcmds.c:90 commands/publicationcmds.c:133 +#: commands/sequence.c:1266 commands/sequence.c:1276 commands/sequence.c:1286 +#: commands/sequence.c:1296 commands/sequence.c:1306 commands/sequence.c:1316 +#: commands/sequence.c:1326 commands/sequence.c:1336 commands/sequence.c:1346 +#: commands/subscriptioncmds.c:124 commands/subscriptioncmds.c:134 +#: commands/subscriptioncmds.c:144 commands/subscriptioncmds.c:154 +#: commands/subscriptioncmds.c:168 commands/subscriptioncmds.c:179 +#: commands/subscriptioncmds.c:193 commands/subscriptioncmds.c:203 +#: commands/subscriptioncmds.c:213 commands/tablecmds.c:7500 +#: commands/typecmds.c:335 commands/typecmds.c:1416 commands/typecmds.c:1425 +#: commands/typecmds.c:1433 commands/typecmds.c:1441 commands/typecmds.c:1449 +#: commands/typecmds.c:1457 commands/user.c:133 commands/user.c:147 +#: commands/user.c:156 commands/user.c:165 commands/user.c:174 +#: commands/user.c:183 commands/user.c:192 commands/user.c:201 +#: commands/user.c:210 commands/user.c:219 commands/user.c:228 +#: commands/user.c:237 commands/user.c:246 commands/user.c:582 +#: commands/user.c:590 commands/user.c:598 commands/user.c:606 +#: commands/user.c:614 commands/user.c:622 commands/user.c:630 +#: commands/user.c:638 commands/user.c:647 commands/user.c:655 +#: commands/user.c:663 parser/parse_utilcmd.c:407 +#: replication/pgoutput/pgoutput.c:189 replication/pgoutput/pgoutput.c:210 +#: replication/pgoutput/pgoutput.c:224 replication/pgoutput/pgoutput.c:234 +#: replication/pgoutput/pgoutput.c:244 replication/walsender.c:882 +#: replication/walsender.c:893 replication/walsender.c:903 +#, c-format +msgid "conflicting or redundant options" +msgstr "widersprüchliche oder überflüssige Optionen" + +#: catalog/aclchk.c:1046 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "Vorgabeprivilegien können nicht für Spalten gesetzt werden" + +#: catalog/aclchk.c:1206 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "Klausel IN SCHEMA kann nicht verwendet werden, wenn GRANT/REVOKE ON SCHEMAS verwendet wird" + +#: catalog/aclchk.c:1544 catalog/catalog.c:553 catalog/objectaddress.c:1522 +#: commands/analyze.c:390 commands/copy.c:741 commands/sequence.c:1701 +#: commands/tablecmds.c:6976 commands/tablecmds.c:7119 +#: commands/tablecmds.c:7169 commands/tablecmds.c:7243 +#: commands/tablecmds.c:7313 commands/tablecmds.c:7425 +#: commands/tablecmds.c:7519 commands/tablecmds.c:7578 +#: commands/tablecmds.c:7667 commands/tablecmds.c:7696 +#: commands/tablecmds.c:7851 commands/tablecmds.c:7933 +#: commands/tablecmds.c:8089 commands/tablecmds.c:8207 +#: commands/tablecmds.c:11556 commands/tablecmds.c:11738 +#: commands/tablecmds.c:11898 commands/tablecmds.c:13041 +#: commands/tablecmds.c:15602 commands/trigger.c:924 parser/analyze.c:2413 +#: parser/parse_relation.c:714 parser/parse_target.c:1064 +#: parser/parse_type.c:144 parser/parse_utilcmd.c:3453 +#: parser/parse_utilcmd.c:3488 parser/parse_utilcmd.c:3530 utils/adt/acl.c:2845 +#: utils/adt/ruleutils.c:2708 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "Spalte »%s« von Relation »%s« existiert nicht" + +#: catalog/aclchk.c:1807 catalog/objectaddress.c:1362 commands/sequence.c:1139 +#: commands/tablecmds.c:249 commands/tablecmds.c:16466 utils/adt/acl.c:2053 +#: utils/adt/acl.c:2083 utils/adt/acl.c:2115 utils/adt/acl.c:2147 +#: utils/adt/acl.c:2175 utils/adt/acl.c:2205 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "»%s« ist keine Sequenz" + +#: catalog/aclchk.c:1845 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "Sequenz »%s« unterstützt nur die Privilegien USAGE, SELECT und UPDATE" + +#: catalog/aclchk.c:1862 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "ungültiger Privilegtyp %s für Tabelle" + +#: catalog/aclchk.c:2028 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "ungültiger Privilegtyp %s für Spalte" + +#: catalog/aclchk.c:2041 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "Sequenz »%s« unterstützt nur den Spaltenprivilegientyp SELECT" + +#: catalog/aclchk.c:2623 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "Sprache »%s« ist nicht »trusted«" + +#: catalog/aclchk.c:2625 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "GRANT und REVOKE sind für nicht vertrauenswürdige Sprachen nicht erlaubt, weil nur Superuser nicht vertrauenswürdige Sprachen verwenden können." + +#: catalog/aclchk.c:3139 +#, c-format +msgid "cannot set privileges of array types" +msgstr "für Array-Typen können keine Privilegien gesetzt werden" + +#: catalog/aclchk.c:3140 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Setzen Sie stattdessen die Privilegien des Elementtyps." + +#: catalog/aclchk.c:3147 catalog/objectaddress.c:1656 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "»%s« ist keine Domäne" + +#: catalog/aclchk.c:3267 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "unbekannter Privilegtyp »%s«" + +#: catalog/aclchk.c:3328 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "keine Berechtigung für Aggregatfunktion %s" + +#: catalog/aclchk.c:3331 +#, c-format +msgid "permission denied for collation %s" +msgstr "keine Berechtigung für Sortierfolge %s" + +#: catalog/aclchk.c:3334 +#, c-format +msgid "permission denied for column %s" +msgstr "keine Berechtigung für Spalte %s" + +#: catalog/aclchk.c:3337 +#, c-format +msgid "permission denied for conversion %s" +msgstr "keine Berechtigung für Konversion %s" + +#: catalog/aclchk.c:3340 +#, c-format +msgid "permission denied for database %s" +msgstr "keine Berechtigung für Datenbank %s" + +#: catalog/aclchk.c:3343 +#, c-format +msgid "permission denied for domain %s" +msgstr "keine Berechtigung für Domäne %s" + +#: catalog/aclchk.c:3346 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "keine Berechtigung für Ereignistrigger %s" + +#: catalog/aclchk.c:3349 +#, c-format +msgid "permission denied for extension %s" +msgstr "keine Berechtigung für Erweiterung %s" + +#: catalog/aclchk.c:3352 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "keine Berechtigung für Fremddaten-Wrapper %s" + +#: catalog/aclchk.c:3355 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "keine Berechtigung für Fremdserver %s" + +#: catalog/aclchk.c:3358 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "keine Berechtigung für Fremdtabelle %s" + +#: catalog/aclchk.c:3361 +#, c-format +msgid "permission denied for function %s" +msgstr "keine Berechtigung für Funktion %s" + +#: catalog/aclchk.c:3364 +#, c-format +msgid "permission denied for index %s" +msgstr "keine Berechtigung für Index %s" + +#: catalog/aclchk.c:3367 +#, c-format +msgid "permission denied for language %s" +msgstr "keine Berechtigung für Sprache %s" + +#: catalog/aclchk.c:3370 +#, c-format +msgid "permission denied for large object %s" +msgstr "keine Berechtigung für Large Object %s" + +#: catalog/aclchk.c:3373 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "keine Berechtigung für materialisierte Sicht %s" + +#: catalog/aclchk.c:3376 +#, c-format +msgid "permission denied for operator class %s" +msgstr "keine Berechtigung für Operatorklasse %s" + +#: catalog/aclchk.c:3379 +#, c-format +msgid "permission denied for operator %s" +msgstr "keine Berechtigung für Operator %s" + +#: catalog/aclchk.c:3382 +#, c-format +msgid "permission denied for operator family %s" +msgstr "keine Berechtigung für Operatorfamilie %s" + +#: catalog/aclchk.c:3385 +#, c-format +msgid "permission denied for policy %s" +msgstr "keine Berechtigung für Policy %s" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for procedure %s" +msgstr "keine Berechtigung für Prozedur %s" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for publication %s" +msgstr "keine Berechtigung für Publikation %s" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for routine %s" +msgstr "keine Berechtigung für Routine %s" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for schema %s" +msgstr "keine Berechtigung für Schema %s" + +#: catalog/aclchk.c:3400 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1799 +#: commands/sequence.c:1863 +#, c-format +msgid "permission denied for sequence %s" +msgstr "keine Berechtigung für Sequenz %s" + +#: catalog/aclchk.c:3403 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "keine Berechtigung für Statistikobjekt %s" + +#: catalog/aclchk.c:3406 +#, c-format +msgid "permission denied for subscription %s" +msgstr "keine Berechtigung für Subskription %s" + +#: catalog/aclchk.c:3409 +#, c-format +msgid "permission denied for table %s" +msgstr "keine Berechtigung für Tabelle %s" + +#: catalog/aclchk.c:3412 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "keine Berechtigung für Tablespace %s" + +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "keine Berechtigung für Textsuchekonfiguration %s" + +#: catalog/aclchk.c:3418 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "keine Berechtigung für Textsuchewörterbuch %s" + +#: catalog/aclchk.c:3421 +#, c-format +msgid "permission denied for type %s" +msgstr "keine Berechtigung für Typ %s" + +#: catalog/aclchk.c:3424 +#, c-format +msgid "permission denied for view %s" +msgstr "keine Berechtigung für Sicht %s" + +#: catalog/aclchk.c:3459 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "Berechtigung nur für Eigentümer der Aggregatfunktion %s" + +#: catalog/aclchk.c:3462 +#, c-format +msgid "must be owner of collation %s" +msgstr "Berechtigung nur für Eigentümer der Sortierfolge %s" + +#: catalog/aclchk.c:3465 +#, c-format +msgid "must be owner of conversion %s" +msgstr "Berechtigung nur für Eigentümer der Konversion %s" + +#: catalog/aclchk.c:3468 +#, c-format +msgid "must be owner of database %s" +msgstr "Berechtigung nur für Eigentümer der Datenbank %s" + +#: catalog/aclchk.c:3471 +#, c-format +msgid "must be owner of domain %s" +msgstr "Berechtigung nur für Eigentümer der Domäne %s" + +#: catalog/aclchk.c:3474 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "Berechtigung nur für Eigentümer des Ereignistriggers %s" + +#: catalog/aclchk.c:3477 +#, c-format +msgid "must be owner of extension %s" +msgstr "Berechtigung nur für Eigentümer der Erweiterung %s" + +#: catalog/aclchk.c:3480 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "Berechtigung nur für Eigentümer des Fremddaten-Wrappers %s" + +#: catalog/aclchk.c:3483 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "Berechtigung nur für Eigentümer des Fremdservers %s" + +#: catalog/aclchk.c:3486 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "Berechtigung nur für Eigentümer der Fremdtabelle %s" + +#: catalog/aclchk.c:3489 +#, c-format +msgid "must be owner of function %s" +msgstr "Berechtigung nur für Eigentümer der Funktion %s" + +#: catalog/aclchk.c:3492 +#, c-format +msgid "must be owner of index %s" +msgstr "Berechtigung nur für Eigentümer des Index %s" + +#: catalog/aclchk.c:3495 +#, c-format +msgid "must be owner of language %s" +msgstr "Berechtigung nur für Eigentümer der Sprache %s" + +#: catalog/aclchk.c:3498 +#, c-format +msgid "must be owner of large object %s" +msgstr "Berechtigung nur für Eigentümer des Large Object %s" + +#: catalog/aclchk.c:3501 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "Berechtigung nur für Eigentümer der materialisierten Sicht %s" + +#: catalog/aclchk.c:3504 +#, c-format +msgid "must be owner of operator class %s" +msgstr "Berechtigung nur für Eigentümer der Operatorklasse %s" + +#: catalog/aclchk.c:3507 +#, c-format +msgid "must be owner of operator %s" +msgstr "Berechtigung nur für Eigentümer des Operators %s" + +#: catalog/aclchk.c:3510 +#, c-format +msgid "must be owner of operator family %s" +msgstr "Berechtigung nur für Eigentümer der Operatorfamilie %s" + +#: catalog/aclchk.c:3513 +#, c-format +msgid "must be owner of procedure %s" +msgstr "Berechtigung nur für Eigentümer der Prozedur %s" + +#: catalog/aclchk.c:3516 +#, c-format +msgid "must be owner of publication %s" +msgstr "Berechtigung nur für Eigentümer der Publikation %s" + +#: catalog/aclchk.c:3519 +#, c-format +msgid "must be owner of routine %s" +msgstr "Berechtigung nur für Eigentümer der Routine %s" + +#: catalog/aclchk.c:3522 +#, c-format +msgid "must be owner of sequence %s" +msgstr "Berechtigung nur für Eigentümer der Sequenz %s" + +#: catalog/aclchk.c:3525 +#, c-format +msgid "must be owner of subscription %s" +msgstr "Berechtigung nur für Eigentümer der Subskription %s" + +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of table %s" +msgstr "Berechtigung nur für Eigentümer der Tabelle %s" + +#: catalog/aclchk.c:3531 +#, c-format +msgid "must be owner of type %s" +msgstr "Berechtigung nur für Eigentümer des Typs %s" + +#: catalog/aclchk.c:3534 +#, c-format +msgid "must be owner of view %s" +msgstr "Berechtigung nur für Eigentümer der Sicht %s" + +#: catalog/aclchk.c:3537 +#, c-format +msgid "must be owner of schema %s" +msgstr "Berechtigung nur für Eigentümer des Schemas %s" + +#: catalog/aclchk.c:3540 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "Berechtigung nur für Eigentümer des Statistikobjekts %s" + +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "Berechtigung nur für Eigentümer des Tablespace %s" + +#: catalog/aclchk.c:3546 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "Berechtigung nur für Eigentümer der Textsuchekonfiguration %s" + +#: catalog/aclchk.c:3549 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "Berechtigung nur für Eigentümer des Textsuchewörterbuches %s" + +#: catalog/aclchk.c:3563 +#, c-format +msgid "must be owner of relation %s" +msgstr "Berechtigung nur für Eigentümer der Relation %s" + +#: catalog/aclchk.c:3607 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "keine Berechtigung für Spalte »%s« von Relation »%s«" + +#: catalog/aclchk.c:3750 catalog/aclchk.c:3769 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "Attribut %d der Relation mit OID %u existiert nicht" + +#: catalog/aclchk.c:3864 catalog/aclchk.c:4836 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "Relation mit OID %u existiert nicht" + +#: catalog/aclchk.c:3977 catalog/aclchk.c:5254 +#, c-format +msgid "database with OID %u does not exist" +msgstr "Datenbank mit OID %u existiert nicht" + +#: catalog/aclchk.c:4031 catalog/aclchk.c:4914 tcop/fastpath.c:141 +#: utils/fmgr/fmgr.c:2051 +#, c-format +msgid "function with OID %u does not exist" +msgstr "Funktion mit OID %u existiert nicht" + +#: catalog/aclchk.c:4085 catalog/aclchk.c:4940 +#, c-format +msgid "language with OID %u does not exist" +msgstr "Sprache mit OID %u existiert nicht" + +#: catalog/aclchk.c:4249 catalog/aclchk.c:5012 commands/collationcmds.c:517 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "Schema mit OID %u existiert nicht" + +#: catalog/aclchk.c:4313 catalog/aclchk.c:5039 utils/adt/genfile.c:688 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "Tablespace mit OID %u existiert nicht" + +#: catalog/aclchk.c:4372 catalog/aclchk.c:5173 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "Fremddaten-Wrapper mit OID %u existiert nicht" + +#: catalog/aclchk.c:4434 catalog/aclchk.c:5200 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "Fremdserver mit OID %u existiert nicht" + +#: catalog/aclchk.c:4494 catalog/aclchk.c:4862 utils/cache/typcache.c:384 +#: utils/cache/typcache.c:439 +#, c-format +msgid "type with OID %u does not exist" +msgstr "Typ mit OID %u existiert nicht" + +#: catalog/aclchk.c:4888 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "Operator mit OID %u existiert nicht" + +#: catalog/aclchk.c:5065 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "Operatorklasse mit OID %u existiert nicht" + +#: catalog/aclchk.c:5092 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "Operatorfamilie mit OID %u existiert nicht" + +#: catalog/aclchk.c:5119 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "Textsuchewörterbuch mit OID %u existiert nicht" + +#: catalog/aclchk.c:5146 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "Textsuchekonfiguration mit OID %u existiert nicht" + +#: catalog/aclchk.c:5227 commands/event_trigger.c:453 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "Ereignistrigger mit OID %u existiert nicht" + +#: catalog/aclchk.c:5280 commands/collationcmds.c:368 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "Sortierfolge mit OID %u existiert nicht" + +#: catalog/aclchk.c:5306 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "Konversion mit OID %u existiert nicht" + +#: catalog/aclchk.c:5347 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "Erweiterung mit OID %u existiert nicht" + +#: catalog/aclchk.c:5374 commands/publicationcmds.c:771 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "Publikation mit OID %u existiert nicht" + +#: catalog/aclchk.c:5400 commands/subscriptioncmds.c:1459 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "Subskription mit OID %u existiert nicht" + +#: catalog/aclchk.c:5426 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "Statistikobjekt mit OID %u existiert nicht" + +#: catalog/catalog.c:378 +#, fuzzy, c-format +#| msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgid "still finding an unused OID within relation \"%s\"" +msgstr "beim Einfügen von Indextupel (%u,%u) in Relation »%s«" + +#: catalog/catalog.c:380 +#, c-format +msgid "OID candidates were checked \"%llu\" times, but no unused OID is yet found." +msgstr "" + +#: catalog/catalog.c:403 +#, c-format +msgid "new OID has been assigned in relation \"%s\" after \"%llu\" retries" +msgstr "" + +#: catalog/catalog.c:532 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "nur Superuser können pg_nextoid() aufrufen" + +#: catalog/catalog.c:540 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() kann nur mit Systemkatalogen verwendet werden" + +#: catalog/catalog.c:545 parser/parse_utilcmd.c:2276 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "Index »%s« gehört nicht zu Tabelle »%s«" + +#: catalog/catalog.c:562 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "Spalte »%s« hat nicht Typ oid" + +#: catalog/catalog.c:569 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "»%s« ist kein Index für Spalte »%s«" + +#: catalog/dependency.c:821 catalog/dependency.c:1060 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "kann %s nicht löschen, wird von %s benötigt" + +#: catalog/dependency.c:823 catalog/dependency.c:1062 +#, c-format +msgid "You can drop %s instead." +msgstr "Sie können stattdessen %s löschen." + +#: catalog/dependency.c:931 catalog/pg_shdepend.c:696 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "kann %s nicht löschen, wird vom Datenbanksystem benötigt" + +#: catalog/dependency.c:1135 catalog/dependency.c:1144 +#, c-format +msgid "%s depends on %s" +msgstr "%s hängt von %s ab" + +#: catalog/dependency.c:1156 catalog/dependency.c:1165 +#, c-format +msgid "drop cascades to %s" +msgstr "Löschvorgang löscht ebenfalls %s" + +#: catalog/dependency.c:1173 catalog/pg_shdepend.c:825 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"und %d weiteres Objekt (Liste im Serverlog)" +msgstr[1] "" +"\n" +"und %d weitere Objekte (Liste im Serverlog)" + +#: catalog/dependency.c:1185 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "kann %s nicht löschen, weil andere Objekte davon abhängen" + +#: catalog/dependency.c:1187 catalog/dependency.c:1188 +#: catalog/dependency.c:1194 catalog/dependency.c:1195 +#: catalog/dependency.c:1206 catalog/dependency.c:1207 +#: commands/tablecmds.c:1298 commands/tablecmds.c:13659 +#: commands/tablespace.c:481 commands/user.c:1095 commands/view.c:495 +#: libpq/auth.c:338 replication/syncrep.c:1043 storage/lmgr/deadlock.c:1152 +#: storage/lmgr/proc.c:1433 utils/adt/acl.c:5250 utils/adt/jsonfuncs.c:618 +#: utils/adt/jsonfuncs.c:624 utils/misc/guc.c:7114 utils/misc/guc.c:7150 +#: utils/misc/guc.c:7220 utils/misc/guc.c:11400 utils/misc/guc.c:11434 +#: utils/misc/guc.c:11468 utils/misc/guc.c:11511 utils/misc/guc.c:11553 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1189 catalog/dependency.c:1196 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Verwenden Sie DROP ... CASCADE, um die abhängigen Objekte ebenfalls zu löschen." + +#: catalog/dependency.c:1193 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "kann gewünschte Objekte nicht löschen, weil andere Objekte davon abhängen" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1202 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "Löschvorgang löscht ebenfalls %d weiteres Objekt" +msgstr[1] "Löschvorgang löscht ebenfalls %d weitere Objekte" + +#: catalog/dependency.c:1863 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "Konstante vom Typ %s kann hier nicht verwendet werden" + +#: catalog/heap.c:332 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "keine Berechtigung, um »%s.%s« zu erzeugen" + +#: catalog/heap.c:334 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "Änderungen an Systemkatalogen sind gegenwärtig nicht erlaubt." + +#: catalog/heap.c:511 commands/tablecmds.c:2335 commands/tablecmds.c:2972 +#: commands/tablecmds.c:6567 +#, c-format +msgid "tables can have at most %d columns" +msgstr "Tabellen können höchstens %d Spalten haben" + +#: catalog/heap.c:529 commands/tablecmds.c:6866 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "Spaltenname »%s« steht im Konflikt mit dem Namen einer Systemspalte" + +#: catalog/heap.c:545 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "Spaltenname »%s« mehrmals angegeben" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:620 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "Partitionierungsschlüsselspalte %s hat Pseudotyp %s" + +#: catalog/heap.c:625 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "Spalte »%s« hat Pseudotyp %s" + +#: catalog/heap.c:656 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "zusammengesetzter Typ %s kann nicht Teil von sich selbst werden" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:711 +#, c-format +msgid "no collation was derived for partition key column %s with collatable type %s" +msgstr "für Partitionierungsschlüsselspalte %s mit sortierbarem Typ %s wurde keine Sortierfolge abgeleitet" + +#: catalog/heap.c:717 commands/createas.c:203 commands/createas.c:506 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "für Spalte »%s« mit sortierbarem Typ %s wurde keine Sortierfolge abgeleitet" + +#: catalog/heap.c:1199 catalog/index.c:870 commands/createas.c:411 +#: commands/tablecmds.c:3853 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "Relation »%s« existiert bereits" + +#: catalog/heap.c:1215 catalog/pg_type.c:435 catalog/pg_type.c:773 +#: catalog/pg_type.c:920 commands/typecmds.c:249 commands/typecmds.c:261 +#: commands/typecmds.c:757 commands/typecmds.c:1172 commands/typecmds.c:1398 +#: commands/typecmds.c:1590 commands/typecmds.c:2563 +#, c-format +msgid "type \"%s\" already exists" +msgstr "Typ »%s« existiert bereits" + +#: catalog/heap.c:1216 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "Eine Relation hat einen zugehörigen Typ mit dem selben Namen, daher müssen Sie einen Namen wählen, der nicht mit einem bestehenden Typ kollidiert." + +#: catalog/heap.c:1245 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "Heap-OID-Wert für pg_class ist im Binary-Upgrade-Modus nicht gesetzt" + +#: catalog/heap.c:2450 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "zur partitionierten Tabelle »%s« kann kein NO-INHERIT-Constraint hinzugefügt werden" + +#: catalog/heap.c:2722 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "Check-Constraint »%s« existiert bereits" + +#: catalog/heap.c:2892 catalog/index.c:884 catalog/pg_constraint.c:670 +#: commands/tablecmds.c:8581 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "Constraint »%s« existiert bereits für Relation »%s«" + +#: catalog/heap.c:2899 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "Constraint »%s« kollidiert mit nicht vererbtem Constraint für Relation »%s«" + +#: catalog/heap.c:2910 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "Constraint »%s« kollidiert mit vererbtem Constraint für Relation »%s«" + +#: catalog/heap.c:2920 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "Constraint »%s« kollidiert mit NOT-VALID-Constraint für Relation »%s«" + +#: catalog/heap.c:2925 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "Constraint »%s« wird mit geerbter Definition zusammengeführt" + +#: catalog/heap.c:3030 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "generierte Spalte »%s« kann nicht im Spaltengenerierungsausdruck verwendet werden" + +#: catalog/heap.c:3032 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "Eine generierte Spalte kann nicht auf eine andere generierte Spalte verweisen." + +#: catalog/heap.c:3038 +#, c-format +msgid "cannot use whole-row variable in column generation expression" +msgstr "Variable mit Verweis auf die ganze Zeile kann nicht im Spaltengenerierungsausdruck verwendet werden" + +#: catalog/heap.c:3039 +#, c-format +msgid "This would cause the generated column to depend on its own value." +msgstr "Dadurch würde die generierte Spalte von ihrem eigenen Wert abhängen." + +#: catalog/heap.c:3092 +#, c-format +msgid "generation expression is not immutable" +msgstr "Generierungsausdruck ist nicht »immutable«" + +#: catalog/heap.c:3120 rewrite/rewriteHandler.c:1245 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "Spalte »%s« hat Typ %s, aber der Vorgabeausdruck hat Typ %s" + +#: catalog/heap.c:3125 commands/prepare.c:367 parser/analyze.c:2637 +#: parser/parse_target.c:595 parser/parse_target.c:883 +#: parser/parse_target.c:893 rewrite/rewriteHandler.c:1250 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Sie müssen den Ausdruck umschreiben oder eine Typumwandlung vornehmen." + +#: catalog/heap.c:3172 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "nur Verweise auf Tabelle »%s« sind im Check-Constraint zugelassen" + +#: catalog/heap.c:3470 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "nicht unterstützte Kombination aus ON COMMIT und Fremdschlüssel" + +#: catalog/heap.c:3471 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "Tabelle »%s« verweist auf »%s«, aber sie haben nicht die gleiche ON-COMMIT-Einstellung." + +#: catalog/heap.c:3476 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "kann eine Tabelle, die in einen Fremdschlüssel-Constraint eingebunden ist, nicht leeren" + +#: catalog/heap.c:3477 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "Tabelle »%s« verweist auf »%s«." + +#: catalog/heap.c:3479 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "Leeren Sie die Tabelle »%s« gleichzeitig oder verwenden Sie TRUNCATE ... CASCADE." + +#: catalog/index.c:221 parser/parse_utilcmd.c:2182 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "mehrere Primärschlüssel für Tabelle »%s« nicht erlaubt" + +#: catalog/index.c:239 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "Primärschlüssel können keine Ausdrücke sein" + +#: catalog/index.c:256 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "Primärschlüsselspalte »%s« ist nicht als NOT NULL markiert" + +#: catalog/index.c:769 catalog/index.c:1905 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "benutzerdefinierte Indexe für Systemkatalogtabellen werden nicht unterstützt" + +#: catalog/index.c:809 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "nichtdeterministische Sortierfolgen werden von Operatorklasse »%s« nicht unterstützt" + +#: catalog/index.c:824 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "nebenläufige Indexerzeugung für Systemkatalogtabellen wird nicht unterstützt" + +#: catalog/index.c:833 catalog/index.c:1284 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "nebenläufige Indexerzeugung für Exclusion-Constraints wird nicht unterstützt" + +#: catalog/index.c:842 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "Cluster-globale Indexe können nicht nach initdb erzeugt werden" + +#: catalog/index.c:862 commands/createas.c:417 commands/sequence.c:154 +#: parser/parse_utilcmd.c:211 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "Relation »%s« existiert bereits, wird übersprungen" + +#: catalog/index.c:912 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "Index-OID-Wert für pg_class ist im Binary-Upgrade-Modus nicht gesetzt" + +#: catalog/index.c:2191 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY muss die erste Aktion in einer Transaktion sein" + +#: catalog/index.c:3576 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "kann temporäre Tabellen anderer Sitzungen nicht reindizieren" + +#: catalog/index.c:3587 commands/indexcmds.c:3426 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "ungültiger Index einer TOAST-Tabelle kann nicht reindiziert werden" + +#: catalog/index.c:3603 commands/indexcmds.c:3306 commands/indexcmds.c:3450 +#: commands/tablecmds.c:3292 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "Systemrelation »%s« kann nicht verschoben werden" + +#: catalog/index.c:3747 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "Index »%s« wurde neu indiziert" + +#: catalog/index.c:3878 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "ungültiger Index »%s.%s« einer TOAST-Tabelle kann nicht reindizert werden, wird übersprungen" + +#: catalog/namespace.c:257 catalog/namespace.c:461 catalog/namespace.c:553 +#: commands/trigger.c:5134 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "Verweise auf andere Datenbanken sind nicht implementiert: »%s.%s.%s«" + +#: catalog/namespace.c:314 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "temporäre Tabellen können keinen Schemanamen angeben" + +#: catalog/namespace.c:395 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "konnte Sperre für Relation »%s.%s« nicht setzen" + +#: catalog/namespace.c:400 commands/lockcmds.c:143 commands/lockcmds.c:228 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "konnte Sperre für Relation »%s« nicht setzen" + +#: catalog/namespace.c:428 parser/parse_relation.c:1362 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "Relation »%s.%s« existiert nicht" + +#: catalog/namespace.c:433 parser/parse_relation.c:1375 +#: parser/parse_relation.c:1383 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "Relation »%s« existiert nicht" + +#: catalog/namespace.c:499 catalog/namespace.c:3029 commands/extension.c:1519 +#: commands/extension.c:1525 +#, c-format +msgid "no schema has been selected to create in" +msgstr "kein Schema für die Objekterzeugung ausgewählt" + +#: catalog/namespace.c:651 catalog/namespace.c:664 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "kann keine Relationen in temporären Schemas anderer Sitzungen erzeugen" + +#: catalog/namespace.c:655 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "kann keine temporäre Relation in einem nicht-temporären Schema erzeugen" + +#: catalog/namespace.c:670 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "nur temporäre Relationen können in temporären Schemas erzeugt werden" + +#: catalog/namespace.c:2221 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "Statistikobjekt »%s« existiert nicht" + +#: catalog/namespace.c:2344 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "Textsucheparser »%s« existiert nicht" + +#: catalog/namespace.c:2470 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "Textsuchewörterbuch »%s« existiert nicht" + +#: catalog/namespace.c:2597 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "Textsuchevorlage »%s« existiert nicht" + +#: catalog/namespace.c:2723 commands/tsearchcmds.c:1121 +#: utils/cache/ts_cache.c:613 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "Textsuchekonfiguration »%s« existiert nicht" + +#: catalog/namespace.c:2836 parser/parse_expr.c:810 parser/parse_target.c:1256 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "Verweise auf andere Datenbanken sind nicht implementiert: %s" + +#: catalog/namespace.c:2842 gram.y:15126 gram.y:17084 parser/parse_expr.c:817 +#: parser/parse_target.c:1263 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "falscher qualifizierter Name (zu viele Namensteile): %s" + +#: catalog/namespace.c:2972 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "Objekte können nicht in oder aus temporären Schemas verschoben werden" + +#: catalog/namespace.c:2978 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "Objekte können nicht in oder aus TOAST-Schemas verschoben werden" + +#: catalog/namespace.c:3051 commands/schemacmds.c:233 commands/schemacmds.c:313 +#: commands/tablecmds.c:1243 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "Schema »%s« existiert nicht" + +#: catalog/namespace.c:3082 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "falscher Relationsname (zu viele Namensteile): %s" + +#: catalog/namespace.c:3645 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "Sortierfolge »%s« für Kodierung »%s« existiert nicht" + +#: catalog/namespace.c:3700 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "Konversion »%s« existiert nicht" + +#: catalog/namespace.c:3964 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "keine Berechtigung, um temporäre Tabellen in Datenbank »%s« zu erzeugen" + +#: catalog/namespace.c:3980 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "während der Wiederherstellung können keine temporären Tabellen erzeugt werden" + +#: catalog/namespace.c:3986 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "während einer parallelen Operation können keine temporären Tabellen erzeugt werden" + +#: catalog/namespace.c:4285 commands/tablespace.c:1217 commands/variable.c:64 +#: utils/misc/guc.c:11585 utils/misc/guc.c:11663 +#, c-format +msgid "List syntax is invalid." +msgstr "Die Listensyntax ist ungültig." + +#: catalog/objectaddress.c:1370 catalog/pg_publication.c:57 +#: commands/policy.c:95 commands/policy.c:375 commands/policy.c:465 +#: commands/tablecmds.c:243 commands/tablecmds.c:285 commands/tablecmds.c:2145 +#: commands/tablecmds.c:6016 commands/tablecmds.c:11673 +#, c-format +msgid "\"%s\" is not a table" +msgstr "»%s« ist keine Tabelle" + +#: catalog/objectaddress.c:1377 commands/tablecmds.c:255 +#: commands/tablecmds.c:6046 commands/tablecmds.c:16471 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "»%s« ist keine Sicht" + +#: catalog/objectaddress.c:1384 commands/matview.c:175 commands/tablecmds.c:261 +#: commands/tablecmds.c:16476 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "»%s« ist keine materialisierte Sicht" + +#: catalog/objectaddress.c:1391 commands/tablecmds.c:279 +#: commands/tablecmds.c:6049 commands/tablecmds.c:16481 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "»%s« ist keine Fremdtabelle" + +#: catalog/objectaddress.c:1432 +#, c-format +msgid "must specify relation and object name" +msgstr "Relations- und Objektname müssen angegeben werden" + +#: catalog/objectaddress.c:1508 catalog/objectaddress.c:1561 +#, c-format +msgid "column name must be qualified" +msgstr "Spaltenname muss qualifiziert werden" + +#: catalog/objectaddress.c:1608 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "Vorgabewert für Spalte »%s« von Relation »%s« existiert nicht" + +#: catalog/objectaddress.c:1645 commands/functioncmds.c:137 +#: commands/tablecmds.c:271 commands/typecmds.c:274 commands/typecmds.c:3713 +#: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:791 +#: utils/adt/acl.c:4411 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "Typ »%s« existiert nicht" + +#: catalog/objectaddress.c:1764 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "Operator %d (%s, %s) von %s existiert nicht" + +#: catalog/objectaddress.c:1795 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "Funktion %d (%s, %s) von %s existiert nicht" + +#: catalog/objectaddress.c:1846 catalog/objectaddress.c:1872 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "Benutzerabbildung für Benutzer »%s« auf Server »%s« existiert nicht" + +#: catalog/objectaddress.c:1861 commands/foreigncmds.c:430 +#: commands/foreigncmds.c:988 commands/foreigncmds.c:1347 foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "Server »%s« existiert nicht" + +#: catalog/objectaddress.c:1928 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "Publikationsrelation »%s« in Publikation »%s« existiert nicht" + +#: catalog/objectaddress.c:1990 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "unbekannter Standard-ACL-Objekttyp »%c«" + +#: catalog/objectaddress.c:1991 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Gültige Objekttypen sind »%c«, »%c«, »%c«, »%c«, »%c«." + +#: catalog/objectaddress.c:2042 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "Standard-ACL für Benutzer »%s« in Schema »%s« für %s existiert nicht" + +#: catalog/objectaddress.c:2047 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "Standard-ACL für Benutzer »%s« für %s existiert nicht" + +#: catalog/objectaddress.c:2074 catalog/objectaddress.c:2132 +#: catalog/objectaddress.c:2189 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "Namens- oder Argumentlisten dürfen keine NULL-Werte enthalten" + +#: catalog/objectaddress.c:2108 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "nicht unterstützter Objekttyp »%s«" + +#: catalog/objectaddress.c:2128 catalog/objectaddress.c:2146 +#: catalog/objectaddress.c:2287 +#, c-format +msgid "name list length must be exactly %d" +msgstr "Länge der Namensliste muss genau %d sein" + +#: catalog/objectaddress.c:2150 +#, c-format +msgid "large object OID may not be null" +msgstr "Large-Object-OID darf nicht NULL sein" + +#: catalog/objectaddress.c:2159 catalog/objectaddress.c:2222 +#: catalog/objectaddress.c:2229 +#, c-format +msgid "name list length must be at least %d" +msgstr "Länge der Namensliste muss mindestens %d sein" + +#: catalog/objectaddress.c:2215 catalog/objectaddress.c:2236 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "Länge der Argumentliste muss genau %d sein" + +#: catalog/objectaddress.c:2488 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "Berechtigung nur für Eigentümer des Large Object %u" + +#: catalog/objectaddress.c:2503 commands/functioncmds.c:1556 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "Berechtigung nur für Eigentümer des Typs %s oder des Typs %s" + +#: catalog/objectaddress.c:2553 catalog/objectaddress.c:2570 +#, c-format +msgid "must be superuser" +msgstr "Berechtigung nur für Superuser" + +#: catalog/objectaddress.c:2560 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "Berechtigung nur mit CREATEROLE-Privileg" + +#: catalog/objectaddress.c:2639 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "unbekannter Objekttyp »%s«" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2882 +#, c-format +msgid "column %s of %s" +msgstr "Spalte %s von %s" + +#: catalog/objectaddress.c:2897 +#, c-format +msgid "function %s" +msgstr "Funktion %s" + +#: catalog/objectaddress.c:2910 +#, c-format +msgid "type %s" +msgstr "Typ %s" + +#: catalog/objectaddress.c:2947 +#, c-format +msgid "cast from %s to %s" +msgstr "Typumwandlung von %s in %s" + +#: catalog/objectaddress.c:2980 +#, c-format +msgid "collation %s" +msgstr "Sortierfolge %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3011 +#, c-format +msgid "constraint %s on %s" +msgstr "Constraint %s für %s" + +#: catalog/objectaddress.c:3017 +#, c-format +msgid "constraint %s" +msgstr "Constraint %s" + +#: catalog/objectaddress.c:3049 +#, c-format +msgid "conversion %s" +msgstr "Konversion %s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:3095 +#, c-format +msgid "default value for %s" +msgstr "Vorgabewert für %s" + +#: catalog/objectaddress.c:3109 +#, c-format +msgid "language %s" +msgstr "Sprache %s" + +#: catalog/objectaddress.c:3117 +#, c-format +msgid "large object %u" +msgstr "Large Object %u" + +#: catalog/objectaddress.c:3130 +#, c-format +msgid "operator %s" +msgstr "Operator %s" + +#: catalog/objectaddress.c:3167 +#, c-format +msgid "operator class %s for access method %s" +msgstr "Operatorklasse %s für Zugriffsmethode %s" + +#: catalog/objectaddress.c:3195 +#, c-format +msgid "access method %s" +msgstr "Zugriffsmethode %s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3244 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "Operator %d (%s, %s) von %s: %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3301 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "Funktion %d (%s, %s) von %s: %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3353 +#, c-format +msgid "rule %s on %s" +msgstr "Regel %s für %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3399 +#, c-format +msgid "trigger %s on %s" +msgstr "Trigger %s für %s" + +#: catalog/objectaddress.c:3419 +#, c-format +msgid "schema %s" +msgstr "Schema %s" + +#: catalog/objectaddress.c:3447 +#, c-format +msgid "statistics object %s" +msgstr "Statistikobjekt %s" + +#: catalog/objectaddress.c:3478 +#, c-format +msgid "text search parser %s" +msgstr "Textsucheparser %s" + +#: catalog/objectaddress.c:3509 +#, c-format +msgid "text search dictionary %s" +msgstr "Textsuchewörterbuch %s" + +#: catalog/objectaddress.c:3540 +#, c-format +msgid "text search template %s" +msgstr "Textsuchevorlage %s" + +#: catalog/objectaddress.c:3571 +#, c-format +msgid "text search configuration %s" +msgstr "Textsuchekonfiguration %s" + +#: catalog/objectaddress.c:3584 +#, c-format +msgid "role %s" +msgstr "Rolle %s" + +#: catalog/objectaddress.c:3600 +#, c-format +msgid "database %s" +msgstr "Datenbank %s" + +#: catalog/objectaddress.c:3616 +#, c-format +msgid "tablespace %s" +msgstr "Tablespace %s" + +#: catalog/objectaddress.c:3627 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "Fremddaten-Wrapper %s" + +#: catalog/objectaddress.c:3637 +#, c-format +msgid "server %s" +msgstr "Server %s" + +#: catalog/objectaddress.c:3670 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "Benutzerabbildung für %s auf Server %s" + +#: catalog/objectaddress.c:3722 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Relationen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3726 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "Vorgabeprivilegien für neue Relationen von Rolle %s" + +#: catalog/objectaddress.c:3732 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Sequenzen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3736 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "Vorgabeprivilegien für neue Sequenzen von Rolle %s" + +#: catalog/objectaddress.c:3742 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Funktionen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3746 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "Vorgabeprivilegien für neue Funktionen von Rolle %s" + +#: catalog/objectaddress.c:3752 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Typen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3756 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "Vorgabeprivilegien für neue Typen von Rolle %s" + +#: catalog/objectaddress.c:3762 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "Vorgabeprivilegien für neue Schemas von Rolle %s" + +#: catalog/objectaddress.c:3769 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3773 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "Vorgabeprivilegien von Rolle %s" + +#: catalog/objectaddress.c:3795 +#, c-format +msgid "extension %s" +msgstr "Erweiterung %s" + +#: catalog/objectaddress.c:3812 +#, c-format +msgid "event trigger %s" +msgstr "Ereignistrigger %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3856 +#, c-format +msgid "policy %s on %s" +msgstr "Policy %s für %s" + +#: catalog/objectaddress.c:3870 +#, c-format +msgid "publication %s" +msgstr "Publikation %s" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3898 +#, c-format +msgid "publication of %s in publication %s" +msgstr "Publikation von %s in Publikation %s" + +#: catalog/objectaddress.c:3911 +#, c-format +msgid "subscription %s" +msgstr "Subskription %s" + +#: catalog/objectaddress.c:3932 +#, c-format +msgid "transform for %s language %s" +msgstr "Transformation %s für Sprache %s" + +#: catalog/objectaddress.c:4003 +#, c-format +msgid "table %s" +msgstr "Tabelle %s" + +#: catalog/objectaddress.c:4008 +#, c-format +msgid "index %s" +msgstr "Index %s" + +#: catalog/objectaddress.c:4012 +#, c-format +msgid "sequence %s" +msgstr "Sequenz %s" + +#: catalog/objectaddress.c:4016 +#, c-format +msgid "toast table %s" +msgstr "TOAST-Tabelle %s" + +#: catalog/objectaddress.c:4020 +#, c-format +msgid "view %s" +msgstr "Sicht %s" + +#: catalog/objectaddress.c:4024 +#, c-format +msgid "materialized view %s" +msgstr "materialisierte Sicht %s" + +#: catalog/objectaddress.c:4028 +#, c-format +msgid "composite type %s" +msgstr "zusammengesetzter Typ %s" + +#: catalog/objectaddress.c:4032 +#, c-format +msgid "foreign table %s" +msgstr "Fremdtabelle %s" + +#: catalog/objectaddress.c:4037 +#, c-format +msgid "relation %s" +msgstr "Relation %s" + +#: catalog/objectaddress.c:4078 +#, c-format +msgid "operator family %s for access method %s" +msgstr "Operatorfamilie %s für Zugriffsmethode %s" + +#: catalog/pg_aggregate.c:129 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "Aggregatfunktionen können nicht mehr als %d Argument haben" +msgstr[1] "Aggregatfunktionen können nicht mehr als %d Argumente haben" + +#: catalog/pg_aggregate.c:144 catalog/pg_aggregate.c:158 +#, c-format +msgid "cannot determine transition data type" +msgstr "kann Übergangsdatentyp nicht bestimmen" + +#: catalog/pg_aggregate.c:173 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "eine variadische Ordered-Set-Aggregatfunktion muss VARIADIC-Typ ANY verwenden" + +#: catalog/pg_aggregate.c:199 +#, c-format +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" +msgstr "eine Hypothetical-Set-Aggregatfunktion muss direkte Argumente haben, die mit ihren aggregierten Argumenten übereinstimmen" + +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "Rückgabetyp der Übergangsfunktion %s ist nicht %s" + +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 +#, c-format +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" +msgstr "Anfangswert darf nicht ausgelassen werden, wenn Übergangsfunktion strikt ist und Übergangstyp nicht mit Eingabetyp kompatibel ist" + +#: catalog/pg_aggregate.c:335 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "Rückgabetyp der inversen Übergangsfunktion %s ist nicht %s" + +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2852 +#, c-format +msgid "strictness of aggregate's forward and inverse transition functions must match" +msgstr "Striktheit der vorwärtigen und inversen Übergangsfunktionen einer Aggregatfunktion müssen übereinstimmen" + +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:554 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "Abschlussfunktion mit zusätzlichen Argumenten darf nicht als STRICT deklariert sein" + +#: catalog/pg_aggregate.c:427 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "Rückgabetyp der Kombinierfunktion %s ist nicht %s" + +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:4128 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "Kombinierfunktion mit Übergangstyp %s darf nicht als STRICT deklariert sein" + +#: catalog/pg_aggregate.c:458 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "Rückgabetyp der Serialisierungsfunktion %s ist nicht %s" + +#: catalog/pg_aggregate.c:479 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "Rückgabetyp der Deserialisierungsfunktion %s ist nicht %s" + +#: catalog/pg_aggregate.c:498 catalog/pg_proc.c:189 catalog/pg_proc.c:223 +#, c-format +msgid "cannot determine result data type" +msgstr "kann Ergebnisdatentyp nicht bestimmen" + +#: catalog/pg_aggregate.c:513 catalog/pg_proc.c:202 catalog/pg_proc.c:231 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "unsichere Verwendung des Pseudotyps »internal«" + +#: catalog/pg_aggregate.c:567 +#, c-format +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" +msgstr "Moving-Aggregat-Implementierung gibt Typ %s zurück, aber die normale Implementierung gibt Typ %s zurück" + +#: catalog/pg_aggregate.c:578 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "Sortieroperator kann nur für Aggregatfunktionen mit einem Argument angegeben werden" + +#: catalog/pg_aggregate.c:706 catalog/pg_proc.c:384 +#, c-format +msgid "cannot change routine kind" +msgstr "kann Routinenart nicht ändern" + +#: catalog/pg_aggregate.c:708 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "»%s« ist eine normale Aggregatfunktion." + +#: catalog/pg_aggregate.c:710 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "»%s« ist eine Ordered-Set-Aggregatfunktion." + +#: catalog/pg_aggregate.c:712 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "»%s« ist eine Hypothetical-Set-Aggregatfunktion." + +#: catalog/pg_aggregate.c:717 +#, c-format +msgid "cannot change number of direct arguments of an aggregate function" +msgstr "die Anzahl direkter Argumente einer Aggregatfunktion kann nicht geändert werden" + +#: catalog/pg_aggregate.c:858 commands/functioncmds.c:676 +#: commands/typecmds.c:1992 commands/typecmds.c:2038 commands/typecmds.c:2090 +#: commands/typecmds.c:2127 commands/typecmds.c:2161 commands/typecmds.c:2195 +#: commands/typecmds.c:2229 commands/typecmds.c:2258 commands/typecmds.c:2345 +#: commands/typecmds.c:2387 parser/parse_func.c:416 parser/parse_func.c:447 +#: parser/parse_func.c:474 parser/parse_func.c:488 parser/parse_func.c:610 +#: parser/parse_func.c:630 parser/parse_func.c:2143 parser/parse_func.c:2334 +#, c-format +msgid "function %s does not exist" +msgstr "Funktion %s existiert nicht" + +#: catalog/pg_aggregate.c:864 +#, c-format +msgid "function %s returns a set" +msgstr "Funktion %s gibt eine Ergebnismenge zurück" + +#: catalog/pg_aggregate.c:879 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "Funktion %s muss VARIADIC ANY akzeptieren, um in dieser Aggregatfunktion verwendet zu werden" + +#: catalog/pg_aggregate.c:903 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "Funktion %s erfordert Typumwandlung zur Laufzeit" + +#: catalog/pg_cast.c:68 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "Typumwandlung von Typ %s in Typ %s existiert bereits" + +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "Sortierfolge »%s« existiert bereits, wird übersprungen" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits, wird übersprungen" + +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "Sortierfolge »%s« existiert bereits" + +#: catalog/pg_collation.c:105 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits" + +#: catalog/pg_constraint.c:678 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "Constraint »%s« für Domäne %s existiert bereits" + +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "Constraint »%s« für Tabelle »%s« existiert nicht" + +#: catalog/pg_constraint.c:1056 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "Constraint »%s« für Domäne %s existiert nicht" + +#: catalog/pg_conversion.c:67 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "Konversion »%s« existiert bereits" + +#: catalog/pg_conversion.c:80 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "Standardumwandlung von %s nach %s existiert bereits" + +#: catalog/pg_depend.c:204 commands/extension.c:3343 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "%s ist schon Mitglied der Erweiterung »%s«" + +#: catalog/pg_depend.c:580 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "kann Abhängigkeit von %s nicht entfernen, weil es ein Systemobjekt ist" + +#: catalog/pg_enum.c:128 catalog/pg_enum.c:230 catalog/pg_enum.c:525 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "ungültiges Enum-Label »%s«" + +#: catalog/pg_enum.c:129 catalog/pg_enum.c:231 catalog/pg_enum.c:526 +#, c-format +msgid "Labels must be %d bytes or less." +msgstr "Labels müssen %d oder weniger Bytes haben." + +#: catalog/pg_enum.c:259 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "Enum-Label »%s« existiert bereits, wird übersprungen" + +#: catalog/pg_enum.c:266 catalog/pg_enum.c:569 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "Enum-Label »%s« existiert bereits" + +#: catalog/pg_enum.c:321 catalog/pg_enum.c:564 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "»%s« ist kein existierendes Enum-Label" + +#: catalog/pg_enum.c:379 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "OID-Wert für pg_enum ist im Binary-Upgrade-Modus nicht gesetzt" + +#: catalog/pg_enum.c:389 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "ALTER TYPE ADD BEFORE/AFTER ist mit Binary Upgrade inkompatibel" + +#: catalog/pg_inherits.c:593 +#, fuzzy, c-format +#| msgid "cannot inherit from partition \"%s\"" +msgid "cannot detach partition \"%s\"" +msgstr "von Partition »%s« kann nicht geerbt werden" + +#: catalog/pg_inherits.c:595 +#, c-format +msgid "The partition is being detached concurrently or has an unfinished detach." +msgstr "" + +#: catalog/pg_inherits.c:596 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation" +msgstr "" + +#: catalog/pg_inherits.c:600 +#, fuzzy, c-format +#| msgid "cannot cluster on partial index \"%s\"" +msgid "cannot complete detaching partition \"%s\"" +msgstr "kann nicht anhand des partiellen Index »%s« clustern" + +#: catalog/pg_inherits.c:602 +#, c-format +msgid "There's no pending concurrent detach." +msgstr "" + +#: catalog/pg_namespace.c:64 commands/schemacmds.c:242 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "Schema »%s« existiert bereits" + +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "»%s« ist kein gültiger Operatorname" + +#: catalog/pg_operator.c:370 +#, c-format +msgid "only binary operators can have commutators" +msgstr "nur binäre Operatoren können Kommutatoren haben" + +#: catalog/pg_operator.c:374 commands/operatorcmds.c:507 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "nur binäre Operatoren können Join-Selectivity haben" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can merge join" +msgstr "nur binäre Operatoren können an einem Merge-Verbund teilnehmen" + +#: catalog/pg_operator.c:382 +#, c-format +msgid "only binary operators can hash" +msgstr "nur binäre Operatoren können eine Hash-Funktion haben" + +#: catalog/pg_operator.c:393 +#, c-format +msgid "only boolean operators can have negators" +msgstr "nur Boole’sche Operatoren können Negatoren haben" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:515 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "nur Boole’sche Operatoren können Restriction-Selectivity haben" + +#: catalog/pg_operator.c:401 commands/operatorcmds.c:519 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "nur Boole’sche Operatoren können Join-Selectivity haben" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can merge join" +msgstr "nur Boole’sche Operatoren können an einem Merge-Verbund teilnehmen" + +#: catalog/pg_operator.c:409 +#, c-format +msgid "only boolean operators can hash" +msgstr "nur Boole’sche Operatoren können eine Hash-Funktion haben" + +#: catalog/pg_operator.c:421 +#, c-format +msgid "operator %s already exists" +msgstr "Operator %s existiert bereits" + +#: catalog/pg_operator.c:621 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "Operator kann nicht sein eigener Negator oder Sortierungsoperator sein" + +#: catalog/pg_proc.c:130 parser/parse_func.c:2205 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "Funktionen können nicht mehr als %d Argument haben" +msgstr[1] "Funktionen können nicht mehr als %d Argumente haben" + +#: catalog/pg_proc.c:374 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "Funktion »%s« existiert bereits mit den selben Argumenttypen" + +#: catalog/pg_proc.c:386 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "»%s« ist eine Aggregatfunktion." + +#: catalog/pg_proc.c:388 +#, c-format +msgid "\"%s\" is a function." +msgstr "»%s« ist eine Funktion." + +#: catalog/pg_proc.c:390 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "»%s« ist eine Prozedur." + +#: catalog/pg_proc.c:392 +#, c-format +msgid "\"%s\" is a window function." +msgstr "»%s« ist eine Fensterfunktion." + +#: catalog/pg_proc.c:412 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "man kann nicht ändern, ob eine Prozedur Ausgabeparameter hat" + +#: catalog/pg_proc.c:413 catalog/pg_proc.c:443 +#, c-format +msgid "cannot change return type of existing function" +msgstr "kann Rückgabetyp einer bestehenden Funktion nicht ändern" + +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:419 catalog/pg_proc.c:446 catalog/pg_proc.c:493 +#: catalog/pg_proc.c:519 catalog/pg_proc.c:545 +#, c-format +msgid "Use %s %s first." +msgstr "Verwenden Sie zuerst %s %s." + +#: catalog/pg_proc.c:444 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "Der von OUT-Parametern bestimmte Zeilentyp ist verschieden." + +#: catalog/pg_proc.c:490 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "kann Name des Eingabeparameters »%s« nicht ändern" + +#: catalog/pg_proc.c:517 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "kann Parametervorgabewerte einer bestehenden Funktion nicht entfernen" + +#: catalog/pg_proc.c:543 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "kann Datentyp eines bestehenden Parametervorgabewerts nicht ändern" + +#: catalog/pg_proc.c:753 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "es gibt keine eingebaute Funktion namens %s" + +#: catalog/pg_proc.c:851 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "SQL-Funktionen können keinen Rückgabetyp »%s« haben" + +#: catalog/pg_proc.c:866 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "SQL-Funktionen können keine Argumente vom Typ »%s« haben" + +#: catalog/pg_proc.c:978 executor/functions.c:1458 +#, c-format +msgid "SQL function \"%s\"" +msgstr "SQL-Funktion »%s«" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Only tables can be added to publications." +msgstr "Nur Tabellen können Teil einer Publikationen sein." + +#: catalog/pg_publication.c:65 +#, c-format +msgid "\"%s\" is a system table" +msgstr "»%s« ist eine Systemtabelle" + +#: catalog/pg_publication.c:67 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "Systemtabellen können nicht Teil einer Publikationen sein." + +#: catalog/pg_publication.c:73 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "Tabelle »%s« kann nicht repliziert werden" + +#: catalog/pg_publication.c:75 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "Temporäre und ungeloggte Tabellen können nicht repliziert werden." + +#: catalog/pg_publication.c:174 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "Relation »%s« ist schon Mitglied der Publikation »%s«" + +#: catalog/pg_publication.c:470 commands/publicationcmds.c:451 +#: commands/publicationcmds.c:739 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "Publikation »%s« existiert nicht" + +#: catalog/pg_shdepend.c:832 +#, c-format +msgid "" +"\n" +"and objects in %d other database (see server log for list)" +msgid_plural "" +"\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "" +"\n" +"und Objekte in %d anderen Datenbank (Liste im Serverlog)" +msgstr[1] "" +"\n" +"und Objekte in %d anderen Datenbanken (Liste im Serverlog)" + +#: catalog/pg_shdepend.c:1176 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "Rolle %u wurde gleichzeitig gelöscht" + +#: catalog/pg_shdepend.c:1188 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "Tablespace %u wurde gleichzeitig gelöscht" + +#: catalog/pg_shdepend.c:1202 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "Datenbank %u wurde gleichzeitig gelöscht" + +#: catalog/pg_shdepend.c:1247 +#, c-format +msgid "owner of %s" +msgstr "Eigentümer von %s" + +#: catalog/pg_shdepend.c:1249 +#, c-format +msgid "privileges for %s" +msgstr "Privilegien für %s" + +#: catalog/pg_shdepend.c:1251 +#, c-format +msgid "target of %s" +msgstr "Ziel von %s" + +#: catalog/pg_shdepend.c:1253 +#, c-format +msgid "tablespace for %s" +msgstr "Tablespace für %s" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1261 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%d Objekt in %s" +msgstr[1] "%d Objekte in %s" + +#: catalog/pg_shdepend.c:1372 +#, c-format +msgid "cannot drop objects owned by %s because they are required by the database system" +msgstr "kann Objekte, die %s gehören, nicht löschen, weil sie vom Datenbanksystem benötigt werden" + +#: catalog/pg_shdepend.c:1519 +#, c-format +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" +msgstr "kann den Eigentümer von den Objekten, die %s gehören, nicht ändern, weil die Objekte vom Datenbanksystem benötigt werden" + +#: catalog/pg_subscription.c:174 commands/subscriptioncmds.c:775 +#: commands/subscriptioncmds.c:1085 commands/subscriptioncmds.c:1427 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "Subskription »%s« existiert nicht" + +#: catalog/pg_subscription.c:432 +#, fuzzy, c-format +#| msgid "could not find function information for function \"%s\"" +msgid "could not drop relation mapping for subscription \"%s\"" +msgstr "konnte Funktionsinformationen für Funktion »%s« nicht finden" + +#: catalog/pg_subscription.c:434 +#, c-format +msgid "Table synchronization for relation \"%s\" is in progress and is in state \"%c\"." +msgstr "Tabellensynchronisierung für Relation »%s« ist im Gang und hat Status »%c«." + +#. translator: first %s is a SQL ALTER command and second %s is a +#. SQL DROP command +#. +#: catalog/pg_subscription.c:441 +#, c-format +msgid "Use %s to enable subscription if not already enabled or use %s to drop the subscription." +msgstr "Verwenden Sie %s um die Subskription zu aktivieren, falls noch nicht aktiviert, oder %s um die Subskription zu löschen." + +#: catalog/pg_type.c:136 catalog/pg_type.c:475 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" + +#: catalog/pg_type.c:255 +#, c-format +msgid "invalid type internal size %d" +msgstr "ungültige interne Typgröße %d" + +#: catalog/pg_type.c:271 catalog/pg_type.c:279 catalog/pg_type.c:287 +#: catalog/pg_type.c:296 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "Ausrichtung »%c« ist ungültig für Typen mit Wertübergabe mit Größe %d" + +#: catalog/pg_type.c:303 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "interne Größe %d ist ungültig für Typen mit Wertübergabe" + +#: catalog/pg_type.c:313 catalog/pg_type.c:319 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "Ausrichtung »%c« ist ungültig für Typen variabler Länge" + +#: catalog/pg_type.c:327 commands/typecmds.c:4164 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "Typen mit fester Größe müssen Storage-Typ PLAIN haben" + +#: catalog/pg_type.c:816 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "konnte keinen Arraytypnamen für Datentyp »%s« erzeugen" + +#: catalog/pg_type.c:921 +#, fuzzy, c-format +#| msgid "Failed while creating memory context \"%s\"." +msgid "Failed while creating a multirange type for type \"%s\"." +msgstr "Fehler während der Erzeugung des Speicherkontexts »%s«." + +#: catalog/pg_type.c:922 +#, c-format +msgid "You can manually specify a multirange type name using the \"multirange_type_name\" attribute" +msgstr "" + +#: catalog/storage.c:450 storage/buffer/bufmgr.c:1026 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "ungültige Seite in Block %u von Relation %s" + +#: catalog/toasting.c:104 commands/indexcmds.c:667 commands/tablecmds.c:6028 +#: commands/tablecmds.c:16336 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "»%s« ist keine Tabelle oder materialisierte Sicht" + +#: commands/aggregatecmds.c:170 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "nur Ordered-Set-Aggregatfunktionen können Hypothetical-Set-Aggregatfunktionen sein" + +#: commands/aggregatecmds.c:195 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "Attribut »%s« für Aggregatfunktion unbekannt" + +#: commands/aggregatecmds.c:205 +#, c-format +msgid "aggregate stype must be specified" +msgstr "»stype« für Aggregatfunktion muss angegeben werden" + +#: commands/aggregatecmds.c:209 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "»sfunc« für Aggregatfunktion muss angegeben werden" + +#: commands/aggregatecmds.c:221 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "»msfunc« für Aggregatfunktion muss angegeben werden, wenn »mstype« angegeben ist" + +#: commands/aggregatecmds.c:225 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "»minvfunc« für Aggregatfunktion muss angegeben werden, wenn »mstype« angegeben ist" + +#: commands/aggregatecmds.c:232 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "»msfunc« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" + +#: commands/aggregatecmds.c:236 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "»minvfunc« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" + +#: commands/aggregatecmds.c:240 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "»mfinalfunc« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" + +#: commands/aggregatecmds.c:244 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "»msspace« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" + +#: commands/aggregatecmds.c:248 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "»minitcond« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" + +#: commands/aggregatecmds.c:277 +#, c-format +msgid "aggregate input type must be specified" +msgstr "Eingabetyp für Aggregatfunktion muss angegeben werden" + +#: commands/aggregatecmds.c:307 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "Angabe »basetype« ist überflüssig bei Angabe des Eingabetyps der Aggregatfunktion" + +#: commands/aggregatecmds.c:350 commands/aggregatecmds.c:391 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "Übergangsdatentyp von Aggregatfunktion kann nicht %s sein" + +#: commands/aggregatecmds.c:362 +#, c-format +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "Serialisierungsfunktionen dürfen nur angegeben werden, wenn der Übergangsdatentyp der Aggregatfunktion %s ist" + +#: commands/aggregatecmds.c:372 +#, c-format +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "Serialisierungs- und Deserialisierungsfunktionen müssen zusammen angegeben werden" + +#: commands/aggregatecmds.c:437 commands/functioncmds.c:624 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "Parameter »parallel« muss SAFE, RESTRICTED oder UNSAFE sein" + +#: commands/aggregatecmds.c:493 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "Parameter »%s« muss READ_ONLY, SHAREABLE oder READ_WRITE sein" + +#: commands/alter.c:84 commands/event_trigger.c:174 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "Ereignistrigger »%s« existiert bereits" + +#: commands/alter.c:87 commands/foreigncmds.c:597 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "Fremddaten-Wrapper »%s« existiert bereits" + +#: commands/alter.c:90 commands/foreigncmds.c:879 +#, c-format +msgid "server \"%s\" already exists" +msgstr "Server »%s« existiert bereits" + +#: commands/alter.c:93 commands/proclang.c:133 +#, c-format +msgid "language \"%s\" already exists" +msgstr "Sprache »%s« existiert bereits" + +#: commands/alter.c:96 commands/publicationcmds.c:183 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "Publikation »%s« existiert bereits" + +#: commands/alter.c:99 commands/subscriptioncmds.c:398 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "Subskription »%s« existiert bereits" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "Konversion »%s« existiert bereits in Schema »%s«" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "Statistikobjekt »%s« existiert bereits in Schema »%s«" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr "Textsucheparser »%s« existiert bereits in Schema »%s«" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "Textsuchewörterbuch »%s« existiert bereits in Schema »%s«" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "Textsuchevorlage »%s« existiert bereits in Schema »%s«" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "Textsuchekonfiguration »%s« existiert bereits in Schema »%s«" + +#: commands/alter.c:215 +#, c-format +msgid "must be superuser to rename %s" +msgstr "nur Superuser können %s umbenennen" + +#: commands/alter.c:744 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "nur Superuser können Schema von %s setzen" + +#: commands/amcmds.c:60 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "keine Berechtigung, um Zugriffsmethode »%s« zu erzeugen" + +#: commands/amcmds.c:62 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "Nur Superuser können Zugriffsmethoden anlegen." + +#: commands/amcmds.c:71 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "Zugriffsmethode »%s« existiert bereits" + +#: commands/amcmds.c:154 commands/indexcmds.c:210 commands/indexcmds.c:818 +#: commands/opclasscmds.c:370 commands/opclasscmds.c:824 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "Zugriffsmethode »%s« existiert nicht" + +#: commands/amcmds.c:243 +#, c-format +msgid "handler function is not specified" +msgstr "keine Handler-Funktion angegeben" + +#: commands/amcmds.c:264 commands/event_trigger.c:183 +#: commands/foreigncmds.c:489 commands/proclang.c:80 commands/trigger.c:681 +#: parser/parse_clause.c:941 +#, c-format +msgid "function %s must return type %s" +msgstr "Funktion %s muss Rückgabetyp %s haben" + +#: commands/analyze.c:227 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "überspringe »%s« --- kann diese Fremdtabelle nicht analysieren" + +#: commands/analyze.c:244 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "überspringe »%s« --- kann Nicht-Tabellen oder besondere Systemtabellen nicht analysieren" + +#: commands/analyze.c:324 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "analysiere Vererbungsbaum von »%s.%s«" + +#: commands/analyze.c:329 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "analysiere »%s.%s«" + +#: commands/analyze.c:395 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "Spalte »%s« von Relation »%s« erscheint mehrmals" + +#: commands/analyze.c:790 +#, fuzzy, c-format +#| msgid "automatic analyze of table \"%s.%s.%s\"" +msgid "automatic analyze of table \"%s.%s.%s\"\n" +msgstr "automatisches Analysieren der Tabelle »%s.%s.%s«" + +#: commands/analyze.c:811 +#, c-format +msgid "system usage: %s" +msgstr "Systembenutzung: %s" + +#: commands/analyze.c:1350 +#, c-format +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "»%s«: %d von %u Seiten gelesen, enthalten %.0f lebende Zeilen und %.0f tote Zeilen; %d Zeilen in Stichprobe, schätzungsweise %.0f Zeilen insgesamt" + +#: commands/analyze.c:1430 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "überspringe Analysieren des Vererbungsbaums »%s.%s« --- dieser Vererbungsbaum enthält keine abgeleiteten Tabellen" + +#: commands/analyze.c:1528 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "überspringe Analysieren des Vererbungsbaums »%s.%s« --- dieser Vererbungsbaum enthält keine analysierbaren abgeleiteten Tabellen" + +#: commands/async.c:639 +#, c-format +msgid "channel name cannot be empty" +msgstr "Kanalname kann nicht leer sein" + +#: commands/async.c:645 +#, c-format +msgid "channel name too long" +msgstr "Kanalname zu lang" + +#: commands/async.c:650 +#, c-format +msgid "payload string too long" +msgstr "Payload-Zeichenkette zu lang" + +#: commands/async.c:869 +#, c-format +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "PREPARE kann nicht in einer Transaktion ausgeführt werden, die LISTEN, UNLISTEN oder NOTIFY ausgeführt hat" + +#: commands/async.c:975 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "zu viele Benachrichtigungen in NOTIFY-Schlange" + +#: commands/async.c:1646 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "NOTIFY-Schlange ist %.0f%% voll" + +#: commands/async.c:1648 +#, c-format +msgid "The server process with PID %d is among those with the oldest transactions." +msgstr "Der Serverprozess mit PID %d gehört zu denen mit den ältesten Transaktionen." + +#: commands/async.c:1651 +#, c-format +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." +msgstr "Die NOTIFY-Schlange kann erst geleert werden, wenn dieser Prozess seine aktuelle Transaktion beendet." + +#: commands/cluster.c:119 +#, c-format +msgid "unrecognized CLUSTER option \"%s\"" +msgstr "unbekannte CLUSTER-Option »%s«" + +#: commands/cluster.c:147 commands/cluster.c:386 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "kann temporäre Tabellen anderer Sitzungen nicht clustern" + +#: commands/cluster.c:155 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "eine partitionierte Tabelle kann nicht geclustert werden" + +#: commands/cluster.c:173 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "es gibt keinen bereits geclusterten Index für Tabelle »%s«" + +#: commands/cluster.c:187 commands/tablecmds.c:13496 commands/tablecmds.c:15364 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "Index »%s« für Tabelle »%s« existiert nicht" + +#: commands/cluster.c:375 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "globaler Katalog kann nicht geclustert werden" + +#: commands/cluster.c:390 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "temporäre Tabellen anderer Sitzungen können nicht gevacuumt werden" + +#: commands/cluster.c:456 commands/tablecmds.c:15374 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "»%s« ist kein Index für Tabelle »%s«" + +#: commands/cluster.c:464 +#, c-format +msgid "cannot cluster on index \"%s\" because access method does not support clustering" +msgstr "kann nicht anhand des Index »%s« clustern, weil die Indexmethode Clustern nicht unterstützt" + +#: commands/cluster.c:476 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "kann nicht anhand des partiellen Index »%s« clustern" + +#: commands/cluster.c:490 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "kann nicht anhand des ungültigen Index »%s« clustern" + +#: commands/cluster.c:514 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "ein Index kann nicht als anhand einer partitionierten Tabelle geclustert markiert werden" + +#: commands/cluster.c:887 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr "clustere »%s.%s« durch Index-Scan von »%s«" + +#: commands/cluster.c:893 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "clustere »%s.%s« durch sequenziellen Scan und Sortieren" + +#: commands/cluster.c:924 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "»%s«: %.0f entfernbare, %.0f nicht entfernbare Zeilenversionen in %u Seiten gefunden" + +#: commands/cluster.c:928 +#, c-format +msgid "" +"%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "" +"%.0f tote Zeilenversionen können noch nicht entfernt werden.\n" +"%s." + +#: commands/collationcmds.c:106 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "Attribut »%s« für Sortierfolge unbekannt" + +#: commands/collationcmds.c:149 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "Sortierfolge »default« kann nicht kopiert werden" + +#: commands/collationcmds.c:182 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "unbekannter Sortierfolgen-Provider: %s" + +#: commands/collationcmds.c:191 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "Parameter »lc_collate« muss angegeben werden" + +#: commands/collationcmds.c:196 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "Parameter »lc_ctype« muss angegeben werden" + +#: commands/collationcmds.c:206 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "nichtdeterministische Sortierfolgen werden von diesem Provider nicht unterstützt" + +#: commands/collationcmds.c:266 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits in Schema »%s«" + +#: commands/collationcmds.c:277 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "Sortierfolge »%s« existiert bereits in Schema »%s«" + +#: commands/collationcmds.c:325 +#, c-format +msgid "changing version from %s to %s" +msgstr "Version wird von %s in %s geändert" + +#: commands/collationcmds.c:340 +#, c-format +msgid "version has not changed" +msgstr "Version hat sich nicht geändert" + +#: commands/collationcmds.c:454 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "konnte Locale-Namen »%s« nicht in Sprach-Tag umwandeln: %s" + +#: commands/collationcmds.c:512 +#, c-format +msgid "must be superuser to import system collations" +msgstr "nur Superuser können Systemsortierfolgen importieren" + +#: commands/collationcmds.c:540 commands/copyfrom.c:1500 commands/copyto.c:688 +#: libpq/be-secure-common.c:81 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "konnte Befehl »%s« nicht ausführen: %m" + +#: commands/collationcmds.c:671 +#, c-format +msgid "no usable system locales were found" +msgstr "keine brauchbaren System-Locales gefunden" + +#: commands/comment.c:61 commands/dbcommands.c:841 commands/dbcommands.c:1037 +#: commands/dbcommands.c:1150 commands/dbcommands.c:1340 +#: commands/dbcommands.c:1588 commands/dbcommands.c:1702 +#: commands/dbcommands.c:2142 utils/init/postinit.c:887 +#: utils/init/postinit.c:992 utils/init/postinit.c:1009 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "Datenbank »%s« existiert nicht" + +#: commands/comment.c:101 commands/seclabel.c:191 parser/parse_utilcmd.c:989 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, zusammengesetzter Typ noch Fremdtabelle" + +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1948 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "Funktion »%s« wurde nicht von Triggermanager aufgerufen" + +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1957 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "Funktion »%s« muss AFTER ROW ausgelöst werden" + +#: commands/constraint.c:84 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "Funktion »%s« muss von INSERT oder UPDATE ausgelöst werden" + +#: commands/conversioncmds.c:67 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "Quellkodierung »%s« existiert nicht" + +#: commands/conversioncmds.c:74 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "Zielkodierung »%s« existiert nicht" + +#: commands/conversioncmds.c:87 +#, c-format +msgid "encoding conversion to or from \"SQL_ASCII\" is not supported" +msgstr "Kodierungsumwandlung nach oder von »SQL_ASCII« wird nicht unterstützt" + +#: commands/conversioncmds.c:100 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "Kodierungskonversionsfunktion %s muss Typ %s zurückgeben" + +#: commands/conversioncmds.c:130 +#, c-format +msgid "encoding conversion function %s returned incorrect result for empty input" +msgstr "Kodierungskonversionsfunktion %s hat falsches Ergebnis für leere Eingabe zurückgegeben" + +#: commands/copy.c:86 +#, c-format +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "nur Superuser oder Mitglieder von pg_execute_server_program können COPY mit externen Programmen verwenden" + +#: commands/copy.c:87 commands/copy.c:96 commands/copy.c:103 +#, c-format +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." +msgstr "Jeder kann COPY mit STDOUT oder STDIN verwenden. Der Befehl \\copy in psql funktioniert auch für jeden." + +#: commands/copy.c:95 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "nur Superuser oder Mitglieder von pg_read_server_files können mit COPY aus einer Datei lesen" + +#: commands/copy.c:102 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "nur Superuser oder Mitglieder von pg_write_server_files können mit COPY in eine Datei schreiben" + +#: commands/copy.c:188 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM wird nicht unterstützt mit Sicherheit auf Zeilenebene" + +#: commands/copy.c:189 +#, c-format +msgid "Use INSERT statements instead." +msgstr "Verwenden Sie stattdessen INSERT-Anweisungen." + +#: commands/copy.c:374 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "COPY-Format »%s« nicht erkannt" + +#: commands/copy.c:447 commands/copy.c:463 commands/copy.c:478 +#: commands/copy.c:500 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "Argument von Option »%s« muss eine Liste aus Spaltennamen sein" + +#: commands/copy.c:515 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "Argument von Option »%s« muss ein gültiger Kodierungsname sein" + +#: commands/copy.c:522 commands/dbcommands.c:253 commands/dbcommands.c:1536 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "Option »%s« nicht erkannt" + +#: commands/copy.c:534 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "DELIMITER kann nicht im BINARY-Modus angegeben werden" + +#: commands/copy.c:539 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "NULL kann nicht im BINARY-Modus angegeben werden" + +#: commands/copy.c:561 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "DELIMITER für COPY muss ein einzelnes Ein-Byte-Zeichen sein" + +#: commands/copy.c:568 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "COPY-Trennzeichen kann nicht Newline oder Carriage Return sein" + +#: commands/copy.c:574 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "COPY NULL-Darstellung kann nicht Newline oder Carriage Return enthalten" + +#: commands/copy.c:591 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "DELIMITER für COPY darf nicht »%s« sein" + +#: commands/copy.c:597 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "COPY HEADER ist nur im CSV-Modus verfügbar" + +#: commands/copy.c:603 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "Quote-Zeichen für COPY ist nur im CSV-Modus verfügbar" + +#: commands/copy.c:608 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "Quote-Zeichen für COPY muss ein einzelnes Ein-Byte-Zeichen sein" + +#: commands/copy.c:613 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "DELIMITER und QUOTE für COPY müssen verschieden sein" + +#: commands/copy.c:619 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "Escape-Zeichen für COPY ist nur im CSV-Modus verfügbar" + +#: commands/copy.c:624 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "Escape-Zeichen für COPY muss ein einzelnes Ein-Byte-Zeichen sein" + +#: commands/copy.c:630 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "FORCE_QUOTE für COPY ist nur im CSV-Modus verfügbar" + +#: commands/copy.c:634 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "FORCE_QUOTE ist nur bei COPY TO verfügbar" + +#: commands/copy.c:640 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "FORCE_NOT_NULL für COPY ist nur im CSV-Modus verfügbar" + +#: commands/copy.c:644 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "FORCE_NOT_NULL ist nur bei COPY FROM verfügbar" + +#: commands/copy.c:650 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "FORCE_NULL für COPY ist nur im CSV-Modus verfügbar" + +#: commands/copy.c:655 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "FORCE_NULL ist nur bei COPY FROM verfügbar" + +#: commands/copy.c:661 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "Trennzeichen für COPY darf nicht in der NULL-Darstellung erscheinen" + +#: commands/copy.c:668 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "CSV-Quote-Zeichen darf nicht in der NULL-Darstellung erscheinen" + +#: commands/copy.c:729 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "Spalte »%s« ist eine generierte Spalte" + +#: commands/copy.c:731 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "Generierte Spalten können nicht in COPY verwendet werden." + +#: commands/copy.c:746 commands/indexcmds.c:1754 commands/statscmds.c:238 +#: commands/tablecmds.c:2366 commands/tablecmds.c:3022 +#: commands/tablecmds.c:3515 parser/parse_relation.c:3593 +#: parser/parse_relation.c:3613 utils/adt/tsvector_op.c:2680 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "Spalte »%s« existiert nicht" + +#: commands/copy.c:753 commands/tablecmds.c:2392 commands/trigger.c:933 +#: parser/parse_target.c:1080 parser/parse_target.c:1091 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "Spalte »%s« mehrmals angegeben" + +#: commands/copyfrom.c:127 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, Zeile %s, Spalte %s" + +#: commands/copyfrom.c:131 commands/copyfrom.c:172 +#, c-format +msgid "COPY %s, line %s" +msgstr "COPY %s, Zeile %s" + +#: commands/copyfrom.c:142 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, Zeile %s, Spalte %s: »%s«" + +#: commands/copyfrom.c:150 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, Zeile %s, Spalte %s: NULL Eingabe" + +#: commands/copyfrom.c:166 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, Zeile %s: »%s«" + +#: commands/copyfrom.c:566 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "kann nicht in Sicht »%s« kopieren" + +#: commands/copyfrom.c:568 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "Um Kopieren in eine Sicht zu ermöglichen, richten Sie einen INSTEAD OF INSERT Trigger ein." + +#: commands/copyfrom.c:572 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "kann nicht in materialisierte Sicht »%s« kopieren" + +#: commands/copyfrom.c:577 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "kann nicht in Sequenz »%s« kopieren" + +#: commands/copyfrom.c:582 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "kann nicht in Relation »%s« kopieren, die keine Tabelle ist" + +#: commands/copyfrom.c:622 +#, c-format +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "COPY FREEZE kann nicht in einer partitionierten Tabelle durchgeführt werden" + +#: commands/copyfrom.c:637 +#, c-format +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "COPY FREEZE kann nicht durchgeführt werden wegen vorheriger Aktivität in dieser Transaktion" + +#: commands/copyfrom.c:643 +#, c-format +msgid "cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "COPY FREEZE kann nicht durchgeführt werden, weil die Tabelle nicht in der aktuellen Transaktion erzeugt oder geleert wurde" + +#: commands/copyfrom.c:1264 commands/copyto.c:618 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "Spalte »%s« mit FORCE_NOT_NULL wird von COPY nicht verwendet" + +#: commands/copyfrom.c:1287 commands/copyto.c:641 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "Spalte »%s« mit FORCE_NULL wird von COPY nicht verwendet" + +#: commands/copyfrom.c:1519 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "Mit COPY FROM liest der PostgreSQL-Serverprozess eine Datei. Möglicherweise möchten Sie Funktionalität auf Client-Seite verwenden, wie zum Beispiel \\copy in psql." + +#: commands/copyfrom.c:1532 commands/copyto.c:740 +#, c-format +msgid "\"%s\" is a directory" +msgstr "»%s« ist ein Verzeichnis" + +#: commands/copyfrom.c:1600 commands/copyto.c:302 libpq/be-secure-common.c:105 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "konnte Pipe zu externem Programm nicht schließen: %m" + +#: commands/copyfrom.c:1615 commands/copyto.c:307 +#, c-format +msgid "program \"%s\" failed" +msgstr "Programm »%s« fehlgeschlagen" + +#: commands/copyfromparse.c:199 +#, c-format +msgid "COPY file signature not recognized" +msgstr "COPY-Datei-Signatur nicht erkannt" + +#: commands/copyfromparse.c:204 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "ungültiger COPY-Dateikopf (Flags fehlen)" + +#: commands/copyfromparse.c:208 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "ungültiger COPY-Dateikopf (WITH OIDS)" + +#: commands/copyfromparse.c:213 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "unbekannte kritische Flags im COPY-Dateikopf" + +#: commands/copyfromparse.c:219 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "ungültiger COPY-Dateikopf (Länge fehlt)" + +#: commands/copyfromparse.c:226 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "ungültiger COPY-Dateikopf (falsche Länge)" + +#: commands/copyfromparse.c:255 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "konnte nicht aus COPY-Datei lesen: %m" + +#: commands/copyfromparse.c:277 commands/copyfromparse.c:302 +#: tcop/postgres.c:360 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "unerwartetes EOF auf Client-Verbindung mit einer offenen Transaktion" + +#: commands/copyfromparse.c:293 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "unerwarteter Messagetyp 0x%02X während COPY FROM STDIN" + +#: commands/copyfromparse.c:316 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "COPY FROM STDIN fehlgeschlagen: %s" + +#: commands/copyfromparse.c:841 commands/copyfromparse.c:1451 +#: commands/copyfromparse.c:1681 +#, c-format +msgid "extra data after last expected column" +msgstr "zusätzliche Daten nach letzter erwarteter Spalte" + +#: commands/copyfromparse.c:855 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "fehlende Daten für Spalte »%s«" + +#: commands/copyfromparse.c:933 +#, c-format +msgid "received copy data after EOF marker" +msgstr "COPY-Daten nach EOF-Markierung empfangen" + +#: commands/copyfromparse.c:940 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "Feldanzahl in Zeile ist %d, erwartet wurden %d" + +#: commands/copyfromparse.c:1233 commands/copyfromparse.c:1250 +#, c-format +msgid "literal carriage return found in data" +msgstr "Carriage-Return-Zeichen in Daten gefunden" + +#: commands/copyfromparse.c:1234 commands/copyfromparse.c:1251 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "ungequotetes Carriage-Return-Zeichen in Daten gefunden" + +#: commands/copyfromparse.c:1236 commands/copyfromparse.c:1253 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "Verwenden Sie »\\r«, um ein Carriage-Return-Zeichen darzustellen." + +#: commands/copyfromparse.c:1237 commands/copyfromparse.c:1254 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "Verwenden Sie ein gequotetes CSV-Feld, um ein Carriage-Return-Zeichen darzustellen." + +#: commands/copyfromparse.c:1266 +#, c-format +msgid "literal newline found in data" +msgstr "Newline-Zeichen in Daten gefunden" + +#: commands/copyfromparse.c:1267 +#, c-format +msgid "unquoted newline found in data" +msgstr "ungequotetes Newline-Zeichen in Daten gefunden" + +#: commands/copyfromparse.c:1269 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "Verwenden Sie »\\n«, um ein Newline-Zeichen darzustellen." + +#: commands/copyfromparse.c:1270 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "Verwenden Sie ein gequotetes CSV-Feld, um ein Newline-Zeichen darzustellen." + +#: commands/copyfromparse.c:1316 commands/copyfromparse.c:1352 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "COPY-Ende-Markierung stimmt nicht mit vorherigem Newline-Stil überein" + +#: commands/copyfromparse.c:1325 commands/copyfromparse.c:1341 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "COPY-Ende-Markierung verfälscht" + +#: commands/copyfromparse.c:1765 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "Quotes in CSV-Feld nicht abgeschlossen" + +#: commands/copyfromparse.c:1841 commands/copyfromparse.c:1860 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "unerwartetes EOF in COPY-Daten" + +#: commands/copyfromparse.c:1850 +#, c-format +msgid "invalid field size" +msgstr "ungültige Feldgröße" + +#: commands/copyfromparse.c:1873 +#, c-format +msgid "incorrect binary data format" +msgstr "falsches Binärdatenformat" + +#: commands/copyto.c:235 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "konnte nicht zum COPY-Programm schreiben: %m" + +#: commands/copyto.c:240 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "konnte nicht in COPY-Datei schreiben: %m" + +#: commands/copyto.c:370 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "kann nicht aus Sicht »%s« kopieren" + +#: commands/copyto.c:372 commands/copyto.c:378 commands/copyto.c:384 +#: commands/copyto.c:395 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "Versuchen Sie die Variante COPY (SELECT ...) TO." + +#: commands/copyto.c:376 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "kann nicht aus materialisierter Sicht »%s« kopieren" + +#: commands/copyto.c:382 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "kann nicht aus Fremdtabelle »%s« kopieren" + +#: commands/copyto.c:388 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "kann nicht aus Sequenz »%s« kopieren" + +#: commands/copyto.c:393 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "kann nicht aus partitionierter Tabelle »%s« kopieren" + +#: commands/copyto.c:399 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "kann nicht aus Relation »%s«, die keine Tabelle ist, kopieren" + +#: commands/copyto.c:457 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "DO-INSTEAD-NOTHING-Regeln werden für COPY nicht unterstützt" + +#: commands/copyto.c:471 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "DO-INSTEAD-Regeln mit Bedingung werden für COPY nicht unterstützt" + +#: commands/copyto.c:475 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "DO-ALSO-Regeln werden für COPY nicht unterstützt" + +#: commands/copyto.c:480 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "DO-INSTEAD-Regeln mit mehreren Anweisungen werden für COPY nicht unterstützt" + +#: commands/copyto.c:490 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO) wird nicht unterstützt" + +#: commands/copyto.c:507 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "COPY-Anfrage muss eine RETURNING-Klausel haben" + +#: commands/copyto.c:536 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "die von der COPY-Anweisung verwendete Relation hat sich geändert" + +#: commands/copyto.c:595 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "FORCE_QUOTE-Spalte »%s« wird von COPY nicht verwendet" + +#: commands/copyto.c:705 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "relativer Pfad bei COPY in Datei nicht erlaubt" + +#: commands/copyto.c:724 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "konnte Datei »%s« nicht zum Schreiben öffnen: %m" + +#: commands/copyto.c:727 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "Mit COPY TO schreibt der PostgreSQL-Serverprozess eine Datei. Möglicherweise möchten Sie Funktionalität auf Client-Seite verwenden, wie zum Beispiel \\copy in psql." + +#: commands/createas.c:215 commands/createas.c:517 +#, c-format +msgid "too many column names were specified" +msgstr "zu viele Spaltennamen wurden angegeben" + +#: commands/createas.c:540 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "Policys sind für diesen Befehl noch nicht implementiert" + +#: commands/dbcommands.c:246 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATION wird nicht mehr unterstützt" + +#: commands/dbcommands.c:247 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "Verwenden Sie stattdessen Tablespaces." + +#: commands/dbcommands.c:261 +#, c-format +msgid "LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE." +msgstr "LOCALE kann nicht zusammen mit LC_COLLATE oder LC_CTYPE angegeben werden." + +#: commands/dbcommands.c:279 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%d ist kein gültiger Kodierungscode" + +#: commands/dbcommands.c:290 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%s ist kein gültiger Kodierungsname" + +#: commands/dbcommands.c:314 commands/dbcommands.c:1569 commands/user.c:275 +#: commands/user.c:691 +#, c-format +msgid "invalid connection limit: %d" +msgstr "ungültige Verbindungshöchstgrenze: %d" + +#: commands/dbcommands.c:333 +#, c-format +msgid "permission denied to create database" +msgstr "keine Berechtigung, um Datenbank zu erzeugen" + +#: commands/dbcommands.c:356 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "Template-Datenbank »%s« existiert nicht" + +#: commands/dbcommands.c:368 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "keine Berechtigung, um Datenbank »%s« zu kopieren" + +#: commands/dbcommands.c:384 +#, c-format +msgid "invalid server encoding %d" +msgstr "ungültige Serverkodierung %d" + +#: commands/dbcommands.c:390 commands/dbcommands.c:395 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "ungültiger Locale-Name: »%s«" + +#: commands/dbcommands.c:415 +#, c-format +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" +msgstr "neue Kodierung (%s) ist inkompatibel mit der Kodierung der Template-Datenbank (%s)" + +#: commands/dbcommands.c:418 +#, c-format +msgid "Use the same encoding as in the template database, or use template0 as template." +msgstr "Verwenden Sie die gleiche Kodierung wie die Template-Datenbank oder verwenden Sie template0 als Template." + +#: commands/dbcommands.c:423 +#, c-format +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" +msgstr "neue Sortierreihenfolge (%s) ist inkompatibel mit der Sortierreihenfolge der Template-Datenbank (%s)" + +#: commands/dbcommands.c:425 +#, c-format +msgid "Use the same collation as in the template database, or use template0 as template." +msgstr "Verwenden Sie die gleiche Sortierreihenfolge wie die Template-Datenbank oder verwenden Sie template0 als Template." + +#: commands/dbcommands.c:430 +#, c-format +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" +msgstr "neues LC_CTYPE (%s) ist inkompatibel mit dem LC_CTYPE der Template-Datenbank (%s)" + +#: commands/dbcommands.c:432 +#, c-format +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." +msgstr "Verwenden Sie das gleiche LC_CTYPE wie die Template-Datenbank oder verwenden Sie template0 als Template." + +#: commands/dbcommands.c:454 commands/dbcommands.c:1196 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "pg_global kann nicht als Standard-Tablespace verwendet werden" + +#: commands/dbcommands.c:480 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "kann neuen Standard-Tablespace »%s« nicht setzen" + +#: commands/dbcommands.c:482 +#, c-format +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." +msgstr "Es gibt einen Konflikt, weil Datenbank »%s« schon einige Tabellen in diesem Tablespace hat." + +#: commands/dbcommands.c:512 commands/dbcommands.c:1066 +#, c-format +msgid "database \"%s\" already exists" +msgstr "Datenbank »%s« existiert bereits" + +#: commands/dbcommands.c:526 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "auf Quelldatenbank »%s« wird gerade von anderen Benutzern zugegriffen" + +#: commands/dbcommands.c:769 commands/dbcommands.c:784 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "Kodierung »%s« stimmt nicht mit Locale »%s« überein" + +#: commands/dbcommands.c:772 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "Die gewählte LC_CTYPE-Einstellung verlangt die Kodierung »%s«." + +#: commands/dbcommands.c:787 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "Die gewählte LC_COLLATE-Einstellung verlangt die Kodierung »%s«." + +#: commands/dbcommands.c:848 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "Datenbank »%s« existiert nicht, wird übersprungen" + +#: commands/dbcommands.c:872 +#, c-format +msgid "cannot drop a template database" +msgstr "Template-Datenbank kann nicht gelöscht werden" + +#: commands/dbcommands.c:878 +#, c-format +msgid "cannot drop the currently open database" +msgstr "kann aktuell geöffnete Datenbank nicht löschen" + +#: commands/dbcommands.c:891 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "Datenbank »%s« wird von einem aktiven logischen Replikations-Slot verwendet" + +#: commands/dbcommands.c:893 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "%d Slot ist vorhanden." +msgstr[1] "%d Slots sind vorhanden." + +#: commands/dbcommands.c:907 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "Datenbank »%s« wird von einer Subskription für logische Replikation verwendet" + +#: commands/dbcommands.c:909 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "%d Subskription ist vorhanden." +msgstr[1] "%d Subskriptionen sind vorhanden." + +#: commands/dbcommands.c:930 commands/dbcommands.c:1088 +#: commands/dbcommands.c:1218 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "auf Datenbank »%s« wird von anderen Benutzern zugegriffen" + +#: commands/dbcommands.c:1048 +#, c-format +msgid "permission denied to rename database" +msgstr "keine Berechtigung, um Datenbank umzubenennen" + +#: commands/dbcommands.c:1077 +#, c-format +msgid "current database cannot be renamed" +msgstr "aktuelle Datenbank kann nicht umbenannt werden" + +#: commands/dbcommands.c:1174 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "kann den Tablespace der aktuell geöffneten Datenbank nicht ändern" + +#: commands/dbcommands.c:1277 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "einige Relationen von Datenbank »%s« ist bereits in Tablespace »%s«" + +#: commands/dbcommands.c:1279 +#, c-format +msgid "You must move them back to the database's default tablespace before using this command." +msgstr "Sie müssen sie zurück in den Standard-Tablespace der Datenbank verschieben, bevor Sie diesen Befehl verwenden können." + +#: commands/dbcommands.c:1404 commands/dbcommands.c:1980 +#: commands/dbcommands.c:2203 commands/dbcommands.c:2261 +#: commands/tablespace.c:631 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "einige nutzlose Dateien wurde möglicherweise im alten Datenbankverzeichnis »%s« zurückgelassen" + +#: commands/dbcommands.c:1460 +#, c-format +msgid "unrecognized DROP DATABASE option \"%s\"" +msgstr "unbekannte DROP-DATABASE-Option »%s«" + +#: commands/dbcommands.c:1550 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "Option »%s« kann nicht mit anderen Optionen angegeben werden" + +#: commands/dbcommands.c:1606 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "Verbindungen mit der aktuellen Datenbank können nicht verboten werden" + +#: commands/dbcommands.c:1742 +#, c-format +msgid "permission denied to change owner of database" +msgstr "keine Berechtigung, um Eigentümer der Datenbank zu ändern" + +#: commands/dbcommands.c:2086 +#, c-format +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." +msgstr "%d andere Sitzung(en) und %d vorbereitete Transaktion(en) verwenden die Datenbank." + +#: commands/dbcommands.c:2089 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "%d andere Sitzung verwendet die Datenbank." +msgstr[1] "%d andere Sitzungen verwenden die Datenbank." + +#: commands/dbcommands.c:2094 storage/ipc/procarray.c:3726 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "%d vorbereitete Transaktion verwendet die Datenbank." +msgstr[1] "%d vorbereitete Transaktionen verwenden die Datenbank." + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 +#: commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%s erfordert einen Parameter" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 +#: commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%s erfordert einen numerischen Wert" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "%s erfordert einen Boole’schen Wert" + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%s erfordert einen ganzzahligen Wert" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "Argument von %s muss ein Name sein" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "Argument von %s muss ein Typname sein" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "ungültiges Argument für %s: »%s«" + +#: commands/dropcmds.c:100 commands/functioncmds.c:1385 +#: utils/adt/ruleutils.c:2806 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "»%s« ist eine Aggregatfunktion" + +#: commands/dropcmds.c:102 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "Verwenden Sie DROP AGGREGATE, um Aggregatfunktionen zu löschen." + +#: commands/dropcmds.c:158 commands/sequence.c:447 commands/tablecmds.c:3599 +#: commands/tablecmds.c:3757 commands/tablecmds.c:3802 +#: commands/tablecmds.c:15797 tcop/utility.c:1291 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "Relation »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:188 commands/dropcmds.c:287 commands/tablecmds.c:1248 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "Schema »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:228 commands/dropcmds.c:267 commands/tablecmds.c:272 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "Typ »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:257 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "Zugriffsmethode »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:275 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "Sortierfolge »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:282 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "Konversion »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:293 commands/statscmds.c:630 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "Statistikobjekt »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:300 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr "Textsucheparser »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:307 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "Textsuchewörterbuch »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:314 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "Textsuchevorlage »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:321 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "Textsuchekonfiguration »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:326 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "Erweiterung »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:336 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "Funktion %s(%s) existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:349 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "Prozedur %s(%s) existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:362 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "Routine %s(%s) existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:375 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "Aggregatfunktion %s(%s) existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:388 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "Operator %s existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:394 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "Sprache »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:403 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "Typumwandlung von Typ %s in Typ %s existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:412 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "Transformation für Typ %s Sprache »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:420 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "Trigger »%s« für Relation »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:429 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "Policy »%s« für Relation »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:436 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "Ereignistrigger »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:442 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "Regel »%s« für Relation »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:449 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "Fremddaten-Wrapper »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:453 commands/foreigncmds.c:1351 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "Server »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:462 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "Operatorklasse »%s« existiert nicht für Zugriffsmethode »%s«, wird übersprungen" + +#: commands/dropcmds.c:474 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "Operatorfamilie »%s« existiert nicht für Zugriffsmethode »%s«, wird übersprungen" + +#: commands/dropcmds.c:481 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "Publikation »%s« existiert nicht, wird übersprungen" + +#: commands/event_trigger.c:125 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "keine Berechtigung, um Ereignistrigger »%s« zu erzeugen" + +#: commands/event_trigger.c:127 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "Nur Superuser können Ereignistrigger anlegen." + +#: commands/event_trigger.c:136 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "unbekannter Ereignisname »%s«" + +#: commands/event_trigger.c:153 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "unbekannte Filtervariable »%s«" + +#: commands/event_trigger.c:207 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "Filterwert »%s« nicht erkannt für Filtervariable »%s«" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:213 commands/event_trigger.c:235 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "Ereignistrigger für %s werden nicht unterstützt" + +#: commands/event_trigger.c:248 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "Filtervariable »%s« mehrmals angegeben" + +#: commands/event_trigger.c:377 commands/event_trigger.c:421 +#: commands/event_trigger.c:515 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "Ereignistrigger »%s« existiert nicht" + +#: commands/event_trigger.c:483 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "keine Berechtigung, um Eigentümer des Ereignistriggers »%s« zu ändern" + +#: commands/event_trigger.c:485 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "Der Eigentümer eines Ereignistriggers muss ein Superuser sein." + +#: commands/event_trigger.c:1304 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%s kann nur in einer sql_drop-Ereignistriggerfunktion aufgerufen werden" + +#: commands/event_trigger.c:1424 commands/event_trigger.c:1445 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%s kann nur in einer table_rewrite-Ereignistriggerfunktion aufgerufen werden" + +#: commands/event_trigger.c:1862 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%s kann nur in einer Ereignistriggerfunktion aufgerufen werden" + +#: commands/explain.c:218 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "unbekannter Wert für EXPLAIN-Option »%s«: »%s«" + +#: commands/explain.c:225 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "unbekannte EXPLAIN-Option »%s«" + +#: commands/explain.c:233 +#, c-format +msgid "EXPLAIN option WAL requires ANALYZE" +msgstr "EXPLAIN-Option WAL erfordert ANALYZE" + +#: commands/explain.c:242 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "EXPLAIN-Option TIMING erfordert ANALYZE" + +#: commands/extension.c:173 commands/extension.c:3013 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "Erweiterung »%s« existiert nicht" + +#: commands/extension.c:272 commands/extension.c:281 commands/extension.c:293 +#: commands/extension.c:303 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "ungültiger Erweiterungsname: »%s«" + +#: commands/extension.c:273 +#, c-format +msgid "Extension names must not be empty." +msgstr "Erweiterungsnamen dürfen nicht leer sein." + +#: commands/extension.c:282 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "Erweiterungsnamen dürfen nicht »--« enthalten." + +#: commands/extension.c:294 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "Erweiterungsnamen dürfen nicht mit »-« anfangen oder aufhören." + +#: commands/extension.c:304 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "Erweiterungsnamen dürfen keine Verzeichnistrennzeichen enthalten." + +#: commands/extension.c:319 commands/extension.c:328 commands/extension.c:337 +#: commands/extension.c:347 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "ungültiger Erweiterungsversionsname: »%s«" + +#: commands/extension.c:320 +#, c-format +msgid "Version names must not be empty." +msgstr "Versionsnamen dürfen nicht leer sein." + +#: commands/extension.c:329 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "Versionsnamen dürfen nicht »--« enthalten." + +#: commands/extension.c:338 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "Versionsnamen dürfen nicht mit »-« anfangen oder aufhören." + +#: commands/extension.c:348 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "Versionsnamen dürfen keine Verzeichnistrennzeichen enthalten." + +#: commands/extension.c:498 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "konnte Erweiterungskontrolldatei »%s« nicht öffnen: %m" + +#: commands/extension.c:520 commands/extension.c:530 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "Parameter »%s« kann nicht in einer sekundären Erweitungskontrolldatei gesetzt werden" + +#: commands/extension.c:552 commands/extension.c:560 commands/extension.c:568 +#: utils/misc/guc.c:7092 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "Parameter »%s« erfordert einen Boole’schen Wert" + +#: commands/extension.c:577 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "»%s« ist kein gültiger Kodierungsname" + +#: commands/extension.c:591 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "Parameter »%s« muss eine Liste von Erweiterungsnamen sein" + +#: commands/extension.c:598 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "unbekannter Parameter »%s« in Datei »%s«" + +#: commands/extension.c:607 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr "Parameter »schema« kann nicht angegeben werden, wenn »relocatable« an ist" + +#: commands/extension.c:785 +#, c-format +msgid "transaction control statements are not allowed within an extension script" +msgstr "Transaktionskontrollanweisungen sind nicht in einem Erweiterungsskript erlaubt" + +#: commands/extension.c:861 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "keine Berechtigung, um Erweiterung »%s« zu erzeugen" + +#: commands/extension.c:864 +#, c-format +msgid "Must have CREATE privilege on current database to create this extension." +msgstr "CREATE-Privileg für die aktuelle Datenbank wird benötigt, um diese Erweiterung anzulegen." + +#: commands/extension.c:865 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "Nur Superuser können diese Erweiterung anlegen." + +#: commands/extension.c:869 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "keine Berechtigung, um Erweiterung »%s« zu aktualisieren" + +#: commands/extension.c:872 +#, c-format +msgid "Must have CREATE privilege on current database to update this extension." +msgstr "CREATE-Privileg für die aktuelle Datenbank wird benötigt, um diese Erweiterung zu aktualisieren." + +#: commands/extension.c:873 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "Nur Superuser können diese Erweiterung aktualisieren." + +#: commands/extension.c:1200 +#, c-format +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "Erweiterung »%s« hat keinen Aktualisierungspfad von Version »%s« auf Version »%s«" + +#: commands/extension.c:1408 commands/extension.c:3074 +#, c-format +msgid "version to install must be specified" +msgstr "die zu installierende Version muss angegeben werden" + +#: commands/extension.c:1445 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "Erweiterung »%s« hat kein Installationsskript und keinen Aktualisierungspfad für Version »%s«" + +#: commands/extension.c:1479 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "Erweiterung »%s« muss in Schema »%s« installiert werden" + +#: commands/extension.c:1639 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "zyklische Abhängigkeit zwischen Erweiterungen »%s« und »%s« entdeckt" + +#: commands/extension.c:1644 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "installiere benötigte Erweiterung »%s«" + +#: commands/extension.c:1667 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr "benötigte Erweiterung »%s« ist nicht installiert" + +#: commands/extension.c:1670 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "Verwenden Sie CREATE EXTENSION ... CASCADE, um die benötigten Erweiterungen ebenfalls zu installieren." + +#: commands/extension.c:1705 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "Erweiterung »%s« existiert bereits, wird übersprungen" + +#: commands/extension.c:1712 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "Erweiterung »%s« existiert bereits" + +#: commands/extension.c:1723 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "geschachteltes CREATE EXTENSION wird nicht unterstützt" + +#: commands/extension.c:1896 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "Erweiterung »%s« kann nicht gelöscht werden, weil sie gerade geändert wird" + +#: commands/extension.c:2457 +#, c-format +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "%s kann nur von einem SQL-Skript aufgerufen werden, das von CREATE EXTENSION ausgeführt wird" + +#: commands/extension.c:2469 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "OID %u bezieht sich nicht auf eine Tabelle" + +#: commands/extension.c:2474 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "Tabelle »%s« ist kein Mitglied der anzulegenden Erweiterung" + +#: commands/extension.c:2828 +#, c-format +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" +msgstr "kann Erweiterung »%s« nicht in Schema »%s« verschieben, weil die Erweiterung das Schema enthält" + +#: commands/extension.c:2869 commands/extension.c:2932 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "Erweiterung »%s« unterstützt SET SCHEMA nicht" + +#: commands/extension.c:2934 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "%s ist nicht im Schema der Erweiterung (»%s«)" + +#: commands/extension.c:2993 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "geschachteltes ALTER EXTENSION wird nicht unterstützt" + +#: commands/extension.c:3085 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "Version »%s« von Erweiterung »%s« ist bereits installiert" + +#: commands/extension.c:3297 +#, c-format +msgid "cannot add an object of this type to an extension" +msgstr "ein Objekt dieses Typs kann nicht zu einer Erweiterung hinzugefügt werden" + +#: commands/extension.c:3355 +#, c-format +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" +msgstr "kann Schema »%s« nicht zu Erweiterung »%s« hinzufügen, weil das Schema die Erweiterung enthält" + +#: commands/extension.c:3383 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "%s ist kein Mitglied der Erweiterung »%s«" + +#: commands/extension.c:3449 +#, c-format +msgid "file \"%s\" is too large" +msgstr "Datei »%s« ist zu groß" + +#: commands/foreigncmds.c:148 commands/foreigncmds.c:157 +#, c-format +msgid "option \"%s\" not found" +msgstr "Option »%s« nicht gefunden" + +#: commands/foreigncmds.c:167 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "Option »%s« mehrmals angegeben" + +#: commands/foreigncmds.c:221 commands/foreigncmds.c:229 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "keine Berechtigung, um Eigentümer des Fremddaten-Wrappers »%s« zu ändern" + +#: commands/foreigncmds.c:223 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "Nur Superuser können den Eigentümer eines Fremddaten-Wrappers ändern." + +#: commands/foreigncmds.c:231 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "Der Eigentümer eines Fremddaten-Wrappers muss ein Superuser sein." + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:711 foreign/foreign.c:701 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "Fremddaten-Wrapper »%s« existiert nicht" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "keine Berechtigung, um Fremddaten-Wrapper »%s« zu erzeugen" + +#: commands/foreigncmds.c:586 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "Nur Superuser können Fremddaten-Wrapper anlegen." + +#: commands/foreigncmds.c:701 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "keine Berechtigung, um Fremddaten-Wrapper »%s« zu ändern" + +#: commands/foreigncmds.c:703 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "Nur Superuser können Fremddaten-Wrapper ändern." + +#: commands/foreigncmds.c:734 +#, c-format +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" +msgstr "das Ändern des Handlers des Fremddaten-Wrappers kann das Verhalten von bestehenden Fremdtabellen verändern" + +#: commands/foreigncmds.c:749 +#, c-format +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +msgstr "durch Ändern des Validators des Fremddaten-Wrappers können die Optionen von abhängigen Objekten ungültig werden" + +#: commands/foreigncmds.c:871 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "Server »%s« existiert bereits, wird übersprungen" + +#: commands/foreigncmds.c:1135 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "Benutzerabbildung für »%s« existiert bereits für Server »%s«, wird übersprungen" + +#: commands/foreigncmds.c:1145 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "Benutzerabbildung für »%s« existiert bereits für Server »%s«" + +#: commands/foreigncmds.c:1245 commands/foreigncmds.c:1365 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«" + +#: commands/foreigncmds.c:1370 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "Benutzerabbildung für »%s« existiert nicht für Server »%s«, wird übersprungen" + +#: commands/foreigncmds.c:1498 foreign/foreign.c:389 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "Fremddaten-Wrapper »%s« hat keinen Handler" + +#: commands/foreigncmds.c:1504 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "Fremddaten-Wrapper »%s« unterstützt IMPORT FOREIGN SCHEMA nicht" + +#: commands/foreigncmds.c:1607 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "importiere Fremdtabelle »%s«" + +#: commands/functioncmds.c:108 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "SQL-Funktion kann keinen Hüllen-Rückgabetyp %s haben" + +#: commands/functioncmds.c:113 +#, c-format +msgid "return type %s is only a shell" +msgstr "Rückgabetyp %s ist nur eine Hülle" + +#: commands/functioncmds.c:143 parser/parse_type.c:354 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "Typmodifikator kann für Hüllentyp »%s« nicht angegeben werden" + +#: commands/functioncmds.c:149 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "Typ »%s« ist noch nicht definiert" + +#: commands/functioncmds.c:150 +#, c-format +msgid "Creating a shell type definition." +msgstr "Hüllentypdefinition wird erzeugt." + +#: commands/functioncmds.c:244 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "SQL-Funktion kann keinen Hüllentyp %s annehmen" + +#: commands/functioncmds.c:250 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "Aggregatfunktion kann keinen Hüllentyp %s annehmen" + +#: commands/functioncmds.c:255 +#, c-format +msgid "argument type %s is only a shell" +msgstr "Argumenttyp %s ist nur eine Hülle" + +#: commands/functioncmds.c:265 +#, c-format +msgid "type %s does not exist" +msgstr "Typ %s existiert nicht" + +#: commands/functioncmds.c:279 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "Aggregatfunktionen können keine SETOF-Argumente haben" + +#: commands/functioncmds.c:283 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "Prozeduren können keine SETOF-Argumente haben" + +#: commands/functioncmds.c:287 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "Funktionen können keine SETOF-Argumente haben" + +#: commands/functioncmds.c:307 +#, c-format +msgid "VARIADIC parameter must be the last signature parameter" +msgstr "VARIADIC-Parameter muss der letzte Signaturparameter sein" + +#: commands/functioncmds.c:337 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "VARIADIC-Parameter muss ein Array sein" + +#: commands/functioncmds.c:377 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "Parametername »%s« mehrmals angegeben" + +#: commands/functioncmds.c:395 +#, c-format +msgid "only input parameters can have default values" +msgstr "nur Eingabeparameter können Vorgabewerte haben" + +#: commands/functioncmds.c:410 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "Tabellenverweise können nicht in Parametervorgabewerten verwendet werden" + +#: commands/functioncmds.c:434 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "Eingabeparameter hinter einem mit Vorgabewert müssen auch einen Vorgabewert haben" + +#: commands/functioncmds.c:586 commands/functioncmds.c:777 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "ungültiges Attribut in Prozedurdefinition" + +#: commands/functioncmds.c:682 +#, c-format +msgid "support function %s must return type %s" +msgstr "Unterstützungsfunktion %s muss Rückgabetyp %s haben" + +#: commands/functioncmds.c:693 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "nur Superuser können eine Support-Funktion angeben" + +#: commands/functioncmds.c:826 commands/functioncmds.c:1430 +#, c-format +msgid "COST must be positive" +msgstr "COST muss positiv sein" + +#: commands/functioncmds.c:834 commands/functioncmds.c:1438 +#, c-format +msgid "ROWS must be positive" +msgstr "ROWS muss positiv sein" + +#: commands/functioncmds.c:863 +#, c-format +msgid "no function body specified" +msgstr "kein Funktionskörper angegeben" + +#: commands/functioncmds.c:868 +#, c-format +msgid "duplicate function body specified" +msgstr "doppelter Funktionskörper angegeben" + +#: commands/functioncmds.c:873 +#, c-format +msgid "inline SQL function body only valid for language SQL" +msgstr "Inline-SQL-Funktionskörper ist nur gültig für Sprache SQL" + +#: commands/functioncmds.c:915 +#, c-format +msgid "SQL function with unquoted function body cannot have polymorphic arguments" +msgstr "SQL-Funktion mit Funktionsrumpf nicht in Anführungszeichen kann keine polymorphen Argumente haben" + +#: commands/functioncmds.c:941 commands/functioncmds.c:960 +#, c-format +msgid "%s is not yet supported in unquoted SQL function body" +msgstr "%s ist in SQL-Funktionen nicht in Anführungszeichen noch nicht erlaubt" + +#: commands/functioncmds.c:988 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "nur ein AS-Element benötigt für Sprache »%s«" + +#: commands/functioncmds.c:1093 +#, c-format +msgid "no language specified" +msgstr "keine Sprache angegeben" + +#: commands/functioncmds.c:1101 commands/functioncmds.c:2103 +#: commands/proclang.c:237 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "Sprache »%s« existiert nicht" + +#: commands/functioncmds.c:1103 commands/functioncmds.c:2105 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Verwenden Sie CREATE EXTENSION, um die Sprache in die Datenbank zu laden." + +#: commands/functioncmds.c:1138 commands/functioncmds.c:1422 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "nur Superuser können eine »leakproof«-Funktion definieren" + +#: commands/functioncmds.c:1189 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "Ergebnistyp der Funktion muss %s sein wegen OUT-Parametern" + +#: commands/functioncmds.c:1202 +#, c-format +msgid "function result type must be specified" +msgstr "Ergebnistyp der Funktion muss angegeben werden" + +#: commands/functioncmds.c:1256 commands/functioncmds.c:1442 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "ROWS ist nicht anwendbar, wenn die Funktion keine Ergebnismenge zurückgibt" + +#: commands/functioncmds.c:1542 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "Quelldatentyp %s ist ein Pseudotyp" + +#: commands/functioncmds.c:1548 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "Zieldatentyp %s ist ein Pseudotyp" + +#: commands/functioncmds.c:1572 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "Typumwandlung wird ignoriert werden, weil der Quelldatentyp eine Domäne ist" + +#: commands/functioncmds.c:1577 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "Typumwandlung wird ignoriert werden, weil der Zieldatentyp eine Domäne ist" + +#: commands/functioncmds.c:1602 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "Typumwandlungsfunktion muss ein bis drei Argumente haben" + +#: commands/functioncmds.c:1606 +#, c-format +msgid "argument of cast function must match or be binary-coercible from source data type" +msgstr "Argument der Typumwandlungsfunktion muss mit Quelldatentyp übereinstimmen oder in ihn binär-umwandelbar sein" + +#: commands/functioncmds.c:1610 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "zweites Argument der Typumwandlungsfunktion muss Typ %s haben" + +#: commands/functioncmds.c:1615 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "drittes Argument der Typumwandlungsfunktion muss Typ %s haben" + +#: commands/functioncmds.c:1620 +#, c-format +msgid "return data type of cast function must match or be binary-coercible to target data type" +msgstr "Rückgabetyp der Typumwandlungsfunktion muss mit Zieldatentyp übereinstimmen oder in ihn binär-umwandelbar sein" + +#: commands/functioncmds.c:1631 +#, c-format +msgid "cast function must not be volatile" +msgstr "Typumwandlungsfunktion darf nicht VOLATILE sein" + +#: commands/functioncmds.c:1636 +#, c-format +msgid "cast function must be a normal function" +msgstr "Typumwandlungsfunktion muss eine normale Funktion sein" + +#: commands/functioncmds.c:1640 +#, c-format +msgid "cast function must not return a set" +msgstr "Typumwandlungsfunktion darf keine Ergebnismenge zurückgeben" + +#: commands/functioncmds.c:1666 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "nur Superuser können Typumwandlungen mit WITHOUT FUNCTION erzeugen" + +#: commands/functioncmds.c:1681 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "Quelldatentyp und Zieldatentyp sind nicht physikalisch kompatibel" + +#: commands/functioncmds.c:1696 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "zusammengesetzte Datentypen sind nicht binärkompatibel" + +#: commands/functioncmds.c:1702 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "Enum-Datentypen sind nicht binärkompatibel" + +#: commands/functioncmds.c:1708 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "Array-Datentypen sind nicht binärkompatibel" + +#: commands/functioncmds.c:1725 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "Domänendatentypen dürfen nicht als binärkompatibel markiert werden" + +#: commands/functioncmds.c:1735 +#, c-format +msgid "source data type and target data type are the same" +msgstr "Quelldatentyp und Zieldatentyp sind der selbe" + +#: commands/functioncmds.c:1768 +#, c-format +msgid "transform function must not be volatile" +msgstr "Transformationsfunktion darf nicht VOLATILE sein" + +#: commands/functioncmds.c:1772 +#, c-format +msgid "transform function must be a normal function" +msgstr "Transformationsfunktion muss eine normale Funktion sein" + +#: commands/functioncmds.c:1776 +#, c-format +msgid "transform function must not return a set" +msgstr "Transformationsfunktion darf keine Ergebnismenge zurückgeben" + +#: commands/functioncmds.c:1780 +#, c-format +msgid "transform function must take one argument" +msgstr "Transformationsfunktion muss ein Argument haben" + +#: commands/functioncmds.c:1784 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "erstes Argument der Transformationsfunktion muss Typ %s haben" + +#: commands/functioncmds.c:1823 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "Datentyp %s ist ein Pseudotyp" + +#: commands/functioncmds.c:1829 +#, c-format +msgid "data type %s is a domain" +msgstr "Datentyp %s ist eine Domäne" + +#: commands/functioncmds.c:1869 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "Rückgabetyp der FROM-SQL-Funktion muss %s sein" + +#: commands/functioncmds.c:1895 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "Rückgabetyp der TO-SQL-Funktion muss der zu transformierende Datentyp sein" + +#: commands/functioncmds.c:1924 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "Transformation für Typ %s Sprache »%s« existiert bereits" + +#: commands/functioncmds.c:2011 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "Transformation für Typ %s Sprache »%s« existiert nicht" + +#: commands/functioncmds.c:2035 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "Funktion %s existiert bereits in Schema »%s«" + +#: commands/functioncmds.c:2090 +#, c-format +msgid "no inline code specified" +msgstr "kein Inline-Code angegeben" + +#: commands/functioncmds.c:2136 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "Sprache »%s« unterstützt das Ausführen von Inline-Code nicht" + +#: commands/functioncmds.c:2253 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "kann nicht mehr als %d Argument an eine Prozedur übergeben" +msgstr[1] "kann nicht mehr als %d Argumente an eine Prozedur übergeben" + +#: commands/indexcmds.c:618 +#, c-format +msgid "must specify at least one column" +msgstr "mindestens eine Spalte muss angegeben werden" + +#: commands/indexcmds.c:622 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "Index kann nicht mehr als %d Spalten enthalten" + +#: commands/indexcmds.c:661 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "kann keinen Index für Fremdtabelle »%s« erzeugen" + +#: commands/indexcmds.c:692 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "kann Index für partitionierte Tabelle »%s« nicht nebenläufig erzeugen" + +#: commands/indexcmds.c:697 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "kann keinen Exclusion-Constraint für partitionierte Tabelle »%s« erzeugen" + +#: commands/indexcmds.c:707 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "kann keine Indexe für temporäre Tabellen anderer Sitzungen erzeugen" + +#: commands/indexcmds.c:745 commands/tablecmds.c:748 commands/tablespace.c:1185 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "für partitionierte Relationen kann kein Standard-Tablespace angegeben werden" + +#: commands/indexcmds.c:777 commands/tablecmds.c:783 commands/tablecmds.c:3299 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "nur geteilte Relationen können in den Tablespace »pg_global« gelegt werden" + +#: commands/indexcmds.c:810 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "ersetze Zugriffsmethode »gist« für obsolete Methode »rtree«" + +#: commands/indexcmds.c:831 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "Zugriffsmethode »%s« unterstützt keine Unique Indexe" + +#: commands/indexcmds.c:836 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "Zugriffsmethode »%s« unterstützt keine eingeschlossenen Spalten" + +#: commands/indexcmds.c:841 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "Zugriffsmethode »%s« unterstützt keine mehrspaltigen Indexe" + +#: commands/indexcmds.c:846 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "Zugriffsmethode »%s« unterstützt keine Exclusion-Constraints" + +#: commands/indexcmds.c:969 +#, c-format +msgid "cannot match partition key to an index using access method \"%s\"" +msgstr "Partitionierungsschlüssel kann nicht mit Zugriffsmethode »%s« mit einem Index gepaart werden" + +#: commands/indexcmds.c:979 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "nicht unterstützter %s-Constraint mit Partitionierungsschlüsseldefinition" + +#: commands/indexcmds.c:981 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "%s-Constraints können nicht verwendet werden, wenn Partitionierungsschlüssel Ausdrücke enthalten." + +#: commands/indexcmds.c:1020 +#, c-format +msgid "unique constraint on partitioned table must include all partitioning columns" +msgstr "Unique-Constraint für partitionierte Tabelle muss alle Partitionierungsspalten enthalten" + +#: commands/indexcmds.c:1021 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "Im %s-Constraint in Tabelle »%s« fehlt Spalte »%s«, welche Teil des Partitionierungsschlüssels ist." + +#: commands/indexcmds.c:1040 commands/indexcmds.c:1059 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "Indexerzeugung für Systemspalten wird nicht unterstützt" + +#: commands/indexcmds.c:1231 tcop/utility.c:1477 +#, c-format +msgid "cannot create unique index on partitioned table \"%s\"" +msgstr "kann keinen Unique Index für partitionierte Tabelle »%s« erzeugen" + +#: commands/indexcmds.c:1233 tcop/utility.c:1479 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "Tabelle »%s« enthält Partitionen, die Fremdtabellen sind." + +#: commands/indexcmds.c:1683 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "Funktionen im Indexprädikat müssen als IMMUTABLE markiert sein" + +#: commands/indexcmds.c:1749 parser/parse_utilcmd.c:2525 +#: parser/parse_utilcmd.c:2660 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "Spalte »%s«, die im Schlüssel verwendet wird, existiert nicht" + +#: commands/indexcmds.c:1773 parser/parse_utilcmd.c:1824 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "in eingeschlossenen Spalten werden keine Ausdrücke unterstützt" + +#: commands/indexcmds.c:1814 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "Funktionen im Indexausdruck müssen als IMMUTABLE markiert sein" + +#: commands/indexcmds.c:1829 +#, c-format +msgid "including column does not support a collation" +msgstr "inkludierte Spalte unterstützt keine Sortierfolge" + +#: commands/indexcmds.c:1833 +#, c-format +msgid "including column does not support an operator class" +msgstr "inkludierte Spalte unterstützt keine Operatorklasse" + +#: commands/indexcmds.c:1837 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "inkludierte Spalte unterstützt die Optionen ASC/DESC nicht" + +#: commands/indexcmds.c:1841 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "inkludierte Spalte unterstützt die Optionen NULLS FIRST/LAST nicht" + +#: commands/indexcmds.c:1868 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "konnte die für den Indexausdruck zu verwendende Sortierfolge nicht bestimmen" + +#: commands/indexcmds.c:1876 commands/tablecmds.c:16802 commands/typecmds.c:810 +#: parser/parse_expr.c:2680 parser/parse_type.c:566 parser/parse_utilcmd.c:3813 +#: utils/adt/misc.c:599 +#, c-format +msgid "collations are not supported by type %s" +msgstr "Sortierfolgen werden von Typ %s nicht unterstützt" + +#: commands/indexcmds.c:1914 +#, c-format +msgid "operator %s is not commutative" +msgstr "Operator %s ist nicht kommutativ" + +#: commands/indexcmds.c:1916 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "In Exclusion-Constraints können nur kommutative Operatoren verwendet werden." + +#: commands/indexcmds.c:1942 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "Operator %s ist kein Mitglied der Operatorfamilie »%s«" + +#: commands/indexcmds.c:1945 +#, c-format +msgid "The exclusion operator must be related to the index operator class for the constraint." +msgstr "Der Exklusionsoperator muss in Beziehung zur Indexoperatorklasse des Constraints stehen." + +#: commands/indexcmds.c:1980 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "Zugriffsmethode »%s« unterstützt die Optionen ASC/DESC nicht" + +#: commands/indexcmds.c:1985 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "Zugriffsmethode »%s« unterstützt die Optionen NULLS FIRST/LAST nicht" + +#: commands/indexcmds.c:2031 commands/tablecmds.c:16827 +#: commands/tablecmds.c:16833 commands/typecmds.c:2318 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "Datentyp %s hat keine Standardoperatorklasse für Zugriffsmethode »%s«" + +#: commands/indexcmds.c:2033 +#, c-format +msgid "You must specify an operator class for the index or define a default operator class for the data type." +msgstr "Sie müssen für den Index eine Operatorklasse angeben oder eine Standardoperatorklasse für den Datentyp definieren." + +#: commands/indexcmds.c:2062 commands/indexcmds.c:2070 +#: commands/opclasscmds.c:205 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "Operatorklasse »%s« existiert nicht für Zugriffsmethode »%s«" + +#: commands/indexcmds.c:2084 commands/typecmds.c:2306 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "Operatorklasse »%s« akzeptiert Datentyp %s nicht" + +#: commands/indexcmds.c:2174 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "es gibt mehrere Standardoperatorklassen für Datentyp %s" + +#: commands/indexcmds.c:2502 +#, c-format +msgid "unrecognized REINDEX option \"%s\"" +msgstr "unbekannte REINDEX-Option »%s«" + +#: commands/indexcmds.c:2726 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "Tabelle »%s« hat keine Indexe, die nebenläufig reindiziert werden können" + +#: commands/indexcmds.c:2740 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "Tabelle »%s« hat keine zu reindizierenden Indexe" + +#: commands/indexcmds.c:2780 commands/indexcmds.c:3287 +#: commands/indexcmds.c:3415 +#, c-format +msgid "cannot reindex system catalogs concurrently" +msgstr "Systemkataloge können nicht nebenläufig reindiziert werden" + +#: commands/indexcmds.c:2803 +#, c-format +msgid "can only reindex the currently open database" +msgstr "nur die aktuell geöffnete Datenbank kann reindiziert werden" + +#: commands/indexcmds.c:2891 +#, c-format +msgid "cannot reindex system catalogs concurrently, skipping all" +msgstr "Systemkataloge können nicht nebenläufig reindiziert werden, werden alle übersprungen" + +#: commands/indexcmds.c:2924 +#, c-format +msgid "cannot move system relations, skipping all" +msgstr "Systemrelationen können nicht verschoben werden, werden alle übersprungen" + +#: commands/indexcmds.c:2971 +#, c-format +msgid "while reindexing partitioned table \"%s.%s\"" +msgstr "beim Reindizieren der partitionierten Tabelle »%s.%s«" + +#: commands/indexcmds.c:2974 +#, c-format +msgid "while reindexing partitioned index \"%s.%s\"" +msgstr "beim Reindizieren des partitionierten Index »%s.%s«" + +#: commands/indexcmds.c:3167 commands/indexcmds.c:4003 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "Tabelle »%s.%s« wurde neu indiziert" + +#: commands/indexcmds.c:3319 commands/indexcmds.c:3371 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "ungültiger Index »%s.%s« kann nicht nebenläufig reindizert werden, wird übersprungen" + +#: commands/indexcmds.c:3325 +#, c-format +msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "Exclusion-Constraint-Index »%s.%s« kann nicht nebenläufig reindizert werden, wird übersprungen" + +#: commands/indexcmds.c:3480 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "diese Art Relation kann nicht nebenläufig reindiziert werden" + +#: commands/indexcmds.c:3501 +#, c-format +msgid "cannot move non-shared relation to tablespace \"%s\"" +msgstr "nicht geteilte Relation kann nicht nach Tablespace »%s« verschoben werden" + +#: commands/indexcmds.c:3984 commands/indexcmds.c:3996 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr "Index »%s.%s« wurde neu indiziert" + +#: commands/lockcmds.c:92 commands/tablecmds.c:6019 commands/trigger.c:289 +#: rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:938 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "»%s« ist keine Tabelle oder Sicht" + +#: commands/matview.c:182 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "CONCURRENTLY kann nicht verwendet werden, wenn die materialisierte Sicht nicht befüllt ist" + +#: commands/matview.c:188 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "Optionen CONCURRENTLY und WITH NO DATA können nicht zusammen verwendet werden" + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "kann materialisierte Sicht »%s« nicht nebenläufig auffrischen" + +#: commands/matview.c:247 +#, c-format +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "Erzeugen Sie einen Unique Index ohne WHERE-Klausel für eine oder mehrere Spalten der materialisierten Sicht." + +#: commands/matview.c:652 +#, c-format +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "neue Daten für materialisierte Sicht »%s« enthalten doppelte Zeilen ohne Spalten mit NULL-Werten" + +#: commands/matview.c:654 +#, c-format +msgid "Row: %s" +msgstr "Zeile: %s" + +#: commands/opclasscmds.c:124 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "Operatorfamilie »%s« existiert nicht für Zugriffsmethode »%s«" + +#: commands/opclasscmds.c:266 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "Operatorfamilie »%s« für Zugriffsmethode »%s« existiert bereits" + +#: commands/opclasscmds.c:411 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "nur Superuser können Operatorklassen erzeugen" + +#: commands/opclasscmds.c:484 commands/opclasscmds.c:901 +#: commands/opclasscmds.c:1047 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "ungültige Operatornummer %d, muss zwischen 1 und %d sein" + +#: commands/opclasscmds.c:529 commands/opclasscmds.c:951 +#: commands/opclasscmds.c:1063 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "ungültige Funktionsnummer %d, muss zwischen 1 und %d sein" + +#: commands/opclasscmds.c:558 +#, c-format +msgid "storage type specified more than once" +msgstr "Storage-Typ mehrmals angegeben" + +#: commands/opclasscmds.c:585 +#, c-format +msgid "storage type cannot be different from data type for access method \"%s\"" +msgstr "Storage-Typ kann nicht vom Datentyp der Zugriffsmethode »%s« verschieden sein" + +#: commands/opclasscmds.c:601 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "Operatorklasse »%s« für Zugriffsmethode »%s« existiert bereits" + +#: commands/opclasscmds.c:629 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "konnte Operatorklasse »%s« nicht zum Standard für Typ %s machen" + +#: commands/opclasscmds.c:632 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "Operatorklasse »%s« ist bereits der Standard." + +#: commands/opclasscmds.c:792 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "nur Superuser können Operatorfamilien erzeugen" + +#: commands/opclasscmds.c:852 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "nur Superuser können Operatorfamilien ändern" + +#: commands/opclasscmds.c:910 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "Operatorargumenttypen müssen in ALTER OPERATOR FAMILY angegeben werden" + +#: commands/opclasscmds.c:985 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "STORAGE kann in ALTER OPERATOR FAMILY nicht angegeben werden" + +#: commands/opclasscmds.c:1119 +#, c-format +msgid "one or two argument types must be specified" +msgstr "ein oder zwei Argumenttypen müssen angegeben werden" + +#: commands/opclasscmds.c:1145 +#, c-format +msgid "index operators must be binary" +msgstr "Indexoperatoren müssen binär sein" + +#: commands/opclasscmds.c:1164 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "Zugriffsmethode »%s« unterstützt keine Sortieroperatoren" + +#: commands/opclasscmds.c:1175 +#, c-format +msgid "index search operators must return boolean" +msgstr "Indexsuchoperatoren müssen Typ boolean zurückgeben" + +#: commands/opclasscmds.c:1215 +#, c-format +msgid "associated data types for operator class options parsing functions must match opclass input type" +msgstr "zugehörige Datentypen für Operatorklassenoptionsparsefunktionen müssen mit Operatorklasseneingabetyp übereinstimmen" + +#: commands/opclasscmds.c:1222 +#, c-format +msgid "left and right associated data types for operator class options parsing functions must match" +msgstr "linke und rechte zugehörige Datentypen für Operatorklassenoptionsparsefunktionen müssen übereinstimmen" + +#: commands/opclasscmds.c:1230 +#, c-format +msgid "invalid operator class options parsing function" +msgstr "ungültige Operatorklassenoptionsparsefunktion" + +#: commands/opclasscmds.c:1231 +#, c-format +msgid "Valid signature of operator class options parsing function is %s." +msgstr "Gültige Signatur einer Operatorklassenoptionsparsefunktion ist %s." + +#: commands/opclasscmds.c:1250 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "btree-Vergleichsfunktionen müssen zwei Argumente haben" + +#: commands/opclasscmds.c:1254 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "btree-Vergleichsfunktionen müssen Typ integer zurückgeben" + +#: commands/opclasscmds.c:1271 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "btree-Sortierunterstützungsfunktionen müssen Typ »internal« akzeptieren" + +#: commands/opclasscmds.c:1275 +#, c-format +msgid "btree sort support functions must return void" +msgstr "btree-Sortierunterstützungsfunktionen müssen Typ void zurückgeben" + +#: commands/opclasscmds.c:1286 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "btree-in_range-Funktionen müssen fünf Argumente haben" + +#: commands/opclasscmds.c:1290 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "btree-in_range-Funktionen müssen Typ boolean zurückgeben" + +#: commands/opclasscmds.c:1306 +#, c-format +msgid "btree equal image functions must have one argument" +msgstr "btree-equal-image-Funktionen müssen ein Argument haben" + +#: commands/opclasscmds.c:1310 +#, c-format +msgid "btree equal image functions must return boolean" +msgstr "btree-equal-image-Funktionen müssen Typ boolean zurückgeben" + +#: commands/opclasscmds.c:1323 +#, c-format +msgid "btree equal image functions must not be cross-type" +msgstr "btree-equal-image-Funktionen dürfen nicht typübergreifend sein" + +#: commands/opclasscmds.c:1333 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "Hash-Funktion 1 muss ein Argument haben" + +#: commands/opclasscmds.c:1337 +#, c-format +msgid "hash function 1 must return integer" +msgstr "Hash-Funktion 1 muss Typ integer zurückgeben" + +#: commands/opclasscmds.c:1344 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "Hash-Funktion 2 muss zwei Argumente haben" + +#: commands/opclasscmds.c:1348 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "Hash-Funktion 2 muss Typ bigint zurückgeben" + +#: commands/opclasscmds.c:1373 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "zugehörige Datentypen müssen für Indexunterstützungsfunktion angegeben werden" + +#: commands/opclasscmds.c:1398 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "Funktionsnummer %d für (%s,%s) einscheint mehrmals" + +#: commands/opclasscmds.c:1405 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "Operatornummer %d für (%s,%s) einscheint mehrmals" + +#: commands/opclasscmds.c:1451 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "Operator %d(%s,%s) existiert bereits in Operatorfamilie »%s«" + +#: commands/opclasscmds.c:1557 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "Funktion %d(%s,%s) existiert bereits in Operatorfamilie »%s«" + +#: commands/opclasscmds.c:1638 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "Operator %d(%s,%s) existiert nicht in Operatorfamilie »%s«" + +#: commands/opclasscmds.c:1678 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "Funktion %d(%s,%s) existiert nicht in Operatorfamilie »%s«" + +#: commands/opclasscmds.c:1709 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "Operatorklasse »%s« für Zugriffsmethode »%s« existiert bereits in Schema »%s«" + +#: commands/opclasscmds.c:1732 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "Operatorfamilie »%s« für Zugriffsmethode »%s« existiert bereits in Schema »%s«" + +#: commands/operatorcmds.c:111 commands/operatorcmds.c:119 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "SETOF-Typ nicht als Operatorargument erlaubt" + +#: commands/operatorcmds.c:152 commands/operatorcmds.c:479 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "Operator-Attribut »%s« unbekannt" + +#: commands/operatorcmds.c:163 +#, c-format +msgid "operator function must be specified" +msgstr "Operatorfunktion muss angegeben werden" + +#: commands/operatorcmds.c:181 +#, c-format +msgid "operator argument types must be specified" +msgstr "Operatorargumenttypen müssen angegeben werden" + +#: commands/operatorcmds.c:185 +#, c-format +msgid "operator right argument type must be specified" +msgstr "rechtes Argument des Operators muss angegeben werden" + +#: commands/operatorcmds.c:186 +#, c-format +msgid "Postfix operators are not supported." +msgstr "Postfix-Operatoren werden nicht unterstützt." + +#: commands/operatorcmds.c:290 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "Restriktionsschätzfunktion %s muss Typ %s zurückgeben" + +#: commands/operatorcmds.c:333 +#, c-format +msgid "join estimator function %s has multiple matches" +msgstr "Join-Schätzfunktion %s hat mehrere Übereinstimmungen" + +#: commands/operatorcmds.c:348 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "Join-Schätzfunktion %s muss Typ %s zurückgeben" + +#: commands/operatorcmds.c:473 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "Operator-Attribut »%s« kann nicht geändert werden" + +#: commands/policy.c:88 commands/policy.c:381 commands/policy.c:471 +#: commands/statscmds.c:150 commands/tablecmds.c:1561 commands/tablecmds.c:2150 +#: commands/tablecmds.c:3409 commands/tablecmds.c:5998 +#: commands/tablecmds.c:8860 commands/tablecmds.c:16392 +#: commands/tablecmds.c:16427 commands/trigger.c:295 commands/trigger.c:1271 +#: commands/trigger.c:1380 rewrite/rewriteDefine.c:277 +#: rewrite/rewriteDefine.c:943 rewrite/rewriteRemove.c:80 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "keine Berechtigung: »%s« ist ein Systemkatalog" + +#: commands/policy.c:171 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "angegebene Rollen außer PUBLIC werden ignoriert" + +#: commands/policy.c:172 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "Alle Rollen sind Mitglieder der Rolle PUBLIC." + +#: commands/policy.c:495 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "Rolle »%s« konnte nicht aus Policy »%s« für »%s« entfernt werden" + +#: commands/policy.c:704 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "WITH CHECK kann nicht auf SELECT oder DELETE angewendet werden" + +#: commands/policy.c:713 commands/policy.c:1018 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "für INSERT sind nur WITH-CHECK-Ausdrücke erlaubt" + +#: commands/policy.c:788 commands/policy.c:1241 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "Policy »%s« für Tabelle »%s« existiert bereits" + +#: commands/policy.c:990 commands/policy.c:1269 commands/policy.c:1340 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "Policy »%s« für Tabelle »%s« existiert nicht" + +#: commands/policy.c:1008 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "für SELECT und DELETE sind nur USING-Ausdrücke erlaubt" + +#: commands/portalcmds.c:60 commands/portalcmds.c:187 commands/portalcmds.c:238 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "ungültiger Cursorname: darf nicht leer sein" + +#: commands/portalcmds.c:72 +#, c-format +msgid "cannot create a cursor WITH HOLD within security-restricted operation" +msgstr "kann WITH-HOLD-Cursor nicht in einer sicherheitsbeschränkten Operation erzeugen" + +#: commands/portalcmds.c:195 commands/portalcmds.c:248 +#: executor/execCurrent.c:70 utils/adt/xml.c:2594 utils/adt/xml.c:2764 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "Cursor »%s« existiert nicht" + +#: commands/prepare.c:76 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "ungültiger Anweisungsname: darf nicht leer sein" + +#: commands/prepare.c:134 parser/parse_param.c:313 tcop/postgres.c:1473 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "konnte Datentyp von Parameter $%d nicht ermitteln" + +#: commands/prepare.c:152 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "Utility-Anweisungen können nicht vorbereitet werden" + +#: commands/prepare.c:256 commands/prepare.c:261 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "vorbereitete Anweisung ist kein SELECT" + +#: commands/prepare.c:328 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "falsche Anzahl Parameter für vorbereitete Anweisung »%s«" + +#: commands/prepare.c:330 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "%d Parameter erwartet aber %d erhalten." + +#: commands/prepare.c:363 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "Parameter $%d mit Typ %s kann nicht in erwarteten Typ %s umgewandelt werden" + +#: commands/prepare.c:447 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "vorbereitete Anweisung »%s« existiert bereits" + +#: commands/prepare.c:486 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "vorbereitete Anweisung »%s« existiert nicht" + +#: commands/proclang.c:68 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "nur Superuser können maßgeschneiderte prozedurale Sprachen erzeugen" + +#: commands/publicationcmds.c:107 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "ungültige Listensyntax für »publish«-Option" + +#: commands/publicationcmds.c:125 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "unbekannter »publish«-Wert: »%s«" + +#: commands/publicationcmds.c:140 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "unbekannter Publikationsparameter: »%s«" + +#: commands/publicationcmds.c:172 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "nur Superuser können eine Publikation FOR ALL TABLES erzeugen" + +#: commands/publicationcmds.c:248 +#, c-format +msgid "wal_level is insufficient to publish logical changes" +msgstr "wal_level ist nicht ausreichend, um logische Veränderungen zu publizieren" + +#: commands/publicationcmds.c:249 +#, c-format +msgid "Set wal_level to logical before creating subscriptions." +msgstr "Setzen Sie wal_level auf »logical« bevor Sie Subskriptionen erzeugen." + +#: commands/publicationcmds.c:369 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "Publikation »%s« ist als FOR ALL TABLES definiert" + +#: commands/publicationcmds.c:371 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "In einer FOR-ALL-TABLES-Publikation können keine Tabellen hinzugefügt oder entfernt werden." + +#: commands/publicationcmds.c:660 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "Relation »%s« ist nicht Teil der Publikation" + +#: commands/publicationcmds.c:703 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "keine Berechtigung, um Eigentümer der Publikation »%s« zu ändern" + +#: commands/publicationcmds.c:705 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "Der Eigentümer einer FOR-ALL-TABLES-Publikation muss ein Superuser sein." + +#: commands/schemacmds.c:105 commands/schemacmds.c:258 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "inakzeptabler Schemaname »%s«" + +#: commands/schemacmds.c:106 commands/schemacmds.c:259 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "Der Präfix »pg_« ist für Systemschemas reserviert." + +#: commands/schemacmds.c:120 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "Schema »%s« existiert bereits, wird übersprungen" + +#: commands/seclabel.c:129 +#, c-format +msgid "no security label providers have been loaded" +msgstr "es sind keine Security-Label-Provider geladen" + +#: commands/seclabel.c:133 +#, c-format +msgid "must specify provider when multiple security label providers have been loaded" +msgstr "Provider muss angegeben werden, wenn mehrere Security-Label-Provider geladen sind" + +#: commands/seclabel.c:151 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "Security-Label-Provider »%s« ist nicht geladen" + +#: commands/seclabel.c:158 +#, c-format +msgid "security labels are not supported for this type of object" +msgstr "Security-Labels werden für diese Art Objekt nicht unterstützt" + +#: commands/sequence.c:140 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "ungeloggte Sequenzen werden nicht unterstützt" + +#: commands/sequence.c:709 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "nextval: Maximalwert von Sequenz »%s« erreicht (%s)" + +#: commands/sequence.c:732 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "nextval: Minimalwert von Sequenz »%s« erreicht (%s)" + +#: commands/sequence.c:850 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "currval von Sequenz »%s« ist in dieser Sitzung noch nicht definiert" + +#: commands/sequence.c:869 commands/sequence.c:875 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "lastval ist in dieser Sitzung noch nicht definiert" + +#: commands/sequence.c:963 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "setval: Wert %s ist außerhalb des gültigen Bereichs von Sequenz »%s« (%s..%s)" + +#: commands/sequence.c:1359 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "ungültige Sequenzoption SEQUENCE NAME" + +#: commands/sequence.c:1385 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "Typ von Identitätsspalte muss smallint, integer oder bigint sein" + +#: commands/sequence.c:1386 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "Sequenztyp muss smallint, integer oder bigint sein" + +#: commands/sequence.c:1420 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "INCREMENT darf nicht null sein" + +#: commands/sequence.c:1473 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) ist außerhalb des gültigen Bereichs für Sequenzdatentyp %s" + +#: commands/sequence.c:1510 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s) ist außerhalb des gültigen Bereichs für Sequenzdatentyp %s" + +#: commands/sequence.c:1524 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "MINVALUE (%s) muss kleiner als MAXVALUE (%s) sein" + +#: commands/sequence.c:1551 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "START-Wert (%s) kann nicht kleiner als MINVALUE (%s) sein" + +#: commands/sequence.c:1563 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "START-Wert (%s) kann nicht größer als MAXVALUE (%s) sein" + +#: commands/sequence.c:1593 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "RESTART-Wert (%s) kann nicht kleiner als MINVALUE (%s) sein" + +#: commands/sequence.c:1605 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "RESTART-Wert (%s) kann nicht größer als MAXVALUE (%s) sein" + +#: commands/sequence.c:1620 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "CACHE (%s) muss größer als null sein" + +#: commands/sequence.c:1657 +#, c-format +msgid "invalid OWNED BY option" +msgstr "ungültige OWNED BY Option" + +#: commands/sequence.c:1658 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "Geben Sie OWNED BY tabelle.spalte oder OWNED BY NONE an." + +#: commands/sequence.c:1683 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr "Relation »%s«, auf die verwiesen wird, ist keine Tabelle oder Fremdtabelle" + +#: commands/sequence.c:1690 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "Sequenz muss selben Eigentümer wie die verknüpfte Tabelle haben" + +#: commands/sequence.c:1694 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "Sequenz muss im selben Schema wie die verknüpfte Tabelle sein" + +#: commands/sequence.c:1716 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "kann Eigentümer einer Identitätssequenz nicht ändern" + +#: commands/sequence.c:1717 commands/tablecmds.c:13188 +#: commands/tablecmds.c:15817 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "Sequenz »%s« ist mit Tabelle »%s« verknüpft." + +#: commands/statscmds.c:111 commands/statscmds.c:120 tcop/utility.c:1827 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "in CREATE STATISTICS ist nur eine einzelne Relation erlaubt" + +#: commands/statscmds.c:138 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "Relation »%s« ist keine Tabelle, Fremdtabelle oder materialisierte Sicht" + +#: commands/statscmds.c:188 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "Statistikobjekt »%s« existiert bereits, wird übersprungen" + +#: commands/statscmds.c:196 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "Statistikobjekt »%s« existiert bereits" + +#: commands/statscmds.c:207 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "Statistiken können nicht mehr als %d Spalten enthalten" + +#: commands/statscmds.c:246 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "Statistikerzeugung für Systemspalten wird nicht unterstützt" + +#: commands/statscmds.c:253 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "Spalte »%s« kann nicht in Statistiken verwendet werden, weil ihr Typ %s keine Standardoperatorklasse für btree hat" + +#: commands/statscmds.c:282 +#, c-format +msgid "expression cannot be used in multivariate statistics because its type %s has no default btree operator class" +msgstr "Ausdruck kann nicht in multivariaten Statistiken verwendet werden, weil sein Typ %s keine Standardoperatorklasse für btree hat" + +#: commands/statscmds.c:303 +#, c-format +msgid "when building statistics on a single expression, statistics kinds may not be specified" +msgstr "" + +#: commands/statscmds.c:332 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "unbekannte Statistikart »%s«" + +#: commands/statscmds.c:361 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "erweiterte Statistiken benötigen mindestens 2 Spalten" + +#: commands/statscmds.c:379 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "doppelter Spaltenname in Statistikdefinition" + +#: commands/statscmds.c:414 +#, c-format +msgid "duplicate expression in statistics definition" +msgstr "doppelter Ausdruck in Statistikdefinition" + +#: commands/statscmds.c:595 commands/tablecmds.c:7830 +#, c-format +msgid "statistics target %d is too low" +msgstr "Statistikziel %d ist zu niedrig" + +#: commands/statscmds.c:603 commands/tablecmds.c:7838 +#, c-format +msgid "lowering statistics target to %d" +msgstr "setze Statistikziel auf %d herab" + +#: commands/statscmds.c:626 +#, c-format +msgid "statistics object \"%s.%s\" does not exist, skipping" +msgstr "Statistikobjekt »%s.%s« existiert nicht, wird übersprungen" + +#: commands/subscriptioncmds.c:221 +#, c-format +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "unbekannter Subskriptionsparameter: »%s«" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:235 commands/subscriptioncmds.c:241 +#: commands/subscriptioncmds.c:247 commands/subscriptioncmds.c:266 +#: commands/subscriptioncmds.c:272 +#, c-format +msgid "%s and %s are mutually exclusive options" +msgstr "die Optionen %s und %s schließen einander aus" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:279 commands/subscriptioncmds.c:285 +#, c-format +msgid "subscription with %s must also set %s" +msgstr "Subskription mit %s muss auch %s setzen" + +#: commands/subscriptioncmds.c:378 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "nur Superuser können Subskriptionen erzeugen" + +#: commands/subscriptioncmds.c:471 commands/subscriptioncmds.c:568 +#: replication/logical/tablesync.c:970 replication/logical/worker.c:3143 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "konnte nicht mit dem Publikationsserver verbinden: %s" + +#: commands/subscriptioncmds.c:513 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "Replikations-Slot »%s« wurde auf dem Publikationsserver erzeugt" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:526 +#, c-format +msgid "tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "keine Tabellen wurden zur Subskription hinzugefügt; Sie müssen %s ausführen, um Tabellen zur Subskription hinzuzufügen" + +#: commands/subscriptioncmds.c:824 +#, c-format +msgid "cannot set %s for enabled subscription" +msgstr "für eine aktivierte Subskription kann nicht %s gesetzt werden" + +#: commands/subscriptioncmds.c:880 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "eine Subskription ohne Slot-Name kann nicht aktiviert werden" + +#: commands/subscriptioncmds.c:932 commands/subscriptioncmds.c:980 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" + +#: commands/subscriptioncmds.c:933 commands/subscriptioncmds.c:981 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "Verwenden Sie ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:1001 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESH ist für eine deaktivierte Subskription nicht erlaubt" + +#: commands/subscriptioncmds.c:1089 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "Subskription »%s« existiert nicht, wird übersprungen" + +#: commands/subscriptioncmds.c:1341 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "Replikations-Slot »%s« auf dem Publikationsserver wurde gelöscht" + +#: commands/subscriptioncmds.c:1350 commands/subscriptioncmds.c:1357 +#, c-format +msgid "could not drop replication slot \"%s\" on publisher: %s" +msgstr "konnte Replikations-Slot »%s« auf dem Publikationsserver nicht löschen: %s" + +#: commands/subscriptioncmds.c:1391 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "keine Berechtigung, um Eigentümer der Subskription »%s« zu ändern" + +#: commands/subscriptioncmds.c:1393 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "Der Eigentümer einer Subskription muss ein Superuser sein." + +#: commands/subscriptioncmds.c:1508 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "konnte Liste der replizierten Tabellen nicht vom Publikationsserver empfangen: %s" + +#: commands/subscriptioncmds.c:1572 +#, c-format +msgid "could not connect to publisher when attempting to drop replication slot \"%s\": %s" +msgstr "konnte beim Versuch den Replikations-Slot »%s« zu löschen nicht mit dem Publikationsserver verbinden: %s" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:1575 +#, c-format +msgid "Use %s to disassociate the subscription from the slot." +msgstr "Verwenden Sie %s, um die Subskription vom Slot zu trennen." + +#: commands/subscriptioncmds.c:1605 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "Publikationsname »%s« mehrmals angegeben" + +#: commands/subscriptioncmds.c:1649 +#, c-format +msgid "publication \"%s\" is already in subscription \"%s\"" +msgstr "Publikation »%s« ist bereits in Subskription »%s«" + +#: commands/subscriptioncmds.c:1663 +#, c-format +msgid "publication \"%s\" is not in subscription \"%s\"" +msgstr "Publikation »%s« ist nicht in Subskription »%s«" + +#: commands/subscriptioncmds.c:1674 +#, c-format +msgid "subscription must contain at least one publication" +msgstr "Subskription muss mindestens eine Publikation enthalten" + +#: commands/tablecmds.c:241 commands/tablecmds.c:283 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "Tabelle »%s« existiert nicht" + +#: commands/tablecmds.c:242 commands/tablecmds.c:284 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "Tabelle »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:244 commands/tablecmds.c:286 +msgid "Use DROP TABLE to remove a table." +msgstr "Verwenden Sie DROP TABLE, um eine Tabelle zu löschen." + +#: commands/tablecmds.c:247 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "Sequenz »%s« existiert nicht" + +#: commands/tablecmds.c:248 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "Sequenz »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:250 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "Verwenden Sie DROP SEQUENCE, um eine Sequenz zu löschen." + +#: commands/tablecmds.c:253 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "Sicht »%s« existiert nicht" + +#: commands/tablecmds.c:254 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "Sicht »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:256 +msgid "Use DROP VIEW to remove a view." +msgstr "Verwenden Sie DROP VIEW, um eine Sicht zu löschen." + +#: commands/tablecmds.c:259 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr "materialisierte Sicht »%s« existiert nicht" + +#: commands/tablecmds.c:260 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr "materialisierte Sicht »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:262 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "Verwenden Sie DROP MATERIALIZED VIEW, um eine materialisierte Sicht zu löschen." + +#: commands/tablecmds.c:265 commands/tablecmds.c:289 commands/tablecmds.c:18238 +#: parser/parse_utilcmd.c:2257 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "Index »%s« existiert nicht" + +#: commands/tablecmds.c:266 commands/tablecmds.c:290 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "Index »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:268 commands/tablecmds.c:292 +msgid "Use DROP INDEX to remove an index." +msgstr "Verwenden Sie DROP INDEX, um einen Index zu löschen." + +#: commands/tablecmds.c:273 +#, c-format +msgid "\"%s\" is not a type" +msgstr "»%s« ist kein Typ" + +#: commands/tablecmds.c:274 +msgid "Use DROP TYPE to remove a type." +msgstr "Verwenden Sie DROP TYPE, um einen Typen zu löschen." + +#: commands/tablecmds.c:277 commands/tablecmds.c:13027 +#: commands/tablecmds.c:15520 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "Fremdtabelle »%s« existiert nicht" + +#: commands/tablecmds.c:278 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "Fremdtabelle »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:280 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "Verwenden Sie DROP FOREIGN TABLE, um eine Fremdtabelle zu löschen." + +#: commands/tablecmds.c:664 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMIT kann nur mit temporären Tabellen verwendet werden" + +#: commands/tablecmds.c:695 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "kann temporäre Tabelle nicht in einer sicherheitsbeschränkten Operation erzeugen" + +#: commands/tablecmds.c:731 commands/tablecmds.c:14311 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "von der Relation »%s« würde mehrmals geerbt werden" + +#: commands/tablecmds.c:916 +#, c-format +msgid "specifying a table access method is not supported on a partitioned table" +msgstr "Angabe einer Tabellenzugriffsmethode wird für partitionierte Tabellen nicht unterstützt" + +#: commands/tablecmds.c:1012 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "»%s« ist nicht partitioniert" + +#: commands/tablecmds.c:1107 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "Partitionierung kann nicht mehr als %d Spalten verwenden" + +#: commands/tablecmds.c:1163 +#, c-format +msgid "cannot create foreign partition of partitioned table \"%s\"" +msgstr "kann keine Fremdpartition der partitionierten Tabelle »%s« erzeugen" + +#: commands/tablecmds.c:1165 +#, c-format +msgid "Table \"%s\" contains indexes that are unique." +msgstr "Tabelle »%s« enthält Unique Indexe." + +#: commands/tablecmds.c:1328 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLY unterstützt das Löschen von mehreren Objekten nicht" + +#: commands/tablecmds.c:1332 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLY unterstützt kein CASCADE" + +#: commands/tablecmds.c:1433 +#, c-format +msgid "cannot drop partitioned index \"%s\" concurrently" +msgstr "kann partitionierten Index »%s« nicht nebenläufig löschen" + +#: commands/tablecmds.c:1705 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "kann nicht nur eine partitionierte Tabelle leeren" + +#: commands/tablecmds.c:1706 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "Lassen Sie das Schlüsselwort ONLY weg oder wenden Sie TRUNCATE ONLY direkt auf die Partitionen an." + +#: commands/tablecmds.c:1779 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "Truncate-Vorgang leert ebenfalls Tabelle »%s«" + +#: commands/tablecmds.c:2138 +#, c-format +msgid "cannot truncate foreign table \"%s\"" +msgstr "kann Fremdtabelle »%s« nicht leeren" + +#: commands/tablecmds.c:2187 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "kann temporäre Tabellen anderer Sitzungen nicht leeren" + +#: commands/tablecmds.c:2449 commands/tablecmds.c:14208 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "von partitionierter Tabelle »%s« kann nicht geerbt werden" + +#: commands/tablecmds.c:2454 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "von Partition »%s« kann nicht geerbt werden" + +#: commands/tablecmds.c:2462 parser/parse_utilcmd.c:2487 +#: parser/parse_utilcmd.c:2629 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "geerbte Relation »%s« ist keine Tabelle oder Fremdtabelle" + +#: commands/tablecmds.c:2474 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "eine temporäre Relation kann nicht als Partition der permanenten Relation »%s« erzeugt werden" + +#: commands/tablecmds.c:2483 commands/tablecmds.c:14187 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "von temporärer Relation »%s« kann nicht geerbt werden" + +#: commands/tablecmds.c:2493 commands/tablecmds.c:14195 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "von temporärer Relation einer anderen Sitzung kann nicht geerbt werden" + +#: commands/tablecmds.c:2547 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "geerbte Definitionen von Spalte »%s« werden zusammengeführt" + +#: commands/tablecmds.c:2555 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "geerbte Spalte »%s« hat Typkonflikt" + +#: commands/tablecmds.c:2557 commands/tablecmds.c:2580 +#: commands/tablecmds.c:2597 commands/tablecmds.c:2853 +#: commands/tablecmds.c:2883 commands/tablecmds.c:2897 +#: parser/parse_coerce.c:2090 parser/parse_coerce.c:2110 +#: parser/parse_coerce.c:2130 parser/parse_coerce.c:2150 +#: parser/parse_coerce.c:2205 parser/parse_coerce.c:2238 +#: parser/parse_coerce.c:2316 parser/parse_coerce.c:2348 +#: parser/parse_coerce.c:2382 parser/parse_coerce.c:2402 +#: parser/parse_param.c:227 +#, c-format +msgid "%s versus %s" +msgstr "%s gegen %s" + +#: commands/tablecmds.c:2566 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "geerbte Spalte »%s« hat Sortierfolgenkonflikt" + +#: commands/tablecmds.c:2568 commands/tablecmds.c:2865 +#: commands/tablecmds.c:6498 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "»%s« gegen »%s«" + +#: commands/tablecmds.c:2578 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "geerbte Spalte »%s« hat einen Konflikt bei einem Storage-Parameter" + +#: commands/tablecmds.c:2595 commands/tablecmds.c:2895 +#, c-format +msgid "column \"%s\" has a compression method conflict" +msgstr "für Spalte »%s« besteht ein Komprimierungsmethodenkonflikt" + +#: commands/tablecmds.c:2610 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "geerbte Spalte »%s« hat einen Generierungskonflikt" + +#: commands/tablecmds.c:2704 commands/tablecmds.c:2759 +#: commands/tablecmds.c:11772 parser/parse_utilcmd.c:1301 +#: parser/parse_utilcmd.c:1344 parser/parse_utilcmd.c:1752 +#: parser/parse_utilcmd.c:1860 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "kann Verweis auf ganze Zeile der Tabelle nicht umwandeln" + +#: commands/tablecmds.c:2705 parser/parse_utilcmd.c:1302 +#, c-format +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "Generierungsausdruck für Spalte »%s« enthält einen Verweis auf die ganze Zeile der Tabelle »%s«." + +#: commands/tablecmds.c:2760 parser/parse_utilcmd.c:1345 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "Constraint »%s« enthält einen Verweis auf die ganze Zeile der Tabelle »%s«." + +#: commands/tablecmds.c:2839 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "Spalte »%s« wird mit geerbter Definition zusammengeführt" + +#: commands/tablecmds.c:2843 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "Spalte »%s« wird verschoben und mit geerbter Definition zusammengeführt" + +#: commands/tablecmds.c:2844 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "Benutzerdefinierte Spalte wurde auf die Position der geerbten Spalte verschoben." + +#: commands/tablecmds.c:2851 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "für Spalte »%s« besteht ein Typkonflikt" + +#: commands/tablecmds.c:2863 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "für Spalte »%s« besteht ein Sortierfolgenkonflikt" + +#: commands/tablecmds.c:2881 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "für Spalte »%s« besteht ein Konflikt bei einem Storage-Parameter" + +#: commands/tablecmds.c:2922 +#, c-format +msgid "child column \"%s\" specifies generation expression" +msgstr "abgeleitete Spalte »%s« gibt einen Generierungsausdruck an" + +#: commands/tablecmds.c:2924 +#, c-format +msgid "Omit the generation expression in the definition of the child table column to inherit the generation expression from the parent table." +msgstr "Lassen Sie den Generierungsausdruck in der Definition der abgeleiteten Spalte weg, um den Generierungsausdruck der Elterntabelle zu erben." + +#: commands/tablecmds.c:2928 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies default" +msgstr "Spalte »%s« erbt von einer generierten Spalte aber hat einen Vorgabewert angegeben" + +#: commands/tablecmds.c:2933 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies identity" +msgstr "Spalte »%s« erbt von einer generierten Spalte aber ist als Identitätsspalte definiert" + +#: commands/tablecmds.c:3042 +#, c-format +msgid "column \"%s\" inherits conflicting generation expressions" +msgstr "Spalte »%s« erbt widersprüchliche Generierungsausdrücke" + +#: commands/tablecmds.c:3047 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "Spalte »%s« erbt widersprüchliche Vorgabewerte" + +#: commands/tablecmds.c:3049 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "Um den Konflikt zu lösen, geben Sie einen Vorgabewert ausdrücklich an." + +#: commands/tablecmds.c:3095 +#, c-format +msgid "check constraint name \"%s\" appears multiple times but with different expressions" +msgstr "Check-Constraint-Name »%s« erscheint mehrmals, aber mit unterschiedlichen Ausdrücken" + +#: commands/tablecmds.c:3308 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "temporäre Tabellen anderer Sitzungen können nicht verschoben werden" + +#: commands/tablecmds.c:3378 +#, c-format +msgid "cannot rename column of typed table" +msgstr "Spalte einer getypten Tabelle kann nicht umbenannt werden" + +#: commands/tablecmds.c:3397 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" +msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, zusammengesetzter Typ, Index noch Fremdtabelle" + +#: commands/tablecmds.c:3491 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "vererbte Spalte »%s« muss ebenso in den abgeleiteten Tabellen umbenannt werden" + +#: commands/tablecmds.c:3523 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "Systemspalte »%s« kann nicht umbenannt werden" + +#: commands/tablecmds.c:3538 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "kann vererbte Spalte »%s« nicht umbenennen" + +#: commands/tablecmds.c:3690 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "vererbter Constraint »%s« muss ebenso in den abgeleiteten Tabellen umbenannt werden" + +#: commands/tablecmds.c:3697 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "kann vererbten Constraint »%s« nicht umbenennen" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3930 +#, c-format +msgid "cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "%s mit Relation »%s« nicht möglich, weil sie von aktiven Anfragen in dieser Sitzung verwendet wird" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3939 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "%s mit Relation »%s« nicht möglich, weil es anstehende Trigger-Ereignisse dafür gibt" + +#: commands/tablecmds.c:4403 +#, c-format +msgid "cannot alter partition \"%s\" with an incomplete detach" +msgstr "kann Partition »%s« mit einem unvollständigen Detach nicht ändern" + +#: commands/tablecmds.c:4405 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." +msgstr "Verwendet Sie ALTER TABLE ... DETACH PARTITION ... FINALIZE, um die unerledigte Detach-Operation zu vervollständigen." + +#: commands/tablecmds.c:4597 commands/tablecmds.c:4612 +#, c-format +msgid "cannot change persistence setting twice" +msgstr "Persistenzeinstellung kann nicht zweimal geändert werden" + +#: commands/tablecmds.c:5355 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "Systemrelation »%s« kann nicht neu geschrieben werden" + +#: commands/tablecmds.c:5361 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "Tabelle »%s«, die als Katalogtabelle verwendet wird, kann nicht neu geschrieben werden" + +#: commands/tablecmds.c:5371 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "kann temporäre Tabellen anderer Sitzungen nicht neu schreiben" + +#: commands/tablecmds.c:5832 +#, c-format +msgid "column \"%s\" of relation \"%s\" contains null values" +msgstr "Spalte »%s« von Relation »%s« enthält NULL-Werte" + +#: commands/tablecmds.c:5849 +#, c-format +msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" +msgstr "Check-Constraint »%s« von Relation »%s« wird von irgendeiner Zeile verletzt" + +#: commands/tablecmds.c:5868 partitioning/partbounds.c:3282 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "aktualisierter Partitions-Constraint der Standardpartition »%s« würde von irgendeiner Zeile verletzt werden" + +#: commands/tablecmds.c:5874 +#, c-format +msgid "partition constraint of relation \"%s\" is violated by some row" +msgstr "Partitions-Constraint von Relation »%s« wird von irgendeiner Zeile verletzt" + +#: commands/tablecmds.c:6022 commands/trigger.c:1265 commands/trigger.c:1371 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "»%s« ist keine Tabelle, Sicht oder Fremdtabelle" + +#: commands/tablecmds.c:6025 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht noch Index" + +#: commands/tablecmds.c:6031 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "»%s« ist weder Tabelle, materialisierte Sicht noch Index" + +#: commands/tablecmds.c:6034 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "»%s« ist weder Tabelle, materialisierte Sicht noch Fremdtabelle" + +#: commands/tablecmds.c:6037 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "»%s« ist keine Tabelle oder Fremdtabelle" + +#: commands/tablecmds.c:6040 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "»%s« ist weder Tabelle, zusammengesetzter Typ noch Fremdtabelle" + +#: commands/tablecmds.c:6043 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "»%s« ist weder Tabelle, materialisierte Sicht, Index noch Fremdtabelle" + +#: commands/tablecmds.c:6053 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "»%s« hat den falschen Typ" + +#: commands/tablecmds.c:6256 commands/tablecmds.c:6263 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "kann Typ »%s« nicht ändern, weil Spalte »%s.%s« ihn verwendet" + +#: commands/tablecmds.c:6270 +#, c-format +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "kann Fremdtabelle »%s« nicht ändern, weil Spalte »%s.%s« ihren Zeilentyp verwendet" + +#: commands/tablecmds.c:6277 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "kann Tabelle »%s« nicht ändern, weil Spalte »%s.%s« ihren Zeilentyp verwendet" + +#: commands/tablecmds.c:6333 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "kann Typ »%s« nicht ändern, weil er der Typ einer getypten Tabelle ist" + +#: commands/tablecmds.c:6335 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "Verwenden Sie ALTER ... CASCADE, um die getypten Tabellen ebenfalls zu ändern." + +#: commands/tablecmds.c:6381 +#, c-format +msgid "type %s is not a composite type" +msgstr "Typ %s ist kein zusammengesetzter Typ" + +#: commands/tablecmds.c:6408 +#, c-format +msgid "cannot add column to typed table" +msgstr "zu einer getypten Tabelle kann keine Spalte hinzugefügt werden" + +#: commands/tablecmds.c:6461 +#, c-format +msgid "cannot add column to a partition" +msgstr "zu einer Partition kann keine Spalte hinzugefügt werden" + +#: commands/tablecmds.c:6490 commands/tablecmds.c:14438 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "abgeleitete Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" + +#: commands/tablecmds.c:6496 commands/tablecmds.c:14445 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Sortierfolge für Spalte »%s«" + +#: commands/tablecmds.c:6510 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "Definition von Spalte »%s« für abgeleitete Tabelle »%s« wird zusammengeführt" + +#: commands/tablecmds.c:6553 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "eine Identitätsspalte kann nicht rekursiv zu einer Tabelle hinzugefügt werden, die abgeleitete Tabellen hat" + +#: commands/tablecmds.c:6796 +#, c-format +msgid "column must be added to child tables too" +msgstr "Spalte muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" + +#: commands/tablecmds.c:6874 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "Spalte »%s« von Relation »%s« existiert bereits, wird übersprungen" + +#: commands/tablecmds.c:6881 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "Spalte »%s« von Relation »%s« existiert bereits" + +#: commands/tablecmds.c:6947 commands/tablecmds.c:11410 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "Constraint kann nicht nur von der partitionierten Tabelle entfernt werden, wenn Partitionen existieren" + +#: commands/tablecmds.c:6948 commands/tablecmds.c:7252 +#: commands/tablecmds.c:8275 commands/tablecmds.c:11411 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "Lassen Sie das Schlüsselwort ONLY weg." + +#: commands/tablecmds.c:6985 commands/tablecmds.c:7178 +#: commands/tablecmds.c:7320 commands/tablecmds.c:7434 +#: commands/tablecmds.c:7528 commands/tablecmds.c:7587 +#: commands/tablecmds.c:7705 commands/tablecmds.c:7871 +#: commands/tablecmds.c:7941 commands/tablecmds.c:8097 +#: commands/tablecmds.c:11565 commands/tablecmds.c:13050 +#: commands/tablecmds.c:15611 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "Systemspalte »%s« kann nicht geändert werden" + +#: commands/tablecmds.c:6991 commands/tablecmds.c:7326 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "Spalte »%s« von Relation »%s« ist eine Identitätsspalte" + +#: commands/tablecmds.c:7027 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "Spalte »%s« ist in einem Primärschlüssel" + +#: commands/tablecmds.c:7049 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "Spalte »%s« ist in Elterntabelle als NOT NULL markiert" + +#: commands/tablecmds.c:7249 commands/tablecmds.c:8758 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "Constraint muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" + +#: commands/tablecmds.c:7250 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "Spalte »%s« von Relation »%s« ist nicht bereits NOT NULL." + +#: commands/tablecmds.c:7328 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "Verwenden Sie stattdessen ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." + +#: commands/tablecmds.c:7333 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "Spalte »%s« von Relation »%s« ist eine generierte Spalte" + +#: commands/tablecmds.c:7336 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." +msgstr "Verwenden Sie stattdessen ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION." + +#: commands/tablecmds.c:7445 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "Spalte »%s« von Relation »%s« muss als NOT NULL deklariert werden, bevor Sie Identitätsspalte werden kann" + +#: commands/tablecmds.c:7451 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "Spalte »%s« von Relation »%s« ist bereits eine Identitätsspalte" + +#: commands/tablecmds.c:7457 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "Spalte »%s« von Relation »%s« hat bereits einen Vorgabewert" + +#: commands/tablecmds.c:7534 commands/tablecmds.c:7595 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte" + +#: commands/tablecmds.c:7600 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte, wird übersprungen" + +#: commands/tablecmds.c:7653 +#, c-format +msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" +msgstr "ALTER TABLE / DROP EXPRESSION muss auch auf abgeleitete Tabellen angewendet werden" + +#: commands/tablecmds.c:7675 +#, c-format +msgid "cannot drop generation expression from inherited column" +msgstr "Generierungsausdruck von vererbter Spalte kann nicht gelöscht werden" + +#: commands/tablecmds.c:7713 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column" +msgstr "Spalte »%s« von Relation »%s« ist keine gespeicherte generierte Spalte" + +#: commands/tablecmds.c:7718 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column, skipping" +msgstr "Spalte »%s« von Relation »%s« ist keine gespeicherte generierte Spalte, wird übersprungen" + +#: commands/tablecmds.c:7818 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "auf eine Nicht-Index-Spalte kann nicht per Nummer verwiesen werden" + +#: commands/tablecmds.c:7861 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "Spalte Nummer %d von Relation »%s« existiert nicht" + +#: commands/tablecmds.c:7880 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "Statistiken von eingeschlossener Spalte »%s« von Index »%s« können nicht geändert werden" + +#: commands/tablecmds.c:7885 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "kann Statistiken von Spalte »%s« von Index »%s«, welche kein Ausdruck ist, nicht ändern" + +#: commands/tablecmds.c:7887 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Ändern Sie stattdessen die Statistiken für die Tabellenspalte." + +#: commands/tablecmds.c:8077 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "ungültiger Storage-Typ »%s«" + +#: commands/tablecmds.c:8109 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "Spaltendatentyp %s kann nur Storage-Typ PLAIN" + +#: commands/tablecmds.c:8154 +#, c-format +msgid "cannot drop column from typed table" +msgstr "aus einer getypten Tabelle können keine Spalten gelöscht werden" + +#: commands/tablecmds.c:8213 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "Spalte »%s« von Relation »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:8226 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "Systemspalte »%s« kann nicht gelöscht werden" + +#: commands/tablecmds.c:8236 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "geerbte Spalte »%s« kann nicht gelöscht werden" + +#: commands/tablecmds.c:8249 +#, c-format +msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "Spalte »%s« kann nicht gelöscht werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" + +#: commands/tablecmds.c:8274 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "Spalte kann nicht nur aus der partitionierten Tabelle gelöscht werden, wenn Partitionen existieren" + +#: commands/tablecmds.c:8478 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX wird für partitionierte Tabellen nicht unterstützt" + +#: commands/tablecmds.c:8503 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX benennt Index »%s« um in »%s«" + +#: commands/tablecmds.c:8838 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "ONLY nicht möglich für Fremdschlüssel für partitionierte Tabelle »%s« verweisend auf Relation »%s«" + +#: commands/tablecmds.c:8844 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "Hinzufügen von Fremdschlüssel mit NOT VALID nicht möglich für partitionierte Tabelle »%s« verweisend auf Relation »%s«" + +#: commands/tablecmds.c:8847 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Dieses Feature wird für partitionierte Tabellen noch nicht unterstützt." + +#: commands/tablecmds.c:8854 commands/tablecmds.c:9259 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "Relation »%s«, auf die verwiesen wird, ist keine Tabelle" + +#: commands/tablecmds.c:8877 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "Constraints für permanente Tabellen dürfen nur auf permanente Tabellen verweisen" + +#: commands/tablecmds.c:8884 +#, c-format +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" +msgstr "Constraints für ungeloggte Tabellen dürfen nur auf permanente oder ungeloggte Tabellen verweisen" + +#: commands/tablecmds.c:8890 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "Constraints für temporäre Tabellen dürfen nur auf temporäre Tabellen verweisen" + +#: commands/tablecmds.c:8894 +#, c-format +msgid "constraints on temporary tables must involve temporary tables of this session" +msgstr "Constraints für temporäre Tabellen müssen temporäre Tabellen dieser Sitzung beinhalten" + +#: commands/tablecmds.c:8960 commands/tablecmds.c:8966 +#, c-format +msgid "invalid %s action for foreign key constraint containing generated column" +msgstr "ungültige %s-Aktion für Fremdschlüssel-Constraint, der eine generierte Spalte enthält" + +#: commands/tablecmds.c:8982 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "Anzahl der Quell- und Zielspalten im Fremdschlüssel stimmt nicht überein" + +#: commands/tablecmds.c:9089 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "Fremdschlüssel-Constraint »%s« kann nicht implementiert werden" + +#: commands/tablecmds.c:9091 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "Schlüsselspalten »%s« und »%s« haben inkompatible Typen: %s und %s." + +#: commands/tablecmds.c:9454 commands/tablecmds.c:9847 +#: parser/parse_utilcmd.c:796 parser/parse_utilcmd.c:925 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "Fremdschlüssel-Constraints auf Fremdtabellen werden nicht unterstützt" + +#: commands/tablecmds.c:10214 commands/tablecmds.c:10492 +#: commands/tablecmds.c:11367 commands/tablecmds.c:11442 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "Constraint »%s« von Relation »%s« existiert nicht" + +#: commands/tablecmds.c:10221 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "Constraint »%s« von Relation »%s« ist kein Fremdschlüssel-Constraint" + +#: commands/tablecmds.c:10259 +#, c-format +msgid "cannot alter constraint \"%s\" on relation \"%s\"" +msgstr "Constraint »%s« von Relation »%s« kann nicht geändert werden" + +#: commands/tablecmds.c:10262 +#, c-format +msgid "Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\"." +msgstr "Constraint »%s« ist von Constraint »%s« von Relation »%s« abgeleitet." + +#: commands/tablecmds.c:10264 +#, c-format +msgid "You may alter the constraint it derives from, instead." +msgstr "Sie können stattdessen den Constraint, von dem er abgeleitet ist, ändern." + +#: commands/tablecmds.c:10500 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "Constraint »%s« von Relation »%s« ist kein Fremdschlüssel- oder Check-Constraint" + +#: commands/tablecmds.c:10578 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "Constraint muss ebenso in den abgeleiteten Tabellen validiert werden" + +#: commands/tablecmds.c:10662 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "Spalte »%s«, die im Fremdschlüssel verwendet wird, existiert nicht" + +#: commands/tablecmds.c:10667 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "Fremdschlüssel kann nicht mehr als %d Schlüssel haben" + +#: commands/tablecmds.c:10732 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "aufschiebbarer Primärschlüssel kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" + +#: commands/tablecmds.c:10749 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Primärschlüssel" + +#: commands/tablecmds.c:10814 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "die Liste der Spalten, auf die ein Fremdschlüssel verweist, darf keine doppelten Einträge enthalten" + +#: commands/tablecmds.c:10908 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "aufschiebbarer Unique-Constraint kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" + +#: commands/tablecmds.c:10913 +#, c-format +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Unique-Constraint, der auf die angegebenen Schlüssel passt" + +#: commands/tablecmds.c:11323 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "geerbter Constraint »%s« von Relation »%s« kann nicht gelöscht werden" + +#: commands/tablecmds.c:11373 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "Constraint »%s« von Relation »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:11549 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "Spaltentyp einer getypten Tabelle kann nicht geändert werden" + +#: commands/tablecmds.c:11576 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "kann vererbte Spalte »%s« nicht ändern" + +#: commands/tablecmds.c:11585 +#, c-format +msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "Spalte »%s« kann nicht geändert werden, weil sie Teil des Partitionierungsschlüssels von Relation »%s« ist" + +#: commands/tablecmds.c:11635 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "Ergebnis der USING-Klausel für Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" + +#: commands/tablecmds.c:11638 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." + +#: commands/tablecmds.c:11642 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:11645 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "Sie müssen möglicherweise »USING %s::%s« angeben." + +#: commands/tablecmds.c:11745 +#, c-format +msgid "cannot alter inherited column \"%s\" of relation \"%s\"" +msgstr "geerbte Spalte »%s« von Relation »%s« kann nicht geändert werden" + +#: commands/tablecmds.c:11773 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "USING-Ausdruck enthält einen Verweis auf die ganze Zeile der Tabelle." + +#: commands/tablecmds.c:11784 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "Typ der vererbten Spalte »%s« muss ebenso in den abgeleiteten Tabellen geändert werden" + +#: commands/tablecmds.c:11909 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "Typ der Spalte »%s« kann nicht zweimal geändert werden" + +#: commands/tablecmds.c:11947 +#, c-format +msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" +msgstr "Generierungsausdruck der Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" + +#: commands/tablecmds.c:11952 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "Vorgabewert der Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" + +#: commands/tablecmds.c:12030 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "Typ einer Spalte, die von einer generierten Spalte verwendet wird, kann nicht geändert werden" + +#: commands/tablecmds.c:12031 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "Spalte »%s« wird von generierter Spalte »%s« verwendet." + +#: commands/tablecmds.c:12052 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "Typ einer Spalte, die von einer Sicht oder Regel verwendet wird, kann nicht geändert werden" + +#: commands/tablecmds.c:12053 commands/tablecmds.c:12072 +#: commands/tablecmds.c:12090 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%s hängt von Spalte »%s« ab" + +#: commands/tablecmds.c:12071 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "Typ einer Spalte, die in einer Trigger-Definition verwendet wird, kann nicht geändert werden" + +#: commands/tablecmds.c:12089 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "Typ einer Spalte, die in einer Policy-Definition verwendet wird, kann nicht geändert werden" + +#: commands/tablecmds.c:13158 commands/tablecmds.c:13170 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "kann Eigentümer des Index »%s« nicht ändern" + +#: commands/tablecmds.c:13160 commands/tablecmds.c:13172 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "Ändern Sie stattdessen den Eigentümer der Tabelle des Index." + +#: commands/tablecmds.c:13186 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "kann Eigentümer der Sequenz »%s« nicht ändern" + +#: commands/tablecmds.c:13200 commands/tablecmds.c:16503 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "Verwenden Sie stattdessen ALTER TYPE." + +#: commands/tablecmds.c:13209 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "»%s« ist keine Tabelle, Sicht, Sequenz oder Fremdtabelle" + +#: commands/tablecmds.c:13548 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "mehrere SET TABLESPACE Unterbefehle sind ungültig" + +#: commands/tablecmds.c:13625 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, Index noch TOAST-Tabelle" + +#: commands/tablecmds.c:13658 commands/view.c:494 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "WITH CHECK OPTION wird nur für automatisch aktualisierbare Sichten unterstützt" + +#: commands/tablecmds.c:13910 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "nur Tabellen, Indexe und materialisierte Sichten existieren in Tablespaces" + +#: commands/tablecmds.c:13922 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "Relationen können nicht in den oder aus dem Tablespace »pg_global« verschoben werden" + +#: commands/tablecmds.c:14014 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "Abbruch weil Sperre für Relation »%s.%s« nicht verfügbar ist" + +#: commands/tablecmds.c:14030 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "keine passenden Relationen in Tablespace »%s« gefunden" + +#: commands/tablecmds.c:14146 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "Vererbung einer getypten Tabelle kann nicht geändert werden" + +#: commands/tablecmds.c:14151 commands/tablecmds.c:14707 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "Vererbung einer Partition kann nicht geändert werden" + +#: commands/tablecmds.c:14156 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "Vererbung einer partitionierten Tabelle kann nicht geändert werden" + +#: commands/tablecmds.c:14202 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "an temporäre Relation einer anderen Sitzung kann nicht vererbt werden" + +#: commands/tablecmds.c:14215 +#, c-format +msgid "cannot inherit from a partition" +msgstr "von einer Partition kann nicht geerbt werden" + +#: commands/tablecmds.c:14237 commands/tablecmds.c:17147 +#, c-format +msgid "circular inheritance not allowed" +msgstr "zirkuläre Vererbung ist nicht erlaubt" + +#: commands/tablecmds.c:14238 commands/tablecmds.c:17148 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "»%s« ist schon von »%s« abgeleitet." + +#: commands/tablecmds.c:14251 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "Trigger »%s« verhindert, dass Tabelle »%s« ein Vererbungskind werden kann" + +#: commands/tablecmds.c:14253 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." +msgstr "ROW-Trigger mit Übergangstabellen werden in Vererbungshierarchien nicht unterstützt." + +#: commands/tablecmds.c:14456 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "Spalte »%s« in abgeleiteter Tabelle muss als NOT NULL markiert sein" + +#: commands/tablecmds.c:14465 +#, c-format +msgid "column \"%s\" in child table must be a generated column" +msgstr "Spalte »%s« in abgeleiteter Tabelle muss eine generierte Spalte sein" + +#: commands/tablecmds.c:14515 +#, c-format +msgid "column \"%s\" in child table has a conflicting generation expression" +msgstr "Spalte »%s« in abgeleiteter Tabelle hat einen widersprüchlichen Generierungsausdruck" + +#: commands/tablecmds.c:14543 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "Spalte »%s« fehlt in abgeleiteter Tabelle" + +#: commands/tablecmds.c:14631 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Definition für Check-Constraint »%s«" + +#: commands/tablecmds.c:14639 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" +msgstr "Constraint »%s« kollidiert mit nicht vererbtem Constraint für abgeleitete Tabelle »%s«" + +#: commands/tablecmds.c:14650 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "Constraint »%s« kollidiert mit NOT-VALID-Constraint für abgeleitete Tabelle »%s«" + +#: commands/tablecmds.c:14685 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "Constraint »%s« fehlt in abgeleiteter Tabelle" + +#: commands/tablecmds.c:14773 +#, fuzzy, c-format +#| msgid "Unlogged partitioned table \"%s.%s\"" +msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" +msgstr "Ungeloggte partitionierte Tabelle »%s.%s«" + +#: commands/tablecmds.c:14777 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the detach operation." +msgstr "Verwenden Sie ALTER TABLE ... DETACH PARTITION ... FINALIZE, um die Detach-Operation zu vervollständigen." + +#: commands/tablecmds.c:14802 commands/tablecmds.c:14850 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "Relation »%s« ist keine Partition von Relation »%s«" + +#: commands/tablecmds.c:14856 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "Relation »%s« ist keine Basisrelation von Relation »%s«" + +#: commands/tablecmds.c:15084 +#, c-format +msgid "typed tables cannot inherit" +msgstr "getypte Tabellen können nicht erben" + +#: commands/tablecmds.c:15114 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "Spalte »%s« fehlt in Tabelle" + +#: commands/tablecmds.c:15125 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "Tabelle hat Spalte »%s«, aber Typ benötigt »%s«" + +#: commands/tablecmds.c:15134 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" + +#: commands/tablecmds.c:15148 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "Tabelle hat zusätzliche Spalte »%s«" + +#: commands/tablecmds.c:15200 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "»%s« ist keine getypte Tabelle" + +#: commands/tablecmds.c:15382 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "nicht eindeutiger Index »%s« kann nicht als Replik-Identität verwendet werden" + +#: commands/tablecmds.c:15388 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil er nicht IMMEDIATE ist" + +#: commands/tablecmds.c:15394 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "Ausdrucksindex »%s« kann nicht als Replik-Identität verwendet werden" + +#: commands/tablecmds.c:15400 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "partieller Index »%s« kann nicht als Replik-Identität verwendet werden" + +#: commands/tablecmds.c:15406 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "ungültiger Index »%s« kann nicht als Replik-Identität verwendet werden" + +#: commands/tablecmds.c:15423 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte %d eine Systemspalte ist" + +#: commands/tablecmds.c:15430 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte »%s« NULL-Werte akzeptiert" + +#: commands/tablecmds.c:15677 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "kann den geloggten Status der Tabelle »%s« nicht ändern, weil sie temporär ist" + +#: commands/tablecmds.c:15701 +#, c-format +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "kann Tabelle »%s« nicht in ungeloggt ändern, weil sie Teil einer Publikation ist" + +#: commands/tablecmds.c:15703 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "Ungeloggte Relationen können nicht repliziert werden." + +#: commands/tablecmds.c:15748 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "konnte Tabelle »%s« nicht in geloggt ändern, weil sie auf die ungeloggte Tabelle »%s« verweist" + +#: commands/tablecmds.c:15758 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "konnte Tabelle »%s« nicht in ungeloggt ändern, weil sie auf die geloggte Tabelle »%s« verweist" + +#: commands/tablecmds.c:15816 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "einer Tabelle zugeordnete Sequenz kann nicht in ein anderes Schema verschoben werden" + +#: commands/tablecmds.c:15923 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "Relation »%s« existiert bereits in Schema »%s«" + +#: commands/tablecmds.c:16486 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "»%s« ist kein zusammengesetzter Typ" + +#: commands/tablecmds.c:16518 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, Sequenz noch Fremdtabelle" + +#: commands/tablecmds.c:16553 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "unbekannte Partitionierungsstrategie »%s«" + +#: commands/tablecmds.c:16561 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "Partitionierungsstrategie »list« kann nicht mit mehr als einer Spalte verwendet werden" + +#: commands/tablecmds.c:16627 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "Spalte »%s«, die im Partitionierungsschlüssel verwendet wird, existiert nicht" + +#: commands/tablecmds.c:16635 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "Systemspalte »%s« kann nicht im Partitionierungsschlüssel verwendet werden" + +#: commands/tablecmds.c:16646 commands/tablecmds.c:16760 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "generierte Spalte kann nicht im Partitionierungsschlüssel verwendet werden" + +#: commands/tablecmds.c:16647 commands/tablecmds.c:16761 commands/trigger.c:635 +#: rewrite/rewriteHandler.c:884 rewrite/rewriteHandler.c:919 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "Spalte »%s« ist eine generierte Spalte." + +#: commands/tablecmds.c:16723 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "Funktionen im Partitionierungsschlüsselausdruck müssen als IMMUTABLE markiert sein" + +#: commands/tablecmds.c:16743 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "Partitionierungsschlüsselausdruck kann nicht auf Systemspalten verweisen" + +#: commands/tablecmds.c:16773 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "Partitionierungsschlüssel kann kein konstanter Ausdruck sein" + +#: commands/tablecmds.c:16794 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "konnte die für den Partitionierungsausdruck zu verwendende Sortierfolge nicht bestimmen" + +#: commands/tablecmds.c:16829 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "Sie müssen eine hash-Operatorklasse angeben oder eine hash-Standardoperatorklasse für den Datentyp definieren." + +#: commands/tablecmds.c:16835 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "Sie müssen eine btree-Operatorklasse angeben oder eine btree-Standardoperatorklasse für den Datentyp definieren." + +#: commands/tablecmds.c:17087 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "»%s« ist bereits eine Partition" + +#: commands/tablecmds.c:17093 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "eine getypte Tabelle kann nicht als Partition angefügt werden" + +#: commands/tablecmds.c:17109 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "ein Vererbungskind kann nicht als Partition angefügt werden" + +#: commands/tablecmds.c:17123 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "eine Tabelle mit abgeleiteten Tabellen kann nicht als Partition angefügt werden" + +#: commands/tablecmds.c:17157 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "eine temporäre Relation kann nicht als Partition an permanente Relation »%s« angefügt werden" + +#: commands/tablecmds.c:17165 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "eine permanente Relation kann nicht als Partition an temporäre Relation »%s« angefügt werden" + +#: commands/tablecmds.c:17173 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "kann nicht als Partition an temporäre Relation einer anderen Sitzung anfügen" + +#: commands/tablecmds.c:17180 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "temporäre Relation einer anderen Sitzung kann nicht als Partition angefügt werden" + +#: commands/tablecmds.c:17200 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "Tabelle »%s« enthält Spalte »%s«, die nicht in der Elterntabelle »%s« gefunden wurde" + +#: commands/tablecmds.c:17203 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "Die neue Partition darf nur Spalten enthalten, die auch die Elterntabelle hat." + +#: commands/tablecmds.c:17215 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "Trigger »%s« verhindert, dass Tabelle »%s« eine Partition werden kann" + +#: commands/tablecmds.c:17217 commands/trigger.c:441 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "ROW-Trigger mit Übergangstabellen werden für Partitionen nicht unterstützt" + +#: commands/tablecmds.c:17380 +#, c-format +msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" +msgstr "kann Fremdtabelle »%s« nicht als Partition an partitionierte Tabelle »%s« anfügen" + +#: commands/tablecmds.c:17383 +#, c-format +msgid "Partitioned table \"%s\" contains unique indexes." +msgstr "Partitionierte Tabelle »%s« enthält Unique-Indexe." + +#: commands/tablecmds.c:17703 +#, fuzzy, c-format +#| msgid "a hash-partitioned table may not have a default partition" +msgid "cannot detach partitions concurrently when a default partition exists" +msgstr "eine hashpartitionierte Tabelle kann keine Standardpartition haben" + +#: commands/tablecmds.c:17812 +#, c-format +msgid "partitioned table \"%s\" was removed concurrently" +msgstr "partitionierte Tabelle »%s« wurde nebenläufig entfernt" + +#: commands/tablecmds.c:17818 +#, c-format +msgid "partition \"%s\" was removed concurrently" +msgstr "Partition »%s« wurde nebenläufig entfernt" + +#: commands/tablecmds.c:18272 commands/tablecmds.c:18292 +#: commands/tablecmds.c:18312 commands/tablecmds.c:18331 +#: commands/tablecmds.c:18373 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "kann Index »%s« nicht als Partition an Index »%s« anfügen" + +#: commands/tablecmds.c:18275 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "Index »%s« ist bereits an einen anderen Index angefügt." + +#: commands/tablecmds.c:18295 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "Index »%s« ist kein Index irgendeiner Partition von Tabelle »%s«." + +#: commands/tablecmds.c:18315 +#, c-format +msgid "The index definitions do not match." +msgstr "Die Indexdefinitionen stimmen nicht überein." + +#: commands/tablecmds.c:18334 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "Der Index »%s« gehört zu einem Constraint in Tabelle »%s«, aber kein Constraint existiert für Index »%s«." + +#: commands/tablecmds.c:18376 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "Ein anderer Index ist bereits für Partition »%s« angefügt." + +#: commands/tablecmds.c:18606 +#, c-format +msgid "column data type %s does not support compression" +msgstr "Spaltendatentyp %s unterstützt keine Komprimierung" + +#: commands/tablecmds.c:18613 +#, c-format +msgid "invalid compression method \"%s\"" +msgstr "ungültige Komprimierungsmethode »%s«" + +#: commands/tablespace.c:162 commands/tablespace.c:179 +#: commands/tablespace.c:190 commands/tablespace.c:198 +#: commands/tablespace.c:650 replication/slot.c:1409 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" + +#: commands/tablespace.c:209 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "konnte »stat« für Verzeichnis »%s« nicht ausführen: %m" + +#: commands/tablespace.c:218 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "»%s« existiert, ist aber kein Verzeichnis" + +#: commands/tablespace.c:249 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "keine Berechtigung, um Tablespace »%s« zu erzeugen" + +#: commands/tablespace.c:251 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "Nur Superuser können Tablespaces anlegen." + +#: commands/tablespace.c:267 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "Tablespace-Pfad darf keine Apostrophe enthalten" + +#: commands/tablespace.c:277 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "Tablespace-Pfad muss ein absoluter Pfad sein" + +#: commands/tablespace.c:289 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "Tablespace-Pfad »%s« ist zu lang" + +#: commands/tablespace.c:296 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "Tablespace-Pfad sollte nicht innerhalb des Datenverzeichnisses sein" + +#: commands/tablespace.c:305 commands/tablespace.c:977 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "inakzeptabler Tablespace-Name »%s«" + +#: commands/tablespace.c:307 commands/tablespace.c:978 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "Der Präfix »pg_« ist für System-Tablespaces reserviert." + +#: commands/tablespace.c:326 commands/tablespace.c:999 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "Tablespace »%s« existiert bereits" + +#: commands/tablespace.c:444 commands/tablespace.c:960 +#: commands/tablespace.c:1049 commands/tablespace.c:1118 +#: commands/tablespace.c:1264 commands/tablespace.c:1467 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "Tablespace »%s« existiert nicht" + +#: commands/tablespace.c:450 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "Tablespace »%s« existiert nicht, wird übersprungen" + +#: commands/tablespace.c:478 +#, c-format +msgid "tablespace \"%s\" cannot be dropped because some objects depend on it" +msgstr "kann Tablespace »%s« nicht löschen, weil andere Objekte davon abhängen" + +#: commands/tablespace.c:537 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "Tablespace »%s« ist nicht leer" + +#: commands/tablespace.c:609 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "Verzeichnis »%s« existiert nicht" + +#: commands/tablespace.c:610 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "Erzeugen Sie dieses Verzeichnis für den Tablespace bevor Sie den Server neu starten." + +#: commands/tablespace.c:615 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "konnte Zugriffsrechte für Verzeichnis »%s« nicht setzen: %m" + +#: commands/tablespace.c:645 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "Verzeichnis »%s« ist bereits als Tablespace in Verwendung" + +#: commands/tablespace.c:769 commands/tablespace.c:782 +#: commands/tablespace.c:818 commands/tablespace.c:910 storage/file/fd.c:3161 +#: storage/file/fd.c:3557 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht löschen: %m" + +#: commands/tablespace.c:831 commands/tablespace.c:919 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht löschen: %m" + +#: commands/tablespace.c:841 commands/tablespace.c:928 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "»%s« ist kein Verzeichnis oder symbolische Verknüpfung" + +#: commands/tablespace.c:1123 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "Tablespace »%s« existiert nicht." + +#: commands/tablespace.c:1566 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "Verzeichnisse für Tablespace %u konnten nicht entfernt werden" + +#: commands/tablespace.c:1568 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "Sie können die Verzeichnisse falls nötig manuell entfernen." + +#: commands/trigger.c:198 commands/trigger.c:209 +#, c-format +msgid "\"%s\" is a table" +msgstr "»%s« ist eine Tabelle" + +#: commands/trigger.c:200 commands/trigger.c:211 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "Tabellen können keine INSTEAD OF-Trigger haben." + +#: commands/trigger.c:232 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "»%s« ist eine partitionierte Tabelle" + +#: commands/trigger.c:234 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Trigger für partitionierte Tabellen können keine Übergangstabellen haben." + +#: commands/trigger.c:246 commands/trigger.c:253 commands/trigger.c:423 +#, c-format +msgid "\"%s\" is a view" +msgstr "»%s« ist eine Sicht" + +#: commands/trigger.c:248 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "Sichten können keine BEFORE- oder AFTER-Trigger auf Zeilenebene haben." + +#: commands/trigger.c:255 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "Sichten können keine TRUNCATE-Trigger haben." + +#: commands/trigger.c:263 commands/trigger.c:270 commands/trigger.c:282 +#: commands/trigger.c:416 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "»%s« ist eine Fremdtabelle" + +#: commands/trigger.c:265 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "Fremdtabellen können keine INSTEAD OF-Trigger haben." + +#: commands/trigger.c:272 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "Fremdtabellen können keine TRUNCATE-Trigger haben." + +#: commands/trigger.c:284 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "Fremdtabellen können keine Constraint-Trigger haben." + +#: commands/trigger.c:359 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "TRUNCATE FOR EACH ROW-Trigger werden nicht unterstützt" + +#: commands/trigger.c:367 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "INSTEAD OF-Trigger müssen FOR EACH ROW sein" + +#: commands/trigger.c:371 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "INSTEAD OF-Trigger können keine WHEN-Bedingungen haben" + +#: commands/trigger.c:375 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "INSTEAD OF-Trigger können keine Spaltenlisten haben" + +#: commands/trigger.c:404 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "Benennung von ROW-Variablen in der REFERENCING-Klausel wird nicht unterstützt" + +#: commands/trigger.c:405 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "Verwenden Sie OLD TABLE und NEW TABLE, um Übergangstabellen zu benennen." + +#: commands/trigger.c:418 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Trigger für Fremdtabellen können keine Übergangstabellen haben." + +#: commands/trigger.c:425 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Trigger für Sichten können keine Übergangstabellen haben." + +#: commands/trigger.c:445 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "ROW-Trigger mit Übergangstabellen werden für Vererbungskinder nicht unterstützt" + +#: commands/trigger.c:451 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "Übergangstabellenname kann nur für einen AFTER-Trigger angegeben werden" + +#: commands/trigger.c:456 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "TRUNCATE-Trigger mit Übergangstabellen werden nicht unterstützt" + +#: commands/trigger.c:473 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "Übergangstabellen können nicht für Trigger mit mehr als einem Ereignis angegeben werden" + +#: commands/trigger.c:484 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "Übergangstabellen können nicht für Trigger mit Spaltenlisten angegeben werden" + +#: commands/trigger.c:501 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "NEW TABLE kann nur für INSERT- oder UPDATE-Trigger angegeben werden" + +#: commands/trigger.c:506 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE kann nicht mehrmals angegeben werden" + +#: commands/trigger.c:516 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE kann nur für DELETE- oder UPDATE-Trigger angegeben werden" + +#: commands/trigger.c:521 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE kann nicht mehrmals angegeben werden" + +#: commands/trigger.c:531 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "Name für OLD TABLE und NEW TABLE kann nicht gleich sein" + +#: commands/trigger.c:595 commands/trigger.c:608 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "WHEN-Bedingung eines Statement-Triggers kann keine Verweise auf Spaltenwerte enthalten" + +#: commands/trigger.c:600 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "WHEN-Bedingung eines INSERT-Triggers kann keine Verweise auf OLD-Werte enthalten" + +#: commands/trigger.c:613 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "WHEN-Bedingung eines DELETE-Triggers kann keine Verweise auf NEW-Werte enthalten" + +#: commands/trigger.c:618 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "WHEN-Bedingung eines BEFORE-Triggers kann keine Verweise auf Systemspalten in NEW enthalten" + +#: commands/trigger.c:626 commands/trigger.c:634 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "WHEN-Bedingung eines BEFORE-Triggers kann keine Verweise auf generierte Spalten in NEW enthalten" + +#: commands/trigger.c:627 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "Ein Verweis auf die ganze Zeile der Tabelle wird verwendet und die Tabelle enthält generierte Spalten." + +#: commands/trigger.c:741 commands/trigger.c:1450 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "Trigger »%s« für Relation »%s« existiert bereits" + +#: commands/trigger.c:755 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" is an internal trigger" +msgstr "Trigger »%s« für Relation »%s« ist ein interner Trigger" + +#: commands/trigger.c:774 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" is a constraint trigger" +msgstr "Trigger »%s« für Relation »%s« ist ein Constraint-Trigger" + +#: commands/trigger.c:1336 commands/trigger.c:1497 commands/trigger.c:1612 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "Trigger »%s« für Tabelle »%s« existiert nicht" + +#: commands/trigger.c:1580 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "keine Berechtigung: »%s« ist ein Systemtrigger" + +#: commands/trigger.c:2160 +#, c-format +msgid "trigger function %u returned null value" +msgstr "Triggerfunktion %u gab NULL-Wert zurück" + +#: commands/trigger.c:2220 commands/trigger.c:2434 commands/trigger.c:2673 +#: commands/trigger.c:2977 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "Trigger für BEFORE STATEMENT kann keinen Wert zurückgeben" + +#: commands/trigger.c:2294 +#, c-format +msgid "moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported" +msgstr "Verschieben einer Zeile in eine andere Partition durch einen BEFORE-FOR-EACH-ROW-Trigger wird nicht unterstützt" + +#: commands/trigger.c:2295 +#, c-format +msgid "Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." +msgstr "Vor der Ausführung von Trigger »%s« gehörte die Zeile in Partition »%s.%s«." + +#: commands/trigger.c:3043 executor/nodeModifyTable.c:1811 +#: executor/nodeModifyTable.c:1893 +#, c-format +msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" + +#: commands/trigger.c:3044 executor/nodeModifyTable.c:1193 +#: executor/nodeModifyTable.c:1267 executor/nodeModifyTable.c:1812 +#: executor/nodeModifyTable.c:1894 +#, c-format +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." +msgstr "Verwenden Sie einen AFTER-Trigger anstelle eines BEFORE-Triggers, um Änderungen an andere Zeilen zu propagieren." + +#: commands/trigger.c:3073 executor/nodeLockRows.c:225 +#: executor/nodeLockRows.c:234 executor/nodeModifyTable.c:228 +#: executor/nodeModifyTable.c:1209 executor/nodeModifyTable.c:1829 +#: executor/nodeModifyTable.c:2059 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "konnte Zugriff nicht serialisieren wegen gleichzeitiger Aktualisierung" + +#: commands/trigger.c:3081 executor/nodeModifyTable.c:1299 +#: executor/nodeModifyTable.c:1911 executor/nodeModifyTable.c:2083 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "konnte Zugriff nicht serialisieren wegen gleichzeitigem Löschen" + +#: commands/trigger.c:4142 +#, c-format +msgid "cannot fire deferred trigger within security-restricted operation" +msgstr "aufgeschobener Trigger kann nicht in einer sicherheitsbeschränkten Operation ausgelöst werden" + +#: commands/trigger.c:5185 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "Constraint »%s« ist nicht aufschiebbar" + +#: commands/trigger.c:5208 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "Constraint »%s« existiert nicht" + +#: commands/tsearchcmds.c:118 commands/tsearchcmds.c:635 +#, c-format +msgid "function %s should return type %s" +msgstr "Funktion %s sollte Rückgabetyp %s haben" + +#: commands/tsearchcmds.c:194 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "nur Superuser können Textsucheparser anlegen" + +#: commands/tsearchcmds.c:247 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "Textsucheparserparameter »%s« nicht erkannt" + +#: commands/tsearchcmds.c:257 +#, c-format +msgid "text search parser start method is required" +msgstr "Textsucheparserstartmethode muss angegeben werden" + +#: commands/tsearchcmds.c:262 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "Gettoken-Methode für Textsucheparser muss angegeben werden" + +#: commands/tsearchcmds.c:267 +#, c-format +msgid "text search parser end method is required" +msgstr "Textsucheparserendemethode muss angegeben werden" + +#: commands/tsearchcmds.c:272 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "Lextypes-Methode für Textsucheparser muss angegeben werden" + +#: commands/tsearchcmds.c:366 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "Textsuchevorlage »%s« akzeptiert keine Optionen" + +#: commands/tsearchcmds.c:440 +#, c-format +msgid "text search template is required" +msgstr "Textsuchevorlage muss angegeben werden" + +#: commands/tsearchcmds.c:701 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "nur Superuser können Textsuchevorlagen erzeugen" + +#: commands/tsearchcmds.c:743 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "Textsuchevorlageparameter »%s« nicht erkannt" + +#: commands/tsearchcmds.c:753 +#, c-format +msgid "text search template lexize method is required" +msgstr "Lexize-Methode für Textsuchevorlage muss angegeben werden" + +#: commands/tsearchcmds.c:933 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "Textsuchekonfigurationsparameter »%s« nicht erkannt" + +#: commands/tsearchcmds.c:940 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "Optionen PARSER und COPY können nicht beide angegeben werden" + +#: commands/tsearchcmds.c:976 +#, c-format +msgid "text search parser is required" +msgstr "Textsucheparser muss angegeben werden" + +#: commands/tsearchcmds.c:1200 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "Tokentyp »%s« existiert nicht" + +#: commands/tsearchcmds.c:1427 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "Mapping für Tokentyp »%s« existiert nicht" + +#: commands/tsearchcmds.c:1433 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "Mapping für Tokentyp »%s« existiert nicht, wird übersprungen" + +#: commands/tsearchcmds.c:1596 commands/tsearchcmds.c:1711 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "ungültiges Parameterlistenformat: »%s«" + +#: commands/typecmds.c:217 +#, c-format +msgid "must be superuser to create a base type" +msgstr "nur Superuser können Basistypen anlegen" + +#: commands/typecmds.c:275 +#, c-format +msgid "Create the type as a shell type, then create its I/O functions, then do a full CREATE TYPE." +msgstr "Erzeugen Sie den Typ als Shell-Typ, legen Sie dann die I/O-Funktionen an und führen Sie dann das volle CREATE TYPE aus." + +#: commands/typecmds.c:327 commands/typecmds.c:1465 commands/typecmds.c:4281 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "Typ-Attribut »%s« nicht erkannt" + +#: commands/typecmds.c:385 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "ungültige Typenkategorie »%s«: muss einfacher ASCII-Wert sein" + +#: commands/typecmds.c:404 +#, c-format +msgid "array element type cannot be %s" +msgstr "Arrayelementtyp kann nicht %s sein" + +#: commands/typecmds.c:436 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "Ausrichtung »%s« nicht erkannt" + +#: commands/typecmds.c:453 commands/typecmds.c:4155 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "Storage-Typ »%s« nicht erkannt" + +#: commands/typecmds.c:464 +#, c-format +msgid "type input function must be specified" +msgstr "Typeingabefunktion muss angegeben werden" + +#: commands/typecmds.c:468 +#, c-format +msgid "type output function must be specified" +msgstr "Typausgabefunktion muss angegeben werden" + +#: commands/typecmds.c:473 +#, c-format +msgid "type modifier output function is useless without a type modifier input function" +msgstr "Typmodifikatorausgabefunktion ist nutzlos ohne Typmodifikatoreingabefunktion" + +#: commands/typecmds.c:515 +#, c-format +msgid "element type cannot be specified without a valid subscripting procedure" +msgstr "" + +#: commands/typecmds.c:784 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "»%s« ist kein gültiger Basistyp für eine Domäne" + +#: commands/typecmds.c:882 +#, c-format +msgid "multiple default expressions" +msgstr "mehrere Vorgabeausdrücke" + +#: commands/typecmds.c:945 commands/typecmds.c:954 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "wiedersprüchliche NULL/NOT NULL-Constraints" + +#: commands/typecmds.c:970 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "Check-Constraints für Domänen können nicht als NO INHERIT markiert werden" + +#: commands/typecmds.c:979 commands/typecmds.c:2975 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "Unique-Constraints sind nicht für Domänen möglich" + +#: commands/typecmds.c:985 commands/typecmds.c:2981 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "Primärschlüssel-Constraints sind nicht fürDomänen möglich" + +#: commands/typecmds.c:991 commands/typecmds.c:2987 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "Exclusion-Constraints sind nicht für Domänen möglich" + +#: commands/typecmds.c:997 commands/typecmds.c:2993 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "Fremdschlüssel-Constraints sind nicht für Domänen möglich" + +#: commands/typecmds.c:1006 commands/typecmds.c:3002 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "Setzen des Constraint-Modus wird für Domänen nicht unterstützt" + +#: commands/typecmds.c:1320 utils/cache/typcache.c:2545 +#, c-format +msgid "%s is not an enum" +msgstr "»%s« ist kein Enum" + +#: commands/typecmds.c:1473 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "Typ-Attribut »subtype« muss angegeben werden" + +#: commands/typecmds.c:1478 +#, c-format +msgid "range subtype cannot be %s" +msgstr "Bereichtsuntertyp kann nicht %s sein" + +#: commands/typecmds.c:1497 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "Sortierfolge für Bereichstyp angegeben, aber Untertyp unterstützt keine Sortierfolgen" + +#: commands/typecmds.c:1507 +#, c-format +msgid "cannot specify a canonical function without a pre-created shell type" +msgstr "Canonical-Funktion kann nicht angegeben werden ohne einen vorher angelegten Shell-Typ" + +#: commands/typecmds.c:1508 +#, c-format +msgid "Create the type as a shell type, then create its canonicalization function, then do a full CREATE TYPE." +msgstr "Erzeugen Sie den Typ als Shell-Typ, legen Sie dann die Canonicalization-Funktion an und führen Sie dann das volle CREATE TYPE aus." + +#: commands/typecmds.c:1982 +#, c-format +msgid "type input function %s has multiple matches" +msgstr "Typeingabefunktion %s hat mehrere Übereinstimmungen" + +#: commands/typecmds.c:2000 +#, c-format +msgid "type input function %s must return type %s" +msgstr "Typeingabefunktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2016 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "Typeingabefunktion %s sollte nicht VOLATILE sein" + +#: commands/typecmds.c:2044 +#, c-format +msgid "type output function %s must return type %s" +msgstr "Typausgabefunktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2051 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "Typausgabefunktion %s sollte nicht VOLATILE sein" + +#: commands/typecmds.c:2080 +#, c-format +msgid "type receive function %s has multiple matches" +msgstr "Typempfangsfunktion %s hat mehrere Übereinstimmungen" + +#: commands/typecmds.c:2098 +#, c-format +msgid "type receive function %s must return type %s" +msgstr "Typempfangsfunktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2105 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "Typempfangsfunktion %s sollte nicht VOLATILE sein" + +#: commands/typecmds.c:2133 +#, c-format +msgid "type send function %s must return type %s" +msgstr "Typsendefunktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2140 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "Typsendefunktion %s sollte nicht VOLATILE sein" + +#: commands/typecmds.c:2167 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr "typmod_in-Funktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2174 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "Typmodifikatoreingabefunktion %s sollte nicht VOLATILE sein" + +#: commands/typecmds.c:2201 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "typmod_out-Funktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2208 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "Typmodifikatorausgabefunktion %s sollte nicht VOLATILE sein" + +#: commands/typecmds.c:2235 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "Typanalysefunktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2264 +#, fuzzy, c-format +#| msgid "type input function %s must return type %s" +msgid "type subscripting function %s must return type %s" +msgstr "Typeingabefunktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2274 +#, c-format +msgid "user-defined types cannot use subscripting function %s" +msgstr "" + +#: commands/typecmds.c:2320 +#, c-format +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." +msgstr "Sie müssen für den Bereichstyp eine Operatorklasse angeben oder eine Standardoperatorklasse für den Untertyp definieren." + +#: commands/typecmds.c:2351 +#, c-format +msgid "range canonical function %s must return range type" +msgstr "Bereichstyp-Canonical-Funktion %s muss Bereichstyp zurückgeben" + +#: commands/typecmds.c:2357 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "Bereichstyp-Canonical-Funktion %s muss »immutable« sein" + +#: commands/typecmds.c:2393 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "Bereichstyp-Untertyp-Diff-Funktion %s muss Typ %s zurückgeben" + +#: commands/typecmds.c:2400 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "Bereichstyp-Untertyp-Diff-Funktion %s muss »immutable« sein" + +#: commands/typecmds.c:2427 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "Array-OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" + +#: commands/typecmds.c:2460 +#, c-format +msgid "pg_type multirange OID value not set when in binary upgrade mode" +msgstr "Multirange-OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" + +#: commands/typecmds.c:2493 +#, c-format +msgid "pg_type multirange array OID value not set when in binary upgrade mode" +msgstr "Multirange-Array-OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" + +#: commands/typecmds.c:2791 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "Spalte »%s« von Tabelle »%s« enthält NULL-Werte" + +#: commands/typecmds.c:2904 commands/typecmds.c:3106 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "Constraint »%s« von Domäne »%s« existiert nicht" + +#: commands/typecmds.c:2908 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "Constraint »%s« von Domäne »%s« existiert nicht, wird übersprungen" + +#: commands/typecmds.c:3113 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "Constraint »%s« von Domäne »%s« ist kein Check-Constraint" + +#: commands/typecmds.c:3219 +#, c-format +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "Spalte »%s« von Tabelle »%s« enthält Werte, die den neuen Constraint verletzen" + +#: commands/typecmds.c:3448 commands/typecmds.c:3646 commands/typecmds.c:3727 +#: commands/typecmds.c:3913 +#, c-format +msgid "%s is not a domain" +msgstr "%s ist keine Domäne" + +#: commands/typecmds.c:3480 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "Constraint »%s« für Domäne »%s« existiert bereits" + +#: commands/typecmds.c:3531 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "Tabellenverweise können in Domänen-Check-Constraints nicht verwendet werden" + +#: commands/typecmds.c:3658 commands/typecmds.c:3739 commands/typecmds.c:4030 +#, c-format +msgid "%s is a table's row type" +msgstr "%s ist der Zeilentyp einer Tabelle" + +#: commands/typecmds.c:3660 commands/typecmds.c:3741 commands/typecmds.c:4032 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "Verwenden Sie stattdessen ALTER TABLE." + +#: commands/typecmds.c:3666 commands/typecmds.c:3747 commands/typecmds.c:3945 +#, c-format +msgid "cannot alter array type %s" +msgstr "Array-Typ %s kann nicht verändert werden" + +#: commands/typecmds.c:3668 commands/typecmds.c:3749 commands/typecmds.c:3947 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "Sie können den Typ %s ändern, wodurch der Array-Typ ebenfalls geändert wird." + +#: commands/typecmds.c:4015 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "Typ %s existiert bereits in Schema »%s«" + +#: commands/typecmds.c:4183 +#, c-format +msgid "cannot change type's storage to PLAIN" +msgstr "Storage-Typ eines Typs kann nicht in PLAIN geändert werden" + +#: commands/typecmds.c:4276 +#, c-format +msgid "type attribute \"%s\" cannot be changed" +msgstr "Typ-Attribut »%s« kann nicht geändert werden" + +#: commands/typecmds.c:4294 +#, c-format +msgid "must be superuser to alter a type" +msgstr "nur Superuser können Typen ändern" + +#: commands/typecmds.c:4315 commands/typecmds.c:4324 +#, c-format +msgid "%s is not a base type" +msgstr "%s ist kein Basistyp" + +#: commands/user.c:140 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSID kann nicht mehr angegeben werden" + +#: commands/user.c:294 +#, c-format +msgid "must be superuser to create superusers" +msgstr "nur Superuser können Superuser anlegen" + +#: commands/user.c:301 +#, c-format +msgid "must be superuser to create replication users" +msgstr "nur Superuser können Replikationsbenutzer anlegen" + +#: commands/user.c:308 +#, c-format +msgid "must be superuser to create bypassrls users" +msgstr "nur Superuser können Benutzer mit »bypassrls« anlegen" + +#: commands/user.c:315 +#, c-format +msgid "permission denied to create role" +msgstr "keine Berechtigung, um Rolle zu erzeugen" + +#: commands/user.c:325 commands/user.c:1226 commands/user.c:1233 gram.y:15283 +#: gram.y:15328 utils/adt/acl.c:5248 utils/adt/acl.c:5254 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "Rollenname »%s« ist reserviert" + +#: commands/user.c:327 commands/user.c:1228 commands/user.c:1235 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "Rollennamen, die mit »pg_« anfangen, sind reserviert." + +#: commands/user.c:348 commands/user.c:1250 +#, c-format +msgid "role \"%s\" already exists" +msgstr "Rolle »%s« existiert bereits" + +#: commands/user.c:414 commands/user.c:845 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "leere Zeichenkette ist kein gültiges Passwort, Passwort wird entfernt" + +#: commands/user.c:443 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "OID-Wert für pg_auth ist im Binary-Upgrade-Modus nicht gesetzt" + +#: commands/user.c:722 +#, fuzzy, c-format +#| msgid "must be superuser to change bypassrls attribute" +msgid "must be superuser to alter superuser roles or change superuser attribute" +msgstr "nur Superuser können das Attribut »bypassrls« ändern" + +#: commands/user.c:729 +#, fuzzy, c-format +#| msgid "must be superuser or replication role to use replication slots" +msgid "must be superuser to alter replication roles or change replication attribute" +msgstr "nur Superuser und Replikationsrollen können Replikations-Slots verwenden" + +#: commands/user.c:736 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "nur Superuser können das Attribut »bypassrls« ändern" + +#: commands/user.c:752 commands/user.c:953 +#, c-format +msgid "permission denied" +msgstr "keine Berechtigung" + +#: commands/user.c:946 commands/user.c:1487 commands/user.c:1665 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "nur Superuser können Superuser ändern" + +#: commands/user.c:983 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "nur Superuser können globale Einstellungen ändern" + +#: commands/user.c:1005 +#, c-format +msgid "permission denied to drop role" +msgstr "keine Berechtigung, um Rolle zu entfernen" + +#: commands/user.c:1030 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "in DROP ROLE kann kein Rollenplatzhalter verwendet werden" + +#: commands/user.c:1040 commands/user.c:1197 commands/variable.c:778 +#: commands/variable.c:781 commands/variable.c:865 commands/variable.c:868 +#: utils/adt/acl.c:5103 utils/adt/acl.c:5151 utils/adt/acl.c:5179 +#: utils/adt/acl.c:5198 utils/init/miscinit.c:705 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "Rolle »%s« existiert nicht" + +#: commands/user.c:1045 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "Rolle »%s« existiert nicht, wird übersprungen" + +#: commands/user.c:1058 commands/user.c:1062 +#, c-format +msgid "current user cannot be dropped" +msgstr "aktueller Benutzer kann nicht entfernt werden" + +#: commands/user.c:1066 +#, c-format +msgid "session user cannot be dropped" +msgstr "aktueller Sitzungsbenutzer kann nicht entfernt werden" + +#: commands/user.c:1076 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "nur Superuser können Superuser löschen" + +#: commands/user.c:1092 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "kann Rolle »%s« nicht löschen, weil andere Objekte davon abhängen" + +#: commands/user.c:1213 +#, c-format +msgid "session user cannot be renamed" +msgstr "aktueller Sitzungsbenutzer kann nicht umbenannt werden" + +#: commands/user.c:1217 +#, c-format +msgid "current user cannot be renamed" +msgstr "aktueller Benutzer kann nicht umbenannt werden" + +#: commands/user.c:1260 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "nur Superuser können Superuser umbenennen" + +#: commands/user.c:1267 +#, c-format +msgid "permission denied to rename role" +msgstr "keine Berechtigung, um Rolle umzubenennen" + +#: commands/user.c:1288 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "MD5-Passwort wegen Rollenumbenennung gelöscht" + +#: commands/user.c:1348 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "bei GRANT/REVOKE ROLE können keine Spaltennamen angegeben werden" + +#: commands/user.c:1386 +#, c-format +msgid "permission denied to drop objects" +msgstr "keine Berechtigung, um Objekte zu löschen" + +#: commands/user.c:1413 commands/user.c:1422 +#, c-format +msgid "permission denied to reassign objects" +msgstr "keine Berechtigung, um Objekte neu zuzuordnen" + +#: commands/user.c:1495 commands/user.c:1673 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "Admin-Option für Rolle »%s« wird benötigt" + +#: commands/user.c:1509 +#, fuzzy, c-format +#| msgid "table \"%s\" cannot be replicated" +msgid "role \"%s\" cannot have explicit members" +msgstr "Tabelle »%s« kann nicht repliziert werden" + +#: commands/user.c:1524 +#, c-format +msgid "must be superuser to set grantor" +msgstr "nur Superuser können Grantor setzen" + +#: commands/user.c:1560 +#, fuzzy, c-format +#| msgid "role \"%s\" is not a member of role \"%s\"" +msgid "role \"%s\" cannot be a member of any role" +msgstr "Rolle »%s« ist kein Mitglied der Rolle »%s«" + +#: commands/user.c:1573 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "Rolle »%s« ist ein Mitglied der Rolle »%s«" + +#: commands/user.c:1588 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "Rolle »%s« ist schon Mitglied der Rolle »%s«" + +#: commands/user.c:1695 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "Rolle »%s« ist kein Mitglied der Rolle »%s«" + +#: commands/vacuum.c:132 +#, c-format +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "unbekannte ANALYZE-Option »%s«" + +#: commands/vacuum.c:156 +#, c-format +msgid "parallel option requires a value between 0 and %d" +msgstr "Option PARALLEL benötigt einen Wert zwischen 0 und %d" + +#: commands/vacuum.c:168 +#, fuzzy, c-format +#| msgid "parallel vacuum degree must be between 0 and %d" +msgid "parallel workers for vacuum must be between 0 and %d" +msgstr "Grad für paralleles Vacuum muss zwischen 0 und %d sein" + +#: commands/vacuum.c:185 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "unbekannte VACUUM-Option »%s«" + +#: commands/vacuum.c:208 +#, c-format +msgid "VACUUM FULL cannot be performed in parallel" +msgstr "VACUUM FULL kann nicht parallel ausgeführt werden" + +#: commands/vacuum.c:224 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "Option ANALYZE muss angegeben werden, wenn eine Spaltenliste angegeben ist" + +#: commands/vacuum.c:314 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s kann nicht aus VACUUM oder ANALYZE ausgeführt werden" + +#: commands/vacuum.c:324 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "VACUUM-Option DISABLE_PAGE_SKIPPING kann nicht zusammen mit FULL verwendet werden" + +#: commands/vacuum.c:331 +#, c-format +msgid "PROCESS_TOAST required with VACUUM FULL" +msgstr "PROCESS_TOAST benötigt VACUUM FULL" + +#: commands/vacuum.c:572 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "überspringe »%s« --- nur Superuser kann sie vacuumen" + +#: commands/vacuum.c:576 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "überspringe »%s« --- nur Superuser oder Eigentümer der Datenbank kann sie vacuumen" + +#: commands/vacuum.c:580 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "überspringe »%s« --- nur Eigentümer der Tabelle oder der Datenbank kann sie vacuumen" + +#: commands/vacuum.c:595 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "überspringe »%s« --- nur Superuser kann sie analysieren" + +#: commands/vacuum.c:599 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "überspringe »%s« --- nur Superuser oder Eigentümer der Datenbank kann sie analysieren" + +#: commands/vacuum.c:603 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "überspringe »%s« --- nur Eigentümer der Tabelle oder der Datenbank kann sie analysieren" + +#: commands/vacuum.c:682 commands/vacuum.c:778 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "überspringe Vacuum von »%s« --- Sperre nicht verfügbar" + +#: commands/vacuum.c:687 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "überspringe Vacuum von »%s« --- Relation existiert nicht mehr" + +#: commands/vacuum.c:703 commands/vacuum.c:783 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "überspringe Analyze von »%s« --- Sperre nicht verfügbar" + +#: commands/vacuum.c:708 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "überspringe Analyze von »%s« --- Relation existiert nicht mehr" + +#: commands/vacuum.c:1026 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "älteste xmin ist weit in der Vergangenheit" + +#: commands/vacuum.c:1027 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Schließen Sie bald alle offenen Transaktionen, um Überlaufprobleme zu vermeiden.\n" +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." + +#: commands/vacuum.c:1068 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "älteste Multixact ist weit in der Vergangenheit" + +#: commands/vacuum.c:1069 +#, c-format +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "Schließen Sie bald alle offenen Transaktionen mit Multixacts, um Überlaufprobleme zu vermeiden." + +#: commands/vacuum.c:1726 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "einige Datenbanken sind seit über 2 Milliarden Transaktionen nicht gevacuumt worden" + +#: commands/vacuum.c:1727 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "Sie haben möglicherweise bereits Daten wegen Transaktionsnummernüberlauf verloren." + +#: commands/vacuum.c:1891 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "überspringe »%s« --- kann Nicht-Tabellen oder besondere Systemtabellen nicht vacuumen" + +#: commands/variable.c:165 utils/misc/guc.c:11625 utils/misc/guc.c:11687 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "Unbekanntes Schlüsselwort: »%s«." + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "Widersprüchliche »datestyle«-Angaben." + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "Im Zeitzonenintervall können keine Monate angegeben werden." + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "Im Zeitzonenintervall können keine Tage angegeben werden." + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "Zeitzone »%s« verwendet anscheinend Schaltsekunden" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQL unterstützt keine Schaltsekunden." + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "Zeitzonenabstand zu UTC ist außerhalb des gültigen Bereichs." + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "kann den Read/Write-Modus einer Transaktion nicht in einer Read-Only-Transaktion setzen" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "Read/Write-Modus einer Transaktion muss vor allen Anfragen gesetzt werden" + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "kann den Read/Write-Modus einer Transaktion nicht während der Wiederherstellung setzen" + +#: commands/variable.c:534 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "SET TRANSACTION ISOLATION LEVEL muss vor allen Anfragen aufgerufen werden" + +#: commands/variable.c:541 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "SET TRANSACTION ISOLATION LEVEL kann nicht in einer Subtransaktion aufgerufen werden" + +#: commands/variable.c:548 storage/lmgr/predicate.c:1693 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "kann serialisierbaren Modus nicht in einem Hot Standby verwenden" + +#: commands/variable.c:549 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "Sie können stattdessen REPEATABLE READ verwenden." + +#: commands/variable.c:567 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "SET TRANSACTION [NOT] DEFERRABLE kann nicht in einer Subtransaktion aufgerufen werden" + +#: commands/variable.c:573 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "SET TRANSACTION [NOT] DEFERRABLE muss vor allen Anfragen aufgerufen werden" + +#: commands/variable.c:655 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "Umwandlung zwischen %s und %s wird nicht unterstützt." + +#: commands/variable.c:662 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "»client_encoding« kann jetzt nicht geändert werden." + +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "client_encoding kann nicht während einer parallelen Operation geändert werden" + +#: commands/variable.c:890 +#, c-format +msgid "permission will be denied to set role \"%s\"" +msgstr "Berechtigung fehlt, um Rolle »%s« zu setzen" + +#: commands/variable.c:895 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "keine Berechtigung, um Rolle »%s« zu setzen" + +#: commands/view.c:84 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "konnte die für die Sichtspalte »%s« zu verwendende Sortierfolge nicht bestimmen" + +#: commands/view.c:265 commands/view.c:276 +#, c-format +msgid "cannot drop columns from view" +msgstr "aus einer Sicht können keine Spalten gelöscht werden" + +#: commands/view.c:281 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "kann Namen der Sichtspalte »%s« nicht in »%s« ändern" + +#: commands/view.c:284 +#, c-format +msgid "Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead." +msgstr "Verwenden Sie stattdessen ALTER VIEW ... RENAME COLUMN ..., um den Namen einer Sichtspalte zu ändern." + +#: commands/view.c:290 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "kann Datentyp der Sichtspalte »%s« nicht von %s in %s ändern" + +#: commands/view.c:441 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "Sichten dürfen kein SELECT INTO enthalten" + +#: commands/view.c:453 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "Sichten dürfen keine datenmodifizierenden Anweisungen in WITH enthalten" + +#: commands/view.c:523 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "CREATE VIEW gibt mehr Spaltennamen als Spalten an" + +#: commands/view.c:531 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "Sichten können nicht ungeloggt sein, weil sie keinen Speicherplatz verwenden" + +#: commands/view.c:545 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "Sicht »%s« wird eine temporäre Sicht" + +#: executor/execCurrent.c:79 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "Cursor »%s« ist keine SELECT-Anfrage" + +#: executor/execCurrent.c:85 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "Cursor »%s« wurde aus einer vorherigen Transaktion beibehalten" + +#: executor/execCurrent.c:118 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "Cursor »%s« hat mehrere FOR UPDATE/SHARE-Verweise auf Tabelle »%s«" + +#: executor/execCurrent.c:127 +#, c-format +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "Cursor »%s« hat keinen FOR UPDATE/SHARE-Verweis auf Tabelle »%s«" + +#: executor/execCurrent.c:137 executor/execCurrent.c:182 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr "Cursor »%s« ist nicht auf eine Zeile positioniert" + +#: executor/execCurrent.c:169 executor/execCurrent.c:228 +#: executor/execCurrent.c:239 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "Cursor »%s« ist kein einfach aktualisierbarer Scan der Tabelle »%s«" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2451 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "Typ von Parameter %d (%s) stimmt nicht mit dem überein, als der Plan vorbereitet worden ist (%s)" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2463 +#, c-format +msgid "no value found for parameter %d" +msgstr "kein Wert für Parameter %d gefunden" + +#: executor/execExpr.c:632 executor/execExpr.c:639 executor/execExpr.c:645 +#: executor/execExprInterp.c:4023 executor/execExprInterp.c:4040 +#: executor/execExprInterp.c:4141 executor/nodeModifyTable.c:117 +#: executor/nodeModifyTable.c:128 executor/nodeModifyTable.c:145 +#: executor/nodeModifyTable.c:153 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "Zeilentyp der Tabelle und der von der Anfrage angegebene Zeilentyp stimmen nicht überein" + +#: executor/execExpr.c:633 executor/nodeModifyTable.c:118 +#, c-format +msgid "Query has too many columns." +msgstr "Anfrage hat zu viele Spalten." + +#: executor/execExpr.c:640 executor/nodeModifyTable.c:146 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "Anfrage liefert einen Wert für eine gelöschte Spalte auf Position %d." + +#: executor/execExpr.c:646 executor/execExprInterp.c:4041 +#: executor/nodeModifyTable.c:129 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "Tabelle hat Typ %s auf Position %d, aber Anfrage erwartet %s." + +#: executor/execExpr.c:1110 parser/parse_agg.c:827 +#, c-format +msgid "window function calls cannot be nested" +msgstr "Aufrufe von Fensterfunktionen können nicht geschachtelt werden" + +#: executor/execExpr.c:1615 +#, c-format +msgid "target type is not an array" +msgstr "Zieltyp ist kein Array" + +#: executor/execExpr.c:1955 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW()-Spalte hat Typ %s statt Typ %s" + +#: executor/execExpr.c:2480 executor/execSRF.c:718 parser/parse_func.c:136 +#: parser/parse_func.c:654 parser/parse_func.c:1030 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "kann nicht mehr als %d Argument an eine Funktion übergeben" +msgstr[1] "kann nicht mehr als %d Argumente an eine Funktion übergeben" + +#: executor/execExpr.c:2866 parser/parse_node.c:277 parser/parse_node.c:327 +#, fuzzy, c-format +#| msgid "cannot subscript type %s because it is not an array" +msgid "cannot subscript type %s because it does not support subscripting" +msgstr "kann aus Typ %s kein Element auswählen, weil er kein Array ist" + +#: executor/execExpr.c:2994 executor/execExpr.c:3016 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support subscriptions." +msgid "type %s does not support subscripted assignment" +msgstr "Der Server (Version %s) unterstützt keine Subskriptionen." + +#: executor/execExprInterp.c:1916 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "Attribut %d von Typ %s wurde gelöscht" + +#: executor/execExprInterp.c:1922 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "Attribut %d von Typ %s hat falschen Typ" + +#: executor/execExprInterp.c:1924 executor/execExprInterp.c:3052 +#: executor/execExprInterp.c:3098 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "Tabelle hat Typ %s, aber Anfrage erwartet %s." + +#: executor/execExprInterp.c:2003 utils/adt/expandedrecord.c:99 +#: utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1748 +#: utils/cache/typcache.c:1904 utils/cache/typcache.c:2033 +#: utils/fmgr/funcapi.c:458 +#, c-format +msgid "type %s is not composite" +msgstr "Typ %s ist kein zusammengesetzter Typ" + +#: executor/execExprInterp.c:2541 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF wird für diesen Tabellentyp nicht unterstützt" + +#: executor/execExprInterp.c:2754 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "kann inkompatible Arrays nicht verschmelzen" + +#: executor/execExprInterp.c:2755 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "Arrayelement mit Typ %s kann nicht in ARRAY-Konstrukt mit Elementtyp %s verwendet werden." + +#: executor/execExprInterp.c:2776 utils/adt/arrayfuncs.c:262 +#: utils/adt/arrayfuncs.c:562 utils/adt/arrayfuncs.c:1304 +#: utils/adt/arrayfuncs.c:3374 utils/adt/arrayfuncs.c:5336 +#: utils/adt/arrayfuncs.c:5853 utils/adt/arraysubs.c:150 +#: utils/adt/arraysubs.c:488 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "Anzahl der Arraydimensionen (%d) überschreitet erlaubtes Maximum (%d)" + +#: executor/execExprInterp.c:2796 executor/execExprInterp.c:2826 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben" + +#: executor/execExprInterp.c:3051 executor/execExprInterp.c:3097 +#, c-format +msgid "attribute %d has wrong type" +msgstr "Attribut %d hat falschen Typ" + +#: executor/execExprInterp.c:3652 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "Domäne %s erlaubt keine NULL-Werte" + +#: executor/execExprInterp.c:3667 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "Wert für Domäne %s verletzt Check-Constraint »%s«" + +#: executor/execExprInterp.c:4024 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "Tabellenzeile enthält %d Attribut, aber Anfrage erwartet %d." +msgstr[1] "Tabellenzeile enthält %d Attribute, aber Anfrage erwartet %d." + +#: executor/execExprInterp.c:4142 executor/execSRF.c:977 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "Physischer Speicher stimmt nicht überein mit gelöschtem Attribut auf Position %d." + +#: executor/execIndexing.c:571 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "ON CONFLICT unterstützt keine aufschiebbaren Unique-Constraints/Exclusion-Constraints als Arbiter" + +#: executor/execIndexing.c:842 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "konnte Exclusion-Constraint »%s« nicht erzeugen" + +#: executor/execIndexing.c:845 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "Schlüssel %s kollidiert mit Schlüssel %s." + +#: executor/execIndexing.c:847 +#, c-format +msgid "Key conflicts exist." +msgstr "Es bestehen Schlüsselkonflikte." + +#: executor/execIndexing.c:853 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "kollidierender Schlüsselwert verletzt Exclusion-Constraint »%s«" + +#: executor/execIndexing.c:856 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "Schlüssel %s kollidiert mit vorhandenem Schlüssel %s." + +#: executor/execIndexing.c:858 +#, c-format +msgid "Key conflicts with existing key." +msgstr "Der Schlüssel kollidiert mit einem vorhandenen Schlüssel." + +#: executor/execMain.c:1007 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "kann Sequenz »%s« nicht ändern" + +#: executor/execMain.c:1013 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "kann TOAST-Relation »%s« nicht ändern" + +#: executor/execMain.c:1031 rewrite/rewriteHandler.c:3041 +#: rewrite/rewriteHandler.c:3824 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "kann nicht in Sicht »%s« einfügen" + +#: executor/execMain.c:1033 rewrite/rewriteHandler.c:3044 +#: rewrite/rewriteHandler.c:3827 +#, c-format +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "Um Einfügen in die Sicht zu ermöglichen, richten Sie einen INSTEAD OF INSERT Trigger oder eine ON INSERT DO INSTEAD Regel ohne Bedingung ein." + +#: executor/execMain.c:1039 rewrite/rewriteHandler.c:3049 +#: rewrite/rewriteHandler.c:3832 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "kann Sicht »%s« nicht aktualisieren" + +#: executor/execMain.c:1041 rewrite/rewriteHandler.c:3052 +#: rewrite/rewriteHandler.c:3835 +#, c-format +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "Um Aktualisieren der Sicht zu ermöglichen, richten Sie einen INSTEAD OF UPDATE Trigger oder eine ON UPDATE DO INSTEAD Regel ohne Bedingung ein." + +#: executor/execMain.c:1047 rewrite/rewriteHandler.c:3057 +#: rewrite/rewriteHandler.c:3840 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "kann nicht aus Sicht »%s« löschen" + +#: executor/execMain.c:1049 rewrite/rewriteHandler.c:3060 +#: rewrite/rewriteHandler.c:3843 +#, c-format +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "Um Löschen aus der Sicht zu ermöglichen, richten Sie einen INSTEAD OF DELETE Trigger oder eine ON DELETE DO INSTEAD Regel ohne Bedingung ein." + +#: executor/execMain.c:1060 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "kann materialisierte Sicht »%s« nicht ändern" + +#: executor/execMain.c:1072 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "kann nicht in Fremdtabelle »%s« einfügen" + +#: executor/execMain.c:1078 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "Fremdtabelle »%s« erlaubt kein Einfügen" + +#: executor/execMain.c:1085 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "kann Fremdtabelle »%s« nicht aktualisieren" + +#: executor/execMain.c:1091 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "Fremdtabelle »%s« erlaubt kein Aktualisieren" + +#: executor/execMain.c:1098 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "kann nicht aus Fremdtabelle »%s« löschen" + +#: executor/execMain.c:1104 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "Fremdtabelle »%s« erlaubt kein Löschen" + +#: executor/execMain.c:1115 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "kann Relation »%s« nicht ändern" + +#: executor/execMain.c:1142 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "kann Zeilen in Sequenz »%s« nicht sperren" + +#: executor/execMain.c:1149 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "kann Zeilen in TOAST-Relation »%s« nicht sperren" + +#: executor/execMain.c:1156 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "kann Zeilen in Sicht »%s« nicht sperren" + +#: executor/execMain.c:1164 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "kann Zeilen in materialisierter Sicht »%s« nicht sperren" + +#: executor/execMain.c:1173 executor/execMain.c:2555 +#: executor/nodeLockRows.c:132 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "kann Zeilen in Fremdtabelle »%s« nicht sperren" + +#: executor/execMain.c:1179 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "kann Zeilen in Relation »%s« nicht sperren" + +#: executor/execMain.c:1803 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "neue Zeile für Relation »%s« verletzt Partitions-Constraint" + +#: executor/execMain.c:1805 executor/execMain.c:1888 executor/execMain.c:1938 +#: executor/execMain.c:2047 +#, c-format +msgid "Failing row contains %s." +msgstr "Fehlgeschlagene Zeile enthält %s." + +#: executor/execMain.c:1885 +#, c-format +msgid "null value in column \"%s\" of relation \"%s\" violates not-null constraint" +msgstr "NULL-Wert in Spalte »%s« von Relation »%s« verletzt Not-Null-Constraint" + +#: executor/execMain.c:1936 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "neue Zeile für Relation »%s« verletzt Check-Constraint »%s«" + +#: executor/execMain.c:2045 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "neue Zeile verletzt Check-Option für Sicht »%s«" + +#: executor/execMain.c:2055 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene »%s« für Tabelle »%s«" + +#: executor/execMain.c:2060 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene für Tabelle »%s«" + +#: executor/execMain.c:2067 +#, c-format +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene »%s« (USING-Ausdruck) für Tabelle »%s«" + +#: executor/execMain.c:2072 +#, c-format +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene (USING-Ausdruck) für Tabelle »%s«" + +#: executor/execPartition.c:322 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "keine Partition von Relation »%s« für die Zeile gefunden" + +#: executor/execPartition.c:325 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "Partitionierungsschlüssel der fehlgeschlagenen Zeile enthält %s." + +#: executor/execReplication.c:196 executor/execReplication.c:373 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "das zu sperrende Tupel wurde schon durch ein gleichzeitiges Update in eine andere Partition verschoben, versuche erneut" + +#: executor/execReplication.c:200 executor/execReplication.c:377 +#, c-format +msgid "concurrent update, retrying" +msgstr "gleichzeitige Aktualisierung, versuche erneut" + +#: executor/execReplication.c:206 executor/execReplication.c:383 +#, c-format +msgid "concurrent delete, retrying" +msgstr "gleichzeitiges Löschen, versuche erneut" + +#: executor/execReplication.c:269 parser/parse_cte.c:502 +#: parser/parse_oper.c:233 utils/adt/array_userfuncs.c:720 +#: utils/adt/array_userfuncs.c:859 utils/adt/arrayfuncs.c:3654 +#: utils/adt/arrayfuncs.c:4174 utils/adt/arrayfuncs.c:6166 +#: utils/adt/rowtypes.c:1203 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "konnte keinen Ist-Gleich-Operator für Typ %s ermitteln" + +#: executor/execReplication.c:590 +#, c-format +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "Tabelle »%s« kann nicht aktualisiert werden, weil sie keine Replik-Identität hat und Updates publiziert" + +#: executor/execReplication.c:592 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Um Aktualisieren der Tabelle zu ermöglichen, setzen Sie REPLICA IDENTITY mit ALTER TABLE." + +#: executor/execReplication.c:596 +#, c-format +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "aus Tabelle »%s« kann nicht gelöscht werden, weil sie keine Replik-Identität hat und Deletes publiziert" + +#: executor/execReplication.c:598 +#, c-format +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Um Löschen in der Tabelle zu ermöglichen, setzen Sie REPLICA IDENTITY mit ALTER TABLE." + +#: executor/execReplication.c:617 executor/execReplication.c:625 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "Relation »%s.%s« kann nicht als Ziel für logische Replikation verwendet werden" + +#: executor/execReplication.c:619 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "»%s.%s« ist eine Fremdtabelle." + +#: executor/execReplication.c:627 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "»%s.%s« ist keine Tabelle." + +#: executor/execSRF.c:315 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "von Funktion zurückgegebene Zeilen haben nicht alle den selben Zeilentyp" + +#: executor/execSRF.c:365 +#, c-format +msgid "table-function protocol for value-per-call mode was not followed" +msgstr "Tabellenfunktionsprotokoll für Value-per-Call-Modus wurde nicht befolgt" + +#: executor/execSRF.c:373 executor/execSRF.c:667 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "Tabellenfunktionsprotokoll für Materialisierungsmodus wurde nicht befolgt" + +#: executor/execSRF.c:380 executor/execSRF.c:685 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "unbekannter returnMode von Tabellenfunktion: %d" + +#: executor/execSRF.c:894 +#, c-format +msgid "function returning setof record called in context that cannot accept type record" +msgstr "Funktion mit Ergebnis SETOF RECORD in einem Zusammenhang aufgerufen, der den Typ RECORD nicht verarbeiten kann" + +#: executor/execSRF.c:950 executor/execSRF.c:966 executor/execSRF.c:976 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "von Funktion zurückgegebene Zeile und von der Anfrage angegebene zurückzugebende Zeile stimmen nicht überein" + +#: executor/execSRF.c:951 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "Zurückgegebene Zeile enthält %d Attribut, aber Anfrage erwartet %d." +msgstr[1] "Zurückgegebene Zeile enthält %d Attribute, aber Anfrage erwartet %d." + +#: executor/execSRF.c:967 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "Rückgabetyp war %s auf Position %d, aber Anfrage erwartet %s." + +#: executor/execTuples.c:146 executor/execTuples.c:353 +#: executor/execTuples.c:521 executor/execTuples.c:712 +#, c-format +msgid "cannot retrieve a system column in this context" +msgstr "Systemspalte kann in diesem Kontext nicht ausgelesen werden" + +#: executor/execUtils.c:736 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "materialisierte Sicht »%s« wurde noch nicht befüllt" + +#: executor/execUtils.c:738 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "Verwenden Sie den Befehl REFRESH MATERIALIZED VIEW." + +#: executor/functions.c:217 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "konnte tatsächlichen Typ von Argument mit deklarierten Typ %s nicht bestimmen" + +#: executor/functions.c:515 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "COPY vom/zum Client funktioniert in einer SQL-Funktion nicht" + +#. translator: %s is a SQL statement name +#: executor/functions.c:521 +#, c-format +msgid "%s is not allowed in a SQL function" +msgstr "%s ist in SQL-Funktionen nicht erlaubt" + +#. translator: %s is a SQL statement name +#: executor/functions.c:529 executor/spi.c:1633 executor/spi.c:2485 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "%s ist in als nicht »volatile« markierten Funktionen nicht erlaubt" + +#: executor/functions.c:1442 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "SQL-Funktion »%s« Anweisung %d" + +#: executor/functions.c:1468 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "SQL-Funktion »%s« beim Start" + +#: executor/functions.c:1571 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "Aufruf von Prozeduren mit Ausgabeargumenten wird in SQL-Funktionen nicht unterstützt" + +#: executor/functions.c:1705 executor/functions.c:1743 +#: executor/functions.c:1757 executor/functions.c:1847 +#: executor/functions.c:1880 executor/functions.c:1894 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "Rückgabetyp von Funktion stimmt nicht überein; deklariert als %s" + +#: executor/functions.c:1707 +#, c-format +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "Die letzte Anweisung der Funktion muss ein SELECT oder INSERT/UPDATE/DELETE RETURNING sein." + +#: executor/functions.c:1745 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "Die letzte Anweisung muss genau eine Spalte zurückgeben." + +#: executor/functions.c:1759 +#, c-format +msgid "Actual return type is %s." +msgstr "Eigentlicher Rückgabetyp ist %s." + +#: executor/functions.c:1849 +#, c-format +msgid "Final statement returns too many columns." +msgstr "Die letzte Anweisung gibt zu viele Spalten zurück." + +#: executor/functions.c:1882 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "Die letzte Anweisung ergibt %s statt %s in Spalte %d." + +#: executor/functions.c:1896 +#, c-format +msgid "Final statement returns too few columns." +msgstr "Die letzte Anweisung gibt zu wenige Spalten zurück." + +#: executor/functions.c:1924 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "Rückgabetyp %s wird von SQL-Funktionen nicht unterstützt" + +#: executor/nodeAgg.c:3083 executor/nodeAgg.c:3092 executor/nodeAgg.c:3104 +#, c-format +msgid "unexpected EOF for tape %d: requested %zu bytes, read %zu bytes" +msgstr "unerwartetes EOF für Tape %d: %zu Bytes angefordert, %zu Bytes gelesen" + +#: executor/nodeAgg.c:3977 parser/parse_agg.c:666 parser/parse_agg.c:696 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "Aufrufe von Aggregatfunktionen können nicht geschachtelt werden" + +#: executor/nodeAgg.c:4185 executor/nodeWindowAgg.c:2836 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "Aggregatfunktion %u muss kompatiblen Eingabe- und Übergangstyp haben" + +#: executor/nodeCustom.c:145 executor/nodeCustom.c:156 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "Custom-Scan »%s« unterstützt MarkPos nicht" + +#: executor/nodeHashjoin.c:1046 executor/nodeHashjoin.c:1076 +#, c-format +msgid "could not rewind hash-join temporary file" +msgstr "konnte Position in temporärer Datei für Hash-Verbund nicht auf Anfang setzen" + +#: executor/nodeHashjoin.c:1272 executor/nodeHashjoin.c:1283 +#, c-format +msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgstr "konnte nicht aus temporärer Datei für Hash-Verbund lesen: es wurden nur %zu von %zu Bytes gelesen" + +#: executor/nodeIndexonlyscan.c:242 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "verlustbehaftete Abstandsfunktionen werden in Index-Only-Scans nicht unterstützt" + +#: executor/nodeLimit.c:374 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET darf nicht negativ sein" + +#: executor/nodeLimit.c:400 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT darf nicht negativ sein" + +#: executor/nodeMergejoin.c:1570 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "RIGHT JOIN wird nur für Merge-Verbund-fähige Verbundbedingungen unterstützt" + +#: executor/nodeMergejoin.c:1588 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "FULL JOIN wird nur für Merge-Verbund-fähige Verbundbedingungen unterstützt" + +#: executor/nodeModifyTable.c:154 +#, c-format +msgid "Query has too few columns." +msgstr "Anfrage hat zu wenige Spalten." + +#: executor/nodeModifyTable.c:1192 executor/nodeModifyTable.c:1266 +#, c-format +msgid "tuple to be deleted was already modified by an operation triggered by the current command" +msgstr "das zu löschende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" + +#: executor/nodeModifyTable.c:1441 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "ungültige ON-UPDATE-Angabe" + +#: executor/nodeModifyTable.c:1442 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "Das Ergebnistupel würde in einer anderen Partition erscheinen als das ursprüngliche Tupel." + +#: executor/nodeModifyTable.c:2038 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "Befehl in ON CONFLICT DO UPDATE kann eine Zeile nicht ein zweites Mal ändern" + +#: executor/nodeModifyTable.c:2039 +#, c-format +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." +msgstr "Stellen Sie sicher, dass keine im selben Befehl fürs Einfügen vorgesehene Zeilen doppelte Werte haben, die einen Constraint verletzen würden." + +#: executor/nodeSamplescan.c:259 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "Parameter von TABLESAMPLE darf nicht NULL sein" + +#: executor/nodeSamplescan.c:271 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "Parameter von TABLESAMPLE REPEATABLE darf nicht NULL sein" + +#: executor/nodeSubplan.c:346 executor/nodeSubplan.c:385 +#: executor/nodeSubplan.c:1159 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "als Ausdruck verwendete Unteranfrage ergab mehr als eine Zeile" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "Namensraum-URI darf nicht NULL sein" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "Zeilenfilterausdruck darf nicht NULL sein" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "Spaltenfilterausdruck darf nicht NULL sein" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "Filter für Spalte »%s« ist NULL." + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "NULL ist in Spalte »%s« nicht erlaubt" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "Moving-Aggregat-Übergangsfunktion darf nicht NULL zurückgeben" + +#: executor/nodeWindowAgg.c:2058 +#, c-format +msgid "frame starting offset must not be null" +msgstr "Frame-Start-Offset darf nicht NULL sein" + +#: executor/nodeWindowAgg.c:2071 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "Frame-Start-Offset darf nicht negativ sein" + +#: executor/nodeWindowAgg.c:2083 +#, c-format +msgid "frame ending offset must not be null" +msgstr "Frame-Ende-Offset darf nicht NULL sein" + +#: executor/nodeWindowAgg.c:2096 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "Frame-Ende-Offset darf nicht negativ sein" + +#: executor/nodeWindowAgg.c:2752 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "Aggregatfunktion %s unterstützt die Verwendung als Fensterfunktion nicht" + +#: executor/spi.c:237 executor/spi.c:302 +#, c-format +msgid "invalid transaction termination" +msgstr "ungültige Transaktionsbeendung" + +#: executor/spi.c:251 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "während eine Subtransaktion aktiv ist kann nicht committet werden" + +#: executor/spi.c:308 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "während eine Subtransaktion aktiv ist kann nicht zurückgerollt werden" + +#: executor/spi.c:380 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "Transaktion ließ nicht-leeren SPI-Stack zurück" + +#: executor/spi.c:381 executor/spi.c:443 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "Prüfen Sie, ob Aufrufe von »SPI_finish« fehlen." + +#: executor/spi.c:442 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "Subtransaktion ließ nicht-leeren SPI-Stack zurück" + +#: executor/spi.c:1495 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "Plan mit mehreren Anfragen kann nicht als Cursor geöffnet werden" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1500 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "%s kann nicht als Cursor geöffnet werden" + +#: executor/spi.c:1607 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE wird nicht unterstützt" + +#: executor/spi.c:1608 parser/analyze.c:2806 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "Scrollbare Cursor müssen READ ONLY sein." + +#: executor/spi.c:2808 +#, c-format +msgid "SQL expression \"%s\"" +msgstr "SQL-Ausdruck »%s«" + +#: executor/spi.c:2813 +#, c-format +msgid "PL/pgSQL assignment \"%s\"" +msgstr "PL/pgSQL-Zuweisung »%s«" + +#: executor/spi.c:2816 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "SQL-Anweisung »%s«" + +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "konnte Tupel nicht an Shared-Memory-Queue senden" + +#: foreign/foreign.c:220 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "Benutzerabbildung für »%s« nicht gefunden" + +#: foreign/foreign.c:672 +#, c-format +msgid "invalid option \"%s\"" +msgstr "ungültige Option »%s«" + +#: foreign/foreign.c:673 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "Gültige Optionen in diesem Zusammenhang sind: %s" + +#: gram.y:1107 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD wird nicht mehr unterstützt" + +#: gram.y:1108 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "Lassen Sie UNENCRYPTED weg, um das Passwort stattdessen in verschlüsselter Form zu speichern." + +#: gram.y:1170 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "unbekannte Rollenoption »%s«" + +#: gram.y:1417 gram.y:1432 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS kann keine Schemaelemente enthalten" + +#: gram.y:1578 +#, c-format +msgid "current database cannot be changed" +msgstr "aktuelle Datenbank kann nicht geändert werden" + +#: gram.y:1702 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "Zeitzonenintervall muss HOUR oder HOUR TO MINUTE sein" + +#: gram.y:2270 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "Spaltennummer muss im Bereich 1 bis %d sein" + +#: gram.y:2811 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "Sequenzoption »%s« wird hier nicht unterstützt" + +#: gram.y:2840 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "Modulus für Hashpartition mehrmals angegeben" + +#: gram.y:2849 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "Rest für Hashpartition mehrmals angegeben" + +#: gram.y:2856 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "unbekannte Hashpartitionsbegrenzungsangabe »%s«" + +#: gram.y:2864 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "Modulus für Hashpartition muss angegeben werden" + +#: gram.y:2868 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "Rest für Hashpartition muss angegeben werden" + +#: gram.y:3069 gram.y:3102 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "STDIN/STDOUT sind nicht mit PROGRAM erlaubt" + +#: gram.y:3075 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "mit COPY TO ist keine WHERE-Klausel erlaubt" + +#: gram.y:3407 gram.y:3414 gram.y:11689 gram.y:11697 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "die Verwendung von GLOBAL beim Erzeugen einer temporären Tabelle ist veraltet" + +#: gram.y:3665 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "für eine generierte Spalte muss GENERATED ALWAYS angegeben werden" + +#: gram.y:3933 utils/adt/ri_triggers.c:2032 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL ist noch nicht implementiert" + +#: gram.y:4634 +#, c-format +msgid "CREATE EXTENSION ... FROM is no longer supported" +msgstr "CREATE EXTENSION ... FROM wird nicht mehr unterstützt" + +#: gram.y:5297 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "unbekannte Zeilensicherheitsoption »%s«" + +#: gram.y:5298 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "Aktuell werden nur PERMISSIVE und RESTRICTIVE unterstützt." + +#: gram.y:5380 +#, c-format +msgid "CREATE OR REPLACE CONSTRAINT TRIGGER is not supported" +msgstr "CREATE OR REPLACE CONSTRAINT TRIGGER wird nicht unterstützt" + +#: gram.y:5417 +msgid "duplicate trigger events specified" +msgstr "mehrere Trigger-Ereignisse angegeben" + +#: gram.y:5558 parser/parse_utilcmd.c:3734 parser/parse_utilcmd.c:3760 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "Constraint, der als INITIALLY DEFERRED deklariert wurde, muss DEFERRABLE sein" + +#: gram.y:5565 +#, c-format +msgid "conflicting constraint properties" +msgstr "widersprüchliche Constraint-Eigentschaften" + +#: gram.y:5661 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION ist noch nicht implementiert" + +#: gram.y:6044 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK wird nicht mehr benötigt" + +#: gram.y:6045 +#, c-format +msgid "Update your data type." +msgstr "Aktualisieren Sie Ihren Datentyp." + +#: gram.y:7770 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "Aggregatfunktionen können keine OUT-Argumente haben" + +#: gram.y:8212 utils/adt/regproc.c:709 utils/adt/regproc.c:750 +#, c-format +msgid "missing argument" +msgstr "Argument fehlt" + +#: gram.y:8213 utils/adt/regproc.c:710 utils/adt/regproc.c:751 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "Verwenden Sie NONE, um das fehlende Argument eines unären Operators anzugeben." + +#: gram.y:10152 gram.y:10170 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION wird für rekursive Sichten nicht unterstützt" + +#: gram.y:11826 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "Syntax LIMIT x,y wird nicht unterstützt" + +#: gram.y:11827 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "Verwenden Sie die getrennten Klauseln LIMIT und OFFSET." + +#: gram.y:12165 gram.y:12190 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "VALUES in FROM muss Aliasnamen erhalten" + +#: gram.y:12166 gram.y:12191 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "Zum Beispiel FROM (VALUES ...) [AS] xyz." + +#: gram.y:12171 gram.y:12196 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "Unteranfrage in FROM muss Aliasnamen erhalten" + +#: gram.y:12172 gram.y:12197 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "Zum Beispiel FROM (SELECT ...) [AS] xyz." + +#: gram.y:12692 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "nur ein DEFAULT-Wert ist erlaubt" + +#: gram.y:12701 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "nur ein PATH-Wert pro Spalte ist erlaubt" + +#: gram.y:12710 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "widersprüchliche oder überflüssige NULL/NOT NULL-Deklarationen für Spalte »%s«" + +#: gram.y:12719 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "unbekannte Spaltenoption »%s«" + +#: gram.y:12973 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "Präzision von Typ float muss mindestens 1 Bit sein" + +#: gram.y:12982 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "Präzision von Typ float muss weniger als 54 Bits sein" + +#: gram.y:13480 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "falsche Anzahl Parameter auf linker Seite von OVERLAPS-Ausdruck" + +#: gram.y:13485 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "falsche Anzahl Parameter auf rechter Seite von OVERLAPS-Ausdruck" + +#: gram.y:13653 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "UNIQUE-Prädikat ist noch nicht implementiert" + +#: gram.y:14012 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "in WITHIN GROUP können nicht mehrere ORDER-BY-Klauseln verwendet werden" + +#: gram.y:14017 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "DISTINCT kann nicht mit WITHIN GROUP verwendet werden" + +#: gram.y:14022 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "VARIADIC kann nicht mit WITHIN GROUP verwendet werden" + +#: gram.y:14546 gram.y:14569 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "Frame-Beginn kann nicht UNBOUNDED FOLLOWING sein" + +#: gram.y:14551 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "Frame der in der folgenden Zeile beginnt kann nicht in der aktuellen Zeile enden" + +#: gram.y:14574 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "Frame-Ende kann nicht UNBOUNDED PRECEDING sein" + +#: gram.y:14580 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "Frame der in der aktuellen Zeile beginnt kann keine vorhergehenden Zeilen haben" + +#: gram.y:14587 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "Frame der in der folgenden Zeile beginnt kann keine vorhergehenden Zeilen haben" + +#: gram.y:15219 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "Typmodifikator kann keinen Parameternamen haben" + +#: gram.y:15225 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "Typmodifikator kann kein ORDER BY haben" + +#: gram.y:15290 gram.y:15297 gram.y:15304 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s kann hier nicht als Rollenname verwendet werden" + +#: gram.y:15393 gram.y:16825 +#, c-format +msgid "WITH TIES cannot be specified without ORDER BY clause" +msgstr "WITH TIES kann nicht ohne ORDER-BY-Klausel angegeben werden" + +#: gram.y:16501 gram.y:16690 +msgid "improper use of \"*\"" +msgstr "unzulässige Verwendung von »*«" + +#: gram.y:16653 gram.y:16670 tsearch/spell.c:982 tsearch/spell.c:999 +#: tsearch/spell.c:1016 tsearch/spell.c:1033 tsearch/spell.c:1098 +#, c-format +msgid "syntax error" +msgstr "Syntaxfehler" + +#: gram.y:16755 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "eine Ordered-Set-Aggregatfunktion mit einem direkten VARIADIC-Argument muss ein aggregiertes VARIADIC-Argument des selben Datentyps haben" + +#: gram.y:16792 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "mehrere ORDER-BY-Klauseln sind nicht erlaubt" + +#: gram.y:16803 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "mehrere OFFSET-Klauseln sind nicht erlaubt" + +#: gram.y:16812 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "mehrere LIMIT-Klauseln sind nicht erlaubt" + +#: gram.y:16821 +#, c-format +msgid "multiple limit options not allowed" +msgstr "mehrere Limit-Optionen sind nicht erlaubt" + +#: gram.y:16833 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "mehrere WITH-Klauseln sind nicht erlaubt" + +#: gram.y:17025 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "OUT- und INOUT-Argumente sind in TABLE-Funktionen nicht erlaubt" + +#: gram.y:17121 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "mehrere COLLATE-Klauseln sind nicht erlaubt" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17159 gram.y:17172 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "%s-Constraints können nicht als DEFERRABLE markiert werden" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17185 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "%s-Constraints können nicht als NOT VALID markiert werden" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17198 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "%s-Constraints können nicht als NO INHERIT markiert werden" + +#: guc-file.l:314 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %d" +msgstr "unbekannter Konfigurationsparameter »%s« in Datei »%s« Zeile %d" + +#: guc-file.l:351 utils/misc/guc.c:7360 utils/misc/guc.c:7558 +#: utils/misc/guc.c:7652 utils/misc/guc.c:7746 utils/misc/guc.c:7866 +#: utils/misc/guc.c:7965 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "Parameter »%s« kann nicht geändert werden, ohne den Server neu zu starten" + +#: guc-file.l:387 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "Parameter »%s« wurde aus Konfigurationsdatei entfernt, wird auf Standardwert zurückgesetzt" + +#: guc-file.l:453 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "Parameter »%s« auf »%s« gesetzt" + +#: guc-file.l:495 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "Konfigurationsdatei »%s« enthält Fehler" + +#: guc-file.l:500 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "Konfigurationsdatei »%s« enthält Fehler; nicht betroffene Änderungen wurden durchgeführt" + +#: guc-file.l:505 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "Konfigurationsdatei »%s« enthält Fehler; keine Änderungen wurden durchgeführt" + +#: guc-file.l:577 +#, c-format +msgid "empty configuration file name: \"%s\"" +msgstr "leerer Konfigurationsdateiname: »%s«" + +#: guc-file.l:594 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "konnte Konfigurationsdatei »%s« nicht öffnen: maximale Verschachtelungstiefe überschritten" + +#: guc-file.l:614 +#, c-format +msgid "configuration file recursion in \"%s\"" +msgstr "Konfigurationsdateirekursion in »%s«" + +#: guc-file.l:630 libpq/hba.c:2251 libpq/hba.c:2665 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "konnte Konfigurationsdatei »%s« nicht öffnen: %m" + +#: guc-file.l:641 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "fehlende Konfigurationsdatei »%s« wird übersprungen" + +#: guc-file.l:895 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "Syntaxfehler in Datei »%s«, Zeile %u, am Ende der Zeile" + +#: guc-file.l:905 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "Syntaxfehler in Datei »%s«, Zeile %u, bei »%s«" + +#: guc-file.l:925 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "zu viele Syntaxfehler gefunden, Datei »%s« wird aufgegeben" + +#: guc-file.l:980 +#, c-format +msgid "empty configuration directory name: \"%s\"" +msgstr "leerer Konfigurationsverzeichnisname: »%s«" + +#: guc-file.l:999 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "konnte Konfigurationsverzeichnis »%s« nicht öffnen: %m" + +#: jit/jit.c:205 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:417 +#: utils/fmgr/dfmgr.c:465 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "konnte nicht auf Datei »%s« zugreifen: %m" + +#: jsonpath_gram.y:528 jsonpath_scan.l:519 jsonpath_scan.l:530 +#: jsonpath_scan.l:540 jsonpath_scan.l:582 utils/adt/encode.c:435 +#: utils/adt/encode.c:501 utils/adt/jsonfuncs.c:623 utils/adt/varlena.c:339 +#: utils/adt/varlena.c:380 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "ungültige Eingabesyntax für Typ %s" + +#: jsonpath_gram.y:529 +#, c-format +msgid "unrecognized flag character \"%.*s\" in LIKE_REGEX predicate" +msgstr "unbekanntes Flag-Zeichen »%.*s« in LIKE_REGEX-Prädikat" + +#: jsonpath_gram.y:583 +#, c-format +msgid "XQuery \"x\" flag (expanded regular expressions) is not implemented" +msgstr "XQuery-Flag »x« (expanded regular expression) ist nicht implementiert" + +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:286 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "%s am Ende der jsonpath-Eingabe" + +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:293 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s bei »%s« in jsonpath-Eingabe" + +#: jsonpath_scan.l:498 utils/adt/jsonfuncs.c:617 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "nicht unterstützte Unicode-Escape-Sequenz" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Fehler bei DSA-Anfrage mit Größe %zu." + +#: libpq/auth-scram.c:249 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "Client hat einen ungültigen SASL-Authentifizierungsmechanismums gewählt" + +#: libpq/auth-scram.c:270 libpq/auth-scram.c:510 libpq/auth-scram.c:521 +#, c-format +msgid "invalid SCRAM secret for user \"%s\"" +msgstr "ungültiges SCRAM-Geheimnis für Benutzer »%s«" + +#: libpq/auth-scram.c:281 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM secret." +msgstr "Benutzer »%s« hat kein gültiges SCRAM-Geheimnis." + +#: libpq/auth-scram.c:359 libpq/auth-scram.c:364 libpq/auth-scram.c:701 +#: libpq/auth-scram.c:709 libpq/auth-scram.c:814 libpq/auth-scram.c:827 +#: libpq/auth-scram.c:837 libpq/auth-scram.c:945 libpq/auth-scram.c:952 +#: libpq/auth-scram.c:967 libpq/auth-scram.c:982 libpq/auth-scram.c:996 +#: libpq/auth-scram.c:1014 libpq/auth-scram.c:1029 libpq/auth-scram.c:1340 +#: libpq/auth-scram.c:1348 +#, c-format +msgid "malformed SCRAM message" +msgstr "fehlerhafte SCRAM-Nachricht" + +#: libpq/auth-scram.c:360 +#, c-format +msgid "The message is empty." +msgstr "Die Nachricht ist leer." + +#: libpq/auth-scram.c:365 +#, c-format +msgid "Message length does not match input length." +msgstr "Länge der Nachricht stimmt nicht mit Länge der Eingabe überein." + +#: libpq/auth-scram.c:397 +#, c-format +msgid "invalid SCRAM response" +msgstr "ungültige SCRAM-Antwort" + +#: libpq/auth-scram.c:398 +#, c-format +msgid "Nonce does not match." +msgstr "Nonce stimmt nicht überein." + +#: libpq/auth-scram.c:472 +#, c-format +msgid "could not generate random salt" +msgstr "konnte zufälliges Salt nicht erzeugen" + +#: libpq/auth-scram.c:702 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Attribut »%c« wurde erwartet, aber »%s« wurde gefunden." + +#: libpq/auth-scram.c:710 libpq/auth-scram.c:838 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Zeichen »=« für Attribut »%c« wurde erwartet." + +#: libpq/auth-scram.c:815 +#, c-format +msgid "Attribute expected, but found end of string." +msgstr "Attribut wurde erwartet, aber Ende der Zeichenkette wurde gefunden." + +#: libpq/auth-scram.c:828 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Attribut wurde erwartet, aber ungültiges Zeichen »%s« wurde gefunden." + +#: libpq/auth-scram.c:946 libpq/auth-scram.c:968 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "Der Client hat SCRAM-SHA-256-PLUS gewählt, aber die SCRAM-Nachricht enthielt keine Channel-Binding-Daten." + +#: libpq/auth-scram.c:953 libpq/auth-scram.c:983 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Komma wurde erwartet, aber Zeichen »%s« wurde gefunden." + +#: libpq/auth-scram.c:974 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "Fehler bei der Aushandlung von SCRAM-Channel-Binding" + +#: libpq/auth-scram.c:975 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "Der Client unterstützt SCRAM-Channel-Binding aber glaubt dass der Server es nicht tut. Dieser Server unterstützt jedoch Channel-Binding." + +#: libpq/auth-scram.c:997 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "Der Client hat SCRAM-SHA-256 ohne Channel-Binding gewählt, aber die SCRAM-Nachricht enthält Channel-Binding-Daten." + +#: libpq/auth-scram.c:1008 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "nicht unterstützter SCRAM-Channel-Binding-Typ »%s«" + +#: libpq/auth-scram.c:1015 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Unerwartetes Channel-Binding-Flag »%s«." + +#: libpq/auth-scram.c:1025 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "Client verwendet Autorisierungsidentität, was nicht unterstützt wird" + +#: libpq/auth-scram.c:1030 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Unerwartetes Attribut »%s« in »client-first-message«." + +#: libpq/auth-scram.c:1046 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "Client verlangt eine nicht unterstützte SCRAM-Erweiterung" + +#: libpq/auth-scram.c:1060 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "nicht druckbare Zeichen in SCRAM-Nonce" + +#: libpq/auth-scram.c:1188 +#, c-format +msgid "could not generate random nonce" +msgstr "konnte zufällige Nonce nicht erzeugen" + +#: libpq/auth-scram.c:1198 +#, c-format +msgid "could not encode random nonce" +msgstr "konnte zufällige Nonce nicht kodieren" + +#: libpq/auth-scram.c:1304 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "SCRAM-Channel-Binding-Prüfung fehlgeschlagen" + +#: libpq/auth-scram.c:1322 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "unerwartetes SCRAM-Channel-Binding-Attribut in »client-final-message«" + +#: libpq/auth-scram.c:1341 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "Fehlerhafter Proof in »client-final-message«." + +#: libpq/auth-scram.c:1349 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Müll am Ende der »client-final-message« gefunden." + +#: libpq/auth.c:284 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "Authentifizierung für Benutzer »%s« fehlgeschlagen: Host abgelehnt" + +#: libpq/auth.c:287 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "»trust«-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:290 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "Ident-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:293 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "Peer-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:298 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "Passwort-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:303 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "GSSAPI-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:306 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "SSPI-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:309 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "PAM-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:312 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "BSD-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:315 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "LDAP-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:318 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:321 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "RADIUS-Authentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:324 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "Authentifizierung für Benutzer »%s« fehlgeschlagen: ungültige Authentifizierungsmethode" + +#: libpq/auth.c:328 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "Verbindung stimmte mit pg_hba.conf-Zeile %d überein: »%s«" + +#: libpq/auth.c:371 +#, fuzzy, c-format +#| msgid "Connections and Authentication" +msgid "connection was re-authenticated" +msgstr "Verbindungen und Authentifizierung" + +#: libpq/auth.c:372 +#, c-format +msgid "previous ID: \"%s\"; new ID: \"%s\"" +msgstr "" + +#: libpq/auth.c:381 +#, c-format +msgid "connection authenticated: identity=\"%s\" method=%s (%s:%d)" +msgstr "" + +#: libpq/auth.c:420 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "Client-Zertifikate können nur überprüft werden, wenn Wurzelzertifikat verfügbar ist" + +#: libpq/auth.c:431 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "Verbindung erfordert ein gültiges Client-Zertifikat" + +#: libpq/auth.c:462 libpq/auth.c:508 +msgid "GSS encryption" +msgstr "GSS-Verschlüsselung" + +#: libpq/auth.c:465 libpq/auth.c:511 +msgid "SSL encryption" +msgstr "SSL-Verschlüsselung" + +#: libpq/auth.c:467 libpq/auth.c:513 +msgid "no encryption" +msgstr "keine Verschlüsselung" + +#. translator: last %s describes encryption state +#: libpq/auth.c:473 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "pg_hba.conf lehnt Replikationsverbindung ab für Host »%s«, Benutzer »%s«, %s" + +#. translator: last %s describes encryption state +#: libpq/auth.c:480 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf lehnt Verbindung ab für Host »%s«, Benutzer »%s«, Datenbank »%s«, %s" + +#: libpq/auth.c:518 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung stimmt überein." + +#: libpq/auth.c:521 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung nicht geprüft." + +#: libpq/auth.c:524 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung stimmt nicht überein." + +#: libpq/auth.c:527 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "Konnte Client-Hostnamen »%s« nicht in IP-Adresse übersetzen: %s." + +#: libpq/auth.c:532 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "Konnte Client-IP-Adresse nicht in einen Hostnamen auflösen: %s." + +#. translator: last %s describes encryption state +#: libpq/auth.c:540 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "kein pg_hba.conf-Eintrag für Replikationsverbindung von Host »%s«, Benutzer »%s«, %s" + +#. translator: last %s describes encryption state +#: libpq/auth.c:548 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "kein pg_hba.conf-Eintrag für Host »%s«, Benutzer »%s«, Datenbank »%s«, %s" + +#: libpq/auth.c:721 +#, c-format +msgid "expected password response, got message type %d" +msgstr "Passwort-Antwort erwartet, Message-Typ %d empfangen" + +#: libpq/auth.c:742 +#, c-format +msgid "invalid password packet size" +msgstr "ungültige Größe des Passwortpakets" + +#: libpq/auth.c:760 +#, c-format +msgid "empty password returned by client" +msgstr "Client gab leeres Passwort zurück" + +#: libpq/auth.c:887 libpq/hba.c:1366 +#, c-format +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "MD5-Authentifizierung wird nicht unterstützt, wenn »db_user_namespace« angeschaltet ist" + +#: libpq/auth.c:893 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "konnte zufälliges MD5-Salt nicht erzeugen" + +#: libpq/auth.c:959 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "SASL-Antwort erwartet, Message-Typ %d empfangen" + +#: libpq/auth.c:1088 libpq/be-secure-gssapi.c:535 +#, c-format +msgid "could not set environment: %m" +msgstr "konnte Umgebung nicht setzen: %m" + +#: libpq/auth.c:1124 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "GSS-Antwort erwartet, Message-Typ %d empfangen" + +#: libpq/auth.c:1184 +msgid "accepting GSS security context failed" +msgstr "Annahme des GSS-Sicherheitskontexts fehlgeschlagen" + +#: libpq/auth.c:1224 +msgid "retrieving GSS user name failed" +msgstr "Abfrage des GSS-Benutzernamens fehlgeschlagen" + +#: libpq/auth.c:1365 +msgid "could not acquire SSPI credentials" +msgstr "konnte SSPI-Credentials nicht erhalten" + +#: libpq/auth.c:1390 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "SSPI-Antwort erwartet, Message-Typ %d empfangen" + +#: libpq/auth.c:1468 +msgid "could not accept SSPI security context" +msgstr "konnte SSPI-Sicherheitskontext nicht akzeptieren" + +#: libpq/auth.c:1530 +msgid "could not get token from SSPI security context" +msgstr "konnte kein Token vom SSPI-Sicherheitskontext erhalten" + +#: libpq/auth.c:1669 libpq/auth.c:1688 +#, c-format +msgid "could not translate name" +msgstr "konnte Namen nicht umwandeln" + +#: libpq/auth.c:1701 +#, c-format +msgid "realm name too long" +msgstr "Realm-Name zu lang" + +#: libpq/auth.c:1716 +#, c-format +msgid "translated account name too long" +msgstr "umgewandelter Account-Name zu lang" + +#: libpq/auth.c:1897 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "konnte Socket für Ident-Verbindung nicht erzeugen: %m" + +#: libpq/auth.c:1912 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "konnte nicht mit lokaler Adresse »%s« verbinden: %m" + +#: libpq/auth.c:1924 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "konnte nicht mit Ident-Server auf Adresse »%s«, Port %s verbinden: %m" + +#: libpq/auth.c:1946 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "konnte Anfrage an Ident-Server auf Adresse »%s«, Port %s nicht senden: %m" + +#: libpq/auth.c:1963 +#, c-format +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "konnte Antwort von Ident-Server auf Adresse »%s«, Port %s nicht empfangen: %m" + +#: libpq/auth.c:1973 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "ungültig formatierte Antwort vom Ident-Server: »%s«" + +#: libpq/auth.c:2026 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "Peer-Authentifizierung wird auf dieser Plattform nicht unterstützt" + +#: libpq/auth.c:2030 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "konnte Credentials von Gegenstelle nicht ermitteln: %m" + +#: libpq/auth.c:2042 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "konnte lokale Benutzer-ID %ld nicht nachschlagen: %s" + +#: libpq/auth.c:2143 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "Fehler von der unteren PAM-Ebene: %s" + +#: libpq/auth.c:2154 +#, fuzzy, c-format +#| msgid "unsupported format code: %d" +msgid "unsupported PAM conversation %d/\"%s\"" +msgstr "nicht unterstützter Formatcode: %d" + +#: libpq/auth.c:2214 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "konnte PAM-Authenticator nicht erzeugen: %s" + +#: libpq/auth.c:2225 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER) fehlgeschlagen: %s" + +#: libpq/auth.c:2257 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST) fehlgeschlagen: %s" + +#: libpq/auth.c:2269 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "pam_set_item(PAM_CONV) fehlgeschlagen: %s" + +#: libpq/auth.c:2282 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "pam_authenticate fehlgeschlagen: %s" + +#: libpq/auth.c:2295 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmt fehlgeschlagen: %s" + +#: libpq/auth.c:2306 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "konnte PAM-Authenticator nicht freigeben: %s" + +#: libpq/auth.c:2386 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "konnte LDAP nicht initialisieren: Fehlercode %d" + +#: libpq/auth.c:2423 +#, c-format +msgid "could not extract domain name from ldapbasedn" +msgstr "konnte keinen Domain-Namen aus ldapbasedn herauslesen" + +#: libpq/auth.c:2431 +#, c-format +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "LDAP-Authentifizierung konnte keine DNS-SRV-Einträge für »%s« finden" + +#: libpq/auth.c:2433 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "Geben Sie einen LDAP-Servernamen explizit an." + +#: libpq/auth.c:2485 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "konnte LDAP nicht initialisieren: %s" + +#: libpq/auth.c:2495 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ldaps wird mit dieser LDAP-Bibliothek nicht unterstützt" + +#: libpq/auth.c:2503 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "konnte LDAP nicht initialisieren: %m" + +#: libpq/auth.c:2513 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "konnte LDAP-Protokollversion nicht setzen: %s" + +#: libpq/auth.c:2553 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "konnte Funktion _ldap_start_tls_sA in wldap32.dll nicht laden" + +#: libpq/auth.c:2554 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "LDAP über SSL wird auf dieser Plattform nicht unterstützt." + +#: libpq/auth.c:2570 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "konnte LDAP-TLS-Sitzung nicht starten: %s" + +#: libpq/auth.c:2641 +#, c-format +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "LDAP-Server nicht angegeben, und kein ldapbasedn" + +#: libpq/auth.c:2648 +#, c-format +msgid "LDAP server not specified" +msgstr "LDAP-Server nicht angegeben" + +#: libpq/auth.c:2710 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "ungültiges Zeichen im Benutzernamen für LDAP-Authentifizierung" + +#: libpq/auth.c:2727 +#, c-format +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "erstes LDAP-Binden für ldapbinddn »%s« auf Server »%s« fehlgeschlagen: %s" + +#: libpq/auth.c:2756 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "konnte LDAP nicht mit Filter »%s« auf Server »%s« durchsuchen: %s" + +#: libpq/auth.c:2770 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "LDAP-Benutzer »%s« existiert nicht" + +#: libpq/auth.c:2771 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "LDAP-Suche nach Filter »%s« auf Server »%s« gab keine Einträge zurück." + +#: libpq/auth.c:2775 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "LDAP-Benutzer »%s« ist nicht eindeutig" + +#: libpq/auth.c:2776 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "LDAP-Suche nach Filter »%s« auf Server »%s« gab %d Eintrag zurück." +msgstr[1] "LDAP-Suche nach Filter »%s« auf Server »%s« gab %d Einträge zurück." + +#: libpq/auth.c:2796 +#, c-format +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "konnte DN fũr den ersten Treffer für »%s« auf Server »%s« nicht lesen: %s" + +#: libpq/auth.c:2817 +#, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "Losbinden fehlgeschlagen nach Suche nach Benutzer »%s« auf Server »%s«" + +#: libpq/auth.c:2848 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "LDAP-Login fehlgeschlagen für Benutzer »%s« auf Server »%s«: %s" + +#: libpq/auth.c:2880 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "LDAP-Diagnostik: %s" + +#: libpq/auth.c:2918 +#, c-format +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen: Client-Zertifikat enthält keinen Benutzernamen" + +#: libpq/auth.c:2939 +#, fuzzy, c-format +#| msgid "certificate authentication failed for user \"%s\"" +msgid "certificate authentication failed for user \"%s\": unable to retrieve subject DN" +msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen" + +#: libpq/auth.c:2962 +#, c-format +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch" +msgstr "Zertifikatüberprüfung (clientcert=verify=full) für Benutzer »%s« fehlgeschlagen: DN stimmt nicht überein" + +#: libpq/auth.c:2967 +#, c-format +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" +msgstr "Zertifikatüberprüfung (clientcert=verify=full) für Benutzer »%s« fehlgeschlagen: CN stimmt nicht überein" + +#: libpq/auth.c:3069 +#, c-format +msgid "RADIUS server not specified" +msgstr "RADIUS-Server nicht angegeben" + +#: libpq/auth.c:3076 +#, c-format +msgid "RADIUS secret not specified" +msgstr "RADIUS-Geheimnis nicht angegeben" + +#: libpq/auth.c:3090 +#, c-format +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "RADIUS-Authentifizierung unterstützt keine Passwörter länger als %d Zeichen" + +#: libpq/auth.c:3197 libpq/hba.c:2004 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "konnte RADIUS-Servername »%s« nicht in Adresse übersetzen: %s" + +#: libpq/auth.c:3211 +#, c-format +msgid "could not generate random encryption vector" +msgstr "konnte zufälligen Verschlüsselungsvektor nicht erzeugen" + +#: libpq/auth.c:3245 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "konnte MD5-Verschlüsselung des Passworts nicht durchführen" + +#: libpq/auth.c:3271 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "konnte RADIUS-Socket nicht erstellen: %m" + +#: libpq/auth.c:3293 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "konnte lokales RADIUS-Socket nicht binden: %m" + +#: libpq/auth.c:3303 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "konnte RADIUS-Paket nicht senden: %m" + +#: libpq/auth.c:3336 libpq/auth.c:3362 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "Zeitüberschreitung beim Warten auf RADIUS-Antwort von %s" + +#: libpq/auth.c:3355 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "konnte Status des RADIUS-Sockets nicht prüfen: %m" + +#: libpq/auth.c:3385 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "konnte RADIUS-Antwort nicht lesen: %m" + +#: libpq/auth.c:3398 libpq/auth.c:3402 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "RADIUS-Antwort von %s wurde von falschem Port gesendet: %d" + +#: libpq/auth.c:3411 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "RADIUS-Antwort von %s zu kurz: %d" + +#: libpq/auth.c:3418 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "RADIUS-Antwort von %s hat verfälschte Länge: %d (tatsächliche Länge %d)" + +#: libpq/auth.c:3426 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "RADIUS-Antwort von %s unterscheidet sich von Anfrage: %d (sollte %d sein)" + +#: libpq/auth.c:3451 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "konnte MD5-Verschlüsselung des empfangenen Pakets nicht durchführen" + +#: libpq/auth.c:3460 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "RADIUS-Antwort von %s hat falsche MD5-Signatur" + +#: libpq/auth.c:3478 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "RADIUS-Antwort von %s hat ungültigen Code (%d) für Benutzer »%s«" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:553 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "ungültiger Large-Object-Deskriptor: %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "Large-Objekt-Deskriptor %d wurde nicht zum Lesen geöffnet" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:560 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "Large-Objekt-Deskriptor %d wurde nicht zum Schreiben geöffnet" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "Ergebnis von lo_lseek ist außerhalb des gültigen Bereichs für Large-Object-Deskriptor %d" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "Ergebnis von lo_tell ist außerhalb des gültigen Bereichs für Large-Object-Deskriptor: %d" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "konnte Serverdatei »%s« nicht öffnen: %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "konnte Serverdatei »%s« nicht lesen: %m" + +#: libpq/be-fsstubs.c:514 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "konnte Serverdatei »%s« nicht erstellen: %m" + +#: libpq/be-fsstubs.c:526 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "konnte Serverdatei »%s« nicht schreiben: %m" + +#: libpq/be-fsstubs.c:760 +#, c-format +msgid "large object read request is too large" +msgstr "Large-Object-Leseaufforderung ist zu groß" + +#: libpq/be-fsstubs.c:802 utils/adt/genfile.c:267 utils/adt/genfile.c:306 +#: utils/adt/genfile.c:342 +#, c-format +msgid "requested length cannot be negative" +msgstr "verlangte Länge darf nicht negativ sein" + +#: libpq/be-fsstubs.c:855 storage/large_object/inv_api.c:297 +#: storage/large_object/inv_api.c:309 storage/large_object/inv_api.c:513 +#: storage/large_object/inv_api.c:624 storage/large_object/inv_api.c:814 +#, c-format +msgid "permission denied for large object %u" +msgstr "keine Berechtigung für Large Object %u" + +#: libpq/be-secure-common.c:93 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "konnte nicht von Befehl »%s« lesen: %m" + +#: libpq/be-secure-common.c:113 +#, c-format +msgid "command \"%s\" failed" +msgstr "Befehl »%s« fehlgeschlagen" + +#: libpq/be-secure-common.c:141 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "konnte auf private Schlüsseldatei »%s« nicht zugreifen: %m" + +#: libpq/be-secure-common.c:150 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "private Schlüsseldatei »%s« ist keine normale Datei" + +#: libpq/be-secure-common.c:165 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "private Schlüsseldatei »%s« muss als Eigentümer den Datenbankbenutzer oder »root« haben" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "private Schlüsseldatei »%s« erlaubt Zugriff von Gruppe oder Welt" + +#: libpq/be-secure-common.c:190 +#, c-format +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "Dateirechte müssen u=rw (0600) oder weniger sein, wenn der Eigentümer der Datenbankbenutzer ist, oder u=rw,g=r (0640) oder weniger, wenn der Eigentümer »root« ist." + +#: libpq/be-secure-gssapi.c:204 +msgid "GSSAPI wrap error" +msgstr "GSSAPI-Wrap-Fehler" + +#: libpq/be-secure-gssapi.c:211 +#, c-format +msgid "outgoing GSSAPI message would not use confidentiality" +msgstr "ausgehende GSSAPI-Nachricht würde keine Vertraulichkeit verwenden" + +#: libpq/be-secure-gssapi.c:218 libpq/be-secure-gssapi.c:622 +#, c-format +msgid "server tried to send oversize GSSAPI packet (%zu > %zu)" +msgstr "Server versuchte übergroßes GSSAPI-Paket zu senden (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:351 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "übergroßes GSSAPI-Paket vom Client gesendet (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:389 +msgid "GSSAPI unwrap error" +msgstr "GSSAPI-Unwrap-Fehler" + +#: libpq/be-secure-gssapi.c:396 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "eingehende GSSAPI-Nachricht verwendete keine Vertraulichkeit" + +#: libpq/be-secure-gssapi.c:570 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "übergroßes GSSAPI-Paket vom Client gesendet (%zu > %d)" + +#: libpq/be-secure-gssapi.c:594 +msgid "could not accept GSSAPI security context" +msgstr "konnte GSSAPI-Sicherheitskontext nicht akzeptieren" + +#: libpq/be-secure-gssapi.c:689 +msgid "GSSAPI size check error" +msgstr "GSSAPI-Fehler bei der Größenprüfung" + +#: libpq/be-secure-openssl.c:115 +#, c-format +msgid "could not create SSL context: %s" +msgstr "konnte SSL-Kontext nicht erzeugen: %s" + +#: libpq/be-secure-openssl.c:141 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "konnte Serverzertifikatsdatei »%s« nicht laden: %s" + +#: libpq/be-secure-openssl.c:161 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "private Schlüsseldatei »%s« kann nicht neu geladen werden, weil sie eine Passphrase benötigt" + +#: libpq/be-secure-openssl.c:166 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "konnte private Schlüsseldatei »%s« nicht laden: %s" + +#: libpq/be-secure-openssl.c:175 +#, c-format +msgid "check of private key failed: %s" +msgstr "Überprüfung des privaten Schlüssels fehlgeschlagen: %s" + +#. translator: first %s is a GUC option name, second %s is its value +#: libpq/be-secure-openssl.c:188 libpq/be-secure-openssl.c:211 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "»%s«-Wert »%s« wird von dieser Installation nicht unterstützt" + +#: libpq/be-secure-openssl.c:198 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "konnte minimale SSL-Protokollversion nicht setzen" + +#: libpq/be-secure-openssl.c:221 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "konnte maximale SSL-Protokollversion nicht setzen" + +#: libpq/be-secure-openssl.c:237 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "konnte SSL-Protokollversionsbereich nicht setzen" + +#: libpq/be-secure-openssl.c:238 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "»%s« kann nicht höher als »%s« sein" + +#: libpq/be-secure-openssl.c:275 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "konnte Cipher-Liste nicht setzen (keine gültigen Ciphers verfügbar)" + +#: libpq/be-secure-openssl.c:295 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "konnte Root-Zertifikat-Datei »%s« nicht laden: %s" + +#: libpq/be-secure-openssl.c:344 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "konnte SSL-Certificate-Revocation-List-Datei »%s« nicht laden: %s" + +#: libpq/be-secure-openssl.c:352 +#, c-format +msgid "could not load SSL certificate revocation list directory \"%s\": %s" +msgstr "konnte SSL-Certificate-Revocation-List-Verzeichnis »%s« nicht laden: %s" + +#: libpq/be-secure-openssl.c:360 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s" +msgstr "konnte SSL-Certificate-Revocation-List-Datei »%s« oder -Verzeichnis »%s« nicht laden: %s" + +#: libpq/be-secure-openssl.c:418 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "konnte SSL-Verbindung nicht initialisieren: SSL-Kontext nicht eingerichtet" + +#: libpq/be-secure-openssl.c:429 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "konnte SSL-Verbindung nicht initialisieren: %s" + +#: libpq/be-secure-openssl.c:437 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "konnte SSL-Socket nicht setzen: %s" + +#: libpq/be-secure-openssl.c:492 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "konnte SSL-Verbindung nicht annehmen: %m" + +#: libpq/be-secure-openssl.c:496 libpq/be-secure-openssl.c:549 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "konnte SSL-Verbindung nicht annehmen: EOF entdeckt" + +#: libpq/be-secure-openssl.c:535 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "konnte SSL-Verbindung nicht annehmen: %s" + +#: libpq/be-secure-openssl.c:538 +#, c-format +msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." +msgstr "Das zeigt möglicherweise an, dass der Client keine SSL-Protokollversion zwischen %s und %s unterstützt." + +#: libpq/be-secure-openssl.c:554 libpq/be-secure-openssl.c:734 +#: libpq/be-secure-openssl.c:798 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "unbekannter SSL-Fehlercode: %d" + +#: libpq/be-secure-openssl.c:600 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "Common-Name im SSL-Zertifikat enthält Null-Byte" + +#: libpq/be-secure-openssl.c:640 +#, c-format +msgid "SSL certificate's distinguished name contains embedded null" +msgstr "Distinguished Name im SSL-Zertifikat enthält Null-Byte" + +#: libpq/be-secure-openssl.c:723 libpq/be-secure-openssl.c:782 +#, c-format +msgid "SSL error: %s" +msgstr "SSL-Fehler: %s" + +#: libpq/be-secure-openssl.c:963 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "konnte DH-Parameterdatei »%s« nicht öffnen: %m" + +#: libpq/be-secure-openssl.c:975 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "konnte DH-Parameterdatei nicht laden: %s" + +#: libpq/be-secure-openssl.c:985 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "ungültige DH-Parameter: %s" + +#: libpq/be-secure-openssl.c:994 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "ungültige DH-Parameter: p ist keine Primzahl" + +#: libpq/be-secure-openssl.c:1003 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "ungültige DH-Parameter: weder geeigneter Generator noch sichere Primzahl" + +#: libpq/be-secure-openssl.c:1164 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: konnte DH-Parameter nicht laden" + +#: libpq/be-secure-openssl.c:1172 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: konnte DH-Parameter nicht setzen: %s" + +#: libpq/be-secure-openssl.c:1199 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: unbekannter Kurvenname: %s" + +#: libpq/be-secure-openssl.c:1208 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: konnte Schlüssel nicht erzeugen" + +#: libpq/be-secure-openssl.c:1236 +msgid "no SSL error reported" +msgstr "kein SSL-Fehler berichtet" + +#: libpq/be-secure-openssl.c:1240 +#, c-format +msgid "SSL error code %lu" +msgstr "SSL-Fehlercode %lu" + +#: libpq/be-secure-openssl.c:1394 +#, c-format +msgid "failed to create BIO" +msgstr "" + +#: libpq/be-secure-openssl.c:1404 +#, c-format +msgid "could not get NID for ASN1_OBJECT object" +msgstr "" + +#: libpq/be-secure-openssl.c:1412 +#, fuzzy, c-format +#| msgid "could not create LDAP structure\n" +msgid "could not convert NID %d to an ASN1_OBJECT structure" +msgstr "konnte LDAP-Struktur nicht erzeugen\n" + +#: libpq/be-secure.c:209 libpq/be-secure.c:305 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "Verbindung wird abgebrochen wegen unerwartetem Ende des Postmasters" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "Rolle »%s« existiert nicht." + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "Benutzer »%s« hat kein Passwort zugewiesen." + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "Benutzer »%s« hat ein abgelaufenes Passwort." + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "Benutzer »%s« hat ein Passwort, das nicht mit MD5-Authentifizierung verwendet werden kann." + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "Passwort stimmt nicht überein für Benutzer »%s«." + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "Passwort von Benutzer »%s« hat unbekanntes Format." + +#: libpq/hba.c:241 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "Token in Authentifizierungsdatei zu lang, wird übersprungen: »%s«" + +#: libpq/hba.c:413 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "konnte sekundäre Authentifizierungsdatei »@%s« nicht als »%s« öffnen: %m" + +#: libpq/hba.c:859 +#, c-format +msgid "error enumerating network interfaces: %m" +msgstr "Fehler beim Aufzählen der Netzwerkschnittstellen: %m" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:886 +#, c-format +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "Authentifizierungsoption »%s« ist nur gültig für Authentifizierungsmethoden %s" + +#: libpq/hba.c:888 libpq/hba.c:908 libpq/hba.c:946 libpq/hba.c:996 +#: libpq/hba.c:1010 libpq/hba.c:1034 libpq/hba.c:1043 libpq/hba.c:1056 +#: libpq/hba.c:1077 libpq/hba.c:1090 libpq/hba.c:1110 libpq/hba.c:1132 +#: libpq/hba.c:1144 libpq/hba.c:1203 libpq/hba.c:1223 libpq/hba.c:1237 +#: libpq/hba.c:1257 libpq/hba.c:1268 libpq/hba.c:1283 libpq/hba.c:1302 +#: libpq/hba.c:1318 libpq/hba.c:1330 libpq/hba.c:1367 libpq/hba.c:1408 +#: libpq/hba.c:1421 libpq/hba.c:1443 libpq/hba.c:1455 libpq/hba.c:1473 +#: libpq/hba.c:1523 libpq/hba.c:1567 libpq/hba.c:1578 libpq/hba.c:1594 +#: libpq/hba.c:1611 libpq/hba.c:1622 libpq/hba.c:1641 libpq/hba.c:1657 +#: libpq/hba.c:1673 libpq/hba.c:1727 libpq/hba.c:1744 libpq/hba.c:1757 +#: libpq/hba.c:1769 libpq/hba.c:1788 libpq/hba.c:1875 libpq/hba.c:1893 +#: libpq/hba.c:1987 libpq/hba.c:2006 libpq/hba.c:2035 libpq/hba.c:2048 +#: libpq/hba.c:2071 libpq/hba.c:2093 libpq/hba.c:2107 tsearch/ts_locale.c:232 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "Zeile %d in Konfigurationsdatei »%s«" + +#: libpq/hba.c:906 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "Authentifizierungsmethode »%s« benötigt Argument »%s«" + +#: libpq/hba.c:934 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "fehlender Eintrag in Datei »%s« am Ende von Zeile %d" + +#: libpq/hba.c:945 +#, c-format +msgid "multiple values in ident field" +msgstr "mehrere Werte in Ident-Feld" + +#: libpq/hba.c:994 +#, c-format +msgid "multiple values specified for connection type" +msgstr "mehrere Werte angegeben für Verbindungstyp" + +#: libpq/hba.c:995 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "Geben Sie genau einen Verbindungstyp pro Zeile an." + +#: libpq/hba.c:1009 +#, c-format +msgid "local connections are not supported by this build" +msgstr "lokale Verbindungen werden von dieser Installation nicht unterstützt" + +#: libpq/hba.c:1032 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "hostssl-Eintrag kann nicht angewendet werden, weil SSL deaktiviert ist" + +#: libpq/hba.c:1033 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "Setzen Sie ssl = on in postgresql.conf." + +#: libpq/hba.c:1041 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "hostssl-Eintrag kann nicht angewendet werden, weil SSL von dieser Installation nicht unterstützt wird" + +#: libpq/hba.c:1042 +#, c-format +msgid "Compile with --with-ssl to use SSL connections." +msgstr "Kompilieren Sie mit --with-ssl, um SSL-Verbindungen zu verwenden." + +#: libpq/hba.c:1054 +#, c-format +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "hostgssenc-Eintrag kann nicht angewendet werden, weil GSSAPI von dieser Installation nicht unterstützt wird" + +#: libpq/hba.c:1055 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "Kompilieren Sie mit --with-gssapi, um GSSAPI-Verbindungen zu verwenden." + +#: libpq/hba.c:1075 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "ungültiger Verbindungstyp »%s«" + +#: libpq/hba.c:1089 +#, c-format +msgid "end-of-line before database specification" +msgstr "Zeilenende vor Datenbankangabe" + +#: libpq/hba.c:1109 +#, c-format +msgid "end-of-line before role specification" +msgstr "Zeilenende vor Rollenangabe" + +#: libpq/hba.c:1131 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "Zeilenende vor IP-Adressangabe" + +#: libpq/hba.c:1142 +#, c-format +msgid "multiple values specified for host address" +msgstr "mehrere Werte für Hostadresse angegeben" + +#: libpq/hba.c:1143 +#, c-format +msgid "Specify one address range per line." +msgstr "Geben Sie einen Adressbereich pro Zeile an." + +#: libpq/hba.c:1201 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "ungültige IP-Adresse »%s«: %s" + +#: libpq/hba.c:1221 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "Angabe von sowohl Hostname als auch CIDR-Maske ist ungültig: »%s«" + +#: libpq/hba.c:1235 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "ungültige CIDR-Maske in Adresse »%s«" + +#: libpq/hba.c:1255 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "Zeilenende vor Netzmaskenangabe" + +#: libpq/hba.c:1256 +#, c-format +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "Geben Sie einen Adressbereich in CIDR-Schreibweise oder eine separate Netzmaske an." + +#: libpq/hba.c:1267 +#, c-format +msgid "multiple values specified for netmask" +msgstr "mehrere Werte für Netzmaske angegeben" + +#: libpq/hba.c:1281 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "ungültige IP-Maske »%s«: %s" + +#: libpq/hba.c:1301 +#, c-format +msgid "IP address and mask do not match" +msgstr "IP-Adresse und -Maske passen nicht zusammen" + +#: libpq/hba.c:1317 +#, c-format +msgid "end-of-line before authentication method" +msgstr "Zeilenende vor Authentifizierungsmethode" + +#: libpq/hba.c:1328 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "mehrere Werte für Authentifizierungstyp angegeben" + +#: libpq/hba.c:1329 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "Geben Sie genau einen Authentifizierungstyp pro Zeile an." + +#: libpq/hba.c:1406 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "ungültige Authentifizierungsmethode »%s«" + +#: libpq/hba.c:1419 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "ungültige Authentifizierungsmethode »%s«: von dieser Installation nicht unterstützt" + +#: libpq/hba.c:1442 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "gssapi-Authentifizierung wird auf lokalen Sockets nicht unterstützt" + +#: libpq/hba.c:1454 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "peer-Authentifizierung wird nur auf lokalen Sockets unterstützt" + +#: libpq/hba.c:1472 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "cert-Authentifizierung wird nur auf »hostssl«-Verbindungen unterstützt" + +#: libpq/hba.c:1522 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "Authentifizierungsoption nicht im Format name=wert: %s" + +#: libpq/hba.c:1566 +#, c-format +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter oder ldapurl kann nicht zusammen mit ldapprefix verwendet werden" + +#: libpq/hba.c:1577 +#, c-format +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "Authentifizierungsmethode »ldap« benötigt Argument »ldapbasedn«, »ldapprefix« oder »ldapsuffix«" + +#: libpq/hba.c:1593 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ldapsearchattribute kann nicht zusammen mit ldapsearchfilter verwendet werden" + +#: libpq/hba.c:1610 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "List der RADIUS-Server darf nicht leer sein" + +#: libpq/hba.c:1621 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "Liste der RADIUS-Geheimnisse darf nicht leer sein" + +#: libpq/hba.c:1638 +#, c-format +msgid "the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "die Anzahl der RADIUS-Geheimnisse (%d) muss 1 oder gleich der Anzahl der RADIUS-Server (%d) sein" + +#: libpq/hba.c:1654 +#, c-format +msgid "the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "die Anzahl der RADIUS-Ports (%d) muss 1 oder gleich der Anzahl der RADIUS-Server (%d) sein" + +#: libpq/hba.c:1670 +#, c-format +msgid "the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "die Anzahl der RADIUS-Bezeichner (%d) muss 1 oder gleich der Anzahl der RADIUS-Server (%d) sein" + +#: libpq/hba.c:1717 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi und cert" + +#: libpq/hba.c:1726 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert kann nur für »hostssl«-Zeilen konfiguriert werden" + +#: libpq/hba.c:1743 +#, c-format +msgid "clientcert only accepts \"verify-full\" when using \"cert\" authentication" +msgstr "clientcert akzeptiert »verify-full« nur, wenn »cert«-Authentifizierung verwendet wird" + +#: libpq/hba.c:1756 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "ungültiger Wert für clientcert: »%s«" + +#: libpq/hba.c:1768 +#, c-format +msgid "clientname can only be configured for \"hostssl\" rows" +msgstr "clientname kann nur für »hostssl«-Zeilen konfiguriert werden" + +#: libpq/hba.c:1787 +#, c-format +msgid "invalid value for clientname: \"%s\"" +msgstr "ungültiger Wert für clientname: »%s«" + +#: libpq/hba.c:1821 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "konnte LDAP-URL »%s« nicht interpretieren: %s" + +#: libpq/hba.c:1832 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "nicht unterstütztes LDAP-URL-Schema: %s" + +#: libpq/hba.c:1856 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "LDAP-URLs werden auf dieser Plattform nicht unterstützt" + +#: libpq/hba.c:1874 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "ungültiger ldapscheme-Wert: »%s«" + +#: libpq/hba.c:1892 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "ungültige LDAP-Portnummer: »%s«" + +#: libpq/hba.c:1938 libpq/hba.c:1945 +msgid "gssapi and sspi" +msgstr "gssapi und sspi" + +#: libpq/hba.c:1954 libpq/hba.c:1963 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1985 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "konnte RADIUS-Serverliste »%s« nicht parsen" + +#: libpq/hba.c:2033 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "konnte RADIUS-Portliste »%s« nicht parsen" + +#: libpq/hba.c:2047 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "ungültige RADIUS-Portnummer: »%s«" + +#: libpq/hba.c:2069 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "konnte RADIUS-Geheimnisliste »%s« nicht parsen" + +#: libpq/hba.c:2091 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "konnte RADIUS-Bezeichnerliste »%s« nicht parsen" + +#: libpq/hba.c:2105 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "unbekannter Authentifizierungsoptionsname: »%s«" + +#: libpq/hba.c:2302 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "Konfigurationsdatei »%s« enthält keine Einträge" + +#: libpq/hba.c:2820 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "ungültiger regulärer Ausdruck »%s«: %s" + +#: libpq/hba.c:2880 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "Suche nach regulärem Ausdruck für »%s« fehlgeschlagen: %s" + +#: libpq/hba.c:2899 +#, c-format +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "regulärer Ausdruck »%s« hat keine Teilausdrücke wie von der Backreference in »%s« verlangt" + +#: libpq/hba.c:2995 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "angegebener Benutzername (%s) und authentifizierter Benutzername (%s) stimmen nicht überein" + +#: libpq/hba.c:3015 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "kein passender Eintrag in Usermap »%s« für Benutzer »%s«, authentifiziert als »%s«" + +#: libpq/hba.c:3048 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "konnte Usermap-Datei »%s« nicht öffnen: %m" + +#: libpq/pqcomm.c:204 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "konnte Socket nicht auf nicht-blockierenden Modus umstellen: %m" + +#: libpq/pqcomm.c:362 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "Unix-Domain-Socket-Pfad »%s« ist zu lang (maximal %d Bytes)" + +#: libpq/pqcomm.c:383 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "konnte Hostname »%s«, Dienst »%s« nicht in Adresse übersetzen: %s" + +#: libpq/pqcomm.c:387 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "konnte Dienst »%s« nicht in Adresse übersetzen: %s" + +#: libpq/pqcomm.c:414 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "konnte nicht an alle verlangten Adressen binden: MAXLISTEN (%d) überschritten" + +#: libpq/pqcomm.c:423 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:427 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:432 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:437 +#, c-format +msgid "unrecognized address family %d" +msgstr "unbekannte Adressfamilie %d" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:463 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "konnte %s-Socket für Adresse »%s« nicht erzeugen: %m" + +#. translator: third %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:489 libpq/pqcomm.c:507 +#, c-format +msgid "%s(%s) failed for %s address \"%s\": %m" +msgstr "%s(%s) für %s-Adresse »%s« fehlgeschlagen: %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:530 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "konnte %s-Adresse »%s« nicht binden: %m" + +#: libpq/pqcomm.c:534 +#, c-format +msgid "Is another postmaster already running on port %d?" +msgstr "Läuft bereits ein anderer Postmaster auf Port %d?" + +#: libpq/pqcomm.c:536 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "Läuft bereits ein anderer Postmaster auf Port %d? Wenn nicht, warten Sie einige Sekunden und versuchen Sie erneut." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:569 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "konnte nicht auf %s-Adresse »%s« hören: %m" + +#: libpq/pqcomm.c:578 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "erwarte Verbindungen auf Unix-Socket »%s«" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:584 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "erwarte Verbindungen auf %s-Adresse »%s«, Port %d" + +#: libpq/pqcomm.c:675 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "Gruppe »%s« existiert nicht" + +#: libpq/pqcomm.c:685 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "konnte Gruppe von Datei »%s« nicht setzen: %m" + +#: libpq/pqcomm.c:696 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "konnte Zugriffsrechte von Datei »%s« nicht setzen: %m" + +#: libpq/pqcomm.c:726 +#, c-format +msgid "could not accept new connection: %m" +msgstr "konnte neue Verbindung nicht akzeptieren: %m" + +#: libpq/pqcomm.c:766 libpq/pqcomm.c:775 libpq/pqcomm.c:807 libpq/pqcomm.c:817 +#: libpq/pqcomm.c:1630 libpq/pqcomm.c:1675 libpq/pqcomm.c:1715 +#: libpq/pqcomm.c:1759 libpq/pqcomm.c:1798 libpq/pqcomm.c:1837 +#: libpq/pqcomm.c:1873 libpq/pqcomm.c:1912 postmaster/pgstat.c:618 +#: postmaster/pgstat.c:629 +#, c-format +msgid "%s(%s) failed: %m" +msgstr "%s(%s) fehlgeschlagen: %m" + +#: libpq/pqcomm.c:921 +#, c-format +msgid "there is no client connection" +msgstr "es besteht keine Client-Verbindung" + +#: libpq/pqcomm.c:972 libpq/pqcomm.c:1068 +#, c-format +msgid "could not receive data from client: %m" +msgstr "konnte Daten vom Client nicht empfangen: %m" + +#: libpq/pqcomm.c:1161 tcop/postgres.c:4290 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "Verbindung wird abgebrochen, weil Protokollsynchronisierung verloren wurde" + +#: libpq/pqcomm.c:1227 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "unerwartetes EOF im Message-Längenwort" + +#: libpq/pqcomm.c:1237 +#, c-format +msgid "invalid message length" +msgstr "ungültige Message-Länge" + +#: libpq/pqcomm.c:1259 libpq/pqcomm.c:1272 +#, c-format +msgid "incomplete message from client" +msgstr "unvollständige Message vom Client" + +#: libpq/pqcomm.c:1383 +#, c-format +msgid "could not send data to client: %m" +msgstr "konnte Daten nicht an den Client senden: %m" + +#: libpq/pqcomm.c:1598 +#, c-format +msgid "%s(%s) failed: error code %d" +msgstr "%s(%s) fehlgeschlagen: Fehlercode %d" + +#: libpq/pqcomm.c:1687 +#, fuzzy, c-format +#| msgid "using recovery command file \"%s\" is not supported" +msgid "setting the keepalive idle time is not supported" +msgstr "Verwendung von Recovery-Befehlsdatei »%s« wird nicht unterstützt" + +#: libpq/pqcomm.c:1771 libpq/pqcomm.c:1846 libpq/pqcomm.c:1921 +#, c-format +msgid "%s(%s) not supported" +msgstr "%s(%s) nicht unterstützt" + +#: libpq/pqcomm.c:1956 +#, fuzzy, c-format +#| msgid "could not set SSL socket: %s" +msgid "could not poll socket: %m" +msgstr "konnte SSL-Socket nicht setzen: %s" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "keine Daten in Message übrig" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1481 utils/adt/rowtypes.c:588 +#, c-format +msgid "insufficient data left in message" +msgstr "nicht genug Daten in Message übrig" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "ungültige Zeichenkette in Message" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "ungültiges Message-Format" + +#: main/main.c:245 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: WSAStartup fehlgeschlagen: %d\n" + +#: main/main.c:309 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%s ist der PostgreSQL-Server.\n" +"\n" + +#: main/main.c:310 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Aufruf:\n" +" %s [OPTION]...\n" +"\n" + +#: main/main.c:311 +#, c-format +msgid "Options:\n" +msgstr "Optionen:\n" + +#: main/main.c:312 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B ZAHL Anzahl der geteilten Puffer\n" + +#: main/main.c:313 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NAME=WERT setze Konfigurationsparameter\n" + +#: main/main.c:314 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NAME Wert des Konfigurationsparameters ausgeben, dann beenden\n" + +#: main/main.c:315 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 Debug-Level\n" + +#: main/main.c:316 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D VERZEICHNIS Datenbankverzeichnis\n" + +#: main/main.c:317 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e verwende europäisches Datumseingabeformat (DMY)\n" + +#: main/main.c:318 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F »fsync« ausschalten\n" + +#: main/main.c:319 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h HOSTNAME horche auf Hostname oder IP-Adresse\n" + +#: main/main.c:320 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i ermögliche TCP/IP-Verbindungen\n" + +#: main/main.c:321 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k VERZEICHNIS Ort der Unix-Domain-Socket\n" + +#: main/main.c:323 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l ermögliche SSL-Verbindungen\n" + +#: main/main.c:325 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N ZAHL Anzahl der erlaubten Verbindungen\n" + +#: main/main.c:326 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT auf dieser Portnummer horchen\n" + +#: main/main.c:327 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s zeige Statistiken nach jeder Anfrage\n" + +#: main/main.c:328 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S ZAHL setze Speicher für Sortiervorgänge (in kB)\n" + +#: main/main.c:329 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: main/main.c:330 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NAME=WERT setze Konfigurationsparameter\n" + +#: main/main.c:331 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config zeige Konfigurationsparameter und beende\n" + +#: main/main.c:332 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: main/main.c:334 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"Entwickleroptionen:\n" + +#: main/main.c:335 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h verbiete Verwendung einiger Plantypen\n" + +#: main/main.c:336 +#, c-format +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr " -n Shared Memory nach abnormalem Ende nicht neu initialisieren\n" + +#: main/main.c:337 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O erlaube Änderungen an Systemtabellenstruktur\n" + +#: main/main.c:338 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P schalte Systemindexe aus\n" + +#: main/main.c:339 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex zeige Zeitmessung nach jeder Anfrage\n" + +#: main/main.c:340 +#, c-format +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr " -T SIGSTOP an alle Backend-Prozesse senden wenn einer stirbt\n" + +#: main/main.c:341 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr " -W ZAHL warte ZAHL Sekunden, um Debugger starten zu können\n" + +#: main/main.c:343 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"Optionen für Einzelbenutzermodus:\n" + +#: main/main.c:344 +#, c-format +msgid " --single selects single-user mode (must be first argument)\n" +msgstr " --single wählt den Einzelbenutzermodus (muss erstes Argument sein)\n" + +#: main/main.c:345 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAME Datenbankname (Vorgabe: Benutzername)\n" + +#: main/main.c:346 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 Debug-Level setzen\n" + +#: main/main.c:347 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E gebe Befehl vor der Ausführung aus\n" + +#: main/main.c:348 +#, c-format +msgid " -j do not use newline as interactive query delimiter\n" +msgstr "" +" -j verwende Zeilenende nicht als Anfrageende im interaktiven\n" +" Modus\n" + +#: main/main.c:349 main/main.c:354 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r DATEINAME sende stdout und stderr in genannte Datei\n" + +#: main/main.c:351 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"Optionen für Bootstrap-Modus:\n" + +#: main/main.c:352 +#, c-format +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot wählt den Bootstrap-Modus (muss erstes Argument sein)\n" + +#: main/main.c:353 +#, c-format +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr " DBNAME Datenbankname (Pflichtangabe im Bootstrap-Modus)\n" + +#: main/main.c:355 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM interne Verwendung\n" + +#: main/main.c:357 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"In der Dokumentation finden Sie eine komplette Liste der Konfigurations-\n" +"parameter und Informationen wie man sie auf der Kommandozeile oder in der\n" +"Konfiguratonsdatei setzen kann.\n" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: main/main.c:361 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: main/main.c:372 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Der PostgreSQL-Server darf nicht als »root« ausgeführt werden. Der\n" +"Server muss unter einer unprivilegierten Benutzer-ID gestartet werden,\n" +"um mögliche Sicherheitskompromittierung zu verhindern. In der\n" +"Dokumentation finden Sie weitere Informationen darüber, wie der\n" +"Server richtig gestartet wird.\n" + +#: main/main.c:389 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: reelle und effektive Benutzer-IDs müssen übereinstimmen\n" + +#: main/main.c:396 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Der PostgreSQL-Server darf nicht als Benutzer mit Administrator-Rechten\n" +"ausgeführt werden. Der Server muss unter einer unprivilegierten\n" +"Benutzer-ID gestartet werden, um mögliche Sicherheitskompromittierung zu\n" +"verhindern. In der Dokumentation finden Sie weitere Informationen darüber,\n" +"wie der Server richtig gestartet wird.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "erweiterbarer Knotentyp »%s« existiert bereits" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "ExtensibleNodeMethods »%s« wurde nicht registriert" + +#: nodes/makefuncs.c:150 +#, c-format +msgid "relation \"%s\" does not have a composite type" +msgstr "Relation »%s« hat keinen zusammengesetzten Typ" + +#: nodes/nodeFuncs.c:114 nodes/nodeFuncs.c:145 parser/parse_coerce.c:2472 +#: parser/parse_coerce.c:2584 parser/parse_coerce.c:2630 +#: parser/parse_expr.c:2021 parser/parse_func.c:709 parser/parse_oper.c:883 +#: utils/fmgr/funcapi.c:558 +#, c-format +msgid "could not find array type for data type %s" +msgstr "konnte Arraytyp für Datentyp %s nicht finden" + +#: nodes/params.c:417 +#, c-format +msgid "portal \"%s\" with parameters: %s" +msgstr "Portal »%s« mit Parametern: %s" + +#: nodes/params.c:420 +#, c-format +msgid "unnamed portal with parameters: %s" +msgstr "unbenanntes Portal mit Parametern: %s" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN wird nur für Merge- oder Hash-Verbund-fähige Verbundbedingungen unterstützt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1192 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s kann nicht auf die nullbare Seite eines äußeren Verbundes angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1315 parser/analyze.c:1675 parser/analyze.c:1919 +#: parser/analyze.c:3013 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s ist nicht in UNION/INTERSECT/EXCEPT erlaubt" + +#: optimizer/plan/planner.c:1978 optimizer/plan/planner.c:3634 +#, c-format +msgid "could not implement GROUP BY" +msgstr "konnte GROUP BY nicht implementieren" + +#: optimizer/plan/planner.c:1979 optimizer/plan/planner.c:3635 +#: optimizer/plan/planner.c:4392 optimizer/prep/prepunion.c:1046 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "Einige Datentypen unterstützen nur Hashing, während andere nur Sortieren unterstützen." + +#: optimizer/plan/planner.c:4391 +#, c-format +msgid "could not implement DISTINCT" +msgstr "konnte DISTINCT nicht implementieren" + +#: optimizer/plan/planner.c:5239 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "konnte PARTITION BY für Fenster nicht implementieren" + +#: optimizer/plan/planner.c:5240 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "Fensterpartitionierungsspalten müssen sortierbare Datentypen haben." + +#: optimizer/plan/planner.c:5244 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "konnte ORDER BY für Fenster nicht implementieren" + +#: optimizer/plan/planner.c:5245 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Fenstersortierspalten müssen sortierbare Datentypen haben." + +#: optimizer/plan/setrefs.c:479 +#, c-format +msgid "too many range table entries" +msgstr "zu viele Range-Table-Einträge" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "could not implement recursive UNION" +msgstr "konnte rekursive UNION nicht implementieren" + +#: optimizer/prep/prepunion.c:510 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Alle Spaltendatentypen müssen hashbar sein." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1045 +#, c-format +msgid "could not implement %s" +msgstr "konnte %s nicht implementieren" + +#: optimizer/util/clauses.c:4670 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "SQL-Funktion »%s« beim Inlining" + +#: optimizer/util/plancat.c:132 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "während der Wiederherstellung kann nicht auf temporäre oder ungeloggte Tabellen zugegriffen werden" + +#: optimizer/util/plancat.c:672 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "Inferenzangaben mit Unique-Index über die gesamte Zeile werden nicht unterstützt" + +#: optimizer/util/plancat.c:689 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "Constraint in der ON-CONFLICT-Klausel hat keinen zugehörigen Index" + +#: optimizer/util/plancat.c:739 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE nicht unterstützt mit Exclusion-Constraints" + +#: optimizer/util/plancat.c:844 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "es gibt keinen Unique-Constraint oder Exclusion-Constraint, der auf die ON-CONFLICT-Angabe passt" + +#: parser/analyze.c:735 parser/analyze.c:1449 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "VALUES-Listen müssen alle die gleiche Länge haben" + +#: parser/analyze.c:936 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT hat mehr Ausdrücke als Zielspalten" + +#: parser/analyze.c:954 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT hat mehr Zielspalten als Ausdrücke" + +#: parser/analyze.c:958 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "Der einzufügende Wert ist ein Zeilenausdruck mit der gleichen Anzahl Spalten wie von INSERT erwartet. Haben Sie versehentlich zu viele Klammern gesetzt?" + +#: parser/analyze.c:1257 parser/analyze.c:1648 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO ist hier nicht erlaubt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1578 parser/analyze.c:3192 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s kann nicht auf VALUES angewendet werden" + +#: parser/analyze.c:1814 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "ungültige ORDER-BY-Klausel mit UNION/INTERSECT/EXCEPT" + +#: parser/analyze.c:1815 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "Es können nur Ergebnisspaltennamen verwendet werden, keine Ausdrücke oder Funktionen." + +#: parser/analyze.c:1816 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "Fügen Sie den Ausdrück/die Funktion jedem SELECT hinzu oder verlegen Sie die UNION in eine FROM-Klausel." + +#: parser/analyze.c:1909 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO ist nur im ersten SELECT von UNION/INTERSECT/EXCEPT erlaubt" + +#: parser/analyze.c:1981 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "Teilanweisung von UNION/INTERSECT/EXCEPT kann nicht auf andere Relationen auf der selben Anfrageebene verweisen" + +#: parser/analyze.c:2068 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "jede %s-Anfrage muss die gleiche Anzahl Spalten haben" + +#: parser/analyze.c:2468 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNING muss mindestens eine Spalte haben" + +#: parser/analyze.c:2571 +#, c-format +msgid "assignment source returned %d column" +msgid_plural "assignment source returned %d columns" +msgstr[0] "Quelle der Wertzuweisung hat %d Spalte zurückgegeben" +msgstr[1] "Quelle der Wertzuweisung hat %d Spalten zurückgegeben" + +#: parser/analyze.c:2632 +#, c-format +msgid "variable \"%s\" is of type %s but expression is of type %s" +msgstr "Variable »%s« hat Typ %s, aber der Ausdruck hat Typ %s" + +#. translator: %s is a SQL keyword +#: parser/analyze.c:2756 parser/analyze.c:2764 +#, c-format +msgid "cannot specify both %s and %s" +msgstr "%s und %s können nicht beide angegeben werden" + +#: parser/analyze.c:2784 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR darf keine datenmodifizierenden Anweisungen in WITH enthalten" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2792 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s wird nicht unterstützt" + +#: parser/analyze.c:2795 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "Haltbare Cursor müssen READ ONLY sein." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2803 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s wird nicht unterstützt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2814 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not valid" +msgstr "DECLARE INSENSITIVE CURSOR ... %s ist nicht gültig" + +#: parser/analyze.c:2817 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Insensitive Cursor müssen READ ONLY sein." + +#: parser/analyze.c:2883 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "materialisierte Sichten dürfen keine datenmodifizierenden Anweisungen in WITH verwenden" + +#: parser/analyze.c:2893 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "materialisierte Sichten dürfen keine temporären Tabellen oder Sichten verwenden" + +#: parser/analyze.c:2903 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "materialisierte Sichten können nicht unter Verwendung von gebundenen Parametern definiert werden" + +#: parser/analyze.c:2915 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "materialisierte Sichten können nicht ungeloggt sein" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3020 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s ist nicht mit DISTINCT-Klausel erlaubt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3027 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s ist nicht mit GROUP-BY-Klausel erlaubt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3034 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s ist nicht mit HAVING-Klausel erlaubt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3041 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s ist nicht mit Aggregatfunktionen erlaubt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3048 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s ist nicht mit Fensterfunktionen erlaubt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3055 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s ist nicht mit Funktionen mit Ergebnismenge in der Targetliste erlaubt" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3134 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%s muss unqualifizierte Relationsnamen angeben" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3165 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s kann nicht auf einen Verbund angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3174 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s kann nicht auf eine Funktion angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3183 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s kann nicht auf eine Tabellenfunktion angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3201 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s kann nicht auf eine WITH-Anfrage angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3210 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s kann nicht auf einen benannten Tupelstore angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3230 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "Relation »%s« in %s nicht in der FROM-Klausel gefunden" + +#: parser/parse_agg.c:220 parser/parse_oper.c:227 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "konnte keine Sortieroperator für Typ %s ermitteln" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "Aggregatfunktionen mit DISTINCT müssen ihre Eingaben sortieren können." + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING muss weniger als 32 Argumente haben" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "Aggregatfunktionen sind in JOIN-Bedingungen nicht erlaubt" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "Gruppieroperationen sind in JOIN-Bedingungen nicht erlaubt" + +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "Aggregatfunktionen sind nicht in der FROM-Klausel ihrer eigenen Anfrageebene erlaubt" + +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "Gruppieroperationen sind nicht in der FROM-Klausel ihrer eigenen Anfrageebene erlaubt" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "Aggregatfunktionen sind in Funktionen in FROM nicht erlaubt" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "Gruppieroperationen sind in Funktionen in FROM nicht erlaubt" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "Aggregatfunktionen sind in Policy-Ausdrücken nicht erlaubt" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "Gruppieroperationen sind in Policy-Ausdrücken nicht erlaubt" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "Aggregatfunktionen sind in der Fenster-RANGE-Klausel nicht erlaubt" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "Gruppieroperationen sind in der Fenster-RANGE-Klausel nicht erlaubt" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "Aggregatfunktionen sind in der Fenster-ROWS-Klausel nicht erlaubt" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "Gruppieroperationen sind in der Fenster-ROWS-Klausel nicht erlaubt" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "Aggregatfunktionen sind in der Fenster-GROUPS-Klausel nicht erlaubt" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "Gruppieroperationen sind in der Fenster-GROUPS-Klausel nicht erlaubt" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "Aggregatfunktionen sind in Check-Constraints nicht erlaubt" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "Gruppieroperationen sind in Check-Constraints nicht erlaubt" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "Aggregatfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "Gruppieroperationen sind in DEFAULT-Ausdrücken nicht erlaubt" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "Aggregatfunktionen sind in Indexausdrücken nicht erlaubt" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "Gruppieroperationen sind in Indexausdrücken nicht erlaubt" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "Aggregatfunktionen sind in Indexprädikaten nicht erlaubt" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "Gruppieroperationen sind in Indexprädikaten nicht erlaubt" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in statistics expressions" +msgstr "Aggregatfunktionen sind in Statistikausdrücken nicht erlaubt" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in statistics expressions" +msgstr "Gruppieroperationen sind in Statistikausdrücken nicht erlaubt" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "Aggregatfunktionen sind in Umwandlungsausdrücken nicht erlaubt" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in transform expressions" +msgstr "Gruppieroperationen sind in Umwandlungsausdrücken nicht erlaubt" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "Aggregatfunktionen sind in EXECUTE-Parametern nicht erlaubt" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "Gruppieroperationen sind in EXECUTE-Parametern nicht erlaubt" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "Aggregatfunktionen sind in der WHEN-Bedingung eines Triggers nicht erlaubt" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "Gruppieroperationen sind in der WHEN-Bedingung eines Triggers nicht erlaubt" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition bound" +msgstr "Aggregatfunktionen sind in Partitionsbegrenzungen nicht erlaubt" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition bound" +msgstr "Gruppieroperationen sind in Partitionsbegrenzungen nicht erlaubt" + +#: parser/parse_agg.c:525 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "Aggregatfunktionen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" + +#: parser/parse_agg.c:527 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "Gruppieroperationen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" + +#: parser/parse_agg.c:533 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "Aggregatfunktionen sind in Spaltengenerierungsausdrücken nicht erlaubt" + +#: parser/parse_agg.c:535 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "Gruppieroperationen sind in Spaltengenerierungsausdrücken nicht erlaubt" + +#: parser/parse_agg.c:541 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "Aggregatfunktionen sind in CALL-Argumenten nicht erlaubt" + +#: parser/parse_agg.c:543 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "Gruppieroperationen sind in CALL-Argumenten nicht erlaubt" + +#: parser/parse_agg.c:549 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "Aggregatfunktionen sind in COPY-FROM-WHERE-Bedingungen nicht erlaubt" + +#: parser/parse_agg.c:551 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "Gruppieroperationen sind in COPY-FROM-WHERE-Bedingungen nicht erlaubt" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:578 parser/parse_clause.c:1847 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "Aggregatfunktionen sind in %s nicht erlaubt" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:581 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "Gruppieroperationen sind in %s nicht erlaubt" + +#: parser/parse_agg.c:689 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "Aggregatfunktion auf äußerer Ebene kann keine Variable einer unteren Ebene in ihren direkten Argumenten haben" + +#: parser/parse_agg.c:768 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "Aufrufe von Aggregatfunktionen können keine Aufrufe von Funktionen mit Ergebnismenge enthalten" + +#: parser/parse_agg.c:769 parser/parse_expr.c:1673 parser/parse_expr.c:2146 +#: parser/parse_func.c:882 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Sie können möglicherweise die Funktion mit Ergebnismenge in ein LATERAL-FROM-Element verschieben." + +#: parser/parse_agg.c:774 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "Aufrufe von Aggregatfunktionen können keine Aufrufe von Fensterfunktionen enthalten" + +#: parser/parse_agg.c:853 +msgid "window functions are not allowed in JOIN conditions" +msgstr "Fensterfunktionen sind in JOIN-Bedingungen nicht erlaubt" + +#: parser/parse_agg.c:860 +msgid "window functions are not allowed in functions in FROM" +msgstr "Fensterfunktionen sind in Funktionen in FROM nicht erlaubt" + +#: parser/parse_agg.c:866 +msgid "window functions are not allowed in policy expressions" +msgstr "Fensterfunktionen sind in Policy-Ausdrücken nicht erlaubt" + +#: parser/parse_agg.c:879 +msgid "window functions are not allowed in window definitions" +msgstr "Fensterfunktionen sind in Fensterdefinitionen nicht erlaubt" + +#: parser/parse_agg.c:911 +msgid "window functions are not allowed in check constraints" +msgstr "Fensterfunktionen sind in Check-Constraints nicht erlaubt" + +#: parser/parse_agg.c:915 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "Fensterfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" + +#: parser/parse_agg.c:918 +msgid "window functions are not allowed in index expressions" +msgstr "Fensterfunktionen sind in Indexausdrücken nicht erlaubt" + +#: parser/parse_agg.c:921 +msgid "window functions are not allowed in statistics expressions" +msgstr "Fensterfunktionen sind in Statistikausdrücken nicht erlaubt" + +#: parser/parse_agg.c:924 +msgid "window functions are not allowed in index predicates" +msgstr "Fensterfunktionen sind in Indexprädikaten nicht erlaubt" + +#: parser/parse_agg.c:927 +msgid "window functions are not allowed in transform expressions" +msgstr "Fensterfunktionen sind in Umwandlungsausdrücken nicht erlaubt" + +#: parser/parse_agg.c:930 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "Fensterfunktionen sind in EXECUTE-Parametern nicht erlaubt" + +#: parser/parse_agg.c:933 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "Fensterfunktionen sind in der WHEN-Bedingung eines Triggers nicht erlaubt" + +#: parser/parse_agg.c:936 +msgid "window functions are not allowed in partition bound" +msgstr "Fensterfunktionen sind in Partitionsbegrenzungen nicht erlaubt" + +#: parser/parse_agg.c:939 +msgid "window functions are not allowed in partition key expressions" +msgstr "Fensterfunktionen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" + +#: parser/parse_agg.c:942 +msgid "window functions are not allowed in CALL arguments" +msgstr "Fensterfunktionen sind in CALL-Argumenten nicht erlaubt" + +#: parser/parse_agg.c:945 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "Fensterfunktionen sind in COPY-FROM-WHERE-Bedingungen nicht erlaubt" + +#: parser/parse_agg.c:948 +msgid "window functions are not allowed in column generation expressions" +msgstr "Fensterfunktionen sind in Spaltengenerierungsausdrücken nicht erlaubt" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:971 parser/parse_clause.c:1856 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "Fensterfunktionen sind in %s nicht erlaubt" + +#: parser/parse_agg.c:1005 parser/parse_clause.c:2690 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "Fenster »%s« existiert nicht" + +#: parser/parse_agg.c:1089 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "zu viele Grouping-Sets vorhanden (maximal 4096)" + +#: parser/parse_agg.c:1229 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "Aggregatfunktionen sind nicht im rekursiven Ausdruck einer rekursiven Anfrage erlaubt" + +#: parser/parse_agg.c:1422 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "Spalte »%s.%s« muss in der GROUP-BY-Klausel erscheinen oder in einer Aggregatfunktion verwendet werden" + +#: parser/parse_agg.c:1425 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "Direkte Argumente einer Ordered-Set-Aggregatfunktion dürfen nur gruppierte Spalten verwenden." + +#: parser/parse_agg.c:1430 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "Unteranfrage verwendet nicht gruppierte Spalte »%s.%s« aus äußerer Anfrage" + +#: parser/parse_agg.c:1594 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "Argumente von GROUPING müssen Gruppierausdrücke der zugehörigen Anfrageebene sein" + +#: parser/parse_clause.c:190 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "Relation »%s« kann nicht das Ziel einer datenverändernden Anweisung sein" + +#: parser/parse_clause.c:571 parser/parse_clause.c:599 parser/parse_func.c:2438 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "Funktionen mit Ergebnismenge müssen auf oberster Ebene von FROM erscheinen" + +#: parser/parse_clause.c:611 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "mehrere Spaltendefinitionslisten für die selbe Funktion sind nicht erlaubt" + +#: parser/parse_clause.c:644 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "ROWS FROM() mit mehreren Funktionen kann keine Spaltendefinitionsliste haben" + +#: parser/parse_clause.c:645 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "Geben Sie innerhalb von ROWS FROM() jeder Funktion eine eigene Spaltendefinitionsliste." + +#: parser/parse_clause.c:651 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "UNNEST() mit mehreren Argumenten kann keine Spaltendefinitionsliste haben" + +#: parser/parse_clause.c:652 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "Verwenden Sie getrennte UNNEST()-Aufrufe innerhalb von ROWS FROM() und geben Sie jeder eine eigene Spaltendefinitionsliste." + +#: parser/parse_clause.c:659 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY kann nicht mit einer Spaltendefinitionsliste verwendet werden" + +#: parser/parse_clause.c:660 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Geben Sie die Spaltendefinitionsliste innerhalb von ROWS FROM() an." + +#: parser/parse_clause.c:760 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "nur eine FOR-ORDINALITY-Spalte ist erlaubt" + +#: parser/parse_clause.c:821 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "Spaltenname »%s« ist nicht eindeutig" + +#: parser/parse_clause.c:863 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "Namensraumname »%s« ist nicht eindeutig" + +#: parser/parse_clause.c:873 +#, c-format +msgid "only one default namespace is allowed" +msgstr "nur ein Standardnamensraum ist erlaubt" + +#: parser/parse_clause.c:933 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "Tablesample-Methode %s existiert nicht" + +#: parser/parse_clause.c:955 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "Tablesample-Methode %s benötigt %d Argument, nicht %d" +msgstr[1] "Tablesample-Methode %s benötigt %d Argumente, nicht %d" + +#: parser/parse_clause.c:989 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "Tablesample-Methode %s unterstützt REPEATABLE nicht" + +#: parser/parse_clause.c:1135 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLE-Klausel kann nur auf Tabellen und materialisierte Sichten angewendet werden" + +#: parser/parse_clause.c:1325 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "Spaltenname »%s« erscheint mehrmals in der USING-Klausel" + +#: parser/parse_clause.c:1340 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der linken Tabelle" + +#: parser/parse_clause.c:1349 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der linken Tabelle" + +#: parser/parse_clause.c:1364 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der rechten Tabelle" + +#: parser/parse_clause.c:1373 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der rechten Tabelle" + +#: parser/parse_clause.c:1452 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "Spaltenaliasliste für »%s« hat zu viele Einträge" + +#: parser/parse_clause.c:1792 +#, c-format +msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" +msgstr "Zeilenzahl in FETCH FIRST ... WITH TIES darf nicht NULL sein" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1817 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "Argument von %s darf keine Variablen enthalten" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1982 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s »%s« ist nicht eindeutig" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2011 +#, c-format +msgid "non-integer constant in %s" +msgstr "Konstante in %s ist keine ganze Zahl" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2033 +#, c-format +msgid "%s position %d is not in select list" +msgstr "%s Position %d ist nicht in der Select-Liste" + +#: parser/parse_clause.c:2472 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE ist auf 12 Elemente begrenzt" + +#: parser/parse_clause.c:2678 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "Fenster »%s« ist bereits definiert" + +#: parser/parse_clause.c:2739 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "PARTITION-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" + +#: parser/parse_clause.c:2751 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "ORDER-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" + +#: parser/parse_clause.c:2781 parser/parse_clause.c:2787 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "kann Fenster »%s« nicht kopieren, weil es eine Frame-Klausel hat" + +#: parser/parse_clause.c:2789 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Lassen Sie die Klammern in dieser OVER-Klausel weg." + +#: parser/parse_clause.c:2809 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE mit Offset PRECEDING/FOLLOWING benötigt genau eine ORDER-BY-Spalte" + +#: parser/parse_clause.c:2832 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPS-Modus erfordert eine ORDER-BY-Klausel" + +#: parser/parse_clause.c:2902 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "in einer Aggregatfunktion mit DISTINCT müssen ORDER-BY-Ausdrücke in der Argumentliste erscheinen" + +#: parser/parse_clause.c:2903 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "bei SELECT DISTINCT müssen ORDER-BY-Ausdrücke in der Select-Liste erscheinen" + +#: parser/parse_clause.c:2935 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "eine Aggregatfunktion mit DISTINCT muss mindestens ein Argument haben" + +#: parser/parse_clause.c:2936 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT muss mindestens eine Spalte haben" + +#: parser/parse_clause.c:3002 parser/parse_clause.c:3034 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "Ausdrücke in SELECT DISTINCT ON müssen mit den ersten Ausdrücken in ORDER BY übereinstimmen" + +#: parser/parse_clause.c:3112 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC ist in der ON-CONFLICT-Klausel nicht erlaubt" + +#: parser/parse_clause.c:3118 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST ist in der ON-CONFLICT-Klausel nicht erlaubt" + +#: parser/parse_clause.c:3197 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE benötigt Inferenzangabe oder Constraint-Namen" + +#: parser/parse_clause.c:3198 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Zum Bespiel ON CONFLICT (Spaltenname)." + +#: parser/parse_clause.c:3209 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT wird nicht mit Systemkatalogtabellen unterstützt" + +#: parser/parse_clause.c:3217 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT wird nicht unterstützt mit Tabelle »%s«, die als Katalogtabelle verwendet wird" + +#: parser/parse_clause.c:3347 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "Operator %s ist kein gültiger Sortieroperator" + +#: parser/parse_clause.c:3349 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "Sortieroperatoren müssen die Mitglieder »<« oder »>« einer »btree«-Operatorfamilie sein." + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE mit Offset PRECEDING/FOLLOWING wird für Spaltentyp %s nicht unterstützt" + +#: parser/parse_clause.c:3666 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE mit Offset PRECEDING/FOLLOWING wird für Spaltentyp %s und Offset-Typ %s nicht unterstützt" + +#: parser/parse_clause.c:3669 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Wandeln Sie den Offset-Wert in einen passenden Typ um." + +#: parser/parse_clause.c:3674 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE mit Offset PRECEDING/FOLLOWING hat mehrere Interpretationen für Spaltentyp %s und Offset-Typ %s" + +#: parser/parse_clause.c:3677 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Wandeln Sie den Offset-Wert in den genauen beabsichtigten Typ um." + +#: parser/parse_coerce.c:1034 parser/parse_coerce.c:1072 +#: parser/parse_coerce.c:1090 parser/parse_coerce.c:1105 +#: parser/parse_expr.c:2055 parser/parse_expr.c:2649 parser/parse_target.c:995 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "kann Typ %s nicht in Typ %s umwandeln" + +#: parser/parse_coerce.c:1075 +#, c-format +msgid "Input has too few columns." +msgstr "Eingabe hat zu wenige Spalten." + +#: parser/parse_coerce.c:1093 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "Kann in Spalte %3$d Typ %1$s nicht in Typ %2$s umwandeln." + +#: parser/parse_coerce.c:1108 +#, c-format +msgid "Input has too many columns." +msgstr "Eingabe hat zu viele Spalten." + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1163 parser/parse_coerce.c:1211 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "Argument von %s muss Typ %s haben, nicht Typ %s" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1174 parser/parse_coerce.c:1223 +#, c-format +msgid "argument of %s must not return a set" +msgstr "Argument von %s darf keine Ergebnismenge zurückgeben" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1363 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "%s-Typen %s und %s passen nicht zusammen" + +#: parser/parse_coerce.c:1475 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "Argumenttypen %s und %s passen nicht zusammen" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1527 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%s konnte Typ %s nicht in %s umwandeln" + +#: parser/parse_coerce.c:2089 parser/parse_coerce.c:2109 +#: parser/parse_coerce.c:2129 parser/parse_coerce.c:2149 +#: parser/parse_coerce.c:2204 parser/parse_coerce.c:2237 +#, c-format +msgid "arguments declared \"%s\" are not all alike" +msgstr "als »%s« deklarierte Argumente sind nicht alle gleich" + +#: parser/parse_coerce.c:2183 parser/parse_coerce.c:2297 +#: utils/fmgr/funcapi.c:489 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "als %s deklariertes Argument ist kein Array sondern Typ %s" + +#: parser/parse_coerce.c:2216 parser/parse_coerce.c:2329 +#: utils/fmgr/funcapi.c:503 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "als %s deklariertes Argument ist kein Bereichstyp sondern Typ %s" + +#: parser/parse_coerce.c:2250 parser/parse_coerce.c:2363 +#: utils/fmgr/funcapi.c:521 utils/fmgr/funcapi.c:586 +#, c-format +msgid "argument declared %s is not a multirange type but type %s" +msgstr "als %s deklariertes Argument ist kein Multirange-Typ sondern Typ %s" + +#: parser/parse_coerce.c:2288 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "kann Elementtyp des Arguments mit Typ »anyarray« nicht bestimmen" + +#: parser/parse_coerce.c:2314 parser/parse_coerce.c:2346 +#: parser/parse_coerce.c:2380 parser/parse_coerce.c:2400 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "als %s deklariertes Argument ist nicht mit als %s deklariertem Argument konsistent" + +#: parser/parse_coerce.c:2427 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "konnte polymorphischen Typ nicht bestimmen, weil Eingabe Typ %s hat" + +#: parser/parse_coerce.c:2441 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "mit »anynonarray« gepaarter Typ ist ein Array-Typ: %s" + +#: parser/parse_coerce.c:2451 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "mit »anyenum« gepaarter Typ ist kein Enum-Typ: %s" + +#: parser/parse_coerce.c:2482 parser/parse_coerce.c:2532 +#: parser/parse_coerce.c:2596 parser/parse_coerce.c:2643 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "konnte polymorphischen Typ %s nicht bestimmen, weil Eingabe Typ %s hat" + +#: parser/parse_coerce.c:2492 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "anycompatiblerange-Typ %s stimmt nicht mit anycompatible-Typ %s überein" + +#: parser/parse_coerce.c:2506 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "mit »anycompatiblenonarray« gepaarter Typ ist ein Array-Typ: %s" + +#: parser/parse_coerce.c:2607 parser/parse_coerce.c:2658 +#: utils/fmgr/funcapi.c:614 +#, c-format +msgid "could not find multirange type for data type %s" +msgstr "konnte Multirange-Typ für Datentyp %s nicht finden" + +#: parser/parse_coerce.c:2739 +#, fuzzy, c-format +#| msgid "A result of type %s requires at least one input of type %s." +msgid "A result of type %s requires at least one input of type anyrange or anymultirange." +msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ %s." + +#: parser/parse_coerce.c:2756 +#, fuzzy, c-format +#| msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgid "A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange." +msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ anycompatible, anycompatiblearray, anycompatiblenonarray oder anycompatiblerange." + +#: parser/parse_coerce.c:2768 +#, fuzzy, c-format +#| msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange." +msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange." +msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ anyelement, anyarray, anynonarray, anyenum oder anyrange." + +#: parser/parse_coerce.c:2780 +#, c-format +msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "Ein Ergebnis mit Typ %s benötigt mindestens eine Eingabe mit Typ anycompatible, anycompatiblearray, anycompatiblenonarray oder anycompatiblerange." + +#: parser/parse_coerce.c:2810 +msgid "A result of type internal requires at least one input of type internal." +msgstr "Ein Ergebnis mit Typ internal benötigt mindestens eine Eingabe mit Typ internal." + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:1004 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "implizite Sortierfolgen »%s« und »%s« stimmen nicht überein" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:1007 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "Sie können die Sortierfolge auswählen, indem Sie die COLLATE-Klausel auf einen oder beide Ausdrücke anwenden." + +#: parser/parse_collate.c:854 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "explizite Sortierfolgen »%s« und »%s« stimmen nicht überein" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht in ihrem nicht-rekursiven Teilausdruck erscheinen" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht in einer Unteranfrage erscheinen" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht in einem äußeren Verbund erscheinen" + +#: parser/parse_cte.c:52 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht in INTERSECT erscheinen" + +#: parser/parse_cte.c:54 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht in EXCEPT erscheinen" + +#: parser/parse_cte.c:136 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "WIHT-Anfragename »%s« mehrmals angegeben" + +#: parser/parse_cte.c:268 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "WITH-Klausel mit datenmodifizierender Anweisung muss auf der obersten Ebene sein" + +#: parser/parse_cte.c:317 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "Spalte %2$d in rekursiver Anfrage »%1$s« hat Typ %3$s im nicht-rekursiven Teilausdruck aber Typ %4$s insgesamt" + +#: parser/parse_cte.c:323 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Wandeln Sie die Ausgabe des nicht-rekursiven Teilausdrucks in den korrekten Typ um." + +#: parser/parse_cte.c:328 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "Spalte %2$d in rekursiver Anfrage »%1$s« hat Sortierfolge %3$s im nicht-rekursiven Teilausdruck aber Sortierfolge %4$s insgesamt" + +#: parser/parse_cte.c:332 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "Verwenden Sie die COLLATE-Klausel, um die Sortierfolge des nicht-rekursiven Teilsausdrucks zu setzen." + +#: parser/parse_cte.c:350 +#, c-format +msgid "WITH query is not recursive" +msgstr "WITH-Anfrage ist nicht rekursiv" + +#: parser/parse_cte.c:381 +#, c-format +msgid "with a SEARCH or CYCLE clause, the left side of the UNION must be a SELECT" +msgstr "mit einer SEARCH- oder CYCLE-Klausel muss die linke Seite von UNION ein SELECT sein" + +#: parser/parse_cte.c:386 +#, c-format +msgid "with a SEARCH or CYCLE clause, the right side of the UNION must be a SELECT" +msgstr "mit einer SEARCH- oder CYCLE-Klausel muss mit rechte Seite von UNION ein SELECT sein" + +#: parser/parse_cte.c:401 +#, c-format +msgid "search column \"%s\" not in WITH query column list" +msgstr "Search-Spalte »%s« ist nicht in der Spaltenliste der WITH-Anfrage" + +#: parser/parse_cte.c:408 +#, c-format +msgid "search column \"%s\" specified more than once" +msgstr "Search-Spalte »%s« mehrmals angegeben" + +#: parser/parse_cte.c:417 +#, c-format +msgid "search sequence column name \"%s\" already used in WITH query column list" +msgstr "Search-Sequenz-Spaltenname »%s« schon in Spaltenliste der WITH-Anfrage verwendet" + +#: parser/parse_cte.c:436 +#, c-format +msgid "cycle column \"%s\" not in WITH query column list" +msgstr "Cycle-Spalte »%s« ist nicht in der Spaltenliste der WITH-Anfrage" + +#: parser/parse_cte.c:443 +#, c-format +msgid "cycle column \"%s\" specified more than once" +msgstr "Zyklusspalte »%s« mehrmals angegeben" + +#: parser/parse_cte.c:452 +#, c-format +msgid "cycle mark column name \"%s\" already used in WITH query column list" +msgstr "Zyklusmarkierungsspaltenname »%s« schon in Spaltenliste der WITH-Anfrage verwendet" + +#: parser/parse_cte.c:464 +#, c-format +msgid "cycle path column name \"%s\" already used in WITH query column list" +msgstr "Zykluspfadspaltenname »%s« schon in Spaltenliste der WITH-Anfrage verwendet" + +#: parser/parse_cte.c:472 +#, c-format +msgid "cycle mark column name and cycle path column name are the same" +msgstr "Zyklusmarkierungsspaltenname und Zykluspfadspaltenname sind gleich" + +#: parser/parse_cte.c:508 +#, c-format +msgid "could not identify an inequality operator for type %s" +msgstr "konnte keinen Ist-Ungleich-Operator für Typ %s ermitteln" + +#: parser/parse_cte.c:520 +#, c-format +msgid "search sequence column name and cycle mark column name are the same" +msgstr "Search-Sequenz-Spaltenname und Zyklusmarkierungsspaltenname sind gleich" + +#: parser/parse_cte.c:527 +#, c-format +msgid "search sequence column name and cycle path column name are the same" +msgstr "Search-Sequenz-Spaltenname und Zykluspfadspaltenname sind gleich" + +#: parser/parse_cte.c:611 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "WITH-Anfrage »%s« hat %d Spalten verfügbar, aber %d Spalten wurden angegeben" + +#: parser/parse_cte.c:791 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "gegenseitige Rekursion zwischen WITH-Elementen ist nicht implementiert" + +#: parser/parse_cte.c:843 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "rekursive Anfrage »%s« darf keine datenmodifizierenden Anweisungen enthalten" + +#: parser/parse_cte.c:851 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "rekursive Anfrage »%s« hat nicht die Form nicht-rekursiver-Ausdruck UNION [ALL] rekursiver-Ausdruck" + +#: parser/parse_cte.c:895 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "ORDER BY in einer rekursiven Anfrage ist nicht implementiert" + +#: parser/parse_cte.c:901 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "OFFSET in einer rekursiven Anfrage ist nicht implementiert" + +#: parser/parse_cte.c:907 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "LIMIT in einer rekursiven Anfrage ist nicht implementiert" + +#: parser/parse_cte.c:913 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "FOR UPDATE/SHARE in einer rekursiven Anfrage ist nicht implementiert" + +#: parser/parse_cte.c:970 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht mehrmals erscheinen" + +#: parser/parse_expr.c:287 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "DEFAULT ist in diesem Zusammenhang nicht erlaubt" + +#: parser/parse_expr.c:340 parser/parse_relation.c:3592 +#: parser/parse_relation.c:3612 +#, c-format +msgid "column %s.%s does not exist" +msgstr "Spalte %s.%s existiert nicht" + +#: parser/parse_expr.c:352 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "Spalte »%s« nicht gefunden im Datentyp %s" + +#: parser/parse_expr.c:358 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "konnte Spalte »%s« im Record-Datentyp nicht identifizieren" + +#: parser/parse_expr.c:364 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "Spaltenschreibweise .%s mit Typ %s verwendet, der kein zusammengesetzter Typ ist" + +#: parser/parse_expr.c:395 parser/parse_target.c:740 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "Zeilenexpansion mit »*« wird hier nicht unterstützt" + +#: parser/parse_expr.c:516 +msgid "cannot use column reference in DEFAULT expression" +msgstr "Spaltenverweise können nicht in DEFAULT-Ausdrücken verwendet werden" + +#: parser/parse_expr.c:519 +msgid "cannot use column reference in partition bound expression" +msgstr "Spaltenverweise können nicht in Partitionsbegrenzungsausdrücken verwendet werden" + +#: parser/parse_expr.c:788 parser/parse_relation.c:807 +#: parser/parse_relation.c:889 parser/parse_target.c:1235 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "Spaltenverweis »%s« ist nicht eindeutig" + +#: parser/parse_expr.c:844 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:208 parser/parse_param.c:307 +#, c-format +msgid "there is no parameter $%d" +msgstr "es gibt keinen Parameter $%d" + +#: parser/parse_expr.c:1044 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULLIF erfordert, dass Operator = boolean ergibt" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1050 parser/parse_expr.c:2965 +#, c-format +msgid "%s must not return a set" +msgstr "%s darf keine Ergebnismenge zurückgeben" + +#: parser/parse_expr.c:1430 parser/parse_expr.c:1462 +#, c-format +msgid "number of columns does not match number of values" +msgstr "Anzahl der Spalten stimmt nicht mit der Anzahl der Werte überein" + +#: parser/parse_expr.c:1476 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "die Quelle für ein UPDATE-Element mit mehreren Spalten muss ein Sub-SELECT oder ein ROW()-Ausdruck sein" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1671 parser/parse_expr.c:2144 parser/parse_func.c:2560 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "Funktionen mit Ergebnismenge sind in %s nicht erlaubt" + +#: parser/parse_expr.c:1733 +msgid "cannot use subquery in check constraint" +msgstr "Unteranfragen können nicht in Check-Constraints verwendet werden" + +#: parser/parse_expr.c:1737 +msgid "cannot use subquery in DEFAULT expression" +msgstr "Unteranfragen können nicht in DEFAULT-Ausdrücken verwendet werden" + +#: parser/parse_expr.c:1740 +msgid "cannot use subquery in index expression" +msgstr "Unteranfragen können nicht in Indexausdrücken verwendet werden" + +#: parser/parse_expr.c:1743 +msgid "cannot use subquery in index predicate" +msgstr "Unteranfragen können nicht im Indexprädikat verwendet werden" + +#: parser/parse_expr.c:1746 +msgid "cannot use subquery in statistics expression" +msgstr "Unteranfragen können nicht in Statistikausdrücken verwendet werden" + +#: parser/parse_expr.c:1749 +msgid "cannot use subquery in transform expression" +msgstr "Unteranfragen können in Umwandlungsausdrücken nicht verwendet werden" + +#: parser/parse_expr.c:1752 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "Unteranfragen können nicht in EXECUTE-Parameter verwendet werden" + +#: parser/parse_expr.c:1755 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "Unteranfragen können nicht in der WHEN-Bedingung eines Triggers verwendet werden" + +#: parser/parse_expr.c:1758 +msgid "cannot use subquery in partition bound" +msgstr "Unteranfragen können nicht in Partitionsbegrenzungen verwendet werden" + +#: parser/parse_expr.c:1761 +msgid "cannot use subquery in partition key expression" +msgstr "Unteranfragen können nicht in Partitionierungsschlüsselausdrücken verwendet werden" + +#: parser/parse_expr.c:1764 +msgid "cannot use subquery in CALL argument" +msgstr "Unteranfragen können nicht in CALL-Argument verwendet werden" + +#: parser/parse_expr.c:1767 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "Unteranfragen können nicht in COPY-FROM-WHERE-Bedingungen verwendet werden" + +#: parser/parse_expr.c:1770 +msgid "cannot use subquery in column generation expression" +msgstr "Unteranfragen können nicht in Spaltengenerierungsausdrücken verwendet werden" + +#: parser/parse_expr.c:1823 +#, c-format +msgid "subquery must return only one column" +msgstr "Unteranfrage darf nur eine Spalte zurückgeben" + +#: parser/parse_expr.c:1894 +#, c-format +msgid "subquery has too many columns" +msgstr "Unteranfrage hat zu viele Spalten" + +#: parser/parse_expr.c:1899 +#, c-format +msgid "subquery has too few columns" +msgstr "Unteranfrage hat zu wenige Spalten" + +#: parser/parse_expr.c:1995 +#, c-format +msgid "cannot determine type of empty array" +msgstr "kann Typ eines leeren Arrays nicht bestimmen" + +#: parser/parse_expr.c:1996 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "Wandeln Sie ausdrücklich in den gewünschten Typ um, zum Beispiel ARRAY[]::integer[]." + +#: parser/parse_expr.c:2010 +#, c-format +msgid "could not find element type for data type %s" +msgstr "konnte Elementtyp für Datentyp %s nicht finden" + +#: parser/parse_expr.c:2290 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "unbenannter XML-Attributwert muss ein Spaltenverweis sein" + +#: parser/parse_expr.c:2291 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "unbenannter XML-Elementwert muss ein Spaltenverweis sein" + +#: parser/parse_expr.c:2306 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "XML-Attributname »%s« einscheint mehrmals" + +#: parser/parse_expr.c:2413 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "kann das Ergebnis von XMLSERIALIZE nicht in Typ %s umwandeln" + +#: parser/parse_expr.c:2722 parser/parse_expr.c:2918 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "ungleiche Anzahl Einträge in Zeilenausdrücken" + +#: parser/parse_expr.c:2732 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "kann Zeilen mit Länge null nicht vergleichen" + +#: parser/parse_expr.c:2757 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "Zeilenvergleichsoperator muss Typ boolean zurückgeben, nicht Typ %s" + +#: parser/parse_expr.c:2764 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "Zeilenvergleichsoperator darf keine Ergebnismenge zurückgeben" + +#: parser/parse_expr.c:2823 parser/parse_expr.c:2864 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "konnte Interpretation des Zeilenvergleichsoperators %s nicht bestimmen" + +#: parser/parse_expr.c:2825 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "Zeilenvergleichsoperatoren müssen einer »btree«-Operatorfamilie zugeordnet sein." + +#: parser/parse_expr.c:2866 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Es gibt mehrere gleichermaßen plausible Kandidaten." + +#: parser/parse_expr.c:2959 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROM erfordert, dass Operator = boolean ergibt" + +#: parser/parse_func.c:192 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "Argumentname »%s« mehrmals angegeben" + +#: parser/parse_func.c:203 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "Positionsargument kann nicht hinter benanntem Argument stehen" + +#: parser/parse_func.c:286 parser/parse_func.c:2257 +#, c-format +msgid "%s is not a procedure" +msgstr "%s ist keine Prozedur" + +#: parser/parse_func.c:290 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Um eine Funktion aufzurufen, verwenden Sie SELECT." + +#: parser/parse_func.c:296 +#, c-format +msgid "%s is a procedure" +msgstr "%s ist eine Prozedur" + +#: parser/parse_func.c:300 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Um eine Prozedur aufzurufen, verwenden Sie CALL." + +#: parser/parse_func.c:314 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) angegeben, aber %s ist keine Aggregatfunktion" + +#: parser/parse_func.c:321 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT wurde angegeben, aber %s ist keine Aggregatfunktion" + +#: parser/parse_func.c:327 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP wurde angegeben, aber %s ist keine Aggregatfunktion" + +#: parser/parse_func.c:333 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY angegeben, aber %s ist keine Aggregatfunktion" + +#: parser/parse_func.c:339 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER wurde angegeben, aber %s ist keine Aggregatfunktion" + +#: parser/parse_func.c:345 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER angegeben, aber %s ist keine Fensterfunktion oder Aggregatfunktion" + +#: parser/parse_func.c:383 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "WITHIN GROUP muss angegeben werden für Ordered-Set-Aggregatfunktion %s" + +#: parser/parse_func.c:389 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "OVER wird für Ordered-Set-Aggregatfunktion %s nicht unterstützt" + +#: parser/parse_func.c:420 parser/parse_func.c:451 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct argument, not %d." +msgid_plural "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr[0] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt %d direktes Argument, nicht %d." +msgstr[1] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt %d direkte Argumente, nicht %d." + +#: parser/parse_func.c:478 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "Um die Hypothetical-Set-Aggregatfunktion %s zu verwenden, muss die Anzahl der hypothetischen direkten Argumente (hier %d) mit der Anzahl der Sortierspalten (hier %d) übereinstimmen." + +#: parser/parse_func.c:492 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct argument." +msgid_plural "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr[0] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt mindestens %d direktes Argument." +msgstr[1] "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt mindestens %d direkte Argumente." + +#: parser/parse_func.c:513 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s ist keine Ordered-Set-Aggregatfunktion und kann deshalb kein WITHIN GROUP haben" + +#: parser/parse_func.c:526 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "Fensterfunktion %s erfordert eine OVER-Klausel" + +#: parser/parse_func.c:533 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "Fensterfunktion %s kann kein WITHIN GROUP haben" + +#: parser/parse_func.c:562 +#, c-format +msgid "procedure %s is not unique" +msgstr "Prozedur %s ist nicht eindeutig" + +#: parser/parse_func.c:565 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "Konnte keine beste Kandidatprozedur auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_func.c:571 +#, c-format +msgid "function %s is not unique" +msgstr "Funktion %s ist nicht eindeutig" + +#: parser/parse_func.c:574 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "Konnte keine beste Kandidatfunktion auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_func.c:613 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "Keine Aggregatfunktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Mõglicherweise steht ORDER BY an der falschen Stelle; ORDER BY muss hinter allen normalen Argumenten der Aggregatfunktion stehen." + +#: parser/parse_func.c:621 parser/parse_func.c:2300 +#, c-format +msgid "procedure %s does not exist" +msgstr "Prozedur %s existiert nicht" + +#: parser/parse_func.c:624 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Keine Prozedur stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_func.c:633 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "Keine Funktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_func.c:735 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "VARIADIC-Argument muss ein Array sein" + +#: parser/parse_func.c:789 parser/parse_func.c:853 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "beim Aufruf einer parameterlosen Aggregatfunktion muss %s(*) angegeben werden" + +#: parser/parse_func.c:796 +#, c-format +msgid "aggregates cannot return sets" +msgstr "Aggregatfunktionen können keine Ergebnismengen zurückgeben" + +#: parser/parse_func.c:811 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "Aggregatfunktionen können keine benannten Argumente verwenden" + +#: parser/parse_func.c:843 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "DISTINCT ist für Fensterfunktionen nicht implementiert" + +#: parser/parse_func.c:863 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "ORDER BY in Aggregatfunktion ist für Fensterfunktionen nicht implementiert" + +#: parser/parse_func.c:872 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "FILTER ist für Fensterfunktionen, die keine Aggregatfunktionen sind, nicht implementiert" + +#: parser/parse_func.c:881 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "Aufrufe von Fensterfunktionen können keine Aufrufe von Funktionen mit Ergebnismenge enthalten" + +#: parser/parse_func.c:889 +#, c-format +msgid "window functions cannot return sets" +msgstr "Fensterfunktionen können keine Ergebnismengen zurückgeben" + +#: parser/parse_func.c:2138 parser/parse_func.c:2329 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "konnte keine Funktion namens »%s« finden" + +#: parser/parse_func.c:2152 parser/parse_func.c:2347 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "Funktionsname »%s« ist nicht eindeutig" + +#: parser/parse_func.c:2154 parser/parse_func.c:2349 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Geben Sie eine Argumentliste an, um die Funktion eindeutig auszuwählen." + +#: parser/parse_func.c:2198 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "Prozeduren können nicht mehr als %d Argument haben" +msgstr[1] "Prozeduren können nicht mehr als %d Argumente haben" + +#: parser/parse_func.c:2247 +#, c-format +msgid "%s is not a function" +msgstr "%s ist keine Funktion" + +#: parser/parse_func.c:2267 +#, c-format +msgid "function %s is not an aggregate" +msgstr "Funktion %s ist keine Aggregatfunktion" + +#: parser/parse_func.c:2295 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "konnte keine Prozedur namens »%s« finden" + +#: parser/parse_func.c:2309 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "konnte keine Aggregatfunktion namens »%s« finden" + +#: parser/parse_func.c:2314 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "Aggregatfunktion %s(*) existiert nicht" + +#: parser/parse_func.c:2319 +#, c-format +msgid "aggregate %s does not exist" +msgstr "Aggregatfunktion %s existiert nicht" + +#: parser/parse_func.c:2354 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "Prozedurname »%s« ist nicht eindeutig" + +#: parser/parse_func.c:2356 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Geben Sie eine Argumentliste an, um die Prozedur eindeutig auszuwählen." + +#: parser/parse_func.c:2361 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "Aggregatfunktionsname »%s« ist nicht eindeutig" + +#: parser/parse_func.c:2363 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Geben Sie eine Argumentliste an, um die Aggregatfunktion eindeutig auszuwählen." + +#: parser/parse_func.c:2368 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "Routinenname »%s« ist nicht eindeutig" + +#: parser/parse_func.c:2370 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Geben Sie eine Argumentliste an, um die Routine eindeutig auszuwählen." + +#: parser/parse_func.c:2425 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "Funktionen mit Ergebnismenge sind in JOIN-Bedingungen nicht erlaubt" + +#: parser/parse_func.c:2446 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "Funktionen mit Ergebnismenge sind in Policy-Ausdrücken nicht erlaubt" + +#: parser/parse_func.c:2462 +msgid "set-returning functions are not allowed in window definitions" +msgstr "Funktionen mit Ergebnismenge sind in Fensterdefinitionen nicht erlaubt" + +#: parser/parse_func.c:2500 +msgid "set-returning functions are not allowed in check constraints" +msgstr "Funktionen mit Ergebnismenge sind in Check-Constraints nicht erlaubt" + +#: parser/parse_func.c:2504 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "Funktionen mit Ergebnismenge sind in DEFAULT-Ausdrücken nicht erlaubt" + +#: parser/parse_func.c:2507 +msgid "set-returning functions are not allowed in index expressions" +msgstr "Funktionen mit Ergebnismenge sind in Indexausdrücken nicht erlaubt" + +#: parser/parse_func.c:2510 +msgid "set-returning functions are not allowed in index predicates" +msgstr "Funktionen mit Ergebnismenge sind in Indexprädikaten nicht erlaubt" + +#: parser/parse_func.c:2513 +msgid "set-returning functions are not allowed in statistics expressions" +msgstr "Funktionen mit Ergebnismenge sind in Statistikausdrücken nicht erlaubt" + +#: parser/parse_func.c:2516 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "Funktionen mit Ergebnismenge sind in Umwandlungsausdrücken nicht erlaubt" + +#: parser/parse_func.c:2519 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "Funktionen mit Ergebnismenge sind in EXECUTE-Parametern nicht erlaubt" + +#: parser/parse_func.c:2522 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "Funktionen mit Ergebnismenge sind in der WHEN-Bedingung eines Triggers nicht erlaubt" + +#: parser/parse_func.c:2525 +msgid "set-returning functions are not allowed in partition bound" +msgstr "Funktionen mit Ergebnismenge sind in Partitionsbegrenzungen nicht erlaubt" + +#: parser/parse_func.c:2528 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "Funktionen mit Ergebnismenge sind in Partitionierungsschlüsselausdrücken nicht erlaubt" + +#: parser/parse_func.c:2531 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "Funktionen mit Ergebnismenge sind in CALL-Argumenten nicht erlaubt" + +#: parser/parse_func.c:2534 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "Funktionen mit Ergebnismenge sind in COPY-FROM-WHERE-Bedingungen nicht erlaubt" + +#: parser/parse_func.c:2537 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "Funktionen mit Ergebnismenge sind in Spaltengenerierungsausdrücken nicht erlaubt" + +#: parser/parse_node.c:87 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "Targetlisten können höchstens %d Einträge haben" + +#: parser/parse_oper.c:123 parser/parse_oper.c:690 +#, fuzzy, c-format +#| msgid "postfix operators are not supported anymore (operator \"%s\")" +msgid "postfix operators are not supported" +msgstr "Postfix-Operatoren werden nicht mehr unterstützt (Operator »%s«)" + +#: parser/parse_oper.c:130 parser/parse_oper.c:649 utils/adt/regproc.c:538 +#: utils/adt/regproc.c:722 +#, c-format +msgid "operator does not exist: %s" +msgstr "Operator existiert nicht: %s" + +#: parser/parse_oper.c:229 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Verwenden Sie einen ausdrücklichen Sortieroperator oder ändern Sie die Anfrage." + +#: parser/parse_oper.c:485 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "Operator erfordert Typumwandlung zur Laufzeit: %s" + +#: parser/parse_oper.c:641 +#, c-format +msgid "operator is not unique: %s" +msgstr "Operator ist nicht eindeutig: %s" + +#: parser/parse_oper.c:643 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "Konnte keinen besten Kandidatoperator auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_oper.c:652 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Kein Operator stimmt mit dem angegebenen Namen und Argumenttyp überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_oper.c:654 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "Kein Operator stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_oper.c:714 parser/parse_oper.c:828 +#, c-format +msgid "operator is only a shell: %s" +msgstr "Operator ist nur eine Hülle: %s" + +#: parser/parse_oper.c:816 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (array) erfordert Array auf der rechten Seite" + +#: parser/parse_oper.c:858 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (array) erfordert, dass Operator boolean ergibt" + +#: parser/parse_oper.c:863 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (array) erfordert, dass Operator keine Ergebnismenge zurückgibt" + +#: parser/parse_param.c:225 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "inkonsistente Typen für Parameter $%d ermittelt" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "Tabellenbezug »%s« ist nicht eindeutig" + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "Tabellenbezug %u ist nicht eindeutig" + +#: parser/parse_relation.c:445 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "Tabellenname »%s« mehrmals angegeben" + +#: parser/parse_relation.c:474 parser/parse_relation.c:3532 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "ungültiger Verweis auf FROM-Klausel-Eintrag für Tabelle »%s«" + +#: parser/parse_relation.c:478 parser/parse_relation.c:3537 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Es gibt einen Eintrag für Tabelle »%s«, aber auf ihn kann aus diesem Teil der Anfrage nicht verwiesen werden." + +#: parser/parse_relation.c:480 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "Der JOIN-Typ für LATERAL muss INNER oder LEFT sein." + +#: parser/parse_relation.c:691 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "Verweis auf Systemspalte »%s« im Check-Constraint ist ungültig" + +#: parser/parse_relation.c:700 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "Systemspalte »%s« kann nicht in Spaltengenerierungsausdruck verwendet werden" + +#: parser/parse_relation.c:1173 parser/parse_relation.c:1625 +#: parser/parse_relation.c:2302 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "Tabelle »%s« hat %d Spalten, aber %d Spalten wurden angegeben" + +#: parser/parse_relation.c:1377 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "Es gibt ein WITH-Element namens »%s«, aber darauf kann aus diesem Teil der Anfrage kein Bezug genommen werden." + +#: parser/parse_relation.c:1379 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "Verwenden Sie WITH RECURSIVE oder sortieren Sie die WITH-Ausdrücke um, um Vorwärtsreferenzen zu entfernen." + +#: parser/parse_relation.c:1767 +#, fuzzy, c-format +#| msgid "a column definition list is required for functions returning \"record\"" +msgid "a column definition list is redundant for a function with OUT parameters" +msgstr "eine Spaltendefinitionsliste ist erforderlich bei Funktionen, die »record« zurückgeben" + +#: parser/parse_relation.c:1773 +#, fuzzy, c-format +#| msgid "a column definition list is required for functions returning \"record\"" +msgid "a column definition list is redundant for a function returning a named composite type" +msgstr "eine Spaltendefinitionsliste ist erforderlich bei Funktionen, die »record« zurückgeben" + +#: parser/parse_relation.c:1780 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "eine Spaltendefinitionsliste ist nur erlaubt bei Funktionen, die »record« zurückgeben" + +#: parser/parse_relation.c:1791 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "eine Spaltendefinitionsliste ist erforderlich bei Funktionen, die »record« zurückgeben" + +#: parser/parse_relation.c:1880 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "Funktion »%s« in FROM hat nicht unterstützten Rückgabetyp %s" + +#: parser/parse_relation.c:2089 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "VALUES-Liste »%s« hat %d Spalten verfügbar, aber %d Spalten wurden angegeben" + +#: parser/parse_relation.c:2161 +#, c-format +msgid "joins can have at most %d columns" +msgstr "Verbunde können höchstens %d Spalten haben" + +#: parser/parse_relation.c:2275 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "WITH-Anfrage »%s« hat keine RETURNING-Klausel" + +#: parser/parse_relation.c:3307 parser/parse_relation.c:3317 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "Spalte %d von Relation »%s« existiert nicht" + +#: parser/parse_relation.c:3535 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Vielleicht wurde beabsichtigt, auf den Tabellenalias »%s« zu verweisen." + +#: parser/parse_relation.c:3543 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "fehlender Eintrag in FROM-Klausel für Tabelle »%s«" + +#: parser/parse_relation.c:3595 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Vielleicht wurde beabsichtigt, auf die Spalte »%s.%s« zu verweisen." + +#: parser/parse_relation.c:3597 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Es gibt eine Spalte namens »%s« in Tabelle »%s«, aber auf sie kann aus diesem Teil der Anfrage nicht verwiesen werden." + +#: parser/parse_relation.c:3614 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "Vielleicht wurde beabsichtigt, auf die Spalte »%s.%s« oder die Spalte »%s.%s« zu verweisen." + +#: parser/parse_target.c:483 parser/parse_target.c:804 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "kann Systemspalte »%s« keinen Wert zuweisen" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "kann Arrayelement nicht auf DEFAULT setzen" + +#: parser/parse_target.c:516 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "kann Subfeld nicht auf DEFAULT setzen" + +#: parser/parse_target.c:590 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "Spalte »%s« hat Typ %s, aber der Ausdruck hat Typ %s" + +#: parser/parse_target.c:788 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "kann Feld »%s« in Spalte »%s« nicht setzen, weil ihr Typ %s kein zusammengesetzter Typ ist" + +#: parser/parse_target.c:797 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "kann Feld »%s« in Spalte »%s« nicht setzen, weil es keine solche Spalte in Datentyp %s gibt" + +#: parser/parse_target.c:878 +#, fuzzy, c-format +#| msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgid "subscripted assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "Wertzuweisung für »%s« erfordert Typ %s, aber Ausdruck hat Typ %s" + +#: parser/parse_target.c:888 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "Subfeld »%s« hat Typ %s, aber der Ausdruck hat Typ %s" + +#: parser/parse_target.c:1323 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "SELECT * ist nicht gültig, wenn keine Tabellen angegeben sind" + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "falscher %%TYPE-Verweis (zu wenige Namensteile): %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "falscher %%TYPE-Verweis (zu viele Namensteile): %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "Typverweis %s in %s umgewandelt" + +#: parser/parse_type.c:278 parser/parse_type.c:803 utils/cache/typcache.c:389 +#: utils/cache/typcache.c:444 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "Typ »%s« ist nur eine Hülle" + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "Typmodifikator ist für Typ »%s« nicht erlaubt" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "Typmodifikatoren müssen einfache Konstanten oder Bezeichner sein" + +#: parser/parse_type.c:721 parser/parse_type.c:766 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "ungültiger Typname: »%s«" + +#: parser/parse_utilcmd.c:266 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "partitionierte Tabelle kann nicht als Vererbungskind erzeugt werden" + +#: parser/parse_utilcmd.c:580 +#, c-format +msgid "array of serial is not implemented" +msgstr "Array aus Typ serial ist nicht implementiert" + +#: parser/parse_utilcmd.c:659 parser/parse_utilcmd.c:671 +#: parser/parse_utilcmd.c:730 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "widersprüchliche NULL/NOT NULL-Deklarationen für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:683 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "mehrere Vorgabewerte angegeben für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:700 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "Identitätsspalten in getypten Tabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:704 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "Identitätsspalten in partitionierten Tabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:713 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "mehrere Identitätsangaben für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:743 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "generierte Spalten in getypten Tabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:747 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "generierte Spalten in partitionierten Tabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:752 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "mehrere Generierungsklauseln angegeben für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:770 parser/parse_utilcmd.c:885 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "Primärschlüssel für Fremdtabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:779 parser/parse_utilcmd.c:895 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "Unique-Constraints auf Fremdtabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:824 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "sowohl Vorgabewert als auch Identität angegeben für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:832 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "sowohl Vorgabewert als auch Generierungsausdruck angegeben für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:840 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "sowohl Identität als auch Generierungsausdruck angegeben für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:905 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "Exclusion-Constraints auf Fremdtabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:911 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "Exclusion-Constraints auf partitionierten Tabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:976 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "LIKE wird für das Erzeugen von Fremdtabellen nicht unterstützt" + +#: parser/parse_utilcmd.c:1753 parser/parse_utilcmd.c:1861 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "Index »%s« enthält einen Verweis auf die ganze Zeile der Tabelle." + +#: parser/parse_utilcmd.c:2248 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "bestehender Index kann nicht in CREATE TABLE verwendet werden" + +#: parser/parse_utilcmd.c:2268 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "Index »%s« gehört bereits zu einem Constraint" + +#: parser/parse_utilcmd.c:2283 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "Index »%s« ist nicht gültig" + +#: parser/parse_utilcmd.c:2289 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "»%s« ist kein Unique Index" + +#: parser/parse_utilcmd.c:2290 parser/parse_utilcmd.c:2297 +#: parser/parse_utilcmd.c:2304 parser/parse_utilcmd.c:2381 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "Ein Primärschlüssel oder Unique-Constraint kann nicht mit einem solchen Index erzeugt werden." + +#: parser/parse_utilcmd.c:2296 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "Index »%s« enthält Ausdrücke" + +#: parser/parse_utilcmd.c:2303 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "»%s« ist ein partieller Index" + +#: parser/parse_utilcmd.c:2315 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "»%s« ist ein aufschiebbarer Index" + +#: parser/parse_utilcmd.c:2316 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "Ein nicht aufschiebbarer Constraint kann nicht mit einem aufschiebbaren Index erzeugt werden." + +#: parser/parse_utilcmd.c:2380 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "Index »%s« Spalte Nummer %d hat nicht das Standardsortierverhalten" + +#: parser/parse_utilcmd.c:2537 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "Spalte »%s« erscheint zweimal im Primärschlüssel-Constraint" + +#: parser/parse_utilcmd.c:2543 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "Spalte »%s« erscheint zweimal im Unique-Constraint" + +#: parser/parse_utilcmd.c:2896 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "Indexausdrücke und -prädikate können nur auf die zu indizierende Tabelle verweisen" + +#: parser/parse_utilcmd.c:2974 +#, c-format +msgid "statistics expressions can refer only to the table being indexed" +msgstr "Statistikausdrücke können nur auf die zu indizierende Tabelle verweisen" + +#: parser/parse_utilcmd.c:3020 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "Regeln für materialisierte Sichten werden nicht unterstützt" + +#: parser/parse_utilcmd.c:3083 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "WHERE-Bedingung einer Regel kann keine Verweise auf andere Relationen enthalten" + +#: parser/parse_utilcmd.c:3157 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "Regeln mit WHERE-Bedingungen können als Aktion nur SELECT, INSERT, UPDATE oder DELETE haben" + +#: parser/parse_utilcmd.c:3175 parser/parse_utilcmd.c:3276 +#: rewrite/rewriteHandler.c:508 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "UNION/INTERSECTION/EXCEPT mit Bedingung sind nicht implementiert" + +#: parser/parse_utilcmd.c:3193 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "ON-SELECT-Regel kann nicht OLD verwenden" + +#: parser/parse_utilcmd.c:3197 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "ON-SELECT-Regel kann nicht NEW verwenden" + +#: parser/parse_utilcmd.c:3206 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "ON-INSERT-Regel kann nicht OLD verwenden" + +#: parser/parse_utilcmd.c:3212 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "ON-DELETE-Regel kann nicht NEW verwenden" + +#: parser/parse_utilcmd.c:3240 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "in WITH-Anfrage kann nicht auf OLD verweisen werden" + +#: parser/parse_utilcmd.c:3247 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "in WITH-Anfrage kann nicht auf NEW verwiesen werden" + +#: parser/parse_utilcmd.c:3706 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "falsch platzierte DEFERRABLE-Klausel" + +#: parser/parse_utilcmd.c:3711 parser/parse_utilcmd.c:3726 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "mehrere DEFERRABLE/NOT DEFERRABLE-Klauseln sind nicht erlaubt" + +#: parser/parse_utilcmd.c:3721 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "falsch platzierte NOT DEFERRABLE-Klausel" + +#: parser/parse_utilcmd.c:3742 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "falsch platzierte INITIALLY DEFERRED-Klausel" + +#: parser/parse_utilcmd.c:3747 parser/parse_utilcmd.c:3773 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "mehrere INITIALLY IMMEDIATE/DEFERRED-Klauseln sind nicht erlaubt" + +#: parser/parse_utilcmd.c:3768 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "falsch platzierte INITIALLY IMMEDIATE-Klausel" + +#: parser/parse_utilcmd.c:3959 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE gibt ein Schema an (%s) welches nicht gleich dem zu erzeugenden Schema ist (%s)" + +#: parser/parse_utilcmd.c:3994 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "»%s« ist keine partitionierte Tabelle" + +#: parser/parse_utilcmd.c:4001 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "Tabelle »%s« ist nicht partitioniert" + +#: parser/parse_utilcmd.c:4008 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "Index »%s« ist nicht partitioniert" + +#: parser/parse_utilcmd.c:4048 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "eine hashpartitionierte Tabelle kann keine Standardpartition haben" + +#: parser/parse_utilcmd.c:4065 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "ungültige Begrenzungsangabe für eine Hash-Partition" + +#: parser/parse_utilcmd.c:4071 partitioning/partbounds.c:4701 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "Modulus für Hashpartition muss eine positive ganze Zahl sein" + +#: parser/parse_utilcmd.c:4078 partitioning/partbounds.c:4709 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "Rest für Hashpartition muss kleiner als Modulus sein" + +#: parser/parse_utilcmd.c:4091 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "ungültige Begrenzungsangabe für eine Listenpartition" + +#: parser/parse_utilcmd.c:4144 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "ungültige Begrenzungsangabe für eine Bereichspartition" + +#: parser/parse_utilcmd.c:4150 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM muss genau einen Wert pro Partitionierungsspalte angeben" + +#: parser/parse_utilcmd.c:4154 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO muss genau einen Wert pro Partitionierungsspalte angeben" + +#: parser/parse_utilcmd.c:4268 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "NULL kann nicht in der Bereichsgrenze angegeben werden" + +#: parser/parse_utilcmd.c:4317 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "jede Begrenzung, die auf MAXVALUE folgt, muss auch MAXVALUE sein" + +#: parser/parse_utilcmd.c:4324 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "jede Begrenzung, die auf MINVALUE folgt, muss auch MINVALUE sein" + +#: parser/parse_utilcmd.c:4367 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "angegebener Wert kann nicht in Typ %s für Spalte »%s« umgewandelt werden" + +#: parser/parser.c:247 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "auf UESCAPE muss eine einfache Zeichenkettenkonstante folgen" + +#: parser/parser.c:252 +msgid "invalid Unicode escape character" +msgstr "ungültiges Unicode-Escape-Zeichen" + +#: parser/parser.c:321 scan.l:1329 +#, c-format +msgid "invalid Unicode escape value" +msgstr "ungültiger Unicode-Escape-Wert" + +#: parser/parser.c:468 scan.l:677 utils/adt/varlena.c:6566 +#, c-format +msgid "invalid Unicode escape" +msgstr "ungültiges Unicode-Escape" + +#: parser/parser.c:469 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "Unicode-Escapes müssen \\XXXX oder \\+XXXXXX sein." + +#: parser/parser.c:497 scan.l:638 scan.l:654 scan.l:670 +#: utils/adt/varlena.c:6591 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "ungültiges Unicode-Surrogatpaar" + +#: parser/scansup.c:101 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%.*s\"" +msgstr "Bezeichner »%s« wird auf »%.*s« gekürzt" + +#: partitioning/partbounds.c:2821 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "Partition »%s« kollidiert mit bestehender Standardpartition »%s«" + +#: partitioning/partbounds.c:2870 partitioning/partbounds.c:2888 +#: partitioning/partbounds.c:2904 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "der Modulus jeder Hashpartition muss ein Faktor des nächstgrößeren Modulus sein" + +#: partitioning/partbounds.c:2871 partitioning/partbounds.c:2905 +#, c-format +msgid "The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\"." +msgstr "Der neue Modulus %d ist kein Faktor von %d, dem Modulus der bestehenden Partition »%s«." + +#: partitioning/partbounds.c:2889 +#, c-format +msgid "The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\"." +msgstr "Der neue Modulus %d ist nicht durch %d, den Modulus der bestehenden Parition »%s«, teilbar." + +#: partitioning/partbounds.c:3018 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "leere Bereichsgrenze angegeben für Partition »%s«" + +#: partitioning/partbounds.c:3020 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Angegebene Untergrenze %s ist größer als oder gleich der Obergrenze %s." + +#: partitioning/partbounds.c:3132 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" + +#: partitioning/partbounds.c:3249 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "Scannen von Fremdtabelle »%s«, die eine Partition der Standardpartition »%s« ist, wurde übersprungen" + +#: partitioning/partbounds.c:4705 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "Rest für Hashpartition muss eine nichtnegative ganze Zahl sein" + +#: partitioning/partbounds.c:4729 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "»%s« ist keine Hash-partitionierte Tabelle" + +#: partitioning/partbounds.c:4740 partitioning/partbounds.c:4857 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "Anzahl der Partitionierungsspalten (%d) stimmt nicht mit der Anzahl der angegebenen Partitionierungsschlüssel (%d) überein" + +#: partitioning/partbounds.c:4762 +#, c-format +msgid "column %d of the partition key has type %s, but supplied value is of type %s" +msgstr "Spalte %d des Partitionierungsschlüssels hat Typ %s, aber der angegebene Wert hat Typ %s" + +#: partitioning/partbounds.c:4794 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "Spalte %d des Partitionierungsschlüssels hat Typ »%s«, aber der angegebene Wert hat Typ »%s«" + +#: port/pg_sema.c:209 port/pg_shmem.c:668 port/posix_sema.c:209 +#: port/sysv_sema.c:327 port/sysv_shmem.c:668 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "konnte »stat« für Datenverzeichnis »%s« nicht ausführen: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "konnte Shared-Memory-Segment nicht erzeugen: %m" + +#: port/pg_shmem.c:218 port/sysv_shmem.c:218 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "Fehlgeschlagener Systemaufruf war shmget(Key=%lu, Größe=%zu, 0%o)." + +#: port/pg_shmem.c:222 port/sysv_shmem.c:222 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Dieser Fehler bedeutet gewöhnlich, dass das von PostgreSQL angeforderte Shared-Memory-Segment den Kernel-Parameter SHMMAX überschreitet, oder eventuell, dass es kleiner als der Kernel-Parameter SHMMIN ist.\n" +"Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." + +#: port/pg_shmem.c:229 port/sysv_shmem.c:229 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Dieser Fehler bedeutet gewöhnlich, dass das von PostgreSQL angeforderte Shared-Memory-Segment den Kernel-Parameter SHMALL überschreitet. Sie müssen eventuell den Kernel mit einem größeren SHMALL neu konfigurieren.\n" +"Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." + +#: port/pg_shmem.c:235 port/sysv_shmem.c:235 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Dieser Fehler bedeutet *nicht*, dass kein Platz mehr auf der Festplatte ist. Er tritt auf, wenn entweder alle verfügbaren Shared-Memory-IDs aufgebraucht sind, dann müssen den Kernelparameter SHMMNI erhöhen, oder weil die Systemhöchstgrenze für Shared Memory insgesamt erreicht wurde.\n" +"Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." + +#: port/pg_shmem.c:606 port/sysv_shmem.c:606 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "konnte anonymes Shared Memory nicht mappen: %m" + +#: port/pg_shmem.c:608 port/sysv_shmem.c:608 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "" +"Dieser Fehler bedeutet gewöhnlich, dass das von PostgreSQL angeforderte Shared-Memory-Segment den verfügbaren Speicher, Swap-Space oder Huge Pages überschreitet. Um die benötigte Shared-Memory-Größe zu reduzieren (aktuell %zu Bytes), reduzieren Sie den Shared-Memory-Verbrauch von PostgreSQL, beispielsweise indem Sie »shared_buffers« oder »max_connections« reduzieren.\n" +"Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." + +#: port/pg_shmem.c:676 port/sysv_shmem.c:676 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "Huge Pages werden auf dieser Plattform nicht unterstützt" + +#: port/pg_shmem.c:737 port/sysv_shmem.c:737 utils/init/miscinit.c:1167 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "bereits bestehender Shared-Memory-Block (Schlüssel %lu, ID %lu) wird noch benutzt" + +#: port/pg_shmem.c:740 port/sysv_shmem.c:740 utils/init/miscinit.c:1169 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Beenden Sie alle alten Serverprozesse, die zum Datenverzeichnis »%s« gehören." + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "konnte Semaphore nicht erzeugen: %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "Fehlgeschlagener Systemaufruf war semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:129 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"Dieser Fehler bedeutet *nicht*, dass kein Platz mehr auf der Festplatte ist. Er tritt auf, wenn entweder die Systemhöchstgrenze für die Anzahl Semaphor-Sets (SEMMNI) oder die Systemhöchstgrenze für die Anzahl Semaphore (SEMMNS) überschritten würde. Sie müssen den entsprechenden Kernelparameter erhöhen. Alternativ können Sie den Semaphorverbrauch von PostgreSQL reduzieren indem Sie den Parameter »max_connections« herabsetzen.\n" +"Die PostgreSQL-Dokumentation enthält weitere Informationen, wie Sie Ihr System für PostgreSQL konfigurieren können." + +#: port/sysv_sema.c:159 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "Sie müssen möglicherweise den Kernelparameter SEMVMX auf mindestens %d erhöhen. Weitere Informationen finden Sie in der PostgreSQL-Dokumentation." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "konnte dbghelp.dll nicht laden, kann Crash-Dump nicht schreiben\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "konnte benötigte Funktionen in dbghelp.dll nicht laden, kann Crash-Dump nicht schreiben\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "konnte Crash-Dump-Datei »%s« nicht zum Schreiben öffnen: Fehlercode %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "Crash-Dump nach Datei »%s« geschrieben\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "konnte Crash-Dump nicht nach Datei »%s« schreiben: Fehlercode %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "konnte Listener-Pipe für Signale für PID %d nicht erzeugen: Fehlercode %lu" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "konnte Listener-Pipe für Signale nicht erzeugen: Fehlercode %lu; wiederhole Versuch\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "konnte Semaphore nicht erzeugen: Fehlercode %lu" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "konnte Semaphore nicht sperren: Fehlercode %lu" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "konnte Semaphore nicht entsperren: Fehlercode %lu" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "konnte Semaphore nicht versuchsweise sperren: Fehlercode %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:159 port/win32_shmem.c:171 +#: port/win32_shmem.c:187 +#, c-format +msgid "could not enable user right \"%s\": error code %lu" +msgstr "konnte Benutzerrecht »%s« nicht aktivieren: Fehlercode %lu" + +#. translator: This is a term from Windows and should be translated to +#. match the Windows localization. +#. +#: port/win32_shmem.c:150 port/win32_shmem.c:159 port/win32_shmem.c:171 +#: port/win32_shmem.c:182 port/win32_shmem.c:184 port/win32_shmem.c:187 +msgid "Lock pages in memory" +msgstr "Sperren von Seiten im Speicher" + +#: port/win32_shmem.c:152 port/win32_shmem.c:160 port/win32_shmem.c:172 +#: port/win32_shmem.c:188 +#, c-format +msgid "Failed system call was %s." +msgstr "Fehlgeschlagener Systemaufruf war %s." + +#: port/win32_shmem.c:182 +#, c-format +msgid "could not enable user right \"%s\"" +msgstr "konnte Benutzerrecht »%s« nicht aktivieren" + +#: port/win32_shmem.c:183 +#, c-format +msgid "Assign user right \"%s\" to the Windows user account which runs PostgreSQL." +msgstr "Weisen Sie dem Windows-Benutzerkonto, unter dem PostgreSQL läuft, das Benutzerrecht »%s« zu." + +#: port/win32_shmem.c:241 +#, c-format +msgid "the processor does not support large pages" +msgstr "der Prozessor unterstützt keine Large Pages" + +#: port/win32_shmem.c:310 port/win32_shmem.c:346 port/win32_shmem.c:364 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "konnte Shared-Memory-Segment nicht erzeugen: Fehlercode %lu" + +#: port/win32_shmem.c:311 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "Fehlgeschlagener Systemaufruf war CreateFileMapping(Größe=%zu, Name=%s)." + +#: port/win32_shmem.c:336 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "bereits bestehender Shared-Memory-Block wird noch benutzt" + +#: port/win32_shmem.c:337 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "Prüfen Sie, ob irgendwelche alten Serverprozesse noch laufen und beenden Sie diese." + +#: port/win32_shmem.c:347 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "Fehlgeschlagener Systemaufruf war DuplicateHandle." + +#: port/win32_shmem.c:365 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "Fehlgeschlagener Systemaufruf war MapViewOfFileEx." + +#: postmaster/autovacuum.c:411 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "konnte Autovacuum-Launcher-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/autovacuum.c:1489 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "konnte Autovacuum-Worker-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/autovacuum.c:2326 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "Autovacuum: lösche verwaiste temporäre Tabelle »%s.%s.%s«" + +#: postmaster/autovacuum.c:2555 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "automatisches Vacuum der Tabelle »%s.%s.%s«" + +#: postmaster/autovacuum.c:2558 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "automatisches Analysieren der Tabelle »%s.%s.%s«" + +#: postmaster/autovacuum.c:2751 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "verarbeite Arbeitseintrag für Relation »%s.%s.%s«" + +#: postmaster/autovacuum.c:3432 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "Autovacuum wegen Fehlkonfiguration nicht gestartet" + +#: postmaster/autovacuum.c:3433 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "Schalten Sie die Option »track_counts« ein." + +#: postmaster/bgworker.c:256 +#, c-format +msgid "inconsistent background worker state (max_worker_processes=%d, total_slots=%d)" +msgstr "inkonsistenter Background-Worker-Zustand (max_worker_processes=%d, total_slots=%d)" + +#: postmaster/bgworker.c:661 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "Background-Worker »%s«: muss mit Shared Memory verbinden, um eine Datenbankverbindung anzufordern" + +#: postmaster/bgworker.c:670 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "Background-Worker »%s«: kann kein Datenbankzugriff anfordern, wenn er nach Postmaster-Start gestartet hat" + +#: postmaster/bgworker.c:684 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "Background-Worker »%s«: ungültiges Neustart-Intervall" + +#: postmaster/bgworker.c:699 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "Background-Worker »%s«: parallele Arbeitsprozesse dürfen nicht für Neustart konfiguriert sein" + +#: postmaster/bgworker.c:723 tcop/postgres.c:3188 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "Background-Worker »%s« wird abgebrochen aufgrund von Anweisung des Administrators" + +#: postmaster/bgworker.c:904 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "Background-Worker »%s«: muss in shared_preload_libraries registriert sein" + +#: postmaster/bgworker.c:916 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "Background-Worker »%s«: nur dynamische Background-Worker können Benachrichtigung verlangen" + +#: postmaster/bgworker.c:931 +#, c-format +msgid "too many background workers" +msgstr "zu viele Background-Worker" + +#: postmaster/bgworker.c:932 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "Mit den aktuellen Einstellungen können bis zu %d Background-Worker registriert werden." +msgstr[1] "Mit den aktuellen Einstellungen können bis zu %d Background-Worker registriert werden." + +#: postmaster/bgworker.c:936 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "Erhöhen Sie eventuell den Konfigurationsparameter »max_worker_processes«." + +#: postmaster/checkpointer.c:428 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "Checkpoints passieren zu oft (alle %d Sekunde)" +msgstr[1] "Checkpoints passieren zu oft (alle %d Sekunden)" + +#: postmaster/checkpointer.c:432 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "Erhöhen Sie eventuell den Konfigurationsparameter »max_wal_size«." + +#: postmaster/checkpointer.c:1056 +#, c-format +msgid "checkpoint request failed" +msgstr "Checkpoint-Anforderung fehlgeschlagen" + +#: postmaster/checkpointer.c:1057 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "Einzelheiten finden Sie in den letzten Meldungen im Serverlog." + +#: postmaster/pgarch.c:372 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode ist an, aber archive_command ist nicht gesetzt" + +#: postmaster/pgarch.c:394 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "verwaiste Archivstatusdatei »%s« wurde entfernt" + +#: postmaster/pgarch.c:404 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "Entfernen der verwaisten Archivstatusdatei »%s« schlug zu oft fehl, wird später erneut versucht" + +#: postmaster/pgarch.c:440 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "Archivieren der Write-Ahead-Log-Datei »%s« schlug zu oft fehl, wird später erneut versucht" + +#: postmaster/pgarch.c:541 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "Archivbefehl ist fehlgeschlagen mit Statuscode %d" + +#: postmaster/pgarch.c:543 postmaster/pgarch.c:553 postmaster/pgarch.c:559 +#: postmaster/pgarch.c:568 +#, c-format +msgid "The failed archive command was: %s" +msgstr "Der fehlgeschlagene Archivbefehl war: %s" + +#: postmaster/pgarch.c:550 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "Archivbefehl wurde durch Ausnahme 0x%X beendet" + +#: postmaster/pgarch.c:552 postmaster/postmaster.c:3724 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "Sehen Sie die Beschreibung des Hexadezimalwerts in der C-Include-Datei »ntstatus.h« nach." + +#: postmaster/pgarch.c:557 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "Archivbefehl wurde von Signal %d beendet: %s" + +#: postmaster/pgarch.c:566 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "Archivbefehl hat mit unbekanntem Status %d beendet" + +#: postmaster/pgstat.c:417 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "konnte »localhost« nicht auflösen: %s" + +#: postmaster/pgstat.c:440 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "andere Adresse für Statistiksammelprozess wird versucht" + +#: postmaster/pgstat.c:449 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "konnte Socket für Statistiksammelprozess nicht erzeugen: %m" + +#: postmaster/pgstat.c:461 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "konnte Socket für Statistiksammelprozess nicht binden: %m" + +#: postmaster/pgstat.c:472 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "konnte Adresse für Socket für Statistiksammelprozess nicht ermitteln: %m" + +#: postmaster/pgstat.c:488 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "konnte nicht mit Socket für Statistiksammelprozess verbinden: %m" + +#: postmaster/pgstat.c:509 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "konnte Testnachricht auf Socket für Statistiksammelprozess nicht senden: %m" + +#: postmaster/pgstat.c:535 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "select() im Statistiksammelprozess fehlgeschlagen: %m" + +#: postmaster/pgstat.c:550 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "Testnachricht auf Socket für Statistiksammelprozess kam nicht durch" + +#: postmaster/pgstat.c:565 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "konnte Testnachricht auf Socket für Statistiksammelprozess nicht empfangen: %m" + +#: postmaster/pgstat.c:575 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "fehlerhafte Übertragung der Testnachricht auf Socket für Statistiksammelprozess" + +#: postmaster/pgstat.c:598 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "konnte Socket von Statistiksammelprozess nicht auf nicht blockierenden Modus setzen: %m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "Statistiksammelprozess abgeschaltet wegen nicht funkionierender Socket" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "konnte Statistiksammelprozess nicht starten (fork-Fehler): %m" + +#: postmaster/pgstat.c:1459 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "unbekanntes Reset-Ziel: »%s«" + +#: postmaster/pgstat.c:1460 +#, fuzzy, c-format +#| msgid "Target must be \"archiver\" or \"bgwriter\"." +msgid "Target must be \"archiver\", \"bgwriter\" or \"wal\"." +msgstr "Das Reset-Ziel muss »archiver« oder »bgwriter« sein." + +#: postmaster/pgstat.c:3298 +#, c-format +msgid "could not read statistics message: %m" +msgstr "konnte Statistiknachricht nicht lesen: %m" + +#: postmaster/pgstat.c:3644 postmaster/pgstat.c:3829 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "konnte temporäre Statistikdatei »%s« nicht öffnen: %m" + +#: postmaster/pgstat.c:3739 postmaster/pgstat.c:3874 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "konnte temporäre Statistikdatei »%s« nicht schreiben: %m" + +#: postmaster/pgstat.c:3748 postmaster/pgstat.c:3883 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "konnte temporäre Statistikdatei »%s« nicht schließen: %m" + +#: postmaster/pgstat.c:3756 postmaster/pgstat.c:3891 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "konnte temporäre Statistikdatei »%s« nicht in »%s« umbenennen: %m" + +#: postmaster/pgstat.c:3989 postmaster/pgstat.c:4255 postmaster/pgstat.c:4412 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "konnte Statistikdatei »%s« nicht öffnen: %m" + +#: postmaster/pgstat.c:4001 postmaster/pgstat.c:4011 postmaster/pgstat.c:4032 +#: postmaster/pgstat.c:4043 postmaster/pgstat.c:4054 postmaster/pgstat.c:4076 +#: postmaster/pgstat.c:4091 postmaster/pgstat.c:4161 postmaster/pgstat.c:4192 +#: postmaster/pgstat.c:4267 postmaster/pgstat.c:4287 postmaster/pgstat.c:4305 +#: postmaster/pgstat.c:4321 postmaster/pgstat.c:4339 postmaster/pgstat.c:4355 +#: postmaster/pgstat.c:4424 postmaster/pgstat.c:4436 postmaster/pgstat.c:4448 +#: postmaster/pgstat.c:4459 postmaster/pgstat.c:4470 postmaster/pgstat.c:4495 +#: postmaster/pgstat.c:4522 postmaster/pgstat.c:4535 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "verfälschte Statistikdatei »%s«" + +#: postmaster/pgstat.c:4644 +#, c-format +msgid "statistics collector's time %s is later than backend local time %s" +msgstr "" + +#: postmaster/pgstat.c:4667 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "verwende veraltete Statistiken anstatt aktueller, weil der Statistiksammelprozess nicht antwortet" + +#: postmaster/pgstat.c:4794 +#, c-format +msgid "stats_timestamp %s is later than collector's time %s for database %u" +msgstr "" + +#: postmaster/pgstat.c:5004 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "Datenbank-Hash-Tabelle beim Aufräumen verfälscht --- Abbruch" + +#: postmaster/postmaster.c:745 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: ungültiges Argument für Option -f: »%s«\n" + +#: postmaster/postmaster.c:824 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: ungültiges Argument für Option -t: »%s«\n" + +#: postmaster/postmaster.c:875 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: ungültiges Argument: »%s«\n" + +#: postmaster/postmaster.c:917 +#, c-format +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) muss kleiner als max_connections (%d) sein\n" + +#: postmaster/postmaster.c:924 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "WAL-Archivierung kann nicht eingeschaltet werden, wenn wal_level »minimal« ist" + +#: postmaster/postmaster.c:927 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WAL-Streaming (max_wal_senders > 0) benötigt wal_level »replica« oder »logical«" + +#: postmaster/postmaster.c:935 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: ungültige datetoken-Tabellen, bitte reparieren\n" + +#: postmaster/postmaster.c:1052 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "konnte Ein-/Ausgabe-Completion-Port für Child-Queue nicht erzeugen" + +#: postmaster/postmaster.c:1117 +#, c-format +msgid "ending log output to stderr" +msgstr "Logausgabe nach stderr endet" + +#: postmaster/postmaster.c:1118 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "Die weitere Logausgabe geht an Logziel »%s«." + +#: postmaster/postmaster.c:1129 +#, c-format +msgid "starting %s" +msgstr "%s startet" + +#: postmaster/postmaster.c:1158 postmaster/postmaster.c:1257 +#: utils/init/miscinit.c:1627 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "ungültige Listensyntax für Parameter »%s«" + +#: postmaster/postmaster.c:1189 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "konnte Listen-Socket für »%s« nicht erzeugen" + +#: postmaster/postmaster.c:1195 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "konnte keine TCP/IP-Sockets erstellen" + +#: postmaster/postmaster.c:1227 +#, c-format +msgid "DNSServiceRegister() failed: error code %ld" +msgstr "DNSServiceRegister() fehlgeschlagen: Fehlercode %ld" + +#: postmaster/postmaster.c:1279 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "konnte Unix-Domain-Socket in Verzeichnis »%s« nicht erzeugen" + +#: postmaster/postmaster.c:1285 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "konnte keine Unix-Domain-Sockets erzeugen" + +#: postmaster/postmaster.c:1297 +#, c-format +msgid "no socket created for listening" +msgstr "keine Listen-Socket erzeugt" + +#: postmaster/postmaster.c:1328 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: konnte Rechte der externen PID-Datei »%s« nicht ändern: %s\n" + +#: postmaster/postmaster.c:1332 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: konnte externe PID-Datei »%s« nicht schreiben: %s\n" + +#: postmaster/postmaster.c:1365 utils/init/postinit.c:216 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "konnte pg_hba.conf nicht laden" + +#: postmaster/postmaster.c:1391 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "Postmaster ist während des Starts multithreaded geworden" + +#: postmaster/postmaster.c:1392 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "Setzen Sie die Umgebungsvariable LC_ALL auf eine gültige Locale." + +#: postmaster/postmaster.c:1487 +#, c-format +msgid "%s: could not locate my own executable path" +msgstr "%s: konnte Pfad des eigenen Programs nicht finden" + +#: postmaster/postmaster.c:1494 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: konnte kein passendes Programm »postgres« finden" + +#: postmaster/postmaster.c:1517 utils/misc/tzparser.c:340 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "Dies kann auf eine unvollständige PostgreSQL-Installation hindeuten, oder darauf, dass die Datei »%s« von ihrer richtigen Stelle verschoben worden ist." + +#: postmaster/postmaster.c:1544 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: konnte das Datenbanksystem nicht finden\n" +"Es wurde im Verzeichnis »%s« erwartet,\n" +"aber die Datei »%s« konnte nicht geöffnet werden: %s\n" + +#: postmaster/postmaster.c:1721 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "select() fehlgeschlagen im Postmaster: %m" + +#: postmaster/postmaster.c:1857 +#, c-format +msgid "issuing SIGKILL to recalcitrant children" +msgstr "" + +#: postmaster/postmaster.c:1878 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "führe sofortiges Herunterfahren durch, weil Sperrdatei im Datenverzeichnis ungültig ist" + +#: postmaster/postmaster.c:1981 postmaster/postmaster.c:2009 +#, c-format +msgid "incomplete startup packet" +msgstr "unvollständiges Startpaket" + +#: postmaster/postmaster.c:1993 +#, c-format +msgid "invalid length of startup packet" +msgstr "ungültige Länge des Startpakets" + +#: postmaster/postmaster.c:2048 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "konnte SSL-Verhandlungsantwort nicht senden: %m" + +#: postmaster/postmaster.c:2080 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "konnte GSSAPI-Verhandlungsantwort nicht senden: %m" + +#: postmaster/postmaster.c:2110 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "nicht unterstütztes Frontend-Protokoll %u.%u: Server unterstützt %u.0 bis %u.%u" + +#: postmaster/postmaster.c:2174 utils/misc/guc.c:7112 utils/misc/guc.c:7148 +#: utils/misc/guc.c:7218 utils/misc/guc.c:8550 utils/misc/guc.c:11506 +#: utils/misc/guc.c:11547 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "ungültiger Wert für Parameter »%s«: »%s«" + +#: postmaster/postmaster.c:2177 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "Gültige Werte sind: »false«, 0, »true«, 1, »database«." + +#: postmaster/postmaster.c:2222 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "ungültiges Layout des Startpakets: Abschluss als letztes Byte erwartet" + +#: postmaster/postmaster.c:2239 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "kein PostgreSQL-Benutzername im Startpaket angegeben" + +#: postmaster/postmaster.c:2303 +#, c-format +msgid "the database system is starting up" +msgstr "das Datenbanksystem startet" + +#: postmaster/postmaster.c:2309 +#, c-format +msgid "the database system is not yet accepting connections" +msgstr "das Datenbanksystem nimmt noch keine Verbindungen an" + +#: postmaster/postmaster.c:2310 +#, c-format +msgid "Consistent recovery state has not been yet reached." +msgstr "Konsistenter Wiederherstellungszustand wurde noch nicht erreicht." + +#: postmaster/postmaster.c:2314 +#, c-format +msgid "the database system is not accepting connections" +msgstr "das Datenbanksystem nimmt keine Verbindungen an" + +#: postmaster/postmaster.c:2315 +#, c-format +msgid "Hot standby mode is disabled." +msgstr "Hot-Standby-Modus ist deaktiviert." + +#: postmaster/postmaster.c:2320 +#, c-format +msgid "the database system is shutting down" +msgstr "das Datenbanksystem fährt herunter" + +#: postmaster/postmaster.c:2325 +#, c-format +msgid "the database system is in recovery mode" +msgstr "das Datenbanksystem ist im Wiederherstellungsmodus" + +#: postmaster/postmaster.c:2330 storage/ipc/procarray.c:463 +#: storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:361 +#, c-format +msgid "sorry, too many clients already" +msgstr "tut mir leid, schon zu viele Verbindungen" + +#: postmaster/postmaster.c:2420 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "falscher Schlüssel in Stornierungsanfrage für Prozess %d" + +#: postmaster/postmaster.c:2432 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "PID %d in Stornierungsanfrage stimmte mit keinem Prozess überein" + +#: postmaster/postmaster.c:2686 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "SIGHUP empfangen, Konfigurationsdateien werden neu geladen" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2712 postmaster/postmaster.c:2716 +#, c-format +msgid "%s was not reloaded" +msgstr "%s wurde nicht neu geladen" + +#: postmaster/postmaster.c:2726 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "SSL-Konfiguration wurde nicht neu geladen" + +#: postmaster/postmaster.c:2782 +#, c-format +msgid "received smart shutdown request" +msgstr "intelligentes Herunterfahren verlangt" + +#: postmaster/postmaster.c:2828 +#, c-format +msgid "received fast shutdown request" +msgstr "schnelles Herunterfahren verlangt" + +#: postmaster/postmaster.c:2846 +#, c-format +msgid "aborting any active transactions" +msgstr "etwaige aktive Transaktionen werden abgebrochen" + +#: postmaster/postmaster.c:2870 +#, c-format +msgid "received immediate shutdown request" +msgstr "sofortiges Herunterfahren verlangt" + +#: postmaster/postmaster.c:2947 +#, c-format +msgid "shutdown at recovery target" +msgstr "Herunterfahren beim Wiederherstellungsziel" + +#: postmaster/postmaster.c:2965 postmaster/postmaster.c:3001 +msgid "startup process" +msgstr "Startprozess" + +#: postmaster/postmaster.c:2968 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "Serverstart abgebrochen wegen Startprozessfehler" + +#: postmaster/postmaster.c:3043 +#, c-format +msgid "database system is ready to accept connections" +msgstr "Datenbanksystem ist bereit, um Verbindungen anzunehmen" + +#: postmaster/postmaster.c:3064 +msgid "background writer process" +msgstr "Background-Writer-Prozess" + +#: postmaster/postmaster.c:3118 +msgid "checkpointer process" +msgstr "Checkpointer-Prozess" + +#: postmaster/postmaster.c:3134 +msgid "WAL writer process" +msgstr "WAL-Schreibprozess" + +#: postmaster/postmaster.c:3149 +msgid "WAL receiver process" +msgstr "WAL-Receiver-Prozess" + +#: postmaster/postmaster.c:3164 +msgid "autovacuum launcher process" +msgstr "Autovacuum-Launcher-Prozess" + +#: postmaster/postmaster.c:3182 +msgid "archiver process" +msgstr "Archivierprozess" + +#: postmaster/postmaster.c:3197 +msgid "statistics collector process" +msgstr "Statistiksammelprozess" + +#: postmaster/postmaster.c:3211 +msgid "system logger process" +msgstr "Systemlogger-Prozess" + +#: postmaster/postmaster.c:3275 +#, c-format +msgid "background worker \"%s\"" +msgstr "Background-Worker »%s«" + +#: postmaster/postmaster.c:3359 postmaster/postmaster.c:3379 +#: postmaster/postmaster.c:3386 postmaster/postmaster.c:3404 +msgid "server process" +msgstr "Serverprozess" + +#: postmaster/postmaster.c:3458 +#, c-format +msgid "terminating any other active server processes" +msgstr "aktive Serverprozesse werden abgebrochen" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3711 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) beendete mit Status %d" + +#: postmaster/postmaster.c:3713 postmaster/postmaster.c:3725 +#: postmaster/postmaster.c:3735 postmaster/postmaster.c:3746 +#, c-format +msgid "Failed process was running: %s" +msgstr "Der fehlgeschlagene Prozess führte aus: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3722 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) wurde durch Ausnahme 0x%X beendet" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3732 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) wurde von Signal %d beendet: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3744 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) beendete mit unbekanntem Status %d" + +#: postmaster/postmaster.c:3959 +#, c-format +msgid "abnormal database system shutdown" +msgstr "abnormales Herunterfahren des Datenbanksystems" + +#: postmaster/postmaster.c:3997 +#, fuzzy, c-format +#| msgid "aborting startup due to startup process failure" +msgid "shutting down due to startup process failure" +msgstr "Serverstart abgebrochen wegen Startprozessfehler" + +#: postmaster/postmaster.c:4003 +#, c-format +msgid "shutting down because restart_after_crash is off" +msgstr "" + +#: postmaster/postmaster.c:4015 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "alle Serverprozesse beendet; initialisiere neu" + +#: postmaster/postmaster.c:4189 postmaster/postmaster.c:5548 +#: postmaster/postmaster.c:5939 +#, c-format +msgid "could not generate random cancel key" +msgstr "konnte zufälligen Stornierungsschlüssel nicht erzeugen" + +#: postmaster/postmaster.c:4243 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "konnte neuen Prozess für Verbindung nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:4285 +msgid "could not fork new process for connection: " +msgstr "konnte neuen Prozess für Verbindung nicht starten (fork-Fehler): " + +#: postmaster/postmaster.c:4391 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "Verbindung empfangen: Host=%s Port=%s" + +#: postmaster/postmaster.c:4396 +#, c-format +msgid "connection received: host=%s" +msgstr "Verbindung empfangen: Host=%s" + +#: postmaster/postmaster.c:4639 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "konnte Serverprozess »%s« nicht ausführen: %m" + +#: postmaster/postmaster.c:4697 +#, fuzzy, c-format +#| msgid "could not close handle to backend parameter variables: error code %lu\n" +msgid "could not create backend parameter file mapping: error code %lu" +msgstr "konnte Handle für Backend-Parametervariablen nicht schließen: Fehlercode %lu\n" + +#: postmaster/postmaster.c:4706 +#, fuzzy, c-format +#| msgid "could not map view of backend variables: error code %lu\n" +msgid "could not map backend parameter memory: error code %lu" +msgstr "konnte Sicht der Backend-Variablen nicht mappen: Fehlercode %lu\n" + +#: postmaster/postmaster.c:4733 +#, fuzzy, c-format +#| msgid "command too long\n" +msgid "subprocess command line too long" +msgstr "Befehl zu lang\n" + +#: postmaster/postmaster.c:4751 +#, fuzzy, c-format +#| msgid "pgpipe: getsockname() failed: error code %d" +msgid "CreateProcess() call failed: %m (error code %lu)" +msgstr "pgpipe: getsockname() fehlgeschlagen: Fehlercode %d" + +#: postmaster/postmaster.c:4778 +#, fuzzy, c-format +#| msgid "could not unmap view of backend variables: error code %lu\n" +msgid "could not unmap view of backend parameter file: error code %lu" +msgstr "konnte Sicht der Backend-Variablen nicht unmappen: Fehlercode %lu\n" + +#: postmaster/postmaster.c:4782 +#, fuzzy, c-format +#| msgid "could not close handle to backend parameter variables: error code %lu\n" +msgid "could not close handle to backend parameter file: error code %lu" +msgstr "konnte Handle für Backend-Parametervariablen nicht schließen: Fehlercode %lu\n" + +#: postmaster/postmaster.c:4804 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "Aufgabe nach zu vielen Versuchen, Shared Memory zu reservieren" + +#: postmaster/postmaster.c:4805 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Dies kann durch ASLR oder Antivirus-Software verursacht werden." + +#: postmaster/postmaster.c:4995 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "SSL-Konfiguration konnte im Kindprozess nicht geladen werden" + +#: postmaster/postmaster.c:5121 +#, c-format +msgid "Please report this to <%s>." +msgstr "Bitte berichten Sie dies an <%s>." + +#: postmaster/postmaster.c:5208 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "Datenbanksystem ist bereit, um lesende Verbindungen anzunehmen" + +#: postmaster/postmaster.c:5472 +#, c-format +msgid "could not fork startup process: %m" +msgstr "konnte Startprozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5476 +#, c-format +msgid "could not fork archiver process: %m" +msgstr "konnte Archivierer-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5480 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "konnte Background-Writer-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5484 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "konnte Checkpointer-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5488 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "konnte WAL-Writer-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5492 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "konnte WAL-Receiver-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5496 +#, c-format +msgid "could not fork process: %m" +msgstr "konnte Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5697 postmaster/postmaster.c:5720 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "die Notwendigkeit, Datenbankverbindungen zu erzeugen, wurde bei der Registrierung nicht angezeigt" + +#: postmaster/postmaster.c:5704 postmaster/postmaster.c:5727 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "ungültiger Verarbeitungsmodus in Background-Worker" + +#: postmaster/postmaster.c:5812 +#, c-format +msgid "could not fork worker process: %m" +msgstr "konnte Worker-Prozess nicht starten (fork-Fehler): %m" + +#: postmaster/postmaster.c:5925 +#, c-format +msgid "no slot available for new worker process" +msgstr "kein Slot für neuen Worker-Prozess verfügbar" + +#: postmaster/postmaster.c:6259 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "konnte Socket %d nicht für Verwendung in Backend duplizieren: Fehlercode %d" + +#: postmaster/postmaster.c:6291 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "konnte geerbtes Socket nicht erzeugen: Fehlercode %d\n" + +#: postmaster/postmaster.c:6320 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "konnte Servervariablendatei »%s« nicht öffnen: %s\n" + +#: postmaster/postmaster.c:6327 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "konnte nicht aus Servervariablendatei »%s« lesen: %s\n" + +#: postmaster/postmaster.c:6336 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "konnte Datei »%s« nicht löschen: %s\n" + +#: postmaster/postmaster.c:6353 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "konnte Sicht der Backend-Variablen nicht mappen: Fehlercode %lu\n" + +#: postmaster/postmaster.c:6362 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "konnte Sicht der Backend-Variablen nicht unmappen: Fehlercode %lu\n" + +#: postmaster/postmaster.c:6369 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "konnte Handle für Backend-Parametervariablen nicht schließen: Fehlercode %lu\n" + +#: postmaster/postmaster.c:6546 +#, c-format +msgid "could not read exit code for process\n" +msgstr "konnte Exitcode des Prozesses nicht lesen\n" + +#: postmaster/postmaster.c:6551 +#, c-format +msgid "could not post child completion status\n" +msgstr "konnte Child-Completion-Status nicht versenden\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "konnte nicht aus Logger-Pipe lesen: %m" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "konnte Pipe für Syslog nicht erzeugen: %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "konnte Systemlogger nicht starten (fork-Fehler): %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "Logausgabe wird an Logsammelprozess umgeleitet" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "Die weitere Logausgabe wird im Verzeichnis »%s« erscheinen." + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "konnte Standardausgabe nicht umleiten: %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "konnte Standardfehlerausgabe nicht umleiten: %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "konnte nicht in Logdatei schreiben: %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "konnte Logdatei »%s« nicht öffnen: %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "automatische Rotation abgeschaltet (SIGHUP zum Wiederanschalten verwenden)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "konnte die für den regulären Ausdruck zu verwendende Sortierfolge nicht bestimmen" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "nichtdeterministische Sortierfolgen werden von regulären Ausdrücken nicht unterstützt" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "ungültige Zeitleiste %u" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "ungültige Streaming-Startposition" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "Zeichenkette in Anführungszeichen nicht abgeschlossen" + +#: replication/backup_manifest.c:255 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "End-Zeitleiste %u wurde erwartet, aber Zeitleiste %u wurde gefunden" + +#: replication/backup_manifest.c:272 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "Start-Zeitleiste %u wurde erwartet, aber Zeitleiste %u wurde gefunden" + +#: replication/backup_manifest.c:299 +#, c-format +msgid "start timeline %u not found in history of timeline %u" +msgstr "Start-Zeitleiste %u nicht in der History der Zeitleiste %u gefunden" + +#: replication/backup_manifest.c:352 +#, c-format +msgid "could not rewind temporary file" +msgstr "konnte Position in temporärer Datei nicht auf Anfang setzen" + +#: replication/backup_manifest.c:379 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "konnte nicht aus temporärer Datei lesen: %m" + +#: replication/basebackup.c:546 +#, c-format +msgid "could not find any WAL files" +msgstr "konnte keine WAL-Dateien finden" + +#: replication/basebackup.c:561 replication/basebackup.c:577 +#: replication/basebackup.c:586 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "konnte WAL-Datei »%s« nicht finden" + +#: replication/basebackup.c:629 replication/basebackup.c:659 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "unerwartete WAL-Dateigröße »%s«" + +#: replication/basebackup.c:644 replication/basebackup.c:1771 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "Basissicherung konnte keine Daten senden, Sicherung abgebrochen" + +#: replication/basebackup.c:722 +#, c-format +msgid "%lld total checksum verification failure" +msgid_plural "%lld total checksum verification failures" +msgstr[0] "%lld Prüfsummenfehler insgesamt" +msgstr[1] "%lld Prüfsummenfehler insgesamt" + +#: replication/basebackup.c:729 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "Prüfsummenüberprüfung bei der Basissicherung fehlgeschlagen" + +#: replication/basebackup.c:789 replication/basebackup.c:798 +#: replication/basebackup.c:807 replication/basebackup.c:816 +#: replication/basebackup.c:825 replication/basebackup.c:836 +#: replication/basebackup.c:853 replication/basebackup.c:862 +#: replication/basebackup.c:874 replication/basebackup.c:898 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "doppelte Option »%s«" + +#: replication/basebackup.c:842 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d ist außerhalb des gültigen Bereichs für Parameter »%s« (%d ... %d)" + +#: replication/basebackup.c:887 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "unbekannte Manifestoption: »%s«" + +#: replication/basebackup.c:903 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "unbekannter Prüfsummenalgorithmus: »%s«" + +#: replication/basebackup.c:918 +#, c-format +msgid "manifest checksums require a backup manifest" +msgstr "Manifest-Prüfsummen benötigen ein Backup-Manifest" + +#: replication/basebackup.c:1519 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "überspringe besondere Datei »%s«" + +#: replication/basebackup.c:1640 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "ungültige Segmentnummer %d in Datei »%s«" + +#: replication/basebackup.c:1678 +#, c-format +msgid "could not verify checksum in file \"%s\", block %u: read buffer size %d and page size %d differ" +msgstr "konnte Prüfsumme in Datei »%s«, Block %u nicht überprüfen: gelesene Puffergröße %d und Seitengröße %d sind verschieden" + +#: replication/basebackup.c:1751 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated %X but expected %X" +msgstr "Prüfsummenüberprüfung fehlgeschlagen in Datei »%s«, Block %u: berechnet %X, aber erwartet %X" + +#: replication/basebackup.c:1758 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "weitere Prüfsummenfehler in Datei »%s« werden nicht berichtet werden" + +#: replication/basebackup.c:1816 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "Datei »%s« hat insgesamt %d Prüfsummenfehler" +msgstr[1] "Datei »%s« hat insgesamt %d Prüfsummenfehler" + +#: replication/basebackup.c:1852 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "Dateiname zu lang für Tar-Format: »%s«" + +#: replication/basebackup.c:1857 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "Ziel der symbolischen Verknüpfung zu lang für Tar-Format: Dateiname »%s«, Ziel »%s«" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, c-format +msgid "could not clear search path: %s" +msgstr "konnte Suchpfad nicht auf leer setzen: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:256 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "ungültige Syntax für Verbindungszeichenkette: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:281 +#, c-format +msgid "could not parse connection string: %s" +msgstr "konnte Verbindungsparameter nicht interpretieren: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:353 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "konnte Datenbanksystemidentifikator und Zeitleisten-ID nicht vom Primärserver empfangen: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:364 +#: replication/libpqwalreceiver/libpqwalreceiver.c:588 +#, c-format +msgid "invalid response from primary server" +msgstr "ungültige Antwort vom Primärserver" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:365 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:440 +#: replication/libpqwalreceiver/libpqwalreceiver.c:446 +#: replication/libpqwalreceiver/libpqwalreceiver.c:475 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "konnte WAL-Streaming nicht starten: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:498 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "konnte End-of-Streaming-Nachricht nicht an Primärserver senden: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:520 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "unerwartete Ergebnismenge nach End-of-Streaming" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:534 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "Fehler beim Beenden des COPY-Datenstroms: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:543 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "Fehler beim Lesen des Ergebnisses von Streaming-Befehl: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 +#: replication/libpqwalreceiver/libpqwalreceiver.c:785 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "unerwartetes Ergebnis nach CommandComplete: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:577 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "konnte Zeitleisten-History-Datei nicht vom Primärserver empfangen: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:589 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "1 Tupel mit 2 Feldern erwartet, %d Tupel mit %d Feldern erhalten." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:749 +#: replication/libpqwalreceiver/libpqwalreceiver.c:800 +#: replication/libpqwalreceiver/libpqwalreceiver.c:806 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "konnte keine Daten vom WAL-Stream empfangen: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:825 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "konnte keine Daten an den WAL-Stream senden: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:878 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:923 +#, c-format +msgid "invalid query response" +msgstr "ungültige Antwort auf Anfrage" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:924 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "%d Felder erwartet, %d Feldern erhalten." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:994 +#, c-format +msgid "the query interface requires a database connection" +msgstr "Ausführen von Anfragen benötigt eine Datenbankverbindung" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1025 +msgid "empty query" +msgstr "leere Anfrage" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1031 +#, fuzzy +#| msgid "unexpected delimiter" +msgid "unexpected pipeline mode" +msgstr "unerwartetes Trennzeichen" + +#: replication/logical/launcher.c:286 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "Arbeitsprozesse für logische Replikation können nicht gestartet werden, wenn max_replication_slots = 0" + +#: replication/logical/launcher.c:366 +#, c-format +msgid "out of logical replication worker slots" +msgstr "alle Slots für Arbeitsprozesse für logische Replikation belegt" + +#: replication/logical/launcher.c:367 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "Sie müssen möglicherweise max_logical_replication_workers erhöhen." + +#: replication/logical/launcher.c:422 +#, c-format +msgid "out of background worker slots" +msgstr "alle Slots für Background-Worker belegt" + +#: replication/logical/launcher.c:423 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "Sie müssen möglicherweise max_worker_processes erhöhen." + +#: replication/logical/launcher.c:577 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "Arbeitsprozess-Slot %d für logische Replikation ist leer, kann nicht zugeteilt werden" + +#: replication/logical/launcher.c:586 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "Arbeitsprozess-Slot %d für logische Replikation wird schon von einem anderen Arbeitsprozess verwendet, kann nicht zugeteilt werden" + +#: replication/logical/logical.c:115 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "logische Dekodierung erfordert wal_level >= logical" + +#: replication/logical/logical.c:120 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "logische Dekodierung benötigt eine Datenbankverbindung" + +#: replication/logical/logical.c:138 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "logische Dekodierung kann nicht während der Wiederherstellung verwendet werden" + +#: replication/logical/logical.c:347 replication/logical/logical.c:499 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "physischer Replikations-Slot kann nicht für logisches Dekodieren verwendet werden" + +#: replication/logical/logical.c:352 replication/logical/logical.c:504 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "Replikations-Slot »%s« wurde nicht in dieser Datenbank erzeugt" + +#: replication/logical/logical.c:359 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "logischer Replikations-Slot kann nicht in einer Transaktion erzeugt werden, die Schreibvorgänge ausgeführt hat" + +#: replication/logical/logical.c:549 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "starte logisches Dekodieren für Slot »%s«" + +#: replication/logical/logical.c:551 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Streaming beginnt bei Transaktionen, die nach %X/%X committen; lese WAL ab %X/%X." + +#: replication/logical/logical.c:696 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s, zugehörige LSN %X/%X" + +#: replication/logical/logical.c:702 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s" + +#: replication/logical/logical.c:868 +#, c-format +msgid "logical replication at prepare time requires begin_prepare_cb callback" +msgstr "" + +#: replication/logical/logical.c:911 +#, c-format +msgid "logical replication at prepare time requires prepare_cb callback" +msgstr "" + +#: replication/logical/logical.c:954 +#, c-format +msgid "logical replication at prepare time requires commit_prepared_cb callback" +msgstr "" + +#: replication/logical/logical.c:998 +#, c-format +msgid "logical replication at prepare time requires rollback_prepared_cb callback" +msgstr "" + +#: replication/logical/logical.c:1220 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_start_cb callback" +msgstr "logische Dekodierung benötigt eine Datenbankverbindung" + +#: replication/logical/logical.c:1266 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_stop_cb callback" +msgstr "logische Dekodierung benötigt eine Datenbankverbindung" + +#: replication/logical/logical.c:1305 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_abort_cb callback" +msgstr "logische Dekodierung benötigt eine Datenbankverbindung" + +#: replication/logical/logical.c:1348 +#, c-format +msgid "logical streaming at prepare time requires a stream_prepare_cb callback" +msgstr "" + +#: replication/logical/logical.c:1387 +#, c-format +msgid "logical streaming requires a stream_commit_cb callback" +msgstr "" + +#: replication/logical/logical.c:1433 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_change_cb callback" +msgstr "logische Dekodierung benötigt eine Datenbankverbindung" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "nur Superuser und Replikationsrollen können Replikations-Slots verwenden" + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "Slot-Name darf nicht NULL sein" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "Optionen-Array darf nicht NULL sein" + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "Array muss eindimensional sein" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "Array darf keine NULL-Werte enthalten" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 +#: utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "Array muss eine gerade Anzahl Elemente haben" + +#: replication/logical/logicalfuncs.c:251 +#, c-format +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "aus Replikations-Slot »%s« können keine Änderungen mehr gelesen werden" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:650 +#, fuzzy, c-format +#| msgid "This slot has never previously reserved WAL, or has been invalidated." +msgid "This slot has never previously reserved WAL, or it has been invalidated." +msgstr "Diese Slot hat nie zuvor WAL reserviert oder er wurde ungültig gemacht." + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "Ausgabe-Plugin »%s« erzeugt binäre Ausgabe, aber Funktion »%s« erwartet Textdaten" + +#: replication/logical/origin.c:188 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "Replication-Origin kann nicht abgefragt oder geändert werden, wenn max_replication_slots = 0" + +#: replication/logical/origin.c:193 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "Replication-Origins können nicht während der Wiederherstellung geändert werden" + +#: replication/logical/origin.c:228 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "Replication-Origin »%s« existiert nicht" + +#: replication/logical/origin.c:319 +#, c-format +msgid "could not find free replication origin OID" +msgstr "konnte keine freie Replication-Origin-OID finden" + +#: replication/logical/origin.c:355 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "konnte Replication-Origin mit OID %d nicht löschen, wird von PID %d verwendet" + +#: replication/logical/origin.c:476 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "Replication-Origin mit OID %u existiert nicht" + +#: replication/logical/origin.c:741 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "Replikations-Checkpoint hat falsche magische Zahl %u statt %u" + +#: replication/logical/origin.c:782 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "konnte keinen freien Replication-State finden, erhöhen Sie max_replication_slots" + +#: replication/logical/origin.c:790 +#, fuzzy, c-format +#| msgid "recovery restart point at %X/%X" +msgid "recovered replication state of node %u to %X/%X" +msgstr "Recovery-Restart-Punkt bei %X/%X" + +#: replication/logical/origin.c:800 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "Replikations-Slot-Checkpoint hat falsche Prüfsumme %u, erwartet wurde %u" + +#: replication/logical/origin.c:928 replication/logical/origin.c:1114 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "Replication-Origin mit OID %d ist bereits aktiv für PID %d" + +#: replication/logical/origin.c:939 replication/logical/origin.c:1126 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "konnte keinen freien Replication-State-Slot für Replication-Origin mit OID %u finden" + +#: replication/logical/origin.c:941 replication/logical/origin.c:1128 +#: replication/slot.c:1798 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "Erhöhen Sie max_replication_slots und versuchen Sie es erneut." + +#: replication/logical/origin.c:1085 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "kann Replication-Origin nicht einrichten, wenn schon einer eingerichtet ist" + +#: replication/logical/origin.c:1165 replication/logical/origin.c:1377 +#: replication/logical/origin.c:1397 +#, c-format +msgid "no replication origin is configured" +msgstr "kein Replication-Origin konfiguriert" + +#: replication/logical/origin.c:1248 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "Replication-Origin-Name »%s« ist reserviert" + +#: replication/logical/origin.c:1250 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "Replication-Origin-Namen, die mit »pg_« anfangen, sind reserviert." + +#: replication/logical/relation.c:248 +#, c-format +msgid "\"%s\"" +msgstr "»%s«" + +#: replication/logical/relation.c:251 +#, c-format +msgid ", \"%s\"" +msgstr ", »%s«" + +#: replication/logical/relation.c:257 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing replicated column: %s" +msgid_plural "logical replication target relation \"%s.%s\" is missing replicated columns: %s" +msgstr[0] "in Zielrelation für logische Replikation »%s.%s« fehlt eine replizierte Spalte: %s" +msgstr[1] "in Zielrelation für logische Replikation »%s.%s« fehlen replizierte Spalten: %s" + +#: replication/logical/relation.c:337 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "Zielrelation für logische Replikation »%s.%s« existiert nicht" + +#: replication/logical/relation.c:418 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "Zielrelation für logische Replikation »%s.%s« verwendet Systemspalten in REPLICA-IDENTITY-Index" + +#: replication/logical/reorderbuffer.c:3777 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "konnte nicht in Datendatei für XID %u schreiben: %m" + +#: replication/logical/reorderbuffer.c:4120 +#: replication/logical/reorderbuffer.c:4145 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %m" + +#: replication/logical/reorderbuffer.c:4124 +#: replication/logical/reorderbuffer.c:4149 +#, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %d statt %u Bytes gelesen" + +#: replication/logical/reorderbuffer.c:4397 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "konnte Datei »%s« nicht löschen, bei Löschen von pg_replslot/%s/xid*: %m" + +#: replication/logical/reorderbuffer.c:4887 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "konnte nicht aus Datei »%s« lesen: %d statt %d Bytes gelesen" + +#: replication/logical/snapbuild.c:588 +#, c-format +msgid "initial slot snapshot too large" +msgstr "initialer Slot-Snapshot ist zu groß" + +#: replication/logical/snapbuild.c:642 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "logischer Dekodierungs-Snapshot exportiert: »%s« mit %u Transaktions-ID" +msgstr[1] "logischer Dekodierungs-Snapshot exportiert: »%s« mit %u Transaktions-IDs" + +#: replication/logical/snapbuild.c:1254 replication/logical/snapbuild.c:1347 +#: replication/logical/snapbuild.c:1878 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "logisches Dekodieren fand konsistenten Punkt bei %X/%X" + +#: replication/logical/snapbuild.c:1256 +#, c-format +msgid "There are no running transactions." +msgstr "Keine laufenden Transaktionen." + +#: replication/logical/snapbuild.c:1298 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "logisches Dekodieren fand initialen Startpunkt bei %X/%X" + +#: replication/logical/snapbuild.c:1300 replication/logical/snapbuild.c:1324 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Warten auf Abschluss der Transaktionen (ungefähr %d), die älter als %u sind." + +#: replication/logical/snapbuild.c:1322 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "logisches Dekodieren fand initialen konsistenten Punkt bei %X/%X" + +#: replication/logical/snapbuild.c:1349 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Es laufen keine alten Transaktionen mehr." + +#: replication/logical/snapbuild.c:1746 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "Scanbuild-State-Datei »%s« hat falsche magische Zahl %u statt %u" + +#: replication/logical/snapbuild.c:1752 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "Snapbuild-State-Datei »%s« hat nicht unterstützte Version: %u statt %u" + +#: replication/logical/snapbuild.c:1823 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "Prüfsummenfehler bei Snapbuild-State-Datei »%s«: ist %u, sollte %u sein" + +#: replication/logical/snapbuild.c:1880 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "Logische Dekodierung beginnt mit gespeichertem Snapshot." + +#: replication/logical/snapbuild.c:1952 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "konnte Dateinamen »%s« nicht parsen" + +#: replication/logical/tablesync.c:144 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat abgeschlossen" + +#: replication/logical/tablesync.c:726 replication/logical/tablesync.c:767 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "konnte Tabelleninformationen für Tabelle »%s.%s« nicht vom Publikationsserver holen: %s" + +#: replication/logical/tablesync.c:732 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "Tabelle »%s.%s« nicht auf dem Publikationsserver gefunden" + +#: replication/logical/tablesync.c:854 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "konnte Kopieren des Anfangsinhalts für Tabelle »%s.%s« nicht starten: %s" + +#: replication/logical/tablesync.c:1053 +#, fuzzy, c-format +#| msgid "table copy could not start transaction on publisher" +msgid "table copy could not start transaction on publisher: %s" +msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht gestartet werden" + +#: replication/logical/tablesync.c:1101 +#, c-format +msgid "replication origin \"%s\" already exists" +msgstr "Replication-Origin »%s« existiert bereits" + +#: replication/logical/tablesync.c:1113 +#, fuzzy, c-format +#| msgid "table copy could not finish transaction on publisher" +msgid "table copy could not finish transaction on publisher: %s" +msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht beenden werden" + +#: replication/logical/worker.c:525 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "Verarbeiten empfangener Daten für Replikationszielrelation »%s.%s« Spalte »%s«, entfernter Typ %s, lokaler Typ %s" + +#: replication/logical/worker.c:605 replication/logical/worker.c:734 +#, fuzzy, c-format +#| msgid "incorrect binary data format in function argument %d" +msgid "incorrect binary data format in logical replication column %d" +msgstr "falsches Binärdatenformat in Funktionsargument %d" + +#: replication/logical/worker.c:813 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "ORIGIN-Nachricht in falscher Reihenfolge gesendet" + +#: replication/logical/worker.c:1072 replication/logical/worker.c:1084 +#, fuzzy, c-format +#| msgid "could not read from backend variables file \"%s\": %s\n" +msgid "could not read from streaming transaction's changes file \"%s\": %m" +msgstr "konnte nicht aus Servervariablendatei »%s« lesen: %s\n" + +#: replication/logical/worker.c:1313 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "Publikationsserver hat nicht die Replikidentitätsspalten gesendet, die von Replikationszielrelation »%s.%s« erwartet wurden" + +#: replication/logical/worker.c:1320 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "Zielrelation für logische Replikation »%s.%s« hat weder REPLICA-IDENTITY-Index noch Primärschlüssel und die publizierte Relation hat kein REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:2039 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "ungültiger Nachrichtentyp für logische Replikation »%c«" + +#: replication/logical/worker.c:2190 +#, c-format +msgid "data stream from publisher has ended" +msgstr "Datenstrom vom Publikationsserver endete" + +#: replication/logical/worker.c:2340 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "Arbeitsprozess für logische Replikation wird abgebrochen wegen Zeitüberschreitung" + +#: replication/logical/worker.c:2488 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription entfernt wurde" + +#: replication/logical/worker.c:2502 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription deaktiviert wurde" + +#: replication/logical/worker.c:2524 +#, fuzzy, c-format +#| msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgid "logical replication apply worker for subscription \"%s\" will restart because of a parameter change" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird neu starten, weil die Subskription umbenannt wurde" + +#: replication/logical/worker.c:2687 replication/logical/worker.c:2709 +#, fuzzy, c-format +#| msgid "could not read from file \"%s\": %m" +msgid "could not read from streaming transaction's subxact file \"%s\": %m" +msgstr "konnte nicht aus Datei »%s« lesen: %m" + +#: replication/logical/worker.c:3055 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "Apply-Worker für logische Replikation für Subskription %u« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" + +#: replication/logical/worker.c:3067 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" + +#: replication/logical/worker.c:3085 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" + +#: replication/logical/worker.c:3089 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« hat gestartet" + +#: replication/logical/worker.c:3126 +#, c-format +msgid "subscription has no replication slot set" +msgstr "für die Subskription ist kein Replikations-Slot gesetzt" + +#: replication/pgoutput/pgoutput.c:195 +#, c-format +msgid "invalid proto_version" +msgstr "ungültige proto_version" + +#: replication/pgoutput/pgoutput.c:200 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version »%s« ist außerhalb des gültigen Bereichs" + +#: replication/pgoutput/pgoutput.c:217 +#, c-format +msgid "invalid publication_names syntax" +msgstr "ungültige Syntax für publication_names" + +#: replication/pgoutput/pgoutput.c:287 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "Client sendete proto_version=%d, aber wir unterstützen nur Protokoll %d oder niedriger" + +#: replication/pgoutput/pgoutput.c:293 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "Client sendete proto_version=%d, aber wir unterstützen nur Protokoll %d oder höher" + +#: replication/pgoutput/pgoutput.c:299 +#, c-format +msgid "publication_names parameter missing" +msgstr "Parameter »publication_names« fehlt" + +#: replication/pgoutput/pgoutput.c:312 +#, fuzzy, c-format +#| msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgid "requested proto_version=%d does not support streaming, need %d or higher" +msgstr "Client sendete proto_version=%d, aber wir unterstützen nur Protokoll %d oder höher" + +#: replication/pgoutput/pgoutput.c:317 +#, fuzzy, c-format +#| msgid "integer of size %lu not supported by pqPutInt" +msgid "streaming requested, but not supported by output plugin" +msgstr "Integer der Größe %lu wird von pqPutInt nicht unterstützt" + +#: replication/slot.c:182 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "Replikations-Slot-Name »%s« ist zu kurz" + +#: replication/slot.c:191 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "Replikations-Slot-Name »%s« ist zu lang" + +#: replication/slot.c:204 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "Replikations-Slot-Name »%s« enthält ungültiges Zeichen" + +#: replication/slot.c:206 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "Replikations-Slot-Namen dürfen nur Kleinbuchstaben, Zahlen und Unterstriche enthalten." + +#: replication/slot.c:260 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "Replikations-Slot »%s« existiert bereits" + +#: replication/slot.c:270 +#, c-format +msgid "all replication slots are in use" +msgstr "alle Replikations-Slots sind in Benutzung" + +#: replication/slot.c:271 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Geben Sie einen frei oder erhöhen Sie max_replication_slots." + +#: replication/slot.c:424 replication/slotfuncs.c:761 +#: utils/adt/pgstatfuncs.c:2227 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "Replikations-Slot »%s« existiert nicht" + +#: replication/slot.c:462 replication/slot.c:1043 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "Replikations-Slot »%s« ist aktiv für PID %d" + +#: replication/slot.c:701 replication/slot.c:1350 replication/slot.c:1733 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "konnte Verzeichnis »%s« nicht löschen" + +#: replication/slot.c:1078 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "Replikations-Slots können nur verwendet werden, wenn max_replication_slots > 0" + +#: replication/slot.c:1083 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "Replikations-Slots können nur verwendet werden, wenn wal_level >= replica" + +#: replication/slot.c:1239 +#, c-format +msgid "terminating process %d because replication slot \"%s\" is too far behind" +msgstr "Prozess %d wird beendet, weil Replikations-Slot »%s« zu weit zurück liegt" + +#: replication/slot.c:1258 +#, c-format +msgid "invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size" +msgstr "Slot »%s« wird ungültig gemacht, weil seine restart_lsn %X/%X max_slot_wal_keep_size überschreitet" + +#: replication/slot.c:1671 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "Replikations-Slot-Datei »%s« hat falsche magische Zahl: %u statt %u" + +#: replication/slot.c:1678 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "Replikations-Slot-Datei »%s« hat nicht unterstützte Version %u" + +#: replication/slot.c:1685 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "Replikations-Slot-Datei »%s« hat falsche Länge %u" + +#: replication/slot.c:1721 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "Prüfsummenfehler bei Replikations-Slot-Datei »%s«: ist %u, sollte %u sein" + +#: replication/slot.c:1755 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "logischer Replikations-Slot »%s« existiert, aber wal_level < logical" + +#: replication/slot.c:1757 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Ändern Sie wal_level in logical oder höher." + +#: replication/slot.c:1761 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "physischer Replikations-Slot »%s« existiert, aber wal_level < replica" + +#: replication/slot.c:1763 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Ändern Sie wal_level in replica oder höher." + +#: replication/slot.c:1797 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "zu viele aktive Replikations-Slots vor dem Herunterfahren" + +#: replication/slotfuncs.c:626 +#, c-format +msgid "invalid target WAL LSN" +msgstr "ungültige Ziel-WAL-LSN" + +#: replication/slotfuncs.c:648 +#, c-format +msgid "replication slot \"%s\" cannot be advanced" +msgstr "Replikations-Slot »%s« kann nicht vorwärtsgesetzt werden" + +#: replication/slotfuncs.c:666 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "Replikations-Slot kann nicht auf %X/%X vorwärtsgesetzt werden, Minimum ist %X/%X" + +#: replication/slotfuncs.c:773 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "physischer Replikations-Slot »%s« kann nicht als logischer Replikations-Slot kopiert werden" + +#: replication/slotfuncs.c:775 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "logischer Replikations-Slot »%s« kann nicht als physischer Replikations-Slot kopiert werden" + +#: replication/slotfuncs.c:782 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "ein Replikations-Slot, der kein WAL reserviert, kann nicht kopiert werden" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "konnte Replikations-Slot »%s« nicht kopieren" + +#: replication/slotfuncs.c:861 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "Der Quell-Replikations-Slot wurde während der Kopieroperation inkompatibel geändert." + +#: replication/slotfuncs.c:867 +#, c-format +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "kann unfertigen Replikations-Slot »%s« nicht kopieren" + +#: replication/slotfuncs.c:869 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "Versuchen Sie es erneut, wenn confirmed_flush_lsn des Quell-Replikations-Slots gültig ist." + +#: replication/syncrep.c:268 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "Warten auf synchrone Replikation wird storniert and Verbindung wird abgebrochen, aufgrund von Anweisung des Administrators" + +#: replication/syncrep.c:269 replication/syncrep.c:286 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert." + +#: replication/syncrep.c:285 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "storniere Warten auf synchrone Replikation wegen Benutzeraufforderung" + +#: replication/syncrep.c:494 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "Standby »%s« ist jetzt ein synchroner Standby mit Priorität %u" + +#: replication/syncrep.c:498 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "Standby »%s« ist jetzt ein Kandidat für synchroner Standby mit Quorum" + +#: replication/syncrep.c:1045 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "Parser für synchronous_standby_names fehlgeschlagen" + +#: replication/syncrep.c:1051 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "Anzahl synchroner Standbys (%d) muss größer als null sein" + +#: replication/walreceiver.c:160 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "WAL-Receiver-Prozess wird abgebrochen aufgrund von Anweisung des Administrators" + +#: replication/walreceiver.c:285 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "konnte nicht mit dem Primärserver verbinden: %s" + +#: replication/walreceiver.c:331 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "Datenbanksystemidentifikator unterscheidet sich zwischen Primär- und Standby-Server" + +#: replication/walreceiver.c:332 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "Identifikator des Primärservers ist %s, Identifikator des Standby ist %s." + +#: replication/walreceiver.c:342 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "höchste Zeitleiste %u des primären Servers liegt hinter Wiederherstellungszeitleiste %u zurück" + +#: replication/walreceiver.c:396 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "WAL-Streaming vom Primärserver gestartet bei %X/%X auf Zeitleiste %u" + +#: replication/walreceiver.c:400 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "WAL-Streaming neu gestartet bei %X/%X auf Zeitleiste %u" + +#: replication/walreceiver.c:428 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "kann WAL-Streaming nicht fortsetzen, Wiederherstellung ist bereits beendet" + +#: replication/walreceiver.c:465 +#, c-format +msgid "replication terminated by primary server" +msgstr "Replikation wurde durch Primärserver beendet" + +#: replication/walreceiver.c:466 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "WAL-Ende erreicht auf Zeitleiste %u bei %X/%X." + +#: replication/walreceiver.c:554 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "WAL-Receiver-Prozess wird abgebrochen wegen Zeitüberschreitung" + +#: replication/walreceiver.c:592 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "Primärserver enthält kein WAL mehr auf angeforderter Zeitleiste %u" + +#: replication/walreceiver.c:608 replication/walreceiver.c:903 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "konnte Logsegment %s nicht schließen: %m" + +#: replication/walreceiver.c:727 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "hole Zeitleisten-History-Datei für Zeitleiste %u vom Primärserver" + +#: replication/walreceiver.c:950 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "konnte nicht in Logsegment %s bei Position %u, Länge %lu schreiben: %m" + +#: replication/walsender.c:524 storage/smgr/md.c:1320 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "konnte Positionszeiger nicht ans Ende der Datei »%s« setzen: %m" + +#: replication/walsender.c:528 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "konnte Positionszeiger nicht den Anfang der Datei »%s« setzen: %m" + +#: replication/walsender.c:579 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM wurde nicht vor START_REPLICATION ausgeführt" + +#: replication/walsender.c:608 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "logischer Replikations-Slot kann nicht für physische Replikation verwendet werden" + +#: replication/walsender.c:677 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "angeforderter Startpunkt %X/%X auf Zeitleiste %u ist nicht in der History dieses Servers" + +#: replication/walsender.c:680 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "Die History dieses Servers zweigte von Zeitleiste %u bei %X/%X ab." + +#: replication/walsender.c:724 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "angeforderter Startpunkt %X/%X ist vor der WAL-Flush-Position dieses Servers %X/%X" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:974 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s darf nicht in einer Transaktion aufgerufen werden" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:984 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s muss in einer Transaktion aufgerufen werden" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:990 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s muss in einer Transaktion im Isolationsmodus REPEATABLE READ aufgerufen werden" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:996 +#, c-format +msgid "%s must be called before any query" +msgstr "%s muss vor allen Anfragen aufgerufen werden" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1002 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s darf nicht in einer Subtransaktion aufgerufen werden" + +#: replication/walsender.c:1145 +#, c-format +msgid "cannot read from logical replication slot \"%s\"" +msgstr "kann nicht aus logischem Replikations-Slot »%s« lesen" + +#: replication/walsender.c:1147 +#, c-format +msgid "This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "Dieser Slot wurde ungültig gemacht, weil er die maximale reservierte Größe überschritten hat." + +#: replication/walsender.c:1157 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "WAL-Sender-Prozess wird nach Beförderung abgebrochen" + +#: replication/walsender.c:1523 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "während der WAL-Sender im Stoppmodus ist können keine neuen Befehle ausgeführt werden" + +#: replication/walsender.c:1560 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "im WAL-Sender für physische Replikation können keine SQL-Befehle ausgeführt werden" + +#: replication/walsender.c:1583 +#, c-format +msgid "received replication command: %s" +msgstr "Replikationsbefehl empfangen: %s" + +#: replication/walsender.c:1591 tcop/fastpath.c:208 tcop/postgres.c:1078 +#: tcop/postgres.c:1430 tcop/postgres.c:1691 tcop/postgres.c:2176 +#: tcop/postgres.c:2586 tcop/postgres.c:2665 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "aktuelle Transaktion wurde abgebrochen, Befehle werden bis zum Ende der Transaktion ignoriert" + +#: replication/walsender.c:1726 replication/walsender.c:1761 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "unerwartetes EOF auf Standby-Verbindung" + +#: replication/walsender.c:1749 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "ungültiger Standby-Message-Typ »%c«" + +#: replication/walsender.c:1838 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "unerwarteter Message-Typ »%c«" + +#: replication/walsender.c:2251 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "WAL-Sender-Prozess wird abgebrochen wegen Zeitüberschreitung bei der Replikation" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:999 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "Regel »%s« für Relation »%s« existiert bereits" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "Regelaktionen für OLD sind nicht implementiert" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "Verwenden Sie stattdessen Sichten oder Trigger." + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "Regelaktionen für NEW sind nicht implementiert" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "Verwenden Sie stattdessen Trigger." + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "INSTEAD-NOTHING-Regeln für SELECT sind nicht implementiert" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "Verwenden Sie stattdessen Sichten." + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "mehrere Regelaktionen für SELECT-Regeln sind nicht implementiert" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "Regeln für SELECT müssen als Aktion INSTEAD SELECT haben" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "Regeln für SELECT dürfen keine datenmodifizierenden Anweisungen in WITH enthalten" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "Ereignisqualifikationen sind nicht implementiert für SELECT-Regeln" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "»%s« ist bereits eine Sicht" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "Sicht-Regel für »%s« muss »%s« heißen" + +#: rewrite/rewriteDefine.c:435 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "kann partitionierte Tabelle »%s« nicht in eine Sicht umwandeln" + +#: rewrite/rewriteDefine.c:444 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "kann Partition »%s« nicht in eine Sicht umwandeln" + +#: rewrite/rewriteDefine.c:453 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie nicht leer ist" + +#: rewrite/rewriteDefine.c:462 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Trigger hat" + +#: rewrite/rewriteDefine.c:464 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "Insbesondere darf die Tabelle nicht in Fremschlüsselverhältnisse eingebunden sein." + +#: rewrite/rewriteDefine.c:469 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Indexe hat" + +#: rewrite/rewriteDefine.c:475 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie abgeleitete Tabellen hat" + +#: rewrite/rewriteDefine.c:481 +#, c-format +msgid "could not convert table \"%s\" to a view because it has parent tables" +msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Elterntabellen hat" + +#: rewrite/rewriteDefine.c:487 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Sicherheit auf Zeilenebene eingeschaltet hat" + +#: rewrite/rewriteDefine.c:493 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Policys für Sicherheit auf Zeilenebene hat" + +#: rewrite/rewriteDefine.c:520 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "Regel kann nicht mehrere RETURNING-Listen enthalten" + +#: rewrite/rewriteDefine.c:525 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "RETURNING-Listen werden in Regeln mit Bedingung nicht unterstützt" + +#: rewrite/rewriteDefine.c:529 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "RETURNING-Listen werden nur in INSTEAD-Regeln unterstützt" + +#: rewrite/rewriteDefine.c:693 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "Targetliste von SELECT-Regel hat zu viele Einträge" + +#: rewrite/rewriteDefine.c:694 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "RETURNING-Liste hat zu viele Einträge" + +#: rewrite/rewriteDefine.c:721 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "kann Relation mit gelöschten Spalten nicht in Sicht umwandeln" + +#: rewrite/rewriteDefine.c:722 +#, c-format +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "für eine Relation mit gelöschten Spalten kann keine RETURNING-Liste erzeugt werden" + +#: rewrite/rewriteDefine.c:728 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "Spaltenname in Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" + +#: rewrite/rewriteDefine.c:730 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECT-Targeteintrag heißt »%s«." + +#: rewrite/rewriteDefine.c:739 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "Typ von Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" + +#: rewrite/rewriteDefine.c:741 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "Eintrag %d in RETURNING-Liste hat anderen Typ als Spalte »%s«" + +#: rewrite/rewriteDefine.c:744 rewrite/rewriteDefine.c:768 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECT-Targeteintrag hat Typ %s, aber Spalte hat Typ %s." + +#: rewrite/rewriteDefine.c:747 rewrite/rewriteDefine.c:772 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "Eintrag in RETURNING-Liste hat Typ %s, aber Spalte hat Typ %s." + +#: rewrite/rewriteDefine.c:763 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "Größe von Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" + +#: rewrite/rewriteDefine.c:765 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "Eintrag %d in RETURNING-Liste hat andere Größe als Spalte »%s«" + +#: rewrite/rewriteDefine.c:782 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "Targetliste von SELECT-Regeln hat zu wenige Einträge" + +#: rewrite/rewriteDefine.c:783 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "RETURNING-Liste hat zu wenige Einträge" + +#: rewrite/rewriteDefine.c:876 rewrite/rewriteDefine.c:990 +#: rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "Regel »%s« für Relation »%s« existiert nicht" + +#: rewrite/rewriteDefine.c:1009 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "Umbenennen einer ON-SELECT-Regel ist nicht erlaubt" + +#: rewrite/rewriteHandler.c:551 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "WITH-Anfragename »%s« erscheint sowohl in der Regelaktion als auch in der umzuschreibenden Anfrage" + +#: rewrite/rewriteHandler.c:611 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "RETURNING-Listen können nicht in mehreren Regeln auftreten" + +#: rewrite/rewriteHandler.c:843 rewrite/rewriteHandler.c:882 +#, fuzzy, c-format +#| msgid "cannot insert into column \"%s\"" +msgid "cannot insert a non-DEFAULT value into column \"%s\"" +msgstr "kann nicht in Spalte »%s« einfügen" + +#: rewrite/rewriteHandler.c:845 rewrite/rewriteHandler.c:911 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "Spalte »%s« ist eine Identitätsspalte, die als GENERATED ALWAYS definiert ist." + +#: rewrite/rewriteHandler.c:847 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Verwenden Sie OVERRIDING SYSTEM VALUE, um diese Einschränkung außer Kraft zu setzen." + +#: rewrite/rewriteHandler.c:909 rewrite/rewriteHandler.c:917 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "Spalte »%s« kann nur auf DEFAULT aktualisiert werden" + +#: rewrite/rewriteHandler.c:1064 rewrite/rewriteHandler.c:1082 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "mehrere Zuweisungen zur selben Spalte »%s«" + +#: rewrite/rewriteHandler.c:2084 rewrite/rewriteHandler.c:3898 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "unendliche Rekursion entdeckt in Regeln für Relation »%s«" + +#: rewrite/rewriteHandler.c:2169 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "unendliche Rekursion entdeckt in Policys für Relation »%s«" + +#: rewrite/rewriteHandler.c:2489 +msgid "Junk view columns are not updatable." +msgstr "Junk-Sichtspalten sind nicht aktualisierbar." + +#: rewrite/rewriteHandler.c:2494 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "Sichtspalten, die nicht Spalten ihrer Basisrelation sind, sind nicht aktualisierbar." + +#: rewrite/rewriteHandler.c:2497 +msgid "View columns that refer to system columns are not updatable." +msgstr "Sichtspalten, die auf Systemspalten verweisen, sind nicht aktualisierbar." + +#: rewrite/rewriteHandler.c:2500 +msgid "View columns that return whole-row references are not updatable." +msgstr "Sichtspalten, die Verweise auf ganze Zeilen zurückgeben, sind nicht aktualisierbar." + +#: rewrite/rewriteHandler.c:2561 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "Sichten, die DISTINCT enthalten, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2564 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "Sichten, die GROUP BY enthalten, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2567 +msgid "Views containing HAVING are not automatically updatable." +msgstr "Sichten, die HAVING enthalten, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2570 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "Sichten, die UNION, INTERSECT oder EXCEPT enthalten, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2573 +msgid "Views containing WITH are not automatically updatable." +msgstr "Sichten, die WITH enthalten, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2576 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "Sichten, die LIMIT oder OFFSET enthalten, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2588 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "Sichten, die Aggregatfunktionen zurückgeben, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2591 +msgid "Views that return window functions are not automatically updatable." +msgstr "Sichten, die Fensterfunktionen zurückgeben, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2594 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "Sichten, die Funktionen mit Ergebnismenge zurückgeben, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2601 rewrite/rewriteHandler.c:2605 +#: rewrite/rewriteHandler.c:2613 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "Sichten, die nicht aus einer einzigen Tabelle oder Sicht lesen, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2616 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "Sichten, die TABLESAMPLE enthalten, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:2640 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "Sichten, die keine aktualisierbaren Spalten haben, sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:3117 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "kann nicht in Spalte »%s« von Sicht »%s« einfügen" + +#: rewrite/rewriteHandler.c:3125 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "kann Spalte »%s« von Sicht »%s« nicht aktualisieren" + +#: rewrite/rewriteHandler.c:3603 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "DO-INSTEAD-NOTHING-Regeln werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" + +#: rewrite/rewriteHandler.c:3617 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "DO-INSTEAD-Regeln mit Bedingung werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" + +#: rewrite/rewriteHandler.c:3621 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "DO-ALSO-Regeln werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" + +#: rewrite/rewriteHandler.c:3626 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "DO-INSTEAD-Regeln mit mehreren Anweisungen werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" + +#: rewrite/rewriteHandler.c:3826 rewrite/rewriteHandler.c:3834 +#: rewrite/rewriteHandler.c:3842 +#, c-format +msgid "Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "Sichten mit DO-INSTEAD-Regeln mit Bedingung sind nicht automatisch aktualisierbar." + +#: rewrite/rewriteHandler.c:3935 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "INSERT RETURNING kann in Relation »%s« nicht ausgeführt werden" + +#: rewrite/rewriteHandler.c:3937 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "Sie benötigen eine ON INSERT DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." + +#: rewrite/rewriteHandler.c:3942 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "UPDATE RETURNING kann in Relation »%s« nicht ausgeführt werden" + +#: rewrite/rewriteHandler.c:3944 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "Sie benötigen eine ON UPDATE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." + +#: rewrite/rewriteHandler.c:3949 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "DELETE RETURNING kann in Relation »%s« nicht ausgeführt werden" + +#: rewrite/rewriteHandler.c:3951 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "Sie benötigen eine ON DELETE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." + +#: rewrite/rewriteHandler.c:3969 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "INSERT mit ON-CONFLICT-Klausel kann nicht mit Tabelle verwendet werden, die INSERT- oder UPDATE-Regeln hat" + +#: rewrite/rewriteHandler.c:4026 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "WITH kann nicht in einer Anfrage verwendet werden, die durch Regeln in mehrere Anfragen umgeschrieben wird" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "Utility-Anweisungen mit Bedingung sind nicht implementiert" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "WHERE CURRENT OF mit einer Sicht ist nicht implementiert" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "NEW-Variablen in ON UPDATE-Regeln können nicht auf Spalten verweisen, die Teil einer Mehrfachzuweisung in dem UPDATE-Befehl sind" + +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "/*-Kommentar nicht abgeschlossen" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "Bitkettenkonstante nicht abgeschlossen" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "hexadezimale Zeichenkette nicht abgeschlossen" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "unsichere Verwendung von Zeichenkette mit Unicode-Escapes" + +#: scan.l:543 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "Zeichenketten mit Unicode-Escapes können nicht verwendet werden, wenn standard_conforming_strings aus ist." + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "unbehandelter vorheriger Zustand in xqs" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Unicode-Escapes müssen \\uXXXX oder \\UXXXXXXXX sein." + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "unsichere Verwendung von \\' in Zeichenkettenkonstante" + +#: scan.l:690 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "Verwenden Sie '', um Quotes in Zeichenketten zu schreiben. \\' ist in bestimmten Client-seitigen Kodierungen unsicher." + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "Dollar-Quotes nicht abgeschlossen" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "Bezeichner in Anführungszeichen hat Länge null" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "Bezeichner in Anführungszeichen nicht abgeschlossen" + +#: scan.l:963 +msgid "operator too long" +msgstr "Operator zu lang" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1171 +#, c-format +msgid "%s at end of input" +msgstr "%s am Ende der Eingabe" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1179 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s bei »%s«" + +#: scan.l:1373 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "nicht standardkonforme Verwendung von \\' in Zeichenkettenkonstante" + +#: scan.l:1374 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "Verwenden Sie '', um Quotes in Zeichenketten zu schreiben, oder verwenden Sie die Syntax für Escape-Zeichenketten (E'...')." + +#: scan.l:1383 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "nicht standardkonforme Verwendung von \\\\ in Zeichenkettenkonstante" + +#: scan.l:1384 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Verwenden Sie die Syntax für Escape-Zeichenketten für Backslashes, z.B. E'\\\\'." + +#: scan.l:1398 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "nicht standardkonforme Verwendung von Escape in Zeichenkettenkonstante" + +#: scan.l:1399 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Verwenden Sie die Syntax für Escape-Zeichenketten, z.B. E'\\r\\n'." + +#: snowball/dict_snowball.c:215 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "kein Snowball-Stemmer für Sprache »%s« und Kodierung »%s« verfügbar" + +#: snowball/dict_snowball.c:238 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "mehrere »StopWords«-Parameter" + +#: snowball/dict_snowball.c:247 +#, c-format +msgid "multiple Language parameters" +msgstr "mehrere »Language«-Parameter" + +#: snowball/dict_snowball.c:254 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "unbekannter Snowball-Parameter: »%s«" + +#: snowball/dict_snowball.c:262 +#, c-format +msgid "missing Language parameter" +msgstr "Parameter »Language« fehlt" + +#: statistics/extended_stats.c:175 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "Statistikobjekt »%s.%s« konnte für Relation »%s.%s« nicht berechnet werden" + +#: statistics/extended_stats.c:2277 +#, fuzzy, c-format +#| msgid "relation \"%s\" does not have a composite type" +msgid "relation \"pg_statistic\" does not have a composite type" +msgstr "Relation »%s« hat keinen zusammengesetzten Typ" + +#: statistics/mcv.c:1368 utils/adt/jsonfuncs.c:1941 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "Funktion, die einen Record zurückgibt, in einem Zusammenhang aufgerufen, der Typ record nicht verarbeiten kann" + +#: storage/buffer/bufmgr.c:601 storage/buffer/bufmgr.c:761 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "auf temporäre Tabellen anderer Sitzungen kann nicht zugegriffen werden" + +#: storage/buffer/bufmgr.c:917 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "unerwartete Daten hinter Dateiende in Block %u von Relation %s" + +#: storage/buffer/bufmgr.c:919 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "Das scheint mit fehlerhaften Kernels vorzukommen; Sie sollten eine Systemaktualisierung in Betracht ziehen." + +#: storage/buffer/bufmgr.c:1018 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "ungültige Seite in Block %u von Relation %s; fülle Seite mit Nullen" + +#: storage/buffer/bufmgr.c:4524 +#, c-format +msgid "could not write block %u of %s" +msgstr "konnte Block %u von %s nicht schreiben" + +#: storage/buffer/bufmgr.c:4526 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Mehrere Fehlschläge --- Schreibfehler ist möglicherweise dauerhaft." + +#: storage/buffer/bufmgr.c:4547 storage/buffer/bufmgr.c:4566 +#, c-format +msgid "writing block %u of relation %s" +msgstr "schreibe Block %u von Relation %s" + +#: storage/buffer/bufmgr.c:4870 +#, c-format +msgid "snapshot too old" +msgstr "Snapshot zu alt" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "kein leerer lokaler Puffer verfügbar" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "während einer parallelen Operation kann nicht auf temporäre Tabellen zugegriffen werden" + +#: storage/file/buffile.c:323 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "konnte temporäre Datei »%s« von BufFile »%s« nicht öffnen: %m" + +#: storage/file/buffile.c:684 storage/file/buffile.c:805 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "konnte Größe von temporärer Datei »%s« von BufFile »%s« nicht bestimmen: %m" + +#: storage/file/buffile.c:884 +#, fuzzy, c-format +#| msgid "could not delete file \"%s\": %m" +msgid "could not delete shared fileset \"%s\": %m" +msgstr "konnte Datei »%s« nicht löschen: %m" + +#: storage/file/buffile.c:902 storage/smgr/md.c:306 storage/smgr/md.c:865 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "kann Datei »%s« nicht kürzen: %m" + +#: storage/file/fd.c:515 storage/file/fd.c:587 storage/file/fd.c:623 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "konnte schmutzige Daten nicht flushen: %m" + +#: storage/file/fd.c:545 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "konnte Größe der schmutzigen Daten nicht bestimmen: %m" + +#: storage/file/fd.c:597 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "munmap() fehlgeschlagen beim Flushen von Daten: %m" + +#: storage/file/fd.c:836 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "konnte Datei »%s« nicht nach »%s« linken: %m" + +#: storage/file/fd.c:929 +#, c-format +msgid "getrlimit failed: %m" +msgstr "getrlimit fehlgeschlagen: %m" + +#: storage/file/fd.c:1019 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "nicht genug Dateideskriptoren verfügbar, um Serverprozess zu starten" + +#: storage/file/fd.c:1020 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "System erlaubt %d, wir benötigen mindestens %d." + +#: storage/file/fd.c:1071 storage/file/fd.c:2408 storage/file/fd.c:2518 +#: storage/file/fd.c:2669 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "keine Dateideskriptoren mehr: %m; freigeben und nochmal versuchen" + +#: storage/file/fd.c:1445 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "temporäre Datei: Pfad »%s«, Größe %lu" + +#: storage/file/fd.c:1576 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "konnte temporäres Verzeichnis »%s« nicht erzeugen: %m" + +#: storage/file/fd.c:1583 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "konnte temporäres Unterverzeichnis »%s« nicht erzeugen: %m" + +#: storage/file/fd.c:1776 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht erzeugen: %m" + +#: storage/file/fd.c:1810 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht öffnen: %m" + +#: storage/file/fd.c:1851 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht löschen: %m" + +#: storage/file/fd.c:1939 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "konnte Datei »%s« nicht löschen: %m" + +#: storage/file/fd.c:2119 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "Größe der temporären Datei überschreitet temp_file_limit (%dkB)" + +#: storage/file/fd.c:2384 storage/file/fd.c:2443 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "maxAllocatedDescs (%d) überschritten beim Versuch, die Datei »%s« zu öffnen" + +#: storage/file/fd.c:2488 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "maxAllocatedDescs (%d) überschritten beim Versuch, den Befehl »%s« auszuführen" + +#: storage/file/fd.c:2645 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "maxAllocatedDescs (%d) überschritten beim Versuch, das Verzeichnis »%s« zu öffnen" + +#: storage/file/fd.c:3175 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "unerwartete Datei im Verzeichnis für temporäre Dateien gefunden: »%s«" + +#: storage/file/fd.c:3298 +#, fuzzy, c-format +#| msgid "could not open file \"%s\": %m" +msgid "could not open %s: %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: storage/file/fd.c:3304 +#, fuzzy, c-format +#| msgid "could not fsync file \"%s\": %m" +msgid "could not sync filesystem for \"%s\": %m" +msgstr "konnte Datei »%s« nicht fsyncen: %m" + +#: storage/file/sharedfileset.c:144 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "konnte nicht an ein SharedFileSet anbinden, das schon zerstört ist" + +#: storage/ipc/dsm.c:351 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "Kontrollsegment von dynamischem Shared Memory ist verfälscht" + +#: storage/ipc/dsm.c:415 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "Kontrollsegment von dynamischem Shared Memory ist ungültig" + +#: storage/ipc/dsm.c:592 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "zu viele dynamische Shared-Memory-Segmente" + +#: storage/ipc/dsm_impl.c:233 storage/ipc/dsm_impl.c:529 +#: storage/ipc/dsm_impl.c:633 storage/ipc/dsm_impl.c:804 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "konnte Shared-Memory-Segment »%s« nicht unmappen: %m" + +#: storage/ipc/dsm_impl.c:243 storage/ipc/dsm_impl.c:539 +#: storage/ipc/dsm_impl.c:643 storage/ipc/dsm_impl.c:814 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "konnte Shared-Memory-Segment »%s« nicht entfernen: %m" + +#: storage/ipc/dsm_impl.c:267 storage/ipc/dsm_impl.c:714 +#: storage/ipc/dsm_impl.c:828 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "konnte Shared-Memory-Segment »%s« nicht öffnen: %m" + +#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:555 +#: storage/ipc/dsm_impl.c:759 storage/ipc/dsm_impl.c:852 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "konnte »stat« für Shared-Memory-Segment »%s« nicht ausführen: %m" + +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:903 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "konnte Größe des Shared-Memory-Segments »%s« nicht auf %zu Bytes ändern: %m" + +#: storage/ipc/dsm_impl.c:341 storage/ipc/dsm_impl.c:576 +#: storage/ipc/dsm_impl.c:735 storage/ipc/dsm_impl.c:925 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "konnte Shared-Memory-Segment »%s« nicht mappen: %m" + +#: storage/ipc/dsm_impl.c:511 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "konnte Shared-Memory-Segment nicht finden: %m" + +#: storage/ipc/dsm_impl.c:699 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "konnte Shared-Memory-Segment »%s« nicht erzeugen: %m" + +#: storage/ipc/dsm_impl.c:936 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "konnte Shared-Memory-Segment »%s« nicht schließen: %m" + +#: storage/ipc/dsm_impl.c:975 storage/ipc/dsm_impl.c:1023 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "konnte Handle für »%s« nicht duplizieren: %m" + +#: storage/ipc/procarray.c:3724 +#, c-format +msgid "database \"%s\" is being used by prepared transactions" +msgstr "Datenbank »%s« wird von vorbereiteten Transaktionen verwendet" + +#: storage/ipc/procarray.c:3756 storage/ipc/signalfuncs.c:219 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "nur Superuser können Prozesse eines Superusers beenden" + +#: storage/ipc/procarray.c:3763 storage/ipc/signalfuncs.c:224 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "muss Mitglied der Rolle sein, deren Prozess beendet wird, oder Mitglied von pg_signal_backend" + +#: storage/ipc/shm_mq.c:368 +#, c-format +msgid "cannot send a message of size %zu via shared memory queue" +msgstr "kann Nachricht mit Größe %zu nicht über Shared-Memory-Queue senden" + +#: storage/ipc/shm_mq.c:694 +#, c-format +msgid "invalid message size %zu in shared memory queue" +msgstr "ungültige Nachrichtengröße %zu in Shared-Memory-Queue" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:981 +#: storage/lmgr/lock.c:1019 storage/lmgr/lock.c:2844 storage/lmgr/lock.c:4173 +#: storage/lmgr/lock.c:4238 storage/lmgr/lock.c:4545 +#: storage/lmgr/predicate.c:2470 storage/lmgr/predicate.c:2485 +#: storage/lmgr/predicate.c:3967 storage/lmgr/predicate.c:5078 +#: utils/hash/dynahash.c:1112 +#, c-format +msgid "out of shared memory" +msgstr "Shared Memory aufgebraucht" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "Shared Memory aufgebraucht (%zu Bytes angefordert)" + +#: storage/ipc/shmem.c:445 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "konnte ShmemIndex-Eintrag für Datenstruktur »%s« nicht erzeugen" + +#: storage/ipc/shmem.c:460 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "ShmemIndex-Eintraggröße ist falsch für Datenstruktur »%s«: erwartet %zu, tatsächlich %zu" + +#: storage/ipc/shmem.c:479 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "nicht genug Shared-Memory für Datenstruktur »%s« (%zu Bytes angefordert)" + +#: storage/ipc/shmem.c:511 storage/ipc/shmem.c:530 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "angeforderte Shared-Memory-Größe übersteigt Kapazität von size_t" + +#: storage/ipc/signalfuncs.c:68 storage/ipc/signalfuncs.c:261 +#: utils/adt/mcxtfuncs.c:196 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d ist kein PostgreSQL-Serverprozess" + +#: storage/ipc/signalfuncs.c:99 storage/lmgr/proc.c:1454 +#: utils/adt/mcxtfuncs.c:210 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "konnte Signal nicht an Prozess %d senden: %m" + +#: storage/ipc/signalfuncs.c:119 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "nur Superuser können Anfragen eines Superusers stornieren" + +#: storage/ipc/signalfuncs.c:124 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "muss Mitglied der Rolle sein, deren Anfrage storniert wird, oder Mitglied von pg_signal_backend" + +#: storage/ipc/signalfuncs.c:165 +#, c-format +msgid "could not check the existence of the backend with PID %d: %m" +msgstr "konnte die Existenz des Backend mit PID %d nicht prüfen: %m" + +#: storage/ipc/signalfuncs.c:183 +#, fuzzy, c-format +#| msgid "server did not promote within %d seconds" +msgid "backend with PID %d did not terminate within %lld milliseconds" +msgstr "Befördern des Servers wurde nicht innerhalb von %d Sekunden abgeschlossen" + +#: storage/ipc/signalfuncs.c:212 +#, c-format +msgid "\"timeout\" must not be negative" +msgstr "»timeout« darf nicht negativ sein" + +#: storage/ipc/signalfuncs.c:254 +#, c-format +msgid "\"timeout\" must not be negative or zero" +msgstr "»timeout« darf nicht negativ oder null sein" + +#: storage/ipc/signalfuncs.c:300 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "nur Superuser können mit adminpack 1.0 Logdateien rotieren" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:302 utils/adt/genfile.c:255 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Verwenden Sie stattdessen %s, was im Kernsystem enthalten ist." + +#: storage/ipc/signalfuncs.c:308 storage/ipc/signalfuncs.c:328 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "Rotierung nicht möglich, weil Logsammlung nicht aktiv ist" + +#: storage/ipc/standby.c:305 +#, fuzzy, c-format +#| msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgid "recovery still waiting after %ld.%03d ms: %s" +msgstr "Prozess %d wartet immer noch auf %s-Sperre auf %s nach %ld,%03d ms" + +#: storage/ipc/standby.c:314 +#, fuzzy, c-format +#| msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgid "recovery finished waiting after %ld.%03d ms: %s" +msgstr "Prozess %d wartet immer noch auf %s-Sperre auf %s nach %ld,%03d ms" + +#: storage/ipc/standby.c:878 tcop/postgres.c:3317 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "storniere Anfrage wegen Konflikt mit der Wiederherstellung" + +#: storage/ipc/standby.c:879 tcop/postgres.c:2471 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "Benutzertransaktion hat Verklemmung (Deadlock) mit Wiederherstellung verursacht." + +#: storage/ipc/standby.c:1421 +msgid "unknown reason" +msgstr "unbekannter Grund" + +#: storage/ipc/standby.c:1426 +msgid "recovery conflict on buffer pin" +msgstr "" + +#: storage/ipc/standby.c:1429 +#, fuzzy +#| msgid "abort reason: recovery conflict" +msgid "recovery conflict on lock" +msgstr "Abbruchgrund: Konflikt bei Wiederherstellung" + +#: storage/ipc/standby.c:1432 +#, fuzzy +#| msgid "remove a tablespace" +msgid "recovery conflict on tablespace" +msgstr "entfernt einen Tablespace" + +#: storage/ipc/standby.c:1435 +msgid "recovery conflict on snapshot" +msgstr "" + +#: storage/ipc/standby.c:1438 +msgid "recovery conflict on buffer deadlock" +msgstr "" + +#: storage/ipc/standby.c:1441 +#, fuzzy +#| msgid "already connected to a database" +msgid "recovery conflict on database" +msgstr "bereits mit einer Datenbank verbunden" + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "pg_largeobject-Eintrag für OID %u, Seite %d hat ungültige Datenfeldgröße %d" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "ungültige Flags zum Öffnen eines Large Objects: %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "ungültige »whence«-Angabe: %d" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "ungültige Größe der Large-Object-Schreibaufforderung: %d" + +#: storage/lmgr/deadlock.c:1122 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "Prozess %d wartet auf %s-Sperre auf %s; blockiert von Prozess %d." + +#: storage/lmgr/deadlock.c:1141 +#, c-format +msgid "Process %d: %s" +msgstr "Prozess %d: %s" + +#: storage/lmgr/deadlock.c:1150 +#, c-format +msgid "deadlock detected" +msgstr "Verklemmung (Deadlock) entdeckt" + +#: storage/lmgr/deadlock.c:1153 +#, c-format +msgid "See server log for query details." +msgstr "Einzelheiten zur Anfrage finden Sie im Serverlog." + +#: storage/lmgr/lmgr.c:831 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "beim Aktualisieren von Tupel (%u,%u) in Relation »%s«" + +#: storage/lmgr/lmgr.c:834 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "beim Löschen von Tupel (%u,%u) in Relation »%s«" + +#: storage/lmgr/lmgr.c:837 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "beim Sperren von Tupel (%u,%u) in Relation »%s«" + +#: storage/lmgr/lmgr.c:840 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "beim Sperren von aktualisierter Version (%u,%u) von Tupel in Relation »%s«" + +#: storage/lmgr/lmgr.c:843 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "beim Einfügen von Indextupel (%u,%u) in Relation »%s«" + +#: storage/lmgr/lmgr.c:846 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "beim Prüfen der Eindeutigkeit von Tupel (%u,%u) in Relation »%s«" + +#: storage/lmgr/lmgr.c:849 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "beim erneuten Prüfen des aktualisierten Tupels (%u,%u) in Relation »%s«" + +#: storage/lmgr/lmgr.c:852 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "beim Prüfen eines Exclusion-Constraints für Tupel (%u,%u) in Relation »%s«" + +#: storage/lmgr/lmgr.c:1106 +#, c-format +msgid "relation %u of database %u" +msgstr "Relation %u der Datenbank %u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "Erweiterung von Relation %u in Datenbank %u" + +#: storage/lmgr/lmgr.c:1118 +#, c-format +msgid "pg_database.datfrozenxid of database %u" +msgstr "pg_database.datfrozenxid der Datenbank %u" + +#: storage/lmgr/lmgr.c:1123 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "Seite %u von Relation %u von Datenbank %u" + +#: storage/lmgr/lmgr.c:1130 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "Tupel (%u, %u) von Relation %u von Datenbank %u" + +#: storage/lmgr/lmgr.c:1138 +#, c-format +msgid "transaction %u" +msgstr "Transaktion %u" + +#: storage/lmgr/lmgr.c:1143 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "virtuelle Transaktion %d/%u" + +#: storage/lmgr/lmgr.c:1149 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "spekulatives Token %u von Transaktion %u" + +#: storage/lmgr/lmgr.c:1155 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "Objekt %u von Klasse %u von Datenbank %u" + +#: storage/lmgr/lmgr.c:1163 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "Benutzersperre [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1170 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "Benutzersperre [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1178 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "unbekannter Locktag-Typ %d" + +#: storage/lmgr/lock.c:802 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "Sperrmodus %s kann während der Wiederherstellung nicht auf Datenbankobjekte gesetzt werden" + +#: storage/lmgr/lock.c:804 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "Nur Sperren gleich oder unter RowExclusiveLock können während der Wiederherstellung auf Datenbankobjekte gesetzt werden." + +#: storage/lmgr/lock.c:982 storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 +#: storage/lmgr/lock.c:4174 storage/lmgr/lock.c:4239 storage/lmgr/lock.c:4546 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "Sie müssen möglicherweise max_locks_per_transaction erhöhen." + +#: storage/lmgr/lock.c:3283 storage/lmgr/lock.c:3399 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "PREPARE kann nicht ausgeführt werden, wenn für das selbe Objekt Sperren auf Sitzungsebene und auf Transaktionsebene gehalten werden" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "nicht genügend Elemente in RWConflictPool, um einen Lese-/Schreibkonflikt aufzuzeichnen" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "Sie müssten entweder weniger Transaktionen auf einmal ausführen oder max_connections erhöhen." + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "nicht genügend Elemente in RWConflictPool, um einen möglichen Lese-/Schreibkonflikt aufzuzeichnen" + +#: storage/lmgr/predicate.c:1694 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "»default_transaction_isolation« ist auf »serializable« gesetzt." + +#: storage/lmgr/predicate.c:1695 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "Mit »SET default_transaction_isolation = 'repeatable read'« können Sie die Voreinstellung ändern." + +#: storage/lmgr/predicate.c:1746 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "eine Transaktion, die einen Snapshot importiert, must READ ONLY DEFERRABLE sein" + +#: storage/lmgr/predicate.c:1825 utils/time/snapmgr.c:567 +#: utils/time/snapmgr.c:573 +#, c-format +msgid "could not import the requested snapshot" +msgstr "konnte den angeforderten Snapshot nicht importieren" + +#: storage/lmgr/predicate.c:1826 utils/time/snapmgr.c:574 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "Der Ausgangsprozess mit PID %d läuft nicht mehr." + +#: storage/lmgr/predicate.c:2471 storage/lmgr/predicate.c:2486 +#: storage/lmgr/predicate.c:3968 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "Sie müssen möglicherweise max_pred_locks_per_transaction erhöhen." + +#: storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4135 +#: storage/lmgr/predicate.c:4168 storage/lmgr/predicate.c:4176 +#: storage/lmgr/predicate.c:4215 storage/lmgr/predicate.c:4457 +#: storage/lmgr/predicate.c:4794 storage/lmgr/predicate.c:4806 +#: storage/lmgr/predicate.c:4849 storage/lmgr/predicate.c:4887 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "konnte Zugriff nicht serialisieren wegen Lese-/Schreib-Abhängigkeiten zwischen Transaktionen" + +#: storage/lmgr/predicate.c:4101 storage/lmgr/predicate.c:4137 +#: storage/lmgr/predicate.c:4170 storage/lmgr/predicate.c:4178 +#: storage/lmgr/predicate.c:4217 storage/lmgr/predicate.c:4459 +#: storage/lmgr/predicate.c:4796 storage/lmgr/predicate.c:4808 +#: storage/lmgr/predicate.c:4851 storage/lmgr/predicate.c:4889 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "Die Transaktion könnte erfolgreich sein, wenn sie erneut versucht würde." + +#: storage/lmgr/proc.c:357 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "Anzahl angeforderter Standby-Verbindungen überschreitet max_wal_senders (aktuell %d)" + +#: storage/lmgr/proc.c:1551 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "Prozess %d vermied Verklemmung wegen %s-Sperre auf %s durch Umordnen der Queue nach %ld,%03d ms" + +#: storage/lmgr/proc.c:1566 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "Prozess %d hat Verklemmung festgestellt beim Warten auf %s-Sperre auf %s nach %ld,%03d ms" + +#: storage/lmgr/proc.c:1575 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "Prozess %d wartet immer noch auf %s-Sperre auf %s nach %ld,%03d ms" + +#: storage/lmgr/proc.c:1582 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "Prozess %d erlangte %s-Sperre auf %s nach %ld,%03d ms" + +#: storage/lmgr/proc.c:1599 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "Prozess %d konnte %s-Sperre auf %s nach %ld,%03d ms nicht erlangen" + +#: storage/page/bufpage.c:152 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "Seitenüberprüfung fehlgeschlagen, berechnete Prüfsumme %u, aber erwartet %u" + +#: storage/page/bufpage.c:217 storage/page/bufpage.c:739 +#: storage/page/bufpage.c:1066 storage/page/bufpage.c:1201 +#: storage/page/bufpage.c:1307 storage/page/bufpage.c:1419 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "verfälschte Seitenzeiger: lower = %u, upper = %u, special = %u" + +#: storage/page/bufpage.c:768 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "verfälschter Line-Pointer: %u" + +#: storage/page/bufpage.c:795 storage/page/bufpage.c:1259 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "verfälschte Item-Längen: gesamt %u, verfügbarer Platz %u" + +#: storage/page/bufpage.c:1085 storage/page/bufpage.c:1226 +#: storage/page/bufpage.c:1323 storage/page/bufpage.c:1435 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "verfälschter Line-Pointer: offset = %u, size = %u" + +#: storage/smgr/md.c:434 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "kann Datei »%s« nicht auf über %u Blöcke erweitern" + +#: storage/smgr/md.c:449 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "konnte Datei »%s« nicht erweitern: %m" + +#: storage/smgr/md.c:451 storage/smgr/md.c:458 storage/smgr/md.c:746 +#, c-format +msgid "Check free disk space." +msgstr "Prüfen Sie den freien Festplattenplatz." + +#: storage/smgr/md.c:455 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "konnte Datei »%s« nicht erweitern: es wurden nur %d von %d Bytes bei Block %u geschrieben" + +#: storage/smgr/md.c:667 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "konnte Block %u in Datei »%s« nicht lesen: %m" + +#: storage/smgr/md.c:683 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "konnte Block %u in Datei »%s« nicht lesen: es wurden nur %d von %d Bytes gelesen" + +#: storage/smgr/md.c:737 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "konnte Block %u in Datei »%s« nicht schreiben: %m" + +#: storage/smgr/md.c:742 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "konnte Block %u in Datei »%s« nicht schreiben: es wurden nur %d von %d Bytes geschrieben" + +#: storage/smgr/md.c:836 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "konnte Datei »%s« nicht auf %u Blöcke kürzen: es sind jetzt nur %u Blöcke" + +#: storage/smgr/md.c:891 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "konnte Datei »%s« nicht auf %u Blöcke kürzen: %m" + +#: storage/smgr/md.c:1285 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "konnte Datei »%s« nicht öffnen (Zielblock %u): vorhergehendes Segment hat nur %u Blöcke" + +#: storage/smgr/md.c:1299 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "konnte Datei »%s« nicht öffnen (Zielblock %u): %m" + +#: tcop/fastpath.c:148 +#, c-format +msgid "cannot call function %s via fastpath interface" +msgstr "Funktion %s kann nicht via Fastpath-Interface aufgerufen werden" + +#: tcop/fastpath.c:233 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "Fastpath-Funktionsaufruf: »%s« (OID %u)" + +#: tcop/fastpath.c:312 tcop/postgres.c:1298 tcop/postgres.c:1556 +#: tcop/postgres.c:2015 tcop/postgres.c:2252 +#, c-format +msgid "duration: %s ms" +msgstr "Dauer: %s ms" + +#: tcop/fastpath.c:316 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "Dauer: %s ms Fastpath-Funktionsaufruf: »%s« (OID %u)" + +#: tcop/fastpath.c:352 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "Funktionsaufruf-Message enthält %d Argumente, aber Funktion benötigt %d" + +#: tcop/fastpath.c:360 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "Funktionsaufruf-Message enthält %d Argumentformate aber %d Argumente" + +#: tcop/fastpath.c:384 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "ungültige Argumentgröße %d in Funktionsaufruf-Message" + +#: tcop/fastpath.c:447 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "falsches Binärdatenformat in Funktionsargument %d" + +#: tcop/postgres.c:446 tcop/postgres.c:4716 +#, c-format +msgid "invalid frontend message type %d" +msgstr "ungültiger Frontend-Message-Typ %d" + +#: tcop/postgres.c:1015 +#, c-format +msgid "statement: %s" +msgstr "Anweisung: %s" + +#: tcop/postgres.c:1303 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "Dauer: %s ms Anweisung: %s" + +#: tcop/postgres.c:1409 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "kann nicht mehrere Befehle in vorbereitete Anweisung einfügen" + +#: tcop/postgres.c:1561 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "Dauer: %s ms Parsen %s: %s" + +#: tcop/postgres.c:1627 tcop/postgres.c:2567 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "unbenannte vorbereitete Anweisung existiert nicht" + +#: tcop/postgres.c:1668 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "Binden-Nachricht hat %d Parameterformate aber %d Parameter" + +#: tcop/postgres.c:1674 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "Binden-Nachricht enthält %d Parameter, aber vorbereitete Anweisung »%s« erfordert %d" + +#: tcop/postgres.c:1893 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "falsches Binärdatenformat in Binden-Parameter %d" + +#: tcop/postgres.c:2020 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "Dauer: %s ms Binden %s%s%s: %s" + +#: tcop/postgres.c:2070 tcop/postgres.c:2651 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "Portal »%s« existiert nicht" + +#: tcop/postgres.c:2155 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2157 tcop/postgres.c:2260 +msgid "execute fetch from" +msgstr "Ausführen Fetch von" + +#: tcop/postgres.c:2158 tcop/postgres.c:2261 +msgid "execute" +msgstr "Ausführen" + +#: tcop/postgres.c:2257 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "Dauer: %s ms %s %s%s%s: %s" + +#: tcop/postgres.c:2403 +#, c-format +msgid "prepare: %s" +msgstr "Vorbereiten: %s" + +#: tcop/postgres.c:2428 +#, c-format +msgid "parameters: %s" +msgstr "Parameter: %s" + +#: tcop/postgres.c:2443 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "Abbruchgrund: Konflikt bei Wiederherstellung" + +#: tcop/postgres.c:2459 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "Benutzer hat Shared-Buffer-Pin zu lange gehalten." + +#: tcop/postgres.c:2462 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "Benutzer hat Relationssperre zu lange gehalten." + +#: tcop/postgres.c:2465 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "Benutzer hat (möglicherweise) einen Tablespace verwendet, der gelöscht werden muss." + +#: tcop/postgres.c:2468 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "Benutzeranfrage hat möglicherweise Zeilenversionen sehen müssen, die entfernt werden müssen." + +#: tcop/postgres.c:2474 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "Benutzer war mit einer Datenbank verbunden, die gelöscht werden muss." + +#: tcop/postgres.c:2513 +#, c-format +msgid "portal \"%s\" parameter $%d = %s" +msgstr "Portal »%s« Parameter $%d = %s" + +#: tcop/postgres.c:2516 +#, c-format +msgid "portal \"%s\" parameter $%d" +msgstr "Portal »%s« Parameter $%d" + +#: tcop/postgres.c:2522 +#, c-format +msgid "unnamed portal parameter $%d = %s" +msgstr "unbenanntes Portal Parameter $%d = %s" + +#: tcop/postgres.c:2525 +#, c-format +msgid "unnamed portal parameter $%d" +msgstr "unbenanntes Portal Parameter $%d" + +#: tcop/postgres.c:2871 +#, c-format +msgid "terminating connection because of unexpected SIGQUIT signal" +msgstr "Verbindung wird abgebrochen wegen unerwartetem SIGQUIT-Signal" + +#: tcop/postgres.c:2877 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "Verbindung wird abgebrochen wegen Absturz eines anderen Serverprozesses" + +#: tcop/postgres.c:2878 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "Der Postmaster hat diesen Serverprozess angewiesen, die aktuelle Transaktion zurückzurollen und die Sitzung zu beenden, weil ein anderer Serverprozess abnormal beendet wurde und möglicherweise das Shared Memory verfälscht hat." + +#: tcop/postgres.c:2882 tcop/postgres.c:3243 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "In einem Moment sollten Sie wieder mit der Datenbank verbinden und Ihren Befehl wiederholen können." + +#: tcop/postgres.c:2889 +#, fuzzy, c-format +#| msgid "terminating connection due to administrator command" +msgid "terminating connection due to immediate shutdown command" +msgstr "Verbindung wird abgebrochen aufgrund von Anweisung des Administrators" + +#: tcop/postgres.c:2975 +#, c-format +msgid "floating-point exception" +msgstr "Fließkommafehler" + +#: tcop/postgres.c:2976 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "Eine ungültige Fließkommaoperation wurde signalisiert. Das bedeutet wahrscheinlich ein Ergebnis außerhalb des gültigen Bereichs oder eine ungültige Operation, zum Beispiel Division durch null." + +#: tcop/postgres.c:3147 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "storniere Authentifizierung wegen Zeitüberschreitung" + +#: tcop/postgres.c:3151 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "Autovacuum-Prozess wird abgebrochen aufgrund von Anweisung des Administrators" + +#: tcop/postgres.c:3155 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "Arbeitsprozess für logische Replikation wird abgebrochen aufgrund von Anweisung des Administrators" + +#: tcop/postgres.c:3172 tcop/postgres.c:3182 tcop/postgres.c:3241 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "Verbindung wird abgebrochen wegen Konflikt mit der Wiederherstellung" + +#: tcop/postgres.c:3193 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "Verbindung wird abgebrochen aufgrund von Anweisung des Administrators" + +#: tcop/postgres.c:3224 +#, c-format +msgid "connection to client lost" +msgstr "Verbindung zum Client wurde verloren" + +#: tcop/postgres.c:3294 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "storniere Anfrage wegen Zeitüberschreitung einer Sperre" + +#: tcop/postgres.c:3301 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "storniere Anfrage wegen Zeitüberschreitung der Anfrage" + +#: tcop/postgres.c:3308 +#, c-format +msgid "canceling autovacuum task" +msgstr "storniere Autovacuum-Aufgabe" + +#: tcop/postgres.c:3331 +#, c-format +msgid "canceling statement due to user request" +msgstr "storniere Anfrage wegen Benutzeraufforderung" + +#: tcop/postgres.c:3345 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "Verbindung wird abgebrochen wegen Zeitüberschreitung in inaktiver Transaktion" + +#: tcop/postgres.c:3356 +#, c-format +msgid "terminating connection due to idle-session timeout" +msgstr "Verbindung wird abgebrochen wegen Zeitüberschreitung in inaktiver Sitzung" + +#: tcop/postgres.c:3475 +#, c-format +msgid "stack depth limit exceeded" +msgstr "Grenze für Stacktiefe überschritten" + +#: tcop/postgres.c:3476 +#, c-format +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "Erhöhen Sie den Konfigurationsparameter »max_stack_depth« (aktuell %dkB), nachdem Sie sichergestellt haben, dass die Stacktiefenbegrenzung Ihrer Plattform ausreichend ist." + +#: tcop/postgres.c:3539 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "»max_stack_depth« darf %ldkB nicht überschreiten." + +#: tcop/postgres.c:3541 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "Erhöhen Sie die Stacktiefenbegrenzung Ihrer Plattform mit »ulimit -s« oder der lokalen Entsprechung." + +#: tcop/postgres.c:3897 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "ungültiges Kommandozeilenargument für Serverprozess: %s" + +#: tcop/postgres.c:3898 tcop/postgres.c:3904 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Versuchen Sie »%s --help« für weitere Informationen." + +#: tcop/postgres.c:3902 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: ungültiges Kommandozeilenargument: %s" + +#: tcop/postgres.c:3965 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: weder Datenbankname noch Benutzername angegeben" + +#: tcop/postgres.c:4618 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "ungültiger Subtyp %d von CLOSE-Message" + +#: tcop/postgres.c:4653 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "ungültiger Subtyp %d von DESCRIBE-Message" + +#: tcop/postgres.c:4737 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "Fastpath-Funktionsaufrufe werden auf einer Replikationsverbindung nicht unterstützt" + +#: tcop/postgres.c:4741 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "erweitertes Anfrageprotokoll wird nicht auf einer Replikationsverbindung unterstützt" + +#: tcop/postgres.c:4918 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "Verbindungsende: Sitzungszeit: %d:%02d:%02d.%03d Benutzer=%s Datenbank=%s Host=%s%s%s" + +#: tcop/pquery.c:636 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "Bind-Message hat %d Ergebnisspalten, aber Anfrage hat %d Spalten" + +#: tcop/pquery.c:939 +#, c-format +msgid "cursor can only scan forward" +msgstr "Cursor kann nur vorwärts scannen" + +#: tcop/pquery.c:940 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Deklarieren Sie ihn mit der Option SCROLL, um rückwarts scannen zu können." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:414 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "%s kann nicht in einer Read-Only-Transaktion ausgeführt werden" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:432 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "%s kann nicht während einer parallelen Operation ausgeführt werden" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:451 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "%s kann nicht während der Wiederherstellung ausgeführt werden" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:469 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "kann %s nicht in einer sicherheitsbeschränkten Operation ausführen" + +#: tcop/utility.c:913 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "nur Superuser können CHECKPOINT ausführen" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:615 +#, c-format +msgid "multiple DictFile parameters" +msgstr "mehrere DictFile-Parameter" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "mehrere AffFile-Parameter" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "unbekannter Ispell-Parameter: »%s«" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "Parameter »AffFile« fehlt" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:639 +#, c-format +msgid "missing DictFile parameter" +msgstr "Parameter »DictFile« fehlt" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "mehrere »Accept«-Parameter" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "unbekannter Parameter für das einfache Wörterbuch: »%s«" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "unbekannter Synonymparameter: »%s«" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "Parameter »Synonyms« fehlt" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "konnte Synonymdatei »%s« nicht öffnen: %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "konnte Thesaurusdatei »%s« nicht öffnen: %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "unerwartetes Trennzeichen" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "unerwartetes Ende der Zeile oder des Lexems" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "unerwartetes Ende der Zeile" + +#: tsearch/dict_thesaurus.c:292 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "zu viele Lexeme in Thesauruseintrag" + +#: tsearch/dict_thesaurus.c:416 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "Thesaurus-Beispielwort »%s« wird nicht vom Unterwörterbuch erkannt (Regel %d)" + +#: tsearch/dict_thesaurus.c:422 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "Thesaurus-Beispielwort »%s« ist ein Stoppwort (Regel %d)" + +#: tsearch/dict_thesaurus.c:425 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Verwenden Sie »?«, um ein Stoppwort in einem Beispielsatz darzustellen." + +#: tsearch/dict_thesaurus.c:567 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "Thesaurus-Ersatzwort »%s« ist ein Stoppwort (Regel %d)" + +#: tsearch/dict_thesaurus.c:574 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "Thesaurus-Ersatzwort »%s« wird nicht vom Unterwörterbuch erkannt (Regel %d)" + +#: tsearch/dict_thesaurus.c:586 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "Thesaurus-Ersatzausdruck ist leer (Regel %d)" + +#: tsearch/dict_thesaurus.c:624 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "mehrere »Dictionary«-Parameter" + +#: tsearch/dict_thesaurus.c:631 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "unbekannter Thesaurus-Parameter: »%s«" + +#: tsearch/dict_thesaurus.c:643 +#, c-format +msgid "missing Dictionary parameter" +msgstr "Parameter »Dictionary« fehlt" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1062 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "ungültiges Affix-Flag »%s«" + +#: tsearch/spell.c:384 tsearch/spell.c:1066 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "Affix-Flag »%s« ist außerhalb des gültigen Bereichs" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "ungültiges Zeichen in Affix-Flag »%s«" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "ungültiges Affix-Flag »%s« mit Flag-Wert »long«" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "konnte Wörterbuchdatei »%s« nicht öffnen: %m" + +#: tsearch/spell.c:763 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "ungültiger regulärer Ausdruck: %s" + +#: tsearch/spell.c:1189 tsearch/spell.c:1201 tsearch/spell.c:1760 +#: tsearch/spell.c:1765 tsearch/spell.c:1770 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "ungültiges Affixalias »%s«" + +#: tsearch/spell.c:1242 tsearch/spell.c:1313 tsearch/spell.c:1462 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "konnte Affixdatei »%s« nicht öffnen: %m" + +#: tsearch/spell.c:1296 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Ispell-Wörterbuch unterstützt nur die Flag-Werte »default«, »long« und »num«" + +#: tsearch/spell.c:1340 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "ungültige Anzahl Flag-Vektor-Aliasse" + +#: tsearch/spell.c:1363 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "Anzahl der Aliasse überschreitet angegebene Zahl %d" + +#: tsearch/spell.c:1578 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "Affixdatei enthält Befehle im alten und im neuen Stil" + +#: tsearch/to_tsany.c:195 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "Zeichenkette ist zu lang für tsvector (%d Bytes, maximal %d Bytes)" + +#: tsearch/ts_locale.c:227 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "Zeile %d in Konfigurationsdatei »%s«: »%s«" + +#: tsearch/ts_locale.c:307 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "Umwandlung von wchar_t in Serverkodierung fehlgeschlagen: %m" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 +#: tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "Wort ist zu lang, um indiziert zu werden" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 +#: tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "Wörter, die länger als %d Zeichen sind, werden ignoriert." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "ungültiger Textsuchekonfigurationsdateiname »%s«" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "konnte Stoppwortdatei »%s« nicht öffnen: %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "Textsucheparser unterstützt das Erzeugen von Headlines nicht" + +#: tsearch/wparser_def.c:2578 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "unbekannter Headline-Parameter: »%s«" + +#: tsearch/wparser_def.c:2597 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "»MinWords« sollte kleiner als »MaxWords« sein" + +#: tsearch/wparser_def.c:2601 +#, c-format +msgid "MinWords should be positive" +msgstr "»MinWords« sollte positiv sein" + +#: tsearch/wparser_def.c:2605 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "»ShortWord« sollte >= 0 sein" + +#: tsearch/wparser_def.c:2609 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "»MaxFragments« sollte >= 0 sein" + +#: utils/adt/acl.c:165 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "Bezeichner zu lang" + +#: utils/adt/acl.c:166 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "Bezeichner muss weniger als %d Zeichen haben." + +#: utils/adt/acl.c:249 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "unbekanntes Schlüsselwort: »%s«" + +#: utils/adt/acl.c:250 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "ACL-Schlüsselwort muss »group« oder »user« sein." + +#: utils/adt/acl.c:255 +#, c-format +msgid "missing name" +msgstr "Name fehlt" + +#: utils/adt/acl.c:256 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "Auf das Schlüsselwort »group« oder »user« muss ein Name folgen." + +#: utils/adt/acl.c:262 +#, c-format +msgid "missing \"=\" sign" +msgstr "»=«-Zeichen fehlt" + +#: utils/adt/acl.c:315 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "ungültiges Moduszeichen: muss eines aus »%s« sein" + +#: utils/adt/acl.c:337 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "auf das »/«-Zeichen muss ein Name folgen" + +#: utils/adt/acl.c:345 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "nicht angegebener Grantor wird auf user ID %u gesetzt" + +#: utils/adt/acl.c:531 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "ACL-Array enthält falschen Datentyp" + +#: utils/adt/acl.c:535 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "ACL-Arrays müssen eindimensional sein" + +#: utils/adt/acl.c:539 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "ACL-Array darf keine NULL-Werte enthalten" + +#: utils/adt/acl.c:563 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "überflüssiger Müll am Ende der ACL-Angabe" + +#: utils/adt/acl.c:1198 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "Grant-Optionen können nicht an den eigenen Grantor gegeben werden" + +#: utils/adt/acl.c:1259 +#, c-format +msgid "dependent privileges exist" +msgstr "abhängige Privilegien existieren" + +#: utils/adt/acl.c:1260 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Verwenden Sie CASCADE, um diese auch zu entziehen." + +#: utils/adt/acl.c:1514 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert wird nicht mehr unterstützt" + +#: utils/adt/acl.c:1524 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove wird nicht mehr unterstützt" + +#: utils/adt/acl.c:1610 utils/adt/acl.c:1664 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "unbekannter Privilegtyp: »%s«" + +#: utils/adt/acl.c:3446 utils/adt/regproc.c:101 utils/adt/regproc.c:276 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "Funktion »%s« existiert nicht" + +#: utils/adt/acl.c:4898 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "Berechtigung nur für Mitglied von Rolle »%s«" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:935 +#: utils/adt/arrayfuncs.c:1543 utils/adt/arrayfuncs.c:3262 +#: utils/adt/arrayfuncs.c:3404 utils/adt/arrayfuncs.c:5945 +#: utils/adt/arrayfuncs.c:6286 utils/adt/arrayutils.c:94 +#: utils/adt/arrayutils.c:103 utils/adt/arrayutils.c:110 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "Arraygröße überschreitet erlaubtes Maximum (%d)" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:467 +#: utils/adt/array_userfuncs.c:547 utils/adt/json.c:645 utils/adt/json.c:740 +#: utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 +#: utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "konnte Eingabedatentypen nicht bestimmen" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "Eingabedatentyp ist kein Array" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/float.c:1233 utils/adt/float.c:1307 utils/adt/float.c:4052 +#: utils/adt/float.c:4066 utils/adt/int.c:757 utils/adt/int.c:779 +#: utils/adt/int.c:793 utils/adt/int.c:807 utils/adt/int.c:838 +#: utils/adt/int.c:859 utils/adt/int.c:976 utils/adt/int.c:990 +#: utils/adt/int.c:1004 utils/adt/int.c:1037 utils/adt/int.c:1051 +#: utils/adt/int.c:1065 utils/adt/int.c:1096 utils/adt/int.c:1178 +#: utils/adt/int.c:1242 utils/adt/int.c:1310 utils/adt/int.c:1316 +#: utils/adt/int8.c:1299 utils/adt/numeric.c:1776 utils/adt/numeric.c:4207 +#: utils/adt/varbit.c:1195 utils/adt/varbit.c:1596 utils/adt/varlena.c:1121 +#: utils/adt/varlena.c:3433 +#, c-format +msgid "integer out of range" +msgstr "integer ist außerhalb des gültigen Bereichs" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "Argument muss entweder leer oder ein eindimensionales Array sein" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "inkompatible Arrays können nicht aneinandergehängt werden" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Arrays mit Elementtypen %s und %s sind nicht kompatibel für Aneinanderhängen." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Arrays mit %d und %d Dimensionen sind nicht kompatibel für Aneinanderhängen." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "Arrays mit unterschiedlichen Elementdimensionen sind nicht kompatibel für Aneinanderhängen." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Arrays mit unterschiedlichen Dimensionen sind nicht kompatibel für Aneinanderhängen." + +#: utils/adt/array_userfuncs.c:663 utils/adt/array_userfuncs.c:815 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "Suche nach Elementen in mehrdimensionalen Arrays wird nicht unterstützt" + +#: utils/adt/array_userfuncs.c:687 +#, c-format +msgid "initial position must not be null" +msgstr "Startposition darf nicht NULL sein" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 +#: utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#: utils/adt/arrayfuncs.c:492 utils/adt/arrayfuncs.c:508 +#: utils/adt/arrayfuncs.c:519 utils/adt/arrayfuncs.c:534 +#: utils/adt/arrayfuncs.c:555 utils/adt/arrayfuncs.c:585 +#: utils/adt/arrayfuncs.c:592 utils/adt/arrayfuncs.c:600 +#: utils/adt/arrayfuncs.c:634 utils/adt/arrayfuncs.c:657 +#: utils/adt/arrayfuncs.c:677 utils/adt/arrayfuncs.c:789 +#: utils/adt/arrayfuncs.c:798 utils/adt/arrayfuncs.c:828 +#: utils/adt/arrayfuncs.c:843 utils/adt/arrayfuncs.c:896 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "fehlerhafte Arraykonstante: »%s«" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "Auf »[« müssen explizit angegebene Array-Dimensionen folgen." + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "Dimensionswert fehlt." + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "»%s« fehlt nach Arraydimensionen." + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2909 +#: utils/adt/arrayfuncs.c:2941 utils/adt/arrayfuncs.c:2956 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "Obergrenze kann nicht kleiner als Untergrenze sein" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "Arraywert muss mit »{« oder Dimensionsinformationen anfangen." + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "Array-Inhalt muss mit {« anfangen." + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "Angegebene Array-Dimensionen stimmen nicht mit dem Array-Inhalt überein." + +#: utils/adt/arrayfuncs.c:493 utils/adt/arrayfuncs.c:520 +#: utils/adt/multirangetypes.c:162 utils/adt/rangetypes.c:2310 +#: utils/adt/rangetypes.c:2318 utils/adt/rowtypes.c:211 +#: utils/adt/rowtypes.c:219 +#, c-format +msgid "Unexpected end of input." +msgstr "Unerwartetes Ende der Eingabe." + +#: utils/adt/arrayfuncs.c:509 utils/adt/arrayfuncs.c:556 +#: utils/adt/arrayfuncs.c:586 utils/adt/arrayfuncs.c:635 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "Unerwartetes Zeichen »%c«." + +#: utils/adt/arrayfuncs.c:535 utils/adt/arrayfuncs.c:658 +#, c-format +msgid "Unexpected array element." +msgstr "Unerwartetes Arrayelement." + +#: utils/adt/arrayfuncs.c:593 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "Zeichen »%c« ohne Gegenstück." + +#: utils/adt/arrayfuncs.c:601 utils/adt/jsonfuncs.c:2593 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "Mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben." + +#: utils/adt/arrayfuncs.c:678 +#, c-format +msgid "Junk after closing right brace." +msgstr "Müll nach schließender rechter geschweifter Klammer." + +#: utils/adt/arrayfuncs.c:1300 utils/adt/arrayfuncs.c:3370 +#: utils/adt/arrayfuncs.c:5849 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "ungültige Anzahl Dimensionen: %d" + +#: utils/adt/arrayfuncs.c:1311 +#, c-format +msgid "invalid array flags" +msgstr "ungültige Array-Flags" + +#: utils/adt/arrayfuncs.c:1333 +#, c-format +msgid "binary data has array element type %u (%s) instead of expected %u (%s)" +msgstr "binäre Daten haben Array-Elementtyp %u (%s) statt erwartet %u (%s)" + +#: utils/adt/arrayfuncs.c:1377 utils/adt/multirangetypes.c:443 +#: utils/adt/rangetypes.c:333 utils/cache/lsyscache.c:2905 +#, c-format +msgid "no binary input function available for type %s" +msgstr "keine binäre Eingabefunktion verfügbar für Typ %s" + +#: utils/adt/arrayfuncs.c:1517 +#, c-format +msgid "improper binary format in array element %d" +msgstr "falsches Binärformat in Arrayelement %d" + +#: utils/adt/arrayfuncs.c:1598 utils/adt/multirangetypes.c:448 +#: utils/adt/rangetypes.c:338 utils/cache/lsyscache.c:2938 +#, c-format +msgid "no binary output function available for type %s" +msgstr "keine binäre Ausgabefunktion verfügbar für Typ %s" + +#: utils/adt/arrayfuncs.c:2077 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "Auswählen von Stücken aus Arrays mit fester Länge ist nicht implementiert" + +#: utils/adt/arrayfuncs.c:2255 utils/adt/arrayfuncs.c:2277 +#: utils/adt/arrayfuncs.c:2326 utils/adt/arrayfuncs.c:2565 +#: utils/adt/arrayfuncs.c:2887 utils/adt/arrayfuncs.c:5835 +#: utils/adt/arrayfuncs.c:5861 utils/adt/arrayfuncs.c:5872 +#: utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 +#: utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4427 utils/adt/jsonfuncs.c:4580 +#: utils/adt/jsonfuncs.c:4692 utils/adt/jsonfuncs.c:4741 +#, c-format +msgid "wrong number of array subscripts" +msgstr "falsche Anzahl Arrayindizes" + +#: utils/adt/arrayfuncs.c:2260 utils/adt/arrayfuncs.c:2368 +#: utils/adt/arrayfuncs.c:2632 utils/adt/arrayfuncs.c:2946 +#, c-format +msgid "array subscript out of range" +msgstr "Arrayindex außerhalb des gültigen Bereichs" + +#: utils/adt/arrayfuncs.c:2265 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "Array mit fester Länge kann keinen NULL-Wert enthalten" + +#: utils/adt/arrayfuncs.c:2834 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "Aktualisieren von Stücken aus Arrays mit fester Länge ist nicht implementiert" + +#: utils/adt/arrayfuncs.c:2865 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "Array-Slice-Index muss beide Begrenzungen angeben" + +#: utils/adt/arrayfuncs.c:2866 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "Wenn ein Slice eines leeren Array-Wertes zugewiesen wird, dann müssen die Slice-Begrenzungen vollständig angegeben werden." + +#: utils/adt/arrayfuncs.c:2877 utils/adt/arrayfuncs.c:2973 +#, c-format +msgid "source array too small" +msgstr "Quellarray ist zu klein" + +#: utils/adt/arrayfuncs.c:3528 +#, c-format +msgid "null array element not allowed in this context" +msgstr "NULL-Werte im Array sind in diesem Zusammenhang nicht erlaubt" + +#: utils/adt/arrayfuncs.c:3630 utils/adt/arrayfuncs.c:3801 +#: utils/adt/arrayfuncs.c:4157 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "kann Arrays mit verschiedenen Elementtypen nicht vergleichen" + +#: utils/adt/arrayfuncs.c:3979 utils/adt/multirangetypes.c:2670 +#: utils/adt/multirangetypes.c:2742 utils/adt/rangetypes.c:1343 +#: utils/adt/rangetypes.c:1407 utils/adt/rowtypes.c:1858 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "konnte keine Hash-Funktion für Typ %s ermitteln" + +#: utils/adt/arrayfuncs.c:4072 utils/adt/rowtypes.c:1979 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "konnte keine erweiterte Hash-Funktion für Typ %s ermitteln" + +#: utils/adt/arrayfuncs.c:5249 +#, c-format +msgid "data type %s is not an array type" +msgstr "Datentyp %s ist kein Array-Typ" + +#: utils/adt/arrayfuncs.c:5304 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "Arrays, die NULL sind, können nicht akkumuliert werden" + +#: utils/adt/arrayfuncs.c:5332 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "leere Arrays können nicht akkumuliert werden" + +#: utils/adt/arrayfuncs.c:5359 utils/adt/arrayfuncs.c:5365 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "Arrays unterschiedlicher Dimensionalität können nicht akkumuliert werden" + +#: utils/adt/arrayfuncs.c:5733 utils/adt/arrayfuncs.c:5773 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "Dimensions-Array oder Untergrenzen-Array darf nicht NULL sein" + +#: utils/adt/arrayfuncs.c:5836 utils/adt/arrayfuncs.c:5862 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "Dimensions-Array muss eindimensional sein." + +#: utils/adt/arrayfuncs.c:5841 utils/adt/arrayfuncs.c:5867 +#, c-format +msgid "dimension values cannot be null" +msgstr "Dimensionswerte dürfen nicht NULL sein" + +#: utils/adt/arrayfuncs.c:5873 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "Untergrenzen-Array hat andere Größe als Dimensions-Array." + +#: utils/adt/arrayfuncs.c:6151 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "Entfernen von Elementen aus mehrdimensionalen Arrays wird nicht unterstützt" + +#: utils/adt/arrayfuncs.c:6428 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" + +#: utils/adt/arrayfuncs.c:6433 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "»thresholds«-Array darf keine NULL-Werte enthalten" + +#: utils/adt/arrayfuncs.c:6666 +#, fuzzy, c-format +#| msgid "number of parameters must be between 0 and 65535\n" +msgid "number of elements to trim must be between 0 and %d" +msgstr "Anzahl der Parameter muss zwischen 0 und 65535 sein\n" + +#: utils/adt/arraysubs.c:93 utils/adt/arraysubs.c:130 +#, c-format +msgid "array subscript must have type integer" +msgstr "Arrayindex muss Typ integer haben" + +#: utils/adt/arraysubs.c:198 utils/adt/arraysubs.c:217 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "Arrayindex in Zuweisung darf nicht NULL sein" + +#: utils/adt/arrayutils.c:140 +#, c-format +msgid "array lower bound is too large: %d" +msgstr "Array-Untergrenze ist zu groß: %d" + +#: utils/adt/arrayutils.c:240 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "Typmod-Array muss Typ cstring[] haben" + +#: utils/adt/arrayutils.c:245 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "Typmod-Arrays müssen eindimensional sein" + +#: utils/adt/arrayutils.c:250 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "Typmod-Array darf keine NULL-Werte enthalten" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "Kodierungsumwandlung zwischen %s und ASCII wird nicht unterstützt" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3802 +#: utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:283 +#: utils/adt/float.c:400 utils/adt/float.c:485 utils/adt/float.c:501 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1389 utils/adt/geo_ops.c:1424 +#: utils/adt/geo_ops.c:1432 utils/adt/geo_ops.c:3488 utils/adt/geo_ops.c:4657 +#: utils/adt/geo_ops.c:4672 utils/adt/geo_ops.c:4679 utils/adt/int8.c:126 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:702 +#: utils/adt/numeric.c:721 utils/adt/numeric.c:6861 utils/adt/numeric.c:6885 +#: utils/adt/numeric.c:6909 utils/adt/numeric.c:7878 utils/adt/numutils.c:116 +#: utils/adt/numutils.c:126 utils/adt/numutils.c:170 utils/adt/numutils.c:246 +#: utils/adt/numutils.c:322 utils/adt/oid.c:44 utils/adt/oid.c:58 +#: utils/adt/oid.c:64 utils/adt/oid.c:86 utils/adt/pg_lsn.c:74 +#: utils/adt/tid.c:76 utils/adt/tid.c:84 utils/adt/tid.c:92 +#: utils/adt/timestamp.c:496 utils/adt/uuid.c:136 utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "ungültige Eingabesyntax für Typ %s: »%s«" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 +#: utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "Wert »%s« ist außerhalb des gültigen Bereichs für Typ %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:104 utils/adt/int.c:822 utils/adt/int.c:938 +#: utils/adt/int.c:1018 utils/adt/int.c:1080 utils/adt/int.c:1118 +#: utils/adt/int.c:1146 utils/adt/int8.c:600 utils/adt/int8.c:658 +#: utils/adt/int8.c:985 utils/adt/int8.c:1065 utils/adt/int8.c:1127 +#: utils/adt/int8.c:1207 utils/adt/numeric.c:3032 utils/adt/numeric.c:3055 +#: utils/adt/numeric.c:3140 utils/adt/numeric.c:3158 utils/adt/numeric.c:3254 +#: utils/adt/numeric.c:8427 utils/adt/numeric.c:8717 utils/adt/numeric.c:10299 +#: utils/adt/timestamp.c:3281 +#, c-format +msgid "division by zero" +msgstr "Division durch Null" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "\"char\" ist außerhalb des gültigen Bereichs" + +#: utils/adt/date.c:62 utils/adt/timestamp.c:97 utils/adt/varbit.c:105 +#: utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "ungültige Typmodifikation" + +#: utils/adt/date.c:74 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "Präzision von TIME(%d)%s darf nicht negativ sein" + +#: utils/adt/date.c:80 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "Präzision von TIME(%d)%s auf erlaubten Höchstwert %d reduziert" + +#: utils/adt/date.c:159 utils/adt/date.c:167 utils/adt/formatting.c:4252 +#: utils/adt/formatting.c:4261 utils/adt/formatting.c:4367 +#: utils/adt/formatting.c:4377 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "date ist außerhalb des gültigen Bereichs: »%s«" + +#: utils/adt/date.c:214 utils/adt/date.c:525 utils/adt/date.c:549 +#: utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "date ist außerhalb des gültigen Bereichs" + +#: utils/adt/date.c:260 utils/adt/timestamp.c:580 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "Datum-Feldwert ist außerhalb des gültigen Bereichs: %d-%02d-%02d" + +#: utils/adt/date.c:267 utils/adt/date.c:276 utils/adt/timestamp.c:586 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "date ist außerhalb des gültigen Bereichs: %d-%02d-%02d" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "kann unendliche date-Werte nicht subtrahieren" + +#: utils/adt/date.c:598 utils/adt/date.c:661 utils/adt/date.c:697 +#: utils/adt/date.c:2881 utils/adt/date.c:2891 +#, c-format +msgid "date out of range for timestamp" +msgstr "Datum ist außerhalb des gültigen Bereichs für Typ »timestamp«" + +#: utils/adt/date.c:1127 utils/adt/date.c:1210 utils/adt/date.c:1226 +#, c-format +msgid "date units \"%s\" not supported" +msgstr "»date«-Einheit »%s« nicht unterstützt" + +#: utils/adt/date.c:1235 +#, c-format +msgid "date units \"%s\" not recognized" +msgstr "»date«-Einheit »%s« nicht erkannt" + +#: utils/adt/date.c:1318 utils/adt/date.c:1364 utils/adt/date.c:1920 +#: utils/adt/date.c:1951 utils/adt/date.c:1980 utils/adt/date.c:2844 +#: utils/adt/datetime.c:405 utils/adt/datetime.c:1700 +#: utils/adt/formatting.c:4109 utils/adt/formatting.c:4141 +#: utils/adt/formatting.c:4221 utils/adt/formatting.c:4343 utils/adt/json.c:418 +#: utils/adt/json.c:457 utils/adt/timestamp.c:224 utils/adt/timestamp.c:256 +#: utils/adt/timestamp.c:698 utils/adt/timestamp.c:707 +#: utils/adt/timestamp.c:785 utils/adt/timestamp.c:818 +#: utils/adt/timestamp.c:2860 utils/adt/timestamp.c:2881 +#: utils/adt/timestamp.c:2894 utils/adt/timestamp.c:2903 +#: utils/adt/timestamp.c:2911 utils/adt/timestamp.c:2966 +#: utils/adt/timestamp.c:2989 utils/adt/timestamp.c:3002 +#: utils/adt/timestamp.c:3013 utils/adt/timestamp.c:3021 +#: utils/adt/timestamp.c:3681 utils/adt/timestamp.c:3806 +#: utils/adt/timestamp.c:3891 utils/adt/timestamp.c:3981 +#: utils/adt/timestamp.c:4069 utils/adt/timestamp.c:4172 +#: utils/adt/timestamp.c:4674 utils/adt/timestamp.c:4948 +#: utils/adt/timestamp.c:5401 utils/adt/timestamp.c:5415 +#: utils/adt/timestamp.c:5420 utils/adt/timestamp.c:5434 +#: utils/adt/timestamp.c:5467 utils/adt/timestamp.c:5554 +#: utils/adt/timestamp.c:5595 utils/adt/timestamp.c:5599 +#: utils/adt/timestamp.c:5668 utils/adt/timestamp.c:5672 +#: utils/adt/timestamp.c:5686 utils/adt/timestamp.c:5720 utils/adt/xml.c:2232 +#: utils/adt/xml.c:2239 utils/adt/xml.c:2259 utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "timestamp ist außerhalb des gültigen Bereichs" + +#: utils/adt/date.c:1537 utils/adt/date.c:2339 utils/adt/formatting.c:4429 +#, c-format +msgid "time out of range" +msgstr "time ist außerhalb des gültigen Bereichs" + +#: utils/adt/date.c:1589 utils/adt/timestamp.c:595 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "Zeit-Feldwert ist außerhalb des gültigen Bereichs: %d:%02d:%02g" + +#: utils/adt/date.c:2109 utils/adt/date.c:2643 utils/adt/float.c:1047 +#: utils/adt/float.c:1123 utils/adt/int.c:614 utils/adt/int.c:661 +#: utils/adt/int.c:696 utils/adt/int8.c:499 utils/adt/numeric.c:2443 +#: utils/adt/timestamp.c:3330 utils/adt/timestamp.c:3361 +#: utils/adt/timestamp.c:3392 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "ungültige vorhergehende oder folgende Größe in Fensterfunktion" + +#: utils/adt/date.c:2208 utils/adt/date.c:2224 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "»time«-Einheit »%s« nicht erkannt" + +#: utils/adt/date.c:2347 +#, c-format +msgid "time zone displacement out of range" +msgstr "Zeitzonenunterschied ist außerhalb des gültigen Bereichs" + +#: utils/adt/date.c:2986 utils/adt/date.c:3006 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "»time with time zone«-Einheit »%s« nicht erkannt" + +#: utils/adt/date.c:3095 utils/adt/datetime.c:951 utils/adt/datetime.c:1858 +#: utils/adt/datetime.c:4648 utils/adt/timestamp.c:515 +#: utils/adt/timestamp.c:542 utils/adt/timestamp.c:4255 +#: utils/adt/timestamp.c:5426 utils/adt/timestamp.c:5678 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "Zeitzone »%s« nicht erkannt" + +#: utils/adt/date.c:3127 utils/adt/timestamp.c:5456 utils/adt/timestamp.c:5709 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "Intervall-Zeitzone »%s« darf keine Monate oder Tage enthalten" + +#: utils/adt/datetime.c:3775 utils/adt/datetime.c:3782 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "Datum/Zeit-Feldwert ist außerhalb des gültigen Bereichs: »%s«" + +#: utils/adt/datetime.c:3784 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Möglicherweise benötigen Sie eine andere »datestyle«-Einstellung." + +#: utils/adt/datetime.c:3789 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "»interval«-Feldwert ist außerhalb des gültigen Bereichs: »%s«" + +#: utils/adt/datetime.c:3795 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "Zeitzonenunterschied ist außerhalb des gültigen Bereichs: »%s«" + +#: utils/adt/datetime.c:4650 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "Dieser Zeitzonenname erscheint in der Konfigurationsdatei für Zeitzonenabkürzung »%s«." + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "ungültiger »Datum«-Zeiger" + +#: utils/adt/dbsize.c:749 utils/adt/dbsize.c:817 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "ungültige Größe: »%s«" + +#: utils/adt/dbsize.c:818 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "Ungültige Größeneinheit: »%s«." + +#: utils/adt/dbsize.c:819 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Gültige Einheiten sind »kB«, »MB«, »GB« und »TB«." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "Typ %s ist keine Domäne" + +#: utils/adt/encode.c:68 utils/adt/encode.c:112 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "unbekannte Kodierung: »%s«" + +#: utils/adt/encode.c:82 +#, c-format +msgid "result of encoding conversion is too large" +msgstr "Ergebnis der Kodierungsumwandlung ist zu groß" + +#: utils/adt/encode.c:126 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "Ergebnis der Dekodierungsumwandlung ist zu groß" + +#: utils/adt/encode.c:261 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "unerwartetes »=« beim Dekodieren von Base64-Sequenz" + +#: utils/adt/encode.c:273 +#, c-format +msgid "invalid symbol \"%.*s\" found while decoding base64 sequence" +msgstr "ungültiges Symbol »%.*s« beim Dekodieren von Base64-Sequenz" + +#: utils/adt/encode.c:304 +#, c-format +msgid "invalid base64 end sequence" +msgstr "ungültige Base64-Endsequenz" + +#: utils/adt/encode.c:305 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "Die Eingabedaten haben fehlendes Padding, sind zu kurz oder sind anderweitig verfälscht." + +#: utils/adt/enum.c:99 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "unsichere Verwendung des neuen Werts »%s« des Enum-Typs %s" + +#: utils/adt/enum.c:102 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "Neue Enum-Werte müssen committet werden, bevor sie verwendet werden können." + +#: utils/adt/enum.c:120 utils/adt/enum.c:130 utils/adt/enum.c:188 +#: utils/adt/enum.c:198 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "ungültiger Eingabewert für Enum %s: »%s«" + +#: utils/adt/enum.c:160 utils/adt/enum.c:226 utils/adt/enum.c:285 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "ungültiger interner Wert für Enum: %u" + +#: utils/adt/enum.c:445 utils/adt/enum.c:474 utils/adt/enum.c:514 +#: utils/adt/enum.c:534 +#, c-format +msgid "could not determine actual enum type" +msgstr "konnte tatsächlichen Enum-Typen nicht bestimmen" + +#: utils/adt/enum.c:453 utils/adt/enum.c:482 +#, c-format +msgid "enum %s contains no values" +msgstr "Enum %s enthält keine Werte" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "Wert ist außerhalb des gültigen Bereichs: Überlauf" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "Wert ist außerhalb des gültigen Bereichs: Unterlauf" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ real" + +#: utils/adt/float.c:477 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ double precision" + +#: utils/adt/float.c:1258 utils/adt/float.c:1332 utils/adt/int.c:334 +#: utils/adt/int.c:872 utils/adt/int.c:894 utils/adt/int.c:908 +#: utils/adt/int.c:922 utils/adt/int.c:954 utils/adt/int.c:1192 +#: utils/adt/int8.c:1320 utils/adt/numeric.c:4317 utils/adt/numeric.c:4326 +#, c-format +msgid "smallint out of range" +msgstr "smallint ist außerhalb des gültigen Bereichs" + +#: utils/adt/float.c:1458 utils/adt/numeric.c:3550 utils/adt/numeric.c:9310 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "Quadratwurzel von negativer Zahl kann nicht ermittelt werden" + +#: utils/adt/float.c:1526 utils/adt/numeric.c:3825 utils/adt/numeric.c:3935 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "null hoch eine negative Zahl ist undefiniert" + +#: utils/adt/float.c:1530 utils/adt/numeric.c:3829 utils/adt/numeric.c:3940 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "eine negative Zahl hoch eine nicht ganze Zahl ergibt ein komplexes Ergebnis" + +#: utils/adt/float.c:1706 utils/adt/float.c:1739 utils/adt/numeric.c:3737 +#: utils/adt/numeric.c:9974 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "Logarithmus von null kann nicht ermittelt werden" + +#: utils/adt/float.c:1710 utils/adt/float.c:1743 utils/adt/numeric.c:3675 +#: utils/adt/numeric.c:3732 utils/adt/numeric.c:9978 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "Logarithmus negativer Zahlen kann nicht ermittelt werden" + +#: utils/adt/float.c:1776 utils/adt/float.c:1807 utils/adt/float.c:1902 +#: utils/adt/float.c:1929 utils/adt/float.c:1957 utils/adt/float.c:1984 +#: utils/adt/float.c:2131 utils/adt/float.c:2168 utils/adt/float.c:2338 +#: utils/adt/float.c:2394 utils/adt/float.c:2459 utils/adt/float.c:2516 +#: utils/adt/float.c:2707 utils/adt/float.c:2731 +#, c-format +msgid "input is out of range" +msgstr "Eingabe ist außerhalb des gültigen Bereichs" + +#: utils/adt/float.c:2798 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "setseed-Parameter %g ist außerhalb des gültigen Bereichs [-1;-1]" + +#: utils/adt/float.c:4030 utils/adt/numeric.c:1716 +#, c-format +msgid "count must be greater than zero" +msgstr "Anzahl muss größer als null sein" + +#: utils/adt/float.c:4035 utils/adt/numeric.c:1727 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "Operand, Untergrenze und Obergrenze dürfen nicht NaN sein" + +#: utils/adt/float.c:4041 utils/adt/numeric.c:1732 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "Untergrenze und Obergrenze müssen endlich sein" + +#: utils/adt/float.c:4075 utils/adt/numeric.c:1746 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "Untergrenze kann nicht gleich der Obergrenze sein" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "ungültige Formatangabe für Intervall-Wert" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "Intervalle beziehen sich nicht auf bestimmte Kalenderdaten." + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "»EEEE« muss das letzte Muster sein" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "»9« muss vor »PR« stehen" + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "»0« muss vor »PR« stehen" + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "mehrere Dezimalpunkte" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "»V« und Dezimalpunkt können nicht zusammen verwendet werden" + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "»S« kann nicht zweimal verwendet werden" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "»S« und »PL«/»MI«/»SG«/»PR« können nicht zusammen verwendet werden" + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "»S« und »MI« können nicht zusammen verwendet werden" + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "»S« und »PL« können nicht zusammen verwendet werden" + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "»S« und »SG« können nicht zusammen verwendet werden" + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "»PR« und »S«/»PL«/»MI«/»SG« können nicht zusammen verwendet werden" + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "»EEEE« kann nicht zweimal verwendet werden" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "»EEEE« ist mit anderen Formaten inkompatibel" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "»EEEE« kann nur zusammen mit Platzhaltern für Ziffern oder Dezimalpunkt verwendet werden." + +#: utils/adt/formatting.c:1394 +#, c-format +msgid "invalid datetime format separator: \"%s\"" +msgstr "ungültiges Datum-/Zeit-Formattrennzeichen: »%s«" + +#: utils/adt/formatting.c:1521 +#, c-format +msgid "\"%s\" is not a number" +msgstr "»%s« ist keine Zahl" + +#: utils/adt/formatting.c:1599 +#, c-format +msgid "case conversion failed: %s" +msgstr "Groß/Klein-Umwandlung fehlgeschlagen: %s" + +#: utils/adt/formatting.c:1664 utils/adt/formatting.c:1788 +#: utils/adt/formatting.c:1913 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "konnte die für die Funktion %s zu verwendende Sortierfolge nicht bestimmen" + +#: utils/adt/formatting.c:2285 +#, c-format +msgid "invalid combination of date conventions" +msgstr "ungültige Kombination von Datumskonventionen" + +#: utils/adt/formatting.c:2286 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "Die Gregorianische und die ISO-Konvention für Wochendaten können nicht einer Formatvorlage gemischt werden." + +#: utils/adt/formatting.c:2309 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "widersprüchliche Werte für das Feld »%s« in Formatzeichenkette" + +#: utils/adt/formatting.c:2312 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "Der Wert widerspricht einer vorherigen Einstellung für den selben Feldtyp." + +#: utils/adt/formatting.c:2383 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "Quellzeichenkette zu kurz für Formatfeld »%s»" + +#: utils/adt/formatting.c:2386 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "Feld benötigt %d Zeichen, aber nur %d verbleiben." + +#: utils/adt/formatting.c:2389 utils/adt/formatting.c:2404 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "Wenn die Quellzeichenkette keine feste Breite hat, versuchen Sie den Modifikator »FM«." + +#: utils/adt/formatting.c:2399 utils/adt/formatting.c:2413 +#: utils/adt/formatting.c:2636 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "ungültiger Wert »%s« für »%s«" + +#: utils/adt/formatting.c:2401 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "Feld benötigt %d Zeichen, aber nur %d konnten geparst werden." + +#: utils/adt/formatting.c:2415 +#, c-format +msgid "Value must be an integer." +msgstr "Der Wert muss eine ganze Zahl sein." + +#: utils/adt/formatting.c:2420 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "Wert für »%s« in der Eingabezeichenkette ist außerhalb des gültigen Bereichs" + +#: utils/adt/formatting.c:2422 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "Der Wert muss im Bereich %d bis %d sein." + +#: utils/adt/formatting.c:2638 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "Der angegebene Wert stimmte mit keinem der für dieses Feld zulässigen Werte überein." + +#: utils/adt/formatting.c:2855 utils/adt/formatting.c:2875 +#: utils/adt/formatting.c:2895 utils/adt/formatting.c:2915 +#: utils/adt/formatting.c:2934 utils/adt/formatting.c:2953 +#: utils/adt/formatting.c:2977 utils/adt/formatting.c:2995 +#: utils/adt/formatting.c:3013 utils/adt/formatting.c:3031 +#: utils/adt/formatting.c:3048 utils/adt/formatting.c:3065 +#, c-format +msgid "localized string format value too long" +msgstr "lokalisierter Formatwert ist zu lang" + +#: utils/adt/formatting.c:3342 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "Formattrennzeichen »%c« ohne passende Eingabe" + +#: utils/adt/formatting.c:3403 +#, c-format +msgid "unmatched format character \"%s\"" +msgstr "Formatzeichen »%s« ohne passende Eingabe" + +#: utils/adt/formatting.c:3509 utils/adt/formatting.c:3853 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "Formatfeld »%s« wird nur in to_char unterstützt" + +#: utils/adt/formatting.c:3684 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "ungültige Eingabe für »Y,YYY«" + +#: utils/adt/formatting.c:3770 +#, c-format +msgid "input string is too short for datetime format" +msgstr "Eingabezeichenkette ist zu kurz für Datum-/Zeitformat" + +#: utils/adt/formatting.c:3778 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "nach dem Datum-/Zeitformat bleiben noch Zeichen in der Eingabezeichenkette" + +#: utils/adt/formatting.c:4323 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "Zeitzone fehlt in Eingabezeichenkette für Typ timestamptz" + +#: utils/adt/formatting.c:4329 +#, c-format +msgid "timestamptz out of range" +msgstr "timestamptz ist außerhalb des gültigen Bereichs" + +#: utils/adt/formatting.c:4357 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "Datum-/Zeitformat hat Zeitzone aber keine Zeit" + +#: utils/adt/formatting.c:4409 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "Zeitzone fehlt in Eingabezeichenkette für Typ timetz" + +#: utils/adt/formatting.c:4415 +#, c-format +msgid "timetz out of range" +msgstr "timetz ist außerhalb des gültigen Bereichs" + +#: utils/adt/formatting.c:4441 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "Datum-/Zeitformat hat kein Datum und keine Zeit" + +#: utils/adt/formatting.c:4574 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "Stunde »%d« ist bei einer 12-Stunden-Uhr ungültig" + +#: utils/adt/formatting.c:4576 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Verwenden Sie die 24-Stunden-Uhr oder geben Sie eine Stunde zwischen 1 und 12 an." + +#: utils/adt/formatting.c:4687 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "kann Tag des Jahres nicht berechnen ohne Jahrinformationen" + +#: utils/adt/formatting.c:5606 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "»E« wird nicht bei der Eingabe unterstützt" + +#: utils/adt/formatting.c:5618 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "»RN« wird nicht bei der Eingabe unterstützt" + +#: utils/adt/genfile.c:78 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "Verweis auf übergeordnetes Verzeichnis (»..«) nicht erlaubt" + +#: utils/adt/genfile.c:89 +#, c-format +msgid "absolute path not allowed" +msgstr "absoluter Pfad nicht erlaubt" + +#: utils/adt/genfile.c:94 +#, c-format +msgid "path must be in or below the current directory" +msgstr "Pfad muss in oder unter aktuellem Verzeichnis sein" + +#: utils/adt/genfile.c:119 utils/adt/oracle_compat.c:187 +#: utils/adt/oracle_compat.c:285 utils/adt/oracle_compat.c:833 +#: utils/adt/oracle_compat.c:1128 +#, c-format +msgid "requested length too large" +msgstr "verlangte Länge zu groß" + +#: utils/adt/genfile.c:136 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %m" + +#: utils/adt/genfile.c:176 +#, c-format +msgid "file length too large" +msgstr "Dateilänge zu groß" + +#: utils/adt/genfile.c:253 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "nur Superuser können mit adminpack 1.0 Dateien lesen" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "ungültige »line«-Angabe: A und B können nicht beide null sein" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1097 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "ungültige »line«-Angabe: es müssen zwei verschiedene Punkte angegeben werden" + +#: utils/adt/geo_ops.c:1410 utils/adt/geo_ops.c:3498 utils/adt/geo_ops.c:4366 +#: utils/adt/geo_ops.c:5260 +#, c-format +msgid "too many points requested" +msgstr "zu viele Punkte verlangt" + +#: utils/adt/geo_ops.c:1472 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "ungültige Anzahl Punkte in externem »path«-Wert" + +#: utils/adt/geo_ops.c:2549 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "Funktion »dist_lb« ist nicht implementiert" + +#: utils/adt/geo_ops.c:2568 +#, c-format +msgid "function \"dist_bl\" not implemented" +msgstr "Funktion »dist_bl« ist nicht implementiert" + +#: utils/adt/geo_ops.c:2987 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "Funktion »close_sl« ist nicht implementiert" + +#: utils/adt/geo_ops.c:3134 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "Funktion »close_lb« ist nicht implementiert" + +#: utils/adt/geo_ops.c:3545 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "ungültige Anzahl Punkte in externem »polygon«-Wert" + +#: utils/adt/geo_ops.c:4081 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "Funktion »poly_distance« ist nicht implementiert" + +#: utils/adt/geo_ops.c:4458 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "Funktion »path_center« ist nicht implementiert" + +#: utils/adt/geo_ops.c:4475 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "offener Pfad kann nicht in Polygon umgewandelt werden" + +#: utils/adt/geo_ops.c:4725 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "ungültiger Radius in externem »circle«-Wert" + +#: utils/adt/geo_ops.c:5246 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "kann Kreis mit Radius null nicht in Polygon umwandeln" + +#: utils/adt/geo_ops.c:5251 +#, c-format +msgid "must request at least 2 points" +msgstr "mindestens 2 Punkte müssen angefordert werden" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector-Wert hat zu viele Elemente" + +#: utils/adt/int.c:237 +#, c-format +msgid "invalid int2vector data" +msgstr "ungültige int2vector-Daten" + +#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector-Wert hat zu viele Elemente" + +#: utils/adt/int.c:1508 utils/adt/int8.c:1446 utils/adt/numeric.c:1624 +#: utils/adt/timestamp.c:5771 utils/adt/timestamp.c:5851 +#, c-format +msgid "step size cannot equal zero" +msgstr "Schrittgröße kann nicht gleich null sein" + +#: utils/adt/int8.c:534 utils/adt/int8.c:557 utils/adt/int8.c:571 +#: utils/adt/int8.c:585 utils/adt/int8.c:616 utils/adt/int8.c:640 +#: utils/adt/int8.c:722 utils/adt/int8.c:790 utils/adt/int8.c:796 +#: utils/adt/int8.c:822 utils/adt/int8.c:836 utils/adt/int8.c:860 +#: utils/adt/int8.c:873 utils/adt/int8.c:942 utils/adt/int8.c:956 +#: utils/adt/int8.c:970 utils/adt/int8.c:1001 utils/adt/int8.c:1023 +#: utils/adt/int8.c:1037 utils/adt/int8.c:1051 utils/adt/int8.c:1084 +#: utils/adt/int8.c:1098 utils/adt/int8.c:1112 utils/adt/int8.c:1143 +#: utils/adt/int8.c:1165 utils/adt/int8.c:1179 utils/adt/int8.c:1193 +#: utils/adt/int8.c:1355 utils/adt/int8.c:1390 utils/adt/numeric.c:4276 +#: utils/adt/varbit.c:1676 +#, c-format +msgid "bigint out of range" +msgstr "bigint ist außerhalb des gültigen Bereichs" + +#: utils/adt/int8.c:1403 +#, c-format +msgid "OID out of range" +msgstr "OID ist außerhalb des gültigen Bereichs" + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "Schlüsselwert muss skalar sein, nicht Array, zusammengesetzt oder json" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1994 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "konnte Datentyp von Argument %d nicht ermitteln" + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "Feldname darf nicht NULL sein" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "Argumentliste muss gerade Anzahl Elemente haben" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "Die Argumente von %s müssen abwechselnd Schlüssel und Werte sein." + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "Argument %d darf nicht NULL sein" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "Objektschlüssel sollten Text sein." + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "Array muss zwei Spalten haben" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 +#: utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "NULL-Werte sind nicht als Objektschlüssel erlaubt" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "Array-Dimensionen passen nicht" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "Zeichenkette ist zu lang für jsonb" + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "Aufgrund einer Einschränkung der Implementierung können jsonb-Zeichenketten nicht länger als %d Bytes sein." + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "Argument %d: Schlüssel darf nicht NULL sein" + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "Objektschlüssel müssen Zeichenketten sein" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "kann jsonb-Null-Wert nicht in Typ %s umwandeln" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "kann jsonb-Zeichenkette nicht in Typ %s umwandeln" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "kann jsonb numerischen Wert nicht in Typ %s umwandeln" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "kann jsonb-boolean nicht in Typ %s umwandeln" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "kann jsonb-Array nicht in Typ %s umwandeln" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "kann jsonb-Objekt nicht in Typ %s umwandeln" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "kann jsonb-Array oder -Objekt nicht in Typ %s umwandeln" + +#: utils/adt/jsonb_util.c:751 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "Anzahl der jsonb-Objekte-Paare überschreitet erlaubtes Maximum (%zu)" + +#: utils/adt/jsonb_util.c:792 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "Anzahl der jsonb-Arrayelemente überschreitet erlaubtes Maximum (%zu)" + +#: utils/adt/jsonb_util.c:1666 utils/adt/jsonb_util.c:1686 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "Gesamtgröße der jsonb-Array-Elemente überschreitet die maximale Größe von %u Bytes" + +#: utils/adt/jsonb_util.c:1747 utils/adt/jsonb_util.c:1782 +#: utils/adt/jsonb_util.c:1802 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "Gesamtgröße der jsonb-Objektelemente überschreitet die maximale Größe von %u Bytes" + +#: utils/adt/jsonbsubs.c:70 utils/adt/jsonbsubs.c:152 +#, fuzzy, c-format +#| msgid "this build does not support compression" +msgid "jsonb subscript does not support slices" +msgstr "diese Installation unterstützt keine Komprimierung" + +#: utils/adt/jsonbsubs.c:103 utils/adt/jsonbsubs.c:118 +#, fuzzy, c-format +#| msgid "log format \"%s\" is not supported" +msgid "subscript type is not supported" +msgstr "Logformat »%s« wird nicht unterstützt" + +#: utils/adt/jsonbsubs.c:104 +#, c-format +msgid "Jsonb subscript must be coerced only to one type, integer or text." +msgstr "" + +#: utils/adt/jsonbsubs.c:119 +#, c-format +msgid "Jsonb subscript must be coerced to either integer or text" +msgstr "" + +#: utils/adt/jsonbsubs.c:140 +#, fuzzy, c-format +#| msgid "array subscript must have type integer" +msgid "jsonb subscript must have text type" +msgstr "Arrayindex muss Typ integer haben" + +#: utils/adt/jsonbsubs.c:208 +#, fuzzy, c-format +#| msgid "array subscript in assignment must not be null" +msgid "jsonb subscript in assignment must not be null" +msgstr "Arrayindex in Zuweisung darf nicht NULL sein" + +#: utils/adt/jsonfuncs.c:555 utils/adt/jsonfuncs.c:789 +#: utils/adt/jsonfuncs.c:2471 utils/adt/jsonfuncs.c:2911 +#: utils/adt/jsonfuncs.c:3700 utils/adt/jsonfuncs.c:4030 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "%s kann nicht mit einem skalaren Wert aufgerufen werden" + +#: utils/adt/jsonfuncs.c:560 utils/adt/jsonfuncs.c:776 +#: utils/adt/jsonfuncs.c:2913 utils/adt/jsonfuncs.c:3689 +#, c-format +msgid "cannot call %s on an array" +msgstr "%s kann nicht mit einem Array aufgerufen werden" + +#: utils/adt/jsonfuncs.c:685 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "JSON-Daten, Zeile %d: %s%s%s" + +#: utils/adt/jsonfuncs.c:1823 utils/adt/jsonfuncs.c:1858 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "kann nicht die Arraylänge eines skalaren Wertes ermitteln" + +#: utils/adt/jsonfuncs.c:1827 utils/adt/jsonfuncs.c:1846 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "kann nicht die Arraylänge eines Nicht-Arrays ermitteln" + +#: utils/adt/jsonfuncs.c:1923 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "%s kann nicht mit etwas aufgerufen werden, das kein Objekt ist" + +#: utils/adt/jsonfuncs.c:2162 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "kann Array nicht in ein Objekt zerlegen" + +#: utils/adt/jsonfuncs.c:2174 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "kann skalaren Wert nicht zerlegen" + +#: utils/adt/jsonfuncs.c:2220 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "kann keine Elemente aus einem skalaren Wert auswählen" + +#: utils/adt/jsonfuncs.c:2224 +#, c-format +msgid "cannot extract elements from an object" +msgstr "kann keine Elemente aus einem Objekt auswählen" + +#: utils/adt/jsonfuncs.c:2458 utils/adt/jsonfuncs.c:3915 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "%s kann nicht mit etwas aufgerufen werden, das kein Array ist" + +#: utils/adt/jsonfuncs.c:2528 utils/adt/jsonfuncs.c:2533 +#: utils/adt/jsonfuncs.c:2550 utils/adt/jsonfuncs.c:2556 +#, c-format +msgid "expected JSON array" +msgstr "JSON-Array wurde erwartet" + +#: utils/adt/jsonfuncs.c:2529 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Prüfen Sie den Wert des Schlüssels »%s«." + +#: utils/adt/jsonfuncs.c:2551 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Prüfen Sie das Arrayelement %s des Schlüssels »%s«." + +#: utils/adt/jsonfuncs.c:2557 +#, c-format +msgid "See the array element %s." +msgstr "Prüfen Sie das Arrayelement %s." + +#: utils/adt/jsonfuncs.c:2592 +#, c-format +msgid "malformed JSON array" +msgstr "fehlerhaftes JSON-Array" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3419 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "erstes Argument von %s muss ein Zeilentyp sein" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3443 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "konnte Zeilentyp für Ergebnis von %s nicht ermitteln" + +#: utils/adt/jsonfuncs.c:3445 +#, c-format +msgid "Provide a non-null record argument, or call the function in the FROM clause using a column definition list." +msgstr "Geben Sie ein »record«-Argument, das nicht NULL ist, an oder rufen Sie die Funktion in der FROM-Klausel mit einer Spaltendefinitionsliste auf." + +#: utils/adt/jsonfuncs.c:3932 utils/adt/jsonfuncs.c:4012 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "Argument von %s muss ein Array von Objekten sein" + +#: utils/adt/jsonfuncs.c:3965 +#, c-format +msgid "cannot call %s on an object" +msgstr "%s kann nicht mit einem Objekt aufgerufen werden" + +#: utils/adt/jsonfuncs.c:4373 utils/adt/jsonfuncs.c:4432 +#: utils/adt/jsonfuncs.c:4512 +#, c-format +msgid "cannot delete from scalar" +msgstr "kann nicht aus skalarem Wert löschen" + +#: utils/adt/jsonfuncs.c:4517 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "aus einem Objekt kann nicht per numerischem Index gelöscht werden" + +#: utils/adt/jsonfuncs.c:4585 utils/adt/jsonfuncs.c:4746 +#, c-format +msgid "cannot set path in scalar" +msgstr "in einem skalaren Wert kann kein Pfad gesetzt werden" + +#: utils/adt/jsonfuncs.c:4627 utils/adt/jsonfuncs.c:4669 +#, c-format +msgid "null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"" +msgstr "null_value_treatment muss »delete_key«, »return_target«, »use_json_null« oder »raise_exception« sein" + +#: utils/adt/jsonfuncs.c:4640 +#, c-format +msgid "JSON value must not be null" +msgstr "JSON-Wert darf nicht NULL sein" + +#: utils/adt/jsonfuncs.c:4641 +#, c-format +msgid "Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "Ausnahme wurde ausgelöst, weil null_value_treatment »raise_exception« ist." + +#: utils/adt/jsonfuncs.c:4642 +#, c-format +msgid "To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed." +msgstr "Um dies zu vermeiden, ändern Sie das Argument null_value_treatment oder sorgen Sie dafür, dass kein SQL NULL übergeben wird." + +#: utils/adt/jsonfuncs.c:4697 +#, c-format +msgid "cannot delete path in scalar" +msgstr "in einem skalaren Wert kann kein Pfad gelöscht werden" + +#: utils/adt/jsonfuncs.c:4913 +#, c-format +msgid "path element at position %d is null" +msgstr "Pfadelement auf Position %d ist NULL" + +#: utils/adt/jsonfuncs.c:4932 utils/adt/jsonfuncs.c:4963 +#: utils/adt/jsonfuncs.c:5030 +#, c-format +msgid "cannot replace existing key" +msgstr "existierender Schlüssel kann nicht ersetzt werden" + +#: utils/adt/jsonfuncs.c:4933 utils/adt/jsonfuncs.c:4964 +#, c-format +msgid "The path assumes key is a composite object, but it is a scalar value." +msgstr "" + +#: utils/adt/jsonfuncs.c:5031 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "Verwenden Sie die Funktion jsonb_set, um den Schlüsselwert zu ersetzen." + +#: utils/adt/jsonfuncs.c:5135 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "Pfadelement auf Position %d ist keine ganze Zahl: »%s«" + +#: utils/adt/jsonfuncs.c:5152 +#, fuzzy, c-format +#| msgid "path element at position %d is not an integer: \"%s\"" +msgid "path element at position %d is out of range: %d" +msgstr "Pfadelement auf Position %d ist keine ganze Zahl: »%s«" + +#: utils/adt/jsonfuncs.c:5304 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "falscher Flag-Typ, nur Arrays und skalare Werte sind erlaubt" + +#: utils/adt/jsonfuncs.c:5311 +#, c-format +msgid "flag array element is not a string" +msgstr "Flag-Array-Element ist keine Zeichenkette" + +#: utils/adt/jsonfuncs.c:5312 utils/adt/jsonfuncs.c:5334 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "Mögliche Werte sind: »string«, »numeric«, »boolean«, »key« und »all«." + +#: utils/adt/jsonfuncs.c:5332 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "falsche Flag im Flag-Array: »%s«" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ ist nicht erlaubt in Wurzelausdrücken" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST ist nur in Arrayindizes erlaubt" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "ein einzelnes Ergebnis mit Typ boolean wird erwartet" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "Argument »vars« ist kein Objekt" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "JSON-Path-Parameter sollten als Schüssel-Wert-Paare im »vars«-Objekt kodiert werden." + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "JSON-Objekt enthält Schlüssel »%s« nicht" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "JSON-Path-Member-Zugriff kann nur auf ein Objekt angewendet werden" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "JSON-Path-Wildcard-Array-Indizierung kann nur auf ein Array angewendet werden" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "JSON-Path-Arrayindex ist außerhalb des gültigen Bereichs" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "JSON-Path-Array-Indizierung kann nur auf ein Array angewendet werden" + +#: utils/adt/jsonpath_exec.c:872 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "JSON-Path-Wildcard-Member-Zugriff kann nur auf ein Objekt angwendet werden" + +#: utils/adt/jsonpath_exec.c:1002 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "Jsonpath-Item-Methode .%s() kann nur auf ein Array angewendet werden" + +#: utils/adt/jsonpath_exec.c:1055 +#, c-format +msgid "numeric argument of jsonpath item method .%s() is out of range for type double precision" +msgstr "numerisches Argument der JSON-Path-Item-Methode .%s() ist außerhalb des gültigen Bereichs für Typ double precision" + +#: utils/adt/jsonpath_exec.c:1076 +#, c-format +msgid "string argument of jsonpath item method .%s() is not a valid representation of a double precision number" +msgstr "Zeichenkettenargument der JSON-Path-Item-Methode .%s() ist nicht gültig für Typ double precision" + +#: utils/adt/jsonpath_exec.c:1089 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "JSON-Path-Item-Methode .%s() kann nur auf eine Zeichenkette oder einen numerischen Wert angewendet werden" + +#: utils/adt/jsonpath_exec.c:1579 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "linker Operand des JSON-Path-Operators %s ist kein einzelner numerischer Wert" + +#: utils/adt/jsonpath_exec.c:1586 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "rechter Operand des JSON-Path-Operators %s ist kein einzelner numerischer Wert" + +#: utils/adt/jsonpath_exec.c:1654 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "Operand des unären JSON-Path-Operators %s ist kein numerischer Wert" + +#: utils/adt/jsonpath_exec.c:1752 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "JSON-Path-Item-Methode .%s() kann nur auf einen numerischen Wert angewendet werden" + +#: utils/adt/jsonpath_exec.c:1792 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "JSON-Path-Item-Methode .%s() kann nur auf eine Zeichenkette angewendet werden" + +#: utils/adt/jsonpath_exec.c:1886 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "Datum-/Zeitformat nicht erkannt: »%s«" + +#: utils/adt/jsonpath_exec.c:1888 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "Verwenden Sie das Template-Argument für .datetime(), um das Eingabeformat anzugeben." + +#: utils/adt/jsonpath_exec.c:1956 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "JSON-Path-Item-Methode .%s() kann nur auf ein Objekt angewendet werden" + +#: utils/adt/jsonpath_exec.c:2138 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "konnte JSON-Path-Variable »%s« nicht finden" + +#: utils/adt/jsonpath_exec.c:2402 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "JSON-Path-Arrayindex ist kein einzelner numerischer Wert" + +#: utils/adt/jsonpath_exec.c:2414 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "JSON-Path-Arrayindex außerhalb des gültigen Bereichs für ganze Zahlen" + +#: utils/adt/jsonpath_exec.c:2591 +#, c-format +msgid "cannot convert value from %s to %s without time zone usage" +msgstr "Wert kann nicht von %s nach %s konvertiert werden ohne Verwendung von Zeitzonen" + +#: utils/adt/jsonpath_exec.c:2593 +#, c-format +msgid "Use *_tz() function for time zone support." +msgstr "Verwenden Sie die *_tz()-Funktion für Zeitzonenunterstützung." + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "Levenshtein-Argument überschreitet die maximale Länge von %d Zeichen" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "nichtdeterministische Sortierfolgen werden von LIKE nicht unterstützt" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "konnte die für ILIKE zu verwendende Sortierfolge nicht bestimmen" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "nichtdeterministische Sortierfolgen werden von ILIKE nicht unterstützt" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "LIKE-Muster darf nicht mit Escape-Zeichen enden" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "ungültige ESCAPE-Zeichenkette" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "ESCAPE-Zeichenkette muss null oder ein Zeichen lang sein." + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "Mustersuche ohne Rücksicht auf Groß-/Kleinschreibung wird für Typ bytea nicht unterstützt" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "Mustersuche mit regulären Ausdrücken wird für Typ bytea nicht unterstützt" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "ungültiger Oktettwert in »macaddr«-Wert: »%s«" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "macaddr8-Daten außerhalb des gültigen Bereichs für Umwandlung in macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Nur Adressen, die FF und FE als Werte im 4. und 5. Byte von links haben, zum Beispiel xx:xx:xx:ff:fe:xx:xx:xx, kommen für eine Umwandlung von macaddr8 nach macaddr in Frage." + +#: utils/adt/mcxtfuncs.c:204 +#, fuzzy, c-format +#| msgid "must be superuser to alter a type" +msgid "must be a superuser to log memory contexts" +msgstr "nur Superuser können Typen ändern" + +#: utils/adt/misc.c:243 +#, c-format +msgid "global tablespace never has databases" +msgstr "globaler Tablespace hat niemals Datenbanken" + +#: utils/adt/misc.c:265 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u ist keine Tablespace-OID" + +#: utils/adt/misc.c:455 +msgid "unreserved" +msgstr "unreserviert" + +#: utils/adt/misc.c:459 +msgid "unreserved (cannot be function or type name)" +msgstr "unreserviert (kann nicht Funktions- oder Typname sein)" + +#: utils/adt/misc.c:463 +msgid "reserved (can be function or type name)" +msgstr "reserviert (kann Funktions- oder Typname sein)" + +#: utils/adt/misc.c:467 +msgid "reserved" +msgstr "reserviert" + +#: utils/adt/misc.c:478 +msgid "can be bare label" +msgstr "" + +#: utils/adt/misc.c:483 +msgid "requires AS" +msgstr "" + +#: utils/adt/misc.c:730 utils/adt/misc.c:744 utils/adt/misc.c:783 +#: utils/adt/misc.c:789 utils/adt/misc.c:795 utils/adt/misc.c:818 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "Zeichenkette ist kein gültiger Bezeichner: »%s«" + +#: utils/adt/misc.c:732 +#, c-format +msgid "String has unclosed double quotes." +msgstr "Zeichenkette hat nicht geschlossene doppelte Anführungszeichen." + +#: utils/adt/misc.c:746 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "Bezeichner in Anführungszeichen darf nicht leer sein." + +#: utils/adt/misc.c:785 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "Kein gültiger Bezeichner vor ».«." + +#: utils/adt/misc.c:791 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "Kein gültiger Bezeichner nach ».«." + +#: utils/adt/misc.c:849 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "Logformat »%s« wird nicht unterstützt" + +#: utils/adt/misc.c:850 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "Die unterstützten Logformate sind »stderr« und »csvlog«." + +#: utils/adt/multirangetypes.c:147 utils/adt/multirangetypes.c:160 +#: utils/adt/multirangetypes.c:189 utils/adt/multirangetypes.c:259 +#: utils/adt/multirangetypes.c:283 +#, fuzzy, c-format +#| msgid "malformed range literal: \"%s\"" +msgid "malformed multirange literal: \"%s\"" +msgstr "fehlerhafte Bereichskonstante: »%s«" + +#: utils/adt/multirangetypes.c:149 +#, fuzzy, c-format +#| msgid "Missing left parenthesis." +msgid "Missing left brace." +msgstr "Linke Klammer fehlt." + +#: utils/adt/multirangetypes.c:191 +#, fuzzy, c-format +#| msgid "unexpected array start" +msgid "Expected range start." +msgstr "unerwarteter Array-Start" + +#: utils/adt/multirangetypes.c:261 +#, fuzzy, c-format +#| msgid "unexpected end of line" +msgid "Expected comma or end of multirange." +msgstr "unerwartetes Ende der Zeile" + +#: utils/adt/multirangetypes.c:285 +#, fuzzy, c-format +#| msgid "Junk after closing right brace." +msgid "Junk after right brace." +msgstr "Müll nach schließender rechter geschweifter Klammer." + +#: utils/adt/multirangetypes.c:971 +#, fuzzy, c-format +#| msgid "thresholds must be one-dimensional array" +msgid "multiranges cannot be constructed from multi-dimensional arrays" +msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" + +#: utils/adt/multirangetypes.c:977 utils/adt/multirangetypes.c:1042 +#, fuzzy, c-format +#| msgid "type %s is not a composite type" +msgid "type %u does not match constructor type" +msgstr "Typ %s ist kein zusammengesetzter Typ" + +#: utils/adt/multirangetypes.c:999 +#, c-format +msgid "multirange values cannot contain NULL members" +msgstr "" + +#: utils/adt/multirangetypes.c:1349 +#, fuzzy, c-format +#| msgid "%s must be called inside a transaction" +msgid "range_agg must be called with a range" +msgstr "%s muss in einer Transaktion aufgerufen werden" + +#: utils/adt/multirangetypes.c:1420 +#, c-format +msgid "range_intersect_agg must be called with a multirange" +msgstr "" + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "ungültiger cidr-Wert: »%s«" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "Wert hat gesetzte Bits rechts von der Maske." + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 +#: utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "konnte inet-Wert nicht formatieren: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "ungültige Adressfamilie in externem »%s«-Wert" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "ungültige Bits in externem »%s«-Wert" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "ungültige Länge in externem »%s«-Wert" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "ungültiger externer »cidr«-Wert" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "ungültige Maskenlänge: %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "konnte cidr-Wert nicht formatieren: %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "Adressen verschiedener Familien können nicht zusammengeführt werden" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "binäres »Und« nicht mit »inet«-Werten unterschiedlicher Größe möglich" + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "binäres »Oder« nicht mit »inet«-Werten unterschiedlicher Größe möglich" + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "Ergebnis ist außerhalb des gültigen Bereichs" + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "Subtraktion von »inet«-Werten unterschiedlicher Größe nicht möglich" + +#: utils/adt/numeric.c:975 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "ungültiges Vorzeichen in externem »numeric«-Wert" + +#: utils/adt/numeric.c:981 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "ungültige Skala in externem »numeric«-Wert" + +#: utils/adt/numeric.c:990 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "ungültige Ziffer in externem »numeric«-Wert" + +#: utils/adt/numeric.c:1203 utils/adt/numeric.c:1217 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "Präzision von NUMERIC (%d) muss zwischen 1 und %d liegen" + +#: utils/adt/numeric.c:1208 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "Skala von NUMERIC (%d) muss zwischen 0 und %d liegen" + +#: utils/adt/numeric.c:1226 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "ungültiker Modifikator für Typ NUMERIC" + +#: utils/adt/numeric.c:1584 +#, c-format +msgid "start value cannot be NaN" +msgstr "Startwert kann nicht NaN sein" + +#: utils/adt/numeric.c:1588 +#, fuzzy, c-format +#| msgid "start value cannot be NaN" +msgid "start value cannot be infinity" +msgstr "Startwert kann nicht NaN sein" + +#: utils/adt/numeric.c:1595 +#, c-format +msgid "stop value cannot be NaN" +msgstr "Stoppwert kann nicht NaN sein" + +#: utils/adt/numeric.c:1599 +#, fuzzy, c-format +#| msgid "stop value cannot be NaN" +msgid "stop value cannot be infinity" +msgstr "Stoppwert kann nicht NaN sein" + +#: utils/adt/numeric.c:1612 +#, c-format +msgid "step size cannot be NaN" +msgstr "Schrittgröße kann nicht NaN sein" + +#: utils/adt/numeric.c:1616 +#, fuzzy, c-format +#| msgid "step size cannot be NaN" +msgid "step size cannot be infinity" +msgstr "Schrittgröße kann nicht NaN sein" + +#: utils/adt/numeric.c:3490 +#, fuzzy, c-format +#| msgid "zero raised to a negative power is undefined" +msgid "factorial of a negative number is undefined" +msgstr "null hoch eine negative Zahl ist undefiniert" + +#: utils/adt/numeric.c:3500 utils/adt/numeric.c:6924 utils/adt/numeric.c:7408 +#: utils/adt/numeric.c:9783 utils/adt/numeric.c:10221 utils/adt/numeric.c:10335 +#: utils/adt/numeric.c:10408 +#, c-format +msgid "value overflows numeric format" +msgstr "Wert verursacht Überlauf im »numeric«-Format" + +#: utils/adt/numeric.c:4185 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "kann NaN nicht in integer umwandeln" + +#: utils/adt/numeric.c:4189 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to integer" +msgstr "kann Unendlich nicht in numeric umwandeln" + +#: utils/adt/numeric.c:4263 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "kann NaN nicht in bigint umwandeln" + +#: utils/adt/numeric.c:4267 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to bigint" +msgstr "kann Unendlich nicht in numeric umwandeln" + +#: utils/adt/numeric.c:4304 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "kann NaN nicht in smallint umwandeln" + +#: utils/adt/numeric.c:4308 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to smallint" +msgstr "kann Unendlich nicht in numeric umwandeln" + +#: utils/adt/numeric.c:4499 +#, fuzzy, c-format +#| msgid "cannot convert NaN to bigint" +msgid "cannot convert NaN to pg_lsn" +msgstr "kann NaN nicht in bigint umwandeln" + +#: utils/adt/numeric.c:4503 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to pg_lsn" +msgstr "kann Unendlich nicht in numeric umwandeln" + +#: utils/adt/numeric.c:4512 +#, fuzzy, c-format +#| msgid "bigint out of range" +msgid "pg_lsn out of range" +msgstr "bigint ist außerhalb des gültigen Bereichs" + +#: utils/adt/numeric.c:7492 utils/adt/numeric.c:7539 +#, c-format +msgid "numeric field overflow" +msgstr "Feldüberlauf bei Typ »numeric«" + +#: utils/adt/numeric.c:7493 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "Ein Feld mit Präzision %d, Skala %d muss beim Runden einen Betrag von weniger als %s%d ergeben." + +#: utils/adt/numeric.c:7540 +#, fuzzy, c-format +#| msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgid "A field with precision %d, scale %d cannot hold an infinite value." +msgstr "Ein Feld mit Präzision %d, Skala %d muss beim Runden einen Betrag von weniger als %s%d ergeben." + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "Wert »%s« ist außerhalb des gültigen Bereichs für 8-Bit-Ganzzahl" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "ungültige oidvector-Daten" + +#: utils/adt/oracle_compat.c:970 +#, c-format +msgid "requested character too large" +msgstr "verlangtes Zeichen zu groß" + +#: utils/adt/oracle_compat.c:1020 utils/adt/oracle_compat.c:1082 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "gewünschtes Zeichen ist zu groß für die Kodierung: %d" + +#: utils/adt/oracle_compat.c:1061 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "gewünschtes Zeichen ist nicht gültig für die Kodierung: %d" + +#: utils/adt/oracle_compat.c:1075 +#, c-format +msgid "null character not permitted" +msgstr "Null-Zeichen ist nicht erlaubt" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "Perzentilwert %g ist nicht zwischen 0 und 1" + +#: utils/adt/pg_locale.c:1228 +#, c-format +msgid "Apply system library package updates." +msgstr "Aktualisieren Sie die Systembibliotheken." + +#: utils/adt/pg_locale.c:1442 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "konnte Locale »%s« nicht erzeugen: %m" + +#: utils/adt/pg_locale.c:1445 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "Das Betriebssystem konnte keine Locale-Daten für den Locale-Namen »%s« finden." + +#: utils/adt/pg_locale.c:1547 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "Sortierfolgen mit unterschiedlichen »collate«- und »ctype«-Werten werden auf dieser Plattform nicht unterstützt" + +#: utils/adt/pg_locale.c:1556 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "Sortierfolgen-Provider LIBC wird auf dieser Plattform nicht unterstützt" + +#: utils/adt/pg_locale.c:1568 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "Sortierfolgen mit unterschiedlichen »collate«- und »ctype«-Werten werden von ICU nicht unterstützt" + +#: utils/adt/pg_locale.c:1574 utils/adt/pg_locale.c:1661 +#: utils/adt/pg_locale.c:1940 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "konnte Collator für Locale »%s« nicht öffnen: %s" + +#: utils/adt/pg_locale.c:1588 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU wird in dieser Installation nicht unterstützt" + +#: utils/adt/pg_locale.c:1609 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "Sortierfolge »%s« hat keine tatsächliche Version, aber eine Version wurde angegeben" + +#: utils/adt/pg_locale.c:1616 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "Version von Sortierfolge »%s« stimmt nicht überein" + +#: utils/adt/pg_locale.c:1618 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "Die Sortierfolge in der Datenbank wurde mit Version %s erzeugt, aber das Betriebssystem hat Version %s." + +#: utils/adt/pg_locale.c:1621 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "Bauen Sie alle von dieser Sortierfolge beinflussten Objekte neu und führen Sie ALTER COLLATION %s REFRESH VERSION aus, oder bauen Sie PostgreSQL mit der richtigen Bibliotheksversion." + +#: utils/adt/pg_locale.c:1692 +#, fuzzy, c-format +#| msgid "could not create locale \"%s\": %m" +msgid "could not load locale \"%s\"" +msgstr "konnte Locale »%s« nicht erzeugen: %m" + +#: utils/adt/pg_locale.c:1717 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "konnte Sortierfolgenversion für Locale »%s« nicht ermitteln: Fehlercode %lu" + +#: utils/adt/pg_locale.c:1755 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "Kodierung »%s« wird von ICU nicht unterstützt" + +#: utils/adt/pg_locale.c:1762 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "konnte ICU-Konverter für Kodierung »%s« nicht öffnen: %s" + +#: utils/adt/pg_locale.c:1793 utils/adt/pg_locale.c:1802 +#: utils/adt/pg_locale.c:1831 utils/adt/pg_locale.c:1841 +#, c-format +msgid "%s failed: %s" +msgstr "%s fehlgeschlagen: %s" + +#: utils/adt/pg_locale.c:2113 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "ungültiges Mehrbytezeichen für Locale" + +#: utils/adt/pg_locale.c:2114 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "Die LC_CTYPE-Locale des Servers ist wahrscheinlich mit der Kodierung der Datenbank inkompatibel." + +#: utils/adt/pg_lsn.c:263 +#, fuzzy, c-format +#| msgid "cannot convert NaN to bigint" +msgid "cannot add NaN to pg_lsn" +msgstr "kann NaN nicht in bigint umwandeln" + +#: utils/adt/pg_lsn.c:297 +#, fuzzy, c-format +#| msgid "cannot subtract infinite dates" +msgid "cannot subtract NaN from pg_lsn" +msgstr "kann unendliche date-Werte nicht subtrahieren" + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "Funktion kann nur aufgerufen werden, wenn der Server im Binary-Upgrade-Modus ist" + +#: utils/adt/pgstatfuncs.c:503 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "ungültiger Befehlsname: »%s«" + +#: utils/adt/pseudotypes.c:58 utils/adt/pseudotypes.c:92 +#, c-format +msgid "cannot display a value of type %s" +msgstr "kann keinen Wert vom Typ %s anzeigen" + +#: utils/adt/pseudotypes.c:321 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "kann keinen Wert eines Hüllentyps annehmen" + +#: utils/adt/pseudotypes.c:331 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "kann keinen Wert eines Hüllentyps anzeigen" + +#: utils/adt/rangetypes.c:404 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "Flags-Argument des Bereichstyp-Konstruktors darf nicht NULL sein" + +#: utils/adt/rangetypes.c:1003 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "Ergebnis von Bereichsdifferenz würde nicht zusammenhängend sein" + +#: utils/adt/rangetypes.c:1064 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "Ergebnis von Bereichsvereinigung würde nicht zusammenhängend sein" + +#: utils/adt/rangetypes.c:1214 +#, c-format +msgid "range_intersect_agg must be called with a range" +msgstr "" + +#: utils/adt/rangetypes.c:1689 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "Bereichsuntergrenze muss kleiner als oder gleich der Bereichsobergrenze sein" + +#: utils/adt/rangetypes.c:2112 utils/adt/rangetypes.c:2125 +#: utils/adt/rangetypes.c:2139 +#, c-format +msgid "invalid range bound flags" +msgstr "ungültige Markierungen für Bereichsgrenzen" + +#: utils/adt/rangetypes.c:2113 utils/adt/rangetypes.c:2126 +#: utils/adt/rangetypes.c:2140 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Gültige Werte sind »[]«, »[)«, »(]« und »()«." + +#: utils/adt/rangetypes.c:2205 utils/adt/rangetypes.c:2222 +#: utils/adt/rangetypes.c:2235 utils/adt/rangetypes.c:2253 +#: utils/adt/rangetypes.c:2264 utils/adt/rangetypes.c:2308 +#: utils/adt/rangetypes.c:2316 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "fehlerhafte Bereichskonstante: »%s«" + +#: utils/adt/rangetypes.c:2207 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "Müll nach Schlüsselwort »empty«." + +#: utils/adt/rangetypes.c:2224 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Linke runde oder eckige Klammer fehlt." + +#: utils/adt/rangetypes.c:2237 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Komma fehlt nach Untergrenze." + +#: utils/adt/rangetypes.c:2255 +#, c-format +msgid "Too many commas." +msgstr "Zu viele Kommas." + +#: utils/adt/rangetypes.c:2266 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "Müll nach rechter runder oder eckiger Klammer." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4560 +#, c-format +msgid "regular expression failed: %s" +msgstr "regulärer Ausdruck fehlgeschlagen: %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%.*s\"" +msgstr "ungültige Option für regulären Ausdruck: »%.*s«" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "SQL regulärer Ausdruck darf nicht mehr als zwei Escape-Double-Quote-Separatoren enthalten" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s unterstützt die »Global«-Option nicht" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "Verwenden Sie stattdessen die Funktion regexp_matches." + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "zu viele Treffer für regulären Ausdruck" + +#: utils/adt/regproc.c:105 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "es gibt mehrere Funktionen namens »%s«" + +#: utils/adt/regproc.c:542 +#, c-format +msgid "more than one operator named %s" +msgstr "es gibt mehrere Operatoren namens %s" + +#: utils/adt/regproc.c:714 utils/adt/regproc.c:755 utils/adt/regproc.c:2054 +#: utils/adt/ruleutils.c:9642 utils/adt/ruleutils.c:9811 +#, c-format +msgid "too many arguments" +msgstr "zu viele Argumente" + +#: utils/adt/regproc.c:715 utils/adt/regproc.c:756 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Geben Sie zwei Argumente für den Operator an." + +#: utils/adt/regproc.c:1638 utils/adt/regproc.c:1662 utils/adt/regproc.c:1763 +#: utils/adt/regproc.c:1787 utils/adt/regproc.c:1889 utils/adt/regproc.c:1894 +#: utils/adt/varlena.c:3709 utils/adt/varlena.c:3714 +#, c-format +msgid "invalid name syntax" +msgstr "ungültige Namenssyntax" + +#: utils/adt/regproc.c:1952 +#, c-format +msgid "expected a left parenthesis" +msgstr "linke Klammer erwartet" + +#: utils/adt/regproc.c:1968 +#, c-format +msgid "expected a right parenthesis" +msgstr "rechte Klammer erwartet" + +#: utils/adt/regproc.c:1987 +#, c-format +msgid "expected a type name" +msgstr "Typname erwartet" + +#: utils/adt/regproc.c:2019 +#, c-format +msgid "improper type name" +msgstr "falscher Typname" + +#: utils/adt/ri_triggers.c:300 utils/adt/ri_triggers.c:1545 +#: utils/adt/ri_triggers.c:2530 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "Einfügen oder Aktualisieren in Tabelle »%s« verletzt Fremdschlüssel-Constraint »%s«" + +#: utils/adt/ri_triggers.c:303 utils/adt/ri_triggers.c:1548 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL erlaubt das Mischen von Schlüsseln, die NULL und nicht NULL sind, nicht." + +#: utils/adt/ri_triggers.c:1965 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "Funktion »%s« muss von INSERT ausgelöst werden" + +#: utils/adt/ri_triggers.c:1971 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "Funktion »%s« muss von UPDATE ausgelöst werden" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "Funktion »%s« muss von DELETE ausgelöst werden" + +#: utils/adt/ri_triggers.c:2000 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "kein »pg_constraint«-Eintrag für Trigger »%s« für Tabelle »%s«" + +#: utils/adt/ri_triggers.c:2002 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "Entfernen Sie diesen Referentielle-Integritäts-Trigger und seine Partner und führen Sie dann ALTER TABLE ADD CONSTRAINT aus." + +#: utils/adt/ri_triggers.c:2355 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "RI-Anfrage in Tabelle »%s« für Constraint »%s« von Tabelle »%s« ergab unerwartetes Ergebnis" + +#: utils/adt/ri_triggers.c:2359 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Das liegt höchstwahrscheinlich daran, dass eine Regel die Anfrage umgeschrieben hat." + +#: utils/adt/ri_triggers.c:2520 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "Entfernen der Partition »%s« verletzt Fremdschlüssel-Constraint »%s«" + +#: utils/adt/ri_triggers.c:2523 utils/adt/ri_triggers.c:2548 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "Auf Schlüssel (%s)=(%s) wird noch aus Tabelle »%s« verwiesen." + +#: utils/adt/ri_triggers.c:2534 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "Schlüssel (%s)=(%s) ist nicht in Tabelle »%s« vorhanden." + +#: utils/adt/ri_triggers.c:2537 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "Der Schlüssel ist nicht in Tabelle »%s« vorhanden." + +#: utils/adt/ri_triggers.c:2543 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "Aktualisieren oder Löschen in Tabelle »%s« verletzt Fremdschlüssel-Constraint »%s« von Tabelle »%s«" + +#: utils/adt/ri_triggers.c:2551 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "Auf den Schlüssel wird noch aus Tabelle »%s« verwiesen." + +#: utils/adt/rowtypes.c:105 utils/adt/rowtypes.c:483 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "Eingabe anonymer zusammengesetzter Typen ist nicht implementiert" + +#: utils/adt/rowtypes.c:157 utils/adt/rowtypes.c:186 utils/adt/rowtypes.c:209 +#: utils/adt/rowtypes.c:217 utils/adt/rowtypes.c:269 utils/adt/rowtypes.c:277 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "fehlerhafte Record-Konstante: »%s«" + +#: utils/adt/rowtypes.c:158 +#, c-format +msgid "Missing left parenthesis." +msgstr "Linke Klammer fehlt." + +#: utils/adt/rowtypes.c:187 +#, c-format +msgid "Too few columns." +msgstr "Zu wenige Spalten." + +#: utils/adt/rowtypes.c:270 +#, c-format +msgid "Too many columns." +msgstr "Zu viele Spalten." + +#: utils/adt/rowtypes.c:278 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Müll nach rechter Klammer." + +#: utils/adt/rowtypes.c:532 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "falsche Anzahl der Spalten: %d, erwartet wurden %d" + +#: utils/adt/rowtypes.c:574 +#, c-format +msgid "binary data has type %u (%s) instead of expected %u (%s) in record column %d" +msgstr "binäre Daten haben Typ %u (%s) statt erwartet %u (%s) in Record-Spalte %d" + +#: utils/adt/rowtypes.c:641 +#, c-format +msgid "improper binary format in record column %d" +msgstr "falsches Binärformat in Record-Spalte %d" + +#: utils/adt/rowtypes.c:932 utils/adt/rowtypes.c:1178 utils/adt/rowtypes.c:1436 +#: utils/adt/rowtypes.c:1682 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "kann unterschiedliche Spaltentyp %s und %s in Record-Spalte %d nicht vergleichen" + +#: utils/adt/rowtypes.c:1023 utils/adt/rowtypes.c:1248 +#: utils/adt/rowtypes.c:1533 utils/adt/rowtypes.c:1718 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "kann Record-Typen mit unterschiedlicher Anzahl Spalten nicht vergleichen" + +#: utils/adt/ruleutils.c:5069 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "Regel »%s« hat nicht unterstützten Ereignistyp %d" + +#: utils/adt/timestamp.c:109 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "Präzision von TIMESTAMP(%d)%s darf nicht negativ sein" + +#: utils/adt/timestamp.c:115 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "Präzision von TIMESTAMP(%d)%s auf erlaubten Höchstwert %d reduziert" + +#: utils/adt/timestamp.c:178 utils/adt/timestamp.c:436 utils/misc/guc.c:12411 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestamp ist außerhalb des gültigen Bereichs: »%s«" + +#: utils/adt/timestamp.c:374 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "Präzision von timestamp(%d) muss zwischen %d und %d sein" + +#: utils/adt/timestamp.c:498 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "Numerische Zeitzonen müssen »-« oder »+« als erstes Zeichen haben." + +#: utils/adt/timestamp.c:511 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "numerische Zeitzone »%s« ist außerhalb des gültigen Bereichs" + +#: utils/adt/timestamp.c:607 utils/adt/timestamp.c:617 +#: utils/adt/timestamp.c:625 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestamp ist außerhalb des gültigen Bereichs: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:726 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "timestamp kann nicht NaN sein" + +#: utils/adt/timestamp.c:744 utils/adt/timestamp.c:756 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "timestamp ist außerhalb des gültigen Bereichs: »%g«" + +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "ungültiger Modifikator für Typ INTERVAL" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d)-Präzision darf nicht negativ sein" + +#: utils/adt/timestamp.c:1090 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d)-Präzision auf erlaubtes Maximum %d reduziert" + +#: utils/adt/timestamp.c:1472 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "Präzision von interval(%d) muss zwischen %d und %d sein" + +#: utils/adt/timestamp.c:2660 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "kann unendliche timestamp-Werte nicht subtrahieren" + +#: utils/adt/timestamp.c:3837 utils/adt/timestamp.c:4015 +#, fuzzy, c-format +#| msgid "bigint out of range" +msgid "origin out of range" +msgstr "bigint ist außerhalb des gültigen Bereichs" + +#: utils/adt/timestamp.c:3842 utils/adt/timestamp.c:4020 +#, c-format +msgid "timestamps cannot be binned into intervals containing months or years" +msgstr "" + +#: utils/adt/timestamp.c:3973 utils/adt/timestamp.c:4610 +#: utils/adt/timestamp.c:4810 utils/adt/timestamp.c:4857 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "»timestamp«-Einheit »%s« nicht unterstützt" + +#: utils/adt/timestamp.c:3987 utils/adt/timestamp.c:4564 +#: utils/adt/timestamp.c:4867 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "»timestamp«-Einheit »%s« nicht erkannt" + +#: utils/adt/timestamp.c:4161 utils/adt/timestamp.c:4605 +#: utils/adt/timestamp.c:5081 utils/adt/timestamp.c:5129 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "»timestamp with time zone«-Einheit »%s« nicht unterstützt" + +#: utils/adt/timestamp.c:4178 utils/adt/timestamp.c:4559 +#: utils/adt/timestamp.c:5138 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "»timestamp with time zone«-Einheit »%s« nicht erkannt" + +#: utils/adt/timestamp.c:4336 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "»interval«-Einheit »%s« wird nicht unterstützt, weil Monate gewöhnlich partielle Wochen haben" + +#: utils/adt/timestamp.c:4342 utils/adt/timestamp.c:5261 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "»interval«-Einheit »%s« nicht unterstützt" + +#: utils/adt/timestamp.c:4358 utils/adt/timestamp.c:5322 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "»interval«-Einheit »%s« nicht erkannt" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: muss als Trigger aufgerufen werden" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: muss bei UPDATE aufgerufen werden" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: muss vor dem UPDATE aufgerufen werden" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: muss für jede Zeile aufgerufen werden" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_in ist nicht implementiert" + +#: utils/adt/tsquery.c:199 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "Abstand im Phrasenoperator sollte nicht größer als %d sein" + +#: utils/adt/tsquery.c:306 utils/adt/tsquery.c:691 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "Syntaxfehler in tsquery: »%s«" + +#: utils/adt/tsquery.c:330 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "kein Operand in tsquery: »%s«" + +#: utils/adt/tsquery.c:534 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "Wert ist zu groß in tsquery: »%s«" + +#: utils/adt/tsquery.c:539 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "Operator ist zu lang in tsquery: »%s«" + +#: utils/adt/tsquery.c:567 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "Wort ist zu lang in tsquery: »%s«" + +#: utils/adt/tsquery.c:835 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "Textsucheanfrage enthält keine Lexeme: »%s«" + +#: utils/adt/tsquery.c:846 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsquery ist zu groß" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "Textsucheanfrage enthält nur Stoppwörter oder enthält keine Lexeme, ignoriert" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "Abstand im Phrasenoperator sollte nicht negativ und kleiner als %d sein" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "ts_rewrite-Anfrage muss zwei tsquery-Spalten zurückgeben" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "Gewichtungs-Array muss eindimensional sein" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "Gewichtungs-Array ist zu kurz" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "Gewichtungs-Array darf keine NULL-Werte enthalten" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:871 +#, c-format +msgid "weight out of range" +msgstr "Gewichtung ist außerhalb des gültigen Bereichs" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "Wort ist zu lang (%ld Bytes, maximal %ld Bytes)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "Zeichenkette ist zu lang für tsvector (%ld Bytes, maximal %ld Bytes)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "Lexem-Array darf keine NULL-Werte enthalten" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "Gewichtungs-Array darf keine NULL-Werte enthalten" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "unbekannte Gewichtung: »%c«" + +#: utils/adt/tsvector_op.c:2426 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "ts_stat-Anfrage muss eine tsvector-Spalte zurückgeben" + +#: utils/adt/tsvector_op.c:2615 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "tsvector-Spalte »%s« existiert nicht" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "Spalte »%s« hat nicht Typ tsvector" + +#: utils/adt/tsvector_op.c:2634 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "Konfigurationsspalte »%s« existiert nicht" + +#: utils/adt/tsvector_op.c:2640 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "Spalte »%s« hat nicht Typ regconfig" + +#: utils/adt/tsvector_op.c:2647 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "Konfigurationsspalte »%s« darf nicht NULL sein" + +#: utils/adt/tsvector_op.c:2660 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "Textsuchekonfigurationsname »%s« muss Schemaqualifikation haben" + +#: utils/adt/tsvector_op.c:2685 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "Spalte »%s« hat keinen Zeichentyp" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "Syntaxfehler in tsvector: »%s«" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "es gibt kein escaptes Zeichen: »%s«" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "falsche Positionsinformationen in tsvector: »%s«" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "konnte keine Zufallswerte erzeugen" + +#: utils/adt/varbit.c:110 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "Länge von Typ %s muss mindestens 1 sein" + +#: utils/adt/varbit.c:115 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "Länge von Typ %s kann %d nicht überschreiten" + +#: utils/adt/varbit.c:198 utils/adt/varbit.c:499 utils/adt/varbit.c:994 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "Länge der Bitkette überschreitet erlaubtes Maximum (%d)" + +#: utils/adt/varbit.c:212 utils/adt/varbit.c:356 utils/adt/varbit.c:406 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "Länge der Bitkette %d stimmt nicht mit Typ bit(%d) überein" + +#: utils/adt/varbit.c:234 utils/adt/varbit.c:535 +#, c-format +msgid "\"%.*s\" is not a valid binary digit" +msgstr "»%.*s« ist keine gültige Binärziffer" + +#: utils/adt/varbit.c:259 utils/adt/varbit.c:560 +#, c-format +msgid "\"%.*s\" is not a valid hexadecimal digit" +msgstr "»%.*s« ist keine gültige Hexadezimalziffer" + +#: utils/adt/varbit.c:347 utils/adt/varbit.c:652 +#, c-format +msgid "invalid length in external bit string" +msgstr "ungültige Länge in externer Bitkette" + +#: utils/adt/varbit.c:513 utils/adt/varbit.c:661 utils/adt/varbit.c:757 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "Bitkette ist zu lang für Typ bit varying(%d)" + +#: utils/adt/varbit.c:1081 utils/adt/varbit.c:1191 utils/adt/varlena.c:897 +#: utils/adt/varlena.c:960 utils/adt/varlena.c:1117 utils/adt/varlena.c:3351 +#: utils/adt/varlena.c:3429 +#, c-format +msgid "negative substring length not allowed" +msgstr "negative Teilzeichenkettenlänge nicht erlaubt" + +#: utils/adt/varbit.c:1261 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "binäres »Und« nicht mit Bitketten unterschiedlicher Länge möglich" + +#: utils/adt/varbit.c:1302 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "binäres »Oder« nicht mit Bitketten unterschiedlicher Länge möglich" + +#: utils/adt/varbit.c:1342 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "binäres »Exklusiv-Oder« nicht mit Bitketten unterschiedlicher Länge möglich" + +#: utils/adt/varbit.c:1824 utils/adt/varbit.c:1882 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "Bitindex %d ist außerhalb des gültigen Bereichs (0..%d)" + +#: utils/adt/varbit.c:1833 utils/adt/varlena.c:3633 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "neues Bit muss 0 oder 1 sein" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "Wert zu lang für Typ character(%d)" + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "Wert zu lang für Typ character varying(%d)" + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1523 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "konnte die für den Zeichenkettenvergleich zu verwendende Sortierfolge nicht bestimmen" + +#: utils/adt/varlena.c:1216 utils/adt/varlena.c:1963 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "nichtdeterministische Sortierfolgen werden für Teilzeichenkettensuchen nicht unterstützt" + +#: utils/adt/varlena.c:1622 utils/adt/varlena.c:1635 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "konnte Zeichenkette nicht in UTF-16 umwandeln: Fehlercode %lu" + +#: utils/adt/varlena.c:1650 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "konnte Unicode-Zeichenketten nicht vergleichen: %m" + +#: utils/adt/varlena.c:1701 utils/adt/varlena.c:2415 +#, c-format +msgid "collation failed: %s" +msgstr "Vergleichung fehlgeschlagen: %s" + +#: utils/adt/varlena.c:2623 +#, c-format +msgid "sort key generation failed: %s" +msgstr "Sortierschlüsselerzeugung fehlgeschlagen: %s" + +#: utils/adt/varlena.c:3517 utils/adt/varlena.c:3584 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "Index %d ist außerhalb des gültigen Bereichs, 0..%d" + +#: utils/adt/varlena.c:3548 utils/adt/varlena.c:3620 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "Index %lld ist außerhalb des gültigen Bereichs, 0..%lld" + +#: utils/adt/varlena.c:4656 +#, c-format +msgid "field position must not be zero" +msgstr "Feldposition darf nicht null sein" + +#: utils/adt/varlena.c:5697 +#, c-format +msgid "unterminated format() type specifier" +msgstr "Typspezifikation in format() nicht abgeschlossen" + +#: utils/adt/varlena.c:5698 utils/adt/varlena.c:5832 utils/adt/varlena.c:5953 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "Für ein einzelnes »%%« geben Sie »%%%%« an." + +#: utils/adt/varlena.c:5830 utils/adt/varlena.c:5951 +#, c-format +msgid "unrecognized format() type specifier \"%.*s\"" +msgstr "unbekannte Typspezifikation in format(): »%.*s«" + +#: utils/adt/varlena.c:5843 utils/adt/varlena.c:5900 +#, c-format +msgid "too few arguments for format()" +msgstr "zu wenige Argumente für format()" + +#: utils/adt/varlena.c:5996 utils/adt/varlena.c:6178 +#, c-format +msgid "number is out of range" +msgstr "Zahl ist außerhalb des gültigen Bereichs" + +#: utils/adt/varlena.c:6059 utils/adt/varlena.c:6087 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "Format gibt Argument 0 an, aber die Argumente sind von 1 an nummeriert" + +#: utils/adt/varlena.c:6080 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "Argumentposition der Breitenangabe muss mit »$« enden" + +#: utils/adt/varlena.c:6125 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "NULL-Werte können nicht als SQL-Bezeichner formatiert werden" + +#: utils/adt/varlena.c:6251 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "Unicode-Normalisierung kann nur durchgeführt werden, wenn die Serverkodierung UTF8 ist" + +#: utils/adt/varlena.c:6264 +#, c-format +msgid "invalid normalization form: %s" +msgstr "ungültige Normalisierungsform: %s" + +#: utils/adt/varlena.c:6467 utils/adt/varlena.c:6502 utils/adt/varlena.c:6537 +#, c-format +msgid "invalid Unicode code point: %04X" +msgstr "ungültiger Unicode-Codepunkt: %04X" + +#: utils/adt/varlena.c:6567 +#, fuzzy, c-format +#| msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgid "Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX." +msgstr "Unicode-Escapes müssen \\uXXXX oder \\UXXXXXXXX sein." + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "Argument von ntile muss größer als null sein" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "Argument von nth_value muss größer als null sein" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "Transaktions-ID %s ist in der Zukunft" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "ungültige externe pg_snapshot-Daten" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "nicht unterstützte XML-Funktionalität" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Diese Funktionalität verlangt, dass der Server mit Libxml-Unterstützung gebaut wird." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:627 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "ungültiger Kodierungsname »%s«" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "ungültiger XML-Kommentar" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "kein XML-Dokument" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "ungültige XML-Verarbeitungsanweisung" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "Die Zielangabe der XML-Verarbeitungsanweisung darf nicht »%s« sein." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML-Verarbeitungsanweisung darf nicht »?>« enthalten." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "xmlvalidate ist nicht implementiert" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "konnte XML-Bibliothek nicht initialisieren" + +#: utils/adt/xml.c:962 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2 hat inkompatiblen char-Typ: sizeof(char)=%u, sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "konnte XML-Fehlerbehandlung nicht einrichten" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "Das deutet wahrscheinlich darauf hin, dass die verwendete Version von libxml2 nicht mit den Header-Dateien der Version, mit der PostgreSQL gebaut wurde, kompatibel ist." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "Ungültiger Zeichenwert." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "Leerzeichen benötigt." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "standalone akzeptiert nur »yes« oder »no«." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "Fehlerhafte Deklaration: Version fehlt." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "Fehlende Kodierung in Textdeklaration." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "Beim Parsen der XML-Deklaration: »?>« erwartet." + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "Unbekannter Libxml-Fehlercode: %d." + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML unterstützt keine unendlichen Datumswerte." + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML unterstützt keine unendlichen timestamp-Werte." + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "ungültige Anfrage" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "ungültiges Array for XML-Namensraumabbildung" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "Das Array muss zweidimensional sein und die Länge der zweiten Achse muss gleich 2 sein." + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "leerer XPath-Ausdruck" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "weder Namensraumname noch URI dürfen NULL sein" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "konnte XML-Namensraum mit Namen »%s« und URI »%s« nicht registrieren" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "DEFAULT-Namensraum wird nicht unterstützt" + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "Zeilenpfadfilter darf nicht leer sein" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "Spaltenpfadfilter darf nicht leer sein" + +#: utils/adt/xml.c:4655 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "XPath-Ausdruck für Spalte gab mehr als einen Wert zurück" + +#: utils/cache/lsyscache.c:1042 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "Typumwandlung von Typ %s in Typ %s existiert nicht" + +#: utils/cache/lsyscache.c:2834 utils/cache/lsyscache.c:2867 +#: utils/cache/lsyscache.c:2900 utils/cache/lsyscache.c:2933 +#, c-format +msgid "type %s is only a shell" +msgstr "Typ %s ist nur eine Hülle" + +#: utils/cache/lsyscache.c:2839 +#, c-format +msgid "no input function available for type %s" +msgstr "keine Eingabefunktion verfügbar für Typ %s" + +#: utils/cache/lsyscache.c:2872 +#, c-format +msgid "no output function available for type %s" +msgstr "keine Ausgabefunktion verfügbar für Typ %s" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d für Typ %s" + +#: utils/cache/plancache.c:720 +#, c-format +msgid "cached plan must not change result type" +msgstr "gecachter Plan darf den Ergebnistyp nicht ändern" + +#: utils/cache/relcache.c:6213 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "konnte Initialisierungsdatei für Relationscache »%s« nicht erzeugen: %m" + +#: utils/cache/relcache.c:6215 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Setze trotzdem fort, aber irgendwas stimmt nicht." + +#: utils/cache/relcache.c:6537 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "konnte Cache-Datei »%s« nicht löschen: %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "PREPARE kann nicht in einer Transaktion ausgeführt werden, die das Relation-Mapping geändert hat" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "Relation-Mapping-Datei »%s« enthält ungültige Daten" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "Relation-Mapping-Datei »%s« enthält falsche Prüfsumme" + +#: utils/cache/typcache.c:1808 utils/fmgr/funcapi.c:463 +#, c-format +msgid "record type has not been registered" +msgstr "Record-Typ wurde nicht registriert" + +#: utils/error/assert.c:39 +#, fuzzy, c-format +#| msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgid "TRAP: ExceptionalCondition: bad arguments in PID %d\n" +msgstr "TRAP: ExceptionalCondition: fehlerhafte Argumente\n" + +#: utils/error/assert.c:42 +#, fuzzy, c-format +#| msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d, PID: %d)\n" +msgstr "TRAP: %s(»%s«, Datei: »%s«, Zeile: %d)\n" + +#: utils/error/elog.c:409 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "Fehler geschah bevor Fehlermeldungsverarbeitung bereit war\n" + +#: utils/error/elog.c:1948 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "konnte Datei »%s« nicht als stderr neu öffnen: %m" + +#: utils/error/elog.c:1961 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "konnte Datei »%s« nicht als stdout neu öffnen: %m" + +#: utils/error/elog.c:2456 utils/error/elog.c:2490 utils/error/elog.c:2506 +msgid "[unknown]" +msgstr "[unbekannt]" + +#: utils/error/elog.c:3026 utils/error/elog.c:3344 utils/error/elog.c:3451 +msgid "missing error text" +msgstr "fehlender Fehlertext" + +#: utils/error/elog.c:3029 utils/error/elog.c:3032 +#, c-format +msgid " at character %d" +msgstr " bei Zeichen %d" + +#: utils/error/elog.c:3042 utils/error/elog.c:3049 +msgid "DETAIL: " +msgstr "DETAIL: " + +#: utils/error/elog.c:3056 +msgid "HINT: " +msgstr "TIPP: " + +#: utils/error/elog.c:3063 +msgid "QUERY: " +msgstr "ANFRAGE: " + +#: utils/error/elog.c:3070 +msgid "CONTEXT: " +msgstr "ZUSAMMENHANG: " + +#: utils/error/elog.c:3080 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "ORT: %s, %s:%d\n" + +#: utils/error/elog.c:3087 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "ORT: %s:%d\n" + +#: utils/error/elog.c:3094 +msgid "BACKTRACE: " +msgstr "BACKTRACE: " + +#: utils/error/elog.c:3108 +msgid "STATEMENT: " +msgstr "ANWEISUNG: " + +#: utils/error/elog.c:3496 +msgid "DEBUG" +msgstr "DEBUG" + +#: utils/error/elog.c:3500 +msgid "LOG" +msgstr "LOG" + +#: utils/error/elog.c:3503 +msgid "INFO" +msgstr "INFO" + +#: utils/error/elog.c:3506 +msgid "NOTICE" +msgstr "HINWEIS" + +#: utils/error/elog.c:3510 +msgid "WARNING" +msgstr "WARNUNG" + +#: utils/error/elog.c:3513 +msgid "ERROR" +msgstr "FEHLER" + +#: utils/error/elog.c:3516 +msgid "FATAL" +msgstr "FATAL" + +#: utils/error/elog.c:3519 +msgid "PANIC" +msgstr "PANIK" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "konnte Funktion »%s« nicht in Datei »%s« finden" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "konnte Bibliothek »%s« nicht laden: %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "inkompatible Bibliothek »%s«: magischer Block fehlt" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "Erweiterungsbibliotheken müssen das Makro PG_MODULE_MAGIC verwenden." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "inkompatible Bibliothek »%s«: Version stimmt nicht überein" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "Serverversion ist %d, Bibliotheksversion ist %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "Server hat FUNC_MAX_ARGS = %d, Bibliothek hat %d." + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "Server hat INDEX_MAX_KEYS = %d, Bibliothek hat %d." + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "Server hat NAMEDATALEN = %d, Bibliothek hat %d." + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "Server hat FLOAT8PASSBYVAL = %s, Bibliothek hat %s." + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "Magischer Block hat unerwartete Länge oder unterschiedliches Padding." + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "inkompatible Bibliothek »%s«: magischer Block stimmt überein" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "Zugriff auf Bibliothek »%s« ist nicht erlaubt" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "ungültiger Makroname in Parameter »dynamic_library_path«: %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "eine Komponente im Parameter »dynamic_library_path« hat Länge null" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "eine Komponente im Parameter »dynamic_library_path« ist kein absoluter Pfad" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "interne Funktion »%s« ist nicht in der internen Suchtabelle" + +#: utils/fmgr/fmgr.c:484 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "konnte Funktionsinformationen für Funktion »%s« nicht finden" + +#: utils/fmgr/fmgr.c:486 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "Von SQL aufrufbare Funktionen benötigen ein begleitendes PG_FUNCTION_INFO_V1(funkname)." + +#: utils/fmgr/fmgr.c:504 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "Info-Funktion »%2$s« berichtete unbekannte API-Version %1$d" + +#: utils/fmgr/fmgr.c:1999 +#, c-format +msgid "operator class options info is absent in function call context" +msgstr "Operatorklassenoptionsinformationen fehlen im Funktionsaufrufkontext" + +#: utils/fmgr/fmgr.c:2066 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "Sprachvalidierungsfunktion %u wurde für Sprache %u statt %u aufgerufen" + +#: utils/fmgr/funcapi.c:386 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "konnte tatsächlichen Ergebnistyp von Funktion »%s« mit deklarierten Rückgabetyp %s nicht bestimmen" + +#: utils/fmgr/funcapi.c:531 +#, fuzzy, c-format +#| msgid "argument declared %s is not a range type but type %s" +msgid "argument declared %s does not contain a range type but type %s" +msgstr "als %s deklariertes Argument ist kein Bereichstyp sondern Typ %s" + +#: utils/fmgr/funcapi.c:1833 utils/fmgr/funcapi.c:1865 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "Anzahl der Aliasnamen stimmt nicht mit der Anzahl der Spalten überein" + +#: utils/fmgr/funcapi.c:1859 +#, c-format +msgid "no column alias was provided" +msgstr "Spaltenalias fehlt" + +#: utils/fmgr/funcapi.c:1883 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "konnte Zeilenbeschreibung für Funktion, die »record« zurückgibt, nicht ermitteln" + +#: utils/init/miscinit.c:315 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "Datenverzeichnis »%s« existiert nicht" + +#: utils/init/miscinit.c:320 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" + +#: utils/init/miscinit.c:328 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "angegebenes Datenverzeichnis »%s« ist kein Verzeichnis" + +#: utils/init/miscinit.c:344 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "Datenverzeichnis »%s« hat falschen Eigentümer" + +#: utils/init/miscinit.c:346 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "Der Server muss von dem Benutzer gestartet werden, dem das Datenverzeichnis gehört." + +#: utils/init/miscinit.c:364 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "Datenverzeichnis »%s« hat ungültige Zugriffsrechte" + +#: utils/init/miscinit.c:366 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Rechte sollten u=rwx (0700) oder u=rwx,g=rx (0750) sein." + +#: utils/init/miscinit.c:645 utils/misc/guc.c:7481 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "kann Parameter »%s« nicht in einer sicherheitsbeschränkten Operation setzen" + +#: utils/init/miscinit.c:713 +#, c-format +msgid "role with OID %u does not exist" +msgstr "Rolle mit OID %u existiert nicht" + +#: utils/init/miscinit.c:743 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "Rolle »%s« hat keine Berechtigung zum Einloggen" + +#: utils/init/miscinit.c:761 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "zu viele Verbindungen von Rolle »%s«" + +#: utils/init/miscinit.c:821 +#, c-format +msgid "permission denied to set session authorization" +msgstr "keine Berechtigung, um Sitzungsautorisierung zu setzen" + +#: utils/init/miscinit.c:904 +#, c-format +msgid "invalid role OID: %u" +msgstr "ungültige Rollen-OID: %u" + +#: utils/init/miscinit.c:958 +#, c-format +msgid "database system is shut down" +msgstr "Datenbanksystem ist heruntergefahren" + +#: utils/init/miscinit.c:1045 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "konnte Sperrdatei »%s« nicht erstellen: %m" + +#: utils/init/miscinit.c:1059 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "konnte Sperrdatei »%s« nicht öffnen: %m" + +#: utils/init/miscinit.c:1066 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "konnte Sperrdatei »%s« nicht lesen: %m" + +#: utils/init/miscinit.c:1075 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "Sperrdatei »%s« ist leer" + +#: utils/init/miscinit.c:1076 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "Entweder startet gerade ein anderer Server oder die Sperrdatei ist von einen Absturz übrig geblieben." + +#: utils/init/miscinit.c:1120 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "Sperrdatei »%s« existiert bereits" + +#: utils/init/miscinit.c:1124 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "Läuft bereits ein anderer postgres-Prozess (PID %d) im Datenverzeichnis »%s«?" + +#: utils/init/miscinit.c:1126 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "Läuft bereits ein anderer postmaster-Prozess (PID %d) im Datenverzeichnis »%s«?" + +#: utils/init/miscinit.c:1129 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "Verwendet bereits ein anderer postgres-Prozess (PID %d) die Socketdatei »%s«?" + +#: utils/init/miscinit.c:1131 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "Verwendet bereits ein anderer postmaster-Prozess (PID %d) die Socketdatei »%s«?" + +#: utils/init/miscinit.c:1182 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "konnte alte Sperrdatei »%s« nicht löschen: %m" + +#: utils/init/miscinit.c:1184 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "Die Datei ist anscheinend aus Versehen übrig geblieben, konnte aber nicht gelöscht werden. Bitte entfernen Sie die Datei von Hand und versuchen Sie es erneut." + +#: utils/init/miscinit.c:1221 utils/init/miscinit.c:1235 +#: utils/init/miscinit.c:1246 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "konnte Sperrdatei »%s« nicht schreiben: %m" + +#: utils/init/miscinit.c:1357 utils/init/miscinit.c:1499 utils/misc/guc.c:10377 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "konnte nicht aus Datei »%s« lesen: %m" + +#: utils/init/miscinit.c:1487 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "konnte Datei »%s« nicht öffnen: %m; setze trotzdem fort" + +#: utils/init/miscinit.c:1512 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "Sperrdatei »%s« enthält falsche PID: %ld statt %ld" + +#: utils/init/miscinit.c:1551 utils/init/miscinit.c:1567 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "»%s« ist kein gültiges Datenverzeichnis" + +#: utils/init/miscinit.c:1553 +#, c-format +msgid "File \"%s\" is missing." +msgstr "Die Datei »%s« fehlt." + +#: utils/init/miscinit.c:1569 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "Die Datei »%s« enthält keine gültigen Daten." + +#: utils/init/miscinit.c:1571 +#, c-format +msgid "You might need to initdb." +msgstr "Sie müssen möglicherweise initdb ausführen." + +#: utils/init/miscinit.c:1579 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "Das Datenverzeichnis wurde von PostgreSQL Version %s initialisiert, welche nicht mit dieser Version %s kompatibel ist." + +#: utils/init/postinit.c:254 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "Replikationsverbindung autorisiert: Benutzer=%s" + +#: utils/init/postinit.c:257 +#, c-format +msgid "connection authorized: user=%s" +msgstr "Verbindung autorisiert: Benutzer=%s" + +#: utils/init/postinit.c:260 +#, c-format +msgid " database=%s" +msgstr " Datenbank=%s" + +#: utils/init/postinit.c:263 +#, c-format +msgid " application_name=%s" +msgstr " application_name=%s" + +#: utils/init/postinit.c:268 +#, c-format +msgid " SSL enabled (protocol=%s, cipher=%s, bits=%d)" +msgstr "SSL an (Protokoll=%s, Verschlüsselungsmethode=%s, Bits=%d)" + +#: utils/init/postinit.c:280 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s, principal=%s)" +msgstr " GSS (authentifiziert=%s, verschlüsselt=%s, Principal=%s)" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 +#: utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "no" +msgstr "nein" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 +#: utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "yes" +msgstr "ja" + +#: utils/init/postinit.c:286 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s)" +msgstr " GSS (authentifiziert=%s, verschlüsselt=%s)" + +#: utils/init/postinit.c:323 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "Datenbank »%s« ist aus pg_database verschwunden" + +#: utils/init/postinit.c:325 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "Datenbank-OID %u gehört jetzt anscheinend zu »%s«." + +#: utils/init/postinit.c:345 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "Datenbank »%s« akzeptiert gegenwärtig keine Verbindungen" + +#: utils/init/postinit.c:358 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "keine Berechtigung für Datenbank »%s«" + +#: utils/init/postinit.c:359 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "Benutzer hat das CONNECT-Privileg nicht." + +#: utils/init/postinit.c:376 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "zu viele Verbindungen für Datenbank »%s«" + +#: utils/init/postinit.c:398 utils/init/postinit.c:405 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "Datenbank-Locale ist inkompatibel mit Betriebssystem" + +#: utils/init/postinit.c:399 +#, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "Die Datenbank wurde mit LC_COLLATE »%s« initialisiert, was von setlocale() nicht erkannt wird." + +#: utils/init/postinit.c:401 utils/init/postinit.c:408 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "Erzeugen Sie die Datenbank neu mit einer anderen Locale oder installieren Sie die fehlende Locale." + +#: utils/init/postinit.c:406 +#, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "Die Datenbank wurde mit LC_CTYPE »%s« initialisiert, was von setlocale() nicht erkannt wird." + +#: utils/init/postinit.c:761 +#, c-format +msgid "no roles are defined in this database system" +msgstr "in diesem Datenbanksystem sind keine Rollen definiert" + +#: utils/init/postinit.c:762 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Sie sollten sofort CREATE USER \"%s\" SUPERUSER; ausführen." + +#: utils/init/postinit.c:798 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "während des Herunterfahrens der Datenbank sind keine neuen Replikationsverbindungen erlaubt" + +#: utils/init/postinit.c:802 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "nur Superuser können während des Herunterfahrens der Datenbank verbinden" + +#: utils/init/postinit.c:812 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "nur Superuser können im Binary-Upgrade-Modus verbinden" + +#: utils/init/postinit.c:825 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "die verbleibenden Verbindungen sind für Superuser auf Nicht-Replikationsverbindungen reserviert" + +#: utils/init/postinit.c:835 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "nur Superuser und Replikationsrollen können WAL-Sender starten" + +#: utils/init/postinit.c:904 +#, c-format +msgid "database %u does not exist" +msgstr "Datenbank %u existiert nicht" + +#: utils/init/postinit.c:993 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Sie wurde anscheinend gerade gelöscht oder umbenannt." + +#: utils/init/postinit.c:1011 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Das Datenbankunterverzeichnis »%s« fehlt." + +#: utils/init/postinit.c:1016 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" + +#: utils/mb/conv.c:522 utils/mb/conv.c:733 +#, c-format +msgid "invalid encoding number: %d" +msgstr "ungültige Kodierungsnummer: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:129 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:165 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "unerwartete Kodierungs-ID %d für ISO-8859-Zeichensatz" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:110 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:146 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "unerwartete Kodierungs-ID %d für WIN-Zeichensatz" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:900 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "Umwandlung zwischen %s und %s wird nicht unterstützt" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "Standardumwandlung von Kodierung »%s« nach »%s« existiert nicht" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:430 utils/mb/mbutils.c:815 +#: utils/mb/mbutils.c:842 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "Zeichenkette mit %d Bytes ist zu lang für Kodierungsumwandlung." + +#: utils/mb/mbutils.c:568 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "ungültiger Quellkodierungsname »%s«" + +#: utils/mb/mbutils.c:573 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "ungültiger Zielkodierungsname »%s«" + +#: utils/mb/mbutils.c:713 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "ungültiger Byte-Wert für Kodierung »%s«: 0x%02x" + +#: utils/mb/mbutils.c:877 +#, c-format +msgid "invalid Unicode code point" +msgstr "ungültiger Unicode-Codepunkt" + +#: utils/mb/mbutils.c:1146 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codeset fehlgeschlagen" + +#: utils/mb/mbutils.c:1667 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "ungültige Byte-Sequenz für Kodierung »%s«: %s" + +#: utils/mb/mbutils.c:1700 +#, c-format +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "Zeichen mit Byte-Folge %s in Kodierung »%s« hat keine Entsprechung in Kodierung »%s«" + +#: utils/misc/guc.c:718 +msgid "Ungrouped" +msgstr "Ungruppiert" + +#: utils/misc/guc.c:720 +msgid "File Locations" +msgstr "Dateipfade" + +#: utils/misc/guc.c:722 +msgid "Connections and Authentication / Connection Settings" +msgstr "Verbindungen und Authentifizierung / Verbindungseinstellungen" + +#: utils/misc/guc.c:724 +msgid "Connections and Authentication / Authentication" +msgstr "Verbindungen und Authentifizierung / Authentifizierung" + +#: utils/misc/guc.c:726 +msgid "Connections and Authentication / SSL" +msgstr "Verbindungen und Authentifizierung / SSL" + +#: utils/misc/guc.c:728 +msgid "Resource Usage / Memory" +msgstr "Resourcenbenutzung / Speicher" + +#: utils/misc/guc.c:730 +msgid "Resource Usage / Disk" +msgstr "Resourcenbenutzung / Festplatte" + +#: utils/misc/guc.c:732 +msgid "Resource Usage / Kernel Resources" +msgstr "Resourcenbenutzung / Kernelresourcen" + +#: utils/misc/guc.c:734 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Resourcenbenutzung / Kostenbasierte Vacuum-Verzögerung" + +#: utils/misc/guc.c:736 +msgid "Resource Usage / Background Writer" +msgstr "Resourcenbenutzung / Background-Writer" + +#: utils/misc/guc.c:738 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Resourcenbenutzung / Asynchrones Verhalten" + +#: utils/misc/guc.c:740 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead-Log / Einstellungen" + +#: utils/misc/guc.c:742 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead-Log / Checkpoints" + +#: utils/misc/guc.c:744 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead-Log / Archivierung" + +#: utils/misc/guc.c:746 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead-Log / Archivwiederherstellung" + +#: utils/misc/guc.c:748 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead-Log / Wiederherstellungsziele" + +#: utils/misc/guc.c:750 +msgid "Replication / Sending Servers" +msgstr "Replikation / sendende Server" + +#: utils/misc/guc.c:752 +msgid "Replication / Primary Server" +msgstr "Replikation / Primärserver" + +#: utils/misc/guc.c:754 +msgid "Replication / Standby Servers" +msgstr "Replikation / Standby-Server" + +#: utils/misc/guc.c:756 +msgid "Replication / Subscribers" +msgstr "Replikation / Subskriptionsserver" + +#: utils/misc/guc.c:758 +msgid "Query Tuning / Planner Method Configuration" +msgstr "Anfragetuning / Planermethoden" + +#: utils/misc/guc.c:760 +msgid "Query Tuning / Planner Cost Constants" +msgstr "Anfragetuning / Planerkosten" + +#: utils/misc/guc.c:762 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "Anfragetuning / Genetischer Anfrageoptimierer" + +#: utils/misc/guc.c:764 +msgid "Query Tuning / Other Planner Options" +msgstr "Anfragetuning / Andere Planeroptionen" + +#: utils/misc/guc.c:766 +msgid "Reporting and Logging / Where to Log" +msgstr "Berichte und Logging / Wohin geloggt wird" + +#: utils/misc/guc.c:768 +msgid "Reporting and Logging / When to Log" +msgstr "Berichte und Logging / Wann geloggt wird" + +#: utils/misc/guc.c:770 +msgid "Reporting and Logging / What to Log" +msgstr "Berichte und Logging / Was geloggt wird" + +#: utils/misc/guc.c:772 +msgid "Reporting and Logging / Process Title" +msgstr "Berichte und Logging / Prozesstitel" + +#: utils/misc/guc.c:774 +msgid "Statistics / Monitoring" +msgstr "Statistiken / Überwachung" + +#: utils/misc/guc.c:776 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "Statistiken / Statistiksammler für Anfragen und Indexe" + +#: utils/misc/guc.c:778 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:780 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "Standardeinstellungen für Clientverbindungen / Anweisungsverhalten" + +#: utils/misc/guc.c:782 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "Standardeinstellungen für Clientverbindungen / Locale und Formatierung" + +#: utils/misc/guc.c:784 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "Standardeinstellungen für Clientverbindungen / Shared Library Preloading" + +#: utils/misc/guc.c:786 +msgid "Client Connection Defaults / Other Defaults" +msgstr "Standardeinstellungen für Clientverbindungen / Andere" + +#: utils/misc/guc.c:788 +msgid "Lock Management" +msgstr "Sperrenverwaltung" + +#: utils/misc/guc.c:790 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Versions- und Plattformkompatibilität / Frühere PostgreSQL-Versionen" + +#: utils/misc/guc.c:792 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Versions- und Plattformkompatibilität / Andere Plattformen und Clients" + +#: utils/misc/guc.c:794 +msgid "Error Handling" +msgstr "Fehlerbehandlung" + +#: utils/misc/guc.c:796 +msgid "Preset Options" +msgstr "Voreingestellte Optionen" + +#: utils/misc/guc.c:798 +msgid "Customized Options" +msgstr "Angepasste Optionen" + +#: utils/misc/guc.c:800 +msgid "Developer Options" +msgstr "Entwickleroptionen" + +#: utils/misc/guc.c:858 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Gültige Einheiten für diesen Parameter sind »B«, »kB«, »MB«, »GB« und »TB«." + +#: utils/misc/guc.c:895 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Gültige Einheiten für diesen Parameter sind »us«, »ms«, »s«, »min«, »h« und »d«." + +#: utils/misc/guc.c:957 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "Ermöglicht sequenzielle Scans in Planer." + +#: utils/misc/guc.c:967 +msgid "Enables the planner's use of index-scan plans." +msgstr "Ermöglicht Index-Scans im Planer." + +#: utils/misc/guc.c:977 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Ermöglicht Index-Only-Scans im Planer." + +#: utils/misc/guc.c:987 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "Ermöglicht Bitmap-Scans im Planer." + +#: utils/misc/guc.c:997 +msgid "Enables the planner's use of TID scan plans." +msgstr "Ermöglicht TID-Scans im Planer." + +#: utils/misc/guc.c:1007 +msgid "Enables the planner's use of explicit sort steps." +msgstr "Ermöglicht Sortierschritte im Planer." + +#: utils/misc/guc.c:1017 +msgid "Enables the planner's use of incremental sort steps." +msgstr "Ermöglicht inkrementelle Sortierschritte im Planer." + +#: utils/misc/guc.c:1026 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Ermöglicht Hash-Aggregierung im Planer." + +#: utils/misc/guc.c:1036 +msgid "Enables the planner's use of materialization." +msgstr "Ermöglicht Materialisierung im Planer." + +#: utils/misc/guc.c:1046 +#, fuzzy +#| msgid "Enables the planner's use of parallel hash plans." +msgid "Enables the planner's use of result caching." +msgstr "Ermöglicht parallele Hash-Pläne im Planer." + +#: utils/misc/guc.c:1056 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "Ermöglicht Nested-Loop-Verbunde im Planer." + +#: utils/misc/guc.c:1066 +msgid "Enables the planner's use of merge join plans." +msgstr "Ermöglicht Merge-Verbunde im Planer." + +#: utils/misc/guc.c:1076 +msgid "Enables the planner's use of hash join plans." +msgstr "Ermöglicht Hash-Verbunde im Planer." + +#: utils/misc/guc.c:1086 +msgid "Enables the planner's use of gather merge plans." +msgstr "Ermöglicht Gather-Merge-Pläne im Planer." + +#: utils/misc/guc.c:1096 +msgid "Enables partitionwise join." +msgstr "Ermöglicht partitionsweise Verbunde." + +#: utils/misc/guc.c:1106 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Ermöglicht partitionsweise Aggregierung und Gruppierung." + +#: utils/misc/guc.c:1116 +msgid "Enables the planner's use of parallel append plans." +msgstr "Ermöglicht parallele Append-Pläne im Planer." + +#: utils/misc/guc.c:1126 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Ermöglicht parallele Hash-Pläne im Planer." + +#: utils/misc/guc.c:1136 +msgid "Enables plan-time and execution-time partition pruning." +msgstr "Ermöglicht Partition-Pruning zur Planzeit und zur Ausführungszeit." + +#: utils/misc/guc.c:1137 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Erlaubt es dem Planer und dem Executor, Partitionsbegrenzungen mit Bedingungen in der Anfrage zu vergleichen, um festzustellen, welche Partitionen gelesen werden müssen." + +#: utils/misc/guc.c:1148 +#, fuzzy +#| msgid "Enables the planner's use of parallel append plans." +msgid "Enables the planner's use of async append plans." +msgstr "Ermöglicht parallele Append-Pläne im Planer." + +#: utils/misc/guc.c:1158 +msgid "Enables genetic query optimization." +msgstr "Ermöglicht genetische Anfrageoptimierung." + +#: utils/misc/guc.c:1159 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Dieser Algorithmus versucht das Planen ohne erschöpfende Suche durchzuführen." + +#: utils/misc/guc.c:1170 +msgid "Shows whether the current user is a superuser." +msgstr "Zeigt, ob der aktuelle Benutzer ein Superuser ist." + +#: utils/misc/guc.c:1180 +msgid "Enables advertising the server via Bonjour." +msgstr "Ermöglicht die Bekanntgabe des Servers mit Bonjour." + +#: utils/misc/guc.c:1189 +msgid "Collects transaction commit time." +msgstr "Sammelt Commit-Timestamps von Transaktionen." + +#: utils/misc/guc.c:1198 +msgid "Enables SSL connections." +msgstr "Ermöglicht SSL-Verbindungen." + +#: utils/misc/guc.c:1207 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "ssl_passphrase_command auch beim Neuladen des Servers verwenden." + +#: utils/misc/guc.c:1216 +msgid "Give priority to server ciphersuite order." +msgstr "Der Ciphersuite-Reihenfolge des Servers Vorrang geben." + +#: utils/misc/guc.c:1225 +msgid "Forces synchronization of updates to disk." +msgstr "Erzwingt die Synchronisierung von Aktualisierungen auf Festplatte." + +#: utils/misc/guc.c:1226 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "Der Server verwendet den Systemaufruf fsync() an mehreren Stellen, um sicherzustellen, dass Datenänderungen physikalisch auf die Festplatte geschrieben werden. Das stellt sicher, dass der Datenbankcluster nach einem Betriebssystemabsturz oder Hardwarefehler in einem korrekten Zustand wiederhergestellt werden kann." + +#: utils/misc/guc.c:1237 +msgid "Continues processing after a checksum failure." +msgstr "Setzt die Verarbeitung trotz Prüfsummenfehler fort." + +#: utils/misc/guc.c:1238 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "Wenn eine fehlerhafte Prüfsumme entdeckt wird, gibt PostgreSQL normalerweise ein Fehler aus und bricht die aktuelle Transaktion ab. Wenn »ignore_checksum_failure« an ist, dann wird der Fehler ignoriert (aber trotzdem eine Warnung ausgegeben) und die Verarbeitung geht weiter. Dieses Verhalten kann Abstürze und andere ernsthafte Probleme verursachen. Es hat keine Auswirkungen, wenn Prüfsummen nicht eingeschaltet sind." + +#: utils/misc/guc.c:1252 +msgid "Continues processing past damaged page headers." +msgstr "Setzt die Verarbeitung trotz kaputter Seitenköpfe fort." + +#: utils/misc/guc.c:1253 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "Wenn ein kaputter Seitenkopf entdeckt wird, gibt PostgreSQL normalerweise einen Fehler aus und bricht die aktuelle Transaktion ab. Wenn »zero_damaged_pages« an ist, dann wird eine Warnung ausgegeben, die kaputte Seite mit Nullen gefüllt und die Verarbeitung geht weiter. Dieses Verhalten zerstört Daten, nämlich alle Zeilen in der kaputten Seite." + +#: utils/misc/guc.c:1266 +msgid "Continues recovery after an invalid pages failure." +msgstr "Setzt die Wiederherstellung trotz Fehler durch ungültige Seiten fort." + +#: utils/misc/guc.c:1267 +msgid "Detection of WAL records having references to invalid pages during recovery causes PostgreSQL to raise a PANIC-level error, aborting the recovery. Setting ignore_invalid_pages to true causes the system to ignore invalid page references in WAL records (but still report a warning), and continue recovery. This behavior may cause crashes, data loss, propagate or hide corruption, or other serious problems. Only has an effect during recovery or in standby mode." +msgstr "Wenn WAL-Einträge mit Verweisen auf ungültige Seiten bei der Wiederherstellung erkannt werden, verursacht das einen PANIC-Fehler, wodurch die Wiederherstellung abgebrochen wird. Wenn »ignore_invalid_pages« an ist, dann werden ungültige Seitenverweise in WAL-Einträgen ignoriert (aber trotzen eine Warnung ausgegeben) und die Wiederherstellung wird fortgesetzt. Dieses Verhalten kann Abstürze und Datenverlust verursachen, Datenverfälschung verbreiten oder verstecken sowie andere ernsthafte Probleme verursachen. Es hat nur Auswirkungen im Wiederherstellungs- oder Standby-Modus." + +#: utils/misc/guc.c:1285 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "Schreibt volle Seiten in den WAL, sobald sie nach einem Checkpoint geändert werden." + +#: utils/misc/guc.c:1286 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "Ein Seitenschreibvorgang während eines Betriebssystemabsturzes könnte eventuell nur teilweise geschrieben worden sein. Bei der Wiederherstellung sind die im WAL gespeicherten Zeilenänderungen nicht ausreichend. Diese Option schreibt Seiten, sobald sie nach einem Checkpoint geändert worden sind, damit eine volle Wiederherstellung möglich ist." + +#: utils/misc/guc.c:1299 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification." +msgstr "Schreibt volle Seiten in den WAL, sobald sie nach einem Checkpoint geändert werden, auch für eine nicht kritische Änderung." + +#: utils/misc/guc.c:1309 +msgid "Compresses full-page writes written in WAL file." +msgstr "Komprimiert in WAL-Dateien geschriebene volle Seiten." + +#: utils/misc/guc.c:1319 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Schreibt Nullen in neue WAL-Dateien vor der ersten Verwendung." + +#: utils/misc/guc.c:1329 +msgid "Recycles WAL files by renaming them." +msgstr "WAL-Dateien werden durch Umbenennen wiederverwendet." + +#: utils/misc/guc.c:1339 +msgid "Logs each checkpoint." +msgstr "Schreibt jeden Checkpoint in den Log." + +#: utils/misc/guc.c:1348 +msgid "Logs each successful connection." +msgstr "Schreibt jede erfolgreiche Verbindung in den Log." + +#: utils/misc/guc.c:1357 +msgid "Logs end of a session, including duration." +msgstr "Schreibt jedes Verbindungsende mit Sitzungszeit in den Log." + +#: utils/misc/guc.c:1366 +msgid "Logs each replication command." +msgstr "Schreibt jeden Replikationsbefehl in den Log." + +#: utils/misc/guc.c:1375 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Zeigt, ob der laufende Server Assertion-Prüfungen aktiviert hat." + +#: utils/misc/guc.c:1390 +msgid "Terminate session on any error." +msgstr "Sitzung bei jedem Fehler abbrechen." + +#: utils/misc/guc.c:1399 +msgid "Reinitialize server after backend crash." +msgstr "Server nach Absturz eines Serverprozesses reinitialisieren." + +#: utils/misc/guc.c:1408 +#, fuzzy +#| msgid "Reinitialize server after backend crash." +msgid "Remove temporary files after backend crash." +msgstr "Server nach Absturz eines Serverprozesses reinitialisieren." + +#: utils/misc/guc.c:1418 +msgid "Logs the duration of each completed SQL statement." +msgstr "Loggt die Dauer jeder abgeschlossenen SQL-Anweisung." + +#: utils/misc/guc.c:1427 +msgid "Logs each query's parse tree." +msgstr "Scheibt den Parsebaum jeder Anfrage in den Log." + +#: utils/misc/guc.c:1436 +msgid "Logs each query's rewritten parse tree." +msgstr "Schreibt den umgeschriebenen Parsebaum jeder Anfrage in den Log." + +#: utils/misc/guc.c:1445 +msgid "Logs each query's execution plan." +msgstr "Schreibt den Ausführungsplan jeder Anfrage in den Log." + +#: utils/misc/guc.c:1454 +msgid "Indents parse and plan tree displays." +msgstr "Rückt die Anzeige von Parse- und Planbäumen ein." + +#: utils/misc/guc.c:1463 +msgid "Writes parser performance statistics to the server log." +msgstr "Schreibt Parser-Leistungsstatistiken in den Serverlog." + +#: utils/misc/guc.c:1472 +msgid "Writes planner performance statistics to the server log." +msgstr "Schreibt Planer-Leistungsstatistiken in den Serverlog." + +#: utils/misc/guc.c:1481 +msgid "Writes executor performance statistics to the server log." +msgstr "Schreibt Executor-Leistungsstatistiken in den Serverlog." + +#: utils/misc/guc.c:1490 +msgid "Writes cumulative performance statistics to the server log." +msgstr "Schreibt Gesamtleistungsstatistiken in den Serverlog." + +#: utils/misc/guc.c:1500 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "Loggt Statistiken über Systemressourcen (Speicher und CPU) während diverser B-Baum-Operationen." + +#: utils/misc/guc.c:1512 +msgid "Collects information about executing commands." +msgstr "Sammelt Informationen über ausgeführte Befehle." + +#: utils/misc/guc.c:1513 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "Schaltet die Sammlung von Informationen über den aktuell ausgeführten Befehl jeder Sitzung ein, einschließlich der Zeit, and dem die Befehlsausführung begann." + +#: utils/misc/guc.c:1523 +msgid "Collects statistics on database activity." +msgstr "Sammelt Statistiken über Datenbankaktivität." + +#: utils/misc/guc.c:1532 +msgid "Collects timing statistics for database I/O activity." +msgstr "Sammelt Zeitmessungsstatistiken über Datenbank-I/O-Aktivität." + +#: utils/misc/guc.c:1541 +#, fuzzy +#| msgid "Collects timing statistics for database I/O activity." +msgid "Collects timing statistics for WAL I/O activity." +msgstr "Sammelt Zeitmessungsstatistiken über Datenbank-I/O-Aktivität." + +#: utils/misc/guc.c:1551 +msgid "Updates the process title to show the active SQL command." +msgstr "Der Prozesstitel wird aktualisiert, um den aktuellen SQL-Befehl anzuzeigen." + +#: utils/misc/guc.c:1552 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "Ermöglicht das Aktualisieren des Prozesstitels bei jedem von Server empfangenen neuen SQL-Befehl." + +#: utils/misc/guc.c:1565 +msgid "Starts the autovacuum subprocess." +msgstr "Startet den Autovacuum-Prozess." + +#: utils/misc/guc.c:1575 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "Erzeugt Debug-Ausgabe für LISTEN und NOTIFY." + +#: utils/misc/guc.c:1587 +msgid "Emits information about lock usage." +msgstr "Gibt Informationen über Sperrenverwendung aus." + +#: utils/misc/guc.c:1597 +msgid "Emits information about user lock usage." +msgstr "Gibt Informationen über Benutzersperrenverwendung aus." + +#: utils/misc/guc.c:1607 +msgid "Emits information about lightweight lock usage." +msgstr "Gibt Informationen über die Verwendung von Lightweight Locks aus." + +#: utils/misc/guc.c:1617 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "Gibt Informationen über alle aktuellen Sperren aus, wenn eine Verklemmung auftritt." + +#: utils/misc/guc.c:1629 +msgid "Logs long lock waits." +msgstr "Schreibt Meldungen über langes Warten auf Sperren in den Log." + +#: utils/misc/guc.c:1638 +#, fuzzy +#| msgid "abort reason: recovery conflict" +msgid "Logs standby recovery conflict waits." +msgstr "Abbruchgrund: Konflikt bei Wiederherstellung" + +#: utils/misc/guc.c:1647 +msgid "Logs the host name in the connection logs." +msgstr "Schreibt den Hostnamen jeder Verbindung in den Log." + +#: utils/misc/guc.c:1648 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "In der Standardeinstellung zeigen die Verbindungslogs nur die IP-Adresse der Clienthosts. Wenn Sie den Hostnamen auch anzeigen wollen, dann können Sie diese Option anschalten, aber je nachdem, wie Ihr DNS eingerichtet ist, kann das die Leistung nicht unerheblich beeinträchtigen." + +#: utils/misc/guc.c:1659 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "Behandelt »ausdruck=NULL« als »ausdruck IS NULL«." + +#: utils/misc/guc.c:1660 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "Wenn an, dann werden Ausdrücke der Form ausdruck = NULL (oder NULL = ausdruck) wie ausdruck IS NULL behandelt, das heißt, sie ergeben wahr, wenn das Ergebnis von ausdruck der NULL-Wert ist, und ansonsten falsch. Das korrekte Verhalten von ausdruck = NULL ist immer den NULL-Wert (für unbekannt) zurückzugeben." + +#: utils/misc/guc.c:1672 +msgid "Enables per-database user names." +msgstr "Ermöglicht Datenbank-lokale Benutzernamen." + +#: utils/misc/guc.c:1681 +msgid "Sets the default read-only status of new transactions." +msgstr "Setzt den Standardwert für die Read-Only-Einstellung einer neuen Transaktion." + +#: utils/misc/guc.c:1691 +msgid "Sets the current transaction's read-only status." +msgstr "Setzt die Read-Only-Einstellung der aktuellen Transaktion." + +#: utils/misc/guc.c:1701 +msgid "Sets the default deferrable status of new transactions." +msgstr "Setzt den Standardwert für die Deferrable-Einstellung einer neuen Transaktion." + +#: utils/misc/guc.c:1710 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "Ob eine serialisierbare Read-Only-Transaktion aufgeschoben werden soll, bis sie ohne mögliche Serialisierungsfehler ausgeführt werden kann." + +#: utils/misc/guc.c:1720 +msgid "Enable row security." +msgstr "Schaltet Sicherheit auf Zeilenebene ein." + +#: utils/misc/guc.c:1721 +msgid "When enabled, row security will be applied to all users." +msgstr "Wenn eingeschaltet, wird Sicherheit auf Zeilenebene auf alle Benutzer angewendet." + +#: utils/misc/guc.c:1729 +msgid "Check routine bodies during CREATE FUNCTION and CREATE PROCEDURE." +msgstr "Prüft Funktionskörper bei der Ausführung von CREATE FUNCTION und CREATE PROCEDURE." + +#: utils/misc/guc.c:1738 +msgid "Enable input of NULL elements in arrays." +msgstr "Ermöglicht die Eingabe von NULL-Elementen in Arrays." + +#: utils/misc/guc.c:1739 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "Wenn dies eingeschaltet ist, wird ein nicht gequotetes NULL in einem Array-Eingabewert als NULL-Wert interpretiert, ansonsten als Zeichenkette." + +#: utils/misc/guc.c:1755 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OIDS wird nicht mehr unterstützt; kann nur auf falsch gesetzt werden." + +#: utils/misc/guc.c:1765 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "Startet einen Subprozess, um die Stderr-Ausgabe und/oder CSV-Logs in Logdateien auszugeben." + +#: utils/misc/guc.c:1774 +msgid "Truncate existing log files of same name during log rotation." +msgstr "Kürzt existierende Logdateien mit dem selben Namen beim Rotieren." + +#: utils/misc/guc.c:1785 +msgid "Emit information about resource usage in sorting." +msgstr "Gibt Informationen über die Ressourcenverwendung beim Sortieren aus." + +#: utils/misc/guc.c:1799 +msgid "Generate debugging output for synchronized scanning." +msgstr "Erzeugt Debug-Ausgabe für synchronisiertes Scannen." + +#: utils/misc/guc.c:1814 +msgid "Enable bounded sorting using heap sort." +msgstr "Ermöglicht Bounded Sorting mittels Heap-Sort." + +#: utils/misc/guc.c:1827 +msgid "Emit WAL-related debugging output." +msgstr "Gibt diverse Debug-Meldungen über WAL aus." + +#: utils/misc/guc.c:1839 +#, fuzzy +#| msgid "Datetimes are integer based." +msgid "Shows whether datetimes are integer based." +msgstr "Datum/Zeit verwendet intern ganze Zahlen." + +#: utils/misc/guc.c:1850 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "Bestimmt, ob Groß-/Kleinschreibung bei Kerberos- und GSSAPI-Benutzernamen ignoriert werden soll." + +#: utils/misc/guc.c:1860 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Warnt bei Backslash-Escapes in normalen Zeichenkettenkonstanten." + +#: utils/misc/guc.c:1870 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "Bewirkt, dass Zeichenketten der Art '...' Backslashes als normales Zeichen behandeln." + +#: utils/misc/guc.c:1881 +msgid "Enable synchronized sequential scans." +msgstr "Ermöglicht synchronisierte sequenzielle Scans." + +#: utils/misc/guc.c:1891 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Setzt ob die Transaktion mit dem Wiederherstellungsziel einbezogen oder ausgeschlossen wird." + +#: utils/misc/guc.c:1901 +msgid "Allows connections and queries during recovery." +msgstr "Erlaubt Verbindungen und Anfragen während der Wiederherstellung." + +#: utils/misc/guc.c:1911 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "Erlaubt Rückmeldungen von einem Hot Standby an den Primärserver, um Anfragekonflikte zu vermeiden." + +#: utils/misc/guc.c:1921 +msgid "Shows whether hot standby is currently active." +msgstr "Zeigt, ob Hot Standby aktuell aktiv ist." + +#: utils/misc/guc.c:1932 +msgid "Allows modifications of the structure of system tables." +msgstr "Erlaubt Änderungen an der Struktur von Systemtabellen." + +#: utils/misc/guc.c:1943 +msgid "Disables reading from system indexes." +msgstr "Schaltet das Lesen aus Systemindexen ab." + +#: utils/misc/guc.c:1944 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "Das Aktualisieren der Indexe wird nicht verhindert, also ist die Verwendung unbedenklich. Schlimmstenfalls wird alles langsamer." + +#: utils/misc/guc.c:1955 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "Schaltet den rückwärtskompatiblen Modus für Privilegienprüfungen bei Large Objects ein." + +#: utils/misc/guc.c:1956 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "Überspringt Privilegienprüfungen beim Lesen oder Ändern von Large Objects, zur Kompatibilität mit PostgreSQL-Versionen vor 9.0." + +#: utils/misc/guc.c:1966 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "Wenn SQL-Fragmente erzeugt werden, alle Bezeichner quoten." + +#: utils/misc/guc.c:1976 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Zeigt, ob Datenprüfsummen in diesem Cluster angeschaltet sind." + +#: utils/misc/guc.c:1987 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "Syslog-Nachrichten mit Sequenznummern versehen, um Unterdrückung doppelter Nachrichten zu unterbinden." + +#: utils/misc/guc.c:1997 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "An Syslog gesendete Nachrichten nach Zeilen und in maximal 1024 Bytes aufteilen." + +#: utils/misc/guc.c:2007 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Kontrolliert, ob Gather und Gather Merge auch Subpläne ausführen." + +#: utils/misc/guc.c:2008 +msgid "Should gather nodes also run subplans or just gather tuples?" +msgstr "Sollen Gather-Knoten auch Subpläne ausführen oder nur Tupel sammeln?" + +#: utils/misc/guc.c:2018 +msgid "Allow JIT compilation." +msgstr "Erlaubt JIT-Kompilierung." + +#: utils/misc/guc.c:2029 +msgid "Register JIT-compiled functions with debugger." +msgstr "JIT-kompilierte Funktionen im Debugger registrieren." + +#: utils/misc/guc.c:2046 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "LLVM-Bitcode in Dateien schreiben, um Debuggen von JIT zu erleichtern." + +#: utils/misc/guc.c:2057 +msgid "Allow JIT compilation of expressions." +msgstr "Erlaubt JIT-Kompilierung von Ausdrücken." + +#: utils/misc/guc.c:2068 +msgid "Register JIT-compiled functions with perf profiler." +msgstr "JIT-kompilierte Funktionen im Profiler perf registrieren." + +#: utils/misc/guc.c:2085 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Erlaubt JIT-Kompilierung von Tuple-Deforming." + +#: utils/misc/guc.c:2096 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Ob nach fehlgeschlagenem Synchronisieren von Datendateien fortgesetzt werden soll." + +#: utils/misc/guc.c:2105 +msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." +msgstr "Bestimmt, ob der WAL-Receiver einen temporären Replikations-Slot erzeugen soll, wenn kein permanenter Slot konfiguriert ist." + +#: utils/misc/guc.c:2123 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "Erzwingt das Umschalten zur nächsten WAL-Datei, wenn seit N Sekunden keine neue Datei begonnen worden ist." + +#: utils/misc/guc.c:2134 +msgid "Waits N seconds on connection startup after authentication." +msgstr "Wartet beim Starten einer Verbindung N Sekunden nach der Authentifizierung." + +#: utils/misc/guc.c:2135 utils/misc/guc.c:2733 +msgid "This allows attaching a debugger to the process." +msgstr "Das ermöglicht es, einen Debugger in den Prozess einzuhängen." + +#: utils/misc/guc.c:2144 +msgid "Sets the default statistics target." +msgstr "Setzt das voreingestellte Statistikziel." + +#: utils/misc/guc.c:2145 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "Diese Einstellung gilt für Tabellenspalten, für die kein spaltenspezifisches Ziel mit ALTER TABLE SET STATISTICS gesetzt worden ist." + +#: utils/misc/guc.c:2154 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "Setzt die Größe der FROM-Liste, ab der Unteranfragen nicht kollabiert werden." + +#: utils/misc/guc.c:2156 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "Der Planer bindet Unteranfragen in die übergeordneten Anfragen ein, wenn die daraus resultierende FROM-Liste nicht mehr als so viele Elemente haben würde." + +#: utils/misc/guc.c:2167 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "Setzt die Größe der FROM-Liste, ab der JOIN-Konstrukte nicht aufgelöst werden." + +#: utils/misc/guc.c:2169 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "Der Planer löst ausdrückliche JOIN-Konstrukte in FROM-Listen auf, wenn die daraus resultierende FROM-Liste nicht mehr als so viele Elemente haben würde." + +#: utils/misc/guc.c:2180 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "Setzt die Anzahl der Elemente in der FROM-Liste, ab der GEQO verwendet wird." + +#: utils/misc/guc.c:2190 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: wird für die Berechnung der Vorgabewerte anderer GEQO-Parameter verwendet." + +#: utils/misc/guc.c:2200 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: Anzahl der Individien in der Bevölkerung." + +#: utils/misc/guc.c:2201 utils/misc/guc.c:2211 +msgid "Zero selects a suitable default value." +msgstr "Null wählt einen passenden Vorgabewert." + +#: utils/misc/guc.c:2210 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: Anzahl der Iterationen im Algorithmus." + +#: utils/misc/guc.c:2222 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Setzt die Zeit, die gewartet wird, bis auf Verklemmung geprüft wird." + +#: utils/misc/guc.c:2233 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ein Hot-Standby-Server archivierte WAL-Daten verarbeitet." + +#: utils/misc/guc.c:2244 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ein Hot-Standby-Server gestreamte WAL-Daten verarbeitet." + +#: utils/misc/guc.c:2255 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "Setzt die minimale Verzögerung für das Einspielen von Änderungen während der Wiederherstellung." + +#: utils/misc/guc.c:2266 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "Setzt das maximale Intervall zwischen Statusberichten des WAL-Receivers an den sendenden Server." + +#: utils/misc/guc.c:2277 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "Setzt die maximale Zeit, um auf den Empfang von Daten vom sendenden Server zu warten." + +#: utils/misc/guc.c:2288 +msgid "Sets the maximum number of concurrent connections." +msgstr "Setzt die maximale Anzahl gleichzeitiger Verbindungen." + +#: utils/misc/guc.c:2299 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "Setzt die Anzahl der für Superuser reservierten Verbindungen." + +#: utils/misc/guc.c:2309 +#, fuzzy +#| msgid "could not map dynamic shared memory segment" +msgid "Amount of dynamic shared memory reserved at startup." +msgstr "konnte dynamisches Shared-Memory-Segment nicht mappen" + +#: utils/misc/guc.c:2324 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Setzt die Anzahl der vom Server verwendeten Shared-Memory-Puffer." + +#: utils/misc/guc.c:2335 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Setzt die maximale Anzahl der von jeder Sitzung verwendeten temporären Puffer." + +#: utils/misc/guc.c:2346 +msgid "Sets the TCP port the server listens on." +msgstr "Setzt den TCP-Port, auf dem der Server auf Verbindungen wartet." + +#: utils/misc/guc.c:2356 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Setzt die Zugriffsrechte für die Unix-Domain-Socket." + +#: utils/misc/guc.c:2357 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unix-Domain-Sockets verwenden die üblichen Zugriffsrechte für Unix-Dateisysteme. Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" + +#: utils/misc/guc.c:2371 +msgid "Sets the file permissions for log files." +msgstr "Setzt die Dateizugriffsrechte für Logdateien." + +#: utils/misc/guc.c:2372 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" + +#: utils/misc/guc.c:2386 +#, fuzzy +#| msgid "Mode of the data directory." +msgid "Shows the mode of the data directory." +msgstr "Zugriffsrechte des Datenverzeichnisses." + +#: utils/misc/guc.c:2387 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" + +#: utils/misc/guc.c:2400 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Setzt die maximale Speichergröße für Anfrage-Arbeitsbereiche." + +#: utils/misc/guc.c:2401 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "Gibt die Speichermenge an, die für interne Sortiervorgänge und Hashtabellen verwendet werden kann, bevor auf temporäre Dateien umgeschaltet wird." + +#: utils/misc/guc.c:2413 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Setzt die maximale Speichergröße für Wartungsoperationen." + +#: utils/misc/guc.c:2414 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Das schließt Operationen wie VACUUM und CREATE INDEX ein." + +#: utils/misc/guc.c:2424 +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "Setzt die maximale Speichergröße für logische Dekodierung." + +#: utils/misc/guc.c:2425 +msgid "This much memory can be used by each internal reorder buffer before spilling to disk." +msgstr "Gibt die Speichermenge an, die für jeden internen Reorder-Puffer verwendet werden kann, bevor auf Festplatte ausgelagert wird." + +#: utils/misc/guc.c:2441 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Setzt die maximale Stackgröße, in Kilobytes." + +#: utils/misc/guc.c:2452 +msgid "Limits the total size of all temporary files used by each process." +msgstr "Beschränkt die Gesamtgröße aller temporären Dateien, die von einem Prozess verwendet werden." + +#: utils/misc/guc.c:2453 +msgid "-1 means no limit." +msgstr "-1 bedeutet keine Grenze." + +#: utils/misc/guc.c:2463 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Vacuum-Kosten für eine im Puffer-Cache gefundene Seite." + +#: utils/misc/guc.c:2473 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Vacuum-Kosten für eine nicht im Puffer-Cache gefundene Seite." + +#: utils/misc/guc.c:2483 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Vacuum-Kosten für eine durch Vacuum schmutzig gemachte Seite." + +#: utils/misc/guc.c:2493 +msgid "Vacuum cost amount available before napping." +msgstr "Verfügbare Vacuum-Kosten vor Nickerchen." + +#: utils/misc/guc.c:2503 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "Verfügbare Vacuum-Kosten vor Nickerchen, für Autovacuum." + +#: utils/misc/guc.c:2513 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "Setzt die maximale Zahl gleichzeitig geöffneter Dateien für jeden Serverprozess." + +#: utils/misc/guc.c:2526 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Setzt die maximale Anzahl von gleichzeitig vorbereiteten Transaktionen." + +#: utils/misc/guc.c:2537 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Setzt die minimale Tabellen-OID für das Verfolgen von Sperren." + +#: utils/misc/guc.c:2538 +msgid "Is used to avoid output on system tables." +msgstr "Wird verwendet, um Ausgabe für Systemtabellen zu vermeiden." + +#: utils/misc/guc.c:2547 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "Setzt die OID der Tabelle mit bedingungsloser Sperrenverfolgung." + +#: utils/misc/guc.c:2559 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Setzt die maximal erlaubte Dauer jeder Anweisung." + +#: utils/misc/guc.c:2560 utils/misc/guc.c:2571 utils/misc/guc.c:2582 +#: utils/misc/guc.c:2593 +msgid "A value of 0 turns off the timeout." +msgstr "Der Wert 0 schaltet die Zeitprüfung aus." + +#: utils/misc/guc.c:2570 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Setzt die maximal erlaubte Dauer, um auf eine Sperre zu warten." + +#: utils/misc/guc.c:2581 +#, fuzzy +#| msgid "Sets the maximum allowed duration of any idling transaction." +msgid "Sets the maximum allowed idle time between queries, when in a transaction." +msgstr "Setzt die maximal erlaubte Dauer einer inaktiven Transaktion." + +#: utils/misc/guc.c:2592 +#, fuzzy +#| msgid "Sets the maximum allowed duration of any idling transaction." +msgid "Sets the maximum allowed idle time between queries, when not in a transaction." +msgstr "Setzt die maximal erlaubte Dauer einer inaktiven Transaktion." + +#: utils/misc/guc.c:2603 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "Mindestalter, bei dem VACUUM eine Tabellenzeile einfrieren soll." + +#: utils/misc/guc.c:2613 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." + +#: utils/misc/guc.c:2623 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "Mindestalter, bei dem VACUUM eine MultiXactId in einer Tabellenzeile einfrieren soll." + +#: utils/misc/guc.c:2633 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "Multixact-Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." + +#: utils/misc/guc.c:2643 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "Anzahl Transaktionen, um die VACUUM- und HOT-Aufräumen aufgeschoben werden soll." + +#: utils/misc/guc.c:2652 +#, fuzzy +#| msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgid "Age at which VACUUM should trigger failsafe to avoid a wraparound outage." +msgstr "Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." + +#: utils/misc/guc.c:2661 +#, fuzzy +#| msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgid "Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage." +msgstr "Multixact-Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." + +#: utils/misc/guc.c:2674 +msgid "Sets the maximum number of locks per transaction." +msgstr "Setzt die maximale Anzahl Sperren pro Transaktion." + +#: utils/misc/guc.c:2675 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Die globale Sperrentabelle wird mit der Annahme angelegt, das höchstens max_locks_per_transaction * max_connections verschiedene Objekte gleichzeitig gesperrt werden müssen." + +#: utils/misc/guc.c:2686 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Setzt die maximale Anzahl Prädikatsperren pro Transaktion." + +#: utils/misc/guc.c:2687 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Die globale Prädikatsperrentabelle wird mit der Annahme angelegt, das höchstens max_pred_locks_per_transaction * max_connections verschiedene Objekte gleichzeitig gesperrt werden müssen." + +#: utils/misc/guc.c:2698 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Setzt die maximale Anzahl Prädikatsperren für Seiten und Tupel pro Relation." + +#: utils/misc/guc.c:2699 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Wenn mehr als diese Gesamtzahl Seiten und Tupel in der selben Relation von einer Verbindung gesperrt sind, werden diese Sperren durch eine Sperre auf Relationsebene ersetzt." + +#: utils/misc/guc.c:2709 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Setzt die maximale Anzahl Prädikatsperren für Tupel pro Seite." + +#: utils/misc/guc.c:2710 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Wenn mehr als diese Anzahl Tupel auf der selben Seite von einer Verbindung gesperrt sind, werden diese Sperren durch eine Sperre auf Seitenebene ersetzt." + +#: utils/misc/guc.c:2720 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "Setzt die maximale Zeit, um die Client-Authentifizierung zu beenden." + +#: utils/misc/guc.c:2732 +msgid "Waits N seconds on connection startup before authentication." +msgstr "Wartet beim Starten einer Verbindung N Sekunden vor der Authentifizierung." + +#: utils/misc/guc.c:2743 +msgid "Sets the size of WAL files held for standby servers." +msgstr "Setzt die Größe der für Standby-Server vorgehaltenen WAL-Dateien." + +#: utils/misc/guc.c:2754 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "Setzt die minimale Größe, auf die der WAL geschrumpft wird." + +#: utils/misc/guc.c:2766 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Setzt die WAL-Größe, die einen Checkpoint auslöst." + +#: utils/misc/guc.c:2778 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "Setzt die maximale Zeit zwischen automatischen WAL-Checkpoints." + +#: utils/misc/guc.c:2789 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "Schreibt eine Logmeldung, wenn Checkpoint-Segmente häufiger als dieser Wert gefüllt werden." + +#: utils/misc/guc.c:2791 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "Schreibe Meldung in den Serverlog, wenn Checkpoints, die durch Füllen der Checkpoint-Segmente ausgelöst werden, häufiger als dieser Wert in Sekunden passieren. Null schaltet die Warnung ab." + +#: utils/misc/guc.c:2803 utils/misc/guc.c:3019 utils/misc/guc.c:3066 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "Anzahl der Seiten, nach denen getätigte Schreibvorgänge auf die Festplatte zurückgeschrieben werden." + +#: utils/misc/guc.c:2814 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "Setzt die Anzahl Diskseitenpuffer für WAL im Shared Memory." + +#: utils/misc/guc.c:2825 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "Zeit zwischen WAL-Flush-Operationen im WAL-Writer." + +#: utils/misc/guc.c:2836 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "Ein Flush wird ausgelöst, wenn diese Menge WAL vom WAL-Writer geschrieben worden ist." + +#: utils/misc/guc.c:2847 +#, fuzzy +#| msgid "Size of new file to fsync instead of writing WAL." +msgid "Minimum size of new file to fsync instead of writing WAL." +msgstr "Größe ab der neue Datei gefsynct wird statt WAL zu schreiben." + +#: utils/misc/guc.c:2858 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "Setzt die maximale Anzahl gleichzeitig laufender WAL-Sender-Prozesse." + +#: utils/misc/guc.c:2869 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Setzt die maximale Anzahl von gleichzeitig definierten Replikations-Slots." + +#: utils/misc/guc.c:2879 +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "Setzt die maximale WAL-Größe, die von Replikations-Slots reserviert werden kann." + +#: utils/misc/guc.c:2880 +msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "Replikations-Slots werden als fehlgeschlagen markiert, und Segmente zum Löschen oder Wiederverwenden freigegeben, wenn so viel Platz von WAL auf der Festplatte belegt wird." + +#: utils/misc/guc.c:2892 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "Setzt die maximale Zeit, um auf WAL-Replikation zu warten." + +#: utils/misc/guc.c:2903 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "Setzt die Verzögerung in Millisekunden zwischen Transaktionsabschluss und dem Schreiben von WAL auf die Festplatte." + +#: utils/misc/guc.c:2915 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "Setzt die minimale Anzahl gleichzeitig offener Transaktionen bevor »commit_delay« angewendet wird." + +#: utils/misc/guc.c:2926 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Setzt die Anzahl ausgegebener Ziffern für Fließkommawerte." + +#: utils/misc/guc.c:2927 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "Diese Einstellung betrifft real, double precision und geometrische Datentypen. Null oder ein negativer Parameterwert wird zur Standardziffernanzahl (FLT_DIG bzw. DBL_DIG) hinzuaddiert. Ein Wert größer als Null wählt präzisen Ausgabemodus." + +#: utils/misc/guc.c:2939 +msgid "Sets the minimum execution time above which a sample of statements will be logged. Sampling is determined by log_statement_sample_rate." +msgstr "Setzt die minimale Ausführungszeit, über der Stichproben aller Anweisungen geloggt werden. Die Stichproben werden durch log_statement_sample_rate bestimmt." + +#: utils/misc/guc.c:2942 +msgid "Zero logs a sample of all queries. -1 turns this feature off." +msgstr "Null loggt eine Stichprobe aller Anfragen. -1 schaltet dieses Feature aus." + +#: utils/misc/guc.c:2952 +msgid "Sets the minimum execution time above which all statements will be logged." +msgstr "Setzt die minimale Ausführungszeit, über der alle Anweisungen geloggt werden." + +#: utils/misc/guc.c:2954 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "Null zeigt alle Anfragen. -1 schaltet dieses Feature aus." + +#: utils/misc/guc.c:2964 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "Setzt die minimale Ausführungszeit, über der Autovacuum-Aktionen geloggt werden." + +#: utils/misc/guc.c:2966 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "Null gibt alls Aktionen aus. -1 schaltet die Log-Aufzeichnung über Autovacuum aus." + +#: utils/misc/guc.c:2976 +msgid "When logging statements, limit logged parameter values to first N bytes." +msgstr "Wenn Anweisungen geloggt werden, die geloggten Parameterwerte auf die ersten N Bytes begrenzen." + +#: utils/misc/guc.c:2977 utils/misc/guc.c:2988 +msgid "-1 to print values in full." +msgstr "-1 um die Werte vollständig auszugeben." + +#: utils/misc/guc.c:2987 +msgid "When reporting an error, limit logged parameter values to first N bytes." +msgstr "Wenn ein Fehler ausgegeben wird, die geloggten Parameterwerte auf die ersten N Bytes begrenzen." + +#: utils/misc/guc.c:2998 +msgid "Background writer sleep time between rounds." +msgstr "Schlafzeit zwischen Durchläufen des Background-Writers." + +#: utils/misc/guc.c:3009 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "Maximale Anzahl der vom Background-Writer pro Durchlauf zu flushenden LRU-Seiten." + +#: utils/misc/guc.c:3032 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "Anzahl simultaner Anfragen, die das Festplattensubsystem effizient bearbeiten kann." + +#: utils/misc/guc.c:3050 +msgid "A variant of effective_io_concurrency that is used for maintenance work." +msgstr "Eine Variante von effective_io_concurrency, die für Wartungsarbeiten verwendet wird." + +#: utils/misc/guc.c:3079 +msgid "Maximum number of concurrent worker processes." +msgstr "Maximale Anzahl gleichzeitiger Worker-Prozesse." + +#: utils/misc/guc.c:3091 +msgid "Maximum number of logical replication worker processes." +msgstr "Maximale Anzahl Arbeitsprozesse für logische Replikation." + +#: utils/misc/guc.c:3103 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Maximale Anzahl Arbeitsprozesse für Tabellensynchronisation pro Subskription." + +#: utils/misc/guc.c:3113 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "Automatische Rotation der Logdateien geschieht nach N Minuten." + +#: utils/misc/guc.c:3124 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "Automatische Rotation der Logdateien geschieht nach N Kilobytes." + +#: utils/misc/guc.c:3135 +msgid "Shows the maximum number of function arguments." +msgstr "Setzt die maximale Anzahl von Funktionsargumenten." + +#: utils/misc/guc.c:3146 +msgid "Shows the maximum number of index keys." +msgstr "Zeigt die maximale Anzahl von Indexschlüsseln." + +#: utils/misc/guc.c:3157 +msgid "Shows the maximum identifier length." +msgstr "Zeigt die maximale Länge von Bezeichnern." + +#: utils/misc/guc.c:3168 +msgid "Shows the size of a disk block." +msgstr "Zeigt die Größe eines Diskblocks." + +#: utils/misc/guc.c:3179 +msgid "Shows the number of pages per disk file." +msgstr "Zeigt die Anzahl Seiten pro Diskdatei." + +#: utils/misc/guc.c:3190 +msgid "Shows the block size in the write ahead log." +msgstr "Zeigt die Blockgröße im Write-Ahead-Log." + +#: utils/misc/guc.c:3201 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "Setzt die Zeit, die gewartet wird, bevor nach einem fehlgeschlagenen Versuch neue WAL-Daten angefordert werden." + +#: utils/misc/guc.c:3213 +msgid "Shows the size of write ahead log segments." +msgstr "Zeigt die Größe eines Write-Ahead-Log-Segments." + +#: utils/misc/guc.c:3226 +msgid "Time to sleep between autovacuum runs." +msgstr "Wartezeit zwischen Autovacuum-Durchläufen." + +#: utils/misc/guc.c:3236 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Mindestanzahl an geänderten oder gelöschten Tupeln vor einem Vacuum." + +#: utils/misc/guc.c:3245 +msgid "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums." +msgstr "Mindestanzahl an Einfügeoperationen vor einem Vacuum, oder -1 um auszuschalten." + +#: utils/misc/guc.c:3254 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "Mindestanzahl an Einfüge-, Änderungs- oder Löschoperationen vor einem Analyze." + +#: utils/misc/guc.c:3264 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "Alter, nach dem eine Tabelle automatisch gevacuumt wird, um Transaktionsnummernüberlauf zu verhindern." + +#: utils/misc/guc.c:3279 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "Multixact-Alter, nach dem eine Tabelle automatisch gevacuumt wird, um Transaktionsnummernüberlauf zu verhindern." + +#: utils/misc/guc.c:3289 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "Setzt die maximale Anzahl gleichzeitig laufender Autovacuum-Worker-Prozesse." + +#: utils/misc/guc.c:3299 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Setzt die maximale Anzahl paralleler Prozesse pro Wartungsoperation." + +#: utils/misc/guc.c:3309 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Setzt die maximale Anzahl paralleler Prozesse pro Executor-Knoten." + +#: utils/misc/guc.c:3320 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Setzt die maximale Anzahl paralleler Arbeitsprozesse, die gleichzeitig aktiv sein können." + +#: utils/misc/guc.c:3331 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "Setzt die maximale Speichergröße für jeden Autovacuum-Worker-Prozess." + +#: utils/misc/guc.c:3342 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "Zeit bevor ein Snapshot zu alt ist, um Seiten zu lesen, die geändert wurden, nachdem der Snapshot gemacht wurde." + +#: utils/misc/guc.c:3343 +msgid "A value of -1 disables this feature." +msgstr "Der Wert -1 schaltet dieses Feature aus." + +#: utils/misc/guc.c:3353 +msgid "Time between issuing TCP keepalives." +msgstr "Zeit zwischen TCP-Keepalive-Sendungen." + +#: utils/misc/guc.c:3354 utils/misc/guc.c:3365 utils/misc/guc.c:3489 +msgid "A value of 0 uses the system default." +msgstr "Der Wert 0 verwendet die Systemvoreinstellung." + +#: utils/misc/guc.c:3364 +msgid "Time between TCP keepalive retransmits." +msgstr "Zeit zwischen TCP-Keepalive-Neuübertragungen." + +#: utils/misc/guc.c:3375 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "SSL-Renegotiation wird nicht mehr unterstützt; kann nur auf 0 gesetzt werden." + +#: utils/misc/guc.c:3386 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "Maximale Anzahl an TCP-Keepalive-Neuübertragungen." + +#: utils/misc/guc.c:3387 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "Dies bestimmt die Anzahl von aufeinanderfolgenden Keepalive-Neuübertragungen, die verloren gehen dürfen, bis die Verbindung als tot betrachtet wird. Der Wert 0 verwendet die Betriebssystemvoreinstellung." + +#: utils/misc/guc.c:3398 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "Setzt die maximal erlaubte Anzahl Ergebnisse für eine genaue Suche mit GIN." + +#: utils/misc/guc.c:3409 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Setzt die Annahme des Planers über die Gesamtgröße der Daten-Caches." + +#: utils/misc/guc.c:3410 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Das heißt, die Gesamtgröße der Caches (Kernel-Cache und Shared Buffers), die für Datendateien von PostgreSQL verwendet wird. Das wird in Diskseiten gemessen, welche normalerweise 8 kB groß sind." + +#: utils/misc/guc.c:3421 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "Setzt die Mindestmenge an Tabellendaten für einen parallelen Scan." + +#: utils/misc/guc.c:3422 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Wenn der Planer schätzt, dass zu wenige Tabellenseiten gelesen werden werden um diesen Wert zu erreichen, dann wird kein paralleler Scan in Erwägung gezogen werden." + +#: utils/misc/guc.c:3432 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "Setzt die Mindestmenge an Indexdaten für einen parallelen Scan." + +#: utils/misc/guc.c:3433 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Wenn der Planer schätzt, dass zu wenige Indexseiten gelesen werden werden um diesen Wert zu erreichen, dann wird kein paralleler Scan in Erwägung gezogen werden." + +#: utils/misc/guc.c:3444 +msgid "Shows the server version as an integer." +msgstr "Zeigt die Serverversion als Zahl." + +#: utils/misc/guc.c:3455 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "Schreibt Meldungen über die Verwendung von temporären Dateien in den Log, wenn sie größer als diese Anzahl an Kilobytes sind." + +#: utils/misc/guc.c:3456 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "Null loggt alle Dateien. Die Standardeinstellung ist -1 (wodurch dieses Feature ausgeschaltet wird)." + +#: utils/misc/guc.c:3466 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "Setzt die für pg_stat_activity.query reservierte Größe, in Bytes." + +#: utils/misc/guc.c:3477 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "Setzt die maximale Größe der Pending-Liste eines GIN-Index." + +#: utils/misc/guc.c:3488 +msgid "TCP user timeout." +msgstr "TCP-User-Timeout." + +#: utils/misc/guc.c:3499 +msgid "The size of huge page that should be requested." +msgstr "" + +#: utils/misc/guc.c:3510 +msgid "Aggressively invalidate system caches for debugging purposes." +msgstr "" + +#: utils/misc/guc.c:3533 +#, fuzzy +#| msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgid "Sets the time interval between checks for disconnection while running queries." +msgstr "Setzt das maximale Intervall zwischen Statusberichten des WAL-Receivers an den sendenden Server." + +#: utils/misc/guc.c:3553 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "Setzt den vom Planer geschätzten Aufwand, um eine sequenzielle Diskseite zu lesen." + +#: utils/misc/guc.c:3564 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "Setzt den vom Planer geschätzten Aufwand, um eine nichtsequenzielle Diskseite zu lesen." + +#: utils/misc/guc.c:3575 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "Setzt den vom Planer geschätzten Aufwand für die Verarbeitung einer Zeile." + +#: utils/misc/guc.c:3586 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "Setzt den vom Planer geschätzten Aufwand für die Verarbeitung eines Indexeintrags während eines Index-Scans." + +#: utils/misc/guc.c:3597 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "Setzt den vom Planer geschätzten Aufwand für die Verarbeitung eines Operators oder Funktionsaufrufs." + +#: utils/misc/guc.c:3608 +#, fuzzy +#| msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to leader backend." +msgstr "Setzt den vom Planer geschätzten Aufwand, um eine Zeile vom Arbeitsprozess and das Master-Backend zu senden." + +#: utils/misc/guc.c:3619 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "Setzt den vom Planer geschätzten Aufwand für das Starten von Arbeitsprozessen für parallele Anfragen." + +#: utils/misc/guc.c:3631 +msgid "Perform JIT compilation if query is more expensive." +msgstr "JIT-Kompilierung durchführen, wenn die Anfrage teurer ist." + +#: utils/misc/guc.c:3632 +msgid "-1 disables JIT compilation." +msgstr "-1 schaltet JIT-Kompilierung aus." + +#: utils/misc/guc.c:3642 +msgid "Optimize JIT-compiled functions if query is more expensive." +msgstr "JIT-kompilierte Funktionen optimieren, wenn die Anfrage teurer ist." + +#: utils/misc/guc.c:3643 +msgid "-1 disables optimization." +msgstr "-1 schaltet Optimierung aus." + +#: utils/misc/guc.c:3653 +msgid "Perform JIT inlining if query is more expensive." +msgstr "JIT-Inlining durchführen, wenn die Anfrage teurer ist." + +#: utils/misc/guc.c:3654 +msgid "-1 disables inlining." +msgstr "-1 schaltet Inlining aus." + +#: utils/misc/guc.c:3664 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "Setzt den vom Planer geschätzten Anteil der Cursor-Zeilen, die ausgelesen werden werden." + +#: utils/misc/guc.c:3676 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: selektiver Auswahldruck in der Bevölkerung." + +#: utils/misc/guc.c:3687 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: Ausgangswert für die zufällige Pfadauswahl." + +#: utils/misc/guc.c:3698 +msgid "Multiple of work_mem to use for hash tables." +msgstr "Vielfaches von work_mem zur Verwendung bei Hash-Tabellen." + +#: utils/misc/guc.c:3709 +msgid "Multiple of the average buffer usage to free per round." +msgstr "Vielfaches der durchschnittlichen freizugebenden Pufferverwendung pro Runde." + +#: utils/misc/guc.c:3719 +msgid "Sets the seed for random-number generation." +msgstr "Setzt den Ausgangswert für die Zufallszahlenerzeugung." + +#: utils/misc/guc.c:3730 +msgid "Vacuum cost delay in milliseconds." +msgstr "Vacuum-Kosten-Verzögerung in Millisekunden." + +#: utils/misc/guc.c:3741 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Vacuum-Kosten-Verzögerung in Millisekunden, für Autovacuum." + +#: utils/misc/guc.c:3752 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "Anzahl geänderter oder gelöschter Tupel vor einem Vacuum, relativ zu reltuples." + +#: utils/misc/guc.c:3762 +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "Anzahl eingefügter Tupel vor einem Vacuum, relativ zu reltuples." + +#: utils/misc/guc.c:3772 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "Anzahl eingefügter, geänderter oder gelöschter Tupel vor einem Analyze, relativ zu reltuples." + +#: utils/misc/guc.c:3782 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "Zeit, die damit verbracht wird, modifizierte Puffer während eines Checkpoints zurückzuschreiben, als Bruchteil des Checkpoint-Intervalls." + +#: utils/misc/guc.c:3792 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "Anteil der zu loggenden Anweisungen, die log_min_duration_sample überschreiten." + +#: utils/misc/guc.c:3793 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "Verwenden Sie einen Wert zwischen 0.0 (nie loggen) und 1.0 (immer loggen)." + +#: utils/misc/guc.c:3802 +#, fuzzy +#| msgid "Sets the fraction of transactions to log for new transactions." +msgid "Sets the fraction of transactions from which to log all statements." +msgstr "Setzt den Bruchteil zu loggender Transaktionen." + +#: utils/misc/guc.c:3803 +#, fuzzy +#| msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgid "Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "Loggt alle Anweisungen in einem Bruchteil der Transaktionen. Verwenden Sie einen Wert zwischen 0.0 (nie loggen) und 1.0 (alle Anweisungen für alle Transaktionen loggen)." + +#: utils/misc/guc.c:3822 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "Setzt den Shell-Befehl, der aufgerufen wird, um eine WAL-Datei zu archivieren." + +#: utils/misc/guc.c:3832 +msgid "Sets the shell command that will be called to retrieve an archived WAL file." +msgstr "Setzt den Shell-Befehl, der aufgerufen wird, um eine archivierte WAL-Datei zurückzuholen." + +#: utils/misc/guc.c:3842 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "Setzt den Shell-Befehl, der bei jedem Restart-Punkt ausgeführt wird." + +#: utils/misc/guc.c:3852 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "Setzt den Shell-Befehl, der einmal am Ende der Wiederherstellung ausgeführt wird." + +#: utils/misc/guc.c:3862 +msgid "Specifies the timeline to recover into." +msgstr "Gibt die Zeitleiste für die Wiederherstellung an." + +#: utils/misc/guc.c:3872 +msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." +msgstr "Auf »immediate« setzen, um die Wiederherstellung zu beenden, sobald ein konsistenter Zustand erreicht ist." + +#: utils/misc/guc.c:3881 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "Setzt die Transaktions-ID, bis zu der die Wiederherstellung voranschreiten wird." + +#: utils/misc/guc.c:3890 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "Setzt den Zeitstempel, bis zu dem die Wiederherstellung voranschreiten wird." + +#: utils/misc/guc.c:3899 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "Setzt den benannten Restore-Punkt, bis zu dem die Wiederherstellung voranschreiten wird." + +#: utils/misc/guc.c:3908 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "Setzt die LSN der Write-Ahead-Log-Position, bis zu der die Wiederherstellung voranschreiten wird." + +#: utils/misc/guc.c:3918 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "Gibt einen Dateinamen an, dessen Präsenz die Wiederherstellung im Standby beendet." + +#: utils/misc/guc.c:3928 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "Setzt die Verbindungszeichenkette zur Verbindung mit dem sendenden Server." + +#: utils/misc/guc.c:3939 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "Setzt den Namen des zu verwendenden Replikations-Slots auf dem sendenden Server." + +#: utils/misc/guc.c:3949 +msgid "Sets the client's character set encoding." +msgstr "Setzt die Zeichensatzkodierung des Clients." + +#: utils/misc/guc.c:3960 +msgid "Controls information prefixed to each log line." +msgstr "Bestimmt die Informationen, die vor jede Logzeile geschrieben werden." + +#: utils/misc/guc.c:3961 +msgid "If blank, no prefix is used." +msgstr "Wenn leer, dann wird kein Präfix verwendet." + +#: utils/misc/guc.c:3970 +msgid "Sets the time zone to use in log messages." +msgstr "Setzt die in Logmeldungen verwendete Zeitzone." + +#: utils/misc/guc.c:3980 +msgid "Sets the display format for date and time values." +msgstr "Setzt das Ausgabeformat für Datums- und Zeitwerte." + +#: utils/misc/guc.c:3981 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "Kontrolliert auch die Interpretation von zweideutigen Datumseingaben." + +#: utils/misc/guc.c:3992 +msgid "Sets the default table access method for new tables." +msgstr "Setzt die Standard-Tabellenzugriffsmethode für neue Tabellen." + +#: utils/misc/guc.c:4003 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "Setzt den Standard-Tablespace für Tabellen und Indexe." + +#: utils/misc/guc.c:4004 +msgid "An empty string selects the database's default tablespace." +msgstr "Eine leere Zeichenkette wählt den Standard-Tablespace der Datenbank." + +#: utils/misc/guc.c:4014 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "Setzt den oder die Tablespaces für temporäre Tabellen und Sortierdateien." + +#: utils/misc/guc.c:4025 +msgid "Sets the path for dynamically loadable modules." +msgstr "Setzt den Pfad für ladbare dynamische Bibliotheken." + +#: utils/misc/guc.c:4026 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "Wenn ein dynamisch ladbares Modul geöffnet werden muss und der angegebene Name keine Verzeichniskomponente hat (das heißt er enthält keinen Schrägstrich), dann sucht das System in diesem Pfad nach der angegebenen Datei." + +#: utils/misc/guc.c:4039 +msgid "Sets the location of the Kerberos server key file." +msgstr "Setzt den Ort der Kerberos-Server-Schlüsseldatei." + +#: utils/misc/guc.c:4050 +msgid "Sets the Bonjour service name." +msgstr "Setzt den Bonjour-Servicenamen." + +#: utils/misc/guc.c:4062 +msgid "Shows the collation order locale." +msgstr "Zeigt die Locale für die Sortierreihenfolge." + +#: utils/misc/guc.c:4073 +msgid "Shows the character classification and case conversion locale." +msgstr "Zeigt die Locale für Zeichenklassifizierung und Groß-/Kleinschreibung." + +#: utils/misc/guc.c:4084 +msgid "Sets the language in which messages are displayed." +msgstr "Setzt die Sprache, in der Mitteilungen ausgegeben werden." + +#: utils/misc/guc.c:4094 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Setzt die Locale für die Formatierung von Geldbeträgen." + +#: utils/misc/guc.c:4104 +msgid "Sets the locale for formatting numbers." +msgstr "Setzt die Locale für die Formatierung von Zahlen." + +#: utils/misc/guc.c:4114 +msgid "Sets the locale for formatting date and time values." +msgstr "Setzt die Locale für die Formatierung von Datums- und Zeitwerten." + +#: utils/misc/guc.c:4124 +msgid "Lists shared libraries to preload into each backend." +msgstr "Listet dynamische Bibliotheken, die vorab in jeden Serverprozess geladen werden." + +#: utils/misc/guc.c:4135 +msgid "Lists shared libraries to preload into server." +msgstr "Listet dynamische Bibliotheken, die vorab in den Server geladen werden." + +#: utils/misc/guc.c:4146 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "Listet unprivilegierte dynamische Bibliotheken, die vorab in jeden Serverprozess geladen werden." + +#: utils/misc/guc.c:4157 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "Setzt die Schemasuchreihenfolge für Namen ohne Schemaqualifikation." + +#: utils/misc/guc.c:4169 +#, fuzzy +#| msgid "Sets the server (database) character set encoding." +msgid "Shows the server (database) character set encoding." +msgstr "Setzt die Zeichensatzkodierung des Servers (der Datenbank)." + +#: utils/misc/guc.c:4181 +msgid "Shows the server version." +msgstr "Zeigt die Serverversion." + +#: utils/misc/guc.c:4193 +msgid "Sets the current role." +msgstr "Setzt die aktuelle Rolle." + +#: utils/misc/guc.c:4205 +msgid "Sets the session user name." +msgstr "Setzt den Sitzungsbenutzernamen." + +#: utils/misc/guc.c:4216 +msgid "Sets the destination for server log output." +msgstr "Setzt das Ziel für die Serverlogausgabe." + +#: utils/misc/guc.c:4217 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "Gültige Werte sind Kombinationen von »stderr«, »syslog«, »csvlog« und »eventlog«, je nach Plattform." + +#: utils/misc/guc.c:4228 +msgid "Sets the destination directory for log files." +msgstr "Bestimmt das Zielverzeichnis für Logdateien." + +#: utils/misc/guc.c:4229 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "Kann relativ zum Datenverzeichnis oder als absoluter Pfad angegeben werden." + +#: utils/misc/guc.c:4239 +msgid "Sets the file name pattern for log files." +msgstr "Bestimmt das Dateinamenmuster für Logdateien." + +#: utils/misc/guc.c:4250 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "Setzt den Programmnamen, mit dem PostgreSQL-Meldungen im Syslog identifiziert werden." + +#: utils/misc/guc.c:4261 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "Setzt den Programmnamen, mit dem PostgreSQL-Meldungen im Ereignisprotokoll identifiziert werden." + +#: utils/misc/guc.c:4272 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "Setzt die Zeitzone, in der Zeitangaben interpretiert und ausgegeben werden." + +#: utils/misc/guc.c:4282 +msgid "Selects a file of time zone abbreviations." +msgstr "Wählt eine Datei mit Zeitzonenabkürzungen." + +#: utils/misc/guc.c:4292 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Setzt die Eigentümergruppe der Unix-Domain-Socket." + +#: utils/misc/guc.c:4293 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "Der Eigentümer ist immer der Benutzer, der den Server startet." + +#: utils/misc/guc.c:4303 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Setzt die Verzeichnisse, in denen Unix-Domain-Sockets erzeugt werden sollen." + +#: utils/misc/guc.c:4318 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Setzt den Hostnamen oder die IP-Adresse(n), auf der auf Verbindungen gewartet wird." + +#: utils/misc/guc.c:4333 +msgid "Sets the server's data directory." +msgstr "Setzt das Datenverzeichnis des Servers." + +#: utils/misc/guc.c:4344 +msgid "Sets the server's main configuration file." +msgstr "Setzt die Hauptkonfigurationsdatei des Servers." + +#: utils/misc/guc.c:4355 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Setzt die »hba«-Konfigurationsdatei des Servers." + +#: utils/misc/guc.c:4366 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Setzt die »ident«-Konfigurationsdatei des Servers." + +#: utils/misc/guc.c:4377 +msgid "Writes the postmaster PID to the specified file." +msgstr "Schreibt die Postmaster-PID in die angegebene Datei." + +#: utils/misc/guc.c:4388 +#, fuzzy +#| msgid "Name of the SSL library." +msgid "Shows the name of the SSL library." +msgstr "Name der SSL-Bibliothek." + +#: utils/misc/guc.c:4403 +msgid "Location of the SSL server certificate file." +msgstr "Ort der SSL-Serverzertifikatsdatei." + +#: utils/misc/guc.c:4413 +msgid "Location of the SSL server private key file." +msgstr "Setzt den Ort der Datei mit dem privaten SSL-Server-Schlüssel." + +#: utils/misc/guc.c:4423 +msgid "Location of the SSL certificate authority file." +msgstr "Ort der SSL-Certificate-Authority-Datei." + +#: utils/misc/guc.c:4433 +msgid "Location of the SSL certificate revocation list file." +msgstr "Ort der SSL-Certificate-Revocation-List-Datei." + +#: utils/misc/guc.c:4443 +#, fuzzy +#| msgid "Location of the SSL certificate revocation list file." +msgid "Location of the SSL certificate revocation list directory." +msgstr "Ort der SSL-Certificate-Revocation-List-Datei." + +#: utils/misc/guc.c:4453 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Schreibt temporäre Statistikdateien in das angegebene Verzeichnis." + +#: utils/misc/guc.c:4464 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "Anzahl synchroner Standbys und Liste der Namen der möglichen synchronen Standbys." + +#: utils/misc/guc.c:4475 +msgid "Sets default text search configuration." +msgstr "Setzt die vorgegebene Textsuchekonfiguration." + +#: utils/misc/guc.c:4485 +msgid "Sets the list of allowed SSL ciphers." +msgstr "Setzt die Liste der erlaubten SSL-Verschlüsselungsalgorithmen." + +#: utils/misc/guc.c:4500 +msgid "Sets the curve to use for ECDH." +msgstr "Setzt die für ECDH zu verwendende Kurve." + +#: utils/misc/guc.c:4515 +msgid "Location of the SSL DH parameters file." +msgstr "Setzt den Ort der SSL-DH-Parameter-Datei." + +#: utils/misc/guc.c:4526 +msgid "Command to obtain passphrases for SSL." +msgstr "Befehl zum Einlesen von Passphrasen für SSL." + +#: utils/misc/guc.c:4537 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "Setzt den Anwendungsnamen, der in Statistiken und Logs verzeichnet wird." + +#: utils/misc/guc.c:4548 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Setzt den Namen des Clusters, welcher im Prozesstitel angezeigt wird." + +#: utils/misc/guc.c:4559 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "Setzt die WAL-Resource-Manager, für die WAL-Konsistenzprüfungen durchgeführt werden." + +#: utils/misc/guc.c:4560 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "Volle Seitenabbilder werden für alle Datenblöcke geloggt und gegen die Resultate der WAL-Wiederherstellung geprüft." + +#: utils/misc/guc.c:4570 +msgid "JIT provider to use." +msgstr "Zu verwendender JIT-Provider." + +#: utils/misc/guc.c:4581 +msgid "Log backtrace for errors in these functions." +msgstr "Backtrace für Fehler in diesen Funktionen loggen." + +#: utils/misc/guc.c:4601 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Bestimmt, ob »\\'« in Zeichenkettenkonstanten erlaubt ist." + +#: utils/misc/guc.c:4611 +msgid "Sets the output format for bytea." +msgstr "Setzt das Ausgabeformat für bytea." + +#: utils/misc/guc.c:4621 +msgid "Sets the message levels that are sent to the client." +msgstr "Setzt die Meldungstypen, die an den Client gesendet werden." + +#: utils/misc/guc.c:4622 utils/misc/guc.c:4708 utils/misc/guc.c:4719 +#: utils/misc/guc.c:4795 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "Jeder Wert schließt alle ihm folgenden Werte mit ein. Je weiter hinten der Wert steht, desto weniger Meldungen werden gesendet werden." + +#: utils/misc/guc.c:4632 +#, fuzzy +#| msgid "unterminated quoted identifier" +msgid "Compute query identifiers." +msgstr "Bezeichner in Anführungszeichen nicht abgeschlossen" + +#: utils/misc/guc.c:4642 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "Ermöglicht dem Planer die Verwendung von Constraints, um Anfragen zu optimieren." + +#: utils/misc/guc.c:4643 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "Tabellen-Scans werden übersprungen, wenn deren Constraints garantieren, dass keine Zeile mit der Abfrage übereinstimmt." + +#: utils/misc/guc.c:4654 +#, fuzzy +#| msgid "Sets the default table access method for new tables." +msgid "Sets the default compression method for compressible values." +msgstr "Setzt die Standard-Tabellenzugriffsmethode für neue Tabellen." + +#: utils/misc/guc.c:4665 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Setzt den Transaktionsisolationsgrad neuer Transaktionen." + +#: utils/misc/guc.c:4675 +msgid "Sets the current transaction's isolation level." +msgstr "Zeigt den Isolationsgrad der aktuellen Transaktion." + +#: utils/misc/guc.c:4686 +msgid "Sets the display format for interval values." +msgstr "Setzt das Ausgabeformat für Intervallwerte." + +#: utils/misc/guc.c:4697 +msgid "Sets the verbosity of logged messages." +msgstr "Setzt den Detailgrad von geloggten Meldungen." + +#: utils/misc/guc.c:4707 +msgid "Sets the message levels that are logged." +msgstr "Setzt die Meldungstypen, die geloggt werden." + +#: utils/misc/guc.c:4718 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "Schreibt alle Anweisungen, die einen Fehler auf dieser Stufe oder höher verursachen, in den Log." + +#: utils/misc/guc.c:4729 +msgid "Sets the type of statements logged." +msgstr "Setzt die Anweisungsarten, die geloggt werden." + +#: utils/misc/guc.c:4739 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "Setzt die zu verwendende Syslog-»Facility«, wenn Syslog angeschaltet ist." + +#: utils/misc/guc.c:4754 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "Setzt das Sitzungsverhalten für Trigger und Regeln." + +#: utils/misc/guc.c:4764 +msgid "Sets the current transaction's synchronization level." +msgstr "Setzt den Synchronisationsgrad der aktuellen Transaktion." + +#: utils/misc/guc.c:4774 +msgid "Allows archiving of WAL files using archive_command." +msgstr "Erlaubt die Archivierung von WAL-Dateien mittels archive_command." + +#: utils/misc/guc.c:4784 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "Setzt die Aktion, die beim Erreichen des Wiederherstellungsziels durchgeführt wird." + +#: utils/misc/guc.c:4794 +msgid "Enables logging of recovery-related debugging information." +msgstr "Ermöglicht das Loggen von Debug-Informationen über die Wiederherstellung." + +#: utils/misc/guc.c:4810 +msgid "Collects function-level statistics on database activity." +msgstr "Sammelt Statistiken auf Funktionsebene über Datenbankaktivität." + +#: utils/misc/guc.c:4820 +#, fuzzy +#| msgid "Set the level of information written to the WAL." +msgid "Sets the level of information written to the WAL." +msgstr "Setzt den Umfang der in den WAL geschriebenen Informationen." + +#: utils/misc/guc.c:4830 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Wählt die zu verwendende Implementierung von dynamischem Shared Memory." + +#: utils/misc/guc.c:4840 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "Wählt die Shared-Memory-Implementierung, die für den Haupt-Shared-Memory-Bereich verwendet wird." + +#: utils/misc/guc.c:4850 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "Wählt die Methode, um das Schreiben von WAL-Änderungen auf die Festplatte zu erzwingen." + +#: utils/misc/guc.c:4860 +msgid "Sets how binary values are to be encoded in XML." +msgstr "Setzt, wie binäre Werte in XML kodiert werden." + +#: utils/misc/guc.c:4870 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "Setzt, ob XML-Daten in impliziten Parse- und Serialisierungsoperationen als Dokument oder Fragment betrachtet werden sollen." + +#: utils/misc/guc.c:4881 +msgid "Use of huge pages on Linux or Windows." +msgstr "Huge Pages auf Linux oder Windows verwenden." + +#: utils/misc/guc.c:4891 +msgid "Forces use of parallel query facilities." +msgstr "Verwendung der Einrichtungen für parallele Anfragen erzwingen." + +#: utils/misc/guc.c:4892 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "Wenn möglich werden Anfragen in einem parallelen Arbeitsprozess und mit parallelen Beschränkungen ausgeführt." + +#: utils/misc/guc.c:4902 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "Wählt den Algorithmus zum Verschlüsseln von Passwörtern." + +#: utils/misc/guc.c:4912 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Kontrolliert, ob der Planer einen maßgeschneiderten oder einen allgemeinen Plan verwendet." + +#: utils/misc/guc.c:4913 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "Vorbereitete Anweisungen können maßgeschneiderte oder allgemeine Pläne haben und der Planer wird versuchen, den besseren auszuwählen. Diese Einstellung kann das Standardverhalten außer Kraft setzen." + +#: utils/misc/guc.c:4925 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "Setzt die minimale zu verwendende SSL/TLS-Protokollversion." + +#: utils/misc/guc.c:4937 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "Setzt die maximale zu verwendende SSL/TLS-Protokollversion." + +#: utils/misc/guc.c:4949 +msgid "Sets the method for synchronizing the data directory before crash recovery." +msgstr "" + +#: utils/misc/guc.c:5518 +#, fuzzy, c-format +#| msgid "unrecognized configuration parameter \"%s\"" +msgid "invalid configuration parameter name \"%s\"" +msgstr "unbekannter Konfigurationsparameter »%s«" + +#: utils/misc/guc.c:5520 +#, c-format +msgid "Custom parameter names must be two or more simple identifiers separated by dots." +msgstr "" + +#: utils/misc/guc.c:5529 utils/misc/guc.c:9288 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "unbekannter Konfigurationsparameter »%s«" + +#: utils/misc/guc.c:5822 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: konnte nicht auf Verzeichnis »%s« zugreifen: %s\n" + +#: utils/misc/guc.c:5827 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "Führen Sie initdb oder pg_basebackup aus, um ein PostgreSQL-Datenverzeichnis zu initialisieren.\n" + +#: utils/misc/guc.c:5847 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%s weiß nicht, wo die Serverkonfigurationsdatei zu finden ist.\n" +"Sie müssen die Kommandozeilenoption --config-file oder -D angegeben oder\n" +"die Umgebungsvariable PGDATA setzen.\n" + +#: utils/misc/guc.c:5866 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: konnte nicht auf die Serverkonfigurationsdatei »%s« zugreifen: %s\n" + +#: utils/misc/guc.c:5892 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s weiß nicht, wo die Systemdaten für das Datenbanksystem\n" +"zu finden sind. Sie können dies mit »data_directory« in »%s«, mit der\n" +"Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" + +#: utils/misc/guc.c:5940 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s weiß nicht, wo die »hba«-Konfigurationsdatei zu finden ist.\n" +"Sie können dies mit »hba_file« in »%s«, mit der\n" +"Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" + +#: utils/misc/guc.c:5963 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s weiß nicht, wo die »ident«-Konfigurationsdatei zu finden ist.\n" +"Sie können dies mit »ident_file« in »%s«, mit der\n" +"Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" + +#: utils/misc/guc.c:6888 +msgid "Value exceeds integer range." +msgstr "Wert überschreitet Bereich für ganze Zahlen." + +#: utils/misc/guc.c:7124 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s ist außerhalb des gültigen Bereichs für Parameter »%s« (%d ... %d)" + +#: utils/misc/guc.c:7160 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s ist außerhalb des gültigen Bereichs für Parameter »%s« (%g ... %g)" + +#: utils/misc/guc.c:7320 utils/misc/guc.c:8692 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "während einer parallelen Operation können keine Parameter gesetzt werden" + +#: utils/misc/guc.c:7337 utils/misc/guc.c:8533 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "Parameter »%s« kann nicht geändert werden" + +#: utils/misc/guc.c:7370 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "Parameter »%s« kann jetzt nicht geändert werden" + +#: utils/misc/guc.c:7388 utils/misc/guc.c:7435 utils/misc/guc.c:11333 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "keine Berechtigung, um Parameter »%s« zu setzen" + +#: utils/misc/guc.c:7425 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "Parameter »%s« kann nach Start der Verbindung nicht geändert werden" + +#: utils/misc/guc.c:7473 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "Parameter »%s« kann nicht in einer Security-Definer-Funktion gesetzt werden" + +#: utils/misc/guc.c:8106 utils/misc/guc.c:8153 utils/misc/guc.c:9550 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "nur Superuser oder Mitglieder von pg_read_all_settings können »%s« ansehen" + +#: utils/misc/guc.c:8237 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s darf nur ein Argument haben" + +#: utils/misc/guc.c:8485 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "nur Superuser können den Befehl ALTER SYSTEM ausführen" + +#: utils/misc/guc.c:8566 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "Parameterwert für ALTER SYSTEM darf keine Newline enthalten" + +#: utils/misc/guc.c:8611 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "konnte Inhalt der Datei »%s« nicht parsen" + +#: utils/misc/guc.c:8768 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT ist nicht implementiert" + +#: utils/misc/guc.c:8852 +#, c-format +msgid "SET requires parameter name" +msgstr "SET benötigt Parameternamen" + +#: utils/misc/guc.c:8985 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "Versuch, den Parameter »%s« zu redefinieren" + +#: utils/misc/guc.c:10780 +#, c-format +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "beim Setzen von Parameter »%s« auf »%s«" + +#: utils/misc/guc.c:10945 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "Parameter »%s« kann nicht gesetzt werden" + +#: utils/misc/guc.c:11037 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "konnte Wert von Parameter »%s« nicht lesen" + +#: utils/misc/guc.c:11395 utils/misc/guc.c:11429 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "ungültiger Wert für Parameter »%s«: %d" + +#: utils/misc/guc.c:11463 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "ungültiger Wert für Parameter »%s«: %g" + +#: utils/misc/guc.c:11750 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "»temp_buffers« kann nicht geändert werden, nachdem in der Sitzung auf temporäre Tabellen zugriffen wurde." + +#: utils/misc/guc.c:11762 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour wird von dieser Installation nicht unterstützt" + +#: utils/misc/guc.c:11775 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL wird von dieser Installation nicht unterstützt" + +#: utils/misc/guc.c:11787 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "Kann Parameter nicht einschalten, wenn »log_statement_stats« an ist." + +#: utils/misc/guc.c:11799 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "Kann »log_statement_stats« nicht einschalten, wenn »log_parser_stats«, »log_planner_stats« oder »log_executor_stats« an ist." + +#: utils/misc/guc.c:12029 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "effective_io_concurrency muss auf Plattformen ohne posix_fadvise() auf 0 gesetzt sein." + +#: utils/misc/guc.c:12042 +#, c-format +msgid "maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "maintenance_io_concurrency muss auf Plattformen ohne posix_fadvise() auf 0 gesetzt sein." + +#: utils/misc/guc.c:12056 +#, fuzzy, c-format +#| msgid "huge pages not supported on this platform" +msgid "huge_page_size must be 0 on this platform." +msgstr "Huge Pages werden auf dieser Plattform nicht unterstützt" + +#: utils/misc/guc.c:12070 +#, fuzzy, c-format +#| msgid "maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgid "client_connection_check_interval must be set to 0 on platforms that lack POLLRDHUP." +msgstr "maintenance_io_concurrency muss auf Plattformen ohne posix_fadvise() auf 0 gesetzt sein." + +#: utils/misc/guc.c:12198 +#, c-format +msgid "invalid character" +msgstr "ungültiges Zeichen" + +#: utils/misc/guc.c:12258 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline ist keine gültige Zahl." + +#: utils/misc/guc.c:12298 +#, c-format +msgid "multiple recovery targets specified" +msgstr "mehrere Wiederherstellungsziele angegeben" + +#: utils/misc/guc.c:12299 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr "Höchstens eins aus recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid darf gesetzt sein." + +#: utils/misc/guc.c:12307 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "Der einzige erlaubte Wert ist »immediate«." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "interner Fehler: unbekannter Parametertyp\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "in der Anfrage angegebenes Rückgabetupel und Rückgabetyp der Funktion sind nicht kompatibel" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "berechnete CRC-Prüfsumme stimmt nicht mit dem Wert in der Datei überein" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: Benutzer: %d,%02d s, System: %d,%02d s, verstrichen: %d,%02d s" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "Policy für Sicherheit auf Zeilenebene für Tabelle »%s« würde Auswirkung auf die Anfrage haben" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "Um die Policy für den Tabelleneigentümer zu deaktivieren, verwenden Sie ALTER TABLE NO FORCE ROW LEVEL SECURITY." + +#: utils/misc/timeout.c:484 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "kann keine weiteren Gründe für Zeitüberschreitungen hinzufügen" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "Zeitzonenabkürzung »%s« ist zu lang (maximal %d Zeichen) in Zeitzonendatei »%s«, Zeile %d" + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "Zeitzonenabstand %d ist außerhalb des gültigen Bereichs in Zeitzonendatei »%s«, Zeile %d" + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "fehlende Zeitzonenabkürzung in Zeitzonendatei »%s«, Zeile %d" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "fehlender Zeitzonenabstand in Zeitzonendatei »%s«, Zeile %d" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "ungültige Zahl für Zeitzonenabstand in Zeitzonendatei »%s«, Zeile %d" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "ungültige Syntax in Zeitzonendatei »%s«, Zeile %d" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "Zeitzonenabkürzung »%s« ist mehrfach definiert" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "Eintrag in Zeitzonendatei »%s«, Zeile %d, steht im Konflikt mit Eintrag in Datei »%s«, Zeile %d." + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "ungültiger Zeitzonen-Dateiname »%s«" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "Rekursionsbeschränkung für Zeitzonendatei überschritten in Datei »%s«" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "konnte Zeitzonendatei »%s« nicht lesen: %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "Zeile ist zu lang in Zeitzonendatei »%s«, Zeile %d" + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "@INCLUDE ohne Dateiname in Zeitzonendatei »%s«, Zeile %d" + +#: utils/mmgr/aset.c:477 utils/mmgr/generation.c:235 utils/mmgr/slab.c:237 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Fehler während der Erzeugung des Speicherkontexts »%s«." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1329 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "konnte nicht an dynamische Shared Area anbinden" + +#: utils/mmgr/mcxt.c:889 utils/mmgr/mcxt.c:925 utils/mmgr/mcxt.c:963 +#: utils/mmgr/mcxt.c:1001 utils/mmgr/mcxt.c:1083 utils/mmgr/mcxt.c:1114 +#: utils/mmgr/mcxt.c:1150 utils/mmgr/mcxt.c:1202 utils/mmgr/mcxt.c:1237 +#: utils/mmgr/mcxt.c:1272 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Fehler bei Anfrage mit Größe %zu im Speicherkontext »%s«." + +#: utils/mmgr/mcxt.c:1046 +#, c-format +msgid "logging memory contexts of PID %d" +msgstr "" + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "Cursor »%s« existiert bereits" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "bestehender Cursor »%s« wird geschlossen" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "Portal »%s« kann nicht ausgeführt werden" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "gepinntes Portal »%s« kann nicht gelöscht werden" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "aktives Portal »%s« kann nicht gelöscht werden" + +#: utils/mmgr/portalmem.c:736 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "PREPARE kann nicht in einer Transaktion ausgeführt werden, die einen Cursor mit WITH HOLD erzeugt hat" + +#: utils/mmgr/portalmem.c:1275 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "in einer Cursor-Schleife, die nicht nur liest, können keine Transaktionsbefehle ausgeführt werden" + +#: utils/sort/logtape.c:268 utils/sort/logtape.c:291 +#, c-format +msgid "could not seek to block %ld of temporary file" +msgstr "konnte Positionszeiger in temporärer Datei nicht auf Block %ld setzen" + +#: utils/sort/logtape.c:297 +#, c-format +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "konnte Block %ld von temporärer Datei nicht lesen: es wurden nur %zu von %zu Bytes gelesen" + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 +#: utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 +#: utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "konnte nicht aus temporärer Datei für Shared-Tuplestore lesen" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "unerwarteter Chunk in temporärer Datei für Shared-Tuplestore" + +#: utils/sort/sharedtuplestore.c:569 +#, c-format +msgid "could not seek to block %u in shared tuplestore temporary file" +msgstr "konnte Positionszeiger in temporärer Datei für Shared-Tuplestore nicht auf Block %u setzen" + +#: utils/sort/sharedtuplestore.c:576 +#, c-format +msgid "could not read from shared tuplestore temporary file: read only %zu of %zu bytes" +msgstr "konnte nicht aus temporärer Datei für Shared-Tuplestore lesen: es wurden nur %zu von %zu Bytes gelesen" + +#: utils/sort/tuplesort.c:3216 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "ein externer Sortiervorgang kann nicht mehr als %d Durchgänge haben" + +#: utils/sort/tuplesort.c:4297 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "konnte Unique Index »%s« nicht erstellen" + +#: utils/sort/tuplesort.c:4299 +#, c-format +msgid "Key %s is duplicated." +msgstr "Schlüssel %s ist doppelt vorhanden." + +#: utils/sort/tuplesort.c:4300 +#, c-format +msgid "Duplicate keys exist." +msgstr "Es existieren doppelte Schlüssel." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "konnte Positionszeiger in temporärer Datei für Tuplestore nicht setzen" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 +#: utils/sort/tuplestore.c:1548 +#, c-format +msgid "could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "konnte nicht aus temporärer Datei für Tuplestore lesen: es wurden nur %zu von %zu Bytes gelesen" + +#: utils/time/snapmgr.c:568 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "Die Quelltransaktion läuft nicht mehr." + +#: utils/time/snapmgr.c:1147 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "aus einer Subtransaktion kann kein Snapshot exportiert werden" + +#: utils/time/snapmgr.c:1306 utils/time/snapmgr.c:1311 +#: utils/time/snapmgr.c:1316 utils/time/snapmgr.c:1331 +#: utils/time/snapmgr.c:1336 utils/time/snapmgr.c:1341 +#: utils/time/snapmgr.c:1356 utils/time/snapmgr.c:1361 +#: utils/time/snapmgr.c:1366 utils/time/snapmgr.c:1468 +#: utils/time/snapmgr.c:1484 utils/time/snapmgr.c:1509 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "ungültige Snapshot-Daten in Datei »%s«" + +#: utils/time/snapmgr.c:1403 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "SET TRANSACTION SNAPSHOT muss vor allen Anfragen aufgerufen werden" + +#: utils/time/snapmgr.c:1412 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "eine Snapshot-importierende Transaktion muss Isolationsgrad SERIALIZABLE oder REPEATABLE READ haben" + +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1430 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "ungültiger Snapshot-Bezeichner: »%s«" + +#: utils/time/snapmgr.c:1522 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "eine serialisierbare Transaktion kann keinen Snapshot aus einer nicht-serialisierbaren Transaktion importieren" + +#: utils/time/snapmgr.c:1526 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "eine serialisierbare Transaktion, die nicht im Read-Only-Modus ist, kann keinen Snapshot aus einer Read-Only-Transaktion importieren" + +#: utils/time/snapmgr.c:1541 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "kann keinen Snapshot aus einer anderen Datenbank importieren" diff --git a/src/backend/po/es.po b/src/backend/po/es.po new file mode 100644 index 000000000000..f935c37165ea --- /dev/null +++ b/src/backend/po/es.po @@ -0,0 +1,29284 @@ +# Spanish message translation file for PostgreSQL server +# +# Copyright (c) 2002-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Karim Mribti 2002. +# Alvaro Herrera 2003-2014 +# Jaime Casanova 2005, 2006, 2014 +# Emanuel Calvo Franco 2008 +# +# Glosario: +# +# character carácter +# checksum suma de verificación +# cluster (de la orden cluster) reordenar +# command orden +# to defer postergar +# floating point coma flotante +# foreign-data wrapper conector de datos externos +# to fsync sincronizar (fsync) +# to grant otorgar +# lexeme lexema +# locale configuración regional +# to lock bloquear +# lock (sustantivo) candado +# to obtain a lock bloquear un candado +# malformed mal formado +# mapping mapeo +# operator class clase de operadores +# to overflow desbordar +# parser analizador sintáctico +# to parse interpretar +# partition bound borde de partición +# partition key llave de particionamiento +# permission denied permiso denegado +# to poll monitorear +# privilege privilegio +# to revoke revocar +# row registro, fila +# row type tipo de registro +# rule regla de reescritura +# schema esquema +# to skip ignorar +# trigger disparador +# window function función de ventana deslizante +# +# FIXME varios: +# * "port" se traduce en forma inconsistente; corregir +# * "window function" probablemente debería ser "función de ventana deslizante" +# * buscar un término mejor que "Entrada" para traducir "entry" (elemento?) +# * traducimos "large object" como "objeto grande". ¿debería dejarse sin traducir? +# * "concurrently" -> "por una transacción concurrente". Discutible ... +# * "standby" -> ?? +# * "timeline" -> ?? +# * "restartpoint" -> ?? +# * "whole-row" -> ?? +# * "range type" -> "tipo de rango" +# * "range canonical function" -> "función canónica del rango" +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL server 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-11 16:40+0000\n" +"PO-Revision-Date: 2021-06-21 12:29+0200\n" +"Last-Translator: Álvaro Herrera \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 +#: ../common/config_info.c:150 ../common/config_info.c:158 +#: ../common/config_info.c:166 ../common/config_info.c:174 +#: ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "no registrado" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 +#: commands/copyfrom.c:1516 commands/extension.c:3455 utils/adt/genfile.c:128 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 +#: access/transam/timeline.c:143 access/transam/timeline.c:362 +#: access/transam/twophase.c:1271 access/transam/xlog.c:3547 +#: access/transam/xlog.c:4772 access/transam/xlog.c:11338 +#: access/transam/xlog.c:11351 access/transam/xlog.c:11804 +#: access/transam/xlog.c:11884 access/transam/xlog.c:11921 +#: access/transam/xlog.c:11981 access/transam/xlogfuncs.c:703 +#: access/transam/xlogfuncs.c:722 commands/extension.c:3465 libpq/hba.c:534 +#: replication/basebackup.c:2020 replication/logical/origin.c:729 +#: replication/logical/origin.c:765 replication/logical/reorderbuffer.c:4880 +#: replication/logical/snapbuild.c:1733 replication/logical/snapbuild.c:1775 +#: replication/logical/snapbuild.c:1802 replication/slot.c:1725 +#: replication/slot.c:1766 replication/walsender.c:544 +#: storage/file/buffile.c:445 storage/file/copydir.c:195 +#: utils/adt/genfile.c:202 utils/adt/misc.c:859 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 +#: access/transam/xlog.c:3552 access/transam/xlog.c:4777 +#: replication/basebackup.c:2024 replication/logical/origin.c:734 +#: replication/logical/origin.c:773 replication/logical/snapbuild.c:1738 +#: replication/logical/snapbuild.c:1780 replication/logical/snapbuild.c:1807 +#: replication/slot.c:1729 replication/slot.c:1770 replication/walsender.c:549 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 +#: ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 +#: access/heap/rewriteheap.c:1185 access/heap/rewriteheap.c:1288 +#: access/transam/timeline.c:392 access/transam/timeline.c:438 +#: access/transam/timeline.c:516 access/transam/twophase.c:1283 +#: access/transam/twophase.c:1680 access/transam/xlog.c:3419 +#: access/transam/xlog.c:3587 access/transam/xlog.c:3592 +#: access/transam/xlog.c:3920 access/transam/xlog.c:4742 +#: access/transam/xlog.c:5667 access/transam/xlogfuncs.c:728 +#: commands/copyfrom.c:1576 commands/copyto.c:328 libpq/be-fsstubs.c:462 +#: libpq/be-fsstubs.c:533 replication/logical/origin.c:667 +#: replication/logical/origin.c:806 replication/logical/reorderbuffer.c:4938 +#: replication/logical/snapbuild.c:1642 replication/logical/snapbuild.c:1815 +#: replication/slot.c:1616 replication/slot.c:1777 replication/walsender.c:559 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:738 +#: storage/file/fd.c:3534 storage/file/fd.c:3637 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "discordancia en orden de bytes" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"posible discordancia en orden de bytes\n" +"El ordenamiento de bytes usado para almacenar el archivo pg_control puede no\n" +"coincidir con el usado por este programa. En tal caso los resultados de abajo\n" +"serían erróneos, y la instalación de PostgreSQL sería incompatible con este\n" +"directorio de datos." + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 +#: ../common/file_utils.c:232 ../common/file_utils.c:291 +#: ../common/file_utils.c:365 access/heap/rewriteheap.c:1271 +#: access/transam/timeline.c:111 access/transam/timeline.c:251 +#: access/transam/timeline.c:348 access/transam/twophase.c:1227 +#: access/transam/xlog.c:3305 access/transam/xlog.c:3461 +#: access/transam/xlog.c:3502 access/transam/xlog.c:3700 +#: access/transam/xlog.c:3785 access/transam/xlog.c:3888 +#: access/transam/xlog.c:4762 access/transam/xlogutils.c:803 +#: postmaster/syslogger.c:1488 replication/basebackup.c:616 +#: replication/basebackup.c:1610 replication/logical/origin.c:719 +#: replication/logical/reorderbuffer.c:3548 +#: replication/logical/reorderbuffer.c:4095 +#: replication/logical/reorderbuffer.c:4860 +#: replication/logical/snapbuild.c:1597 replication/logical/snapbuild.c:1704 +#: replication/slot.c:1697 replication/walsender.c:517 +#: replication/walsender.c:2526 storage/file/copydir.c:161 +#: storage/file/fd.c:713 storage/file/fd.c:3521 storage/file/fd.c:3608 +#: storage/smgr/md.c:502 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1938 +#: utils/init/miscinit.c:1346 utils/init/miscinit.c:1480 +#: utils/init/miscinit.c:1557 utils/misc/guc.c:8604 utils/misc/guc.c:8636 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 +#: access/transam/twophase.c:1653 access/transam/twophase.c:1662 +#: access/transam/xlog.c:11095 access/transam/xlog.c:11133 +#: access/transam/xlog.c:11546 access/transam/xlogfuncs.c:782 +#: postmaster/postmaster.c:5659 postmaster/syslogger.c:1499 +#: postmaster/syslogger.c:1512 utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 +#: ../common/file_utils.c:303 ../common/file_utils.c:373 +#: access/heap/rewriteheap.c:967 access/heap/rewriteheap.c:1179 +#: access/heap/rewriteheap.c:1282 access/transam/timeline.c:432 +#: access/transam/timeline.c:510 access/transam/twophase.c:1674 +#: access/transam/xlog.c:3412 access/transam/xlog.c:3581 +#: access/transam/xlog.c:4735 access/transam/xlog.c:10586 +#: access/transam/xlog.c:10627 replication/logical/snapbuild.c:1635 +#: replication/slot.c:1602 replication/slot.c:1707 storage/file/fd.c:730 +#: storage/file/fd.c:3629 storage/smgr/md.c:950 storage/smgr/md.c:991 +#: storage/sync/sync.c:417 utils/cache/relmapper.c:885 utils/misc/guc.c:8391 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" + +#: ../common/cryptohash_openssl.c:104 ../common/exec.c:522 ../common/exec.c:567 +#: ../common/exec.c:659 ../common/hmac_openssl.c:103 ../common/psprintf.c:143 +#: ../common/stringinfo.c:305 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1341 access/transam/xlog.c:6633 +#: lib/dshash.c:246 libpq/auth.c:1482 libpq/auth.c:1550 libpq/auth.c:2108 +#: libpq/be-secure-gssapi.c:520 postmaster/bgworker.c:349 +#: postmaster/bgworker.c:948 postmaster/postmaster.c:2516 +#: postmaster/postmaster.c:4175 postmaster/postmaster.c:4845 +#: postmaster/postmaster.c:5584 postmaster/postmaster.c:5948 +#: replication/libpqwalreceiver/libpqwalreceiver.c:282 +#: replication/logical/logical.c:205 replication/walsender.c:591 +#: storage/buffer/localbuf.c:442 storage/file/fd.c:882 storage/file/fd.c:1352 +#: storage/file/fd.c:1513 storage/file/fd.c:2321 storage/ipc/procarray.c:1388 +#: storage/ipc/procarray.c:2182 storage/ipc/procarray.c:2189 +#: storage/ipc/procarray.c:2678 storage/ipc/procarray.c:3302 +#: utils/adt/cryptohashfuncs.c:46 utils/adt/cryptohashfuncs.c:66 +#: utils/adt/formatting.c:1699 utils/adt/formatting.c:1823 +#: utils/adt/formatting.c:1948 utils/adt/pg_locale.c:450 +#: utils/adt/pg_locale.c:614 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:513 utils/hash/dynahash.c:613 +#: utils/hash/dynahash.c:1116 utils/mb/mbutils.c:401 utils/mb/mbutils.c:429 +#: utils/mb/mbutils.c:814 utils/mb/mbutils.c:841 utils/misc/guc.c:5035 +#: utils/misc/guc.c:5051 utils/misc/guc.c:5064 utils/misc/guc.c:8369 +#: utils/misc/tzparser.c:467 utils/mmgr/aset.c:476 utils/mmgr/dsa.c:701 +#: utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:234 +#: utils/mmgr/mcxt.c:888 utils/mmgr/mcxt.c:924 utils/mmgr/mcxt.c:962 +#: utils/mmgr/mcxt.c:1000 utils/mmgr/mcxt.c:1082 utils/mmgr/mcxt.c:1113 +#: utils/mmgr/mcxt.c:1149 utils/mmgr/mcxt.c:1201 utils/mmgr/mcxt.c:1236 +#: utils/mmgr/mcxt.c:1271 utils/mmgr/slab.c:236 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" + +#: ../common/exec.c:136 ../common/exec.c:253 ../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "el binario «%s» no es válido" + +#: ../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "no se pudo leer el binario «%s»" + +#: ../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "no se pudo encontrar un «%s» para ejecutar" + +#: ../common/exec.c:269 ../common/exec.c:308 utils/init/miscinit.c:425 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: ../common/exec.c:286 access/transam/xlog.c:10969 +#: replication/basebackup.c:1428 utils/adt/misc.c:340 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" + +#: ../common/exec.c:409 libpq/pqcomm.c:746 storage/ipc/latch.c:1064 +#: storage/ipc/latch.c:1233 storage/ipc/latch.c:1462 storage/ipc/latch.c:1614 +#: storage/ipc/latch.c:1730 +#, fuzzy, c-format +#| msgid "%s failed: %m" +msgid "%s() failed: %m" +msgstr "%s falló: %m" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 +#: ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 +#: ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 +#: utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../common/file_utils.c:87 ../common/file_utils.c:451 +#: ../common/file_utils.c:455 access/transam/twophase.c:1239 +#: access/transam/xlog.c:11071 access/transam/xlog.c:11109 +#: access/transam/xlog.c:11326 access/transam/xlogarchive.c:110 +#: access/transam/xlogarchive.c:227 commands/copyfrom.c:1526 +#: commands/copyto.c:734 commands/extension.c:3444 commands/tablespace.c:807 +#: commands/tablespace.c:898 guc-file.l:1060 replication/basebackup.c:439 +#: replication/basebackup.c:622 replication/basebackup.c:698 +#: replication/logical/snapbuild.c:1514 storage/file/copydir.c:68 +#: storage/file/copydir.c:107 storage/file/fd.c:1863 storage/file/fd.c:1949 +#: storage/file/fd.c:3149 storage/file/fd.c:3353 utils/adt/dbsize.c:70 +#: utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 utils/adt/genfile.c:418 +#: utils/adt/genfile.c:644 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: ../common/file_utils.c:166 ../common/pgfnames.c:48 commands/tablespace.c:730 +#: commands/tablespace.c:740 postmaster/postmaster.c:1515 +#: storage/file/fd.c:2724 storage/file/reinit.c:122 utils/adt/misc.c:262 +#: utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: ../common/file_utils.c:200 ../common/pgfnames.c:69 storage/file/fd.c:2736 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" + +#: ../common/file_utils.c:383 access/transam/xlogarchive.c:412 +#: postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1654 +#: replication/slot.c:668 replication/slot.c:1488 replication/slot.c:1630 +#: storage/file/fd.c:748 storage/file/fd.c:846 utils/time/snapmgr.c:1265 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "no se pudo renombrar el archivo de «%s» a «%s»: %m" + +#: ../common/hex.c:54 +#, fuzzy, c-format +#| msgid "invalid hexadecimal digit: \"%c\"" +msgid "invalid hexadecimal digit" +msgstr "el dígito hexadecimal no es válido: «%c»" + +#: ../common/hex.c:59 +#, fuzzy, c-format +#| msgid "invalid hexadecimal digit: \"%c\"" +msgid "invalid hexadecimal digit: \"%.*s\"" +msgstr "el dígito hexadecimal no es válido: «%c»" + +#: ../common/hex.c:90 +#, c-format +msgid "overflow of destination buffer in hex encoding" +msgstr "" + +#: ../common/hex.c:136 ../common/hex.c:141 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "el dato hexadecimal no es válido: tiene un número impar de dígitos" + +#: ../common/hex.c:152 +#, c-format +msgid "overflow of destination buffer in hex decoding" +msgstr "" + +#: ../common/jsonapi.c:1066 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "La secuencia de escape «%s» no es válida." + +#: ../common/jsonapi.c:1069 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Los caracteres con valor 0x%02x deben ser escapados" + +#: ../common/jsonapi.c:1072 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Se esperaba el fin de la entrada, se encontró «%s»." + +#: ../common/jsonapi.c:1075 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Se esperaba un elemento de array o «]», se encontró «%s»." + +#: ../common/jsonapi.c:1078 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Se esperaba «,» o «]», se encontró «%s»." + +#: ../common/jsonapi.c:1081 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Se esperaba «:», se encontró «%s»." + +#: ../common/jsonapi.c:1084 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Se esperaba un valor JSON, se encontró «%s»." + +#: ../common/jsonapi.c:1087 +msgid "The input string ended unexpectedly." +msgstr "La cadena de entrada terminó inesperadamente." + +#: ../common/jsonapi.c:1089 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Se esperaba una cadena o «}», se encontró «%s»." + +#: ../common/jsonapi.c:1092 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Se esperaba «,» o «}», se encontró «%s»." + +#: ../common/jsonapi.c:1095 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Se esperaba una cadena, se encontró «%s»." + +#: ../common/jsonapi.c:1098 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "El elemento «%s» no es válido." + +#: ../common/jsonapi.c:1101 jsonpath_scan.l:499 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 no puede ser convertido a text." + +#: ../common/jsonapi.c:1103 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "«\\u» debe ser seguido por cuatro dígitos hexadecimales." + +#: ../common/jsonapi.c:1106 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Los valores de escape Unicode no se pueden utilizar para valores de código superiores a 007F cuando la codificación no es UTF8." + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:520 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Un «high-surrogate» Unicode no puede venir después de un «high-surrogate»." + +#: ../common/jsonapi.c:1110 jsonpath_scan.l:531 jsonpath_scan.l:541 +#: jsonpath_scan.l:583 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Un «low-surrogate» Unicode debe seguir a un «high-surrogate»." + +#: ../common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "nombre de «fork» no válido" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Los nombres de «fork» válidos son «main», «fsm», «vm» e «init»." + +#: ../common/restricted_token.c:64 libpq/auth.c:1512 libpq/auth.c:2544 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "no se pudo cargar la biblioteca «%s»: código de error %lu" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "no se pueden crear tokens restrigidos en esta plataforma: código de error %lu" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "no se pudo abrir el token de proceso: código de error %lu" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "no se pudo emplazar los SIDs: código de error %lu" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "no se pudo crear el token restringido: código de error %lu" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "no se pudo iniciar el proceso para la orden «%s»: código de error %lu" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "no se pudo re-ejecutar con el token restringido: código de error %lu" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "no se pudo obtener el código de salida del subproceso»: código de error %lu" + +#: ../common/rmtree.c:79 replication/basebackup.c:1181 +#: replication/basebackup.c:1357 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "no se pudo hacer stat al archivo o directorio «%s»: %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "no se pudo borrar el archivo o el directorio «%s»: %m" + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "No se puede agrandar el búfer de cadena que ya tiene %d bytes en %d bytes adicionales." + +#: ../common/stringinfo.c:310 +#, c-format +msgid "" +"out of memory\n" +"\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "" +"memoria agotada\n" +"\n" +"No se puede agrandar el búfer de cadena que ya tiene %d bytes en %d bytes adicionales.\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "no se pudo encontrar el ID de usuario efectivo %ld: %s" + +#: ../common/username.c:45 libpq/auth.c:2044 +msgid "user does not exist" +msgstr "usuario no existe" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "fallo en la búsqueda de nombre de usuario: código de error %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "la orden no es ejecutable" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "orden no encontrada" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "el proceso hijo terminó con código de salida %d" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "el proceso hijo fue terminado por una excepción 0x%X" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "el proceso hijo terminó con código %d no reconocido" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "no se pudo determinar la codificación para el codeset «%s»" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "no se pudo determinar la codificación para la configuración regional «%s»: el codeset es «%s»" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "no se pudo definir un junction para «%s»: %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "no se pudo definir un junction para «%s»: %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "no se pudo obtener junction para «%s»: %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "no se pudo obtener junction para «%s»: %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "no se pudo abrir el archivo «%s»: %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "infracción de bloqueo (locking violation)" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "infracción de uso compartido (sharing violation)" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "Reintentando durante 30 segundos." + +#: ../port/open.c:129 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "Es posible que tenga antivirus, sistema de respaldos, o software similar interfiriendo con el sistema de bases de datos." + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "no se pudo obtener el directorio de trabajo actual: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "error %d de sistema operativo" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "no se pudo obtener el SID del grupo Administrators: código de error %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "no se pudo obtener el SID del grupo PowerUsers: código de error %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "no se pudo verificar el token de proceso: código de error %lu\n" + +#: access/brin/brin.c:214 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "petición para sumarización BRIN de rango para el índice «%s» página %u no fue registrada" + +#: access/brin/brin.c:1015 access/brin/brin.c:1092 access/gin/ginfast.c:1035 +#: access/transam/xlog.c:10748 access/transam/xlog.c:11277 +#: access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 +#: access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 +#: access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 +#: access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "la recuperación está en proceso" + +#: access/brin/brin.c:1016 access/brin/brin.c:1093 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Las funciones de control de BRIN no pueden ejecutarse durante la recuperación." + +#: access/brin/brin.c:1024 access/brin/brin.c:1101 +#, c-format +msgid "block number out of range: %s" +msgstr "número de bloque fuera de rango: %s" + +#: access/brin/brin.c:1047 access/brin/brin.c:1124 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "«%s» no es un índice BRIN" + +#: access/brin/brin.c:1063 access/brin/brin.c:1140 +#, fuzzy, c-format +#| msgid "could not open parent table of index %s" +msgid "could not open parent table of index \"%s\"" +msgstr "no se pudo abrir la tabla padre del índice %s" + +#: access/brin/brin_bloom.c:751 access/brin/brin_bloom.c:793 +#: access/brin/brin_minmax_multi.c:2987 access/brin/brin_minmax_multi.c:3130 +#: statistics/dependencies.c:651 statistics/dependencies.c:704 +#: statistics/mcv.c:1483 statistics/mcv.c:1514 statistics/mvdistinct.c:343 +#: statistics/mvdistinct.c:396 utils/adt/pseudotypes.c:43 +#: utils/adt/pseudotypes.c:77 utils/adt/pseudotypes.c:252 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "no se puede aceptar un valor de tipo %s" + +#: access/brin/brin_minmax_multi.c:2146 access/brin/brin_minmax_multi.c:2153 +#: access/brin/brin_minmax_multi.c:2160 utils/adt/timestamp.c:941 +#: utils/adt/timestamp.c:1515 utils/adt/timestamp.c:1982 +#: utils/adt/timestamp.c:3059 utils/adt/timestamp.c:3064 +#: utils/adt/timestamp.c:3069 utils/adt/timestamp.c:3119 +#: utils/adt/timestamp.c:3126 utils/adt/timestamp.c:3133 +#: utils/adt/timestamp.c:3153 utils/adt/timestamp.c:3160 +#: utils/adt/timestamp.c:3167 utils/adt/timestamp.c:3197 +#: utils/adt/timestamp.c:3205 utils/adt/timestamp.c:3249 +#: utils/adt/timestamp.c:3676 utils/adt/timestamp.c:3801 +#: utils/adt/timestamp.c:4349 +#, c-format +msgid "interval out of range" +msgstr "interval fuera de rango" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 +#: access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1441 access/spgist/spgdoinsert.c:2000 +#: access/spgist/spgdoinsert.c:2275 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "el tamaño de fila de índice %zu excede el máximo %zu para el índice «%s»" + +#: access/brin/brin_revmap.c:393 access/brin/brin_revmap.c:399 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "índice BRIN corrompido: mapa de rango inconsistente" + +#: access/brin/brin_revmap.c:602 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "tipo de página 0x%04X inesperado en el índice BRIN «%s» bloque %u" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 +#: access/gist/gistvalidate.c:153 access/hash/hashvalidate.c:139 +#: access/nbtree/nbtvalidate.c:120 access/spgist/spgvalidate.c:189 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "familia de operadores «%s» de método de acceso %s contiene la función %s con número de soporte %d no válido" + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 +#: access/gist/gistvalidate.c:165 access/hash/hashvalidate.c:118 +#: access/nbtree/nbtvalidate.c:132 access/spgist/spgvalidate.c:201 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "familia de operadores «%s» de método de acceso %s contiene la función %s con signatura incorrecta para el número de soporte %d" + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 +#: access/gist/gistvalidate.c:185 access/hash/hashvalidate.c:160 +#: access/nbtree/nbtvalidate.c:152 access/spgist/spgvalidate.c:221 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "familia de operadores «%s» de método de acceso %s contiene el operador %s con número de estrategia %d no válido" + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 +#: access/hash/hashvalidate.c:173 access/nbtree/nbtvalidate.c:165 +#: access/spgist/spgvalidate.c:237 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "familia de operadores «%s» de método de acceso %s contiene especificación ORDER BY no válida para el operador %s" + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 +#: access/gist/gistvalidate.c:233 access/hash/hashvalidate.c:186 +#: access/nbtree/nbtvalidate.c:178 access/spgist/spgvalidate.c:253 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "familia de operadores «%s» de método de acceso %s contiene el operador %s con signatura incorrecta" + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:226 +#: access/nbtree/nbtvalidate.c:236 access/spgist/spgvalidate.c:280 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "el/los operador(es) para los tipos %3$s y %4$s faltan de la familia de operadores «%1$s» de método de acceso %2$s" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "la(s) función/funciones de soporte para los tipos %3$s y %4$s faltan de la familia de operadores «%1$s» de método de acceso %2$s" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:240 +#: access/nbtree/nbtvalidate.c:260 access/spgist/spgvalidate.c:315 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "faltan operadores de la clase de operadores «%s» del método de acceso %s" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 +#: access/gist/gistvalidate.c:274 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "falta la función de soporte %3$d de la clase de operadores «%1$s» del método de acceso %2$s" + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "El tipo retornado %s no coincide con el tipo de registro esperado %s en la columna %d." + +#: access/common/attmap.c:150 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "La cantidad de columnas retornadas (%d) no coincide con la cantidad esperada de columnas (%d)." + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "no se pudo convertir el tipo de registro" + +#: access/common/attmap.c:230 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "El atributo «%s» de tipo %s no coincide con el atributo correspondiente de tipo %s." + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "El atributo «%s» de tipo %s no existe en el tipo %s." + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "el número de columnas (%d) excede el límite (%d)" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "el número de columnas del índice (%d) excede el límite (%d)" + +#: access/common/indextuple.c:190 access/spgist/spgutils.c:947 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "fila de índice requiere %zu bytes, tamaño máximo es %zu" + +#: access/common/printtup.c:292 tcop/fastpath.c:106 tcop/fastpath.c:453 +#: tcop/postgres.c:1900 +#, c-format +msgid "unsupported format code: %d" +msgstr "código de formato no soportado: %d" + +#: access/common/reloptions.c:506 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Los valores aceptables son «on», «off» y «auto»." + +#: access/common/reloptions.c:517 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "Los valores aceptables son «local» y «cascaded»." + +#: access/common/reloptions.c:665 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "el límite de tipos de parámetros de relación definidos por el usuario ha sido excedido" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESET no debe incluir valores de parámetros" + +#: access/common/reloptions.c:1240 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "espacio de nombre de parámetro «%s» no reconocido" + +#: access/common/reloptions.c:1277 utils/misc/guc.c:12514 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "las tablas declaradas WITH OIDS no está soportado" + +#: access/common/reloptions.c:1447 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "parámetro «%s» no reconocido" + +#: access/common/reloptions.c:1559 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "el parámetro «%s» fue especificado más de una vez" + +#: access/common/reloptions.c:1575 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "valor no válido para la opción booleana «%s»: «%s»" + +#: access/common/reloptions.c:1587 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "valor no válido para la opción entera «%s»: «%s»" + +#: access/common/reloptions.c:1593 access/common/reloptions.c:1613 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "el valor %s está fuera del rango de la opción «%s»" + +#: access/common/reloptions.c:1595 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Los valores aceptables están entre «%d» y «%d»." + +#: access/common/reloptions.c:1607 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "valor no válido para la opción de coma flotante «%s»: «%s»" + +#: access/common/reloptions.c:1615 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Valores aceptables están entre «%f» y «%f»." + +#: access/common/reloptions.c:1637 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "valor no válido para la opción enum «%s»: %s" + +#: access/common/toast_compression.c:32 +#, fuzzy, c-format +#| msgid "unlink not supported with compression" +msgid "unsupported LZ4 compression method" +msgstr "unlink no soportado con compresión" + +#: access/common/toast_compression.c:33 +#, fuzzy, c-format +#| msgid "This functionality requires the server to be built with libxml support." +msgid "This functionality requires the server to be built with lz4 support." +msgstr "Esta funcionalidad requiere que el servidor haya sido construido con soporte libxml." + +#: access/common/toast_compression.c:34 utils/adt/pg_locale.c:1589 +#: utils/adt/xml.c:224 +#, fuzzy, c-format +#| msgid "You need to rebuild PostgreSQL using --with-icu." +msgid "You need to rebuild PostgreSQL using %s." +msgstr "Necesita reconstruir PostgreSQL usando --with-icu." + +#: access/common/tupdesc.c:825 parser/parse_clause.c:771 +#: parser/parse_relation.c:1838 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "la columna «%s» no puede ser declarada SETOF" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "la «posting list» es demasiado larga" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "Reduzca maintenance_work_mem." + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "La lista de pendientes GIN no puede limpiarse durante la recuperación." + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "«%s» no es un índice GIN" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "no se pueden acceder índices temporales de otras sesiones" + +#: access/gin/ginget.c:270 access/nbtree/nbtinsert.c:759 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "no se pudo volver a encontrar la tupla dentro del índice «%s»" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "los índices GIN antiguos no soportan recorridos del índice completo ni búsquedas de nulos" + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "Para corregir esto, ejecute REINDEX INDEX \"%s\"." + +#: access/gin/ginutil.c:145 executor/execExpr.c:2166 +#: utils/adt/arrayfuncs.c:3818 utils/adt/arrayfuncs.c:6452 +#: utils/adt/rowtypes.c:957 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "no se pudo identificar una función de comparación para el tipo %s" + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:102 access/spgist/spgvalidate.c:102 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "la familia de operadores «%s» del método de acceso %s contiene el procedimiento de soporte %s registrado entre tipos distintos" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "falta la función de soporte %3$d o %4$d de la clase de operadores «%1$s» del método de accesso %2$s" + +#: access/gin/ginvalidate.c:333 access/gist/gistvalidate.c:350 +#: access/spgist/spgvalidate.c:387 +#, fuzzy, c-format +#| msgid "operator family %s for access method %s" +msgid "support function number %d is invalid for access method %s" +msgstr "familia de operadores %s para el método de acceso %s" + +#: access/gist/gist.c:758 access/gist/gistvacuum.c:420 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "el índice «%s» contiene una tupla interna marcada como no válida" + +#: access/gist/gist.c:760 access/gist/gistvacuum.c:422 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "Esto es causado por una división de página incompleta durante una recuperación antes de actualizar a PostgreSQL 9.1." + +#: access/gist/gist.c:761 access/gist/gistutil.c:801 access/gist/gistutil.c:812 +#: access/gist/gistvacuum.c:423 access/hash/hashutil.c:227 +#: access/hash/hashutil.c:238 access/hash/hashutil.c:250 +#: access/hash/hashutil.c:271 access/nbtree/nbtpage.c:810 +#: access/nbtree/nbtpage.c:821 +#, c-format +msgid "Please REINDEX it." +msgstr "Por favor aplíquele REINDEX." + +#: access/gist/gist.c:1175 +#, fuzzy, c-format +#| msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgid "fixing incomplete split in index \"%s\", block %u" +msgstr "tipo de página 0x%04X inesperado en el índice BRIN «%s» bloque %u" + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "el método picksplit para la columna %d del índice «%s» falló" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "El índice no es óptimo. Para optimizarlo, contacte un desarrollador o trate de usar la columna en segunda posición en la orden CREATE INDEX." + +#: access/gist/gistutil.c:798 access/hash/hashutil.c:224 +#: access/nbtree/nbtpage.c:807 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "índice «%s» contiene páginas vacías no esperadas en el bloque %u" + +#: access/gist/gistutil.c:809 access/hash/hashutil.c:235 +#: access/hash/hashutil.c:247 access/nbtree/nbtpage.c:818 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "el índice «%s» contiene una página corrupta en el bloque %u" + +#: access/gist/gistvalidate.c:203 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "la familia de operadores «%s» del método de acceso %s contiene una especificación ORDER BY no soportada para el operador %s" + +#: access/gist/gistvalidate.c:214 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "la familia de operadores «%s» del método de acceso %s contiene una especificación de familia en ORDER BY incorrecta para el operador %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "no se pudo determinar qué ordenamiento usar para el hashing de cadenas" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:713 +#: catalog/heap.c:719 commands/createas.c:206 commands/createas.c:509 +#: commands/indexcmds.c:1869 commands/tablecmds.c:16795 commands/view.c:86 +#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1666 +#: utils/adt/formatting.c:1790 utils/adt/formatting.c:1915 utils/adt/like.c:194 +#: utils/adt/like_support.c:1003 utils/adt/varchar.c:733 +#: utils/adt/varchar.c:994 utils/adt/varchar.c:1054 utils/adt/varlena.c:1524 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Use la cláusula COLLATE para establecer el ordenamiento explícitamente." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "el tamaño de fila de índice %zu excede el máximo para hash %zu" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:2004 +#: access/spgist/spgdoinsert.c:2279 access/spgist/spgutils.c:1008 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Valores mayores a una página del buffer no pueden ser indexados." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "número no válido de bloque de «overflow» %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "se agotaron las páginas de desbordamiento en el índice hash «%s»" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "los índices hash no soportan recorridos del índice completo" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "el índice «%s» no es un índice hash" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "el índice «%s» tiene una versión de hash incorrecta" + +#: access/hash/hashvalidate.c:198 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "la familia de operadores «%s» del método de acceso %s no tiene función de soporte para el operador %s" + +#: access/hash/hashvalidate.c:256 access/nbtree/nbtvalidate.c:276 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "faltan operadores entre tipos en la familia de operadores «%s» del método de acceso %s" + +#: access/heap/heapam.c:2260 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "no se pueden insertar tuplas en un ayudante paralelo" + +#: access/heap/heapam.c:2731 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "no se pueden eliminar tuplas durante una operación paralela" + +#: access/heap/heapam.c:2777 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "se intentó eliminar una tupla invisible" + +#: access/heap/heapam.c:3209 access/heap/heapam.c:6010 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "no se pueden actualizar tuplas durante una operación paralela" + +#: access/heap/heapam.c:3342 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "se intentó actualizar una tupla invisible" + +#: access/heap/heapam.c:4663 access/heap/heapam.c:4701 +#: access/heap/heapam.c:4957 access/heap/heapam_handler.c:454 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "no se pudo bloquear un candado en la fila de la relación «%s»" + +#: access/heap/heapam_handler.c:403 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "el registro a ser bloqueado ya fue movido a otra partición por un update concurrente" + +#: access/heap/hio.c:360 access/heap/rewriteheap.c:665 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "fila es demasiado grande: tamaño %zu, tamaño máximo %zu" + +#: access/heap/rewriteheap.c:927 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "no se pudo escribir al archivo «%s», se escribió %d de %d: %m" + +#: access/heap/rewriteheap.c:1020 access/heap/rewriteheap.c:1138 +#: access/transam/timeline.c:329 access/transam/timeline.c:485 +#: access/transam/xlog.c:3328 access/transam/xlog.c:3516 +#: access/transam/xlog.c:4714 access/transam/xlog.c:11086 +#: access/transam/xlog.c:11124 access/transam/xlog.c:11529 +#: access/transam/xlogfuncs.c:776 postmaster/postmaster.c:4600 +#: postmaster/postmaster.c:5646 replication/logical/origin.c:587 +#: replication/slot.c:1549 storage/file/copydir.c:167 storage/smgr/md.c:218 +#: utils/time/snapmgr.c:1244 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "no se pudo crear archivo «%s»: %m" + +#: access/heap/rewriteheap.c:1148 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "no se pudo truncar el archivo «%s» a %u: %m" + +#: access/heap/rewriteheap.c:1166 access/transam/timeline.c:384 +#: access/transam/timeline.c:424 access/transam/timeline.c:502 +#: access/transam/xlog.c:3400 access/transam/xlog.c:3572 +#: access/transam/xlog.c:4726 postmaster/postmaster.c:4610 +#: postmaster/postmaster.c:4620 replication/logical/origin.c:599 +#: replication/logical/origin.c:641 replication/logical/origin.c:660 +#: replication/logical/snapbuild.c:1611 replication/slot.c:1584 +#: storage/file/buffile.c:506 storage/file/copydir.c:207 +#: utils/init/miscinit.c:1421 utils/init/miscinit.c:1432 +#: utils/init/miscinit.c:1440 utils/misc/guc.c:8352 utils/misc/guc.c:8383 +#: utils/misc/guc.c:10292 utils/misc/guc.c:10306 utils/time/snapmgr.c:1249 +#: utils/time/snapmgr.c:1256 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "no se pudo escribir a archivo «%s»: %m" + +#: access/heap/rewriteheap.c:1256 access/transam/twophase.c:1613 +#: access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:422 +#: postmaster/postmaster.c:1096 postmaster/syslogger.c:1465 +#: replication/logical/origin.c:575 replication/logical/reorderbuffer.c:4362 +#: replication/logical/snapbuild.c:1556 replication/logical/snapbuild.c:1972 +#: replication/slot.c:1681 storage/file/fd.c:788 storage/file/fd.c:3169 +#: storage/file/fd.c:3231 storage/file/reinit.c:250 storage/ipc/dsm.c:315 +#: storage/smgr/md.c:344 storage/smgr/md.c:394 storage/sync/sync.c:231 +#: utils/time/snapmgr.c:1589 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "no se pudo eliminar el archivo «%s»: %m" + +#: access/heap/vacuumlazy.c:745 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum agresivo automático para prevenir wraparound de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:747 +#, c-format +msgid "automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum automático para prevenir wraparound de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:752 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum agresivo automático de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:754 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum automático de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:761 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "páginas: %u eliminadas, %u quedan, %u saltadas debido a «pins», %u congeladas saltadas\n" + +#: access/heap/vacuumlazy.c:767 +#, fuzzy, c-format +#| msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgid "tuples: %lld removed, %lld remain, %lld are dead but not yet removable, oldest xmin: %u\n" +msgstr "tuplas: %.0f removidas, %.0f permanecen ,%.0f están muertas pero aún no se pueden quitar, el xmin más antiguo: %u\n" + +#: access/heap/vacuumlazy.c:773 commands/analyze.c:794 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "uso de búfers: %lld aciertos, %lld fallos, %lld ensuciados\n" + +#: access/heap/vacuumlazy.c:783 +#, c-format +msgid " %u pages from table (%.2f%% of total) had %lld dead item identifiers removed\n" +msgstr "" + +#: access/heap/vacuumlazy.c:786 +#, fuzzy +#| msgid "index \"%s\" not found" +msgid "index scan not needed:" +msgstr "índice «%s» no encontrado" + +#: access/heap/vacuumlazy.c:788 +#, fuzzy +#| msgid "index \"%s\" was reindexed" +msgid "index scan needed:" +msgstr "el índice «%s» fue reindexado" + +#: access/heap/vacuumlazy.c:792 +#, c-format +msgid " %u pages from table (%.2f%% of total) have %lld dead item identifiers\n" +msgstr "" + +#: access/heap/vacuumlazy.c:795 +msgid "index scan bypassed:" +msgstr "" + +#: access/heap/vacuumlazy.c:797 +msgid "index scan bypassed by failsafe:" +msgstr "" + +#: access/heap/vacuumlazy.c:813 +#, c-format +msgid "index \"%s\": pages: %u in total, %u newly deleted, %u currently deleted, %u reusable\n" +msgstr "" + +#: access/heap/vacuumlazy.c:820 commands/analyze.c:798 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "tasa lectura promedio: %.3f MB/s, tasa escritura promedio: %.3f MB/s\n" + +#: access/heap/vacuumlazy.c:824 commands/analyze.c:802 +msgid "I/O Timings:" +msgstr "" + +#: access/heap/vacuumlazy.c:826 commands/analyze.c:804 +#, c-format +msgid " read=%.3f" +msgstr "" + +#: access/heap/vacuumlazy.c:829 commands/analyze.c:807 +#, c-format +msgid " write=%.3f" +msgstr "" + +#: access/heap/vacuumlazy.c:833 +#, c-format +msgid "system usage: %s\n" +msgstr "uso de sistema: %s\n" + +#: access/heap/vacuumlazy.c:835 +#, fuzzy, c-format +#| msgid "WAL usage: %ld records, %ld full page images, " +msgid "WAL usage: %lld records, %lld full page images, %llu bytes" +msgstr "uso de WAL: %ld registros, %ld imágenes de página, " + +#: access/heap/vacuumlazy.c:911 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "haciendo vacuum agresivamente a «%s.%s»" + +#: access/heap/vacuumlazy.c:916 commands/cluster.c:898 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "haciendo vacuum a «%s.%s»" + +#: access/heap/vacuumlazy.c:1627 +#, fuzzy, c-format +#| msgid "\"%s\": removed %d row versions in %d pages" +msgid "\"%s\": removed %lld dead item identifiers in %u pages" +msgstr "«%s»: se eliminaron %d versiones de filas en %d páginas" + +#: access/heap/vacuumlazy.c:1633 +#, fuzzy, c-format +#| msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgid "%lld dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f versiones muertas de filas no pueden ser eliminadas aún, xmin máx antiguo: %u\n" + +#: access/heap/vacuumlazy.c:1635 +#, c-format +msgid "%u page removed.\n" +msgid_plural "%u pages removed.\n" +msgstr[0] "" +msgstr[1] "" + +#: access/heap/vacuumlazy.c:1639 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Omitiendo %u página debido a «pins» de página, " +msgstr[1] "Omitiendo %u páginas debido a «pins» de página, " + +#: access/heap/vacuumlazy.c:1643 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u página marcadas «frozen».\n" +msgstr[1] "%u páginas marcadas «frozen».\n" + +#: access/heap/vacuumlazy.c:1647 commands/indexcmds.c:3986 +#: commands/indexcmds.c:4005 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1650 +#, fuzzy, c-format +#| msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgid "\"%s\": found %lld removable, %lld nonremovable row versions in %u out of %u pages" +msgstr "«%s»: se encontraron %.0f versiones de filas eliminables y %.0f no eliminables en %u de %u páginas" + +#: access/heap/vacuumlazy.c:2155 +#, c-format +msgid "\"%s\": index scan bypassed: %u pages from table (%.2f%% of total) have %lld dead item identifiers" +msgstr "" + +#: access/heap/vacuumlazy.c:2366 +#, fuzzy, c-format +#| msgid "\"%s\": removed %d row versions in %d pages" +msgid "\"%s\": removed %d dead item identifiers in %u pages" +msgstr "«%s»: se eliminaron %d versiones de filas en %d páginas" + +#: access/heap/vacuumlazy.c:2598 +#, fuzzy, c-format +#| msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgid "bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans" +msgstr "vacuum automático de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:2603 +#, fuzzy, c-format +#| msgid "oldest xmin is far in the past" +msgid "table's relfrozenxid or relminmxid is too far in the past" +msgstr "xmin más antiguo es demasiado antiguo" + +#: access/heap/vacuumlazy.c:2604 +#, c-format +msgid "" +"Consider increasing configuration parameter \"maintenance_work_mem\" or \"autovacuum_work_mem\".\n" +"You might also need to consider other ways for VACUUM to keep up with the allocation of transaction IDs." +msgstr "" + +#: access/heap/vacuumlazy.c:2744 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "se lanzó %d proceso asistente para «cleanup» de índices (planeados: %d)" +msgstr[1] "se lanzaron %d procesos asistentes para «cleanup» de índices (planeados: %d)" + +#: access/heap/vacuumlazy.c:2750 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "se lanzó %d proceso asistente para «vacuum» de índices (planeados: %d)" +msgstr[1] "se lanzaron %d procesos asistentes para «vacuum» índices (planeados: %d)" + +#: access/heap/vacuumlazy.c:3039 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "se recorrió el índice «%s» para eliminar %d versiones de filas" + +#: access/heap/vacuumlazy.c:3096 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "el índice «%s» ahora contiene %.0f versiones de filas en %u páginas" + +#: access/heap/vacuumlazy.c:3100 +#, fuzzy, c-format +#| msgid "" +#| "%.0f index row versions were removed.\n" +#| "%u index pages have been deleted, %u are currently reusable.\n" +#| "%s." +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages were newly deleted.\n" +"%u index pages are currently deleted, of which %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f versiones de filas del índice fueron eliminadas.\n" +"%u páginas de índice han sido eliminadas, %u son reusables.\n" +"%s." + +#: access/heap/vacuumlazy.c:3212 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "«%s»: suspendiendo el truncado debido a una petición de candado en conflicto" + +#: access/heap/vacuumlazy.c:3278 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "«%s»: truncadas %u a %u páginas" + +#: access/heap/vacuumlazy.c:3343 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "«%s»: suspendiendo el truncado debido a una petición de candado en conflicto" + +#: access/heap/vacuumlazy.c:3489 +#, c-format +msgid "disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel" +msgstr "desactivando el comportamiento paralelo de vacuum en «%s» --- no se puede hacer vacuum de tablas temporales en paralelo" + +#: access/heap/vacuumlazy.c:4244 +#, fuzzy, c-format +#| msgid "while scanning block %u of relation \"%s.%s\"" +msgid "while scanning block %u and offset %u of relation \"%s.%s\"" +msgstr "recorriendo el bloque %u de la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4247 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "recorriendo el bloque %u de la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4251 +#, c-format +msgid "while scanning relation \"%s.%s\"" +msgstr "recorriendo la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4259 +#, fuzzy, c-format +#| msgid "while vacuuming block %u of relation \"%s.%s\"" +msgid "while vacuuming block %u and offset %u of relation \"%s.%s\"" +msgstr "haciendo «vacuum» al bloque %u de la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4262 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "haciendo «vacuum» al bloque %u de la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4266 +#, c-format +msgid "while vacuuming relation \"%s.%s\"" +msgstr "mientras se hacía «vacuum» a la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4271 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "mientras se hacía «vacuum» al índice «%s» de la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4276 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "mientras se limpiaba el índice «%s» de la relación «%s.%s»" + +#: access/heap/vacuumlazy.c:4282 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "error mientras se truncaba la relación «%s.%s» a %u bloques" + +#: access/index/amapi.c:83 commands/amcmds.c:143 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "el método de acceso «%s» no es de tipo %s" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "el método de acceso «%s» no tiene manejador" + +#: access/index/genam.c:486 +#, fuzzy, c-format +#| msgid "cannot reindex system catalogs concurrently" +msgid "transaction aborted during system catalog scan" +msgstr "no se pueden reindexar catálogos de sistema concurrentemente" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1355 +#: commands/indexcmds.c:2670 commands/tablecmds.c:267 commands/tablecmds.c:291 +#: commands/tablecmds.c:16493 commands/tablecmds.c:18195 +#, c-format +msgid "\"%s\" is not an index" +msgstr "«%s» no es un índice" + +#: access/index/indexam.c:973 +#, c-format +msgid "operator class %s has no options" +msgstr "clase de operadores «%s» no tiene opciones" + +#: access/nbtree/nbtinsert.c:665 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "llave duplicada viola restricción de unicidad «%s»" + +#: access/nbtree/nbtinsert.c:667 +#, c-format +msgid "Key %s already exists." +msgstr "Ya existe la llave %s." + +#: access/nbtree/nbtinsert.c:761 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Esto puede deberse a una expresión de índice no inmutable." + +#: access/nbtree/nbtpage.c:159 access/nbtree/nbtpage.c:608 +#: parser/parse_utilcmd.c:2329 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "el índice «%s» no es un btree" + +#: access/nbtree/nbtpage.c:166 access/nbtree/nbtpage.c:615 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "discordancia de versión en índice «%s»: versión de archivo %d, versión de código %d, mínima versión soportada %d" + +#: access/nbtree/nbtpage.c:1875 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "el índice «%s» contiene una página interna parcialmente muerta" + +#: access/nbtree/nbtpage.c:1877 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "Esto puede ser causado por la interrupción de un VACUUM en la versión 9.3 o anteriores, antes de actualizar. Ejecute REINDEX por favor." + +#: access/nbtree/nbtutils.c:2665 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "el tamaño de fila de índice %1$zu excede el máximo %3$zu para btree versión %2$u para el índice «%4$s»" + +#: access/nbtree/nbtutils.c:2671 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "La tupla de índice hace referencia a la tupla (%u,%u) en la relación «%s»." + +#: access/nbtree/nbtutils.c:2675 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"Valores mayores a 1/3 de la página del buffer no pueden ser indexados.\n" +"Considere un índice sobre una función que genere un hash MD5 del valor, o utilice un esquema de indexación de texto completo." + +#: access/nbtree/nbtvalidate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "falta una función de soporte para los tipos %3$s y %4$s en la familia de operadores «%1$s» del método de acceso %2$s" + +#: access/spgist/spgutils.c:232 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "método «compress» debe estar definido cuando el tipo hoja es distinto del tipo de entrada" + +#: access/spgist/spgutils.c:1005 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "el tamaño de tupla interna SP-GiST %zu excede el máximo %zu" + +#: access/spgist/spgvalidate.c:136 +#, fuzzy, c-format +#| msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgid "SP-GiST leaf data type %s does not match declared type %s" +msgstr "el tipo anycompatiblerange %s no coincide con el tipo anycompatible %s" + +#: access/spgist/spgvalidate.c:302 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "falta la función de soporte %3$d para el tipo %4$s de la clase de operadores «%1$s» del método de accesso %2$s" + +#: access/table/table.c:49 access/table/table.c:83 access/table/table.c:112 +#: access/table/table.c:145 catalog/aclchk.c:1792 +#, c-format +msgid "\"%s\" is an index" +msgstr "«%s» es un índice" + +#: access/table/table.c:54 access/table/table.c:88 access/table/table.c:117 +#: access/table/table.c:150 catalog/aclchk.c:1799 commands/tablecmds.c:13198 +#: commands/tablecmds.c:16502 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "«%s» es un tipo compuesto" + +#: access/table/tableam.c:266 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "el tid (%u, %u) no es válido para la relación «%s»" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "%s no puede ser vacío." + +#: access/table/tableamapi.c:122 utils/misc/guc.c:12438 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s es demasiado largo (máximo %d caracteres)." + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "no existe el método de acceso de tabla «%s»" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "No existe el método de acceso de tabla «%s»." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "el porcentaje de muestreo debe estar entre 0 y 100" + +#: access/transam/commit_ts.c:278 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "no se puede obtener el timestamp de compromiso de la transacción %u" + +#: access/transam/commit_ts.c:376 +#, c-format +msgid "could not get commit timestamp data" +msgstr "no se pudo obtener datos de compromiso de transacción" + +#: access/transam/commit_ts.c:378 +#, fuzzy, c-format +#| msgid "Make sure the configuration parameter \"%s\" is set on the master server." +msgid "Make sure the configuration parameter \"%s\" is set on the primary server." +msgstr "Asegúrese que el parámetro de configuración «%s» esté definido en el servidor maestro." + +#: access/transam/commit_ts.c:380 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "Asegúrese que el parámetro de configuración «%s» esté definido." + +#: access/transam/multixact.c:1021 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "la base de datos no está aceptando órdenes que generen nuevos MultiXactIds para evitar pérdida de datos debido al reciclaje de transacciones en la base de datos «%s»" + +#: access/transam/multixact.c:1023 access/transam/multixact.c:1030 +#: access/transam/multixact.c:1054 access/transam/multixact.c:1063 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Ejecute VACUUM de la base completa en esa base de datos.\n" +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." + +#: access/transam/multixact.c:1028 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "la base de datos no está aceptando órdenes que generen nuevos MultiXactIds para evitar pérdida de datos debido al problema del reciclaje de transacciones en la base con OID %u" + +#: access/transam/multixact.c:1049 access/transam/multixact.c:2330 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "base de datos «%s» debe ser limpiada antes de que %u más MultiXactId sea usado" +msgstr[1] "base de datos «%s» debe ser limpiada dentro de que %u más MultiXactIds sean usados" + +#: access/transam/multixact.c:1058 access/transam/multixact.c:2339 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "base de datos con OID %u debe ser limpiada antes de que %u más MultiXactId sea usado" +msgstr[1] "base de datos con OID %u debe ser limpiada antes de que %u más MultiXactIds sean usados" + +#: access/transam/multixact.c:1119 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "límite de miembros de multixact alcanzado" + +#: access/transam/multixact.c:1120 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "Esta orden crearía un multixact con %u miembros, pero el espacio que queda sólo sirve para %u miembro." +msgstr[1] "Esta orden crearía un multixact con %u miembros, pero el espacio que queda sólo sirve para %u miembros." + +#: access/transam/multixact.c:1125 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Ejecute un VACUUM de la base completa en la base de datos con OID %u con vacuum_multixact_freeze_min_age y vacuum_multixact_freeze_table_age reducidos." + +#: access/transam/multixact.c:1156 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "base de datos con OID %u debe ser limpiada antes de que %d miembro más de multixact sea usado" +msgstr[1] "base de datos con OID %u debe ser limpiada antes de que %d más miembros de multixact sean usados" + +#: access/transam/multixact.c:1161 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Ejecute un VACUUM de la base completa en esa base de datos con vacuum_multixact_freeze_min_age y vacuum_multixact_freeze_table_age reducidos." + +#: access/transam/multixact.c:1298 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "el MultiXactId %u ya no existe -- aparente problema por reciclaje" + +#: access/transam/multixact.c:1306 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "el MultiXactId %u no se ha creado aún -- aparente problema por reciclaje" + +#: access/transam/multixact.c:2335 access/transam/multixact.c:2344 +#: access/transam/varsup.c:151 access/transam/varsup.c:158 +#: access/transam/varsup.c:466 access/transam/varsup.c:473 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Para evitar que la base de datos se desactive, ejecute VACUUM en esa base de datos.\n" +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." + +#: access/transam/multixact.c:2618 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "las protecciones de reciclaje de miembros de multixact están inhabilitadas porque el multixact más antiguo %u en checkpoint no existe en disco" + +#: access/transam/multixact.c:2640 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "las protecciones de reciclaje de miembros de multixact están habilitadas" + +#: access/transam/multixact.c:3027 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "multixact más antiguo %u no encontrado, multixact más antiguo es %u, omitiendo el truncado" + +#: access/transam/multixact.c:3045 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "no se puede truncar hasta el MultiXact %u porque no existe en disco, omitiendo el truncado" + +#: access/transam/multixact.c:3359 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "el MultiXactId no es válido: %u" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "el ayudante paralelo no pudo iniciar" + +#: access/transam/parallel.c:708 access/transam/parallel.c:827 +#, c-format +msgid "More details may be available in the server log." +msgstr "Puede haber más detalles disponibles en el log del servidor." + +#: access/transam/parallel.c:888 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "postmaster terminó durante una transacción paralela" + +#: access/transam/parallel.c:1075 +#, c-format +msgid "lost connection to parallel worker" +msgstr "se ha perdido la conexión al ayudante paralelo" + +#: access/transam/parallel.c:1141 access/transam/parallel.c:1143 +msgid "parallel worker" +msgstr "ayudante paralelo" + +#: access/transam/parallel.c:1294 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "no se pudo mapear el segmento de memoria compartida dinámica" + +#: access/transam/parallel.c:1299 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "número mágico no válido en segmento de memoria compartida dinámica" + +#: access/transam/slru.c:712 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "el archivo «%s» no existe, leyendo como ceros" + +#: access/transam/slru.c:944 access/transam/slru.c:950 +#: access/transam/slru.c:958 access/transam/slru.c:963 +#: access/transam/slru.c:970 access/transam/slru.c:975 +#: access/transam/slru.c:982 access/transam/slru.c:989 +#, c-format +msgid "could not access status of transaction %u" +msgstr "no se pudo encontrar el estado de la transacción %u" + +#: access/transam/slru.c:945 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "No se pudo abrir el archivo «%s»: %m." + +#: access/transam/slru.c:951 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "No se pudo posicionar (seek) en el archivo «%s» a la posición %u: %m." + +#: access/transam/slru.c:959 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "No se pudo leer desde el archivo «%s» en la posición %u: %m." + +#: access/transam/slru.c:964 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "No se pudo leer desde el archivo «%s» en la posición %u: se leyeron muy pocos bytes." + +#: access/transam/slru.c:971 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "No se pudo escribir al archivo «%s» en la posición %u: %m." + +#: access/transam/slru.c:976 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "No se pudo escribir al archivo «%s» en la posición %u: se escribieron muy pocos bytes." + +#: access/transam/slru.c:983 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "No se pudo sincronizar (fsync) archivo «%s»: %m." + +#: access/transam/slru.c:990 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "No se pudo cerrar el archivo «%s»: %m." + +#: access/transam/slru.c:1251 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "no se pudo truncar el directorio «%s»: aparente problema por reciclaje de transacciones" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "error de sintaxis en archivo de historia: %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Se esperaba un ID numérico de timeline." + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Se esperaba una ubicación de punto de cambio del registro de transacciones." + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "datos no válidos en archivo de historia: %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "IDs de timeline deben ser una secuencia creciente." + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "datos no válidos en archivo de historia «%s»" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "IDs de timeline deben ser menores que el ID de timeline del hijo." + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "el timeline %u solicitado no está en la historia de este servidor" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "identificador de transacción «%s» es demasiado largo" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "las transacciones preparadas están deshabilitadas" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "Defina max_prepared_transactions a un valor distinto de cero." + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "identificador de transacción «%s» ya está siendo utilizado" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2385 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "se alcanzó el número máximo de transacciones preparadas" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2386 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "Incremente max_prepared_transactions (actualmente es %d)." + +#: access/transam/twophase.c:584 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "transacción preparada con identificador «%s» está ocupada" + +#: access/transam/twophase.c:590 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "se ha denegado el permiso para finalizar la transacción preparada" + +#: access/transam/twophase.c:591 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "Debe ser superusuario o el usuario que preparó la transacción." + +#: access/transam/twophase.c:602 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "la transacción preparada pertenece a otra base de datos" + +#: access/transam/twophase.c:603 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "Conéctese a la base de datos donde la transacción fue preparada para terminarla." + +#: access/transam/twophase.c:618 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "transacción preparada con identificador «%s» no existe" + +#: access/transam/twophase.c:1093 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "el largo máximo del archivo de estado de dos fases fue excedido" + +#: access/transam/twophase.c:1247 +#, fuzzy, c-format +#| msgid "incorrect size of file \"%s\": %zu byte" +#| msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgid "incorrect size of file \"%s\": %lld byte" +msgid_plural "incorrect size of file \"%s\": %lld bytes" +msgstr[0] "tamaño incorrecto de archivo «%s»: %zu byte" +msgstr[1] "tamaño incorrecto de archivo «%s»: %zu bytes" + +#: access/transam/twophase.c:1256 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "alineamiento incorrecto del offset del CRC para el archivo «%s»" + +#: access/transam/twophase.c:1274 +#, fuzzy, c-format +#| msgid "could not read file \"%s\": read %d of %zu" +msgid "could not read file \"%s\": read %d of %lld" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" + +#: access/transam/twophase.c:1289 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "número mágico no válido almacenado en archivo «%s»" + +#: access/transam/twophase.c:1295 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "tamaño no válido en archivo «%s»" + +#: access/transam/twophase.c:1307 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "la suma de verificación calculada no coincide con el valor almacenado en el archivo «%s»" + +#: access/transam/twophase.c:1342 access/transam/xlog.c:6634 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "Falló mientras se emplazaba un procesador de lectura de WAL." + +#: access/transam/twophase.c:1357 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "no se pudo leer el archivo de estado de dos fases desde WAL en %X/%X" + +#: access/transam/twophase.c:1364 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "los datos de estado de dos fases esperados no están presentes en WAL en %X/%X" + +#: access/transam/twophase.c:1641 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "no se pudo recrear archivo «%s»: %m" + +#: access/transam/twophase.c:1768 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "%u archivo de estado de dos fases fue escrito para transacción de larga duración" +msgstr[1] "%u archivos de estado de dos fases fueron escritos para transacciones de larga duración" + +#: access/transam/twophase.c:2002 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "recuperando transacción preparada %u desde memoria compartida" + +#: access/transam/twophase.c:2093 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "eliminando archivo obsoleto de estado de dos fases para transacción %u" + +#: access/transam/twophase.c:2100 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "eliminando de memoria estado de dos fases obsoleto para transacción %u" + +#: access/transam/twophase.c:2113 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "eliminando archivo futuro de estado de dos fases para transacción %u" + +#: access/transam/twophase.c:2120 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "eliminando estado de dos fases futuro de memoria para transacción %u" + +#: access/transam/twophase.c:2145 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "archivo de estado de dos fases corrupto para transacción %u" + +#: access/transam/twophase.c:2150 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "estado de dos fases en memoria corrupto para transacción %u" + +#: access/transam/varsup.c:129 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "la base de datos no está aceptando órdenes para evitar pérdida de datos debido al problema del reciclaje de transacciones en la base de datos «%s»" + +#: access/transam/varsup.c:131 access/transam/varsup.c:138 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Detenga el postmaster y ejecute VACUUM de la base completa en esa base de datos.\n" +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." + +#: access/transam/varsup.c:136 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "la base de datos no está aceptando órdenes para evitar pérdida de datos debido al problema del reciclaje de transacciones en la base con OID %u" + +#: access/transam/varsup.c:148 access/transam/varsup.c:463 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "base de datos «%s» debe ser limpiada dentro de %u transacciones" + +#: access/transam/varsup.c:155 access/transam/varsup.c:470 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "base de datos con OID %u debe ser limpiada dentro de %u transacciones" + +#: access/transam/xact.c:1045 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "no se pueden tener más de 2^32-2 órdenes en una transacción" + +#: access/transam/xact.c:1582 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "se superó el número máximo de subtransacciones comprometidas (%d)" + +#: access/transam/xact.c:2423 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "no se puede hacer PREPARE de una transacción que ha operado en objetos temporales" + +#: access/transam/xact.c:2433 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "no se puede hacer PREPARE de una transacción que ha exportado snapshots" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3388 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s no puede ser ejecutado dentro de un bloque de transacción" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3398 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s no puede ser ejecutado dentro de una subtransacción" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3408 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s no puede ser ejecutado desde una función" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3477 access/transam/xact.c:3783 +#: access/transam/xact.c:3862 access/transam/xact.c:3985 +#: access/transam/xact.c:4136 access/transam/xact.c:4205 +#: access/transam/xact.c:4316 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "la orden %s sólo puede ser usada en bloques de transacción" + +#: access/transam/xact.c:3669 +#, c-format +msgid "there is already a transaction in progress" +msgstr "ya hay una transacción en curso" + +#: access/transam/xact.c:3788 access/transam/xact.c:3867 +#: access/transam/xact.c:3990 +#, c-format +msgid "there is no transaction in progress" +msgstr "no hay una transacción en curso" + +#: access/transam/xact.c:3878 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "no se puede comprometer una transacción durante una operación paralela" + +#: access/transam/xact.c:4001 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "no se puede abortar durante una operación paralela" + +#: access/transam/xact.c:4100 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "no se pueden definir savepoints durante una operación paralela" + +#: access/transam/xact.c:4187 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "no se pueden liberar savepoints durante una operación paralela" + +#: access/transam/xact.c:4197 access/transam/xact.c:4248 +#: access/transam/xact.c:4308 access/transam/xact.c:4357 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "no existe el «savepoint» «%s»" + +#: access/transam/xact.c:4254 access/transam/xact.c:4363 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "el «savepoint» «%s» no existe dentro del nivel de savepoint actual" + +#: access/transam/xact.c:4296 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "no se puede hacer rollback a un savepoint durante una operación paralela" + +#: access/transam/xact.c:4424 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "no se pueden iniciar subtransacciones durante una operación paralela" + +#: access/transam/xact.c:4492 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "no se pueden comprometer subtransacciones durante una operación paralela" + +#: access/transam/xact.c:5133 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "no se pueden tener más de 2^32-1 subtransacciones en una transacción" + +#: access/transam/xlog.c:1825 +#, c-format +msgid "request to flush past end of generated WAL; request %X/%X, current position %X/%X" +msgstr "" + +#: access/transam/xlog.c:2586 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "no se pudo escribir archivo de registro %s en la posición %u, largo %zu: %m" + +#: access/transam/xlog.c:3988 access/transam/xlogutils.c:798 +#: replication/walsender.c:2520 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "el segmento de WAL solicitado %s ya ha sido eliminado" + +#: access/transam/xlog.c:4263 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "no se pudo renombrar el archivo «%s»: %m" + +#: access/transam/xlog.c:4305 access/transam/xlog.c:4315 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "no existe el directorio WAL «%s»" + +#: access/transam/xlog.c:4321 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "creando el directorio WAL faltante «%s»" + +#: access/transam/xlog.c:4324 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "no se pudo crear el directorio faltante «%s»: %m" + +#: access/transam/xlog.c:4427 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "ID de timeline %u inesperado en archivo %s, posición %u" + +#: access/transam/xlog.c:4565 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "el nuevo timeline %u especificado no es hijo del timeline de sistema %u" + +#: access/transam/xlog.c:4579 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "el nuevo timeline %u bifurcó del timeline del sistema actual %u antes del punto re recuperación actual %X/%X" + +#: access/transam/xlog.c:4598 +#, c-format +msgid "new target timeline is %u" +msgstr "el nuevo timeline destino es %u" + +#: access/transam/xlog.c:4634 +#, c-format +msgid "could not generate secret authorization token" +msgstr "no se pudo generar un token de autorización secreto" + +#: access/transam/xlog.c:4793 access/transam/xlog.c:4802 +#: access/transam/xlog.c:4826 access/transam/xlog.c:4833 +#: access/transam/xlog.c:4840 access/transam/xlog.c:4845 +#: access/transam/xlog.c:4852 access/transam/xlog.c:4859 +#: access/transam/xlog.c:4866 access/transam/xlog.c:4873 +#: access/transam/xlog.c:4880 access/transam/xlog.c:4887 +#: access/transam/xlog.c:4896 access/transam/xlog.c:4903 +#: utils/init/miscinit.c:1578 +#, c-format +msgid "database files are incompatible with server" +msgstr "los archivos de base de datos son incompatibles con el servidor" + +#: access/transam/xlog.c:4794 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "Los archivos de base de datos fueron inicializados con PG_CONTROL_VERSION %d (0x%08x), pero el servidor fue compilado con PG_CONTROL_VERSION %d (0x%08x)." + +#: access/transam/xlog.c:4798 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "Este puede ser un problema de discordancia en el orden de bytes. Parece que necesitará ejecutar initdb." + +#: access/transam/xlog.c:4803 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "Los archivos de base de datos fueron inicializados con PG_CONTROL_VERSION %d, pero el servidor fue compilado con PG_CONTROL_VERSION %d." + +#: access/transam/xlog.c:4806 access/transam/xlog.c:4830 +#: access/transam/xlog.c:4837 access/transam/xlog.c:4842 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Parece que necesita ejecutar initdb." + +#: access/transam/xlog.c:4817 +#, c-format +msgid "incorrect checksum in control file" +msgstr "la suma de verificación es incorrecta en el archivo de control" + +#: access/transam/xlog.c:4827 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "Los archivos de base de datos fueron inicializados con CATALOG_VERSION_NO %d, pero el servidor fue compilado con CATALOG_VERSION_NO %d." + +#: access/transam/xlog.c:4834 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "Los archivos de la base de datos fueron inicializados con MAXALIGN %d, pero el servidor fue compilado con MAXALIGN %d." + +#: access/transam/xlog.c:4841 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "Los archivos de la base de datos parecen usar un formato de número de coma flotante distinto al del ejecutable del servidor." + +#: access/transam/xlog.c:4846 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "Los archivos de base de datos fueron inicializados con BLCKSZ %d, pero el servidor fue compilado con BLCKSZ %d." + +#: access/transam/xlog.c:4849 access/transam/xlog.c:4856 +#: access/transam/xlog.c:4863 access/transam/xlog.c:4870 +#: access/transam/xlog.c:4877 access/transam/xlog.c:4884 +#: access/transam/xlog.c:4891 access/transam/xlog.c:4899 +#: access/transam/xlog.c:4906 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Parece que necesita recompilar o ejecutar initdb." + +#: access/transam/xlog.c:4853 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "Los archivos de la base de datos fueron inicializados con RELSEG_SIZE %d, pero el servidor fue compilado con RELSEG_SIZE %d." + +#: access/transam/xlog.c:4860 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "Los archivos de base de datos fueron inicializados con XLOG_BLCKSZ %d, pero el servidor fue compilado con XLOG_BLCKSZ %d." + +#: access/transam/xlog.c:4867 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "Los archivos de la base de datos fueron inicializados con NAMEDATALEN %d, pero el servidor fue compilado con NAMEDATALEN %d." + +#: access/transam/xlog.c:4874 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "Los archivos de la base de datos fueron inicializados con INDEX_MAX_KEYS %d, pero el servidor fue compilado con INDEX_MAX_KEYS %d." + +#: access/transam/xlog.c:4881 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "Los archivos de la base de datos fueron inicializados con TOAST_MAX_CHUNK_SIZE %d, pero el servidor fue compilado con TOAST_MAX_CHUNK_SIZE %d." + +#: access/transam/xlog.c:4888 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "Los archivos de base de datos fueron inicializados con LOBLKSIZE %d, pero el servidor fue compilado con LOBLKSIZE %d." + +#: access/transam/xlog.c:4897 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "Los archivos de base de datos fueron inicializados sin USE_FLOAT8_BYVAL, pero el servidor fue compilado con USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4904 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "Los archivos de base de datos fueron inicializados con USE_FLOAT8_BYVAL, pero el servidor fue compilado sin USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4913 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d byte" +msgstr[1] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d bytes" + +#: access/transam/xlog.c:4925 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "«min_wal_size» debe ser al menos el doble de «wal_segment_size»" + +#: access/transam/xlog.c:4929 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "«max_wal_size» debe ser al menos el doble de «wal_segment_size»" + +#: access/transam/xlog.c:5363 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "no se pudo escribir el archivo WAL de boostrap: %m" + +#: access/transam/xlog.c:5371 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "no se pudo sincronizar (fsync) el archivo de WAL de bootstrap: %m" + +#: access/transam/xlog.c:5377 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "no se pudo cerrar el archivo WAL de bootstrap: %m" + +#: access/transam/xlog.c:5438 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "el uso del archivo de configuración de recuperación «%s» no está soportado" + +#: access/transam/xlog.c:5503 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "el modo standby no está soportado en el modo mono-usuario" + +#: access/transam/xlog.c:5520 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "no se especifica primary_conninfo ni restore_command" + +#: access/transam/xlog.c:5521 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "El servidor de bases de datos monitoreará el subdirectorio pg_wal con regularidad en búsqueda de archivos almacenados ahí." + +#: access/transam/xlog.c:5529 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "debe especificarse restore_command cuando el modo standby no está activo" + +#: access/transam/xlog.c:5567 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "no existe el timeline %u especificado como destino de recuperación" + +#: access/transam/xlog.c:5689 +#, c-format +msgid "archive recovery complete" +msgstr "recuperación completa" + +#: access/transam/xlog.c:5755 access/transam/xlog.c:6026 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "deteniendo recuperación al alcanzar un estado consistente" + +#: access/transam/xlog.c:5776 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "deteniendo recuperación antes de la ubicación (LSN) de WAL «%X/%X»" + +#: access/transam/xlog.c:5861 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "deteniendo recuperación antes de comprometer la transacción %u, hora %s" + +#: access/transam/xlog.c:5868 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "deteniendo recuperación antes de abortar la transacción %u, hora %s" + +#: access/transam/xlog.c:5921 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "deteniendo recuperación en el punto de recuperación «%s», hora %s" + +#: access/transam/xlog.c:5939 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "deteniendo recuperación después de la ubicación (LSN) de WAL «%X/%X»" + +#: access/transam/xlog.c:6006 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "deteniendo recuperación de comprometer la transacción %u, hora %s" + +#: access/transam/xlog.c:6014 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "deteniendo recuperación después de abortar la transacción %u, hora %s" + +#: access/transam/xlog.c:6059 +#, c-format +msgid "pausing at the end of recovery" +msgstr "pausando al final de la recuperación" + +#: access/transam/xlog.c:6060 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "Ejecute pg_wal_replay_resume() para promover." + +#: access/transam/xlog.c:6063 access/transam/xlog.c:6336 +#, c-format +msgid "recovery has paused" +msgstr "la recuperación está en pausa" + +#: access/transam/xlog.c:6064 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Ejecute pg_wal_replay_resume() para continuar." + +#: access/transam/xlog.c:6327 +#, fuzzy, c-format +#| msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgid "hot standby is not possible because of insufficient parameter settings" +msgstr "hot standby no es posible porque wal_level no estaba configurado como «replica» o superior en el servidor maestro" + +#: access/transam/xlog.c:6328 access/transam/xlog.c:6355 +#: access/transam/xlog.c:6385 +#, fuzzy, c-format +#| msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" +msgid "%s = %d is a lower setting than on the primary server, where its value was %d." +msgstr "hot standby no es posible puesto que %s = %d es una configuración menor que en el servidor maestro (su valor era %d)" + +#: access/transam/xlog.c:6337 +#, c-format +msgid "If recovery is unpaused, the server will shut down." +msgstr "" + +#: access/transam/xlog.c:6338 +#, c-format +msgid "You can then restart the server after making the necessary configuration changes." +msgstr "" + +#: access/transam/xlog.c:6349 +#, fuzzy, c-format +#| msgid "rotation not possible because log collection not active" +msgid "promotion is not possible because of insufficient parameter settings" +msgstr "la rotación no es posible porque la recoleccion de log no está activa" + +#: access/transam/xlog.c:6359 +#, fuzzy, c-format +#| msgid "Sets the server's main configuration file." +msgid "Restart the server after making the necessary configuration changes." +msgstr "Define la ubicación del archivo principal de configuración del servidor." + +#: access/transam/xlog.c:6383 +#, c-format +msgid "recovery aborted because of insufficient parameter settings" +msgstr "" + +#: access/transam/xlog.c:6389 +#, c-format +msgid "You can restart the server after making the necessary configuration changes." +msgstr "" + +#: access/transam/xlog.c:6411 +#, fuzzy, c-format +#| msgid "WAL was generated with wal_level=minimal, data may be missing" +msgid "WAL was generated with wal_level=minimal, cannot continue recovering" +msgstr "WAL fue generado con wal_level=minimal, puede haber datos faltantes" + +#: access/transam/xlog.c:6412 +#, fuzzy, c-format +#| msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgid "This happens if you temporarily set wal_level=minimal on the server." +msgstr "Esto sucede si temporalmente define wal_level=minimal sin tomar un nuevo respaldo base." + +#: access/transam/xlog.c:6413 +#, c-format +msgid "Use a backup taken after setting wal_level to higher than minimal." +msgstr "" + +#: access/transam/xlog.c:6482 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "el archivo de control contiene una ubicación no válida de punto de control" + +#: access/transam/xlog.c:6493 +#, c-format +msgid "database system was shut down at %s" +msgstr "el sistema de bases de datos fue apagado en %s" + +#: access/transam/xlog.c:6499 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "el sistema de bases de datos fue apagado durante la recuperación en %s" + +#: access/transam/xlog.c:6505 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "el apagado del sistema de datos fue interrumpido; última vez registrada en funcionamiento en %s" + +#: access/transam/xlog.c:6511 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "el sistema de bases de datos fue interrumpido durante la recuperación en %s" + +#: access/transam/xlog.c:6513 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "Esto probablemente significa que algunos datos están corruptos y tendrá que usar el respaldo más reciente para la recuperación." + +#: access/transam/xlog.c:6519 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "el sistema de bases de datos fue interrumpido durante la recuperación en el instante de registro %s" + +#: access/transam/xlog.c:6521 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "Si esto ha ocurrido más de una vez, algunos datos podrían estar corruptos y podría ser necesario escoger un punto de recuperación anterior." + +#: access/transam/xlog.c:6527 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "el sistema de bases de datos fue interrumpido; última vez en funcionamiento en %s" + +#: access/transam/xlog.c:6533 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "el archivo de control contiene un estado no válido del clúster" + +#: access/transam/xlog.c:6590 +#, c-format +msgid "entering standby mode" +msgstr "entrando al modo standby" + +#: access/transam/xlog.c:6593 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "comenzando el proceso de recuperación hasta el XID %u" + +#: access/transam/xlog.c:6597 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "comenzando el proceso de recuperación hasta %s" + +#: access/transam/xlog.c:6601 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "comenzando el proceso de recuperación hasta «%s»" + +#: access/transam/xlog.c:6605 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "comenzando el proceso de recuperación punto-en-el-tiempo a la ubicación (LSN) de WAL «%X/%X»" + +#: access/transam/xlog.c:6609 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "comenzando recuperación a un punto en el tiempo hasta alcanzar un estado consistente" + +#: access/transam/xlog.c:6612 +#, c-format +msgid "starting archive recovery" +msgstr "comenzando proceso de recuperación" + +#: access/transam/xlog.c:6686 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "no se pudo encontrar la ubicación de redo referida por el registro de punto de control" + +# Purposefully deviate from quoting convention here, since argument is a shell command. +#: access/transam/xlog.c:6687 access/transam/xlog.c:6697 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" +"Si está restaurando de un respaldo, ejecute «touch \"%s.recovery.signal\"» y agregue las opciones de restauración necesarias.\n" +"Si no está restaurando de un respaldo, intente eliminar el archivo \"%s/backup_label\".\n" +"Tenga cuidado: eliminar \"%s/backup_label\" resultará en un clúster corrupto si está restaurando de un respaldo." + +#: access/transam/xlog.c:6696 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "no se pudo localizar el registro del punto de control requerido" + +#: access/transam/xlog.c:6725 commands/tablespace.c:666 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "no se pudo crear el enlace simbólico «%s»: %m" + +#: access/transam/xlog.c:6757 access/transam/xlog.c:6763 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "ignorando el archivo «%s» porque no existe un archivo «%s»" + +#: access/transam/xlog.c:6759 access/transam/xlog.c:12060 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "El archivo «%s» fue renombrado a «%s»." + +#: access/transam/xlog.c:6765 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "No se pudo renombrar el archivo de «%s» a «%s»: %m." + +#: access/transam/xlog.c:6816 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "no se pudo localizar un registro de punto de control válido" + +#: access/transam/xlog.c:6854 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "el timeline solicitado %u no es un hijo de la historia de este servidor" + +#: access/transam/xlog.c:6856 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "El punto de control más reciente está en %X/%X en el timeline %u, pero en la historia del timeline solicitado, el servidor se desvió desde ese timeline en %X/%X." + +#: access/transam/xlog.c:6870 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "el timeline solicitado %u no contiene el punto mínimo de recuperación %X/%X en el timeline %u" + +#: access/transam/xlog.c:6900 +#, c-format +msgid "invalid next transaction ID" +msgstr "el siguiente ID de transacción no es válido" + +#: access/transam/xlog.c:7000 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "redo no es válido en el registro de punto de control" + +#: access/transam/xlog.c:7011 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "registro redo no es válido en el punto de control de apagado" + +#: access/transam/xlog.c:7045 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "el sistema de bases de datos no fue apagado apropiadamente; se está efectuando la recuperación automática" + +#: access/transam/xlog.c:7049 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "la recuperación comienza en el timeline %u y tiene un timeline de destino %u" + +#: access/transam/xlog.c:7096 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label contiene datos inconsistentes con el archivo de control" + +#: access/transam/xlog.c:7097 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "Esto significa que el respaldo está corrupto y deberá usar otro respaldo para la recuperación." + +#: access/transam/xlog.c:7323 +#, c-format +msgid "redo starts at %X/%X" +msgstr "redo comienza en %X/%X" + +#: access/transam/xlog.c:7548 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "el punto de detención de recuperación pedido es antes del punto de recuperación consistente" + +#: access/transam/xlog.c:7586 +#, fuzzy, c-format +#| msgid "redo done at %X/%X" +msgid "redo done at %X/%X system usage: %s" +msgstr "redo listo en %X/%X" + +#: access/transam/xlog.c:7592 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "última transacción completada al tiempo de registro %s" + +#: access/transam/xlog.c:7601 +#, c-format +msgid "redo is not required" +msgstr "no se requiere redo" + +#: access/transam/xlog.c:7613 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "la recuperación terminó antes de alcanzar el punto configurado como destino de recuperación" + +#: access/transam/xlog.c:7692 access/transam/xlog.c:7696 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "WAL termina antes del fin del respaldo en línea" + +#: access/transam/xlog.c:7693 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "Todo el WAL generado durante el respaldo en línea debe estar disponible durante la recuperación." + +#: access/transam/xlog.c:7697 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "Un respaldo en línea iniciado con pg_start_backup() debe ser terminado con pg_stop_backup(), y todos los archivos WAL hasta ese punto deben estar disponibles durante la recuperación." + +#: access/transam/xlog.c:7700 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL termina antes del punto de recuperación consistente" + +#: access/transam/xlog.c:7735 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "seleccionado nuevo ID de timeline: %u" + +#: access/transam/xlog.c:8178 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "el estado de recuperación consistente fue alcanzado en %X/%X" + +#: access/transam/xlog.c:8387 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "el enlace de punto de control primario en archivo de control no es válido" + +#: access/transam/xlog.c:8391 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "el enlace del punto de control en backup_label no es válido" + +#: access/transam/xlog.c:8409 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "el registro del punto de control primario no es válido" + +#: access/transam/xlog.c:8413 +#, c-format +msgid "invalid checkpoint record" +msgstr "el registro del punto de control no es válido" + +#: access/transam/xlog.c:8424 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "el ID de gestor de recursos en el registro del punto de control primario no es válido" + +#: access/transam/xlog.c:8428 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "el ID de gestor de recursos en el registro del punto de control no es válido" + +#: access/transam/xlog.c:8441 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "xl_info en el registro del punto de control primario no es válido" + +#: access/transam/xlog.c:8445 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "xl_info en el registro del punto de control no es válido" + +#: access/transam/xlog.c:8456 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "la longitud del registro del punto de control primario no es válida" + +#: access/transam/xlog.c:8460 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "la longitud del registro de punto de control no es válida" + +#: access/transam/xlog.c:8641 +#, c-format +msgid "shutting down" +msgstr "apagando" + +#. translator: the placeholders show checkpoint options +#: access/transam/xlog.c:8680 +#, c-format +msgid "restartpoint starting:%s%s%s%s%s%s%s%s" +msgstr "" + +#. translator: the placeholders show checkpoint options +#: access/transam/xlog.c:8692 +#, c-format +msgid "checkpoint starting:%s%s%s%s%s%s%s%s" +msgstr "" + +#: access/transam/xlog.c:8752 +#, c-format +msgid "restartpoint complete: wrote %d buffers (%.1f%%); %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB" +msgstr "" + +#: access/transam/xlog.c:8772 +#, c-format +msgid "checkpoint complete: wrote %d buffers (%.1f%%); %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB" +msgstr "" + +#: access/transam/xlog.c:9205 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "hay actividad de WAL mientras el sistema se está apagando" + +#: access/transam/xlog.c:9661 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "restartpoint de recuperación en %X/%X" + +#: access/transam/xlog.c:9663 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Última transacción completada al tiempo de registro %s." + +#: access/transam/xlog.c:9903 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "punto de recuperación «%s» creado en %X/%X" + +#: access/transam/xlog.c:10048 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "ID de timeline previo %u inesperado (timeline actual %u) en el registro de punto de control" + +#: access/transam/xlog.c:10057 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "ID de timeline %u inesperado (después de %u) en el registro de punto de control" + +#: access/transam/xlog.c:10073 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "timeline ID %u inesperado en registro de checkpoint, antes de alcanzar el punto mínimo de recuperación %X/%X en el timeline %u" + +#: access/transam/xlog.c:10148 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "el respaldo en línea fue cancelado, la recuperación no puede continuar" + +#: access/transam/xlog.c:10204 access/transam/xlog.c:10260 +#: access/transam/xlog.c:10283 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "ID de timeline %u inesperado (debería ser %u) en el registro de punto de control" + +#: access/transam/xlog.c:10632 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync write-through) el archivo «%s»: %m" + +#: access/transam/xlog.c:10638 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "no se pudo sincronizar (fdatasync) archivo «%s»: %m" + +#: access/transam/xlog.c:10749 access/transam/xlog.c:11278 +#: access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 +#: access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 +#: access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "Las funciones de control de WAL no pueden ejecutarse durante la recuperación." + +#: access/transam/xlog.c:10758 access/transam/xlog.c:11287 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "el nivel de WAL no es suficiente para hacer un respaldo en línea" + +#: access/transam/xlog.c:10759 access/transam/xlog.c:11288 +#: access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "wal_level debe ser definido a «replica» o «logical» al inicio del servidor." + +#: access/transam/xlog.c:10764 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "la etiqueta de respaldo es demasiado larga (máximo %d bytes)" + +#: access/transam/xlog.c:10801 access/transam/xlog.c:11077 +#: access/transam/xlog.c:11115 +#, c-format +msgid "a backup is already in progress" +msgstr "ya hay un respaldo en curso" + +#: access/transam/xlog.c:10802 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "Ejecute pg_stop_backup() e intente nuevamente." + +#: access/transam/xlog.c:10898 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "el WAL generado con full_page_writes=off fue restaurado desde el último restartpoint" + +#: access/transam/xlog.c:10900 access/transam/xlog.c:11483 +#, fuzzy, c-format +#| msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the primary, and then try an online backup again." +msgstr "Esto significa que el respaldo que estaba siendo tomado en el standby está corrupto y no debería usarse. Active full_page_writes y ejecute CHECKPOINT en el maestro, luego trate de ejecutar un respaldo en línea nuevamente." + +#: access/transam/xlog.c:10976 replication/basebackup.c:1433 +#: utils/adt/misc.c:345 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "la ruta «%s» del enlace simbólico es demasiado larga" + +#: access/transam/xlog.c:11026 commands/tablespace.c:402 +#: commands/tablespace.c:578 replication/basebackup.c:1448 utils/adt/misc.c:353 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "tablespaces no están soportados en esta plataforma" + +#: access/transam/xlog.c:11078 access/transam/xlog.c:11116 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "Si está seguro que no hay un respaldo en curso, elimine el archivo «%s» e intente nuevamente." + +#: access/transam/xlog.c:11303 +#, c-format +msgid "exclusive backup not in progress" +msgstr "no hay un respaldo exclusivo en curso" + +#: access/transam/xlog.c:11330 +#, c-format +msgid "a backup is not in progress" +msgstr "no hay un respaldo en curso" + +#: access/transam/xlog.c:11416 access/transam/xlog.c:11429 +#: access/transam/xlog.c:11818 access/transam/xlog.c:11824 +#: access/transam/xlog.c:11872 access/transam/xlog.c:11952 +#: access/transam/xlog.c:11976 access/transam/xlogfuncs.c:733 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "datos no válidos en archivo «%s»" + +#: access/transam/xlog.c:11433 replication/basebackup.c:1281 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "el standby fue promovido durante el respaldo en línea" + +#: access/transam/xlog.c:11434 replication/basebackup.c:1282 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "Esto significa que el respaldo que se estaba tomando está corrupto y no debería ser usado. Trate de ejecutar un nuevo respaldo en línea." + +#: access/transam/xlog.c:11481 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "el WAL generado con full_page_writes=off fue restaurado durante el respaldo en línea" + +#: access/transam/xlog.c:11601 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "respaldo base completo, esperando que se archiven los segmentos WAL requeridos" + +#: access/transam/xlog.c:11613 +#, c-format +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "todavía en espera de que todos los segmentos WAL requeridos sean archivados (han pasado %d segundos)" + +#: access/transam/xlog.c:11615 +#, c-format +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "Verifique que su archive_command se esté ejecutando con normalidad. Puede cancelar este respaldo con confianza, pero el respaldo de la base de datos no será utilizable a menos que disponga de todos los segmentos de WAL." + +#: access/transam/xlog.c:11622 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "todos los segmentos de WAL requeridos han sido archivados" + +#: access/transam/xlog.c:11626 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "el archivado de WAL no está activo; debe asegurarse que todos los segmentos WAL requeridos se copian por algún otro mecanismo para completar el respaldo" + +#: access/transam/xlog.c:11679 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "abortando el backup porque el proceso servidor terminó antes de que pg_stop_backup fuera invocada" + +#: access/transam/xlog.c:11873 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "El ID de timeline interpretado es %u, pero se esperaba %u." + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:12001 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "redo WAL en %X/%X para %s" + +#: access/transam/xlog.c:12049 +#, c-format +msgid "online backup mode was not canceled" +msgstr "el modo de respaldo en línea no fue cancelado" + +#: access/transam/xlog.c:12050 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "El archivo «%s» no se pudo renombrar a «%s»: %m." + +#: access/transam/xlog.c:12059 access/transam/xlog.c:12071 +#: access/transam/xlog.c:12081 +#, c-format +msgid "online backup mode canceled" +msgstr "el modo de respaldo en línea fue cancelado" + +#: access/transam/xlog.c:12072 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "Los archivos «%s» y «%s» fueron renombrados a «%s» y «%s», respectivamente." + +#: access/transam/xlog.c:12082 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "El archivo «%s» fue renombrado a «%s», pero el archivo «%s» no pudo ser renombrado a «%s»: %m." + +# XXX why talk about "log segment" instead of "file"? +#: access/transam/xlog.c:12215 access/transam/xlogutils.c:967 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "no se pudo leer del archivo de segmento %s, posición %u: %m" + +# XXX why talk about "log segment" instead of "file"? +#: access/transam/xlog.c:12221 access/transam/xlogutils.c:974 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "no se pudo leer del archivo de segmento %s, posición %u: leídos %d de %zu" + +#: access/transam/xlog.c:12766 +#, fuzzy, c-format +#| msgid "WAL receiver process shutdown requested" +msgid "WAL receiver process shutdown requested" +msgstr "se recibió una petición de apagado del proceso receptor de wal" + +#: access/transam/xlog.c:12861 +#, c-format +msgid "received promote request" +msgstr "se recibió petición de promoción" + +#: access/transam/xlog.c:12874 +#, c-format +msgid "promote trigger file found: %s" +msgstr "se encontró el archivo disparador de promoción: %s" + +#: access/transam/xlog.c:12882 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo disparador de promoción «%s»: %m" + +#: access/transam/xlogarchive.c:205 +#, fuzzy, c-format +#| msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgid "archive file \"%s\" has wrong size: %lld instead of %lld" +msgstr "el archivo «%s» tiene tamaño erróneo: %lu en lugar de %lu" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "se ha restaurado el archivo «%s» desde el área de archivado" + +#: access/transam/xlogarchive.c:228 +#, c-format +msgid "restore_command returned a zero exit status, but stat() failed." +msgstr "" + +#: access/transam/xlogarchive.c:260 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "no se pudo recuperar el archivo «%s»: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:369 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s «%s»: %s" + +#: access/transam/xlogarchive.c:479 access/transam/xlogarchive.c:543 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "no se pudo crear el archivo de estado «%s»: %m" + +#: access/transam/xlogarchive.c:487 access/transam/xlogarchive.c:551 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "no se pudo escribir el archivo de estado «%s»: %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "ya hay un respaldo en curso en esta sesión" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "respaldo no-exclusivo en curso" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "¿Quiso usar pg_stop_backup('f')?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1311 +#: commands/event_trigger.c:1869 commands/extension.c:1944 +#: commands/extension.c:2052 commands/extension.c:2337 commands/prepare.c:712 +#: executor/execExpr.c:2507 executor/execSRF.c:738 executor/functions.c:1057 +#: foreign/foreign.c:520 libpq/hba.c:2718 replication/logical/launcher.c:937 +#: replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1494 +#: replication/slotfuncs.c:255 replication/walsender.c:3291 +#: storage/ipc/shmem.c:554 utils/adt/datetime.c:4812 utils/adt/genfile.c:507 +#: utils/adt/genfile.c:590 utils/adt/jsonfuncs.c:1933 +#: utils/adt/jsonfuncs.c:2045 utils/adt/jsonfuncs.c:2233 +#: utils/adt/jsonfuncs.c:2342 utils/adt/jsonfuncs.c:3803 +#: utils/adt/mcxtfuncs.c:132 utils/adt/misc.c:218 utils/adt/pgstatfuncs.c:477 +#: utils/adt/pgstatfuncs.c:587 utils/adt/pgstatfuncs.c:1887 +#: utils/adt/varlena.c:4832 utils/fmgr/funcapi.c:74 utils/misc/guc.c:9993 +#: utils/mmgr/portalmem.c:1141 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "se llamó una función que retorna un conjunto en un contexto que no puede aceptarlo" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1315 +#: commands/event_trigger.c:1873 commands/extension.c:1948 +#: commands/extension.c:2056 commands/extension.c:2341 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2722 replication/logical/launcher.c:941 +#: replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1498 +#: replication/slotfuncs.c:259 replication/walsender.c:3295 +#: storage/ipc/shmem.c:558 utils/adt/datetime.c:4816 utils/adt/genfile.c:511 +#: utils/adt/genfile.c:594 utils/adt/mcxtfuncs.c:136 utils/adt/misc.c:222 +#: utils/adt/pgstatfuncs.c:481 utils/adt/pgstatfuncs.c:591 +#: utils/adt/pgstatfuncs.c:1891 utils/adt/varlena.c:4836 utils/misc/guc.c:9997 +#: utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1145 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "se requiere un nodo «materialize», pero no está permitido en este contexto" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "no hay un respaldo no-exclusivo en progreso" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "¿Quiso usar pg_stop_backup('t')?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "el nivel de WAL no es suficiente para crear un punto de recuperación" + +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "el valor es demasiado largo para un punto de recuperación (máximo %d caracteres)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "No se puede ejecutar %s durante la recuperación." + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:561 +#: access/transam/xlogfuncs.c:585 access/transam/xlogfuncs.c:608 +#: access/transam/xlogfuncs.c:763 +#, c-format +msgid "recovery is not in progress" +msgstr "la recuperación no está en proceso" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:562 +#: access/transam/xlogfuncs.c:586 access/transam/xlogfuncs.c:609 +#: access/transam/xlogfuncs.c:764 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "Las funciones de control de recuperación sólo pueden ejecutarse durante la recuperación." + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:567 +#, c-format +msgid "standby promotion is ongoing" +msgstr "la promoción del standby está en curso" + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:568 +#, fuzzy, c-format +#| msgid "%s cannot be executed from a function" +msgid "%s cannot be executed after promotion is triggered." +msgstr "%s no puede ser ejecutado después que una promoción es solicitada." + +#: access/transam/xlogfuncs.c:769 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "«wait_seconds» no puede ser negativo o cero" + +#: access/transam/xlogfuncs.c:789 storage/ipc/signalfuncs.c:281 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "no se pudo enviar señal a postmaster: %m" + +#: access/transam/xlogfuncs.c:825 +#, fuzzy, c-format +#| msgid "server did not promote within %d seconds" +msgid "server did not promote within %d second" +msgid_plural "server did not promote within %d seconds" +msgstr[0] "el servidor no promovió en %d segundos" +msgstr[1] "el servidor no promovió en %d segundos" + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "posición de registro no válida en %X/%X" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "contrecord solicitado por %X/%X" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "largo de registro no válido en %X/%X: se esperaba %u, se obtuvo %u" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "largo de registro %u en %X/%X demasiado largo" + +#: access/transam/xlogreader.c:453 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "no hay bandera de contrecord en %X/%X" + +#: access/transam/xlogreader.c:466 +#, fuzzy, c-format +#| msgid "invalid contrecord length %u at %X/%X" +msgid "invalid contrecord length %u (expected %lld) at %X/%X" +msgstr "largo de contrecord %u no válido en %X/%X" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "ID de gestor de recursos %u no válido en %X/%X" + +#: access/transam/xlogreader.c:716 access/transam/xlogreader.c:732 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "registro con prev-link %X/%X incorrecto en %X/%X" + +#: access/transam/xlogreader.c:768 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "suma de verificación de los datos del gestor de recursos incorrecta en el registro en %X/%X" + +#: access/transam/xlogreader.c:805 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "número mágico %04X no válido en archivo %s, posición %u" + +#: access/transam/xlogreader.c:819 access/transam/xlogreader.c:860 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "info bits %04X no válidos en archivo %s, posición %u" + +#: access/transam/xlogreader.c:834 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "archivo WAL es de un sistema de bases de datos distinto: identificador de sistema en archivo WAL es %llu, identificador en pg_control es %llu" + +#: access/transam/xlogreader.c:842 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "archivo WAL es de un sistema de bases de datos distinto: tamaño de segmento incorrecto en cabecera de paǵina" + +#: access/transam/xlogreader.c:848 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "archivo WAL es de un sistema de bases de datos distinto: XLOG_BLCKSZ incorrecto en cabecera de paǵina" + +#: access/transam/xlogreader.c:879 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "pageaddr %X/%X inesperado en archivo %s, posición %u" + +#: access/transam/xlogreader.c:904 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "ID de timeline %u fuera de secuencia (después de %u) en archivo %s, posición %u" + +#: access/transam/xlogreader.c:1249 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %u fuera de orden en %X/%X" + +#: access/transam/xlogreader.c:1271 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA está definido, pero no hay datos en %X/%X" + +#: access/transam/xlogreader.c:1278 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA no está definido, pero el largo de los datos es %u en %X/%X" + +#: access/transam/xlogreader.c:1314 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE está definido, pero posición del agujero es %u largo %u largo de imagen %u en %X/%X" + +#: access/transam/xlogreader.c:1330 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE no está definido, pero posición del agujero es %u largo %u en %X/%X" + +#: access/transam/xlogreader.c:1345 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED definido, pero largo de imagen de bloque es %u en %X/%X" + +#: access/transam/xlogreader.c:1360 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "ni BKPIMAGE_HAS_HOLE ni BKPIMAGE_IS_COMPRESSED está definido, pero largo de imagen de bloque es %u en %X/%X" + +#: access/transam/xlogreader.c:1376 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL está definido, pero no hay «rel» anterior en %X/%X " + +#: access/transam/xlogreader.c:1388 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "block_id %u no válido en %X/%X" + +#: access/transam/xlogreader.c:1475 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "registro con largo no válido en %X/%X" + +#: access/transam/xlogreader.c:1564 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "imagen comprimida no válida en %X/%X, bloque %d" + +#: bootstrap/bootstrap.c:270 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X require un valor potencia de dos entre 1 MB y 1 GB" + +#: bootstrap/bootstrap.c:287 postmaster/postmaster.c:847 tcop/postgres.c:3858 +#, c-format +msgid "--%s requires a value" +msgstr "--%s requiere un valor" + +#: bootstrap/bootstrap.c:292 postmaster/postmaster.c:852 tcop/postgres.c:3863 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s requiere un valor" + +#: bootstrap/bootstrap.c:303 postmaster/postmaster.c:864 +#: postmaster/postmaster.c:877 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: bootstrap/bootstrap.c:312 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: argumentos de línea de órdenes no válidos\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "la opción de grant sólo puede ser otorgada a roles" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "no se otorgaron privilegios para la columna «%s» de la relación «%s»" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "no se otorgaron privilegios para «%s»" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "no todos los privilegios fueron otorgados para la columna «%s» de la relación «%s»" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "no todos los privilegios fueron otorgados para «%s»" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "ningún privilegio pudo ser revocado para la columna «%s» de la relación «%s»" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "ningún privilegio pudo ser revocado para «%s»" + +#: catalog/aclchk.c:342 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "no todos los privilegios pudieron ser revocados para la columna «%s» de la relación «%s»" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "no todos los privilegios pudieron ser revocados para «%s»" + +#: catalog/aclchk.c:379 +#, fuzzy, c-format +#| msgid "must be superuser" +msgid "grantor must be current user" +msgstr "debe ser superusuario" + +#: catalog/aclchk.c:446 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "el tipo de privilegio %s no es válido para una relación" + +#: catalog/aclchk.c:450 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "el tipo de privilegio %s no es válido para una secuencia" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "el tipo de privilegio %s no es válido para una base de datos" + +#: catalog/aclchk.c:458 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "el tipo de privilegio %s no es válido para un dominio" + +#: catalog/aclchk.c:462 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "el tipo de privilegio %s no es válido para una función" + +#: catalog/aclchk.c:466 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "el tipo de privilegio %s no es válido para un lenguaje" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "el tipo de privilegio %s no es válido para un objeto grande" + +#: catalog/aclchk.c:474 catalog/aclchk.c:1013 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "el tipo de privilegio %s no es válido para un esquema" + +#: catalog/aclchk.c:478 catalog/aclchk.c:1001 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "el tipo de privilegio %s no es válido para un procedimiento" + +#: catalog/aclchk.c:482 catalog/aclchk.c:1005 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "el tipo de privilegio %s no es válido para una rutina" + +#: catalog/aclchk.c:486 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "el tipo de privilegio %s no es válido para un tablespace" + +#: catalog/aclchk.c:490 catalog/aclchk.c:1009 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "el tipo de privilegio %s no es válido para un tipo" + +#: catalog/aclchk.c:494 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "el tipo de privilegio %s no es válido para un conector de datos externos" + +#: catalog/aclchk.c:498 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "el tipo de privilegio %s no es válido para un servidor foráneo" + +#: catalog/aclchk.c:537 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "los privilegios de columna son sólo válidos para relaciones" + +#: catalog/aclchk.c:697 catalog/aclchk.c:4164 catalog/aclchk.c:4985 +#: catalog/objectaddress.c:1060 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "no existe el objeto grande %u" + +#: catalog/aclchk.c:926 catalog/aclchk.c:935 commands/collationcmds.c:119 +#: commands/copy.c:362 commands/copy.c:382 commands/copy.c:392 +#: commands/copy.c:401 commands/copy.c:410 commands/copy.c:420 +#: commands/copy.c:429 commands/copy.c:438 commands/copy.c:456 +#: commands/copy.c:472 commands/copy.c:492 commands/copy.c:509 +#: commands/dbcommands.c:157 commands/dbcommands.c:166 +#: commands/dbcommands.c:175 commands/dbcommands.c:184 +#: commands/dbcommands.c:193 commands/dbcommands.c:202 +#: commands/dbcommands.c:211 commands/dbcommands.c:220 +#: commands/dbcommands.c:229 commands/dbcommands.c:238 +#: commands/dbcommands.c:260 commands/dbcommands.c:1502 +#: commands/dbcommands.c:1511 commands/dbcommands.c:1520 +#: commands/dbcommands.c:1529 commands/extension.c:1735 +#: commands/extension.c:1745 commands/extension.c:1755 +#: commands/extension.c:3055 commands/foreigncmds.c:539 +#: commands/foreigncmds.c:548 commands/functioncmds.c:604 +#: commands/functioncmds.c:770 commands/functioncmds.c:779 +#: commands/functioncmds.c:788 commands/functioncmds.c:797 +#: commands/functioncmds.c:2094 commands/functioncmds.c:2102 +#: commands/publicationcmds.c:90 commands/publicationcmds.c:133 +#: commands/sequence.c:1266 commands/sequence.c:1276 commands/sequence.c:1286 +#: commands/sequence.c:1296 commands/sequence.c:1306 commands/sequence.c:1316 +#: commands/sequence.c:1326 commands/sequence.c:1336 commands/sequence.c:1346 +#: commands/subscriptioncmds.c:124 commands/subscriptioncmds.c:134 +#: commands/subscriptioncmds.c:144 commands/subscriptioncmds.c:154 +#: commands/subscriptioncmds.c:168 commands/subscriptioncmds.c:179 +#: commands/subscriptioncmds.c:193 commands/subscriptioncmds.c:203 +#: commands/subscriptioncmds.c:213 commands/tablecmds.c:7500 +#: commands/typecmds.c:335 commands/typecmds.c:1416 commands/typecmds.c:1425 +#: commands/typecmds.c:1433 commands/typecmds.c:1441 commands/typecmds.c:1449 +#: commands/typecmds.c:1457 commands/user.c:133 commands/user.c:147 +#: commands/user.c:156 commands/user.c:165 commands/user.c:174 +#: commands/user.c:183 commands/user.c:192 commands/user.c:201 +#: commands/user.c:210 commands/user.c:219 commands/user.c:228 +#: commands/user.c:237 commands/user.c:246 commands/user.c:582 +#: commands/user.c:590 commands/user.c:598 commands/user.c:606 +#: commands/user.c:614 commands/user.c:622 commands/user.c:630 +#: commands/user.c:638 commands/user.c:647 commands/user.c:655 +#: commands/user.c:663 parser/parse_utilcmd.c:407 +#: replication/pgoutput/pgoutput.c:189 replication/pgoutput/pgoutput.c:210 +#: replication/pgoutput/pgoutput.c:224 replication/pgoutput/pgoutput.c:234 +#: replication/pgoutput/pgoutput.c:244 replication/walsender.c:882 +#: replication/walsender.c:893 replication/walsender.c:903 +#, c-format +msgid "conflicting or redundant options" +msgstr "opciones contradictorias o redundantes" + +#: catalog/aclchk.c:1046 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "los privilegios por omisión no pueden definirse para columnas" + +#: catalog/aclchk.c:1206 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "No puede utilizar la cláusula IN SCHEMA cuando se utiliza GRANT / REVOKE ON SCHEMAS" + +#: catalog/aclchk.c:1544 catalog/catalog.c:553 catalog/objectaddress.c:1522 +#: commands/analyze.c:390 commands/copy.c:741 commands/sequence.c:1701 +#: commands/tablecmds.c:6976 commands/tablecmds.c:7119 +#: commands/tablecmds.c:7169 commands/tablecmds.c:7243 +#: commands/tablecmds.c:7313 commands/tablecmds.c:7425 +#: commands/tablecmds.c:7519 commands/tablecmds.c:7578 +#: commands/tablecmds.c:7667 commands/tablecmds.c:7696 +#: commands/tablecmds.c:7851 commands/tablecmds.c:7933 +#: commands/tablecmds.c:8089 commands/tablecmds.c:8207 +#: commands/tablecmds.c:11556 commands/tablecmds.c:11738 +#: commands/tablecmds.c:11898 commands/tablecmds.c:13041 +#: commands/tablecmds.c:15602 commands/trigger.c:924 parser/analyze.c:2415 +#: parser/parse_relation.c:714 parser/parse_target.c:1064 +#: parser/parse_type.c:144 parser/parse_utilcmd.c:3453 +#: parser/parse_utilcmd.c:3488 parser/parse_utilcmd.c:3530 utils/adt/acl.c:2845 +#: utils/adt/ruleutils.c:2708 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "no existe la columna «%s» en la relación «%s»" + +#: catalog/aclchk.c:1807 catalog/objectaddress.c:1362 commands/sequence.c:1139 +#: commands/tablecmds.c:249 commands/tablecmds.c:16466 utils/adt/acl.c:2053 +#: utils/adt/acl.c:2083 utils/adt/acl.c:2115 utils/adt/acl.c:2147 +#: utils/adt/acl.c:2175 utils/adt/acl.c:2205 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "«%s» no es una secuencia" + +#: catalog/aclchk.c:1845 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "la secuencia «%s» sólo soporta los privilegios USAGE, SELECT, y UPDATE" + +#: catalog/aclchk.c:1862 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "el tipo de privilegio %s no es válido para una tabla" + +#: catalog/aclchk.c:2028 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "el tipo de privilegio %s no es válido para una columna" + +#: catalog/aclchk.c:2041 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "la secuencia «%s» sólo soporta el privilegio SELECT" + +#: catalog/aclchk.c:2623 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "el lenguaje «%s» no es confiable (trusted)" + +#: catalog/aclchk.c:2625 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "GRANT y REVOKE no están permitidos en lenguajes no confiables, porque sólo los superusuarios pueden usar lenguajes no confiables." + +#: catalog/aclchk.c:3139 +#, c-format +msgid "cannot set privileges of array types" +msgstr "no se puede definir privilegios para tipos de array" + +#: catalog/aclchk.c:3140 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Defina los privilegios del tipo elemento en su lugar." + +#: catalog/aclchk.c:3147 catalog/objectaddress.c:1656 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "«%s» no es un dominio" + +#: catalog/aclchk.c:3267 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "tipo de privilegio «%s» no reconocido" + +#: catalog/aclchk.c:3328 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "permiso denegado a la función de agregación %s" + +#: catalog/aclchk.c:3331 +#, c-format +msgid "permission denied for collation %s" +msgstr "permiso denegado al ordenamiento (collation) %s" + +#: catalog/aclchk.c:3334 +#, c-format +msgid "permission denied for column %s" +msgstr "permiso denegado a la columna %s" + +#: catalog/aclchk.c:3337 +#, c-format +msgid "permission denied for conversion %s" +msgstr "permiso denegado a la conversión %s" + +#: catalog/aclchk.c:3340 +#, c-format +msgid "permission denied for database %s" +msgstr "permiso denegado a la base de datos %s" + +#: catalog/aclchk.c:3343 +#, c-format +msgid "permission denied for domain %s" +msgstr "permiso denegado al dominio %s" + +#: catalog/aclchk.c:3346 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "permiso denegado al disparador por eventos %s" + +#: catalog/aclchk.c:3349 +#, c-format +msgid "permission denied for extension %s" +msgstr "permiso denegado a la extensión %s" + +#: catalog/aclchk.c:3352 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "permiso denegado al conector de datos externos %s" + +#: catalog/aclchk.c:3355 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "permiso denegado al servidor foráneo %s" + +#: catalog/aclchk.c:3358 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "permiso denegado a la tabla foránea %s" + +#: catalog/aclchk.c:3361 +#, c-format +msgid "permission denied for function %s" +msgstr "permiso denegado a la función %s" + +#: catalog/aclchk.c:3364 +#, c-format +msgid "permission denied for index %s" +msgstr "permiso denegado al índice %s" + +#: catalog/aclchk.c:3367 +#, c-format +msgid "permission denied for language %s" +msgstr "permiso denegado al lenguaje %s" + +#: catalog/aclchk.c:3370 +#, c-format +msgid "permission denied for large object %s" +msgstr "permiso denegado al objeto grande %s" + +#: catalog/aclchk.c:3373 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "permiso denegado a la vista materializada %s" + +#: catalog/aclchk.c:3376 +#, c-format +msgid "permission denied for operator class %s" +msgstr "permiso denegado a la clase de operadores %s" + +#: catalog/aclchk.c:3379 +#, c-format +msgid "permission denied for operator %s" +msgstr "permiso denegado al operador %s" + +#: catalog/aclchk.c:3382 +#, c-format +msgid "permission denied for operator family %s" +msgstr "permiso denegado a la familia de operadores %s" + +#: catalog/aclchk.c:3385 +#, c-format +msgid "permission denied for policy %s" +msgstr "permiso denegado a la política %s" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for procedure %s" +msgstr "permiso denegado al procedimiento %s" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for publication %s" +msgstr "permiso denegado a la publicación %s" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for routine %s" +msgstr "permiso denegado a la rutina %s" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for schema %s" +msgstr "permiso denegado al esquema %s" + +#: catalog/aclchk.c:3400 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1799 +#: commands/sequence.c:1863 +#, c-format +msgid "permission denied for sequence %s" +msgstr "permiso denegado a la secuencia %s" + +#: catalog/aclchk.c:3403 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "permiso denegado al objeto de estadísticas %s" + +#: catalog/aclchk.c:3406 +#, c-format +msgid "permission denied for subscription %s" +msgstr "permiso denegado a la suscripción %s" + +#: catalog/aclchk.c:3409 +#, c-format +msgid "permission denied for table %s" +msgstr "permiso denegado a la tabla %s" + +#: catalog/aclchk.c:3412 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "permiso denegado al tablespace %s" + +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "permiso denegado a la configuración de búsqueda en texto %s" + +#: catalog/aclchk.c:3418 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "permiso denegado a la configuración de búsqueda en texto %s" + +#: catalog/aclchk.c:3421 +#, c-format +msgid "permission denied for type %s" +msgstr "permiso denegado al tipo %s" + +#: catalog/aclchk.c:3424 +#, c-format +msgid "permission denied for view %s" +msgstr "permiso denegado a la vista %s" + +#: catalog/aclchk.c:3459 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "debe ser dueño de la función de agregación %s" + +#: catalog/aclchk.c:3462 +#, c-format +msgid "must be owner of collation %s" +msgstr "debe ser dueño del ordenamiento (collation) %s" + +#: catalog/aclchk.c:3465 +#, c-format +msgid "must be owner of conversion %s" +msgstr "debe ser dueño de la conversión %s" + +#: catalog/aclchk.c:3468 +#, c-format +msgid "must be owner of database %s" +msgstr "debe ser dueño de la base de datos %s" + +#: catalog/aclchk.c:3471 +#, c-format +msgid "must be owner of domain %s" +msgstr "debe ser dueño del dominio %s" + +#: catalog/aclchk.c:3474 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "debe ser dueño del disparador por eventos %s" + +#: catalog/aclchk.c:3477 +#, c-format +msgid "must be owner of extension %s" +msgstr "debe ser dueño de la extensión %s" + +#: catalog/aclchk.c:3480 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "debe ser dueño del conector de datos externos %s" + +#: catalog/aclchk.c:3483 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "debe ser dueño del servidor foráneo %s" + +#: catalog/aclchk.c:3486 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "debe ser dueño de la tabla foránea %s" + +#: catalog/aclchk.c:3489 +#, c-format +msgid "must be owner of function %s" +msgstr "debe ser dueño de la función %s" + +#: catalog/aclchk.c:3492 +#, c-format +msgid "must be owner of index %s" +msgstr "debe ser dueño del índice %s" + +#: catalog/aclchk.c:3495 +#, c-format +msgid "must be owner of language %s" +msgstr "debe ser dueño del lenguaje %s" + +#: catalog/aclchk.c:3498 +#, c-format +msgid "must be owner of large object %s" +msgstr "debe ser dueño del objeto grande %s" + +#: catalog/aclchk.c:3501 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "debe ser dueño de la vista materializada %s" + +#: catalog/aclchk.c:3504 +#, c-format +msgid "must be owner of operator class %s" +msgstr "debe ser dueño de la clase de operadores %s" + +#: catalog/aclchk.c:3507 +#, c-format +msgid "must be owner of operator %s" +msgstr "debe ser dueño del operador %s" + +#: catalog/aclchk.c:3510 +#, c-format +msgid "must be owner of operator family %s" +msgstr "debe ser dueño de la familia de operadores %s" + +#: catalog/aclchk.c:3513 +#, c-format +msgid "must be owner of procedure %s" +msgstr "debe ser dueño del procedimiento %s" + +#: catalog/aclchk.c:3516 +#, c-format +msgid "must be owner of publication %s" +msgstr "debe ser dueño de la publicación %s" + +#: catalog/aclchk.c:3519 +#, c-format +msgid "must be owner of routine %s" +msgstr "debe ser dueño de la rutina %s" + +#: catalog/aclchk.c:3522 +#, c-format +msgid "must be owner of sequence %s" +msgstr "debe ser dueño de la secuencia %s" + +#: catalog/aclchk.c:3525 +#, c-format +msgid "must be owner of subscription %s" +msgstr "debe ser dueño de la suscripción %s" + +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of table %s" +msgstr "debe ser dueño de la tabla %s" + +#: catalog/aclchk.c:3531 +#, c-format +msgid "must be owner of type %s" +msgstr "debe ser dueño del tipo %s" + +#: catalog/aclchk.c:3534 +#, c-format +msgid "must be owner of view %s" +msgstr "debe ser dueño de la vista %s" + +#: catalog/aclchk.c:3537 +#, c-format +msgid "must be owner of schema %s" +msgstr "debe ser dueño del esquema %s" + +#: catalog/aclchk.c:3540 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "debe ser dueño del objeto de estadísticas %s" + +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "debe ser dueño del tablespace %s" + +#: catalog/aclchk.c:3546 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "debe ser dueño de la configuración de búsqueda en texto %s" + +#: catalog/aclchk.c:3549 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "debe ser dueño del diccionario de búsqueda en texto %s" + +#: catalog/aclchk.c:3563 +#, c-format +msgid "must be owner of relation %s" +msgstr "debe ser dueño de la relación %s" + +#: catalog/aclchk.c:3607 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "permiso denegado a la columna «%s» de la relación «%s»" + +#: catalog/aclchk.c:3750 catalog/aclchk.c:3769 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "no existe el atributo %d de la relación con OID %u" + +#: catalog/aclchk.c:3864 catalog/aclchk.c:4836 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "no existe la relación con OID %u" + +#: catalog/aclchk.c:3977 catalog/aclchk.c:5254 +#, c-format +msgid "database with OID %u does not exist" +msgstr "no existe la base de datos con OID %u" + +#: catalog/aclchk.c:4031 catalog/aclchk.c:4914 tcop/fastpath.c:141 +#: utils/fmgr/fmgr.c:2051 +#, c-format +msgid "function with OID %u does not exist" +msgstr "no existe la función con OID %u" + +#: catalog/aclchk.c:4085 catalog/aclchk.c:4940 +#, c-format +msgid "language with OID %u does not exist" +msgstr "no existe el lenguaje con OID %u" + +#: catalog/aclchk.c:4249 catalog/aclchk.c:5012 commands/collationcmds.c:517 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "no existe el esquema con OID %u" + +#: catalog/aclchk.c:4313 catalog/aclchk.c:5039 utils/adt/genfile.c:688 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "no existe el tablespace con OID %u" + +#: catalog/aclchk.c:4372 catalog/aclchk.c:5173 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "no existe el conector de datos externos con OID %u" + +#: catalog/aclchk.c:4434 catalog/aclchk.c:5200 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "no existe el servidor foráneo con OID %u" + +#: catalog/aclchk.c:4494 catalog/aclchk.c:4862 utils/cache/typcache.c:384 +#: utils/cache/typcache.c:439 +#, c-format +msgid "type with OID %u does not exist" +msgstr "no existe el tipo con OID %u" + +#: catalog/aclchk.c:4888 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "no existe el operador con OID %u" + +#: catalog/aclchk.c:5065 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "no existe la clase de operadores con OID %u" + +#: catalog/aclchk.c:5092 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "no existe la familia de operadores con OID %u" + +#: catalog/aclchk.c:5119 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "no existe el diccionario de búsqueda en texto con OID %u" + +#: catalog/aclchk.c:5146 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "no existe la configuración de búsqueda en texto con OID %u" + +#: catalog/aclchk.c:5227 commands/event_trigger.c:453 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "no existe el disparador por eventos con OID %u" + +#: catalog/aclchk.c:5280 commands/collationcmds.c:368 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "no existe el ordenamiento (collation) con OID %u" + +#: catalog/aclchk.c:5306 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "no existe la conversión con OID %u" + +#: catalog/aclchk.c:5347 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "no existe la extensión con OID %u" + +#: catalog/aclchk.c:5374 commands/publicationcmds.c:771 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "no existe la publicación con OID %u" + +#: catalog/aclchk.c:5400 commands/subscriptioncmds.c:1459 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "no existe la suscripción con OID %u" + +#: catalog/aclchk.c:5426 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "no existe el objeto de estadísticas con OID %u" + +#: catalog/catalog.c:378 +#, fuzzy, c-format +#| msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgid "still finding an unused OID within relation \"%s\"" +msgstr "mientras se insertaba la tupla de índice (%u,%u) en la relación «%s»" + +#: catalog/catalog.c:380 +#, c-format +msgid "OID candidates were checked \"%llu\" times, but no unused OID is yet found." +msgstr "" + +#: catalog/catalog.c:403 +#, c-format +msgid "new OID has been assigned in relation \"%s\" after \"%llu\" retries" +msgstr "" + +#: catalog/catalog.c:532 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "debe ser superusuario para invocar pg_nextoid()" + +#: catalog/catalog.c:540 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() sólo puede usarse en catálogos de sistema" + +#: catalog/catalog.c:545 parser/parse_utilcmd.c:2276 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "el índice «%s» no pertenece a la tabla «%s»" + +#: catalog/catalog.c:562 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "la columna «%s» no es de tipo oid" + +#: catalog/catalog.c:569 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "«el índice %s» no es el índice para la columna «%s»" + +#: catalog/dependency.c:821 catalog/dependency.c:1060 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "no se puede eliminar %s porque %s lo requiere" + +#: catalog/dependency.c:823 catalog/dependency.c:1062 +#, c-format +msgid "You can drop %s instead." +msgstr "Puede eliminar %s en su lugar." + +#: catalog/dependency.c:931 catalog/pg_shdepend.c:696 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "no se puede eliminar %s porque es requerido por el sistema" + +#: catalog/dependency.c:1135 catalog/dependency.c:1144 +#, c-format +msgid "%s depends on %s" +msgstr "%s depende de %s" + +#: catalog/dependency.c:1156 catalog/dependency.c:1165 +#, c-format +msgid "drop cascades to %s" +msgstr "eliminando además %s" + +#: catalog/dependency.c:1173 catalog/pg_shdepend.c:825 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"y %d otro objeto (vea el registro del servidor para obtener la lista)" +msgstr[1] "" +"\n" +"y otros %d objetos (vea el registro del servidor para obtener la lista)" + +#: catalog/dependency.c:1185 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "no se puede eliminar %s porque otros objetos dependen de él" + +#: catalog/dependency.c:1187 catalog/dependency.c:1188 +#: catalog/dependency.c:1194 catalog/dependency.c:1195 +#: catalog/dependency.c:1206 catalog/dependency.c:1207 +#: commands/tablecmds.c:1298 commands/tablecmds.c:13659 +#: commands/tablespace.c:481 commands/user.c:1095 commands/view.c:495 +#: libpq/auth.c:338 replication/syncrep.c:1043 storage/lmgr/deadlock.c:1152 +#: storage/lmgr/proc.c:1433 utils/adt/acl.c:5250 utils/adt/jsonfuncs.c:618 +#: utils/adt/jsonfuncs.c:624 utils/misc/guc.c:7114 utils/misc/guc.c:7150 +#: utils/misc/guc.c:7220 utils/misc/guc.c:11400 utils/misc/guc.c:11434 +#: utils/misc/guc.c:11468 utils/misc/guc.c:11511 utils/misc/guc.c:11553 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1189 catalog/dependency.c:1196 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Use DROP ... CASCADE para eliminar además los objetos dependientes." + +#: catalog/dependency.c:1193 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "no se puede eliminar el o los objetos deseados porque otros objetos dependen de ellos" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1202 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "eliminando además %d objeto más" +msgstr[1] "eliminando además %d objetos más" + +#: catalog/dependency.c:1863 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "no se puede usar una constante de tipo %s aquí" + +#: catalog/heap.c:332 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "se ha denegado el permiso para crear «%s.%s»" + +#: catalog/heap.c:334 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "Las modificaciones al catálogo del sistema están actualmente deshabilitadas." + +#: catalog/heap.c:511 commands/tablecmds.c:2335 commands/tablecmds.c:2972 +#: commands/tablecmds.c:6567 +#, c-format +msgid "tables can have at most %d columns" +msgstr "las tablas pueden tener a lo más %d columnas" + +#: catalog/heap.c:529 commands/tablecmds.c:6866 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "el nombre de columna «%s» colisiona con nombre de una columna de sistema" + +#: catalog/heap.c:545 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "el nombre de columna «%s» fue especificado más de una vez" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:620 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "la columna %s de la llave de partición tiene pseudotipo %s" + +#: catalog/heap.c:625 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "la columna «%s» tiene pseudotipo %s" + +#: catalog/heap.c:656 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "un tipo compuesto %s no puede ser hecho miembro de sí mismo" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:711 +#, c-format +msgid "no collation was derived for partition key column %s with collatable type %s" +msgstr "no se derivó ningún ordenamiento (collate) para la columna %s de llave de partición con tipo ordenable %s" + +#: catalog/heap.c:717 commands/createas.c:203 commands/createas.c:506 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "no se derivó ningún ordenamiento (collate) para la columna «%s» con tipo ordenable %s" + +#: catalog/heap.c:1199 catalog/index.c:870 commands/createas.c:411 +#: commands/tablecmds.c:3853 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "la relación «%s» ya existe" + +#: catalog/heap.c:1215 catalog/pg_type.c:435 catalog/pg_type.c:773 +#: catalog/pg_type.c:920 commands/typecmds.c:249 commands/typecmds.c:261 +#: commands/typecmds.c:757 commands/typecmds.c:1172 commands/typecmds.c:1398 +#: commands/typecmds.c:1590 commands/typecmds.c:2563 +#, c-format +msgid "type \"%s\" already exists" +msgstr "ya existe un tipo «%s»" + +#: catalog/heap.c:1216 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "Una relación tiene un tipo asociado del mismo nombre, de modo que debe usar un nombre que no entre en conflicto con un tipo existente." + +#: catalog/heap.c:1245 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "el valor de OID de heap de pg_class no se definió en modo de actualización binaria" + +#: catalog/heap.c:2450 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "no se puede agregar una restricción NO INHERIT a la tabla particionada «%s»" + +#: catalog/heap.c:2722 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "la restricción «check» «%s» ya existe" + +#: catalog/heap.c:2892 catalog/index.c:884 catalog/pg_constraint.c:670 +#: commands/tablecmds.c:8581 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "la restricción «%s» para la relación «%s» ya existe" + +#: catalog/heap.c:2899 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "la restricción «%s» está en conflicto con la restricción no heredada de la relación «%s»" + +#: catalog/heap.c:2910 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "la restricción «%s» está en conflicto con la restricción heredada de la relación «%s»" + +#: catalog/heap.c:2920 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "la restricción «%s» está en conflicto con la restricción NOT VALID de la relación «%s»" + +#: catalog/heap.c:2925 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "mezclando la restricción «%s» con la definición heredada" + +#: catalog/heap.c:3030 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "no se puede usar la columna generada «%s» en una expresión de generación de columna" + +#: catalog/heap.c:3032 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "Una columna generada no puede hacer referencia a otra columna generada." + +#: catalog/heap.c:3038 +#, fuzzy, c-format +#| msgid "cannot use subquery in column generation expression" +msgid "cannot use whole-row variable in column generation expression" +msgstr "no se puede usar una subconsulta en una expresión de generación de columna" + +#: catalog/heap.c:3039 +#, c-format +msgid "This would cause the generated column to depend on its own value." +msgstr "" + +#: catalog/heap.c:3092 +#, c-format +msgid "generation expression is not immutable" +msgstr "la expresión de generación no es inmutable" + +#: catalog/heap.c:3120 rewrite/rewriteHandler.c:1245 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "la columna «%s» es de tipo %s pero la expresión default es de tipo %s" + +#: catalog/heap.c:3125 commands/prepare.c:367 parser/analyze.c:2639 +#: parser/parse_target.c:595 parser/parse_target.c:883 +#: parser/parse_target.c:893 rewrite/rewriteHandler.c:1250 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Necesitará reescribir la expresión o aplicarle una conversión de tipo." + +#: catalog/heap.c:3172 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "sólo la tabla «%s» puede ser referenciada en una restricción «check»" + +#: catalog/heap.c:3470 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "combinación de ON COMMIT y llaves foráneas no soportada" + +#: catalog/heap.c:3471 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "La tabla «%s» se refiere a «%s», pero no tienen la misma expresión para ON COMMIT." + +#: catalog/heap.c:3476 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "no se puede truncar una tabla referida en una llave foránea" + +#: catalog/heap.c:3477 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "La tabla «%s» hace referencia a «%s»." + +#: catalog/heap.c:3479 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "Trunque la tabla «%s» al mismo tiempo, o utilice TRUNCATE ... CASCADE." + +#: catalog/index.c:221 parser/parse_utilcmd.c:2182 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "no se permiten múltiples llaves primarias para la tabla «%s»" + +#: catalog/index.c:239 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "las llaves primarias no pueden ser expresiones" + +#: catalog/index.c:256 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "columna de llave primaria «%s» no está marcada NOT NULL" + +#: catalog/index.c:769 catalog/index.c:1905 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "los usuarios no pueden crear índices en tablas del sistema" + +#: catalog/index.c:809 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "los ordenamientos no determinísticos no están soportados para la clase de operadores «%s»" + +#: catalog/index.c:824 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "no se pueden crear índices de forma concurrente en tablas del sistema" + +#: catalog/index.c:833 catalog/index.c:1284 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "no se pueden crear índices para restricciones de exclusión de forma concurrente" + +#: catalog/index.c:842 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "no se pueden crear índices compartidos después de initdb" + +#: catalog/index.c:862 commands/createas.c:417 commands/sequence.c:154 +#: parser/parse_utilcmd.c:211 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "la relación «%s» ya existe, omitiendo" + +#: catalog/index.c:912 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "el valor de OID de índice de pg_class no se definió en modo de actualización binaria" + +#: catalog/index.c:2191 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY debe ser la primera acción en una transacción" + +#: catalog/index.c:3576 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "no se puede hacer reindex de tablas temporales de otras sesiones" + +#: catalog/index.c:3587 commands/indexcmds.c:3426 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "no es posible reindexar un índice no válido en tabla TOAST" + +#: catalog/index.c:3603 commands/indexcmds.c:3306 commands/indexcmds.c:3450 +#: commands/tablecmds.c:3292 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "no se puede mover la relación de sistema «%s»" + +#: catalog/index.c:3747 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "el índice «%s» fue reindexado" + +#: catalog/index.c:3878 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "no se puede reindexar el índice no válido «%s.%s» en tabla TOAST, omitiendo" + +#: catalog/namespace.c:258 catalog/namespace.c:462 catalog/namespace.c:554 +#: commands/trigger.c:5134 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "no están implementadas las referencias entre bases de datos: «%s.%s.%s»" + +#: catalog/namespace.c:315 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "las tablas temporales no pueden especificar un nombre de esquema" + +#: catalog/namespace.c:396 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "no se pudo bloquear un candado en la relación «%s.%s»" + +#: catalog/namespace.c:401 commands/lockcmds.c:143 commands/lockcmds.c:228 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "no se pudo bloquear un candado en la relación «%s»" + +#: catalog/namespace.c:429 parser/parse_relation.c:1362 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "no existe la relación «%s.%s»" + +#: catalog/namespace.c:434 parser/parse_relation.c:1375 +#: parser/parse_relation.c:1383 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "no existe la relación «%s»" + +#: catalog/namespace.c:500 catalog/namespace.c:3075 commands/extension.c:1519 +#: commands/extension.c:1525 +#, c-format +msgid "no schema has been selected to create in" +msgstr "no se ha seleccionado ningún esquema dentro del cual crear" + +#: catalog/namespace.c:652 catalog/namespace.c:665 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "no se pueden crear relaciones en esquemas temporales de otras sesiones" + +#: catalog/namespace.c:656 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "no se pueden crear tablas temporales en esquemas no temporales" + +#: catalog/namespace.c:671 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "sólo relaciones temporales pueden ser creadas en los esquemas temporales" + +#: catalog/namespace.c:2267 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "no existe el objeto de estadísticas «%s»" + +#: catalog/namespace.c:2390 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "no existe el analizador de búsqueda en texto «%s»" + +#: catalog/namespace.c:2516 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "no existe el diccionario de búsqueda en texto «%s»" + +#: catalog/namespace.c:2643 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "no existe la plantilla de búsqueda en texto «%s»" + +#: catalog/namespace.c:2769 commands/tsearchcmds.c:1121 +#: utils/cache/ts_cache.c:613 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "no existe la configuración de búsqueda en texto «%s»" + +#: catalog/namespace.c:2882 parser/parse_expr.c:810 parser/parse_target.c:1256 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "no están implementadas las referencias entre bases de datos: %s" + +#: catalog/namespace.c:2888 gram.y:15102 gram.y:17061 parser/parse_expr.c:817 +#: parser/parse_target.c:1263 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "el nombre no es válido (demasiados puntos): %s" + +#: catalog/namespace.c:3018 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "no se puede mover objetos hacia o desde esquemas temporales" + +#: catalog/namespace.c:3024 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "no se puede mover objetos hacia o desde el esquema TOAST" + +#: catalog/namespace.c:3097 commands/schemacmds.c:233 commands/schemacmds.c:313 +#: commands/tablecmds.c:1243 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "no existe el esquema «%s»" + +#: catalog/namespace.c:3128 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "el nombre de relación no es válido (demasiados puntos): %s" + +#: catalog/namespace.c:3691 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "no existe el ordenamiento (collation) «%s» para la codificación «%s»" + +#: catalog/namespace.c:3746 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "no existe la conversión «%s»" + +#: catalog/namespace.c:4010 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "se ha denegado el permiso para crear tablas temporales en la base de datos «%s»" + +#: catalog/namespace.c:4026 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "no se pueden crear tablas temporales durante la recuperación" + +#: catalog/namespace.c:4032 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "no se pueden crear tablas temporales durante una operación paralela" + +#: catalog/namespace.c:4331 commands/tablespace.c:1217 commands/variable.c:64 +#: utils/misc/guc.c:11585 utils/misc/guc.c:11663 +#, c-format +msgid "List syntax is invalid." +msgstr "La sintaxis de lista no es válida." + +#: catalog/objectaddress.c:1370 catalog/pg_publication.c:57 +#: commands/policy.c:95 commands/policy.c:375 commands/policy.c:465 +#: commands/tablecmds.c:243 commands/tablecmds.c:285 commands/tablecmds.c:2145 +#: commands/tablecmds.c:6016 commands/tablecmds.c:11673 +#, c-format +msgid "\"%s\" is not a table" +msgstr "«%s» no es una tabla" + +#: catalog/objectaddress.c:1377 commands/tablecmds.c:255 +#: commands/tablecmds.c:6046 commands/tablecmds.c:16471 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "«%s» no es una vista" + +#: catalog/objectaddress.c:1384 commands/matview.c:175 commands/tablecmds.c:261 +#: commands/tablecmds.c:16476 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "«%s» no es una vista materializada" + +#: catalog/objectaddress.c:1391 commands/tablecmds.c:279 +#: commands/tablecmds.c:6049 commands/tablecmds.c:16481 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "«%s» no es una tabla foránea" + +#: catalog/objectaddress.c:1432 +#, c-format +msgid "must specify relation and object name" +msgstr "debe especificar nombre de relación y nombre de objeto" + +#: catalog/objectaddress.c:1508 catalog/objectaddress.c:1561 +#, c-format +msgid "column name must be qualified" +msgstr "el nombre de columna debe ser calificado" + +#: catalog/objectaddress.c:1608 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "no existe el valor por omisión para la columna «%s» de la relación «%s»" + +#: catalog/objectaddress.c:1645 commands/functioncmds.c:137 +#: commands/tablecmds.c:271 commands/typecmds.c:274 commands/typecmds.c:3713 +#: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:791 +#: utils/adt/acl.c:4411 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "no existe el tipo «%s»" + +#: catalog/objectaddress.c:1764 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "no existe el operador %d (%s, %s) de %s" + +#: catalog/objectaddress.c:1795 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "no existe la función %d (%s, %s) de %s" + +#: catalog/objectaddress.c:1846 catalog/objectaddress.c:1872 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "no existe el mapeo para el usuario «%s» en el servidor «%s»" + +#: catalog/objectaddress.c:1861 commands/foreigncmds.c:430 +#: commands/foreigncmds.c:988 commands/foreigncmds.c:1347 foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "no existe el servidor «%s»" + +#: catalog/objectaddress.c:1928 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "no existe la relación «%s» en la publicación «%s»" + +#: catalog/objectaddress.c:1990 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "tipo de objeto para ACL por omisión «%c» no reconocido" + +#: catalog/objectaddress.c:1991 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Tipos válidos de objeto son «%c», «%c», «%c», «%c» y «%c»." + +#: catalog/objectaddress.c:2042 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "no existe el ACL por omisión para el usuario «%s» en el esquema «%s» en %s" + +#: catalog/objectaddress.c:2047 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "no existe el ACL por omisión para el usuario «%s» en %s" + +#: catalog/objectaddress.c:2074 catalog/objectaddress.c:2132 +#: catalog/objectaddress.c:2189 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "las listas de nombres o argumentos no pueden contener nulls" + +#: catalog/objectaddress.c:2108 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "tipo de objeto «%s» no soportado" + +#: catalog/objectaddress.c:2128 catalog/objectaddress.c:2146 +#: catalog/objectaddress.c:2287 +#, c-format +msgid "name list length must be exactly %d" +msgstr "el largo de la lista de nombres debe ser exactamente %d" + +#: catalog/objectaddress.c:2150 +#, c-format +msgid "large object OID may not be null" +msgstr "el OID de objeto grande no puede ser null" + +#: catalog/objectaddress.c:2159 catalog/objectaddress.c:2222 +#: catalog/objectaddress.c:2229 +#, c-format +msgid "name list length must be at least %d" +msgstr "el largo de la lista de nombres debe ser al menos %d" + +#: catalog/objectaddress.c:2215 catalog/objectaddress.c:2236 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "el largo de la lista de argumentos debe ser exactamente %d" + +#: catalog/objectaddress.c:2488 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "debe ser dueño del objeto grande %u" + +#: catalog/objectaddress.c:2503 commands/functioncmds.c:1581 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "debe ser dueño del tipo %s o el tipo %s" + +#: catalog/objectaddress.c:2553 catalog/objectaddress.c:2570 +#, c-format +msgid "must be superuser" +msgstr "debe ser superusuario" + +#: catalog/objectaddress.c:2560 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "debe tener privilegio CREATEROLE" + +#: catalog/objectaddress.c:2639 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "tipo de objeto «%s» no reconocido" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2882 +#, c-format +msgid "column %s of %s" +msgstr " columna %s de %s" + +#: catalog/objectaddress.c:2897 +#, c-format +msgid "function %s" +msgstr "función %s" + +#: catalog/objectaddress.c:2910 +#, c-format +msgid "type %s" +msgstr "tipo %s" + +#: catalog/objectaddress.c:2947 +#, c-format +msgid "cast from %s to %s" +msgstr "conversión de %s a %s" + +#: catalog/objectaddress.c:2980 +#, c-format +msgid "collation %s" +msgstr "ordenamiento (collation) %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3011 +#, c-format +msgid "constraint %s on %s" +msgstr "restricción «%s» en %s" + +#: catalog/objectaddress.c:3017 +#, c-format +msgid "constraint %s" +msgstr "restricción %s" + +#: catalog/objectaddress.c:3049 +#, c-format +msgid "conversion %s" +msgstr "conversión %s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:3095 +#, c-format +msgid "default value for %s" +msgstr "valor por omisión para %s" + +#: catalog/objectaddress.c:3109 +#, c-format +msgid "language %s" +msgstr "lenguaje %s" + +#: catalog/objectaddress.c:3117 +#, c-format +msgid "large object %u" +msgstr "objeto grande %u" + +#: catalog/objectaddress.c:3130 +#, c-format +msgid "operator %s" +msgstr "operador %s" + +#: catalog/objectaddress.c:3167 +#, c-format +msgid "operator class %s for access method %s" +msgstr "clase de operadores «%s» para el método de acceso «%s»" + +#: catalog/objectaddress.c:3195 +#, c-format +msgid "access method %s" +msgstr "método de acceso %s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3244 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "operador %d (%s, %s) de %s: %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3301 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "función %d (%s, %s) de %s: %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3353 +#, c-format +msgid "rule %s on %s" +msgstr "regla %s en %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3399 +#, c-format +msgid "trigger %s on %s" +msgstr "disparador %s en %s" + +#: catalog/objectaddress.c:3419 +#, c-format +msgid "schema %s" +msgstr "esquema %s" + +#: catalog/objectaddress.c:3447 +#, c-format +msgid "statistics object %s" +msgstr "object de estadísticas %s" + +#: catalog/objectaddress.c:3478 +#, c-format +msgid "text search parser %s" +msgstr "analizador de búsqueda en texto %s" + +#: catalog/objectaddress.c:3509 +#, c-format +msgid "text search dictionary %s" +msgstr "diccionario de búsqueda en texto %s" + +#: catalog/objectaddress.c:3540 +#, c-format +msgid "text search template %s" +msgstr "plantilla de búsqueda en texto %s" + +#: catalog/objectaddress.c:3571 +#, c-format +msgid "text search configuration %s" +msgstr "configuración de búsqueda en texto %s" + +#: catalog/objectaddress.c:3584 +#, c-format +msgid "role %s" +msgstr "rol %s" + +#: catalog/objectaddress.c:3600 +#, c-format +msgid "database %s" +msgstr "base de datos %s" + +#: catalog/objectaddress.c:3616 +#, c-format +msgid "tablespace %s" +msgstr "tablespace %s" + +#: catalog/objectaddress.c:3627 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "conector de datos externos %s" + +#: catalog/objectaddress.c:3637 +#, c-format +msgid "server %s" +msgstr "servidor %s" + +#: catalog/objectaddress.c:3670 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "mapeo para el usuario %s en el servidor %s" + +#: catalog/objectaddress.c:3722 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevas relaciones pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3726 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "privilegios por omisión en nuevas relaciones pertenecientes al rol %s" + +#: catalog/objectaddress.c:3732 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevas secuencias pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3736 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "privilegios por omisión en nuevas secuencias pertenecientes al rol %s" + +#: catalog/objectaddress.c:3742 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevas funciones pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3746 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "privilegios por omisión en nuevas funciones pertenecientes al rol %s" + +#: catalog/objectaddress.c:3752 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevos tipos pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3756 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "privilegios por omisión en nuevos tipos pertenecientes al rol %s" + +#: catalog/objectaddress.c:3762 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "privilegios por omisión en nuevos esquemas pertenecientes al rol %s" + +#: catalog/objectaddress.c:3769 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "privilegios por omisión pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3773 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "privilegios por omisión pertenecientes al rol %s" + +#: catalog/objectaddress.c:3795 +#, c-format +msgid "extension %s" +msgstr "extensión %s" + +#: catalog/objectaddress.c:3812 +#, c-format +msgid "event trigger %s" +msgstr "disparador por eventos %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3856 +#, c-format +msgid "policy %s on %s" +msgstr "política %s en %s" + +#: catalog/objectaddress.c:3870 +#, c-format +msgid "publication %s" +msgstr "publicación %s" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3898 +#, c-format +msgid "publication of %s in publication %s" +msgstr "publicación de %s en la publicación %s" + +#: catalog/objectaddress.c:3911 +#, c-format +msgid "subscription %s" +msgstr "suscripción %s" + +#: catalog/objectaddress.c:3932 +#, c-format +msgid "transform for %s language %s" +msgstr "transformación para %s lenguaje %s" + +#: catalog/objectaddress.c:4003 +#, c-format +msgid "table %s" +msgstr "tabla %s" + +#: catalog/objectaddress.c:4008 +#, c-format +msgid "index %s" +msgstr "índice %s" + +#: catalog/objectaddress.c:4012 +#, c-format +msgid "sequence %s" +msgstr "secuencia %s" + +#: catalog/objectaddress.c:4016 +#, c-format +msgid "toast table %s" +msgstr "tabla toast %s" + +#: catalog/objectaddress.c:4020 +#, c-format +msgid "view %s" +msgstr "vista %s" + +#: catalog/objectaddress.c:4024 +#, c-format +msgid "materialized view %s" +msgstr "vista materializada %s" + +#: catalog/objectaddress.c:4028 +#, c-format +msgid "composite type %s" +msgstr "tipo compuesto %s" + +#: catalog/objectaddress.c:4032 +#, c-format +msgid "foreign table %s" +msgstr "tabla foránea %s" + +#: catalog/objectaddress.c:4037 +#, c-format +msgid "relation %s" +msgstr "relación %s" + +#: catalog/objectaddress.c:4078 +#, c-format +msgid "operator family %s for access method %s" +msgstr "familia de operadores %s para el método de acceso %s" + +#: catalog/pg_aggregate.c:129 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "las funciones de agregación no pueden tener más de %d argumento" +msgstr[1] "las funciones de agregación no pueden tener más de %d argumentos" + +#: catalog/pg_aggregate.c:144 catalog/pg_aggregate.c:158 +#, c-format +msgid "cannot determine transition data type" +msgstr "no se pudo determinar el tipo de dato de transición" + +#: catalog/pg_aggregate.c:173 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "una función de agregación variádica de conjuntos ordenados debe ser de tipo VARIADIC ANY" + +#: catalog/pg_aggregate.c:199 +#, c-format +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" +msgstr "la función de agregación de conjunto hipotético debe tener argumentos directos que coincidan con los argumentos agregados" + +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "el tipo de retorno de la función de transición %s no es %s" + +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 +#, c-format +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" +msgstr "no se puede omitir el valor inicial cuando la función de transición es «strict» y el tipo de transición no es compatible con el tipo de entrada" + +#: catalog/pg_aggregate.c:335 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "el tipo de retorno de la función inversa de transición %s no es %s" + +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2852 +#, c-format +msgid "strictness of aggregate's forward and inverse transition functions must match" +msgstr "la opción «strict» de las funciones de transición directa e inversa deben coincidir exactamente en la función de agregación" + +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:554 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "la función final con argumentos extra no debe declararse STRICT" + +#: catalog/pg_aggregate.c:427 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "el tipo de retorno de la función «combine» %s no es %s" + +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:4128 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "la función «combine» con tipo de transición %s no debe declararse STRICT" + +#: catalog/pg_aggregate.c:458 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "el tipo de retorno de la función de serialización %s no es %s" + +#: catalog/pg_aggregate.c:479 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "el tipo de retorno de la función de deserialización %s no es %s" + +#: catalog/pg_aggregate.c:498 catalog/pg_proc.c:189 catalog/pg_proc.c:223 +#, c-format +msgid "cannot determine result data type" +msgstr "no se puede determinar el tipo de dato del resultado" + +#: catalog/pg_aggregate.c:513 catalog/pg_proc.c:202 catalog/pg_proc.c:231 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "uso inseguro de pseudotipo «internal»" + +#: catalog/pg_aggregate.c:567 +#, c-format +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" +msgstr "la implementación de la función de agregación en modo «moving» devuelve tipo de dato %s, pero la implementación normal devuelve tipo de dato %s" + +#: catalog/pg_aggregate.c:578 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "el operador de ordenamiento sólo puede ser especificado para funciones de agregación de un solo argumento" + +#: catalog/pg_aggregate.c:706 catalog/pg_proc.c:384 +#, c-format +msgid "cannot change routine kind" +msgstr "no se puede cambiar el tipo de rutina" + +#: catalog/pg_aggregate.c:708 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "«%s» es una función de agregación corriente." + +#: catalog/pg_aggregate.c:710 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "«%s» es una función de agregación de conjunto ordenado." + +#: catalog/pg_aggregate.c:712 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "«%s» es una agregación de conjunto hipotético." + +#: catalog/pg_aggregate.c:717 +#, c-format +msgid "cannot change number of direct arguments of an aggregate function" +msgstr "no se puede cambiar cantidad de argumentos directos de una función de agregación" + +#: catalog/pg_aggregate.c:858 commands/functioncmds.c:701 +#: commands/typecmds.c:1992 commands/typecmds.c:2038 commands/typecmds.c:2090 +#: commands/typecmds.c:2127 commands/typecmds.c:2161 commands/typecmds.c:2195 +#: commands/typecmds.c:2229 commands/typecmds.c:2258 commands/typecmds.c:2345 +#: commands/typecmds.c:2387 parser/parse_func.c:417 parser/parse_func.c:448 +#: parser/parse_func.c:475 parser/parse_func.c:489 parser/parse_func.c:611 +#: parser/parse_func.c:631 parser/parse_func.c:2173 parser/parse_func.c:2446 +#, c-format +msgid "function %s does not exist" +msgstr "no existe la función %s" + +#: catalog/pg_aggregate.c:864 +#, c-format +msgid "function %s returns a set" +msgstr "la función %s retorna un conjunto" + +#: catalog/pg_aggregate.c:879 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "la función %s debe aceptar VARIADIC ANY para usarse en esta agregación" + +#: catalog/pg_aggregate.c:903 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "la función %s requiere conversión de tipos en tiempo de ejecución" + +#: catalog/pg_cast.c:68 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "ya existe una conversión del tipo %s al tipo %s" + +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "el ordenamiento «%s» ya existe, omitiendo" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "el ordenamiento «%s» para la codificación «%s» ya existe, omitiendo" + +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "el ordenamiento «%s» ya existe" + +#: catalog/pg_collation.c:105 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "la codificación «%2$s» ya tiene un ordenamiento llamado «%1$s»" + +#: catalog/pg_constraint.c:678 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "el dominio %2$s ya contiene una restricción llamada «%1$s»" + +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "no existe la restricción «%s» para la tabla «%s»" + +#: catalog/pg_constraint.c:1056 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "no existe la restricción «%s» para el dominio %s" + +#: catalog/pg_conversion.c:67 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "ya existe la conversión «%s»" + +#: catalog/pg_conversion.c:80 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "ya existe una conversión por omisión desde %s a %s" + +#: catalog/pg_depend.c:204 commands/extension.c:3343 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "«%s» ya es un miembro de la extensión «%s»" + +#: catalog/pg_depend.c:580 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "no se puede eliminar dependencia a %s porque es un objeto requerido por el sistema" + +#: catalog/pg_enum.c:128 catalog/pg_enum.c:230 catalog/pg_enum.c:525 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "la etiqueta enum «%s» no es válida" + +#: catalog/pg_enum.c:129 catalog/pg_enum.c:231 catalog/pg_enum.c:526 +#, fuzzy, c-format +#| msgid "Labels must be %d characters or less." +msgid "Labels must be %d bytes or less." +msgstr "Las etiquetas deben ser de %d caracteres o menos." + +#: catalog/pg_enum.c:259 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "la etiqueta de enum «%s» ya existe, omitiendo" + +#: catalog/pg_enum.c:266 catalog/pg_enum.c:569 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "la etiqueta de enum «%s» ya existe" + +#: catalog/pg_enum.c:321 catalog/pg_enum.c:564 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "«%s» no es una etiqueta de enum existente" + +#: catalog/pg_enum.c:379 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "el valor de OID de pg_enum no se definió en modo de actualización binaria" + +#: catalog/pg_enum.c:389 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "ALTER TYPE ADD BEFORE/AFTER es incompatible con la actualización binaria" + +#: catalog/pg_inherits.c:593 +#, fuzzy, c-format +#| msgid "cannot inherit from partition \"%s\"" +msgid "cannot detach partition \"%s\"" +msgstr "no se puede heredar de la partición «%s»" + +#: catalog/pg_inherits.c:595 +#, c-format +msgid "The partition is being detached concurrently or has an unfinished detach." +msgstr "" + +#: catalog/pg_inherits.c:596 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation" +msgstr "" + +#: catalog/pg_inherits.c:600 +#, fuzzy, c-format +#| msgid "cannot cluster on partial index \"%s\"" +msgid "cannot complete detaching partition \"%s\"" +msgstr "no se puede reordenar en índice parcial «%s»" + +#: catalog/pg_inherits.c:602 +#, c-format +msgid "There's no pending concurrent detach." +msgstr "" + +#: catalog/pg_namespace.c:64 commands/schemacmds.c:242 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "ya existe el esquema «%s»" + +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "«%s» no es un nombre válido de operador" + +#: catalog/pg_operator.c:370 +#, c-format +msgid "only binary operators can have commutators" +msgstr "sólo los operadores binarios pueden tener conmutadores" + +#: catalog/pg_operator.c:374 commands/operatorcmds.c:507 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "sólo los operadores binarios pueden tener selectividad de join" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can merge join" +msgstr "sólo los operadores binarios pueden ser usados en merge join" + +#: catalog/pg_operator.c:382 +#, c-format +msgid "only binary operators can hash" +msgstr "sólo los operadores binarios pueden ser usados en hash" + +#: catalog/pg_operator.c:393 +#, c-format +msgid "only boolean operators can have negators" +msgstr "sólo los operadores booleanos pueden tener negadores" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:515 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "sólo los operadores booleanos pueden tener selectividad de restricción" + +#: catalog/pg_operator.c:401 commands/operatorcmds.c:519 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "sólo los operadores booleanos pueden tener selectividad de join" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can merge join" +msgstr "sólo los operadores booleanos pueden ser usados en merge join" + +#: catalog/pg_operator.c:409 +#, c-format +msgid "only boolean operators can hash" +msgstr "sólo los operadores booleanos pueden ser usados en hash" + +#: catalog/pg_operator.c:421 +#, c-format +msgid "operator %s already exists" +msgstr "ya existe un operador %s" + +#: catalog/pg_operator.c:621 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "un operador no puede ser su propio negador u operador de ordenamiento" + +#: catalog/pg_proc.c:130 parser/parse_func.c:2235 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "las funciones no pueden tener más de %d argumento" +msgstr[1] "las funciones no pueden tener más de %d argumentos" + +#: catalog/pg_proc.c:374 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "ya existe una función «%s» con los mismos argumentos" + +#: catalog/pg_proc.c:386 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "«%s» es una función de agregación." + +#: catalog/pg_proc.c:388 +#, c-format +msgid "\"%s\" is a function." +msgstr "«%s» es una función de agregación." + +#: catalog/pg_proc.c:390 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "«%s» es un índice parcial." + +#: catalog/pg_proc.c:392 +#, c-format +msgid "\"%s\" is a window function." +msgstr "«%s» es una función de ventana deslizante." + +#: catalog/pg_proc.c:412 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "no se puede cambiar que un procedimiento tenga parámetros de salida" + +#: catalog/pg_proc.c:413 catalog/pg_proc.c:443 +#, c-format +msgid "cannot change return type of existing function" +msgstr "no se puede cambiar el tipo de retorno de una función existente" + +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:419 catalog/pg_proc.c:446 catalog/pg_proc.c:491 +#: catalog/pg_proc.c:517 catalog/pg_proc.c:543 +#, c-format +msgid "Use %s %s first." +msgstr "Use %s %s primero." + +#: catalog/pg_proc.c:444 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "Tipo de registro definido por parámetros OUT es diferente." + +#: catalog/pg_proc.c:488 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "no se puede cambiar el nombre del parámetro de entrada «%s»" + +#: catalog/pg_proc.c:515 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "no se puede eliminar el valor por omisión de funciones existentes" + +#: catalog/pg_proc.c:541 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "no se puede cambiar el tipo de dato del valor por omisión de un parámetro" + +#: catalog/pg_proc.c:751 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "no hay ninguna función interna llamada «%s»" + +#: catalog/pg_proc.c:849 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "las funciones SQL no pueden retornar el tipo %s" + +#: catalog/pg_proc.c:864 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "las funciones SQL no pueden tener argumentos de tipo %s" + +#: catalog/pg_proc.c:976 executor/functions.c:1457 +#, c-format +msgid "SQL function \"%s\"" +msgstr "función SQL «%s»" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Only tables can be added to publications." +msgstr "Sólo se pueden agregar tablas a las publicaciones." + +#: catalog/pg_publication.c:65 +#, c-format +msgid "\"%s\" is a system table" +msgstr "«%s» es una tabla de sistema" + +#: catalog/pg_publication.c:67 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "Las tablas de sistema no pueden agregarse a publicaciones." + +#: catalog/pg_publication.c:73 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "la tabla «%s» no puede replicarse" + +#: catalog/pg_publication.c:75 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "Las tablas temporales o «unlogged» no pueden replicarse." + +#: catalog/pg_publication.c:174 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "la relación «%s» ya es un miembro de la publicación «%s»" + +#: catalog/pg_publication.c:470 commands/publicationcmds.c:451 +#: commands/publicationcmds.c:739 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "no existe la publicación «%s»" + +#: catalog/pg_shdepend.c:832 +#, c-format +msgid "" +"\n" +"and objects in %d other database (see server log for list)" +msgid_plural "" +"\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "" +"\n" +"y objetos en %d base de datos (vea el registro del servidor para obtener la lista)" +msgstr[1] "" +"\n" +"y objetos en otras %d bases de datos (vea el registro del servidor para obtener la lista)" + +#: catalog/pg_shdepend.c:1176 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "el rol %u fue eliminado por una transacción concurrente" + +#: catalog/pg_shdepend.c:1188 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "el tablespace %u fue eliminado por una transacción concurrente" + +#: catalog/pg_shdepend.c:1202 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "la base de datos %u fue eliminado por una transacción concurrente" + +#: catalog/pg_shdepend.c:1247 +#, c-format +msgid "owner of %s" +msgstr "dueño de %s" + +#: catalog/pg_shdepend.c:1249 +#, c-format +msgid "privileges for %s" +msgstr "privilegios para %s" + +#: catalog/pg_shdepend.c:1251 +#, c-format +msgid "target of %s" +msgstr "destino de %s" + +#: catalog/pg_shdepend.c:1253 +#, fuzzy, c-format +#| msgid "tablespace %s" +msgid "tablespace for %s" +msgstr "tablespace %s" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1261 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%d objeto en %s" +msgstr[1] "%d objetos en %s" + +#: catalog/pg_shdepend.c:1372 +#, c-format +msgid "cannot drop objects owned by %s because they are required by the database system" +msgstr "no se puede eliminar objetos de propiedad de %s porque son requeridos por el sistema" + +#: catalog/pg_shdepend.c:1519 +#, c-format +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" +msgstr "no se puede reasignar la propiedad de objetos de %s porque son requeridos por el sistema" + +#: catalog/pg_subscription.c:174 commands/subscriptioncmds.c:775 +#: commands/subscriptioncmds.c:1085 commands/subscriptioncmds.c:1427 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "no existe la suscripción «%s»" + +#: catalog/pg_subscription.c:432 +#, fuzzy, c-format +#| msgid "could not find function information for function \"%s\"" +msgid "could not drop relation mapping for subscription \"%s\"" +msgstr "no se pudo encontrar información de función para la función «%s»" + +#: catalog/pg_subscription.c:434 +#, c-format +msgid "Table synchronization for relation \"%s\" is in progress and is in state \"%c\"." +msgstr "" + +#. translator: first %s is a SQL ALTER command and second %s is a +#. SQL DROP command +#. +#: catalog/pg_subscription.c:441 +#, c-format +msgid "Use %s to enable subscription if not already enabled or use %s to drop the subscription." +msgstr "" + +#: catalog/pg_type.c:136 catalog/pg_type.c:475 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "el valor de OID de pg_type no se definió en modo de actualización binaria" + +#: catalog/pg_type.c:255 +#, c-format +msgid "invalid type internal size %d" +msgstr "el tamaño interno de tipo %d no es válido" + +#: catalog/pg_type.c:271 catalog/pg_type.c:279 catalog/pg_type.c:287 +#: catalog/pg_type.c:296 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "el alineamiento «%c» no es válido para un tipo pasado por valor de tamaño %d" + +#: catalog/pg_type.c:303 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "el tamaño interno %d no es válido para un tipo pasado por valor" + +#: catalog/pg_type.c:313 catalog/pg_type.c:319 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "el alineamiento «%c» no es válido para un tipo de largo variable" + +#: catalog/pg_type.c:327 commands/typecmds.c:4164 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "los tipos de tamaño fijo deben tener almacenamiento PLAIN" + +#: catalog/pg_type.c:816 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "no se pudo formar un nombre de tipo de array para el tipo «%s»" + +#: catalog/pg_type.c:921 +#, fuzzy, c-format +#| msgid "Failed while creating memory context \"%s\"." +msgid "Failed while creating a multirange type for type \"%s\"." +msgstr "Falla al crear el contexto de memoria «%s»." + +#: catalog/pg_type.c:922 +#, c-format +msgid "You can manually specify a multirange type name using the \"multirange_type_name\" attribute" +msgstr "" + +#: catalog/storage.c:450 storage/buffer/bufmgr.c:1026 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "la página no es válida en el bloque %u de la relación %s" + +#: catalog/toasting.c:104 commands/indexcmds.c:667 commands/tablecmds.c:6028 +#: commands/tablecmds.c:16336 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "«%s» no es una tabla o vista materializada" + +#: commands/aggregatecmds.c:170 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "sólo las funciones de agregación de conjuntos ordenados pueden ser hipotéticas" + +#: commands/aggregatecmds.c:195 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "el atributo de la función de agregación «%s» no es reconocido" + +#: commands/aggregatecmds.c:205 +#, c-format +msgid "aggregate stype must be specified" +msgstr "debe especificarse el tipo de transición (stype) de la función de agregación" + +#: commands/aggregatecmds.c:209 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "debe especificarse la función de transición (sfunc) de la función de agregación" + +#: commands/aggregatecmds.c:221 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "debe especificarse la función de transición msfunc cuando se especifica mstype" + +#: commands/aggregatecmds.c:225 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "debe especificarse la función de transición minvfunc cuando se especifica mstype" + +#: commands/aggregatecmds.c:232 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "no debe especificarse msfunc sin mstype" + +#: commands/aggregatecmds.c:236 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "no debe especificarse minvfunc sin mstype" + +#: commands/aggregatecmds.c:240 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "no debe especificarse mfinalfunc sin mstype" + +#: commands/aggregatecmds.c:244 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "no debe especificarse msspace sin mstype" + +#: commands/aggregatecmds.c:248 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "no debe especificarse minitcond sin mstype" + +#: commands/aggregatecmds.c:277 +#, c-format +msgid "aggregate input type must be specified" +msgstr "debe especificarse el tipo de entrada de la función de agregación" + +#: commands/aggregatecmds.c:307 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "el tipo base es redundante con el tipo de entrada en la función de agregación" + +#: commands/aggregatecmds.c:350 commands/aggregatecmds.c:391 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "el tipo de transición de la función de agregación no puede ser %s" + +#: commands/aggregatecmds.c:362 +#, c-format +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "las funciones de serialización pueden especificarse sólo cuando el tipo de transición de la función de agregación es %s" + +#: commands/aggregatecmds.c:372 +#, c-format +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "debe especificar ambas o ninguna de las funciones de serialización y deserialización" + +#: commands/aggregatecmds.c:437 commands/functioncmds.c:649 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "el parámetro «parallel» debe ser SAFE, RESTRICTED o UNSAFE" + +#: commands/aggregatecmds.c:493 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "el parámetro «%s» debe ser READ_ONLY, SHAREABLE o READ_WRITE" + +#: commands/alter.c:84 commands/event_trigger.c:174 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "el disparador por eventos «%s» ya existe" + +#: commands/alter.c:87 commands/foreigncmds.c:597 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "el conector de datos externos «%s» ya existe" + +#: commands/alter.c:90 commands/foreigncmds.c:879 +#, c-format +msgid "server \"%s\" already exists" +msgstr "el servidor «%s» ya existe" + +#: commands/alter.c:93 commands/proclang.c:133 +#, c-format +msgid "language \"%s\" already exists" +msgstr "ya existe el lenguaje «%s»" + +#: commands/alter.c:96 commands/publicationcmds.c:183 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "la publicación «%s» ya existe" + +#: commands/alter.c:99 commands/subscriptioncmds.c:398 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "la suscripción «%s» ya existe" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "ya existe una conversión llamada «%s» en el esquema «%s»" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "ya existe un objeto de estadísticas llamado «%s» en el esquema «%s»" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr "el analizador de búsqueda en texto «%s» ya existe en el esquema «%s»" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "el diccionario de búsqueda en texto «%s» ya existe en el esquema «%s»" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "la plantilla de búsqueda en texto «%s» ya existe en el esquema «%s»" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "la configuración de búsqueda en texto «%s» ya existe en el esquema «%s»" + +#: commands/alter.c:215 +#, c-format +msgid "must be superuser to rename %s" +msgstr "debe ser superusuario para cambiar el nombre de «%s»" + +#: commands/alter.c:744 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "debe ser superusuario para definir el esquema de %s" + +#: commands/amcmds.c:60 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "se ha denegado el permiso para crear el método de acceso «%s»" + +#: commands/amcmds.c:62 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "Debe ser superusuario para crear un método de acceso." + +#: commands/amcmds.c:71 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "el método de acceso «%s» ya existe" + +#: commands/amcmds.c:154 commands/indexcmds.c:210 commands/indexcmds.c:818 +#: commands/opclasscmds.c:370 commands/opclasscmds.c:824 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "no existe el método de acceso «%s»" + +#: commands/amcmds.c:243 +#, c-format +msgid "handler function is not specified" +msgstr "no se ha especificado una función manejadora" + +#: commands/amcmds.c:264 commands/event_trigger.c:183 +#: commands/foreigncmds.c:489 commands/proclang.c:80 commands/trigger.c:681 +#: parser/parse_clause.c:940 +#, c-format +msgid "function %s must return type %s" +msgstr "la función %s debe retornar el tipo %s" + +#: commands/analyze.c:227 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "omitiendo «%s»: no se puede analizar esta tabla foránea" + +#: commands/analyze.c:244 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "omitiendo «%s»: no se pueden analizar objetos que no son tablas, ni tablas especiales de sistema" + +#: commands/analyze.c:324 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "analizando la jerarquía de herencia «%s.%s»" + +#: commands/analyze.c:329 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "analizando «%s.%s»" + +#: commands/analyze.c:395 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "la columna «%s» aparece más de una vez en la relación «%s»" + +#: commands/analyze.c:790 +#, fuzzy, c-format +#| msgid "automatic analyze of table \"%s.%s.%s\"" +msgid "automatic analyze of table \"%s.%s.%s\"\n" +msgstr "análisis automático de la tabla «%s.%s.%s»" + +#: commands/analyze.c:811 +#, fuzzy, c-format +#| msgid "system usage: %s\n" +msgid "system usage: %s" +msgstr "uso de sistema: %s\n" + +#: commands/analyze.c:1350 +#, c-format +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "«%s»: se procesaron %d de %u páginas, que contenían %.0f filas vigentes y %.0f filas no vigentes; %d filas en la muestra, %.0f total de filas estimadas" + +#: commands/analyze.c:1430 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "omitiendo el análisis del árbol de herencia «%s.%s» --- este árbol no contiene tablas hijas" + +#: commands/analyze.c:1528 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "omitiendo el análisis del árbol de herencia «%s.%s» --- este árbol no contiene tablas hijas analizables" + +#: commands/async.c:639 +#, c-format +msgid "channel name cannot be empty" +msgstr "el nombre de canal no puede ser vacío" + +#: commands/async.c:645 +#, c-format +msgid "channel name too long" +msgstr "el nombre de canal es demasiado largo" + +#: commands/async.c:650 +#, c-format +msgid "payload string too long" +msgstr "la cadena de carga es demasiado larga" + +#: commands/async.c:869 +#, c-format +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "no se puede hacer PREPARE de una transacción que ha ejecutado LISTEN, UNLISTEN o NOTIFY" + +#: commands/async.c:975 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "demasiadas notificaciones en la cola NOTIFY" + +#: commands/async.c:1646 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "la cola NOTIFY está %.0f%% llena" + +#: commands/async.c:1648 +#, c-format +msgid "The server process with PID %d is among those with the oldest transactions." +msgstr "El proceso servidor con PID %d está entre aquellos con transacciones más antiguas." + +#: commands/async.c:1651 +#, c-format +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." +msgstr "La cola NOTIFY no puede vaciarse hasta que ese proceso cierre su transacción actual." + +#: commands/cluster.c:119 +#, fuzzy, c-format +#| msgid "unrecognized VACUUM option \"%s\"" +msgid "unrecognized CLUSTER option \"%s\"" +msgstr "opción de VACUUM «%s» no reconocida" + +#: commands/cluster.c:147 commands/cluster.c:386 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "no se pueden reordenar tablas temporales de otras sesiones" + +#: commands/cluster.c:155 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "no se puede hacer «cluster» a una tabla particionada" + +#: commands/cluster.c:173 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "no hay un índice de ordenamiento definido para la tabla «%s»" + +#: commands/cluster.c:187 commands/tablecmds.c:13496 commands/tablecmds.c:15364 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "no existe el índice «%s» en la tabla «%s»" + +#: commands/cluster.c:375 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "no se puede reordenar un catálogo compartido" + +#: commands/cluster.c:390 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "no se puede hacer vacuum a tablas temporales de otras sesiones" + +#: commands/cluster.c:456 commands/tablecmds.c:15374 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "«%s» no es un índice de la tabla «%s»" + +#: commands/cluster.c:464 +#, c-format +msgid "cannot cluster on index \"%s\" because access method does not support clustering" +msgstr "no se puede reordenar en índice «%s» porque el método de acceso no soporta reordenamiento" + +#: commands/cluster.c:476 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "no se puede reordenar en índice parcial «%s»" + +#: commands/cluster.c:490 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "no se puede reordenar en el índice no válido «%s»" + +#: commands/cluster.c:514 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "no se puede marcar un índice «clustered» en una tabla particionada" + +#: commands/cluster.c:887 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr "reordenando «%s.%s» usando un recorrido de índice en «%s»" + +#: commands/cluster.c:893 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "reordenando «%s.%s» usando un recorrido secuencial y ordenamiento" + +#: commands/cluster.c:924 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "«%s»: se encontraron %.0f versiones eliminables de filas y %.0f no eliminables en %u páginas" + +#: commands/cluster.c:928 +#, c-format +msgid "" +"%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "" +"%.0f versiones muertas de filas no pueden ser eliminadas aún.\n" +"%s." + +#: commands/collationcmds.c:106 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "el atributo de ordenamiento (collation) «%s» no es reconocido" + +#: commands/collationcmds.c:149 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "el ordenamiento «default» no puede copiarse" + +#: commands/collationcmds.c:182 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "proveedor de ordenamiento no reconocido: %s" + +#: commands/collationcmds.c:191 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "debe especificarse el parámetro «lc_collate»" + +#: commands/collationcmds.c:196 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "debe especificarse el parámetro «lc_ctype»" + +#: commands/collationcmds.c:206 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "los ordenamientos no determinísticos no están soportados con este proveedor" + +#: commands/collationcmds.c:266 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "ya existe un ordenamiento (collation) llamado «%s» para la codificación «%s» en el esquema «%s»" + +#: commands/collationcmds.c:277 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "ya existe un ordenamiento llamado «%s» en el esquema «%s»" + +#: commands/collationcmds.c:325 +#, c-format +msgid "changing version from %s to %s" +msgstr "cambiando versión de %s a %s" + +#: commands/collationcmds.c:340 +#, c-format +msgid "version has not changed" +msgstr "la versión no ha cambiado" + +#: commands/collationcmds.c:454 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "no se pudo convertir el nombre de configuración regional «%s» a etiqueta de lenguaje: %s" + +#: commands/collationcmds.c:512 +#, c-format +msgid "must be superuser to import system collations" +msgstr "debe ser superusuario para importar ordenamientos del sistema" + +#: commands/collationcmds.c:540 commands/copyfrom.c:1500 commands/copyto.c:688 +#: libpq/be-secure-common.c:81 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "no se pudo ejecutar la orden «%s»: %m" + +#: commands/collationcmds.c:671 +#, c-format +msgid "no usable system locales were found" +msgstr "no se encontraron locales de sistema utilizables" + +#: commands/comment.c:61 commands/dbcommands.c:841 commands/dbcommands.c:1037 +#: commands/dbcommands.c:1150 commands/dbcommands.c:1340 +#: commands/dbcommands.c:1588 commands/dbcommands.c:1702 +#: commands/dbcommands.c:2142 utils/init/postinit.c:887 +#: utils/init/postinit.c:992 utils/init/postinit.c:1009 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "no existe la base de datos «%s»" + +#: commands/comment.c:101 commands/seclabel.c:191 parser/parse_utilcmd.c:989 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "«%s» no es una tabla, vista, vista materializada, tipo compuesto, o tabla foránea" + +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1948 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "la función «%s» no fue ejecutada por el manejador de triggers" + +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1957 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "la función «%s» debe ser ejecutada AFTER ROW" + +#: commands/constraint.c:84 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "la función «%s» debe ser ejecutada en INSERT o UPDATE" + +#: commands/conversioncmds.c:67 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "no existe la codificación fuente «%s»" + +#: commands/conversioncmds.c:74 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "no existe la codificación de destino «%s»" + +#: commands/conversioncmds.c:87 +#, c-format +msgid "encoding conversion to or from \"SQL_ASCII\" is not supported" +msgstr "la conversión de codificación desde o hacia a «SQL_ASCII» no está soportada" + +#: commands/conversioncmds.c:100 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "la función de conversión de codificación %s debe retornar tipo %s" + +#: commands/conversioncmds.c:130 +#, fuzzy, c-format +#| msgid "encoding conversion function %s must return type %s" +msgid "encoding conversion function %s returned incorrect result for empty input" +msgstr "la función de conversión de codificación %s debe retornar tipo %s" + +#: commands/copy.c:86 +#, c-format +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "debe ser superusuario o miembro del rol pg_execute_server_program para usar COPY desde o hacia un programa externo" + +#: commands/copy.c:87 commands/copy.c:96 commands/copy.c:103 +#, c-format +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." +msgstr "Cualquier usuario puede usar COPY hacia la salida estándar o desde la entrada estándar. La orden \\copy de psql también puede ser utilizado por cualquier usuario." + +#: commands/copy.c:95 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "debe ser superusuario o miembro del rol pg_read_server_files para hacer COPY desde un archivo" + +#: commands/copy.c:102 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "debe ser superusuario o miembro del rol pg_write_server_files para hacer COPY a un archivo" + +#: commands/copy.c:188 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM no está soportado con seguridad a nivel de registros" + +#: commands/copy.c:189 +#, c-format +msgid "Use INSERT statements instead." +msgstr "Use sentencias INSERT en su lugar." + +#: commands/copy.c:374 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "el formato de COPY «%s» no es reconocido" + +#: commands/copy.c:447 commands/copy.c:463 commands/copy.c:478 +#: commands/copy.c:500 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "el argumento de la opción «%s» debe ser una lista de nombres de columna" + +#: commands/copy.c:515 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "el argumento de la opción «%s» debe ser un nombre válido de codificación" + +#: commands/copy.c:522 commands/dbcommands.c:253 commands/dbcommands.c:1536 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "no se reconoce la opción «%s»" + +#: commands/copy.c:534 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "no se puede especificar DELIMITER en modo BINARY" + +#: commands/copy.c:539 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "no se puede especificar NULL en modo BINARY" + +#: commands/copy.c:561 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "el delimitador de COPY debe ser un solo carácter de un byte" + +#: commands/copy.c:568 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "el delimitador de COPY no puede ser el carácter de nueva línea ni el de retorno de carro" + +#: commands/copy.c:574 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "la representación de null de COPY no puede usar el carácter de nueva línea ni el de retorno de carro" + +#: commands/copy.c:591 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "el delimitador de COPY no puede ser «%s»" + +#: commands/copy.c:597 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "el «header» de COPY está disponible sólo en modo CSV" + +#: commands/copy.c:603 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "el «quote» de COPY está disponible sólo en modo CSV" + +#: commands/copy.c:608 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "la comilla («quote») de COPY debe ser un solo carácter de un byte" + +#: commands/copy.c:613 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "el delimitador de COPY y la comilla («quote») deben ser diferentes" + +#: commands/copy.c:619 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "escape de COPY disponible sólo en modo CSV" + +#: commands/copy.c:624 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "el escape de COPY debe ser un sólo carácter de un byte" + +#: commands/copy.c:630 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "el forzado de comillas de COPY sólo está disponible en modo CSV" + +#: commands/copy.c:634 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "el forzado de comillas de COPY sólo está disponible en COPY TO" + +#: commands/copy.c:640 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "el forzado de no nulos en COPY sólo está disponible en modo CSV" + +#: commands/copy.c:644 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "el forzado de no nulos en COPY sólo está disponible usando COPY FROM" + +#: commands/copy.c:650 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "el forzado de nulos en COPY sólo está disponible en modo CSV" + +#: commands/copy.c:655 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "el forzado de nulos en COPY sólo está disponible usando COPY FROM" + +#: commands/copy.c:661 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "el delimitador de COPY no debe aparecer en la especificación NULL" + +#: commands/copy.c:668 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "el carácter de «quote» de CSV no debe aparecer en la especificación NULL" + +#: commands/copy.c:729 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "la columna «%s» es una columna generada" + +#: commands/copy.c:731 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "Las columnas generadas no pueden usarse en COPY." + +#: commands/copy.c:746 commands/indexcmds.c:1754 commands/statscmds.c:238 +#: commands/tablecmds.c:2366 commands/tablecmds.c:3022 +#: commands/tablecmds.c:3515 parser/parse_relation.c:3593 +#: parser/parse_relation.c:3613 utils/adt/tsvector_op.c:2680 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "no existe la columna «%s»" + +#: commands/copy.c:753 commands/tablecmds.c:2392 commands/trigger.c:933 +#: parser/parse_target.c:1080 parser/parse_target.c:1091 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "la columna «%s» fue especificada más de una vez" + +#: commands/copyfrom.c:127 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, línea %s, columna %s" + +#: commands/copyfrom.c:131 commands/copyfrom.c:172 +#, c-format +msgid "COPY %s, line %s" +msgstr "COPY %s, línea %s" + +#: commands/copyfrom.c:142 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, línea %s, columna %s: «%s»" + +#: commands/copyfrom.c:150 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, línea %s, columna %s: entrada nula" + +#: commands/copyfrom.c:166 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, línea %s: «%s»" + +#: commands/copyfrom.c:566 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "no se puede copiar hacia la vista «%s»" + +#: commands/copyfrom.c:568 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "Para posibilitar «copy» a una vista, provea un disparador INSTEAD OF INSERT." + +#: commands/copyfrom.c:572 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "no se puede copiar hacia la vista materializada «%s»" + +#: commands/copyfrom.c:577 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "no se puede copiar hacia la secuencia «%s»" + +#: commands/copyfrom.c:582 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "no se puede copiar hacia la relación «%s» porque no es una tabla" + +#: commands/copyfrom.c:622 +#, c-format +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "no se puede hacer COPY FREEZE a una tabla particionada" + +#: commands/copyfrom.c:637 +#, c-format +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "no se puede ejecutar COPY FREEZE debido a actividad anterior en la transacción" + +#: commands/copyfrom.c:643 +#, c-format +msgid "cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "no se puede ejecutar COPY FREEZE porque la tabla no fue creada ni truncada en la subtransacción en curso" + +#: commands/copyfrom.c:1264 commands/copyto.c:618 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "la columna FORCE_NOT_NULL «%s» no es referenciada en COPY" + +#: commands/copyfrom.c:1287 commands/copyto.c:641 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "la columna FORCE_NULL «%s» no es referenciada en COPY" + +#: commands/copyfrom.c:1519 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY FROM indica al proceso servidor de PostgreSQL leer un archivo. Puede desear usar una facilidad del lado del cliente como \\copy de psql." + +#: commands/copyfrom.c:1532 commands/copyto.c:740 +#, c-format +msgid "\"%s\" is a directory" +msgstr "«%s» es un directorio" + +#: commands/copyfrom.c:1600 commands/copyto.c:302 libpq/be-secure-common.c:105 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "no se pudo cerrar la tubería a la orden externa: %m" + +#: commands/copyfrom.c:1615 commands/copyto.c:307 +#, c-format +msgid "program \"%s\" failed" +msgstr "el programa «%s» falló" + +#: commands/copyfromparse.c:199 +#, c-format +msgid "COPY file signature not recognized" +msgstr "la signatura del archivo COPY no es reconocido" + +#: commands/copyfromparse.c:204 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "el encabezado del archivo COPY no es válido (faltan campos)" + +#: commands/copyfromparse.c:208 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "encabezado de archivo COPY no válido (WITH OIDS)" + +#: commands/copyfromparse.c:213 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "valores requeridos no reconocidos en encabezado de COPY" + +#: commands/copyfromparse.c:219 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "el encabezado del archivo COPY no es válido (falta el largo)" + +#: commands/copyfromparse.c:226 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "el encabezado del archivo COPY no es válido (largo incorrecto)" + +#: commands/copyfromparse.c:255 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "no se pudo leer desde archivo COPY: %m" + +#: commands/copyfromparse.c:277 commands/copyfromparse.c:302 +#: tcop/postgres.c:360 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "se encontró fin de archivo inesperado en una conexión con una transacción abierta" + +#: commands/copyfromparse.c:293 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "se recibió un mensaje de tipo 0x%02X inesperado durante COPY desde la entrada estándar" + +#: commands/copyfromparse.c:316 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "falló COPY desde la entrada estándar: %s" + +#: commands/copyfromparse.c:841 commands/copyfromparse.c:1451 +#: commands/copyfromparse.c:1681 +#, c-format +msgid "extra data after last expected column" +msgstr "datos extra después de la última columna esperada" + +#: commands/copyfromparse.c:855 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "faltan datos en la columna «%s»" + +#: commands/copyfromparse.c:933 +#, c-format +msgid "received copy data after EOF marker" +msgstr "se recibieron datos de copy después del marcador EOF" + +#: commands/copyfromparse.c:940 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "la cantidad de registros es %d, pero se esperaban %d" + +#: commands/copyfromparse.c:1233 commands/copyfromparse.c:1250 +#, c-format +msgid "literal carriage return found in data" +msgstr "se encontró un retorno de carro literal en los datos" + +#: commands/copyfromparse.c:1234 commands/copyfromparse.c:1251 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "se encontró un retorno de carro fuera de comillas en los datos" + +#: commands/copyfromparse.c:1236 commands/copyfromparse.c:1253 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "Use «\\r» para representar el retorno de carro." + +#: commands/copyfromparse.c:1237 commands/copyfromparse.c:1254 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "Use un campo CSV entre comillas para representar el retorno de carro." + +#: commands/copyfromparse.c:1266 +#, c-format +msgid "literal newline found in data" +msgstr "se encontró un salto de línea literal en los datos" + +#: commands/copyfromparse.c:1267 +#, c-format +msgid "unquoted newline found in data" +msgstr "se encontró un salto de línea fuera de comillas en los datos" + +#: commands/copyfromparse.c:1269 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "Use «\\n» para representar un salto de línea." + +#: commands/copyfromparse.c:1270 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "Use un campo CSV entre comillas para representar un salto de línea." + +#: commands/copyfromparse.c:1316 commands/copyfromparse.c:1352 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "el marcador fin-de-copy no coincide con el estilo previo de salto de línea" + +#: commands/copyfromparse.c:1325 commands/copyfromparse.c:1341 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "marcador fin-de-copy corrupto" + +#: commands/copyfromparse.c:1765 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "un valor entre comillas está inconcluso" + +#: commands/copyfromparse.c:1841 commands/copyfromparse.c:1860 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "EOF inesperado en datos de COPY" + +#: commands/copyfromparse.c:1850 +#, c-format +msgid "invalid field size" +msgstr "el tamaño de campo no es válido" + +#: commands/copyfromparse.c:1873 +#, c-format +msgid "incorrect binary data format" +msgstr "el formato de datos binarios es incorrecto" + +#: commands/copyto.c:235 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "no se pudo escribir al programa COPY: %m" + +#: commands/copyto.c:240 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "no se pudo escribir archivo COPY: %m" + +#: commands/copyto.c:370 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "no se puede copiar desde la vista «%s»" + +#: commands/copyto.c:372 commands/copyto.c:378 commands/copyto.c:384 +#: commands/copyto.c:395 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "Intente la forma COPY (SELECT ...) TO." + +#: commands/copyto.c:376 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "no se puede copiar desde la vista materializada «%s»" + +#: commands/copyto.c:382 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "no se puede copiar desde la tabla foránea «%s»" + +#: commands/copyto.c:388 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "no se puede copiar desde la secuencia «%s»" + +#: commands/copyto.c:393 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "no se puede hacer copy de la tabla particionada «%s»" + +#: commands/copyto.c:399 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "no se puede copiar desde la relación «%s» porque no es una tabla" + +#: commands/copyto.c:457 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "las reglas DO INSTEAD NOTHING no están soportadas para COPY" + +#: commands/copyto.c:471 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "las reglas DO INSTEAD condicionales no están soportadas para COPY" + +#: commands/copyto.c:475 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "las reglas DO ALSO no están soportadas para COPY" + +#: commands/copyto.c:480 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "las reglas DO INSTEAD de múltiples sentencias no están soportadas para COPY" + +#: commands/copyto.c:490 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO) no está soportado" + +#: commands/copyto.c:507 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "la consulta COPY debe tener una cláusula RETURNING" + +#: commands/copyto.c:536 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "la relación referenciada por la sentencia COPY ha cambiado" + +#: commands/copyto.c:595 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "la columna FORCE_QUOTE «%s» no es referenciada en COPY" + +#: commands/copyto.c:705 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "no se permiten rutas relativas para COPY hacia un archivo" + +#: commands/copyto.c:724 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "no se pudo abrir el archivo «%s» para escritura: %m" + +#: commands/copyto.c:727 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TO indica al proceso servidor PostgreSQL escribir a un archivo. Puede desear usar facilidades del lado del cliente, como \\copy de psql." + +#: commands/createas.c:215 commands/createas.c:517 +#, c-format +msgid "too many column names were specified" +msgstr "se especificaron demasiados nombres de columna" + +#: commands/createas.c:540 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "las políticas no están implementadas para esta orden" + +#: commands/dbcommands.c:246 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATION ya no está soportado" + +#: commands/dbcommands.c:247 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "Considere usar tablespaces." + +#: commands/dbcommands.c:261 +#, c-format +msgid "LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE." +msgstr "LOCALE no puede configurarse junto con LC_COLLATE o LC_CTYPE." + +#: commands/dbcommands.c:279 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%d no es un código válido de codificación" + +#: commands/dbcommands.c:290 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%s no es un nombre válido de codificación" + +#: commands/dbcommands.c:314 commands/dbcommands.c:1569 commands/user.c:275 +#: commands/user.c:691 +#, c-format +msgid "invalid connection limit: %d" +msgstr "límite de conexión no válido: %d" + +#: commands/dbcommands.c:333 +#, c-format +msgid "permission denied to create database" +msgstr "se ha denegado el permiso para crear la base de datos" + +#: commands/dbcommands.c:356 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "no existe la base de datos patrón «%s»" + +#: commands/dbcommands.c:368 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "se ha denegado el permiso para copiar la base de datos «%s»" + +#: commands/dbcommands.c:384 +#, c-format +msgid "invalid server encoding %d" +msgstr "la codificación de servidor %d no es válida" + +#: commands/dbcommands.c:390 commands/dbcommands.c:395 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "nombre de configuración regional no válido: «%s»" + +#: commands/dbcommands.c:415 +#, c-format +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" +msgstr "la nueva codificación (%s) es incompatible con la codificación de la base de datos patrón (%s)" + +#: commands/dbcommands.c:418 +#, c-format +msgid "Use the same encoding as in the template database, or use template0 as template." +msgstr "Use la misma codificación que en la base de datos patrón, o bien use template0 como patrón." + +#: commands/dbcommands.c:423 +#, c-format +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" +msgstr "la nueva «collation» (%s) es incompatible con la «collation» de la base de datos patrón (%s)" + +#: commands/dbcommands.c:425 +#, c-format +msgid "Use the same collation as in the template database, or use template0 as template." +msgstr "Use la misma «collation» que en la base de datos patrón, o bien use template0 como patrón." + +#: commands/dbcommands.c:430 +#, c-format +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" +msgstr "el nuevo LC_CTYPE (%s) es incompatible con el LC_CTYPE de la base de datos patrón (%s)" + +#: commands/dbcommands.c:432 +#, c-format +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." +msgstr "Use el mismo LC_CTYPE que en la base de datos patrón, o bien use template0 como patrón." + +#: commands/dbcommands.c:454 commands/dbcommands.c:1196 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "no puede usarse pg_global como tablespace por omisión" + +#: commands/dbcommands.c:480 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "no se puede asignar el nuevo tablespace por omisión «%s»" + +#: commands/dbcommands.c:482 +#, c-format +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." +msgstr "Hay un conflicto puesto que la base de datos «%s» ya tiene algunas tablas en este tablespace." + +#: commands/dbcommands.c:512 commands/dbcommands.c:1066 +#, c-format +msgid "database \"%s\" already exists" +msgstr "la base de datos «%s» ya existe" + +#: commands/dbcommands.c:526 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "la base de datos de origen «%s» está siendo utilizada por otros usuarios" + +#: commands/dbcommands.c:769 commands/dbcommands.c:784 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "la codificación «%s» no coincide con la configuración regional «%s»" + +#: commands/dbcommands.c:772 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "El parámetro LC_CTYPE escogido requiere la codificación «%s»." + +#: commands/dbcommands.c:787 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "El parámetro LC_COLLATE escogido requiere la codificación «%s»." + +#: commands/dbcommands.c:848 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "no existe la base de datos «%s», omitiendo" + +#: commands/dbcommands.c:872 +#, c-format +msgid "cannot drop a template database" +msgstr "no se puede borrar una base de datos patrón" + +#: commands/dbcommands.c:878 +#, c-format +msgid "cannot drop the currently open database" +msgstr "no se puede eliminar la base de datos activa" + +#: commands/dbcommands.c:891 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "la base de datos «%s» está en uso por un slot de replicación activo" + +#: commands/dbcommands.c:893 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "Hay %d slot activo." +msgstr[1] "Hay %d slots activos." + +#: commands/dbcommands.c:907 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "la base de datos «%s» está siendo utilizada por suscripciones de replicación lógica" + +#: commands/dbcommands.c:909 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "Hay %d suscripción." +msgstr[1] "Hay %d suscripciones." + +#: commands/dbcommands.c:930 commands/dbcommands.c:1088 +#: commands/dbcommands.c:1218 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "la base de datos «%s» está siendo utilizada por otros usuarios" + +#: commands/dbcommands.c:1048 +#, c-format +msgid "permission denied to rename database" +msgstr "se ha denegado el permiso para cambiar el nombre a la base de datos" + +#: commands/dbcommands.c:1077 +#, c-format +msgid "current database cannot be renamed" +msgstr "no se puede cambiar el nombre de la base de datos activa" + +#: commands/dbcommands.c:1174 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "no se puede cambiar el tablespace de la base de datos activa" + +#: commands/dbcommands.c:1277 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "algunas relaciones de la base de datos «%s» ya están en el tablespace «%s»" + +#: commands/dbcommands.c:1279 +#, c-format +msgid "You must move them back to the database's default tablespace before using this command." +msgstr "Debe moverlas de vuelta al tablespace por omisión de la base de datos antes de ejecutar esta orden." + +#: commands/dbcommands.c:1404 commands/dbcommands.c:1980 +#: commands/dbcommands.c:2203 commands/dbcommands.c:2261 +#: commands/tablespace.c:631 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "algunos archivos inútiles pueden haber quedado en el directorio \"%s\"" + +#: commands/dbcommands.c:1460 +#, c-format +msgid "unrecognized DROP DATABASE option \"%s\"" +msgstr "opción de DROP DATABASE «%s» no reconocida" + +#: commands/dbcommands.c:1550 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "la opción «%s» no puede ser especificada con otras opciones" + +#: commands/dbcommands.c:1606 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "no se pueden prohibir las conexiones para la base de datos actual" + +#: commands/dbcommands.c:1742 +#, c-format +msgid "permission denied to change owner of database" +msgstr "se ha denegado el permiso para cambiar el dueño de la base de datos" + +#: commands/dbcommands.c:2086 +#, c-format +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." +msgstr "Hay otras %d sesiones y %d transacciones preparadas usando la base de datos." + +#: commands/dbcommands.c:2089 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "Hay %d otra sesión usando la base de datos." +msgstr[1] "Hay otras %d sesiones usando la base de datos." + +#: commands/dbcommands.c:2094 storage/ipc/procarray.c:3726 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "Hay %d otra transacción preparada usando la base de datos." +msgstr[1] "Hay otras %d transacciones preparadas usando la base de datos." + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 +#: commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%s requiere un parámetro" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 +#: commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%s requiere un valor numérico" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "«%s» requiere un valor lógico (booleano)" + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%s requiere valor entero" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "el argumento de %s debe ser un nombre" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "el argumento de %s debe ser un nombre de tipo" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "argumento no válido para %s: «%s»" + +#: commands/dropcmds.c:100 commands/functioncmds.c:1410 +#: utils/adt/ruleutils.c:2806 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "«%s» es una función de agregación" + +#: commands/dropcmds.c:102 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "Use DROP AGGREGATE para eliminar funciones de agregación." + +#: commands/dropcmds.c:158 commands/sequence.c:447 commands/tablecmds.c:3599 +#: commands/tablecmds.c:3757 commands/tablecmds.c:3802 +#: commands/tablecmds.c:15797 tcop/utility.c:1291 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "no existe la relación «%s», omitiendo" + +#: commands/dropcmds.c:188 commands/dropcmds.c:287 commands/tablecmds.c:1248 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "el esquema «%s» no existe, omitiendo" + +#: commands/dropcmds.c:228 commands/dropcmds.c:267 commands/tablecmds.c:272 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "el tipo «%s» no existe, omitiendo" + +#: commands/dropcmds.c:257 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "no existe el método de acceso «%s», omitiendo" + +#: commands/dropcmds.c:275 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "no existe el ordenamiento (collation) «%s», omitiendo" + +#: commands/dropcmds.c:282 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "no existe la conversión «%s», omitiendo" + +#: commands/dropcmds.c:293 commands/statscmds.c:630 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "no existe el objeto de estadísticas «%s», omitiendo" + +#: commands/dropcmds.c:300 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr "el analizador de búsqueda en texto «%s» no existe, omitiendo" + +#: commands/dropcmds.c:307 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "el diccionario de búsqueda en texto «%s» no existe, omitiendo" + +#: commands/dropcmds.c:314 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "la plantilla de búsqueda en texto «%s» no existe, omitiendo" + +#: commands/dropcmds.c:321 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "no existe la configuración de búsqueda en texto «%s», omitiendo" + +#: commands/dropcmds.c:326 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "no existe la extensión «%s», omitiendo" + +#: commands/dropcmds.c:336 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "no existe la función %s(%s), omitiendo" + +#: commands/dropcmds.c:349 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "el procedimiento %s(%s) no existe, omitiendo" + +#: commands/dropcmds.c:362 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "no existe la rutina %s(%s), omitiendo" + +#: commands/dropcmds.c:375 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "la función de agregación %s(%s) no existe, omitiendo" + +#: commands/dropcmds.c:388 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "el operador %s no existe, omitiendo" + +#: commands/dropcmds.c:394 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "el lenguaje «%s» no existe, omitiendo" + +#: commands/dropcmds.c:403 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "no existe la conversión del tipo %s al tipo %s, omitiendo" + +#: commands/dropcmds.c:412 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "la transformación para el tipo %s lenguaje «%s» no existe, omitiendo" + +#: commands/dropcmds.c:420 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "disparador «%s» para la relación «%s» no existe, omitiendo" + +#: commands/dropcmds.c:429 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "la política «%s» para la relación «%s» no existe, omitiendo" + +#: commands/dropcmds.c:436 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "el disparador por eventos «%s» no existe, omitiendo" + +#: commands/dropcmds.c:442 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "la regla «%s» para la relación «%s» no existe, omitiendo" + +#: commands/dropcmds.c:449 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "no existe el conector de datos externos «%s», omitiendo" + +#: commands/dropcmds.c:453 commands/foreigncmds.c:1351 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "el servidor «%s» no existe, omitiendo" + +#: commands/dropcmds.c:462 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "no existe la clase de operadores «%s» para el método de acceso «%s», omitiendo" + +#: commands/dropcmds.c:474 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "no existe la familia de operadores «%s» para el método de acceso «%s», omitiendo" + +#: commands/dropcmds.c:481 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "no existe la publicación «%s», omitiendo" + +#: commands/event_trigger.c:125 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "se ha denegado el permiso para crear el disparador por eventos «%s»" + +#: commands/event_trigger.c:127 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "Debe ser superusuario para crear un disparador por eventos." + +#: commands/event_trigger.c:136 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "nomre de evento «%s» no reconocido" + +#: commands/event_trigger.c:153 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "variable de filtro «%s» no reconocida" + +#: commands/event_trigger.c:207 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "el valor de filtro «%s» no es reconocido por la variable de filtro «%s»" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:213 commands/event_trigger.c:235 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "los disparadores por eventos no están soportados para %s" + +#: commands/event_trigger.c:248 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "la variable de filtro «%s» fue especificada más de una vez" + +#: commands/event_trigger.c:377 commands/event_trigger.c:421 +#: commands/event_trigger.c:515 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "no existe el disparador por eventos «%s»" + +#: commands/event_trigger.c:483 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "se ha denegado el permiso para cambiar el dueño del disparador por eventos «%s»" + +#: commands/event_trigger.c:485 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "El dueño de un disparador por eventos debe ser un superusuario." + +#: commands/event_trigger.c:1304 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%s sólo puede invocarse en una función de un disparador en el evento sql_drop" + +#: commands/event_trigger.c:1424 commands/event_trigger.c:1445 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%s sólo puede invocarse en una función de un disparador en el evento table_rewrite" + +#: commands/event_trigger.c:1862 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%s sólo puede invocarse en una función de un disparador por eventos" + +#: commands/explain.c:218 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "valor no reconocido para la opción de EXPLAIN «%s»: «%s»" + +#: commands/explain.c:225 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "opción de EXPLAIN «%s» no reconocida" + +#: commands/explain.c:233 +#, c-format +msgid "EXPLAIN option WAL requires ANALYZE" +msgstr "la opción WAL de EXPLAIN requiere ANALYZE" + +#: commands/explain.c:242 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "la opción TIMING de EXPLAIN requiere ANALYZE" + +#: commands/extension.c:173 commands/extension.c:3013 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "no existe la extensión «%s»" + +#: commands/extension.c:272 commands/extension.c:281 commands/extension.c:293 +#: commands/extension.c:303 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "nombre de extensión no válido: «%s»" + +#: commands/extension.c:273 +#, c-format +msgid "Extension names must not be empty." +msgstr "Los nombres de extensión no deben ser vacíos." + +#: commands/extension.c:282 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "Los nombres de extensión no deben contener «--»." + +#: commands/extension.c:294 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "Los nombres de extensión no deben empezar ni terminar con «-»." + +#: commands/extension.c:304 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "Los nombres de extensión no deben contener caracteres separadores de directorio." + +#: commands/extension.c:319 commands/extension.c:328 commands/extension.c:337 +#: commands/extension.c:347 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "nombre de versión de extensión no válido: «%s»" + +#: commands/extension.c:320 +#, c-format +msgid "Version names must not be empty." +msgstr "Los nombres de versión no deben ser vacíos." + +#: commands/extension.c:329 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "Los nombres de versión no deben contener «--»." + +#: commands/extension.c:338 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "Los nombres de versión no deben empezar ni terminar con «-»." + +#: commands/extension.c:348 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "Los nombres de versión no deben contener caracteres separadores de directorio." + +#: commands/extension.c:498 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "no se pudo abrir el archivo de control de extensión «%s»: %m" + +#: commands/extension.c:520 commands/extension.c:530 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "el parámetro «%s» no se puede cambiar en un archivo control secundario de extensión" + +#: commands/extension.c:552 commands/extension.c:560 commands/extension.c:568 +#: utils/misc/guc.c:7092 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "el parámetro «%s» requiere un valor lógico (booleano)" + +#: commands/extension.c:577 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "«%s» no es un nombre válido de codificación" + +#: commands/extension.c:591 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "el parámetro «%s» debe ser una lista de nombres de extensión" + +#: commands/extension.c:598 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "parámetro no reconocido «%s» en el archivo «%s»" + +#: commands/extension.c:607 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr "el parámetro «schema» no puede ser especificado cuando «relocatable» es verdadero" + +#: commands/extension.c:785 +#, c-format +msgid "transaction control statements are not allowed within an extension script" +msgstr "las sentencias de control de transacción no están permitidos dentro de un guión de transacción" + +#: commands/extension.c:861 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "se ha denegado el permiso para crear la extensión «%s»" + +#: commands/extension.c:864 +#, c-format +msgid "Must have CREATE privilege on current database to create this extension." +msgstr "Debe tener privilegio CREATE en la base de datos actual para crear esta extensión." + +#: commands/extension.c:865 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "Debe ser superusuario para crear esta extensión." + +#: commands/extension.c:869 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "se ha denegado el permiso para actualizar la extensión «%s»" + +#: commands/extension.c:872 +#, c-format +msgid "Must have CREATE privilege on current database to update this extension." +msgstr "Debe tener privilegio CREATE en la base de datos actual para actualizar esta extensión." + +#: commands/extension.c:873 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "Debe ser superusuario para actualizar esta extensión." + +#: commands/extension.c:1200 +#, c-format +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "la extensión «%s» no tiene ruta de actualización desde la versión «%s» hasta la versión «%s»" + +#: commands/extension.c:1408 commands/extension.c:3074 +#, c-format +msgid "version to install must be specified" +msgstr "la versión a instalar debe ser especificada" + +#: commands/extension.c:1445 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "la extensión «%s» no tiene script de instalación ni ruta de actualización para la versión «%s»" + +#: commands/extension.c:1479 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "la extensión «%s» debe ser instalada en el esquema «%s»" + +#: commands/extension.c:1639 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "detectada una dependencia cíclica entre las extensiones «%s» y «%s»" + +#: commands/extension.c:1644 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "instalando la extensión requerida «%s»" + +#: commands/extension.c:1667 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr "la extensión requerida «%s» no está instalada" + +#: commands/extension.c:1670 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "Use CREATE EXTENSION ... CASCADE para instalar además las extensiones requeridas." + +#: commands/extension.c:1705 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "la extensión «%s» ya existe, omitiendo" + +#: commands/extension.c:1712 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "la extensión «%s» ya existe" + +#: commands/extension.c:1723 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "los CREATE EXTENSION anidados no están soportados" + +#: commands/extension.c:1896 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "no se puede eliminar la extensión «%s» porque está siendo modificada" + +#: commands/extension.c:2457 +#, c-format +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "%s sólo puede invocarse desde un script SQL ejecutado por CREATE EXTENSION" + +#: commands/extension.c:2469 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "el OID %u no hace referencia a una tabla" + +#: commands/extension.c:2474 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "el tabla «%s» no es un miembro de la extensión que se está creando" + +#: commands/extension.c:2828 +#, c-format +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" +msgstr "no se puede mover la extensión «%s» al esquema «%s» porque la extensión contiene al esquema" + +#: commands/extension.c:2869 commands/extension.c:2932 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "la extensión «%s» no soporta SET SCHEMA" + +#: commands/extension.c:2934 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "%s no está en el esquema de la extensión, «%s»" + +#: commands/extension.c:2993 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "los ALTER EXTENSION anidados no están soportados" + +#: commands/extension.c:3085 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "la versión «%s» de la extensión «%s» ya está instalada" + +#: commands/extension.c:3297 +#, fuzzy, c-format +#| msgid "cannot cast jsonb object to type %s" +msgid "cannot add an object of this type to an extension" +msgstr "no se puede convertir un objeto jsonb a tipo %s" + +#: commands/extension.c:3355 +#, c-format +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" +msgstr "no se puede agregar el esquema «%s» a la extensión «%s» porque el esquema contiene la extensión" + +#: commands/extension.c:3383 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "%s no es un miembro de la extensión «%s»" + +#: commands/extension.c:3449 +#, c-format +msgid "file \"%s\" is too large" +msgstr "el archivo «%s» es demasiado grande" + +#: commands/foreigncmds.c:148 commands/foreigncmds.c:157 +#, c-format +msgid "option \"%s\" not found" +msgstr "opción «%s» no encontrada" + +#: commands/foreigncmds.c:167 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "la opción «%s» fue especificada más de una vez" + +#: commands/foreigncmds.c:221 commands/foreigncmds.c:229 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "se ha denegado el permiso para cambiar el dueño del conector de datos externos «%s»" + +#: commands/foreigncmds.c:223 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "Debe ser superusuario para cambiar el dueño de un conector de datos externos." + +#: commands/foreigncmds.c:231 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "El dueño de un conector de datos externos debe ser un superusuario." + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:711 foreign/foreign.c:701 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "no existe el conector de datos externos «%s»" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "se ha denegado el permiso para crear el conector de datos externos «%s»" + +#: commands/foreigncmds.c:586 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "Debe ser superusuario para crear un conector de datos externos." + +#: commands/foreigncmds.c:701 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "se ha denegado el permiso para cambiar el conector de datos externos «%s»" + +#: commands/foreigncmds.c:703 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "Debe ser superusuario para alterar un conector de datos externos." + +#: commands/foreigncmds.c:734 +#, c-format +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" +msgstr "al cambiar el manejador del conector de datos externos, el comportamiento de las tablas foráneas existentes puede cambiar" + +#: commands/foreigncmds.c:749 +#, c-format +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +msgstr "al cambiar el validador del conector de datos externos, las opciones para los objetos dependientes de él pueden volverse no válidas" + +#: commands/foreigncmds.c:871 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "el servidor «%s» ya existe, omitiendo" + +#: commands/foreigncmds.c:1135 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "el mapeo de usuario «%s» ya existe para el servidor «%s», omitiendo" + +#: commands/foreigncmds.c:1145 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "el mapeo de usuario «%s» ya existe para el servidor «%s»" + +#: commands/foreigncmds.c:1245 commands/foreigncmds.c:1365 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "no existe el mapeo de usuario «%s» para el servidor «%s»" + +#: commands/foreigncmds.c:1370 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "no existe el mapeo de usuario «%s» para el servidor «%s», omitiendo" + +#: commands/foreigncmds.c:1498 foreign/foreign.c:389 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "el conector de datos externos «%s» no tiene manejador" + +#: commands/foreigncmds.c:1504 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "el conector de datos externos «%s» no soporta IMPORT FOREIGN SCHEMA" + +#: commands/foreigncmds.c:1607 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "importando la tabla foránea «%s»" + +#: commands/functioncmds.c:108 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "una función SQL no puede retornar el tipo inconcluso %s" + +#: commands/functioncmds.c:113 +#, c-format +msgid "return type %s is only a shell" +msgstr "el tipo de retorno %s está inconcluso" + +#: commands/functioncmds.c:143 parser/parse_type.c:354 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "no se puede especificar un modificador de tipo para el tipo inconcluso «%s»" + +#: commands/functioncmds.c:149 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "el tipo «%s» no ha sido definido aún" + +#: commands/functioncmds.c:150 +#, c-format +msgid "Creating a shell type definition." +msgstr "Creando una definición de tipo inconclusa." + +#: commands/functioncmds.c:249 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "las funciones SQL no pueden aceptar el tipo inconcluso %s" + +#: commands/functioncmds.c:255 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "las funciones de agregación no pueden aceptar el tipo inconcluso %s" + +#: commands/functioncmds.c:260 +#, c-format +msgid "argument type %s is only a shell" +msgstr "el tipo de argumento %s está inconcluso" + +#: commands/functioncmds.c:270 +#, c-format +msgid "type %s does not exist" +msgstr "no existe el tipo %s" + +#: commands/functioncmds.c:284 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "las funciones de agregación no pueden aceptar argumentos de conjunto" + +#: commands/functioncmds.c:288 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "los procedimientos no pueden aceptar argumentos de conjunto" + +#: commands/functioncmds.c:292 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "funciones no pueden aceptar argumentos de conjunto" + +#: commands/functioncmds.c:302 +#, fuzzy, c-format +#| msgid "VARIADIC parameter must be the last input parameter" +msgid "VARIADIC parameter must be the last input parameter" +msgstr "el parámetro VARIADIC debe ser el último parámetro de entrada" + +#: commands/functioncmds.c:322 +#, fuzzy, c-format +#| msgid "VARIADIC parameter must be the last input parameter" +msgid "VARIADIC parameter must be the last parameter" +msgstr "el parámetro VARIADIC debe ser el último parámetro de entrada" + +#: commands/functioncmds.c:347 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "el parámetro VARIADIC debe ser un array" + +#: commands/functioncmds.c:392 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "nombre de parámetro «%s» usado más de una vez" + +#: commands/functioncmds.c:410 +#, c-format +msgid "only input parameters can have default values" +msgstr "solo los parámetros de entrada pueden tener valores por omisión" + +#: commands/functioncmds.c:425 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "no se pueden usar referencias a tablas en el valor por omisión de un parámetro" + +#: commands/functioncmds.c:449 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "los parámetros de entrada después de uno que tenga valor por omisión también deben tener valores por omisión" + +#: commands/functioncmds.c:459 +#, fuzzy, c-format +#| msgid "input parameters after one with a default value must also have defaults" +msgid "procedure OUT parameters cannot appear after one with a default value" +msgstr "los parámetros de entrada después de uno que tenga valor por omisión también deben tener valores por omisión" + +#: commands/functioncmds.c:611 commands/functioncmds.c:802 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "atributo no válido en definición de procedimiento" + +#: commands/functioncmds.c:707 +#, c-format +msgid "support function %s must return type %s" +msgstr "la función de soporte %s debe retornar el tipo %s" + +#: commands/functioncmds.c:718 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "debe ser superusuario para especificar una función de soporte" + +#: commands/functioncmds.c:851 commands/functioncmds.c:1455 +#, c-format +msgid "COST must be positive" +msgstr "COST debe ser positivo" + +#: commands/functioncmds.c:859 commands/functioncmds.c:1463 +#, c-format +msgid "ROWS must be positive" +msgstr "ROWS debe ser positivo" + +#: commands/functioncmds.c:888 +#, c-format +msgid "no function body specified" +msgstr "no se ha especificado un cuerpo para la función" + +#: commands/functioncmds.c:893 +#, fuzzy, c-format +#| msgid "no function body specified" +msgid "duplicate function body specified" +msgstr "no se ha especificado un cuerpo para la función" + +#: commands/functioncmds.c:898 +#, c-format +msgid "inline SQL function body only valid for language SQL" +msgstr "" + +#: commands/functioncmds.c:940 +#, fuzzy, c-format +#| msgid "event trigger functions cannot have declared arguments" +msgid "SQL function with unquoted function body cannot have polymorphic arguments" +msgstr "las funciones de disparador por eventos no pueden tener argumentos declarados" + +#: commands/functioncmds.c:966 commands/functioncmds.c:985 +#, fuzzy, c-format +#| msgid "%s is not allowed in a SQL function" +msgid "%s is not yet supported in unquoted SQL function body" +msgstr "%s no está permitido en una función SQL" + +#: commands/functioncmds.c:1013 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "sólo se requiere un item AS para el lenguaje «%s»" + +#: commands/functioncmds.c:1118 +#, c-format +msgid "no language specified" +msgstr "no se ha especificado el lenguaje" + +#: commands/functioncmds.c:1126 commands/functioncmds.c:2128 +#: commands/proclang.c:237 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "no existe el lenguaje «%s»" + +#: commands/functioncmds.c:1128 commands/functioncmds.c:2130 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Use CREATE EXTENSION para cargar el lenguaje en la base de datos." + +#: commands/functioncmds.c:1163 commands/functioncmds.c:1447 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "sólo un superusuario puede definir funciones «leakproof»" + +#: commands/functioncmds.c:1214 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "tipo de retorno de función debe ser %s debido a los parámetros OUT" + +#: commands/functioncmds.c:1227 +#, c-format +msgid "function result type must be specified" +msgstr "el tipo de retorno de la función debe ser especificado" + +#: commands/functioncmds.c:1281 commands/functioncmds.c:1467 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "ROWS no es aplicable cuando una función no retorna un conjunto" + +#: commands/functioncmds.c:1567 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "el tipo de origen %s es un pseudotipo" + +#: commands/functioncmds.c:1573 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "el tipo de retorno %s es un pseudotipo" + +#: commands/functioncmds.c:1597 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "el cast será ignorado porque el tipo de datos de origen es un dominio" + +#: commands/functioncmds.c:1602 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "el cast será ignorado porque el tipo de datos de destino es un dominio" + +#: commands/functioncmds.c:1627 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "la función de conversión lleva de uno a tres argumentos" + +#: commands/functioncmds.c:1631 +#, c-format +msgid "argument of cast function must match or be binary-coercible from source data type" +msgstr "el argumento de la función de conversión debe coincidir o ser binario-convertible con el tipo de origen" + +#: commands/functioncmds.c:1635 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "el segundo argumento de la función de conversión debe ser de tipo %s" + +#: commands/functioncmds.c:1640 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "el tercer argumento de la función de conversión debe ser de tipo %s" + +#: commands/functioncmds.c:1645 +#, c-format +msgid "return data type of cast function must match or be binary-coercible to target data type" +msgstr "el tipo de salida de la función de conversión debe coincidir o ser binario-convertible con el tipo de retorno" + +#: commands/functioncmds.c:1656 +#, c-format +msgid "cast function must not be volatile" +msgstr "la función de conversión no debe ser volatile" + +#: commands/functioncmds.c:1661 +#, c-format +msgid "cast function must be a normal function" +msgstr "la función de conversión debe ser una función normal" + +#: commands/functioncmds.c:1665 +#, c-format +msgid "cast function must not return a set" +msgstr "la función de conversión no debe retornar un conjunto" + +#: commands/functioncmds.c:1691 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "debe ser superusuario para crear una conversión sin especificar función" + +#: commands/functioncmds.c:1706 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "los tipos de datos de origen y destino no son físicamente compatibles" + +#: commands/functioncmds.c:1721 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "los tipos de datos compuestos no son binario-compatibles" + +#: commands/functioncmds.c:1727 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "los tipos de datos enum no son binario-compatibles" + +#: commands/functioncmds.c:1733 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "los tipos de datos de array no son binario-compatibles" + +#: commands/functioncmds.c:1750 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "los tipos de dato de dominio no deben ser marcados binario-compatibles" + +#: commands/functioncmds.c:1760 +#, c-format +msgid "source data type and target data type are the same" +msgstr "el tipo de origen y el tipo de retorno son el mismo" + +#: commands/functioncmds.c:1793 +#, c-format +msgid "transform function must not be volatile" +msgstr "la función de transformación no debe ser volatile" + +#: commands/functioncmds.c:1797 +#, c-format +msgid "transform function must be a normal function" +msgstr "la función de transformación debe ser una función normal" + +#: commands/functioncmds.c:1801 +#, c-format +msgid "transform function must not return a set" +msgstr "la función de transformación no debe retornar un conjunto" + +#: commands/functioncmds.c:1805 +#, c-format +msgid "transform function must take one argument" +msgstr "la función de transformación debe recibir un argumento" + +#: commands/functioncmds.c:1809 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "el primer argumento de la función de transformación debe ser de tipo %s" + +#: commands/functioncmds.c:1848 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "el tipo de dato %s es un pseudo-tipo" + +#: commands/functioncmds.c:1854 +#, c-format +msgid "data type %s is a domain" +msgstr "tipo de dato «%s» es un dominio" + +#: commands/functioncmds.c:1894 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "el tipo de dato de retorno de la función FROM SQL debe ser %s" + +#: commands/functioncmds.c:1920 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "el tipo de dato de retorno de la función TO SQL debe ser el tipo de dato de la transformación" + +#: commands/functioncmds.c:1949 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "la transformación para el tipo %s lenguaje «%s» ya existe" + +#: commands/functioncmds.c:2036 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "la transformación para el tipo %s lenguaje «%s» no existe" + +#: commands/functioncmds.c:2060 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "ya existe una función llamada %s en el esquema «%s»" + +#: commands/functioncmds.c:2115 +#, c-format +msgid "no inline code specified" +msgstr "no se ha especificado código" + +#: commands/functioncmds.c:2161 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "el lenguaje «%s» no soporta ejecución de código en línea" + +#: commands/functioncmds.c:2256 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "no se pueden pasar más de %d argumento a un procedimiento" +msgstr[1] "no se pueden pasar más de %d argumentos a un procedimiento" + +#: commands/indexcmds.c:618 +#, c-format +msgid "must specify at least one column" +msgstr "debe especificar al menos una columna" + +#: commands/indexcmds.c:622 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "no se puede usar más de %d columnas en un índice" + +#: commands/indexcmds.c:661 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "no se puede crear un índice en la tabla foránea «%s»" + +#: commands/indexcmds.c:692 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "no se puede crear un índice en la tabla particionada «%s» concurrentemente" + +#: commands/indexcmds.c:697 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "no se pueden create restricciones de exclusión en la tabla particionada «%s»" + +#: commands/indexcmds.c:707 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "no se pueden crear índices en tablas temporales de otras sesiones" + +#: commands/indexcmds.c:745 commands/tablecmds.c:748 commands/tablespace.c:1185 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "no se puede especificar el tablespace por omisión para las relaciones particionadas" + +#: commands/indexcmds.c:777 commands/tablecmds.c:783 commands/tablecmds.c:3299 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "sólo relaciones compartidas pueden ser puestas en el tablespace pg_global" + +#: commands/indexcmds.c:810 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "sustituyendo el método de acceso obsoleto «rtree» por «gist»" + +#: commands/indexcmds.c:831 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "el método de acceso «%s» no soporta índices únicos" + +#: commands/indexcmds.c:836 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "el método de acceso «%s» no soporta columnas incluidas" + +#: commands/indexcmds.c:841 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "el método de acceso «%s» no soporta índices multicolumna" + +#: commands/indexcmds.c:846 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "el método de acceso «%s» no soporta restricciones de exclusión" + +#: commands/indexcmds.c:969 +#, c-format +msgid "cannot match partition key to an index using access method \"%s\"" +msgstr "no se puede hacer coincidir la llave de partición a un índice usando el método de acceso «%s»" + +#: commands/indexcmds.c:979 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "restricción %s no soportada con definición de llave de particionamiento" + +#: commands/indexcmds.c:981 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "No se pueden usar restricciones %s cuando las llaves de particionamiento incluyen expresiones." + +#: commands/indexcmds.c:1020 +#, fuzzy, c-format +#| msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgid "unique constraint on partitioned table must include all partitioning columns" +msgstr "no se pueden eliminar restricciones sólo de la tabla particionada cuando existen particiones" + +#: commands/indexcmds.c:1021 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "La restricción %s en la tabla «%s» no incluye la columna «%s» que es parte de la llave de particionamiento." + +#: commands/indexcmds.c:1040 commands/indexcmds.c:1059 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "la creación de índices en columnas de sistema no está soportada" + +#: commands/indexcmds.c:1231 tcop/utility.c:1477 +#, c-format +msgid "cannot create unique index on partitioned table \"%s\"" +msgstr "no se puede crear un índice único en la tabla particionada «%s»" + +#: commands/indexcmds.c:1233 tcop/utility.c:1479 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "La tabla «%s» contiene particiones que son tablas foráneas." + +#: commands/indexcmds.c:1683 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "las funciones utilizadas en predicados de índice deben estar marcadas IMMUTABLE" + +#: commands/indexcmds.c:1749 parser/parse_utilcmd.c:2525 +#: parser/parse_utilcmd.c:2660 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "no existe la columna «%s» en la llave" + +#: commands/indexcmds.c:1773 parser/parse_utilcmd.c:1824 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "las expresiones no están soportadas en columnas incluidas" + +#: commands/indexcmds.c:1814 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "las funciones utilizadas en expresiones de índice deben estar marcadas IMMUTABLE" + +#: commands/indexcmds.c:1829 +#, c-format +msgid "including column does not support a collation" +msgstr "la columna incluida no permite un ordenamiento (collation)" + +#: commands/indexcmds.c:1833 +#, c-format +msgid "including column does not support an operator class" +msgstr "la columna incluida no permite una clase de operadores" + +#: commands/indexcmds.c:1837 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "la columna incluida no permite las opciones ASC/DESC" + +#: commands/indexcmds.c:1841 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "la columna incluida no permite las opciones NULLS FIRST/LAST" + +#: commands/indexcmds.c:1868 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "no se pudo determinar qué ordenamiento (collation) usar para la expresión de índice" + +#: commands/indexcmds.c:1876 commands/tablecmds.c:16802 commands/typecmds.c:810 +#: parser/parse_expr.c:2680 parser/parse_type.c:566 parser/parse_utilcmd.c:3813 +#: utils/adt/misc.c:599 +#, c-format +msgid "collations are not supported by type %s" +msgstr "los ordenamientos (collation) no están soportados por el tipo %s" + +#: commands/indexcmds.c:1914 +#, c-format +msgid "operator %s is not commutative" +msgstr "el operador %s no es conmutativo" + +#: commands/indexcmds.c:1916 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "Sólo operadores conmutativos pueden ser usados en restricciones de exclusión." + +#: commands/indexcmds.c:1942 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "el operador %s no es un miembro de la familia de operadores «%s»" + +#: commands/indexcmds.c:1945 +#, c-format +msgid "The exclusion operator must be related to the index operator class for the constraint." +msgstr "El operador de exclusión debe estar relacionado con la clase de operadores del índice para la restricción." + +#: commands/indexcmds.c:1980 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "el método de acceso «%s» no soporta las opciones ASC/DESC" + +#: commands/indexcmds.c:1985 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "el método de acceso «%s» no soporta las opciones NULLS FIRST/LAST" + +#: commands/indexcmds.c:2031 commands/tablecmds.c:16827 +#: commands/tablecmds.c:16833 commands/typecmds.c:2318 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "el tipo de dato %s no tiene una clase de operadores por omisión para el método de acceso «%s»" + +#: commands/indexcmds.c:2033 +#, c-format +msgid "You must specify an operator class for the index or define a default operator class for the data type." +msgstr "Debe especificar una clase de operadores para el índice, o definir una clase de operadores por omisión para el tipo de datos." + +#: commands/indexcmds.c:2062 commands/indexcmds.c:2070 +#: commands/opclasscmds.c:205 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "no existe la clase de operadores «%s» para el método de acceso «%s»" + +#: commands/indexcmds.c:2084 commands/typecmds.c:2306 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "la clase de operadores «%s» no acepta el tipo de datos %s" + +#: commands/indexcmds.c:2174 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "hay múltiples clases de operadores por omisión para el tipo de datos %s" + +#: commands/indexcmds.c:2502 +#, fuzzy, c-format +#| msgid "unrecognized EXPLAIN option \"%s\"" +msgid "unrecognized REINDEX option \"%s\"" +msgstr "opción de EXPLAIN «%s» no reconocida" + +#: commands/indexcmds.c:2726 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "la tabla «%s» no tiene índices que puedan ser reindexados concurrentemente" + +#: commands/indexcmds.c:2740 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "la tabla «%s» no tiene índices para reindexar" + +#: commands/indexcmds.c:2780 commands/indexcmds.c:3287 +#: commands/indexcmds.c:3415 +#, c-format +msgid "cannot reindex system catalogs concurrently" +msgstr "no se pueden reindexar catálogos de sistema concurrentemente" + +#: commands/indexcmds.c:2803 +#, c-format +msgid "can only reindex the currently open database" +msgstr "sólo se puede reindexar la base de datos actualmente abierta" + +#: commands/indexcmds.c:2891 +#, c-format +msgid "cannot reindex system catalogs concurrently, skipping all" +msgstr "no se puede reindexar un catálogo de sistema concurrentemente, omitiéndolos todos" + +#: commands/indexcmds.c:2924 +#, fuzzy, c-format +#| msgid "cannot move system relation \"%s\"" +msgid "cannot move system relations, skipping all" +msgstr "no se puede mover la relación de sistema «%s»" + +#: commands/indexcmds.c:2971 +#, fuzzy, c-format +#| msgid "Unlogged partitioned table \"%s.%s\"" +msgid "while reindexing partitioned table \"%s.%s\"" +msgstr "Tabla unlogged particionada «%s.%s»" + +#: commands/indexcmds.c:2974 +#, fuzzy, c-format +#| msgid "Unlogged partitioned index \"%s.%s\"" +msgid "while reindexing partitioned index \"%s.%s\"" +msgstr "Índice particionado unlogged «%s.%s»" + +#: commands/indexcmds.c:3167 commands/indexcmds.c:4003 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "la tabla «%s.%s» fue reindexada" + +#: commands/indexcmds.c:3319 commands/indexcmds.c:3371 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "no se puede reindexar el índice no válido «%s.%s» concurrentemente, omitiendo" + +#: commands/indexcmds.c:3325 +#, c-format +msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "no se puede reindexar el índice de restricción de exclusión «%s.%s» concurrentemente, omitiendo" + +#: commands/indexcmds.c:3480 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "no se puede reindexar este tipo de relación concurrentemente" + +#: commands/indexcmds.c:3501 +#, fuzzy, c-format +#| msgid "cannot move system relation \"%s\"" +msgid "cannot move non-shared relation to tablespace \"%s\"" +msgstr "no se puede mover la relación de sistema «%s»" + +#: commands/indexcmds.c:3984 commands/indexcmds.c:3996 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr "el índice «%s.%s» fue reindexado" + +#: commands/lockcmds.c:92 commands/tablecmds.c:6019 commands/trigger.c:289 +#: rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:938 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "«%s» no es una tabla o vista" + +#: commands/matview.c:182 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "no se puede usar CONCURRENTLY cuando la vista materializada no contiene datos" + +#: commands/matview.c:188 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "las opciones CONCURRENTLY y WITH NO DATA no pueden usarse juntas" + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "no se puede refrescar la vista materializada «%s» concurrentemente" + +#: commands/matview.c:247 +#, c-format +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "Cree un índice único sin cláusula WHERE en una o más columnas de la vista materializada." + +#: commands/matview.c:652 +#, c-format +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "nuevos datos para la vista materializada «%s» contiene filas duplicadas sin columnas nulas" + +#: commands/matview.c:654 +#, c-format +msgid "Row: %s" +msgstr "Fila: %s" + +#: commands/opclasscmds.c:124 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "no existe la familia de operadores «%s» para el método de acceso «%s»" + +#: commands/opclasscmds.c:266 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "ya exista una familia de operadores «%s» para el método de acceso «%s»" + +#: commands/opclasscmds.c:411 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "debe ser superusuario para crear una clase de operadores" + +#: commands/opclasscmds.c:484 commands/opclasscmds.c:901 +#: commands/opclasscmds.c:1047 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "el número de operador %d es incorrecto, debe estar entre 1 y %d" + +#: commands/opclasscmds.c:529 commands/opclasscmds.c:951 +#: commands/opclasscmds.c:1063 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "número de función %d no válido, debe estar entre 1 y %d" + +#: commands/opclasscmds.c:558 +#, c-format +msgid "storage type specified more than once" +msgstr "el tipo de almacenamiento fue especificado más de una vez" + +#: commands/opclasscmds.c:585 +#, c-format +msgid "storage type cannot be different from data type for access method \"%s\"" +msgstr "el tipo de almacenamiento no puede ser diferente del tipo de dato para el método de acceso «%s»" + +#: commands/opclasscmds.c:601 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "ya exista una clase de operadores «%s» para el método de acceso «%s»" + +#: commands/opclasscmds.c:629 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "no se pudo hacer que «%s» sea la clase de operadores por omisión para el tipo %s" + +#: commands/opclasscmds.c:632 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "Actualmente, «%s» es la clase de operadores por omisión." + +#: commands/opclasscmds.c:792 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "debe ser superusuario para crear una familia de operadores" + +#: commands/opclasscmds.c:852 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "debe ser superusuario para alterar una familia de operadores" + +#: commands/opclasscmds.c:910 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "los tipos de los argumentos de operador deben ser especificados en ALTER OPERATOR FAMILY" + +#: commands/opclasscmds.c:985 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "STORAGE no puede ser especificado en ALTER OPERATOR FAMILY" + +#: commands/opclasscmds.c:1119 +#, c-format +msgid "one or two argument types must be specified" +msgstr "uno o dos tipos de argumento debe/n ser especificado" + +#: commands/opclasscmds.c:1145 +#, c-format +msgid "index operators must be binary" +msgstr "los operadores de índice deben ser binarios" + +#: commands/opclasscmds.c:1164 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "el método de acceso «%s» no soporta operadores de ordenamiento" + +#: commands/opclasscmds.c:1175 +#, c-format +msgid "index search operators must return boolean" +msgstr "los operadores de búsqueda en índices deben retornar boolean" + +#: commands/opclasscmds.c:1215 +#, fuzzy, c-format +#| msgid "associated data types for opclass options parsing functions must match opclass input type" +msgid "associated data types for operator class options parsing functions must match opclass input type" +msgstr "los tipos de dato asociados a las funciones de interpretación de opciones de la clase de operadores deben coincidir exactamente con el tipo de entrada de la clase de operadores" + +#: commands/opclasscmds.c:1222 +#, fuzzy, c-format +#| msgid "left and right associated data types for opclass options parsing functions must match" +msgid "left and right associated data types for operator class options parsing functions must match" +msgstr "los tipos de dato izquierdo y derecho asociados a las funciones de interpretación de opciones de la clase de operadores deben coincidir" + +#: commands/opclasscmds.c:1230 +#, fuzzy, c-format +#| msgid "invalid opclass options parsing function" +msgid "invalid operator class options parsing function" +msgstr "función de interpretación de opciones de la clase de operadores no válida" + +#: commands/opclasscmds.c:1231 +#, fuzzy, c-format +#| msgid "Valid signature of opclass options parsing function is '%s'." +msgid "Valid signature of operator class options parsing function is %s." +msgstr "La signatura válida para la función de interpretación de opciones de una clase de operadores es '%s'." + +#: commands/opclasscmds.c:1250 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "las funciones de comparación btree deben tener dos argumentos" + +#: commands/opclasscmds.c:1254 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "las funciones de comparación btree deben retornar entero" + +#: commands/opclasscmds.c:1271 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "las funciones btree de soporte de ordenamiento deben aceptar tipo «internal»" + +#: commands/opclasscmds.c:1275 +#, c-format +msgid "btree sort support functions must return void" +msgstr "las funciones btree de soporte de ordenamiento deben retornar void" + +#: commands/opclasscmds.c:1286 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "las funciones btree in_range deben tener cinco argumentos" + +#: commands/opclasscmds.c:1290 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "las funciones btree in_range deben retornar booleano" + +#: commands/opclasscmds.c:1306 +#, c-format +msgid "btree equal image functions must have one argument" +msgstr "las funciones btree de igualdad de imagen deben tener un argumento" + +#: commands/opclasscmds.c:1310 +#, c-format +msgid "btree equal image functions must return boolean" +msgstr "las funciones btree de igualdad de imagen deben retornar booleano" + +#: commands/opclasscmds.c:1323 +#, c-format +msgid "btree equal image functions must not be cross-type" +msgstr "las funciones btree de igualdad de imagen no deben ser entre distintos tipos" + +#: commands/opclasscmds.c:1333 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "la función de hash 1 debe tener un argumento" + +#: commands/opclasscmds.c:1337 +#, c-format +msgid "hash function 1 must return integer" +msgstr "la función de hash 1 debe retornar integer" + +#: commands/opclasscmds.c:1344 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "la función de hash 2 debe tener dos argumentos" + +#: commands/opclasscmds.c:1348 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "la función de hash 2 debe retornar bigint" + +#: commands/opclasscmds.c:1373 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "los tipos de datos asociados deben ser especificados para una función de soporte de índice" + +#: commands/opclasscmds.c:1398 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "la función número %d para (%s,%s) aparece más de una vez" + +#: commands/opclasscmds.c:1405 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "el número de operador %d para (%s,%s) aparece más de una vez" + +#: commands/opclasscmds.c:1451 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "ya existe un operador %d(%s,%s) en la familia de operadores «%s»" + +#: commands/opclasscmds.c:1557 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "ya existe una función %d(%s,%s) en la familia de operador «%s»" + +#: commands/opclasscmds.c:1638 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "no existe el operador %d(%s,%s) en la familia de operadores «%s»" + +#: commands/opclasscmds.c:1678 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "no existe la función %d(%s,%s) en la familia de operadores «%s»" + +#: commands/opclasscmds.c:1709 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "ya existe una clase de operadores «%s» para el método de acceso «%s» en el esquema «%s»" + +#: commands/opclasscmds.c:1732 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "ya existe una familia de operadores «%s» para el método de acceso «%s» en el esquema «%s»" + +#: commands/operatorcmds.c:111 commands/operatorcmds.c:119 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "no se permite un tipo SETOF en los argumentos de un operador" + +#: commands/operatorcmds.c:152 commands/operatorcmds.c:479 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "el atributo de operador «%s» no es reconocido" + +#: commands/operatorcmds.c:163 +#, c-format +msgid "operator function must be specified" +msgstr "la función del operador debe especificarse" + +#: commands/operatorcmds.c:181 +#, fuzzy, c-format +#| msgid "one or two argument types must be specified" +msgid "operator argument types must be specified" +msgstr "uno o dos tipos de argumento debe/n ser especificado" + +#: commands/operatorcmds.c:185 +#, fuzzy, c-format +#| msgid "one or two argument types must be specified" +msgid "operator right argument type must be specified" +msgstr "uno o dos tipos de argumento debe/n ser especificado" + +#: commands/operatorcmds.c:186 +#, fuzzy, c-format +#| msgid "log format \"%s\" is not supported" +msgid "Postfix operators are not supported." +msgstr "el formato de log «%s» no está soportado" + +#: commands/operatorcmds.c:290 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "la función de estimación de restricción %s debe retornar tipo %s" + +#: commands/operatorcmds.c:333 +#, c-format +msgid "join estimator function %s has multiple matches" +msgstr "la función de estimación de join %s tiene múltiples coincidencias" + +#: commands/operatorcmds.c:348 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "la función de estimación de join %s debe retornar tipo %s" + +#: commands/operatorcmds.c:473 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "el atributo de operador «%s» no puede ser cambiado" + +#: commands/policy.c:88 commands/policy.c:381 commands/policy.c:471 +#: commands/statscmds.c:150 commands/tablecmds.c:1561 commands/tablecmds.c:2150 +#: commands/tablecmds.c:3409 commands/tablecmds.c:5998 +#: commands/tablecmds.c:8860 commands/tablecmds.c:16392 +#: commands/tablecmds.c:16427 commands/trigger.c:295 commands/trigger.c:1271 +#: commands/trigger.c:1380 rewrite/rewriteDefine.c:277 +#: rewrite/rewriteDefine.c:943 rewrite/rewriteRemove.c:80 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "permiso denegado: «%s» es un catálogo de sistema" + +#: commands/policy.c:171 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "ignorando los roles especificados que no son PUBLIC" + +#: commands/policy.c:172 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "Todos los roles son miembros del rol PUBLIC." + +#: commands/policy.c:495 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "el rol «%s» no pudo ser eliminado de la política «%s» en «%s»" + +#: commands/policy.c:704 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "WITH CHECK no puede ser aplicado a SELECT o DELETE" + +#: commands/policy.c:713 commands/policy.c:1018 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "sólo se permite una expresión WITH CHECK para INSERT" + +#: commands/policy.c:788 commands/policy.c:1241 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "la política «%s» para la tabla «%s» ya existe" + +#: commands/policy.c:990 commands/policy.c:1269 commands/policy.c:1340 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "no existe la política «%s» para la tabla «%s»" + +#: commands/policy.c:1008 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "sólo se permite una expresión USING para SELECT, DELETE" + +#: commands/portalcmds.c:60 commands/portalcmds.c:187 commands/portalcmds.c:238 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "el nombre de cursor no es válido: no debe ser vacío" + +#: commands/portalcmds.c:72 +#, fuzzy, c-format +#| msgid "cannot create temporary table within security-restricted operation" +msgid "cannot create a cursor WITH HOLD within security-restricted operation" +msgstr "no se puede crear una tabla temporal dentro una operación restringida por seguridad" + +#: commands/portalcmds.c:195 commands/portalcmds.c:248 +#: executor/execCurrent.c:70 utils/adt/xml.c:2594 utils/adt/xml.c:2764 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "no existe el cursor «%s»" + +#: commands/prepare.c:76 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "el nombre de sentencia no es válido: no debe ser vacío" + +#: commands/prepare.c:134 parser/parse_param.c:313 tcop/postgres.c:1473 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "no se pudo determinar el tipo del parámetro $%d" + +#: commands/prepare.c:152 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "sentencias de utilidad no pueden ser preparadas" + +#: commands/prepare.c:256 commands/prepare.c:261 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "la sentencia preparada no es un SELECT" + +#: commands/prepare.c:328 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "el número de parámetros es incorrecto en la sentencia preparada «%s»" + +#: commands/prepare.c:330 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "Se esperaban %d parámetros pero se obtuvieron %d." + +#: commands/prepare.c:363 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "el parámetro $%d de tipo %s no puede ser convertido al tipo esperado %s" + +#: commands/prepare.c:447 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "la sentencia preparada «%s» ya existe" + +#: commands/prepare.c:486 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "no existe la sentencia preparada «%s»" + +#: commands/proclang.c:68 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "debe ser superusuario para crear un lenguaje procedural personalizado" + +#: commands/publicationcmds.c:107 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "sintaxis de entrada no válida para la opción «publish»" + +#: commands/publicationcmds.c:125 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "valor de «publish» no reconocido: «%s»" + +#: commands/publicationcmds.c:140 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "parámetro de publicación no reconocido: «%s»" + +#: commands/publicationcmds.c:172 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "debe ser superusuario para crear publicaciones FOR ALL TABLES" + +#: commands/publicationcmds.c:248 +#, c-format +msgid "wal_level is insufficient to publish logical changes" +msgstr "wal_level es insuficiente para publicar cambios lógicos" + +#: commands/publicationcmds.c:249 +#, c-format +msgid "Set wal_level to logical before creating subscriptions." +msgstr "Cambie wal_level a logical antes de crear suscripciones." + +#: commands/publicationcmds.c:369 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "la publicación \"%s\" se define como FOR ALL TABLES" + +#: commands/publicationcmds.c:371 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "Las tablas no se pueden agregar ni eliminar de las publicaciones FOR ALL TABLES." + +#: commands/publicationcmds.c:660 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "relación «%s» no es parte de la publicación" + +#: commands/publicationcmds.c:703 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "se ha denegado el permiso para cambiar el dueño de la publicación «%s»" + +#: commands/publicationcmds.c:705 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "El dueño de una publicación FOR ALL TABLES debe ser un superusuario." + +#: commands/schemacmds.c:105 commands/schemacmds.c:258 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "el nombre de schema «%s» es inaceptable" + +#: commands/schemacmds.c:106 commands/schemacmds.c:259 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "El prefijo «pg_» está reservado para esquemas del sistema." + +#: commands/schemacmds.c:120 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "el esquema «%s» ya existe, omitiendo" + +#: commands/seclabel.c:129 +#, c-format +msgid "no security label providers have been loaded" +msgstr "no se ha cargado ningún proveedor de etiquetas de seguridad" + +#: commands/seclabel.c:133 +#, c-format +msgid "must specify provider when multiple security label providers have been loaded" +msgstr "debe especificar un proveedor de etiquetas de seguridad cuando más de uno ha sido cargados" + +#: commands/seclabel.c:151 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "el proveedor de etiquetas de seguridad «%s» no está cargado" + +#: commands/seclabel.c:158 +#, fuzzy, c-format +#| msgid "tablespaces are not supported on this platform" +msgid "security labels are not supported for this type of object" +msgstr "tablespaces no están soportados en esta plataforma" + +#: commands/sequence.c:140 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "las secuencias «unlogged» no están soportadas" + +#: commands/sequence.c:709 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "nextval: se alcanzó el valor máximo de la secuencia «%s» (%s)" + +#: commands/sequence.c:732 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "nextval: se alcanzó el valor mínimo de la secuencia «%s» (%s)" + +#: commands/sequence.c:850 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "currval de la secuencia «%s» no está definido en esta sesión" + +#: commands/sequence.c:869 commands/sequence.c:875 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "lastval no está definido en esta sesión" + +#: commands/sequence.c:963 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "setval: el valor %s está fuera del rango de la secuencia «%s» (%s..%s)" + +#: commands/sequence.c:1359 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "opción de secuencia no válida SEQUENCE NAME" + +#: commands/sequence.c:1385 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "el tipo de columna de identidad debe ser smallint, integer o bigint" + +#: commands/sequence.c:1386 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "el tipo de secuencia debe ser smallint, integer o bigint" + +#: commands/sequence.c:1420 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "INCREMENT no debe ser cero" + +#: commands/sequence.c:1473 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) está fuera de rango para el tipo de dato de la secuencia %s" + +#: commands/sequence.c:1510 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s) está fuera de rango para el tipo de dato de la secuencia %s" + +#: commands/sequence.c:1524 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "MINVALUE (%s) debe ser menor que MAXVALUE (%s)" + +#: commands/sequence.c:1551 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "el valor START (%s) no puede ser menor que MINVALUE (%s)" + +#: commands/sequence.c:1563 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "el valor START (%s) no puede ser mayor que MAXVALUE (%s)" + +#: commands/sequence.c:1593 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "el valor RESTART (%s) no puede ser menor que MINVALUE (%s)" + +#: commands/sequence.c:1605 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "el valor RESTART (%s) no puede ser mayor que MAXVALUE (%s)" + +#: commands/sequence.c:1620 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "CACHE (%s) debe ser mayor que cero" + +#: commands/sequence.c:1657 +#, c-format +msgid "invalid OWNED BY option" +msgstr "opción OWNED BY no válida" + +#: commands/sequence.c:1658 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "Especifique OWNED BY tabla.columna o OWNED BY NONE." + +#: commands/sequence.c:1683 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr "la relación referida «%s» no es una tabla o tabla foránea" + +#: commands/sequence.c:1690 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "la secuencia debe tener el mismo dueño que la tabla a la que está enlazada" + +#: commands/sequence.c:1694 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "la secuencia debe estar en el mismo esquema que la tabla a la que está enlazada" + +#: commands/sequence.c:1716 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "no se puede cambiar el dueño de la secuencia de identidad" + +#: commands/sequence.c:1717 commands/tablecmds.c:13188 +#: commands/tablecmds.c:15817 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "La secuencia «%s» está enlazada a la tabla «%s»." + +#: commands/statscmds.c:111 commands/statscmds.c:120 tcop/utility.c:1827 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "sólo se permite una relación en CREATE STATISTICS" + +#: commands/statscmds.c:138 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "la relación «%s» no es una tabla, tabla foránea o vista materializada" + +#: commands/statscmds.c:188 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "el objeto de estadísticas «%s» ya existe, omitiendo" + +#: commands/statscmds.c:196 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "el objeto de estadísticas «%s» ya existe" + +#: commands/statscmds.c:207 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "no se puede tener más de %d columnas en estadísticas" + +#: commands/statscmds.c:246 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "la creación de estadísticas en columnas de sistema no está soportada" + +#: commands/statscmds.c:253 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "la columna «%s» no puede ser usado en estadísticas porque su tipo %s no tiene una clase de operadores por omisión para btree" + +#: commands/statscmds.c:282 +#, fuzzy, c-format +#| msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgid "expression cannot be used in multivariate statistics because its type %s has no default btree operator class" +msgstr "la columna «%s» no puede ser usado en estadísticas porque su tipo %s no tiene una clase de operadores por omisión para btree" + +#: commands/statscmds.c:303 +#, c-format +msgid "when building statistics on a single expression, statistics kinds may not be specified" +msgstr "" + +#: commands/statscmds.c:332 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "tipo de estadísticas «%s» no reconocido" + +#: commands/statscmds.c:361 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "las estadísticas extendidas requieren al menos 2 columnas" + +#: commands/statscmds.c:379 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "nombre de columna duplicado en definición de estadísticas" + +#: commands/statscmds.c:414 +#, fuzzy, c-format +#| msgid "duplicate column name in statistics definition" +msgid "duplicate expression in statistics definition" +msgstr "nombre de columna duplicado en definición de estadísticas" + +#: commands/statscmds.c:595 commands/tablecmds.c:7830 +#, c-format +msgid "statistics target %d is too low" +msgstr "el valor de estadísticas %d es demasiado bajo" + +#: commands/statscmds.c:603 commands/tablecmds.c:7838 +#, c-format +msgid "lowering statistics target to %d" +msgstr "bajando el valor de estadísticas a %d" + +#: commands/statscmds.c:626 +#, c-format +msgid "statistics object \"%s.%s\" does not exist, skipping" +msgstr "no existe el objeto de estadísticas «%s.%s», omitiendo" + +#: commands/subscriptioncmds.c:221 +#, c-format +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "parámetro de suscripción no reconocido: «%s»" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:235 commands/subscriptioncmds.c:241 +#: commands/subscriptioncmds.c:247 commands/subscriptioncmds.c:266 +#: commands/subscriptioncmds.c:272 +#, c-format +msgid "%s and %s are mutually exclusive options" +msgstr "%s y %s son opciones mutuamente excluyentes" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:279 commands/subscriptioncmds.c:285 +#, c-format +msgid "subscription with %s must also set %s" +msgstr "suscripción con %s también debe activar %s" + +#: commands/subscriptioncmds.c:378 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "debe ser superusuario para crear suscripciones" + +#: commands/subscriptioncmds.c:471 commands/subscriptioncmds.c:568 +#: replication/logical/tablesync.c:970 replication/logical/worker.c:3154 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "no se pudo connectar con el editor (publisher): %s" + +#: commands/subscriptioncmds.c:513 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "se creó el slot de replicación «%s» en el editor (publisher)" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:526 +#, c-format +msgid "tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "las tablas no se suscribieron, tendrá que ejecutar %s para suscribir las tablas" + +#: commands/subscriptioncmds.c:824 +#, c-format +msgid "cannot set %s for enabled subscription" +msgstr "no se puede establecer %s para la suscripción activada" + +#: commands/subscriptioncmds.c:880 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "no se puede habilitar la suscripción que no tiene un nombre de slot" + +#: commands/subscriptioncmds.c:932 commands/subscriptioncmds.c:980 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION con actualización no está permitido para las suscripciones desactivadas" + +#: commands/subscriptioncmds.c:933 commands/subscriptioncmds.c:981 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:1001 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESH no está permitido para las suscripciones desactivadas" + +#: commands/subscriptioncmds.c:1089 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "no existe la suscripción «%s», omitiendo" + +#: commands/subscriptioncmds.c:1341 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "eliminando el slot de replicación «%s» en editor (publisher)" + +#: commands/subscriptioncmds.c:1350 commands/subscriptioncmds.c:1357 +#, fuzzy, c-format +#| msgid "could not drop the replication slot \"%s\" on publisher" +msgid "could not drop replication slot \"%s\" on publisher: %s" +msgstr "no se pudo eliminar el slot de replicación «%s» en editor (publisher)" + +#: commands/subscriptioncmds.c:1391 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "se ha denegado el permiso para cambiar el dueño de la suscripción «%s»" + +#: commands/subscriptioncmds.c:1393 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "El dueño de una suscripción debe ser un superusuario." + +#: commands/subscriptioncmds.c:1508 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "no se pudo recibir la lista de tablas replicadas desde el editor (publisher): %s" + +#: commands/subscriptioncmds.c:1572 +#, fuzzy, c-format +#| msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgid "could not connect to publisher when attempting to drop replication slot \"%s\": %s" +msgstr "no se pudo conectar con el editor (publisher) al intentar eliminar el slot \"%s\"" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:1575 +#, c-format +msgid "Use %s to disassociate the subscription from the slot." +msgstr "Use %s para disociar la suscripción del slot." + +#: commands/subscriptioncmds.c:1605 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "nombre de publicación «%s» usado más de una vez" + +#: commands/subscriptioncmds.c:1649 +#, fuzzy, c-format +#| msgid "publication \"%s\" already exists" +msgid "publication \"%s\" is already in subscription \"%s\"" +msgstr "la publicación «%s» ya existe" + +#: commands/subscriptioncmds.c:1663 +#, fuzzy, c-format +#| msgid "publication of %s in publication %s" +msgid "publication \"%s\" is not in subscription \"%s\"" +msgstr "publicación de %s en la publicación %s" + +#: commands/subscriptioncmds.c:1674 +#, fuzzy, c-format +#| msgid "relation \"%s\" is not part of the publication" +msgid "subscription must contain at least one publication" +msgstr "relación «%s» no es parte de la publicación" + +#: commands/tablecmds.c:241 commands/tablecmds.c:283 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "no existe la tabla «%s»" + +#: commands/tablecmds.c:242 commands/tablecmds.c:284 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "la tabla «%s» no existe, omitiendo" + +#: commands/tablecmds.c:244 commands/tablecmds.c:286 +msgid "Use DROP TABLE to remove a table." +msgstr "Use DROP TABLE para eliminar una tabla." + +#: commands/tablecmds.c:247 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "no existe la secuencia «%s»" + +#: commands/tablecmds.c:248 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "la secuencia «%s» no existe, omitiendo" + +#: commands/tablecmds.c:250 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "Use DROP SEQUENCE para eliminar una secuencia." + +#: commands/tablecmds.c:253 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "no existe la vista «%s»" + +#: commands/tablecmds.c:254 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "la vista «%s» no existe, omitiendo" + +#: commands/tablecmds.c:256 +msgid "Use DROP VIEW to remove a view." +msgstr "Use DROP VIEW para eliminar una vista." + +#: commands/tablecmds.c:259 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr "no existe la vista materializada «%s»" + +#: commands/tablecmds.c:260 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr "la vista materializada «%s» no existe, omitiendo" + +#: commands/tablecmds.c:262 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "Use DROP MATERIALIZED VIEW para eliminar una vista materializada." + +#: commands/tablecmds.c:265 commands/tablecmds.c:289 commands/tablecmds.c:18238 +#: parser/parse_utilcmd.c:2257 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "no existe el índice «%s»" + +#: commands/tablecmds.c:266 commands/tablecmds.c:290 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "el índice «%s» no existe, omitiendo" + +#: commands/tablecmds.c:268 commands/tablecmds.c:292 +msgid "Use DROP INDEX to remove an index." +msgstr "Use DROP INDEX para eliminar un índice." + +#: commands/tablecmds.c:273 +#, c-format +msgid "\"%s\" is not a type" +msgstr "«%s» no es un tipo" + +#: commands/tablecmds.c:274 +msgid "Use DROP TYPE to remove a type." +msgstr "Use DROP TYPE para eliminar un tipo." + +#: commands/tablecmds.c:277 commands/tablecmds.c:13027 +#: commands/tablecmds.c:15520 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "no existe la tabla foránea «%s»" + +#: commands/tablecmds.c:278 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "la tabla foránea «%s» no existe, omitiendo" + +#: commands/tablecmds.c:280 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "Use DROP FOREIGN TABLE para eliminar una tabla foránea." + +#: commands/tablecmds.c:664 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMIT sólo puede ser usado en tablas temporales" + +#: commands/tablecmds.c:695 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "no se puede crear una tabla temporal dentro una operación restringida por seguridad" + +#: commands/tablecmds.c:731 commands/tablecmds.c:14311 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "se heredaría de la relación «%s» más de una vez" + +#: commands/tablecmds.c:916 +#, c-format +msgid "specifying a table access method is not supported on a partitioned table" +msgstr "especificar un método de acceso de tablas no está soportado en tablas particionadas." + +#: commands/tablecmds.c:1012 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "«%s» no está particionada" + +#: commands/tablecmds.c:1107 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "no se puede particionar usando más de %d columnas" + +#: commands/tablecmds.c:1163 +#, c-format +msgid "cannot create foreign partition of partitioned table \"%s\"" +msgstr "no se puede crear una partición foránea en la tabla particionada «%s»" + +#: commands/tablecmds.c:1165 +#, c-format +msgid "Table \"%s\" contains indexes that are unique." +msgstr "La tabla «%s» contiene índices que son únicos." + +#: commands/tablecmds.c:1328 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLY no soporta eliminar múltiples objetos" + +#: commands/tablecmds.c:1332 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLY no soporta CASCADE" + +#: commands/tablecmds.c:1433 +#, c-format +msgid "cannot drop partitioned index \"%s\" concurrently" +msgstr "no se puede eliminar el índice particionado «%s» concurrentemente" + +#: commands/tablecmds.c:1705 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "no se puede truncar ONLY una tabla particionada" + +#: commands/tablecmds.c:1706 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "No especifique la opción ONLY, o ejecute TRUNCATE ONLY en las particiones directamente." + +#: commands/tablecmds.c:1779 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "truncando además la tabla «%s»" + +#: commands/tablecmds.c:2138 +#, fuzzy, c-format +#| msgid "cannot update foreign table \"%s\"" +msgid "cannot truncate foreign table \"%s\"" +msgstr "no se puede actualizar la tabla foránea «%s»" + +#: commands/tablecmds.c:2187 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "no se pueden truncar tablas temporales de otras sesiones" + +#: commands/tablecmds.c:2449 commands/tablecmds.c:14208 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "no se puede heredar de la tabla particionada «%s»" + +#: commands/tablecmds.c:2454 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "no se puede heredar de la partición «%s»" + +#: commands/tablecmds.c:2462 parser/parse_utilcmd.c:2487 +#: parser/parse_utilcmd.c:2629 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "la relación heredada «%s» no es una tabla o tabla foránea" + +#: commands/tablecmds.c:2474 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "no se puede crear una relación temporal como partición de la relación permanente «%s»" + +#: commands/tablecmds.c:2483 commands/tablecmds.c:14187 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "no se puede heredar de la tabla temporal «%s»" + +#: commands/tablecmds.c:2493 commands/tablecmds.c:14195 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "no se puede heredar de una tabla temporal de otra sesión" + +#: commands/tablecmds.c:2547 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "mezclando múltiples definiciones heredadas de la columna «%s»" + +#: commands/tablecmds.c:2555 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "columna heredada «%s» tiene conflicto de tipos" + +#: commands/tablecmds.c:2557 commands/tablecmds.c:2580 +#: commands/tablecmds.c:2597 commands/tablecmds.c:2853 +#: commands/tablecmds.c:2883 commands/tablecmds.c:2897 +#: parser/parse_coerce.c:2090 parser/parse_coerce.c:2110 +#: parser/parse_coerce.c:2130 parser/parse_coerce.c:2150 +#: parser/parse_coerce.c:2205 parser/parse_coerce.c:2238 +#: parser/parse_coerce.c:2316 parser/parse_coerce.c:2348 +#: parser/parse_coerce.c:2382 parser/parse_coerce.c:2402 +#: parser/parse_param.c:227 +#, c-format +msgid "%s versus %s" +msgstr "%s versus %s" + +#: commands/tablecmds.c:2566 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "columna heredada «%s» tiene conflicto de ordenamiento (collation)" + +#: commands/tablecmds.c:2568 commands/tablecmds.c:2865 +#: commands/tablecmds.c:6498 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "«%s» versus «%s»" + +#: commands/tablecmds.c:2578 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "columna heredada «%s» tiene conflicto de parámetros de almacenamiento" + +#: commands/tablecmds.c:2595 commands/tablecmds.c:2895 +#, fuzzy, c-format +#| msgid "column \"%s\" has a collation conflict" +msgid "column \"%s\" has a compression method conflict" +msgstr "la columna «%s» tiene conflicto de ordenamientos (collation)" + +#: commands/tablecmds.c:2610 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "columna heredada «%s» tiene conflicto de generación" + +#: commands/tablecmds.c:2704 commands/tablecmds.c:2759 +#: commands/tablecmds.c:11772 parser/parse_utilcmd.c:1301 +#: parser/parse_utilcmd.c:1344 parser/parse_utilcmd.c:1752 +#: parser/parse_utilcmd.c:1860 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "no se puede convertir una referencia a la fila completa (whole-row)" + +#: commands/tablecmds.c:2705 parser/parse_utilcmd.c:1302 +#, c-format +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "La expresión de generación para la columna «%s» contiene una referencia a la fila completa (whole-row) de la tabla «%s»." + +#: commands/tablecmds.c:2760 parser/parse_utilcmd.c:1345 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "La restricción «%s» contiene una referencia a la fila completa (whole-row) de la tabla «%s»." + +#: commands/tablecmds.c:2839 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "mezclando la columna «%s» con la definición heredada" + +#: commands/tablecmds.c:2843 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "moviendo y mezclando la columna «%s» con la definición heredada" + +#: commands/tablecmds.c:2844 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "La columna especificada por el usuario fue movida a la posición de la columna heredada." + +#: commands/tablecmds.c:2851 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "la columna «%s» tiene conflicto de tipos" + +#: commands/tablecmds.c:2863 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "la columna «%s» tiene conflicto de ordenamientos (collation)" + +#: commands/tablecmds.c:2881 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "la columna «%s» tiene conflicto de parámetros de almacenamiento" + +#: commands/tablecmds.c:2922 +#, c-format +msgid "child column \"%s\" specifies generation expression" +msgstr "la columna hija «%s» especifica una expresión de generación de columna" + +#: commands/tablecmds.c:2924 +#, c-format +msgid "Omit the generation expression in the definition of the child table column to inherit the generation expression from the parent table." +msgstr "Omita la expresión de generación en la definición de la columna en la tabla hija para heredar la expresión de generación de la tabla padre." + +#: commands/tablecmds.c:2928 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies default" +msgstr "la columna «%s» hereda de una columna generada pero especifica un valor por omisión" + +#: commands/tablecmds.c:2933 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies identity" +msgstr "la columna «%s» hereda de una columna generada pero especifica una identidad" + +#: commands/tablecmds.c:3042 +#, c-format +msgid "column \"%s\" inherits conflicting generation expressions" +msgstr "la columna «%s» hereda expresiones de generación en conflicto" + +#: commands/tablecmds.c:3047 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "la columna «%s» hereda valores por omisión no coincidentes" + +#: commands/tablecmds.c:3049 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "Para resolver el conflicto, indique explícitamente un valor por omisión." + +#: commands/tablecmds.c:3095 +#, c-format +msgid "check constraint name \"%s\" appears multiple times but with different expressions" +msgstr "la restricción «check» «%s» aparece más de una vez con diferentes expresiones" + +#: commands/tablecmds.c:3308 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "no se pueden mover tablas temporales de otras sesiones" + +#: commands/tablecmds.c:3378 +#, c-format +msgid "cannot rename column of typed table" +msgstr "no se puede cambiar el nombre a una columna de una tabla tipada" + +#: commands/tablecmds.c:3397 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" +msgstr "«%s» no es una tabla, vista, vista materializada, tipo compuesto, índice o tabla foránea" + +#: commands/tablecmds.c:3491 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "debe cambiar el nombre a la columna heredada «%s» en las tablas hijas también" + +#: commands/tablecmds.c:3523 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "no se puede cambiar el nombre a la columna de sistema «%s»" + +#: commands/tablecmds.c:3538 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "no se puede cambiar el nombre a la columna heredada «%s»" + +#: commands/tablecmds.c:3690 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "debe cambiar el nombre a la restricción heredada «%s» en las tablas hijas también" + +#: commands/tablecmds.c:3697 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "no se puede cambiar el nombre a la restricción heredada «%s»" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3930 +#, c-format +msgid "cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "no se puede hacer %s en «%s» porque está siendo usada por consultas activas en esta sesión" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3939 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "no se puede hacer %s en «%s» porque tiene eventos de disparador pendientes" + +#: commands/tablecmds.c:4403 +#, fuzzy, c-format +#| msgid "cannot convert partition \"%s\" to a view" +msgid "cannot alter partition \"%s\" with an incomplete detach" +msgstr "no se puede convertir la partición «%s» en vista" + +#: commands/tablecmds.c:4405 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." +msgstr "" + +#: commands/tablecmds.c:4597 commands/tablecmds.c:4612 +#, c-format +msgid "cannot change persistence setting twice" +msgstr "no se puede cambiar la opción de persistencia dos veces" + +#: commands/tablecmds.c:5355 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "no se puede reescribir la relación de sistema «%s»" + +#: commands/tablecmds.c:5361 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "no se puede reescribir la tabla «%s» que es usada como tabla de catálogo" + +#: commands/tablecmds.c:5371 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "no se puede reescribir tablas temporales de otras sesiones" + +#: commands/tablecmds.c:5832 +#, c-format +msgid "column \"%s\" of relation \"%s\" contains null values" +msgstr "la columna «%s» de la relación «%s» contiene valores null" + +#: commands/tablecmds.c:5849 +#, c-format +msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" +msgstr "la restricción check «%s» de la relación «%s» es violada por alguna fila" + +#: commands/tablecmds.c:5868 partitioning/partbounds.c:3282 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "la restricción de partición actualizada para la partición default «%s» sería violada por alguna fila" + +#: commands/tablecmds.c:5874 +#, c-format +msgid "partition constraint of relation \"%s\" is violated by some row" +msgstr "la restricción de partición de la relación «%s» es violada por alguna fila" + +#: commands/tablecmds.c:6022 commands/trigger.c:1265 commands/trigger.c:1371 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "«%s» no es una tabla, vista o tabla foránea" + +#: commands/tablecmds.c:6025 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "«%s» no es una tabla, vista, vista materializada, o índice" + +#: commands/tablecmds.c:6031 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "«%s» no es una tabla, vista materializada, o índice" + +#: commands/tablecmds.c:6034 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "«%s» no es una tabla, vista materializada o tabla foránea" + +#: commands/tablecmds.c:6037 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "«%s» no es una tabla o tabla foránea" + +#: commands/tablecmds.c:6040 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "«%s» no es una tabla, tipo compuesto, o tabla foránea" + +#: commands/tablecmds.c:6043 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "«%s» no es una tabla, vista materializada, índice o tabla foránea" + +#: commands/tablecmds.c:6053 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "«%s» es tipo equivocado" + +#: commands/tablecmds.c:6256 commands/tablecmds.c:6263 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "no se puede alterar el tipo «%s» porque la columna «%s.%s» lo usa" + +#: commands/tablecmds.c:6270 +#, c-format +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "no se puede alterar la tabla foránea «%s» porque la columna «%s.%s» usa su tipo de registro" + +#: commands/tablecmds.c:6277 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "no se puede alterar la tabla «%s» porque la columna «%s.%s» usa su tipo de registro" + +#: commands/tablecmds.c:6333 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "no se puede cambiar el tipo «%s» porque es el tipo de una tabla tipada" + +#: commands/tablecmds.c:6335 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "Use ALTER ... CASCADE para eliminar además las tablas tipadas." + +#: commands/tablecmds.c:6381 +#, c-format +msgid "type %s is not a composite type" +msgstr "el tipo %s no es un tipo compuesto" + +#: commands/tablecmds.c:6408 +#, c-format +msgid "cannot add column to typed table" +msgstr "no se puede agregar una columna a una tabla tipada" + +#: commands/tablecmds.c:6461 +#, c-format +msgid "cannot add column to a partition" +msgstr "no se puede agregar una columna a una partición" + +#: commands/tablecmds.c:6490 commands/tablecmds.c:14438 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "la tabla hija «%s» tiene un tipo diferente para la columna «%s»" + +#: commands/tablecmds.c:6496 commands/tablecmds.c:14445 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "la tabla hija «%s» tiene un ordenamiento (collation) diferente para la columna «%s»" + +#: commands/tablecmds.c:6510 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "mezclando la definición de la columna «%s» en la tabla hija «%s»" + +#: commands/tablecmds.c:6553 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "no se puede agregar una columna de identidad recursivamente a una tabla que tiene tablas hijas" + +#: commands/tablecmds.c:6796 +#, c-format +msgid "column must be added to child tables too" +msgstr "la columna debe ser agregada a las tablas hijas también" + +#: commands/tablecmds.c:6874 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "la columna «%s» de la relación «%s» ya existe, omitiendo" + +#: commands/tablecmds.c:6881 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "ya existe la columna «%s» en la relación «%s»" + +#: commands/tablecmds.c:6947 commands/tablecmds.c:11410 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "no se pueden eliminar restricciones sólo de la tabla particionada cuando existen particiones" + +#: commands/tablecmds.c:6948 commands/tablecmds.c:7252 +#: commands/tablecmds.c:8275 commands/tablecmds.c:11411 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "No especifique la opción ONLY." + +#: commands/tablecmds.c:6985 commands/tablecmds.c:7178 +#: commands/tablecmds.c:7320 commands/tablecmds.c:7434 +#: commands/tablecmds.c:7528 commands/tablecmds.c:7587 +#: commands/tablecmds.c:7705 commands/tablecmds.c:7871 +#: commands/tablecmds.c:7941 commands/tablecmds.c:8097 +#: commands/tablecmds.c:11565 commands/tablecmds.c:13050 +#: commands/tablecmds.c:15611 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "no se puede alterar columna de sistema «%s»" + +#: commands/tablecmds.c:6991 commands/tablecmds.c:7326 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "la columna «%s» en la relación «%s» es una columna de identidad" + +#: commands/tablecmds.c:7027 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "la columna «%s» está en la llave primaria" + +#: commands/tablecmds.c:7049 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "columna «%s» está marcada NOT NULL en la tabla padre" + +#: commands/tablecmds.c:7249 commands/tablecmds.c:8758 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "la restricción debe ser agregada a las tablas hijas también" + +#: commands/tablecmds.c:7250 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "La columna «%s» de la relación «%s» no está previamente marcada NOT NULL." + +#: commands/tablecmds.c:7328 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY en su lugar." + +#: commands/tablecmds.c:7333 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "la columna «%s» en la relación «%s» es una columna generada" + +#: commands/tablecmds.c:7336 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." +msgstr "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION en su lugar." + +#: commands/tablecmds.c:7445 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "la columna «%s» en la relación «%s» debe ser declarada NOT NULL antes de que una identidad pueda agregarse" + +#: commands/tablecmds.c:7451 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "la columna «%s» en la relación «%s» ya es una columna de identidad" + +#: commands/tablecmds.c:7457 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "la columna «%s» en la relación «%s» ya tiene un valor por omisión" + +#: commands/tablecmds.c:7534 commands/tablecmds.c:7595 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "la columna «%s» en la relación «%s» no es una columna identidad" + +#: commands/tablecmds.c:7600 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "la columna «%s» de la relación «%s» no es una columna identidad, omitiendo" + +#: commands/tablecmds.c:7653 +#, fuzzy, c-format +#| msgid "column must be added to child tables too" +msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" +msgstr "la columna debe ser agregada a las tablas hijas también" + +#: commands/tablecmds.c:7675 +#, c-format +msgid "cannot drop generation expression from inherited column" +msgstr "no se puede eliminar la expresión de generación de una columna heredada" + +#: commands/tablecmds.c:7713 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column" +msgstr "la columna «%s» en la relación «%s» no es una columna generada almacenada" + +#: commands/tablecmds.c:7718 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column, skipping" +msgstr "la columna «%s» de la relación «%s» no es una columna generada almacenada, omitiendo" + +#: commands/tablecmds.c:7818 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "no se puede referir a columnas que no son de índice por número" + +#: commands/tablecmds.c:7861 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "no existe la columna número %d en la relación «%s»" + +#: commands/tablecmds.c:7880 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "no se puede alterar estadísticas en la columna incluida «%s» del índice «%s»" + +#: commands/tablecmds.c:7885 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "no se puede alterar estadísticas en la columna no-de-expresión «%s» del índice «%s»" + +#: commands/tablecmds.c:7887 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Altere las estadísticas en la columna de la tabla en su lugar." + +#: commands/tablecmds.c:8077 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "tipo de almacenamiento no válido «%s»" + +#: commands/tablecmds.c:8109 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "el tipo de datos %s de la columna sólo puede tener almacenamiento PLAIN" + +#: commands/tablecmds.c:8154 +#, c-format +msgid "cannot drop column from typed table" +msgstr "no se pueden eliminar columnas de una tabla tipada" + +#: commands/tablecmds.c:8213 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "no existe la columna «%s» en la relación «%s», omitiendo" + +#: commands/tablecmds.c:8226 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "no se puede eliminar la columna de sistema «%s»" + +#: commands/tablecmds.c:8236 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "no se puede eliminar la columna heredada «%s»" + +#: commands/tablecmds.c:8249 +#, c-format +msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "no se puede eliminar la columna «%s» porque es parte de la llave de partición de la relación «%s»" + +#: commands/tablecmds.c:8274 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "no se pueden eliminar columnas sólo de una tabla particionada cuando existe particiones" + +#: commands/tablecmds.c:8478 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX no está soportado en tablas particionadas" + +#: commands/tablecmds.c:8503 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX renombrará el índice «%s» a «%s»" + +#: commands/tablecmds.c:8838 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "no se puede usar ONLY para una llave foránea en la tabla particionada «%s» haciendo referencia a la relación «%s»" + +#: commands/tablecmds.c:8844 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "no se puede agregar una llave foránea NOT VALID a la tabla particionada «%s» haciendo referencia a la relación «%s»" + +#: commands/tablecmds.c:8847 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Esta característica no está aún soportada en tablas particionadas." + +#: commands/tablecmds.c:8854 commands/tablecmds.c:9259 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "la relación referida «%s» no es una tabla" + +#: commands/tablecmds.c:8877 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "las restricciones en tablas permanentes sólo pueden hacer referencia a tablas permanentes" + +#: commands/tablecmds.c:8884 +#, c-format +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" +msgstr "las restricciones en tablas «unlogged» sólo pueden hacer referencia a tablas permanentes o «unlogged»" + +#: commands/tablecmds.c:8890 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "las restricciones en tablas temporales sólo pueden hacer referencia a tablas temporales" + +#: commands/tablecmds.c:8894 +#, c-format +msgid "constraints on temporary tables must involve temporary tables of this session" +msgstr "las restricciones en tablas temporales sólo pueden hacer referencia a tablas temporales de esta sesión" + +#: commands/tablecmds.c:8960 commands/tablecmds.c:8966 +#, c-format +msgid "invalid %s action for foreign key constraint containing generated column" +msgstr "acción %s no válida para restricción de llave foránea que contiene columnas generadas" + +#: commands/tablecmds.c:8982 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "el número de columnas referidas en la llave foránea no coincide con el número de columnas de referencia" + +#: commands/tablecmds.c:9089 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "la restricción de llave foránea «%s» no puede ser implementada" + +#: commands/tablecmds.c:9091 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "Las columnas llave «%s» y «%s» son de tipos incompatibles: %s y %s" + +#: commands/tablecmds.c:9454 commands/tablecmds.c:9847 +#: parser/parse_utilcmd.c:796 parser/parse_utilcmd.c:925 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "las restricciones de llave foránea no están soportadas en tablas foráneas" + +#: commands/tablecmds.c:10214 commands/tablecmds.c:10492 +#: commands/tablecmds.c:11367 commands/tablecmds.c:11442 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "no existe la restricción «%s» en la relación «%s»" + +#: commands/tablecmds.c:10221 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "la restricción «%s» de la relación «%s» no es una restriccion de llave foránea" + +#: commands/tablecmds.c:10259 +#, fuzzy, c-format +#| msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgid "cannot alter constraint \"%s\" on relation \"%s\"" +msgstr "no se puede eliminar la restricción «%s» heredada de la relación «%s»" + +#: commands/tablecmds.c:10262 +#, fuzzy, c-format +#| msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgid "Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\"." +msgstr "la restricción «%s» está en conflicto con la restricción heredada de la relación «%s»" + +#: commands/tablecmds.c:10264 +#, c-format +msgid "You may alter the constraint it derives from, instead." +msgstr "" + +#: commands/tablecmds.c:10500 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "la restricción «%s» de la relación «%s» no es una llave foránea o restricción «check»" + +#: commands/tablecmds.c:10578 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "la restricción debe ser validada en las tablas hijas también" + +#: commands/tablecmds.c:10662 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "no existe la columna «%s» referida en la llave foránea" + +#: commands/tablecmds.c:10667 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "no se puede tener más de %d columnas en una llave foránea" + +#: commands/tablecmds.c:10732 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "no se puede usar una llave primaria postergable para la tabla referenciada «%s»" + +#: commands/tablecmds.c:10749 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "no hay llave primaria para la tabla referida «%s»" + +#: commands/tablecmds.c:10814 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "la lista de columnas referidas en una llave foránea no debe contener duplicados" + +#: commands/tablecmds.c:10908 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "no se puede usar una restricción unique postergable para la tabla referenciada «%s»" + +#: commands/tablecmds.c:10913 +#, c-format +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "no hay restricción unique que coincida con las columnas dadas en la tabla referida «%s»" + +#: commands/tablecmds.c:11323 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "no se puede eliminar la restricción «%s» heredada de la relación «%s»" + +#: commands/tablecmds.c:11373 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "no existe la restricción «%s» en la relación «%s», omitiendo" + +#: commands/tablecmds.c:11549 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "no se puede cambiar el tipo de una columna de una tabla tipada" + +#: commands/tablecmds.c:11576 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "no se puede alterar la columna heredada «%s»" + +#: commands/tablecmds.c:11585 +#, c-format +msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "no se puede alterar la columna «%s» porque es parte de la llave de partición de la relación «%s»" + +#: commands/tablecmds.c:11635 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "el resultado de la cláusula USING para la columna «%s» no puede ser convertido automáticamente al tipo %s" + +#: commands/tablecmds.c:11638 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "Puede ser necesario agregar un cast explícito." + +#: commands/tablecmds.c:11642 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "la columna «%s» no puede convertirse automáticamente al tipo %s" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:11645 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "Puede ser necesario especificar «USING %s::%s»." + +#: commands/tablecmds.c:11745 +#, c-format +msgid "cannot alter inherited column \"%s\" of relation \"%s\"" +msgstr "no se puede alterar la columna heredada «%s» de la relación «%s»" + +#: commands/tablecmds.c:11773 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "La expresión USING contiene una referencia a la fila completa (whole-row)." + +#: commands/tablecmds.c:11784 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "debe cambiar el tipo a la columna heredada «%s» en las tablas hijas también" + +#: commands/tablecmds.c:11909 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "no se puede alterar el tipo de la columna «%s» dos veces" + +#: commands/tablecmds.c:11947 +#, c-format +msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" +msgstr "la expresión de generación para la columna «%s» no puede ser convertido automáticamente al tipo %s" + +#: commands/tablecmds.c:11952 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "el valor por omisión para la columna «%s» no puede ser convertido automáticamente al tipo %s" + +#: commands/tablecmds.c:12030 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "no se puede alterar el tipo de una columna usada por una columna generada" + +#: commands/tablecmds.c:12031 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "La columna «%s» es usada por la columna generada «%s»." + +#: commands/tablecmds.c:12052 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "no se puede alterar el tipo de una columna usada en una regla o vista" + +#: commands/tablecmds.c:12053 commands/tablecmds.c:12072 +#: commands/tablecmds.c:12090 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%s depende de la columna «%s»" + +#: commands/tablecmds.c:12071 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "no se puede alterar el tipo de una columna usada en una definición de trigger" + +#: commands/tablecmds.c:12089 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "no se puede alterar el tipo de una columna usada en una definición de política" + +#: commands/tablecmds.c:13158 commands/tablecmds.c:13170 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "no se puede cambiar el dueño del índice «%s»" + +#: commands/tablecmds.c:13160 commands/tablecmds.c:13172 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "Considere cambiar el dueño de la tabla en vez de cambiar el dueño del índice." + +#: commands/tablecmds.c:13186 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "no se puede cambiar el dueño de la secuencia «%s»" + +#: commands/tablecmds.c:13200 commands/tablecmds.c:16503 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "Considere usar ALTER TYPE." + +#: commands/tablecmds.c:13209 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "«%s» no es una tabla, vista, secuencia o tabla foránea" + +#: commands/tablecmds.c:13548 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "no se pueden tener múltiples subórdenes SET TABLESPACE" + +#: commands/tablecmds.c:13625 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "«%s» no es una tabla, vista, tabla materializada, índice o tabla TOAST" + +#: commands/tablecmds.c:13658 commands/view.c:494 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "WITH CHECK OPTION sólo puede usarse en vistas automáticamente actualizables" + +#: commands/tablecmds.c:13910 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "solamente tablas, índices y vistas materializadas existen en tablespaces" + +#: commands/tablecmds.c:13922 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "no se puede mover objetos hacia o desde el tablespace pg_global" + +#: commands/tablecmds.c:14014 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "cancelando porque el lock en la relación «%s.%s» no está disponible" + +#: commands/tablecmds.c:14030 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "no se encontraron relaciones coincidentes en el tablespace «%s»" + +#: commands/tablecmds.c:14146 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "no se puede cambiar la herencia de una tabla tipada" + +#: commands/tablecmds.c:14151 commands/tablecmds.c:14707 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "no puede cambiar la herencia de una partición" + +#: commands/tablecmds.c:14156 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "no se puede cambiar la herencia de una tabla particionada" + +#: commands/tablecmds.c:14202 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "no se puede agregar herencia a tablas temporales de otra sesión" + +#: commands/tablecmds.c:14215 +#, c-format +msgid "cannot inherit from a partition" +msgstr "no se puede heredar de una partición" + +#: commands/tablecmds.c:14237 commands/tablecmds.c:17147 +#, c-format +msgid "circular inheritance not allowed" +msgstr "la herencia circular no está permitida" + +#: commands/tablecmds.c:14238 commands/tablecmds.c:17148 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "«%s» ya es un hijo de «%s»." + +#: commands/tablecmds.c:14251 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "el trigger «%s» impide a la tabla «%s» convertirse en hija de herencia" + +#: commands/tablecmds.c:14253 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." +msgstr "Los triggers ROW con tablas de transición no están permitidos en jerarquías de herencia." + +#: commands/tablecmds.c:14456 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "columna «%s» en tabla hija debe marcarse como NOT NULL" + +#: commands/tablecmds.c:14465 +#, fuzzy, c-format +#| msgid "column \"%s\" in child table must be marked NOT NULL" +msgid "column \"%s\" in child table must be a generated column" +msgstr "columna «%s» en tabla hija debe marcarse como NOT NULL" + +#: commands/tablecmds.c:14515 +#, fuzzy, c-format +#| msgid "column \"%s\" inherits conflicting generation expressions" +msgid "column \"%s\" in child table has a conflicting generation expression" +msgstr "la columna «%s» hereda expresiones de generación en conflicto" + +#: commands/tablecmds.c:14543 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "tabla hija no tiene la columna «%s»" + +#: commands/tablecmds.c:14631 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "la tabla hija «%s» tiene una definición diferente para la restricción «check» «%s»" + +#: commands/tablecmds.c:14639 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" +msgstr "la restricción «%s» está en conflicto con la restricción no heredada en la tabla hija «%s»" + +#: commands/tablecmds.c:14650 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "la restricción «%s» está en conflicto con la restricción NOT VALID en la tabla hija «%s»" + +#: commands/tablecmds.c:14685 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "tabla hija no tiene la restricción «%s»" + +#: commands/tablecmds.c:14773 +#, fuzzy, c-format +#| msgid "partition \"%s\" would overlap partition \"%s\"" +msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" +msgstr "la partición «%s» traslaparía con la partición «%s»" + +#: commands/tablecmds.c:14777 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the detach operation." +msgstr "" + +#: commands/tablecmds.c:14802 commands/tablecmds.c:14850 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "relación «%s» no es una partición de la relación «%s»" + +#: commands/tablecmds.c:14856 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "relación «%s» no es un padre de la relación «%s»" + +#: commands/tablecmds.c:15084 +#, c-format +msgid "typed tables cannot inherit" +msgstr "las tablas tipadas no pueden heredar" + +#: commands/tablecmds.c:15114 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "la tabla no tiene la columna «%s»" + +#: commands/tablecmds.c:15125 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "la tabla tiene columna «%s» en la posición en que el tipo requiere «%s»." + +#: commands/tablecmds.c:15134 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "la tabla «%s» tiene un tipo diferente para la columna «%s»" + +#: commands/tablecmds.c:15148 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "tabla tiene la columna extra «%s»" + +#: commands/tablecmds.c:15200 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "«%s» no es una tabla tipada" + +#: commands/tablecmds.c:15382 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "no se puede usar el índice no-único «%s» como identidad de réplica" + +#: commands/tablecmds.c:15388 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "no puede usar el índice no-inmediato «%s» como identidad de réplica" + +#: commands/tablecmds.c:15394 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "no se puede usar el índice funcional «%s» como identidad de réplica" + +#: commands/tablecmds.c:15400 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "no se puede usar el índice parcial «%s» como identidad de réplica" + +#: commands/tablecmds.c:15406 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "no se puede usar el índice no válido «%s» como identidad de réplica" + +#: commands/tablecmds.c:15423 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "el índice «%s» no puede usarse como identidad de réplica porque la column %d es una columna de sistema" + +#: commands/tablecmds.c:15430 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "el índice «%s» no puede usarse como identidad de réplica porque la column «%s» acepta valores nulos" + +#: commands/tablecmds.c:15677 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "no se puede cambiar el estado «logged» de la tabla «%s» porque es temporal" + +#: commands/tablecmds.c:15701 +#, c-format +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "no se pudo cambiar la tabla «%s» a «unlogged» porque es parte de una publicación" + +#: commands/tablecmds.c:15703 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "Las tablas «unlogged» no pueden replicarse." + +#: commands/tablecmds.c:15748 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "no se pudo cambiar la tabla «%s» a «logged» porque hace referencia a la tabla «unlogged» «%s»" + +#: commands/tablecmds.c:15758 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "no se pudo cambiar la tabla «%s» a «unlogged» porque hace referencia a la tabla «logged» «%s»" + +#: commands/tablecmds.c:15816 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "no se puede mover una secuencia enlazada a una tabla hacia otro esquema" + +#: commands/tablecmds.c:15923 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "ya existe una relación llamada «%s» en el esquema «%s»" + +#: commands/tablecmds.c:16486 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "«%s» no es un tipo compuesto" + +#: commands/tablecmds.c:16518 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "«%s» no es una tabla, vista, vista materializada, secuencia o tabla foránea" + +#: commands/tablecmds.c:16553 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "estrategia de particionamiento «%s» no reconocida" + +#: commands/tablecmds.c:16561 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "no se puede usar la estrategia de particionamiento «list» con más de una columna" + +#: commands/tablecmds.c:16627 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "la columna «%s» nombrada en llave de particionamiento no existe" + +#: commands/tablecmds.c:16635 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "no se puede usar la columna de sistema «%s» en llave de particionamiento" + +#: commands/tablecmds.c:16646 commands/tablecmds.c:16760 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "no se puede usar una columna generada en llave de particionamiento" + +#: commands/tablecmds.c:16647 commands/tablecmds.c:16761 commands/trigger.c:635 +#: rewrite/rewriteHandler.c:884 rewrite/rewriteHandler.c:919 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "La columna «%s» es una columna generada." + +#: commands/tablecmds.c:16723 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "las funciones utilizadas en expresiones de la llave de particionamiento deben estar marcadas IMMUTABLE" + +#: commands/tablecmds.c:16743 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "las expresiones en la llave de particionamiento no pueden contener referencias a columnas de sistema" + +#: commands/tablecmds.c:16773 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "no se pueden usar expresiones constantes como llave de particionamiento" + +#: commands/tablecmds.c:16794 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "no se pudo determinar qué ordenamiento (collation) usar para la expresión de particionamiento" + +#: commands/tablecmds.c:16829 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "Debe especificar una clase de operadores hash, o definir una clase de operadores por omisión para hash para el tipo de datos." + +#: commands/tablecmds.c:16835 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "Debe especificar una clase de operadores btree, o definir una clase de operadores por omisión para btree para el tipo de datos." + +#: commands/tablecmds.c:17087 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "«%s» ya es una partición" + +#: commands/tablecmds.c:17093 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "no puede adjuntar tabla tipada como partición" + +#: commands/tablecmds.c:17109 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "no puede adjuntar hija de herencia como partición" + +#: commands/tablecmds.c:17123 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "no puede adjuntar ancestro de herencia como partición" + +#: commands/tablecmds.c:17157 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "no se puede adjuntar una relación temporal como partición de la relación permanente «%s»" + +#: commands/tablecmds.c:17165 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "no se puede adjuntar una relación permanente como partición de la relación temporal «%s»" + +#: commands/tablecmds.c:17173 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "no se puede adjuntar como partición de una relación temporal de otra sesión" + +#: commands/tablecmds.c:17180 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "no se adjuntar una relación temporal de otra sesión como partición" + +#: commands/tablecmds.c:17200 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "la tabla «%s» contiene la columna «%s» no encontrada en el padre «%s»" + +#: commands/tablecmds.c:17203 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "La nueva partición sólo puede contener las columnas presentes en el padre." + +#: commands/tablecmds.c:17215 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "el trigger «%s» impide a la tabla «%s» devenir partición" + +#: commands/tablecmds.c:17217 commands/trigger.c:441 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "los triggers ROW con tablas de transición no están soportados en particiones" + +#: commands/tablecmds.c:17380 +#, c-format +msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" +msgstr "no se puede adjuntar la tabla foránea «%s» como partición de la tabla particionada «%s»" + +#: commands/tablecmds.c:17383 +#, fuzzy, c-format +#| msgid "Table \"%s\" contains unique indexes." +msgid "Partitioned table \"%s\" contains unique indexes." +msgstr "La tabla «%s» contiene índices únicos." + +#: commands/tablecmds.c:17703 +#, fuzzy, c-format +#| msgid "a hash-partitioned table may not have a default partition" +msgid "cannot detach partitions concurrently when a default partition exists" +msgstr "una tabla particionada por hash no puede tener una partición default" + +#: commands/tablecmds.c:17812 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\" concurrently" +msgid "partitioned table \"%s\" was removed concurrently" +msgstr "no se puede crear un índice en la tabla particionada «%s» concurrentemente" + +#: commands/tablecmds.c:17818 +#, fuzzy, c-format +#| msgid "cannot drop partitioned index \"%s\" concurrently" +msgid "partition \"%s\" was removed concurrently" +msgstr "no se puede eliminar el índice particionado «%s» concurrentemente" + +#: commands/tablecmds.c:18272 commands/tablecmds.c:18292 +#: commands/tablecmds.c:18312 commands/tablecmds.c:18331 +#: commands/tablecmds.c:18373 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "no se puede adjuntar el índice «%s» como partición del índice «%s»" + +#: commands/tablecmds.c:18275 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "El índice «%s» ya está adjunto a otro índice." + +#: commands/tablecmds.c:18295 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "El índice «%s» no es un índice en una partición de la tabla «%s»." + +#: commands/tablecmds.c:18315 +#, c-format +msgid "The index definitions do not match." +msgstr "Las definiciones de los índices no coinciden." + +#: commands/tablecmds.c:18334 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "El índice «%s» pertenece a una restricción en la tabla «%s», pero no existe una restricción para el índice «%s»." + +#: commands/tablecmds.c:18376 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "Otro índice ya está adjunto para la partición «%s»." + +#: commands/tablecmds.c:18606 +#, fuzzy, c-format +#| msgid "this build does not support compression" +msgid "column data type %s does not support compression" +msgstr "esta instalación no soporta compresión" + +#: commands/tablecmds.c:18613 +#, fuzzy, c-format +#| msgid "invalid compression level \"%s\"" +msgid "invalid compression method \"%s\"" +msgstr "valor de compresión «%s» no válido" + +#: commands/tablespace.c:162 commands/tablespace.c:179 +#: commands/tablespace.c:190 commands/tablespace.c:198 +#: commands/tablespace.c:650 replication/slot.c:1476 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" + +#: commands/tablespace.c:209 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "no se pudo hacer stat al directorio «%s»: %m" + +#: commands/tablespace.c:218 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "«%s» existe pero no es un directorio" + +#: commands/tablespace.c:249 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "se ha denegado el permiso para crear el tablespace «%s»" + +#: commands/tablespace.c:251 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "Debe ser superusuario para crear tablespaces." + +#: commands/tablespace.c:267 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "la ruta del tablespace no puede contener comillas simples" + +#: commands/tablespace.c:277 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "la ubicación del tablespace debe ser una ruta absoluta" + +#: commands/tablespace.c:289 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "la ruta «%s» del tablespace es demasiado larga" + +#: commands/tablespace.c:296 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "la ubicación del tablespace no debe estar dentro del directorio de datos" + +#: commands/tablespace.c:305 commands/tablespace.c:977 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "el nombre de tablespace «%s» es inaceptable" + +#: commands/tablespace.c:307 commands/tablespace.c:978 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "El prefijo «pg_» está reservado para tablespaces del sistema." + +#: commands/tablespace.c:326 commands/tablespace.c:999 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "el tablespace «%s» ya existe" + +#: commands/tablespace.c:444 commands/tablespace.c:960 +#: commands/tablespace.c:1049 commands/tablespace.c:1118 +#: commands/tablespace.c:1264 commands/tablespace.c:1467 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "no existe el tablespace «%s»" + +#: commands/tablespace.c:450 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "el tablespace «%s» no existe, omitiendo" + +#: commands/tablespace.c:478 +#, fuzzy, c-format +#| msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgid "tablespace \"%s\" cannot be dropped because some objects depend on it" +msgstr "no se puede eliminar el rol «%s» porque otros objetos dependen de él" + +#: commands/tablespace.c:537 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "el tablespace «%s» no está vacío" + +#: commands/tablespace.c:609 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "no existe el directorio «%s»" + +#: commands/tablespace.c:610 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "Cree este directorio para el tablespace antes de reiniciar el servidor." + +#: commands/tablespace.c:615 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "no se pudo definir los permisos del directorio «%s»: %m" + +#: commands/tablespace.c:645 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "el directorio «%s» ya está siendo usado como tablespace" + +#: commands/tablespace.c:769 commands/tablespace.c:782 +#: commands/tablespace.c:818 commands/tablespace.c:910 storage/file/fd.c:3161 +#: storage/file/fd.c:3557 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "no se pudo eliminar el directorio «%s»: %m" + +#: commands/tablespace.c:831 commands/tablespace.c:919 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "no se pudo eliminar el enlace simbólico «%s»: %m" + +#: commands/tablespace.c:841 commands/tablespace.c:928 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "«%s» no es un directorio o enlace simbólico" + +#: commands/tablespace.c:1123 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "No existe el tablespace «%s»." + +#: commands/tablespace.c:1566 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "algunos directorios para el tablespace %u no pudieron eliminarse" + +#: commands/tablespace.c:1568 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "Puede eliminar los directorios manualmente, si es necesario." + +#: commands/trigger.c:198 commands/trigger.c:209 +#, c-format +msgid "\"%s\" is a table" +msgstr "«%s» es una tabla" + +#: commands/trigger.c:200 commands/trigger.c:211 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "Las tablas no pueden tener disparadores INSTEAD OF." + +#: commands/trigger.c:232 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "«%s» es una tabla particionada" + +#: commands/trigger.c:234 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Los triggers en tablas particionadas no pueden tener tablas de transición." + +#: commands/trigger.c:246 commands/trigger.c:253 commands/trigger.c:423 +#, c-format +msgid "\"%s\" is a view" +msgstr "«%s» es una vista" + +#: commands/trigger.c:248 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "Las vistas no pueden tener disparadores BEFORE o AFTER a nivel de fila." + +#: commands/trigger.c:255 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "Las vistas no pueden tener disparadores TRUNCATE." + +#: commands/trigger.c:263 commands/trigger.c:270 commands/trigger.c:282 +#: commands/trigger.c:416 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "«%s» es una tabla foránea" + +#: commands/trigger.c:265 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "Las tablas foráneas no pueden tener disparadores INSTEAD OF." + +#: commands/trigger.c:272 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "Las tablas foráneas no pueden tener disparadores TRUNCATE." + +#: commands/trigger.c:284 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "Las tablas foráneas no pueden tener disparadores de restricción." + +#: commands/trigger.c:359 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "los disparadores TRUNCATE FOR EACH ROW no están soportados" + +#: commands/trigger.c:367 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "los disparadores INSTEAD OF deben ser FOR EACH ROW" + +#: commands/trigger.c:371 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "los disparadores INSTEAD OF no pueden tener condiciones WHEN" + +#: commands/trigger.c:375 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "los disparadores INSTEAD OF no pueden tener listas de columnas" + +#: commands/trigger.c:404 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "dar nombre a una variable ROW en la cláusula REFERENCING no está soportado" + +#: commands/trigger.c:405 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "utilice OLD TABLE o NEW TABLE para nombrar tablas de transición." + +#: commands/trigger.c:418 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Las tablas foráneas no pueden tener tablas de transición." + +#: commands/trigger.c:425 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Las triggers en vistas no pueden tener tablas de transición." + +#: commands/trigger.c:445 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "los triggers ROW con tablas de transición no están soportados con hijas de herencia" + +#: commands/trigger.c:451 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "el nombre de la tabla de transición solo se puede especificar para un disparador AFTER" + +#: commands/trigger.c:456 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "los triggers TRUNCATE con tablas de transición no están soportados" + +#: commands/trigger.c:473 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "las tablas de transición no pueden especificarse para triggers con más de un evento" + +#: commands/trigger.c:484 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "las tablas de transición no pueden especificarse para triggers con lista de columnas" + +#: commands/trigger.c:501 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "NEW TABLE sólo se puede especificar para un disparador INSERT o UPDATE" + +#: commands/trigger.c:506 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE no se puede especificar varias veces" + +#: commands/trigger.c:516 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE sólo se puede especificar para un disparador DELETE o UPDATE" + +#: commands/trigger.c:521 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE no se puede especificar varias veces" + +#: commands/trigger.c:531 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "el nombre de OLD TABLE y el nombre de NEW TABLE no pueden ser iguales" + +#: commands/trigger.c:595 commands/trigger.c:608 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "la condición WHEN de un disparador por sentencias no pueden referirse a los valores de las columnas" + +#: commands/trigger.c:600 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "la condición WHEN de un disparador en INSERT no puede referirse a valores OLD" + +#: commands/trigger.c:613 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "la condición WHEN de un disparador en DELETE no puede referirse a valores NEW" + +#: commands/trigger.c:618 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "la condición WHEN de un disparador BEFORE no puede referirse a columnas de sistema de NEW" + +#: commands/trigger.c:626 commands/trigger.c:634 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "la condición WHEN del trigger BEFORE no puede hacer referencia a columnas NEW generadas" + +#: commands/trigger.c:627 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "Se utiliza una referencia de la tupla completa, y la tabla contiene columnas generadas" + +#: commands/trigger.c:741 commands/trigger.c:1450 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "ya existe un trigger «%s» para la relación «%s»" + +#: commands/trigger.c:755 +#, fuzzy, c-format +#| msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgid "trigger \"%s\" for relation \"%s\" is an internal trigger" +msgstr "disparador «%s» para la relación «%s» no existe, omitiendo" + +#: commands/trigger.c:774 +#, fuzzy, c-format +#| msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgid "trigger \"%s\" for relation \"%s\" is a constraint trigger" +msgstr "disparador «%s» para la relación «%s» no existe, omitiendo" + +#: commands/trigger.c:1336 commands/trigger.c:1497 commands/trigger.c:1612 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "no existe el trigger «%s» para la tabla «%s»" + +#: commands/trigger.c:1580 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "permiso denegado: «%s» es un trigger de sistema" + +#: commands/trigger.c:2160 +#, c-format +msgid "trigger function %u returned null value" +msgstr "la función de trigger %u ha retornado un valor null" + +#: commands/trigger.c:2220 commands/trigger.c:2434 commands/trigger.c:2673 +#: commands/trigger.c:2977 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "un trigger BEFORE STATEMENT no puede retornar un valor" + +#: commands/trigger.c:2294 +#, c-format +msgid "moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported" +msgstr "mover registros a otra partición durante un trigger BEFORE FOR EACH ROW no está soportado" + +#: commands/trigger.c:2295 +#, c-format +msgid "Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." +msgstr "Antes de ejecutar el trigger «%s», la fila iba a estar en la partición «%s.%s»." + +#: commands/trigger.c:3043 executor/nodeModifyTable.c:1811 +#: executor/nodeModifyTable.c:1893 +#, c-format +msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgstr "el registro a ser actualizado ya fue modificado por una operación disparada por la orden actual" + +#: commands/trigger.c:3044 executor/nodeModifyTable.c:1193 +#: executor/nodeModifyTable.c:1267 executor/nodeModifyTable.c:1812 +#: executor/nodeModifyTable.c:1894 +#, c-format +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." +msgstr "Considere usar un disparador AFTER en lugar de un disparador BEFORE para propagar cambios a otros registros." + +#: commands/trigger.c:3073 executor/nodeLockRows.c:229 +#: executor/nodeLockRows.c:238 executor/nodeModifyTable.c:228 +#: executor/nodeModifyTable.c:1209 executor/nodeModifyTable.c:1829 +#: executor/nodeModifyTable.c:2059 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "no se pudo serializar el acceso debido a un update concurrente" + +#: commands/trigger.c:3081 executor/nodeModifyTable.c:1299 +#: executor/nodeModifyTable.c:1911 executor/nodeModifyTable.c:2083 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "no se pudo serializar el acceso debido a un delete concurrente" + +#: commands/trigger.c:4142 +#, fuzzy, c-format +#| msgid "cannot create temporary table within security-restricted operation" +msgid "cannot fire deferred trigger within security-restricted operation" +msgstr "no se puede crear una tabla temporal dentro una operación restringida por seguridad" + +#: commands/trigger.c:5185 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "la restricción «%s» no es postergable" + +#: commands/trigger.c:5208 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "no existe la restricción «%s»" + +#: commands/tsearchcmds.c:118 commands/tsearchcmds.c:635 +#, c-format +msgid "function %s should return type %s" +msgstr "la función %s debería retornar el tipo %s" + +#: commands/tsearchcmds.c:194 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "debe ser superusuario para crear analizadores de búsqueda en texto" + +#: commands/tsearchcmds.c:247 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "el parámetro de analizador de búsqueda en texto «%s» no es reconocido" + +#: commands/tsearchcmds.c:257 +#, c-format +msgid "text search parser start method is required" +msgstr "el método «start» del analizador de búsqueda en texto es obligatorio" + +#: commands/tsearchcmds.c:262 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "el método «gettoken» del analizador de búsqueda en texto es obligatorio" + +#: commands/tsearchcmds.c:267 +#, c-format +msgid "text search parser end method is required" +msgstr "el método «end» del analizador de búsqueda en texto es obligatorio" + +#: commands/tsearchcmds.c:272 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "el método «lextypes» del analizador de búsqueda en texto es obligatorio" + +#: commands/tsearchcmds.c:366 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "la plantilla de búsquede en texto «%s» no acepta opciones" + +#: commands/tsearchcmds.c:440 +#, c-format +msgid "text search template is required" +msgstr "la plantilla de búsqueda en texto es obligatoria" + +#: commands/tsearchcmds.c:701 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "debe ser superusuario para crear una plantilla de búsqueda en texto" + +#: commands/tsearchcmds.c:743 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "el parámetro de la plantilla de búsqueda en texto «%s» no es reconocido" + +#: commands/tsearchcmds.c:753 +#, c-format +msgid "text search template lexize method is required" +msgstr "el método «lexize» de la plantilla de búsqueda en texto es obligatorio" + +#: commands/tsearchcmds.c:933 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "el parámetro de configuración de búsqueda en texto «%s» no es reconocido" + +#: commands/tsearchcmds.c:940 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "no se puede especificar simultáneamente las opciones PARSER y COPY" + +#: commands/tsearchcmds.c:976 +#, c-format +msgid "text search parser is required" +msgstr "el analizador de búsqueda en texto es obligatorio" + +#: commands/tsearchcmds.c:1200 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "no existe el tipo de elemento «%s»" + +#: commands/tsearchcmds.c:1427 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "no existe un mapeo para el tipo de elemento «%s»" + +#: commands/tsearchcmds.c:1433 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "el mapeo para el tipo de elemento «%s» no existe, omitiendo" + +#: commands/tsearchcmds.c:1596 commands/tsearchcmds.c:1711 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "el formato de la lista de parámetros no es válido: «%s»" + +#: commands/typecmds.c:217 +#, c-format +msgid "must be superuser to create a base type" +msgstr "debe ser superusuario para crear un tipo base" + +#: commands/typecmds.c:275 +#, c-format +msgid "Create the type as a shell type, then create its I/O functions, then do a full CREATE TYPE." +msgstr "Cree el tipo como un tipo inconcluso, luego cree sus funciones de I/O, luego haga un CREATE TYPE completo." + +#: commands/typecmds.c:327 commands/typecmds.c:1465 commands/typecmds.c:4281 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "el atributo de tipo «%s» no es reconocido" + +#: commands/typecmds.c:385 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "la categoría de tipo «%s» no es válida: debe ser ASCII simple" + +#: commands/typecmds.c:404 +#, c-format +msgid "array element type cannot be %s" +msgstr "el tipo de elemento de array no puede ser %s" + +#: commands/typecmds.c:436 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "el alineamiento «%s» no es reconocido" + +#: commands/typecmds.c:453 commands/typecmds.c:4155 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "el almacenamiento «%s» no es reconocido" + +#: commands/typecmds.c:464 +#, c-format +msgid "type input function must be specified" +msgstr "debe especificarse la función de ingreso del tipo" + +#: commands/typecmds.c:468 +#, c-format +msgid "type output function must be specified" +msgstr "debe especificarse la función de salida de tipo" + +#: commands/typecmds.c:473 +#, c-format +msgid "type modifier output function is useless without a type modifier input function" +msgstr "la función de salida de modificadores de tipo es inútil sin una función de entrada de modificadores de tipo" + +#: commands/typecmds.c:515 +#, c-format +msgid "element type cannot be specified without a valid subscripting procedure" +msgstr "" + +#: commands/typecmds.c:784 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "«%s» no es un tipo de dato base válido para un dominio" + +#: commands/typecmds.c:882 +#, c-format +msgid "multiple default expressions" +msgstr "múltiples expresiones default" + +#: commands/typecmds.c:945 commands/typecmds.c:954 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "las restricciones NULL/NOT NULL no coinciden" + +#: commands/typecmds.c:970 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "las restricciones «check» en dominios no pueden ser marcadas NO INHERIT" + +#: commands/typecmds.c:979 commands/typecmds.c:2975 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "no se pueden poner restricciones de unicidad a un dominio" + +#: commands/typecmds.c:985 commands/typecmds.c:2981 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "no se pueden poner restricciones de llave primaria a un dominio" + +#: commands/typecmds.c:991 commands/typecmds.c:2987 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "las restricciones de exclusión no son posibles para los dominios" + +#: commands/typecmds.c:997 commands/typecmds.c:2993 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "no se pueden poner restricciones de llave foránea a un dominio" + +#: commands/typecmds.c:1006 commands/typecmds.c:3002 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "no se puede especificar la postergabilidad de las restricciones a un dominio" + +#: commands/typecmds.c:1320 utils/cache/typcache.c:2545 +#, c-format +msgid "%s is not an enum" +msgstr "%s no es un enum" + +#: commands/typecmds.c:1473 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "el atributo de tipo «subtype» es obligatorio" + +#: commands/typecmds.c:1478 +#, c-format +msgid "range subtype cannot be %s" +msgstr "el subtipo de rango no puede ser %s" + +#: commands/typecmds.c:1497 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "se especificó un ordenamiento (collation) al rango, pero el subtipo no soporta ordenamiento" + +#: commands/typecmds.c:1507 +#, c-format +msgid "cannot specify a canonical function without a pre-created shell type" +msgstr "no se puede especificar una función canónica sin antes crear un tipo inconcluso" + +#: commands/typecmds.c:1508 +#, c-format +msgid "Create the type as a shell type, then create its canonicalization function, then do a full CREATE TYPE." +msgstr "Cree el tipo como un tipo inconcluso, luego cree su función de canonicalización, luego haga un CREATE TYPE completo." + +#: commands/typecmds.c:1982 +#, c-format +msgid "type input function %s has multiple matches" +msgstr "la función de entrada %s del tipo tiene múltiples coincidencias" + +#: commands/typecmds.c:2000 +#, c-format +msgid "type input function %s must return type %s" +msgstr "la función de entrada %s del tipo debe retornar %s" + +#: commands/typecmds.c:2016 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "la función de entrada %s no debe ser volatile" + +#: commands/typecmds.c:2044 +#, c-format +msgid "type output function %s must return type %s" +msgstr "la función de salida %s del tipo debe retornar %s" + +#: commands/typecmds.c:2051 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "la función de salida %s no debe ser volatile" + +#: commands/typecmds.c:2080 +#, c-format +msgid "type receive function %s has multiple matches" +msgstr "la función de recepción %s del tipo tiene múltiples coincidencias" + +#: commands/typecmds.c:2098 +#, c-format +msgid "type receive function %s must return type %s" +msgstr "la función de recepción %s del tipo debe retornar %s" + +#: commands/typecmds.c:2105 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "la función «receive» %s del tipo no debe ser volatile" + +#: commands/typecmds.c:2133 +#, c-format +msgid "type send function %s must return type %s" +msgstr "la función «send» %s del tipo debe retornar %s" + +#: commands/typecmds.c:2140 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "la función «send» %s no debe ser volatile" + +#: commands/typecmds.c:2167 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr "la función typmod_in %s debe retornar tipo %s" + +#: commands/typecmds.c:2174 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "la función de modificadores de tipo %s no debe ser volatile" + +#: commands/typecmds.c:2201 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "la función typmod_out %s debe retornar tipo %s" + +#: commands/typecmds.c:2208 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "la función de salida de modificadores de tipo %s no debe ser volatile" + +#: commands/typecmds.c:2235 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "la función de análisis %s del tipo debe retornar %s" + +#: commands/typecmds.c:2264 +#, fuzzy, c-format +#| msgid "type input function %s must return type %s" +msgid "type subscripting function %s must return type %s" +msgstr "la función de entrada %s del tipo debe retornar %s" + +#: commands/typecmds.c:2274 +#, c-format +msgid "user-defined types cannot use subscripting function %s" +msgstr "" + +#: commands/typecmds.c:2320 +#, c-format +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." +msgstr "Debe especificar una clase de operadores para el tipo de rango, o definir una clase de operadores por omisión para el subtipo." + +#: commands/typecmds.c:2351 +#, c-format +msgid "range canonical function %s must return range type" +msgstr "la función canónica %s del rango debe retornar tipo de rango" + +#: commands/typecmds.c:2357 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "la función canónica %s del rango debe ser inmutable" + +#: commands/typecmds.c:2393 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "la función «diff» de subtipo, %s, debe retornar tipo %s" + +#: commands/typecmds.c:2400 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "la función «diff» de subtipo, %s, debe ser inmutable" + +#: commands/typecmds.c:2427 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "el valor de OID de pg_type no se definió en modo de actualización binaria" + +#: commands/typecmds.c:2460 +#, fuzzy, c-format +#| msgid "pg_type array OID value not set when in binary upgrade mode" +msgid "pg_type multirange OID value not set when in binary upgrade mode" +msgstr "el valor de OID de pg_type no se definió en modo de actualización binaria" + +#: commands/typecmds.c:2493 +#, fuzzy, c-format +#| msgid "pg_type array OID value not set when in binary upgrade mode" +msgid "pg_type multirange array OID value not set when in binary upgrade mode" +msgstr "el valor de OID de pg_type no se definió en modo de actualización binaria" + +#: commands/typecmds.c:2791 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "la columna «%s» de la tabla «%s» contiene valores null" + +#: commands/typecmds.c:2904 commands/typecmds.c:3106 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "no existe la restricción «%s» en el dominio «%s»" + +#: commands/typecmds.c:2908 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "no existe la restricción «%s» en el dominio «%s», omitiendo" + +#: commands/typecmds.c:3113 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "la restricción «%s» en el dominio «%s» no es una restricción «check»" + +#: commands/typecmds.c:3219 +#, c-format +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "la columna «%s» de la relación «%s» contiene valores que violan la nueva restricción" + +#: commands/typecmds.c:3448 commands/typecmds.c:3646 commands/typecmds.c:3727 +#: commands/typecmds.c:3913 +#, c-format +msgid "%s is not a domain" +msgstr "%s no es un dominio" + +#: commands/typecmds.c:3480 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "el dominio «%2$s» ya contiene una restricción llamada «%1$s»" + +#: commands/typecmds.c:3531 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "no se pueden usar referencias a tablas en restricción «check» para un dominio" + +#: commands/typecmds.c:3658 commands/typecmds.c:3739 commands/typecmds.c:4030 +#, c-format +msgid "%s is a table's row type" +msgstr "%s es el tipo de registro de una tabla" + +#: commands/typecmds.c:3660 commands/typecmds.c:3741 commands/typecmds.c:4032 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "Considere usar ALTER TABLE." + +#: commands/typecmds.c:3666 commands/typecmds.c:3747 commands/typecmds.c:3945 +#, c-format +msgid "cannot alter array type %s" +msgstr "no se puede alterar el tipo de array «%s»" + +#: commands/typecmds.c:3668 commands/typecmds.c:3749 commands/typecmds.c:3947 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "Puede alterar el tipo %s, lo cual alterará el tipo de array también." + +#: commands/typecmds.c:4015 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "ya existe un tipo llamado «%s» en el esquema «%s»" + +#: commands/typecmds.c:4183 +#, c-format +msgid "cannot change type's storage to PLAIN" +msgstr "no se puede cambiar el almacenamiento del tipo a PLAIN" + +#: commands/typecmds.c:4276 +#, c-format +msgid "type attribute \"%s\" cannot be changed" +msgstr "el atributo de tipo «%s» no puede ser cambiado" + +#: commands/typecmds.c:4294 +#, c-format +msgid "must be superuser to alter a type" +msgstr "debe ser superusuario para alterar un tipo" + +#: commands/typecmds.c:4315 commands/typecmds.c:4324 +#, c-format +msgid "%s is not a base type" +msgstr "«%s» no es un tipo base" + +#: commands/user.c:140 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSID ya no puede ser especificado" + +#: commands/user.c:294 +#, c-format +msgid "must be superuser to create superusers" +msgstr "debe ser superusuario para crear superusuarios" + +#: commands/user.c:301 +#, c-format +msgid "must be superuser to create replication users" +msgstr "debe ser superusuario para crear usuarios de replicación" + +#: commands/user.c:308 +#, fuzzy, c-format +#| msgid "must be superuser to create superusers" +msgid "must be superuser to create bypassrls users" +msgstr "debe ser superusuario para crear superusuarios" + +#: commands/user.c:315 +#, c-format +msgid "permission denied to create role" +msgstr "se ha denegado el permiso para crear el rol" + +#: commands/user.c:325 commands/user.c:1226 commands/user.c:1233 gram.y:15259 +#: gram.y:15304 utils/adt/acl.c:5248 utils/adt/acl.c:5254 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "el nombre de rol «%s» está reservado" + +#: commands/user.c:327 commands/user.c:1228 commands/user.c:1235 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "Los nombres de rol que empiezan con «pg_» están reservados." + +#: commands/user.c:348 commands/user.c:1250 +#, c-format +msgid "role \"%s\" already exists" +msgstr "el rol «%s» ya existe" + +#: commands/user.c:414 commands/user.c:845 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "la cadena vacía no es una contraseña válida, limpiando la contraseña" + +#: commands/user.c:443 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "el valor de OID de pg_authid no se definió en modo de actualización binaria" + +#: commands/user.c:722 +#, fuzzy, c-format +#| msgid "must be superuser to change bypassrls attribute" +msgid "must be superuser to alter superuser roles or change superuser attribute" +msgstr "debe ser superusuario para cambiar el atributo bypassrls" + +#: commands/user.c:729 +#, fuzzy, c-format +#| msgid "must be superuser or replication role to use replication slots" +msgid "must be superuser to alter replication roles or change replication attribute" +msgstr "debe ser superusuario o rol de replicación para usar slots de replicación" + +#: commands/user.c:736 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "debe ser superusuario para cambiar el atributo bypassrls" + +#: commands/user.c:752 commands/user.c:953 +#, c-format +msgid "permission denied" +msgstr "permiso denegado" + +#: commands/user.c:946 commands/user.c:1487 commands/user.c:1665 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "debe ser superusuario para alterar superusuarios" + +#: commands/user.c:983 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "debe ser superusuario para alterar parámetros globalmente" + +#: commands/user.c:1005 +#, c-format +msgid "permission denied to drop role" +msgstr "se ha denegado el permiso para eliminar el rol" + +#: commands/user.c:1030 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "no se puede usar un especificador especial de rol en DROP ROLE" + +#: commands/user.c:1040 commands/user.c:1197 commands/variable.c:778 +#: commands/variable.c:781 commands/variable.c:865 commands/variable.c:868 +#: utils/adt/acl.c:5103 utils/adt/acl.c:5151 utils/adt/acl.c:5179 +#: utils/adt/acl.c:5198 utils/init/miscinit.c:705 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "no existe el rol «%s»" + +#: commands/user.c:1045 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "el rol «%s» no existe, omitiendo" + +#: commands/user.c:1058 commands/user.c:1062 +#, c-format +msgid "current user cannot be dropped" +msgstr "el usuario activo no puede ser eliminado" + +#: commands/user.c:1066 +#, c-format +msgid "session user cannot be dropped" +msgstr "no se puede eliminar un usuario de la sesión" + +#: commands/user.c:1076 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "debe ser superusuario para eliminar superusuarios" + +#: commands/user.c:1092 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "no se puede eliminar el rol «%s» porque otros objetos dependen de él" + +#: commands/user.c:1213 +#, c-format +msgid "session user cannot be renamed" +msgstr "no se puede cambiar el nombre a un usuario de la sesión" + +#: commands/user.c:1217 +#, c-format +msgid "current user cannot be renamed" +msgstr "no se puede cambiar el nombre al usuario activo" + +#: commands/user.c:1260 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "debe ser superusuario para cambiar el nombre a superusuarios" + +#: commands/user.c:1267 +#, c-format +msgid "permission denied to rename role" +msgstr "se ha denegado el permiso para cambiar el nombre al rol" + +#: commands/user.c:1288 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "la contraseña MD5 fue borrada debido al cambio de nombre del rol" + +#: commands/user.c:1348 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "los nombres de columna no pueden ser incluidos en GRANT/REVOKE ROLE" + +#: commands/user.c:1386 +#, c-format +msgid "permission denied to drop objects" +msgstr "se ha denegado el permiso para eliminar objetos" + +#: commands/user.c:1413 commands/user.c:1422 +#, c-format +msgid "permission denied to reassign objects" +msgstr "se ha denegado el permiso para reasignar objetos" + +#: commands/user.c:1495 commands/user.c:1673 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "debe tener opción de admin en rol «%s»" + +#: commands/user.c:1509 +#, fuzzy, c-format +#| msgid "table \"%s\" cannot be replicated" +msgid "role \"%s\" cannot have explicit members" +msgstr "la tabla «%s» no puede replicarse" + +#: commands/user.c:1524 +#, c-format +msgid "must be superuser to set grantor" +msgstr "debe ser superusuario para especificar el cedente (grantor)" + +#: commands/user.c:1560 +#, fuzzy, c-format +#| msgid "role \"%s\" is not a member of role \"%s\"" +msgid "role \"%s\" cannot be a member of any role" +msgstr "el rol «%s» no es un miembro del rol «%s»" + +#: commands/user.c:1573 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "el rol «%s» es un miembro del rol «%s»" + +#: commands/user.c:1588 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "el rol «%s» ya es un miembro del rol «%s»" + +#: commands/user.c:1695 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "el rol «%s» no es un miembro del rol «%s»" + +#: commands/vacuum.c:132 +#, c-format +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "opción de ANALYZE «%s» no reconocida" + +#: commands/vacuum.c:156 +#, c-format +msgid "parallel option requires a value between 0 and %d" +msgstr "la opción parallel requiere un valor entre 0 y %d" + +#: commands/vacuum.c:168 +#, fuzzy, c-format +#| msgid "parallel vacuum degree must be between 0 and %d" +msgid "parallel workers for vacuum must be between 0 and %d" +msgstr "el grado de paralelismo de vacuum debe estar entre 0 y %d" + +#: commands/vacuum.c:185 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "opción de VACUUM «%s» no reconocida" + +#: commands/vacuum.c:208 +#, c-format +msgid "VACUUM FULL cannot be performed in parallel" +msgstr "VACUUM FULL no puede ser ejecutado en paralelo" + +#: commands/vacuum.c:224 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "la opción ANALYZE debe especificarse cuando se provee una lista de columnas" + +#: commands/vacuum.c:314 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s no puede ejecutarse desde VACUUM o ANALYZE" + +#: commands/vacuum.c:324 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "la opción DISABLE_PAGE_SKIPPING de VACUUM no puede usarse con FULL" + +#: commands/vacuum.c:331 +#, c-format +msgid "PROCESS_TOAST required with VACUUM FULL" +msgstr "" + +#: commands/vacuum.c:572 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "omitiendo «%s»: sólo un superusuario puede aplicarle VACUUM" + +#: commands/vacuum.c:576 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "omitiendo «%s»: sólo un superusuario o el dueño de la base de datos puede aplicarle VACUUM" + +#: commands/vacuum.c:580 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "omitiendo «%s»: sólo su dueño o el de la base de datos puede aplicarle VACUUM" + +#: commands/vacuum.c:595 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "omitiendo «%s»: sólo un superusuario puede analizarla" + +#: commands/vacuum.c:599 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "omitiendo «%s»: sólo un superusuario o el dueño de la base de datos puede analizarla" + +#: commands/vacuum.c:603 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "omitiendo «%s»: sólo su dueño o el de la base de datos puede analizarla" + +#: commands/vacuum.c:682 commands/vacuum.c:778 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "omitiendo el vacuum de «%s»: el candado no está disponible" + +#: commands/vacuum.c:687 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "omitiendo el vacuum de «%s» --- la relación ya no existe" + +#: commands/vacuum.c:703 commands/vacuum.c:783 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "omitiendo analyze de «%s»: el candado no está disponible" + +#: commands/vacuum.c:708 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "omitiendo analyze de «%s» --- la relación ya no existe" + +#: commands/vacuum.c:1026 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "xmin más antiguo es demasiado antiguo" + +#: commands/vacuum.c:1027 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Cierre transaciones abiertas pronto para impedir problemas por reciclaje de contadores.\n" +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." + +#: commands/vacuum.c:1068 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "multixact más antiguo es demasiado antiguo" + +#: commands/vacuum.c:1069 +#, c-format +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "Cierre transacciones con multixact pronto para prevenir problemas por reciclaje del contador." + +#: commands/vacuum.c:1726 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "algunas bases de datos no han tenido VACUUM en más de 2 mil millones de transacciones" + +#: commands/vacuum.c:1727 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "Puede haber sufrido ya problemas de pérdida de datos por reciclaje del contador de transacciones." + +#: commands/vacuum.c:1891 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "omitiendo «%s»: no se puede aplicar VACUUM a objetos que no son tablas o a tablas especiales de sistema" + +#: commands/variable.c:165 utils/misc/guc.c:11625 utils/misc/guc.c:11687 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "Palabra clave no reconocida: «%s»." + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "Especificaciones contradictorias de «datestyle»." + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "No se pueden especificar meses en el intervalo de huso horario." + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "No se pueden especificar días en el intervalo de huso horario." + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "el huso horario «%s» parece usar segundos intercalares (bisiestos)" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQL no soporta segundos intercalares." + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "El desplazamiento de huso horario UTC está fuera de rango." + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "no se puede poner en modo de escritura dentro de una transacción de sólo lectura" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "el modo de escritura debe ser activado antes de cualquier consulta" + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "no se puede poner en modo de escritura durante la recuperación" + +#: commands/variable.c:534 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "SET TRANSACTION ISOLATION LEVEL debe ser llamado antes de cualquier consulta" + +#: commands/variable.c:541 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "SET TRANSACTION ISOLATION LEVEL no debe ser llamado en una subtransacción" + +#: commands/variable.c:548 storage/lmgr/predicate.c:1693 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "no se puede utilizar el modo serializable en un hot standby" + +#: commands/variable.c:549 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "Puede utilizar REPEATABLE READ en su lugar." + +#: commands/variable.c:567 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "SET TRANSACTION [NOT] DEFERRABLE no puede ser llamado en una subtransacción" + +#: commands/variable.c:573 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "SET TRANSACTION [NOT] DEFERRABLE debe ser llamado antes de cualquier consulta" + +#: commands/variable.c:655 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "La conversión entre %s y %s no está soportada." + +#: commands/variable.c:662 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "No se puede cambiar «client_encoding» ahora." + +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "no se puede cambiar «client_encoding» durante una operación paralela" + +#: commands/variable.c:890 +#, fuzzy, c-format +#| msgid "permission denied to set role \"%s\"" +msgid "permission will be denied to set role \"%s\"" +msgstr "se ha denegado el permiso para definir el rol «%s»" + +#: commands/variable.c:895 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "se ha denegado el permiso para definir el rol «%s»" + +#: commands/view.c:84 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "no se pudo determinar el ordenamiento (collation) a usar para la columna «%s» de vista" + +#: commands/view.c:265 commands/view.c:276 +#, c-format +msgid "cannot drop columns from view" +msgstr "no se pueden eliminar columnas de una vista" + +#: commands/view.c:281 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "no se puede cambiar el nombre de la columna «%s» de la vista a «%s»" + +#: commands/view.c:284 +#, c-format +msgid "Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead." +msgstr "Use ALTER VIEW ... RENAME COLUMN ... para cambiar el nombre de una columna de una vista." + +#: commands/view.c:290 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "no se puede cambiar el tipo de dato de la columna «%s» de la vista de %s a %s" + +#: commands/view.c:441 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "una vista no puede tener SELECT INTO" + +#: commands/view.c:453 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "las vistas no deben contener sentencias que modifiquen datos en WITH" + +#: commands/view.c:523 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "CREATE VIEW especifica más nombres de columna que columnas" + +#: commands/view.c:531 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "las vistas no pueden ser «unlogged» porque no tienen almacenamiento" + +#: commands/view.c:545 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "la vista «%s» será una vista temporal" + +#: executor/execCurrent.c:79 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "el cursor «%s» no es una orden SELECT" + +#: executor/execCurrent.c:85 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "el cursor «%s» está abierto desde una transacción anterior" + +#: executor/execCurrent.c:118 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "el cursor «%s» tiene múltiples referencias FOR UPDATE/SHARE a la tabla «%s»" + +#: executor/execCurrent.c:127 +#, c-format +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "el cursor «%s» no tiene una referencia FOR UPDATE/SHARE a la tabla «%s»" + +#: executor/execCurrent.c:137 executor/execCurrent.c:182 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr "el cursor «%s» no está posicionado en una fila" + +#: executor/execCurrent.c:169 executor/execCurrent.c:228 +#: executor/execCurrent.c:239 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "el cursor «%s» no es un recorrido simplemente actualizable de la tabla «%s»" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2451 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "el tipo del parámetro %d (%s) no coincide aquel con que fue preparado el plan (%s)" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2463 +#, c-format +msgid "no value found for parameter %d" +msgstr "no se encontró un valor para parámetro %d" + +#: executor/execExpr.c:632 executor/execExpr.c:639 executor/execExpr.c:645 +#: executor/execExprInterp.c:4023 executor/execExprInterp.c:4040 +#: executor/execExprInterp.c:4141 executor/nodeModifyTable.c:117 +#: executor/nodeModifyTable.c:128 executor/nodeModifyTable.c:145 +#: executor/nodeModifyTable.c:153 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "el tipo de registro de la tabla no coincide con el tipo de registro de la consulta" + +#: executor/execExpr.c:633 executor/nodeModifyTable.c:118 +#, c-format +msgid "Query has too many columns." +msgstr "La consulta tiene demasiadas columnas." + +#: executor/execExpr.c:640 executor/nodeModifyTable.c:146 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "La consulta entrega un valor para una columna eliminada en la posición %d." + +#: executor/execExpr.c:646 executor/execExprInterp.c:4041 +#: executor/nodeModifyTable.c:129 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "La tabla tiene tipo %s en posición ordinal %d, pero la consulta esperaba %s." + +#: executor/execExpr.c:1110 parser/parse_agg.c:827 +#, c-format +msgid "window function calls cannot be nested" +msgstr "no se pueden anidar llamadas a funciones de ventana deslizante" + +#: executor/execExpr.c:1615 +#, c-format +msgid "target type is not an array" +msgstr "el tipo de destino no es un array" + +#: executor/execExpr.c:1955 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "la columna de ROW() es de tipo %s en lugar de ser de tipo %s" + +#: executor/execExpr.c:2480 executor/execSRF.c:718 parser/parse_func.c:138 +#: parser/parse_func.c:655 parser/parse_func.c:1031 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "no se pueden pasar más de %d argumento a una función" +msgstr[1] "no se pueden pasar más de %d argumentos a una función" + +#: executor/execExpr.c:2866 parser/parse_node.c:277 parser/parse_node.c:327 +#, fuzzy, c-format +#| msgid "cannot subscript type %s because it is not an array" +msgid "cannot subscript type %s because it does not support subscripting" +msgstr "no se puede poner subíndices al tipo %s porque no es un array" + +#: executor/execExpr.c:2994 executor/execExpr.c:3016 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support subscriptions." +msgid "type %s does not support subscripted assignment" +msgstr "El servidor (versión %s) no soporta suscripciones." + +#: executor/execExprInterp.c:1916 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "El atributo %d de tipo %s ha sido eliminado" + +#: executor/execExprInterp.c:1922 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "el atributo %d del tipo %s tiene tipo erróneo" + +#: executor/execExprInterp.c:1924 executor/execExprInterp.c:3052 +#: executor/execExprInterp.c:3098 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "La tabla tiene tipo %s, pero la consulta esperaba %s." + +#: executor/execExprInterp.c:2003 utils/adt/expandedrecord.c:99 +#: utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1748 +#: utils/cache/typcache.c:1904 utils/cache/typcache.c:2033 +#: utils/fmgr/funcapi.c:458 +#, c-format +msgid "type %s is not composite" +msgstr "el tipo %s no es compuesto" + +#: executor/execExprInterp.c:2541 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF no está soportado para este tipo de tabla" + +#: executor/execExprInterp.c:2754 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "no se puede mezclar arrays incompatibles" + +#: executor/execExprInterp.c:2755 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "El array con tipo de elemento %s no puede ser incluido en una sentencia ARRAY con tipo de elemento %s." + +#: executor/execExprInterp.c:2776 utils/adt/arrayfuncs.c:262 +#: utils/adt/arrayfuncs.c:562 utils/adt/arrayfuncs.c:1304 +#: utils/adt/arrayfuncs.c:3374 utils/adt/arrayfuncs.c:5336 +#: utils/adt/arrayfuncs.c:5853 utils/adt/arraysubs.c:150 +#: utils/adt/arraysubs.c:488 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "el número de dimensiones del array (%d) excede el máximo permitido (%d)" + +#: executor/execExprInterp.c:2796 executor/execExprInterp.c:2826 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "los arrays multidimensionales deben tener expresiones de arrays con dimensiones coincidentes" + +#: executor/execExprInterp.c:3051 executor/execExprInterp.c:3097 +#, c-format +msgid "attribute %d has wrong type" +msgstr "el atributo %d tiene tipo erróneo" + +#: executor/execExprInterp.c:3652 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "el dominio %s no permite valores null" + +#: executor/execExprInterp.c:3667 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "el valor para el dominio %s viola la restricción «check» «%s»" + +#: executor/execExprInterp.c:4024 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "La fila de la tabla contiene %d atributo, pero la consulta esperaba %d." +msgstr[1] "La fila de la tabla contiene %d atributos, pero la consulta esperaba %d." + +#: executor/execExprInterp.c:4142 executor/execSRF.c:977 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "Discordancia de almacenamiento físico en atributo eliminado en la posición %d." + +#: executor/execIndexing.c:571 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "ON CONFLICT no soporta las restricciones únicas o de exclusión postergables como árbitros" + +#: executor/execIndexing.c:842 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "no se pudo crear la restricción de exclusión «%s»" + +#: executor/execIndexing.c:845 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "La llave %s está en conflicto con la llave %s." + +#: executor/execIndexing.c:847 +#, c-format +msgid "Key conflicts exist." +msgstr "Existe un conflicto de llave." + +#: executor/execIndexing.c:853 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "llave en conflicto viola la restricción de exclusión «%s»" + +#: executor/execIndexing.c:856 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "La llave %s está en conflicto con la llave existente %s." + +#: executor/execIndexing.c:858 +#, c-format +msgid "Key conflicts with existing key." +msgstr "La llave está en conflicto con una llave existente." + +#: executor/execMain.c:1007 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "no se puede cambiar la secuencia «%s»" + +#: executor/execMain.c:1013 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "no se puede cambiar la relación TOAST «%s»" + +#: executor/execMain.c:1031 rewrite/rewriteHandler.c:3041 +#: rewrite/rewriteHandler.c:3824 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "no se puede insertar en la vista «%s»" + +#: executor/execMain.c:1033 rewrite/rewriteHandler.c:3044 +#: rewrite/rewriteHandler.c:3827 +#, c-format +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "Para posibilitar las inserciones en la vista, provea un disparador INSTEAD OF INSERT o una regla incodicional ON INSERT DO INSTEAD." + +#: executor/execMain.c:1039 rewrite/rewriteHandler.c:3049 +#: rewrite/rewriteHandler.c:3832 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "no se puede actualizar la vista «%s»" + +#: executor/execMain.c:1041 rewrite/rewriteHandler.c:3052 +#: rewrite/rewriteHandler.c:3835 +#, c-format +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "Para posibilitar las actualizaciones en la vista, provea un disparador INSTEAD OF UPDATE o una regla incondicional ON UPDATE DO INSTEAD." + +#: executor/execMain.c:1047 rewrite/rewriteHandler.c:3057 +#: rewrite/rewriteHandler.c:3840 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "no se puede eliminar de la vista «%s»" + +#: executor/execMain.c:1049 rewrite/rewriteHandler.c:3060 +#: rewrite/rewriteHandler.c:3843 +#, c-format +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "Para posibilitar las eliminaciones en la vista, provea un disparador INSTEAD OF DELETE o una regla incondicional ON DELETE DO INSTEAD." + +#: executor/execMain.c:1060 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "no se puede cambiar la vista materializada «%s»" + +#: executor/execMain.c:1072 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "no se puede insertar en la tabla foránea «%s»" + +#: executor/execMain.c:1078 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "la tabla foránea «%s» no permite inserciones" + +#: executor/execMain.c:1085 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "no se puede actualizar la tabla foránea «%s»" + +#: executor/execMain.c:1091 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "la tabla foránea «%s» no permite actualizaciones" + +#: executor/execMain.c:1098 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "no se puede eliminar desde la tabla foránea «%s»" + +#: executor/execMain.c:1104 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "la tabla foránea «%s» no permite eliminaciones" + +#: executor/execMain.c:1115 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "no se puede cambiar la relación «%s»" + +#: executor/execMain.c:1142 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "no se puede bloquear registros de la secuencia «%s»" + +#: executor/execMain.c:1149 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "no se puede bloquear registros en la relación TOAST «%s»" + +#: executor/execMain.c:1156 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "no se puede bloquear registros en la vista «%s»" + +#: executor/execMain.c:1164 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "no se puede bloquear registros en la vista materializada «%s»" + +#: executor/execMain.c:1173 executor/execMain.c:2555 +#: executor/nodeLockRows.c:136 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "no se puede bloquear registros en la tabla foránea «%s»" + +#: executor/execMain.c:1179 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "no se puede bloquear registros en la tabla «%s»" + +#: executor/execMain.c:1803 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "el nuevo registro para la relación «%s» viola la restricción de partición" + +#: executor/execMain.c:1805 executor/execMain.c:1888 executor/execMain.c:1938 +#: executor/execMain.c:2047 +#, c-format +msgid "Failing row contains %s." +msgstr "La fila que falla contiene %s." + +#: executor/execMain.c:1885 +#, c-format +msgid "null value in column \"%s\" of relation \"%s\" violates not-null constraint" +msgstr "el valor nulo en la columna «%s» de la relación «%s» viola la restricción de no nulo" + +#: executor/execMain.c:1936 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "el nuevo registro para la relación «%s» viola la restricción «check» «%s»" + +#: executor/execMain.c:2045 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "el nuevo registro para la vista «%s» viola la opción check" + +#: executor/execMain.c:2055 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "el nuevo registro viola la política de seguridad de registros «%s» para la tabla «%s»" + +#: executor/execMain.c:2060 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "el nuevo registro viola la política de seguridad de registros para la tabla «%s»" + +#: executor/execMain.c:2067 +#, c-format +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "el nuevo registro viola la política de seguridad de registros «%s» (expresión USING) para la tabla «%s»" + +#: executor/execMain.c:2072 +#, c-format +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "el nuevo registro viola la política de seguridad de registros (expresión USING) para la tabla «%s»" + +#: executor/execPartition.c:322 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "no se encontró una partición de «%s» para el registro" + +#: executor/execPartition.c:325 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "La llave de particionamiento de la fila que falla contiene %s." + +#: executor/execReplication.c:196 executor/execReplication.c:373 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "el registro a ser bloqueado ya fue movido a otra partición debido a un update concurrente, reintentando" + +#: executor/execReplication.c:200 executor/execReplication.c:377 +#, c-format +msgid "concurrent update, retrying" +msgstr "actualización simultánea, reintentando" + +#: executor/execReplication.c:206 executor/execReplication.c:383 +#, c-format +msgid "concurrent delete, retrying" +msgstr "eliminacón concurrente, reintentando" + +#: executor/execReplication.c:269 parser/parse_cte.c:502 +#: parser/parse_oper.c:233 utils/adt/array_userfuncs.c:720 +#: utils/adt/array_userfuncs.c:859 utils/adt/arrayfuncs.c:3654 +#: utils/adt/arrayfuncs.c:4174 utils/adt/arrayfuncs.c:6166 +#: utils/adt/rowtypes.c:1203 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "no se pudo identificar un operador de igualdad para el tipo %s" + +#: executor/execReplication.c:590 +#, c-format +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "no se puede actualizar la tabla «%s» porque no tiene identidad de replicación y publica updates" + +#: executor/execReplication.c:592 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Para habilitar la actualización de la tabla, configure REPLICA IDENTITY utilizando ALTER TABLE." + +#: executor/execReplication.c:596 +#, c-format +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "no se puede eliminar de la tabla «%s» porque no tiene una identidad de replicación y publica deletes" + +#: executor/execReplication.c:598 +#, c-format +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "para habilitar la eliminación en la tabla, configure REPLICA IDENTITY utilizando ALTER TABLE." + +#: executor/execReplication.c:617 executor/execReplication.c:625 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "no se puede usar la relación «%s.%s» como destino de replicación lógica" + +#: executor/execReplication.c:619 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "«%s.%s» es una tabla foránea." + +#: executor/execReplication.c:627 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "«%s.%s» no es una tabla." + +#: executor/execSRF.c:315 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "las filas retornadas por la función no tienen todas el mismo tipo de registro" + +#: executor/execSRF.c:365 +#, fuzzy, c-format +#| msgid "table-function protocol for materialize mode was not followed" +msgid "table-function protocol for value-per-call mode was not followed" +msgstr "no se siguió el protocolo de función tabular para el modo de materialización" + +#: executor/execSRF.c:373 executor/execSRF.c:667 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "no se siguió el protocolo de función tabular para el modo de materialización" + +#: executor/execSRF.c:380 executor/execSRF.c:685 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "modo de retorno de la función tabular no es reconocido: %d" + +#: executor/execSRF.c:894 +#, c-format +msgid "function returning setof record called in context that cannot accept type record" +msgstr "se llamó una función que retorna «setof record» en un contexto que no puede aceptar el tipo record" + +#: executor/execSRF.c:950 executor/execSRF.c:966 executor/execSRF.c:976 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "la fila de retorno especificada en la consulta no coincide con fila de retorno de la función" + +#: executor/execSRF.c:951 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "Fila retornada contiene %d atributo, pero la consulta esperaba %d." +msgstr[1] "Fila retornada contiene %d atributos, pero la consulta esperaba %d." + +#: executor/execSRF.c:967 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "Tipo retornado %s en posición ordinal %d, pero la consulta esperaba %s." + +#: executor/execTuples.c:146 executor/execTuples.c:353 +#: executor/execTuples.c:521 executor/execTuples.c:712 +#, fuzzy, c-format +#| msgid "cannot use system column \"%s\" in partition key" +msgid "cannot retrieve a system column in this context" +msgstr "no se puede usar la columna de sistema «%s» en llave de particionamiento" + +#: executor/execUtils.c:736 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "la vista materializada «%s» no ha sido poblada" + +#: executor/execUtils.c:738 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "Use la orden REFRESH MATERIALIZED VIEW." + +#: executor/functions.c:217 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "no se pudo determinar el tipo de argumento declarado %s" + +#: executor/functions.c:514 +#, fuzzy, c-format +#| msgid "cannot COPY to/from client in a SQL function" +msgid "cannot COPY to/from client in an SQL function" +msgstr "no se puede ejecutar COPY desde/a un cliente en una función SQL" + +#. translator: %s is a SQL statement name +#: executor/functions.c:520 +#, fuzzy, c-format +#| msgid "%s is not allowed in a SQL function" +msgid "%s is not allowed in an SQL function" +msgstr "%s no está permitido en una función SQL" + +#. translator: %s is a SQL statement name +#: executor/functions.c:528 executor/spi.c:1633 executor/spi.c:2485 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "%s no está permitido en una función no-«volatile»" + +#: executor/functions.c:1441 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "función SQL «%s» en la sentencia %d" + +#: executor/functions.c:1467 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "función SQL «%s» durante el inicio" + +#: executor/functions.c:1552 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "no está permitido invocar procedimientos con arguments de salida en funciones SQL" + +#: executor/functions.c:1685 executor/functions.c:1723 +#: executor/functions.c:1737 executor/functions.c:1827 +#: executor/functions.c:1860 executor/functions.c:1874 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "el tipo de retorno de función declarada para retornar %s no concuerda" + +#: executor/functions.c:1687 +#, c-format +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "La sentencia final de la función debe ser un SELECT o INSERT/UPDATE/DELETE RETURNING." + +#: executor/functions.c:1725 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "La sentencia final debe retornar exactamente una columna." + +#: executor/functions.c:1739 +#, c-format +msgid "Actual return type is %s." +msgstr "El verdadero tipo de retorno es %s." + +#: executor/functions.c:1829 +#, c-format +msgid "Final statement returns too many columns." +msgstr "La sentencia final retorna demasiadas columnas." + +#: executor/functions.c:1862 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "La sentencia final retorna %s en lugar de %s en la columna %d." + +#: executor/functions.c:1876 +#, c-format +msgid "Final statement returns too few columns." +msgstr "La sentencia final retorna muy pocas columnas." + +#: executor/functions.c:1904 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "el tipo de retorno %s no es soportado en funciones SQL" + +#: executor/nodeAgg.c:3083 executor/nodeAgg.c:3092 executor/nodeAgg.c:3104 +#, c-format +msgid "unexpected EOF for tape %d: requested %zu bytes, read %zu bytes" +msgstr "EOF inesperado para la cinta %d: se requerían %zu bytes, se leyeron %zu bytes" + +#: executor/nodeAgg.c:3977 parser/parse_agg.c:666 parser/parse_agg.c:696 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "no se pueden anidar llamadas a funciones de agregación" + +#: executor/nodeAgg.c:4185 executor/nodeWindowAgg.c:2836 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "la función de agregación %u necesita tener tipos de entrada y transición compatibles" + +#: executor/nodeCustom.c:145 executor/nodeCustom.c:156 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "el scan personalizado «%s» no soporta MarkPos" + +#: executor/nodeHashjoin.c:1046 executor/nodeHashjoin.c:1076 +#, c-format +msgid "could not rewind hash-join temporary file" +msgstr "no se puede rebobinar el archivo temporal del hash-join" + +#: executor/nodeHashjoin.c:1272 executor/nodeHashjoin.c:1283 +#, c-format +msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgstr "no se pudo leer el archivo temporal de hash-join: se leyeron sólo %zu de %zu bytes" + +#: executor/nodeIndexonlyscan.c:242 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "no se permiten funciones de ventana deslizante en predicados de índice" + +#: executor/nodeLimit.c:374 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET no debe ser negativo" + +#: executor/nodeLimit.c:400 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT no debe ser negativo" + +#: executor/nodeMergejoin.c:1570 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "RIGHT JOIN sólo está soportado con condiciones que se pueden usar con merge join" + +#: executor/nodeMergejoin.c:1588 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "FULL JOIN sólo está soportado con condiciones que se pueden usar con merge join" + +#: executor/nodeModifyTable.c:154 +#, c-format +msgid "Query has too few columns." +msgstr "La consulta tiene muy pocas columnas." + +#: executor/nodeModifyTable.c:1192 executor/nodeModifyTable.c:1266 +#, c-format +msgid "tuple to be deleted was already modified by an operation triggered by the current command" +msgstr "el registro a ser eliminado ya fue modificado por una operación disparada por la orden actual" + +#: executor/nodeModifyTable.c:1441 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "especificación ON UPDATE no válida" + +#: executor/nodeModifyTable.c:1442 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "La tupla de resultado aparecería en una partición diferente que la tupla original." + +#: executor/nodeModifyTable.c:2038 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "la orden ON CONFLICT DO UPDATE no puede afectar el registro una segunda vez" + +#: executor/nodeModifyTable.c:2039 +#, c-format +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." +msgstr "Asegúrese de que ningún registro propuesto para inserción dentro de la misma orden tenga valores duplicados restringidos." + +#: executor/nodeSamplescan.c:259 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "el parámetro TABLESAMPLE no puede ser null" + +#: executor/nodeSamplescan.c:271 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "el parámetro TABLESAMPLE REPEATABLE no puede ser null" + +#: executor/nodeSubplan.c:346 executor/nodeSubplan.c:385 +#: executor/nodeSubplan.c:1159 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "una subconsulta utilizada como expresión retornó más de un registro" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "la URI del espacio de nombres no debe ser null" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "la expresión filtro de filas no debe ser null" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "la expresión filtro de columnas no debe ser null" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "El filtro para la columna «%s» es null." + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "null no está permitido en la columna «%s»" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "la función de transición de moving-aggregate no debe retornar valor nulo" + +#: executor/nodeWindowAgg.c:2058 +#, c-format +msgid "frame starting offset must not be null" +msgstr "la posición inicial del marco no debe ser null" + +#: executor/nodeWindowAgg.c:2071 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "la posición inicial del marco no debe ser negativa" + +#: executor/nodeWindowAgg.c:2083 +#, c-format +msgid "frame ending offset must not be null" +msgstr "la posición final del marco no debe ser null" + +#: executor/nodeWindowAgg.c:2096 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "la posición final del marco no debe ser negativa" + +#: executor/nodeWindowAgg.c:2752 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "la función de agregación %s no permite ser usada como función ventana" + +#: executor/spi.c:237 executor/spi.c:302 +#, c-format +msgid "invalid transaction termination" +msgstr "terminación de transacción no válida" + +#: executor/spi.c:251 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "no se puede comprometer mientras hay una subtransacción activa" + +#: executor/spi.c:308 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "no se puede hacer rollback mientras hay una subtransacción activa" + +#: executor/spi.c:380 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "transacción dejó un stack SPI no vacío" + +#: executor/spi.c:381 executor/spi.c:443 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "Revise llamadas a «SPI_finish» faltantes." + +#: executor/spi.c:442 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "subtransacción dejó un stack SPI no vacío" + +#: executor/spi.c:1495 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "no se puede abrir plan de varias consultas como cursor" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1500 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "no se puede abrir consulta %s como cursor" + +#: executor/spi.c:1607 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE no está soportado" + +#: executor/spi.c:1608 parser/analyze.c:2808 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "Los cursores declarados SCROLL deben ser READ ONLY." + +#: executor/spi.c:2808 +#, fuzzy, c-format +#| msgid "SQL function \"%s\"" +msgid "SQL expression \"%s\"" +msgstr "función SQL «%s»" + +#: executor/spi.c:2813 +#, fuzzy, c-format +#| msgid "SQL statement \"%s\"" +msgid "PL/pgSQL assignment \"%s\"" +msgstr "sentencia SQL: «%s»" + +#: executor/spi.c:2816 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "sentencia SQL: «%s»" + +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "no se pudo enviar la tupla a la cola en memoria compartida" + +#: foreign/foreign.c:220 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "no se encontró un mapeo para el usuario «%s»" + +#: foreign/foreign.c:672 +#, c-format +msgid "invalid option \"%s\"" +msgstr "el nombre de opción «%s» no es válido" + +#: foreign/foreign.c:673 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "Las opciones válidas en este contexto son: %s" + +#: gram.y:1107 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD ya no está soportado" + +#: gram.y:1108 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "Quite UNENCRYPTED para almacenar la contraseña en su lugar en forma cifrada." + +#: gram.y:1170 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "opción de rol «%s» no reconocida" + +#: gram.y:1417 gram.y:1432 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS no puede incluir elementos de esquema" + +#: gram.y:1578 +#, c-format +msgid "current database cannot be changed" +msgstr "no se puede cambiar la base de datos activa" + +#: gram.y:1702 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "el intervalo de huso horario debe ser HOUR o HOUR TO MINUTE" + +#: gram.y:2270 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "el número de columna debe estar en el rango de 1 a %d" + +#: gram.y:2811 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "la opción de secuencia «%s» no está soportado aquí" + +#: gram.y:2840 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "el módulo para partición de hash fue especificado más de una vez" + +#: gram.y:2849 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "el remanentde para partición de hash fue especificado más de una vez" + +#: gram.y:2856 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "especificación de borde de partición hash «%s» no reconocida" + +#: gram.y:2864 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "el módulo para una partición hash debe ser especificado" + +#: gram.y:2868 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "remanente en partición hash debe ser especificado" + +#: gram.y:3069 gram.y:3102 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "STDIN/STDOUT no están permitidos con PROGRAM" + +#: gram.y:3075 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "la cláusula WHERE no está permitida con COPY TO" + +#: gram.y:3407 gram.y:3414 gram.y:11665 gram.y:11673 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "GLOBAL está obsoleto para la creación de tablas temporales" + +#: gram.y:3665 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "para una columna generada, GENERATED ALWAYS debe ser especificado" + +#: gram.y:3933 utils/adt/ri_triggers.c:2032 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL no está implementada" + +#: gram.y:4634 +#, c-format +msgid "CREATE EXTENSION ... FROM is no longer supported" +msgstr "CREATE EXTENSION ... FROM ya no está soportado" + +#: gram.y:5297 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "opción de seguridad de registro «%s» no reconocida" + +#: gram.y:5298 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "sólo se admiten actualmente políticas PERMISSIVE o RESTRICTIVE." + +#: gram.y:5380 +#, fuzzy, c-format +#| msgid "nested CREATE EXTENSION is not supported" +msgid "CREATE OR REPLACE CONSTRAINT TRIGGER is not supported" +msgstr "los CREATE EXTENSION anidados no están soportados" + +#: gram.y:5417 +msgid "duplicate trigger events specified" +msgstr "se han especificado eventos de disparador duplicados" + +#: gram.y:5558 parser/parse_utilcmd.c:3734 parser/parse_utilcmd.c:3760 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "una restricción declarada INITIALLY DEFERRED debe ser DEFERRABLE" + +#: gram.y:5565 +#, c-format +msgid "conflicting constraint properties" +msgstr "propiedades de restricción contradictorias" + +#: gram.y:5661 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION no está implementado" + +#: gram.y:6044 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK ya no es requerido" + +#: gram.y:6045 +#, c-format +msgid "Update your data type." +msgstr "Actualice su tipo de datos." + +#: gram.y:7741 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "las funciones de agregación no pueden tener argumentos de salida" + +#: gram.y:8188 utils/adt/regproc.c:710 utils/adt/regproc.c:751 +#, c-format +msgid "missing argument" +msgstr "falta un argumento" + +#: gram.y:8189 utils/adt/regproc.c:711 utils/adt/regproc.c:752 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "Use NONE para denotar el argumento faltante de un operador unario." + +#: gram.y:10128 gram.y:10146 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION no está soportado con vistas recursivas" + +#: gram.y:11802 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "la sintaxis LIMIT #,# no está soportada" + +#: gram.y:11803 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "Use cláusulas LIMIT y OFFSET separadas." + +#: gram.y:12141 gram.y:12166 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "VALUES en FROM debe tener un alias" + +#: gram.y:12142 gram.y:12167 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "Por ejemplo, FROM (VALUES ...) [AS] foo." + +#: gram.y:12147 gram.y:12172 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "las subconsultas en FROM deben tener un alias" + +#: gram.y:12148 gram.y:12173 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "Por ejemplo, FROM (SELECT ...) [AS] foo." + +#: gram.y:12668 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "Sólo se permite un valor DEFAULT" + +#: gram.y:12677 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "sólo se permite un valor de PATH por columna" + +#: gram.y:12686 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "declaraciones NULL/NOT NULL en conflicto o redundantes para la columna «%s»" + +#: gram.y:12695 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "opción de columna «%s» no reconocida" + +#: gram.y:12949 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "la precisión para el tipo float debe ser al menos 1 bit" + +#: gram.y:12958 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "la precisión para el tipo float debe ser menor de 54 bits" + +#: gram.y:13456 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "el número de parámetros es incorrecto al lado izquierdo de la expresión OVERLAPS" + +#: gram.y:13461 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "el número de parámetros es incorrecto al lado derecho de la expresión OVERLAPS" + +#: gram.y:13629 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "el predicado UNIQUE no está implementado" + +#: gram.y:13988 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "no se permiten múltiples cláusulas ORDER BY con WITHIN GROUP" + +#: gram.y:13993 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "no se permite DISTINCT con WITHIN GROUP" + +#: gram.y:13998 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "no se permite VARIADIC con WITHIN GROUP" + +#: gram.y:14522 gram.y:14545 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "el inicio de «frame» no puede ser UNBOUNDED FOLLOWING" + +#: gram.y:14527 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "el «frame» que se inicia desde la siguiente fila no puede terminar en la fila actual" + +#: gram.y:14550 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "el fin de «frame» no puede ser UNBOUNDED PRECEDING" + +#: gram.y:14556 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "el «frame» que se inicia desde la fila actual no puede tener filas precedentes" + +#: gram.y:14563 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "el «frame» que se inicia desde la fila siguiente no puede tener filas precedentes" + +#: gram.y:15195 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "el modificador de tipo no puede tener nombre de parámetro" + +#: gram.y:15201 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "el modificador de tipo no puede tener ORDER BY" + +#: gram.y:15266 gram.y:15273 gram.y:15280 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s no puede ser usado como nombre de rol aquí" + +#: gram.y:15369 gram.y:16800 +#, fuzzy, c-format +#| msgid "WITH TIES cannot be specified without ORDER BY clause" +msgid "WITH TIES cannot be specified without ORDER BY clause" +msgstr "la opción WITH TIES no puede ser especificada sin una cláusula ORDER BY" + +#: gram.y:16477 gram.y:16666 +msgid "improper use of \"*\"" +msgstr "uso impropio de «*»" + +#: gram.y:16629 gram.y:16646 tsearch/spell.c:982 tsearch/spell.c:999 +#: tsearch/spell.c:1016 tsearch/spell.c:1033 tsearch/spell.c:1098 +#, c-format +msgid "syntax error" +msgstr "error de sintaxis" + +#: gram.y:16730 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "una agregación de conjunto-ordenado con un argumento directo VARIADIC debe tener al menos un argumento agregado VARIADIC del mismo tipo de datos" + +#: gram.y:16767 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "no se permiten múltiples cláusulas ORDER BY" + +#: gram.y:16778 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "no se permiten múltiples cláusulas OFFSET" + +#: gram.y:16787 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "no se permiten múltiples cláusulas LIMIT" + +#: gram.y:16796 +#, c-format +msgid "multiple limit options not allowed" +msgstr "no se permiten múltiples opciones limit" + +#: gram.y:16808 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "no se permiten múltiples cláusulas WITH" + +#: gram.y:17002 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "los argumentos OUT e INOUT no están permitidos en funciones TABLE" + +#: gram.y:17098 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "no se permiten múltiples cláusulas COLLATE" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17136 gram.y:17149 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "las restricciones %s no pueden ser marcadas DEFERRABLE" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17162 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "las restricciones %s no pueden ser marcadas NOT VALID" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17175 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "las restricciones %s no pueden ser marcadas NO INHERIT" + +#: guc-file.l:314 +#, fuzzy, c-format +#| msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %d" +msgstr "parámetro de configuración «%s» no reconocido en el archivo «%s» línea %u" + +#: guc-file.l:351 utils/misc/guc.c:7360 utils/misc/guc.c:7558 +#: utils/misc/guc.c:7652 utils/misc/guc.c:7746 utils/misc/guc.c:7866 +#: utils/misc/guc.c:7965 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "el parámetro «%s» no se puede cambiar sin reiniciar el servidor" + +#: guc-file.l:387 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "parámetro «%s» eliminado del archivo de configuración, volviendo al valor por omisión" + +#: guc-file.l:453 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "el parámetro «%s» fue cambiado a «%s»" + +#: guc-file.l:495 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "el archivo de configuración «%s» contiene errores" + +#: guc-file.l:500 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "el archivo de configuración «%s» contiene errores; los cambios no afectados fueron aplicados" + +#: guc-file.l:505 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "el archivo de configuración «%s» contiene errores; no se aplicó ningún cambio" + +#: guc-file.l:577 +#, c-format +msgid "empty configuration file name: \"%s\"" +msgstr "nombre de archivo de configuración vacío: «%s»" + +#: guc-file.l:594 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "no se pudo abrir el archivo de configuración «%s»: nivel de anidamiento máximo excedido" + +#: guc-file.l:614 +#, c-format +msgid "configuration file recursion in \"%s\"" +msgstr "recursión de archivos de configuración en «%s»" + +#: guc-file.l:630 libpq/hba.c:2251 libpq/hba.c:2665 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "no se pudo abrir el archivo de configuración «%s»: %m" + +#: guc-file.l:641 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "omitiendo el archivo de configuración faltante «%s»" + +#: guc-file.l:895 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "error de sintaxis en el archivo «%s» línea %u, cerca del fin de línea" + +#: guc-file.l:905 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "error de sintaxis en el archivo «%s» línea %u, cerca de la palabra «%s»" + +#: guc-file.l:925 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "se encontraron demasiados errores de sintaxis, abandonando el archivo «%s»" + +#: guc-file.l:980 +#, c-format +msgid "empty configuration directory name: \"%s\"" +msgstr "nombre de directorio de configuración vacío: «%s»" + +#: guc-file.l:999 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "no se pudo abrir el directorio de configuración «%s»: %m" + +#: jit/jit.c:205 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:417 +#: utils/fmgr/dfmgr.c:465 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "no se pudo acceder al archivo «%s»: %m" + +#: jsonpath_gram.y:528 jsonpath_scan.l:519 jsonpath_scan.l:530 +#: jsonpath_scan.l:540 jsonpath_scan.l:582 utils/adt/encode.c:435 +#: utils/adt/encode.c:501 utils/adt/jsonfuncs.c:623 utils/adt/varlena.c:339 +#: utils/adt/varlena.c:380 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "sintaxis de entrada no válida para tipo %s" + +#: jsonpath_gram.y:529 +#, fuzzy, c-format +#| msgid "unrecognized flag character \"%c\" in LIKE_REGEX predicate" +msgid "unrecognized flag character \"%.*s\" in LIKE_REGEX predicate" +msgstr "parámetro no reconocido «%c» en predicado LIKE_REGEX" + +#: jsonpath_gram.y:583 +#, c-format +msgid "XQuery \"x\" flag (expanded regular expressions) is not implemented" +msgstr "la opción «x» de XQuery (expresiones regulares expandidas) no está implementada" + +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:286 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "%s al final de la entrada jsonpath" + +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:293 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s en o cerca de «%s» de la entrada jsonpath" + +#: jsonpath_scan.l:498 utils/adt/jsonfuncs.c:617 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "secuencia de escape Unicode no soportado" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Falla en petición DSA de tamaño %zu." + +#: libpq/auth-scram.c:249 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "cliente eligió un mecanismo de autentificación SASL no válido" + +#: libpq/auth-scram.c:270 libpq/auth-scram.c:510 libpq/auth-scram.c:521 +#, c-format +msgid "invalid SCRAM secret for user \"%s\"" +msgstr "el secreto SCRAM para el usuario «%s» no es válido" + +#: libpq/auth-scram.c:281 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM secret." +msgstr "El usuario «%s» no tiene un secreto SCRAM válido." + +#: libpq/auth-scram.c:359 libpq/auth-scram.c:364 libpq/auth-scram.c:701 +#: libpq/auth-scram.c:709 libpq/auth-scram.c:814 libpq/auth-scram.c:827 +#: libpq/auth-scram.c:837 libpq/auth-scram.c:945 libpq/auth-scram.c:952 +#: libpq/auth-scram.c:967 libpq/auth-scram.c:982 libpq/auth-scram.c:996 +#: libpq/auth-scram.c:1014 libpq/auth-scram.c:1029 libpq/auth-scram.c:1340 +#: libpq/auth-scram.c:1348 +#, c-format +msgid "malformed SCRAM message" +msgstr "mensaje SCRAM mal formado" + +#: libpq/auth-scram.c:360 +#, c-format +msgid "The message is empty." +msgstr "El mensaje está vacío." + +#: libpq/auth-scram.c:365 +#, c-format +msgid "Message length does not match input length." +msgstr "El largo del mensaje no coincide con el largo de entrada." + +#: libpq/auth-scram.c:397 +#, c-format +msgid "invalid SCRAM response" +msgstr "respuesta SCRAM no válida" + +#: libpq/auth-scram.c:398 +#, c-format +msgid "Nonce does not match." +msgstr "El «nonce» no coincide." + +#: libpq/auth-scram.c:472 +#, c-format +msgid "could not generate random salt" +msgstr "no se pudo generar una sal aleatoria" + +#: libpq/auth-scram.c:702 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Se esperaba un atributo «%c» pero se encontró «%s»." + +#: libpq/auth-scram.c:710 libpq/auth-scram.c:838 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Se esperaba el carácter «=» para el atributo «%c»." + +#: libpq/auth-scram.c:815 +#, c-format +msgid "Attribute expected, but found end of string." +msgstr "Se esperaba un atributo, se encontró el fin de la cadena." + +#: libpq/auth-scram.c:828 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Se esperaba un atributo, se encontró el carácter no válido «%s»." + +#: libpq/auth-scram.c:946 libpq/auth-scram.c:968 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "El cliente seleccionó SCRAM-SHA-256-PLUS, pero el mensaje SCRAM no incluye los datos de enlazado (binding) del canal." + +#: libpq/auth-scram.c:953 libpq/auth-scram.c:983 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Se esperaba una coma, se encontró el carácter «%s»." + +#: libpq/auth-scram.c:974 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "error de negociación de enlazado (binding) de canal SCRAM" + +#: libpq/auth-scram.c:975 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "El cliente soporta enlazado (binding) de canal SCRAM, pero piensa que el servidor no. Sin embargo, este servidor sí soporta enlazado de canal." + +#: libpq/auth-scram.c:997 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "El cliente seleccionó SCRAM-SHA-256 sin enlazado de canal, pero el mensaje SCRAM incluye datos de enlazado de canal." + +#: libpq/auth-scram.c:1008 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "tipo de enlazado de canal SCRAM «%s» no soportado" + +#: libpq/auth-scram.c:1015 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Indicador de enlazado de canal «%s» inesperado." + +#: libpq/auth-scram.c:1025 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "el cliente usa identidad de autorización, pero no está soportada" + +#: libpq/auth-scram.c:1030 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Atributo inesperado \"%s\" en client-first-message." + +#: libpq/auth-scram.c:1046 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "el cliente requiere una extensión SCRAM no soportada" + +#: libpq/auth-scram.c:1060 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "caracteres no imprimibles en el «nonce» SCRAM" + +#: libpq/auth-scram.c:1188 +#, c-format +msgid "could not generate random nonce" +msgstr "no se pudo generar un «nonce» aleatorio" + +#: libpq/auth-scram.c:1198 +#, c-format +msgid "could not encode random nonce" +msgstr "no se pudo codificar un «nonce» aleatorio" + +#: libpq/auth-scram.c:1304 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "la verificación de enlazado (binding) de canal SCRAM falló" + +#: libpq/auth-scram.c:1322 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "atributo de enlazado de canal SCRAM inesperado en client-final-message" + +#: libpq/auth-scram.c:1341 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "Prueba (proof) mal formada en client-final-message." + +#: libpq/auth-scram.c:1349 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Basura encontrada al final de client-final-message." + +#: libpq/auth.c:284 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "la autentificación falló para el usuario «%s»: anfitrión rechazado" + +#: libpq/auth.c:287 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "la autentificación «trust» falló para el usuario «%s»" + +#: libpq/auth.c:290 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "la autentificación Ident falló para el usuario «%s»" + +#: libpq/auth.c:293 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "la autentificación Peer falló para el usuario «%s»" + +#: libpq/auth.c:298 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "la autentificación password falló para el usuario «%s»" + +#: libpq/auth.c:303 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "la autentificación GSSAPI falló para el usuario «%s»" + +#: libpq/auth.c:306 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "la autentificación SSPI falló para el usuario «%s»" + +#: libpq/auth.c:309 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "la autentificación PAM falló para el usuario «%s»" + +#: libpq/auth.c:312 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "la autentificación BSD falló para el usuario «%s»" + +#: libpq/auth.c:315 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "la autentificación LDAP falló para el usuario «%s»" + +#: libpq/auth.c:318 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "la autentificación por certificado falló para el usuario «%s»" + +#: libpq/auth.c:321 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "la autentificación RADIUS falló para el usuario «%s»" + +#: libpq/auth.c:324 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "la autentificación falló para el usuario «%s»: método de autentificación no válido" + +#: libpq/auth.c:328 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "La conexión coincidió con la línea %d de pg_hba.conf: «%s»" + +#: libpq/auth.c:371 +#, fuzzy, c-format +#| msgid "Connections and Authentication" +msgid "connection was re-authenticated" +msgstr "Conexiones y Autentificación" + +#: libpq/auth.c:372 +#, c-format +msgid "previous ID: \"%s\"; new ID: \"%s\"" +msgstr "" + +#: libpq/auth.c:381 +#, c-format +msgid "connection authenticated: identity=\"%s\" method=%s (%s:%d)" +msgstr "" + +#: libpq/auth.c:420 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "los certificados de cliente sólo pueden verificarse si un almacén de certificado raíz está disponible" + +#: libpq/auth.c:431 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "la conexión requiere un certificado de cliente válido" + +#: libpq/auth.c:462 libpq/auth.c:508 +#, fuzzy +#| msgid "GSSAPI-encrypted connection\n" +msgid "GSS encryption" +msgstr "Conexión Cifrada GSSAPI\n" + +#: libpq/auth.c:465 libpq/auth.c:511 +#, fuzzy +#| msgid "SSL on" +msgid "SSL encryption" +msgstr "SSL activo" + +#: libpq/auth.c:467 libpq/auth.c:513 +msgid "no encryption" +msgstr "" + +#. translator: last %s describes encryption state +#: libpq/auth.c:473 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "pg_hba.conf rechaza la conexión de replicación para el servidor «%s», usuario «%s», %s" + +#. translator: last %s describes encryption state +#: libpq/auth.c:480 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf rechaza la conexión para el servidor «%s», usuario «%s», base de datos «%s», %s" + +#: libpq/auth.c:518 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado es coincidente." + +#: libpq/auth.c:521 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado no fue verificado." + +#: libpq/auth.c:524 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado no es coincidente." + +#: libpq/auth.c:527 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "No se pudo traducir el nombre de host del cliente «%s» a una dirección IP: %s." + +#: libpq/auth.c:532 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "No se pudo obtener la dirección IP del cliente a un nombre de host: %s." + +#. translator: last %s describes encryption state +#: libpq/auth.c:540 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "no hay una línea en pg_hba.conf para la conexión de replicación desde el servidor «%s», usuario «%s», %s" + +#. translator: last %s describes encryption state +#: libpq/auth.c:548 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "no hay una línea en pg_hba.conf para «%s», usuario «%s», base de datos «%s», %s" + +#: libpq/auth.c:721 +#, c-format +msgid "expected password response, got message type %d" +msgstr "se esperaba una respuesta de contraseña, se obtuvo mensaje de tipo %d" + +#: libpq/auth.c:742 +#, c-format +msgid "invalid password packet size" +msgstr "el tamaño del paquete de contraseña no es válido" + +#: libpq/auth.c:760 +#, c-format +msgid "empty password returned by client" +msgstr "el cliente retornó una contraseña vacía" + +#: libpq/auth.c:887 libpq/hba.c:1366 +#, c-format +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "la autentificación MD5 no está soportada cuando «db_user_namespace» está activo" + +#: libpq/auth.c:893 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "no se pudo generar una sal MD5 aleatoria" + +#: libpq/auth.c:959 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "se esperaba una respuesta SASL, se obtuvo mensaje de tipo %d" + +#: libpq/auth.c:1088 libpq/be-secure-gssapi.c:535 +#, fuzzy, c-format +#| msgid "could not send data to client: %m" +msgid "could not set environment: %m" +msgstr "no se pudo enviar datos al cliente: %m" + +#: libpq/auth.c:1124 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "se esperaba una respuesta GSS, se obtuvo mensaje de tipo %d" + +#: libpq/auth.c:1184 +msgid "accepting GSS security context failed" +msgstr "falló la aceptación del contexto de seguridad GSS" + +#: libpq/auth.c:1224 +msgid "retrieving GSS user name failed" +msgstr "falló la obtención del nombre de usuario GSS" + +#: libpq/auth.c:1365 +msgid "could not acquire SSPI credentials" +msgstr "no se pudo obtener las credenciales SSPI" + +#: libpq/auth.c:1390 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "se esperaba una respuesta SSPI, se obtuvo mensaje de tipo %d" + +#: libpq/auth.c:1468 +msgid "could not accept SSPI security context" +msgstr "no se pudo aceptar un contexto SSPI" + +#: libpq/auth.c:1530 +msgid "could not get token from SSPI security context" +msgstr "no se pudo obtener un testigo (token) desde el contexto de seguridad SSPI" + +#: libpq/auth.c:1669 libpq/auth.c:1688 +#, c-format +msgid "could not translate name" +msgstr "no se pudo traducir el nombre" + +#: libpq/auth.c:1701 +#, c-format +msgid "realm name too long" +msgstr "nombre de «realm» demasiado largo" + +#: libpq/auth.c:1716 +#, c-format +msgid "translated account name too long" +msgstr "nombre de cuenta traducido demasiado largo" + +#: libpq/auth.c:1897 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "no se pudo crear un socket para conexión Ident: %m" + +#: libpq/auth.c:1912 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "no se pudo enlazar a la dirección local «%s»: %m" + +#: libpq/auth.c:1924 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "no se pudo conectar al servidor Ident en dirección «%s», port %s: %m" + +#: libpq/auth.c:1946 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "no se pudo enviar consulta Ident al servidor «%s», port %s: %m" + +#: libpq/auth.c:1963 +#, c-format +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "no se pudo recibir respuesta Ident desde el servidor «%s», port %s: %m" + +#: libpq/auth.c:1973 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "respuesta del servidor Ident en formato no válido: «%s»" + +#: libpq/auth.c:2026 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "método de autentificación peer no está soportado en esta plataforma" + +#: libpq/auth.c:2030 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "no se pudo recibir credenciales: %m" + +#: libpq/auth.c:2042 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "no se pudo encontrar el ID del usuario local %ld: %s" + +#: libpq/auth.c:2143 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "se ha recibido un error de la biblioteca PAM: %s" + +#: libpq/auth.c:2154 +#, fuzzy, c-format +#| msgid "unsupported format code: %d" +msgid "unsupported PAM conversation %d/\"%s\"" +msgstr "código de formato no soportado: %d" + +#: libpq/auth.c:2214 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "no se pudo crear autenticador PAM: %s" + +#: libpq/auth.c:2225 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER) falló: %s" + +#: libpq/auth.c:2257 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST) falló: %s" + +#: libpq/auth.c:2269 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "pam_set_item(PAM_CONV) falló: %s" + +#: libpq/auth.c:2282 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "pam_authenticate falló: %s" + +#: libpq/auth.c:2295 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmt falló: %s" + +#: libpq/auth.c:2306 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "no se pudo liberar autenticador PAM: %s" + +#: libpq/auth.c:2386 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "no se pudo inicializar LDAP: código de error %d" + +#: libpq/auth.c:2423 +#, c-format +msgid "could not extract domain name from ldapbasedn" +msgstr "no se pudo extraer el nombre de dominio de ldapbasedn" + +#: libpq/auth.c:2431 +#, c-format +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "la autentificación LDAP no pudo encontrar registros DNS SRV para «%s»" + +#: libpq/auth.c:2433 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "Defina un nombre de servidor LDAP explícitamente." + +#: libpq/auth.c:2485 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "no se pudo inicializar LDAP: %s" + +#: libpq/auth.c:2495 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ldaps no está soportado con esta biblioteca LDAP" + +#: libpq/auth.c:2503 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "no se pudo inicializar LDAP: %m" + +#: libpq/auth.c:2513 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "no se pudo definir la versión de protocolo LDAP: %s" + +#: libpq/auth.c:2553 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "no se pudo cargar la función _ldap_start_tls_sA en wldap32.dll" + +#: libpq/auth.c:2554 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "LDAP sobre SSL no está soportado en esta plataforma." + +#: libpq/auth.c:2570 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "no se pudo iniciar sesión de LDAP TLS: %s" + +#: libpq/auth.c:2641 +#, c-format +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "servidor LDAP no especificado, y no hay ldapbasedn" + +#: libpq/auth.c:2648 +#, c-format +msgid "LDAP server not specified" +msgstr "servidor LDAP no especificado" + +#: libpq/auth.c:2710 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "carácter no válido en nombre de usuario para autentificación LDAP" + +#: libpq/auth.c:2727 +#, c-format +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "no se pudo hacer el enlace LDAP inicial para el ldapbinddb «%s» en el servidor «%s»: %s" + +#: libpq/auth.c:2756 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "no se pudo hacer la búsqueda LDAP para el filtro «%s» en el servidor «%s»: %s" + +#: libpq/auth.c:2770 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "no existe el usuario LDAP «%s»" + +#: libpq/auth.c:2771 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "La búsqueda LDAP para el filtro «%s» en el servidor «%s» no retornó elementos." + +#: libpq/auth.c:2775 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "el usuario LDAP «%s» no es única" + +#: libpq/auth.c:2776 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "La búsqueda LDAP para el filtro «%s» en el servidor «%s» retornó %d elemento." +msgstr[1] "La búsqueda LDAP para el filtro «%s» en el servidor «%s» retornó %d elementos." + +#: libpq/auth.c:2796 +#, c-format +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "no se pudo obtener el dn para la primera entrada que coincide con «%s» en el servidor «%s»: %s" + +#: libpq/auth.c:2817 +#, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "no se pudo desconectar (unbind) después de buscar al usuario «%s» en el servidor «%s»" + +#: libpq/auth.c:2848 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "falló el inicio de sesión LDAP para el usuario «%s» en el servidor «%s»: %s" + +#: libpq/auth.c:2880 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "Diagnóstico LDAP: %s" + +#: libpq/auth.c:2918 +#, c-format +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "la autentificación con certificado falló para el usuario «%s»: el certificado de cliente no contiene un nombre de usuario" + +#: libpq/auth.c:2939 +#, fuzzy, c-format +#| msgid "certificate authentication failed for user \"%s\"" +msgid "certificate authentication failed for user \"%s\": unable to retrieve subject DN" +msgstr "la autentificación por certificado falló para el usuario «%s»" + +#: libpq/auth.c:2962 +#, fuzzy, c-format +#| msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch" +msgstr "la validación de certificado (clientcert=verify-full) falló para el usuario «%s»: discordancia de CN" + +#: libpq/auth.c:2967 +#, c-format +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" +msgstr "la validación de certificado (clientcert=verify-full) falló para el usuario «%s»: discordancia de CN" + +#: libpq/auth.c:3069 +#, c-format +msgid "RADIUS server not specified" +msgstr "servidor RADIUS no especificado" + +#: libpq/auth.c:3076 +#, c-format +msgid "RADIUS secret not specified" +msgstr "secreto RADIUS no especificado" + +#: libpq/auth.c:3090 +#, c-format +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "la autentificación RADIUS no soporta contraseñas más largas de %d caracteres" + +#: libpq/auth.c:3197 libpq/hba.c:2004 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "no se pudo traducir el nombre de servidor RADIUS «%s» a dirección: %s" + +#: libpq/auth.c:3211 +#, c-format +msgid "could not generate random encryption vector" +msgstr "no se pudo generar un vector aleatorio de encriptación" + +#: libpq/auth.c:3245 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "no se pudo efectuar cifrado MD5 de la contraseña" + +#: libpq/auth.c:3271 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "no se pudo crear el socket RADIUS: %m" + +#: libpq/auth.c:3293 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "no se pudo enlazar el socket RADIUS local: %m" + +#: libpq/auth.c:3303 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "no se pudo enviar el paquete RADIUS: %m" + +#: libpq/auth.c:3336 libpq/auth.c:3362 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "se agotó el tiempo de espera de la respuesta RADIUS desde %s" + +#: libpq/auth.c:3355 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "no se pudo verificar el estado en el socket %m" + +#: libpq/auth.c:3385 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "no se pudo leer la respuesta RADIUS: %m" + +#: libpq/auth.c:3398 libpq/auth.c:3402 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "la respuesta RADIUS desde %s fue enviada desde el port incorrecto: %d" + +#: libpq/auth.c:3411 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "la respuesta RADIUS desde %s es demasiado corta: %d" + +#: libpq/auth.c:3418 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "la respuesta RADIUS desde %ss tiene largo corrupto: %d (largo real %d)" + +#: libpq/auth.c:3426 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "la respuesta RADIUS desde %s es a una petición diferente: %d (debería ser %d)" + +#: libpq/auth.c:3451 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "no se pudo realizar cifrado MD5 del paquete recibido" + +#: libpq/auth.c:3460 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "la respuesta RADIUS desde %s tiene firma MD5 incorrecta" + +#: libpq/auth.c:3478 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "la respuesta RADIUS desde %s tiene código no válido (%d) para el usuario «%s»" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:553 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "el descriptor de objeto grande no es válido: %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "el descriptor de objeto grande %d no fue abierto para lectura" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:560 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "el descriptor de objeto grande %d no fue abierto para escritura" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "resultado de lo_lseek fuera de rango para el descriptor de objeto grande %d" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "resultado de lo_tell fuera de rango para el descriptor de objeto grande %d" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "no se pudo abrir el archivo de servidor «%s»: %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "no se pudo leer el archivo de servidor «%s»: %m" + +#: libpq/be-fsstubs.c:514 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "no se pudo crear el archivo del servidor «%s»: %m" + +#: libpq/be-fsstubs.c:526 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "no se pudo escribir el archivo del servidor «%s»: %m" + +#: libpq/be-fsstubs.c:760 +#, c-format +msgid "large object read request is too large" +msgstr "el tamaño de petición de lectura de objeto grande es muy grande" + +#: libpq/be-fsstubs.c:802 utils/adt/genfile.c:267 utils/adt/genfile.c:306 +#: utils/adt/genfile.c:342 +#, c-format +msgid "requested length cannot be negative" +msgstr "el tamaño solicitado no puede ser negativo" + +#: libpq/be-fsstubs.c:855 storage/large_object/inv_api.c:297 +#: storage/large_object/inv_api.c:309 storage/large_object/inv_api.c:513 +#: storage/large_object/inv_api.c:624 storage/large_object/inv_api.c:814 +#, c-format +msgid "permission denied for large object %u" +msgstr "permiso denegado al objeto grande %u" + +#: libpq/be-secure-common.c:93 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "no se pudo leer desde la orden «%s»: %m" + +#: libpq/be-secure-common.c:113 +#, c-format +msgid "command \"%s\" failed" +msgstr "la orden «%s» falló" + +#: libpq/be-secure-common.c:141 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "no se pudo acceder al archivo de la llave privada «%s»: %m" + +#: libpq/be-secure-common.c:150 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "el archivo de llave privada «%s» no es un archivo regular" + +#: libpq/be-secure-common.c:165 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "el archivo de llave privada «%s» debe ser de propiedad del usuario de base de datos o root" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "el archivo de la llave privada «%s» tiene acceso para el grupo u otros" + +#: libpq/be-secure-common.c:190 +#, c-format +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "El archivo debe tener permisos u=rw (0600) o menos si es de propiedad del usuario de base deatos, o permisos u=rw,g=r (0640) o menos si es de root." + +#: libpq/be-secure-gssapi.c:204 +msgid "GSSAPI wrap error" +msgstr "error de «wrap» de GSSAPI" + +#: libpq/be-secure-gssapi.c:211 +#, c-format +msgid "outgoing GSSAPI message would not use confidentiality" +msgstr "mensaje saliente GSSAPI no proveería confidencialidad" + +#: libpq/be-secure-gssapi.c:218 libpq/be-secure-gssapi.c:622 +#, c-format +msgid "server tried to send oversize GSSAPI packet (%zu > %zu)" +msgstr "el servidor intentó enviar un paquete GSSAPI demasiado grande (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:351 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "paquete GSSAPI demasiado grande enviado por el cliente (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:389 +msgid "GSSAPI unwrap error" +msgstr "error de «unwrap» de GSSAPI" + +#: libpq/be-secure-gssapi.c:396 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "mensaje GSSAPI entrante no usó confidencialidad" + +#: libpq/be-secure-gssapi.c:570 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "paquete GSSAPI demasiado grande enviado por el cliente (%zu > %d)" + +#: libpq/be-secure-gssapi.c:594 +msgid "could not accept GSSAPI security context" +msgstr "no se pudo aceptar un contexto de seguridad GSSAPI" + +#: libpq/be-secure-gssapi.c:689 +msgid "GSSAPI size check error" +msgstr "error de verificación de tamaño GSSAPI" + +#: libpq/be-secure-openssl.c:115 +#, c-format +msgid "could not create SSL context: %s" +msgstr "no se pudo crear un contexto SSL: %s" + +#: libpq/be-secure-openssl.c:141 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "no se pudo cargar el archivo de certificado de servidor «%s»: %s" + +#: libpq/be-secure-openssl.c:161 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "el archivo de clave privada \"%s\" no se puede volver a cargar porque requiere una contraseña" + +#: libpq/be-secure-openssl.c:166 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "no se pudo cargar el archivo de la llave privada «%s»: %s" + +#: libpq/be-secure-openssl.c:175 +#, c-format +msgid "check of private key failed: %s" +msgstr "falló la revisión de la llave privada: %s" + +#. translator: first %s is a GUC option name, second %s is its value +#: libpq/be-secure-openssl.c:188 libpq/be-secure-openssl.c:211 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "el valor «%2$s» para la opción «%1$s» no está soportado en este servidor" + +#: libpq/be-secure-openssl.c:198 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "no se pudo definir la versión mínima de protocolo SSL" + +#: libpq/be-secure-openssl.c:221 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "no se pudo definir la versión máxima de protocolo SSL" + +#: libpq/be-secure-openssl.c:237 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "no se pudo definir el rango de versión de protocolo SSL" + +#: libpq/be-secure-openssl.c:238 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "«%s» no puede ser más alto que «%s»" + +#: libpq/be-secure-openssl.c:275 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "no se pudo establecer la lista de cifrado (no hay cifradores disponibles)" + +#: libpq/be-secure-openssl.c:295 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "no se pudo cargar el archivo del certificado raíz «%s»: %s" + +#: libpq/be-secure-openssl.c:344 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "no se pudo cargar el archivo de lista de revocación de certificados SSL «%s»: %s" + +#: libpq/be-secure-openssl.c:352 +#, fuzzy, c-format +#| msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgid "could not load SSL certificate revocation list directory \"%s\": %s" +msgstr "no se pudo cargar el archivo de lista de revocación de certificados SSL «%s»: %s" + +#: libpq/be-secure-openssl.c:360 +#, fuzzy, c-format +#| msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgid "could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s" +msgstr "no se pudo cargar el archivo de lista de revocación de certificados SSL «%s»: %s" + +#: libpq/be-secure-openssl.c:418 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "no se pudo inicializar la conexión SSL: el contexto SSL no está instalado" + +#: libpq/be-secure-openssl.c:429 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "no se pudo inicializar la conexión SSL: %s" + +#: libpq/be-secure-openssl.c:437 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "no se definir un socket SSL: %s" + +#: libpq/be-secure-openssl.c:492 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "no se pudo aceptar una conexión SSL: %m" + +#: libpq/be-secure-openssl.c:496 libpq/be-secure-openssl.c:549 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "no se pudo aceptar una conexión SSL: se detectó EOF" + +#: libpq/be-secure-openssl.c:535 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "no se pudo aceptar una conexión SSL: %s" + +#: libpq/be-secure-openssl.c:538 +#, c-format +msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." +msgstr "Esto puede indicar que el cliente no soporta ninguna versión del protocolo SSL entre %s and %s." + +#: libpq/be-secure-openssl.c:554 libpq/be-secure-openssl.c:734 +#: libpq/be-secure-openssl.c:798 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "código de error SSL no reconocido: %d" + +#: libpq/be-secure-openssl.c:600 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "el «common name» del certificado SSL contiene un carácter null" + +#: libpq/be-secure-openssl.c:640 +#, fuzzy, c-format +#| msgid "SSL certificate's name contains embedded null\n" +msgid "SSL certificate's distinguished name contains embedded null" +msgstr "el elemento de nombre en el certificado SSL contiene un carácter null\n" + +#: libpq/be-secure-openssl.c:723 libpq/be-secure-openssl.c:782 +#, c-format +msgid "SSL error: %s" +msgstr "error de SSL: %s" + +#: libpq/be-secure-openssl.c:963 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "no se pudo abrir el archivo de parámetros DH «%s»: %m" + +#: libpq/be-secure-openssl.c:975 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "no se pudo cargar el archivo de parámetros DH: %s" + +#: libpq/be-secure-openssl.c:985 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "parámetros DH no válidos: %s" + +#: libpq/be-secure-openssl.c:994 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "parámetros DH no válidos: p no es primo" + +#: libpq/be-secure-openssl.c:1003 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "parámetros DH no válidos: no hay generador apropiado o primo seguro" + +#: libpq/be-secure-openssl.c:1164 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: no se pudo cargar los parámetros DH" + +#: libpq/be-secure-openssl.c:1172 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: no se pudo definir los parámetros DH: %s" + +#: libpq/be-secure-openssl.c:1199 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: nombre de curva no reconocida: %s" + +#: libpq/be-secure-openssl.c:1208 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: no se pudo crear la llave" + +#: libpq/be-secure-openssl.c:1236 +msgid "no SSL error reported" +msgstr "código de error SSL no reportado" + +#: libpq/be-secure-openssl.c:1240 +#, c-format +msgid "SSL error code %lu" +msgstr "código de error SSL %lu" + +#: libpq/be-secure-openssl.c:1394 +#, c-format +msgid "failed to create BIO" +msgstr "" + +#: libpq/be-secure-openssl.c:1404 +#, c-format +msgid "could not get NID for ASN1_OBJECT object" +msgstr "" + +#: libpq/be-secure-openssl.c:1412 +#, fuzzy, c-format +#| msgid "could not create LDAP structure\n" +msgid "could not convert NID %d to an ASN1_OBJECT structure" +msgstr "no se pudo crear estructura LDAP\n" + +#: libpq/be-secure.c:209 libpq/be-secure.c:305 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "terminando la conexión debido al término inesperado de postmaster" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "No existe el rol «%s»." + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "El usuario «%s» no tiene una contraseña asignada." + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "El usuario «%s» tiene contraseña expirada." + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "El usuario \"%s\" tiene una contraseña que no se puede usar con la autentificación MD5." + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "La contraseña no coincide para el usuario «%s»." + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "La contraseña del usuario \"%s\" está en un formato no reconocido." + +#: libpq/hba.c:241 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "una palabra en el archivo de autentificación es demasiado larga, omitiendo: «%s»" + +#: libpq/hba.c:413 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "no se pudo abrir el archivo secundario de autentificación «@%s» como «%s»: %m" + +#: libpq/hba.c:859 +#, fuzzy, c-format +#| msgid "error during file seek: %m" +msgid "error enumerating network interfaces: %m" +msgstr "error durante el posicionamiento (seek) en el archivo: %m" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:886 +#, c-format +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "la opción de autentificación «%s» sólo es válida para los métodos de autentificación %s" + +#: libpq/hba.c:888 libpq/hba.c:908 libpq/hba.c:946 libpq/hba.c:996 +#: libpq/hba.c:1010 libpq/hba.c:1034 libpq/hba.c:1043 libpq/hba.c:1056 +#: libpq/hba.c:1077 libpq/hba.c:1090 libpq/hba.c:1110 libpq/hba.c:1132 +#: libpq/hba.c:1144 libpq/hba.c:1203 libpq/hba.c:1223 libpq/hba.c:1237 +#: libpq/hba.c:1257 libpq/hba.c:1268 libpq/hba.c:1283 libpq/hba.c:1302 +#: libpq/hba.c:1318 libpq/hba.c:1330 libpq/hba.c:1367 libpq/hba.c:1408 +#: libpq/hba.c:1421 libpq/hba.c:1443 libpq/hba.c:1455 libpq/hba.c:1473 +#: libpq/hba.c:1523 libpq/hba.c:1567 libpq/hba.c:1578 libpq/hba.c:1594 +#: libpq/hba.c:1611 libpq/hba.c:1622 libpq/hba.c:1641 libpq/hba.c:1657 +#: libpq/hba.c:1673 libpq/hba.c:1727 libpq/hba.c:1744 libpq/hba.c:1757 +#: libpq/hba.c:1769 libpq/hba.c:1788 libpq/hba.c:1875 libpq/hba.c:1893 +#: libpq/hba.c:1987 libpq/hba.c:2006 libpq/hba.c:2035 libpq/hba.c:2048 +#: libpq/hba.c:2071 libpq/hba.c:2093 libpq/hba.c:2107 tsearch/ts_locale.c:232 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "línea %d del archivo de configuración «%s»" + +#: libpq/hba.c:906 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "el método de autentificación «%s» requiere que el argumento «%s» esté definido" + +#: libpq/hba.c:934 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "falta una entrada en el archivo «%s» al final de la línea %d" + +#: libpq/hba.c:945 +#, c-format +msgid "multiple values in ident field" +msgstr "múltiples valores en campo «ident»" + +#: libpq/hba.c:994 +#, c-format +msgid "multiple values specified for connection type" +msgstr "múltiples valores especificados para tipo de conexión" + +#: libpq/hba.c:995 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "Especifique exactamente un tipo de conexión por línea." + +#: libpq/hba.c:1009 +#, c-format +msgid "local connections are not supported by this build" +msgstr "las conexiones locales no están soportadas en este servidor" + +#: libpq/hba.c:1032 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "el registro hostssl no puede coincidir porque SSL está deshabilitado" + +#: libpq/hba.c:1033 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "Defina «ssl = on» en postgresql.conf." + +#: libpq/hba.c:1041 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "el registro hostssl no puede coincidir porque SSL no está soportado en esta instalación" + +#: libpq/hba.c:1042 +#, fuzzy, c-format +#| msgid "Compile with --with-openssl to use SSL connections." +msgid "Compile with --with-ssl to use SSL connections." +msgstr "Compile con --with-openssl para usar conexiones SSL." + +#: libpq/hba.c:1054 +#, c-format +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "el registro hostgssenc no puede coincidir porque GSSAPI no está soportado en esta instalación" + +#: libpq/hba.c:1055 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "Compile con --with-gssapi para usar conexiones GSSAPI." + +#: libpq/hba.c:1075 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "tipo de conexión «%s» no válido" + +#: libpq/hba.c:1089 +#, c-format +msgid "end-of-line before database specification" +msgstr "fin de línea antes de especificación de base de datos" + +#: libpq/hba.c:1109 +#, c-format +msgid "end-of-line before role specification" +msgstr "fin de línea antes de especificación de rol" + +#: libpq/hba.c:1131 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "fin de línea antes de especificación de dirección IP" + +#: libpq/hba.c:1142 +#, c-format +msgid "multiple values specified for host address" +msgstr "múltiples valores especificados para la dirección de anfitrión" + +#: libpq/hba.c:1143 +#, c-format +msgid "Specify one address range per line." +msgstr "Especifique un rango de direcciones por línea." + +#: libpq/hba.c:1201 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "dirección IP «%s» no válida: %s" + +#: libpq/hba.c:1221 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "especificar tanto el nombre de host como la máscara CIDR no es válido: «%s»" + +#: libpq/hba.c:1235 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "máscara CIDR no válida en dirección «%s»" + +#: libpq/hba.c:1255 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "fin de línea antes de especificación de máscara de red" + +#: libpq/hba.c:1256 +#, c-format +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "Especifique un rango de direcciones en notación CIDR, o provea una netmask separadamente." + +#: libpq/hba.c:1267 +#, c-format +msgid "multiple values specified for netmask" +msgstr "múltiples valores especificados para la máscara de red" + +#: libpq/hba.c:1281 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "máscara IP «%s» no válida: %s" + +#: libpq/hba.c:1301 +#, c-format +msgid "IP address and mask do not match" +msgstr "La dirección y máscara IP no coinciden" + +#: libpq/hba.c:1317 +#, c-format +msgid "end-of-line before authentication method" +msgstr "fin de línea antes de especificación de método de autentificación" + +#: libpq/hba.c:1328 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "múltiples valores especificados para el tipo de autentificación" + +#: libpq/hba.c:1329 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "Especifique exactamente un tipo de autentificación por línea." + +#: libpq/hba.c:1406 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "método de autentificación «%s» no válido" + +#: libpq/hba.c:1419 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "método de autentificación «%s» no válido: este servidor no lo soporta" + +#: libpq/hba.c:1442 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "la autentificación gssapi no está soportada en conexiones locales" + +#: libpq/hba.c:1454 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "la autentificación peer sólo está soportada en conexiones locales" + +#: libpq/hba.c:1472 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "la autentificación cert sólo está soportada en conexiones hostssl" + +#: libpq/hba.c:1522 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "opción de autentificación en formato nombre=valor: %s" + +#: libpq/hba.c:1566 +#, c-format +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "no se puede usar ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter o ldapurl junto con ldapprefix" + +#: libpq/hba.c:1577 +#, c-format +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "el método de autentificación «ldap» requiere que los argumento «ldapbasedn», «ldapprefix» o «ldapsuffix» estén definidos" + +#: libpq/hba.c:1593 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "no se puede usar ldapsearchattribute junto con ldapsearchfilter" + +#: libpq/hba.c:1610 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "la lista de servidores RADIUS no puede ser vacía" + +#: libpq/hba.c:1621 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "la lista de secretos RADIUS no puede ser vacía" + +#: libpq/hba.c:1638 +#, fuzzy, c-format +#| msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgid "the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "el número de %s (%d) debe ser 1 o igual al número de %s (%d)" + +#: libpq/hba.c:1654 +#, fuzzy, c-format +#| msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgid "the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "el número de %s (%d) debe ser 1 o igual al número de %s (%d)" + +#: libpq/hba.c:1670 +#, fuzzy, c-format +#| msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgid "the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "el número de %s (%d) debe ser 1 o igual al número de %s (%d)" + +#: libpq/hba.c:1717 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi y cert" + +#: libpq/hba.c:1726 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert sólo puede ser configurado en líneas «hostssl»" + +#: libpq/hba.c:1743 +#, fuzzy, c-format +#| msgid "clientcert can not be set to \"no-verify\" when using \"cert\" authentication" +msgid "clientcert only accepts \"verify-full\" when using \"cert\" authentication" +msgstr "clientcert no puede establecerse a «no-verify» cuando se emplea autentificación «cert»" + +#: libpq/hba.c:1756 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "valor no válido para el parámetro clientcert: «%s»" + +#: libpq/hba.c:1768 +#, fuzzy, c-format +#| msgid "clientcert can only be configured for \"hostssl\" rows" +msgid "clientname can only be configured for \"hostssl\" rows" +msgstr "clientcert sólo puede ser configurado en líneas «hostssl»" + +#: libpq/hba.c:1787 +#, fuzzy, c-format +#| msgid "invalid value for clientcert: \"%s\"" +msgid "invalid value for clientname: \"%s\"" +msgstr "valor no válido para el parámetro clientcert: «%s»" + +#: libpq/hba.c:1821 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "no se pudo interpretar la URL LDAP «%s»: %s" + +#: libpq/hba.c:1832 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "esquema de URL LDAP no soportado: %s" + +#: libpq/hba.c:1856 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "las URLs LDAP no está soportado en esta plataforma" + +#: libpq/hba.c:1874 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "valor ldapscheme no válido: «%s»" + +#: libpq/hba.c:1892 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "número de puerto LDAP no válido: «%s»" + +#: libpq/hba.c:1938 libpq/hba.c:1945 +msgid "gssapi and sspi" +msgstr "gssapi y sspi" + +#: libpq/hba.c:1954 libpq/hba.c:1963 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1985 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "no se pudo interpretar la lista de servidores RADIUS «%s»" + +#: libpq/hba.c:2033 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "no se pudo interpretar la lista de port RADIUS «%s»" + +#: libpq/hba.c:2047 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "número de puerto RADIUS no válido: «%s»" + +#: libpq/hba.c:2069 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "no se pudo interpretar la lista de secretos RADIUS «%s»" + +#: libpq/hba.c:2091 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "no se pudo interpretar la lista de identificadoes RADIUS «%s»" + +#: libpq/hba.c:2105 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "nombre de opción de autentificación desconocido: «%s»" + +#: libpq/hba.c:2302 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "el archivo de configuración «%s» no contiene líneas" + +#: libpq/hba.c:2820 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "la expresión regular «%s» no es válida: %s" + +#: libpq/hba.c:2880 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "la coincidencia de expresión regular para «%s» falló: %s" + +#: libpq/hba.c:2899 +#, c-format +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "la expresión regular «%s» no tiene subexpresiones según lo requiere la referencia hacia atrás en «%s»" + +#: libpq/hba.c:2995 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "el nombre de usuario entregado (%s) y el nombre de usuario autentificado (%s) no coinciden" + +#: libpq/hba.c:3015 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "no hay coincidencia en el mapa «%s» para el usuario «%s» autentificado como «%s»" + +#: libpq/hba.c:3048 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "no se pudo abrir el archivo de mapa de usuarios «%s»: %m" + +#: libpq/pqcomm.c:204 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "no se pudo establecer el socket en modo no bloqueante: %m" + +#: libpq/pqcomm.c:362 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "la ruta al socket de dominio Unix «%s» es demasiado larga (máximo %d bytes)" + +#: libpq/pqcomm.c:383 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "no se pudo traducir el nombre de host «%s», servicio «%s» a dirección: %s" + +#: libpq/pqcomm.c:387 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "no se pudo traducir el servicio «%s» a dirección: %s" + +#: libpq/pqcomm.c:414 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "no se pudo enlazar a todas las direcciones pedidas: MAXLISTEN (%d) fue excedido" + +#: libpq/pqcomm.c:423 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:427 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:432 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:437 +#, c-format +msgid "unrecognized address family %d" +msgstr "la familia de direcciones %d no reconocida" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:463 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "no se pudo crear el socket %s de escucha para la dirección «%s»: %m" + +#. translator: third %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:489 libpq/pqcomm.c:507 +#, fuzzy, c-format +#| msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgid "%s(%s) failed for %s address \"%s\": %m" +msgstr "setsockopt(IPV6_V6ONLY) falló para la dirección %s «%s»: %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:530 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "no se pudo enlazar a la dirección %s «%s»: %m" + +#: libpq/pqcomm.c:534 +#, fuzzy, c-format +#| msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgid "Is another postmaster already running on port %d?" +msgstr "¿Hay otro postmaster corriendo en el puerto %d? Si no, aguarde unos segundos y reintente." + +#: libpq/pqcomm.c:536 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "¿Hay otro postmaster corriendo en el puerto %d? Si no, aguarde unos segundos y reintente." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:569 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "no se pudo escuchar en la dirección %s «%s»: %m" + +#: libpq/pqcomm.c:578 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "escuchando en el socket Unix «%s»" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:584 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "escuchando en la dirección %s «%s», port %d" + +#: libpq/pqcomm.c:675 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "no existe el grupo «%s»" + +#: libpq/pqcomm.c:685 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "no se pudo definir el grupo del archivo «%s»: %m" + +#: libpq/pqcomm.c:696 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "no se pudo definir los permisos del archivo «%s»: %m" + +#: libpq/pqcomm.c:726 +#, c-format +msgid "could not accept new connection: %m" +msgstr "no se pudo aceptar una nueva conexión: %m" + +#: libpq/pqcomm.c:766 libpq/pqcomm.c:775 libpq/pqcomm.c:807 libpq/pqcomm.c:817 +#: libpq/pqcomm.c:1630 libpq/pqcomm.c:1675 libpq/pqcomm.c:1715 +#: libpq/pqcomm.c:1759 libpq/pqcomm.c:1798 libpq/pqcomm.c:1837 +#: libpq/pqcomm.c:1873 libpq/pqcomm.c:1912 postmaster/pgstat.c:618 +#: postmaster/pgstat.c:629 +#, fuzzy, c-format +#| msgid "%s failed: %m" +msgid "%s(%s) failed: %m" +msgstr "%s falló: %m" + +#: libpq/pqcomm.c:921 +#, c-format +msgid "there is no client connection" +msgstr "no hay conexión de cliente" + +#: libpq/pqcomm.c:972 libpq/pqcomm.c:1068 +#, c-format +msgid "could not receive data from client: %m" +msgstr "no se pudo recibir datos del cliente: %m" + +#: libpq/pqcomm.c:1161 tcop/postgres.c:4290 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "terminando la conexión por pérdida de sincronía del protocolo" + +#: libpq/pqcomm.c:1227 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "EOF inesperado dentro de la palabra de tamaño del mensaje" + +#: libpq/pqcomm.c:1237 +#, c-format +msgid "invalid message length" +msgstr "el largo de mensaje no es válido" + +#: libpq/pqcomm.c:1259 libpq/pqcomm.c:1272 +#, c-format +msgid "incomplete message from client" +msgstr "mensaje incompleto del cliente" + +#: libpq/pqcomm.c:1383 +#, c-format +msgid "could not send data to client: %m" +msgstr "no se pudo enviar datos al cliente: %m" + +#: libpq/pqcomm.c:1598 +#, fuzzy, c-format +#| msgid "pgpipe: getsockname() failed: error code %d" +msgid "%s(%s) failed: error code %d" +msgstr "pgpipe: getsockname() falló: código de error %d" + +#: libpq/pqcomm.c:1687 +#, fuzzy, c-format +#| msgid "using recovery command file \"%s\" is not supported" +msgid "setting the keepalive idle time is not supported" +msgstr "el uso del archivo de configuración de recuperación «%s» no está soportado" + +#: libpq/pqcomm.c:1771 libpq/pqcomm.c:1846 libpq/pqcomm.c:1921 +#, fuzzy, c-format +#| msgid "log format \"%s\" is not supported" +msgid "%s(%s) not supported" +msgstr "el formato de log «%s» no está soportado" + +#: libpq/pqcomm.c:1956 +#, fuzzy, c-format +#| msgid "could not set SSL socket: %s" +msgid "could not poll socket: %m" +msgstr "no se definir un socket SSL: %s" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "no hay datos restantes en el mensaje" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1481 utils/adt/rowtypes.c:588 +#, c-format +msgid "insufficient data left in message" +msgstr "los datos restantes del mensaje son insuficientes" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "cadena inválida en el mensaje" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "formato de mensaje no válido" + +#: main/main.c:245 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: WSAStartup falló: %d\n" + +#: main/main.c:309 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%s es el servidor PostgreSQL.\n" +"\n" + +#: main/main.c:310 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Empleo:\n" +" %s [OPCION]...\n" +"\n" + +#: main/main.c:311 +#, c-format +msgid "Options:\n" +msgstr "Opciones:\n" + +#: main/main.c:312 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS número de búfers de memoria compartida\n" + +#: main/main.c:313 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c VAR=VALOR definir parámetro de ejecución\n" + +#: main/main.c:314 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NOMBRE imprimir valor de parámetro de configuración, luego salir\n" + +#: main/main.c:315 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 nivel de depuración\n" + +#: main/main.c:316 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D DATADIR directorio de bases de datos\n" + +#: main/main.c:317 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e usar estilo europeo de fechas (DMY)\n" + +#: main/main.c:318 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F desactivar fsync\n" + +#: main/main.c:319 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h NOMBRE nombre de host o dirección IP en que escuchar\n" + +#: main/main.c:320 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i activar conexiones TCP/IP\n" + +#: main/main.c:321 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k DIRECTORIO ubicación del socket Unix\n" + +#: main/main.c:323 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l activar conexiones SSL\n" + +#: main/main.c:325 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-CONN número máximo de conexiones permitidas\n" + +#: main/main.c:326 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PUERTO número de puerto en el cual escuchar\n" + +#: main/main.c:327 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s mostrar estadísticas después de cada consulta\n" + +#: main/main.c:328 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM definir cantidad de memoria para ordenamientos (en kB)\n" + +#: main/main.c:329 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de la versión, luego salir\n" + +#: main/main.c:330 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NOMBRE=VALOR definir parámetro de ejecución\n" + +#: main/main.c:331 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr "" +" --describe-config\n" +" mostrar parámetros de configuración y salir\n" + +#: main/main.c:332 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help muestra esta ayuda, luego sale\n" + +#: main/main.c:334 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"Opciones de desarrollador:\n" + +#: main/main.c:335 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h impedir el uso de algunos tipos de planes\n" + +#: main/main.c:336 +#, c-format +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr " -n no reinicializar memoria compartida después de salida anormal\n" + +#: main/main.c:337 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O permitir cambios en estructura de tablas de sistema\n" + +#: main/main.c:338 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P desactivar índices de sistema\n" + +#: main/main.c:339 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex mostrar tiempos después de cada consulta\n" + +#: main/main.c:340 +#, c-format +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr "" +" -T enviar SIGSTOP a todos los procesos backend si uno de ellos\n" +" muere\n" + +#: main/main.c:341 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr " -W NÚM espera NÚM segundos para permitir acoplar un depurador\n" + +#: main/main.c:343 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"Opciones para modo mono-usuario:\n" + +#: main/main.c:344 +#, c-format +msgid " --single selects single-user mode (must be first argument)\n" +msgstr " --single selecciona modo mono-usuario (debe ser el primer argumento)\n" + +#: main/main.c:345 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAME nombre de base de datos (el valor por omisión es el nombre de usuario)\n" + +#: main/main.c:346 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 nivel de depuración\n" + +#: main/main.c:347 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E mostrar las consultas antes de su ejecución\n" + +#: main/main.c:348 +#, c-format +msgid " -j do not use newline as interactive query delimiter\n" +msgstr " -j no usar saltos de línea como delimitadores de consulta\n" + +#: main/main.c:349 main/main.c:354 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r ARCHIVO enviar salida estándar y de error a ARCHIVO\n" + +#: main/main.c:351 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"Opciones para modo de inicio (bootstrapping):\n" + +#: main/main.c:352 +#, c-format +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot selecciona modo de inicio (debe ser el primer argumento)\n" + +#: main/main.c:353 +#, c-format +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr " DBNAME nombre de base de datos (argumento obligatorio en modo de inicio)\n" + +#: main/main.c:355 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM uso interno\n" + +#: main/main.c:357 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Por favor lea la documentación para obtener la lista de parámetros de\n" +"configuración y cómo definirlos en la línea de órdenes o en el archivo\n" +"de configuración.\n" +"\n" +"Reporte errores a <%s>.\n" + +#: main/main.c:361 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: main/main.c:372 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"No se permite ejecución del servidor PostgreSQL como «root».\n" +"El servidor debe ser iniciado con un usuario no privilegiado\n" +"para prevenir posibles compromisos de seguridad del sistema.\n" +"Vea la documentación para obtener más información acerca de cómo\n" +"iniciar correctamente el servidor.\n" + +#: main/main.c:389 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: los IDs de usuario real y efectivo deben coincidir\n" + +#: main/main.c:396 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"No se permite ejecución del servidor PostgreSQL por un usuario con privilegios administrativos.\n" +"El servidor debe ser iniciado con un usuario no privilegiado\n" +"para prevenir posibles compromisos de seguridad del sistema.\n" +"Vea la documentación para obtener más información acerca de cómo\n" +"iniciar correctamente el servidor.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "el tipo de nodo extensible «%s» ya existe" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "ExtensibleNodeMethods «%s» no fue registrado" + +#: nodes/makefuncs.c:150 +#, fuzzy, c-format +#| msgid "\"%s\" is not a composite type" +msgid "relation \"%s\" does not have a composite type" +msgstr "«%s» no es un tipo compuesto" + +#: nodes/nodeFuncs.c:114 nodes/nodeFuncs.c:145 parser/parse_coerce.c:2472 +#: parser/parse_coerce.c:2584 parser/parse_coerce.c:2630 +#: parser/parse_expr.c:2021 parser/parse_func.c:710 parser/parse_oper.c:883 +#: utils/fmgr/funcapi.c:558 +#, c-format +msgid "could not find array type for data type %s" +msgstr "no se pudo encontrar un tipo de array para el tipo de dato %s" + +#: nodes/params.c:417 +#, fuzzy, c-format +#| msgid "extended query \"%s\" with parameters: %s" +msgid "portal \"%s\" with parameters: %s" +msgstr "consulta extendida «%s» con parámetros: %s" + +#: nodes/params.c:420 +#, fuzzy, c-format +#| msgid "extended query with parameters: %s" +msgid "unnamed portal with parameters: %s" +msgstr "consulta extendida con parámetros: %s" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN sólo está soportado con condiciones que se pueden usar con merge join o hash join" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1192 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s no puede ser aplicado al lado nulable de un outer join" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1315 parser/analyze.c:1677 parser/analyze.c:1921 +#: parser/analyze.c:3099 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s no está permitido con UNION/INTERSECT/EXCEPT" + +#: optimizer/plan/planner.c:1978 optimizer/plan/planner.c:3634 +#, c-format +msgid "could not implement GROUP BY" +msgstr "no se pudo implementar GROUP BY" + +#: optimizer/plan/planner.c:1979 optimizer/plan/planner.c:3635 +#: optimizer/plan/planner.c:4392 optimizer/prep/prepunion.c:1046 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "Algunos de los tipos sólo soportan hashing, mientras que otros sólo soportan ordenamiento." + +#: optimizer/plan/planner.c:4391 +#, c-format +msgid "could not implement DISTINCT" +msgstr "no se pudo implementar DISTINCT" + +#: optimizer/plan/planner.c:5239 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "No se pudo implementar PARTITION BY de ventana" + +#: optimizer/plan/planner.c:5240 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "Las columnas de particionamiento de ventana deben de tipos que se puedan ordenar." + +#: optimizer/plan/planner.c:5244 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "no se pudo implementar ORDER BY de ventana" + +#: optimizer/plan/planner.c:5245 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Las columnas de ordenamiento de ventana debe ser de tipos que se puedan ordenar." + +#: optimizer/plan/setrefs.c:479 +#, c-format +msgid "too many range table entries" +msgstr "demasiadas «range table entries»" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "could not implement recursive UNION" +msgstr "no se pudo implementar UNION recursivo" + +#: optimizer/prep/prepunion.c:510 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Todos los tipos de dato de las columnas deben ser tipos de los que se puedan hacer un hash." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1045 +#, c-format +msgid "could not implement %s" +msgstr "no se pudo implementar %s" + +#: optimizer/util/clauses.c:4721 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "función SQL «%s», durante expansión en línea" + +#: optimizer/util/plancat.c:132 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "no se puede acceder a tablas temporales o «unlogged» durante la recuperación" + +#: optimizer/util/plancat.c:672 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "no están soportadas las especificaciones de inferencia de índice único de registro completo" + +#: optimizer/util/plancat.c:689 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "la restricción en la cláusula ON CONFLICT no tiene un índice asociado" + +#: optimizer/util/plancat.c:739 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE no está soportado con restricciones de exclusión" + +#: optimizer/util/plancat.c:844 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "no hay restricción única o de exclusión que coincida con la especificación ON CONFLICT" + +#: parser/analyze.c:737 parser/analyze.c:1451 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "las listas VALUES deben ser todas de la misma longitud" + +#: parser/analyze.c:938 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT tiene más expresiones que columnas de destino" + +#: parser/analyze.c:956 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT tiene más columnas de destino que expresiones" + +#: parser/analyze.c:960 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "La fuente de inserción es una expresión de fila que contiene la misma cantidad de columnas que esperaba el INSERT. ¿Usó accidentalmente paréntesis extra?" + +#: parser/analyze.c:1259 parser/analyze.c:1650 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO no está permitido aquí" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1580 parser/analyze.c:3278 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s no puede ser aplicado a VALUES" + +#: parser/analyze.c:1816 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "cláusula UNION/INTERSECT/EXCEPT ORDER BY no válida" + +#: parser/analyze.c:1817 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "Sólo nombres de columna del resultado pueden usarse, no expresiones o funciones." + +#: parser/analyze.c:1818 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "Agregue la función o expresión a todos los SELECT, o mueva el UNION dentro de una cláusula FROM." + +#: parser/analyze.c:1911 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "sólo se permite INTO en el primer SELECT de UNION/INTERSECT/EXCEPT" + +#: parser/analyze.c:1983 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "una sentencia miembro de UNION/INSERT/EXCEPT no puede referirse a otras relaciones del mismo nivel de la consulta" + +#: parser/analyze.c:2070 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "cada consulta %s debe tener el mismo número de columnas" + +#: parser/analyze.c:2470 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNING debe tener al menos una columna" + +#: parser/analyze.c:2573 +#, fuzzy, c-format +#| msgid "query \"%s\" returned %d column" +#| msgid_plural "query \"%s\" returned %d columns" +msgid "assignment source returned %d column" +msgid_plural "assignment source returned %d columns" +msgstr[0] "la consulta «%s» retornó %d columna" +msgstr[1] "la consulta «%s» retornó %d columnas" + +#: parser/analyze.c:2634 +#, fuzzy, c-format +#| msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgid "variable \"%s\" is of type %s but expression is of type %s" +msgstr "el subcampo «%s» es de tipo %s pero la expresión es de tipo %s" + +#. translator: %s is a SQL keyword +#: parser/analyze.c:2758 parser/analyze.c:2766 +#, fuzzy, c-format +#| msgid "cannot specify both SCROLL and NO SCROLL" +msgid "cannot specify both %s and %s" +msgstr "no se puede especificar SCROLL y NO SCROLL" + +#: parser/analyze.c:2786 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR no debe contener sentencias que modifiquen datos en WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2794 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s no está soportado" + +#: parser/analyze.c:2797 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "Los cursores declarados HOLD deben ser READ ONLY." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2805 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s no está soportado" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2816 +#, fuzzy, c-format +#| msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgid "DECLARE INSENSITIVE CURSOR ... %s is not valid" +msgstr "DECLARE INSENSITIVE CURSOR ... %s no está soportado" + +#: parser/analyze.c:2819 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Los cursores insensitivos deben ser READ ONLY." + +#: parser/analyze.c:2885 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "las vistas materializadas no deben usar sentencias que modifiquen datos en WITH" + +#: parser/analyze.c:2895 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "las vistas materializadas no deben usar tablas temporales o vistas" + +#: parser/analyze.c:2905 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "las vistas materializadas no pueden definirse usando parámetros enlazados" + +#: parser/analyze.c:2917 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "las vistas materializadas no pueden ser «unlogged»" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3106 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s no está permitido con cláusulas DISTINCT" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3113 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s no está permitido con cláusulas GROUP BY" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3120 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s no está permitido con cláusulas HAVING" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3127 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s no está permitido con funciones de agregación" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3134 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s no está permitido con funciones de ventana deslizante" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3141 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s no está permitido con funciones que retornan conjuntos en la lista de resultados" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3220 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%s debe especificar nombres de relaciones sin calificar" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3251 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s no puede ser aplicado a un join" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3260 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s no puede ser aplicado a una función" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3269 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s no puede ser aplicado a una función de tabla" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3287 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s no puede ser aplicado a una consulta WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3296 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s no puede ser aplicado a un «tuplestore» con nombre" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3316 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "la relación «%s» en la cláusula %s no fue encontrada en la cláusula FROM" + +#: parser/parse_agg.c:220 parser/parse_oper.c:227 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "no se pudo identificar un operador de ordenamiento para el tipo %s" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "Las funciones de agregación con DISTINCT deben ser capaces de ordenar sus valores de entrada." + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING debe tener menos de 32 argumentos" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "no se permiten funciones de agregación en las condiciones de JOIN" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "no se permiten las operaciones «grouping» en condiciones JOIN" + +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "las funciones de agregación no están permitidas en la cláusula FROM de su mismo nivel de consulta" + +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "las operaciones «grouping» no están permitidas en la cláusula FROM de su mismo nivel de consulta" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "no se permiten funciones de agregación en una función en FROM" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "no se permiten operaciones «grouping» en funciones en FROM" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "no se permiten funciones de agregación en expresiones de políticas" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de políticas" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "no se permiten funciones de agregación en RANGE de ventana deslizante" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "no se permiten operaciones «grouping» en RANGE de ventana deslizante" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "no se permiten funciones de agregación en ROWS de ventana deslizante" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "no se permiten operaciones «grouping» en ROWS de ventana deslizante" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "no se permiten funciones de agregación en GROUPS de ventana deslizante" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "no se permiten operaciones «grouping» en GROUPS de ventana deslizante" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "no se permiten funciones de agregación en restricciones «check»" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "no se permiten operaciones «grouping» en restricciones «check»" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "no se permiten funciones de agregación en expresiones DEFAULT" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "no se permiten operaciones «grouping» en expresiones DEFAULT" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "no se permiten funciones de agregación en una expresión de índice" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de índice" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "no se permiten funciones de agregación en predicados de índice" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "no se permiten operaciones «grouping» en predicados de índice" + +#: parser/parse_agg.c:490 +#, fuzzy +#| msgid "aggregate functions are not allowed in policy expressions" +msgid "aggregate functions are not allowed in statistics expressions" +msgstr "no se permiten funciones de agregación en expresiones de políticas" + +#: parser/parse_agg.c:492 +#, fuzzy +#| msgid "grouping operations are not allowed in policy expressions" +msgid "grouping operations are not allowed in statistics expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de políticas" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "no se permiten funciones de agregación en una expresión de transformación" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in transform expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de transformación" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "no se permiten funciones de agregación en un parámetro a EXECUTE" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "no se permiten operaciones «grouping» en parámetros a EXECUTE" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "no se permiten funciones de agregación en condición WHEN de un disparador" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "no se permiten operaciones «grouping» en condiciones WHEN de un disparador" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition bound" +msgstr "no se permiten funciones de agregación en borde de partición" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition bound" +msgstr "no se permiten operaciones «grouping» en borde de partición" + +#: parser/parse_agg.c:525 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "no se permiten funciones de agregación en una expresión de llave de particionaiento" + +#: parser/parse_agg.c:527 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de llave de particionamiento" + +#: parser/parse_agg.c:533 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "no se permiten funciones de agregación en expresiones de generación de columna" + +#: parser/parse_agg.c:535 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de generación de columna" + +#: parser/parse_agg.c:541 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "no se permiten funciones de agregación en argumentos de CALL" + +#: parser/parse_agg.c:543 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "no se permiten operaciones «grouping» en argumentos de CALL" + +#: parser/parse_agg.c:549 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten funciones de agregación en las condiciones WHERE de COPY FROM" + +#: parser/parse_agg.c:551 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten las operaciones «grouping» en condiciones WHERE de COPY FROM" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:578 parser/parse_clause.c:1846 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "no se permiten funciones de agregación en %s" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:581 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "no se permiten operaciones «grouping» en %s" + +#: parser/parse_agg.c:689 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "una función de agregación de nivel exterior no puede contener una variable de nivel inferior en sus argumentos directos" + +#: parser/parse_agg.c:768 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "las llamadas a funciones de agregación no pueden contener llamadas a funciones que retornan conjuntos" + +#: parser/parse_agg.c:769 parser/parse_expr.c:1673 parser/parse_expr.c:2146 +#: parser/parse_func.c:883 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Puede intentar mover la funci[on que retorna conjuntos a un elemento LATERAL FROM." + +#: parser/parse_agg.c:774 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "las llamadas a funciones de agregación no pueden contener llamadas a funciones de ventana deslizante" + +#: parser/parse_agg.c:853 +msgid "window functions are not allowed in JOIN conditions" +msgstr "no se permiten funciones de ventana deslizante en condiciones JOIN" + +#: parser/parse_agg.c:860 +msgid "window functions are not allowed in functions in FROM" +msgstr "no se permiten funciones de ventana deslizante en funciones en FROM" + +#: parser/parse_agg.c:866 +msgid "window functions are not allowed in policy expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de políticas" + +#: parser/parse_agg.c:879 +msgid "window functions are not allowed in window definitions" +msgstr "no se permiten funciones de ventana deslizante en definiciones de ventana deslizante" + +#: parser/parse_agg.c:911 +msgid "window functions are not allowed in check constraints" +msgstr "no se permiten funciones de ventana deslizante en restricciones «check»" + +#: parser/parse_agg.c:915 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones DEFAULT" + +#: parser/parse_agg.c:918 +msgid "window functions are not allowed in index expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de índice" + +#: parser/parse_agg.c:921 +#, fuzzy +#| msgid "window functions are not allowed in policy expressions" +msgid "window functions are not allowed in statistics expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de políticas" + +#: parser/parse_agg.c:924 +msgid "window functions are not allowed in index predicates" +msgstr "no se permiten funciones de ventana deslizante en predicados de índice" + +#: parser/parse_agg.c:927 +msgid "window functions are not allowed in transform expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de transformación" + +#: parser/parse_agg.c:930 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "no se permiten funciones de ventana deslizante en parámetros a EXECUTE" + +#: parser/parse_agg.c:933 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "no se permiten funciones de ventana deslizante en condiciones WHEN de un disparador" + +#: parser/parse_agg.c:936 +msgid "window functions are not allowed in partition bound" +msgstr "no se permiten funciones de ventana deslizante en borde de partición" + +#: parser/parse_agg.c:939 +msgid "window functions are not allowed in partition key expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de llave de particionamiento" + +#: parser/parse_agg.c:942 +msgid "window functions are not allowed in CALL arguments" +msgstr "no se permiten funciones de ventana deslizante en argumentos de CALL" + +#: parser/parse_agg.c:945 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten funciones de ventana deslizante en las condiciones WHERE de COPY FROM" + +#: parser/parse_agg.c:948 +msgid "window functions are not allowed in column generation expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de generación de columna" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:971 parser/parse_clause.c:1855 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "no se permiten funciones de ventana deslizante en %s" + +#: parser/parse_agg.c:1005 parser/parse_clause.c:2689 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "la ventana «%s» no existe" + +#: parser/parse_agg.c:1089 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "demasiados conjuntos «grouping» presentes (máximo 4096)" + +#: parser/parse_agg.c:1229 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "no se permiten funciones de agregación en el término recursivo de una consulta recursiva" + +#: parser/parse_agg.c:1422 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "la columna «%s.%s» debe aparecer en la cláusula GROUP BY o ser usada en una función de agregación" + +#: parser/parse_agg.c:1425 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "Argumentos directos de una función de agregación de conjuntos ordenados debe usar sólo columnas agrupadas." + +#: parser/parse_agg.c:1430 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "la subconsulta usa la columna «%s.%s» no agrupada de una consulta exterior" + +#: parser/parse_agg.c:1594 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "los argumentos de GROUPING deben ser expresiones agrupantes del nivel de consulta asociado" + +#: parser/parse_clause.c:190 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "relación «%s» no puede ser destino de una sentencia modificadora" + +#: parser/parse_clause.c:570 parser/parse_clause.c:598 parser/parse_func.c:2554 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "las funciones que retornan conjuntos deben aparecer en el nivel más externo del FROM" + +#: parser/parse_clause.c:610 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "no se permiten múltiples definiciones de columnas para la misma función" + +#: parser/parse_clause.c:643 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "ROWS FROM() con varias funciones no puede tener una lista de definición de columnas" + +#: parser/parse_clause.c:644 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "Ponga una lista de columnas separada para cada función dentro de ROWS FROM()." + +#: parser/parse_clause.c:650 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "UNNEST() con varios argumentos no puede tener una lista de definición de columnas" + +#: parser/parse_clause.c:651 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "Use llamadas a UNNEST() separadas dentro de ROWS FROM() y adjunte una lista de columnas a cada una." + +#: parser/parse_clause.c:658 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY no puede usarse con una lista de definición de columnas" + +#: parser/parse_clause.c:659 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Ponga una lista de columnas dentro de ROWS FROM()." + +#: parser/parse_clause.c:759 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "sólo se permite una columna FOR ORDINALITY" + +#: parser/parse_clause.c:820 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "el nombre de columna «%s» no es único" + +#: parser/parse_clause.c:862 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "el espacio de nombres «%s» no es único" + +#: parser/parse_clause.c:872 +#, c-format +msgid "only one default namespace is allowed" +msgstr "sólo se permite un espacio de nombres predeterminado" + +#: parser/parse_clause.c:932 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "no existe el método de tablesample «%s»" + +#: parser/parse_clause.c:954 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "el método de tablesample «%s» requiere %d argumento, no %d" +msgstr[1] "el método de tablesample «%s» requiere %d argumentos, no %d" + +#: parser/parse_clause.c:988 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "el método de tablesample «%s» no soporta la opción REPEATABLE" + +#: parser/parse_clause.c:1134 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "la cláusula TABLESAMPLE sólo puede aplicarse a tablas y vistas materializadas" + +#: parser/parse_clause.c:1324 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "la columna «%s» aparece más de una vez en la cláusula USING" + +#: parser/parse_clause.c:1339 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "la columna común «%s» aparece más de una vez en la tabla izquierda" + +#: parser/parse_clause.c:1348 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "la columna «%s» especificada en la cláusula USING no existe en la tabla izquierda" + +#: parser/parse_clause.c:1363 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "la columna común «%s» aparece más de una vez en la tabla derecha" + +#: parser/parse_clause.c:1372 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "la columna «%s» especificada en la cláusula USING no existe en la tabla derecha" + +#: parser/parse_clause.c:1451 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "la lista de alias de columnas para «%s» tiene demasiadas entradas" + +#: parser/parse_clause.c:1791 +#, fuzzy, c-format +#| msgid "row count cannot be NULL in FETCH FIRST ... WITH TIES clause" +msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" +msgstr "la cantidad de registros no puede ser nula en la cláusula FETCH FIRST ... WITH TIES" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1816 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "el argumento de %s no puede contener variables" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1981 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s «%s» es ambiguo" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2010 +#, c-format +msgid "non-integer constant in %s" +msgstr "constante no entera en %s" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2032 +#, c-format +msgid "%s position %d is not in select list" +msgstr "la posición %2$d de %1$s no está en la lista de resultados" + +#: parser/parse_clause.c:2471 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE está limitado a 12 elementos" + +#: parser/parse_clause.c:2677 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "la ventana «%s» ya está definida" + +#: parser/parse_clause.c:2738 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "no se puede pasar a llevar la cláusula PARTITION BY de la ventana «%s»" + +#: parser/parse_clause.c:2750 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "no se puede pasar a llevar la cláusula ORDER BY de la ventana «%s»" + +#: parser/parse_clause.c:2780 parser/parse_clause.c:2786 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "no se puede copiar la ventana «%s» porque tiene una cláusula «frame»" + +#: parser/parse_clause.c:2788 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Omita el uso de paréntesis en esta cláusula OVER." + +#: parser/parse_clause.c:2808 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING requiere exactamente una columna ORDER BY" + +#: parser/parse_clause.c:2831 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "el modo GROUPS requiere una cláusula ORDER BY" + +#: parser/parse_clause.c:2901 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "en una agregación con DISTINCT, las expresiones en ORDER BY deben aparecer en la lista de argumentos" + +#: parser/parse_clause.c:2902 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "para SELECT DISTINCT, las expresiones en ORDER BY deben aparecer en la lista de resultados" + +#: parser/parse_clause.c:2934 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "una función de agregación con DISTINCT debe tener al menos un argumento" + +#: parser/parse_clause.c:2935 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT debe tener al menos una columna" + +#: parser/parse_clause.c:3001 parser/parse_clause.c:3033 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "las expresiones de SELECT DISTINCT ON deben coincidir con las expresiones iniciales de ORDER BY" + +#: parser/parse_clause.c:3111 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC no están permitidos en cláusulas ON CONFLICT" + +#: parser/parse_clause.c:3117 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST no están permitidos en cláusulas ON CONFLICT" + +#: parser/parse_clause.c:3196 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE requiere una especificación de inferencia o nombre de restricción" + +#: parser/parse_clause.c:3197 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Por ejemplo, ON CONFLICT (nombre_de_columna)." + +#: parser/parse_clause.c:3208 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT no está soportado con tablas que son catálogos de sistema" + +#: parser/parse_clause.c:3216 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT no está soportado en la tabla «%s» usada como catálogo de sistema" + +#: parser/parse_clause.c:3346 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "el operador «%s» no es un operador válido de ordenamiento" + +#: parser/parse_clause.c:3348 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "Los operadores de ordenamiento deben ser miembros «<» o «>» de una familia de operadores btree." + +#: parser/parse_clause.c:3659 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING no está soportado para la columna de tipo %s" + +#: parser/parse_clause.c:3665 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING no está soportado para la columna de tipo %s y tipo de desplazamiento %s" + +#: parser/parse_clause.c:3668 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Convierta el valor de desplazamiento a un tipo apropiado." + +#: parser/parse_clause.c:3673 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING tiene múltiples interpretaciones para la columna de tipo %s y tipo de desplazamiento %s" + +#: parser/parse_clause.c:3676 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Convierta el valor de desplazamiento al tipo deseado exacto." + +#: parser/parse_coerce.c:1034 parser/parse_coerce.c:1072 +#: parser/parse_coerce.c:1090 parser/parse_coerce.c:1105 +#: parser/parse_expr.c:2055 parser/parse_expr.c:2649 parser/parse_target.c:995 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "no se puede convertir el tipo %s a %s" + +#: parser/parse_coerce.c:1075 +#, c-format +msgid "Input has too few columns." +msgstr "La entrada tiene muy pocas columnas." + +#: parser/parse_coerce.c:1093 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "No se puede convertir el tipo %s a %s en la columna %d." + +#: parser/parse_coerce.c:1108 +#, c-format +msgid "Input has too many columns." +msgstr "La entrada tiene demasiadas columnas." + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1163 parser/parse_coerce.c:1211 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "el argumento de %s debe ser de tipo %s, no tipo %s" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1174 parser/parse_coerce.c:1223 +#, c-format +msgid "argument of %s must not return a set" +msgstr "el argumento de %s no debe retornar un conjunto" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1363 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "los tipos %2$s y %3$s no son coincidentes en %1$s" + +#: parser/parse_coerce.c:1475 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "los tipos de argumento %s y %s no pueden hacerse coincidir" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1527 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%s no pudo convertir el tipo %s a %s" + +#: parser/parse_coerce.c:2089 parser/parse_coerce.c:2109 +#: parser/parse_coerce.c:2129 parser/parse_coerce.c:2149 +#: parser/parse_coerce.c:2204 parser/parse_coerce.c:2237 +#, fuzzy, c-format +#| msgid "arguments declared \"anyarray\" are not all alike" +msgid "arguments declared \"%s\" are not all alike" +msgstr "los argumentos declarados «anyarray» no son de tipos compatibles" + +#: parser/parse_coerce.c:2183 parser/parse_coerce.c:2297 +#: utils/fmgr/funcapi.c:489 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "el argumento declarado %s no es un array sino de tipo %s" + +#: parser/parse_coerce.c:2216 parser/parse_coerce.c:2329 +#: utils/fmgr/funcapi.c:503 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "el argumento declarado %s no es un tipo de rango sino tipo %s" + +#: parser/parse_coerce.c:2250 parser/parse_coerce.c:2363 +#: utils/fmgr/funcapi.c:521 utils/fmgr/funcapi.c:586 +#, fuzzy, c-format +#| msgid "argument declared %s is not a range type but type %s" +msgid "argument declared %s is not a multirange type but type %s" +msgstr "el argumento declarado %s no es un tipo de rango sino tipo %s" + +#: parser/parse_coerce.c:2288 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "no se puede determinar el tipo del argumento «anyarray»" + +#: parser/parse_coerce.c:2314 parser/parse_coerce.c:2346 +#: parser/parse_coerce.c:2380 parser/parse_coerce.c:2400 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "el argumento declarado %s no es consistente con el argumento declarado %s" + +#: parser/parse_coerce.c:2427 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "no se pudo determinar el tipo polimórfico porque la entrada es de tipo %s" + +#: parser/parse_coerce.c:2441 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "el argumento emparejado con anynonarray es un array: %s" + +#: parser/parse_coerce.c:2451 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "el tipo emparejado con anyenum no es un tipo enum: %s" + +#: parser/parse_coerce.c:2482 parser/parse_coerce.c:2532 +#: parser/parse_coerce.c:2596 parser/parse_coerce.c:2643 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "no se pudo determinar el tipo polimórfico %s porque la entrada es de tipo %s" + +#: parser/parse_coerce.c:2492 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "el tipo anycompatiblerange %s no coincide con el tipo anycompatible %s" + +#: parser/parse_coerce.c:2506 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "el argumento emparejado a anycompatiblenonarray es un array: %s" + +#: parser/parse_coerce.c:2607 parser/parse_coerce.c:2658 +#: utils/fmgr/funcapi.c:614 +#, fuzzy, c-format +#| msgid "could not find array type for data type %s" +msgid "could not find multirange type for data type %s" +msgstr "no se pudo encontrar un tipo de array para el tipo de dato %s" + +#: parser/parse_coerce.c:2739 +#, fuzzy, c-format +#| msgid "A result of type %s requires at least one input of type %s." +msgid "A result of type %s requires at least one input of type anyrange or anymultirange." +msgstr "Un resultado de tipo %s requiere al menos un argumento de tipo %s." + +#: parser/parse_coerce.c:2756 +#, fuzzy, c-format +#| msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgid "A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange." +msgstr "Un resultado de tipo %s requiere al menos una entrada de tipo anycompatible, anycompatiblearray, anycompatiblenonarray, o anycompatiblerange." + +#: parser/parse_coerce.c:2768 +#, fuzzy, c-format +#| msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange." +msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange." +msgstr "Un resultado de tipo %s requiere al menos una entrada de tipo anyelement, anyarray, anynonarray, anyenum, o anyrange." + +#: parser/parse_coerce.c:2780 +#, c-format +msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "Un resultado de tipo %s requiere al menos una entrada de tipo anycompatible, anycompatiblearray, anycompatiblenonarray, o anycompatiblerange." + +#: parser/parse_coerce.c:2810 +msgid "A result of type internal requires at least one input of type internal." +msgstr "Un resultado de tipo internal requiere al menos una entrada de tipo internal." + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:1004 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "discordancia de ordenamientos (collation) entre los ordenamientos implícitos «%s» y «%s»" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:1007 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "Puede elegir el ordenamiento aplicando la cláusula COLLATE a una o ambas expresiones." + +#: parser/parse_collate.c:854 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "discordancia de ordenamientos (collation) entre los ordenamientos explícitos «%s» y «%s»" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "la referencia recursiva a la consulta «%s» no debe aparecer dentro de su término no recursivo" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "la referencia recursiva a la consulta «%s» no debe aparecer dentro de una subconsulta" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "la referencia recursiva a la consulta «%s» no debe aparecer dentro de un outer join" + +#: parser/parse_cte.c:52 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "la referencia recursiva a la consulta «%s» no debe aparecer dentro de INTERSECT" + +#: parser/parse_cte.c:54 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "la referencia recursiva a la consulta «%s» no debe aparecer dentro de EXCEPT" + +#: parser/parse_cte.c:136 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "el nombre de consulta WITH «%s» fue especificado más de una vez" + +#: parser/parse_cte.c:268 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "la cláusula WITH que contiene las sentencias que modifican datos debe estar en el nivel más externo" + +#: parser/parse_cte.c:317 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "la columna %2$d en la consulta recursiva «%1$s» tiene tipo %3$s en el término no recursivo, pero %4$s en general" + +#: parser/parse_cte.c:323 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Aplique una conversión de tipo a la salida del término no recursivo al tipo correcto." + +#: parser/parse_cte.c:328 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "la columna %2$d en la consulta recursiva «%1$s» tiene ordenamiento (collation) %3$s en el término no recursivo, pero %4$s en general" + +#: parser/parse_cte.c:332 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "Use la clásula COLLATE para definir el ordenamiento del término no-recursivo." + +#: parser/parse_cte.c:350 +#, c-format +msgid "WITH query is not recursive" +msgstr "" + +#: parser/parse_cte.c:381 +#, c-format +msgid "with a SEARCH or CYCLE clause, the left side of the UNION must be a SELECT" +msgstr "" + +#: parser/parse_cte.c:386 +#, c-format +msgid "with a SEARCH or CYCLE clause, the right side of the UNION must be a SELECT" +msgstr "" + +#: parser/parse_cte.c:401 +#, c-format +msgid "search column \"%s\" not in WITH query column list" +msgstr "" + +#: parser/parse_cte.c:408 +#, fuzzy, c-format +#| msgid "column \"%s\" specified more than once" +msgid "search column \"%s\" specified more than once" +msgstr "la columna «%s» fue especificada más de una vez" + +#: parser/parse_cte.c:417 +#, c-format +msgid "search sequence column name \"%s\" already used in WITH query column list" +msgstr "" + +#: parser/parse_cte.c:436 +#, fuzzy, c-format +#| msgid "column \"%s\" named in key does not exist" +msgid "cycle column \"%s\" not in WITH query column list" +msgstr "no existe la columna «%s» en la llave" + +#: parser/parse_cte.c:443 +#, fuzzy, c-format +#| msgid "column \"%s\" specified more than once" +msgid "cycle column \"%s\" specified more than once" +msgstr "la columna «%s» fue especificada más de una vez" + +#: parser/parse_cte.c:452 +#, c-format +msgid "cycle mark column name \"%s\" already used in WITH query column list" +msgstr "" + +#: parser/parse_cte.c:464 +#, c-format +msgid "cycle path column name \"%s\" already used in WITH query column list" +msgstr "" + +#: parser/parse_cte.c:472 +#, c-format +msgid "cycle mark column name and cycle path column name are the same" +msgstr "" + +#: parser/parse_cte.c:508 +#, fuzzy, c-format +#| msgid "could not identify an equality operator for type %s" +msgid "could not identify an inequality operator for type %s" +msgstr "no se pudo identificar un operador de igualdad para el tipo %s" + +#: parser/parse_cte.c:520 +#, c-format +msgid "search sequence column name and cycle mark column name are the same" +msgstr "" + +#: parser/parse_cte.c:527 +#, c-format +msgid "search sequence column name and cycle path column name are the same" +msgstr "" + +#: parser/parse_cte.c:611 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "la consulta WITH «%s» tiene %d columnas disponibles pero se especificaron %d" + +#: parser/parse_cte.c:791 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "la recursión mutua entre elementos de WITH no está implementada" + +#: parser/parse_cte.c:843 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "la consulta recursiva «%s» no debe contener sentencias que modifiquen datos" + +#: parser/parse_cte.c:851 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "la consulta recursiva «%s» no tiene la forma término-no-recursivo UNION [ALL] término-recursivo" + +#: parser/parse_cte.c:895 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "ORDER BY no está implementado en una consulta recursiva" + +#: parser/parse_cte.c:901 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "OFFSET no está implementado en una consulta recursiva" + +#: parser/parse_cte.c:907 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "LIMIT no está implementado en una consulta recursiva" + +#: parser/parse_cte.c:913 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "FOR UPDATE/SHARE no está implementado en una consulta recursiva" + +#: parser/parse_cte.c:970 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "la referencia recursiva a la consulta «%s» no debe aparecer más de una vez" + +#: parser/parse_expr.c:287 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "DEFAULT no está permitido en este contexto" + +#: parser/parse_expr.c:340 parser/parse_relation.c:3592 +#: parser/parse_relation.c:3612 +#, c-format +msgid "column %s.%s does not exist" +msgstr "no existe la columna %s.%s" + +#: parser/parse_expr.c:352 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "la columna «%s» no fue encontrado en el tipo %s" + +#: parser/parse_expr.c:358 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "no se pudo identificar la columna «%s» en el tipo de dato record" + +#: parser/parse_expr.c:364 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "la notación de columna .%s fue aplicada al tipo %s, que no es un tipo compuesto" + +#: parser/parse_expr.c:395 parser/parse_target.c:740 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "la expansión de filas a través de «*» no está soportado aquí" + +#: parser/parse_expr.c:516 +msgid "cannot use column reference in DEFAULT expression" +msgstr "no se pueden usar referencias a columnas en una cláusula DEFAULT" + +#: parser/parse_expr.c:519 +msgid "cannot use column reference in partition bound expression" +msgstr "no se pueden usar referencias a columnas en expresión de borde de partición" + +#: parser/parse_expr.c:788 parser/parse_relation.c:807 +#: parser/parse_relation.c:889 parser/parse_target.c:1235 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "la referencia a la columna «%s» es ambigua" + +#: parser/parse_expr.c:844 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:208 parser/parse_param.c:307 +#, c-format +msgid "there is no parameter $%d" +msgstr "no hay parámetro $%d" + +#: parser/parse_expr.c:1044 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULLIF requiere que el operador = retorne boolean" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1050 parser/parse_expr.c:2965 +#, c-format +msgid "%s must not return a set" +msgstr "%s no debe retornar un conjunto" + +#: parser/parse_expr.c:1430 parser/parse_expr.c:1462 +#, c-format +msgid "number of columns does not match number of values" +msgstr "el número de columnas no coincide con el número de valores" + +#: parser/parse_expr.c:1476 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "el origen para un UPDATE de varias columnas debe ser una expresión sub-SELECT o ROW ()" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1671 parser/parse_expr.c:2144 parser/parse_func.c:2676 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "no se permiten funciones que retornan conjuntos en %s" + +#: parser/parse_expr.c:1733 +msgid "cannot use subquery in check constraint" +msgstr "no se pueden usar subconsultas en una restricción «check»" + +#: parser/parse_expr.c:1737 +msgid "cannot use subquery in DEFAULT expression" +msgstr "no se puede usar una subconsulta en una expresión DEFAULT" + +#: parser/parse_expr.c:1740 +msgid "cannot use subquery in index expression" +msgstr "no se puede usar una subconsulta en una expresión de índice" + +#: parser/parse_expr.c:1743 +msgid "cannot use subquery in index predicate" +msgstr "no se puede usar una subconsulta en un predicado de índice" + +#: parser/parse_expr.c:1746 +#, fuzzy +#| msgid "cannot use subquery in partition key expression" +msgid "cannot use subquery in statistics expression" +msgstr "no se puede usar una subconsulta en una expresión de llave de partición" + +#: parser/parse_expr.c:1749 +msgid "cannot use subquery in transform expression" +msgstr "no se puede usar una subconsulta en una expresión de transformación" + +#: parser/parse_expr.c:1752 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "no se puede usar una subconsulta en un parámetro a EXECUTE" + +#: parser/parse_expr.c:1755 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "no se puede usar una subconsulta en la condición WHEN de un disparador" + +#: parser/parse_expr.c:1758 +msgid "cannot use subquery in partition bound" +msgstr "no se puede usar una subconsulta en un borde de partición" + +#: parser/parse_expr.c:1761 +msgid "cannot use subquery in partition key expression" +msgstr "no se puede usar una subconsulta en una expresión de llave de partición" + +#: parser/parse_expr.c:1764 +msgid "cannot use subquery in CALL argument" +msgstr "no se puede usar una subconsulta en un argumento a CALL" + +#: parser/parse_expr.c:1767 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "no se puede usar una subconsulta en la condición WHERE de COPY FROM" + +#: parser/parse_expr.c:1770 +msgid "cannot use subquery in column generation expression" +msgstr "no se puede usar una subconsulta en una expresión de generación de columna" + +#: parser/parse_expr.c:1823 +#, c-format +msgid "subquery must return only one column" +msgstr "la subconsulta debe retornar sólo una columna" + +#: parser/parse_expr.c:1894 +#, c-format +msgid "subquery has too many columns" +msgstr "la subconsulta tiene demasiadas columnas" + +#: parser/parse_expr.c:1899 +#, c-format +msgid "subquery has too few columns" +msgstr "la subconsulta tiene muy pocas columnas" + +#: parser/parse_expr.c:1995 +#, c-format +msgid "cannot determine type of empty array" +msgstr "no se puede determinar el tipo de un array vacío" + +#: parser/parse_expr.c:1996 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "Agregue una conversión de tipo explícita al tipo deseado, por ejemplo ARRAY[]::integer[]." + +#: parser/parse_expr.c:2010 +#, c-format +msgid "could not find element type for data type %s" +msgstr "no se pudo encontrar el tipo de dato de elemento para el tipo de dato %s" + +#: parser/parse_expr.c:2290 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "el valor del atributo XML sin nombre debe ser una referencia a una columna" + +#: parser/parse_expr.c:2291 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "el valor del elemento XML sin nombre debe ser una referencia a una columna" + +#: parser/parse_expr.c:2306 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "el nombre de atributo XML «%s» aparece más de una vez" + +#: parser/parse_expr.c:2413 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "no se puede convertir el resultado de XMLSERIALIZE a %s" + +#: parser/parse_expr.c:2722 parser/parse_expr.c:2918 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "número desigual de entradas en expresiones de registro" + +#: parser/parse_expr.c:2732 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "no se pueden comparar registros de largo cero" + +#: parser/parse_expr.c:2757 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "el operador de comparación de registros debe retornar tipo boolean, no tipo %s" + +#: parser/parse_expr.c:2764 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "el operador de comparación de registros no puede retornar un conjunto" + +#: parser/parse_expr.c:2823 parser/parse_expr.c:2864 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "no se pudo determinar la interpretación del operador de comparación de registros %s" + +#: parser/parse_expr.c:2825 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "Los operadores de comparación de registros deben estar asociados a una familia de operadores btree." + +#: parser/parse_expr.c:2866 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Hay múltiples candidatos igualmente plausibles." + +#: parser/parse_expr.c:2959 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROM requiere que el operador = retorne boolean" + +#: parser/parse_func.c:194 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "nombre de argumento «%s» especificado más de una vez" + +#: parser/parse_func.c:205 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "un argumento posicional no puede seguir a un argumento con nombre" + +#: parser/parse_func.c:287 parser/parse_func.c:2369 +#, c-format +msgid "%s is not a procedure" +msgstr "%s no es un procedimiento" + +#: parser/parse_func.c:291 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Para invocar a una función, use SELECT." + +#: parser/parse_func.c:297 +#, c-format +msgid "%s is a procedure" +msgstr "%s es un procedimiento" + +#: parser/parse_func.c:301 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Para invocar a un procedimiento, use CALL." + +#: parser/parse_func.c:315 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "se especificó %s(*), pero %s no es una función de agregación" + +#: parser/parse_func.c:322 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "se especificó DISTINCT, pero %s no es una función de agregación" + +#: parser/parse_func.c:328 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "se especificó WITHIN GROUP, pero %s no es una función de agregación" + +#: parser/parse_func.c:334 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "se especificó ORDER BY, pero %s no es una función de agregación" + +#: parser/parse_func.c:340 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "se especificó FILTER, pero %s no es una función de agregación" + +#: parser/parse_func.c:346 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "se especificó OVER, pero %s no es una función de ventana deslizante ni una función de agregación" + +#: parser/parse_func.c:384 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "WITHIN GROUP es obligatorio para la función de agregación de conjuntos ordenados %s" + +#: parser/parse_func.c:390 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "OVER no está soportado para la función de agregación de conjuntos ordenados %s" + +#: parser/parse_func.c:421 parser/parse_func.c:452 +#, fuzzy, c-format +#| msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgid "There is an ordered-set aggregate %s, but it requires %d direct argument, not %d." +msgid_plural "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr[0] "Hay una función de agregación de conjuntos ordenados %s, pero requiere %d argumentos directos, no %d." +msgstr[1] "Hay una función de agregación de conjuntos ordenados %s, pero requiere %d argumentos directos, no %d." + +#: parser/parse_func.c:479 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "Para usar la función de agregación de conjunto hipotética %s, el número de argumentos hipotéticos directos (acá %d) debe coincidir con el número de columnas del ordenamiento (acá %d)." + +#: parser/parse_func.c:493 +#, fuzzy, c-format +#| msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct argument." +msgid_plural "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr[0] "Hay una función de agregación de conjuntos ordenados %s, pero requiere al menos %d argumentos directos" +msgstr[1] "Hay una función de agregación de conjuntos ordenados %s, pero requiere al menos %d argumentos directos" + +#: parser/parse_func.c:514 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s no es una función de agregación de conjunto ordenado, por lo que no puede tener WITHIN GROUP" + +#: parser/parse_func.c:527 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "la función de ventana deslizante %s requiere una cláusula OVER" + +#: parser/parse_func.c:534 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "la función de ventana deslizante %s no puede tener WITHIN GROUP" + +#: parser/parse_func.c:563 +#, c-format +msgid "procedure %s is not unique" +msgstr "la procedimiento %s no es único" + +#: parser/parse_func.c:566 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "No se pudo escoger el procedimiento más adecuado. Puede ser necesario agregar conversiones explícitas de tipos." + +#: parser/parse_func.c:572 +#, c-format +msgid "function %s is not unique" +msgstr "la función %s no es única" + +#: parser/parse_func.c:575 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "No se pudo escoger la función más adecuada. Puede ser necesario agregar conversiones explícitas de tipos." + +#: parser/parse_func.c:614 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "Ninguna función coincide en el nombre y tipos de argumentos. Quizás puso ORDER BY en una mala posición; ORDER BY debe aparecer después de todos los argumentos normales de la función de agregación." + +#: parser/parse_func.c:622 parser/parse_func.c:2412 +#, c-format +msgid "procedure %s does not exist" +msgstr "no existe el procedimiento «%s»" + +#: parser/parse_func.c:625 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ningún procedimiento coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos." + +#: parser/parse_func.c:634 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ninguna función coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos." + +#: parser/parse_func.c:736 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "el parámetro VARIADIC debe ser un array" + +#: parser/parse_func.c:790 parser/parse_func.c:854 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*) debe ser usado para invocar una función de agregación sin parámetros" + +#: parser/parse_func.c:797 +#, c-format +msgid "aggregates cannot return sets" +msgstr "las funciones de agregación no pueden retornar conjuntos" + +#: parser/parse_func.c:812 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "las funciones de agregación no pueden usar argumentos con nombre" + +#: parser/parse_func.c:844 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "DISTINCT no está implementado para funciones de ventana deslizante" + +#: parser/parse_func.c:864 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "el ORDER BY de funciones de agregación no está implementado para funciones de ventana deslizante" + +#: parser/parse_func.c:873 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "FILTER no está implementado para funciones de ventana deslizante" + +#: parser/parse_func.c:882 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "las llamadas a funciones de ventana no pueden contener llamadas a funciones que retornan conjuntos" + +#: parser/parse_func.c:890 +#, c-format +msgid "window functions cannot return sets" +msgstr "las funciones de ventana deslizante no pueden retornar conjuntos" + +#: parser/parse_func.c:2168 parser/parse_func.c:2441 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "no se pudo encontrar una función llamada «%s»" + +#: parser/parse_func.c:2182 parser/parse_func.c:2459 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "el nombre de función «%s» no es único" + +#: parser/parse_func.c:2184 parser/parse_func.c:2462 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Especifique la lista de argumentos para seleccionar la función sin ambigüedad." + +#: parser/parse_func.c:2228 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "los procedimientos no pueden tener más de %d argumento" +msgstr[1] "los procedimientos no pueden tener más de %d argumentos" + +#: parser/parse_func.c:2359 +#, c-format +msgid "%s is not a function" +msgstr "«%s» no es una función" + +#: parser/parse_func.c:2379 +#, c-format +msgid "function %s is not an aggregate" +msgstr "la función %s no es una función de agregación" + +#: parser/parse_func.c:2407 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "no se pudo encontrar un procedimiento llamado «%s»" + +#: parser/parse_func.c:2421 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "no se pudo encontrar una función de agregación llamada «%s»" + +#: parser/parse_func.c:2426 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "no existe la función de agregación %s(*)" + +#: parser/parse_func.c:2431 +#, c-format +msgid "aggregate %s does not exist" +msgstr "no existe la función de agregación %s" + +#: parser/parse_func.c:2467 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "el nombre de procedimiento «%s» no es única" + +#: parser/parse_func.c:2470 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Especifique la lista de argumentos para seleccionar el procedimiento sin ambigüedad." + +#: parser/parse_func.c:2475 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "el atributo de la función de agregación «%s» no es único" + +#: parser/parse_func.c:2478 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Especifique la lista de argumentos para seleccionar la función de agregación sin ambigüedad." + +#: parser/parse_func.c:2483 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "el nombre de rutina «%s» no es único" + +#: parser/parse_func.c:2486 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Especifique la lista de argumentos para seleccionar la rutina sin ambigüedad." + +#: parser/parse_func.c:2541 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "no se permiten funciones que retornan conjuntos en condiciones JOIN" + +#: parser/parse_func.c:2562 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de política" + +#: parser/parse_func.c:2578 +msgid "set-returning functions are not allowed in window definitions" +msgstr "no se permiten funciones que retornan conjuntos definiciones de ventana deslizante" + +#: parser/parse_func.c:2616 +msgid "set-returning functions are not allowed in check constraints" +msgstr "no se permiten funciones de que retornan conjuntos en restricciones «check»" + +#: parser/parse_func.c:2620 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones DEFAULT" + +#: parser/parse_func.c:2623 +msgid "set-returning functions are not allowed in index expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de índice" + +#: parser/parse_func.c:2626 +msgid "set-returning functions are not allowed in index predicates" +msgstr "no se permiten funciones que retornan conjuntos en predicados de índice" + +#: parser/parse_func.c:2629 +#, fuzzy +#| msgid "set-returning functions are not allowed in policy expressions" +msgid "set-returning functions are not allowed in statistics expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de política" + +#: parser/parse_func.c:2632 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de transformación" + +#: parser/parse_func.c:2635 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "no se permiten funciones que retornan conjuntos en parámetros a EXECUTE" + +#: parser/parse_func.c:2638 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "no se permiten funciones que retornan conjuntos en condiciones WHEN de un disparador" + +#: parser/parse_func.c:2641 +msgid "set-returning functions are not allowed in partition bound" +msgstr "no se permiten funciones que retornan conjuntos en bordes de partición" + +#: parser/parse_func.c:2644 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de llave de particionamiento" + +#: parser/parse_func.c:2647 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "no se permiten funciones que retornan conjuntos en argumentos de CALL" + +#: parser/parse_func.c:2650 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten funciones que retornan conjuntos en las condiciones WHERE de COPY FROM" + +#: parser/parse_func.c:2653 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de generación de columna" + +#: parser/parse_node.c:87 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "las listas de resultados pueden tener a lo más %d entradas" + +#: parser/parse_oper.c:123 parser/parse_oper.c:690 +#, fuzzy, c-format +#| msgid "log format \"%s\" is not supported" +msgid "postfix operators are not supported" +msgstr "el formato de log «%s» no está soportado" + +#: parser/parse_oper.c:130 parser/parse_oper.c:649 utils/adt/regproc.c:539 +#: utils/adt/regproc.c:723 +#, c-format +msgid "operator does not exist: %s" +msgstr "el operador no existe: %s" + +#: parser/parse_oper.c:229 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Use un operador de ordenamiento explícito o modifique la consulta." + +#: parser/parse_oper.c:485 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "el operador requiere conversión explícita de tipos: %s" + +#: parser/parse_oper.c:641 +#, c-format +msgid "operator is not unique: %s" +msgstr "el operador no es único: %s" + +#: parser/parse_oper.c:643 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "No se pudo escoger el operador más adecuado. Puede ser necesario agregar conversiones explícitas de tipos." + +#: parser/parse_oper.c:652 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Ningún operador coincide en el nombre y tipo de argumento. Puede ser necesario agregar conversión explícita de tipos." + +#: parser/parse_oper.c:654 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ningún operador coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos." + +#: parser/parse_oper.c:714 parser/parse_oper.c:828 +#, c-format +msgid "operator is only a shell: %s" +msgstr "el operador está inconcluso: %s" + +#: parser/parse_oper.c:816 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (array) requiere un array al lado derecho" + +#: parser/parse_oper.c:858 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (array) requiere un operador que entregue boolean" + +#: parser/parse_oper.c:863 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (array) requiere un operador que no retorne un conjunto" + +#: parser/parse_param.c:225 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "para el parámetro $%d se dedujeron tipos de dato inconsistentes" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "la referencia a la tabla «%s» es ambigua" + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "la referencia a la tabla %u es ambigua" + +#: parser/parse_relation.c:445 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "el nombre de tabla «%s» fue especificado más de una vez" + +#: parser/parse_relation.c:474 parser/parse_relation.c:3532 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "referencia a la entrada de la cláusula FROM para la tabla «%s» no válida" + +#: parser/parse_relation.c:478 parser/parse_relation.c:3537 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Hay una entrada para la tabla «%s», pero no puede ser referenciada desde esta parte de la consulta." + +#: parser/parse_relation.c:480 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "El tipo de JOIN debe ser INNER o LEFT para una referencia LATERAL." + +#: parser/parse_relation.c:691 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "la referencia a columna a sistema «%s» en una restricción check no es válida" + +#: parser/parse_relation.c:700 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "no se puede usar la columna de sistema «%s» en una expresión de generación de columna" + +#: parser/parse_relation.c:1173 parser/parse_relation.c:1625 +#: parser/parse_relation.c:2302 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "la tabla «%s» tiene %d columnas pero se especificaron %d" + +#: parser/parse_relation.c:1377 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "Hay un elemento WITH llamado «%s», pero no puede ser referenciada desde esta parte de la consulta." + +#: parser/parse_relation.c:1379 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "Use WITH RECURSIVE, o reordene los elementos de WITH para eliminar referencias hacia adelante." + +#: parser/parse_relation.c:1767 +#, fuzzy, c-format +#| msgid "a column definition list is required for functions returning \"record\"" +msgid "a column definition list is redundant for a function with OUT parameters" +msgstr "la lista de definición de columnas es obligatoria para funciones que retornan «record»" + +#: parser/parse_relation.c:1773 +#, fuzzy, c-format +#| msgid "a column definition list is required for functions returning \"record\"" +msgid "a column definition list is redundant for a function returning a named composite type" +msgstr "la lista de definición de columnas es obligatoria para funciones que retornan «record»" + +#: parser/parse_relation.c:1780 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "sólo se permite una lista de definición de columnas en funciones que retornan «record»" + +#: parser/parse_relation.c:1791 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "la lista de definición de columnas es obligatoria para funciones que retornan «record»" + +#: parser/parse_relation.c:1880 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "la función «%s» en FROM tiene el tipo de retorno no soportado %s" + +#: parser/parse_relation.c:2089 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "la lista VALUES «%s» tiene %d columnas disponibles pero se especificaron %d" + +#: parser/parse_relation.c:2161 +#, c-format +msgid "joins can have at most %d columns" +msgstr "los joins pueden tener a lo más %d columnas" + +#: parser/parse_relation.c:2275 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "la consulta WITH «%s» no tiene una cláusula RETURNING" + +#: parser/parse_relation.c:3307 parser/parse_relation.c:3317 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "no existe la columna %d en la relación «%s»" + +#: parser/parse_relation.c:3535 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Probablemente quiera hacer referencia al alias de la tabla «%s»." + +#: parser/parse_relation.c:3543 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "falta una entrada para la tabla «%s» en la cláusula FROM" + +#: parser/parse_relation.c:3595 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Probablemente quiera hacer referencia a la columna «%s.%s»." + +#: parser/parse_relation.c:3597 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Hay una columna llamada «%s» en la tabla «%s», pero no puede ser referenciada desde esta parte de la consulta." + +#: parser/parse_relation.c:3614 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "Probablemente quiera hacer referencia a la columna «%s.%s» o la columna «%s.%s»." + +#: parser/parse_target.c:483 parser/parse_target.c:804 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "no se puede asignar a la columna de sistema «%s»" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "no se puede definir un elemento de array a DEFAULT" + +#: parser/parse_target.c:516 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "no se puede definir un subcampo a DEFAULT" + +#: parser/parse_target.c:590 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "la columna «%s» es de tipo %s pero la expresión es de tipo %s" + +#: parser/parse_target.c:788 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "no se puede asignar al campo «%s» de la columna «%s» porque su tipo %s no es un tipo compuesto" + +#: parser/parse_target.c:797 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "no se puede asignar al campo «%s» de la columna «%s» porque no existe esa columna en el tipo de dato %s" + +#: parser/parse_target.c:878 +#, fuzzy, c-format +#| msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgid "subscripted assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "la asignación de array a «%s» requiere tipo %s pero la expresión es de tipo %s" + +#: parser/parse_target.c:888 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "el subcampo «%s» es de tipo %s pero la expresión es de tipo %s" + +#: parser/parse_target.c:1323 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "SELECT * sin especificar tablas no es válido" + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "referencia %%TYPE inapropiada (muy pocos nombres con punto): %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "la referencia a %%TYPE es inapropiada (demasiados nombres con punto): %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "la referencia al tipo %s convertida a %s" + +#: parser/parse_type.c:278 parser/parse_type.c:803 utils/cache/typcache.c:389 +#: utils/cache/typcache.c:444 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "el tipo «%s» está inconcluso" + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "un modificador de tipo no está permitido para el tipo «%s»" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "los modificadores de tipo deben ser constantes simples o identificadores" + +#: parser/parse_type.c:721 parser/parse_type.c:766 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "el nombre de tipo «%s» no es válido" + +#: parser/parse_utilcmd.c:266 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "no se puede crear una tabla particionada como hija de herencia" + +#: parser/parse_utilcmd.c:580 +#, c-format +msgid "array of serial is not implemented" +msgstr "array de serial no está implementado" + +#: parser/parse_utilcmd.c:659 parser/parse_utilcmd.c:671 +#: parser/parse_utilcmd.c:730 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "las declaraciones NULL/NOT NULL no son coincidentes para la columna «%s» de la tabla «%s»" + +#: parser/parse_utilcmd.c:683 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "múltiples valores default especificados para columna «%s» de tabla «%s»" + +#: parser/parse_utilcmd.c:700 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "las columnas identidad no está soportadas en tablas tipadas" + +#: parser/parse_utilcmd.c:704 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "las columnas identidad no están soportadas en particiones" + +#: parser/parse_utilcmd.c:713 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "múltiples especificaciones de identidad para columna «%s» de tabla «%s»" + +#: parser/parse_utilcmd.c:743 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "las columnas generadas no están soportadas en tablas tipadas" + +#: parser/parse_utilcmd.c:747 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "las columnas generadas no están soportadas en particiones" + +#: parser/parse_utilcmd.c:752 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "múltiples cláusulas de generación especificadas para columna «%s» de tabla «%s»" + +#: parser/parse_utilcmd.c:770 parser/parse_utilcmd.c:885 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "las restricciones de llave primaria no están soportadas en tablas foráneas" + +#: parser/parse_utilcmd.c:779 parser/parse_utilcmd.c:895 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "las restricciones unique no están soportadas en tablas foráneas" + +#: parser/parse_utilcmd.c:824 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "tanto el valor por omisión como identidad especificados para columna «%s» de tabla «%s»" + +#: parser/parse_utilcmd.c:832 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "tanto el valor por omisión como expresión de generación especificados para columna «%s» de tabla «%s»" + +#: parser/parse_utilcmd.c:840 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "tanto identidad como expresión de generación especificados para columna «%s» de tabla «%s»" + +#: parser/parse_utilcmd.c:905 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "las restricciones de exclusión no están soportadas en tablas foráneas" + +#: parser/parse_utilcmd.c:911 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "las restricciones de exclusión no están soportadas en tablas particionadas" + +#: parser/parse_utilcmd.c:976 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "LIKE no está soportado para la creación de tablas foráneas" + +#: parser/parse_utilcmd.c:1753 parser/parse_utilcmd.c:1861 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "El índice «%s» contiene una referencia a la fila completa (whole-row)." + +#: parser/parse_utilcmd.c:2248 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "no se puede usar un índice existente en CREATE TABLE" + +#: parser/parse_utilcmd.c:2268 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "el índice «%s» ya está asociado a una restricción" + +#: parser/parse_utilcmd.c:2283 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "el índice «%s» no es válido" + +#: parser/parse_utilcmd.c:2289 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "«%s» no es un índice único" + +#: parser/parse_utilcmd.c:2290 parser/parse_utilcmd.c:2297 +#: parser/parse_utilcmd.c:2304 parser/parse_utilcmd.c:2381 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "No se puede crear una restricción de llave primaria o única usando un índice así." + +#: parser/parse_utilcmd.c:2296 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "el índice «%s» contiene expresiones" + +#: parser/parse_utilcmd.c:2303 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "«%s» es un índice parcial" + +#: parser/parse_utilcmd.c:2315 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "«%s» no es un índice postergable (deferrable)" + +#: parser/parse_utilcmd.c:2316 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "No se puede crear una restricción no postergable usando un índice postergable." + +#: parser/parse_utilcmd.c:2380 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "el índice «%s» columna número %d no tiene comportamiento de ordenamiento por omisión" + +#: parser/parse_utilcmd.c:2537 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "la columna «%s» aparece dos veces en llave primaria" + +#: parser/parse_utilcmd.c:2543 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "la columna «%s» aparece dos veces en restricción unique" + +#: parser/parse_utilcmd.c:2896 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "las expresiones y predicados de índice sólo pueden referirse a la tabla en indexación" + +#: parser/parse_utilcmd.c:2974 +#, fuzzy, c-format +#| msgid "index expressions and predicates can refer only to the table being indexed" +msgid "statistics expressions can refer only to the table being indexed" +msgstr "las expresiones y predicados de índice sólo pueden referirse a la tabla en indexación" + +#: parser/parse_utilcmd.c:3020 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "las reglas en vistas materializadas no están soportadas" + +#: parser/parse_utilcmd.c:3083 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "la condición WHERE de la regla no puede contener referencias a otras relaciones" + +#: parser/parse_utilcmd.c:3157 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "las reglas con condiciones WHERE sólo pueden tener acciones SELECT, INSERT, UPDATE o DELETE" + +#: parser/parse_utilcmd.c:3175 parser/parse_utilcmd.c:3276 +#: rewrite/rewriteHandler.c:508 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "las sentencias UNION/INTERSECT/EXCEPT condicionales no están implementadas" + +#: parser/parse_utilcmd.c:3193 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "una regla ON SELECT no puede usar OLD" + +#: parser/parse_utilcmd.c:3197 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "una regla ON SELECT no puede usar NEW" + +#: parser/parse_utilcmd.c:3206 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "una regla ON INSERT no puede usar OLD" + +#: parser/parse_utilcmd.c:3212 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "una regla ON DELETE no puede usar NEW" + +#: parser/parse_utilcmd.c:3240 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "no se puede hacer referencia a OLD dentro de una consulta WITH" + +#: parser/parse_utilcmd.c:3247 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "no se puede hacer referencia a NEW dentro de una consulta WITH" + +#: parser/parse_utilcmd.c:3706 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "cláusula DEFERRABLE mal puesta" + +#: parser/parse_utilcmd.c:3711 parser/parse_utilcmd.c:3726 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "no se permiten múltiples cláusulas DEFERRABLE/NOT DEFERRABLE" + +#: parser/parse_utilcmd.c:3721 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "la cláusula NOT DEFERRABLE está mal puesta" + +#: parser/parse_utilcmd.c:3742 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "la cláusula INITIALLY DEFERRED está mal puesta" + +#: parser/parse_utilcmd.c:3747 parser/parse_utilcmd.c:3773 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "no se permiten múltiples cláusulas INITIALLY IMMEDIATE/DEFERRED" + +#: parser/parse_utilcmd.c:3768 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "la cláusula INITIALLY IMMEDIATE está mal puesta" + +#: parser/parse_utilcmd.c:3959 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE especifica un esquema (%s) diferente del que se está creando (%s)" + +#: parser/parse_utilcmd.c:3994 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "«%s» no es una tabla particionada" + +#: parser/parse_utilcmd.c:4001 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "«la tabla %s» no está particionada" + +#: parser/parse_utilcmd.c:4008 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "el índice «%s» no está particionado" + +#: parser/parse_utilcmd.c:4048 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "una tabla particionada por hash no puede tener una partición default" + +#: parser/parse_utilcmd.c:4065 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "especificación de borde no válida para partición de hash" + +#: parser/parse_utilcmd.c:4071 partitioning/partbounds.c:4701 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "el módulo para una partición hash debe ser un entero positivo" + +#: parser/parse_utilcmd.c:4078 partitioning/partbounds.c:4709 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "remanente en partición hash debe ser menor que el módulo" + +#: parser/parse_utilcmd.c:4091 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "especificación de borde no válida para partición de lista" + +#: parser/parse_utilcmd.c:4144 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "especificación de borde no válida para partición de rango" + +#: parser/parse_utilcmd.c:4150 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM debe especificar exactamente un valor por cada columna de particionado" + +#: parser/parse_utilcmd.c:4154 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO debe especificar exactamente un valor por cada columna de particionado" + +#: parser/parse_utilcmd.c:4268 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "no se puede especificar NULL en borde de rango" + +#: parser/parse_utilcmd.c:4317 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "cada borde que sigue a un MAXVALUE debe ser también MAXVALUE" + +#: parser/parse_utilcmd.c:4324 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "cada borde que siga a un MINVALUE debe ser también MINVALUE" + +#: parser/parse_utilcmd.c:4367 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "el valor especificado no puede ser convertido al tipo %s para la columna «%s»" + +#: parser/parser.c:247 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "UESCAPE debe ser seguido por un literal de cadena simple" + +#: parser/parser.c:252 +msgid "invalid Unicode escape character" +msgstr "carácter de escape Unicode no válido" + +#: parser/parser.c:321 scan.l:1329 +#, c-format +msgid "invalid Unicode escape value" +msgstr "valor de escape Unicode no válido" + +#: parser/parser.c:468 scan.l:677 utils/adt/varlena.c:6566 +#, c-format +msgid "invalid Unicode escape" +msgstr "valor de escape Unicode no válido" + +#: parser/parser.c:469 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "Los escapes Unicode deben ser \\XXXX o \\+XXXXXX." + +#: parser/parser.c:497 scan.l:638 scan.l:654 scan.l:670 +#: utils/adt/varlena.c:6591 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "par sustituto (surrogate) Unicode no válido" + +#: parser/scansup.c:101 +#, fuzzy, c-format +#| msgid "identifier \"%s\" will be truncated to \"%s\"" +msgid "identifier \"%s\" will be truncated to \"%.*s\"" +msgstr "el identificador «%s» se truncará a «%s»" + +#: partitioning/partbounds.c:2821 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "la partición «%s» está en conflicto con la partición default «%s» existente" + +#: partitioning/partbounds.c:2870 partitioning/partbounds.c:2888 +#: partitioning/partbounds.c:2904 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "cada módulo de partición hash debe ser un factor del próximo mayor módulo" + +#: partitioning/partbounds.c:2871 partitioning/partbounds.c:2905 +#, c-format +msgid "The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\"." +msgstr "" + +#: partitioning/partbounds.c:2889 +#, c-format +msgid "The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\"." +msgstr "" + +#: partitioning/partbounds.c:3018 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "borde de rango vació especificado para la partición «%s»" + +#: partitioning/partbounds.c:3020 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "El límite inferior %s especificado es mayor o igual al límite superior %s." + +#: partitioning/partbounds.c:3132 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "la partición «%s» traslaparía con la partición «%s»" + +#: partitioning/partbounds.c:3249 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "se omitió recorrer la tabla foránea «%s» que es una partición de la partición default «%s»" + +#: partitioning/partbounds.c:4705 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "remanente en partición hash debe ser un entero no negativo" + +#: partitioning/partbounds.c:4729 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "«%s» es una tabla particionada por hash" + +#: partitioning/partbounds.c:4740 partitioning/partbounds.c:4857 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "el número de columnas de particionamiento (%d) no coincide con el número de llaves de particionamiento provistas (%d)" + +#: partitioning/partbounds.c:4762 +#, fuzzy, c-format +#| msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgid "column %d of the partition key has type %s, but supplied value is of type %s" +msgstr "la columna %d de la llave de particionamiento tiene tipo «%s», pero el valor dado es de tipo «%s»" + +#: partitioning/partbounds.c:4794 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "la columna %d de la llave de particionamiento tiene tipo «%s», pero el valor dado es de tipo «%s»" + +#: port/pg_sema.c:209 port/pg_shmem.c:668 port/posix_sema.c:209 +#: port/sysv_sema.c:327 port/sysv_shmem.c:668 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "no se pudo hacer stat al directorio de datos «%s»: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "no se pudo crear el segmento de memoria compartida: %m" + +#: port/pg_shmem.c:218 port/sysv_shmem.c:218 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "La llamada a sistema fallida fue shmget(key=%lu, size=%zu, 0%o)." + +#: port/pg_shmem.c:222 port/sysv_shmem.c:222 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Este error normalmente significa que la petición de un segmento de memoria compartida de PostgreSQL excedió el parámetro SHMMAX del kernel, o posiblemente que es menor que el parámetro SHMMIN del kernel.\n" +"La documentación de PostgreSQL contiene más información acerca de la configuración de memoria compartida." + +#: port/pg_shmem.c:229 port/sysv_shmem.c:229 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Este error normalmente significa que la petición de un segmento de memoria compartida de PostgreSQL excedió el parámetro SHMALL del kernel. Puede ser necesario reconfigurar el kernel con un SHMALL mayor.\n" +"La documentación de PostgreSQL contiene más información acerca de la configuración de memoria compartida." + +#: port/pg_shmem.c:235 port/sysv_shmem.c:235 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Este error *no* significa que se haya quedado sin espacio en disco. Ocurre cuando se han usado todos los IDs de memoria compartida disponibles, en cuyo caso puede incrementar el parámetro SHMMNI del kernel, o bien porque se ha alcanzado el límite total de memoria compartida.\n" +"La documentación de PostgreSQL contiene más información acerca de la configuración de memoria compartida." + +#: port/pg_shmem.c:606 port/sysv_shmem.c:606 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "no se pudo mapear memoria compartida anónima: %m" + +#: port/pg_shmem.c:608 port/sysv_shmem.c:608 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "Este error normalmente significa que la petición de un segmento de memoria compartida de PostgreSQL excedía la memoria disponible, el espacio de intercambio (swap), o las huge pages. Para reducir el tamaño de la petición (actualmente %zu bytes), reduzca el uso de memoria compartida de PostgreSQL, quizás reduciendo el parámetro shared_buffers o el parámetro max_connections." + +#: port/pg_shmem.c:676 port/sysv_shmem.c:676 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "las huge pages no están soportados en esta plataforma" + +#: port/pg_shmem.c:737 port/sysv_shmem.c:737 utils/init/miscinit.c:1167 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "el bloque de memoria compartida preexistente (clave %lu, ID %lu) aún está en uso" + +#: port/pg_shmem.c:740 port/sysv_shmem.c:740 utils/init/miscinit.c:1169 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Termine cualquier proceso de servidor asociado al directorio de datos «%s»." + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "no se pudo crear semáforos: %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "La llamada a sistema fallida fue semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:129 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"Este error *no* significa que se haya quedado sin espacio en disco.\n" +"Ocurre cuando se alcanza el límite del sistema del número de semáforos (SEMMNI), o bien cuando se excede el total de semáforos del sistema (SEMMNS).Necesita incrementar el parámetro respectivo del kernel. Alternativamente, reduzca el consumo de semáforos de PostgreSQL reduciendo el parámetro max_connections.\n" +"La documentación de PostgreSQL contiene más información acerca de cómo configurar su sistema para PostgreSQL." + +#: port/sysv_sema.c:159 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "Probablemente necesita incrementar el valor SEMVMX del kernel hasta al menos %d. Examine la documentación de PostgreSQL para obtener más detalles." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "no se pudo cargar dbghelp.dll, no se puede escribir el volcado de la caída\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "no fue posible cargar las funciones requeridas desde dbghelp.dll, no se puede escribir el volcado de la caída\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "no se pudo abrir el archivo del volcado de caída «%s» para escritura: código de error %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "se escribió el volcado de caída en el archivo «%s».\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "no se pudo escribir el volcado de caída al archivo «%s»: código de error %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "no se pudo crear tubería para escuchar señales para el PID %d: código de error %lu" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "no se pudo crear tubería para escuchar señales: código de error %lu; reintentando\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "no se pudo crear semáforo: código de error %lu" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "no se pudo bloquear semáforo: código de error %lu" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "no se pudo desbloquear semáforo: código de error %lu" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "no se pudo intentar-bloquear (try-lock) el semáforo: código de error %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:159 port/win32_shmem.c:171 +#: port/win32_shmem.c:187 +#, fuzzy, c-format +#| msgid "%s: could not open service \"%s\": error code %lu\n" +msgid "could not enable user right \"%s\": error code %lu" +msgstr "%s: no se pudo abrir el servicio «%s»: código de error %lu\n" + +#. translator: This is a term from Windows and should be translated to +#. match the Windows localization. +#. +#: port/win32_shmem.c:150 port/win32_shmem.c:159 port/win32_shmem.c:171 +#: port/win32_shmem.c:182 port/win32_shmem.c:184 port/win32_shmem.c:187 +#, fuzzy +#| msgid "Resource Usage / Memory" +msgid "Lock pages in memory" +msgstr "Uso de Recursos / Memoria" + +#: port/win32_shmem.c:152 port/win32_shmem.c:160 port/win32_shmem.c:172 +#: port/win32_shmem.c:188 +#, c-format +msgid "Failed system call was %s." +msgstr "La llamada a sistema fallida fue %s." + +#: port/win32_shmem.c:182 +#, fuzzy, c-format +#| msgid "could not parse limit \"%s\"" +msgid "could not enable user right \"%s\"" +msgstr "no se pudo interpretar el límite «%s»" + +#: port/win32_shmem.c:183 +#, fuzzy, c-format +#| msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgid "Assign user right \"%s\" to the Windows user account which runs PostgreSQL." +msgstr "Asigne el privilegio «Bloquear páginas en la memoria» a la cuenta de usuario de Windows que ejecuta PostgreSQL." + +#: port/win32_shmem.c:241 +#, c-format +msgid "the processor does not support large pages" +msgstr "el procesador no soporta páginas grandes" + +#: port/win32_shmem.c:310 port/win32_shmem.c:346 port/win32_shmem.c:364 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "no se pudo crear el segmento de memoria compartida: código de error %lu" + +#: port/win32_shmem.c:311 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "La llamada a sistema fallida fue CreateFileMapping(size=%zu, name=%s)." + +#: port/win32_shmem.c:336 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "el bloque de memoria compartida preexistente aún está en uso" + +#: port/win32_shmem.c:337 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "Verifique si hay procesos de servidor antiguos aún en funcionamiento, y termínelos." + +#: port/win32_shmem.c:347 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "La llamada a sistema fallida fue DuplicateHandle." + +#: port/win32_shmem.c:365 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "La llamada a sistema fallida fue MapViewOfFileEx." + +#: postmaster/autovacuum.c:411 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "no se pudo iniciar el lanzador autovacuum: %m" + +#: postmaster/autovacuum.c:1489 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "no se pudo lanzar el proceso «autovacuum worker»: %m" + +#: postmaster/autovacuum.c:2326 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "autovacuum: eliminando tabla temporal huérfana «%s.%s.%s»" + +#: postmaster/autovacuum.c:2555 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "vacuum automático de la tabla «%s.%s.%s»" + +#: postmaster/autovacuum.c:2558 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "análisis automático de la tabla «%s.%s.%s»" + +#: postmaster/autovacuum.c:2751 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "procesando elemento de tarea de la tabla «%s.%s.%s»" + +#: postmaster/autovacuum.c:3432 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "autovacuum no fue iniciado debido a un error de configuración" + +#: postmaster/autovacuum.c:3433 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "Active la opción «track_counts»." + +#: postmaster/bgworker.c:256 +#, c-format +msgid "inconsistent background worker state (max_worker_processes=%d, total_slots=%d)" +msgstr "" + +#: postmaster/bgworker.c:661 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "proceso ayudante «%s»: debe acoplarse a memoria compartida para poder solicitar una conexión a base de datos" + +#: postmaster/bgworker.c:670 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "proceso ayudante «%s»: no se puede solicitar una conexión a base de datos si está iniciando en el momento de inicio de postmaster" + +#: postmaster/bgworker.c:684 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "proceso ayudante «%s»: intervalo de reinicio no válido" + +#: postmaster/bgworker.c:699 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "proceso ayudante «%s»: los ayudantes paralelos no pueden ser configurados «restart»" + +#: postmaster/bgworker.c:723 tcop/postgres.c:3188 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "terminando el proceso ayudante «%s» debido a una orden del administrador" + +#: postmaster/bgworker.c:904 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "proceso ayudante «%s»: debe ser registrado en shared_preload_libraries" + +#: postmaster/bgworker.c:916 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "proceso ayudante «%s»: sólo los ayudantes dinámicos pueden pedir notificaciones" + +#: postmaster/bgworker.c:931 +#, c-format +msgid "too many background workers" +msgstr "demasiados procesos ayudantes" + +#: postmaster/bgworker.c:932 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "Hasta %d proceso ayudante puede registrarse con la configuración actual." +msgstr[1] "Hasta %d procesos ayudantes pueden registrarse con la configuración actual." + +# FIXME a %s would be nice here +#: postmaster/bgworker.c:936 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "Considere incrementar el parámetro de configuración «max_worker_processes»." + +#: postmaster/checkpointer.c:428 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "los puntos de control están ocurriendo con demasiada frecuencia (cada %d segundo)" +msgstr[1] "los puntos de control están ocurriendo con demasiada frecuencia (cada %d segundos)" + +# FIXME a %s would be nice here +#: postmaster/checkpointer.c:432 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "Considere incrementar el parámetro de configuración «max_wal_size»." + +#: postmaster/checkpointer.c:1056 +#, c-format +msgid "checkpoint request failed" +msgstr "falló la petición de punto de control" + +#: postmaster/checkpointer.c:1057 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "Vea los mensajes recientes en el registro del servidor para obtener más detalles." + +#: postmaster/pgarch.c:372 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode activado, pero archive_command no está definido" + +#: postmaster/pgarch.c:394 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "eliminando archivo de estado huérfano «%s»" + +#: postmaster/pgarch.c:404 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "la eliminación del archivo de estado huérfano «%s» falló demasiadas veces, se tratará de nuevo después" + +#: postmaster/pgarch.c:440 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "el archivado del archivo de WAL «%s» falló demasiadas veces, se tratará de nuevo más tarde" + +#: postmaster/pgarch.c:541 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "la orden de archivado falló con código de retorno %d" + +#: postmaster/pgarch.c:543 postmaster/pgarch.c:553 postmaster/pgarch.c:559 +#: postmaster/pgarch.c:568 +#, c-format +msgid "The failed archive command was: %s" +msgstr "La orden fallida era: «%s»" + +#: postmaster/pgarch.c:550 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "la orden de archivado fue terminada por una excepción 0x%X" + +#: postmaster/pgarch.c:552 postmaster/postmaster.c:3724 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "Vea el archivo «ntstatus.h» para una descripción del valor hexadecimal." + +#: postmaster/pgarch.c:557 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "la orden de archivado fue terminada por una señal %d: %s" + +#: postmaster/pgarch.c:566 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "la orden de archivado fue terminada con código %d no reconocido" + +#: postmaster/pgstat.c:417 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "no se pudo resolver «localhost»: %s" + +#: postmaster/pgstat.c:440 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "intentando otra dirección para el recolector de estadísticas" + +#: postmaster/pgstat.c:449 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "no se pudo crear el socket para el recolector de estadísticas: %m" + +#: postmaster/pgstat.c:461 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "no se pudo enlazar (bind) el socket para el recolector de estadísticas: %m" + +#: postmaster/pgstat.c:472 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "no se pudo obtener la dirección del socket de estadísticas: %m" + +#: postmaster/pgstat.c:488 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "no se pudo conectar el socket para el recolector de estadísticas: %m" + +#: postmaster/pgstat.c:509 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "no se pudo enviar el mensaje de prueba al recolector de estadísticas: %m" + +#: postmaster/pgstat.c:535 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "select() falló en el recolector de estadísticas: %m" + +#: postmaster/pgstat.c:550 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "el mensaje de prueba al recolector de estadísticas no ha sido recibido en el socket" + +#: postmaster/pgstat.c:565 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "no se pudo recibir el mensaje de prueba en el socket del recolector de estadísticas: %m" + +#: postmaster/pgstat.c:575 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "transmisión del mensaje de prueba incorrecta en el socket del recolector de estadísticas" + +#: postmaster/pgstat.c:598 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "no se pudo poner el socket de estadísticas en modo no bloqueante: %m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "desactivando el recolector de estadísticas por falla del socket" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "no se pudo crear el proceso para el recolector de estadísticas: %m" + +#: postmaster/pgstat.c:1459 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "destino de reset no reconocido: «%s»" + +#: postmaster/pgstat.c:1460 +#, fuzzy, c-format +#| msgid "Target must be \"archiver\" or \"bgwriter\"." +msgid "Target must be \"archiver\", \"bgwriter\" or \"wal\"." +msgstr "El destino debe ser «archiver» o «bgwriter»." + +#: postmaster/pgstat.c:3298 +#, c-format +msgid "could not read statistics message: %m" +msgstr "no se pudo leer un mensaje de estadísticas: %m" + +#: postmaster/pgstat.c:3644 postmaster/pgstat.c:3829 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "no se pudo abrir el archivo temporal de estadísticas «%s»: %m" + +#: postmaster/pgstat.c:3739 postmaster/pgstat.c:3874 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "no se pudo escribir el archivo temporal de estadísticas «%s»: %m" + +#: postmaster/pgstat.c:3748 postmaster/pgstat.c:3883 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "no se pudo cerrar el archivo temporal de estadísticas «%s»: %m" + +#: postmaster/pgstat.c:3756 postmaster/pgstat.c:3891 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "no se pudo cambiar el nombre al archivo temporal de estadísticas de «%s» a «%s»: %m" + +#: postmaster/pgstat.c:3989 postmaster/pgstat.c:4255 postmaster/pgstat.c:4412 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "no se pudo abrir el archivo de estadísticas «%s»: %m" + +#: postmaster/pgstat.c:4001 postmaster/pgstat.c:4011 postmaster/pgstat.c:4032 +#: postmaster/pgstat.c:4043 postmaster/pgstat.c:4054 postmaster/pgstat.c:4076 +#: postmaster/pgstat.c:4091 postmaster/pgstat.c:4161 postmaster/pgstat.c:4192 +#: postmaster/pgstat.c:4267 postmaster/pgstat.c:4287 postmaster/pgstat.c:4305 +#: postmaster/pgstat.c:4321 postmaster/pgstat.c:4339 postmaster/pgstat.c:4355 +#: postmaster/pgstat.c:4424 postmaster/pgstat.c:4436 postmaster/pgstat.c:4448 +#: postmaster/pgstat.c:4459 postmaster/pgstat.c:4470 postmaster/pgstat.c:4495 +#: postmaster/pgstat.c:4522 postmaster/pgstat.c:4535 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "el archivo de estadísticas «%s» está corrupto" + +#: postmaster/pgstat.c:4644 +#, c-format +msgid "statistics collector's time %s is later than backend local time %s" +msgstr "" + +#: postmaster/pgstat.c:4667 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "usando estadísticas añejas en vez de actualizadas porque el recolector de estadísticas no está respondiendo" + +#: postmaster/pgstat.c:4794 +#, c-format +msgid "stats_timestamp %s is later than collector's time %s for database %u" +msgstr "" + +#: postmaster/pgstat.c:5004 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "el hash de bases de datos se corrompió durante la finalización; abortando" + +#: postmaster/postmaster.c:745 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: argumento no válido para la opción -f: «%s»\n" + +#: postmaster/postmaster.c:824 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: argumento no válido para la opción -t: «%s»\n" + +#: postmaster/postmaster.c:875 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: argumento no válido: «%s»\n" + +#: postmaster/postmaster.c:917 +#, c-format +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) debe ser menor que max_connections (%d)\n" + +#: postmaster/postmaster.c:924 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "el archivador de WAL no puede activarse cuando wal_level es «minimal»" + +#: postmaster/postmaster.c:927 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "el flujo de WAL (max_wal_senders > 0) requiere wal_level «replica» o «logical»" + +#: postmaster/postmaster.c:935 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: las tablas de palabras clave de fecha no son válidas, arréglelas\n" + +#: postmaster/postmaster.c:1052 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "no se pudo crear el port E/S de reporte de completitud para la cola de procesos hijos" + +#: postmaster/postmaster.c:1117 +#, c-format +msgid "ending log output to stderr" +msgstr "terminando la salida de registro a stderr" + +#: postmaster/postmaster.c:1118 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "La salida futura del registro será enviada al destino de log «%s»." + +#: postmaster/postmaster.c:1129 +#, c-format +msgid "starting %s" +msgstr "iniciando %s" + +#: postmaster/postmaster.c:1158 postmaster/postmaster.c:1257 +#: utils/init/miscinit.c:1627 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "la sintaxis de lista no es válida para el parámetro «%s»" + +#: postmaster/postmaster.c:1189 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "no se pudo crear el socket de escucha para «%s»" + +#: postmaster/postmaster.c:1195 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "no se pudo crear ningún socket TCP/IP" + +#: postmaster/postmaster.c:1227 +#, fuzzy, c-format +#| msgid "pgpipe: getsockname() failed: error code %d" +msgid "DNSServiceRegister() failed: error code %ld" +msgstr "pgpipe: getsockname() falló: código de error %d" + +#: postmaster/postmaster.c:1279 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "no se pudo crear el socket de dominio Unix en el directorio «%s»" + +#: postmaster/postmaster.c:1285 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "no se pudo crear ningún socket de dominio Unix" + +#: postmaster/postmaster.c:1297 +#, c-format +msgid "no socket created for listening" +msgstr "no se creó el socket de atención" + +#: postmaster/postmaster.c:1328 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: no se pudo cambiar los permisos del archivo de PID externo «%s»: %s\n" + +#: postmaster/postmaster.c:1332 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: no pudo escribir en el archivo externo de PID «%s»: %s\n" + +#: postmaster/postmaster.c:1365 utils/init/postinit.c:216 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "no se pudo cargar pg_hba.conf" + +#: postmaster/postmaster.c:1391 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "postmaster se volvió multi-hilo durante la partida" + +#: postmaster/postmaster.c:1392 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "Defina la variable de ambiente LC_ALL a un valor válido." + +#: postmaster/postmaster.c:1487 +#, fuzzy, c-format +#| msgid "%s: could not locate my own executable path\n" +msgid "%s: could not locate my own executable path" +msgstr "%s: no se pudo localizar la ruta de mi propio ejecutable\n" + +#: postmaster/postmaster.c:1494 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: no se pudo localizar el ejecutable postgres correspondiente" + +#: postmaster/postmaster.c:1517 utils/misc/tzparser.c:340 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "Esto puede indicar una instalación de PostgreSQL incompleta, o que el archivo «%s» ha sido movido de la ubicación adecuada." + +#: postmaster/postmaster.c:1544 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: no se pudo encontrar el sistema de base de datos\n" +"Se esperaba encontrar en el directorio PGDATA «%s»,\n" +"pero no se pudo abrir el archivo «%s»: %s\n" + +#: postmaster/postmaster.c:1721 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "select() falló en postmaster: %m" + +#: postmaster/postmaster.c:1857 +#, c-format +msgid "issuing SIGKILL to recalcitrant children" +msgstr "" + +#: postmaster/postmaster.c:1878 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "ejecutando un apagado inmediato porque el archivo de bloqueo del directorio de datos no es válido" + +#: postmaster/postmaster.c:1981 postmaster/postmaster.c:2009 +#, c-format +msgid "incomplete startup packet" +msgstr "el paquete de inicio está incompleto" + +#: postmaster/postmaster.c:1993 +#, c-format +msgid "invalid length of startup packet" +msgstr "el de paquete de inicio tiene largo incorrecto" + +#: postmaster/postmaster.c:2048 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "no se pudo enviar la respuesta de negociación SSL: %m" + +#: postmaster/postmaster.c:2080 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "no se pudo enviar la respuesta de negociación GSSAPI: %m" + +#: postmaster/postmaster.c:2110 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "el protocolo %u.%u no está soportado: servidor soporta %u.0 hasta %u.%u" + +#: postmaster/postmaster.c:2174 utils/misc/guc.c:7112 utils/misc/guc.c:7148 +#: utils/misc/guc.c:7218 utils/misc/guc.c:8550 utils/misc/guc.c:11506 +#: utils/misc/guc.c:11547 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "valor no válido para el parámetro «%s»: «%s»" + +#: postmaster/postmaster.c:2177 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "Los valores válidos son: «false», 0, «true», 1, «database»." + +#: postmaster/postmaster.c:2222 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "el paquete de inicio no es válido: se esperaba un terminador en el último byte" + +#: postmaster/postmaster.c:2239 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "no se especifica un nombre de usuario en el paquete de inicio" + +#: postmaster/postmaster.c:2303 +#, c-format +msgid "the database system is starting up" +msgstr "el sistema de base de datos está iniciándose" + +#: postmaster/postmaster.c:2309 +#, fuzzy, c-format +#| msgid "database system is ready to accept connections" +msgid "the database system is not yet accepting connections" +msgstr "el sistema de bases de datos está listo para aceptar conexiones" + +#: postmaster/postmaster.c:2310 +#, fuzzy, c-format +#| msgid "consistent recovery state reached at %X/%X" +msgid "Consistent recovery state has not been yet reached." +msgstr "el estado de recuperación consistente fue alcanzado en %X/%X" + +#: postmaster/postmaster.c:2314 +#, fuzzy, c-format +#| msgid "database system is ready to accept connections" +msgid "the database system is not accepting connections" +msgstr "el sistema de bases de datos está listo para aceptar conexiones" + +#: postmaster/postmaster.c:2315 +#, c-format +msgid "Hot standby mode is disabled." +msgstr "" + +#: postmaster/postmaster.c:2320 +#, c-format +msgid "the database system is shutting down" +msgstr "el sistema de base de datos está apagándose" + +#: postmaster/postmaster.c:2325 +#, c-format +msgid "the database system is in recovery mode" +msgstr "el sistema de base de datos está en modo de recuperación" + +#: postmaster/postmaster.c:2330 storage/ipc/procarray.c:463 +#: storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:361 +#, c-format +msgid "sorry, too many clients already" +msgstr "lo siento, ya tenemos demasiados clientes" + +#: postmaster/postmaster.c:2420 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "llave incorrecta en la petición de cancelación para el proceso %d" + +#: postmaster/postmaster.c:2432 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "el PID %d en la petición de cancelación no coincidió con ningún proceso" + +#: postmaster/postmaster.c:2686 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "se recibió SIGHUP, volviendo a cargar archivos de configuración" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2712 postmaster/postmaster.c:2716 +#, c-format +msgid "%s was not reloaded" +msgstr "%s no fue vuelto a cargar" + +#: postmaster/postmaster.c:2726 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "la configuración SSL no fue vuelta a cargar" + +#: postmaster/postmaster.c:2782 +#, c-format +msgid "received smart shutdown request" +msgstr "se recibió petición de apagado inteligente" + +#: postmaster/postmaster.c:2828 +#, c-format +msgid "received fast shutdown request" +msgstr "se recibió petición de apagado rápido" + +#: postmaster/postmaster.c:2846 +#, c-format +msgid "aborting any active transactions" +msgstr "abortando transacciones activas" + +#: postmaster/postmaster.c:2870 +#, c-format +msgid "received immediate shutdown request" +msgstr "se recibió petición de apagado inmediato" + +#: postmaster/postmaster.c:2947 +#, c-format +msgid "shutdown at recovery target" +msgstr "apagándose al alcanzar el destino de recuperación" + +#: postmaster/postmaster.c:2965 postmaster/postmaster.c:3001 +msgid "startup process" +msgstr "proceso de inicio" + +#: postmaster/postmaster.c:2968 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "abortando el inicio debido a una falla en el procesamiento de inicio" + +#: postmaster/postmaster.c:3043 +#, c-format +msgid "database system is ready to accept connections" +msgstr "el sistema de bases de datos está listo para aceptar conexiones" + +#: postmaster/postmaster.c:3064 +msgid "background writer process" +msgstr "proceso background writer" + +#: postmaster/postmaster.c:3118 +msgid "checkpointer process" +msgstr "proceso checkpointer" + +#: postmaster/postmaster.c:3134 +msgid "WAL writer process" +msgstr "proceso escritor de WAL" + +#: postmaster/postmaster.c:3149 +msgid "WAL receiver process" +msgstr "proceso receptor de WAL" + +#: postmaster/postmaster.c:3164 +msgid "autovacuum launcher process" +msgstr "proceso lanzador de autovacuum" + +#: postmaster/postmaster.c:3182 +msgid "archiver process" +msgstr "proceso de archivado" + +#: postmaster/postmaster.c:3197 +msgid "statistics collector process" +msgstr "recolector de estadísticas" + +#: postmaster/postmaster.c:3211 +msgid "system logger process" +msgstr "proceso de log" + +#: postmaster/postmaster.c:3275 +#, c-format +msgid "background worker \"%s\"" +msgstr "proceso ayudante «%s»" + +#: postmaster/postmaster.c:3359 postmaster/postmaster.c:3379 +#: postmaster/postmaster.c:3386 postmaster/postmaster.c:3404 +msgid "server process" +msgstr "proceso de servidor" + +#: postmaster/postmaster.c:3458 +#, c-format +msgid "terminating any other active server processes" +msgstr "terminando todos los otros procesos de servidor activos" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3711 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) terminó con código de salida %d" + +#: postmaster/postmaster.c:3713 postmaster/postmaster.c:3725 +#: postmaster/postmaster.c:3735 postmaster/postmaster.c:3746 +#, c-format +msgid "Failed process was running: %s" +msgstr "El proceso que falló estaba ejecutando: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3722 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) fue terminado por una excepción 0x%X" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3732 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) fue terminado por una señal %d: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3744 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) terminó con código %d no reconocido" + +#: postmaster/postmaster.c:3959 +#, c-format +msgid "abnormal database system shutdown" +msgstr "apagado anormal del sistema de bases de datos" + +#: postmaster/postmaster.c:3997 +#, fuzzy, c-format +#| msgid "aborting startup due to startup process failure" +msgid "shutting down due to startup process failure" +msgstr "abortando el inicio debido a una falla en el procesamiento de inicio" + +#: postmaster/postmaster.c:4003 +#, c-format +msgid "shutting down because restart_after_crash is off" +msgstr "" + +#: postmaster/postmaster.c:4015 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "todos los procesos fueron terminados; reinicializando" + +#: postmaster/postmaster.c:4189 postmaster/postmaster.c:5548 +#: postmaster/postmaster.c:5939 +#, c-format +msgid "could not generate random cancel key" +msgstr "no se pudo generar una llave de cancelación aleatoria" + +#: postmaster/postmaster.c:4243 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "no se pudo lanzar el nuevo proceso para la conexión: %m" + +#: postmaster/postmaster.c:4285 +msgid "could not fork new process for connection: " +msgstr "no se pudo lanzar el nuevo proceso para la conexión: " + +#: postmaster/postmaster.c:4391 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "conexión recibida: host=%s port=%s" + +#: postmaster/postmaster.c:4396 +#, c-format +msgid "connection received: host=%s" +msgstr "conexión recibida: host=%s" + +#: postmaster/postmaster.c:4639 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "no se pudo lanzar el proceso servidor «%s»: %m" + +#: postmaster/postmaster.c:4697 +#, fuzzy, c-format +#| msgid "could not close handle to backend parameter variables: error code %lu\n" +msgid "could not create backend parameter file mapping: error code %lu" +msgstr "no se pudo cerrar el archivo de variables de servidor: código de error %lu\n" + +#: postmaster/postmaster.c:4706 +#, fuzzy, c-format +#| msgid "could not map view of backend variables: error code %lu\n" +msgid "could not map backend parameter memory: error code %lu" +msgstr "no se pudo mapear la vista del archivo de variables: código de error %lu\n" + +#: postmaster/postmaster.c:4733 +#, fuzzy, c-format +#| msgid "command too long\n" +msgid "subprocess command line too long" +msgstr "orden demasiado larga\n" + +#: postmaster/postmaster.c:4751 +#, fuzzy, c-format +#| msgid "pgpipe: getsockname() failed: error code %d" +msgid "CreateProcess() call failed: %m (error code %lu)" +msgstr "pgpipe: getsockname() falló: código de error %d" + +#: postmaster/postmaster.c:4778 +#, fuzzy, c-format +#| msgid "could not unmap view of backend variables: error code %lu\n" +msgid "could not unmap view of backend parameter file: error code %lu" +msgstr "no se pudo desmapear la vista del archivo de variables: código de error %lu\n" + +#: postmaster/postmaster.c:4782 +#, fuzzy, c-format +#| msgid "could not close handle to backend parameter variables: error code %lu\n" +msgid "could not close handle to backend parameter file: error code %lu" +msgstr "no se pudo cerrar el archivo de variables de servidor: código de error %lu\n" + +#: postmaster/postmaster.c:4804 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "renunciar después de demasiados intentos de reservar memoria compartida" + +#: postmaster/postmaster.c:4805 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Esto podría deberse a ASLR o un software antivirus." + +#: postmaster/postmaster.c:4995 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "No se pudo cargar la configuración SSL en proceso secundario" + +#: postmaster/postmaster.c:5121 +#, c-format +msgid "Please report this to <%s>." +msgstr "Por favor reporte esto a <%s>." + +#: postmaster/postmaster.c:5208 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "el sistema de bases de datos está listo para aceptar conexiones de sólo lectura" + +#: postmaster/postmaster.c:5472 +#, c-format +msgid "could not fork startup process: %m" +msgstr "no se pudo lanzar el proceso de inicio: %m" + +#: postmaster/postmaster.c:5476 +#, fuzzy, c-format +#| msgid "could not fork WAL receiver process: %m" +msgid "could not fork archiver process: %m" +msgstr "no se pudo lanzar el proceso receptor de WAL: %m" + +#: postmaster/postmaster.c:5480 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "no se pudo lanzar el background writer: %m" + +#: postmaster/postmaster.c:5484 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "no se pudo lanzar el checkpointer: %m" + +#: postmaster/postmaster.c:5488 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "no se pudo lanzar el proceso escritor de WAL: %m" + +#: postmaster/postmaster.c:5492 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "no se pudo lanzar el proceso receptor de WAL: %m" + +#: postmaster/postmaster.c:5496 +#, c-format +msgid "could not fork process: %m" +msgstr "no se pudo lanzar el proceso: %m" + +#: postmaster/postmaster.c:5697 postmaster/postmaster.c:5720 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "el requerimiento de conexión a base de datos no fue indicado durante el registro" + +#: postmaster/postmaster.c:5704 postmaster/postmaster.c:5727 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "modo de procesamiento no válido en proceso ayudante" + +#: postmaster/postmaster.c:5812 +#, c-format +msgid "could not fork worker process: %m" +msgstr "no se pudo lanzar el proceso ayudante: %m" + +#: postmaster/postmaster.c:5925 +#, c-format +msgid "no slot available for new worker process" +msgstr "no hay slot disponible para un nuevo proceso ayudante" + +#: postmaster/postmaster.c:6259 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "no se pudo duplicar el socket %d para su empleo en el backend: código de error %d" + +#: postmaster/postmaster.c:6291 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "no se pudo crear el socket heradado: código de error %d\n" + +#: postmaster/postmaster.c:6320 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "no se pudo abrir el archivo de variables de servidor «%s»: %s\n" + +#: postmaster/postmaster.c:6327 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "no se pudo leer el archivo de variables de servidor «%s»: %s\n" + +#: postmaster/postmaster.c:6336 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "no se pudo eliminar el archivo «%s»: %s\n" + +#: postmaster/postmaster.c:6353 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "no se pudo mapear la vista del archivo de variables: código de error %lu\n" + +#: postmaster/postmaster.c:6362 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "no se pudo desmapear la vista del archivo de variables: código de error %lu\n" + +#: postmaster/postmaster.c:6369 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "no se pudo cerrar el archivo de variables de servidor: código de error %lu\n" + +#: postmaster/postmaster.c:6546 +#, c-format +msgid "could not read exit code for process\n" +msgstr "no se pudo leer el código de salida del proceso\n" + +#: postmaster/postmaster.c:6551 +#, c-format +msgid "could not post child completion status\n" +msgstr "no se pudo publicar el estado de completitud del proceso hijo\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "no se pudo leer desde la tubería de log: %m" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "no se pudo crear la tubería para syslog: %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "no se pudo crear el proceso de log: %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "redirigiendo la salida del registro al proceso recolector de registro" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "La salida futura del registro aparecerá en el directorio «%s»." + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "no se pudo redirigir stdout: %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "no se pudo redirigir stderr: %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "no se pudo escribir al archivo de log: %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "no se pudo abrir el archivo de registro «%s»: %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "desactivando rotación automática (use SIGHUP para reactivarla)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "no se pudo determinar qué ordenamiento usar para la expresión regular" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "los ordenamientos no determinísticos no están soportados para expresiones regulares" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "timeline %u no válido" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "posición de inicio de flujo de WAL no válida" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "una cadena de caracteres entre comillas está inconclusa" + +#: replication/backup_manifest.c:255 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "se esperaba el timeline de término %u pero se encontró el tieneline %u" + +#: replication/backup_manifest.c:272 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "se esperaba el timeline de inicio %u pero se encontró el timeline %u" + +#: replication/backup_manifest.c:299 +#, c-format +msgid "start timeline %u not found in history of timeline %u" +msgstr "el timeline de inicio %u no fue encontrado en la historia del timeline %u" + +#: replication/backup_manifest.c:352 +#, c-format +msgid "could not rewind temporary file" +msgstr "no se puede rebobinar el archivo temporal" + +#: replication/backup_manifest.c:379 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "no se pudo leer del archivo temporal: %m" + +#: replication/basebackup.c:546 +#, c-format +msgid "could not find any WAL files" +msgstr "no se pudo encontrar ningún archivo de WAL" + +#: replication/basebackup.c:561 replication/basebackup.c:577 +#: replication/basebackup.c:586 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "no se pudo encontrar archivo de WAL «%s»" + +#: replication/basebackup.c:629 replication/basebackup.c:659 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "tamaño del archivo WAL «%s» inesperado" + +#: replication/basebackup.c:644 replication/basebackup.c:1771 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "el respaldo base no pudo enviar datos, abortando el respaldo" + +#: replication/basebackup.c:722 +#, fuzzy, c-format +#| msgid "%lld total checksum verification failures" +msgid "%lld total checksum verification failure" +msgid_plural "%lld total checksum verification failures" +msgstr[0] "%lld fallas de verificación de suma de comprobación en total" +msgstr[1] "%lld fallas de verificación de suma de comprobación en total" + +#: replication/basebackup.c:729 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "falla en verificación de checksums durante respaldo base" + +#: replication/basebackup.c:789 replication/basebackup.c:798 +#: replication/basebackup.c:807 replication/basebackup.c:816 +#: replication/basebackup.c:825 replication/basebackup.c:836 +#: replication/basebackup.c:853 replication/basebackup.c:862 +#: replication/basebackup.c:874 replication/basebackup.c:898 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "nombre de opción «%s» duplicada" + +#: replication/basebackup.c:842 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d está fuera del rango aceptable para el parámetro «%s» (%d .. %d)" + +#: replication/basebackup.c:887 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "opción de manifiesto «%s» no reconocida" + +#: replication/basebackup.c:903 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "algoritmo de suma de comprobación no reconocido: \"%s\"" + +#: replication/basebackup.c:918 +#, fuzzy, c-format +#| msgid "manifest checksum mismatch" +msgid "manifest checksums require a backup manifest" +msgstr "discordancia en la suma de comprobación del manifiesto" + +#: replication/basebackup.c:1519 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "omitiendo el archivo especial «%s»" + +#: replication/basebackup.c:1640 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "número de segmento %d no válido en archivo «%s»" + +#: replication/basebackup.c:1678 +#, fuzzy, c-format +#| msgid "could not verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgid "could not verify checksum in file \"%s\", block %u: read buffer size %d and page size %d differ" +msgstr "no se pudo verificar el checksum en el archivo «%s», bloque %d: el tamaño leído %d y el tamaño de página %d difieren" + +#: replication/basebackup.c:1751 +#, fuzzy, c-format +#| msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgid "checksum verification failed in file \"%s\", block %u: calculated %X but expected %X" +msgstr "verificación de checksums falló en archivo «%s», bloque %d: calculado %X pero se esperaba %X" + +#: replication/basebackup.c:1758 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "subsiguientes fallas de verificación de checksums en el archivo «%s» no se reportarán" + +#: replication/basebackup.c:1816 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "el archivo «%s» tiene un total de %d falla de verificación de checksum" +msgstr[1] "el archivo «%s» tiene un total de %d fallas de verificación de checksums" + +#: replication/basebackup.c:1852 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "nombre de archivo demasiado largo para el formato tar: «%s»" + +#: replication/basebackup.c:1857 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "destino de enlace simbólico demasiado largo para el formato tar: nombre de archivo «%s», destino «%s»" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, fuzzy, c-format +#| msgid "could not clear search_path: %s" +msgid "could not clear search path: %s" +msgstr "no se pudo limpiar search_path: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:256 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "sintaxis de cadena de conexión no válida: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:281 +#, c-format +msgid "could not parse connection string: %s" +msgstr "no se pudo interpretar la cadena de conexión: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:353 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "no se pudo recibir el identificador de sistema y el ID de timeline del servidor primario: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:364 +#: replication/libpqwalreceiver/libpqwalreceiver.c:588 +#, c-format +msgid "invalid response from primary server" +msgstr "respuesta no válida del servidor primario" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:365 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "No se pudo identificar el sistema: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d o más campos." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:440 +#: replication/libpqwalreceiver/libpqwalreceiver.c:446 +#: replication/libpqwalreceiver/libpqwalreceiver.c:475 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "no se pudo iniciar el flujo de WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:498 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "no se pudo enviar el mensaje fin-de-flujo al primario: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:520 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "conjunto de resultados inesperado después del fin-de-flujo" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:534 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "ocurrió un error mientras se apagaba el flujo COPY: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:543 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "ocurrió un error mientras se leía la orden de flujo: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 +#: replication/libpqwalreceiver/libpqwalreceiver.c:785 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "resultado inesperado después de CommandComplete: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:577 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "no se pudo recibir el archivo de historia de timeline del servidor primario: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:589 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "Se esperaba 1 tupla con 2 campos, se obtuvieron %d tuplas con %d campos." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:749 +#: replication/libpqwalreceiver/libpqwalreceiver.c:800 +#: replication/libpqwalreceiver/libpqwalreceiver.c:806 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "no se pudo recibir datos desde el flujo de WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:825 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "no se pudo enviar datos al flujo de WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:878 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "no se pudo create el slot de replicación «%s»: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:923 +#, c-format +msgid "invalid query response" +msgstr "respuesta no válida a consulta" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:924 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "Se esperaban %d campos, se obtuvieron %d campos." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:994 +#, c-format +msgid "the query interface requires a database connection" +msgstr "la interfaz de consulta requiere una conexión a base de datos" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1025 +msgid "empty query" +msgstr "consulta vacía" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1031 +#, fuzzy +#| msgid "unexpected delimiter" +msgid "unexpected pipeline mode" +msgstr "delimitador inesperado" + +#: replication/logical/launcher.c:286 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "no se pueden iniciar procesos ayudantes de replicación cuando max_replication_slots = 0" + +#: replication/logical/launcher.c:366 +#, c-format +msgid "out of logical replication worker slots" +msgstr "se agotaron los slots de procesos ayudantes de replicación" + +#: replication/logical/launcher.c:367 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "Puede ser necesario incrementar max_logical_replication_workers." + +#: replication/logical/launcher.c:422 +#, c-format +msgid "out of background worker slots" +msgstr "se acabaron los slots de procesos ayudante" + +#: replication/logical/launcher.c:423 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "Puede ser necesario incrementar max_worker_processes." + +#: replication/logical/launcher.c:577 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "el slot del worker de replicación lógica %d está vacío, no se puede adjuntar" + +#: replication/logical/launcher.c:586 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "el slot de replicación lógica %d ya está siendo utilizado por otro worker, no se puede adjuntar" + +# FIXME see slot.c:779. See also postmaster.c:835 +#: replication/logical/logical.c:115 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "la decodificación lógica requiere wal_level >= logical" + +#: replication/logical/logical.c:120 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "decodificación lógica requiere una conexión a una base de datos" + +#: replication/logical/logical.c:138 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "la decodificación lógica no puede ejecutarse durante la recuperación" + +#: replication/logical/logical.c:347 replication/logical/logical.c:499 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "no se puede usar un slot de replicación física para decodificación lógica" + +#: replication/logical/logical.c:352 replication/logical/logical.c:504 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "el slot de replicación «%s» no fue creado en esta base de datos" + +#: replication/logical/logical.c:359 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "no se puede crear un slot de replicación lógica en una transacción que ha efectuado escrituras" + +#: replication/logical/logical.c:549 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "iniciando la decodificación lógica para el slot «%s»" + +#: replication/logical/logical.c:551 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Transacciones en flujo comprometiendo después de %X/%X, leyendo WAL desde %X/%X." + +#: replication/logical/logical.c:696 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "slot «%s», plugin de salida «%s», en el callback %s, LSN asociado %X/%X" + +# FIXME must quote callback name? Need a translator: comment? +#: replication/logical/logical.c:702 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "slot «%s», plugin de salida «%s», en el callback %s" + +#: replication/logical/logical.c:868 +#, c-format +msgid "logical replication at prepare time requires begin_prepare_cb callback" +msgstr "" + +#: replication/logical/logical.c:911 +#, c-format +msgid "logical replication at prepare time requires prepare_cb callback" +msgstr "" + +#: replication/logical/logical.c:954 +#, c-format +msgid "logical replication at prepare time requires commit_prepared_cb callback" +msgstr "" + +#: replication/logical/logical.c:998 +#, c-format +msgid "logical replication at prepare time requires rollback_prepared_cb callback" +msgstr "" + +#: replication/logical/logical.c:1220 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_start_cb callback" +msgstr "decodificación lógica requiere una conexión a una base de datos" + +#: replication/logical/logical.c:1266 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_stop_cb callback" +msgstr "decodificación lógica requiere una conexión a una base de datos" + +#: replication/logical/logical.c:1305 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_abort_cb callback" +msgstr "decodificación lógica requiere una conexión a una base de datos" + +#: replication/logical/logical.c:1348 +#, c-format +msgid "logical streaming at prepare time requires a stream_prepare_cb callback" +msgstr "" + +#: replication/logical/logical.c:1387 +#, c-format +msgid "logical streaming requires a stream_commit_cb callback" +msgstr "" + +#: replication/logical/logical.c:1433 +#, fuzzy, c-format +#| msgid "logical decoding requires a database connection" +msgid "logical streaming requires a stream_change_cb callback" +msgstr "decodificación lógica requiere una conexión a una base de datos" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "debe ser superusuario o rol de replicación para usar slots de replicación" + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "el nombre de slot no debe ser null" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "el array de opciones no debe ser null" + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "el array debe ser unidimensional" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "el array no debe contener nulls" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 +#: utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "el array debe tener un número par de elementos" + +#: replication/logical/logicalfuncs.c:251 +#, fuzzy, c-format +#| msgid "cannot change relation \"%s\"" +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "no se puede cambiar la relación «%s»" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:650 +#, fuzzy, c-format +#| msgid "This slot has never previously reserved WAL, or has been invalidated." +msgid "This slot has never previously reserved WAL, or it has been invalidated." +msgstr "Este slot nunca ha reservado WAL previamente, o ha sido invalidado." + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "el plugin de salida de decodificación lógica «%s» produce salida binaria, pero «%s» espera datos textuales" + +#: replication/logical/origin.c:188 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "no se puede consultar o manipular orígenes de replicación cuando max_replication_slots = 0" + +#: replication/logical/origin.c:193 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "no se puede manipular orígenes de replicación durante la recuperación" + +#: replication/logical/origin.c:228 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "no existe el origen de replicación «%s»" + +#: replication/logical/origin.c:319 +#, c-format +msgid "could not find free replication origin OID" +msgstr "no se pudo encontrar un OID de origen de replicación libre" + +#: replication/logical/origin.c:355 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "no se pudo eliminar el origen de replicación con OID %d, en uso por el PID %d" + +#: replication/logical/origin.c:476 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "el origen de replicación con OID %u no existe" + +#: replication/logical/origin.c:741 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "el checkpoint de replicación tiene número mágico erróneo %u en lugar de %u" + +#: replication/logical/origin.c:782 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "no se pudo encontrar una estructura de replicación libre, incremente max_replication_slots" + +#: replication/logical/origin.c:790 +#, fuzzy, c-format +#| msgid "recovery restart point at %X/%X" +msgid "recovered replication state of node %u to %X/%X" +msgstr "restartpoint de recuperación en %X/%X" + +#: replication/logical/origin.c:800 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "el checkpoint del slot de replicación tiene suma de verificación errónea %u, se esperaba %u" + +#: replication/logical/origin.c:928 replication/logical/origin.c:1114 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "el origen de replicación con OID %d ya está activo para el PID %d" + +#: replication/logical/origin.c:939 replication/logical/origin.c:1126 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "no se pudo encontrar un slot libre para el estado del origen de replicación con OID %u" + +#: replication/logical/origin.c:941 replication/logical/origin.c:1128 +#: replication/slot.c:1865 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "Aumente max_replication_slots y reintente." + +#: replication/logical/origin.c:1085 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "no se puede establecer un destino de replicación cuando ya hay uno definido" + +#: replication/logical/origin.c:1165 replication/logical/origin.c:1377 +#: replication/logical/origin.c:1397 +#, c-format +msgid "no replication origin is configured" +msgstr "no hay un destino de replicación configurado" + +#: replication/logical/origin.c:1248 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "el nombre de origen de replicación «%s» está reservado" + +#: replication/logical/origin.c:1250 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "Los nombres de origen que empiezan con «pg_» están reservados." + +#: replication/logical/relation.c:248 +#, c-format +msgid "\"%s\"" +msgstr "" + +#: replication/logical/relation.c:251 +#, c-format +msgid ", \"%s\"" +msgstr "" + +#: replication/logical/relation.c:257 +#, fuzzy, c-format +#| msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgid "logical replication target relation \"%s.%s\" is missing replicated column: %s" +msgid_plural "logical replication target relation \"%s.%s\" is missing replicated columns: %s" +msgstr[0] "a la relación destino de replicación lógica «%s.%s» le faltan algunas columnas replicadas" +msgstr[1] "a la relación destino de replicación lógica «%s.%s» le faltan algunas columnas replicadas" + +#: replication/logical/relation.c:337 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "la relación destino de replicación lógica «%s.%s» no existe" + +#: replication/logical/relation.c:418 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "la relación de destino de replicación lógica «%s.%s» usa columnas de sistemas en el índice REPLICA IDENTITY" + +#: replication/logical/reorderbuffer.c:3777 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "no se pudo escribir al archivo de datos para el XID %u: %m" + +#: replication/logical/reorderbuffer.c:4120 +#: replication/logical/reorderbuffer.c:4145 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "no se pudo leer desde el archivo de desborde de reorderbuffer: %m" + +#: replication/logical/reorderbuffer.c:4124 +#: replication/logical/reorderbuffer.c:4149 +#, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "no se pudo leer desde el archivo de desborde de reorderbuffer: se leyeron sólo %d en ve de %u bytes" + +#: replication/logical/reorderbuffer.c:4397 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "no se pudo borrar el archivo «%s» durante la eliminación de pg_replslot/%s/xid*: %m" + +# FIXME almost duplicated again!? +#: replication/logical/reorderbuffer.c:4887 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "no se pudo leer del archivo «%s»: se leyeron %d en lugar de %d bytes" + +#: replication/logical/snapbuild.c:588 +#, c-format +msgid "initial slot snapshot too large" +msgstr "el snapshot inicial del slot es demasiado grande" + +# FIXME: snapshot? instantánea? +#: replication/logical/snapbuild.c:642 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "se exportó un snapshot de decodificación lógica: «%s» con %u ID de transacción" +msgstr[1] "se exportó un snapshot de decodificación lógica: «%s» con %u IDs de transacción" + +#: replication/logical/snapbuild.c:1254 replication/logical/snapbuild.c:1347 +#: replication/logical/snapbuild.c:1878 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "la decodificación lógica encontró un punto consistente en %X/%X" + +#: replication/logical/snapbuild.c:1256 +#, c-format +msgid "There are no running transactions." +msgstr "No hay transacciones en ejecución." + +#: replication/logical/snapbuild.c:1298 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "decodificación lógica encontró punto de inicio en %X/%X" + +#: replication/logical/snapbuild.c:1300 replication/logical/snapbuild.c:1324 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Esperando que las (aproximadamente %d) transacciones más antiguas que %u terminen." + +#: replication/logical/snapbuild.c:1322 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "la decodificación lógica encontró un punto consistente inicial en %X/%X" + +#: replication/logical/snapbuild.c:1349 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Ya no hay transacciones antiguas en ejecución." + +# FIXME "snapbuild"? +#: replication/logical/snapbuild.c:1746 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "el archivo de estado de snapbuild «%s» tiene número mágico erróneo: %u en lugar de %u" + +#: replication/logical/snapbuild.c:1752 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "el archivo de estado de snapbuild «%s» tiene versión no soportada: %u en vez de %u" + +#: replication/logical/snapbuild.c:1823 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "suma de verificación no coincidente para el archivo de estado de snapbuild «%s»: es %u, debería ser %u" + +#: replication/logical/snapbuild.c:1880 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "La decodificación lógica comenzará usando el snapshot guardado." + +#: replication/logical/snapbuild.c:1952 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "no se pudo interpretar el nombre de archivo «%s»" + +#: replication/logical/tablesync.c:144 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "el ayudante de sincronización de tabla de replicación lógica para la suscripción «%s», tabla «%s» ha terminado" + +#: replication/logical/tablesync.c:726 replication/logical/tablesync.c:767 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "no se pudo obtener información de la tabla «%s.%s» del editor (publisher): %s" + +#: replication/logical/tablesync.c:732 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "la tabla \"%s.%s\" no fue encontrada en el editor (publisher)" + +#: replication/logical/tablesync.c:854 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "no se pudo iniciar la copia de contenido inicial para de la tabla «%s.%s»: %s" + +#: replication/logical/tablesync.c:1053 +#, fuzzy, c-format +#| msgid "table copy could not start transaction on publisher" +msgid "table copy could not start transaction on publisher: %s" +msgstr "la copia de la tabla no pudo iniciar una transacción en el editor (publisher)" + +#: replication/logical/tablesync.c:1101 +#, fuzzy, c-format +#| msgid "replication slot \"%s\" already exists" +msgid "replication origin \"%s\" already exists" +msgstr "el slot de replicación «%s» ya existe" + +#: replication/logical/tablesync.c:1113 +#, fuzzy, c-format +#| msgid "table copy could not finish transaction on publisher" +msgid "table copy could not finish transaction on publisher: %s" +msgstr "la copia de tabla no pudo terminar la transacción en el editor (publisher)" + +#: replication/logical/worker.c:527 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "Procesamiento de datos remotos para la relación de destino de replicación \"%s.%s\" columna \"%s\", tipo remoto %s, tipo local %s" + +#: replication/logical/worker.c:607 replication/logical/worker.c:736 +#, fuzzy, c-format +#| msgid "incorrect binary data format in function argument %d" +msgid "incorrect binary data format in logical replication column %d" +msgstr "el formato de datos binarios es incorrecto en argumento %d a función" + +#: replication/logical/worker.c:815 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "mensaje ORIGIN enviado fuera de orden" + +#: replication/logical/worker.c:1080 replication/logical/worker.c:1092 +#, fuzzy, c-format +#| msgid "could not read from backend variables file \"%s\": %s\n" +msgid "could not read from streaming transaction's changes file \"%s\": %m" +msgstr "no se pudo leer el archivo de variables de servidor «%s»: %s\n" + +#: replication/logical/worker.c:1322 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "el editor (publisher) no envía la columna identidad de réplica esperada por la relación de destino de replicación lógica «%s.%s»" + +#: replication/logical/worker.c:1329 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "la relación destino de replicación lógica «%s.%s» no tiene índice REPLICA IDENTITY ni PRIMARY KEY y la relación publicada no tiene REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:2050 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "tipo de mensaje de replicación lógica «%c» no válido" + +#: replication/logical/worker.c:2201 +#, c-format +msgid "data stream from publisher has ended" +msgstr "el flujo de datos del publisher ha terminado" + +#: replication/logical/worker.c:2351 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "terminando el proceso de replicación lógica debido a que se agotó el tiempo de espera" + +#: replication/logical/worker.c:2499 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se detendrá porque la suscripción fue eliminada" + +#: replication/logical/worker.c:2513 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se detendrá porque la suscripción fue inhabilitada" + +#: replication/logical/worker.c:2535 +#, fuzzy, c-format +#| msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgid "logical replication apply worker for subscription \"%s\" will restart because of a parameter change" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque a la suscripción se le cambió el nombre" + +#: replication/logical/worker.c:2698 replication/logical/worker.c:2720 +#, fuzzy, c-format +#| msgid "could not read from file \"%s\": %m" +msgid "could not read from streaming transaction's subxact file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: replication/logical/worker.c:3066 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "el ayudante «apply» de replicación lógica para la suscripción %u no se iniciará porque la suscripción fue eliminada durante el inicio" + +#: replication/logical/worker.c:3078 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» no se iniciará porque la suscripción fue inhabilitada durante el inicio" + +#: replication/logical/worker.c:3096 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "el ayudante de sincronización de tabla de replicación lógica para la suscripción «%s», tabla «%s» ha iniciado" + +#: replication/logical/worker.c:3100 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» ha iniciado" + +#: replication/logical/worker.c:3137 +#, c-format +msgid "subscription has no replication slot set" +msgstr "la suscripción no tiene un slot de replicación establecido" + +#: replication/pgoutput/pgoutput.c:195 +#, c-format +msgid "invalid proto_version" +msgstr "proto_version no válido" + +#: replication/pgoutput/pgoutput.c:200 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version «%s» fuera de rango" + +#: replication/pgoutput/pgoutput.c:217 +#, c-format +msgid "invalid publication_names syntax" +msgstr "sintaxis de publication_names no válida" + +#: replication/pgoutput/pgoutput.c:287 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "el cliente envió proto_version=%d pero sólo soportamos el protocolo %d o inferior" + +#: replication/pgoutput/pgoutput.c:293 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "el cliente envió proto_version=%d pero sólo soportamos el protocolo %d o superior" + +#: replication/pgoutput/pgoutput.c:299 +#, c-format +msgid "publication_names parameter missing" +msgstr "parámetro publication_names faltante" + +#: replication/pgoutput/pgoutput.c:312 +#, fuzzy, c-format +#| msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgid "requested proto_version=%d does not support streaming, need %d or higher" +msgstr "el cliente envió proto_version=%d pero sólo soportamos el protocolo %d o superior" + +#: replication/pgoutput/pgoutput.c:317 +#, fuzzy, c-format +#| msgid "integer of size %lu not supported by pqPutInt" +msgid "streaming requested, but not supported by output plugin" +msgstr "el entero de tamaño %lu no está soportado por pqPutInt" + +#: replication/slot.c:182 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "el nombre de slot de replicación «%s» es demasiado corto" + +#: replication/slot.c:191 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "el nombre de slot de replicación «%s» es demasiado largo" + +#: replication/slot.c:204 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "el nombre de slot de replicación «%s» contiene caracteres no válidos" + +#: replication/slot.c:206 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "Los nombres de slots de replicación sólo pueden contener letras minúsculas, números y el carácter «_»." + +#: replication/slot.c:260 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "el slot de replicación «%s» ya existe" + +#: replication/slot.c:270 +#, c-format +msgid "all replication slots are in use" +msgstr "todos los slots de replicación están en uso" + +#: replication/slot.c:271 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Libere uno o incremente max_replication_slots." + +#: replication/slot.c:424 replication/slotfuncs.c:761 +#: utils/adt/pgstatfuncs.c:2227 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "no existe el slot de replicación «%s»" + +#: replication/slot.c:462 replication/slot.c:1043 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "el slot de replicación «%s» está activo para el PID %d" + +#: replication/slot.c:701 replication/slot.c:1417 replication/slot.c:1800 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "no se pudo eliminar el directorio «%s»" + +#: replication/slot.c:1078 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "los slots de replicación sólo pueden usarse si max_replication_slots > 0" + +# FIXME see logical.c:81 +#: replication/slot.c:1083 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "los slots de replicación sólo pueden usarse si wal_level >= replica" + +#: replication/slot.c:1262 +#, fuzzy, c-format +#| msgid "terminating walsender process due to replication timeout" +msgid "terminating process %d to release replication slot \"%s\"" +msgstr "terminando el proceso walsender debido a que se agotó el tiempo de espera de replicación" + +#: replication/slot.c:1300 +#, c-format +msgid "invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size" +msgstr "invalidando el slot «%s» porque su restart_lsn %X/%X excede max_slot_wal_keep_size" + +#: replication/slot.c:1738 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "el archivo de slot de replicación «%s» tiene número mágico erróneo: %u en lugar de %u" + +#: replication/slot.c:1745 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "el archivo de slot de replicación «%s» tiene versión no soportada %u" + +#: replication/slot.c:1752 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "el archivo de slot de replicación «%s» tiene largo corrupto %u" + +#: replication/slot.c:1788 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "suma de verificación no coincidenete en archivo de slot de replicación «%s»: es %u, debería ser %u" + +# FIXME see slot.c:779. See also postmaster.c:835 +#: replication/slot.c:1822 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "existe el slot de replicación lógica «%s», pero wal_level < logical" + +#: replication/slot.c:1824 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Cambie wal_level a logical o superior." + +# FIXME see slot.c:779. See also postmaster.c:835 +#: replication/slot.c:1828 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "existe el slot de replicación lógica «%s», pero wal_level < logical" + +# <> hello vim +#: replication/slot.c:1830 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Cambie wal_level a replica o superior." + +#: replication/slot.c:1864 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "demasiados slots de replicacion activos antes del apagado" + +#: replication/slotfuncs.c:626 +#, c-format +msgid "invalid target WAL LSN" +msgstr "el LSN de wal de destino no es válido" + +#: replication/slotfuncs.c:648 +#, fuzzy, c-format +#| msgid "replication slot \"%s\" does not exist" +msgid "replication slot \"%s\" cannot be advanced" +msgstr "no existe el slot de replicación «%s»" + +#: replication/slotfuncs.c:666 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "no puede avanzar un slot de replicación a %X/%X, el mínimo es %X/%X" + +#: replication/slotfuncs.c:773 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "no se puede copiar el slot de replicación física «%s» como slot de replicación lógica" + +#: replication/slotfuncs.c:775 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "no se puede copiar el slot de replicación lógica «%s» como slot de replicación física" + +#: replication/slotfuncs.c:782 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "no puede copiar un slot de replicación que no ha reservado WAL" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "no se pudo copiar el slot de replicación «%s»" + +#: replication/slotfuncs.c:861 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "El slot de replicación de origen fue modificado incompatiblemente durante la operación de copia." + +#: replication/slotfuncs.c:867 +#, fuzzy, c-format +#| msgid "could not copy replication slot \"%s\"" +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "no se pudo copiar el slot de replicación «%s»" + +#: replication/slotfuncs.c:869 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "Reintente cuando el confirmed_flush_lsn del slot de replicación de origen sea válido." + +#: replication/syncrep.c:268 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "cancelando la espera para la replicación sincrónica y terminando la conexión debido a una orden del administrador" + +#: replication/syncrep.c:269 replication/syncrep.c:286 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "La transacción ya fue comprometida localmente, pero pudo no haber sido replicada al standby." + +#: replication/syncrep.c:285 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "cancelando espera para la replicación sincrónica debido a una petición del usuario" + +#: replication/syncrep.c:494 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "el standby «%s» es ahora un standby sincrónico con prioridad %u" + +#: replication/syncrep.c:498 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "el standby «%s» es ahora un candidato para standby sincrónico de quórum" + +#: replication/syncrep.c:1045 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "falló la interpretación de synchronous_standby_names" + +#: replication/syncrep.c:1051 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "el argumento de standby sincrónicos (%d) debe ser mayor que cero" + +#: replication/walreceiver.c:160 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "terminando el proceso walreceiver debido a una orden del administrador" + +#: replication/walreceiver.c:285 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "no se pudo conectar al servidor primario: %s" + +#: replication/walreceiver.c:331 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "el identificador de sistema difiere entre el primario y el standby" + +#: replication/walreceiver.c:332 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "El identificador del primario es %s, el identificador del standby es %s." + +#: replication/walreceiver.c:342 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "el timeline más alto del primario, %u, está más atrás que el timeline de recuperación %u" + +#: replication/walreceiver.c:396 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "iniciando el flujo de WAL desde el primario en %X/%X en el timeline %u" + +#: replication/walreceiver.c:400 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "reiniciando el flujo de WAL en %X/%X en el timeline %u" + +#: replication/walreceiver.c:428 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "no se puede continuar el flujo de WAL; la recuperación ya ha terminado" + +#: replication/walreceiver.c:465 +#, c-format +msgid "replication terminated by primary server" +msgstr "replicación terminada por el servidor primario" + +#: replication/walreceiver.c:466 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "Se alcanzó el fin de WAL en el timeline %u en la posición %X/%X." + +#: replication/walreceiver.c:554 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "terminando el proceso walreceiver debido a que se agotó el tiempo de espera" + +#: replication/walreceiver.c:592 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "el servidor primario no contiene más WAL en el timeline %u solicitado" + +#: replication/walreceiver.c:608 replication/walreceiver.c:903 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "no se pudo cerrar archivo de segmento %s: %m" + +#: replication/walreceiver.c:727 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "trayendo el archivo de historia del timeline para el timeline %u desde el servidor primario" + +#: replication/walreceiver.c:950 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "no se pudo escribir al segmento de log %s en la posición %u, largo %lu: %m" + +#: replication/walsender.c:524 storage/smgr/md.c:1320 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "no se pudo posicionar (seek) al fin del archivo «%s»: %m" + +#: replication/walsender.c:528 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "no se pudo posicionar (seek) al comienzo del archivo «%s»: %m" + +#: replication/walsender.c:579 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM no se ha ejecutado antes de START_REPLICATION" + +#: replication/walsender.c:608 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "no se puede usar un slot de replicación lógica para replicación física" + +#: replication/walsender.c:677 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "el punto de inicio solicitado %X/%X del timeline %u no está en la historia de este servidor" + +#: replication/walsender.c:680 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "La historia de este servidor bifurcó desde el timeline %u en %X/%X." + +#: replication/walsender.c:724 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "el punto de inicio solicitado %X/%X está más adelante que la posición de sincronización (flush) de WAL de este servidor %X/%X" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:974 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s no debe ser ejecutado dentro de una transacción" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:984 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s no debe ser ejecutado dentro de una transacción" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:990 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s debe llamarse en una transacción de modo de aislamiento REPEATABLE READ" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:996 +#, c-format +msgid "%s must be called before any query" +msgstr "%s debe ser llamado antes de cualquier consulta" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1002 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s no está permitido en una subtransacción" + +#: replication/walsender.c:1145 +#, fuzzy, c-format +#| msgid "created temporary replication slot \"%s\"" +msgid "cannot read from logical replication slot \"%s\"" +msgstr "se creó slot temporal de replicación «%s»" + +#: replication/walsender.c:1147 +#, c-format +msgid "This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "Este slot ha sido invalidado porque excedió el máximo del tamaño de reserva." + +#: replication/walsender.c:1157 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "terminando el proceso walsender luego de la promoción" + +#: replication/walsender.c:1523 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "no puede ejecutar nuevas órdenes mientras el «WAL sender» está en modo de apagarse" + +#: replication/walsender.c:1560 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "no puede ejecutar órdenes SQL en el «WAL sender» para replicación física" + +#: replication/walsender.c:1583 +#, c-format +msgid "received replication command: %s" +msgstr "se recibió orden de replicación: %s" + +#: replication/walsender.c:1591 tcop/fastpath.c:208 tcop/postgres.c:1078 +#: tcop/postgres.c:1430 tcop/postgres.c:1691 tcop/postgres.c:2176 +#: tcop/postgres.c:2586 tcop/postgres.c:2665 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "transacción abortada, las órdenes serán ignoradas hasta el fin de bloque de transacción" + +#: replication/walsender.c:1726 replication/walsender.c:1761 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "se encontró fin de archivo inesperado en la conexión standby" + +#: replication/walsender.c:1749 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "el tipo «%c» de mensaje del standby no es válido" + +#: replication/walsender.c:1838 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "mensaje de tipo «%c» inesperado" + +#: replication/walsender.c:2251 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "terminando el proceso walsender debido a que se agotó el tiempo de espera de replicación" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:999 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "ya existe una regla llamada «%s» para la relación «%s»" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "las acciones de regla en OLD no están implementadas" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "Use vistas o triggers en su lugar." + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "las acciones de regla en NEW no están implementadas" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "Use triggers en su lugar." + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "las reglas INSTEAD NOTHING en SELECT no están implementadas" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "Use vistas en su lugar." + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "las reglas de múltiples acciones en SELECT no están implementadas" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "las reglas en SELECT deben tener una acción INSTEAD SELECT" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "las reglas en SELECT no deben contener sentencias que modifiquen datos en WITH" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "las calificaciones de eventos no están implementadas para las reglas en SELECT" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "«%s» ya es una vista" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "la regla de vista para «%s» debe llamarse «%s»" + +#: rewrite/rewriteDefine.c:435 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "no se puede convertir la tabla particionada «%s» en vista" + +#: rewrite/rewriteDefine.c:444 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "no se puede convertir la partición «%s» en vista" + +#: rewrite/rewriteDefine.c:453 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "no se pudo convertir la tabla «%s» en vista porque no está vacía" + +#: rewrite/rewriteDefine.c:462 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "no se pudo convertir la tabla «%s» en vista porque tiene triggers" + +#: rewrite/rewriteDefine.c:464 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "En particular, la tabla no puede estar involucrada en relaciones de llave foránea." + +#: rewrite/rewriteDefine.c:469 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "no se pudo convertir la tabla «%s» en vista porque tiene índices" + +#: rewrite/rewriteDefine.c:475 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "no se pudo convertir la tabla «%s» en vista porque tiene tablas hijas" + +#: rewrite/rewriteDefine.c:481 +#, fuzzy, c-format +#| msgid "could not convert table \"%s\" to a view because it has child tables" +msgid "could not convert table \"%s\" to a view because it has parent tables" +msgstr "no se pudo convertir la tabla «%s» en vista porque tiene tablas hijas" + +#: rewrite/rewriteDefine.c:487 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "no se pudo convertir la tabla «%s» en vista porque tiene seguridad de registros activada" + +#: rewrite/rewriteDefine.c:493 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "no se pudo convertir la tabla «%s» en vista porque tiene políticas de seguridad de registros" + +#: rewrite/rewriteDefine.c:520 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "no se pueden tener múltiples listas RETURNING en una regla" + +#: rewrite/rewriteDefine.c:525 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "listas de RETURNING no están soportadas en reglas condicionales" + +#: rewrite/rewriteDefine.c:529 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "listas de RETURNING no están soportadas en reglas que no estén marcadas INSTEAD" + +#: rewrite/rewriteDefine.c:693 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "la lista de destinos en la regla de SELECT tiene demasiadas entradas" + +#: rewrite/rewriteDefine.c:694 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "la lista de RETURNING tiene demasiadas entradas" + +#: rewrite/rewriteDefine.c:721 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "no se puede convertir en vista una relación que contiene columnas eliminadas" + +#: rewrite/rewriteDefine.c:722 +#, c-format +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "no se puede crear una lista RETURNING para una relación que contiene columnas eliminadas" + +#: rewrite/rewriteDefine.c:728 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "la entrada de destino %d de la regla de SELECT tiene un nombre de columna diferente de «%s»" + +#: rewrite/rewriteDefine.c:730 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "La entrada de destino de SELECT tiene nombre «%s»." + +#: rewrite/rewriteDefine.c:739 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "el destino %d de la regla de SELECT tiene un tipo diferente de la columna «%s»" + +#: rewrite/rewriteDefine.c:741 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "el destino %d de la lista de RETURNING tiene un tipo diferente de la columna «%s»" + +#: rewrite/rewriteDefine.c:744 rewrite/rewriteDefine.c:768 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "La entrada de destino de SELECT tiene un tipo «%s», pero la columna tiene tipo «%s»." + +#: rewrite/rewriteDefine.c:747 rewrite/rewriteDefine.c:772 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "una entrada de la lista RETURNING tiene tipo %s, pero la columna tiene tipo %s." + +#: rewrite/rewriteDefine.c:763 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "el destino %d de la regla de SELECT tiene un tamaño diferente de la columna «%s»" + +#: rewrite/rewriteDefine.c:765 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "el destino %d de la lista RETURNING tiene un tamaño diferente de la columna «%s»" + +#: rewrite/rewriteDefine.c:782 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "la lista de destinos de regla de SELECT tiene muy pocas entradas" + +#: rewrite/rewriteDefine.c:783 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "la lista de RETURNING tiene muy pocas entradas" + +#: rewrite/rewriteDefine.c:876 rewrite/rewriteDefine.c:990 +#: rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "no existe la regla «%s» para la relación «%s»" + +#: rewrite/rewriteDefine.c:1009 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "no se permite cambiar el nombre de una regla ON SELECT" + +#: rewrite/rewriteHandler.c:551 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "el nombre de consulta WITH «%s» aparece tanto en una acción de regla y en la consulta que está siendo reescrita" + +#: rewrite/rewriteHandler.c:611 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "no se puede usar RETURNING en múltiples reglas" + +#: rewrite/rewriteHandler.c:843 rewrite/rewriteHandler.c:882 +#, fuzzy, c-format +#| msgid "cannot insert into column \"%s\"" +msgid "cannot insert a non-DEFAULT value into column \"%s\"" +msgstr "no se puede insertar en la columna «%s»" + +#: rewrite/rewriteHandler.c:845 rewrite/rewriteHandler.c:911 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "La columna \"%s\" es una columna de identidad definida como GENERATED ALWAYS." + +#: rewrite/rewriteHandler.c:847 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Use OVERRIDING SYSTEM VALUE para controlar manualmente." + +#: rewrite/rewriteHandler.c:909 rewrite/rewriteHandler.c:917 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "la columna «%s» sólo puede actualizarse a DEFAULT" + +#: rewrite/rewriteHandler.c:1064 rewrite/rewriteHandler.c:1082 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "hay múltiples asignaciones a la misma columna «%s»" + +#: rewrite/rewriteHandler.c:2084 rewrite/rewriteHandler.c:3898 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "se detectó recursión infinita en las reglas de la relación «%s»" + +#: rewrite/rewriteHandler.c:2169 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "se detectó recursión infinita en la política para la relación «%s»" + +#: rewrite/rewriteHandler.c:2489 +msgid "Junk view columns are not updatable." +msgstr "Las columnas «basura» de vistas no son actualizables." + +#: rewrite/rewriteHandler.c:2494 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "Las columnas de vistas que no son columnas de su relación base no son actualizables." + +#: rewrite/rewriteHandler.c:2497 +msgid "View columns that refer to system columns are not updatable." +msgstr "Las columnas de vistas que se refieren a columnas de sistema no son actualizables." + +#: rewrite/rewriteHandler.c:2500 +msgid "View columns that return whole-row references are not updatable." +msgstr "Las columnas de vistas que retornan referencias a la fila completa no son actualizables." + +# XXX a %s here would be nice ... +#: rewrite/rewriteHandler.c:2561 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "Las vistas que contienen DISTINCT no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2564 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "Las vistas que contienen GROUP BY no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2567 +msgid "Views containing HAVING are not automatically updatable." +msgstr "Las vistas que contienen HAVING no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2570 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "Las vistas que contienen UNION, INTERSECT o EXCEPT no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2573 +msgid "Views containing WITH are not automatically updatable." +msgstr "Las vistas que contienen WITH no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2576 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "Las vistas que contienen LIMIT u OFFSET no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2588 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "Las vistas que retornan funciones de agregación no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2591 +msgid "Views that return window functions are not automatically updatable." +msgstr "Las vistas que retornan funciones ventana no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2594 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "Las vistas que retornan funciones-que-retornan-conjuntos no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2601 rewrite/rewriteHandler.c:2605 +#: rewrite/rewriteHandler.c:2613 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "Las vistas que no extraen desde una única tabla o vista no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2616 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "Las vistas que contienen TABLESAMPLE no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:2640 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "Las vistas que no tienen columnas actualizables no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:3117 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "no se puede insertar en la columna «%s» de la vista «%s»" + +#: rewrite/rewriteHandler.c:3125 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "no se puede actualizar la columna «%s» vista «%s»" + +#: rewrite/rewriteHandler.c:3603 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "las reglas DO INSTEAD NOTHING no están soportadas para sentencias que modifiquen datos en WITH" + +#: rewrite/rewriteHandler.c:3617 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "las reglas DO INSTEAD condicionales no están soportadas para sentencias que modifiquen datos en WITH" + +#: rewrite/rewriteHandler.c:3621 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "las reglas DO ALSO no están soportadas para sentencias que modifiquen datos en WITH" + +#: rewrite/rewriteHandler.c:3626 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "las reglas DO INSTEAD de múltiples sentencias no están soportadas para sentencias que modifiquen datos en WITH" + +# XXX a %s here would be nice ... +#: rewrite/rewriteHandler.c:3826 rewrite/rewriteHandler.c:3834 +#: rewrite/rewriteHandler.c:3842 +#, fuzzy, c-format +#| msgid "Views containing DISTINCT are not automatically updatable." +msgid "Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "Las vistas que contienen DISTINCT no son automáticamente actualizables." + +#: rewrite/rewriteHandler.c:3935 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "no se puede hacer INSERT RETURNING a la relación «%s»" + +#: rewrite/rewriteHandler.c:3937 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "Necesita un regla incondicional ON INSERT DO INSTEAD con una cláusula RETURNING." + +#: rewrite/rewriteHandler.c:3942 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "no se puede hacer UPDATE RETURNING a la relación «%s»" + +#: rewrite/rewriteHandler.c:3944 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "Necesita un regla incondicional ON UPDATE DO INSTEAD con una cláusula RETURNING." + +#: rewrite/rewriteHandler.c:3949 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "no se puede hacer DELETE RETURNING a la relación «%s»" + +#: rewrite/rewriteHandler.c:3951 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "Necesita un regla incondicional ON DELETE DO INSTEAD con una clásula RETURNING." + +#: rewrite/rewriteHandler.c:3969 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "INSERT con una cláusula ON CONFLICT no puede usarse con una tabla que tiene reglas INSERT o UPDATE" + +#: rewrite/rewriteHandler.c:4026 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "WITH no puede ser usado en una consulta que está siendo convertida en múltiples consultas a través de reglas" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "las sentencias condicionales de utilidad no están implementadas" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "WHERE CURRENT OF no está implementado en una vista" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "las variables NEW en reglas ON UPDATE no pueden referenciar columnas que son parte de una asignación múltiple en la orden UPDATE" + +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "un comentario /* está inconcluso" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "una cadena de bits está inconclusa" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "una cadena hexadecimal está inconclusa" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "uso inseguro de literal de cadena con escapes Unicode" + +#: scan.l:543 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "Los literales de cadena con escapes Unicode no pueden usarse cuando standard_conforming_strings está desactivado." + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "estado previo no manejado en xqs" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Los escapes Unicode deben ser \\uXXXX o \\UXXXXXXXX." + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "uso inseguro de \\' en un literal de cadena" + +#: scan.l:690 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "Use '' para escribir comillas en cadenas. \\' es inseguro en codificaciones de sólo cliente." + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "una cadena separada por $ está inconclusa" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "un identificador delimitado tiene largo cero" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "un identificador entre comillas está inconcluso" + +#: scan.l:963 +msgid "operator too long" +msgstr "el operador es demasiado largo" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1171 +#, c-format +msgid "%s at end of input" +msgstr "%s al final de la entrada" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1179 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s en o cerca de «%s»" + +#: scan.l:1373 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "uso no estandar de \\' en un literal de cadena" + +#: scan.l:1374 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "Use '' para escribir comillas en cadenas, o use la sintaxis de escape de cadenas (E'...')." + +#: scan.l:1383 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "uso no estandar de \\\\ en un literal de cadena" + +#: scan.l:1384 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Use '' para escribir comillas en cadenas, o use la sintaxis de escape de cadenas (E'\\\\')." + +#: scan.l:1398 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "uso no estandar de escape en un literal de cadena" + +#: scan.l:1399 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Use la sintaxis de escape para cadenas, por ej. E'\\r\\n'." + +#: snowball/dict_snowball.c:215 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "no se encontró un analizador Snowball para el lenguaje «%s» y la codificación «%s»" + +#: snowball/dict_snowball.c:238 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "parámetro StopWords duplicado" + +#: snowball/dict_snowball.c:247 +#, c-format +msgid "multiple Language parameters" +msgstr "parámetro Language duplicado" + +#: snowball/dict_snowball.c:254 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "parámetro Snowball no reconocido: «%s»" + +#: snowball/dict_snowball.c:262 +#, c-format +msgid "missing Language parameter" +msgstr "falta un parámetro Language" + +#: statistics/extended_stats.c:175 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "el objeto de estadísticas «%s.%s» no pudo ser calculado para la relación «%s.%s»" + +#: statistics/extended_stats.c:2277 +#, fuzzy, c-format +#| msgid "\"%s\" is not a composite type" +msgid "relation \"pg_statistic\" does not have a composite type" +msgstr "«%s» no es un tipo compuesto" + +#: statistics/mcv.c:1371 utils/adt/jsonfuncs.c:1941 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "se llamó una función que retorna un registro en un contexto que no puede aceptarlo" + +#: storage/buffer/bufmgr.c:601 storage/buffer/bufmgr.c:761 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "no se pueden acceder tablas temporales de otras sesiones" + +#: storage/buffer/bufmgr.c:917 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "datos inesperados más allá del EOF en el bloque %u de relación %s" + +#: storage/buffer/bufmgr.c:919 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "Esto parece ocurrir sólo con kernels defectuosos; considere actualizar su sistema." + +#: storage/buffer/bufmgr.c:1018 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "la página no es válida en el bloque %u de la relación «%s»; reinicializando la página" + +#: storage/buffer/bufmgr.c:4524 +#, c-format +msgid "could not write block %u of %s" +msgstr "no se pudo escribir el bloque %u de %s" + +#: storage/buffer/bufmgr.c:4526 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Múltiples fallas --- el error de escritura puede ser permanente." + +#: storage/buffer/bufmgr.c:4547 storage/buffer/bufmgr.c:4566 +#, c-format +msgid "writing block %u of relation %s" +msgstr "escribiendo el bloque %u de la relación %s" + +#: storage/buffer/bufmgr.c:4870 +#, c-format +msgid "snapshot too old" +msgstr "snapshot demasiado antiguo" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "no hay ningún búfer local disponible" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "no se pueden acceder tablas temporales durante una operación paralela" + +#: storage/file/buffile.c:323 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "no se pudo abrir archivo temporal «%s» del BufFile «%s»: %m" + +#: storage/file/buffile.c:684 storage/file/buffile.c:805 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "no se pudo determinar el tamaño del archivo temporal «%s» del BufFile «%s»: %m" + +#: storage/file/buffile.c:884 +#, fuzzy, c-format +#| msgid "could not delete file \"%s\": %m" +msgid "could not delete shared fileset \"%s\": %m" +msgstr "no se pudo borrar el archivo «%s»: %m" + +#: storage/file/buffile.c:902 storage/smgr/md.c:306 storage/smgr/md.c:865 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "no se pudo truncar el archivo «%s»: %m" + +#: storage/file/fd.c:515 storage/file/fd.c:587 storage/file/fd.c:623 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "no se pudo sincronizar (flush) datos «sucios»: %m" + +#: storage/file/fd.c:545 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "no se pudo determinar el tamaño de los datos «sucios»: %m" + +#: storage/file/fd.c:597 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "no se pudo ejecutar munmap() mientras se sincronizaban (flush) datos: %m" + +#: storage/file/fd.c:836 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "no se pudo enlazar (link) el archivo «%s» a «%s»: %m" + +#: storage/file/fd.c:929 +#, c-format +msgid "getrlimit failed: %m" +msgstr "getrlimit falló: %m" + +#: storage/file/fd.c:1019 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "los descriptores de archivo disponibles son insuficientes para iniciar un proceso servidor" + +#: storage/file/fd.c:1020 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "El sistema permite %d, se requieren al menos %d." + +#: storage/file/fd.c:1071 storage/file/fd.c:2408 storage/file/fd.c:2518 +#: storage/file/fd.c:2669 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "se agotaron los descriptores de archivo: %m; libere e intente nuevamente" + +#: storage/file/fd.c:1445 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "archivo temporal: ruta «%s», tamaño %lu" + +#: storage/file/fd.c:1576 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "no se pudo crear el directorio temporal «%s»: %m" + +#: storage/file/fd.c:1583 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "no se pudo crear el subdirectorio temporal «%s»: %m" + +#: storage/file/fd.c:1776 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "no se pudo crear el archivo temporal «%s»: %m" + +#: storage/file/fd.c:1810 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "no se pudo abrir el archivo temporal «%s»: %m" + +#: storage/file/fd.c:1851 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "no se pudo eliminar (unlink) el archivo temporal «%s»: %m" + +#: storage/file/fd.c:1939 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "no se pudo borrar el archivo «%s»: %m" + +#: storage/file/fd.c:2119 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "el tamaño del archivo temporal excede temp_file_limit permitido (%dkB)" + +#: storage/file/fd.c:2384 storage/file/fd.c:2443 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "se excedió maxAllocatedDescs (%d) mientras se trataba de abrir el archivo «%s»" + +#: storage/file/fd.c:2488 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "se excedió maxAllocatedDescs (%d) mientras se trataba de ejecutar la orden «%s»" + +#: storage/file/fd.c:2645 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "se excedió maxAllocatedDescs (%d) mientras se trataba de abrir el directorio «%s»" + +#: storage/file/fd.c:3175 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "archivo inesperado en directorio de archivos temporales: «%s»" + +#: storage/file/fd.c:3298 +#, fuzzy, c-format +#| msgid "could not open file \"%s\": %m" +msgid "could not open %s: %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: storage/file/fd.c:3304 +#, fuzzy, c-format +#| msgid "could not fsync file \"%s\": %m" +msgid "could not sync filesystem for \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" + +#: storage/file/sharedfileset.c:144 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "no se puede adjuntar a un SharedFileSet que ya está destruido" + +#: storage/ipc/dsm.c:351 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "el segmento de control de memoria compartida dinámica está corrupto" + +#: storage/ipc/dsm.c:415 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "el segmento de control de memoria compartida dinámica no es válido" + +#: storage/ipc/dsm.c:592 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "demasiados segmentos de memoria compartida dinámica" + +#: storage/ipc/dsm_impl.c:233 storage/ipc/dsm_impl.c:529 +#: storage/ipc/dsm_impl.c:633 storage/ipc/dsm_impl.c:804 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "no se pudo desmapear el segmento de memoria compartida «%s»: %m" + +#: storage/ipc/dsm_impl.c:243 storage/ipc/dsm_impl.c:539 +#: storage/ipc/dsm_impl.c:643 storage/ipc/dsm_impl.c:814 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "no se pudo eliminar el segmento de memoria compartida «%s»: %m" + +#: storage/ipc/dsm_impl.c:267 storage/ipc/dsm_impl.c:714 +#: storage/ipc/dsm_impl.c:828 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "no se pudo abrir el segmento de memoria compartida «%s»: %m" + +#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:555 +#: storage/ipc/dsm_impl.c:759 storage/ipc/dsm_impl.c:852 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "no se pudo hacer stat del segmento de memoria compartida «%s»: %m" + +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:903 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "no se pudo redimensionar el segmento de memoria compartida «%s» a %zu bytes: %m" + +#: storage/ipc/dsm_impl.c:341 storage/ipc/dsm_impl.c:576 +#: storage/ipc/dsm_impl.c:735 storage/ipc/dsm_impl.c:925 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "no se pudo mapear el segmento de memoria compartida «%s»: %m" + +#: storage/ipc/dsm_impl.c:511 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "no se pudo obtener el segmento de memoria compartida: %m" + +#: storage/ipc/dsm_impl.c:699 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "no se pudo crear el segmento de memoria compartida «%s»: %m" + +#: storage/ipc/dsm_impl.c:936 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "no se pudo cerrar el segmento de memoria compartida «%s»: %m" + +#: storage/ipc/dsm_impl.c:975 storage/ipc/dsm_impl.c:1023 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "no se pudo duplicar el «handle» para «%s»: %m" + +#: storage/ipc/procarray.c:3724 +#, fuzzy, c-format +#| msgid "database \"%s\" is being used by logical replication subscription" +msgid "database \"%s\" is being used by prepared transactions" +msgstr "la base de datos «%s» está siendo utilizada por suscripciones de replicación lógica" + +#: storage/ipc/procarray.c:3756 storage/ipc/signalfuncs.c:219 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "debe ser superusuario para terminar proceso de superusuario" + +#: storage/ipc/procarray.c:3763 storage/ipc/signalfuncs.c:224 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "debe ser miembro del rol cuyo proceso se está terminando o ser miembro de pg_signal_backend" + +#: storage/ipc/shm_mq.c:368 +#, fuzzy, c-format +#| msgid "could not send tuple to shared-memory queue" +msgid "cannot send a message of size %zu via shared memory queue" +msgstr "no se pudo enviar la tupla a la cola en memoria compartida" + +#: storage/ipc/shm_mq.c:694 +#, fuzzy, c-format +#| msgid "invalid magic number in dynamic shared memory segment" +msgid "invalid message size %zu in shared memory queue" +msgstr "número mágico no válido en segmento de memoria compartida dinámica" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:981 +#: storage/lmgr/lock.c:1019 storage/lmgr/lock.c:2844 storage/lmgr/lock.c:4173 +#: storage/lmgr/lock.c:4238 storage/lmgr/lock.c:4545 +#: storage/lmgr/predicate.c:2470 storage/lmgr/predicate.c:2485 +#: storage/lmgr/predicate.c:3967 storage/lmgr/predicate.c:5078 +#: utils/hash/dynahash.c:1112 +#, c-format +msgid "out of shared memory" +msgstr "memoria compartida agotada" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "memoria compartida agotada (%zu bytes solicitados)" + +#: storage/ipc/shmem.c:445 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "no se pudo crear la entrada en ShmemIndex para la estructura «%s»" + +#: storage/ipc/shmem.c:460 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "el tamaño de la entrada ShmemIndex es incorrecto para la estructura «%s»: se esperaba %zu, real %zu" + +#: storage/ipc/shmem.c:479 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "el espacio de memoria compartida es insuficiente para la estructura «%s» (%zu bytes solicitados)" + +#: storage/ipc/shmem.c:511 storage/ipc/shmem.c:530 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "la petición de tamaño de memoria compartida desborda size_t" + +#: storage/ipc/signalfuncs.c:68 storage/ipc/signalfuncs.c:261 +#: utils/adt/mcxtfuncs.c:204 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d no es un proceso servidor de PostgreSQL" + +#: storage/ipc/signalfuncs.c:99 storage/lmgr/proc.c:1454 +#: utils/adt/mcxtfuncs.c:212 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "no se pudo enviar la señal al proceso %d: %m" + +#: storage/ipc/signalfuncs.c:119 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "debe ser superusuario para cancelar una consulta de superusuario" + +#: storage/ipc/signalfuncs.c:124 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "debe ser miembro del rol cuya consulta se está cancelando o ser miembro de pg_signal_backend" + +#: storage/ipc/signalfuncs.c:165 +#, c-format +msgid "could not check the existence of the backend with PID %d: %m" +msgstr "" + +#: storage/ipc/signalfuncs.c:183 +#, fuzzy, c-format +#| msgid "server did not promote within %d seconds" +msgid "backend with PID %d did not terminate within %lld milliseconds" +msgstr "el servidor no promovió en %d segundos" + +#: storage/ipc/signalfuncs.c:212 +#, fuzzy, c-format +#| msgid "LIMIT must not be negative" +msgid "\"timeout\" must not be negative" +msgstr "LIMIT no debe ser negativo" + +#: storage/ipc/signalfuncs.c:254 +#, fuzzy, c-format +#| msgid "\"wait_seconds\" must not be negative or zero" +msgid "\"timeout\" must not be negative or zero" +msgstr "«wait_seconds» no puede ser negativo o cero" + +#: storage/ipc/signalfuncs.c:300 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "bebe ser superusuario para rotar archivos de log con adminpack 1.0" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:302 utils/adt/genfile.c:255 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Considere usar %s, que es parte del servidor, en su lugar." + +#: storage/ipc/signalfuncs.c:308 storage/ipc/signalfuncs.c:328 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "la rotación no es posible porque la recoleccion de log no está activa" + +#: storage/ipc/standby.c:305 +#, fuzzy, c-format +#| msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgid "recovery still waiting after %ld.%03d ms: %s" +msgstr "el proceso %d aún espera %s en %s después de %ld.%03d ms" + +#: storage/ipc/standby.c:314 +#, fuzzy, c-format +#| msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgid "recovery finished waiting after %ld.%03d ms: %s" +msgstr "el proceso %d aún espera %s en %s después de %ld.%03d ms" + +#: storage/ipc/standby.c:878 tcop/postgres.c:3317 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "cancelando la sentencia debido a un conflicto con la recuperación" + +#: storage/ipc/standby.c:879 tcop/postgres.c:2471 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "La transacción del usuario causó un «deadlock» con la recuperación." + +#: storage/ipc/standby.c:1421 +#, fuzzy +#| msgid "unknown" +msgid "unknown reason" +msgstr "desconocido" + +#: storage/ipc/standby.c:1426 +msgid "recovery conflict on buffer pin" +msgstr "" + +#: storage/ipc/standby.c:1429 +#, fuzzy +#| msgid "abort reason: recovery conflict" +msgid "recovery conflict on lock" +msgstr "razón para abortar: conflicto en la recuperación" + +#: storage/ipc/standby.c:1432 +#, fuzzy +#| msgid "remove a tablespace" +msgid "recovery conflict on tablespace" +msgstr "elimina un tablespace" + +#: storage/ipc/standby.c:1435 +msgid "recovery conflict on snapshot" +msgstr "" + +#: storage/ipc/standby.c:1438 +msgid "recovery conflict on buffer deadlock" +msgstr "" + +#: storage/ipc/standby.c:1441 +#, fuzzy +#| msgid "already connected to a database" +msgid "recovery conflict on database" +msgstr "ya está conectado a una base de datos" + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "la entrada pg_largeobject para el OID %u, página %d tiene tamaño de campo %d no válido" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "opciones no válidas para abrir un objeto grande: %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "parámetro «whence» no válido: %d" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "tamaño de petición de escritura de objeto grande no válido: %d" + +#: storage/lmgr/deadlock.c:1122 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "El proceso %d espera %s en %s; bloqueado por proceso %d." + +#: storage/lmgr/deadlock.c:1141 +#, c-format +msgid "Process %d: %s" +msgstr "Proceso %d: %s" + +#: storage/lmgr/deadlock.c:1150 +#, c-format +msgid "deadlock detected" +msgstr "se ha detectado un deadlock" + +#: storage/lmgr/deadlock.c:1153 +#, c-format +msgid "See server log for query details." +msgstr "Vea el registro del servidor para obtener detalles de las consultas." + +#: storage/lmgr/lmgr.c:831 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "mientras se actualizaba la tupla (%u,%u) en la relación «%s»" + +#: storage/lmgr/lmgr.c:834 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "mientras se borraba la tupla (%u,%u) en la relación «%s»" + +#: storage/lmgr/lmgr.c:837 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "mientras se bloqueaba la tupla (%u,%u) de la relación «%s»" + +#: storage/lmgr/lmgr.c:840 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "mientras se bloqueaba la versión actualizada (%u,%u) en la relación «%s»" + +#: storage/lmgr/lmgr.c:843 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "mientras se insertaba la tupla de índice (%u,%u) en la relación «%s»" + +#: storage/lmgr/lmgr.c:846 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "mientras se verificaba la unicidad de la tupla (%u,%u) en la relación «%s»" + +#: storage/lmgr/lmgr.c:849 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "mientras se verificaba la tupla actualizada (%u,%u) en la relación «%s»" + +#: storage/lmgr/lmgr.c:852 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "mientras se verificaba una restricción de exclusión en la tupla (%u,%u) en la relación «%s»" + +#: storage/lmgr/lmgr.c:1106 +#, c-format +msgid "relation %u of database %u" +msgstr "relación %u de la base de datos %u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "extensión de la relación %u de la base de datos %u" + +#: storage/lmgr/lmgr.c:1118 +#, fuzzy, c-format +#| msgid "relation %u of database %u" +msgid "pg_database.datfrozenxid of database %u" +msgstr "relación %u de la base de datos %u" + +#: storage/lmgr/lmgr.c:1123 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "página %u de la relación %u de la base de datos %u" + +#: storage/lmgr/lmgr.c:1130 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "tupla (%u,%u) de la relación %u de la base de datos %u" + +#: storage/lmgr/lmgr.c:1138 +#, c-format +msgid "transaction %u" +msgstr "transacción %u" + +#: storage/lmgr/lmgr.c:1143 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "transacción virtual %d/%u" + +#: storage/lmgr/lmgr.c:1149 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "token especulativo %u de la transacción %u" + +#: storage/lmgr/lmgr.c:1155 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "objeto %u de clase %u de la base de datos %u" + +#: storage/lmgr/lmgr.c:1163 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "candado de usuario [%u,%u,%u]" + +# XXX is this a good translation? +#: storage/lmgr/lmgr.c:1170 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "candado consultivo [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1178 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "tipo de locktag %d no reconocido" + +#: storage/lmgr/lock.c:802 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "no se puede adquirir candado en modo %s en objetos de la base de datos mientras la recuperación está en proceso" + +#: storage/lmgr/lock.c:804 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "Sólo candados RowExclusiveLock o menor pueden ser adquiridos en objetos de la base de datos durante la recuperación." + +#: storage/lmgr/lock.c:982 storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 +#: storage/lmgr/lock.c:4174 storage/lmgr/lock.c:4239 storage/lmgr/lock.c:4546 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "Puede ser necesario incrementar max_locks_per_transaction." + +#: storage/lmgr/lock.c:3283 storage/lmgr/lock.c:3399 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "no se puede hacer PREPARE mientras se mantienen candados a nivel de sesión y transacción simultáneamente sobre el mismo objeto" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "no hay suficientes elementos en RWConflictPool para registrar un conflicto read/write" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "Puede ser necesario ejecutar menos transacciones al mismo tiempo, o incrementar max_connections." + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "no hay suficientes elementos en RWConflictPool para registrar un potencial conflicto read/write" + +#: storage/lmgr/predicate.c:1694 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "«default_transaction_isolation» está definido a «serializable»." + +#: storage/lmgr/predicate.c:1695 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "Puede usar «SET default_transaction_isolation = 'repeatable read'» para cambiar el valor por omisión." + +#: storage/lmgr/predicate.c:1746 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "una transacción que importa un snapshot no debe ser READ ONLY DEFERRABLE" + +#: storage/lmgr/predicate.c:1825 utils/time/snapmgr.c:567 +#: utils/time/snapmgr.c:573 +#, c-format +msgid "could not import the requested snapshot" +msgstr "no se pudo importar el snapshot solicitado" + +#: storage/lmgr/predicate.c:1826 utils/time/snapmgr.c:574 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "El proceso de origen con PID %d ya no está en ejecución." + +#: storage/lmgr/predicate.c:2471 storage/lmgr/predicate.c:2486 +#: storage/lmgr/predicate.c:3968 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "Puede ser necesario incrementar max_pred_locks_per_transaction." + +#: storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4135 +#: storage/lmgr/predicate.c:4168 storage/lmgr/predicate.c:4176 +#: storage/lmgr/predicate.c:4215 storage/lmgr/predicate.c:4457 +#: storage/lmgr/predicate.c:4794 storage/lmgr/predicate.c:4806 +#: storage/lmgr/predicate.c:4849 storage/lmgr/predicate.c:4887 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "no se pudo serializar el acceso debido a dependencias read/write entre transacciones" + +#: storage/lmgr/predicate.c:4101 storage/lmgr/predicate.c:4137 +#: storage/lmgr/predicate.c:4170 storage/lmgr/predicate.c:4178 +#: storage/lmgr/predicate.c:4217 storage/lmgr/predicate.c:4459 +#: storage/lmgr/predicate.c:4796 storage/lmgr/predicate.c:4808 +#: storage/lmgr/predicate.c:4851 storage/lmgr/predicate.c:4889 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "La transacción podría tener éxito si es reintentada." + +#: storage/lmgr/proc.c:357 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "la cantidad de conexiones standby pedidas excede max_wal_senders (actualmente %d)" + +#: storage/lmgr/proc.c:1551 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "el proceso %d evitó un deadlock para %s en %s reordenando la cola después de %ld.%03d ms" + +#: storage/lmgr/proc.c:1566 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "el proceso %d detectó un deadlock mientras esperaba %s en %s después de %ld.%03d ms" + +#: storage/lmgr/proc.c:1575 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "el proceso %d aún espera %s en %s después de %ld.%03d ms" + +#: storage/lmgr/proc.c:1582 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "el proceso %d adquirió %s en %s después de %ld.%03d ms" + +#: storage/lmgr/proc.c:1599 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "el proceso %d no pudo adquirir %s en %s después de %ld.%03d ms" + +#: storage/page/bufpage.c:152 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "la suma de verificación falló, se calculó %u pero se esperaba %u" + +#: storage/page/bufpage.c:217 storage/page/bufpage.c:739 +#: storage/page/bufpage.c:1066 storage/page/bufpage.c:1201 +#: storage/page/bufpage.c:1307 storage/page/bufpage.c:1419 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "los punteros de página están corruptos: inferior = %u, superior = %u, especial = %u" + +#: storage/page/bufpage.c:768 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "puntero de ítem corrupto: %u" + +#: storage/page/bufpage.c:795 storage/page/bufpage.c:1259 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "los largos de ítem están corruptos: total %u, espacio disponible %u" + +#: storage/page/bufpage.c:1085 storage/page/bufpage.c:1226 +#: storage/page/bufpage.c:1323 storage/page/bufpage.c:1435 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "puntero de ítem corrupto: desplazamiento = %u, tamaño = %u" + +#: storage/smgr/md.c:434 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "no se pudo extender el archivo «%s» más allá de %u bloques" + +#: storage/smgr/md.c:449 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "no se pudo extender el archivo «%s»: %m" + +#: storage/smgr/md.c:451 storage/smgr/md.c:458 storage/smgr/md.c:746 +#, c-format +msgid "Check free disk space." +msgstr "Verifique el espacio libre en disco." + +#: storage/smgr/md.c:455 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "no se pudo extender el archivo «%s»: sólo se escribieron %d de %d bytes en el bloque %u" + +#: storage/smgr/md.c:667 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "no se pudo leer el bloque %u del archivo «%s»: %m" + +#: storage/smgr/md.c:683 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "no se pudo leer el bloque %u del archivo «%s»: se leyeron sólo %d de %d bytes" + +#: storage/smgr/md.c:737 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "no se pudo escribir el bloque %u en el archivo «%s»: %m" + +#: storage/smgr/md.c:742 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "no se pudo escribir el bloque %u en el archivo «%s»: se escribieron sólo %d de %d bytes" + +#: storage/smgr/md.c:836 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "no se pudo truncar el archivo «%s» a %u bloques: es de sólo %u bloques ahora" + +#: storage/smgr/md.c:891 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "no se pudo truncar el archivo «%s» a %u bloques: %m" + +#: storage/smgr/md.c:1285 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "no se pudo abrir el archivo «%s» (bloque buscado %u): el segmento previo sólo tiene %u bloques" + +#: storage/smgr/md.c:1299 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "no se pudo abrir el archivo «%s» (bloque buscado %u): %m" + +#: tcop/fastpath.c:148 +#, c-format +msgid "cannot call function %s via fastpath interface" +msgstr "" + +#: tcop/fastpath.c:233 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "llamada a función fastpath: «%s» (OID %u)" + +#: tcop/fastpath.c:312 tcop/postgres.c:1298 tcop/postgres.c:1556 +#: tcop/postgres.c:2015 tcop/postgres.c:2252 +#, c-format +msgid "duration: %s ms" +msgstr "duración: %s ms" + +#: tcop/fastpath.c:316 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "duración: %s ms llamada a función fastpath: «%s» (OID %u)" + +#: tcop/fastpath.c:352 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "el mensaje de llamada a función contiene %d argumentos pero la función requiere %d" + +#: tcop/fastpath.c:360 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "el mensaje de llamada a función contiene %d formatos de argumento pero %d argumentos" + +#: tcop/fastpath.c:384 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "el tamaño de argumento %d no es válido en el mensaje de llamada a función" + +#: tcop/fastpath.c:447 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "el formato de datos binarios es incorrecto en argumento %d a función" + +#: tcop/postgres.c:446 tcop/postgres.c:4716 +#, c-format +msgid "invalid frontend message type %d" +msgstr "el tipo de mensaje de frontend %d no es válido" + +#: tcop/postgres.c:1015 +#, c-format +msgid "statement: %s" +msgstr "sentencia: %s" + +#: tcop/postgres.c:1303 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "duración: %s ms sentencia: %s" + +#: tcop/postgres.c:1409 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "no se pueden insertar múltiples órdenes en una sentencia preparada" + +#: tcop/postgres.c:1561 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "duración: %s ms parse: %s: %s" + +#: tcop/postgres.c:1627 tcop/postgres.c:2567 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "no existe una sentencia preparada sin nombre" + +#: tcop/postgres.c:1668 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "el mensaje de enlace (bind) tiene %d formatos de parámetro pero %d parámetros" + +#: tcop/postgres.c:1674 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "el mensaje de enlace (bind) entrega %d parámetros, pero la sentencia preparada «%s» requiere %d" + +#: tcop/postgres.c:1893 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "el formato de datos binarios es incorrecto en el parámetro de enlace %d" + +#: tcop/postgres.c:2020 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "duración: %s ms bind %s%s%s: %s" + +#: tcop/postgres.c:2070 tcop/postgres.c:2651 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "no existe el portal «%s»" + +#: tcop/postgres.c:2155 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2157 tcop/postgres.c:2260 +msgid "execute fetch from" +msgstr "ejecutar fetch desde" + +#: tcop/postgres.c:2158 tcop/postgres.c:2261 +msgid "execute" +msgstr "ejecutar" + +#: tcop/postgres.c:2257 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "duración: %s ms %s %s%s%s: %s" + +#: tcop/postgres.c:2403 +#, c-format +msgid "prepare: %s" +msgstr "prepare: %s" + +#: tcop/postgres.c:2428 +#, c-format +msgid "parameters: %s" +msgstr "parámetros: %s" + +#: tcop/postgres.c:2443 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "razón para abortar: conflicto en la recuperación" + +#: tcop/postgres.c:2459 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "El usuario mantuvo el búfer compartido «clavado» por demasiado tiempo." + +#: tcop/postgres.c:2462 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "El usuario mantuvo una relación bloqueada por demasiado tiempo." + +#: tcop/postgres.c:2465 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "El usuario estaba o pudo haber estado usando un tablespace que debía ser eliminado." + +#: tcop/postgres.c:2468 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "La consulta del usuario pudo haber necesitado examinar versiones de tuplas que debían eliminarse." + +#: tcop/postgres.c:2474 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "El usuario estaba conectado a una base de datos que debía ser eliminada." + +#: tcop/postgres.c:2513 +#, fuzzy, c-format +#| msgid "there is no parameter $%d" +msgid "portal \"%s\" parameter $%d = %s" +msgstr "no hay parámetro $%d" + +#: tcop/postgres.c:2516 +#, fuzzy, c-format +#| msgid "there is no parameter $%d" +msgid "portal \"%s\" parameter $%d" +msgstr "no hay parámetro $%d" + +#: tcop/postgres.c:2522 +#, fuzzy, c-format +#| msgid "unrecognized Snowball parameter: \"%s\"" +msgid "unnamed portal parameter $%d = %s" +msgstr "parámetro Snowball no reconocido: «%s»" + +#: tcop/postgres.c:2525 +#, fuzzy, c-format +#| msgid "no value found for parameter %d" +msgid "unnamed portal parameter $%d" +msgstr "no se encontró un valor para parámetro %d" + +#: tcop/postgres.c:2871 +#, fuzzy, c-format +#| msgid "terminating connection due to unexpected postmaster exit" +msgid "terminating connection because of unexpected SIGQUIT signal" +msgstr "terminando la conexión debido al término inesperado de postmaster" + +#: tcop/postgres.c:2877 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "terminando la conexión debido a una falla en otro proceso servidor" + +#: tcop/postgres.c:2878 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "Postmaster ha ordenado que este proceso servidor cancele la transacción en curso y finalice la conexión, porque otro proceso servidor ha terminado anormalmente y podría haber corrompido la memoria compartida." + +#: tcop/postgres.c:2882 tcop/postgres.c:3243 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "Dentro de un momento debería poder reconectarse y repetir la consulta." + +#: tcop/postgres.c:2889 +#, fuzzy, c-format +#| msgid "terminating connection due to administrator command" +msgid "terminating connection due to immediate shutdown command" +msgstr "terminando la conexión debido a una orden del administrador" + +#: tcop/postgres.c:2975 +#, c-format +msgid "floating-point exception" +msgstr "excepción de coma flotante" + +#: tcop/postgres.c:2976 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "Se ha recibido una señal de una operación de coma flotante no válida. Esto puede significar un resultado fuera de rango o una operación no válida, como una división por cero." + +#: tcop/postgres.c:3147 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "cancelando la autentificación debido a que se agotó el tiempo de espera" + +#: tcop/postgres.c:3151 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "terminando el proceso autovacuum debido a una orden del administrador" + +#: tcop/postgres.c:3155 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "terminando el proceso de replicación lógica debido a una orden del administrador" + +#: tcop/postgres.c:3172 tcop/postgres.c:3182 tcop/postgres.c:3241 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "terminando la conexión debido a un conflicto con la recuperación" + +#: tcop/postgres.c:3193 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "terminando la conexión debido a una orden del administrador" + +#: tcop/postgres.c:3224 +#, c-format +msgid "connection to client lost" +msgstr "se ha perdido la conexión al cliente" + +#: tcop/postgres.c:3294 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "cancelando la sentencia debido a que se agotó el tiempo de espera de candados (locks)" + +#: tcop/postgres.c:3301 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "cancelando la sentencia debido a que se agotó el tiempo de espera de sentencias" + +#: tcop/postgres.c:3308 +#, c-format +msgid "canceling autovacuum task" +msgstr "cancelando tarea de autovacuum" + +#: tcop/postgres.c:3331 +#, c-format +msgid "canceling statement due to user request" +msgstr "cancelando la sentencia debido a una petición del usuario" + +#: tcop/postgres.c:3345 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "terminando la conexión debido a que se agotó el tiempo de espera para transacciones abiertas inactivas" + +#: tcop/postgres.c:3356 +#, fuzzy, c-format +#| msgid "terminating connection due to idle-in-transaction timeout" +msgid "terminating connection due to idle-session timeout" +msgstr "terminando la conexión debido a que se agotó el tiempo de espera para transacciones abiertas inactivas" + +#: tcop/postgres.c:3475 +#, c-format +msgid "stack depth limit exceeded" +msgstr "límite de profundidad de stack alcanzado" + +#: tcop/postgres.c:3476 +#, c-format +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "Incremente el parámetro de configuración «max_stack_depth» (actualmente %dkB), después de asegurarse que el límite de profundidad de stack de la plataforma es adecuado." + +#: tcop/postgres.c:3539 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "«max_stack_depth» no debe exceder %ldkB." + +#: tcop/postgres.c:3541 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "Incremente el límite de profundidad del stack del sistema usando «ulimit -s» o el equivalente de su sistema." + +#: tcop/postgres.c:3897 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "argumentos de línea de órdenes no válidos para proceso servidor: %s" + +#: tcop/postgres.c:3898 tcop/postgres.c:3904 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Pruebe «%s --help» para mayor información." + +#: tcop/postgres.c:3902 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: argumento de línea de órdenes no válido: %s" + +#: tcop/postgres.c:3965 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: no se ha especificado base de datos ni usuario" + +#: tcop/postgres.c:4618 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "subtipo %d de mensaje CLOSE no válido" + +#: tcop/postgres.c:4653 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "subtipo %d de mensaje DESCRIBE no válido" + +#: tcop/postgres.c:4737 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "la invocación «fastpath» de funciones no está soportada en conexiones de replicación" + +#: tcop/postgres.c:4741 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "el protocolo extendido de consultas no está soportado en conexiones de replicación" + +#: tcop/postgres.c:4918 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "desconexión: duración de sesión: %d:%02d:%02d.%03d usuario=%s base=%s host=%s%s%s" + +#: tcop/pquery.c:636 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "el mensaje de enlace (bind) tiene %d formatos de resultado pero la consulta tiene %d columnas" + +#: tcop/pquery.c:939 +#, c-format +msgid "cursor can only scan forward" +msgstr "el cursor sólo se puede desplazar hacia adelante" + +#: tcop/pquery.c:940 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Declárelo con SCROLL para permitirle desplazar hacia atrás." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:414 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "no se puede ejecutar %s en una transacción de sólo lectura" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:432 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "no se puede ejecutar %s durante una operación paralela" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:451 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "no se puede ejecutar %s durante la recuperación" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:469 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "no se puede ejecutar %s durante una operación restringida por seguridad" + +#: tcop/utility.c:913 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "debe ser superusuario para ejecutar CHECKPOINT" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:615 +#, c-format +msgid "multiple DictFile parameters" +msgstr "parámetro DictFile duplicado" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "parámetro AffFile duplicado" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "parámetro Ispell no reconocido: «%s»" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "falta un parámetro AffFile" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:639 +#, c-format +msgid "missing DictFile parameter" +msgstr "falta un parámetro DictFile" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "parámetro Accept duplicado" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "parámetro del diccionario simple no reconocido: «%s»" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "parámetro de sinónimo no reconocido «%s»" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "falta un parámetro Synonyms" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "no se pudo abrir el archivo de sinónimos «%s»: %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "no se pudo abrir el archivo del tesauro «%s»: %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "delimitador inesperado" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "fin de línea o lexema inesperado" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "fin de línea inesperado" + +#: tsearch/dict_thesaurus.c:292 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "demasiados lexemas en la entrada del tesauro" + +#: tsearch/dict_thesaurus.c:416 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "la palabra de muestra «%s» del tesauro no es reconocido por el subdiccionario (regla %d)" + +# XXX -- stopword? +#: tsearch/dict_thesaurus.c:422 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "la palabra de muestra «%s» del tesauro es una stopword (regla %d)" + +# XXX -- stopword? +#: tsearch/dict_thesaurus.c:425 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Use «?» para representar una stopword en una frase muestra." + +# XXX -- stopword? +#: tsearch/dict_thesaurus.c:567 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "la palabra sustituta «%s» del tesauro es una stopword (regla %d)" + +#: tsearch/dict_thesaurus.c:574 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "la palabra sustituta «%s» del tesauro no es reconocida por el subdiccionario (regla %d)" + +#: tsearch/dict_thesaurus.c:586 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "la frase sustituta del tesauro está vacía (regla %d)" + +#: tsearch/dict_thesaurus.c:624 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "parámetro Dictionary duplicado" + +#: tsearch/dict_thesaurus.c:631 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "parámetro no reconocido de tesauro: «%s»" + +#: tsearch/dict_thesaurus.c:643 +#, c-format +msgid "missing Dictionary parameter" +msgstr "falta un paramétro Dictionary" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1062 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "marca de afijo «%s» no válida" + +#: tsearch/spell.c:384 tsearch/spell.c:1066 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "la marca de afijo «%s» fuera de rango" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "caracteres no válidos en la marca de afijo «%s»" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "marca de afijo «%s» no válida con el valor de marca «long»" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "no se pudo abrir el archivo de diccionario «%s»: %m" + +#: tsearch/spell.c:763 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "la expresión regular no es válida: %s" + +#: tsearch/spell.c:1189 tsearch/spell.c:1201 tsearch/spell.c:1760 +#: tsearch/spell.c:1765 tsearch/spell.c:1770 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "alias de afijo «%s» no válido" + +#: tsearch/spell.c:1242 tsearch/spell.c:1313 tsearch/spell.c:1462 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "no se pudo abrir el archivo de afijos «%s»: %m" + +#: tsearch/spell.c:1296 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "el diccionario Ispell sólo permite los valores «default», «long» y «num»" + +#: tsearch/spell.c:1340 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "número no válido de alias de opciones" + +#: tsearch/spell.c:1363 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "el número de aliases excede el número especificado %d" + +#: tsearch/spell.c:1578 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "el archivo de «affix» contiene órdenes en estilos antiguo y nuevo" + +#: tsearch/to_tsany.c:195 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "la cadena es demasiado larga para tsvector (%d bytes, máximo %d bytes)" + +#: tsearch/ts_locale.c:227 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "línea %d del archivo de configuración «%s»: «%s»" + +#: tsearch/ts_locale.c:307 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "conversión desde un wchar_t a la codificación del servidor falló: %m" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 +#: tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "la palabra es demasiado larga para ser indexada" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 +#: tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "Las palabras más largas que %d caracteres son ignoradas." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "nombre de configuración de búsqueda en texto «%s» no válido" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "no se pudo abrir el archivo de stopwords «%s»: %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "el analizador de búsqueda en texto no soporta creación de encabezados (headline)" + +#: tsearch/wparser_def.c:2578 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "parámetro de encabezado (headline) no reconocido: «%s»" + +#: tsearch/wparser_def.c:2597 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "MinWords debería ser menor que MaxWords" + +#: tsearch/wparser_def.c:2601 +#, c-format +msgid "MinWords should be positive" +msgstr "MinWords debería ser positivo" + +#: tsearch/wparser_def.c:2605 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "ShortWord debería ser >= 0" + +#: tsearch/wparser_def.c:2609 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "MaxFragments debería ser >= 0" + +#: utils/adt/acl.c:165 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "el identificador es demasiado largo" + +#: utils/adt/acl.c:166 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "El identificador debe ser menor a %d caracteres." + +#: utils/adt/acl.c:249 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "palabra clave no reconocida: «%s»" + +#: utils/adt/acl.c:250 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "Palabra clave de ACL debe ser «group» o «user»." + +#: utils/adt/acl.c:255 +#, c-format +msgid "missing name" +msgstr "falta un nombre" + +#: utils/adt/acl.c:256 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "Debe venir un nombre después de una palabra clave «group» o «user»." + +#: utils/adt/acl.c:262 +#, c-format +msgid "missing \"=\" sign" +msgstr "falta un signo «=»" + +#: utils/adt/acl.c:315 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "carácter de modo no válido: debe ser uno de «%s»" + +#: utils/adt/acl.c:337 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "debe venir un nombre después del signo «/»" + +#: utils/adt/acl.c:345 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "usando el cedente por omisión con ID %u" + +#: utils/adt/acl.c:531 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "el array ACL contiene tipo de datos incorrecto" + +#: utils/adt/acl.c:535 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "los array de ACL debe ser unidimensional" + +#: utils/adt/acl.c:539 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "los arrays de ACL no pueden contener valores nulos" + +#: utils/adt/acl.c:563 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "basura extra al final de la especificación de la ACL" + +#: utils/adt/acl.c:1198 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "la opción de grant no puede ser otorgada de vuelta a quien la otorgó" + +#: utils/adt/acl.c:1259 +#, c-format +msgid "dependent privileges exist" +msgstr "existen privilegios dependientes" + +#: utils/adt/acl.c:1260 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Use CASCADE para revocarlos también." + +#: utils/adt/acl.c:1514 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert ya no está soportado" + +#: utils/adt/acl.c:1524 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove ya no está soportado" + +#: utils/adt/acl.c:1610 utils/adt/acl.c:1664 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "tipo de privilegio no reconocido: «%s»" + +#: utils/adt/acl.c:3446 utils/adt/regproc.c:101 utils/adt/regproc.c:277 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "no existe la función «%s»" + +#: utils/adt/acl.c:4898 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "debe ser miembro del rol «%s»" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:935 +#: utils/adt/arrayfuncs.c:1543 utils/adt/arrayfuncs.c:3262 +#: utils/adt/arrayfuncs.c:3404 utils/adt/arrayfuncs.c:5945 +#: utils/adt/arrayfuncs.c:6286 utils/adt/arrayutils.c:94 +#: utils/adt/arrayutils.c:103 utils/adt/arrayutils.c:110 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "el tamaño del array excede el máximo permitido (%d)" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:467 +#: utils/adt/array_userfuncs.c:547 utils/adt/json.c:645 utils/adt/json.c:740 +#: utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 +#: utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "no se pudo determinar el tipo de dato de entrada" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "el tipo de entrada no es un array" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/float.c:1233 utils/adt/float.c:1307 utils/adt/float.c:4052 +#: utils/adt/float.c:4066 utils/adt/int.c:757 utils/adt/int.c:779 +#: utils/adt/int.c:793 utils/adt/int.c:807 utils/adt/int.c:838 +#: utils/adt/int.c:859 utils/adt/int.c:976 utils/adt/int.c:990 +#: utils/adt/int.c:1004 utils/adt/int.c:1037 utils/adt/int.c:1051 +#: utils/adt/int.c:1065 utils/adt/int.c:1096 utils/adt/int.c:1178 +#: utils/adt/int.c:1242 utils/adt/int.c:1310 utils/adt/int.c:1316 +#: utils/adt/int8.c:1299 utils/adt/numeric.c:1776 utils/adt/numeric.c:4207 +#: utils/adt/varbit.c:1195 utils/adt/varbit.c:1596 utils/adt/varlena.c:1121 +#: utils/adt/varlena.c:3433 +#, c-format +msgid "integer out of range" +msgstr "entero fuera de rango" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "el argumento debe ser vacío o un array unidimensional" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "no se pueden concatenar arrays incompatibles" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Los arrays con elementos de tipo %s y %s son incompatibles para la concatenación." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Los arrays de dimesiones %d y %d son incompatibles para la concatenación." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "Los arrays con elementos de diferentes dimensiones son incompatibles para la concatenación." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Los arrays con diferentes dimensiones son incompatibles para la concatenación." + +#: utils/adt/array_userfuncs.c:663 utils/adt/array_userfuncs.c:815 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "no está soportada la búsqueda de elementos en arrays multidimensionales" + +#: utils/adt/array_userfuncs.c:687 +#, c-format +msgid "initial position must not be null" +msgstr "la posición inicial no debe ser null" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 +#: utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#: utils/adt/arrayfuncs.c:492 utils/adt/arrayfuncs.c:508 +#: utils/adt/arrayfuncs.c:519 utils/adt/arrayfuncs.c:534 +#: utils/adt/arrayfuncs.c:555 utils/adt/arrayfuncs.c:585 +#: utils/adt/arrayfuncs.c:592 utils/adt/arrayfuncs.c:600 +#: utils/adt/arrayfuncs.c:634 utils/adt/arrayfuncs.c:657 +#: utils/adt/arrayfuncs.c:677 utils/adt/arrayfuncs.c:789 +#: utils/adt/arrayfuncs.c:798 utils/adt/arrayfuncs.c:828 +#: utils/adt/arrayfuncs.c:843 utils/adt/arrayfuncs.c:896 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "literal de array mal formado: «%s»" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "Un «[» debe introducir dimensiones de array especificadas explícitamente." + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "Falta un valor de dimensión de array." + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "Falta «%s» luego de las dimensiones de array." + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2909 +#: utils/adt/arrayfuncs.c:2941 utils/adt/arrayfuncs.c:2956 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "el límite superior no puede ser menor que el límite inferior" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "El valor de array debe comenzar con «{» o información de dimensión." + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "El contenido del array debe empezar con «{»." + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "Las dimensiones del array especificadas no coinciden con el contenido del array." + +#: utils/adt/arrayfuncs.c:493 utils/adt/arrayfuncs.c:520 +#: utils/adt/multirangetypes.c:162 utils/adt/rangetypes.c:2310 +#: utils/adt/rangetypes.c:2318 utils/adt/rowtypes.c:211 +#: utils/adt/rowtypes.c:219 +#, c-format +msgid "Unexpected end of input." +msgstr "Fin inesperado de la entrada." + +#: utils/adt/arrayfuncs.c:509 utils/adt/arrayfuncs.c:556 +#: utils/adt/arrayfuncs.c:586 utils/adt/arrayfuncs.c:635 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "Carácter «%c» inesperado." + +#: utils/adt/arrayfuncs.c:535 utils/adt/arrayfuncs.c:658 +#, c-format +msgid "Unexpected array element." +msgstr "Elemento de array inesperado." + +#: utils/adt/arrayfuncs.c:593 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "Carácter «%c» desemparejado." + +#: utils/adt/arrayfuncs.c:601 utils/adt/jsonfuncs.c:2593 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "Los arrays multidimensionales deben tener sub-arrays con dimensiones coincidentes." + +#: utils/adt/arrayfuncs.c:678 +#, c-format +msgid "Junk after closing right brace." +msgstr "Basura después de la llave derecha de cierre." + +#: utils/adt/arrayfuncs.c:1300 utils/adt/arrayfuncs.c:3370 +#: utils/adt/arrayfuncs.c:5849 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "número incorrecto de dimensiones: %d" + +#: utils/adt/arrayfuncs.c:1311 +#, c-format +msgid "invalid array flags" +msgstr "opciones de array no válidas" + +#: utils/adt/arrayfuncs.c:1333 +#, c-format +msgid "binary data has array element type %u (%s) instead of expected %u (%s)" +msgstr "" + +#: utils/adt/arrayfuncs.c:1377 utils/adt/multirangetypes.c:443 +#: utils/adt/rangetypes.c:333 utils/cache/lsyscache.c:2905 +#, c-format +msgid "no binary input function available for type %s" +msgstr "no hay una función binaria de entrada para el tipo %s" + +#: utils/adt/arrayfuncs.c:1517 +#, c-format +msgid "improper binary format in array element %d" +msgstr "el formato binario no es válido en elemento %d de array" + +#: utils/adt/arrayfuncs.c:1598 utils/adt/multirangetypes.c:448 +#: utils/adt/rangetypes.c:338 utils/cache/lsyscache.c:2938 +#, c-format +msgid "no binary output function available for type %s" +msgstr "no hay una función binaria de salida para el tipo %s" + +#: utils/adt/arrayfuncs.c:2077 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "no está implementada la obtención de segmentos de arrays de largo fijo" + +#: utils/adt/arrayfuncs.c:2255 utils/adt/arrayfuncs.c:2277 +#: utils/adt/arrayfuncs.c:2326 utils/adt/arrayfuncs.c:2565 +#: utils/adt/arrayfuncs.c:2887 utils/adt/arrayfuncs.c:5835 +#: utils/adt/arrayfuncs.c:5861 utils/adt/arrayfuncs.c:5872 +#: utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 +#: utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4427 utils/adt/jsonfuncs.c:4580 +#: utils/adt/jsonfuncs.c:4692 utils/adt/jsonfuncs.c:4741 +#, c-format +msgid "wrong number of array subscripts" +msgstr "número incorrecto de subíndices del array" + +#: utils/adt/arrayfuncs.c:2260 utils/adt/arrayfuncs.c:2368 +#: utils/adt/arrayfuncs.c:2632 utils/adt/arrayfuncs.c:2946 +#, c-format +msgid "array subscript out of range" +msgstr "subíndice de array fuera de rango" + +#: utils/adt/arrayfuncs.c:2265 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "no se puede asignar un valor nulo a un elemento de un array de longitud fija" + +#: utils/adt/arrayfuncs.c:2834 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "no están implementadas las actualizaciones en segmentos de arrays de largo fija" + +#: utils/adt/arrayfuncs.c:2865 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "los subíndices del segmento de array deben especificar ambos bordes" + +#: utils/adt/arrayfuncs.c:2866 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "Cuando se asigna a un segmento de un array vacío, los bordes del segmento deben ser especificados completamente." + +#: utils/adt/arrayfuncs.c:2877 utils/adt/arrayfuncs.c:2973 +#, c-format +msgid "source array too small" +msgstr "el array de origen es demasiado pequeño" + +#: utils/adt/arrayfuncs.c:3528 +#, c-format +msgid "null array element not allowed in this context" +msgstr "los arrays con elementos null no son permitidos en este contexto" + +#: utils/adt/arrayfuncs.c:3630 utils/adt/arrayfuncs.c:3801 +#: utils/adt/arrayfuncs.c:4157 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "no se pueden comparar arrays con elementos de distintos tipos" + +#: utils/adt/arrayfuncs.c:3979 utils/adt/multirangetypes.c:2670 +#: utils/adt/multirangetypes.c:2742 utils/adt/rangetypes.c:1343 +#: utils/adt/rangetypes.c:1407 utils/adt/rowtypes.c:1858 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "no se pudo identificar una función de hash para el tipo %s" + +#: utils/adt/arrayfuncs.c:4072 utils/adt/rowtypes.c:1979 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "no se pudo identificar una función de hash extendida para el tipo %s" + +#: utils/adt/arrayfuncs.c:5249 +#, c-format +msgid "data type %s is not an array type" +msgstr "el tipo %s no es un array" + +#: utils/adt/arrayfuncs.c:5304 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "no se pueden acumular arrays nulos" + +#: utils/adt/arrayfuncs.c:5332 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "no se pueden acumular arrays vacíos" + +#: utils/adt/arrayfuncs.c:5359 utils/adt/arrayfuncs.c:5365 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "no se pueden acumular arrays de distinta dimensionalidad" + +#: utils/adt/arrayfuncs.c:5733 utils/adt/arrayfuncs.c:5773 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "el array de dimensiones o el array de límites inferiores debe ser no nulo" + +#: utils/adt/arrayfuncs.c:5836 utils/adt/arrayfuncs.c:5862 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "El array de dimensiones debe ser unidimensional." + +#: utils/adt/arrayfuncs.c:5841 utils/adt/arrayfuncs.c:5867 +#, c-format +msgid "dimension values cannot be null" +msgstr "los valores de dimensión no pueden ser null" + +#: utils/adt/arrayfuncs.c:5873 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "El array de límites inferiores tiene tamaño diferente que el array de dimensiones." + +#: utils/adt/arrayfuncs.c:6151 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "la eliminación de elementos desde arrays multidimensionales no está soportada" + +#: utils/adt/arrayfuncs.c:6428 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "los umbrales deben ser un array unidimensional" + +#: utils/adt/arrayfuncs.c:6433 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "el array de umbrales no debe contener nulos" + +#: utils/adt/arrayfuncs.c:6666 +#, fuzzy, c-format +#| msgid "number of parameters must be between 0 and 65535\n" +msgid "number of elements to trim must be between 0 and %d" +msgstr "el número de parámetros debe estar entre 0 y 65535\n" + +#: utils/adt/arraysubs.c:93 utils/adt/arraysubs.c:130 +#, c-format +msgid "array subscript must have type integer" +msgstr "los subíndices de arrays deben tener tipo entero" + +#: utils/adt/arraysubs.c:198 utils/adt/arraysubs.c:217 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "subíndice de array en asignación no puede ser nulo" + +#: utils/adt/arrayutils.c:140 +#, c-format +msgid "array lower bound is too large: %d" +msgstr "" + +#: utils/adt/arrayutils.c:240 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "el array de typmod debe ser de tipo cstring[]" + +#: utils/adt/arrayutils.c:245 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "array de typmod debe ser unidimensional" + +#: utils/adt/arrayutils.c:250 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "los arrays de typmod no deben contener valores nulos" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "la conversión de codificación de %s a ASCII no está soportada" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3802 +#: utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:283 +#: utils/adt/float.c:400 utils/adt/float.c:485 utils/adt/float.c:501 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1389 utils/adt/geo_ops.c:1424 +#: utils/adt/geo_ops.c:1432 utils/adt/geo_ops.c:3488 utils/adt/geo_ops.c:4657 +#: utils/adt/geo_ops.c:4672 utils/adt/geo_ops.c:4679 utils/adt/int8.c:126 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:702 +#: utils/adt/numeric.c:721 utils/adt/numeric.c:6861 utils/adt/numeric.c:6885 +#: utils/adt/numeric.c:6909 utils/adt/numeric.c:7878 utils/adt/numutils.c:116 +#: utils/adt/numutils.c:126 utils/adt/numutils.c:170 utils/adt/numutils.c:246 +#: utils/adt/numutils.c:322 utils/adt/oid.c:44 utils/adt/oid.c:58 +#: utils/adt/oid.c:64 utils/adt/oid.c:86 utils/adt/pg_lsn.c:74 +#: utils/adt/tid.c:76 utils/adt/tid.c:84 utils/adt/tid.c:92 +#: utils/adt/timestamp.c:496 utils/adt/uuid.c:136 utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "la sintaxis de entrada no es válida para tipo %s: «%s»" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 +#: utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "el valor «%s» está fuera de rango para el tipo %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:104 utils/adt/int.c:822 utils/adt/int.c:938 +#: utils/adt/int.c:1018 utils/adt/int.c:1080 utils/adt/int.c:1118 +#: utils/adt/int.c:1146 utils/adt/int8.c:600 utils/adt/int8.c:658 +#: utils/adt/int8.c:985 utils/adt/int8.c:1065 utils/adt/int8.c:1127 +#: utils/adt/int8.c:1207 utils/adt/numeric.c:3032 utils/adt/numeric.c:3055 +#: utils/adt/numeric.c:3140 utils/adt/numeric.c:3158 utils/adt/numeric.c:3254 +#: utils/adt/numeric.c:8427 utils/adt/numeric.c:8717 utils/adt/numeric.c:10299 +#: utils/adt/timestamp.c:3281 +#, c-format +msgid "division by zero" +msgstr "división por cero" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "«char» fuera de rango" + +#: utils/adt/date.c:62 utils/adt/timestamp.c:97 utils/adt/varbit.c:105 +#: utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "el modificador de tipo no es válido" + +#: utils/adt/date.c:74 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "la precisión de TIME(%d)%s no debe ser negativa" + +#: utils/adt/date.c:80 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "la precisión de TIME(%d)%s fue reducida al máximo permitido, %d" + +#: utils/adt/date.c:159 utils/adt/date.c:167 utils/adt/formatting.c:4252 +#: utils/adt/formatting.c:4261 utils/adt/formatting.c:4367 +#: utils/adt/formatting.c:4377 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "fecha fuera de rango: «%s»" + +#: utils/adt/date.c:214 utils/adt/date.c:525 utils/adt/date.c:549 +#: utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "fecha fuera de rango" + +#: utils/adt/date.c:260 utils/adt/timestamp.c:580 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "valor en campo de fecha fuera de rango: %d-%02d-%02d" + +#: utils/adt/date.c:267 utils/adt/date.c:276 utils/adt/timestamp.c:586 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "fecha fuera de rango: %d-%02d-%02d" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "no se pueden restar fechas infinitas" + +#: utils/adt/date.c:598 utils/adt/date.c:661 utils/adt/date.c:697 +#: utils/adt/date.c:2881 utils/adt/date.c:2891 +#, c-format +msgid "date out of range for timestamp" +msgstr "fecha fuera de rango para timestamp" + +#: utils/adt/date.c:1127 utils/adt/date.c:1210 utils/adt/date.c:1226 +#, fuzzy, c-format +#| msgid "interval units \"%s\" not supported" +msgid "date units \"%s\" not supported" +msgstr "las unidades de interval «%s» no están soportadas" + +#: utils/adt/date.c:1235 +#, fuzzy, c-format +#| msgid "\"time\" units \"%s\" not recognized" +msgid "date units \"%s\" not recognized" +msgstr "las unidades de «time» «%s» no son reconocidas" + +#: utils/adt/date.c:1318 utils/adt/date.c:1364 utils/adt/date.c:1920 +#: utils/adt/date.c:1951 utils/adt/date.c:1980 utils/adt/date.c:2844 +#: utils/adt/datetime.c:405 utils/adt/datetime.c:1700 +#: utils/adt/formatting.c:4109 utils/adt/formatting.c:4141 +#: utils/adt/formatting.c:4221 utils/adt/formatting.c:4343 utils/adt/json.c:418 +#: utils/adt/json.c:457 utils/adt/timestamp.c:224 utils/adt/timestamp.c:256 +#: utils/adt/timestamp.c:698 utils/adt/timestamp.c:707 +#: utils/adt/timestamp.c:785 utils/adt/timestamp.c:818 +#: utils/adt/timestamp.c:2860 utils/adt/timestamp.c:2881 +#: utils/adt/timestamp.c:2894 utils/adt/timestamp.c:2903 +#: utils/adt/timestamp.c:2911 utils/adt/timestamp.c:2966 +#: utils/adt/timestamp.c:2989 utils/adt/timestamp.c:3002 +#: utils/adt/timestamp.c:3013 utils/adt/timestamp.c:3021 +#: utils/adt/timestamp.c:3681 utils/adt/timestamp.c:3806 +#: utils/adt/timestamp.c:3891 utils/adt/timestamp.c:3981 +#: utils/adt/timestamp.c:4069 utils/adt/timestamp.c:4172 +#: utils/adt/timestamp.c:4674 utils/adt/timestamp.c:4948 +#: utils/adt/timestamp.c:5401 utils/adt/timestamp.c:5415 +#: utils/adt/timestamp.c:5420 utils/adt/timestamp.c:5434 +#: utils/adt/timestamp.c:5467 utils/adt/timestamp.c:5554 +#: utils/adt/timestamp.c:5595 utils/adt/timestamp.c:5599 +#: utils/adt/timestamp.c:5668 utils/adt/timestamp.c:5672 +#: utils/adt/timestamp.c:5686 utils/adt/timestamp.c:5720 utils/adt/xml.c:2232 +#: utils/adt/xml.c:2239 utils/adt/xml.c:2259 utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "timestamp fuera de rango" + +#: utils/adt/date.c:1537 utils/adt/date.c:2339 utils/adt/formatting.c:4429 +#, c-format +msgid "time out of range" +msgstr "hora fuera de rango" + +#: utils/adt/date.c:1589 utils/adt/timestamp.c:595 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "valor en campo de hora fuera de rango: %d:%02d:%02g" + +#: utils/adt/date.c:2109 utils/adt/date.c:2643 utils/adt/float.c:1047 +#: utils/adt/float.c:1123 utils/adt/int.c:614 utils/adt/int.c:661 +#: utils/adt/int.c:696 utils/adt/int8.c:499 utils/adt/numeric.c:2443 +#: utils/adt/timestamp.c:3330 utils/adt/timestamp.c:3361 +#: utils/adt/timestamp.c:3392 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "tamaño «preceding» o «following» no válido en ventana deslizante" + +#: utils/adt/date.c:2208 utils/adt/date.c:2224 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "las unidades de «time» «%s» no son reconocidas" + +#: utils/adt/date.c:2347 +#, c-format +msgid "time zone displacement out of range" +msgstr "desplazamiento de huso horario fuera de rango" + +#: utils/adt/date.c:2986 utils/adt/date.c:3006 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "las unidades de «timestamp with time zone» «%s» no son reconocidas" + +#: utils/adt/date.c:3095 utils/adt/datetime.c:951 utils/adt/datetime.c:1858 +#: utils/adt/datetime.c:4648 utils/adt/timestamp.c:515 +#: utils/adt/timestamp.c:542 utils/adt/timestamp.c:4255 +#: utils/adt/timestamp.c:5426 utils/adt/timestamp.c:5678 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "el huso horario «%s» no es reconocido" + +#: utils/adt/date.c:3127 utils/adt/timestamp.c:5456 utils/adt/timestamp.c:5709 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "el intervalo de huso horario «%s» no debe especificar meses o días" + +#: utils/adt/datetime.c:3775 utils/adt/datetime.c:3782 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "valor de hora/fecha fuera de rango: «%s»" + +#: utils/adt/datetime.c:3784 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Quizás necesite una configuración diferente de «datestyle»." + +#: utils/adt/datetime.c:3789 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "valor de interval fuera de rango: «%s»" + +#: utils/adt/datetime.c:3795 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "desplazamiento de huso horario fuera de rango: «%s»" + +#: utils/adt/datetime.c:4650 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "Este nombre de huso horario aparece en el archivo de configuración para abreviaciones de husos horarios «%s»." + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "puntero a Datum no válido" + +#: utils/adt/dbsize.c:749 utils/adt/dbsize.c:817 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "tamaño no válido: «%s»" + +#: utils/adt/dbsize.c:818 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "Nombre de unidad de tamaño no válido: «%s»." + +#: utils/adt/dbsize.c:819 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Unidades válidas son «bytes«, «kB», «MB», «GB» y «TB»." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "tipo «%s» no es un dominio" + +#: utils/adt/encode.c:68 utils/adt/encode.c:112 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "no se reconoce la codificación: «%s»" + +#: utils/adt/encode.c:82 +#, fuzzy, c-format +#| msgid "result of decoding conversion is too large" +msgid "result of encoding conversion is too large" +msgstr "el resultado de la conversión de codificación es demasiado grande" + +#: utils/adt/encode.c:126 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "el resultado de la conversión de codificación es demasiado grande" + +#: utils/adt/encode.c:261 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "«=» inesperado mientras se decodificaba la secuencia base64" + +#: utils/adt/encode.c:273 +#, fuzzy, c-format +#| msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgid "invalid symbol \"%.*s\" found while decoding base64 sequence" +msgstr "símbolo «%c» no válido al decodificar secuencia base64" + +#: utils/adt/encode.c:304 +#, c-format +msgid "invalid base64 end sequence" +msgstr "secuencia de término base64 no válida" + +#: utils/adt/encode.c:305 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "A los datos de entrada les falta relleno, o están truncados, o están corruptos de alguna otra forma." + +#: utils/adt/enum.c:99 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "uso inseguro del nuevo valor «%s» del tipo enum %s" + +#: utils/adt/enum.c:102 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "Los nuevos valores de enum deben estar comprometidos (committed) antes de que puedan usarse." + +#: utils/adt/enum.c:120 utils/adt/enum.c:130 utils/adt/enum.c:188 +#: utils/adt/enum.c:198 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "la sintaxis de entrada no es válida para el enum %s: «%s»" + +#: utils/adt/enum.c:160 utils/adt/enum.c:226 utils/adt/enum.c:285 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "el valor interno no es válido para enum: %u" + +#: utils/adt/enum.c:445 utils/adt/enum.c:474 utils/adt/enum.c:514 +#: utils/adt/enum.c:534 +#, c-format +msgid "could not determine actual enum type" +msgstr "no se pudo determinar el tipo enum efectivo" + +#: utils/adt/enum.c:453 utils/adt/enum.c:482 +#, c-format +msgid "enum %s contains no values" +msgstr "el enum %s no contiene valores" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "valor fuera de rango: desbordamiento" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "valor fuera de rango: desbordamiento por abajo" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "«%s» está fuera de rango para el tipo real" + +#: utils/adt/float.c:477 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "«%s» está fuera de rango para el tipo double precision" + +#: utils/adt/float.c:1258 utils/adt/float.c:1332 utils/adt/int.c:334 +#: utils/adt/int.c:872 utils/adt/int.c:894 utils/adt/int.c:908 +#: utils/adt/int.c:922 utils/adt/int.c:954 utils/adt/int.c:1192 +#: utils/adt/int8.c:1320 utils/adt/numeric.c:4317 utils/adt/numeric.c:4326 +#, c-format +msgid "smallint out of range" +msgstr "smallint fuera de rango" + +#: utils/adt/float.c:1458 utils/adt/numeric.c:3550 utils/adt/numeric.c:9310 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "no se puede calcular la raíz cuadrada un de número negativo" + +#: utils/adt/float.c:1526 utils/adt/numeric.c:3825 utils/adt/numeric.c:3935 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "cero elevado a una potencia negativa es indefinido" + +#: utils/adt/float.c:1530 utils/adt/numeric.c:3829 utils/adt/numeric.c:3940 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "un número negativo elevado a una potencia no positiva entrega un resultado complejo" + +#: utils/adt/float.c:1706 utils/adt/float.c:1739 utils/adt/numeric.c:3737 +#: utils/adt/numeric.c:9974 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "no se puede calcular logaritmo de cero" + +#: utils/adt/float.c:1710 utils/adt/float.c:1743 utils/adt/numeric.c:3675 +#: utils/adt/numeric.c:3732 utils/adt/numeric.c:9978 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "no se puede calcular logaritmo de un número negativo" + +#: utils/adt/float.c:1776 utils/adt/float.c:1807 utils/adt/float.c:1902 +#: utils/adt/float.c:1929 utils/adt/float.c:1957 utils/adt/float.c:1984 +#: utils/adt/float.c:2131 utils/adt/float.c:2168 utils/adt/float.c:2338 +#: utils/adt/float.c:2394 utils/adt/float.c:2459 utils/adt/float.c:2516 +#: utils/adt/float.c:2707 utils/adt/float.c:2731 +#, c-format +msgid "input is out of range" +msgstr "la entrada está fuera de rango" + +#: utils/adt/float.c:2798 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "parámetro setseed %g fuera del rango permitido [-1,1]" + +#: utils/adt/float.c:4030 utils/adt/numeric.c:1716 +#, c-format +msgid "count must be greater than zero" +msgstr "count debe ser mayor que cero" + +#: utils/adt/float.c:4035 utils/adt/numeric.c:1727 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "el operando, límite inferior y límite superior no pueden ser NaN" + +#: utils/adt/float.c:4041 utils/adt/numeric.c:1732 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "los límites inferior y superior deben ser finitos" + +#: utils/adt/float.c:4075 utils/adt/numeric.c:1746 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "el límite superior no puede ser igual al límite inferior" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "especificación de formato no válida para un valor de interval" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "Los Interval no están ... a valores determinados de fechas de calendario." + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "«EEEE» debe ser el último patrón usado" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "«9» debe ir antes de «PR»" + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "«0» debe ir antes de «PR»" + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "hay múltiples puntos decimales" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "no se puede usar «V» y un punto decimal simultáneamente" + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "no se puede usar «S» dos veces" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "no se puede usar «S» y «PL»/«MI»/«SG»/«PR» simultáneamente" + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "no se puede usar «S» y «MI» simultáneamente" + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "no se puede usar «S» y «PL» simultáneamente" + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "no se puede usar «S» y «SG» simultáneamente" + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "no se puede usar «PR» y «S»/«PL»/«MI»/«SG» simultáneamente" + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "no se puede usar «EEEE» dos veces" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "«EEEE» es incompatible con otros formatos" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "«EEEE» sólo puede ser usado en conjunción con patrones de dígitos y puntos decimales." + +#: utils/adt/formatting.c:1394 +#, fuzzy, c-format +#| msgid "unmatched format separator \"%c\"" +msgid "invalid datetime format separator: \"%s\"" +msgstr "separador de formato «%c» desemparejado" + +#: utils/adt/formatting.c:1521 +#, c-format +msgid "\"%s\" is not a number" +msgstr "«%s» no es un número" + +#: utils/adt/formatting.c:1599 +#, c-format +msgid "case conversion failed: %s" +msgstr "falló la conversión de mayúsculas: %s" + +#: utils/adt/formatting.c:1664 utils/adt/formatting.c:1788 +#: utils/adt/formatting.c:1913 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "no se pudo determinar qué ordenamiento usar para la función %s" + +#: utils/adt/formatting.c:2285 +#, c-format +msgid "invalid combination of date conventions" +msgstr "combinacion invalida de convenciones de fecha" + +#: utils/adt/formatting.c:2286 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr " No mezclar convenciones de semana Gregorianas e ISO en una plantilla formateada" + +#: utils/adt/formatting.c:2309 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "valores en conflicto para le campo \"%s\" en cadena de formato" + +#: utils/adt/formatting.c:2312 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "Este valor se contradice con un seteo previo para el mismo tipo de campo" + +#: utils/adt/formatting.c:2383 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "cadena de texto fuente muy corta para campo formateado \"%s\" " + +#: utils/adt/formatting.c:2386 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "El campo requiere %d caractéres, pero solo quedan %d." + +#: utils/adt/formatting.c:2389 utils/adt/formatting.c:2404 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "Si su cadena de texto no es de ancho modificado, trate de usar el modificador \"FM\" " + +#: utils/adt/formatting.c:2399 utils/adt/formatting.c:2413 +#: utils/adt/formatting.c:2636 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "el valor «%s» no es válido para «%s»" + +#: utils/adt/formatting.c:2401 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "El campo requiere %d caracteres, pero sólo %d pudieron ser analizados." + +#: utils/adt/formatting.c:2415 +#, c-format +msgid "Value must be an integer." +msgstr "El valor debe ser un entero." + +#: utils/adt/formatting.c:2420 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "el valor para «%s» en la cadena de origen está fuera de rango" + +#: utils/adt/formatting.c:2422 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "El valor debe estar en el rango de %d a %d." + +#: utils/adt/formatting.c:2638 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "El valor dado no concuerda con ninguno de los valores permitidos para este campo." + +#: utils/adt/formatting.c:2855 utils/adt/formatting.c:2875 +#: utils/adt/formatting.c:2895 utils/adt/formatting.c:2915 +#: utils/adt/formatting.c:2934 utils/adt/formatting.c:2953 +#: utils/adt/formatting.c:2977 utils/adt/formatting.c:2995 +#: utils/adt/formatting.c:3013 utils/adt/formatting.c:3031 +#: utils/adt/formatting.c:3048 utils/adt/formatting.c:3065 +#, c-format +msgid "localized string format value too long" +msgstr "cadena traducida en cadena de formato es demasiado larga" + +#: utils/adt/formatting.c:3342 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "separador de formato «%c» desemparejado" + +#: utils/adt/formatting.c:3403 +#, fuzzy, c-format +#| msgid "unmatched format separator \"%c\"" +msgid "unmatched format character \"%s\"" +msgstr "separador de formato «%c» desemparejado" + +#: utils/adt/formatting.c:3509 utils/adt/formatting.c:3853 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "el campo de formato «%s» sólo está soportado en to_char" + +#: utils/adt/formatting.c:3684 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "cadena de entrada no válida para «Y,YYY»" + +#: utils/adt/formatting.c:3770 +#, c-format +msgid "input string is too short for datetime format" +msgstr "cadena de entrada muy corta para formato de fecha/hora" + +#: utils/adt/formatting.c:3778 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "quedan caracteres al final de la cadena de entrada después del formato fecha/hora" + +#: utils/adt/formatting.c:4323 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "falta el huso horario en la cadena de entrada para el tipo timestamptz" + +#: utils/adt/formatting.c:4329 +#, c-format +msgid "timestamptz out of range" +msgstr "timestamptz fuera de rango" + +#: utils/adt/formatting.c:4357 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "el formato de fecha/hora tiene huso horario pero no hora" + +#: utils/adt/formatting.c:4409 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "falta el huso horario en la cadena de entrada del tipo timetz" + +#: utils/adt/formatting.c:4415 +#, c-format +msgid "timetz out of range" +msgstr "timetz fuera de rango" + +#: utils/adt/formatting.c:4441 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "el formato de fecha/hora no tiene fecha ni hora" + +#: utils/adt/formatting.c:4574 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "la hora «%d» no es válida para el reloj de 12 horas" + +#: utils/adt/formatting.c:4576 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Use el reloj de 24 horas, o entregue una hora entre 1 y 12." + +#: utils/adt/formatting.c:4687 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "no se puede calcular el día del año sin conocer el año" + +#: utils/adt/formatting.c:5606 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "«EEEE» no está soportado en la entrada" + +#: utils/adt/formatting.c:5618 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "«RN» no está soportado en la entrada" + +#: utils/adt/genfile.c:78 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "no se permiten referencias a directorios padre («..»)" + +#: utils/adt/genfile.c:89 +#, c-format +msgid "absolute path not allowed" +msgstr "no se permiten rutas absolutas" + +#: utils/adt/genfile.c:94 +#, c-format +msgid "path must be in or below the current directory" +msgstr "la ruta debe estar en o debajo del directorio actual" + +#: utils/adt/genfile.c:119 utils/adt/oracle_compat.c:187 +#: utils/adt/oracle_compat.c:285 utils/adt/oracle_compat.c:833 +#: utils/adt/oracle_compat.c:1128 +#, c-format +msgid "requested length too large" +msgstr "el tamaño solicitado es demasiado grande" + +#: utils/adt/genfile.c:136 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "no se pudo posicionar (seek) el archivo «%s»: %m" + +#: utils/adt/genfile.c:176 +#, fuzzy, c-format +#| msgid "requested length too large" +msgid "file length too large" +msgstr "el tamaño solicitado es demasiado grande" + +#: utils/adt/genfile.c:253 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "Debe ser superusuario leer archivos con adminpack 1.0." + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "especificación de línea no válida: A y B no pueden ser ambos cero" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1097 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "especificación de línea no válida: deben ser dos puntos distintos" + +#: utils/adt/geo_ops.c:1410 utils/adt/geo_ops.c:3498 utils/adt/geo_ops.c:4366 +#: utils/adt/geo_ops.c:5260 +#, c-format +msgid "too many points requested" +msgstr "se pidieron demasiados puntos" + +#: utils/adt/geo_ops.c:1472 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "el número de puntos no es válido en el valor «path» externo" + +#: utils/adt/geo_ops.c:2549 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "la función «dist_lb» no está implementada" + +#: utils/adt/geo_ops.c:2568 +#, fuzzy, c-format +#| msgid "function \"dist_lb\" not implemented" +msgid "function \"dist_bl\" not implemented" +msgstr "la función «dist_lb» no está implementada" + +#: utils/adt/geo_ops.c:2987 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "la función «close_sl» no está implementada" + +#: utils/adt/geo_ops.c:3134 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "la función «close_lb» no está implementada" + +#: utils/adt/geo_ops.c:3545 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "el número de puntos no es válido en «polygon» externo" + +#: utils/adt/geo_ops.c:4081 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "la función «poly_distance» no está implementada" + +#: utils/adt/geo_ops.c:4458 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "la función «path_center» no está implementada" + +#: utils/adt/geo_ops.c:4475 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "no se puede convertir un camino abierto en polygon" + +#: utils/adt/geo_ops.c:4725 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "el radio no es válido en el valor «circle» externo" + +#: utils/adt/geo_ops.c:5246 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "no se puede convertir un círculo de radio cero a polygon" + +#: utils/adt/geo_ops.c:5251 +#, c-format +msgid "must request at least 2 points" +msgstr "debe pedir al menos 2 puntos" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector tiene demasiados elementos" + +#: utils/adt/int.c:237 +#, c-format +msgid "invalid int2vector data" +msgstr "datos de int2vector no válidos" + +#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "el oidvector tiene demasiados elementos" + +#: utils/adt/int.c:1508 utils/adt/int8.c:1446 utils/adt/numeric.c:1624 +#: utils/adt/timestamp.c:5771 utils/adt/timestamp.c:5851 +#, c-format +msgid "step size cannot equal zero" +msgstr "el tamaño de paso no puede ser cero" + +#: utils/adt/int8.c:534 utils/adt/int8.c:557 utils/adt/int8.c:571 +#: utils/adt/int8.c:585 utils/adt/int8.c:616 utils/adt/int8.c:640 +#: utils/adt/int8.c:722 utils/adt/int8.c:790 utils/adt/int8.c:796 +#: utils/adt/int8.c:822 utils/adt/int8.c:836 utils/adt/int8.c:860 +#: utils/adt/int8.c:873 utils/adt/int8.c:942 utils/adt/int8.c:956 +#: utils/adt/int8.c:970 utils/adt/int8.c:1001 utils/adt/int8.c:1023 +#: utils/adt/int8.c:1037 utils/adt/int8.c:1051 utils/adt/int8.c:1084 +#: utils/adt/int8.c:1098 utils/adt/int8.c:1112 utils/adt/int8.c:1143 +#: utils/adt/int8.c:1165 utils/adt/int8.c:1179 utils/adt/int8.c:1193 +#: utils/adt/int8.c:1355 utils/adt/int8.c:1390 utils/adt/numeric.c:4276 +#: utils/adt/varbit.c:1676 +#, c-format +msgid "bigint out of range" +msgstr "bigint fuera de rango" + +#: utils/adt/int8.c:1403 +#, c-format +msgid "OID out of range" +msgstr "OID fuera de rango" + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "el valor de llave debe ser escalar, no array, composite o json" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1992 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "no se pudo determinar el tipo de dato para el argumento %d" + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "el nombre de campo no debe ser null" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "la lista de argumentos debe tener un número par de elementos" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "El argumento de %s debe consistir de llaves y valores alternados." + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "el argumento %d no puede ser null" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "Las llaves de un objeto deben ser de texto." + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "un array debe tener dos columnas" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 +#: utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "no se permite el valor nulo como llave en un objeto" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "las dimensiones de array no coinciden" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "la cadena es demasiado larga para representarla como cadena jsonb." + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "Debido a una restricción de la implementación, las cadenas en jsonb no pueden exceder los %d bytes." + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "argumento %d: la llave no puede ser null" + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "las llaves de un objeto deben ser cadenas" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "no se puede convertir un null jsonb a tipo %s" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "no se puede convertir un string jsonb a tipo %s" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "no se puede convertir un numérico jsonb a tipo %s" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "no se puede convertir un booleano jsonb a tipo %s" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "no se puede convertir un array jsonb a tipo %s" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "no se puede convertir un objeto jsonb a tipo %s" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "no se puede convertir un array u objeto jsonb a tipo %s" + +#: utils/adt/jsonb_util.c:751 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "el número de pares en objeto jsonb excede el máximo permitido (%zu)" + +#: utils/adt/jsonb_util.c:792 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "el número de elementos del array jsonb excede el máximo permitido (%zu)" + +#: utils/adt/jsonb_util.c:1666 utils/adt/jsonb_util.c:1686 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "el tamaño total de los elementos del array jsonb excede el máximo de %u bytes" + +#: utils/adt/jsonb_util.c:1747 utils/adt/jsonb_util.c:1782 +#: utils/adt/jsonb_util.c:1802 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "el tamaño total de los elementos del objeto jsonb excede el máximo de %u bytes" + +#: utils/adt/jsonbsubs.c:70 utils/adt/jsonbsubs.c:152 +#, fuzzy, c-format +#| msgid "this build does not support compression" +msgid "jsonb subscript does not support slices" +msgstr "esta instalación no soporta compresión" + +#: utils/adt/jsonbsubs.c:103 utils/adt/jsonbsubs.c:118 +#, fuzzy, c-format +#| msgid "log format \"%s\" is not supported" +msgid "subscript type is not supported" +msgstr "el formato de log «%s» no está soportado" + +#: utils/adt/jsonbsubs.c:104 +#, c-format +msgid "Jsonb subscript must be coerced only to one type, integer or text." +msgstr "" + +#: utils/adt/jsonbsubs.c:119 +#, c-format +msgid "Jsonb subscript must be coerced to either integer or text" +msgstr "" + +#: utils/adt/jsonbsubs.c:140 +#, fuzzy, c-format +#| msgid "array subscript must have type integer" +msgid "jsonb subscript must have text type" +msgstr "los subíndices de arrays deben tener tipo entero" + +#: utils/adt/jsonbsubs.c:208 +#, fuzzy, c-format +#| msgid "array subscript in assignment must not be null" +msgid "jsonb subscript in assignment must not be null" +msgstr "subíndice de array en asignación no puede ser nulo" + +#: utils/adt/jsonfuncs.c:555 utils/adt/jsonfuncs.c:789 +#: utils/adt/jsonfuncs.c:2471 utils/adt/jsonfuncs.c:2911 +#: utils/adt/jsonfuncs.c:3700 utils/adt/jsonfuncs.c:4030 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "no se puede invocar %s en un escalar" + +#: utils/adt/jsonfuncs.c:560 utils/adt/jsonfuncs.c:776 +#: utils/adt/jsonfuncs.c:2913 utils/adt/jsonfuncs.c:3689 +#, c-format +msgid "cannot call %s on an array" +msgstr "no se puede invocar %s en un array" + +#: utils/adt/jsonfuncs.c:685 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "Datos JSON, línea %d: %s%s%s" + +#: utils/adt/jsonfuncs.c:1823 utils/adt/jsonfuncs.c:1858 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "no se puede obtener el largo de array de un escalar" + +#: utils/adt/jsonfuncs.c:1827 utils/adt/jsonfuncs.c:1846 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "no se puede obtener el largo de array de un no-array" + +#: utils/adt/jsonfuncs.c:1923 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "no se puede invocar %s en un no-objeto" + +#: utils/adt/jsonfuncs.c:2162 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "no se puede desconstruir un array como un objeto" + +#: utils/adt/jsonfuncs.c:2174 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "no se puede desconstruir un escalar" + +#: utils/adt/jsonfuncs.c:2220 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "no se pueden extraer elementos de un escalar" + +#: utils/adt/jsonfuncs.c:2224 +#, c-format +msgid "cannot extract elements from an object" +msgstr "no se pudo extraer elementos de un objeto" + +#: utils/adt/jsonfuncs.c:2458 utils/adt/jsonfuncs.c:3915 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "no se puede invocar %s en un no-array" + +#: utils/adt/jsonfuncs.c:2528 utils/adt/jsonfuncs.c:2533 +#: utils/adt/jsonfuncs.c:2550 utils/adt/jsonfuncs.c:2556 +#, c-format +msgid "expected JSON array" +msgstr "se esperaba un array JSON" + +#: utils/adt/jsonfuncs.c:2529 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Vea el valor de la llave «%s»." + +#: utils/adt/jsonfuncs.c:2551 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Vea el elemento %s de la llave «%s»." + +#: utils/adt/jsonfuncs.c:2557 +#, c-format +msgid "See the array element %s." +msgstr "Veo el elemento de array %s." + +#: utils/adt/jsonfuncs.c:2592 +#, c-format +msgid "malformed JSON array" +msgstr "array JSON mal formado" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3419 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "el primer argumento de %s debe ser un tipo de registro" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3443 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "no se pudo determinar el tipo de dato para el resultado de %s" + +#: utils/adt/jsonfuncs.c:3445 +#, c-format +msgid "Provide a non-null record argument, or call the function in the FROM clause using a column definition list." +msgstr "Provea un argumento de registro no-nulo, o invoque la función en la cláusula FROM usando una lista de definición de columnas." + +#: utils/adt/jsonfuncs.c:3932 utils/adt/jsonfuncs.c:4012 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "el argumento de %s debe ser un array de objetos" + +#: utils/adt/jsonfuncs.c:3965 +#, c-format +msgid "cannot call %s on an object" +msgstr "no se puede invocar %s en un objeto" + +#: utils/adt/jsonfuncs.c:4373 utils/adt/jsonfuncs.c:4432 +#: utils/adt/jsonfuncs.c:4512 +#, c-format +msgid "cannot delete from scalar" +msgstr "no se puede eliminar de un escalar" + +#: utils/adt/jsonfuncs.c:4517 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "no se puede eliminar de un objeto usando un índice numérico" + +#: utils/adt/jsonfuncs.c:4585 utils/adt/jsonfuncs.c:4746 +#, c-format +msgid "cannot set path in scalar" +msgstr "no se puede definir una ruta en un escalar" + +#: utils/adt/jsonfuncs.c:4627 utils/adt/jsonfuncs.c:4669 +#, c-format +msgid "null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"" +msgstr "null_value_treatment debe ser «delete_key», «return_target», «use_json_null», o «raise_exception»" + +#: utils/adt/jsonfuncs.c:4640 +#, fuzzy, c-format +#| msgid "slot name must not be null" +msgid "JSON value must not be null" +msgstr "el nombre de slot no debe ser null" + +#: utils/adt/jsonfuncs.c:4641 +#, c-format +msgid "Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "Una excepción fue lanzada porque null_value_treatment es «raise_exception»." + +#: utils/adt/jsonfuncs.c:4642 +#, c-format +msgid "To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed." +msgstr "Para impedir esto, puede cambiar el argumento null_value_treatment o asegurarse que no se pase un nulo SQL." + +#: utils/adt/jsonfuncs.c:4697 +#, c-format +msgid "cannot delete path in scalar" +msgstr "no se puede eliminar una ruta en un escalar" + +#: utils/adt/jsonfuncs.c:4913 +#, c-format +msgid "path element at position %d is null" +msgstr "el elemento en la posición %d de la ruta es null" + +#: utils/adt/jsonfuncs.c:4932 utils/adt/jsonfuncs.c:4963 +#: utils/adt/jsonfuncs.c:5030 +#, c-format +msgid "cannot replace existing key" +msgstr "no se puede reemplazar una llave existente" + +#: utils/adt/jsonfuncs.c:4933 utils/adt/jsonfuncs.c:4964 +#, c-format +msgid "The path assumes key is a composite object, but it is a scalar value." +msgstr "" + +#: utils/adt/jsonfuncs.c:5031 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "Intente usar la función jsonb_set para reemplazar el valor de la llave." + +#: utils/adt/jsonfuncs.c:5135 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "el elemento de ruta en la posición %d no es un entero: «%s»" + +#: utils/adt/jsonfuncs.c:5152 +#, fuzzy, c-format +#| msgid "path element at position %d is not an integer: \"%s\"" +msgid "path element at position %d is out of range: %d" +msgstr "el elemento de ruta en la posición %d no es un entero: «%s»" + +#: utils/adt/jsonfuncs.c:5304 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "indicador de tipo errónea, sólo se permiten arrays y tipos escalares" + +#: utils/adt/jsonfuncs.c:5311 +#, c-format +msgid "flag array element is not a string" +msgstr "elemento del array de opciones no es un string" + +#: utils/adt/jsonfuncs.c:5312 utils/adt/jsonfuncs.c:5334 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "Los valores posibles son: «string», «numeric», «boolean», «key» y «all»." + +#: utils/adt/jsonfuncs.c:5332 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "indicador erróneo en array de indicadores: «%s»" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ no es permitido en expresiones raíz" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST sólo está permitido en subíndices de array" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "se esperaba un único resultado booleano" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "el argumento «vars» no es un objeto" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "Los parámetros jsonpath deben codificarse como pares llave-valor del objeto «vars»." + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "el objeto JSON no contiene la llave «%s»" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "el método de acceso a un miembro jsonpath sólo puede aplicarse a un objeto" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "el método de acceso comodín de array jsonpath sólo puede aplicarse a un array" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "subíndice de array jsonpath fuera de los bordes" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "el método de acceso de array jsonpath sólo puede aplicarse a un array" + +#: utils/adt/jsonpath_exec.c:872 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "el método de acesso comodín de objeto jsonpath sólo puede aplicarse a un objeto" + +#: utils/adt/jsonpath_exec.c:1002 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "el método de ítem jsonpath .%s() sólo puede aplicase a un array" + +#: utils/adt/jsonpath_exec.c:1055 +#, fuzzy, c-format +#| msgid "string argument of jsonpath item method .%s() is not a valid representation of a double precision number" +msgid "numeric argument of jsonpath item method .%s() is out of range for type double precision" +msgstr "el argumento cadena del método de item jsonpath .%s() no es una representación válida de un número de precisión doble" + +#: utils/adt/jsonpath_exec.c:1076 +#, c-format +msgid "string argument of jsonpath item method .%s() is not a valid representation of a double precision number" +msgstr "el argumento cadena del método de item jsonpath .%s() no es una representación válida de un número de precisión doble" + +#: utils/adt/jsonpath_exec.c:1089 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "el método de ítem jsonpath .%s() sólo puede aplicarse a un valor numérico o de cadena" + +#: utils/adt/jsonpath_exec.c:1579 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "el operando izquiero del operador jsonpath %s no es un valor numérico escalar" + +#: utils/adt/jsonpath_exec.c:1586 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "el operando derecho del operador jsonpath %s no es un valor numérico escalar" + +#: utils/adt/jsonpath_exec.c:1654 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "el operando del operador jsonpath unario %s no es un valor numérico" + +#: utils/adt/jsonpath_exec.c:1752 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "el método de ítem jsonpath .%s() sólo puede aplicarse a un valor numérico" + +#: utils/adt/jsonpath_exec.c:1792 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "el método de ítem jsonpath .%s() sólo puede aplicase a una cadena" + +#: utils/adt/jsonpath_exec.c:1886 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "el formato de fecha/hora no se reconoce: «%s»" + +#: utils/adt/jsonpath_exec.c:1888 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "Use un argumento de patrón fecha/hora para especificar el formato de entrada del dato." + +#: utils/adt/jsonpath_exec.c:1956 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "el método de ítem jsonpath .%s() sólo puede ser aplicado a un objeto" + +#: utils/adt/jsonpath_exec.c:2138 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "no se pudo encontrar la variable jsonpath «%s»" + +#: utils/adt/jsonpath_exec.c:2402 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "el subíndice de array jsonpath no es un único valor numérico" + +#: utils/adt/jsonpath_exec.c:2414 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "subíndice de array jsonpath fuera del rango entero" + +#: utils/adt/jsonpath_exec.c:2591 +#, fuzzy, c-format +#| msgid "cannot convert value from %s to %s without timezone usage" +msgid "cannot convert value from %s to %s without time zone usage" +msgstr "no se puede convertir el valor de %s a %s sin uso de huso horario" + +#: utils/adt/jsonpath_exec.c:2593 +#, fuzzy, c-format +#| msgid "Use *_tz() function for timezone support." +msgid "Use *_tz() function for time zone support." +msgstr "Utilice una función *_tz() para el soporte de huso horario." + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "el argumento levenshtein excede el largo máximo de %d caracteres" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "los ordenamientos no determinísticos no están soportados para LIKE" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "no se pudo determinar qué ordenamiento (collation) usar para ILIKE" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "los ordenamientos no determinísticos no están soportados para ILIKE" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "el patrón de LIKE debe no terminar con un carácter de escape" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "cadena de escape no válida" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "La cadena de escape debe ser vacía o un carácter." + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "no está soportada la comparación insensible a mayúsculas en bytea" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "no está soportada la comparación con expresiones regulares en bytea" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "valor de octeto no válido en valor «macaddr»: «%s»" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "datos macaddr8 fuera de rango para convertir a macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Sólo las direcciones que tienen FF y FF como valores en el cuarto y quinto bytes desde la izquierda, por ejemplo xx:xx:xx:ff:fe:xx:xx:xx se pueden convertir de macaddr8 a macaddr." + +#: utils/adt/mcxtfuncs.c:184 +#, fuzzy, c-format +#| msgid "must be superuser to alter a type" +msgid "must be a superuser to log memory contexts" +msgstr "debe ser superusuario para alterar un tipo" + +#: utils/adt/misc.c:243 +#, c-format +msgid "global tablespace never has databases" +msgstr "el tablespace global nunca tiene bases de datos" + +#: utils/adt/misc.c:265 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u no es un OID de tablespace" + +#: utils/adt/misc.c:455 +msgid "unreserved" +msgstr "no reservado" + +#: utils/adt/misc.c:459 +msgid "unreserved (cannot be function or type name)" +msgstr "no reservado (no puede ser nombre de función o de tipo)" + +#: utils/adt/misc.c:463 +msgid "reserved (can be function or type name)" +msgstr "reservado (puede ser nombre de función o de tipo)" + +#: utils/adt/misc.c:467 +msgid "reserved" +msgstr "reservado" + +#: utils/adt/misc.c:478 +msgid "can be bare label" +msgstr "" + +#: utils/adt/misc.c:483 +msgid "requires AS" +msgstr "" + +#: utils/adt/misc.c:730 utils/adt/misc.c:744 utils/adt/misc.c:783 +#: utils/adt/misc.c:789 utils/adt/misc.c:795 utils/adt/misc.c:818 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "la cadena no es un identificador válido: «%s»" + +#: utils/adt/misc.c:732 +#, c-format +msgid "String has unclosed double quotes." +msgstr "La cadena tiene comillas dobles sin cerrar." + +#: utils/adt/misc.c:746 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "El identificador en comillas no debe ser vacío." + +#: utils/adt/misc.c:785 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "No hay un identificador válido antes de «.»." + +#: utils/adt/misc.c:791 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "No hay un identificador válido después de «.»." + +#: utils/adt/misc.c:849 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "el formato de log «%s» no está soportado" + +#: utils/adt/misc.c:850 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "Los formatos de registro admitidos son \"stderr\" y \"csvlog\"." + +#: utils/adt/multirangetypes.c:147 utils/adt/multirangetypes.c:160 +#: utils/adt/multirangetypes.c:189 utils/adt/multirangetypes.c:259 +#: utils/adt/multirangetypes.c:283 +#, fuzzy, c-format +#| msgid "malformed range literal: \"%s\"" +msgid "malformed multirange literal: \"%s\"" +msgstr "literal de rango mal formado: «%s»" + +#: utils/adt/multirangetypes.c:149 +#, fuzzy, c-format +#| msgid "Missing left parenthesis." +msgid "Missing left brace." +msgstr "Falta paréntesis izquierdo." + +#: utils/adt/multirangetypes.c:191 +#, fuzzy, c-format +#| msgid "unexpected array start" +msgid "Expected range start." +msgstr "inicio de array inesperado" + +#: utils/adt/multirangetypes.c:261 +#, fuzzy, c-format +#| msgid "unexpected end of line" +msgid "Expected comma or end of multirange." +msgstr "fin de línea inesperado" + +#: utils/adt/multirangetypes.c:285 +#, fuzzy, c-format +#| msgid "Junk after closing right brace." +msgid "Junk after right brace." +msgstr "Basura después de la llave derecha de cierre." + +#: utils/adt/multirangetypes.c:971 +#, fuzzy, c-format +#| msgid "thresholds must be one-dimensional array" +msgid "multiranges cannot be constructed from multi-dimensional arrays" +msgstr "los umbrales deben ser un array unidimensional" + +#: utils/adt/multirangetypes.c:977 utils/adt/multirangetypes.c:1042 +#, fuzzy, c-format +#| msgid "type %s is not a composite type" +msgid "type %u does not match constructor type" +msgstr "el tipo %s no es un tipo compuesto" + +#: utils/adt/multirangetypes.c:999 +#, c-format +msgid "multirange values cannot contain NULL members" +msgstr "" + +#: utils/adt/multirangetypes.c:1349 +#, fuzzy, c-format +#| msgid "%s must be called inside a transaction" +msgid "range_agg must be called with a range" +msgstr "%s no debe ser ejecutado dentro de una transacción" + +#: utils/adt/multirangetypes.c:1420 +#, c-format +msgid "range_intersect_agg must be called with a multirange" +msgstr "" + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "valor cidr no válido: «%s»" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "El valor tiene bits definidos a la derecha de la máscara" + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 +#: utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "no se pudo dar formato al valor inet: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "familia de dirección no válida en valor «%s» externo" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "bits no válidos en valor «%s» externo" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "largo no válido en valor «%s» externo" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "valor externo «cidr» no válido" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "largo de máscara no válido: %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "no se pudo dar formato al valor cidr: %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "no se pueden mezclar direcciones de familias diferentes" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "no se puede hacer AND entre valores inet de distintos tamaños" + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "no se puede hacer OR entre valores inet de distintos tamaños" + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "el resultado está fuera de rango" + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "no se puede sustraer valores inet de distintos tamaños" + +#: utils/adt/numeric.c:975 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "el signo no es válido en el valor «numeric» externo" + +#: utils/adt/numeric.c:981 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "la escala no es válida en el valor «numeric» externo" + +#: utils/adt/numeric.c:990 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "hay un dígito no válido en el valor «numeric» externo" + +#: utils/adt/numeric.c:1203 utils/adt/numeric.c:1217 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "la precisión %d de NUMERIC debe estar entre 1 y %d" + +#: utils/adt/numeric.c:1208 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "la escala de NUMERIC, %d, debe estar entre 0 y la precisión %d" + +#: utils/adt/numeric.c:1226 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "modificador de tipo NUMERIC no es válido" + +#: utils/adt/numeric.c:1584 +#, c-format +msgid "start value cannot be NaN" +msgstr "el valor de inicio no puede ser NaN" + +#: utils/adt/numeric.c:1588 +#, fuzzy, c-format +#| msgid "start value cannot be NaN" +msgid "start value cannot be infinity" +msgstr "el valor de inicio no puede ser NaN" + +#: utils/adt/numeric.c:1595 +#, c-format +msgid "stop value cannot be NaN" +msgstr "el valor de término no puede ser NaN" + +#: utils/adt/numeric.c:1599 +#, fuzzy, c-format +#| msgid "stop value cannot be NaN" +msgid "stop value cannot be infinity" +msgstr "el valor de término no puede ser NaN" + +#: utils/adt/numeric.c:1612 +#, c-format +msgid "step size cannot be NaN" +msgstr "el tamaño de paso no puede ser NaN" + +#: utils/adt/numeric.c:1616 +#, fuzzy, c-format +#| msgid "step size cannot be NaN" +msgid "step size cannot be infinity" +msgstr "el tamaño de paso no puede ser NaN" + +#: utils/adt/numeric.c:3490 +#, fuzzy, c-format +#| msgid "zero raised to a negative power is undefined" +msgid "factorial of a negative number is undefined" +msgstr "cero elevado a una potencia negativa es indefinido" + +#: utils/adt/numeric.c:3500 utils/adt/numeric.c:6924 utils/adt/numeric.c:7408 +#: utils/adt/numeric.c:9783 utils/adt/numeric.c:10221 utils/adt/numeric.c:10335 +#: utils/adt/numeric.c:10408 +#, c-format +msgid "value overflows numeric format" +msgstr "el valor excede el formato numeric" + +#: utils/adt/numeric.c:4185 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "no se puede convertir NaN a entero" + +#: utils/adt/numeric.c:4189 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to integer" +msgstr "no se puede convertir infinito a numeric" + +#: utils/adt/numeric.c:4263 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "no se puede convertir NaN a bigint" + +#: utils/adt/numeric.c:4267 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to bigint" +msgstr "no se puede convertir infinito a numeric" + +#: utils/adt/numeric.c:4304 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "no se puede convertir NaN a smallint" + +#: utils/adt/numeric.c:4308 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to smallint" +msgstr "no se puede convertir infinito a numeric" + +#: utils/adt/numeric.c:4499 +#, fuzzy, c-format +#| msgid "cannot convert NaN to bigint" +msgid "cannot convert NaN to pg_lsn" +msgstr "no se puede convertir NaN a bigint" + +#: utils/adt/numeric.c:4503 +#, fuzzy, c-format +#| msgid "cannot convert infinity to numeric" +msgid "cannot convert infinity to pg_lsn" +msgstr "no se puede convertir infinito a numeric" + +#: utils/adt/numeric.c:4512 +#, fuzzy, c-format +#| msgid "bigint out of range" +msgid "pg_lsn out of range" +msgstr "bigint fuera de rango" + +#: utils/adt/numeric.c:7492 utils/adt/numeric.c:7539 +#, c-format +msgid "numeric field overflow" +msgstr "desbordamiento de campo numeric" + +#: utils/adt/numeric.c:7493 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "Un campo con precisión %d, escala %d debe redondear a un valor absoluto menor que %s%d." + +#: utils/adt/numeric.c:7540 +#, fuzzy, c-format +#| msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgid "A field with precision %d, scale %d cannot hold an infinite value." +msgstr "Un campo con precisión %d, escala %d debe redondear a un valor absoluto menor que %s%d." + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "el valor «%s» está fuera de rango para un entero de 8 bits" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "datos de oidvector no válidos" + +#: utils/adt/oracle_compat.c:970 +#, c-format +msgid "requested character too large" +msgstr "el carácter solicitado es demasiado grande" + +#: utils/adt/oracle_compat.c:1020 utils/adt/oracle_compat.c:1082 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "el carácter pedido es demasiado largo para el encoding: %d" + +#: utils/adt/oracle_compat.c:1061 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "el carácter pedido no es válido para el encoding: %d" + +#: utils/adt/oracle_compat.c:1075 +#, c-format +msgid "null character not permitted" +msgstr "el carácter nulo no está permitido" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "el valor de percentil %g no está entre 0 y 1" + +#: utils/adt/pg_locale.c:1228 +#, c-format +msgid "Apply system library package updates." +msgstr "Aplique actualizaciones de paquetes de bibliotecas del sistema." + +#: utils/adt/pg_locale.c:1442 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "no se pudo crear la configuración regional «%s»: %m" + +#: utils/adt/pg_locale.c:1445 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "El sistema operativo no pudo encontrar datos de configuración regional para la configuración «%s»." + +#: utils/adt/pg_locale.c:1547 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "los ordenamientos (collation) con valores collate y ctype diferentes no están soportados en esta plataforma" + +#: utils/adt/pg_locale.c:1556 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "el proveedor de ordenamientos LIBC no está soportado en esta plataforma" + +#: utils/adt/pg_locale.c:1568 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "los ordenamientos (collation) con valores collate y ctype diferentes no están soportados por ICU" + +#: utils/adt/pg_locale.c:1574 utils/adt/pg_locale.c:1661 +#: utils/adt/pg_locale.c:1940 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "no se pudo abrir el «collator» para la configuración regional «%s»: %s" + +#: utils/adt/pg_locale.c:1588 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU no está soportado en este servidor" + +#: utils/adt/pg_locale.c:1609 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "la extensión «%s» no tiene versión actual, pero se especificó una versión" + +#: utils/adt/pg_locale.c:1616 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "el ordenamiento (collation) «%s» tiene una discordancia de versión" + +#: utils/adt/pg_locale.c:1618 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "El ordenamiento en la base de datos fue creado usando la versión %s, pero el sistema operativo provee la versión %s." + +#: utils/adt/pg_locale.c:1621 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "Reconstruya todos los objetos afectados por este ordenamiento y ejecute ALTER COLLATION %s REFRESH VERSION, o construya PostgreSQL con la versión correcta de la biblioteca." + +#: utils/adt/pg_locale.c:1692 +#, fuzzy, c-format +#| msgid "could not create locale \"%s\": %m" +msgid "could not load locale \"%s\"" +msgstr "no se pudo crear la configuración regional «%s»: %m" + +#: utils/adt/pg_locale.c:1717 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "no se pudo obtener la versión de «collation» para la configuración regional «%s»: código de error %lu" + +#: utils/adt/pg_locale.c:1755 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "la codificación «%s» no estæ soportada por ICU" + +#: utils/adt/pg_locale.c:1762 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "no se pudo abrir el conversor ICU para la codificación «%s»: %s" + +#: utils/adt/pg_locale.c:1793 utils/adt/pg_locale.c:1802 +#: utils/adt/pg_locale.c:1831 utils/adt/pg_locale.c:1841 +#, c-format +msgid "%s failed: %s" +msgstr "%s falló: %s" + +#: utils/adt/pg_locale.c:2113 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "el carácter multibyte no es válido para esta configuración regional" + +#: utils/adt/pg_locale.c:2114 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "La configuración regional LC_CTYPE del servidor es probablemente incompatible con la codificación de la base de datos." + +#: utils/adt/pg_lsn.c:263 +#, fuzzy, c-format +#| msgid "cannot convert NaN to bigint" +msgid "cannot add NaN to pg_lsn" +msgstr "no se puede convertir NaN a bigint" + +#: utils/adt/pg_lsn.c:297 +#, fuzzy, c-format +#| msgid "cannot subtract infinite dates" +msgid "cannot subtract NaN from pg_lsn" +msgstr "no se pueden restar fechas infinitas" + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "la función sólo puede invocarse cuando el servidor está en modo de actualización binaria" + +#: utils/adt/pgstatfuncs.c:503 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "nombre de orden no válido: «%s»" + +#: utils/adt/pseudotypes.c:58 utils/adt/pseudotypes.c:92 +#, c-format +msgid "cannot display a value of type %s" +msgstr "no se puede desplegar un valor de tipo %s" + +#: utils/adt/pseudotypes.c:321 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "no se puede aceptar un valor de un tipo inconcluso" + +#: utils/adt/pseudotypes.c:331 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "no se puede desplegar un valor de un tipo inconcluso" + +#: utils/adt/rangetypes.c:404 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "el argumento de opciones del constructor de rango no debe ser null" + +#: utils/adt/rangetypes.c:1003 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "el resultado de la diferencia de rangos no sería contiguo" + +#: utils/adt/rangetypes.c:1064 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "el resultado de la unión de rangos no sería contiguo" + +#: utils/adt/rangetypes.c:1214 +#, c-format +msgid "range_intersect_agg must be called with a range" +msgstr "" + +#: utils/adt/rangetypes.c:1689 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "el límite inferior del rango debe ser menor o igual al límite superior del rango" + +#: utils/adt/rangetypes.c:2112 utils/adt/rangetypes.c:2125 +#: utils/adt/rangetypes.c:2139 +#, c-format +msgid "invalid range bound flags" +msgstr "opciones de bordes de rango no válidas" + +#: utils/adt/rangetypes.c:2113 utils/adt/rangetypes.c:2126 +#: utils/adt/rangetypes.c:2140 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Los valores aceptables son «[]», «[)», «(]» y «()»." + +#: utils/adt/rangetypes.c:2205 utils/adt/rangetypes.c:2222 +#: utils/adt/rangetypes.c:2235 utils/adt/rangetypes.c:2253 +#: utils/adt/rangetypes.c:2264 utils/adt/rangetypes.c:2308 +#: utils/adt/rangetypes.c:2316 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "literal de rango mal formado: «%s»" + +#: utils/adt/rangetypes.c:2207 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "Basura a continuación de la palabra «empty»." + +#: utils/adt/rangetypes.c:2224 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Falta paréntesis o corchete izquierdo." + +#: utils/adt/rangetypes.c:2237 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Coma faltante después del límite inferior." + +#: utils/adt/rangetypes.c:2255 +#, c-format +msgid "Too many commas." +msgstr "Demasiadas comas." + +#: utils/adt/rangetypes.c:2266 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "Basura después del paréntesis o corchete derecho." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4560 +#, c-format +msgid "regular expression failed: %s" +msgstr "la expresión regular falló: %s" + +#: utils/adt/regexp.c:426 +#, fuzzy, c-format +#| msgid "invalid regular expression option: \"%c\"" +msgid "invalid regular expression option: \"%.*s\"" +msgstr "opción de expresión regular no válida: «%c»" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "la expresión regular SQL no puede contener más de dos separadores escape-comilla doble" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s no soporta la opción «global»" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "En su lugar, utilice la función regexp_matches." + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "demasiadas coincidencias de la expresión regular" + +#: utils/adt/regproc.c:105 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "existe más de una función llamada «%s»" + +#: utils/adt/regproc.c:543 +#, c-format +msgid "more than one operator named %s" +msgstr "existe más de un operador llamado %s" + +#: utils/adt/regproc.c:715 utils/adt/regproc.c:756 utils/adt/regproc.c:2055 +#: utils/adt/ruleutils.c:9650 utils/adt/ruleutils.c:9819 +#, c-format +msgid "too many arguments" +msgstr "demasiados argumentos" + +#: utils/adt/regproc.c:716 utils/adt/regproc.c:757 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Provea dos tipos de argumento para un operador." + +#: utils/adt/regproc.c:1639 utils/adt/regproc.c:1663 utils/adt/regproc.c:1764 +#: utils/adt/regproc.c:1788 utils/adt/regproc.c:1890 utils/adt/regproc.c:1895 +#: utils/adt/varlena.c:3709 utils/adt/varlena.c:3714 +#, c-format +msgid "invalid name syntax" +msgstr "la sintaxis de nombre no es válida" + +#: utils/adt/regproc.c:1953 +#, c-format +msgid "expected a left parenthesis" +msgstr "se esperaba un paréntesis izquierdo" + +#: utils/adt/regproc.c:1969 +#, c-format +msgid "expected a right parenthesis" +msgstr "se esperaba un paréntesis derecho" + +#: utils/adt/regproc.c:1988 +#, c-format +msgid "expected a type name" +msgstr "se esperaba un nombre de tipo" + +#: utils/adt/regproc.c:2020 +#, c-format +msgid "improper type name" +msgstr "el nombre de tipo no es válido" + +#: utils/adt/ri_triggers.c:300 utils/adt/ri_triggers.c:1545 +#: utils/adt/ri_triggers.c:2530 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "inserción o actualización en la tabla «%s» viola la llave foránea «%s»" + +#: utils/adt/ri_triggers.c:303 utils/adt/ri_triggers.c:1548 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL no permite la mezcla de valores de clave nulos y no nulos." + +#: utils/adt/ri_triggers.c:1965 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "la función «%s» debe ser ejecutada en INSERT" + +#: utils/adt/ri_triggers.c:1971 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "la función «%s» debe ser ejecutada en UPDATE" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "la función «%s» debe ser ejecutada en DELETE" + +#: utils/adt/ri_triggers.c:2000 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "no hay una entrada en pg_constraint para el trigger «%s» en tabla «%s»" + +#: utils/adt/ri_triggers.c:2002 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "Elimine este trigger de integridad referencial y sus pares, y utilice ALTER TABLE ADD CONSTRAINT." + +#: utils/adt/ri_triggers.c:2355 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "la consulta de integridad referencial en «%s» de la restricción «%s» en «%s» entregó un resultado inesperado" + +#: utils/adt/ri_triggers.c:2359 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Esto probablemente es causado por una regla que reescribió la consulta." + +#: utils/adt/ri_triggers.c:2520 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "eliminar la partición «%s» viola la llave foránea «%s»" + +#: utils/adt/ri_triggers.c:2523 utils/adt/ri_triggers.c:2548 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "La llave (%s)=(%s) todavía es referida desde la tabla «%s»." + +#: utils/adt/ri_triggers.c:2534 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "La llave (%s)=(%s) no está presente en la tabla «%s»." + +#: utils/adt/ri_triggers.c:2537 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "La llave no está presente en la tabla «%s»." + +#: utils/adt/ri_triggers.c:2543 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "update o delete en «%s» viola la llave foránea «%s» en la tabla «%s»" + +#: utils/adt/ri_triggers.c:2551 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "La llave todavía es referida desde la tabla «%s»." + +#: utils/adt/rowtypes.c:105 utils/adt/rowtypes.c:483 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "el ingreso de tipos compuestos anónimos no está implementado" + +#: utils/adt/rowtypes.c:157 utils/adt/rowtypes.c:186 utils/adt/rowtypes.c:209 +#: utils/adt/rowtypes.c:217 utils/adt/rowtypes.c:269 utils/adt/rowtypes.c:277 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "literal de record mal formado: «%s»" + +#: utils/adt/rowtypes.c:158 +#, c-format +msgid "Missing left parenthesis." +msgstr "Falta paréntesis izquierdo." + +#: utils/adt/rowtypes.c:187 +#, c-format +msgid "Too few columns." +msgstr "Muy pocas columnas." + +#: utils/adt/rowtypes.c:270 +#, c-format +msgid "Too many columns." +msgstr "Demasiadas columnas." + +#: utils/adt/rowtypes.c:278 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Basura después del paréntesis derecho." + +#: utils/adt/rowtypes.c:532 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "número de columnas erróneo: %d, se esperaban %d" + +#: utils/adt/rowtypes.c:574 +#, c-format +msgid "binary data has type %u (%s) instead of expected %u (%s) in record column %d" +msgstr "" + +#: utils/adt/rowtypes.c:641 +#, c-format +msgid "improper binary format in record column %d" +msgstr "formato binario incorrecto en la columna record %d" + +#: utils/adt/rowtypes.c:932 utils/adt/rowtypes.c:1178 utils/adt/rowtypes.c:1436 +#: utils/adt/rowtypes.c:1682 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "no se pueden comparar los tipos de columnas disímiles %s y %s en la columna %d" + +#: utils/adt/rowtypes.c:1023 utils/adt/rowtypes.c:1248 +#: utils/adt/rowtypes.c:1533 utils/adt/rowtypes.c:1718 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "no se pueden comparar registros con cantidad distinta de columnas" + +#: utils/adt/ruleutils.c:5077 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "la regla «%s» tiene el tipo de evento no soportado %d" + +#: utils/adt/timestamp.c:109 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "la precisión de TIMESTAMP(%d)%s no debe ser negativa" + +#: utils/adt/timestamp.c:115 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "la precisión de TIMESTAMP(%d)%s fue reducida al máximo permitido, %d" + +#: utils/adt/timestamp.c:178 utils/adt/timestamp.c:436 utils/misc/guc.c:12411 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestamp fuera de rango: «%s»" + +#: utils/adt/timestamp.c:374 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "la precisión de timestamp(%d) debe estar entre %d y %d" + +#: utils/adt/timestamp.c:498 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "Los husos horarios numéricos deben tener «-» o «+» como su primer carácter." + +#: utils/adt/timestamp.c:511 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "huso horario numérico «%s» fuera de rango" + +#: utils/adt/timestamp.c:607 utils/adt/timestamp.c:617 +#: utils/adt/timestamp.c:625 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestamp fuera de rango: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:726 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "el timestamp no puede ser NaN" + +#: utils/adt/timestamp.c:744 utils/adt/timestamp.c:756 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "timestamp fuera de rango: «%g»" + +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "modificador de tipo INTERVAL no válido" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "la precisión de INTERVAL(%d) no debe ser negativa" + +#: utils/adt/timestamp.c:1090 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "la precisión de INTERVAL(%d) fue reducida al máximo permitido, %d" + +#: utils/adt/timestamp.c:1472 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "la precisión de interval(%d) debe estar entre %d y %d" + +#: utils/adt/timestamp.c:2660 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "no se pueden restar timestamps infinitos" + +#: utils/adt/timestamp.c:3837 utils/adt/timestamp.c:4015 +#, fuzzy, c-format +#| msgid "bigint out of range" +msgid "origin out of range" +msgstr "bigint fuera de rango" + +#: utils/adt/timestamp.c:3842 utils/adt/timestamp.c:4020 +#, c-format +msgid "timestamps cannot be binned into intervals containing months or years" +msgstr "" + +#: utils/adt/timestamp.c:3973 utils/adt/timestamp.c:4610 +#: utils/adt/timestamp.c:4810 utils/adt/timestamp.c:4857 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "las unidades de timestamp «%s» no están soportadas" + +#: utils/adt/timestamp.c:3987 utils/adt/timestamp.c:4564 +#: utils/adt/timestamp.c:4867 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "las unidades de timestamp «%s» no son reconocidas" + +#: utils/adt/timestamp.c:4161 utils/adt/timestamp.c:4605 +#: utils/adt/timestamp.c:5081 utils/adt/timestamp.c:5129 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "las unidades de timestamp with time zone «%s» no están soportadas" + +#: utils/adt/timestamp.c:4178 utils/adt/timestamp.c:4559 +#: utils/adt/timestamp.c:5138 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "las unidades de timestamp with time zone «%s» no son reconocidas" + +#: utils/adt/timestamp.c:4336 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "las unidades de intervalo «%s» no están soportadas porque los meses normalmente tienen semanas fraccionales" + +#: utils/adt/timestamp.c:4342 utils/adt/timestamp.c:5261 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "las unidades de interval «%s» no están soportadas" + +#: utils/adt/timestamp.c:4358 utils/adt/timestamp.c:5322 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "las unidades de interval «%s» no son reconocidas" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: debe ser invocado como trigger" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: debe ser invocado en «UPDATE»" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: debe ser invocado «BEFORE UPDATE»" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: debe ser invocado «FOR EACH ROW»" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_in no está implementado" + +#: utils/adt/tsquery.c:199 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "distancia en operador de frases no debe ser mayor que %d" + +#: utils/adt/tsquery.c:306 utils/adt/tsquery.c:691 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "error de sintaxis en tsquery: «%s»" + +#: utils/adt/tsquery.c:330 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "no hay operando en tsquery: «%s»" + +#: utils/adt/tsquery.c:534 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "el valor es demasiado grande en tsquery: «%s»" + +#: utils/adt/tsquery.c:539 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "el operando es muy largo en tsquery: «%s»" + +#: utils/adt/tsquery.c:567 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "palabra demasiado larga en tsquery: «%s»" + +#: utils/adt/tsquery.c:835 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "la consulta de búsqueda en texto no contiene lexemas: «%s»" + +#: utils/adt/tsquery.c:846 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "el tsquery es demasiado grande" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "la consulta de búsqueda en texto contiene sólo stopwords o no contiene lexemas; ignorada" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "la distancia en el operador de frases debe ser no negativa y menor que %d" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "consulta ts_rewrite debe retornar dos columnas tsquery" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "el array de pesos debe ser unidimensional" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "el array de pesos es muy corto" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "los arrays de pesos no deben contener valores nulos" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:871 +#, c-format +msgid "weight out of range" +msgstr "peso fuera de rango" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "la palabra es demasiado larga (%ld, máximo %ld bytes)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "la cadena es demasiado larga para tsvector (%ld bytes, máximo %ld bytes)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "el array de lexemas no debe contener nulls" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "el array de pesos no debe contener nulls" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "no se reconoce el peso: «%c»" + +#: utils/adt/tsvector_op.c:2426 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "la consulta ts_stat debe retornar una columna tsvector" + +#: utils/adt/tsvector_op.c:2615 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "la columna tsvector «%s» no existe" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "la columna «%s» no es de tipo tsvector" + +#: utils/adt/tsvector_op.c:2634 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "la columna de configuración «%s» no existe" + +#: utils/adt/tsvector_op.c:2640 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "la columna «%s» no es de tipo regconfig" + +#: utils/adt/tsvector_op.c:2647 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "la columna de configuración «%s» no debe ser nula" + +#: utils/adt/tsvector_op.c:2660 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "el nombre de la configuración de búsqueda «%s» debe ser calificada con esquema" + +#: utils/adt/tsvector_op.c:2685 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "la columna «%s» no es de un tipo textual" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "error de sintaxis en tsvector: «%s»" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "no hay carácter escapado: «%s»" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "información posicional incorrecta en tsvector: «%s»" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "no se pudo generar valores aleatorios" + +#: utils/adt/varbit.c:110 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "el largo para el tipo %s debe ser al menos 1" + +#: utils/adt/varbit.c:115 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "el largo del tipo %s no puede exceder %d" + +#: utils/adt/varbit.c:198 utils/adt/varbit.c:499 utils/adt/varbit.c:994 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "el tamaño de la cadena de bits excede el máximo permitido (%d)" + +#: utils/adt/varbit.c:212 utils/adt/varbit.c:356 utils/adt/varbit.c:406 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "el largo de la cadena de bits %d no coincide con el tipo bit(%d)" + +#: utils/adt/varbit.c:234 utils/adt/varbit.c:535 +#, fuzzy, c-format +#| msgid "\"%c\" is not a valid binary digit" +msgid "\"%.*s\" is not a valid binary digit" +msgstr "«%c» no es un dígito binario válido" + +#: utils/adt/varbit.c:259 utils/adt/varbit.c:560 +#, fuzzy, c-format +#| msgid "\"%c\" is not a valid hexadecimal digit" +msgid "\"%.*s\" is not a valid hexadecimal digit" +msgstr "«%c» no es un dígito hexadecimal válido" + +#: utils/adt/varbit.c:347 utils/adt/varbit.c:652 +#, c-format +msgid "invalid length in external bit string" +msgstr "el largo no es válido en cadena de bits externa" + +#: utils/adt/varbit.c:513 utils/adt/varbit.c:661 utils/adt/varbit.c:757 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "la cadena de bits es demasiado larga para el tipo bit varying(%d)" + +#: utils/adt/varbit.c:1081 utils/adt/varbit.c:1191 utils/adt/varlena.c:897 +#: utils/adt/varlena.c:960 utils/adt/varlena.c:1117 utils/adt/varlena.c:3351 +#: utils/adt/varlena.c:3429 +#, c-format +msgid "negative substring length not allowed" +msgstr "no se permite un largo negativo de subcadena" + +#: utils/adt/varbit.c:1261 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "no se puede hacer AND entre cadenas de bits de distintos tamaños" + +#: utils/adt/varbit.c:1302 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "no se puede hacer OR entre cadenas de bits de distintos tamaños" + +#: utils/adt/varbit.c:1342 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "no se puede hacer XOR entre cadenas de bits de distintos tamaños" + +#: utils/adt/varbit.c:1824 utils/adt/varbit.c:1882 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "el índice de bit %d está fuera del rango válido (0..%d)" + +#: utils/adt/varbit.c:1833 utils/adt/varlena.c:3633 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "el nuevo bit debe ser 0 o 1" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "el valor es demasiado largo para el tipo character(%d)" + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "el valor es demasiado largo para el tipo character varying(%d)" + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1523 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "no se pudo determinar qué ordenamiento usar para la comparación de cadenas" + +#: utils/adt/varlena.c:1216 utils/adt/varlena.c:1963 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "los ordenamientos no determinísticos no están soportados para búsquedas de sub-cadenas" + +#: utils/adt/varlena.c:1622 utils/adt/varlena.c:1635 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "no se pudo convertir la cadena a UTF-16: código de error %lu" + +#: utils/adt/varlena.c:1650 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "no se pudieron comparar las cadenas Unicode: %m" + +#: utils/adt/varlena.c:1701 utils/adt/varlena.c:2415 +#, c-format +msgid "collation failed: %s" +msgstr "el ordenamiento falló: %s" + +#: utils/adt/varlena.c:2623 +#, c-format +msgid "sort key generation failed: %s" +msgstr "la generación de la llave de ordenamiento falló: %s" + +#: utils/adt/varlena.c:3517 utils/adt/varlena.c:3584 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "el índice %d está fuera de rango [0..%d]" + +#: utils/adt/varlena.c:3548 utils/adt/varlena.c:3620 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "el índice %lld está fuera de rango, 0..%lld" + +#: utils/adt/varlena.c:4656 +#, fuzzy, c-format +#| msgid "field position must be greater than zero" +msgid "field position must not be zero" +msgstr "la posición del campo debe ser mayor que cero" + +#: utils/adt/varlena.c:5697 +#, c-format +msgid "unterminated format() type specifier" +msgstr "especificador de tipo inconcluso en format()" + +#: utils/adt/varlena.c:5698 utils/adt/varlena.c:5832 utils/adt/varlena.c:5953 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "Para un «%%» solo, use «%%%%»." + +#: utils/adt/varlena.c:5830 utils/adt/varlena.c:5951 +#, fuzzy, c-format +#| msgid "unrecognized format() type specifier \"%c\"" +msgid "unrecognized format() type specifier \"%.*s\"" +msgstr "especificador de tipo no reconocido «%c» en format()" + +#: utils/adt/varlena.c:5843 utils/adt/varlena.c:5900 +#, c-format +msgid "too few arguments for format()" +msgstr "muy pocos argumentos para format()" + +#: utils/adt/varlena.c:5996 utils/adt/varlena.c:6178 +#, c-format +msgid "number is out of range" +msgstr "el número está fuera de rango" + +#: utils/adt/varlena.c:6059 utils/adt/varlena.c:6087 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "la conversión especifica el argumento 0, pero los argumentos se numeran desde 1" + +#: utils/adt/varlena.c:6080 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "la posición del argumento de anchura debe terminar con «$»" + +#: utils/adt/varlena.c:6125 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "los valores nulos no pueden ser formateados como un identificador SQL" + +#: utils/adt/varlena.c:6251 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "la normalización Unicode sólo puede ser hecha si la codificación de servidor es UTF8" + +#: utils/adt/varlena.c:6264 +#, c-format +msgid "invalid normalization form: %s" +msgstr "forma de normalización no válida: %s" + +#: utils/adt/varlena.c:6467 utils/adt/varlena.c:6502 utils/adt/varlena.c:6537 +#, fuzzy, c-format +#| msgid "invalid Unicode escape" +msgid "invalid Unicode code point: %04X" +msgstr "valor de escape Unicode no válido" + +#: utils/adt/varlena.c:6567 +#, fuzzy, c-format +#| msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgid "Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX." +msgstr "Los escapes Unicode deben ser \\uXXXX o \\UXXXXXXXX." + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "el argumento de ntile debe ser mayor que cero" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "el argumento de nth_value debe ser mayor que cero" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "el ID de transacción %s está en el futuro" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "datos externos pg_snapshot no válidos" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "característica XML no soportada" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Esta funcionalidad requiere que el servidor haya sido construido con soporte libxml." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:627 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "nombre de codificación «%s» no válido" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "comentario XML no válido" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "no es un documento XML" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "instrucción de procesamiento XML no válida" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "el nombre de destino de la instrucción de procesamiento XML no puede ser «%s»." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "la instrucción de procesamiento XML no puede contener «?>»." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "xmlvalidate no está implementado" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "no se pudo inicializar la biblioteca XML" + +#: utils/adt/xml.c:962 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2 tiene tipo char incompatible: sizeof(char)=%u, sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "no se pudo instalar un gestor de errores XML" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "Esto probablemente indica que la versión de libxml2 en uso no es compatible con los archivos de cabecera libxml2 con los que PostgreSQL fue construido." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "Valor de carácter no válido." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "Se requiere un espacio." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "standalone acepta sólo 'yes' y 'no'." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "Declaración mal formada: falta la versión." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "Falta especificación de codificación en declaración de texto." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "Procesando declaración XML: se esperaba '?>'." + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "Código de error libxml no reconocido: %d." + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML no soporta valores infinitos de fecha." + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML no soporta valores infinitos de timestamp." + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "consulta no válido" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "array no válido para mapeo de espacio de nombres XML" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "El array debe ser bidimensional y el largo del segundo eje igual a 2." + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "expresion XPath vacía" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "ni el espacio de nombres ni la URI pueden ser vacíos" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "no se pudo registrar un espacio de nombres XML llamado «%s» con URI «%s»" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "el espacio de nombres DEFAULT no está soportado" + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "el «path» de filtro de registros no debe ser la cadena vacía" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "el «path» de filtro de columna no debe ser la cadena vacía" + +#: utils/adt/xml.c:4655 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "la expresión XPath de columna retornó más de un valor" + +#: utils/cache/lsyscache.c:1042 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "no existe la conversión del tipo %s al tipo %s" + +#: utils/cache/lsyscache.c:2834 utils/cache/lsyscache.c:2867 +#: utils/cache/lsyscache.c:2900 utils/cache/lsyscache.c:2933 +#, c-format +msgid "type %s is only a shell" +msgstr "el tipo %s está inconcluso" + +#: utils/cache/lsyscache.c:2839 +#, c-format +msgid "no input function available for type %s" +msgstr "no hay una función de entrada para el tipo %s" + +#: utils/cache/lsyscache.c:2872 +#, c-format +msgid "no output function available for type %s" +msgstr "no hay una función de salida para el tipo %s" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "falta la función de soporte %3$d para el tipo %4$s de la clase de operadores «%1$s» del método de acceso %2$s" + +#: utils/cache/plancache.c:720 +#, c-format +msgid "cached plan must not change result type" +msgstr "el plan almacenado no debe cambiar el tipo de resultado" + +#: utils/cache/relcache.c:6213 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "no se pudo crear el archivo de cache de catálogos de sistema «%s»: %m" + +#: utils/cache/relcache.c:6215 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Prosiguiendo de todas maneras, pero hay algo mal." + +#: utils/cache/relcache.c:6537 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "no se pudo eliminar el archivo de cache «%s»: %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "no se puede hacer PREPARE de una transacción que ha modificado el mapeo de relaciones" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "el archivo de mapeo de relaciones «%s» contiene datos no válidos" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "el archivo de mapeo de relaciones «%s» tiene una suma de verificación incorrecta" + +#: utils/cache/typcache.c:1808 utils/fmgr/funcapi.c:463 +#, c-format +msgid "record type has not been registered" +msgstr "el tipo record no ha sido registrado" + +#: utils/error/assert.c:39 +#, fuzzy, c-format +#| msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgid "TRAP: ExceptionalCondition: bad arguments in PID %d\n" +msgstr "TRAP: ExceptionalConditions: argumentos erróneos\n" + +#: utils/error/assert.c:42 +#, fuzzy, c-format +#| msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d, PID: %d)\n" +msgstr "TRAP: %s(«%s», Archivo: «%s», Línea: %d)\n" + +#: utils/error/elog.c:409 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "ocurrió un error antes de que el procesamiento de errores esté disponible\n" + +#: utils/error/elog.c:1948 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "no se pudo reabrir «%s» para error estándar: %m" + +#: utils/error/elog.c:1961 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "no se pudo reabrir «%s» para usar como salida estándar: %m" + +#: utils/error/elog.c:2456 utils/error/elog.c:2490 utils/error/elog.c:2506 +msgid "[unknown]" +msgstr "[desconocido]" + +#: utils/error/elog.c:3026 utils/error/elog.c:3344 utils/error/elog.c:3451 +msgid "missing error text" +msgstr "falta un texto de mensaje de error" + +#: utils/error/elog.c:3029 utils/error/elog.c:3032 +#, c-format +msgid " at character %d" +msgstr " en carácter %d" + +#: utils/error/elog.c:3042 utils/error/elog.c:3049 +msgid "DETAIL: " +msgstr "DETALLE: " + +#: utils/error/elog.c:3056 +msgid "HINT: " +msgstr "HINT: " + +#: utils/error/elog.c:3063 +msgid "QUERY: " +msgstr "CONSULTA: " + +#: utils/error/elog.c:3070 +msgid "CONTEXT: " +msgstr "CONTEXTO: " + +#: utils/error/elog.c:3080 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "UBICACIÓN: %s, %s:%d\n" + +#: utils/error/elog.c:3087 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "UBICACIÓN: %s:%d\n" + +#: utils/error/elog.c:3094 +msgid "BACKTRACE: " +msgstr "BACKTRACE: " + +#: utils/error/elog.c:3108 +msgid "STATEMENT: " +msgstr "SENTENCIA: " + +#: utils/error/elog.c:3496 +msgid "DEBUG" +msgstr "DEBUG" + +#: utils/error/elog.c:3500 +msgid "LOG" +msgstr "LOG" + +#: utils/error/elog.c:3503 +msgid "INFO" +msgstr "INFO" + +#: utils/error/elog.c:3506 +msgid "NOTICE" +msgstr "NOTICE" + +#: utils/error/elog.c:3510 +msgid "WARNING" +msgstr "WARNING" + +#: utils/error/elog.c:3513 +msgid "ERROR" +msgstr "ERROR" + +#: utils/error/elog.c:3516 +msgid "FATAL" +msgstr "FATAL" + +#: utils/error/elog.c:3519 +msgid "PANIC" +msgstr "PANIC" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "no se pudo encontrar la función «%s» en el archivo «%s»" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "no se pudo cargar la biblioteca «%s»: %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "biblioteca «%s» incompatible: no se encuentra el bloque mágico" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "Se requiere que las bibliotecas de extensión usen la macro PG_MODULE_MAGIC." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "biblioteca «%s» incompatible: versión no coincide" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "Versión del servidor %d, versión de biblioteca %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "El servidor tiene FUNC_MAX_ARGS = %d, la librería tiene %d" + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "El servidor tiene INDEX_MAX_KEYS = %d, la librería tiene %d" + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "El servidor tiene NAMEDATALEN = %d, la librería tiene %d" + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "El servidor tiene FLOAT8PASSBYVAL = %s, la librería tiene %s" + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "El bloque mágico tiene un largo inesperado, o una diferencia de relleno." + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "biblioteca «%s» incompatible: bloque mágico no coincide" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "no está permitido el acceso a la biblioteca «%s»" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "el nombre de macro no es válido en la ruta a biblioteca dinámica: %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "se encontró componente de largo cero en el parámetro «dynamic_library_path»" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "un componente en el parámetro «dynamic_library_path» no es una ruta absoluta" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "la función interna «%s» no está en la tabla interna de búsqueda" + +#: utils/fmgr/fmgr.c:484 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "no se pudo encontrar información de función para la función «%s»" + +#: utils/fmgr/fmgr.c:486 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "Funciones invocables desde SQL necesitan PG_FUNCTION_INFO_V1(función) que los acompañe." + +#: utils/fmgr/fmgr.c:504 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "la versión de API %d no reconocida fue reportada por la función «%s»" + +#: utils/fmgr/fmgr.c:1999 +#, fuzzy, c-format +#| msgid "operator class options info is absent in function call context" +msgid "operator class options info is absent in function call context" +msgstr "la información de opciones de la clase de operadores está ausente en el contexto de llamada a función" + +#: utils/fmgr/fmgr.c:2066 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "función de validación de lenguaje %u invocada para el lenguaje %u en lugar de %u" + +#: utils/fmgr/funcapi.c:386 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "no se pudo determinar el tipo verdadero de resultado para la función «%s» declarada retornando tipo %s" + +#: utils/fmgr/funcapi.c:531 +#, fuzzy, c-format +#| msgid "argument declared %s is not a range type but type %s" +msgid "argument declared %s does not contain a range type but type %s" +msgstr "el argumento declarado %s no es un tipo de rango sino tipo %s" + +#: utils/fmgr/funcapi.c:1831 utils/fmgr/funcapi.c:1863 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "el número de aliases no coincide con el número de columnas" + +#: utils/fmgr/funcapi.c:1857 +#, c-format +msgid "no column alias was provided" +msgstr "no se entregó alias de columna" + +#: utils/fmgr/funcapi.c:1881 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "no se pudo encontrar descripción de registro de función que retorna record" + +#: utils/init/miscinit.c:315 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "no existe el directorio de datos «%s»" + +#: utils/init/miscinit.c:320 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "no se pudo obtener los permisos del directorio «%s»: %m" + +#: utils/init/miscinit.c:328 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "el directorio de datos especificado «%s» no es un directorio" + +#: utils/init/miscinit.c:344 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "el directorio de datos «%s» tiene dueño equivocado" + +#: utils/init/miscinit.c:346 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "El servidor debe ser iniciado por el usuario dueño del directorio de datos." + +#: utils/init/miscinit.c:364 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "el directorio de datos «%s» tiene permisos no válidos" + +#: utils/init/miscinit.c:366 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Los permisos deberían ser u=rwx (0700) o u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:645 utils/misc/guc.c:7481 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "no se puede definir el parámetro «%s» dentro de una operación restringida por seguridad" + +#: utils/init/miscinit.c:713 +#, c-format +msgid "role with OID %u does not exist" +msgstr "no existe el rol con OID %u" + +#: utils/init/miscinit.c:743 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "al rol «%s» no se le permite conectarse" + +#: utils/init/miscinit.c:761 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "demasiadas conexiones para el rol «%s»" + +#: utils/init/miscinit.c:821 +#, c-format +msgid "permission denied to set session authorization" +msgstr "se ha denegado el permiso para cambiar el usuario actual" + +#: utils/init/miscinit.c:904 +#, c-format +msgid "invalid role OID: %u" +msgstr "el OID de rol no es válido: %u" + +#: utils/init/miscinit.c:958 +#, c-format +msgid "database system is shut down" +msgstr "el sistema de bases de datos está apagado" + +#: utils/init/miscinit.c:1045 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "no se pudo crear el archivo de bloqueo «%s»: %m" + +#: utils/init/miscinit.c:1059 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "no se pudo abrir el archivo de bloqueo «%s»: %m" + +#: utils/init/miscinit.c:1066 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "no se pudo leer el archivo de bloqueo «%s»: %m" + +#: utils/init/miscinit.c:1075 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "el archivo de bloqueo «%s» está vacío" + +#: utils/init/miscinit.c:1076 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "Otro proceso servidor está iniciándose, o el archivo de bloqueo es remanente de una caída durante un inicio anterior." + +#: utils/init/miscinit.c:1120 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "el archivo de bloqueo «%s» ya existe" + +#: utils/init/miscinit.c:1124 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "¿Hay otro postgres (PID %d) corriendo en el directorio de datos «%s»?" + +#: utils/init/miscinit.c:1126 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "¿Hay otro postmaster (PID %d) corriendo en el directorio de datos «%s»?" + +#: utils/init/miscinit.c:1129 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "¿Hay otro postgres (PID %d) usando el socket «%s»?" + +#: utils/init/miscinit.c:1131 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "¿Hay otro postmaster (PID %d) usando el socket «%s»?" + +#: utils/init/miscinit.c:1182 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "no se pudo eliminar el archivo de bloqueo antiguo «%s»: %m" + +#: utils/init/miscinit.c:1184 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "El archivo parece accidentalmente abandonado, pero no pudo ser eliminado. Por favor elimine el archivo manualmente e intente nuevamente." + +#: utils/init/miscinit.c:1221 utils/init/miscinit.c:1235 +#: utils/init/miscinit.c:1246 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "no se pudo escribir el archivo de bloqueo «%s»: %m" + +#: utils/init/miscinit.c:1357 utils/init/miscinit.c:1499 utils/misc/guc.c:10377 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: utils/init/miscinit.c:1487 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "no se pudo abrir el archivo «%s»: %m; continuando de todas formas" + +#: utils/init/miscinit.c:1512 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "el archivo de bloqueo «%s» tiene un PID erróneo: %ld en lugar de %ld" + +#: utils/init/miscinit.c:1551 utils/init/miscinit.c:1567 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "«%s» no es un directorio de datos válido" + +#: utils/init/miscinit.c:1553 +#, c-format +msgid "File \"%s\" is missing." +msgstr "Falta el archivo «%s»." + +#: utils/init/miscinit.c:1569 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "El archivo «%s» no contiene datos válidos." + +#: utils/init/miscinit.c:1571 +#, c-format +msgid "You might need to initdb." +msgstr "Puede ser necesario ejecutar initdb." + +#: utils/init/miscinit.c:1579 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "El directorio de datos fue inicializado por PostgreSQL versión %s, que no es compatible con esta versión %s." + +#: utils/init/postinit.c:254 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "conexión de replicación autorizada: usuario=%s" + +#: utils/init/postinit.c:257 +#, fuzzy, c-format +#| msgid "replication connection authorized: user=%s" +msgid "connection authorized: user=%s" +msgstr "conexión de replicación autorizada: usuario=%s" + +#: utils/init/postinit.c:260 +#, fuzzy, c-format +#| msgid "database %s" +msgid " database=%s" +msgstr "base de datos %s" + +#: utils/init/postinit.c:263 +#, fuzzy, c-format +#| msgid "publication_name" +msgid " application_name=%s" +msgstr "nombre_de_publicación" + +#: utils/init/postinit.c:268 +#, fuzzy, c-format +#| msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgid " SSL enabled (protocol=%s, cipher=%s, bits=%d)" +msgstr "Conexión SSL (protocolo: %s, cifrado: %s, bits: %s, compresión: %s)\n" + +#: utils/init/postinit.c:280 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s, principal=%s)" +msgstr "" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 +#: utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "no" +msgstr "no" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 +#: utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "yes" +msgstr "sí" + +#: utils/init/postinit.c:286 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s)" +msgstr "" + +#: utils/init/postinit.c:323 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "la base de datos «%s» ha desaparecido de pg_database" + +#: utils/init/postinit.c:325 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "Base de datos con OID %u ahora parece pertenecer a «%s»." + +#: utils/init/postinit.c:345 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "la base de datos «%s» no acepta conexiones" + +#: utils/init/postinit.c:358 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "permiso denegado a la base de datos «%s»" + +#: utils/init/postinit.c:359 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "Usuario no tiene privilegios de conexión." + +#: utils/init/postinit.c:376 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "demasiadas conexiones para la base de datos «%s»" + +#: utils/init/postinit.c:398 utils/init/postinit.c:405 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "la configuración regional es incompatible con el sistema operativo" + +#: utils/init/postinit.c:399 +#, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "La base de datos fue inicializada con LC_COLLATE «%s», el cual no es reconocido por setlocale()." + +#: utils/init/postinit.c:401 utils/init/postinit.c:408 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "Recree la base de datos con otra configuración regional, o instale la configuración regional faltante." + +#: utils/init/postinit.c:406 +#, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "La base de datos fueron inicializada con LC_CTYPE «%s», el cual no es reconocido por setlocale()." + +#: utils/init/postinit.c:761 +#, c-format +msgid "no roles are defined in this database system" +msgstr "no hay roles definidos en esta base de datos" + +#: utils/init/postinit.c:762 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Debería ejecutar imediatamente CREATE USER \"%s\" SUPERUSER;." + +#: utils/init/postinit.c:798 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "nuevas conexiones de replicación no son permitidas durante el apagado de la base de datos" + +#: utils/init/postinit.c:802 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "debe ser superusuario para conectarse durante el apagado de la base de datos" + +#: utils/init/postinit.c:812 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "debe ser superusuario para conectarse en modo de actualización binaria" + +#: utils/init/postinit.c:825 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "las conexiones restantes están reservadas a superusuarios y no de replicación" + +#: utils/init/postinit.c:835 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "debe ser superusuario o rol de replicación para iniciar el walsender" + +#: utils/init/postinit.c:904 +#, c-format +msgid "database %u does not exist" +msgstr "no existe la base de datos %u" + +#: utils/init/postinit.c:993 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Parece haber sido eliminada o renombrada." + +#: utils/init/postinit.c:1011 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Falta el subdirectorio de base de datos «%s»." + +#: utils/init/postinit.c:1016 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "no se pudo acceder al directorio «%s»: %m" + +#: utils/mb/conv.c:522 utils/mb/conv.c:733 +#, c-format +msgid "invalid encoding number: %d" +msgstr "el número de codificación no es válido: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:129 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:165 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "ID de codificación %d inesperado para juegos de caracteres ISO 8859" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:110 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:146 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "ID de codificación %d inesperado para juegos de caracteres WIN" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:900 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "la conversión entre %s y %s no está soportada" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "no existe el procedimiento por omisión de conversión desde la codificación «%s» a «%s»" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:430 utils/mb/mbutils.c:815 +#: utils/mb/mbutils.c:842 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "La cadena de %d bytes es demasiado larga para la recodificación." + +#: utils/mb/mbutils.c:568 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "la codificación de origen «%s» no es válida" + +#: utils/mb/mbutils.c:573 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "la codificación de destino «%s» no es válida" + +#: utils/mb/mbutils.c:713 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "byte no válido para codificación «%s»: 0x%02x" + +#: utils/mb/mbutils.c:877 +#, fuzzy, c-format +#| msgid "invalid Unicode escape" +msgid "invalid Unicode code point" +msgstr "valor de escape Unicode no válido" + +#: utils/mb/mbutils.c:1146 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codeset falló" + +#: utils/mb/mbutils.c:1667 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "secuencia de bytes no válida para codificación «%s»: %s" + +#: utils/mb/mbutils.c:1700 +#, c-format +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "carácter con secuencia de bytes %s en codificación «%s» no tiene equivalente en la codificación «%s»" + +#: utils/misc/guc.c:718 +msgid "Ungrouped" +msgstr "Sin Grupo" + +#: utils/misc/guc.c:720 +msgid "File Locations" +msgstr "Ubicaciones de Archivos" + +#: utils/misc/guc.c:722 +msgid "Connections and Authentication / Connection Settings" +msgstr "Conexiones y Autentificación / Parámetros de Conexión" + +#: utils/misc/guc.c:724 +msgid "Connections and Authentication / Authentication" +msgstr "Conexiones y Autentificación / Autentificación" + +#: utils/misc/guc.c:726 +msgid "Connections and Authentication / SSL" +msgstr "Conexiones y Autentificación / SSL" + +#: utils/misc/guc.c:728 +msgid "Resource Usage / Memory" +msgstr "Uso de Recursos / Memoria" + +#: utils/misc/guc.c:730 +msgid "Resource Usage / Disk" +msgstr "Uso de Recursos / Disco" + +#: utils/misc/guc.c:732 +msgid "Resource Usage / Kernel Resources" +msgstr "Uso de Recursos / Recursos del Kernel" + +#: utils/misc/guc.c:734 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Uso de Recursos / Retardo de Vacuum por Costos" + +#: utils/misc/guc.c:736 +msgid "Resource Usage / Background Writer" +msgstr "Uso de Recursos / Escritor en Segundo Plano" + +#: utils/misc/guc.c:738 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Uso de Recursos / Comportamiento Asíncrono" + +#: utils/misc/guc.c:740 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead Log / Configuraciones" + +#: utils/misc/guc.c:742 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead Log / Puntos de Control (Checkpoints)" + +#: utils/misc/guc.c:744 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead Log / Archivado" + +#: utils/misc/guc.c:746 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead Log / Recuperación desde Archivo" + +#: utils/misc/guc.c:748 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead Log / Destino de Recuperación" + +#: utils/misc/guc.c:750 +msgid "Replication / Sending Servers" +msgstr "Replicación / Servidores de Envío" + +#: utils/misc/guc.c:752 +#, fuzzy +#| msgid "Replication / Master Server" +msgid "Replication / Primary Server" +msgstr "Replicación / Servidor Maestro" + +#: utils/misc/guc.c:754 +msgid "Replication / Standby Servers" +msgstr "Replicación / Servidores Standby" + +#: utils/misc/guc.c:756 +msgid "Replication / Subscribers" +msgstr "Replicación / Suscriptores" + +#: utils/misc/guc.c:758 +msgid "Query Tuning / Planner Method Configuration" +msgstr "Afinamiento de Consultas / Configuración de Métodos del Planner" + +#: utils/misc/guc.c:760 +msgid "Query Tuning / Planner Cost Constants" +msgstr "Afinamiento de Consultas / Constantes de Costo del Planner" + +#: utils/misc/guc.c:762 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "Afinamiento de Consultas / Optimizador Genético de Consultas" + +#: utils/misc/guc.c:764 +msgid "Query Tuning / Other Planner Options" +msgstr "Afinamiento de Consultas / Otras Opciones del Planner" + +#: utils/misc/guc.c:766 +msgid "Reporting and Logging / Where to Log" +msgstr "Reporte y Registro / Cuándo Registrar" + +#: utils/misc/guc.c:768 +msgid "Reporting and Logging / When to Log" +msgstr "Reporte y Registro / Cuándo Registrar" + +#: utils/misc/guc.c:770 +msgid "Reporting and Logging / What to Log" +msgstr "Reporte y Registro / Qué Registrar" + +#: utils/misc/guc.c:772 +#, fuzzy +#| msgid "Reporting and Logging / Where to Log" +msgid "Reporting and Logging / Process Title" +msgstr "Reporte y Registro / Cuándo Registrar" + +#: utils/misc/guc.c:774 +msgid "Statistics / Monitoring" +msgstr "Estadísticas / Monitoreo" + +#: utils/misc/guc.c:776 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "Estadísticas / Recolector de Estadísticas de Consultas e Índices" + +#: utils/misc/guc.c:778 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:780 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "Valores por Omisión de Conexiones / Comportamiento de Sentencias" + +#: utils/misc/guc.c:782 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "Valores por Omisión de Conexiones / Configuraciones Regionales y Formateo" + +#: utils/misc/guc.c:784 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "Valores por Omisión de Conexiones / Precargado de Bibliotecas Compartidas" + +#: utils/misc/guc.c:786 +msgid "Client Connection Defaults / Other Defaults" +msgstr "Valores por Omisión de Conexiones / Otros Valores" + +#: utils/misc/guc.c:788 +msgid "Lock Management" +msgstr "Manejo de Bloqueos" + +#: utils/misc/guc.c:790 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Compatibilidad de Versión y Plataforma / Versiones Anteriores de PostgreSQL" + +#: utils/misc/guc.c:792 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Compatibilidad de Versión y Plataforma / Otras Plataformas y Clientes" + +#: utils/misc/guc.c:794 +msgid "Error Handling" +msgstr "Gestión de Errores" + +#: utils/misc/guc.c:796 +msgid "Preset Options" +msgstr "Opciones Predefinidas" + +#: utils/misc/guc.c:798 +msgid "Customized Options" +msgstr "Opciones Personalizadas" + +#: utils/misc/guc.c:800 +msgid "Developer Options" +msgstr "Opciones de Desarrollador" + +#: utils/misc/guc.c:858 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Unidades válidas para este parámetro son «B», «kB», «MB», «GB» y «TB»." + +#: utils/misc/guc.c:895 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Unidades válidas son para este parámetro son «us», «ms», «s», «min», «h» y «d»." + +#: utils/misc/guc.c:957 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "Permitir el uso de planes de recorrido secuencial." + +#: utils/misc/guc.c:967 +msgid "Enables the planner's use of index-scan plans." +msgstr "Permitir el uso de planes de recorrido de índice." + +#: utils/misc/guc.c:977 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Permitir el uso de planes de recorrido de sólo-índice." + +#: utils/misc/guc.c:987 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "Permitir el uso de planes de recorrido de índice por mapas de bits." + +#: utils/misc/guc.c:997 +msgid "Enables the planner's use of TID scan plans." +msgstr "Permitir el uso de planes de recorrido por TID." + +#: utils/misc/guc.c:1007 +msgid "Enables the planner's use of explicit sort steps." +msgstr "Permitir el uso de pasos explícitos de ordenamiento." + +#: utils/misc/guc.c:1017 +#, fuzzy +#| msgid "Enables the planner's use of explicit sort steps." +msgid "Enables the planner's use of incremental sort steps." +msgstr "Permitir el uso de pasos explícitos de ordenamiento." + +#: utils/misc/guc.c:1026 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Permitir el uso de planes de agregación a través de hash." + +#: utils/misc/guc.c:1036 +msgid "Enables the planner's use of materialization." +msgstr "Permitir el uso de materialización de planes." + +#: utils/misc/guc.c:1046 +#, fuzzy +#| msgid "Enables the planner's use of parallel hash plans." +msgid "Enables the planner's use of result caching." +msgstr "Permitir el uso de planes «hash join» paralelos." + +#: utils/misc/guc.c:1056 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "Permitir el uso de planes «nested-loop join»." + +#: utils/misc/guc.c:1066 +msgid "Enables the planner's use of merge join plans." +msgstr "Permitir el uso de planes «merge join»." + +#: utils/misc/guc.c:1076 +msgid "Enables the planner's use of hash join plans." +msgstr "Permitir el uso de planes «hash join»." + +#: utils/misc/guc.c:1086 +msgid "Enables the planner's use of gather merge plans." +msgstr "Permitir el uso de planes «gather merge»." + +#: utils/misc/guc.c:1096 +msgid "Enables partitionwise join." +msgstr "Permitir el uso de joins por particiones." + +#: utils/misc/guc.c:1106 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Permitir el uso de agregación y agrupamiento por particiones." + +#: utils/misc/guc.c:1116 +msgid "Enables the planner's use of parallel append plans." +msgstr "Permitir el uso de planes «append» paralelos." + +#: utils/misc/guc.c:1126 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Permitir el uso de planes «hash join» paralelos." + +#: utils/misc/guc.c:1136 +#, fuzzy +#| msgid "Enables plan-time and run-time partition pruning." +msgid "Enables plan-time and execution-time partition pruning." +msgstr "Permitir el uso de poda de particiones en tiempo de plan y ejecución." + +#: utils/misc/guc.c:1137 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Permite al optimizador de consultas y al ejecutor a comparar bordes de particiones a condiciones en las consultas para determinar qué particiones deben recorrerse." + +#: utils/misc/guc.c:1148 +#, fuzzy +#| msgid "Enables the planner's use of parallel append plans." +msgid "Enables the planner's use of async append plans." +msgstr "Permitir el uso de planes «append» paralelos." + +#: utils/misc/guc.c:1158 +msgid "Enables genetic query optimization." +msgstr "Permitir el uso del optimizador genético de consultas." + +#: utils/misc/guc.c:1159 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Este algoritmo intenta planear las consultas sin hacer búsqueda exhaustiva." + +#: utils/misc/guc.c:1170 +msgid "Shows whether the current user is a superuser." +msgstr "Indica si el usuario actual es superusuario." + +#: utils/misc/guc.c:1180 +msgid "Enables advertising the server via Bonjour." +msgstr "Permitir la publicación del servidor vía Bonjour." + +#: utils/misc/guc.c:1189 +msgid "Collects transaction commit time." +msgstr "Recolectar tiempo de compromiso de transacciones." + +#: utils/misc/guc.c:1198 +msgid "Enables SSL connections." +msgstr "Permitir conexiones SSL." + +#: utils/misc/guc.c:1207 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "También usar ssl_passphrase_command durante la recarga del servidor." + +#: utils/misc/guc.c:1216 +msgid "Give priority to server ciphersuite order." +msgstr "Da prioridad al orden de algoritmos de cifrado especificado por el servidor." + +#: utils/misc/guc.c:1225 +msgid "Forces synchronization of updates to disk." +msgstr "Forzar la sincronización de escrituras a disco." + +#: utils/misc/guc.c:1226 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "El servidor usará la llamada a sistema fsync() en varios lugares para asegurarse que las actualizaciones son escritas físicamente a disco. Esto asegura que las bases de datos se recuperarán a un estado consistente después de una caída de hardware o sistema operativo." + +#: utils/misc/guc.c:1237 +msgid "Continues processing after a checksum failure." +msgstr "Continuar procesando después de una falla de suma de verificación." + +#: utils/misc/guc.c:1238 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "La detección de una suma de verificación que no coincide normalmente hace que PostgreSQL reporte un error, abortando la transacción en curso. Definiendo ignore_checksum_failure a true hace que el sistema ignore la falla (pero aún así reporta un mensaje de warning), y continúe el procesamiento. Este comportamiento podría causar caídas del sistema u otros problemas serios. Sólo tiene efecto si las sumas de verificación están activadas." + +#: utils/misc/guc.c:1252 +msgid "Continues processing past damaged page headers." +msgstr "Continuar procesando después de detectar encabezados de página dañados." + +#: utils/misc/guc.c:1253 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "La detección de un encabezado de página dañado normalmente hace que PostgreSQL reporte un error, abortando la transacción en curso. Definiendo zero_damaged_pages a true hace que el sistema reporte un mensaje de warning, escriba ceros en toda la página, y continúe el procesamiento. Este comportamiento destruirá datos; en particular, todas las tuplas en la página dañada." + +#: utils/misc/guc.c:1266 +#, fuzzy +#| msgid "Continues processing after a checksum failure." +msgid "Continues recovery after an invalid pages failure." +msgstr "Continuar procesando después de una falla de suma de verificación." + +#: utils/misc/guc.c:1267 +#, fuzzy +#| msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgid "Detection of WAL records having references to invalid pages during recovery causes PostgreSQL to raise a PANIC-level error, aborting the recovery. Setting ignore_invalid_pages to true causes the system to ignore invalid page references in WAL records (but still report a warning), and continue recovery. This behavior may cause crashes, data loss, propagate or hide corruption, or other serious problems. Only has an effect during recovery or in standby mode." +msgstr "La detección de una suma de verificación que no coincide normalmente hace que PostgreSQL reporte un error, abortando la transacción en curso. Definiendo ignore_checksum_failure a true hace que el sistema ignore la falla (pero aún así reporta un mensaje de warning), y continúe el procesamiento. Este comportamiento podría causar caídas del sistema u otros problemas serios. Sólo tiene efecto si las sumas de verificación están activadas." + +#: utils/misc/guc.c:1285 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "Escribe páginas completas a WAL cuando son modificadas después de un punto de control." + +#: utils/misc/guc.c:1286 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "Una escritura de página que está siendo procesada durante una caída del sistema operativo puede ser completada sólo parcialmente. Durante la recuperación, los cambios de registros (tuplas) almacenados en WAL no son suficientes para la recuperación. Esta opción activa la escritura de las páginas a WAL cuando son modificadas por primera vez después de un punto de control, de manera que una recuperación total es posible." + +#: utils/misc/guc.c:1299 +#, fuzzy +#| msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification." +msgstr "Escribir páginas completas a WAL cuando son modificadas después de un punto de control, incluso para modificaciones no críticas." + +#: utils/misc/guc.c:1309 +msgid "Compresses full-page writes written in WAL file." +msgstr "Comprimir las imágenes de páginas completas al escribirlas a WAL." + +#: utils/misc/guc.c:1319 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Escribir ceros a nuevos archivos WAL antes del primer uso." + +#: utils/misc/guc.c:1329 +msgid "Recycles WAL files by renaming them." +msgstr "Reciclar archivos de WAL cambiándoles de nombre." + +#: utils/misc/guc.c:1339 +msgid "Logs each checkpoint." +msgstr "Registrar cada punto de control." + +#: utils/misc/guc.c:1348 +msgid "Logs each successful connection." +msgstr "Registrar cada conexión exitosa." + +#: utils/misc/guc.c:1357 +msgid "Logs end of a session, including duration." +msgstr "Registrar el fin de una sesión, incluyendo su duración." + +#: utils/misc/guc.c:1366 +msgid "Logs each replication command." +msgstr "Registrar cada orden de replicación." + +#: utils/misc/guc.c:1375 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Indica si el servidor actual tiene activas las aseveraciones (asserts) activas." + +#: utils/misc/guc.c:1390 +msgid "Terminate session on any error." +msgstr "Terminar sesión ante cualquier error." + +#: utils/misc/guc.c:1399 +msgid "Reinitialize server after backend crash." +msgstr "Reinicializar el servidor después de una caída de un proceso servidor." + +#: utils/misc/guc.c:1408 +#, fuzzy +#| msgid "Reinitialize server after backend crash." +msgid "Remove temporary files after backend crash." +msgstr "Reinicializar el servidor después de una caída de un proceso servidor." + +#: utils/misc/guc.c:1418 +msgid "Logs the duration of each completed SQL statement." +msgstr "Registrar la duración de cada sentencia SQL ejecutada." + +#: utils/misc/guc.c:1427 +msgid "Logs each query's parse tree." +msgstr "Registrar cada arbol analizado de consulta " + +#: utils/misc/guc.c:1436 +msgid "Logs each query's rewritten parse tree." +msgstr "Registrar cada reescritura del arból analizado de consulta" + +#: utils/misc/guc.c:1445 +msgid "Logs each query's execution plan." +msgstr "Registrar el plan de ejecución de cada consulta." + +#: utils/misc/guc.c:1454 +msgid "Indents parse and plan tree displays." +msgstr "Indentar los árboles de parse y plan." + +#: utils/misc/guc.c:1463 +msgid "Writes parser performance statistics to the server log." +msgstr "Escribir estadísticas de parser al registro del servidor." + +#: utils/misc/guc.c:1472 +msgid "Writes planner performance statistics to the server log." +msgstr "Escribir estadísticas de planner al registro del servidor." + +#: utils/misc/guc.c:1481 +msgid "Writes executor performance statistics to the server log." +msgstr "Escribir estadísticas del executor al registro del servidor." + +#: utils/misc/guc.c:1490 +msgid "Writes cumulative performance statistics to the server log." +msgstr "Escribir estadísticas acumulativas al registro del servidor." + +#: utils/misc/guc.c:1500 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "Registrar uso de recursos de sistema (memoria y CPU) en varias operaciones B-tree." + +#: utils/misc/guc.c:1512 +msgid "Collects information about executing commands." +msgstr "Recolectar estadísticas sobre órdenes en ejecución." + +#: utils/misc/guc.c:1513 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "Activa la recolección de información sobre la orden actualmente en ejecución en cada sesión, junto con el momento en el cual esa orden comenzó la ejecución." + +#: utils/misc/guc.c:1523 +msgid "Collects statistics on database activity." +msgstr "Recolectar estadísticas de actividad de la base de datos." + +#: utils/misc/guc.c:1532 +msgid "Collects timing statistics for database I/O activity." +msgstr "Recolectar estadísticas de tiempos en las operaciones de I/O de la base de datos." + +#: utils/misc/guc.c:1541 +#, fuzzy +#| msgid "Collects timing statistics for database I/O activity." +msgid "Collects timing statistics for WAL I/O activity." +msgstr "Recolectar estadísticas de tiempos en las operaciones de I/O de la base de datos." + +#: utils/misc/guc.c:1551 +msgid "Updates the process title to show the active SQL command." +msgstr "Actualiza el título del proceso para mostrar la orden SQL activo." + +#: utils/misc/guc.c:1552 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "Habilita que se actualice el título del proceso cada vez que una orden SQL es recibido por el servidor." + +#: utils/misc/guc.c:1565 +msgid "Starts the autovacuum subprocess." +msgstr "Iniciar el subproceso de autovacuum." + +#: utils/misc/guc.c:1575 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "Generar salida de depuración para LISTEN y NOTIFY." + +#: utils/misc/guc.c:1587 +msgid "Emits information about lock usage." +msgstr "Emitir información acerca del uso de locks." + +#: utils/misc/guc.c:1597 +msgid "Emits information about user lock usage." +msgstr "Emitir información acerca del uso de locks de usuario." + +#: utils/misc/guc.c:1607 +msgid "Emits information about lightweight lock usage." +msgstr "Emitir información acerca del uso de «lightweight locks»." + +#: utils/misc/guc.c:1617 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "Volcar información acerca de los locks existentes cuando se agota el tiempo de deadlock." + +#: utils/misc/guc.c:1629 +msgid "Logs long lock waits." +msgstr "Registrar esperas largas de bloqueos." + +#: utils/misc/guc.c:1638 +#, fuzzy +#| msgid "abort reason: recovery conflict" +msgid "Logs standby recovery conflict waits." +msgstr "razón para abortar: conflicto en la recuperación" + +#: utils/misc/guc.c:1647 +msgid "Logs the host name in the connection logs." +msgstr "Registrar el nombre del host en la conexión." + +#: utils/misc/guc.c:1648 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "Por omisión, los registros de conexión sólo muestran la dirección IP del host que establece la conexión. Si desea que se despliegue el nombre del host puede activar esta opción, pero dependiendo de su configuración de resolución de nombres esto puede imponer una penalización de rendimiento no despreciable." + +#: utils/misc/guc.c:1659 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "Tratar expr=NULL como expr IS NULL." + +#: utils/misc/guc.c:1660 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "Cuando está activado, expresiones de la forma expr = NULL (o NULL = expr) son tratadas como expr IS NULL, esto es, retornarán verdadero si expr es evaluada al valor nulo, y falso en caso contrario. El comportamiento correcto de expr = NULL es retornar siempre null (desconocido)." + +#: utils/misc/guc.c:1672 +msgid "Enables per-database user names." +msgstr "Activar el uso de nombre de usuario locales a cada base de datos." + +#: utils/misc/guc.c:1681 +msgid "Sets the default read-only status of new transactions." +msgstr "Estado por omisión de sólo lectura de nuevas transacciones." + +#: utils/misc/guc.c:1691 +msgid "Sets the current transaction's read-only status." +msgstr "Activa el estado de sólo lectura de la transacción en curso." + +#: utils/misc/guc.c:1701 +msgid "Sets the default deferrable status of new transactions." +msgstr "Estado por omisión de postergable de nuevas transacciones." + +#: utils/misc/guc.c:1710 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "Si está activo, las transacciones serializables de sólo lectura serán pausadas hasta que puedan ejecutarse sin posibles fallas de serialización." + +#: utils/misc/guc.c:1720 +msgid "Enable row security." +msgstr "Activar seguridad de registros." + +#: utils/misc/guc.c:1721 +msgid "When enabled, row security will be applied to all users." +msgstr "Cuando está activada, la seguridad de registros se aplicará a todos los usuarios." + +#: utils/misc/guc.c:1729 +#, fuzzy +#| msgid "Check function bodies during CREATE FUNCTION." +msgid "Check routine bodies during CREATE FUNCTION and CREATE PROCEDURE." +msgstr "Verificar definición de funciones durante CREATE FUNCTION." + +#: utils/misc/guc.c:1738 +msgid "Enable input of NULL elements in arrays." +msgstr "Habilita el ingreso de elementos nulos en arrays." + +#: utils/misc/guc.c:1739 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "Cuando está activo, un valor NULL sin comillas en la entrada de un array significa un valor nulo; en caso contrario es tomado literalmente." + +#: utils/misc/guc.c:1755 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OIDS ya no está soportado; esto sólo puede ser false." + +#: utils/misc/guc.c:1765 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "Lanzar un subproceso para capturar stderr y/o logs CSV en archivos de log." + +#: utils/misc/guc.c:1774 +msgid "Truncate existing log files of same name during log rotation." +msgstr "Truncar archivos de log del mismo nombre durante la rotación." + +#: utils/misc/guc.c:1785 +msgid "Emit information about resource usage in sorting." +msgstr "Emitir información acerca de uso de recursos durante los ordenamientos." + +#: utils/misc/guc.c:1799 +msgid "Generate debugging output for synchronized scanning." +msgstr "Generar salida de depuración para recorrido sincronizado." + +#: utils/misc/guc.c:1814 +msgid "Enable bounded sorting using heap sort." +msgstr "Activar ordenamiento acotado usando «heap sort»." + +#: utils/misc/guc.c:1827 +msgid "Emit WAL-related debugging output." +msgstr "Activar salida de depuración de WAL." + +#: utils/misc/guc.c:1839 +#, fuzzy +#| msgid "Datetimes are integer based." +msgid "Shows whether datetimes are integer based." +msgstr "Las fechas y horas se basan en tipos enteros." + +#: utils/misc/guc.c:1850 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "Define que los nombres de usuario Kerberos y GSSAPI deberían ser tratados sin distinción de mayúsculas." + +#: utils/misc/guc.c:1860 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Avisa acerca de escapes de backslash en literales de cadena corrientes." + +#: utils/misc/guc.c:1870 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "Provoca que las cadenas '...' traten las barras inclinadas inversas (\\) en forma literal." + +#: utils/misc/guc.c:1881 +msgid "Enable synchronized sequential scans." +msgstr "Permitir la sincronización de recorridos secuenciales." + +#: utils/misc/guc.c:1891 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Define si incluir o excluir la transacción con el destino de recuperación." + +#: utils/misc/guc.c:1901 +msgid "Allows connections and queries during recovery." +msgstr "Permite conexiones y consultas durante la recuperación." + +#: utils/misc/guc.c:1911 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "Permite retroalimentación desde un hot standby hacia el primario que evitará conflictos en consultas." + +#: utils/misc/guc.c:1921 +msgid "Shows whether hot standby is currently active." +msgstr "" + +#: utils/misc/guc.c:1932 +msgid "Allows modifications of the structure of system tables." +msgstr "Permite modificaciones de la estructura de las tablas del sistema." + +#: utils/misc/guc.c:1943 +msgid "Disables reading from system indexes." +msgstr "Deshabilita lectura de índices del sistema." + +#: utils/misc/guc.c:1944 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "No evita la actualización de índices, así que es seguro. Lo peor que puede ocurrir es lentitud del sistema." + +#: utils/misc/guc.c:1955 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "Activa el modo de compatibilidad con versiones anteriores de las comprobaciones de privilegios de objetos grandes." + +#: utils/misc/guc.c:1956 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "Omite las comprobaciones de privilegios cuando se leen o modifican los objetos grandes, para compatibilidad con versiones de PostgreSQL anteriores a 9.0." + +#: utils/misc/guc.c:1966 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "Al generar fragmentos SQL, entrecomillar todos los identificadores." + +#: utils/misc/guc.c:1976 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Indica si las sumas de verificación están activas en este cluster." + +#: utils/misc/guc.c:1987 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "Agregar número de secuencia a mensajes syslog para evitar supresión de duplicados." + +#: utils/misc/guc.c:1997 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "Dividir mensajes enviados a syslog en líneas y que quepan en 1024 bytes." + +#: utils/misc/guc.c:2007 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Controla si los Gather y Gather Merge también ejecutan subplanes." + +#: utils/misc/guc.c:2008 +#, fuzzy +#| msgid "Should gather nodes also run subplans, or just gather tuples?" +msgid "Should gather nodes also run subplans or just gather tuples?" +msgstr "¿Deben los nodos de recolección ejecutar subplanes, o sólo recolectar tuplas?" + +#: utils/misc/guc.c:2018 +msgid "Allow JIT compilation." +msgstr "Permitir compilación JIT." + +#: utils/misc/guc.c:2029 +#, fuzzy +#| msgid "Register JIT compiled function with debugger." +msgid "Register JIT-compiled functions with debugger." +msgstr "Registra la función JIT compilada con el depurador." + +#: utils/misc/guc.c:2046 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Escribe el bitcode LLVM para facilitar depuración de JIT." + +#: utils/misc/guc.c:2057 +msgid "Allow JIT compilation of expressions." +msgstr "Permitir compilación JIT de expresiones." + +#: utils/misc/guc.c:2068 +#, fuzzy +#| msgid "Register JIT compiled function with perf profiler." +msgid "Register JIT-compiled functions with perf profiler." +msgstr "Registrar funciones JIT-compiladas con el analizador «perf»." + +#: utils/misc/guc.c:2085 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Permitir compilación JIT de deformación de tuplas." + +#: utils/misc/guc.c:2096 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Si continuar ejecutando después de una falla al sincronizar archivos de datos." + +#: utils/misc/guc.c:2105 +msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." +msgstr "Definir si un receptor de WAL debe crear un slot de replicación temporal en caso de no haber configurado un slot permanente." + +#: utils/misc/guc.c:2123 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "Fuerza a que utilizar el siguiente archivo de WAL si no se ha comenzado un nuevo archivo de WAL dentro de N segundos." + +#: utils/misc/guc.c:2134 +msgid "Waits N seconds on connection startup after authentication." +msgstr "Espera N segundos al inicio de la conexión después de la autentificación." + +#: utils/misc/guc.c:2135 utils/misc/guc.c:2733 +msgid "This allows attaching a debugger to the process." +msgstr "Esto permite adjuntar un depurador al proceso." + +#: utils/misc/guc.c:2144 +msgid "Sets the default statistics target." +msgstr "Definir el valor por omisión de toma de estadísticas." + +#: utils/misc/guc.c:2145 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "Esto se aplica a columnas de tablas que no tienen un valor definido a través de ALTER TABLE SET STATISTICS." + +#: utils/misc/guc.c:2154 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "Tamaño de lista de FROM a partir del cual subconsultas no serán colapsadas." + +#: utils/misc/guc.c:2156 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "El planner mezclará subconsultas en consultas de nivel superior si la lista FROM resultante es menor que esta cantidad de ítems." + +#: utils/misc/guc.c:2167 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "Tamaño de lista de FROM a partir del cual constructos JOIN no serán aplanados." + +#: utils/misc/guc.c:2169 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "El planner aplanará constructos JOIN explícitos en listas de ítems FROM siempre que la lista resultante no tenga más que esta cantidad de ítems." + +#: utils/misc/guc.c:2180 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "Umbral de ítems en FROM a partir del cual se usará GEQO." + +#: utils/misc/guc.c:2190 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: effort se usa para determinar los valores por defecto para otros parámetros." + +#: utils/misc/guc.c:2200 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: número de individuos en una población." + +#: utils/misc/guc.c:2201 utils/misc/guc.c:2211 +msgid "Zero selects a suitable default value." +msgstr "Cero selecciona un valor por omisión razonable." + +#: utils/misc/guc.c:2210 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: número de iteraciones del algoritmo." + +#: utils/misc/guc.c:2222 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Define el tiempo a esperar un lock antes de buscar un deadlock." + +#: utils/misc/guc.c:2233 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "Define el máximo retardo antes de cancelar consultas cuando un servidor hot standby está procesando datos de WAL archivado." + +#: utils/misc/guc.c:2244 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "Define el máximo retardo antes de cancelar consultas cuando un servidor hot standby está procesando datos de WAL en flujo." + +#: utils/misc/guc.c:2255 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "Define el retraso mínimo para aplicar cambios durante la recuperación." + +#: utils/misc/guc.c:2266 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "Define el intervalo máximo entre reportes de estado que el receptor de WAL envía al servidor origen." + +#: utils/misc/guc.c:2277 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "Define el máximo tiempo de espera para recibir datos desde el servidor origen." + +#: utils/misc/guc.c:2288 +msgid "Sets the maximum number of concurrent connections." +msgstr "Número máximo de conexiones concurrentes." + +#: utils/misc/guc.c:2299 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "Número de conexiones reservadas para superusuarios." + +#: utils/misc/guc.c:2309 +#, fuzzy +#| msgid "could not map dynamic shared memory segment" +msgid "Amount of dynamic shared memory reserved at startup." +msgstr "no se pudo mapear el segmento de memoria compartida dinámica" + +#: utils/misc/guc.c:2324 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Número de búfers de memoria compartida usados por el servidor." + +#: utils/misc/guc.c:2335 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Número de búfers de memoria temporal usados por cada sesión." + +#: utils/misc/guc.c:2346 +msgid "Sets the TCP port the server listens on." +msgstr "Puerto TCP en el cual escuchará el servidor." + +#: utils/misc/guc.c:2356 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Privilegios de acceso al socket Unix." + +#: utils/misc/guc.c:2357 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Los sockets de dominio Unix usan la funcionalidad de permisos de archivos estándar de Unix. Se espera que el valor de esta opción sea una especificación numérica de modo, en la forma aceptada por las llamadas a sistema chmod y umask. Para usar el modo octal acostumbrado, comience el número con un 0 (cero)." + +#: utils/misc/guc.c:2371 +msgid "Sets the file permissions for log files." +msgstr "Define los privilegios para los archivos del registro del servidor." + +#: utils/misc/guc.c:2372 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Se espera que el valor de esta opción sea una especificación numérica de modo, en la forma aceptada por las llamadas a sistema chmod y umask. Para usar el modo octal acostumbrado, comience el número con un 0 (cero)." + +#: utils/misc/guc.c:2386 +#, fuzzy +#| msgid "Mode of the data directory." +msgid "Shows the mode of the data directory." +msgstr "Modo del directorio de datos." + +#: utils/misc/guc.c:2387 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "El valor del parámetro es una especificación numérica de modo, en la forma aceptada por las llamadas a sistema chmod y umask. (Para usar el modo octal acostumbrado, comience el número con un 0 (cero).)" + +#: utils/misc/guc.c:2400 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Establece el límite de memoria que se usará para espacios de trabajo de consultas." + +#: utils/misc/guc.c:2401 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "Esta es la cantidad máxima de memoria que se usará para operaciones internas de ordenamiento y tablas de hashing, antes de comenzar a usar archivos temporales en disco." + +#: utils/misc/guc.c:2413 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Establece el límite de memoria que se usará para operaciones de mantención." + +#: utils/misc/guc.c:2414 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Esto incluye operaciones como VACUUM y CREATE INDEX." + +#: utils/misc/guc.c:2424 +#, fuzzy +#| msgid "Sets the maximum memory to be used for maintenance operations." +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "Establece el límite de memoria que se usará para operaciones de mantención." + +#: utils/misc/guc.c:2425 +#, fuzzy +#| msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgid "This much memory can be used by each internal reorder buffer before spilling to disk." +msgstr "Esta es la cantidad máxima de memoria que se usará para operaciones internas de ordenamiento y tablas de hashing, antes de comenzar a usar archivos temporales en disco." + +#: utils/misc/guc.c:2441 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Establece el tamaño máximo del stack, en kilobytes." + +#: utils/misc/guc.c:2452 +msgid "Limits the total size of all temporary files used by each process." +msgstr "Limita el tamaño total de todos los archivos temporales usados en cada proceso." + +#: utils/misc/guc.c:2453 +msgid "-1 means no limit." +msgstr "-1 significa sin límite." + +#: utils/misc/guc.c:2463 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Costo de Vacuum de una página encontrada en el buffer." + +#: utils/misc/guc.c:2473 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Costo de Vacuum de una página no encontrada en el cache." + +#: utils/misc/guc.c:2483 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Costo de Vacuum de una página ensuciada por vacuum." + +#: utils/misc/guc.c:2493 +msgid "Vacuum cost amount available before napping." +msgstr "Costo de Vacuum disponible antes de descansar." + +#: utils/misc/guc.c:2503 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "Costo de Vacuum disponible antes de descansar, para autovacuum." + +#: utils/misc/guc.c:2513 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "Define la cantidad máxima de archivos abiertos por cada subproceso." + +#: utils/misc/guc.c:2526 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Define la cantidad máxima de transacciones preparadas simultáneas." + +#: utils/misc/guc.c:2537 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Define el OID mínimo para hacer seguimiento de locks." + +#: utils/misc/guc.c:2538 +msgid "Is used to avoid output on system tables." +msgstr "Se usa para evitar salida excesiva por tablas de sistema." + +#: utils/misc/guc.c:2547 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "Define el OID de una tabla con trazado incondicional de locks." + +#: utils/misc/guc.c:2559 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Define la duración máxima permitida de sentencias." + +#: utils/misc/guc.c:2560 utils/misc/guc.c:2571 utils/misc/guc.c:2582 +#: utils/misc/guc.c:2593 +msgid "A value of 0 turns off the timeout." +msgstr "Un valor de 0 desactiva el máximo." + +#: utils/misc/guc.c:2570 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Define la duración máxima permitida de cualquier espera por un lock." + +#: utils/misc/guc.c:2581 +#, fuzzy +#| msgid "Sets the maximum allowed duration of any idling transaction." +msgid "Sets the maximum allowed idle time between queries, when in a transaction." +msgstr "Define la duración máxima permitida de transacciones inactivas." + +#: utils/misc/guc.c:2592 +#, fuzzy +#| msgid "Sets the maximum allowed duration of any idling transaction." +msgid "Sets the maximum allowed idle time between queries, when not in a transaction." +msgstr "Define la duración máxima permitida de transacciones inactivas." + +#: utils/misc/guc.c:2603 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "Mínima edad a la cual VACUUM debería congelar (freeze) una fila de una tabla." + +#: utils/misc/guc.c:2613 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "Edad a la cual VACUUM debería recorrer una tabla completa para congelar (freeze) las filas." + +#: utils/misc/guc.c:2623 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "Mínima edad a la cual VACUUM debería congelar (freeze) el multixact en una fila." + +#: utils/misc/guc.c:2633 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "Edad de multixact a la cual VACUUM debería recorrer una tabla completa para congelar (freeze) las filas." + +#: utils/misc/guc.c:2643 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "Número de transacciones por las cuales VACUUM y la limpieza HOT deberían postergarse." + +#: utils/misc/guc.c:2652 +#, fuzzy +#| msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgid "Age at which VACUUM should trigger failsafe to avoid a wraparound outage." +msgstr "Edad a la cual VACUUM debería recorrer una tabla completa para congelar (freeze) las filas." + +#: utils/misc/guc.c:2661 +#, fuzzy +#| msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgid "Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage." +msgstr "Edad de multixact a la cual VACUUM debería recorrer una tabla completa para congelar (freeze) las filas." + +#: utils/misc/guc.c:2674 +msgid "Sets the maximum number of locks per transaction." +msgstr "Cantidad máxima de candados (locks) por transacción." + +#: utils/misc/guc.c:2675 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "El tamaño de la tabla compartida de candados se calcula usando la suposición de que a lo más max_locks_per_transaction * max_connections objetos necesitarán ser bloqueados simultáneamente." + +#: utils/misc/guc.c:2686 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Cantidad máxima de candados (locks) de predicado por transacción." + +#: utils/misc/guc.c:2687 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "El tamaño de la tabla compartida de candados se calcula usando la suposición de que a lo más max_pred_locks_per_transaction * max_connections objetos necesitarán ser bloqueados simultáneamente." + +#: utils/misc/guc.c:2698 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Cantidad máxima de páginas y tuplas bloqueadas por predicado." + +#: utils/misc/guc.c:2699 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Si más que este total de páginas y tuplas en la misma relación están bloqueadas por una conexión, esos locks son reemplazados por un lock a nivel de relación." + +#: utils/misc/guc.c:2709 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Cantidad máxima de locks de predicado por página." + +#: utils/misc/guc.c:2710 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Si más que este número de tuplas de la misma página están bloqueadas por una conexión, esos locks son reemplazados por un lock a nivel de página." + +#: utils/misc/guc.c:2720 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "Define el tiempo máximo para completar proceso de autentificación." + +#: utils/misc/guc.c:2732 +msgid "Waits N seconds on connection startup before authentication." +msgstr "Espera N segundos al inicio de la conexión antes de la autentificación." + +#: utils/misc/guc.c:2743 +#, fuzzy +#| msgid "Shows the size of write ahead log segments." +msgid "Sets the size of WAL files held for standby servers." +msgstr "Muestra el tamaño de los segmentos de WAL." + +#: utils/misc/guc.c:2754 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "Define el tamaño mínimo al cual reducir el WAL." + +#: utils/misc/guc.c:2766 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Define el tamaño de WAL que desencadena un checkpoint." + +#: utils/misc/guc.c:2778 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "Define el tiempo máximo entre puntos de control de WAL automáticos." + +#: utils/misc/guc.c:2789 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "Registrar si el llenado de segmentos de WAL es más frecuente que esto." + +#: utils/misc/guc.c:2791 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "Envía un mensaje a los registros del servidor si los punto de control causados por el llenado de archivos de segmento sucede con más frecuencia que este número de segundos. Un valor de 0 (cero) desactiva la opción." + +#: utils/misc/guc.c:2803 utils/misc/guc.c:3019 utils/misc/guc.c:3066 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "Número de páginas después del cual las escrituras previamente ejecutadas se sincronizan a disco." + +#: utils/misc/guc.c:2814 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "Búfers en memoria compartida para páginas de WAL." + +#: utils/misc/guc.c:2825 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "Tiempo entre sincronizaciones de WAL ejecutadas por el proceso escritor de WAL." + +#: utils/misc/guc.c:2836 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "Cantidad de WAL escrito por el proceso escritor de WAL que desencadena una sincronización (flush)." + +#: utils/misc/guc.c:2847 +#, fuzzy +#| msgid "Size of new file to fsync instead of writing WAL." +msgid "Minimum size of new file to fsync instead of writing WAL." +msgstr "Tamaño del nuevo archivo para hacer fsync en lugar de escribir WAL." + +#: utils/misc/guc.c:2858 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "Define la cantidad máxima de procesos «WAL sender» simultáneos." + +#: utils/misc/guc.c:2869 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Define la cantidad máxima de slots de replicación definidos simultáneamente." + +#: utils/misc/guc.c:2879 +#, fuzzy +#| msgid "Sets the maximum number of simultaneously defined replication slots." +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "Define la cantidad máxima de slots de replicación definidos simultáneamente." + +#: utils/misc/guc.c:2880 +msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "Los slots de replicación serán invalidados, y los segmentos de WAL eliminados o reciclados, si se usa esta cantidad de espacio de disco en WAL." + +#: utils/misc/guc.c:2892 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "Define el tiempo máximo a esperar la replicación de WAL." + +#: utils/misc/guc.c:2903 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "Retardo en microsegundos entre completar una transacción y escribir WAL a disco." + +#: utils/misc/guc.c:2915 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "Mínimo de transacciones concurrentes para esperar commit_delay." + +#: utils/misc/guc.c:2926 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Ajustar el número de dígitos mostrados para valores de coma flotante." + +#: utils/misc/guc.c:2927 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "Esto afecta los tipos real, de doble precisión, y geométricos. Un valor del parámetro cero o negativo se agrega a la cantidad estándar de dígitos (FLT_DIG o DBL_DIG, según sea apropiado). Cualquier valor mayor que cero selecciona el modo de salida preciso." + +#: utils/misc/guc.c:2939 +#, fuzzy +#| msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgid "Sets the minimum execution time above which a sample of statements will be logged. Sampling is determined by log_statement_sample_rate." +msgstr "Tiempo mínimo de ejecución a partir del cual se registran las acciones de autovacuum." + +#: utils/misc/guc.c:2942 +#, fuzzy +#| msgid "Zero prints all queries. -1 turns this feature off." +msgid "Zero logs a sample of all queries. -1 turns this feature off." +msgstr "Cero imprime todas las consultas. -1 desactiva esta funcionalidad." + +#: utils/misc/guc.c:2952 +#, fuzzy +#| msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgid "Sets the minimum execution time above which all statements will be logged." +msgstr "Tiempo mínimo de ejecución a partir del cual se registran las acciones de autovacuum." + +#: utils/misc/guc.c:2954 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "Cero imprime todas las consultas. -1 desactiva esta funcionalidad." + +#: utils/misc/guc.c:2964 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "Tiempo mínimo de ejecución a partir del cual se registran las acciones de autovacuum." + +#: utils/misc/guc.c:2966 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "Cero registra todas las acciones. -1 desactiva el registro de autovacuum." + +#: utils/misc/guc.c:2976 +msgid "When logging statements, limit logged parameter values to first N bytes." +msgstr "Cuando se registren sentencias, limitar los valores de parámetros registrados a los primeros N bytes." + +#: utils/misc/guc.c:2977 utils/misc/guc.c:2988 +msgid "-1 to print values in full." +msgstr "-1 para mostrar los valores completos." + +#: utils/misc/guc.c:2987 +msgid "When reporting an error, limit logged parameter values to first N bytes." +msgstr "Cuando se reporta un error, limitar los valores de parámetros registrados a los primeros N bytes." + +#: utils/misc/guc.c:2998 +msgid "Background writer sleep time between rounds." +msgstr "Tiempo de descanso entre rondas del background writer" + +#: utils/misc/guc.c:3009 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "Número máximo de páginas LRU a escribir en cada ronda del background writer" + +#: utils/misc/guc.c:3032 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "Cantidad máxima de peticiones simultáneas que pueden ser manejadas eficientemente por el sistema de disco." + +#: utils/misc/guc.c:3050 +msgid "A variant of effective_io_concurrency that is used for maintenance work." +msgstr "Una variante de effective_io_concurrency que se usa para tareas de mantención." + +#: utils/misc/guc.c:3079 +msgid "Maximum number of concurrent worker processes." +msgstr "Número máximo de procesos ayudantes concurrentes." + +#: utils/misc/guc.c:3091 +msgid "Maximum number of logical replication worker processes." +msgstr "Número máximo de procesos ayudantes de replicación lógica." + +#: utils/misc/guc.c:3103 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Número máximo de procesos ayudantes de sincronización por suscripción." + +#: utils/misc/guc.c:3113 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "La rotación automática de archivos de log se efectuará después de N minutos." + +#: utils/misc/guc.c:3124 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "La rotación automática de archivos de log se efectuará después de N kilobytes." + +#: utils/misc/guc.c:3135 +msgid "Shows the maximum number of function arguments." +msgstr "Muestra la cantidad máxima de argumentos de funciones." + +#: utils/misc/guc.c:3146 +msgid "Shows the maximum number of index keys." +msgstr "Muestra la cantidad máxima de claves de índices." + +#: utils/misc/guc.c:3157 +msgid "Shows the maximum identifier length." +msgstr "Muestra el largo máximo de identificadores." + +#: utils/misc/guc.c:3168 +msgid "Shows the size of a disk block." +msgstr "Muestra el tamaño de un bloque de disco." + +#: utils/misc/guc.c:3179 +msgid "Shows the number of pages per disk file." +msgstr "Muestra el número de páginas por archivo en disco." + +#: utils/misc/guc.c:3190 +msgid "Shows the block size in the write ahead log." +msgstr "Muestra el tamaño de bloque en el write-ahead log." + +#: utils/misc/guc.c:3201 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "Define el tiempo a esperar antes de reintentar obtener WAL después de un intento fallido." + +#: utils/misc/guc.c:3213 +msgid "Shows the size of write ahead log segments." +msgstr "Muestra el tamaño de los segmentos de WAL." + +#: utils/misc/guc.c:3226 +msgid "Time to sleep between autovacuum runs." +msgstr "Tiempo de descanso entre ejecuciones de autovacuum." + +#: utils/misc/guc.c:3236 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Número mínimo de updates o deletes antes de ejecutar vacuum." + +#: utils/misc/guc.c:3245 +#, fuzzy +#| msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgid "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums." +msgstr "Número mínimo de inserciones, actualizaciones y eliminaciones de tuplas antes de ejecutar analyze." + +#: utils/misc/guc.c:3254 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "Número mínimo de inserciones, actualizaciones y eliminaciones de tuplas antes de ejecutar analyze." + +#: utils/misc/guc.c:3264 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "Edad a la cual aplicar VACUUM automáticamente a una tabla para prevenir problemas por reciclaje de ID de transacción." + +#: utils/misc/guc.c:3279 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "Edad de multixact a la cual aplicar VACUUM automáticamente a una tabla para prevenir problemas por reciclaje de ID de multixacts." + +#: utils/misc/guc.c:3289 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "Define la cantidad máxima de procesos «autovacuum worker» simultáneos." + +#: utils/misc/guc.c:3299 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Cantidad máxima de procesos ayudantes paralelos por operación de mantención." + +#: utils/misc/guc.c:3309 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Cantidad máxima de locks de predicado por nodo de ejecución." + +#: utils/misc/guc.c:3320 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Define la cantidad máxima de procesos ayudantes que pueden estar activos en un momento dado." + +#: utils/misc/guc.c:3331 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "Establece el límite de memoria que cada proceso «autovacuum worker» usará." + +#: utils/misc/guc.c:3342 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "Tiempo antes de que un snapshot sea demasiado antiguo para leer páginas después de que el snapshot fue tomado." + +#: utils/misc/guc.c:3343 +msgid "A value of -1 disables this feature." +msgstr "El valor -1 desactiva esta característica." + +#: utils/misc/guc.c:3353 +msgid "Time between issuing TCP keepalives." +msgstr "Tiempo entre cada emisión de TCP keepalive." + +#: utils/misc/guc.c:3354 utils/misc/guc.c:3365 utils/misc/guc.c:3489 +msgid "A value of 0 uses the system default." +msgstr "Un valor 0 usa el valor por omisión del sistema." + +#: utils/misc/guc.c:3364 +msgid "Time between TCP keepalive retransmits." +msgstr "Tiempo entre retransmisiones TCP keepalive." + +#: utils/misc/guc.c:3375 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "La renegociación SSL ya no está soportada; esto sólo puede ser 0." + +#: utils/misc/guc.c:3386 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "Cantidad máxima de retransmisiones TCP keepalive." + +#: utils/misc/guc.c:3387 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "Esto controla el número de retransmisiones consecutivas de keepalive que pueden ser perdidas antes que la conexión sea considerada muerta. Un valor 0 usa el valor por omisión del sistema." + +#: utils/misc/guc.c:3398 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "Define el máximo de resultados permitidos por búsquedas exactas con GIN." + +#: utils/misc/guc.c:3409 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Define la suposición del optimizador sobre el tamaño total de los caches de datos." + +#: utils/misc/guc.c:3410 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Esto es, el tamaño total de caches (cache del kernel y búfers compartidos) usados por archivos de datos de PostgreSQL. Esto se mide en páginas de disco, que normalmente son de 8 kB cada una." + +#: utils/misc/guc.c:3421 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "Define la cantidad mínima de datos en una tabla para un recorrido paralelo." + +#: utils/misc/guc.c:3422 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Si el planificador estima que leerá un número de páginas de tabla demasiado pequeñas para alcanzar este límite, no se considerará una búsqueda paralela." + +#: utils/misc/guc.c:3432 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "Define la cantidad mínima de datos en un índice para un recorrido paralelo." + +#: utils/misc/guc.c:3433 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Si el planificador estima que leerá un número de páginas de índice demasiado pequeñas para alcanzar este límite, no se considerará una búsqueda paralela." + +#: utils/misc/guc.c:3444 +msgid "Shows the server version as an integer." +msgstr "Muestra la versión del servidor como un número entero." + +#: utils/misc/guc.c:3455 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "Registra el uso de archivos temporales que crezcan más allá de este número de kilobytes." + +#: utils/misc/guc.c:3456 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "Cero registra todos los archivos. El valor por omisión es -1 (lo cual desactiva el registro)." + +#: utils/misc/guc.c:3466 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "Tamaño reservado para pg_stat_activity.query, en bytes." + +#: utils/misc/guc.c:3477 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "Define el tamaño máximo de la lista de pendientes de un índice GIN." + +#: utils/misc/guc.c:3488 +msgid "TCP user timeout." +msgstr "Tiempo de expiración de TCP." + +#: utils/misc/guc.c:3499 +msgid "The size of huge page that should be requested." +msgstr "" + +#: utils/misc/guc.c:3510 +msgid "Aggressively invalidate system caches for debugging purposes." +msgstr "" + +#: utils/misc/guc.c:3533 +#, fuzzy +#| msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgid "Sets the time interval between checks for disconnection while running queries." +msgstr "Define el intervalo máximo entre reportes de estado que el receptor de WAL envía al servidor origen." + +#: utils/misc/guc.c:3553 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "Estimación del costo de una página leída secuencialmente." + +#: utils/misc/guc.c:3564 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "Estimación del costo de una página leída no secuencialmente." + +#: utils/misc/guc.c:3575 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "Estimación del costo de procesar cada tupla (fila)." + +#: utils/misc/guc.c:3586 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "Estimación del costo de procesar cada fila de índice durante un recorrido de índice." + +#: utils/misc/guc.c:3597 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "Estimación del costo de procesar cada operador o llamada a función." + +#: utils/misc/guc.c:3608 +#, fuzzy +#| msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to leader backend." +msgstr "Estimación del costo de pasar cada tupla (fila) desde un proceso ayudante al proceso servidor principal." + +#: utils/misc/guc.c:3619 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "Estimación del costo de lanzar procesos ayudantes para consultas en paralelo." + +#: utils/misc/guc.c:3631 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Ejecutar compilación JIT si la consulta es más cara." + +#: utils/misc/guc.c:3632 +msgid "-1 disables JIT compilation." +msgstr "-1 inhabilita compilación JIT." + +#: utils/misc/guc.c:3642 +#, fuzzy +#| msgid "Optimize JITed functions if query is more expensive." +msgid "Optimize JIT-compiled functions if query is more expensive." +msgstr "Optimizar funciones JIT-compiladas si la consulta es más cara." + +#: utils/misc/guc.c:3643 +msgid "-1 disables optimization." +msgstr "-1 inhabilita la optimización." + +#: utils/misc/guc.c:3653 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Ejecutar «inlining» JIT si la consulta es más cara." + +#: utils/misc/guc.c:3654 +msgid "-1 disables inlining." +msgstr "-1 inhabilita el «inlining»." + +#: utils/misc/guc.c:3664 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "Estimación de la fracción de filas de un cursor que serán extraídas." + +#: utils/misc/guc.c:3676 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: presión selectiva dentro de la población." + +#: utils/misc/guc.c:3687 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: semilla para la selección aleatoria de caminos." + +#: utils/misc/guc.c:3698 +msgid "Multiple of work_mem to use for hash tables." +msgstr "Múltiplo de work_mem para el uso de tablas de hash." + +#: utils/misc/guc.c:3709 +msgid "Multiple of the average buffer usage to free per round." +msgstr "Múltiplo del uso promedio de búfers que liberar en cada ronda." + +#: utils/misc/guc.c:3719 +msgid "Sets the seed for random-number generation." +msgstr "Semilla para la generación de números aleatorios." + +#: utils/misc/guc.c:3730 +msgid "Vacuum cost delay in milliseconds." +msgstr "Tiempo de descanso de vacuum en milisegundos." + +#: utils/misc/guc.c:3741 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Tiempo de descanso de vacuum en milisegundos, para autovacuum." + +#: utils/misc/guc.c:3752 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "Número de updates o deletes de tuplas antes de ejecutar un vacuum, como fracción de reltuples." + +#: utils/misc/guc.c:3762 +#, fuzzy +#| msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "Número de inserts de tuplas antes de ejecutar una limpieza de índice, como fracción de reltuples." + +#: utils/misc/guc.c:3772 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "Número mínimo de inserciones, actualizaciones y eliminaciones de tuplas antes de ejecutar analyze, como fracción de reltuples." + +#: utils/misc/guc.c:3782 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "Tiempo utilizado en escribir páginas «sucias» durante los puntos de control, medido como fracción del intervalo del punto de control." + +#: utils/misc/guc.c:3792 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "Fracción de sentencias que duren más de log_min_duration_sample a ser registradas." + +#: utils/misc/guc.c:3793 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "Use un valor entre 0.0 (no registrar nunca) y 1.0 (registrar siempre)." + +#: utils/misc/guc.c:3802 +#, fuzzy +#| msgid "Set the fraction of transactions to log for new transactions." +msgid "Sets the fraction of transactions from which to log all statements." +msgstr "Define la fracción de transacciones que registrar en el log, para nuevas transacciones." + +#: utils/misc/guc.c:3803 +#, fuzzy +#| msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgid "Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "Registra todas las sentencias de una fracción de transacciones. Use un valor entre 0.0 (nunca registrar) y 1.0 (registrar todas las sentencias de todas las transacciones)." + +#: utils/misc/guc.c:3822 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "Orden de shell que se invocará para archivar un archivo WAL." + +#: utils/misc/guc.c:3832 +#, fuzzy +#| msgid "Sets the shell command that will be called to archive a WAL file." +msgid "Sets the shell command that will be called to retrieve an archived WAL file." +msgstr "Orden de shell que se invocará para archivar un archivo WAL." + +#: utils/misc/guc.c:3842 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "Orden de shell que se invocará en cada «restart point»." + +#: utils/misc/guc.c:3852 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "Orden de shell que se invocará una vez al terminar la recuperación." + +#: utils/misc/guc.c:3862 +msgid "Specifies the timeline to recover into." +msgstr "Especifica la línea de tiempo a la cual recuperar." + +#: utils/misc/guc.c:3872 +msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." +msgstr "Defina a «immediate» para terminar la recuperación en cuando se alcance el estado consistente." + +#: utils/misc/guc.c:3881 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "Define el ID de transacción hasta el cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3890 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "Define la marca de tiempo hasta la cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3899 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "Define el nombre del punto de restauración hasta el cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3908 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "Define el LSN de la ubicación de WAL hasta la cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3918 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "Especifica un nombre de archivo cuya presencia termina la recuperación en el standby." + +#: utils/misc/guc.c:3928 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "Define la cadena de conexión que se usará para conectarse al servidor de origen." + +#: utils/misc/guc.c:3939 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "Define el nombre del slot de replicación a utilizar en el servidor de origen." + +#: utils/misc/guc.c:3949 +msgid "Sets the client's character set encoding." +msgstr "Codificación del juego de caracteres del cliente." + +#: utils/misc/guc.c:3960 +msgid "Controls information prefixed to each log line." +msgstr "Controla el prefijo que antecede cada línea registrada." + +#: utils/misc/guc.c:3961 +msgid "If blank, no prefix is used." +msgstr "si está en blanco, no se usa prefijo." + +#: utils/misc/guc.c:3970 +msgid "Sets the time zone to use in log messages." +msgstr "Define el huso horario usando en los mensajes registrados." + +#: utils/misc/guc.c:3980 +msgid "Sets the display format for date and time values." +msgstr "Formato de salida para valores de horas y fechas." + +#: utils/misc/guc.c:3981 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "También controla la interpretación de entradas ambiguas de fechas" + +#: utils/misc/guc.c:3992 +msgid "Sets the default table access method for new tables." +msgstr "Define el método de acceso a tablas por omisión para nuevas tablas." + +#: utils/misc/guc.c:4003 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "Define el tablespace en el cual crear tablas e índices." + +#: utils/misc/guc.c:4004 +msgid "An empty string selects the database's default tablespace." +msgstr "Una cadena vacía especifica el tablespace por omisión de la base de datos." + +#: utils/misc/guc.c:4014 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "Define el/los tablespace/s en el cual crear tablas temporales y archivos de ordenamiento." + +#: utils/misc/guc.c:4025 +msgid "Sets the path for dynamically loadable modules." +msgstr "Ruta para módulos dinámicos." + +#: utils/misc/guc.c:4026 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "Si se necesita abrir un módulo dinámico y el nombre especificado no tiene un componente de directorio (es decir, no contiene un slash), el sistema buscará el archivo especificado en esta ruta." + +#: utils/misc/guc.c:4039 +msgid "Sets the location of the Kerberos server key file." +msgstr "Ubicación del archivo de llave del servidor Kerberos." + +#: utils/misc/guc.c:4050 +msgid "Sets the Bonjour service name." +msgstr "Nombre del servicio Bonjour." + +#: utils/misc/guc.c:4062 +msgid "Shows the collation order locale." +msgstr "Configuración regional de ordenamiento de cadenas (collation)." + +#: utils/misc/guc.c:4073 +msgid "Shows the character classification and case conversion locale." +msgstr "Configuración regional de clasificación de caracteres y conversión de mayúsculas." + +#: utils/misc/guc.c:4084 +msgid "Sets the language in which messages are displayed." +msgstr "Idioma en el que se despliegan los mensajes." + +#: utils/misc/guc.c:4094 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Configuración regional para formatos de moneda." + +#: utils/misc/guc.c:4104 +msgid "Sets the locale for formatting numbers." +msgstr "Configuración regional para formatos de números." + +#: utils/misc/guc.c:4114 +msgid "Sets the locale for formatting date and time values." +msgstr "Configuración regional para formatos de horas y fechas." + +#: utils/misc/guc.c:4124 +msgid "Lists shared libraries to preload into each backend." +msgstr "Bibliotecas compartidas a precargar en cada proceso." + +#: utils/misc/guc.c:4135 +msgid "Lists shared libraries to preload into server." +msgstr "Bibliotecas compartidas a precargar en el servidor." + +#: utils/misc/guc.c:4146 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "Bibliotecas compartidas no privilegiadas a precargar en cada proceso." + +#: utils/misc/guc.c:4157 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "Orden de búsqueda en schemas para nombres que no especifican schema." + +#: utils/misc/guc.c:4169 +#, fuzzy +#| msgid "Sets the server (database) character set encoding." +msgid "Shows the server (database) character set encoding." +msgstr "Codificación de caracteres del servidor (bases de datos)." + +#: utils/misc/guc.c:4181 +msgid "Shows the server version." +msgstr "Versión del servidor." + +#: utils/misc/guc.c:4193 +msgid "Sets the current role." +msgstr "Define el rol actual." + +#: utils/misc/guc.c:4205 +msgid "Sets the session user name." +msgstr "Define el nombre del usuario de sesión." + +#: utils/misc/guc.c:4216 +msgid "Sets the destination for server log output." +msgstr "Define el destino de la salida del registro del servidor." + +#: utils/misc/guc.c:4217 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "Los valores aceptables son combinaciones de «stderr», «syslog», «csvlog» y «eventlog», dependiendo de la plataforma." + +#: utils/misc/guc.c:4228 +msgid "Sets the destination directory for log files." +msgstr "Define el directorio de destino de los archivos del registro del servidor." + +#: utils/misc/guc.c:4229 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "Puede ser una ruta relativa al directorio de datos o una ruta absoluta." + +#: utils/misc/guc.c:4239 +msgid "Sets the file name pattern for log files." +msgstr "Define el patrón para los nombres de archivo del registro del servidor." + +#: utils/misc/guc.c:4250 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "Nombre de programa para identificar PostgreSQL en mensajes de syslog." + +#: utils/misc/guc.c:4261 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "Nombre de programa para identificar PostgreSQL en mensajes del log de eventos." + +#: utils/misc/guc.c:4272 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "Huso horario para desplegar e interpretar valores de tiempo." + +#: utils/misc/guc.c:4282 +msgid "Selects a file of time zone abbreviations." +msgstr "Selecciona un archivo de abreviaciones de huso horario." + +#: utils/misc/guc.c:4292 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Grupo dueño del socket de dominio Unix." + +#: utils/misc/guc.c:4293 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "El usuario dueño del socket siempre es el usuario que inicia el servidor." + +#: utils/misc/guc.c:4303 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Directorios donde se crearán los sockets de dominio Unix." + +#: utils/misc/guc.c:4318 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Define el nombre de anfitrión o dirección IP en la cual escuchar." + +#: utils/misc/guc.c:4333 +msgid "Sets the server's data directory." +msgstr "Define la ubicación del directorio de datos." + +#: utils/misc/guc.c:4344 +msgid "Sets the server's main configuration file." +msgstr "Define la ubicación del archivo principal de configuración del servidor." + +#: utils/misc/guc.c:4355 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Define la ubicación del archivo de configuración «hba» del servidor." + +#: utils/misc/guc.c:4366 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Define la ubicación del archivo de configuración «ident» del servidor." + +#: utils/misc/guc.c:4377 +msgid "Writes the postmaster PID to the specified file." +msgstr "Registra el PID de postmaster en el archivo especificado." + +#: utils/misc/guc.c:4388 +#, fuzzy +#| msgid "Name of the SSL library." +msgid "Shows the name of the SSL library." +msgstr "Nombre de la biblioteca SSL." + +#: utils/misc/guc.c:4403 +msgid "Location of the SSL server certificate file." +msgstr "Ubicación del archivo de certificado SSL del servidor." + +#: utils/misc/guc.c:4413 +msgid "Location of the SSL server private key file." +msgstr "Ubicación del archivo de la llave SSL privada del servidor." + +#: utils/misc/guc.c:4423 +msgid "Location of the SSL certificate authority file." +msgstr "Ubicación del archivo de autoridad certificadora SSL." + +#: utils/misc/guc.c:4433 +msgid "Location of the SSL certificate revocation list file." +msgstr "Ubicación del archivo de lista de revocación de certificados SSL" + +#: utils/misc/guc.c:4443 +#, fuzzy +#| msgid "Location of the SSL certificate revocation list file." +msgid "Location of the SSL certificate revocation list directory." +msgstr "Ubicación del archivo de lista de revocación de certificados SSL" + +#: utils/misc/guc.c:4453 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Escribe los archivos temporales de estadísticas al directorio especificado." + +#: utils/misc/guc.c:4464 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "Número de standbys sincrónicos y lista de nombres de los potenciales sincrónicos." + +#: utils/misc/guc.c:4475 +msgid "Sets default text search configuration." +msgstr "Define la configuración de búsqueda en texto por omisión." + +#: utils/misc/guc.c:4485 +msgid "Sets the list of allowed SSL ciphers." +msgstr "Define la lista de cifrados SSL permitidos." + +#: utils/misc/guc.c:4500 +msgid "Sets the curve to use for ECDH." +msgstr "Define la curva a usar para ECDH." + +#: utils/misc/guc.c:4515 +msgid "Location of the SSL DH parameters file." +msgstr "Ubicación del archivo de parámetros DH para SSL." + +#: utils/misc/guc.c:4526 +msgid "Command to obtain passphrases for SSL." +msgstr "Orden para obtener frases clave para SSL." + +#: utils/misc/guc.c:4537 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "Define el nombre de aplicación a reportarse en estadísticas y logs." + +#: utils/misc/guc.c:4548 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Define el nombre del clúster, el cual se incluye en el título de proceso." + +#: utils/misc/guc.c:4559 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "Define los gestores de recursos WAL para los cuales hacer verificaciones de consistencia WAL." + +#: utils/misc/guc.c:4560 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "Se registrarán imágenes de página completa para todos los bloques de datos, y comparados con los resultados de la aplicación de WAL." + +#: utils/misc/guc.c:4570 +msgid "JIT provider to use." +msgstr "Proveedor JIT a usar." + +#: utils/misc/guc.c:4581 +#, fuzzy +#| msgid "Logs the host name in the connection logs." +msgid "Log backtrace for errors in these functions." +msgstr "Registrar el nombre del host en la conexión." + +#: utils/misc/guc.c:4601 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Define si «\\'» está permitido en literales de cadena." + +#: utils/misc/guc.c:4611 +msgid "Sets the output format for bytea." +msgstr "Formato de salida para bytea." + +#: utils/misc/guc.c:4621 +msgid "Sets the message levels that are sent to the client." +msgstr "Nivel de mensajes enviados al cliente." + +#: utils/misc/guc.c:4622 utils/misc/guc.c:4708 utils/misc/guc.c:4719 +#: utils/misc/guc.c:4795 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "Cada nivel incluye todos los niveles que lo siguen. Mientras más posterior el nivel, menos mensajes se enviarán." + +#: utils/misc/guc.c:4632 +#, fuzzy +#| msgid "unterminated quoted identifier" +msgid "Compute query identifiers." +msgstr "un identificador entre comillas está inconcluso" + +#: utils/misc/guc.c:4642 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "Permitir el uso de restricciones para limitar los accesos a tablas." + +#: utils/misc/guc.c:4643 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "Las tablas no serán recorridas si sus restricciones garantizan que ninguna fila coincidirá con la consulta." + +#: utils/misc/guc.c:4654 +#, fuzzy +#| msgid "Sets the default table access method for new tables." +msgid "Sets the default compression method for compressible values." +msgstr "Define el método de acceso a tablas por omisión para nuevas tablas." + +#: utils/misc/guc.c:4665 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Nivel de aislación (isolation level) de transacciones nuevas." + +#: utils/misc/guc.c:4675 +msgid "Sets the current transaction's isolation level." +msgstr "Define el nivel de aislación de la transacción en curso." + +#: utils/misc/guc.c:4686 +msgid "Sets the display format for interval values." +msgstr "Formato de salida para valores de intervalos." + +#: utils/misc/guc.c:4697 +msgid "Sets the verbosity of logged messages." +msgstr "Verbosidad de los mensajes registrados." + +#: utils/misc/guc.c:4707 +msgid "Sets the message levels that are logged." +msgstr "Nivel de mensajes registrados." + +#: utils/misc/guc.c:4718 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "Registrar sentencias que generan error de nivel superior o igual a éste." + +#: utils/misc/guc.c:4729 +msgid "Sets the type of statements logged." +msgstr "Define el tipo de sentencias que se registran." + +#: utils/misc/guc.c:4739 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "«Facility» de syslog que se usará cuando syslog esté habilitado." + +#: utils/misc/guc.c:4754 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "Define el comportamiento de la sesión con respecto a disparadores y reglas de reescritura." + +#: utils/misc/guc.c:4764 +msgid "Sets the current transaction's synchronization level." +msgstr "Define el nivel de sincronización de la transacción en curso." + +#: utils/misc/guc.c:4774 +msgid "Allows archiving of WAL files using archive_command." +msgstr "Permite el archivado de WAL usando archive_command." + +#: utils/misc/guc.c:4784 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "Acción a ejecutar al alcanzar el destino de recuperación." + +#: utils/misc/guc.c:4794 +msgid "Enables logging of recovery-related debugging information." +msgstr "Recolectar información de depuración relacionada con la recuperación." + +#: utils/misc/guc.c:4810 +msgid "Collects function-level statistics on database activity." +msgstr "Recolectar estadísticas de actividad de funciones en la base de datos." + +#: utils/misc/guc.c:4820 +#, fuzzy +#| msgid "Set the level of information written to the WAL." +msgid "Sets the level of information written to the WAL." +msgstr "Nivel de información escrita a WAL." + +#: utils/misc/guc.c:4830 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Escoge la implementación de memoria compartida dinámica que se usará." + +#: utils/misc/guc.c:4840 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "Escoge la implementación de memoria compartida dinámica que se usará para la región principal de memoria compartida." + +#: utils/misc/guc.c:4850 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "Selecciona el método usado para forzar escritura de WAL a disco." + +#: utils/misc/guc.c:4860 +msgid "Sets how binary values are to be encoded in XML." +msgstr "Define cómo se codificarán los valores binarios en XML." + +#: utils/misc/guc.c:4870 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "Define si los datos XML implícitos en operaciones de análisis y serialización serán considerados documentos o fragmentos de contenido." + +#: utils/misc/guc.c:4881 +msgid "Use of huge pages on Linux or Windows." +msgstr "Usar páginas grandes (huge) en Linux o Windows." + +#: utils/misc/guc.c:4891 +msgid "Forces use of parallel query facilities." +msgstr "Obliga al uso de la funcionalidad de consultas paralelas." + +#: utils/misc/guc.c:4892 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "Si es posible, ejecuta cada consulta en un ayudante paralelo y con restricciones de paralelismo." + +#: utils/misc/guc.c:4902 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "Escoge el algoritmo para cifrar contraseñas." + +#: utils/misc/guc.c:4912 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Controla la selección del optimizador de planes genéricos o «custom»." + +#: utils/misc/guc.c:4913 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "Las sentencias preparadas pueden tener planes genéricos y «custom», y el optimizador intentará escoger cuál es mejor. Esto puede usarse para controlar manualmente el comportamiento." + +#: utils/misc/guc.c:4925 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "Define la versión mínima del protocolo SSL/TLS a usar." + +#: utils/misc/guc.c:4937 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "Define la versión máxima del protocolo SSL/TLS a usar." + +#: utils/misc/guc.c:4949 +msgid "Sets the method for synchronizing the data directory before crash recovery." +msgstr "" + +#: utils/misc/guc.c:5518 +#, fuzzy, c-format +#| msgid "unrecognized configuration parameter \"%s\"" +msgid "invalid configuration parameter name \"%s\"" +msgstr "parámetro de configuración «%s» no reconocido" + +#: utils/misc/guc.c:5520 +#, c-format +msgid "Custom parameter names must be two or more simple identifiers separated by dots." +msgstr "" + +#: utils/misc/guc.c:5529 utils/misc/guc.c:9288 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "parámetro de configuración «%s» no reconocido" + +#: utils/misc/guc.c:5822 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: no se pudo acceder al directorio «%s»: %s\n" + +#: utils/misc/guc.c:5827 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "Ejecute initdb o pg_basebackup para inicializar un directorio de datos de PostgreSQL.\n" + +#: utils/misc/guc.c:5847 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%s no sabe dónde encontrar el archivo de configuración del servidor.\n" +"Debe especificar la opción --config-file o -D o definir la variable de ambiente PGDATA.\n" + +#: utils/misc/guc.c:5866 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: no se pudo acceder al archivo de configuración «%s»: %s\n" + +#: utils/misc/guc.c:5892 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s no sabe dónde encontrar los archivos de sistema de la base de datos.\n" +"Esto puede especificarse como «data_directory» en «%s», o usando la opción -D, o a través de la variable de ambiente PGDATA.\n" + +#: utils/misc/guc.c:5940 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s no sabe dónde encontrar el archivo de configuración «hba».\n" +"Esto puede especificarse como «hba_file» en «%s», o usando la opción -D, o a través de la variable de ambiente PGDATA.\n" + +#: utils/misc/guc.c:5963 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s no sabe dónde encontrar el archivo de configuración «ident».\n" +"Esto puede especificarse como «ident_file» en «%s», o usando la opción -D, o a través de la variable de ambiente PGDATA.\n" + +#: utils/misc/guc.c:6888 +msgid "Value exceeds integer range." +msgstr "El valor excede el rango para enteros." + +#: utils/misc/guc.c:7124 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s está fuera del rango aceptable para el parámetro «%s» (%d .. %d)" + +#: utils/misc/guc.c:7160 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s está fuera del rango aceptable para el parámetro «%s» (%g .. %g)" + +#: utils/misc/guc.c:7320 utils/misc/guc.c:8692 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "no se puede definir parámetros durante una operación paralela" + +#: utils/misc/guc.c:7337 utils/misc/guc.c:8533 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "no se puede cambiar el parámetro «%s»" + +#: utils/misc/guc.c:7370 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "el parámetro «%s» no se puede cambiar en este momento" + +#: utils/misc/guc.c:7388 utils/misc/guc.c:7435 utils/misc/guc.c:11333 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "se ha denegado el permiso para cambiar la opción «%s»" + +#: utils/misc/guc.c:7425 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "el parámetro «%s» no se puede cambiar después de efectuar la conexión" + +#: utils/misc/guc.c:7473 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "no se puede definir el parámetro «%s» dentro una función security-definer" + +#: utils/misc/guc.c:8106 utils/misc/guc.c:8153 utils/misc/guc.c:9550 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "debe ser superusuario o miembro del rol pg_read_all settings para examinar «%s»" + +#: utils/misc/guc.c:8237 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s lleva sólo un argumento" + +#: utils/misc/guc.c:8485 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "debe ser superusuario para ejecutar la orden ALTER SYSTEM" + +#: utils/misc/guc.c:8566 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "los valores de parámetros para ALTER SYSTEM no deben contener saltos de línea" + +#: utils/misc/guc.c:8611 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "no se pudo interpretar el contenido del archivo «%s»" + +#: utils/misc/guc.c:8768 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT no está implementado" + +#: utils/misc/guc.c:8852 +#, c-format +msgid "SET requires parameter name" +msgstr "SET requiere el nombre de un parámetro" + +#: utils/misc/guc.c:8985 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "intento de cambiar la opción «%s»" + +#: utils/misc/guc.c:10780 +#, fuzzy, c-format +#| msgid "parameter \"%s\" changed to \"%s\"" +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "el parámetro «%s» fue cambiado a «%s»" + +#: utils/misc/guc.c:10945 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "no se pudo cambiar el parámetro «%s»" + +#: utils/misc/guc.c:11037 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "no se pudo interpretar el valor de para el parámetro «%s»" + +#: utils/misc/guc.c:11395 utils/misc/guc.c:11429 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "valor no válido para el parámetro «%s»: %d" + +#: utils/misc/guc.c:11463 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "valor no válido para el parámetro «%s»: %g" + +#: utils/misc/guc.c:11750 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "«temp_buffers» no puede ser cambiado después de que cualquier tabla temporal haya sido accedida en la sesión." + +#: utils/misc/guc.c:11762 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour no está soportado en este servidor" + +#: utils/misc/guc.c:11775 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL no está soportado en este servidor" + +#: utils/misc/guc.c:11787 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "No se puede activar el parámetro cuando «log_statement_stats» está activo." + +#: utils/misc/guc.c:11799 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "No se puede activar «log_statement_stats» cuando «log_parser_stats», «log_planner_stats» o «log_executor_stats» están activos." + +#: utils/misc/guc.c:12029 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "effective_io_concurrency debe ser 0 en plataformas que no tienen posix_fadvise()." + +#: utils/misc/guc.c:12042 +#, fuzzy, c-format +#| msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgid "maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "effective_io_concurrency debe ser 0 en plataformas que no tienen posix_fadvise()." + +#: utils/misc/guc.c:12056 +#, fuzzy, c-format +#| msgid "huge pages not supported on this platform" +msgid "huge_page_size must be 0 on this platform." +msgstr "las huge pages no están soportados en esta plataforma" + +#: utils/misc/guc.c:12070 +#, fuzzy, c-format +#| msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgid "client_connection_check_interval must be set to 0 on platforms that lack POLLRDHUP." +msgstr "effective_io_concurrency debe ser 0 en plataformas que no tienen posix_fadvise()." + +#: utils/misc/guc.c:12198 +#, fuzzy, c-format +#| msgid "Invalid character value." +msgid "invalid character" +msgstr "Valor de carácter no válido." + +#: utils/misc/guc.c:12258 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline no es un número válido." + +#: utils/misc/guc.c:12298 +#, c-format +msgid "multiple recovery targets specified" +msgstr "múltiples valores de destino de recuperación especificados" + +#: utils/misc/guc.c:12299 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr "A lo más uno de recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid puede estar definido." + +#: utils/misc/guc.c:12307 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "El único valor permitido es «immediate»." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "error interno: tipo parámetro no reconocido\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "tupla de retorno especificada por la consulta y el tipo retornado por la función no son compatibles" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "la suma de verificación calculada no coincide con el valor almacenado en el archivo" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: usuario: %d.%02d s, sistema: %d.%02d s, transcurrido: %d.%02d s" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "la consulta sería afectada por la política de seguridad de registros para la tabla «%s»" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "Para desactivar la política para el dueño de la tabla, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." + +#: utils/misc/timeout.c:484 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "no se pueden agregar más razones de timeout" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "la abreviación del huso horario «%s» es demasiado larga (máximo %d caracteres) en archivo de huso horario «%s», línea %d" + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "desplazamiento de huso horario %d está fuera de rango en el archivo de huso horario «%s», línea %d" + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "falta una abreviación de huso horario en el archivo de huso horario «%s», línea %d" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "falta un desplazamiento de huso horario en el archivo de huso horario «%s», línea %d" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "número no válido para desplazamiento de huso horario en archivo de huso horario «%s», línea %d" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "sintaxis no válida en archivo de huso horario «%s», línea %d" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "abreviación de huso horario «%s» está definida múltiples veces" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "Entrada en archivo de huso horario «%s», línea %d, causa conflictos con entrada en archivo «%s», línea %d." + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "nombre de huso horario «%s» no válido" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "límite de recursión excedido en el archivo «%s»" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "no se pudo leer archivo de huso horario «%s»: %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "línea demasiado larga en archivo de huso horario «%s», línea %d" + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "@INCLUDE sin nombre de archivo en archivo de huso horario «%s», línea %d" + +#: utils/mmgr/aset.c:477 utils/mmgr/generation.c:235 utils/mmgr/slab.c:237 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Falla al crear el contexto de memoria «%s»." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1329 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "no se pudo adjuntar al segmento de memoria compartida dinámica" + +#: utils/mmgr/mcxt.c:889 utils/mmgr/mcxt.c:925 utils/mmgr/mcxt.c:963 +#: utils/mmgr/mcxt.c:1001 utils/mmgr/mcxt.c:1083 utils/mmgr/mcxt.c:1114 +#: utils/mmgr/mcxt.c:1150 utils/mmgr/mcxt.c:1202 utils/mmgr/mcxt.c:1237 +#: utils/mmgr/mcxt.c:1272 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Falló una petición de tamaño %zu en el contexto de memoria «%s»." + +#: utils/mmgr/mcxt.c:1046 +#, c-format +msgid "logging memory contexts of PID %d" +msgstr "" + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "el cursor «%s» ya existe" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "cerrando el cursor «%s» preexistente" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "el portal «%s» no puede ser ejecutado" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "no se puede eliminar el portal «pinned» «%s»" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "no se puede eliminar el portal activo «%s»" + +#: utils/mmgr/portalmem.c:736 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "no se puede hacer PREPARE de una transacción que ha creado un cursor WITH HOLD" + +#: utils/mmgr/portalmem.c:1275 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "no se pueden ejecutar órdenes de transacción dentro de un bucle de cursor que no es de sólo lectura" + +#: utils/sort/logtape.c:268 utils/sort/logtape.c:291 +#, fuzzy, c-format +#| msgid "could not rewind temporary file" +msgid "could not seek to block %ld of temporary file" +msgstr "no se puede rebobinar el archivo temporal" + +#: utils/sort/logtape.c:297 +#, fuzzy, c-format +#| msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "no se pudo leer el archivo temporal de hash-join: se leyeron sólo %zu de %zu bytes" + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 +#: utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 +#: utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "no se pudo leer desde el archivo temporal del tuplestore compartido" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "trozo inesperado en archivo temporal del tuplestore compartido" + +#: utils/sort/sharedtuplestore.c:569 +#, fuzzy, c-format +#| msgid "could not seek block %u in shared tuplestore temporary file" +msgid "could not seek to block %u in shared tuplestore temporary file" +msgstr "no se pudo posicionar (seek) al bloque %u en el archivo temporal del tuplestore compartido" + +#: utils/sort/sharedtuplestore.c:576 +#, fuzzy, c-format +#| msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgid "could not read from shared tuplestore temporary file: read only %zu of %zu bytes" +msgstr "no se pudo leer el archivo temporal de hash-join: se leyeron sólo %zu de %zu bytes" + +#: utils/sort/tuplesort.c:3216 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "no se pueden tener más de %d pasadas para un ordenamiento externo" + +#: utils/sort/tuplesort.c:4297 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "no se pudo crear el índice único «%s»" + +#: utils/sort/tuplesort.c:4299 +#, c-format +msgid "Key %s is duplicated." +msgstr "La llave %s está duplicada." + +#: utils/sort/tuplesort.c:4300 +#, c-format +msgid "Duplicate keys exist." +msgstr "Existe una llave duplicada." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "no se pudo posicionar (seek) en el archivo temporal del tuplestore" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 +#: utils/sort/tuplestore.c:1548 +#, fuzzy, c-format +#| msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgid "could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "no se pudo leer el archivo temporal de hash-join: se leyeron sólo %zu de %zu bytes" + +#: utils/time/snapmgr.c:568 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "La transacción de origen ya no está en ejecución." + +#: utils/time/snapmgr.c:1147 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "no se puede exportar snapshots desde una subtransacción" + +#: utils/time/snapmgr.c:1306 utils/time/snapmgr.c:1311 +#: utils/time/snapmgr.c:1316 utils/time/snapmgr.c:1331 +#: utils/time/snapmgr.c:1336 utils/time/snapmgr.c:1341 +#: utils/time/snapmgr.c:1356 utils/time/snapmgr.c:1361 +#: utils/time/snapmgr.c:1366 utils/time/snapmgr.c:1468 +#: utils/time/snapmgr.c:1484 utils/time/snapmgr.c:1509 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "datos no válidos en archivo de snapshot «%s»" + +#: utils/time/snapmgr.c:1403 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "SET TRANSACTION SNAPSHOT debe ser llamado antes de cualquier consulta" + +#: utils/time/snapmgr.c:1412 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "una transacción que importa un snapshot no debe tener nivel de aislación SERIALIZABLE o REPEATABLE READ" + +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1430 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "identificador de snapshot no válido: «%s»" + +#: utils/time/snapmgr.c:1522 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "una transacción serializable no puede importar un snapshot desde una transacción no serializable" + +#: utils/time/snapmgr.c:1526 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "una transacción serializable que no es de sólo lectura no puede importar un snapshot de una transacción de sólo lectura" + +#: utils/time/snapmgr.c:1541 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "no se puede importar un snapshot desde una base de datos diferente" + +#~ msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +#~ msgstr "Número de inserts de tuplas antes de ejecutar una limpieza de índice, como fracción de reltuples." + +#~ msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +#~ msgstr "Para arrays RAID, esto debería ser aproximadamente la cantidad de discos en el array." + +#~ msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +#~ msgstr "Emitir una advertencia en constructos que cambiaron significado desde PostgreSQL 9.4." + +#~ msgid "Version and Platform Compatibility" +#~ msgstr "Compatibilidad de Versión y Plataforma" + +#~ msgid "Client Connection Defaults" +#~ msgstr "Valores por Omisión de Conexiones" + +#~ msgid "Statistics" +#~ msgstr "Estadísticas" + +#~ msgid "Process Title" +#~ msgstr "Título de Proceso" + +#~ msgid "Reporting and Logging" +#~ msgstr "Reporte y Registro" + +#~ msgid "Query Tuning" +#~ msgstr "Afinamiento de Consultas" + +#~ msgid "Replication" +#~ msgstr "Replicación" + +#~ msgid "Write-Ahead Log" +#~ msgstr "Write-Ahead Log" + +#~ msgid "Resource Usage" +#~ msgstr "Uso de Recursos" + +#~ msgid "connection authorized: user=%s database=%s" +#~ msgstr "conexión autorizada: usuario=%s database=%s" + +#~ msgid "connection authorized: user=%s database=%s application_name=%s" +#~ msgstr "conexión autorizada: usuario=%s base de datos=%s application_name=%s" + +#~ msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "conexión autorizada: usuario=%s base de datos=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s" + +#~ msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "conexión autorizada: usuario=%s base_de_datos=%s application_name=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s)" + +#~ msgid "replication connection authorized: user=%s application_name=%s" +#~ msgstr "conexión de replicación autorizada: usuario=%s application_name=%s" + +#~ msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "conexión de replicación autorizada: usuario=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s)" + +#~ msgid "on" +#~ msgstr "activado" + +#~ msgid "off" +#~ msgstr "desactivado" + +#~ msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "conexión de replicación autorizada: usuario=%s application_name=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s)" + +#~ msgid "loaded library \"%s\"" +#~ msgstr "biblioteca «%s» cargada" + +#~ msgid "You need to rebuild PostgreSQL using --with-libxml." +#~ msgstr "Necesita reconstruir PostgreSQL usando --with-libxml." + +#~ msgid "wrong data type: %u, expected %u" +#~ msgstr "tipo de dato erróneo: %u, se esperaba %u" + +#~ msgid "invalid concatenation of jsonb objects" +#~ msgstr "concatenación no válida de objetos jsonb" + +#~ msgid "wrong element type" +#~ msgstr "el tipo de elemento es erróneo" + +#~ msgid "logical replication launcher shutting down" +#~ msgstr "lanzador de replicación lógica apagándose" + +#~ msgid "bind %s to %s" +#~ msgstr "bind %s a %s" + +#~ msgid "parse %s: %s" +#~ msgstr "parse %s: %s" + +#~ msgid "unexpected EOF on client connection" +#~ msgstr "se encontró fin de archivo inesperado en la conexión del cliente" + +#~ msgid "could not fsync file \"%s\" but retrying: %m" +#~ msgstr "no se pudo sincronizar (fsync) archivo «%s» pero reintentando: %m" + +#~ msgid "could not forward fsync request because request queue is full" +#~ msgstr "no se pudo enviar una petición fsync porque la cola de peticiones está llena" + +#~ msgid "sending cancel to blocking autovacuum PID %d" +#~ msgstr "enviando señal de cancelación a la tarea autovacuum bloqueante con PID %d" + +#~ msgid "Process %d waits for %s on %s." +#~ msgstr "El proceso %d espera %s en %s." + +#~ msgid "deferrable snapshot was unsafe; trying a new one" +#~ msgstr "la instantánea postergada era insegura; intentando con una nueva" + +#~ msgid "\"%s\" has now caught up with upstream server" +#~ msgstr "«%s» ha alcanzado al servidor de origen" + +#~ msgid "unexpected standby message type \"%c\", after receiving CopyDone" +#~ msgstr "mensaje de standby de tipo «%c» inesperado, después de recibir CopyDone" + +#~ msgid "standby \"%s\" now has synchronous standby priority %u" +#~ msgstr "el standby «%s» ahora tiene prioridad sincrónica %u" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +#~ msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque las publicaciones de la suscripción fueron cambiadas" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +#~ msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque el nombre del slot de replicación fue cambiado" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +#~ msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque la información de conexión fue cambiada" + +#~ msgid "could not fetch table info for table \"%s.%s\": %s" +#~ msgstr "no se pudo obtener información de la tabla «%s.%s»: %s" + +#~ msgid "only superusers can query or manipulate replication origins" +#~ msgstr "debe ser superusuario para consultar o manipular orígenes de replicación" + +#~ msgid "logical replication launcher started" +#~ msgstr "lanzador de replicación lógica iniciado" + +#~ msgid "starting logical replication worker for subscription \"%s\"" +#~ msgstr "iniciando el proceso ayudante de replicación lógica para la suscripción «%s»" + +#~ msgid "could not reread block %d of file \"%s\": %m" +#~ msgstr "no se pudo leer el bloque %d del archivo «%s»: %m" + +#~ msgid "could not fseek in file \"%s\": %m" +#~ msgstr "no se pudo posicionar (fseek) el archivo «%s»: %m" + +#~ msgid "could not read from file \"%s\"" +#~ msgstr "no se pudo leer del archivo «%s»" + +#~ msgid "logger shutting down" +#~ msgstr "proceso logger apagándose" + +#~ msgid "starting background worker process \"%s\"" +#~ msgstr "iniciando el proceso ayudante «%s»" + +#~ msgid "could not fork archiver: %m" +#~ msgstr "no se pudo lanzar el proceso archivador: %m" + +#~ msgid "compacted fsync request queue from %d entries to %d entries" +#~ msgstr "la cola de peticiones de fsync fue compactada de %d a %d elementos" + +#~ msgid "unregistering background worker \"%s\"" +#~ msgstr "des-registrando el proceso ayudante «%s»" + +#~ msgid "registering background worker \"%s\"" +#~ msgstr "registrando el proceso ayudante «%s»" + +#~ msgid "autovacuum: processing database \"%s\"" +#~ msgstr "autovacuum: procesando la base de datos «%s»" + +#~ msgid "autovacuum launcher shutting down" +#~ msgstr "lanzador de autovacuum apagándose" + +#~ msgid "autovacuum launcher started" +#~ msgstr "lanzador de autovacuum iniciado" + +#~ msgid "disabling huge pages" +#~ msgstr "desactivando «huge pages»" + +#~ msgid "could not enable Lock Pages in Memory user right" +#~ msgstr "no se pudo activar el privilegio «Bloquear páginas en la memoria»" + +#~ msgid "could not enable Lock Pages in Memory user right: error code %lu" +#~ msgstr "no se pudo activar el privilegio «Bloquear páginas en la memoria»: código de error %lu" + +#~ msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +#~ msgstr "el ordenamiento (collation) del valor de borde de partición para la columna «%s» no coincide con el ordenamiento de la llave de particionamiento «%s»" + +#~ msgid "could not determine which collation to use for partition bound expression" +#~ msgstr "no se pudo determinar qué ordenamiento (collation) usar para la expresión de borde de particionamiento" + +#~ msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +#~ msgstr "%s creará una secuencia implícita «%s» para la columna serial «%s.%s»" + +#~ msgid "array assignment requires type %s but expression is of type %s" +#~ msgstr "la asignación de array debe tener tipo %s pero la expresión es de tipo %s" + +#~ msgid "operator precedence change: %s is now lower precedence than %s" +#~ msgstr "cambio de precedencia de operadores: %s es ahora de menor precedencia que %s" + +#~ msgid "arguments declared \"anycompatiblerange\" are not all alike" +#~ msgstr "los argumentos declarados «anycompatiblerange» no son todos parecidos" + +#~ msgid "arguments declared \"anyrange\" are not all alike" +#~ msgstr "los argumentos declarados «anyrange» no son de tipos compatibles" + +#~ msgid "arguments declared \"anyelement\" are not all alike" +#~ msgstr "los argumentos declarados «anyelement» no son de tipos compatibles" + +#~ msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +#~ msgstr " -o OPCIONES pasar «OPCIONES» a cada proceso servidor (obsoleto)\n" + +#~ msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +#~ msgstr "¿Hay otro postmaster corriendo en el puerto %d? Si no, elimine el socket «%s» y reintente." + +#~ msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +#~ msgstr "setsockopt(SO_REUSEADDR) falló para la dirección %s «%s»: %m" + +#~ msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +#~ msgstr "El cifrado GSSAPI sólo soporta autentificación gss, trust o reject" + +#~ msgid "authentication file line too long" +#~ msgstr "línea en el archivo de autentificación demasiado larga" + +#~ msgid "SSL connection from \"%s\"" +#~ msgstr "conexión SSL desde «%s»" + +#~ msgid "SSPI is not supported in protocol version 2" +#~ msgstr "SSPI no está soportado por el protocolo versión 2" + +#~ msgid "GSSAPI is not supported in protocol version 2" +#~ msgstr "GSSAPI no está soportado por el protocolo versión 2" + +#~ msgid "SASL authentication is not supported in protocol version 2" +#~ msgstr "autentificación SASL no está soportada en el protocolo versión 2" + +#~ msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +#~ msgstr "no hay una línea en pg_hba.conf para «%s», usuario «%s», base de datos «%s»" + +#~ msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +#~ msgstr "no hay una línea en pg_hba.conf para la conexión de replicación desde el servidor «%s», usuario «%s»" + +#~ msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +#~ msgstr "pg_hba.conf rechaza la conexión para el servidor «%s», usuario «%s», base de datos «%s»" + +#~ msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +#~ msgstr "pg_hba.conf rechaza la conexión de replicación para el servidor «%s», usuario «%s»" + +#~ msgid "SSL off" +#~ msgstr "SSL inactivo" + +#~ msgid "GSSAPI encryption can only be used with gss, trust, or reject authentication methods" +#~ msgstr "el cifrado GSSAPI sólo puede ser usado con los métodos gss, trust o reject" + +#~ msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +#~ msgstr "tiempo en «inline»: %.3fs, opt: %.3fs, emisión: %.3fs" + +#~ msgid "must be superuser to alter replication users" +#~ msgstr "debe ser superusuario para alterar usuarios de replicación" + +#~ msgid "moving row to another partition during a BEFORE trigger is not supported" +#~ msgstr "mover registros a otra partición durante un trigger BEFORE no está soportado" + +#~ msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +#~ msgstr "la restricción de partición actualizada para la partición por omisión \"%s\" está implícita en las restricciones existentes" + +#~ msgid "partition constraint for table \"%s\" is implied by existing constraints" +#~ msgstr "la restricción de partición para la tabla \"%s\" está implícita en las restricciones existentes" + +#~ msgid "validating foreign key constraint \"%s\"" +#~ msgstr "validando restricción de llave foránea «%s»" + +#~ msgid "verifying table \"%s\"" +#~ msgstr "verificando tabla «%s»" + +#~ msgid "rewriting table \"%s\"" +#~ msgstr "reescribiendo tabla «%s»" + +#~ msgid "The error was: %s" +#~ msgstr "El error fue: %s" + +#~ msgid "table \"%s.%s\" removed from subscription \"%s\"" +#~ msgstr "tabla «%s.%s» eliminada de suscripción «%s»" + +#~ msgid "table \"%s.%s\" added to subscription \"%s\"" +#~ msgstr "tabla «%s.%s» agregada a suscripción «%s»" + +#~ msgid "at least one of leftarg or rightarg must be specified" +#~ msgstr "debe especificar al menos uno de los argumentos izquierdo o derecho" + +#~ msgid "REINDEX is not yet implemented for partitioned indexes" +#~ msgstr "REINDEX no está implementado aún para tablas particionadas" + +#~ msgid "cannot reindex invalid index on TOAST table concurrently" +#~ msgstr "no se puede reindexar el índice no válido en una tabla TOAST concurrentemente" + +#~ msgid "%s %s will create implicit index \"%s\" for table \"%s\"" +#~ msgstr "%s %s creará el índice implícito «%s» para la tabla «%s»" + +#~ msgid "insufficient columns in %s constraint definition" +#~ msgstr "columnas insuficientes en definición de restricción %s" + +#~ msgid "INOUT arguments are permitted." +#~ msgstr "Argumentos INOUT están permitidos." + +#~ msgid "procedures cannot have OUT arguments" +#~ msgstr "los procedimientos no pueden tener argumentos OUT" + +#~ msgid "connection lost during COPY to stdout" +#~ msgstr "se perdió la conexión durante COPY a la salida estándar" + +#~ msgid "COPY BINARY is not supported to stdout or from stdin" +#~ msgstr "COPY BINARY no está soportado a la salida estándar o desde la entrada estándar" + +#~ msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" +#~ msgstr "analyze automático de la tabla «%s.%s.%s»: uso del sistema: %s" + +#~ msgid "must be superuser to drop access methods" +#~ msgstr "debe ser superusuario para eliminar métodos de acceso" + +#~ msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +#~ msgstr "REINDEX de tablas particionadas no está implementado aún, omitiendo «%s»" + +#~ msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +#~ msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +#~ msgstr[0] "construyendo índice «%s» en la tabla «%s» solicitando %d ayudante paralelo" +#~ msgstr[1] "construyendo índice «%s» en la tabla «%s» solicitando %d ayudantes paralelos" + +#~ msgid "building index \"%s\" on table \"%s\" serially" +#~ msgstr "construyendo índice «%s» en la tabla «%s» en forma serial" + +#~ msgid "drop auto-cascades to %s" +#~ msgstr "eliminando automáticamente %s" + +#~ msgid "backup timeline %u in file \"%s\"" +#~ msgstr "línea de tiempo %u en archivo «%s»" + +#~ msgid "backup label %s in file \"%s\"" +#~ msgstr "etiqueta de respaldo %s en archivo «%s»" + +#~ msgid "backup time %s in file \"%s\"" +#~ msgstr "tiempo de respaldo %s en archivo «%s»" + +#~ msgid "skipping restartpoint, already performed at %X/%X" +#~ msgstr "omitiendo el restartpoint, ya fue llevado a cabo en %X/%X" + +#~ msgid "skipping restartpoint, recovery has already ended" +#~ msgstr "omitiendo el restartpoint, la recuperación ya ha terminado" + +#~ msgid "checkpoint skipped because system is idle" +#~ msgstr "omitiendo checkpoint porque el sistema está inactivo" + +#~ msgid "initializing for hot standby" +#~ msgstr "inicializando para hot standby" + +#~ msgid "checkpoint record is at %X/%X" +#~ msgstr "el registro del punto de control está en %X/%X" + +#~ msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +#~ msgstr "Defina wal_level a «replica» en el maestro, o bien desactive hot_standby en este servidor." + +#~ msgid "removing write-ahead log file \"%s\"" +#~ msgstr "eliminando archivo de WAL «%s»" + +#~ msgid "recycled write-ahead log file \"%s\"" +#~ msgstr "reciclado archivo de WAL «%s»" + +#~ msgid "updated min recovery point to %X/%X on timeline %u" +#~ msgstr "el punto mínimo de recuperación fue actualizado a %X/%X en el timeline %u" + +#~ msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +#~ msgstr "no se puede hacer PREPARE de una transacción que ha manipulado procesos ayudantes de replicación lógica" + +#~ msgid "transaction ID wrap limit is %u, limited by database with OID %u" +#~ msgstr "el límite para el reciclaje de ID de transacciones es %u, limitado por base de datos con OID %u" + +#~ msgid "removing file \"%s\"" +#~ msgstr "eliminando el archivo «%s»" + +#~ msgid "MultiXact member stop limit is now %u based on MultiXact %u" +#~ msgstr "el límite de detención de miembros de multixact es ahora %u basado en el multixact %u" + +#~ msgid "oldest MultiXactId member is at offset %u" +#~ msgstr "el miembro de multixact más antiguo está en la posición %u" + +#~ msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +#~ msgstr "el límite para el reciclaje de MultiXactId es %u, limitado por base de datos con OID %u" + +#~ msgid "%u page is entirely empty.\n" +#~ msgid_plural "%u pages are entirely empty.\n" +#~ msgstr[0] "%u página está completamente vacía.\n" +#~ msgstr[1] "%u páginas están completamente vacías.\n" + +#~ msgid "There were %.0f unused item identifiers.\n" +#~ msgstr "Hubo %.0f identificadores de ítem sin usar.\n" + +#~ msgid "\"%s\": removed %.0f row versions in %u pages" +#~ msgstr "«%s»: se eliminaron %.0f versiones de filas en %u páginas" + +#~ msgid "password too long" +#~ msgstr "la contraseña es demasiado larga" + +#~ msgid "pclose failed: %m" +#~ msgstr "pclose falló: %m" diff --git a/src/backend/po/fr.po b/src/backend/po/fr.po new file mode 100644 index 000000000000..0d953bc4571c --- /dev/null +++ b/src/backend/po/fr.po @@ -0,0 +1,31833 @@ +# translation of postgres.po to fr_fr +# french message translation file for postgres +# +# Use these quotes: « %s » +# Guillaume Lelarge , 2003-2009. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-19 16:10+0000\n" +"PO-Revision-Date: 2021-06-21 12:29+0200\n" +"Last-Translator: Christophe Courtois \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.4.3\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 ../common/config_info.c:150 ../common/config_info.c:158 ../common/config_info.c:166 ../common/config_info.c:174 ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "non enregistré" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 commands/copyfrom.c:1516 commands/extension.c:3456 utils/adt/genfile.c:128 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 access/transam/timeline.c:143 access/transam/timeline.c:362 access/transam/twophase.c:1271 access/transam/xlog.c:3545 access/transam/xlog.c:4770 access/transam/xlog.c:11336 access/transam/xlog.c:11349 access/transam/xlog.c:11802 access/transam/xlog.c:11882 access/transam/xlog.c:11919 access/transam/xlog.c:11979 access/transam/xlogfuncs.c:703 access/transam/xlogfuncs.c:722 commands/extension.c:3466 libpq/hba.c:534 replication/basebackup.c:2020 replication/logical/origin.c:729 replication/logical/origin.c:765 replication/logical/reorderbuffer.c:4905 replication/logical/snapbuild.c:1733 +#: replication/logical/snapbuild.c:1775 replication/logical/snapbuild.c:1802 replication/slot.c:1700 replication/slot.c:1741 replication/walsender.c:544 storage/file/buffile.c:445 storage/file/copydir.c:195 utils/adt/genfile.c:202 utils/adt/misc.c:859 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "n'a pas pu lire le fichier « %s » : %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 access/transam/xlog.c:3550 access/transam/xlog.c:4775 replication/basebackup.c:2024 replication/logical/origin.c:734 replication/logical/origin.c:773 replication/logical/snapbuild.c:1738 replication/logical/snapbuild.c:1780 replication/logical/snapbuild.c:1807 replication/slot.c:1704 replication/slot.c:1745 replication/walsender.c:549 utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %zu" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 access/heap/rewriteheap.c:1185 access/heap/rewriteheap.c:1288 access/transam/timeline.c:392 access/transam/timeline.c:438 access/transam/timeline.c:516 access/transam/twophase.c:1283 access/transam/twophase.c:1680 access/transam/xlog.c:3417 access/transam/xlog.c:3585 access/transam/xlog.c:3590 access/transam/xlog.c:3918 access/transam/xlog.c:4740 access/transam/xlog.c:5665 access/transam/xlogfuncs.c:728 commands/copyfrom.c:1576 commands/copyto.c:328 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:533 replication/logical/origin.c:667 +#: replication/logical/origin.c:806 replication/logical/reorderbuffer.c:4963 replication/logical/snapbuild.c:1642 replication/logical/snapbuild.c:1815 replication/slot.c:1591 replication/slot.c:1752 replication/walsender.c:559 storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:738 storage/file/fd.c:3534 storage/file/fd.c:3637 utils/cache/relmapper.c:753 utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "n'a pas pu fermer le fichier « %s » : %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "incohérence dans l'ordre des octets" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"ATTENTION : possible incohérence dans l'ordre des octets\n" +"L'ordre des octets utilisé pour enregistrer le fichier pg_control peut ne\n" +"pas correspondre à celui utilisé par ce programme. Dans ce cas, les\n" +"résultats ci-dessous sont incorrects, et l'installation de PostgreSQL\n" +"est incompatible avec ce répertoire des données." + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 ../common/file_utils.c:232 ../common/file_utils.c:291 ../common/file_utils.c:365 access/heap/rewriteheap.c:1271 access/transam/timeline.c:111 access/transam/timeline.c:251 access/transam/timeline.c:348 access/transam/twophase.c:1227 access/transam/xlog.c:3303 access/transam/xlog.c:3459 access/transam/xlog.c:3500 access/transam/xlog.c:3698 access/transam/xlog.c:3783 access/transam/xlog.c:3886 access/transam/xlog.c:4760 access/transam/xlogutils.c:803 postmaster/syslogger.c:1488 replication/basebackup.c:616 replication/basebackup.c:1610 replication/logical/origin.c:719 replication/logical/reorderbuffer.c:3570 +#: replication/logical/reorderbuffer.c:4119 replication/logical/reorderbuffer.c:4885 replication/logical/snapbuild.c:1597 replication/logical/snapbuild.c:1704 replication/slot.c:1672 replication/walsender.c:517 replication/walsender.c:2526 storage/file/copydir.c:161 storage/file/fd.c:713 storage/file/fd.c:3521 storage/file/fd.c:3608 storage/smgr/md.c:502 utils/cache/relmapper.c:724 utils/cache/relmapper.c:836 utils/error/elog.c:1938 utils/init/miscinit.c:1346 utils/init/miscinit.c:1480 utils/init/miscinit.c:1557 utils/misc/guc.c:8604 utils/misc/guc.c:8636 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier « %s » : %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 access/transam/twophase.c:1653 access/transam/twophase.c:1662 access/transam/xlog.c:11093 access/transam/xlog.c:11131 access/transam/xlog.c:11544 access/transam/xlogfuncs.c:782 postmaster/postmaster.c:5659 postmaster/syslogger.c:1499 postmaster/syslogger.c:1512 utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "impossible d'écrire le fichier « %s » : %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 ../common/file_utils.c:303 ../common/file_utils.c:373 access/heap/rewriteheap.c:967 access/heap/rewriteheap.c:1179 access/heap/rewriteheap.c:1282 access/transam/timeline.c:432 access/transam/timeline.c:510 access/transam/twophase.c:1674 access/transam/xlog.c:3410 access/transam/xlog.c:3579 access/transam/xlog.c:4733 access/transam/xlog.c:10584 access/transam/xlog.c:10625 replication/logical/snapbuild.c:1635 replication/slot.c:1577 replication/slot.c:1682 storage/file/fd.c:730 storage/file/fd.c:3629 storage/smgr/md.c:950 storage/smgr/md.c:991 storage/sync/sync.c:417 utils/cache/relmapper.c:885 +#: utils/misc/guc.c:8391 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m" + +#: ../common/cryptohash_openssl.c:104 ../common/exec.c:522 ../common/exec.c:567 ../common/exec.c:659 ../common/hmac_openssl.c:103 ../common/psprintf.c:143 ../common/stringinfo.c:305 ../port/path.c:630 ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1341 access/transam/xlog.c:6631 lib/dshash.c:246 libpq/auth.c:1482 libpq/auth.c:1550 libpq/auth.c:2108 libpq/be-secure-gssapi.c:520 postmaster/bgworker.c:349 postmaster/bgworker.c:948 postmaster/postmaster.c:2516 postmaster/postmaster.c:4175 postmaster/postmaster.c:4845 postmaster/postmaster.c:5584 postmaster/postmaster.c:5948 replication/libpqwalreceiver/libpqwalreceiver.c:283 replication/logical/logical.c:205 +#: replication/walsender.c:591 storage/buffer/localbuf.c:442 storage/file/fd.c:882 storage/file/fd.c:1352 storage/file/fd.c:1513 storage/file/fd.c:2321 storage/ipc/procarray.c:1411 storage/ipc/procarray.c:2205 storage/ipc/procarray.c:2212 storage/ipc/procarray.c:2701 storage/ipc/procarray.c:3325 utils/adt/cryptohashfuncs.c:46 utils/adt/cryptohashfuncs.c:66 utils/adt/formatting.c:1699 utils/adt/formatting.c:1823 utils/adt/formatting.c:1948 utils/adt/pg_locale.c:450 utils/adt/pg_locale.c:614 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 utils/hash/dynahash.c:513 utils/hash/dynahash.c:613 utils/hash/dynahash.c:1116 utils/mb/mbutils.c:401 utils/mb/mbutils.c:429 utils/mb/mbutils.c:814 +#: utils/mb/mbutils.c:841 utils/misc/guc.c:5035 utils/misc/guc.c:5051 utils/misc/guc.c:5064 utils/misc/guc.c:8369 utils/misc/tzparser.c:467 utils/mmgr/aset.c:476 utils/mmgr/dsa.c:701 utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:234 utils/mmgr/mcxt.c:888 utils/mmgr/mcxt.c:924 utils/mmgr/mcxt.c:962 utils/mmgr/mcxt.c:1000 utils/mmgr/mcxt.c:1082 utils/mmgr/mcxt.c:1113 utils/mmgr/mcxt.c:1149 utils/mmgr/mcxt.c:1201 utils/mmgr/mcxt.c:1236 utils/mmgr/mcxt.c:1271 utils/mmgr/slab.c:236 +#, c-format +msgid "out of memory" +msgstr "mémoire épuisée" + +#: ../common/exec.c:136 ../common/exec.c:253 ../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" + +#: ../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "binaire « %s » invalide" + +#: ../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "n'a pas pu lire le binaire « %s »" + +#: ../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "n'a pas pu trouver un « %s » à exécuter" + +#: ../common/exec.c:269 ../common/exec.c:308 utils/init/miscinit.c:425 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" + +#: ../common/exec.c:286 access/transam/xlog.c:10967 replication/basebackup.c:1428 utils/adt/misc.c:340 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" + +#: ../common/exec.c:409 libpq/pqcomm.c:746 storage/ipc/latch.c:1064 storage/ipc/latch.c:1233 storage/ipc/latch.c:1462 storage/ipc/latch.c:1614 storage/ipc/latch.c:1730 +#, c-format +msgid "%s() failed: %m" +msgstr "échec de %s() : %m" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" + +#: ../common/file_utils.c:87 ../common/file_utils.c:451 ../common/file_utils.c:455 access/transam/twophase.c:1239 access/transam/xlog.c:11069 access/transam/xlog.c:11107 access/transam/xlog.c:11324 access/transam/xlogarchive.c:110 access/transam/xlogarchive.c:227 commands/copyfrom.c:1526 commands/copyto.c:728 commands/extension.c:3445 commands/tablespace.c:807 commands/tablespace.c:898 guc-file.l:1060 replication/basebackup.c:439 replication/basebackup.c:622 replication/basebackup.c:698 replication/logical/snapbuild.c:1514 storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1863 storage/file/fd.c:1949 storage/file/fd.c:3149 storage/file/fd.c:3353 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 utils/adt/genfile.c:418 utils/adt/genfile.c:644 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "n'a pas pu tester le fichier « %s » : %m" + +#: ../common/file_utils.c:166 ../common/pgfnames.c:48 commands/tablespace.c:730 commands/tablespace.c:740 postmaster/postmaster.c:1515 storage/file/fd.c:2724 storage/file/reinit.c:122 utils/adt/misc.c:262 utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" + +#: ../common/file_utils.c:200 ../common/pgfnames.c:69 storage/file/fd.c:2736 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "n'a pas pu lire le répertoire « %s » : %m" + +#: ../common/file_utils.c:383 access/transam/xlogarchive.c:412 postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1654 replication/slot.c:643 replication/slot.c:1463 replication/slot.c:1605 storage/file/fd.c:748 storage/file/fd.c:846 utils/time/snapmgr.c:1265 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "n'a pas pu renommer le fichier « %s » en « %s » : %m" + +#: ../common/hex.c:54 +#, c-format +msgid "invalid hexadecimal digit" +msgstr "chiffre hexadécimal invalide" + +#: ../common/hex.c:59 +#, c-format +msgid "invalid hexadecimal digit: \"%.*s\"" +msgstr "chiffre hexadécimal invalide : « %.*s »" + +#: ../common/hex.c:90 +#, c-format +msgid "overflow of destination buffer in hex encoding" +msgstr "Calcule les identifiants de requête" + +#: ../common/hex.c:136 ../common/hex.c:141 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "donnée hexadécimale invalide : nombre pair de chiffres" + +#: ../common/hex.c:152 +#, c-format +msgid "overflow of destination buffer in hex decoding" +msgstr "" + +#: ../common/jsonapi.c:1066 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "La séquence d'échappement « \\%s » est invalide." + +#: ../common/jsonapi.c:1069 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Le caractère de valeur 0x%02x doit être échappé." + +#: ../common/jsonapi.c:1072 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Attendait une fin de l'entrée, mais a trouvé « %s »." + +#: ../common/jsonapi.c:1075 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Élément de tableau ou « ] » attendu, mais trouvé « %s »." + +#: ../common/jsonapi.c:1078 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "« , » ou « ] » attendu, mais trouvé « %s »." + +#: ../common/jsonapi.c:1081 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "« : » attendu, mais trouvé « %s »." + +#: ../common/jsonapi.c:1084 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Valeur JSON attendue, mais « %s » trouvé." + +#: ../common/jsonapi.c:1087 +msgid "The input string ended unexpectedly." +msgstr "La chaîne en entrée se ferme de manière inattendue." + +#: ../common/jsonapi.c:1089 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Chaîne ou « } » attendu, mais « %s » trouvé" + +#: ../common/jsonapi.c:1092 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "« , » ou « } » attendu, mais trouvé « %s »." + +#: ../common/jsonapi.c:1095 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Chaîne attendue, mais « %s » trouvé." + +#: ../common/jsonapi.c:1098 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Le jeton « %s » n'est pas valide." + +#: ../common/jsonapi.c:1101 jsonpath_scan.l:499 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 ne peut pas être converti en texte." + +#: ../common/jsonapi.c:1103 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "« \\u » doit être suivi par quatre chiffres hexadécimaux." + +#: ../common/jsonapi.c:1106 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "les valeurs d'échappement Unicode ne peuvent pas être utilisées pour des valeurs de point code au-dessus de 007F quand l'encodage n'est pas UTF8." + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:520 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Une substitution unicode haute ne doit pas suivre une substitution haute." + +#: ../common/jsonapi.c:1110 jsonpath_scan.l:531 jsonpath_scan.l:541 jsonpath_scan.l:583 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Une substitution unicode basse ne doit pas suivre une substitution haute." + +#: ../common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../common/logging.c:266 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "n'a pas pu fermer le répertoire « %s » : %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "nom du fork invalide" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Les noms de fork valides sont « main », « fsm », « vm » et « init »." + +#: ../common/restricted_token.c:64 libpq/auth.c:1512 libpq/auth.c:2544 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "n'a pas pu charger la bibliothèque « %s » : code d'erreur %lu" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "ne peut pas créer les jetons restreints sur cette plateforme : code d'erreur %lu" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "n'a pas pu ouvrir le jeton du processus : code d'erreur %lu" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "n'a pas pu allouer les SID : code d'erreur %lu" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "n'a pas pu créer le jeton restreint : code d'erreur %lu" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "n'a pas pu démarrer le processus pour la commande « %s » : code d'erreur %lu" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "n'a pas pu ré-exécuter le jeton restreint : code d'erreur %lu" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "n'a pas pu récupérer le code de statut du sous-processus : code d'erreur %lu" + +#: ../common/rmtree.c:79 replication/basebackup.c:1181 replication/basebackup.c:1357 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "" +"n'a pas pu récupérer les informations sur le fichier ou répertoire\n" +"« %s » : %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier ou répertoire « %s » : %m" + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "Ne peut pas agrandir le tampon de chaîne, qui contient %d octets, de %d octets." + +#: ../common/stringinfo.c:310 +#, c-format +msgid "" +"out of memory\n" +"\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "" +"plus de mémoire\n" +"\n" +"Ne peut pas agrandir le tampon de chaîne, qui contient %d octets, de %d octets.\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "n'a pas pu trouver l'identifiant réel %ld de l'utilisateur : %s" + +#: ../common/username.c:45 libpq/auth.c:2044 +msgid "user does not exist" +msgstr "l'utilisateur n'existe pas" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "échec de la recherche du nom d'utilisateur : code d'erreur %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "commande non exécutable" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "commande introuvable" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "le processus fils a quitté avec le code de sortie %d" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "le processus fils a été terminé par l'exception 0x%X" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "le processus fils a été terminé par le signal %d : %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "le processus fils a quitté avec un statut %d non reconnu" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "n'a pas pu déterminer l'encodage pour le codeset « %s »" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "n'a pas pu déterminer l'encodage pour la locale « %s » : le codeset vaut « %s »" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "n'a pas pu configurer la jonction pour « %s » : %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "n'a pas pu configurer la jonction pour « %s » : %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "n'a pas pu obtenir la jonction pour « %s » : %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "n'a pas pu obtenir la jonction pour « %s » : %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "n'a pas pu ouvrir le fichier « %s » : %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "violation du verrou" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "violation du partage" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "Continue à tenter pendant 30 secondes." + +#: ../port/open.c:129 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "" +"Vous pouvez avoir un antivirus, un outil de sauvegarde ou un logiciel\n" +"similaire interférant avec le système de bases de données." + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "n'a pas pu obtenir le répertoire de travail : %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "erreur %d du système d'exploitation" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "n'a pas pu obtenir le SID du groupe d'administrateurs : code d'erreur %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "" +"n'a pas pu obtenir le SID du groupe des utilisateurs avec pouvoir :\n" +"code d'erreur %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "n'a pas pu vérifier l'appartenance du jeton d'accès : code d'erreur %lu\n" + +#: access/brin/brin.c:214 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "requête de résumé d'intervalle BRIN pour la page « %s » de l'index « %u » n'a pas été enregistrée" + +#: access/brin/brin.c:1015 access/brin/brin.c:1092 access/gin/ginfast.c:1035 access/transam/xlog.c:10746 access/transam/xlog.c:11275 access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "restauration en cours" + +#: access/brin/brin.c:1016 access/brin/brin.c:1093 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Les fonctions de contrôle BRIN ne peuvent pas être exécutées pendant la restauration." + +#: access/brin/brin.c:1024 access/brin/brin.c:1101 +#, c-format +msgid "block number out of range: %s" +msgstr "numéro de bloc en dehors des limites : %s" + +#: access/brin/brin.c:1047 access/brin/brin.c:1124 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "« %s » n'est pas un index BRIN" + +#: access/brin/brin.c:1063 access/brin/brin.c:1140 +#, c-format +msgid "could not open parent table of index \"%s\"" +msgstr "n'a pas pu ouvrir la table parent de l'index « %s »" + +#: access/brin/brin_bloom.c:751 access/brin/brin_bloom.c:793 access/brin/brin_minmax_multi.c:2987 access/brin/brin_minmax_multi.c:3130 statistics/dependencies.c:651 statistics/dependencies.c:704 statistics/mcv.c:1483 statistics/mcv.c:1514 statistics/mvdistinct.c:343 statistics/mvdistinct.c:396 utils/adt/pseudotypes.c:43 utils/adt/pseudotypes.c:77 utils/adt/pseudotypes.c:252 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "ne peut pas accepter une valeur de type %s" + +#: access/brin/brin_minmax_multi.c:2146 access/brin/brin_minmax_multi.c:2153 access/brin/brin_minmax_multi.c:2160 utils/adt/timestamp.c:941 utils/adt/timestamp.c:1515 utils/adt/timestamp.c:1982 utils/adt/timestamp.c:3059 utils/adt/timestamp.c:3064 utils/adt/timestamp.c:3069 utils/adt/timestamp.c:3119 utils/adt/timestamp.c:3126 utils/adt/timestamp.c:3133 utils/adt/timestamp.c:3153 utils/adt/timestamp.c:3160 utils/adt/timestamp.c:3167 utils/adt/timestamp.c:3197 utils/adt/timestamp.c:3205 utils/adt/timestamp.c:3249 utils/adt/timestamp.c:3676 utils/adt/timestamp.c:3801 utils/adt/timestamp.c:4349 +#, c-format +msgid "interval out of range" +msgstr "intervalle en dehors des limites" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 access/gist/gist.c:1441 access/spgist/spgdoinsert.c:2000 access/spgist/spgdoinsert.c:2275 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "la taille de la ligne index, %zu, dépasse le maximum, %zu, pour l'index « %s »" + +#: access/brin/brin_revmap.c:393 access/brin/brin_revmap.c:399 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "index BRIN corrompu : carte d'intervalle incohérente" + +#: access/brin/brin_revmap.c:602 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "type de page 0x%04X dans l'index BRIN « %s », bloc %u" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 access/gist/gistvalidate.c:153 access/hash/hashvalidate.c:139 access/nbtree/nbtvalidate.c:120 access/spgist/spgvalidate.c:189 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s contient la fonction %s avec\n" +"le numéro de support invalide %d" + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 access/gist/gistvalidate.c:165 access/hash/hashvalidate.c:118 access/nbtree/nbtvalidate.c:132 access/spgist/spgvalidate.c:201 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s contient la fonction %s avec une mauvaise\n" +"signature pour le numéro de support %d" + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 access/gist/gistvalidate.c:185 access/hash/hashvalidate.c:160 access/nbtree/nbtvalidate.c:152 access/spgist/spgvalidate.c:221 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s contient l'opérateur %s avec le numéro\n" +"de stratégie invalide %d" + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 access/hash/hashvalidate.c:173 access/nbtree/nbtvalidate.c:165 access/spgist/spgvalidate.c:237 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s contient la spécification ORDER BY\n" +"invalide pour l'opérateur %s" + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 access/gist/gistvalidate.c:233 access/hash/hashvalidate.c:186 access/nbtree/nbtvalidate.c:178 access/spgist/spgvalidate.c:253 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "la famille d'opérateur « %s » de la méthode d'accès %s contient l'opérateur %s avec une mauvaise signature" + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:226 access/nbtree/nbtvalidate.c:236 access/spgist/spgvalidate.c:280 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s nécessite des opérateurs supplémentaires\n" +"pour les types %s et %s" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s nécessite des fonctions de support\n" +"manquantes pour les types %s et %s" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:240 access/nbtree/nbtvalidate.c:260 access/spgist/spgvalidate.c:315 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "il manque un ou des opérateurs à la classe d'opérateur « %s » de la méthode d'accès %s" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 access/gist/gistvalidate.c:274 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "la classe d'opérateur « %s » de la méthode d'accès %s nécessite la fonction de support manquante %d" + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "Le type %s renvoyé ne correspond pas au type %s attendu dans la colonne %d." + +#: access/common/attmap.c:150 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "" +"Le nombre de colonnes renvoyées (%d) ne correspond pas au nombre de colonnes\n" +"attendues (%d)." + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "n'a pas pu convertir le type de ligne" + +#: access/common/attmap.c:230 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "L'attribut « %s » du type %s ne correspond pas à l'attribut correspondant de type %s." + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "L'attribut « %s » du type %s n'existe pas dans le type %s." + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "le nombre de colonnes (%d) dépasse la limite (%d)" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "le nombre de colonnes indexées (%d) dépasse la limite (%d)" + +#: access/common/indextuple.c:190 access/spgist/spgutils.c:947 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "la ligne index requiert %zu octets, la taille maximum est %zu" + +#: access/common/printtup.c:292 tcop/fastpath.c:106 tcop/fastpath.c:453 tcop/postgres.c:1900 +#, c-format +msgid "unsupported format code: %d" +msgstr "code de format non supporté : %d" + +#: access/common/reloptions.c:512 access/common/reloptions.c:523 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Les valeurs valides sont entre « on », « off » et « auto »." + +#: access/common/reloptions.c:534 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "Les valeurs valides sont entre « local » et « cascaded »." + +#: access/common/reloptions.c:682 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "limite dépassée des types de paramètres de la relation définie par l'utilisateur" + +#: access/common/reloptions.c:1225 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESET ne doit pas inclure de valeurs pour les paramètres" + +#: access/common/reloptions.c:1257 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "espace de nom du paramètre « %s » non reconnu" + +#: access/common/reloptions.c:1294 utils/misc/guc.c:12514 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "les tables avec WITH OIDS ne sont pas supportées" + +#: access/common/reloptions.c:1464 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "paramètre « %s » non reconnu" + +#: access/common/reloptions.c:1576 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "le paramètre « %s » est spécifié plus d'une fois" + +#: access/common/reloptions.c:1592 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "valeur invalide pour l'option booléenne « %s » : %s" + +#: access/common/reloptions.c:1604 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "valeur invalide pour l'option de type integer « %s » : %s" + +#: access/common/reloptions.c:1610 access/common/reloptions.c:1630 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "valeur %s en dehors des limites pour l'option « %s »" + +#: access/common/reloptions.c:1612 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Les valeurs valides sont entre « %d » et « %d »." + +#: access/common/reloptions.c:1624 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "valeur invalide pour l'option de type float « %s » : %s" + +#: access/common/reloptions.c:1632 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Les valeurs valides sont entre « %f » et « %f »." + +#: access/common/reloptions.c:1654 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "valeur invalide pour l'option enum « %s » : %s" + +#: access/common/toast_compression.c:32 +#, c-format +msgid "unsupported LZ4 compression method" +msgstr "méthode compression LZ4 non supportée" + +#: access/common/toast_compression.c:33 +#, c-format +msgid "This functionality requires the server to be built with lz4 support." +msgstr "Cette fonctionnalité nécessite que le serveur dispose du support de lz4." + +#: access/common/toast_compression.c:34 utils/adt/pg_locale.c:1589 utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using %s." +msgstr "Vous devez recompiler PostgreSQL en utilisant %s." + +#: access/common/tupdesc.c:825 parser/parse_clause.c:771 parser/parse_relation.c:1838 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "la colonne « %s » ne peut pas être déclarée SETOF" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "la posting list est trop longue" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "Réduisez le maintenance_work_mem." + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "la pending list GIN ne peut pas être nettoyée lors de la restauration." + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "« %s » n'est pas un index GIN" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "ne peut pas accéder aux index temporaires d'autres sessions" + +#: access/gin/ginget.c:270 access/nbtree/nbtinsert.c:759 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "échec pour retrouver la ligne dans l'index « %s »" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "" +"les anciens index GIN ne supportent pas les parcours complets d'index et les\n" +"recherches de valeurs NULL" + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "Pour corriger ceci, faites un REINDEX INDEX « %s »." + +#: access/gin/ginutil.c:145 executor/execExpr.c:2166 utils/adt/arrayfuncs.c:3818 utils/adt/arrayfuncs.c:6452 utils/adt/rowtypes.c:957 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "n'a pas pu identifier une fonction de comparaison pour le type %s" + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 access/hash/hashvalidate.c:102 access/spgist/spgvalidate.c:102 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s contient la fonction de support\n" +"%s avec des types en entrée gauche et droite différents" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "la classe d'opérateur « %s » de la méthode d'accès %s nécessite la fonction de support manquante %d ou %d" + +#: access/gin/ginvalidate.c:333 access/gist/gistvalidate.c:350 access/spgist/spgvalidate.c:387 +#, c-format +msgid "support function number %d is invalid for access method %s" +msgstr "le numéro de fonction d'appui %d est invalide pour la méthode d'accès %s" + +#: access/gist/gist.c:758 access/gist/gistvacuum.c:420 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "l'index « %s » contient une ligne interne marquée comme invalide" + +#: access/gist/gist.c:760 access/gist/gistvacuum.c:422 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "" +"Ceci est dû à la division d'une page incomplète à la restauration suite à un\n" +"crash avant la mise à jour en 9.1." + +#: access/gist/gist.c:761 access/gist/gistutil.c:801 access/gist/gistutil.c:812 access/gist/gistvacuum.c:423 access/hash/hashutil.c:227 access/hash/hashutil.c:238 access/hash/hashutil.c:250 access/hash/hashutil.c:271 access/nbtree/nbtpage.c:810 access/nbtree/nbtpage.c:821 +#, c-format +msgid "Please REINDEX it." +msgstr "Merci d'exécuter REINDEX sur cet objet." + +#: access/gist/gist.c:1175 +#, c-format +msgid "fixing incomplete split in index \"%s\", block %u" +msgstr "" + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "la méthode picksplit pour la colonne %d de l'index « %s » a échoué" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "" +"L'index n'est pas optimal. Pour l'optimiser, contactez un développeur\n" +"ou essayez d'utiliser la colonne comme second dans la commande\n" +"CREATE INDEX." + +#: access/gist/gistutil.c:798 access/hash/hashutil.c:224 access/nbtree/nbtpage.c:807 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "l'index « %s » contient une page zéro inattendue au bloc %u" + +#: access/gist/gistutil.c:809 access/hash/hashutil.c:235 access/hash/hashutil.c:247 access/nbtree/nbtpage.c:818 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "l'index « %s » contient une page corrompue au bloc %u" + +#: access/gist/gistvalidate.c:203 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s contient une spécification ORDER BY\n" +"non supportée pour l'opérateur %s" + +#: access/gist/gistvalidate.c:214 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s contient la spécification opfamily ORDER BY\n" +"incorrecte pour l'opérateur %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour le hachage de chaîne" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:713 catalog/heap.c:719 commands/createas.c:206 commands/createas.c:503 commands/indexcmds.c:1869 commands/tablecmds.c:16794 commands/view.c:86 regex/regc_pg_locale.c:263 utils/adt/formatting.c:1666 utils/adt/formatting.c:1790 utils/adt/formatting.c:1915 utils/adt/like.c:194 utils/adt/like_support.c:1003 utils/adt/varchar.c:733 utils/adt/varchar.c:994 utils/adt/varchar.c:1054 utils/adt/varlena.c:1524 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Utilisez la clause COLLARE pour configurer explicitement le collationnement." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "la taille de la ligne index, %zu, dépasse le hachage maximum, %zu" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:2004 access/spgist/spgdoinsert.c:2279 access/spgist/spgutils.c:1008 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Les valeurs plus larges qu'une page de tampon ne peuvent pas être indexées." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "numéro de bloc de surcharge invalide %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "en dehors des pages surchargées dans l'index haché « %s »" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "les index hachés ne supportent pas les parcours complets d'index" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "l'index « %s » n'est pas un index haché" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "l'index « %s » a la mauvaise version de hachage" + +#: access/hash/hashvalidate.c:198 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s requiert la fonction de support\n" +"pour l'opérateur %s" + +#: access/hash/hashvalidate.c:256 access/nbtree/nbtvalidate.c:276 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "il manque un opérateur inter-type pour la famille d'opérateur « %s » de la méthode d'accès %s" + +#: access/heap/heapam.c:2260 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "ne peut pas insérer de lignes dans un processus parallèle" + +#: access/heap/heapam.c:2731 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "ne peut pas supprimer les lignes lors d'une opération parallèle" + +#: access/heap/heapam.c:2777 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "tentative de supprimer une ligne invisible" + +#: access/heap/heapam.c:3209 access/heap/heapam.c:6010 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "ne peut pas mettre à jour les lignes lors d'une opération parallèle" + +#: access/heap/heapam.c:3342 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "tentative de mettre à jour une ligne invisible" + +#: access/heap/heapam.c:4663 access/heap/heapam.c:4701 access/heap/heapam.c:4957 access/heap/heapam_handler.c:452 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "n'a pas pu obtenir un verrou sur la relation « %s »" + +#: access/heap/heapam_handler.c:401 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "la ligne à verrouiller était déjà déplacée dans une autre partition du fait d'une mise à jour concurrente" + +#: access/heap/hio.c:360 access/heap/rewriteheap.c:665 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "la ligne est trop grande : taille %zu, taille maximale %zu" + +#: access/heap/rewriteheap.c:927 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "n'a pas pu écrire le fichier « %s », a écrit %d de %d : %m" + +#: access/heap/rewriteheap.c:1020 access/heap/rewriteheap.c:1138 access/transam/timeline.c:329 access/transam/timeline.c:485 access/transam/xlog.c:3326 access/transam/xlog.c:3514 access/transam/xlog.c:4712 access/transam/xlog.c:11084 access/transam/xlog.c:11122 access/transam/xlog.c:11527 access/transam/xlogfuncs.c:776 postmaster/postmaster.c:4600 postmaster/postmaster.c:5646 replication/logical/origin.c:587 replication/slot.c:1524 storage/file/copydir.c:167 storage/smgr/md.c:218 utils/time/snapmgr.c:1244 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "n'a pas pu créer le fichier « %s » : %m" + +#: access/heap/rewriteheap.c:1148 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "n'a pas pu tronquer le fichier « %s » en %u : %m" + +#: access/heap/rewriteheap.c:1166 access/transam/timeline.c:384 access/transam/timeline.c:424 access/transam/timeline.c:502 access/transam/xlog.c:3398 access/transam/xlog.c:3570 access/transam/xlog.c:4724 postmaster/postmaster.c:4610 postmaster/postmaster.c:4620 replication/logical/origin.c:599 replication/logical/origin.c:641 replication/logical/origin.c:660 replication/logical/snapbuild.c:1611 replication/slot.c:1559 storage/file/buffile.c:506 storage/file/copydir.c:207 utils/init/miscinit.c:1421 utils/init/miscinit.c:1432 utils/init/miscinit.c:1440 utils/misc/guc.c:8352 utils/misc/guc.c:8383 utils/misc/guc.c:10292 utils/misc/guc.c:10306 utils/time/snapmgr.c:1249 +#: utils/time/snapmgr.c:1256 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "n'a pas pu écrire dans le fichier « %s » : %m" + +#: access/heap/rewriteheap.c:1256 access/transam/twophase.c:1613 access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:422 postmaster/postmaster.c:1096 postmaster/syslogger.c:1465 replication/logical/origin.c:575 replication/logical/reorderbuffer.c:4387 replication/logical/snapbuild.c:1556 replication/logical/snapbuild.c:1972 replication/slot.c:1656 storage/file/fd.c:788 storage/file/fd.c:3169 storage/file/fd.c:3231 storage/file/reinit.c:250 storage/ipc/dsm.c:315 storage/smgr/md.c:344 storage/smgr/md.c:394 storage/sync/sync.c:231 utils/time/snapmgr.c:1589 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier « %s » : %m" + +#: access/heap/vacuumlazy.c:772 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "VACUUM automatique agressif pour éviter un rebouclage des identifiants de transaction dans la table « %s.%s.%s » : %d parcours d'index\n" + +#: access/heap/vacuumlazy.c:774 +#, c-format +msgid "automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "VACUUM automatique pour éviter un rebouclage des identifiants de transaction dans la table « %s.%s.%s » : parcours d'index : %d\n" + +#: access/heap/vacuumlazy.c:779 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "VACUUM automatique agressif de la table « %s.%s.%s » : %d parcours d'index\n" + +#: access/heap/vacuumlazy.c:781 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "VACUUM automatique de la table « %s.%s.%s » : %d parcours d'index\n" + +#: access/heap/vacuumlazy.c:788 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "pages : %u supprimées, %u restants, %u ignorées à cause de verrous; %u ignorées car gelées\n" + +#: access/heap/vacuumlazy.c:794 +#, c-format +msgid "tuples: %lld removed, %lld remain, %lld are dead but not yet removable, oldest xmin: %u\n" +msgstr "lignes : %lld supprimées, %lld restantes, %lld sont mortes mais pas encore supprimables, plus ancien xmin : %u\n" + +#: access/heap/vacuumlazy.c:800 commands/analyze.c:794 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "utilisation du cache : %lld récupérés, %lld ratés, %lld modifiés\n" + +#: access/heap/vacuumlazy.c:810 +#, c-format +msgid " %u pages from table (%.2f%% of total) had %lld dead item identifiers removed\n" +msgstr "" + +#: access/heap/vacuumlazy.c:813 +msgid "index scan not needed:" +msgstr "parcours d'index non nécessaire :" + +#: access/heap/vacuumlazy.c:815 +msgid "index scan needed:" +msgstr "parcours d'index nécessaire :" + +#: access/heap/vacuumlazy.c:819 +#, c-format +msgid " %u pages from table (%.2f%% of total) have %lld dead item identifiers\n" +msgstr "" + +#: access/heap/vacuumlazy.c:822 +msgid "index scan bypassed:" +msgstr "" + +#: access/heap/vacuumlazy.c:824 +msgid "index scan bypassed by failsafe:" +msgstr "" + +#: access/heap/vacuumlazy.c:840 +#, c-format +msgid "index \"%s\": pages: %u in total, %u newly deleted, %u currently deleted, %u reusable\n" +msgstr "index \"%s\": blocs : %u au total, %u nouvellement supprimés, %u actuellement supprimés, %u réutilisables\n" + +#: access/heap/vacuumlazy.c:847 commands/analyze.c:798 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "vitesse moyenne de lecture : %.3f Mo/s, vitesse moyenne d'écriture : %.3f Mo/s\n" + +#: access/heap/vacuumlazy.c:851 commands/analyze.c:802 +msgid "I/O Timings:" +msgstr "Chronométrages I/O :" + +#: access/heap/vacuumlazy.c:853 commands/analyze.c:804 +#, c-format +msgid " read=%.3f" +msgstr " lu=%.3f" + +#: access/heap/vacuumlazy.c:856 commands/analyze.c:807 +#, c-format +msgid " write=%.3f" +msgstr " écrit=%.3f" + +#: access/heap/vacuumlazy.c:860 +#, c-format +msgid "system usage: %s\n" +msgstr "utilisation du système : %s\n" + +#: access/heap/vacuumlazy.c:862 +#, c-format +msgid "WAL usage: %lld records, %lld full page images, %llu bytes" +msgstr "utilisation des WAL : %lld enregistrements, %lld images complètes de blocs, %llu octets" + +#: access/heap/vacuumlazy.c:937 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "exécution d'un VACUUM agressif sur « %s.%s »" + +#: access/heap/vacuumlazy.c:942 commands/cluster.c:898 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "exécution du VACUUM sur « %s.%s »" + +#: access/heap/vacuumlazy.c:1652 +#, c-format +msgid "\"%s\": removed %lld dead item identifiers in %u pages" +msgstr "« %s »: %lld versions de ligne supprimées dans %u blocs" + +#: access/heap/vacuumlazy.c:1658 +#, c-format +msgid "%lld dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%lld versions de lignes mortes ne peuvent pas encore être supprimées, plus ancien xmin : %u\n" + +#: access/heap/vacuumlazy.c:1660 +#, c-format +msgid "%u page removed.\n" +msgid_plural "%u pages removed.\n" +msgstr[0] "%u bloc supprimé.\n" +msgstr[1] "%u blocs supprimés.\n" + +#: access/heap/vacuumlazy.c:1664 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Ignore %u page à cause des verrous de blocs, " +msgstr[1] "Ignore %u pages à cause des verrous de blocs, " + +#: access/heap/vacuumlazy.c:1668 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u page gelée.\n" +msgstr[1] "%u pages gelées.\n" + +#: access/heap/vacuumlazy.c:1672 commands/indexcmds.c:3986 commands/indexcmds.c:4005 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1675 +#, c-format +msgid "\"%s\": found %lld removable, %lld nonremovable row versions in %u out of %u pages" +msgstr "« %s » : trouvé %lld versions de ligne supprimables, %lld non supprimables, dans %u blocs sur %u" + +#: access/heap/vacuumlazy.c:2179 +#, c-format +msgid "\"%s\": index scan bypassed: %u pages from table (%.2f%% of total) have %lld dead item identifiers" +msgstr "" + +#: access/heap/vacuumlazy.c:2390 +#, c-format +msgid "\"%s\": removed %d dead item identifiers in %u pages" +msgstr "« %s »: %d versions de lignes mortes supprimées dans %u blocs" + +#: access/heap/vacuumlazy.c:2625 +#, c-format +msgid "bypassing nonessential maintenance of table \"%s.%s.%s\" as a failsafe after %d index scans" +msgstr "" + +#: access/heap/vacuumlazy.c:2630 +#, c-format +msgid "table's relfrozenxid or relminmxid is too far in the past" +msgstr "le relfrozenxid ou le relminmxid de la table est loin dans le passé" + +#: access/heap/vacuumlazy.c:2631 +#, c-format +msgid "" +"Consider increasing configuration parameter \"maintenance_work_mem\" or \"autovacuum_work_mem\".\n" +"You might also need to consider other ways for VACUUM to keep up with the allocation of transaction IDs." +msgstr "" +"Réfléchissez à augmenter la valeur du paramètre de configuration « maintenance_work_mem » ou « autovacuum_work_mem ».\n" +"Vous pouvez aussi réfléchir à d'autres façons d'exécuter un VACUUM pour tenir sur l'allocation des identifiants de transaction." + +#: access/heap/vacuumlazy.c:2771 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "a lancé %d worker parallélisé pour le nettoyage d'index du VACUUM (planifié : %d)" +msgstr[1] "a lancé %d workers parallélisés pour le nettoyage d'index du VACUUM (planifié : %d)" + +#: access/heap/vacuumlazy.c:2777 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "a lancé %d worker parallélisé pour le vacuum d'index (planifié : %d)" +msgstr[1] "a lancé %d workers parallélisés pour le vacuum d'index (planifié : %d)" + +#: access/heap/vacuumlazy.c:3066 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "a parcouru l'index « %s » pour supprimer %d versions de lignes" + +#: access/heap/vacuumlazy.c:3123 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "l'index « %s » contient maintenant %.0f versions de ligne dans %u pages" + +#: access/heap/vacuumlazy.c:3127 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages were newly deleted.\n" +"%u index pages are currently deleted, of which %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f versions de ligne d'index ont été supprimées.\n" +"%u blocs d'index ont été nouvellement supprimés.\n" +"%u blocs d'index sont actuellement supprimés, dont %u sont actuellement réutilisables.\n" +"%s." + +#: access/heap/vacuumlazy.c:3236 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "« %s » : arrêt du TRUNCATE à cause d'un conflit dans la demande de verrou" + +#: access/heap/vacuumlazy.c:3302 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "« %s » : %u pages tronqués en %u" + +#: access/heap/vacuumlazy.c:3366 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "« %s » : mis en suspens du TRUNCATE à cause d'un conflit dans la demande de verrou" + +#: access/heap/vacuumlazy.c:3511 +#, c-format +msgid "disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel" +msgstr "désactivation de l'option de parallélisation du VACUUM sur « %s » --- ne peut pas exécuter un VACUUM parallélisé sur des tables temporaires" + +#: access/heap/vacuumlazy.c:4266 +#, c-format +msgid "while scanning block %u and offset %u of relation \"%s.%s\"" +msgstr "lors du parcours du bloc %u et du décalage %u de la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4269 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "lors du parcours du bloc %u de la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4273 +#, c-format +msgid "while scanning relation \"%s.%s\"" +msgstr "lors du parcours de la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4281 +#, c-format +msgid "while vacuuming block %u and offset %u of relation \"%s.%s\"" +msgstr "lors du traitement par VACUUM du bloc %u et du décalage %u de la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4284 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "lors du VACUUM du bloc %u de la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4288 +#, c-format +msgid "while vacuuming relation \"%s.%s\"" +msgstr "lors du vacuum de la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4293 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "lors du nettoyage de l'index « %s » dans la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4298 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "lors du nettoyage de l'index « %s » dans la relation « %s.%s »" + +#: access/heap/vacuumlazy.c:4304 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "lors du tronquage de la relation « %s.%s » à %u blocs" + +#: access/index/amapi.c:83 commands/amcmds.c:143 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "la méthode d'accès « %s » n'est pas de type %s" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "la méthode d'accès « %s » n'a pas de handler" + +#: access/index/genam.c:486 +#, c-format +msgid "transaction aborted during system catalog scan" +msgstr "transaction annulée lors du parcours du catalogue système" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1355 commands/indexcmds.c:2670 commands/tablecmds.c:267 commands/tablecmds.c:291 commands/tablecmds.c:16492 commands/tablecmds.c:18194 +#, c-format +msgid "\"%s\" is not an index" +msgstr "« %s » n'est pas un index" + +#: access/index/indexam.c:973 +#, c-format +msgid "operator class %s has no options" +msgstr "la classe d'opérateur %s n'a pas d'options" + +#: access/nbtree/nbtinsert.c:665 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "la valeur d'une clé dupliquée rompt la contrainte unique « %s »" + +#: access/nbtree/nbtinsert.c:667 +#, c-format +msgid "Key %s already exists." +msgstr "La clé « %s » existe déjà." + +#: access/nbtree/nbtinsert.c:761 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Ceci peut être dû à une expression d'index immutable." + +#: access/nbtree/nbtpage.c:159 access/nbtree/nbtpage.c:608 parser/parse_utilcmd.c:2319 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "l'index « %s » n'est pas un btree" + +#: access/nbtree/nbtpage.c:166 access/nbtree/nbtpage.c:615 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "la version ne correspond pas dans l'index « %s » : version du fichier %d, version courante %d, version minimale supportée %d" + +#: access/nbtree/nbtpage.c:1875 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "l'index « %s » contient une page interne à moitié morte" + +#: access/nbtree/nbtpage.c:1877 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "Ceci peut être dû à un VACUUM interrompu en version 9.3 ou antérieure, avant la mise à jour. Merci d'utiliser REINDEX." + +#: access/nbtree/nbtutils.c:2665 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "la taille de la ligne d'index, %zu, dépasse le maximum pour un btree de version %u, soit %zu, pour l'index « %s »" + +#: access/nbtree/nbtutils.c:2671 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "La ligne d'index référence le tuple (%u,%u) dans la relation « %s »." + +#: access/nbtree/nbtutils.c:2675 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"Les valeurs plus larges qu'un tiers d'une page de tampon ne peuvent pas être\n" +"indexées.\n" +"Utilisez un index sur le hachage MD5 de la valeur ou passez à l'indexation\n" +"de la recherche plein texte." + +#: access/nbtree/nbtvalidate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s nécessite une fonction de support\n" +"manquante pour les types %s et %s" + +#: access/spgist/spgutils.c:232 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "la méthode de compression doit être définie quand le type feuille est différent du type d'entrée" + +#: access/spgist/spgutils.c:1005 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "la taille de la ligne interne SP-GiST, %zu, dépasse le maximum %zu" + +#: access/spgist/spgvalidate.c:136 +#, c-format +msgid "SP-GiST leaf data type %s does not match declared type %s" +msgstr "le type de données feuille SP-GiST %s ne correspond pas au type déclaré %s" + +#: access/spgist/spgvalidate.c:302 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès %s nécessite la fonction de support %d\n" +"pour le type %s" + +#: access/table/table.c:49 access/table/table.c:83 access/table/table.c:112 access/table/table.c:145 catalog/aclchk.c:1792 +#, c-format +msgid "\"%s\" is an index" +msgstr "« %s » est un index" + +#: access/table/table.c:54 access/table/table.c:88 access/table/table.c:117 access/table/table.c:150 catalog/aclchk.c:1799 commands/tablecmds.c:13197 commands/tablecmds.c:16501 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "« %s » est un type composite" + +#: access/table/tableam.c:266 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "le tid (%u, %u) n'est pas valide pour la relation « %s »" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "%s ne peut pas être vide." + +#: access/table/tableamapi.c:122 utils/misc/guc.c:12438 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s est trop long (%d caractères maximum)." + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "la méthode d'accès à la table « %s » n'existe pas" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "La méthode d'accès « %s » n'existe pas." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "le pourcentage de l'échantillonnage doit être compris entre 0 et 100" + +#: access/transam/commit_ts.c:278 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "ne peut pas récupérer l'horodatage de la validation pour la transaction %u" + +#: access/transam/commit_ts.c:376 +#, c-format +msgid "could not get commit timestamp data" +msgstr "n'a pas pu récupérer les données d'horodatage de la validation" + +#: access/transam/commit_ts.c:378 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the primary server." +msgstr "Assurez-vous que le paramètre de configuration « %s » soit configuré sur le serveur primaire." + +#: access/transam/commit_ts.c:380 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "Assurez-vous que le paramètre de configuration « %s » soit configuré." + +#: access/transam/multixact.c:1021 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "la base de données n'accepte pas de commandes qui génèrent de nouveaux MultiXactId pour éviter les pertes de données suite à une réinitialisation de l'identifiant de transaction dans la base de données « %s »" + +#: access/transam/multixact.c:1023 access/transam/multixact.c:1030 access/transam/multixact.c:1054 access/transam/multixact.c:1063 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Exécutez un VACUUM sur toute cette base.\n" +"Vous pourriez avoir besoin de valider ou d'annuler de vieilles transactions préparées, ou de supprimer les slots de réplication périmés." + +#: access/transam/multixact.c:1028 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "" +"la base de données n'accepte pas de commandes qui génèrent de nouveaux MultiXactId pour éviter des pertes de données à cause de la réinitialisation de l'identifiant de transaction dans\n" +"la base de données d'OID %u" + +#: access/transam/multixact.c:1049 access/transam/multixact.c:2333 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "un VACUUM doit être exécuté sur la base de données « %s » dans un maximum de %u MultiXactId" +msgstr[1] "un VACUUM doit être exécuté sur la base de données « %s » dans un maximum de %u MultiXactId" + +#: access/transam/multixact.c:1058 access/transam/multixact.c:2342 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "un VACUUM doit être exécuté sur la base de données d'OID %u dans un maximum de %u MultiXactId" +msgstr[1] "un VACUUM doit être exécuté sur la base de données d'OID %u dans un maximum de %u MultiXactId" + +#: access/transam/multixact.c:1119 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "dépassement de limite des membres du multixact" + +#: access/transam/multixact.c:1120 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "Cette commande créera un multixact avec %u membres, mais l'espace restant est seulement suffisant pour %u membre." +msgstr[1] "Cette commande créera un multixact avec %u membres, mais l'espace restant est seulement suffisant pour %u membres." + +#: access/transam/multixact.c:1125 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Exécute un VACUUM sur la base dans la base d'OID %u avec une configuration réduite pour vacuum_multixact_freeze_min_age et vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1156 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "un VACUUM doit être exécuté sur la base de données d'OID %u avant que %d MultiXactId supplémentaire ne soit utilisé" +msgstr[1] "un VACUUM doit être exécuté sur la base de données d'OID %u avant que %d MultiXactId supplémentaires ne soient utilisés" + +#: access/transam/multixact.c:1161 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Exécute un VACUUM sur la base dans cette base avec une configuration réduite pour vacuum_multixact_freeze_min_age et vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1300 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "le MultiXactId %u n'existe plus : wraparound apparent" + +#: access/transam/multixact.c:1306 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "le MultiXactId %u n'a pas encore été créé : wraparound apparent" + +#: access/transam/multixact.c:2338 access/transam/multixact.c:2347 access/transam/varsup.c:151 access/transam/varsup.c:158 access/transam/varsup.c:466 access/transam/varsup.c:473 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Pour éviter un arrêt de la base de données, exécutez un VACUUM sur toute cette\n" +"base. Vous pourriez avoir besoin d'enregistrer ou d'annuler les slots de réplication\n" +"trop anciens." + +#: access/transam/multixact.c:2621 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "Les protections sur la réutilisation d'un membre MultiXact sont désactivées car le plus ancien MultiXact géré par un checkpoint, %u, n'existe pas sur disque" + +#: access/transam/multixact.c:2643 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "Les protections sur la réutilisation d'un membre MultiXact sont maintenant activées" + +#: access/transam/multixact.c:3030 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "plus ancien MultiXact introuvable %u, plus récent MultiXact %u, ignore le troncage" + +#: access/transam/multixact.c:3048 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "ne peut pas tronquer jusqu'au MutiXact %u car il n'existe pas sur disque, ignore le troncage" + +#: access/transam/multixact.c:3362 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "MultiXactId invalide : %u" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "échec de l'initialisation du worker parallèle" + +#: access/transam/parallel.c:708 access/transam/parallel.c:827 +#, c-format +msgid "More details may be available in the server log." +msgstr "Plus de détails sont disponibles dans les traces du serveur." + +#: access/transam/parallel.c:888 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "postmaster a quitté pendant une transaction parallèle" + +#: access/transam/parallel.c:1075 +#, c-format +msgid "lost connection to parallel worker" +msgstr "perte de la connexion au processus parallèle" + +#: access/transam/parallel.c:1141 access/transam/parallel.c:1143 +msgid "parallel worker" +msgstr "processus parallèle" + +#: access/transam/parallel.c:1294 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "n'a pas pu mapper le segment de mémoire partagée dynamique" + +#: access/transam/parallel.c:1299 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "numéro magique invalide dans le segment de mémoire partagée dynamique" + +#: access/transam/slru.c:712 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "le fichier « %s » n'existe pas, contenu lu comme des zéros" + +#: access/transam/slru.c:944 access/transam/slru.c:950 access/transam/slru.c:958 access/transam/slru.c:963 access/transam/slru.c:970 access/transam/slru.c:975 access/transam/slru.c:982 access/transam/slru.c:989 +#, c-format +msgid "could not access status of transaction %u" +msgstr "n'a pas pu accéder au statut de la transaction %u" + +#: access/transam/slru.c:945 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "N'a pas pu ouvrir le fichier « %s » : %m." + +#: access/transam/slru.c:951 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "N'a pas pu se déplacer dans le fichier « %s » au décalage %u : %m." + +#: access/transam/slru.c:959 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "N'a pas pu lire le fichier « %s » au décalage %u : %m." + +#: access/transam/slru.c:964 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "N'a pas pu lire le fichier « %s » au décalage %u : lu trop peu d'octets." + +#: access/transam/slru.c:971 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "N'a pas pu écrire le fichier « %s » au décalage %u : %m." + +#: access/transam/slru.c:976 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "N'a pas pu écrire dans le fichier « %s » au décalage %u : écrit trop peu d'octets." + +#: access/transam/slru.c:983 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "N'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m." + +#: access/transam/slru.c:990 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "N'a pas pu fermer le fichier « %s » : %m." + +#: access/transam/slru.c:1251 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "n'a pas pu tronquer le répertoire « %s » : contournement apparent" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "erreur de syntaxe dans le fichier historique : %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Attendait un identifiant timeline numérique." + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Attendait un emplacement de bascule de journal de transactions." + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "données invalides dans le fichier historique : %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Les identifiants timeline doivent être en ordre croissant." + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "données invalides dans le fichier historique « %s »" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "" +"Les identifiants timeline doivent être plus petits que les enfants des\n" +"identifiants timeline." + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "la timeline %u requise n'est pas dans l'historique de ce serveur" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "l'identifiant de la transaction « %s » est trop long" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "les transactions préparées sont désactivées" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "Configure max_prepared_transactions à une valeur différente de zéro." + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "l'identifiant de la transaction « %s » est déjà utilisé" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2385 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "nombre maximum de transactions préparées obtenu" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2386 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "Augmentez max_prepared_transactions (actuellement %d)." + +#: access/transam/twophase.c:584 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "la transaction préparée d'identifiant « %s » est occupée" + +#: access/transam/twophase.c:590 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "droit refusé pour terminer la transaction préparée" + +#: access/transam/twophase.c:591 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "Doit être super-utilisateur ou l'utilisateur qui a préparé la transaction." + +#: access/transam/twophase.c:602 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "la transaction préparée appartient à une autre base de données" + +#: access/transam/twophase.c:603 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "" +"Connectez-vous à la base de données où la transaction a été préparée pour\n" +"la terminer." + +#: access/transam/twophase.c:618 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "la transaction préparée d'identifiant « %s » n'existe pas" + +#: access/transam/twophase.c:1093 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "" +"longueur maximale dépassée pour le fichier de statut de la validation en\n" +"deux phase" + +#: access/transam/twophase.c:1247 +#, c-format +msgid "incorrect size of file \"%s\": %lld byte" +msgid_plural "incorrect size of file \"%s\": %lld bytes" +msgstr[0] "taille incorrecte du fichier « %s » : %lld octet" +msgstr[1] "taille incorrecte du fichier « %s » : %lld octets" + +#: access/transam/twophase.c:1256 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "alignement incorrect du décalage CRC pour le fichier « %s »" + +#: access/transam/twophase.c:1274 +#, c-format +msgid "could not read file \"%s\": read %d of %lld" +msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %lld" + +#: access/transam/twophase.c:1289 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "nombre magique invalide dans le fichier « %s »" + +#: access/transam/twophase.c:1295 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "taille invalide stockée dans le fichier « %s »" + +#: access/transam/twophase.c:1307 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "la somme de contrôle CRC calculée ne correspond par à la valeur enregistrée dans le fichier « %s »" + +#: access/transam/twophase.c:1342 access/transam/xlog.c:6632 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "Échec lors de l'allocation d'un processeur de lecture de journaux de transactions." + +#: access/transam/twophase.c:1357 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "n'a pas pu lire le fichier d'état de la validation en deux phases depuis les journaux de transactions à %X/%X" + +#: access/transam/twophase.c:1364 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "" +"le fichier d'état de la validation en deux phases attendu n'est pas présent\n" +"dans les journaux de transaction à %X/%X" + +#: access/transam/twophase.c:1641 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "n'a pas pu recréer le fichier « %s » : %m" + +#: access/transam/twophase.c:1768 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "le fichier d'état de la validation en deux phases %u a été écrit pour une transaction préparée de longue durée" +msgstr[1] "les fichiers d'état de la validation en deux phases %u ont été écrits pour des transactions préparées de longue durée" + +#: access/transam/twophase.c:2002 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "récupération de la transaction préparée %u à partir de la mémoire partagée" + +#: access/transam/twophase.c:2093 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "suppression du vieux fichier d'état de la validation en deux phases pour la transaction %u" + +#: access/transam/twophase.c:2100 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "suppression du vieux fichier d'état de la validation en deux phases de la mémoire pour la transaction %u" + +#: access/transam/twophase.c:2113 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "suppression du futur fichier d'état de la validation en deux phases pour la transaction %u" + +#: access/transam/twophase.c:2120 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "suppression du futur fichier d'état de la validation en deux phases en mémoire pour la transaction %u" + +#: access/transam/twophase.c:2145 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "fichier d'état de la validation en deux phases pour la transaction %u corrompu" + +#: access/transam/twophase.c:2150 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "mémoire d'état de la validation en deux phases pour la transaction %u corrompue" + +#: access/transam/varsup.c:129 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "" +"la base de données n'accepte plus de requêtes pour éviter des pertes de\n" +"données à cause de la réinitialisation de l'identifiant de transaction dans\n" +"la base de données « %s »" + +#: access/transam/varsup.c:131 access/transam/varsup.c:138 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Arrêtez le postmaster et utilisez un moteur autonome pour exécuter VACUUM\n" +"sur cette base de données.\n" +"Vous pouvez avoir besoin de valider ou d'annuler les anciennes transactions préparées,\n" +"ou de supprimer les slots de réplication trop anciens." + +#: access/transam/varsup.c:136 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "" +"la base de données n'accepte plus de requêtes pour éviter des pertes de\n" +"données à cause de la réinitialisation de l'identifiant de transaction dans\n" +"la base de données %u" + +#: access/transam/varsup.c:148 access/transam/varsup.c:463 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "" +"un VACUUM doit être exécuté sur la base de données « %s » dans un maximum de\n" +"%u transactions" + +#: access/transam/varsup.c:155 access/transam/varsup.c:470 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "" +"un VACUUM doit être exécuté sur la base de données d'OID %u dans un maximum de\n" +"%u transactions" + +#: access/transam/xact.c:1045 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "ne peux pas avoir plus de 2^32-2 commandes dans une transaction" + +#: access/transam/xact.c:1582 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "nombre maximum de sous-transactions validées (%d) dépassé" + +#: access/transam/xact.c:2423 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "" +"ne peut pas préparer (PREPARE) une transaction qui a travaillé sur des\n" +"objets temporaires" + +#: access/transam/xact.c:2433 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "ne peut pas préparer (PREPARE) une transaction qui a exporté des snapshots" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3388 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s ne peut pas être exécuté dans un bloc de transaction" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3398 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s ne peut pas être exécuté dans une sous-transaction" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3408 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s ne peut pas être exécuté à partir d'une fonction" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3477 access/transam/xact.c:3783 access/transam/xact.c:3862 access/transam/xact.c:3985 access/transam/xact.c:4136 access/transam/xact.c:4205 access/transam/xact.c:4316 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s peut seulement être utilisé dans des blocs de transaction" + +#: access/transam/xact.c:3669 +#, c-format +msgid "there is already a transaction in progress" +msgstr "une transaction est déjà en cours" + +#: access/transam/xact.c:3788 access/transam/xact.c:3867 access/transam/xact.c:3990 +#, c-format +msgid "there is no transaction in progress" +msgstr "aucune transaction en cours" + +#: access/transam/xact.c:3878 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "ne peut pas valider pendant une opération parallèle" + +#: access/transam/xact.c:4001 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "ne peut pas annuler pendant une opération en parallèle" + +#: access/transam/xact.c:4100 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "ne peut pas définir de points de sauvegarde lors d'une opération parallèle" + +#: access/transam/xact.c:4187 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "ne peut pas relâcher de points de sauvegarde pendant une opération parallèle" + +#: access/transam/xact.c:4197 access/transam/xact.c:4248 access/transam/xact.c:4308 access/transam/xact.c:4357 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "le point de sauvegarde « %s » n'existe pas" + +#: access/transam/xact.c:4254 access/transam/xact.c:4363 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "le point de sauvegarde « %s » n'existe pas dans le niveau de point de sauvegarde actuel" + +#: access/transam/xact.c:4296 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "ne peut pas retourner à un point de sauvegarde pendant un opération parallèle" + +#: access/transam/xact.c:4424 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "ne peut pas lancer de sous-transactions pendant une opération parallèle" + +#: access/transam/xact.c:4492 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "ne peut pas valider de sous-transactions pendant une opération parallèle" + +#: access/transam/xact.c:5133 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "ne peut pas avoir plus de 2^32-1 sous-transactions dans une transaction" + +#: access/transam/xlog.c:1823 +#, c-format +msgid "request to flush past end of generated WAL; request %X/%X, current position %X/%X" +msgstr "" + +#: access/transam/xlog.c:2584 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "n'a pas pu écrire le fichier de transactions %s au décalage %u, longueur %zu : %m" + +#: access/transam/xlog.c:3986 access/transam/xlogutils.c:798 replication/walsender.c:2520 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "le segment demandé du journal de transaction, %s, a déjà été supprimé" + +#: access/transam/xlog.c:4261 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "n'a pas pu renommer le fichier « %s » : %m" + +#: access/transam/xlog.c:4303 access/transam/xlog.c:4313 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "le répertoire « %s » requis pour les journaux de transactions n'existe pas" + +#: access/transam/xlog.c:4319 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "création du répertoire manquant pour les journaux de transactions « %s »" + +#: access/transam/xlog.c:4322 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "n'a pas pu créer le répertoire « %s » manquant : %m" + +#: access/transam/xlog.c:4425 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "identifiant timeline %u inattendu dans le journal de transactions %s, décalage %u" + +#: access/transam/xlog.c:4563 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "la nouvelle timeline %u n'est pas une enfant de la timeline %u du système" + +#: access/transam/xlog.c:4577 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "" +"la nouvelle timeline %u a été créée à partir de la timeline de la base de données système %u\n" +"avant le point de restauration courant %X/%X" + +#: access/transam/xlog.c:4596 +#, c-format +msgid "new target timeline is %u" +msgstr "la nouvelle timeline cible est %u" + +#: access/transam/xlog.c:4632 +#, c-format +msgid "could not generate secret authorization token" +msgstr "n'a pas pu générer le jeton secret d'autorisation" + +#: access/transam/xlog.c:4791 access/transam/xlog.c:4800 access/transam/xlog.c:4824 access/transam/xlog.c:4831 access/transam/xlog.c:4838 access/transam/xlog.c:4843 access/transam/xlog.c:4850 access/transam/xlog.c:4857 access/transam/xlog.c:4864 access/transam/xlog.c:4871 access/transam/xlog.c:4878 access/transam/xlog.c:4885 access/transam/xlog.c:4894 access/transam/xlog.c:4901 utils/init/miscinit.c:1578 +#, c-format +msgid "database files are incompatible with server" +msgstr "les fichiers de la base de données sont incompatibles avec le serveur" + +#: access/transam/xlog.c:4792 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "" +"Le cluster de base de données a été initialisé avec un PG_CONTROL_VERSION à\n" +"%d (0x%08x) alors que le serveur a été compilé avec un PG_CONTROL_VERSION à\n" +"%d (0x%08x)." + +#: access/transam/xlog.c:4796 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "" +"Ceci peut être un problème d'incohérence dans l'ordre des octets.\n" +"Il se peut que vous ayez besoin d'initdb." + +#: access/transam/xlog.c:4801 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "" +"Le cluster de base de données a été initialisé avec un PG_CONTROL_VERSION à\n" +"%d alors que le serveur a été compilé avec un PG_CONTROL_VERSION à %d." + +#: access/transam/xlog.c:4804 access/transam/xlog.c:4828 access/transam/xlog.c:4835 access/transam/xlog.c:4840 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Il semble que vous avez besoin d'initdb." + +#: access/transam/xlog.c:4815 +#, c-format +msgid "incorrect checksum in control file" +msgstr "somme de contrôle incorrecte dans le fichier de contrôle" + +#: access/transam/xlog.c:4825 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "" +"Le cluster de base de données a été initialisé avec un CATALOG_VERSION_NO à\n" +"%d alors que le serveur a été compilé avec un CATALOG_VERSION_NO à %d." + +#: access/transam/xlog.c:4832 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "" +"Le cluster de bases de données a été initialisé avec un MAXALIGN à %d alors\n" +"que le serveur a été compilé avec un MAXALIGN à %d." + +#: access/transam/xlog.c:4839 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "" +"Le cluster de bases de données semble utiliser un format différent pour les\n" +"nombres à virgule flottante de celui de l'exécutable serveur." + +#: access/transam/xlog.c:4844 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "" +"Le cluster de base de données a été initialisé avec un BLCKSZ à %d alors que\n" +"le serveur a été compilé avec un BLCKSZ à %d." + +#: access/transam/xlog.c:4847 access/transam/xlog.c:4854 access/transam/xlog.c:4861 access/transam/xlog.c:4868 access/transam/xlog.c:4875 access/transam/xlog.c:4882 access/transam/xlog.c:4889 access/transam/xlog.c:4897 access/transam/xlog.c:4904 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Il semble que vous avez besoin de recompiler ou de relancer initdb." + +#: access/transam/xlog.c:4851 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "" +"Le cluster de bases de données a été initialisé avec un RELSEG_SIZE à %d\n" +"alors que le serveur a été compilé avec un RELSEG_SIZE à %d." + +#: access/transam/xlog.c:4858 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "" +"Le cluster de base de données a été initialisé avec un XLOG_BLCKSZ à %d\n" +"alors que le serveur a été compilé avec un XLOG_BLCKSZ à %d." + +#: access/transam/xlog.c:4865 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "" +"Le cluster de bases de données a été initialisé avec un NAMEDATALEN à %d\n" +"alors que le serveur a été compilé avec un NAMEDATALEN à %d." + +#: access/transam/xlog.c:4872 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "" +"Le groupe de bases de données a été initialisé avec un INDEX_MAX_KEYS à %d\n" +"alors que le serveur a été compilé avec un INDEX_MAX_KEYS à %d." + +#: access/transam/xlog.c:4879 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "" +"Le cluster de bases de données a été initialisé avec un TOAST_MAX_CHUNK_SIZE\n" +"à %d alors que le serveur a été compilé avec un TOAST_MAX_CHUNK_SIZE à %d." + +#: access/transam/xlog.c:4886 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "" +"Le cluster de base de données a été initialisé avec un LOBLKSIZE à %d alors que\n" +"le serveur a été compilé avec un LOBLKSIZE à %d." + +#: access/transam/xlog.c:4895 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "" +"Le cluster de base de données a été initialisé sans USE_FLOAT8_BYVAL\n" +"alors que le serveur a été compilé avec USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4902 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "" +"Le cluster de base de données a été initialisé avec USE_FLOAT8_BYVAL\n" +"alors que le serveur a été compilé sans USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4911 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octet" +msgstr[1] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octets" + +#: access/transam/xlog.c:4923 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "« min_wal_size » doit être au moins le double de « wal_segment_size »" + +#: access/transam/xlog.c:4927 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "« max_wal_size » doit être au moins le double de « wal_segment_size »" + +#: access/transam/xlog.c:5361 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "n'a pas pu écrire le « bootstrap » du journal des transactions : %m" + +#: access/transam/xlog.c:5369 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "" +"n'a pas pu synchroniser sur disque (fsync) le « bootstrap » du journal des\n" +"transactions : %m" + +#: access/transam/xlog.c:5375 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "n'a pas pu fermer le « bootstrap » du journal des transactions : %m" + +# /* +# * Check for old recovery API file: recovery.conf +# */ +#: access/transam/xlog.c:5436 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "utiliser le fichier de commande de la restauration « %s » n'est plus supporté" + +#: access/transam/xlog.c:5501 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "le mode de restauration n'est pas supporté pour les serveurs mono-utilisateur" + +#: access/transam/xlog.c:5518 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "ni primary_conninfo ni restore_command n'est spécifié" + +#: access/transam/xlog.c:5519 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "" +"Le serveur de la base de données va régulièrement interroger le sous-répertoire\n" +"pg_wal pour vérifier les fichiers placés ici." + +#: access/transam/xlog.c:5527 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "doit spécifier une restore_command quand le mode standby n'est pas activé" + +#: access/transam/xlog.c:5565 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "le timeline cible, %u, de la restauration n'existe pas" + +#: access/transam/xlog.c:5687 +#, c-format +msgid "archive recovery complete" +msgstr "restauration de l'archive terminée" + +#: access/transam/xlog.c:5753 access/transam/xlog.c:6024 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "arrêt de la restauration après avoir atteint le point de cohérence" + +#: access/transam/xlog.c:5774 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "arrêt de la restauration avant l'emplacement WAL (LSN) « %X/%X »" + +#: access/transam/xlog.c:5859 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "arrêt de la restauration avant validation de la transaction %u, %s" + +#: access/transam/xlog.c:5866 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "arrêt de la restauration avant annulation de la transaction %u, %s" + +#: access/transam/xlog.c:5919 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "restauration en arrêt au point de restauration « %s », heure %s" + +#: access/transam/xlog.c:5937 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "arrêt de la restauration après l'emplacement WAL (LSN) « %X/%X »" + +#: access/transam/xlog.c:6004 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "arrêt de la restauration après validation de la transaction %u, %s" + +#: access/transam/xlog.c:6012 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "arrêt de la restauration après annulation de la transaction %u, %s" + +#: access/transam/xlog.c:6057 +#, c-format +msgid "pausing at the end of recovery" +msgstr "pause à la fin de la restauration" + +#: access/transam/xlog.c:6058 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "Exécuter pg_wal_replay_resume() pour promouvoir." + +#: access/transam/xlog.c:6061 access/transam/xlog.c:6334 +#, c-format +msgid "recovery has paused" +msgstr "restauration en pause" + +#: access/transam/xlog.c:6062 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Exécuter pg_wal_replay_resume() pour continuer." + +#: access/transam/xlog.c:6325 +#, c-format +msgid "hot standby is not possible because of insufficient parameter settings" +msgstr "le hot standby n'est pas possible à cause d'un paramétrage insuffisant" + +#: access/transam/xlog.c:6326 access/transam/xlog.c:6353 access/transam/xlog.c:6383 +#, c-format +msgid "%s = %d is a lower setting than on the primary server, where its value was %d." +msgstr "%s = %d est un paramétrage plus bas que celui du serveur primaire, où sa valeur était %d." + +#: access/transam/xlog.c:6335 +#, c-format +msgid "If recovery is unpaused, the server will shut down." +msgstr "Si la restauration sort de la pause, le serveur sera arrêté." + +#: access/transam/xlog.c:6336 +#, c-format +msgid "You can then restart the server after making the necessary configuration changes." +msgstr "Vous pouvez alors redémarrer le serveur après avoir réaliser les modifications nécessaires sur la configuration." + +#: access/transam/xlog.c:6347 +#, c-format +msgid "promotion is not possible because of insufficient parameter settings" +msgstr "la promotion n'est pas possible à cause d'une configuration insuffisante des paramètres" + +#: access/transam/xlog.c:6357 +#, c-format +msgid "Restart the server after making the necessary configuration changes." +msgstr "Redémarre le serveur après avoir effectuer les changements nécessaires de configuration." + +#: access/transam/xlog.c:6381 +#, c-format +msgid "recovery aborted because of insufficient parameter settings" +msgstr "restauration annulée à cause d'un paramétrage insuffisant" + +#: access/transam/xlog.c:6387 +#, c-format +msgid "You can restart the server after making the necessary configuration changes." +msgstr "Vous pouvez redémarrer le serveur après avoir réalisé les modifications nécessaires sur la configuration." + +#: access/transam/xlog.c:6409 +#, c-format +msgid "WAL was generated with wal_level=minimal, cannot continue recovering" +msgstr "le journal de transactions a été généré avec le paramètre wal_level=minimal, ne peut pas continuer la restauration" + +#: access/transam/xlog.c:6410 +#, c-format +msgid "This happens if you temporarily set wal_level=minimal on the server." +msgstr "Ceci peut arriver si vous configurez temporairement wal_level à minimal sur le serveur." + +#: access/transam/xlog.c:6411 +#, c-format +msgid "Use a backup taken after setting wal_level to higher than minimal." +msgstr "Utilisez la sauvegarde prise lors que la configuration de wal_level était au-dessus du niveau minimal." + +#: access/transam/xlog.c:6480 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "le fichier de contrôle contient un emplacement de checkpoint invalide" + +#: access/transam/xlog.c:6491 +#, c-format +msgid "database system was shut down at %s" +msgstr "le système de bases de données a été arrêté à %s" + +#: access/transam/xlog.c:6497 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "le système de bases de données a été arrêté pendant la restauration à %s" + +#: access/transam/xlog.c:6503 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "le système de bases de données a été interrompu ; dernier lancement connu à %s" + +#: access/transam/xlog.c:6509 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "le système de bases de données a été interrompu lors d'une restauration à %s" + +#: access/transam/xlog.c:6511 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "" +"Ceci signifie probablement que des données ont été corrompues et que vous\n" +"devrez utiliser la dernière sauvegarde pour la restauration." + +#: access/transam/xlog.c:6517 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "" +"le système de bases de données a été interrompu lors d'une récupération à %s\n" +"(moment de la journalisation)" + +#: access/transam/xlog.c:6519 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "" +"Si c'est arrivé plus d'une fois, des données ont pu être corrompues et vous\n" +"pourriez avoir besoin de choisir une cible de récupération antérieure." + +#: access/transam/xlog.c:6525 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "le système de bases de données a été interrompu ; dernier lancement connu à %s" + +#: access/transam/xlog.c:6531 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "le fichier de contrôle contient un état invalide de l'instance" + +#: access/transam/xlog.c:6588 +#, c-format +msgid "entering standby mode" +msgstr "entre en mode standby" + +#: access/transam/xlog.c:6591 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "début de la restauration de l'archive au XID %u" + +#: access/transam/xlog.c:6595 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "début de la restauration de l'archive à %s" + +#: access/transam/xlog.c:6599 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "début de la restauration PITR à « %s »" + +#: access/transam/xlog.c:6603 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "début de la restauration PITR à l'emplacement WAL (LSN) « %X/%X »" + +#: access/transam/xlog.c:6607 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "début de la restauration de l'archive jusqu'au point de cohérence le plus proche" + +#: access/transam/xlog.c:6610 +#, c-format +msgid "starting archive recovery" +msgstr "début de la restauration de l'archive" + +#: access/transam/xlog.c:6684 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "n'a pas pu localiser l'enregistrement redo référencé par le point de vérification" + +#: access/transam/xlog.c:6685 access/transam/xlog.c:6695 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" +"Si vous restaurez depuis une sauvegarde, créez le fichier vide « %s/recovery.signal » et ajoutez les options de restauration nécessaires.\n" +"Si vous ne restaurez pas depuis une sauvegarde, essayez de supprimer « %s/backup_label ».\n" +"Attention : supprimer « %s/backup_label » lors d'une restauration de sauvegarde entraînera la corruption de l'instance." + +#: access/transam/xlog.c:6694 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "n'a pas pu localiser l'enregistrement d'un point de vérification requis" + +#: access/transam/xlog.c:6723 commands/tablespace.c:666 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "n'a pas pu créer le lien symbolique « %s » : %m" + +#: access/transam/xlog.c:6755 access/transam/xlog.c:6761 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "ignore le fichier « %s » car le fichier « %s » n'existe pas" + +#: access/transam/xlog.c:6757 access/transam/xlog.c:12058 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "Le fichier « %s » a été renommé en « %s »." + +#: access/transam/xlog.c:6763 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "N'a pas pu renommer le fichier « %s » en « %s » : %m." + +#: access/transam/xlog.c:6814 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "n'a pas pu localiser un enregistrement d'un point de vérification valide" + +#: access/transam/xlog.c:6852 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "la timeline requise %u n'est pas un fils de l'historique de ce serveur" + +#: access/transam/xlog.c:6854 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "Le dernier checkpoint est à %X/%X sur la timeline %u, mais dans l'historique de la timeline demandée, le serveur est sorti de cette timeline à %X/%X." + +#: access/transam/xlog.c:6868 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "la timeline requise, %u, ne contient pas le point de restauration minimum (%X/%X) sur la timeline %u" + +#: access/transam/xlog.c:6898 +#, c-format +msgid "invalid next transaction ID" +msgstr "prochain ID de transaction invalide" + +#: access/transam/xlog.c:6998 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "ré-exécution invalide dans l'enregistrement du point de vérification" + +#: access/transam/xlog.c:7009 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "enregistrement de ré-exécution invalide dans le point de vérification d'arrêt" + +#: access/transam/xlog.c:7043 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "" +"le système de bases de données n'a pas été arrêté proprement ; restauration\n" +"automatique en cours" + +#: access/transam/xlog.c:7047 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "la restauration après crash commence par la timeline %u et a la timeline %u en cible" + +#: access/transam/xlog.c:7094 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label contient des données incohérentes avec le fichier de contrôle" + +#: access/transam/xlog.c:7095 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "" +"Ceci signifie que la sauvegarde a été corrompue et que vous devrez utiliser\n" +"la dernière sauvegarde pour la restauration." + +#: access/transam/xlog.c:7321 +#, c-format +msgid "redo starts at %X/%X" +msgstr "la ré-exécution commence à %X/%X" + +#: access/transam/xlog.c:7546 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "" +"le point d'arrêt de la restauration demandée se trouve avant le point\n" +"cohérent de restauration" + +#: access/transam/xlog.c:7584 +#, c-format +msgid "redo done at %X/%X system usage: %s" +msgstr "rejeu exécuté à %X/%X utilisation système : %s" + +#: access/transam/xlog.c:7590 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "la dernière transaction a eu lieu à %s (moment de la journalisation)" + +#: access/transam/xlog.c:7599 +#, c-format +msgid "redo is not required" +msgstr "la ré-exécution n'est pas nécessaire" + +#: access/transam/xlog.c:7611 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "la restauration s'est terminée avant d'avoir atteint la cible configurée pour la restauration" + +#: access/transam/xlog.c:7690 access/transam/xlog.c:7694 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "le journal de transactions se termine avant la fin de la sauvegarde de base" + +#: access/transam/xlog.c:7691 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "Tous les journaux de transactions générés pendant la sauvegarde en ligne doivent être disponibles pour la restauration." + +#: access/transam/xlog.c:7695 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "" +"Une sauvegarde en ligne commencée avec pg_start_backup() doit se terminer avec\n" +"pg_stop_backup() et tous les journaux de transactions générés entre les deux\n" +"doivent être disponibles pour la restauration." + +#: access/transam/xlog.c:7698 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "Le journal de transaction se termine avant un point de restauration cohérent" + +#: access/transam/xlog.c:7733 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "identifiant d'un timeline nouvellement sélectionné : %u" + +#: access/transam/xlog.c:8176 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "état de restauration cohérent atteint à %X/%X" + +#: access/transam/xlog.c:8385 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "lien du point de vérification primaire invalide dans le fichier de contrôle" + +#: access/transam/xlog.c:8389 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "lien du point de vérification invalide dans le fichier backup_label" + +#: access/transam/xlog.c:8407 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "enregistrement du point de vérification primaire invalide" + +#: access/transam/xlog.c:8411 +#, c-format +msgid "invalid checkpoint record" +msgstr "enregistrement du point de vérification invalide" + +#: access/transam/xlog.c:8422 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "identifiant du gestionnaire de ressource invalide dans l'enregistrement primaire du point de vérification" + +#: access/transam/xlog.c:8426 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "identifiant du gestionnaire de ressource invalide dans l'enregistrement du point de vérification" + +#: access/transam/xlog.c:8439 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "xl_info invalide dans l'enregistrement du point de vérification primaire" + +#: access/transam/xlog.c:8443 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "xl_info invalide dans l'enregistrement du point de vérification" + +#: access/transam/xlog.c:8454 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "longueur invalide de l'enregistrement primaire du point de vérification" + +#: access/transam/xlog.c:8458 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "longueur invalide de l'enregistrement du point de vérification" + +#: access/transam/xlog.c:8639 +#, c-format +msgid "shutting down" +msgstr "arrêt en cours" + +#. translator: the placeholders show checkpoint options +#: access/transam/xlog.c:8678 +#, c-format +msgid "restartpoint starting:%s%s%s%s%s%s%s%s" +msgstr "début du restartpoint :%s%s%s%s%s%s%s%s" + +#. translator: the placeholders show checkpoint options +#: access/transam/xlog.c:8690 +#, c-format +msgid "checkpoint starting:%s%s%s%s%s%s%s%s" +msgstr "début du checkpoint :%s%s%s%s%s%s%s%s" + +#: access/transam/xlog.c:8750 +#, c-format +msgid "restartpoint complete: wrote %d buffers (%.1f%%); %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB" +msgstr "" + +#: access/transam/xlog.c:8770 +#, c-format +msgid "checkpoint complete: wrote %d buffers (%.1f%%); %d WAL file(s) added, %d removed, %d recycled; write=%ld.%03d s, sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, estimate=%d kB" +msgstr "" + +#: access/transam/xlog.c:9203 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "" +"activité en cours du journal de transactions alors que le système de bases\n" +"de données est en cours d'arrêt" + +#: access/transam/xlog.c:9659 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "la ré-exécution en restauration commence à %X/%X" + +#: access/transam/xlog.c:9661 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "La dernière transaction a eu lieu à %s (moment de la journalisation)." + +#: access/transam/xlog.c:9901 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "point de restauration « %s » créé à %X/%X" + +#: access/transam/xlog.c:10046 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "identifiant de timeline précédent %u inattendu (identifiant de la timeline courante %u) dans l'enregistrement du point de vérification" + +#: access/transam/xlog.c:10055 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "" +"identifiant timeline %u inattendu (après %u) dans l'enregistrement du point\n" +"de vérification" + +#: access/transam/xlog.c:10071 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "identifiant timeline %u inattendu dans l'enregistrement du checkpoint, avant d'atteindre le point de restauration minimum %X/%X sur la timeline %u" + +#: access/transam/xlog.c:10146 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "la sauvegarde en ligne a été annulée, la restauration ne peut pas continuer" + +#: access/transam/xlog.c:10202 access/transam/xlog.c:10258 access/transam/xlog.c:10281 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "" +"identifiant timeline %u inattendu (devrait être %u) dans l'enregistrement du\n" +"point de vérification" + +#: access/transam/xlog.c:10630 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier %s : %m" + +#: access/transam/xlog.c:10636 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fdatasync) le fichier « %s » : %m" + +#: access/transam/xlog.c:10747 access/transam/xlog.c:11276 access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "les fonctions de contrôle des journaux de transactions ne peuvent pas être exécutées lors de la restauration." + +#: access/transam/xlog.c:10756 access/transam/xlog.c:11285 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "Le niveau de journalisation n'est pas suffisant pour faire une sauvegarde en ligne" + +#: access/transam/xlog.c:10757 access/transam/xlog.c:11286 access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "" +"wal_level doit être configuré à « replica » ou « logical »\n" +"au démarrage du serveur." + +#: access/transam/xlog.c:10762 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "label de sauvegarde trop long (%d octets maximum)" + +#: access/transam/xlog.c:10799 access/transam/xlog.c:11075 access/transam/xlog.c:11113 +#, c-format +msgid "a backup is already in progress" +msgstr "une sauvegarde est déjà en cours" + +#: access/transam/xlog.c:10800 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "Exécutez pg_stop_backup() et tentez de nouveau." + +# /* +# * Check to see if all WAL replayed during online backup +# * (i.e., since last restartpoint used as backup starting +# * checkpoint) contain full-page writes. +# */ +#: access/transam/xlog.c:10896 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "Un journal de transaction généré avec full_page_writes=off a été rejoué depuis le dernier point de reprise (restartpoint)" + +#: access/transam/xlog.c:10898 access/transam/xlog.c:11481 +#, c-format +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the primary, and then try an online backup again." +msgstr "Cela signifie que la sauvegarde en cours de réalisation sur le secondaire est corrompue et ne devrait pas être utilisée. Activez full_page_writes et lancez CHECKPOINT sur le primaire, puis recommencez la sauvegarde." + +#: access/transam/xlog.c:10974 replication/basebackup.c:1433 utils/adt/misc.c:345 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "la cible du lien symbolique « %s » est trop longue" + +#: access/transam/xlog.c:11024 commands/tablespace.c:402 commands/tablespace.c:578 replication/basebackup.c:1448 utils/adt/misc.c:353 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "les tablespaces ne sont pas supportés sur cette plateforme" + +#: access/transam/xlog.c:11076 access/transam/xlog.c:11114 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "" +"Si vous êtes certain qu'aucune sauvegarde n'est en cours, supprimez le\n" +"fichier « %s » et recommencez de nouveau." + +#: access/transam/xlog.c:11301 +#, c-format +msgid "exclusive backup not in progress" +msgstr "une sauvegarde exclusive n'est pas en cours" + +#: access/transam/xlog.c:11328 +#, c-format +msgid "a backup is not in progress" +msgstr "aucune sauvegarde n'est en cours" + +#: access/transam/xlog.c:11414 access/transam/xlog.c:11427 access/transam/xlog.c:11816 access/transam/xlog.c:11822 access/transam/xlog.c:11870 access/transam/xlog.c:11950 access/transam/xlog.c:11974 access/transam/xlogfuncs.c:733 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "données invalides dans le fichier « %s »" + +#: access/transam/xlog.c:11431 replication/basebackup.c:1281 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "le standby a été promu lors de la sauvegarde en ligne" + +#: access/transam/xlog.c:11432 replication/basebackup.c:1282 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "" +"Cela signifie que la sauvegarde en cours de réalisation est corrompue et ne\n" +"doit pas être utilisée. Recommencez la sauvegarde." + +#: access/transam/xlog.c:11479 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "Un journal de transaction généré avec full_page_writes=off a été rejoué pendant la sauvegarde en ligne" + +#: access/transam/xlog.c:11599 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "backup de base terminé, en attente de l'archivage des journaux de transactions nécessaires" + +#: access/transam/xlog.c:11611 +#, c-format +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "toujours en attente de la fin de l'archivage de tous les segments de journaux de transactions requis (%d secondes passées)" + +#: access/transam/xlog.c:11613 +#, c-format +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "Vérifiez que votre archive_command s'exécute correctement. Vous pouvez annuler cette sauvegarde sans souci, mais elle ne sera pas utilisable sans tous les segments WAL." + +#: access/transam/xlog.c:11620 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "tous les journaux de transactions requis ont été archivés" + +#: access/transam/xlog.c:11624 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "L'archivage des journaux de transactions n'est pas activé ; vous devez vous assurer que tous les des journaux de transactions requis sont copiés par d'autres moyens pour terminer la sauvegarde" + +#: access/transam/xlog.c:11677 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "annulation de la sauvegarde due à la déconnexion du processus serveur avant que pg_stop_backup ne soit appelé" + +#: access/transam/xlog.c:11871 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "L'identifiant de timeline parsé est %u, mais %u était attendu." + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11999 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "rejeu des WAL à %X/%X pour %s" + +#: access/transam/xlog.c:12047 +#, c-format +msgid "online backup mode was not canceled" +msgstr "le mode de sauvegarde en ligne n'a pas été annulé" + +#: access/transam/xlog.c:12048 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "Le fichier « %s » n'a pas pu être renommé en « %s » : %m." + +#: access/transam/xlog.c:12057 access/transam/xlog.c:12069 access/transam/xlog.c:12079 +#, c-format +msgid "online backup mode canceled" +msgstr "mode de sauvegarde en ligne annulé" + +#: access/transam/xlog.c:12070 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "Les fichiers « %s » et « %s » sont renommés respectivement « %s » et « %s »." + +#: access/transam/xlog.c:12080 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "Le fichier « %s » a été renommé en « %s », mais le fichier « %s » n'a pas pu être renommé en « %s » : %m." + +#: access/transam/xlog.c:12213 access/transam/xlogutils.c:967 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "n'a pas pu lire le journal de transactions %s, décalage %u : %m" + +#: access/transam/xlog.c:12219 access/transam/xlogutils.c:974 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "n'a pas pu lire à partir du segment %s du journal de transactions, décalage %u: lu %d sur %zu" + +#: access/transam/xlog.c:12764 +#, c-format +msgid "WAL receiver process shutdown requested" +msgstr "le processus wal receiver a reçu une demande d'arrêt" + +#: access/transam/xlog.c:12859 +#, c-format +msgid "received promote request" +msgstr "a reçu une demande de promotion" + +#: access/transam/xlog.c:12872 +#, c-format +msgid "promote trigger file found: %s" +msgstr "fichier trigger de promotion trouvé : %s" + +#: access/transam/xlog.c:12880 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "n'a pas pu récupérer les propriétés du fichier trigger pour la promotion « %s » : %m" + +#: access/transam/xlogarchive.c:205 +#, c-format +msgid "archive file \"%s\" has wrong size: %lld instead of %lld" +msgstr "le fichier d'archive « %s » a la mauvaise taille : %lld au lieu de %lld" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "restauration du journal de transactions « %s » à partir de l'archive" + +#: access/transam/xlogarchive.c:228 +#, c-format +msgid "restore_command returned a zero exit status, but stat() failed." +msgstr "restore_command a renvoyé un code de sortie zéro, mais stat() a échoué." + +#: access/transam/xlogarchive.c:260 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "n'a pas pu restaurer le fichier « %s » à partir de l'archive : %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:369 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s « %s »: %s" + +#: access/transam/xlogarchive.c:479 access/transam/xlogarchive.c:543 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "n'a pas pu créer le fichier de statut d'archivage « %s » : %m" + +#: access/transam/xlogarchive.c:487 access/transam/xlogarchive.c:551 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "n'a pas pu écrire le fichier de statut d'archivage « %s » : %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "une sauvegarde est déjà en cours dans cette session" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "une sauvegarde non exclusive est en cours" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "Souhaitiez-vous utiliser pg_stop_backup('f') ?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1311 commands/event_trigger.c:1869 commands/extension.c:1945 commands/extension.c:2053 commands/extension.c:2338 commands/prepare.c:713 executor/execExpr.c:2507 executor/execSRF.c:738 executor/functions.c:1058 foreign/foreign.c:520 libpq/hba.c:2718 replication/logical/launcher.c:937 replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1494 replication/slotfuncs.c:255 replication/walsender.c:3291 storage/ipc/shmem.c:554 utils/adt/datetime.c:4812 utils/adt/genfile.c:507 utils/adt/genfile.c:590 utils/adt/jsonfuncs.c:1933 utils/adt/jsonfuncs.c:2045 utils/adt/jsonfuncs.c:2233 utils/adt/jsonfuncs.c:2342 +#: utils/adt/jsonfuncs.c:3803 utils/adt/mcxtfuncs.c:132 utils/adt/misc.c:218 utils/adt/pgstatfuncs.c:477 utils/adt/pgstatfuncs.c:587 utils/adt/pgstatfuncs.c:1887 utils/adt/varlena.c:4832 utils/fmgr/funcapi.c:74 utils/misc/guc.c:9993 utils/mmgr/portalmem.c:1141 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "" +"la fonction avec set-value a été appelée dans un contexte qui n'accepte pas\n" +"un ensemble" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1315 commands/event_trigger.c:1873 commands/extension.c:1949 commands/extension.c:2057 commands/extension.c:2342 commands/prepare.c:717 foreign/foreign.c:525 libpq/hba.c:2722 replication/logical/launcher.c:941 replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1498 replication/slotfuncs.c:259 replication/walsender.c:3295 storage/ipc/shmem.c:558 utils/adt/datetime.c:4816 utils/adt/genfile.c:511 utils/adt/genfile.c:594 utils/adt/mcxtfuncs.c:136 utils/adt/misc.c:222 utils/adt/pgstatfuncs.c:481 utils/adt/pgstatfuncs.c:591 utils/adt/pgstatfuncs.c:1891 utils/adt/varlena.c:4836 utils/misc/guc.c:9997 +#: utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1145 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "mode matérialisé requis mais interdit dans ce contexte" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "une sauvegarde non exclusive n'est pas en cours" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "Souhaitiez-vous utiliser pg_stop_backup('t') ?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "le niveau de journalisation n'est pas suffisant pour créer un point de restauration" + +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "valeur trop longue pour le point de restauration (%d caractères maximum)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "%s ne peut pas être exécuté lors de la restauration." + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:561 access/transam/xlogfuncs.c:585 access/transam/xlogfuncs.c:608 access/transam/xlogfuncs.c:763 +#, c-format +msgid "recovery is not in progress" +msgstr "la restauration n'est pas en cours" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:562 access/transam/xlogfuncs.c:586 access/transam/xlogfuncs.c:609 access/transam/xlogfuncs.c:764 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "" +"Les fonctions de contrôle de la restauration peuvent seulement être exécutées\n" +"lors de la restauration." + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:567 +#, c-format +msgid "standby promotion is ongoing" +msgstr "la promotion du standby est en cours" + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:568 +#, c-format +msgid "%s cannot be executed after promotion is triggered." +msgstr "%s ne peut pas être exécuté une fois la promotion en cours d'exécution." + +#: access/transam/xlogfuncs.c:769 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "« wait_seconds » ne doit pas être négatif ou nul" + +#: access/transam/xlogfuncs.c:789 storage/ipc/signalfuncs.c:245 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "n'a pas pu envoyer le signal au postmaster : %m" + +#: access/transam/xlogfuncs.c:825 +#, c-format +msgid "server did not promote within %d second" +msgid_plural "server did not promote within %d seconds" +msgstr[0] "le serveur ne s'est pas promu en %d seconde" +msgstr[1] "le serveur ne s'est pas promu dans les %d secondes" + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "décalage invalide de l'enregistrement %X/%X" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "« contrecord » est requis par %X/%X" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "longueur invalide de l'enregistrement à %X/%X : voulait %u, a eu %u" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "longueur trop importante de l'enregistrement %u à %X/%X" + +#: access/transam/xlogreader.c:453 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "il n'existe pas de drapeau contrecord à %X/%X" + +#: access/transam/xlogreader.c:466 +#, c-format +msgid "invalid contrecord length %u (expected %lld) at %X/%X" +msgstr "longueur %u invalide du contrecord (%lld attendu) à %X/%X" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "identifiant du gestionnaire de ressources invalide %u à %X/%X" + +#: access/transam/xlogreader.c:716 access/transam/xlogreader.c:732 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "enregistrement avec prev-link %X/%X incorrect à %X/%X" + +#: access/transam/xlogreader.c:768 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "" +"somme de contrôle des données du gestionnaire de ressources incorrecte à\n" +"l'enregistrement %X/%X" + +#: access/transam/xlogreader.c:805 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "numéro magique invalide %04X dans le segment %s, décalage %u" + +#: access/transam/xlogreader.c:819 access/transam/xlogreader.c:860 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "bits d'information %04X invalides dans le segment %s, décalage %u" + +#: access/transam/xlogreader.c:834 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "le fichier WAL provient d'un système différent : l'identifiant système de la base dans le fichier WAL est %llu, alors que l'identifiant système de la base dans pg_control est %llu" + +#: access/transam/xlogreader.c:842 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "Le fichier WAL provient d'un système différent : taille invalide du segment dans l'en-tête de page" + +#: access/transam/xlogreader.c:848 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "le fichier WAL provient d'une instance différente : XLOG_BLCKSZ incorrect dans l'en-tête de page" + +#: access/transam/xlogreader.c:879 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "pageaddr %X/%X inattendue dans le journal de transactions %s, segment %u" + +#: access/transam/xlogreader.c:904 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "identifiant timeline %u hors de la séquence (après %u) dans le segment %s, décalage %u" + +#: access/transam/xlogreader.c:1249 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %u désordonné à %X/%X" + +#: access/transam/xlogreader.c:1271 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA configuré, mais aucune donnée inclus à %X/%X" + +#: access/transam/xlogreader.c:1278 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA non configuré, mais la longueur des données est %u à %X/%X" + +#: access/transam/xlogreader.c:1314 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE configué, mais du trou rencontré à l'offset %u longueur %u longueur de l'image du bloc %u à %X/%X" + +#: access/transam/xlogreader.c:1330 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE non configuré, mais trou rencontré à l'offset %u longueur %u à %X/%X" + +#: access/transam/xlogreader.c:1345 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED configuré, mais la longueur de l'image du bloc est %u à %X/%X" + +#: access/transam/xlogreader.c:1360 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "ni BKPIMAGE_HAS_HOLE ni BKPIMAGE_IS_COMPRESSED configuré, mais la longueur de l'image du bloc est %u à %X/%X" + +#: access/transam/xlogreader.c:1376 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL configuré, mais pas de relation précédente à %X/%X" + +#: access/transam/xlogreader.c:1388 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "block_id %u invalide à %X/%X" + +#: access/transam/xlogreader.c:1475 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "enregistrement de longueur invalide à %X/%X" + +#: access/transam/xlogreader.c:1564 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "image compressée invalide à %X/%X, bloc %d" + +#: bootstrap/bootstrap.c:270 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X nécessite une puissance de deux entre 1 MB et 1 GB" + +#: bootstrap/bootstrap.c:287 postmaster/postmaster.c:847 tcop/postgres.c:3858 +#, c-format +msgid "--%s requires a value" +msgstr "--%s requiert une valeur" + +#: bootstrap/bootstrap.c:292 postmaster/postmaster.c:852 tcop/postgres.c:3863 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s requiert une valeur" + +#: bootstrap/bootstrap.c:303 postmaster/postmaster.c:864 postmaster/postmaster.c:877 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: bootstrap/bootstrap.c:312 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s : arguments invalides en ligne de commande\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "les options grant peuvent seulement être données aux rôles" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "aucun droit n'a pu être accordé pour la colonne « %s » de la relation « %s »" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "aucun droit n'a été accordé pour « %s »" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "certains droits n'ont pu être accordé pour la colonne « %s » de la relation « %s »" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "tous les droits n'ont pas été accordés pour « %s »" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "aucun droit n'a pu être révoqué pour la colonne « %s » de la relation « %s »" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "aucun droit n'a pu être révoqué pour « %s »" + +#: catalog/aclchk.c:342 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "certains droits n'ont pu être révoqués pour la colonne « %s » de la relation « %s »" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "certains droits n'ont pu être révoqués pour « %s »" + +#: catalog/aclchk.c:379 +#, c-format +msgid "grantor must be current user" +msgstr "le concédant doit être l'utilisateur actuel" + +#: catalog/aclchk.c:446 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "droit %s invalide pour la relation" + +#: catalog/aclchk.c:450 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "droit %s invalide pour la séquence" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "droit %s invalide pour la base de données" + +#: catalog/aclchk.c:458 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "type de droit %s invalide pour le domaine" + +#: catalog/aclchk.c:462 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "droit %s invalide pour la fonction" + +#: catalog/aclchk.c:466 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "droit %s invalide pour le langage" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "type de droit invalide, %s, pour le Large Object" + +#: catalog/aclchk.c:474 catalog/aclchk.c:1013 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "droit %s invalide pour le schéma" + +#: catalog/aclchk.c:478 catalog/aclchk.c:1001 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "type de droit %s invalide pour la procédure " + +#: catalog/aclchk.c:482 catalog/aclchk.c:1005 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "droit %s invalide pour la routine" + +#: catalog/aclchk.c:486 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "droit %s invalide pour le tablespace" + +#: catalog/aclchk.c:490 catalog/aclchk.c:1009 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "type de droit %s invalide pour le type" + +#: catalog/aclchk.c:494 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "type de droit %s invalide pour le wrapper de données distantes" + +#: catalog/aclchk.c:498 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "type de droit %s invalide pour le serveur distant" + +#: catalog/aclchk.c:537 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "les droits sur la colonne sont seulement valides pour les relations" + +#: catalog/aclchk.c:697 catalog/aclchk.c:4164 catalog/aclchk.c:4985 catalog/objectaddress.c:1060 catalog/pg_largeobject.c:116 storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "le « Large Object » %u n'existe pas" + +#: catalog/aclchk.c:926 catalog/aclchk.c:935 commands/collationcmds.c:119 commands/copy.c:362 commands/copy.c:382 commands/copy.c:392 commands/copy.c:401 commands/copy.c:410 commands/copy.c:420 commands/copy.c:429 commands/copy.c:438 commands/copy.c:456 commands/copy.c:472 commands/copy.c:492 commands/copy.c:509 commands/dbcommands.c:157 commands/dbcommands.c:166 commands/dbcommands.c:175 commands/dbcommands.c:184 commands/dbcommands.c:193 commands/dbcommands.c:202 commands/dbcommands.c:211 commands/dbcommands.c:220 commands/dbcommands.c:229 commands/dbcommands.c:238 commands/dbcommands.c:260 commands/dbcommands.c:1502 commands/dbcommands.c:1511 commands/dbcommands.c:1520 +#: commands/dbcommands.c:1529 commands/extension.c:1736 commands/extension.c:1746 commands/extension.c:1756 commands/extension.c:3056 commands/foreigncmds.c:539 commands/foreigncmds.c:548 commands/functioncmds.c:604 commands/functioncmds.c:770 commands/functioncmds.c:779 commands/functioncmds.c:788 commands/functioncmds.c:797 commands/functioncmds.c:2094 commands/functioncmds.c:2102 commands/publicationcmds.c:90 commands/publicationcmds.c:133 commands/sequence.c:1266 commands/sequence.c:1276 commands/sequence.c:1286 commands/sequence.c:1296 commands/sequence.c:1306 commands/sequence.c:1316 commands/sequence.c:1326 commands/sequence.c:1336 commands/sequence.c:1346 +#: commands/subscriptioncmds.c:124 commands/subscriptioncmds.c:134 commands/subscriptioncmds.c:144 commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:168 commands/subscriptioncmds.c:179 commands/subscriptioncmds.c:193 commands/subscriptioncmds.c:203 commands/subscriptioncmds.c:213 commands/tablecmds.c:7499 commands/typecmds.c:335 commands/typecmds.c:1416 commands/typecmds.c:1425 commands/typecmds.c:1433 commands/typecmds.c:1441 commands/typecmds.c:1449 commands/typecmds.c:1457 commands/user.c:133 commands/user.c:147 commands/user.c:156 commands/user.c:165 commands/user.c:174 commands/user.c:183 commands/user.c:192 commands/user.c:201 commands/user.c:210 commands/user.c:219 +#: commands/user.c:228 commands/user.c:237 commands/user.c:246 commands/user.c:582 commands/user.c:590 commands/user.c:598 commands/user.c:606 commands/user.c:614 commands/user.c:622 commands/user.c:630 commands/user.c:638 commands/user.c:647 commands/user.c:655 commands/user.c:663 parser/parse_utilcmd.c:397 replication/pgoutput/pgoutput.c:189 replication/pgoutput/pgoutput.c:210 replication/pgoutput/pgoutput.c:224 replication/pgoutput/pgoutput.c:234 replication/pgoutput/pgoutput.c:244 replication/walsender.c:882 replication/walsender.c:893 replication/walsender.c:903 +#, c-format +msgid "conflicting or redundant options" +msgstr "options en conflit ou redondantes" + +#: catalog/aclchk.c:1046 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "les droits par défaut ne peuvent pas être configurés pour les colonnes" + +#: catalog/aclchk.c:1206 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "ne peut pas utiliser la clause IN SCHEMA lors de l'utilisation de GRANT/REVOKE ON SCHEMAS" + +#: catalog/aclchk.c:1544 catalog/catalog.c:553 catalog/objectaddress.c:1522 commands/analyze.c:390 commands/copy.c:741 commands/sequence.c:1701 commands/tablecmds.c:6975 commands/tablecmds.c:7118 commands/tablecmds.c:7168 commands/tablecmds.c:7242 commands/tablecmds.c:7312 commands/tablecmds.c:7424 commands/tablecmds.c:7518 commands/tablecmds.c:7577 commands/tablecmds.c:7666 commands/tablecmds.c:7695 commands/tablecmds.c:7850 commands/tablecmds.c:7932 commands/tablecmds.c:8088 commands/tablecmds.c:8206 commands/tablecmds.c:11555 commands/tablecmds.c:11737 commands/tablecmds.c:11897 commands/tablecmds.c:13040 commands/tablecmds.c:15601 commands/trigger.c:924 parser/analyze.c:2415 +#: parser/parse_relation.c:714 parser/parse_target.c:1064 parser/parse_type.c:144 parser/parse_utilcmd.c:3421 parser/parse_utilcmd.c:3456 parser/parse_utilcmd.c:3498 utils/adt/acl.c:2845 utils/adt/ruleutils.c:2708 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "la colonne « %s » de la relation « %s » n'existe pas" + +#: catalog/aclchk.c:1807 catalog/objectaddress.c:1362 commands/sequence.c:1139 commands/tablecmds.c:249 commands/tablecmds.c:16465 utils/adt/acl.c:2053 utils/adt/acl.c:2083 utils/adt/acl.c:2115 utils/adt/acl.c:2147 utils/adt/acl.c:2175 utils/adt/acl.c:2205 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "« %s » n'est pas une séquence" + +#: catalog/aclchk.c:1845 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "la séquence « %s » accepte seulement les droits USAGE, SELECT et UPDATE" + +#: catalog/aclchk.c:1862 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "type de droit %s invalide pour la table" + +#: catalog/aclchk.c:2028 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "type de droit %s invalide pour la colonne" + +#: catalog/aclchk.c:2041 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "la séquence « %s » accepte seulement le droit SELECT pour les colonnes" + +#: catalog/aclchk.c:2623 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "le langage « %s » n'est pas de confiance" + +#: catalog/aclchk.c:2625 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "GRANT et REVOKE ne sont pas autorisés sur des langages qui ne sont pas de confiance car seuls les super-utilisateurs peuvent utiliser ces langages." + +#: catalog/aclchk.c:3139 +#, c-format +msgid "cannot set privileges of array types" +msgstr "ne peut pas configurer les droits des types tableau" + +#: catalog/aclchk.c:3140 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Configurez les droits du type élément à la place." + +#: catalog/aclchk.c:3147 catalog/objectaddress.c:1656 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "« %s » n'est pas un domaine" + +#: catalog/aclchk.c:3267 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "type de droit « %s » non reconnu" + +#: catalog/aclchk.c:3328 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "droit refusé pour l'aggrégat %s" + +#: catalog/aclchk.c:3331 +#, c-format +msgid "permission denied for collation %s" +msgstr "droit refusé pour le collationnement %s" + +#: catalog/aclchk.c:3334 +#, c-format +msgid "permission denied for column %s" +msgstr "droit refusé pour la colonne %s" + +#: catalog/aclchk.c:3337 +#, c-format +msgid "permission denied for conversion %s" +msgstr "droit refusé pour la conversion %s" + +#: catalog/aclchk.c:3340 +#, c-format +msgid "permission denied for database %s" +msgstr "droit refusé pour la base de données %s" + +#: catalog/aclchk.c:3343 +#, c-format +msgid "permission denied for domain %s" +msgstr "droit refusé pour le domaine %s" + +#: catalog/aclchk.c:3346 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "droit refusé pour le trigger sur événement %s" + +#: catalog/aclchk.c:3349 +#, c-format +msgid "permission denied for extension %s" +msgstr "droit refusé pour l'extension %s" + +#: catalog/aclchk.c:3352 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "droit refusé pour le wrapper de données distantes %s" + +#: catalog/aclchk.c:3355 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "droit refusé pour le serveur distant %s" + +#: catalog/aclchk.c:3358 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "droit refusé pour la table distante %s" + +#: catalog/aclchk.c:3361 +#, c-format +msgid "permission denied for function %s" +msgstr "droit refusé pour la fonction %s" + +#: catalog/aclchk.c:3364 +#, c-format +msgid "permission denied for index %s" +msgstr "droit refusé pour l'index %s" + +#: catalog/aclchk.c:3367 +#, c-format +msgid "permission denied for language %s" +msgstr "droit refusé pour le langage %s" + +#: catalog/aclchk.c:3370 +#, c-format +msgid "permission denied for large object %s" +msgstr "droit refusé pour le Large Object %s" + +#: catalog/aclchk.c:3373 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "droit refusé pour la vue matérialisée %s" + +#: catalog/aclchk.c:3376 +#, c-format +msgid "permission denied for operator class %s" +msgstr "droit refusé pour la classe d'opérateur %s" + +#: catalog/aclchk.c:3379 +#, c-format +msgid "permission denied for operator %s" +msgstr "droit refusé pour l'opérateur %s" + +#: catalog/aclchk.c:3382 +#, c-format +msgid "permission denied for operator family %s" +msgstr "droit refusé pour la famille d'opérateur %s" + +#: catalog/aclchk.c:3385 +#, c-format +msgid "permission denied for policy %s" +msgstr "droit refusé pour la politique %s" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for procedure %s" +msgstr "droit refusé pour la procédure %s" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for publication %s" +msgstr "droit refusé pour la publication %s" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for routine %s" +msgstr "droit refusé pour la routine %s" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for schema %s" +msgstr "droit refusé pour le schéma %s" + +#: catalog/aclchk.c:3400 commands/sequence.c:610 commands/sequence.c:844 commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1799 commands/sequence.c:1863 +#, c-format +msgid "permission denied for sequence %s" +msgstr "droit refusé pour la séquence %s" + +#: catalog/aclchk.c:3403 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "droit refusé pour l'objet statistique %s" + +#: catalog/aclchk.c:3406 +#, c-format +msgid "permission denied for subscription %s" +msgstr "droit refusé pour la souscription %s" + +#: catalog/aclchk.c:3409 +#, c-format +msgid "permission denied for table %s" +msgstr "droit refusé pour la table %s" + +#: catalog/aclchk.c:3412 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "droit refusé pour le tablespace %s" + +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "droit refusé pour la configuration de recherche plein texte %s" + +#: catalog/aclchk.c:3418 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "droit refusé pour le dictionnaire de recherche plein texte %s" + +#: catalog/aclchk.c:3421 +#, c-format +msgid "permission denied for type %s" +msgstr "droit refusé pour le type %s" + +#: catalog/aclchk.c:3424 +#, c-format +msgid "permission denied for view %s" +msgstr "droit refusé pour la vue %s" + +#: catalog/aclchk.c:3459 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "doit être le propriétaire de l'aggrégat %s" + +#: catalog/aclchk.c:3462 +#, c-format +msgid "must be owner of collation %s" +msgstr "doit être le propriétaire du collationnement %s" + +#: catalog/aclchk.c:3465 +#, c-format +msgid "must be owner of conversion %s" +msgstr "doit être le propriétaire de la conversion %s" + +#: catalog/aclchk.c:3468 +#, c-format +msgid "must be owner of database %s" +msgstr "doit être le propriétaire de la base de données %s" + +#: catalog/aclchk.c:3471 +#, c-format +msgid "must be owner of domain %s" +msgstr "doit être le propriétaire du domaine %s" + +#: catalog/aclchk.c:3474 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "doit être le propriétaire du trigger sur événement %s" + +#: catalog/aclchk.c:3477 +#, c-format +msgid "must be owner of extension %s" +msgstr "doit être le propriétaire de l'extension %s" + +#: catalog/aclchk.c:3480 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "doit être le propriétaire du wrapper de données distantes %s" + +#: catalog/aclchk.c:3483 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "doit être le propriétaire de serveur distant %s" + +#: catalog/aclchk.c:3486 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "doit être le propriétaire de la table distante %s" + +#: catalog/aclchk.c:3489 +#, c-format +msgid "must be owner of function %s" +msgstr "doit être le propriétaire de la fonction %s" + +#: catalog/aclchk.c:3492 +#, c-format +msgid "must be owner of index %s" +msgstr "doit être le propriétaire de l'index %s" + +#: catalog/aclchk.c:3495 +#, c-format +msgid "must be owner of language %s" +msgstr "doit être le propriétaire du langage %s" + +#: catalog/aclchk.c:3498 +#, c-format +msgid "must be owner of large object %s" +msgstr "doit être le propriétaire du Large Object %s" + +#: catalog/aclchk.c:3501 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "doit être le propriétaire de la vue matérialisée %s" + +#: catalog/aclchk.c:3504 +#, c-format +msgid "must be owner of operator class %s" +msgstr "doit être le propriétaire de la classe d'opérateur %s" + +#: catalog/aclchk.c:3507 +#, c-format +msgid "must be owner of operator %s" +msgstr "doit être le prorpriétaire de l'opérateur %s" + +#: catalog/aclchk.c:3510 +#, c-format +msgid "must be owner of operator family %s" +msgstr "doit être le prorpriétaire de la famille d'opérateur %s" + +#: catalog/aclchk.c:3513 +#, c-format +msgid "must be owner of procedure %s" +msgstr "doit être le prorpriétaire de la procédure %s" + +#: catalog/aclchk.c:3516 +#, c-format +msgid "must be owner of publication %s" +msgstr "doit être le propriétaire de la publication %s" + +#: catalog/aclchk.c:3519 +#, c-format +msgid "must be owner of routine %s" +msgstr "doit être le propriétaire de la routine %s" + +#: catalog/aclchk.c:3522 +#, c-format +msgid "must be owner of sequence %s" +msgstr "doit être le propriétaire de la séquence %s" + +#: catalog/aclchk.c:3525 +#, c-format +msgid "must be owner of subscription %s" +msgstr "doit être le propriétaire de la souscription %s" + +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of table %s" +msgstr "doit être le propriétaire de la table %s" + +#: catalog/aclchk.c:3531 +#, c-format +msgid "must be owner of type %s" +msgstr "doit être le propriétaire du type %s" + +#: catalog/aclchk.c:3534 +#, c-format +msgid "must be owner of view %s" +msgstr "doit être le propriétaire de la vue %s" + +#: catalog/aclchk.c:3537 +#, c-format +msgid "must be owner of schema %s" +msgstr "doit être le propriétaire du schéma %s" + +#: catalog/aclchk.c:3540 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "doit être le propriétaire de l'objet statistique %s" + +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "doit être le propriétaire du tablespace %s" + +#: catalog/aclchk.c:3546 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "doit être le propriétaire de la configuration de recherche plein texte %s" + +#: catalog/aclchk.c:3549 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "doit être le propriétaire du dictionnaire de recherche plein texte %s" + +#: catalog/aclchk.c:3563 +#, c-format +msgid "must be owner of relation %s" +msgstr "doit être le propriétaire de la relation %s" + +#: catalog/aclchk.c:3607 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "droit refusé pour la colonne « %s » de la relation « %s »" + +#: catalog/aclchk.c:3750 catalog/aclchk.c:3769 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "l'attribut %d de la relation d'OID %u n'existe pas" + +#: catalog/aclchk.c:3864 catalog/aclchk.c:4836 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "la relation d'OID %u n'existe pas" + +#: catalog/aclchk.c:3977 catalog/aclchk.c:5254 +#, c-format +msgid "database with OID %u does not exist" +msgstr "la base de données d'OID %u n'existe pas" + +#: catalog/aclchk.c:4031 catalog/aclchk.c:4914 tcop/fastpath.c:141 utils/fmgr/fmgr.c:2051 +#, c-format +msgid "function with OID %u does not exist" +msgstr "la fonction d'OID %u n'existe pas" + +#: catalog/aclchk.c:4085 catalog/aclchk.c:4940 +#, c-format +msgid "language with OID %u does not exist" +msgstr "le langage d'OID %u n'existe pas" + +#: catalog/aclchk.c:4249 catalog/aclchk.c:5012 commands/collationcmds.c:517 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "le schéma d'OID %u n'existe pas" + +#: catalog/aclchk.c:4313 catalog/aclchk.c:5039 utils/adt/genfile.c:688 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "le tablespace d'OID %u n'existe pas" + +#: catalog/aclchk.c:4372 catalog/aclchk.c:5173 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "le wrapper de données distantes d'OID %u n'existe pas" + +#: catalog/aclchk.c:4434 catalog/aclchk.c:5200 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "le serveur distant d'OID %u n'existe pas" + +#: catalog/aclchk.c:4494 catalog/aclchk.c:4862 utils/cache/typcache.c:384 utils/cache/typcache.c:439 +#, c-format +msgid "type with OID %u does not exist" +msgstr "le type d'OID %u n'existe pas" + +#: catalog/aclchk.c:4888 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "l'opérateur d'OID %u n'existe pas" + +#: catalog/aclchk.c:5065 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "la classe d'opérateur d'OID %u n'existe pas" + +#: catalog/aclchk.c:5092 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "la famille d'opérateur d'OID %u n'existe pas" + +#: catalog/aclchk.c:5119 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "le dictionnaire de recherche plein texte d'OID %u n'existe pas" + +#: catalog/aclchk.c:5146 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "la configuration de recherche plein texte d'OID %u n'existe pas" + +#: catalog/aclchk.c:5227 commands/event_trigger.c:453 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "le trigger sur événement d'OID %u n'existe pas" + +#: catalog/aclchk.c:5280 commands/collationcmds.c:368 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "le collationnement d'OID %u n'existe pas" + +#: catalog/aclchk.c:5306 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "la conversion d'OID %u n'existe pas" + +#: catalog/aclchk.c:5347 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "l'extension d'OID %u n'existe pas" + +#: catalog/aclchk.c:5374 commands/publicationcmds.c:771 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "la publication d'OID %u n'existe pas" + +#: catalog/aclchk.c:5400 commands/subscriptioncmds.c:1462 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "la souscription d'OID %u n'existe pas" + +#: catalog/aclchk.c:5426 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "l'objet statistique d'OID %u n'existe pas" + +#: catalog/catalog.c:378 +#, c-format +msgid "still finding an unused OID within relation \"%s\"" +msgstr "trouve de nouveau un OID inutilisé dans la relation « %s »" + +#: catalog/catalog.c:380 +#, c-format +msgid "OID candidates were checked \"%llu\" times, but no unused OID is yet found." +msgstr "Les candidats OID ont été vérifiés « %llu » fois, mais aucun OID inutilisé n'a encore été trouvé." + +#: catalog/catalog.c:403 +#, c-format +msgid "new OID has been assigned in relation \"%s\" after \"%llu\" retries" +msgstr "le nouvel OID a été affecté à la relation « %s » après « %llu » tentatives" + +#: catalog/catalog.c:532 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "doit être un super-utilisateur pour appeller pg_nextoid()" + +#: catalog/catalog.c:540 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() ne peut être utilisé que pour les catalogues système" + +#: catalog/catalog.c:545 parser/parse_utilcmd.c:2266 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "l'index « %s » n'appartient pas à la table « %s »" + +#: catalog/catalog.c:562 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "la colonne « %s » n'est pas de type oid" + +#: catalog/catalog.c:569 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "l'index « %s » n'est pas un index de la colonne « %s »" + +#: catalog/dependency.c:821 catalog/dependency.c:1060 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "n'a pas pu supprimer %s car il est requis par %s" + +#: catalog/dependency.c:823 catalog/dependency.c:1062 +#, c-format +msgid "You can drop %s instead." +msgstr "Vous pouvez supprimer %s à la place." + +#: catalog/dependency.c:931 catalog/pg_shdepend.c:696 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "n'a pas pu supprimer %s car il est requis par le système de bases de données" + +#: catalog/dependency.c:1135 catalog/dependency.c:1144 +#, c-format +msgid "%s depends on %s" +msgstr "%s dépend de %s" + +#: catalog/dependency.c:1156 catalog/dependency.c:1165 +#, c-format +msgid "drop cascades to %s" +msgstr "DROP cascade sur %s" + +#: catalog/dependency.c:1173 catalog/pg_shdepend.c:825 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"et %d autre objet (voir le journal applicatif du serveur pour une liste)" +msgstr[1] "" +"\n" +"et %d autres objets (voir le journal applicatif du serveur pour une liste)" + +#: catalog/dependency.c:1185 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "n'a pas pu supprimer %s car d'autres objets en dépendent" + +#: catalog/dependency.c:1187 catalog/dependency.c:1188 catalog/dependency.c:1194 catalog/dependency.c:1195 catalog/dependency.c:1206 catalog/dependency.c:1207 commands/tablecmds.c:1298 commands/tablecmds.c:13658 commands/tablespace.c:481 commands/user.c:1095 commands/view.c:492 libpq/auth.c:338 replication/syncrep.c:1043 storage/lmgr/deadlock.c:1152 storage/lmgr/proc.c:1433 utils/adt/acl.c:5250 utils/adt/jsonfuncs.c:618 utils/adt/jsonfuncs.c:624 utils/misc/guc.c:7114 utils/misc/guc.c:7150 utils/misc/guc.c:7220 utils/misc/guc.c:11400 utils/misc/guc.c:11434 utils/misc/guc.c:11468 utils/misc/guc.c:11511 utils/misc/guc.c:11553 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1189 catalog/dependency.c:1196 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Utilisez DROP ... CASCADE pour supprimer aussi les objets dépendants." + +#: catalog/dependency.c:1193 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "ne peut pas supprimer les objets désirés car d'autres objets en dépendent" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1202 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "DROP cascade sur %d autre objet" +msgstr[1] "DROP cascade sur %d autres objets" + +#: catalog/dependency.c:1863 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "la constante de type %s ne peut pas être utilisée ici" + +#: catalog/heap.c:332 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "droit refusé pour créer « %s.%s »" + +#: catalog/heap.c:334 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "Les modifications du catalogue système sont actuellement interdites." + +#: catalog/heap.c:511 commands/tablecmds.c:2335 commands/tablecmds.c:2972 commands/tablecmds.c:6566 +#, c-format +msgid "tables can have at most %d columns" +msgstr "les tables peuvent avoir au plus %d colonnes" + +#: catalog/heap.c:529 commands/tablecmds.c:6865 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "le nom de la colonne « %s » entre en conflit avec le nom d'une colonne système" + +#: catalog/heap.c:545 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "colonne « %s » spécifiée plus d'une fois" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:620 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "la colonne de clé de partitionnement %s a le pseudo type %s" + +#: catalog/heap.c:625 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "la colonne « %s » a le pseudo type %s" + +#: catalog/heap.c:656 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "le type composite %s ne peut pas être membre de lui-même" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:711 +#, c-format +msgid "no collation was derived for partition key column %s with collatable type %s" +msgstr "aucun collationnement n'a été dérivé pour la colonne « %s » sur la clé de partitionnement et de type collationnable %s" + +#: catalog/heap.c:717 commands/createas.c:203 commands/createas.c:500 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "aucun collationnement n'a été dérivé pour la colonne « %s » de type collationnable %s" + +#: catalog/heap.c:1199 catalog/index.c:870 commands/createas.c:405 commands/tablecmds.c:3853 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "la relation « %s » existe déjà" + +#: catalog/heap.c:1215 catalog/pg_type.c:435 catalog/pg_type.c:773 catalog/pg_type.c:920 commands/typecmds.c:249 commands/typecmds.c:261 commands/typecmds.c:757 commands/typecmds.c:1172 commands/typecmds.c:1398 commands/typecmds.c:1590 commands/typecmds.c:2563 +#, c-format +msgid "type \"%s\" already exists" +msgstr "le type « %s » existe déjà" + +#: catalog/heap.c:1216 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "Une relation a un type associé du même nom, donc vous devez utiliser un nom qui n'entre pas en conflit avec un type existant." + +#: catalog/heap.c:1245 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "OID du heap de pg_class non configuré en mode de mise à jour binaire" + +#: catalog/heap.c:2458 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "ne peut pas ajouter une contrainte NO INHERIT pour la table partitionnée « %s »" + +#: catalog/heap.c:2730 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "la contrainte de vérification « %s » existe déjà" + +#: catalog/heap.c:2900 catalog/index.c:884 catalog/pg_constraint.c:670 commands/tablecmds.c:8580 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "la contrainte « %s » de la relation « %s » existe déjà" + +#: catalog/heap.c:2907 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "la contrainte « %s » entre en conflit avec la constrainte non héritée sur la relation « %s »" + +#: catalog/heap.c:2918 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "la contrainte « %s » entre en conflit avec une contrainte héritée sur la relation « %s »" + +#: catalog/heap.c:2928 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "la contrainte « %s » entre en conflit avec une contrainte NOT VALID sur la relation « %s »" + +#: catalog/heap.c:2933 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "assemblage de la contrainte « %s » avec une définition héritée" + +#: catalog/heap.c:3038 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "ne peut pas utiliser la colonne générée « %s » dans une expression de génération de colonne" + +#: catalog/heap.c:3040 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "Une colonne générée ne peut référencer une autre colonne générée." + +#: catalog/heap.c:3046 +#, c-format +msgid "cannot use whole-row variable in column generation expression" +msgstr "ne peut pas utiliser une variable de ligne dans l'expression de génération d'une colonne" + +#: catalog/heap.c:3047 +#, c-format +msgid "This would cause the generated column to depend on its own value." +msgstr "" + +#: catalog/heap.c:3100 +#, c-format +msgid "generation expression is not immutable" +msgstr "l'expression de génération n'est pas immuable" + +#: catalog/heap.c:3128 rewrite/rewriteHandler.c:1245 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "la colonne « %s » est de type %s alors que l'expression par défaut est de type %s" + +#: catalog/heap.c:3133 commands/prepare.c:368 parser/analyze.c:2639 parser/parse_target.c:595 parser/parse_target.c:883 parser/parse_target.c:893 rewrite/rewriteHandler.c:1250 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Vous devez réécrire l'expression ou lui appliquer une transformation de type." + +#: catalog/heap.c:3180 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "seule la table « %s » peut être référencée dans la contrainte de vérification" + +#: catalog/heap.c:3478 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "combinaison ON COMMIT et clé étrangère non supportée" + +#: catalog/heap.c:3479 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "" +"La table « %s » référence « %s » mais elles n'ont pas la même valeur pour le\n" +"paramètre ON COMMIT." + +#: catalog/heap.c:3484 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "ne peut pas tronquer une table référencée dans une contrainte de clé étrangère" + +#: catalog/heap.c:3485 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "La table « %s » référence « %s »." + +#: catalog/heap.c:3487 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "Tronquez la table « %s » en même temps, ou utilisez TRUNCATE ... CASCADE." + +#: catalog/index.c:221 parser/parse_utilcmd.c:2172 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "les clés primaires multiples ne sont pas autorisées pour la table « %s »" + +#: catalog/index.c:239 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "les clés primaires ne peuvent pas être des expressions" + +#: catalog/index.c:256 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "la colonne de clé primaire « %s » n'est pas marquée NOT NULL" + +#: catalog/index.c:769 catalog/index.c:1905 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "les index définis par l'utilisateur sur les tables du catalogue système ne sont pas supportés" + +#: catalog/index.c:809 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "les collationnements non-déterministes ne sont pas supportés pour la classe d'opérateurs « %s »" + +#: catalog/index.c:824 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "" +"la création en parallèle d'un index sur les tables du catalogue système\n" +"n'est pas supportée" + +#: catalog/index.c:833 catalog/index.c:1284 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "la création de manière concurrente d'un index pour les contraintes d'exclusion n'est pas supportée" + +#: catalog/index.c:842 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "les index partagés ne peuvent pas être créés après initdb" + +#: catalog/index.c:862 commands/createas.c:411 commands/sequence.c:154 parser/parse_utilcmd.c:201 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "la relation « %s » existe déjà, poursuite du traitement" + +#: catalog/index.c:912 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "OID de l'index de pg_class non configuré en mode de mise à jour binaire" + +#: catalog/index.c:2191 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY doit être la première action dans une transaction" + +#: catalog/index.c:3576 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "ne peut pas ré-indexer les tables temporaires des autres sessions" + +#: catalog/index.c:3587 commands/indexcmds.c:3426 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "ne peut pas réindexer un index invalide sur une table TOAST" + +#: catalog/index.c:3603 commands/indexcmds.c:3306 commands/indexcmds.c:3450 commands/tablecmds.c:3292 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "ne peut pas déplacer la colonne système « %s »" + +#: catalog/index.c:3747 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "l'index « %s » a été réindexée" + +#: catalog/index.c:3878 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "ne peut pas réindexer l'index invalide « %s.%s » sur une table TOAST, ignoré" + +#: catalog/namespace.c:258 catalog/namespace.c:462 catalog/namespace.c:554 commands/trigger.c:5134 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "les références entre bases de données ne sont pas implémentées : « %s.%s.%s »" + +#: catalog/namespace.c:315 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "les tables temporaires ne peuvent pas spécifier un nom de schéma" + +#: catalog/namespace.c:396 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "n'a pas pu obtenir un verrou sur la relation « %s.%s »" + +#: catalog/namespace.c:401 commands/lockcmds.c:143 commands/lockcmds.c:228 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "n'a pas pu obtenir un verrou sur la relation « %s »" + +#: catalog/namespace.c:429 parser/parse_relation.c:1362 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "la relation « %s.%s » n'existe pas" + +#: catalog/namespace.c:434 parser/parse_relation.c:1375 parser/parse_relation.c:1383 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "la relation « %s » n'existe pas" + +#: catalog/namespace.c:500 catalog/namespace.c:3075 commands/extension.c:1520 commands/extension.c:1526 +#, c-format +msgid "no schema has been selected to create in" +msgstr "aucun schéma n'a été sélectionné pour cette création" + +#: catalog/namespace.c:652 catalog/namespace.c:665 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "ne peut pas créer les relations dans les schémas temporaires d'autres sessions" + +#: catalog/namespace.c:656 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "ne peut pas créer une relation temporaire dans un schéma non temporaire" + +#: catalog/namespace.c:671 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "seules les relations temporaires peuvent être créées dans des schémas temporaires" + +#: catalog/namespace.c:2267 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "l'objet statistique « %s » n'existe pas" + +#: catalog/namespace.c:2390 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "l'analyseur de recherche plein texte « %s » n'existe pas" + +#: catalog/namespace.c:2516 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "le dictionnaire de recherche plein texte « %s » n'existe pas" + +#: catalog/namespace.c:2643 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "le modèle de recherche plein texte « %s » n'existe pas" + +#: catalog/namespace.c:2769 commands/tsearchcmds.c:1121 utils/cache/ts_cache.c:613 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "la configuration de recherche plein texte « %s » n'existe pas" + +#: catalog/namespace.c:2882 parser/parse_expr.c:810 parser/parse_target.c:1256 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "les références entre bases de données ne sont pas implémentées : %s" + +#: catalog/namespace.c:2888 gram.y:15102 gram.y:17061 parser/parse_expr.c:817 parser/parse_target.c:1263 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "mauvaise qualification du nom (trop de points entre les noms) : %s" + +#: catalog/namespace.c:3018 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "ne peut pas déplacer les objets dans ou à partir des schémas temporaires" + +#: catalog/namespace.c:3024 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "ne peut pas déplacer les objets dans ou à partir des schémas TOAST" + +#: catalog/namespace.c:3097 commands/schemacmds.c:234 commands/schemacmds.c:314 commands/tablecmds.c:1243 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "le schéma « %s » n'existe pas" + +#: catalog/namespace.c:3128 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "nom de relation incorrecte (trop de points entre les noms) : %s" + +#: catalog/namespace.c:3691 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "le collationnement « %s » pour l'encodage « %s » n'existe pas" + +#: catalog/namespace.c:3746 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "la conversion « %s » n'existe pas" + +#: catalog/namespace.c:4010 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "droit refusé pour la création de tables temporaires dans la base de données « %s »" + +#: catalog/namespace.c:4026 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "ne peut pas créer des tables temporaires lors de la restauration" + +#: catalog/namespace.c:4032 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "ne peut pas créer de tables temporaires pendant une opération parallèle" + +#: catalog/namespace.c:4331 commands/tablespace.c:1217 commands/variable.c:64 utils/misc/guc.c:11585 utils/misc/guc.c:11663 +#, c-format +msgid "List syntax is invalid." +msgstr "La syntaxe de la liste est invalide." + +#: catalog/objectaddress.c:1370 catalog/pg_publication.c:57 commands/policy.c:96 commands/policy.c:376 commands/policy.c:465 commands/tablecmds.c:243 commands/tablecmds.c:285 commands/tablecmds.c:2145 commands/tablecmds.c:6015 commands/tablecmds.c:11672 +#, c-format +msgid "\"%s\" is not a table" +msgstr "« %s » n'est pas une table" + +#: catalog/objectaddress.c:1377 commands/tablecmds.c:255 commands/tablecmds.c:6045 commands/tablecmds.c:16470 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "« %s » n'est pas une vue" + +#: catalog/objectaddress.c:1384 commands/matview.c:175 commands/tablecmds.c:261 commands/tablecmds.c:16475 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "« %s » n'est pas une vue matérialisée" + +#: catalog/objectaddress.c:1391 commands/tablecmds.c:279 commands/tablecmds.c:6048 commands/tablecmds.c:16480 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "« %s » n'est pas une table distante" + +#: catalog/objectaddress.c:1432 +#, c-format +msgid "must specify relation and object name" +msgstr "doit indiquer les noms de relation et d'objet" + +#: catalog/objectaddress.c:1508 catalog/objectaddress.c:1561 +#, c-format +msgid "column name must be qualified" +msgstr "le nom de la colonne doit être qualifié" + +#: catalog/objectaddress.c:1608 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "la valeur par défaut de la colonne « %s » de la relation « %s » n'existe pas" + +#: catalog/objectaddress.c:1645 commands/functioncmds.c:137 commands/tablecmds.c:271 commands/typecmds.c:274 commands/typecmds.c:3713 parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:791 utils/adt/acl.c:4411 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "le type « %s » n'existe pas" + +#: catalog/objectaddress.c:1764 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "l'opérateur %d (%s, %s) de %s n'existe pas" + +#: catalog/objectaddress.c:1795 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "la fonction %d (%s, %s) de %s n'existe pas" + +#: catalog/objectaddress.c:1846 catalog/objectaddress.c:1872 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "la correspondance pour l'utilisateur « %s » sur le serveur « %s » n'existe pas" + +#: catalog/objectaddress.c:1861 commands/foreigncmds.c:430 commands/foreigncmds.c:988 commands/foreigncmds.c:1347 foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "le serveur « %s » n'existe pas" + +#: catalog/objectaddress.c:1928 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "la relation de publication « %s » dans la publication « %s » n'existe pas" + +#: catalog/objectaddress.c:1990 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "type d'objet de droits par défaut non reconnu « %c »" + +#: catalog/objectaddress.c:1991 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Les types d'objet valides sont « %c », « %c », « %c », « %c », « %c »." + +#: catalog/objectaddress.c:2042 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "le droit par défaut pour l'utilisateur « %s » dans le schéma « %s » de %s n'existe pas" + +#: catalog/objectaddress.c:2047 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "le droit par défaut pour l'utilisateur « %s » sur %s n'existe pas" + +#: catalog/objectaddress.c:2074 catalog/objectaddress.c:2132 catalog/objectaddress.c:2189 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "le nom ou les listes d'arguments ne peuvent pas contenir de valeurs NULL" + +#: catalog/objectaddress.c:2108 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "type d'objet « %s » non supporté" + +#: catalog/objectaddress.c:2128 catalog/objectaddress.c:2146 catalog/objectaddress.c:2287 +#, c-format +msgid "name list length must be exactly %d" +msgstr "la liste de nom doit être exactement de longueur %d" + +#: catalog/objectaddress.c:2150 +#, c-format +msgid "large object OID may not be null" +msgstr "l'OID du Large Object peut ne pas être NULL" + +#: catalog/objectaddress.c:2159 catalog/objectaddress.c:2222 catalog/objectaddress.c:2229 +#, c-format +msgid "name list length must be at least %d" +msgstr "la longueur de la liste de nom doit au moins être %d" + +#: catalog/objectaddress.c:2215 catalog/objectaddress.c:2236 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "la longueur de la liste d'arguments doit être %d exactement" + +#: catalog/objectaddress.c:2488 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "doit être le propriétaire du Large Object %u" + +#: catalog/objectaddress.c:2503 commands/functioncmds.c:1581 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "doit être le propriétaire du type %s ou du type %s" + +#: catalog/objectaddress.c:2553 catalog/objectaddress.c:2570 +#, c-format +msgid "must be superuser" +msgstr "doit être super-utilisateur" + +#: catalog/objectaddress.c:2560 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "doit avoir l'attribut CREATEROLE" + +#: catalog/objectaddress.c:2639 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "type d'objet non reconnu « %s »" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2882 +#, c-format +msgid "column %s of %s" +msgstr "colonne %s de %s" + +#: catalog/objectaddress.c:2897 +#, c-format +msgid "function %s" +msgstr "fonction %s" + +#: catalog/objectaddress.c:2910 +#, c-format +msgid "type %s" +msgstr "type %s" + +#: catalog/objectaddress.c:2947 +#, c-format +msgid "cast from %s to %s" +msgstr "conversion de %s en %s" + +#: catalog/objectaddress.c:2980 +#, c-format +msgid "collation %s" +msgstr "collationnement %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3011 +#, c-format +msgid "constraint %s on %s" +msgstr "contrainte %s sur %s" + +#: catalog/objectaddress.c:3017 +#, c-format +msgid "constraint %s" +msgstr "contrainte %s" + +#: catalog/objectaddress.c:3049 +#, c-format +msgid "conversion %s" +msgstr "conversion %s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:3095 +#, c-format +msgid "default value for %s" +msgstr "valeur par défaut pour %s" + +#: catalog/objectaddress.c:3109 +#, c-format +msgid "language %s" +msgstr "langage %s" + +#: catalog/objectaddress.c:3117 +#, c-format +msgid "large object %u" +msgstr "« Large Object » %u" + +#: catalog/objectaddress.c:3130 +#, c-format +msgid "operator %s" +msgstr "opérateur %s" + +#: catalog/objectaddress.c:3167 +#, c-format +msgid "operator class %s for access method %s" +msgstr "classe d'opérateur %s pour la méthode d'accès %s" + +#: catalog/objectaddress.c:3195 +#, c-format +msgid "access method %s" +msgstr "méthode d'accès %s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3244 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "opérateur %d (%s, %s) de %s : %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3301 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "fonction %d (%s, %s) de %s : %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3353 +#, c-format +msgid "rule %s on %s" +msgstr "règle %s sur %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3399 +#, c-format +msgid "trigger %s on %s" +msgstr "trigger %s sur %s" + +#: catalog/objectaddress.c:3419 +#, c-format +msgid "schema %s" +msgstr "schéma %s" + +#: catalog/objectaddress.c:3447 +#, c-format +msgid "statistics object %s" +msgstr "objet statistique %s" + +#: catalog/objectaddress.c:3478 +#, c-format +msgid "text search parser %s" +msgstr "analyseur %s de la recherche plein texte" + +#: catalog/objectaddress.c:3509 +#, c-format +msgid "text search dictionary %s" +msgstr "dictionnaire %s de la recherche plein texte" + +#: catalog/objectaddress.c:3540 +#, c-format +msgid "text search template %s" +msgstr "modèle %s de la recherche plein texte" + +#: catalog/objectaddress.c:3571 +#, c-format +msgid "text search configuration %s" +msgstr "configuration %s de recherche plein texte" + +#: catalog/objectaddress.c:3584 +#, c-format +msgid "role %s" +msgstr "rôle %s" + +#: catalog/objectaddress.c:3600 +#, c-format +msgid "database %s" +msgstr "base de données %s" + +#: catalog/objectaddress.c:3616 +#, c-format +msgid "tablespace %s" +msgstr "tablespace %s" + +#: catalog/objectaddress.c:3627 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "wrapper de données distantes %s" + +#: catalog/objectaddress.c:3637 +#, c-format +msgid "server %s" +msgstr "serveur %s" + +#: catalog/objectaddress.c:3670 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "correspondance utilisateur pour %s sur le serveur %s" + +#: catalog/objectaddress.c:3722 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouvelles relations appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3726 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "droits par défaut pour les nouvelles relations appartenant au rôle %s" + +#: catalog/objectaddress.c:3732 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouvelles séquences appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3736 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "droits par défaut pour les nouvelles séquences appartenant au rôle %s" + +#: catalog/objectaddress.c:3742 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouvelles fonctions appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3746 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "droits par défaut pour les nouvelles fonctions appartenant au rôle %s" + +#: catalog/objectaddress.c:3752 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouveaux types appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3756 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "droits par défaut pour les nouveaux types appartenant au rôle %s" + +#: catalog/objectaddress.c:3762 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "droits par défaut pour les nouveaux schémas appartenant au rôle %s" + +#: catalog/objectaddress.c:3769 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "droits par défaut appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3773 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "droits par défaut appartenant au rôle %s" + +#: catalog/objectaddress.c:3795 +#, c-format +msgid "extension %s" +msgstr "extension %s" + +#: catalog/objectaddress.c:3812 +#, c-format +msgid "event trigger %s" +msgstr "trigger sur événement %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3856 +#, c-format +msgid "policy %s on %s" +msgstr "politique %s sur %s" + +#: catalog/objectaddress.c:3870 +#, c-format +msgid "publication %s" +msgstr "publication %s" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3898 +#, c-format +msgid "publication of %s in publication %s" +msgstr "publication de %s dans la publication %s" + +#: catalog/objectaddress.c:3911 +#, c-format +msgid "subscription %s" +msgstr "souscription %s" + +#: catalog/objectaddress.c:3932 +#, c-format +msgid "transform for %s language %s" +msgstr "transformation pour %s langage %s" + +#: catalog/objectaddress.c:4003 +#, c-format +msgid "table %s" +msgstr "table %s" + +#: catalog/objectaddress.c:4008 +#, c-format +msgid "index %s" +msgstr "index %s" + +#: catalog/objectaddress.c:4012 +#, c-format +msgid "sequence %s" +msgstr "séquence %s" + +#: catalog/objectaddress.c:4016 +#, c-format +msgid "toast table %s" +msgstr "table TOAST %s" + +#: catalog/objectaddress.c:4020 +#, c-format +msgid "view %s" +msgstr "vue %s" + +#: catalog/objectaddress.c:4024 +#, c-format +msgid "materialized view %s" +msgstr "vue matérialisée %s" + +#: catalog/objectaddress.c:4028 +#, c-format +msgid "composite type %s" +msgstr "type composite %s" + +#: catalog/objectaddress.c:4032 +#, c-format +msgid "foreign table %s" +msgstr "table distante %s" + +#: catalog/objectaddress.c:4037 +#, c-format +msgid "relation %s" +msgstr "relation %s" + +#: catalog/objectaddress.c:4078 +#, c-format +msgid "operator family %s for access method %s" +msgstr "famille d'opérateur %s pour la méthode d'accès %s" + +#: catalog/pg_aggregate.c:129 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "les agrégats ne peuvent avoir plus de %d argument" +msgstr[1] "les agrégats ne peuvent avoir plus de %d arguments" + +#: catalog/pg_aggregate.c:144 catalog/pg_aggregate.c:158 +#, c-format +msgid "cannot determine transition data type" +msgstr "n'a pas pu déterminer le type de données de transition" + +#: catalog/pg_aggregate.c:173 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "un agrégat à ensemble trié variadique doit être VARIADIC sur le type ANY" + +#: catalog/pg_aggregate.c:199 +#, c-format +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" +msgstr "un agrégat d'ensemble hypothétique doit avoir des arguments directs correspondant aux arguments agrégés" + +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "le type de retour de la fonction de transition %s n'est pas %s" + +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 +#, c-format +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" +msgstr "" +"ne doit pas omettre la valeur initiale lorsque la fonction de transition est\n" +"stricte et que le type de transition n'est pas compatible avec le type en\n" +"entrée" + +#: catalog/pg_aggregate.c:335 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "le type de retour de la fonction de transition inverse %s n'est pas %s" + +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2852 +#, c-format +msgid "strictness of aggregate's forward and inverse transition functions must match" +msgstr "la fonction de transition d'agrégat en déplacement ne doit pas renvoyer null" + +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:554 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "la fonction finale avec des arguments supplémentaires ne doit pas être déclarée avec la clause STRICT" + +#: catalog/pg_aggregate.c:427 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "le type de retour de la fonction de d'unification %s n'est pas %s" + +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:4128 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "la fonction d'unification avec le type de transaction %s ne doit pas être déclaré STRICT" + +#: catalog/pg_aggregate.c:458 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "le type de retour de la fonction de sérialisation %s n'est pas %s" + +#: catalog/pg_aggregate.c:479 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "le type de retour de la fonction de désérialisation %s n'est pas %s" + +#: catalog/pg_aggregate.c:498 catalog/pg_proc.c:189 catalog/pg_proc.c:223 +#, c-format +msgid "cannot determine result data type" +msgstr "n'a pas pu déterminer le type de données en résultat" + +#: catalog/pg_aggregate.c:513 catalog/pg_proc.c:202 catalog/pg_proc.c:231 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "utilisation non sûre des pseudo-types « INTERNAL »" + +#: catalog/pg_aggregate.c:567 +#, c-format +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" +msgstr "l'impémentation d'aggrégat glissant retourne le type %s, mais l'implémentation standard retourne le type %s" + +#: catalog/pg_aggregate.c:578 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "l'opérateur de tri peut seulement être indiqué pour des agrégats à un seul argument" + +#: catalog/pg_aggregate.c:706 catalog/pg_proc.c:384 +#, c-format +msgid "cannot change routine kind" +msgstr "ne peut pas modifier le type de routine" + +#: catalog/pg_aggregate.c:708 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "« %s » est une fonction d'agrégat ordinaire." + +#: catalog/pg_aggregate.c:710 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "« %s » est un agrégat d'ensemble trié." + +#: catalog/pg_aggregate.c:712 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "« %s » est un agrégat d'ensemble hypothétique." + +#: catalog/pg_aggregate.c:717 +#, c-format +msgid "cannot change number of direct arguments of an aggregate function" +msgstr "ne peut pas changer le nombre d'arguments directs d'une fonction d'agrégation" + +#: catalog/pg_aggregate.c:858 commands/functioncmds.c:701 commands/typecmds.c:1992 commands/typecmds.c:2038 commands/typecmds.c:2090 commands/typecmds.c:2127 commands/typecmds.c:2161 commands/typecmds.c:2195 commands/typecmds.c:2229 commands/typecmds.c:2258 commands/typecmds.c:2345 commands/typecmds.c:2387 parser/parse_func.c:417 parser/parse_func.c:448 parser/parse_func.c:475 parser/parse_func.c:489 parser/parse_func.c:611 parser/parse_func.c:631 parser/parse_func.c:2173 parser/parse_func.c:2446 +#, c-format +msgid "function %s does not exist" +msgstr "la fonction %s n'existe pas" + +#: catalog/pg_aggregate.c:864 +#, c-format +msgid "function %s returns a set" +msgstr "la fonction %s renvoie un ensemble" + +#: catalog/pg_aggregate.c:879 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "la fonction %s doit accepter VARIADIC ANY pour être utilisé dans cet agrégat" + +#: catalog/pg_aggregate.c:903 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "la fonction %s requiert une coercion sur le type à l'exécution" + +#: catalog/pg_cast.c:68 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "la conversion du type %s vers le type %s existe déjà" + +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "le collationnement « %s » existe déjà, poursuite du traitement" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "le collationnement « %s » pour l'encodage « %s » existe déjà, poursuite du traitement" + +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "le collationnement « %s » existe déjà" + +#: catalog/pg_collation.c:105 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "le collationnement « %s » pour l'encodage « %s » existe déjà" + +#: catalog/pg_constraint.c:678 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "la contrainte « %s » du domaine %s existe déjà" + +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "la contrainte « %s » de la table « %s » n'existe pas" + +#: catalog/pg_constraint.c:1056 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "la contrainte « %s » du domaine %s n'existe pas" + +#: catalog/pg_conversion.c:67 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "la conversion « %s » existe déjà" + +#: catalog/pg_conversion.c:80 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "la conversion par défaut de %s vers %s existe déjà" + +#: catalog/pg_depend.c:204 commands/extension.c:3344 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "%s est déjà un membre de l'extension « %s »" + +#: catalog/pg_depend.c:580 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "ne peut pas supprimer la dépendance sur %s car il s'agit d'un objet système" + +#: catalog/pg_enum.c:128 catalog/pg_enum.c:230 catalog/pg_enum.c:525 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "nom du label enum « %s » invalide" + +#: catalog/pg_enum.c:129 catalog/pg_enum.c:231 catalog/pg_enum.c:526 +#, c-format +msgid "Labels must be %d bytes or less." +msgstr "Les labels doivent avoir au plus %d caractères." + +#: catalog/pg_enum.c:259 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "le label « %s » existe déjà, poursuite du traitement" + +#: catalog/pg_enum.c:266 catalog/pg_enum.c:569 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "le label « %s » existe déjà" + +#: catalog/pg_enum.c:321 catalog/pg_enum.c:564 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "« %s » n'est pas un label d'enum existant" + +#: catalog/pg_enum.c:379 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "OID de pg_enum non configuré en mode de mise à jour binaire" + +#: catalog/pg_enum.c:389 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "ALTER TYPE ADD BEFORE/AFTER est incompatible avec la mise à jour binaire" + +#: catalog/pg_inherits.c:593 +#, c-format +msgid "cannot detach partition \"%s\"" +msgstr "ne peut pas détacher la partition « %s »" + +#: catalog/pg_inherits.c:595 +#, c-format +msgid "The partition is being detached concurrently or has an unfinished detach." +msgstr "La partition est en cours de détachement ou à un détachement non terminé." + +#: catalog/pg_inherits.c:596 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation" +msgstr "Utilisez ALTER TABLE ... DETACH PARTITION ... FINALIZE pour terminer l'opération de détachement en attente" + +#: catalog/pg_inherits.c:600 +#, c-format +msgid "cannot complete detaching partition \"%s\"" +msgstr "ne peut pas terminer le détachement de la partition « %s »" + +#: catalog/pg_inherits.c:602 +#, c-format +msgid "There's no pending concurrent detach." +msgstr "Il n'y a pas de détachement en attente." + +#: catalog/pg_namespace.c:64 commands/schemacmds.c:243 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "le schéma « %s » existe déjà" + +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "« %s » n'est pas un nom d'opérateur valide" + +#: catalog/pg_operator.c:370 +#, c-format +msgid "only binary operators can have commutators" +msgstr "seuls les opérateurs binaires peuvent avoir des commutateurs" + +#: catalog/pg_operator.c:374 commands/operatorcmds.c:507 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "seuls les opérateurs binaires peuvent avoir une sélectivité des jointures" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can merge join" +msgstr "seuls les opérateurs binaires peuvent exécuter des jointures MERGE" + +#: catalog/pg_operator.c:382 +#, c-format +msgid "only binary operators can hash" +msgstr "seuls les opérateurs binaires ont du hachage" + +#: catalog/pg_operator.c:393 +#, c-format +msgid "only boolean operators can have negators" +msgstr "seuls les opérateurs booléens peuvent avoir des négations" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:515 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "seuls les opérateurs booléens peuvent avoir une sélectivité des restrictions" + +#: catalog/pg_operator.c:401 commands/operatorcmds.c:519 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "seuls les opérateurs booléens peuvent avoir une sélectivité des jointures" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can merge join" +msgstr "seuls les opérateurs booléens peuvent exécuter des jointures MERGE" + +#: catalog/pg_operator.c:409 +#, c-format +msgid "only boolean operators can hash" +msgstr "seuls les opérateurs booléens peuvent hacher" + +#: catalog/pg_operator.c:421 +#, c-format +msgid "operator %s already exists" +msgstr "l'opérateur %s existe déjà" + +#: catalog/pg_operator.c:621 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "l'opérateur ne peut pas être son propre opérateur de négation ou de tri" + +#: catalog/pg_proc.c:130 parser/parse_func.c:2235 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "les fonctions ne peuvent avoir plus de %d argument" +msgstr[1] "les fonctions ne peuvent avoir plus de %d arguments" + +#: catalog/pg_proc.c:374 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "la fonction « %s » existe déjà avec des types d'arguments identiques" + +#: catalog/pg_proc.c:386 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "« %s » est une fonction d'agrégat." + +#: catalog/pg_proc.c:388 +#, c-format +msgid "\"%s\" is a function." +msgstr "« %s » est une fonction." + +#: catalog/pg_proc.c:390 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "« %s » est une procédure." + +#: catalog/pg_proc.c:392 +#, c-format +msgid "\"%s\" is a window function." +msgstr "la fonction « %s » est une fonction window." + +#: catalog/pg_proc.c:412 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "ne peut pas changer le fait qu'une procédure ait des paramètres en sortie ou non" + +#: catalog/pg_proc.c:413 catalog/pg_proc.c:443 +#, c-format +msgid "cannot change return type of existing function" +msgstr "ne peut pas modifier le type de retour d'une fonction existante" + +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:419 catalog/pg_proc.c:446 catalog/pg_proc.c:491 catalog/pg_proc.c:517 catalog/pg_proc.c:543 +#, c-format +msgid "Use %s %s first." +msgstr "Utilisez tout d'abord %s %s." + +#: catalog/pg_proc.c:444 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "Le type de ligne défini par les paramètres OUT est différent." + +#: catalog/pg_proc.c:488 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "ne peut pas modifier le nom du paramètre en entrée « %s »" + +#: catalog/pg_proc.c:515 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "" +"ne peut pas supprimer les valeurs par défaut des paramètres de la\n" +"fonction existante" + +#: catalog/pg_proc.c:541 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "" +"ne peut pas modifier le type de données d'un paramètre avec une valeur\n" +"par défaut" + +#: catalog/pg_proc.c:751 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "il n'existe pas de fonction intégrée nommée « %s »" + +#: catalog/pg_proc.c:849 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "les fonctions SQL ne peuvent pas renvoyer un type %s" + +#: catalog/pg_proc.c:864 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "les fonctions SQL ne peuvent avoir d'arguments du type %s" + +#: catalog/pg_proc.c:976 executor/functions.c:1458 +#, c-format +msgid "SQL function \"%s\"" +msgstr "Fonction SQL « %s »" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Only tables can be added to publications." +msgstr "Seules des tables peuvent être ajoutées aux publications." + +#: catalog/pg_publication.c:65 +#, c-format +msgid "\"%s\" is a system table" +msgstr "« %s » est une table système" + +#: catalog/pg_publication.c:67 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "Les tables systèmes ne peuvent pas être ajoutées à une publication." + +#: catalog/pg_publication.c:73 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "la table « %s » ne peut pas être répliquée" + +#: catalog/pg_publication.c:75 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "Les tables tremporaires et les tables non journalisées ne peuvent pas être répliquées." + +#: catalog/pg_publication.c:174 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "la relation « %s » est déjà un membre de la publication « %s »" + +#: catalog/pg_publication.c:470 commands/publicationcmds.c:451 commands/publicationcmds.c:739 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "la publication « %s » n'existe pas" + +#: catalog/pg_shdepend.c:832 +#, c-format +msgid "" +"\n" +"and objects in %d other database (see server log for list)" +msgid_plural "" +"\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "" +"\n" +"et des objets dans %d autre base de données (voir le journal applicatif du serveur pour une liste)" +msgstr[1] "" +"\n" +"et des objets dans %d autres bases de données (voir le journal applicatif du serveur pour une liste)" + +#: catalog/pg_shdepend.c:1176 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "le rôle %u a été supprimé simultanément" + +#: catalog/pg_shdepend.c:1188 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "le tablespace %u a été supprimé simultanément" + +#: catalog/pg_shdepend.c:1202 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "la base de données %u a été supprimé simultanément" + +#: catalog/pg_shdepend.c:1247 +#, c-format +msgid "owner of %s" +msgstr "propriétaire de %s" + +#: catalog/pg_shdepend.c:1249 +#, c-format +msgid "privileges for %s" +msgstr "droits pour %s" + +#: catalog/pg_shdepend.c:1251 +#, c-format +msgid "target of %s" +msgstr "cible de %s" + +#: catalog/pg_shdepend.c:1253 +#, c-format +msgid "tablespace for %s" +msgstr "tablespace pour %s" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1261 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%d objet dans %s" +msgstr[1] "%d objets dans %s" + +#: catalog/pg_shdepend.c:1372 +#, c-format +msgid "cannot drop objects owned by %s because they are required by the database system" +msgstr "n'a pas pu supprimer les objets appartenant à %s car ils sont nécessaires au système de bases de données" + +#: catalog/pg_shdepend.c:1519 +#, c-format +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" +msgstr "" +"ne peut pas réaffecter les objets appartenant à %s car ils sont nécessaires au\n" +"système de bases de données" + +#: catalog/pg_subscription.c:174 commands/subscriptioncmds.c:777 commands/subscriptioncmds.c:1087 commands/subscriptioncmds.c:1430 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "la souscription « %s » n'existe pas" + +#: catalog/pg_subscription.c:432 +#, c-format +msgid "could not drop relation mapping for subscription \"%s\"" +msgstr "n'a pas pu supprimer la correspondance des relations pour la souscription « %s »" + +#: catalog/pg_subscription.c:434 +#, c-format +msgid "Table synchronization for relation \"%s\" is in progress and is in state \"%c\"." +msgstr "La synchronization de la table « %s » est en cours et est dans l'état « %c »." + +#. translator: first %s is a SQL ALTER command and second %s is a +#. SQL DROP command +#. +#: catalog/pg_subscription.c:441 +#, c-format +msgid "Use %s to enable subscription if not already enabled or use %s to drop the subscription." +msgstr "Utiliser %s pour activer la souscription si elle n'est pas déjà activée ou utiliser %s pour supprimer la souscription." + +#: catalog/pg_type.c:136 catalog/pg_type.c:475 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "OID de pg_type non configuré en mode de mise à jour binaire" + +#: catalog/pg_type.c:255 +#, c-format +msgid "invalid type internal size %d" +msgstr "taille interne de type invalide %d" + +#: catalog/pg_type.c:271 catalog/pg_type.c:279 catalog/pg_type.c:287 catalog/pg_type.c:296 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "l'alignement « %c » est invalide pour le type passé par valeur de taille %d" + +#: catalog/pg_type.c:303 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "la taille interne %d est invalide pour le type passé par valeur" + +#: catalog/pg_type.c:313 catalog/pg_type.c:319 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "l'alignement « %c » est invalide pour le type de longueur variable" + +#: catalog/pg_type.c:327 commands/typecmds.c:4164 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "les types de taille fixe doivent avoir un stockage de base" + +#: catalog/pg_type.c:816 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "n'a pas pu former le nom du type array pour le type de données « %s »" + +#: catalog/pg_type.c:921 +#, c-format +msgid "Failed while creating a multirange type for type \"%s\"." +msgstr "Échec lors de la création d'un type multirange pour le type « %s »." + +#: catalog/pg_type.c:922 +#, c-format +msgid "You can manually specify a multirange type name using the \"multirange_type_name\" attribute" +msgstr "Vous pouvez modifier manuellement un nom de type multirange en utilisant l'attribut « multirange_type_name »" + +#: catalog/storage.c:450 storage/buffer/bufmgr.c:1026 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "page invalide dans le bloc %u de la relation %s" + +#: catalog/toasting.c:104 commands/indexcmds.c:667 commands/tablecmds.c:6027 commands/tablecmds.c:16335 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "« %s » n'est ni une table ni une vue matérialisée" + +#: commands/aggregatecmds.c:170 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "seuls les agrégats à ensemble ordonné peuvent être hypothétiques" + +#: commands/aggregatecmds.c:195 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "l'attribut de l'agrégat « %s » n'est pas reconnu" + +#: commands/aggregatecmds.c:205 +#, c-format +msgid "aggregate stype must be specified" +msgstr "l'agrégat stype doit être spécifié" + +#: commands/aggregatecmds.c:209 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "l'agrégat sfunc doit être spécifié" + +#: commands/aggregatecmds.c:221 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "la fonction msfunc de l'agrégat doit être spécifiée quand mstype est spécifié" + +#: commands/aggregatecmds.c:225 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "la fonction minvfunc de l'agrégat doit être spécifiée quand mstype est spécifié" + +#: commands/aggregatecmds.c:232 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "la fonction msfunc de l'agrégat ne doit pas être spécifiée sans mstype" + +#: commands/aggregatecmds.c:236 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "la fonction minvfunc de l'agrégat ne doit pas être spécifiée sans mstype" + +#: commands/aggregatecmds.c:240 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "la fonction mfinalfunc de l'agrégat ne doit pas être spécifiée sans mstype" + +#: commands/aggregatecmds.c:244 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "la fonction msspace de l'agrégat ne doit pas être spécifiée sans mstype" + +#: commands/aggregatecmds.c:248 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "la fonction minitcond de l'agrégat ne doit pas être spécifiée sans mstype" + +#: commands/aggregatecmds.c:277 +#, c-format +msgid "aggregate input type must be specified" +msgstr "le type d'entrée de l'agrégat doit être précisé" + +#: commands/aggregatecmds.c:307 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "le type de base est redondant avec la spécification du type en entrée de l'agrégat" + +#: commands/aggregatecmds.c:350 commands/aggregatecmds.c:391 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "le type de données de transition de l'agrégat ne peut pas être %s" + +#: commands/aggregatecmds.c:362 +#, c-format +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "les fonctions de sérialisation ne peuvent être spécifiées que quand le type de données des transitions d'aggrégat est %s" + +#: commands/aggregatecmds.c:372 +#, c-format +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "doit spécifier soit toutes soit aucunes des fonctions de sérialisation et désérialisation" + +#: commands/aggregatecmds.c:437 commands/functioncmds.c:649 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "le paramètre « parallel » doit être SAFE, RESTRICTED ou UNSAFE" + +#: commands/aggregatecmds.c:493 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "le paramètre « %s » doit être READ_ONLY, SHAREABLE, ou READ_WRITE" + +#: commands/alter.c:84 commands/event_trigger.c:174 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "le trigger sur événement « %s » existe déjà" + +#: commands/alter.c:87 commands/foreigncmds.c:597 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "le wrapper de données distantes « %s » existe déjà" + +#: commands/alter.c:90 commands/foreigncmds.c:879 +#, c-format +msgid "server \"%s\" already exists" +msgstr "le serveur « %s » existe déjà" + +#: commands/alter.c:93 commands/proclang.c:133 +#, c-format +msgid "language \"%s\" already exists" +msgstr "le langage « %s » existe déjà" + +#: commands/alter.c:96 commands/publicationcmds.c:183 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "la publication « %s » existe déjà" + +#: commands/alter.c:99 commands/subscriptioncmds.c:398 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "la souscription « %s » existe déjà" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "la conversion « %s » existe déjà dans le schéma « %s »" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "l'objet statistique « %s » existe déjà dans le schéma « %s »" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr "l'analyseur de recherche plein texte « %s » existe déjà dans le schéma « %s »" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "le dictionnaire de recherche plein texte « %s » existe déjà dans le schéma « %s »" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "le modèle de recherche plein texte « %s » existe déjà dans le schéma « %s »" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "la configuration de recherche plein texte « %s » existe déjà dans le schéma « %s »" + +#: commands/alter.c:215 +#, c-format +msgid "must be superuser to rename %s" +msgstr "doit être super-utilisateur pour renommer « %s »" + +#: commands/alter.c:744 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "doit être super-utilisateur pour configurer le schéma de %s" + +#: commands/amcmds.c:60 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "droit refusé pour créer la méthode d'accès « %s »" + +#: commands/amcmds.c:62 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "Doit être super-utilisateur pour créer une méthode d'accès." + +#: commands/amcmds.c:71 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "la méthode d'accès « %s » existe déjà" + +#: commands/amcmds.c:154 commands/indexcmds.c:210 commands/indexcmds.c:818 commands/opclasscmds.c:370 commands/opclasscmds.c:824 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "la méthode d'accès « %s » n'existe pas" + +#: commands/amcmds.c:243 +#, c-format +msgid "handler function is not specified" +msgstr "la fonction handler n'est pas spécifiée" + +#: commands/amcmds.c:264 commands/event_trigger.c:183 commands/foreigncmds.c:489 commands/proclang.c:80 commands/trigger.c:681 parser/parse_clause.c:940 +#, c-format +msgid "function %s must return type %s" +msgstr "la fonction %s doit renvoyer le type %s" + +#: commands/analyze.c:227 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "ignore « %s » --- ne peut pas analyser cette table distante" + +#: commands/analyze.c:244 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "ignore « %s » --- ne peut pas analyser les objets autres que les tables et les tables système" + +# ereport(elevel, +# (errmsg("analyzing \"%s.%s\" inheritance tree", +# get_namespace_name(RelationGetNamespace(onerel)), +# RelationGetRelationName(onerel)))); +#: commands/analyze.c:324 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "analyse de l'arbre d'héritage de « %s.%s »" + +#: commands/analyze.c:329 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "analyse « %s.%s »" + +#: commands/analyze.c:395 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "la colonne « %s » de la relation « %s » apparait plus d'une fois" + +#: commands/analyze.c:790 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"\n" +msgstr "ANALYZE automatique de la table « %s.%s.%s »\n" + +#: commands/analyze.c:811 +#, c-format +msgid "system usage: %s" +msgstr "utilisation du système : %s" + +#: commands/analyze.c:1350 +#, c-format +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "« %s » : %d pages parcourues parmi %u, contenant %.0f lignes à conserver et %.0f lignes à supprimer ; %d lignes dans l'échantillon, %.0f lignes totales estimées" + +#: commands/analyze.c:1430 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "ignore l'analyse de l'arbre d'héritage « %s.%s » --- cet arbre d'héritage ne contient pas de tables enfants" + +#: commands/analyze.c:1528 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "ignore l'analyse de l'arbre d'héritage « %s.%s » --- cet arbre d'héritage ne contient pas de tables enfants analysables" + +#: commands/async.c:639 +#, c-format +msgid "channel name cannot be empty" +msgstr "le nom du canal ne peut pas être vide" + +#: commands/async.c:645 +#, c-format +msgid "channel name too long" +msgstr "nom du canal trop long" + +#: commands/async.c:650 +#, c-format +msgid "payload string too long" +msgstr "chaîne de charge trop longue" + +#: commands/async.c:869 +#, c-format +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "" +"ne peut pas exécuter PREPARE sur une transaction qui a exécuté LISTEN,\n" +"UNLISTEN ou NOTIFY" + +#: commands/async.c:975 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "trop de notifications dans la queue NOTIFY" + +#: commands/async.c:1646 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "la queue NOTIFY est pleine à %.0f%%" + +#: commands/async.c:1648 +#, c-format +msgid "The server process with PID %d is among those with the oldest transactions." +msgstr "Le processus serveur de PID %d est parmi ceux qui ont les transactions les plus anciennes." + +#: commands/async.c:1651 +#, c-format +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." +msgstr "" +"La queue NOTIFY ne peut pas être vidée jusqu'à ce que le processus finisse\n" +"sa transaction en cours." + +#: commands/cluster.c:119 +#, c-format +msgid "unrecognized CLUSTER option \"%s\"" +msgstr "option de CLUSTER « %s » non reconnue" + +#: commands/cluster.c:147 commands/cluster.c:386 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "ne peut pas exécuter CLUSTER sur les tables temporaires des autres sessions" + +#: commands/cluster.c:155 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "ne peut pas exécuter CLUSTER sur une table partitionnée" + +#: commands/cluster.c:173 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "il n'y a pas d'index CLUSTER précédent pour la table « %s »" + +#: commands/cluster.c:187 commands/tablecmds.c:13495 commands/tablecmds.c:15363 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "l'index « %s » pour la table « %s » n'existe pas" + +#: commands/cluster.c:375 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "ne peut pas exécuter CLUSTER sur un catalogue partagé" + +#: commands/cluster.c:390 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "ne peut pas exécuter VACUUM sur les tables temporaires des autres sessions" + +#: commands/cluster.c:456 commands/tablecmds.c:15373 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "« %s » n'est pas un index de la table « %s »" + +#: commands/cluster.c:464 +#, c-format +msgid "cannot cluster on index \"%s\" because access method does not support clustering" +msgstr "" +"ne peut pas exécuter CLUSTER sur l'index « %s » car la méthode d'accès de\n" +"l'index ne gère pas cette commande" + +#: commands/cluster.c:476 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "ne peut pas exécuter CLUSTER sur l'index partiel « %s »" + +#: commands/cluster.c:490 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "ne peut pas exécuter la commande CLUSTER sur l'index invalide « %s »" + +#: commands/cluster.c:514 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "ne peut pas marquer un index comme CLUSTER sur une table partitionnée" + +#: commands/cluster.c:887 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr "cluster sur « %s.%s » en utilisant un parcours d'index sur « %s »" + +#: commands/cluster.c:893 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "cluster sur « %s.%s » en utilisant un parcours séquentiel puis un tri" + +#: commands/cluster.c:924 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "« %s » : %.0f versions de ligne supprimables, %.0f non supprimables, dans %u pages" + +#: commands/cluster.c:928 +#, c-format +msgid "" +"%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "" +"%.0f versions de lignes ne peuvent pas encore être supprimées.\n" +"%s." + +#: commands/collationcmds.c:106 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "attribut de collationnement « %s » non reconnu" + +#: commands/collationcmds.c:149 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "le collationnement « default » ne peut pas être copié" + +#: commands/collationcmds.c:182 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "fournisseur de collationnement non reconnu : %s" + +#: commands/collationcmds.c:191 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "le paramètre « lc_collate » doit être spécifié" + +#: commands/collationcmds.c:196 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "le paramètre « lc_ctype » doit être spécifié" + +#: commands/collationcmds.c:206 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "les collationnements non déterministes ne sont pas supportés avec ce fournisseur" + +#: commands/collationcmds.c:266 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "le collationnament « %s » pour l'encodage « %s » existe déjà dans le schéma « %s »" + +#: commands/collationcmds.c:277 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "le collationnement « %s » existe déjà dans le schéma « %s »" + +#: commands/collationcmds.c:325 +#, c-format +msgid "changing version from %s to %s" +msgstr "changement de version de %s à %s" + +#: commands/collationcmds.c:340 +#, c-format +msgid "version has not changed" +msgstr "la version n'a pas changé" + +#: commands/collationcmds.c:454 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "n'a pas pu convertir le nom de locale « %s » en balise de langage : %s" + +#: commands/collationcmds.c:512 +#, c-format +msgid "must be superuser to import system collations" +msgstr "doit être super-utilisateur pour importer les collationnements systèmes" + +#: commands/collationcmds.c:540 commands/copyfrom.c:1500 commands/copyto.c:682 libpq/be-secure-common.c:81 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "n'a pas pu exécuter la commande « %s » : %m" + +#: commands/collationcmds.c:671 +#, c-format +msgid "no usable system locales were found" +msgstr "aucune locale système utilisable n'a été trouvée" + +#: commands/comment.c:61 commands/dbcommands.c:841 commands/dbcommands.c:1037 commands/dbcommands.c:1150 commands/dbcommands.c:1340 commands/dbcommands.c:1588 commands/dbcommands.c:1702 commands/dbcommands.c:2142 utils/init/postinit.c:887 utils/init/postinit.c:992 utils/init/postinit.c:1009 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "la base de données « %s » n'existe pas" + +#: commands/comment.c:101 commands/seclabel.c:191 parser/parse_utilcmd.c:979 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "« %s » n'est ni une table, ni une vue, ni une vue matérialisée, ni un type composite, ni une table distante" + +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1948 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "la fonction « %s » n'a pas été appelée par le gestionnaire de triggers" + +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1957 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "la fonction « %s » doit être exécutée pour l'instruction AFTER ROW" + +#: commands/constraint.c:84 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "la fonction « %s » doit être exécutée pour les instructions INSERT ou UPDATE" + +#: commands/conversioncmds.c:67 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "le codage source « %s » n'existe pas" + +#: commands/conversioncmds.c:74 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "l'encodage de destination « %s » n'existe pas" + +#: commands/conversioncmds.c:87 +#, c-format +msgid "encoding conversion to or from \"SQL_ASCII\" is not supported" +msgstr "la conversion de l'encodage de ou vers « SQL_ASCII » n'est pas supportée" + +#: commands/conversioncmds.c:100 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "la fonction de conversion d'encodage %s doit renvoyer le type %s" + +#: commands/conversioncmds.c:130 +#, c-format +msgid "encoding conversion function %s returned incorrect result for empty input" +msgstr "la fonction de conversion d'encodage %s a renvoyé un résultat incorrect pour l'entrée vide" + +#: commands/copy.c:86 +#, c-format +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "doit être super-utilisateur ou membre du rôle pg_execute_server_program pour utiliser COPY avec un programme externe" + +#: commands/copy.c:87 commands/copy.c:96 commands/copy.c:103 +#, c-format +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." +msgstr "Tout le monde peut utiliser COPY vers stdout ou à partir de stdin. La commande \\copy de psql fonctionne aussi pour tout le monde." + +#: commands/copy.c:95 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "doit être super-utilisateur ou membre du rôle pg_read_all_settings pour utiliser COPY depuis un fichier" + +#: commands/copy.c:102 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "doit être super-utilisateur ou membre de pg_read_all_settings pour utiliser COPY vers un fichier" + +#: commands/copy.c:188 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM non supporté avec la sécurité niveau ligne" + +#: commands/copy.c:189 +#, c-format +msgid "Use INSERT statements instead." +msgstr "Utilisez des instructions INSERT à la place." + +#: commands/copy.c:374 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "format COPY « %s » non reconnu" + +#: commands/copy.c:447 commands/copy.c:463 commands/copy.c:478 commands/copy.c:500 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "l'argument de l'option « %s » doit être une liste de noms de colonnes" + +#: commands/copy.c:515 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "l'argument de l'option « %s » doit être un nom d'encodage valide" + +#: commands/copy.c:522 commands/dbcommands.c:253 commands/dbcommands.c:1536 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "option « %s » non reconnue" + +#: commands/copy.c:534 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "ne peut pas spécifier le délimiteur (DELIMITER) en mode binaire (BINARY)" + +#: commands/copy.c:539 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "ne peut pas spécifier NULL en mode binaire (BINARY)" + +#: commands/copy.c:561 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "le délimiteur COPY doit être un seul caractère d'un octet" + +#: commands/copy.c:568 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "le délimiteur de COPY ne peut pas être un retour à la ligne ou un retour chariot" + +#: commands/copy.c:574 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "la représentation du NULL dans COPY ne peut pas utiliser un retour à la ligne ou un retour chariot" + +#: commands/copy.c:591 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "le délimiteur de COPY ne peut pas être « %s »" + +#: commands/copy.c:597 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "COPY HEADER disponible uniquement en mode CSV" + +#: commands/copy.c:603 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "le guillemet dans COPY n'est disponible que dans le mode CSV" + +#: commands/copy.c:608 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "le guillemet dans COPY doit être un seul caractère d'un octet" + +#: commands/copy.c:613 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "le délimiteur de COPY ne doit pas être un guillemet" + +#: commands/copy.c:619 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "le caractère d'échappement COPY n'est disponible que dans le mode CSV" + +#: commands/copy.c:624 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "le caractère d'échappement COPY doit être un seul caractère d'un octet" + +#: commands/copy.c:630 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "le guillemet forcé COPY n'est disponible que dans le mode CSV" + +#: commands/copy.c:634 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "le guillemet forcé pour COPY n'est disponible qu'en utilisant COPY TO" + +#: commands/copy.c:640 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "« COPY force not null » n'est disponible que dans la version CSV" + +#: commands/copy.c:644 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "« COPY force not null » n'est disponible qu'en utilisant COPY FROM" + +#: commands/copy.c:650 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "« COPY force null » n'est disponible que dans le mode CSV" + +#: commands/copy.c:655 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "« COPY force null » n'est disponible qu'en utilisant COPY FROM" + +#: commands/copy.c:661 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "le délimiteur COPY ne doit pas apparaître dans la spécification de NULL" + +#: commands/copy.c:668 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "le caractère guillemet pour CSV ne doit pas apparaître dans la spécification de NULL" + +#: commands/copy.c:729 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "la colonne « %s » est une colonne générée" + +#: commands/copy.c:731 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "Les colonnes générées ne peuvent pas être utilisées dans COPY." + +#: commands/copy.c:746 commands/indexcmds.c:1754 commands/statscmds.c:238 commands/tablecmds.c:2366 commands/tablecmds.c:3022 commands/tablecmds.c:3515 parser/parse_relation.c:3593 parser/parse_relation.c:3613 utils/adt/tsvector_op.c:2680 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "la colonne « %s » n'existe pas" + +#: commands/copy.c:753 commands/tablecmds.c:2392 commands/trigger.c:933 parser/parse_target.c:1080 parser/parse_target.c:1091 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "la colonne « %s » est spécifiée plus d'une fois" + +#: commands/copyfrom.c:127 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, ligne %s, colonne %s" + +#: commands/copyfrom.c:131 commands/copyfrom.c:172 +#, c-format +msgid "COPY %s, line %s" +msgstr "COPY %s, ligne %s" + +#: commands/copyfrom.c:142 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, ligne %s, colonne %s : « %s »" + +#: commands/copyfrom.c:150 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, ligne %s, colonne %s : NULL en entrée" + +#: commands/copyfrom.c:166 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, ligne %s : « %s »" + +#: commands/copyfrom.c:566 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "ne peut pas copier vers la vue « %s »" + +#: commands/copyfrom.c:568 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "Pour activer la copie d'une vue, fournissez un trigger INSTEAD OF INSERT." + +#: commands/copyfrom.c:572 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "ne peut pas copier vers la vue matérialisée « %s »" + +#: commands/copyfrom.c:577 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "ne peut pas copier vers la séquence « %s »" + +#: commands/copyfrom.c:582 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "ne peut pas copier vers la relation « %s », qui n'est pas une table" + +#: commands/copyfrom.c:622 +#, c-format +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "ne peut pas exécuter COPY FREEZE sur une table partitionnée" + +#: commands/copyfrom.c:637 +#, c-format +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "n'a pas pu exécuter un COPY FREEZE à cause d'une activité transactionnelle précédente" + +#: commands/copyfrom.c:643 +#, c-format +msgid "cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "n'a pas pu exécuter un COPY FREEZE parce que la table n'a pas été créée ou tronquée dans la transaction en cours" + +#: commands/copyfrom.c:1264 commands/copyto.c:612 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "la colonne « %s » FORCE_NOT_NULL n'est pas référencée par COPY" + +#: commands/copyfrom.c:1287 commands/copyto.c:635 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "la colonne « %s » FORCE_NULL n'est pas référencée par COPY" + +#: commands/copyfrom.c:1519 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TO indique au serveur PostgreSQL de lire un fichier. Vous pourriez vouloir utiliser la fonctionnalité \\copy de psql pour lire en local." + +#: commands/copyfrom.c:1532 commands/copyto.c:734 +#, c-format +msgid "\"%s\" is a directory" +msgstr "« %s » est un répertoire" + +#: commands/copyfrom.c:1600 commands/copyto.c:302 libpq/be-secure-common.c:105 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "n'a pas pu fermer le fichier pipe vers la commande externe : %m" + +#: commands/copyfrom.c:1615 commands/copyto.c:307 +#, c-format +msgid "program \"%s\" failed" +msgstr "le programme « %s » a échoué" + +#: commands/copyfromparse.c:199 +#, c-format +msgid "COPY file signature not recognized" +msgstr "la signature du fichier COPY n'est pas reconnue" + +#: commands/copyfromparse.c:204 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "en-tête du fichier COPY invalide (options manquantes)" + +#: commands/copyfromparse.c:208 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "en-tête du fichier COPY invalide (WITH OIDS)" + +#: commands/copyfromparse.c:213 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "options critiques non reconnues dans l'en-tête du fichier COPY" + +#: commands/copyfromparse.c:219 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "en-tête du fichier COPY invalide (longueur manquante)" + +#: commands/copyfromparse.c:226 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "en-tête du fichier COPY invalide (mauvaise longueur)" + +#: commands/copyfromparse.c:255 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "n'a pas pu lire le fichier COPY : %m" + +#: commands/copyfromparse.c:277 commands/copyfromparse.c:302 tcop/postgres.c:360 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "" +"fin de fichier (EOF) inattendue de la connexion du client avec une\n" +"transaction ouverte" + +#: commands/copyfromparse.c:293 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "type 0x%02X du message, inattendu, lors d'une opération COPY à partir de stdin" + +#: commands/copyfromparse.c:316 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "échec de la commande COPY à partir de stdin : %s" + +#: commands/copyfromparse.c:841 commands/copyfromparse.c:1451 commands/copyfromparse.c:1681 +#, c-format +msgid "extra data after last expected column" +msgstr "données supplémentaires après la dernière colonne attendue" + +#: commands/copyfromparse.c:855 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "données manquantes pour la colonne « %s »" + +#: commands/copyfromparse.c:933 +#, c-format +msgid "received copy data after EOF marker" +msgstr "a reçu des données de COPY après le marqueur de fin" + +#: commands/copyfromparse.c:940 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "le nombre de champs de la ligne est %d, %d attendus" + +#: commands/copyfromparse.c:1233 commands/copyfromparse.c:1250 +#, c-format +msgid "literal carriage return found in data" +msgstr "retour chariot trouvé dans les données" + +#: commands/copyfromparse.c:1234 commands/copyfromparse.c:1251 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "retour chariot sans guillemet trouvé dans les données" + +#: commands/copyfromparse.c:1236 commands/copyfromparse.c:1253 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "Utilisez « \\r » pour représenter un retour chariot." + +#: commands/copyfromparse.c:1237 commands/copyfromparse.c:1254 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "Utiliser le champ CSV entre guillemets pour représenter un retour chariot." + +#: commands/copyfromparse.c:1266 +#, c-format +msgid "literal newline found in data" +msgstr "retour à la ligne trouvé dans les données" + +#: commands/copyfromparse.c:1267 +#, c-format +msgid "unquoted newline found in data" +msgstr "retour à la ligne trouvé dans les données" + +#: commands/copyfromparse.c:1269 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "Utilisez « \\n » pour représenter un retour à la ligne." + +#: commands/copyfromparse.c:1270 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "Utiliser un champ CSV entre guillemets pour représenter un retour à la ligne." + +#: commands/copyfromparse.c:1316 commands/copyfromparse.c:1352 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "le marqueur fin-de-copie ne correspond pas à un précédent style de fin de ligne" + +#: commands/copyfromparse.c:1325 commands/copyfromparse.c:1341 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "marqueur fin-de-copie corrompu" + +#: commands/copyfromparse.c:1765 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "champ CSV entre guillemets non terminé" + +#: commands/copyfromparse.c:1841 commands/copyfromparse.c:1860 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "fin de fichier (EOF) inattendu dans les données du COPY" + +#: commands/copyfromparse.c:1850 +#, c-format +msgid "invalid field size" +msgstr "taille du champ invalide" + +#: commands/copyfromparse.c:1873 +#, c-format +msgid "incorrect binary data format" +msgstr "format de données binaires incorrect" + +#: commands/copyto.c:235 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "n'a pas pu écrire vers le programme COPY : %m" + +#: commands/copyto.c:240 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "n'a pas pu écrire dans le fichier COPY : %m" + +#: commands/copyto.c:370 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "ne peut pas copier à partir de la vue « %s »" + +#: commands/copyto.c:372 commands/copyto.c:378 commands/copyto.c:384 commands/copyto.c:395 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "Tentez la variante COPY (SELECT ...) TO." + +#: commands/copyto.c:376 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "ne peut pas copier à partir de la vue matérialisée « %s »" + +#: commands/copyto.c:382 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "ne peut pas copier à partir de la table distante « %s »" + +#: commands/copyto.c:388 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "ne peut pas copier à partir de la séquence « %s »" + +#: commands/copyto.c:393 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "ne peut pas copier à partir de la table partitionnée « %s »" + +#: commands/copyto.c:399 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "ne peut pas copier depuis la relation « %s », qui n'est pas une table" + +#: commands/copyto.c:451 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "les règles DO INSTEAD NOTHING ne sont pas supportées pour COPY" + +#: commands/copyto.c:465 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "les règles DO INSTEAD conditionnelles ne sont pas supportées par l'instruction COPY" + +#: commands/copyto.c:469 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "les règles DO ALSO ne sont pas supportées pour COPY" + +#: commands/copyto.c:474 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "les règles DO INSTEAD multi-instructions ne sont pas supportées par l'instruction COPY" + +#: commands/copyto.c:484 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO) n'est pas supporté" + +#: commands/copyto.c:501 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "La requête COPY doit avoir une clause RETURNING" + +#: commands/copyto.c:530 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "la relation référencée par l'instruction COPY a changé" + +#: commands/copyto.c:589 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "la colonne « %s » FORCE_QUOTE n'est pas référencée par COPY" + +#: commands/copyto.c:699 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "un chemin relatif n'est pas autorisé à utiliser COPY vers un fichier" + +#: commands/copyto.c:718 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » en écriture : %m" + +#: commands/copyto.c:721 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TO indique au serveur PostgreSQL d'écrire un fichier. Vous pourriez vouloir utiliser la fonctionnalité \\copy de psql pour écrire en local." + +#: commands/createas.c:215 commands/createas.c:511 +#, c-format +msgid "too many column names were specified" +msgstr "trop de noms de colonnes ont été spécifiés" + +#: commands/createas.c:534 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "politiques non encore implémentées pour cette commande" + +#: commands/dbcommands.c:246 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATION n'est plus supporté" + +#: commands/dbcommands.c:247 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "Considérer l'utilisation de tablespaces." + +#: commands/dbcommands.c:261 +#, c-format +msgid "LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE." +msgstr "LOCALE ne peut pas être spécifié avec LC_COLLATE ou LC_CTYPE." + +#: commands/dbcommands.c:279 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%d n'est pas un code d'encodage valide" + +#: commands/dbcommands.c:290 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%s n'est pas un nom d'encodage valide" + +#: commands/dbcommands.c:314 commands/dbcommands.c:1569 commands/user.c:275 commands/user.c:691 +#, c-format +msgid "invalid connection limit: %d" +msgstr "limite de connexion invalide : %d" + +#: commands/dbcommands.c:333 +#, c-format +msgid "permission denied to create database" +msgstr "droit refusé pour créer une base de données" + +#: commands/dbcommands.c:356 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "la base de données modèle « %s » n'existe pas" + +#: commands/dbcommands.c:368 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "droit refusé pour copier la base de données « %s »" + +#: commands/dbcommands.c:384 +#, c-format +msgid "invalid server encoding %d" +msgstr "encodage serveur %d invalide" + +#: commands/dbcommands.c:390 commands/dbcommands.c:395 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "nom de locale invalide : « %s »" + +#: commands/dbcommands.c:415 +#, c-format +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" +msgstr "" +"le nouvel encodage (%sà est incompatible avec l'encodage de la base de\n" +"données modèle (%s)" + +#: commands/dbcommands.c:418 +#, c-format +msgid "Use the same encoding as in the template database, or use template0 as template." +msgstr "" +"Utilisez le même encodage que celui de la base de données modèle,\n" +"ou utilisez template0 comme modèle." + +#: commands/dbcommands.c:423 +#, c-format +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" +msgstr "" +"le nouveau tri (%s) est incompatible avec le tri de la base de\n" +"données modèle (%s)" + +#: commands/dbcommands.c:425 +#, c-format +msgid "Use the same collation as in the template database, or use template0 as template." +msgstr "" +"Utilisez le même tri que celui de la base de données modèle,\n" +"ou utilisez template0 comme modèle." + +#: commands/dbcommands.c:430 +#, c-format +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" +msgstr "" +"le nouveau LC_CTYPE (%s) est incompatible avec le LC_CTYPE de la base de\n" +"données modèle (%s)" + +#: commands/dbcommands.c:432 +#, c-format +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." +msgstr "" +"Utilisez le même LC_CTYPE que celui de la base de données modèle,\n" +"ou utilisez template0 comme modèle." + +#: commands/dbcommands.c:454 commands/dbcommands.c:1196 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "pg_global ne peut pas être utilisé comme tablespace par défaut" + +#: commands/dbcommands.c:480 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "ne peut pas affecter un nouveau tablespace par défaut « %s »" + +#: commands/dbcommands.c:482 +#, c-format +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." +msgstr "" +"Il existe un conflit car la base de données « %s » a déjà quelques tables\n" +"dans son tablespace." + +#: commands/dbcommands.c:512 commands/dbcommands.c:1066 +#, c-format +msgid "database \"%s\" already exists" +msgstr "la base de données « %s » existe déjà" + +#: commands/dbcommands.c:526 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "la base de données source « %s » est accédée par d'autres utilisateurs" + +#: commands/dbcommands.c:769 commands/dbcommands.c:784 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "l'encodage « %s » ne correspond pas à la locale « %s »" + +#: commands/dbcommands.c:772 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "Le paramètre LC_CTYPE choisi nécessite l'encodage « %s »." + +#: commands/dbcommands.c:787 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "Le paramètre LC_COLLATE choisi nécessite l'encodage « %s »." + +#: commands/dbcommands.c:848 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "la base de données « %s » n'existe pas, poursuite du traitement" + +#: commands/dbcommands.c:872 +#, c-format +msgid "cannot drop a template database" +msgstr "ne peut pas supprimer une base de données modèle" + +#: commands/dbcommands.c:878 +#, c-format +msgid "cannot drop the currently open database" +msgstr "ne peut pas supprimer la base de données actuellement ouverte" + +#: commands/dbcommands.c:891 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "la base de données « %s » est utilisée par un slot de réplication logique actif" + +#: commands/dbcommands.c:893 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "Il existe %d slot actif." +msgstr[1] "Il existe %d slots actifs." + +#: commands/dbcommands.c:907 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "la base de données « %s » est utilisée par une souscription de réplication logique" + +#: commands/dbcommands.c:909 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "Il existe %d souscription." +msgstr[1] "Il existe %d souscriptions." + +#: commands/dbcommands.c:930 commands/dbcommands.c:1088 commands/dbcommands.c:1218 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "la base de données « %s » est en cours d'utilisation par d'autres utilisateurs" + +#: commands/dbcommands.c:1048 +#, c-format +msgid "permission denied to rename database" +msgstr "droit refusé pour le renommage de la base de données" + +#: commands/dbcommands.c:1077 +#, c-format +msgid "current database cannot be renamed" +msgstr "la base de données actuelle ne peut pas être renommée" + +#: commands/dbcommands.c:1174 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "ne peut pas modifier le tablespace de la base de données actuellement ouverte" + +#: commands/dbcommands.c:1277 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "" +"certaines relations de la base de données « %s » sont déjà dans le\n" +"tablespace « %s »" + +#: commands/dbcommands.c:1279 +#, c-format +msgid "You must move them back to the database's default tablespace before using this command." +msgstr "" +"Vous devez d'abord les déplacer dans le tablespace par défaut de la base\n" +"de données avant d'utiliser cette commande." + +#: commands/dbcommands.c:1404 commands/dbcommands.c:1980 commands/dbcommands.c:2203 commands/dbcommands.c:2261 commands/tablespace.c:631 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "" +"certains fichiers inutiles pourraient se trouver dans l'ancien répertoire\n" +"de la base de données « %s »" + +#: commands/dbcommands.c:1460 +#, c-format +msgid "unrecognized DROP DATABASE option \"%s\"" +msgstr "option de DROP DATABASE « %s » non reconnue" + +#: commands/dbcommands.c:1550 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "l'option « %s » ne peut pas être spécifié avec d'autres options" + +#: commands/dbcommands.c:1606 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "ne peut pas désactiver les connexions pour la base de données courante" + +#: commands/dbcommands.c:1742 +#, c-format +msgid "permission denied to change owner of database" +msgstr "droit refusé pour modifier le propriétaire de la base de données" + +#: commands/dbcommands.c:2086 +#, c-format +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." +msgstr "%d autres sessions et %d transactions préparées utilisent la base de données." + +#: commands/dbcommands.c:2089 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "%d autre session utilise la base de données." +msgstr[1] "%d autres sessions utilisent la base de données." + +#: commands/dbcommands.c:2094 storage/ipc/procarray.c:3749 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "%d transaction préparée utilise la base de données." +msgstr[1] "%d transactions préparées utilisent la base de données." + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%s requiert un paramètre" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%s requiert une valeur numérique" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "%s requiert une valeur booléenne" + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%s requiert une valeur entière" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "l'argument de %s doit être un nom" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "l'argument de %s doit être un nom de type" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "argument invalide pour %s : « %s »" + +#: commands/dropcmds.c:100 commands/functioncmds.c:1410 utils/adt/ruleutils.c:2806 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "« %s » est une fonction d'agrégat" + +#: commands/dropcmds.c:102 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "Utiliser DROP AGGREGATE pour supprimer les fonctions d'agrégat." + +#: commands/dropcmds.c:158 commands/sequence.c:447 commands/tablecmds.c:3599 commands/tablecmds.c:3757 commands/tablecmds.c:3802 commands/tablecmds.c:15796 tcop/utility.c:1307 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "la relation « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:188 commands/dropcmds.c:287 commands/tablecmds.c:1248 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "le schéma « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:228 commands/dropcmds.c:267 commands/tablecmds.c:272 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "le type « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:257 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "la méthode d'accès « %s » n'existe pas, ignoré" + +#: commands/dropcmds.c:275 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "le collationnement « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:282 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "la conversion « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:293 commands/statscmds.c:630 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "l'objet statistique « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:300 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr "" +"l'analyseur de recherche plein texte « %s » n'existe pas, poursuite du\n" +"traitement" + +#: commands/dropcmds.c:307 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "" +"le dictionnaire de recherche plein texte « %s » n'existe pas, poursuite du\n" +"traitement" + +#: commands/dropcmds.c:314 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "le modèle de recherche plein texte « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:321 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "" +"la configuration de recherche plein texte « %s » n'existe pas, poursuite du\n" +"traitement" + +#: commands/dropcmds.c:326 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "l'extension « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:336 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "la fonction %s(%s) n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:349 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "la procédure %s(%s) n'existe pas, ignoré" + +#: commands/dropcmds.c:362 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "la routine %s(%s) n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:375 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "l'agrégat %s(%s) n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:388 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "l'opérateur %s n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:394 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "le langage « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:403 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "la conversion du type %s vers le type %s n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:412 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "la transformation pour le type %s et le langage « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:420 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "le trigger « %s » de la relation « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:429 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "la politique « %s » de la relation « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:436 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "le trigger sur événement « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:442 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "la règle « %s » de la relation « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:449 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "le wrapper de données distantes « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:453 commands/foreigncmds.c:1351 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "le serveur « %s » n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:462 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "la classe d'opérateur « %s » n'existe pas pour la méthode d'accès « %s », ignoré" + +#: commands/dropcmds.c:474 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "la famille d'opérateur « %s » n'existe pas pour la méthode d'accès « %s », ignoré" + +#: commands/dropcmds.c:481 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "la publication « %s » n'existe pas, poursuite du traitement" + +#: commands/event_trigger.c:125 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "droit refusé pour créer le trigger sur événement « %s »" + +#: commands/event_trigger.c:127 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "Doit être super-utilisateur pour créer un trigger sur événement." + +#: commands/event_trigger.c:136 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "nom d'événement non reconnu : « %s »" + +#: commands/event_trigger.c:153 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "variable « %s » du filtre non reconnue" + +#: commands/event_trigger.c:207 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "valeur de filtre « %s » non reconnue pour la variable de filtre « %s »" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:213 commands/event_trigger.c:235 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "les triggers sur événement ne sont pas supportés pour %s" + +#: commands/event_trigger.c:248 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "variable « %s » du filtre spécifiée plus d'une fois" + +#: commands/event_trigger.c:377 commands/event_trigger.c:421 commands/event_trigger.c:515 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "le trigger sur événement « %s » n'existe pas" + +#: commands/event_trigger.c:483 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "droit refusé pour modifier le propriétaire du trigger sur événement « %s »" + +#: commands/event_trigger.c:485 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "Le propriétaire du trigger sur événement doit être un super-utilisateur." + +#: commands/event_trigger.c:1304 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%s peut seulement être appelé dans une fonction de trigger sur événement sql_drop" + +#: commands/event_trigger.c:1424 commands/event_trigger.c:1445 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%s peut seulement être appelé dans une fonction de trigger sur événement table_rewrite" + +#: commands/event_trigger.c:1862 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%s peut seulement être appelé dans une fonction de trigger sur événement" + +#: commands/explain.c:218 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "valeur non reconnue pour l'option « %s » d'EXPLAIN : « %s »" + +#: commands/explain.c:225 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "option d'EXPLAIN « %s » non reconnue" + +#: commands/explain.c:233 +#, c-format +msgid "EXPLAIN option WAL requires ANALYZE" +msgstr "l'option WAL d'EXPLAIN nécessite ANALYZE" + +#: commands/explain.c:242 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "l'option TIMING d'EXPLAIN nécessite ANALYZE" + +#: commands/extension.c:173 commands/extension.c:3014 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "l'extension « %s » n'existe pas" + +#: commands/extension.c:272 commands/extension.c:281 commands/extension.c:293 commands/extension.c:303 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "nom d'extension invalide : « %s »" + +#: commands/extension.c:273 +#, c-format +msgid "Extension names must not be empty." +msgstr "Les noms d'extension ne doivent pas être vides." + +#: commands/extension.c:282 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "Les noms d'extension ne doivent pas contenir « -- »." + +#: commands/extension.c:294 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "Les noms des extensions ne doivent pas commencer ou finir avec un tiret (« - »)." + +#: commands/extension.c:304 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "Les noms des extensions ne doivent pas contenir des caractères séparateurs de répertoire." + +#: commands/extension.c:319 commands/extension.c:328 commands/extension.c:337 commands/extension.c:347 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "nom de version de l'extension invalide : « %s »" + +#: commands/extension.c:320 +#, c-format +msgid "Version names must not be empty." +msgstr "Les noms de version ne doivent pas être vides." + +#: commands/extension.c:329 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "Les noms de version ne doivent pas contenir « -- »." + +#: commands/extension.c:338 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "Les noms de version ne doivent ni commencer ni se terminer avec un tiret." + +#: commands/extension.c:348 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "" +"Les noms de version ne doivent pas contenir de caractères séparateurs de\n" +"répertoire." + +#: commands/extension.c:498 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier de contrôle d'extension « %s » : %m" + +#: commands/extension.c:520 commands/extension.c:530 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "" +"le paramètre « %s » ne peut pas être configuré dans un fichier de contrôle\n" +"secondaire de l'extension" + +#: commands/extension.c:552 commands/extension.c:560 commands/extension.c:568 utils/misc/guc.c:7092 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "le paramètre « %s » requiert une valeur booléenne" + +#: commands/extension.c:577 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "« %s » n'est pas un nom d'encodage valide" + +#: commands/extension.c:591 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "l'argument « %s » doit être une liste de noms d'extension" + +#: commands/extension.c:598 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "paramètre « %s » non reconnu dans le fichier « %s »" + +#: commands/extension.c:607 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr "le paramètre « schema » ne peut pas être indiqué quand « relocatable » est vrai" + +#: commands/extension.c:785 +#, c-format +msgid "transaction control statements are not allowed within an extension script" +msgstr "" +"les instructions de contrôle des transactions ne sont pas autorisées dans un\n" +"script d'extension" + +#: commands/extension.c:862 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "droit refusé pour créer l'extension « %s »" + +#: commands/extension.c:865 +#, c-format +msgid "Must have CREATE privilege on current database to create this extension." +msgstr "Doit avoir le droit CREATE sur la base actuelle pour créer cette extension." + +#: commands/extension.c:866 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "Doit être super-utilisateur pour créer cette extension." + +#: commands/extension.c:870 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "droit refusé pour mettre à jour l'extension « %s »" + +#: commands/extension.c:873 +#, c-format +msgid "Must have CREATE privilege on current database to update this extension." +msgstr "Doit avoir le droit CREATE sur la base actuelle pour mettre à jour cette extension." + +#: commands/extension.c:874 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "Doit être super-utilisateur pour mettre à jour cette extension." + +#: commands/extension.c:1201 +#, c-format +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "l'extension « %s » n'a pas de chemin de mise à jour pour aller de la version « %s » à la version « %s »" + +#: commands/extension.c:1409 commands/extension.c:3075 +#, c-format +msgid "version to install must be specified" +msgstr "la version à installer doit être précisée" + +#: commands/extension.c:1446 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "l'extension « %s » n'a pas de script d'installation ou de chemin de mise à jour pour la version « %s »" + +#: commands/extension.c:1480 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "l'extension « %s » doit être installée dans le schéma « %s »" + +#: commands/extension.c:1640 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "dépendance cyclique détectée entre les extensions « %s » et « %s »" + +#: commands/extension.c:1645 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "installation de l'extension requise « %s »" + +#: commands/extension.c:1668 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr "l'extension « %s » requise n'est pas installée" + +#: commands/extension.c:1671 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "Utilisez CREATE EXTENSION ... CASCADE pour installer également les extensions requises." + +#: commands/extension.c:1706 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "l'extension « %s » existe déjà, poursuite du traitement" + +#: commands/extension.c:1713 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "l'extension « %s » existe déjà" + +#: commands/extension.c:1724 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "le CREATE EXTENSION imbriqué n'est pas supporté" + +#: commands/extension.c:1897 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "ne peut pas supprimer l'extension « %s » car il est en cours de modification" + +#: commands/extension.c:2458 +#, c-format +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "%s ne peut être appelé qu'à partir d'un script SQL exécuté par CREATE EXTENSION" + +#: commands/extension.c:2470 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "l'OID %u ne fait pas référence à une table" + +#: commands/extension.c:2475 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "la table « %s » n'est pas un membre de l'extension en cours de création" + +#: commands/extension.c:2829 +#, c-format +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" +msgstr "" +"ne peut pas déplacer l'extension « %s » dans le schéma « %s » car l'extension\n" +"contient le schéma" + +#: commands/extension.c:2870 commands/extension.c:2933 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "l'extension « %s » ne supporte pas SET SCHEMA" + +#: commands/extension.c:2935 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "%s n'est pas dans le schéma de l'extension « %s »" + +#: commands/extension.c:2994 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "un ALTER EXTENSION imbriqué n'est pas supporté" + +#: commands/extension.c:3086 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "la version « %s » de l'extension « %s » est déjà installée" + +#: commands/extension.c:3298 +#, c-format +msgid "cannot add an object of this type to an extension" +msgstr "ne peut pas ajouter un objet de ce type à une extension" + +#: commands/extension.c:3356 +#, c-format +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" +msgstr "" +"ne peut pas ajouter le schéma « %s » à l'extension « %s » car le schéma\n" +"contient l'extension" + +#: commands/extension.c:3384 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "%s n'est pas un membre de l'extension « %s »" + +#: commands/extension.c:3450 +#, c-format +msgid "file \"%s\" is too large" +msgstr "le fichier « %s » est trop gros" + +#: commands/foreigncmds.c:148 commands/foreigncmds.c:157 +#, c-format +msgid "option \"%s\" not found" +msgstr "option « %s » non trouvé" + +#: commands/foreigncmds.c:167 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "option « %s » fournie plus d'une fois" + +#: commands/foreigncmds.c:221 commands/foreigncmds.c:229 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "droit refusé pour modifier le propriétaire du wrapper de données distantes « %s »" + +#: commands/foreigncmds.c:223 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "" +"Doit être super-utilisateur pour modifier le propriétaire du wrapper de\n" +"données distantes." + +#: commands/foreigncmds.c:231 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "Le propriétaire du wrapper de données distantes doit être un super-utilisateur." + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:711 foreign/foreign.c:701 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "le wrapper de données distantes « %s » n'existe pas" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "droit refusé pour la création du wrapper de données distantes « %s »" + +#: commands/foreigncmds.c:586 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "Doit être super-utilisateur pour créer un wrapper de données distantes." + +#: commands/foreigncmds.c:701 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "droit refusé pour modifier le wrapper de données distantes « %s »" + +#: commands/foreigncmds.c:703 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "Doit être super-utilisateur pour modifier un wrapper de données distantes." + +#: commands/foreigncmds.c:734 +#, c-format +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" +msgstr "" +"la modification du validateur de wrapper de données distantes peut modifier\n" +"le comportement des tables distantes existantes" + +#: commands/foreigncmds.c:749 +#, c-format +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +msgstr "" +"la modification du validateur du wrapper de données distantes peut faire en\n" +"sorte que les options des objets dépendants deviennent invalides" + +#: commands/foreigncmds.c:871 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "le serveur « %s » existe déjà, poursuite du traitement" + +#: commands/foreigncmds.c:1135 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "la correspondance d'utilisateur « %s » existe déjà pour le serveur « %s », poursuite du traitement" + +#: commands/foreigncmds.c:1145 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "la correspondance d'utilisateur « %s » existe déjà pour le serveur « %s »" + +#: commands/foreigncmds.c:1245 commands/foreigncmds.c:1365 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "la correspondance d'utilisateur « %s » n'existe pas pour le serveur « %s »" + +#: commands/foreigncmds.c:1370 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "la correspondance d'utilisateur « %s » n'existe pas pour le serveur « %s », poursuite du traitement" + +#: commands/foreigncmds.c:1498 foreign/foreign.c:389 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "le wrapper de données distantes « %s » n'a pas de gestionnaire" + +#: commands/foreigncmds.c:1504 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "le wrapper de données distantes « %s » ne supporte pas IMPORT FOREIGN SCHEMA" + +#: commands/foreigncmds.c:1606 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "import de la table distante « %s »" + +#: commands/functioncmds.c:108 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "la fonction SQL ne peut pas retourner le type shell %s" + +#: commands/functioncmds.c:113 +#, c-format +msgid "return type %s is only a shell" +msgstr "le type de retour %s est seulement un shell" + +#: commands/functioncmds.c:143 parser/parse_type.c:354 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "le modificateur de type ne peut pas être précisé pour le type shell « %s »" + +#: commands/functioncmds.c:149 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "le type « %s » n'est pas encore défini" + +#: commands/functioncmds.c:150 +#, c-format +msgid "Creating a shell type definition." +msgstr "Création d'une définition d'un type shell." + +#: commands/functioncmds.c:249 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "la fonction SQL ne peut pas accepter le type shell %s" + +#: commands/functioncmds.c:255 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "l'agrégat ne peut pas accepter le type shell %s" + +#: commands/functioncmds.c:260 +#, c-format +msgid "argument type %s is only a shell" +msgstr "le type d'argument %s n'est qu'une enveloppe" + +#: commands/functioncmds.c:270 +#, c-format +msgid "type %s does not exist" +msgstr "le type %s n'existe pas" + +#: commands/functioncmds.c:284 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "les agrégats ne peuvent pas utiliser des ensembles comme arguments" + +#: commands/functioncmds.c:288 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "les procédures ne peuvent pas utiliser des arguments d'ensemble" + +#: commands/functioncmds.c:292 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "les fonctions ne peuvent pas accepter des arguments d'ensemble" + +#: commands/functioncmds.c:302 +#, c-format +msgid "VARIADIC parameter must be the last input parameter" +msgstr "le paramètre VARIADIC doit être le dernier paramètre en entrée" + +#: commands/functioncmds.c:322 +#, c-format +msgid "VARIADIC parameter must be the last parameter" +msgstr "le paramètre VARIADIC doit être le dernier paramètre" + +#: commands/functioncmds.c:347 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "le paramètre VARIADIC doit être un tableau" + +#: commands/functioncmds.c:392 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "le nom du paramètre « %s » est utilisé plus d'une fois" + +#: commands/functioncmds.c:410 +#, c-format +msgid "only input parameters can have default values" +msgstr "seuls les paramètres en entrée peuvent avoir des valeurs par défaut" + +#: commands/functioncmds.c:425 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "" +"ne peut pas utiliser les références de tables dans la valeur par défaut des\n" +"paramètres" + +#: commands/functioncmds.c:449 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "les paramètres en entrée suivant un paramètre avec valeur par défaut doivent aussi avoir des valeurs par défaut" + +#: commands/functioncmds.c:459 +#, c-format +msgid "procedure OUT parameters cannot appear after one with a default value" +msgstr "les paramètres OUT d'une procédure ne peuvent pas apparaître après un paramètre ayant une valeur par défaut" + +#: commands/functioncmds.c:611 commands/functioncmds.c:802 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "attribute invalide dans la définition de la procédure" + +#: commands/functioncmds.c:707 +#, c-format +msgid "support function %s must return type %s" +msgstr "la fonction de support %s doit renvoyer le type %s" + +#: commands/functioncmds.c:718 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "doit être super-utilisateur pour spécifier une fonction de support" + +#: commands/functioncmds.c:851 commands/functioncmds.c:1455 +#, c-format +msgid "COST must be positive" +msgstr "COST doit être positif" + +#: commands/functioncmds.c:859 commands/functioncmds.c:1463 +#, c-format +msgid "ROWS must be positive" +msgstr "ROWS doit être positif" + +#: commands/functioncmds.c:888 +#, c-format +msgid "no function body specified" +msgstr "aucun corps de fonction spécifié" + +#: commands/functioncmds.c:893 +#, c-format +msgid "duplicate function body specified" +msgstr "corps de fonction dupliqué spécifié" + +#: commands/functioncmds.c:898 +#, c-format +msgid "inline SQL function body only valid for language SQL" +msgstr "" + +#: commands/functioncmds.c:940 +#, c-format +msgid "SQL function with unquoted function body cannot have polymorphic arguments" +msgstr "la fonction SQL avec un corps de fonction sans guillemets ne peuvent pas avoir des arguments polymorphiques" + +#: commands/functioncmds.c:966 commands/functioncmds.c:985 +#, c-format +msgid "%s is not yet supported in unquoted SQL function body" +msgstr "%s n'est pas encore accepté dans une corps de fonction SQL sans guillemets" + +#: commands/functioncmds.c:1013 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "seul un élément AS est nécessaire pour le langage « %s »" + +#: commands/functioncmds.c:1118 +#, c-format +msgid "no language specified" +msgstr "aucun langage spécifié" + +#: commands/functioncmds.c:1126 commands/functioncmds.c:2128 commands/proclang.c:237 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "le langage « %s » n'existe pas" + +#: commands/functioncmds.c:1128 commands/functioncmds.c:2130 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Utiliser CREATE EXTENSION pour charger le langage dans la base de données." + +#: commands/functioncmds.c:1163 commands/functioncmds.c:1447 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "seul un superutilisateur peut définir une fonction leakproof" + +#: commands/functioncmds.c:1214 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "le type de résultat de la fonction doit être %s à cause des paramètres OUT" + +#: commands/functioncmds.c:1227 +#, c-format +msgid "function result type must be specified" +msgstr "le type de résultat de la fonction doit être spécifié" + +#: commands/functioncmds.c:1281 commands/functioncmds.c:1467 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "ROWS n'est pas applicable quand la fonction ne renvoie pas un ensemble" + +#: commands/functioncmds.c:1567 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "le type de données source %s est un pseudo-type" + +#: commands/functioncmds.c:1573 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "le type de données cible %s est un pseudo-type" + +#: commands/functioncmds.c:1597 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "la conversion sera ignorée car le type de données source est un domaine" + +#: commands/functioncmds.c:1602 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "la conversion sera ignorée car le type de données cible est un domaine" + +#: commands/functioncmds.c:1627 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "la fonction de conversion doit prendre de un à trois arguments" + +#: commands/functioncmds.c:1631 +#, c-format +msgid "argument of cast function must match or be binary-coercible from source data type" +msgstr "l'argument de la fonction de conversion doit correspondre ou être binary-coercible à partir du type de la donnée source" + +#: commands/functioncmds.c:1635 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "le second argument de la fonction de conversion doit être de type %s" + +#: commands/functioncmds.c:1640 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "le troisième argument de la fonction de conversion doit être de type %s" + +#: commands/functioncmds.c:1645 +#, c-format +msgid "return data type of cast function must match or be binary-coercible to target data type" +msgstr "" +"le type de donnée en retour de la fonction de conversion doit correspondre\n" +"ou être coercible binairement au type de données cible" + +#: commands/functioncmds.c:1656 +#, c-format +msgid "cast function must not be volatile" +msgstr "la fonction de conversion ne doit pas être volatile" + +#: commands/functioncmds.c:1661 +#, c-format +msgid "cast function must be a normal function" +msgstr "la fonction de conversion doit être une fonction normale" + +#: commands/functioncmds.c:1665 +#, c-format +msgid "cast function must not return a set" +msgstr "la fonction de conversion ne doit pas renvoyer un ensemble" + +#: commands/functioncmds.c:1691 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "doit être super-utilisateur pour créer une fonction de conversion SANS FONCTION" + +#: commands/functioncmds.c:1706 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "les types de données source et cible ne sont pas physiquement compatibles" + +#: commands/functioncmds.c:1721 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "les types de données composites ne sont pas compatibles binairement" + +#: commands/functioncmds.c:1727 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "les types de données enum ne sont pas compatibles binairement" + +#: commands/functioncmds.c:1733 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "les types de données tableau ne sont pas compatibles binairement" + +#: commands/functioncmds.c:1750 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "les types de données domaines ne sont pas compatibles binairement" + +#: commands/functioncmds.c:1760 +#, c-format +msgid "source data type and target data type are the same" +msgstr "les types de données source et cible sont identiques" + +#: commands/functioncmds.c:1793 +#, c-format +msgid "transform function must not be volatile" +msgstr "la fonction de transformation ne doit pas être volatile" + +#: commands/functioncmds.c:1797 +#, c-format +msgid "transform function must be a normal function" +msgstr "la fonction de transformation doit être une fonction normale" + +#: commands/functioncmds.c:1801 +#, c-format +msgid "transform function must not return a set" +msgstr "la fonction de transformation ne doit pas renvoyer un ensemble" + +#: commands/functioncmds.c:1805 +#, c-format +msgid "transform function must take one argument" +msgstr "la fonction de transformation doit prendre de un argument" + +#: commands/functioncmds.c:1809 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "le premier argument de la fonction de transformation doit être de type %s" + +#: commands/functioncmds.c:1848 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "le type de données %s est un pseudo-type" + +#: commands/functioncmds.c:1854 +#, c-format +msgid "data type %s is a domain" +msgstr "le type de données %s est un domaine" + +#: commands/functioncmds.c:1894 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "le type de donnée en retour de la fonction FROM SQL doit être %s" + +#: commands/functioncmds.c:1920 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "le type de donnée en retour de la fonction TO SQL doit être du type de données de la transformation" + +#: commands/functioncmds.c:1949 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "la transformation pour le type %s et le langage « %s » existe déjà" + +#: commands/functioncmds.c:2036 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "la transformation pour le type %s et le langage « %s » n'existe pas" + +#: commands/functioncmds.c:2060 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "la fonction %s existe déjà dans le schéma « %s »" + +#: commands/functioncmds.c:2115 +#, c-format +msgid "no inline code specified" +msgstr "aucun code en ligne spécifié" + +#: commands/functioncmds.c:2161 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "le langage « %s » ne supporte pas l'exécution de code en ligne" + +#: commands/functioncmds.c:2256 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "ne peut pas passer plus de %d argument à une procédure" +msgstr[1] "ne peut pas passer plus de %d arguments à une procédure" + +#: commands/indexcmds.c:618 +#, c-format +msgid "must specify at least one column" +msgstr "doit spécifier au moins une colonne" + +#: commands/indexcmds.c:622 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "ne peut pas utiliser plus de %d colonnes dans un index" + +#: commands/indexcmds.c:661 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "ne peut pas créer un index sur la table distante « %s »" + +#: commands/indexcmds.c:692 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "ne peut pas créer un index sur la table partitionnée « %s » de manière concurrente" + +#: commands/indexcmds.c:697 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "ne peut pas créer de contraintes d'exclusion sur la table partitionnée « %s »" + +#: commands/indexcmds.c:707 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "ne peut pas créer les index sur les tables temporaires des autres sessions" + +#: commands/indexcmds.c:745 commands/tablecmds.c:748 commands/tablespace.c:1185 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "ne peut pas spécifier un tablespace par défaut pour les relations partitionnées" + +#: commands/indexcmds.c:777 commands/tablecmds.c:783 commands/tablecmds.c:3299 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "seules les relations partagées peuvent être placées dans le tablespace pg_global" + +#: commands/indexcmds.c:810 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "substitution de la méthode d'accès obsolète « rtree » par « gist »" + +#: commands/indexcmds.c:831 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "la méthode d'accès « %s » ne supporte pas les index uniques" + +#: commands/indexcmds.c:836 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "la méthode d'accès « %s » ne supporte pas les colonnes incluses" + +#: commands/indexcmds.c:841 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "la méthode d'accès « %s » ne supporte pas les index multi-colonnes" + +#: commands/indexcmds.c:846 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "la méthode d'accès « %s » ne supporte pas les contraintes d'exclusion" + +#: commands/indexcmds.c:969 +#, c-format +msgid "cannot match partition key to an index using access method \"%s\"" +msgstr "ne peut pas faire correspondre la clé de partitionnement à un index utilisant la méthode d'accès « %s »" + +#: commands/indexcmds.c:979 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "contrainte %s non supportée avec la définition de clé de partitionnement" + +#: commands/indexcmds.c:981 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "les contraintes %s ne peuvent pas être utilisées quand les clés de partitionnement incluent des expressions." + +#: commands/indexcmds.c:1020 +#, c-format +msgid "unique constraint on partitioned table must include all partitioning columns" +msgstr "la contrainte unique sur la table partitionnée doit inclure toutes les colonnes de partitionnement" + +#: commands/indexcmds.c:1021 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "la contrainte %s sur la table « %s » ne contient pas la colonne « %s » qui fait partie de la clé de partitionnement." + +#: commands/indexcmds.c:1040 commands/indexcmds.c:1059 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "la création d'un index sur les tables du catalogue système n'est pas supportée" + +#: commands/indexcmds.c:1231 tcop/utility.c:1493 +#, c-format +msgid "cannot create unique index on partitioned table \"%s\"" +msgstr "ne peut pas créer un index unique sur la table partitionnée « %s »" + +#: commands/indexcmds.c:1233 tcop/utility.c:1495 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "La table « %s » contient des partitions qui ne sont pas des tables distantes." + +#: commands/indexcmds.c:1683 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "les fonctions dans un prédicat d'index doivent être marquées comme IMMUTABLE" + +#: commands/indexcmds.c:1749 parser/parse_utilcmd.c:2515 parser/parse_utilcmd.c:2650 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "la colonne « %s » nommée dans la clé n'existe pas" + +#: commands/indexcmds.c:1773 parser/parse_utilcmd.c:1814 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "les expressions ne sont pas supportées dans les colonnes incluses" + +#: commands/indexcmds.c:1814 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "" +"les fonctions dans l'expression de l'index doivent être marquées comme\n" +"IMMUTABLE" + +#: commands/indexcmds.c:1829 +#, c-format +msgid "including column does not support a collation" +msgstr "une colonne incluse ne supporte pas de collationnement" + +#: commands/indexcmds.c:1833 +#, c-format +msgid "including column does not support an operator class" +msgstr "une colonne incluse ne supporte pas de classe d'opérateur" + +#: commands/indexcmds.c:1837 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "une colonne incluse ne supporte pas d'options ASC/DESC" + +#: commands/indexcmds.c:1841 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "une colonne incluse ne supporte pas d'options NULLS FIRST/LAST" + +#: commands/indexcmds.c:1868 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour l'expression d'index" + +#: commands/indexcmds.c:1876 commands/tablecmds.c:16801 commands/typecmds.c:810 parser/parse_expr.c:2680 parser/parse_type.c:566 parser/parse_utilcmd.c:3781 utils/adt/misc.c:599 +#, c-format +msgid "collations are not supported by type %s" +msgstr "les collationnements ne sont pas supportés par le type %s" + +#: commands/indexcmds.c:1914 +#, c-format +msgid "operator %s is not commutative" +msgstr "l'opérateur %s n'est pas commutatif" + +#: commands/indexcmds.c:1916 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "Seuls les opérateurs commutatifs peuvent être utilisés dans les contraintes d'exclusion." + +#: commands/indexcmds.c:1942 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "l'opérateur %s n'est pas un membre de la famille d'opérateur « %s »" + +#: commands/indexcmds.c:1945 +#, c-format +msgid "The exclusion operator must be related to the index operator class for the constraint." +msgstr "" +"L'opérateur d'exclusion doit être en relation avec la classe d'opérateur de\n" +"l'index pour la contrainte." + +#: commands/indexcmds.c:1980 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "la méthode d'accès « %s » ne supporte pas les options ASC/DESC" + +#: commands/indexcmds.c:1985 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "la méthode d'accès « %s » ne supporte pas les options NULLS FIRST/LAST" + +#: commands/indexcmds.c:2031 commands/tablecmds.c:16826 commands/tablecmds.c:16832 commands/typecmds.c:2318 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "" +"le type de données %s n'a pas de classe d'opérateurs par défaut pour la\n" +"méthode d'accès « %s »" + +#: commands/indexcmds.c:2033 +#, c-format +msgid "You must specify an operator class for the index or define a default operator class for the data type." +msgstr "" +"Vous devez spécifier une classe d'opérateur pour l'index ou définir une\n" +"classe d'opérateur par défaut pour le type de données." + +#: commands/indexcmds.c:2062 commands/indexcmds.c:2070 commands/opclasscmds.c:205 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "la classe d'opérateur « %s » n'existe pas pour la méthode d'accès « %s »" + +#: commands/indexcmds.c:2084 commands/typecmds.c:2306 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "la classe d'opérateur « %s » n'accepte pas le type de données %s" + +#: commands/indexcmds.c:2174 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "" +"il existe de nombreuses classes d'opérateur par défaut pour le type de\n" +"données %s" + +#: commands/indexcmds.c:2502 +#, c-format +msgid "unrecognized REINDEX option \"%s\"" +msgstr "option de REINDEX « %s » non reconnue" + +#: commands/indexcmds.c:2726 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "la table « %s » n'a pas d'index qui puisse être réindexé concuremment" + +#: commands/indexcmds.c:2740 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "la table « %s » n'a pas d'index à réindexer" + +#: commands/indexcmds.c:2780 commands/indexcmds.c:3287 commands/indexcmds.c:3415 +#, c-format +msgid "cannot reindex system catalogs concurrently" +msgstr "ne peut pas réindexer les catalogues système de manière concurrente" + +#: commands/indexcmds.c:2803 +#, c-format +msgid "can only reindex the currently open database" +msgstr "peut seulement réindexer la base de données en cours" + +#: commands/indexcmds.c:2891 +#, c-format +msgid "cannot reindex system catalogs concurrently, skipping all" +msgstr "ne peut pas réindexer les catalogues système de manière concurrente, ignore tout" + +#: commands/indexcmds.c:2924 +#, c-format +msgid "cannot move system relations, skipping all" +msgstr "ne peut pas déplacer les relations systèmes, toutes ignorées" + +#: commands/indexcmds.c:2971 +#, c-format +msgid "while reindexing partitioned table \"%s.%s\"" +msgstr "lors de la réindexation de la table partitionnée « %s.%s »" + +#: commands/indexcmds.c:2974 +#, c-format +msgid "while reindexing partitioned index \"%s.%s\"" +msgstr "lors de la réindexation de l'index partitionné « %s.%s »" + +#: commands/indexcmds.c:3167 commands/indexcmds.c:4003 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "la table « %s.%s » a été réindexée" + +#: commands/indexcmds.c:3319 commands/indexcmds.c:3371 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "ne peut pas réindexer l'index invalide « %s.%s » de manière concurrente, ignoré" + +#: commands/indexcmds.c:3325 +#, c-format +msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "ne peut pas réindexer l'index de contrainte d'exclusion « %s.%s » de manière concurrente, ignoré" + +#: commands/indexcmds.c:3480 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "ne peut pas réindexer ce type de relation de manière concurrente" + +#: commands/indexcmds.c:3501 +#, c-format +msgid "cannot move non-shared relation to tablespace \"%s\"" +msgstr "ne peut pas déplacer la relation non partagée dans le tablespace « %s »" + +#: commands/indexcmds.c:3984 commands/indexcmds.c:3996 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr "l'index « %s.%s » a été réindexé" + +#: commands/lockcmds.c:92 commands/tablecmds.c:6018 commands/trigger.c:289 rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:938 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "« %s » n'est ni une table ni une vue" + +#: commands/matview.c:182 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "CONCURRENTLY ne peut pas être utilisé quand la vue matérialisée n'est pas peuplée" + +#: commands/matview.c:188 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "Les options CONCURRENTLY et WITH NO DATA ne peuvent pas être utilisées ensemble" + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "ne peut pas rafraîchir de manière concurrente la vue matérialisée « %s »" + +#: commands/matview.c:247 +#, c-format +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "Crée un index unique sans clause WHERE sur une ou plusieurs colonnes de la vue matérialisée." + +#: commands/matview.c:652 +#, c-format +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "les nouvelles données pour la vue matérialisée « %s » contiennent des lignes dupliquées sans colonnes NULL" + +#: commands/matview.c:654 +#, c-format +msgid "Row: %s" +msgstr "Ligne : %s" + +#: commands/opclasscmds.c:124 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "la famille d'opérateur « %s » n'existe pas pour la méthode d'accès « %s »" + +#: commands/opclasscmds.c:266 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "la famille d'opérateur « %s » existe déjà pour la méthode d'accès « %s »" + +#: commands/opclasscmds.c:411 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "doit être super-utilisateur pour créer une classe d'opérateur" + +#: commands/opclasscmds.c:484 commands/opclasscmds.c:901 commands/opclasscmds.c:1047 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "numéro d'opérateur %d invalide, doit être compris entre 1 et %d" + +#: commands/opclasscmds.c:529 commands/opclasscmds.c:951 commands/opclasscmds.c:1063 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "numéro de fonction %d invalide, doit être compris entre 1 et %d" + +#: commands/opclasscmds.c:558 +#, c-format +msgid "storage type specified more than once" +msgstr "type de stockage spécifié plus d'une fois" + +#: commands/opclasscmds.c:585 +#, c-format +msgid "storage type cannot be different from data type for access method \"%s\"" +msgstr "" +"le type de stockage ne peut pas être différent du type de données pour la\n" +"méthode d'accès « %s »" + +#: commands/opclasscmds.c:601 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "la classe d'opérateur « %s » existe déjà pour la méthode d'accès « %s »" + +#: commands/opclasscmds.c:629 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "n'a pas pu rendre la classe d'opérateur « %s » par défaut pour le type %s" + +#: commands/opclasscmds.c:632 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "La classe d'opérateur « %s » est déjà la classe par défaut." + +#: commands/opclasscmds.c:792 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "doit être super-utilisateur pour créer une famille d'opérateur" + +#: commands/opclasscmds.c:852 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "doit être super-utilisateur pour modifier une famille d'opérateur" + +#: commands/opclasscmds.c:910 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "" +"les types d'argument de l'opérateur doivent être indiqués dans ALTER\n" +"OPERATOR FAMILY" + +#: commands/opclasscmds.c:985 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "STORAGE ne peut pas être spécifié dans ALTER OPERATOR FAMILY" + +#: commands/opclasscmds.c:1119 +#, c-format +msgid "one or two argument types must be specified" +msgstr "un ou deux types d'argument doit être spécifié" + +#: commands/opclasscmds.c:1145 +#, c-format +msgid "index operators must be binary" +msgstr "les opérateurs d'index doivent être binaires" + +#: commands/opclasscmds.c:1164 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "la méthode d'accès « %s » ne supporte pas les opérateurs de tri" + +#: commands/opclasscmds.c:1175 +#, c-format +msgid "index search operators must return boolean" +msgstr "les opérateurs de recherche d'index doivent renvoyer un booléen" + +#: commands/opclasscmds.c:1215 +#, c-format +msgid "associated data types for operator class options parsing functions must match opclass input type" +msgstr "les types de données associés pour les fonctions d'analyses des options d'une classe d'opérateur doivent correspondre au type en entrée de la classe d'opérateur" + +#: commands/opclasscmds.c:1222 +#, c-format +msgid "left and right associated data types for operator class options parsing functions must match" +msgstr "les types de données associés gauche et droite pour les fonctions d'analyses des options d'une classe d'opérateur doivent correspondre" + +#: commands/opclasscmds.c:1230 +#, c-format +msgid "invalid operator class options parsing function" +msgstr "fonction d'analyse des options de classe d'opérateur invalide" + +#: commands/opclasscmds.c:1231 +#, c-format +msgid "Valid signature of operator class options parsing function is %s." +msgstr "La signature valide de la fonction d'analyse des options de la classe d'opérateur est « %s »." + +#: commands/opclasscmds.c:1250 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "les fonctions de comparaison btree doivent avoir deux arguments" + +#: commands/opclasscmds.c:1254 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "les fonctions de comparaison btree doivent renvoyer un entier" + +#: commands/opclasscmds.c:1271 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "les fonctions de support de tri btree doivent accepter le type « internal »" + +#: commands/opclasscmds.c:1275 +#, c-format +msgid "btree sort support functions must return void" +msgstr "les fonctions de support de tri btree doivent renvoyer void" + +#: commands/opclasscmds.c:1286 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "les fonctions in_range btree doivent avoir cinq arguments" + +#: commands/opclasscmds.c:1290 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "les fonctions in_range btree doivent retourner un booléen" + +#: commands/opclasscmds.c:1306 +#, c-format +msgid "btree equal image functions must have one argument" +msgstr "les fonctions d'égalité d'image btree doivent avoir un argument" + +#: commands/opclasscmds.c:1310 +#, c-format +msgid "btree equal image functions must return boolean" +msgstr "les fonctions d'égalité d'image btree doivent retourner un booléen" + +#: commands/opclasscmds.c:1323 +#, c-format +msgid "btree equal image functions must not be cross-type" +msgstr "les fonctions d'égalité d'image btree ne doivent pas être inter-types" + +#: commands/opclasscmds.c:1333 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "la fonction de hachage 1 doit avoir un argument" + +#: commands/opclasscmds.c:1337 +#, c-format +msgid "hash function 1 must return integer" +msgstr "la fonction de hachage 1 doit retourner un integer" + +#: commands/opclasscmds.c:1344 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "la fonction de hachage 1 doit avoir deux arguments" + +#: commands/opclasscmds.c:1348 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "la fonction de hachage 2 doit retourner un bigint" + +#: commands/opclasscmds.c:1373 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "les types de données associés doivent être indiqués pour la fonction de support de l'index" + +#: commands/opclasscmds.c:1398 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "le numéro de fonction %d pour (%s, %s) apparaît plus d'une fois" + +#: commands/opclasscmds.c:1405 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "le numéro d'opérateur %d pour (%s, %s) apparaît plus d'une fois" + +#: commands/opclasscmds.c:1451 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "l'opérateur %d(%s, %s) existe déjà dans la famille d'opérateur « %s »" + +#: commands/opclasscmds.c:1557 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "la fonction %d(%s, %s) existe déjà dans la famille d'opérateur « %s »" + +#: commands/opclasscmds.c:1638 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "l'opérateur %d(%s, %s) n'existe pas dans la famille d'opérateur « %s »" + +#: commands/opclasscmds.c:1678 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "la fonction %d(%s, %s) n'existe pas dans la famille d'opérateur « %s »" + +#: commands/opclasscmds.c:1709 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "" +"la classe d'opérateur « %s » de la méthode d'accès « %s » existe déjà dans\n" +"le schéma « %s »" + +#: commands/opclasscmds.c:1732 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "" +"la famille d'opérateur « %s » de la méthode d'accès « %s » existe déjà dans\n" +"le schéma « %s »" + +#: commands/operatorcmds.c:111 commands/operatorcmds.c:119 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "type SETOF non autorisé pour l'argument de l'opérateur" + +#: commands/operatorcmds.c:152 commands/operatorcmds.c:479 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "l'attribut « %s » de l'opérateur n'est pas reconnu" + +#: commands/operatorcmds.c:163 +#, c-format +msgid "operator function must be specified" +msgstr "la fonction d'opérateur doit être spécifiée" + +#: commands/operatorcmds.c:181 +#, c-format +msgid "operator argument types must be specified" +msgstr "le type des arguments de l'opérateur doit être spécifié" + +#: commands/operatorcmds.c:185 +#, c-format +msgid "operator right argument type must be specified" +msgstr "le type de l'argument droit de l'opérateur doit être spécifié" + +#: commands/operatorcmds.c:186 +#, c-format +msgid "Postfix operators are not supported." +msgstr "Les opérateurs postfixes ne sont pas supportés." + +#: commands/operatorcmds.c:290 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "" +"la fonction d'estimation de la restriction, de nom %s, doit renvoyer le type\n" +"%s" + +#: commands/operatorcmds.c:333 +#, c-format +msgid "join estimator function %s has multiple matches" +msgstr "la fonction d'estimation de la jointure, de nom %s, a plusieurs correspondances" + +#: commands/operatorcmds.c:348 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "" +"la fonction d'estimation de la jointure, de nom %s, doit renvoyer le type\n" +"%s" + +#: commands/operatorcmds.c:473 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "l'attribut « %s » de l'opérateur ne peut pas être changé" + +#: commands/policy.c:89 commands/policy.c:382 commands/policy.c:471 commands/statscmds.c:150 commands/tablecmds.c:1561 commands/tablecmds.c:2150 commands/tablecmds.c:3409 commands/tablecmds.c:5997 commands/tablecmds.c:8859 commands/tablecmds.c:16391 commands/tablecmds.c:16426 commands/trigger.c:295 commands/trigger.c:1271 commands/trigger.c:1380 rewrite/rewriteDefine.c:277 rewrite/rewriteDefine.c:943 rewrite/rewriteRemove.c:80 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "droit refusé : « %s » est un catalogue système" + +#: commands/policy.c:172 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "ingore les rôles spécifiés autre que PUBLIC" + +#: commands/policy.c:173 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "Tous les rôles sont membres du rôle PUBLIC." + +#: commands/policy.c:488 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "le rôle « %s » n'a pas pu être supprimé de la politique « %s » sur « %s »" + +#: commands/policy.c:708 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "WITH CHECK ne peut pas être appliqué à SELECT et DELETE" + +#: commands/policy.c:717 commands/policy.c:1022 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "seule une expression WITH CHECK est autorisée pour INSERT" + +#: commands/policy.c:792 commands/policy.c:1245 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "la politique « %s » pour la table « %s » existe déjà" + +#: commands/policy.c:994 commands/policy.c:1273 commands/policy.c:1344 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "la politique « %s » pour la table « %s » n'existe pas" + +#: commands/policy.c:1012 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "seule une expression USING est autorisée pour SELECT, DELETE" + +#: commands/portalcmds.c:60 commands/portalcmds.c:181 commands/portalcmds.c:232 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "nom de curseur invalide : il ne doit pas être vide" + +#: commands/portalcmds.c:72 +#, c-format +msgid "cannot create a cursor WITH HOLD within security-restricted operation" +msgstr "ne peut pas créer un curseur WITH HOLD à l'intérieur d'une opération restreinte pour sécurité" + +#: commands/portalcmds.c:189 commands/portalcmds.c:242 executor/execCurrent.c:70 utils/adt/xml.c:2594 utils/adt/xml.c:2764 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "le curseur « %s » n'existe pas" + +#: commands/prepare.c:76 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "nom de l'instruction invalide : ne doit pas être vide" + +#: commands/prepare.c:131 parser/parse_param.c:313 tcop/postgres.c:1473 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "n'a pas pu déterminer le type de données du paramètre $%d" + +#: commands/prepare.c:149 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "les instructions utilitaires ne peuvent pas être préparées" + +#: commands/prepare.c:264 commands/prepare.c:269 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "l'instruction préparée n'est pas un SELECT" + +#: commands/prepare.c:329 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "mauvais nombre de paramètres pour l'instruction préparée « %s »" + +#: commands/prepare.c:331 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "%d paramètres attendus mais %d reçus." + +#: commands/prepare.c:364 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "" +"le paramètre $%d de type %s ne peut être utilisé dans la coercion à cause du\n" +"type %s attendu" + +#: commands/prepare.c:448 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "l'instruction préparée « %s » existe déjà" + +#: commands/prepare.c:487 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "l'instruction préparée « %s » n'existe pas" + +#: commands/proclang.c:68 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "doit être super-utilisateur pour créer un langage de procédures personnalisé" + +#: commands/publicationcmds.c:107 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "syntaxe de liste invalide pour l'option « publish »" + +#: commands/publicationcmds.c:125 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "type « publish » non reconnu : « %s »" + +#: commands/publicationcmds.c:140 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "paramètre de publication non reconnu : « %s »" + +#: commands/publicationcmds.c:172 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "doit être super-utilisateur pour créer une publication « FOR ALL TABLES »" + +#: commands/publicationcmds.c:248 +#, c-format +msgid "wal_level is insufficient to publish logical changes" +msgstr "la valeur de wal_level est insuffisante pour publier des modifications logiques" + +#: commands/publicationcmds.c:249 +#, c-format +msgid "Set wal_level to logical before creating subscriptions." +msgstr "Configurez wal_level à la valeur logical pour créer des souscriptions." + +#: commands/publicationcmds.c:369 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "la publication « %s » est définie avec FOR ALL TABLES" + +#: commands/publicationcmds.c:371 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "Les tables ne peuvent pas être ajoutées ou supprimées à des publications FOR ALL TABLES." + +#: commands/publicationcmds.c:660 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "la relation « %s » ne fait pas partie de la publication" + +#: commands/publicationcmds.c:703 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "droit refusé pour modifier le propriétaire de la publication « %s »" + +#: commands/publicationcmds.c:705 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "Le propriétaire d'une publication FOR ALL TABLES doit être un super-utilisateur." + +#: commands/schemacmds.c:105 commands/schemacmds.c:259 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "nom de schéma « %s » inacceptable" + +#: commands/schemacmds.c:106 commands/schemacmds.c:260 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "Le préfixe « pg_ » est réservé pour les schémas système." + +#: commands/schemacmds.c:120 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "la schéma « %s » existe déjà, poursuite du traitement" + +#: commands/seclabel.c:129 +#, c-format +msgid "no security label providers have been loaded" +msgstr "aucun fournisseur de label de sécurité n'a été chargé" + +#: commands/seclabel.c:133 +#, c-format +msgid "must specify provider when multiple security label providers have been loaded" +msgstr "doit indiquer le fournisseur quand plusieurs fournisseurs de labels de sécurité sont chargés" + +#: commands/seclabel.c:151 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "le fournisseur « %s » de label de sécurité n'est pas chargé" + +#: commands/seclabel.c:158 +#, c-format +msgid "security labels are not supported for this type of object" +msgstr "les labels de sécurité ne sont pas supportés pour ce type d'objet" + +#: commands/sequence.c:140 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "les séquences non tracées ne sont pas supportées" + +#: commands/sequence.c:709 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "nextval : valeur maximale de la séquence « %s » (%s) atteinte" + +#: commands/sequence.c:732 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "nextval : valeur minimale de la séquence « %s » (%s) atteinte" + +#: commands/sequence.c:850 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "" +"la valeur courante (currval) de la séquence « %s » n'est pas encore définie\n" +"dans cette session" + +#: commands/sequence.c:869 commands/sequence.c:875 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "la dernière valeur (lastval) n'est pas encore définie dans cette session" + +#: commands/sequence.c:963 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "setval : la valeur %s est en dehors des limites de la séquence « %s » (%s..%s)" + +#: commands/sequence.c:1359 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "option SEQUENCE NAME invalide" + +#: commands/sequence.c:1385 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "le type de colonne identité doit être smallint, integer ou bigint" + +#: commands/sequence.c:1386 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "le type de séquence doit être smallint, integer ou bigint" + +#: commands/sequence.c:1420 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "la valeur INCREMENT ne doit pas être zéro" + +#: commands/sequence.c:1473 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) est hors des limites pour le type de données séquence %s" + +#: commands/sequence.c:1510 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s) est hors des limites pour le type de données séquence %s" + +#: commands/sequence.c:1524 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "la valeur MINVALUE (%s) doit être moindre que la valeur MAXVALUE (%s)" + +#: commands/sequence.c:1551 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "la valeur START (%s) ne peut pas être plus petite que MINVALUE (%s)" + +#: commands/sequence.c:1563 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "la valeur START (%s) ne peut pas être plus grande que MAXVALUE (%s)" + +#: commands/sequence.c:1593 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "la valeur RESTART (%s) ne peut pas être plus petite que celle de MINVALUE (%s)" + +#: commands/sequence.c:1605 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "la valeur RESTART (%s) ne peut pas être plus grande que celle de MAXVALUE (%s)" + +#: commands/sequence.c:1620 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "la valeur CACHE (%s) doit être plus grande que zéro" + +#: commands/sequence.c:1657 +#, c-format +msgid "invalid OWNED BY option" +msgstr "option OWNED BY invalide" + +#: commands/sequence.c:1658 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "Indiquer OWNED BY table.colonne ou OWNED BY NONE." + +#: commands/sequence.c:1683 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr "la relation référencée « %s » n'est ni une table ni une table distante" + +#: commands/sequence.c:1690 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "la séquence doit avoir le même propriétaire que la table avec laquelle elle est liée" + +#: commands/sequence.c:1694 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "la séquence doit être dans le même schéma que la table avec laquelle elle est liée" + +#: commands/sequence.c:1716 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "ne peut pas modifier le propriétaire de la séquence d'identité" + +#: commands/sequence.c:1717 commands/tablecmds.c:13187 commands/tablecmds.c:15816 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "La séquence « %s » est liée à la table « %s »." + +#: commands/statscmds.c:111 commands/statscmds.c:120 tcop/utility.c:1843 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "seule une relation seule est acceptée dans CREATE STATISTICS" + +#: commands/statscmds.c:138 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "la relation « %s » n'est pas une table, une table distante ou une vue matérialisée" + +#: commands/statscmds.c:188 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "l'objet statistique « %s » existe déjà, poursuite du traitement" + +#: commands/statscmds.c:196 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "l'objet statistique « %s » existe déjà" + +#: commands/statscmds.c:207 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "ne peut pas avoir plus de %d colonnes dans des statistiques" + +#: commands/statscmds.c:246 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "la création de statistiques sur les colonnes systèmes n'est pas supportée" + +#: commands/statscmds.c:253 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "la colonne « %s » ne peut pas être utilisée dans des statistiques parce que son type %s n'a pas de classe d'opérateur btree par défaut" + +#: commands/statscmds.c:282 +#, c-format +msgid "expression cannot be used in multivariate statistics because its type %s has no default btree operator class" +msgstr "l'expression ne peut pas être utilisée dans des statistiques multivariates parce que son type %s n'a pas de classe d'opérateur btree par défaut" + +#: commands/statscmds.c:303 +#, c-format +msgid "when building statistics on a single expression, statistics kinds may not be specified" +msgstr "" + +#: commands/statscmds.c:332 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "type de statistique « %s » non reconnu" + +#: commands/statscmds.c:361 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "les statistiques étendues requièrent au moins 2 colonnes" + +#: commands/statscmds.c:379 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "nom de colonne dupliqué dans la définition des statistiques" + +#: commands/statscmds.c:414 +#, c-format +msgid "duplicate expression in statistics definition" +msgstr "expression dupliquée dans la définition des statistiques" + +#: commands/statscmds.c:595 commands/tablecmds.c:7829 +#, c-format +msgid "statistics target %d is too low" +msgstr "la cible statistique %d est trop basse" + +#: commands/statscmds.c:603 commands/tablecmds.c:7837 +#, c-format +msgid "lowering statistics target to %d" +msgstr "abaissement de la cible statistique à %d" + +#: commands/statscmds.c:626 +#, c-format +msgid "statistics object \"%s.%s\" does not exist, skipping" +msgstr "l'objet statistique « %s.%s » n'existe pas, poursuite du traitement" + +#: commands/subscriptioncmds.c:221 +#, c-format +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "paramètre de souscription non reconnu : « %s »" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:235 commands/subscriptioncmds.c:241 commands/subscriptioncmds.c:247 commands/subscriptioncmds.c:266 commands/subscriptioncmds.c:272 +#, c-format +msgid "%s and %s are mutually exclusive options" +msgstr "%s et %s sont des options mutuellement exclusives" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:279 commands/subscriptioncmds.c:285 +#, c-format +msgid "subscription with %s must also set %s" +msgstr "la souscription avec %s doit aussi configurer %s" + +#: commands/subscriptioncmds.c:378 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "doit être super-utilisateur pour créer des souscriptions" + +#: commands/subscriptioncmds.c:472 commands/subscriptioncmds.c:570 replication/logical/tablesync.c:975 replication/logical/worker.c:3212 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "n'a pas pu se connecter au publieur : %s" + +#: commands/subscriptioncmds.c:514 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "création du slot de réplication « %s » sur le publieur" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:527 +#, c-format +msgid "tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "les tables n'étaient pas souscrites, vous devrez exécuter %s pour souscrire aux tables" + +#: commands/subscriptioncmds.c:826 +#, c-format +msgid "cannot set %s for enabled subscription" +msgstr "ne peut définir %s pour une souscription active" + +#: commands/subscriptioncmds.c:882 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "ne peut pas activer une souscription qui n'a pas de nom de slot" + +#: commands/subscriptioncmds.c:934 commands/subscriptioncmds.c:982 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION avec rafraîchissement n'est pas autorisé pour les souscriptions désactivées" + +#: commands/subscriptioncmds.c:935 commands/subscriptioncmds.c:983 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "Utilisez ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:1003 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESH n'est pas autorisé pour les souscriptions désactivées" + +#: commands/subscriptioncmds.c:1091 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "la souscription « %s » n'existe pas, poursuite du traitement" + +#: commands/subscriptioncmds.c:1343 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "slot de réplication « %s » supprimé sur le publieur" + +#: commands/subscriptioncmds.c:1352 commands/subscriptioncmds.c:1360 +#, c-format +msgid "could not drop replication slot \"%s\" on publisher: %s" +msgstr "n'a pas pu supprimer le slot de réplication « %s » sur le publieur : %s" + +#: commands/subscriptioncmds.c:1394 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "droit refusé pour modifier le propriétaire de la souscription « %s »" + +#: commands/subscriptioncmds.c:1396 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "Le propriétaire d'une souscription doit être un super-utilisateur." + +#: commands/subscriptioncmds.c:1512 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "n'a pas pu recevoir la liste des tables répliquées à partir du publieur : %s" + +#: commands/subscriptioncmds.c:1577 +#, c-format +msgid "could not connect to publisher when attempting to drop replication slot \"%s\": %s" +msgstr "n'a pas pu se connecter au publieur lors de la tentative de suppression du slot de réplication « %s » : %s" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:1580 +#, c-format +msgid "Use %s to disassociate the subscription from the slot." +msgstr "Utilisez %s pour dissocier la souscription du slot." + +#: commands/subscriptioncmds.c:1610 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "nom de publication « %s » utilisé plus d'une fois" + +#: commands/subscriptioncmds.c:1654 +#, c-format +msgid "publication \"%s\" is already in subscription \"%s\"" +msgstr "la publication « %s » est déjà dans la souscription « %s »" + +#: commands/subscriptioncmds.c:1668 +#, c-format +msgid "publication \"%s\" is not in subscription \"%s\"" +msgstr "la publication « %s » n'est pas dans la souscription « %s »" + +#: commands/subscriptioncmds.c:1679 +#, c-format +msgid "subscription must contain at least one publication" +msgstr "la souscription doit contenir au moins une publication" + +#: commands/tablecmds.c:241 commands/tablecmds.c:283 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "la table « %s » n'existe pas" + +#: commands/tablecmds.c:242 commands/tablecmds.c:284 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "la table « %s » n'existe pas, poursuite du traitement" + +#: commands/tablecmds.c:244 commands/tablecmds.c:286 +msgid "Use DROP TABLE to remove a table." +msgstr "Utilisez DROP TABLE pour supprimer une table." + +#: commands/tablecmds.c:247 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "la séquence « %s » n'existe pas" + +#: commands/tablecmds.c:248 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "la séquence « %s » n'existe pas, poursuite du traitement" + +#: commands/tablecmds.c:250 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "Utilisez DROP SEQUENCE pour supprimer une séquence." + +#: commands/tablecmds.c:253 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "la vue « %s » n'existe pas" + +#: commands/tablecmds.c:254 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "la vue « %s » n'existe pas, poursuite du traitement" + +#: commands/tablecmds.c:256 +msgid "Use DROP VIEW to remove a view." +msgstr "Utilisez DROP VIEW pour supprimer une vue." + +#: commands/tablecmds.c:259 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr "la vue matérialisée « %s » n'existe pas" + +#: commands/tablecmds.c:260 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr "la vue matérialisée « %s » n'existe pas, poursuite du traitement" + +#: commands/tablecmds.c:262 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "Utilisez DROP MATERIALIZED VIEW pour supprimer une vue matérialisée." + +#: commands/tablecmds.c:265 commands/tablecmds.c:289 commands/tablecmds.c:18237 parser/parse_utilcmd.c:2247 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "l'index « %s » n'existe pas" + +#: commands/tablecmds.c:266 commands/tablecmds.c:290 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "l'index « %s » n'existe pas, poursuite du traitement" + +#: commands/tablecmds.c:268 commands/tablecmds.c:292 +msgid "Use DROP INDEX to remove an index." +msgstr "Utilisez DROP INDEX pour supprimer un index." + +#: commands/tablecmds.c:273 +#, c-format +msgid "\"%s\" is not a type" +msgstr "« %s » n'est pas un type" + +#: commands/tablecmds.c:274 +msgid "Use DROP TYPE to remove a type." +msgstr "Utilisez DROP TYPE pour supprimer un type." + +#: commands/tablecmds.c:277 commands/tablecmds.c:13026 commands/tablecmds.c:15519 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "la table distante « %s » n'existe pas" + +#: commands/tablecmds.c:278 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "la table distante « %s » n'existe pas, poursuite du traitement" + +#: commands/tablecmds.c:280 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "Utilisez DROP FOREIGN TABLE pour supprimer une table distante." + +#: commands/tablecmds.c:664 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMIT peut seulement être utilisé sur des tables temporaires" + +#: commands/tablecmds.c:695 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "" +"ne peut pas créer une table temporaire à l'intérieur d'une fonction\n" +"restreinte pour sécurité" + +#: commands/tablecmds.c:731 commands/tablecmds.c:14310 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "la relation « %s » serait héritée plus d'une fois" + +#: commands/tablecmds.c:916 +#, c-format +msgid "specifying a table access method is not supported on a partitioned table" +msgstr "spécifier une méthode d'accès à la table n'est pas supporté sur une partitionnée" + +#: commands/tablecmds.c:1012 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "« %s » n'est pas partitionné" + +#: commands/tablecmds.c:1107 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "ne peut pas partitionner en utilisant plus de %d colonnes" + +#: commands/tablecmds.c:1163 +#, c-format +msgid "cannot create foreign partition of partitioned table \"%s\"" +msgstr "ne peut pas créer une partition distante sur la table partitionnée « %s »" + +#: commands/tablecmds.c:1165 +#, c-format +msgid "Table \"%s\" contains indexes that are unique." +msgstr "La table « %s » contient des index qui sont uniques." + +#: commands/tablecmds.c:1328 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLY ne permet pas de supprimer plusieurs objets" + +#: commands/tablecmds.c:1332 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLY ne permet pas la CASCADE" + +#: commands/tablecmds.c:1433 +#, c-format +msgid "cannot drop partitioned index \"%s\" concurrently" +msgstr "ne peut pas supprimer l'index partitionné « %s » de manière concurrente" + +#: commands/tablecmds.c:1705 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "ne peut pas seulement tronquer une table partitionnée" + +#: commands/tablecmds.c:1706 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "Ne spécifiez pas le mot clé ONLY ou utilisez TRUNCATE ONLY directement sur les partitions." + +#: commands/tablecmds.c:1779 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "TRUNCATE cascade sur la table « %s »" + +#: commands/tablecmds.c:2138 +#, c-format +msgid "cannot truncate foreign table \"%s\"" +msgstr "ne peut pas tronquer la table distante « %s »" + +#: commands/tablecmds.c:2187 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "ne peut pas tronquer les tables temporaires des autres sessions" + +#: commands/tablecmds.c:2449 commands/tablecmds.c:14207 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "ne peut pas hériter de la table partitionnée « %s »" + +#: commands/tablecmds.c:2454 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "ne peut pas hériter de la partition « %s »" + +#: commands/tablecmds.c:2462 parser/parse_utilcmd.c:2477 parser/parse_utilcmd.c:2619 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "la relation héritée « %s » n'est ni une table ni une table distante" + +#: commands/tablecmds.c:2474 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "ne peut pas créer une relation temporaire comme partition de la relation permanente « %s »" + +#: commands/tablecmds.c:2483 commands/tablecmds.c:14186 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "ine peut pas hériter à partir d'une relation temporaire « %s »" + +#: commands/tablecmds.c:2493 commands/tablecmds.c:14194 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "ne peut pas hériter de la table temporaire d'une autre session" + +#: commands/tablecmds.c:2547 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "assemblage de plusieurs définitions d'héritage pour la colonne « %s »" + +#: commands/tablecmds.c:2555 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "la colonne héritée « %s » a un conflit de type" + +#: commands/tablecmds.c:2557 commands/tablecmds.c:2580 commands/tablecmds.c:2597 commands/tablecmds.c:2853 commands/tablecmds.c:2883 commands/tablecmds.c:2897 parser/parse_coerce.c:2090 parser/parse_coerce.c:2110 parser/parse_coerce.c:2130 parser/parse_coerce.c:2150 parser/parse_coerce.c:2205 parser/parse_coerce.c:2238 parser/parse_coerce.c:2316 parser/parse_coerce.c:2348 parser/parse_coerce.c:2382 parser/parse_coerce.c:2402 parser/parse_param.c:227 +#, c-format +msgid "%s versus %s" +msgstr "%s versus %s" + +#: commands/tablecmds.c:2566 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "la colonne héritée « %s » a un conflit sur le collationnement" + +#: commands/tablecmds.c:2568 commands/tablecmds.c:2865 commands/tablecmds.c:6497 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "« %s » versus « %s »" + +#: commands/tablecmds.c:2578 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "la colonne héritée « %s » a un conflit de paramètre de stockage" + +#: commands/tablecmds.c:2595 commands/tablecmds.c:2895 +#, c-format +msgid "column \"%s\" has a compression method conflict" +msgstr "la colonne « %s » a un conflit sur la méthode de compression" + +#: commands/tablecmds.c:2610 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "la colonne héritée « %s » a un conflit de génération" + +#: commands/tablecmds.c:2704 commands/tablecmds.c:2759 commands/tablecmds.c:11771 parser/parse_utilcmd.c:1291 parser/parse_utilcmd.c:1334 parser/parse_utilcmd.c:1742 parser/parse_utilcmd.c:1850 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "ne peut pas convertir une référence de ligne complète de table" + +#: commands/tablecmds.c:2705 parser/parse_utilcmd.c:1292 +#, c-format +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "L'expression de génération de la colonne « %s » contient une référence de ligne complète vers la table « %s »." + +#: commands/tablecmds.c:2760 parser/parse_utilcmd.c:1335 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "La constrainte « %s » contient une référence de ligne complète vers la table « %s »." + +#: commands/tablecmds.c:2839 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "assemblage de la colonne « %s » avec une définition héritée" + +#: commands/tablecmds.c:2843 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "déplacement et assemblage de la colonne « %s » avec une définition héritée" + +#: commands/tablecmds.c:2844 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "Colonne utilisateur déplacée à la position de la colonne héritée." + +#: commands/tablecmds.c:2851 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "la colonne « %s » a un conflit de type" + +#: commands/tablecmds.c:2863 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "la colonne « %s » a un conflit sur le collationnement" + +#: commands/tablecmds.c:2881 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "la colonne « %s » a un conflit de paramètre de stockage" + +#: commands/tablecmds.c:2922 +#, c-format +msgid "child column \"%s\" specifies generation expression" +msgstr "la colonne enfant « %s » précise une expression de génération" + +#: commands/tablecmds.c:2924 +#, c-format +msgid "Omit the generation expression in the definition of the child table column to inherit the generation expression from the parent table." +msgstr "Omettre l'expression de génération dans la définition de la colonne de la table fille pour hériter de l'expression de génération de la table parent." + +#: commands/tablecmds.c:2928 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies default" +msgstr "la colonne « %s » hérite d'une colonne générée mais indique une valeur par défaut" + +#: commands/tablecmds.c:2933 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies identity" +msgstr "la colonne « %s » hérite d'une colonne générée mais précise une identité" + +#: commands/tablecmds.c:3042 +#, c-format +msgid "column \"%s\" inherits conflicting generation expressions" +msgstr "la colonne « %s » hérite d'expressions de génération en conflit" + +#: commands/tablecmds.c:3047 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "la colonne « %s » hérite de valeurs par défaut conflictuelles" + +#: commands/tablecmds.c:3049 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "Pour résoudre le conflit, spécifiez explicitement une valeur par défaut." + +#: commands/tablecmds.c:3095 +#, c-format +msgid "check constraint name \"%s\" appears multiple times but with different expressions" +msgstr "" +"le nom de la contrainte de vérification, « %s », apparaît plusieurs fois\n" +"mais avec des expressions différentes" + +#: commands/tablecmds.c:3308 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "ne peut pas déplacer les tables temporaires d'autres sessions" + +#: commands/tablecmds.c:3378 +#, c-format +msgid "cannot rename column of typed table" +msgstr "ne peut pas renommer une colonne d'une table typée" + +#: commands/tablecmds.c:3397 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" +msgstr "« %s » n'est ni une table, ni une vue, ni une vue matérialisée, ni un type composite, ni un index, ni une table distante" + +#: commands/tablecmds.c:3491 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "la colonne héritée « %s » doit aussi être renommée pour les tables filles" + +#: commands/tablecmds.c:3523 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "ne peut pas renommer la colonne système « %s »" + +#: commands/tablecmds.c:3538 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "ne peut pas renommer la colonne héritée « %s »" + +#: commands/tablecmds.c:3690 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "la contrainte héritée « %s » doit aussi être renommée pour les tables enfants" + +#: commands/tablecmds.c:3697 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "ne peut pas renommer la colonne héritée « %s »" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3930 +#, c-format +msgid "cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "" +"ne peut pas exécuter %s « %s » car cet objet est en cours d'utilisation par\n" +"des requêtes actives dans cette session" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3939 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "ne peut pas exécuter %s « %s » car il reste des événements sur les triggers" + +#: commands/tablecmds.c:4403 +#, c-format +msgid "cannot alter partition \"%s\" with an incomplete detach" +msgstr "ne peut pas modifier la partition « %s » avec un détachement incomplet" + +#: commands/tablecmds.c:4405 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the pending detach operation." +msgstr "Utiliser ALTER TABLE ... DETACH PARTITION ... FINALIZE pour terminer l'opération de détachement en attente." + +#: commands/tablecmds.c:4596 commands/tablecmds.c:4611 +#, c-format +msgid "cannot change persistence setting twice" +msgstr "ne peut pas modifier la configuration de la persistence deux fois" + +#: commands/tablecmds.c:5354 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "ne peut pas ré-écrire la relation système « %s »" + +#: commands/tablecmds.c:5360 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "ne peut pas réécrire la table « %s » utilisée comme une table catalogue" + +#: commands/tablecmds.c:5370 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "ne peut pas ré-écrire les tables temporaires des autres sessions" + +#: commands/tablecmds.c:5831 +#, c-format +msgid "column \"%s\" of relation \"%s\" contains null values" +msgstr "la colonne « %s » de la table « %s » contient des valeurs NULL" + +#: commands/tablecmds.c:5848 +#, c-format +msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" +msgstr "la contrainte de vérification « %s » de la relation « %s » est violée par une ligne" + +#: commands/tablecmds.c:5867 partitioning/partbounds.c:3282 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "la contrainte de partition mise à jour pour la partition par défaut « %s » serait transgressée par des lignes" + +#: commands/tablecmds.c:5873 +#, c-format +msgid "partition constraint of relation \"%s\" is violated by some row" +msgstr "la contrainte de partition de la relation « %s » est violée par une ligne" + +#: commands/tablecmds.c:6021 commands/trigger.c:1265 commands/trigger.c:1371 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "« %s » n'est ni une table, ni une vue, ni une table distante" + +#: commands/tablecmds.c:6024 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "« %s » n'est ni une table, ni une vue, ni une vue matérialisée, ni une séquence, ni une table distante" + +#: commands/tablecmds.c:6030 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "« %s » n'est ni une table, ni une vue matérialisée, ni un index" + +#: commands/tablecmds.c:6033 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "« %s » n'est ni une table, ni une vue matérialisée, ni une table distante" + +#: commands/tablecmds.c:6036 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "« %s » n'est ni une table ni une table distante" + +#: commands/tablecmds.c:6039 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "« %s » n'est ni une table, ni un type composite, ni une table distante" + +#: commands/tablecmds.c:6042 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "« %s » n'est ni une table, ni une vue matérialisée, ni un index, ni une table distante" + +#: commands/tablecmds.c:6052 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "« %s » est du mauvais type" + +#: commands/tablecmds.c:6255 commands/tablecmds.c:6262 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "ne peux pas modifier le type « %s » car la colonne « %s.%s » l'utilise" + +#: commands/tablecmds.c:6269 +#, c-format +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "" +"ne peut pas modifier la table distante « %s » car la colonne « %s.%s » utilise\n" +"son type de ligne" + +#: commands/tablecmds.c:6276 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "" +"ne peut pas modifier la table « %s » car la colonne « %s.%s » utilise\n" +"son type de ligne" + +#: commands/tablecmds.c:6332 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "ne peut pas modifier le type « %s » car il s'agit du type d'une table de type" + +#: commands/tablecmds.c:6334 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "Utilisez ALTER ... CASCADE pour modifier aussi les tables de type." + +#: commands/tablecmds.c:6380 +#, c-format +msgid "type %s is not a composite type" +msgstr "le type %s n'est pas un type composite" + +#: commands/tablecmds.c:6407 +#, c-format +msgid "cannot add column to typed table" +msgstr "ne peut pas ajouter une colonne à une table typée" + +#: commands/tablecmds.c:6460 +#, c-format +msgid "cannot add column to a partition" +msgstr "ne peut pas ajouter une colonne à une partition" + +#: commands/tablecmds.c:6489 commands/tablecmds.c:14437 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "la table fille « %s » a un type différent pour la colonne « %s »" + +#: commands/tablecmds.c:6495 commands/tablecmds.c:14444 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "la table fille « %s » a un collationnement différent pour la colonne « %s »" + +#: commands/tablecmds.c:6509 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "assemblage de la définition de la colonne « %s » pour le fils « %s »" + +#: commands/tablecmds.c:6552 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "ne peut pas ajouter récursivement la colonne identité à une table qui a des tables filles" + +#: commands/tablecmds.c:6795 +#, c-format +msgid "column must be added to child tables too" +msgstr "la colonne doit aussi être ajoutée aux tables filles" + +#: commands/tablecmds.c:6873 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "la colonne « %s » de la relation « %s » existe déjà, poursuite du traitement" + +#: commands/tablecmds.c:6880 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "la colonne « %s » de la relation « %s » existe déjà" + +#: commands/tablecmds.c:6946 commands/tablecmds.c:11409 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "ne peut pas supprimer une contrainte uniquement d'une table partitionnée quand des partitions existent" + +#: commands/tablecmds.c:6947 commands/tablecmds.c:7251 commands/tablecmds.c:8274 commands/tablecmds.c:11410 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "Ne spécifiez pas le mot clé ONLY." + +#: commands/tablecmds.c:6984 commands/tablecmds.c:7177 commands/tablecmds.c:7319 commands/tablecmds.c:7433 commands/tablecmds.c:7527 commands/tablecmds.c:7586 commands/tablecmds.c:7704 commands/tablecmds.c:7870 commands/tablecmds.c:7940 commands/tablecmds.c:8096 commands/tablecmds.c:11564 commands/tablecmds.c:13049 commands/tablecmds.c:15610 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "n'a pas pu modifier la colonne système « %s »" + +#: commands/tablecmds.c:6990 commands/tablecmds.c:7325 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne d'identité" + +#: commands/tablecmds.c:7026 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "la colonne « %s » est dans une clé primaire" + +#: commands/tablecmds.c:7048 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "la colonne « %s » est marquée NOT NULL dans la table parent" + +#: commands/tablecmds.c:7248 commands/tablecmds.c:8757 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "la contrainte doit aussi être ajoutée aux tables filles" + +#: commands/tablecmds.c:7249 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "la colonne « %s » de la relation « %s » n'est pas déjà NOT NULL." + +#: commands/tablecmds.c:7327 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "Utilisez à la place ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." + +#: commands/tablecmds.c:7332 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "la colonne « %s » de la relation « %s » est une colonne générée" + +#: commands/tablecmds.c:7335 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." +msgstr "Utilisez à la place ALTER TABLE ... ALTER COLUMN ... DROP EXTENSION." + +#: commands/tablecmds.c:7444 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "la colonne « %s » de la relation « %s » doit être déclarée NOT NULL avant que la colonne identité puisse être ajoutée" + +#: commands/tablecmds.c:7450 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "la colonne « %s » de la relation « %s » est déjà une colonne d'identité" + +#: commands/tablecmds.c:7456 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "la colonne « %s » de la relation « %s » a déjà une valeur par défaut" + +#: commands/tablecmds.c:7533 commands/tablecmds.c:7594 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne d'identité" + +#: commands/tablecmds.c:7599 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne d'identité, poursuite du traitement" + +#: commands/tablecmds.c:7652 +#, c-format +msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" +msgstr "ALTER TABLE / DROP EXPRESSION doit aussi être appliqué aux tables filles" + +#: commands/tablecmds.c:7674 +#, c-format +msgid "cannot drop generation expression from inherited column" +msgstr "ne peut pas supprimer l'expression de génération à partir d'une colonne héritée" + +#: commands/tablecmds.c:7712 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column" +msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne générée stockée" + +#: commands/tablecmds.c:7717 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column, skipping" +msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne générée stockée, ignoré" + +#: commands/tablecmds.c:7817 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "impossible de référence une colonne non liée à une table par un nombre" + +#: commands/tablecmds.c:7860 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "la colonne numéro %d de la relation « %s » n'existe pas" + +#: commands/tablecmds.c:7879 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "ne peut modifier les statistiques sur la colonne incluse « %s » de l'index « %s »" + +#: commands/tablecmds.c:7884 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "ne peut modifier les statistiques sur la colonne « %s » de l'index « %s », qui n'est pas une expression" + +#: commands/tablecmds.c:7886 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Modifie les statistiques sur la colonne de la table à la place." + +#: commands/tablecmds.c:8076 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "type de stockage « %s » invalide" + +#: commands/tablecmds.c:8108 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "le type de données %s de la colonne peut seulement avoir un stockage PLAIN" + +#: commands/tablecmds.c:8153 +#, c-format +msgid "cannot drop column from typed table" +msgstr "ne peut pas supprimer une colonne à une table typée" + +#: commands/tablecmds.c:8212 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "la colonne « %s » de la relation « %s » n'existe pas, ignore" + +#: commands/tablecmds.c:8225 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "ne peut pas supprimer la colonne système « %s »" + +#: commands/tablecmds.c:8235 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "ne peut pas supprimer la colonne héritée « %s »" + +#: commands/tablecmds.c:8248 +#, c-format +msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "ne peut supprimer la colonne « %s » car elle fait partie de la clé de partitionnement de la relation « %s »" + +#: commands/tablecmds.c:8273 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "ne peut pas supprimer une colonne sur une seule partition quand plusieurs partitions existent" + +#: commands/tablecmds.c:8477 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX n'est pas supporté sur les tables partitionnées" + +#: commands/tablecmds.c:8502 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX renommera l'index « %s » en « %s »" + +#: commands/tablecmds.c:8837 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "ne peut pas utiliser ONLY pour une clé étrangère sur la table partitionnée « %s » référençant la relation « %s »" + +#: commands/tablecmds.c:8843 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "ne peut pas ajouter de clé étrangère NOT VALID sur la table partitionnée « %s » référençant la relation « %s »" + +#: commands/tablecmds.c:8846 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Cette fonctionnalité n'est pas encore implémentée sur les tables partitionnées." + +#: commands/tablecmds.c:8853 commands/tablecmds.c:9258 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "la relation référencée « %s » n'est pas une table" + +#: commands/tablecmds.c:8876 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "les contraintes sur les tables permanentes peuvent seulement référencer des tables permanentes" + +#: commands/tablecmds.c:8883 +#, c-format +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" +msgstr "les contraintes sur les tables non tracées peuvent seulement référencer des tables permanentes ou non tracées" + +#: commands/tablecmds.c:8889 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "" +"les contraintes sur des tables temporaires ne peuvent référencer que des\n" +"tables temporaires" + +#: commands/tablecmds.c:8893 +#, c-format +msgid "constraints on temporary tables must involve temporary tables of this session" +msgstr "" +"les contraintes sur des tables temporaires doivent référencer les tables\n" +"temporaires de cette session" + +#: commands/tablecmds.c:8959 commands/tablecmds.c:8965 +#, c-format +msgid "invalid %s action for foreign key constraint containing generated column" +msgstr "action %s invalide pour une clé étrangère contenant une colonne générée" + +#: commands/tablecmds.c:8981 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "nombre de colonnes de référence et référencées pour la clé étrangère en désaccord" + +#: commands/tablecmds.c:9088 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "la contrainte de clé étrangère « %s » ne peut pas être implémentée" + +#: commands/tablecmds.c:9090 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "Les colonnes clés « %s » et « %s » sont de types incompatibles : %s et %s." + +#: commands/tablecmds.c:9453 commands/tablecmds.c:9846 parser/parse_utilcmd.c:786 parser/parse_utilcmd.c:915 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "les clés étrangères ne sont pas supportées par les tables distantes" + +#: commands/tablecmds.c:10213 commands/tablecmds.c:10491 commands/tablecmds.c:11366 commands/tablecmds.c:11441 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "la contrainte « %s » de la relation « %s » n'existe pas" + +#: commands/tablecmds.c:10220 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "la contrainte « %s » de la relation « %s » n'est pas une clé étrangère" + +#: commands/tablecmds.c:10258 +#, c-format +msgid "cannot alter constraint \"%s\" on relation \"%s\"" +msgstr "ne peut pas modifier la contrainte « %s » de la relation « %s »" + +#: commands/tablecmds.c:10261 +#, c-format +msgid "Constraint \"%s\" is derived from constraint \"%s\" of relation \"%s\"." +msgstr "La contrainte « %s » est dérivée de la contrainte « %s » de la relation « %s »" + +#: commands/tablecmds.c:10263 +#, c-format +msgid "You may alter the constraint it derives from, instead." +msgstr "Vous pouvez modifier la contrainte dont elle dérive à la place." + +#: commands/tablecmds.c:10499 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "la contrainte « %s » de la relation « %s » n'est pas une clé étrangère ou une contrainte de vérification" + +#: commands/tablecmds.c:10577 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "la contrainte doit aussi être validée sur les tables enfants" + +#: commands/tablecmds.c:10661 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "la colonne « %s » référencée dans la contrainte de clé étrangère n'existe pas" + +#: commands/tablecmds.c:10666 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "ne peut pas avoir plus de %d clés dans une clé étrangère" + +#: commands/tablecmds.c:10731 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "ne peut pas utiliser une clé primaire déferrable pour la table « %s » référencée" + +#: commands/tablecmds.c:10748 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "il n'y a pas de clé primaire pour la table « %s » référencée" + +#: commands/tablecmds.c:10813 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "la liste de colonnes référencées dans la clé étrangère ne doit pas contenir de duplicats" + +#: commands/tablecmds.c:10907 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "" +"ne peut pas utiliser une contrainte unique déferrable pour la table\n" +"référencée « %s »" + +#: commands/tablecmds.c:10912 +#, c-format +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "il n'existe aucune contrainte unique correspondant aux clés données pour la table « %s » référencée" + +#: commands/tablecmds.c:11322 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "ne peut pas supprimer la contrainte héritée « %s » de la relation « %s »" + +#: commands/tablecmds.c:11372 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "la contrainte « %s » de la relation « %s » n'existe pas, ignore" + +#: commands/tablecmds.c:11548 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "ne peut pas modifier le type d'une colonne appartenant à une table typée" + +#: commands/tablecmds.c:11575 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "ne peut pas modifier la colonne héritée « %s »" + +#: commands/tablecmds.c:11584 +#, c-format +msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "ne peut pas modifier la colonne « %s » car elle fait partie de la clé de partitionnement de la relation « %s »" + +#: commands/tablecmds.c:11634 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "le résultat de la clause USING pour la colonne « %s » ne peut pas être converti automatiquement vers le type %s" + +#: commands/tablecmds.c:11637 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "Vous pouvez avoir besoin d'ajouter une conversion explicite." + +#: commands/tablecmds.c:11641 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "la colonne « %s » ne peut pas être convertie vers le type %s" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:11644 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "Vous pouvez avoir besoin de spécifier \"USING %s::%s\"." + +#: commands/tablecmds.c:11744 +#, c-format +msgid "cannot alter inherited column \"%s\" of relation \"%s\"" +msgstr "ne peut pas modifier la colonne héritée « %s » de la relation « %s »" + +#: commands/tablecmds.c:11772 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "l'expression USING contient une référence de table de ligne complète." + +#: commands/tablecmds.c:11783 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "le type de colonne héritée « %s » doit aussi être renommée pour les tables filles" + +#: commands/tablecmds.c:11908 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "ne peut pas modifier la colonne « %s » deux fois" + +#: commands/tablecmds.c:11946 +#, c-format +msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" +msgstr "l'expression de génération de la colonne « %s » ne peut pas être convertie vers le type %s automatiquement" + +#: commands/tablecmds.c:11951 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "" +"la valeur par défaut de la colonne « %s » ne peut pas être convertie vers le\n" +"type %s automatiquement" + +#: commands/tablecmds.c:12029 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "ne peut pas modifier le type d'une colonne utilisée dans colonne générée" + +#: commands/tablecmds.c:12030 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "La colonne « %s » est utilisée par la colonne générée « %s »" + +#: commands/tablecmds.c:12051 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "ne peut pas modifier le type d'une colonne utilisée dans une vue ou une règle" + +#: commands/tablecmds.c:12052 commands/tablecmds.c:12071 commands/tablecmds.c:12089 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%s dépend de la colonne « %s »" + +#: commands/tablecmds.c:12070 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "ne peut pas modifier le type d'une colonne utilisée dans la définition d'un trigger" + +#: commands/tablecmds.c:12088 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "ne peut pas modifier le type d'une colonne utilisée dans la définition d'une politique" + +#: commands/tablecmds.c:13157 commands/tablecmds.c:13169 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "ne peut pas modifier le propriétaire de l'index « %s »" + +#: commands/tablecmds.c:13159 commands/tablecmds.c:13171 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "Modifier à la place le propriétaire de la table concernée par l'index." + +#: commands/tablecmds.c:13185 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "ne peut pas modifier le propriétaire de la séquence « %s »" + +#: commands/tablecmds.c:13199 commands/tablecmds.c:16502 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "Utilisez ALTER TYPE à la place." + +#: commands/tablecmds.c:13208 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "« %s » n'est ni une table, ni une vue, ni une séquence, ni une table distante" + +#: commands/tablecmds.c:13547 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "ne peut pas avoir de nombreuses sous-commandes SET TABLESPACE" + +#: commands/tablecmds.c:13624 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "« %s » n'est ni une table, ni une vue, ni une vue matérialisée, ni un index, ni une table TOAST" + +#: commands/tablecmds.c:13657 commands/view.c:491 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "WITH CHECK OPTION est uniquement accepté pour les vues dont la mise à jour est automatique" + +#: commands/tablecmds.c:13909 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "seuls les tables, index et vues matérialisées existent dans les tablespaces" + +#: commands/tablecmds.c:13921 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "ne peut pas déplacer les relations dans ou à partir du tablespace pg_global" + +#: commands/tablecmds.c:14013 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "annulation car le verrou sur la relation « %s.%s » n'est pas disponible" + +#: commands/tablecmds.c:14029 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "aucune relation correspondante trouvée dans le tablespace « %s »" + +#: commands/tablecmds.c:14145 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "ne peut pas modifier l'héritage d'une table typée" + +#: commands/tablecmds.c:14150 commands/tablecmds.c:14706 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "ne peut pas modifier l'héritage d'une partition" + +#: commands/tablecmds.c:14155 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "ne peut pas modifier l'héritage d'une table partitionnée" + +#: commands/tablecmds.c:14201 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "ne peut pas hériter à partir d'une relation temporaire d'une autre session" + +#: commands/tablecmds.c:14214 +#, c-format +msgid "cannot inherit from a partition" +msgstr "ne peut pas hériter d'une partition" + +#: commands/tablecmds.c:14236 commands/tablecmds.c:17146 +#, c-format +msgid "circular inheritance not allowed" +msgstr "héritage circulaire interdit" + +#: commands/tablecmds.c:14237 commands/tablecmds.c:17147 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "« %s » est déjà un enfant de « %s »." + +#: commands/tablecmds.c:14250 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "le trigger « %s » empêche la table « %s » de devenir une fille dans l'héritage" + +#: commands/tablecmds.c:14252 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." +msgstr "les triggers ROW avec des tables de transition ne sont pas supportés dans les hiérarchies d'héritage." + +#: commands/tablecmds.c:14455 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "la colonne « %s » de la table enfant doit être marquée comme NOT NULL" + +#: commands/tablecmds.c:14464 +#, c-format +msgid "column \"%s\" in child table must be a generated column" +msgstr "la colonne « %s » de la table enfant doit être une colonne générée" + +#: commands/tablecmds.c:14514 +#, c-format +msgid "column \"%s\" in child table has a conflicting generation expression" +msgstr "la colonne « %s » de la table enfant a une expression de génération en conflit" + +#: commands/tablecmds.c:14542 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "la table enfant n'a pas de colonne « %s »" + +#: commands/tablecmds.c:14630 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "la table fille « %s » a un type différent pour la contrainte de vérification « %s »" + +#: commands/tablecmds.c:14638 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" +msgstr "la contrainte « %s » entre en conflit avec une contrainte non héritée sur la table fille « %s »" + +#: commands/tablecmds.c:14649 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "la contrainte « %s » entre en conflit avec une contrainte NOT VALID sur la table fille « %s »" + +#: commands/tablecmds.c:14684 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "la table enfant n'a pas de contrainte « %s »" + +#: commands/tablecmds.c:14772 +#, c-format +msgid "partition \"%s\" already pending detach in partitioned table \"%s.%s\"" +msgstr "la partition « %s » déjà en attente de détachement de la table partitionnée « %s.%s »" + +#: commands/tablecmds.c:14776 +#, c-format +msgid "Use ALTER TABLE ... DETACH PARTITION ... FINALIZE to complete the detach operation." +msgstr "Utiliser ALTER TABLE ... DETACH PARTITION ... FINALIZE pour terminer l'opération de détachement." + +#: commands/tablecmds.c:14801 commands/tablecmds.c:14849 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "la relation « %s » n'est pas une partition de la relation « %s »" + +#: commands/tablecmds.c:14855 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "la relation « %s » n'est pas un parent de la relation « %s »" + +#: commands/tablecmds.c:15083 +#, c-format +msgid "typed tables cannot inherit" +msgstr "les tables avec type ne peuvent pas hériter d'autres tables" + +#: commands/tablecmds.c:15113 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "la colonne « %s » manque à la table" + +#: commands/tablecmds.c:15124 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "la table a une colonne « %s » alors que le type impose « %s »" + +#: commands/tablecmds.c:15133 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "la table « %s » a un type différent pour la colonne « %s »" + +#: commands/tablecmds.c:15147 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "la table a une colonne supplémentaire « %s »" + +#: commands/tablecmds.c:15199 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "« %s » n'est pas une table typée" + +#: commands/tablecmds.c:15381 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "ne peut pas utiliser l'index non unique « %s » comme identité de réplicat" + +#: commands/tablecmds.c:15387 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "ne peut pas utiliser l'index « %s » immédiat comme identité de réplicat" + +#: commands/tablecmds.c:15393 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "ne peut pas utiliser un index par expression « %s » comme identité de réplicat" + +#: commands/tablecmds.c:15399 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "ne peut pas utiliser l'index partiel « %s » comme identité de réplicat" + +#: commands/tablecmds.c:15405 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "ne peut pas utiliser l'index invalide « %s » comme identité de réplicat" + +#: commands/tablecmds.c:15422 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "l'index « %s » ne peut pas être utilisé comme identité de réplicat car la colonne %d est une colonne système" + +#: commands/tablecmds.c:15429 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "l'index « %s » ne peut pas être utilisé comme identité de réplicat car la colonne « %s » peut être NULL" + +#: commands/tablecmds.c:15676 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "ne peut pas modifier le statut de journalisation de la table « %s » parce qu'elle est temporaire" + +#: commands/tablecmds.c:15700 +#, c-format +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "ne peut pas modifier la table « %s » en non journalisée car elle fait partie d'une publication" + +#: commands/tablecmds.c:15702 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "Les relations non journalisées ne peuvent pas être répliquées." + +#: commands/tablecmds.c:15747 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "n'a pas pu passer la table « %s » en journalisé car elle référence la table non journalisée « %s »" + +#: commands/tablecmds.c:15757 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "n'a pas pu passer la table « %s » en non journalisé car elle référence la table journalisée « %s »" + +#: commands/tablecmds.c:15815 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "ne peut pas déplacer une séquence OWNED BY dans un autre schéma" + +#: commands/tablecmds.c:15922 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "la relation « %s » existe déjà dans le schéma « %s »" + +#: commands/tablecmds.c:16485 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "« %s » n'est pas un type composite" + +#: commands/tablecmds.c:16517 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "« %s » n'est ni une table, ni une vue, ni une vue matérialisée, ni une séquence, ni une table distante" + +#: commands/tablecmds.c:16552 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "stratégie de partitionnement « %s » non reconnue" + +#: commands/tablecmds.c:16560 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "ne peut pas utiliser la stratégie de partitionnement « list » avec plus d'une colonne" + +#: commands/tablecmds.c:16626 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "la colonne « %s » nommée dans la clé de partitionnement n'existe pas" + +#: commands/tablecmds.c:16634 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "ne peut pas utiliser la colonne système « %s » comme clé de partitionnement" + +#: commands/tablecmds.c:16645 commands/tablecmds.c:16759 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "ne peut pas utiliser une colonne générée dans une clé de partitionnement" + +#: commands/tablecmds.c:16646 commands/tablecmds.c:16760 commands/trigger.c:635 rewrite/rewriteHandler.c:884 rewrite/rewriteHandler.c:919 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "la colonne « %s » est une colonne générée." + +#: commands/tablecmds.c:16722 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "" +"les fonctions dans une expression de clé de partitionnement doivent être marquées comme\n" +"IMMUTABLE" + +#: commands/tablecmds.c:16742 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "les expressions de la clé de partitionnement ne peuvent pas contenir des références aux colonnes systèmes" + +#: commands/tablecmds.c:16772 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "ne peut pas utiliser une expression constante comme clé de partitionnement" + +#: commands/tablecmds.c:16793 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour l'expression de partitionnement" + +#: commands/tablecmds.c:16828 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "" +"Vous devez spécifier une classe d'opérateur hash ou définir une\n" +"classe d'opérateur hash par défaut pour le type de données." + +#: commands/tablecmds.c:16834 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "" +"Vous devez spécifier une classe d'opérateur btree ou définir une\n" +"classe d'opérateur btree par défaut pour le type de données." + +#: commands/tablecmds.c:17086 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "« %s » est déjà une partition" + +#: commands/tablecmds.c:17092 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "ne peut pas attacher une table typée à une partition" + +#: commands/tablecmds.c:17108 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "ne peut pas ajouter la table en héritage comme une partition" + +#: commands/tablecmds.c:17122 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "ne peut pas attacher le parent d'héritage comme partition" + +#: commands/tablecmds.c:17156 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "ne peut pas attacher une relation temporaire comme partition de la relation permanente « %s »" + +#: commands/tablecmds.c:17164 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "ne peut pas attacher une relation permanente comme partition de la relation temporaire « %s »" + +#: commands/tablecmds.c:17172 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "ne peut pas attacher comme partition d'une relation temporaire d'une autre session" + +#: commands/tablecmds.c:17179 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "ne peut pas attacher une relation temporaire d'une autre session comme partition" + +#: commands/tablecmds.c:17199 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "la table « %s » contient la colonne « %s » introuvable dans le parent « %s »" + +#: commands/tablecmds.c:17202 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "La nouvelle partition pourrait seulement contenir les colonnes présentes dans le parent." + +#: commands/tablecmds.c:17214 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "le trigger « %s » empêche la table « %s » de devenir une partition" + +#: commands/tablecmds.c:17216 commands/trigger.c:441 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "les triggers ROW avec des tables de transition ne sont pas supportés sur les partitions" + +#: commands/tablecmds.c:17379 +#, c-format +msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" +msgstr "ne peut pas attacher la table distante « %s » comme partition de la table partitionnée « %s »" + +#: commands/tablecmds.c:17382 +#, c-format +msgid "Partitioned table \"%s\" contains unique indexes." +msgstr "La table partitionnée « %s » contient des index uniques." + +#: commands/tablecmds.c:17702 +#, c-format +msgid "cannot detach partitions concurrently when a default partition exists" +msgstr "ne peut pas détacher les partitions en parallèle quand une partition par défaut existe" + +#: commands/tablecmds.c:17811 +#, c-format +msgid "partitioned table \"%s\" was removed concurrently" +msgstr "la table partitionnée « %s » a été supprimée de manière concurrente" + +#: commands/tablecmds.c:17817 +#, c-format +msgid "partition \"%s\" was removed concurrently" +msgstr "la partition « %s » a été supprimée de façon concurrente" + +#: commands/tablecmds.c:18271 commands/tablecmds.c:18291 commands/tablecmds.c:18311 commands/tablecmds.c:18330 commands/tablecmds.c:18372 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "ne peut pas attacher l'index « %s » comme une partition de l'index « %s »" + +#: commands/tablecmds.c:18274 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "L'index « %s » est déjà attaché à un autre index." + +#: commands/tablecmds.c:18294 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "L'index « %s » n'est un index sur aucune des partitions de la table « %s »." + +#: commands/tablecmds.c:18314 +#, c-format +msgid "The index definitions do not match." +msgstr "La définition de l'index correspond pas." + +#: commands/tablecmds.c:18333 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "L'index « %s » appartient à une contrainte dans la table « %s » mais aucune contrainte n'existe pour l'index « %s »." + +#: commands/tablecmds.c:18375 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "Un autre index est déjà attaché pour la partition « %s »." + +#: commands/tablecmds.c:18605 +#, c-format +msgid "column data type %s does not support compression" +msgstr "le type de données %s ne supporte pas la compression" + +#: commands/tablecmds.c:18612 +#, c-format +msgid "invalid compression method \"%s\"" +msgstr "méthode de compression « %s » invalide" + +#: commands/tablespace.c:162 commands/tablespace.c:179 commands/tablespace.c:190 commands/tablespace.c:198 commands/tablespace.c:650 replication/slot.c:1451 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "n'a pas pu créer le répertoire « %s » : %m" + +#: commands/tablespace.c:209 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "n'a pas pu lire les informations sur le répertoire « %s » : %m" + +#: commands/tablespace.c:218 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "« %s » existe mais n'est pas un répertoire" + +#: commands/tablespace.c:249 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "droit refusé pour créer le tablespace « %s »" + +#: commands/tablespace.c:251 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "Doit être super-utilisateur pour créer un tablespace." + +#: commands/tablespace.c:267 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "le chemin du tablespace ne peut pas contenir de guillemets simples" + +#: commands/tablespace.c:277 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "le chemin du tablespace doit être un chemin absolu" + +#: commands/tablespace.c:289 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "le chemin du tablespace « %s » est trop long" + +#: commands/tablespace.c:296 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "l'emplacement du tablespace ne doit pas être dans le répertoire de données" + +#: commands/tablespace.c:305 commands/tablespace.c:977 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "nom inacceptable pour le tablespace « %s »" + +#: commands/tablespace.c:307 commands/tablespace.c:978 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "Le préfixe « pg_ » est réservé pour les tablespaces système." + +#: commands/tablespace.c:326 commands/tablespace.c:999 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "le tablespace « %s » existe déjà" + +#: commands/tablespace.c:444 commands/tablespace.c:960 commands/tablespace.c:1049 commands/tablespace.c:1118 commands/tablespace.c:1264 commands/tablespace.c:1467 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "le tablespace « %s » n'existe pas" + +#: commands/tablespace.c:450 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "le tablespace « %s » n'existe pas, poursuite du traitement" + +#: commands/tablespace.c:478 +#, c-format +msgid "tablespace \"%s\" cannot be dropped because some objects depend on it" +msgstr "le tablespace « %s » ne peut pas être supprimé car d'autres objets en dépendent" + +#: commands/tablespace.c:537 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "le tablespace « %s » n'est pas vide" + +#: commands/tablespace.c:609 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "le répertoire « %s » n'existe pas" + +#: commands/tablespace.c:610 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "Créer le répertoire pour ce tablespace avant de redémarrer le serveur." + +#: commands/tablespace.c:615 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "n'a pas pu configurer les droits du répertoire « %s » : %m" + +#: commands/tablespace.c:645 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "répertoire « %s » déjà utilisé comme tablespace" + +#: commands/tablespace.c:769 commands/tablespace.c:782 commands/tablespace.c:818 commands/tablespace.c:910 storage/file/fd.c:3161 storage/file/fd.c:3557 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "n'a pas pu supprimer le répertoire « %s » : %m" + +#: commands/tablespace.c:831 commands/tablespace.c:919 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "n'a pas pu supprimer le lien symbolique « %s » : %m" + +#: commands/tablespace.c:841 commands/tablespace.c:928 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "« %s » n'est ni un répertoire ni un lien symbolique" + +#: commands/tablespace.c:1123 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "Le tablespace « %s » n'existe pas." + +#: commands/tablespace.c:1566 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "les répertoires du tablespace %u n'ont pas pu être supprimés" + +#: commands/tablespace.c:1568 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "Vous pouvez supprimer les répertoires manuellement si nécessaire." + +#: commands/trigger.c:198 commands/trigger.c:209 +#, c-format +msgid "\"%s\" is a table" +msgstr "« %s » est une table" + +#: commands/trigger.c:200 commands/trigger.c:211 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "Les tables ne peuvent pas avoir de triggers INSTEAD OF." + +#: commands/trigger.c:232 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "« %s » est une table partitionnée" + +#: commands/trigger.c:234 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Les triggers sur les tables partitionnées ne peuvent pas avoir de tables de transition." + +#: commands/trigger.c:246 commands/trigger.c:253 commands/trigger.c:423 +#, c-format +msgid "\"%s\" is a view" +msgstr "« %s » est une vue" + +#: commands/trigger.c:248 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "Les vues ne peuvent pas avoir de trigger BEFORE ou AFTER au niveau ligne." + +#: commands/trigger.c:255 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "Les vues ne peuvent pas avoir de triggers TRUNCATE." + +#: commands/trigger.c:263 commands/trigger.c:270 commands/trigger.c:282 commands/trigger.c:416 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "« %s » est une table distante" + +#: commands/trigger.c:265 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "Les tables distantes ne peuvent pas avoir de triggers INSTEAD OF." + +#: commands/trigger.c:272 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "Les tables distantes ne peuvent pas avoir de triggers TRUNCATE." + +#: commands/trigger.c:284 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "Les tables distantes ne peuvent pas avoir de triggers de contrainte." + +#: commands/trigger.c:359 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "les triggers TRUNCATE FOR EACH ROW ne sont pas supportés" + +#: commands/trigger.c:367 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "les triggers INSTEAD OF doivent être FOR EACH ROW" + +#: commands/trigger.c:371 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "les triggers INSTEAD OF ne peuvent pas avoir de conditions WHEN" + +#: commands/trigger.c:375 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "les triggers INSTEAD OF ne peuvent pas avoir de liste de colonnes" + +#: commands/trigger.c:404 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "le nommage de variable ROW dans la clause REFERENCING n'est pas supporté" + +#: commands/trigger.c:405 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "Utilisez OLD TABLE ou NEW TABLE pour nommer les tables de transition." + +#: commands/trigger.c:418 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Les triggers sur les tables distantes ne peuvent pas avoir de tables de transition." + +#: commands/trigger.c:425 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Les triggers sur les vues ne peuvent pas avoir de tables de transition." + +#: commands/trigger.c:445 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "les triggers ROW avec des tables de transition ne sont pas supportés sur les filles en héritage" + +#: commands/trigger.c:451 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "le nom de la table de transition peut seulement être spécifié pour un trigger AFTER" + +#: commands/trigger.c:456 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "les triggers TRUNCATE avec des tables de transition ne sont pas supportés" + +#: commands/trigger.c:473 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "les tables de transition ne peuvent pas être spécifiées pour les triggers avec plus d'un événement" + +#: commands/trigger.c:484 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "les tables de transition ne peuvent pas être spécifiées pour les triggers avec des listes de colonnes" + +#: commands/trigger.c:501 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "OLD TABLE peut seulement être spécifié pour un trigger INSERT ou UPDATE" + +#: commands/trigger.c:506 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE ne peut pas être spécifié plusieurs fois" + +#: commands/trigger.c:516 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE peut seulement être spécifié pour un trigger DELETE ou UPDATE" + +#: commands/trigger.c:521 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE ne peut pas être spécifié plusieurs fois" + +#: commands/trigger.c:531 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "les noms de OLD TABLE et NEW TABLE ne peuvent pas être identiques" + +#: commands/trigger.c:595 commands/trigger.c:608 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "" +"la condition WHEN de l'instruction du trigger ne peut pas référencer les valeurs\n" +"des colonnes" + +#: commands/trigger.c:600 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "la condition WHEN du trigger INSERT ne peut pas référencer les valeurs OLD" + +#: commands/trigger.c:613 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "la condition WHEN du trigger DELETE ne peut pas référencer les valeurs NEW" + +#: commands/trigger.c:618 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "la condition WHEN d'un trigger BEFORE ne doit pas référencer dans NEW les colonnes système" + +#: commands/trigger.c:626 commands/trigger.c:634 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "la condition WHEN d'un trigger BEFORE ne doit pas référencer dans NEW les colonnes générées" + +#: commands/trigger.c:627 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "Une référence comprenant toute une ligne est utilisée et la table contient des colonnes générées." + +#: commands/trigger.c:741 commands/trigger.c:1450 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "le trigger « %s » de la relation « %s » existe déjà" + +#: commands/trigger.c:755 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" is an internal trigger" +msgstr "le trigger « %s » de la relation « %s » est un trigger interne" + +#: commands/trigger.c:774 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" is a constraint trigger" +msgstr "le trigger « %s » de la relation « %s » est un trigger de contrainte" + +#: commands/trigger.c:1336 commands/trigger.c:1497 commands/trigger.c:1612 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "le trigger « %s » de la table « %s » n'existe pas" + +#: commands/trigger.c:1580 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "droit refusé : « %s » est un trigger système" + +#: commands/trigger.c:2160 +#, c-format +msgid "trigger function %u returned null value" +msgstr "la fonction trigger %u a renvoyé la valeur NULL" + +#: commands/trigger.c:2220 commands/trigger.c:2434 commands/trigger.c:2673 commands/trigger.c:2977 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "un trigger BEFORE STATEMENT ne peut pas renvoyer une valeur" + +#: commands/trigger.c:2294 +#, c-format +msgid "moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported" +msgstr "le déplacement de la ligne vers une autre partition par un trigger BEFORE FOR EACH ROW n'est pas supporté" + +#: commands/trigger.c:2295 +#, c-format +msgid "Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." +msgstr "Avant d'exécuter le trigger « %s », la ligne devait aller dans la partition « %s.%s »." + +#: commands/trigger.c:3043 executor/nodeModifyTable.c:1822 executor/nodeModifyTable.c:1904 +#, c-format +msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgstr "la ligne à mettre à jour était déjà modifiée par une opération déclenchée par la commande courante" + +#: commands/trigger.c:3044 executor/nodeModifyTable.c:1204 executor/nodeModifyTable.c:1278 executor/nodeModifyTable.c:1823 executor/nodeModifyTable.c:1905 +#, c-format +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." +msgstr "Considérez l'utilisation d'un trigger AFTER au lieu d'un trigger BEFORE pour propager les changements sur les autres lignes." + +#: commands/trigger.c:3073 executor/nodeLockRows.c:229 executor/nodeLockRows.c:238 executor/nodeModifyTable.c:228 executor/nodeModifyTable.c:1220 executor/nodeModifyTable.c:1840 executor/nodeModifyTable.c:2070 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "n'a pas pu sérialiser un accès à cause d'une mise à jour en parallèle" + +#: commands/trigger.c:3081 executor/nodeModifyTable.c:1310 executor/nodeModifyTable.c:1922 executor/nodeModifyTable.c:2094 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "n'a pas pu sérialiser un accès à cause d'une suppression en parallèle" + +#: commands/trigger.c:4142 +#, c-format +msgid "cannot fire deferred trigger within security-restricted operation" +msgstr "ne peut pas déclencher un trigger déferré à l'intérieur d'une opération restreinte pour sécurité" + +#: commands/trigger.c:5185 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "la contrainte « %s » n'est pas DEFERRABLE" + +#: commands/trigger.c:5208 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "la contrainte « %s » n'existe pas" + +#: commands/tsearchcmds.c:118 commands/tsearchcmds.c:635 +#, c-format +msgid "function %s should return type %s" +msgstr "la fonction %s doit renvoyer le type %s" + +#: commands/tsearchcmds.c:194 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "doit être super-utilisateur pour créer des analyseurs de recherche plein texte" + +#: commands/tsearchcmds.c:247 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "paramètre de l'analyseur de recherche plein texte « %s » non reconnu" + +#: commands/tsearchcmds.c:257 +#, c-format +msgid "text search parser start method is required" +msgstr "la méthode start de l'analyseur de recherche plein texte est requise" + +#: commands/tsearchcmds.c:262 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "la méthode gettoken de l'analyseur de recherche plein texte est requise" + +#: commands/tsearchcmds.c:267 +#, c-format +msgid "text search parser end method is required" +msgstr "la méthode end l'analyseur de recherche de texte est requise" + +#: commands/tsearchcmds.c:272 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "la méthode lextypes de l'analyseur de recherche plein texte est requise" + +#: commands/tsearchcmds.c:366 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "le modèle de recherche plein texte « %s » n'accepte pas d'options" + +#: commands/tsearchcmds.c:440 +#, c-format +msgid "text search template is required" +msgstr "le modèle de la recherche plein texte est requis" + +#: commands/tsearchcmds.c:701 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "doit être super-utilisateur pour créer des modèles de recherche plein texte" + +#: commands/tsearchcmds.c:743 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "paramètre de modèle de recherche plein texte « %s » non reconnu" + +#: commands/tsearchcmds.c:753 +#, c-format +msgid "text search template lexize method is required" +msgstr "la méthode lexize du modèle de recherche plein texte est requise" + +#: commands/tsearchcmds.c:933 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "paramètre de configuration de recherche plein texte « %s » non reconnu" + +#: commands/tsearchcmds.c:940 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "ne peut pas spécifier à la fois PARSER et COPY" + +#: commands/tsearchcmds.c:976 +#, c-format +msgid "text search parser is required" +msgstr "l'analyseur de la recherche plein texte est requis" + +#: commands/tsearchcmds.c:1200 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "le type de jeton « %s » n'existe pas" + +#: commands/tsearchcmds.c:1427 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "la correspondance pour le type de jeton « %s » n'existe pas" + +#: commands/tsearchcmds.c:1433 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "" +"la correspondance pour le type de jeton « %s » n'existe pas, poursuite du\n" +"traitement" + +#: commands/tsearchcmds.c:1596 commands/tsearchcmds.c:1711 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "format de liste de paramètres invalide : « %s »" + +#: commands/typecmds.c:217 +#, c-format +msgid "must be superuser to create a base type" +msgstr "doit être super-utilisateur pour créer un type de base" + +#: commands/typecmds.c:275 +#, c-format +msgid "Create the type as a shell type, then create its I/O functions, then do a full CREATE TYPE." +msgstr "Créez le type comme un type shell, puis créez ses fonctions I/O, puis faites un vrai CREATE TYPE." + +#: commands/typecmds.c:327 commands/typecmds.c:1465 commands/typecmds.c:4281 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "attribut du type « %s » non reconnu" + +#: commands/typecmds.c:385 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "catégorie de type « %s » invalide : doit être de l'ASCII pur" + +#: commands/typecmds.c:404 +#, c-format +msgid "array element type cannot be %s" +msgstr "le type d'élément tableau ne peut pas être %s" + +#: commands/typecmds.c:436 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "alignement « %s » non reconnu" + +#: commands/typecmds.c:453 commands/typecmds.c:4155 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "stockage « %s » non reconnu" + +#: commands/typecmds.c:464 +#, c-format +msgid "type input function must be specified" +msgstr "le type d'entrée de la fonction doit être spécifié" + +#: commands/typecmds.c:468 +#, c-format +msgid "type output function must be specified" +msgstr "le type de sortie de la fonction doit être spécifié" + +#: commands/typecmds.c:473 +#, c-format +msgid "type modifier output function is useless without a type modifier input function" +msgstr "" +"la fonction en sortie du modificateur de type est inutile sans une fonction\n" +"en entrée du modificateur de type" + +#: commands/typecmds.c:515 +#, c-format +msgid "element type cannot be specified without a valid subscripting procedure" +msgstr "" + +#: commands/typecmds.c:784 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "« %s » n'est pas un type de base valide pour un domaine" + +#: commands/typecmds.c:882 +#, c-format +msgid "multiple default expressions" +msgstr "multiples expressions par défaut" + +#: commands/typecmds.c:945 commands/typecmds.c:954 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "contraintes NULL/NOT NULL en conflit" + +#: commands/typecmds.c:970 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "les contraintes CHECK pour les domaines ne peuvent pas être marquées NO INHERIT" + +#: commands/typecmds.c:979 commands/typecmds.c:2975 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "contraintes uniques impossible pour les domaines" + +#: commands/typecmds.c:985 commands/typecmds.c:2981 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "contraintes de clé primaire impossible pour les domaines" + +#: commands/typecmds.c:991 commands/typecmds.c:2987 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "contraintes d'exclusion impossible pour les domaines" + +#: commands/typecmds.c:997 commands/typecmds.c:2993 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "contraintes de clé étrangère impossible pour les domaines" + +#: commands/typecmds.c:1006 commands/typecmds.c:3002 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "spécifier des contraintes déferrantes n'est pas supporté par les domaines" + +#: commands/typecmds.c:1320 utils/cache/typcache.c:2545 +#, c-format +msgid "%s is not an enum" +msgstr "%s n'est pas un enum" + +#: commands/typecmds.c:1473 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "l'attribut du sous-type est requis" + +#: commands/typecmds.c:1478 +#, c-format +msgid "range subtype cannot be %s" +msgstr "le sous-type de l'intervalle ne peut pas être %s" + +#: commands/typecmds.c:1497 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "collationnement spécifié pour l'intervalle mais le sous-type ne supporte pas les collationnements" + +#: commands/typecmds.c:1507 +#, c-format +msgid "cannot specify a canonical function without a pre-created shell type" +msgstr "ne peut pas spécifier une fonction canonique sans un type shell précédemment créé" + +#: commands/typecmds.c:1508 +#, c-format +msgid "Create the type as a shell type, then create its canonicalization function, then do a full CREATE TYPE." +msgstr "Créez le type comme un type shell, puis créez sa fonction canonisée, puis faites un vrai CREATE TYPE." + +#: commands/typecmds.c:1982 +#, c-format +msgid "type input function %s has multiple matches" +msgstr "la fonction d'entrée du type %s a plusieurs correspondances" + +#: commands/typecmds.c:2000 +#, c-format +msgid "type input function %s must return type %s" +msgstr "le type d'entrée de la fonction %s doit être %s" + +#: commands/typecmds.c:2016 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "la fonction en entrée du type %s ne doit pas être volatile" + +#: commands/typecmds.c:2044 +#, c-format +msgid "type output function %s must return type %s" +msgstr "le type de sortie de la fonction %s doit être %s" + +#: commands/typecmds.c:2051 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "la fonction en entrée du type %s ne doit pas être volatile" + +#: commands/typecmds.c:2080 +#, c-format +msgid "type receive function %s has multiple matches" +msgstr "la fonction receive du type %s a plusieurs correspondances" + +#: commands/typecmds.c:2098 +#, c-format +msgid "type receive function %s must return type %s" +msgstr "la fonction receive du type %s doit renvoyer le type %s" + +#: commands/typecmds.c:2105 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "la fonction receive du type %s ne doit pas être volatile" + +#: commands/typecmds.c:2133 +#, c-format +msgid "type send function %s must return type %s" +msgstr "le type de sortie de la fonction d'envoi %s doit être %s" + +#: commands/typecmds.c:2140 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "la fonction send du type %s ne doit pas être volatile" + +#: commands/typecmds.c:2167 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr "le type de sortie de la fonction typmod_in %s doit être %s" + +#: commands/typecmds.c:2174 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "la fonction en entrée du modificateur de type %s ne devrait pas être volatile" + +#: commands/typecmds.c:2201 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "le type de sortie de la fonction typmod_out %s doit être %s" + +#: commands/typecmds.c:2208 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "la fonction en sortie du modificateur de type %s ne devrait pas être volatile" + +#: commands/typecmds.c:2235 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "la fonction analyze du type %s doit renvoyer le type %s" + +#: commands/typecmds.c:2264 +#, c-format +msgid "type subscripting function %s must return type %s" +msgstr "la fonction %s d'indiçage de type doit renvoyer le type %s" + +#: commands/typecmds.c:2274 +#, c-format +msgid "user-defined types cannot use subscripting function %s" +msgstr "" + +#: commands/typecmds.c:2320 +#, c-format +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." +msgstr "" +"Vous devez spécifier une classe d'opérateur pour le type range ou définir une\n" +"classe d'opérateur par défaut pour le sous-type." + +#: commands/typecmds.c:2351 +#, c-format +msgid "range canonical function %s must return range type" +msgstr "la fonction canonical %s du range doit renvoyer le type range" + +#: commands/typecmds.c:2357 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "la fonction canonical %s du range doit être immutable" + +#: commands/typecmds.c:2393 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "" +"la fonction %s de calcul de différence pour le sous-type d'un intervalle de\n" +"valeur doit renvoyer le type %s" + +#: commands/typecmds.c:2400 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "" +"la fonction %s de calcul de différence pour le sous-type d'un intervalle de\n" +"valeur doit être immutable" + +#: commands/typecmds.c:2427 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "les valeurs d'OID du tableau pgtype ne sont pas positionnées en mode de mise à jour binaire" + +#: commands/typecmds.c:2460 +#, c-format +msgid "pg_type multirange OID value not set when in binary upgrade mode" +msgstr "valeur d'OID du multirange de pg_type non positionnée en mode de mise à jour binaire" + +#: commands/typecmds.c:2493 +#, c-format +msgid "pg_type multirange array OID value not set when in binary upgrade mode" +msgstr "valeur d'OID du tableau multirange de pg_type non positionnée en mode de mise à jour binaire" + +#: commands/typecmds.c:2791 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "la colonne « %s » de la table « %s » contient des valeurs NULL" + +#: commands/typecmds.c:2904 commands/typecmds.c:3106 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "la contrainte « %s » du domaine « %s » n'existe pas" + +#: commands/typecmds.c:2908 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "la contrainte « %s » du domaine « %s » n'existe pas, ignore" + +#: commands/typecmds.c:3113 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "la contrainte « %s » du domaine « %s » n'est pas une contrainte de vérification" + +#: commands/typecmds.c:3219 +#, c-format +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "" +"la colonne « %s » de la table « %s » contient des valeurs violant la\n" +"nouvelle contrainte" + +#: commands/typecmds.c:3448 commands/typecmds.c:3646 commands/typecmds.c:3727 commands/typecmds.c:3913 +#, c-format +msgid "%s is not a domain" +msgstr "%s n'est pas un domaine" + +#: commands/typecmds.c:3480 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "la contrainte « %s » du domaine « %s » existe déjà" + +#: commands/typecmds.c:3531 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "" +"ne peut pas utiliser les références de table dans la contrainte de\n" +"vérification du domaine" + +#: commands/typecmds.c:3658 commands/typecmds.c:3739 commands/typecmds.c:4030 +#, c-format +msgid "%s is a table's row type" +msgstr "« %s » est du type ligne de table" + +#: commands/typecmds.c:3660 commands/typecmds.c:3741 commands/typecmds.c:4032 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "Utilisez ALTER TABLE à la place." + +#: commands/typecmds.c:3666 commands/typecmds.c:3747 commands/typecmds.c:3945 +#, c-format +msgid "cannot alter array type %s" +msgstr "ne peut pas modifier le type array %s" + +#: commands/typecmds.c:3668 commands/typecmds.c:3749 commands/typecmds.c:3947 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "Vous pouvez modifier le type %s, ce qui va modifier aussi le type tableau." + +#: commands/typecmds.c:4015 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "le type « %s » existe déjà dans le schéma « %s »" + +#: commands/typecmds.c:4183 +#, c-format +msgid "cannot change type's storage to PLAIN" +msgstr "ne peut pas modifier le stockage du type en PLAIN" + +#: commands/typecmds.c:4276 +#, c-format +msgid "type attribute \"%s\" cannot be changed" +msgstr "l'attribut du type « %s » ne peut pas être changé" + +#: commands/typecmds.c:4294 +#, c-format +msgid "must be superuser to alter a type" +msgstr "doit être super-utilisateur pour modifier un type" + +#: commands/typecmds.c:4315 commands/typecmds.c:4324 +#, c-format +msgid "%s is not a base type" +msgstr "« %s » n'est pas un type de base" + +#: commands/user.c:140 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSID ne peut plus être spécifié" + +#: commands/user.c:294 +#, c-format +msgid "must be superuser to create superusers" +msgstr "doit être super-utilisateur pour créer des super-utilisateurs" + +#: commands/user.c:301 +#, c-format +msgid "must be superuser to create replication users" +msgstr "doit être super-utilisateur pour créer des utilisateurs avec l'attribut réplication" + +#: commands/user.c:308 +#, c-format +msgid "must be superuser to create bypassrls users" +msgstr "doit être super-utilisateur pour créer des utilisateurs avec l'attribut BYPASSRLS" + +#: commands/user.c:315 +#, c-format +msgid "permission denied to create role" +msgstr "droit refusé pour créer un rôle" + +#: commands/user.c:325 commands/user.c:1226 commands/user.c:1233 gram.y:15259 gram.y:15304 utils/adt/acl.c:5248 utils/adt/acl.c:5254 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "le nom du rôle « %s » est réservé" + +#: commands/user.c:327 commands/user.c:1228 commands/user.c:1235 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "Les noms de rôle commençant par « pg_ » sont réservés." + +#: commands/user.c:348 commands/user.c:1250 +#, c-format +msgid "role \"%s\" already exists" +msgstr "le rôle « %s » existe déjà" + +#: commands/user.c:414 commands/user.c:845 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "une chaîne vide n'est pas un mot de passe valide, effacement du mot de passe" + +#: commands/user.c:443 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "la valeur d'OID de pg_authid n'est pas positionnée en mode de mise à jour binaire" + +#: commands/user.c:722 +#, c-format +msgid "must be superuser to alter superuser roles or change superuser attribute" +msgstr "doit être super-utilisateur pour modifier les rôles ayant l'attribut SUPERUSER ou pour changer l'attribut SUPERUSER" + +#: commands/user.c:729 +#, c-format +msgid "must be superuser to alter replication roles or change replication attribute" +msgstr "doit être super-utilisateur pour modifier les rôles ayant l'attribut REPLICATION ou pour changer l'attribut REPLICATION" + +#: commands/user.c:736 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "doit être super-utilisateur pour modifier l'attribut bypassrls" + +#: commands/user.c:752 commands/user.c:953 +#, c-format +msgid "permission denied" +msgstr "droit refusé" + +#: commands/user.c:946 commands/user.c:1487 commands/user.c:1665 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "doit être super-utilisateur pour modifier des super-utilisateurs" + +#: commands/user.c:983 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "doit être super-utilisateur pour modifier globalement les configurations" + +#: commands/user.c:1005 +#, c-format +msgid "permission denied to drop role" +msgstr "droit refusé pour supprimer le rôle" + +#: commands/user.c:1030 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "ne peut pas être le spécificateur de rôle spécial dans DROP ROLE" + +#: commands/user.c:1040 commands/user.c:1197 commands/variable.c:778 commands/variable.c:781 commands/variable.c:865 commands/variable.c:868 utils/adt/acl.c:5103 utils/adt/acl.c:5151 utils/adt/acl.c:5179 utils/adt/acl.c:5198 utils/init/miscinit.c:705 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "le rôle « %s » n'existe pas" + +#: commands/user.c:1045 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "le rôle « %s » n'existe pas, poursuite du traitement" + +#: commands/user.c:1058 commands/user.c:1062 +#, c-format +msgid "current user cannot be dropped" +msgstr "l'utilisateur actuel ne peut pas être supprimé" + +#: commands/user.c:1066 +#, c-format +msgid "session user cannot be dropped" +msgstr "l'utilisateur de la session ne peut pas être supprimé" + +#: commands/user.c:1076 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "doit être super-utilisateur pour supprimer des super-utilisateurs" + +#: commands/user.c:1092 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "le rôle « %s » ne peut pas être supprimé car d'autres objets en dépendent" + +#: commands/user.c:1213 +#, c-format +msgid "session user cannot be renamed" +msgstr "l'utilisateur de la session ne peut pas être renommé" + +#: commands/user.c:1217 +#, c-format +msgid "current user cannot be renamed" +msgstr "l'utilisateur courant ne peut pas être renommé" + +#: commands/user.c:1260 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "doit être super-utilisateur pour renommer les super-utilisateurs" + +#: commands/user.c:1267 +#, c-format +msgid "permission denied to rename role" +msgstr "droit refusé pour renommer le rôle" + +#: commands/user.c:1288 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "mot de passe MD5 effacé à cause du renommage du rôle" + +#: commands/user.c:1348 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "les noms de colonne ne peuvent pas être inclus dans GRANT/REVOKE ROLE" + +#: commands/user.c:1386 +#, c-format +msgid "permission denied to drop objects" +msgstr "droit refusé pour supprimer les objets" + +#: commands/user.c:1413 commands/user.c:1422 +#, c-format +msgid "permission denied to reassign objects" +msgstr "droit refusé pour ré-affecter les objets" + +#: commands/user.c:1495 commands/user.c:1673 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "doit avoir l'option admin sur le rôle « %s »" + +#: commands/user.c:1509 +#, c-format +msgid "role \"%s\" cannot have explicit members" +msgstr "le rôle « %s » ne peut pas avoir de membres explicites" + +#: commands/user.c:1524 +#, c-format +msgid "must be superuser to set grantor" +msgstr "doit être super-utilisateur pour configurer le « donneur de droits »" + +#: commands/user.c:1560 +#, c-format +msgid "role \"%s\" cannot be a member of any role" +msgstr "le rôle « %s » n'est pas un membre de tout autre rôle" + +#: commands/user.c:1573 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "le rôle « %s » est un membre du rôle « %s »" + +#: commands/user.c:1588 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "le rôle « %s » est déjà un membre du rôle « %s »" + +#: commands/user.c:1695 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "le rôle « %s » n'est pas un membre du rôle « %s »" + +#: commands/vacuum.c:132 +#, c-format +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "option d'ANALYZE « %s » non reconnue" + +#: commands/vacuum.c:170 +#, c-format +msgid "parallel option requires a value between 0 and %d" +msgstr "l'option parallel nécessite une valeur comprise entre 0 et %d" + +#: commands/vacuum.c:182 +#, c-format +msgid "parallel workers for vacuum must be between 0 and %d" +msgstr "le nombre de processus workers parallélisés pour le VACUUM doit être entre 0 et %d" + +#: commands/vacuum.c:199 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "option « %s » de la commande VACUUM non reconnue" + +#: commands/vacuum.c:222 +#, c-format +msgid "VACUUM FULL cannot be performed in parallel" +msgstr "Un VACUUM FULL ne peut être exécuté de façon parallélisé" + +#: commands/vacuum.c:238 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "l'option ANALYZE doit être spécifiée quand une liste de colonne est fournie" + +#: commands/vacuum.c:328 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s ne peut pas être exécuté dans un VACUUM ou un ANALYZE" + +#: commands/vacuum.c:338 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "l'option DISABLE_PAGE_SKIPPING de la commande VACUUM ne pas être utilisée en même temps que l'option FULL" + +#: commands/vacuum.c:345 +#, c-format +msgid "PROCESS_TOAST required with VACUUM FULL" +msgstr "PROCESS_TOAST requis avec VACUUM FULL" + +#: commands/vacuum.c:586 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "ignore « %s » --- seul le super-utilisateur peut exécuter un VACUUM" + +#: commands/vacuum.c:590 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "" +"ignore « %s » --- seul le super-utilisateur ou le propriétaire de la base de données\n" +"peuvent exécuter un VACUUM" + +#: commands/vacuum.c:594 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "" +"ignore « %s » --- seul le propriétaire de la table ou de la base de données\n" +"peut exécuter un VACUUM" + +#: commands/vacuum.c:609 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "ignore « %s » --- seul le super-utilisateur peut l'analyser" + +#: commands/vacuum.c:613 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "" +"ignore « %s » --- seul le super-utilisateur ou le propriétaire de la base de\n" +"données peut l'analyser" + +#: commands/vacuum.c:617 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "" +"ignore « %s » --- seul le propriétaire de la table ou de la base de données\n" +"peut l'analyser" + +#: commands/vacuum.c:696 commands/vacuum.c:792 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "ignore le vacuum de « %s » --- verrou non disponible" + +#: commands/vacuum.c:701 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "ignore le vacuum de « %s » --- la relation n'existe plus" + +#: commands/vacuum.c:717 commands/vacuum.c:797 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "ignore l'analyse de « %s » --- verrou non disponible" + +#: commands/vacuum.c:722 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "ignore l'analyse de « %s » --- la relation n'existe plus" + +#: commands/vacuum.c:1040 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "le plus ancien xmin est loin dans le passé" + +#: commands/vacuum.c:1041 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Fermer les transactions dès que possible pour éviter des problèmes de rebouclage d'identifiants de transaction.\n" +"Vous pouvez avoir besoin de valider ou d'annuler les anciennes transactions préparées, ou de supprimer les slots de réplication trop anciens." + +#: commands/vacuum.c:1082 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "le plus ancien multixact est loin dans le passé" + +#: commands/vacuum.c:1083 +#, c-format +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "" +"Fermez les transactions ouvertes avec multixacts rapidement pour éviter des problèmes de\n" +"réinitialisation." + +#: commands/vacuum.c:1740 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "" +"certaines bases de données n'ont pas eu droit à l'opération de maintenance\n" +"VACUUM depuis plus de 2 milliards de transactions" + +#: commands/vacuum.c:1741 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "" +"Vous pouvez avoir déjà souffert de pertes de données suite à une\n" +"réinitialisation de l'identifiant des transactions." + +#: commands/vacuum.c:1905 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "" +"ignore « %s » --- n'a pas pu exécuter un VACUUM sur les objets autres que\n" +"des tables et les tables systèmes" + +#: commands/variable.c:165 utils/misc/guc.c:11625 utils/misc/guc.c:11687 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "Mot clé non reconnu : « %s »." + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "Spécifications « datestyle » conflictuelles" + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "Ne peut pas spécifier des mois dans un interval avec fuseau horaire." + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "Ne peut pas spécifier des jours dans un interval avec fuseau horaire." + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "le fuseau horaire « %s » semble utiliser les secondes intercalaires" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQL ne supporte pas les secondes « leap »." + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "le décalage du fuseau horaire UTC est en dehors des limites." + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "" +"ne peut pas initialiser le mode lecture-écriture de la transaction à\n" +"l'intérieur d'une transaction en lecture seule" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "" +"le mode de transaction lecture/écriture doit être configuré avant d'exécuter\n" +"la première requête" + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "" +"ne peut pas initialiser le mode lecture-écriture des transactions lors de la\n" +"restauration" + +#: commands/variable.c:534 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "SET TRANSACTION ISOLATION LEVEL doit être appelé avant toute requête" + +#: commands/variable.c:541 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "" +"SET TRANSACTION ISOLATION LEVEL ne doit pas être appelé dans une\n" +"sous-transaction" + +#: commands/variable.c:548 storage/lmgr/predicate.c:1693 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "ne peut pas utiliser le mode sérialisable sur un serveur en « Hot Standby »" + +#: commands/variable.c:549 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "Vous pouvez utiliser REPEATABLE READ à la place." + +#: commands/variable.c:567 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "" +"SET TRANSACTION [NOT] DEFERRABLE ne doit pas être appelé dans une\n" +"sous-transaction" + +#: commands/variable.c:573 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "SET TRANSACTION [NOT] DEFERRABLE doit être appelé avant toute requête" + +#: commands/variable.c:655 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "La conversion entre %s et %s n'est pas supportée." + +#: commands/variable.c:662 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "Ne peut pas modifier « client_encoding » maintenant." + +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "ne peut pas modifier le client_encoding lors d'une opération parallélisée" + +#: commands/variable.c:890 +#, c-format +msgid "permission will be denied to set role \"%s\"" +msgstr "le droit sera refusé pour configurer le rôle « %s »" + +#: commands/variable.c:895 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "droit refusé pour configurer le rôle « %s »" + +#: commands/view.c:84 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour la colonne « %s » de la vue" + +#: commands/view.c:265 commands/view.c:276 +#, c-format +msgid "cannot drop columns from view" +msgstr "ne peut pas supprimer les colonnes d'une vue" + +#: commands/view.c:281 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "ne peut pas modifier le nom de la colonne « %s » de la vue en « %s »" + +#: commands/view.c:284 +#, c-format +msgid "Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead." +msgstr "À la place, utilisez ALTER VIEW ... RENAME COLUMN ... pour modifier le nom de la colonne d'une vue." + +#: commands/view.c:290 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "ne peut pas modifier le type de données de la colonne « %s » de la vue de %s à %s" + +#: commands/view.c:438 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "les vues ne peuvent pas contenir SELECT INTO" + +#: commands/view.c:450 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "les vues ne peuvent pas contenir d'instructions de modifications de données avec WITH" + +#: commands/view.c:520 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "CREATE VIEW spécifie plus de noms de colonnes que de colonnes" + +#: commands/view.c:528 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "les vues ne peuvent pas être non tracées car elles n'ont pas de stockage" + +#: commands/view.c:542 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "la vue « %s » sera une vue temporaire" + +#: executor/execCurrent.c:79 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "le curseur « %s » n'est pas une requête SELECT" + +#: executor/execCurrent.c:85 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "le curseur « %s » est détenu par une transaction précédente" + +#: executor/execCurrent.c:118 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "le curseur « %s » a plusieurs références FOR UPDATE/SHARE pour la table « %s »" + +#: executor/execCurrent.c:127 +#, c-format +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "le curseur « %s » n'a pas de référence FOR UPDATE/SHARE pour la table « %s »" + +#: executor/execCurrent.c:137 executor/execCurrent.c:182 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr "le curseur « %s » n'est pas positionné sur une ligne" + +#: executor/execCurrent.c:169 executor/execCurrent.c:228 executor/execCurrent.c:239 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "le curseur « %s » n'est pas un parcours modifiable de la table « %s »" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2451 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "le type de paramètre %d (%s) ne correspond pas à ce qui est préparé dans le plan (%s)" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2463 +#, c-format +msgid "no value found for parameter %d" +msgstr "aucune valeur trouvée pour le paramètre %d" + +#: executor/execExpr.c:632 executor/execExpr.c:639 executor/execExpr.c:645 executor/execExprInterp.c:4023 executor/execExprInterp.c:4040 executor/execExprInterp.c:4141 executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:128 executor/nodeModifyTable.c:145 executor/nodeModifyTable.c:153 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "le type de ligne de la table et celui spécifié par la requête ne correspondent pas" + +#: executor/execExpr.c:633 executor/nodeModifyTable.c:118 +#, c-format +msgid "Query has too many columns." +msgstr "La requête a trop de colonnes." + +#: executor/execExpr.c:640 executor/nodeModifyTable.c:146 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "" +"La requête fournit une valeur pour une colonne supprimée à la position\n" +"ordinale %d." + +#: executor/execExpr.c:646 executor/execExprInterp.c:4041 executor/nodeModifyTable.c:129 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "La table a le type %s à la position ordinale %d alors que la requête attend %s." + +#: executor/execExpr.c:1110 parser/parse_agg.c:827 +#, c-format +msgid "window function calls cannot be nested" +msgstr "les appels à la fonction window ne peuvent pas être imbriqués" + +#: executor/execExpr.c:1615 +#, c-format +msgid "target type is not an array" +msgstr "le type cible n'est pas un tableau" + +#: executor/execExpr.c:1955 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "une colonne ROW() a le type %s au lieu du type %s" + +#: executor/execExpr.c:2480 executor/execSRF.c:718 parser/parse_func.c:138 parser/parse_func.c:655 parser/parse_func.c:1031 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "ne peut pas passer plus de %d argument à une fonction" +msgstr[1] "ne peut pas passer plus de %d arguments à une fonction" + +#: executor/execExpr.c:2866 parser/parse_node.c:277 parser/parse_node.c:327 +#, c-format +msgid "cannot subscript type %s because it does not support subscripting" +msgstr "ne peut pas indicer le type %s car il ne supporte pas les indices" + +#: executor/execExpr.c:2994 executor/execExpr.c:3016 +#, c-format +msgid "type %s does not support subscripted assignment" +msgstr "le type %s ne supporte pas l'affectation avec indice" + +#: executor/execExprInterp.c:1916 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "l'attribut %d du type %s a été supprimé" + +#: executor/execExprInterp.c:1922 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "l'attribut %d de type %s a un mauvais type" + +#: executor/execExprInterp.c:1924 executor/execExprInterp.c:3052 executor/execExprInterp.c:3098 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "La table a le type %s alors que la requête attend %s." + +#: executor/execExprInterp.c:2003 utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1748 utils/cache/typcache.c:1904 utils/cache/typcache.c:2033 utils/fmgr/funcapi.c:458 +#, c-format +msgid "type %s is not composite" +msgstr "le type %s n'est pas un type composite" + +#: executor/execExprInterp.c:2541 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF n'est pas supporté pour ce type de table" + +#: executor/execExprInterp.c:2754 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "ne peut pas fusionner les tableaux incompatibles" + +#: executor/execExprInterp.c:2755 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "Le tableau avec le type d'élément %s ne peut pas être inclus dans la construction ARRAY avec le type d'élément %s." + +#: executor/execExprInterp.c:2776 utils/adt/arrayfuncs.c:262 utils/adt/arrayfuncs.c:562 utils/adt/arrayfuncs.c:1304 utils/adt/arrayfuncs.c:3374 utils/adt/arrayfuncs.c:5336 utils/adt/arrayfuncs.c:5853 utils/adt/arraysubs.c:150 utils/adt/arraysubs.c:488 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "le nombre de dimensions du tableau (%d) dépasse le maximum autorisé (%d)" + +#: executor/execExprInterp.c:2796 executor/execExprInterp.c:2826 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "" +"les tableaux multidimensionnels doivent avoir des expressions de tableaux\n" +"avec les dimensions correspondantes" + +#: executor/execExprInterp.c:3051 executor/execExprInterp.c:3097 +#, c-format +msgid "attribute %d has wrong type" +msgstr "l'attribut %d a un mauvais type" + +#: executor/execExprInterp.c:3652 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "le domaine %s n'autorise pas les valeurs NULL" + +#: executor/execExprInterp.c:3667 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "la valeur pour le domaine %s viole la contrainte de vérification « %s »" + +#: executor/execExprInterp.c:4024 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "La ligne de la table contient %d attribut alors que la requête en attend %d." +msgstr[1] "La ligne de la table contient %d attributs alors que la requête en attend %d." + +#: executor/execExprInterp.c:4142 executor/execSRF.c:977 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "" +"Le stockage physique ne correspond pas à l'attribut supprimé à la position\n" +"ordinale %d." + +#: executor/execIndexing.c:571 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "ON CONFLICT ne supporte pas les contraintes uniques diferrables et les contraintes d'exclusion différables comme arbitres" + +#: executor/execIndexing.c:842 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "n'a pas pu créer la contrainte d'exclusion « %s »" + +#: executor/execIndexing.c:845 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "La clé %s est en conflit avec la clé %s." + +#: executor/execIndexing.c:847 +#, c-format +msgid "Key conflicts exist." +msgstr "Un conflit de clés est présent." + +#: executor/execIndexing.c:853 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "la valeur d'une clé en conflit rompt la contrainte d'exclusion « %s »" + +#: executor/execIndexing.c:856 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "La clé %s est en conflit avec la clé existante %s." + +#: executor/execIndexing.c:858 +#, c-format +msgid "Key conflicts with existing key." +msgstr "La clé est en conflit avec une clé existante." + +#: executor/execMain.c:1007 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "ne peut pas modifier la séquence « %s »" + +#: executor/execMain.c:1013 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "ne peut pas modifier la relation TOAST « %s »" + +#: executor/execMain.c:1031 rewrite/rewriteHandler.c:3041 rewrite/rewriteHandler.c:3824 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "ne peut pas insérer dans la vue « %s »" + +#: executor/execMain.c:1033 rewrite/rewriteHandler.c:3044 rewrite/rewriteHandler.c:3827 +#, c-format +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "Pour activer l'insertion dans la vue, fournissez un trigger INSTEAD OF INSERT ou une règle ON INSERT DO INSTEAD sans condition." + +#: executor/execMain.c:1039 rewrite/rewriteHandler.c:3049 rewrite/rewriteHandler.c:3832 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "ne peut pas mettre à jour la vue « %s »" + +#: executor/execMain.c:1041 rewrite/rewriteHandler.c:3052 rewrite/rewriteHandler.c:3835 +#, c-format +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "Pour activer la mise à jour dans la vue, fournissez un trigger INSTEAD OF UPDATE ou une règle ON UPDATE DO INSTEAD sans condition." + +#: executor/execMain.c:1047 rewrite/rewriteHandler.c:3057 rewrite/rewriteHandler.c:3840 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "ne peut pas supprimer à partir de la vue « %s »" + +#: executor/execMain.c:1049 rewrite/rewriteHandler.c:3060 rewrite/rewriteHandler.c:3843 +#, c-format +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "Pour activer la suppression dans la vue, fournissez un trigger INSTEAD OF DELETE ou une règle ON DELETE DO INSTEAD sans condition." + +#: executor/execMain.c:1060 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "ne peut pas modifier la vue matérialisée « %s »" + +#: executor/execMain.c:1072 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "ne peut pas insérer dans la table distante « %s »" + +#: executor/execMain.c:1078 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "la table distante « %s » n'autorise pas les insertions" + +#: executor/execMain.c:1085 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "ne peut pas modifier la table distante « %s »" + +#: executor/execMain.c:1091 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "la table distante « %s » n'autorise pas les modifications" + +#: executor/execMain.c:1098 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "ne peut pas supprimer à partir de la table distante « %s »" + +#: executor/execMain.c:1104 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "la table distante « %s » n'autorise pas les suppressions" + +#: executor/execMain.c:1115 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "ne peut pas modifier la relation « %s »" + +#: executor/execMain.c:1142 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "ne peut pas verrouiller les lignes dans la séquence « %s »" + +#: executor/execMain.c:1149 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "ne peut pas verrouiller les lignes dans la relation TOAST « %s »" + +#: executor/execMain.c:1156 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "ne peut pas verrouiller les lignes dans la vue « %s »" + +#: executor/execMain.c:1164 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "ne peut pas verrouiller les lignes dans la vue matérialisée « %s »" + +#: executor/execMain.c:1173 executor/execMain.c:2555 executor/nodeLockRows.c:136 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "ne peut pas verrouiller la table distante « %s »" + +#: executor/execMain.c:1179 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "n'a pas pu verrouiller les lignes dans la relation « %s »" + +#: executor/execMain.c:1803 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "la nouvelle ligne de la relation « %s » viole la contrainte de partitionnement" + +#: executor/execMain.c:1805 executor/execMain.c:1888 executor/execMain.c:1938 executor/execMain.c:2047 +#, c-format +msgid "Failing row contains %s." +msgstr "La ligne en échec contient %s." + +#: executor/execMain.c:1885 +#, c-format +msgid "null value in column \"%s\" of relation \"%s\" violates not-null constraint" +msgstr "une valeur NULL viole la contrainte NOT NULL de la colonne « %s » dans la relation « %s »" + +#: executor/execMain.c:1936 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "la nouvelle ligne de la relation « %s » viole la contrainte de vérification « %s »" + +#: executor/execMain.c:2045 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "la nouvelle ligne viole la contrainte de vérification pour la vue « %s »" + +#: executor/execMain.c:2055 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne « %s » pour la table « %s »" + +#: executor/execMain.c:2060 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne pour la table « %s »" + +#: executor/execMain.c:2067 +#, c-format +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne « %s » (expression USING) pour la table « %s »" + +#: executor/execMain.c:2072 +#, c-format +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne (expression USING) pour la table « %s »" + +#: executor/execPartition.c:322 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "aucune partition de la relation « %s » trouvée pour la ligne" + +#: executor/execPartition.c:325 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "La clé de partitionnement de la ligne en échec contient %s." + +#: executor/execReplication.c:196 executor/execReplication.c:373 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "la ligne à verrouiller était déjà déplacée vers une autre partition du fait d'une mise à jour concurrente, nouvelle tentative" + +#: executor/execReplication.c:200 executor/execReplication.c:377 +#, c-format +msgid "concurrent update, retrying" +msgstr "mise à jour concurrente, nouvelle tentative" + +#: executor/execReplication.c:206 executor/execReplication.c:383 +#, c-format +msgid "concurrent delete, retrying" +msgstr "suppression concurrente, nouvelle tentative" + +#: executor/execReplication.c:269 parser/parse_cte.c:502 parser/parse_oper.c:233 utils/adt/array_userfuncs.c:720 utils/adt/array_userfuncs.c:859 utils/adt/arrayfuncs.c:3654 utils/adt/arrayfuncs.c:4174 utils/adt/arrayfuncs.c:6166 utils/adt/rowtypes.c:1203 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "n'a pas pu identifier un opérateur d'égalité pour le type %s" + +#: executor/execReplication.c:590 +#, c-format +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "ne peut pas mettre à jour la table « %s » car elle n'a pas d'identité de réplicat et publie des mises à jour" + +#: executor/execReplication.c:592 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Pour permettre les mises à jour sur la table, configurez REPLICA IDENTITY en utilisant ALTER TABLE." + +#: executor/execReplication.c:596 +#, c-format +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "ne peut pas supprimer à partir de la table « %s » car elle n'a pas d'identité de réplicat et publie des suppressions" + +#: executor/execReplication.c:598 +#, c-format +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Pour permettre les suppressions sur la table, configurez REPLICA IDENTITY en utilisant ALTER TABLE." + +#: executor/execReplication.c:617 executor/execReplication.c:625 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "ne peut pas utiliser la relation « %s.%s » comme cible d'une réplication logique" + +#: executor/execReplication.c:619 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "« %s.%s » est une table distante." + +#: executor/execReplication.c:627 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "« %s.%s » n'est pas une table." + +#: executor/execSRF.c:315 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "les lignes renvoyées par la fonction ne sont pas toutes du même type ligne" + +#: executor/execSRF.c:365 +#, c-format +msgid "table-function protocol for value-per-call mode was not followed" +msgstr "le protocole de la fonction table pour le mode valeur-par-appel n'a pas été suivi" + +#: executor/execSRF.c:373 executor/execSRF.c:667 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "le protocole de la fonction table pour le mode matérialisé n'a pas été respecté" + +#: executor/execSRF.c:380 executor/execSRF.c:685 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "returnMode de la fonction table non reconnu : %d" + +#: executor/execSRF.c:894 +#, c-format +msgid "function returning setof record called in context that cannot accept type record" +msgstr "" +"la fonction renvoyant des lignes a été appelée dans un contexte qui\n" +"n'accepte pas un ensemble" + +#: executor/execSRF.c:950 executor/execSRF.c:966 executor/execSRF.c:976 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "la ligne de retour spécifiée par la requête et la ligne de retour de la fonction ne correspondent pas" + +#: executor/execSRF.c:951 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "La ligne renvoyée contient %d attribut mais la requête en attend %d." +msgstr[1] "La ligne renvoyée contient %d attributs mais la requête en attend %d." + +#: executor/execSRF.c:967 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "A renvoyé le type %s à la position ordinale %d, mais la requête attend %s." + +#: executor/execTuples.c:146 executor/execTuples.c:353 executor/execTuples.c:521 executor/execTuples.c:712 +#, c-format +msgid "cannot retrieve a system column in this context" +msgstr "ne peut pas récupérer une colonne système dans ce contexte" + +#: executor/execUtils.c:736 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "la vue matérialisée « %s » n'a pas été peuplée" + +#: executor/execUtils.c:738 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "Utilisez la commande REFRESH MATERIALIZED VIEW." + +#: executor/functions.c:217 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "n'a pas pu déterminer le type actuel de l'argument déclaré %s" + +#: executor/functions.c:514 +#, c-format +msgid "cannot COPY to/from client in an SQL function" +msgstr "ne peut pas utiliser COPY TO/FROM dans une fonction SQL" + +#. translator: %s is a SQL statement name +#: executor/functions.c:520 +#, c-format +msgid "%s is not allowed in an SQL function" +msgstr "%s n'est pas autorisé dans une fonction SQL" + +#. translator: %s is a SQL statement name +#: executor/functions.c:528 executor/spi.c:1633 executor/spi.c:2485 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "%s n'est pas autorisé dans une fonction non volatile" + +#: executor/functions.c:1442 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "fonction SQL « %s », instruction %d" + +#: executor/functions.c:1468 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "fonction SQL « %s » lors du lancement" + +#: executor/functions.c:1553 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "l'appel à des procédures avec des arguments en sortie n'est pas supporté dans les fonctions SQL" + +#: executor/functions.c:1686 executor/functions.c:1724 executor/functions.c:1738 executor/functions.c:1828 executor/functions.c:1861 executor/functions.c:1875 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "le type de retour ne correspond pas à la fonction déclarant renvoyer %s" + +#: executor/functions.c:1688 +#, c-format +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "" +"L'instruction finale de la fonction doit être un SELECT ou un\n" +"INSERT/UPDATE/DELETE RETURNING." + +#: executor/functions.c:1726 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "L'instruction finale doit renvoyer exactement une colonne." + +#: executor/functions.c:1740 +#, c-format +msgid "Actual return type is %s." +msgstr "Le code de retour réel est %s." + +#: executor/functions.c:1830 +#, c-format +msgid "Final statement returns too many columns." +msgstr "L'instruction finale renvoie beaucoup trop de colonnes." + +#: executor/functions.c:1863 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "L'instruction finale renvoie %s au lieu de %s pour la colonne %d." + +#: executor/functions.c:1877 +#, c-format +msgid "Final statement returns too few columns." +msgstr "L'instruction finale renvoie trop peu de colonnes." + +#: executor/functions.c:1905 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "le type de retour %s n'est pas supporté pour les fonctions SQL" + +#: executor/nodeAgg.c:3083 executor/nodeAgg.c:3092 executor/nodeAgg.c:3104 +#, c-format +msgid "unexpected EOF for tape %d: requested %zu bytes, read %zu bytes" +msgstr "fin de fichier inattendu pour la cassette %d : attendait %zu octets, a lu %zu octets" + +#: executor/nodeAgg.c:3977 parser/parse_agg.c:666 parser/parse_agg.c:696 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "les appels à la fonction d'agrégat ne peuvent pas être imbriqués" + +#: executor/nodeAgg.c:4185 executor/nodeWindowAgg.c:2836 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "l'agrégat %u a besoin d'avoir des types compatibles en entrée et en transition" + +#: executor/nodeCustom.c:145 executor/nodeCustom.c:156 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "le parcours personnalisé « %s » ne supporte pas MarkPos" + +#: executor/nodeHashjoin.c:1046 executor/nodeHashjoin.c:1076 +#, c-format +msgid "could not rewind hash-join temporary file" +msgstr "n'a pas pu revenir au début du fichier temporaire pour la jointure de hachage" + +#: executor/nodeHashjoin.c:1272 executor/nodeHashjoin.c:1283 +#, c-format +msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgstr "n'a pas pu lire le fichier temporaire pour la jointure de hachage : a lu seulement %zu octets sur %zu" + +#: executor/nodeIndexonlyscan.c:242 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "les fonctions de distance à perte ne sont pas supportées dans les parcours d'index seul" + +#: executor/nodeLimit.c:374 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET ne doit pas être négatif" + +#: executor/nodeLimit.c:400 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT ne doit pas être négative" + +#: executor/nodeMergejoin.c:1570 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "RIGHT JOIN est supporté seulement avec les conditions de jointures MERGE" + +#: executor/nodeMergejoin.c:1588 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "FULL JOIN est supporté seulement avec les conditions de jointures MERGE" + +#: executor/nodeModifyTable.c:154 +#, c-format +msgid "Query has too few columns." +msgstr "La requête n'a pas assez de colonnes." + +#: executor/nodeModifyTable.c:1203 executor/nodeModifyTable.c:1277 +#, c-format +msgid "tuple to be deleted was already modified by an operation triggered by the current command" +msgstr "la ligne à supprimer était déjà modifiée par une opération déclenchée par la commande courante" + +#: executor/nodeModifyTable.c:1452 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "spécification ON UPDATE invalide" + +#: executor/nodeModifyTable.c:1453 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "La ligne résultante apparaîtrait dans une partition différente de la ligne originale." + +#: executor/nodeModifyTable.c:2049 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "la commande ON CONFLICT DO UPDATE ne peut pas affecter une ligne la deuxième fois" + +#: executor/nodeModifyTable.c:2050 +#, c-format +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." +msgstr "S'assure qu'aucune ligne proposée à l'insertion dans la même commande n'a de valeurs contraintes dupliquées." + +#: executor/nodeSamplescan.c:259 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "le paramètre de TABLESAMPLE ne peut pas être NULL" + +#: executor/nodeSamplescan.c:271 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "le paramètre TABLESAMPLE REPEATABLE ne peut pas être NULL" + +#: executor/nodeSubplan.c:346 executor/nodeSubplan.c:385 executor/nodeSubplan.c:1159 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "plus d'une ligne renvoyée par une sous-requête utilisée comme une expression" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "l'URI de l'espace de nom ne doit pas être NULL" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "l'expression de filtre de lignes ne doit pas être NULL" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "l'expression de filtre de colonnes ne doit pas être NULL" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "Le filtre pour la colonne « %s » est NULL." + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "NULL n'est pas autorisé dans la colonne « %s »" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "la fonction de conversion de l'agrégat en déplacement ne doit pas renvoyer null" + +#: executor/nodeWindowAgg.c:2058 +#, c-format +msgid "frame starting offset must not be null" +msgstr "l'offset de début de frame ne doit pas être NULL" + +#: executor/nodeWindowAgg.c:2071 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "l'offset de début de frame ne doit pas être négatif" + +#: executor/nodeWindowAgg.c:2083 +#, c-format +msgid "frame ending offset must not be null" +msgstr "l'offset de fin de frame ne doit pas être NULL" + +#: executor/nodeWindowAgg.c:2096 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "l'offset de fin de frame ne doit pas être négatif" + +#: executor/nodeWindowAgg.c:2752 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "la fonction d'agrégat %s ne supporte pas l'utilisation en tant que fonction de fenêtrage" + +#: executor/spi.c:237 executor/spi.c:302 +#, c-format +msgid "invalid transaction termination" +msgstr "arrêt de transaction invalide" + +#: executor/spi.c:251 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "ne peut pas valider la transaction pendant qu'une sous-transaction est active" + +#: executor/spi.c:308 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "ne peut pas annuler la transaction pendant qu'une sous-transaction est active" + +#: executor/spi.c:380 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "transaction gauche non vide dans la pile SPI" + +#: executor/spi.c:381 executor/spi.c:443 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "Vérifiez les appels manquants à « SPI_finish »." + +#: executor/spi.c:442 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "sous-transaction gauche non vide dans la pile SPI" + +#: executor/spi.c:1495 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "ne peut pas ouvrir le plan à plusieurs requêtes comme curseur" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1500 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "ne peut pas ouvrir la requête %s comme curseur" + +#: executor/spi.c:1607 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE n'est pas supporté" + +#: executor/spi.c:1608 parser/analyze.c:2808 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "Les curseurs déplaçables doivent être en lecture seule (READ ONLY)." + +#: executor/spi.c:2809 +#, c-format +msgid "SQL expression \"%s\"" +msgstr "expression SQL « %s »" + +#: executor/spi.c:2814 +#, c-format +msgid "PL/pgSQL assignment \"%s\"" +msgstr "affectation PL/pgSQL « %s »" + +#: executor/spi.c:2817 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "instruction SQL « %s »" + +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "n'a pas pu envoyer la ligne dans la queue en mémoire partagée" + +#: foreign/foreign.c:220 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "correspondance utilisateur non trouvée pour « %s »" + +#: foreign/foreign.c:672 +#, c-format +msgid "invalid option \"%s\"" +msgstr "option « %s » invalide" + +#: foreign/foreign.c:673 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "Les options valides dans ce contexte sont %s" + +#: gram.y:1107 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD n'est plus supporté" + +#: gram.y:1108 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "Supprimez UNENCRYPTED pour enregistrer le mot de passe dans sa forme chiffrée à la place." + +#: gram.y:1170 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "option « %s » du rôle non reconnue" + +#: gram.y:1417 gram.y:1432 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS n'inclut pas les éléments du schéma" + +#: gram.y:1578 +#, c-format +msgid "current database cannot be changed" +msgstr "la base de données actuelle ne peut pas être changée" + +#: gram.y:1702 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "l'intervalle de fuseau horaire doit être HOUR ou HOUR TO MINUTE" + +#: gram.y:2270 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "le numéro de colonne doit être dans l'intervalle entre 1 et %d" + +#: gram.y:2811 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "option de séquence « %s » non supportée ici" + +#: gram.y:2840 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "le modulus pour la partition hash est spécifié plus d'une fois" + +#: gram.y:2849 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "le reste pour la partition hash est spécifié plus d'une fois" + +#: gram.y:2856 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "spécification de limite de partition hash non reconnue « %s »" + +#: gram.y:2864 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "le modulus pour les partition hash doit être spécifié" + +#: gram.y:2868 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "le reste pour les partition hash doit être spécifié" + +#: gram.y:3069 gram.y:3102 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "STDIN/STDOUT non autorisé dans PROGRAM" + +#: gram.y:3075 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "la clause WHERE n'est pas autorisée avec COPY TO" + +#: gram.y:3407 gram.y:3414 gram.y:11665 gram.y:11673 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "GLOBAL est obsolète dans la création de la table temporaire" + +#: gram.y:3665 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "pour une colonne générée, GENERATED ALWAYS doit toujours être spécifié" + +#: gram.y:3933 utils/adt/ri_triggers.c:2032 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL non implémenté" + +#: gram.y:4634 +#, c-format +msgid "CREATE EXTENSION ... FROM is no longer supported" +msgstr "CREATE EXTENSION ... FROM n'est plus supporté" + +#: gram.y:5297 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "option « %s » de sécurité de ligne non reconnue" + +#: gram.y:5298 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "Seules les politiques PERMISSIVE et RESTRICTIVE sont supportées actuellement." + +#: gram.y:5380 +#, c-format +msgid "CREATE OR REPLACE CONSTRAINT TRIGGER is not supported" +msgstr "CREATE OR REPLACE CONSTRAINT TRIGGER n'est pas supporté" + +#: gram.y:5417 +msgid "duplicate trigger events specified" +msgstr "événements de trigger dupliqués spécifiés" + +#: gram.y:5558 parser/parse_utilcmd.c:3702 parser/parse_utilcmd.c:3728 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "la contrainte déclarée INITIALLY DEFERRED doit être DEFERRABLE" + +#: gram.y:5565 +#, c-format +msgid "conflicting constraint properties" +msgstr "propriétés de contrainte en conflit" + +#: gram.y:5661 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION n'est pas encore implémenté" + +#: gram.y:6044 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK n'est plus nécessaire" + +#: gram.y:6045 +#, c-format +msgid "Update your data type." +msgstr "Mettez à jour votre type de données." + +#: gram.y:7741 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "les agrégats ne peuvent pas avoir d'arguments en sortie" + +#: gram.y:8188 utils/adt/regproc.c:710 utils/adt/regproc.c:751 +#, c-format +msgid "missing argument" +msgstr "argument manquant" + +#: gram.y:8189 utils/adt/regproc.c:711 utils/adt/regproc.c:752 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "Utilisez NONE pour dénoter l'argument manquant d'un opérateur unitaire." + +#: gram.y:10128 gram.y:10146 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION non supporté sur les vues récursives" + +#: gram.y:11802 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "la syntaxe LIMIT #,# n'est pas supportée" + +#: gram.y:11803 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "Utilisez les clauses séparées LIMIT et OFFSET." + +#: gram.y:12141 gram.y:12166 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "VALUES dans FROM doit avoir un alias" + +#: gram.y:12142 gram.y:12167 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "Par exemple, FROM (VALUES ...) [AS] quelquechose." + +#: gram.y:12147 gram.y:12172 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "la sous-requête du FROM doit avoir un alias" + +#: gram.y:12148 gram.y:12173 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "Par exemple, FROM (SELECT...) [AS] quelquechose." + +#: gram.y:12668 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "seule une valeur DEFAULT est autorisée" + +#: gram.y:12677 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "seule une valeur PATH par colonne est autorisée" + +#: gram.y:12686 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "déclarations NULL/NOT NULL en conflit ou redondantes pour la colonne « %s »" + +#: gram.y:12695 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "option de colonne « %s » non reconnue" + +#: gram.y:12949 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "la précision du type float doit être d'au moins un bit" + +#: gram.y:12958 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "la précision du type float doit être inférieur à 54 bits" + +#: gram.y:13456 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "mauvais nombre de paramètres sur le côté gauche de l'expression OVERLAPS" + +#: gram.y:13461 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "mauvais nombre de paramètres sur le côté droit de l'expression OVERLAPS" + +#: gram.y:13629 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "prédicat UNIQUE non implémenté" + +#: gram.y:13988 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "ne peut pas utiliser des clauses ORDER BY multiples dans WITHIN GROUP" + +#: gram.y:13993 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "ne peut pas utiliser DISTINCT avec WITHIN GROUP" + +#: gram.y:13998 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "ne peut pas utiliser VARIADIC avec WITHIN GROUP" + +#: gram.y:14522 gram.y:14545 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "la fin du frame ne peut pas être UNBOUNDED FOLLOWING" + +#: gram.y:14527 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "la frame commençant après la ligne suivante ne peut pas se terminer avec la ligne actuelle" + +#: gram.y:14550 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "la fin du frame ne peut pas être UNBOUNDED PRECEDING" + +#: gram.y:14556 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "la frame commençant à la ligne courante ne peut pas avoir des lignes précédentes" + +#: gram.y:14563 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "la frame commençant à la ligne suivante ne peut pas avoir des lignes précédentes" + +#: gram.y:15195 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "le modificateur de type ne peut pas avoir de nom de paramètre" + +#: gram.y:15201 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "le modificateur de type ne peut pas avoir de clause ORDER BY" + +#: gram.y:15266 gram.y:15273 gram.y:15280 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s ne peut pas être utilisé comme nom de rôle ici" + +#: gram.y:15369 gram.y:16800 +#, c-format +msgid "WITH TIES cannot be specified without ORDER BY clause" +msgstr "WITH TIES ne peut pas être indiqué sans clause ORDER BY" + +#: gram.y:16477 gram.y:16666 +msgid "improper use of \"*\"" +msgstr "mauvaise utilisation de « * »" + +#: gram.y:16629 gram.y:16646 tsearch/spell.c:982 tsearch/spell.c:999 tsearch/spell.c:1016 tsearch/spell.c:1033 tsearch/spell.c:1098 +#, c-format +msgid "syntax error" +msgstr "erreur de syntaxe" + +#: gram.y:16730 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "un agrégat par ensemble ordonné avec un argument VARIADIC direct doit avoir un argument VARIADIC agrégé du même type de données" + +#: gram.y:16767 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "clauses ORDER BY multiples non autorisées" + +#: gram.y:16778 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "clauses OFFSET multiples non autorisées" + +#: gram.y:16787 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "clauses LIMIT multiples non autorisées" + +#: gram.y:16796 +#, c-format +msgid "multiple limit options not allowed" +msgstr "options limite multiples non autorisées" + +#: gram.y:16808 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "clauses WITH multiples non autorisées" + +#: gram.y:17002 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "les arguments OUT et INOUT ne sont pas autorisés dans des fonctions TABLE" + +#: gram.y:17098 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "clauses COLLATE multiples non autorisées" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17136 gram.y:17149 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "les contraintes %s ne peuvent pas être marquées comme DEFERRABLE" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17162 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "les contraintes %s ne peuvent pas être marquées comme NOT VALID" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:17175 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "les contraintes %s ne peuvent pas être marquées NO INHERIT" + +#: guc-file.l:314 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %d" +msgstr "paramètre de configuration « %s » non reconnu dans le fichier « %s », ligne %d" + +#: guc-file.l:351 utils/misc/guc.c:7360 utils/misc/guc.c:7558 utils/misc/guc.c:7652 utils/misc/guc.c:7746 utils/misc/guc.c:7866 utils/misc/guc.c:7965 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "le paramètre « %s » ne peut pas être modifié sans redémarrer le serveur" + +#: guc-file.l:387 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "" +"paramètre « %s » supprimé du fichier de configuration ;\n" +"réinitialisation à la valeur par défaut" + +#: guc-file.l:453 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "paramètre « %s » modifié par « %s »" + +#: guc-file.l:495 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "le fichier de configuration « %s » contient des erreurs" + +#: guc-file.l:500 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "le fichier de configuration « %s » contient des erreurs ; les modifications non affectées ont été appliquées" + +#: guc-file.l:505 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "le fichier de configuration « %s » contient des erreurs ; aucune modification n'a été appliquée" + +#: guc-file.l:577 +#, c-format +msgid "empty configuration file name: \"%s\"" +msgstr "nom de fichier de configuration vide : « %s »" + +#: guc-file.l:594 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "" +"n'a pas pu ouvrir le fichier de configuration « %s » : profondeur\n" +"d'imbrication dépassé" + +#: guc-file.l:614 +#, c-format +msgid "configuration file recursion in \"%s\"" +msgstr "le fichier de configuration « %s » contient une récursion" + +#: guc-file.l:630 libpq/hba.c:2251 libpq/hba.c:2665 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier de configuration « %s » : %m" + +#: guc-file.l:641 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "ignore le fichier de configuration « %s » manquant" + +#: guc-file.l:895 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "erreur de syntaxe dans le fichier « %s », ligne %u, près de la fin de ligne" + +#: guc-file.l:905 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "erreur de syntaxe dans le fichier « %s », ligne %u, près du mot clé « %s »" + +#: guc-file.l:925 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "trop d'erreurs de syntaxe trouvées, abandon du fichier « %s »" + +#: guc-file.l:980 +#, c-format +msgid "empty configuration directory name: \"%s\"" +msgstr "nom de répertoire de configuration vide : « %s »" + +#: guc-file.l:999 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "n'a pas pu ouvrir le répertoire de configuration « %s » : %m" + +#: jit/jit.c:205 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:417 utils/fmgr/dfmgr.c:465 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "n'a pas pu accéder au fichier « %s » : %m" + +#: jsonpath_gram.y:528 jsonpath_scan.l:519 jsonpath_scan.l:530 jsonpath_scan.l:540 jsonpath_scan.l:582 utils/adt/encode.c:435 utils/adt/encode.c:501 utils/adt/jsonfuncs.c:623 utils/adt/varlena.c:339 utils/adt/varlena.c:380 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "syntaxe en entrée invalide pour le type %s" + +#: jsonpath_gram.y:529 +#, c-format +msgid "unrecognized flag character \"%.*s\" in LIKE_REGEX predicate" +msgstr "caractère d'état « %.*s » non reconnu dans un prédicat LIKE_REGEX" + +#: jsonpath_gram.y:583 +#, c-format +msgid "XQuery \"x\" flag (expanded regular expressions) is not implemented" +msgstr "le flag XQuery « x » (expression régulière étendue) n'est pas implémenté" + +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:286 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "%s à la fin de l'entrée jsonpath" + +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:293 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s sur ou près de « %s » de l'entrée jsonpath" + +#: jsonpath_scan.l:498 utils/adt/jsonfuncs.c:617 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "séquence d'échappement Unicode non supportée" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Échec d'une requête DSA de taille %zu." + +#: libpq/auth-scram.c:249 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "le client a sélectionné un mécanisme d'authentification SASL invalide" + +#: libpq/auth-scram.c:270 libpq/auth-scram.c:510 libpq/auth-scram.c:521 +#, c-format +msgid "invalid SCRAM secret for user \"%s\"" +msgstr "secret SCRAM invalide pour l'utilisateur « %s »" + +#: libpq/auth-scram.c:281 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM secret." +msgstr "L'utilisateur « %s » n'a pas de secret SCRAM valide." + +#: libpq/auth-scram.c:359 libpq/auth-scram.c:364 libpq/auth-scram.c:701 libpq/auth-scram.c:709 libpq/auth-scram.c:814 libpq/auth-scram.c:827 libpq/auth-scram.c:837 libpq/auth-scram.c:945 libpq/auth-scram.c:952 libpq/auth-scram.c:967 libpq/auth-scram.c:982 libpq/auth-scram.c:996 libpq/auth-scram.c:1014 libpq/auth-scram.c:1029 libpq/auth-scram.c:1340 libpq/auth-scram.c:1348 +#, c-format +msgid "malformed SCRAM message" +msgstr "message SCRAM malformé" + +#: libpq/auth-scram.c:360 +#, c-format +msgid "The message is empty." +msgstr "Le message est vide." + +#: libpq/auth-scram.c:365 +#, c-format +msgid "Message length does not match input length." +msgstr "La longueur du message ne correspond pas à la longueur en entrée." + +#: libpq/auth-scram.c:397 +#, c-format +msgid "invalid SCRAM response" +msgstr "réponse SCRAM invalide" + +#: libpq/auth-scram.c:398 +#, c-format +msgid "Nonce does not match." +msgstr "Le nonce ne correspond pas." + +#: libpq/auth-scram.c:472 +#, c-format +msgid "could not generate random salt" +msgstr "n'a pas pu générer le sel aléatoire" + +#: libpq/auth-scram.c:702 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Attribut attendu « %c », mais « %s » trouvé." + +#: libpq/auth-scram.c:710 libpq/auth-scram.c:838 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Caractère « = » attendu pour l'attribut « %c »." + +#: libpq/auth-scram.c:815 +#, c-format +msgid "Attribute expected, but found end of string." +msgstr "Attribut attendu, mais a trouvé une fin de chaîne." + +#: libpq/auth-scram.c:828 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Attribut attendu, mais a trouvé le caractère invalide « %s »." + +#: libpq/auth-scram.c:946 libpq/auth-scram.c:968 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "Le client a sélectionné SCRAM-SHA-256-PLUS, mais le message SCRAM n'inclut pas de données de channel-binding." + +#: libpq/auth-scram.c:953 libpq/auth-scram.c:983 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Virgule attendue, mais caractère « %s » trouvé." + +#: libpq/auth-scram.c:974 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "Erreur de négociation de channel-binding SCRAM" + +#: libpq/auth-scram.c:975 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "Le client supporte le channel binding SCRAM mais pense que le serveur ne le supporte pas. Cependant, ce serveur supporte vraiment le channel-binding." + +#: libpq/auth-scram.c:997 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "Le client a sélectionné SCRAM-SHA-256 sans channel binding, mais le message SCRAM inclue des données de channel-binding." + +#: libpq/auth-scram.c:1008 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "type de channel-binding SCRAM « %s » non supporté" + +#: libpq/auth-scram.c:1015 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Drapeau du channel-binding inattendu « %s »." + +#: libpq/auth-scram.c:1025 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "le client utilise une identité d'autorisation, mais elle n'est pas supportée" + +#: libpq/auth-scram.c:1030 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Attribut « %s » inattendu dans client-first-message." + +#: libpq/auth-scram.c:1046 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "le client requiert une extension SCRAM non supportée" + +#: libpq/auth-scram.c:1060 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "caractères non affichables dans le nonce SCRAM" + +#: libpq/auth-scram.c:1188 +#, c-format +msgid "could not generate random nonce" +msgstr "n'a pas pu générer le nonce aléatoire" + +#: libpq/auth-scram.c:1198 +#, c-format +msgid "could not encode random nonce" +msgstr "n'a pas pu chiffrer le nonce aléatoire" + +#: libpq/auth-scram.c:1304 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "la vérification du channel-binding SCRAM a échoué" + +#: libpq/auth-scram.c:1322 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "attribut du lien de canal SCRAM inattendu dans client-final-message" + +#: libpq/auth-scram.c:1341 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "Preuve malformée dans le client-final-message." + +#: libpq/auth-scram.c:1349 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Problème trouvé à la fin de client-final-message." + +#: libpq/auth.c:284 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "authentification échouée pour l'utilisateur « %s » : hôte rejeté" + +#: libpq/auth.c:287 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "authentification « trust » échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:290 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "Échec de l'authentification Ident pour l'utilisateur « %s »" + +#: libpq/auth.c:293 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "authentification peer échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:298 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "authentification par mot de passe échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:303 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "authentification GSSAPI échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:306 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "authentification SSPI échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:309 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "authentification PAM échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:312 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "authentification BSD échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:315 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "authentification LDAP échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:318 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "authentification par le certificat échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:321 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "authentification RADIUS échouée pour l'utilisateur « %s »" + +#: libpq/auth.c:324 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "authentification échouée pour l'utilisateur « %s » : méthode d'authentification invalide" + +#: libpq/auth.c:328 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "La connexion correspond à la ligne %d du pg_hba.conf : « %s »" + +#: libpq/auth.c:371 +#, c-format +msgid "connection was re-authenticated" +msgstr "la connexion a été ré-authentifiée" + +#: libpq/auth.c:372 +#, c-format +msgid "previous ID: \"%s\"; new ID: \"%s\"" +msgstr "ID précédent : « %s » ; nouvel ID : « %s »" + +#: libpq/auth.c:381 +#, c-format +msgid "connection authenticated: identity=\"%s\" method=%s (%s:%d)" +msgstr "connexion authentifiée : identité=\"%s\" méthode=%s (%s:%d)" + +#: libpq/auth.c:420 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "" +"les certificats cert peuvent seulement être vérifiés si un emplacement de\n" +"certificat racine est disponible" + +#: libpq/auth.c:431 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "la connexion requiert un certificat client valide" + +#: libpq/auth.c:462 libpq/auth.c:508 +msgid "GSS encryption" +msgstr "chiffrement GSS" + +#: libpq/auth.c:465 libpq/auth.c:511 +msgid "SSL encryption" +msgstr "chiffrement SSL" + +#: libpq/auth.c:467 libpq/auth.c:513 +msgid "no encryption" +msgstr "aucun chiffrement" + +#. translator: last %s describes encryption state +#: libpq/auth.c:473 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "" +"pg_hba.conf rejette la connexion de la réplication pour l'hôte « %s »,\n" +"utilisateur « %s », %s" + +#. translator: last %s describes encryption state +#: libpq/auth.c:480 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "" +"pg_hba.conf rejette la connexion pour l'hôte « %s », utilisateur « %s », base\n" +"de données « %s », %s" + +#: libpq/auth.c:518 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "Adresse IP du client résolue en « %s », la recherche inverse correspond bien." + +#: libpq/auth.c:521 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "Adresse IP du client résolue en « %s », la recherche inverse n'est pas vérifiée." + +#: libpq/auth.c:524 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "Adresse IP du client résolue en « %s », la recherche inverse ne correspond pas." + +#: libpq/auth.c:527 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "N'a pas pu traduire le nom d'hôte « %s » du client en adresse IP : %s." + +#: libpq/auth.c:532 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "N'a pas pu résoudre l'adresse IP du client à partir du nom d'hôte : %s." + +#. translator: last %s describes encryption state +#: libpq/auth.c:540 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "" +"aucune entrée dans pg_hba.conf pour la connexion de la réplication à partir de\n" +"l'hôte « %s », utilisateur « %s », %s" + +#. translator: last %s describes encryption state +#: libpq/auth.c:548 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "" +"aucune entrée dans pg_hba.conf pour l'hôte « %s », utilisateur « %s »,\n" +"base de données « %s », %s" + +#: libpq/auth.c:721 +#, c-format +msgid "expected password response, got message type %d" +msgstr "en attente du mot de passe, a reçu un type de message %d" + +#: libpq/auth.c:742 +#, c-format +msgid "invalid password packet size" +msgstr "taille du paquet du mot de passe invalide" + +#: libpq/auth.c:760 +#, c-format +msgid "empty password returned by client" +msgstr "mot de passe vide renvoyé par le client" + +#: libpq/auth.c:887 libpq/hba.c:1366 +#, c-format +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "l'authentification MD5 n'est pas supportée quand « db_user_namespace » est activé" + +#: libpq/auth.c:893 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "n'a pas pu générer le sel MD5 aléatoire" + +#: libpq/auth.c:959 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "attendait une réponse SASL, a reçu le type de message %d" + +#: libpq/auth.c:1088 libpq/be-secure-gssapi.c:535 +#, c-format +msgid "could not set environment: %m" +msgstr "n'a pas pu configurer l'environnement : %m" + +#: libpq/auth.c:1124 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "en attente d'une réponse GSS, a reçu un message de type %d" + +#: libpq/auth.c:1184 +msgid "accepting GSS security context failed" +msgstr "échec de l'acceptation du contexte de sécurité GSS" + +#: libpq/auth.c:1224 +msgid "retrieving GSS user name failed" +msgstr "échec lors de la récupération du nom de l'utilisateur avec GSS" + +#: libpq/auth.c:1365 +msgid "could not acquire SSPI credentials" +msgstr "n'a pas pu obtenir les pièces d'identité SSPI" + +#: libpq/auth.c:1390 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "en attente d'une réponse SSPI, a reçu un message de type %d" + +#: libpq/auth.c:1468 +msgid "could not accept SSPI security context" +msgstr "n'a pas pu accepter le contexte de sécurité SSPI" + +#: libpq/auth.c:1530 +msgid "could not get token from SSPI security context" +msgstr "n'a pas pu obtenir le jeton du contexte de sécurité SSPI" + +#: libpq/auth.c:1669 libpq/auth.c:1688 +#, c-format +msgid "could not translate name" +msgstr "n'a pas pu traduit le nom" + +#: libpq/auth.c:1701 +#, c-format +msgid "realm name too long" +msgstr "nom du royaume trop long" + +#: libpq/auth.c:1716 +#, c-format +msgid "translated account name too long" +msgstr "traduction du nom de compte trop longue" + +#: libpq/auth.c:1897 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "n'a pas pu créer le socket pour la connexion Ident : %m" + +#: libpq/auth.c:1912 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "n'a pas pu se lier à l'adresse locale « %s » : %m" + +#: libpq/auth.c:1924 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "n'a pas pu se connecter au serveur Ident à l'adresse « %s », port %s : %m" + +#: libpq/auth.c:1946 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "n'a pas pu envoyer la requête au serveur Ident à l'adresse « %s », port %s : %m" + +#: libpq/auth.c:1963 +#, c-format +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "" +"n'a pas pu recevoir la réponse du serveur Ident à l'adresse « %s », port %s :\n" +"%m" + +#: libpq/auth.c:1973 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "réponse mal formatée du serveur Ident : « %s »" + +#: libpq/auth.c:2026 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "la méthode d'authentification «peer n'est pas supportée sur cette plateforme" + +#: libpq/auth.c:2030 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "n'a pas pu obtenir l'authentification de l'autre : %m" + +#: libpq/auth.c:2042 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "n'a pas pu rechercher l'identifiant %ld de l'utilisateur local : %s" + +#: libpq/auth.c:2143 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "erreur provenant de la couche PAM : %s" + +#: libpq/auth.c:2154 +#, c-format +msgid "unsupported PAM conversation %d/\"%s\"" +msgstr "conversation PAM %d/\"%s\" non supportée" + +#: libpq/auth.c:2214 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "n'a pas pu créer l'authenticateur PAM : %s" + +#: libpq/auth.c:2225 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER) a échoué : %s" + +#: libpq/auth.c:2257 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST) a échoué : %s" + +#: libpq/auth.c:2269 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "pam_set_item(PAM_CONV) a échoué : %s" + +#: libpq/auth.c:2282 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "pam_authenticate a échoué : %s" + +#: libpq/auth.c:2295 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmt a échoué : %s" + +#: libpq/auth.c:2306 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "n'a pas pu fermer l'authenticateur PAM : %s" + +#: libpq/auth.c:2386 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "n'a pas pu initialiser LDAP : code d'erreur %d" + +#: libpq/auth.c:2423 +#, c-format +msgid "could not extract domain name from ldapbasedn" +msgstr "n'a pas pu extraire le nom de domaine depuis ldapbasedn" + +#: libpq/auth.c:2431 +#, c-format +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "l'authentification LDAP n'a pu trouver les enregistrement DNS SRV pour « %s »" + +#: libpq/auth.c:2433 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "Définit un nom de serveur LDAP explicitement." + +#: libpq/auth.c:2485 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "n'a pas pu initialiser LDAP : %s" + +#: libpq/auth.c:2495 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ldaps non supporté avec cette bibliothèque LDAP" + +#: libpq/auth.c:2503 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "n'a pas pu initialiser LDAP : %m" + +#: libpq/auth.c:2513 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "n'a pas pu initialiser la version du protocole LDAP : %s" + +#: libpq/auth.c:2553 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "n'a pas pu charger la fonction _ldap_start_tls_sA de wldap32.dll" + +#: libpq/auth.c:2554 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "LDAP via SSL n'est pas supporté sur cette plateforme." + +#: libpq/auth.c:2570 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "n'a pas pu démarrer la session TLS LDAP : %s" + +#: libpq/auth.c:2641 +#, c-format +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "serveur LDAP non précisé, et il n'y a pas de ldapbasedn" + +#: libpq/auth.c:2648 +#, c-format +msgid "LDAP server not specified" +msgstr "serveur LDAP non précisé" + +#: libpq/auth.c:2710 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "caractère invalide dans le nom de l'utilisateur pour l'authentification LDAP" + +#: libpq/auth.c:2727 +#, c-format +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "n'a pas pu réaliser le lien LDAP initiale pour ldapbinddn « %s » sur le serveur « %s » : %s" + +#: libpq/auth.c:2756 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "n'a pas pu rechercher dans LDAP pour filtrer « %s » sur le serveur « %s » : %s" + +#: libpq/auth.c:2770 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "l'utilisateur LDAP « %s » n'existe pas" + +#: libpq/auth.c:2771 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "la recherche LDAP pour le filtre « %s » sur le serveur « %s » n'a renvoyé aucun enregistrement." + +#: libpq/auth.c:2775 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "l'utilisateur LDAP « %s » n'est pas unique" + +#: libpq/auth.c:2776 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "la recherche LDAP pour le filtre « %s » sur le serveur « %s » a renvoyé %d enregistrement." +msgstr[1] "la recherche LDAP pour le filtre « %s » sur le serveur « %s » a renvoyé %d enregistrements." + +#: libpq/auth.c:2796 +#, c-format +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "" +"n'a pas pu obtenir le dn pour la première entrée correspondante « %s » sur\n" +"le serveur « %s » : %s" + +#: libpq/auth.c:2817 +#, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "" +"n'a pas pu exécuter le unbind après la recherche de l'utilisateur « %s »\n" +"sur le serveur « %s »" + +#: libpq/auth.c:2848 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "échec de connexion LDAP pour l'utilisateur « %s » sur le serveur « %s » : %s" + +#: libpq/auth.c:2880 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "diagnostique LDAP: %s" + +#: libpq/auth.c:2918 +#, c-format +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "" +"l'authentification par le certificat a échoué pour l'utilisateur « %s » :\n" +"le certificat du client ne contient aucun nom d'utilisateur" + +#: libpq/auth.c:2939 +#, c-format +msgid "certificate authentication failed for user \"%s\": unable to retrieve subject DN" +msgstr "authentification par certificat échouée pour l'utilisateur « %s » : incapable de récupérer le DN sujet" + +#: libpq/auth.c:2962 +#, c-format +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": DN mismatch" +msgstr "la validation du certificat (clientcert=verify-full) a échoué pour l'utilisateur « %s » : incohérence de DN" + +#: libpq/auth.c:2967 +#, c-format +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" +msgstr "l'authentification par certificat (clientcert=verify-full) a échoué pour l'utilisateur « %s » : incohérence de CN" + +#: libpq/auth.c:3069 +#, c-format +msgid "RADIUS server not specified" +msgstr "serveur RADIUS non précisé" + +#: libpq/auth.c:3076 +#, c-format +msgid "RADIUS secret not specified" +msgstr "secret RADIUS non précisé" + +#: libpq/auth.c:3090 +#, c-format +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "l'authentification RADIUS ne supporte pas les mots de passe de plus de %d caractères" + +#: libpq/auth.c:3197 libpq/hba.c:2004 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "n'a pas pu traduire le nom du serveur RADIUS « %s » en une adresse : %s" + +#: libpq/auth.c:3211 +#, c-format +msgid "could not generate random encryption vector" +msgstr "n'a pas pu générer le vecteur de chiffrement aléatoire" + +#: libpq/auth.c:3245 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "n'a pas pu réaliser le chiffrement MD5 du mot de passe" + +#: libpq/auth.c:3271 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "n'a pas pu créer le socket RADIUS : %m" + +#: libpq/auth.c:3293 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "n'a pas pu se lier à la socket RADIUS : %m" + +#: libpq/auth.c:3303 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "n'a pas pu transmettre le paquet RADIUS : %m" + +#: libpq/auth.c:3336 libpq/auth.c:3362 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "dépassement du délai pour la réponse du RADIUS à partir de %s" + +#: libpq/auth.c:3355 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "n'a pas pu vérifier le statut sur la socket RADIUS : %m" + +#: libpq/auth.c:3385 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "n'a pas pu lire la réponse RADIUS : %m" + +#: libpq/auth.c:3398 libpq/auth.c:3402 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "la réponse RADIUS de %s a été envoyée à partir d'un mauvais port : %d" + +#: libpq/auth.c:3411 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "réponse RADIUS de %s trop courte : %d" + +#: libpq/auth.c:3418 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "la réponse RADIUS de %s a une longueur corrompue : %d (longueur réelle %d)" + +#: libpq/auth.c:3426 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "la réponse RADIUS de %s correspond à une demande différente : %d (devrait être %d)" + +#: libpq/auth.c:3451 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "n'a pas pu réaliser le chiffrement MD5 du paquet reçu" + +#: libpq/auth.c:3460 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "la réponse RADIUS de %s a une signature MD5 invalide" + +#: libpq/auth.c:3478 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "la réponse RADIUS de %s a un code invalide (%d) pour l'utilisateur « %s »" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:553 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "descripteur invalide de « Large Object » : %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "le descripteur %d du « Large Object » n'a pas été ouvert pour la lecture" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:560 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "le descripteur %d du « Large Object » n'a pas été ouvert pour l'écriture" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "résultat de lo_lseek en dehors de l'intervalle pour le descripteur de Large Object %d" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "résultat de lo_tell en dehors de l'intervalle pour le descripteur de Large Object %d" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier serveur « %s » : %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "n'a pas pu lire le fichier serveur « %s » : %m" + +#: libpq/be-fsstubs.c:514 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "n'a pas pu créer le fichier serveur « %s » : %m" + +#: libpq/be-fsstubs.c:526 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "n'a pas pu écrire le fichier serveur « %s » : %m" + +#: libpq/be-fsstubs.c:760 +#, c-format +msgid "large object read request is too large" +msgstr "la demande de lecture du Large Object est trop grande" + +#: libpq/be-fsstubs.c:802 utils/adt/genfile.c:267 utils/adt/genfile.c:306 utils/adt/genfile.c:342 +#, c-format +msgid "requested length cannot be negative" +msgstr "la longueur demandée ne peut pas être négative" + +#: libpq/be-fsstubs.c:855 storage/large_object/inv_api.c:297 storage/large_object/inv_api.c:309 storage/large_object/inv_api.c:513 storage/large_object/inv_api.c:624 storage/large_object/inv_api.c:814 +#, c-format +msgid "permission denied for large object %u" +msgstr "droit refusé pour le Large Object %u" + +#: libpq/be-secure-common.c:93 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "n'a pas pu lire à partir de la commande « %s » : %m" + +#: libpq/be-secure-common.c:113 +#, c-format +msgid "command \"%s\" failed" +msgstr "la commande « %s » a échoué" + +#: libpq/be-secure-common.c:141 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "n'a pas pu accéder au fichier de la clé privée « %s » : %m" + +#: libpq/be-secure-common.c:150 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "le fichier de clé privée « %s » n'est pas un fichier" + +#: libpq/be-secure-common.c:165 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "le fichier de clé privée « %s » doit avoir le même propriétaire que la base de donnée ou root" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "" +"le fichier de clé privé « %s » est accessible par le groupe et/ou par les\n" +"autres" + +#: libpq/be-secure-common.c:190 +#, c-format +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "" +"Le fichier doit avoir les permissions u=rw (0600) ou moins si le propriétaire est le même que la base de données,\n" +"ou les permissions u=rw,g=r (0640) ou moins si le propriétaire est root." + +#: libpq/be-secure-gssapi.c:204 +msgid "GSSAPI wrap error" +msgstr "erreur d'empaquetage GSSAPI" + +#: libpq/be-secure-gssapi.c:211 +#, c-format +msgid "outgoing GSSAPI message would not use confidentiality" +msgstr "le message sortant GSSAPI n'utilliserait pas la confidentialité" + +#: libpq/be-secure-gssapi.c:218 libpq/be-secure-gssapi.c:622 +#, c-format +msgid "server tried to send oversize GSSAPI packet (%zu > %zu)" +msgstr "le serveur a tenté d'envoyer un paquet GSSAPI surdimensionné (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:351 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "paquet GSSAPI surdimensionné envoyé par le client (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:389 +msgid "GSSAPI unwrap error" +msgstr "erreur de dépaquetage GSSAPI" + +#: libpq/be-secure-gssapi.c:396 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "le message GSSAPI en entrée n'a pas utilisé la confidentialité" + +#: libpq/be-secure-gssapi.c:570 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "paquet GSSAPI surdimensionné envoyé par le client (%zu > %d)" + +#: libpq/be-secure-gssapi.c:594 +msgid "could not accept GSSAPI security context" +msgstr "n'a pas pu accepter le contexte de sécurité GSSAPI" + +#: libpq/be-secure-gssapi.c:689 +msgid "GSSAPI size check error" +msgstr "erreur de vérification de taille GSSAPI" + +#: libpq/be-secure-openssl.c:115 +#, c-format +msgid "could not create SSL context: %s" +msgstr "n'a pas pu créer le contexte SSL : %s" + +#: libpq/be-secure-openssl.c:141 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "n'a pas pu charger le fichier du certificat serveur « %s » : %s" + +#: libpq/be-secure-openssl.c:161 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "le fichier de clé privée « %s » ne peut pas être rechargé car il nécessaire une phrase de passe" + +#: libpq/be-secure-openssl.c:166 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "n'a pas pu charger le fichier de clé privée « %s » : %s" + +#: libpq/be-secure-openssl.c:175 +#, c-format +msgid "check of private key failed: %s" +msgstr "échec de la vérification de la clé privée : %s" + +# (errmsg("%s setting %s not supported by this build", +# guc_name, +# GetConfigOption(guc_name, false, false)))); +#. translator: first %s is a GUC option name, second %s is its value +#: libpq/be-secure-openssl.c:188 libpq/be-secure-openssl.c:211 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "le paramètre %s ne supporte pas la valeur %s dans cette installation" + +#: libpq/be-secure-openssl.c:198 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "n'a pas pu mettre en place la version minimum de protocole SSL" + +#: libpq/be-secure-openssl.c:221 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "n'a pas pu mettre en place la version maximum de protocole SSL" + +#: libpq/be-secure-openssl.c:237 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "n'a pas pu configurer l'intervalle de versions pour le protocole SSL" + +#: libpq/be-secure-openssl.c:238 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "« %s » ne peut pas être supérieur à « %s »" + +#: libpq/be-secure-openssl.c:275 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "n'a pas pu configurer la liste des algorithmes de chiffrement (pas d'algorithmes valides disponibles)" + +#: libpq/be-secure-openssl.c:295 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "n'a pas pu charger le fichier du certificat racine « %s » : %s" + +#: libpq/be-secure-openssl.c:344 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "n'a pas pu charger le fichier de liste de révocation des certificats SSL (« %s ») : %s" + +#: libpq/be-secure-openssl.c:352 +#, c-format +msgid "could not load SSL certificate revocation list directory \"%s\": %s" +msgstr "n'a pas pu charger le répertoire de liste de révocation des certificats SSL « %s » : %s" + +#: libpq/be-secure-openssl.c:360 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s" +msgstr "n'a pas pu charger le fichier de liste de révocation des certificats SSL (« %s ») ou répertoire %s : %s" + +#: libpq/be-secure-openssl.c:418 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "n'a pas pu initialiser la connexion SSL : contexte SSL non configuré" + +#: libpq/be-secure-openssl.c:429 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "n'a pas pu initialiser la connexion SSL : %s" + +#: libpq/be-secure-openssl.c:437 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "n'a pas pu créer le socket SSL : %s" + +#: libpq/be-secure-openssl.c:492 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "n'a pas pu accepter la connexion SSL : %m" + +#: libpq/be-secure-openssl.c:496 libpq/be-secure-openssl.c:549 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "n'a pas pu accepter la connexion SSL : fin de fichier détecté" + +#: libpq/be-secure-openssl.c:535 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "n'a pas pu accepter la connexion SSL : %s" + +#: libpq/be-secure-openssl.c:538 +#, c-format +msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." +msgstr "Ceci pourrait indiquer que le client ne supporte pas la version du protocole SSL entre %s et %s." + +#: libpq/be-secure-openssl.c:554 libpq/be-secure-openssl.c:734 libpq/be-secure-openssl.c:798 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "code d'erreur SSL inconnu : %d" + +#: libpq/be-secure-openssl.c:600 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "le nom commun du certificat SSL contient des NULL" + +#: libpq/be-secure-openssl.c:640 +#, c-format +msgid "SSL certificate's distinguished name contains embedded null" +msgstr "le nom distingué du certificat SSL contient des NULL" + +#: libpq/be-secure-openssl.c:723 libpq/be-secure-openssl.c:782 +#, c-format +msgid "SSL error: %s" +msgstr "erreur SSL : %s" + +#: libpq/be-secure-openssl.c:963 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier de paramètres DH « %s » : %m" + +#: libpq/be-secure-openssl.c:975 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "n'a pas pu charger le fichier de paramètres DH : %s" + +#: libpq/be-secure-openssl.c:985 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "paramètres DH invalides : %s" + +#: libpq/be-secure-openssl.c:994 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "paramètres DH invalides : p n'est pas premier" + +#: libpq/be-secure-openssl.c:1003 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "paramètres DH invalides : pas de générateur convenable ou de premier sûr" + +#: libpq/be-secure-openssl.c:1164 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH : n'a pas pu charger les paramètres DH" + +#: libpq/be-secure-openssl.c:1172 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH : n'a pas pu configurer les paramètres DH : %s" + +#: libpq/be-secure-openssl.c:1199 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH : nome de courbe non reconnu : %s" + +#: libpq/be-secure-openssl.c:1208 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH : n'a pas pu créer la clé" + +#: libpq/be-secure-openssl.c:1236 +msgid "no SSL error reported" +msgstr "aucune erreur SSL reportée" + +#: libpq/be-secure-openssl.c:1240 +#, c-format +msgid "SSL error code %lu" +msgstr "erreur SSL de code %lu" + +#: libpq/be-secure-openssl.c:1394 +#, c-format +msgid "failed to create BIO" +msgstr "échec pour la création de BIO" + +#: libpq/be-secure-openssl.c:1404 +#, c-format +msgid "could not get NID for ASN1_OBJECT object" +msgstr "n'a pas pu obtenir un NID pour l'objet ASN1_OBJECT" + +#: libpq/be-secure-openssl.c:1412 +#, c-format +msgid "could not convert NID %d to an ASN1_OBJECT structure" +msgstr "n'a pas pu convertir le NID %d en une structure ASN1_OBJECT" + +#: libpq/be-secure.c:209 libpq/be-secure.c:305 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "arrêt des connexions suite à un arrêt inatendu du postmaster" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "Le rôle « %s » n'existe pas." + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "L'utilisateur « %s » n'a pas de mot de passe affecté." + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "L'utilisateur « %s » a un mot de passe expiré." + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "L'utilisateur « %s » a un mot de passe qui ne peut pas être utilisé avec une authentification MD5." + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "Le mot de passe ne correspond pas pour l'utilisateur %s." + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "Le mot de passe de l'utilisateur « %s » est dans un format non reconnu." + +#: libpq/hba.c:241 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "jeton du fichier d'authentification trop long, ignore : « %s »" + +#: libpq/hba.c:413 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "" +"n'a pas pu ouvrir le fichier d'authentification secondaire « @%s » comme\n" +"« %s » : %m" + +#: libpq/hba.c:859 +#, c-format +msgid "error enumerating network interfaces: %m" +msgstr "erreur lors de l'énumération des interfaces réseau : %m" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:886 +#, c-format +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "l'option d'authentification « %s » n'est valide que pour les méthodes d'authentification « %s »" + +#: libpq/hba.c:888 libpq/hba.c:908 libpq/hba.c:946 libpq/hba.c:996 libpq/hba.c:1010 libpq/hba.c:1034 libpq/hba.c:1043 libpq/hba.c:1056 libpq/hba.c:1077 libpq/hba.c:1090 libpq/hba.c:1110 libpq/hba.c:1132 libpq/hba.c:1144 libpq/hba.c:1203 libpq/hba.c:1223 libpq/hba.c:1237 libpq/hba.c:1257 libpq/hba.c:1268 libpq/hba.c:1283 libpq/hba.c:1302 libpq/hba.c:1318 libpq/hba.c:1330 libpq/hba.c:1367 libpq/hba.c:1408 libpq/hba.c:1421 libpq/hba.c:1443 libpq/hba.c:1455 libpq/hba.c:1473 libpq/hba.c:1523 libpq/hba.c:1567 libpq/hba.c:1578 libpq/hba.c:1594 libpq/hba.c:1611 libpq/hba.c:1622 libpq/hba.c:1641 libpq/hba.c:1657 libpq/hba.c:1673 libpq/hba.c:1727 libpq/hba.c:1744 libpq/hba.c:1757 +#: libpq/hba.c:1769 libpq/hba.c:1788 libpq/hba.c:1875 libpq/hba.c:1893 libpq/hba.c:1987 libpq/hba.c:2006 libpq/hba.c:2035 libpq/hba.c:2048 libpq/hba.c:2071 libpq/hba.c:2093 libpq/hba.c:2107 tsearch/ts_locale.c:232 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "ligne %d du fichier de configuration « %s »" + +#: libpq/hba.c:906 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "la méthode d'authentification « %s » requiert un argument « %s » pour être mise en place" + +#: libpq/hba.c:934 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "entrée manquante dans le fichier « %s » à la fin de la ligne %d" + +#: libpq/hba.c:945 +#, c-format +msgid "multiple values in ident field" +msgstr "plusieurs valeurs dans le champ ident" + +#: libpq/hba.c:994 +#, c-format +msgid "multiple values specified for connection type" +msgstr "plusieurs valeurs indiquées pour le type de connexion" + +#: libpq/hba.c:995 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "Indiquez uniquement un type de connexion par ligne." + +#: libpq/hba.c:1009 +#, c-format +msgid "local connections are not supported by this build" +msgstr "les connexions locales ne sont pas supportées dans cette installation" + +#: libpq/hba.c:1032 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "l'enregistrement hostssl ne peut pas correspondre car SSL est désactivé" + +#: libpq/hba.c:1033 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "Configurez ssl = on dans le postgresql.conf." + +#: libpq/hba.c:1041 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "l'enregistrement hostssl ne peut pas correspondre parce que SSL n'est pas supporté par cette installation" + +#: libpq/hba.c:1042 +#, c-format +msgid "Compile with --with-ssl to use SSL connections." +msgstr "Compilez avec --with-ssl pour utiliser les connexions SSL." + +#: libpq/hba.c:1054 +#, c-format +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "l'enregistrement hostgssenc ne peut pas correspondre parce que GSSAPI n'est pas supporté par cette installation" + +#: libpq/hba.c:1055 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "Compilez avec --with-gssapi pour utiliser les connexions GSSAPI." + +#: libpq/hba.c:1075 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "type de connexion « %s » invalide" + +#: libpq/hba.c:1089 +#, c-format +msgid "end-of-line before database specification" +msgstr "fin de ligne avant la spécification de la base de données" + +#: libpq/hba.c:1109 +#, c-format +msgid "end-of-line before role specification" +msgstr "fin de ligne avant la spécification du rôle" + +#: libpq/hba.c:1131 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "fin de ligne avant la spécification de l'adresse IP" + +#: libpq/hba.c:1142 +#, c-format +msgid "multiple values specified for host address" +msgstr "plusieurs valeurs indiquées pour l'adresse hôte" + +#: libpq/hba.c:1143 +#, c-format +msgid "Specify one address range per line." +msgstr "Indiquez un sous-réseau par ligne." + +#: libpq/hba.c:1201 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "adresse IP « %s » invalide : %s" + +#: libpq/hba.c:1221 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "spécifier le nom d'hôte et le masque CIDR n'est pas valide : « %s »" + +#: libpq/hba.c:1235 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "masque CIDR invalide dans l'adresse « %s »" + +#: libpq/hba.c:1255 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "fin de ligne avant la spécification du masque réseau" + +#: libpq/hba.c:1256 +#, c-format +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "Indiquez un sous-réseau en notation CIDR ou donnez un masque réseau séparé." + +#: libpq/hba.c:1267 +#, c-format +msgid "multiple values specified for netmask" +msgstr "plusieurs valeurs indiquées pour le masque réseau" + +#: libpq/hba.c:1281 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "masque IP « %s » invalide : %s" + +#: libpq/hba.c:1301 +#, c-format +msgid "IP address and mask do not match" +msgstr "l'adresse IP et le masque ne correspondent pas" + +#: libpq/hba.c:1317 +#, c-format +msgid "end-of-line before authentication method" +msgstr "fin de ligne avant la méthode d'authentification" + +#: libpq/hba.c:1328 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "plusieurs valeurs indiquées pour le type d'authentification" + +#: libpq/hba.c:1329 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "Indiquez uniquement un type d'authentification par ligne." + +#: libpq/hba.c:1406 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "méthode d'authentification « %s » invalide" + +#: libpq/hba.c:1419 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "" +"méthode d'authentification « %s » invalide : non supportée sur cette\n" +"installation" + +#: libpq/hba.c:1442 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "" +"l'authentification gssapi n'est pas supportée sur les connexions locales par\n" +"socket" + +#: libpq/hba.c:1454 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "" +"l'authentification peer est seulement supportée sur les connexions locales par\n" +"socket" + +#: libpq/hba.c:1472 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "l'authentification cert est seulement supportée sur les connexions hostssl" + +#: libpq/hba.c:1522 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "l'option d'authentification n'est pas dans le format nom=valeur : %s" + +#: libpq/hba.c:1566 +#, c-format +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ne peut pas utiliser ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchattribute ou ldapurl avec ldapprefix" + +#: libpq/hba.c:1577 +#, c-format +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "la méthode d'authentification « ldap » requiert un argument « ldapbasedn », « ldapprefix » ou « ldapsuffix » pour être mise en place" + +#: libpq/hba.c:1593 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ne peut pas utiliser ldapsearchattribute avec ldapsearchfilter" + +#: libpq/hba.c:1610 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "la liste de serveurs RADIUS ne peut pas être vide" + +#: libpq/hba.c:1621 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "la liste des secrets RADIUS ne peut pas être vide" + +#: libpq/hba.c:1638 +#, fuzzy, c-format +#| msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgid "the number of RADIUS secrets (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "le nombre de %s (%d) doit valoir 1 ou être identique au nombre de %s (%d)" + +#: libpq/hba.c:1654 +#, fuzzy, c-format +#| msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgid "the number of RADIUS ports (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "le nombre de %s (%d) doit valoir 1 ou être identique au nombre de %s (%d)" + +#: libpq/hba.c:1670 +#, fuzzy, c-format +#| msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgid "the number of RADIUS identifiers (%d) must be 1 or the same as the number of RADIUS servers (%d)" +msgstr "le nombre de %s (%d) doit valoir 1 ou être identique au nombre de %s (%d)" + +#: libpq/hba.c:1717 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi et cert" + +#: libpq/hba.c:1726 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert ne peut être configuré que pour les lignes « hostssl »" + +#: libpq/hba.c:1743 +#, c-format +msgid "clientcert only accepts \"verify-full\" when using \"cert\" authentication" +msgstr "clientcert accepte seulement « verify-full » lors de l'utilisation de l'authentification « cert »" + +#: libpq/hba.c:1756 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "valeur invalide pour clientcert : « %s »" + +#: libpq/hba.c:1768 +#, c-format +msgid "clientname can only be configured for \"hostssl\" rows" +msgstr "clientname peut seulement être configuré pour les lignes « hostssl »" + +#: libpq/hba.c:1787 +#, c-format +msgid "invalid value for clientname: \"%s\"" +msgstr "valeur invalide pour clientname : « %s »" + +#: libpq/hba.c:1821 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "n'a pas pu analyser l'URL LDAP « %s » : %s" + +#: libpq/hba.c:1832 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "méthode URL LDAP non supporté : %s" + +#: libpq/hba.c:1856 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "URLs LDAP non supportées sur cette plateforme" + +#: libpq/hba.c:1874 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "valeur ldapscheme invalide : « %s »" + +#: libpq/hba.c:1892 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "numéro de port LDAP invalide : « %s »" + +#: libpq/hba.c:1938 libpq/hba.c:1945 +msgid "gssapi and sspi" +msgstr "gssapi et sspi" + +#: libpq/hba.c:1954 libpq/hba.c:1963 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1985 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "n'a pas pu analyser la liste de serveurs RADIUS « %s »" + +#: libpq/hba.c:2033 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "n'a pas pu analyser la liste de ports RADIUS « %s »" + +#: libpq/hba.c:2047 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "numéro de port RADIUS invalide : « %s »" + +#: libpq/hba.c:2069 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "n'a pas pu analyser la liste de secrets RADIUS « %s »" + +#: libpq/hba.c:2091 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "n'a pas pu analyser la liste des identifieurs RADIUS « %s »" + +#: libpq/hba.c:2105 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "nom d'option de l'authentification inconnu : « %s »" + +#: libpq/hba.c:2302 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "le fichier de configuration « %s » ne contient aucun enregistrement" + +#: libpq/hba.c:2820 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "expression rationnelle invalide « %s » : %s" + +#: libpq/hba.c:2880 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "la correspondance de l'expression rationnelle pour « %s » a échoué : %s" + +#: libpq/hba.c:2899 +#, c-format +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "" +"l'expression rationnelle « %s » n'a pas de sous-expressions comme celle\n" +"demandée par la référence dans « %s »" + +#: libpq/hba.c:2995 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "" +"le nom d'utilisateur (%s) et le nom d'utilisateur authentifié (%s) fournis ne\n" +"correspondent pas" + +#: libpq/hba.c:3015 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "" +"pas de correspondance dans la usermap « %s » pour l'utilisateur « %s »\n" +"authentifié en tant que « %s »" + +#: libpq/hba.c:3048 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier usermap « %s » : %m" + +#: libpq/pqcomm.c:204 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "n'a pas pu activer le mode non-bloquant pour la socket : %m" + +#: libpq/pqcomm.c:362 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "Le chemin du socket de domaine Unix, « %s », est trop (maximum %d octets)" + +#: libpq/pqcomm.c:383 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "n'a pas pu résoudre le nom de l'hôte « %s », service « %s » par l'adresse : %s" + +#: libpq/pqcomm.c:387 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "n'a pas pu résoudre le service « %s » par l'adresse : %s" + +#: libpq/pqcomm.c:414 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "n'a pas pu se lier à toutes les adresses requises : MAXLISTEN (%d) dépassé" + +#: libpq/pqcomm.c:423 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:427 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:432 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:437 +#, c-format +msgid "unrecognized address family %d" +msgstr "famille d'adresse %d non reconnue" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:463 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "n'a pas pu créer le socket %s pour l'adresse « %s » : %m" + +#. translator: third %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:489 libpq/pqcomm.c:507 +#, c-format +msgid "%s(%s) failed for %s address \"%s\": %m" +msgstr "%s(%s) a échoué pour %s, adresse « %s » : %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:530 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "n'a pas pu lier %s à l'adresse « %s » : %m" + +#: libpq/pqcomm.c:534 +#, c-format +msgid "Is another postmaster already running on port %d?" +msgstr "Un autre postmaster fonctionne-t'il déjà sur le port %d ?" + +#: libpq/pqcomm.c:536 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "" +"Un autre postmaster fonctionne-t'il déjà sur le port %d ?\n" +"Sinon, attendez quelques secondes et réessayez." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:569 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "n'a pas pu écouter sur « %s », adresse « %s » : %m" + +#: libpq/pqcomm.c:578 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "écoute sur la socket Unix « %s »" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:584 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "en écoute sur %s, adresse « %s », port %d" + +#: libpq/pqcomm.c:675 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "le groupe « %s » n'existe pas" + +#: libpq/pqcomm.c:685 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "n'a pas pu initialiser le groupe du fichier « %s » : %m" + +#: libpq/pqcomm.c:696 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "n'a pas pu initialiser les droits du fichier « %s » : %m" + +#: libpq/pqcomm.c:726 +#, c-format +msgid "could not accept new connection: %m" +msgstr "n'a pas pu accepter la nouvelle connexion : %m" + +#: libpq/pqcomm.c:766 libpq/pqcomm.c:775 libpq/pqcomm.c:807 libpq/pqcomm.c:817 libpq/pqcomm.c:1630 libpq/pqcomm.c:1675 libpq/pqcomm.c:1715 libpq/pqcomm.c:1759 libpq/pqcomm.c:1798 libpq/pqcomm.c:1837 libpq/pqcomm.c:1873 libpq/pqcomm.c:1912 postmaster/pgstat.c:618 postmaster/pgstat.c:629 +#, c-format +msgid "%s(%s) failed: %m" +msgstr "échec de %s(%s) : %m" + +#: libpq/pqcomm.c:921 +#, c-format +msgid "there is no client connection" +msgstr "il n'y a pas de connexion client" + +#: libpq/pqcomm.c:972 libpq/pqcomm.c:1068 +#, c-format +msgid "could not receive data from client: %m" +msgstr "n'a pas pu recevoir les données du client : %m" + +#: libpq/pqcomm.c:1161 tcop/postgres.c:4290 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "arrêt de la connexion à cause d'une perte de synchronisation du protocole" + +#: libpq/pqcomm.c:1227 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "fin de fichier (EOF) inattendue à l'intérieur de la longueur du message" + +#: libpq/pqcomm.c:1237 +#, c-format +msgid "invalid message length" +msgstr "longueur du message invalide" + +#: libpq/pqcomm.c:1259 libpq/pqcomm.c:1272 +#, c-format +msgid "incomplete message from client" +msgstr "message incomplet du client" + +#: libpq/pqcomm.c:1383 +#, c-format +msgid "could not send data to client: %m" +msgstr "n'a pas pu envoyer les données au client : %m" + +#: libpq/pqcomm.c:1598 +#, c-format +msgid "%s(%s) failed: error code %d" +msgstr "échec de %s(%s) : code d'erreur %d" + +# /* +# * Check for old recovery API file: recovery.conf +# */ +#: libpq/pqcomm.c:1687 +#, c-format +msgid "setting the keepalive idle time is not supported" +msgstr "configurer le temps d'attente du keepalive n'est pas supporté" + +#: libpq/pqcomm.c:1771 libpq/pqcomm.c:1846 libpq/pqcomm.c:1921 +#, c-format +msgid "%s(%s) not supported" +msgstr "%s(%s) non supporté" + +#: libpq/pqcomm.c:1956 +#, c-format +msgid "could not poll socket: %m" +msgstr "n'a pas pu interroger la socket : %m" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "pas de données dans le message" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 utils/adt/arrayfuncs.c:1481 utils/adt/rowtypes.c:588 +#, c-format +msgid "insufficient data left in message" +msgstr "données insuffisantes laissées dans le message" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "chaîne invalide dans le message" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "format du message invalide" + +#: main/main.c:245 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s : WSAStartup a échoué : %d\n" + +#: main/main.c:309 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%s est le serveur PostgreSQL.\n" +"\n" + +#: main/main.c:310 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Usage :\n" +" %s [OPTION]...\n" +"\n" + +#: main/main.c:311 +#, c-format +msgid "Options:\n" +msgstr "Options :\n" + +#: main/main.c:312 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS nombre de tampons partagés (shared buffers)\n" + +#: main/main.c:313 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NOM=VALEUR configure un paramètre d'exécution\n" + +#: main/main.c:314 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr "" +" -C NOM affiche la valeur d'un paramètre en exécution,\n" +" puis quitte\n" + +#: main/main.c:315 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 niveau de débogage\n" + +#: main/main.c:316 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D RÉPDONNEES répertoire de la base de données\n" + +#: main/main.c:317 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e utilise le format européen de saisie des dates (DMY)\n" + +#: main/main.c:318 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F désactive fsync\n" + +#: main/main.c:319 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h NOMHÔTE nom d'hôte ou adresse IP à écouter\n" + +#: main/main.c:320 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i active les connexions TCP/IP\n" + +#: main/main.c:321 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k RÉPERTOIRE emplacement des sockets de domaine Unix\n" + +#: main/main.c:323 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l active les connexions SSL\n" + +#: main/main.c:325 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-CONNECT nombre maximum de connexions simultanées\n" + +#: main/main.c:326 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT numéro du port à écouter\n" + +#: main/main.c:327 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s affiche les statistiques après chaque requête\n" + +#: main/main.c:328 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM configure la mémoire pour les tris (en ko)\n" + +#: main/main.c:329 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version et quitte\n" + +#: main/main.c:330 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NOM=VALEUR configure un paramètre d'exécution\n" + +#: main/main.c:331 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config décrit les paramètres de configuration, puis quitte\n" + +#: main/main.c:332 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide et quitte\n" + +#: main/main.c:334 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"Options pour le développeur :\n" + +#: main/main.c:335 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h interdit l'utilisation de certains types de plan\n" + +#: main/main.c:336 +#, c-format +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr "" +" -n ne réinitialise pas la mémoire partagée après un arrêt\n" +" brutal\n" + +#: main/main.c:337 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr "" +" -O autorise les modifications de structure des tables\n" +" système\n" + +#: main/main.c:338 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P désactive les index systèmes\n" + +#: main/main.c:339 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex affiche les horodatages pour chaque requête\n" + +#: main/main.c:340 +#, c-format +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr "" +" -T envoie SIGSTOP à tous les processus serveur si l'un\n" +" d'entre eux meurt\n" + +#: main/main.c:341 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr "" +" -W NUM attends NUM secondes pour permettre l'attache d'un\n" +" débogueur\n" + +#: main/main.c:343 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"Options pour le mode mono-utilisateur :\n" + +#: main/main.c:344 +#, c-format +msgid " --single selects single-user mode (must be first argument)\n" +msgstr "" +" --single sélectionne le mode mono-utilisateur (doit être le\n" +" premier argument)\n" + +#: main/main.c:345 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " NOMBASE nom de la base (par défaut, le même que l'utilisateur)\n" + +#: main/main.c:346 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 surcharge le niveau de débogage\n" + +#: main/main.c:347 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E affiche la requête avant de l'exécuter\n" + +#: main/main.c:348 +#, c-format +msgid " -j do not use newline as interactive query delimiter\n" +msgstr "" +" -j n'utilise pas le retour à la ligne comme délimiteur de\n" +" requête\n" + +#: main/main.c:349 main/main.c:354 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r FICHIER envoie stdout et stderr dans le fichier indiqué\n" + +#: main/main.c:351 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"Options pour le mode « bootstrapping » :\n" + +#: main/main.c:352 +#, c-format +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr "" +" --boot sélectionne le mode « bootstrapping » (doit être le\n" +" premier argument)\n" + +#: main/main.c:353 +#, c-format +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr "" +" NOMBASE nom de la base (argument obligatoire dans le mode\n" +" « bootstrapping »)\n" + +#: main/main.c:355 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM utilisation interne\n" + +#: main/main.c:357 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Merci de lire la documentation pour la liste complète des paramètres\n" +"de configuration et pour savoir comment les configurer sur la\n" +"ligne de commande ou dans le fichier de configuration.\n" +"\n" +"Rapportez les bogues à <%s>.\n" + +#: main/main.c:361 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil de %s : <%s>\n" + +#: main/main.c:372 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"L'exécution du serveur PostgreSQL par l'utilisateur « root » n'est pas autorisée.\n" +"Le serveur doit être lancé avec un utilisateur non privilégié pour empêcher\n" +"tout problème possible de sécurité sur le serveur. Voir la documentation pour\n" +"plus d'informations sur le lancement propre du serveur.\n" + +#: main/main.c:389 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s : les identifiants réel et effectif de l'utilisateur doivent correspondre\n" + +#: main/main.c:396 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"L'exécution du serveur PostgreSQL par un utilisateur doté de droits d'administrateur n'est pas permise.\n" +"Le serveur doit être lancé avec un utilisateur non privilégié pour empêcher\n" +"tout problème de sécurité sur le serveur. Voir la documentation pour\n" +"plus d'informations sur le lancement propre du serveur.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "le type de nœud extensible « %s » existe déjà" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "ExtensibleNodeMethods \"%s\" n'a pas été enregistré" + +#: nodes/makefuncs.c:150 +#, c-format +msgid "relation \"%s\" does not have a composite type" +msgstr "la relation « %s » n'a pas un type composite" + +#: nodes/nodeFuncs.c:114 nodes/nodeFuncs.c:145 parser/parse_coerce.c:2472 parser/parse_coerce.c:2584 parser/parse_coerce.c:2630 parser/parse_expr.c:2021 parser/parse_func.c:710 parser/parse_oper.c:883 utils/fmgr/funcapi.c:558 +#, c-format +msgid "could not find array type for data type %s" +msgstr "n'a pas pu trouver de type tableau pour le type de données %s" + +#: nodes/params.c:417 +#, c-format +msgid "portal \"%s\" with parameters: %s" +msgstr "portail « %s » avec les paramètres : %s" + +#: nodes/params.c:420 +#, c-format +msgid "unnamed portal with parameters: %s" +msgstr "portail non nommé avec les paramètres : « %s »" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "" +"FULL JOIN est supporté seulement avec les conditions de jointures MERGE et de\n" +"jointures HASH JOIN" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1192 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s ne peut être appliqué sur le côté possiblement NULL d'une jointure externe" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1315 parser/analyze.c:1677 parser/analyze.c:1921 parser/analyze.c:3099 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s n'est pas autorisé avec UNION/INTERSECT/EXCEPT" + +#: optimizer/plan/planner.c:1978 optimizer/plan/planner.c:3634 +#, c-format +msgid "could not implement GROUP BY" +msgstr "n'a pas pu implanter GROUP BY" + +#: optimizer/plan/planner.c:1979 optimizer/plan/planner.c:3635 optimizer/plan/planner.c:4392 optimizer/prep/prepunion.c:1046 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "" +"Certains des types de données supportent seulement le hachage,\n" +"alors que les autres supportent seulement le tri." + +#: optimizer/plan/planner.c:4391 +#, c-format +msgid "could not implement DISTINCT" +msgstr "n'a pas pu implanter DISTINCT" + +#: optimizer/plan/planner.c:5239 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "n'a pas pu implanter PARTITION BY de window" + +#: optimizer/plan/planner.c:5240 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "" +"Les colonnes de partitionnement de window doivent être d'un type de données\n" +"triables." + +#: optimizer/plan/planner.c:5244 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "n'a pas pu implanter ORDER BY dans le window" + +#: optimizer/plan/planner.c:5245 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Les colonnes de tri de la window doivent être d'un type de données triable." + +#: optimizer/plan/setrefs.c:479 +#, c-format +msgid "too many range table entries" +msgstr "trop d'enregistrements dans la table range" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "could not implement recursive UNION" +msgstr "n'a pas pu implanter le UNION récursif" + +#: optimizer/prep/prepunion.c:510 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Tous les types de données des colonnes doivent être hachables." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1045 +#, c-format +msgid "could not implement %s" +msgstr "n'a pas pu implanter %s" + +#: optimizer/util/clauses.c:4721 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "fonction SQL « %s » durant « inlining »" + +#: optimizer/util/plancat.c:132 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "ne peut pas accéder à des tables temporaires et non tracées lors de la restauration" + +#: optimizer/util/plancat.c:672 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "les spécifications d'inférence d'index unique pour une ligne entière ne sont pas supportées" + +#: optimizer/util/plancat.c:689 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "la contrainte de la clause ON CONFLICT n'a pas d'index associé" + +#: optimizer/util/plancat.c:739 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE non supporté avec les contraintes d'exclusion" + +#: optimizer/util/plancat.c:844 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "il n'existe aucune contrainte unique ou contrainte d'exclusion correspondant à la spécification ON CONFLICT" + +#: parser/analyze.c:737 parser/analyze.c:1451 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "les listes VALUES doivent être toutes de la même longueur" + +#: parser/analyze.c:938 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT a plus d'expressions que les colonnes cibles" + +#: parser/analyze.c:956 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT a plus de colonnes cibles que d'expressions" + +#: parser/analyze.c:960 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "" +"La source d'insertion est une expression de ligne contenant le même nombre\n" +"de colonnes que celui attendu par INSERT. Auriez-vous utilisé des parenthèses\n" +"supplémentaires ?" + +#: parser/analyze.c:1259 parser/analyze.c:1650 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO n'est pas autorisé ici" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1580 parser/analyze.c:3278 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s ne peut pas être appliqué à VALUES" + +#: parser/analyze.c:1816 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "clause UNION/INTERSECT/EXCEPT ORDER BY invalide" + +#: parser/analyze.c:1817 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "" +"Seuls les noms de colonnes résultats peuvent être utilisés, pas les\n" +"expressions et les fonctions." + +#: parser/analyze.c:1818 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "Ajouter l'expression/fonction à chaque SELECT, ou déplacer l'UNION dans une clause FROM." + +#: parser/analyze.c:1911 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO est autorisé uniquement sur le premier SELECT d'un UNION/INTERSECT/EXCEPT" + +#: parser/analyze.c:1983 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "" +"L'instruction membre UNION/INTERSECT/EXCEPT ne peut pas faire référence à\n" +"d'autres relations que celles de la requête de même niveau" + +#: parser/analyze.c:2070 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "chaque requête %s doit avoir le même nombre de colonnes" + +#: parser/analyze.c:2470 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNING doit avoir au moins une colonne" + +#: parser/analyze.c:2573 +#, c-format +msgid "assignment source returned %d column" +msgid_plural "assignment source returned %d columns" +msgstr[0] "la source d'affectation a renvoyé %d colonne" +msgstr[1] "la source d'affectation a renvoyé %d colonnes" + +#: parser/analyze.c:2634 +#, c-format +msgid "variable \"%s\" is of type %s but expression is of type %s" +msgstr "la variable « %s » est de type %s mais l'expression est de type %s" + +#. translator: %s is a SQL keyword +#: parser/analyze.c:2758 parser/analyze.c:2766 +#, c-format +msgid "cannot specify both %s and %s" +msgstr "ne peut pas spécifier à la fois %s et %s" + +#: parser/analyze.c:2786 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR ne doit pas contenir des instructions de modification de données dans WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2794 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s n'est pas supporté" + +#: parser/analyze.c:2797 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "Les curseurs détenables doivent être en lecture seule (READ ONLY)." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2805 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s n'est pas supporté" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2816 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not valid" +msgstr "DECLARE INSENSITIVE CURSOR ... %s n'est pas valide" + +#: parser/analyze.c:2819 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Les curseurs insensibles doivent être en lecture seule (READ ONLY)." + +#: parser/analyze.c:2885 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "les vues matérialisées ne peuvent pas contenir d'instructions de modifications de données avec WITH" + +#: parser/analyze.c:2895 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "les vues matérialisées ne doivent pas utiliser de tables temporaires ou de vues" + +#: parser/analyze.c:2905 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "les vues matérialisées ne peuvent pas être définies en utilisant des paramètres liés" + +#: parser/analyze.c:2917 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "les vues matérialisées ne peuvent pas être non journalisées (UNLOGGED)" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3106 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s n'est pas autorisé avec la clause DISTINCT" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3113 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s n'est pas autorisé avec la clause GROUP BY" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3120 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s n'est pas autorisé avec la clause HAVING" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3127 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s n'est pas autorisé avec les fonctions d'agrégat" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3134 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s n'est pas autorisé avec les fonctions de fenêtrage" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3141 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s n'est pas autorisé avec les fonctions renvoyant plusieurs lignes dans la liste cible" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3220 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%s doit indiquer les noms de relation non qualifiés" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3251 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s ne peut pas être appliqué à une jointure" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3260 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s ne peut pas être appliqué à une fonction" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3269 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s ne peut pas être appliqué à une fonction de table" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3287 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s ne peut pas être appliqué à une requête WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3296 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s ne peut pas être appliqué à une tuplestore nommé" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:3316 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "relation « %s » dans une clause %s introuvable dans la clause FROM" + +#: parser/parse_agg.c:220 parser/parse_oper.c:227 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "n'a pas pu identifier un opérateur de tri pour le type %s" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "Les agrégats avec DISTINCT doivent être capables de trier leur entrée." + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING doit avoir moins de 32 arguments" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les conditions de jointures" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les conditions de jointure" + +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans la clause FROM de leur propre niveau de requête" + +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "les fonctions de regroupement ne sont pas autorisés dans la clause FROM du même niveau de la requête" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les fonctions dans une clause FROM" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les fonctions contenues dans la clause FROM" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les expressions de politique" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les expressions de politique" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans le RANGE d'un fenêtrage" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "les fonctions de regroupement ne sont pas autorisés dans le RANGE de fenêtrage" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans le ROWS d'un fenêtrage" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "les fonctions de regroupement ne sont pas autorisés dans le ROWS de fenêtrage" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans le GROUPS d'un fenêtrage" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "les fonctions de regroupement ne sont pas autorisés dans le GROUPS de fenêtrage" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les contraintes CHECK" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les contraintes CHECK" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les expressions par défaut" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les expressions par défaut" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les expressions d'index" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les expressions d'index" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les prédicats d'index" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les prédicats d'index" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in statistics expressions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les expressions statistiques" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in statistics expressions" +msgstr "les fonctions de regroupement ne sont pas autorisées dans les expressions statistiques" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les expressions de transformation" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in transform expressions" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les expressions de transformation" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les paramètres d'EXECUTE" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les paramètres d'EXECUTE" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les conditions WHEN des triggers" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les conditions WHEN des triggers" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition bound" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les limites de partition" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition bound" +msgstr "les opérations de regroupement ne sont pas autorisées dans les limites de partition" + +#: parser/parse_agg.c:525 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les expressions de clé de partitionnement" + +#: parser/parse_agg.c:527 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "les opérations de regroupement ne sont pas autorisées dans les expressions de clé de partitionnement" + +#: parser/parse_agg.c:533 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les expressions de génération de colonne" + +#: parser/parse_agg.c:535 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "les fonctions de regroupement ne sont pas autorisées dans les expressions de génération de colonne" + +#: parser/parse_agg.c:541 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les arguments de CALL" + +#: parser/parse_agg.c:543 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les arguments de CALL" + +#: parser/parse_agg.c:549 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans les conditions de COPY FROM WHERE" + +#: parser/parse_agg.c:551 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "les fonctions de regroupement ne sont pas autorisées dans les conditions WHERE d'un COPY FROM" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:578 parser/parse_clause.c:1846 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans %s" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:581 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "les fonctions de regroupement ne sont pas autorisés dans %s" + +#: parser/parse_agg.c:689 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "un aggrégat de niveau externe ne peut pas contenir de variable de niveau inférieur dans ses arguments directs" + +#: parser/parse_agg.c:768 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "les appels à la fonction d'agrégat ne peuvent pas contenir des appels à des fonctions retournant des ensembles" + +#: parser/parse_agg.c:769 parser/parse_expr.c:1673 parser/parse_expr.c:2146 parser/parse_func.c:883 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Vous devriez être capable de déplacer la fonction SETOF dans un élément LATERAL FROM." + +#: parser/parse_agg.c:774 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "les appels à la fonction d'agrégat ne peuvent pas contenir des appels à une fonction de fenêtrage" + +#: parser/parse_agg.c:853 +msgid "window functions are not allowed in JOIN conditions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les conditions de jointure" + +#: parser/parse_agg.c:860 +msgid "window functions are not allowed in functions in FROM" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les fonctions contenues dans la clause FROM" + +#: parser/parse_agg.c:866 +msgid "window functions are not allowed in policy expressions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions de politique" + +#: parser/parse_agg.c:879 +msgid "window functions are not allowed in window definitions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les définitions de fenêtres" + +#: parser/parse_agg.c:911 +msgid "window functions are not allowed in check constraints" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les contraintes CHECK" + +#: parser/parse_agg.c:915 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions par défaut" + +#: parser/parse_agg.c:918 +msgid "window functions are not allowed in index expressions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions d'index" + +#: parser/parse_agg.c:921 +msgid "window functions are not allowed in statistics expressions" +msgstr "les fonctions de fenêtrage ne sont pas autorisées dans les expressions statistiques" + +#: parser/parse_agg.c:924 +msgid "window functions are not allowed in index predicates" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les prédicats d'index" + +#: parser/parse_agg.c:927 +msgid "window functions are not allowed in transform expressions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions de transformation" + +#: parser/parse_agg.c:930 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les paramètres d'EXECUTE" + +#: parser/parse_agg.c:933 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les conditions WHEN des triggers" + +#: parser/parse_agg.c:936 +msgid "window functions are not allowed in partition bound" +msgstr "les fonctions de fenêtrage ne sont pas autorisées dans les limites de partition" + +#: parser/parse_agg.c:939 +msgid "window functions are not allowed in partition key expressions" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions de clé de partitionnement" + +#: parser/parse_agg.c:942 +msgid "window functions are not allowed in CALL arguments" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les arguments de CALL" + +#: parser/parse_agg.c:945 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "les fonctions de fenêtrage ne sont pas autorisées dans les conditions WHERE d'un COPY FROM" + +#: parser/parse_agg.c:948 +msgid "window functions are not allowed in column generation expressions" +msgstr "les fonctions de fenêtrage ne sont pas autorisées dans les expressions de génération de colonne" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:971 parser/parse_clause.c:1855 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans %s" + +#: parser/parse_agg.c:1005 parser/parse_clause.c:2689 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "le window « %s » n'existe pas" + +#: parser/parse_agg.c:1089 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "trop d'ensembles de regroupement présents (4096 maximum)" + +#: parser/parse_agg.c:1229 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "les fonctions d'agrégat ne sont pas autorisées dans le terme récursif d'une requête récursive" + +#: parser/parse_agg.c:1422 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "la colonne « %s.%s » doit apparaître dans la clause GROUP BY ou doit être utilisé dans une fonction d'agrégat" + +#: parser/parse_agg.c:1425 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "Les arguments directs d'un agégat par ensemble ordonné doivent seulement utiliser des colonnes groupées." + +#: parser/parse_agg.c:1430 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "" +"la sous-requête utilise une colonne « %s.%s » non groupée dans la requête\n" +"externe" + +#: parser/parse_agg.c:1594 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "les arguments de la clause GROUPING doivent être des expressions de regroupement du niveau associé de la requête" + +#: parser/parse_clause.c:190 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "la relation « %s » ne peut pas être la cible d'une instruction modifiée" + +#: parser/parse_clause.c:570 parser/parse_clause.c:598 parser/parse_func.c:2554 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "les fonctions renvoyant des ensembles doivent apparaître au niveau haut d'un FROM" + +#: parser/parse_clause.c:610 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "plusieurs listes de définition de colonnes ne sont pas autorisées pour la même fonction" + +#: parser/parse_clause.c:643 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "ROWS FROM() avec plusieurs fonctions ne peut pas avoir une liste de définitions de colonnes" + +#: parser/parse_clause.c:644 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "Placer une liste de définitions de colonnes séparée pour chaque fonction à l'intérieur de ROWS FROM()." + +#: parser/parse_clause.c:650 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "UNNEST() avec plusieurs arguments ne peut pas avoir de liste de définition de colonnes" + +#: parser/parse_clause.c:651 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "Utiliser des appels séparés UNNEST() à l'intérieur de ROWS FROM(), et attacher une liste de définition des colonnes pour chaque." + +#: parser/parse_clause.c:658 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY ne peut pas être utilisé avec une liste de définitions de colonnes" + +#: parser/parse_clause.c:659 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Placez la liste de définitions des colonnes dans ROWS FROM()." + +#: parser/parse_clause.c:759 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "seule une colonne FOR ORDINALITY est autorisée" + +#: parser/parse_clause.c:820 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "le nom de colonne « %s » n'est pas unique" + +#: parser/parse_clause.c:862 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "l'espace de nom « %s » n'est pas unique" + +#: parser/parse_clause.c:872 +#, c-format +msgid "only one default namespace is allowed" +msgstr "seul un espace de nom par défaut est autorisé" + +#: parser/parse_clause.c:932 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "la méthode d'échantillonage %s n'existe pas" + +#: parser/parse_clause.c:954 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "la méthode d'échantillonage %s requiert %d argument, et non pas %d" +msgstr[1] "la méthode d'échantillonage %s requiert %d arguments, et non pas %d" + +#: parser/parse_clause.c:988 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "la méthode d'échantillonage %s ne supporte pas REPEATABLE" + +#: parser/parse_clause.c:1134 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "la clause TABLESAMPLE n'est applicable qu'aux tables et vues matérialisées" + +#: parser/parse_clause.c:1324 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "le nom de la colonne « %s » apparaît plus d'une fois dans la clause USING" + +#: parser/parse_clause.c:1339 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "" +"le nom commun de la colonne « %s » apparaît plus d'une fois dans la table de\n" +"gauche" + +#: parser/parse_clause.c:1348 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "" +"la colonne « %s » spécifiée dans la clause USING n'existe pas dans la table\n" +"de gauche" + +#: parser/parse_clause.c:1363 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "" +"le nom commun de la colonne « %s » apparaît plus d'une fois dans la table de\n" +" droite" + +#: parser/parse_clause.c:1372 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "" +"la colonne « %s » spécifiée dans la clause USING n'existe pas dans la table\n" +"de droite" + +#: parser/parse_clause.c:1451 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "la liste d'alias de colonnes pour « %s » a beaucoup trop d'entrées" + +#: parser/parse_clause.c:1791 +#, c-format +msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" +msgstr "un nombre de lignes ne peut pas être NULL dans une clause FETCH FIRST ... WITH TIES" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1816 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "l'argument de « %s » ne doit pas contenir de variables" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1981 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s « %s » est ambigu" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2010 +#, c-format +msgid "non-integer constant in %s" +msgstr "constante non entière dans %s" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2032 +#, c-format +msgid "%s position %d is not in select list" +msgstr "%s, à la position %d, n'est pas dans la liste SELECT" + +#: parser/parse_clause.c:2471 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE est limité à 12 éléments" + +#: parser/parse_clause.c:2677 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "le window « %s » est déjà définie" + +#: parser/parse_clause.c:2738 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "n'a pas pu surcharger la clause PARTITION BY de window « %s »" + +#: parser/parse_clause.c:2750 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "n'a pas pu surcharger la clause ORDER BY de window « %s »" + +#: parser/parse_clause.c:2780 parser/parse_clause.c:2786 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "ne peut pas copier la fenêtre « %s » car il dispose d'une clause de portée" + +#: parser/parse_clause.c:2788 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Omettre les parenthèses dans cette clause OVER." + +#: parser/parse_clause.c:2808 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE avec offset PRECEDING/FOLLOWING nécessite exactement une colonne ORDER BY" + +#: parser/parse_clause.c:2831 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "le mode GROUPS nécessite une clause ORDER BY" + +#: parser/parse_clause.c:2901 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "" +"dans un agrégat avec DISTINCT, les expressions ORDER BY doivent apparaître\n" +"dans la liste d'argument" + +#: parser/parse_clause.c:2902 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "" +"pour SELECT DISTINCT, ORDER BY, les expressions doivent apparaître dans la\n" +"liste SELECT" + +#: parser/parse_clause.c:2934 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "un agrégat avec DISTINCT doit avoir au moins un argument" + +#: parser/parse_clause.c:2935 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT doit avoir au moins une colonne" + +#: parser/parse_clause.c:3001 parser/parse_clause.c:3033 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "les expressions SELECT DISTINCT ON doivent correspondre aux expressions ORDER BY initiales" + +#: parser/parse_clause.c:3111 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC n'est pas autorisé avec la clause ON CONFLICT" + +#: parser/parse_clause.c:3117 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST n'est pas autorisé avec la clause ON CONFLICT" + +#: parser/parse_clause.c:3196 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE requiert une spécification d'inférence ou un nom de contrainte" + +#: parser/parse_clause.c:3197 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Par exemple, ON CONFLICT (nom_colonne)" + +#: parser/parse_clause.c:3208 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT n'est pas supporté avec les catalogues systèmes" + +#: parser/parse_clause.c:3216 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT n'est pas supporté sur la table « %s » utilisée comme une table catalogue" + +#: parser/parse_clause.c:3346 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "l'opérateur %s n'est pas un opérateur de tri valide" + +#: parser/parse_clause.c:3348 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "" +"Les opérateurs de tri doivent être les membres « < » ou « > » des familles\n" +"d'opérateurs btree." + +#: parser/parse_clause.c:3659 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE avec offset PRECEDING/FOLLOWING n'est pas supporté pour le type de collone %s" + +#: parser/parse_clause.c:3665 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE avec offset PRECEDING/FOLLOWING n'est pas supporté pour le type de colonne %s et le type d'ossfet %s" + +#: parser/parse_clause.c:3668 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Transtypez la valeur d'offset vers un type approprié." + +#: parser/parse_clause.c:3673 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE avec offset PRECEDING/FOLLOWING a de multiples interprétations pour le type de colonne %s et le type d'offset %s" + +#: parser/parse_clause.c:3676 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Transtypez la valeur d'offset vers exactement le type attendu." + +#: parser/parse_coerce.c:1034 parser/parse_coerce.c:1072 parser/parse_coerce.c:1090 parser/parse_coerce.c:1105 parser/parse_expr.c:2055 parser/parse_expr.c:2649 parser/parse_target.c:995 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "ne peut pas convertir le type %s en %s" + +#: parser/parse_coerce.c:1075 +#, c-format +msgid "Input has too few columns." +msgstr "L'entrée n'a pas assez de colonnes." + +#: parser/parse_coerce.c:1093 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "Ne peut pas convertir le type %s en %s dans la colonne %d." + +#: parser/parse_coerce.c:1108 +#, c-format +msgid "Input has too many columns." +msgstr "L'entrée a trop de colonnes." + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1163 parser/parse_coerce.c:1211 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "l'argument de %s doit être de type %s, et non du type %s" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1174 parser/parse_coerce.c:1223 +#, c-format +msgid "argument of %s must not return a set" +msgstr "l'argument de %s ne doit pas renvoyer un ensemble" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1363 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "les %s types %s et %s ne peuvent pas correspondre" + +#: parser/parse_coerce.c:1475 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "les types d'argument %s et %s ne se correspondent pas" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1527 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%s n'a pas pu convertir le type %s en %s" + +#: parser/parse_coerce.c:2089 parser/parse_coerce.c:2109 parser/parse_coerce.c:2129 parser/parse_coerce.c:2149 parser/parse_coerce.c:2204 parser/parse_coerce.c:2237 +#, c-format +msgid "arguments declared \"%s\" are not all alike" +msgstr "les arguments déclarés « %s » ne sont pas tous identiques" + +#: parser/parse_coerce.c:2183 parser/parse_coerce.c:2297 utils/fmgr/funcapi.c:489 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "l'argument déclaré %s n'est pas un tableau mais est du type %s" + +#: parser/parse_coerce.c:2216 parser/parse_coerce.c:2329 utils/fmgr/funcapi.c:503 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "l'argument déclaré %s n'est pas un type d'intervalle mais est du type %s" + +#: parser/parse_coerce.c:2250 parser/parse_coerce.c:2363 utils/fmgr/funcapi.c:521 utils/fmgr/funcapi.c:586 +#, c-format +msgid "argument declared %s is not a multirange type but type %s" +msgstr "l'argument déclaré %s n'est pas un type multirange mais est du type %s" + +#: parser/parse_coerce.c:2288 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "ne peut pas déterminer le type d'élément d'un argument « anyarray »" + +#: parser/parse_coerce.c:2314 parser/parse_coerce.c:2346 parser/parse_coerce.c:2380 parser/parse_coerce.c:2400 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "l'argument déclaré %s n'est pas cohérent avec l'argument déclaré %s" + +#: parser/parse_coerce.c:2427 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "" +"n'a pas pu déterminer le type polymorphique car l'entrée dispose\n" +"du type %s" + +#: parser/parse_coerce.c:2441 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "le type déclaré anynonarray est un type tableau : %s" + +#: parser/parse_coerce.c:2451 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "le type déclaré anyenum n'est pas un type enum : %s" + +#: parser/parse_coerce.c:2482 parser/parse_coerce.c:2532 parser/parse_coerce.c:2596 parser/parse_coerce.c:2643 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "n'a pas pu déterminer le type polymorphique %s car l'entrée dispose du type %s" + +#: parser/parse_coerce.c:2492 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "le type anycompatiblerange %s ne correspond pas au type anycompatible %s." + +#: parser/parse_coerce.c:2506 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "le type correspondant à anycompatiblenonarray est un type tableau : %s" + +#: parser/parse_coerce.c:2607 parser/parse_coerce.c:2658 utils/fmgr/funcapi.c:614 +#, c-format +msgid "could not find multirange type for data type %s" +msgstr "n'a pas pu trouver le type multirange pour le type de données %s" + +#: parser/parse_coerce.c:2739 +#, c-format +msgid "A result of type %s requires at least one input of type anyrange or anymultirange." +msgstr "Un résultat de type %s nécessite au moins une entrée de type anyrange ou anymultirange." + +#: parser/parse_coerce.c:2756 +#, c-format +msgid "A result of type %s requires at least one input of type anycompatiblerange or anycompatiblemultirange." +msgstr "Un résultat de type %s requiert au moins une entrée de type anycompatiblerange ou anycompatiblemultirange." + +#: parser/parse_coerce.c:2768 +#, c-format +msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, anyrange, or anymultirange." +msgstr "Un résultat de type %s requiert au moins une entrée de type anyelement, anyarray, anynonarray, anyenum, anyrange ou anymultirange." + +#: parser/parse_coerce.c:2780 +#, c-format +msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "Un résultat de type %s requiert au moins une entrée de type anycompatible, anycompatiblearray, anycompatiblenonarray ou anycompatiblerange." + +#: parser/parse_coerce.c:2810 +msgid "A result of type internal requires at least one input of type internal." +msgstr "Un résultat de type internal nécessite au moins une entrée de type internal." + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 parser/parse_collate.c:1004 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "le collationnement ne correspond pas aux collationnements implicites « %s » et « %s »" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 parser/parse_collate.c:1007 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "Vous pouvez choisir le collationnement en appliquant la clause COLLATE à une ou aux deux expressions." + +#: parser/parse_collate.c:854 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "le collationnement ne correspond pas aux collationnements explicites « %s » et « %s »" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "" +"la référence récursive à la requête « %s » ne doit pas apparaître à\n" +"l'intérieur de son terme non récursif" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "" +"la référence récursive à la requête « %s » ne doit pas apparaître à\n" +"l'intérieur d'une sous-requête" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "" +"la référence récursive à la requête « %s » ne doit pas apparaître à\n" +"l'intérieur d'une jointure externe" + +#: parser/parse_cte.c:52 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "" +"la référence récursive à la requête « %s » ne doit pas apparaître à\n" +"l'intérieur d'INTERSECT" + +#: parser/parse_cte.c:54 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "" +"la référence récursive à la requête « %s » ne doit pas apparaître à\n" +"l'intérieur d'EXCEPT" + +#: parser/parse_cte.c:136 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "le nom de la requête WITH « %s » est spécifié plus d'une fois" + +#: parser/parse_cte.c:268 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "la clause WITH contenant une instruction de modification de données doit être au plus haut niveau" + +#: parser/parse_cte.c:317 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "" +"dans la requête récursive « %s », la colonne %d a le type %s dans le terme non\n" +"récursif mais le type global %s" + +#: parser/parse_cte.c:323 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Convertit la sortie du terme non récursif dans le bon type." + +#: parser/parse_cte.c:328 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "requête récursive « %s » : la colonne %d a le collationnement « %s » dans un terme non récursifet un collationnement « %s » global" + +#: parser/parse_cte.c:332 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "Utilisez la clause COLLATE pour configurer le collationnement du terme non récursif." + +#: parser/parse_cte.c:350 +#, c-format +msgid "WITH query is not recursive" +msgstr "la requête WITH n'est pas récursive" + +#: parser/parse_cte.c:381 +#, c-format +msgid "with a SEARCH or CYCLE clause, the left side of the UNION must be a SELECT" +msgstr "avec une clause SEARCH ou CYCLE, le côté gauche de l'UNION doit être un SELECT" + +#: parser/parse_cte.c:386 +#, c-format +msgid "with a SEARCH or CYCLE clause, the right side of the UNION must be a SELECT" +msgstr "avec une clause SEARCH ou CYCLE, le côté droit de l'UNION doit être un SELECT" + +#: parser/parse_cte.c:401 +#, c-format +msgid "search column \"%s\" not in WITH query column list" +msgstr "colonne de recherche « %s » non présent dans la liste des colonnes de la requête WITH" + +#: parser/parse_cte.c:408 +#, c-format +msgid "search column \"%s\" specified more than once" +msgstr "la colonne de recherche « %s » est spécifiée plus d'une fois" + +#: parser/parse_cte.c:417 +#, c-format +msgid "search sequence column name \"%s\" already used in WITH query column list" +msgstr "nom de colonne « %s » de la séquence de recherche déjà utilisé dans la liste des colonnes de la requête WITH" + +#: parser/parse_cte.c:436 +#, c-format +msgid "cycle column \"%s\" not in WITH query column list" +msgstr "la colonne cycle « %s » n'est pas dans la liste de colonne de la requête WITH" + +#: parser/parse_cte.c:443 +#, c-format +msgid "cycle column \"%s\" specified more than once" +msgstr "la colonne cycle « %s » est spécifiée plus d'une fois" + +#: parser/parse_cte.c:452 +#, c-format +msgid "cycle mark column name \"%s\" already used in WITH query column list" +msgstr "nom de colonne « %s » de marque du cycle déjà utilisé dans la liste des colonnes de la requête WITH" + +#: parser/parse_cte.c:464 +#, c-format +msgid "cycle path column name \"%s\" already used in WITH query column list" +msgstr "nom de colonne « %s » de chemin du cycle déjà utilisé dans la liste des colonnes de la requête WITH" + +#: parser/parse_cte.c:472 +#, c-format +msgid "cycle mark column name and cycle path column name are the same" +msgstr "le nom de colonne de marque du cycle est identique au nom de colonne de chemin du cycle" + +#: parser/parse_cte.c:508 +#, c-format +msgid "could not identify an inequality operator for type %s" +msgstr "n'a pas pu identifier un opérateur d'inégalité pour le type %s" + +#: parser/parse_cte.c:520 +#, c-format +msgid "search sequence column name and cycle mark column name are the same" +msgstr "le nom de la colonne de séquence de recherche est identique au nom de la colonne de marque du cycle" + +#: parser/parse_cte.c:527 +#, c-format +msgid "search sequence column name and cycle path column name are the same" +msgstr "le nom de la colonne de séquence de recherche est identique au nom de la colonne de chemin du cycle" + +#: parser/parse_cte.c:611 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "la requête WITH « %s » a %d colonnes disponibles mais %d colonnes spécifiées" + +#: parser/parse_cte.c:791 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "la récursion mutuelle entre des éléments WITH n'est pas implantée" + +#: parser/parse_cte.c:843 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "la requête récursive « %s » ne doit pas contenir des instructions de modification de données" + +#: parser/parse_cte.c:851 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "" +"la requête récursive « %s » n'a pas la forme terme-non-récursive UNION [ALL]\n" +"terme-récursive" + +#: parser/parse_cte.c:895 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "ORDER BY dans une requête récursive n'est pas implanté" + +#: parser/parse_cte.c:901 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "OFFSET dans une requête récursive n'est pas implémenté" + +#: parser/parse_cte.c:907 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "LIMIT dans une requête récursive n'est pas implémenté" + +#: parser/parse_cte.c:913 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "FOR UPDATE/SHARE dans une requête récursive n'est pas implémenté" + +#: parser/parse_cte.c:970 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "la référence récursive à la requête « %s » ne doit pas apparaître plus d'une fois" + +#: parser/parse_expr.c:287 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "DEFAULT interdit dans ce contexte" + +#: parser/parse_expr.c:340 parser/parse_relation.c:3592 parser/parse_relation.c:3612 +#, c-format +msgid "column %s.%s does not exist" +msgstr "la colonne %s.%s n'existe pas" + +#: parser/parse_expr.c:352 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "colonne « %s » introuvable pour le type de données %s" + +#: parser/parse_expr.c:358 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "n'a pas pu identifier la colonne « %s » dans le type de données de l'enregistrement" + +#: parser/parse_expr.c:364 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "notation d'attribut .%s appliqué au type %s, qui n'est pas un type composé" + +#: parser/parse_expr.c:395 parser/parse_target.c:740 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "l'expansion de ligne via « * » n'est pas supporté ici" + +#: parser/parse_expr.c:516 +msgid "cannot use column reference in DEFAULT expression" +msgstr "ne peut pas utiliser une référence de colonne dans l'expression par défaut" + +#: parser/parse_expr.c:519 +msgid "cannot use column reference in partition bound expression" +msgstr "ne peut pas utiliser une référence de colonne dans une expression de limite de partition" + +#: parser/parse_expr.c:788 parser/parse_relation.c:807 parser/parse_relation.c:889 parser/parse_target.c:1235 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "la référence à la colonne « %s » est ambigu" + +#: parser/parse_expr.c:844 parser/parse_param.c:110 parser/parse_param.c:142 parser/parse_param.c:208 parser/parse_param.c:307 +#, c-format +msgid "there is no parameter $%d" +msgstr "Il n'y a pas de paramètre $%d" + +#: parser/parse_expr.c:1044 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULLIF requiert l'opérateur = pour comparer des booleéns" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1050 parser/parse_expr.c:2965 +#, c-format +msgid "%s must not return a set" +msgstr "%s ne doit pas renvoyer un ensemble" + +#: parser/parse_expr.c:1430 parser/parse_expr.c:1462 +#, c-format +msgid "number of columns does not match number of values" +msgstr "le nombre de colonnes ne correspond pas au nombre de valeurs" + +#: parser/parse_expr.c:1476 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "la source d'un élément UPDATE multi-colonnes doit être un sous-SELECT ou une expression ROW()" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1671 parser/parse_expr.c:2144 parser/parse_func.c:2676 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "les fonctions renvoyant un ensemble ne sont pas autorisés dans %s" + +#: parser/parse_expr.c:1733 +msgid "cannot use subquery in check constraint" +msgstr "ne peut pas utiliser une sous-requête dans la contrainte de vérification" + +#: parser/parse_expr.c:1737 +msgid "cannot use subquery in DEFAULT expression" +msgstr "ne peut pas utiliser de sous-requête dans une expression DEFAULT" + +#: parser/parse_expr.c:1740 +msgid "cannot use subquery in index expression" +msgstr "ne peut pas utiliser la sous-requête dans l'expression de l'index" + +#: parser/parse_expr.c:1743 +msgid "cannot use subquery in index predicate" +msgstr "ne peut pas utiliser une sous-requête dans un prédicat d'index" + +#: parser/parse_expr.c:1746 +msgid "cannot use subquery in statistics expression" +msgstr "ne peut pas utiliser une sous-requête dans l'expression des statistiques" + +#: parser/parse_expr.c:1749 +msgid "cannot use subquery in transform expression" +msgstr "ne peut pas utiliser une sous-requête dans l'expression de transformation" + +#: parser/parse_expr.c:1752 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "ne peut pas utiliser les sous-requêtes dans le paramètre EXECUTE" + +#: parser/parse_expr.c:1755 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "ne peut pas utiliser une sous-requête dans la condition WHEN d'un trigger" + +#: parser/parse_expr.c:1758 +msgid "cannot use subquery in partition bound" +msgstr "ne peut pas utiliser de sous-requête dans une limite de partition" + +#: parser/parse_expr.c:1761 +msgid "cannot use subquery in partition key expression" +msgstr "ne peut pas utiliser de sous-requête dans l'expression de clé de partitionnement" + +#: parser/parse_expr.c:1764 +msgid "cannot use subquery in CALL argument" +msgstr "ne peut pas utiliser de sous-requête dans l'argument CALL" + +#: parser/parse_expr.c:1767 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "ne peut pas utiliser une sous-requête dans la condition WHERE d'un COPY FROM" + +#: parser/parse_expr.c:1770 +msgid "cannot use subquery in column generation expression" +msgstr "ne peut pas utiliser une sous-requête dans l'expression de génération d'une colonne" + +#: parser/parse_expr.c:1823 +#, c-format +msgid "subquery must return only one column" +msgstr "la sous-requête doit renvoyer une seule colonne" + +#: parser/parse_expr.c:1894 +#, c-format +msgid "subquery has too many columns" +msgstr "la sous-requête a trop de colonnes" + +#: parser/parse_expr.c:1899 +#, c-format +msgid "subquery has too few columns" +msgstr "la sous-requête n'a pas assez de colonnes" + +#: parser/parse_expr.c:1995 +#, c-format +msgid "cannot determine type of empty array" +msgstr "ne peut pas déterminer le type d'un tableau vide" + +#: parser/parse_expr.c:1996 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "Convertit explicitement vers le type désiré, par exemple ARRAY[]::integer[]." + +#: parser/parse_expr.c:2010 +#, c-format +msgid "could not find element type for data type %s" +msgstr "n'a pas pu trouver le type d'élément pour le type de données %s" + +#: parser/parse_expr.c:2290 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "la valeur d'un attribut XML sans nom doit être une référence de colonne" + +#: parser/parse_expr.c:2291 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "la valeur d'un élément XML sans nom doit être une référence de colonne" + +#: parser/parse_expr.c:2306 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "le nom de l'attribut XML « %s » apparaît plus d'une fois" + +#: parser/parse_expr.c:2413 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "ne peut pas convertir le résultat XMLSERIALIZE en %s" + +#: parser/parse_expr.c:2722 parser/parse_expr.c:2918 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "nombre différent d'entrées dans les expressions de ligne" + +#: parser/parse_expr.c:2732 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "n'a pas pu comparer des lignes de taille zéro" + +#: parser/parse_expr.c:2757 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "" +"l'opérateur de comparaison de ligne doit renvoyer le type booléen, et non le\n" +"type %s" + +#: parser/parse_expr.c:2764 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "l'opérateur de comparaison de ligne ne doit pas renvoyer un ensemble" + +#: parser/parse_expr.c:2823 parser/parse_expr.c:2864 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "n'a pas pu déterminer l'interprétation de l'opérateur de comparaison de ligne %s" + +#: parser/parse_expr.c:2825 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "" +"Les opérateurs de comparaison de lignes doivent être associés à des familles\n" +"d'opérateurs btree." + +#: parser/parse_expr.c:2866 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Il existe de nombreus candidats également plausibles." + +#: parser/parse_expr.c:2959 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROM requiert l'opérateur = pour comparer des booléens" + +#: parser/parse_func.c:194 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "nom « %s » de l'argument spécifié plus d'une fois" + +#: parser/parse_func.c:205 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "l'argument positionné ne doit pas suivre l'argument nommé" + +#: parser/parse_func.c:287 parser/parse_func.c:2369 +#, c-format +msgid "%s is not a procedure" +msgstr "%s n'est pas une procédure" + +#: parser/parse_func.c:291 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Pour appeler une fonction, utilisez SELECT." + +#: parser/parse_func.c:297 +#, c-format +msgid "%s is a procedure" +msgstr "%s est une procédure" + +#: parser/parse_func.c:301 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Pour appeler une procédure, utilisez CALL." + +#: parser/parse_func.c:315 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) spécifié, mais %s n'est pas une fonction d'agrégat" + +#: parser/parse_func.c:322 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT spécifié mais %s n'est pas une fonction d'agrégat" + +#: parser/parse_func.c:328 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP spécifié, mais %s n'est pas une fonction d'agrégat" + +#: parser/parse_func.c:334 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY spécifié, mais %s n'est pas une fonction d'agrégat" + +#: parser/parse_func.c:340 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER spécifié mais %s n'est pas une fonction d'agrégat" + +#: parser/parse_func.c:346 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER spécifié, mais %s n'est pas une fonction window ou une fonction d'agrégat" + +#: parser/parse_func.c:384 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "WITHIN GROUP est requis pour l'agrégat à ensemble ordonné %s" + +#: parser/parse_func.c:390 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "OVER n'est pas supporté pour l'agrégat %s à ensemble trié" + +#: parser/parse_func.c:421 parser/parse_func.c:452 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct argument, not %d." +msgid_plural "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr[0] "Il existe un agrégat par ensemble trié nommé %s, mais il requiert %d argument direct, pas %d." +msgstr[1] "Il existe un agrégat par ensemble trié nommé %s, mais il requiert %d arguments directs, pas %d." + +#: parser/parse_func.c:479 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "Pour utiliser l'agrégat à ensemble hypothétique %s, le nombre d'arguments directs hypothétiques (ici %d) doit correspondre au nombre de colonnes de tri (ici %d)." + +#: parser/parse_func.c:493 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct argument." +msgid_plural "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr[0] "Il existe un agrégat par ensemble trié nommé %s, mais il requiert au moins %d argument direct." +msgstr[1] "Il existe un agrégat par ensemble trié nommé %s, mais il requiert au moins %d arguments directs." + +#: parser/parse_func.c:514 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s n'est pas un agrégat par ensemble trié, donc il ne peut pas avoir WITHIN GROUP" + +#: parser/parse_func.c:527 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "la fonction de fenêtrage %s nécessite une clause OVER" + +#: parser/parse_func.c:534 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "la fonction de fenêtrage %s ne peut avoir WITHIN GROUP" + +#: parser/parse_func.c:563 +#, c-format +msgid "procedure %s is not unique" +msgstr "la procédure %s n'est pas unique" + +#: parser/parse_func.c:566 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "" +"N'a pas pu choisir un meilleur candidat pour la procédure. Vous pourriez avoir besoin\n" +"d'ajouter une conversion de type explicite." + +#: parser/parse_func.c:572 +#, c-format +msgid "function %s is not unique" +msgstr "la fonction %s n'est pas unique" + +#: parser/parse_func.c:575 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "" +"N'a pas pu choisir un meilleur candidat dans les fonctions. Vous pourriez\n" +"avoir besoin d'ajouter des conversions explicites de type." + +#: parser/parse_func.c:614 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "" +"Aucune fonction d'agrégat ne correspond au nom donné et aux types d'arguments.\n" +"Peut-être avez-vous mal placé la clause ORDER BY.\n" +"Cette dernière doit apparaître après tous les arguments standards de l'agrégat." + +#: parser/parse_func.c:622 parser/parse_func.c:2412 +#, c-format +msgid "procedure %s does not exist" +msgstr "la procédure %s n'existe pas" + +#: parser/parse_func.c:625 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "" +"Aucune procédure ne correspond au nom donné et aux types d'arguments.\n" +"Vous pourriez avoir besoin d'ajouter des conversions de type explicites." + +#: parser/parse_func.c:634 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "" +"Aucune fonction ne correspond au nom donné et aux types d'arguments.\n" +"Vous devez ajouter des conversions explicites de type." + +#: parser/parse_func.c:736 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "l'argument VARIADIC doit être un tableau" + +#: parser/parse_func.c:790 parser/parse_func.c:854 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*) doit être utilisé pour appeler une fonction d'agrégat sans paramètre" + +#: parser/parse_func.c:797 +#, c-format +msgid "aggregates cannot return sets" +msgstr "les agrégats ne peuvent pas renvoyer des ensembles" + +#: parser/parse_func.c:812 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "les agrégats ne peuvent pas utiliser des arguments nommés" + +#: parser/parse_func.c:844 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "DISTINCT n'est pas implémenté pour des fonctions window" + +#: parser/parse_func.c:864 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "l'agrégat ORDER BY n'est pas implémenté pour les fonctions de fenêtrage" + +#: parser/parse_func.c:873 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "FILTER n'est pas implémenté pour des fonctions de fenêtrage non agrégats" + +#: parser/parse_func.c:882 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "" +"les appels à la fonction de fenêtrage ne peuvent pas contenir des appels à des\n" +"fonctions renvoyant des ensembles de lignes" + +#: parser/parse_func.c:890 +#, c-format +msgid "window functions cannot return sets" +msgstr "les fonctions window ne peuvent pas renvoyer des ensembles" + +#: parser/parse_func.c:2168 parser/parse_func.c:2441 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "n'a pas pu trouver une fonction nommée « %s »" + +#: parser/parse_func.c:2182 parser/parse_func.c:2459 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "le nom de la fonction « %s » n'est pas unique" + +#: parser/parse_func.c:2184 parser/parse_func.c:2462 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Indiquez la liste d'arguments pour sélectionner la fonction sans ambiguïté." + +#: parser/parse_func.c:2228 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "les procédures ne peuvent avoir plus de %d argument" +msgstr[1] "les procédures ne peuvent avoir plus de %d arguments" + +#: parser/parse_func.c:2359 +#, c-format +msgid "%s is not a function" +msgstr "%s n'est pas une fonction" + +#: parser/parse_func.c:2379 +#, c-format +msgid "function %s is not an aggregate" +msgstr "la fonction %s n'est pas un agrégat" + +#: parser/parse_func.c:2407 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "n'a pas pu trouver une procédure nommée « %s »" + +#: parser/parse_func.c:2421 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "n'a pas pu trouver un aggrégat nommé « %s »" + +#: parser/parse_func.c:2426 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "l'agrégat %s(*) n'existe pas" + +#: parser/parse_func.c:2431 +#, c-format +msgid "aggregate %s does not exist" +msgstr "l'agrégat %s n'existe pas" + +#: parser/parse_func.c:2467 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "le nom de la procédure « %s » n'est pas unique" + +#: parser/parse_func.c:2470 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Définit la liste d'arguments pour sélectionner la procédure sans ambiguïté." + +#: parser/parse_func.c:2475 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "le nom d'agrégat « %s » n'est pas unique" + +#: parser/parse_func.c:2478 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Définit la liste d'arguments pour sélectionner l'agrégat sans ambiguïté." + +#: parser/parse_func.c:2483 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "le nom de la routine « %s » n'est pas unique" + +#: parser/parse_func.c:2486 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Définit la liste d'arguments pour sélectionner la routine sans ambiguïté." + +#: parser/parse_func.c:2541 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "les fonctions renvoyant un ensemble de lignes ne sont pas autorisées dans les conditions JOIN" + +#: parser/parse_func.c:2562 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions de politique" + +#: parser/parse_func.c:2578 +msgid "set-returning functions are not allowed in window definitions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les définitions de fenêtres" + +#: parser/parse_func.c:2616 +msgid "set-returning functions are not allowed in check constraints" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les contraintes CHECK" + +#: parser/parse_func.c:2620 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions par défaut" + +#: parser/parse_func.c:2623 +msgid "set-returning functions are not allowed in index expressions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions d'index" + +#: parser/parse_func.c:2626 +msgid "set-returning functions are not allowed in index predicates" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les prédicats d'index" + +#: parser/parse_func.c:2629 +msgid "set-returning functions are not allowed in statistics expressions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions statistiques" + +#: parser/parse_func.c:2632 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions de transformation" + +#: parser/parse_func.c:2635 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les paramètres d'EXECUTE" + +#: parser/parse_func.c:2638 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les conditions WHEN des triggers" + +#: parser/parse_func.c:2641 +msgid "set-returning functions are not allowed in partition bound" +msgstr "les fonctions renvoyant un ensemble de lignes ne sont pas autorisées dans les limites de partition" + +#: parser/parse_func.c:2644 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions de clé de partitionnement" + +#: parser/parse_func.c:2647 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les arguments de CALL" + +#: parser/parse_func.c:2650 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "les fonctions renvoyant un ensemble de lignes ne sont pas autorisées dans les conditions WHERE d'un COPY FROM" + +#: parser/parse_func.c:2653 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "les fonctions renvoyant un ensemble de lignes ne sont pas autorisées dans les expressions de génération de colonne" + +#: parser/parse_node.c:87 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "les listes cibles peuvent avoir au plus %d colonnes" + +#: parser/parse_oper.c:123 parser/parse_oper.c:690 +#, c-format +msgid "postfix operators are not supported" +msgstr "les opérateurs postfixes ne sont pas supportés" + +#: parser/parse_oper.c:130 parser/parse_oper.c:649 utils/adt/regproc.c:539 utils/adt/regproc.c:723 +#, c-format +msgid "operator does not exist: %s" +msgstr "l'opérateur n'existe pas : %s" + +#: parser/parse_oper.c:229 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Utilisez un opérateur explicite de tri ou modifiez la requête." + +#: parser/parse_oper.c:485 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "l'opérateur requiert la coercion du type à l'exécution : %s" + +#: parser/parse_oper.c:641 +#, c-format +msgid "operator is not unique: %s" +msgstr "l'opérateur n'est pas unique : %s" + +#: parser/parse_oper.c:643 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "" +"N'a pas pu choisir un meilleur candidat pour l'opérateur. Vous devez ajouter une\n" +"conversion explicite de type." + +#: parser/parse_oper.c:652 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "" +"Aucun opérateur ne correspond au nom donné et au type d'argument.\n" +"Vous devez ajouter des conversions explicites de type." + +#: parser/parse_oper.c:654 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "" +"Aucun opérateur ne correspond au nom donné et aux types d'arguments.\n" +"Vous devez ajouter des conversions explicites de type." + +#: parser/parse_oper.c:714 parser/parse_oper.c:828 +#, c-format +msgid "operator is only a shell: %s" +msgstr "l'opérateur est seulement un shell : %s" + +#: parser/parse_oper.c:816 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (tableau) requiert un tableau sur le côté droit" + +#: parser/parse_oper.c:858 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (tableau) requiert un opérateur pour comparer des booléens" + +#: parser/parse_oper.c:863 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (tableau) requiert que l'opérateur ne renvoie pas un ensemble" + +#: parser/parse_param.c:225 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "types incohérents déduit pour le paramètre $%d" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "la référence à la table « %s » est ambigu" + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "la référence à la table %u est ambigu" + +#: parser/parse_relation.c:445 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "le nom de la table « %s » est spécifié plus d'une fois" + +#: parser/parse_relation.c:474 parser/parse_relation.c:3532 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "référence invalide d'une entrée de la clause FROM pour la table « %s »" + +#: parser/parse_relation.c:478 parser/parse_relation.c:3537 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "" +"Il existe une entrée pour la table « %s » mais elle ne peut pas être\n" +"référencée de cette partie de la requête." + +#: parser/parse_relation.c:480 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "Le type JOIN combiné doit être INNER ou LEFT pour une référence LATERAL." + +#: parser/parse_relation.c:691 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "la référence de la colonne système « %s » dans la contrainte CHECK est invalide" + +#: parser/parse_relation.c:700 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "ne peut pas utiliser la colonne système « %s » dans une expression de génération de colonne" + +#: parser/parse_relation.c:1173 parser/parse_relation.c:1625 parser/parse_relation.c:2302 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "la table « %s » a %d colonnes disponibles mais %d colonnes spécifiées" + +#: parser/parse_relation.c:1377 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "" +"Il existe un élément WITH nommé « %s » mais il ne peut pas être\n" +"référencée de cette partie de la requête." + +#: parser/parse_relation.c:1379 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "" +"Utilisez WITH RECURSIVE ou ré-ordonnez les éléments WITH pour supprimer\n" +"les références en avant." + +#: parser/parse_relation.c:1767 +#, c-format +msgid "a column definition list is redundant for a function with OUT parameters" +msgstr "une liste de définition de colonnes est redondante pour une fonction avec paramètres OUT" + +#: parser/parse_relation.c:1773 +#, c-format +msgid "a column definition list is redundant for a function returning a named composite type" +msgstr "une liste de définition de colonnes est redondante pour une fonction renvoyant un type composite nommé" + +#: parser/parse_relation.c:1780 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "une liste de définition de colonnes n'autorisée que pour les fonctions renvoyant un « record »" + +#: parser/parse_relation.c:1791 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "une liste de définition de colonnes est requise pour les fonctions renvoyant un « record »" + +#: parser/parse_relation.c:1880 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "la fonction « %s » dans la clause FROM a un type de retour %s non supporté" + +#: parser/parse_relation.c:2089 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "les listes de VALUES « %s » ont %d colonnes disponibles mais %d colonnes spécifiées" + +#: parser/parse_relation.c:2161 +#, c-format +msgid "joins can have at most %d columns" +msgstr "les jointures peuvent avoir au plus %d colonnes" + +#: parser/parse_relation.c:2275 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "La requête WITH « %s » n'a pas de clause RETURNING" + +#: parser/parse_relation.c:3307 parser/parse_relation.c:3317 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "la colonne %d de la relation « %s » n'existe pas" + +#: parser/parse_relation.c:3535 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Peut-être que vous souhaitiez référencer l'alias de la table « %s »." + +#: parser/parse_relation.c:3543 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "entrée manquante de la clause FROM pour la table « %s »" + +#: parser/parse_relation.c:3595 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Peut-être que vous souhaitiez référencer la colonne « %s.%s »." + +#: parser/parse_relation.c:3597 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Il existe une colonne nommée « %s » pour la table « %s » mais elle ne peut pas être référencée dans cette partie de la requête." + +#: parser/parse_relation.c:3614 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "Peut-être que vous souhaitiez référencer la colonne « %s.%s » ou la colonne « %s.%s »." + +#: parser/parse_target.c:483 parser/parse_target.c:804 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "ne peut pas affecter à une colonne système « %s »" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "ne peut pas initialiser un élément d'un tableau avec DEFAULT" + +#: parser/parse_target.c:516 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "ne peut pas initialiser un sous-champ avec DEFAULT" + +#: parser/parse_target.c:590 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "la colonne « %s » est de type %s mais l'expression est de type %s" + +#: parser/parse_target.c:788 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "" +"ne peut pas l'affecter au champ « %s » de la colonne « %s » parce que son\n" +"type %s n'est pas un type composé" + +#: parser/parse_target.c:797 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "" +"ne peut pas l'affecter au champ « %s » de la colonne « %s » parce qu'il n'existe\n" +"pas une telle colonne dans le type de données %s" + +#: parser/parse_target.c:878 +#, c-format +msgid "subscripted assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "" + +#: parser/parse_target.c:888 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "le sous-champ « %s » est de type %s mais l'expression est de type %s" + +#: parser/parse_target.c:1323 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "Un SELECT * sans table spécifiée n'est pas valide" + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "référence %%TYPE invalide (trop peu de points entre les noms) : %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "référence %%TYPE invalide (trop de points entre les noms) : %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "référence de type %s convertie en %s" + +#: parser/parse_type.c:278 parser/parse_type.c:803 utils/cache/typcache.c:389 utils/cache/typcache.c:444 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "le type « %s » est seulement un shell" + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "le modificateur de type n'est pas autorisé pour le type « %s »" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "les modificateurs de type doivent être des constantes ou des identifiants" + +#: parser/parse_type.c:721 parser/parse_type.c:766 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "nom de type « %s » invalide" + +#: parser/parse_utilcmd.c:256 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "ne peut pas créer une table partitionnée comme la fille d'un héritage" + +#: parser/parse_utilcmd.c:570 +#, c-format +msgid "array of serial is not implemented" +msgstr "le tableau de type serial n'est pas implémenté" + +#: parser/parse_utilcmd.c:649 parser/parse_utilcmd.c:661 parser/parse_utilcmd.c:720 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "déclarations NULL/NOT NULL en conflit pour la colonne « %s » de la table « %s »" + +#: parser/parse_utilcmd.c:673 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "" +"plusieurs valeurs par défaut sont spécifiées pour la colonne « %s » de la table\n" +"« %s »" + +#: parser/parse_utilcmd.c:690 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "les colonnes d'identité uniques ne sont pas supportées sur les tables typées" + +#: parser/parse_utilcmd.c:694 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "les colonnes d'identité ne sont pas supportées sur les partitions" + +#: parser/parse_utilcmd.c:703 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "plusieurs spécifications d'identité pour la colonne « %s » de la table « %s »" + +#: parser/parse_utilcmd.c:733 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "les colonnes générées ne sont pas supportées sur les tables typées" + +#: parser/parse_utilcmd.c:737 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "les colonnes générées ne sont pas supportées sur les partitions" + +#: parser/parse_utilcmd.c:742 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "plusieurs expressions de géénration sont spécifiées pour la colonne « %s » de la table « %s »" + +#: parser/parse_utilcmd.c:760 parser/parse_utilcmd.c:875 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "les clés primaires ne sont pas supportées par les tables distantes" + +#: parser/parse_utilcmd.c:769 parser/parse_utilcmd.c:885 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "les contraintes uniques ne sont pas supportées par les tables distantes" + +#: parser/parse_utilcmd.c:814 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "une valeur par défaut et une identité ont été spécifiées pour la colonne « %s » de la table « %s »" + +#: parser/parse_utilcmd.c:822 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "une valeur par défaut et une expression de génération ont été spécifiées à la fois pour la colonne « %s » de la table « %s »" + +#: parser/parse_utilcmd.c:830 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "une identité et une expression de génération ont été spécifiées à la fois pour la colonne « %s » de la table « %s »" + +#: parser/parse_utilcmd.c:895 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "les contraintes d'exclusion ne sont pas supportées par les tables distantes" + +#: parser/parse_utilcmd.c:901 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "les contraintes d'exclusion ne sont pas supportées sur les tables partitionnées" + +#: parser/parse_utilcmd.c:966 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "LIKE n'est pas supporté pour la création de tables distantes" + +#: parser/parse_utilcmd.c:1743 parser/parse_utilcmd.c:1851 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "l'index « %s » contient une référence de table de ligne complète" + +#: parser/parse_utilcmd.c:2238 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "ne peut pas utiliser un index existant dans CREATE TABLE" + +#: parser/parse_utilcmd.c:2258 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "l'index « %s » est déjà associé à une contrainte" + +#: parser/parse_utilcmd.c:2273 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "l'index « %s » n'est pas valide" + +#: parser/parse_utilcmd.c:2279 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "« %s » n'est pas un index unique" + +#: parser/parse_utilcmd.c:2280 parser/parse_utilcmd.c:2287 parser/parse_utilcmd.c:2294 parser/parse_utilcmd.c:2371 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "Ne peut pas créer une clé primaire ou une contrainte unique avec cet index." + +#: parser/parse_utilcmd.c:2286 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "l'index « %s » contient des expressions" + +#: parser/parse_utilcmd.c:2293 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "« %s » est un index partiel" + +#: parser/parse_utilcmd.c:2305 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "« %s » est un index déferrable" + +#: parser/parse_utilcmd.c:2306 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "Ne peut pas créer une contrainte non-déferrable utilisant un index déferrable." + +#: parser/parse_utilcmd.c:2370 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "l'index « %s », colonne numéro %d, n'a pas de tri par défaut" + +#: parser/parse_utilcmd.c:2527 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "la colonne « %s » apparaît deux fois dans la contrainte de la clé primaire" + +#: parser/parse_utilcmd.c:2533 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "la colonne « %s » apparaît deux fois sur une contrainte unique" + +#: parser/parse_utilcmd.c:2880 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "les expressions et prédicats d'index peuvent seulement faire référence à la table en cours d'indexage" + +#: parser/parse_utilcmd.c:2952 +#, c-format +msgid "statistics expressions can refer only to the table being indexed" +msgstr "les expressions statistiques peuvent seulement faire référence à la table en cours d'indexage" + +#: parser/parse_utilcmd.c:2995 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "les règles ne sont pas supportés sur les vues matérialisées" + +#: parser/parse_utilcmd.c:3058 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "" +"la condition WHERE d'une règle ne devrait pas contenir de références à d'autres\n" +"relations" + +#: parser/parse_utilcmd.c:3131 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "les règles avec des conditions WHERE ne peuvent contenir que des actions SELECT, INSERT, UPDATE ou DELETE " + +#: parser/parse_utilcmd.c:3149 parser/parse_utilcmd.c:3250 rewrite/rewriteHandler.c:508 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "" +"les instructions conditionnelles UNION/INTERSECT/EXCEPT ne sont pas\n" +"implémentées" + +#: parser/parse_utilcmd.c:3167 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "la règle ON SELECT ne peut pas utiliser OLD" + +#: parser/parse_utilcmd.c:3171 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "la règle ON SELECT ne peut pas utiliser NEW" + +#: parser/parse_utilcmd.c:3180 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "la règle ON INSERT ne peut pas utiliser OLD" + +#: parser/parse_utilcmd.c:3186 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "la règle ON INSERT ne peut pas utiliser NEW" + +#: parser/parse_utilcmd.c:3214 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "ne peut référencer OLD dans une requête WITH" + +#: parser/parse_utilcmd.c:3221 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "ne peut référencer NEW dans une requête WITH" + +#: parser/parse_utilcmd.c:3674 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "clause DEFERRABLE mal placée" + +#: parser/parse_utilcmd.c:3679 parser/parse_utilcmd.c:3694 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "clauses DEFERRABLE/NOT DEFERRABLE multiples non autorisées" + +#: parser/parse_utilcmd.c:3689 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "clause NOT DEFERRABLE mal placée" + +#: parser/parse_utilcmd.c:3710 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "clause INITIALLY DEFERRED mal placée" + +#: parser/parse_utilcmd.c:3715 parser/parse_utilcmd.c:3741 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "clauses INITIALLY IMMEDIATE/DEFERRED multiples non autorisées" + +#: parser/parse_utilcmd.c:3736 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "clause INITIALLY IMMEDIATE mal placée" + +#: parser/parse_utilcmd.c:3927 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE spécifie un schéma (%s) différent de celui tout juste créé (%s)" + +#: parser/parse_utilcmd.c:3962 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "« %s » n'est pas une table partitionnée" + +#: parser/parse_utilcmd.c:3969 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "la table « %s » n'est pas partitionné" + +#: parser/parse_utilcmd.c:3976 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "l'index « %s » n'est pas partitionné" + +#: parser/parse_utilcmd.c:4016 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "une table partitionnées par hash ne peut pas avoir de partition par défaut" + +#: parser/parse_utilcmd.c:4033 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "spécification de limite invalide pour une partition par hash" + +#: parser/parse_utilcmd.c:4039 partitioning/partbounds.c:4701 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "le modulus pour une partition par hash doit être un entier positif" + +#: parser/parse_utilcmd.c:4046 partitioning/partbounds.c:4709 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "le modulus pour une partition par hash doit être inférieur au modulus" + +#: parser/parse_utilcmd.c:4059 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "spécification de limite invalide pour une partition par liste" + +#: parser/parse_utilcmd.c:4112 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "spécification de limite invalide pour une partition par intervalle" + +#: parser/parse_utilcmd.c:4118 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM doit spécifier exactement une valeur par colonne de partitionnement" + +#: parser/parse_utilcmd.c:4122 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO doit spécifier exactement une valeur par colonne de partitionnement" + +#: parser/parse_utilcmd.c:4236 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "ne peut pas spécifier NULL dans la limite de l'intervalle" + +#: parser/parse_utilcmd.c:4285 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "chaque limite suivant MAXVALUE doit aussi être MAXVALUE" + +#: parser/parse_utilcmd.c:4292 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "chaque limite suivant MINVALUE doit aussi être MINVALUE" + +#: parser/parse_utilcmd.c:4335 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "la valeur spécifiée ne peut pas être convertie vers le type %s pour la colonne « %s »" + +#: parser/parser.c:247 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "UESCAPE doit être suivi par une simple chaîne litérale" + +#: parser/parser.c:252 +msgid "invalid Unicode escape character" +msgstr "chaîne d'échappement Unicode invalide" + +#: parser/parser.c:321 scan.l:1329 +#, c-format +msgid "invalid Unicode escape value" +msgstr "valeur d'échappement Unicode invalide" + +#: parser/parser.c:468 scan.l:677 utils/adt/varlena.c:6566 +#, c-format +msgid "invalid Unicode escape" +msgstr "échappement Unicode invalide" + +#: parser/parser.c:469 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "Les échappements Unicode doivent être de la forme \\XXXX ou \\+XXXXXX." + +#: parser/parser.c:497 scan.l:638 scan.l:654 scan.l:670 utils/adt/varlena.c:6591 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "paire surrogate Unicode invalide" + +#: parser/scansup.c:101 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%.*s\"" +msgstr "l'identifiant « %s » sera tronqué en « %.*s »" + +#: partitioning/partbounds.c:2821 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "la partition « %s » est en conflit avec la partition par défaut existante « %s »" + +#: partitioning/partbounds.c:2870 partitioning/partbounds.c:2888 partitioning/partbounds.c:2904 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "chaque modulo de partition hash doit être un facteur du prochain plus gros modulo" + +#: partitioning/partbounds.c:2871 partitioning/partbounds.c:2905 +#, c-format +msgid "The new modulus %d is not a factor of %d, the modulus of existing partition \"%s\"." +msgstr "" + +#: partitioning/partbounds.c:2889 +#, c-format +msgid "The new modulus %d is not divisible by %d, the modulus of existing partition \"%s\"." +msgstr "" + +#: partitioning/partbounds.c:3018 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "limite d'intervalle vide indiquée pour la partition « %s »" + +#: partitioning/partbounds.c:3020 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "La limite inférieure spécifiée %s est supérieure ou égale à la limite supérieure %s." + +#: partitioning/partbounds.c:3132 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "la partition « %s » surchargerait la partition « %s »" + +#: partitioning/partbounds.c:3249 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "parcours ignoré pour la table distante « %s » qui n'est pas une partition ou partition par défaut « %s »" + +#: partitioning/partbounds.c:4705 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "le reste pour une partition hash doit être un entier non négatif" + +#: partitioning/partbounds.c:4729 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "« %s » n'est pas une table partitionnée par hash" + +#: partitioning/partbounds.c:4740 partitioning/partbounds.c:4857 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "le nombre de colonnes de partitionnement (%d) ne correspond pas au nombre de clés de partitionnement fourni (%d)" + +#: partitioning/partbounds.c:4762 +#, c-format +msgid "column %d of the partition key has type %s, but supplied value is of type %s" +msgstr "la colonne %d de la clé de partitionnement a pour type %s, mais la valeur fournie est de type %s" + +#: partitioning/partbounds.c:4794 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "la colonne %d de la clé de partitionnement a pour type « %s », mais la valeur fournie a pour type « %s »" + +#: port/pg_sema.c:209 port/pg_shmem.c:668 port/posix_sema.c:209 port/sysv_sema.c:327 port/sysv_shmem.c:668 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "n'a pas pu lire les informations sur le répertoire des données « %s » : %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "n'a pas pu créer le segment de mémoire partagée : %m" + +#: port/pg_shmem.c:218 port/sysv_shmem.c:218 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "L'appel système qui a échoué était shmget(clé=%lu, taille=%zu, 0%o)." + +#: port/pg_shmem.c:222 port/sysv_shmem.c:222 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Cette erreur signifie habituellement que la demande de PostgreSQL pour un segment de mémoire partagée dépasse la valeur du paramètre SHMMAX du noyau, ou est plus petite\n" +"que votre paramètre SHMMIN du noyau. La documentation PostgreSQL contient plus d'information sur la configuration de la mémoire partagée." + +#: port/pg_shmem.c:229 port/sysv_shmem.c:229 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Cette erreur signifie habituellement que la demande de PostgreSQL pour un segment de mémoire partagée dépasse le paramètre SHMALL du noyau. Vous pourriez avoir besoin de reconfigurer\n" +"le noyau avec un SHMALL plus important. La documentation PostgreSQL contient plus d'information sur la configuration de la mémoire partagée." + +#: port/pg_shmem.c:235 port/sysv_shmem.c:235 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Cette erreur ne signifie *pas* que vous manquez d'espace disque. Elle survient si tous les identifiants de mémoire partagé disponibles ont été pris, auquel cas vous devez augmenter le paramètre SHMMNI de votre noyau, ou parce que la limite maximum de la mémoire partagée\n" +"de votre système a été atteinte. La documentation de PostgreSQL contient plus d'informations sur la configuration de la mémoire partagée." + +#: port/pg_shmem.c:606 port/sysv_shmem.c:606 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "n'a pas pu créer le segment de mémoire partagée anonyme : %m" + +#: port/pg_shmem.c:608 port/sysv_shmem.c:608 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "" +"Cette erreur signifie habituellement que la demande de PostgreSQL pour un\n" +"segment de mémoire partagée dépasse la mémoire disponible, l'espace swap ou\n" +"les Huge Pages. Pour réduire la taille demandée (actuellement %zu octets),\n" +"diminuez l'utilisation de la mémoire partagée, par exemple en réduisant la\n" +"valeur du paramètre shared_buffers de PostgreSQL ou le paramètre\n" +"max_connections." + +#: port/pg_shmem.c:676 port/sysv_shmem.c:676 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "Huge Pages non supportées sur cette plateforme" + +#: port/pg_shmem.c:737 port/sysv_shmem.c:737 utils/init/miscinit.c:1167 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "" +"le bloc de mémoire partagé pré-existant (clé %lu, ID %lu) est en cours\n" +"d'utilisation" + +#: port/pg_shmem.c:740 port/sysv_shmem.c:740 utils/init/miscinit.c:1169 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Termine les anciens processus serveurs associés avec le répertoire de données « %s »." + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "n'a pas pu créer des sémaphores : %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "L'appel système qui a échoué était semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:129 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"Cette erreur ne signifie *pas* que vous manquez d'espace disque. Il arrive\n" +"que soit la limite système du nombre maximum d'ensembles de sémaphores\n" +"(SEMMNI) ou le nombre maximum de sémaphores pour le système (SEMMNS) soit\n" +"dépassée. Vous avez besoin d'augmenter le paramètre noyau respectif.\n" +"Autrement, réduisez la consommation de sémaphores par PostgreSQL en réduisant\n" +"son paramètre max_connections.\n" +"La documentation de PostgreSQL contient plus d'informations sur la\n" +"configuration de votre système avec PostgreSQL." + +#: port/sysv_sema.c:159 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "" +"Vous pouvez avoir besoin d'augmenter la valeur SEMVMX par noyau pour valoir\n" +"au moins de %d. Regardez dans la documentation de PostgreSQL pour les détails." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "n'a pas pu charger dbghelp.dll, ne peut pas écrire le « crashdump »\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "n'a pas pu charger les fonctions requises dans dbghelp.dll, ne peut pas écrire le « crashdump »\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "n'a pas pu ouvrir le fichier « crashdump » « %s » en écriture : code d'erreur %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "a écrit le « crash dump » dans le fichier « %s »\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "n'a pas pu écrire le « crashdump » dans le fichier « %s » : code d'erreur %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "" +"n'a pas pu créer le tube d'écoute de signal pour l'identifiant de processus %d :\n" +"code d'erreur %lu" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "n'a pas pu créer le tube d'écoute de signal : code d'erreur %lu ; nouvelle tentative\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "n'a pas pu créer la sémaphore : code d'erreur %lu" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "n'a pas pu verrouiller la sémaphore : code d'erreur %lu" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "n'a pas pu déverrouiller la sémaphore : code d'erreur %lu" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "n'a pas pu tenter le verrouillage de la sémaphore : code d'erreur %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:159 port/win32_shmem.c:171 port/win32_shmem.c:187 +#, c-format +msgid "could not enable user right \"%s\": error code %lu" +msgstr "n'a pas pu activer le droit utilisateur « %s » : code d'erreur %lu" + +#. translator: This is a term from Windows and should be translated to +#. match the Windows localization. +#. +#: port/win32_shmem.c:150 port/win32_shmem.c:159 port/win32_shmem.c:171 port/win32_shmem.c:182 port/win32_shmem.c:184 port/win32_shmem.c:187 +msgid "Lock pages in memory" +msgstr "Verrouillage des pages en mémoire" + +#: port/win32_shmem.c:152 port/win32_shmem.c:160 port/win32_shmem.c:172 port/win32_shmem.c:188 +#, c-format +msgid "Failed system call was %s." +msgstr "L'appel système qui a échoué était %s." + +#: port/win32_shmem.c:182 +#, c-format +msgid "could not enable user right \"%s\"" +msgstr "n'a pas pu activer le droit utilisateur « %s »" + +#: port/win32_shmem.c:183 +#, c-format +msgid "Assign user right \"%s\" to the Windows user account which runs PostgreSQL." +msgstr "Assignez le droit d'utilisateur « %s » au compte d'utilisateur Windows qui fait tourner PostgreSQL." + +#: port/win32_shmem.c:241 +#, c-format +msgid "the processor does not support large pages" +msgstr "le processeur ne supporte pas les Large Pages" + +#: port/win32_shmem.c:310 port/win32_shmem.c:346 port/win32_shmem.c:364 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "n'a pas pu créer le segment de mémoire partagée : code d'erreur %lu" + +#: port/win32_shmem.c:311 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "L'appel système qui a échoué était CreateFileMapping(taille=%zu, nom=%s)." + +#: port/win32_shmem.c:336 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "le bloc de mémoire partagé pré-existant est toujours en cours d'utilisation" + +#: port/win32_shmem.c:337 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "" +"Vérifier s'il n'y a pas de vieux processus serveur en cours d'exécution. Si c'est le\n" +"cas, fermez-les." + +#: port/win32_shmem.c:347 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "L'appel système qui a échoué était DuplicateHandle." + +#: port/win32_shmem.c:365 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "L'appel système qui a échoué était MapViewOfFileEx." + +#: postmaster/autovacuum.c:411 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "n'a pas pu exécuter le processus autovacuum maître : %m" + +#: postmaster/autovacuum.c:1489 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "n'a pas pu exécuter le processus autovacuum worker : %m" + +#: postmaster/autovacuum.c:2326 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "autovacuum : suppression de la table temporaire orpheline « %s.%s.%s »" + +#: postmaster/autovacuum.c:2555 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "VACUUM automatique de la table « %s.%s.%s »" + +#: postmaster/autovacuum.c:2558 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "ANALYZE automatique de la table « %s.%s.%s »" + +#: postmaster/autovacuum.c:2751 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "traitement de l'enregistrement de travail pour la relation « %s.%s.%s »" + +#: postmaster/autovacuum.c:3438 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "autovacuum non démarré à cause d'une mauvaise configuration" + +#: postmaster/autovacuum.c:3439 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "Activez l'option « track_counts »." + +#: postmaster/bgworker.c:256 +#, c-format +msgid "inconsistent background worker state (max_worker_processes=%d, total_slots=%d)" +msgstr "" + +#: postmaster/bgworker.c:661 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "processus en tâche de fond « %s » : doit se lier à la mémoire partagée pour pouvoir demander une connexion à une base" + +#: postmaster/bgworker.c:670 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "processus en tâche de fond « %s » : ne peut pas réclamer un accès à la base s'il démarre au lancement du postmaster" + +#: postmaster/bgworker.c:684 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "processus en tâche de fond « %s »: intervalle de redémarrage invalide" + +#: postmaster/bgworker.c:699 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "processus en tâche de fond « %s »: les processus parallélisés ne sont peut-être pas être configurés pour redémarrer" + +#: postmaster/bgworker.c:723 tcop/postgres.c:3188 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "arrêt du processus en tâche de fond « %s » suite à la demande de l'administrateur" + +#: postmaster/bgworker.c:904 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "processus en tâche de fond « %s » : doit être listé dans shared_preload_libraries" + +#: postmaster/bgworker.c:916 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "processus en tâche de fond « %s » : seuls les processus en tâche de fond dynamiques peuvent demander des notifications" + +#: postmaster/bgworker.c:931 +#, c-format +msgid "too many background workers" +msgstr "trop de processus en tâche de fond" + +#: postmaster/bgworker.c:932 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "Un maximum de %d processus en tâche de fond peut être enregistré avec la configuration actuelle." +msgstr[1] "Un maximum de %d processus en tâche de fond peuvent être enregistrés avec la configuration actuelle." + +#: postmaster/bgworker.c:936 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "Considérez l'augmentation du paramètre « max_worker_processes »." + +#: postmaster/checkpointer.c:428 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "" +"les points de vérification (checkpoints) arrivent trop fréquemment\n" +"(toutes les %d seconde)" +msgstr[1] "" +"les points de vérification (checkpoints) arrivent trop fréquemment\n" +"(toutes les %d secondes)" + +#: postmaster/checkpointer.c:432 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "Considérez l'augmentation du paramètre « max_wal_size »." + +#: postmaster/checkpointer.c:1056 +#, c-format +msgid "checkpoint request failed" +msgstr "échec de la demande de point de vérification" + +#: postmaster/checkpointer.c:1057 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "" +"Consultez les messages récents du serveur dans les journaux applicatifs pour\n" +"plus de détails." + +#: postmaster/pgarch.c:365 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode activé, cependant archive_command n'est pas configuré" + +#: postmaster/pgarch.c:387 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "supprimé le fichier de statut d'archivage orphelin « %s »" + +#: postmaster/pgarch.c:397 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "la suppression du fichier de statut d'archive orphelin « %s » a échoué trop de fois, une nouvelle tentative aura lieu plus tard" + +#: postmaster/pgarch.c:433 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "l'archivage du journal de transactions « %s » a échoué trop de fois, nouvelle tentative repoussée" + +#: postmaster/pgarch.c:534 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "échec de la commande d'archivage avec un code de retour %d" + +#: postmaster/pgarch.c:536 postmaster/pgarch.c:546 postmaster/pgarch.c:552 postmaster/pgarch.c:561 +#, c-format +msgid "The failed archive command was: %s" +msgstr "La commande d'archivage qui a échoué était : %s" + +#: postmaster/pgarch.c:543 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "la commande d'archivage a été terminée par l'exception 0x%X" + +#: postmaster/pgarch.c:545 postmaster/postmaster.c:3724 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "" +"Voir le fichier d'en-tête C « ntstatus.h » pour une description de la valeur\n" +"hexadécimale." + +#: postmaster/pgarch.c:550 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "la commande d'archivage a été terminée par le signal %d : %s" + +#: postmaster/pgarch.c:559 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "la commande d'archivage a quitté avec le statut non reconnu %d" + +#: postmaster/pgstat.c:417 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "n'a pas pu résoudre « localhost » : %s" + +#: postmaster/pgstat.c:440 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "nouvelle tentative avec une autre adresse pour le récupérateur de statistiques" + +#: postmaster/pgstat.c:449 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "n'a pas pu créer la socket pour le récupérateur de statistiques : %m" + +#: postmaster/pgstat.c:461 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "n'a pas pu lier la socket au récupérateur de statistiques : %m" + +#: postmaster/pgstat.c:472 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "n'a pas pu obtenir l'adresse de la socket du récupérateur de statistiques : %m" + +#: postmaster/pgstat.c:488 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "n'a pas pu connecter la socket au récupérateur de statistiques : %m" + +#: postmaster/pgstat.c:509 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "" +"n'a pas pu envoyer le message de tests sur la socket du récupérateur de\n" +"statistiques : %m" + +#: postmaster/pgstat.c:535 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "échec du select() dans le récupérateur de statistiques : %m" + +#: postmaster/pgstat.c:550 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "" +"le message de test n'a pas pu arriver sur la socket du récupérateur de\n" +"statistiques : %m" + +#: postmaster/pgstat.c:565 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "" +"n'a pas pu recevoir le message de tests sur la socket du récupérateur de\n" +"statistiques : %m" + +#: postmaster/pgstat.c:575 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "" +"transmission incorrecte du message de tests sur la socket du récupérateur de\n" +"statistiques" + +#: postmaster/pgstat.c:598 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "" +"n'a pas pu initialiser la socket du récupérateur de statistiques dans le mode\n" +"non bloquant : %m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "" +"désactivation du récupérateur de statistiques à cause du manque de socket\n" +"fonctionnel" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "" +"n'a pas pu lancer le processus fils correspondant au récupérateur de\n" +"statistiques : %m" + +#: postmaster/pgstat.c:1459 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "cible reset non reconnu : « %s »" + +#: postmaster/pgstat.c:1460 +#, c-format +msgid "Target must be \"archiver\", \"bgwriter\" or \"wal\"." +msgstr "La cible doit être « archiver », « bgwriter » ou « wal »." + +#: postmaster/pgstat.c:3298 +#, c-format +msgid "could not read statistics message: %m" +msgstr "n'a pas pu lire le message des statistiques : %m" + +#: postmaster/pgstat.c:3644 postmaster/pgstat.c:3829 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier temporaire des statistiques « %s » : %m" + +#: postmaster/pgstat.c:3739 postmaster/pgstat.c:3874 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "n'a pas pu écrire le fichier temporaire des statistiques « %s » : %m" + +#: postmaster/pgstat.c:3748 postmaster/pgstat.c:3883 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "n'a pas pu fermer le fichier temporaire des statistiques « %s » : %m" + +#: postmaster/pgstat.c:3756 postmaster/pgstat.c:3891 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "" +"n'a pas pu renommer le fichier temporaire des statistiques « %s » en\n" +"« %s » : %m" + +#: postmaster/pgstat.c:3989 postmaster/pgstat.c:4255 postmaster/pgstat.c:4412 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier de statistiques « %s » : %m" + +#: postmaster/pgstat.c:4001 postmaster/pgstat.c:4011 postmaster/pgstat.c:4032 postmaster/pgstat.c:4043 postmaster/pgstat.c:4054 postmaster/pgstat.c:4076 postmaster/pgstat.c:4091 postmaster/pgstat.c:4161 postmaster/pgstat.c:4192 postmaster/pgstat.c:4267 postmaster/pgstat.c:4287 postmaster/pgstat.c:4305 postmaster/pgstat.c:4321 postmaster/pgstat.c:4339 postmaster/pgstat.c:4355 postmaster/pgstat.c:4424 postmaster/pgstat.c:4436 postmaster/pgstat.c:4448 postmaster/pgstat.c:4459 postmaster/pgstat.c:4470 postmaster/pgstat.c:4495 postmaster/pgstat.c:4522 postmaster/pgstat.c:4535 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "fichier de statistiques « %s » corrompu" + +#: postmaster/pgstat.c:4644 +#, c-format +msgid "statistics collector's time %s is later than backend local time %s" +msgstr "l'heure du collecteur de statistiques %s est plus avancé que l'heure locale du processus serveur %s" + +#: postmaster/pgstat.c:4667 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "" +"utilise de vieilles statistiques à la place des actuelles car le collecteur de\n" +"statistiques ne répond pas" + +#: postmaster/pgstat.c:4794 +#, c-format +msgid "stats_timestamp %s is later than collector's time %s for database %u" +msgstr "stats_timestamp %s est plus avancé que l'heure du collecteur %s pour la base de données %u" + +#: postmaster/pgstat.c:5004 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "" +"corruption de la table hachée de la base de données lors du lancement\n" +"--- annulation" + +#: postmaster/postmaster.c:745 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s : argument invalide pour l'option -f : « %s »\n" + +#: postmaster/postmaster.c:824 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s : argument invalide pour l'option -t : « %s »\n" + +#: postmaster/postmaster.c:875 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s : argument invalide : « %s »\n" + +#: postmaster/postmaster.c:917 +#, c-format +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s : superuser_reserved_connections (%d) doit être inférieur à max_connections (%d)\n" + +#: postmaster/postmaster.c:924 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "L'archivage des journaux de transactions ne peut pas être activé quand wal_level vaut « minimal »" + +#: postmaster/postmaster.c:927 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "l'envoi d'un flux de transactions (max_wal_senders > 0) nécessite que le paramètre wal_level à « replica » ou « logical »" + +#: postmaster/postmaster.c:935 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s : tables datetoken invalide, merci de corriger\n" + +#: postmaster/postmaster.c:1052 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "n'a pas pu créer un port de terminaison I/O pour la queue" + +#: postmaster/postmaster.c:1117 +#, c-format +msgid "ending log output to stderr" +msgstr "arrêt des traces sur stderr" + +#: postmaster/postmaster.c:1118 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "Les traces suivantes iront sur « %s »." + +#: postmaster/postmaster.c:1129 +#, c-format +msgid "starting %s" +msgstr "démarrage de %s" + +#: postmaster/postmaster.c:1158 postmaster/postmaster.c:1257 utils/init/miscinit.c:1627 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "syntaxe de liste invalide pour le paramètre « %s »" + +#: postmaster/postmaster.c:1189 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "n'a pas pu créer le socket d'écoute pour « %s »" + +#: postmaster/postmaster.c:1195 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "n'a pas pu créer de socket TCP/IP" + +#: postmaster/postmaster.c:1227 +#, c-format +msgid "DNSServiceRegister() failed: error code %ld" +msgstr "échec de DNSServiceRegister() : code d'erreur %ld" + +#: postmaster/postmaster.c:1279 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "n'a pas pu créer la socket de domaine Unix dans le répertoire « %s »" + +#: postmaster/postmaster.c:1285 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "n'a pas pu créer les sockets de domaine Unix" + +#: postmaster/postmaster.c:1297 +#, c-format +msgid "no socket created for listening" +msgstr "pas de socket créé pour l'écoute" + +#: postmaster/postmaster.c:1328 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s : n'a pas pu modifier les droits du fichier PID externe « %s » : %s\n" + +#: postmaster/postmaster.c:1332 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s : n'a pas pu écrire le fichier PID externe « %s » : %s\n" + +#: postmaster/postmaster.c:1365 utils/init/postinit.c:216 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "n'a pas pu charger pg_hba.conf" + +#: postmaster/postmaster.c:1391 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "le postmaster est devenu multithreadé lors du démarrage" + +#: postmaster/postmaster.c:1392 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "Configurez la variable d'environnement LC_ALL avec une locale valide." + +#: postmaster/postmaster.c:1487 +#, c-format +msgid "%s: could not locate my own executable path" +msgstr "%s : n'a pas pu localiser le chemin de mon propre exécutable" + +#: postmaster/postmaster.c:1494 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s : n'a pas pu localiser l'exécutable postgres correspondant" + +#: postmaster/postmaster.c:1517 utils/misc/tzparser.c:340 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "Ceci peut indiquer une installation PostgreSQL incomplète, ou que le fichier « %s » a été déplacé." + +#: postmaster/postmaster.c:1544 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s : n'a pas pu trouver le système de bases de données\n" +"S'attendait à le trouver dans le répertoire « %s »,\n" +"mais n'a pas réussi à ouvrir le fichier « %s »: %s\n" + +#: postmaster/postmaster.c:1721 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "échec de select() dans postmaster : %m" + +#: postmaster/postmaster.c:1857 +#, c-format +msgid "issuing SIGKILL to recalcitrant children" +msgstr "exécution de SIGKILL pour les processus fils récalcitrants" + +#: postmaster/postmaster.c:1878 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "forçage d'un arrêt immédiat car le fichier de verrou du répertoire de données est invalide" + +#: postmaster/postmaster.c:1981 postmaster/postmaster.c:2009 +#, c-format +msgid "incomplete startup packet" +msgstr "paquet de démarrage incomplet" + +#: postmaster/postmaster.c:1993 +#, c-format +msgid "invalid length of startup packet" +msgstr "longueur invalide du paquet de démarrage" + +#: postmaster/postmaster.c:2048 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "échec lors de l'envoi de la réponse de négotiation SSL : %m" + +#: postmaster/postmaster.c:2080 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "échec lors de l'envoi de la réponse à la négociation GSSAPI : %m" + +#: postmaster/postmaster.c:2110 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "protocole frontal %u.%u non supporté : le serveur supporte de %u.0 à %u.%u" + +#: postmaster/postmaster.c:2174 utils/misc/guc.c:7112 utils/misc/guc.c:7148 utils/misc/guc.c:7218 utils/misc/guc.c:8550 utils/misc/guc.c:11506 utils/misc/guc.c:11547 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "valeur invalide pour le paramètre « %s » : « %s »" + +#: postmaster/postmaster.c:2177 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "Les valeurs valides sont : « false », « 0 », « true », « 1 », « database »." + +#: postmaster/postmaster.c:2222 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "" +"configuration invalide du paquet de démarrage : terminaison attendue comme\n" +"dernier octet" + +#: postmaster/postmaster.c:2239 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "aucun nom d'utilisateur PostgreSQL n'a été spécifié dans le paquet de démarrage" + +#: postmaster/postmaster.c:2303 +#, c-format +msgid "the database system is starting up" +msgstr "le système de bases de données se lance" + +#: postmaster/postmaster.c:2309 +#, c-format +msgid "the database system is not yet accepting connections" +msgstr "le système de bases de données n'accepte pas encore de connexions" + +#: postmaster/postmaster.c:2310 +#, c-format +msgid "Consistent recovery state has not been yet reached." +msgstr "L'état de restauration cohérent n'a pas encore été atteint." + +#: postmaster/postmaster.c:2314 +#, c-format +msgid "the database system is not accepting connections" +msgstr "le système de bases de données n'accepte pas de connexions" + +#: postmaster/postmaster.c:2315 +#, c-format +msgid "Hot standby mode is disabled." +msgstr "Le mode Hot Standby est désactivé" + +#: postmaster/postmaster.c:2320 +#, c-format +msgid "the database system is shutting down" +msgstr "le système de base de données s'arrête" + +#: postmaster/postmaster.c:2325 +#, c-format +msgid "the database system is in recovery mode" +msgstr "le système de bases de données est en cours de restauration" + +#: postmaster/postmaster.c:2330 storage/ipc/procarray.c:464 storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:361 +#, c-format +msgid "sorry, too many clients already" +msgstr "désolé, trop de clients sont déjà connectés" + +#: postmaster/postmaster.c:2420 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "mauvaise clé dans la demande d'annulation pour le processus %d" + +#: postmaster/postmaster.c:2432 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "le PID %d dans la demande d'annulation ne correspond à aucun processus" + +#: postmaster/postmaster.c:2686 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "a reçu SIGHUP, rechargement des fichiers de configuration" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2712 postmaster/postmaster.c:2716 +#, c-format +msgid "%s was not reloaded" +msgstr "%s n'a pas été rechargé" + +#: postmaster/postmaster.c:2726 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "la configuration SSL n'a pas été rechargée" + +#: postmaster/postmaster.c:2782 +#, c-format +msgid "received smart shutdown request" +msgstr "a reçu une demande d'arrêt intelligent" + +#: postmaster/postmaster.c:2828 +#, c-format +msgid "received fast shutdown request" +msgstr "a reçu une demande d'arrêt rapide" + +#: postmaster/postmaster.c:2846 +#, c-format +msgid "aborting any active transactions" +msgstr "annulation des transactions actives" + +#: postmaster/postmaster.c:2870 +#, c-format +msgid "received immediate shutdown request" +msgstr "a reçu une demande d'arrêt immédiat" + +#: postmaster/postmaster.c:2947 +#, c-format +msgid "shutdown at recovery target" +msgstr "arrêt sur la cible de restauration" + +#: postmaster/postmaster.c:2965 postmaster/postmaster.c:3001 +msgid "startup process" +msgstr "processus de lancement" + +#: postmaster/postmaster.c:2968 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "annulation du démarrage à cause d'un échec dans le processus de lancement" + +#: postmaster/postmaster.c:3043 +#, c-format +msgid "database system is ready to accept connections" +msgstr "le système de bases de données est prêt pour accepter les connexions" + +#: postmaster/postmaster.c:3064 +msgid "background writer process" +msgstr "processus d'écriture en tâche de fond" + +#: postmaster/postmaster.c:3118 +msgid "checkpointer process" +msgstr "processus checkpointer" + +#: postmaster/postmaster.c:3134 +msgid "WAL writer process" +msgstr "processus d'écriture des journaux de transaction" + +#: postmaster/postmaster.c:3149 +msgid "WAL receiver process" +msgstr "processus de réception des journaux de transaction" + +#: postmaster/postmaster.c:3164 +msgid "autovacuum launcher process" +msgstr "processus de lancement de l'autovacuum" + +#: postmaster/postmaster.c:3182 +msgid "archiver process" +msgstr "processus d'archivage" + +#: postmaster/postmaster.c:3197 +msgid "statistics collector process" +msgstr "processus de récupération des statistiques" + +#: postmaster/postmaster.c:3211 +msgid "system logger process" +msgstr "processus des journaux applicatifs" + +#: postmaster/postmaster.c:3275 +#, c-format +msgid "background worker \"%s\"" +msgstr "processus en tâche de fond « %s »" + +#: postmaster/postmaster.c:3359 postmaster/postmaster.c:3379 postmaster/postmaster.c:3386 postmaster/postmaster.c:3404 +msgid "server process" +msgstr "processus serveur" + +#: postmaster/postmaster.c:3458 +#, c-format +msgid "terminating any other active server processes" +msgstr "arrêt des autres processus serveur actifs" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3711 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) a quitté avec le code de sortie %d" + +#: postmaster/postmaster.c:3713 postmaster/postmaster.c:3725 postmaster/postmaster.c:3735 postmaster/postmaster.c:3746 +#, c-format +msgid "Failed process was running: %s" +msgstr "Le processus qui a échoué exécutait : %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3722 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) a été arrêté par l'exception 0x%X" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3732 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) a été arrêté par le signal %d : %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3744 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) a quitté avec le statut inattendu %d" + +#: postmaster/postmaster.c:3959 +#, c-format +msgid "abnormal database system shutdown" +msgstr "le système de base de données a été arrêté anormalement" + +#: postmaster/postmaster.c:3997 +#, c-format +msgid "shutting down due to startup process failure" +msgstr "arrêt à cause d'un échec du processus startup" + +#: postmaster/postmaster.c:4003 +#, c-format +msgid "shutting down because restart_after_crash is off" +msgstr "" + +#: postmaster/postmaster.c:4015 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "tous les processus serveur sont arrêtés ; réinitialisation" + +#: postmaster/postmaster.c:4189 postmaster/postmaster.c:5548 postmaster/postmaster.c:5939 +#, c-format +msgid "could not generate random cancel key" +msgstr "n'a pas pu générer la clé d'annulation aléatoire" + +#: postmaster/postmaster.c:4243 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "n'a pas pu lancer le nouveau processus fils pour la connexion : %m" + +#: postmaster/postmaster.c:4285 +msgid "could not fork new process for connection: " +msgstr "n'a pas pu lancer le nouveau processus fils pour la connexion : " + +#: postmaster/postmaster.c:4391 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "connexion reçue : hôte=%s port=%s" + +#: postmaster/postmaster.c:4396 +#, c-format +msgid "connection received: host=%s" +msgstr "connexion reçue : hôte=%s" + +#: postmaster/postmaster.c:4639 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "n'a pas pu exécuter le processus serveur « %s » : %m" + +#: postmaster/postmaster.c:4697 +#, c-format +msgid "could not create backend parameter file mapping: error code %lu" +msgstr "n'a pas pu créer le lien vers le fichier de paramètres du processus serveur : code d'erreur %lu" + +#: postmaster/postmaster.c:4706 +#, c-format +msgid "could not map backend parameter memory: error code %lu" +msgstr "n'a pas pu mapper la mémoire des paramètres du processus serveur : code d'erreur %lu" + +#: postmaster/postmaster.c:4733 +#, c-format +msgid "subprocess command line too long" +msgstr "ligne de commande du sous-processus trop longue" + +#: postmaster/postmaster.c:4751 +#, c-format +msgid "CreateProcess() call failed: %m (error code %lu)" +msgstr "échec de l'appel à CreateProcess() : %m (code d'erreur %lu)" + +#: postmaster/postmaster.c:4778 +#, c-format +msgid "could not unmap view of backend parameter file: error code %lu" +msgstr "" + +#: postmaster/postmaster.c:4782 +#, c-format +msgid "could not close handle to backend parameter file: error code %lu" +msgstr "n'a pas pu fermer le lien vers le fichier de paramètres du processus serveur : code d'erreur %lu" + +#: postmaster/postmaster.c:4804 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "abandon après trop de tentatives pour réserver la mémoire partagée" + +#: postmaster/postmaster.c:4805 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Ceci pourrait être causé par un logiciel ASLR ou un antivirus." + +#: postmaster/postmaster.c:4995 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "la configuration SSL n'a pas pu être chargée dans le processus fils" + +#: postmaster/postmaster.c:5121 +#, c-format +msgid "Please report this to <%s>." +msgstr "Merci de signaler ceci à <%s>." + +#: postmaster/postmaster.c:5208 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "le système de bases de données est prêt pour accepter les connexions en lecture seule" + +#: postmaster/postmaster.c:5472 +#, c-format +msgid "could not fork startup process: %m" +msgstr "n'a pas pu lancer le processus fils de démarrage : %m" + +#: postmaster/postmaster.c:5476 +#, c-format +msgid "could not fork archiver process: %m" +msgstr "n'a pas pu créer un processus fils d'archivage des journaux de transactions : %m" + +#: postmaster/postmaster.c:5480 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "" +"n'a pas pu créer un processus fils du processus d'écriture en tâche de\n" +"fond : %m" + +#: postmaster/postmaster.c:5484 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "n'a pas pu créer le processus checkpointer : %m" + +#: postmaster/postmaster.c:5488 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "" +"n'a pas pu créer un processus fils du processus d'écriture des journaux de\n" +"transaction : %m" + +#: postmaster/postmaster.c:5492 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "" +"n'a pas pu créer un processus fils de réception des journaux de\n" +"transactions : %m" + +#: postmaster/postmaster.c:5496 +#, c-format +msgid "could not fork process: %m" +msgstr "n'a pas pu lancer le processus fils : %m" + +#: postmaster/postmaster.c:5697 postmaster/postmaster.c:5720 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "pré-requis de la connexion à la base non indiqué lors de l'enregistrement" + +#: postmaster/postmaster.c:5704 postmaster/postmaster.c:5727 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "mode de traitement invalide dans le processus en tâche de fond" + +#: postmaster/postmaster.c:5812 +#, c-format +msgid "could not fork worker process: %m" +msgstr "n'a pas pu créer un processus fils du processus en tâche de fond : %m" + +#: postmaster/postmaster.c:5925 +#, c-format +msgid "no slot available for new worker process" +msgstr "aucun slot disponible pour le nouveau processus worker" + +#: postmaster/postmaster.c:6259 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "n'a pas pu dupliquer la socket %d pour le serveur : code d'erreur %d" + +#: postmaster/postmaster.c:6291 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "n'a pas pu créer la socket héritée : code d'erreur %d\n" + +#: postmaster/postmaster.c:6320 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "n'a pas pu ouvrir le fichier des variables moteurs « %s » : %s\n" + +#: postmaster/postmaster.c:6327 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "n'a pas pu lire le fichier de configuration serveur « %s » : %s\n" + +#: postmaster/postmaster.c:6336 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "n'a pas pu supprimer le fichier « %s » : %s\n" + +#: postmaster/postmaster.c:6353 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "" +"n'a pas pu exécuter \"map\" la vue des variables serveurs : code\n" +"d'erreur %lu\n" + +#: postmaster/postmaster.c:6362 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "" +"n'a pas pu exécuter \"unmap\" sur la vue des variables serveurs : code\n" +"d'erreur %lu\n" + +#: postmaster/postmaster.c:6369 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "" +"n'a pas pu fermer le lien vers les variables des paramètres du serveur :\n" +"code d'erreur %lu\n" + +#: postmaster/postmaster.c:6546 +#, c-format +msgid "could not read exit code for process\n" +msgstr "n'a pas pu lire le code de sortie du processus\n" + +#: postmaster/postmaster.c:6551 +#, c-format +msgid "could not post child completion status\n" +msgstr "n'a pas pu poster le statut de fin de l'enfant\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "n'a pas pu lire à partir du tube des journaux applicatifs : %m" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "n'a pas pu créer un tube pour syslog : %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "n'a pas pu lancer le processus des journaux applicatifs : %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "redirection des traces vers le processus de récupération des traces" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "Les prochaines traces apparaîtront dans le répertoire « %s »." + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "n'a pas pu rediriger la sortie (stdout) : %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "n'a pas pu rediriger la sortie des erreurs (stderr) : %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "n'a pas pu écrire dans le journal applicatif : %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier applicatif « %s » : %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "désactivation de la rotation automatique (utilisez SIGHUP pour la réactiver)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour une expression rationnelle" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "les collationnements non déterministes ne sont pas supportés pour les expressions rationnelles" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "timeline %u invalide" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "emplacement de démarrage du flux de réplication invalide" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "chaîne entre guillemets non terminée" + +#: replication/backup_manifest.c:255 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "timeline de fin attendue %u mais a trouvé la timeline %u" + +#: replication/backup_manifest.c:272 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "timeline de début attendue %u mais a trouvé la timeline %u" + +#: replication/backup_manifest.c:299 +#, c-format +msgid "start timeline %u not found in history of timeline %u" +msgstr "timeline de début %u non trouvée dans l'historique de la timeline %u" + +#: replication/backup_manifest.c:352 +#, c-format +msgid "could not rewind temporary file" +msgstr "n'a pas pu revenir au début du fichier temporaire" + +#: replication/backup_manifest.c:379 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "n'a pas pu lire le fichier temporaire : %m" + +#: replication/basebackup.c:546 +#, c-format +msgid "could not find any WAL files" +msgstr "n'a pas pu trouver un seul fichier WAL" + +#: replication/basebackup.c:561 replication/basebackup.c:577 replication/basebackup.c:586 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "n'a pas pu trouver le fichier WAL « %s »" + +#: replication/basebackup.c:629 replication/basebackup.c:659 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "taille du fichier WAL « %s » inattendue" + +#: replication/basebackup.c:644 replication/basebackup.c:1771 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "la sauvegarde de base n'a pas pu envoyer les données, annulation de la sauvegarde" + +#: replication/basebackup.c:722 +#, c-format +msgid "%lld total checksum verification failure" +msgid_plural "%lld total checksum verification failures" +msgstr[0] "%lld erreur de vérifications des sommes de contrôle au total" +msgstr[1] "%lld erreurs de vérifications des sommes de contrôle au total" + +#: replication/basebackup.c:729 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "échec de la véffication de somme de controle durant la sauvegarde de base" + +#: replication/basebackup.c:789 replication/basebackup.c:798 replication/basebackup.c:807 replication/basebackup.c:816 replication/basebackup.c:825 replication/basebackup.c:836 replication/basebackup.c:853 replication/basebackup.c:862 replication/basebackup.c:874 replication/basebackup.c:898 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "option « %s » dupliquée" + +#: replication/basebackup.c:842 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d est en dehors des limites valides pour le paramètre « %s » (%d .. %d)" + +#: replication/basebackup.c:887 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "option de manifeste non reconnue : « %s »" + +#: replication/basebackup.c:903 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "algorithme de somme de contrôle inconnu : « %s »" + +#: replication/basebackup.c:918 +#, c-format +msgid "manifest checksums require a backup manifest" +msgstr "les sommes de contrôles du manifeste nécessitent un manifeste de sauvegarde" + +#: replication/basebackup.c:1519 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "ignore le fichier spécial « %s »" + +#: replication/basebackup.c:1640 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "numéro de segment %d invalide dans le fichier « %s »" + +#: replication/basebackup.c:1678 +#, c-format +msgid "could not verify checksum in file \"%s\", block %u: read buffer size %d and page size %d differ" +msgstr "n'a pas pu vérifier la somme de contrôle dans le fichier « %s », bloc %u : la taille de tampon de lecture %d et la taille de bloc %d diffèrent" + +#: replication/basebackup.c:1751 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated %X but expected %X" +msgstr "échec de la vérification de la somme de contrôle dans le fichier « %s », bloc %u : calculé %X, mais attendu %X" + +#: replication/basebackup.c:1758 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "les prochains échec de vérification de somme de contrôle dans le fichier « %s » ne seront pas reportés" + +#: replication/basebackup.c:1816 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "le fichier « %s » a un total de %d échec de vérification de somme de contrôle" +msgstr[1] "le fichier « %s » a un total de %d échecs de vérification de somme de contrôle" + +#: replication/basebackup.c:1852 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "nom du fichier trop long pour le format tar : « %s »" + +#: replication/basebackup.c:1857 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "cible du lien symbolique trop longue pour le format tar : nom de fichier « %s », cible « %s »" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, c-format +msgid "could not clear search path: %s" +msgstr "n'a pas pu effacer le search_path : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:256 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "syntaxe de la chaîne de connexion invalide : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:282 +#, c-format +msgid "could not parse connection string: %s" +msgstr "n'a pas pu analyser la chaîne de connexion : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:355 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "" +"n'a pas pu recevoir l'identifiant du système de bases de données et\n" +"l'identifiant de la timeline à partir du serveur principal : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:367 replication/libpqwalreceiver/libpqwalreceiver.c:601 +#, c-format +msgid "invalid response from primary server" +msgstr "réponse invalide du serveur principal" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:368 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "" +"N'a pas pu identifier le système : a récupéré %d lignes et %d champs,\n" +"attendait %d lignes et %d champs (ou plus)." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:444 replication/libpqwalreceiver/libpqwalreceiver.c:451 replication/libpqwalreceiver/libpqwalreceiver.c:481 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "n'a pas pu démarrer l'envoi des WAL : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "n'a pas pu transmettre le message de fin d'envoi de flux au primaire : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:528 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "ensemble de résultats inattendu après la fin du flux de réplication" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:543 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "erreur lors de l'arrêt de la copie en flux : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:553 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "erreur lors de la lecture de la commande de flux : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:562 replication/libpqwalreceiver/libpqwalreceiver.c:800 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "résultat inattendu après CommandComplete : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:589 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "n'a pas pu recevoir le fichier historique à partir du serveur principal : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:602 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "Attendait 1 ligne avec 2 champs, a obtenu %d lignes avec %d champs." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:763 replication/libpqwalreceiver/libpqwalreceiver.c:816 replication/libpqwalreceiver/libpqwalreceiver.c:823 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "n'a pas pu recevoir des données du flux de WAL : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:843 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "n'a pas pu transmettre les données au flux WAL : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:897 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "n'a pas pu créer le slot de réplication « %s » : %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:943 +#, c-format +msgid "invalid query response" +msgstr "réponse à la requête invalide" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:944 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "Attendait %d champs, a obtenu %d champs." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1014 +#, c-format +msgid "the query interface requires a database connection" +msgstr "l'interface de la requête requiert une connexion à une base" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1045 +msgid "empty query" +msgstr "requête vide" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1051 +msgid "unexpected pipeline mode" +msgstr "mode pipeline inattendu" + +#: replication/logical/launcher.c:286 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "ne peut pas démarrer les processus worker de la réplication logique quand max_replication_slots = 0" + +#: replication/logical/launcher.c:366 +#, c-format +msgid "out of logical replication worker slots" +msgstr "plus de slots de processus worker pour la réplication logique" + +#: replication/logical/launcher.c:367 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "Vous pourriez avoir besoin d'augmenter max_logical_replication_workers." + +#: replication/logical/launcher.c:422 +#, c-format +msgid "out of background worker slots" +msgstr "plus de slots de processus en tâche de fond" + +#: replication/logical/launcher.c:423 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "Vous pourriez avoir besoin d'augmenter max_worker_processes." + +#: replication/logical/launcher.c:577 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "le slot %d du processus de réplication logique est vide, ne peut pas s'y attacher" + +#: replication/logical/launcher.c:586 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "le slot %d du processus de réplication logique est déjà utilisé par un autre processus, ne peut pas s'attacher" + +#: replication/logical/logical.c:115 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "le décodage logique requiert wal_level >= logical" + +#: replication/logical/logical.c:120 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "le décodage logique requiert une connexion à une base" + +#: replication/logical/logical.c:138 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "le décodage logique ne peut pas être utilisé lors de la restauration" + +#: replication/logical/logical.c:347 replication/logical/logical.c:499 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "ne peut pas utiliser un slot de réplication physique pour le décodage logique" + +#: replication/logical/logical.c:352 replication/logical/logical.c:504 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "le slot de réplication « %s » n'a pas été créé dans cette base de données" + +#: replication/logical/logical.c:359 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "ne peut pas créer un slot de réplication logique dans une transaction qui a fait des écritures" + +#: replication/logical/logical.c:549 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "début du décodage logique pour le slot « %s »" + +#: replication/logical/logical.c:551 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Envoi des transactions validées après %X/%X, lecture des journaux à partir de %X/%X." + +#: replication/logical/logical.c:696 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "slot « %s », plugin de sortie « %s », dans la fonction d'appel %s, associé au LSN %X/%X" + +#: replication/logical/logical.c:702 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "slot « %s », plugin de sortie « %s », dans la fonction d'appel %s" + +#: replication/logical/logical.c:868 +#, c-format +msgid "logical replication at prepare time requires begin_prepare_cb callback" +msgstr "la réplication logique lors de la préparation requiert la fonction begin_prepare_cb" + +#: replication/logical/logical.c:911 +#, c-format +msgid "logical replication at prepare time requires prepare_cb callback" +msgstr "la réplication logique lors de la préparation requiert la fonction prepare_cb" + +#: replication/logical/logical.c:954 +#, c-format +msgid "logical replication at prepare time requires commit_prepared_cb callback" +msgstr "la réplication logique lors de la préparation requiert la fonction commit_prepared_cb" + +#: replication/logical/logical.c:998 +#, c-format +msgid "logical replication at prepare time requires rollback_prepared_cb callback" +msgstr "la réplication logique lors de la préparation requiert la fonction rollback_prepared_cb" + +#: replication/logical/logical.c:1220 +#, c-format +msgid "logical streaming requires a stream_start_cb callback" +msgstr "le flux logique requiert une fonction stream_start_cb" + +#: replication/logical/logical.c:1266 +#, c-format +msgid "logical streaming requires a stream_stop_cb callback" +msgstr "le flux logique requiert une fonction stream_stop_cb" + +#: replication/logical/logical.c:1305 +#, c-format +msgid "logical streaming requires a stream_abort_cb callback" +msgstr "le flux logique requiert une fonction stream_abort_cb" + +#: replication/logical/logical.c:1348 +#, c-format +msgid "logical streaming at prepare time requires a stream_prepare_cb callback" +msgstr "la réplication logique lors de la préparation requiert la fonction stream_prepare_cb" + +#: replication/logical/logical.c:1387 +#, c-format +msgid "logical streaming requires a stream_commit_cb callback" +msgstr "la réplication logique requiert la fonction stream_commit_cb" + +#: replication/logical/logical.c:1433 +#, c-format +msgid "logical streaming requires a stream_change_cb callback" +msgstr "le flux logique requiert une fonction stream_change_cb" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "" +"doit être un superutilisateur ou un rôle ayant l'attribut de réplication\n" +"pour utiliser des slots de réplication" + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "le nom du slot ne doit pas être NULL" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "le tableau options ne doit pas être NULL" + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "le tableau doit avoir une dimension" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "le tableau ne doit pas contenir de valeurs NULL" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "le tableau doit avoir un nombre pair d'éléments" + +#: replication/logical/logicalfuncs.c:251 +#, c-format +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "ne peut plus obtenir de modifications à partir du slot de réplication « %s »" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:650 +#, c-format +msgid "This slot has never previously reserved WAL, or it has been invalidated." +msgstr "Ce slot n'a jamais réservé de WAL précédemment, ou a été invalidé." + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "le plugin de sortie « %s » pour le décodage logique produit une sortie binaire, mais la fonction « %s » attend des données texte" + +#: replication/logical/origin.c:188 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "ne peut pas lire ou manipuler une originie de réplication logique quand max_replication_slots = 0" + +#: replication/logical/origin.c:193 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "ne peut pas manipuler les origines de réplication lors d'une restauration" + +#: replication/logical/origin.c:228 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "l'origine de réplication « %s » n'existe pas" + +#: replication/logical/origin.c:319 +#, c-format +msgid "could not find free replication origin OID" +msgstr "n'a pas pu trouver d'OID d'origine de réplication libre" + +#: replication/logical/origin.c:355 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "ne peut pas supprimer l'origine de réplication d'OID %d, utilisée par le PID %d" + +#: replication/logical/origin.c:476 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "l'origine de réplication d'OID %u n'existe pas" + +#: replication/logical/origin.c:741 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "le checkpoint de réplication a le mauvais nombre magique (%u au lieu de %u)" + +#: replication/logical/origin.c:782 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "n'a pas pu trouver d'état de réplication libre, augmentez max_replication_slots" + +#: replication/logical/origin.c:790 +#, c-format +msgid "recovered replication state of node %u to %X/%X" +msgstr "restauration de l'état de réplication du nœud %u à %X/%X" + +#: replication/logical/origin.c:800 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "le point de contrôle du slot de réplication à la mauvaise somme de contrôle %u, %u attendu" + +#: replication/logical/origin.c:928 replication/logical/origin.c:1114 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "l'origine de réplication d'OID %d est déjà active pour le PID %d" + +#: replication/logical/origin.c:939 replication/logical/origin.c:1126 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "n'a pas pu trouver de slot d'état de réplication libre pour l'origine de réplication d'OID %u" + +#: replication/logical/origin.c:941 replication/logical/origin.c:1128 replication/slot.c:1840 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "Augmentez max_replication_slots et recommencez." + +#: replication/logical/origin.c:1085 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "ne peut pas configurer l'origine de réplication si une origine existe déjà" + +#: replication/logical/origin.c:1165 replication/logical/origin.c:1377 replication/logical/origin.c:1397 +#, c-format +msgid "no replication origin is configured" +msgstr "aucune origine de réplication n'est configurée" + +#: replication/logical/origin.c:1248 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "le nom d'origine de réplication « %s » est réservé" + +#: replication/logical/origin.c:1250 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "Les noms d'origine commençant par « pg_ » sont réservés." + +#: replication/logical/relation.c:248 +#, c-format +msgid "\"%s\"" +msgstr "\"%s\"" + +#: replication/logical/relation.c:251 +#, c-format +msgid ", \"%s\"" +msgstr ", \"%s\"" + +#: replication/logical/relation.c:257 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing replicated column: %s" +msgid_plural "logical replication target relation \"%s.%s\" is missing replicated columns: %s" +msgstr[0] "il manque une colonne répliquée à la relation cible de la réplication logique « %s.%s » : %s" +msgstr[1] "il manque plusieurs colonnes répliquées à la relation cible de la réplication logique « %s.%s » : %s" + +#: replication/logical/relation.c:337 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "la relation cible de la réplication logique « %s.%s » n'existe pas" + +#: replication/logical/relation.c:418 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "la relation cible « %s.%s » de réplication logique utilise des colonnes systèmes dans l'index REPLICA IDENTITY" + +#: replication/logical/reorderbuffer.c:3800 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "n'a pas pu écrire dans le fichier pour le XID %u : %m" + +#: replication/logical/reorderbuffer.c:4144 replication/logical/reorderbuffer.c:4169 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "n'a pas pu lire le fichier « reorderbuffer spill » : %m" + +#: replication/logical/reorderbuffer.c:4148 replication/logical/reorderbuffer.c:4173 +#, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "" +"n'a pas pu lire à partir du fichier « reorderbuffer spill » : a lu seulement %d octets\n" +"sur %u" + +#: replication/logical/reorderbuffer.c:4422 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "n'a pas pu supprimer le fichier « %s » pendant la suppression de pg_replslot/%s/xid* : %m" + +#: replication/logical/reorderbuffer.c:4912 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "n'a pas pu lire à partir du fichier « %s » : lu %d octets au lieu de %d octets" + +#: replication/logical/snapbuild.c:588 +#, c-format +msgid "initial slot snapshot too large" +msgstr "snapshot du slot initial trop gros" + +#: replication/logical/snapbuild.c:642 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "snapshot exporté pour le décodage logique : « %s » avec %u identifiant de transaction" +msgstr[1] "snapshot exporté pour le décodage logique : « %s » avec %u identifiants de transaction" + +#: replication/logical/snapbuild.c:1254 replication/logical/snapbuild.c:1347 replication/logical/snapbuild.c:1878 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "le décodage logique a trouvé le point de cohérence à %X/%X" + +#: replication/logical/snapbuild.c:1256 +#, c-format +msgid "There are no running transactions." +msgstr "Il n'existe pas de transactions en cours." + +#: replication/logical/snapbuild.c:1298 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "le décodage logique a trouvé le point de démarrage à %X/%X" + +#: replication/logical/snapbuild.c:1300 replication/logical/snapbuild.c:1324 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "En attente de transactions (approximativement %d) plus anciennes que %u pour terminer." + +#: replication/logical/snapbuild.c:1322 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "le décodage logique a trouvé le point de cohérence initial à %X/%X" + +#: replication/logical/snapbuild.c:1349 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Il n'existe plus d'anciennes transactions." + +#: replication/logical/snapbuild.c:1746 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "le fichier d'état snapbuild « %s » a le nombre magique: %u au lieu de %u" + +#: replication/logical/snapbuild.c:1752 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "le fichier d'état snapbuild « %s » a une version non supportée : %u au lieu de %u" + +#: replication/logical/snapbuild.c:1823 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "" +"différence de somme de contrôle pour lefichier d'état snapbuild %s :\n" +"est %u, devrait être %u" + +#: replication/logical/snapbuild.c:1880 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "Le décodage logique commencera en utilisant un snapshot sauvegardé." + +#: replication/logical/snapbuild.c:1952 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "n'a pas pu analyser le mode du fichier « %s »" + +#: replication/logical/tablesync.c:144 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "le worker de synchronisation de table en réplication logique pour la souscription « %s », table « %s », a terminé" + +#: replication/logical/tablesync.c:727 replication/logical/tablesync.c:770 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "n'a pas pu récupérer l'information sur la table « %s.%s » à partir du publieur : %s" + +#: replication/logical/tablesync.c:734 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "table « %s.%s » non trouvée sur le publieur" + +#: replication/logical/tablesync.c:858 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "n'a pas pu lancer la copie initiale du contenu de la table « %s.%s » : %s" + +#: replication/logical/tablesync.c:1059 +#, c-format +msgid "table copy could not start transaction on publisher: %s" +msgstr "la copie de table n'a pas pu démarrer la transaction sur le publieur : %s" + +#: replication/logical/tablesync.c:1107 +#, c-format +msgid "replication origin \"%s\" already exists" +msgstr "l'origine de réplication « %s » existe déjà" + +#: replication/logical/tablesync.c:1120 +#, c-format +msgid "table copy could not finish transaction on publisher: %s" +msgstr "la copie de table n'a pas pu finir la transaction sur le publieur : %s" + +#: replication/logical/worker.c:530 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "traitement des données distantes pour la relation cible « %s.%s » de réplication logique, colonne « %s », type distant %s, type local %s" + +#: replication/logical/worker.c:610 replication/logical/worker.c:739 +#, c-format +msgid "incorrect binary data format in logical replication column %d" +msgstr "format des données binaires incorrect dans la colonne de réplication logique %d" + +#: replication/logical/worker.c:1111 replication/logical/worker.c:1125 +#, c-format +msgid "could not read from streaming transaction's changes file \"%s\": %m" +msgstr "n'a pas pu lire à partir du fichier de changements de transaction en flux « %s » : %m" + +#: replication/logical/worker.c:1355 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "le publieur n'a pas envoyé la colonne d'identité du réplicat attendue par la relation cible « %s.%s » de la réplication logique" + +#: replication/logical/worker.c:1362 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "la relation cible « %s.%s » de réplication logique n'a ni un index REPLICA IDENTITY ni une clé primaire, et la relation publiée n'a pas REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:2241 +#, c-format +msgid "data stream from publisher has ended" +msgstr "le flux de données provenant du publieur s'est terminé" + +#: replication/logical/worker.c:2392 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "arrêt du processus worker de la réplication logique suite à l'expiration du délai de réplication" + +#: replication/logical/worker.c:2540 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "le processus apply de réplication logique pour la souscription « %s » s'arrêtera car la souscription a été supprimée" + +#: replication/logical/worker.c:2554 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "le processus apply de réplication logique pour la souscription « %s » s'arrêtera car la souscription a été désactivée" + +#: replication/logical/worker.c:2576 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because of a parameter change" +msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car un paramètre a été modifié" + +#: replication/logical/worker.c:2741 replication/logical/worker.c:2763 +#, c-format +msgid "could not read from streaming transaction's subxact file \"%s\": %m" +msgstr "n'a pas pu lire à partir du fichier subxact de transaction en flux « %s » : %m" + +#: replication/logical/worker.c:3122 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "le processus apply de réplication logique pour la souscription %u ne démarrera pas car la souscription a été désactivée au démarrage" + +#: replication/logical/worker.c:3134 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "le processus apply de réplication logique pour la souscription « %s » ne démarrera pas car la souscription a été désactivée au démarrage" + +#: replication/logical/worker.c:3152 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "le processus de synchronisation des tables en réplication logique pour la souscription « %s », table « %s » a démarré" + +#: replication/logical/worker.c:3156 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "le processus apply de réplication logique pour la souscription « %s » a démarré" + +#: replication/logical/worker.c:3194 +#, c-format +msgid "subscription has no replication slot set" +msgstr "la souscription n'a aucun ensemble de slot de réplication" + +#: replication/pgoutput/pgoutput.c:195 +#, c-format +msgid "invalid proto_version" +msgstr "proto_version invalide" + +#: replication/pgoutput/pgoutput.c:200 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version « %s » en dehors des limites" + +#: replication/pgoutput/pgoutput.c:217 +#, c-format +msgid "invalid publication_names syntax" +msgstr "syntaxe publication_names invalide" + +#: replication/pgoutput/pgoutput.c:287 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "le client a envoyé proto_version=%d mais nous supportons seulement le protocole %d et les protocoles antérieurs" + +#: replication/pgoutput/pgoutput.c:293 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "le client a envoyé proto_version=%d mais nous supportons seulement le protocole %d et les protocoles supérieurs" + +#: replication/pgoutput/pgoutput.c:299 +#, c-format +msgid "publication_names parameter missing" +msgstr "paramètre publication_names manquant" + +#: replication/pgoutput/pgoutput.c:312 +#, c-format +msgid "requested proto_version=%d does not support streaming, need %d or higher" +msgstr "proto_version=%d demandé, mais ne supporte par le flux, nécessite %d ou supérieur" + +#: replication/pgoutput/pgoutput.c:317 +#, c-format +msgid "streaming requested, but not supported by output plugin" +msgstr "flux demandé, mais non supporté par le plugin de sortie" + +#: replication/slot.c:180 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "le nom du slot de réplication « %s » est trop court" + +#: replication/slot.c:189 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "le nom du slot de réplication « %s » est trop long" + +#: replication/slot.c:202 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "le nom du slot de réplication « %s » contient un caractère invalide" + +#: replication/slot.c:204 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "Les noms des slots de réplication peuvent seulement contenir des lettres, des nombres et des tirets bas." + +#: replication/slot.c:258 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "le slot de réplication « %s » existe déjà" + +#: replication/slot.c:268 +#, c-format +msgid "all replication slots are in use" +msgstr "tous les slots de réplication sont utilisés" + +#: replication/slot.c:269 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Libérez un slot ou augmentez max_replication_slots." + +#: replication/slot.c:402 replication/slotfuncs.c:761 utils/adt/pgstatfuncs.c:2227 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "le slot de réplication « %s » n'existe pas" + +#: replication/slot.c:448 replication/slot.c:1018 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "le slot de réplication « %s » est actif pour le PID %d" + +#: replication/slot.c:676 replication/slot.c:1392 replication/slot.c:1775 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "n'a pas pu supprimer le répertoire « %s »" + +#: replication/slot.c:1053 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "les slots de réplications peuvent seulement être utilisés si max_replication_slots > 0" + +#: replication/slot.c:1058 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "les slots de réplication peuvent seulement être utilisés si wal_level >= replica" + +#: replication/slot.c:1237 +#, c-format +msgid "terminating process %d to release replication slot \"%s\"" +msgstr "arrêt du processus %d pour relâcher le slot de réplication « %s »" + +#: replication/slot.c:1275 +#, c-format +msgid "invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size" +msgstr "invalidation du slot « %s » parce que son restart_lsn %X/%X dépasse max_slot_wal_keep_size" + +#: replication/slot.c:1713 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "le fichier « %s » du slot de réplication a le nombre magique %u au lieu de %u" + +#: replication/slot.c:1720 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "le fichier « %s » du slot de réplication a une version %u non supportée" + +#: replication/slot.c:1727 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "le slot de réplication « %s » a une taille %u corrompue" + +#: replication/slot.c:1763 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "différence de somme de contrôle pour le fichier de slot de réplication « %s » : est %u, devrait être %u" + +#: replication/slot.c:1797 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "le slot de réplication logique « %s » existe mais, wal_level < logical" + +#: replication/slot.c:1799 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Modifiez wal_level pour valoir logical ou supérieur." + +#: replication/slot.c:1803 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "le slot de réplication physique « %s » existe mais, wal_level < replica" + +#: replication/slot.c:1805 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Modifiez wal_level pour valoir replica ou supérieur." + +#: replication/slot.c:1839 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "trop de slots de réplication actifs avant l'arrêt" + +#: replication/slotfuncs.c:626 +#, c-format +msgid "invalid target WAL LSN" +msgstr "WAL LSN cible invalide" + +#: replication/slotfuncs.c:648 +#, c-format +msgid "replication slot \"%s\" cannot be advanced" +msgstr "le slot de réplication « %s » ne peut pas être avancé" + +#: replication/slotfuncs.c:666 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "impossible d'avancer le slot de réplication vers %X/%X, le minimum est %X/%X" + +#: replication/slotfuncs.c:773 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "ne peut pas copier le slot de réplication physique « %s » en tant que slot de réplication logique" + +#: replication/slotfuncs.c:775 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "ne peut pas copier le slot de réplication logique « %s » en tant que slot de réplication physique" + +#: replication/slotfuncs.c:782 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "ne peut pas copier un slot de réplication qui n'a pas auparavant réservé de WAL" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "n'a pas pu copier le slot de réplication « %s »" + +#: replication/slotfuncs.c:861 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "Le slot de réplication source a été modifié de manière incompatible durant l'opération de copie." + +#: replication/slotfuncs.c:867 +#, c-format +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "ne peut pas copier le slot de réplication logique non terminé « %s »" + +#: replication/slotfuncs.c:869 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "Ré-essayez quand la valeur de confirmed_flush_lsn pour le slot de réplication source est valide." + +#: replication/syncrep.c:268 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "" +"annulation de l'attente pour la réplication synchrone et arrêt des connexions\n" +"suite à la demande de l'administrateur" + +#: replication/syncrep.c:269 replication/syncrep.c:286 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "" +"La transaction a déjà enregistré les données localement, mais il se peut que\n" +"cela n'ait pas été répliqué sur le serveur en standby." + +#: replication/syncrep.c:285 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "annulation de l'attente pour la réplication synchrone à la demande de l'utilisateur" + +#: replication/syncrep.c:494 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "le serveur « %s » en standby est maintenant un serveur standby synchrone de priorité %u" + +#: replication/syncrep.c:498 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "le serveur standby « %s » est maintenant un candidat dans le quorum des standbys synchrones" + +#: replication/syncrep.c:1045 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "l'analyseur du paramètre synchronous_standby_names a échoué" + +#: replication/syncrep.c:1051 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "le nombre de standbys synchrones (%d) doit être supérieur à zéro" + +#: replication/walreceiver.c:160 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "arrêt du processus walreceiver suite à la demande de l'administrateur" + +#: replication/walreceiver.c:288 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "n'a pas pu se connecter au serveur principal : %s" + +#: replication/walreceiver.c:335 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "" +"l'identifiant du système de bases de données diffère entre le serveur principal\n" +"et le serveur en attente" + +#: replication/walreceiver.c:336 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "" +"L'identifiant du serveur principal est %s, l'identifiant du serveur en attente\n" +"est %s." + +#: replication/walreceiver.c:347 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "la plus grande timeline %u du serveur principal est derrière la timeline de restauration %u" + +#: replication/walreceiver.c:401 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "démarré le flux des journaux depuis le principal à %X/%X sur la timeline %u" + +#: replication/walreceiver.c:405 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "recommence le flux WAL à %X/%X sur la timeline %u" + +#: replication/walreceiver.c:434 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "ne peut pas continuer le flux de journaux de transactions, la récupération est déjà terminée" + +#: replication/walreceiver.c:471 +#, c-format +msgid "replication terminated by primary server" +msgstr "réplication terminée par le serveur primaire" + +#: replication/walreceiver.c:472 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "Fin du WAL atteint sur la timeline %u à %X/%X." + +#: replication/walreceiver.c:561 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "arrêt du processus walreceiver suite à l'expiration du délai de réplication" + +#: replication/walreceiver.c:599 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "le serveur principal ne contient plus de WAL sur la timeline %u demandée" + +#: replication/walreceiver.c:615 replication/walreceiver.c:910 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "n'a pas pu fermer le journal de transactions %s : %m" + +#: replication/walreceiver.c:734 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "récupération du fichier historique pour la timeline %u à partir du serveur principal" + +#: replication/walreceiver.c:957 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "n'a pas pu écrire le journal de transactions %s au décalage %u, longueur %lu : %m" + +#: replication/walsender.c:524 storage/smgr/md.c:1320 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "n'a pas pu trouver la fin du fichier « %s » : %m" + +#: replication/walsender.c:528 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "n'a pas pu se déplacer au début du fichier « %s » : %m" + +#: replication/walsender.c:579 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM n'a pas été exécuté avant START_REPLICATION" + +#: replication/walsender.c:608 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "ne peut pas utiliser un slot de réplication logique pour une réplication physique" + +#: replication/walsender.c:677 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "le point de reprise %X/%X de la timeline %u n'est pas dans l'historique du serveur" + +#: replication/walsender.c:680 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "L'historique du serveur a changé à partir de la timeline %u à %X/%X." + +#: replication/walsender.c:724 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "le point de reprise requis %X/%X est devant la position de vidage des WAL de ce serveur %X/%X" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:974 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s ne doit pas être appelé depuis une transaction" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:984 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s doit être appelé au sein d'une transaction" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:990 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s doit être appelé dans le niveau d'isolation REPEATABLE READ" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:996 +#, c-format +msgid "%s must be called before any query" +msgstr "%s doit être appelé avant toute requête" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1002 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s ne doit pas être appelé depuis une sous-transaction" + +#: replication/walsender.c:1145 +#, c-format +msgid "cannot read from logical replication slot \"%s\"" +msgstr "ne peut pas lire à partir du slot de réplication logique « %s »" + +#: replication/walsender.c:1147 +#, c-format +msgid "This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "Ce slot a été invalidé parce qu'il dépassait la taille maximale réservée." + +#: replication/walsender.c:1157 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "arrêt du processus walreceiver suite promotion" + +#: replication/walsender.c:1523 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "ne peut pas exécuter de nouvelles commandes alors que le walsender est en mode d'arrêt" + +#: replication/walsender.c:1560 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "ne peut pas exécuter des commandes SQL dans le walsender pour la réplication physique" + +#: replication/walsender.c:1583 +#, c-format +msgid "received replication command: %s" +msgstr "commande de réplication reçu : %s" + +#: replication/walsender.c:1591 tcop/fastpath.c:208 tcop/postgres.c:1078 tcop/postgres.c:1430 tcop/postgres.c:1691 tcop/postgres.c:2176 tcop/postgres.c:2586 tcop/postgres.c:2665 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "" +"la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc\n" +"de la transaction" + +#: replication/walsender.c:1726 replication/walsender.c:1761 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "fin de fichier (EOF) inattendue de la connexion du serveur en attente" + +#: replication/walsender.c:1749 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "type de message « %c » invalide pour le serveur en standby" + +#: replication/walsender.c:1838 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "type de message « %c » inattendu" + +#: replication/walsender.c:2251 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "arrêt du processus walreceiver suite à l'expiration du délai de réplication" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:999 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "la règle « %s » existe déjà pour la relation « %s »" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "les actions de la règle sur OLD ne sont pas implémentées" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "Utilisez à la place des vues ou des triggers." + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "les actions de la règle sur NEW ne sont pas implémentées" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "Utilisez des triggers à la place." + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "les règles INSTEAD NOTHING sur SELECT ne sont pas implémentées" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "Utilisez les vues à la place." + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "les actions multiples pour les règles sur SELECT ne sont pas implémentées" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "les règles sur SELECT doivent avoir une action INSTEAD SELECT" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "" +"les règles sur SELECT ne doivent pas contenir d'instructions de modification\n" +"de données avec WITH" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "" +"les qualifications d'événements ne sont pas implémentées pour les règles sur\n" +"SELECT" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "« %s » est déjà une vue" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "la règle de la vue pour « %s » doit être nommée « %s »" + +#: rewrite/rewriteDefine.c:435 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "ne peut pas convertir la table partitionnée « %s » en une vue" + +#: rewrite/rewriteDefine.c:444 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "ne peut pas convertir la partition « %s » en une vue" + +#: rewrite/rewriteDefine.c:453 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "n'a pas pu convertir la table « %s » en une vue car elle n'est pas vide" + +#: rewrite/rewriteDefine.c:462 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "n'a pas pu convertir la table « %s » en une vue parce qu'elle a des triggers" + +#: rewrite/rewriteDefine.c:464 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "" +"En particulier, la table ne peut pas être impliquée dans les relations des\n" +"clés étrangères." + +#: rewrite/rewriteDefine.c:469 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "n'a pas pu convertir la table « %s » en une vue parce qu'elle a des index" + +#: rewrite/rewriteDefine.c:475 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "n'a pas pu convertir la table « %s » en une vue parce qu'elle a des tables filles" + +#: rewrite/rewriteDefine.c:481 +#, c-format +msgid "could not convert table \"%s\" to a view because it has parent tables" +msgstr "n'a pas pu convertir la table « %s » en une vue parce qu'elle a des tables parents" + +#: rewrite/rewriteDefine.c:487 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "n'a pas pu convertir la table « %s » en une vue parce que le mode sécurité des lignes est activé pour elle" + +#: rewrite/rewriteDefine.c:493 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "n'a pas pu convertir la table « %s » en une vue parce qu'elle a des politiques de sécurité" + +#: rewrite/rewriteDefine.c:520 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "ne peut pas avoir plusieurs listes RETURNING dans une règle" + +#: rewrite/rewriteDefine.c:525 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "les listes RETURNING ne sont pas supportés dans des règles conditionnelles" + +#: rewrite/rewriteDefine.c:529 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "les listes RETURNING ne sont pas supportées dans des règles autres que INSTEAD" + +#: rewrite/rewriteDefine.c:693 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "la liste cible de la règle SELECT a trop d'entrées" + +#: rewrite/rewriteDefine.c:694 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "la liste RETURNING a trop d'entrées" + +#: rewrite/rewriteDefine.c:721 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "ne peut pas convertir la relation contenant les colonnes supprimées de la vue" + +#: rewrite/rewriteDefine.c:722 +#, c-format +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "ne peut pas créer une liste RETURNING pour une relation contenant des colonnes supprimées" + +#: rewrite/rewriteDefine.c:728 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "l'entrée cible de la règle SELECT %d a un nom de colonne différent pour la colonne « %s »" + +#: rewrite/rewriteDefine.c:730 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "l'entrée cible de la règle SELECT est nommée « %s »." + +#: rewrite/rewriteDefine.c:739 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "l'entrée cible de la règle SELECT %d a un type différent de la colonne « %s »" + +#: rewrite/rewriteDefine.c:741 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "l'entrée %d de la liste RETURNING a un type différent de la colonne « %s »" + +#: rewrite/rewriteDefine.c:744 rewrite/rewriteDefine.c:768 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "l'entrée de la liste SELECT a le type %s alors que la colonne a le type %s." + +#: rewrite/rewriteDefine.c:747 rewrite/rewriteDefine.c:772 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "l'entrée de la liste RETURNING a le type %s alors que la colonne a le type %s." + +#: rewrite/rewriteDefine.c:763 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "l'entrée cible de la règle SELECT %d a un taille différente de la colonne « %s »" + +#: rewrite/rewriteDefine.c:765 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "l'entrée %d de la liste RETURNING a une taille différente de la colonne « %s »" + +#: rewrite/rewriteDefine.c:782 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "l'entrée cible de la règle SELECT n'a pas assez d'entrées" + +#: rewrite/rewriteDefine.c:783 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "la liste RETURNING n'a pas assez d'entrées" + +#: rewrite/rewriteDefine.c:876 rewrite/rewriteDefine.c:990 rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "la règle « %s » de la relation « %s » n'existe pas" + +#: rewrite/rewriteDefine.c:1009 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "le renommage d'une règle ON SELECT n'est pas autorisé" + +#: rewrite/rewriteHandler.c:551 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "Le nom de la requête WITH « %s » apparaît à la fois dans l'action d'une règle et dans la requête en cours de ré-écriture" + +#: rewrite/rewriteHandler.c:611 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "ne peut pas avoir des listes RETURNING dans plusieurs règles" + +#: rewrite/rewriteHandler.c:843 rewrite/rewriteHandler.c:882 +#, c-format +msgid "cannot insert a non-DEFAULT value into column \"%s\"" +msgstr "ne peut pas insérer une valeur pas par défaut dans la colonne « %s »" + +#: rewrite/rewriteHandler.c:845 rewrite/rewriteHandler.c:911 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "La colonne « %s » est une colonne d'identité définie comme GENERATED ALWAYS." + +#: rewrite/rewriteHandler.c:847 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Utilisez OVERRIDING SYSTEM VALUE pour surcharger." + +#: rewrite/rewriteHandler.c:909 rewrite/rewriteHandler.c:917 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "la colonne « %s » peut seulement être mise à jour en DEFAULT" + +#: rewrite/rewriteHandler.c:1064 rewrite/rewriteHandler.c:1082 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "affectations multiples pour la même colonne « %s »" + +#: rewrite/rewriteHandler.c:2084 rewrite/rewriteHandler.c:3898 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "récursion infinie détectée dans les règles de la relation « %s »" + +#: rewrite/rewriteHandler.c:2169 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "récursion infinie détectée dans la politique pour la relation « %s »" + +#: rewrite/rewriteHandler.c:2489 +msgid "Junk view columns are not updatable." +msgstr "Les colonnes « junk » des vues ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2494 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "Les colonnes des vues qui ne font pas référence à des colonnes de la relation de base ne sont pas automatiquement modifiables." + +#: rewrite/rewriteHandler.c:2497 +msgid "View columns that refer to system columns are not updatable." +msgstr "Les colonnes des vues qui font référence à des colonnes systèmes ne sont pas automatiquement modifiables." + +#: rewrite/rewriteHandler.c:2500 +msgid "View columns that return whole-row references are not updatable." +msgstr "Les colonnes de vue qui font références à des lignes complètes ne sont pas automatiquement modifiables." + +#: rewrite/rewriteHandler.c:2561 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "Les vues contenant DISTINCT ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2564 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "Les vues contenant GROUP BY ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2567 +msgid "Views containing HAVING are not automatically updatable." +msgstr "Les vues contenant HAVING ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2570 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "Les vues contenant UNION, INTERSECT ou EXCEPT ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2573 +msgid "Views containing WITH are not automatically updatable." +msgstr "Les vues contenant WITH ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2576 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "Les vues contenant LIMIT ou OFFSET ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2588 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "Les vues qui renvoient des fonctions d'agrégat ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2591 +msgid "Views that return window functions are not automatically updatable." +msgstr "Les vues qui renvoient des fonctions de fenêtrage ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2594 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "Les vues qui renvoient des fonctions à plusieurs lignes ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2601 rewrite/rewriteHandler.c:2605 rewrite/rewriteHandler.c:2613 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "Les vues qui lisent plusieurs tables ou vues ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2616 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "Les vues contenant TABLESAMPLE ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:2640 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "Les vues qui possèdent des colonnes non modifiables ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:3117 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "ne peut pas insérer dans la colonne « %s » de la vue « %s »" + +#: rewrite/rewriteHandler.c:3125 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "ne peut pas mettre à jour la colonne « %s » de la vue « %s »" + +#: rewrite/rewriteHandler.c:3603 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "les règles DO INSTEAD NOTHING ne sont pas supportées par les instructions de modification de données dans WITH" + +#: rewrite/rewriteHandler.c:3617 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "" +"les règles DO INSTEAD conditionnelles ne sont pas supportées par les\n" +"instructions de modification de données dans WITH" + +#: rewrite/rewriteHandler.c:3621 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "les règles DO ALSO ne sont pas supportées par les instructions de modification de données dans WITH" + +#: rewrite/rewriteHandler.c:3626 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "" +"les règles DO INSTEAD multi-instructions ne sont pas supportées pour les\n" +"instructions de modification de données dans WITH" + +#: rewrite/rewriteHandler.c:3826 rewrite/rewriteHandler.c:3834 rewrite/rewriteHandler.c:3842 +#, c-format +msgid "Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "Les vues contenant des règles DO INSTEAD conditionnelles ne sont pas automatiquement disponibles en écriture." + +#: rewrite/rewriteHandler.c:3935 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "ne peut pas exécuter INSERT RETURNING sur la relation « %s »" + +#: rewrite/rewriteHandler.c:3937 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "" +"Vous avez besoin d'une règle ON INSERT DO INSTEAD sans condition avec une\n" +"clause RETURNING." + +#: rewrite/rewriteHandler.c:3942 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "ne peut pas exécuter UPDATE RETURNING sur la relation « %s »" + +#: rewrite/rewriteHandler.c:3944 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "" +"Vous avez besoin d'une règle ON UPDATE DO INSTEAD sans condition avec une\n" +"clause RETURNING." + +#: rewrite/rewriteHandler.c:3949 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "ne peut pas exécuter DELETE RETURNING sur la relation « %s »" + +#: rewrite/rewriteHandler.c:3951 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "" +"Vous avez besoin d'une règle ON DELETE DO INSTEAD sans condition avec une\n" +"clause RETURNING." + +#: rewrite/rewriteHandler.c:3969 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "INSERT avec une clause ON CONFLICT ne peut pas être utilisée avec une table qui a des règles pour INSERT ou UPDATE" + +#: rewrite/rewriteHandler.c:4026 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "WITH ne peut pas être utilisé dans une requête réécrite par des règles en plusieurs requêtes" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "les instructions conditionnelles ne sont pas implémentées" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "WHERE CURRENT OF n'est pas implémenté sur une vue" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "les variables NEW dans des règles ON UPDATE ne peuvent pas référencer des colonnes faisant partie d'une affectation multiple dans une commande UPDATE" + +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "commentaire /* non terminé" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "chaîne littérale bit non terminée" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "chaîne littérale hexadécimale non terminée" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "utilisation non sûre de la constante de chaîne avec des échappements Unicode" + +#: scan.l:543 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "" +"Les constantes de chaîne avec des échappements Unicode ne peuvent pas être\n" +"utilisées quand standard_conforming_strings est désactivé." + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "état précédent non géré dans xqs" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Les échappements Unicode doivent être de la forme \\uXXXX ou \\UXXXXXXXX." + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "utilisation non sûre de \\' dans une chaîne littérale" + +#: scan.l:690 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "" +"Utilisez '' pour écrire des guillemets dans une chaîne. \\' n'est pas sécurisé\n" +"pour les encodages clients." + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "chaîne entre guillemets dollars non terminée" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "identifiant délimité de longueur nulle" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "identifiant entre guillemets non terminé" + +#: scan.l:963 +msgid "operator too long" +msgstr "opérateur trop long" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1171 +#, c-format +msgid "%s at end of input" +msgstr "%s à la fin de l'entrée" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1179 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s sur ou près de « %s »" + +#: scan.l:1373 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "utilisation non standard de \\' dans une chaîne littérale" + +#: scan.l:1374 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "" +"Utilisez '' pour écrire des guillemets dans une chaîne ou utilisez la syntaxe de\n" +"chaîne d'échappement (E'...')." + +#: scan.l:1383 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "utilisation non standard de \\\\ dans une chaîne littérale" + +#: scan.l:1384 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Utilisez la syntaxe de chaîne d'échappement pour les antislashs, c'est-à-dire E'\\\\'." + +#: scan.l:1398 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "utilisation non standard d'un échappement dans une chaîne littérale" + +#: scan.l:1399 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "" +"Utilisez la syntaxe de la chaîne d'échappement pour les échappements,\n" +"c'est-à-dire E'\\r\\n'." + +#: snowball/dict_snowball.c:215 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "aucun stemmer Snowball disponible pour la langue « %s » et l'encodage « %s »" + +#: snowball/dict_snowball.c:238 tsearch/dict_ispell.c:74 tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "plusieurs paramètres StopWords" + +#: snowball/dict_snowball.c:247 +#, c-format +msgid "multiple Language parameters" +msgstr "multiples paramètres Language" + +#: snowball/dict_snowball.c:254 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "paramètre Snowball non reconnu : « %s »" + +#: snowball/dict_snowball.c:262 +#, c-format +msgid "missing Language parameter" +msgstr "paramètre Language manquant" + +#: statistics/extended_stats.c:175 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "l'objet de statistiques « %s.%s » n'a pas pu être calculé pour la relation « %s.%s »" + +#: statistics/extended_stats.c:2277 +#, c-format +msgid "relation \"pg_statistic\" does not have a composite type" +msgstr "la relation « pg_statistic » n'a pas un type composite" + +#: statistics/mcv.c:1371 utils/adt/jsonfuncs.c:1941 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "" +"fonction renvoyant le type record appelée dans un contexte qui ne peut pas\n" +"accepter le type record" + +#: storage/buffer/bufmgr.c:601 storage/buffer/bufmgr.c:761 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "ne peut pas accéder aux tables temporaires d'autres sessions" + +#: storage/buffer/bufmgr.c:917 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "" +"données inattendues après la fin de fichier dans le bloc %u de la relation\n" +"%s" + +#: storage/buffer/bufmgr.c:919 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "" +"Ceci s'est déjà vu avec des noyaux buggés ; pensez à mettre à jour votre\n" +"système." + +#: storage/buffer/bufmgr.c:1018 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "page invalide dans le bloc %u de la relation %s ; remplacement de la page par des zéros" + +#: storage/buffer/bufmgr.c:4524 +#, c-format +msgid "could not write block %u of %s" +msgstr "n'a pas pu écrire le bloc %u de %s" + +#: storage/buffer/bufmgr.c:4526 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Échecs multiples --- l'erreur d'écriture pourrait être permanente." + +#: storage/buffer/bufmgr.c:4547 storage/buffer/bufmgr.c:4566 +#, c-format +msgid "writing block %u of relation %s" +msgstr "écriture du bloc %u de la relation %s" + +#: storage/buffer/bufmgr.c:4870 +#, c-format +msgid "snapshot too old" +msgstr "snapshot trop ancien" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "aucun tampon local vide disponible" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "ne peut pas accéder à des tables temporaires pendant une opération parallèle" + +#: storage/file/buffile.c:323 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier temporaire « %s » à partir de BufFile « %s » : %m" + +#: storage/file/buffile.c:684 storage/file/buffile.c:805 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "n'a pas pu déterminer la taille du fichier temporaire « %s » à partir de BufFile « %s » : %m" + +#: storage/file/buffile.c:884 +#, c-format +msgid "could not delete shared fileset \"%s\": %m" +msgstr "n'a pas pu supprimer l'ensemble de fichiers partagés « %s » : %m" + +#: storage/file/buffile.c:902 storage/smgr/md.c:306 storage/smgr/md.c:865 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "n'a pas pu tronquer le fichier « %s » : %m" + +#: storage/file/fd.c:515 storage/file/fd.c:587 storage/file/fd.c:623 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "n'a pas pu vider les données modifiées : %m" + +#: storage/file/fd.c:545 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "n'a pas pu déterminer la taille des données modifiées : %m" + +#: storage/file/fd.c:597 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "n'a pas exécuter munmap() durant la synchronisation des données : %m" + +#: storage/file/fd.c:836 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "n'a pas pu lier le fichier « %s » à « %s » : %m" + +#: storage/file/fd.c:929 +#, c-format +msgid "getrlimit failed: %m" +msgstr "échec de getrlimit : %m" + +#: storage/file/fd.c:1019 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "nombre de descripteurs de fichier insuffisant pour lancer le processus serveur" + +#: storage/file/fd.c:1020 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "Le système autorise %d, nous avons besoin d'au moins %d." + +#: storage/file/fd.c:1071 storage/file/fd.c:2408 storage/file/fd.c:2518 storage/file/fd.c:2669 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "plus de descripteurs de fichiers : %m; quittez et ré-essayez" + +#: storage/file/fd.c:1445 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "fichier temporaire : chemin « %s », taille %lu" + +#: storage/file/fd.c:1576 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "ne peut pas créer le répertoire temporaire « %s » : %m" + +#: storage/file/fd.c:1583 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "ne peut pas créer le sous-répertoire temporaire « %s » : %m" + +#: storage/file/fd.c:1776 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "n'a pas pu créer le fichier temporaire « %s » : %m" + +#: storage/file/fd.c:1810 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier temporaire « %s » : %m" + +#: storage/file/fd.c:1851 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier temporaire « %s » : %m" + +#: storage/file/fd.c:1939 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier « %s » : %m" + +#: storage/file/fd.c:2119 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "la taille du fichier temporaire dépasse temp_file_limit (%d Ko)" + +#: storage/file/fd.c:2384 storage/file/fd.c:2443 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "dépassement de maxAllocatedDescs (%d) lors de la tentative d'ouverture du fichier « %s »" + +#: storage/file/fd.c:2488 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "dépassement de maxAllocatedDescs (%d) lors de la tentative d'exécution de la commande « %s »" + +#: storage/file/fd.c:2645 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "dépassement de maxAllocatedDescs (%d) lors de la tentative d'ouverture du répertoire « %s »" + +#: storage/file/fd.c:3175 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "fichier non attendu dans le répertoire des fichiers temporaires : « %s »" + +#: storage/file/fd.c:3298 +#, c-format +msgid "could not open %s: %m" +msgstr "n'a pas pu ouvrir %s : %m" + +#: storage/file/fd.c:3304 +#, c-format +msgid "could not sync filesystem for \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fsync) le système de fichiers pour « %s » : %m" + +#: storage/file/sharedfileset.c:144 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "n'a pas pu s'attacher a un SharedFileSet qui est déjà détruit" + +#: storage/ipc/dsm.c:351 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "le segment contrôle de mémoire partagée dynamique est corrompu" + +#: storage/ipc/dsm.c:415 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "le segment contrôle de mémoire partagée dynamique n'est pas valide" + +#: storage/ipc/dsm.c:592 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "trop de segments de mémoire partagée dynamique" + +#: storage/ipc/dsm_impl.c:233 storage/ipc/dsm_impl.c:529 storage/ipc/dsm_impl.c:633 storage/ipc/dsm_impl.c:804 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "n'a pas pu annuler le mappage du segment de mémoire partagée « %s » : %m" + +#: storage/ipc/dsm_impl.c:243 storage/ipc/dsm_impl.c:539 storage/ipc/dsm_impl.c:643 storage/ipc/dsm_impl.c:814 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "n'a pas pu supprimer le segment de mémoire partagée « %s » : %m" + +#: storage/ipc/dsm_impl.c:267 storage/ipc/dsm_impl.c:714 storage/ipc/dsm_impl.c:828 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "n'a pas pu ouvrir le segment de mémoire partagée « %s » : %m" + +#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:555 storage/ipc/dsm_impl.c:759 storage/ipc/dsm_impl.c:852 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "n'a pas pu obtenir des informations sur le segment de mémoire partagée « %s » : %m" + +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:903 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "n'a pas pu retailler le segment de mémoire partagée « %s » en %zu octets : %m" + +#: storage/ipc/dsm_impl.c:341 storage/ipc/dsm_impl.c:576 storage/ipc/dsm_impl.c:735 storage/ipc/dsm_impl.c:925 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "n'a pas pu mapper le segment de mémoire partagée « %s » : %m" + +#: storage/ipc/dsm_impl.c:511 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "n'a pas pu obtenir le segment de mémoire partagée : %m" + +#: storage/ipc/dsm_impl.c:699 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "n'a pas pu créer le segment de mémoire partagée « %s » : %m" + +#: storage/ipc/dsm_impl.c:936 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "n'a pas pu fermer le segment de mémoire partagée « %s » : %m" + +#: storage/ipc/dsm_impl.c:975 storage/ipc/dsm_impl.c:1023 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "n'a pas pu dupliquer le lien pour « %s » : %m" + +#: storage/ipc/procarray.c:3747 +#, c-format +msgid "database \"%s\" is being used by prepared transactions" +msgstr "la base de données « %s » est utilisée par des transactions préparées." + +#: storage/ipc/procarray.c:3779 storage/ipc/signalfuncs.c:219 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "doit être super-utilisateur pour terminer le processus d'un super-utilisateur" + +#: storage/ipc/procarray.c:3786 storage/ipc/signalfuncs.c:224 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "doit être un membre du rôle dont le processus est en cours d'arrêt ou membre de pg_signal_backend" + +#: storage/ipc/shm_mq.c:368 +#, c-format +msgid "cannot send a message of size %zu via shared memory queue" +msgstr "ne peut pas envoyer un message de taille %zu via la queue en mémoire partagée" + +#: storage/ipc/shm_mq.c:694 +#, c-format +msgid "invalid message size %zu in shared memory queue" +msgstr "taille %zu invalide pour le message dans la queue de mémoire partagée" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:981 storage/lmgr/lock.c:1019 storage/lmgr/lock.c:2844 storage/lmgr/lock.c:4173 storage/lmgr/lock.c:4238 storage/lmgr/lock.c:4545 storage/lmgr/predicate.c:2470 storage/lmgr/predicate.c:2485 storage/lmgr/predicate.c:3967 storage/lmgr/predicate.c:5078 utils/hash/dynahash.c:1112 +#, c-format +msgid "out of shared memory" +msgstr "mémoire partagée épuisée" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "pas assez de mémoire partagée (%zu octets demandés)" + +#: storage/ipc/shmem.c:445 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "n'a pas pu créer l'entrée ShmemIndex pour la structure de données « %s »" + +#: storage/ipc/shmem.c:460 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "La taille de l'entrée ShmemIndex est mauvaise pour la structure de données « %s » : %zu attendu, %zu obtenu" + +#: storage/ipc/shmem.c:479 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "pas assez de mémoire partagée pour la structure de données « %s » (%zu octets demandés)" + +#: storage/ipc/shmem.c:511 storage/ipc/shmem.c:530 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "la taille de la mémoire partagée demandée dépasse size_t" + +#: storage/ipc/signalfuncs.c:68 utils/adt/mcxtfuncs.c:204 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "le PID %d n'est pas un processus du serveur PostgreSQL" + +#: storage/ipc/signalfuncs.c:99 storage/lmgr/proc.c:1454 utils/adt/mcxtfuncs.c:212 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "n'a pas pu envoyer le signal au processus %d : %m" + +#: storage/ipc/signalfuncs.c:119 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "doit être super-utilisateur pour annuler la requête d'un super-utilisateur" + +#: storage/ipc/signalfuncs.c:124 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "doit être un membre du rôle dont la requête est en cours d'annulation ou membre de pg_signal_backend" + +#: storage/ipc/signalfuncs.c:165 +#, c-format +msgid "could not check the existence of the backend with PID %d: %m" +msgstr "n'a pas pu vérifier l'existence du processus serveur de PID %d : %m" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "backend with PID %d did not terminate within %lld milliseconds" +msgstr "le processus serveur de PID %d ne s'est pas terminé dans les %lld secondes" + +#: storage/ipc/signalfuncs.c:212 +#, c-format +msgid "\"timeout\" must not be negative" +msgstr "« timeout » ne doit pas être négatif" + +#: storage/ipc/signalfuncs.c:264 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "doit être super-utilisateur pour exécuter la rotation des journaux applicatifs avec adminpack 1.0" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:266 utils/adt/genfile.c:255 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Considérer l'utilisation de %s, qui fait partie de l'installation par défaut, à la place." + +#: storage/ipc/signalfuncs.c:272 storage/ipc/signalfuncs.c:292 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "rotation impossible car la récupération des journaux applicatifs n'est pas activée" + +#: storage/ipc/standby.c:305 +#, c-format +msgid "recovery still waiting after %ld.%03d ms: %s" +msgstr "restauration toujours en attente après %ld.%03d ms : %s" + +#: storage/ipc/standby.c:314 +#, c-format +msgid "recovery finished waiting after %ld.%03d ms: %s" +msgstr "la restauration a fini d'attendre après %ld.%03d ms : %s" + +#: storage/ipc/standby.c:878 tcop/postgres.c:3317 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "annulation de la requête à cause d'un conflit avec la restauration" + +#: storage/ipc/standby.c:879 tcop/postgres.c:2471 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "La transaction de l'utilisateur causait un verrou mortel lors de la restauration." + +#: storage/ipc/standby.c:1421 +msgid "unknown reason" +msgstr "raison inconnue" + +#: storage/ipc/standby.c:1426 +msgid "recovery conflict on buffer pin" +msgstr "" + +#: storage/ipc/standby.c:1429 +msgid "recovery conflict on lock" +msgstr "conflit de restauration sur le verrou" + +#: storage/ipc/standby.c:1432 +msgid "recovery conflict on tablespace" +msgstr "conflit lors de la restauration sur un tablespace" + +#: storage/ipc/standby.c:1435 +msgid "recovery conflict on snapshot" +msgstr "" + +#: storage/ipc/standby.c:1438 +msgid "recovery conflict on buffer deadlock" +msgstr "" + +#: storage/ipc/standby.c:1441 +msgid "recovery conflict on database" +msgstr "conflit de restauration sur la base de données" + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "l'entrée du Large Object d'OID %u, en page %d, a une taille de champ de données invalide, %d" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "drapeaux invalides pour l'ouverture d'un « Large Object » : %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "paramétrage de « whence » invalide : %d" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "taille de la requête d'écriture du « Large Object » invalide : %d" + +#: storage/lmgr/deadlock.c:1122 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "Le processus %d attend %s sur %s ; bloqué par le processus %d." + +#: storage/lmgr/deadlock.c:1141 +#, c-format +msgid "Process %d: %s" +msgstr "Processus %d : %s" + +#: storage/lmgr/deadlock.c:1150 +#, c-format +msgid "deadlock detected" +msgstr "interblocage (deadlock) détecté" + +#: storage/lmgr/deadlock.c:1153 +#, c-format +msgid "See server log for query details." +msgstr "Voir les journaux applicatifs du serveur pour les détails sur la requête." + +#: storage/lmgr/lmgr.c:831 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "lors de la mise à jour de la ligne (%u,%u) dans la relation « %s »" + +#: storage/lmgr/lmgr.c:834 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "lors de la suppression de la ligne (%u,%u) dans la relation « %s »" + +#: storage/lmgr/lmgr.c:837 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "lors du verrouillage de la ligne (%u,%u) dans la relation « %s »" + +#: storage/lmgr/lmgr.c:840 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "lors du verrou de la version mise à jour (%u, %u) de la ligne de la relation « %s »" + +#: storage/lmgr/lmgr.c:843 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "lors de l'insertion de l'enregistrement (%u, %u) de l'index dans la relation « %s »" + +#: storage/lmgr/lmgr.c:846 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "lors de la vérification de l'unicité de l'enregistrement (%u,%u) dans la relation « %s »" + +#: storage/lmgr/lmgr.c:849 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "lors de la re-vérification de l'enregistrement mis à jour (%u,%u) dans la relation « %s »" + +#: storage/lmgr/lmgr.c:852 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "lors de la vérification de la contrainte d'exclusion sur l'enregistrement (%u,%u) dans la relation « %s »" + +#: storage/lmgr/lmgr.c:1106 +#, c-format +msgid "relation %u of database %u" +msgstr "relation %u de la base de données %u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "extension de la relation %u de la base de données %u" + +#: storage/lmgr/lmgr.c:1118 +#, c-format +msgid "pg_database.datfrozenxid of database %u" +msgstr "pg_database.datfrozenxid de la base %u" + +#: storage/lmgr/lmgr.c:1123 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "page %u de la relation %u de la base de données %u" + +#: storage/lmgr/lmgr.c:1130 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "ligne (%u,%u) de la relation %u de la base de données %u" + +#: storage/lmgr/lmgr.c:1138 +#, c-format +msgid "transaction %u" +msgstr "transaction %u" + +#: storage/lmgr/lmgr.c:1143 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "transaction virtuelle %d/%u" + +#: storage/lmgr/lmgr.c:1149 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "jeton spéculatif %u de la transaction %u" + +#: storage/lmgr/lmgr.c:1155 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "objet %u de la classe %u de la base de données %u" + +#: storage/lmgr/lmgr.c:1163 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "verrou utilisateur [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1170 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "verrou informatif [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1178 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "type locktag non reconnu %d" + +#: storage/lmgr/lock.c:802 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "" +"ne peut pas acquérir le mode de verrou %s sur les objets de base de données\n" +"alors que la restauration est en cours" + +#: storage/lmgr/lock.c:804 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "" +"Seuls RowExclusiveLock et les verrous inférieurs peuvent être acquis sur les\n" +"objets d'une base pendant une restauration." + +#: storage/lmgr/lock.c:982 storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 storage/lmgr/lock.c:4174 storage/lmgr/lock.c:4239 storage/lmgr/lock.c:4546 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "Vous pourriez avoir besoin d'augmenter max_locks_per_transaction." + +#: storage/lmgr/lock.c:3283 storage/lmgr/lock.c:3399 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "ne peut pas utiliser PREPARE lorsque des verrous de niveau session et deniveau transaction sont détenus sur le même objet" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "pas assez d'éléments dans RWConflictPool pour enregistrer un conflit en lecture/écriture" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "" +"Il est possible que vous ayez à exécuter moins de transactions à la fois\n" +"ou d'augmenter max_connections." + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "pas assez d'éléments dans RWConflictPool pour enregistrer un conflit en lecture/écriture potentiel" + +#: storage/lmgr/predicate.c:1694 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "« default_transaction_isolation » est configuré à « serializable »." + +#: storage/lmgr/predicate.c:1695 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "" +"Vous pouvez utiliser « SET default_transaction_isolation = 'repeatable read' »\n" +"pour modifier la valeur par défaut." + +#: storage/lmgr/predicate.c:1746 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "une transaction important un snapshot ne doit pas être READ ONLY DEFERRABLE" + +#: storage/lmgr/predicate.c:1825 utils/time/snapmgr.c:567 utils/time/snapmgr.c:573 +#, c-format +msgid "could not import the requested snapshot" +msgstr "n'a pas pu importer le snapshot demandé" + +#: storage/lmgr/predicate.c:1826 utils/time/snapmgr.c:574 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "Le processus source de PID %d n'est plus en cours d'exécution." + +#: storage/lmgr/predicate.c:2471 storage/lmgr/predicate.c:2486 storage/lmgr/predicate.c:3968 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "Vous pourriez avoir besoin d'augmenter max_pred_locks_per_transaction." + +#: storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4135 storage/lmgr/predicate.c:4168 storage/lmgr/predicate.c:4176 storage/lmgr/predicate.c:4215 storage/lmgr/predicate.c:4457 storage/lmgr/predicate.c:4794 storage/lmgr/predicate.c:4806 storage/lmgr/predicate.c:4849 storage/lmgr/predicate.c:4887 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "" +"n'a pas pu sérialiser un accès à cause des dépendances de lecture/écriture\n" +"parmi les transactions" + +#: storage/lmgr/predicate.c:4101 storage/lmgr/predicate.c:4137 storage/lmgr/predicate.c:4170 storage/lmgr/predicate.c:4178 storage/lmgr/predicate.c:4217 storage/lmgr/predicate.c:4459 storage/lmgr/predicate.c:4796 storage/lmgr/predicate.c:4808 storage/lmgr/predicate.c:4851 storage/lmgr/predicate.c:4889 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "La transaction pourrait réussir après une nouvelle tentative." + +#: storage/lmgr/proc.c:357 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "" +"le nombre de connexions demandées par le serveur en attente dépasse\n" +"max_wal_senders (actuellement %d)" + +#: storage/lmgr/proc.c:1551 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "" +"le processus %d a évité un verrou mortel pour %s sur %s en modifiant l'ordre\n" +"de la queue après %ld.%03d ms" + +#: storage/lmgr/proc.c:1566 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "" +"le processus %d a détecté un verrou mortel alors qu'il était en attente de\n" +"%s sur %s après %ld.%03d ms" + +#: storage/lmgr/proc.c:1575 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "le processus %d est toujours en attente de %s sur %s après %ld.%03d ms" + +#: storage/lmgr/proc.c:1582 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "le processus %d a acquis %s sur %s après %ld.%03d ms" + +#: storage/lmgr/proc.c:1599 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "le processus %d a échoué pour l'acquisition de %s sur %s après %ld.%03d ms" + +#: storage/page/bufpage.c:152 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "échec de la vérification de la page, somme de contrôle calculé %u, mais attendait %u" + +#: storage/page/bufpage.c:217 storage/page/bufpage.c:739 storage/page/bufpage.c:1066 storage/page/bufpage.c:1201 storage/page/bufpage.c:1307 storage/page/bufpage.c:1419 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "pointeurs de page corrompus : le plus bas = %u, le plus haut = %u, spécial = %u" + +#: storage/page/bufpage.c:768 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "pointeur de ligne corrompu : %u" + +#: storage/page/bufpage.c:795 storage/page/bufpage.c:1259 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "longueurs d'élément corrompues : total %u, espace disponible %u" + +#: storage/page/bufpage.c:1085 storage/page/bufpage.c:1226 storage/page/bufpage.c:1323 storage/page/bufpage.c:1435 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "pointeur de ligne corrompu : décalage = %u, taille = %u" + +#: storage/smgr/md.c:434 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "ne peut pas étendre le fichier « %s » de plus de %u blocs" + +#: storage/smgr/md.c:449 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "n'a pas pu étendre le fichier « %s » : %m" + +#: storage/smgr/md.c:451 storage/smgr/md.c:458 storage/smgr/md.c:746 +#, c-format +msgid "Check free disk space." +msgstr "Vérifiez l'espace disque disponible." + +#: storage/smgr/md.c:455 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "" +"n'a pas pu étendre le fichier « %s » : a écrit seulement %d octets sur %d\n" +"au bloc %u" + +#: storage/smgr/md.c:667 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "n'a pas pu lire le bloc %u dans le fichier « %s » : %m" + +#: storage/smgr/md.c:683 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "" +"n'a pas pu lire le bloc %u du fichier « %s » : a lu seulement %d octets\n" +"sur %d" + +#: storage/smgr/md.c:737 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "n'a pas pu écrire le bloc %u dans le fichier « %s » : %m" + +#: storage/smgr/md.c:742 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "" +"n'a pas pu écrire le bloc %u du fichier « %s » : a seulement écrit %d\n" +"octets sur %d" + +#: storage/smgr/md.c:836 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "n'a pas pu tronquer le fichier « %s » en %u blocs : il y a seulement %u blocs" + +#: storage/smgr/md.c:891 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "n'a pas pu tronquer le fichier « %s » en %u blocs : %m" + +#: storage/smgr/md.c:1285 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "n'a pas pu ouvrir le fichier « %s » (bloc cible %u) : le segment précédent ne fait que %u blocs" + +#: storage/smgr/md.c:1299 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "n'a pas pu ouvrir le fichier « %s » (bloc cible %u) : %m" + +#: tcop/fastpath.c:148 +#, c-format +msgid "cannot call function %s via fastpath interface" +msgstr "ne peut pas appeler la fonction %s via l'interface fastpath" + +#: tcop/fastpath.c:233 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "appel de fonction fastpath : « %s » (OID %u)" + +#: tcop/fastpath.c:312 tcop/postgres.c:1298 tcop/postgres.c:1556 tcop/postgres.c:2015 tcop/postgres.c:2252 +#, c-format +msgid "duration: %s ms" +msgstr "durée : %s ms" + +#: tcop/fastpath.c:316 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "durée : %s ms, appel de fonction fastpath : « %s » (OID %u)" + +#: tcop/fastpath.c:352 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "" +"le message d'appel de la fonction contient %d arguments mais la fonction en\n" +"requiert %d" + +#: tcop/fastpath.c:360 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "" +"le message d'appel de la fonction contient %d formats d'argument mais %d\n" +" arguments" + +#: tcop/fastpath.c:384 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "taille de l'argument %d invalide dans le message d'appel de la fonction" + +#: tcop/fastpath.c:447 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "format des données binaires incorrect dans l'argument de la fonction %d" + +#: tcop/postgres.c:446 tcop/postgres.c:4716 +#, c-format +msgid "invalid frontend message type %d" +msgstr "type %d du message de l'interface invalide" + +#: tcop/postgres.c:1015 +#, c-format +msgid "statement: %s" +msgstr "instruction : %s" + +#: tcop/postgres.c:1303 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "durée : %s ms, instruction : %s" + +#: tcop/postgres.c:1409 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "ne peut pas insérer les commandes multiples dans une instruction préparée" + +#: tcop/postgres.c:1561 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "durée : %s ms, analyse %s : %s" + +#: tcop/postgres.c:1627 tcop/postgres.c:2567 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "l'instruction préparée non nommée n'existe pas" + +#: tcop/postgres.c:1668 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "le message bind a %d formats de paramètres mais %d paramètres" + +#: tcop/postgres.c:1674 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "le message bind fournit %d paramètres, mais l'instruction préparée « %s » en requiert %d" + +#: tcop/postgres.c:1893 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "format des données binaires incorrect dans le paramètre bind %d" + +#: tcop/postgres.c:2020 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "durée : %s ms, lien %s%s%s : %s" + +#: tcop/postgres.c:2070 tcop/postgres.c:2651 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "le portail « %s » n'existe pas" + +#: tcop/postgres.c:2155 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2157 tcop/postgres.c:2260 +msgid "execute fetch from" +msgstr "exécute fetch à partir de" + +#: tcop/postgres.c:2158 tcop/postgres.c:2261 +msgid "execute" +msgstr "exécute" + +#: tcop/postgres.c:2257 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "durée : %s ms %s %s%s%s: %s" + +#: tcop/postgres.c:2403 +#, c-format +msgid "prepare: %s" +msgstr "préparation : %s" + +#: tcop/postgres.c:2428 +#, c-format +msgid "parameters: %s" +msgstr "paramètres : %s" + +#: tcop/postgres.c:2443 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "raison de l'annulation : conflit de restauration" + +#: tcop/postgres.c:2459 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "L'utilisateur conservait des blocs disques en mémoire partagée depuis trop longtemps." + +#: tcop/postgres.c:2462 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "L'utilisateur conservait un verrou sur une relation depuis trop longtemps." + +#: tcop/postgres.c:2465 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "L'utilisateur utilisait ou pouvait utiliser un tablespace qui doit être supprimé." + +#: tcop/postgres.c:2468 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "" +"La requête de l'utilisateur pourrait avoir eu besoin de voir des versions de\n" +"lignes qui doivent être supprimées." + +#: tcop/postgres.c:2474 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "L'utilisateur était connecté à une base de donnée qui doit être supprimée." + +#: tcop/postgres.c:2513 +#, c-format +msgid "portal \"%s\" parameter $%d = %s" +msgstr "portail « %s » paramètre $%d = %s" + +#: tcop/postgres.c:2516 +#, c-format +msgid "portal \"%s\" parameter $%d" +msgstr "portail « %s » paramètre $%d" + +#: tcop/postgres.c:2522 +#, c-format +msgid "unnamed portal parameter $%d = %s" +msgstr "paramètre de portail non nommé $%d = %s" + +#: tcop/postgres.c:2525 +#, c-format +msgid "unnamed portal parameter $%d" +msgstr "paramètre de portail non nommé $%d" + +#: tcop/postgres.c:2871 +#, c-format +msgid "terminating connection because of unexpected SIGQUIT signal" +msgstr "arrêt des connexions suite à un signal SIGQUIT inattendu" + +#: tcop/postgres.c:2877 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "arrêt de la connexion à cause de l'arrêt brutal d'un autre processus serveur" + +#: tcop/postgres.c:2878 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "" +"Le postmaster a commandé à ce processus serveur d'annuler la transaction\n" +"courante et de quitter car un autre processus serveur a quitté anormalement\n" +"et qu'il existe probablement de la mémoire partagée corrompue." + +#: tcop/postgres.c:2882 tcop/postgres.c:3243 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "" +"Dans un moment, vous devriez être capable de vous reconnecter à la base de\n" +"données et de relancer votre commande." + +#: tcop/postgres.c:2889 +#, c-format +msgid "terminating connection due to immediate shutdown command" +msgstr "arrêt des connexions suite à la commande d'arrêt immédiat" + +#: tcop/postgres.c:2975 +#, c-format +msgid "floating-point exception" +msgstr "exception due à une virgule flottante" + +#: tcop/postgres.c:2976 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "Une opération invalide sur les virgules flottantes a été signalée. Ceci signifie probablement un résultat en dehors de l'échelle ou une opération invalide telle qu'une division par zéro." + +#: tcop/postgres.c:3147 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "annulation de l'authentification à cause du délai écoulé" + +#: tcop/postgres.c:3151 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "arrêt du processus autovacuum suite à la demande de l'administrateur" + +#: tcop/postgres.c:3155 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "arrêt des processus workers de réplication logique suite à la demande de l'administrateur" + +#: tcop/postgres.c:3172 tcop/postgres.c:3182 tcop/postgres.c:3241 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "arrêt de la connexion à cause d'un conflit avec la restauration" + +#: tcop/postgres.c:3193 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "arrêt des connexions suite à la demande de l'administrateur" + +#: tcop/postgres.c:3224 +#, c-format +msgid "connection to client lost" +msgstr "connexion au client perdue" + +#: tcop/postgres.c:3294 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "annulation de la requête à cause du délai écoulé pour l'obtention des verrous" + +#: tcop/postgres.c:3301 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "annulation de la requête à cause du délai écoulé pour l'exécution de l'instruction" + +#: tcop/postgres.c:3308 +#, c-format +msgid "canceling autovacuum task" +msgstr "annulation de la tâche d'autovacuum" + +#: tcop/postgres.c:3331 +#, c-format +msgid "canceling statement due to user request" +msgstr "annulation de la requête à la demande de l'utilisateur" + +#: tcop/postgres.c:3345 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "arrêt des connexions suite à l'expiration du délai d'inactivité en transaction" + +#: tcop/postgres.c:3356 +#, c-format +msgid "terminating connection due to idle-session timeout" +msgstr "arrêt des connexions suite à l'expiration du délai d'inactivité de la session" + +#: tcop/postgres.c:3475 +#, c-format +msgid "stack depth limit exceeded" +msgstr "dépassement de limite (en profondeur) de la pile" + +#: tcop/postgres.c:3476 +#, c-format +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "" +"Augmenter le paramètre « max_stack_depth » (actuellement %d Ko) après vous\n" +"être assuré que la limite de profondeur de la pile de la plateforme est\n" +"adéquate." + +#: tcop/postgres.c:3539 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "« max_stack_depth » ne doit pas dépasser %ld ko." + +#: tcop/postgres.c:3541 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "" +"Augmenter la limite de profondeur de la pile sur votre plateforme via\n" +"« ulimit -s » ou l'équivalent local." + +#: tcop/postgres.c:3897 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "argument invalide en ligne de commande pour le processus serveur : %s" + +#: tcop/postgres.c:3898 tcop/postgres.c:3904 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Essayez « %s --help » pour plus d'informations." + +#: tcop/postgres.c:3902 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s : argument invalide en ligne de commande : %s" + +#: tcop/postgres.c:3965 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s : ni base de données ni utilisateur spécifié" + +#: tcop/postgres.c:4618 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "sous-type %d du message CLOSE invalide" + +#: tcop/postgres.c:4653 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "sous-type %d du message DESCRIBE invalide" + +#: tcop/postgres.c:4737 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "appels à la fonction fastpath non supportés dans une connexion de réplication" + +#: tcop/postgres.c:4741 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "protocole étendu de requêtes non supporté dans une connexion de réplication" + +#: tcop/postgres.c:4918 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "" +"déconnexion : durée de la session : %d:%02d:%02d.%03d\n" +"utilisateur=%s base=%s hôte=%s%s%s" + +#: tcop/pquery.c:636 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "le message bind a %d formats de résultat mais la requête a %d colonnes" + +#: tcop/pquery.c:939 +#, c-format +msgid "cursor can only scan forward" +msgstr "le curseur peut seulement parcourir en avant" + +#: tcop/pquery.c:940 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Déclarez-le avec l'option SCROLL pour activer le parcours inverse." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:414 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "ne peut pas exécuter %s dans une transaction en lecture seule" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:432 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "ne peut pas exécuté %s lors d'une opération parallèle" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:451 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "ne peut pas exécuté %s lors de la restauration" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:469 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "" +"ne peut pas exécuter %s à l'intérieur d'une fonction restreinte\n" +"pour sécurité" + +#: tcop/utility.c:928 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "doit être super-utilisateur pour exécuter un point de vérification (CHECKPOINT)" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:615 +#, c-format +msgid "multiple DictFile parameters" +msgstr "multiples paramètres DictFile" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "multiples paramètres AffFile" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "paramètre Ispell non reconnu : « %s »" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "paramètre AffFile manquant" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:639 +#, c-format +msgid "missing DictFile parameter" +msgstr "paramètre DictFile manquant" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "multiples paramètres Accept" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "paramètre de dictionnaire simple non reconnu : « %s »" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "paramètre synonyme non reconnu : « %s »" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "paramètre Synonyms manquant" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier synonyme « %s » : %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "n'a pas pu ouvrir le thésaurus « %s » : %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "délimiteur inattendu" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "fin de ligne ou lexeme inattendu" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "fin de ligne inattendue" + +#: tsearch/dict_thesaurus.c:292 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "trop de lexèmes dans l'entrée du thésaurus" + +#: tsearch/dict_thesaurus.c:416 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "" +"le mot d'exemple « %s » du thésaurus n'est pas reconnu par le\n" +"sous-dictionnaire (règle %d)" + +#: tsearch/dict_thesaurus.c:422 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "le mot d'exemple « %s » du thésaurus est un terme courant (règle %d)" + +#: tsearch/dict_thesaurus.c:425 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Utilisez « ? » pour représenter un terme courant dans une phrase." + +#: tsearch/dict_thesaurus.c:567 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "le mot substitut « %s » du thésaurus est un terme courant (règle %d)" + +#: tsearch/dict_thesaurus.c:574 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "" +"le mot substitut « %s » du thésaurus n'est pas reconnu par le\n" +"sous-dictionnaire (règle %d)" + +#: tsearch/dict_thesaurus.c:586 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "la phrase substitut du thésaurus est vide (règle %d)" + +#: tsearch/dict_thesaurus.c:624 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "multiples paramètres Dictionary" + +#: tsearch/dict_thesaurus.c:631 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "paramètre Thesaurus non reconnu : « %s »" + +#: tsearch/dict_thesaurus.c:643 +#, c-format +msgid "missing Dictionary parameter" +msgstr "paramètre Dictionary manquant" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 tsearch/spell.c:1062 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "drapeau d'affixe invalide « %s »" + +#: tsearch/spell.c:384 tsearch/spell.c:1066 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "le drapeau d'affixe « %s » est en dehors des limites" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "données invalides dans le drapeau d'affixe « %s »" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "drapeau d'affixe invalide « %s » avec la valeur de drapeau « long »" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier dictionnaire « %s » : %m" + +#: tsearch/spell.c:763 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "expression rationnelle invalide : %s" + +#: tsearch/spell.c:1189 tsearch/spell.c:1201 tsearch/spell.c:1760 tsearch/spell.c:1765 tsearch/spell.c:1770 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "alias d'affixe invalide « %s »" + +#: tsearch/spell.c:1242 tsearch/spell.c:1313 tsearch/spell.c:1462 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier affixe « %s » : %m" + +#: tsearch/spell.c:1296 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "le dictionnaire Ispell supporte seulement les valeurs de drapeau « default », « long » et « num »" + +#: tsearch/spell.c:1340 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "nombre d'alias de vecteur de drapeau invalide" + +#: tsearch/spell.c:1363 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "le nombre d'alias excède le nombre %d spécifié" + +#: tsearch/spell.c:1578 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "le fichier d'affixes contient des commandes ancien et nouveau style" + +#: tsearch/to_tsany.c:195 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "la chaîne est trop longue (%d octets, max %d octets)" + +#: tsearch/ts_locale.c:227 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "ligne %d du fichier de configuration « %s » : « %s »" + +#: tsearch/ts_locale.c:307 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "échec de l'encodage de wchar_t vers l'encodage du serveur : %m" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "le mot est trop long pour être indexé" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "Les mots de plus de %d caractères sont ignorés." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "nom du fichier de configuration de la recherche plein texte invalide : « %s »" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier des termes courants « %s » : %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "l'analyseur de recherche plein texte ne supporte pas headline" + +#: tsearch/wparser_def.c:2578 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "paramètre headline non reconnu : « %s »" + +#: tsearch/wparser_def.c:2597 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "MinWords doit avoir une valeur plus petite que celle de MaxWords" + +#: tsearch/wparser_def.c:2601 +#, c-format +msgid "MinWords should be positive" +msgstr "MinWords doit être positif" + +#: tsearch/wparser_def.c:2605 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "ShortWord devrait être positif ou nul" + +#: tsearch/wparser_def.c:2609 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "MaxFragments devrait être positif ou nul" + +#: utils/adt/acl.c:165 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "identifiant trop long" + +#: utils/adt/acl.c:166 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "L'identifiant doit faire moins de %d caractères." + +#: utils/adt/acl.c:249 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "mot clé non reconnu : « %s »" + +#: utils/adt/acl.c:250 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "le mot clé ACL doit être soit « group » soit « user »." + +#: utils/adt/acl.c:255 +#, c-format +msgid "missing name" +msgstr "nom manquant" + +#: utils/adt/acl.c:256 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "Un nom doit suivre le mot clé « group » ou « user »." + +#: utils/adt/acl.c:262 +#, c-format +msgid "missing \"=\" sign" +msgstr "signe « = » manquant" + +#: utils/adt/acl.c:315 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "mode caractère invalide : doit faire partie de « %s »" + +#: utils/adt/acl.c:337 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "un nom doit suivre le signe « / »" + +#: utils/adt/acl.c:345 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "par défaut, le « donneur de droits » devient l'utilisateur d'identifiant %u" + +#: utils/adt/acl.c:531 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "le tableau d'ACL contient un type de données incorrect" + +#: utils/adt/acl.c:535 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "les tableaux d'ACL ne doivent avoir qu'une seule dimension" + +#: utils/adt/acl.c:539 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "les tableaux d'ACL ne doivent pas contenir de valeurs NULL" + +#: utils/adt/acl.c:563 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "données superflues à la fin de la spécification de l'ACL" + +#: utils/adt/acl.c:1198 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "les options grant ne peuvent pas être rendues à votre propre donateur" + +#: utils/adt/acl.c:1259 +#, c-format +msgid "dependent privileges exist" +msgstr "des privilèges dépendants existent" + +#: utils/adt/acl.c:1260 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Utilisez CASCADE pour les révoquer aussi." + +#: utils/adt/acl.c:1514 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert n'est plus supporté" + +#: utils/adt/acl.c:1524 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove n'est plus supporté" + +#: utils/adt/acl.c:1610 utils/adt/acl.c:1664 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "type de droit non reconnu : « %s »" + +#: utils/adt/acl.c:3446 utils/adt/regproc.c:101 utils/adt/regproc.c:277 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "la fonction « %s » n'existe pas" + +#: utils/adt/acl.c:4898 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "doit être un membre du rôle « %s »" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:935 utils/adt/arrayfuncs.c:1543 utils/adt/arrayfuncs.c:3262 utils/adt/arrayfuncs.c:3404 utils/adt/arrayfuncs.c:5945 utils/adt/arrayfuncs.c:6286 utils/adt/arrayutils.c:94 utils/adt/arrayutils.c:103 utils/adt/arrayutils.c:110 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "la taille du tableau dépasse le maximum permis (%d)" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:467 utils/adt/array_userfuncs.c:547 utils/adt/json.c:645 utils/adt/json.c:740 utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "n'a pas pu déterminer le type de données date en entrée" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "le type de données en entrée n'est pas un tableau" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 utils/adt/float.c:1233 utils/adt/float.c:1307 utils/adt/float.c:4052 utils/adt/float.c:4066 utils/adt/int.c:757 utils/adt/int.c:779 utils/adt/int.c:793 utils/adt/int.c:807 utils/adt/int.c:838 utils/adt/int.c:859 utils/adt/int.c:976 utils/adt/int.c:990 utils/adt/int.c:1004 utils/adt/int.c:1037 utils/adt/int.c:1051 utils/adt/int.c:1065 utils/adt/int.c:1096 utils/adt/int.c:1178 utils/adt/int.c:1242 utils/adt/int.c:1310 utils/adt/int.c:1316 utils/adt/int8.c:1299 utils/adt/numeric.c:1776 utils/adt/numeric.c:4207 utils/adt/varbit.c:1195 utils/adt/varbit.c:1596 utils/adt/varlena.c:1121 utils/adt/varlena.c:3433 +#, c-format +msgid "integer out of range" +msgstr "entier en dehors des limites" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "l'argument doit être vide ou doit être un tableau à une dimension" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "ne peut pas concaténer des tableaux non compatibles" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Les tableaux avec les types d'élément %s et %s ne sont pas compatibles pour la concaténation." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Les tableaux de dimensions %d et %d ne sont pas compatibles pour la concaténation." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "Les tableaux avec des éléments de dimensions différentes ne sont pas compatibles pour une concaténation." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Les tableaux de dimensions différentes ne sont pas compatibles pour une concaténation." + +#: utils/adt/array_userfuncs.c:663 utils/adt/array_userfuncs.c:815 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "la recherche d'éléments dans des tableaux multidimensionnels n'est pas supportée" + +#: utils/adt/array_userfuncs.c:687 +#, c-format +msgid "initial position must not be null" +msgstr "la position initiale ne doit pas être NULL" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 utils/adt/arrayfuncs.c:492 utils/adt/arrayfuncs.c:508 utils/adt/arrayfuncs.c:519 utils/adt/arrayfuncs.c:534 utils/adt/arrayfuncs.c:555 utils/adt/arrayfuncs.c:585 utils/adt/arrayfuncs.c:592 utils/adt/arrayfuncs.c:600 utils/adt/arrayfuncs.c:634 utils/adt/arrayfuncs.c:657 utils/adt/arrayfuncs.c:677 utils/adt/arrayfuncs.c:789 utils/adt/arrayfuncs.c:798 utils/adt/arrayfuncs.c:828 utils/adt/arrayfuncs.c:843 utils/adt/arrayfuncs.c:896 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "tableau litéral mal formé : « %s »" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "« [ » doit introduire des dimensions explicites de tableau." + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "Valeur manquante de la dimension du tableau." + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "« %s » manquant après les dimensions du tableau." + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2909 utils/adt/arrayfuncs.c:2941 utils/adt/arrayfuncs.c:2956 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "la limite supérieure ne peut pas être plus petite que la limite inférieure" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "La valeur du tableau doit commencer par « { » ou par l'information de la dimension." + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "Le contenu du tableau doit commencer par « { »." + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "Les dimensions spécifiées du tableau ne correspondent pas au contenu du tableau." + +#: utils/adt/arrayfuncs.c:493 utils/adt/arrayfuncs.c:520 utils/adt/multirangetypes.c:162 utils/adt/rangetypes.c:2310 utils/adt/rangetypes.c:2318 utils/adt/rowtypes.c:211 utils/adt/rowtypes.c:219 +#, c-format +msgid "Unexpected end of input." +msgstr "Fin de l'entrée inattendue." + +#: utils/adt/arrayfuncs.c:509 utils/adt/arrayfuncs.c:556 utils/adt/arrayfuncs.c:586 utils/adt/arrayfuncs.c:635 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "Caractère « %c » inattendu." + +#: utils/adt/arrayfuncs.c:535 utils/adt/arrayfuncs.c:658 +#, c-format +msgid "Unexpected array element." +msgstr "Élément de tableau inattendu." + +#: utils/adt/arrayfuncs.c:593 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "Caractère « %c » sans correspondance." + +#: utils/adt/arrayfuncs.c:601 utils/adt/jsonfuncs.c:2593 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "Les tableaux multidimensionnels doivent avoir des sous-tableaux avec les dimensions correspondantes" + +#: utils/adt/arrayfuncs.c:678 +#, c-format +msgid "Junk after closing right brace." +msgstr "Problème après la parenthèse droite fermante." + +#: utils/adt/arrayfuncs.c:1300 utils/adt/arrayfuncs.c:3370 utils/adt/arrayfuncs.c:5849 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "nombre de dimensions invalide : %d" + +#: utils/adt/arrayfuncs.c:1311 +#, c-format +msgid "invalid array flags" +msgstr "drapeaux de tableau invalides" + +#: utils/adt/arrayfuncs.c:1333 +#, c-format +msgid "binary data has array element type %u (%s) instead of expected %u (%s)" +msgstr "" + +#: utils/adt/arrayfuncs.c:1377 utils/adt/multirangetypes.c:443 utils/adt/rangetypes.c:333 utils/cache/lsyscache.c:2905 +#, c-format +msgid "no binary input function available for type %s" +msgstr "aucune fonction d'entrée binaire disponible pour le type %s" + +#: utils/adt/arrayfuncs.c:1517 +#, c-format +msgid "improper binary format in array element %d" +msgstr "format binaire mal conçu dans l'élément du tableau %d" + +#: utils/adt/arrayfuncs.c:1598 utils/adt/multirangetypes.c:448 utils/adt/rangetypes.c:338 utils/cache/lsyscache.c:2938 +#, c-format +msgid "no binary output function available for type %s" +msgstr "aucune fonction de sortie binaire disponible pour le type %s" + +#: utils/adt/arrayfuncs.c:2077 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "les morceaux des tableaux à longueur fixe ne sont pas implémentés" + +#: utils/adt/arrayfuncs.c:2255 utils/adt/arrayfuncs.c:2277 utils/adt/arrayfuncs.c:2326 utils/adt/arrayfuncs.c:2565 utils/adt/arrayfuncs.c:2887 utils/adt/arrayfuncs.c:5835 utils/adt/arrayfuncs.c:5861 utils/adt/arrayfuncs.c:5872 utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4427 utils/adt/jsonfuncs.c:4580 utils/adt/jsonfuncs.c:4692 utils/adt/jsonfuncs.c:4741 +#, c-format +msgid "wrong number of array subscripts" +msgstr "mauvais nombre d'indices du tableau" + +#: utils/adt/arrayfuncs.c:2260 utils/adt/arrayfuncs.c:2368 utils/adt/arrayfuncs.c:2632 utils/adt/arrayfuncs.c:2946 +#, c-format +msgid "array subscript out of range" +msgstr "indice du tableau en dehors de l'intervalle" + +#: utils/adt/arrayfuncs.c:2265 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "ne peut pas affecter une valeur NULL à un élément d'un tableau à longueur fixe" + +#: utils/adt/arrayfuncs.c:2834 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "" +"les mises à jour de morceaux des tableaux à longueur fixe ne sont pas\n" +"implémentées" + +#: utils/adt/arrayfuncs.c:2865 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "la tranche d'indice de tableau doit fournir les deux limites" + +#: utils/adt/arrayfuncs.c:2866 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "Les limites de tranches doivent être entièrement spécifiées lors de l'assignation d'une valeur d'un tableau vide à une tranche." + +#: utils/adt/arrayfuncs.c:2877 utils/adt/arrayfuncs.c:2973 +#, c-format +msgid "source array too small" +msgstr "tableau source trop petit" + +#: utils/adt/arrayfuncs.c:3528 +#, c-format +msgid "null array element not allowed in this context" +msgstr "élément NULL de tableau interdit dans ce contexte" + +#: utils/adt/arrayfuncs.c:3630 utils/adt/arrayfuncs.c:3801 utils/adt/arrayfuncs.c:4157 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "ne peut pas comparer des tableaux ayant des types d'éléments différents" + +#: utils/adt/arrayfuncs.c:3979 utils/adt/multirangetypes.c:2670 utils/adt/multirangetypes.c:2742 utils/adt/rangetypes.c:1343 utils/adt/rangetypes.c:1407 utils/adt/rowtypes.c:1858 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "n'a pas pu identifier une fonction de hachage pour le type %s" + +#: utils/adt/arrayfuncs.c:4072 utils/adt/rowtypes.c:1979 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "n'a pas pu identifier une fonction de hachage étendue pour le type %s" + +#: utils/adt/arrayfuncs.c:5249 +#, c-format +msgid "data type %s is not an array type" +msgstr "le type de données %s n'est pas un type tableau" + +#: utils/adt/arrayfuncs.c:5304 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "ne peut pas accumuler des tableaux NULL" + +#: utils/adt/arrayfuncs.c:5332 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "ne peut pas concaténer des tableaux vides" + +#: utils/adt/arrayfuncs.c:5359 utils/adt/arrayfuncs.c:5365 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "ne peut pas accumuler des tableaux de dimensions différentes" + +#: utils/adt/arrayfuncs.c:5733 utils/adt/arrayfuncs.c:5773 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "la dimension ou la limite basse du tableau ne peut pas être NULL" + +#: utils/adt/arrayfuncs.c:5836 utils/adt/arrayfuncs.c:5862 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "Le tableau doit avoir une seule dimension." + +#: utils/adt/arrayfuncs.c:5841 utils/adt/arrayfuncs.c:5867 +#, c-format +msgid "dimension values cannot be null" +msgstr "les valeurs de dimension ne peuvent pas être NULL" + +#: utils/adt/arrayfuncs.c:5873 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "La limite basse du tableau a une taille différentes des dimensions du tableau." + +#: utils/adt/arrayfuncs.c:6151 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "la suppression d'éléments de tableaux multidimensionnels n'est pas supportée" + +#: utils/adt/arrayfuncs.c:6428 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "les limites doivent être un tableau à une dimension" + +#: utils/adt/arrayfuncs.c:6433 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "le tableau de limites ne doit pas contenir de valeurs NULL" + +#: utils/adt/arrayfuncs.c:6666 +#, c-format +msgid "number of elements to trim must be between 0 and %d" +msgstr "le nombre d'éléments à couper doit être compris entre 0 et %d" + +#: utils/adt/arraysubs.c:93 utils/adt/arraysubs.c:130 +#, c-format +msgid "array subscript must have type integer" +msgstr "l'indice d'un tableau doit être de type entier" + +#: utils/adt/arraysubs.c:198 utils/adt/arraysubs.c:217 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "l'indice du tableau dans l'affectation ne doit pas être NULL" + +#: utils/adt/arrayutils.c:140 +#, c-format +msgid "array lower bound is too large: %d" +msgstr "" + +#: utils/adt/arrayutils.c:240 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "le tableau typmod doit être de type cstring[]" + +#: utils/adt/arrayutils.c:245 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "le tableau typmod doit avoir une seule dimension" + +#: utils/adt/arrayutils.c:250 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "le tableau typmod ne doit pas contenir de valeurs NULL" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "la conversion de l'encodage de %s vers l'ASCII n'est pas supportée" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3802 utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:283 utils/adt/float.c:400 utils/adt/float.c:485 utils/adt/float.c:501 utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1389 utils/adt/geo_ops.c:1424 utils/adt/geo_ops.c:1432 utils/adt/geo_ops.c:3488 utils/adt/geo_ops.c:4657 utils/adt/geo_ops.c:4672 utils/adt/geo_ops.c:4679 utils/adt/int8.c:126 utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 +#: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:702 utils/adt/numeric.c:721 utils/adt/numeric.c:6861 utils/adt/numeric.c:6885 utils/adt/numeric.c:6909 utils/adt/numeric.c:7878 utils/adt/numutils.c:116 utils/adt/numutils.c:126 utils/adt/numutils.c:170 utils/adt/numutils.c:246 utils/adt/numutils.c:322 utils/adt/oid.c:44 utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 utils/adt/pg_lsn.c:74 utils/adt/tid.c:76 utils/adt/tid.c:84 utils/adt/tid.c:92 utils/adt/timestamp.c:496 utils/adt/uuid.c:136 utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "syntaxe en entrée invalide pour le type %s : « %s »" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "la valeur « %s » est en dehors des limites pour le type %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 utils/adt/float.c:104 utils/adt/int.c:822 utils/adt/int.c:938 utils/adt/int.c:1018 utils/adt/int.c:1080 utils/adt/int.c:1118 utils/adt/int.c:1146 utils/adt/int8.c:600 utils/adt/int8.c:658 utils/adt/int8.c:985 utils/adt/int8.c:1065 utils/adt/int8.c:1127 utils/adt/int8.c:1207 utils/adt/numeric.c:3032 utils/adt/numeric.c:3055 utils/adt/numeric.c:3140 utils/adt/numeric.c:3158 utils/adt/numeric.c:3254 utils/adt/numeric.c:8427 utils/adt/numeric.c:8717 utils/adt/numeric.c:10299 utils/adt/timestamp.c:3281 +#, c-format +msgid "division by zero" +msgstr "division par zéro" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "« char » hors des limites" + +#: utils/adt/date.c:62 utils/adt/timestamp.c:97 utils/adt/varbit.c:105 utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "modifieur de type invalide" + +#: utils/adt/date.c:74 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "la précision de TIME(%d)%s ne doit pas être négative" + +#: utils/adt/date.c:80 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "la précision de TIME(%d)%s a été réduite au maximum autorisée, %d" + +#: utils/adt/date.c:159 utils/adt/date.c:167 utils/adt/formatting.c:4252 utils/adt/formatting.c:4261 utils/adt/formatting.c:4367 utils/adt/formatting.c:4377 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "date en dehors des limites : « %s »" + +#: utils/adt/date.c:214 utils/adt/date.c:525 utils/adt/date.c:549 utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "date en dehors des limites" + +#: utils/adt/date.c:260 utils/adt/timestamp.c:580 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "valeur du champ date en dehors des limites : %d-%02d-%02d" + +#: utils/adt/date.c:267 utils/adt/date.c:276 utils/adt/timestamp.c:586 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "date en dehors des limites : %d-%02d-%02d" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "ne peut pas soustraire les valeurs dates infinies" + +#: utils/adt/date.c:598 utils/adt/date.c:661 utils/adt/date.c:697 utils/adt/date.c:2881 utils/adt/date.c:2891 +#, c-format +msgid "date out of range for timestamp" +msgstr "date en dehors des limites pour un timestamp" + +#: utils/adt/date.c:1127 utils/adt/date.c:1210 utils/adt/date.c:1226 +#, c-format +msgid "date units \"%s\" not supported" +msgstr "unités de date « %s » non supportées" + +#: utils/adt/date.c:1235 +#, c-format +msgid "date units \"%s\" not recognized" +msgstr "unités de date « %s » non reconnues" + +#: utils/adt/date.c:1318 utils/adt/date.c:1364 utils/adt/date.c:1920 utils/adt/date.c:1951 utils/adt/date.c:1980 utils/adt/date.c:2844 utils/adt/datetime.c:405 utils/adt/datetime.c:1700 utils/adt/formatting.c:4109 utils/adt/formatting.c:4141 utils/adt/formatting.c:4221 utils/adt/formatting.c:4343 utils/adt/json.c:418 utils/adt/json.c:457 utils/adt/timestamp.c:224 utils/adt/timestamp.c:256 utils/adt/timestamp.c:698 utils/adt/timestamp.c:707 utils/adt/timestamp.c:785 utils/adt/timestamp.c:818 utils/adt/timestamp.c:2860 utils/adt/timestamp.c:2881 utils/adt/timestamp.c:2894 utils/adt/timestamp.c:2903 utils/adt/timestamp.c:2911 utils/adt/timestamp.c:2966 utils/adt/timestamp.c:2989 +#: utils/adt/timestamp.c:3002 utils/adt/timestamp.c:3013 utils/adt/timestamp.c:3021 utils/adt/timestamp.c:3681 utils/adt/timestamp.c:3806 utils/adt/timestamp.c:3891 utils/adt/timestamp.c:3981 utils/adt/timestamp.c:4069 utils/adt/timestamp.c:4172 utils/adt/timestamp.c:4674 utils/adt/timestamp.c:4948 utils/adt/timestamp.c:5401 utils/adt/timestamp.c:5415 utils/adt/timestamp.c:5420 utils/adt/timestamp.c:5434 utils/adt/timestamp.c:5467 utils/adt/timestamp.c:5554 utils/adt/timestamp.c:5595 utils/adt/timestamp.c:5599 utils/adt/timestamp.c:5668 utils/adt/timestamp.c:5672 utils/adt/timestamp.c:5686 utils/adt/timestamp.c:5720 utils/adt/xml.c:2232 utils/adt/xml.c:2239 utils/adt/xml.c:2259 +#: utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "timestamp en dehors des limites" + +#: utils/adt/date.c:1537 utils/adt/date.c:2339 utils/adt/formatting.c:4429 +#, c-format +msgid "time out of range" +msgstr "heure en dehors des limites" + +#: utils/adt/date.c:1589 utils/adt/timestamp.c:595 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "valeur du champ time en dehors des limites : %d:%02d:%02g" + +#: utils/adt/date.c:2109 utils/adt/date.c:2643 utils/adt/float.c:1047 utils/adt/float.c:1123 utils/adt/int.c:614 utils/adt/int.c:661 utils/adt/int.c:696 utils/adt/int8.c:499 utils/adt/numeric.c:2443 utils/adt/timestamp.c:3330 utils/adt/timestamp.c:3361 utils/adt/timestamp.c:3392 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "taille précédente ou suivante invalide dans la fonction de fenêtrage" + +#: utils/adt/date.c:2208 utils/adt/date.c:2224 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "unités « %s » non reconnues pour le type « time »" + +#: utils/adt/date.c:2347 +#, c-format +msgid "time zone displacement out of range" +msgstr "déplacement du fuseau horaire en dehors des limites" + +#: utils/adt/date.c:2986 utils/adt/date.c:3006 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "unités « %s » non reconnues pour le type « time with time zone »" + +#: utils/adt/date.c:3095 utils/adt/datetime.c:951 utils/adt/datetime.c:1858 utils/adt/datetime.c:4648 utils/adt/timestamp.c:515 utils/adt/timestamp.c:542 utils/adt/timestamp.c:4255 utils/adt/timestamp.c:5426 utils/adt/timestamp.c:5678 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "le fuseau horaire « %s » n'est pas reconnu" + +#: utils/adt/date.c:3127 utils/adt/timestamp.c:5456 utils/adt/timestamp.c:5709 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "l'intervalle de fuseau horaire « %s » ne doit pas spécifier de mois ou de jours" + +#: utils/adt/datetime.c:3775 utils/adt/datetime.c:3782 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "valeur du champ date/time en dehors des limites : « %s »" + +#: utils/adt/datetime.c:3784 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Peut-être avez-vous besoin d'un paramétrage « datestyle » différent." + +#: utils/adt/datetime.c:3789 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "valeur du champ interval en dehors des limites : « %s »" + +#: utils/adt/datetime.c:3795 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "déplacement du fuseau horaire en dehors des limites : « %s »" + +#: utils/adt/datetime.c:4650 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "Ce nom du fuseau horaire apparaît dans le fichier de configuration des abréviations de fuseaux horaires « %s »." + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "pointeur Datum invalide" + +#: utils/adt/dbsize.c:749 utils/adt/dbsize.c:817 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "taille invalide : « %s »" + +#: utils/adt/dbsize.c:818 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "Unité invalide pour une taille : « %s »." + +#: utils/adt/dbsize.c:819 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Les unités valides pour ce paramètre sont « bytes », « kB », « MB », « GB » et « TB »." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "le type %s n'est pas un domaine" + +#: utils/adt/encode.c:68 utils/adt/encode.c:112 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "encodage non reconnu : « %s »" + +#: utils/adt/encode.c:82 +#, c-format +msgid "result of encoding conversion is too large" +msgstr "la résultat de la conversion d'encodage est trop importante" + +#: utils/adt/encode.c:126 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "le résultat de la conversion du décodage est trop grand" + +#: utils/adt/encode.c:261 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "« = » inattendu lors du décodage de la séquence en base64" + +#: utils/adt/encode.c:273 +#, c-format +msgid "invalid symbol \"%.*s\" found while decoding base64 sequence" +msgstr "symbole « %.*s » invalide trouvé lors du décodage de la séquence en base64" + +#: utils/adt/encode.c:304 +#, c-format +msgid "invalid base64 end sequence" +msgstr "séquence base64 de fin invalide" + +#: utils/adt/encode.c:305 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "Les données en entrée manquent un alignement, sont tronquées ou ont une corruption autre." + +#: utils/adt/enum.c:99 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "utilisation non sûre de la nouvelle valeur « %s » du type enum %s" + +#: utils/adt/enum.c:102 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "Les nouvelles valeurs enum doivent être validées (COMMIT) avant de pouvoir être utilisées." + +#: utils/adt/enum.c:120 utils/adt/enum.c:130 utils/adt/enum.c:188 utils/adt/enum.c:198 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "valeur en entrée invalide pour le enum %s : « %s »" + +#: utils/adt/enum.c:160 utils/adt/enum.c:226 utils/adt/enum.c:285 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "valeur interne invalide pour le enum : %u" + +#: utils/adt/enum.c:445 utils/adt/enum.c:474 utils/adt/enum.c:514 utils/adt/enum.c:534 +#, c-format +msgid "could not determine actual enum type" +msgstr "n'a pas pu déterminer le type enum actuel" + +#: utils/adt/enum.c:453 utils/adt/enum.c:482 +#, c-format +msgid "enum %s contains no values" +msgstr "l'énumération « %s » ne contient aucune valeur" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "valeur en dehors des limites : dépassement" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "valeur en dehors des limites : trop petit" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "« %s » est en dehors des limites du type real" + +#: utils/adt/float.c:477 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "« %s » est en dehors des limites du type double precision" + +#: utils/adt/float.c:1258 utils/adt/float.c:1332 utils/adt/int.c:334 utils/adt/int.c:872 utils/adt/int.c:894 utils/adt/int.c:908 utils/adt/int.c:922 utils/adt/int.c:954 utils/adt/int.c:1192 utils/adt/int8.c:1320 utils/adt/numeric.c:4317 utils/adt/numeric.c:4326 +#, c-format +msgid "smallint out of range" +msgstr "smallint en dehors des limites" + +#: utils/adt/float.c:1458 utils/adt/numeric.c:3550 utils/adt/numeric.c:9310 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "ne peut pas calculer la racine carré d'un nombre négatif" + +#: utils/adt/float.c:1526 utils/adt/numeric.c:3825 utils/adt/numeric.c:3935 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "zéro à une puissance négative est indéfini" + +#: utils/adt/float.c:1530 utils/adt/numeric.c:3829 utils/adt/numeric.c:3940 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "un nombre négatif élevé à une puissance non entière donne un résultat complexe" + +#: utils/adt/float.c:1706 utils/adt/float.c:1739 utils/adt/numeric.c:3737 utils/adt/numeric.c:9974 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "ne peut pas calculer le logarithme de zéro" + +#: utils/adt/float.c:1710 utils/adt/float.c:1743 utils/adt/numeric.c:3675 utils/adt/numeric.c:3732 utils/adt/numeric.c:9978 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "ne peut pas calculer le logarithme sur un nombre négatif" + +#: utils/adt/float.c:1776 utils/adt/float.c:1807 utils/adt/float.c:1902 utils/adt/float.c:1929 utils/adt/float.c:1957 utils/adt/float.c:1984 utils/adt/float.c:2131 utils/adt/float.c:2168 utils/adt/float.c:2338 utils/adt/float.c:2394 utils/adt/float.c:2459 utils/adt/float.c:2516 utils/adt/float.c:2707 utils/adt/float.c:2731 +#, c-format +msgid "input is out of range" +msgstr "l'entrée est en dehors des limites" + +#: utils/adt/float.c:2798 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "le paramètre setseed %g est en dehors de la fenêtre permise [-1,1]" + +#: utils/adt/float.c:4030 utils/adt/numeric.c:1716 +#, c-format +msgid "count must be greater than zero" +msgstr "le total doit être supérieur à zéro" + +#: utils/adt/float.c:4035 utils/adt/numeric.c:1727 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "la limite inférieure et supérieure de l'opérande ne peuvent pas être NaN" + +#: utils/adt/float.c:4041 utils/adt/numeric.c:1732 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "les limites basse et haute doivent être finies" + +#: utils/adt/float.c:4075 utils/adt/numeric.c:1746 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "la limite inférieure ne peut pas être plus égale à la limite supérieure" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "format de spécification invalide pour une valeur intervalle" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "Les intervalles ne sont pas liés aux dates de calendriers spécifiques." + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "« EEEE » doit être le dernier motif utilisé" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "« 9 » doit être avant « PR »" + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "« 0 » doit être avant « PR »" + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "multiples points décimaux" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "ne peut pas utiliser « V » et le point décimal ensemble" + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "ne peut pas utiliser « S » deux fois" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "ne peut pas utiliser « S » et « PL »/« MI »/« SG »/« PR » ensemble" + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "ne peut pas utiliser « S » et « MI » ensemble" + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "ne peut pas utiliser « S » et « PL » ensemble" + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "ne peut pas utiliser « S » et « SG » ensemble" + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "ne peut pas utiliser « PR » et « S »/« PL »/« MI »/« SG » ensemble" + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "ne peut pas utiliser « EEEE » deux fois" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "« EEEE » est incompatible avec les autres formats" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "« EEEE » ne peut être utilisé qu'avec les motifs de chiffres et de points décimaux." + +#: utils/adt/formatting.c:1394 +#, c-format +msgid "invalid datetime format separator: \"%s\"" +msgstr "séparateur de format datetime invalide : « %s »" + +#: utils/adt/formatting.c:1521 +#, c-format +msgid "\"%s\" is not a number" +msgstr "« %s » n'est pas un nombre" + +#: utils/adt/formatting.c:1599 +#, c-format +msgid "case conversion failed: %s" +msgstr "échec de la conversion de casse : %s" + +#: utils/adt/formatting.c:1664 utils/adt/formatting.c:1788 utils/adt/formatting.c:1913 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour la fonction %s" + +#: utils/adt/formatting.c:2285 +#, c-format +msgid "invalid combination of date conventions" +msgstr "combinaison invalide des conventions de date" + +#: utils/adt/formatting.c:2286 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "" +"Ne pas mixer les conventions de jour de semaine grégorien et ISO dans un\n" +"modèle de formatage." + +#: utils/adt/formatting.c:2309 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "valeur conflictuelle pour le champ « %s » dans la chaîne de formatage" + +#: utils/adt/formatting.c:2312 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "Cette valeur contredit une configuration précédente pour le même type de champ." + +#: utils/adt/formatting.c:2383 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "chaîne source trop petite pour le champ de formatage « %s »" + +#: utils/adt/formatting.c:2386 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "Le champ requiert %d caractères, mais seuls %d restent." + +#: utils/adt/formatting.c:2389 utils/adt/formatting.c:2404 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "" +"Si votre chaîne source n'a pas une taille fixe, essayez d'utiliser le\n" +"modifieur « FM »." + +#: utils/adt/formatting.c:2399 utils/adt/formatting.c:2413 utils/adt/formatting.c:2636 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "valeur « %s » invalide pour « %s »" + +#: utils/adt/formatting.c:2401 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "Le champ nécessite %d caractères, mais seulement %d ont pu être analysés." + +#: utils/adt/formatting.c:2415 +#, c-format +msgid "Value must be an integer." +msgstr "La valeur doit être un entier." + +#: utils/adt/formatting.c:2420 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "la valeur pour « %s » dans la chaîne source est en dehors des limites" + +#: utils/adt/formatting.c:2422 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "La valeur doit être compris entre %d et %d." + +#: utils/adt/formatting.c:2638 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "La valeur donnée ne correspond pas aux valeurs autorisées pour ce champ." + +#: utils/adt/formatting.c:2855 utils/adt/formatting.c:2875 utils/adt/formatting.c:2895 utils/adt/formatting.c:2915 utils/adt/formatting.c:2934 utils/adt/formatting.c:2953 utils/adt/formatting.c:2977 utils/adt/formatting.c:2995 utils/adt/formatting.c:3013 utils/adt/formatting.c:3031 utils/adt/formatting.c:3048 utils/adt/formatting.c:3065 +#, c-format +msgid "localized string format value too long" +msgstr "chaîne localisée trop longue" + +#: utils/adt/formatting.c:3342 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "séparateur de format « %c » sans correspondance" + +#: utils/adt/formatting.c:3403 +#, c-format +msgid "unmatched format character \"%s\"" +msgstr "caractère de format « %s » sans correspondance" + +#: utils/adt/formatting.c:3509 utils/adt/formatting.c:3853 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "le formatage du champ « %s » est seulement supporté dans to_char" + +#: utils/adt/formatting.c:3684 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "chaîne invalide en entrée pour « Y,YYY »" + +#: utils/adt/formatting.c:3770 +#, c-format +msgid "input string is too short for datetime format" +msgstr "la chaîne en entrée est trop courte pour le format datetime" + +#: utils/adt/formatting.c:3778 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "les caractères en fin de chaîne restent dans la chaîne en entrée après le format datetime" + +#: utils/adt/formatting.c:4323 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "manque du fuseau horaire dans la chaîne en entrée pour le type timestamptz" + +#: utils/adt/formatting.c:4329 +#, c-format +msgid "timestamptz out of range" +msgstr "timestamptz en dehors des limites" + +#: utils/adt/formatting.c:4357 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "le format datetime a une zone de fuseau horaire mais pas d'heure" + +#: utils/adt/formatting.c:4409 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "manque du fuseau horaire dans la chaîne en entrée pour le type timetz" + +#: utils/adt/formatting.c:4415 +#, c-format +msgid "timetz out of range" +msgstr "timetz en dehors des limites" + +#: utils/adt/formatting.c:4441 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "le format datetime n'a ni date ni heure" + +#: utils/adt/formatting.c:4574 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "l'heure « %d » est invalide pour une horloge sur 12 heures" + +#: utils/adt/formatting.c:4576 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Utilisez une horloge sur 24 heures ou donnez une heure entre 1 et 12." + +#: utils/adt/formatting.c:4687 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "ne peut pas calculer le jour de l'année sans information sur l'année" + +#: utils/adt/formatting.c:5606 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "« EEEE » non supporté en entrée" + +#: utils/adt/formatting.c:5618 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "« RN » non supporté en entrée" + +#: utils/adt/genfile.c:78 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "référence non autorisée au répertoire parent (« .. »)" + +#: utils/adt/genfile.c:89 +#, c-format +msgid "absolute path not allowed" +msgstr "chemin absolu non autorisé" + +#: utils/adt/genfile.c:94 +#, c-format +msgid "path must be in or below the current directory" +msgstr "le chemin doit être dans ou en-dessous du répertoire courant" + +#: utils/adt/genfile.c:119 utils/adt/oracle_compat.c:187 utils/adt/oracle_compat.c:285 utils/adt/oracle_compat.c:833 utils/adt/oracle_compat.c:1128 +#, c-format +msgid "requested length too large" +msgstr "longueur demandée trop importante" + +#: utils/adt/genfile.c:136 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "n'a pas pu parcourir le fichier « %s » : %m" + +#: utils/adt/genfile.c:176 +#, c-format +msgid "file length too large" +msgstr "longueur du fichier trop importante" + +#: utils/adt/genfile.c:253 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "doit être super-utilisateur pour lire des fichiers avec adminpack 1.0" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "spécification invalide de ligne : A et B ne peuvent pas être à zéro tous les deux" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1097 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "spécification de ligne invalide : doit être deux points distincts" + +#: utils/adt/geo_ops.c:1410 utils/adt/geo_ops.c:3498 utils/adt/geo_ops.c:4366 utils/adt/geo_ops.c:5260 +#, c-format +msgid "too many points requested" +msgstr "trop de points demandé" + +#: utils/adt/geo_ops.c:1472 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "nombre de points invalide dans la valeur externe de « path »" + +#: utils/adt/geo_ops.c:2549 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "la fonction « dist_lb » n'est pas implémentée" + +#: utils/adt/geo_ops.c:2568 +#, c-format +msgid "function \"dist_bl\" not implemented" +msgstr "fonction « dist_lb » non implémentée" + +#: utils/adt/geo_ops.c:2987 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "la fonction « close_sl » n'est pas implémentée" + +#: utils/adt/geo_ops.c:3134 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "la fonction « close_lb » n'est pas implémentée" + +#: utils/adt/geo_ops.c:3545 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "nombre de points invalide dans la valeur externe de « polygon »" + +#: utils/adt/geo_ops.c:4081 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "la fonction « poly_distance » n'est pas implémentée" + +#: utils/adt/geo_ops.c:4458 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "la fonction « path_center » n'est pas implémentée" + +#: utils/adt/geo_ops.c:4475 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "le chemin ouvert ne peut être converti en polygône" + +#: utils/adt/geo_ops.c:4725 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "diamètre invalide pour la valeur externe de « circle »" + +#: utils/adt/geo_ops.c:5246 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "ne peut pas convertir le cercle avec un diamètre zéro en un polygône" + +#: utils/adt/geo_ops.c:5251 +#, c-format +msgid "must request at least 2 points" +msgstr "doit demander au moins deux points" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector a trop d'éléments" + +#: utils/adt/int.c:237 +#, c-format +msgid "invalid int2vector data" +msgstr "données int2vector invalide" + +#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector a trop d'éléments" + +#: utils/adt/int.c:1508 utils/adt/int8.c:1446 utils/adt/numeric.c:1624 utils/adt/timestamp.c:5771 utils/adt/timestamp.c:5851 +#, c-format +msgid "step size cannot equal zero" +msgstr "la taille du pas ne peut pas valoir zéro" + +#: utils/adt/int8.c:534 utils/adt/int8.c:557 utils/adt/int8.c:571 utils/adt/int8.c:585 utils/adt/int8.c:616 utils/adt/int8.c:640 utils/adt/int8.c:722 utils/adt/int8.c:790 utils/adt/int8.c:796 utils/adt/int8.c:822 utils/adt/int8.c:836 utils/adt/int8.c:860 utils/adt/int8.c:873 utils/adt/int8.c:942 utils/adt/int8.c:956 utils/adt/int8.c:970 utils/adt/int8.c:1001 utils/adt/int8.c:1023 utils/adt/int8.c:1037 utils/adt/int8.c:1051 utils/adt/int8.c:1084 utils/adt/int8.c:1098 utils/adt/int8.c:1112 utils/adt/int8.c:1143 utils/adt/int8.c:1165 utils/adt/int8.c:1179 utils/adt/int8.c:1193 utils/adt/int8.c:1355 utils/adt/int8.c:1390 utils/adt/numeric.c:4276 utils/adt/varbit.c:1676 +#, c-format +msgid "bigint out of range" +msgstr "bigint en dehors des limites" + +#: utils/adt/int8.c:1403 +#, c-format +msgid "OID out of range" +msgstr "OID en dehors des limites" + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "la valeur clé doit être scalaire, et non pas un tableau ou une valeur composite ou un json" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1992 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "n'a pas pu déterminer le type de données pour l'argument %d" + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "le nom du champ ne doit pas être NULL" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "la liste d'arguments doit avoir un nombre pair d'éléments" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "Les arguments de %s doivent consister en clés et valeurs alternées." + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "l'argument %d ne peut pas être NULL" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "Les clés de l'objet doivent être du texte." + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "le tableau doit avoir deux colonnes" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "valeur NULL non autorisée pour une clé d'objet" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "dimensions du tableau non correspondantes" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "chaîne trop longue pour être représentée en tant que chaîne jsonb" + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "Dû à l'implémentation, les chaînes jsonb ne peuvent excéder %d octets." + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "argument %d : la clé ne doit pas être NULL" + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "les clés de l'objet doivent être du texte" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "ne peut pas convertir un jsonb NULL vers le type %s" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "ne peut pas convertir la chaîne jsonb vers le type %s" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "ne peut pas convertir le numeric jsonb vers le type %s" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "ne peut pas convertir le booléen jsonb vers le type %s" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "ne peut pas convertir le tableau jsonb vers le type %s" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "ne peut pas convertir l'objet jsonb vers le type %s" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "ne peut pas convertir le tableau ou l'objet jsonb vers le type %s" + +#: utils/adt/jsonb_util.c:751 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "le nombre de paires d'objets jsonb dépasse le maximum autorisé (%zu)" + +#: utils/adt/jsonb_util.c:792 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "le nombre d'éléments du tableau jsonb dépasse le maximum autorisé (%zu)" + +#: utils/adt/jsonb_util.c:1666 utils/adt/jsonb_util.c:1686 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "la taille totale des éléments du tableau jsonb dépasse le maximum de %u octets" + +#: utils/adt/jsonb_util.c:1747 utils/adt/jsonb_util.c:1782 utils/adt/jsonb_util.c:1802 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "la taille totale des éléments de l'objet JSON dépasse le maximum de %u octets" + +#: utils/adt/jsonbsubs.c:70 utils/adt/jsonbsubs.c:152 +#, c-format +msgid "jsonb subscript does not support slices" +msgstr "" + +#: utils/adt/jsonbsubs.c:103 utils/adt/jsonbsubs.c:118 +#, c-format +msgid "subscript type is not supported" +msgstr "le type subscript n'est pas supporté" + +#: utils/adt/jsonbsubs.c:104 +#, c-format +msgid "Jsonb subscript must be coerced only to one type, integer or text." +msgstr "" + +#: utils/adt/jsonbsubs.c:119 +#, c-format +msgid "Jsonb subscript must be coerced to either integer or text" +msgstr "" + +#: utils/adt/jsonbsubs.c:140 +#, c-format +msgid "jsonb subscript must have text type" +msgstr "l'indice d'un jsonb doit être de type text" + +#: utils/adt/jsonbsubs.c:208 +#, c-format +msgid "jsonb subscript in assignment must not be null" +msgstr "l'indice d'un jsonb lors d'une affectation ne doit pas être NULL" + +#: utils/adt/jsonfuncs.c:555 utils/adt/jsonfuncs.c:789 utils/adt/jsonfuncs.c:2471 utils/adt/jsonfuncs.c:2911 utils/adt/jsonfuncs.c:3700 utils/adt/jsonfuncs.c:4030 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "ne peut pas appeler %s sur un scalaire" + +#: utils/adt/jsonfuncs.c:560 utils/adt/jsonfuncs.c:776 utils/adt/jsonfuncs.c:2913 utils/adt/jsonfuncs.c:3689 +#, c-format +msgid "cannot call %s on an array" +msgstr "ne peut pas appeler %s sur un tableau" + +#: utils/adt/jsonfuncs.c:685 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "données JSON, ligne %d : %s%s%s" + +#: utils/adt/jsonfuncs.c:1823 utils/adt/jsonfuncs.c:1858 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "ne peut pas obtenir la longueur d'un scalaire" + +#: utils/adt/jsonfuncs.c:1827 utils/adt/jsonfuncs.c:1846 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "ne peut pas obtenir la longueur du tableau d'un objet qui n'est pas un tableau" + +#: utils/adt/jsonfuncs.c:1923 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "ne peut pas appeler %s sur un non objet" + +#: utils/adt/jsonfuncs.c:2162 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "ne peut pas déconstruire un tableau sous la forme d'un objet" + +#: utils/adt/jsonfuncs.c:2174 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "ne peut pas décomposer un scalaire" + +#: utils/adt/jsonfuncs.c:2220 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "ne peut pas extraire des éléments d'un scalaire" + +#: utils/adt/jsonfuncs.c:2224 +#, c-format +msgid "cannot extract elements from an object" +msgstr "ne peut pas extraire des éléments d'un objet" + +#: utils/adt/jsonfuncs.c:2458 utils/adt/jsonfuncs.c:3915 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "ne peut pas appeler %s sur un type non tableau" + +#: utils/adt/jsonfuncs.c:2528 utils/adt/jsonfuncs.c:2533 utils/adt/jsonfuncs.c:2550 utils/adt/jsonfuncs.c:2556 +#, c-format +msgid "expected JSON array" +msgstr "attendait un tableau JSON" + +#: utils/adt/jsonfuncs.c:2529 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Voir la valeur de la clé « %s »." + +#: utils/adt/jsonfuncs.c:2551 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Voir l'élément de tableau %s de la clé « %s »." + +#: utils/adt/jsonfuncs.c:2557 +#, c-format +msgid "See the array element %s." +msgstr "Voir l'élément de tableau %s." + +#: utils/adt/jsonfuncs.c:2592 +#, c-format +msgid "malformed JSON array" +msgstr "tableau JSON mal formé" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3419 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "le premier argument de %s doit être un type row" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3443 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "n'a pas pu déterminer le type de ligne pour le résultat %s" + +#: utils/adt/jsonfuncs.c:3445 +#, c-format +msgid "Provide a non-null record argument, or call the function in the FROM clause using a column definition list." +msgstr "Fournissez comme argument un enregistrement non NULL, ou appelez la fonction dans la clause FROM en utilisant une liste de définition de colonnes." + +#: utils/adt/jsonfuncs.c:3932 utils/adt/jsonfuncs.c:4012 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "l'argument de %s doit être un tableau d'objets" + +#: utils/adt/jsonfuncs.c:3965 +#, c-format +msgid "cannot call %s on an object" +msgstr "ne peut pas appeler %s sur un objet" + +#: utils/adt/jsonfuncs.c:4373 utils/adt/jsonfuncs.c:4432 utils/adt/jsonfuncs.c:4512 +#, c-format +msgid "cannot delete from scalar" +msgstr "ne peut pas supprimer à partir du scalaire" + +#: utils/adt/jsonfuncs.c:4517 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "ne peut pas supprimer à partir de l'objet en utilisant l'index de l'entier" + +#: utils/adt/jsonfuncs.c:4585 utils/adt/jsonfuncs.c:4746 +#, c-format +msgid "cannot set path in scalar" +msgstr "ne peut pas initialiser le chemin dans le scalaire" + +#: utils/adt/jsonfuncs.c:4627 utils/adt/jsonfuncs.c:4669 +#, c-format +msgid "null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"" +msgstr "null_value_treatment doit valoir \"delete_key\", \"return_target\", \"use_json_null\" ou \"raise_exception\"" + +#: utils/adt/jsonfuncs.c:4640 +#, c-format +msgid "JSON value must not be null" +msgstr "la valeur JSON ne doit pas être NULL" + +#: utils/adt/jsonfuncs.c:4641 +#, c-format +msgid "Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "Une exception a été levée parce que null_value_treatment vaut « raise_exception »." + +#: utils/adt/jsonfuncs.c:4642 +#, c-format +msgid "To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed." +msgstr "Pour éviter cela, soit vous changez l'argument null_value_treatment soit vous vous assurez qu'un NULL SQL n'est pas fourni" + +#: utils/adt/jsonfuncs.c:4697 +#, c-format +msgid "cannot delete path in scalar" +msgstr "ne peut pas supprimer un chemin dans le scalaire" + +#: utils/adt/jsonfuncs.c:4913 +#, c-format +msgid "path element at position %d is null" +msgstr "l'élément de chemin à la position %d est nul" + +#: utils/adt/jsonfuncs.c:4932 utils/adt/jsonfuncs.c:4963 utils/adt/jsonfuncs.c:5030 +#, c-format +msgid "cannot replace existing key" +msgstr "ne peut pas remplacer une clé existante" + +#: utils/adt/jsonfuncs.c:4933 utils/adt/jsonfuncs.c:4964 +#, c-format +msgid "The path assumes key is a composite object, but it is a scalar value." +msgstr "Le chemin assume que la clé est un objet composite, alors qu'il s'agit d'une valeur scalaire." + +#: utils/adt/jsonfuncs.c:5031 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "Essayez d'utiliser la fonction jsonb_set pour remplacer la valeur de la clé." + +#: utils/adt/jsonfuncs.c:5135 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "l'élément du chemin à la position %d n'est pas un entier : « %s »" + +#: utils/adt/jsonfuncs.c:5152 +#, c-format +msgid "path element at position %d is out of range: %d" +msgstr "l'élément du chemin à la position %d est en dehors de l'échelle : %d" + +#: utils/adt/jsonfuncs.c:5304 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "mauvais type de drapeau, seuls les tableaux et scalaires sont autorisés" + +#: utils/adt/jsonfuncs.c:5311 +#, c-format +msgid "flag array element is not a string" +msgstr "le drapeau d'élément de tableau n'est pas une chaîne" + +#: utils/adt/jsonfuncs.c:5312 utils/adt/jsonfuncs.c:5334 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "Les valeurs possibles sont : « string », « numeric », « boolean », « key » et « all »." + +#: utils/adt/jsonfuncs.c:5332 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "mauvais drapeau dans le drapeau de tableau : « %s »" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ n'est pas autorisé dans les expressions racine" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST n'est autorisé que dans les indices de tableau" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "un résultat booléen unique est attendu" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "l'argument « vars » n'est pas un objet" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "Les paramètres jsonpath doivent être encodés en paires clé-valeur d'objets « vars »" + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "l'objet JSON ne contient pas la clé « %s »" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "l'accesseur du membre jsonpath ne peut être appliqué qu'à un objet" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "l'accesseur de tableau générique jsonpath ne peut être appliqué qu'à un tableau" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "indice du tableau jsonpath hors limites" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "l'accesseur de tableau jsonpath ne peut être appliqué qu'à un tableau" + +#: utils/adt/jsonpath_exec.c:872 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "l'accesseur du membre générique jsonpath ne peut être appliqué qu'à un objet" + +#: utils/adt/jsonpath_exec.c:1002 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "la méthode de l'objet jsonpath .%s() ne peut être appliquée qu'à un tableau" + +#: utils/adt/jsonpath_exec.c:1055 +#, c-format +msgid "numeric argument of jsonpath item method .%s() is out of range for type double precision" +msgstr "l'argument numérique de la méthode jsonpath .%s() est en dehors des limites du type double precision" + +#: utils/adt/jsonpath_exec.c:1076 +#, c-format +msgid "string argument of jsonpath item method .%s() is not a valid representation of a double precision number" +msgstr "l'argument chaîne de la méthode jsonpath .%s() n'est pas une représentation valide d'un nombre à double précision" + +#: utils/adt/jsonpath_exec.c:1089 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "la méthode de l'objet jsonpath .%s() ne peut être appliquée qu'à une chaîne ou une valeur numérique" + +#: utils/adt/jsonpath_exec.c:1579 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "l'opérande gauche de l'opérateur jsonpath %s n'est pas une valeur numérique unique" + +#: utils/adt/jsonpath_exec.c:1586 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "l'opérande droite de l'opérateur jsonpath %s n'est pas une valeur numérique unique" + +#: utils/adt/jsonpath_exec.c:1654 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "l'opérande de l'opérateur jsonpath unaire %s n'est pas une valeur numérique" + +#: utils/adt/jsonpath_exec.c:1752 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "la méthode de l'objet jsonpath .%s() ne peut être appliquée qu'à une valeur numérique" + +#: utils/adt/jsonpath_exec.c:1792 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "la méthode de l'objet jsonpath .%s() ne peut être appliquée qu'à une chaîne" + +#: utils/adt/jsonpath_exec.c:1886 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "le format datetime n'est pas reconnu : « %s »" + +#: utils/adt/jsonpath_exec.c:1888 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "Utilisez un argument modèle de datetime pour indiquer le format de données en entrée." + +#: utils/adt/jsonpath_exec.c:1956 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "la méthode .%s() de l'entité jsonpath ne peut être appliquée qu'à un objet" + +#: utils/adt/jsonpath_exec.c:2138 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "n'a pas pu trouver la variable jsonpath « %s »" + +#: utils/adt/jsonpath_exec.c:2402 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "l'indice du tableau jsonpath n'est pas une valeur numérique unique" + +#: utils/adt/jsonpath_exec.c:2414 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "indice du tableau jsonpath hors des limites d'un entier" + +#: utils/adt/jsonpath_exec.c:2591 +#, c-format +msgid "cannot convert value from %s to %s without time zone usage" +msgstr "ne peut pas convertir la valeur de %s à %s sans utilisation des fuseaux horaires" + +#: utils/adt/jsonpath_exec.c:2593 +#, c-format +msgid "Use *_tz() function for time zone support." +msgstr "Utilisez la fonction *_tz() pour le support des fuseaux horaires." + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "l'argument levenshtein dépasse la longueur maximale de %d caractères" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "les collationnements non déterministes ne sont pas supportés pour LIKE" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour ILIKE" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "les collationnements non déterministes ne sont pas supportés pour ILIKE" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "le motif LIKE ne doit pas se terminer avec un caractère d'échappement" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "chaîne d'échappement invalide" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "La chaîne d'échappement doit être vide ou ne contenir qu'un caractère." + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "la recherche insensible à la casse n'est pas supportée avec le type bytea" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "la recherche par expression rationnelle n'est pas supportée sur le type bytea" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "valeur d'un octet invalide dans la valeur de « macaddr » : « %s »" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "donnée macaddr8 hors de l'échelle pour être convertie en macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Seules les adresses qui ont FF ou FE comme valeurs dans les 4è et 5è octets à partir de la gauche, par exemple xx:xx:xx:ff:fe:xx:xx:xx, , sont éligibles à être converties de macaddr8 à macaddr." + +#: utils/adt/mcxtfuncs.c:184 +#, c-format +msgid "must be a superuser to log memory contexts" +msgstr "doit être super-utilisateur pour tracer les contextes mémoires" + +#: utils/adt/misc.c:243 +#, c-format +msgid "global tablespace never has databases" +msgstr "le tablespace global n'a jamais de bases de données" + +#: utils/adt/misc.c:265 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u n'est pas un OID de tablespace" + +#: utils/adt/misc.c:455 +msgid "unreserved" +msgstr "non réservé" + +#: utils/adt/misc.c:459 +msgid "unreserved (cannot be function or type name)" +msgstr "non réservé (ne peut pas être un nom de fonction ou de type)" + +#: utils/adt/misc.c:463 +msgid "reserved (can be function or type name)" +msgstr "réservé (peut être un nom de fonction ou de type)" + +#: utils/adt/misc.c:467 +msgid "reserved" +msgstr "réservé" + +#: utils/adt/misc.c:478 +msgid "can be bare label" +msgstr "peut être un label brut" + +#: utils/adt/misc.c:483 +msgid "requires AS" +msgstr "requiert AS" + +#: utils/adt/misc.c:730 utils/adt/misc.c:744 utils/adt/misc.c:783 utils/adt/misc.c:789 utils/adt/misc.c:795 utils/adt/misc.c:818 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "la chaîne n'est pas un identifiant valide : « %s »" + +#: utils/adt/misc.c:732 +#, c-format +msgid "String has unclosed double quotes." +msgstr "La chaîne des guillements doubles non fermés." + +#: utils/adt/misc.c:746 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "L'identifiant entre guillemets ne doit pas être vide." + +#: utils/adt/misc.c:785 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "Pas d'identifiant valide avant « . »." + +#: utils/adt/misc.c:791 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "Pas d'identifiant valide après « . »." + +#: utils/adt/misc.c:849 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "le format de trace « %s » n'est pas supporté" + +#: utils/adt/misc.c:850 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "Les formats de traces supportés sont « stderr » et « csvlog »." + +#: utils/adt/multirangetypes.c:147 utils/adt/multirangetypes.c:160 utils/adt/multirangetypes.c:189 utils/adt/multirangetypes.c:259 utils/adt/multirangetypes.c:283 +#, c-format +msgid "malformed multirange literal: \"%s\"" +msgstr "litéral multirange mal formé : « %s »" + +#: utils/adt/multirangetypes.c:149 +#, c-format +msgid "Missing left brace." +msgstr "Parenthèse gauche manquante." + +#: utils/adt/multirangetypes.c:191 +#, c-format +msgid "Expected range start." +msgstr "Début d'intervalle attendu." + +#: utils/adt/multirangetypes.c:261 +#, c-format +msgid "Expected comma or end of multirange." +msgstr "Virgule ou fin de multirange attendue." + +#: utils/adt/multirangetypes.c:285 +#, fuzzy, c-format +#| msgid "Junk after right bracket." +msgid "Junk after right brace." +msgstr "Problème après la parenthèse droite." + +#: utils/adt/multirangetypes.c:971 +#, c-format +msgid "multiranges cannot be constructed from multi-dimensional arrays" +msgstr "des multiranges ne peuvent pas être construits à partir de tableaux multidimensionnels" + +#: utils/adt/multirangetypes.c:977 utils/adt/multirangetypes.c:1042 +#, c-format +msgid "type %u does not match constructor type" +msgstr "le type %u ne correspond pas un type constructeur" + +#: utils/adt/multirangetypes.c:999 +#, c-format +msgid "multirange values cannot contain NULL members" +msgstr "les valeurs multirange ne peuvent pas contenir des membres NULL" + +#: utils/adt/multirangetypes.c:1349 +#, c-format +msgid "range_agg must be called with a range" +msgstr "range_agg doit être appelé avec un intervalle" + +#: utils/adt/multirangetypes.c:1420 +#, c-format +msgid "range_intersect_agg must be called with a multirange" +msgstr "range_intersect_agg doit être appelé avec un multirange" + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "valeur cidr invalide : « %s »" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "La valeur a des bits positionnés à la droite du masque." + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "n'a pas pu formater la valeur inet : %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "famille d'adresses invalide dans la valeur externe « %s »" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "bits invalides dans la valeur externe « %s »" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "longueur invalide dans la valeur externe « %s »" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "valeur externe « cidr » invalide" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "longueur du masque invalide : %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "n'a pas pu formater la valeur cidr : %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "ne peut pas assembler les adresses de familles différentes" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "" +"ne peut pas utiliser l'opérateur AND sur des champs de type inet de tailles\n" +"différentes" + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "" +"ne peut pas utiliser l'opérateur OR sur des champs de type inet de tailles\n" +"différentes" + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "le résultat est en dehors des limites" + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "ne peut pas soustraire des valeurs inet de tailles différentes" + +#: utils/adt/numeric.c:975 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "signe invalide dans la valeur externe « numeric »" + +#: utils/adt/numeric.c:981 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "échelle invalide dans la valeur externe « numeric »" + +#: utils/adt/numeric.c:990 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "chiffre invalide dans la valeur externe « numeric »" + +#: utils/adt/numeric.c:1203 utils/adt/numeric.c:1217 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "la précision NUMERIC %d doit être comprise entre 1 et %d" + +#: utils/adt/numeric.c:1208 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "l'échelle NUMERIC %d doit être comprise entre 0 et le précision %d" + +#: utils/adt/numeric.c:1226 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "modificateur de type NUMERIC invalide" + +#: utils/adt/numeric.c:1584 +#, c-format +msgid "start value cannot be NaN" +msgstr "la valeur de démarrage ne peut pas être NaN" + +#: utils/adt/numeric.c:1588 +#, c-format +msgid "start value cannot be infinity" +msgstr "la valeur de démarrage ne peut pas être infinity" + +#: utils/adt/numeric.c:1595 +#, c-format +msgid "stop value cannot be NaN" +msgstr "la valeur d'arrêt ne peut pas être NaN" + +#: utils/adt/numeric.c:1599 +#, c-format +msgid "stop value cannot be infinity" +msgstr "la valeur d'arrêt ne peut pas être infinity" + +#: utils/adt/numeric.c:1612 +#, c-format +msgid "step size cannot be NaN" +msgstr "la taille du pas ne peut pas être NaN" + +#: utils/adt/numeric.c:1616 +#, c-format +msgid "step size cannot be infinity" +msgstr "la taille du pas ne peut pas être infinity" + +#: utils/adt/numeric.c:3490 +#, c-format +msgid "factorial of a negative number is undefined" +msgstr "la factorielle d'un nombre négatif est indéfini" + +#: utils/adt/numeric.c:3500 utils/adt/numeric.c:6924 utils/adt/numeric.c:7408 utils/adt/numeric.c:9783 utils/adt/numeric.c:10221 utils/adt/numeric.c:10335 utils/adt/numeric.c:10408 +#, c-format +msgid "value overflows numeric format" +msgstr "la valeur dépasse le format numeric" + +#: utils/adt/numeric.c:4185 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "ne peut pas convertir NaN en un entier" + +#: utils/adt/numeric.c:4189 +#, c-format +msgid "cannot convert infinity to integer" +msgstr "ne peut pas convertir infinity en integer" + +#: utils/adt/numeric.c:4263 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "ne peut pas convertir NaN en un entier de type bigint" + +#: utils/adt/numeric.c:4267 +#, c-format +msgid "cannot convert infinity to bigint" +msgstr "ne peut pas convertir infinity en bigint" + +#: utils/adt/numeric.c:4304 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "ne peut pas convertir NaN en un entier de type smallint" + +#: utils/adt/numeric.c:4308 +#, c-format +msgid "cannot convert infinity to smallint" +msgstr "ne peut pas convertir infinity en smallint" + +#: utils/adt/numeric.c:4499 +#, c-format +msgid "cannot convert NaN to pg_lsn" +msgstr "ne peut pas convertir NaN en un pg_lsn" + +#: utils/adt/numeric.c:4503 +#, c-format +msgid "cannot convert infinity to pg_lsn" +msgstr "ne peut pas convertir infinity en pg_lsn" + +#: utils/adt/numeric.c:4512 +#, c-format +msgid "pg_lsn out of range" +msgstr "pg_lsn hors des limites" + +#: utils/adt/numeric.c:7492 utils/adt/numeric.c:7539 +#, c-format +msgid "numeric field overflow" +msgstr "champ numérique en dehors des limites" + +#: utils/adt/numeric.c:7493 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "Un champ de précision %d et d'échelle %d doit être arrondi à une valeur absolue inférieure à %s%d." + +#: utils/adt/numeric.c:7540 +#, c-format +msgid "A field with precision %d, scale %d cannot hold an infinite value." +msgstr "Un champ de précision %d et d'échelle %d ne peut pas contenir une valeur infinie." + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "la valeur « %s » est en dehors des limites des entiers sur 8 bits" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "donnée oidvector invalide" + +#: utils/adt/oracle_compat.c:970 +#, c-format +msgid "requested character too large" +msgstr "caractère demandé trop long" + +#: utils/adt/oracle_compat.c:1020 utils/adt/oracle_compat.c:1082 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "caractère demandé trop long pour l'encodage : %d" + +#: utils/adt/oracle_compat.c:1061 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "caractère demandé invalide pour l'encodage : %d" + +#: utils/adt/oracle_compat.c:1075 +#, c-format +msgid "null character not permitted" +msgstr "caractère nul interdit" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "la valeur centile %g n'est pas entre 0 et 1" + +#: utils/adt/pg_locale.c:1228 +#, c-format +msgid "Apply system library package updates." +msgstr "Applique les mises à jour du paquet de bibliothèque système." + +#: utils/adt/pg_locale.c:1442 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "n'a pas pu créer la locale « %s » : %m" + +#: utils/adt/pg_locale.c:1445 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "Le système d'exploitation n'a pas pu trouver des données de locale pour la locale « %s »." + +#: utils/adt/pg_locale.c:1547 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "" +"les collationnements avec des valeurs différents pour le tri et le jeu de\n" +"caractères ne sont pas supportés sur cette plateforme" + +#: utils/adt/pg_locale.c:1556 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "le fournisseur du collationnement, LIBC, n'est pas supporté sur cette plateforme" + +#: utils/adt/pg_locale.c:1568 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "les collationnements avec des valeurs différentes pour le tri (collate) et le jeu de caractères (ctype) ne sont pas supportés par ICU" + +#: utils/adt/pg_locale.c:1574 utils/adt/pg_locale.c:1661 utils/adt/pg_locale.c:1940 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "n'a pas pu ouvrir le collationneur pour la locale « %s » : %s" + +#: utils/adt/pg_locale.c:1588 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU n'est pas supporté dans cette installation" + +#: utils/adt/pg_locale.c:1609 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "le collationnement « %s » n'a pas de version réelle mais une version était indiquée" + +#: utils/adt/pg_locale.c:1616 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "le collationnement « %s » a des versions différentes" + +#: utils/adt/pg_locale.c:1618 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "Le collationnement dans la base de données a été créé en utilisant la version %s mais le système d'exploitation fournit la version %s." + +#: utils/adt/pg_locale.c:1621 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "Reconstruisez tous les objets affectés par ce collationnement, et lancez ALTER COLLATION %s REFRESH VERSION, ou construisez PostgreSQL avec la bonne version de bibliothèque." + +#: utils/adt/pg_locale.c:1692 +#, c-format +msgid "could not load locale \"%s\"" +msgstr "n'a pas pu charger la locale « %s »" + +#: utils/adt/pg_locale.c:1717 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "n'a pas obtenir la version du collationnement pour la locale « %s » : code d'erreur %lu" + +#: utils/adt/pg_locale.c:1755 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "encodage « %s » non supporté par ICU" + +#: utils/adt/pg_locale.c:1762 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "n'a pas pu ouvrir le convertisseur ICU pour l'encodage « %s » : %s" + +#: utils/adt/pg_locale.c:1793 utils/adt/pg_locale.c:1802 utils/adt/pg_locale.c:1831 utils/adt/pg_locale.c:1841 +#, c-format +msgid "%s failed: %s" +msgstr "échec de %s : %s" + +#: utils/adt/pg_locale.c:2113 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "caractère multi-octets invalide pour la locale" + +#: utils/adt/pg_locale.c:2114 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "" +"La locale LC_CTYPE du serveur est probablement incompatible avec l'encodage\n" +"de la base de données." + +#: utils/adt/pg_lsn.c:263 +#, c-format +msgid "cannot add NaN to pg_lsn" +msgstr "ne peut pas ajouter NaN à pg_lsn" + +#: utils/adt/pg_lsn.c:297 +#, c-format +msgid "cannot subtract NaN from pg_lsn" +msgstr "ne peut pas soustraire NaN de pg_lsn" + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "la fonction peut seulement être appelée quand le serveur est en mode de mise à jour binaire" + +#: utils/adt/pgstatfuncs.c:503 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "nom de commande invalide : « %s »" + +#: utils/adt/pseudotypes.c:58 utils/adt/pseudotypes.c:92 +#, c-format +msgid "cannot display a value of type %s" +msgstr "ne peut pas afficher une valeur de type %s" + +#: utils/adt/pseudotypes.c:321 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "ne peut pas accepter une valeur de type shell" + +#: utils/adt/pseudotypes.c:331 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "ne peut pas afficher une valeur de type shell" + +#: utils/adt/rangetypes.c:404 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "l'argument flags du contructeur d'intervalle ne doit pas être NULL" + +#: utils/adt/rangetypes.c:1003 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "le résultat de la différence d'intervalle de valeur ne sera pas contigu" + +#: utils/adt/rangetypes.c:1064 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "le résultat de l'union d'intervalle pourrait ne pas être contigü" + +#: utils/adt/rangetypes.c:1214 +#, c-format +msgid "range_intersect_agg must be called with a range" +msgstr "range_intersect_agg doit être appelé avec un range" + +#: utils/adt/rangetypes.c:1689 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "" +"la limite inférieure de l'intervalle de valeurs doit être inférieure ou égale\n" +"à la limite supérieure de l'intervalle de valeurs" + +#: utils/adt/rangetypes.c:2112 utils/adt/rangetypes.c:2125 utils/adt/rangetypes.c:2139 +#, c-format +msgid "invalid range bound flags" +msgstr "drapeaux de limite de l'intervalle invalides" + +#: utils/adt/rangetypes.c:2113 utils/adt/rangetypes.c:2126 utils/adt/rangetypes.c:2140 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Les valeurs valides sont entre « [] », « [) », « (] » et « () »." + +#: utils/adt/rangetypes.c:2205 utils/adt/rangetypes.c:2222 utils/adt/rangetypes.c:2235 utils/adt/rangetypes.c:2253 utils/adt/rangetypes.c:2264 utils/adt/rangetypes.c:2308 utils/adt/rangetypes.c:2316 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "intervalle litéral mal formé : « %s »" + +#: utils/adt/rangetypes.c:2207 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "Cochonnerie après le mot clé « empty »." + +#: utils/adt/rangetypes.c:2224 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Parenthèse gauche ou crochet manquant." + +#: utils/adt/rangetypes.c:2237 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Virgule manquante après une limite basse." + +#: utils/adt/rangetypes.c:2255 +#, c-format +msgid "Too many commas." +msgstr "Trop de virgules." + +#: utils/adt/rangetypes.c:2266 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "Problème après la parenthèse droite ou le crochet droit." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4560 +#, c-format +msgid "regular expression failed: %s" +msgstr "l'expression rationnelle a échoué : %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%.*s\"" +msgstr "option d'expression rationnelle invalide : « %.*s »" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "une expression régulière SQL ne peut contenir plus de deux guillemets doubles comme séparateur d'échappement" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s ne supporte pas l'option « global »" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "Utilisez la foncction regexp_matches à la place." + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "trop de correspondances pour l'expression rationnelle" + +#: utils/adt/regproc.c:105 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "il existe plus d'une fonction nommée « %s »" + +#: utils/adt/regproc.c:543 +#, c-format +msgid "more than one operator named %s" +msgstr "il existe plus d'un opérateur nommé%s" + +#: utils/adt/regproc.c:715 utils/adt/regproc.c:756 utils/adt/regproc.c:2055 utils/adt/ruleutils.c:9650 utils/adt/ruleutils.c:9819 +#, c-format +msgid "too many arguments" +msgstr "trop d'arguments" + +#: utils/adt/regproc.c:716 utils/adt/regproc.c:757 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Fournit deux types d'argument pour l'opérateur." + +#: utils/adt/regproc.c:1639 utils/adt/regproc.c:1663 utils/adt/regproc.c:1764 utils/adt/regproc.c:1788 utils/adt/regproc.c:1890 utils/adt/regproc.c:1895 utils/adt/varlena.c:3709 utils/adt/varlena.c:3714 +#, c-format +msgid "invalid name syntax" +msgstr "syntaxe du nom invalide" + +#: utils/adt/regproc.c:1953 +#, c-format +msgid "expected a left parenthesis" +msgstr "attendait une parenthèse gauche" + +#: utils/adt/regproc.c:1969 +#, c-format +msgid "expected a right parenthesis" +msgstr "attendait une parenthèse droite" + +#: utils/adt/regproc.c:1988 +#, c-format +msgid "expected a type name" +msgstr "attendait un nom de type" + +#: utils/adt/regproc.c:2020 +#, c-format +msgid "improper type name" +msgstr "nom du type invalide" + +#: utils/adt/ri_triggers.c:300 utils/adt/ri_triggers.c:1545 utils/adt/ri_triggers.c:2530 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "" +"une instruction insert ou update sur la table « %s » viole la contrainte de clé\n" +"étrangère « %s »" + +#: utils/adt/ri_triggers.c:303 utils/adt/ri_triggers.c:1548 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL n'autorise pas le mixage de valeurs clés NULL et non NULL." + +#: utils/adt/ri_triggers.c:1965 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "la fonction « %s » doit être exécutée pour l'instruction INSERT" + +#: utils/adt/ri_triggers.c:1971 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "la fonction « %s » doit être exécutée pour l'instruction UPDATE" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "la fonction « %s » doit être exécutée pour l'instruction DELETE" + +#: utils/adt/ri_triggers.c:2000 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "aucune entrée pg_constraint pour le trigger « %s » sur la table « %s »" + +#: utils/adt/ri_triggers.c:2002 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "" +"Supprimez ce trigger sur une intégrité référentielle et ses enfants,\n" +"puis faites un ALTER TABLE ADD CONSTRAINT." + +#: utils/adt/ri_triggers.c:2355 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "" +"la requête d'intégrité référentielle sur « %s » à partir de la contrainte « %s »\n" +"sur « %s » donne des résultats inattendus" + +#: utils/adt/ri_triggers.c:2359 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Ceci est certainement dû à une règle qui a ré-écrit la requête." + +#: utils/adt/ri_triggers.c:2520 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "la suppression de la partition « %s » viole la contrainte de clé étrangère « %s »" + +#: utils/adt/ri_triggers.c:2523 utils/adt/ri_triggers.c:2548 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "La clé (%s)=(%s) est toujours référencée à partir de la table « %s »." + +#: utils/adt/ri_triggers.c:2534 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "La clé (%s)=(%s) n'est pas présente dans la table « %s »." + +#: utils/adt/ri_triggers.c:2537 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "La clé n'est pas présente dans la table « %s »." + +#: utils/adt/ri_triggers.c:2543 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "UPDATE ou DELETE sur la table « %s » viole la contrainte de clé étrangère « %s » de la table « %s »" + +#: utils/adt/ri_triggers.c:2551 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "La clé est toujours référencée à partir de la table « %s »." + +#: utils/adt/rowtypes.c:105 utils/adt/rowtypes.c:483 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "l'ajout de colonnes ayant un type composé n'est pas implémenté" + +#: utils/adt/rowtypes.c:157 utils/adt/rowtypes.c:186 utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 utils/adt/rowtypes.c:269 utils/adt/rowtypes.c:277 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "enregistrement litéral invalide : « %s »" + +#: utils/adt/rowtypes.c:158 +#, c-format +msgid "Missing left parenthesis." +msgstr "Parenthèse gauche manquante." + +#: utils/adt/rowtypes.c:187 +#, c-format +msgid "Too few columns." +msgstr "Pas assez de colonnes." + +#: utils/adt/rowtypes.c:270 +#, c-format +msgid "Too many columns." +msgstr "Trop de colonnes." + +#: utils/adt/rowtypes.c:278 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Problème après la parenthèse droite." + +#: utils/adt/rowtypes.c:532 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "mauvais nombre de colonnes : %d, alors que %d attendu" + +#: utils/adt/rowtypes.c:574 +#, c-format +msgid "binary data has type %u (%s) instead of expected %u (%s) in record column %d" +msgstr "" + +#: utils/adt/rowtypes.c:641 +#, c-format +msgid "improper binary format in record column %d" +msgstr "format binaire invalide dans l'enregistrement de la colonne %d" + +#: utils/adt/rowtypes.c:932 utils/adt/rowtypes.c:1178 utils/adt/rowtypes.c:1436 utils/adt/rowtypes.c:1682 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "" +"ne peut pas comparer les types de colonnes non similaires %s et %s pour la\n" +"colonne %d de l'enregistrement" + +#: utils/adt/rowtypes.c:1023 utils/adt/rowtypes.c:1248 utils/adt/rowtypes.c:1533 utils/adt/rowtypes.c:1718 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "" +"ne peut pas comparer les types d'enregistrement avec des numéros différents\n" +"des colonnes" + +#: utils/adt/ruleutils.c:5077 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "la règle « %s » a un type d'événement %d non supporté" + +#: utils/adt/timestamp.c:109 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "la précision de TIMESTAMP(%d)%s ne doit pas être négative" + +#: utils/adt/timestamp.c:115 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "la précision de TIMESTAMP(%d)%s est réduite au maximum autorisé, %d" + +#: utils/adt/timestamp.c:178 utils/adt/timestamp.c:436 utils/misc/guc.c:12411 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestamp en dehors de limites : « %s »" + +#: utils/adt/timestamp.c:374 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "la précision de timestamp(%d) doit être comprise entre %d et %d" + +#: utils/adt/timestamp.c:498 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "Les fuseaux horaires numériques doivent avoir « - » ou « + » comme premier caractère." + +#: utils/adt/timestamp.c:511 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "le fuseau horaire numérique « %s » est en dehors des limites" + +#: utils/adt/timestamp.c:607 utils/adt/timestamp.c:617 utils/adt/timestamp.c:625 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestamp en dehors de limites : %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:726 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "timestamp ne peut pas valoir NaN" + +#: utils/adt/timestamp.c:744 utils/adt/timestamp.c:756 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "timestamp en dehors de limites : « %g »" + +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "modificateur de type INTERVAL invalide" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "la précision de l'intervalle INTERVAL(%d) ne doit pas être négative" + +#: utils/adt/timestamp.c:1090 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "La précision de l'intervalle INTERVAL(%d) doit être réduit au maximum permis, %d" + +#: utils/adt/timestamp.c:1472 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "la précision de interval(%d) doit être comprise entre %d et %d" + +#: utils/adt/timestamp.c:2660 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "ne peut pas soustraire les valeurs timestamps infinies" + +#: utils/adt/timestamp.c:3837 utils/adt/timestamp.c:4015 +#, c-format +msgid "origin out of range" +msgstr "origine hors des limites" + +#: utils/adt/timestamp.c:3842 utils/adt/timestamp.c:4020 +#, c-format +msgid "timestamps cannot be binned into intervals containing months or years" +msgstr "" + +#: utils/adt/timestamp.c:3973 utils/adt/timestamp.c:4610 utils/adt/timestamp.c:4810 utils/adt/timestamp.c:4857 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "les unités timestamp « %s » ne sont pas supportées" + +#: utils/adt/timestamp.c:3987 utils/adt/timestamp.c:4564 utils/adt/timestamp.c:4867 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "les unité « %s » ne sont pas reconnues pour le type timestamp" + +#: utils/adt/timestamp.c:4161 utils/adt/timestamp.c:4605 utils/adt/timestamp.c:5081 utils/adt/timestamp.c:5129 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "les unités « %s » ne sont pas supportées pour le type « timestamp with time zone »" + +#: utils/adt/timestamp.c:4178 utils/adt/timestamp.c:4559 utils/adt/timestamp.c:5138 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "les unités « %s » ne sont pas reconnues pour le type « timestamp with time zone »" + +#: utils/adt/timestamp.c:4336 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "unités d'intervalle « %s » non supportées car les mois ont généralement des semaines fractionnaires" + +#: utils/adt/timestamp.c:4342 utils/adt/timestamp.c:5261 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "les unités « %s » ne sont pas supportées pour le type interval" + +#: utils/adt/timestamp.c:4358 utils/adt/timestamp.c:5322 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "les unités « %s » ne sont pas reconnues pour le type interval" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger : doit être appelé par un trigger" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger : doit être appelé sur une mise à jour" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger : doit être appelé avant une mise à jour" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger : doit être appelé pour chaque ligne" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_in n'est pas encore implémenté" + +#: utils/adt/tsquery.c:199 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "la distance dans l'opérateur de phrase ne devrait pas être plus que %d" + +#: utils/adt/tsquery.c:306 utils/adt/tsquery.c:691 utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "erreur de syntaxe dans tsquery : « %s »" + +#: utils/adt/tsquery.c:330 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "aucun opérande dans tsquery : « %s »" + +#: utils/adt/tsquery.c:534 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "valeur trop importante dans tsquery : « %s »" + +#: utils/adt/tsquery.c:539 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "l'opérande est trop long dans tsquery : « %s »" + +#: utils/adt/tsquery.c:567 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "le mot est trop long dans tsquery : « %s »" + +#: utils/adt/tsquery.c:835 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "la requête de recherche plein texte ne contient pas de lexemes : « %s »" + +#: utils/adt/tsquery.c:846 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "le champ tsquery est trop gros" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "" +"la requête de recherche plein texte ne contient que des termes courants\n" +"ou ne contient pas de lexemes, ignoré" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "la distance dans l'opérateur de phrase devrait être non négative et inférieure à %d" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "la requête ts_rewrite doit renvoyer deux colonnes tsquery" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "le tableau de poids doit avoir une seule dimension" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "le tableau de poids est trop court" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "le tableau de poids ne doit pas contenir de valeurs NULL" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:871 +#, c-format +msgid "weight out of range" +msgstr "poids en dehors des limites" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "le mot est trop long (%ld octets, max %ld octets)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "la chaîne est trop longue pour tsvector (%ld octets, max %ld octets)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "le tableau de lexème ne doit pas contenir de valeurs NULL" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "le tableau de poids ne doit pas contenir de valeurs NULL" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "poids non reconnu : « %c »" + +#: utils/adt/tsvector_op.c:2426 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "la requête ts_stat doit renvoyer une colonne tsvector" + +#: utils/adt/tsvector_op.c:2615 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "la colonne tsvector « %s » n'existe pas" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "la colonne « %s » n'est pas de type tsvector" + +#: utils/adt/tsvector_op.c:2634 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "la colonne de configuration « %s » n'existe pas" + +#: utils/adt/tsvector_op.c:2640 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "la colonne « %s » n'est pas de type regconfig" + +#: utils/adt/tsvector_op.c:2647 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "la colonne de configuration « %s » ne doit pas être NULL" + +#: utils/adt/tsvector_op.c:2660 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "" +"le nom de la configuration de la recherche plein texte « %s » doit être\n" +"qualifié par son schéma" + +#: utils/adt/tsvector_op.c:2685 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "la colonne « %s » n'est pas de type caractère" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "erreur de syntaxe dans tsvector : « %s »" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "il n'existe pas de caractères d'échappement : « %s »" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "mauvaise information de position dans tsvector : « %s »" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "n'a pas pu générer de valeurs aléatoires" + +#: utils/adt/varbit.c:110 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "la longueur du type %s doit être d'au moins 1" + +#: utils/adt/varbit.c:115 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "la longueur du type %s ne peut pas excéder %d" + +#: utils/adt/varbit.c:198 utils/adt/varbit.c:499 utils/adt/varbit.c:994 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "la longueur de la chaîne de bits dépasse le maximum permis (%d)" + +#: utils/adt/varbit.c:212 utils/adt/varbit.c:356 utils/adt/varbit.c:406 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "la longueur (en bits) de la chaîne %d ne correspond pas au type bit(%d)" + +#: utils/adt/varbit.c:234 utils/adt/varbit.c:535 +#, c-format +msgid "\"%.*s\" is not a valid binary digit" +msgstr "« %.*s » n'est pas un chiffre binaire valide" + +#: utils/adt/varbit.c:259 utils/adt/varbit.c:560 +#, c-format +msgid "\"%.*s\" is not a valid hexadecimal digit" +msgstr "« %.*s » n'est pas un chiffre hexadécimal valide" + +#: utils/adt/varbit.c:347 utils/adt/varbit.c:652 +#, c-format +msgid "invalid length in external bit string" +msgstr "longueur invalide dans la chaîne bit externe" + +#: utils/adt/varbit.c:513 utils/adt/varbit.c:661 utils/adt/varbit.c:757 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "la chaîne de bits est trop longue pour le type bit varying(%d)" + +#: utils/adt/varbit.c:1081 utils/adt/varbit.c:1191 utils/adt/varlena.c:897 utils/adt/varlena.c:960 utils/adt/varlena.c:1117 utils/adt/varlena.c:3351 utils/adt/varlena.c:3429 +#, c-format +msgid "negative substring length not allowed" +msgstr "longueur de sous-chaîne négative non autorisée" + +#: utils/adt/varbit.c:1261 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "ne peut pas utiliser l'opérateur AND sur des chaînes bit de tailles différentes" + +#: utils/adt/varbit.c:1302 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "ne peut pas utiliser l'opérateur OR sur des chaînes bit de tailles différentes" + +#: utils/adt/varbit.c:1342 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "ne peut pas utiliser l'opérateur XOR sur des chaînes bit de tailles différentes" + +#: utils/adt/varbit.c:1824 utils/adt/varbit.c:1882 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "index de bit %d en dehors des limites valides (0..%d)" + +#: utils/adt/varbit.c:1833 utils/adt/varlena.c:3633 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "le nouveau bit doit valoir soit 0 soit 1" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "valeur trop longue pour le type character(%d)" + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "valeur trop longue pour le type character varying(%d)" + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1523 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "n'a pas pu déterminer le collationnement à utiliser pour la comparaison de chaîne" + +#: utils/adt/varlena.c:1216 utils/adt/varlena.c:1963 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "les collationnements non déterministes ne sont pas supportés pour les recherches de sous-chaînes" + +#: utils/adt/varlena.c:1622 utils/adt/varlena.c:1635 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "n'a pas pu convertir la chaîne en UTF-16 : erreur %lu" + +#: utils/adt/varlena.c:1650 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "n'a pas pu comparer les chaînes unicode : %m" + +#: utils/adt/varlena.c:1701 utils/adt/varlena.c:2415 +#, c-format +msgid "collation failed: %s" +msgstr "échec du collationnement : %s" + +#: utils/adt/varlena.c:2623 +#, c-format +msgid "sort key generation failed: %s" +msgstr "échec de génération de la clé de tri : %s" + +#: utils/adt/varlena.c:3517 utils/adt/varlena.c:3584 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "index %d en dehors des limites valides, 0..%d" + +#: utils/adt/varlena.c:3548 utils/adt/varlena.c:3620 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "index %lld en dehors des limites valides, 0..%lld" + +#: utils/adt/varlena.c:4656 +#, c-format +msgid "field position must not be zero" +msgstr "la position du champ ne doit pas être zéro" + +#: utils/adt/varlena.c:5697 +#, c-format +msgid "unterminated format() type specifier" +msgstr "spécificateur de type pour format() non terminé" + +#: utils/adt/varlena.c:5698 utils/adt/varlena.c:5832 utils/adt/varlena.c:5953 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "Pour un unique \"%%\" utilisez \"%%%%\"." + +#: utils/adt/varlena.c:5830 utils/adt/varlena.c:5951 +#, c-format +msgid "unrecognized format() type specifier \"%.*s\"" +msgstr "spécificateur de type « %.*s » pour format() non reconnu" + +#: utils/adt/varlena.c:5843 utils/adt/varlena.c:5900 +#, c-format +msgid "too few arguments for format()" +msgstr "trop peu d'arguments pour format()" + +#: utils/adt/varlena.c:5996 utils/adt/varlena.c:6178 +#, c-format +msgid "number is out of range" +msgstr "le nombre est en dehors des limites" + +#: utils/adt/varlena.c:6059 utils/adt/varlena.c:6087 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "le format indique l'argument 0 mais les arguments sont numérotés à partir de 1" + +#: utils/adt/varlena.c:6080 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "la position de l'argument width doit se terminer par « $ »" + +#: utils/adt/varlena.c:6125 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "les valeurs NULL ne peuvent pas être formatés comme un identifiant SQL" + +#: utils/adt/varlena.c:6251 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "La normalisation Unicode peut seulement être exécutée si l'encodage serveur est UTF8" + +#: utils/adt/varlena.c:6264 +#, c-format +msgid "invalid normalization form: %s" +msgstr "forme de normalisation invalide : %s" + +#: utils/adt/varlena.c:6467 utils/adt/varlena.c:6502 utils/adt/varlena.c:6537 +#, c-format +msgid "invalid Unicode code point: %04X" +msgstr "point code Unicode invalide : %04X" + +#: utils/adt/varlena.c:6567 +#, c-format +msgid "Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX." +msgstr "Les échappements Unicode doivent être de la forme \\XXXX, \\+XXXXXX, \\uXXXX ou \\UXXXXXXXX." + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "l'argument de ntile doit être supérieur à zéro" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "l'argument de nth_value doit être supérieur à zéro" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "l'identifiant de transaction %s est dans le futur" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "données pg_snapshot externes invalides" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "fonctionnalité XML non supportée" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Cette fonctionnalité nécessite que le serveur dispose du support de libxml." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:627 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "nom d'encodage « %s » invalide" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "commentaire XML invalide" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "pas un document XML" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "instruction de traitement XML invalide" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "le nom de la cible de l'instruction de traitement XML ne peut pas être « %s »." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "l'instruction de traitement XML ne peut pas contenir « ?> »." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "xmlvalidate n'est pas implémenté" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "n'a pas pu initialiser la bibliothèque XML" + +#: utils/adt/xml.c:962 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "" +"libxml2 a un type de caractère incompatible : sizeof(char)=%u,\n" +"sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "n'a pas pu configurer le gestionnaire d'erreurs XML" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "" +"Ceci indique probablement que la version de libxml2 en cours d'utilisation\n" +"n'est pas compatible avec les fichiers d'en-tête de libxml2 avec lesquels\n" +"PostgreSQL a été construit." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "Valeur invalide pour le caractère." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "Espace requis." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "la version autonome accepte seulement 'yes' et 'no'." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "Déclaration mal formée : version manquante." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "Encodage manquant dans la déclaration du texte." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "Analyse de la déclaration XML : « ?> » attendu." + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "Code d'erreur libxml non reconnu : %d." + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML ne supporte pas les valeurs infinies de date." + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML ne supporte pas les valeurs infinies de timestamp." + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "requête invalide" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "tableau invalide pour la correspondance de l'espace de nom XML" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "" +"Le tableau doit avoir deux dimensions avec une longueur de 2 pour le\n" +"deuxième axe." + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "expression XPath vide" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "ni le nom de l'espace de noms ni l'URI ne peuvent être NULL" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "n'a pas pu enregistrer l'espace de noms XML de nom « %s » et d'URI « %s »" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "l'espace de nom DEFAULT n'est pas supporté" + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "le filtre du chemin de ligne ne doit pas être une chaîne vide" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "le filtre du chemin de colonne ne doit pas être une chaîne vide" + +#: utils/adt/xml.c:4655 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "plus d'une valeur renvoyée par l'expression XPath de colonne" + +#: utils/cache/lsyscache.c:1042 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "la conversion du type %s vers le type %s n'existe pas" + +#: utils/cache/lsyscache.c:2834 utils/cache/lsyscache.c:2867 utils/cache/lsyscache.c:2900 utils/cache/lsyscache.c:2933 +#, c-format +msgid "type %s is only a shell" +msgstr "le type %s est seulement un shell" + +#: utils/cache/lsyscache.c:2839 +#, c-format +msgid "no input function available for type %s" +msgstr "aucune fonction en entrée disponible pour le type %s" + +#: utils/cache/lsyscache.c:2872 +#, c-format +msgid "no output function available for type %s" +msgstr "aucune fonction en sortie disponible pour le type %s" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "la classe d'opérateur « %s » de la méthode d'accès %s nécessite la fonction de support manquante %d pour le type %s" + +#: utils/cache/plancache.c:720 +#, c-format +msgid "cached plan must not change result type" +msgstr "le plan en cache ne doit pas modifier le type en résultat" + +#: utils/cache/relcache.c:6223 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "n'a pas pu créer le fichier d'initialisation relation-cache « %s » : %m" + +#: utils/cache/relcache.c:6225 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Continue malgré tout, mais quelque chose s'est mal passé." + +#: utils/cache/relcache.c:6547 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier cache « %s » : %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "" +"ne peut pas préparer (PREPARE) une transaction qui a modifié la correspondance\n" +"de relation" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "le fichier de correspondance des relations « %s » contient des données invalides" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "" +"le fichier de correspondance des relations « %s » contient une somme de\n" +"contrôle incorrecte" + +#: utils/cache/typcache.c:1808 utils/fmgr/funcapi.c:463 +#, c-format +msgid "record type has not been registered" +msgstr "le type d'enregistrement n'a pas été enregistré" + +#: utils/error/assert.c:39 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments in PID %d\n" +msgstr "TRAP : ExceptionalCondition : mauvais arguments dans le PID %d\n" + +#: utils/error/assert.c:42 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d, PID: %d)\n" +msgstr "TRAP : %s(« %s », Fichier : « %s », Ligne : %d, PID : %d)\n" + +#: utils/error/elog.c:409 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "erreur survenue avant que le traitement des messages d'erreurs ne soit disponible\n" + +#: utils/error/elog.c:1948 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "n'a pas pu ré-ouvrir le fichier « %s » comme stderr : %m" + +#: utils/error/elog.c:1961 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "n'a pas pu ré-ouvrir le fichier « %s » comme stdout : %m" + +#: utils/error/elog.c:2456 utils/error/elog.c:2490 utils/error/elog.c:2506 +msgid "[unknown]" +msgstr "[inconnu]" + +#: utils/error/elog.c:3026 utils/error/elog.c:3344 utils/error/elog.c:3451 +msgid "missing error text" +msgstr "texte d'erreur manquant" + +#: utils/error/elog.c:3029 utils/error/elog.c:3032 +#, c-format +msgid " at character %d" +msgstr " au caractère %d" + +#: utils/error/elog.c:3042 utils/error/elog.c:3049 +msgid "DETAIL: " +msgstr "DÉTAIL: " + +#: utils/error/elog.c:3056 +msgid "HINT: " +msgstr "ASTUCE : " + +#: utils/error/elog.c:3063 +msgid "QUERY: " +msgstr "REQUÊTE : " + +#: utils/error/elog.c:3070 +msgid "CONTEXT: " +msgstr "CONTEXTE : " + +#: utils/error/elog.c:3080 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "EMPLACEMENT : %s, %s:%d\n" + +#: utils/error/elog.c:3087 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "EMPLACEMENT : %s:%d\n" + +#: utils/error/elog.c:3094 +msgid "BACKTRACE: " +msgstr "PILE D'APPEL : " + +#: utils/error/elog.c:3108 +msgid "STATEMENT: " +msgstr "INSTRUCTION : " + +#: utils/error/elog.c:3496 +msgid "DEBUG" +msgstr "DEBUG" + +#: utils/error/elog.c:3500 +msgid "LOG" +msgstr "LOG" + +#: utils/error/elog.c:3503 +msgid "INFO" +msgstr "INFO" + +#: utils/error/elog.c:3506 +msgid "NOTICE" +msgstr "NOTICE" + +#: utils/error/elog.c:3510 +msgid "WARNING" +msgstr "ATTENTION" + +#: utils/error/elog.c:3513 +msgid "ERROR" +msgstr "ERREUR" + +#: utils/error/elog.c:3516 +msgid "FATAL" +msgstr "FATAL" + +#: utils/error/elog.c:3519 +msgid "PANIC" +msgstr "PANIC" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "n'a pas pu trouver la fonction « %s » dans le fichier « %s »" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "n'a pas pu charger la bibliothèque « %s » : %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "bibliothèque « %s » incompatible : bloc magique manquant" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "" +"Les bibliothèques étendues nécessitent l'utilisation de la macro\n" +"PG_MODULE_MAGIC." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "bibliothèque « %s » incompatible : versions différentes" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "La version du serveur est %d, celle de la bibliothèque est %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "Le serveur a FUNC_MAX_ARGS = %d, la bibliothèque a %d." + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "Le serveur a INDEX_MAX_KEYS = %d, la bibliothèque a %d." + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "Le serveur a NAMEDATALEN = %d, la bibliothèque a %d." + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "Le serveur a FLOAT8PASSBYVAL = %s, la bibliothèque a %s." + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "Le bloc magique a une longueur inattendue ou une différence de padding." + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "bibliothèque « %s » incompatible : différences dans le bloc magique" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "l'accès à la bibliothèque « %s » n'est pas autorisé" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "nom de macro invalide dans le chemin des bibliothèques partagées : %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "composant de longueur zéro dans le paramètre « dynamic_library_path »" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "un composant du paramètre « dynamic_library_path » n'est pas un chemin absolu" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "la fonction interne « %s » n'est pas dans une table de recherche interne" + +#: utils/fmgr/fmgr.c:484 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "n'a pas pu trouver d'informations sur la fonction « %s »" + +#: utils/fmgr/fmgr.c:486 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "Les fonctions appelables en SQL ont besoin d'un PG_FUNCTION_INFO_V1(nom_fonction)." + +#: utils/fmgr/fmgr.c:504 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "version API %d non reconnue mais rapportée par la fonction info « %s »" + +#: utils/fmgr/fmgr.c:1999 +#, c-format +msgid "operator class options info is absent in function call context" +msgstr "les informations sur les options de la classe d'opérateur sont absentes dans le contexte d'appel à la fonction" + +#: utils/fmgr/fmgr.c:2066 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "fonction %u de validation du langage appelée pour le langage %u au lieu de %u" + +#: utils/fmgr/funcapi.c:386 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "" +"n'a pas pu déterminer le type du résultat actuel pour la fonction « %s »\n" +"déclarant retourner le type %s" + +#: utils/fmgr/funcapi.c:531 +#, c-format +msgid "argument declared %s does not contain a range type but type %s" +msgstr "l'argument déclaré %s ne contient pas un type d'intervalle mais un type %s" + +#: utils/fmgr/funcapi.c:1831 utils/fmgr/funcapi.c:1863 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "le nombre d'alias ne correspond pas au nombre de colonnes" + +#: utils/fmgr/funcapi.c:1857 +#, c-format +msgid "no column alias was provided" +msgstr "aucun alias de colonne n'a été fourni" + +#: utils/fmgr/funcapi.c:1881 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "" +"n'a pas pu déterminer la description de la ligne pour la fonction renvoyant\n" +"l'enregistrement" + +#: utils/init/miscinit.c:315 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "le répertoire des données « %s » n'existe pas" + +#: utils/init/miscinit.c:320 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "n'a pas pu lire les droits du répertoire « %s » : %m" + +#: utils/init/miscinit.c:328 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "le répertoire des données « %s » n'est pas un répertoire" + +#: utils/init/miscinit.c:344 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "le répertoire des données « %s » a un mauvais propriétaire" + +#: utils/init/miscinit.c:346 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "" +"Le serveur doit être en cours d'exécution par l'utilisateur qui possède le\n" +"répertoire des données." + +#: utils/init/miscinit.c:364 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "le répertoire des données « %s » a des permissions non valides" + +#: utils/init/miscinit.c:366 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Les droits devraient être u=rwx (0700) ou u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:645 utils/misc/guc.c:7481 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "" +"ne peut pas configurer le paramètre « %s » à l'intérieur d'une fonction\n" +"restreinte pour sécurité" + +#: utils/init/miscinit.c:713 +#, c-format +msgid "role with OID %u does not exist" +msgstr "le rôle d'OID %u n'existe pas" + +#: utils/init/miscinit.c:743 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "le rôle « %s » n'est pas autorisé à se connecter" + +#: utils/init/miscinit.c:761 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "trop de connexions pour le rôle « %s »" + +#: utils/init/miscinit.c:821 +#, c-format +msgid "permission denied to set session authorization" +msgstr "droit refusé pour initialiser une autorisation de session" + +#: utils/init/miscinit.c:904 +#, c-format +msgid "invalid role OID: %u" +msgstr "OID du rôle invalide : %u" + +#: utils/init/miscinit.c:958 +#, c-format +msgid "database system is shut down" +msgstr "le système de base de données est arrêté" + +#: utils/init/miscinit.c:1045 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "n'a pas pu créer le fichier verrou « %s » : %m" + +#: utils/init/miscinit.c:1059 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier verrou « %s » : %m" + +#: utils/init/miscinit.c:1066 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "n'a pas pu lire le fichier verrou « %s » : %m" + +#: utils/init/miscinit.c:1075 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "le fichier verrou « %s » est vide" + +#: utils/init/miscinit.c:1076 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "Soit un autre serveur est en cours de démarrage, soit le fichier verrou est un reste d'un précédent crash au démarrage du serveur." + +#: utils/init/miscinit.c:1120 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "le fichier verrou « %s » existe déjà" + +#: utils/init/miscinit.c:1124 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "" +"Un autre postgres (de PID %d) est-il déjà lancé avec comme répertoire de\n" +"données « %s » ?" + +#: utils/init/miscinit.c:1126 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "" +"Un autre postmaster (de PID %d) est-il déjà lancé avec comme répertoire de\n" +"données « %s » ?" + +#: utils/init/miscinit.c:1129 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "Un autre postgres (de PID %d) est-il déjà lancé en utilisant la socket « %s » ?" + +#: utils/init/miscinit.c:1131 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "Un autre postmaster (de PID %d) est-il déjà lancé en utilisant la socket « %s » ?" + +#: utils/init/miscinit.c:1182 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "n'a pas pu supprimer le vieux fichier verrou « %s » : %m" + +#: utils/init/miscinit.c:1184 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "" +"Le fichier semble avoir été oublié accidentellement mais il ne peut pas être\n" +"supprimé. Merci de supprimer ce fichier manuellement et de ré-essayer." + +#: utils/init/miscinit.c:1221 utils/init/miscinit.c:1235 utils/init/miscinit.c:1246 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "n'a pas pu écrire le fichier verrou « %s » : %m" + +#: utils/init/miscinit.c:1357 utils/init/miscinit.c:1499 utils/misc/guc.c:10377 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "n'a pas pu lire à partir du fichier « %s » : %m" + +#: utils/init/miscinit.c:1487 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "n'a pas pu ouvrir le fichier « %s » : %m ; poursuite du traitement" + +#: utils/init/miscinit.c:1512 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "le fichier de verrou « %s » contient le mauvais PID : %ld au lieu de %ld" + +#: utils/init/miscinit.c:1551 utils/init/miscinit.c:1567 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "« %s » n'est pas un répertoire de données valide" + +#: utils/init/miscinit.c:1553 +#, c-format +msgid "File \"%s\" is missing." +msgstr "Le fichier « %s » est manquant." + +#: utils/init/miscinit.c:1569 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "Le fichier « %s » ne contient aucune donnée valide." + +#: utils/init/miscinit.c:1571 +#, c-format +msgid "You might need to initdb." +msgstr "Vous pouvez avoir besoin d'exécuter initdb." + +#: utils/init/miscinit.c:1579 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "" +"Le répertoire des données a été initialisé avec PostgreSQL version %s,\n" +"qui est non compatible avec cette version %s." + +#: utils/init/postinit.c:254 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "connexion de réplication autorisée : utilisateur=%s" + +#: utils/init/postinit.c:257 +#, c-format +msgid "connection authorized: user=%s" +msgstr "connexion autorisée : utilisateur=%s" + +#: utils/init/postinit.c:260 +#, c-format +msgid " database=%s" +msgstr " base de données %s" + +#: utils/init/postinit.c:263 +#, c-format +msgid " application_name=%s" +msgstr " application_name=%s" + +#: utils/init/postinit.c:268 +#, c-format +msgid " SSL enabled (protocol=%s, cipher=%s, bits=%d)" +msgstr "SSL activé (protocole : %s, chiffrement : %s, bits : %d)" + +#: utils/init/postinit.c:280 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s, principal=%s)" +msgstr " GSS (authentifié=%s, chiffré=%s, principal=%s)" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "no" +msgstr "non" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "yes" +msgstr "oui" + +#: utils/init/postinit.c:286 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s)" +msgstr " GSS (authentifié=%s, chiffré=%s)" + +#: utils/init/postinit.c:323 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "la base de données « %s » a disparu de pg_database" + +#: utils/init/postinit.c:325 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "La base de données d'OID %u semble maintenant appartenir à « %s »." + +#: utils/init/postinit.c:345 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "la base de données « %s » n'accepte plus les connexions" + +#: utils/init/postinit.c:358 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "droit refusé pour la base de données « %s »" + +#: utils/init/postinit.c:359 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "L'utilisateur n'a pas le droit CONNECT." + +#: utils/init/postinit.c:376 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "trop de connexions pour la base de données « %s »" + +#: utils/init/postinit.c:398 utils/init/postinit.c:405 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "la locale de la base de données est incompatible avec le système d'exploitation" + +#: utils/init/postinit.c:399 +#, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "" +"La base de données a été initialisée avec un LC_COLLATE à « %s »,\n" +"qui n'est pas reconnu par setlocale()." + +#: utils/init/postinit.c:401 utils/init/postinit.c:408 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "" +"Recréez la base de données avec une autre locale ou installez la locale\n" +"manquante." + +#: utils/init/postinit.c:406 +#, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "" +"La base de données a été initialisée avec un LC_CTYPE à « %s »,\n" +"qui n'est pas reconnu par setlocale()." + +#: utils/init/postinit.c:761 +#, c-format +msgid "no roles are defined in this database system" +msgstr "aucun rôle n'est défini dans le système de bases de données" + +#: utils/init/postinit.c:762 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Vous devez immédiatement exécuter « CREATE USER \"%s\" CREATEUSER; »." + +#: utils/init/postinit.c:798 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "" +"les nouvelles connexions pour la réplication ne sont pas autorisées pendant\n" +"l'arrêt du serveur de base de données" + +#: utils/init/postinit.c:802 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "" +"doit être super-utilisateur pour se connecter pendant un arrêt de la base de\n" +"données" + +#: utils/init/postinit.c:812 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "doit être super-utilisateur pour se connecter en mode de mise à jour binaire" + +#: utils/init/postinit.c:825 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "" +"les emplacements de connexions restants sont réservés pour les connexions\n" +"superutilisateur non relatif à la réplication" + +#: utils/init/postinit.c:835 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "" +"doit être un superutilisateur ou un rôle ayant l'attribut de réplication\n" +"pour exécuter walsender" + +#: utils/init/postinit.c:904 +#, c-format +msgid "database %u does not exist" +msgstr "la base de données « %u » n'existe pas" + +#: utils/init/postinit.c:993 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Cet objet semble avoir été tout juste supprimé ou renommé." + +#: utils/init/postinit.c:1011 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Le sous-répertoire de la base de données « %s » est manquant." + +#: utils/init/postinit.c:1016 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "n'a pas pu accéder au répertoire « %s » : %m" + +#: utils/mb/conv.c:522 utils/mb/conv.c:733 +#, c-format +msgid "invalid encoding number: %d" +msgstr "numéro d'encodage invalide : %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:129 utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:165 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "identifiant d'encodage %d inattendu pour les jeux de caractères ISO-8859" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:110 utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:146 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "identifiant d'encodage %d inattendu pour les jeux de caractères WIN" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:900 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "la conversion entre %s et %s n'est pas supportée" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "" +"la fonction de conversion par défaut pour l'encodage de « %s » en « %s »\n" +"n'existe pas" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:430 utils/mb/mbutils.c:815 utils/mb/mbutils.c:842 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "Une chaîne de %d octets est trop longue pour la conversion d'encodage." + +#: utils/mb/mbutils.c:568 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "nom de l'encodage source « %s » invalide" + +#: utils/mb/mbutils.c:573 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "nom de l'encodage destination « %s » invalide" + +#: utils/mb/mbutils.c:713 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "valeur d'octet invalide pour l'encodage « %s » : 0x%02x" + +#: utils/mb/mbutils.c:877 +#, c-format +msgid "invalid Unicode code point" +msgstr "point code Unicode invalide" + +#: utils/mb/mbutils.c:1146 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "échec de bind_textdomain_codeset" + +#: utils/mb/mbutils.c:1667 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "séquence d'octets invalide pour l'encodage « %s » : %s" + +#: utils/mb/mbutils.c:1700 +#, c-format +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "" +"le caractère dont la séquence d'octets est %s dans l'encodage « %s » n'a pas\n" +"d'équivalent dans l'encodage « %s »" + +#: utils/misc/guc.c:718 +msgid "Ungrouped" +msgstr "Dégroupé" + +#: utils/misc/guc.c:720 +msgid "File Locations" +msgstr "Emplacement des fichiers" + +#: utils/misc/guc.c:722 +msgid "Connections and Authentication / Connection Settings" +msgstr "Connexions et authentification / Paramétrages de connexion" + +#: utils/misc/guc.c:724 +msgid "Connections and Authentication / Authentication" +msgstr "Connexions et authentification / Authentification" + +#: utils/misc/guc.c:726 +msgid "Connections and Authentication / SSL" +msgstr "Connexions et authentification / SSL" + +#: utils/misc/guc.c:728 +msgid "Resource Usage / Memory" +msgstr "Utilisation des ressources / Mémoire" + +#: utils/misc/guc.c:730 +msgid "Resource Usage / Disk" +msgstr "Utilisation des ressources / Disques" + +#: utils/misc/guc.c:732 +msgid "Resource Usage / Kernel Resources" +msgstr "Utilisation des ressources / Ressources noyau" + +#: utils/misc/guc.c:734 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Utilisation des ressources / Délai du VACUUM basé sur le coût" + +#: utils/misc/guc.c:736 +msgid "Resource Usage / Background Writer" +msgstr "Utilisation des ressources / Processus d'écriture en tâche de fond" + +#: utils/misc/guc.c:738 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Utilisation des ressources / Comportement asynchrone" + +#: utils/misc/guc.c:740 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead Log / Paramétrages" + +#: utils/misc/guc.c:742 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead Log / Points de vérification (Checkpoints)" + +#: utils/misc/guc.c:744 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead Log / Archivage" + +#: utils/misc/guc.c:746 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead Log / Restauration d'archive" + +#: utils/misc/guc.c:748 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead Log / Cible de restauration" + +#: utils/misc/guc.c:750 +msgid "Replication / Sending Servers" +msgstr "Réplication / Serveurs d'envoi" + +#: utils/misc/guc.c:752 +msgid "Replication / Primary Server" +msgstr "Réplication / Serveur primaire" + +#: utils/misc/guc.c:754 +msgid "Replication / Standby Servers" +msgstr "Réplication / Serveurs en attente" + +#: utils/misc/guc.c:756 +msgid "Replication / Subscribers" +msgstr "Réplication / Abonnés" + +#: utils/misc/guc.c:758 +msgid "Query Tuning / Planner Method Configuration" +msgstr "Optimisation des requêtes / Configuration de la méthode du planificateur" + +#: utils/misc/guc.c:760 +msgid "Query Tuning / Planner Cost Constants" +msgstr "Optimisation des requêtes / Constantes des coûts du planificateur" + +#: utils/misc/guc.c:762 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "Optimisation des requêtes / Optimiseur génétique de requêtes" + +#: utils/misc/guc.c:764 +msgid "Query Tuning / Other Planner Options" +msgstr "Optimisation des requêtes / Autres options du planificateur" + +#: utils/misc/guc.c:766 +msgid "Reporting and Logging / Where to Log" +msgstr "Rapports et traces / Où tracer" + +#: utils/misc/guc.c:768 +msgid "Reporting and Logging / When to Log" +msgstr "Rapports et traces / Quand tracer" + +#: utils/misc/guc.c:770 +msgid "Reporting and Logging / What to Log" +msgstr "Rapports et traces / Que tracer" + +#: utils/misc/guc.c:772 +msgid "Reporting and Logging / Process Title" +msgstr "Rapports et traces / Titre du processus" + +#: utils/misc/guc.c:774 +msgid "Statistics / Monitoring" +msgstr "Statistiques / Surveillance" + +#: utils/misc/guc.c:776 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "Statistiques / Récupérateur des statistiques sur les requêtes et sur les index" + +#: utils/misc/guc.c:778 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:780 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "Valeurs par défaut pour les connexions client / Comportement des instructions" + +#: utils/misc/guc.c:782 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "Valeurs par défaut pour les connexions client / Locale et formattage" + +#: utils/misc/guc.c:784 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "Valeurs par défaut pour les connexions des clients / Préchargement des bibliothèques partagées" + +#: utils/misc/guc.c:786 +msgid "Client Connection Defaults / Other Defaults" +msgstr "Valeurs par défaut pour les connexions client / Autres valeurs par défaut" + +#: utils/misc/guc.c:788 +msgid "Lock Management" +msgstr "Gestion des verrous" + +#: utils/misc/guc.c:790 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Compatibilité des versions et des plateformes / Anciennes versions de PostgreSQL" + +#: utils/misc/guc.c:792 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Compatibilité des versions et des plateformes / Anciennes plateformes et anciens clients" + +#: utils/misc/guc.c:794 +msgid "Error Handling" +msgstr "Gestion des erreurs" + +#: utils/misc/guc.c:796 +msgid "Preset Options" +msgstr "Options pré-configurées" + +#: utils/misc/guc.c:798 +msgid "Customized Options" +msgstr "Options personnalisées" + +#: utils/misc/guc.c:800 +msgid "Developer Options" +msgstr "Options pour le développeur" + +#: utils/misc/guc.c:858 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Les unités valides pour ce paramètre sont « B », « kB », « MB », « GB » et « TB »." + +#: utils/misc/guc.c:895 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Les unités valides pour ce paramètre sont «us », « ms », « s », « min », « h » et « d »." + +#: utils/misc/guc.c:957 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "Active l'utilisation des parcours séquentiels par le planificateur." + +#: utils/misc/guc.c:967 +msgid "Enables the planner's use of index-scan plans." +msgstr "Active l'utilisation des parcours d'index par le planificateur." + +#: utils/misc/guc.c:977 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Active l'utilisation des parcours d'index seul par le planificateur." + +#: utils/misc/guc.c:987 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "Active l'utilisation des parcours de bitmap par le planificateur." + +#: utils/misc/guc.c:997 +msgid "Enables the planner's use of TID scan plans." +msgstr "Active l'utilisation de plans de parcours TID par le planificateur." + +#: utils/misc/guc.c:1007 +msgid "Enables the planner's use of explicit sort steps." +msgstr "Active l'utilisation des étapes de tris explicites par le planificateur." + +#: utils/misc/guc.c:1017 +msgid "Enables the planner's use of incremental sort steps." +msgstr "Active l'utilisation des étapes de tris incrémentaux par le planificateur." + +#: utils/misc/guc.c:1026 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Active l'utilisation de plans d'agrégats hachés par le planificateur." + +#: utils/misc/guc.c:1036 +msgid "Enables the planner's use of materialization." +msgstr "Active l'utilisation de la matérialisation par le planificateur." + +#: utils/misc/guc.c:1046 +msgid "Enables the planner's use of result caching." +msgstr "Active l'utilisation du cache de résultat par le planificateur." + +#: utils/misc/guc.c:1056 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "Active l'utilisation de plans avec des jointures imbriquées par le planificateur." + +#: utils/misc/guc.c:1066 +msgid "Enables the planner's use of merge join plans." +msgstr "Active l'utilisation de plans de jointures MERGE par le planificateur." + +#: utils/misc/guc.c:1076 +msgid "Enables the planner's use of hash join plans." +msgstr "Active l'utilisation de plans de jointures hachées par le planificateur." + +#: utils/misc/guc.c:1086 +msgid "Enables the planner's use of gather merge plans." +msgstr "Active l'utilisation de plans GATHER MERGE par le planificateur." + +#: utils/misc/guc.c:1096 +msgid "Enables partitionwise join." +msgstr "Active l'utilisation de jointures entre partitions." + +#: utils/misc/guc.c:1106 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Active les agrégations et regroupements par partition." + +#: utils/misc/guc.c:1116 +msgid "Enables the planner's use of parallel append plans." +msgstr "Active l'utilisation de plans Append parallèles par le planificateur." + +#: utils/misc/guc.c:1126 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Active l'utilisation de plans de jointures hachées parallèles par le planificateur." + +#: utils/misc/guc.c:1136 +msgid "Enables plan-time and execution-time partition pruning." +msgstr "Active l'élagage de partition durant la planification et l'exécution." + +#: utils/misc/guc.c:1137 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Autorise le planificateur de requête et l'exécuteur à comparer les limites des partitions avec les conditions des requêtes pour déterminer les partitions à parcourir." + +#: utils/misc/guc.c:1148 +msgid "Enables the planner's use of async append plans." +msgstr "Active l'utilisation de plans Append asynchrones par le planificateur." + +#: utils/misc/guc.c:1158 +msgid "Enables genetic query optimization." +msgstr "Active l'optimisation génétique des requêtes." + +#: utils/misc/guc.c:1159 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Cet algorithme essaie de faire une planification sans recherche exhaustive." + +#: utils/misc/guc.c:1170 +msgid "Shows whether the current user is a superuser." +msgstr "Affiche si l'utilisateur actuel est un super-utilisateur." + +#: utils/misc/guc.c:1180 +msgid "Enables advertising the server via Bonjour." +msgstr "Active la publication du serveur via Bonjour." + +#: utils/misc/guc.c:1189 +msgid "Collects transaction commit time." +msgstr "Récupère l'horodatage de la validation de la transaction." + +#: utils/misc/guc.c:1198 +msgid "Enables SSL connections." +msgstr "Active les connexions SSL." + +#: utils/misc/guc.c:1207 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Utilise également ssl_passphrase_command durant le rechargement du serveur." + +#: utils/misc/guc.c:1216 +msgid "Give priority to server ciphersuite order." +msgstr "Donne la priorité à l'ordre des chiffrements du serveur." + +#: utils/misc/guc.c:1225 +msgid "Forces synchronization of updates to disk." +msgstr "Force la synchronisation des mises à jour sur le disque." + +#: utils/misc/guc.c:1226 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "" +"Le serveur utilisera l'appel système fsync() à différents endroits pour\n" +"s'assurer que les mises à jour sont écrites physiquement sur le disque. Ceci\n" +"nous assure qu'un groupe de bases de données se retrouvera dans un état\n" +"cohérent après un arrêt brutal dû au système d'exploitation ou au matériel." + +#: utils/misc/guc.c:1237 +msgid "Continues processing after a checksum failure." +msgstr "Continue le traitement après un échec de la somme de contrôle." + +#: utils/misc/guc.c:1238 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "La détection d'une erreur de somme de contrôle a normalement pour effet de rapporter une erreur, annulant la transaction en cours. Régler ignore_checksum_failure à true permet au système d'ignorer cette erreur (mais rapporte toujours un avertissement), et continue le traitement. Ce comportement pourrait causer un arrêt brutal ou d'autres problèmes sérieux. Cela a un effet seulement si les sommes de contrôle (checksums) sont activés." + +#: utils/misc/guc.c:1252 +msgid "Continues processing past damaged page headers." +msgstr "Continue le travail après les en-têtes de page endommagés." + +#: utils/misc/guc.c:1253 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "" +"La détection d'une en-tête de page endommagée cause normalement le rapport\n" +"d'une erreur par PostgreSQL, l'annulation de la transaction en cours.\n" +"Initialiser zero_damaged_pages à true fait que le système ne rapporte qu'un\n" +"message d'attention et continue à travailler. Ce comportement détruira des\n" +"données, notamment toutes les lignes de la page endommagée." + +#: utils/misc/guc.c:1266 +msgid "Continues recovery after an invalid pages failure." +msgstr "Continue la restauration après un échec des pages invalides." + +#: utils/misc/guc.c:1267 +msgid "Detection of WAL records having references to invalid pages during recovery causes PostgreSQL to raise a PANIC-level error, aborting the recovery. Setting ignore_invalid_pages to true causes the system to ignore invalid page references in WAL records (but still report a warning), and continue recovery. This behavior may cause crashes, data loss, propagate or hide corruption, or other serious problems. Only has an effect during recovery or in standby mode." +msgstr "La détection des enregistrements de journaux de transactions ayant des références à des blocs invalides lors de la restauration a pour effet que PostgreSQL lève une erreur de niveau PANIC, annulant la restauration. Configurer ignore_invalid_pages à true permet au système d'ignorer les références invalides de page dans les enregistrements des journaux de transactions (tout en rapportant toujours un message d'avertissement), et continue la restauration. Ce comportement pourrait causer des arrêts brutaux, des pertes de données, propager ou cacher une corruption, ainsi que d'autres problèmes sérieux. Ce paramètre a un effet seulement lors de la restauration et en mode standby." + +#: utils/misc/guc.c:1285 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "" +"Écrit des pages complètes dans les WAL lors d'une première modification après\n" +"un point de vérification." + +#: utils/misc/guc.c:1286 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "Une page écrite au moment d'un arrêt brutal du système d'exploitation pourrait n'être écrite sur le disque que partiellement. Lors de la récupération, les modifications stockées dans le journal de transaction ne sont pas suffisantes pour terminer la récupération. Cette option écrit les pages lors de la première modification après un checkpoint afin que la récupération complète soit possible." + +#: utils/misc/guc.c:1299 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification." +msgstr "Écrit des pages complètes dans les WAL lors d'une première modification après un point de vérification, y compris pour des modifications non critiques." + +#: utils/misc/guc.c:1309 +msgid "Compresses full-page writes written in WAL file." +msgstr "Compresse les blocs complets écrits dans les journaux de transactions." + +#: utils/misc/guc.c:1319 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Écrit des zéros dans les nouveaux journaux de transaction avant leur première utilisation." + +#: utils/misc/guc.c:1329 +msgid "Recycles WAL files by renaming them." +msgstr "Recycle les journaux de transactions en les renommant." + +#: utils/misc/guc.c:1339 +msgid "Logs each checkpoint." +msgstr "Trace tous les points de vérification." + +#: utils/misc/guc.c:1348 +msgid "Logs each successful connection." +msgstr "Trace toutes les connexions réussies." + +#: utils/misc/guc.c:1357 +msgid "Logs end of a session, including duration." +msgstr "Trace la fin d'une session, avec sa durée." + +#: utils/misc/guc.c:1366 +msgid "Logs each replication command." +msgstr "Trace chaque commande de réplication." + +#: utils/misc/guc.c:1375 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Affiche si le serveur en cours d'exécution a les vérifications d'assertion activées." + +#: utils/misc/guc.c:1390 +msgid "Terminate session on any error." +msgstr "Termine la session sans erreur." + +#: utils/misc/guc.c:1399 +msgid "Reinitialize server after backend crash." +msgstr "Réinitialisation du serveur après un arrêt brutal d'un processus serveur." + +#: utils/misc/guc.c:1408 +msgid "Remove temporary files after backend crash." +msgstr "Suppression des fichiers temporaires après un arrêt brutal d'un processus serveur." + +#: utils/misc/guc.c:1418 +msgid "Logs the duration of each completed SQL statement." +msgstr "Trace la durée de chaque instruction SQL terminée." + +#: utils/misc/guc.c:1427 +msgid "Logs each query's parse tree." +msgstr "Trace l'arbre d'analyse de chaque requête." + +#: utils/misc/guc.c:1436 +msgid "Logs each query's rewritten parse tree." +msgstr "Trace l'arbre d'analyse réécrit de chaque requête." + +#: utils/misc/guc.c:1445 +msgid "Logs each query's execution plan." +msgstr "Trace le plan d'exécution de chaque requête." + +#: utils/misc/guc.c:1454 +msgid "Indents parse and plan tree displays." +msgstr "Indente l'affichage des arbres d'analyse et de planification." + +#: utils/misc/guc.c:1463 +msgid "Writes parser performance statistics to the server log." +msgstr "" +"Écrit les statistiques de performance de l'analyseur dans les journaux applicatifs\n" +"du serveur." + +#: utils/misc/guc.c:1472 +msgid "Writes planner performance statistics to the server log." +msgstr "" +"Écrit les statistiques de performance de planification dans les journaux\n" +"applicatifs du serveur." + +#: utils/misc/guc.c:1481 +msgid "Writes executor performance statistics to the server log." +msgstr "" +"Écrit les statistiques de performance de l'exécuteur dans les journaux applicatifs\n" +"du serveur." + +#: utils/misc/guc.c:1490 +msgid "Writes cumulative performance statistics to the server log." +msgstr "" +"Écrit les statistiques de performance cumulatives dans les journaux applicatifs\n" +"du serveur." + +#: utils/misc/guc.c:1500 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "Trace les statistiques d'utilisation des ressources systèmes (mémoire et CPU) sur les différentes opérations B-tree." + +#: utils/misc/guc.c:1512 +msgid "Collects information about executing commands." +msgstr "Récupère les statistiques sur les commandes en exécution." + +#: utils/misc/guc.c:1513 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "" +"Active la récupération d'informations sur la commande en cours d'exécution\n" +"pour chaque session, avec l'heure de début de l'exécution de la commande." + +#: utils/misc/guc.c:1523 +msgid "Collects statistics on database activity." +msgstr "Récupère les statistiques sur l'activité de la base de données." + +#: utils/misc/guc.c:1532 +msgid "Collects timing statistics for database I/O activity." +msgstr "Récupère les statistiques d'horodatage sur l'activité en entrées/sorties de la base de données." + +#: utils/misc/guc.c:1541 +msgid "Collects timing statistics for WAL I/O activity." +msgstr "Récupère les statistiques d'horodatage sur l'activité en entrées/sorties des journaux de transactions." + +#: utils/misc/guc.c:1551 +msgid "Updates the process title to show the active SQL command." +msgstr "" +"Met à jour le titre du processus pour indiquer la commande SQL en cours\n" +"d'exécution." + +#: utils/misc/guc.c:1552 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "" +"Active la mise à jour du titre du processus chaque fois qu'une nouvelle\n" +"commande SQL est reçue par le serveur." + +#: utils/misc/guc.c:1565 +msgid "Starts the autovacuum subprocess." +msgstr "Exécute le sous-processus de l'autovacuum." + +#: utils/misc/guc.c:1575 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "Génère une sortie de débogage pour LISTEN et NOTIFY." + +#: utils/misc/guc.c:1587 +msgid "Emits information about lock usage." +msgstr "Émet des informations sur l'utilisation des verrous." + +#: utils/misc/guc.c:1597 +msgid "Emits information about user lock usage." +msgstr "Émet des informations sur l'utilisation des verrous utilisateurs." + +#: utils/misc/guc.c:1607 +msgid "Emits information about lightweight lock usage." +msgstr "Émet des informations sur l'utilisation des verrous légers." + +#: utils/misc/guc.c:1617 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "Trace les informations sur les verrous actuels lorsqu'un délai sur le deadlock est dépassé." + +#: utils/misc/guc.c:1629 +msgid "Logs long lock waits." +msgstr "Trace les attentes longues de verrou." + +#: utils/misc/guc.c:1638 +msgid "Logs standby recovery conflict waits." +msgstr "" + +#: utils/misc/guc.c:1647 +msgid "Logs the host name in the connection logs." +msgstr "Trace le nom d'hôte dans les traces de connexion." + +#: utils/misc/guc.c:1648 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "Par défaut, une connexion ne trace que l'adresse IP de l'hôte se connectant. Si vous voulez que s'affiche le nom de l'hôte, vous pouvez activer cette option mais, selon la configuration de la résolution de noms de votre hôte, cela peut imposer un coût en performances non négligeable." + +#: utils/misc/guc.c:1659 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "Traite « expr=NULL » comme « expr IS NULL »." + +#: utils/misc/guc.c:1660 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "" +"Une fois activé, les expressions de la forme expr = NULL (ou NULL = expr)\n" +"sont traitées comme expr IS NULL, c'est-à-dire qu'elles renvoient true si\n" +"l'expression est évaluée comme étant NULL et false sinon. Le comportement\n" +"correct de expr = NULL est de toujours renvoyer NULL (inconnu)." + +#: utils/misc/guc.c:1672 +msgid "Enables per-database user names." +msgstr "Active les noms d'utilisateur par base de données." + +#: utils/misc/guc.c:1681 +msgid "Sets the default read-only status of new transactions." +msgstr "Initialise le statut de lecture seule par défaut des nouvelles transactions." + +#: utils/misc/guc.c:1691 +msgid "Sets the current transaction's read-only status." +msgstr "Affiche le statut de lecture seule de la transaction actuelle." + +#: utils/misc/guc.c:1701 +msgid "Sets the default deferrable status of new transactions." +msgstr "Initialise le statut déferrable par défaut des nouvelles transactions." + +#: utils/misc/guc.c:1710 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "" +"S'il faut repousser une transaction sérialisable en lecture seule jusqu'à ce qu'elle\n" +"puisse être exécutée sans échecs possibles de sérialisation." + +#: utils/misc/guc.c:1720 +msgid "Enable row security." +msgstr "Active la sécurité niveau ligne." + +#: utils/misc/guc.c:1721 +msgid "When enabled, row security will be applied to all users." +msgstr "Lorsqu'il est activé, le mode de sécurité niveau ligne sera appliqué à tous les utilisateurs." + +#: utils/misc/guc.c:1729 +msgid "Check routine bodies during CREATE FUNCTION and CREATE PROCEDURE." +msgstr "Vérifie les corps de routine lors du CREATE FUNCTION et du CREATE PROCEDURE." + +#: utils/misc/guc.c:1738 +msgid "Enable input of NULL elements in arrays." +msgstr "Active la saisie d'éléments NULL dans les tableaux." + +#: utils/misc/guc.c:1739 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "" +"Si activé, un NULL sans guillemets en tant que valeur d'entrée dans un\n" +"tableau signifie une valeur NULL ; sinon, il sera pris littéralement." + +#: utils/misc/guc.c:1755 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OID n'est plus supporté ; ce paramètre ne peut être positionné qu'à false (faux)." + +#: utils/misc/guc.c:1765 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "" +"Lance un sous-processus pour capturer la sortie d'erreurs (stderr) et/ou\n" +"csvlogs dans des journaux applicatifs." + +#: utils/misc/guc.c:1774 +msgid "Truncate existing log files of same name during log rotation." +msgstr "" +"Tronque les journaux applicatifs existants du même nom lors de la rotation\n" +"des journaux applicatifs." + +#: utils/misc/guc.c:1785 +msgid "Emit information about resource usage in sorting." +msgstr "Émet des informations sur l'utilisation des ressources lors d'un tri." + +#: utils/misc/guc.c:1799 +msgid "Generate debugging output for synchronized scanning." +msgstr "Génère une sortie de débogage pour les parcours synchronisés." + +#: utils/misc/guc.c:1814 +msgid "Enable bounded sorting using heap sort." +msgstr "Active le tri limité en utilisant le tri de heap." + +#: utils/misc/guc.c:1827 +msgid "Emit WAL-related debugging output." +msgstr "Émet une sortie de débogage concernant les journaux de transactions." + +#: utils/misc/guc.c:1839 +msgid "Shows whether datetimes are integer based." +msgstr "Indique si les types datetime sont basés sur des entiers." + +#: utils/misc/guc.c:1850 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "" +"Indique si les noms d'utilisateurs Kerberos et GSSAPI devraient être traités\n" +"sans se soucier de la casse." + +#: utils/misc/guc.c:1860 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Avertie sur les échappements par antislash dans les chaînes ordinaires." + +#: utils/misc/guc.c:1870 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "Fait que les chaînes '...' traitent les antislashs littéralement." + +#: utils/misc/guc.c:1881 +msgid "Enable synchronized sequential scans." +msgstr "Active l'utilisation des parcours séquentiels synchronisés." + +#: utils/misc/guc.c:1891 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Définit s'il faut inclure ou exclure la transaction de la cible de restauration." + +#: utils/misc/guc.c:1901 +msgid "Allows connections and queries during recovery." +msgstr "Autorise les connexions et les requêtes pendant la restauration." + +#: utils/misc/guc.c:1911 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "Permet l'envoi d'informations d'un serveur en hot standby vers le serveur principal pour éviter les conflits de requêtes." + +#: utils/misc/guc.c:1921 +msgid "Shows whether hot standby is currently active." +msgstr "Affiche si le hot standby est actuellement actif." + +#: utils/misc/guc.c:1932 +msgid "Allows modifications of the structure of system tables." +msgstr "Permet les modifications de la structure des tables systèmes." + +#: utils/misc/guc.c:1943 +msgid "Disables reading from system indexes." +msgstr "Désactive la lecture des index système." + +#: utils/misc/guc.c:1944 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "" +"Cela n'empêche pas la mise à jour des index, donc vous pouvez l'utiliser en\n" +"toute sécurité. La pire conséquence est la lenteur." + +#: utils/misc/guc.c:1955 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "" +"Active la compatibilité ascendante pour la vérification des droits sur les\n" +"Large Objects." + +#: utils/misc/guc.c:1956 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "" +"Ignore la vérification des droits lors de la lecture et de la modification\n" +"des Larges Objects, pour la compatibilité avec les versions antérieures à la\n" +"9.0." + +#: utils/misc/guc.c:1966 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "Lors de la génération des rragments SQL, mettre entre guillemets tous les identifiants." + +#: utils/misc/guc.c:1976 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Affiche si les sommes de contrôle sont activées sur les données pour cette instance." + +#: utils/misc/guc.c:1987 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "Ajoute un numéro de séquence aux messages syslog pour éviter des suppressions de doublons." + +#: utils/misc/guc.c:1997 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "Sépare les messages envoyés à syslog par lignes afin de les faire tenir dans 1024 octets." + +#: utils/misc/guc.c:2007 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Controle si les nœuds Gather et Gather Merge doivent également exécuter des sous-plans." + +#: utils/misc/guc.c:2008 +msgid "Should gather nodes also run subplans or just gather tuples?" +msgstr "Est-ce que les nœuds Gather devraient également exécuter des sous-plans, ou juste recueillir des lignes ?" + +#: utils/misc/guc.c:2018 +msgid "Allow JIT compilation." +msgstr "Autorise la compilation JIT." + +#: utils/misc/guc.c:2029 +msgid "Register JIT-compiled functions with debugger." +msgstr "Enregistre les fonctions compilées avec JIT avec le debugger." + +#: utils/misc/guc.c:2046 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Écrire le bitcode LLVM pour faciliter de débugage JIT." + +#: utils/misc/guc.c:2057 +msgid "Allow JIT compilation of expressions." +msgstr "Autorise la compilation JIT des expressions." + +#: utils/misc/guc.c:2068 +msgid "Register JIT-compiled functions with perf profiler." +msgstr "Enregistre les fonctions compilées avec JIT avec l'outil de profilage perf." + +#: utils/misc/guc.c:2085 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Autorise la compilation JIT de la décomposition des lignes." + +#: utils/misc/guc.c:2096 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Soit de continuer à s'exécuter après un échec lors de la synchronisation des fichiers de données." + +#: utils/misc/guc.c:2105 +msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." +msgstr "Configure si un wal receiver doit créer un slot de réplication temporaire si aucun slot permanent n'est configuré." + +#: utils/misc/guc.c:2123 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "" +"Force un changement du journal de transaction si un nouveau fichier n'a pas\n" +"été créé depuis N secondes." + +#: utils/misc/guc.c:2134 +msgid "Waits N seconds on connection startup after authentication." +msgstr "Attends N secondes après l'authentification." + +#: utils/misc/guc.c:2135 utils/misc/guc.c:2733 +msgid "This allows attaching a debugger to the process." +msgstr "Ceci permet d'attacher un débogueur au processus." + +#: utils/misc/guc.c:2144 +msgid "Sets the default statistics target." +msgstr "Initialise la cible par défaut des statistiques." + +#: utils/misc/guc.c:2145 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "" +"Ceci s'applique aux colonnes de tables qui n'ont pas de cible spécifique\n" +"pour la colonne initialisée via ALTER TABLE SET STATISTICS." + +#: utils/misc/guc.c:2154 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "" +"Initialise la taille de la liste FROM en dehors de laquelle les\n" +"sous-requêtes ne sont pas rassemblées." + +#: utils/misc/guc.c:2156 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "" +"Le planificateur fusionne les sous-requêtes dans des requêtes supérieures\n" +"si la liste FROM résultante n'a pas plus de ce nombre d'éléments." + +#: utils/misc/guc.c:2167 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "" +"Initialise la taille de la liste FROM en dehors de laquelle les contructions\n" +"JOIN ne sont pas aplanies." + +#: utils/misc/guc.c:2169 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "" +"La planificateur applanira les constructions JOIN explicites dans des listes\n" +"d'éléments FROM lorsqu'une liste d'au plus ce nombre d'éléments en\n" +"résulterait." + +#: utils/misc/guc.c:2180 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "Initialise la limite des éléments FROM en dehors de laquelle GEQO est utilisé." + +#: utils/misc/guc.c:2190 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "" +"GEQO : l'effort est utilisé pour initialiser une valeur par défaut pour les\n" +"autres paramètres GEQO." + +#: utils/misc/guc.c:2200 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO : nombre d'individus dans une population." + +#: utils/misc/guc.c:2201 utils/misc/guc.c:2211 +msgid "Zero selects a suitable default value." +msgstr "Zéro sélectionne une valeur par défaut convenable." + +#: utils/misc/guc.c:2210 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO : nombre d'itérations dans l'algorithme." + +#: utils/misc/guc.c:2222 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Temps d'attente du verrou avant de vérifier les verrous bloqués." + +#: utils/misc/guc.c:2233 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "Définit le délai maximum avant d'annuler les requêtes lorsqu'un serveur « hot standby » traite les données des journaux de transactions archivés" + +#: utils/misc/guc.c:2244 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "" +"Initialise le délai maximum avant d'annuler les requêtes lorsqu'un serveur en\n" +"hotstandby traite les données des journaux de transactions envoyés en flux." + +#: utils/misc/guc.c:2255 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "Définit la durée minimale pour appliquer des changements lors de la restauration." + +#: utils/misc/guc.c:2266 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "Définit l'intervalle maximum entre les rapports du statut du walreceiver au serveur émetteur." + +#: utils/misc/guc.c:2277 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "Définit la durée maximale d'attente pour réceptionner des donnés du serveur émetteur." + +#: utils/misc/guc.c:2288 +msgid "Sets the maximum number of concurrent connections." +msgstr "Nombre maximum de connexions simultanées." + +#: utils/misc/guc.c:2299 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "Nombre de connexions réservées aux super-utilisateurs." + +#: utils/misc/guc.c:2309 +msgid "Amount of dynamic shared memory reserved at startup." +msgstr "Quantité de mémoire partagée dynamique réservée au démarrage." + +#: utils/misc/guc.c:2324 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Nombre de tampons en mémoire partagée utilisé par le serveur." + +#: utils/misc/guc.c:2335 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Nombre maximum de tampons en mémoire partagée utilisés par chaque session." + +#: utils/misc/guc.c:2346 +msgid "Sets the TCP port the server listens on." +msgstr "Port TCP sur lequel le serveur écoutera." + +#: utils/misc/guc.c:2356 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Droits d'accès au socket domaine Unix." + +#: utils/misc/guc.c:2357 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "" +"Les sockets de domaine Unix utilise l'ensemble des droits habituels du système\n" +"de fichiers Unix. La valeur de ce paramètre doit être une spécification en\n" +"mode numérique de la forme acceptée par les appels système chmod et umask\n" +"(pour utiliser le format octal, le nombre doit commencer par un zéro)." + +#: utils/misc/guc.c:2371 +msgid "Sets the file permissions for log files." +msgstr "Initialise les droits des fichiers de trace." + +#: utils/misc/guc.c:2372 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "" +"La valeur du paramètre est attendue dans le format numérique du mode accepté\n" +"par les appels système chmod et umask (pour utiliser le format octal\n" +"personnalisé, le numéro doit commencer par un zéro)." + +#: utils/misc/guc.c:2386 +msgid "Shows the mode of the data directory." +msgstr "Affiche le mode du répertoire des données." + +#: utils/misc/guc.c:2387 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "" +"La valeur du paramètre est une spécification numérique de mode dans la forme acceptée\n" +"par les appels système chmod et umask (pour utiliser le format octal\n" +"personnalisé, le numéro doit commencer par un 0 (zéro).)" + +#: utils/misc/guc.c:2400 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Initialise la mémoire maximum utilisée pour les espaces de travail des requêtes." + +#: utils/misc/guc.c:2401 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "" +"Spécifie la mémoire à utiliser par les opérations de tris internes et par\n" +"les tables de hachage avant de passer sur des fichiers temporaires sur disque." + +#: utils/misc/guc.c:2413 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Initialise la mémoire maximum utilisée pour les opérations de maintenance." + +#: utils/misc/guc.c:2414 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Ceci inclut les opérations comme VACUUM et CREATE INDEX." + +#: utils/misc/guc.c:2424 +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "Initialise la mémoire maximum utilisée pour le décodage logique." + +#: utils/misc/guc.c:2425 +msgid "This much memory can be used by each internal reorder buffer before spilling to disk." +msgstr "Cette quantité de mémoire peut être utilisée par chaque cache de tri interne avant de passer sur des fichiers temporaires sur disque." + +#: utils/misc/guc.c:2441 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Initialise la profondeur maximale de la pile, en Ko." + +#: utils/misc/guc.c:2452 +msgid "Limits the total size of all temporary files used by each process." +msgstr "Limite la taille totale de tous les fichiers temporaires utilisés par chaque processus." + +#: utils/misc/guc.c:2453 +msgid "-1 means no limit." +msgstr "-1 signifie sans limite." + +#: utils/misc/guc.c:2463 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Coût d'un VACUUM pour une page trouvée dans le cache du tampon." + +#: utils/misc/guc.c:2473 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Coût d'un VACUUM pour une page introuvable dans le cache du tampon." + +#: utils/misc/guc.c:2483 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Coût d'un VACUUM pour une page modifiée par VACUUM." + +#: utils/misc/guc.c:2493 +msgid "Vacuum cost amount available before napping." +msgstr "Coût du VACUUM disponible avant un repos." + +#: utils/misc/guc.c:2503 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "Coût du VACUUM disponible avant un repos, pour autovacuum." + +#: utils/misc/guc.c:2513 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "" +"Initialise le nombre maximum de fichiers ouverts simultanément pour chaque\n" +"processus serveur." + +#: utils/misc/guc.c:2526 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Initialise le nombre maximum de transactions préparées simultanément." + +#: utils/misc/guc.c:2537 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Initialise l'OID minimum des tables pour tracer les verrous." + +#: utils/misc/guc.c:2538 +msgid "Is used to avoid output on system tables." +msgstr "Est utilisé pour éviter la sortie sur des tables systèmes." + +#: utils/misc/guc.c:2547 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "Configure l'OID de la table avec une trace des verrous sans condition." + +#: utils/misc/guc.c:2559 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Initialise la durée maximum permise pour toute instruction." + +#: utils/misc/guc.c:2560 utils/misc/guc.c:2571 utils/misc/guc.c:2582 utils/misc/guc.c:2593 +msgid "A value of 0 turns off the timeout." +msgstr "Une valeur de 0 désactive le timeout." + +#: utils/misc/guc.c:2570 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Initialise la durée maximum permise pour toute attente d'un verrou." + +#: utils/misc/guc.c:2581 +msgid "Sets the maximum allowed idle time between queries, when in a transaction." +msgstr "Configure la durée maximale autorisée d'attente entre deux requêtes dans une transaction." + +#: utils/misc/guc.c:2592 +msgid "Sets the maximum allowed idle time between queries, when not in a transaction." +msgstr "Configure la durée maximale autorisée d'attente entre deux requêtes hors d'une transaction." + +#: utils/misc/guc.c:2603 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "Âge minimum à partir duquel VACUUM devra geler une ligne de table." + +#: utils/misc/guc.c:2613 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "Âge à partir duquel VACUUM devra parcourir une table complète pour geler les lignes." + +#: utils/misc/guc.c:2623 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "Âge minimum à partir duquel VACUUM devra geler un MultiXactId dans une ligne de table." + +#: utils/misc/guc.c:2633 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "" +"Âge Multixact à partir duquel VACUUM devra parcourir une table complète pour geler les\n" +"lignes." + +#: utils/misc/guc.c:2643 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "Nombre de transactions à partir duquel les nettoyages VACUUM et HOT doivent être déferrés." + +#: utils/misc/guc.c:2652 +msgid "Age at which VACUUM should trigger failsafe to avoid a wraparound outage." +msgstr "" + +#: utils/misc/guc.c:2661 +msgid "Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage." +msgstr "" + +#: utils/misc/guc.c:2674 +msgid "Sets the maximum number of locks per transaction." +msgstr "Initialise le nombre maximum de verrous par transaction." + +#: utils/misc/guc.c:2675 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "" +"La table des verrous partagés est dimensionnée sur l'idée qu'au plus\n" +"max_locks_per_transaction * max_connections objets distincts auront besoin\n" +"d'être verrouillés à tout moment." + +#: utils/misc/guc.c:2686 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Initialise le nombre maximum de verrous prédicats par transaction." + +#: utils/misc/guc.c:2687 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "" +"La table des verrous de prédicat partagés est dimensionnée sur l'idée qu'au plus\n" +"max_pred_locks_per_transaction * max_connections objets distincts auront besoin\n" +"d'être verrouillés à tout moment." + +#: utils/misc/guc.c:2698 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Initialise le nombre maximum de pages et lignes verrouillées avec prédicats par transaction." + +#: utils/misc/guc.c:2699 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Si plus que ce nombre de pages et lignes dans la même relation sont verrouillées par une connexion, ces verrous sont remplacés par un verrou de niveau relation." + +#: utils/misc/guc.c:2709 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Initialise le nombre maximum de lignes verrouillées avec prédicat par transaction." + +#: utils/misc/guc.c:2710 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Si plus que ce nombre de lignes sur la même page sont verrouillées par une connexion, ces verrous sont remplacés par un verrou de niveau de page." + +#: utils/misc/guc.c:2720 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "" +"Initialise le temps maximum en secondes pour terminer l'authentification du\n" +"client." + +#: utils/misc/guc.c:2732 +msgid "Waits N seconds on connection startup before authentication." +msgstr "Attends N secondes au lancement de la connexion avant l'authentification." + +#: utils/misc/guc.c:2743 +msgid "Sets the size of WAL files held for standby servers." +msgstr "Initialise la volumétrie de journaux de transactions conservés pour les serveurs standby." + +#: utils/misc/guc.c:2754 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "Initialise la taille minimale à laquelle réduire l'espace des journaux de transaction." + +#: utils/misc/guc.c:2766 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Initialise la volumétrie de journaux de transaction qui déclenche un checkpoint." + +#: utils/misc/guc.c:2778 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "" +"Initialise le temps maximum entre des points de vérification (checkpoints)\n" +"pour les journaux de transactions." + +#: utils/misc/guc.c:2789 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "" +"Active des messages d'avertissement si les segments des points de\n" +"vérifications se remplissent plus fréquemment que cette durée." + +#: utils/misc/guc.c:2791 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "" +"Écrit un message dans les journaux applicatifs du serveur si les points de\n" +"vérifications causées par le remplissage des journaux de transaction avec\n" +"des points de vérification qui arrivent plus fréquemment que ce nombre de\n" +"secondes. Une valeur 0 désactive l'avertissement." + +#: utils/misc/guc.c:2803 utils/misc/guc.c:3019 utils/misc/guc.c:3066 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "Nombre de pages après lequel les précédentes écritures seront synchronisées sur disque." + +#: utils/misc/guc.c:2814 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "" +"Initialise le nombre de tampons de pages disque dans la mémoire partagée\n" +"pour les journaux de transactions." + +#: utils/misc/guc.c:2825 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "Temps entre les synchronisations des WAL sur disque effectuées par le processus d'écriture des journaux de transaction." + +#: utils/misc/guc.c:2836 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "Quantité de WAL écrits par le processus d'écriture des journaux de transaction devant déclencher une synchronisation sur disque." + +#: utils/misc/guc.c:2847 +msgid "Minimum size of new file to fsync instead of writing WAL." +msgstr "Taille minimale d'un nouveau fichier à synchroniser sur disque au lieu d'écrire dans les journaux de transactions." + +#: utils/misc/guc.c:2858 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "" +"Initialise le nombre maximum de processus d'envoi des journaux de transactions\n" +"exécutés simultanément." + +#: utils/misc/guc.c:2869 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Initialise le nombre maximum de slots de réplication définis simultanément." + +#: utils/misc/guc.c:2879 +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "Initialise la volumétrie maximale des journaux de transactions pouvant être réservée pour les slots de réplication." + +#: utils/misc/guc.c:2880 +msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "Les slots de réplication seront marqués comme échoués, et les segments relâchés pour suppression ou recyclage si autant d'espace est occupé par les journaux sur disque." + +#: utils/misc/guc.c:2892 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "Initialise le temps maximum à attendre pour la réplication des WAL." + +#: utils/misc/guc.c:2903 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "" +"Initialise le délai en microsecondes entre l'acceptation de la transaction\n" +"et le vidage du journal de transaction sur disque." + +#: utils/misc/guc.c:2915 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "" +"Initialise le nombre minimum de transactions ouvertes simultanément avant le\n" +"commit_delay." + +#: utils/misc/guc.c:2926 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Initialise le nombre de chiffres affichés pour les valeurs à virgule flottante." + +#: utils/misc/guc.c:2927 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "Ceci affecte les types de données real, double precision et géométriques. Une valeur zéro ou négative du paramètre est ajoutée au nombre standard de chiffres (FLT_DIG ou DBL_DIG comme approprié). Toute valeur plus grande que zéro sélectionne le mode de sortie précis." + +#: utils/misc/guc.c:2939 +msgid "Sets the minimum execution time above which a sample of statements will be logged. Sampling is determined by log_statement_sample_rate." +msgstr "Initialise le temps d'exécution minimum au-dessus duquel un échantillon de requêtes est tracé. L'échantillonnage est déterminé par log_statement_sample_rate." + +#: utils/misc/guc.c:2942 +msgid "Zero logs a sample of all queries. -1 turns this feature off." +msgstr "Zéro trace un échantillon de toutes les requêtes. -1 désactive cette fonctionnalité." + +#: utils/misc/guc.c:2952 +msgid "Sets the minimum execution time above which all statements will be logged." +msgstr "Initialise le temps d'exécution minimum au-dessus duquel toutes les requêtes seront tracées." + +#: utils/misc/guc.c:2954 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "Zéro affiche toutes les requêtes. -1 désactive cette fonctionnalité." + +#: utils/misc/guc.c:2964 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "" +"Initialise le temps d'exécution minimum au-dessus duquel les actions\n" +"autovacuum seront tracées." + +#: utils/misc/guc.c:2966 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "Zéro affiche toutes les requêtes. -1 désactive cette fonctionnalité." + +#: utils/misc/guc.c:2976 +msgid "When logging statements, limit logged parameter values to first N bytes." +msgstr "Lors de la trace des requêtes, limite les valeurs des paramètres tracés aux N premiers octets." + +#: utils/misc/guc.c:2977 utils/misc/guc.c:2988 +msgid "-1 to print values in full." +msgstr "-1 pour afficher les valeurs complètement." + +#: utils/misc/guc.c:2987 +msgid "When reporting an error, limit logged parameter values to first N bytes." +msgstr "Lors de la trace d'une erreur, limite les valeurs des paramètres tracés aux N premiers octets." + +#: utils/misc/guc.c:2998 +msgid "Background writer sleep time between rounds." +msgstr "Durée d'endormissement du processus d'écriture en tâche de fond (background writer) entre deux cycles." + +#: utils/misc/guc.c:3009 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "Nombre maximum de pages LRU à nettoyer par le processus d'écriture en tâche de fond (background writer)" + +#: utils/misc/guc.c:3032 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "Nombre de requêtes simultanées pouvant être gérées efficacement par le sous-système disque." + +#: utils/misc/guc.c:3050 +msgid "A variant of effective_io_concurrency that is used for maintenance work." +msgstr "Une variante de effective_io_concurrency pouvant être utilisée pour les travaux de maintenance." + +#: utils/misc/guc.c:3079 +msgid "Maximum number of concurrent worker processes." +msgstr "Nombre maximum de background workers simultanés." + +#: utils/misc/guc.c:3091 +msgid "Maximum number of logical replication worker processes." +msgstr "Nombre maximum de processus workers de réplication logique." + +#: utils/misc/guc.c:3103 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Nombre maximum de workers de synchronisation par souscription." + +#: utils/misc/guc.c:3113 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "La rotation automatique des journaux applicatifs s'effectuera toutes les N minutes." + +#: utils/misc/guc.c:3124 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "La rotation automatique des journaux applicatifs s'effectuera après N kilooctets." + +#: utils/misc/guc.c:3135 +msgid "Shows the maximum number of function arguments." +msgstr "Affiche le nombre maximum d'arguments de fonction." + +#: utils/misc/guc.c:3146 +msgid "Shows the maximum number of index keys." +msgstr "Affiche le nombre maximum de clés d'index." + +#: utils/misc/guc.c:3157 +msgid "Shows the maximum identifier length." +msgstr "Affiche la longueur maximum d'un identifiant." + +#: utils/misc/guc.c:3168 +msgid "Shows the size of a disk block." +msgstr "Affiche la taille d'un bloc de disque." + +#: utils/misc/guc.c:3179 +msgid "Shows the number of pages per disk file." +msgstr "Affiche le nombre de pages par fichier." + +#: utils/misc/guc.c:3190 +msgid "Shows the block size in the write ahead log." +msgstr "Affiche la taille du bloc dans les journaux de transactions." + +#: utils/misc/guc.c:3201 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "Initalise le temps à attendre avant de retenter de récupérer un WAL après une tentative infructueuse." + +#: utils/misc/guc.c:3213 +msgid "Shows the size of write ahead log segments." +msgstr "Affiche la taille des journaux de transactions." + +#: utils/misc/guc.c:3226 +msgid "Time to sleep between autovacuum runs." +msgstr "Durée d'endormissement entre deux exécutions d'autovacuum." + +#: utils/misc/guc.c:3236 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Nombre minimum de lignes mises à jour ou supprimées avant le VACUUM." + +#: utils/misc/guc.c:3245 +msgid "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums." +msgstr "Nombre minimum de lignes insérées avant un ANALYZE, ou -1 pour désactiver ce comportement" + +#: utils/misc/guc.c:3254 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "Nombre minimum de lignes insérées, mises à jour ou supprimées avant un ANALYZE." + +#: utils/misc/guc.c:3264 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "Âge à partir duquel l'autovacuum se déclenche sur une table pour empêcher un rebouclage des identifiants de transaction." + +#: utils/misc/guc.c:3279 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "Âge multixact à partir duquel l'autovacuum se déclenche sur une table pour empêcher la réinitialisation du multixact" + +#: utils/misc/guc.c:3289 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "Initialise le nombre maximum de processus autovacuum exécutés simultanément." + +#: utils/misc/guc.c:3299 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Initialise le nombre maximum de processus parallèles par opération de maintenance." + +#: utils/misc/guc.c:3309 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Initialise le nombre maximum de processus parallèles par nœud d'exécution." + +#: utils/misc/guc.c:3320 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Configure le nombre maximum de processus parallélisés pouvant être actifs en même temps." + +#: utils/misc/guc.c:3331 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "Initialise la mémoire maximum utilisée par chaque processus autovacuum worker." + +#: utils/misc/guc.c:3342 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "Temps à partir duquel un snapshot est trop ancien pour lire des pages ayant changées après que le snapshot ait été effectué." + +#: utils/misc/guc.c:3343 +msgid "A value of -1 disables this feature." +msgstr "Une valeur de -1 désactive cette fonctionnalité." + +#: utils/misc/guc.c:3353 +msgid "Time between issuing TCP keepalives." +msgstr "Secondes entre l'exécution de « TCP keepalives »." + +#: utils/misc/guc.c:3354 utils/misc/guc.c:3365 utils/misc/guc.c:3489 +msgid "A value of 0 uses the system default." +msgstr "Une valeur de 0 utilise la valeur par défaut du système." + +#: utils/misc/guc.c:3364 +msgid "Time between TCP keepalive retransmits." +msgstr "Secondes entre les retransmissions de « TCP keepalive »." + +#: utils/misc/guc.c:3375 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "La renégociation SSL n'est plus supportée; ce paramètre ne peut être positionné qu'à 0." + +#: utils/misc/guc.c:3386 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "Nombre maximum de retransmissions de « TCP keepalive »." + +#: utils/misc/guc.c:3387 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "" +"Ceci contrôle le nombre de retransmissions keepalive consécutives qui\n" +"peuvent être perdues avant qu'une connexion ne soit considérée morte. Une\n" +"valeur de 0 utilise la valeur par défaut du système." + +#: utils/misc/guc.c:3398 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "Configure le nombre maximum de résultats lors d'une recherche par GIN." + +#: utils/misc/guc.c:3409 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Initialise le sentiment du planificateur sur la taille des caches disques." + +#: utils/misc/guc.c:3410 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "" +"C'est-à-dire, la portion des caches disques (noyau et PostgreSQL) qui sera utilisé pour les\n" +"fichiers de données de PostgreSQL. C'est mesuré en pages disque, qui font\n" +"normalement 8 Ko chaque." + +#: utils/misc/guc.c:3421 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "Configure la quantité minimale de données de table pour un parcours parallèle." + +#: utils/misc/guc.c:3422 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Si le planificateur estime qu'il lira un nombre de blocs de table trop petit pour atteindre cette limite, un parcours parallèle ne sera pas considéré." + +#: utils/misc/guc.c:3432 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "Configure la quantité minimale de données d'index pour un parcours parallèle." + +#: utils/misc/guc.c:3433 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Si le planificateur estime qu'il lira un nombre de blocs d'index trop petit pour atteindre cette limite, un parcours parallèle ne sera pas considéré." + +#: utils/misc/guc.c:3444 +msgid "Shows the server version as an integer." +msgstr "Affiche la version du serveur sous la forme d'un entier." + +#: utils/misc/guc.c:3455 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "" +"Trace l'utilisation de fichiers temporaires plus gros que ce nombre de\n" +"kilooctets." + +#: utils/misc/guc.c:3456 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "" +"Zéro trace toutes les requêtes. La valeur par défaut est -1 (désactivant\n" +"cette fonctionnalité)." + +#: utils/misc/guc.c:3466 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "Configure la taille réservée pour pg_stat_activity.query, en octets." + +#: utils/misc/guc.c:3477 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "Configure la taille maximale de la pending list d'un index GIN." + +#: utils/misc/guc.c:3488 +msgid "TCP user timeout." +msgstr "Délai d'attente maximal TCP utilisateur." + +#: utils/misc/guc.c:3499 +msgid "The size of huge page that should be requested." +msgstr "La taille du Huge Page devant être réclamé." + +#: utils/misc/guc.c:3510 +msgid "Aggressively invalidate system caches for debugging purposes." +msgstr "" + +#: utils/misc/guc.c:3533 +msgid "Sets the time interval between checks for disconnection while running queries." +msgstr "Configure l'intervalle de temps entre des vérifications de déconnexion lors de l'exécution de requêtes." + +#: utils/misc/guc.c:3553 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "" +"Initialise l'estimation du planificateur pour le coût d'une page disque\n" +"récupérée séquentiellement." + +#: utils/misc/guc.c:3564 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "" +"Initialise l'estimation du plnnificateur pour le coût d'une page disque\n" +"récupérée non séquentiellement." + +#: utils/misc/guc.c:3575 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "" +"Initialise l'estimation du planificateur pour le coût d'exécution sur chaque\n" +"ligne." + +#: utils/misc/guc.c:3586 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "" +"Initialise l'estimation du planificateur pour le coût de traitement de\n" +"chaque ligne indexée lors d'un parcours d'index." + +#: utils/misc/guc.c:3597 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "" +"Initialise l'estimation du planificateur pour le coût de traitement de\n" +"chaque opérateur ou appel de fonction." + +#: utils/misc/guc.c:3608 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to leader backend." +msgstr "Configure l'estimation du planificateur pour le coût de passage de chaque ligne d'un processus worker vers son processus leader." + +#: utils/misc/guc.c:3619 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "Initialise l'estimation du planificateur pour le coût de démarrage des processus d'exécution de requêtes parallèles." + +#: utils/misc/guc.c:3631 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Effectuer une compilation JIT si la requête est plus coûteuse." + +#: utils/misc/guc.c:3632 +msgid "-1 disables JIT compilation." +msgstr "-1 désactive la compilation JIT." + +#: utils/misc/guc.c:3642 +msgid "Optimize JIT-compiled functions if query is more expensive." +msgstr "Optimise les fonctions compilées avec JIT si la requête est plus coûteuse." + +#: utils/misc/guc.c:3643 +msgid "-1 disables optimization." +msgstr "-1 désactive l'optimisation." + +#: utils/misc/guc.c:3653 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Effectuer un inlining JIT si la requête est plus coûteuse." + +#: utils/misc/guc.c:3654 +msgid "-1 disables inlining." +msgstr "-1 désactive l'inlining." + +#: utils/misc/guc.c:3664 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "Initialise l'estimation du planificateur de la fraction des lignes d'un curseur à récupérer." + +#: utils/misc/guc.c:3676 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO : pression sélective dans la population." + +#: utils/misc/guc.c:3687 +msgid "GEQO: seed for random path selection." +msgstr "GEQO : graine pour la sélection du chemin aléatoire." + +#: utils/misc/guc.c:3698 +msgid "Multiple of work_mem to use for hash tables." +msgstr "Multiple de work_mem à utiliser pour les tables de hachage." + +#: utils/misc/guc.c:3709 +msgid "Multiple of the average buffer usage to free per round." +msgstr "Multiplede l'utilisation moyenne des tampons à libérer à chaque tour." + +#: utils/misc/guc.c:3719 +msgid "Sets the seed for random-number generation." +msgstr "Initialise la clé pour la génération de nombres aléatoires." + +#: utils/misc/guc.c:3730 +msgid "Vacuum cost delay in milliseconds." +msgstr "Délai d'un coût de VACUUM en millisecondes." + +#: utils/misc/guc.c:3741 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Délai d'un coût de VACUUM en millisecondes, pour autovacuum." + +#: utils/misc/guc.c:3752 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "" +"Nombre de lignes modifiées ou supprimées avant d'exécuter un VACUUM\n" +"(fraction de reltuples)." + +#: utils/misc/guc.c:3762 +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "Nombre de lignes insérées avant d'effectuer un VACUUM (fraction de reltuples)." + +#: utils/misc/guc.c:3772 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "" +"Nombre de lignes insérées, mises à jour ou supprimées avant d'analyser\n" +"une fraction de reltuples." + +#: utils/misc/guc.c:3782 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "" +"Temps passé à vider les tampons lors du point de vérification, en tant que\n" +"fraction de l'intervalle du point de vérification." + +#: utils/misc/guc.c:3792 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "Fraction de requêtes dépassant log_min_duration_sample à tracer" + +#: utils/misc/guc.c:3793 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "Utilisez une valeur entre 0,0 (pas de trace) et 1.0 (tracer tout)." + +#: utils/misc/guc.c:3802 +msgid "Sets the fraction of transactions from which to log all statements." +msgstr "Configure la fraction des transactions pour lesquelles il faut tracer toutes les requêtes" + +#: utils/misc/guc.c:3803 +msgid "Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "Utiliser une valeur entre 0.0 (aucune trace) et 1.0 (trace tous les requêtes de toutes les transactions)." + +#: utils/misc/guc.c:3822 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "La commande shell qui sera appelée pour archiver un journal de transaction." + +#: utils/misc/guc.c:3832 +msgid "Sets the shell command that will be called to retrieve an archived WAL file." +msgstr "Définit la commande shell qui sera appelée pour récupérer un fichier WAL archivé." + +#: utils/misc/guc.c:3842 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "Définit la commande shell qui sera appelée à chaque point de reprise (restart point)." + +#: utils/misc/guc.c:3852 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "Définit la commande shell qui sera appelée une fois à la fin de la restauration." + +#: utils/misc/guc.c:3862 +msgid "Specifies the timeline to recover into." +msgstr "Définit la timeline cible de la restauration." + +#: utils/misc/guc.c:3872 +msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." +msgstr "Positionner à « immediate » pour arrêter la restauration dès qu'un état consistent est atteint." + +#: utils/misc/guc.c:3881 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "Définit l'identifiant de transaction jusqu'où la restauration s'effectuera." + +#: utils/misc/guc.c:3890 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "Définit le point dans le temps jusqu'où la restauration s'effectuera." + +#: utils/misc/guc.c:3899 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "Définit le point de restauration nommé jusqu'où la restauration va procéder." + +#: utils/misc/guc.c:3908 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "Définit le LSN des journaux de transactions jusqu'où la restauration s'effectuera." + +# trigger_file +#: utils/misc/guc.c:3918 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "Définit un nom de fichier dont la présence termine la restauration du serveur secondaire." + +#: utils/misc/guc.c:3928 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "Définit la chaîne de connexion à utiliser pour se connecter au serveur émetteur." + +#: utils/misc/guc.c:3939 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "Définit le nom du slot de réplication à utiliser sur le serveur émetteur." + +#: utils/misc/guc.c:3949 +msgid "Sets the client's character set encoding." +msgstr "Initialise l'encodage du client." + +#: utils/misc/guc.c:3960 +msgid "Controls information prefixed to each log line." +msgstr "Contrôle l'information préfixée sur chaque ligne de trace." + +#: utils/misc/guc.c:3961 +msgid "If blank, no prefix is used." +msgstr "Si vide, aucun préfixe n'est utilisé." + +#: utils/misc/guc.c:3970 +msgid "Sets the time zone to use in log messages." +msgstr "Initialise le fuseau horaire à utiliser pour les journaux applicatifs." + +#: utils/misc/guc.c:3980 +msgid "Sets the display format for date and time values." +msgstr "Initialise le format d'affichage des valeurs date et time." + +#: utils/misc/guc.c:3981 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "Contrôle aussi l'interprétation des dates ambiguës en entrée." + +#: utils/misc/guc.c:3992 +msgid "Sets the default table access method for new tables." +msgstr "Définit la méthode d'accès par défaut pour les nouvelles tables." + +#: utils/misc/guc.c:4003 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "Initialise le tablespace par défaut pour créer les tables et index." + +#: utils/misc/guc.c:4004 +msgid "An empty string selects the database's default tablespace." +msgstr "Une chaîne vide sélectionne le tablespace par défaut de la base de données." + +#: utils/misc/guc.c:4014 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "" +"Initialise le(s) tablespace(s) à utiliser pour les tables temporaires et les\n" +"fichiers de tri." + +#: utils/misc/guc.c:4025 +msgid "Sets the path for dynamically loadable modules." +msgstr "Initialise le chemin des modules chargeables dynamiquement." + +#: utils/misc/guc.c:4026 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "" +"Si un module chargeable dynamiquement a besoin d'être ouvert et que le nom\n" +"spécifié n'a pas une composante répertoire (c'est-à-dire que le nom ne\n" +"contient pas un '/'), le système cherche le fichier spécifié sur ce chemin." + +#: utils/misc/guc.c:4039 +msgid "Sets the location of the Kerberos server key file." +msgstr "Initalise l'emplacement du fichier de la clé serveur pour Kerberos." + +#: utils/misc/guc.c:4050 +msgid "Sets the Bonjour service name." +msgstr "Initialise le nom du service Bonjour." + +#: utils/misc/guc.c:4062 +msgid "Shows the collation order locale." +msgstr "Affiche la locale de tri et de groupement." + +#: utils/misc/guc.c:4073 +msgid "Shows the character classification and case conversion locale." +msgstr "Affiche la classification des caractères et la locale de conversions." + +#: utils/misc/guc.c:4084 +msgid "Sets the language in which messages are displayed." +msgstr "Initialise le langage dans lequel les messages sont affichés." + +#: utils/misc/guc.c:4094 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Initialise la locale pour le formattage des montants monétaires." + +#: utils/misc/guc.c:4104 +msgid "Sets the locale for formatting numbers." +msgstr "Initialise la locale pour formater les nombres." + +#: utils/misc/guc.c:4114 +msgid "Sets the locale for formatting date and time values." +msgstr "Initialise la locale pour formater les valeurs date et time." + +#: utils/misc/guc.c:4124 +msgid "Lists shared libraries to preload into each backend." +msgstr "Liste les bibliothèques partagées à précharger dans chaque processus serveur." + +#: utils/misc/guc.c:4135 +msgid "Lists shared libraries to preload into server." +msgstr "Liste les bibliothèques partagées à précharger dans le serveur." + +#: utils/misc/guc.c:4146 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "Liste les bibliothèques partagées non privilégiées à précharger dans chaque processus serveur." + +#: utils/misc/guc.c:4157 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "" +"Initialise l'ordre de recherche des schémas pour les noms qui ne précisent\n" +"pas le schéma." + +#: utils/misc/guc.c:4169 +msgid "Shows the server (database) character set encoding." +msgstr "Affiche l'encodage des caractères pour le serveur (base de données)." + +#: utils/misc/guc.c:4181 +msgid "Shows the server version." +msgstr "Affiche la version du serveur." + +#: utils/misc/guc.c:4193 +msgid "Sets the current role." +msgstr "Initialise le rôle courant." + +#: utils/misc/guc.c:4205 +msgid "Sets the session user name." +msgstr "Initialise le nom de l'utilisateur de la session." + +#: utils/misc/guc.c:4216 +msgid "Sets the destination for server log output." +msgstr "Initialise la destination des journaux applicatifs du serveur." + +#: utils/misc/guc.c:4217 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "" +"Les valeurs valides sont une combinaison de « stderr », « syslog »,\n" +"« csvlog » et « eventlog », suivant la plateforme." + +#: utils/misc/guc.c:4228 +msgid "Sets the destination directory for log files." +msgstr "Initialise le répertoire de destination pour les journaux applicatifs." + +#: utils/misc/guc.c:4229 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "Accepte un chemin relatif ou absolu pour le répertoire des données." + +#: utils/misc/guc.c:4239 +msgid "Sets the file name pattern for log files." +msgstr "Initialise le modèle de nom de fichiers pour les journaux applicatifs." + +#: utils/misc/guc.c:4250 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "" +"Initialise le nom du programme utilisé pour identifier les messages de\n" +"PostgreSQL dans syslog." + +#: utils/misc/guc.c:4261 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "" +"Initialise le nom de l'application, utilisé pour identifier les messages de\n" +"PostgreSQL dans eventlog." + +#: utils/misc/guc.c:4272 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "Initialise la zone horaire pour afficher et interpréter les dates/heures." + +#: utils/misc/guc.c:4282 +msgid "Selects a file of time zone abbreviations." +msgstr "Sélectionne un fichier contenant les abréviations des fuseaux horaires." + +#: utils/misc/guc.c:4292 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Initialise le groupe d'appartenance du socket domaine Unix." + +#: utils/misc/guc.c:4293 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "Le propriétaire du socket est toujours l'utilisateur qui a lancé le serveur." + +#: utils/misc/guc.c:4303 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Initialise les répertoires où les sockets de domaine Unix seront créés." + +#: utils/misc/guc.c:4318 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Initialise le nom de l'hôte ou l'adresse IP à écouter." + +#: utils/misc/guc.c:4333 +msgid "Sets the server's data directory." +msgstr "Initialise le répertoire des données du serveur." + +#: utils/misc/guc.c:4344 +msgid "Sets the server's main configuration file." +msgstr "Voir le fichier de configuration principal du serveur." + +#: utils/misc/guc.c:4355 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Initialise le fichier de configuration « hba » du serveur." + +#: utils/misc/guc.c:4366 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Initialise le fichier de configuration « ident » du serveur." + +#: utils/misc/guc.c:4377 +msgid "Writes the postmaster PID to the specified file." +msgstr "Écrit le PID du postmaster PID dans le fichier spécifié." + +#: utils/misc/guc.c:4388 +msgid "Shows the name of the SSL library." +msgstr "Affiche le nom de la bibliothèque SSL." + +#: utils/misc/guc.c:4403 +msgid "Location of the SSL server certificate file." +msgstr "Emplacement du fichier du certificat serveur SSL." + +#: utils/misc/guc.c:4413 +msgid "Location of the SSL server private key file." +msgstr "Emplacement du fichier de la clé privée SSL du serveur." + +#: utils/misc/guc.c:4423 +msgid "Location of the SSL certificate authority file." +msgstr "Emplacement du fichier du certificat autorité SSL." + +#: utils/misc/guc.c:4433 +msgid "Location of the SSL certificate revocation list file." +msgstr "Emplacement du fichier de liste de révocation des certificats SSL." + +#: utils/misc/guc.c:4443 +msgid "Location of the SSL certificate revocation list directory." +msgstr "Emplacement du répertoire de liste de révocation des certificats SSL." + +#: utils/misc/guc.c:4453 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Écrit les fichiers statistiques temporaires dans le répertoire indiqué." + +#: utils/misc/guc.c:4464 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "Nombre de standbys synchrones et liste des noms des synchrones potentiels." + +#: utils/misc/guc.c:4475 +msgid "Sets default text search configuration." +msgstr "Initialise la configuration par défaut de la recherche plein texte." + +#: utils/misc/guc.c:4485 +msgid "Sets the list of allowed SSL ciphers." +msgstr "Initialise la liste des chiffrements SSL autorisés." + +#: utils/misc/guc.c:4500 +msgid "Sets the curve to use for ECDH." +msgstr "Initialise la courbe à utiliser pour ECDH." + +#: utils/misc/guc.c:4515 +msgid "Location of the SSL DH parameters file." +msgstr "Emplacement du fichier des paramètres DH SSL." + +#: utils/misc/guc.c:4526 +msgid "Command to obtain passphrases for SSL." +msgstr "Commande pour obtenir la phrase de passe pour SSL." + +#: utils/misc/guc.c:4537 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "Configure le nom de l'application à indiquer dans les statistiques et les journaux." + +#: utils/misc/guc.c:4548 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Configure le nom du cluster, qui est inclus dans le titre du processus." + +#: utils/misc/guc.c:4559 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "Configure les gestionnaires de ressource des WAL pour lesquels des vérifications de cohérence sont effectuées." + +#: utils/misc/guc.c:4560 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "Des images complètes de bloc seront tracées pour tous les blocs de données et vérifiées avec le résultat du rejeu des journaux de transactions." + +#: utils/misc/guc.c:4570 +msgid "JIT provider to use." +msgstr "Fournisseur JIT à utiliser." + +#: utils/misc/guc.c:4581 +msgid "Log backtrace for errors in these functions." +msgstr "Trace la pile pour les erreurs dans ces fonctions." + +#: utils/misc/guc.c:4601 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Indique si « \\' » est autorisé dans une constante de chaîne." + +#: utils/misc/guc.c:4611 +msgid "Sets the output format for bytea." +msgstr "Initialise le format de sortie pour bytea." + +#: utils/misc/guc.c:4621 +msgid "Sets the message levels that are sent to the client." +msgstr "Initialise les niveaux de message envoyés au client." + +#: utils/misc/guc.c:4622 utils/misc/guc.c:4708 utils/misc/guc.c:4719 utils/misc/guc.c:4795 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "" +"Chaque niveau inclut les niveaux qui suivent. Plus loin sera le niveau,\n" +"moindre sera le nombre de messages envoyés." + +#: utils/misc/guc.c:4632 +msgid "Compute query identifiers." +msgstr "Calcule les identifiants de requête." + +#: utils/misc/guc.c:4642 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "Active l'utilisation des contraintes par le planificateur pour optimiser les requêtes." + +#: utils/misc/guc.c:4643 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "" +"Les parcours de tables seront ignorés si leur contraintes garantissent\n" +"qu'aucune ligne ne correspond à la requête." + +#: utils/misc/guc.c:4654 +msgid "Sets the default compression method for compressible values." +msgstr "Définit la méthode de compression par défaut pour les valeurs compressibles." + +#: utils/misc/guc.c:4665 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Initialise le niveau d'isolation des transactions pour chaque nouvelle transaction." + +#: utils/misc/guc.c:4675 +msgid "Sets the current transaction's isolation level." +msgstr "Initialise le niveau d'isolation de la transaction courante." + +#: utils/misc/guc.c:4686 +msgid "Sets the display format for interval values." +msgstr "Initialise le format d'affichage des valeurs interval." + +#: utils/misc/guc.c:4697 +msgid "Sets the verbosity of logged messages." +msgstr "Initialise la verbosité des messages tracés." + +#: utils/misc/guc.c:4707 +msgid "Sets the message levels that are logged." +msgstr "Initialise les niveaux de messages tracés." + +#: utils/misc/guc.c:4718 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "" +"Génère une trace pour toutes les instructions qui produisent une erreur de\n" +"ce niveau ou de niveaux plus importants." + +#: utils/misc/guc.c:4729 +msgid "Sets the type of statements logged." +msgstr "Initialise le type d'instructions tracées." + +#: utils/misc/guc.c:4739 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "" +"Initialise le niveau (« facility ») de syslog à utiliser lors de l'activation\n" +"de syslog." + +#: utils/misc/guc.c:4754 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "" +"Configure le comportement des sessions pour les triggers et les règles de\n" +"ré-écriture." + +#: utils/misc/guc.c:4764 +msgid "Sets the current transaction's synchronization level." +msgstr "Initialise le niveau d'isolation de la transaction courante." + +#: utils/misc/guc.c:4774 +msgid "Allows archiving of WAL files using archive_command." +msgstr "Autorise l'archivage des journaux de transactions en utilisant archive_command." + +#: utils/misc/guc.c:4784 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "Définit l'action à exécuter à l'arrivée à la cible de la restauration." + +#: utils/misc/guc.c:4794 +msgid "Enables logging of recovery-related debugging information." +msgstr "Active les traces sur les informations de débogage relatives à la restauration." + +#: utils/misc/guc.c:4810 +msgid "Collects function-level statistics on database activity." +msgstr "Récupère les statistiques niveau fonction sur l'activité de la base de données." + +#: utils/misc/guc.c:4820 +msgid "Sets the level of information written to the WAL." +msgstr "Configure le niveau des informations écrites dans les journaux de transactions." + +#: utils/misc/guc.c:4830 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Sélectionne l'implémentation de la mémoire partagée dynamique." + +#: utils/misc/guc.c:4840 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "Sélectionne l'implémentation de mémoire partagée utilisée pour la principale région de mémoire partagée." + +#: utils/misc/guc.c:4850 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "" +"Sélectionne la méthode utilisée pour forcer la mise à jour des journaux de\n" +"transactions sur le disque." + +#: utils/misc/guc.c:4860 +msgid "Sets how binary values are to be encoded in XML." +msgstr "Configure comment les valeurs binaires seront codées en XML." + +#: utils/misc/guc.c:4870 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "" +"Configure si les données XML dans des opérations d'analyse et de\n" +"sérialisation implicite doivent être considérées comme des documents\n" +"ou des fragments de contenu." + +#: utils/misc/guc.c:4881 +msgid "Use of huge pages on Linux or Windows." +msgstr "Utilisation des HugePages sur Linux ou Windows." + +#: utils/misc/guc.c:4891 +msgid "Forces use of parallel query facilities." +msgstr "Force l'utilisation des fonctionnalités de requête parallèle." + +#: utils/misc/guc.c:4892 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "Si possible, exécute des requêtes utilisant des processus parallèles et avec les restrictions parallèles." + +#: utils/misc/guc.c:4902 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "Choisit l'algorithme pour le chiffrement des mots de passe." + +#: utils/misc/guc.c:4912 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Contrôle le choix par le planificateur du plan personnalisé ou du plan générique." + +#: utils/misc/guc.c:4913 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "Les requêtes préparées peuvent avoir des plans particulier et générique, et le planificateur tentera de choisir le meilleur. Ceci peut être utilisé pour remplacer le comportement par défaut." + +#: utils/misc/guc.c:4925 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "Définit la version minimale du protocole SSL/TLS à utiliser." + +#: utils/misc/guc.c:4937 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "Définit la version maximum du protocole SSL/TLS à utiliser." + +#: utils/misc/guc.c:4949 +msgid "Sets the method for synchronizing the data directory before crash recovery." +msgstr "Configure la méthode de synchronisation du répertoire de données avant la restauration après crash." + +#: utils/misc/guc.c:5518 +#, c-format +msgid "invalid configuration parameter name \"%s\"" +msgstr "paramètre de configuration « %s » invalide" + +#: utils/misc/guc.c:5520 +#, c-format +msgid "Custom parameter names must be two or more simple identifiers separated by dots." +msgstr "Les noms de paramètres personnalisés doivent avoir deux ou plusieurs identifiants simples séparés par des points." + +#: utils/misc/guc.c:5529 utils/misc/guc.c:9288 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "paramètre de configuration « %s » non reconnu" + +#: utils/misc/guc.c:5822 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" + +#: utils/misc/guc.c:5827 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "Lancer initdb ou pg_basebackup pour initialiser un répertoire de données PostgreSQL.\n" + +#: utils/misc/guc.c:5847 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%s ne sait pas où trouver le fichier de configuration du serveur.\n" +"Vous devez soit spécifier l'option --config-file, soit spécifier l'option -D, soit initialiser la variable d'environnement PGDATA.\n" + +#: utils/misc/guc.c:5866 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s : n'a pas pu accéder au fichier de configuration « %s » : %s\n" + +#: utils/misc/guc.c:5892 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s ne sait pas où trouver les données du système de bases de données.\n" +"Il est configurable avec « data_directory » dans « %s » ou avec l'option -D ou encore avec la variable d'environnement PGDATA.\n" + +#: utils/misc/guc.c:5940 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s ne sait pas où trouver le fichier de configuration « hba ».\n" +"Il est configurable avec « hba_file » dans « %s » ou avec l'option -D ou encore avec la variable d'environnement PGDATA.\n" + +#: utils/misc/guc.c:5963 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s ne sait pas où trouver le fichier de configuration « hba ».\n" +"Il est configurable avec « ident_file » dans « %s » ou avec l'option -D ou encore avec la variable d'environnement PGDATA.\n" + +#: utils/misc/guc.c:6888 +msgid "Value exceeds integer range." +msgstr "La valeur dépasse l'échelle des entiers." + +#: utils/misc/guc.c:7124 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s est en dehors des limites valides pour le paramètre « %s » (%d .. %d)" + +#: utils/misc/guc.c:7160 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s est en dehors des limites valides pour le paramètre « %s » (%g .. %g)" + +#: utils/misc/guc.c:7320 utils/misc/guc.c:8692 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "ne peut pas configurer les paramètres lors d'une opération parallèle" + +#: utils/misc/guc.c:7337 utils/misc/guc.c:8533 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "le paramètre « %s » ne peut pas être changé" + +#: utils/misc/guc.c:7370 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "le paramètre « %s » ne peut pas être modifié maintenant" + +#: utils/misc/guc.c:7388 utils/misc/guc.c:7435 utils/misc/guc.c:11333 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "droit refusé pour initialiser le paramètre « %s »" + +#: utils/misc/guc.c:7425 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "le paramètre « %s » ne peut pas être initialisé après le lancement du serveur" + +#: utils/misc/guc.c:7473 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "" +"ne peut pas configurer le paramètre « %s » à l'intérieur d'une fonction\n" +"SECURITY DEFINER" + +#: utils/misc/guc.c:8106 utils/misc/guc.c:8153 utils/misc/guc.c:9550 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "doit être super-utilisateur ou membre de pg_read_all_settings pour examiner « %s »" + +#: utils/misc/guc.c:8237 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s prend un seul argument" + +#: utils/misc/guc.c:8485 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "doit être super-utilisateur pour exécuter la commande ALTER SYSTEM" + +#: utils/misc/guc.c:8566 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "la valeur du paramètre pour ALTER SYSTEM ne doit pas contenir de caractère de retour à la ligne" + +#: utils/misc/guc.c:8611 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "n'a pas pu analyser le contenu du fichier « %s »" + +#: utils/misc/guc.c:8768 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT n'est pas implémenté" + +#: utils/misc/guc.c:8852 +#, c-format +msgid "SET requires parameter name" +msgstr "SET requiert le nom du paramètre" + +#: utils/misc/guc.c:8985 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "tentative de redéfinition du paramètre « %s »" + +#: utils/misc/guc.c:10780 +#, c-format +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "lors de la configuration du paramètre « %s » en « %s »" + +#: utils/misc/guc.c:10945 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "le paramètre « %s » n'a pas pu être configuré" + +#: utils/misc/guc.c:11037 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "n'a pas pu analyser la configuration du paramètre « %s »" + +#: utils/misc/guc.c:11395 utils/misc/guc.c:11429 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "valeur invalide pour le paramètre « %s » : %d" + +#: utils/misc/guc.c:11463 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "valeur invalide pour le paramètre « %s » : %g" + +#: utils/misc/guc.c:11750 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "« temp_buffers » ne peut pas être modifié après que des tables temporaires aient été utilisées dans la session." + +#: utils/misc/guc.c:11762 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour n'est pas supporté dans cette installation" + +#: utils/misc/guc.c:11775 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL n'est pas supporté dans cette installation" + +#: utils/misc/guc.c:11787 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "Ne peut pas activer le paramètre avec « log_statement_stats » à true." + +#: utils/misc/guc.c:11799 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "" +"Ne peut pas activer « log_statement_stats » lorsque « log_parser_stats »,\n" +"« log_planner_stats » ou « log_executor_stats » est true." + +#: utils/misc/guc.c:12029 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "effective_io_concurrency doit être positionné à 0 sur les plateformes où manque posix_fadvise()" + +#: utils/misc/guc.c:12042 +#, c-format +msgid "maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "maintenance_io_concurrency doit être positionné à 0 sur les plateformes où manque posix_fadvise()" + +#: utils/misc/guc.c:12056 +#, c-format +msgid "huge_page_size must be 0 on this platform." +msgstr "huge_page_size doit valoir 0 sur cette plateforme" + +#: utils/misc/guc.c:12070 +#, c-format +msgid "client_connection_check_interval must be set to 0 on platforms that lack POLLRDHUP." +msgstr "client_connection_check_interval doit être positionné à 0 sur les plateformes où POLLRDHUP manque" + +#: utils/misc/guc.c:12198 +#, c-format +msgid "invalid character" +msgstr "caractère invalide" + +#: utils/misc/guc.c:12258 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline n'est pas un nombre valide ." + +#: utils/misc/guc.c:12298 +#, c-format +msgid "multiple recovery targets specified" +msgstr "multiples cibles de restauration spécifiées" + +#: utils/misc/guc.c:12299 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr "Une seule valeur peut être spécifiée, parmi recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid." + +#: utils/misc/guc.c:12307 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "La seule valeur autorisée est « immediate »." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "erreur interne : type de paramètre d'exécution non reconnu\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "une ligne de sortie spécifiée à la requête et un type de sortie de fonction ne sont pas compatibles" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "la somme de contrôle CRC calculée ne correspond par à la valeur enregistrée dans le fichier" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU : utilisateur : %d.%02d s, système : %d.%02d s, temps passé : %d.%02d s" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "la requête pourrait être affectée par une politique de sécurité au niveau ligne pour la table « %s »" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "Pour désactiver la politique pour le propriétaire de la table, utilisez ALTER TABLE NO FORCE ROW LEVEL SECURITY." + +#: utils/misc/timeout.c:484 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "ne peut pas ajouter plus de raisons de timeout" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "" +"l'abréviation « %s » du fuseau horaire est trop long (maximum %d caractères)\n" +"dans le fichier de fuseaux horaires « %s », ligne %d" + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "" +"le décalage %d du fuseau horaire est en dehors des limites dans le fichier\n" +"des fuseaux horaires « %s », ligne %d" + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "abréviation du fuseau horaire manquant dans le fichier « %s », ligne %d" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "décalage du fuseau horaire manquant dans le fichier « %s », ligne %d" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "" +"nombre invalide pour le décalage du fuseau horaire dans le fichier des\n" +"fuseaux horaires « %s », ligne %d" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "syntaxe invalide dans le fichier des fuseaux horaires « %s », ligne %d" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "l'abréviation « %s » du fuseau horaire est définie plusieurs fois" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "" +"L'entrée dans le fichier des fuseaux horaires « %s », ligne %d, est en\n" +"conflit avec l'entrée du fichier « %s », ligne %d." + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "nom du fichier de fuseaux horaires invalide : « %s »" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "" +"limite de récursion dépassée dans le fichier « %s » (fichier des fuseaux\n" +"horaires)" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "n'a pas pu lire le fichier des fuseaux horaires « %s » : %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "" +"une ligne est trop longue dans le fichier des fuseaux horaires « %s »,\n" +"ligne %d" + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "@INCLUDE sans nom de fichier dans le fichier des fuseaux horaires « %s », ligne %d" + +#: utils/mmgr/aset.c:477 utils/mmgr/generation.c:235 utils/mmgr/slab.c:237 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Échec lors de la création du contexte mémoire « %s »." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1329 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "n'a pas pu attacher le segment de mémoire partagée dynamique" + +#: utils/mmgr/mcxt.c:889 utils/mmgr/mcxt.c:925 utils/mmgr/mcxt.c:963 utils/mmgr/mcxt.c:1001 utils/mmgr/mcxt.c:1083 utils/mmgr/mcxt.c:1114 utils/mmgr/mcxt.c:1150 utils/mmgr/mcxt.c:1202 utils/mmgr/mcxt.c:1237 utils/mmgr/mcxt.c:1272 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Échec d'une requête de taille %zu dans le contexte mémoire « %s »." + +#: utils/mmgr/mcxt.c:1046 +#, c-format +msgid "logging memory contexts of PID %d" +msgstr "" + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "le curseur « %s » existe déjà" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "fermeture du curseur existant « %s »" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "le portail « %s » ne peut pas être exécuté de nouveau" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "ne peut pas supprimer le portail épinglé « %s »" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "ne peut pas supprimer le portail actif « %s »" + +#: utils/mmgr/portalmem.c:736 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "ne peut pas préparer une transaction qui a créé un curseur WITH HOLD" + +#: utils/mmgr/portalmem.c:1275 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "ne peut pas effectuer de commandes de transaction dans une boucle de curseur qui n'est pas en lecture seule" + +#: utils/sort/logtape.c:268 utils/sort/logtape.c:291 +#, c-format +msgid "could not seek to block %ld of temporary file" +msgstr "n'a pas pu se positionner sur le bloc %ld du fichier temporaire" + +#: utils/sort/logtape.c:297 +#, c-format +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "n'a pas pu lire le bloc %ld du fichier temporaire : a lu seulement %zu octets sur %zu" + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "n'a pas pu lire le fichier temporaire tuplestore partagé : %m" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "tronçon non attendu dans le fichier temporaire tuplestore partagé" + +#: utils/sort/sharedtuplestore.c:569 +#, c-format +msgid "could not seek to block %u in shared tuplestore temporary file" +msgstr "n'a pas pu lire le bloc %u dans le fichier temporaire tuplestore partagé" + +#: utils/sort/sharedtuplestore.c:576 +#, c-format +msgid "could not read from shared tuplestore temporary file: read only %zu of %zu bytes" +msgstr "n'a pas pu lire le fichier temporaire tuplestore partagé : a lu seulement %zu octets sur %zu" + +#: utils/sort/tuplesort.c:3216 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "ne peut pas avoir plus de %d exécutions pour un tri externe" + +#: utils/sort/tuplesort.c:4297 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "n'a pas pu créer l'index unique « %s »" + +#: utils/sort/tuplesort.c:4299 +#, c-format +msgid "Key %s is duplicated." +msgstr "La clé %s est dupliquée." + +#: utils/sort/tuplesort.c:4300 +#, c-format +msgid "Duplicate keys exist." +msgstr "Des clés dupliquées existent." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "n'a pas pu se déplacer dans le fichier temporaire tuplestore" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 utils/sort/tuplestore.c:1548 +#, c-format +msgid "could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "n'a pas pu lire le fichier temporaire tuplestore : a lu seulement %zu octets sur %zu" + +#: utils/time/snapmgr.c:568 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "La transaction source n'est plus en cours d'exécution." + +#: utils/time/snapmgr.c:1147 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "ne peut pas exporter un snapshot dans un sous-transaction" + +#: utils/time/snapmgr.c:1306 utils/time/snapmgr.c:1311 utils/time/snapmgr.c:1316 utils/time/snapmgr.c:1331 utils/time/snapmgr.c:1336 utils/time/snapmgr.c:1341 utils/time/snapmgr.c:1356 utils/time/snapmgr.c:1361 utils/time/snapmgr.c:1366 utils/time/snapmgr.c:1468 utils/time/snapmgr.c:1484 utils/time/snapmgr.c:1509 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "données invalides du snapshot dans le fichier « %s »" + +#: utils/time/snapmgr.c:1403 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "SET TRANSACTION SNAPSHOT doit être appelé avant toute requête" + +#: utils/time/snapmgr.c:1412 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "une transaction important un snapshot doit avoir le niveau d'isolation SERIALIZABLE ou REPEATABLE READ" + +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1430 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "identifiant invalide du snapshot : « %s »" + +#: utils/time/snapmgr.c:1522 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "une transaction sérialisable ne peut pas importer un snapshot provenant d'une transaction non sérialisable" + +#: utils/time/snapmgr.c:1526 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "une transaction sérialisable en écriture ne peut pas importer un snapshot provenant d'une transaction en lecture seule" + +#: utils/time/snapmgr.c:1541 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "ne peut pas importer un snapshot à partir d'une base de données différente" + +#~ msgid "only simple column references and expressions are allowed in CREATE STATISTICS" +#~ msgstr "seules des références et expressions à une seule colonne sont acceptées dans CREATE STATISTICS" + +#~ msgid "ORIGIN message sent out of order" +#~ msgstr "message ORIGIN en désordre" + +#~ msgid "invalid logical replication message type \"%c\"" +#~ msgstr "type de message « %c » de la réplication logique invalide" + +#~ msgid "there is no contrecord flag at %X/%X reading %X/%X" +#~ msgstr "il n'existe pas de drapeau contrecord à %X/%X en lisant %X/%X" + +#~ msgid "invalid contrecord length %u at %X/%X reading %X/%X, expected %u" +#~ msgstr "longueur %u invalide du contrecord à %X/%X en lisant %X/%X, attendait %u" + +#~ msgid "Connections and Authentication" +#~ msgstr "Connexions et authentification" + +#~ msgid "Resource Usage" +#~ msgstr "Utilisation des ressources" + +#~ msgid "Write-Ahead Log" +#~ msgstr "Write-Ahead Log" + +#~ msgid "Replication" +#~ msgstr "Réplication" + +#~ msgid "Query Tuning" +#~ msgstr "Optimisation des requêtes" + +#~ msgid "Reporting and Logging" +#~ msgstr "Rapports et traces" + +#~ msgid "Process Title" +#~ msgstr "Titre du processus" + +#~ msgid "Statistics" +#~ msgstr "Statistiques" + +#~ msgid "Client Connection Defaults" +#~ msgstr "Valeurs par défaut pour les connexions client" + +#~ msgid "Version and Platform Compatibility" +#~ msgstr "Compatibilité des versions et des plateformes" + +#~ msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +#~ msgstr "" +#~ "Pour les systèmes RAID, cela devrait être approximativement le nombre de\n" +#~ "têtes de lecture du système." + +#~ msgid "GSSAPI encryption can only be used with gss, trust, or reject authentication methods" +#~ msgstr "le chiffrement GSSAPI ne peut être utilisé qu'avec les méthodes d'authentification gss, trust ou reject" + +#~ msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +#~ msgstr "" +#~ "pg_hba.conf rejette la connexion de la réplication pour l'hôte « %s »,\n" +#~ "utilisateur « %s »" + +#~ msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +#~ msgstr "" +#~ "pg_hba.conf rejette la connexion pour l'hôte « %s », utilisateur « %s », base\n" +#~ "de données « %s »" + +#~ msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +#~ msgstr "" +#~ "aucune entrée dans pg_hba.conf pour la connexion de la réplication à partir de\n" +#~ "l'hôte « %s », utilisateur « %s »" + +#~ msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +#~ msgstr "" +#~ "aucune entrée dans pg_hba.conf pour l'hôte « %s », utilisateur « %s »,\n" +#~ "base de données « %s »" + +#~ msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +#~ msgstr "le chiffrement GSSAPI ne supporte que l'authentification gss, trust ou reject" + +#~ msgid "unexpected standby message type \"%c\", after receiving CopyDone" +#~ msgstr "type de message standby « %c » inattendu, après avoir reçu CopyDone" + +#~ msgid "invalid concatenation of jsonb objects" +#~ msgstr "concaténation invalide d'objets jsonb" + +#~ msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "connexion de réplication autorisée : utilisateur=%s, nom d'application=%s, SSL activé (protocole=%s, chiffrement=%s, bits=%d, compression=%s)" + +#~ msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "connexion autorisée : utilisateur=%s, SSL activé (protocole=%s, chiffrement=%s, bits=%d, compression=%s)" + +#~ msgid "replication connection authorized: user=%s application_name=%s" +#~ msgstr "connexion de réplication autorisée : utilisateur=%s nom d'application=%s" + +#~ msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "connexion autorisée : utilisateur=%s base de données=%s nom d'application=%s SSL activé (protocole=%s, chiffrement=%s, bits=%d, compression=%s)" + +#~ msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "connexion autorisée : utilisateur=%s, base de données=%s, SSL activé (protocole=%s, chiffrement=%s, bits=%d, compression=%s)" + +#~ msgid "connection authorized: user=%s database=%s application_name=%s" +#~ msgstr "connexion autorisée : utilisateur=%s base de données=%s nom d'application=%s" + +#~ msgid "connection authorized: user=%s database=%s" +#~ msgstr "connexion autorisée : utilisateur=%s, base de données=%s" + +#~ msgid "cannot create restricted tokens on this platform" +#~ msgstr "ne peut pas créer les jetons restreints sur cette plateforme" + +#~ msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +#~ msgstr "reste d'espace de ligne réservé dans l'index BRIN « %s », suppression" + +#~ msgid "invalid value for \"buffering\" option" +#~ msgstr "valeur invalide pour l'option « buffering »" + +#~ msgid "could not write block %ld of temporary file: %m" +#~ msgstr "n'a pas pu écrire le bloc %ld du fichier temporaire : %m" + +#~ msgid "skipping redundant vacuum to prevent wraparound of table \"%s.%s.%s\"" +#~ msgstr "ignore un VACUUM redondant pour éviter le rebouclage des identifiants dans la table \"%s.%s.%s\"" + +#~ msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." +#~ msgstr "" +#~ "Le cluster de base de données a été initialisé sans USE_FLOAT4_BYVAL\n" +#~ "alors que le serveur a été compilé avec USE_FLOAT4_BYVAL." + +#~ msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." +#~ msgstr "" +#~ "Le cluster de base de données a été initialisé avec USE_FLOAT4_BYVAL\n" +#~ "alors que le serveur a été compilé sans USE_FLOAT4_BYVAL." + +#~ msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +#~ msgstr "le fichier WAL provient d'une instance différente : l'identifiant système de la base dans le fichier WAL est %s, alors que l'identifiant système de l'instance dans pg_control est %s" + +#~ msgid "could not seek in log segment %s to offset %u: %m" +#~ msgstr "n'a pas pu se déplacer dans le journal de transactions %s au décalage %u : %m" + +#~ msgid "could not read from log segment %s, offset %u, length %lu: %m" +#~ msgstr "n'a pas pu lire le journal de transactions %s, décalage %u, longueur %lu : %m" + +#~ msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." +#~ msgstr "Un agrégat utilisant un type de transition polymorphique doit avoir au moins un argument polymorphique." + +#~ msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." +#~ msgstr "Un agrégat renvoyant un type polymorphique doit avoir au moins un argument de type polymorphique." + +#~ msgid "A function returning \"internal\" must have at least one \"internal\" argument." +#~ msgstr "Une fonction renvoyant « internal » doit avoir au moins un argument du type « internal »." + +#~ msgid "A function returning a polymorphic type must have at least one polymorphic argument." +#~ msgstr "Une fonction renvoyant un type polymorphique doit avoir au moins un argument de type polymorphique." + +#~ msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." +#~ msgstr "Une fonction renvoyant « anyrange » doit avoir au moins un argument du type « anyrange »." + +#~ msgid "Adding partitioned tables to publications is not supported." +#~ msgstr "Ajouter des tables partitionnées à des publications n'est pas supporté." + +#~ msgid "You can add the table partitions individually." +#~ msgstr "Vous pouvez ajouter les partitions de table individuellement." + +#~ msgid "EXPLAIN option BUFFERS requires ANALYZE" +#~ msgstr "l'option BUFFERS d'EXPLAIN nécessite ANALYZE" + +#~ msgid "FROM version must be different from installation target version \"%s\"" +#~ msgstr "la version FROM doit être différente de la version cible d'installation « %s »" + +#~ msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" +#~ msgstr "" +#~ "utilisation des informations de pg_pltemplate au lieu des paramètres de\n" +#~ "CREATE LANGUAGE" + +#~ msgid "must be superuser to create procedural language \"%s\"" +#~ msgstr "doit être super-utilisateur pour créer le langage de procédures « %s »" + +#~ msgid "unsupported language \"%s\"" +#~ msgstr "langage non supporté « %s »" + +#~ msgid "The supported languages are listed in the pg_pltemplate system catalog." +#~ msgstr "Les langages supportés sont listés dans le catalogue système pg_pltemplate." + +#~ msgid "changing return type of function %s from %s to %s" +#~ msgstr "changement du type de retour de la fonction %s de %s vers %s" + +#~ msgid "column \"%s\" contains null values" +#~ msgstr "la colonne « %s » contient des valeurs NULL" + +#~ msgid "updated partition constraint for default partition would be violated by some row" +#~ msgstr "la contrainte de partition mise à jour pour la partition par défaut serait transgressée par des lignes" + +#~ msgid "partition key expressions cannot contain whole-row references" +#~ msgstr "les expressions de clé de partitionnement ne peuvent pas contenir des références à des lignes complètes" + +#~ msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +#~ msgstr "Les tables partitionnées ne peuvent pas avoir de triggers BEFORE / FOR EACH ROW." + +#~ msgid "Found referenced table's UPDATE trigger." +#~ msgstr "Trigger UPDATE de la table référencée trouvé." + +#~ msgid "Found referenced table's DELETE trigger." +#~ msgstr "Trigger DELETE de la table référencée trouvé." + +#~ msgid "Found referencing table's trigger." +#~ msgstr "Trigger de la table référencée trouvé." + +#~ msgid "ignoring incomplete trigger group for constraint \"%s\" %s" +#~ msgstr "ignore le groupe de trigger incomplet pour la contrainte « %s » %s" + +#~ msgid "converting trigger group into constraint \"%s\" %s" +#~ msgstr "conversion du groupe de trigger en une contrainte « %s » %s" + +#~ msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" +#~ msgstr "changement du type d'argument de la fonction %s d'« opaque » à « cstring »" + +#~ msgid "changing argument type of function %s from \"opaque\" to %s" +#~ msgstr "changement du type d'argument de la fonction %s d'« opaque » à %s" + +#~ msgid "invalid value for \"check_option\" option" +#~ msgstr "valeur invalide pour l'option « check_option »" + +#~ msgid "\"%s.%s\" is a partitioned table." +#~ msgstr "« %s.%s » est une table partitionnée." + +#~ msgid "could not determine actual result type for function declared to return type %s" +#~ msgstr "" +#~ "n'a pas pu déterminer le type du résultat actuel pour la fonction déclarant\n" +#~ "renvoyer le type %s" + +#~ msgid "could not write to hash-join temporary file: %m" +#~ msgstr "n'a pas pu écrire le fichier temporaire de la jointure hâchée : %m" + +#~ msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." +#~ msgstr "" +#~ "Les valeurs d'échappement unicode ne peuvent pas être utilisées pour les valeurs de point de code\n" +#~ "au-dessus de 007F quand l'encodage serveur n'est pas UTF8." + +#~ msgid "could not load wldap32.dll" +#~ msgstr "n'a pas pu charger wldap32.dll" + +#~ msgid "SSL certificate revocation list file \"%s\" ignored" +#~ msgstr "liste de révocation des certificats SSL « %s » ignorée" + +#~ msgid "SSL library does not support certificate revocation lists." +#~ msgstr "La bibliothèque SSL ne supporte pas les listes de révocation des certificats." + +#~ msgid "could not create signal dispatch thread: error code %lu\n" +#~ msgstr "n'a pas pu créer le thread de répartition des signaux : code d'erreur %lu\n" + +#~ msgid "Please report this to ." +#~ msgstr "Veuillez rapporter ceci à ." + +#~ msgid "replication origin %d is already active for PID %d" +#~ msgstr "l'origine de réplication %d est déjà active pour le PID %d" + +#~ msgid "cannot advance replication slot that has not previously reserved WAL" +#~ msgstr "impossible d'avancer un slot de réplication qui n'a pas auparavant réservé de WAL" + +#~ msgid "could not read from log segment %s, offset %u, length %zu: %m" +#~ msgstr "n'a pas pu lire le segment %s du journal de transactions, décalage %u, longueur %zu : %m" + +#~ msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" +#~ msgstr "" +#~ "Les valeurs d'échappement unicode ne peuvent pas être utilisées pour les\n" +#~ "valeurs de point de code au-dessus de 007F quand l'encodage serveur n'est\n" +#~ "pas UTF8" + +#~ msgid "cannot use advisory locks during a parallel operation" +#~ msgstr "ne peut pas utiliser les verrous informatifs lors d'une opération parallèle" + +#~ msgid "cannot output a value of type %s" +#~ msgstr "ne peut pas afficher une valeur de type %s" + +#~ msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." +#~ msgstr "Le serveur a FLOAT4PASSBYVAL = %s, la bibliothèque a %s." + +#~ msgid "encoding name too long" +#~ msgstr "nom d'encodage trop long" + +#~ msgid "Encrypt passwords." +#~ msgstr "Chiffre les mots de passe." + +#~ msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +#~ msgstr "" +#~ "Lorsqu'un mot de passe est spécifié dans CREATE USER ou ALTER USER sans\n" +#~ "indiquer ENCRYPTED ou UNENCRYPTED, ce paramètre détermine si le mot de passe\n" +#~ "doit être chiffré." + +#~ msgid "could not write to temporary file: %m" +#~ msgstr "n'a pas pu écrire dans le fichier temporaire : %m" + +#~ msgid "could not write to tuplestore temporary file: %m" +#~ msgstr "n'a pas pu écrire le fichier temporaire tuplestore : %m" + +#~ msgid "cannot PREPARE a transaction that has operated on temporary namespace" +#~ msgstr "" +#~ "ne peut pas préparer (PREPARE) une transaction qui a travaillé sur un\n" +#~ "schéma temporaire" + +#~ msgid "view must have at least one column" +#~ msgstr "la vue doit avoir au moins une colonne" + +#~ msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." +#~ msgstr "" +#~ "Si vous êtes sûr qu'aucun processus serveur n'est toujours en cours\n" +#~ "d'exécution, supprimez le bloc de mémoire partagée\n" +#~ "ou supprimez simplement le fichier « %s »." + +#~ msgid "foreign key referencing partitioned table \"%s\" must not be ONLY" +#~ msgstr "la clé étrangère référençant la table partitionnée « %s » ne doit pas être ONLY" + +#~ msgid "invalid number of arguments: object must be matched key value pairs" +#~ msgstr "nombre d'arguments invalide : l'objet doit correspond aux paires clé/valeur" + +#~ msgid "" +#~ "WARNING: Calculated CRC checksum does not match value stored in file.\n" +#~ "Either the file is corrupt, or it has a different layout than this program\n" +#~ "is expecting. The results below are untrustworthy.\n" +#~ "\n" +#~ msgstr "" +#~ "ATTENTION : Les sommes de contrôle (CRC) calculées ne correspondent pas aux\n" +#~ "valeurs stockées dans le fichier.\n" +#~ "Soit le fichier est corrompu, soit son organisation diffère de celle\n" +#~ "attendue par le programme.\n" +#~ "Les résultats ci-dessous ne sont pas dignes de confiance.\n" +#~ "\n" + +#~ msgid "index row size %lu exceeds maximum %lu for index \"%s\"" +#~ msgstr "la taille de la ligne index, %lu, dépasse le maximum, %lu, pour l'index « %s »" + +#~ msgid "brin operator family \"%s\" contains function %s with invalid support number %d" +#~ msgstr "" +#~ "la famille d'opérateur brin « %s » contient la fonction %s\n" +#~ "avec le numéro de support %d invalide" + +#~ msgid "brin operator family \"%s\" contains function %s with wrong signature for support number %d" +#~ msgstr "" +#~ "la famille d'opérateur brin « %s » contient la fonction %s\n" +#~ "avec une mauvaise signature pour le numéro de support %d" + +#~ msgid "brin operator family \"%s\" contains operator %s with invalid strategy number %d" +#~ msgstr "" +#~ "la famille d'opérateur brin « %s » contient l'opérateur %s\n" +#~ "avec le numéro de stratégie %d invalide" + +#~ msgid "brin operator family \"%s\" contains invalid ORDER BY specification for operator %s" +#~ msgstr "" +#~ "la famille d'opérateur brin « %s » contient une spécification\n" +#~ "ORDER BY invalide pour l'opérateur %s" + +#~ msgid "brin operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "la famille d'opérateur brin « %s » contient l'opérateur %s avec une mauvaise signature" + +#~ msgid "gist operator family \"%s\" contains support procedure %s with cross-type registration" +#~ msgstr "" +#~ "la famille d'opérateur gist « %s » contient la procédure de support\n" +#~ "%s avec un enregistrement inter-type" + +#~ msgid "gist operator family \"%s\" contains function %s with invalid support number %d" +#~ msgstr "" +#~ "la famille d'opérateur gist « %s » contient la fonction %s avec\n" +#~ "le numéro de support invalide %d" + +#~ msgid "gist operator family \"%s\" contains function %s with wrong signature for support number %d" +#~ msgstr "" +#~ "la famille d'opérateur gist « %s » contient la fonction %s avec une mauvaise\n" +#~ "signature pour le numéro de support %d" + +#~ msgid "gist operator family \"%s\" contains operator %s with invalid strategy number %d" +#~ msgstr "" +#~ "la famille d'opérateur gist « %s » contient l'opérateur %s avec le numéro\n" +#~ "de stratégie invalide %d" + +#~ msgid "gist operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "la famille d'opérateur gist « %s » contient l'opérateur %s avec une mauvaise signature" + +#~ msgid "hash operator family \"%s\" contains support procedure %s with cross-type registration" +#~ msgstr "" +#~ "la famille d'opérateur hash « %s » contient la procédure de support\n" +#~ "%s avec un enregistrement inter-type" + +#~ msgid "hash operator family \"%s\" contains function %s with wrong signature for support number %d" +#~ msgstr "" +#~ "la famille d'opérateur hash « %s » contient la fonction %s avec une mauvaise\n" +#~ "signature pour le numéro de support %d" + +#~ msgid "hash operator family \"%s\" contains function %s with invalid support number %d" +#~ msgstr "" +#~ "la famille d'opérateur hash « %s » contient la fonction %s avec\n" +#~ "le numéro de support invalide %d" + +#~ msgid "hash operator family \"%s\" contains operator %s with invalid strategy number %d" +#~ msgstr "" +#~ "la famille d'opérateur hash « %s » contient l'opérateur %s avec le numéro\n" +#~ "de stratégie invalide %d" + +#~ msgid "hash operator family \"%s\" contains invalid ORDER BY specification for operator %s" +#~ msgstr "" +#~ "la famille d'opérateur hash « %s » contient la spécification ORDER BY\n" +#~ "non supportée pour l'opérateur %s" + +#~ msgid "hash operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "la famille d'opérateur hash « %s » contient l'opérateur %s avec une mauvaise signature" + +#~ msgid "hash operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "la famille d'opérateur hash « %s » nécessite des opérateurs supplémentaires\n" +#~ "pour les types %s et %s" + +#~ msgid "hash operator class \"%s\" is missing operator(s)" +#~ msgstr "il manque des opérateurs pour la classe d'opérateur hash « %s »" + +#~ msgid "btree operator family \"%s\" contains function %s with invalid support number %d" +#~ msgstr "" +#~ "la famille d'opérateur btree « %s » contient la fonction %s\n" +#~ "avec le numéro de support invalide %d" + +#~ msgid "btree operator family \"%s\" contains function %s with wrong signature for support number %d" +#~ msgstr "" +#~ "la famille d'opérateur btree « %s » contient la fonction %s\n" +#~ "avec une mauvaise signature pour le numéro de support %d" + +#~ msgid "btree operator family \"%s\" contains operator %s with invalid strategy number %d" +#~ msgstr "" +#~ "la famille d'opérateur btree « %s » contient l'opérateur %s\n" +#~ "avec le numéro de stratégie invalide %d" + +#~ msgid "btree operator family \"%s\" contains invalid ORDER BY specification for operator %s" +#~ msgstr "" +#~ "la famille d'opérateur btree « %s » contient une spécification\n" +#~ "ORDER BY invalide pour l'opérateur %s" + +#~ msgid "btree operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "la famille d'opérateur btree « %s » contient l'opérateur %s avec une mauvaise signature" + +#~ msgid "btree operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "la famille d'opérateur btree « %s » nécessite des opérateurs supplémentaires\n" +#~ "pour les types %s et %s" + +#~ msgid "btree operator class \"%s\" is missing operator(s)" +#~ msgstr "il manque des opérateurs pour la classe d'opérateur btree « %s »" + +#~ msgid "btree operator family \"%s\" is missing cross-type operator(s)" +#~ msgstr "il manque des opérateurs inter-type pour la famille d'opérateur btree « %s »" + +#~ msgid "spgist operator family \"%s\" contains support procedure %s with cross-type registration" +#~ msgstr "" +#~ "la famille d'opérateur spgist « %s » contient la procédure de support\n" +#~ "%s avec un enregistrement inter-type" + +#~ msgid "spgist operator family \"%s\" contains function %s with invalid support number %d" +#~ msgstr "" +#~ "la famille d'opérateur spgist « %s » contient la fonction %s\n" +#~ "avec le numéro de support %d invalide" + +#~ msgid "spgist operator family \"%s\" contains function %s with wrong signature for support number %d" +#~ msgstr "" +#~ "la famille d'opérateur spgist « %s » contient la fonction %s\n" +#~ "avec une mauvaise signature pour le numéro de support %d" + +#~ msgid "spgist operator family \"%s\" contains operator %s with invalid strategy number %d" +#~ msgstr "" +#~ "la famille d'opérateur spgist « %s » contient l'opérateur %s\n" +#~ "avec le numéro de stratégie invalide %d" + +#~ msgid "spgist operator family \"%s\" contains invalid ORDER BY specification for operator %s" +#~ msgstr "" +#~ "la famille d'opérateur spgist « %s » contient une spécification\n" +#~ "ORDER BY invalide pour l'opérateur %s" + +#~ msgid "spgist operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "la famille d'opérateur spgist « %s » contient l'opérateur %s avec une mauvaise signature" + +#~ msgid "spgist operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "la famille d'opérateur spgist « %s » nécessite des opérateurs supplémentaires\n" +#~ "pour les types %s et %s" + +#~ msgid "spgist operator class \"%s\" is missing operator(s)" +#~ msgstr "il manque des opérateurs pour la classe d'opérateur spgist « %s »" + +#~ msgid "Expected a transaction log switchpoint location." +#~ msgstr "Attendait un emplacement de bascule dans le journal de transactions." + +#~ msgid "could not remove old transaction log file \"%s\": %m" +#~ msgstr "n'a pas pu supprimer l'ancien journal de transaction « %s » : %m" + +#~ msgid "removing transaction log backup history file \"%s\"" +#~ msgstr "suppression du fichier historique des journaux de transaction « %s »" + +#~ msgid "The database cluster was initialized without HAVE_INT64_TIMESTAMP but the server was compiled with HAVE_INT64_TIMESTAMP." +#~ msgstr "Le cluster de bases de données a été initialisé sans HAVE_INT64_TIMESTAMPalors que le serveur a été compilé avec." + +#~ msgid "The database cluster was initialized with HAVE_INT64_TIMESTAMP but the server was compiled without HAVE_INT64_TIMESTAMP." +#~ msgstr "" +#~ "Le cluster de bases de données a été initialisé avec HAVE_INT64_TIMESTAMP\n" +#~ "alors que le serveur a été compilé sans." + +#~ msgid "invalid privilege type USAGE for table" +#~ msgstr "droit USAGE invalide pour la table" + +#~ msgid "column \"%s\" has type \"unknown\"" +#~ msgstr "la colonne « %s » est de type « unknown »" + +#~ msgid "Proceeding with relation creation anyway." +#~ msgstr "Poursuit malgré tout la création de la relation." + +#~ msgid "default expression must not return a set" +#~ msgstr "l'expression par défaut ne doit pas renvoyer un ensemble" + +#~ msgid "access method name cannot be qualified" +#~ msgstr "le nom de la méthode d'accès ne peut pas être qualifiée" + +#~ msgid "database name cannot be qualified" +#~ msgstr "le nom de la base de donnée ne peut être qualifié" + +#~ msgid "extension name cannot be qualified" +#~ msgstr "le nom de l'extension ne peut pas être qualifié" + +#~ msgid "tablespace name cannot be qualified" +#~ msgstr "le nom du tablespace ne peut pas être qualifié" + +#~ msgid "role name cannot be qualified" +#~ msgstr "le nom du rôle ne peut pas être qualifié" + +#~ msgid "schema name cannot be qualified" +#~ msgstr "le nom du schéma ne peut pas être qualifié" + +#~ msgid "language name cannot be qualified" +#~ msgstr "le nom du langage ne peut pas être qualifié" + +#~ msgid "foreign-data wrapper name cannot be qualified" +#~ msgstr "le nom du wrapper de données distantes ne peut pas être qualifié" + +#~ msgid "server name cannot be qualified" +#~ msgstr "le nom du serveur ne peut pas être qualifié" + +#~ msgid "event trigger name cannot be qualified" +#~ msgstr "le nom du trigger sur événement ne peut pas être qualifié" + +#~ msgid "hash indexes are not WAL-logged and their use is discouraged" +#~ msgstr "les index hash ne sont pas journalisés, leur utilisation est donc déconseillée" + +#~ msgid "changing return type of function %s from \"opaque\" to \"language_handler\"" +#~ msgstr "" +#~ "changement du type du code retour de la fonction %s d'« opaque » à\n" +#~ "« language_handler »" + +#~ msgid "changing return type of function %s from \"opaque\" to \"trigger\"" +#~ msgstr "changement du type de retour de la fonction %s de « opaque » vers « trigger »" + +#~ msgid "functions and operators can take at most one set argument" +#~ msgstr "les fonctions et opérateurs peuvent prendre au plus un argument d'ensemble" + +#~ msgid "IS DISTINCT FROM does not support set arguments" +#~ msgstr "IS DISTINCT FROM ne supporte pas les arguments d'ensemble" + +#~ msgid "op ANY/ALL (array) does not support set arguments" +#~ msgstr "" +#~ "l'opérateur ANY/ALL (pour les types array) ne supporte pas les arguments\n" +#~ "d'ensemble" + +#~ msgid "NULLIF does not support set arguments" +#~ msgstr "NULLIF ne supporte pas les arguments d'ensemble" + +#~ msgid "hostssl requires SSL to be turned on" +#~ msgstr "hostssl requiert que SSL soit activé" + +#~ msgid "could not create %s socket: %m" +#~ msgstr "n'a pas pu créer le socket %s : %m" + +#~ msgid "WHERE CURRENT OF is not supported on a view with no underlying relation" +#~ msgstr "WHERE CURRENT OF n'est pas supporté pour une vue sans table sous-jacente" + +#~ msgid "WHERE CURRENT OF is not supported on a view with more than one underlying relation" +#~ msgstr "WHERE CURRENT OF n'est pas supporté pour une vue avec plus d'une table sous-jacente" + +#~ msgid "WHERE CURRENT OF is not supported on a view with grouping or aggregation" +#~ msgstr "WHERE CURRENT OF n'est pas supporté pour une vue avec regroupement ou agrégat" + +#~ msgid "DEFAULT can only appear in a VALUES list within INSERT" +#~ msgstr "DEFAULT peut seulement apparaître dans la liste VALUES comprise dans un INSERT" + +#~ msgid "argument of %s must be type boolean, not type %s" +#~ msgstr "l'argument de %s doit être de type booléen, et non du type %s" + +#~ msgid "argument declared \"anyrange\" is not consistent with argument declared \"anyelement\"" +#~ msgstr "" +#~ "l'argument déclaré « anyrange » n'est pas cohérent avec l'argument déclaré\n" +#~ "« anyelement »" + +#~ msgid "index expression cannot return a set" +#~ msgstr "l'expression de l'index ne peut pas renvoyer un ensemble" + +#~ msgid "transform expression must not return a set" +#~ msgstr "l'expression de transformation ne doit pas renvoyer un ensemble" + +#~ msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" +#~ msgstr "" +#~ "autovacuum : a trouvé la table temporaire orpheline « %s.%s » dans la base de\n" +#~ "données « %s »" + +#~ msgid "transaction log switch forced (archive_timeout=%d)" +#~ msgstr "changement forcé du journal de transaction (archive_timeout=%d)" + +#~ msgid "archived transaction log file \"%s\"" +#~ msgstr "journal des transactions archivé « %s »" + +#~ msgid "syntax error: unexpected character \"%s\"" +#~ msgstr "erreur de syntaxe : caractère « %s » inattendu" + +#~ msgid "invalid socket: %s" +#~ msgstr "socket invalide : %s" + +#~ msgid "select() failed: %m" +#~ msgstr "échec de select() : %m" + +#~ msgid "Transaction ID %u finished; no more running transactions." +#~ msgstr "Identifiant de transaction %u terminé ; plus de transactions en cours." + +#~ msgid "%u transaction needs to finish." +#~ msgid_plural "%u transactions need to finish." +#~ msgstr[0] "La transaction %u doit se terminer." +#~ msgstr[1] "Les transactions %u doivent se terminer." + +#~ msgid "rule \"%s\" does not exist" +#~ msgstr "la règle « %s » n'existe pas" + +#~ msgid "there are multiple rules named \"%s\"" +#~ msgstr "il existe de nombreuses règles nommées « %s »" + +#~ msgid "Specify a relation name as well as a rule name." +#~ msgstr "Spécifier un nom de relation ainsi qu'un nom de règle." + +#~ msgid "not enough shared memory for elements of data structure \"%s\" (%zu bytes requested)" +#~ msgstr "" +#~ "pas assez de mémoire partagée pour les éléments de la structure de données\n" +#~ "« %s » (%zu octets demandés)" + +#~ msgid "invalid input syntax for type boolean: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type booléen : « %s »" + +#~ msgid "invalid input syntax for type money: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type money : « %s »" + +#~ msgid "invalid input syntax for type bytea" +#~ msgstr "syntaxe en entrée invalide pour le type bytea" + +#~ msgid "invalid input syntax for type real: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type real : « %s »" + +#~ msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" +#~ msgstr "les motifs de format « TZ »/« tz »/« OF » ne sont pas supportés dans to_date" + +#~ msgid "value \"%s\" is out of range for type bigint" +#~ msgstr "la valeur « %s » est en dehors des limites du type bigint" + +#~ msgid "could not determine data type for argument 1" +#~ msgstr "n'a pas pu déterminer le type de données pour l'argument 1" + +#~ msgid "could not determine data type for argument 2" +#~ msgstr "n'a pas pu déterminer le type de données pour l'argument 2" + +#~ msgid "argument %d: could not determine data type" +#~ msgstr "argument %d : n'a pas pu déterminer le type de données" + +#~ msgid "invalid input syntax for type macaddr: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type macaddr : « %s »" + +#~ msgid "invalid input syntax for type tinterval: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type tinterval : « %s »" + +#~ msgid "invalid input syntax for type numeric: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type numeric : « %s »" + +#~ msgid "invalid input syntax for type double precision: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type double precision : « %s »" + +#~ msgid "value \"%s\" is out of range for type integer" +#~ msgstr "la valeur « %s » est en dehors des limites du type integer" + +#~ msgid "value \"%s\" is out of range for type smallint" +#~ msgstr "la valeur « %s » est en dehors des limites du type smallint" + +#~ msgid "invalid input syntax for type oid: \"%s\"" +#~ msgstr "syntaxe invalide en entrée pour le type oid : « %s »" + +#~ msgid "invalid input syntax for type pg_lsn: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type pg_lsn : « %s »" + +#~ msgid "cannot accept a value of type any" +#~ msgstr "ne peut pas accepter une valeur de type any" + +#~ msgid "cannot accept a value of type anyarray" +#~ msgstr "ne peut pas accepter une valeur de type anyarray" + +#~ msgid "cannot accept a value of type anyenum" +#~ msgstr "ne peut pas accepter une valeur de type anyenum" + +#~ msgid "cannot accept a value of type anyrange" +#~ msgstr "ne peut pas accepter une valeur de type anyrange" + +#~ msgid "cannot accept a value of type trigger" +#~ msgstr "ne peut pas accepter une valeur de type trigger" + +#~ msgid "cannot display a value of type trigger" +#~ msgstr "ne peut pas afficher une valeur de type trigger" + +#~ msgid "cannot accept a value of type event_trigger" +#~ msgstr "ne peut pas accepter une valeur de type event_trigger" + +#~ msgid "cannot display a value of type event_trigger" +#~ msgstr "ne peut pas afficher une valeur de type event_trigger" + +#~ msgid "cannot accept a value of type language_handler" +#~ msgstr "ne peut pas accepter une valeur de type language_handler" + +#~ msgid "cannot display a value of type language_handler" +#~ msgstr "ne peut pas afficher une valeur de type language_handler" + +#~ msgid "cannot accept a value of type fdw_handler" +#~ msgstr "ne peut pas accepter une valeur de type fdw_handler" + +#~ msgid "cannot display a value of type fdw_handler" +#~ msgstr "ne peut pas afficher une valeur de type fdw_handler" + +#~ msgid "cannot accept a value of type index_am_handler" +#~ msgstr "ne peut pas accepter une valeur de type index_am_handler" + +#~ msgid "cannot display a value of type index_am_handler" +#~ msgstr "ne peut pas afficher une valeur de type index_am_handler" + +#~ msgid "cannot accept a value of type tsm_handler" +#~ msgstr "ne peut pas accepter une valeur de type tsm_handler" + +#~ msgid "cannot display a value of type tsm_handler" +#~ msgstr "ne peut pas afficher une valeur de type tsm_handler" + +#~ msgid "cannot accept a value of type internal" +#~ msgstr "ne peut pas accepter une valeur de type internal" + +#~ msgid "cannot display a value of type internal" +#~ msgstr "ne peut pas afficher une valeur de type internal" + +#~ msgid "cannot accept a value of type opaque" +#~ msgstr "ne peut pas accepter une valeur de type opaque" + +#~ msgid "cannot display a value of type opaque" +#~ msgstr "ne peut pas afficher une valeur de type opaque" + +#~ msgid "cannot accept a value of type anyelement" +#~ msgstr "ne peut pas accepter une valeur de type anyelement" + +#~ msgid "cannot display a value of type anyelement" +#~ msgstr "ne peut pas afficher une valeur de type anyelement" + +#~ msgid "cannot accept a value of type anynonarray" +#~ msgstr "ne peut pas accepter une valeur de type anynonarray" + +#~ msgid "cannot display a value of type anynonarray" +#~ msgstr "ne peut pas afficher une valeur de type anynonarray" + +#~ msgid "invalid input syntax for type tid: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type tid : « %s »" + +#~ msgid "invalid input syntax for type txid_snapshot: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type txid_snapshot : « %s »" + +#~ msgid "invalid input syntax for uuid: \"%s\"" +#~ msgstr "syntaxe invalide en entrée pour l'uuid : « %s »" + +#~ msgid "function %u has too many arguments (%d, maximum is %d)" +#~ msgstr "la fonction %u a trop d'arguments (%d, le maximum étant %d)" + +#~ msgid "Causes subtables to be included by default in various commands." +#~ msgstr "" +#~ "Fait que les sous-tables soient incluses par défaut dans les différentes\n" +#~ "commandes." + +#~ msgid "could not create two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu créer le fichier de statut de la validation en deux phases nommé\n" +#~ "« %s » : %m" + +#~ msgid "could not seek in two-phase state file: %m" +#~ msgstr "" +#~ "n'a pas pu se déplacer dans le fichier de statut de la validation en deux\n" +#~ "phases : %m" + +#~ msgid "two-phase state file for transaction %u is corrupt" +#~ msgstr "" +#~ "le fichier d'état de la validation en deux phases est corrompu pour la\n" +#~ "transaction %u" + +#~ msgid "could not fsync two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu synchroniser sur disque (fsync) le fichier d'état de la\n" +#~ "validation en deux phases nommé « %s » : %m" + +#~ msgid "could not close two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu fermer le fichier d'état de la validation en deux phases nommé\n" +#~ "« %s » : %m" + +#~ msgid "could not link file \"%s\" to \"%s\" (initialization of log file): %m" +#~ msgstr "n'a pas pu lier le fichier « %s » à « %s » (initialisation du journal de transactions) : %m" + +#~ msgid "could not rename file \"%s\" to \"%s\" (initialization of log file): %m" +#~ msgstr "n'a pas pu renommer le fichier « %s » en « %s » (initialisation du journal de transactions) : %m" + +#~ msgid "ignoring \"%s\" file because no \"%s\" file exists" +#~ msgstr "ignore le fichier « %s » parce que le fichier « %s » n'existe pas" + +#~ msgid "must be superuser or replication role to run a backup" +#~ msgstr "doit être super-utilisateur ou avoir l'attribut de réplication pour exécuter une sauvegarde" + +#~ msgid "must be superuser to switch transaction log files" +#~ msgstr "doit être super-utilisateur pour changer de journal de transactions" + +#~ msgid "must be superuser to create a restore point" +#~ msgstr "doit être super-utilisateur pour créer un point de restauration" + +#~ msgid "must be superuser to control recovery" +#~ msgstr "doit être super-utilisateur pour contrôler la restauration" + +#~ msgid "invalid record length at %X/%X" +#~ msgstr "longueur invalide de l'enregistrement à %X/%X" + +#~ msgid "%s is already in schema \"%s\"" +#~ msgstr "%s existe déjà dans le schéma « %s »" + +#~ msgid "function \"%s\" must return type \"event_trigger\"" +#~ msgstr "la fonction « %s » doit renvoyer le type « event_trigger »" + +#~ msgid "function %s must return type \"fdw_handler\"" +#~ msgstr "la fonction %s doit renvoyer le type « fdw_handler »" + +#~ msgid "could not reposition held cursor" +#~ msgstr "n'a pas pu repositionner le curseur détenu" + +#~ msgid "function %s must return type \"language_handler\"" +#~ msgstr "la fonction %s doit renvoyer le type « language_handler »" + +#~ msgid "function %s must return type \"trigger\"" +#~ msgstr "la fonction %s doit renvoyer le type « trigger »" + +#~ msgid "changing return type of function %s from \"opaque\" to \"cstring\"" +#~ msgstr "changement du type de retour de la fonction %s d'« opaque » vers « cstring »" + +#~ msgid "type output function %s must return type \"cstring\"" +#~ msgstr "le type de sortie de la fonction %s doit être « cstring »" + +#~ msgid "type send function %s must return type \"bytea\"" +#~ msgstr "la fonction send du type %s doit renvoyer le type « bytea »" + +#~ msgid "typmod_in function %s must return type \"integer\"" +#~ msgstr "la fonction typmod_in %s doit renvoyer le type « entier »" + +#~ msgid "Permissions should be u=rw (0600) or less." +#~ msgstr "Les droits devraient être u=rwx (0600) ou inférieures." + +#~ msgid "function %s must return type \"tsm_handler\"" +#~ msgstr "la fonction %s doit renvoyer le type « tsm_handler »" + +#~ msgid "must be superuser to reset statistics counters" +#~ msgstr "doit être super-utilisateur pour réinitialiser les compteurs statistiques" + +#~ msgid "socket not open" +#~ msgstr "socket non ouvert" + +#~ msgid "multibyte flag character is not allowed" +#~ msgstr "un caractère drapeau multi-octet n'est pas autorisé" + +#~ msgid "could not format \"path\" value" +#~ msgstr "n'a pas pu formater la valeur « path »" + +#~ msgid "invalid input syntax for type box: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type box : « %s »" + +#~ msgid "invalid input syntax for type line: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type line: « %s »" + +#~ msgid "invalid input syntax for type path: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type path : « %s »" + +#~ msgid "invalid input syntax for type point: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type point : « %s »" + +#~ msgid "invalid input syntax for type lseg: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type lseg : « %s »" + +#~ msgid "invalid input syntax for type polygon: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type polygon : « %s »" + +#~ msgid "invalid input syntax for type circle: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type circle : « %s »" + +#~ msgid "could not format \"circle\" value" +#~ msgstr "n'a pas pu formater la valeur « circle »" + +#~ msgid "must be superuser to signal the postmaster" +#~ msgstr "doit être super-utilisateur pour envoyer un signal au postmaster" + +#~ msgid "argument for function \"exp\" too big" +#~ msgstr "l'argument de la fonction « exp » est trop gros" + +#~ msgid "WAL writer sleep time between WAL flushes." +#~ msgstr "" +#~ "Temps d'endormissement du processus d'écriture pendant le vidage des\n" +#~ "journaux de transactions en millisecondes." + +#~ msgid "JSON does not support infinite date values." +#~ msgstr "JSON ne supporte pas les valeurs infinies de date." + +#~ msgid "JSON does not support infinite timestamp values." +#~ msgstr "JSON ne supporte pas les valeurs infinies de timestamp." + +#~ msgid "cannot override frame clause of window \"%s\"" +#~ msgstr "ne peut pas surcharger la frame clause du window « %s »" + +#~ msgid "window functions cannot use named arguments" +#~ msgstr "les fonctions window ne peuvent pas renvoyer des arguments nommés" + +#~ msgid "invalid list syntax for \"unix_socket_directories\"" +#~ msgstr "syntaxe de liste invalide pour le paramètre « unix_socket_directories »" + +#~ msgid "Valid values are '[]', '[)', '(]', and '()'." +#~ msgstr "Les valeurs valides sont « [] », « [) », « (] » et « () »." + +#~ msgid "poll() failed in statistics collector: %m" +#~ msgstr "échec du poll() dans le récupérateur de statistiques : %m" + +#~ msgid "select() failed in logger process: %m" +#~ msgstr "échec de select() dans le processus des journaux applicatifs : %m" + +#~ msgid "%s: could not open log file \"%s/%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le journal applicatif « %s/%s » : %s\n" + +#~ msgid "%s: could not fork background process: %s\n" +#~ msgstr "%s : n'a pas pu créer un processus fils : %s\n" + +#~ msgid "%s: could not dissociate from controlling TTY: %s\n" +#~ msgstr "%s : n'a pas pu se dissocier du TTY contrôlant : %s\n" + +#~ msgid "Runs the server silently." +#~ msgstr "Lance le serveur de manière silencieuse." + +#~ msgid "If this parameter is set, the server will automatically run in the background and any controlling terminals are dissociated." +#~ msgstr "" +#~ "Si ce paramètre est initialisé, le serveur sera exécuté automatiquement en\n" +#~ "tâche de fond et les terminaux de contrôles seront dés-associés." + +#~ msgid "WAL sender sleep time between WAL replications." +#~ msgstr "" +#~ "Temps d'endormissement du processus d'envoi des journaux de transactions entre\n" +#~ "les réplications des journaux de transactions." + +#~ msgid "Sets the list of known custom variable classes." +#~ msgstr "Initialise la liste des classes variables personnalisées connues." + +#~ msgid "foreign key constraint \"%s\" of relation \"%s\" does not exist" +#~ msgstr "la clé étrangère « %s » de la relation « %s » n'existe pas" + +#~ msgid "removing built-in function \"%s\"" +#~ msgstr "suppression de la fonction interne « %s »" + +#~ msgid "permission denied to drop foreign-data wrapper \"%s\"" +#~ msgstr "droit refusé pour supprimer le wrapper de données distantes « %s »" + +#~ msgid "Must be superuser to drop a foreign-data wrapper." +#~ msgstr "Doit être super-utilisateur pour supprimer un wrapper de données distantes." + +#~ msgid "must be superuser to drop text search parsers" +#~ msgstr "" +#~ "doit être super-utilisateur pour supprimer des analyseurs de recherche plein\n" +#~ "texte" + +#~ msgid "must be superuser to drop text search templates" +#~ msgstr "doit être super-utilisateur pour supprimer des modèles de recherche plein texte" + +#~ msgid "recovery is still in progress, can't accept WAL streaming connections" +#~ msgstr "la restauration est en cours, ne peut pas accepter les connexions de flux WAL" + +#~ msgid "standby connections not allowed because wal_level=minimal" +#~ msgstr "connexions standby non autorisées car wal_level=minimal" + +#~ msgid "could not open directory \"pg_tblspc\": %m" +#~ msgstr "n'a pas pu ouvrir le répertoire « pg_tblspc » : %m" + +#~ msgid "could not access root certificate file \"%s\": %m" +#~ msgstr "n'a pas pu accéder au fichier du certificat racine « %s » : %m" + +#~ msgid "SSL certificate revocation list file \"%s\" not found, skipping: %s" +#~ msgstr "liste de révocation des certificats SSL « %s » introuvable, continue : %s" + +#~ msgid "Certificates will not be checked against revocation list." +#~ msgstr "Les certificats ne seront pas vérifiés avec la liste de révocation." + +#~ msgid "missing or erroneous pg_hba.conf file" +#~ msgstr "fichier pg_hba.conf manquant ou erroné" + +#~ msgid "See server log for details." +#~ msgstr "Voir les journaux applicatifs du serveur pour plus de détails." + +#~ msgid "Make sure the root.crt file is present and readable." +#~ msgstr "Assurez-vous que le certificat racine (root.crt) est présent et lisible" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide, puis quitte\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version, puis quitte\n" + +#~ msgid "CREATE TABLE AS cannot specify INTO" +#~ msgstr "CREATE TABLE AS ne peut pas spécifier INTO" + +#~ msgid "column name list not allowed in CREATE TABLE / AS EXECUTE" +#~ msgstr "la liste de noms de colonnes n'est pas autorisée dans CREATE TABLE / AS EXECUTE" + +#~ msgid "INSERT ... SELECT cannot specify INTO" +#~ msgstr "INSERT ... SELECT ne peut pas avoir INTO" + +#~ msgid "DECLARE CURSOR cannot specify INTO" +#~ msgstr "DECLARE CURSOR ne peut pas spécifier INTO" + +#~ msgid "subquery in FROM cannot have SELECT INTO" +#~ msgstr "la sous-requête du FROM ne peut pas avoir de SELECT INTO" + +#~ msgid "subquery cannot have SELECT INTO" +#~ msgstr "la sous-requête ne peut pas avoir de SELECT INTO" + +#~ msgid "subquery in WITH cannot have SELECT INTO" +#~ msgstr "la sous-requête du WITH ne peut pas avoir de SELECT INTO" + +#~ msgid "tablespace %u is not empty" +#~ msgstr "le tablespace %u n'est pas vide" + +#~ msgid "consistent state delayed because recovery snapshot incomplete" +#~ msgstr "état de cohérence pas encore atteint à cause d'un snapshot de restauration incomplet" + +#~ msgid "SSPI error %x" +#~ msgstr "erreur SSPI : %x" + +#~ msgid "%s (%x)" +#~ msgstr "%s (%x)" + +#~ msgid "resetting unlogged relations: cleanup %d init %d" +#~ msgstr "réinitialisation des relations non tracées : nettoyage %d initialisation %d" + +#~ msgid "ALTER TYPE USING is only supported on plain tables" +#~ msgstr "ALTER TYPE USING est seulement supportés sur les tables standards" + +#~ msgid "index \"%s\" is not a b-tree" +#~ msgstr "l'index « %s » n'est pas un btree" + +#~ msgid "unable to read symbolic link %s: %m" +#~ msgstr "incapable de lire le lien symbolique %s : %m" + +#~ msgid "unable to open directory pg_tblspc: %m" +#~ msgstr "impossible d'ouvrir le répertoire p_tblspc : %m" + +#~ msgid "Write-Ahead Log / Streaming Replication" +#~ msgstr "Write-Ahead Log / Réplication en flux" + +#~ msgid "syntax error in recovery command file: %s" +#~ msgstr "erreur de syntaxe dans le fichier de restauration : %s" + +#~ msgid "Lines should have the format parameter = 'value'." +#~ msgstr "Les lignes devraient avoir le format paramètre = 'valeur'" + +#~ msgid "index %u/%u/%u needs VACUUM FULL or REINDEX to finish crash recovery" +#~ msgstr "" +#~ "l'index %u/%u/%u a besoin d'un VACUUM FULL ou d'un REINDEX pour terminer la\n" +#~ "récupération suite à un arrêt brutal" + +#~ msgid "Incomplete insertion detected during crash replay." +#~ msgstr "" +#~ "Insertion incomplète détectée lors de la ré-exécution des requêtes suite à\n" +#~ "l'arrêt brutal." + +#~ msgid "index \"%s\" needs VACUUM or REINDEX to finish crash recovery" +#~ msgstr "" +#~ "l'index « %s » a besoin d'un VACUUM ou d'un REINDEX pour terminer la\n" +#~ "récupération suite à un arrêt brutal" + +#~ msgid "index \"%s\" needs VACUUM FULL or REINDEX to finish crash recovery" +#~ msgstr "" +#~ "l'index « %s » a besoin d'un VACUUM FULL ou d'un REINDEX pour terminer la\n" +#~ "récupération suite à un arrêt brutal" + +#~ msgid "EnumValuesCreate() can only set a single OID" +#~ msgstr "EnumValuesCreate() peut seulement initialiser un seul OID" + +#~ msgid "clustering \"%s.%s\"" +#~ msgstr "exécution de CLUSTER sur « %s.%s »" + +#~ msgid "cannot cluster on index \"%s\" because access method does not handle null values" +#~ msgstr "" +#~ "ne peut pas créer un cluster sur l'index « %s » car la méthode d'accès de\n" +#~ "l'index ne gère pas les valeurs NULL" + +#~ msgid "You might be able to work around this by marking column \"%s\" NOT NULL, or use ALTER TABLE ... SET WITHOUT CLUSTER to remove the cluster specification from the table." +#~ msgstr "" +#~ "Vous pourriez contourner ceci en marquant la colonne « %s » avec la\n" +#~ "contrainte NOT NULL ou en utilisant ALTER TABLE ... SET WITHOUT CLUSTER pour\n" +#~ "supprimer la spécification CLUSTER de la table." + +#~ msgid "You might be able to work around this by marking column \"%s\" NOT NULL." +#~ msgstr "Vous pouvez contourner ceci en marquant la colonne « %s » comme NOT NULL." + +#~ msgid "cannot cluster on expressional index \"%s\" because its index access method does not handle null values" +#~ msgstr "" +#~ "ne peut pas exécuter CLUSTER sur l'index à expression « %s » car sa méthode\n" +#~ "d'accès ne gère pas les valeurs NULL" + +#~ msgid "\"%s\" is not a table, view, or composite type" +#~ msgstr "« %s » n'est pas une table, une vue ou un type composite" + +#~ msgid "must be superuser to comment on procedural language" +#~ msgstr "" +#~ "doit être super-utilisateur pour ajouter un commentaire sur un langage de\n" +#~ "procédures" + +#~ msgid "must be superuser to comment on text search parser" +#~ msgstr "" +#~ "doit être super-utilisateur pour ajouter un commentaire sur l'analyseur de\n" +#~ "recherche plein texte" + +#~ msgid "must be superuser to comment on text search template" +#~ msgstr "" +#~ "doit être super-utilisateur pour ajouter un commentaire sur un modèle de\n" +#~ "recherche plein texte" + +#~ msgid "cannot reference temporary table from permanent table constraint" +#~ msgstr "" +#~ "ne peut pas référencer une table temporaire à partir d'une contrainte de\n" +#~ "table permanente" + +#~ msgid "cannot reference permanent table from temporary table constraint" +#~ msgstr "" +#~ "ne peut pas référencer une table permanente à partir de la contrainte de\n" +#~ "table temporaire" + +#~ msgid "composite type must have at least one attribute" +#~ msgstr "le type composite doit avoir au moins un attribut" + +#~ msgid "database \"%s\" not found" +#~ msgstr "base de données « %s » non trouvée" + +#~ msgid "invalid list syntax for parameter \"datestyle\"" +#~ msgstr "syntaxe de liste invalide pour le paramètre « datestyle »" + +#~ msgid "unrecognized \"datestyle\" key word: \"%s\"" +#~ msgstr "mot clé « datestyle » non reconnu : « %s »" + +#~ msgid "invalid interval value for time zone: month not allowed" +#~ msgstr "valeur d'intervalle invalide pour le fuseau horaire : les mois ne sont pas autorisés" + +#~ msgid "invalid interval value for time zone: day not allowed" +#~ msgstr "valeur d'intervalle invalide pour le fuseau horaire : jour non autorisé" + +#~ msgid "argument to pg_get_expr() must come from system catalogs" +#~ msgstr "l'argument de pg_get_expr() doit provenir des catalogues systèmes" + +#~ msgid "could not enable credential reception: %m" +#~ msgstr "n'a pas pu activer la réception de lettres de créance : %m" + +#~ msgid "could not get effective UID from peer credentials: %m" +#~ msgstr "n'a pas pu obtenir l'UID réel à partir des pièces d'identité de l'autre : %m" + +#~ msgid "Ident authentication is not supported on local connections on this platform" +#~ msgstr "l'authentification Ident n'est pas supportée sur les connexions locales sur cette plateforme" + +#~ msgid "could not create log file \"%s\": %m" +#~ msgstr "n'a pas pu créer le journal applicatif « %s » : %m" + +#~ msgid "could not open new log file \"%s\": %m" +#~ msgstr "n'a pas pu ouvrir le nouveau journal applicatif « %s » : %m" + +#~ msgid "Sets immediate fsync at commit." +#~ msgstr "Configure un fsync immédiat lors du commit." + +#~ msgid "invalid list syntax for parameter \"log_destination\"" +#~ msgstr "syntaxe de liste invalide pour le paramètre « log_destination »" + +#~ msgid "unrecognized \"log_destination\" key word: \"%s\"" +#~ msgstr "mot clé « log_destination » non reconnu : « %s »" + +#~ msgid "cannot drop \"%s\" because it is being used by active queries in this session" +#~ msgstr "" +#~ "ne peut pas supprimer « %s » car cet objet est en cours d'utilisation par\n" +#~ "des requêtes actives dans cette session" + +#~ msgid "parameter \"recovery_target_inclusive\" requires a Boolean value" +#~ msgstr "le paramètre « recovery_target_inclusive » requiert une valeur booléenne" + +#~ msgid "parameter \"standby_mode\" requires a Boolean value" +#~ msgstr "le paramètre « standby_mode » requiert une valeur booléenne" + +#~ msgid "Not safe to send CSV data\n" +#~ msgstr "Envoi non sûr des données CSV\n" + +#~ msgid "recovery restart point at %X/%X with latest known log time %s" +#~ msgstr "" +#~ "point de relancement de la restauration sur %X/%X avec %s comme dernière\n" +#~ "date connue du journal" + +#~ msgid "restartpoint_command = '%s'" +#~ msgstr "restartpoint_command = '%s'" + +#~ msgid "usermap \"%s\"" +#~ msgstr "correspondance utilisateur « %s »" + +#~ msgid "WAL archiving is not active" +#~ msgstr "l'archivage des journaux de transactions n'est pas actif" + +#~ msgid "archive_mode must be enabled at server start." +#~ msgstr "archive_mode doit être activé au lancement du serveur." + +#~ msgid "archive_command must be defined before online backups can be made safely." +#~ msgstr "" +#~ "archive_command doit être défini avant que les sauvegardes à chaud puissent\n" +#~ "s'effectuer correctement." + +#~ msgid "During recovery, allows connections and queries. During normal running, causes additional info to be written to WAL to enable hot standby mode on WAL standby nodes." +#~ msgstr "" +#~ "Lors de la restauration, autorise les connexions et les requêtes. Lors d'une\n" +#~ "exécution normale, fait que des informations supplémentaires sont écrites dans\n" +#~ "les journaux de transactions pour activer le mode Hot Standby sur les nœuds\n" +#~ "en attente." + +#~ msgid "unlogged operation performed, data may be missing" +#~ msgstr "opération réalisée non tracée, les données pourraient manquer" + +#~ msgid "not enough shared memory for walsender" +#~ msgstr "pas assez de mémoire partagée pour le processus d'envoi des journaux de transactions" + +#~ msgid "not enough shared memory for walreceiver" +#~ msgstr "" +#~ "pas assez de mémoire partagée pour le processus de réception des journaux de\n" +#~ "transactions" + +#~ msgid "connection limit exceeded for non-superusers" +#~ msgstr "limite de connexions dépassée pour les utilisateurs standards" + +#~ msgid "not enough shared memory for background writer" +#~ msgstr "pas assez de mémoire partagée pour le processus d'écriture en tâche de fond" + +#, fuzzy +#~ msgid "couldn't put socket to non-blocking mode: %m" +#~ msgstr "n'a pas pu activer le mode non-bloquant pour la socket : %s\n" + +#, fuzzy +#~ msgid "couldn't put socket to blocking mode: %m" +#~ msgstr "n'a pas pu activer le mode bloquant pour la socket : %s\n" + +#~ msgid "WAL file SYSID is %s, pg_control SYSID is %s" +#~ msgstr "le SYSID du journal de transactions WAL est %s, celui de pg_control est %s" + +#, fuzzy +#~ msgid "sorry, too many standbys already" +#~ msgstr "désolé, trop de clients sont déjà connectés" + +#, fuzzy +#~ msgid "invalid WAL message received from primary" +#~ msgstr "format du message invalide" + +#~ msgid "PID %d is among the slowest backends." +#~ msgstr "Le PID %d est parmi les processus serveur les plus lents." + +#~ msgid "transaction is read-only" +#~ msgstr "la transaction est en lecture seule" + +#~ msgid "binary value is out of range for type bigint" +#~ msgstr "la valeur binaire est en dehors des limites du type bigint" + +#~ msgid "redo starts at %X/%X, consistency will be reached at %X/%X" +#~ msgstr "la restauration comme à %X/%X, la cohérence sera atteinte à %X/%X" + +#~ msgid "This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by \"client_encoding\"." +#~ msgstr "" +#~ "Cette erreur peut aussi survenir si la séquence d'octets ne correspond pas\n" +#~ "au jeu de caractères attendu par le serveur, le jeu étant contrôlé par\n" +#~ "« client_encoding »." + +#~ msgid "Sets the language used in DO statement if LANGUAGE is not specified." +#~ msgstr "" +#~ "Configure le langage utilisé dans une instruction DO si la clause LANGUAGE n'est\n" +#~ "pas spécifiée." + +#~ msgid "shared index \"%s\" can only be reindexed in stand-alone mode" +#~ msgstr "un index partagé « %s » peut seulement être réindexé en mode autonome" + +#~ msgid "shared table \"%s\" can only be reindexed in stand-alone mode" +#~ msgstr "la table partagée « %s » peut seulement être réindexé en mode autonome" + +#~ msgid "cannot truncate system relation \"%s\"" +#~ msgstr "ne peut pas tronquer la relation système « %s »" + +#~ msgid "number of distinct values %g is too low" +#~ msgstr "le nombre de valeurs distinctes %g est trop basse" + +#~ msgid "directory \"%s\" is not empty" +#~ msgstr "le répertoire « %s » n'est pas vide" + +#~ msgid "relation \"%s\" TID %u/%u: XMIN_COMMITTED not set for transaction %u --- cannot shrink relation" +#~ msgstr "" +#~ "relation « %s », TID %u/%u : XMIN_COMMITTED non configuré pour la\n" +#~ "transaction %u --- n'a pas pu diminuer la taille de la relation" + +#~ msgid "relation \"%s\" TID %u/%u: dead HOT-updated tuple --- cannot shrink relation" +#~ msgstr "" +#~ "relation « %s », TID %u/%u : ligne morte mise à jour par HOT --- n'a pas pu\n" +#~ "diminuer la taille de la relation" + +#~ msgid "relation \"%s\" TID %u/%u: InsertTransactionInProgress %u --- cannot shrink relation" +#~ msgstr "" +#~ "relation « %s », TID %u/%u : InsertTransactionInProgress %u --- n'a pas pu\n" +#~ "diminuer la taille de la relation" + +#~ msgid "relation \"%s\" TID %u/%u: DeleteTransactionInProgress %u --- cannot shrink relation" +#~ msgstr "" +#~ "relation « %s », TID %u/%u : DeleteTransactionInProgress %u --- n'a pas pu\n" +#~ "diminuer la taille de la relation" + +#~ msgid "" +#~ "%.0f dead row versions cannot be removed yet.\n" +#~ "Nonremovable row versions range from %lu to %lu bytes long.\n" +#~ "There were %.0f unused item pointers.\n" +#~ "Total free space (including removable row versions) is %.0f bytes.\n" +#~ "%u pages are or will become empty, including %u at the end of the table.\n" +#~ "%u pages containing %.0f free bytes are potential move destinations.\n" +#~ "%s." +#~ msgstr "" +#~ "%.0f versions de lignes mortes ne peuvent pas encore être supprimées.\n" +#~ "Les versions non supprimables de ligne vont de %lu to %lu octets.\n" +#~ "Il existait %.0f pointeurs d'éléments inutilisés.\n" +#~ "L'espace libre total (incluant les versions supprimables de ligne) est de\n" +#~ "%.0f octets.\n" +#~ "%u pages sont ou deviendront vides, ceci incluant %u pages en fin de la\n" +#~ "table.\n" +#~ "%u pages contenant %.0f octets libres sont des destinations de déplacement\n" +#~ "disponibles.\n" +#~ "%s." + +#~ msgid "\"%s\": moved %u row versions, truncated %u to %u pages" +#~ msgstr "« %s » : %u versions de ligne déplacées, %u pages tronquées sur %u" + +#~ msgid "Rebuild the index with REINDEX." +#~ msgstr "Reconstruisez l'index avec REINDEX." + +#~ msgid "frame start at CURRENT ROW is not implemented" +#~ msgstr "début du frame à CURRENT ROW n'est pas implémenté" + +#~ msgid "database system is in consistent recovery mode" +#~ msgstr "le système de bases de données est dans un mode de restauration cohérent" + +#~ msgid "DISTINCT is supported only for single-argument aggregates" +#~ msgstr "DISTINCT est seulement supporté pour les agrégats à un seul argument" + +#~ msgid "index row size %lu exceeds btree maximum, %lu" +#~ msgstr "la taille de la ligne index %lu dépasse le maximum de btree, %lu" + +#~ msgid "Table contains duplicated values." +#~ msgstr "La table contient des valeurs dupliquées." + +#~ msgid "Automatically adds missing table references to FROM clauses." +#~ msgstr "" +#~ "Ajoute automatiquement les références à la table manquant dans les clauses\n" +#~ "FROM." + +#~ msgid "Sets the regular expression \"flavor\"." +#~ msgstr "Initialise l'expression rationnelle « flavor »." + +#~ msgid "attempted change of parameter \"%s\" ignored" +#~ msgstr "tentative de modification du paramètre « %s » ignoré" + +#~ msgid "This parameter cannot be changed after server start." +#~ msgstr "Ce paramètre ne peut pas être modifié après le lancement du serveur" + +#~ msgid "invalid database name \"%s\"" +#~ msgstr "nom de base de données « %s » invalide" + +#~ msgid "invalid role name \"%s\"" +#~ msgstr "nom de rôle « %s » invalide" + +#~ msgid "invalid role password \"%s\"" +#~ msgstr "mot de passe « %s » de l'utilisateur invalide" + +#~ msgid "cannot specify CSV in BINARY mode" +#~ msgstr "ne peut pas spécifier CSV en mode binaire (BINARY)" + +#~ msgid "cannot set session authorization within security-definer function" +#~ msgstr "ne peut pas exécuter SESSION AUTHORIZATION sur la fonction SECURITY DEFINER" + +#~ msgid "SELECT FOR UPDATE/SHARE is not supported within a query with multiple result relations" +#~ msgstr "" +#~ "SELECT FOR UPDATE/SHARE n'est pas supporté dans une requête avec plusieurs\n" +#~ "relations" + +#~ msgid "could not remove relation %s: %m" +#~ msgstr "n'a pas pu supprimer la relation %s : %m" + +#~ msgid "could not remove segment %u of relation %s: %m" +#~ msgstr "n'a pas pu supprimer le segment %u de la relation %s : %m" + +#~ msgid "could not seek to block %u of relation %s: %m" +#~ msgstr "n'a pas pu se positionner sur le bloc %u de la relation %s : %m" + +#~ msgid "could not extend relation %s: %m" +#~ msgstr "n'a pas pu étendre la relation %s : %m" + +#~ msgid "could not open relation %s: %m" +#~ msgstr "n'a pas pu ouvrir la relation %s : %m" + +#~ msgid "could not read block %u of relation %s: %m" +#~ msgstr "n'a pas pu lire le bloc %u de la relation %s : %m" + +#~ msgid "could not write block %u of relation %s: %m" +#~ msgstr "n'a pas pu écrire le bloc %u de la relation %s : %m" + +#~ msgid "could not open segment %u of relation %s: %m" +#~ msgstr "n'a pas pu ouvrir le segment %u de la relation %s : %m" + +#~ msgid "could not fsync segment %u of relation %s: %m" +#~ msgstr "" +#~ "n'a pas pu synchroniser sur disque (fsync) le segment %u de la relation\n" +#~ "%s : %m" + +#~ msgid "could not fsync segment %u of relation %s but retrying: %m" +#~ msgstr "" +#~ "n'a pas pu synchroniser sur disque (fsync) le segment %u de la relation\n" +#~ "%s, nouvelle tentative : %m" + +#~ msgid "could not seek to end of segment %u of relation %s: %m" +#~ msgstr "n'a pas pu se déplacer à la fin du segment %u de la relation %s : %m" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed in subqueries" +#~ msgstr "SELECT FOR UPDATE/SHARE n'est pas autorisé dans les sous-requêtes" + +#~ msgid "adding missing FROM-clause entry for table \"%s\"" +#~ msgstr "ajout d'une entrée manquante dans FROM (table « %s »)" + +#~ msgid "OLD used in query that is not in a rule" +#~ msgstr "OLD utilisé dans une requête qui n'est pas une règle" + +#~ msgid "NEW used in query that is not in a rule" +#~ msgstr "NEW utilisé dans une requête qui ne fait pas partie d'une règle" + +#~ msgid "hurrying in-progress restartpoint" +#~ msgstr "accélération du restartpoint en cours" + +#~ msgid "multiple DELETE events specified" +#~ msgstr "multiples événements DELETE spécifiés" + +#~ msgid "multiple TRUNCATE events specified" +#~ msgstr "multiples événements TRUNCATE spécifiés" + +#~ msgid "could not create XPath object" +#~ msgstr "n'a pas pu créer l'objet XPath" + +#, fuzzy +#~ msgid "wrong number of array_subscripts" +#~ msgstr "mauvais nombre d'indices du tableau" + +#~ msgid "fillfactor=%d is out of range (should be between %d and 100)" +#~ msgstr "le facteur de remplissage (%d) est en dehors des limites (il devrait être entre %d et 100)" + +#~ msgid "GIN index does not support search with void query" +#~ msgstr "les index GIN ne supportent pas la recherche avec des requêtes vides" + +#~ msgid "invalid LC_CTYPE setting" +#~ msgstr "paramètre LC_CTYPE invalide" + +#~ msgid "The database cluster was initialized with LOCALE_NAME_BUFLEN %d, but the server was compiled with LOCALE_NAME_BUFLEN %d." +#~ msgstr "" +#~ "Le cluster de bases de données a été initialisé avec un LOCALE_NAME_BUFLEN\n" +#~ "à %d alors que le serveur a été compilé avec un LOCALE_NAME_BUFLEN à %d." + +#~ msgid "It looks like you need to initdb or install locale support." +#~ msgstr "" +#~ "Il semble que vous avez besoin d'exécuter initdb ou d'installer le support\n" +#~ "des locales." + +#~ msgid "log_restartpoints = %s" +#~ msgstr "log_restartpoints = %s" + +#~ msgid "syntax error: cannot back up" +#~ msgstr "erreur de syntaxe : n'a pas pu revenir" + +#~ msgid "syntax error; also virtual memory exhausted" +#~ msgstr "erreur de syntaxe ; de plus, mémoire virtuelle saturée" + +#~ msgid "parser stack overflow" +#~ msgstr "saturation de la pile de l'analyseur" + +#~ msgid "failed to drop all objects depending on %s" +#~ msgstr "échec lors de la suppression de tous les objets dépendant de %s" + +#~ msgid "there are objects dependent on %s" +#~ msgstr "des objets dépendent de %s" + +#~ msgid "multiple constraints named \"%s\" were dropped" +#~ msgstr "les contraintes multiples nommées « %s » ont été supprimées" + +#~ msgid "constraint definition for check constraint \"%s\" does not match" +#~ msgstr "" +#~ "la définition de la contrainte « %s » pour la contrainte de vérification ne\n" +#~ "correspond pas" + +#~ msgid "relation \"%s.%s\" contains more than \"max_fsm_pages\" pages with useful free space" +#~ msgstr "" +#~ "la relation « %s.%s » contient plus de « max_fsm_pages » pages d'espace\n" +#~ "libre utile" + +#~ msgid "Consider using VACUUM FULL on this relation or increasing the configuration parameter \"max_fsm_pages\"." +#~ msgstr "" +#~ "Pensez à compacter cette relation en utilisant VACUUM FULL ou à augmenter le\n" +#~ "paramètre de configuration « max_fsm_pages »." + +#~ msgid "cannot change number of columns in view" +#~ msgstr "ne peut pas modifier le nombre de colonnes dans la vue" + +#~ msgid "unexpected Kerberos user name received from client (received \"%s\", expected \"%s\")" +#~ msgstr "" +#~ "nom d'utilisateur Kerberos inattendu reçu à partir du client (reçu « %s »,\n" +#~ "attendu « %s »)" + +#~ msgid "Kerberos 5 not implemented on this server" +#~ msgstr "Kerberos 5 non implémenté sur ce serveur" + +#~ msgid "GSSAPI not implemented on this server" +#~ msgstr "GSSAPI non implémenté sur ce serveur" + +#~ msgid "could not get security token from context" +#~ msgstr "n'a pas pu récupérer le jeton de sécurité à partir du contexte" + +#~ msgid "unsafe permissions on private key file \"%s\"" +#~ msgstr "droits non sûrs sur le fichier de la clé privée « %s »" + +#~ msgid "File must be owned by the database user and must have no permissions for \"group\" or \"other\"." +#~ msgstr "" +#~ "Le fichier doit appartenir au propriétaire de la base de données et ne doit\n" +#~ "pas avoir de droits pour un groupe ou pour les autres." + +#~ msgid "cannot use authentication method \"crypt\" because password is MD5-encrypted" +#~ msgstr "" +#~ "n'a pas pu utiliser la méthode d'authentification « crypt » car le mot de\n" +#~ "passe est chiffré avec MD5" + +#~ msgid "invalid entry in file \"%s\" at line %d, token \"%s\"" +#~ msgstr "entrée invalide dans le fichier « %s » à la ligne %d, jeton « %s »" + +#~ msgid "missing field in file \"%s\" at end of line %d" +#~ msgstr "champ manquant dans le fichier « %s » à la fin de la ligne %d" + +#~ msgid "cannot use Ident authentication without usermap field" +#~ msgstr "n'a pas pu utiliser l'authentication Ident sans le champ usermap" + +#~ msgid "Ident protocol identifies remote user as \"%s\"" +#~ msgstr "le protocole Ident identifie l'utilisateur distant comme « %s »" + +#~ msgid "SELECT FOR UPDATE/SHARE is not supported for inheritance queries" +#~ msgstr "SELECT FOR UPDATE/SHARE n'est pas supporté pour les requêtes d'héritage" + +#~ msgid "missing FROM-clause entry in subquery for table \"%s\"" +#~ msgstr "entrée manquante de la clause FROM dans la sous-requête de la table « %s »" + +#~ msgid "adding missing FROM-clause entry in subquery for table \"%s\"" +#~ msgstr "entrée manquante de la clause FROM dans la sous-requête pour la table « %s »" + +#~ msgid "%s: the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16\n" +#~ msgstr "" +#~ "%s : le nombre de tampons (-B) doit être au moins deux fois le nombre de\n" +#~ "connexions disponibles (-N) et au moins 16\n" + +#~ msgid "could not set statistics collector timer: %m" +#~ msgstr "n'a pas pu configurer le timer du récupérateur de statistiques : %m" + +#~ msgid "insufficient shared memory for free space map" +#~ msgstr "mémoire partagée insuffisante pour la structure FSM" + +#~ msgid "max_fsm_pages must exceed max_fsm_relations * %d" +#~ msgstr "max_fsm_pages doit excéder max_fsm_relations * %d" + +#~ msgid "free space map contains %d pages in %d relations" +#~ msgstr "la structure FSM contient %d pages dans %d relations" + +#~ msgid "" +#~ "A total of %.0f page slots are in use (including overhead).\n" +#~ "%.0f page slots are required to track all free space.\n" +#~ "Current limits are: %d page slots, %d relations, using %.0f kB." +#~ msgstr "" +#~ "Un total de %.0f emplacements de pages est utilisé (ceci incluant la\n" +#~ "surcharge).\n" +#~ "%.0f emplacements de pages sont requis pour tracer tout l'espace libre.\n" +#~ "Les limites actuelles sont : %d emplacements de pages, %d relations,\n" +#~ "utilisant %.0f Ko." + +#~ msgid "max_fsm_relations(%d) equals the number of relations checked" +#~ msgstr "max_fsm_relations(%d) équivaut au nombre de relations tracées" + +#~ msgid "You have at least %d relations. Consider increasing the configuration parameter \"max_fsm_relations\"." +#~ msgstr "" +#~ "Vous avez au moins %d relations.Considèrez l'augmentation du paramètre de\n" +#~ "configuration « max_fsm_relations »." + +#~ msgid "number of page slots needed (%.0f) exceeds max_fsm_pages (%d)" +#~ msgstr "le nombre d'emplacements de pages nécessaires (%.0f) dépasse max_fsm_pages (%d)" + +#~ msgid "Consider increasing the configuration parameter \"max_fsm_pages\" to a value over %.0f." +#~ msgstr "" +#~ "Considérez l'augmentation du paramètre de configuration « max_fsm_pages »\n" +#~ "à une valeur supérieure à %.0f." + +#~ msgid "Prints the parse tree to the server log." +#~ msgstr "Affiche l'arbre d'analyse dans les journaux applicatifs du serveur." + +#~ msgid "Prints the parse tree after rewriting to server log." +#~ msgstr "Affiche l'arbre d'analyse après ré-écriture dans les journaux applicatifs du serveur." + +#~ msgid "Prints the execution plan to server log." +#~ msgstr "Affiche le plan d'exécution dans les journaux applicatifs du serveur." + +#~ msgid "Uses the indented output format for EXPLAIN VERBOSE." +#~ msgstr "Utilise le format de sortie indenté pour EXPLAIN VERBOSE." + +#~ msgid "Sets the maximum number of tables and indexes for which free space is tracked." +#~ msgstr "" +#~ "Initialise le nombre maximum de tables et index pour lesquels l'espace libre\n" +#~ "est tracé." + +#~ msgid "Valid values are ON, OFF, and SAFE_ENCODING." +#~ msgstr "Les valeurs valides sont ON, OFF et SAFE_ENCODING." + +#~ msgid "Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Each level includes all the levels that follow it." +#~ msgstr "" +#~ "Les valeurs valides sont DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO,\n" +#~ "NOTICE, WARNING, ERROR, LOG, FATAL et PANIC. Chaque niveau incut tous les\n" +#~ "niveaux qui le suit." + +#~ msgid "All SQL statements that cause an error of the specified level or a higher level are logged." +#~ msgstr "" +#~ "Toutes les instructions SQL causant une erreur du niveau spécifié ou d'un\n" +#~ "niveau supérieur sont tracées." + +#~ msgid "Each SQL transaction has an isolation level, which can be either \"read uncommitted\", \"read committed\", \"repeatable read\", or \"serializable\"." +#~ msgstr "" +#~ "Chaque transaction SQL a un niveau d'isolation qui peut être soit « read\n" +#~ "uncommitted », soit « read committed », soit « repeatable read », soit\n" +#~ "« serializable »." + +#~ msgid "Each session can be either \"origin\", \"replica\", or \"local\"." +#~ msgstr "Chaque session peut valoir soit « origin » soit « replica » soit « local »." + +#~ msgid "Sets realm to match Kerberos and GSSAPI users against." +#~ msgstr "" +#~ "Indique le royaume pour l'authentification des utilisateurs via Kerberos et\n" +#~ "GSSAPI." + +#~ msgid "Sets the hostname of the Kerberos server." +#~ msgstr "Initalise le nom d'hôte du serveur Kerberos." + +#~ msgid "This can be set to advanced, extended, or basic." +#~ msgstr "" +#~ "Ceci peut être initialisé avec advanced (avancé), extended (étendu) ou\n" +#~ "basic (basique)." + +#~ msgid "Valid values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7." +#~ msgstr "" +#~ "Les valeurs valides sont LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5,\n" +#~ "LOCAL6, LOCAL7." + +#~ msgid "Valid values are DOCUMENT and CONTENT." +#~ msgstr "Les valeurs valides sont DOCUMENT et CONTENT." + +#~ msgid "not unique \"S\"" +#~ msgstr "« S » non unique" + +#~ msgid "\"TZ\"/\"tz\" not supported" +#~ msgstr "« TZ »/« tz » non supporté" + +#~ msgid "January" +#~ msgstr "Janvier" + +#~ msgid "February" +#~ msgstr "Février" + +#~ msgid "March" +#~ msgstr "Mars" + +#~ msgid "April" +#~ msgstr "Avril" + +#~ msgid "May" +#~ msgstr "Mai" + +#~ msgid "June" +#~ msgstr "Juin" + +#~ msgid "July" +#~ msgstr "Juillet" + +#~ msgid "August" +#~ msgstr "Août" + +#~ msgid "September" +#~ msgstr "Septembre" + +#~ msgid "October" +#~ msgstr "Octobre" + +#~ msgid "November" +#~ msgstr "Novembre" + +#~ msgid "December" +#~ msgstr "Décembre" + +#~ msgid "Jan" +#~ msgstr "Jan" + +#~ msgid "Feb" +#~ msgstr "Fév" + +#~ msgid "Mar" +#~ msgstr "Mar" + +#~ msgid "Apr" +#~ msgstr "Avr" + +#~ msgid "S:May" +#~ msgstr "S:Mai" + +#~ msgid "Jun" +#~ msgstr "Juin" + +#~ msgid "Jul" +#~ msgstr "Juil" + +#~ msgid "Aug" +#~ msgstr "Aoû" + +#~ msgid "Sep" +#~ msgstr "Sep" + +#~ msgid "Oct" +#~ msgstr "Oct" + +#~ msgid "Nov" +#~ msgstr "Nov" + +#~ msgid "Dec" +#~ msgstr "Déc" + +#~ msgid "Sunday" +#~ msgstr "Dimanche" + +#~ msgid "Monday" +#~ msgstr "Lundi" + +#~ msgid "Tuesday" +#~ msgstr "Mardi" + +#~ msgid "Wednesday" +#~ msgstr "Mercredi" + +#~ msgid "Thursday" +#~ msgstr "Jeudi" + +#~ msgid "Friday" +#~ msgstr "Vendredi" + +#~ msgid "Saturday" +#~ msgstr "Samedi" + +#~ msgid "Sun" +#~ msgstr "Dim" + +#~ msgid "Mon" +#~ msgstr "Lun" + +#~ msgid "Tue" +#~ msgstr "Mar" + +#~ msgid "Wed" +#~ msgstr "Mer" + +#~ msgid "Thu" +#~ msgstr "Jeu" + +#~ msgid "Fri" +#~ msgstr "Ven" + +#~ msgid "Sat" +#~ msgstr "Sam" + +#~ msgid "AM/PM hour must be between 1 and 12" +#~ msgstr "l'heure AM/PM doit être compris entre 1 et 12" + +#~ msgid "UTF-16 to UTF-8 translation failed: %lu" +#~ msgstr "échec de la conversion d'UTF16 vers UTF8 : %lu" + +#~ msgid "cannot calculate week number without year information" +#~ msgstr "ne peut pas calculer le numéro de la semaine sans informations sur l'année" + +#~ msgid "query requires full scan, which is not supported by GIN indexes" +#~ msgstr "" +#~ "la requête nécessite un parcours complet, ce qui n'est pas supporté par les\n" +#~ "index GIN" + +#~ msgid "@@ operator does not support lexeme weight restrictions in GIN index searches" +#~ msgstr "" +#~ "l'opérateur @@ ne supporte pas les restrictions de poids de lexeme dans les\n" +#~ "recherches par index GIN" + +#~ msgid "unexpected delimiter at line %d of thesaurus file \"%s\"" +#~ msgstr "délimiteur inattendu sur la ligne %d du thesaurus « %s »" + +#~ msgid "unexpected end of line or lexeme at line %d of thesaurus file \"%s\"" +#~ msgstr "fin de ligne ou de lexeme inattendu sur la ligne %d du thesaurus « %s »" + +#~ msgid "unexpected end of line at line %d of thesaurus file \"%s\"" +#~ msgstr "fin de ligne inattendue à la ligne %d du thésaurus « %s »" + +#~ msgid "could not remove database directory \"%s\"" +#~ msgstr "n'a pas pu supprimer le répertoire de bases de données « %s »" + +#~ msgid "index \"%s\" is not ready" +#~ msgstr "l'index « %s » n'est pas prêt" + +#~ msgid "argument number is out of range" +#~ msgstr "le nombre en argument est en dehors des limites" + +#~ msgid "No rows were found in \"%s\"." +#~ msgstr "Aucune ligne trouvée dans « %s »." + +#~ msgid "inconsistent use of year %04d and \"BC\"" +#~ msgstr "utilisation non cohérente de l'année %04d et de « BC »" + +#~ msgid "\"interval\" time zone \"%s\" not valid" +#~ msgstr "le fuseau horaire « %s » n'est pas valide pour le type « interval »" + +#~ msgid "Not enough memory for reassigning the prepared transaction's locks." +#~ msgstr "Pas assez de mémoire pour réaffecter les verrous des transactions préparées." + +#~ msgid "large object %u was already dropped" +#~ msgstr "le « Large Object » %u a déjà été supprimé" + +#~ msgid "large object %u was not opened for writing" +#~ msgstr "le « Large Object » %u n'a pas été ouvert en écriture" + +#~ msgid "invalid standby query string: %s" +#~ msgstr "chaîne de requête invalide sur le serveur en attente : %s" + +#~ msgid "terminating walsender process to force cascaded standby to update timeline and reconnect" +#~ msgstr "" +#~ "arrêt du processus walreceiver pour forcer le serveur standby en cascade à\n" +#~ "mettre à jour la timeline et à se reconnecter" + +#~ msgid "invalid standby handshake message type %d" +#~ msgstr "type %d du message de handshake du serveur en attente invalide" + +#~ msgid "streaming replication successfully connected to primary" +#~ msgstr "réplication de flux connecté avec succès au serveur principal" + +#~ msgid "shutdown requested, aborting active base backup" +#~ msgstr "arrêt demandé, annulation de la sauvegarde active de base" + +#~ msgid "terminating all walsender processes to force cascaded standby(s) to update timeline and reconnect" +#~ msgstr "" +#~ "arrêt de tous les processus walsender pour forcer les serveurs standby en\n" +#~ "cascade à mettre à jour la timeline et à se reconnecter" + +#~ msgid "" +#~ "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently %lu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.\n" +#~ "If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter, in which case raising the request size or reconfiguring SHMMIN is called for.\n" +#~ "The PostgreSQL documentation contains more information about shared memory configuration." +#~ msgstr "" +#~ "Cette erreur signifie habituellement que la demande de PostgreSQL pour un\n" +#~ "segment de mémoire partagée a dépassé le paramètre SHMMAX de votre noyau.\n" +#~ "Vous pouvez soit réduire la taille de la requête soit reconfigurer le noyau\n" +#~ "avec un SHMMAX plus important. Pour réduire la taille de la requête\n" +#~ "(actuellement %lu octets), réduisez l'utilisation de la mémoire partagée par PostgreSQL,par exemple en réduisant shared_buffers ou max_connections\n" +#~ "Si la taille de la requête est déjà petite, il est possible qu'elle soit\n" +#~ "moindre que le paramètre SHMMIN de votre noyau, auquel cas, augmentez la\n" +#~ "taille de la requête ou reconfigurez SHMMIN.\n" +#~ "La documentation de PostgreSQL contient plus d'informations sur la\n" +#~ "configuration de la mémoire partagée." + +#~ msgid "cannot use window function in rule WHERE condition" +#~ msgstr "ne peut pas utiliser la fonction window dans la condition d'une règle WHERE" + +#~ msgid "cannot use aggregate function in rule WHERE condition" +#~ msgstr "ne peut pas utiliser la fonction d'agrégat dans la condition d'une règle WHERE" + +#~ msgid "arguments of row IN must all be row expressions" +#~ msgstr "les arguments de la ligne IN doivent tous être des expressions de ligne" + +#~ msgid "argument of %s must not contain window functions" +#~ msgstr "l'argument de %s ne doit pas contenir des fonctions window" + +#~ msgid "argument of %s must not contain aggregate functions" +#~ msgstr "l'argument de %s ne doit pas contenir de fonctions d'agrégats" + +#~ msgid "cannot use window function in function expression in FROM" +#~ msgstr "" +#~ "ne peut pas utiliser la fonction window dans l'expression de la fonction\n" +#~ "du FROM" + +#~ msgid "function expression in FROM cannot refer to other relations of same query level" +#~ msgstr "" +#~ "l'expression de la fonction du FROM ne peut pas faire référence à d'autres\n" +#~ "relations sur le même niveau de la requête" + +#~ msgid "subquery in FROM cannot refer to other relations of same query level" +#~ msgstr "" +#~ "la sous-requête du FROM ne peut pas faire référence à d'autres relations\n" +#~ "dans le même niveau de la requête" + +#~ msgid "JOIN/ON clause refers to \"%s\", which is not part of JOIN" +#~ msgstr "la clause JOIN/ON se réfère à « %s », qui ne fait pas partie du JOIN" + +#~ msgid "window functions not allowed in GROUP BY clause" +#~ msgstr "fonctions window non autorisées dans une clause GROUP BY" + +#~ msgid "aggregates not allowed in WHERE clause" +#~ msgstr "agrégats non autorisés dans une clause WHERE" + +#~ msgid "SELECT FOR UPDATE/SHARE cannot be used with foreign table \"%s\"" +#~ msgstr "SELECT FOR UPDATE/SHARE ne peut pas être utilisé avec une table distante « %s »" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with window functions" +#~ msgstr "SELECT FOR UPDATE/SHARE n'est pas autorisé avec les fonctions window" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with aggregate functions" +#~ msgstr "SELECT FOR UPDATE/SHARE n'est pas autorisé avec les fonctions d'agrégats" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with HAVING clause" +#~ msgstr "SELECT FOR UPDATE/SHARE n'est pas autorisé avec la clause HAVING" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with GROUP BY clause" +#~ msgstr "SELECT FOR UPDATE/SHARE n'est pas autorisé avec la clause GROUP BY" + +#~ msgid "RETURNING cannot contain references to other relations" +#~ msgstr "RETURNING ne doit pas contenir de références à d'autres relations" + +#~ msgid "cannot use window function in RETURNING" +#~ msgstr "ne peut pas utiliser une fonction window dans RETURNING" + +#~ msgid "cannot use aggregate function in RETURNING" +#~ msgstr "ne peut pas utiliser une fonction d'agrégat dans RETURNING" + +#~ msgid "cannot use window function in UPDATE" +#~ msgstr "ne peut pas utiliser une fonction window dans un UPDATE" + +#~ msgid "cannot use aggregate function in UPDATE" +#~ msgstr "ne peut pas utiliser une fonction d'agrégat dans un UPDATE" + +#~ msgid "cannot use window function in VALUES" +#~ msgstr "ne peut pas utiliser la fonction window dans un VALUES" + +#~ msgid "cannot use aggregate function in VALUES" +#~ msgstr "ne peut pas utiliser la fonction d'agrégat dans un VALUES" + +#~ msgid "Use SELECT ... UNION ALL ... instead." +#~ msgstr "Utilisez à la place SELECT ... UNION ALL ..." + +#~ msgid "VALUES must not contain OLD or NEW references" +#~ msgstr "VALUES ne doit pas contenir des références à OLD et NEW" + +#~ msgid "VALUES must not contain table references" +#~ msgstr "VALUES ne doit pas contenir de références de table" + +#~ msgid "LDAP search failed for filter \"%s\" on server \"%s\": user is not unique (%ld matches)" +#~ msgstr "" +#~ "échec de la recherche LDAP pour le filtre « %s » sur le serveur « %s » :\n" +#~ "utilisateur non unique (%ld correspondances)" + +#~ msgid "You need an unconditional ON DELETE DO INSTEAD rule or an INSTEAD OF DELETE trigger." +#~ msgstr "Vous avez besoin d'une règle inconditionnelle ON DELETE DO INSTEAD ou d'un trigger INSTEAD OF DELETE." + +#~ msgid "You need an unconditional ON UPDATE DO INSTEAD rule or an INSTEAD OF UPDATE trigger." +#~ msgstr "Vous avez besoin d'une règle non conditionnelle ON UPDATE DO INSTEAD ou d'un trigger INSTEAD OF UPDATE." + +#~ msgid "You need an unconditional ON INSERT DO INSTEAD rule or an INSTEAD OF INSERT trigger." +#~ msgstr "Vous avez besoin d'une règle ON INSERT DO INSTEAD sans condition ou d'un trigger INSTEAD OF INSERT." + +#~ msgid "automatic vacuum of table \"%s.%s.%s\": cannot (re)acquire exclusive lock for truncate scan" +#~ msgstr "vacuum automatique de la table « %s.%s.%s » : ne peut pas acquérir le verrou exclusif pour la tronquer" + +#~ msgid "must be superuser to rename text search templates" +#~ msgstr "doit être super-utilisateur pour renommer les modèles de recherche plein texte" + +#~ msgid "must be superuser to rename text search parsers" +#~ msgstr "" +#~ "doit être super-utilisateur pour renommer les analyseurs de recherche plein\n" +#~ "texte" + +#~ msgid "cannot use window function in trigger WHEN condition" +#~ msgstr "ne peut pas utiliser la fonction window dans la condition WHEN d'un trigger" + +#~ msgid "Use ALTER FOREIGN TABLE instead." +#~ msgstr "Utilisez ALTER FOREIGN TABLE à la place." + +#~ msgid "cannot use window function in transform expression" +#~ msgstr "ne peut pas utiliser la fonction window dans l'expression de la transformation" + +#~ msgid "default values on foreign tables are not supported" +#~ msgstr "les valeurs par défaut ne sont pas supportées sur les tables distantes" + +#~ msgid "constraints on foreign tables are not supported" +#~ msgstr "les contraintes sur les tables distantes ne sont pas supportées" + +#~ msgid "cannot use window function in EXECUTE parameter" +#~ msgstr "ne peut pas utiliser une fonction window dans le paramètre EXECUTE" + +#~ msgid "cannot use aggregate in index predicate" +#~ msgstr "ne peut pas utiliser un agrégat dans un prédicat d'index" + +#~ msgid "function \"%s\" already exists in schema \"%s\"" +#~ msgstr "la fonction « %s » existe déjà dans le schéma « %s »" + +#~ msgid "Use ALTER AGGREGATE to change owner of aggregate functions." +#~ msgstr "Utiliser ALTER AGGREGATE pour changer le propriétaire des fonctions d'agrégat." + +#~ msgid "Use ALTER AGGREGATE to rename aggregate functions." +#~ msgstr "Utiliser ALTER AGGREGATE pour renommer les fonctions d'agrégat." + +#~ msgid "cannot use window function in parameter default value" +#~ msgstr "ne peut pas utiliser la fonction window dans la valeur par défaut d'un paramètre" + +#~ msgid "cannot use aggregate function in parameter default value" +#~ msgstr "" +#~ "ne peut pas utiliser une fonction d'agrégat dans la valeur par défaut d'un\n" +#~ "paramètre" + +#~ msgid "cannot use subquery in parameter default value" +#~ msgstr "ne peut pas utiliser une sous-requête dans une valeur par défaut d'un paramètre" + +#~ msgid "CREATE TABLE AS specifies too many column names" +#~ msgstr "CREATE TABLE AS spécifie trop de noms de colonnes" + +#~ msgid "%s already exists in schema \"%s\"" +#~ msgstr "%s existe déjà dans le schéma « %s »" + +#~ msgid "A function returning ANYRANGE must have at least one ANYRANGE argument." +#~ msgstr "" +#~ "Une fonction renvoyant ANYRANGE doit avoir au moins un argument du type\n" +#~ "ANYRANGE." + +#~ msgid "cannot use window function in check constraint" +#~ msgstr "ne peut pas utiliser une fonction window dans une contrainte de vérification" + +#~ msgid "cannot use window function in default expression" +#~ msgstr "ne peut pas utiliser une fonction window dans une expression par défaut" + +#~ msgid "uncataloged table %s" +#~ msgstr "table %s sans catalogue" + +#~ msgid "xrecoff \"%X\" is out of valid range, 0..%X" +#~ msgstr "xrecoff « %X » en dehors des limites valides, 0..%X" + +#~ msgid "Incorrect XLOG_BLCKSZ in page header." +#~ msgstr "XLOG_BLCKSZ incorrect dans l'en-tête de page." + +#~ msgid "Incorrect XLOG_SEG_SIZE in page header." +#~ msgstr "XLOG_SEG_SIZE incorrecte dans l'en-tête de page." + +#~ msgid "invalid contrecord length %u in log file %u, segment %u, offset %u" +#~ msgstr "" +#~ "longueur invalide du « contrecord » %u dans le journal de tranasctions %u,\n" +#~ "segment %u, décalage %u" + +#~ msgid "there is no contrecord flag in log file %u, segment %u, offset %u" +#~ msgstr "" +#~ "il n'y a pas de drapeaux « contrecord » dans le journal de transactions %u,\n" +#~ "segment %u, décalage %u" + +#~ msgid "could not open file \"%s\" (log file %u, segment %u): %m" +#~ msgstr "n'a pas pu ouvrir le fichier « %s » (journal de transactions %u, segment %u) : %m" + +#~ msgid "unlogged GiST indexes are not supported" +#~ msgstr "les index GiST non tracés ne sont pas supportés" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" + +#~ msgid "Perhaps out of disk space?" +#~ msgstr "Peut-être manquez-vous de place disque ?" + +#~ msgid "time zone offset %d is not a multiple of 900 sec (15 min) in time zone file \"%s\", line %d" +#~ msgstr "" +#~ "le décalage %d du fuseau horaire n'est pas un multiples de 900 secondes\n" +#~ "(15 minutes) dans le fichier des fuseaux horaires « %s », ligne %d" + +#~ msgid "Sets the name of the Kerberos service." +#~ msgstr "Initialise le nom du service Kerberos." + +#~ msgid "No description available." +#~ msgstr "Aucune description disponible." + +#~ msgid "cannot call json_populate_recordset on a nested object" +#~ msgstr "ne peut pas appeler json_populate_recordset sur un objet imbriqué" + +#~ msgid "cannot call json_populate_recordset on a scalar" +#~ msgstr "ne peut pas appeler json_populate_recordset sur un scalaire" + +#~ msgid "cannot call json_populate_recordset with nested arrays" +#~ msgstr "ne peut pas appeler json_populate_recordset avec des tableaux imbriqués" + +#~ msgid "must call json_populate_recordset on an array of objects" +#~ msgstr "doit appeler json_populate_recordset sur un tableau d'objets" + +#~ msgid "cannot call json_populate_recordset with nested objects" +#~ msgstr "ne peut pas appeler json_populate_recordset sur des objets imbriqués" + +#~ msgid "cannot call json_populate_recordset on an object" +#~ msgstr "ne peut pas appeler json_populate_recordset sur un objet" + +#~ msgid "first argument of json_populate_recordset must be a row type" +#~ msgstr "le premier argument de json_populate_recordset doit être un type ROW" + +#~ msgid "first argument of json_populate_record must be a row type" +#~ msgstr "le premier argument de json_populate_record doit être un type ROW" + +#~ msgid "cannot call json_array_elements on a scalar" +#~ msgstr "ne peut pas appeler json_array_elements sur un scalaire" + +#~ msgid "cannot call json_array_elements on a non-array" +#~ msgstr "ne peut pas appeler json_array_elements sur un objet qui n'est pas un tableau" + +#~ msgid "cannot extract field from a non-object" +#~ msgstr "ne peut pas extraire le chemin à partir d'un non-objet" + +#~ msgid "cannot extract array element from a non-array" +#~ msgstr "ne peut pas extraire un élément du tableau à partir d'un objet qui n'est pas un tableau" + +#~ msgid "cannot call json_object_keys on an array" +#~ msgstr "ne peut pas appeler json_object_keys sur un tableau" + +#~ msgid "missing assignment operator" +#~ msgstr "opérateur d'affectation manquant" + +#~ msgid "wrong affix file format for flag" +#~ msgstr "mauvais format de fichier affixe pour le drapeau" + +#~ msgid "Views that return the same column more than once are not automatically updatable." +#~ msgstr "Les vues qui renvoient la même colonne plus d'une fois ne sont pas automatiquement disponibles en écriture." + +#~ msgid "Security-barrier views are not automatically updatable." +#~ msgstr "Les vues avec barrière de sécurité ne sont pas automatiquement disponibles en écriture." + +#~ msgid "Expected 1 tuple with 3 fields, got %d tuples with %d fields." +#~ msgstr "Attendait 1 ligne avec 3 champs, a obtenu %d lignes avec %d champs." + +#~ msgid "%s: could not determine user name (GetUserName failed)\n" +#~ msgstr "%s : n'a pas pu déterminer le nom de l'utilisateur (GetUserName a échoué)\n" + +#~ msgid "%s: invalid effective UID: %d\n" +#~ msgstr "%s : UID effectif invalide : %d\n" + +#~ msgid "krb5 authentication is not supported on local sockets" +#~ msgstr "" +#~ "l'authentification krb5 n'est pas supportée sur les connexions locales par\n" +#~ "socket" + +#~ msgid "SSL renegotiation failure" +#~ msgstr "échec lors de la re-négotiation SSL" + +#~ msgid "local user with ID %d does not exist" +#~ msgstr "l'utilisateur local dont l'identifiant est %d n'existe pas" + +#~ msgid "Kerberos unparse_name returned error %d" +#~ msgstr "unparse_name de Kerberos a renvoyé l'erreur %d" + +#~ msgid "Kerberos recvauth returned error %d" +#~ msgstr "recvauth de Kerberos a renvoyé l'erreur %d" + +#~ msgid "Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d" +#~ msgstr "sname_to_principal(« %s », « %s ») de Kerberos a renvoyé l'erreur %d" + +#~ msgid "Kerberos keytab resolving returned error %d" +#~ msgstr "la résolution keytab de Kerberos a renvoyé l'erreur %d" + +#~ msgid "Kerberos initialization returned error %d" +#~ msgstr "l'initialisation de Kerberos a retourné l'erreur %d" + +#~ msgid "Kerberos 5 authentication failed for user \"%s\"" +#~ msgstr "authentification Kerberos 5 échouée pour l'utilisateur « %s »" + +#~ msgid "trigger \"%s\" for table \"%s\" does not exist, skipping" +#~ msgstr "le trigger « %s » pour la table « %s » n'existe pas, poursuite du traitement" + +#~ msgid "invalid input syntax for transaction log location: \"%s\"" +#~ msgstr "syntaxe invalide en entrée pour l'emplacement du journal de transactions : « %s »" + +#~ msgid "could not parse transaction log location \"%s\"" +#~ msgstr "n'a pas pu analyser l'emplacement du journal des transactions « %s »" + +#~ msgid "%s \"%s\": return code %d" +#~ msgstr "%s « %s » : code de retour %d" + +#~ msgid "assertion checking is not supported by this build" +#~ msgstr "la vérification de l'assertion n'a pas été intégrée lors de la compilation" + +#~ msgid "Set the amount of traffic to send and receive before renegotiating the encryption keys." +#~ msgstr "" +#~ "Configure la quantité de trafic à envoyer et recevoir avant la renégotiation\n" +#~ "des clés d'enchiffrement." + +#~ msgid "Sets the maximum distance in log segments between automatic WAL checkpoints." +#~ msgstr "" +#~ "Initialise la distance maximale dans les journaux de transaction entre chaque\n" +#~ "point de vérification (checkpoints) des journaux." + +#~ msgid "It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-vintage clients." +#~ msgstr "" +#~ "C'est ici uniquement pour ne pas avoir de problèmes avec le SET AUTOCOMMIT\n" +#~ "TO ON des clients 7.3." + +#~ msgid "This parameter doesn't do anything." +#~ msgstr "Ce paramètre ne fait rien." + +#~ msgid "This is a debugging aid." +#~ msgstr "C'est une aide de débogage." + +#~ msgid "Turns on various assertion checks." +#~ msgstr "Active les différentes vérifications des assertions." + +#~ msgid "cannot accept a value of type pg_node_tree" +#~ msgstr "ne peut pas accepter une valeur de type pg_node_tree" + +#~ msgid "must be superuser or have the same role to terminate other server processes" +#~ msgstr "" +#~ "doit être super-utilisateur ou avoir le même rôle pour fermer les connexions\n" +#~ "exécutées dans les autres processus serveur" + +#~ msgid "must be superuser or have the same role to cancel queries running in other server processes" +#~ msgstr "" +#~ "doit être super-utilisateur ou avoir le même rôle pour annuler des requêtes\n" +#~ "exécutées dans les autres processus serveur" + +#~ msgid "invalid symbol" +#~ msgstr "symbole invalide" + +#~ msgid "unexpected \"=\"" +#~ msgstr "« = » inattendu" + +#~ msgid "neither input type is an array" +#~ msgstr "aucun type de données n'est un tableau" + +#~ msgid "could not determine input data types" +#~ msgstr "n'a pas pu déterminer les types de données en entrée" + +#~ msgid "archive member \"%s\" too large for tar format" +#~ msgstr "membre « %s » de l'archive trop volumineux pour le format tar" + +#~ msgid "postmaster became multithreaded" +#~ msgstr "le postmaster est devenu multithreadé" + +#~ msgid "invalid value for parameter \"replication\"" +#~ msgstr "valeur invalide pour le paramètre « replication »" + +#~ msgid "WAL archival (archive_mode=on) requires wal_level \"archive\", \"hot_standby\", or \"logical\"" +#~ msgstr "" +#~ "l'archivage des journaux de transactions (archive_mode=on) nécessite que\n" +#~ "le paramètre wal_level soit initialisé avec « archive », « hot_standby » ou « logical »" + +#~ msgid "Consider increasing the configuration parameter \"checkpoint_segments\"." +#~ msgstr "Considèrez l'augmentation du paramètre « checkpoint_segments »." + +#~ msgid "subquery must return a column" +#~ msgstr "la sous-requête doit renvoyer une colonne" + +#~ msgid " -A 1|0 enable/disable run-time assert checking\n" +#~ msgstr "" +#~ " -A 1|0 active/désactive la vérification des limites (assert) à\n" +#~ " l'exécution\n" + +#~ msgid "%s: setsysinfo failed: %s\n" +#~ msgstr "%s : setsysinfo a échoué : %s\n" + +#~ msgid "could not set socket to blocking mode: %m" +#~ msgstr "n'a pas pu activer le mode bloquant pour la socket : %m" + +#~ msgid "SSL failed to renegotiate connection before limit expired" +#~ msgstr "SSL a échoué à renégotier la connexion avant l'expiration du délai" + +#~ msgid "could not complete SSL handshake on renegotiation, too many failures" +#~ msgstr "n'a pas pu terminer la poignée de main de renégotiation, trop d'échecs" + +#~ msgid "SSL handshake failure on renegotiation, retrying" +#~ msgstr "échec du handshake SSL lors de la renégotiation, nouvelle tentative" + +#~ msgid "SSL failure during renegotiation start" +#~ msgstr "échec SSL au début de la re-négotiation" + +#~ msgid "received password packet" +#~ msgstr "paquet du mot de passe reçu" + +#~ msgid "interval precision specified twice" +#~ msgstr "précision d'intervalle spécifiée deux fois" + +#~ msgid "" +#~ "%.0f dead row versions cannot be removed yet.\n" +#~ "There were %.0f unused item pointers.\n" +#~ "%u pages are entirely empty.\n" +#~ "%s." +#~ msgstr "" +#~ "%.0f versions de lignes mortes ne peuvent pas encore être supprimées.\n" +#~ "Il y avait %.0f pointeurs d'éléments inutilisés.\n" +#~ "%u pages sont entièrement vides.\n" +#~ "%s." + +#~ msgid "" +#~ "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +#~ "pages: %d removed, %d remain\n" +#~ "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n" +#~ "buffer usage: %d hits, %d misses, %d dirtied\n" +#~ "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +#~ "system usage: %s" +#~ msgstr "" +#~ "VACUUM automatique de la table « %s.%s.%s » : parcours d'index : %d\n" +#~ "pages : %d supprimées, %d restantes\n" +#~ "lignes : %.0f supprimées, %.0f restantes, %.0f sont mortes mais non supprimables\n" +#~ "utilisation des tampons : %d lus dans le cache, %d lus hors du cache, %d modifiés\n" +#~ "taux moyen de lecture : %.3f Mo/s, taux moyen d'écriture : %.3f Mo/s\n" +#~ "utilisation système : %s" + +#~ msgid "Specify a USING expression to perform the conversion." +#~ msgstr "Donnez une expression USING pour réaliser la conversion." + +#~ msgid "\"%s\" is not a table, materialized view, composite type, or foreign table" +#~ msgstr "« %s » n'est ni une table, ni une vue matérialisée, ni un type composite, ni une table distante" + +#~ msgid "This name may be disallowed altogether in future versions of PostgreSQL." +#~ msgstr "Ce nom pourrait être interdit dans les prochaines versions de PostgreSQL." + +#~ msgid "=> is deprecated as an operator name" +#~ msgstr "=> est un nom d'opérateur obsolète" + +#~ msgid "WAL file is from different database system: Incorrect XLOG_BLCKSZ in page header." +#~ msgstr "" +#~ "le journal de transactions provient d'un système de bases de données différent :\n" +#~ "XLOG_BLCKSZ incorrect dans l'en-tête de page." + +#~ msgid "WAL file is from different database system: Incorrect XLOG_SEG_SIZE in page header." +#~ msgstr "" +#~ "le journal de transactions provient d'un système de bases de données différent :\n" +#~ "XLOG_SEG_SIZE incorrect dans l'en-tête de page." + +#~ msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s." +#~ msgstr "" +#~ "L'identifiant du journal de transactions du système de base de données est %s,\n" +#~ "l'identifiant pg_control du système de base de données dans pg_control est %s." + +#~ msgid "incorrect total length in record at %X/%X" +#~ msgstr "longueur totale incorrecte à l'enregistrement %X/%X" + +#~ msgid "incorrect hole size in record at %X/%X" +#~ msgstr "taille du trou incorrect à l'enregistrement %X/%X" + +#~ msgid "invalid backup block size in record at %X/%X" +#~ msgstr "taille du bloc de sauvegarde invalide dans l'enregistrement à %X/%X" + +#~ msgid "record with zero length at %X/%X" +#~ msgstr "enregistrement de longueur nulle à %X/%X" + +#~ msgid "invalid xlog switch record at %X/%X" +#~ msgstr "enregistrement de basculement du journal de transaction invalide à %X/%X" + +#~ msgid "oldest unfrozen transaction ID: %u, in database %u" +#~ msgstr "" +#~ "identifiant de transaction non gelé le plus ancien : %u, dans la base de\n" +#~ "données %u" + +#~ msgid "next MultiXactId: %u; next MultiXactOffset: %u" +#~ msgstr "prochain MultiXactId : %u ; prochain MultiXactOffset : %u" + +#~ msgid "next transaction ID: %u/%u; next OID: %u" +#~ msgstr "prochain identifiant de transaction : %u/%u ; prochain OID : %u" + +#~ msgid "redo record is at %X/%X; shutdown %s" +#~ msgstr "l'enregistrement à ré-exécuter se trouve à %X/%X ; arrêt %s" + +#~ msgid "invalid value for recovery parameter \"recovery_target\"" +#~ msgstr "valeur invalide pour le paramètre de restauration « recovery_target »" + +#~ msgid "unrecognized win32 error code: %lu" +#~ msgstr "code d'erreur win32 non reconnu : %lu" + +#~ msgid "mapped win32 error code %lu to %d" +#~ msgstr "correspondance du code d'erreur win32 %lu en %d" + +#~ msgid "too few arguments for format" +#~ msgstr "trop peu d'arguments pour le format" + +#~ msgid "invalid length in external \"numeric\" value" +#~ msgstr "longueur invalide dans la valeur externe « numeric »" + +#~ msgid "time zone abbreviation \"%s\" is not used in time zone \"%s\"" +#~ msgstr "l'abréviation « %s » du fuseau horaire n'est pas utilisée dans le fuseau horaire « %s »" + +#~ msgid "role \"%s\" is reserved" +#~ msgstr "le rôle « %s » est réservé" + +#~ msgid "system columns cannot be used in an ON CONFLICT clause" +#~ msgstr "les colonnes systèmes ne peuvent pas être utilisées dans une clause ON CONFLICT" + +#~ msgid "function returning set of rows cannot return null value" +#~ msgstr "" +#~ "la fonction renvoyant un ensemble de lignes ne peut pas renvoyer une valeur\n" +#~ "NULL" + +#~ msgid "Only superusers can use untrusted languages." +#~ msgstr "" +#~ "Seuls les super-utilisateurs peuvent utiliser des langages qui ne sont pas\n" +#~ "de confiance." + +#~ msgid "huge TLB pages not supported on this platform" +#~ msgstr "Huge Pages TLB non supporté sur cette plateforme." + +#~ msgid "Lower bound of dimension array must be one." +#~ msgstr "La limite inférieure du tableau doit valoir un." + +#~ msgid "aborted" +#~ msgstr "annulé" + +#~ msgid "committed" +#~ msgstr "validé" + +#~ msgid "in progress" +#~ msgstr "en cours" + +#~ msgid "transaction ID " +#~ msgstr "ID de transaction " + +#~ msgid "invalid input syntax for %s: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type %s : « %s »" + +#~ msgid "User \"%s\" has an empty password." +#~ msgstr "L'utilisateur « %s » a un mot de passe vide." + +#~ msgid "removed subscription for table %s.%s" +#~ msgstr "a supprimé une souscription pour la table %s.%s" + +#~ msgid "added subscription for table %s.%s" +#~ msgstr "souscription ajoutée pour la table %s.%s" + +#~ msgid "column \"%s\" referenced in statistics does not exist" +#~ msgstr "la colonne « %s » référencée dans les statistiques n'existe pas" + +#~ msgid "invalid publish list" +#~ msgstr "liste de publication invalide" + +#~ msgid "could not get keyword values for locale \"%s\": %s" +#~ msgstr "n'a pas pu obtenir les valeurs des mots clés pour la locale « %s » : %s" + +#~ msgid "cannot create range partition with empty range" +#~ msgstr "ne peut pas créer une partition par intervalle avec un intervalle vide" + +#~ msgid "When more tuples than this are present, quicksort will be used." +#~ msgstr "Quand plus de lignes que ça sont présentes, quicksort sera utilisé." + +#~ msgid "Sets the maximum number of tuples to be sorted using replacement selection." +#~ msgstr "Configure le nombre maximum de lignes à trier en utilisant la sélection de remplacement." + +#~ msgid "must be superuser to get directory listings" +#~ msgstr "doit être super-utilisateur pour obtenir le contenu du répertoire" + +#~ msgid "must be superuser to get file information" +#~ msgstr "doit être super-utilisateur pour obtenir des informations sur le fichier" + +#~ msgid "could not open tablespace directory \"%s\": %m" +#~ msgstr "n'a pas pu ouvrir le répertoire du tablespace « %s » : %m" + +#~ msgid "There might be an idle transaction or a forgotten prepared transaction causing this." +#~ msgstr "" +#~ "Il pourait y avoir une transaction en attente ou une transaction préparée\n" +#~ "oubliée causant cela." + +#~ msgid "memory for serializable conflict tracking is nearly exhausted" +#~ msgstr "la mémoire pour tracer les conflits sérialisables est pratiquement pleine" + +#~ msgid "logical replication could not find row for delete in replication target relation \"%s\"" +#~ msgstr "la réplication logique n'a pas pu trouver la ligne à supprimer dans la relation cible de réplication %s" + +#~ msgid "data type \"%s.%s\" required for logical replication does not exist" +#~ msgstr "le type de données « %s/%s » requis par la réplication logique n'existe pas" + +#~ msgid "This can be caused by having a publisher with a higher PostgreSQL major version than the subscriber." +#~ msgstr "Ceci peut avoir pour cause un publieur ayant une version majeure de PostgreSQL supérieure à l'abonné" + +#~ msgid "built-in type %u not found" +#~ msgstr "type interne %u non trouvé" + +#~ msgid "worker process" +#~ msgstr "processus de travail" + +#~ msgid "data directory \"%s\" has group or world access" +#~ msgstr "" +#~ "le répertoire des données « %s » est accessible par le groupe et/ou par les\n" +#~ "autres" + +#~ msgid "%s: max_wal_senders must be less than max_connections\n" +#~ msgstr "%s : max_wal_senders doit être inférieur à max_connections\n" + +#~ msgid "could not open archive status directory \"%s\": %m" +#~ msgstr "n'a pas pu accéder au répertoire du statut des archives « %s » : %m" + +#~ msgid "foreign key constraints are not supported on partitioned tables" +#~ msgstr "les clés étrangères ne sont pas supportées sur les tables partitionnées" + +#~ msgid "ON CONFLICT clause is not supported with partitioned tables" +#~ msgstr "la clause ON CONFLICT n'est pas supporté avec les tables partitionnées" + +#~ msgid "Anyone can use the client-side lo_export() provided by libpq." +#~ msgstr "Tout le monde peut utiliser lo_export(), fournie par libpq, du côté client." + +#~ msgid "must be superuser to use server-side lo_export()" +#~ msgstr "doit être super-utilisateur pour utiliser lo_export() du côté serveur" + +#~ msgid "Anyone can use the client-side lo_import() provided by libpq." +#~ msgstr "Tout le monde peut utiliser lo_import(), fourni par libpq, du côté client." + +#~ msgid "must be superuser to use server-side lo_import()" +#~ msgstr "doit être super-utilisateur pour utiliser lo_import() du côté serveur" + +#~ msgid "client requires SCRAM channel binding, but it is not supported" +#~ msgstr "le client requiert le lien de canal SCRAM mais ceci n'est pas supporté" + +#~ msgid "RANGE FOLLOWING is only supported with UNBOUNDED" +#~ msgstr "RANGE FOLLOWING est seulement supporté avec UNBOUNDED" + +#~ msgid "RANGE PRECEDING is only supported with UNBOUNDED" +#~ msgstr "RANGE PRECEDING est seulement supporté avec UNBOUNDED" + +#~ msgid "combine function for aggregate %u must be declared as STRICT" +#~ msgstr "la fonction d'unification pour l'aggrégat %u doit être déclarée comme STRICT" + +#~ msgid "Close open transactions soon to avoid wraparound problems." +#~ msgstr "" +#~ "Fermez les transactions ouvertes rapidement pour éviter des problèmes de\n" +#~ "réinitialisation." + +#~ msgid "column \"%s\" appears more than once in partition key" +#~ msgstr "la colonne « %s » apparaît plus d'une fois dans la clé de partitionnement" + +#~ msgid "operator procedure must be specified" +#~ msgstr "la procédure de l'opérateur doit être spécifiée" + +#~ msgid "procedure number %d for (%s,%s) appears more than once" +#~ msgstr "le numéro de procédure %d pour (%s, %s) apparaît plus d'une fois" + +#~ msgid "invalid procedure number %d, must be between 1 and %d" +#~ msgstr "numéro de procédure %d invalide, doit être compris entre 1 et %d" + +#~ msgid "transform function must not be an aggregate function" +#~ msgstr "la fonction de transformation ne doit pas être une fonction d'agrégat" + +#~ msgid "unrecognized function attribute \"%s\" ignored" +#~ msgstr "l'attribut « %s » non reconnu de la fonction a été ignoré" + +#~ msgid "cannot route inserted tuples to a foreign table" +#~ msgstr "ne peut pas envoyer les lignes insérées dans une table distante" + +#~ msgid "cannot copy to foreign table \"%s\"" +#~ msgstr "ne peut pas copier vers la table distante « %s »" + +#~ msgid "must be superuser to COPY to or from a file" +#~ msgstr "doit être super-utilisateur pour utiliser COPY à partir ou vers un fichier" + +#~ msgid "function \"%s\" is not a window function" +#~ msgstr "la fonction « %s » n'est pas une fonction window" + +#~ msgid "function \"%s\" is not an aggregate function" +#~ msgstr "la fonction « %s » n'est pas une fonction d'agrégat" + +#~ msgid "function \"%s\" is an aggregate function" +#~ msgstr "la fonction « %s » est une fonction d'agrégat" + +#~ msgid "\"%s\" is already an attribute of type %s" +#~ msgstr "« %s » est déjà un attribut du type %s" + +#~ msgid "domain %s has multiple constraints named \"%s\"" +#~ msgstr "le domaine %s a plusieurs contraintes nommées « %s »" + +#~ msgid "table \"%s\" has multiple constraints named \"%s\"" +#~ msgstr "la table « %s » a de nombreuses contraintes nommées « %s »" + +#~ msgid "%s in publication %s" +#~ msgstr "%s dans la publication %s" + +#~ msgid " in schema %s" +#~ msgstr " dans le schéma %s" + +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "le fichier WAL provient d'un système différent : XLOG_SEG_SIZE invalide dans l'en-tête de page" + +#~ msgid "invalid length of secondary checkpoint record" +#~ msgstr "longueur invalide de l'enregistrement secondaire du point de vérification" + +#~ msgid "invalid xl_info in secondary checkpoint record" +#~ msgstr "xl_info invalide dans l'enregistrement du point de vérification secondaire" + +#~ msgid "invalid resource manager ID in secondary checkpoint record" +#~ msgstr "identifiant du gestionnaire de ressource invalide dans l'enregistrement secondaire du point de vérification" + +#~ msgid "invalid secondary checkpoint record" +#~ msgstr "enregistrement du point de vérification secondaire invalide" + +#~ msgid "invalid secondary checkpoint link in control file" +#~ msgstr "lien du point de vérification secondaire invalide dans le fichier de contrôle" + +#~ msgid "using previous checkpoint record at %X/%X" +#~ msgstr "utilisation du précédent enregistrement d'un point de vérification à %X/%X" + +#~ msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." +#~ msgstr "" +#~ "Le cluster de bases de données a été initialisé avec un XLOG_SEG_SIZE à %d\n" +#~ "alors que le serveur a été compilé avec un XLOG_SEG_SIZE à %d." + +#~ msgid "could not open write-ahead log directory \"%s\": %m" +#~ msgstr "n'a pas pu ouvrir le répertoire des journaux de transactions « %s » : %m" + +#~ msgid "no such savepoint" +#~ msgstr "aucun point de sauvegarde" + +#~ msgid "%s cannot be executed from a function or multi-command string" +#~ msgstr "" +#~ "%s ne peut pas être exécuté à partir d'une fonction ou d'une chaîne\n" +#~ "contenant plusieurs commandes" + +#~ msgid "could not open BufFile \"%s\"" +#~ msgstr "n'a pas pu ouvrir le BufFile « %s »" + +#~ msgid "parameter \"%s\" requires a numeric value" +#~ msgstr "le paramètre « %s » requiert une valeur numérique" + +#~ msgid "Create new tables with OIDs by default." +#~ msgstr "Crée des nouvelles tables avec des OID par défaut." + +#~ msgid "could not close relation mapping file \"%s\": %m" +#~ msgstr "n'a pas pu fermer le fichier de correspondance des relations « %s » : %m" + +#~ msgid "could not fsync relation mapping file \"%s\": %m" +#~ msgstr "n'a pas pu synchroniser (fsync) le fichier de correspondance des relations « %s » : %m" + +#~ msgid "could not write to relation mapping file \"%s\": %m" +#~ msgstr "n'a pas pu écrire le fichier de correspondance des relations « %s » : %m" + +#~ msgid "could not read relation mapping file \"%s\": %m" +#~ msgstr "n'a pas pu lire le fichier de correspondance des relations « %s » : %m" + +#~ msgid "invalid input syntax for numeric time zone: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le fuseau horaire numérique : « %s »" + +#~ msgid "date/time value \"%s\" is no longer supported" +#~ msgstr "la valeur date/time « %s » n'est plus supportée" + +#~ msgid "regexp_split_to_array does not support the global option" +#~ msgstr "regexp_split_to_array ne supporte pas l'option globale" + +#~ msgid "regexp_split_to_table does not support the global option" +#~ msgstr "regexp_split_to_table ne supporte pas l'option globale" + +#~ msgid "invalid regexp option: \"%c\"" +#~ msgstr "option invalide de l'expression rationnelle : « %c »" + +#~ msgid "ucnv_fromUChars failed: %s" +#~ msgstr "échec de ucnv_fromUChars : %s" + +#~ msgid "ucnv_toUChars failed: %s" +#~ msgstr "échec de ucnv_toUChars : %s" + +#~ msgid "cannot convert reltime \"invalid\" to interval" +#~ msgstr "ne peut pas convertir reltime « invalid » en interval" + +#~ msgid "invalid status in external \"tinterval\" value" +#~ msgstr "statut invalide dans la valeur externe « tinterval »" + +#~ msgid "cannot convert abstime \"invalid\" to timestamp" +#~ msgstr "ne peut pas convertir un abstime « invalid » en timestamp" + +#~ msgid "invalid time zone name: \"%s\"" +#~ msgstr "nom du fuseau horaire invalide : « %s »" + +#~ msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +#~ msgstr "Considérer l'utilisation de pg_logfile_rotate(), qui est présent par défaut, à la place." + +#~ msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +#~ msgstr "Les arguments de jsonb_build_object() doivent consister en des clés et valeurs alternées" + +#~ msgid "invalid input syntax for integer: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour l'entier : « %s »" + +#~ msgid "cannot convert empty polygon to circle" +#~ msgstr "ne peut pas convertir un polygône vide en cercle" + +#~ msgid "cannot create bounding box for empty polygon" +#~ msgstr "ne peut pas créer une boîte entourée pour un polygône vide" + +#~ msgid "could not determine which collation to use for initcap() function" +#~ msgstr "n'a pas pu déterminer le collationnement à utiliser pour la fonction initcap()" + +#~ msgid "could not determine which collation to use for upper() function" +#~ msgstr "n'a pas pu déterminer le collationnement à utiliser pour la fonction upper()" + +#~ msgid "abstime out of range for date" +#~ msgstr "abstime en dehors des limites pour une date" + +#~ msgid "cannot convert reserved abstime value to date" +#~ msgstr "ne peut pas convertir la valeur réservée abstime en date" + +#~ msgid "date/time value \"current\" is no longer supported" +#~ msgstr "la valeur « current » pour la date et heure n'est plus supportée" + +#~ msgid "could not seek to block %u in file \"%s\": %m" +#~ msgstr "n'a pas pu trouver le bloc %u dans le fichier « %s » : %m" + +#~ msgid "corrupted item pointer: offset = %u, length = %u" +#~ msgstr "pointeur d'élément corrompu : décalage = %u, longueur = %u" + +#~ msgid "poll() failed: %m" +#~ msgstr "échec de poll() : %m" + +#~ msgid "epoll_wait() failed: %m" +#~ msgstr "échec de epoll_wait() : %m" + +#~ msgid "epoll_ctl() failed: %m" +#~ msgstr "échec de epoll_ctl() : %m" + +#~ msgid "Set dynamic_shared_memory_type to a value other than \"none\"." +#~ msgstr "Configurez dynamic_shared_memory_type à une valeur autre que « none »." + +#~ msgid "could not rmdir directory \"%s\": %m" +#~ msgstr "n'a pas pu supprimer le répertoire « %s » : %m" + +#~ msgid "invalid MVNDistinct size %zd (expected at least %zd)" +#~ msgstr "taille MVNDistinct %zd invalide (attendue au moins %zd)" + +#~ msgid "invalid zero-length item array in MVNDistinct" +#~ msgstr "tableau d'élément de longueur zéro invalide dans MVNDistinct" + +#~ msgid "invalid ndistinct type %d (expected %d)" +#~ msgstr "type ndistinct invalide %d (%d attendu)" + +#~ msgid "invalid ndistinct magic %08x (expected %08x)" +#~ msgstr "nombre magique ndistinct invalide %08x (attendu %08x)" + +#~ msgid "invalid zero-length item array in MVDependencies" +#~ msgstr "tableau d'éléments de longueur zéro invalide dans MVDependencies" + +#~ msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" +#~ msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT ne doit pas être appelé dans une sous-transaction" + +#~ msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" +#~ msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT doit être appelé avant toute requête" + +#~ msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" +#~ msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT doit être appelé dans une transaction" + +#~ msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" +#~ msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT ne doit pas être appelé dans une sous-transaction" + +#~ msgid "could not read file \"%s\", read %d of %u: %m" +#~ msgstr "n'a pas pu lire le fichier « %s », a lu %d sur %u : %m" + +#~ msgid "could not read file \"%s\", read %d of %d: %m" +#~ msgstr "n'a pas pu lire le fichier « %s », lu %d sur %d : %m" + +#~ msgid "replication identifier %d is already active for PID %d" +#~ msgstr "l'identificateur de réplication %d est déjà actif pour le PID %d" + +#~ msgid "could not stat control file \"%s\": %m" +#~ msgstr "n'a pas pu récupérer des informations sur le fichier de contrôle « %s » : %m" + +#~ msgid "%s (PID %d) was terminated by signal %d" +#~ msgstr "%s (PID %d) a été arrêté par le signal %d" + +#~ msgid "pg_ident.conf was not reloaded" +#~ msgstr "pg_ident.conf n'a pas été rechargé" + +#~ msgid "archive command was terminated by signal %d" +#~ msgstr "la commande d'archivage a été terminée par le signal %d" + +#~ msgid "Try putting the literal value in single quotes." +#~ msgstr "Placer la valeur littérale en guillemets simples." + +#~ msgid "The cast requires a non-immutable conversion." +#~ msgstr "Cette conversion requiert une conversion non immutable." + +#~ msgid "DROP ASSERTION is not yet implemented" +#~ msgstr "DROP ASSERTION n'est pas encore implémenté" + +#~ msgid "tuple to be updated was already moved to another partition due to concurrent update" +#~ msgstr "la ligne à mettre à jour était déjà déplacée vers une autre partition du fait d'une mise à jour concurrente, nouvelle tentative" + +#~ msgid "tuple to be deleted was already moved to another partition due to concurrent update" +#~ msgstr "la ligne à supprimer était déjà déplacée vers une autre partition du fait d'une mise à jour concurrente" + +#~ msgid "logical replication target relation \"%s.%s\" is not a table" +#~ msgstr "la relation cible de la réplication logique « %s.%s » n'est pas une table" + +#~ msgid "relation \"%s\" page %u is uninitialized --- fixing" +#~ msgstr "relation « %s » : la page %u n'est pas initialisée --- correction en cours" + +#~ msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" +#~ msgstr "ne peut pas attacher la table « %s » avec OID comme partition de la table « %s » sans OID" + +#~ msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" +#~ msgstr "ne peut pas attacher la table « %s » sans OID comme partition de la table « %s » avec OID" + +#~ msgid "data type %s has no default btree operator class" +#~ msgstr "le type de données %s n'a pas de classe d'opérateurs btree par défaut" + +#~ msgid "data type %s has no default hash operator class" +#~ msgstr "le type de données %s n'a pas de classe d'opérateurs hash par défaut" + +#~ msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +#~ msgstr "la table « %s » qui n'a pas d'OID ne peut pas hériter de la table « %s » qui en a" + +#~ msgid "cannot alter type of column referenced in partition key expression" +#~ msgstr "ne peut pas utiliser le type d'une colonne référencée dans l'expression d'une clé de partitionnement" + +#~ msgid "cannot alter type of column named in partition key" +#~ msgstr "ne peut pas modifier le type d'une colonne nommée dans une clé de partitionnement" + +#~ msgid "cannot reference partitioned table \"%s\"" +#~ msgstr "ne peut pas référencer la table partitionnée « %s »" + +#~ msgid "cannot drop column named in partition key" +#~ msgstr "ne peut pas supprimer une colonne nommée dans une clé de partitionnement" + +#~ msgid "child table \"%s\" has a conflicting \"%s\" column" +#~ msgstr "la table fille « %s » a une colonne conflictuelle, « %s »" + +#~ msgid "cannot create table with OIDs as partition of table without OIDs" +#~ msgstr "ne peut pas créer une table avec OID comme partition d'une table sans OID" + +#~ msgid "subscription with slot_name = NONE must also set create_slot = false" +#~ msgstr "la souscription avec slot_name = NONE doit aussi être configurée avec create_slot = false" + +#~ msgid "slot_name = NONE and create_slot = true are mutually exclusive options" +#~ msgstr "slot_name = NONE et create_slot = true sont des options mutuellement exclusives" + +#~ msgid "slot_name = NONE and enabled = true are mutually exclusive options" +#~ msgstr "slot_name = NONE et enabled = true sont des options mutuellement exclusives" + +#~ msgid "connect = false and copy_data = true are mutually exclusive options" +#~ msgstr "connect = false et copy_data = true sont des options mutuellement exclusives" + +#~ msgid "connect = false and create_slot = true are mutually exclusive options" +#~ msgstr "connect = false et create_slot = true sont des options mutuellement exclusives" + +#~ msgid "\"%s\" is not a table or a view" +#~ msgstr "« %s » n'est pas une table ou une vue" + +#~ msgid "server does not exist, skipping" +#~ msgstr "le serveur n'existe pas, poursuite du traitement" + +#~ msgid "invalid OID in COPY data" +#~ msgstr "OID invalide dans les données du COPY" + +#~ msgid "null OID in COPY data" +#~ msgstr "OID NULL dans les données du COPY" + +#~ msgid "missing data for OID column" +#~ msgstr "données manquantes pour la colonne OID" + +#~ msgid "table \"%s\" does not have OIDs" +#~ msgstr "la table « %s » n'a pas d'OID" + +#~ msgid "shared tables cannot be toasted after initdb" +#~ msgstr "" +#~ "les tables partagées ne peuvent pas avoir une table TOAST après la commande\n" +#~ "initdb" + +#~ msgid "pg_walfile_name() cannot be executed during recovery." +#~ msgstr "pg_walfile_name() ne peut pas être exécuté lors de la restauration." + +#~ msgid "pg_walfile_name_offset() cannot be executed during recovery." +#~ msgstr "pg_walfile_name_offset() ne peut pas être exécuté lors de la restauration." + +#~ msgid "could not fdatasync log file %s: %m" +#~ msgstr "n'a pas pu synchroniser sur disque (fdatasync) le journal de transactions %s : %m" + +#~ msgid "could not fsync log file %s: %m" +#~ msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier de transactions « %s » : %m" + +#~ msgid "could not fsync log segment %s: %m" +#~ msgstr "n'a pas pu synchroniser sur disque (fsync) le segment du journal des transactions %s : %m" + +#~ msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." +#~ msgstr "" +#~ "Si vous n'avez pas pu restaurer une sauvegarde, essayez de supprimer le\n" +#~ "fichier « %s/backup_label »." + +#~ msgid "unrecognized recovery parameter \"%s\"" +#~ msgstr "paramètre de restauration « %s » non reconnu" + +#~ msgid "parameter \"%s\" requires a temporal value" +#~ msgstr "le paramètre « %s » requiert une valeur temporelle" + +#~ msgid "recovery_target_time is not a valid timestamp: \"%s\"" +#~ msgstr "recovery_target_timeline n'est pas un horodatage valide : « %s »" + +#~ msgid "recovery_target_xid is not a valid number: \"%s\"" +#~ msgstr "recovery_target_xid n'est pas un nombre valide : « %s »" + +#~ msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." +#~ msgstr "Les valeurs valides sont « pause », « promote » et « shutdown »." + +#~ msgid "invalid value for recovery parameter \"%s\": \"%s\"" +#~ msgstr "valeur invalide pour le paramètre de restauration « %s » : « %s »" + +#~ msgid "could not open recovery command file \"%s\": %m" +#~ msgstr "n'a pas pu ouvrir le fichier de restauration « %s » : %m" + +#~ msgid "could not read from control file: read %d bytes, expected %d" +#~ msgstr "n'a pas pu lire le fichier de contrôle : lu %d octets, %d attendus" + +#~ msgid "could not read from control file: %m" +#~ msgstr "n'a pas pu lire le fichier de contrôle : %m" + +#~ msgid "could not open control file \"%s\": %m" +#~ msgstr "n'a pas pu ouvrir le fichier de contrôle « %s » : %m" + +#~ msgid "could not close control file: %m" +#~ msgstr "n'a pas pu fermer le fichier de contrôle : %m" + +#~ msgid "could not fsync control file: %m" +#~ msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier de contrôle : %m" + +#~ msgid "could not write to control file: %m" +#~ msgstr "n'a pas pu écrire le fichier de contrôle : %m" + +#~ msgid "could not create control file \"%s\": %m" +#~ msgstr "n'a pas pu créer le fichier de contrôle « %s » : %m" + +#~ msgid "could not rename old write-ahead log file \"%s\": %m" +#~ msgstr "n'a pas pu renommer l'ancien journal de transactions « %s » : %m" + +#~ msgid "could not close log file %s: %m" +#~ msgstr "n'a pas pu fermer le fichier de transactions « %s » : %m" + +#~ msgid "could not open write-ahead log file \"%s\": %m" +#~ msgstr "n'a pas pu écrire dans le journal de transactions « %s » : %m" + +#~ msgid "not enough data in file \"%s\"" +#~ msgstr "données insuffisantes dans le fichier « %s »" + +#~ msgid "could not seek in log file %s to offset %u: %m" +#~ msgstr "n'a pas pu se déplacer dans le fichier de transactions « %s » au décalage %u : %m" + +#~ msgid "cannot PREPARE a transaction that has operated on temporary tables" +#~ msgstr "" +#~ "ne peut pas préparer (PREPARE) une transaction qui a travaillé sur des\n" +#~ "tables temporaires" + +#~ msgid "could not close two-phase state file: %m" +#~ msgstr "n'a pas pu fermer le fichier d'état de la validation en deux phases : %m" + +#~ msgid "could not fsync two-phase state file: %m" +#~ msgstr "" +#~ "n'a pas pu synchroniser sur disque (fsync) le fichier d'état de la\n" +#~ "validation en deux phases : %m" + +#~ msgid "could not write two-phase state file: %m" +#~ msgstr "n'a pas pu écrire dans le fichier d'état de la validation en deux phases : %m" + +#~ msgid "could not recreate two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu re-créer le fichier d'état de la validation en deux phases nommé\n" +#~ "« %s » : %m" + +#~ msgid "could not remove two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu supprimer le fichier d'état de la validation en deux phases\n" +#~ "« %s » : %m" + +#~ msgid "could not read two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu lire le fichier d'état de la validation en deux phases nommé\n" +#~ "« %s » : %m" + +#~ msgid "could not stat two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu récupérer des informations sur le fichier d'état de la validation\n" +#~ "en deux phases nommé « %s » : %m" + +#~ msgid "could not open two-phase state file \"%s\": %m" +#~ msgstr "" +#~ "n'a pas pu ouvrir le fichier d'état de la validation en deux phases nommé\n" +#~ "« %s » : %m" + +#~ msgid "unrecognized error %d" +#~ msgstr "erreur %d non reconnue" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "le processus fils a été terminé par le signal %d" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "could not remove file or directory \"%s\": %s\n" +#~ msgstr "n'a pas pu supprimer le fichier ou répertoire « %s » : %s\n" + +#~ msgid "could not stat file or directory \"%s\": %s\n" +#~ msgstr "" +#~ "n'a pas pu récupérer les informations sur le fichier ou répertoire\n" +#~ "« %s » : %s\n" + +#~ msgid "%s: could not get exit code from subprocess: error code %lu\n" +#~ msgstr "%s : n'a pas pu récupérer le code de statut du sous-processus : code d'erreur %lu\n" + +#~ msgid "%s: could not re-execute with restricted token: error code %lu\n" +#~ msgstr "%s : n'a pas pu ré-exécuter le jeton restreint : code d'erreur %lu\n" + +#~ msgid "%s: could not start process for command \"%s\": error code %lu\n" +#~ msgstr "%s : n'a pas pu démarrer le processus pour la commande « %s » : code d'erreur %lu\n" + +#~ msgid "%s: could not create restricted token: error code %lu\n" +#~ msgstr "%s : n'a pas pu créer le jeton restreint : code d'erreur %lu\n" + +#~ msgid "%s: could not allocate SIDs: error code %lu\n" +#~ msgstr "%s : n'a pas pu allouer les SID : code d'erreur %lu\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s : n'a pas pu ouvrir le jeton du processus : code d'erreur %lu\n" + +#~ msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +#~ msgstr "%s : ATTENTION : ne peut pas créer les jetons restreints sur cette plateforme\n" + +#~ msgid "could not close directory \"%s\": %s\n" +#~ msgstr "n'a pas pu fermer le répertoire « %s » : %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "n'a pas pu ouvrir le répertoire « %s » : %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu renommer le fichier « %s » en « %s » : %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu changer le répertoire par « %s » : %s" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "n'a pas pu identifier le répertoire courant : %s" + +#~ msgid "" +#~ "WARNING: possible byte ordering mismatch\n" +#~ "The byte ordering used to store the pg_control file might not match the one\n" +#~ "used by this program. In that case the results below would be incorrect, and\n" +#~ "the PostgreSQL installation would be incompatible with this data directory.\n" +#~ msgstr "" +#~ "ATTENTION : possible incohérence dans l'ordre des octets\n" +#~ "L'ordre des octets utilisé pour enregistrer le fichier pg_control peut ne\n" +#~ "pas correspondre à celui utilisé par ce programme. Dans ce cas, les\n" +#~ "résultats ci-dessous sont incorrects, et l'installation PostgreSQL\n" +#~ "incompatible avec ce répertoire des données.\n" + +#~ msgid "%s: could not read file \"%s\": read %d of %d\n" +#~ msgstr "%s : n'a pas pu lire le fichier « %s » : a lu %d sur %d\n" + +#~ msgid "could not read file \"%s\": read %d of %d" +#~ msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %d" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu lire le fichier « %s » : %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » en lecture : %s\n" + +#~ msgid "insufficient columns in %s constraint definition" +#~ msgstr "colonnes infuffisantes dans la définition de contrainte de %s" + +#~ msgid "cannot reindex invalid index on TOAST table concurrently" +#~ msgstr "ne peut pas réindexer un index invalide sur une table TOAST de manière concurrente" + +#~ msgid "index \"%s\" now contains %.0f row versions in %u pages as reported by parallel vacuum worker" +#~ msgstr "l'index « %s » contient maintenant %.0f versions de lignes dans %u pages, comme indiqué par le worker parallélisé du VACUUM" + +#~ msgid "scanned index \"%s\" to remove %d row versions by parallel vacuum worker" +#~ msgstr "a parcouru l'index « %s » pour supprimer %d versions de lignes par le worker parallélisé du VACUUM" + +#~ msgid "moving row to another partition during a BEFORE trigger is not supported" +#~ msgstr "déplacer une ligne vers une autre partition lors de l'exécution d'un trigger BEFORE n'est pas supporté" + +#~ msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +#~ msgstr "" +#~ "Nombre de lignes insérées avant d'effectuer un nettoyage des index\n" +#~ "(fraction de reltuples)." + +#~ msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +#~ msgstr "Émet un avertissement pour les constructions dont la signification a changé depuis PostgreSQL 9.4." + +#~ msgid "on" +#~ msgstr "activé" + +#~ msgid "off" +#~ msgstr "désactivé" + +#~ msgid "loaded library \"%s\"" +#~ msgstr "bibliothèque « %s » chargée" + +#~ msgid "wrong data type: %u, expected %u" +#~ msgstr "mauvais type de données : %u, alors que %u attendu" + +#~ msgid "wrong element type" +#~ msgstr "mauvais type d'élément" + +#~ msgid "logical replication launcher shutting down" +#~ msgstr "arrêt du processus de lancement de la réplication logique" + +#~ msgid "bind %s to %s" +#~ msgstr "lie %s à %s" + +#~ msgid "parse %s: %s" +#~ msgstr "analyse %s : %s" + +#~ msgid "unexpected EOF on client connection" +#~ msgstr "fin de fichier (EOF) inattendue de la connexion du client" + +#~ msgid "could not fsync file \"%s\" but retrying: %m" +#~ msgstr "" +#~ "n'a pas pu synchroniser sur disque (fsync) le fichier « %s », nouvelle\n" +#~ "tentative : %m" + +#~ msgid "could not forward fsync request because request queue is full" +#~ msgstr "n'a pas pu envoyer la requête fsync car la queue des requêtes est pleine" + +#~ msgid "sending cancel to blocking autovacuum PID %d" +#~ msgstr "envoi de l'annulation pour bloquer le PID %d de l'autovacuum" + +#~ msgid "Process %d waits for %s on %s." +#~ msgstr "Le processus %d attend %s sur %s." + +#~ msgid "deferrable snapshot was unsafe; trying a new one" +#~ msgstr "l'image déferrable est non sûre ; tentative avec une nouvelle image" + +#~ msgid "%s failed: %m" +#~ msgstr "échec de %s : %m" + +#~ msgid "\"%s\" has now caught up with upstream server" +#~ msgstr "« %s » a maintenant rattrapé le serveur en amont" + +#~ msgid "standby \"%s\" now has synchronous standby priority %u" +#~ msgstr "" +#~ "le serveur « %s » en standby a maintenant une priorité %u en tant que standby\n" +#~ "synchrone" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +#~ msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car les publications ont été modifiées" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +#~ msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car le nom du slot de réplication a été modifiée" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +#~ msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car la souscription a été modifiée" + +#~ msgid "could not fetch table info for table \"%s.%s\": %s" +#~ msgstr "n'a pas pu récupérer les informations sur la table « %s.%s » : %s" + +#~ msgid "only superusers can query or manipulate replication origins" +#~ msgstr "seuls les super-utilisateurs peuvent lire ou manipuler les origines de réplication" + +#~ msgid "logical replication launcher started" +#~ msgstr "lancement du processus de lancement de la réplication logique" + +#~ msgid "starting logical replication worker for subscription \"%s\"" +#~ msgstr "lancement du processus worker de réplication logique pour la souscription « %s »" + +#~ msgid "could not reread block %d of file \"%s\": %m" +#~ msgstr "n'a pas pu relire le bloc %d dans le fichier « %s » : %m" + +#~ msgid "could not fseek in file \"%s\": %m" +#~ msgstr "n'a pas pu effectuer de fseek dans le fichier « %s » : %m" + +#~ msgid "could not read from file \"%s\"" +#~ msgstr "n'a pas pu lire à partir du fichier « %s »" + +#~ msgid "logger shutting down" +#~ msgstr "arrêt en cours des journaux applicatifs" + +#~ msgid "starting background worker process \"%s\"" +#~ msgstr "démarrage du processus d'écriture en tâche de fond « %s »" + +#~ msgid "could not fork archiver: %m" +#~ msgstr "n'a pas pu lancer le processus fils correspondant au processus d'archivage : %m" + +#~ msgid "compacted fsync request queue from %d entries to %d entries" +#~ msgstr "a compacté la queue de requêtes fsync de %d entrées à %d" + +#~ msgid "unregistering background worker \"%s\"" +#~ msgstr "désenregistrement du processus en tâche de fond « %s »" + +#~ msgid "registering background worker \"%s\"" +#~ msgstr "enregistrement du processus en tâche de fond « %s »" + +#~ msgid "autovacuum: processing database \"%s\"" +#~ msgstr "autovacuum : traitement de la base de données « %s »" + +#~ msgid "autovacuum launcher shutting down" +#~ msgstr "arrêt du processus de lancement de l'autovacuum" + +#~ msgid "autovacuum launcher started" +#~ msgstr "démarrage du processus de lancement de l'autovacuum" + +#~ msgid "disabling huge pages" +#~ msgstr "désactivation des Huge Pages" + +#~ msgid "could not enable Lock Pages in Memory user right" +#~ msgstr "n'a pas pu activer le Lock Pages in Memory user right" + +#~ msgid "could not enable Lock Pages in Memory user right: error code %lu" +#~ msgstr "n'a pas pu activer le Lock Pages in Memory user right : code d'erreur %lu" + +#~ msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +#~ msgstr "le collationnement de la valeur limite de partition de la colonne « %s » ne correspond pas à celui de la clé de partition « %s »" + +#~ msgid "could not determine which collation to use for partition bound expression" +#~ msgstr "n'a pas pu déterminer le collationnement à utiliser pour l'expression de limites de partitionnement" + +#~ msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +#~ msgstr "%s créera des séquences implicites « %s » pour la colonne serial « %s.%s »" + +#~ msgid "array assignment requires type %s but expression is of type %s" +#~ msgstr "l'affectation de tableaux requiert le type %s mais l'expression est de type %s" + +#~ msgid "operator precedence change: %s is now lower precedence than %s" +#~ msgstr "la précédence d'opérateur change : %s a maintenant une précédence inférieure à %s" + +#~ msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +#~ msgstr " -o OPTIONS passe « OPTIONS » à chaque processus serveur (obsolète)\n" + +#~ msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +#~ msgstr "Un autre postmaster fonctionne-t'il déjà sur le port %d ?Sinon, supprimez le fichier socket « %s » et réessayez." + +#~ msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +#~ msgstr "setsockopt(SO_REUSEADDR) a échoué pour %s, adresse « %s » : %m" + +#~ msgid "authentication file line too long" +#~ msgstr "ligne du fichier d'authentification trop longue" + +#~ msgid "SSL connection from \"%s\"" +#~ msgstr "connexion SSL de « %s »" + +#~ msgid "SSPI is not supported in protocol version 2" +#~ msgstr "SSPI n'est pas supporté dans le protocole de version 2" + +#~ msgid "GSSAPI is not supported in protocol version 2" +#~ msgstr "GSSAPI n'est pas supporté dans le protocole de version 2" + +#~ msgid "SASL authentication is not supported in protocol version 2" +#~ msgstr "l'authentification SASL n'est pas supportée dans le protocole de version 2" + +#~ msgid "SSL off" +#~ msgstr "SSL inactif" + +#~ msgid "SSL on" +#~ msgstr "SSL actif" + +#~ msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +#~ msgstr "temps pour inliner: %.3fs, opt: %.3fs, emit: %.3fs" + +#~ msgid "must be superuser to alter replication users" +#~ msgstr "doit être super-utilisateur pour modifier des utilisateurs ayant l'attribut réplication" + +#~ msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +#~ msgstr "la contrainte de partitionnement pour la partition par défaut « %s » est implicite du fait de contraintes existantes" + +#~ msgid "partition constraint for table \"%s\" is implied by existing constraints" +#~ msgstr "la contrainte de partitionnement pour la table « %s » provient des contraintes existantes" + +#~ msgid "validating foreign key constraint \"%s\"" +#~ msgstr "validation de la contraintes de clé étrangère « %s »" + +#~ msgid "existing constraints on column \"%s.%s\" are sufficient to prove that it does not contain nulls" +#~ msgstr "les contraintes existantes sur la colonne « %s.%s » sont suffisantes pour prouver qu'elle ne contient aucun NULL" + +#~ msgid "verifying table \"%s\"" +#~ msgstr "vérification de la table « %s »" + +#~ msgid "rewriting table \"%s\"" +#~ msgstr "ré-écriture de la table « %s »" + +#~ msgid "The error was: %s" +#~ msgstr "L'erreur était : %s" + +#~ msgid "table \"%s.%s\" removed from subscription \"%s\"" +#~ msgstr "table « %s.%s » supprimée de la souscription « %s »" + +#~ msgid "table \"%s.%s\" added to subscription \"%s\"" +#~ msgstr "table « %s.%s » ajoutée à la souscription « %s »" + +#~ msgid "at least one of leftarg or rightarg must be specified" +#~ msgstr "au moins un des arguments (le gauche ou le droit) doit être spécifié" + +#~ msgid "REINDEX is not yet implemented for partitioned indexes" +#~ msgstr "REINDEX n'est pas implémenté pour des index partitionnés" + +#~ msgid "%s %s will create implicit index \"%s\" for table \"%s\"" +#~ msgstr "%s %s créera un index implicite « %s » pour la table « %s »" + +#~ msgid "INOUT arguments are permitted." +#~ msgstr "les arguments INOUT ne sont pas autorisés." + +#~ msgid "procedures cannot have OUT arguments" +#~ msgstr "les procédures ne peuvent pas avoir d'argument OUT" + +#~ msgid "connection lost during COPY to stdout" +#~ msgstr "connexion perdue lors de l'opération COPY vers stdout" + +#~ msgid "COPY BINARY is not supported to stdout or from stdin" +#~ msgstr "COPY BINARY n'est pas supporté vers stdout ou à partir de stdin" + +#~ msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" +#~ msgstr "ANALYZE automatique de la table « %s.%s.%s » ; utilisation système : %s" + +#~ msgid "must be superuser to drop access methods" +#~ msgstr "doit être super-utilisateur pour supprimer des méthodes d'accès" + +#~ msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +#~ msgstr "REINDEX n'est pas encore implémenté pour les tables partitionnées, « %s » ignoré" + +#~ msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +#~ msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +#~ msgstr[0] "construction de l'index « %s » sur la table « %s » avec une demande de %d processus parallèle" +#~ msgstr[1] "construction de l'index « %s » sur la table « %s » avec une demande de %d processus parallèles" + +#~ msgid "building index \"%s\" on table \"%s\" serially" +#~ msgstr "construction de l'index « %s » sur la table « %s » séquentiellement" + +#~ msgid "drop auto-cascades to %s" +#~ msgstr "DROP cascade automatiquement sur %s" + +#~ msgid "backup timeline %u in file \"%s\"" +#~ msgstr "timeline de sauvegarde %u dans le fichier « %s »" + +#~ msgid "backup label %s in file \"%s\"" +#~ msgstr "label de sauvegarde %s dans le fichier « %s »" + +#~ msgid "backup time %s in file \"%s\"" +#~ msgstr "heure de sauvegarde %s dans le fichier « %s »" + +#~ msgid "skipping restartpoint, already performed at %X/%X" +#~ msgstr "ignore le point de redémarrage, déjà réalisé à %X/%X" + +#~ msgid "skipping restartpoint, recovery has already ended" +#~ msgstr "restartpoint ignoré, la récupération est déjà terminée" + +#~ msgid "checkpoint skipped because system is idle" +#~ msgstr "checkpoint ignoré car le système est inactif" + +#~ msgid "initializing for hot standby" +#~ msgstr "initialisation pour « Hot Standby »" + +#~ msgid "checkpoint record is at %X/%X" +#~ msgstr "l'enregistrement du point de vérification est à %X/%X" + +#~ msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +#~ msgstr "" +#~ "Vous devez soit positionner le paramètre wal_level à « replica » sur le maître,\n" +#~ "soit désactiver le hot_standby ici." + +#~ msgid "removing write-ahead log file \"%s\"" +#~ msgstr "suppression du journal de transactions « %s »" + +#~ msgid "recycled write-ahead log file \"%s\"" +#~ msgstr "recyclage du journal de transactions « %s »" + +#~ msgid "updated min recovery point to %X/%X on timeline %u" +#~ msgstr "mise à jour du point minimum de restauration sur %X/%X pour la timeline %u" + +#~ msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +#~ msgstr "" +#~ "ne peut pas préparer (PREPARE) une transaction qui a travaillé sur des\n" +#~ "workers de réplication logique" + +#~ msgid "transaction ID wrap limit is %u, limited by database with OID %u" +#~ msgstr "" +#~ "la limite de réinitialisation de l'identifiant de transaction est %u,\n" +#~ "limité par la base de données d'OID %u" + +#~ msgid "removing file \"%s\"" +#~ msgstr "suppression du fichier « %s »" + +#~ msgid "MultiXact member stop limit is now %u based on MultiXact %u" +#~ msgstr "La limite d'arrêt d'un membre MultiXact est maintenant %u, basée sur le MultiXact %u" + +#~ msgid "oldest MultiXactId member is at offset %u" +#~ msgstr "le membre le plus ancien du MultiXactId est au décalage %u" + +#~ msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +#~ msgstr "La limite de réinitialisation MultiXactId est %u, limité par la base de données d'OID %u" + +#~ msgid "%u page is entirely empty.\n" +#~ msgid_plural "%u pages are entirely empty.\n" +#~ msgstr[0] "%u page est entièrement vide.\n" +#~ msgstr[1] "%u pages sont entièrement vides.\n" + +#~ msgid "There were %.0f unused item identifiers.\n" +#~ msgstr "Il y avait %.0f identifiants d'éléments inutilisés.\n" + +#~ msgid "\"%s\": removed %.0f row versions in %u pages" +#~ msgstr "« %s » : %.0f versions de ligne supprimées dans %u pages" + +#~ msgid "password too long" +#~ msgstr "mot de passe trop long" + +#~ msgid "pclose failed: %m" +#~ msgstr "échec de pclose : %m" + +#~ msgid "You need to rebuild PostgreSQL using --with-libxml." +#~ msgstr "Vous devez recompiler PostgreSQL en utilisant --with-libxml." + +#~ msgid "You need to rebuild PostgreSQL using --with-icu." +#~ msgstr "Vous devez recompiler PostgreSQL en utilisant --with-icu." + +#~ msgid "arguments declared \"anycompatiblemultirange\" are not all alike" +#~ msgstr "les arguments déclarés « anycompatiblemultirange » ne sont pas tous identiques" + +#~ msgid "arguments declared \"anycompatiblerange\" are not all alike" +#~ msgstr "les arguments déclarés « anycompatiblerange » ne sont pas tous identiques" + +#~ msgid "arguments declared \"anymultirange\" are not all alike" +#~ msgstr "les arguments déclarés « anymultirange » ne sont pas tous identiques" + +#~ msgid "arguments declared \"anyrange\" are not all alike" +#~ msgstr "les arguments déclarés « anyrange » ne sont pas tous identiques" + +#~ msgid "arguments declared \"anyelement\" are not all alike" +#~ msgstr "les arguments déclarés « anyelement » ne sont pas tous identiques" + +#~ msgid "\"timeout\" must not be negative or zero" +#~ msgstr "« timeout » ne doit pas être négatif ou nul" diff --git a/src/backend/po/ja.po b/src/backend/po/ja.po new file mode 100644 index 000000000000..6c025aa917f6 --- /dev/null +++ b/src/backend/po/ja.po @@ -0,0 +1,26884 @@ +# Japanese message translation file for postgres +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# HOTTA Michihide , 2011 +# +msgid "" +msgstr "" +"Project-Id-Version: postgres (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:51+0900\n" +"PO-Revision-Date: 2021-02-05 07:57+0100\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: jpug-doc \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 1.8.13\n" +"X-Poedit-Basepath: ..\n" +"X-Poedit-SearchPath-0: .\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 ../common/config_info.c:150 ../common/config_info.c:158 ../common/config_info.c:166 ../common/config_info.c:174 ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "記録されていません" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 commands/copy.c:3551 commands/extension.c:3455 utils/adt/genfile.c:125 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "ファイル\"%s\"を読み取り用にオープンできませんでした: %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 access/transam/timeline.c:143 access/transam/timeline.c:362 access/transam/twophase.c:1270 access/transam/xlog.c:3501 access/transam/xlog.c:4726 access/transam/xlog.c:11110 access/transam/xlog.c:11123 access/transam/xlog.c:11576 access/transam/xlog.c:11656 access/transam/xlog.c:11695 access/transam/xlog.c:11738 access/transam/xlogfuncs.c:662 access/transam/xlogfuncs.c:681 +#: commands/extension.c:3465 libpq/hba.c:499 replication/basebackup.c:2001 replication/logical/origin.c:712 replication/logical/origin.c:748 replication/logical/reorderbuffer.c:4427 replication/logical/snapbuild.c:1742 replication/logical/snapbuild.c:1784 replication/logical/snapbuild.c:1812 replication/logical/snapbuild.c:1839 replication/slot.c:1623 replication/slot.c:1664 replication/walsender.c:543 storage/file/buffile.c:441 storage/file/copydir.c:195 +#: utils/adt/genfile.c:200 utils/adt/misc.c:763 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "ファイル\"%s\"の読み取りに失敗しました: %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 access/transam/twophase.c:1273 access/transam/xlog.c:3506 access/transam/xlog.c:4731 replication/basebackup.c:2005 replication/logical/origin.c:717 replication/logical/origin.c:756 replication/logical/snapbuild.c:1747 replication/logical/snapbuild.c:1789 replication/logical/snapbuild.c:1817 replication/logical/snapbuild.c:1844 replication/slot.c:1627 replication/slot.c:1668 +#: replication/walsender.c:548 utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$dバイトを読み込みました" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 access/heap/rewriteheap.c:1181 access/heap/rewriteheap.c:1284 access/transam/timeline.c:392 access/transam/timeline.c:438 access/transam/timeline.c:516 access/transam/twophase.c:1282 access/transam/twophase.c:1668 access/transam/xlog.c:3373 access/transam/xlog.c:3541 access/transam/xlog.c:3546 access/transam/xlog.c:3874 +#: access/transam/xlog.c:4696 access/transam/xlog.c:5620 access/transam/xlogfuncs.c:687 commands/copy.c:1860 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:533 replication/logical/origin.c:650 replication/logical/origin.c:789 replication/logical/reorderbuffer.c:4485 replication/logical/snapbuild.c:1654 replication/logical/snapbuild.c:1852 replication/slot.c:1514 replication/slot.c:1675 replication/walsender.c:558 storage/file/copydir.c:218 storage/file/copydir.c:223 +#: storage/file/fd.c:704 storage/file/fd.c:3425 storage/file/fd.c:3528 utils/cache/relmapper.c:753 utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "ファイル\"%s\"をクローズできませんでした: %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "バイトオーダが合っていません" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"バイトオーダが異なる可能性があります。\n" +"pg_controlファイルを格納するために使用するバイトオーダが本プログラムで使用\n" +"されるものと一致しないようです。この場合以下の結果は不正確になります。また、\n" +"PostgreSQLインストレーションはこのデータディレクトリと互換性がなくなります。" + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 ../common/file_utils.c:229 ../common/file_utils.c:288 ../common/file_utils.c:362 access/heap/rewriteheap.c:1267 access/transam/timeline.c:111 access/transam/timeline.c:251 access/transam/timeline.c:348 access/transam/twophase.c:1226 access/transam/xlog.c:3275 access/transam/xlog.c:3415 access/transam/xlog.c:3456 access/transam/xlog.c:3654 access/transam/xlog.c:3739 access/transam/xlog.c:3842 +#: access/transam/xlog.c:4716 access/transam/xlogutils.c:806 postmaster/syslogger.c:1488 replication/basebackup.c:616 replication/basebackup.c:1593 replication/logical/origin.c:702 replication/logical/reorderbuffer.c:3163 replication/logical/reorderbuffer.c:3653 replication/logical/reorderbuffer.c:4407 replication/logical/snapbuild.c:1609 replication/logical/snapbuild.c:1713 replication/slot.c:1595 replication/walsender.c:516 replication/walsender.c:2509 +#: storage/file/copydir.c:161 storage/file/fd.c:679 storage/file/fd.c:3412 storage/file/fd.c:3499 storage/smgr/md.c:475 utils/cache/relmapper.c:724 utils/cache/relmapper.c:836 utils/error/elog.c:1858 utils/init/miscinit.c:1318 utils/init/miscinit.c:1452 utils/init/miscinit.c:1529 utils/misc/guc.c:8270 utils/misc/guc.c:8302 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 access/transam/twophase.c:1641 access/transam/twophase.c:1650 access/transam/xlog.c:10867 access/transam/xlog.c:10905 access/transam/xlog.c:11318 access/transam/xlogfuncs.c:741 postmaster/syslogger.c:1499 postmaster/syslogger.c:1512 utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "ファイル\"%s\"を書き出せませんでした: %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 ../common/file_utils.c:300 ../common/file_utils.c:370 access/heap/rewriteheap.c:961 access/heap/rewriteheap.c:1175 access/heap/rewriteheap.c:1278 access/transam/timeline.c:432 access/transam/timeline.c:510 access/transam/twophase.c:1662 access/transam/xlog.c:3366 access/transam/xlog.c:3535 access/transam/xlog.c:4689 access/transam/xlog.c:10385 access/transam/xlog.c:10412 +#: replication/logical/snapbuild.c:1647 replication/slot.c:1500 replication/slot.c:1605 storage/file/fd.c:696 storage/file/fd.c:3520 storage/smgr/md.c:921 storage/smgr/md.c:962 storage/sync/sync.c:396 utils/cache/relmapper.c:885 utils/misc/guc.c:8053 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "ファイル\"%s\"をfsyncできませんでした: %m" + +#: ../common/exec.c:137 ../common/exec.c:254 ../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "カレントディレクトリを識別できませんでした: %m" + +#: ../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "バイナリ\"%s\"は不正です" + +#: ../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "バイナリ\"%s\"を読み取れませんでした" + +#: ../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "実行すべき\"%s\"がありませんでした" + +#: ../common/exec.c:270 ../common/exec.c:309 utils/init/miscinit.c:397 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "ディレクトリ\"%s\"に移動できませんでした: %m" + +#: ../common/exec.c:287 access/transam/xlog.c:10740 replication/basebackup.c:1413 utils/adt/misc.c:337 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" + +#: ../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pcloseが失敗しました: %m" + +#: ../common/exec.c:539 ../common/exec.c:584 ../common/exec.c:676 ../common/psprintf.c:143 ../common/stringinfo.c:305 ../port/path.c:630 ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1335 access/transam/xlog.c:6491 lib/dshash.c:246 libpq/auth.c:1090 libpq/auth.c:1491 libpq/auth.c:1559 libpq/auth.c:2089 libpq/be-secure-gssapi.c:484 postmaster/bgworker.c:336 postmaster/bgworker.c:886 postmaster/postmaster.c:2520 postmaster/postmaster.c:2542 +#: postmaster/postmaster.c:4168 postmaster/postmaster.c:4862 postmaster/postmaster.c:4941 postmaster/postmaster.c:5624 postmaster/postmaster.c:5984 replication/libpqwalreceiver/libpqwalreceiver.c:276 replication/logical/logical.c:195 replication/walsender.c:590 storage/buffer/localbuf.c:442 storage/file/fd.c:834 storage/file/fd.c:1304 storage/file/fd.c:1465 storage/file/fd.c:2270 storage/ipc/procarray.c:1368 storage/ipc/procarray.c:2106 +#: storage/ipc/procarray.c:2113 storage/ipc/procarray.c:2591 storage/ipc/procarray.c:3215 utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 utils/adt/formatting.c:1698 utils/adt/formatting.c:1822 utils/adt/formatting.c:1947 utils/adt/pg_locale.c:475 utils/adt/pg_locale.c:639 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 utils/hash/dynahash.c:469 utils/hash/dynahash.c:578 utils/hash/dynahash.c:1090 utils/mb/mbutils.c:401 utils/mb/mbutils.c:428 +#: utils/mb/mbutils.c:757 utils/mb/mbutils.c:783 utils/misc/guc.c:4864 utils/misc/guc.c:4880 utils/misc/guc.c:4893 utils/misc/guc.c:8031 utils/misc/tzparser.c:467 utils/mmgr/aset.c:475 utils/mmgr/dsa.c:701 utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:233 utils/mmgr/mcxt.c:829 utils/mmgr/mcxt.c:865 utils/mmgr/mcxt.c:903 utils/mmgr/mcxt.c:941 utils/mmgr/mcxt.c:977 utils/mmgr/mcxt.c:1008 utils/mmgr/mcxt.c:1044 utils/mmgr/mcxt.c:1096 +#: utils/mmgr/mcxt.c:1131 utils/mmgr/mcxt.c:1166 utils/mmgr/slab.c:235 +#, c-format +msgid "out of memory" +msgstr "メモリ不足です" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nullポインタは複製できません(内部エラー)\n" + +#: ../common/file_utils.c:84 ../common/file_utils.c:186 access/transam/twophase.c:1238 access/transam/xlog.c:10843 access/transam/xlog.c:10881 access/transam/xlog.c:11098 access/transam/xlogarchive.c:110 access/transam/xlogarchive.c:226 commands/copy.c:1988 commands/copy.c:3561 commands/extension.c:3444 commands/tablespace.c:795 commands/tablespace.c:886 guc-file.l:1062 replication/basebackup.c:439 replication/basebackup.c:622 replication/basebackup.c:698 +#: replication/logical/snapbuild.c:1523 storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1816 storage/file/fd.c:3096 storage/file/fd.c:3278 storage/file/fd.c:3364 utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 utils/adt/genfile.c:416 utils/adt/genfile.c:642 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "ファイル\"%s\"のstatに失敗しました: %m" + +#: ../common/file_utils.c:163 ../common/pgfnames.c:48 commands/tablespace.c:718 commands/tablespace.c:728 postmaster/postmaster.c:1511 storage/file/fd.c:2673 storage/file/reinit.c:122 utils/adt/misc.c:259 utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: ../common/file_utils.c:197 ../common/pgfnames.c:69 storage/file/fd.c:2685 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m" + +#: ../common/file_utils.c:380 access/transam/xlogarchive.c:411 postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1666 replication/slot.c:651 replication/slot.c:1386 replication/slot.c:1528 storage/file/fd.c:714 utils/time/snapmgr.c:1316 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m" + +#: ../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "エスケープシーケンス\"\\%s\"は不正です。" + +#: ../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "0x%02x値を持つ文字はエスケープしなければなりません" + +#: ../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "入力の終端を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "配列要素または\"]\"を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "\",\"または\"]\"を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "\":\"を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "JSON値を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "入力文字列が予期せず終了しました。" + +#: ../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "文字列または\"}\"を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "\",\"または\"}\"を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "文字列を想定していましたが、\"%s\"でした。" + +#: ../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "トークン\"%s\"は不正です。" + +#: ../common/jsonapi.c:1099 jsonpath_scan.l:500 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 はテキストに変換できません。" + +#: ../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\"の後には16進数の4桁が続かなければなりません。" + +#: ../common/jsonapi.c:1104 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "エンコーディングがUTF-8ではない場合、コードポイントの値が 007F 以上についてはUnicodeエスケープの値は使用できません。" + +#: ../common/jsonapi.c:1106 jsonpath_scan.l:521 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Unicodeのハイサロゲートはハイサロゲートに続いてはいけません。" + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:532 jsonpath_scan.l:542 jsonpath_scan.l:584 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Unicodeのローサロゲートはハイサロゲートに続かなければなりません。" + +#: ../common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "不正なフォーク名です" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "有効なフォーク名は\"main\"、\"fsm\"、\"vm\"および\"init\"です。" + +#: ../common/restricted_token.c:64 libpq/auth.c:1521 libpq/auth.c:2520 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "ライブラリ\"%s\"をロードできませんでした: エラーコード %lu" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "このプラットフォームでは制限付きトークンを生成できません: エラーコード %lu" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "プロセストークンをオープンできませんでした: エラーコード %lu" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SIDを割り当てられませんでした: エラーコード %lu" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "制限付きトークンを生成できませんでした: エラーコード %lu" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "コマンド\"%s\"のためのプロセスを起動できませんでした: エラーコード %lu" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "制限付きトークンで再実行できませんでした: %lu" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "サブプロセスの終了コードを取得できませんでした: エラーコード %lu" + +#: ../common/rmtree.c:79 replication/basebackup.c:1166 replication/basebackup.c:1342 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "\"%s\"というファイルまたはディレクトリの情報を取得できませんでした。: %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "\"%s\"というファイルまたはディレクトリを削除できませんでした: %m" + +#: ../common/saslprep.c:1087 +#, c-format +msgid "password too long" +msgstr "パスワードが長すぎます" + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "%dバイトを持つ文字列バッファを%dバイト多く、大きくすることができません。" + +#: ../common/stringinfo.c:310 +#, c-format +msgid "" +"out of memory\n" +"\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "" +"メモリが足りません\n" +"\n" +"%dバイトの文字列バッファを%dバイト拡げることができません。\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "実効ユーザID %ld が見つかりませんでした: %s" + +#: ../common/username.c:45 libpq/auth.c:2027 +msgid "user does not exist" +msgstr "ユーザが存在しません" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "ユーザ名の参照に失敗: エラーコード %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "コマンドは実行可能形式ではありません" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "コマンドが見つかりません" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "子プロセスが終了コード%dで終了しました" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "子プロセスが例外0x%Xで終了しました" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "子プロセスはシグナル%dにより終了しました: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "子プロセスは認識できないステータス%dで終了しました" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "コードセット\"%s\"用の符号化方式を特定できませんでした" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "ロケール\"%s\"用の符号化方式を特定できませんでした: コードセットは\"%s\"です" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "\"%s\"のジャンクションを設定できませんでした: %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "\"%s\"のジャンクションを設定できませんでした: %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "\"%s\"のジャンクションを取得できませんでした: %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "\"%s\"のジャンクションを取得できませんでした: %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "ファイル\"%s\"をオープンできませんでした: %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "ロック違反" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "共有違反" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "再試行を30秒間続けます。" + +#: ../port/open.c:129 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "データベースシステムに干渉するアンチウィルス、バックアップといったソフトウェアが存在する可能性があります。" + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "現在の作業ディレクトリを取得できませんでした: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "オペレーティングシステムエラー %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "管理者グループのSIDを入手できませんでした: エラーコード %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "PowerUsersグループのSIDを取得できませんでした: エラーコード %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "アクセストークンのメンバーシップを確認できませんでした: エラーコード %lu\n" + +#: access/brin/brin.c:211 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "インデックス\"%s\" ページ%uのBRIN範囲要約のリクエストは登録されていません" + +#: access/brin/brin.c:874 access/brin/brin.c:951 access/gin/ginfast.c:1035 access/transam/xlog.c:10520 access/transam/xlog.c:11049 access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "リカバリは現在進行中です" + +#: access/brin/brin.c:875 access/brin/brin.c:952 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "BRIN制御関数はリカバリ中は実行できません。" + +#: access/brin/brin.c:883 access/brin/brin.c:960 +#, c-format +msgid "block number out of range: %s" +msgstr "ブロック番号が範囲外です: %s" + +#: access/brin/brin.c:906 access/brin/brin.c:983 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\"はBRINインデックスではありません" + +#: access/brin/brin.c:922 access/brin/brin.c:999 +#, c-format +msgid "could not open parent table of index %s" +msgstr "インデックス%sの親テーブルをオープンできませんでした" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 access/gist/gist.c:1436 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "インデックス行サイズ%1$zuはインデックス\"%3$s\"での最大値%2$zuを超えています" + +#: access/brin/brin_revmap.c:392 access/brin/brin_revmap.c:398 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "BRINインデックスが壊れています: 範囲マップの不整合" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "BRINインデックス\"%2$s\"のブロック %3$u のページタイプが予期しない値 0x%1$04X です" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 access/gist/gistvalidate.c:149 access/hash/hashvalidate.c:139 access/nbtree/nbtvalidate.c:120 access/spgist/spgvalidate.c:168 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は不正なサポート番号%4$dを持つ関数%3$sを含んでいます" + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 access/gist/gistvalidate.c:161 access/hash/hashvalidate.c:118 access/nbtree/nbtvalidate.c:132 access/spgist/spgvalidate.c:180 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"はサポート番号%4$dに対して間違ったシグネチャを持つ関数%3$sを含んでいます" + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 access/gist/gistvalidate.c:181 access/hash/hashvalidate.c:160 access/nbtree/nbtvalidate.c:152 access/spgist/spgvalidate.c:200 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は不正なストラテジ番号%4$dを持つ演算子\"%3$s\"を含んでいます" + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 access/hash/hashvalidate.c:173 access/nbtree/nbtvalidate.c:165 access/spgist/spgvalidate.c:216 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は演算子%3$sに対する不正なORDER BY指定を含んでいます" + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 access/gist/gistvalidate.c:229 access/hash/hashvalidate.c:186 access/nbtree/nbtvalidate.c:178 access/spgist/spgvalidate.c:232 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は間違ったシグネチャを持つ演算子%3$sを含んでいます" + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:226 access/nbtree/nbtvalidate.c:236 access/spgist/spgvalidate.c:259 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は%3$sと%4$sの型に対する演算子が含まれていません" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は型%3$sと%4$sに対するサポート関数を含んでいません" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:240 access/nbtree/nbtvalidate.c:260 access/spgist/spgvalidate.c:294 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "アクセスメソッド\"%2$s\"の演算子クラス\"%1$s\"は演算子を含んでいません" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 access/gist/gistvalidate.c:270 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "アクセスメソッド\"%2$s\"の演算子クラス\"%1$s\"はサポート関数%3$dを含んでいません" + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "列%3$dで返された%1$s型が、期待している%2$s型と一致しません。" + +#: access/common/attmap.c:150 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "返された列数(%d)が、期待する列数(%d)と一致しません。" + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "行型に変換できませんでした" + +#: access/common/attmap.c:230 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "%2$s型の属性\"%1$s\"が%3$s型の対応する属性と合致しません。" + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "%2$s型の属性\"%1$s\"が%3$s型の中に存在しません。" + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "列数(%d)が上限(%d)を超えています" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "インデックス列数(%d)が上限(%d)を超えています" + +#: access/common/indextuple.c:187 access/spgist/spgutils.c:704 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "インデックス行が%zuバイトを必要としますが最大値は%zuです" + +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 tcop/postgres.c:1904 +#, c-format +msgid "unsupported format code: %d" +msgstr "非サポートの書式コード: %d" + +#: access/common/reloptions.c:506 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "有効な値の範囲は\"on\"、\"off\"、\"auto\"です。" + +#: access/common/reloptions.c:517 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "有効な値は\"local\"と\"cascaded\"です。" + +#: access/common/reloptions.c:665 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "ユーザ定義リレーションのパラメータ型の制限を超えました" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESETにはパラメータの値を含めてはいけません" + +#: access/common/reloptions.c:1240 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "認識できないパラメータ namaspace \"%s\"" + +#: access/common/reloptions.c:1277 utils/misc/guc.c:12036 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "WITH OIDSと定義されたテーブルはサポートされません" + +#: access/common/reloptions.c:1447 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "認識できないラメータ \"%s\"" + +#: access/common/reloptions.c:1559 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "パラメータ\"%s\"が複数回指定されました" + +#: access/common/reloptions.c:1575 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "不正なブール型オプションの値 \"%s\": %s" + +#: access/common/reloptions.c:1587 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "不正な整数型オプションの値 \"%s\": %s" + +#: access/common/reloptions.c:1593 access/common/reloptions.c:1613 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "値%sはオプション\"%s\"の範囲外です" + +#: access/common/reloptions.c:1595 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "有効な値の範囲は\"%d\"~\"%d\"です。" + +#: access/common/reloptions.c:1607 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "不正な浮動小数点型オプションの値 \"%s\": %s" + +#: access/common/reloptions.c:1615 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "有効な値の範囲は\"%f\"~\"%f\"です。" + +#: access/common/reloptions.c:1637 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "不正な列挙型オプションの値 \"%s\": %s" + +#: access/common/tupdesc.c:840 parser/parse_clause.c:772 parser/parse_relation.c:1803 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "列\"%s\"はSETOFとして宣言できません" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "記録リストが長すぎます" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "maintenance_work_mem を小さくしてください。" + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "GIN保留リストはリカバリ中には処理できません。" + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\"はGINインデックスではありません" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "他のセッションの一時インデックスにはアクセスできません" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "古いGINインデックスはインデックス全体のスキャンやnullの検索をサポートしていません" + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "これを修復するには REINDEX INDEX \"%s\" をおこなってください。" + +#: access/gin/ginutil.c:145 executor/execExpr.c:1862 utils/adt/arrayfuncs.c:3811 utils/adt/arrayfuncs.c:6439 utils/adt/rowtypes.c:956 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "%s型の比較関数が見つかりません" + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 access/hash/hashvalidate.c:102 access/spgist/spgvalidate.c:99 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "アクセスメソッド %2$s の演算子族\"%1$s\"が左右辺の入力型が異なるサポート関数 %3$s を含んでいます" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "アクセスメソッド\"%2$s\"の演算子クラス\"%1$s\"はサポート関数%3$dまたは%4$dを含んでいません" + +#: access/gin/ginvalidate.c:333 access/gist/gistvalidate.c:345 access/spgist/spgvalidate.c:366 +#, c-format +msgid "support function number %d is invalid for access method %s" +msgstr "サポート関数番号%dはアクセスメソッド%sに対して不正です" + +#: access/gist/gist.c:754 access/gist/gistvacuum.c:408 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "インデックス\"%s\"内に無効と判断されている内部タプルがあります" + +#: access/gist/gist.c:756 access/gist/gistvacuum.c:410 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "これは、PostgreSQL 9.1へアップグレードする前のクラッシュリカバリにおける不完全なページ分割が原因で発生します。" + +#: access/gist/gist.c:757 access/gist/gistutil.c:786 access/gist/gistutil.c:797 access/gist/gistvacuum.c:411 access/hash/hashutil.c:227 access/hash/hashutil.c:238 access/hash/hashutil.c:250 access/hash/hashutil.c:271 access/nbtree/nbtpage.c:742 access/nbtree/nbtpage.c:753 +#, c-format +msgid "Please REINDEX it." +msgstr "REINDEXを行ってください。" + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "インデックス\"%2$s\"の列%1$dに対するピックスプリットメソッドが失敗しました" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "インデックスは最適ではありません。最適化するためには開発者に連絡するか、この列をCREATE INDEXコマンドの2番目の列としてみてください。" + +#: access/gist/gistutil.c:783 access/hash/hashutil.c:224 access/nbtree/nbtpage.c:739 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "インデックス\"%s\"のブロック%uに予期していないゼロで埋められたページがあります" + +#: access/gist/gistutil.c:794 access/hash/hashutil.c:235 access/hash/hashutil.c:247 access/nbtree/nbtpage.c:750 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "インデックス\"%s\"のブロック%uに破損したページがあります" + +#: access/gist/gistvalidate.c:199 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は演算子%3$sに対する非サポートのORDER BY指定を含んでいます" + +#: access/gist/gistvalidate.c:210 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は演算子%3$sに対する正しくないORDER BY演算子族を含んでいます" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "文字列のハッシュ値計算で使用する照合順序を特定できませんでした" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:702 catalog/heap.c:708 commands/createas.c:206 commands/createas.c:489 commands/indexcmds.c:1815 commands/tablecmds.c:15892 commands/view.c:86 parser/parse_utilcmd.c:4116 regex/regc_pg_locale.c:263 utils/adt/formatting.c:1665 utils/adt/formatting.c:1789 utils/adt/formatting.c:1914 utils/adt/like.c:194 utils/adt/like_support.c:1003 utils/adt/varchar.c:733 utils/adt/varchar.c:994 +#: utils/adt/varchar.c:1054 utils/adt/varlena.c:1476 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "照合順序を明示するには COLLATE 句を使います。" + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "インデックス行のサイズ%zuがハッシュでの最大値%zuを超えています" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 access/spgist/spgutils.c:765 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "バッファページよりも大きな値をインデックスすることはできません。" + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "不正なオーバーフローブロック番号%u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "ハッシュインデックス\"%s\"の中のオーバーフローページが足りません" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "ハッシュインデックスはインデックス全体のスキャンをサポートしていません" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "インデックス\"%s\"はハッシュインデックスではありません" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "インデックス\"%s\"のハッシュバージョンが不正です" + +#: access/hash/hashvalidate.c:198 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は演算子%3$sに対するサポート関数を含んでいません" + +#: access/hash/hashvalidate.c:256 access/nbtree/nbtvalidate.c:276 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は異なる型間に対応する演算子を含んでいません" + +#: access/heap/heapam.c:2057 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "並列ワーカではタプルの挿入はできません" + +#: access/heap/heapam.c:2475 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "並列処理中はタプルの削除はできません" + +#: access/heap/heapam.c:2521 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "不可視のタプルを削除しようとしました" + +#: access/heap/heapam.c:2947 access/heap/heapam.c:5736 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "並列処理中はタプルの更新はできません" + +#: access/heap/heapam.c:3080 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "不可視のタプルを更新しようとしました" + +#: access/heap/heapam.c:4391 access/heap/heapam.c:4429 access/heap/heapam.c:4686 access/heap/heapam_handler.c:452 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "リレーション\"%s\"の行ロックを取得できませんでした" + +#: access/heap/heapam_handler.c:401 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "ロック対象のタプルは同時に行われた更新によってすでに他の子テーブルに移動されています" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:662 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "行が大きすぎます: サイズは%zu、上限は%zu" + +#: access/heap/rewriteheap.c:921 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "ファイル\"%1$s\"に書き込めませんでした、%3$dバイト中%2$dバイト書き込みました: %m" + +#: access/heap/rewriteheap.c:1015 access/heap/rewriteheap.c:1134 access/transam/timeline.c:329 access/transam/timeline.c:485 access/transam/xlog.c:3298 access/transam/xlog.c:3470 access/transam/xlog.c:4668 access/transam/xlog.c:10858 access/transam/xlog.c:10896 access/transam/xlog.c:11301 access/transam/xlogfuncs.c:735 postmaster/postmaster.c:4623 replication/logical/origin.c:570 replication/slot.c:1447 storage/file/copydir.c:167 storage/smgr/md.c:218 +#: utils/time/snapmgr.c:1295 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "ファイル\"%s\"を作成できませんでした: %m" + +#: access/heap/rewriteheap.c:1144 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "ファイル\"%s\"を%uバイトに切り詰められませんでした: %m" + +#: access/heap/rewriteheap.c:1162 access/transam/timeline.c:384 access/transam/timeline.c:424 access/transam/timeline.c:502 access/transam/xlog.c:3354 access/transam/xlog.c:3526 access/transam/xlog.c:4680 postmaster/postmaster.c:4633 postmaster/postmaster.c:4643 replication/logical/origin.c:582 replication/logical/origin.c:624 replication/logical/origin.c:643 replication/logical/snapbuild.c:1623 replication/slot.c:1482 storage/file/buffile.c:502 +#: storage/file/copydir.c:207 utils/init/miscinit.c:1393 utils/init/miscinit.c:1404 utils/init/miscinit.c:1412 utils/misc/guc.c:8014 utils/misc/guc.c:8045 utils/misc/guc.c:9965 utils/misc/guc.c:9979 utils/time/snapmgr.c:1300 utils/time/snapmgr.c:1307 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "ファイル\"%s\"を書き出せませんでした: %m" + +#: access/heap/rewriteheap.c:1252 access/transam/twophase.c:1601 access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:421 postmaster/postmaster.c:1094 postmaster/syslogger.c:1465 replication/logical/origin.c:558 replication/logical/reorderbuffer.c:3907 replication/logical/snapbuild.c:1565 replication/logical/snapbuild.c:2007 replication/slot.c:1579 storage/file/fd.c:754 storage/file/fd.c:3116 storage/file/fd.c:3178 storage/file/reinit.c:255 +#: storage/ipc/dsm.c:315 storage/smgr/md.c:311 storage/smgr/md.c:367 storage/sync/sync.c:210 utils/time/snapmgr.c:1640 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "ファイル\"%s\"を削除できませんでした: %m" + +#: access/heap/vacuumlazy.c:648 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "テーブル\"%s.%s.%s\"の周回防止のための積極的自動VACUUM: インデックススキャン: %d\n" + +#: access/heap/vacuumlazy.c:650 +#, c-format +msgid "automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "テーブル\"%s.%s.%s\"の周回防止のための自動VACUUM: インデックススキャン: %d\n" + +#: access/heap/vacuumlazy.c:655 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "テーブル\"%s.%s.%s\"の積極的自動VACUUM: インデックススキャン: %d\n" + +#: access/heap/vacuumlazy.c:657 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "テーブル\"%s.%s.%s\"の自動VACUUM: インデックススキャン: %d\n" + +#: access/heap/vacuumlazy.c:664 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "ページ: %uを削除、%uが残存、%uがピンによってスキップ、%uが凍結によってスキップ\n" + +#: access/heap/vacuumlazy.c:670 +#, c-format +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "タプル: %.0fを削除, %.0fが残存, %.0fが参照されていないがまだ削除できない, 最古のxmin: %u\n" + +#: access/heap/vacuumlazy.c:676 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "バッファ使用: %lldヒット, %lld失敗, %lld ダーティ化\n" + +#: access/heap/vacuumlazy.c:680 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "平均読み取り速度: %.3f MB/s, 平均書き込み速度: %.3f MB/s\n" + +#: access/heap/vacuumlazy.c:682 +#, c-format +msgid "system usage: %s\n" +msgstr "システム使用状況: %s\n" + +#: access/heap/vacuumlazy.c:684 +#, c-format +msgid "WAL usage: %ld records, %ld full page images, " +msgstr "WAL出力: %ld レコード, %ld フルページイメージ" + +#: access/heap/vacuumlazy.c:797 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "\"%s.%s\"に対して積極的VACUUMを実行しています" + +#: access/heap/vacuumlazy.c:802 commands/cluster.c:874 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "\"%s.%s\"に対してVACUUMを実行しています" + +#: access/heap/vacuumlazy.c:841 +#, c-format +msgid "disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel" +msgstr "\"%s\"のVACUUMに対するパラレルオプションを無効化します --- 一時テーブルは並列にVACUUMできません" + +#: access/heap/vacuumlazy.c:1736 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%s\": %.0f行バージョンを%uページから削除しました" + +#: access/heap/vacuumlazy.c:1746 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f 個の不要な行バージョンがまだ削除できません、最古のxmin: %u\n" + +#: access/heap/vacuumlazy.c:1748 +#, c-format +msgid "There were %.0f unused item identifiers.\n" +msgstr "%.0f個の使われていないアイテム識別子がありました。\n" + +#: access/heap/vacuumlazy.c:1750 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "バッファピンのため%uページが、" +msgstr[1] "バッファピンのため%uページが、" + +#: access/heap/vacuumlazy.c:1754 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "凍結のため%uページがスキップされました。\n" +msgstr[1] "凍結のため%uページがスキップされました。\n" + +#: access/heap/vacuumlazy.c:1758 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%uページが完全に空です。\n" +msgstr[1] "%uページが完全に空です。\n" + +#: access/heap/vacuumlazy.c:1762 commands/indexcmds.c:3450 commands/indexcmds.c:3468 +#, c-format +msgid "%s." +msgstr "%s。" + +#: access/heap/vacuumlazy.c:1765 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%1$s\": 全 %5$u ページ中の %4$u ページで見つかった行バージョン: 削除可能 %2$.0f 行、削除不可 %3$.0f 行" + +#: access/heap/vacuumlazy.c:1896 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%s\": %d行バージョンを%dページから削除しました" + +#: access/heap/vacuumlazy.c:2151 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "インデックスのクリーンアップのために%d個の並列VACUUMワーカを起動しました (計画値: %d)" +msgstr[1] "インデックスのクリーンアップのために%d個の並列VACUUMワーカを起動しました (計画値: %d)" + +#: access/heap/vacuumlazy.c:2157 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "インデックスのVACUUMのために%d個の並列VACUUMワーカを起動しました (計画値: %d)" +msgstr[1] "インデックスのVACUUMのために%d個の並列VACUUMワーカを起動しました (計画値: %d)" + +#: access/heap/vacuumlazy.c:2449 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions by parallel vacuum worker" +msgstr "%2$d行バージョンを削除するためインデックス\"%1$s\"を並列VACUUMワーカでスキャンしました" + +#: access/heap/vacuumlazy.c:2451 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "%2$d行バージョンを削除するためインデックス\"%1$s\"をスキャンしました" + +#: access/heap/vacuumlazy.c:2515 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages as reported by parallel vacuum worker" +msgstr "並列VACUUMワーカからの報告では、現在インデックス\"%s\"は%.0f行バージョンを%uページで含んでいます" + +#: access/heap/vacuumlazy.c:2517 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "現在インデックス\"%s\"は%.0f行バージョンを%uページで含んでいます" + +#: access/heap/vacuumlazy.c:2524 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"%.0fインデックス行バージョンが削除されました。\n" +"%uインデックスページが削除され、%uページが現在再利用可能です。\n" +"%s。" + +#: access/heap/vacuumlazy.c:2621 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\":競合するロックが存在するため切り詰めを中断します" + +#: access/heap/vacuumlazy.c:2687 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": %uページから%uページに切り詰められました" + +#: access/heap/vacuumlazy.c:2752 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\": 競合するロック要求が存在するため、切り詰めを保留します" + +#: access/heap/vacuumlazy.c:3499 +#, c-format +msgid "starting parallel vacuum worker for %s" +msgstr "\"%s\"に対する並列VACUUMワーカを起動しています" + +#: access/heap/vacuumlazy.c:3590 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "リレーション\\\"%2$s.%3$s\\\"のブロック%1$uのスキャン中" + +#: access/heap/vacuumlazy.c:3596 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "リレーション\\\"%2$s.%3$s\\\"のブロック%1$uのVACUUM処理中" + +#: access/heap/vacuumlazy.c:3601 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "リレーション\\\"%2$s.%3$s\\\"のインデックス%1$sのVACUUM処理中" + +#: access/heap/vacuumlazy.c:3606 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "リレーション\\\"%2$s.%3$s\\\"のインデックス%1$sのクリーンアップ処理中" + +#: access/heap/vacuumlazy.c:3612 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "リレーション \"%s.%s\"を%uブロックに切り詰め中" + +#: access/index/amapi.c:83 commands/amcmds.c:143 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "アクセスメソッド\"%s\"のタイプが%sではありません" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "インデックスアクセスメソッド\"%s\"はハンドラを持っていません" + +#: access/index/genam.c:460 +#, c-format +msgid "transaction aborted during system catalog scan" +msgstr "システムカタログのスキャン中にトランザクションがアボートしました" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1355 commands/indexcmds.c:2517 commands/tablecmds.c:254 commands/tablecmds.c:278 commands/tablecmds.c:15590 commands/tablecmds.c:17045 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\"はインデックスではありません" + +#: access/index/indexam.c:971 +#, c-format +msgid "operator class %s has no options" +msgstr "演算子クラス%sにはオプションはありません" + +#: access/nbtree/nbtinsert.c:651 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "重複したキー値は一意性制約\"%s\"違反となります" + +#: access/nbtree/nbtinsert.c:653 +#, c-format +msgid "Key %s already exists." +msgstr "キー %s はすでに存在します。" + +#: access/nbtree/nbtinsert.c:745 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "インデックス\"%s\"内で行の再検索に失敗しました" + +#: access/nbtree/nbtinsert.c:747 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "これは不変でないインデックス式が原因である可能性があります" + +#: access/nbtree/nbtpage.c:151 access/nbtree/nbtpage.c:539 parser/parse_utilcmd.c:2156 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "インデックス\"%s\"はbtreeではありません" + +#: access/nbtree/nbtpage.c:158 access/nbtree/nbtpage.c:546 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "インデックス\"%s\"におけるバージョンの不整合: ファイルバージョン %d、現在のバージョン %d、サポートされる最小のバージョン %d" + +#: access/nbtree/nbtpage.c:1608 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "インデックス\"%s\"に削除処理中の内部ページがあります" + +#: access/nbtree/nbtpage.c:1610 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "これは9.3かそれ以前のバージョンで、アップグレード前にVACUUMが中断された際に起きた可能性があります。REINDEXしてください。" + +#: access/nbtree/nbtutils.c:2664 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "インデックス行サイズ%1$zuはインデックス\"%4$s\"でのbtreeバージョン %2$u の最大値%3$zuを超えています" + +#: access/nbtree/nbtutils.c:2670 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "インデックス行はリレーション\"%3$s\"のタプル(%1$u,%2$u)を参照しています。" + +#: access/nbtree/nbtutils.c:2674 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"バッファページの1/3を超える値はインデックス化できません。\n" +"MD5ハッシュによる関数インデックスを検討するか、もしくは全文テキストインデックスを使用してください。" + +#: access/nbtree/nbtvalidate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は型%3$sと%4$sに対応するサポート関数を含んでいません" + +#: access/spgist/spgutils.c:148 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "リーフ型が入力型と異なる場合は圧縮メソッドの定義が必要です" + +#: access/spgist/spgutils.c:762 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "SP-GiST内部タプルのサイズ%zuが最大値%zuを超えています" + +#: access/spgist/spgvalidate.c:281 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"は%4$s型に対するサポート関数%3$dを含んでいません" + +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 catalog/aclchk.c:1773 +#, c-format +msgid "\"%s\" is an index" +msgstr "\"%s\"はインデックスです" + +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 catalog/aclchk.c:1780 commands/tablecmds.c:12411 commands/tablecmds.c:15599 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "\"%s\"は複合型です" + +#: access/table/tableam.c:266 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "tid (%u, %u) はリレーション\"%s\"に対して妥当ではありません" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "%sは空にはできません。" + +#: access/table/tableamapi.c:122 utils/misc/guc.c:11960 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s が長過ぎます(最大%d文字)。" + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "テーブルアクセスメソッド\"%s\"は存在しません" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "テーブルアクセスメソッド\"%s\"は存在しません。" + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "サンプリングの割合は0と100の間です" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "トランザクション%uのコミットタイムスタンプは取得できません" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "コミットタイムスタンプ情報を取得できません" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the primary server." +msgstr "プライマリサーバで設定パラメータ\"%s\"がonに設定されていることを確認してください。" + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "設定パラメータ\"%s\"が設定されていることを確認してください。" + +#: access/transam/multixact.c:1002 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "データベース\"%s\"におけるMultiXactIds周回によるデータ損失を防ぐために、データベースは新しくMultiXactIdsを生成するコマンドを受け付けません" + +#: access/transam/multixact.c:1004 access/transam/multixact.c:1011 access/transam/multixact.c:1035 access/transam/multixact.c:1044 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"そのデータベース全体の VACUUM を実行してください。\n" +"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除も必要かもしれません。" + +#: access/transam/multixact.c:1009 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "OID %u を持つデータベースは周回によるデータ損失を防ぐために、新しいMultiXactIdsを生成するコマンドを受け付けない状態になっています" + +#: access/transam/multixact.c:1030 access/transam/multixact.c:2316 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "データベース\"%s\"はあと%u個のMultiXactIdが使われる前にVACUUMする必要があります" +msgstr[1] "データベース\"%s\"はあと%u個のMultiXactIdが使われる前にVACUUMする必要があります" + +#: access/transam/multixact.c:1039 access/transam/multixact.c:2325 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "OID %u のデータベースはあと%u個のMultiXactIdが使われる前にVACUUMする必要があります" +msgstr[1] "OID %u のデータベースはあと%u個のMultiXactIdが使われる前にVACUUMする必要があります" + +#: access/transam/multixact.c:1100 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "マルチトランザクションの\"メンバ\"が制限を超えました" + +#: access/transam/multixact.c:1101 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "このコマンドで%u個のメンバを持つマルチトランザクションが生成されますが、残りのスペースは %u 個のメンバ分しかありません。" +msgstr[1] "このコマンドで%u個のメンバを持つマルチトランザクションが生成されますが、残りのスペースは %u 個のメンバ分しかありません。" + +#: access/transam/multixact.c:1106 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "vacuum_multixact_freeze_min_age と vacuum_multixact_freeze_table_age をより小さな値に設定してOID %u のデータベースでデータベース全体にVACUUMを実行してください。" + +#: access/transam/multixact.c:1137 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "OID %u のデータベースは更に%d個のマルチトランザクションメンバが使用される前にVACUUMを実行する必要があります" +msgstr[1] "OID %u のデータベースは更に%d個のマルチトランザクションメンバが使用される前にVACUUMを実行する必要があります" + +#: access/transam/multixact.c:1142 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "vacuum_multixact_freeze_min_age と vacuum_multixact_freeze_table_age をより小さな値に設定した上で、そのデータベースでVACUUMを実行してください。" + +#: access/transam/multixact.c:1279 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "MultiXactId %uはもう存在しません: 周回しているようです" + +#: access/transam/multixact.c:1287 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "MultiXactId %uを作成できませんでした: 周回している様子" + +#: access/transam/multixact.c:2266 +#, c-format +msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +msgstr "MultiXactIdの周回制限は %u で、OID %u を持つデータベースにより制限されています" + +#: access/transam/multixact.c:2321 access/transam/multixact.c:2330 access/transam/varsup.c:151 access/transam/varsup.c:158 access/transam/varsup.c:466 access/transam/varsup.c:473 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"データベースの停止を防ぐために、データベース全体の VACUUM を実行してください。\n" +"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除も必要かもしれません。" + +#: access/transam/multixact.c:2600 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "最古のMultiXactIdメンバはオフセット%uにあります" + +#: access/transam/multixact.c:2604 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "最古のチェックポイント済みのマルチトランザクション%uがディスク上に存在しないため、マルチトランザクションメンバーの周回防止機能を無効にしました" + +#: access/transam/multixact.c:2626 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "マルチトランザクションメンバーの周回防止機能が有効になりました" + +#: access/transam/multixact.c:2629 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "マルチトランザクションの停止上限がマルチトランザクション%2$uを起点にして%1$uになりました" + +#: access/transam/multixact.c:3009 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "最古のマルチトランザクション%uが見つかりません、アクセス可能な最古のものは%u、切り詰めをスキップします" + +#: access/transam/multixact.c:3027 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "マルチトランザクション%uがディスク上に存在しないため、そこまでの切り詰めができません、切り詰めをスキップします" + +#: access/transam/multixact.c:3341 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "不正なMultiXactId: %u" + +#: access/transam/parallel.c:706 access/transam/parallel.c:825 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "パラレルワーカの初期化に失敗しました" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "More details may be available in the server log." +msgstr "詳細な情報がはサーバログにあるかもしれません。" + +#: access/transam/parallel.c:887 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "並列処理中にpostmasterが終了しました" + +#: access/transam/parallel.c:1074 +#, c-format +msgid "lost connection to parallel worker" +msgstr "パラレルワーカへの接続を失いました" + +#: access/transam/parallel.c:1140 access/transam/parallel.c:1142 +msgid "parallel worker" +msgstr "パラレルワーカ" + +#: access/transam/parallel.c:1293 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "動的共有メモリセグメントをマップできませんでした" + +#: access/transam/parallel.c:1298 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "動的共有メモリセグメントのマジックナンバーが不正です" + +#: access/transam/slru.c:696 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "ファイル\"%s\"が存在しません。ゼロとして読み込みます" + +#: access/transam/slru.c:920 access/transam/slru.c:926 access/transam/slru.c:934 access/transam/slru.c:939 access/transam/slru.c:946 access/transam/slru.c:951 access/transam/slru.c:958 access/transam/slru.c:965 +#, c-format +msgid "could not access status of transaction %u" +msgstr "トランザクション%uのステータスにアクセスできませんでした" + +#: access/transam/slru.c:921 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "ファイル\"%s\"をオープンできませんでした: %m。" + +#: access/transam/slru.c:927 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "ファイル\"%s\"のオフセット%uにシークできませんでした: %m。" + +#: access/transam/slru.c:935 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "ファイル\"%s\"のオフセット%uを読み取れませんでした: %m。" + +#: access/transam/slru.c:940 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "ファイル\"%s\"のオフセット%uを読み取れませんでした: 読み込んだバイト数が足りません。" + +#: access/transam/slru.c:947 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "ファイル\"%s\"のオフセット%uに書き出せませんでした: %m。" + +#: access/transam/slru.c:952 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "ファイル\"%s\"のオフセット%uに書き出せませんでした: 書き込んだバイト数が足りません。" + +#: access/transam/slru.c:959 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "ファイル\"%s\"をfsyncできませんでした: %m。" + +#: access/transam/slru.c:966 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "ファイル\"%s\"をクローズできませんでした: %m。" + +#: access/transam/slru.c:1237 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "ディレクトリ\"%s\"を切り詰めできませんでした: 明らかに周回しています" + +#: access/transam/slru.c:1292 access/transam/slru.c:1348 +#, c-format +msgid "removing file \"%s\"" +msgstr "ファイル\"%s\"を削除しています" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "履歴ファイル内の構文エラー: %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "数字のタイムラインIDを想定しました。" + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "先行書き込みログの切り替え点の場所があるはずでした。" + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "履歴ファイル内の不正なデータ: %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "タイムラインIDは昇順でなければなりません" + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "履歴ファイル\"%s\"内に不正なデータがありました" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "タイムラインIDは子のタイムラインIDより小さくなければなりません。" + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "要求されたタイムライン%uがサーバの履歴上に存在しません" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "トランザクション識別子\"%s\"は長すぎます" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "トランザクションの準備は無効にされているためできません。" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "max_prepared_transactionsを非ゼロに設定してください。" + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "トランザクション識別子\"%s\"はすでに存在します" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2360 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "準備済みのトランザクションの最大数に達しました" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2361 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "max_prepared_transactionsを増加してください(現状%d)。" + +#: access/transam/twophase.c:583 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "識別子\"%s\"の準備されたトランザクションのロックが取得できません" + +#: access/transam/twophase.c:589 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "準備されたトランザクションの終了が拒否されました" + +#: access/transam/twophase.c:590 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "スーパユーザまたはこのトランザクションを準備したユーザである必要があります。" + +#: access/transam/twophase.c:601 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "準備されたトランザクションは別のデータベースに属しています" + +#: access/transam/twophase.c:602 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "終了させるためにはこのトランザクションを準備したデータベースに接続してください。" + +#: access/transam/twophase.c:617 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "識別子\"%s\"の準備されたトランザクションはありません" + +#: access/transam/twophase.c:1092 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "2相状態ファイルの最大長が制限を超えました" + +#: access/transam/twophase.c:1246 +#, c-format +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "ファイル\"%s\"のサイズが不正: %zu バイト" +msgstr[1] "ファイル\"%s\"のサイズが不正: %zu バイト" + +#: access/transam/twophase.c:1255 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "ファイル\"%s\"のCRCオフセットのアライメントが不正です" + +#: access/transam/twophase.c:1288 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "ファイル\"%s\"に格納されているマジックナンバーが不正です" + +#: access/transam/twophase.c:1294 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "ファイル\"%s\"内に格納されているサイズが不正です" + +#: access/transam/twophase.c:1306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "算出されたCRCチェックサムがファイル\"%s\"に格納されている値と一致しません" + +#: access/transam/twophase.c:1336 access/transam/xlog.c:6492 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "WALリーダの割り当てに中に失敗しました。" + +#: access/transam/twophase.c:1343 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "WALの%X/%Xから2相状態を読み取れませんでした" + +#: access/transam/twophase.c:1351 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "WALの%X/%Xにあるはずの2相状態のデータがありません" + +#: access/transam/twophase.c:1629 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "ファイル\"%s\"を再作成できませんでした: %m" + +#: access/transam/twophase.c:1756 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "長時間実行中の準備済みトランザクションのために%u個の2相状態ファイルが書き込まれました" +msgstr[1] "長時間実行中の準備済みトランザクションのために%u個の2相状態ファイルが書き込まれました" + +#: access/transam/twophase.c:1990 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "共有メモリから準備済みトランザクション%uを復元します" + +#: access/transam/twophase.c:2081 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "不要になったトランザクション%uの2相状態ファイルを削除します" + +#: access/transam/twophase.c:2088 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "不要になったトランザクション%uの2相状態をメモリから削除します" + +#: access/transam/twophase.c:2101 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "未来のトランザクション%uの2相状態ファイルを削除します" + +#: access/transam/twophase.c:2108 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "未来のトランザクション%uの2相状態をメモリから削除します" + +#: access/transam/twophase.c:2133 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "トランザクション%uの2相状態ファイルが破損しています" + +#: access/transam/twophase.c:2138 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "メモリ上にあるトランザクション%uの2相状態が破損しています" + +#: access/transam/varsup.c:129 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "データベース\"%s\"における周回によるデータ損失を防ぐために、データベースは問い合わせを受け付けていません" + +#: access/transam/varsup.c:131 access/transam/varsup.c:138 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"postmaster を停止後、シングルユーザモードでデータベースをVACUUMを実行してください。\n" +"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除も必要かもしれません。" + +#: access/transam/varsup.c:136 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "OID %uのデータベースは周回によるデータ損失を防ぐために、データベースは問い合わせを受け付けていません" + +#: access/transam/varsup.c:148 access/transam/varsup.c:463 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "データベース\"%s\"は%uトランザクション以内にVACUUMする必要があります" + +#: access/transam/varsup.c:155 access/transam/varsup.c:470 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "OID %uのデータベースは%uトランザクション以内にVACUUMを実行する必要があります" + +#: access/transam/varsup.c:428 +#, c-format +msgid "transaction ID wrap limit is %u, limited by database with OID %u" +msgstr "トランザクションIDの周回制限値はOID %uのデータベースにより%uに制限されています" + +#: access/transam/xact.c:1045 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "1トランザクション内では 2^32-2 個より多くのコマンドを実行できません" + +#: access/transam/xact.c:1582 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "コミットされたサブトランザクション数の最大値(%d)が制限を越えました" + +#: access/transam/xact.c:2422 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "一時オブジェクトに対する操作を行ったトランザクションをPREPAREすることはできません" + +#: access/transam/xact.c:2432 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "エクスポートされたスナップショットを持つトランザクションをPREPAREすることはできません" + +#: access/transam/xact.c:2441 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "論理レプリケーションワーカから操作されたトランザクションをPREPAREすることはできません" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3389 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%sはトランザクションブロックの内側では実行できません" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3399 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%sはサブトランザクションブロックの内側では実行できません" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3409 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s は関数内での実行はできません" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3478 access/transam/xact.c:3784 access/transam/xact.c:3863 access/transam/xact.c:3986 access/transam/xact.c:4137 access/transam/xact.c:4206 access/transam/xact.c:4317 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%sはトランザクションブロック内でのみ使用できます" + +#: access/transam/xact.c:3670 +#, c-format +msgid "there is already a transaction in progress" +msgstr "すでにトランザクションが実行中です" + +#: access/transam/xact.c:3789 access/transam/xact.c:3868 access/transam/xact.c:3991 +#, c-format +msgid "there is no transaction in progress" +msgstr "実行中のトランザクションがありません" + +#: access/transam/xact.c:3879 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "並列処理中にはコミットはできません" + +#: access/transam/xact.c:4002 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "パラレル処理中にロールバックはできません" + +#: access/transam/xact.c:4101 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "パラレル処理中にセーブポイントは定義できません" + +#: access/transam/xact.c:4188 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "並列処理中はセーブポイントの解放はできません" + +#: access/transam/xact.c:4198 access/transam/xact.c:4249 access/transam/xact.c:4309 access/transam/xact.c:4358 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "セーブポイント\"%s\"は存在しません" + +#: access/transam/xact.c:4255 access/transam/xact.c:4364 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "セーブポイント\"%s\"は現在のセーブポイントレベルには存在しません" + +#: access/transam/xact.c:4297 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "パラレル処理中にセーブポイントのロールバックはできません" + +#: access/transam/xact.c:4425 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "並列処理中はサブトランザクションを開始できません" + +#: access/transam/xact.c:4493 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "並列処理中はサブトランザクションをコミットできません" + +#: access/transam/xact.c:5136 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "1トランザクション内には 2^32-1 個より多くのサブトランザクションを作成できません" + +#: access/transam/xlog.c:2552 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "ログファイル%sのオフセット%uに長さ%zuの書き込みができませんでした: %m" + +#: access/transam/xlog.c:2828 +#, c-format +msgid "updated min recovery point to %X/%X on timeline %u" +msgstr "最小リカバリポイントをタイムライン%3$uの%1$X/%2$Xに更新しました" + +#: access/transam/xlog.c:3942 access/transam/xlogutils.c:801 replication/walsender.c:2503 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "要求された WAL セグメント %s はすでに削除されています" + +#: access/transam/xlog.c:4185 +#, c-format +msgid "recycled write-ahead log file \"%s\"" +msgstr "先行書き込みログファイル\"%s\"を再利用しました" + +#: access/transam/xlog.c:4197 +#, c-format +msgid "removing write-ahead log file \"%s\"" +msgstr "先行書き込みログファイル\"%s\"を削除します" + +#: access/transam/xlog.c:4217 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "ファイル\"%s\"の名前を変更できませんでした: %m" + +#: access/transam/xlog.c:4259 access/transam/xlog.c:4269 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "WALディレクトリ\"%s\"は存在しません" + +#: access/transam/xlog.c:4275 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "なかったWALディレクトリ\"%s\"を作成しています" + +#: access/transam/xlog.c:4278 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "なかったディレクトリ\"%s\"の作成に失敗しました: %m" + +#: access/transam/xlog.c:4381 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "ログファイル%2$s、オフセット%3$uのタイムラインID%1$uは想定外です" + +#: access/transam/xlog.c:4519 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "新しいタイムライン%uはデータベースシステムのタイムライン%uの子ではありません" + +#: access/transam/xlog.c:4533 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "新しいタイムライン%uは現在のデータベースシステムのタイムライン%uから現在のリカバリポイント%X/%Xより前に分岐しています" + +#: access/transam/xlog.c:4552 +#, c-format +msgid "new target timeline is %u" +msgstr "新しい目標タイムラインは%uです" + +#: access/transam/xlog.c:4588 +#, c-format +msgid "could not generate secret authorization token" +msgstr "秘密の認証トークンを生成できませんでした" + +#: access/transam/xlog.c:4747 access/transam/xlog.c:4756 access/transam/xlog.c:4780 access/transam/xlog.c:4787 access/transam/xlog.c:4794 access/transam/xlog.c:4799 access/transam/xlog.c:4806 access/transam/xlog.c:4813 access/transam/xlog.c:4820 access/transam/xlog.c:4827 access/transam/xlog.c:4834 access/transam/xlog.c:4841 access/transam/xlog.c:4850 access/transam/xlog.c:4857 utils/init/miscinit.c:1550 +#, c-format +msgid "database files are incompatible with server" +msgstr "データベースファイルがサーバと互換性がありません" + +#: access/transam/xlog.c:4748 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "データベースクラスタはPG_CONTROL_VERSION %d (0x%08x)で初期化されましたが、サーバはPG_CONTROL_VERSION %d (0x%08x)でコンパイルされています。" + +#: access/transam/xlog.c:4752 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "これはバイトオーダの不整合の可能性があります。initdbを実行する必要がありそうです。" + +#: access/transam/xlog.c:4757 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "データベースクラスタはPG_CONTROL_VERSION %d で初期化されましたが、サーバは PG_CONTROL_VERSION %d でコンパイルされています。" + +#: access/transam/xlog.c:4760 access/transam/xlog.c:4784 access/transam/xlog.c:4791 access/transam/xlog.c:4796 +#, c-format +msgid "It looks like you need to initdb." +msgstr "initdbが必要のようです。" + +#: access/transam/xlog.c:4771 +#, c-format +msgid "incorrect checksum in control file" +msgstr "制御ファイル内のチェックサムが不正です" + +#: access/transam/xlog.c:4781 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "データベースクラスタは CATALOG_VERSION_NO %d で初期化されましたが、サーバは CATALOG_VERSION_NO %d でコンパイルされています。" + +#: access/transam/xlog.c:4788 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "データベースクラスタは MAXALIGN %d で初期化されましたが、サーバは MAXALIGN %d でコンパイルされています。" + +#: access/transam/xlog.c:4795 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "データベースクラスタはサーバ実行ファイルと異なる浮動小数点書式を使用しているようです。" + +#: access/transam/xlog.c:4800 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "データベースクラスタは BLCKSZ %d で初期化されましたが、サーバは BLCKSZ %d でコンパイルされています。" + +#: access/transam/xlog.c:4803 access/transam/xlog.c:4810 access/transam/xlog.c:4817 access/transam/xlog.c:4824 access/transam/xlog.c:4831 access/transam/xlog.c:4838 access/transam/xlog.c:4845 access/transam/xlog.c:4853 access/transam/xlog.c:4860 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "再コンパイルもしくは initdb が必要そうです。" + +#: access/transam/xlog.c:4807 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "データベースクラスタは RELSEG_SIZE %d で初期化されましたが、サーバは RELSEG_SIZE %d でコンパイルされています。" + +#: access/transam/xlog.c:4814 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "データベースクラスタは XLOG_BLCKSZ %d で初期化されましたが、サーバは XLOG_BLCKSZ %d でコンパイルされています。" + +#: access/transam/xlog.c:4821 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "データベースクラスタは NAMEDATALEN %d で初期化されましたが、サーバは NAMEDATALEN %d でコンパイルされています。" + +#: access/transam/xlog.c:4828 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "データベースクラスタは INDEX_MAX_KEYS %d で初期化されましたが、サーバは INDEX_MAX_KEYS %d でコンパイルされています。" + +#: access/transam/xlog.c:4835 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "データベースクラスタは TOAST_MAX_CHUNK_SIZE %d で初期化されましたが、サーバは TOAST_MAX_CHUNK_SIZE %d でコンパイルされています。" + +#: access/transam/xlog.c:4842 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "データベースクラスタは LOBLKSIZE %d で初期化されましたが、サーバは LOBLKSIZE %d でコンパイルされています。" + +#: access/transam/xlog.c:4851 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "データベースクラスタは USE_FLOAT8_BYVAL なしで初期化されましたが、サーバ側は USE_FLOAT8_BYVAL 付きでコンパイルされています。" + +#: access/transam/xlog.c:4858 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "データベースクラスタは USE_FLOAT8_BYVAL 付きで初期化されましたが、サーバ側は USE_FLOAT8_BYVAL なしでコンパイルされています。" + +#: access/transam/xlog.c:4867 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WALセグメントのサイズ指定は1MBと1GBの間の2の累乗でなければなりません、しかしコントロールファイルでは%dバイトとなっています" +msgstr[1] "WALセグメントのサイズ指定は1MBと1GBの間の2の累乗でなければなりません、しかしコントロールファイルでは%dバイトとなっています" + +#: access/transam/xlog.c:4879 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\"は最低でも\"wal_segment_size\"の2倍である必要があります。" + +#: access/transam/xlog.c:4883 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\"は最低でも\"wal_segment_size\"の2倍である必要があります。" + +#: access/transam/xlog.c:5316 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "ブートストラップの先行書き込みログファイルに書き込めませんでした: %m" + +#: access/transam/xlog.c:5324 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "ブートストラップの先行書き込みログファイルをfsyncできませんでした: %m" + +#: access/transam/xlog.c:5330 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "ブートストラップの先行書き込みログファイルをクローズできませんでした: %m" + +#: access/transam/xlog.c:5391 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "リカバリコマンドファイル \"%s\"の使用はサポートされません" + +#: access/transam/xlog.c:5456 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "スタンバイモードはシングルユーザサーバではサポートされません" + +#: access/transam/xlog.c:5473 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "primary_conninfo と restore_command のどちらも指定されていません" + +#: access/transam/xlog.c:5474 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "データベースサーバはpg_walサブディレクトリに置かれたファイルを定期的に確認します。" + +#: access/transam/xlog.c:5482 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "スタンバイモードを有効にしない場合は、restore_command の指定が必要です" + +#: access/transam/xlog.c:5520 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "リカバリ目標タイムライン%uが存在しません" + +#: access/transam/xlog.c:5642 +#, c-format +msgid "archive recovery complete" +msgstr "アーカイブリカバリが完了しました" + +#: access/transam/xlog.c:5708 access/transam/xlog.c:5981 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "リカバリ処理は一貫性確保後に停止します" + +#: access/transam/xlog.c:5729 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "リカバリ処理はWAL位置(LSN)\"%X/%X\"の前で停止します" + +#: access/transam/xlog.c:5815 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "リカバリ処理はトランザクション%uのコミット、時刻%sの前に停止します" + +#: access/transam/xlog.c:5822 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "リカバリ処理はトランザクション%uのアボート、時刻%sの前に停止します" + +#: access/transam/xlog.c:5875 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "リカバリ処理は復元ポイント\"%s\"、時刻%s に停止します" + +#: access/transam/xlog.c:5893 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "リカバリ処理はWAL位置(LSN)\"%X/%X\"の後で停止します" + +#: access/transam/xlog.c:5961 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "リカバリ処理はトランザクション%uのコミット、時刻%sの後に停止します" + +#: access/transam/xlog.c:5969 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "リカバリ処理はトランザクション%uのアボート、時刻%sの後に停止します" + +#: access/transam/xlog.c:6018 +#, c-format +msgid "pausing at the end of recovery" +msgstr "リカバリ完了位置で一時停止しています" + +#: access/transam/xlog.c:6019 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "再開するには pg_wal_replay_resume() を実行してください" + +#: access/transam/xlog.c:6022 +#, c-format +msgid "recovery has paused" +msgstr "リカバリは一時停止中です" + +#: access/transam/xlog.c:6023 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "再開するには pg_xlog_replay_resume() を実行してください" + +#: access/transam/xlog.c:6240 +#, c-format +msgid "hot standby is not possible because %s = %d is a lower setting than on the primary server (its value was %d)" +msgstr "%s = %d はプライマリサーバの設定値より小さいため、ホットスタンバイは利用できません (もとの値は%d)" + +#: access/transam/xlog.c:6264 +#, c-format +msgid "WAL was generated with wal_level=minimal, data may be missing" +msgstr "wal_level=minimal でWALが生成されました。データが失われる可能性があります" + +#: access/transam/xlog.c:6265 +#, c-format +msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgstr "これは新しいベースバックアップを取らずに、一時的に wal_level=minimal にした場合に起こります。" + +#: access/transam/xlog.c:6276 +#, c-format +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the primary server" +msgstr "プライマリサーバでwal_levelが\"replica\"またはそれ以上に設定されていないため、ホットスタンバイを使用できません" + +#: access/transam/xlog.c:6277 +#, c-format +msgid "Either set wal_level to \"replica\" on the primary, or turn off hot_standby here." +msgstr "プライマリでwal_levelを\"replica\"にするか、またはここでhot_standbyを無効にしてください。" + +#: access/transam/xlog.c:6339 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "制御ファイル内のチェックポイント位置が不正です" + +#: access/transam/xlog.c:6350 +#, c-format +msgid "database system was shut down at %s" +msgstr "データベースシステムは %s にシャットダウンしました" + +#: access/transam/xlog.c:6356 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "データベースシステムはリカバリ中 %s にシャットダウンしました" + +#: access/transam/xlog.c:6362 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "データベースシステムはシャットダウン中に中断されました; %s まで動作していたことは確認できます" + +#: access/transam/xlog.c:6368 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "データベースシステムはリカバリ中 %s に中断されました" + +#: access/transam/xlog.c:6370 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "これはおそらくデータ破損があり、リカバリのために直前のバックアップを使用しなければならないことを意味します。" + +#: access/transam/xlog.c:6376 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "データベースシステムはリカバリ中ログ時刻 %s に中断されました" + +#: access/transam/xlog.c:6378 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "これが1回以上起きた場合はデータが破損している可能性があるため、より以前のリカバリ目標を選ぶ必要があるかもしれません。" + +#: access/transam/xlog.c:6384 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "データベースシステムは中断されました: %s まで動作していたことは確認できます" + +#: access/transam/xlog.c:6390 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "制御ファイル内のデータベース・クラスタ状態が不正です" + +#: access/transam/xlog.c:6447 +#, c-format +msgid "entering standby mode" +msgstr "スタンバイモードに入ります" + +#: access/transam/xlog.c:6450 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "XID%uまでのポイントインタイムリカバリを開始します" + +#: access/transam/xlog.c:6454 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "%sまでのポイントインタイムリカバリを開始します" + +#: access/transam/xlog.c:6458 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "\"%s\"までのポイントインタイムリカバリを開始します" + +#: access/transam/xlog.c:6462 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "WAL位置(LSN) \"%X/%X\"までのポイントインタイムリカバリを開始します" + +#: access/transam/xlog.c:6467 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "最も古い一貫性確保点までのポイントインタイムリカバリを開始します" + +#: access/transam/xlog.c:6470 +#, c-format +msgid "starting archive recovery" +msgstr "アーカイブリカバリを開始しています" + +#: access/transam/xlog.c:6529 access/transam/xlog.c:6662 +#, c-format +msgid "checkpoint record is at %X/%X" +msgstr "チェックポイントレコードは%X/%Xにあります" + +#: access/transam/xlog.c:6544 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "チェックポイントレコードが参照している redo 位置を見つけられませんでした" + +#: access/transam/xlog.c:6545 access/transam/xlog.c:6555 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" +"バックアップから復旧しているのであれば、touch \"%s/recovery.signal\" の実行および必要なオプションの追加を行ってください。\n" +"バックアップからの復旧でなければ、\"%s/backup_label\"の削除を試みてください。.\n" +"バックアップから復旧で\"%s/backup_label\"を削除すると、クラスタは壊れた状態で復旧されることに注意してください。" + +#: access/transam/xlog.c:6554 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "必要なチェックポイントが見つかりませんでした" + +#: access/transam/xlog.c:6583 commands/tablespace.c:654 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を作成できませんでした: %m" + +#: access/transam/xlog.c:6615 access/transam/xlog.c:6621 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "ファイル\"%2$s\"が存在しないためファイル\"%1$s\"を無視します" + +#: access/transam/xlog.c:6617 access/transam/xlog.c:11817 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "ファイル\"%s\"は\"%s\"にリネームされました。" + +#: access/transam/xlog.c:6623 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m。" + +#: access/transam/xlog.c:6674 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "有効なチェックポイントが見つかりませんでした" + +#: access/transam/xlog.c:6712 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "要求されたタイムライン%uはこのサーバの履歴からの子孫ではありません" + +#: access/transam/xlog.c:6714 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "タイムライン%3$uの最終チェックポイントは%1$X/%2$Xですが、要求されたタイムラインの履歴の中ではサーバはそのタイムラインから%4$X/%5$Xで分岐しています。" + +#: access/transam/xlog.c:6730 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "要求されたタイムライン%1$uはタイムライン%4$uの最小リカバリポイント%2$X/%3$Xを含みません" + +#: access/transam/xlog.c:6761 +#, c-format +msgid "invalid next transaction ID" +msgstr "次のトランザクションIDが不正です" + +#: access/transam/xlog.c:6855 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "チェックポイントレコード内の不正なREDO" + +#: access/transam/xlog.c:6866 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "シャットダウン・チェックポイントにおける不正なREDOレコード" + +#: access/transam/xlog.c:6900 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "データベースシステムは正しくシャットダウンされていません; 自動リカバリを実行中" + +#: access/transam/xlog.c:6904 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "タイムライン%uから、タイムライン%uを目標としてクラッシュリカバリを開始します" + +#: access/transam/xlog.c:6951 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_labelに制御ファイルと整合しないデータが含まれます" + +#: access/transam/xlog.c:6952 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "これはバックアップが破損しており、リカバリには他のバックアップを使用しなければならないことを意味します。" + +#: access/transam/xlog.c:7043 +#, c-format +msgid "initializing for hot standby" +msgstr "ホットスタンバイのための初期化を行っています" + +#: access/transam/xlog.c:7176 +#, c-format +msgid "redo starts at %X/%X" +msgstr "REDOを%X/%Xから開始します" + +#: access/transam/xlog.c:7400 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "要求されたリカバリ停止ポイントは、一貫性があるリカバリポイントより前にあります" + +#: access/transam/xlog.c:7438 +#, c-format +msgid "redo done at %X/%X" +msgstr "REDOが%X/%Xで終了しました" + +#: access/transam/xlog.c:7443 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "最後に完了したトランザクションのログ時刻は%sでした" + +#: access/transam/xlog.c:7452 +#, c-format +msgid "redo is not required" +msgstr "REDOは必要ありません" + +#: access/transam/xlog.c:7464 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "指定したリカバリターゲットに到達する前にリカバリが終了しました" + +#: access/transam/xlog.c:7543 access/transam/xlog.c:7547 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "オンラインバックアップの終了より前にWALが終了しました" + +#: access/transam/xlog.c:7544 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "オンラインバックアップ中に生成されたすべてのWALがリカバリで利用可能である必要があります。" + +#: access/transam/xlog.c:7548 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "pg_start_backup() を使ったオンラインバックアップは pg_stop_backup() で終了なければならず、かつその時点までのすべてのWALはリカバリで利用可能である必要があります" + +#: access/transam/xlog.c:7551 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WALが一貫性があるリカバリポイントより前で終了しました" + +#: access/transam/xlog.c:7586 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "新しいタイムラインIDを選択: %u" + +#: access/transam/xlog.c:8034 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "%X/%X でリカバリの一貫性が確保されました" + +#: access/transam/xlog.c:8244 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "制御ファイル内の最初のチェックポイントへのリンクが不正です" + +#: access/transam/xlog.c:8248 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "backup_labelファイル内のチェックポイントへのリンクが不正です" + +#: access/transam/xlog.c:8266 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "最初のチェックポイントレコードが不正です" + +#: access/transam/xlog.c:8270 +#, c-format +msgid "invalid checkpoint record" +msgstr "チェックポイントレコードが不正です" + +#: access/transam/xlog.c:8281 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "プライマリチェックポイントレコード内のリソースマネージャIDが不正です" + +#: access/transam/xlog.c:8285 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "チェックポイントレコード内のリソースマネージャIDがで不正です" + +#: access/transam/xlog.c:8298 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "最初のチェックポイントレコード内のxl_infoが不正です" + +#: access/transam/xlog.c:8302 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "チェックポイントレコード内のxl_infoが不正です" + +#: access/transam/xlog.c:8313 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "最初のチェックポイントレコード長が不正です" + +#: access/transam/xlog.c:8317 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "チェックポイントレコード長が不正です" + +#: access/transam/xlog.c:8498 +#, c-format +msgid "shutting down" +msgstr "シャットダウンしています" + +#: access/transam/xlog.c:8818 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "システムがアイドル状態なためチェックポイントがスキップされました" + +#: access/transam/xlog.c:9018 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "データベースのシャットダウンに並行して、先行書き込みログが発生しました" + +#: access/transam/xlog.c:9275 +#, c-format +msgid "skipping restartpoint, recovery has already ended" +msgstr "再開ポイントをスキップします、リカバリはすでに終わっています" + +#: access/transam/xlog.c:9298 +#, c-format +msgid "skipping restartpoint, already performed at %X/%X" +msgstr "%X/%X ですでに実行済みの再開ポイントをスキップします" + +#: access/transam/xlog.c:9466 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "リカバリ再開ポイントは%X/%Xです" + +#: access/transam/xlog.c:9468 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "最後に完了したトランザクションはログ時刻 %s のものです" + +#: access/transam/xlog.c:9710 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "復帰ポイント\"%s\"が%X/%Xに作成されました" + +#: access/transam/xlog.c:9855 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "チェックポイントレコードにおいて想定外の前回のタイムラインID %u(現在のタイムラインIDは%u)がありました" + +#: access/transam/xlog.c:9864 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "チェックポイントレコードにおいて想定外のタイムラインID %u (%uの後)がありました" + +#: access/transam/xlog.c:9880 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "タイムライン%4$uの最小リカバリポイント%2$X/%3$Xに達する前のチェックポイントレコード内の想定外のタイムラインID%1$u。" + +#: access/transam/xlog.c:9956 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "オンラインバックアップはキャンセルされ、リカバリを継続できません" + +#: access/transam/xlog.c:10012 access/transam/xlog.c:10068 access/transam/xlog.c:10091 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "チェックポイントレコードにおいて想定外のタイムラインID %u(%uのはず)がありました" + +#: access/transam/xlog.c:10417 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "ライトスルーファイル\"%s\"をfsyncできませんでした: %m" + +#: access/transam/xlog.c:10423 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "ファイル\"%s\"をfdatasyncできませんでした: %m" + +#: access/transam/xlog.c:10521 access/transam/xlog.c:11050 access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "リカバリ中はWAL制御関数は実行できません。" + +#: access/transam/xlog.c:10530 access/transam/xlog.c:11059 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "オンラインバックアップを行うにはWALレベルが不十分です" + +#: access/transam/xlog.c:10531 access/transam/xlog.c:11060 access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "サーバの開始時にwal_levelを\"replica\"または \"logical\"にセットする必要があります。" + +#: access/transam/xlog.c:10536 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "バックアップラベルが長すぎます (最大%dバイト)" + +#: access/transam/xlog.c:10573 access/transam/xlog.c:10849 access/transam/xlog.c:10887 +#, c-format +msgid "a backup is already in progress" +msgstr "すでにバックアップが進行中です" + +#: access/transam/xlog.c:10574 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "pg_stop_backup()を実行後に再試行してください" + +#: access/transam/xlog.c:10670 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "full_page_writes=off で生成されたWALは最終リスタートポイントから再生されます" + +#: access/transam/xlog.c:10672 access/transam/xlog.c:11255 +#, c-format +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the primary, and then try an online backup again." +msgstr "つまりこのスタンバイで取得されたバックアップは破損しており、使用すべきではありません。プライマリでfull_page_writesを有効にしCHECKPOINTを実行したのち、再度オンラインバックアップを試行してください。" + +#: access/transam/xlog.c:10747 replication/basebackup.c:1418 utils/adt/misc.c:342 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "シンボリックリンク\"%s\"の参照先が長すぎます" + +#: access/transam/xlog.c:10799 commands/tablespace.c:402 commands/tablespace.c:566 replication/basebackup.c:1433 utils/adt/misc.c:350 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "このプラットフォームではテーブル空間はサポートしていません" + +#: access/transam/xlog.c:10850 access/transam/xlog.c:10888 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "バックアップが進行中でないことが確かであれば、ファイル\"%s\"を削除し再実行してください。" + +#: access/transam/xlog.c:11075 +#, c-format +msgid "exclusive backup not in progress" +msgstr "排他バックアップは進行中ではありません" + +#: access/transam/xlog.c:11102 +#, c-format +msgid "a backup is not in progress" +msgstr "バックアップが進行中ではありません" + +#: access/transam/xlog.c:11188 access/transam/xlog.c:11201 access/transam/xlog.c:11590 access/transam/xlog.c:11596 access/transam/xlog.c:11644 access/transam/xlog.c:11717 access/transam/xlogfuncs.c:692 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "ファイル\"%s\"内の不正なデータ" + +#: access/transam/xlog.c:11205 replication/basebackup.c:1266 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "オンラインバックアップ中にスタンバイが昇格しました" + +#: access/transam/xlog.c:11206 replication/basebackup.c:1267 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "つまり取得中のバックアップは破損しているため使用してはいけません。再度オンラインバックアップを取得してください。" + +#: access/transam/xlog.c:11253 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "full_page_writes=offで生成されたWALはオンラインバックアップ中に再生されます" + +#: access/transam/xlog.c:11373 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "ベースバックアップ完了、必要な WAL セグメントがアーカイブされるのを待っています" + +#: access/transam/xlog.c:11385 +#, c-format +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "まだ必要なすべての WAL セグメントがアーカイブされるのを待っています(%d 秒経過)" + +#: access/transam/xlog.c:11387 +#, c-format +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "archive_commandが適切に実行されていることを確認してください。バックアップ処理は安全に取り消すことができますが、全てのWALセグメントがそろわなければこのバックアップは利用できません。" + +#: access/transam/xlog.c:11394 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "必要なすべての WAL セグメントがアーカイブされました" + +#: access/transam/xlog.c:11398 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "WAL アーカイブが有効になっていません。バックアップを完了させるには、すべての必要なWALセグメントが他の方法でコピーされたことを確認してください。" + +#: access/transam/xlog.c:11451 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "バックエンドが pg_stop_backup の呼び出し前に終了したため、バックアップは異常終了しました" + +#: access/transam/xlog.c:11627 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "ファイル\"%2$s\"内のバックアップ時刻は %1$s" + +#: access/transam/xlog.c:11632 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "ファイル\"%2$s\"内のバックアップラベルは %1$s" + +#: access/transam/xlog.c:11645 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "読み取られたタイムラインIDは%uでしたが、%uであるはずです。" + +#: access/transam/xlog.c:11649 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "ファイル\"%2$s\"内のバックアップタイムラインは %1$u" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11757 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "%X/%Xにある%sのWAL再生" + +#: access/transam/xlog.c:11806 +#, c-format +msgid "online backup mode was not canceled" +msgstr "オンラインバックアップモードはキャンセルされていません" + +#: access/transam/xlog.c:11807 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m。" + +#: access/transam/xlog.c:11816 access/transam/xlog.c:11828 access/transam/xlog.c:11838 +#, c-format +msgid "online backup mode canceled" +msgstr "オンラインバックアップモードがキャンセルされました" + +#: access/transam/xlog.c:11829 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "ファイル\"%s\"、\"%s\"の名前はそれぞれ\"%s\"、\"%s\"へと変更されました。" + +#: access/transam/xlog.c:11839 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "ファイル\"%s\"の名前は\"%s\"に変更できましたが、\"%s\"の名前は\"%s\"に変更できませんでした: %m" + +#: access/transam/xlog.c:11972 access/transam/xlogutils.c:970 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "ログセグメント%s、オフセット%uを読み取れませんでした: %m" + +#: access/transam/xlog.c:11978 access/transam/xlogutils.c:977 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "ログセグメント%1$s、オフセット%2$uを読み取れませんでした: %4$zu 中 %3$d の読み取り" + +#: access/transam/xlog.c:12507 +#, c-format +msgid "wal receiver process shutdown requested" +msgstr "wal receiverプロセスのシャットダウンが要求されました" + +#: access/transam/xlog.c:12594 +#, c-format +msgid "received promote request" +msgstr "昇格要求を受信しました" + +#: access/transam/xlog.c:12607 +#, c-format +msgid "promote trigger file found: %s" +msgstr "昇格トリガファイルがあります: %s" + +#: access/transam/xlog.c:12615 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "昇格トリガファイル\"%s\"のstatに失敗しました: %m" + +#: access/transam/xlogarchive.c:205 +#, c-format +msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgstr "アーカイブファイル\"%s\"のサイズが不正です: %lu、正しくは%lu" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "ログファイル\"%s\"をアーカイブからリストアしました" + +#: access/transam/xlogarchive.c:259 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "ファイル\"%s\"をアーカイブからリストアできませんでした: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:368 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" + +#: access/transam/xlogarchive.c:478 access/transam/xlogarchive.c:542 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "アーカイブステータスファイル\"%s\"を作成できませんでした: %m" + +#: access/transam/xlogarchive.c:486 access/transam/xlogarchive.c:550 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "アーカイブステータスファイル\"%s\"に書き込めませんでした: %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "このセッションではすでにバックアップが進行中です" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "非排他バックアップが進行中です" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "pg_stop_backup('f') を実行しようとしていたのではないですか?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1311 commands/event_trigger.c:1863 commands/extension.c:1944 commands/extension.c:2052 commands/extension.c:2337 commands/prepare.c:713 executor/execExpr.c:2203 executor/execSRF.c:728 executor/functions.c:1046 foreign/foreign.c:520 libpq/hba.c:2668 replication/logical/launcher.c:1090 replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1481 replication/slotfuncs.c:252 +#: replication/walsender.c:3258 storage/ipc/shmem.c:550 utils/adt/datetime.c:4766 utils/adt/genfile.c:505 utils/adt/genfile.c:588 utils/adt/jsonfuncs.c:1792 utils/adt/jsonfuncs.c:1904 utils/adt/jsonfuncs.c:2092 utils/adt/jsonfuncs.c:2201 utils/adt/jsonfuncs.c:3663 utils/adt/misc.c:215 utils/adt/pgstatfuncs.c:476 utils/adt/pgstatfuncs.c:584 utils/adt/pgstatfuncs.c:1719 utils/fmgr/funcapi.c:72 utils/misc/guc.c:9666 utils/mmgr/mcxt.c:1333 utils/mmgr/portalmem.c:1136 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "このコンテキストで集合値の関数は集合を受け付けられません" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1315 commands/event_trigger.c:1867 commands/extension.c:1948 commands/extension.c:2056 commands/extension.c:2341 commands/prepare.c:717 foreign/foreign.c:525 libpq/hba.c:2672 replication/logical/launcher.c:1094 replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1485 replication/slotfuncs.c:256 replication/walsender.c:3262 storage/ipc/shmem.c:554 utils/adt/datetime.c:4770 +#: utils/adt/genfile.c:509 utils/adt/genfile.c:592 utils/adt/misc.c:219 utils/adt/pgstatfuncs.c:480 utils/adt/pgstatfuncs.c:588 utils/adt/pgstatfuncs.c:1723 utils/misc/guc.c:9670 utils/misc/pg_config.c:43 utils/mmgr/mcxt.c:1337 utils/mmgr/portalmem.c:1140 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "マテリアライズモードが必要ですが、現在のコンテクストで禁止されています" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "非排他バックアップは進行中ではありません" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "pg_stop_backup('t') を実行しようとしていたのではないですか?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "リストアポイントを作るにはWALレベルが不足しています" + +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "リストアポイントとしては値が長すぎます(最大%d文字)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "リカバリ中は %s を実行できません。" + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:558 access/transam/xlogfuncs.c:582 access/transam/xlogfuncs.c:722 +#, c-format +msgid "recovery is not in progress" +msgstr "リカバリが進行中ではありません" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:559 access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "リカバリ制御関数リカバリ中にのみを実行可能です。" + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:564 +#, c-format +msgid "standby promotion is ongoing" +msgstr "スタンバイの昇格を実行中です" + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:565 +#, c-format +msgid "%s cannot be executed after promotion is triggered." +msgstr "%sは昇格を開始した後には実行できません。" + +#: access/transam/xlogfuncs.c:728 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "\"wait_seconds\"は負の値もしくはゼロにはできません" + +#: access/transam/xlogfuncs.c:748 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "postmasterにシグナルを送信できませんでした: %m" + +#: access/transam/xlogfuncs.c:784 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "サーバは%d 秒以内に昇格しませんでした" + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "%X/%Xのレコードオフセットが不正です" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "%X/%Xでは継続レコードが必要です" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "%X/%Xのレコード長が不正です:長さは%uである必要がありますが、実際は%uでした" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "%2$X/%3$Xのレコード長%1$uが大きすぎます" + +#: access/transam/xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "%X/%Xでcontrecordフラグがありません" + +#: access/transam/xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "%2$X/%3$Xのcontrecordの長さ %1$u は不正です" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "%2$X/%3$XのリソースマネージャID %1$uは不正です" + +#: access/transam/xlogreader.c:717 access/transam/xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "%3$X/%4$Xのレコードの後方リンク%1$X/%2$Xが不正です" + +#: access/transam/xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "%X/%Xのレコード内のリソースマネージャデータのチェックサムが不正です" + +#: access/transam/xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "ログセグメント%2$s、オフセット%3$uのマジックナンバー%1$04Xは不正です" + +#: access/transam/xlogreader.c:822 access/transam/xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ログセグメント %2$s、オフセット%3$uの情報ビット%1$04Xは不正です" + +#: access/transam/xlogreader.c:837 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WALファイルは異なるデータベースシステム由来のものです: WALファイルのデータベースシステム識別子は %lluで、pg_control におけるデータベースシステム識別子は %lluです" + +#: access/transam/xlogreader.c:845 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL ファイルは異なるデータベースシステム由来のものです: ページヘッダーのセグメントサイズが正しくありません" + +#: access/transam/xlogreader.c:851 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL ファイルは異なるデータベースシステム由来のものです: ページヘッダーのXLOG_BLCKSZが正しくありません" + +#: access/transam/xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "ログセグメント%3$s、オフセット%4$uに想定外のページアドレス%1$X/%2$X" + +#: access/transam/xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "ログセグメント%3$s、オフセット%4$uのタイムラインID %1$u(%2$uの後)が順序通りではありません" + +#: access/transam/xlogreader.c:1252 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %uが%X/%Xで不正です" + +#: access/transam/xlogreader.c:1275 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATAが設定されていますが、%X/%Xにデータがありません" + +#: access/transam/xlogreader.c:1282 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATAが設定されていませんが、%2$X/%3$Xのデータ長は%1$uです" + +#: access/transam/xlogreader.c:1318 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEが設定されていますが、%4$X/%5$Xでホールオフセット%1$u、長さ%2$u、ブロックイメージ長%3$uです" + +#: access/transam/xlogreader.c:1334 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEが設定されていませんが、%3$X/%4$Xにおけるホールオフセット%1$uの長さが%2$uです" + +#: access/transam/xlogreader.c:1349 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSEDが設定されていますが、%2$X/%3$Xにおいてブロックイメージ長が%1$uです" + +#: access/transam/xlogreader.c:1364 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEもBKPIMAGE_IS_COMPRESSEDも設定されていませんが、%2$X/%3$Xにおいてブロックイメージ長が%1$uです" + +#: access/transam/xlogreader.c:1380 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_RELが設定されていますが、%X/%Xにおいて以前のリレーションがありません" + +#: access/transam/xlogreader.c:1392 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "%2$X/%3$Xにおけるblock_id %1$uが不正です" + +#: access/transam/xlogreader.c:1481 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "%X/%Xのレコードのサイズが不正です" + +#: access/transam/xlogreader.c:1570 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "%X/%X、ブロック %d での圧縮イメージが不正です" + +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X オプションの値は1MBから1GBの間の2の累乗を指定します" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:845 tcop/postgres.c:3705 +#, c-format +msgid "--%s requires a value" +msgstr "--%sには値が必要です" + +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:850 tcop/postgres.c:3710 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %sは値が必要です" + +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:862 postmaster/postmaster.c:875 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細については\"%s --help\"を実行してください。\n" + +#: bootstrap/bootstrap.c:313 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: コマンドライン引数が不正です\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "グラントオプションはロールにのみ付与できます" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"の列\"%1$s\"に付与された権限はありません" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "\"%s\"に付与された権限はありません" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"の列\"%1$s\"に対して一部の権限が付与されませんでした" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "\"%s\"に対して一部の権限が付与されませんでした" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"の列\"%1$s\"に対して取り消せた権限はありません" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "\"%s\"に対して取り消せた権限はありません" + +#: catalog/aclchk.c:342 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"の列\"%1$s\"に対して一部の権限が取り消せませんでした" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "\"%s\"に対して一部の権限が取り消せませんでした" + +#: catalog/aclchk.c:430 catalog/aclchk.c:973 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "リレーションに対する不正な権限のタイプ %s" + +#: catalog/aclchk.c:434 catalog/aclchk.c:977 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "シーケンスに対する不正な権限のタイプ %s" + +#: catalog/aclchk.c:438 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "データベースに対する不正な権限タイプ %s" + +#: catalog/aclchk.c:442 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "ドメインに対する不正な権限タイプ %s" + +#: catalog/aclchk.c:446 catalog/aclchk.c:981 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "関数に対する不正な権限タイプ %s" + +#: catalog/aclchk.c:450 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "言語に対する不正な権限タイプ %s" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "ラージオブジェクトに対する不正な権限タイプ %s" + +#: catalog/aclchk.c:458 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "スキーマに対する不正な権限タイプ %s" + +#: catalog/aclchk.c:462 catalog/aclchk.c:985 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "プロシージャに対する不正な権限タイプ %s" + +#: catalog/aclchk.c:466 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "ルーチンに対する不正な権限のタイプ %s" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "テーブル空間に対する不正な権限タイプ %s" + +#: catalog/aclchk.c:474 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "型に対する不正な権限タイプ %s" + +#: catalog/aclchk.c:478 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "外部データラッパーに対する不正な権限タイプ %s" + +#: catalog/aclchk.c:482 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "外部サーバに対する不正な権限タイプ %s" + +#: catalog/aclchk.c:521 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "列権限はリレーションに対してのみ有効です" + +#: catalog/aclchk.c:681 catalog/aclchk.c:4067 catalog/aclchk.c:4849 catalog/objectaddress.c:1060 catalog/pg_largeobject.c:116 storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "ラージオブジェクト%uは存在しません" + +#: catalog/aclchk.c:910 catalog/aclchk.c:919 commands/collationcmds.c:118 commands/copy.c:1184 commands/copy.c:1204 commands/copy.c:1213 commands/copy.c:1222 commands/copy.c:1231 commands/copy.c:1240 commands/copy.c:1249 commands/copy.c:1258 commands/copy.c:1276 commands/copy.c:1292 commands/copy.c:1312 commands/copy.c:1329 commands/dbcommands.c:157 commands/dbcommands.c:166 commands/dbcommands.c:175 commands/dbcommands.c:184 commands/dbcommands.c:193 +#: commands/dbcommands.c:202 commands/dbcommands.c:211 commands/dbcommands.c:220 commands/dbcommands.c:229 commands/dbcommands.c:238 commands/dbcommands.c:260 commands/dbcommands.c:1502 commands/dbcommands.c:1511 commands/dbcommands.c:1520 commands/dbcommands.c:1529 commands/extension.c:1735 commands/extension.c:1745 commands/extension.c:1755 commands/extension.c:3055 commands/foreigncmds.c:539 commands/foreigncmds.c:548 commands/functioncmds.c:570 +#: commands/functioncmds.c:736 commands/functioncmds.c:745 commands/functioncmds.c:754 commands/functioncmds.c:763 commands/functioncmds.c:1961 commands/functioncmds.c:1969 commands/publicationcmds.c:90 commands/publicationcmds.c:133 commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:113 commands/subscriptioncmds.c:123 commands/subscriptioncmds.c:133 commands/subscriptioncmds.c:143 commands/subscriptioncmds.c:157 commands/subscriptioncmds.c:168 commands/subscriptioncmds.c:182 commands/subscriptioncmds.c:192 commands/tablecmds.c:6959 commands/typecmds.c:322 commands/typecmds.c:1355 commands/typecmds.c:1364 commands/typecmds.c:1372 commands/typecmds.c:1380 commands/typecmds.c:1388 commands/user.c:133 +#: commands/user.c:147 commands/user.c:156 commands/user.c:165 commands/user.c:174 commands/user.c:183 commands/user.c:192 commands/user.c:201 commands/user.c:210 commands/user.c:219 commands/user.c:228 commands/user.c:237 commands/user.c:246 commands/user.c:582 commands/user.c:590 commands/user.c:598 commands/user.c:606 commands/user.c:614 commands/user.c:622 commands/user.c:630 commands/user.c:638 commands/user.c:647 commands/user.c:655 commands/user.c:663 +#: parser/parse_utilcmd.c:386 replication/pgoutput/pgoutput.c:145 replication/pgoutput/pgoutput.c:166 replication/pgoutput/pgoutput.c:180 replication/walsender.c:886 replication/walsender.c:897 replication/walsender.c:907 +#, c-format +msgid "conflicting or redundant options" +msgstr "競合するオプション、あるいは余計なオプションがあります" + +#: catalog/aclchk.c:1030 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "デフォルト権限は列には設定できません" + +#: catalog/aclchk.c:1190 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "GRANT/REVOKE ON SCHEMAS を使っている時には IN SCHEMA 句は指定できません" + +#: catalog/aclchk.c:1525 catalog/catalog.c:506 catalog/objectaddress.c:1522 commands/analyze.c:378 commands/copy.c:5132 commands/sequence.c:1702 commands/tablecmds.c:6499 commands/tablecmds.c:6657 commands/tablecmds.c:6731 commands/tablecmds.c:6801 commands/tablecmds.c:6884 commands/tablecmds.c:6978 commands/tablecmds.c:7037 commands/tablecmds.c:7110 commands/tablecmds.c:7139 commands/tablecmds.c:7294 commands/tablecmds.c:7376 commands/tablecmds.c:7469 +#: commands/tablecmds.c:7624 commands/tablecmds.c:10829 commands/tablecmds.c:11011 commands/tablecmds.c:11171 commands/tablecmds.c:12254 commands/trigger.c:876 parser/analyze.c:2339 parser/parse_relation.c:713 parser/parse_target.c:1036 parser/parse_type.c:144 parser/parse_utilcmd.c:3202 parser/parse_utilcmd.c:3237 parser/parse_utilcmd.c:3279 utils/adt/acl.c:2870 utils/adt/ruleutils.c:2535 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は存在しません" + +#: catalog/aclchk.c:1788 catalog/objectaddress.c:1362 commands/sequence.c:1140 commands/tablecmds.c:236 commands/tablecmds.c:15563 utils/adt/acl.c:2060 utils/adt/acl.c:2090 utils/adt/acl.c:2122 utils/adt/acl.c:2154 utils/adt/acl.c:2182 utils/adt/acl.c:2212 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "\"%s\"はシーケンスではありません" + +#: catalog/aclchk.c:1826 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "シーケンス \"%s\"では USAGE, SELECT, UPDATE 権限のみをサポートします" + +#: catalog/aclchk.c:1843 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "テーブルに対する権限タイプ%sは不正です" + +#: catalog/aclchk.c:2009 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "列では権限タイプ %s は無効です" + +#: catalog/aclchk.c:2022 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "シーケンス \"%s\"では USAGE, SELECT, UPDATE のみをサポートします" + +#: catalog/aclchk.c:2604 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "言語\"%s\"は信頼されていません" + +#: catalog/aclchk.c:2606 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "信頼されない言語はスーパユーザのみが使用可能なため、GRANTとREVOKEは信頼されない言語上では実行不可です。" + +#: catalog/aclchk.c:3120 +#, c-format +msgid "cannot set privileges of array types" +msgstr "配列型の権限を設定できません" + +#: catalog/aclchk.c:3121 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "代わりに要素型の権限を設定してください。" + +#: catalog/aclchk.c:3128 catalog/objectaddress.c:1656 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "\"%s\"はドメインではありません" + +#: catalog/aclchk.c:3248 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "認識できない権限タイプ\"%s\"" + +#: catalog/aclchk.c:3309 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "集約 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3312 +#, c-format +msgid "permission denied for collation %s" +msgstr "照合順序 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3315 +#, c-format +msgid "permission denied for column %s" +msgstr "列 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3318 +#, c-format +msgid "permission denied for conversion %s" +msgstr "変換 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3321 +#, c-format +msgid "permission denied for database %s" +msgstr "データベース %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3324 +#, c-format +msgid "permission denied for domain %s" +msgstr "ドメイン %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3327 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "イベントトリガ %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3330 +#, c-format +msgid "permission denied for extension %s" +msgstr "機能拡張 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3333 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "外部データラッパ %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3336 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "外部サーバ %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3339 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "外部テーブル %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3342 +#, c-format +msgid "permission denied for function %s" +msgstr "関数 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3345 +#, c-format +msgid "permission denied for index %s" +msgstr "インデックス %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3348 +#, c-format +msgid "permission denied for language %s" +msgstr "言語 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3351 +#, c-format +msgid "permission denied for large object %s" +msgstr "ラージオブジェクト %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3354 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "実体化ビュー %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3357 +#, c-format +msgid "permission denied for operator class %s" +msgstr "演算子クラス %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3360 +#, c-format +msgid "permission denied for operator %s" +msgstr "演算子 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3363 +#, c-format +msgid "permission denied for operator family %s" +msgstr "演算子族 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3366 +#, c-format +msgid "permission denied for policy %s" +msgstr "ポリシ %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3369 +#, c-format +msgid "permission denied for procedure %s" +msgstr "プロシージャ %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3372 +#, c-format +msgid "permission denied for publication %s" +msgstr "パブリケーション%sへのアクセスが拒否されました" + +#: catalog/aclchk.c:3375 +#, c-format +msgid "permission denied for routine %s" +msgstr "ルーチン %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3378 +#, c-format +msgid "permission denied for schema %s" +msgstr "スキーマ %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3381 commands/sequence.c:610 commands/sequence.c:844 commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 commands/sequence.c:1864 +#, c-format +msgid "permission denied for sequence %s" +msgstr "シーケンス %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3384 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "統計情報オブジェクト %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3387 +#, c-format +msgid "permission denied for subscription %s" +msgstr "サブスクリプション %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3390 +#, c-format +msgid "permission denied for table %s" +msgstr "テーブル %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3393 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "テーブル空間 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3396 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "テキスト検索設定 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3399 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "テキスト検索辞書 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3402 +#, c-format +msgid "permission denied for type %s" +msgstr "型 %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3405 +#, c-format +msgid "permission denied for view %s" +msgstr "ビュー %s へのアクセスが拒否されました" + +#: catalog/aclchk.c:3440 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "集約 %s の所有者である必要があります" + +#: catalog/aclchk.c:3443 +#, c-format +msgid "must be owner of collation %s" +msgstr "照合順序 %s の所有者である必要があります" + +#: catalog/aclchk.c:3446 +#, c-format +msgid "must be owner of conversion %s" +msgstr "変換 %s の所有者である必要があります" + +#: catalog/aclchk.c:3449 +#, c-format +msgid "must be owner of database %s" +msgstr "データベース %s の所有者である必要があります" + +#: catalog/aclchk.c:3452 +#, c-format +msgid "must be owner of domain %s" +msgstr "ドメイン %s の所有者である必要があります" + +#: catalog/aclchk.c:3455 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "イベントトリガ %s の所有者である必要があります" + +#: catalog/aclchk.c:3458 +#, c-format +msgid "must be owner of extension %s" +msgstr "機能拡張 %s の所有者である必要があります" + +#: catalog/aclchk.c:3461 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "外部データラッパー %s の所有者である必要があります" + +#: catalog/aclchk.c:3464 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "外部サーバ %s の所有者である必要があります" + +#: catalog/aclchk.c:3467 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "外部テーブル %s の所有者である必要があります" + +#: catalog/aclchk.c:3470 +#, c-format +msgid "must be owner of function %s" +msgstr "関数 %s の所有者である必要があります" + +#: catalog/aclchk.c:3473 +#, c-format +msgid "must be owner of index %s" +msgstr "インデックス %s の所有者である必要があります" + +#: catalog/aclchk.c:3476 +#, c-format +msgid "must be owner of language %s" +msgstr "言語 %s の所有者である必要があります" + +#: catalog/aclchk.c:3479 +#, c-format +msgid "must be owner of large object %s" +msgstr "ラージオブジェクト %s の所有者である必要があります" + +#: catalog/aclchk.c:3482 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "実体化ビュー %s の所有者である必要があります" + +#: catalog/aclchk.c:3485 +#, c-format +msgid "must be owner of operator class %s" +msgstr "演算子クラス %s の所有者である必要があります" + +#: catalog/aclchk.c:3488 +#, c-format +msgid "must be owner of operator %s" +msgstr "演算子 %s の所有者である必要があります" + +#: catalog/aclchk.c:3491 +#, c-format +msgid "must be owner of operator family %s" +msgstr "演算子族 %s の所有者である必要があります" + +#: catalog/aclchk.c:3494 +#, c-format +msgid "must be owner of procedure %s" +msgstr "プロシージャ %s の所有者である必要があります" + +#: catalog/aclchk.c:3497 +#, c-format +msgid "must be owner of publication %s" +msgstr "パブリケーション %s の所有者である必要があります" + +#: catalog/aclchk.c:3500 +#, c-format +msgid "must be owner of routine %s" +msgstr "ルーチン %s の所有者である必要があります" + +#: catalog/aclchk.c:3503 +#, c-format +msgid "must be owner of sequence %s" +msgstr "シーケンス %s の所有者である必要があります" + +#: catalog/aclchk.c:3506 +#, c-format +msgid "must be owner of subscription %s" +msgstr "サブスクリプション %s の所有者である必要があります" + +#: catalog/aclchk.c:3509 +#, c-format +msgid "must be owner of table %s" +msgstr "テーブル %s の所有者である必要があります" + +#: catalog/aclchk.c:3512 +#, c-format +msgid "must be owner of type %s" +msgstr "型 %s の所有者である必要があります" + +#: catalog/aclchk.c:3515 +#, c-format +msgid "must be owner of view %s" +msgstr "ビュー %s の所有者である必要があります" + +#: catalog/aclchk.c:3518 +#, c-format +msgid "must be owner of schema %s" +msgstr "スキーマ %s の所有者である必要があります" + +#: catalog/aclchk.c:3521 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "統計情報オブジェクト %s の所有者である必要があります" + +#: catalog/aclchk.c:3524 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "テーブル空間 %s の所有者である必要があります" + +#: catalog/aclchk.c:3527 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "テキスト検索設定 %s の所有者である必要があります" + +#: catalog/aclchk.c:3530 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "テキスト検索辞書 %s の所有者である必要があります" + +#: catalog/aclchk.c:3544 +#, c-format +msgid "must be owner of relation %s" +msgstr "リレーション %s の所有者である必要があります" + +#: catalog/aclchk.c:3588 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"の列\"%1$s\"へのアクセスが拒否されました" + +#: catalog/aclchk.c:3709 catalog/aclchk.c:3717 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "OID %2$uのリレーションに属性%1$dは存在しません" + +#: catalog/aclchk.c:3790 catalog/aclchk.c:4700 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "OID %uのリレーションは存在しません" + +#: catalog/aclchk.c:3880 catalog/aclchk.c:5118 +#, c-format +msgid "database with OID %u does not exist" +msgstr "OID %uのデータベースは存在しません" + +#: catalog/aclchk.c:3934 catalog/aclchk.c:4778 tcop/fastpath.c:221 utils/fmgr/fmgr.c:2055 +#, c-format +msgid "function with OID %u does not exist" +msgstr "OID %uの関数は存在しません" + +#: catalog/aclchk.c:3988 catalog/aclchk.c:4804 +#, c-format +msgid "language with OID %u does not exist" +msgstr "OID %uの言語は存在しません" + +#: catalog/aclchk.c:4152 catalog/aclchk.c:4876 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "OID %uのスキーマは存在しません" + +#: catalog/aclchk.c:4206 catalog/aclchk.c:4903 utils/adt/genfile.c:686 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "OID %uのテーブル空間は存在しません" + +#: catalog/aclchk.c:4265 catalog/aclchk.c:5037 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "OID %uの外部データラッパーは存在しません" + +#: catalog/aclchk.c:4327 catalog/aclchk.c:5064 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "OID %uの外部サーバは存在しません" + +#: catalog/aclchk.c:4387 catalog/aclchk.c:4726 utils/cache/typcache.c:378 utils/cache/typcache.c:432 +#, c-format +msgid "type with OID %u does not exist" +msgstr "OID %uの型は存在しません" + +#: catalog/aclchk.c:4752 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "OID %uの演算子は存在しません" + +#: catalog/aclchk.c:4929 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "OID %uの演算子クラスは存在しません" + +#: catalog/aclchk.c:4956 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "OID %uの演算子族は存在しません" + +#: catalog/aclchk.c:4983 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "OID %uのテキスト検索辞書は存在しません" + +#: catalog/aclchk.c:5010 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "OID %uのテキスト検索設定は存在しません" + +#: catalog/aclchk.c:5091 commands/event_trigger.c:453 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "OID %uのイベントトリガは存在しません" + +#: catalog/aclchk.c:5144 commands/collationcmds.c:367 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "OID %uの照合順序は存在しません" + +#: catalog/aclchk.c:5170 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "OID %uの変換は存在しません" + +#: catalog/aclchk.c:5211 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "OID %uの機能拡張は存在しません" + +#: catalog/aclchk.c:5238 commands/publicationcmds.c:771 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "OID %uのパブリケーションは存在しません" + +#: catalog/aclchk.c:5264 commands/subscriptioncmds.c:1172 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "OID %uのサブスクリプションは存在しません" + +#: catalog/aclchk.c:5290 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "OID %uの統計情報オブジェクトは存在しません" + +#: catalog/catalog.c:485 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "pg_nextoid() を呼び出すにはスーパユーザである必要があります" + +#: catalog/catalog.c:493 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() はシステムカタログでのみ使用できます" + +#: catalog/catalog.c:498 parser/parse_utilcmd.c:2103 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "インデックス\"%s\"はテーブル\"%s\"には属していません" + +#: catalog/catalog.c:515 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "列\"%s\"はoid型ではありません" + +#: catalog/catalog.c:522 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "インデックス\"%s\"は列\"%s\"に対するインデックスではありません" + +#: catalog/dependency.c:821 catalog/dependency.c:1060 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "%2$sが必要としているため%1$sを削除できません" + +#: catalog/dependency.c:823 catalog/dependency.c:1062 +#, c-format +msgid "You can drop %s instead." +msgstr "代わりに%sを削除できます" + +#: catalog/dependency.c:931 catalog/pg_shdepend.c:640 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "データベースシステムが必要としているため%sを削除できません" + +#: catalog/dependency.c:1128 +#, c-format +msgid "drop auto-cascades to %s" +msgstr "削除は自動で%sへ伝播します" + +#: catalog/dependency.c:1141 catalog/dependency.c:1150 +#, c-format +msgid "%s depends on %s" +msgstr "%sは%sに依存しています" + +#: catalog/dependency.c:1162 catalog/dependency.c:1171 +#, c-format +msgid "drop cascades to %s" +msgstr "削除は%sへ伝播します" + +#: catalog/dependency.c:1179 catalog/pg_shdepend.c:769 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"および%d個のその他のオブジェクト(一覧についてはサーバログを参照してください)" +msgstr[1] "" +"\n" +"および%d個のその他のオブジェクト(一覧についてはサーバログを参照してください)" + +#: catalog/dependency.c:1191 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "他のオブジェクトが依存しているため%sを削除できません" + +#: catalog/dependency.c:1193 catalog/dependency.c:1194 catalog/dependency.c:1200 catalog/dependency.c:1201 catalog/dependency.c:1212 catalog/dependency.c:1213 commands/tablecmds.c:1247 commands/tablecmds.c:12872 commands/user.c:1093 commands/view.c:495 libpq/auth.c:334 replication/syncrep.c:1032 storage/lmgr/deadlock.c:1152 storage/lmgr/proc.c:1346 utils/adt/acl.c:5329 utils/adt/jsonfuncs.c:614 utils/adt/jsonfuncs.c:620 utils/misc/guc.c:6789 utils/misc/guc.c:6825 +#: utils/misc/guc.c:6895 utils/misc/guc.c:10965 utils/misc/guc.c:10999 utils/misc/guc.c:11033 utils/misc/guc.c:11067 utils/misc/guc.c:11102 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1195 catalog/dependency.c:1202 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "依存しているオブジェクトも削除するにはDROP ... CASCADEを使用してください" + +#: catalog/dependency.c:1199 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "他のオブジェクトが依存しているため指定したオブジェクトを削除できません" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1208 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "削除は他の%d個のオブジェクトに対しても行われます" +msgstr[1] "削除は他の%d個のオブジェクトに対しても行われます" + +#: catalog/dependency.c:1869 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "%s型の定数をここで使用することはできません" + +#: catalog/heap.c:330 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "\"%s.%s\"を作成する権限がありません" + +#: catalog/heap.c:332 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "システムカタログの更新は現在禁止されています" + +#: catalog/heap.c:500 commands/tablecmds.c:2132 commands/tablecmds.c:2690 commands/tablecmds.c:6094 +#, c-format +msgid "tables can have at most %d columns" +msgstr "テーブルは最大で%d列までしか持てません" + +#: catalog/heap.c:518 commands/tablecmds.c:6389 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "列名\"%s\"はシステム用の列名に使われています" + +#: catalog/heap.c:534 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "列名\"%s\"が複数指定されました" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:609 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "パーティションキー列%sは疑似型%sです" + +#: catalog/heap.c:614 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "列\"%s\"は疑似型%sです" + +#: catalog/heap.c:645 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "複合型 %s がそれ自身のメンバーになることはできません" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:700 +#, c-format +msgid "no collation was derived for partition key column %s with collatable type %s" +msgstr "照合可能な型 %2$s のパーティションキー列%1$sのための照合順序を決定できませんでした" + +#: catalog/heap.c:706 commands/createas.c:203 commands/createas.c:486 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "照合可能な型 %2$s を持つ列\"%1$s\"のための照合順序を決定できませんでした" + +#: catalog/heap.c:1191 catalog/index.c:855 commands/tablecmds.c:3465 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "リレーション\"%s\"はすでに存在します" + +#: catalog/heap.c:1207 catalog/pg_type.c:428 catalog/pg_type.c:750 commands/typecmds.c:238 commands/typecmds.c:250 commands/typecmds.c:719 commands/typecmds.c:1125 commands/typecmds.c:1337 commands/typecmds.c:2124 +#, c-format +msgid "type \"%s\" already exists" +msgstr "型\"%s\"はすでに存在します" + +#: catalog/heap.c:1208 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "リレーションは同じ名前の関連する型を持ちます。このため既存の型と競合しない名前である必要があります。" + +#: catalog/heap.c:1237 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "バイナリアップグレードモード中にpg_classのヒープOIDが設定されていません" + +#: catalog/heap.c:2438 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "パーティション親テーブル\"%s\"に NO INHERIT 制約は追加できません" + +#: catalog/heap.c:2708 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "検査制約\"%s\"はすでに存在します" + +#: catalog/heap.c:2878 catalog/index.c:869 catalog/pg_constraint.c:654 commands/tablecmds.c:7974 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "すでに制約\"%s\"はリレーション\"%s\"に存在します" + +#: catalog/heap.c:2885 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "制約\"%s\"は、リレーション\"%s\"上の継承されていない制約と競合します" + +#: catalog/heap.c:2896 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "制約\"%s\"は、リレーション\"%s\"上の継承された制約と競合します" + +#: catalog/heap.c:2906 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "制約\"%s\"は、リレーション\"%s\"上の NOT VALID 制約と競合します" + +#: catalog/heap.c:2911 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "継承された定義により制約\"%s\"をマージしています" + +#: catalog/heap.c:3013 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "生成カラム\"%s\"はカラム生成式中では使用できません" + +#: catalog/heap.c:3015 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "生成カラムは他の生成カラムを参照できません。" + +#: catalog/heap.c:3067 +#, c-format +msgid "generation expression is not immutable" +msgstr "生成式は不変ではありません" + +#: catalog/heap.c:3095 rewrite/rewriteHandler.c:1192 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "列\"%s\"の型は%sですが、デフォルト式の型は%sです" + +#: catalog/heap.c:3100 commands/prepare.c:367 parser/parse_node.c:412 parser/parse_target.c:589 parser/parse_target.c:869 parser/parse_target.c:879 rewrite/rewriteHandler.c:1197 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "式を書き換えるかキャストする必要があります。" + +#: catalog/heap.c:3147 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "検査制約ではテーブル\"%s\"のみを参照することができます" + +#: catalog/heap.c:3404 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "ON COMMITと外部キーの組み合わせはサポートされていません" + +#: catalog/heap.c:3405 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "テーブル\"%s\"は\"%s\"を参照します。しかし、これらのON COMMIT設定は同一ではありません。" + +#: catalog/heap.c:3410 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "外部キー制約で参照されているテーブルを削除できません" + +#: catalog/heap.c:3411 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "テーブル\"%s\"は\"%s\"を参照します。" + +#: catalog/heap.c:3413 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "同時にテーブル\"%s\"がtruncateされました。TRUNCATE ... CASCADEを使用してください。" + +#: catalog/index.c:218 parser/parse_utilcmd.c:1910 parser/parse_utilcmd.c:2009 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "テーブル\"%s\"に複数のプライマリキーを持たせることはできません" + +#: catalog/index.c:236 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "プライマリキーを式にすることはできません" + +#: catalog/index.c:253 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "主キー列\"%s\"がNOT NULL指定されていません" + +#: catalog/index.c:754 catalog/index.c:1815 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "ユーザによるシステムカタログテーブルに対するインデックスの定義はサポートされていません" + +#: catalog/index.c:794 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "非決定的照合順序は演算子クラス \"%s\" ではサポートされません" + +#: catalog/index.c:809 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "システムカタログテーブルの並行的インデックス作成はサポートされていません" + +#: catalog/index.c:818 catalog/index.c:1253 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "排他制約のためのインデックスの並列的作成はサポートされていません" + +#: catalog/index.c:827 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "initdbの後に共有インデックスを作成できません" + +#: catalog/index.c:847 commands/createas.c:252 commands/sequence.c:154 parser/parse_utilcmd.c:208 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "リレーション\"%s\"はすでに存在します、スキップします" + +#: catalog/index.c:897 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "バイナリアップグレードモード中にpg_classのインデックスOIDが設定されていません" + +#: catalog/index.c:2100 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLYはトランザクション内で最初の操作でなければなりません" + +#: catalog/index.c:2831 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "テーブル\"%2$s\"のインデックス\"%1$s\"を非並列で構築しています" + +#: catalog/index.c:2836 +#, c-format +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "テーブル\"%2$s\"のインデックス\"%1$s\"を%3$d個のパラレルワーカを要求して構築しています" +msgstr[1] "テーブル\"%2$s\"のインデックス\"%1$s\"を%3$d個のパラレルワーカを要求して構築しています" + +#: catalog/index.c:3464 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "他のセッションの一時テーブルはインデクス再構築できません" + +#: catalog/index.c:3475 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "TOASTテーブルの無効なインデックスの再作成はできません" + +#: catalog/index.c:3597 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "インデックス\"%s\"のインデックス再構築が完了しました" + +#: catalog/index.c:3673 commands/indexcmds.c:3017 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "パーティションテーブルの REINDEX は実装されていません、\"%s\"はスキップします" + +#: catalog/index.c:3728 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "TOASTテーブルの無効なインデックス \"%s.%s\"の再作成はできません、スキップします " + +#: catalog/namespace.c:257 catalog/namespace.c:461 catalog/namespace.c:553 commands/trigger.c:5043 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "データベース間の参照は実装されていません: \"%s.%s.%s\"" + +#: catalog/namespace.c:314 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "一時テーブルにはスキーマ名を指定できません" + +#: catalog/namespace.c:395 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "リレーション\"%s.%s\"のロックを取得できませんでした" + +#: catalog/namespace.c:400 commands/lockcmds.c:142 commands/lockcmds.c:227 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "リレーション\"%s\"のロックを取得できませんでした" + +#: catalog/namespace.c:428 parser/parse_relation.c:1357 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "リレーション\"%s.%s\"は存在しません" + +#: catalog/namespace.c:433 parser/parse_relation.c:1370 parser/parse_relation.c:1378 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "リレーション\"%s\"は存在しません" + +#: catalog/namespace.c:499 catalog/namespace.c:3030 commands/extension.c:1519 commands/extension.c:1525 +#, c-format +msgid "no schema has been selected to create in" +msgstr "作成先のスキーマが選択されていません" + +#: catalog/namespace.c:651 catalog/namespace.c:664 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "他のセッションの一時スキーマの中にリレーションを作成できません" + +#: catalog/namespace.c:655 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "非一時スキーマの中に一時リレーションを作成できません" + +#: catalog/namespace.c:670 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "一時スキーマの中には一時リレーションしか作成できません" + +#: catalog/namespace.c:2222 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "統計情報オブジェクト\"%s\"は存在しません" + +#: catalog/namespace.c:2345 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "テキスト検索パーサ\"%s\"は存在しません" + +#: catalog/namespace.c:2471 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "テキスト検索辞書\"%s\"は存在しません" + +#: catalog/namespace.c:2598 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "テキスト検索テンプレート\"%s\"は存在しません" + +#: catalog/namespace.c:2724 commands/tsearchcmds.c:1123 utils/cache/ts_cache.c:617 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "テキスト検索設定\"%s\"は存在しません" + +#: catalog/namespace.c:2837 parser/parse_expr.c:872 parser/parse_target.c:1228 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "データベース間の参照は実装されていません: %s" + +#: catalog/namespace.c:2843 gram.y:14743 gram.y:16189 parser/parse_expr.c:879 parser/parse_target.c:1235 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "修飾名が不適切です(ドット区切りの名前が多すぎます): %s" + +#: catalog/namespace.c:2973 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "一時スキーマへ、または一時スキーマからオブジェクトを移動できません" + +#: catalog/namespace.c:2979 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "TOASTスキーマへ、またはTOASTスキーマからオブジェクトを移動できません" + +#: catalog/namespace.c:3052 commands/schemacmds.c:233 commands/schemacmds.c:313 commands/tablecmds.c:1192 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "スキーマ\"%s\"は存在しません" + +#: catalog/namespace.c:3083 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "リレーション名が不適切です(ドット区切りの名前が多すぎます): %s" + +#: catalog/namespace.c:3646 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "エンコーディング\"%2$s\"の照合順序\"%1$s\"は存在しません" + +#: catalog/namespace.c:3701 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "変換\"%sは存在しません" + +#: catalog/namespace.c:3965 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "データベース\"%s\"に一時テーブルを作成する権限がありません" + +#: catalog/namespace.c:3981 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "リカバリ中は一時テーブルを作成できません" + +#: catalog/namespace.c:3987 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "並行処理中は一時テーブルを作成できません" + +#: catalog/namespace.c:4286 commands/tablespace.c:1205 commands/variable.c:64 utils/misc/guc.c:11134 utils/misc/guc.c:11212 +#, c-format +msgid "List syntax is invalid." +msgstr "リスト文法が無効です" + +#: catalog/objectaddress.c:1370 catalog/pg_publication.c:57 commands/policy.c:95 commands/policy.c:395 commands/policy.c:485 commands/tablecmds.c:230 commands/tablecmds.c:272 commands/tablecmds.c:1976 commands/tablecmds.c:5539 commands/tablecmds.c:10946 +#, c-format +msgid "\"%s\" is not a table" +msgstr "\"%s\"はテーブルではありません" + +#: catalog/objectaddress.c:1377 commands/tablecmds.c:242 commands/tablecmds.c:5569 commands/tablecmds.c:15568 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "\"%s\"はビューではありません" + +#: catalog/objectaddress.c:1384 commands/matview.c:175 commands/tablecmds.c:248 commands/tablecmds.c:15573 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "\"%s\"は実体化ビューではありません" + +#: catalog/objectaddress.c:1391 commands/tablecmds.c:266 commands/tablecmds.c:5572 commands/tablecmds.c:15578 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "\"%s\"は外部テーブルではありません" + +#: catalog/objectaddress.c:1432 +#, c-format +msgid "must specify relation and object name" +msgstr "リレーションとオブジェクトの名前の指定が必要です" + +#: catalog/objectaddress.c:1508 catalog/objectaddress.c:1561 +#, c-format +msgid "column name must be qualified" +msgstr "列名を修飾する必要があります" + +#: catalog/objectaddress.c:1608 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "リレーション\"%2$s\"の列\"%1$s\"に対するデフォルト値が存在しません" + +#: catalog/objectaddress.c:1645 commands/functioncmds.c:133 commands/tablecmds.c:258 commands/typecmds.c:263 commands/typecmds.c:3275 parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:845 utils/adt/acl.c:4436 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "型\"%s\"は存在しません" + +#: catalog/objectaddress.c:1764 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "%4$sの演算子 %1$d (%2$s, %3$s) がありません" + +#: catalog/objectaddress.c:1795 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "%4$s の関数 %1$d (%2$s, %3$s) がありません" + +#: catalog/objectaddress.c:1846 catalog/objectaddress.c:1872 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "ユーザ\"%s\"に対するユーザマッピングがサーバ\"%s\"には存在しません" + +#: catalog/objectaddress.c:1861 commands/foreigncmds.c:430 commands/foreigncmds.c:988 commands/foreigncmds.c:1347 foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "サーバ\"%s\"は存在しません" + +#: catalog/objectaddress.c:1928 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "パブリケーション\"%2$s\"の発行リレーション\"%1$s\"は存在しません" + +#: catalog/objectaddress.c:1990 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "デフォルトのACLオブジェクトタイプ\"%c\"は認識できません" + +#: catalog/objectaddress.c:1991 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "有効な値は \"%c\", \"%c\", \"%c\", \"%c\", \"%c\" です。" + +#: catalog/objectaddress.c:2042 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "ユーザ\"%s\"に対する、名前空間\"%s\"の%sへのデフォルトのACLはありません" + +#: catalog/objectaddress.c:2047 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "ユーザ\"%s\"に対する%sへのデフォルトACLは存在しません" + +#: catalog/objectaddress.c:2074 catalog/objectaddress.c:2132 catalog/objectaddress.c:2189 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "名前または引数のリストはnullを含むことができません" + +#: catalog/objectaddress.c:2108 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "サポートされないオブジェクトタイプ\"%s\"" + +#: catalog/objectaddress.c:2128 catalog/objectaddress.c:2146 catalog/objectaddress.c:2287 +#, c-format +msgid "name list length must be exactly %d" +msgstr "名前リストの長さは正確に%dでなくてはなりません" + +#: catalog/objectaddress.c:2150 +#, c-format +msgid "large object OID may not be null" +msgstr "ラージオブジェクトのOIDはnullにはなり得ません" + +#: catalog/objectaddress.c:2159 catalog/objectaddress.c:2222 catalog/objectaddress.c:2229 +#, c-format +msgid "name list length must be at least %d" +msgstr "名前リストの長さは%d以上でなくてはなりません" + +#: catalog/objectaddress.c:2215 catalog/objectaddress.c:2236 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "引数リストの長さはちょうど%dである必要があります" + +#: catalog/objectaddress.c:2488 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "ラージオブジェクト %u の所有者である必要があります" + +#: catalog/objectaddress.c:2503 commands/functioncmds.c:1445 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "型%sまたは型%sの所有者である必要があります" + +#: catalog/objectaddress.c:2553 catalog/objectaddress.c:2570 +#, c-format +msgid "must be superuser" +msgstr "スーパユーザである必要があります" + +#: catalog/objectaddress.c:2560 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "CREATEROLE 権限が必要です" + +#: catalog/objectaddress.c:2639 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "認識されないオブジェクトタイプ\"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2881 +#, c-format +msgid "column %s of %s" +msgstr "%2$s の列 %1$s" + +#: catalog/objectaddress.c:2895 +#, c-format +msgid "function %s" +msgstr "関数%s" + +#: catalog/objectaddress.c:2907 +#, c-format +msgid "type %s" +msgstr "型%s" + +#: catalog/objectaddress.c:2944 +#, c-format +msgid "cast from %s to %s" +msgstr "%sから%sへの型変換" + +#: catalog/objectaddress.c:2977 +#, c-format +msgid "collation %s" +msgstr "照合順序%s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3008 +#, c-format +msgid "constraint %s on %s" +msgstr "%2$sに対する制約%1$s" + +#: catalog/objectaddress.c:3014 +#, c-format +msgid "constraint %s" +msgstr "制約%s" + +#: catalog/objectaddress.c:3046 +#, c-format +msgid "conversion %s" +msgstr "変換%s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:3092 +#, c-format +msgid "default value for %s" +msgstr "%s のデフォルト値" + +#: catalog/objectaddress.c:3106 +#, c-format +msgid "language %s" +msgstr "言語%s" + +#: catalog/objectaddress.c:3114 +#, c-format +msgid "large object %u" +msgstr "ラージオブジェクト%u" + +#: catalog/objectaddress.c:3127 +#, c-format +msgid "operator %s" +msgstr "演算子%s" + +#: catalog/objectaddress.c:3164 +#, c-format +msgid "operator class %s for access method %s" +msgstr "アクセスメソッド%2$s用の演算子クラス%1$s" + +#: catalog/objectaddress.c:3192 +#, c-format +msgid "access method %s" +msgstr "アクセスメソッド%s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3241 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "%4$sの演算子%1$d (%2$s, %3$s): %5$s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3298 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "%4$s の関数 %1$d (%2$s, %3$s): %5$s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3350 +#, c-format +msgid "rule %s on %s" +msgstr "%2$s のルール %1$s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3396 +#, c-format +msgid "trigger %s on %s" +msgstr "%2$s のトリガ %1$s" + +#: catalog/objectaddress.c:3416 +#, c-format +msgid "schema %s" +msgstr "スキーマ%s" + +#: catalog/objectaddress.c:3444 +#, c-format +msgid "statistics object %s" +msgstr "統計オブジェクト%s" + +#: catalog/objectaddress.c:3475 +#, c-format +msgid "text search parser %s" +msgstr "テキスト検索パーサ%s" + +#: catalog/objectaddress.c:3506 +#, c-format +msgid "text search dictionary %s" +msgstr "テキスト検索辞書%s" + +#: catalog/objectaddress.c:3537 +#, c-format +msgid "text search template %s" +msgstr "テキスト検索テンプレート%s" + +#: catalog/objectaddress.c:3568 +#, c-format +msgid "text search configuration %s" +msgstr "テキスト検索設定%s" + +#: catalog/objectaddress.c:3581 +#, c-format +msgid "role %s" +msgstr "ロール%s" + +#: catalog/objectaddress.c:3597 +#, c-format +msgid "database %s" +msgstr "データベース%s" + +#: catalog/objectaddress.c:3613 +#, c-format +msgid "tablespace %s" +msgstr "テーブル空間%s" + +#: catalog/objectaddress.c:3624 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "外部データラッパー%s" + +#: catalog/objectaddress.c:3634 +#, c-format +msgid "server %s" +msgstr "サーバ%s" + +#: catalog/objectaddress.c:3667 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "サーバ%2$s上のユーザマッピング%1$s" + +#: catalog/objectaddress.c:3719 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "スキーマ %2$s のロール %1$s のものである新しいリレーションのデフォルト権限" + +#: catalog/objectaddress.c:3723 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "新しいリレーションに関するデフォルトの権限は、ロール%sに属します。" + +#: catalog/objectaddress.c:3729 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "スキーマ %2$s のロール %1$s のものである新しいシーケンスのデフォルト権限" + +#: catalog/objectaddress.c:3733 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "新しいシーケンスに関するデフォルトの権限は、ロール%sに属します。" + +#: catalog/objectaddress.c:3739 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "スキーマ %2$s のロール %1$s のものである新しい関数のデフォルト権限" + +#: catalog/objectaddress.c:3743 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "新しい関数に関するデフォルトの権限は、ロール%sに属します。" + +#: catalog/objectaddress.c:3749 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "スキーマ %2$s のロール %1$s のものである新しい型のデフォルト権限" + +#: catalog/objectaddress.c:3753 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "新しい型に関するデフォルトの権限は、ロール%sに属します" + +#: catalog/objectaddress.c:3759 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "ロール%sに属する新しいスキーマ上のデフォルト権限" + +#: catalog/objectaddress.c:3766 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "スキーマ %2$s のロール %1$s に属するデフォルト権限" + +#: catalog/objectaddress.c:3770 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "デフォルトの権限はロール%sに属します。" + +#: catalog/objectaddress.c:3792 +#, c-format +msgid "extension %s" +msgstr "機能拡張%s" + +#: catalog/objectaddress.c:3809 +#, c-format +msgid "event trigger %s" +msgstr "イベントトリガ%s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3853 +#, c-format +msgid "policy %s on %s" +msgstr "%2$s のポリシ %1$s" + +#: catalog/objectaddress.c:3866 +#, c-format +msgid "publication %s" +msgstr "パブリケーション%s" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3894 +#, c-format +msgid "publication of %s in publication %s" +msgstr "パブリケーション %2$s での %1$s の発行" + +#: catalog/objectaddress.c:3906 +#, c-format +msgid "subscription %s" +msgstr "サブスクリプション%s" + +#: catalog/objectaddress.c:3927 +#, c-format +msgid "transform for %s language %s" +msgstr "言語%2$sの%1$s型に対する変換" + +#: catalog/objectaddress.c:3998 +#, c-format +msgid "table %s" +msgstr "テーブル%s" + +#: catalog/objectaddress.c:4003 +#, c-format +msgid "index %s" +msgstr "インデックス%s" + +#: catalog/objectaddress.c:4007 +#, c-format +msgid "sequence %s" +msgstr "シーケンス%s" + +#: catalog/objectaddress.c:4011 +#, c-format +msgid "toast table %s" +msgstr "TOASTテーブル%s" + +#: catalog/objectaddress.c:4015 +#, c-format +msgid "view %s" +msgstr "ビュー%s" + +#: catalog/objectaddress.c:4019 +#, c-format +msgid "materialized view %s" +msgstr "実体化ビュー%s" + +#: catalog/objectaddress.c:4023 +#, c-format +msgid "composite type %s" +msgstr "複合型%s" + +#: catalog/objectaddress.c:4027 +#, c-format +msgid "foreign table %s" +msgstr "外部テーブル%s" + +#: catalog/objectaddress.c:4032 +#, c-format +msgid "relation %s" +msgstr "リレーション%s" + +#: catalog/objectaddress.c:4073 +#, c-format +msgid "operator family %s for access method %s" +msgstr "アクセスメソッド%2$sの演算子族%1$s" + +#: catalog/pg_aggregate.c:128 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "集約は%d個以上の引数を取ることはできません" +msgstr[1] "集約は%d個以上の引数を取ることはできません" + +#: catalog/pg_aggregate.c:143 catalog/pg_aggregate.c:157 +#, c-format +msgid "cannot determine transition data type" +msgstr "遷移データ型を決定できません" + +#: catalog/pg_aggregate.c:172 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "可変長引数の順序集合集約はVARIADIC型のANYを使う必要があります" + +#: catalog/pg_aggregate.c:198 +#, c-format +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" +msgstr "仮説集合集約は集約された引数に適合する直接引数を持つ必要があります" + +#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "遷移関数の戻り値型%sは%sではありません" + +#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#, c-format +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" +msgstr "遷移関数がSTRICTかつ遷移用の型が入力型とバイナリ互換がない場合初期値を省略してはなりません" + +#: catalog/pg_aggregate.c:334 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "逆遷移関数%sの戻り値の型が%sではありません" + +#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2852 +#, c-format +msgid "strictness of aggregate's forward and inverse transition functions must match" +msgstr "集約の前進と反転の遷移関数のSTRICT属性は一致している必要があります" + +#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:553 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "追加の引数を持つ最終関数はSTRICT宣言できません" + +#: catalog/pg_aggregate.c:426 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "結合関数%sの戻り値の型が%sではありません" + +#: catalog/pg_aggregate.c:438 executor/nodeAgg.c:4173 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "遷移タイプ%sの結合関数はSTRICT宣言できません" + +#: catalog/pg_aggregate.c:457 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "直列化関数%sの戻り値の型が%sではありません" + +#: catalog/pg_aggregate.c:478 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "復元関数%sの戻り値の型が%sではありません" + +#: catalog/pg_aggregate.c:497 catalog/pg_proc.c:186 catalog/pg_proc.c:220 +#, c-format +msgid "cannot determine result data type" +msgstr "結果のデータ型を決定できません" + +#: catalog/pg_aggregate.c:512 catalog/pg_proc.c:199 catalog/pg_proc.c:228 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "\"internal\"疑似型の安全ではない使用" + +#: catalog/pg_aggregate.c:566 +#, c-format +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" +msgstr "移動集約の実装が%s型を返却しました、しかし普通の実装の方は%s型を返却しています" + +#: catalog/pg_aggregate.c:577 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "ソート演算子は単一引数の集約でのみ指定可能です" + +#: catalog/pg_aggregate.c:704 catalog/pg_proc.c:374 +#, c-format +msgid "cannot change routine kind" +msgstr "ルーチンの種別は変更できません" + +#: catalog/pg_aggregate.c:706 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "\"%s\"は通常の集約関数です。" + +#: catalog/pg_aggregate.c:708 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "\"%s\"は順序集合集約です。" + +#: catalog/pg_aggregate.c:710 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "\"%s\"は仮説集合集約です。" + +#: catalog/pg_aggregate.c:715 +#, c-format +msgid "cannot change number of direct arguments of an aggregate function" +msgstr "集約関数の直接引数の数は変更できません" + +#: catalog/pg_aggregate.c:852 commands/functioncmds.c:667 commands/typecmds.c:1658 commands/typecmds.c:1704 commands/typecmds.c:1756 commands/typecmds.c:1793 commands/typecmds.c:1827 commands/typecmds.c:1861 commands/typecmds.c:1895 commands/typecmds.c:1972 commands/typecmds.c:2014 parser/parse_func.c:414 parser/parse_func.c:443 parser/parse_func.c:468 parser/parse_func.c:482 parser/parse_func.c:602 parser/parse_func.c:622 parser/parse_func.c:2129 +#: parser/parse_func.c:2320 +#, c-format +msgid "function %s does not exist" +msgstr "関数%sは存在しません" + +#: catalog/pg_aggregate.c:858 +#, c-format +msgid "function %s returns a set" +msgstr "関数%sは集合を返します" + +#: catalog/pg_aggregate.c:873 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "この集約で使うには関数%sは VARIADIC ANY を受け付ける必要があります" + +#: catalog/pg_aggregate.c:897 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "関数%sは実行時の型強制が必要です" + +#: catalog/pg_cast.c:67 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "型%sから型%sへのキャストはすでに存在しています" + +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "照合順序\"%s\"はすでに存在します、スキップします" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "エンコーディング\"%2$s\"に対する照合順序\"%1$s\"はすでに存在します、スキップします" + +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "照合順序\"%s\"はすでに存在します" + +#: catalog/pg_collation.c:105 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "エンコーディング\"%2$s\"の照合順序\"%1$s\"はすでに存在します" + +#: catalog/pg_constraint.c:662 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "ドメイン\"%2$s\"の制約\"%1$s\"はすでに存在します" + +#: catalog/pg_constraint.c:858 catalog/pg_constraint.c:951 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "テーブル\"%2$s\"の制約\"%1$s\"は存在しません" + +#: catalog/pg_constraint.c:1040 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "ドメイン\"%2$s\"に対する制約\"%1$s\"は存在しません" + +#: catalog/pg_conversion.c:67 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "変換\"%s\"はすでに存在します" + +#: catalog/pg_conversion.c:80 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "%sから%sへのデフォルトの変換はすでに存在します" + +#: catalog/pg_depend.c:162 commands/extension.c:3343 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "%sはすでに機能拡張\"%s\"のメンバです" + +#: catalog/pg_depend.c:538 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "システムオブジェクトであるため、%sの依存関係を削除できません。" + +#: catalog/pg_enum.c:127 catalog/pg_enum.c:230 catalog/pg_enum.c:525 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "列挙ラベル\"%s\"は不正です" + +#: catalog/pg_enum.c:128 catalog/pg_enum.c:231 catalog/pg_enum.c:526 +#, c-format +msgid "Labels must be %d characters or less." +msgstr "ラベルは%d文字数以内でなければなりません" + +#: catalog/pg_enum.c:259 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "列挙ラベル\"%s\"はすでに存在します、スキップします" + +#: catalog/pg_enum.c:266 catalog/pg_enum.c:569 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "列挙ラベル\"%s\"はすでに存在します" + +#: catalog/pg_enum.c:321 catalog/pg_enum.c:564 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "\"%s\"は既存の列挙型ラベルではありません" + +#: catalog/pg_enum.c:379 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "バイナリアップグレードモード中に pg_enum のOIDが設定されていません" + +#: catalog/pg_enum.c:389 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "ALTER TYPE ADD BEFORE/AFTER はバイナリアップグレードでは互換性がありません" + +#: catalog/pg_namespace.c:64 commands/schemacmds.c:242 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "スキーマ\"%s\"はすでに存在します" + +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "\"%s\"は有効な演算子名ではありません" + +#: catalog/pg_operator.c:370 +#, c-format +msgid "only binary operators can have commutators" +msgstr "二項演算子のみが交換子を持つことができます" + +#: catalog/pg_operator.c:374 commands/operatorcmds.c:495 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "二項演算子のみが結合選択性を持つことができます" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can merge join" +msgstr "二項演算子のみがマージ結合可能です" + +#: catalog/pg_operator.c:382 +#, c-format +msgid "only binary operators can hash" +msgstr "二項演算子のみがハッシュ可能です" + +#: catalog/pg_operator.c:393 +#, c-format +msgid "only boolean operators can have negators" +msgstr "ブール型演算子のみが否定演算子を持つことができます" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:503 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "ブール型演算子のみが制限選択率を持つことができます" + +#: catalog/pg_operator.c:401 commands/operatorcmds.c:507 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "ブール型演算子のみが結合選択率を持つことができます" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can merge join" +msgstr "ブール型演算子のみがマージ結合可能です" + +#: catalog/pg_operator.c:409 +#, c-format +msgid "only boolean operators can hash" +msgstr "ブール型演算子のみがハッシュ可能です" + +#: catalog/pg_operator.c:421 +#, c-format +msgid "operator %s already exists" +msgstr "演算子%sはすでに存在します" + +#: catalog/pg_operator.c:621 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "演算子は自身の否定子やソート演算子になることはできません" + +#: catalog/pg_proc.c:127 parser/parse_func.c:2191 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "関数は%dを超える引数を取ることができません" +msgstr[1] "関数は%d個を超える引数を取ることができません" + +#: catalog/pg_proc.c:364 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "同じ引数型を持つ関数\"%s\"はすでに存在します" + +#: catalog/pg_proc.c:376 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\"は集約関数です。" + +#: catalog/pg_proc.c:378 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\"は関数です。" + +#: catalog/pg_proc.c:380 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\"はプロシージャです。" + +#: catalog/pg_proc.c:382 +#, c-format +msgid "\"%s\" is a window function." +msgstr "関数\"%s\"はウィンドウ関数です。" + +#: catalog/pg_proc.c:402 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "プロシージャの出力パラメータの有無は変更できません" + +#: catalog/pg_proc.c:403 catalog/pg_proc.c:433 +#, c-format +msgid "cannot change return type of existing function" +msgstr "既存の関数の戻り値型を変更できません" + +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:409 catalog/pg_proc.c:436 catalog/pg_proc.c:481 catalog/pg_proc.c:507 catalog/pg_proc.c:533 +#, c-format +msgid "Use %s %s first." +msgstr "まず %s %s を使用してください。" + +#: catalog/pg_proc.c:434 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "OUTパラメータで定義された行型が異なります。" + +#: catalog/pg_proc.c:478 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "入力パラメーター\"%s\"の名称を変更できません" + +#: catalog/pg_proc.c:505 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "既存の関数からパラメータのデフォルト値を削除できません" + +#: catalog/pg_proc.c:531 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "既存のパラメータのデフォルト値のデータ型を変更できません" + +#: catalog/pg_proc.c:732 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "\"%s\"という名前の組み込み関数はありません" + +#: catalog/pg_proc.c:830 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "SQL関数は型%sを返すことができません" + +#: catalog/pg_proc.c:845 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "SQL関数は型%sの引数と取ることができません" + +#: catalog/pg_proc.c:938 executor/functions.c:1446 +#, c-format +msgid "SQL function \"%s\"" +msgstr "SQL関数\"%s\"" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Only tables can be added to publications." +msgstr "パブリケーションにはテーブルのみが追加できます" + +#: catalog/pg_publication.c:65 +#, c-format +msgid "\"%s\" is a system table" +msgstr "\"%s\"はシステムテーブルです" + +#: catalog/pg_publication.c:67 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "システムテーブルをパブリケーションに追加することはできません" + +#: catalog/pg_publication.c:73 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "テーブル\"%s\"はレプリケーションできません" + +#: catalog/pg_publication.c:75 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "一時テーブルとUNLOGGEDテーブルはレプリケーションできません" + +#: catalog/pg_publication.c:174 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "リレーション\"%s\"はすでにパブリケーション\"%s\"のメンバです" + +#: catalog/pg_publication.c:470 commands/publicationcmds.c:451 commands/publicationcmds.c:739 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "パブリケーション\"%s\"は存在しません" + +#: catalog/pg_shdepend.c:776 +#, c-format +msgid "" +"\n" +"and objects in %d other database (see server log for list)" +msgid_plural "" +"\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "" +"\n" +"および、他の%dのデータベース内のオブジェクト(一覧についてはサーバログを参照してください)" +msgstr[1] "" +"\n" +"および、他の%dのデータベース内のオブジェクト(一覧についてはサーバログを参照してください)" + +#: catalog/pg_shdepend.c:1122 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "ロール%uの削除が同時に行われました" + +#: catalog/pg_shdepend.c:1141 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "テーブル空間%uの削除が同時に行われました" + +#: catalog/pg_shdepend.c:1156 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "データベース%uの削除が同時に行われました" + +#: catalog/pg_shdepend.c:1201 +#, c-format +msgid "owner of %s" +msgstr "%sの所有者" + +#: catalog/pg_shdepend.c:1203 +#, c-format +msgid "privileges for %s" +msgstr "%sの権限" + +#: catalog/pg_shdepend.c:1205 +#, c-format +msgid "target of %s" +msgstr "%sの対象" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1213 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%2$s内の%1$d個のオブジェクト" +msgstr[1] "%2$s内の%1$d個のオブジェクト" + +#: catalog/pg_shdepend.c:1324 +#, c-format +msgid "cannot drop objects owned by %s because they are required by the database system" +msgstr "データベースシステムが必要としているため%sが所有するオブジェクトを削除できません" + +#: catalog/pg_shdepend.c:1471 +#, c-format +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" +msgstr "データベースシステムが必要としているため%sが所有するオブジェクトの所有者を再割り当てできません" + +#: catalog/pg_subscription.c:172 commands/subscriptioncmds.c:671 commands/subscriptioncmds.c:918 commands/subscriptioncmds.c:1140 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "サブスクリプション\"%s\"は存在しません" + +#: catalog/pg_type.c:131 catalog/pg_type.c:468 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "バイナリアップグレードモード中にpg_typeのOIDが設定されていません" + +#: catalog/pg_type.c:249 +#, c-format +msgid "invalid type internal size %d" +msgstr "型の内部サイズ%dは不正です" + +#: catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:281 catalog/pg_type.c:290 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "値渡し型でサイズが%2$dの場合、アラインメント\"%1$c\"は不正です" + +#: catalog/pg_type.c:297 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "値渡し型の場合、内部サイズ%dは不正です" + +#: catalog/pg_type.c:307 catalog/pg_type.c:313 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "可変長型の場合、アラインメント\"%c\"は不正です" + +#: catalog/pg_type.c:321 commands/typecmds.c:3727 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "固定長型の場合はPLAIN格納方式でなければなりません" + +#: catalog/pg_type.c:814 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "\"%s\"型向けの配列型の名前を形成できませんでした" + +#: catalog/storage.c:449 storage/buffer/bufmgr.c:934 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "リレーション%2$sのブロック%1$uに不正なページ" + +#: catalog/toasting.c:103 commands/indexcmds.c:639 commands/tablecmds.c:5551 commands/tablecmds.c:15433 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "\"%s\"はテーブルや実体化ビューではありません" + +#: commands/aggregatecmds.c:171 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "順序集合集約のみが仮説的集約になり得ます" + +#: commands/aggregatecmds.c:196 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "集約の属性\"%sは認識できません" + +#: commands/aggregatecmds.c:206 +#, c-format +msgid "aggregate stype must be specified" +msgstr "集約のstypeを指定する必要があります" + +#: commands/aggregatecmds.c:210 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "集約用の状態遷移関数を指定する必要があります" + +#: commands/aggregatecmds.c:222 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "mstype を指定した場合は集約の msfunc も設定する必要があります" + +#: commands/aggregatecmds.c:226 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "mstype を指定した場合は集約の minvfunc も設定する必要があります" + +#: commands/aggregatecmds.c:233 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "集約の msfunc は mstype を指定してない場合は指定できません" + +#: commands/aggregatecmds.c:237 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "集約の minvfunc は mstype を指定していない場合は指定できません" + +#: commands/aggregatecmds.c:241 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "集約の mfinalfunc は mstype を指定していない場合は指定できません" + +#: commands/aggregatecmds.c:245 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "集約の msspace は mstype を指定していない場合は指定できません" + +#: commands/aggregatecmds.c:249 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "集約の minitcond は mstype を指定していない場合は指定できません" + +#: commands/aggregatecmds.c:278 +#, c-format +msgid "aggregate input type must be specified" +msgstr "集約の入力型を指定する必要があります" + +#: commands/aggregatecmds.c:308 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "集約の入力型指定で基本型が冗長です" + +#: commands/aggregatecmds.c:349 commands/aggregatecmds.c:390 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "集約の遷移データの型を%sにできません" + +#: commands/aggregatecmds.c:361 +#, c-format +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "直列化関数は集約遷移データの型が%sの場合にだけ指定可能です" + +#: commands/aggregatecmds.c:371 +#, c-format +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "直列化関数と復元関数は両方指定するか、両方指定しないかのどちらかである必要があります" + +#: commands/aggregatecmds.c:436 commands/functioncmds.c:615 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "パラメータ\"parallel\"はSAVE、RESTRICTEDまたはUNSAFEのいずれかでなければなりません" + +#: commands/aggregatecmds.c:492 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "パラメータ\"%s\"は READ_ONLY、SHAREABLE または READ_WRITE でなくてはなりません" + +#: commands/alter.c:84 commands/event_trigger.c:174 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "イベントトリガ\"%s\"はすでに存在します" + +#: commands/alter.c:87 commands/foreigncmds.c:597 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "外部データラッパー\"%s\"はすでに存在します" + +#: commands/alter.c:90 commands/foreigncmds.c:879 +#, c-format +msgid "server \"%s\" already exists" +msgstr "サーバ\"%s\"はすでに存在します" + +#: commands/alter.c:93 commands/proclang.c:132 +#, c-format +msgid "language \"%s\" already exists" +msgstr "言語\"%s\"はすでに存在します" + +#: commands/alter.c:96 commands/publicationcmds.c:183 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "パブリケーション\"%s\"はすでに存在します" + +#: commands/alter.c:99 commands/subscriptioncmds.c:397 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "サブスクリプション\"%s\"はすでに存在します" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "変換\"%s\"はスキーマ\"%s\"内にすでに存在します" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "統計情報オブジェクト\"%s\"はスキーマ\"%s\"内にすでに存在します" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr "テキスト検索パーサ\"%s\"はすでにスキーマ\"%s\"存在します" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "テキスト検索辞書\"%s\"はすでにスキーマ\"%s\"存在します" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "テキスト検索テンプレート\"%s\"はすでにスキーマ\"%s\"存在します" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "テキスト検索設定\"%s\"はすでにスキーマ\"%s\"存在します" + +#: commands/alter.c:215 +#, c-format +msgid "must be superuser to rename %s" +msgstr "%sの名前を変更するにはスーパユーザである必要があります" + +#: commands/alter.c:744 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "%sのスキーマを設定するにはスーパユーザである必要があります" + +#: commands/amcmds.c:60 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "アクセスメソッド\"%s\"を作成する権限がありません" + +#: commands/amcmds.c:62 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "アクセスメソッドを作成するにはスーパユーザである必要があります" + +#: commands/amcmds.c:71 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "アクセスメソッド\"%s\"は存在しません" + +#: commands/amcmds.c:154 commands/indexcmds.c:188 commands/indexcmds.c:790 commands/opclasscmds.c:370 commands/opclasscmds.c:824 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "アクセスメソッド\"%s\"は存在しません" + +#: commands/amcmds.c:243 +#, c-format +msgid "handler function is not specified" +msgstr "ハンドラ関数の指定がありません" + +#: commands/amcmds.c:264 commands/event_trigger.c:183 commands/foreigncmds.c:489 commands/proclang.c:79 commands/trigger.c:687 parser/parse_clause.c:941 +#, c-format +msgid "function %s must return type %s" +msgstr "関数%sは型%sを返さなければなりません" + +#: commands/analyze.c:226 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "\"%s\"をスキップしています --- この外部テーブルに対してANALYZEを実行することはできません" + +#: commands/analyze.c:243 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "\"%s\"をスキップしています --- テーブルでないものや特別なシステムテーブルに対してANALYZEを実行することはできません" + +#: commands/analyze.c:318 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "\"%s.%s\"継承ツリーを解析しています" + +#: commands/analyze.c:323 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "\"%s.%s\"を解析しています" + +#: commands/analyze.c:383 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "リレーション\"%2$s\"の列\"%1$s\"が2回以上現れます" + +#: commands/analyze.c:689 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" +msgstr "テーブル\"%s.%s.%s\"の自動ANALYZE システム使用状況: %s\"" + +#: commands/analyze.c:1158 +#, c-format +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "\"%1$s\": %3$uページの内%2$dをスキャン。%4$.0fの有効な行と%5$.0fの不要な行が存在。%6$d行をサンプリング。推定総行数は%7$.0f" + +#: commands/analyze.c:1238 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "継承ツリー\"%s.%s\"のANALYZEをスキップします --- このツリーには子テーブルがありません" + +#: commands/analyze.c:1336 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "継承ツリー\"%s.%s\"のANALYZEをスキップします --- このツリーにはアナライズ可能な子テーブルがありません" + +#: commands/async.c:631 +#, c-format +msgid "channel name cannot be empty" +msgstr "チャネル名が空であることはできません" + +#: commands/async.c:637 +#, c-format +msgid "channel name too long" +msgstr "チャネル名が長すぎます" + +#: commands/async.c:642 +#, c-format +msgid "payload string too long" +msgstr "ペイロード文字列が長すぎます" + +#: commands/async.c:861 +#, c-format +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "LISTEN / UNLISTEN / NOTIFY を実行しているトランザクションは PREPARE できません" + +#: commands/async.c:967 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "NOTIFY キューで発生した通知イベントが多すぎます" + +#: commands/async.c:1633 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "NOTYFY キューが %.0f%% まで一杯になっています" + +#: commands/async.c:1635 +#, c-format +msgid "The server process with PID %d is among those with the oldest transactions." +msgstr "PID %d のサーバプロセスは、この中で最も古いトランザクションを実行中です。" + +#: commands/async.c:1638 +#, c-format +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." +msgstr "このプロセスが現在のトランザクションを終了するまで NOTYFY キューを空にすることはできません" + +#: commands/cluster.c:125 commands/cluster.c:362 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "他のセッションの一時テーブルをクラスタ化できません" + +#: commands/cluster.c:133 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "パーティションテーブルに対して CLUSTER は実行できません" + +#: commands/cluster.c:151 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "テーブル\"%s\"には事前にクラスタ化されたインデックスはありません" + +#: commands/cluster.c:165 commands/tablecmds.c:12709 commands/tablecmds.c:14515 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "テーブル\"%2$s\"にはインデックス\"%1$s\"は存在しません" + +#: commands/cluster.c:351 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "共有カタログをクラスタ化できません" + +#: commands/cluster.c:366 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "他のセッションの一時テーブルに対してはVACUUMを実行できません" + +#: commands/cluster.c:432 commands/tablecmds.c:14525 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "\"%s\"はテーブル\"%s\"のインデックスではありません" + +#: commands/cluster.c:440 +#, c-format +msgid "cannot cluster on index \"%s\" because access method does not support clustering" +msgstr "インデックス\"%s\"でクラスタ化できません。アクセスメソッドがクラスタ化をサポートしないためです" + +#: commands/cluster.c:452 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "部分インデックス\"%s\"をクラスタ化できません" + +#: commands/cluster.c:466 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "無効なインデックス\"%s\"ではクラスタ化できません" + +#: commands/cluster.c:490 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "パーティションテーブル内のインデックスは CLUSTER 済みとマークできません`" + +#: commands/cluster.c:863 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr "\"%3$s\"に対するインデックススキャンを使って\"%1$s.%2$s\"をクラスタ化しています" + +#: commands/cluster.c:869 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "シーケンシャルスキャンとソートを使って\"%s.%s\"をクラスタ化しています" + +#: commands/cluster.c:900 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "\"%1$s\": 全 %4$u ページ中に見つかった行バージョン: 移動可能 %2$.0f 行、削除不可 %3$.0f 行" + +#: commands/cluster.c:904 +#, c-format +msgid "" +"%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "" +"%.0f 個の無効な行が今はまだ削除できません。\n" +"%s." + +#: commands/collationcmds.c:105 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "照合順序の属性\"%s\"が認識できません" + +#: commands/collationcmds.c:148 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "照合順序\"default\"は複製できません" + +#: commands/collationcmds.c:181 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "認識できないの照合順序プロバイダ: %s" + +#: commands/collationcmds.c:190 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "\"lc_collate\"パラメータの指定が必要です" + +#: commands/collationcmds.c:195 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "\"lc_ctype\"パラメータの指定が必要です" + +#: commands/collationcmds.c:205 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "非決定的照合順序はこのプロバイダではサポートされません" + +#: commands/collationcmds.c:265 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "エンコーディング\"%2$s\"のための照合順序\"%1$s\"はすでにスキーマ\"%3$s\"内に存在します" + +#: commands/collationcmds.c:276 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "照合順序\"%s\"はすでにスキーマ\"%s\"内に存在します" + +#: commands/collationcmds.c:324 +#, c-format +msgid "changing version from %s to %s" +msgstr "バージョン%sから%sへの変更" + +#: commands/collationcmds.c:339 +#, c-format +msgid "version has not changed" +msgstr "バージョンが変わっていません" + +#: commands/collationcmds.c:470 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "ロケール名\"%s\"を、言語タグに変換できませんでした: %s" + +#: commands/collationcmds.c:531 +#, c-format +msgid "must be superuser to import system collations" +msgstr "システム照合順序をインポートするにはスーパユーザである必要があります" + +#: commands/collationcmds.c:554 commands/copy.c:1944 commands/copy.c:3536 libpq/be-secure-common.c:81 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "コマンド\"%s\"を実行できませんでした: %m" + +#: commands/collationcmds.c:685 +#, c-format +msgid "no usable system locales were found" +msgstr "使用できるシステムロケールが見つかりません" + +#: commands/comment.c:61 commands/dbcommands.c:841 commands/dbcommands.c:1037 commands/dbcommands.c:1150 commands/dbcommands.c:1340 commands/dbcommands.c:1588 commands/dbcommands.c:1702 commands/dbcommands.c:2142 utils/init/postinit.c:892 utils/init/postinit.c:997 utils/init/postinit.c:1014 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "データベース\"%s\"は存在しません" + +#: commands/comment.c:101 commands/seclabel.c:191 parser/parse_utilcmd.c:955 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "\"%s\"はテーブル、ビュー、実体化ビュー、複合型、外部テーブルのいずれでもありません" + +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1923 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "関数\"%s\"はトリガ関数として呼び出されていません" + +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1932 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "関数\"%s\"はAFTER ROWトリガで実行してください" + +#: commands/constraint.c:84 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "関数\"%s\"はINSERTまたはUPDATEトリガで実行してください" + +#: commands/conversioncmds.c:66 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "変換元符号化方式\"%s\"は存在しません" + +#: commands/conversioncmds.c:73 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "変換先符号化方式\"%s\"は存在しません" + +#: commands/conversioncmds.c:86 +#, c-format +msgid "encoding conversion to or from \"SQL_ASCII\" is not supported" +msgstr "SQL_ASCIIとの間のエンコーディング変換はサポートされていません" + +#: commands/conversioncmds.c:99 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "エンコード変換関数%sは%s型を返す必要があります" + +#: commands/copy.c:434 commands/copy.c:468 +#, c-format +msgid "COPY BINARY is not supported to stdout or from stdin" +msgstr "標準入出力を介したCOPY BINARYはサポートされていません" + +#: commands/copy.c:568 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "COPYプログラムに書き出せませんでした: %m" + +#: commands/copy.c:573 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "COPYファイルに書き出せませんでした: %m" + +#: commands/copy.c:586 +#, c-format +msgid "connection lost during COPY to stdout" +msgstr "標準出力へのCOPY中に接続が失われました" + +#: commands/copy.c:630 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "COPYファイルから読み込めませんでした: %m" + +#: commands/copy.c:648 commands/copy.c:669 commands/copy.c:673 tcop/postgres.c:344 tcop/postgres.c:380 tcop/postgres.c:407 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "トランザクションを実行中のクライアント接続で想定外のEOFがありました" + +#: commands/copy.c:686 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "標準入力からのCOPYが失敗しました: %s" + +#: commands/copy.c:702 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "標準入力からのCOPY中に想定外のメッセージタイプ0x%02Xがありました" + +#: commands/copy.c:911 +#, c-format +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "外部プログラムを入出力対象としたCOPYを行うにはスーパユーザまたは pg_execute_server_program ロールのメンバである必要があります" + +#: commands/copy.c:912 commands/copy.c:921 commands/copy.c:928 +#, c-format +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." +msgstr "標準入出力経由のCOPYは誰でも実行可能です。またpsqlの\\\\copyも誰でも実行できます" + +#: commands/copy.c:920 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "ファイルからの COPY を行うにはスーパユーザまたは pg_read_server_files ロールのメンバである必要があります" + +#: commands/copy.c:927 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "ファイルへの COPY を行うにはスーパユーザまたは pg_write_server_files ロールのメンバである必要があります" + +#: commands/copy.c:1013 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM で行レベルセキュリティはサポートされていません" + +#: commands/copy.c:1014 +#, c-format +msgid "Use INSERT statements instead." +msgstr "代わりにINSERTを文使用してください。" + +#: commands/copy.c:1196 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "COPY フォーマット\"%s\"を認識できません" + +#: commands/copy.c:1267 commands/copy.c:1283 commands/copy.c:1298 commands/copy.c:1320 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "オプション\"%s\"の引数は列名のリストでなければなりません" + +#: commands/copy.c:1335 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "オプション\"%s\"の引数は有効なエンコーディング名でなければなりません" + +#: commands/copy.c:1342 commands/dbcommands.c:253 commands/dbcommands.c:1536 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "タイムゾーン\"%s\"を認識できません" + +#: commands/copy.c:1354 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "BINARYモードではDELIMITERを指定できません" + +#: commands/copy.c:1359 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "BINARYモードではNULLを指定できません" + +#: commands/copy.c:1381 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "COPYの区切り文字は単一の1バイト文字でなければなりません" + +#: commands/copy.c:1388 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "COPYの区切り文字は改行や復帰記号とすることができません" + +#: commands/copy.c:1394 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "COPYのNULL表現には改行や復帰記号を使用することはできません" + +#: commands/copy.c:1411 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "COPYの区切り文字を\"%s\"とすることはできません" + +#: commands/copy.c:1417 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "COPY HEADERはCSVモードでのみ使用できます" + +#: commands/copy.c:1423 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "COPYの引用符はCSVモードでのみ使用できます" + +#: commands/copy.c:1428 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "COPYの引用符は単一の1バイト文字でなければなりません" + +#: commands/copy.c:1433 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "COPYの区切り文字と引用符は異なる文字でなければなりません" + +#: commands/copy.c:1439 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "COPYのエスケープはCSVモードでのみ使用できます" + +#: commands/copy.c:1444 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "COPYのエスケープは単一の1バイト文字でなければなりません" + +#: commands/copy.c:1450 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "COPYのFORCE_QUOTEオプションはCSVモードでのみ使用できます" + +#: commands/copy.c:1454 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "COPYのFORCE_QUOTEオプションはCOPY TOでのみ使用できます" + +#: commands/copy.c:1460 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "COPYのFORCE_NOT_NULLオプションはCSVモードでのみ使用できます" + +#: commands/copy.c:1464 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "COPYのFORCE_NOT_NULLオプションはCOPY FROMでのみ使用できます" + +#: commands/copy.c:1470 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "COPYのFORCE_NULLオプションはCSVモードでのみ使用できます" + +#: commands/copy.c:1475 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "COPYのFORCE_NOT_NULLオプションはCOPY FROMでのみ使用できます" + +#: commands/copy.c:1481 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "COPYの区切り文字をNULLオプションの値に使用できません" + +#: commands/copy.c:1488 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "COPYの引用符をNULLオプションの値に使用できません" + +#: commands/copy.c:1574 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "DO INSTEAD NOTHING ルールは COPY ではサポートされていません" + +#: commands/copy.c:1588 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "条件付き DO INSTEAD ルールは COPY ではサポートされていません" + +#: commands/copy.c:1592 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "DO ALSO ルールは COPY ではサポートされていません" + +#: commands/copy.c:1597 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "マルチステートメントの DO INSTEAD ルールは COPY ではサポートされていません" + +#: commands/copy.c:1607 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO)はサポートされていません" + +#: commands/copy.c:1624 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "COPY文中の問い合わせではRETURNING句が必須です" + +#: commands/copy.c:1653 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "COPY文で参照されているリレーションが変更されました" + +#: commands/copy.c:1712 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "FORCE_QUOTE指定された列\"%s\"はCOPYで参照されません" + +#: commands/copy.c:1735 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "FORCE_NOT_NULL指定された列\"%s\"はCOPYで参照されません" + +#: commands/copy.c:1758 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "FORCE_NULL指定された列\"%s\"はCOPYで参照されません" + +#: commands/copy.c:1824 libpq/be-secure-common.c:105 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "外部コマンドに対するパイプをクローズできませんでした: %m" + +#: commands/copy.c:1839 +#, c-format +msgid "program \"%s\" failed" +msgstr "プログラム\"%s\"の実行に失敗しました" + +#: commands/copy.c:1890 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "ビュー\"%s\"からのコピーはできません" + +#: commands/copy.c:1892 commands/copy.c:1898 commands/copy.c:1904 commands/copy.c:1915 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "COPY (SELECT ...) TO構文を試してください" + +#: commands/copy.c:1896 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "実体化ビュー\"%s\"からのコピーはできません" + +#: commands/copy.c:1902 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "外部テーブル \"%s\" からのコピーはできません" + +#: commands/copy.c:1908 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "シーケンス\"%s\"からのコピーはできません" + +#: commands/copy.c:1913 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"からのコピーはできません" + +#: commands/copy.c:1919 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "テーブル以外のリレーション\"%s\"からのコピーはできません" + +#: commands/copy.c:1959 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "ファイルへのCOPYでは相対パスは指定できません" + +#: commands/copy.c:1978 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "ファイル\"%s\"を書き込み用にオープンできませんでした: %m" + +#: commands/copy.c:1981 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TOによってPostgreSQLサーバプロセスはファイルの書き込みを行います。psqlの \\copy のようなクライアント側の仕組みが必要かもしれません" + +#: commands/copy.c:1994 commands/copy.c:3567 +#, c-format +msgid "\"%s\" is a directory" +msgstr "\"%s\"はディレクトリです" + +#: commands/copy.c:2296 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "%sのCOPY、行 %s、列 %s" + +#: commands/copy.c:2300 commands/copy.c:2347 +#, c-format +msgid "COPY %s, line %s" +msgstr "%sのCOPY、行 %s" + +#: commands/copy.c:2311 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "%sのCOPY、行 %s、列 %s: \"%s\"" + +#: commands/copy.c:2319 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "%sのCOPY、行 %s、列 %s: null が入力されました" + +#: commands/copy.c:2341 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "%sのCOPY、行 %s: \"%s\"" + +#: commands/copy.c:2741 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "ビュー\"%s\"へのコピーはできません" + +#: commands/copy.c:2743 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "ビューへのコピーを可能にするためには、INSTEAD OF INSERTトリガを作成してください。" + +#: commands/copy.c:2747 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "実体化ビュー\"%s\"へのコピーはできません" + +#: commands/copy.c:2752 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "シーケンス\"%s\"へのコピーはできません" + +#: commands/copy.c:2757 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "テーブル以外のリレーション\"%s\"へのコピーはできません" + +#: commands/copy.c:2797 +#, c-format +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "パーティション親テーブルに対して CLUSTER は実行できません" + +#: commands/copy.c:2812 +#, c-format +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "先行するトランザクション処理のためCOPY FREEZEを実行することができません" + +#: commands/copy.c:2818 +#, c-format +msgid "cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "このテーブルは現在のサブトランザクションにおいて作成または切り詰めされていないため、COPY FREEZEを実行することができません" + +#: commands/copy.c:3554 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY FROMによってPostgreSQLサーバプロセスはファイルを読み込みます。psqlの \\copy のようなクライアント側の仕組みが必要かもしれません" + +#: commands/copy.c:3582 +#, c-format +msgid "COPY file signature not recognized" +msgstr "COPYファイルのシグネチャが不明です" + +#: commands/copy.c:3587 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "COPYファイルのヘッダが不正です(フラグがありません)" + +#: commands/copy.c:3591 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "COPYファイルのヘッダが不正です(WITH OIDS)" + +#: commands/copy.c:3596 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "COPYファイルのヘッダ内の重要なフラグが不明です" + +#: commands/copy.c:3602 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "COPYファイルのヘッダが不正です(サイズがありません)" + +#: commands/copy.c:3609 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "COPYファイルのヘッダが不正です(サイズが不正です)" + +#: commands/copy.c:3728 commands/copy.c:4390 commands/copy.c:4620 +#, c-format +msgid "extra data after last expected column" +msgstr "推定最終列の後に余計なデータがありました" + +#: commands/copy.c:3742 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "列\"%s\"のデータがありません" + +#: commands/copy.c:3825 +#, c-format +msgid "received copy data after EOF marker" +msgstr "EOF マーカーの後ろでコピーデータを受信しました" + +#: commands/copy.c:3832 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "行のフィールド数は%d、その期待値は%dです" + +#: commands/copy.c:4149 commands/copy.c:4166 +#, c-format +msgid "literal carriage return found in data" +msgstr "データの中に復帰記号そのものがありました" + +#: commands/copy.c:4150 commands/copy.c:4167 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "データの中に引用符のない復帰記号がありました" + +#: commands/copy.c:4152 commands/copy.c:4169 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "復帰記号は\"\\r\"と表現してください" + +#: commands/copy.c:4153 commands/copy.c:4170 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "復帰記号を表現するにはCSVフィールドを引用符で括ってください" + +#: commands/copy.c:4182 +#, c-format +msgid "literal newline found in data" +msgstr "データの中に改行記号そのものがありました" + +#: commands/copy.c:4183 +#, c-format +msgid "unquoted newline found in data" +msgstr "データの中に引用符のない改行記号がありました" + +#: commands/copy.c:4185 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "改行記号は\"\\n\"と表現してください" + +#: commands/copy.c:4186 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "改行記号を表現するにはCSVフィールドを引用符で括ってください" + +#: commands/copy.c:4232 commands/copy.c:4268 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "コピー終端記号がこれまでの改行方式と一致しません" + +#: commands/copy.c:4241 commands/copy.c:4257 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "コピー終端記号が破損しています" + +#: commands/copy.c:4704 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "CSV引用符が閉じていません" + +#: commands/copy.c:4780 commands/copy.c:4799 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "COPYデータの中に想定外のEOFがあります" + +#: commands/copy.c:4789 +#, c-format +msgid "invalid field size" +msgstr "フィールドサイズが不正です" + +#: commands/copy.c:4812 +#, c-format +msgid "incorrect binary data format" +msgstr "バイナリデータ書式が不正です" + +#: commands/copy.c:5120 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "列\"%s\"は生成カラムです" + +#: commands/copy.c:5122 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "生成カラムはCOPYでは使えません。" + +#: commands/copy.c:5137 commands/indexcmds.c:1700 commands/statscmds.c:217 commands/tablecmds.c:2163 commands/tablecmds.c:2740 commands/tablecmds.c:3127 parser/parse_relation.c:3507 parser/parse_relation.c:3527 utils/adt/tsvector_op.c:2668 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "列\"%s\"は存在しません" + +#: commands/copy.c:5144 commands/tablecmds.c:2189 commands/trigger.c:885 parser/parse_target.c:1052 parser/parse_target.c:1063 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "列\"%s\"が複数指定されました" + +#: commands/createas.c:215 commands/createas.c:497 +#, c-format +msgid "too many column names were specified" +msgstr "指定された列別名が多すぎます" + +#: commands/createas.c:539 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "このコマンドにはポリシは実装されていません" + +#: commands/dbcommands.c:246 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATIONはもはやサポートされません" + +#: commands/dbcommands.c:247 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "代わりにテーブル空間の使用を検討してください" + +#: commands/dbcommands.c:261 +#, c-format +msgid "LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE." +msgstr "" +"LOCALE は LC_COLLATE または LC_CTYPE \n" +"と同時に指定することはできません" + +#: commands/dbcommands.c:279 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%dは有効な符号化方式コードではありません" + +#: commands/dbcommands.c:290 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%sは有効な符号化方式名ではありません" + +#: commands/dbcommands.c:314 commands/dbcommands.c:1569 commands/user.c:275 commands/user.c:691 +#, c-format +msgid "invalid connection limit: %d" +msgstr "不正な接続数制限: %d" + +#: commands/dbcommands.c:333 +#, c-format +msgid "permission denied to create database" +msgstr "データベースを作成する権限がありません" + +#: commands/dbcommands.c:356 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "テンプレートデータベース\"%s\"は存在しません" + +#: commands/dbcommands.c:368 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "データベース\"%s\"をコピーする権限がありません" + +#: commands/dbcommands.c:384 +#, c-format +msgid "invalid server encoding %d" +msgstr "サーバの符号化方式%dは不正です" + +#: commands/dbcommands.c:390 commands/dbcommands.c:395 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "ロケール名\"%s\"は不正です" + +#: commands/dbcommands.c:415 +#, c-format +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" +msgstr "新しい符号化方式(%s)はテンプレートデータベースの符号化方式(%s)と互換性がありません" + +#: commands/dbcommands.c:418 +#, c-format +msgid "Use the same encoding as in the template database, or use template0 as template." +msgstr "テンプレートデータベースの符号化方式と同じものを使うか、もしくは template0 をテンプレートとして使用してください" + +#: commands/dbcommands.c:423 +#, c-format +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" +msgstr "新しい照合順序(%s)はテンプレートデータベースの照合順序(%s)と互換性がありません" + +#: commands/dbcommands.c:425 +#, c-format +msgid "Use the same collation as in the template database, or use template0 as template." +msgstr "テンプレートデータベースの照合順序と同じものを使うか、もしくは template0 をテンプレートとして使用してください" + +#: commands/dbcommands.c:430 +#, c-format +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" +msgstr "新しいLC_CTYPE(%s)はテンプレートデータベース(%s)のLC_CTYPEと互換性がありません" + +#: commands/dbcommands.c:432 +#, c-format +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." +msgstr "テンプレートデータベースのLC_CTYPEと同じものを使うか、もしくはtemplate0をテンプレートとして使用してください" + +#: commands/dbcommands.c:454 commands/dbcommands.c:1196 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "デフォルトのテーブル空間としてpg_globalを使用できません" + +#: commands/dbcommands.c:480 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "新しいデフォルトのテーブル空間\"%s\"を割り当てられません" + +#: commands/dbcommands.c:482 +#, c-format +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." +msgstr "データベース\"%s\"のいくつかテーブルはすでにこのテーブル空間にあるため、競合しています。" + +#: commands/dbcommands.c:512 commands/dbcommands.c:1066 +#, c-format +msgid "database \"%s\" already exists" +msgstr "データベース\"%s\"はすでに存在します" + +#: commands/dbcommands.c:526 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "元となるデータベース\"%s\"は他のユーザによってアクセスされています" + +#: commands/dbcommands.c:769 commands/dbcommands.c:784 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "符号化方式\"%s\"がロケール\"%s\"に合いません" + +#: commands/dbcommands.c:772 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "選択されたLC_CTYPEを設定するには、符号化方式\"%s\"である必要があります。" + +#: commands/dbcommands.c:787 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "選択されたLC_COLLATEを設定するには、符号化方式\"%s\"である必要があります。" + +#: commands/dbcommands.c:848 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "データベース\"%s\"は存在しません、スキップします" + +#: commands/dbcommands.c:872 +#, c-format +msgid "cannot drop a template database" +msgstr "テンプレートデータベースを削除できません" + +#: commands/dbcommands.c:878 +#, c-format +msgid "cannot drop the currently open database" +msgstr "現在オープンしているデータベースを削除できません" + +#: commands/dbcommands.c:891 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "データベース\"%s\"は有効な論理レプリケーションスロットで使用中です" + +#: commands/dbcommands.c:893 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "%d 個のアクティブなスロットがあります。" +msgstr[1] "%d 個のアクティブなスロットがあります。" + +#: commands/dbcommands.c:907 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "データベース\"%s\"は論理レプリケーションのサブスクリプションで使用中です" + +#: commands/dbcommands.c:909 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "%d個のサブスクリプションがあります" +msgstr[1] "%d個のサブスクリプションがあります" + +#: commands/dbcommands.c:930 commands/dbcommands.c:1088 commands/dbcommands.c:1218 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "データベース\"%s\"は他のユーザからアクセスされています" + +#: commands/dbcommands.c:1048 +#, c-format +msgid "permission denied to rename database" +msgstr "データベースの名前を変更する権限がありません" + +#: commands/dbcommands.c:1077 +#, c-format +msgid "current database cannot be renamed" +msgstr "現在のデータベースの名前を変更できません" + +#: commands/dbcommands.c:1174 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "現在オープン中のデータベースのテーブルスペースは変更できません" + +#: commands/dbcommands.c:1277 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "データベース\"%s\"のリレーションの中に、テーブルスペース\"%s\"にすでに存在するものがあります" + +#: commands/dbcommands.c:1279 +#, c-format +msgid "You must move them back to the database's default tablespace before using this command." +msgstr "このコマンドを使う前に、データベースのデフォルトのテーブルスペースに戻す必要があります。" + +#: commands/dbcommands.c:1404 commands/dbcommands.c:1980 commands/dbcommands.c:2203 commands/dbcommands.c:2261 commands/tablespace.c:619 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "元のデータベースのディレクトリ\"%s\"に不要なファイルが残っているかもしれません" + +#: commands/dbcommands.c:1460 +#, c-format +msgid "unrecognized DROP DATABASE option \"%s\"" +msgstr "DROP DATABASEのオプション\"%s\"が認識できません" + +#: commands/dbcommands.c:1550 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "オプション\"%s\"は他のオプションと一緒に指定はできません" + +#: commands/dbcommands.c:1606 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "現在のデータベースへの接続は禁止できません" + +#: commands/dbcommands.c:1742 +#, c-format +msgid "permission denied to change owner of database" +msgstr "データベースの所有者を変更する権限がありません" + +#: commands/dbcommands.c:2086 +#, c-format +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." +msgstr "他にこのデータベースを使っている %d 個のセッションと %d 個の準備済みトランザクションがあります。" + +#: commands/dbcommands.c:2089 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "他にこのデータベースを使っている %d 個のセッションがあります。" +msgstr[1] "他にこのデータベースを使っている %d 個のセッションがあります。" + +#: commands/dbcommands.c:2094 storage/ipc/procarray.c:3632 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "このデータベースを使用する準備されたトランザクションが%d存在します。" +msgstr[1] "このデータベースを使用する準備されたトランザクションが%d存在します。" + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%sはパラメータが必要です" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%sは数値が必要です" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "パラメータ\"%s\"はboolean値が必要です" + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%sは整数値が必要です" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "%sの引数は名前でなければなりません" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "%sの引数は型名でなければなりません" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "%sの引数が不正です: \"%s\"" + +#: commands/dropcmds.c:100 commands/functioncmds.c:1274 utils/adt/ruleutils.c:2633 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "\"%s\"は集約関数です" + +#: commands/dropcmds.c:102 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "集約関数を削除するにはDROP AGGREGATEを使用してください" + +#: commands/dropcmds.c:158 commands/sequence.c:447 commands/tablecmds.c:3211 commands/tablecmds.c:3369 commands/tablecmds.c:3414 commands/tablecmds.c:14894 tcop/utility.c:1276 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:188 commands/dropcmds.c:287 commands/tablecmds.c:1197 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "スキーマ\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:228 commands/dropcmds.c:267 commands/tablecmds.c:259 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "型\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:257 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "アクセスメソッド\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:275 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "照合順序\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:282 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "変換\"%sは存在しません、スキップします" + +#: commands/dropcmds.c:293 commands/statscmds.c:479 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "統計情報オブジェクト\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:300 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr "テキスト検索パーサ\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:307 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "テキスト検索辞書\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:314 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "テキスト検索テンプレート\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:321 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "テキスト検索設定\"%sは存在しません、スキップします" + +#: commands/dropcmds.c:326 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "機能拡張\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:336 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "関数%s(%s)は存在しません、スキップします" + +#: commands/dropcmds.c:349 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "プロシージャ %s(%s) は存在しません、スキップします" + +#: commands/dropcmds.c:362 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "ルーチン %s(%s) は存在しません、スキップします" + +#: commands/dropcmds.c:375 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "集約%s(%s)は存在しません、スキップします" + +#: commands/dropcmds.c:388 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "演算子%sは存在しません、スキップします" + +#: commands/dropcmds.c:394 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "言語\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:403 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "型%sから型%sへのキャストは存在しません、スキップします" + +#: commands/dropcmds.c:412 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "型%s、言語\"%s\"に対する変換は存在しません、スキップします" + +#: commands/dropcmds.c:420 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%2$s\"のトリガ\"%1$s\"は存在しません、スキップします" + +#: commands/dropcmds.c:429 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%2$s\"のポリシ\"%1$s\"は存在しません、スキップします" + +#: commands/dropcmds.c:436 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "イベントトリガ \"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:442 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%2$s\"のルール\"%1$s\"は存在しません、スキップします" + +#: commands/dropcmds.c:449 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "外部データラッパ\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:453 commands/foreigncmds.c:1351 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "外部データラッパ\"%s\"は存在しません、スキップします" + +#: commands/dropcmds.c:462 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "アクセスメソッド\"%2$s\"に対する演算子クラス\"%1$s\"は存在しません、スキップします" + +#: commands/dropcmds.c:474 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "アクセスメソッド\"%2$s\"に対する演算子族\"%1$s\"は存在しません、スキップします" + +#: commands/dropcmds.c:481 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "パブリケーション\"%s\"は存在しません、スキップします" + +#: commands/event_trigger.c:125 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "イベントトリガ \"%s\"を作成する権限がありません" + +#: commands/event_trigger.c:127 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "イベントトリガを作成するにはスーパユーザである必要があります。" + +#: commands/event_trigger.c:136 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "識別できないイベント名\"%s\"" + +#: commands/event_trigger.c:153 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "識別できないフィルタ変数\"%s\"" + +#: commands/event_trigger.c:207 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "フィルタの値\"%s\"はフィルタ変数\"%s\"では認識されません" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:213 commands/event_trigger.c:235 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "%sではイベントトリガはサポートされません" + +#: commands/event_trigger.c:248 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "フィルタ変数\"%s\"が複数指定されました" + +#: commands/event_trigger.c:377 commands/event_trigger.c:421 commands/event_trigger.c:515 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "イベントトリガ\"%s\"は存在しません" + +#: commands/event_trigger.c:483 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "イベントトリガ\"%s\"の所有者を変更する権限がありません" + +#: commands/event_trigger.c:485 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "イベントトリガの所有者はスーパユーザでなければなりません" + +#: commands/event_trigger.c:1304 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%sはsql_dropイベントトリガ関数内でのみ呼び出すことができます" + +#: commands/event_trigger.c:1424 commands/event_trigger.c:1445 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%sはtable_rewriteイベントトリガ関数でのみ呼び出すことができます" + +#: commands/event_trigger.c:1856 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%sはイベントトリガ関数でのみ呼び出すことができます" + +#: commands/explain.c:212 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "EXPLAIN オプション\"%s\"が認識できない値です: \"%s\"" + +#: commands/explain.c:219 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "EXPLAIN オプション\"%s\"が認識できません" + +#: commands/explain.c:227 +#, c-format +msgid "EXPLAIN option BUFFERS requires ANALYZE" +msgstr "EXPLAIN オプションの BUFFERS には ANALYZE 指定が必要です" + +#: commands/explain.c:232 +#, c-format +msgid "EXPLAIN option WAL requires ANALYZE" +msgstr "EXPLAINのオプションWALにはANALYZE指定が必要です" + +#: commands/explain.c:241 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "EXPLAINオプションのTIMINGにはANALYZE指定が必要です" + +#: commands/extension.c:173 commands/extension.c:3013 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "機能拡張\"%s\"は存在しません" + +#: commands/extension.c:272 commands/extension.c:281 commands/extension.c:293 commands/extension.c:303 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "機能拡張名が不正です: \"%s\"" + +#: commands/extension.c:273 +#, c-format +msgid "Extension names must not be empty." +msgstr "機能拡張名が無効です: 空であってはなりません" + +#: commands/extension.c:282 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "機能拡張名に\"--\"が含まれていてはなりません" + +#: commands/extension.c:294 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "機能拡張名が\"-\"で始まったり終わったりしてはなりません" + +#: commands/extension.c:304 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "機能拡張名にディレクトリの区切り文字が含まれていてはなりません" + +#: commands/extension.c:319 commands/extension.c:328 commands/extension.c:337 commands/extension.c:347 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "機能拡張のバージョン名が不正す: \"%s\"" + +#: commands/extension.c:320 +#, c-format +msgid "Version names must not be empty." +msgstr "バージョン名が無効です: 空であってはなりません" + +#: commands/extension.c:329 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "バージョン名に\"--\"が含まれていてはなりません" + +#: commands/extension.c:338 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "バージョン名が\"-\"で始まったり終わったりしてはなりません" + +#: commands/extension.c:348 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "バージョン名にディレクトリの区切り文字が含まれていてはなりません" + +#: commands/extension.c:498 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "機能拡張の制御ファイル\"%s\"をオープンできませんでした: %m" + +#: commands/extension.c:520 commands/extension.c:530 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "セカンダリの機能拡張制御ファイルにパラメータ\"%s\"を設定できません" + +#: commands/extension.c:552 commands/extension.c:560 commands/extension.c:568 utils/misc/guc.c:6767 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "パラメータ\"%s\"にはbooleanを指定します" + +#: commands/extension.c:577 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "\"%s\"は有効な符号化方式名ではありません" + +#: commands/extension.c:591 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "パラメータ\"%s\"は機能拡張名のリストでなければなりません" + +#: commands/extension.c:598 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "ファイル\"%2$s\"中に認識できないパラメータ\"%1$s\"があります" + +#: commands/extension.c:607 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr "\"relocatable\"が真の場合はパラメータ\"schema\"は指定できません" + +#: commands/extension.c:785 +#, c-format +msgid "transaction control statements are not allowed within an extension script" +msgstr "トランザクション制御ステートメントを機能拡張スクリプトの中に書くことはできません" + +#: commands/extension.c:861 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "機能拡張\"%s\"を作成する権限がありません" + +#: commands/extension.c:864 +#, c-format +msgid "Must have CREATE privilege on current database to create this extension." +msgstr "この機能拡張を生成するには現在のデータベースのCREATE権限が必要です。" + +#: commands/extension.c:865 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "この機能拡張を生成するにはスーパユーザである必要があります。" + +#: commands/extension.c:869 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "機能拡張\"%s\"を更新する権限がありません" + +#: commands/extension.c:872 +#, c-format +msgid "Must have CREATE privilege on current database to update this extension." +msgstr "この機能拡張を更新するには現在のデータベースのCREATE権限が必要です。" + +#: commands/extension.c:873 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "この機能拡張を更新するにはスーパユーザである必要があります。" + +#: commands/extension.c:1200 +#, c-format +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "機能拡張\"%s\"について、バージョン\"%s\"からバージョン\"%s\"へのアップデートパスがありません" + +#: commands/extension.c:1408 commands/extension.c:3074 +#, c-format +msgid "version to install must be specified" +msgstr "インストールするバージョンを指定してください" + +#: commands/extension.c:1445 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "機能拡張\"%s\"にはバージョン\"%s\"のインストールスクリプトもアップデートパスもありません" + +#: commands/extension.c:1479 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "機能拡張\"%s\"はスキーマ\"%s\"内にインストールされていなければなりません" + +#: commands/extension.c:1639 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "機能拡張\"%s\"と\"%s\"の間に循環依存関係が検出されました" + +#: commands/extension.c:1644 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "必要な機能拡張をインストールします:\"%s\"" + +#: commands/extension.c:1667 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr "要求された機能拡張\"%s\"はインストールされていません" + +#: commands/extension.c:1670 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "必要な機能拡張を一緒にインストールするには CREATE EXTENSION ... CASCADE を使ってください。" + +#: commands/extension.c:1705 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "機能拡張\"%s\"はすでに存在します、スキップします" + +#: commands/extension.c:1712 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "機能拡張\"%s\"はすでに存在します" + +#: commands/extension.c:1723 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "入れ子の CREATE EXTENSION はサポートされません" + +#: commands/extension.c:1896 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "変更されているため拡張\"%s\"を削除できません" + +#: commands/extension.c:2457 +#, c-format +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "%s はCREATE EXTENSIONにより実行されるSQLスクリプトからのみ呼び出すことができます" + +#: commands/extension.c:2469 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "OID %u がテーブルを参照していません" + +#: commands/extension.c:2474 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "テーブル\"%s\"は生成されようとしている機能拡張のメンバではありません" + +#: commands/extension.c:2828 +#, c-format +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" +msgstr "機能拡張がそのスキーマを含んでいるため、機能拡張\"%s\"をスキーマ\"%s\"に移動できません" + +#: commands/extension.c:2869 commands/extension.c:2932 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "機能拡張\"%s\"は SET SCHEMA をサポートしていません" + +#: commands/extension.c:2934 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "機能拡張のスキーマ\"%2$s\"に%1$sが見つかりません" + +#: commands/extension.c:2993 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "入れ子になった ALTER EXTENSION はサポートされていません" + +#: commands/extension.c:3085 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "機能拡張 \"%2$s\"のバージョン\"%1$s\"はすでにインストールされています" + +#: commands/extension.c:3297 +#, c-format +msgid "cannot add an object of this type to an extension" +msgstr "この型のオブジェクトは機能拡張に追加できません" + +#: commands/extension.c:3355 +#, c-format +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" +msgstr "スキーマ\"%s\"を拡張\"%s\"に追加できません。そのスキーマにその拡張が含まれているためです" + +#: commands/extension.c:3383 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "%s は機能拡張\"%s\"のメンバではありません" + +#: commands/extension.c:3449 +#, c-format +msgid "file \"%s\" is too large" +msgstr "ファイル\"%s\"は大きすぎます" + +#: commands/foreigncmds.c:148 commands/foreigncmds.c:157 +#, c-format +msgid "option \"%s\" not found" +msgstr "オプション\"%s\"が見つかりません" + +#: commands/foreigncmds.c:167 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "オプション\"%s\"が2回以上指定されました" + +#: commands/foreigncmds.c:221 commands/foreigncmds.c:229 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "外部データラッパー\"%s\"の所有者を変更する権限がありません" + +#: commands/foreigncmds.c:223 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "外部データラッパーの所有者を変更するにはスーパユーザである必要があります。" + +#: commands/foreigncmds.c:231 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "外部データラッパーの所有者はスーパユーザでなければなりません" + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:711 foreign/foreign.c:701 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "外部データラッパー\"%s\"は存在しません" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "外部データラッパー\"%s\"を作成する権限がありません" + +#: commands/foreigncmds.c:586 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "外部データラッパを作成するにはスーパユーザである必要があります。" + +#: commands/foreigncmds.c:701 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "外部データラッパー\"%s\"を変更する権限がありません" + +#: commands/foreigncmds.c:703 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "外部データラッパーを更新するにはスーパユーザである必要があります。" + +#: commands/foreigncmds.c:734 +#, c-format +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" +msgstr "外部データラッパーのハンドラーを変更すると、既存の外部テーブルの振る舞いが変わることがあります" + +#: commands/foreigncmds.c:749 +#, c-format +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +msgstr "外部データラッパーのバリデータ(検証用関数)を変更すると、それに依存するオプションが不正になる場合があります" + +#: commands/foreigncmds.c:871 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "サーバ\"%s\"はすでに存在します、スキップします" + +#: commands/foreigncmds.c:1135 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "\"%s\"のユーザマッピングはサーバ\"%s\"に対してすでに存在します、スキップします" + +#: commands/foreigncmds.c:1145 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "\"%s\"のユーザマッピングはサーバ\"%s\"に対してすでに存在します" + +#: commands/foreigncmds.c:1245 commands/foreigncmds.c:1365 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "\"%s\"のユーザマッピングはサーバ\"%s\"に対しては存在しません" + +#: commands/foreigncmds.c:1370 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "\"%s\"のユーザマッピングはサーバ\"%s\"に対しては存在しません、スキップします" + +#: commands/foreigncmds.c:1498 foreign/foreign.c:389 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "外部データラッパー\"%s\"にはハンドラがありません" + +#: commands/foreigncmds.c:1504 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "外部データラッパー\"%s\"は IMPORT FOREIGN SCHEMA をサポートしていません" + +#: commands/foreigncmds.c:1607 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "外部テーブル\"%s\"をインポートします" + +#: commands/functioncmds.c:104 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "SQL関数はシェル型%sを返却することができません" + +#: commands/functioncmds.c:109 +#, c-format +msgid "return type %s is only a shell" +msgstr "戻り値型%sは単なるシェル型です" + +#: commands/functioncmds.c:139 parser/parse_type.c:354 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "シェル型\"%s\"に型修正子を指定できません" + +#: commands/functioncmds.c:145 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "型\"%s\"は未定義です" + +#: commands/functioncmds.c:146 +#, c-format +msgid "Creating a shell type definition." +msgstr "シェル型の定義を作成します" + +#: commands/functioncmds.c:238 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "SQL関数はシェル型\"%s\"を受け付けられません" + +#: commands/functioncmds.c:244 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "集約はシェル型\"%s\"を受け付けられません" + +#: commands/functioncmds.c:249 +#, c-format +msgid "argument type %s is only a shell" +msgstr "引数型%sは単なるシェルです" + +#: commands/functioncmds.c:259 +#, c-format +msgid "type %s does not exist" +msgstr "型%sは存在しません" + +#: commands/functioncmds.c:273 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "集約は集合引数を受け付けられません" + +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "プロシージャは集合引数を受け付けません" + +#: commands/functioncmds.c:281 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "関数は集合を引数として受け付けられません" + +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "プロシージャは出力引数を持てません" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "INOUT 引数は指定可能です" + +#: commands/functioncmds.c:300 +#, c-format +msgid "VARIADIC parameter must be the last input parameter" +msgstr "VARIADIC パラメータは最後の入力パラメータでなければなりません" + +#: commands/functioncmds.c:331 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "VARIADIC パラメータは配列でなければなりません" + +#: commands/functioncmds.c:371 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "パラメータ\"%s\"が複数指定されました" + +#: commands/functioncmds.c:386 +#, c-format +msgid "only input parameters can have default values" +msgstr "入力パラメータのみがデフォルト値を持てます" + +#: commands/functioncmds.c:401 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "パラメータのデフォルト値としてテーブル参照を使用できません" + +#: commands/functioncmds.c:425 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "デフォルト値を持つパラメータの後にある入力パラメータは、必ずデフォルト値を持たなければなりません" + +#: commands/functioncmds.c:577 commands/functioncmds.c:768 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "プロシージャ定義内の不正な属性" + +#: commands/functioncmds.c:673 +#, c-format +msgid "support function %s must return type %s" +msgstr "サポート関数%sは%s型を返さなければなりません" + +#: commands/functioncmds.c:684 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "サポート関数を指定するにはスーパユーザである必要があります" + +#: commands/functioncmds.c:800 +#, c-format +msgid "no function body specified" +msgstr "関数本体の指定がありません" + +#: commands/functioncmds.c:810 +#, c-format +msgid "no language specified" +msgstr "言語が指定されていません" + +#: commands/functioncmds.c:835 commands/functioncmds.c:1319 +#, c-format +msgid "COST must be positive" +msgstr "COSTは正数でなければなりません" + +#: commands/functioncmds.c:843 commands/functioncmds.c:1327 +#, c-format +msgid "ROWS must be positive" +msgstr "ROWSは正数でなければなりません" + +#: commands/functioncmds.c:897 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "言語\"%s\"ではAS項目は1つだけ必要です" + +#: commands/functioncmds.c:995 commands/functioncmds.c:1995 commands/proclang.c:237 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "言語\"%s\"は存在しません" + +#: commands/functioncmds.c:997 commands/functioncmds.c:1997 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "言語をデータベースに読み込むためには CREATE EXTENSION を使用してください" + +#: commands/functioncmds.c:1032 commands/functioncmds.c:1311 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "スーパユーザのみがリークプルーフ関数を定義することができます" + +#: commands/functioncmds.c:1081 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "OUTパラメータで定義されているため、関数の戻り値型は%sでなければなりません" + +#: commands/functioncmds.c:1094 +#, c-format +msgid "function result type must be specified" +msgstr "関数の結果型を指定しなければなりません" + +#: commands/functioncmds.c:1146 commands/functioncmds.c:1331 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "関数が集合を返す場合にROWSは適していません" + +#: commands/functioncmds.c:1431 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "変換元データ型%sは疑似型です" + +#: commands/functioncmds.c:1437 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "変換先データ型%sは疑似型です" + +#: commands/functioncmds.c:1461 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "元のデータ型がドメインであるため、キャストは無視されます" + +#: commands/functioncmds.c:1466 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "対象のデータ型がドメインであるため、キャストは無視されます" + +#: commands/functioncmds.c:1491 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "キャスト関数の引数は1つから3つまでです" + +#: commands/functioncmds.c:1495 +#, c-format +msgid "argument of cast function must match or be binary-coercible from source data type" +msgstr "キャスト関数の引数は変換元データ型と同一であるか、変換元データ型からバイナリ変換可能である必要があります" + +#: commands/functioncmds.c:1499 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "キャスト関数の第2引数は%s型でなければなりません" + +#: commands/functioncmds.c:1504 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "キャスト関数の第3引数は%s型でなければなりません" + +#: commands/functioncmds.c:1509 +#, c-format +msgid "return data type of cast function must match or be binary-coercible to target data type" +msgstr "キャスト関数の戻り値データ型は変換先データ型と一致するか、変換先データ型へバイナリ変換可能である必要があります" + +#: commands/functioncmds.c:1520 +#, c-format +msgid "cast function must not be volatile" +msgstr "キャスト関数はvolatileではいけません" + +#: commands/functioncmds.c:1525 +#, c-format +msgid "cast function must be a normal function" +msgstr "キャスト関数は通常の関数でなければなりません" + +#: commands/functioncmds.c:1529 +#, c-format +msgid "cast function must not return a set" +msgstr "キャスト関数は集合を返してはいけません" + +#: commands/functioncmds.c:1555 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "WITHOUT FUNCTION指定のキャストを作成するにはスーパユーザである必要があります" + +#: commands/functioncmds.c:1570 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "変換元と変換先のデータ型の間には物理的な互換性がありません" + +#: commands/functioncmds.c:1585 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "複合データ型はバイナリ互換ではありません" + +#: commands/functioncmds.c:1591 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "列挙データ型はバイナリ互換ではありません" + +#: commands/functioncmds.c:1597 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "配列データ型はバイナリ互換ではありません" + +#: commands/functioncmds.c:1614 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "ドメインデータ型はバイナリ互換としてマークされていてはなりません" + +#: commands/functioncmds.c:1624 +#, c-format +msgid "source data type and target data type are the same" +msgstr "変換元と変換先のデータ型が同一です" + +#: commands/functioncmds.c:1656 +#, c-format +msgid "transform function must not be volatile" +msgstr "変換関数はvolatileではいけません" + +#: commands/functioncmds.c:1660 +#, c-format +msgid "transform function must be a normal function" +msgstr "変換関数は通常の関数でなければなりません" + +#: commands/functioncmds.c:1664 +#, c-format +msgid "transform function must not return a set" +msgstr "変換関数は集合を返してはいけません" + +#: commands/functioncmds.c:1668 +#, c-format +msgid "transform function must take one argument" +msgstr "変換関数は引数を1つとらなければなりません" + +#: commands/functioncmds.c:1672 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "変換関数の第1引数は%s型でなければなりません" + +#: commands/functioncmds.c:1710 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "データ型%sは擬似型です" + +#: commands/functioncmds.c:1716 +#, c-format +msgid "data type %s is a domain" +msgstr "データ型%sはドメインです" + +#: commands/functioncmds.c:1756 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "FROM SQL関数の戻り値のデータ型は%sでなければなりません" + +#: commands/functioncmds.c:1782 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "TO SQL関数の戻り値データ型はこの変換関数のデータ型でなければなりません" + +#: commands/functioncmds.c:1811 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "型%s、言語\"%s\"の変換はすでに存在します" + +#: commands/functioncmds.c:1903 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "型%s、言語\"%s\"の変換は存在しません" + +#: commands/functioncmds.c:1927 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "関数%sはすでにスキーマ\"%s\"内に存在します" + +#: commands/functioncmds.c:1982 +#, c-format +msgid "no inline code specified" +msgstr "インラインコードの指定がありません" + +#: commands/functioncmds.c:2028 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "言語\"%s\"ではインラインコード実行をサポートしていません" + +#: commands/functioncmds.c:2140 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "プロシージャには %d 個以上の引数を渡すことはできません" +msgstr[1] "プロシージャには %d 個以上の引数を渡すことはできません" + +#: commands/indexcmds.c:590 +#, c-format +msgid "must specify at least one column" +msgstr "少なくとも1つの列を指定しなければなりません" + +#: commands/indexcmds.c:594 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "インデックスには%dを超える列を使用できません" + +#: commands/indexcmds.c:633 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "外部テーブル\"%s\"のインデックスを作成できません" + +#: commands/indexcmds.c:664 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "パーティションテーブル\"%s\"には CREATE INDEX CONCURRENTLY は実行できません" + +#: commands/indexcmds.c:669 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"には排他制約を作成できません" + +#: commands/indexcmds.c:679 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "他のセッションの一時テーブルに対するインデックスを作成できません" + +#: commands/indexcmds.c:717 commands/tablecmds.c:702 commands/tablespace.c:1173 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "パーティション親リレーションにはデフォルトテーブル空間は指定できません" + +#: commands/indexcmds.c:749 commands/tablecmds.c:737 commands/tablecmds.c:13018 commands/tablecmds.c:13132 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "共有リレーションのみをpg_globalテーブル空間に格納することができます" + +#: commands/indexcmds.c:782 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "古いメソッド\"rtree\"をアクセスメソッド\"gist\"に置換しています" + +#: commands/indexcmds.c:803 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "アクセスメソッド\"%s\"では一意性インデックスをサポートしていません" + +#: commands/indexcmds.c:808 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "アクセスメソッド\"%s\"では包含列をサポートしていません" + +#: commands/indexcmds.c:813 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "アクセスメソッド\"%s\"は複数列インデックスをサポートしません" + +#: commands/indexcmds.c:818 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "アクセスメソッド\"%s\"は排除制約をサポートしていません" + +#: commands/indexcmds.c:941 +#, c-format +msgid "cannot match partition key to an index using access method \"%s\"" +msgstr "パーティションキーはアクセスメソッド\"%s\"を使っているインデックスには適合させられません" + +#: commands/indexcmds.c:951 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "パーティションキー定義では %s 制約はサポートしていません" + +#: commands/indexcmds.c:953 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "%s 制約はパーティションキーが式を含む場合は使用できません" + +#: commands/indexcmds.c:992 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "%s 制約定義内の列が足りません" + +#: commands/indexcmds.c:994 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "テーブル\"%2$s\"上の%1$s制約にパーティションキーの一部である列\"%3$s\"が含まれていません。" + +#: commands/indexcmds.c:1013 commands/indexcmds.c:1032 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "システム列へのインデックス作成はサポートされていません" + +#: commands/indexcmds.c:1057 +#, c-format +msgid "%s %s will create implicit index \"%s\" for table \"%s\"" +msgstr "%1$s %2$sはテーブル\"%4$s\"に暗黙的なインデックス\"%3$s\"を作成します" + +#: commands/indexcmds.c:1198 tcop/utility.c:1461 +#, c-format +msgid "cannot create unique index on partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"にはユニークインデックスを構築できません" + +#: commands/indexcmds.c:1200 tcop/utility.c:1463 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "テーブル\"%s\"は外部テーブルを子テーブルとして含んでいます" + +#: commands/indexcmds.c:1629 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "インデックスの述部の関数はIMMUTABLEマークが必要です" + +#: commands/indexcmds.c:1695 parser/parse_utilcmd.c:2352 parser/parse_utilcmd.c:2487 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "キーとして指名された列\"%s\"は存在しません" + +#: commands/indexcmds.c:1719 parser/parse_utilcmd.c:1670 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "包含列では式はサポートされません" + +#: commands/indexcmds.c:1760 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "式インデックスの関数はIMMUTABLEマークが必要です" + +#: commands/indexcmds.c:1775 +#, c-format +msgid "including column does not support a collation" +msgstr "包含列は照合順序をサポートしません" + +#: commands/indexcmds.c:1779 +#, c-format +msgid "including column does not support an operator class" +msgstr "包含列は演算子クラスをサポートしません" + +#: commands/indexcmds.c:1783 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "包含列は ASC/DESC オプションをサポートしません" + +#: commands/indexcmds.c:1787 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "包含列は NULLS FIRST/LAST オプションをサポートしません" + +#: commands/indexcmds.c:1814 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "インデックス式で使用する照合順序を特定できませんでした" + +#: commands/indexcmds.c:1822 commands/tablecmds.c:15899 commands/typecmds.c:771 parser/parse_expr.c:2850 parser/parse_type.c:566 parser/parse_utilcmd.c:3562 parser/parse_utilcmd.c:4123 utils/adt/misc.c:503 +#, c-format +msgid "collations are not supported by type %s" +msgstr "%s 型では照合順序はサポートされません" + +#: commands/indexcmds.c:1860 +#, c-format +msgid "operator %s is not commutative" +msgstr "演算子 %s は可換ではありません" + +#: commands/indexcmds.c:1862 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "排除制約で使えるのは可換演算子だけです" + +#: commands/indexcmds.c:1888 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "演算子%sは演算子族\"%s\"のメンバーではありません" + +#: commands/indexcmds.c:1891 +#, c-format +msgid "The exclusion operator must be related to the index operator class for the constraint." +msgstr "この排除に使用する演算子はこの制約に使用するインデックス演算子に関連付けられている必要があります。" + +#: commands/indexcmds.c:1926 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "アクセスメソッド\"%s\"はASC/DESCオプションをサポートしません" + +#: commands/indexcmds.c:1931 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "アクセスメソッド\"%s\"はNULLS FIRST/LASTオプションをサポートしません" + +#: commands/indexcmds.c:1977 commands/tablecmds.c:15924 commands/tablecmds.c:15930 commands/typecmds.c:1945 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "アクセスメソッド\"%2$s\"にはデータ型%1$s用のデフォルトの演算子クラスがありません" + +#: commands/indexcmds.c:1979 +#, c-format +msgid "You must specify an operator class for the index or define a default operator class for the data type." +msgstr "このインデックスの演算子クラスを指定するか、あるいはこのデータ型のデフォルト演算子クラスを定義しなければなりません。" + +#: commands/indexcmds.c:2008 commands/indexcmds.c:2016 commands/opclasscmds.c:205 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "アクセスメソッド\"%2$s\"用の演算子クラス\"%1$s\"は存在しません" + +#: commands/indexcmds.c:2030 commands/typecmds.c:1933 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "演算子クラス\"%s\"はデータ型%sを受け付けません" + +#: commands/indexcmds.c:2120 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "データ型%sには複数のデフォルトの演算子クラスがあります" + +#: commands/indexcmds.c:2569 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "テーブル\"%s\"には並行インデックス再作成が可能なインデックスがありません" + +#: commands/indexcmds.c:2580 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "テーブル\"%s\"には再構築すべきインデックスはありません" + +#: commands/indexcmds.c:2619 commands/indexcmds.c:2893 commands/indexcmds.c:2986 +#, c-format +msgid "cannot reindex system catalogs concurrently" +msgstr "システムカタログではインデックスの並行再構築はできません" + +#: commands/indexcmds.c:2642 +#, c-format +msgid "can only reindex the currently open database" +msgstr "現在オープンしているデータベースのみをインデックス再構築することができます" + +#: commands/indexcmds.c:2733 +#, c-format +msgid "cannot reindex system catalogs concurrently, skipping all" +msgstr "システムカタログではインデックスの並行再構築はできません、全てスキップします" + +#: commands/indexcmds.c:2785 commands/indexcmds.c:3466 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "テーブル\"%s.%s\"のインデックス再構築が完了しました" + +#: commands/indexcmds.c:2908 commands/indexcmds.c:2954 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "無効なインデックス \"%s.%s\"の並行再構築はできません、スキップします " + +#: commands/indexcmds.c:2914 +#, c-format +msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "排他制約インデックス\"%s.%s\"を並行再構築することはできません、スキップします " + +#: commands/indexcmds.c:2996 +#, c-format +msgid "cannot reindex invalid index on TOAST table concurrently" +msgstr "TOASTテーブルの無効なインデックスの並行再構築はできません" + +#: commands/indexcmds.c:3024 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "このタイプのリレーションでインデックス並列再構築はできません" + +#: commands/indexcmds.c:3448 commands/indexcmds.c:3459 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr " インデックス\"%s.%s\"の再構築が完了しました " + +#: commands/indexcmds.c:3491 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "パーティションインデックスに対する REINDEX は実装されていません" + +#: commands/lockcmds.c:91 commands/tablecmds.c:5542 commands/trigger.c:295 rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:928 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "\"%s\"はテーブルやビューではありません" + +#: commands/lockcmds.c:213 rewrite/rewriteHandler.c:1977 rewrite/rewriteHandler.c:3782 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "リレーション\"%s\"のルールで無限再帰を検出しました" + +#: commands/matview.c:182 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "実体化ビューにデータが投入されていない場合はCONCURRENTLYを使用することはできません" + +#: commands/matview.c:188 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "CONCURRENTLYとWITH NO DATAオプションを同時に使用することはできません" + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "実体化ビュー\"%s\"を平行的に最新化することはできません" + +#: commands/matview.c:247 +#, c-format +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "実体化ビュー上の1つ以上の列に対してWHERE句を持たないUNIQUEインデックスを作成してください。" + +#: commands/matview.c:641 +#, c-format +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "実体化ビュー\"%s\"に対する新しいデータにはNULL列を持たない重複行があります" + +#: commands/matview.c:643 +#, c-format +msgid "Row: %s" +msgstr "行: %s" + +#: commands/opclasscmds.c:124 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "アクセスメソッド\"%2$s\"用の演算子族\"%1$s\"は存在しません" + +#: commands/opclasscmds.c:266 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "アクセスメソッド\"%2$s\"の演算子族\"%1$s\"はすでに存在します" + +#: commands/opclasscmds.c:411 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "演算子クラスを作成するにはスーパユーザである必要があります" + +#: commands/opclasscmds.c:484 commands/opclasscmds.c:901 commands/opclasscmds.c:1047 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "演算子番号%dが不正です。1から%dまででなければなりません" + +#: commands/opclasscmds.c:529 commands/opclasscmds.c:951 commands/opclasscmds.c:1063 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "演算子番号%dが不正です、1と%dの間でなければなりません" + +#: commands/opclasscmds.c:558 +#, c-format +msgid "storage type specified more than once" +msgstr "格納型が複数指定されました" + +#: commands/opclasscmds.c:585 +#, c-format +msgid "storage type cannot be different from data type for access method \"%s\"" +msgstr "アクセスメソッド\"%s\"用のデータ型と異なる格納型を使用できません" + +#: commands/opclasscmds.c:601 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "アクセスメソッド\"%2$s\"の演算子クラス\"%1$s\"はすでに存在します" + +#: commands/opclasscmds.c:629 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "演算子クラス\"%s\"を型%sのデフォルトにすることができませんでした" + +#: commands/opclasscmds.c:632 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "演算子クラス\"%s\"はすでにデフォルトです。" + +#: commands/opclasscmds.c:792 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "演算子族を作成するにはスーパユーザである必要があります" + +#: commands/opclasscmds.c:852 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "演算子族を更新するにはスーパユーザである必要があります" + +#: commands/opclasscmds.c:910 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "ALTER OPERATOR FAMILYでは演算子の引数型の指定が必要です" + +#: commands/opclasscmds.c:985 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "ALTER OPERATOR FAMILYではSTORAGEを指定できません" + +#: commands/opclasscmds.c:1119 +#, c-format +msgid "one or two argument types must be specified" +msgstr "1または2つの引数型が指定する必要があります" + +#: commands/opclasscmds.c:1145 +#, c-format +msgid "index operators must be binary" +msgstr "インデックス演算子は二項演算子でなければなりません" + +#: commands/opclasscmds.c:1164 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "アクセスメソッド\"%s\"は並べ替え演算子をサポートしていません" + +#: commands/opclasscmds.c:1175 +#, c-format +msgid "index search operators must return boolean" +msgstr "インデックス検索演算子はブール型を返す必要があります" + +#: commands/opclasscmds.c:1215 +#, c-format +msgid "associated data types for opclass options parsing functions must match opclass input type" +msgstr "演算子クラスオプションのパース関数の対応するデータ型は演算子クラスの入力型と一致している必要があります" + +#: commands/opclasscmds.c:1222 +#, c-format +msgid "left and right associated data types for opclass options parsing functions must match" +msgstr "演算子クラスオプションのパース関数の左右の対応するデータ型一致している必要があります" + +#: commands/opclasscmds.c:1230 +#, c-format +msgid "invalid opclass options parsing function" +msgstr "不正な演算子クラスオプションのパース関数" + +#: commands/opclasscmds.c:1231 +#, c-format +msgid "Valid signature of opclass options parsing function is '%s'." +msgstr "演算子クラスオプションのパース関数の正しいシグネチャは '%s' です。" + +#: commands/opclasscmds.c:1250 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "btree比較関数は2つの引数を取る必要があります" + +#: commands/opclasscmds.c:1254 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "btree比較関数は整数を返さなければなりません" + +#: commands/opclasscmds.c:1271 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "btreeソートサポート関数は\"internal\"型を取らなければなりません" + +#: commands/opclasscmds.c:1275 +#, c-format +msgid "btree sort support functions must return void" +msgstr "btreeソートサポート関数はvoidを返さなければなりません" + +#: commands/opclasscmds.c:1286 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "btree in_range 関数は5つの引数を取る必要があります" + +#: commands/opclasscmds.c:1290 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "btree in_range 関数はブール型を返す必要があります" + +#: commands/opclasscmds.c:1306 +#, c-format +msgid "btree equal image functions must have one argument" +msgstr "btreeの equal image 関数は1つの引数を取る必要があります" + +#: commands/opclasscmds.c:1310 +#, c-format +msgid "btree equal image functions must return boolean" +msgstr "btreeの euqal image 関数はブール型を返す必要があります" + +#: commands/opclasscmds.c:1323 +#, c-format +msgid "btree equal image functions must not be cross-type" +msgstr "btreeの equal image 関数は同じ型の引数を取る必要があります" + +#: commands/opclasscmds.c:1333 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "ハッシュ関数1は引数を1つ取る必要があります" + +#: commands/opclasscmds.c:1337 +#, c-format +msgid "hash function 1 must return integer" +msgstr "ハッシュ関数1は整数を返す必要があります" + +#: commands/opclasscmds.c:1344 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "ハッシュ関数2は2つの引数を取る必要があります" + +#: commands/opclasscmds.c:1348 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "ハッシュ関数2は bigint を返す必要があります" + +#: commands/opclasscmds.c:1373 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "インデックスサポート関数に対して関連データ型を指定する必要があります" + +#: commands/opclasscmds.c:1398 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "(%2$s,%3$s)に対応する演算子番号%1$dが複数あります" + +#: commands/opclasscmds.c:1405 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "(%2$s,%3$s)用の演算子番号%1$dが複数あります" + +#: commands/opclasscmds.c:1451 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "演算子%d(%s,%s)はすでに演算子族\"%s\"に存在します" + +#: commands/opclasscmds.c:1557 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "関数%d(%s,%s)はすでに演算子族\"%s\"内に存在します" + +#: commands/opclasscmds.c:1638 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "演算子%d(%s,%s)は演算子族\"%s\"内にありません" + +#: commands/opclasscmds.c:1678 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "関数%d(%s,%s)は演算子族\"%s\"内に存在しません" + +#: commands/opclasscmds.c:1709 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "アクセスメソッド\"%2$s\"用の演算子クラス\"%1$s\"はスキーマ\"%3$s\"内にすでに存在します" + +#: commands/opclasscmds.c:1732 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "アクセスメソッド\"%2$s\"用の演算子族\"%1$s\"はスキーマ\"%3$s\"内にすでに存在します" + +#: commands/operatorcmds.c:111 commands/operatorcmds.c:119 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "演算子の引数にはSETOF型を使用できません" + +#: commands/operatorcmds.c:152 commands/operatorcmds.c:467 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "演算子の属性\"%s\"は不明です" + +#: commands/operatorcmds.c:163 +#, c-format +msgid "operator function must be specified" +msgstr "演算子関数を指定する必要があります" + +#: commands/operatorcmds.c:174 +#, c-format +msgid "at least one of leftarg or rightarg must be specified" +msgstr "左右辺のうち少なくともどちらか一方を指定する必要があります" + +#: commands/operatorcmds.c:278 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "制約推定関数 %s は %s型を返す必要があります" + +#: commands/operatorcmds.c:321 +#, c-format +msgid "join estimator function %s has multiple matches" +msgstr "JOIN推定関数 %s が複数合致しました" + +#: commands/operatorcmds.c:336 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "JOIN推定関数 %s は %s型を返す必要があります" + +#: commands/operatorcmds.c:461 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "演算子の属性\"%s\"は変更できません" + +#: commands/policy.c:88 commands/policy.c:401 commands/policy.c:491 commands/tablecmds.c:1499 commands/tablecmds.c:1981 commands/tablecmds.c:3021 commands/tablecmds.c:5521 commands/tablecmds.c:8252 commands/tablecmds.c:15489 commands/tablecmds.c:15524 commands/trigger.c:301 commands/trigger.c:1206 commands/trigger.c:1315 rewrite/rewriteDefine.c:277 rewrite/rewriteDefine.c:933 rewrite/rewriteRemove.c:80 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "権限がありません: \"%s\"はシステムカタログです" + +#: commands/policy.c:171 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "PUBLIC以外の指定されたロールを無視します" + +#: commands/policy.c:172 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "全てのロールがPUBLICロールのメンバーです。" + +#: commands/policy.c:515 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "ロール\"%s\"は\"%s\"に対するポリシ\"%s\"からは削除できませんでした" + +#: commands/policy.c:724 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "SELECTまたはDELETEには WITH CHECK を適用できません" + +#: commands/policy.c:733 commands/policy.c:1038 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "INSERTではWITH CHECK式のみが指定可能です" + +#: commands/policy.c:808 commands/policy.c:1261 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "テーブル\"%2$s\"に対するポリシ\"%1$s\"はすでに存在します" + +#: commands/policy.c:1010 commands/policy.c:1289 commands/policy.c:1360 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "テーブル\"%2$s\"に対するポリシ\"%1$s\"は存在しません" + +#: commands/policy.c:1028 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "SELECT、DELETEにはUSING式のみが指定可能です" + +#: commands/portalcmds.c:59 commands/portalcmds.c:182 commands/portalcmds.c:233 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "カーソル名が不正です: 空ではいけません" + +#: commands/portalcmds.c:190 commands/portalcmds.c:243 executor/execCurrent.c:70 utils/adt/xml.c:2594 utils/adt/xml.c:2764 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "カーソル\"%s\"は存在しません" + +#: commands/prepare.c:76 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "不正な文の名前: 空ではいけません" + +#: commands/prepare.c:134 parser/parse_param.c:304 tcop/postgres.c:1498 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "パラメータ$%dのデータ型が特定できませんでした" + +#: commands/prepare.c:152 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "ユーティリティ文は準備できません" + +#: commands/prepare.c:256 commands/prepare.c:261 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "準備された文はSELECTではありません" + +#: commands/prepare.c:328 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "準備された文\"%s\"のパラメータ数が間違っています" + +#: commands/prepare.c:330 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "%dパラメータを想定しましたが、%dパラメータでした" + +#: commands/prepare.c:363 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "パラメータ$%dの型%sを想定している型%sに強制することができません" + +#: commands/prepare.c:449 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "準備された文\"%s\"はすでに存在します" + +#: commands/prepare.c:488 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "準備された文\"%s\"は存在しません" + +#: commands/proclang.c:67 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "手続き言語を生成するためにはスーパユーザである必要があります" + +#: commands/publicationcmds.c:107 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "\"publish\"オプションのリスト構文が不正です" + +#: commands/publicationcmds.c:125 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "識別できない\"publish\"の値: \"%s\"" + +#: commands/publicationcmds.c:140 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "識別できないパブリケーションのパラメータ: \"%s\"" + +#: commands/publicationcmds.c:172 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "FOR ALL TABLE 指定のパブリケーションを生成するためにはスーパユーザである必要があります" + +#: commands/publicationcmds.c:248 +#, c-format +msgid "wal_level is insufficient to publish logical changes" +msgstr "wal_level が論理更新情報のパブリッシュには不十分です" + +#: commands/publicationcmds.c:249 +#, c-format +msgid "Set wal_level to logical before creating subscriptions." +msgstr "wal_levelをlogicalに設定にしてからサブスクリプションを作成してください。" + +#: commands/publicationcmds.c:369 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "パブリケーション\"%s\"は FOR ALL TABLES と定義されています" + +#: commands/publicationcmds.c:371 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "FOR ALL TABLES指定のパブリケーションではテーブルの追加や削除はできません。" + +#: commands/publicationcmds.c:660 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "リレーション\"%s\"はパブリケーションの一部ではありません" + +#: commands/publicationcmds.c:703 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "パブリケーション\"%s\"の所有者を変更する権限がありません" + +#: commands/publicationcmds.c:705 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "FOR ALL TABLES設定のパブリケーションの所有者はスーパユーザである必要があります" + +#: commands/schemacmds.c:105 commands/schemacmds.c:258 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "スキーマ名\"%s\"は受け付けられません" + +#: commands/schemacmds.c:106 commands/schemacmds.c:259 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "接頭辞\"pg_\"はシステムスキーマ用に予約されています" + +#: commands/schemacmds.c:120 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "スキーマ\"%s\"はすでに存在します、スキップします" + +#: commands/seclabel.c:129 +#, c-format +msgid "no security label providers have been loaded" +msgstr "セキュリティラベルのプロバイダがロードされませんでした" + +#: commands/seclabel.c:133 +#, c-format +msgid "must specify provider when multiple security label providers have been loaded" +msgstr "複数のセキュリティラベルプロバイダがロードされた時は、プロバイダを指定する必要があります" + +#: commands/seclabel.c:151 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "セキュリティラベルプロバイダ\"%s\"はロードされていません" + +#: commands/seclabel.c:158 +#, c-format +msgid "security labels are not supported for this type of object" +msgstr "このプラットフォームではこの型のオブジェクトに対するセキュリティラベルはサポートしていません" + +#: commands/sequence.c:140 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "UNLOGGEDシーケンスはサポートされません" + +# (%s) +#: commands/sequence.c:709 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "nextval: シーケンス\"%s\"の最大値(%s)に達しました" + +#: commands/sequence.c:732 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "nextval: シーケンス\"%s\"の最小値(%s)に達しました" + +#: commands/sequence.c:850 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "本セッションでシーケンス\"%s\"のcurrvalはまだ定義されていません" + +#: commands/sequence.c:869 commands/sequence.c:875 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "本セッションでlastvalはまだ定義されていません" + +#: commands/sequence.c:963 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "setval: 値%sはシーケンス\"%s\"の範囲(%s..%s)外です\"" + +#: commands/sequence.c:1360 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "不正なオプション SEQUENCE NAME" + +#: commands/sequence.c:1386 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "識別列の型はsmallint、integerまたはbigintでなくてはなりません" + +#: commands/sequence.c:1387 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "シーケンスの型はsmallint、integerまたはbigintでなくてはなりません" + +#: commands/sequence.c:1421 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "INCREMENTはゼロではいけません" + +#: commands/sequence.c:1474 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) はシーケンスデータ型%sの範囲外です" + +#: commands/sequence.c:1511 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s) はシーケンスデータ型%sの範囲外です" + +#: commands/sequence.c:1525 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "MINVALUE (%s)はMAXVALUE (%s)より小さくなければなりません" + +#: commands/sequence.c:1552 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "STARTの値(%s)はMINVALUE(%s)より小さくすることはできません" + +#: commands/sequence.c:1564 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "STARTの値(%s)はMAXVALUE(%s)より大きくすることはできません" + +#: commands/sequence.c:1594 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "RESTART の値(%s)は MINVALUE(%s) より小さくすることはできません" + +#: commands/sequence.c:1606 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "RESTART の値(%s)は MAXVALUE(%s) より大きくすることはできません" + +#: commands/sequence.c:1621 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "CACHE(%s)はゼロより大きくなければなりません" + +#: commands/sequence.c:1658 +#, c-format +msgid "invalid OWNED BY option" +msgstr "不正なOWNED BYオプションです" + +#: commands/sequence.c:1659 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "OWNED BY table.column または OWNED BY NONEを指定してください。" + +#: commands/sequence.c:1684 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr "参照先のリレーション\"%s\"はテーブルまたは外部テーブルではありません" + +#: commands/sequence.c:1691 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "シーケンスは関連するテーブルと同じ所有者でなければなりません" + +#: commands/sequence.c:1695 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "シーケンスは関連するテーブルと同じスキーマでなければなりません" + +#: commands/sequence.c:1717 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "識別シーケンスの所有者は変更できません" + +#: commands/sequence.c:1718 commands/tablecmds.c:12401 commands/tablecmds.c:14914 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "シーケンス\"%s\"はテーブル\"%s\"にリンクされています" + +#: commands/statscmds.c:104 commands/statscmds.c:113 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICSで指定可能なリレーションは一つのみです" + +#: commands/statscmds.c:131 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "リレーション\"%s\"はテーブルや外部テーブル、または実体化ビューではありません" + +#: commands/statscmds.c:174 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "統計情報オブジェクト\"%s\"はすでに存在します、スキップします" + +#: commands/statscmds.c:182 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "統計情報オブジェクト\"%s\"はすでに存在します" + +#: commands/statscmds.c:204 commands/statscmds.c:210 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICSでは単純な列参照のみが指定可能です" + +#: commands/statscmds.c:225 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "システム列に対する統計情報の作成はサポートされていません" + +#: commands/statscmds.c:232 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "列\"%s\"の型%sはデフォルトのbtreeオペレータクラスを持たないため統計情報では利用できません" + +#: commands/statscmds.c:239 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "統計情報は%dを超える列を使用できません" + +#: commands/statscmds.c:254 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "拡張統計情報には最低でも2つの列が必要です" + +#: commands/statscmds.c:272 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "定形情報定義中の列名が重複しています" + +#: commands/statscmds.c:306 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "認識できない統計情報種別\"%s\"" + +#: commands/statscmds.c:444 commands/tablecmds.c:7273 +#, c-format +msgid "statistics target %d is too low" +msgstr "統計情報目標%dは小さすぎます" + +#: commands/statscmds.c:452 commands/tablecmds.c:7281 +#, c-format +msgid "lowering statistics target to %d" +msgstr "統計情報目標を%dに減らします" + +#: commands/statscmds.c:475 +#, c-format +msgid "statistics object \"%s.%s\" does not exist, skipping" +msgstr "統計情報オブジェクト\"%s.%s\"は存在しません、スキップします" + +#: commands/subscriptioncmds.c:200 +#, c-format +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "認識できないサブスクリプションパラメータ: \"%s\"" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:214 commands/subscriptioncmds.c:220 commands/subscriptioncmds.c:226 commands/subscriptioncmds.c:245 commands/subscriptioncmds.c:251 +#, c-format +msgid "%s and %s are mutually exclusive options" +msgstr "%s と %s は排他なオプションです" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:258 commands/subscriptioncmds.c:264 +#, c-format +msgid "subscription with %s must also set %s" +msgstr "%s としたサブスクリプションでは %s を設定する必要があります" + +#: commands/subscriptioncmds.c:306 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "パブリケーション名\"%s\"が2回以上使われています" + +#: commands/subscriptioncmds.c:377 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "サブスクリプションを生成するにはスーパユーザである必要があります" + +#: commands/subscriptioncmds.c:469 commands/subscriptioncmds.c:557 replication/logical/tablesync.c:857 replication/logical/worker.c:2129 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "発行サーバへの接続ができませんでした: %s" + +#: commands/subscriptioncmds.c:511 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "発行サーバでレプリケーションスロット\"%s\"を作成しました" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:524 +#, c-format +msgid "tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "テーブルは購読されていません、テーブルを購読するためには %s を実行する必要があります" + +#: commands/subscriptioncmds.c:613 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "テーブル\"%s.%s\"がサブスクリプション\"%s\"に追加されました" + +#: commands/subscriptioncmds.c:637 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "テーブル\"%s.%s\"がサブスクリプション\"%s\"から削除されました" + +#: commands/subscriptioncmds.c:717 +#, c-format +msgid "cannot set %s for enabled subscription" +msgstr "有効にされているサブスクリプションには %s を指定できません" + +#: commands/subscriptioncmds.c:765 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "スロット名を指定されていないサブスクリプションを有効にはできません" + +#: commands/subscriptioncmds.c:817 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "refresh指定された ALTER SUBSCRIPTION は無効化されているサブスクリプションには実行できません" + +#: commands/subscriptioncmds.c:818 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false) を使ってください。" + +#: commands/subscriptioncmds.c:836 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESHは無効化されているサブスクリプションには実行できません" + +#: commands/subscriptioncmds.c:922 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "サブスクリプション\"%s\"は存在しません、スキップします" + +#: commands/subscriptioncmds.c:1047 +#, c-format +msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgstr "レプリケーションスロット\"%s\"を削除するための発行者サーバへの接続に失敗しました" + +#: commands/subscriptioncmds.c:1049 commands/subscriptioncmds.c:1064 replication/logical/tablesync.c:906 replication/logical/tablesync.c:928 +#, c-format +msgid "The error was: %s" +msgstr "発生したエラー: %s" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:1051 +#, c-format +msgid "Use %s to disassociate the subscription from the slot." +msgstr "サブスクリプションのスロットへの関連付けを解除するには %s を実行してください。" + +#: commands/subscriptioncmds.c:1062 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "発行サーバ上のレプリケーションスロット\"%s\"の削除に失敗しました" + +#: commands/subscriptioncmds.c:1067 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "発行サーバ上のレプリケーションスロット\"%s\"を削除しました" + +#: commands/subscriptioncmds.c:1104 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "サブスクリプション\"%s\"の所有者を変更する権限がありません" + +#: commands/subscriptioncmds.c:1106 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "サブスクリプションの所有者はスーパユーザでなければなりません。" + +#: commands/subscriptioncmds.c:1221 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "発行テーブルの一覧を発行サーバから受け取れませんでした: %s" + +#: commands/tablecmds.c:228 commands/tablecmds.c:270 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "テーブル\"%s\"は存在しません" + +#: commands/tablecmds.c:229 commands/tablecmds.c:271 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "テーブル\"%s\"は存在しません、スキップします" + +#: commands/tablecmds.c:231 commands/tablecmds.c:273 +msgid "Use DROP TABLE to remove a table." +msgstr "テーブルを削除するにはDROP TABLEを使用してください。" + +#: commands/tablecmds.c:234 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "シーケンス\"%s\"は存在しません" + +#: commands/tablecmds.c:235 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "シーケンス\"%s\"は存在しません、スキップします" + +#: commands/tablecmds.c:237 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "シーケンスを削除するにはDROP SEQUENCEを使用してください。" + +#: commands/tablecmds.c:240 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "ビュー\"%s\"は存在しません" + +#: commands/tablecmds.c:241 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "ビュー\"%s\"は存在しません、スキップします" + +#: commands/tablecmds.c:243 +msgid "Use DROP VIEW to remove a view." +msgstr "ビューを削除するにはDROP VIEWを使用してください。" + +#: commands/tablecmds.c:246 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr "実体化ビュー\"%s\"は存在しません" + +#: commands/tablecmds.c:247 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr "実体化ビュー\"%s\"は存在しません、スキップします" + +#: commands/tablecmds.c:249 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "実体化ビューを削除するにはDROP MATERIALIZED VIEWを使用してください。" + +#: commands/tablecmds.c:252 commands/tablecmds.c:276 commands/tablecmds.c:17088 parser/parse_utilcmd.c:2084 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "インデックス\"%s\"は存在しません" + +#: commands/tablecmds.c:253 commands/tablecmds.c:277 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "インデックス\"%s\"は存在しません、スキップします" + +#: commands/tablecmds.c:255 commands/tablecmds.c:279 +msgid "Use DROP INDEX to remove an index." +msgstr "インデックスを削除するにはDROP INDEXを使用してください" + +#: commands/tablecmds.c:260 +#, c-format +msgid "\"%s\" is not a type" +msgstr "\"%s\"は型ではありません" + +#: commands/tablecmds.c:261 +msgid "Use DROP TYPE to remove a type." +msgstr "型を削除するにはDROP TYPEを使用してください" + +#: commands/tablecmds.c:264 commands/tablecmds.c:12240 commands/tablecmds.c:14694 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "外部テーブル\"%s\"は存在しません" + +#: commands/tablecmds.c:265 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "外部テーブル\"%s\"は存在しません、スキップします" + +#: commands/tablecmds.c:267 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "外部テーブルを削除するには DROP FOREIGN TABLE を使用してください。" + +#: commands/tablecmds.c:618 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMITは一時テーブルでのみ使用できます" + +#: commands/tablecmds.c:649 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "セキュリティー制限操作中は、一時テーブルを作成できません" + +#: commands/tablecmds.c:685 commands/tablecmds.c:13598 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "リレーション\"%s\"が複数回継承されました" + +#: commands/tablecmds.c:866 +#, c-format +msgid "specifying a table access method is not supported on a partitioned table" +msgstr "パーティション親テーブルではテーブルアクセスメソッドの指定はサポートされていません" + +#: commands/tablecmds.c:962 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "\"%s\"はパーティションされていません" + +#: commands/tablecmds.c:1056 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "%d以上の列を使ったパーティションはできません" + +#: commands/tablecmds.c:1112 +#, c-format +msgid "cannot create foreign partition of partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"では外部子テーブルを作成できません" + +#: commands/tablecmds.c:1114 +#, c-format +msgid "Table \"%s\" contains indexes that are unique." +msgstr "テーブル\"%s\"はユニークインデックスを持っています" + +#: commands/tablecmds.c:1277 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLYは複数オブジェクトの削除をサポートしていません" + +#: commands/tablecmds.c:1281 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLYはCASCADEをサポートしません" + +#: commands/tablecmds.c:1641 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "パーティションの親テーブルのみの切り詰めはできません" + +#: commands/tablecmds.c:1642 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "ONLY キーワードを指定しないでください、もしくは子テーブルに対して直接 TRUNCATE ONLY を実行してください。" + +#: commands/tablecmds.c:1711 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "テーブル\"%s\"へのカスケードを削除します" + +#: commands/tablecmds.c:2018 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "他のセッションの一時テーブルを削除できません" + +#: commands/tablecmds.c:2242 commands/tablecmds.c:13495 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"からの継承はできません" + +#: commands/tablecmds.c:2247 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "パーティション子テーブル\"%s\"からの継承はできません" + +#: commands/tablecmds.c:2255 parser/parse_utilcmd.c:2314 parser/parse_utilcmd.c:2456 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "継承しようとしたリレーション\"%s\"はテーブルまたは外部テーブルではありません" + +#: commands/tablecmds.c:2267 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "一時リレーションを永続リレーション\"%s\"の子テーブルとして作ることはできません" + +#: commands/tablecmds.c:2276 commands/tablecmds.c:13474 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "一時リレーション\"%s\"から継承することはできません" + +#: commands/tablecmds.c:2286 commands/tablecmds.c:13482 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "他のセッションの一時リレーションから継承することはできません" + +#: commands/tablecmds.c:2337 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "複数の継承される列\"%s\"の定義をマージしています" + +#: commands/tablecmds.c:2345 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "継承される列\"%s\"の型が競合しています" + +#: commands/tablecmds.c:2347 commands/tablecmds.c:2370 commands/tablecmds.c:2583 commands/tablecmds.c:2613 parser/parse_coerce.c:1935 parser/parse_coerce.c:1955 parser/parse_coerce.c:1975 parser/parse_coerce.c:2030 parser/parse_coerce.c:2107 parser/parse_coerce.c:2141 parser/parse_param.c:218 +#, c-format +msgid "%s versus %s" +msgstr "%s対%s" + +#: commands/tablecmds.c:2356 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "継承される列 \"%s\"の照合順序が競合しています" + +#: commands/tablecmds.c:2358 commands/tablecmds.c:2595 commands/tablecmds.c:6025 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "\"%s\"対\"%s\"" + +#: commands/tablecmds.c:2368 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "継承される列 \"%s\"の格納パラメーターが競合しています" + +#: commands/tablecmds.c:2384 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "継承された列 \"%s\"の生成が競合しています" + +#: commands/tablecmds.c:2489 commands/tablecmds.c:11045 parser/parse_utilcmd.c:1094 parser/parse_utilcmd.c:1181 parser/parse_utilcmd.c:1597 parser/parse_utilcmd.c:1706 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "行全体テーブル参照を変換できません" + +#: commands/tablecmds.c:2490 parser/parse_utilcmd.c:1182 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "制約\"%s\"はテーブル\"%s\"への行全体参照を含みます。" + +#: commands/tablecmds.c:2569 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "継承される定義で列\"%s\"をマージしています" + +#: commands/tablecmds.c:2573 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "継承される定義で列\"%s\"を移動してマージします" + +#: commands/tablecmds.c:2574 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "ユーザが指定した列が継承した列の位置に移動されました。" + +#: commands/tablecmds.c:2581 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "列\"%s\"の型が競合しています" + +#: commands/tablecmds.c:2593 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "列\"%s\"の照合順序が競合しています" + +#: commands/tablecmds.c:2611 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "列\"%s\"の格納パラメーターが競合しています" + +#: commands/tablecmds.c:2639 +#, c-format +msgid "child column \"%s\" specifies generation expression" +msgstr "子テーブルの列\"%s\"は生成式を指定しています" + +#: commands/tablecmds.c:2641 +#, c-format +msgid "Omit the generation expression in the definition of the child table column to inherit the generation expression from the parent table." +msgstr "親テーブルの生成式を継承するために、子テーブルのカラムの生成式定義を無視しました" + +#: commands/tablecmds.c:2645 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies default" +msgstr "列\"%s\"は生成列を継承しますが、default 指定がされています" + +#: commands/tablecmds.c:2650 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies identity" +msgstr "列\"%s\"は生成列を継承しますが、識別列と指定されています" + +#: commands/tablecmds.c:2760 +#, c-format +msgid "column \"%s\" inherits conflicting generation expressions" +msgstr "列\"%s\"は競合する生成式を継承します" + +#: commands/tablecmds.c:2765 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "列\"%s\"は競合するデフォルト値を継承します" + +#: commands/tablecmds.c:2767 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "競合を解消するには明示的にデフォルトを指定してください" + +#: commands/tablecmds.c:2813 +#, c-format +msgid "check constraint name \"%s\" appears multiple times but with different expressions" +msgstr "異なる式を持つ検査制約名\"%s\"が複数あります。" + +#: commands/tablecmds.c:2990 +#, c-format +msgid "cannot rename column of typed table" +msgstr "型付けされたテーブルの列をリネームできません" + +#: commands/tablecmds.c:3009 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" +msgstr "\"%s\" はテーブル、ビュー、実体化ビュー、複合型、インデックス、外部テーブルのいずれでもありません" + +#: commands/tablecmds.c:3103 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "継承される列\"%s\"の名前を子テーブルでも変更する必要があります" + +#: commands/tablecmds.c:3135 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "システム列%s\"の名前を変更できません" + +#: commands/tablecmds.c:3150 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "継承される列\"%s\"の名前を変更できません" + +#: commands/tablecmds.c:3302 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "継承される制約\"%s\"の名前を子テーブルでも変更する必要があります" + +#: commands/tablecmds.c:3309 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "継承される制約\"%s\"の名前を変更できません" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3542 +#, c-format +msgid "cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "このセッションで実行中の問い合わせで使用されているため\"%2$s\"を%1$sできません" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3551 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "保留中のトリガイベントがあるため\"%2$s\"を%1$sできません" + +#: commands/tablecmds.c:4174 commands/tablecmds.c:4189 +#, c-format +msgid "cannot change persistence setting twice" +msgstr "永続性設定の変更は2度はできません" + +#: commands/tablecmds.c:4882 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "システムリレーション\"%sを書き換えられません" + +#: commands/tablecmds.c:4888 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "カタログテーブルとして使用されているテーブル\"%s\"は書き換えられません" + +#: commands/tablecmds.c:4898 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "他のセッションの一時テーブルを書き換えられません" + +#: commands/tablecmds.c:5187 +#, c-format +msgid "rewriting table \"%s\"" +msgstr "テーブル\"%s\"に再書込しています" + +#: commands/tablecmds.c:5191 +#, c-format +msgid "verifying table \"%s\"" +msgstr "テーブル\"%s\"を検証しています" + +#: commands/tablecmds.c:5356 +#, c-format +msgid "column \"%s\" of relation \"%s\" contains null values" +msgstr "リレーション\"%2$s\"の列\"%1$s\"にNULL値があります" + +#: commands/tablecmds.c:5373 +#, c-format +msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" +msgstr "一部の行がリレーション\"%2$s\"の検査制約\"%1$s\"に違反してます" + +#: commands/tablecmds.c:5392 partitioning/partbounds.c:3237 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "デフォルトパーティション\"%s\"の一部の行が更新後のパーティション制約に違反しています" + +#: commands/tablecmds.c:5398 +#, c-format +msgid "partition constraint of relation \"%s\" is violated by some row" +msgstr "一部の行がリレーション\"%s\"のパーティション制約に違反しています" + +#: commands/tablecmds.c:5545 commands/trigger.c:1200 commands/trigger.c:1306 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "\"%s\"はテーブルやビュー、または外部テーブルではありません" + +#: commands/tablecmds.c:5548 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "\"%s\"はテーブル、ビュー、実体化ビュー、インデックスではありません" + +#: commands/tablecmds.c:5554 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "\"%s\"はテーブルや実体化ビュー、インデックスではありません" + +#: commands/tablecmds.c:5557 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "\"%s\"はテーブルや実体化ビュー、または外部テーブルではありません" + +#: commands/tablecmds.c:5560 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "\"%s\"はテーブルや外部テーブルではありません" + +#: commands/tablecmds.c:5563 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "\"%s\"はテーブル、複合型、外部テーブルのいずれでもありません" + +#: commands/tablecmds.c:5566 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "\"%s\"はテーブルやインデックス、実体化ビュー、インデックス、外部テーブルではありません" + +#: commands/tablecmds.c:5576 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "\"%s\"は誤った型です" + +#: commands/tablecmds.c:5783 commands/tablecmds.c:5790 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "型\"%s\"を変更できません。列\"%s\".\"%s\"でその型を使用しているためです" + +#: commands/tablecmds.c:5797 +#, c-format +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "列%2$s\".\"%3$s\"がその行型を使用しているため、外部テーブル\"%1$s\"を変更できません。" + +#: commands/tablecmds.c:5804 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "テーブル\"%s\"を変更できません。その行型を列\"%s\".\"%s\"で使用しているためです" + +#: commands/tablecmds.c:5860 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "型付けされたテーブルの型であるため、外部テーブル\"%s\"を変更できません。" + +#: commands/tablecmds.c:5862 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "型付けされたテーブルを変更する場合も ALTER .. CASCADE を使用してください" + +#: commands/tablecmds.c:5908 +#, c-format +msgid "type %s is not a composite type" +msgstr "型 %s は複合型ではありません" + +#: commands/tablecmds.c:5935 +#, c-format +msgid "cannot add column to typed table" +msgstr "型付けされたテーブルに列を追加できません" + +#: commands/tablecmds.c:5988 +#, c-format +msgid "cannot add column to a partition" +msgstr "パーティションに列は追加できません" + +#: commands/tablecmds.c:6017 commands/tablecmds.c:13725 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "子テーブル\"%s\"に異なる型の列\"%s\"があります" + +#: commands/tablecmds.c:6023 commands/tablecmds.c:13732 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "子テーブル\"%s\"に異なる照合順序の列\"%s\"があります" + +#: commands/tablecmds.c:6037 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "子\"%2$s\"の列\"%1$s\"の定義をマージしています" + +#: commands/tablecmds.c:6080 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "子テーブルを持つテーブルに識別列を再帰的に追加することはできません" + +#: commands/tablecmds.c:6319 +#, c-format +msgid "column must be added to child tables too" +msgstr "列は子テーブルでも追加する必要があります" + +#: commands/tablecmds.c:6397 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでに存在します、スキップします" + +#: commands/tablecmds.c:6404 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでに存在します" + +#: commands/tablecmds.c:6470 commands/tablecmds.c:10683 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "パーティションが存在する場合にはパーティションテーブルのみから制約を削除することはできません" + +#: commands/tablecmds.c:6471 commands/tablecmds.c:6740 commands/tablecmds.c:7691 commands/tablecmds.c:10684 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "ONLYキーワードを指定しないでください。" + +#: commands/tablecmds.c:6508 commands/tablecmds.c:6666 commands/tablecmds.c:6808 commands/tablecmds.c:6893 commands/tablecmds.c:6987 commands/tablecmds.c:7046 commands/tablecmds.c:7148 commands/tablecmds.c:7314 commands/tablecmds.c:7384 commands/tablecmds.c:7477 commands/tablecmds.c:10838 commands/tablecmds.c:12263 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "システム列\"%s\"を変更できません" + +#: commands/tablecmds.c:6514 commands/tablecmds.c:6814 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は識別列です" + +#: commands/tablecmds.c:6550 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "列\"%s\"はプライマリキーで使用しています" + +#: commands/tablecmds.c:6572 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "列\"%s\"は親テーブルでNOT NULL指定されています" + +#: commands/tablecmds.c:6737 commands/tablecmds.c:8150 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "制約は子テーブルにも追加する必要があります" + +#: commands/tablecmds.c:6738 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでにNOT NULLLではありません。" + +#: commands/tablecmds.c:6773 +#, c-format +msgid "existing constraints on column \"%s\".\"%s\" are sufficient to prove that it does not contain nulls" +msgstr "カラム\"%s\".\"%s\"上の既存の制約はNULLを含まないことを照明するのに十分です" + +#: commands/tablecmds.c:6816 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "代わりに ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY を使ってください。" + +#: commands/tablecmds.c:6821 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は生成カラムです" + +#: commands/tablecmds.c:6824 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." +msgstr "代わりに ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION を使ってください。" + +#: commands/tablecmds.c:6904 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "識別列を追加するにはリレーション\"%s\"の列\"%s\"はNOT NULLと宣言されている必要があります" + +#: commands/tablecmds.c:6910 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでに識別列です" + +#: commands/tablecmds.c:6916 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "リレーション\"%2$s\"の列\"%1$s\"はすでにデフォルト値が指定されています" + +#: commands/tablecmds.c:6993 commands/tablecmds.c:7054 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は識別列ではありません" + +#: commands/tablecmds.c:7059 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は識別列ではありません、スキップします" + +#: commands/tablecmds.c:7118 +#, c-format +msgid "cannot drop generation expression from inherited column" +msgstr "継承列から生成式を削除することはできません" + +#: commands/tablecmds.c:7156 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は格納生成列ではありません" + +#: commands/tablecmds.c:7161 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column, skipping" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は格納生成列ではありません、スキップします" + +#: commands/tablecmds.c:7261 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "非インデックス列を番号で参照することはできません" + +#: commands/tablecmds.c:7304 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "リレーション \"%2$s\"の列 %1$d は存在しません" + +#: commands/tablecmds.c:7323 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "インデックス\"%2$s\"の包含列\"%1$s\"への統計情報の変更はできません" + +#: commands/tablecmds.c:7328 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "インデックス \"%2$s\"の非式列\"%1$s\"の統計情報の変更はできません" + +#: commands/tablecmds.c:7330 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "代わりにテーブルカラムの統計情報を変更してください。" + +#: commands/tablecmds.c:7457 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "不正な格納タイプ\"%s\"" + +#: commands/tablecmds.c:7489 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "列のデータ型%sは格納タイプPLAINしか取ることができません" + +#: commands/tablecmds.c:7571 +#, c-format +msgid "cannot drop column from typed table" +msgstr "型付けされたテーブルから列を削除できません" + +#: commands/tablecmds.c:7630 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%2$s\"の列\"%1$s\"は存在しません、スキップします" + +#: commands/tablecmds.c:7643 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "システム列\"%s\"を削除できません" + +#: commands/tablecmds.c:7653 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "継承される列\"%s\"を削除できません" + +#: commands/tablecmds.c:7666 +#, c-format +msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "列\"%s\"はリレーション\"%s\"のパーティションキーの一部であるため、削除できません" + +#: commands/tablecmds.c:7690 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "子テーブルが存在する場合にはパーティションの親テーブルのみから列を削除することはできません" + +#: commands/tablecmds.c:7871 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX はパーティションテーブルではサポートされていません" + +#: commands/tablecmds.c:7896 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX はインデックス\"%s\"を\"%s\"にリネームします" + +#: commands/tablecmds.c:8230 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "パーティションテーブル\"%s\"で定義されているリレーション\"%s\"を参照する外部キーではONLY指定はできません" + +#: commands/tablecmds.c:8236 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "パーティションテーブル\"%1$s\"にリレーション\"%2$s\"を参照する NOT VALID 指定の外部キーは追加できません " + +#: commands/tablecmds.c:8239 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "この機能はパーティションテーブルに対してはサポートされていません。" + +#: commands/tablecmds.c:8246 commands/tablecmds.c:8651 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "参照先のリレーション\"%s\"はテーブルではありません" + +#: commands/tablecmds.c:8269 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "永続テーブルの制約は永続テーブルだけを参照できます" + +#: commands/tablecmds.c:8276 +#, c-format +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" +msgstr "UNLOGGEDテーブルに対する制約は、永続テーブルまたはUNLOGGEDテーブルだけを参照する場合があります" + +#: commands/tablecmds.c:8282 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "一時テーブルに対する制約は一時テーブルだけを参照する場合があります" + +#: commands/tablecmds.c:8286 +#, c-format +msgid "constraints on temporary tables must involve temporary tables of this session" +msgstr "一時テーブルに対する制約にはこのセッションの一時テーブルを加える必要があります" + +#: commands/tablecmds.c:8352 commands/tablecmds.c:8358 +#, c-format +msgid "invalid %s action for foreign key constraint containing generated column" +msgstr "生成カラムを含む外部キー制約に対する不正な %s 処理" + +#: commands/tablecmds.c:8374 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "外部キーの参照列数と非参照列数が合いません" + +#: commands/tablecmds.c:8481 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "外部キー制約\"%sは実装されていません" + +#: commands/tablecmds.c:8483 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "キーとなる列\"%s\"と\"%s\"との間で型に互換性がありません:%sと%s" + +#: commands/tablecmds.c:8846 commands/tablecmds.c:9239 parser/parse_utilcmd.c:763 parser/parse_utilcmd.c:892 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "外部テーブルでは外部キー制約はサポートされていません" + +#: commands/tablecmds.c:9605 commands/tablecmds.c:9768 commands/tablecmds.c:10640 commands/tablecmds.c:10715 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "リレーション\"%2$s\"の制約\"%1$s\"は存在しません" + +#: commands/tablecmds.c:9612 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "リレーション\"%2$s\"の制約\"%1$s\"は外部キー制約ではありません" + +#: commands/tablecmds.c:9776 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "リレーション\"%2$s\"の制約\"%1$s\"は外部キー制約でも検査制約でもありません" + +#: commands/tablecmds.c:9854 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "制約は子テーブルでも検証される必要があります" + +#: commands/tablecmds.c:9938 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "外部キー制約で参照される列\"%s\"が存在しません" + +#: commands/tablecmds.c:9943 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "外部キーでは%dを超えるキーを持つことができません" + +#: commands/tablecmds.c:10008 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "被参照テーブル\"%s\"には遅延可能プライマリキーは使用できません" + +#: commands/tablecmds.c:10025 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "被参照テーブル\"%s\"にはプライマリキーがありません" + +#: commands/tablecmds.c:10090 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "外部キーの被参照列リストには重複があってはなりません" + +#: commands/tablecmds.c:10184 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "被参照テーブル\"%s\"に対しては、遅延可能な一意性制約は使用できません" + +#: commands/tablecmds.c:10189 +#, c-format +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "被参照テーブル\"%s\"に、指定したキーに一致する一意性制約がありません" + +#: commands/tablecmds.c:10277 +#, c-format +msgid "validating foreign key constraint \"%s\"" +msgstr "外部キー制約\"%s\"を検証しています" + +#: commands/tablecmds.c:10596 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"の継承された制約\"%1$s\"を削除できません" + +#: commands/tablecmds.c:10646 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%2$s\"の制約\"%1$s\"は存在しません、スキップします" + +#: commands/tablecmds.c:10822 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "型付けされたテーブルの列の型を変更できません" + +#: commands/tablecmds.c:10849 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "継承される列\"%s\"を変更できません" + +#: commands/tablecmds.c:10858 +#, c-format +msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "列\"%s\"はリレーション\"%s\"のパーティションキーの一部であるため、変更できません" + +#: commands/tablecmds.c:10908 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "列\"%s\"に対するUSING句の結果は自動的に%s型に型変換できません" + +#: commands/tablecmds.c:10911 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "必要に応じて明示的な型変換を追加してください。" + +#: commands/tablecmds.c:10915 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "列\"%s\"は型%sには自動的に型変換できません" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:10918 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "必要に応じて\"USING %s::%s\"を追加してください。" + +#: commands/tablecmds.c:11018 +#, c-format +msgid "cannot alter inherited column \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"の継承列\"%1$s\"は変更できません" + +#: commands/tablecmds.c:11046 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "USING式が行全体テーブル参照を含んでいます。" + +#: commands/tablecmds.c:11057 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "継承される列\"%s\"の型を子テーブルで変更しなければなりません" + +#: commands/tablecmds.c:11182 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "列\"%s\"の型を2回変更することはできません" + +#: commands/tablecmds.c:11220 +#, c-format +msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" +msgstr "カラム\"%s\"に対する生成式は自動的に%s型にキャストできません" + +#: commands/tablecmds.c:11225 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "列\"%s\"のデフォルト値を自動的に%s型にキャストできません" + +#: commands/tablecmds.c:11303 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "生成カラムで使用される列の型は変更できません" + +#: commands/tablecmds.c:11304 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "カラム\"%s\"は生成カラム\"%s\"で使われています。" + +#: commands/tablecmds.c:11325 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "ビューまたはルールで使用される列の型は変更できません" + +#: commands/tablecmds.c:11326 commands/tablecmds.c:11345 commands/tablecmds.c:11363 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%sは列\"%s\"に依存しています" + +#: commands/tablecmds.c:11344 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "トリガー定義で使用される列の型は変更できません" + +#: commands/tablecmds.c:11362 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "ポリシ定義で使用されている列の型は変更できません" + +#: commands/tablecmds.c:12371 commands/tablecmds.c:12383 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "インデックス\"%s\"の所有者を変更できません" + +#: commands/tablecmds.c:12373 commands/tablecmds.c:12385 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "代わりにインデックスのテーブルの所有者を変更してください" + +#: commands/tablecmds.c:12399 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "シーケンス\"%s\"の所有者を変更できません" + +#: commands/tablecmds.c:12413 commands/tablecmds.c:15600 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "代わりにALTER TYPEを使用してください。" + +#: commands/tablecmds.c:12422 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "\"%s\"はテーブル、ビュー、シーケンス、外部テーブルではありません" + +#: commands/tablecmds.c:12761 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "SET TABLESPACEサブコマンドを複数指定できません" + +#: commands/tablecmds.c:12838 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "\"%s\"はテーブル、ビュー、実体化ビュー、インデックス、TOASTテーブルではありません" + +#: commands/tablecmds.c:12871 commands/view.c:494 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "WITH CHECK OPTIONは自動更新可能ビューでのみサポートされます" + +#: commands/tablecmds.c:13011 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "システムリレーション\"%s\"を移動できません" + +#: commands/tablecmds.c:13027 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "他のセッションの一時テーブルを移動できません" + +#: commands/tablecmds.c:13197 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "テーブルスペースにはテーブル、インデックスおよび実体化ビューしかありません" + +#: commands/tablecmds.c:13209 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "pg_globalテーブルスペースとの間のリレーションの移動はできません" + +#: commands/tablecmds.c:13301 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "リレーション\"%s.%s\"のロックが獲得できなかったため中断します" + +#: commands/tablecmds.c:13317 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "テーブルスペース\"%s\"には合致するリレーションはありませんでした" + +#: commands/tablecmds.c:13433 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "型付けされたテーブルの継承を変更できません" + +#: commands/tablecmds.c:13438 commands/tablecmds.c:13934 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "パーティションの継承は変更できません" + +#: commands/tablecmds.c:13443 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "パーティションテーブルの継承は変更できません" + +#: commands/tablecmds.c:13489 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "他のセッションの一時テーブルを継承できません" + +#: commands/tablecmds.c:13502 +#, c-format +msgid "cannot inherit from a partition" +msgstr "パーティションからの継承はできません" + +#: commands/tablecmds.c:13524 commands/tablecmds.c:16240 +#, c-format +msgid "circular inheritance not allowed" +msgstr "循環継承を行うことはできません" + +#: commands/tablecmds.c:13525 commands/tablecmds.c:16241 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "\"%s\"はすでに\"%s\"の子です" + +#: commands/tablecmds.c:13538 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "トリガ\"%s\"によってテーブル\"%s\"が継承子テーブルになることができません" + +#: commands/tablecmds.c:13540 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." +msgstr "遷移テーブルを使用したROWトリガは継承関係ではサポートされていません。" + +#: commands/tablecmds.c:13743 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "子テーブルの列\"%s\"はNOT NULLである必要があります" + +#: commands/tablecmds.c:13770 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "子テーブルには列\"%s\"がありません" + +#: commands/tablecmds.c:13858 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "子テーブル\"%s\"では検査制約\"%s\"に異なった定義がされています" + +#: commands/tablecmds.c:13866 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" +msgstr "制約\"%s\"は子テーブル\"%s\"上の継承されない制約と競合します" + +#: commands/tablecmds.c:13877 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "制約\"%s\"は子テーブル\"%s\"のNOT VALID制約と衝突しています" + +#: commands/tablecmds.c:13912 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "子テーブルには制約\"%s\"がありません" + +#: commands/tablecmds.c:14001 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "リレーション\"%s\"はリレーション\"%s\"のパーティション子テーブルではありません" + +#: commands/tablecmds.c:14007 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "リレーション\"%s\"はリレーション\"%s\"の親ではありません" + +#: commands/tablecmds.c:14235 +#, c-format +msgid "typed tables cannot inherit" +msgstr "型付けされたテーブルは継承できません" + +#: commands/tablecmds.c:14265 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "テーブルには列\"%s\"がありません" + +#: commands/tablecmds.c:14276 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "テーブルには列\"%s\"がありますが型は\"%s\"を必要としています" + +#: commands/tablecmds.c:14285 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "テーブル\"%s\"では列\"%s\"の型が異なっています" + +#: commands/tablecmds.c:14299 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "テーブルに余分な列\"%s\"があります" + +#: commands/tablecmds.c:14351 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "\"%s\"は型付けされたテーブルではありません" + +#: commands/tablecmds.c:14533 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "非ユニークインデックス\"%s\"は複製識別としては使用できません" + +#: commands/tablecmds.c:14539 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "一意性を即時検査しないインデックス\"%s\"は複製識別には使用できません" + +#: commands/tablecmds.c:14545 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "式インデックス\"%s\"は複製識別としては使用できません" + +#: commands/tablecmds.c:14551 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "部分インデックス\"%s\"を複製識別としては使用できません" + +#: commands/tablecmds.c:14557 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "無効なインデックス\"%s\"は複製識別としては使用できません" + +#: commands/tablecmds.c:14574 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "列%2$dはシステム列であるためインデックス\"%1$s\"は複製識別には使えません" + +#: commands/tablecmds.c:14581 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "列\"%2$s\"はnull可であるためインデックス\"%1$s\"は複製識別には使えません" + +#: commands/tablecmds.c:14774 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "テーブル\"%s\"は一時テーブルであるため、ログ出力設定を変更できません" + +#: commands/tablecmds.c:14798 +#, c-format +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "テーブル\"%s\"はパブリケーションの一部であるため、UNLOGGEDに変更できません" + +#: commands/tablecmds.c:14800 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "UNLOGGEDリレーションはレプリケーションできません。" + +#: commands/tablecmds.c:14845 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "テーブル\"%s\"はUNLOGGEDテーブル\"%s\"を参照しているためLOGGEDには設定できません" + +#: commands/tablecmds.c:14855 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "テーブル\"%s\"はLOGGEDテーブル\"%s\"を参照しているためUNLOGGEDには設定できません" + +#: commands/tablecmds.c:14913 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "所有するシーケンスを他のスキーマに移動することができません" + +#: commands/tablecmds.c:15020 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "リレーション\"%s\"はスキーマ\"%s\"内にすでに存在します" + +#: commands/tablecmds.c:15583 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "\"%s\"は複合型ではありません" + +#: commands/tablecmds.c:15615 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "\"%s\"はテーブル、ビュー、実体化ビュー、シーケンス、外部テーブルではありません" + +#: commands/tablecmds.c:15650 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "識別できないパーティションストラテジ \"%s\"" + +#: commands/tablecmds.c:15658 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "\"list\"パーティションストラテジは2つ以上の列に対しては使えません" + +#: commands/tablecmds.c:15724 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "パーティションキーに指定されている列\"%s\"は存在しません" + +#: commands/tablecmds.c:15732 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "パーティションキーでシステム列\"%s\"は使用できません" + +#: commands/tablecmds.c:15743 commands/tablecmds.c:15857 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "パーティションキーで生成カラムは使用できません" + +#: commands/tablecmds.c:15744 commands/tablecmds.c:15858 commands/trigger.c:641 rewrite/rewriteHandler.c:829 rewrite/rewriteHandler.c:846 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "列\"%s\"は生成カラムです。" + +#: commands/tablecmds.c:15820 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "パーティションキー式で使われる関数はIMMUTABLE指定されている必要があります" + +#: commands/tablecmds.c:15840 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "パーティションキー式はシステム列への参照を含むことができません" + +#: commands/tablecmds.c:15870 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "定数式をパーティションキーとして使うことはできません" + +#: commands/tablecmds.c:15891 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "パーティション式で使用する照合順序を特定できませんでした" + +#: commands/tablecmds.c:15926 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "ハッシュ演算子クラスを指定するか、もしくはこのデータ型にデフォルトのハッシュ演算子クラスを定義する必要があります。" + +#: commands/tablecmds.c:15932 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "btree演算子クラスを指定するか、もしくはこのデータ型にデフォルトのbtree演算子クラスを定義するかする必要があります。" + +#: commands/tablecmds.c:16077 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "テーブル\"%s\"のパーティション制約は既存の制約によって暗黙的に満たされています" + +#: commands/tablecmds.c:16081 partitioning/partbounds.c:3131 partitioning/partbounds.c:3182 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "デフォルトパーティション \"%s\" に対する更新されたパーティション制約は既存の制約によって暗黙的に満たされています" + +#: commands/tablecmds.c:16180 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\"はすでパーティションです" + +#: commands/tablecmds.c:16186 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "型付けされたテーブルをパーティションにアタッチすることはできません" + +#: commands/tablecmds.c:16202 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "継承子テーブルをパーティションにアタッチすることはできません" + +#: commands/tablecmds.c:16216 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "継承親テーブルをパーティションにアタッチすることはできません" + +#: commands/tablecmds.c:16250 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "一時リレーションを永続リレーション \"%s\" の子テーブルとしてアタッチすることはできません" + +#: commands/tablecmds.c:16258 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "永続リレーションを一時リレーション\"%s\"のパーティション子テーブルとしてアタッチすることはできません" + +#: commands/tablecmds.c:16266 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "他セッションの一時リレーションのパーティション子テーブルとしてアタッチすることはできません" + +#: commands/tablecmds.c:16273 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "他セッションの一時リレーションにパーティション子テーブルとしてアタッチすることはできません" + +#: commands/tablecmds.c:16293 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "テーブル\"%1$s\"は親テーブル\"%3$s\"にない列\"%2$s\"を含んでいます" + +#: commands/tablecmds.c:16296 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "新しいパーティションは親に存在する列のみを含むことができます。" + +#: commands/tablecmds.c:16308 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "トリガ\"%s\"のため、テーブル\"%s\"はパーティション子テーブルにはなれません" + +#: commands/tablecmds.c:16310 commands/trigger.c:447 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "遷移テーブルを使用するROWトリガはパーティションではサポートされません" + +#: commands/tablecmds.c:16473 +#, c-format +msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" +msgstr "外部テーブル\"%s\"はパーティションテーブル\"%s\"の子テーブルとしてアタッチすることはできません" + +#: commands/tablecmds.c:16476 +#, c-format +msgid "Table \"%s\" contains unique indexes." +msgstr "テーブル\"%s\"はユニークインデックスを持っています。" + +#: commands/tablecmds.c:17122 commands/tablecmds.c:17142 commands/tablecmds.c:17162 commands/tablecmds.c:17181 commands/tablecmds.c:17223 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "インデックス\"%s\"をインデックス\"%s\"の子インデックスとしてアタッチすることはできません" + +#: commands/tablecmds.c:17125 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "インデックス\"%s\"はすでに別のインデックスにアタッチされています。" + +#: commands/tablecmds.c:17145 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "インデックス\"%s\"はテーブル\"%s\"のどの子テーブルのインデックスでもありません。" + +#: commands/tablecmds.c:17165 +#, c-format +msgid "The index definitions do not match." +msgstr "インデックス定義が合致しません。" + +#: commands/tablecmds.c:17184 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "インデックス\"%s\"はテーブル\"%s\"の制約に属していますが、インデックス\"%s\"には制約がありません。" + +#: commands/tablecmds.c:17226 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "子テーブル\"%s\"にはすでに他のインデックスがアタッチされています。" + +#: commands/tablespace.c:162 commands/tablespace.c:179 commands/tablespace.c:190 commands/tablespace.c:198 commands/tablespace.c:638 replication/slot.c:1374 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" + +#: commands/tablespace.c:209 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"のstatができませんでした: %m" + +#: commands/tablespace.c:218 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "\"%s\"は存在しますが、ディレクトリではありません" + +#: commands/tablespace.c:249 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "テーブル空間\"%s\"を作成する権限がありません" + +#: commands/tablespace.c:251 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "テーブル空間を生成するにはスーパユーザである必要があります。" + +#: commands/tablespace.c:267 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "テーブル空間の場所には単一引用符を含めることができません" + +#: commands/tablespace.c:277 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "テーブル空間の場所は絶対パスでなければなりません" + +#: commands/tablespace.c:289 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "テーブル空間の場所\"%s\"は長すぎます" + +#: commands/tablespace.c:296 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "テーブル空間の場所はデータディレクトリの中に指定すべきではありません" + +#: commands/tablespace.c:305 commands/tablespace.c:965 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "テーブル空間名\"%s\"を受け付けられません" + +#: commands/tablespace.c:307 commands/tablespace.c:966 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "接頭辞\"pg_\"はシステムテーブル空間用に予約されています" + +#: commands/tablespace.c:326 commands/tablespace.c:987 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "テーブル空間\"%s\"はすでに存在します" + +#: commands/tablespace.c:442 commands/tablespace.c:948 commands/tablespace.c:1037 commands/tablespace.c:1106 commands/tablespace.c:1252 commands/tablespace.c:1455 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "テーブル空間\"%s\"は存在しません" + +#: commands/tablespace.c:448 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "テーブル空間\"%s\"は存在しません、スキップします" + +#: commands/tablespace.c:525 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "テーブル空間\"%s\"は空ではありません" + +#: commands/tablespace.c:597 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "ディレクトリ\"%s\"は存在しません" + +#: commands/tablespace.c:598 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "サーバを再起動する前にテーブルスペース用のディレクトリを作成してください" + +#: commands/tablespace.c:603 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"に権限を設定できませんでした: %m" + +#: commands/tablespace.c:633 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "ディレクトリ\"%s\"はすでにテーブルスペースとして使われています" + +#: commands/tablespace.c:757 commands/tablespace.c:770 commands/tablespace.c:806 commands/tablespace.c:898 storage/file/fd.c:3108 storage/file/fd.c:3448 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を削除できませんでした: %m" + +#: commands/tablespace.c:819 commands/tablespace.c:907 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を削除できませんでした: %m" + +#: commands/tablespace.c:829 commands/tablespace.c:916 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "\"%s\"はディレクトリでもシンボリックリンクでもありません" + +#: commands/tablespace.c:1111 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "テーブル空間\"%s\"は存在しません" + +#: commands/tablespace.c:1554 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "テーブル空間%u用のディレクトリを削除することができませんでした" + +#: commands/tablespace.c:1556 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "必要ならば手作業でこのディレクトリを削除することができます" + +#: commands/trigger.c:204 commands/trigger.c:215 +#, c-format +msgid "\"%s\" is a table" +msgstr "\"%s\"はテーブルです" + +#: commands/trigger.c:206 commands/trigger.c:217 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "テーブルは INSTEAD OF トリガーを持つことができません" + +#: commands/trigger.c:238 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\"はパーティションテーブルです" + +#: commands/trigger.c:240 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "パーティションテーブルに対するトリガは遷移テーブルを持てません。" + +#: commands/trigger.c:252 commands/trigger.c:259 commands/trigger.c:429 +#, c-format +msgid "\"%s\" is a view" +msgstr "\"%s\"はビューです" + +#: commands/trigger.c:254 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "ビューは行レベルの BEFORE / AFTER トリガーを持つことができません" + +#: commands/trigger.c:261 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "ビューは TRUNCATE トリガーを持つことができません" + +#: commands/trigger.c:269 commands/trigger.c:276 commands/trigger.c:288 commands/trigger.c:422 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "\"%s\"は外部テーブルです" + +#: commands/trigger.c:271 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "外部テーブルは INSTEAD OF トリガを持つことができません。" + +#: commands/trigger.c:278 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "外部テーブルは TRUNCATE トリガを持つことができません。" + +#: commands/trigger.c:290 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "外部テーブルは制約トリガを持つことができません。" + +#: commands/trigger.c:365 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "TRUNCATE FOR EACH ROW トリガはサポートされていません" + +#: commands/trigger.c:373 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "INSTEAD OF トリガーは FOR EACH ROW でなければなりません" + +#: commands/trigger.c:377 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "INSTEAD OF トリガーは WHEN 条件を持つことができません" + +#: commands/trigger.c:381 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "INSTEAD OF トリガーは列リストを持つことができません" + +#: commands/trigger.c:410 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "REFERENCING句でのROW変数の命名はサポートされていません" + +#: commands/trigger.c:411 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "遷移テーブルを指定するには OLD TABLE または NEW TABLE を使ってください" + +#: commands/trigger.c:424 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "外部テーブルに対するトリガは遷移テーブルを持てません。" + +#: commands/trigger.c:431 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "ビューに対するトリガは遷移テーブルを持てません。" + +#: commands/trigger.c:451 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "遷移テーブルをもったROWトリガは継承子テーブルではサポートされません" + +#: commands/trigger.c:457 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "遷移テーブル名はAFTERトリガでの指定可能です" + +#: commands/trigger.c:462 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "遷移テーブルを使用するTRUNCATEトリガはサポートされていません" + +#: commands/trigger.c:479 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "2つ以上のイベントに対するトリガには遷移テーブルは指定できません" + +#: commands/trigger.c:490 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "列リストを指定したトリガに対しては遷移テーブルは指定できません" + +#: commands/trigger.c:507 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "NEW TABLE はINSERTまたはUPDATEトリガに対してのみ指定可能です" + +#: commands/trigger.c:512 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE は複数回指定できません" + +#: commands/trigger.c:522 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE はDELETEまたはUPDATEトリガに対してのみ指定可能です" + +#: commands/trigger.c:527 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE は複数回指定できません" + +#: commands/trigger.c:537 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "OLD TABLE の名前と NEW TABLE の名前は同じにはできません" + +#: commands/trigger.c:601 commands/trigger.c:614 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "ステートメントトリガーの WHEN 条件では列の値を参照できません" + +#: commands/trigger.c:606 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "INSERT トリガーの WHEN 条件では OLD 値を参照できません" + +#: commands/trigger.c:619 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "DELETE トリガーの WHEN 条件では NEW 値を参照できません" + +#: commands/trigger.c:624 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "BEFORE トリガーの WHEN 条件では NEW システム列を参照できません" + +#: commands/trigger.c:632 commands/trigger.c:640 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "BEFORE トリガーの WHEN 条件では NEW の生成列を参照できません" + +#: commands/trigger.c:633 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "行全体参照が使われていてかつ、このテーブルは生成カラムを含んでいます。" + +#: commands/trigger.c:780 commands/trigger.c:1385 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "リレーション\"%2$s\"用のトリガ\"%1$s\"はすでに存在します" + +#: commands/trigger.c:1271 commands/trigger.c:1432 commands/trigger.c:1568 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "テーブル\"%2$s\"のトリガ\"%1$s\"は存在しません" + +#: commands/trigger.c:1515 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "権限がありません: \"%s\"はシステムトリガです" + +#: commands/trigger.c:2116 +#, c-format +msgid "trigger function %u returned null value" +msgstr "トリガ関数%uはNULL値を返しました" + +#: commands/trigger.c:2176 commands/trigger.c:2390 commands/trigger.c:2625 commands/trigger.c:2933 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "BEFORE STATEMENTトリガは値を返すことができません" + +#: commands/trigger.c:2250 +#, c-format +msgid "moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported" +msgstr "BEFORE FOR EACH ROWトリガの実行では、他のパーティションへの行の移動はサポートされていません" + +#: commands/trigger.c:2251 commands/trigger.c:2755 +#, c-format +msgid "Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." +msgstr "トリガ\"%s\"の実行前には、この行はパーティション\"%s.%s\"に置かれるはずでした。" + +#: commands/trigger.c:2754 +#, c-format +msgid "moving row to another partition during a BEFORE trigger is not supported" +msgstr "BEFOREトリガの実行では、他のパーティションへの行の移動はサポートされません" + +#: commands/trigger.c:2996 executor/nodeModifyTable.c:1380 executor/nodeModifyTable.c:1449 +#, c-format +msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgstr "更新対象のタプルはすでに現在のコマンドによって発行された操作によって変更されています" + +#: commands/trigger.c:2997 executor/nodeModifyTable.c:840 executor/nodeModifyTable.c:914 executor/nodeModifyTable.c:1381 executor/nodeModifyTable.c:1450 +#, c-format +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." +msgstr "他の行への変更を伝搬させるためにBEFOREトリガではなくAFTERトリガの使用を検討してください" + +#: commands/trigger.c:3026 executor/nodeLockRows.c:225 executor/nodeLockRows.c:234 executor/nodeModifyTable.c:220 executor/nodeModifyTable.c:856 executor/nodeModifyTable.c:1397 executor/nodeModifyTable.c:1613 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "更新が同時に行われたためアクセスの直列化ができませんでした" + +#: commands/trigger.c:3034 executor/nodeModifyTable.c:946 executor/nodeModifyTable.c:1467 executor/nodeModifyTable.c:1637 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "削除が同時に行われたためアクセスの直列化ができませんでした" + +#: commands/trigger.c:5094 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "制約\"%s\"は遅延可能ではありません" + +#: commands/trigger.c:5117 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "制約\"%s\"は存在しません" + +#: commands/tsearchcmds.c:118 commands/tsearchcmds.c:636 +#, c-format +msgid "function %s should return type %s" +msgstr "関数%sは型%sを返すことができません" + +#: commands/tsearchcmds.c:195 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "テキスト検索パーサを生成するにはスーパユーザである必要があります" + +#: commands/tsearchcmds.c:248 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "テキスト検索パーサ\"%s\"は不明です" + +#: commands/tsearchcmds.c:258 +#, c-format +msgid "text search parser start method is required" +msgstr "テキスト検索パーサの開始メソッドが必要です" + +#: commands/tsearchcmds.c:263 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "テキスト検索パーサのgettokenメソッドが必要です" + +#: commands/tsearchcmds.c:268 +#, c-format +msgid "text search parser end method is required" +msgstr "テキスト検索パーサの終了メソッドが必要です" + +#: commands/tsearchcmds.c:273 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "テキスト検索パーサのlextypesメソッドが必要です" + +#: commands/tsearchcmds.c:367 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "テキスト検索テンプレート\"%s\"はオプションを受け付けません" + +#: commands/tsearchcmds.c:441 +#, c-format +msgid "text search template is required" +msgstr "テキスト検索テンプレートが必要です" + +#: commands/tsearchcmds.c:703 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "テキスト検索テンプレートを生成するにはスーパユーザである必要があります" + +#: commands/tsearchcmds.c:745 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "テキスト検索テンプレートのパラメータ\"%sは不明です。" + +#: commands/tsearchcmds.c:755 +#, c-format +msgid "text search template lexize method is required" +msgstr "テキスト検索テンプレートのlexizeメソッドが必要です" + +#: commands/tsearchcmds.c:935 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "テキスト検索設定のパラメータ\"%s\"は不明です" + +#: commands/tsearchcmds.c:942 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "PARSERとCOPYオプションをまとめて指定できません" + +#: commands/tsearchcmds.c:978 +#, c-format +msgid "text search parser is required" +msgstr "テキスト検索パーサが必要です" + +#: commands/tsearchcmds.c:1202 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "トークン型\"%s\"は存在しません" + +#: commands/tsearchcmds.c:1429 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "トークン型\"%s\"に対するマップは存在しません" + +#: commands/tsearchcmds.c:1435 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "トークン型\"%s\"に対するマップは存在しません、スキップします" + +#: commands/tsearchcmds.c:1598 commands/tsearchcmds.c:1713 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "不正パラメータリストの書式です: \"%s\"" + +#: commands/typecmds.c:206 +#, c-format +msgid "must be superuser to create a base type" +msgstr "基本型を作成するにはスーパユーザである必要があります" + +#: commands/typecmds.c:264 +#, c-format +msgid "Create the type as a shell type, then create its I/O functions, then do a full CREATE TYPE." +msgstr "最初に型をシェル型として生成して、続いてI/O関数を生成した後に完全な CREATE TYPE を実行してください。" + +#: commands/typecmds.c:314 commands/typecmds.c:1394 commands/typecmds.c:3832 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "型の属性\"%s\"は不明です" + +#: commands/typecmds.c:370 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "型カテゴリ\"%s\"が不正です。単純なASCIIでなければなりません" + +#: commands/typecmds.c:389 +#, c-format +msgid "array element type cannot be %s" +msgstr "%sを配列要素の型にすることはできません" + +#: commands/typecmds.c:421 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "アライメント\"%s\"は不明です" + +#: commands/typecmds.c:438 commands/typecmds.c:3718 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "格納方式\"%s\"は不明です" + +#: commands/typecmds.c:449 +#, c-format +msgid "type input function must be specified" +msgstr "型の入力関数の指定が必要です" + +#: commands/typecmds.c:453 +#, c-format +msgid "type output function must be specified" +msgstr "型の出力関数の指定が必要です" + +#: commands/typecmds.c:458 +#, c-format +msgid "type modifier output function is useless without a type modifier input function" +msgstr "型修正入力関数がない場合の型修正出力関数は意味がありません" + +#: commands/typecmds.c:745 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "\"%s\"はドメインの基本型として無効です" + +#: commands/typecmds.c:837 +#, c-format +msgid "multiple default expressions" +msgstr "デフォルト式が複数あります" + +#: commands/typecmds.c:900 commands/typecmds.c:909 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "NULL制約とNOT NULL制約が競合しています" + +#: commands/typecmds.c:925 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "ドメインに対する検査制約はNO INHERITとマークすることができません" + +#: commands/typecmds.c:934 commands/typecmds.c:2536 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "ドメインでは一意性制約は使用できません" + +#: commands/typecmds.c:940 commands/typecmds.c:2542 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "ドメインではプライマリキー制約はできません" + +#: commands/typecmds.c:946 commands/typecmds.c:2548 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "ドメインでは排除制約は使用できません" + +#: commands/typecmds.c:952 commands/typecmds.c:2554 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "ドメイン用の外部キー制約はできません" + +#: commands/typecmds.c:961 commands/typecmds.c:2563 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "ドメインでは制約遅延の指定はサポートしていません" + +#: commands/typecmds.c:1271 utils/cache/typcache.c:2430 +#, c-format +msgid "%s is not an enum" +msgstr "%s は数値ではありません" + +#: commands/typecmds.c:1402 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "型の属性\"subtype\"が必要です" + +#: commands/typecmds.c:1407 +#, c-format +msgid "range subtype cannot be %s" +msgstr "範囲の派生元型を%sにすることはできません" + +#: commands/typecmds.c:1426 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "範囲の照合順序が指定されましたが、派生もと型が照合順序をサポートしていません" + +#: commands/typecmds.c:1436 +#, c-format +msgid "cannot specify a canonical function without a pre-created shell type" +msgstr "事前にシェル型を生成せずに正規化関数を指定することはできません" + +#: commands/typecmds.c:1437 +#, c-format +msgid "Create the type as a shell type, then create its canonicalization function, then do a full CREATE TYPE." +msgstr "最初に型をシェル型として生成して、続いて正規化関数を生成した後に完全な CREATE TYPE を実行してください。" + +#: commands/typecmds.c:1648 +#, c-format +msgid "type input function %s has multiple matches" +msgstr "型の入力関数%sが複数合致します" + +#: commands/typecmds.c:1666 +#, c-format +msgid "type input function %s must return type %s" +msgstr "型の入力関数%sは型%sを返す必要があります" + +#: commands/typecmds.c:1682 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "型の入力関数%sはvolatileであってはなりません" + +#: commands/typecmds.c:1710 +#, c-format +msgid "type output function %s must return type %s" +msgstr "型の出力関数%sは型%sを返す必要があります" + +#: commands/typecmds.c:1717 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "型の出力関数%sはvolatileであってはなりません" + +#: commands/typecmds.c:1746 +#, c-format +msgid "type receive function %s has multiple matches" +msgstr "型の受信関数 %s が複数合致しました" + +#: commands/typecmds.c:1764 +#, c-format +msgid "type receive function %s must return type %s" +msgstr "型の受信関数%sは型%sを返す必要があります" + +#: commands/typecmds.c:1771 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "型の受信関数%sはvolatileであってはなりません" + +#: commands/typecmds.c:1799 +#, c-format +msgid "type send function %s must return type %s" +msgstr "型の送信関数%sは型%sを返す必要があります" + +#: commands/typecmds.c:1806 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "型の送信関数%sはvolatileであってはなりません" + +#: commands/typecmds.c:1833 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr "typmod_in関数%sは型%sを返す必要があります" + +#: commands/typecmds.c:1840 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "型修正子の入力関数%sはvolatileであってはなりません" + +#: commands/typecmds.c:1867 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "typmod_out関数%sは型%sを返す必要があります" + +#: commands/typecmds.c:1874 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "型修正子の出力関数%sはvolatileであってはなりません" + +#: commands/typecmds.c:1901 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "型のANALYZE関数%sは%s型を返す必要があります" + +#: commands/typecmds.c:1947 +#, c-format +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." +msgstr "この範囲型に演算子クラスを指定するか、派生元の型でデフォルト演算子クラスを定義する必要があります。" + +#: commands/typecmds.c:1978 +#, c-format +msgid "range canonical function %s must return range type" +msgstr "範囲の正規化関数 %s は範囲型を返す必要があります" + +#: commands/typecmds.c:1984 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "範囲の正規化関数 %s は不変関数でなければなりません" + +#: commands/typecmds.c:2020 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "範囲の派生元の型の差分関数 %s は %s型を返す必要があります" + +#: commands/typecmds.c:2027 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "範囲の派生元の型の差分関数 %s は不変関数である必要があります" + +#: commands/typecmds.c:2054 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "バイナリアップグレードモード中にpg_typeの配列型OIDが設定されていません" + +#: commands/typecmds.c:2352 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "テーブル\"%2$s\"の列\"%1$s\"にNULL値があります" + +#: commands/typecmds.c:2465 commands/typecmds.c:2667 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "ドメイン\"%2$s\"の制約\"%1$s\"は存在しません" + +#: commands/typecmds.c:2469 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "ドメイン\"%2$s\"の制約\"%1$s\"は存在しません、スキップします" + +#: commands/typecmds.c:2674 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "ドメイン\"%2$s\"の制約\"%1$s\"は検査制約ではありません" + +#: commands/typecmds.c:2780 +#, c-format +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "テーブル\"%2$s\"の列\"%1$s\"に新しい制約に違反する値があります" + +#: commands/typecmds.c:3009 commands/typecmds.c:3207 commands/typecmds.c:3289 commands/typecmds.c:3476 +#, c-format +msgid "%s is not a domain" +msgstr "%s はドメインではありません" + +#: commands/typecmds.c:3041 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "ドメイン\"%2$s\"の制約\"%1$s\"はすでに存在します" + +#: commands/typecmds.c:3092 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "ドメインの検査制約ではテーブル参照を使用できません" + +#: commands/typecmds.c:3219 commands/typecmds.c:3301 commands/typecmds.c:3593 +#, c-format +msgid "%s is a table's row type" +msgstr "%sはテーブルの行型です" + +#: commands/typecmds.c:3221 commands/typecmds.c:3303 commands/typecmds.c:3595 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "代わりにALTER TABLEを使用してください" + +#: commands/typecmds.c:3228 commands/typecmds.c:3310 commands/typecmds.c:3508 +#, c-format +msgid "cannot alter array type %s" +msgstr "配列型%sを変更できません" + +#: commands/typecmds.c:3230 commands/typecmds.c:3312 commands/typecmds.c:3510 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "型%sを変更することができます。これは同時にその配列型も変更します。" + +#: commands/typecmds.c:3578 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "型\"%s\"はスキーマ\"%s\"内にすでに存在します" + +#: commands/typecmds.c:3746 +#, c-format +msgid "cannot change type's storage to PLAIN" +msgstr "型の格納方式をPLAINには変更できません" + +#: commands/typecmds.c:3827 +#, c-format +msgid "type attribute \"%s\" cannot be changed" +msgstr "型の属性\"%s\"は変更できません" + +#: commands/typecmds.c:3845 +#, c-format +msgid "must be superuser to alter a type" +msgstr "型の変更を行うにはスーパユーザである必要があります" + +#: commands/typecmds.c:3866 commands/typecmds.c:3876 +#, c-format +msgid "%s is not a base type" +msgstr "\"%s\"は基本型ではありません" + +#: commands/user.c:140 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSIDはもう指定することができません" + +#: commands/user.c:294 +#, c-format +msgid "must be superuser to create superusers" +msgstr "スーパユーザを生成するにはスーパユーザである必要があります" + +#: commands/user.c:301 +#, c-format +msgid "must be superuser to create replication users" +msgstr "レプリケーションユーザを生成するにはスーパユーザである必要があります" + +#: commands/user.c:308 commands/user.c:734 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "bypassrls属性を変更するにはスーパユーザである必要があります" + +#: commands/user.c:315 +#, c-format +msgid "permission denied to create role" +msgstr "ロールを作成する権限がありません" + +#: commands/user.c:325 commands/user.c:1224 commands/user.c:1231 gram.y:14900 gram.y:14938 utils/adt/acl.c:5327 utils/adt/acl.c:5333 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "ロール名\"%s\"は予約されています" + +#: commands/user.c:327 commands/user.c:1226 commands/user.c:1233 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "\"pg_\"で始まるロール名は予約されています。" + +#: commands/user.c:348 commands/user.c:1248 +#, c-format +msgid "role \"%s\" already exists" +msgstr "ロール\"%s\"はすでに存在します" + +#: commands/user.c:414 commands/user.c:843 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "空の文字列はパスワードとして使えません、パスワードを消去します" + +#: commands/user.c:443 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "バイナリアップグレードモード中にpg_authidのOIDが設定されていません" + +#: commands/user.c:720 commands/user.c:944 commands/user.c:1485 commands/user.c:1627 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "スーパユーザを更新するにはスーパユーザである必要があります" + +#: commands/user.c:727 +#, c-format +msgid "must be superuser to alter replication users" +msgstr "レプリケーションユーザを更新するにはスーパユーザである必要があります" + +#: commands/user.c:750 commands/user.c:951 +#, c-format +msgid "permission denied" +msgstr "権限がありません" + +#: commands/user.c:981 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "サーバ全体の設定を変更するにはスーパユーザである必要があります" + +#: commands/user.c:1003 +#, c-format +msgid "permission denied to drop role" +msgstr "ロールを削除する権限がありません" + +#: commands/user.c:1028 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "DROP ROLE で特殊ロールの識別子は使えません" + +#: commands/user.c:1038 commands/user.c:1195 commands/variable.c:770 commands/variable.c:844 utils/adt/acl.c:5184 utils/adt/acl.c:5231 utils/adt/acl.c:5259 utils/adt/acl.c:5277 utils/init/miscinit.c:677 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "ロール\"%s\"は存在しません" + +#: commands/user.c:1043 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "ロール\"%s\"は存在しません、スキップします" + +#: commands/user.c:1056 commands/user.c:1060 +#, c-format +msgid "current user cannot be dropped" +msgstr "現在のユーザを削除できません" + +#: commands/user.c:1064 +#, c-format +msgid "session user cannot be dropped" +msgstr "セッションのユーザを削除できません" + +#: commands/user.c:1074 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "スーパユーザを削除するにはスーパユーザである必要があります" + +#: commands/user.c:1090 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "他のオブジェクトが依存していますのでロール\"%s\"を削除できません" + +#: commands/user.c:1211 +#, c-format +msgid "session user cannot be renamed" +msgstr "セッションユーザの名前を変更できません" + +#: commands/user.c:1215 +#, c-format +msgid "current user cannot be renamed" +msgstr "現在のユーザの名前を変更できません" + +#: commands/user.c:1258 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "スーパユーザの名前を変更するにはスーパユーザである必要があります" + +#: commands/user.c:1265 +#, c-format +msgid "permission denied to rename role" +msgstr "ロールの名前を変更する権限がありません" + +#: commands/user.c:1286 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "ロール名が変更されたためMD5パスワードがクリアされました" + +#: commands/user.c:1346 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "列名が GRANT/REVOKE ROLE に含まれていてはなりません" + +#: commands/user.c:1384 +#, c-format +msgid "permission denied to drop objects" +msgstr "オブジェクトを削除する権限がありません" + +#: commands/user.c:1411 commands/user.c:1420 +#, c-format +msgid "permission denied to reassign objects" +msgstr "オブジェクトを再割当てする権限がありません" + +#: commands/user.c:1493 commands/user.c:1635 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "ロール\"%s\"には ADMIN OPTION が必要です" + +#: commands/user.c:1510 +#, c-format +msgid "must be superuser to set grantor" +msgstr "権限付与者を指定するにはスーパユーザである必要があります" + +#: commands/user.c:1535 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "ロール\"%s\"はロール\"%s\"のメンバです" + +#: commands/user.c:1550 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "ロール\"%s\"はすでにロール\"%s\"のメンバです" + +#: commands/user.c:1657 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "ロール\"%s\"はロール\"%s\"のメンバではありません" + +#: commands/vacuum.c:129 +#, c-format +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "ANALYZEオプション\"%s\"が認識できません" + +#: commands/vacuum.c:151 +#, c-format +msgid "parallel option requires a value between 0 and %d" +msgstr "パラレルオプションには0から%dまでの値である必要があります" + +#: commands/vacuum.c:163 +#, c-format +msgid "parallel vacuum degree must be between 0 and %d" +msgstr "並列VACUUMの並列度は0から%dまでの値でなければなりません" + +#: commands/vacuum.c:180 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "認識できないVACUUMオプション \"%s\"" + +#: commands/vacuum.c:203 +#, c-format +msgid "VACUUM FULL cannot be performed in parallel" +msgstr "VACUUM FULLは並列実行できません" + +#: commands/vacuum.c:219 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "ANALYZE オプションは列リストが与えられているときのみ指定できます" + +#: commands/vacuum.c:309 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%sはVACUUMやANALYZEからは実行できません" + +#: commands/vacuum.c:319 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "VACUUM のオプションDISABLE_PAGE_SKIPPINGはFULLと同時には指定できません" + +#: commands/vacuum.c:560 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "\"%s\"をスキップしています --- スーパユーザのみがVACUUMを実行できます" + +#: commands/vacuum.c:564 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "\"%s\"をスキップしています --- スーパユーザもしくはデータベースの所有者のみがVACUUMを実行できます" + +#: commands/vacuum.c:568 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "\"%s\"を飛ばしています --- テーブルまたはデータベースの所有者のみがVACUUMを実行することができます" + +#: commands/vacuum.c:583 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "\"%s\"をスキップしています --- スーパユーザのみがANALYZEを実行できます" + +#: commands/vacuum.c:587 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "\"%s\"をスキップしています --- スーパユーザまたはデータベースの所有者のみがANALYZEを実行できます" + +#: commands/vacuum.c:591 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "\"%s\"をスキップしています --- テーブルまたはデータベースの所有者のみがANALYZEを実行できます" + +#: commands/vacuum.c:670 commands/vacuum.c:766 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "\"%s\"のVACUUM処理をスキップしています -- ロックを獲得できませんでした" + +#: commands/vacuum.c:675 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "\"%s\"のVACUUM処理をスキップしています -- リレーションはすでに存在しません" + +#: commands/vacuum.c:691 commands/vacuum.c:771 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "\"%s\"のANALYZEをスキップしています --- ロック獲得できませんでした" + +#: commands/vacuum.c:696 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "\"%s\"のANALYZEをスキップします --- リレーションはすでに存在しません" + +#: commands/vacuum.c:1011 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "最も古いxminが古すぎます" + +#: commands/vacuum.c:1012 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"周回問題を回避するためにすぐに実行中のトランザクションを終了してください。\n" +"古い準備済みトランザクションのコミットまたはロールバック、もしくは古いレプリケーションスロットの削除が必要な場合もあります。" + +#: commands/vacuum.c:1053 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "最古のマルチトランザクションが古すぎます" + +#: commands/vacuum.c:1054 +#, c-format +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "周回問題を回避するために、マルチトランザクションを使用している実行中のトランザクションをすぐにクローズしてください。" + +#: commands/vacuum.c:1641 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "データベースの一部は20億トランザクション以上の間にVACUUMを実行されていませんでした" + +#: commands/vacuum.c:1642 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "トランザクションの周回によるデータ損失が発生している可能性があります" + +#: commands/vacuum.c:1804 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "\"%s\"をスキップしています --- テーブルではないものや、特別なシステムテーブルに対してはVACUUMを実行できません" + +#: commands/variable.c:165 utils/misc/guc.c:11174 utils/misc/guc.c:11236 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "不明なキーワードです: \"%s\"" + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "\"datestyle\"指定が競合しています。" + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "タイムゾーンのインターバル指定では月は指定できません。" + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "タイムゾーンのインターバル指定では日は指定できません。" + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "タイムゾーン\"%s\"はうるう秒を使用するようです" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQLはうるう秒をサポートしていません。" + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "UTCのタイムゾーンオフセットが範囲外です。" + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "読み取りのみのトランザクションでトランザクションモードを読み書きモードに設定することはできません" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "トランザクションの読み書きモードの設定は、問い合わせより前に行う必要があります" + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "リカバリ中にはトランザクションを読み書きモードに設定できません" + +#: commands/variable.c:534 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "SET TRANSACTION ISOLATION LEVEL は問い合わせより前に実行する必要があります" + +#: commands/variable.c:541 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "SET TRANSACTION ISOLATION LEVELをサブトランザクションで呼び出してはなりません" + +#: commands/variable.c:548 storage/lmgr/predicate.c:1623 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "ホットスタンバイ中はシリアライズモードを使用できません" + +#: commands/variable.c:549 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "代わりに REPEATABLE READ を使ってください" + +#: commands/variable.c:567 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "SET TRANSACTION [NOT] DEFERRABLE をサブトランザクション内部では呼び出せません" + +#: commands/variable.c:573 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "SET TRANSACTION [NOT] DEFERRABLE は問い合わせより前に実行する必要があります" + +#: commands/variable.c:655 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "%sと%s 間の変換はサポートされていません。" + +#: commands/variable.c:662 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "現在は\"client_encoding\"を変更できません。" + +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "並列処理中は\"client_encoding\"を変更できません" + +#: commands/variable.c:863 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "ロール\"%s\"を設定する権限がありません" + +#: commands/view.c:84 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "ビューの列\"%s\"で使用する照合順序を特定できませんでした" + +#: commands/view.c:265 commands/view.c:276 +#, c-format +msgid "cannot drop columns from view" +msgstr "ビューからは列を削除できません" + +#: commands/view.c:281 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "ビューの列名を\"%s\"から\"%s\"に変更できません" + +#: commands/view.c:284 +#, c-format +msgid "Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead." +msgstr "代わりに ALTER VIEW ... RENAME COLUMN ... を使用してビューカラムの名前を変更してください。" + +#: commands/view.c:290 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "ビューの列 \"%s\"のデータ型を %s から %s に変更できません" + +#: commands/view.c:441 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "ビューでは SELECT INTO を使用できません" + +#: commands/view.c:453 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "ビューでは WITH 句にデータを変更するステートメントを含むことはできません" + +#: commands/view.c:523 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "CREATE VIEW で列よりも多くの列名が指定されています" + +#: commands/view.c:531 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "ビューは自身の格納領域を持たないので、UNLOGGEDにはできません" + +#: commands/view.c:545 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "ビュー\"%s\"は一時ビューとなります" + +#: executor/execCurrent.c:79 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "カーソル\"%s\"はSELECT問い合わせではありません" + +#: executor/execCurrent.c:85 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "カーソル\"%s\"は以前のトランザクションから保持されています" + +#: executor/execCurrent.c:118 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "カーソル\"%s\"にはテーブル\"%s\"に対する複数のFOR UPDATE/SHARE参照があります" + +#: executor/execCurrent.c:127 +#, c-format +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "カーソル\"%s\"にはテーブル\"%s\"への FOR UPDATE/SHARE参照がありません" + +#: executor/execCurrent.c:137 executor/execCurrent.c:182 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr "カーソル\"%s\"は行上に位置していません" + +#: executor/execCurrent.c:169 executor/execCurrent.c:228 executor/execCurrent.c:239 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "カーソル\"%s\"はテーブル\"%s\"を単純な更新可能スキャンではありません" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2404 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "パラメータの型%d(%s)が実行計画(%s)を準備する時点と一致しません" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2416 +#, c-format +msgid "no value found for parameter %d" +msgstr "パラメータ%dの値がありません" + +#: executor/execExpr.c:859 parser/parse_agg.c:816 +#, c-format +msgid "window function calls cannot be nested" +msgstr "ウィンドウ関数の呼び出しを入れ子にすることはできません" + +#: executor/execExpr.c:1318 +#, c-format +msgid "target type is not an array" +msgstr "対象型は配列ではありません" + +#: executor/execExpr.c:1651 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW()列の型が%2$sではなく%1$sです" + +#: executor/execExpr.c:2176 executor/execSRF.c:708 parser/parse_func.c:135 parser/parse_func.c:646 parser/parse_func.c:1020 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "関数に%dを超える引数を渡せません" +msgstr[1] "関数に%dを超える引数を渡せません" + +#: executor/execExpr.c:2587 executor/execExpr.c:2593 executor/execExprInterp.c:2730 utils/adt/arrayfuncs.c:262 utils/adt/arrayfuncs.c:560 utils/adt/arrayfuncs.c:1302 utils/adt/arrayfuncs.c:3369 utils/adt/arrayfuncs.c:5329 utils/adt/arrayfuncs.c:5842 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "配列の次数(%d)が上限(%d)を超えています" + +#: executor/execExprInterp.c:1894 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "%2$s型の属性%1$dが削除されています" + +#: executor/execExprInterp.c:1900 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "型%2$sの属性%1$dの型が間違っています" + +#: executor/execExprInterp.c:1902 executor/execExprInterp.c:3002 executor/execExprInterp.c:3049 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "テーブルの型は%sですが、問い合わせでは%sを想定しています。" + +#: executor/execExprInterp.c:2494 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "このタイプのテーブルではWHERE CURRENT OFをサポートしません" + +#: executor/execExprInterp.c:2708 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "互換性がない配列をマージできません" + +#: executor/execExprInterp.c:2709 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "要素型%sの配列を要素型%sのARRAY式に含められません" + +#: executor/execExprInterp.c:2750 executor/execExprInterp.c:2780 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "多次元配列の配列式の次数があっていなければなりません" + +#: executor/execExprInterp.c:3001 executor/execExprInterp.c:3048 +#, c-format +msgid "attribute %d has wrong type" +msgstr "属性%dの型が間違っています" + +#: executor/execExprInterp.c:3158 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "代入における配列の添え字はnullにはできません" + +#: executor/execExprInterp.c:3588 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "ドメイン%sはnull値を許しません" + +#: executor/execExprInterp.c:3603 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "ドメイン%sの値が検査制約\"%s\"に違反しています" + +#: executor/execExprInterp.c:3973 executor/execExprInterp.c:3990 executor/execExprInterp.c:4091 executor/nodeModifyTable.c:109 executor/nodeModifyTable.c:120 executor/nodeModifyTable.c:137 executor/nodeModifyTable.c:145 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "テーブルの行型と問い合わせで指定した行型が一致しません" + +#: executor/execExprInterp.c:3974 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "テーブル行には%d属性ありますが、問い合わせでは%dを想定しています。" +msgstr[1] "テーブル行には%d属性ありますが、問い合わせでは%dを想定しています。" + +#: executor/execExprInterp.c:3991 executor/nodeModifyTable.c:121 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "テーブルでは %2$d 番目の型は %1$s ですが、問い合わせでは %3$s を想定しています。" + +#: executor/execExprInterp.c:4092 executor/execSRF.c:967 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "序数位置%dの削除された属性における物理格納形式が一致しません。" + +#: executor/execIndexing.c:550 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "ON CONFLICT は遅延可なユニーク制約/排除制約の調停主体としての指定をサポートしません" + +#: executor/execIndexing.c:821 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "排除制約\"%s\"を作成できませんでした" + +#: executor/execIndexing.c:824 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "キー %s がキー %s と競合しています" + +#: executor/execIndexing.c:826 +#, c-format +msgid "Key conflicts exist." +msgstr "キーの競合が存在します" + +#: executor/execIndexing.c:832 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "重複キーの値が排除制約\"%s\"に違反しています" + +#: executor/execIndexing.c:835 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "キー %s が既存のキー %s と競合しています" + +#: executor/execIndexing.c:837 +#, c-format +msgid "Key conflicts with existing key." +msgstr "キーが既存のキーと衝突しています" + +#: executor/execMain.c:1091 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "シーケンス\"%s\"を変更できません" + +#: executor/execMain.c:1097 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "TOASTリレーション\"%s\"を変更できません" + +#: executor/execMain.c:1115 rewrite/rewriteHandler.c:2934 rewrite/rewriteHandler.c:3708 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "ビュー\"%s\"へは挿入(INSERT)できません" + +#: executor/execMain.c:1117 rewrite/rewriteHandler.c:2937 rewrite/rewriteHandler.c:3711 +#, c-format +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "ビューへの挿入を可能にするために、INSTEAD OF INSERTトリガまたは無条件のON INSERT DO INSTEADルールを作成してください。" + +#: executor/execMain.c:1123 rewrite/rewriteHandler.c:2942 rewrite/rewriteHandler.c:3716 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "ビュー\"%s\"は更新できません" + +#: executor/execMain.c:1125 rewrite/rewriteHandler.c:2945 rewrite/rewriteHandler.c:3719 +#, c-format +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "ビューへの更新を可能にするために、INSTEAD OF UPDATEトリガまたは無条件のON UPDATE DO INSTEADルールを作成してください。" + +#: executor/execMain.c:1131 rewrite/rewriteHandler.c:2950 rewrite/rewriteHandler.c:3724 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "ビュー\"%s\"からは削除できません" + +#: executor/execMain.c:1133 rewrite/rewriteHandler.c:2953 rewrite/rewriteHandler.c:3727 +#, c-format +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "ビューからの削除を可能にするために、INSTEAD OF DELETEトリガまたは無条件のON DELETE DO INSTEADルールを作成してください。" + +#: executor/execMain.c:1144 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "実体化ビュー\"%s\"を変更できません" + +#: executor/execMain.c:1156 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "外部テーブル\"%s\"への挿入ができません" + +#: executor/execMain.c:1162 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "外部テーブル\"%s\"は挿入を許しません" + +#: executor/execMain.c:1169 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "外部テーブル \"%s\"の更新ができません" + +#: executor/execMain.c:1175 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "外部テーブル\"%s\"は更新を許しません" + +#: executor/execMain.c:1182 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "外部テーブル\"%s\"からの削除ができません" + +#: executor/execMain.c:1188 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "外部テーブル\"%s\"は削除を許しません" + +#: executor/execMain.c:1199 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "リレーション\"%s\"を変更できません" + +#: executor/execMain.c:1226 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "シーケンス\"%s\"では行のロックはできません" + +#: executor/execMain.c:1233 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "TOAST リレーション\"%s\"では行のロックはできません" + +#: executor/execMain.c:1240 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "ビュー\"%s\"では行のロックはできません" + +#: executor/execMain.c:1248 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "実体化ビュー\"%s\"では行のロックはできません" + +#: executor/execMain.c:1257 executor/execMain.c:2627 executor/nodeLockRows.c:132 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "外部テーブル\"%s\"では行のロックはできません" + +#: executor/execMain.c:1263 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "リレーション\"%s\"では行のロックはできません" + +#: executor/execMain.c:1879 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "リレーション\"%s\"の新しい行はパーティション制約に違反しています" + +#: executor/execMain.c:1881 executor/execMain.c:1964 executor/execMain.c:2012 executor/execMain.c:2120 +#, c-format +msgid "Failing row contains %s." +msgstr "失敗した行は%sを含みます" + +#: executor/execMain.c:1961 +#, c-format +msgid "null value in column \"%s\" of relation \"%s\" violates not-null constraint" +msgstr "リレーション\"%2$s\"の列\"%1$s\"のNULL値がが非NULL制約に違反しています" + +#: executor/execMain.c:2010 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "リレーション\"%s\"の新しい行は検査制約\"%s\"に違反しています" + +#: executor/execMain.c:2118 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "新しい行はビュー\"%s\"のチェックオプションに違反しています" + +#: executor/execMain.c:2128 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "新しい行はテーブル\"%2$s\"行レベルセキュリティポリシ\"%1$s\"に違反しています" + +#: executor/execMain.c:2133 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "新しい行はテーブル\"%s\"の行レベルセキュリティポリシに違反しています" + +#: executor/execMain.c:2140 +#, c-format +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "新しい行はテーブル\"%1$s\"の行レベルセキュリティポリシ\"%2$s\"(USING式)に違反しています" + +#: executor/execMain.c:2145 +#, c-format +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "新しい行はテーブル\"%s\"の行レベルセキュリティポリシ(USING式)に違反しています" + +#: executor/execPartition.c:345 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "行に対応するパーティションがリレーション\"%s\"に見つかりません" + +#: executor/execPartition.c:348 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "失敗した行のパーティションキーは%sを含みます。" + +#: executor/execReplication.c:196 executor/execReplication.c:373 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "ロック対象のタプルは同時に行われた更新によって他の子テーブルに移動されています、再試行しています" + +#: executor/execReplication.c:200 executor/execReplication.c:377 +#, c-format +msgid "concurrent update, retrying" +msgstr "同時更新がありました、リトライします" + +#: executor/execReplication.c:206 executor/execReplication.c:383 +#, c-format +msgid "concurrent delete, retrying" +msgstr "並行する削除がありました、リトライします" + +#: executor/execReplication.c:269 parser/parse_oper.c:228 utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 utils/adt/arrayfuncs.c:3647 utils/adt/arrayfuncs.c:4167 utils/adt/arrayfuncs.c:6153 utils/adt/rowtypes.c:1202 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "型%sの等価性演算子を識別できませんでした" + +#: executor/execReplication.c:586 +#, c-format +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "テーブル\"%s\"は複製識別を持たずかつ更新を発行しているため、更新できません" + +#: executor/execReplication.c:588 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "テーブルの更新を可能にするには ALTER TABLE で REPLICA IDENTITY を設定してください。" + +#: executor/execReplication.c:592 +#, c-format +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "テーブル\"%s\"は複製識別がなくかつ削除を発行しているため、このテーブルでは行の削除ができません" + +#: executor/execReplication.c:594 +#, c-format +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "このテーブルでの行削除を可能にするには ALTER TABLE で REPLICA IDENTITY を設定してください。" + +#: executor/execReplication.c:613 executor/execReplication.c:621 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "リレーション\"%s.%s\"は論理レプリケーション先としては使用できません" + +#: executor/execReplication.c:615 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "\"%s.%s\"は外部テーブルです。" + +#: executor/execReplication.c:623 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "\"%s.%s\"はテーブルではありません" + +#: executor/execSRF.c:315 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "関数から戻された行はすべてが同じ行型ではありません" + +#: executor/execSRF.c:363 executor/execSRF.c:657 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "実体化モードのテーブル関数プロトコルに従っていません" + +#: executor/execSRF.c:370 executor/execSRF.c:675 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "識別できないテーブル関数のreturnMode: %d" + +#: executor/execSRF.c:884 +#, c-format +msgid "function returning setof record called in context that cannot accept type record" +msgstr "レコード集合を返す関数が、レコード型が受け付けられない文脈で呼び出されました" + +#: executor/execSRF.c:940 executor/execSRF.c:956 executor/execSRF.c:966 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "問い合わせが指定した戻り値の行と実際の関数の戻り値の行が一致しません" + +#: executor/execSRF.c:941 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "%d属性を持つ行が返されました。問い合わせでは%d個を想定しています。" +msgstr[1] "%d属性を持つ行が返されました。問い合わせでは%d個を想定しています。" + +#: executor/execSRF.c:957 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "序数位置%2$dの型%1$sが返されました。問い合わせでは%3$sを想定しています。" + +#: executor/execUtils.c:750 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "実体化ビュー\"%s\"にはデータが格納されていません" + +#: executor/execUtils.c:752 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "REFRESH MATERIALIZED VIEWコマンドを使用してください。" + +#: executor/functions.c:231 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "%sと宣言された引数の型を特定できませんでした" + +#: executor/functions.c:528 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "SQL関数の中ではクライアントとの間のCOPYはできません" + +#. translator: %s is a SQL statement name +#: executor/functions.c:534 +#, c-format +msgid "%s is not allowed in a SQL function" +msgstr "SQL関数では%sは許可されません" + +#. translator: %s is a SQL statement name +#: executor/functions.c:542 executor/spi.c:1587 executor/spi.c:2381 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "volatile関数以外では%sは許可されません" + +#: executor/functions.c:1430 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "SQL関数\"%s\"の行番号 %d" + +#: executor/functions.c:1456 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "SQL関数\"%s\"の起動中" + +#: executor/functions.c:1549 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "出力引数を持つプロシージャの呼び出しはSQL関数ではサポートされていません" + +#: executor/functions.c:1671 executor/functions.c:1708 executor/functions.c:1722 executor/functions.c:1812 executor/functions.c:1845 executor/functions.c:1859 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "%sを返すと宣言された関数において戻り値型が一致しません" + +#: executor/functions.c:1673 +#, c-format +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "関数の最後のステートメントは SELECT もしくは INSERT/UPDATE/DELETE RETURNING のいずれかである必要があります" + +#: executor/functions.c:1710 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "最後のステートメントはちょうど1列を返さなければなりません。" + +#: executor/functions.c:1724 +#, c-format +msgid "Actual return type is %s." +msgstr "実際の戻り値型は%sです。" + +#: executor/functions.c:1814 +#, c-format +msgid "Final statement returns too many columns." +msgstr "最後のステートメントが返す列が多すぎます。" + +#: executor/functions.c:1847 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "最後のステートメントが列%3$dで%2$sではなく%1$sを返しました。" + +#: executor/functions.c:1861 +#, c-format +msgid "Final statement returns too few columns." +msgstr "最後のステートメントが返す列が少なすぎます。" + +#: executor/functions.c:1889 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "戻り値型%sはSQL関数でサポートされていません" + +#: executor/nodeAgg.c:3076 executor/nodeAgg.c:3085 executor/nodeAgg.c:3097 +#, c-format +msgid "unexpected EOF for tape %d: requested %zu bytes, read %zu bytes" +msgstr "テープ%dに対する予期しないEOF: %zuバイト要求しましたが、%zuバイト読み込みました" + +#: executor/nodeAgg.c:4022 parser/parse_agg.c:655 parser/parse_agg.c:685 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "集約関数の呼び出しを入れ子にすることはできません" + +#: executor/nodeAgg.c:4230 executor/nodeWindowAgg.c:2836 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "集約%uは入力データ型と遷移用の型間で互換性が必要です" + +#: executor/nodeCustom.c:145 executor/nodeCustom.c:156 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "カスタムスキャン\"%s\"はMarkPosをサポートしていません" + +#: executor/nodeHashjoin.c:1046 executor/nodeHashjoin.c:1076 +#, c-format +msgid "could not rewind hash-join temporary file" +msgstr "ハッシュ結合用一時ファイルを巻き戻せませんでした" + +#: executor/nodeHashjoin.c:1272 executor/nodeHashjoin.c:1283 +#, c-format +msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgstr "ハッシュ結合用一時ファイルから読み取れませんでした: %2$zuバイト中%1$zuバイトしか読み込んでいません" + +#: executor/nodeIndexonlyscan.c:242 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "概算距離関数はインデックスオンリースキャンではサポートされていません" + +#: executor/nodeLimit.c:374 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET は負数であってはなりません" + +#: executor/nodeLimit.c:400 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT は負数であってはなりません" + +#: executor/nodeMergejoin.c:1570 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "RIGHT JOINはマージ結合可能な結合条件でのみサポートされています" + +#: executor/nodeMergejoin.c:1588 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "FULL JOINはマージ結合可能な結合条件でのみサポートされています" + +#: executor/nodeModifyTable.c:110 +#, c-format +msgid "Query has too many columns." +msgstr "問い合わせの列が多すぎます" + +#: executor/nodeModifyTable.c:138 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "問い合わせで %d 番目に削除される列の値を指定しています。" + +#: executor/nodeModifyTable.c:146 +#, c-format +msgid "Query has too few columns." +msgstr "問い合わせの列が少なすぎます。" + +#: executor/nodeModifyTable.c:839 executor/nodeModifyTable.c:913 +#, c-format +msgid "tuple to be deleted was already modified by an operation triggered by the current command" +msgstr "削除対象のタプルはすでに現在のコマンドによって引き起こされた操作によって変更されています" + +#: executor/nodeModifyTable.c:1220 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "不正な ON UPDATE 指定です" + +#: executor/nodeModifyTable.c:1221 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "結果タプルをもとのパーティションではなく異なるパーティションに追加しようとしました。" + +#: executor/nodeModifyTable.c:1592 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "ON CONFLICT DO UPDATE コマンドは行に再度影響を与えることはできません" + +#: executor/nodeModifyTable.c:1593 +#, c-format +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." +msgstr "同じコマンドでの挿入候補の行が同じ制約値を持つことがないようにしてください" + +#: executor/nodeSamplescan.c:259 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "TABLESAMPLEパラメータにnullは指定できません" + +#: executor/nodeSamplescan.c:271 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "TABLESAMPLE REPEATABLE パラメータにnullは指定できません" + +#: executor/nodeSubplan.c:346 executor/nodeSubplan.c:385 executor/nodeSubplan.c:1151 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "式として使用された副問い合わせが2行以上の行を返しました" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "名前空間URIにnullは指定できません" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "行フィルタ式はnullになってはなりません" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "列フィルタ式はnullになってはなりません" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "列\"%s\"のフィルタがnullです。" + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "列\"%s\"でnullは許可されません" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "移動集約の推移関数はnullを返却してはなりません" + +#: executor/nodeWindowAgg.c:2058 +#, c-format +msgid "frame starting offset must not be null" +msgstr "フレームの開始オフセットは NULL であってはなりません" + +#: executor/nodeWindowAgg.c:2071 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "フレームの開始オフセットは負数であってはなりません" + +#: executor/nodeWindowAgg.c:2083 +#, c-format +msgid "frame ending offset must not be null" +msgstr "フレームの終了オフセットは NULL であってはなりません" + +#: executor/nodeWindowAgg.c:2096 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "フレームの終了オフセットは負数であってはなりません" + +#: executor/nodeWindowAgg.c:2752 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "集約関数 %s はウィンドウ関数としての使用をサポートしていません" + +#: executor/spi.c:229 executor/spi.c:298 +#, c-format +msgid "invalid transaction termination" +msgstr "不正なトランザクション終了" + +#: executor/spi.c:243 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "サブトランザクションの実行中はコミットできません" + +#: executor/spi.c:304 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "サブトランザクションの実行中はロールバックできません" + +#: executor/spi.c:373 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "トランザクションは空でないSPIスタックを残しました" + +#: executor/spi.c:374 executor/spi.c:436 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "\"SPI_finish\"呼出の抜けを確認ください" + +#: executor/spi.c:435 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "サブトランザクションが空でないSPIスタックを残しました" + +#: executor/spi.c:1451 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "カーソルにマルチクエリの実行計画を開くことができません" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1456 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "カーソルで%s問い合わせを開くことができません" + +#: executor/spi.c:1561 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHAREはサポートされていません" + +#: executor/spi.c:1562 parser/analyze.c:2508 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "スクロール可能カーソルは読み取り専用である必要があります。" + +#: executor/spi.c:2699 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "SQL文 \"%s\"" + +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "共有メモリキューにタプルを送出できませんでした" + +#: foreign/foreign.c:220 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "\"%s\"に対するユーザマッピングが見つかりません" + +#: foreign/foreign.c:672 +#, c-format +msgid "invalid option \"%s\"" +msgstr "不正なオプション\"%s\"" + +#: foreign/foreign.c:673 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "この文脈で有効なオプション: %s" + +#: gram.y:1043 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD は今後サポートされません" + +#: gram.y:1044 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "UNENCRYPTED を削除してください。そうすれば替わりにパスワードを暗号化形式で格納します。" + +#: gram.y:1106 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "ロールオプション\"%s\"が認識できません" + +#: gram.y:1353 gram.y:1368 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTSんはスキーマ要素を含めることはできません" + +#: gram.y:1514 +#, c-format +msgid "current database cannot be changed" +msgstr "現在のデータベースを変更できません" + +#: gram.y:1638 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "タイムゾーンの間隔はHOURまたはHOUR TO MINUTEでなければなりません" + +#: gram.y:2191 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "列番号は1から%dまでの範囲でなければなりません" + +#: gram.y:2723 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "シーケンスのオプション\"%s\"はここではサポートされていません" + +#: gram.y:2752 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "ハッシュパーティションで法(除数)が2回以上指定されています" + +#: gram.y:2761 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "ハッシュパーティションで剰余が2回以上指定されています" + +#: gram.y:2768 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "ハッシュパーティションの境界条件\"%s\"が認識できません" + +#: gram.y:2776 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "ハッシュパーティションでは法(除数)の指定が必要です" + +#: gram.y:2780 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "ハッシュパーティションでは剰余の指定が必要です" + +#: gram.y:2981 gram.y:3014 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "STDIN/STDOUTはPROGRAMと同時に使用できません" + +#: gram.y:2987 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "COPY TO で WHERE 句は使用できません" + +#: gram.y:3319 gram.y:3326 gram.y:11411 gram.y:11419 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "一時テーブル作成におけるGLOBALは廃止予定です" + +#: gram.y:3566 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "生成カラムに対しては GENERATED ALWAYS の指定が必須です" + +#: gram.y:3832 utils/adt/ri_triggers.c:2007 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "MMATCH PARTIAL はまだ実装されていません" + +#: gram.y:4503 +#, c-format +msgid "CREATE EXTENSION ... FROM is no longer supported" +msgstr "CREATE EXTENSION ... FROM はすでにサポートされていません" + +#: gram.y:5166 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "認識できない行セキュリティオプション \"%s\"" + +#: gram.y:5167 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "現時点ではPERMISSIVEもしくはRESTRICTIVEポリシのみがサポートされています" + +#: gram.y:5280 +msgid "duplicate trigger events specified" +msgstr "重複したトリガーイベントが指定されました" + +#: gram.y:5421 parser/parse_utilcmd.c:3483 parser/parse_utilcmd.c:3509 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "INITIALLY DEFERREDと宣言された制約はDEFERRABLEでなければなりません" + +#: gram.y:5428 +#, c-format +msgid "conflicting constraint properties" +msgstr "制約属性の競合" + +#: gram.y:5524 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTIONはまだ実装されていません" + +#: gram.y:5907 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK はもはや必要とされません" + +#: gram.y:5908 +#, c-format +msgid "Update your data type." +msgstr "データ型を更新してください" + +#: gram.y:7595 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "集約は出力の引数を持つことができません" + +#: gram.y:7987 utils/adt/regproc.c:709 utils/adt/regproc.c:750 +#, c-format +msgid "missing argument" +msgstr "引数が足りません" + +#: gram.y:7988 utils/adt/regproc.c:710 utils/adt/regproc.c:751 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "単項演算子の存在しない引数を表すにはNONEを使用してください。" + +#: gram.y:9917 gram.y:9935 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTIONは再帰ビューではサポートされていません" + +#: gram.y:11543 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "LIMIT #,#構文は実装されていません" + +#: gram.y:11544 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "分割してLIMITとOFFSET句を使用してください" + +#: gram.y:11870 gram.y:11895 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "FROM句のVALUESには別名が必要です" + +#: gram.y:11871 gram.y:11896 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "例えば、FROM (VALUES ...) [AS] foo。" + +#: gram.y:11876 gram.y:11901 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "FROM句の副問い合わせには別名が必要です" + +#: gram.y:11877 gram.y:11902 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "例えば、FROM (SELECT ...) [AS] foo。" + +#: gram.y:12355 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "DEFAULT値は一つだけ指定可能です" + +#: gram.y:12364 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "列一つにつきPATH値は一つだけ指定可能です" + +#: gram.y:12373 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "列\"%s\"でNULL / NOT NULL宣言が衝突しているか重複しています" + +#: gram.y:12382 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "認識できない列オプション \"%s\"" + +#: gram.y:12636 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "浮動小数点数の型の精度は最低でも1ビット必要です" + +#: gram.y:12645 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "浮動小数点型の精度は54ビットより低くなければなりません" + +#: gram.y:13136 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "OVERLAPS式の左辺のパラメータ数が間違っています" + +#: gram.y:13141 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "OVERLAPS式の右辺のパラメータ数が間違っています" + +#: gram.y:13316 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "UNIQUE 述部はまだ実装されていません" + +#: gram.y:13679 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "複数のORDER BY句はWITHIN GROUPと一緒には使用できません" + +#: gram.y:13684 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "DISTINCT は WITHIN GROUP と同時には使えません" + +#: gram.y:13689 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "VARIADIC は WITHIN GROUP と同時には使えません" + +#: gram.y:14150 gram.y:14173 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "フレームの開始は UNBOUNDED FOLLOWING であってはなりません" + +#: gram.y:14155 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "次の行から始まるフレームは、現在行では終了できません" + +#: gram.y:14178 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "フレームの終了は UNBOUNDED PRECEDING であってはなりません" + +#: gram.y:14184 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "現在行から始まるフレームは、先行する行を含むことができません" + +#: gram.y:14191 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "次の行から始まるフレームは、先行する行を含むことができません" + +#: gram.y:14836 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "型修正子はパラメータ名を持つことはできません" + +#: gram.y:14842 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "型修正子はORDER BYを持つことはできません" + +#: gram.y:14907 gram.y:14914 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%sはここではロール名として使用できません" + +#: gram.y:15595 gram.y:15784 +msgid "improper use of \"*\"" +msgstr "\"*\"の使い方が不適切です" + +#: gram.y:15747 gram.y:15764 tsearch/spell.c:956 tsearch/spell.c:973 tsearch/spell.c:990 tsearch/spell.c:1007 tsearch/spell.c:1072 +#, c-format +msgid "syntax error" +msgstr "構文エラー" + +#: gram.y:15848 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "VARIADIC直接引数を使った順序集合集約は同じデータタイプのVARIADIC集約引数を一つ持つ必要があります" + +#: gram.y:15885 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "複数のORDER BY句は使用できません" + +#: gram.y:15896 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "複数のOFFSET句は使用できません" + +#: gram.y:15905 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "複数のLIMIT句は使用できません" + +#: gram.y:15914 +#, c-format +msgid "multiple limit options not allowed" +msgstr "複数のLIMITオプションは使用できません" + +#: gram.y:15918 +#, c-format +msgid "WITH TIES options can not be specified without ORDER BY clause" +msgstr "WITH TIESオプションORDER BY句と一緒に指定はできません" + +#: gram.y:15926 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "複数の WITH 句は使用できません" + +#: gram.y:16130 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "テーブル関数では OUT と INOUT 引数は使用できません" + +#: gram.y:16226 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "複数の COLLATE 句は使用できません" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16264 gram.y:16277 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "%s制約は遅延可能にはできません" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16290 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "%s制約をNOT VALIDとマークすることはできません" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16303 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "%s制約をNO INHERITをマークすることはできません" + +#: guc-file.l:316 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "ファイル\"%2$s\"、%3$u行の設定パラメータ\"%1$s\"は不明です" + +#: guc-file.l:353 utils/misc/guc.c:7036 utils/misc/guc.c:7230 utils/misc/guc.c:7320 utils/misc/guc.c:7410 utils/misc/guc.c:7518 utils/misc/guc.c:7613 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "パラメータ\"%s\"を変更するにはサーバの再起動が必要です" + +#: guc-file.l:389 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "パラメーター\"%s\"が設定ファイルから削除されました。デフォルト値に戻ります。" + +#: guc-file.l:455 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "パラメータ\"%s\"は\"%s\"に変更されました" + +#: guc-file.l:497 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "設定ファイル\"%s\"にはエラーがあります" + +#: guc-file.l:502 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "設定ファイル\"%s\"にはエラーがあります。影響がない変更は適用されました" + +#: guc-file.l:507 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "設定ファイル\"%s\"にはエラーがあります。変更は適用されませんでした" + +#: guc-file.l:579 +#, c-format +msgid "empty configuration file name: \"%s\"" +msgstr "空の設定ファイル名: \"%s\"" + +#: guc-file.l:596 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "設定ファイル\"%s\"をオープンできませんでした: 入れ子長が上限を超えています" + +#: guc-file.l:616 +#, c-format +msgid "configuration file recursion in \"%s\"" +msgstr "設定ファイル\"%s\"が再帰しています" + +#: guc-file.l:632 libpq/hba.c:2201 libpq/hba.c:2615 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "設定ファイル\"%s\"をオープンできませんでした: %m" + +#: guc-file.l:643 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "存在しない設定ファイル\"%s\"をスキップします" + +#: guc-file.l:897 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "ファイル\"%s\"の行%uの行末近辺で構文エラーがありました" + +#: guc-file.l:907 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "ファイル\"%s\"の行%uのトークン\"%s\"近辺で構文エラーがありました" + +#: guc-file.l:927 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "多くの構文エラーがありました。ファイル\"%s\"を断念します" + +#: guc-file.l:982 +#, c-format +msgid "empty configuration directory name: \"%s\"" +msgstr "空の設定ディレクトリ名: \"%s\"" + +#: guc-file.l:1001 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "設定ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: jit/jit.c:205 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:417 utils/fmgr/dfmgr.c:465 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "ファイル\"%s\"にアクセスできませんでした: %m" + +#: jit/llvm/llvmjit.c:595 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "所要時間: インライン化: %.3fs、最適化: %.3fs、出力: %.3fs" + +#: jsonpath_gram.y:528 jsonpath_scan.l:520 jsonpath_scan.l:531 jsonpath_scan.l:541 jsonpath_scan.l:583 utils/adt/encode.c:482 utils/adt/encode.c:547 utils/adt/jsonfuncs.c:619 utils/adt/varlena.c:319 utils/adt/varlena.c:360 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "%s型に対する不正な入力構文" + +#: jsonpath_gram.y:529 +#, c-format +msgid "unrecognized flag character \"%.*s\" in LIKE_REGEX predicate" +msgstr "LIKE_REGEX 述語の中に認識できないフラグ文字\"%.*s\"があります" + +#: jsonpath_gram.y:583 +#, c-format +msgid "XQuery \"x\" flag (expanded regular expressions) is not implemented" +msgstr "XQueryの\"x\"フラグ(拡張正規表現)は実装されていません" + +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:287 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "jsonpath の最後に %s があります" + +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:294 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "jsonpath 入力の\"%2$s\"または近くに %1$s があります" + +#: jsonpath_scan.l:499 utils/adt/jsonfuncs.c:613 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "サポートされないUnicodeエスケープシーケンス" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "サイズ%zuの動的共有エリアの要求に失敗しました。" + +#: libpq/auth-scram.c:248 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "クライアントが無効なSASL認証機構を選択しました" + +#: libpq/auth-scram.c:269 libpq/auth-scram.c:509 libpq/auth-scram.c:520 +#, c-format +msgid "invalid SCRAM secret for user \"%s\"" +msgstr "ユーザ\"%s\"に対する不正なSCRAMシークレット" + +#: libpq/auth-scram.c:280 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM secret." +msgstr "ユーザ\"%s\"は有効なSCRAMシークレットを持ちません。" + +#: libpq/auth-scram.c:358 libpq/auth-scram.c:363 libpq/auth-scram.c:693 libpq/auth-scram.c:701 libpq/auth-scram.c:806 libpq/auth-scram.c:819 libpq/auth-scram.c:829 libpq/auth-scram.c:937 libpq/auth-scram.c:944 libpq/auth-scram.c:959 libpq/auth-scram.c:974 libpq/auth-scram.c:988 libpq/auth-scram.c:1006 libpq/auth-scram.c:1021 libpq/auth-scram.c:1321 libpq/auth-scram.c:1329 +#, c-format +msgid "malformed SCRAM message" +msgstr "不正なフォーマットのSCRAMメッセージです" + +#: libpq/auth-scram.c:359 +#, c-format +msgid "The message is empty." +msgstr "メッセージが空です。" + +#: libpq/auth-scram.c:364 +#, c-format +msgid "Message length does not match input length." +msgstr "メッセージの長さが入力の長さと一致しません" + +#: libpq/auth-scram.c:396 +#, c-format +msgid "invalid SCRAM response" +msgstr "不正なSCRAM応答" + +#: libpq/auth-scram.c:397 +#, c-format +msgid "Nonce does not match." +msgstr "Nonce が合致しません" + +#: libpq/auth-scram.c:471 +#, c-format +msgid "could not generate random salt" +msgstr "乱数ソルトを生成できませんでした" + +#: libpq/auth-scram.c:694 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "属性\"%c\"を想定していましたが、\"%s\"でした。" + +#: libpq/auth-scram.c:702 libpq/auth-scram.c:830 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "属性\"%c\"としては文字\"=\"を想定していました。" + +#: libpq/auth-scram.c:807 +#, c-format +msgid "Attribute expected, but found end of string." +msgstr "属性を想定しましたが、文字列が終了しました。" + +#: libpq/auth-scram.c:820 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "属性を想定しましたが、不正な文字\"%s\"でした。" + +#: libpq/auth-scram.c:938 libpq/auth-scram.c:960 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "クライアントは SCRAM-SHA-256-PLUS を選択しましたが、SCRAM メッセージにはチャネルバインディング情報が含まれていません。" + +#: libpq/auth-scram.c:945 libpq/auth-scram.c:975 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "カンマを想定していましたが、文字\"%s\"が見つかりました" + +#: libpq/auth-scram.c:966 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "SCRAM チャネルバインディングのネゴシエーションエラー" + +#: libpq/auth-scram.c:967 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "クライアントは SCRAM チャネルバインディングをサポートしていますが、サーバではサポートされていないと思っています。しかし実際にはサポートしています。" + +#: libpq/auth-scram.c:989 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "クライアントはチャネルバインディングなしの SCRAM-SHA-256 を選択しましたが、SCRAM メッセージにはチャネルバインディング情報が含まれています。" + +#: libpq/auth-scram.c:1000 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "SCRAM チャネルバインディングタイプ \"%s\"はサポートされていません" + +#: libpq/auth-scram.c:1007 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "予期しないチャネル割り当てフラグ \"%s\"" + +#: libpq/auth-scram.c:1017 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "クライアントは認証識別子を使っていますがサポートされていません" + +#: libpq/auth-scram.c:1022 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "client-fist-message での想定外の属性\"%s\"" + +#: libpq/auth-scram.c:1038 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "クライアントはサポート外のSCRAM拡張を要求しています" + +#: libpq/auth-scram.c:1052 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "SCRAM nonce の中に表示不能な文字があります" + +#: libpq/auth-scram.c:1169 +#, c-format +msgid "could not generate random nonce" +msgstr "乱数nonceを生成できませんでした" + +#: libpq/auth-scram.c:1179 +#, c-format +msgid "could not encode random nonce" +msgstr "乱数nonceをエンコードできませんでした" + +#: libpq/auth-scram.c:1285 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "SCRAM チャネルバインディングの確認で失敗しました" + +#: libpq/auth-scram.c:1303 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "client-final-message 中に想定外の SCRAM channel-binding 属性がありました" + +#: libpq/auth-scram.c:1322 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "client-final-message 中の proof の形式が不正です" + +#: libpq/auth-scram.c:1330 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "client-final-message の終端に不要なデータがあります。" + +#: libpq/auth.c:280 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "ユーザ\"%s\"の認証に失敗しました: ホストを拒絶しました" + +#: libpq/auth.c:283 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"の\"trust\"認証に失敗しました" + +#: libpq/auth.c:286 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"のIdent認証に失敗しました" + +#: libpq/auth.c:289 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"で対向(peer)認証に失敗しました" + +#: libpq/auth.c:294 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"のパスワード認証に失敗しました" + +#: libpq/auth.c:299 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"のGSSAPI認証に失敗しました" + +#: libpq/auth.c:302 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"のSSPI認証に失敗しました" + +#: libpq/auth.c:305 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"のPAM認証に失敗しました" + +#: libpq/auth.c:308 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"のBSD認証に失敗しました" + +#: libpq/auth.c:311 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"のLDAP認証に失敗しました" + +#: libpq/auth.c:314 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"の証明書認証に失敗しました" + +#: libpq/auth.c:317 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"の RADIUS 認証に失敗しました" + +#: libpq/auth.c:320 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "ユーザ\"%s\"の認証に失敗しました: 認証方式が不正です" + +#: libpq/auth.c:324 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "接続はpg_hba.confの行%dに一致しました: \"%s\"" + +#: libpq/auth.c:371 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "クライアント証明書はルート証明書ストアが利用できる場合にのみ検証されます" + +#: libpq/auth.c:382 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "この接続には有効なクライアント証明が必要です" + +#: libpq/auth.c:392 +#, c-format +msgid "GSSAPI encryption can only be used with gss, trust, or reject authentication methods" +msgstr "GSSAPI暗号化は gss、trust および reject 認証方式のみで使用できます" + +#: libpq/auth.c:426 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "pg_hba.conf の設定でホスト \"%s\"、ユーザ \"%s\", %s 用のレプリケーション接続を拒否しました" + +#: libpq/auth.c:428 libpq/auth.c:444 libpq/auth.c:502 libpq/auth.c:520 +msgid "SSL off" +msgstr "SSL無効" + +#: libpq/auth.c:428 libpq/auth.c:444 libpq/auth.c:502 libpq/auth.c:520 +msgid "SSL on" +msgstr "SSL有効" + +#: libpq/auth.c:432 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +msgstr "pg_hba.conf の設定でホスト \"%s\"、ユーザ \"%s\"用のレプリケーション接続を拒否しました" + +#: libpq/auth.c:441 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf の設定でホスト \"%s\"、ユーザ \"%s\"、データベース \"%s\", %sの接続を拒否しました" + +#: libpq/auth.c:448 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +msgstr "pg_hba.conf の設定でホスト\"%s\"、ユーザ\"%s\"、データベース\"%s\"用のレプリケーション接続を拒否しました" + +#: libpq/auth.c:477 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "クライアントIPアドレスは\"%s\"に解決され、前方検索と一致しました。" + +#: libpq/auth.c:480 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "クライアントIPアドレスは\"%s\"に解決されました。前方検索は検査されません。" + +#: libpq/auth.c:483 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "クライアントIPアドレスは\"%s\"に解決され、前方検索と一致しませんでした。" + +#: libpq/auth.c:486 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "クライアントのホスト名\"%s\"をIPアドレスに変換できませんでした: %s。" + +#: libpq/auth.c:491 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "クライアントのIPアドレスをホスト名に解決できませんでした: %s。" + +#: libpq/auth.c:500 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "pg_hba.conf にホスト\"%s\"、ユーザ\"%s\", %s用のエントリがありません" + +#: libpq/auth.c:507 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +msgstr "pg_hba.conf にホスト\"%s\"、ユーザ\"%s\"用のエントリがありません" + +#: libpq/auth.c:517 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf にホスト\"%s\"、ユーザ\"%s\"、データベース\"%s, %s用のエントリがありません" + +#: libpq/auth.c:525 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +msgstr "pg_hba.conf にホスト\"%s\"、ユーザ\"%s\"、データベース\"%s用のエントリがありません" + +#: libpq/auth.c:688 +#, c-format +msgid "expected password response, got message type %d" +msgstr "パスワード応答を想定しましたが、メッセージタイプ%dを受け取りました" + +#: libpq/auth.c:716 +#, c-format +msgid "invalid password packet size" +msgstr "パスワードパケットのサイズが不正です" + +#: libpq/auth.c:734 +#, c-format +msgid "empty password returned by client" +msgstr "クライアントから空のパスワードが返されました" + +#: libpq/auth.c:854 libpq/hba.c:1340 +#, c-format +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "\"db_user_namespace\"が有効の場合、MD5 認証はサポートされません" + +#: libpq/auth.c:860 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "ランダムなMD5ソルトの生成に失敗しました" + +#: libpq/auth.c:906 +#, c-format +msgid "SASL authentication is not supported in protocol version 2" +msgstr "プロトコルバージョン2ではSASL認証はサポートされていません" + +#: libpq/auth.c:939 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "SASL応答を想定していましたが、メッセージタイプ%dを受け取りました" + +#: libpq/auth.c:1068 +#, c-format +msgid "GSSAPI is not supported in protocol version 2" +msgstr "プロトコルバージョン 2 では GSSAPI はサポートされていません" + +#: libpq/auth.c:1128 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "GSS応答を想定しましたが、メッセージタイプ %d を受け取りました" + +#: libpq/auth.c:1189 +msgid "accepting GSS security context failed" +msgstr "GSSセキュリティコンテキストの受け付けに失敗しました" + +#: libpq/auth.c:1228 +msgid "retrieving GSS user name failed" +msgstr "GSSユーザ名の受信に失敗しました" + +#: libpq/auth.c:1359 +#, c-format +msgid "SSPI is not supported in protocol version 2" +msgstr "プロトコルバージョン 2 では SSPI はサポートされていません" + +#: libpq/auth.c:1374 +msgid "could not acquire SSPI credentials" +msgstr "SSPIの資格ハンドルを入手できませんでした" + +#: libpq/auth.c:1399 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "SSPI応答を想定しましたが、メッセージタイプ%dを受け取りました" + +#: libpq/auth.c:1477 +msgid "could not accept SSPI security context" +msgstr "SSPIセキュリティコンテキストを受け付けられませんでした" + +#: libpq/auth.c:1539 +msgid "could not get token from SSPI security context" +msgstr "SSPIセキュリティコンテキストからトークンを入手できませんでした" + +#: libpq/auth.c:1658 libpq/auth.c:1677 +#, c-format +msgid "could not translate name" +msgstr "名前の変換ができませんでした" + +#: libpq/auth.c:1690 +#, c-format +msgid "realm name too long" +msgstr "realm名が長すぎます" + +#: libpq/auth.c:1705 +#, c-format +msgid "translated account name too long" +msgstr "変換後のアカウント名が長すぎます" + +#: libpq/auth.c:1886 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "Ident接続用のソケットを作成できませんでした: %m" + +#: libpq/auth.c:1901 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "ローカルアドレス\"%s\"にバインドできませんでした: %m" + +#: libpq/auth.c:1913 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "アドレス\"%s\"、ポート%sのIdentサーバに接続できませんでした: %m" + +#: libpq/auth.c:1935 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "アドレス\"%s\"、ポート%sのIdentサーバに問い合わせを送信できませんでした: %m" + +#: libpq/auth.c:1952 +#, c-format +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "アドレス\"%s\"、ポート%sのIdentサーバからの応答を受信できませんでした: %m" + +#: libpq/auth.c:1962 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "Identサーバからの応答の書式が不正です: \"%s\"" + +#: libpq/auth.c:2009 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "このプラットフォームでは対向(peer)認証はサポートされていません" + +#: libpq/auth.c:2013 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "ピアの資格証明を入手できませんでした: %m" + +#: libpq/auth.c:2025 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "ローカルユーザID %ldの参照に失敗しました: %s" + +#: libpq/auth.c:2124 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "背後のPAM層でエラーがありました: %s" + +#: libpq/auth.c:2194 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "PAM authenticatorを作成できませんでした: %s" + +#: libpq/auth.c:2205 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER)が失敗しました: %s" + +#: libpq/auth.c:2237 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST)が失敗しました: %s" + +#: libpq/auth.c:2249 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "\"pam_set_item(PAM_CONV)が失敗しました: %s" + +#: libpq/auth.c:2262 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "\"pam_authenticateが失敗しました: %s" + +#: libpq/auth.c:2275 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmtが失敗しました: %s" + +#: libpq/auth.c:2286 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "PAM authenticatorを解放できませんでした: %s" + +#: libpq/auth.c:2362 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "LDAPを初期化できませんでした: %d" + +#: libpq/auth.c:2399 +#, c-format +msgid "could not extract domain name from ldapbasedn" +msgstr "ldapbasedn からドメイン名を抽出できませんでした" + +#: libpq/auth.c:2407 +#, c-format +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "LDAP認証で\"%s\"に対する DNS SRV レコードが見つかりませんでした" + +#: libpq/auth.c:2409 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "LDAPサーバ名を明示的に指定してください。" + +#: libpq/auth.c:2461 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "LDAPを初期化できませんでした: %s" + +#: libpq/auth.c:2471 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "この LDAP ライブラリでは ldaps はサポートされていません" + +#: libpq/auth.c:2479 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "LDAPを初期化できませんでした: %m" + +#: libpq/auth.c:2489 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "LDAPプロトコルバージョンを設定できませんでした: %s" + +#: libpq/auth.c:2529 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "wldap32.dllの_ldap_start_tls_sA関数を読み込みできませんでした" + +#: libpq/auth.c:2530 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "このプラットフォームではLDAP over SSLをサポートしていません。" + +#: libpq/auth.c:2546 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "LDAP TLSセッションを開始できませんでした: %s" + +#: libpq/auth.c:2617 +#, c-format +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "LDAP サーバも ldapbasedn も指定されていません" + +#: libpq/auth.c:2624 +#, c-format +msgid "LDAP server not specified" +msgstr "LDAP サーバの指定がありません" + +#: libpq/auth.c:2686 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "LDAP 認証でユーザ名の中に不正な文字があります" + +#: libpq/auth.c:2703 +#, c-format +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "サーバ\"%2$s\"で、ldapbinddn \"%1$s\"によるLDAPバインドを実行できませんでした: %3$s" + +#: libpq/auth.c:2732 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "サーバ\"%2$s\"で、フィルタ\"%1$s\"によるLDAP検索ができませんでした: %3$s" + +#: libpq/auth.c:2746 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "LDAPサーバ\"%s\"は存在しません" + +#: libpq/auth.c:2747 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "サーバ\"%2$s\"で、フィルタ\"%1$s\"によるLDAP検索が何も返しませんでした。" + +#: libpq/auth.c:2751 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "LDAPユーザ\"%s\"は一意ではありません" + +#: libpq/auth.c:2752 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "サーバ\"%2$s\"で、フィルタ\"%1$s\"によるLDAP検索が%3$d項目返しました。" +msgstr[1] "サーバ\"%2$s\"で、フィルタ\"%1$s\"によるLDAP検索が%3$d項目返しました。" + +#: libpq/auth.c:2772 +#, c-format +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "サーバ\"%2$s\"で\"%1$s\"にマッチする最初のエントリの dn を取得できません: %3$s" + +#: libpq/auth.c:2793 +#, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "サーバ\"%2$s\"でユーザ\"%1$s\"の検索後、unbindできませんでした" + +#: libpq/auth.c:2824 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "サーバ\"%2$s\"でユーザ\"%1$s\"のLDAPログインが失敗しました: %3$s" + +#: libpq/auth.c:2853 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "LDAP診断: %s" + +#: libpq/auth.c:2880 +#, c-format +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "ユーザ \"%s\" の証明書認証に失敗しました: クライアント証明書にユーザ名が含まれていません" + +#: libpq/auth.c:2897 +#, c-format +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" +msgstr "ユーザ\"%s\"に対する証明書の検証(clientcert=verify-full) に失敗しました: CN 不一致" + +#: libpq/auth.c:2998 +#, c-format +msgid "RADIUS server not specified" +msgstr "RADIUS サーバが指定されていません" + +#: libpq/auth.c:3005 +#, c-format +msgid "RADIUS secret not specified" +msgstr "RADIUS secret が指定されていません" + +#: libpq/auth.c:3019 +#, c-format +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "RADIUS認証では%d文字より長いパスワードはサポートしていません" + +#: libpq/auth.c:3124 libpq/hba.c:1956 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "RADIUS サーバ名\"%s\"をアドレスに変換できませんでした: %s" + +#: libpq/auth.c:3138 +#, c-format +msgid "could not generate random encryption vector" +msgstr "ランダムな暗号化ベクトルを生成できませんでした" + +#: libpq/auth.c:3172 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "パスワードのMD5暗号化に失敗しました" + +#: libpq/auth.c:3198 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "RADIUSのソケットを作成できませんでした: %m" + +#: libpq/auth.c:3220 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "ローカルの RADIUS ソケットをバインドできませんでした: %m" + +#: libpq/auth.c:3230 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "RADIUS パケットを送信できませんでした: %m" + +#: libpq/auth.c:3263 libpq/auth.c:3289 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "%sからのRADIUSの応答待ちがタイムアウトしました" + +#: libpq/auth.c:3282 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "RADIUSソケットの状態をチェックできませんでした: %m" + +#: libpq/auth.c:3312 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "RADIUS応答を読めませんでした: %m" + +#: libpq/auth.c:3325 libpq/auth.c:3329 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "%sからのRADIUS応答が誤ったポートから送られてきました: %d" + +#: libpq/auth.c:3338 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "%sからのRADIUS応答が短すぎます: %d" + +#: libpq/auth.c:3345 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "%sからのRADIUS応答が間違った長さを保持しています: %d(実際の長さは%d)" + +#: libpq/auth.c:3353 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "%sからのRADIUS応答は異なるリクエストに対するものです: %d (%d であるはず)" + +#: libpq/auth.c:3378 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "受信パケットのMD5暗号化に失敗しました" + +#: libpq/auth.c:3387 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "%sからのRADIUS応答が間違ったMD5シグネチャを保持しています" + +#: libpq/auth.c:3405 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "%1$sからのRADIUS応答がユーザ\"%3$s\"にとって不正なコード(%2$d)を保持しています" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:553 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "ラージオブジェクト記述子が不正です: %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "ラージオブジェクト記述子 %d は読み込み用にオープンされていませんでした" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:560 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "ラージオブジェクト記述子%dは書き込み用に開かれていませんでした" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "lo_lseekの結果がラージオブジェクト記述子の範囲%dを超えています" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "lo_tellの結果がラージオブジェクト記述子の範囲%dを超えています" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "サーバファイル\"%s\"をオープンできませんでした: %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "サーバファイル\"%s\"を読み取れませんでした: %m" + +#: libpq/be-fsstubs.c:514 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "サーバファイル\"%s\"を作成できませんでした: %m" + +#: libpq/be-fsstubs.c:526 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "サーバファイル\"%s\"を書き出せませんでした: %m" + +#: libpq/be-fsstubs.c:760 +#, c-format +msgid "large object read request is too large" +msgstr "ラージオブジェクトの読み込み要求が大きすぎます" + +#: libpq/be-fsstubs.c:802 utils/adt/genfile.c:265 utils/adt/genfile.c:304 utils/adt/genfile.c:340 +#, c-format +msgid "requested length cannot be negative" +msgstr "負の長さを指定することはできません" + +#: libpq/be-fsstubs.c:855 storage/large_object/inv_api.c:297 storage/large_object/inv_api.c:309 storage/large_object/inv_api.c:513 storage/large_object/inv_api.c:624 storage/large_object/inv_api.c:814 +#, c-format +msgid "permission denied for large object %u" +msgstr "ラージオブジェクト %u に対する権限がありません" + +#: libpq/be-secure-common.c:93 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "コマンド\"%s\"から読み取れませんでした: %m" + +#: libpq/be-secure-common.c:113 +#, c-format +msgid "command \"%s\" failed" +msgstr "コマンド\"%s\"の実行に失敗しました" + +#: libpq/be-secure-common.c:141 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "秘密キーファイル\"%s\"にアクセスできませんでした: %m" + +#: libpq/be-secure-common.c:150 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "秘密キーファイル\"%s\"は通常のファイルではありません" + +#: libpq/be-secure-common.c:165 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "秘密キーファイル\"%s\"はデータベースユーザもしくはrootの所有である必要があります" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "秘密キーファイル\"%s\"はグループまたは全員からアクセス可能です" + +#: libpq/be-secure-common.c:190 +#, c-format +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "ファイルはデータベースユーザの所有の場合は u=rw (0600) かそれよりも低いパーミッション、root所有の場合は u=rw,g=r (0640) かそれよりも低いパーミッションである必要があります" + +#: libpq/be-secure-gssapi.c:195 +msgid "GSSAPI wrap error" +msgstr "GSSAPI名ラップエラー" + +#: libpq/be-secure-gssapi.c:199 +#, c-format +msgid "outgoing GSSAPI message would not use confidentiality" +msgstr "送出されるGSSAPIメッセージに機密性が適用されません" + +#: libpq/be-secure-gssapi.c:203 libpq/be-secure-gssapi.c:574 +#, c-format +msgid "server tried to send oversize GSSAPI packet (%zu > %zu)" +msgstr "サーバは過大なサイズのGSSAPIパケットを送信しようとしました: (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:330 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "過大なサイズのGSSAPIパケットがクライアントから送出されました: (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:364 +msgid "GSSAPI unwrap error" +msgstr "GSSAPIアンラップエラー" + +#: libpq/be-secure-gssapi.c:369 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "到着したGSSAPIメッセージには機密性が適用されていません" + +#: libpq/be-secure-gssapi.c:525 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "過大なサイズのGSSAPIパケットがクライアントから送出されました: (%zu > %d)" + +#: libpq/be-secure-gssapi.c:547 +msgid "could not accept GSSAPI security context" +msgstr "GSSAPIセキュリティコンテキストを受け入れられませんでした" + +#: libpq/be-secure-gssapi.c:637 +msgid "GSSAPI size check error" +msgstr "GSSAPIサイズチェックエラー" + +#: libpq/be-secure-openssl.c:112 +#, c-format +msgid "could not create SSL context: %s" +msgstr "SSLコンテキストを作成できませんでした: %s" + +#: libpq/be-secure-openssl.c:138 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "サーバ証明書ファイル\"%s\"をロードできませんでした: %s" + +#: libpq/be-secure-openssl.c:158 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "パスフレーズが要求されたため秘密キーファイル\"%s\"をリロードできませんでした" + +#: libpq/be-secure-openssl.c:163 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "秘密キーファイル\"%s\"をロードできませんでした: %s" + +#: libpq/be-secure-openssl.c:172 +#, c-format +msgid "check of private key failed: %s" +msgstr "秘密キーの検査に失敗しました: %s" + +#: libpq/be-secure-openssl.c:184 libpq/be-secure-openssl.c:206 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "このビルドでは\"%s\"を\"%s\"に設定することはできません" + +#: libpq/be-secure-openssl.c:194 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "SSLプロトコルバージョンを設定できませんでした" + +#: libpq/be-secure-openssl.c:216 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "最大SSLプロトコルバージョンを設定できませんでした" + +#: libpq/be-secure-openssl.c:232 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "SSLプロトコルバージョンの範囲を設定できませんでした" + +#: libpq/be-secure-openssl.c:233 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "\"%s\"は\"%s\"より大きくできません" + +#: libpq/be-secure-openssl.c:257 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "暗号方式リストがセットできません (利用可能な暗号方式がありません)" + +#: libpq/be-secure-openssl.c:275 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "ルート証明書ファイル\"%s\"をロードできませんでした: %s" + +#: libpq/be-secure-openssl.c:302 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "SSL証明失効リストファイル\"%s\"をロードできませんでした: %s" + +#: libpq/be-secure-openssl.c:378 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "SSL接続を初期化できませんでした: SSLコンテクストが準備できていません" + +#: libpq/be-secure-openssl.c:386 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "SSL接続を初期化できませんでした: %s" + +#: libpq/be-secure-openssl.c:394 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "SSLソケットを設定できませんでした: %s" + +#: libpq/be-secure-openssl.c:449 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "SSL接続を受け付けられませんでした: %m" + +#: libpq/be-secure-openssl.c:453 libpq/be-secure-openssl.c:506 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "SSL接続を受け付けられませんでした: EOFを検出しました" + +#: libpq/be-secure-openssl.c:492 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "SSL接続を受け付けられませんでした: %s" + +#: libpq/be-secure-openssl.c:495 +#, c-format +msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." +msgstr "このことは、クライアントがSSLプロトコルのバージョン%sから%sのいずれもサポートしていないことを示唆しているかもしれません。" + +#: libpq/be-secure-openssl.c:511 libpq/be-secure-openssl.c:642 libpq/be-secure-openssl.c:706 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "認識できないSSLエラーコード: %d" + +#: libpq/be-secure-openssl.c:553 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "SSL 証明書のコモンネームに null が含まれています" + +#: libpq/be-secure-openssl.c:631 libpq/be-secure-openssl.c:690 +#, c-format +msgid "SSL error: %s" +msgstr "SSLエラー: %s" + +#: libpq/be-secure-openssl.c:871 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "DHパラメータファイル\"%s\"をオープンできませんでした: %m" + +#: libpq/be-secure-openssl.c:883 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "DHパラメータをロードできませんでした: %s" + +#: libpq/be-secure-openssl.c:893 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "不正なDHパラメータです: %s" + +#: libpq/be-secure-openssl.c:901 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "不正なDHパラメータ: pは素数ではありません" + +#: libpq/be-secure-openssl.c:909 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "不正なDHパラメータ: 適切な生成器も安全な素数もありません" + +#: libpq/be-secure-openssl.c:1065 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: DHパラメータをロードできませんでした" + +#: libpq/be-secure-openssl.c:1073 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: DHパラメータを設定できませんでした: %s" + +#: libpq/be-secure-openssl.c:1100 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: 認識できない曲線名: %s" + +#: libpq/be-secure-openssl.c:1109 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: キーを生成できませんでした" + +#: libpq/be-secure-openssl.c:1137 +msgid "no SSL error reported" +msgstr "SSLエラーはありませんでした" + +#: libpq/be-secure-openssl.c:1141 +#, c-format +msgid "SSL error code %lu" +msgstr "SSLエラーコード: %lu" + +#: libpq/be-secure.c:122 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "\"%s\"からのSSL接続" + +#: libpq/be-secure.c:207 libpq/be-secure.c:303 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "予期しないpostmasterの終了のため、コネクションを終了します" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "ロール\"%s\"は存在しません。" + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "ユーザ\"%s\"はパスワードが設定されていません。" + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "ユーザ\"%s\"のパスワードは期限切れです。" + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "ユーザ\"%s\"のパスワードはMD5認証で使用不能です。" + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "ユーザ\"%s\"のパスワードが合致しません。" + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "ユーザ\"%s\"のパスワードは識別不能な形式です。" + +#: libpq/hba.c:235 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "認証ファイルのトークンが長すぎますので、飛ばします: \"%s\"" + +#: libpq/hba.c:407 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "セカンダリ認証ファイル\"@%s\"を\"%s\"としてオープンできませんでした: %m" + +#: libpq/hba.c:509 +#, c-format +msgid "authentication file line too long" +msgstr "認証ファイルが長すぎます" + +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1013 libpq/hba.c:1022 libpq/hba.c:1035 libpq/hba.c:1056 libpq/hba.c:1069 libpq/hba.c:1089 libpq/hba.c:1111 libpq/hba.c:1123 libpq/hba.c:1179 libpq/hba.c:1199 libpq/hba.c:1213 libpq/hba.c:1232 libpq/hba.c:1243 libpq/hba.c:1258 libpq/hba.c:1276 libpq/hba.c:1292 libpq/hba.c:1304 libpq/hba.c:1341 libpq/hba.c:1382 libpq/hba.c:1395 libpq/hba.c:1417 +#: libpq/hba.c:1430 libpq/hba.c:1442 libpq/hba.c:1460 libpq/hba.c:1510 libpq/hba.c:1554 libpq/hba.c:1565 libpq/hba.c:1581 libpq/hba.c:1598 libpq/hba.c:1608 libpq/hba.c:1668 libpq/hba.c:1706 libpq/hba.c:1728 libpq/hba.c:1740 libpq/hba.c:1827 libpq/hba.c:1845 libpq/hba.c:1939 libpq/hba.c:1958 libpq/hba.c:1987 libpq/hba.c:2000 libpq/hba.c:2023 libpq/hba.c:2045 libpq/hba.c:2059 tsearch/ts_locale.c:190 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "設定ファイル \"%2$s\" の %1$d 行目" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:865 +#, c-format +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "認証オプション\"%s\"は認証方式%sでのみ有効です" + +#: libpq/hba.c:885 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "認証方式\"%s\"の場合は引数\"%s\"がセットされなければなりません" + +#: libpq/hba.c:913 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "ファイル\"%s\"の最終行%dでエントリが足りません" + +#: libpq/hba.c:924 +#, c-format +msgid "multiple values in ident field" +msgstr "identヂールド内の複数の値" + +#: libpq/hba.c:973 +#, c-format +msgid "multiple values specified for connection type" +msgstr "接続タイプで複数の値が指定されました" + +#: libpq/hba.c:974 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "1行に1つの接続タイプだけを指定してください" + +#: libpq/hba.c:988 +#, c-format +msgid "local connections are not supported by this build" +msgstr "このビルドではlocal接続はサポートされていません" + +#: libpq/hba.c:1011 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "SSLが無効なため、hostssl行は照合できません" + +#: libpq/hba.c:1012 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "postgresql.confで ssl = on に設定してください。" + +#: libpq/hba.c:1020 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "このビルドではhostsslはサポートされていないため、hostssl行は照合できません" + +#: libpq/hba.c:1021 +#, c-format +msgid "Compile with --with-openssl to use SSL connections." +msgstr "SSL 接続を有効にするには --with-openssl でコンパイルしてください。" + +#: libpq/hba.c:1033 +#, c-format +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "このビルドでは GSSAPI をサポートしていないため hostgssenc レコードは照合できません" + +#: libpq/hba.c:1034 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "GSSAPI 接続を有効にするには --with-gssapi でコンパイルしてください。" + +#: libpq/hba.c:1054 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "接続オプションタイプ \"%s\" は不正です" + +#: libpq/hba.c:1068 +#, c-format +msgid "end-of-line before database specification" +msgstr "データベース指定の前に行末を検出しました" + +#: libpq/hba.c:1088 +#, c-format +msgid "end-of-line before role specification" +msgstr "ロール指定の前に行末を検出しました" + +#: libpq/hba.c:1110 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "IP アドレス指定の前に行末を検出しました" + +#: libpq/hba.c:1121 +#, c-format +msgid "multiple values specified for host address" +msgstr "ホストアドレスで複数の値が指定されました" + +#: libpq/hba.c:1122 +#, c-format +msgid "Specify one address range per line." +msgstr "1行に1つのアドレス範囲を指定してください" + +#: libpq/hba.c:1177 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "不正なIPアドレス\"%s\": %s" + +#: libpq/hba.c:1197 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "ホスト名とCIDRマスクを両方指定するのは不正です: \"%s\"" + +#: libpq/hba.c:1211 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "IPアドレス\"%s\"内の CIDR マスクが不正です" + +#: libpq/hba.c:1230 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "ネットマスク指定の前に行末を検出しました" + +#: libpq/hba.c:1231 +#, c-format +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "CIDR記法でアドレス範囲を指定してするか、ネットマスクを分けて指定してください。" + +#: libpq/hba.c:1242 +#, c-format +msgid "multiple values specified for netmask" +msgstr "ネットマスクで複数の値が指定されました" + +#: libpq/hba.c:1256 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "不正なIPマスク\"%s\": %s" + +#: libpq/hba.c:1275 +#, c-format +msgid "IP address and mask do not match" +msgstr "IPアドレスとマスクが一致しません" + +#: libpq/hba.c:1291 +#, c-format +msgid "end-of-line before authentication method" +msgstr "認証方式指定の前に行末を検出しました" + +#: libpq/hba.c:1302 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "認証タイプで複数の値が指定されました" + +#: libpq/hba.c:1303 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "認証タイプは1行に1つだけ指定してください。" + +#: libpq/hba.c:1380 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "不正な認証方式\"%s\"" + +#: libpq/hba.c:1393 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "不正な認証方式\"%s\": このビルドではサポートされていません" + +#: libpq/hba.c:1416 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "ローカルソケットではgssapi認証はサポートしていません" + +#: libpq/hba.c:1429 +#, c-format +msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +msgstr "GSSAPI暗号化は gss、trust または reject 認証のみをサポートします" + +#: libpq/hba.c:1441 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "peer認証はローカルソケットでのみサポートしています" + +#: libpq/hba.c:1459 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "hostssl接続では証明書認証のみをサポートしています" + +#: libpq/hba.c:1509 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "認証オプションが 名前=値 形式になっていません: %s" + +#: libpq/hba.c:1553 +#, c-format +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ldapbasedn、 ldapbinddn、ldapbindpasswd、ldapsearchattribute、, ldapsearchfilter またはldapurlは、ldapprefixと同時には指定できません" + +#: libpq/hba.c:1564 +#, c-format +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "\"ldap\"認証方式の場合は引数 \"ldapbasedn\"、\"ldapprefix\"、\"ldapsuffix\"のいずれかを指定してください" + +#: libpq/hba.c:1580 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ldapsearchattribute、ldapsearchfilter と同時には指定できません" + +#: libpq/hba.c:1597 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "RADIUSサーバのリストは空にはできません" + +#: libpq/hba.c:1607 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "RADIUSシークレットのリストは空にはできません" + +#: libpq/hba.c:1662 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "%sの数(%d)は1または%sの数(%d)と同じである必要があります" + +# +#: libpq/hba.c:1696 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident、peer、gssapi、sspiおよびcert" + +#: libpq/hba.c:1705 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "クライアント証明書は\"hostssl\"の行でのみ設定できます" + +#: libpq/hba.c:1727 +#, c-format +msgid "clientcert can not be set to \"no-verify\" when using \"cert\" authentication" +msgstr "\"cert\"認証使用時はclientcertは\"no-verify\"には設定できません" + +#: libpq/hba.c:1739 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "clientcertの値が不正です: \"%s\"" + +#: libpq/hba.c:1773 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "LDAP URL\"%s\"をパースできませんでした: %s" + +#: libpq/hba.c:1784 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "非サポートのLDAP URLコード: %s" + +#: libpq/hba.c:1808 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "このプラットフォームではLDAP URLをサポートしていません。" + +#: libpq/hba.c:1826 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "不正な ldapscheme の値: \"%s\"" + +#: libpq/hba.c:1844 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "不正なLDAPポート番号です: \"%s\"" + +# +#: libpq/hba.c:1890 libpq/hba.c:1897 +msgid "gssapi and sspi" +msgstr "gssapiおよびsspi" + +#: libpq/hba.c:1906 libpq/hba.c:1915 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1937 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "RADIUSサーバのリスト\"%s\"のパースに失敗しました" + +#: libpq/hba.c:1985 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "RADIUSポートのリスト\"%s\"のパースに失敗しました" + +#: libpq/hba.c:1999 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "不正なRADIUSポート番号: \"%s\"" + +#: libpq/hba.c:2021 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "RADIUSシークレットのリスト\"%s\"のパースに失敗しました" + +#: libpq/hba.c:2043 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "RADIUS識別子のリスト\"%s\"のパースに失敗しました" + +#: libpq/hba.c:2057 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "認証オプション名を認識できません: \"%s\"" + +#: libpq/hba.c:2252 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "設定ファイル\"%s\"には何も含まれていません" + +#: libpq/hba.c:2770 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "不正な正規表現\"%s\": %s" + +#: libpq/hba.c:2830 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "正規表現\"%s\"で照合に失敗しました: %s" + +#: libpq/hba.c:2849 +#, c-format +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "正規表現\"%s\"には\"%s\"における後方参照が要求する副表現が含まれていません" + +#: libpq/hba.c:2945 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "与えられたユーザ名 (%s) と認証されたユーザ名 (%s) が一致しません" + +#: libpq/hba.c:2965 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "\"%3$s\"として認証されたユーザ\"%2$s\"はユーザマップ\"%1$s\"に一致しません" + +#: libpq/hba.c:2998 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "ユーザマップファイル\"%s\"をオープンできませんでした: %m" + +#: libpq/pqcomm.c:218 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "ソケットを非ブロッキングモードに設定できませんでした: %m" + +#: libpq/pqcomm.c:372 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "Unixドメインソケットのパス\"%s\"が長すぎます(最大 %d バイト)" + +#: libpq/pqcomm.c:393 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "ホスト名\"%s\"、サービス\"%s\"をアドレスに変換できませんでした: %s" + +#: libpq/pqcomm.c:397 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "サービス\"%s\"をアドレスに変換できませんでした: %s" + +#: libpq/pqcomm.c:424 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "要求されたアドレスを全てバインドできませんでした: MAXLISTEN (%d)を超えています" + +#: libpq/pqcomm.c:433 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:437 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:442 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:447 +#, c-format +msgid "unrecognized address family %d" +msgstr "アドレスファミリ %d を認識できません" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:473 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "アドレス\"%s\"に対する%sソケットの作成に失敗しました: %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:499 +#, c-format +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"に対するsetsockopt(SO_REUSEADDR)が失敗しました: %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:516 +#, c-format +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"に対するsetsockopt(IPV6_V6ONLY)が失敗しました: %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:536 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"のbindに失敗しました: %m" + +#: libpq/pqcomm.c:539 +#, c-format +msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +msgstr "すでに他にpostmasterがポート%dで稼動していませんか? 稼動していなければソケットファイル\"%s\"を削除して再試行してください。" + +#: libpq/pqcomm.c:542 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "すでに他にpostmasterがポート%dで稼動していませんか? 稼動していなければ数秒待ってから再試行してください。" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:575 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"のlistenに失敗しました: %m" + +#: libpq/pqcomm.c:584 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "Unixソケット\"%s\"で待ち受けています" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:590 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "%sアドレス\"%s\"、ポート%dで待ち受けています" + +#: libpq/pqcomm.c:673 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "グループ\"%s\"は存在しません" + +#: libpq/pqcomm.c:683 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "ファイル\"%s\"のグループを設定できませんでした: %m" + +#: libpq/pqcomm.c:694 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "ファイル\"%s\"の権限を設定できませんでした: %m" + +#: libpq/pqcomm.c:724 +#, c-format +msgid "could not accept new connection: %m" +msgstr "新しい接続を受け付けることができませんでした: %m" + +#: libpq/pqcomm.c:914 +#, c-format +msgid "there is no client connection" +msgstr "クライアント接続がありません" + +#: libpq/pqcomm.c:965 libpq/pqcomm.c:1061 +#, c-format +msgid "could not receive data from client: %m" +msgstr "クライアントからデータを受信できませんでした: %m" + +#: libpq/pqcomm.c:1206 tcop/postgres.c:4142 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "プロトコルの同期が失われたためコネクションを終了します" + +#: libpq/pqcomm.c:1272 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "メッセージ長ワード内のEOFは想定外です" + +#: libpq/pqcomm.c:1283 +#, c-format +msgid "invalid message length" +msgstr "メッセージ長が不正です" + +#: libpq/pqcomm.c:1305 libpq/pqcomm.c:1318 +#, c-format +msgid "incomplete message from client" +msgstr "クライアントからのメッセージが不完全です" + +#: libpq/pqcomm.c:1451 +#, c-format +msgid "could not send data to client: %m" +msgstr "クライアントにデータを送信できませんでした: %m" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "メッセージ内にデータが残っていません" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 utils/adt/arrayfuncs.c:1492 utils/adt/rowtypes.c:587 +#, c-format +msgid "insufficient data left in message" +msgstr "メッセージ内に残るデータが不十分です" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "メッセージ内の文字列が不正です" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "メッセージの書式が不正です" + +#: main/main.c:245 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: WSAStartupが失敗しました: %d\n" + +#: main/main.c:309 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%sはPostgreSQLサーバです\n" +"\n" + +#: main/main.c:310 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"使用方法:\n" +" %s [オプション]...\n" +"\n" + +#: main/main.c:311 +#, c-format +msgid "Options:\n" +msgstr "オプション:\n" + +#: main/main.c:312 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS 共有バッファの数\n" + +#: main/main.c:313 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NAME=VALUE 実行時パラメータの設定\n" + +#: main/main.c:314 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NAME 実行時パラメータの値を表示し、終了します\n" + +#: main/main.c:315 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 デバッグレベル\n" + +#: main/main.c:316 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D DATADIR データベースディレクトリ\n" + +#: main/main.c:317 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e ヨーロッパ式の日付フォーマットでの入力(DMY)\n" + +#: main/main.c:318 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F fsyncを無効にします\n" + +#: main/main.c:319 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h HOSTNAME 接続を待ち受けるホスト名またはIPアドレス\n" + +#: main/main.c:320 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i TCP/IP接続を有効にします\n" + +#: main/main.c:321 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k DIRECTORY Unixドメインソケットの場所\n" + +#: main/main.c:323 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l SSL接続を有効にします\n" + +#: main/main.c:325 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-CONNECT 許容する最大接続数\n" + +#: main/main.c:326 +#, c-format +msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr " -o OPTIONS 個々のサーバプロセスに\"OPTIONS\"を渡します(古い形式)\n" + +#: main/main.c:327 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT 接続を待ち受けるポート番号\n" + +#: main/main.c:328 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s 各問い合わせの後に統計情報を表示します\n" + +#: main/main.c:329 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM ソート用のメモリ量 (KB単位)\n" + +#: main/main.c:330 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示し、終了します\n" + +#: main/main.c:331 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NAME=VALUE 実行時パラメータを設定します\n" + +#: main/main.c:332 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config 設定パラメータの説明を出力し、終了します\n" + +#: main/main.c:333 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示し、終了します\n" + +#: main/main.c:335 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"開発者向けオプション:\n" + +#: main/main.c:336 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h いくつかのプランタイプを禁止します\n" + +#: main/main.c:337 +#, c-format +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr " -n 異常終了後に共有メモリの再初期化を行いません\n" + +#: main/main.c:338 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O システムテーブル構造の変更を許可します\n" + +#: main/main.c:339 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P システムインデックスを無効にします\n" + +#: main/main.c:340 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex 各問い合わせの後に時間情報を表示します\n" + +#: main/main.c:341 +#, c-format +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr " -T 1つのバックエンドプロセス異常停止した時に全てのバックエンドプロセスSIGSTOPを送信します\n" + +#: main/main.c:342 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr " -W NUM デバッガをアタッチできるようにNUM秒待機します\n" + +#: main/main.c:344 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"シングルユーザモード用のオプション:\n" + +#: main/main.c:345 +#, c-format +msgid " --single selects single-user mode (must be first argument)\n" +msgstr " --single シングルユーザモードを選択します(最初の引数でなければなりません)\n" + +#: main/main.c:346 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAME データベース名(デフォルトはユーザ名です)\n" + +#: main/main.c:347 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 1-5 デバッグレベルを上書きします\n" + +#: main/main.c:348 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E 実行前に文を表示します\n" + +#: main/main.c:349 +#, c-format +msgid " -j do not use newline as interactive query delimiter\n" +msgstr " -j 対話式問い合わせの区切りとして改行を使用しません\n" + +#: main/main.c:350 main/main.c:355 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r FILENAME 標準出力と標準エラー出力を指定したファイルに出力します\n" + +#: main/main.c:352 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"初期起動用のオプション:\n" + +#: main/main.c:353 +#, c-format +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot 初期起動モードを選択します(最初の引数でなければなりません)\n" + +#: main/main.c:354 +#, c-format +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr " DBNAME データベース名(初期起動モードでは必須の引数)\n" + +#: main/main.c:356 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM 内部使用\n" + +#: main/main.c:358 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"全ての実行時設定パラメータの一覧とコマンドラインや設定ファイルにおける\n" +"設定方法についてはドキュメントを参照してください。\n" +"\n" +"不具合は<%s>まで報告してください。\n" + +#: main/main.c:362 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: main/main.c:373 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"PostgreSQLの\"root\"での実行は許可されません。\n" +"システムセキュリティの低下を防止するため、サーバは非特権ユーザIDで起動\n" +"する必要があります。適切なサーバの起動方法に関する詳細はドキュメントを\n" +"参照してください\n" + +#: main/main.c:390 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: 実ユーザIDと実効ユーザIDは一致しなければなりません\n" + +#: main/main.c:397 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"PostgreSQLを管理者権限を持つユーザでの実行は許可されません。\n" +"システムセキュリティの低下を防止するため、サーバは非特権ユーザIDで起動\n" +"する必要があります。適切なサーバの起動方法に関する詳細はドキュメントを\n" +"参照してください\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "拡張可能ノードタイプ\"%s\"はすでに存在します" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "ExtensibleNodeMethods \"%s\"は登録されていません" + +#: nodes/makefuncs.c:150 +#, c-format +msgid "relation \"%s\" does not have a composite type" +msgstr "リレーション\"%s\"は複合型を持っていません" + +#: nodes/nodeFuncs.c:122 nodes/nodeFuncs.c:153 parser/parse_coerce.c:2208 parser/parse_coerce.c:2317 parser/parse_coerce.c:2352 parser/parse_expr.c:2207 parser/parse_func.c:701 parser/parse_oper.c:967 utils/fmgr/funcapi.c:528 +#, c-format +msgid "could not find array type for data type %s" +msgstr "データ型%sの配列型がありませんでした" + +#: nodes/params.c:417 +#, c-format +msgid "extended query \"%s\" with parameters: %s" +msgstr "パラメータを持つ拡張問い合わせ\"%s\": %s" + +#: nodes/params.c:420 +#, c-format +msgid "extended query with parameters: %s" +msgstr "パラメータを持つ拡張問い合わせ: %s" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN はマージ結合可能もしくはハッシュ結合可能な場合のみサポートされています" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1193 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "外部結合のNULL可な側では%sを適用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1922 parser/analyze.c:1639 parser/analyze.c:1855 parser/analyze.c:2715 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "UNION/INTERSECT/EXCEPTでは%sを使用できません" + +#: optimizer/plan/planner.c:2509 optimizer/plan/planner.c:4162 +#, c-format +msgid "could not implement GROUP BY" +msgstr "GROUP BY を実行できませんでした" + +#: optimizer/plan/planner.c:2510 optimizer/plan/planner.c:4163 optimizer/plan/planner.c:4890 optimizer/prep/prepunion.c:1045 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "一部のデータ型がハッシュのみをサポートする一方で、別の型はソートのみをサポートしています。" + +#: optimizer/plan/planner.c:4889 +#, c-format +msgid "could not implement DISTINCT" +msgstr "DISTINCTを実行できませんでした" + +#: optimizer/plan/planner.c:5737 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "ウィンドウの PARTITION BY を実行できませんでした" + +#: optimizer/plan/planner.c:5738 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "ウィンドウ分割に使用する列は、ソート可能なデータ型でなければなりません。" + +#: optimizer/plan/planner.c:5742 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "ウィンドウの ORDER BY を実行できませんでした" + +#: optimizer/plan/planner.c:5743 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "ウィンドウの順序付けをする列は、ソート可能なデータ型でなければなりません。" + +#: optimizer/plan/setrefs.c:451 +#, c-format +msgid "too many range table entries" +msgstr "レンジテーブルの数が多すぎます" + +#: optimizer/prep/prepunion.c:508 +#, c-format +msgid "could not implement recursive UNION" +msgstr "再帰UNIONを実行できませんでした" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "すべての列のデータ型はハッシュ可能でなければなりません。" + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1044 +#, c-format +msgid "could not implement %s" +msgstr "%sを実行できませんでした" + +#: optimizer/util/clauses.c:4746 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "SQL関数\"%s\"のインライン化処理中" + +#: optimizer/util/plancat.c:132 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "リカバリ中は一時テーブルやUNLOGGEDテーブルにはアクセスできません" + +#: optimizer/util/plancat.c:662 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "行全体に渡るユニークインデックスの推定指定はサポートされていません" + +#: optimizer/util/plancat.c:679 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "ON CONFLICT句中の制約には関連付けられるインデックスがありません" + +#: optimizer/util/plancat.c:729 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATEでの排除制約の使用はサポートされていません" + +#: optimizer/util/plancat.c:834 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "ON CONFLICT 指定に合致するユニーク制約または排除制約がありません" + +#: parser/analyze.c:705 parser/analyze.c:1401 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "VALUESリストはすべて同じ長さでなければなりません" + +#: parser/analyze.c:904 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERTに対象列よりも多くの式があります" + +#: parser/analyze.c:922 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERTに式よりも多くの対象列があります" + +#: parser/analyze.c:926 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "挿入ソースがINSERTが期待するのと同じ列数を含む行表現になっています。うっかり余計なカッコをつけたりしませんでしたか?" + +#: parser/analyze.c:1210 parser/analyze.c:1612 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "ここではSELECT ... INTOは許可されません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1542 parser/analyze.c:2894 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%sをVALUESに使用できません" + +#: parser/analyze.c:1777 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "不正なUNION/INTERSECT/EXCEPT ORDER BY句です" + +#: parser/analyze.c:1778 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "式や関数ではなく、結果列の名前のみが使用できます。" + +#: parser/analyze.c:1779 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "式/関数をすべてのSELECTにつけてください。またはこのUNIONをFROM句に移動してください。" + +#: parser/analyze.c:1845 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTOはUNION/INTERSECT/EXCEPTの最初のSELECTでのみ使用できます" + +#: parser/analyze.c:1917 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "UNION/INTERSECT/EXCEPTの要素となる文では同一問い合わせレベルの他のリレーションを参照できません" + +#: parser/analyze.c:2004 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "すべての%s問い合わせは同じ列数を返す必要があります" + +#: parser/analyze.c:2426 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNINGには少なくとも1つの列が必要です" + +#: parser/analyze.c:2467 +#, c-format +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "SCROLLとNO SCROLLの両方を同時には指定できません" + +#: parser/analyze.c:2486 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR では WITH にデータを変更する文を含んではなりません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2494 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %sはサポートされていません" + +#: parser/analyze.c:2497 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "保持可能カーソルは読み取り専用である必要があります。" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2505 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %sはサポートされていません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2516 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %sはサポートされていません" + +#: parser/analyze.c:2519 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "INSENSITIVEカーソルは読み取り専用である必要があります。" + +#: parser/analyze.c:2585 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "実体化ビューではWITH句にデータを変更する文を含んではなりません" + +#: parser/analyze.c:2595 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "実体化ビューでは一時テーブルやビューを使用してはいけません" + +#: parser/analyze.c:2605 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "実体化ビューは境界パラメータを用いて定義してはなりません" + +#: parser/analyze.c:2617 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "実体化ビューをログ非取得にはできません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2722 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "DISTINCT句では%sを使用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2729 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "GROUP BY句で%sを使用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2736 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "HAVING 句では%sを使用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2743 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "集約関数では%sは使用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2750 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "ウィンドウ関数では%sは使用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2757 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "ターゲットリストの中では%sを集合返却関数と一緒に使うことはできません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2836 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%sでは非修飾のリレーション名を指定してください" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2867 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%sを結合に使用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2876 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%sを関数に使用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2885 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%sはテーブル関数には適用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2903 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%sはWITH問い合わせには適用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2912 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%sは名前付きタプルストアには適用できません" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2932 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "%2$s句のリレーション\"%1$s\"はFROM句にありません" + +#: parser/parse_agg.c:220 parser/parse_oper.c:222 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "型%sの順序演算子を識別できませんでした" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "DISTINCT 付きの集約関数は、入力がソート可能である必要があります。" + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPINGの引数は32より少くなければなりません" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "JOIN条件で集約関数を使用できません" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "グルーピング演算はJOIN条件の中では使用できません" + +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "集約関数は自身の問い合わせレベルのFROM句の中では使用できません" + +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "グルーピング演算は自身のクエリレベルのFROM句の中では使用できません" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "集約関数はFROM句内の関数では使用できません" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "グルーピング演算はFROM句内の関数では使用できません" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "集約関数はポリシ式では使用できません" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "グルーピング演算はポリシ式では使用できません" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "集約関数はウィンドウRANGEの中では集約関数を使用できません" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "ウィンドウ定義のRANGE句の中ではグルーピング演算は使用できません" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "ウィンドウ定義のROWS句では集約関数は使用できません" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "ウィンドウ定義のROWS句ではグルーピング演算は使用できません" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "ウィンドウ定義のGROUPS句では集約関数は使用できません" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "ウィンドウ定義のGROUPS句ではグルーピング演算は使用できません" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "検査制約では集約関数を使用できません" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "検査制約ではグルーピング演算を使用できません" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "DEFAULT式では集約関数を使用できません" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "DEFAULT式ではグルーピング演算を使用できません" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "インデックス式では集約関数を使用できません" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "インデックス式ではグルーピング演算を使用できません" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "インデックス述語では集約関数を使用できません" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "インデックス述語ではグルーピング演算を使用できません" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "変換式では集約関数を使用できません" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in transform expressions" +msgstr "変換式ではグルーピング演算を使用できません" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "EXECUTEのパラメータでは集約関数を使用できません" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "EXECUTEのパラメータではグルーピング演算を使用できません" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "トリガのWHEN条件では集約関数を使用できません" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "トリガのWHEN条件ではグルーピング演算を使用できません" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in partition bound" +msgstr "集約関数はパーティション境界では使用できません" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in partition bound" +msgstr "グルーピング演算はパーティション境界では使用できません" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "パーティションキー式では集約関数は使用できません" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "パーティションキー式ではグルーピング演算は使用できません" + +#: parser/parse_agg.c:526 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "集約関数はカラム生成式では使用できません" + +#: parser/parse_agg.c:528 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "グルーピング演算はカラム生成式では使用できません" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "CALLの引数では集約関数を使用できません" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "CALLの引数ではグルーピング演算を使用できません" + +#: parser/parse_agg.c:542 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "集約関数は COPY FROM の WHERE 条件では使用できません" + +#: parser/parse_agg.c:544 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "グルーピング演算は COPY FROM の WHERE 条件の中では使用できません" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:567 parser/parse_clause.c:1828 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "%sでは集約関数を使用できません" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:570 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "%sではグルーピング演算を使用できません" + +#: parser/parse_agg.c:678 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "アウタレベルの集約は直接引数に低位の変数を含むことができません" + +#: parser/parse_agg.c:757 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "集合返却関数の呼び出しに集約関数の呼び出しを含むことはできません" + +#: parser/parse_agg.c:758 parser/parse_expr.c:1845 parser/parse_expr.c:2332 parser/parse_func.c:872 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "この集合返却関数をLATERAL FROM項目に移動できるかもしれません。" + +#: parser/parse_agg.c:763 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "集約関数の呼び出しにウィンドウ関数の呼び出しを含むことはできません" + +#: parser/parse_agg.c:842 +msgid "window functions are not allowed in JOIN conditions" +msgstr "JOIN条件ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:849 +msgid "window functions are not allowed in functions in FROM" +msgstr "FROM句内の関数ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:855 +msgid "window functions are not allowed in policy expressions" +msgstr "ポリシ式ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:868 +msgid "window functions are not allowed in window definitions" +msgstr "ウィンドウ定義ではウィンドウ関数は使用できません" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in check constraints" +msgstr "検査制約の中ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:904 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "DEFAULT式の中ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:907 +msgid "window functions are not allowed in index expressions" +msgstr "インデックス式ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:910 +msgid "window functions are not allowed in index predicates" +msgstr "インデックス述語ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:913 +msgid "window functions are not allowed in transform expressions" +msgstr "変換式ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:916 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "EXECUTEパラメータではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:919 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "トリガのWHEN条件ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:922 +msgid "window functions are not allowed in partition bound" +msgstr "ウィンドウ関数はパーティション境界では使用できません" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "パーティションキー式ではウィンドウ関数は使用できません" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "CALLの引数ではウィンドウ関数は使用できません" + +#: parser/parse_agg.c:931 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "ウィンドウ関数は COPY FROM の WHERE 条件では使用できません" + +#: parser/parse_agg.c:934 +msgid "window functions are not allowed in column generation expressions" +msgstr "ウィンドウ関数はカラム生成式では使用できません" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:954 parser/parse_clause.c:1837 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "%sの中ではウィンドウ関数を使用できません" + +#: parser/parse_agg.c:988 parser/parse_clause.c:2671 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "ウィンドウ\"%s\"は存在しません" + +#: parser/parse_agg.c:1072 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "グルーピングセットの数が多すぎます (最大4096)" + +#: parser/parse_agg.c:1212 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "再帰問い合わせの再帰項では集約関数を使用できません" + +#: parser/parse_agg.c:1405 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "列\"%s.%s\"はGROUP BY句で指定するか、集約関数内で使用しなければなりません" + +#: parser/parse_agg.c:1408 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "順序集合集約の直接引数はグルーピングされた列のみを使用しなければなりません。" + +#: parser/parse_agg.c:1413 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "外部問い合わせから副問い合わせがグループ化されていない列\"%s.%s\"を使用しています" + +#: parser/parse_agg.c:1577 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "GROUPINGの引数は関連するクエリレベルのグルーピング式でなければなりません" + +#: parser/parse_clause.c:191 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "リレーション\"%s\"は更新文の対象にはなれません" + +#: parser/parse_clause.c:571 parser/parse_clause.c:599 parser/parse_func.c:2424 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "集合返却関数はFROMの最上位レベルにある必要があります" + +#: parser/parse_clause.c:611 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "同じ関数に対して複数の列定義リストを持つことができません" + +#: parser/parse_clause.c:644 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "複数の関数を伴った ROWS FROM() は列定義リストを持つことができません" + +#: parser/parse_clause.c:645 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "ROWS FROM() 内のそれぞれの関数ごとに個別の列定義リストを付けてください。" + +#: parser/parse_clause.c:651 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "複数の引数をもつUNNEST()は列定義リストを持つことができません" + +#: parser/parse_clause.c:652 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "ROWS FROM() の中で個別に UNNEST() をコールして、列定義リストをそれぞれに付加してください。" + +#: parser/parse_clause.c:659 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY は列定義リストがあるときは使えません" + +#: parser/parse_clause.c:660 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "ROWS FROM() の中に列定義リストをおいてください。" + +#: parser/parse_clause.c:760 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "FOR ORDINALITY 列は一つまでです" + +#: parser/parse_clause.c:821 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "列名\"%s\"は一意ではありません" + +#: parser/parse_clause.c:863 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "名前空間名\"%s\"は一意ではありません" + +#: parser/parse_clause.c:873 +#, c-format +msgid "only one default namespace is allowed" +msgstr "デフォルト名前空間は一つのみ指定可能です" + +#: parser/parse_clause.c:933 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "テーブルサンプルメソッド%sは存在しません" + +#: parser/parse_clause.c:955 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "テーブルサンプルメソッド%sは%d個の引数を必要とします、%d個ではありません" +msgstr[1] "テーブルサンプルメソッド%sは%d個の引数を必要とします、%d個ではありません" + +#: parser/parse_clause.c:989 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "テーブルサンプルメソッド%sはREPEATABLEをサポートしていません" + +#: parser/parse_clause.c:1135 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLE句はテーブルおよび実体化ビューのみに適用可能です" + +#: parser/parse_clause.c:1318 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "USING句に列名\"%s\"が複数あります" + +#: parser/parse_clause.c:1333 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "左テーブルに列名\"%s\"が複数あります" + +#: parser/parse_clause.c:1342 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "USING句で指定した列\"%sが左テーブルに存在しません" + +#: parser/parse_clause.c:1357 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "右テーブルに列名\"%s\"が複数あります" + +#: parser/parse_clause.c:1366 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "USING句で指定した列\"%sが右テーブルに存在しません" + +#: parser/parse_clause.c:1447 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "列\"%s\"の別名リストのエントリが多すぎます" + +#: parser/parse_clause.c:1773 +#, c-format +msgid "row count cannot be NULL in FETCH FIRST ... WITH TIES clause" +msgstr "FETCH FIRST ... WITH TIES 節で行数にNULLは指定できません" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1798 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "%sの引数には変数を使用できません" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1963 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s \"%s\"は曖昧です" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1992 +#, c-format +msgid "non-integer constant in %s" +msgstr "%sに整数以外の定数があります" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2014 +#, c-format +msgid "%s position %d is not in select list" +msgstr "%sの位置%dはSELECTリストにありません" + +#: parser/parse_clause.c:2453 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBEは12要素に制限されています" + +#: parser/parse_clause.c:2659 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "ウィンドウ\"%s\"はすでに定義済みです" + +#: parser/parse_clause.c:2720 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "ウィンドウ\"%s\"のPARTITION BY句をオーバーライドできません" + +#: parser/parse_clause.c:2732 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "ウィンドウ\"%s\"のORDER BY句をオーバーライドできません" + +#: parser/parse_clause.c:2762 parser/parse_clause.c:2768 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "フレーム句をもっているため、ウィンドウ\"%s\"はコピーできません" + +#: parser/parse_clause.c:2770 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "このOVER句中の括弧を無視しました" + +#: parser/parse_clause.c:2790 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "offset PRECEDING/FOLLOWING を伴った RANGE はただ一つの ORDER BY 列を必要とします" + +#: parser/parse_clause.c:2813 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPSフレーム指定はORDER BY句を必要とします" + +#: parser/parse_clause.c:2883 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "DISTINCT や ORDER BY 表現を伴なう集約は引数リストの中に現れなければなりません" + +#: parser/parse_clause.c:2884 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "SELECT DISTINCTではORDER BYの式はSELECTリスト内になければなりません" + +#: parser/parse_clause.c:2916 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "DISTINCTを伴った集約は、最低でも一つの引数を取る必要があります" + +#: parser/parse_clause.c:2917 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCTには少なくとも1つの列が必要です" + +#: parser/parse_clause.c:2983 parser/parse_clause.c:3015 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "SELECT DISTINCT ONの式はORDER BY式の先頭に一致しなければなりません" + +#: parser/parse_clause.c:3093 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESCはON CONFLICT句では指定できません" + +#: parser/parse_clause.c:3099 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LASTはON CONFLICT句では指定できません" + +#: parser/parse_clause.c:3178 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE は推定指定または制約名を必要とします" + +#: parser/parse_clause.c:3179 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "例えば、 ON CONFLICT (column_name)。" + +#: parser/parse_clause.c:3190 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "システムカタログテーブルではON CONFLICTはサポートしていません" + +#: parser/parse_clause.c:3198 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT はカタログテーブルとして使用中のテーブル\"%s\"ではサポートされません" + +#: parser/parse_clause.c:3341 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "演算子\"%s\"は有効な順序付け演算子名ではありません" + +#: parser/parse_clause.c:3343 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "順序付け演算子はB-Tree演算子族の\"<\"または\">\"要素でなければなりません。" + +#: parser/parse_clause.c:3654 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "offset PRECEDING/FOLLOWING を伴った RANGE は列型 %s に対してはサポートされません" + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "offset PRECEDING/FOLLOWING を伴った RANGE は列型 %s とオフセット型 %s に対してはサポートされません" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "オフセット値を適切な型にキャストしてください。" + +#: parser/parse_clause.c:3668 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "offset PRECEDING/FOLLOWING を伴った RANGE は列型 %s とオフセット型 %s に対して複数の解釈が可能になっています" + +#: parser/parse_clause.c:3671 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "オフセット値を意図した型そのものにキャストしてください。" + +#: parser/parse_coerce.c:1024 parser/parse_coerce.c:1062 parser/parse_coerce.c:1080 parser/parse_coerce.c:1095 parser/parse_expr.c:2241 parser/parse_expr.c:2819 parser/parse_target.c:967 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "型%sから%sへの型変換ができません" + +#: parser/parse_coerce.c:1065 +#, c-format +msgid "Input has too few columns." +msgstr "入力列が少なすぎます。" + +#: parser/parse_coerce.c:1083 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "列%3$dで型%1$sから%2$sへの型変換ができません。" + +#: parser/parse_coerce.c:1098 +#, c-format +msgid "Input has too many columns." +msgstr "入力列が多すぎます。" + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1153 parser/parse_coerce.c:1201 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "%1$sの引数は型%3$sではなく%2$s型でなければなりません" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1164 parser/parse_coerce.c:1213 +#, c-format +msgid "argument of %s must not return a set" +msgstr "%sの引数は集合を返してはなりません" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1353 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "%sの型%sと%sを一致させることができません" + +#: parser/parse_coerce.c:1465 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "引数の型%sと%sは合致させられません" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1517 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%sで型%sから%sへ変換できませんでした" + +#: parser/parse_coerce.c:1934 +#, c-format +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "\"anyelement\"と宣言された引数が全て同じでありません" + +#: parser/parse_coerce.c:1954 +#, c-format +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "\"anyarray\"と宣言された引数が全て同じでありません" + +#: parser/parse_coerce.c:1974 +#, c-format +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "\"anyrange\"と宣言された引数が全て同じでありません" + +#: parser/parse_coerce.c:2008 parser/parse_coerce.c:2088 utils/fmgr/funcapi.c:487 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "%sと宣言された引数が配列ではなく%s型です" + +#: parser/parse_coerce.c:2029 +#, c-format +msgid "arguments declared \"anycompatiblerange\" are not all alike" +msgstr "\"anycompatiblerange\"と宣言された引数が全て同じでありません" + +#: parser/parse_coerce.c:2041 parser/parse_coerce.c:2122 utils/fmgr/funcapi.c:501 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "%sと宣言された引数が範囲型ではなく型%sです" + +#: parser/parse_coerce.c:2079 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "\"anyarray\"型の引数の要素型を決定できません" + +#: parser/parse_coerce.c:2105 parser/parse_coerce.c:2139 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "%sと宣言された引数と%sと宣言された引数とで整合性がありません" + +#: parser/parse_coerce.c:2163 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "入力型が%sであったため多様型が特定できませんでした" + +#: parser/parse_coerce.c:2177 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "anynonarrayと照合されたは配列型です: %s" + +#: parser/parse_coerce.c:2187 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "anyenumと照合された型は列挙型ではありません: %s" + +#: parser/parse_coerce.c:2218 parser/parse_coerce.c:2267 parser/parse_coerce.c:2329 parser/parse_coerce.c:2365 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "入力型が%2$sであるため多様型%1$sが特定できませんでした" + +#: parser/parse_coerce.c:2228 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "anycompatiblerange型%sはanycompatiblerange型%sと合致しません" + +#: parser/parse_coerce.c:2242 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "anycompatiblenonarrayに対応する型が配列型です: %s" + +#: parser/parse_coerce.c:2433 +#, c-format +msgid "A result of type %s requires at least one input of type %s." +msgstr "%s型の結果には%s型の入力が最低でも一つ必要です。" + +#: parser/parse_coerce.c:2445 +#, c-format +msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange." +msgstr "%s型の返却値には少なくとも一つの anyelement, anyarray, anynonarray, anyenum, または anyrange 型の入力が必要です。" + +#: parser/parse_coerce.c:2457 +#, c-format +msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "%s型の返却値には少なくとも一つの anycompatible, anycompatiblearray, anycompatiblenonarray, または anycompatiblerange型の入力が必要です。" + +#: parser/parse_coerce.c:2487 +msgid "A result of type internal requires at least one input of type internal." +msgstr "internal型の返却値には少なくとも1つのinternal型の入力が必要です。" + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 parser/parse_collate.c:981 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "暗黙の照合順序\"%s\"と\"%s\"の間に照合順序のミスマッチがあります" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 parser/parse_collate.c:984 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "片方もしくは両方の式に対して COLLATE 句を適用することで照合順序を選択できます" + +#: parser/parse_collate.c:831 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "明示的な照合順序\"%s\"と\"%s\"の間に照合順序のミスマッチがあります" + +#: parser/parse_cte.c:42 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "問い合わせ\"%s\"への再帰的参照が、その非再帰項内に現れてはなりません" + +#: parser/parse_cte.c:44 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "問い合わせ\"%s\"への再帰的参照が、副問い合わせ内に現れてはなりません" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "問い合わせ\"%s\"への再帰的参照が、外部結合内に現れてはなりません" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "問い合わせ\"%s\"への再帰的参照が、INTERSECT内に現れてはなりません" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "問い合わせ\"%s\"への再帰的参照が、EXCEPT内で現れてはなりません" + +#: parser/parse_cte.c:132 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "WITH 問い合わせ名\"%s\"が複数回指定されました" + +#: parser/parse_cte.c:264 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "データを変更するようなステートメントを含む WITH 句はトップレベルでなければなりません" + +#: parser/parse_cte.c:313 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "再帰問い合わせ\"%s\"の列%dの型は、非再帰項の内では%sになっていますが全体としては%sです" + +#: parser/parse_cte.c:319 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "非再帰項の出力を正しい型に変換してください。" + +#: parser/parse_cte.c:324 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "再帰問い合わせ\"%s\"の列%dの照合順序は、非再帰項では\"%s\"ですが全体としては\"%s\"です" + +#: parser/parse_cte.c:328 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "COLLATE句を使って非再帰項の照合順序を設定してください。" + +#: parser/parse_cte.c:418 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "WITH問い合わせ\"%s\"には%d列しかありませんが、%d列指定されています" + +#: parser/parse_cte.c:598 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "WITH項目間の再帰は実装されていません" + +#: parser/parse_cte.c:650 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "再帰問い合わせ\"%s\"はデータを更新するス文を含んでいてはなりません" + +#: parser/parse_cte.c:658 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "再帰問い合わせ\"%s\"が、<非再帰項> UNION [ALL] <再帰項> の形式になっていません" + +#: parser/parse_cte.c:702 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "再帰問い合わせ内の ORDER BY は実装されていません" + +#: parser/parse_cte.c:708 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "再帰問い合わせ内の OFFSET は実装されていません" + +#: parser/parse_cte.c:714 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "再帰問い合わせ内の LIMIT は実装されていません" + +#: parser/parse_cte.c:720 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "再帰問い合わせ内の FOR UPDATE/SHARE は実装されていません" + +#: parser/parse_cte.c:777 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "問い合わせ\"%s\"への再帰参照が2回以上現れてはなりません" + +#: parser/parse_expr.c:349 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "この文脈ではDEFAULTは使えません" + +#: parser/parse_expr.c:402 parser/parse_relation.c:3506 parser/parse_relation.c:3526 +#, c-format +msgid "column %s.%s does not exist" +msgstr "列%s.%sは存在しません" + +#: parser/parse_expr.c:414 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "データ型%2$sの列\"%1$s\"はありません" + +#: parser/parse_expr.c:420 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "レコードデータ型の列\"%s\"を識別できませんでした" + +#: parser/parse_expr.c:426 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "列記法 .%sが型%sに使用されましたが、この型は複合型ではありません" + +#: parser/parse_expr.c:457 parser/parse_target.c:729 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "\"*\"を通した行展開は、ここではサポートされていません" + +#: parser/parse_expr.c:578 +msgid "cannot use column reference in DEFAULT expression" +msgstr "列参照はDEFAULT式では使用できません" + +#: parser/parse_expr.c:581 +msgid "cannot use column reference in partition bound expression" +msgstr "列参照はパーティション境界式では使用できません" + +#: parser/parse_expr.c:850 parser/parse_relation.c:799 parser/parse_relation.c:881 parser/parse_target.c:1207 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "列参照\"%s\"は曖昧です" + +#: parser/parse_expr.c:906 parser/parse_param.c:110 parser/parse_param.c:142 parser/parse_param.c:199 parser/parse_param.c:298 +#, c-format +msgid "there is no parameter $%d" +msgstr "パラメータ$%dがありません" + +#: parser/parse_expr.c:1149 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULLIF では = 演算子が boolean を返す必要があります" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1155 parser/parse_expr.c:3135 +#, c-format +msgid "%s must not return a set" +msgstr "%sは集合を返してはなりません" + +#: parser/parse_expr.c:1603 parser/parse_expr.c:1635 +#, c-format +msgid "number of columns does not match number of values" +msgstr "列の数がVALUESの数と一致しません" + +#: parser/parse_expr.c:1649 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "複数列のUPDATE項目のソースは副問合せまたはROW()式でなければなりません" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1843 parser/parse_expr.c:2330 parser/parse_func.c:2540 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "集合返却関数は%sでは使用できません" + +#: parser/parse_expr.c:1904 +msgid "cannot use subquery in check constraint" +msgstr "検査制約では副問い合わせを使用できません" + +#: parser/parse_expr.c:1908 +msgid "cannot use subquery in DEFAULT expression" +msgstr "DEFAULT式には副問い合わせを使用できません" + +#: parser/parse_expr.c:1911 +msgid "cannot use subquery in index expression" +msgstr "式インデックスには副問い合わせを使用できません" + +#: parser/parse_expr.c:1914 +msgid "cannot use subquery in index predicate" +msgstr "インデックスの述部に副問い合わせを使用できません" + +#: parser/parse_expr.c:1917 +msgid "cannot use subquery in transform expression" +msgstr "変換式では副問い合わせを使用できません" + +#: parser/parse_expr.c:1920 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "EXECUTEのパラメータに副問い合わせを使用できません" + +#: parser/parse_expr.c:1923 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "トリガーの WHEN 条件では副問い合わせを使用できません" + +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in partition bound" +msgstr "副問い合わせはパーティション境界では使用できません" + +#: parser/parse_expr.c:1929 +msgid "cannot use subquery in partition key expression" +msgstr "パーティションキー式では副問い合わせを使用できません" + +#: parser/parse_expr.c:1932 +msgid "cannot use subquery in CALL argument" +msgstr "CALLの引数で副問い合わせは使用できません" + +#: parser/parse_expr.c:1935 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "副問い合わせは COPY FROM の WHERE 条件では使用できません" + +#: parser/parse_expr.c:1938 +msgid "cannot use subquery in column generation expression" +msgstr "副問い合わせはカラム生成式では使用できません" + +#: parser/parse_expr.c:1991 +#, c-format +msgid "subquery must return only one column" +msgstr "副問い合わせは1列のみを返さなければなりません" + +#: parser/parse_expr.c:2075 +#, c-format +msgid "subquery has too many columns" +msgstr "副問い合わせの列が多すぎます" + +#: parser/parse_expr.c:2080 +#, c-format +msgid "subquery has too few columns" +msgstr "副問い合わせの列が少なすぎます" + +#: parser/parse_expr.c:2181 +#, c-format +msgid "cannot determine type of empty array" +msgstr "空の配列のデータ型を決定できません" + +#: parser/parse_expr.c:2182 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "必要な型に明示的にキャストしてください。例: ARRAY[]::integer[]" + +#: parser/parse_expr.c:2196 +#, c-format +msgid "could not find element type for data type %s" +msgstr "データ型%sの要素を見つけられませんでした" + +#: parser/parse_expr.c:2481 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "無名のXML属性値は列参照でなければなりません" + +#: parser/parse_expr.c:2482 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "無名のXML要素値は列参照でなければなりません" + +#: parser/parse_expr.c:2497 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "XML属性名\"%s\"が複数あります" + +#: parser/parse_expr.c:2604 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "XMLSERIALIZE の結果を %s へキャストできません" + +#: parser/parse_expr.c:2892 parser/parse_expr.c:3088 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "行式において項目数が一致しません" + +#: parser/parse_expr.c:2902 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "長さ0の行を比較できません" + +#: parser/parse_expr.c:2927 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "行比較演算子は型%sではなくbooleanを返さなければなりません" + +#: parser/parse_expr.c:2934 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "行比較演算子は集合を返してはいけません" + +#: parser/parse_expr.c:2993 parser/parse_expr.c:3034 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "行比較演算子%sの解釈を特定できませんでした" + +#: parser/parse_expr.c:2995 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "行比較演算子はbtree演算子族と関連付けされなければなりません。" + +#: parser/parse_expr.c:3036 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "同程度の適合度の候補が複数存在します。" + +#: parser/parse_expr.c:3129 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROMでは=演算子はbooleanを返さなければなりません" + +#: parser/parse_expr.c:3448 parser/parse_expr.c:3466 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "演算子の優先順位の変更: %sは今では%sより低い優先順位です" + +#: parser/parse_func.c:191 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "引数名\"%s\"が複数回指定されました" + +#: parser/parse_func.c:202 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "位置パラメーターの次には名前付きの引数を指定できません。" + +#: parser/parse_func.c:284 parser/parse_func.c:2243 +#, c-format +msgid "%s is not a procedure" +msgstr "%sはプロシージャではありません" + +#: parser/parse_func.c:288 +#, c-format +msgid "To call a function, use SELECT." +msgstr "関数を呼び出すには SELECT を使用してください。" + +#: parser/parse_func.c:294 +#, c-format +msgid "%s is a procedure" +msgstr "%sはプロシージャです" + +#: parser/parse_func.c:298 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "関数を呼び出すには CALL を使用してください。" + +#: parser/parse_func.c:312 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*)が指定されましたが%sは集約関数ではありません" + +#: parser/parse_func.c:319 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCTが指定されましたが%sは集約関数ではありません" + +#: parser/parse_func.c:325 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUPが指定されましたが%sは集約関数ではありません" + +#: parser/parse_func.c:331 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY が指定されましたが、%sは集約関数ではありません" + +#: parser/parse_func.c:337 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTERが指定されましたが、%sは集約関数ではありません" + +#: parser/parse_func.c:343 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVERが指定されましたが、%sはウィンドウ関数と集約関数のいずれでもありません" + +#: parser/parse_func.c:381 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "順序集合集約%sには WITHIN GROUP が必要です" + +#: parser/parse_func.c:387 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "OVERは順序集合集約%sではサポートされていません" + +#: parser/parse_func.c:418 parser/parse_func.c:447 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr "順序集合集約%1$sはありますが、それは%3$d個ではなく%2$d個の直接引数を必要とします。" + +#: parser/parse_func.c:472 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "仮説集合集約%sを使うには、仮説直接引数(今は%d)がソート列の数(今は%d)と一致する必要があります" + +#: parser/parse_func.c:486 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr "順序集合集約%sはありますが、それは少なくとも%d個の直接引数を必要とします。" + +#: parser/parse_func.c:505 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%sは順序集合集約ではないため、WITHIN GROUP を持つことができません" + +#: parser/parse_func.c:518 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "ウィンドウ関数%sにはOVER句が必要です" + +#: parser/parse_func.c:525 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "ウィンドウ関数%sはWITHIN GROUPを持つことができません" + +#: parser/parse_func.c:554 +#, c-format +msgid "procedure %s is not unique" +msgstr "プロシージャ %s は一意ではありません" + +#: parser/parse_func.c:557 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "最善の候補プロシージャを選択できませんでした。明示的な型キャストが必要かもしれません。" + +#: parser/parse_func.c:563 +#, c-format +msgid "function %s is not unique" +msgstr "関数 %s は一意ではありません" + +#: parser/parse_func.c:566 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "最善の候補関数を選択できませんでした。明示的な型キャストが必要かもしれません" + +#: parser/parse_func.c:605 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "指定した名前と引数型に合致する集約関数がありません。おそらく ORDER BY の位置に誤りがあります。ORDER BY は集約関数のすべての通常の引数の後になければなりません。" + +#: parser/parse_func.c:613 parser/parse_func.c:2286 +#, c-format +msgid "procedure %s does not exist" +msgstr "プロシージャ %s は存在しません" + +#: parser/parse_func.c:616 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "指定した名称と引数の型に合う演算子がありません。明示的な型キャストが必要かもしれません。" + +#: parser/parse_func.c:625 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "指定した名前と引数型に合致する関数がありません。明示的な型変換が必要かもしれません。" + +#: parser/parse_func.c:727 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "VARIADIC引数は配列でなければなりません" + +#: parser/parse_func.c:779 parser/parse_func.c:843 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*)はパラメータがない集約関数の呼び出しに使用しなければなりません" + +#: parser/parse_func.c:786 +#, c-format +msgid "aggregates cannot return sets" +msgstr "集約は集合を返せません" + +#: parser/parse_func.c:801 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "集約では名前付き引数は使えません" + +#: parser/parse_func.c:833 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "ウィンドウ関数に対するDISTINCTは実装されていません" + +#: parser/parse_func.c:853 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "ウィンドウ関数に対する集約の ORDER BY は実装されていません" + +#: parser/parse_func.c:862 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "非集約のウィンドウ関数に対するFILTERは実装されていません" + +#: parser/parse_func.c:871 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "集約関数の呼び出しに集合返却関数の呼び出しを含むことはできません" + +#: parser/parse_func.c:879 +#, c-format +msgid "window functions cannot return sets" +msgstr "ウィンドウ関数は集合を返すことができません" + +#: parser/parse_func.c:2124 parser/parse_func.c:2315 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "\"%s\"という名前の関数は見つかりませんでした" + +#: parser/parse_func.c:2138 parser/parse_func.c:2333 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "関数名\"%s\"は一意ではありません" + +#: parser/parse_func.c:2140 parser/parse_func.c:2335 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "関数を曖昧さなく選択するには引数リストを指定してください。" + +#: parser/parse_func.c:2184 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "プロシージャは%d個以上の引数を取ることはできません" +msgstr[1] "プロシージャは%d個以上の引数を取ることはできません" + +#: parser/parse_func.c:2233 +#, c-format +msgid "%s is not a function" +msgstr "%s は関数ではありません" + +#: parser/parse_func.c:2253 +#, c-format +msgid "function %s is not an aggregate" +msgstr "関数%sは集約ではありません" + +#: parser/parse_func.c:2281 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "\"%s\"という名前のプロシージャは見つかりませんでした" + +#: parser/parse_func.c:2295 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "\"%s\"という名前の集約は見つかりませんでした" + +#: parser/parse_func.c:2300 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "集約%s(*)は存在しません" + +#: parser/parse_func.c:2305 +#, c-format +msgid "aggregate %s does not exist" +msgstr "集約%sは存在しません" + +#: parser/parse_func.c:2340 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "プロシージャ名\"%s\"は一意ではありません" + +#: parser/parse_func.c:2342 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "プロシージャを曖昧さなく選択するには引数リストを指定してください。" + +#: parser/parse_func.c:2347 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "集約名\"%s\"は一意ではありません" + +#: parser/parse_func.c:2349 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "集約を曖昧さなく選択するには引数リストを指定してください。" + +#: parser/parse_func.c:2354 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "ルーチン名\"%s\"は一意ではありません" + +#: parser/parse_func.c:2356 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "ルーチンを曖昧さなく選択するには引数リストを指定してください。" + +#: parser/parse_func.c:2411 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "集合返却関数はJOIN条件では使用できません" + +#: parser/parse_func.c:2432 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "集合返却関数はポリシ式では使用できません" + +#: parser/parse_func.c:2448 +msgid "set-returning functions are not allowed in window definitions" +msgstr "ウィンドウ定義では集合返却関数は使用できません" + +#: parser/parse_func.c:2486 +msgid "set-returning functions are not allowed in check constraints" +msgstr "集合返却関数は検査制約の中では使用できません" + +#: parser/parse_func.c:2490 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "集合返却関数はDEFAULT式の中では使用できません" + +#: parser/parse_func.c:2493 +msgid "set-returning functions are not allowed in index expressions" +msgstr "集合返却関数はインデックス式では使用できません" + +#: parser/parse_func.c:2496 +msgid "set-returning functions are not allowed in index predicates" +msgstr "集合返却関数はインデックス述語では使用できません" + +#: parser/parse_func.c:2499 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "集合返却関数は変換式では使用できません" + +#: parser/parse_func.c:2502 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "集合返却関数はEXECUTEパラメータでは使用できません" + +#: parser/parse_func.c:2505 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "集合返却関数はトリガのWHEN条件では使用できません" + +#: parser/parse_func.c:2508 +msgid "set-returning functions are not allowed in partition bound" +msgstr "集合返却関数はパーティション境界では使用できません" + +#: parser/parse_func.c:2511 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "集合返却関数はパーティションキー式では使用できません" + +#: parser/parse_func.c:2514 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "CALLの引数に集合返却関数は使用できません" + +#: parser/parse_func.c:2517 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "集合返却関数は COPY FROM の WHERE条件では使用できません" + +#: parser/parse_func.c:2520 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "集合返却関数はカラム生成式では使用できません" + +#: parser/parse_node.c:86 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "ターゲットリストは最大でも%dエントリまでしか持てません" + +#: parser/parse_node.c:235 +#, c-format +msgid "cannot subscript type %s because it is not an array" +msgstr "配列ではないため、型%sには添え字をつけられません" + +#: parser/parse_node.c:340 parser/parse_node.c:377 +#, c-format +msgid "array subscript must have type integer" +msgstr "配列の添え字は整数型でなければなりません" + +#: parser/parse_node.c:408 +#, c-format +msgid "array assignment requires type %s but expression is of type %s" +msgstr "配列の代入では型%sが必要でしたが、式は型%sでした" + +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:538 utils/adt/regproc.c:722 +#, c-format +msgid "operator does not exist: %s" +msgstr "演算子が存在しません: %s" + +#: parser/parse_oper.c:224 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "明示的に順序演算子を使用するか問い合わせを変更してください。" + +#: parser/parse_oper.c:480 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "演算子に実行時の型強制が必要です: %s" + +#: parser/parse_oper.c:716 +#, c-format +msgid "operator is not unique: %s" +msgstr "演算子は一意ではありません: %s" + +#: parser/parse_oper.c:718 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "最善の候補演算子を選択できませんでした。明示的な型キャストが必要かもしれません" + +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "指定した名称と引数の型に合う演算子がありません。明示的な型キャストが必要かもしれません。" + +#: parser/parse_oper.c:729 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "指定した名称と引数の型に合う演算子がありません。明示的な型キャストが必要かもしれません。" + +#: parser/parse_oper.c:790 parser/parse_oper.c:912 +#, c-format +msgid "operator is only a shell: %s" +msgstr "演算子は単なるシェルです: %s" + +#: parser/parse_oper.c:900 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "演算子 ANY/ALL (配列) 右辺に配列が必要です" + +#: parser/parse_oper.c:942 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "演算子 ANY/ALL (配列) はブール型を返さなければなりません" + +#: parser/parse_oper.c:947 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "演算子 ANY/ALL (配列) 集合を返してはなりません" + +#: parser/parse_param.c:216 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "パラメータ$%dについて推定された型が不整合です" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "テーブル参照\"%s\"は曖昧です" + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "テーブル参照%uは曖昧です" + +#: parser/parse_relation.c:444 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "テーブル名\"%s\"が複数指定されました" + +#: parser/parse_relation.c:473 parser/parse_relation.c:3446 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "テーブル\"%s\"用のFROM句に対する不正な参照" + +#: parser/parse_relation.c:477 parser/parse_relation.c:3451 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "テーブル\"%s\"の項目がありますが、問い合わせのこの部分からは参照できません。\"" + +#: parser/parse_relation.c:479 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "LATERAL参照では組み合わせる結合のタイプはINNERまたはLEFTでなければなりません" + +#: parser/parse_relation.c:690 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "検査制約で参照されるシステム列\"%s\"は不正です" + +#: parser/parse_relation.c:699 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "カラム生成式ではシステム列\"%s\"は使用できません" + +#: parser/parse_relation.c:1170 parser/parse_relation.c:1620 parser/parse_relation.c:2262 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "テーブル\"%s\"では%d列使用できますが、%d列指定されました" + +#: parser/parse_relation.c:1372 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "\"%s\"というWITH項目はありますが、これは問い合わせのこの部分からは参照できません。" + +#: parser/parse_relation.c:1374 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "WITH RECURSIVE を使うか、もしくは WITH 項目の場所を変えて前方参照をなくしてください" + +#: parser/parse_relation.c:1747 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "列定義リストは\"record\"を返す関数でのみ使用できます" + +#: parser/parse_relation.c:1756 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "\"record\"を返す関数では列定義リストが必要です" + +#: parser/parse_relation.c:1845 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "FROM句の関数\"%s\"の戻り値型%sはサポートされていません" + +#: parser/parse_relation.c:2054 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "VALUESリスト\"%s\"は%d列使用可能ですが、%d列が指定されました" + +#: parser/parse_relation.c:2125 +#, c-format +msgid "joins can have at most %d columns" +msgstr "JOIN で指定できるのは、最大 %d 列です" + +#: parser/parse_relation.c:2235 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "WITH 問い合わせ\"%s\"にRETURNING句がありません" + +#: parser/parse_relation.c:3221 parser/parse_relation.c:3231 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "リレーション\"%2$s\"の列\"%1$d\"は存在しません" + +#: parser/parse_relation.c:3449 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "テーブル別名\"%s\"を参照しようとしていたようです。" + +#: parser/parse_relation.c:3457 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "テーブル\"%s\"用のFROM句エントリがありません" + +#: parser/parse_relation.c:3509 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "列\"%s.%s\"を参照しようとしていたようです。" + +#: parser/parse_relation.c:3511 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "テーブル\"%2$s\"には\"%1$s\"という名前の列がありますが、問い合わせのこの部分からは参照できません。" + +#: parser/parse_relation.c:3528 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "列\"%s.%s\"または列\"%s.%s\"を参照しようとしていたようです。" + +#: parser/parse_target.c:478 parser/parse_target.c:792 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "システム列\"%s\"に代入できません" + +#: parser/parse_target.c:506 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "配列要素にDEFAULTを設定できません" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "サブフィールドにDEFAULTを設定できません" + +#: parser/parse_target.c:584 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "列\"%s\"は型%sですが、式は型%sでした" + +#: parser/parse_target.c:776 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "型%3$sが複合型でありませんので、列\"%2$s\"のフィールド\"%1$s\"に代入できません。" + +#: parser/parse_target.c:785 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "データ型%3$sの列がありませんので、列\"%2$s\"のフィールド\"%1$s\"に代入できません。" + +#: parser/parse_target.c:864 +#, c-format +msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "\"%s\"への配列代入には型%sが必要ですが、式は型%sでした" + +#: parser/parse_target.c:874 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "サブフィールド\"%s\"は型%sですが、式は型%sでした" + +#: parser/parse_target.c:1295 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "テーブル指定のないSELECT *は無効です" + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "%%TYPE参照が不適切です(ドット区切りの名前が少なすぎます: %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "%%TYPE参照が不適切です(ドット区切りの名前が多すぎます: %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "型参照%sは%sに変換されました" + +#: parser/parse_type.c:278 parser/parse_type.c:857 utils/cache/typcache.c:383 utils/cache/typcache.c:437 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "型\"%s\"は単なるシェルです" + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "型\"%s\"では型修正子は許可されません" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "型修正子は単純な定数または識別子でなければなりません" + +#: parser/parse_type.c:721 parser/parse_type.c:820 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "不正な型名\"%s\"" + +#: parser/parse_utilcmd.c:263 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "パーティションテーブルを継承の子テーブルとして作成はできません" + +#: parser/parse_utilcmd.c:427 +#, c-format +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%1$sはシリアル列\"%3$s.%4$s\"用に暗黙的なシーケンス\"%2$s\"を作成します。" + +#: parser/parse_utilcmd.c:558 +#, c-format +msgid "array of serial is not implemented" +msgstr "連番(SERIAL)の配列は実装されていません" + +#: parser/parse_utilcmd.c:636 parser/parse_utilcmd.c:648 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "テーブル\"%2$s\"の列\"%1$s\"でNULL宣言とNOT NULL宣言が競合しています" + +#: parser/parse_utilcmd.c:660 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "テーブル\"%2$s\"の列\"%1$s\"で複数のデフォルト値の指定があります" + +#: parser/parse_utilcmd.c:677 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "型付けされたテーブルでは識別列はサポートされていません" + +#: parser/parse_utilcmd.c:681 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "パーティションでは識別列はサポートされていません" + +#: parser/parse_utilcmd.c:690 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "テーブル\"%2$s\"の列\"%1$s\"に複数の識別指定があります" + +#: parser/parse_utilcmd.c:710 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "型付けされたテーブルでは生成カラムはサポートされていません" + +#: parser/parse_utilcmd.c:714 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "パーティションでは生成カラムはサポートされていません" + +#: parser/parse_utilcmd.c:719 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "テーブル\"%2$s\"の列\"%1$s\"に複数のGENERATED句の指定があります" + +#: parser/parse_utilcmd.c:737 parser/parse_utilcmd.c:852 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "外部テーブルでは主キー制約はサポートされていません" + +#: parser/parse_utilcmd.c:746 parser/parse_utilcmd.c:862 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "外部テーブルではユニーク制約はサポートされていません" + +#: parser/parse_utilcmd.c:791 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "デフォルト値と識別指定の両方がテーブル\"%2$s\"の列\"%1$s\"に指定されています" + +#: parser/parse_utilcmd.c:799 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "テーブル\"%2$s\"の列\"%1$s\"にデフォルト値と生成式の両方が指定されています" + +#: parser/parse_utilcmd.c:807 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "テーブル\"%2$s\"の列\"%1$s\"に識別指定と生成式の両方が指定されています" + +#: parser/parse_utilcmd.c:872 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "外部テーブルでは除外制約はサポートされていません" + +#: parser/parse_utilcmd.c:878 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "パーティションテーブルでは除外制約はサポートされていません" + +#: parser/parse_utilcmd.c:943 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "外部テーブルの作成においてLIKEはサポートされていません" + +#: parser/parse_utilcmd.c:1095 +#, c-format +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "制約\"%s\"はテーブル\"%s\"への行全体参照を含みます。" + +#: parser/parse_utilcmd.c:1598 parser/parse_utilcmd.c:1707 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "インデックス\"%s\"には行全体テーブル参照が含まれます" + +#: parser/parse_utilcmd.c:2075 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "CREATE TABLE では既存のインデックスを使えません" + +#: parser/parse_utilcmd.c:2095 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "インデックス\"%s\"はすでに1つの制約に割り当てられれいます" + +#: parser/parse_utilcmd.c:2110 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "インデックス\"%s\"は有効ではありません" + +#: parser/parse_utilcmd.c:2116 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "\"%s\"はユニークインデックスではありません" + +#: parser/parse_utilcmd.c:2117 parser/parse_utilcmd.c:2124 parser/parse_utilcmd.c:2131 parser/parse_utilcmd.c:2208 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "このようなインデックスを使ってプライマリキーや一意性制約を作成することはできません" + +#: parser/parse_utilcmd.c:2123 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "インデックス\"%s\"は式を含んでいます" + +#: parser/parse_utilcmd.c:2130 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "\"%s\"は部分インデックスです" + +#: parser/parse_utilcmd.c:2142 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\"は遅延可能インデックスです" + +#: parser/parse_utilcmd.c:2143 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "遅延可能インデックスを使った遅延不可制約は作れません。" + +#: parser/parse_utilcmd.c:2207 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "インデックス\"%s\"の列番号%dにはデフォルトのソート動作がありません" + +#: parser/parse_utilcmd.c:2364 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "列\"%s\"がプライマリキー制約内に2回出現します" + +#: parser/parse_utilcmd.c:2370 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "列\"%s\"が一意性制約内に2回出現します" + +#: parser/parse_utilcmd.c:2723 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "インデックス式と述語はインデックス付けされるテーブルのみを参照できます" + +#: parser/parse_utilcmd.c:2769 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "実体化ビューに対するルールはサポートされません" + +#: parser/parse_utilcmd.c:2832 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "ルールのWHERE条件に他のリレーションへの参照を持たせられません" + +#: parser/parse_utilcmd.c:2906 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "ルールのWHERE条件はSELECT、INSERT、UPDATE、DELETE動作のみを持つことができます" + +#: parser/parse_utilcmd.c:2924 parser/parse_utilcmd.c:3025 rewrite/rewriteHandler.c:502 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "条件付きのUNION/INTERSECT/EXCEPT文は実装されていません" + +#: parser/parse_utilcmd.c:2942 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "ON SELECTルールではOLDを使用できません" + +#: parser/parse_utilcmd.c:2946 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "ON SELECTルールではNEWを使用できません" + +#: parser/parse_utilcmd.c:2955 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "ON INSERTルールではOLDを使用できません" + +#: parser/parse_utilcmd.c:2961 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "ON DELETEルールではNEWを使用できません" + +#: parser/parse_utilcmd.c:2989 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "WITH 問い合わせ内では OLD は参照できません" + +#: parser/parse_utilcmd.c:2996 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "WITH 問い合わせ内では NEW は参照できません" + +#: parser/parse_utilcmd.c:3455 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "DEFERRABLE句の場所が間違っています" + +#: parser/parse_utilcmd.c:3460 parser/parse_utilcmd.c:3475 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "複数のDEFERRABLE/NOT DEFERRABLE句を使用できません" + +#: parser/parse_utilcmd.c:3470 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "NOT DEFERRABLE句の場所が間違っています" + +#: parser/parse_utilcmd.c:3491 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "INITIALLY DEFERRED句の場所が間違っています<" + +#: parser/parse_utilcmd.c:3496 parser/parse_utilcmd.c:3522 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "複数のINITIALLY IMMEDIATE/DEFERRED句を使用できません" + +#: parser/parse_utilcmd.c:3517 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "INITIALLY IMMEDIATE句の場所が間違っています<" + +#: parser/parse_utilcmd.c:3708 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATEで指定したスキーマ(%s)が作成先のスキーマ(%s)と異なります" + +#: parser/parse_utilcmd.c:3743 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "\"%s\"はパーティションテーブルではありません" + +#: parser/parse_utilcmd.c:3750 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "テーブル\"%s\"はパーティションされていません" + +#: parser/parse_utilcmd.c:3757 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "インデックス\"%s\"はパーティションされていません" + +#: parser/parse_utilcmd.c:3797 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "ハッシュパーティションテーブルはデフォルトパーティションを持つことができません" + +#: parser/parse_utilcmd.c:3814 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "ハッシュパーティションに対する不正な境界指定" + +#: parser/parse_utilcmd.c:3820 partitioning/partbounds.c:4693 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "ハッシュパーティションの法は正の整数にする必要があります" + +#: parser/parse_utilcmd.c:3827 partitioning/partbounds.c:4701 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "ハッシュパーティションの剰余は法よりも小さくなければなりません" + +#: parser/parse_utilcmd.c:3840 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "リストパーティションに対する不正な境界指定" + +#: parser/parse_utilcmd.c:3893 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "範囲パーティションに対する不正な境界指定" + +#: parser/parse_utilcmd.c:3899 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROMは全てのパーティション列ごとに一つの値を指定しなければなりません" + +#: parser/parse_utilcmd.c:3903 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TOは全てのパーティション列ごとに一つの値を指定しなければなりません" + +#: parser/parse_utilcmd.c:4017 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "範囲境界でNULLは使用できません" + +#: parser/parse_utilcmd.c:4066 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "MAXVALUEに続く境界値はMAXVALUEでなければなりません" + +#: parser/parse_utilcmd.c:4073 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "MINVALUEに続く境界値はMINVALUEでなければなりません" + +#: parser/parse_utilcmd.c:4115 +#, c-format +msgid "could not determine which collation to use for partition bound expression" +msgstr "パーティション境界式で使用する照合順序を特定できませんでした" + +#: parser/parse_utilcmd.c:4132 +#, c-format +msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +msgstr "列\"%s\"に対するパーティション境界値の照合順序がパーティションキーの照合順序\"%s\"と合致しません" + +#: parser/parse_utilcmd.c:4149 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "指定した値は列\"%s\"の%s型に変換できません" + +#: parser/parser.c:228 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "UESCAPE の後には単純な文字列リテラルが続かなければなりません" + +#: parser/parser.c:233 +msgid "invalid Unicode escape character" +msgstr "不正なUnicodeエスケープ文字" + +#: parser/parser.c:302 scan.l:1330 +#, c-format +msgid "invalid Unicode escape value" +msgstr "不正なUnicodeエスケープシーケンスの値" + +#: parser/parser.c:449 scan.l:677 +#, c-format +msgid "invalid Unicode escape" +msgstr "不正なUnicodeエスケープ" + +#: parser/parser.c:450 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "Unicodeエスケープは\\XXXXまたは\\+XXXXXXでなければなりません。" + +#: parser/parser.c:478 scan.l:638 scan.l:654 scan.l:670 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "不正なUnicodeサロゲートペア" + +#: parser/scansup.c:194 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%.*s\"" +msgstr "識別子\"%s\"は\"%.*s\"に切り詰められます" + +#: partitioning/partbounds.c:2833 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "パーティション\"%s\"は既存のデフォルトパーティション\"%s\"と重複しています" + +#: partitioning/partbounds.c:2892 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "ハッシュパーティションの法(除数)は次に大きな法の因数でなければなりません" + +#: partitioning/partbounds.c:2988 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "リレーション\"%s\"に対して空の範囲境界が指定されました" + +#: partitioning/partbounds.c:2990 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "指定された下限%sは上限%sより大きいか同じです。" + +#: partitioning/partbounds.c:3087 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "パーティション\"%s\"はパーティション\"%s\"と重複があります" + +#: partitioning/partbounds.c:3204 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "デフォルトパーティション\"%2$s\"の子テーブルであるためテーブル\"%1$s\"のスキャンをスキップします" + +#: partitioning/partbounds.c:4697 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "ハッシュパーティションの剰余は非負の整数でなければなりません" + +#: partitioning/partbounds.c:4724 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\"はハッシュパーティションテーブルではありません" + +#: partitioning/partbounds.c:4735 partitioning/partbounds.c:4852 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "パーティション列の数(%d)と与えられたキー値の数(%d)が一致していません" + +#: partitioning/partbounds.c:4757 partitioning/partbounds.c:4789 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "パーティションキーの列 %d は \"%s\"型です、しかし与えられた値は \"%s\"型です" + +#: port/pg_sema.c:209 port/pg_shmem.c:668 port/posix_sema.c:209 port/sysv_sema.c:327 port/sysv_shmem.c:668 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "データディレクトリ\"%s\"のstatに失敗しました: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "共有メモリセグメントを作成できませんでした: %m" + +#: port/pg_shmem.c:218 port/sysv_shmem.c:218 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "失敗したシステムコールはshmget(key=%lu, size=%zu, 0%o)です。" + +#: port/pg_shmem.c:222 port/sysv_shmem.c:222 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"通常このエラーは、PostgreSQLが要求する共有メモリセグメントがカーネルのSHMMAXパラメータを超えた場合、または可能性としてはカーネルのSHMMINパラメータより小さい場合に発生します。\n" +"共有メモリの設定に関する詳細情報は、PostgreSQL のドキュメントに記載されています。" + +#: port/pg_shmem.c:229 port/sysv_shmem.c:229 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"通常このエラーは、PostgreSQLが要求する共有メモリセグメントがカーネルのSHMALLパラメータを超えた場合に発生します。より大きなSHMALLでカーネルを再設定する必要があるかもしれません。\n" +"これ以上の共有メモリの設定に関する情報は、PostgreSQL のドキュメントに記載されています。" + +#: port/pg_shmem.c:235 port/sysv_shmem.c:235 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"このエラーはディスクの容量不足を意味していません。このエラーの要因の一つは共有メモリの識別子の枯渇です。この場合はカーネルのSHMMNIパラメータを増やす必要がありますが、そうでなければ要因はシステム全体の共有メモリの制限へ到達となります。\n" +"これ以上の共有メモリの設定に関する情報は、PostgreSQLのドキュメントに記載されています。" + +#: port/pg_shmem.c:606 port/sysv_shmem.c:606 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "匿名共有メモリをマップできませんでした: %m" + +#: port/pg_shmem.c:608 port/sysv_shmem.c:608 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "通常このエラーは、PostgreSQL が要求する共有メモリのサイズが利用可能なメモリやスワップ容量、ないしはヒュージページを超えた場合に発生します。要求サイズ(現在 %zu バイト)を減らすために、shared_buffers または max_connections を減らすことでPostgreSQLの共有メモリの使用量を減らしてください。" + +#: port/pg_shmem.c:676 port/sysv_shmem.c:676 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "このプラットフォームではヒュージページをサポートしていません" + +#: port/pg_shmem.c:737 port/sysv_shmem.c:737 utils/init/miscinit.c:1139 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "既存の共有メモリブロック(キー%lu、ID %lu)がまだ使用中です" + +#: port/pg_shmem.c:740 port/sysv_shmem.c:740 utils/init/miscinit.c:1141 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "データディレクトリ \"%s\". に対応する古いサーバプロセスを終了させてください。" + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "セマフォを作成できませんでした: %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "失敗したシステムコールはsemget(%lu, %d, 0%o)です。" + +#: port/sysv_sema.c:129 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"このエラーは、ディスクが足りなくなったことを意味していません。この原因はセマフォセット数が上限(SEMMNI)に達したか、またはシステム全体でのセマフォ数を上限まで(SEMMNS)を使いきった場合です。対処としては、対応するカーネルのパラメータを増やす必要があります。もしくは PostgreSQLの max_connections を減らすことで、消費するセマフォの数を減らしてください。\n" +"共有メモリの設定に関する詳細情報は、PostgreSQL のドキュメントに記載されています。" + +#: port/sysv_sema.c:159 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "" +"おそらくカーネルのSEMVMX値を最低でも%dまで増やす必要があります。\n" +"詳細はPostgreSQLのドキュメントを調べてください。" + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "dbghelp.dll をロードできず、クラッシュダンプも書き込めません\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "dbghelp.dll で必要とする関数をロードできませんでした。クラッシュダンプを書き込めません\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "クラッシュダンプファイル\"%s\"を書き込み用にオープンできませんでした: エラーコード %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "クラッシュダンプを\"%s\"に書き込みました\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "クラッシュダンプの\"%s\"への書き込みに失敗しました: エラーコード %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "pid %dに対するシグナル監視パイプを作成できませんでした: エラーコード %lu" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "シグナル監視パイプを作成できませんでした: エラーコード %lu: 再実行します\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "セマフォを作成できませんでした: エラーコード %lu" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "セマフォをロックできませんでした: エラーコード %lu" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "セマフォのロックを解除できませんでした: エラーコード %lu" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "セマフォのロック試行に失敗しました: エラーコード %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "Lock Pages in Memoryユーザ権限を有効にできませんでした: エラーコード %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "失敗したシステムコールは %s です。" + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "Lock Pages in Memoryユーザ権限を有効にできませんでした" + +#: port/win32_shmem.c:176 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "PostgreSQL を実行するWindowsユーザアカウントに Lock Pages in Memory 権限を付与してください。" + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "このプロセッサはラージページをサポートしていません" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "ヒュージページを無効にします" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "共有メモリセグメントを作成できませんでした: エラーコード %lu" + +#: port/win32_shmem.c:303 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "失敗したシステムコールはCreateFileMapping(size=%zu, name=%s)です。" + +#: port/win32_shmem.c:328 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "既存の共有メモリブロックはまだ使用中です" + +#: port/win32_shmem.c:329 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "古いサーバプロセスを確認し、実行中であれば終了させてください。" + +#: port/win32_shmem.c:339 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "失敗したシステムコールはMapViewOfFileExです。" + +#: port/win32_shmem.c:357 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "失敗したシステムコールはMapViewOfFileExです。" + +#: postmaster/autovacuum.c:406 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "自動VACUUM起動プロセスを fork できませんでした: %m" + +#: postmaster/autovacuum.c:442 +#, c-format +msgid "autovacuum launcher started" +msgstr "自動VACUUM起動プロセス" + +#: postmaster/autovacuum.c:839 +#, c-format +msgid "autovacuum launcher shutting down" +msgstr "自動VACUUM起動プロセスを停止しています" + +#: postmaster/autovacuum.c:1477 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "自動VACUUMワーカープロセスをforkできませんでした: %m" + +#: postmaster/autovacuum.c:1686 +#, c-format +msgid "autovacuum: processing database \"%s\"" +msgstr "自動VACUUM: データベース\"%s\"の処理中です" + +#: postmaster/autovacuum.c:2260 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "自動VACUUM: 孤立した一時テーブル\"%s.%s.%s\"を削除します" + +#: postmaster/autovacuum.c:2489 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "テーブル\"%s.%s.%s\"に対する自動VACUUM" + +#: postmaster/autovacuum.c:2492 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "テーブル\"%s.%s.%s\"に対する自動ANALYZE" + +#: postmaster/autovacuum.c:2685 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "リレーション\"%s.%s.%s\"の作業エントリを処理しています" + +#: postmaster/autovacuum.c:3289 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "誤設定のため自動VACUUMが起動できません" + +#: postmaster/autovacuum.c:3290 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "\"track_counts\"オプションを有効にしてください。" + +#: postmaster/bgworker.c:394 postmaster/bgworker.c:834 +#, c-format +msgid "registering background worker \"%s\"" +msgstr "バックグラウンドワーカ\"%s\"を登録しています" + +#: postmaster/bgworker.c:426 +#, c-format +msgid "unregistering background worker \"%s\"" +msgstr "バックグラウンドワーカ\"%s\"の登録を解除しています" + +#: postmaster/bgworker.c:591 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "バックグラウンドワーカ\"\"%s: データベース接続を要求するためには共有メモリにアタッチしなければなりません" + +#: postmaster/bgworker.c:600 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "バックグラウンドワーカ\"%s\": postmaster起動中に起動している場合にはデータベースアクセスを要求することはできません" + +#: postmaster/bgworker.c:614 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "バックグラウンドワーカ\"%s\": 不正な再起動間隔" + +#: postmaster/bgworker.c:629 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "バックグラウンドワーカ\"%s\": パラレルワーカは再起動するように設定してはいけません" + +#: postmaster/bgworker.c:653 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "管理者コマンドによりバックグラウンドワーカ\"%s\"を終了しています" + +#: postmaster/bgworker.c:842 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "バックグラウンドワーカ\"%s\": shared_preload_librariesに登録しなければなりません" + +#: postmaster/bgworker.c:854 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "バックグラウンドワーカ\"%s\": 動的バックグラウンドワーカのみが通知を要求できます" + +#: postmaster/bgworker.c:869 +#, c-format +msgid "too many background workers" +msgstr "バックグラウンドワーカが多すぎます" + +#: postmaster/bgworker.c:870 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "現在の設定では最大%dのバックグラウンドワーカを登録することができます。" +msgstr[1] "現在の設定では最大%dのバックグラウンドワーカを登録することができます。" + +#: postmaster/bgworker.c:874 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "設定パラメータ\"max_worker_processes\"を増やすことを検討してください" + +#: postmaster/checkpointer.c:418 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "チェックポイントの発生周期が短すぎます(%d秒間隔)" +msgstr[1] "チェックポイントの発生周期が短すぎます(%d秒間隔)" + +#: postmaster/checkpointer.c:422 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "設定パラメータ\"max_wal_size\"を増やすことを検討してください" + +#: postmaster/checkpointer.c:1032 +#, c-format +msgid "checkpoint request failed" +msgstr "チェックポイント要求が失敗しました" + +#: postmaster/checkpointer.c:1033 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "詳細はサーバログの最近のメッセージを調査してください" + +#: postmaster/checkpointer.c:1217 +#, c-format +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "ぎっしり詰まった fsync リクエストのキューのうち %d から %d までのエントリ" + +#: postmaster/pgarch.c:156 +#, c-format +msgid "could not fork archiver: %m" +msgstr "アーカイバのforkに失敗しました: %m" + +#: postmaster/pgarch.c:434 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_modeは有効ですが、archive_commandが設定されていません" + +#: postmaster/pgarch.c:456 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "孤立したアーカイブステータスファイル\"%s\"を削除しました" + +#: postmaster/pgarch.c:466 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "孤立したアーカイブステータスファイル\"%s\"の削除の失敗回数が上限を超えました、あとでリトライします" + +#: postmaster/pgarch.c:502 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "先行書き込みログファイル\"%s\"のアーカイブ処理の失敗回数が超過しました、後で再度試します" + +#: postmaster/pgarch.c:603 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "アーカイブコマンドがリターンコード %dで失敗しました" + +#: postmaster/pgarch.c:605 postmaster/pgarch.c:615 postmaster/pgarch.c:621 postmaster/pgarch.c:630 +#, c-format +msgid "The failed archive command was: %s" +msgstr "失敗したアーカイブコマンドは次のとおりです: %s" + +#: postmaster/pgarch.c:612 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "アーカイブコマンドが例外0x%Xで終了しました" + +#: postmaster/pgarch.c:614 postmaster/postmaster.c:3744 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "16進値の説明についてはC インクルードファイル\"ntstatus.h\"を参照してください。" + +#: postmaster/pgarch.c:619 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "アーカイブコマンドはシグナル%dにより終了しました: %s" + +#: postmaster/pgarch.c:628 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "アーカイブコマンドは不明のステータス%dで終了しました" + +#: postmaster/pgstat.c:419 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "\"localhost\"を解決できませんでした: %s" + +#: postmaster/pgstat.c:442 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "統計情報コレクタ用の別のアドレスを試みています" + +#: postmaster/pgstat.c:451 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "統計情報コレクタ用のソケットを作成できませんでした: %m" + +#: postmaster/pgstat.c:463 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "統計情報コレクタのソケットをバインドできませんでした: %m" + +#: postmaster/pgstat.c:474 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "統計情報コレクタのソケットからアドレスを入手できませんでした: %m" + +#: postmaster/pgstat.c:490 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "統計情報コレクタのソケットに接続できませんでした: %m" + +#: postmaster/pgstat.c:511 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "統計情報コレクタのソケットに試験メッセージを送信できませんでした: %m" + +#: postmaster/pgstat.c:537 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "統計情報コレクタでselect()が失敗しました: %m" + +#: postmaster/pgstat.c:552 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "統計情報コレクタのソケットから試験メッセージを入手できませんでした" + +#: postmaster/pgstat.c:567 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "統計情報コレクタのソケットから試験メッセージを受信できませんでした: %m" + +#: postmaster/pgstat.c:577 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "統計情報コレクタのソケットでの試験メッセージの送信が不正です" + +#: postmaster/pgstat.c:600 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "統計情報コレクタのソケットを非ブロッキングモードに設定できませんでした: %m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "作業用ソケットの欠落のため統計情報コレクタを無効にしています" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "統計情報コレクタをforkできませんでした: %m" + +#: postmaster/pgstat.c:1376 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "認識できないリセットターゲット: \"%s\"" + +#: postmaster/pgstat.c:1377 +#, c-format +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "対象は\"archiver\"または\"bgwriter\"でなければなりません" + +#: postmaster/pgstat.c:4568 +#, c-format +msgid "could not read statistics message: %m" +msgstr "統計情報メッセージを読み取れませんでした: %m" + +#: postmaster/pgstat.c:4886 postmaster/pgstat.c:5049 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "一時統計情報ファイル\"%s\"をオープンできませんでした: %m" + +#: postmaster/pgstat.c:4959 postmaster/pgstat.c:5094 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "一時統計情報ファイル\"%s\"に書き込みできませんでした: %m" + +#: postmaster/pgstat.c:4968 postmaster/pgstat.c:5103 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "一時統計情報ファイル\"%s\"をクローズできませんでした: %m" + +#: postmaster/pgstat.c:4976 postmaster/pgstat.c:5111 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "一時統計情報ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m" + +#: postmaster/pgstat.c:5208 postmaster/pgstat.c:5425 postmaster/pgstat.c:5579 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "統計情報ファイル\"%s\"をオープンできませんでした: %m" + +#: postmaster/pgstat.c:5220 postmaster/pgstat.c:5230 postmaster/pgstat.c:5251 postmaster/pgstat.c:5262 postmaster/pgstat.c:5284 postmaster/pgstat.c:5299 postmaster/pgstat.c:5362 postmaster/pgstat.c:5437 postmaster/pgstat.c:5457 postmaster/pgstat.c:5475 postmaster/pgstat.c:5491 postmaster/pgstat.c:5509 postmaster/pgstat.c:5525 postmaster/pgstat.c:5591 postmaster/pgstat.c:5603 postmaster/pgstat.c:5615 postmaster/pgstat.c:5626 postmaster/pgstat.c:5651 +#: postmaster/pgstat.c:5673 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "統計情報ファイル\"%s\"が破損しています" + +#: postmaster/pgstat.c:5802 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "統計情報コレクタが応答しないため、最新の統計値の替わりに古い値を使用します" + +#: postmaster/pgstat.c:6132 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "整理処理においてデータベースハッシュテーブルが破損しました --- 中断します" + +#: postmaster/postmaster.c:736 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: -fオプションに対する不正な引数: \"%s\"\n" + +#: postmaster/postmaster.c:822 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: -tオプションに対する不正な引数: \"%s\"\n" + +#: postmaster/postmaster.c:873 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: 不正な引数: \"%s\"\n" + +#: postmaster/postmaster.c:915 +#, c-format +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) は max_connections (%d) より小さくなければなりません\n" + +#: postmaster/postmaster.c:922 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "wal_levelが\"minimal\"の時はWALアーカイブは有効にできません" + +#: postmaster/postmaster.c:925 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WALストリーミング(max_wal_senders > 0)を行うには wal_levelを\"replica\"または\"logical\"にする必要があります" + +#: postmaster/postmaster.c:933 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: データトークンテーブルが不正です、修復してください\n" + +#: postmaster/postmaster.c:1050 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "子キュー向けのI/O終了ポートを作成できませんでした" + +#: postmaster/postmaster.c:1115 +#, c-format +msgid "ending log output to stderr" +msgstr "標準エラー出力へのログ出力を終了しています" + +#: postmaster/postmaster.c:1116 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "この後のログ出力はログ配送先\"%s\"に出力されます。" + +#: postmaster/postmaster.c:1127 +#, c-format +msgid "starting %s" +msgstr "%s を起動しています" + +#: postmaster/postmaster.c:1156 postmaster/postmaster.c:1254 utils/init/miscinit.c:1599 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "パラメータ\"%s\"のリスト構文が不正です" + +#: postmaster/postmaster.c:1187 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "\"%s\"に関する監視用ソケットを作成できませんでした" + +#: postmaster/postmaster.c:1193 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "TCP/IPソケットを作成できませんでした" + +#: postmaster/postmaster.c:1276 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "ディレクトリ\"%s\"においてUnixドメインソケットを作成できませんでした" + +#: postmaster/postmaster.c:1282 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "Unixドメインソケットを作成できませんでした" + +#: postmaster/postmaster.c:1294 +#, c-format +msgid "no socket created for listening" +msgstr "監視用に作成するソケットはありません" + +#: postmaster/postmaster.c:1325 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: 外部PIDファイル\"%s\"の権限を変更できませんでした: %s\n" + +#: postmaster/postmaster.c:1329 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: 外部PIDファイル\"%s\"に書き出せませんでした: %s\n" + +#: postmaster/postmaster.c:1362 utils/init/postinit.c:215 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "pg_hba.conf の読み込みができませんでした" + +#: postmaster/postmaster.c:1388 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "postmasterは起動値処理中はマルチスレッドで動作します" + +#: postmaster/postmaster.c:1389 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "LC_ALL環境変数を使用可能なロケールに設定してください。" + +#: postmaster/postmaster.c:1490 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: 一致するpostgres実行ファイルがありませんでした" + +#: postmaster/postmaster.c:1513 utils/misc/tzparser.c:340 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "これは、PostgreSQLのインストールが不完全であるかまたは、ファイル\"%s\"が本来の場所からなくなってしまったことを示しています。" + +#: postmaster/postmaster.c:1540 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: データベースシステムがありませんでした\n" +"ディレクトリ\"%s\"にあるものと想定していましたが、\n" +"ファイル\"%s\"をオープンできませんでした: %s\n" + +#: postmaster/postmaster.c:1717 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "postmasterでselect()が失敗しました: %m" + +#: postmaster/postmaster.c:1872 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "データディレクトリのロックファイルが不正なため、即時シャットダウンを実行中です" + +#: postmaster/postmaster.c:1975 postmaster/postmaster.c:2006 +#, c-format +msgid "incomplete startup packet" +msgstr "開始パケットが不完全です" + +#: postmaster/postmaster.c:1987 +#, c-format +msgid "invalid length of startup packet" +msgstr "不正な開始パケット長" + +#: postmaster/postmaster.c:2045 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "SSLネゴシエーション応答の送信に失敗しました: %m" + +#: postmaster/postmaster.c:2076 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "GSSAPIネゴシエーション応答の送信に失敗しました: %m" + +#: postmaster/postmaster.c:2106 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "フロントエンドプロトコル%u.%uをサポートしていません: サーバは%u.0から %u.%uまでをサポートします" + +#: postmaster/postmaster.c:2170 utils/misc/guc.c:6787 utils/misc/guc.c:6823 utils/misc/guc.c:6893 utils/misc/guc.c:8216 utils/misc/guc.c:11062 utils/misc/guc.c:11096 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "パラメータ\"%s\"の値が不正です: \"%s\"" + +#: postmaster/postmaster.c:2173 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "有効な値: \"false\", 0, \"true\", 1, \"database\"。" + +#: postmaster/postmaster.c:2218 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "開始パケットの配置が不正です: 最終バイトはターミネータであるはずです" + +#: postmaster/postmaster.c:2256 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "開始パケットで指定されたPostgreSQLユーザ名は存在しません" + +#: postmaster/postmaster.c:2320 +#, c-format +msgid "the database system is starting up" +msgstr "データベースシステムは起動処理中です" + +#: postmaster/postmaster.c:2325 +#, c-format +msgid "the database system is shutting down" +msgstr "データベースシステムはシャットダウンしています" + +#: postmaster/postmaster.c:2330 +#, c-format +msgid "the database system is in recovery mode" +msgstr "データベースシステムはリカバリモードです" + +#: postmaster/postmaster.c:2335 storage/ipc/procarray.c:452 storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:359 +#, c-format +msgid "sorry, too many clients already" +msgstr "現在クライアント数が多すぎます" + +#: postmaster/postmaster.c:2425 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "プロセス%dに対するキャンセル要求においてキーが間違っています" + +#: postmaster/postmaster.c:2437 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "キャンセル要求内のPID %dがどのプロセスにも一致しません" + +#: postmaster/postmaster.c:2708 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "SIGHUPを受け取りました。設定ファイルをリロードしています" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2734 postmaster/postmaster.c:2738 +#, c-format +msgid "%s was not reloaded" +msgstr "%s は再読み込みされていません" + +#: postmaster/postmaster.c:2748 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "SSL設定は再読み込みされていません" + +#: postmaster/postmaster.c:2804 +#, c-format +msgid "received smart shutdown request" +msgstr "スマートシャットダウン要求を受け取りました" + +#: postmaster/postmaster.c:2850 +#, c-format +msgid "received fast shutdown request" +msgstr "高速シャットダウン要求を受け取りました" + +#: postmaster/postmaster.c:2868 +#, c-format +msgid "aborting any active transactions" +msgstr "活動中の全トランザクションをアボートしています" + +#: postmaster/postmaster.c:2892 +#, c-format +msgid "received immediate shutdown request" +msgstr "即時シャットダウン要求を受け取りました" + +#: postmaster/postmaster.c:2967 +#, c-format +msgid "shutdown at recovery target" +msgstr "リカバリ目標でシャットダウンします" + +#: postmaster/postmaster.c:2985 postmaster/postmaster.c:3021 +msgid "startup process" +msgstr "起動プロセス" + +#: postmaster/postmaster.c:2988 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "起動プロセスの失敗のため起動を中断しています" + +#: postmaster/postmaster.c:3063 +#, c-format +msgid "database system is ready to accept connections" +msgstr "データベースシステムの接続受け付け準備が整いました" + +#: postmaster/postmaster.c:3084 +msgid "background writer process" +msgstr "バックグランドライタプロセス" + +#: postmaster/postmaster.c:3138 +msgid "checkpointer process" +msgstr "チェックポイント処理プロセス" + +#: postmaster/postmaster.c:3154 +msgid "WAL writer process" +msgstr "WALライタプロセス" + +#: postmaster/postmaster.c:3169 +msgid "WAL receiver process" +msgstr "WAL 受信プロセス" + +#: postmaster/postmaster.c:3184 +msgid "autovacuum launcher process" +msgstr "自動VACUUM起動プロセス" + +#: postmaster/postmaster.c:3199 +msgid "archiver process" +msgstr "アーカイバプロセス" + +#: postmaster/postmaster.c:3215 +msgid "statistics collector process" +msgstr "統計情報収集プロセス" + +#: postmaster/postmaster.c:3229 +msgid "system logger process" +msgstr "システムログ取得プロセス" + +#: postmaster/postmaster.c:3293 +#, c-format +msgid "background worker \"%s\"" +msgstr "バックグラウンドワーカ\"%s\"" + +#: postmaster/postmaster.c:3377 postmaster/postmaster.c:3397 postmaster/postmaster.c:3404 postmaster/postmaster.c:3422 +msgid "server process" +msgstr "サーバプロセス" + +#: postmaster/postmaster.c:3476 +#, c-format +msgid "terminating any other active server processes" +msgstr "他の活動中のサーバプロセスを終了しています" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3731 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d)は終了コード%dで終了しました" + +#: postmaster/postmaster.c:3733 postmaster/postmaster.c:3745 postmaster/postmaster.c:3755 postmaster/postmaster.c:3766 +#, c-format +msgid "Failed process was running: %s" +msgstr "失敗したプロセスが実行していました: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3742 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d)は例外%Xで終了しました" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3752 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d)はシグナル%dで終了しました: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3764 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d)は認識できないステータス%dで終了しました" + +#: postmaster/postmaster.c:3972 +#, c-format +msgid "abnormal database system shutdown" +msgstr "データベースシステムは異常にシャットダウンしました" + +#: postmaster/postmaster.c:4012 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "全てのサーバプロセスが終了しました: 再初期化しています" + +#: postmaster/postmaster.c:4182 postmaster/postmaster.c:5588 postmaster/postmaster.c:5975 +#, c-format +msgid "could not generate random cancel key" +msgstr "ランダムなキャンセルキーを生成できませんでした" + +#: postmaster/postmaster.c:4236 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "接続用の新しいプロセスをforkできませんでした: %m" + +#: postmaster/postmaster.c:4278 +msgid "could not fork new process for connection: " +msgstr "接続用の新しいプロセスをforkできませんでした" + +#: postmaster/postmaster.c:4387 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "接続を受け付けました: ホスト=%s ポート番号=%s" + +#: postmaster/postmaster.c:4392 +#, c-format +msgid "connection received: host=%s" +msgstr "接続を受け付けました: ホスト=%s" + +#: postmaster/postmaster.c:4662 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "サーバプロセス\"%s\"を実行できませんでした: %m" + +#: postmaster/postmaster.c:4821 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "共有メモリの確保のリトライ回数が多すぎるため中断します" + +#: postmaster/postmaster.c:4822 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "これはASLRまたはアンチウイルスソフトウェアが原因である可能性があります。" + +#: postmaster/postmaster.c:5028 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "SSL構成は子プロセスでは読み込めません" + +#: postmaster/postmaster.c:5160 +#, c-format +msgid "Please report this to <%s>." +msgstr "これを<%s>まで報告してください。" + +#: postmaster/postmaster.c:5253 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "データベースシステムはリードオンリー接続の受け付け準備ができました" + +#: postmaster/postmaster.c:5516 +#, c-format +msgid "could not fork startup process: %m" +msgstr "起動プロセスをforkできませんでした: %m" + +#: postmaster/postmaster.c:5520 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "バックグランドライタプロセスをforkできませんでした: %m" + +#: postmaster/postmaster.c:5524 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "チェックポイント処理プロセスをforkできませんでした: %m" + +#: postmaster/postmaster.c:5528 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "WALライタプロセスをforkできませんでした: %m" + +#: postmaster/postmaster.c:5532 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "WAL 受信プロセスを fork できませんでした: %m" + +#: postmaster/postmaster.c:5536 +#, c-format +msgid "could not fork process: %m" +msgstr "プロセスをforkできませんでした: %m" + +#: postmaster/postmaster.c:5733 postmaster/postmaster.c:5756 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "登録時にデータベース接続の必要性が示されていません" + +#: postmaster/postmaster.c:5740 postmaster/postmaster.c:5763 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "バックグラウンドワーカ内の不正な処理モード" + +#: postmaster/postmaster.c:5836 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "バックグラウンドワーカプロセス\"%s\"を起動しています" + +#: postmaster/postmaster.c:5848 +#, c-format +msgid "could not fork worker process: %m" +msgstr "ワーカプロセスをforkできませんでした: %m" + +#: postmaster/postmaster.c:5961 +#, c-format +msgid "no slot available for new worker process" +msgstr "新しいワーカプロセスに割り当てられるスロットがありません" + +#: postmaster/postmaster.c:6296 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "バックエンドで使用するためにソケット%dを複製できませんでした: エラーコード %d" + +#: postmaster/postmaster.c:6328 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "継承したソケットを作成できませんでした: エラーコード %d\n" + +#: postmaster/postmaster.c:6357 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "バックエンド変数ファイル\"%s\"をオープンできませんでした: %s\n" + +#: postmaster/postmaster.c:6364 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "バックエンド変数ファイル\"%s\"から読み取れませんでした: %s\n" + +#: postmaster/postmaster.c:6373 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "ファイル\"%s\"を削除できませんでした: %s\n" + +#: postmaster/postmaster.c:6390 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "バックエンド変数のビューをマップできませんでした: エラーコード %lu\n" + +#: postmaster/postmaster.c:6399 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "バックエンド変数のビューをアンマップできませんでした: エラーコード %lu\n" + +#: postmaster/postmaster.c:6406 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "バックエンドパラメータ変数のハンドルをクローズできませんでした: エラーコード%lu\n" + +#: postmaster/postmaster.c:6584 +#, c-format +msgid "could not read exit code for process\n" +msgstr "子プロセスの終了コードの読み込みができませんでした\n" + +#: postmaster/postmaster.c:6589 +#, c-format +msgid "could not post child completion status\n" +msgstr "個プロセスの終了コードを投稿できませんでした\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "ロガーパイプから読み取れませんでした: %m" + +#: postmaster/syslogger.c:522 +#, c-format +msgid "logger shutting down" +msgstr "ロガーを停止しています" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "syslog用のパイプを作成できませんでした: %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "システムロガーをforkできませんでした: %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "ログ出力をログ収集プロセスにリダイレクトしています" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "ここからのログ出力はディレクトリ\"%s\"に現れます。" + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "標準出力にリダイレクトできませんでした: %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "標準エラー出力にリダイレクトできませんでした: %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "ログファイルに書き出せませんでした: %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "ロックファイル\"%s\"をオープンできませんでした: %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "自動ローテーションを無効にしています(再度有効にするにはSIGHUPを使用してください)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "正規表現で使用する照合規則を特定できませんでした" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "非決定的照合順序は正規表現ではサポートされていません" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "タイムライン%uは不正です" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "ストリーミングの開始位置が不正です" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "文字列の引用符が閉じていません" + +#: replication/backup_manifest.c:231 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "最終タイムライン%uを期待していましたがタイムライン%uが見つかりました" + +#: replication/backup_manifest.c:248 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "開始タイムライン%uを期待していましたがタイムライン%uが見つかりました" + +#: replication/backup_manifest.c:275 +#, c-format +msgid "start timeline %u not found history of timeline %u" +msgstr "開始タイムライン%uからはタイムライン%uの履歴中にありません" + +#: replication/backup_manifest.c:322 +#, c-format +msgid "could not rewind temporary file" +msgstr "一時ファイルを巻き戻しに失敗しました" + +#: replication/backup_manifest.c:349 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "一時ファイルから読み取りに失敗しました: %m" + +#: replication/basebackup.c:546 +#, c-format +msgid "could not find any WAL files" +msgstr "WALファイルが全くありません" + +#: replication/basebackup.c:561 replication/basebackup.c:577 replication/basebackup.c:586 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "WALファイル\"%s\"がありませんでした" + +#: replication/basebackup.c:629 replication/basebackup.c:659 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "想定しないWALファイルのサイズ\"%s\"" + +#: replication/basebackup.c:644 replication/basebackup.c:1754 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "ベースバックアップがデータを送信できませんでした。バックアップを中止しています" + +#: replication/basebackup.c:722 +#, c-format +msgid "%lld total checksum verification failures" +msgstr " 合計で %lld 個のデータチェックサムエラー" + +#: replication/basebackup.c:726 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "ベースバックアップ中にチェックサム確認が失敗しました" + +#: replication/basebackup.c:779 replication/basebackup.c:788 replication/basebackup.c:797 replication/basebackup.c:806 replication/basebackup.c:815 replication/basebackup.c:826 replication/basebackup.c:843 replication/basebackup.c:852 replication/basebackup.c:864 replication/basebackup.c:888 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "\"%s\"オプションは重複しています" + +#: replication/basebackup.c:832 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%dはパラメータ\"%s\"の有効範囲を超えています(%d .. %d)" + +#: replication/basebackup.c:877 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "認識できない目録オプション: \"%s\"" + +#: replication/basebackup.c:893 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "認識できないチェックサムアルゴリズム: \"%s\"" + +#: replication/basebackup.c:908 +#, c-format +msgid "manifest checksums require a backup manifest" +msgstr "目録のチェックサムにはバックアップ目録が必要です" + +#: replication/basebackup.c:1504 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "スペシャルファイル\"%s\"をスキップしています" + +#: replication/basebackup.c:1623 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "ファイル\"%2$s\"セグメント番号%1$dは不正です" + +#: replication/basebackup.c:1661 +#, c-format +msgid "could not verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "ファイル\"%s\"、ブロック%d でチェックサム検証に失敗しました: 読み込みバッファサイズ%dとページサイズ%dが異なっています" + +#: replication/basebackup.c:1734 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "ファイル\"%s\"のブロック%dでチェックサム検証が失敗しました: 計算されたチェックサムは%Xですが想定は%Xです" + +#: replication/basebackup.c:1741 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "ファイル\"%s\"における以降のチェックサムエラーは報告されません" + +#: replication/basebackup.c:1797 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "ファイル\"%s\"では合計%d個のチェックサムエラーが発生しました" +msgstr[1] "ファイル\"%s\"では合計%d個のチェックサムエラーが発生しました" + +#: replication/basebackup.c:1833 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "ファイル名がtarフォーマットに対して長すぎます: \"%s\"" + +#: replication/basebackup.c:1838 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "シンボリックリンクのリンク先tarのフォーマットにとって長すぎます: ファイル名 \"%s\", リンク先 \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, c-format +msgid "could not clear search path: %s" +msgstr "search_pathを消去できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:251 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "不正な接続文字列の構文: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:275 +#, c-format +msgid "could not parse connection string: %s" +msgstr "接続文字列をパースできませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:347 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "プライマリサーバからデータベースシステムの識別子とタイムライン ID を受信できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:358 replication/libpqwalreceiver/libpqwalreceiver.c:580 +#, c-format +msgid "invalid response from primary server" +msgstr "プライマリサーバからの応答が不正です" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:359 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "システムを識別できませんでした: 受信したのは%d行で%d列、期待していたのは%d行で%d以上の列でした。" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:432 replication/libpqwalreceiver/libpqwalreceiver.c:438 replication/libpqwalreceiver/libpqwalreceiver.c:467 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "WAL ストリーミングを開始できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:490 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "プライマリにストリーミングの終了メッセージを送信できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:512 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "ストリーミングの終了後の想定外の結果セット" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:526 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "ストリーミングCOPY終了中のエラー: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:535 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "ストリーミングコマンドの結果読み取り中のエラー: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:543 replication/libpqwalreceiver/libpqwalreceiver.c:777 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "CommandComplete後の想定外の結果: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:569 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "プライマリサーバからタイムライン履歴ファイルを受信できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:581 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "2個のフィールドを持つ1個のタプルを期待していましたが、%2$d 個のフィールドを持つ %1$d 個のタプルを受信しました。" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:741 replication/libpqwalreceiver/libpqwalreceiver.c:792 replication/libpqwalreceiver/libpqwalreceiver.c:798 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "WAL ストリームからデータを受信できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:817 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "WAL ストリームにデータを送信できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:870 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "レプリケーションスロット\"%s\"を作成できませんでした: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:915 +#, c-format +msgid "invalid query response" +msgstr "不正な問い合わせ応答" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:916 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "%d個の列を期待していましたが、%d列を受信しました。" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:985 +#, c-format +msgid "the query interface requires a database connection" +msgstr "クエリインタフェースの動作にはデータベースコネクションが必要です" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1016 +msgid "empty query" +msgstr "空の問い合わせ" + +#: replication/logical/launcher.c:299 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "サブスクリプション\"%s\"に対応する論理レプリケーションワーカを起動します" + +#: replication/logical/launcher.c:306 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "max_replication_slots = 0 の時は論理レプリケーションワーカは起動できません" + +#: replication/logical/launcher.c:386 +#, c-format +msgid "out of logical replication worker slots" +msgstr "論理レプリケーションワーカスロットは全て使用中です" + +#: replication/logical/launcher.c:387 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "max_logical_replication_workersを増やす必要があるかもしれません。" + +#: replication/logical/launcher.c:442 +#, c-format +msgid "out of background worker slots" +msgstr "バックグラウンドワーカスロットが足りません" + +#: replication/logical/launcher.c:443 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "max_worker_processesを増やす必要があるかもしれません" + +#: replication/logical/launcher.c:642 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "論理レプリケーションワーカスロット%dが空いていないため接続できません" + +#: replication/logical/launcher.c:651 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "論理レプリケーションワーカスロット%dが既に他のワーカに使用されているため接続できません" + +#: replication/logical/launcher.c:955 +#, c-format +msgid "logical replication launcher started" +msgstr "論理レプリケーションランチャが起動しました" + +#: replication/logical/logical.c:105 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "論理デコードを行うためには wal_level >= logical である必要があります" + +#: replication/logical/logical.c:110 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "論理デコードを行うにはデータベース接続が必要です" + +#: replication/logical/logical.c:128 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "リカバリ中は論理デコードは使用できません" + +#: replication/logical/logical.c:311 replication/logical/logical.c:457 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "物理レプリケーションスロットを論理デコードに使用するとはできません" + +#: replication/logical/logical.c:316 replication/logical/logical.c:462 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "レプリケーションスロット\"%s\"はこのデータベースでは作成されていません" + +#: replication/logical/logical.c:323 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "論理レプリケーションスロットは書き込みを行ったトランザクションの中で生成することはできません" + +#: replication/logical/logical.c:502 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "スロット\"%s\"の論理デコードを開始します" + +#: replication/logical/logical.c:504 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "%3$X/%4$XからWALを読み取って、%1$X/%2$X以降にコミットされるトランザクションをストリーミングします。" + +#: replication/logical/logical.c:651 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "スロット\"%s\", 出力プラグイン\"%s\", %sコールバックの処理中, 関連LSN %X/%X" + +#: replication/logical/logical.c:658 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "スロット\"%s\", 出力プラグイン\"%s\", %sコールバックの処理中" + +#: replication/logical/logical.c:965 +#, c-format +msgid "logical streaming requires a stream_start_cb callback" +msgstr "論理ストリーミングを行うにはstream_start_cbコールバックが必要です" + +#: replication/logical/logical.c:1011 +#, c-format +msgid "logical streaming requires a stream_stop_cb callback" +msgstr "論理ストリーミングを行うにはstream_stop_cbコールバックが必要です" + +#: replication/logical/logical.c:1050 +#, c-format +msgid "logical streaming requires a stream_abort_cb callback" +msgstr "論理ストリーミングを行うにはstream_abort_cbコールバックが必要です" + +#: replication/logical/logical.c:1089 +#, c-format +msgid "logical streaming requires a stream_commit_cb callback" +msgstr "論理ストリーミングにはstream_commit_cbコールバックが必要です" + +#: replication/logical/logical.c:1135 +#, c-format +msgid "logical streaming requires a stream_change_cb callback" +msgstr "論理ストリーミングを行うにはstream_change_cbコールバックが必要です" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "レプリケーションスロットを使用するためにはスーパユーザまたはreplicationロールである必要があります" + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "スロット名はnullではあってはなりません" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "オプション配列はnullであってはなりません" + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "配列は1次元でなければなりません" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "配列にはNULL値を含めてはいけません" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "配列の要素数は偶数でなければなりません" + +#: replication/logical/logicalfuncs.c:251 +#, c-format +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "すでにレプリケーションスロット\"%s\"から変更を取り出すことはできません" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:648 +#, c-format +msgid "This slot has never previously reserved WAL, or has been invalidated." +msgstr "このスロットはWALを留保したことがないか、無効化さています。" + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "論理デコード出力プラグイン\"%s\"はバイナリ出力を生成します, しかし関数\"%s\"はテキストデータを期待しています" + +#: replication/logical/origin.c:188 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "max_replication_slots = 0 の時はレプリケーション起点の問い合わせは操作はできません" + +#: replication/logical/origin.c:193 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "リカバリ中はレプリケーション基点を操作できません" + +#: replication/logical/origin.c:228 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "レプリケーション基点\"%s\"は存在しません" + +#: replication/logical/origin.c:319 +#, c-format +msgid "could not find free replication origin OID" +msgstr "複製基点OIDの空きがありません" + +#: replication/logical/origin.c:367 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "OID%dのレプリケーション起点を削除できません, PID%dで使用中です" + +#: replication/logical/origin.c:459 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "OIDが%uのレプリケーション基点がありません" + +#: replication/logical/origin.c:724 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "レプリケーションチェックポイントのマジックナンバー%uは不正です、正しい値は%u" + +#: replication/logical/origin.c:765 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "使用可能なレプリケーションステートが見つかりません、max_replication_slotsを増やしてください" + +#: replication/logical/origin.c:783 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "レプリケーションスロットチェックポイントのチェックサム%uは間違っています、正しくは%uです" + +#: replication/logical/origin.c:911 replication/logical/origin.c:1097 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "OID%dのレプリケーション起点は既にPID%dで使用中です" + +#: replication/logical/origin.c:922 replication/logical/origin.c:1109 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "OID%uのレプリケーション基点に対するレプリケーション状態スロットの空きがありません" + +#: replication/logical/origin.c:924 replication/logical/origin.c:1111 replication/slot.c:1763 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "max_replication_slotsを増やして再度試してください" + +#: replication/logical/origin.c:1068 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "既に初期化されている場合はレプリケーション起点の初期化はできません" + +#: replication/logical/origin.c:1148 replication/logical/origin.c:1364 replication/logical/origin.c:1384 +#, c-format +msgid "no replication origin is configured" +msgstr "レプリケーション起点が構成されていません" + +#: replication/logical/origin.c:1231 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "レプリケーション起点名\"%s\"は予約されています" + +#: replication/logical/origin.c:1233 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "\"pg_\"で始まる起点名は予約されています。" + +#: replication/logical/relation.c:272 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "論理レプリケーション対象のリレーション\"%s.%s\"は存在しません" + +#: replication/logical/relation.c:329 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "論理レプリケーションの対象リレーション\"%s.%s\"はレプリケートされた列の一部を失っています" + +#: replication/logical/relation.c:369 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "論理レプリケーションのターゲットリレーション\"%s.%s\"がREPLICA IDENTITYインデックスでシステム列を使用しています" + +#: replication/logical/reorderbuffer.c:3361 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "XID%uのためのデータファイルの書き出しに失敗しました: %m" + +#: replication/logical/reorderbuffer.c:3678 replication/logical/reorderbuffer.c:3703 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "並べ替えバッファのあふれファイルの読み込みに失敗しました: %m" + +#: replication/logical/reorderbuffer.c:3682 replication/logical/reorderbuffer.c:3707 +#, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "並べ替えバッファのあふれファイルの読み込みに失敗しました: %2$uバイトのはずが%1$dバイトでした" + +#: replication/logical/reorderbuffer.c:3942 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "pg_replslot/%2$s/xid* の削除中にファイル\"%1$s\"が削除できませんでした: %3$m" + +#: replication/logical/reorderbuffer.c:4434 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "ファイル\"%1$s\"の読み込みに失敗しました: %3$dバイトのはずが%2$dバイトでした" + +#: replication/logical/snapbuild.c:607 +#, c-format +msgid "initial slot snapshot too large" +msgstr "初期スロットスナップショットが大きすぎます" + +#: replication/logical/snapbuild.c:661 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "エクスポートされた論理デコードスナップショット: \"%s\" (%u個のトランザクションID を含む)" +msgstr[1] "エクスポートされた論理デコードスナップショット: \"%s\" (%u個のトランザクションID を含む)" + +#: replication/logical/snapbuild.c:1266 replication/logical/snapbuild.c:1359 replication/logical/snapbuild.c:1913 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "論理デコードは一貫性ポイントを%X/%Xで発見しました" + +#: replication/logical/snapbuild.c:1268 +#, c-format +msgid "There are no running transactions." +msgstr "実行中のトランザクションはありません。" + +#: replication/logical/snapbuild.c:1310 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "論理デコードは初期開始点を%X/%Xで発見しました" + +#: replication/logical/snapbuild.c:1312 replication/logical/snapbuild.c:1336 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "%2$uより古いトランザクション(おおよそ%1$d個)の完了を待っています" + +#: replication/logical/snapbuild.c:1334 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "論理デコードは初期の一貫性ポイントを%X/%Xで発見しました" + +#: replication/logical/snapbuild.c:1361 +#, c-format +msgid "There are no old transactions anymore." +msgstr "古いトランザクションはこれ以上はありません" + +#: replication/logical/snapbuild.c:1755 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "スナップショット構築状態ファイル\"%1$s\"のマジックナンバーが不正です: %3$uのはずが%2$uでした" + +#: replication/logical/snapbuild.c:1761 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "スナップショット状態ファイル\"%1$s\"のバージョン%2$uはサポート外です: %3$uのはずが%2$uでした" + +#: replication/logical/snapbuild.c:1860 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "スナップショット生成状態ファイル\"%s\"のチェックサムが一致しません: %uですが、%uであるべきです" + +#: replication/logical/snapbuild.c:1915 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "論理デコードは保存されたスナップショットを使って開始します。" + +#: replication/logical/snapbuild.c:1987 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "ファイル名\"%s\"をパースできませんでした" + +#: replication/logical/tablesync.c:132 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "サブスクリプション\"%s\"、テーブル\"%s\"に対する論理レプリケーションテーブル同期ワーカが終了しました" + +#: replication/logical/tablesync.c:664 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "テーブル\"%s.%s\"のテーブル情報を発行サーバから取得できませんでした: %s" + +#: replication/logical/tablesync.c:670 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "テーブル\"%s.%s\"が発行サーバ上で見つかりませんでした" + +#: replication/logical/tablesync.c:704 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "テーブル\"%s.%s\"のテーブル情報の取得に失敗しました: %s" + +#: replication/logical/tablesync.c:791 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "テーブル\"%s.%s\"の初期内容のコピーを開始できませんでした: %s" + +#: replication/logical/tablesync.c:905 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "テーブルコピー中に発行サーバ上でのトランザクション開始に失敗しました" + +#: replication/logical/tablesync.c:927 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "テーブルコピー中に発行サーバ上でのトランザクション終了に失敗しました" + +#: replication/logical/worker.c:313 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "レプリケーション対象リレーション\"%s.%s\" 列\"%s\"のリモートからのデータを処理中、リモートでの型 %s、ローカルでの型 %s" + +#: replication/logical/worker.c:393 replication/logical/worker.c:522 +#, c-format +msgid "incorrect binary data format in logical replication column %d" +msgstr "論理レプリケーション列%dのバイナリデータ書式が不正です" + +#: replication/logical/worker.c:622 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "ORIGINメッセージが間違った順序で送出されています" + +#: replication/logical/worker.c:772 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "論理レプリケーションの対象リレーション\"%s.%s\"は複製の識別列を期待していましたが、発行サーバは送信しませんでした" + +#: replication/logical/worker.c:779 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "論理レプリケーションの対象リレーション\"%s.%s\"が識別列インデックスも主キーをもっておらず、かつ発行されたリレーションがREPLICA IDENTITY FULLとなっていません" + +#: replication/logical/worker.c:1464 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "不正な論理レプリケーションのメッセージタイプ\"%c\"" + +#: replication/logical/worker.c:1606 +#, c-format +msgid "data stream from publisher has ended" +msgstr "発行サーバからのデータストリームが終了しました" + +#: replication/logical/worker.c:1761 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "タイムアウトにより論理レプリケーションワーカを終了しています" + +#: replication/logical/worker.c:1909 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "サブスクリプション\"%s\"が削除されたため、対応する論理レプリケーション適用ワーカが停止します" + +#: replication/logical/worker.c:1923 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "サブスクリプション\"%s\"が無効化されたため、対応する論理レプリケーション適用ワーカが停止します" + +#: replication/logical/worker.c:1944 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because of a parameter change" +msgstr "パラメータの変更があったため、サブスクリプション\"%s\"に対応する論理レプリケーション適用ワーカが再起動します" + +#: replication/logical/worker.c:2039 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "サブスクリプション%uが削除されたため、対応する論理レプリケーション適用ワーカの起動を中断します" + +#: replication/logical/worker.c:2051 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "サブスクリプション\"%s\"が起動中に無効化されたため、対応する論理レプリケーション適用ワーカは起動しません" + +#: replication/logical/worker.c:2069 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "サブスクリプション\"%s\"、テーブル\"%s\"に対応する論理レプリケーションテーブル同期ワーカが起動しました" + +#: replication/logical/worker.c:2073 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "サブスクリプション\"%s\"に対応する論理レプリケーション適用ワーカが起動しました" + +#: replication/logical/worker.c:2112 +#, c-format +msgid "subscription has no replication slot set" +msgstr "サブスクリプションにレプリケーションスロットが設定されていません" + +#: replication/pgoutput/pgoutput.c:151 +#, c-format +msgid "invalid proto_version" +msgstr "不正なproto_version" + +#: replication/pgoutput/pgoutput.c:156 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version \"%s\"は範囲外です" + +#: replication/pgoutput/pgoutput.c:173 +#, c-format +msgid "invalid publication_names syntax" +msgstr "publication_namesの構文が不正です" + +#: replication/pgoutput/pgoutput.c:226 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "クライアントが proto_version=%d を送信してきましたが、バージョン%d以下のプロトコルのみしかサポートしていません" + +#: replication/pgoutput/pgoutput.c:232 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "クライアントが proto_version=%d を送信してきましたが、バージョン%d以上のプロトコルのみしかサポートしていません" + +#: replication/pgoutput/pgoutput.c:238 +#, c-format +msgid "publication_names parameter missing" +msgstr "publication_namesパラメータが指定されていません" + +#: replication/slot.c:183 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "レプリケーションスロット名\"%s\"は短すぎます" + +#: replication/slot.c:192 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "レプリケーションスロット名\"%s\"は長すぎます" + +#: replication/slot.c:205 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "レプリケーションスロット名\"%s\"は不正な文字を含んでいます" + +#: replication/slot.c:207 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "レプリケーションスロット名は小文字、数字とアンダースコアのみを含むことができます。" + +#: replication/slot.c:254 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "レプリケーションスロット\"%s\"はすでに存在します" + +#: replication/slot.c:264 +#, c-format +msgid "all replication slots are in use" +msgstr "レプリケーションスロットは全て使用中です" + +#: replication/slot.c:265 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "どれか一つを解放するか、max_replication_slots を大きくしてください。" + +#: replication/slot.c:407 replication/slotfuncs.c:760 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "レプリケーションスロット\"%s\"は存在しません" + +#: replication/slot.c:445 replication/slot.c:1007 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "レプリケーションスロット\"%s\"はPID%dで使用中です" + +#: replication/slot.c:684 replication/slot.c:1315 replication/slot.c:1698 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "ディレクトリ\"%s\"を削除できませんでした" + +#: replication/slot.c:1042 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "レプリケーションスロットは max_replication_slots > 0 のときだけ使用できます" + +#: replication/slot.c:1047 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "レプリケーションスロットは wal_level >= replica のときだけ使用できます" + +#: replication/slot.c:1203 +#, c-format +msgid "terminating process %d because replication slot \"%s\" is too far behind" +msgstr "レプリケーションスロット\"%2$s\"の遅れが大きすぎるため、プロセス%1$dを終了しています" + +#: replication/slot.c:1222 +#, c-format +msgid "invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size" +msgstr "restart_lsnの値 %2$X/%3$X が max_slot_wal_keep_size の範囲を超えたため、スロット\"%1$s\"を無効化します" + +#: replication/slot.c:1636 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "レプリケーションスロットファイル\"%1$s\"のマジックナンバーが不正です: %3$uのはずが%2$uでした" + +#: replication/slot.c:1643 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "レプリケーションスロットファイル\"%s\"はサポート外のバージョン%uです" + +#: replication/slot.c:1650 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "レプリケーションスロットファイル\"%s\"のサイズ%uは異常です" + +#: replication/slot.c:1686 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "レプリケーションスロットファイル\"%s\"のチェックサムが一致しません: %uですが、%uであるべきです" + +#: replication/slot.c:1720 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "論理レプリケーションスロット\"%s\"がありますが、wal_level < logical です" + +#: replication/slot.c:1722 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "wal_level を logical もしくはそれより上位の設定にしてください。" + +#: replication/slot.c:1726 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "物理レプリケーションスロット\"%s\"がありますが、wal_level < replica です" + +#: replication/slot.c:1728 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "wal_level を replica もしくはそれより上位の設定にしてください。" + +#: replication/slot.c:1762 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "シャットダウン前のアクティブなレプリケーションスロットの数が多すぎます" + +#: replication/slotfuncs.c:624 +#, c-format +msgid "invalid target WAL LSN" +msgstr "不正な目標WAL LSN" + +#: replication/slotfuncs.c:646 +#, c-format +msgid "replication slot \"%s\" cannot be advanced" +msgstr "レプリケーションスロット\"%s\"は進められません" + +#: replication/slotfuncs.c:664 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "レプリケーションスロットを %X/%X に進めることはできません、最小値は %X/%X" + +#: replication/slotfuncs.c:772 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "物理レプリケーションスロット\"%s\"を論理レプリケーションスロットとしてコピーすることはできません" + +#: replication/slotfuncs.c:774 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "論理レプリケーションスロット\"%s\"を物理レプリケーションスロットとしてコピーすることはできません" + +#: replication/slotfuncs.c:781 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "WAL の留保をしていないレプリケーションスロットはコピーできません" + +#: replication/slotfuncs.c:857 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "レプリケーションスロット\"%s\"をコピーできませんでした" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "コピー処理中にコピー元のレプリケーションスロットが非互換的に変更されました。" + +#: replication/slotfuncs.c:865 +#, c-format +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "未完成の論理レプリケーションスロット\"%s\"はコピーできません" + +#: replication/slotfuncs.c:867 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "このソースレプリケーションスロットの confirmed_flush_lsn が有効値になってから再度実行してください。" + +#: replication/syncrep.c:257 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "管理者コマンドにより同期レプリケーションの待ち状態をキャンセルし、接続を終了しています" + +#: replication/syncrep.c:258 replication/syncrep.c:275 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "トランザクションはローカルではすでにコミット済みですが、スタンバイ側にはレプリケーションされていない可能性があります。" + +#: replication/syncrep.c:274 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "ユーザからの要求により同期レプリケーションの待ち状態をキャンセルしています" + +#: replication/syncrep.c:416 +#, c-format +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "スタンバイの\"%s\"には優先度%uで同期スタンバイが設定されています" + +# y, c-format +#: replication/syncrep.c:483 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "スタンバイ\"%s\"は優先度%uの同期スタンバイになりました" + +#: replication/syncrep.c:487 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "スタンバイ\"%s\"は定足数同期スタンバイの候補になりました" + +#: replication/syncrep.c:1034 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names の読み取りに失敗しました" + +#: replication/syncrep.c:1040 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "同期スタンバイの数(%d)は1以上である必要があります" + +#: replication/walreceiver.c:171 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "管理者コマンドにより WAL 受信プロセスを終了しています" + +#: replication/walreceiver.c:297 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "プライマリサーバへの接続ができませんでした: %s" + +#: replication/walreceiver.c:343 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "データベースシステムの識別子がプライマリサーバとスタンバイサーバ間で異なります" + +#: replication/walreceiver.c:344 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "プライマリ側の識別子は %s ですが、スタンバイ側の識別子は %s です。" + +#: replication/walreceiver.c:354 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "プライマリの最大のタイムライン%uが、リカバリのタイムライン %uより遅れています" + +#: replication/walreceiver.c:408 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "プライマリのタイムライン%3$uの %1$X/%2$XからでWALストリーミングを始めます" + +#: replication/walreceiver.c:413 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "タイムライン%3$uの %1$X/%2$XからでWALストリーミングを再開します" + +#: replication/walreceiver.c:442 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "WAL ストリーミングを継続できません。リカバリはすでに終わっています。" + +#: replication/walreceiver.c:479 +#, c-format +msgid "replication terminated by primary server" +msgstr "プライマリサーバによりレプリケーションが打ち切られました" + +#: replication/walreceiver.c:480 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "タイムライン%uの%X/%XでWALの最後に達しました" + +#: replication/walreceiver.c:568 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "レプリケーションタイムアウトによりwalreceiverを終了しています" + +#: replication/walreceiver.c:606 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "プライマリサーバには要求されたタイムライン%u上にこれ以上WALがありません" + +#: replication/walreceiver.c:622 replication/walreceiver.c:929 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "ログセグメント%sをクローズできませんでした: %m" + +#: replication/walreceiver.c:742 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "プライマリサーバからライムライン%u用のタイムライン履歴ファイルを取り込みしています" + +#: replication/walreceiver.c:976 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "ログファイルセグメント%sのオフセット%uに長さ%luで書き出せませんでした: %m" + +#: replication/walsender.c:523 storage/smgr/md.c:1291 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "ファイル\"%s\"の終端へシークできませんでした: %m" + +#: replication/walsender.c:527 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "ファイル\"%s\"の先頭にシークできませんでした: %m" + +#: replication/walsender.c:578 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM が START_REPLICATION の前に実行されていません" + +#: replication/walsender.c:607 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "論理レプリケーションスロットは物理レプリケーションには使用できません" + +#: replication/walsender.c:676 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "タイムライン%3$u上の要求された開始ポイント%1$X/%2$Xはサーバの履歴にありません" + +#: replication/walsender.c:680 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "サーバの履歴はタイムライン%uの%X/%Xからフォークしました。" + +#: replication/walsender.c:725 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "要求された開始ポイント%X/%XはサーバのWALフラッシュ位置%X/%Xより進んでいます" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:976 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%sはトランザクション内では呼び出せません" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:986 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%sはトランザクション内で呼び出さなければなりません" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:992 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s は REPEATABLE READ 分離レベルのトランザクションで呼び出されなければなりません" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:998 +#, c-format +msgid "%s must be called before any query" +msgstr "%s は問い合わせの実行前に呼び出されなければなりません" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1004 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s はサブトランザクション内では呼び出せません" + +#: replication/walsender.c:1152 +#, c-format +msgid "cannot read from logical replication slot \"%s\"" +msgstr "論理レプリケーションスロット\"%s\"は読み込めません" + +#: replication/walsender.c:1154 +#, c-format +msgid "This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "最大留保量を超えたため、このスロットは無効化されています。" + +#: replication/walsender.c:1164 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "昇格後にWAL送信プロセスを終了します" + +#: replication/walsender.c:1538 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "WAL送信プロセスが停止モードの間は新しいコマンドを実行できません" + +#: replication/walsender.c:1571 +#, c-format +msgid "received replication command: %s" +msgstr "レプリケーションコマンドを受信しました: %s" + +#: replication/walsender.c:1587 tcop/fastpath.c:279 tcop/postgres.c:1103 tcop/postgres.c:1455 tcop/postgres.c:1716 tcop/postgres.c:2174 tcop/postgres.c:2535 tcop/postgres.c:2614 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "現在のトランザクションがアボートしました。トランザクションブロックが終わるまでコマンドは無視されます" + +#: replication/walsender.c:1657 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "物理レプリケーション用のWAL送信プロセスでSQLコマンドは実行できません" + +#: replication/walsender.c:1706 replication/walsender.c:1722 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "スタンバイ接続で想定外のEOFがありました" + +#: replication/walsender.c:1736 +#, c-format +msgid "unexpected standby message type \"%c\", after receiving CopyDone" +msgstr "CopyDoneを受信した後の想定しないスタンバイメッセージタイプ\"%c\"" + +#: replication/walsender.c:1774 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "スタンバイのメッセージタイプ\"%c\"は不正です" + +#: replication/walsender.c:1815 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "想定しないメッセージタイプ\"%c\"" + +#: replication/walsender.c:2234 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "レプリケーションタイムアウトにより WAL 送信プロセスを終了しています" + +#: replication/walsender.c:2311 +#, c-format +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\"は上流サーバに追いつきました" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:989 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "リレーション\"%2$s\"のルール\"%1$s\"はすでに存在します" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "OLDに対するルールアクションは実装されていません" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "代わりにビューかトリガを使用してください。" + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "NEWに対するルールアクションは実装されていません" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "代わりにトリガを使用してください。" + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "SELECTに対するINSTEAD NOTHINGルールは実装されていません" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "代わりにビューを使用してください" + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "SELECTに対するルールにおける複数のアクションは実装されていません" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "SELECTに対するルールはINSTEAD SELECTアクションを持たなければなりません" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "SELECT のルールでは WITH にデータを変更するステートメントを含むことはできません" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "SELECTに対するルールではイベント条件は実装されていません" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "\"%s\"はすでにビューです" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "\"%s\"用のビューのルールの名前は\"%s\"でなければなりません" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "パーティションテーブル\"%s\"はビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:440 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "パーティション子テーブル\"%s\"はビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:449 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "空ではないため、テーブル\"%s\"をビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:458 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "トリガを持っているため、テーブル\"%s\"をビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:460 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "特に、このテーブルは一切の外部キー関係に組み込むことはできません。" + +#: rewrite/rewriteDefine.c:465 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "インデックスを持っているためテーブル\"%s\"をビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:471 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "子テーブルを持っているためテーブル\"%s\"をビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:477 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "行レベルセキュリティが有効になっているため、テーブル\"%s\"をビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:483 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "行レベルセキュリティポリシがあるため、テーブル\"%s\"をビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:510 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "ルールは複数のRETURNINGリストを持つことができません" + +#: rewrite/rewriteDefine.c:515 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "条件付のルールではRETURNINGリストはサポートされません" + +#: rewrite/rewriteDefine.c:519 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "INSTEAD以外のルールではRETURNINGリストはサポートされません" + +#: rewrite/rewriteDefine.c:683 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "SELECTルールのターゲットリストの要素が多すぎます" + +#: rewrite/rewriteDefine.c:684 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "RETURNINGリストの要素が多すぎます" + +#: rewrite/rewriteDefine.c:711 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "削除された列を持つリレーションをビューに変換できませんでした" + +#: rewrite/rewriteDefine.c:712 +#, c-format +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "削除された列を持つリレーションにRETURNINGリストを生成することはできませんでした" + +#: rewrite/rewriteDefine.c:718 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "SELECTルールのターゲットエントリ%dは列\"%s\"とは異なる列名を持っています" + +#: rewrite/rewriteDefine.c:720 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECTのターゲットエントリは\"%s\"と名付けられています。" + +#: rewrite/rewriteDefine.c:729 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "SELECTルールの対象項目%dは\"%s\"と異なる列型を持っています" + +#: rewrite/rewriteDefine.c:731 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "RETURNINGリスト項目%dは\"%s\"と異なる列型を持っています" + +#: rewrite/rewriteDefine.c:734 rewrite/rewriteDefine.c:758 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECTのターゲットエントリの型は%sですが、列の型は%sです。" + +#: rewrite/rewriteDefine.c:737 rewrite/rewriteDefine.c:762 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "RETURNINGリストの要素の型は%sですが、列の型は%sです。" + +#: rewrite/rewriteDefine.c:753 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "SELECTルールの対象項目%dは\"%s\"と異なる列のサイズを持っています" + +#: rewrite/rewriteDefine.c:755 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "RETURNINGリスト項目%dは\"%s\"と異なる列のサイズを持っています" + +#: rewrite/rewriteDefine.c:772 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "SELECTルールのターゲットリストの項目が少なすぎます" + +#: rewrite/rewriteDefine.c:773 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "RETURNINGリストの項目が少なすぎます" + +#: rewrite/rewriteDefine.c:866 rewrite/rewriteDefine.c:980 rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "リレーション\"%2$s\"のルール\"%1$s\"は存在しません" + +#: rewrite/rewriteDefine.c:999 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "ON SELECTルールの名前を変更することはできません" + +#: rewrite/rewriteHandler.c:545 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "WITH の問い合わせ名\"%s\"が、ルールのアクションと書き換えられようとしている問い合わせの両方に現れています" + +#: rewrite/rewriteHandler.c:605 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "複数ルールではRETURNINGリストを持つことはできません" + +#: rewrite/rewriteHandler.c:816 rewrite/rewriteHandler.c:828 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "列\"%s\"への挿入はできません" + +#: rewrite/rewriteHandler.c:817 rewrite/rewriteHandler.c:839 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "列\"%s\"は GENERATED ALWAYS として定義されています。" + +#: rewrite/rewriteHandler.c:819 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "OVERRIDING SYSTEM VALUE を指定することで挿入を強制できます。" + +#: rewrite/rewriteHandler.c:838 rewrite/rewriteHandler.c:845 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "列\"%s\"はDEFAULTにのみ更新可能です" + +#: rewrite/rewriteHandler.c:1014 rewrite/rewriteHandler.c:1032 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "同じ列\"%s\"に複数の代入があります" + +#: rewrite/rewriteHandler.c:2062 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "リレーション\"%s\"のポリシで無限再帰を検出しました" + +#: rewrite/rewriteHandler.c:2382 +msgid "Junk view columns are not updatable." +msgstr "ジャンクビュー列は更新不可です。" + +#: rewrite/rewriteHandler.c:2387 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "基底リレーションの列ではないビュー列は更新不可です。" + +#: rewrite/rewriteHandler.c:2390 +msgid "View columns that refer to system columns are not updatable." +msgstr "システム列を参照するビュー列は更新不可です。" + +#: rewrite/rewriteHandler.c:2393 +msgid "View columns that return whole-row references are not updatable." +msgstr "行全体参照を返すビュー列は更新不可です。" + +#: rewrite/rewriteHandler.c:2454 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "DISTINCTを含むビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2457 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "GROUP BYを含むビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2460 +msgid "Views containing HAVING are not automatically updatable." +msgstr "HAVINGを含むビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2463 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "UNION、INTERSECT、EXCEPTを含むビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2466 +msgid "Views containing WITH are not automatically updatable." +msgstr "WITHを含むビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2469 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "LIMIT、OFFSETを含むビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2481 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "集約関数を返すビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2484 +msgid "Views that return window functions are not automatically updatable." +msgstr "ウィンドウ関数を返すビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2487 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "集合返却関数を返すビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2494 rewrite/rewriteHandler.c:2498 rewrite/rewriteHandler.c:2506 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "単一のテーブルまたはビューからselectしていないビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2509 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "TABLESAMPLEを含むビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:2533 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "更新可能な列を持たないビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:3010 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "ビュー\"%2$s\"の列\"%1$s\"への挿入はできません" + +#: rewrite/rewriteHandler.c:3018 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "ビュー\"%2$s\"の列\"%1$s\"は更新できません" + +#: rewrite/rewriteHandler.c:3496 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "WITH にデータを変更するステートメントがある場合は DO INSTEAD NOTHING ルールはサポートされません" + +#: rewrite/rewriteHandler.c:3510 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "WITH にデータを変更するステートメントがある場合は、条件付き DO INSTEAD ルールはサポートされません" + +#: rewrite/rewriteHandler.c:3514 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "WITH にデータを変更するステートメントがある場合は DO ALSO ルールはサポートされません" + +#: rewrite/rewriteHandler.c:3519 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "WITH にデータを変更するステートメントがある場合はマルチステートメントの DO INSTEAD ルールはサポートされません" + +#: rewrite/rewriteHandler.c:3710 rewrite/rewriteHandler.c:3718 rewrite/rewriteHandler.c:3726 +#, c-format +msgid "Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "条件付きDO INSTEADルールを持つビューは自動更新できません。" + +#: rewrite/rewriteHandler.c:3819 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "リレーション\"%s\"へのINSERT RETURNINGを行うことはできません" + +#: rewrite/rewriteHandler.c:3821 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "RETURNING句を持つ無条件のON INSERT DO INSTEADルールが必要です。" + +#: rewrite/rewriteHandler.c:3826 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "リレーション\"%s\"へのUPDATE RETURNINGを行うことはできません" + +#: rewrite/rewriteHandler.c:3828 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "RETURNING句を持つ無条件のON UPDATE DO INSTEADルールが必要です。" + +#: rewrite/rewriteHandler.c:3833 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "リレーション\"%s\"へのDELETE RETURNINGを行うことはできません" + +#: rewrite/rewriteHandler.c:3835 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "RETURNING句を持つ無条件のON DELETE DO INSTEADルールが必要です。" + +#: rewrite/rewriteHandler.c:3853 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "ON CONFLICT句を伴うINSERTは、INSERTまたはUPDATEルールを持つテーブルでは使えません" + +#: rewrite/rewriteHandler.c:3910 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "複数問い合わせに対するルールにより書き換えられた問い合わせでは WITH を使用できません" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "条件付きのユーティリティ文は実装されていません" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "ビューに対するWHERE CURRENT OFは実装されていません" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "ON UPDATE ルールのNEW変数は、対象のUPDATEコマンドでの複数列代入の一部となる列を参照することはできません" + +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "/*コメントが閉じていません" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "ビット列リテラルの終端がありません" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "16進数文字列リテラルの終端がありません" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "Unicodeエスケープを使った文字列定数の危険な使用" + +#: scan.l:543 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "Unicodeエスケープはstandard_conforming_stringsが無効な時に使用することはできません。" + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "xqsの中で処理されない前ステート" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Unicodeエスケープは\\uXXXXまたは\\UXXXXXXXXでなければなりません。" + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "文字列リテラルで安全ではない\\'が使用されました。" + +#: scan.l:690 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "文字列内で引用符を記述するには''を使用してください。\\'はクライアントのみで有効な符号化形式では安全ではありません。" + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "文字列のドル引用符が閉じていません" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "二重引用符で囲まれた識別子の長さがゼロです" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "識別子の引用符が閉じていません" + +#: scan.l:963 +msgid "operator too long" +msgstr "演算子が長すぎます" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1172 +#, c-format +msgid "%s at end of input" +msgstr "入力の最後で %s" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1180 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "\"%2$s\"またはその近辺で%1$s" + +#: scan.l:1374 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "文字列リテラルないでの\\'の非標準的な使用" + +#: scan.l:1375 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "文字列内で単一引用符を記述するには''、またはエスケープ文字列構文(E'...')を使用してください。" + +#: scan.l:1384 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "文字列リテラル内での\\\\の非標準的な使用" + +#: scan.l:1385 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "バックスラッシュのエスケープ文字列構文、例えばE'\\\\'を使用してください。" + +#: scan.l:1399 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "文字列リテラル内でのエスケープの非標準的な使用" + +#: scan.l:1400 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "エスケープのエスケープ文字列構文、例えばE'\\r\\n'を使用してください。" + +#: snowball/dict_snowball.c:209 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "言語\"%s\"および符号化方式\"%s\"用に使用可能なSnowballステマがありません" + +#: snowball/dict_snowball.c:232 tsearch/dict_ispell.c:74 tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "重複したStopWordsパラメータ" + +#: snowball/dict_snowball.c:241 +#, c-format +msgid "multiple Language parameters" +msgstr "重複したLanguageパラメータ" + +#: snowball/dict_snowball.c:248 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "認識できないSnowballパラメータ: \"%s\"" + +#: snowball/dict_snowball.c:256 +#, c-format +msgid "missing Language parameter" +msgstr "Languageパラメータがありません" + +#: statistics/dependencies.c:667 statistics/dependencies.c:720 statistics/mcv.c:1477 statistics/mcv.c:1508 statistics/mvdistinct.c:348 statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:42 utils/adt/pseudotypes.c:76 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "%s型の値は受け付けられません" + +#: statistics/extended_stats.c:145 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "統計オブジェクト\"%s.%s\"がリレーション\"%s.%s\"に対して計算できませんでした" + +#: statistics/mcv.c:1365 utils/adt/jsonfuncs.c:1800 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "レコード型を受け付けられないコンテキストでレコードを返す関数が呼び出されました" + +#: storage/buffer/bufmgr.c:589 storage/buffer/bufmgr.c:670 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "他のセッションの一時テーブルにはアクセスできません" + +#: storage/buffer/bufmgr.c:826 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "リレーション %2$s の %1$u ブロック目で、EOF の先に想定外のデータを検出しました" + +#: storage/buffer/bufmgr.c:828 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "これはカーネルの不具合で発生した模様です。システムの更新を検討してください。" + +#: storage/buffer/bufmgr.c:926 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "リレーション %2$s の %1$u ブロック目のページが不正です: ページをゼロで埋めました" + +#: storage/buffer/bufmgr.c:4246 +#, c-format +msgid "could not write block %u of %s" +msgstr "%u ブロックを %s に書き出せませんでした" + +#: storage/buffer/bufmgr.c:4248 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "複数回失敗しました ---ずっと書き込みエラーが続くかもしれません。" + +#: storage/buffer/bufmgr.c:4269 storage/buffer/bufmgr.c:4288 +#, c-format +msgid "writing block %u of relation %s" +msgstr "ブロック %u を リレーション %s に書き込んでいます" + +#: storage/buffer/bufmgr.c:4591 +#, c-format +msgid "snapshot too old" +msgstr "スナップショットが古すぎます" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "利用できる、空のローカルバッファがありません" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "並列処理中は一時テーブルにはアクセスできません" + +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "BufFile \"%2$s\"の一時ファイル\"%1$s\"をオープンできませんでした: %m" + +#: storage/file/buffile.c:791 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "BufFile \"%s\"の一時ファイル\"%s\"のサイズの確認に失敗しました: %m" + +#: storage/file/fd.c:508 storage/file/fd.c:580 storage/file/fd.c:616 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "ダーティーデータを書き出しできませんでした: %m" + +#: storage/file/fd.c:538 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "ダーティーデータのサイズを特定できませんでした: %m" + +#: storage/file/fd.c:590 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "データの書き出し中にmunmap()に失敗しました: %m" + +#: storage/file/fd.c:798 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "ファイル\"%s\"から\"%s\"へのリンクができませんでした: %m" + +#: storage/file/fd.c:881 +#, c-format +msgid "getrlimit failed: %m" +msgstr "getrlimitが失敗しました: %m" + +#: storage/file/fd.c:971 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "サーバプロセスを起動させるために利用できるファイル記述子が不足しています" + +#: storage/file/fd.c:972 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "システムでは%d使用できますが、少なくとも%d必要です" + +#: storage/file/fd.c:1023 storage/file/fd.c:2357 storage/file/fd.c:2467 storage/file/fd.c:2618 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "ファイル記述子が不足しています: %m: 解放後再実行してください" + +#: storage/file/fd.c:1397 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "一時ファイル: パス \"%s\"、サイズ %lu" + +#: storage/file/fd.c:1528 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "一時ディレクトリ\"%s\"を作成できませんでした: %m" + +#: storage/file/fd.c:1535 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "一時サブディレクトリ\"%s\"を作成できませんでした: %m" + +#: storage/file/fd.c:1728 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "一時ファイル\"%s\"を作成できませんでした: %m" + +#: storage/file/fd.c:1763 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "一時ファイル\"%s\"をオープンできませんでした: %m" + +#: storage/file/fd.c:1804 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "一時ファイル\"%s\"を unlink できませんでした: %m" + +#: storage/file/fd.c:2068 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "一時ファイルのサイズがtemp_file_limit(%d KB)を超えています" + +#: storage/file/fd.c:2333 storage/file/fd.c:2392 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "ファイル\"%2$s\"をオープンしようとした時にmaxAllocatedDescs(%1$d)を超えました" + +#: storage/file/fd.c:2437 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "コマンド\"%2$s\"を実行しようとした時にmaxAllocatedDescs(%1$d)を超えました" + +#: storage/file/fd.c:2594 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "ディレクトリ\"%2$s\"をオープンしようとした時にmaxAllocatedDescs(%1$d)を超えました" + +#: storage/file/fd.c:3122 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "一時ファイル用ディレクトリに想定外のファイルがありました: \"%s\"" + +#: storage/file/sharedfileset.c:111 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "すでに破棄されているため SharedFileSet にアタッチできません" + +#: storage/ipc/dsm.c:351 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "動的共有メモリの制御セグメントが壊れています" + +#: storage/ipc/dsm.c:415 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "動的共有メモリの制御セグメントの内容が不正です" + +#: storage/ipc/dsm.c:592 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "動的共有メモリセグメントが多すぎます" + +#: storage/ipc/dsm_impl.c:233 storage/ipc/dsm_impl.c:529 storage/ipc/dsm_impl.c:633 storage/ipc/dsm_impl.c:804 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"をアンマップできませんでした: %m" + +#: storage/ipc/dsm_impl.c:243 storage/ipc/dsm_impl.c:539 storage/ipc/dsm_impl.c:643 storage/ipc/dsm_impl.c:814 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"を削除できませんでした: %m" + +#: storage/ipc/dsm_impl.c:267 storage/ipc/dsm_impl.c:714 storage/ipc/dsm_impl.c:828 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"をオープンできませんでした: %m" + +#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:555 storage/ipc/dsm_impl.c:759 storage/ipc/dsm_impl.c:852 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"へのstatが失敗しました: %m" + +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:903 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "共有メモリセグメント\"%s\"の%zuバイトへのサイズ変更ができませんでした: %m" + +#: storage/ipc/dsm_impl.c:341 storage/ipc/dsm_impl.c:576 storage/ipc/dsm_impl.c:735 storage/ipc/dsm_impl.c:925 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"をマップできませんでした: %m" + +#: storage/ipc/dsm_impl.c:511 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "共有メモリセグメントを取得できませんでした: %m" + +#: storage/ipc/dsm_impl.c:699 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"を作成できませんでした: %m" + +#: storage/ipc/dsm_impl.c:936 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"をクローズできませんでした: %m" + +#: storage/ipc/dsm_impl.c:975 storage/ipc/dsm_impl.c:1023 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "\"%s\"のハンドルの複製ができませんでした: %m" + +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:988 storage/ipc/latch.c:1142 storage/ipc/latch.c:1355 storage/ipc/latch.c:1505 storage/ipc/latch.c:1618 +#, c-format +msgid "%s failed: %m" +msgstr "%s が失敗しました: %m" + +#: storage/ipc/procarray.c:3630 +#, c-format +msgid "database \"%s\" is being used by prepared transaction" +msgstr "データベース\"%s\"は準備済みトランザクションで使用中です" + +#: storage/ipc/procarray.c:3662 storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "スーパユーザのプロセスを終了させるにはスーパユーザである必要があります" + +#: storage/ipc/procarray.c:3669 storage/ipc/signalfuncs.c:147 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "終了しようとしているプロセスのロールまたはpg_signal_backendのメンバである必要があります。" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:982 storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 storage/lmgr/lock.c:4174 storage/lmgr/lock.c:4239 storage/lmgr/lock.c:4531 storage/lmgr/predicate.c:2401 storage/lmgr/predicate.c:2416 storage/lmgr/predicate.c:3898 storage/lmgr/predicate.c:5009 utils/hash/dynahash.c:1086 +#, c-format +msgid "out of shared memory" +msgstr "共有メモリが足りません" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "共有メモリが足りません (%zu バイト要求しました)" + +#: storage/ipc/shmem.c:441 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "データ構造体\"%s\"のためのShmemIndexエントリを作成できませんでした" + +#: storage/ipc/shmem.c:456 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "データ構造体\"%s\"のためのShmemIndexエントリのサイズが誤っています: %zuバイトを期待しましたが、実際は%zuバイトでした" + +#: storage/ipc/shmem.c:475 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "データ構造体\"%s\"のための共有メモリが不足しています ( %zu バイトが必要)" + +#: storage/ipc/shmem.c:507 storage/ipc/shmem.c:526 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "要求された共有メモリのサイズはsize_tを超えています" + +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %dはPostgreSQLサーバプロセスではありません" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1362 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "プロセス%dにシグナルを送信できませんでした: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "スーパユーザの問い合わせをキャンセルするにはスーパユーザである必要があります" + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "キャンセルしようとしている問い合わせのロールまたはpg_signal_backendのメンバである必要があります" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "adminpack 1.0 でログファイルをローテートするにはスーパユーザである必要があります" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:253 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "代わりにコアの一部である %s の使用を検討してください。" + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "ログ収集が活動していませんのでローテーションを行うことができません" + +#: storage/ipc/standby.c:580 tcop/postgres.c:3177 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "リカバリで競合が発生したためステートメントをキャンセルしています" + +#: storage/ipc/standby.c:581 tcop/postgres.c:2469 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "リカバリ時にユーザのトランザクションがバッファのデッドロックを引き起こしました。" + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "OID%u、ページ%dに対応するpg_largeobjectのエントリのデータフィールドの大きさ%dは不正です" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "ラージオブジェクトを開くためのフラグが不正です: %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "不正なwhence設定: %d" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "ラージオブジェクトの書き出し要求サイズが不正です: %d" + +#: storage/lmgr/deadlock.c:1122 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "プロセス %d は %s を %s で待機していましたが、プロセス %d でブロックされました" + +#: storage/lmgr/deadlock.c:1141 +#, c-format +msgid "Process %d: %s" +msgstr "プロセス %d: %s" + +#: storage/lmgr/deadlock.c:1150 +#, c-format +msgid "deadlock detected" +msgstr "デッドロックを検出しました" + +#: storage/lmgr/deadlock.c:1153 +#, c-format +msgid "See server log for query details." +msgstr "問い合わせの詳細はサーバログを参照してください" + +#: storage/lmgr/lmgr.c:830 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"のタプル(%1$u,%2$u)の更新中" + +#: storage/lmgr/lmgr.c:833 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"のタプル(%1$u,%2$u)の削除中" + +#: storage/lmgr/lmgr.c:836 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"のタプル(%1$u,%2$u)のロック中" + +#: storage/lmgr/lmgr.c:839 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "リレーション\"%3$s\"のタプルの更新後バージョン(%1$u,%2$u)のロック中" + +#: storage/lmgr/lmgr.c:842 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"のインデックスタプル(%1$u,%2$u)の挿入中" + +#: storage/lmgr/lmgr.c:845 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"のタプル(%1$u,%2$u)の一意性の確認中" + +#: storage/lmgr/lmgr.c:848 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"の更新されたタプル(%1$u,%2$u)の再チェック中" + +#: storage/lmgr/lmgr.c:851 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"のタプル(%1$u,%2$u)に対する排除制約のチェック中" + +#: storage/lmgr/lmgr.c:1106 +#, c-format +msgid "relation %u of database %u" +msgstr "データベース%2$uのリレーション%1$u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "データベース%2$uのリレーション%1$uの拡張" + +#: storage/lmgr/lmgr.c:1118 +#, c-format +msgid "pg_database.datfrozenxid of database %u" +msgstr "データベース%uのpg_database.datfrozenxid" + +#: storage/lmgr/lmgr.c:1123 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "データベース%3$uのリレーション%2$uのページ%1$u" + +#: storage/lmgr/lmgr.c:1130 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "データベース%4$uのリレーション%3$uのタプル(%2$u,%1$u)" + +#: storage/lmgr/lmgr.c:1138 +#, c-format +msgid "transaction %u" +msgstr "トランザクション %u" + +#: storage/lmgr/lmgr.c:1143 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "仮想トランザクション %d/%u" + +#: storage/lmgr/lmgr.c:1149 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "トランザクション%2$uの投機的書き込みトークン%1$u" + +#: storage/lmgr/lmgr.c:1155 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "データベース%3$uのリレーション%2$uのオブジェクト%1$u" + +#: storage/lmgr/lmgr.c:1163 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "ユーザロック[%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1170 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "アドバイザリ・ロック[%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1178 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "ロックタグタイプ%dは不明です" + +#: storage/lmgr/lock.c:803 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "リカバリの実行中はデータベースオブジェクトでロックモード %s を獲得できません" + +#: storage/lmgr/lock.c:805 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "リカバリの実行中は、データベースオブジェクトで RowExclusiveLock もしくはそれ以下だけが獲得できます" + +#: storage/lmgr/lock.c:983 storage/lmgr/lock.c:1021 storage/lmgr/lock.c:2846 storage/lmgr/lock.c:4175 storage/lmgr/lock.c:4240 storage/lmgr/lock.c:4532 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "max_locks_per_transactionを増やす必要があるかもしれません" + +#: storage/lmgr/lock.c:3292 storage/lmgr/lock.c:3408 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "同一オブジェクト上にセッションレベルとトランザクションレベルのロックの両方を保持している時にPREPAREすることはできません" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "RWConflictPoolに読み書き競合を記録するための要素が不足しています" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "トランザクションの同時実行数を減らすか max_connections を増やす必要があるかもしれません" + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "RWConflictPoolに読み書き競合の可能性を記録するための要素が不足しています" + +#: storage/lmgr/predicate.c:1535 +#, c-format +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "遅延可能スナップショットは安全ではありません。新しいスナップショットを取得しようとしています。" + +#: storage/lmgr/predicate.c:1624 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "\"default_transaction_isolation\"が\"serializable\"に設定されました。" + +#: storage/lmgr/predicate.c:1625 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "このデフォルトを変更するためには\"SET default_transaction_isolation = 'repeatable read'\"を使用することができます。" + +#: storage/lmgr/predicate.c:1676 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "スナップショットをインポートするトランザクションはREAD ONLY DEFERRABLEではいけません" + +#: storage/lmgr/predicate.c:1755 utils/time/snapmgr.c:618 utils/time/snapmgr.c:624 +#, c-format +msgid "could not import the requested snapshot" +msgstr "要求したスナップショットをインポートできませんでした" + +#: storage/lmgr/predicate.c:1756 utils/time/snapmgr.c:625 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "PID%dであるソースプロセスは既に実行中ではありません。" + +#: storage/lmgr/predicate.c:2402 storage/lmgr/predicate.c:2417 storage/lmgr/predicate.c:3899 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "max_pred_locks_per_transaction を増やす必要があるかもしれません" + +#: storage/lmgr/predicate.c:4030 storage/lmgr/predicate.c:4066 storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4107 storage/lmgr/predicate.c:4146 storage/lmgr/predicate.c:4388 storage/lmgr/predicate.c:4725 storage/lmgr/predicate.c:4737 storage/lmgr/predicate.c:4780 storage/lmgr/predicate.c:4818 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "トランザクション間で read/write の依存性があったため、アクセスの直列化ができませんでした" + +#: storage/lmgr/predicate.c:4032 storage/lmgr/predicate.c:4068 storage/lmgr/predicate.c:4101 storage/lmgr/predicate.c:4109 storage/lmgr/predicate.c:4148 storage/lmgr/predicate.c:4390 storage/lmgr/predicate.c:4727 storage/lmgr/predicate.c:4739 storage/lmgr/predicate.c:4782 storage/lmgr/predicate.c:4820 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "リトライが行われた場合、このトランザクションは成功するかもしれません" + +#: storage/lmgr/proc.c:355 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "要求されたスタンバイ接続が max_wal_senders を超えています(現在は %d)" + +#: storage/lmgr/proc.c:1333 +#, c-format +msgid "Process %d waits for %s on %s." +msgstr "プロセス%dは%sを%sで待機しています。" + +#: storage/lmgr/proc.c:1344 +#, c-format +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "ブロックしている自動VACUUMプロセスのPID %dへキャンセルを送付しています" + +#: storage/lmgr/proc.c:1464 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "プロセス%1$dは、%4$ld.%5$03d ms後にキューの順番を再調整することで、%3$s上の%2$sに対するデッドロックを防ぎました。" + +#: storage/lmgr/proc.c:1479 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "プロセス%1$dは、%3$s上の%2$sに対し%4$ld.%5$03d ms待機するデッドロックを検知しました" + +#: storage/lmgr/proc.c:1488 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "プロセス%dは%sを%sで待機しています。%ld.%03dミリ秒後" + +#: storage/lmgr/proc.c:1495 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "プロセス%1$dは%4$ld.%5$03d ms後に%3$s上の%2$sを獲得しました" + +#: storage/lmgr/proc.c:1511 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "プロセス%1$dは%4$ld.%5$03d ms後に%3$s上で%2$sを獲得することに失敗しました" + +#: storage/page/bufpage.c:145 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "ページ検証が失敗しました。計算されたチェックサムは%uですが想定は%uです" + +#: storage/page/bufpage.c:209 storage/page/bufpage.c:503 storage/page/bufpage.c:740 storage/page/bufpage.c:873 storage/page/bufpage.c:969 storage/page/bufpage.c:1081 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "ページポインタが破損しています: lower = %u, upper = %u, special = %u\"" + +#: storage/page/bufpage.c:525 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "ラインポインタが破損しています: %u" + +#: storage/page/bufpage.c:552 storage/page/bufpage.c:924 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "アイテム長が破損しています: 合計 %u 利用可能空間 %u" + +#: storage/page/bufpage.c:759 storage/page/bufpage.c:897 storage/page/bufpage.c:985 storage/page/bufpage.c:1097 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "ラインポインタが破損しています: オフセット = %u サイズ = %u" + +#: storage/smgr/md.c:333 storage/smgr/md.c:836 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "ファイル\"%s\"の切り詰め処理ができませんでした: %m" + +#: storage/smgr/md.c:407 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "ファイル\"%s\"を%uブロック以上に拡張できません" + +#: storage/smgr/md.c:422 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "ファイル\"%s\"を拡張できませんでした: %m" + +#: storage/smgr/md.c:424 storage/smgr/md.c:431 storage/smgr/md.c:719 +#, c-format +msgid "Check free disk space." +msgstr "ディスクの空き容量をチェックしてください。" + +#: storage/smgr/md.c:428 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "ファイル\"%1$s\"を拡張できませんでした: %4$uブロックで%3$dバイト中%2$dバイト分のみを書き出しました。" + +#: storage/smgr/md.c:640 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "ファイル\"%2$s\"で%1$uブロックを読み取れませんでした: %3$m" + +#: storage/smgr/md.c:656 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "ファイル\"%2$s\"のブロック%1$uを読み取れませんでした: %4$dバイト中%3$dバイト分のみ読み取りました" + +#: storage/smgr/md.c:710 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "ファイル\"%2$s\"で%1$uブロックが書き出せませんでした: %3$m" + +#: storage/smgr/md.c:715 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "ファイル\"%2$s\"のブロック%1$uを書き込めませんでした: %4$dバイト中%3$dバイト分のみ書き込みました" + +#: storage/smgr/md.c:807 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "ファイル\"%s\"を%uブロックに切り詰められませんでした: 現在は%uブロックのみとなりました" + +#: storage/smgr/md.c:862 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "ファイル\"%s\"を%uブロックに切り詰められませんでした: %m" + +#: storage/smgr/md.c:957 +#, c-format +msgid "could not forward fsync request because request queue is full" +msgstr "リクエストキューが満杯につき fsync リクエストのフォワードができませんでした" + +#: storage/smgr/md.c:1256 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "ファイル\"%s\"(対象ブロック%u)をオープンできませんでした: 直前のセグメントは%uブロックだけでした" + +#: storage/smgr/md.c:1270 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "ファイル \"%s\"(対象ブロック %u)をオープンできませんでした: %m" + +#: storage/sync/sync.c:401 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "ファイル\"%s\"をfsyncできませんでした: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "関数呼び出しメッセージ内の引数サイズ%dが不正です" + +#: tcop/fastpath.c:307 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "近道関数呼び出し: \"%s\"(OID %u))" + +#: tcop/fastpath.c:389 tcop/postgres.c:1323 tcop/postgres.c:1581 tcop/postgres.c:2013 tcop/postgres.c:2250 +#, c-format +msgid "duration: %s ms" +msgstr "期間: %s ミリ秒" + +#: tcop/fastpath.c:393 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "期間: %sミリ秒 ファストパス関数呼び出し: \"%s\" (OID %u)" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "関数呼び出しメッセージには%d引数ありましたが、関数には%d必要です" + +#: tcop/fastpath.c:437 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "関数呼び出しメッセージには%dの引数書式がありましたが、引数は%dでした" + +#: tcop/fastpath.c:524 tcop/fastpath.c:607 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "関数引数%dのバイナリデータ書式が不正です" + +#: tcop/postgres.c:355 tcop/postgres.c:391 tcop/postgres.c:418 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "クライアント接続に想定外のEOFがありました" + +#: tcop/postgres.c:441 tcop/postgres.c:453 tcop/postgres.c:464 tcop/postgres.c:476 tcop/postgres.c:4539 +#, c-format +msgid "invalid frontend message type %d" +msgstr "フロントエンドメッセージタイプ%dが不正です" + +#: tcop/postgres.c:1042 +#, c-format +msgid "statement: %s" +msgstr "文: %s" + +#: tcop/postgres.c:1328 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "期間: %s ミリ秒 文: %s" + +#: tcop/postgres.c:1377 +#, c-format +msgid "parse %s: %s" +msgstr "パース %s: %s" + +#: tcop/postgres.c:1434 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "準備された文に複数のコマンドを挿入できません" + +#: tcop/postgres.c:1586 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "期間: %s ミリ秒 パース%s : %s" + +#: tcop/postgres.c:1633 +#, c-format +msgid "bind %s to %s" +msgstr "バインド%s: %s" + +#: tcop/postgres.c:1652 tcop/postgres.c:2516 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "無名の準備された文が存在しません" + +#: tcop/postgres.c:1693 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "バインドメッセージは%dパラメータ書式ありましたがパラメータは%dでした" + +#: tcop/postgres.c:1699 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "バインドメッセージは%dパラメータを提供しましたが、準備された文\"%s\"では%d必要でした" + +#: tcop/postgres.c:1897 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "バインドパラメータ%dにおいてバイナリデータ書式が不正です" + +#: tcop/postgres.c:2018 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "期間: %s ミリ秒 バインド %s%s%s: %s" + +#: tcop/postgres.c:2068 tcop/postgres.c:2600 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "ポータル\"%s\"は存在しません" + +#: tcop/postgres.c:2153 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2155 tcop/postgres.c:2258 +msgid "execute fetch from" +msgstr "取り出し実行" + +#: tcop/postgres.c:2156 tcop/postgres.c:2259 +msgid "execute" +msgstr "実行" + +#: tcop/postgres.c:2255 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "期間: %s ミリ秒 %s %s%s%s: %s" + +#: tcop/postgres.c:2401 +#, c-format +msgid "prepare: %s" +msgstr "準備: %s" + +#: tcop/postgres.c:2426 +#, c-format +msgid "parameters: %s" +msgstr "パラメータ: %s" + +#: tcop/postgres.c:2441 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "異常終了の理由: リカバリが衝突したため" + +#: tcop/postgres.c:2457 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "ユーザが共有バッファ・ピンを長く保持し過ぎていました" + +#: tcop/postgres.c:2460 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "ユーザリレーションのロックを長く保持し過ぎていました" + +#: tcop/postgres.c:2463 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "削除されるべきテーブルスペースをユーザが使っていました(もしくはその可能性がありました)。" + +#: tcop/postgres.c:2466 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "削除されるべきバージョンの行をユーザ問い合わせが参照しなければならなかった可能性がありました。" + +#: tcop/postgres.c:2472 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "削除されるべきデータベースにユーザが接続していました。" + +#: tcop/postgres.c:2796 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "他のサーバプロセスがクラッシュしたため接続を終了します" + +#: tcop/postgres.c:2797 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "" +"他のサーバプロセスが異常終了し共有メモリが破損した可能性がありましたので、\n" +"postmasterはこのサーバプロセスに対し、現在のトランザクションをロールバック\n" +"し終了するよう指示しました。" + +#: tcop/postgres.c:2801 tcop/postgres.c:3107 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "この後、データベースに再接続し、コマンドを繰り返さなければなりません。" + +#: tcop/postgres.c:2883 +#, c-format +msgid "floating-point exception" +msgstr "浮動小数点例外" + +#: tcop/postgres.c:2884 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "不正な浮動小数点演算がシグナルされました。おそらくこれは、範囲外の結果もしくは0除算のような不正な演算によるものです。" + +#: tcop/postgres.c:3037 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "タイムアウトにより認証処理をキャンセルしています" + +#: tcop/postgres.c:3041 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "管理者コマンドにより自動VACUUM処理を終了しています" + +#: tcop/postgres.c:3045 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "管理者コマンドにより、論理レプリケーションワーカを終了します" + +#: tcop/postgres.c:3049 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "論理レプリケーションランチャを停止します" + +#: tcop/postgres.c:3062 tcop/postgres.c:3072 tcop/postgres.c:3105 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "リカバリで競合が発生したため、接続を終了しています" + +#: tcop/postgres.c:3078 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "管理者コマンドにより接続を終了しています" + +#: tcop/postgres.c:3088 +#, c-format +msgid "connection to client lost" +msgstr "クライアントへの接続が切れました。" + +#: tcop/postgres.c:3154 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "ロックのタイムアウトのためステートメントをキャンセルしています" + +#: tcop/postgres.c:3161 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "ステートメントのタイムアウトのためステートメントをキャンセルしています" + +#: tcop/postgres.c:3168 +#, c-format +msgid "canceling autovacuum task" +msgstr "自動VACUUM処理をキャンセルしています" + +#: tcop/postgres.c:3191 +#, c-format +msgid "canceling statement due to user request" +msgstr "ユーザからの要求により文をキャンセルしています" + +#: tcop/postgres.c:3201 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "トランザクション中アイドルタイムアウトのため接続を終了します" + +#: tcop/postgres.c:3318 +#, c-format +msgid "stack depth limit exceeded" +msgstr "スタック長制限を越えました" + +#: tcop/postgres.c:3319 +#, c-format +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "お使いのプラットフォームにおけるスタック長の制限に適合することを確認後、設定パラメータ \"max_stack_depth\"(現在 %dkB)を増やしてください。" + +#: tcop/postgres.c:3382 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "\"max_stack_depth\"は%ldkBを越えてはなりません。" + +#: tcop/postgres.c:3384 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "プラットフォームのスタック長制限を\"ulimit -s\"または同等の機能を使用して増加してください" + +#: tcop/postgres.c:3744 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "サーバプロセスに対する不正なコマンドライン引数: %s" + +#: tcop/postgres.c:3745 tcop/postgres.c:3751 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "詳細は\"%s --help\"を実行してください。" + +#: tcop/postgres.c:3749 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: 不正なコマンドライン引数: %s" + +#: tcop/postgres.c:3811 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: データベース名もユーザ名も指定されていません" + +#: tcop/postgres.c:4447 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "不正なCLOSEメッセージのサブタイプ%d" + +#: tcop/postgres.c:4482 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "不正なDESCRIBEメッセージのサブタイプ%d" + +#: tcop/postgres.c:4560 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "レプリケーション接続では高速関数呼び出しはサポートされていません" + +#: tcop/postgres.c:4564 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "レプリケーション接続では拡張問い合わせプロトコルはサポートされていません" + +#: tcop/postgres.c:4741 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "接続を切断: セッション時間: %d:%02d:%02d.%03d ユーザ=%s データベース=%s ホスト=%s%s%s" + +#: tcop/pquery.c:629 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "バインドメッセージは%dの結果書式がありましたが、問い合わせは%d列でした" + +#: tcop/pquery.c:932 +#, c-format +msgid "cursor can only scan forward" +msgstr "カーゾルは前方へのスキャンしかできません" + +#: tcop/pquery.c:933 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "後方スキャンを有効にするためにはSCROLLオプションを付けて宣言してください。" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:413 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "リードオンリーのトランザクションでは %s を実行できません" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:431 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "並列処理中は%sを実行できません" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:450 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "リカバリ中は %s を実行できません" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:468 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "セキュリティー制限操作の中では %s を実行できません" + +#: tcop/utility.c:912 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "CHECKPOINTを実行するにはスーパユーザである必要があります" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:620 +#, c-format +msgid "multiple DictFile parameters" +msgstr "重複するDictFileパラメータ" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "重複するAffFileパラメータ" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "認識不可のIspellパラメータ: \"%s\"" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "AffFileパラメータがありません" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:644 +#, c-format +msgid "missing DictFile parameter" +msgstr "DictFileパラメータがありません" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "重複するAcceptパラメータ" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "認識できない単純辞書パラメータ: \"%s\"" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "認識できない類義語パラメータ: \"%s\"" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "類義語パラメータがありません" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "類義語ファイル\"%s\"をオープンできませんでした: %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "シソーラスファイル\"%s\"をオープンできませんでした: %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "想定外のデリミタです" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "想定外の行末もしくは単語の終端です" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "想定外の行末です" + +#: tsearch/dict_thesaurus.c:297 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "シソーラス要素中の語彙素が多すぎます" + +#: tsearch/dict_thesaurus.c:421 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "シソーラスサンプル単語\"%s\"は副辞書で認識されません(規則%d)" + +#: tsearch/dict_thesaurus.c:427 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "シソーラスサンプル単語\"%s\"はストップワードです(規則%d)" + +#: tsearch/dict_thesaurus.c:430 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "サンプルフレーズ内のストップワードを表すには\"?\"を使用してください" + +#: tsearch/dict_thesaurus.c:572 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "シソーラス置換単語\"%s\"はストップワードです(規則%d)" + +#: tsearch/dict_thesaurus.c:579 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "シソーラス置換単語\"%s\"は副辞書で認識されません(規則%d)" + +#: tsearch/dict_thesaurus.c:591 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "シソーラス置換フレーズは空です(規則%d)" + +#: tsearch/dict_thesaurus.c:629 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "重複する辞書パラメータ" + +#: tsearch/dict_thesaurus.c:636 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "認識できないシソーラスパラメータ \"%s\"" + +#: tsearch/dict_thesaurus.c:648 +#, c-format +msgid "missing Dictionary parameter" +msgstr "Dictionaryパラメータがありません" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 tsearch/spell.c:1036 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "不正な接辞フラグ\"%s\"" + +#: tsearch/spell.c:384 tsearch/spell.c:1040 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "接辞フラグ\"%s\"は範囲外です" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "接辞フラグ中の不正な文字\"%s\"" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "\"long\"フラグ値を伴った不正な接辞フラグ\"%s\"" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "辞書ファイル\"%s\"をオープンできませんでした: %m" + +#: tsearch/spell.c:742 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "正規表現が不正です: %s" + +#: tsearch/spell.c:1163 tsearch/spell.c:1175 tsearch/spell.c:1734 tsearch/spell.c:1739 tsearch/spell.c:1744 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "不正な接辞の別名 \"%s\"" + +#: tsearch/spell.c:1216 tsearch/spell.c:1287 tsearch/spell.c:1436 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "affixファイル\"%s\"をオープンできませんでした: %m" + +#: tsearch/spell.c:1270 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Ispell辞書はフラグ値\"default\"、\"long\"および\"num\"のみをサポートします" + +#: tsearch/spell.c:1314 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "不正な数のフラグベクタの別名" + +#: tsearch/spell.c:1337 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "別名の数が指定された数 %d を超えています" + +#: tsearch/spell.c:1552 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "接辞ファイルが新旧両方の形式のコマンドを含んでいます" + +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "TSベクターのための文字列が長すぎます(%dバイト、最大は%dバイト)" + +#: tsearch/ts_locale.c:185 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "設定ファイル\"%2$s\"の%1$d行目: \"%3$s\"" + +#: tsearch/ts_locale.c:302 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "wchar_tからサーバ符号化方式への変換が失敗しました: %m" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "インデックス付けするには単語が長すぎます" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "%dより長い単語は無視されます。" + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "テキスト検索設定ファイル名は%sは不正です" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "ストップワードファイル\"%s\"をオープンできませんでした: %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "テキスト検索パーサは見出し作成をサポートしません" + +#: tsearch/wparser_def.c:2578 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "認識できない見出しパラメータ: \"%s\"" + +#: tsearch/wparser_def.c:2597 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "MinWordsはMaxWordsより小さくなければなりません" + +#: tsearch/wparser_def.c:2601 +#, c-format +msgid "MinWords should be positive" +msgstr "MinWordsは正でなければなりません" + +#: tsearch/wparser_def.c:2605 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "ShortWordは>= 0でなければなりません" + +#: tsearch/wparser_def.c:2609 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "MaxFragments は 0 以上でなければなりません" + +#: utils/adt/acl.c:172 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "識別子が長すぎます" + +#: utils/adt/acl.c:173 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "識別子は%d文字より短くなければなりません。" + +#: utils/adt/acl.c:256 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "キーワードが不明です: \"%s\"" + +#: utils/adt/acl.c:257 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "ACLキーワードは\"group\"または\"user\"でなければなりません。" + +#: utils/adt/acl.c:262 +#, c-format +msgid "missing name" +msgstr "名前がありません" + +#: utils/adt/acl.c:263 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "\"group\"または\"user\"キーワードの後には名前が必要です。" + +#: utils/adt/acl.c:269 +#, c-format +msgid "missing \"=\" sign" +msgstr "\"=\"記号がありません" + +#: utils/adt/acl.c:322 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "不正なモード文字: \"%s\"の一つでなければなりません" + +#: utils/adt/acl.c:344 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "\"/\"記号の後には名前が必要です" + +#: utils/adt/acl.c:352 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "権限付与者をデフォルトのユーザID %uにしています" + +#: utils/adt/acl.c:538 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "ACL配列に不正なデータ型があります。" + +#: utils/adt/acl.c:542 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "ACL配列は1次元の配列でなければなりません" + +#: utils/adt/acl.c:546 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "ACL配列にはNULL値を含めてはいけません" + +#: utils/adt/acl.c:570 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "ACL指定の後に余計なごみがあります" + +#: utils/adt/acl.c:1205 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "グラントオプションでその権限付与者に権限を戻すことはできません" + +#: utils/adt/acl.c:1266 +#, c-format +msgid "dependent privileges exist" +msgstr "依存する権限が存在します" + +#: utils/adt/acl.c:1267 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "これらも取り上げるにはCASCADEを使用してください" + +#: utils/adt/acl.c:1521 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsertはもうサポートされていません" + +#: utils/adt/acl.c:1531 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremoveはもうサポートされていません" + +#: utils/adt/acl.c:1617 utils/adt/acl.c:1671 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "権限タイプが不明です: \"%s\"" + +#: utils/adt/acl.c:3471 utils/adt/regproc.c:101 utils/adt/regproc.c:276 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "関数\"%s\"は存在しません" + +#: utils/adt/acl.c:4943 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "ロール\"%s\"のメンバでなければなりません" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:933 utils/adt/arrayfuncs.c:1554 utils/adt/arrayfuncs.c:3257 utils/adt/arrayfuncs.c:3397 utils/adt/arrayfuncs.c:5932 utils/adt/arrayfuncs.c:6273 utils/adt/arrayutils.c:93 utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "配列の次数が上限(%d)を超えています" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 utils/adt/array_userfuncs.c:546 utils/adt/json.c:645 utils/adt/json.c:740 utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "入力データ型を特定できませんでした" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "入力データ型は配列ではありません" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 utils/adt/arrayfuncs.c:1357 utils/adt/float.c:1233 utils/adt/float.c:1307 utils/adt/float.c:4052 utils/adt/float.c:4066 utils/adt/int.c:757 utils/adt/int.c:779 utils/adt/int.c:793 utils/adt/int.c:807 utils/adt/int.c:838 utils/adt/int.c:859 utils/adt/int.c:976 utils/adt/int.c:990 utils/adt/int.c:1004 utils/adt/int.c:1037 utils/adt/int.c:1051 utils/adt/int.c:1065 utils/adt/int.c:1096 +#: utils/adt/int.c:1178 utils/adt/int.c:1242 utils/adt/int.c:1310 utils/adt/int.c:1316 utils/adt/int8.c:1299 utils/adt/numeric.c:1774 utils/adt/numeric.c:4138 utils/adt/varbit.c:1188 utils/adt/varbit.c:1576 utils/adt/varlena.c:1087 utils/adt/varlena.c:3377 +#, c-format +msgid "integer out of range" +msgstr "integerの範囲外です" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "引数は空か1次元の配列でなければなりません" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "互換性がない配列を連結できません" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "要素型%sと%sの配列の連結には互換性がありません" + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "要素数%dと%dの配列の連結には互換性がありません" + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "異なる要素次数の配列の連結には互換性がありません。" + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "異なる次数の配列の連結には互換性がありません。" + +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "多次元配列内の要素の検索はサポートされません" + +#: utils/adt/array_userfuncs.c:686 +#, c-format +msgid "initial position must not be null" +msgstr "初期位置nullであってはなりません" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:517 utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:553 utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:590 utils/adt/arrayfuncs.c:598 utils/adt/arrayfuncs.c:632 +#: utils/adt/arrayfuncs.c:655 utils/adt/arrayfuncs.c:675 utils/adt/arrayfuncs.c:787 utils/adt/arrayfuncs.c:796 utils/adt/arrayfuncs.c:826 utils/adt/arrayfuncs.c:841 utils/adt/arrayfuncs.c:894 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "配列リテラルの書式が誤っています: \"%s\"" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "\"[\"は配列次元の明示的な指定の先頭である必要があります。" + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "配列の次元数の値がありません。" + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "配列の次元の後に\"%s\"がありません。" + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2905 utils/adt/arrayfuncs.c:2937 utils/adt/arrayfuncs.c:2952 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "上限を下限より小さくすることはできません" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "配列値は\"{\"または次元情報から始まる必要があります。" + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "配列の内容は\"{\"で始まる必要があります。" + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "指定された配列の次元数が配列の内容と合致していません。" + +#: utils/adt/arrayfuncs.c:491 utils/adt/arrayfuncs.c:518 utils/adt/rangetypes.c:2181 utils/adt/rangetypes.c:2189 utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 +#, c-format +msgid "Unexpected end of input." +msgstr "想定外の入力の終端。" + +#: utils/adt/arrayfuncs.c:507 utils/adt/arrayfuncs.c:554 utils/adt/arrayfuncs.c:584 utils/adt/arrayfuncs.c:633 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "想定外の文字\"%c\"。" + +#: utils/adt/arrayfuncs.c:533 utils/adt/arrayfuncs.c:656 +#, c-format +msgid "Unexpected array element." +msgstr "想定外の配列要素。" + +#: utils/adt/arrayfuncs.c:591 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "対応しない\"%c\"文字。" + +#: utils/adt/arrayfuncs.c:599 utils/adt/jsonfuncs.c:2452 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "多次元配列は合致する次元の副配列を持たなければなりません。" + +#: utils/adt/arrayfuncs.c:676 +#, c-format +msgid "Junk after closing right brace." +msgstr "右括弧の後にごみがあります。" + +#: utils/adt/arrayfuncs.c:1298 utils/adt/arrayfuncs.c:3365 utils/adt/arrayfuncs.c:5838 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "不正な次元数: %d" + +#: utils/adt/arrayfuncs.c:1309 +#, c-format +msgid "invalid array flags" +msgstr "不正な配列フラグ" + +#: utils/adt/arrayfuncs.c:1331 +#, c-format +msgid "binary data has array element type %u (%s) instead of expected %u (%s)" +msgstr "バイナリデータ中に期待される型%3$u(%4$s)の代わりに%1$u(%2$s)がありました" + +#: utils/adt/arrayfuncs.c:1388 utils/adt/rangetypes.c:335 utils/cache/lsyscache.c:2835 +#, c-format +msgid "no binary input function available for type %s" +msgstr "型%sにはバイナリ入力関数がありません" + +#: utils/adt/arrayfuncs.c:1528 +#, c-format +msgid "improper binary format in array element %d" +msgstr "配列要素%dのバイナリ書式が不適切です" + +#: utils/adt/arrayfuncs.c:1609 utils/adt/rangetypes.c:340 utils/cache/lsyscache.c:2868 +#, c-format +msgid "no binary output function available for type %s" +msgstr "型%sにはバイナリ出力関数がありません" + +#: utils/adt/arrayfuncs.c:2087 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "固定長配列の部分配列は実装されていません" + +#: utils/adt/arrayfuncs.c:2265 utils/adt/arrayfuncs.c:2287 utils/adt/arrayfuncs.c:2336 utils/adt/arrayfuncs.c:2572 utils/adt/arrayfuncs.c:2883 utils/adt/arrayfuncs.c:5824 utils/adt/arrayfuncs.c:5850 utils/adt/arrayfuncs.c:5861 utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4340 utils/adt/jsonfuncs.c:4490 utils/adt/jsonfuncs.c:4602 utils/adt/jsonfuncs.c:4648 +#, c-format +msgid "wrong number of array subscripts" +msgstr "配列の添え字が不正な数値です" + +#: utils/adt/arrayfuncs.c:2270 utils/adt/arrayfuncs.c:2378 utils/adt/arrayfuncs.c:2636 utils/adt/arrayfuncs.c:2942 +#, c-format +msgid "array subscript out of range" +msgstr "配列の添え字が範囲外です" + +#: utils/adt/arrayfuncs.c:2275 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "固定長配列の要素にNULL値を代入できません" + +#: utils/adt/arrayfuncs.c:2830 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "固定長配列の部分配列の更新は実装されていません" + +#: utils/adt/arrayfuncs.c:2861 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "配列のスライスの添え字は両方の境界を示す必要があります" + +#: utils/adt/arrayfuncs.c:2862 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "空の配列値のスライスに代入するには、スライスの範囲は完全に指定する必要があります。" + +#: utils/adt/arrayfuncs.c:2873 utils/adt/arrayfuncs.c:2968 +#, c-format +msgid "source array too small" +msgstr "元の配列が小さすぎます" + +#: utils/adt/arrayfuncs.c:3521 +#, c-format +msgid "null array element not allowed in this context" +msgstr "この文脈ではNULLの配列要素は許可されません" + +#: utils/adt/arrayfuncs.c:3623 utils/adt/arrayfuncs.c:3794 utils/adt/arrayfuncs.c:4150 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "要素型の異なる配列を比較できません" + +#: utils/adt/arrayfuncs.c:3972 utils/adt/rangetypes.c:1254 utils/adt/rangetypes.c:1318 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "型 %s のハッシュ関数を識別できません" + +#: utils/adt/arrayfuncs.c:4065 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "型 %s の拡張ハッシュ関数を特定できませんでした" + +#: utils/adt/arrayfuncs.c:5242 +#, c-format +msgid "data type %s is not an array type" +msgstr "データ型%sは配列型ではありません" + +#: utils/adt/arrayfuncs.c:5297 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "null配列は連結できません" + +#: utils/adt/arrayfuncs.c:5325 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "空の配列は連結できません" + +#: utils/adt/arrayfuncs.c:5352 utils/adt/arrayfuncs.c:5358 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "次元の異なる配列は結合できません" + +#: utils/adt/arrayfuncs.c:5722 utils/adt/arrayfuncs.c:5762 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "次元配列もしくは下限値配列が NULL であってはなりません" + +#: utils/adt/arrayfuncs.c:5825 utils/adt/arrayfuncs.c:5851 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "次元配列は1次元でなければなりません" + +#: utils/adt/arrayfuncs.c:5830 utils/adt/arrayfuncs.c:5856 +#, c-format +msgid "dimension values cannot be null" +msgstr "次元値にnullにはできません" + +#: utils/adt/arrayfuncs.c:5862 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "下限配列が次元配列のサイズと異なっています" + +#: utils/adt/arrayfuncs.c:6138 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "多次元配列からの要素削除はサポートされません" + +#: utils/adt/arrayfuncs.c:6415 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "閾値は1次元の配列でなければなりません" + +#: utils/adt/arrayfuncs.c:6420 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "閾値配列にはNULL値を含めてはいけません" + +#: utils/adt/arrayutils.c:209 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "typmod配列はcstring[]型でなければなりません" + +#: utils/adt/arrayutils.c:214 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "typmod配列は1次元の配列でなければなりません" + +#: utils/adt/arrayutils.c:219 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "typmod配列にはNULL値を含めてはいけません" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "%s符号化方式からASCIIへの変換はサポートされていません" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3757 utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:283 utils/adt/float.c:400 utils/adt/float.c:485 utils/adt/float.c:501 utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 utils/adt/geo_ops.c:1421 +#: utils/adt/geo_ops.c:3476 utils/adt/geo_ops.c:4645 utils/adt/geo_ops.c:4660 utils/adt/geo_ops.c:4667 utils/adt/int8.c:126 utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:701 utils/adt/numeric.c:720 utils/adt/numeric.c:6856 utils/adt/numeric.c:6880 utils/adt/numeric.c:6904 utils/adt/numeric.c:7873 +#: utils/adt/numutils.c:116 utils/adt/numutils.c:126 utils/adt/numutils.c:170 utils/adt/numutils.c:246 utils/adt/numutils.c:322 utils/adt/oid.c:44 utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 utils/adt/pg_lsn.c:74 utils/adt/tid.c:74 utils/adt/tid.c:82 utils/adt/tid.c:90 utils/adt/timestamp.c:494 utils/adt/uuid.c:136 utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "\"%s\"型の入力構文が不正です: \"%s\"" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "値\"%s\"は型%sの範囲外です" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 utils/adt/float.c:104 utils/adt/int.c:822 utils/adt/int.c:938 utils/adt/int.c:1018 utils/adt/int.c:1080 utils/adt/int.c:1118 utils/adt/int.c:1146 utils/adt/int8.c:600 utils/adt/int8.c:658 utils/adt/int8.c:985 utils/adt/int8.c:1065 utils/adt/int8.c:1127 utils/adt/int8.c:1207 utils/adt/numeric.c:3030 utils/adt/numeric.c:3053 +#: utils/adt/numeric.c:3138 utils/adt/numeric.c:3156 utils/adt/numeric.c:3252 utils/adt/numeric.c:8411 utils/adt/numeric.c:8701 utils/adt/numeric.c:10283 utils/adt/timestamp.c:3264 +#, c-format +msgid "division by zero" +msgstr "0 による除算が行われました" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "\"char\"の範囲外です" + +#: utils/adt/date.c:61 utils/adt/timestamp.c:95 utils/adt/varbit.c:104 utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "不正な型修飾子です。" + +#: utils/adt/date.c:73 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "(%d)%sの精度は負ではいけません" + +#: utils/adt/date.c:79 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%sの位取りを許容最大値%dまで減らしました" + +#: utils/adt/date.c:158 utils/adt/date.c:166 utils/adt/formatting.c:4196 utils/adt/formatting.c:4205 utils/adt/formatting.c:4311 utils/adt/formatting.c:4321 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "日付が範囲外です: \"%s\"" + +#: utils/adt/date.c:213 utils/adt/date.c:525 utils/adt/date.c:549 utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "日付が範囲外です" + +#: utils/adt/date.c:259 utils/adt/timestamp.c:574 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "日付フィールドの値が範囲外です: %d-%02d-%02d" + +#: utils/adt/date.c:266 utils/adt/date.c:275 utils/adt/timestamp.c:580 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "日付が範囲外です: %d-%02d-%02d" + +#: utils/adt/date.c:313 utils/adt/date.c:336 utils/adt/date.c:362 utils/adt/date.c:1170 utils/adt/date.c:1216 utils/adt/date.c:1772 utils/adt/date.c:1803 utils/adt/date.c:1832 utils/adt/date.c:2664 utils/adt/datetime.c:1655 utils/adt/formatting.c:4053 utils/adt/formatting.c:4085 utils/adt/formatting.c:4165 utils/adt/formatting.c:4287 utils/adt/json.c:418 utils/adt/json.c:457 utils/adt/timestamp.c:222 utils/adt/timestamp.c:254 utils/adt/timestamp.c:692 +#: utils/adt/timestamp.c:701 utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 utils/adt/timestamp.c:2843 utils/adt/timestamp.c:2864 utils/adt/timestamp.c:2877 utils/adt/timestamp.c:2886 utils/adt/timestamp.c:2894 utils/adt/timestamp.c:2949 utils/adt/timestamp.c:2972 utils/adt/timestamp.c:2985 utils/adt/timestamp.c:2996 utils/adt/timestamp.c:3004 utils/adt/timestamp.c:3664 utils/adt/timestamp.c:3789 utils/adt/timestamp.c:3830 utils/adt/timestamp.c:3920 +#: utils/adt/timestamp.c:3964 utils/adt/timestamp.c:4067 utils/adt/timestamp.c:4552 utils/adt/timestamp.c:4748 utils/adt/timestamp.c:5075 utils/adt/timestamp.c:5089 utils/adt/timestamp.c:5094 utils/adt/timestamp.c:5108 utils/adt/timestamp.c:5141 utils/adt/timestamp.c:5218 utils/adt/timestamp.c:5259 utils/adt/timestamp.c:5263 utils/adt/timestamp.c:5332 utils/adt/timestamp.c:5336 utils/adt/timestamp.c:5350 utils/adt/timestamp.c:5384 utils/adt/xml.c:2232 +#: utils/adt/xml.c:2239 utils/adt/xml.c:2259 utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "timestampの範囲外です" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "無限大の日付は減算できません" + +#: utils/adt/date.c:589 utils/adt/date.c:646 utils/adt/date.c:680 utils/adt/date.c:2701 utils/adt/date.c:2711 +#, c-format +msgid "date out of range for timestamp" +msgstr "タイムスタンプで日付が範囲外です" + +#: utils/adt/date.c:1389 utils/adt/date.c:2159 utils/adt/formatting.c:4373 +#, c-format +msgid "time out of range" +msgstr "時刻が範囲外です" + +#: utils/adt/date.c:1441 utils/adt/timestamp.c:589 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "時刻フィールドの値が範囲外です: %d:%02d:%02g" + +#: utils/adt/date.c:1961 utils/adt/date.c:2463 utils/adt/float.c:1047 utils/adt/float.c:1123 utils/adt/int.c:614 utils/adt/int.c:661 utils/adt/int.c:696 utils/adt/int8.c:499 utils/adt/numeric.c:2441 utils/adt/timestamp.c:3313 utils/adt/timestamp.c:3344 utils/adt/timestamp.c:3375 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "ウィンドウ関数での不正なサイズの PRECEDING または FOLLOWING 指定" + +#: utils/adt/date.c:2046 utils/adt/date.c:2059 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "\"time\"の単位\"%s\"が不明です" + +#: utils/adt/date.c:2167 +#, c-format +msgid "time zone displacement out of range" +msgstr "タイムゾーンの置換が範囲外です" + +#: utils/adt/date.c:2796 utils/adt/date.c:2809 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "\"time with time zone\"の単位\"%s\"が不明です" + +#: utils/adt/date.c:2882 utils/adt/datetime.c:906 utils/adt/datetime.c:1813 utils/adt/datetime.c:4602 utils/adt/timestamp.c:513 utils/adt/timestamp.c:540 utils/adt/timestamp.c:4150 utils/adt/timestamp.c:5100 utils/adt/timestamp.c:5342 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "タイムゾーン\"%s\"は不明です" + +#: utils/adt/date.c:2914 utils/adt/timestamp.c:5130 utils/adt/timestamp.c:5373 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "intervalによるタイムゾーン\"%s\"には月または日を含めてはいけません" + +#: utils/adt/datetime.c:3730 utils/adt/datetime.c:3737 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "日付時刻のフィールドが範囲外です: \"%s\"" + +#: utils/adt/datetime.c:3739 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "他の\"datestyle\"設定が必要かもしれません。" + +#: utils/adt/datetime.c:3744 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "intervalフィールドの値が範囲外です: \"%s\"" + +#: utils/adt/datetime.c:3750 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "タイムゾーンの置換が範囲外です: \"%s\"" + +#: utils/adt/datetime.c:4604 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "このタイムゾーンはタイムゾーン省略名\"%s\"の構成ファイルにあるようです。" + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "不正なDatumポインタ" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "不正なサイズ: \"%s\"" + +#: utils/adt/dbsize.c:828 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "不正なサイズの単位: \"%s\"" + +#: utils/adt/dbsize.c:829 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "有効な単位は \"bytes\"、\"kB\"、\"MB\"、\"GB\"そして\"TB\"。" + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "型%sはドメインではありません" + +#: utils/adt/encode.c:65 utils/adt/encode.c:113 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "符号化方式が不明です: \"%s\"" + +#: utils/adt/encode.c:79 +#, c-format +msgid "result of encoding conversion is too large" +msgstr "エンコーディング変換の結果が大きすぎです" + +#: utils/adt/encode.c:127 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "デコード変換の結果が大きすぎます" + +#: utils/adt/encode.c:186 +#, c-format +msgid "invalid hexadecimal digit: \"%.*s\"" +msgstr "不正な16進数表現: \"%.*s\"" + +#: utils/adt/encode.c:216 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "不正な16進数データ: 桁数が奇数です" + +#: utils/adt/encode.c:334 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "base64シーケンスのデコード中に想定外の\"=\"" + +#: utils/adt/encode.c:346 +#, c-format +msgid "invalid symbol \"%.*s\" found while decoding base64 sequence" +msgstr "base64シーケンスのデコード中に検出された不正なシンボル\"%.*s\"" + +#: utils/adt/encode.c:367 +#, c-format +msgid "invalid base64 end sequence" +msgstr "不正なbase64終了シーケンス" + +#: utils/adt/encode.c:368 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "入力データにパディングがありません、切り詰められたかさもなければ壊れています。" + +#: utils/adt/enum.c:100 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "列挙型%2$sの新しい値\"%1$s\"の安全ではない使用" + +#: utils/adt/enum.c:103 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "新しい列挙値はコミットするまで使用できません。" + +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 utils/adt/enum.c:199 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "列挙型%sの不正な入力構文: \"%s\"" + +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "列挙型用の不正な内部値: %u" + +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 utils/adt/enum.c:535 +#, c-format +msgid "could not determine actual enum type" +msgstr "実際の列挙型を特定できませんでした" + +#: utils/adt/enum.c:454 utils/adt/enum.c:483 +#, c-format +msgid "enum %s contains no values" +msgstr "列挙型 %s に値がありません" + +#: utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 utils/cache/typcache.c:1632 utils/cache/typcache.c:1788 utils/cache/typcache.c:1918 utils/fmgr/funcapi.c:456 +#, c-format +msgid "type %s is not composite" +msgstr "型%sは複合型ではありません" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "範囲外の値です: オーバーフロー" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "範囲外の値です: アンダーフロー" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "型realでは\"%s\"は範囲外です" + +#: utils/adt/float.c:477 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "型double precisionでは\"%s\"は範囲外です" + +#: utils/adt/float.c:1258 utils/adt/float.c:1332 utils/adt/int.c:334 utils/adt/int.c:872 utils/adt/int.c:894 utils/adt/int.c:908 utils/adt/int.c:922 utils/adt/int.c:954 utils/adt/int.c:1192 utils/adt/int8.c:1320 utils/adt/numeric.c:4268 utils/adt/numeric.c:4277 +#, c-format +msgid "smallint out of range" +msgstr "smallintの範囲外です" + +#: utils/adt/float.c:1458 utils/adt/numeric.c:3548 utils/adt/numeric.c:9294 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "負の値の平方根を取ることができません" + +#: utils/adt/float.c:1526 utils/adt/numeric.c:3823 utils/adt/numeric.c:3933 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "0 の負数乗は定義されていません" + +#: utils/adt/float.c:1530 utils/adt/numeric.c:3827 utils/adt/numeric.c:3938 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "負数を整数でない数でべき乗すると、結果が複雑になります" + +#: utils/adt/float.c:1706 utils/adt/float.c:1739 utils/adt/numeric.c:3735 utils/adt/numeric.c:9958 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "ゼロの対数を取ることができません" + +#: utils/adt/float.c:1710 utils/adt/float.c:1743 utils/adt/numeric.c:3673 utils/adt/numeric.c:3730 utils/adt/numeric.c:9962 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "負の値の対数を取ることができません" + +#: utils/adt/float.c:1776 utils/adt/float.c:1807 utils/adt/float.c:1902 utils/adt/float.c:1929 utils/adt/float.c:1957 utils/adt/float.c:1984 utils/adt/float.c:2131 utils/adt/float.c:2168 utils/adt/float.c:2338 utils/adt/float.c:2394 utils/adt/float.c:2459 utils/adt/float.c:2516 utils/adt/float.c:2707 utils/adt/float.c:2731 +#, c-format +msgid "input is out of range" +msgstr "入力が範囲外です" + +#: utils/adt/float.c:2798 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "setseed のパラメータ %g は設定可能な範囲 [-1, 1] にありません" + +#: utils/adt/float.c:4030 utils/adt/numeric.c:1715 +#, c-format +msgid "count must be greater than zero" +msgstr "カウントは0より大きくなければなりません" + +#: utils/adt/float.c:4035 utils/adt/numeric.c:1726 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "オペランド、下限、上限をNaNにすることはできません" + +#: utils/adt/float.c:4041 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "下限および上限は有限でなければなりません" + +#: utils/adt/float.c:4075 utils/adt/numeric.c:1744 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "下限を上限と同じにできません" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "\"tinterval\"値に対する不正な書式指定" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "時間間隔が特定の暦日付に結びついていません" + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "\"EEEE\"は最終パターンでなければなりません。" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "\"9\"は\"PR\"の前になければなりません" + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "\"0\"は\"PR\"の前になければなりません" + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "複数の小数点があります" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "\"V\"と小数点を混在できません" + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "\"S\"は1回しか使用できません" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "\"S\"と\"PL\"/\"MI\"/\"SG\"/\"PR\"を混在できません" + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "\"S\"と\"MI\"を混在できません" + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "\"S\"と\"PL\"を混在できません" + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "\"S\"と\"SG\"を混在できません" + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "\"PR\"と\"S\"/\"PL\"/\"MI\"/\"SG\"を混在できません" + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "\"EEEE\"は1回しか使用できません" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "\"EEEE\"が他のフォーマットと互換性がありません。" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "\"EEEE\"は数値または小数点パターンと共に指定してください。" + +#: utils/adt/formatting.c:1392 +#, c-format +msgid "invalid datetime format separator: \"%s\"" +msgstr "不正なdatetime書式のセパレータ: \"%s\"" + +#: utils/adt/formatting.c:1520 +#, c-format +msgid "\"%s\" is not a number" +msgstr "\"%s\"は数値ではありません" + +#: utils/adt/formatting.c:1598 +#, c-format +msgid "case conversion failed: %s" +msgstr "文字ケースの変換に失敗しました: %s" + +#: utils/adt/formatting.c:1663 utils/adt/formatting.c:1787 utils/adt/formatting.c:1912 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "%s 関数に対して使用する照合順序を特定できませんでした" + +#: utils/adt/formatting.c:2284 +#, c-format +msgid "invalid combination of date conventions" +msgstr "不正な暦法の組み合わせ" + +#: utils/adt/formatting.c:2285 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "単一の書式テンプレートの中では、グレゴリオ暦とISO歴週日付を混在させないでください。" + +#: utils/adt/formatting.c:2308 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "書式文字列中で\"%s\"フィールドの値が衝突しています" + +#: utils/adt/formatting.c:2311 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "この値は同じフィールド型に対する以前の設定と矛盾しています" + +#: utils/adt/formatting.c:2382 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "書式フィールド\"%s\"に対して元の文字列が短すぎます" + +#: utils/adt/formatting.c:2385 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "フィールドには%d文字必要ですが、%d文字しか残っていません。" + +#: utils/adt/formatting.c:2388 utils/adt/formatting.c:2403 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "元の文字列が固定長でない場合は、修飾子\"FM\"を試してみてください。" + +#: utils/adt/formatting.c:2398 utils/adt/formatting.c:2412 utils/adt/formatting.c:2635 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "\"%2$s\"に対する不正な値\"%1$s\"" + +#: utils/adt/formatting.c:2400 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "このフィールドには%d文字必要ですが、%d文字しかパースされませんでした。" + +#: utils/adt/formatting.c:2414 +#, c-format +msgid "Value must be an integer." +msgstr "値は整数でなければなりません。" + +#: utils/adt/formatting.c:2419 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "もとの文字列において\"%s\"に対応する値が範囲外です" + +#: utils/adt/formatting.c:2421 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "値は%dから%dまでの範囲でなければなりません。" + +#: utils/adt/formatting.c:2637 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "与えられた値がこの項目に対して許されるいずれの値ともマッチしません。" + +#: utils/adt/formatting.c:2854 utils/adt/formatting.c:2874 utils/adt/formatting.c:2894 utils/adt/formatting.c:2914 utils/adt/formatting.c:2933 utils/adt/formatting.c:2952 utils/adt/formatting.c:2976 utils/adt/formatting.c:2994 utils/adt/formatting.c:3012 utils/adt/formatting.c:3030 utils/adt/formatting.c:3047 utils/adt/formatting.c:3064 +#, c-format +msgid "localized string format value too long" +msgstr "地域化した文字列のフォーマットが長すぎます" + +#: utils/adt/formatting.c:3298 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "合致しないフォーマットセパレータ \"%c\"" + +#: utils/adt/formatting.c:3453 utils/adt/formatting.c:3797 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "形式指定フィールド\"%s\"はto_charの中でのみサポートされています" + +#: utils/adt/formatting.c:3628 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr " \"Y,YYY\"に対応する入力文字列が不正です" + +#: utils/adt/formatting.c:3714 +#, c-format +msgid "input string is too short for datetime format" +msgstr "datetime書式に対して入力文字列が短すぎます" + +#: utils/adt/formatting.c:3722 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "datetimeフォーマット後に文字が入力文字列中に残っています" + +#: utils/adt/formatting.c:4267 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "timestamptz型に対応する入力に時間帯がありません" + +#: utils/adt/formatting.c:4273 +#, c-format +msgid "timestamptz out of range" +msgstr "timestamptzの範囲外です" + +#: utils/adt/formatting.c:4301 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "datetimeフォーマットで時間帯は指定されていますが、時刻が指定されていません" + +#: utils/adt/formatting.c:4353 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "timetz型に対する入力文字列中に時間帯がありません" + +#: utils/adt/formatting.c:4359 +#, c-format +msgid "timetz out of range" +msgstr "timetzの範囲外です" + +#: utils/adt/formatting.c:4385 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "datetimeフォーマットで日付は指定されていますが、時間が指定されていません" + +#: utils/adt/formatting.c:4518 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "12時間形式では\"%d\"時は不正です" + +#: utils/adt/formatting.c:4520 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "24時間形式を使うか、もしくは 1 から 12 の間で指定してください。" + +#: utils/adt/formatting.c:4628 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "年の情報なしでは年内の日数は計算できません" + +#: utils/adt/formatting.c:5547 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "\"EEEE\"は入力としてサポートしていません" + +#: utils/adt/formatting.c:5559 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "\"RN\"は入力としてサポートしていません" + +#: utils/adt/genfile.c:75 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "親ディレクトリへの参照(\"..\")は許可されていません" + +#: utils/adt/genfile.c:86 +#, c-format +msgid "absolute path not allowed" +msgstr "絶対パスは許可されていません" + +#: utils/adt/genfile.c:91 +#, c-format +msgid "path must be in or below the current directory" +msgstr "パスはカレントディレクトリもしくはその下でなければなりません" + +#: utils/adt/genfile.c:116 utils/adt/oracle_compat.c:185 utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 utils/adt/oracle_compat.c:1054 +#, c-format +msgid "requested length too large" +msgstr "要求した長さが長すぎます" + +#: utils/adt/genfile.c:133 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "ファイル\"%s\"をシークできませんでした: %m" + +#: utils/adt/genfile.c:174 +#, c-format +msgid "file length too large" +msgstr "ファイルが大きすぎます" + +#: utils/adt/genfile.c:251 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "adminpack 1.0 でファイルを読み込むにはスーパユーザである必要があります" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "不正な直線の指定: AとBは同時に0にはできません" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "不正な直線の指定: 2つの点は異なっている必要があります" + +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3486 utils/adt/geo_ops.c:4354 utils/adt/geo_ops.c:5248 +#, c-format +msgid "too many points requested" +msgstr "要求された点が多すぎます" + +#: utils/adt/geo_ops.c:1461 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "\"path\"の外部値における点の数が不正です" + +#: utils/adt/geo_ops.c:2537 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "関数\"dist_lb\"は実装されていません" + +#: utils/adt/geo_ops.c:2556 +#, c-format +msgid "function \"dist_bl\" not implemented" +msgstr "関数\"dist_bl\"\"は実装されていません" + +#: utils/adt/geo_ops.c:2975 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "関数\"close_sl\"は実装されていません" + +#: utils/adt/geo_ops.c:3122 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "関数\"close_lb\"は実装されていません" + +#: utils/adt/geo_ops.c:3533 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "\"polygon\"の外部値の点の数が不正です" + +#: utils/adt/geo_ops.c:4069 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "関数\"poly_distance\"は実装されていません" + +#: utils/adt/geo_ops.c:4446 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "関数\"path_center\"は実装されていません" + +#: utils/adt/geo_ops.c:4463 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "開経路を多角形に変換できません" + +#: utils/adt/geo_ops.c:4713 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "\"circle\"の外部値の半径が不正です" + +#: utils/adt/geo_ops.c:5234 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "半径0の円を多角形に返還できません" + +#: utils/adt/geo_ops.c:5239 +#, c-format +msgid "must request at least 2 points" +msgstr "少なくとも2ポイントを要求しなければなりません" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vectorの要素数が多すぎます" + +#: utils/adt/int.c:237 +#, c-format +msgid "invalid int2vector data" +msgstr "不正なint2vectorデータ" + +#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvectorの要素が多すぎます" + +#: utils/adt/int.c:1508 utils/adt/int8.c:1446 utils/adt/numeric.c:1623 utils/adt/timestamp.c:5435 utils/adt/timestamp.c:5515 +#, c-format +msgid "step size cannot equal zero" +msgstr "ステップ数をゼロにすることはできません" + +#: utils/adt/int8.c:534 utils/adt/int8.c:557 utils/adt/int8.c:571 utils/adt/int8.c:585 utils/adt/int8.c:616 utils/adt/int8.c:640 utils/adt/int8.c:722 utils/adt/int8.c:790 utils/adt/int8.c:796 utils/adt/int8.c:822 utils/adt/int8.c:836 utils/adt/int8.c:860 utils/adt/int8.c:873 utils/adt/int8.c:942 utils/adt/int8.c:956 utils/adt/int8.c:970 utils/adt/int8.c:1001 utils/adt/int8.c:1023 utils/adt/int8.c:1037 utils/adt/int8.c:1051 utils/adt/int8.c:1084 +#: utils/adt/int8.c:1098 utils/adt/int8.c:1112 utils/adt/int8.c:1143 utils/adt/int8.c:1165 utils/adt/int8.c:1179 utils/adt/int8.c:1193 utils/adt/int8.c:1355 utils/adt/int8.c:1390 utils/adt/numeric.c:4217 utils/adt/varbit.c:1656 +#, c-format +msgid "bigint out of range" +msgstr "bigintの範囲外です" + +#: utils/adt/int8.c:1403 +#, c-format +msgid "OID out of range" +msgstr "OIDの範囲外です" + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "キー値は配列でも複合型でもJSONでもなく、スカラでなくてはなりません" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1812 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "引数%dのデータ型が特定できませんでした" + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "フィールド名はnullであってはなりません" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "引数リストの要素数は偶数でなければなりません" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "%s の引数ではキーと値が交互になっている必要があります。" + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "引数%dはnullであってはなりません" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "オブジェクトキーはテキストでなければなりません。" + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "配列は最低でも2つの列が必要です" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "オブジェクトキーにnullは使えません" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "配列の次元が合っていません" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "文字列はjsonb文字列として表現するには長すぎます" + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "実装上の制約のため、jsonb文字列は%dバイトまでである必要があります。" + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "引数%d: キーはnullであってはなりません" + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "オブエクとキーは文字列である必要があります" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "jsonb null は%s型にはキャストできません" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "jsonb文字列は%s型へはキャストできません" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "jsonb numericは%s型へはキャストできません" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "jsonbブール型は%s型へはキャストできません" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "jsonb配列は%s型へはキャストできません" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "jsonbオブジェクトは%s型へはキャストできません" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "jsonbの配列またはオブジェクトは%s型へはキャストできません" + +#: utils/adt/jsonb_util.c:699 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "jsonbオブジェクトペア数が許された最大の値(%zu)を上回っています" + +#: utils/adt/jsonb_util.c:740 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "jsonbの配列要素の数が許された最大の値(%zu)を上回っています" + +#: utils/adt/jsonb_util.c:1614 utils/adt/jsonb_util.c:1634 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "jsonbの配列要素の全体の大きさが許された最大値%uバイトを上回っています" + +#: utils/adt/jsonb_util.c:1695 utils/adt/jsonb_util.c:1730 utils/adt/jsonb_util.c:1750 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "jsonbのオブジェクト要素全体のサイズが最大値である%uを超えています" + +#: utils/adt/jsonfuncs.c:551 utils/adt/jsonfuncs.c:796 utils/adt/jsonfuncs.c:2330 utils/adt/jsonfuncs.c:2770 utils/adt/jsonfuncs.c:3560 utils/adt/jsonfuncs.c:3891 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "スカラに対して%sを呼び出すことはできません" + +#: utils/adt/jsonfuncs.c:556 utils/adt/jsonfuncs.c:783 utils/adt/jsonfuncs.c:2772 utils/adt/jsonfuncs.c:3549 +#, c-format +msgid "cannot call %s on an array" +msgstr "配列に対して%sを呼び出すことはできません" + +#: utils/adt/jsonfuncs.c:692 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "JSONデータ、%d行目: %s%s%s" + +#: utils/adt/jsonfuncs.c:1682 utils/adt/jsonfuncs.c:1717 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "スカラから配列長を得ることはできません" + +#: utils/adt/jsonfuncs.c:1686 utils/adt/jsonfuncs.c:1705 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "配列では無いものから配列長を得ることはできません" + +#: utils/adt/jsonfuncs.c:1782 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "非オブジェクトに対して%sは呼び出せません" + +#: utils/adt/jsonfuncs.c:2021 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "配列をオブジェクトとして再構築することはできません" + +#: utils/adt/jsonfuncs.c:2033 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "スカラを再構築することはできません" + +#: utils/adt/jsonfuncs.c:2079 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "スカラから要素を取り出すことはできません" + +#: utils/adt/jsonfuncs.c:2083 +#, c-format +msgid "cannot extract elements from an object" +msgstr "オブジェクトから要素を取り出すことはできません" + +#: utils/adt/jsonfuncs.c:2317 utils/adt/jsonfuncs.c:3775 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "非配列に対して%sを呼び出すことはできません" + +#: utils/adt/jsonfuncs.c:2387 utils/adt/jsonfuncs.c:2392 utils/adt/jsonfuncs.c:2409 utils/adt/jsonfuncs.c:2415 +#, c-format +msgid "expected JSON array" +msgstr "JSON配列を期待していました" + +#: utils/adt/jsonfuncs.c:2388 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "キー\"%s\"の値を見てください。" + +#: utils/adt/jsonfuncs.c:2410 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "キー\"%s\"の配列要素%sを見てください。" + +#: utils/adt/jsonfuncs.c:2416 +#, c-format +msgid "See the array element %s." +msgstr "配列要素%sを見てください。" + +#: utils/adt/jsonfuncs.c:2451 +#, c-format +msgid "malformed JSON array" +msgstr "不正な形式のJSON配列" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3278 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "%sの最初の引数は行型でなければなりません" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3302 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "%sの結果に対応する行の型を決定できませんでした" + +#: utils/adt/jsonfuncs.c:3304 +#, c-format +msgid "Provide a non-null record argument, or call the function in the FROM clause using a column definition list." +msgstr "非NULLのレコード引数を与えるか、列定義リストを用いてこの関数をFROM句中で呼び出してください。" + +#: utils/adt/jsonfuncs.c:3792 utils/adt/jsonfuncs.c:3873 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "%sの引数はオブジェクト配列でなければなりません" + +#: utils/adt/jsonfuncs.c:3825 +#, c-format +msgid "cannot call %s on an object" +msgstr "オブジェクトに対して%sを呼び出すことはできません" + +#: utils/adt/jsonfuncs.c:4286 utils/adt/jsonfuncs.c:4345 utils/adt/jsonfuncs.c:4425 +#, c-format +msgid "cannot delete from scalar" +msgstr "スカラから削除することはできません" + +#: utils/adt/jsonfuncs.c:4430 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "オブジェクトから整数添字を使って削除することはできません" + +#: utils/adt/jsonfuncs.c:4495 utils/adt/jsonfuncs.c:4653 +#, c-format +msgid "cannot set path in scalar" +msgstr "スカラにパスを設定することはできません" + +#: utils/adt/jsonfuncs.c:4537 utils/adt/jsonfuncs.c:4579 +#, c-format +msgid "null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"" +msgstr "null_value_treatment は \"delete_key\", \"return_target\", \"use_json_null\" または \"raise_exception\"である必要があります" + +#: utils/adt/jsonfuncs.c:4550 +#, c-format +msgid "JSON value must not be null" +msgstr "JSON値はnullではあってはなりません" + +#: utils/adt/jsonfuncs.c:4551 +#, c-format +msgid "Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "null_value_treatmentが\"raise_exception\"であるため、例外が出力されました" + +#: utils/adt/jsonfuncs.c:4552 +#, c-format +msgid "To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed." +msgstr "これを避けるには、 null_value_treatment引数を変更するか、SQLのNULLを渡さないようにしてください。" + +#: utils/adt/jsonfuncs.c:4607 +#, c-format +msgid "cannot delete path in scalar" +msgstr "スカラでパスを削除することはできません" + +#: utils/adt/jsonfuncs.c:4776 +#, c-format +msgid "invalid concatenation of jsonb objects" +msgstr "jsonbオブジェクト間の不正な結合" + +#: utils/adt/jsonfuncs.c:4810 +#, c-format +msgid "path element at position %d is null" +msgstr "位置%dのパス要素がnullです" + +#: utils/adt/jsonfuncs.c:4896 +#, c-format +msgid "cannot replace existing key" +msgstr "既存のキーを置き換えることはできません" + +#: utils/adt/jsonfuncs.c:4897 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "jsonb_set関数を使ってキー値を置き換えることを試してください。" + +#: utils/adt/jsonfuncs.c:4979 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "位置%dのパス要素が整数ではありません: \"%s\"" + +#: utils/adt/jsonfuncs.c:5098 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "間違ったフラグのタイプ; 配列およびスカラのみ使用可能です" + +#: utils/adt/jsonfuncs.c:5105 +#, c-format +msgid "flag array element is not a string" +msgstr "フラグ配列の要素が文字列ではありません" + +#: utils/adt/jsonfuncs.c:5106 utils/adt/jsonfuncs.c:5128 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "使用可能な値は: \"string\", \"numeric\", \"boolean\", \"key\"、および \"all\"。" + +#: utils/adt/jsonfuncs.c:5126 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "フラグ配列内の間違ったフラグ値: \"%s\"" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "ルート式では@を使用できません" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST は配列の添え字でのみ使用可能です" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "単一のブール値の結果が必要です" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "引数\"vars\"がオブジェクトではありません" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "Jsonpath パラメータは \"vars\"オブジェクトの key-value ペアの形にエンコードされていなければなりません。" + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "JSONオブジェクトはキー\"%s\"を含んでいません" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "jsonpathメンバアクセサはオブジェクトに対してのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "jsonpath ワイルドカード配列アクセサは配列にのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "jsonpath配列の添え字が範囲外です" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "jsonpath 配列アクセサは配列にのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:874 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "jsonpathワイルドカードメンバアクセサはオブジェクトに対してのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:1004 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "jsonpath 項目メソッド .%s() は配列にのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:1059 +#, c-format +msgid "numeric argument of jsonpath item method .%s() is out of range for type double precision" +msgstr "JSONパス項目メソッド .%s() のnumeric型の引数がdouble precisionの範囲外です" + +#: utils/adt/jsonpath_exec.c:1080 +#, c-format +msgid "string argument of jsonpath item method .%s() is not a valid representation of a double precision number" +msgstr "jsonpath項目メソッド .%s() の文字列引数はの有効な倍精度数表現ではありません" + +#: utils/adt/jsonpath_exec.c:1093 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "jsonpath 項目メソッド .%s() は文字列または数値にのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:1583 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "jsonpath演算子 %s の左辺値が単一の数値ではありません" + +#: utils/adt/jsonpath_exec.c:1590 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "jsonpath演算子 %s の右辺値が単一の数値ではありません" + +#: utils/adt/jsonpath_exec.c:1658 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "単項jsonpath演算子 %s のオペランドが数値ではありません" + +#: utils/adt/jsonpath_exec.c:1756 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "jsonpath 項目メソッド .%s() は数値にのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:1796 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "jsonpath 項目メソッド .%s() は文字列にのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:1884 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "datetime書式を認識できません: \"%s\"" + +#: utils/adt/jsonpath_exec.c:1886 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "datetimeテンプレート引数を使って入力データフォーマットを指定してください。" + +#: utils/adt/jsonpath_exec.c:1954 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "jsonpath項目メソッド .%s() はオブジェクトに対してのみ適用可能です" + +#: utils/adt/jsonpath_exec.c:2137 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "jsonpath変数\"%s\"が見つかりませんでした" + +#: utils/adt/jsonpath_exec.c:2401 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "jsonpath配列添え字が単一の数値ではありません" + +#: utils/adt/jsonpath_exec.c:2413 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "jsonpath配列の添え字が整数の範囲外です" + +#: utils/adt/jsonpath_exec.c:2590 +#, c-format +msgid "cannot convert value from %s to %s without timezone usage" +msgstr "時間帯を使用せずに %s から %s への値の変換はできません" + +#: utils/adt/jsonpath_exec.c:2592 +#, c-format +msgid "Use *_tz() function for timezone support." +msgstr "*_tz() 関数を使用することで時間帯がサポートされます" + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "レーベンシュタイン距離関数の引数の長さが上限の%d文字を超えています" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "非決定的照合順序はLIKEではサポートされません" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "ILIKE で使用する照合順序を特定できませんでした" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "非決定的照合順序はILIKEではサポートされません" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "LIKE パターンはエスケープ文字で終わってはなりません" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "不正なエスケープ文字列" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "エスケープ文字は空か1文字でなければなりません。" + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "型byteaでは大文字小文字の区別をしないマッチをサポートしません" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "型byteaでは正規表現のマッチをサポートしません" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "\"macaddr\"の値での不正なオクテット値: \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "macaddr8データがmacaddr型に変換するには範囲外です" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "左から4、5バイト目にFFとFEがあるアドレス、具体的には xx:xx:xx:ff:fe:xx:xx:xx のみがmacaddr8からmacaddrに変換できます。" + +#: utils/adt/misc.c:240 +#, c-format +msgid "global tablespace never has databases" +msgstr "グローバルテーブル空間にデータベースがありません" + +#: utils/adt/misc.c:262 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%uはテーブル空間のOIDではありません" + +#: utils/adt/misc.c:448 +msgid "unreserved" +msgstr "予約されていません" + +#: utils/adt/misc.c:452 +msgid "unreserved (cannot be function or type name)" +msgstr "予約されていません(関数または型名にはできません)" + +#: utils/adt/misc.c:456 +msgid "reserved (can be function or type name)" +msgstr "予約されています(関数または型名にできます)" + +#: utils/adt/misc.c:460 +msgid "reserved" +msgstr "予約されています" + +#: utils/adt/misc.c:634 utils/adt/misc.c:648 utils/adt/misc.c:687 utils/adt/misc.c:693 utils/adt/misc.c:699 utils/adt/misc.c:722 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "文字列は有効な識別子ではありません: \"%s\"" + +#: utils/adt/misc.c:636 +#, c-format +msgid "String has unclosed double quotes." +msgstr "文字列中に閉じられていない二重引用符があります。" + +#: utils/adt/misc.c:650 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "引用符で囲まれた識別子は空であってはなりません。" + +#: utils/adt/misc.c:689 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "\".\"の前に有効な識別子がありません。" + +#: utils/adt/misc.c:695 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "\".\"の後に有効な識別子がありません。" + +#: utils/adt/misc.c:753 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "ログ形式\"%s\"はサポートされていません" + +#: utils/adt/misc.c:754 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "サポートされているログ形式は\"stderr\"と\"csvlog\"です。" + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "不正なCIDR値: \"%s\"" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "値ではマスクの右側のビットがセットされています。" + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "inet値を整形できませんでした: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "外部の\"%s\"値内の不正なアドレスファミリ" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "外部の\"%s\"値内の不正なビット列" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "外部の\"%s\"値内の不正な長さ" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "\"cidr\"の外部値が不正です" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "不正なマスク長: %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "cidr値を整形できませんでした: %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "異なるファミリのアドレスは結合できません" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "サイズが異なるinet値のANDはできません" + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "サイズが異なるinet値のORはできません" + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "結果が範囲外です" + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "サイズが異なるinet値の引き算はできません" + +#: utils/adt/numeric.c:974 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "外部\"numeric\"の値の符号が不正です" + +#: utils/adt/numeric.c:980 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "外部\"numeric\"の値の位取りが不正です" + +#: utils/adt/numeric.c:989 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "外部\"numeric\"の値の桁が不正です" + +#: utils/adt/numeric.c:1202 utils/adt/numeric.c:1216 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "NUMERICの精度%dは1から%dまででなければなりません" + +#: utils/adt/numeric.c:1207 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "NUMERICの位取り%dは0から精度%dまででなければなりません" + +#: utils/adt/numeric.c:1225 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "不正なNUMERIC型の修正子" + +#: utils/adt/numeric.c:1583 +#, c-format +msgid "start value cannot be NaN" +msgstr "開始値はNaNにはできません" + +#: utils/adt/numeric.c:1587 +#, c-format +msgid "start value cannot be infinity" +msgstr "開始値は無限大にはできません" + +#: utils/adt/numeric.c:1594 +#, c-format +msgid "stop value cannot be NaN" +msgstr "終了値はNaNにはできません" + +#: utils/adt/numeric.c:1598 +#, c-format +msgid "stop value cannot be infinity" +msgstr "終了値は無限大にはできません" + +#: utils/adt/numeric.c:1611 +#, c-format +msgid "step size cannot be NaN" +msgstr "加算量はNaNにはできません" + +#: utils/adt/numeric.c:1615 +#, c-format +msgid "step size cannot be infinity" +msgstr "加算量は無限大にはできません" + +#: utils/adt/numeric.c:1730 +#, c-format +msgid "operand, lower bound, and upper bound cannot be infinity" +msgstr "オペランド、下限、上限を無限大にすることはできません" + +#: utils/adt/numeric.c:3488 +#, c-format +msgid "factorial of a negative number is undefined" +msgstr "負数の階乗は定義されていません" + +#: utils/adt/numeric.c:3498 utils/adt/numeric.c:6919 utils/adt/numeric.c:7403 utils/adt/numeric.c:9767 utils/adt/numeric.c:10205 utils/adt/numeric.c:10319 utils/adt/numeric.c:10392 +#, c-format +msgid "value overflows numeric format" +msgstr "値がnumericの形式でオーバフローします" + +#: utils/adt/numeric.c:4116 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "NaNをintegerに変換できません" + +#: utils/adt/numeric.c:4120 +#, c-format +msgid "cannot convert infinity to integer" +msgstr "無限大をintegerには変換できません" + +#: utils/adt/numeric.c:4204 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "NaNをbigintに変換できません" + +#: utils/adt/numeric.c:4208 +#, c-format +msgid "cannot convert infinity to bigint" +msgstr "無限大をbigintには変換できません" + +#: utils/adt/numeric.c:4255 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "NaNをsmallintに変換できません" + +#: utils/adt/numeric.c:4259 +#, c-format +msgid "cannot convert infinity to smallint" +msgstr "無限大をsmallintに変換できません" + +#: utils/adt/numeric.c:4450 +#, c-format +msgid "cannot convert NaN to pg_lsn" +msgstr "NaNをpg_lsnには変換できません" + +#: utils/adt/numeric.c:4454 +#, c-format +msgid "cannot convert infinity to pg_lsn" +msgstr "無限大をpg_lsnに変換できません" + +#: utils/adt/numeric.c:4463 +#, c-format +msgid "pg_lsn out of range" +msgstr "pg_lsnの範囲外です" + +#: utils/adt/numeric.c:7487 utils/adt/numeric.c:7534 +#, c-format +msgid "numeric field overflow" +msgstr "numericフィールドのオーバーフロー" + +#: utils/adt/numeric.c:7488 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "精度%d、位取り%dを持つフィールドは、%s%dより小さな絶対値に丸められます。" + +#: utils/adt/numeric.c:7535 +#, c-format +msgid "A field with precision %d, scale %d cannot hold an infinite value." +msgstr "精度%d、位取り%dを持つフィールドは、無限大値を格納できません。" + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "値\"%s\"は8ビット整数の範囲外です" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "不正なoidvectorデータ" + +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "要求された文字が大きすぎます" + +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "要求された文字は符号化するには大きすぎます: %d" + +#: utils/adt/oracle_compat.c:987 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "要求された文字は不正なため符号化することができません: %d" + +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "NULL文字は許可されません" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "百分位数の値%gが0と1の間ではありません" + +#: utils/adt/pg_locale.c:1253 +#, c-format +msgid "Apply system library package updates." +msgstr "システムライブラリの更新を適用してください。" + +#: utils/adt/pg_locale.c:1468 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "ロケール\"%s\"を作成できませんでした: %m" + +#: utils/adt/pg_locale.c:1471 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "オペレーティングシステムはロケール名\"%s\"のロケールデータを見つけられませんでした。" + +#: utils/adt/pg_locale.c:1573 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "このプラットフォームでは値が異なるcollateとctypeによる照合順序をサポートしていません" + +#: utils/adt/pg_locale.c:1582 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "照合順序プロバイダLIBCはこのプラットフォームではサポートされていません" + +#: utils/adt/pg_locale.c:1594 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "ICUは値が異なるcollateとctypeによる照合順序をサポートしていません" + +#: utils/adt/pg_locale.c:1600 utils/adt/pg_locale.c:1687 utils/adt/pg_locale.c:1960 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "ロケール\"%s\"の照合器をオープンできませんでした: %s" + +#: utils/adt/pg_locale.c:1614 +#, c-format +msgid "ICU is not supported in this build" +msgstr "このビルドではICUはサポートされていません" + +#: utils/adt/pg_locale.c:1615 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "--with-icuを使用してPostgreSQLを再構築する必要があります。" + +#: utils/adt/pg_locale.c:1635 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "照合順序\"%s\"には実際のバージョンがありませんが、バージョンが指定されています" + +#: utils/adt/pg_locale.c:1642 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "照合順序\"%s\"でバージョンの不一致が起きています" + +#: utils/adt/pg_locale.c:1644 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "データベース中の照合順序はバージョン%sで作成されていますが、オペレーティングシステムはバージョン%sを提供しています。" + +#: utils/adt/pg_locale.c:1647 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "この照合順序の影響を受ける全てのオブジェクトを再構築して、ALTER COLLATION %s REFRESH VERSIONを実行するか、正しいバージョンのライブラリを用いてPostgreSQLをビルドしてください。" + +#: utils/adt/pg_locale.c:1738 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "ロケール\"%s\"に対応する照合順序バージョンを取得できませんでした: エラーコード %lu" + +#: utils/adt/pg_locale.c:1775 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "エンコーディング\"%s\"はICUではサポートされていません" + +#: utils/adt/pg_locale.c:1782 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "エンコーディング\"%s\"のICU変換器をオープンできませんでした: %s" + +#: utils/adt/pg_locale.c:1813 utils/adt/pg_locale.c:1822 utils/adt/pg_locale.c:1851 utils/adt/pg_locale.c:1861 +#, c-format +msgid "%s failed: %s" +msgstr "%s が失敗しました: %s" + +#: utils/adt/pg_locale.c:2133 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "ロケールに対する不正なマルチバイト文字" + +#: utils/adt/pg_locale.c:2134 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "おそらくサーバのLC_CTYPEロケールはデータベースの符号化方式と互換性がありません" + +#: utils/adt/pg_lsn.c:269 +#, c-format +msgid "cannot add NaN to pg_lsn" +msgstr "pg_lsnにNaNは加算できません" + +#: utils/adt/pg_lsn.c:303 +#, c-format +msgid "cannot subtract NaN from pg_lsn" +msgstr "pg_lsnからNaNは減算できません" + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "関数はサーバがバイナリアップグレードモードであるときのみ呼び出せます" + +#: utils/adt/pgstatfuncs.c:500 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "不正なコマンド名: \"%s\"" + +#: utils/adt/pseudotypes.c:57 utils/adt/pseudotypes.c:91 +#, c-format +msgid "cannot display a value of type %s" +msgstr "%s型の値は表示できません" + +#: utils/adt/pseudotypes.c:283 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "シェル型の値は受け付けられません" + +#: utils/adt/pseudotypes.c:293 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "シェル型の値は表示できません" + +#: utils/adt/rangetypes.c:406 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "範囲コンストラクタフラグ引数はNULLではいけません" + +#: utils/adt/rangetypes.c:993 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "範囲の差分が連続ではありません" + +#: utils/adt/rangetypes.c:1054 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "範囲の和が連続ではありません" + +#: utils/adt/rangetypes.c:1600 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "範囲の下限は範囲の上限以下でなければなりません" + +#: utils/adt/rangetypes.c:1983 utils/adt/rangetypes.c:1996 utils/adt/rangetypes.c:2010 +#, c-format +msgid "invalid range bound flags" +msgstr "不正な範囲境界フラグ" + +#: utils/adt/rangetypes.c:1984 utils/adt/rangetypes.c:1997 utils/adt/rangetypes.c:2011 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "有効な値は\"[]\"、\"[)\"、\"(]\"、\"()\"です" + +#: utils/adt/rangetypes.c:2076 utils/adt/rangetypes.c:2093 utils/adt/rangetypes.c:2106 utils/adt/rangetypes.c:2124 utils/adt/rangetypes.c:2135 utils/adt/rangetypes.c:2179 utils/adt/rangetypes.c:2187 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "不正な範囲リテラル: \"%s\"" + +#: utils/adt/rangetypes.c:2078 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "\"empty\"キーワードの後にゴミがあります。" + +#: utils/adt/rangetypes.c:2095 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "左括弧または左角括弧がありません" + +#: utils/adt/rangetypes.c:2108 +#, c-format +msgid "Missing comma after lower bound." +msgstr "下限値の後にカンマがありません" + +#: utils/adt/rangetypes.c:2126 +#, c-format +msgid "Too many commas." +msgstr "カンマが多すぎます" + +#: utils/adt/rangetypes.c:2137 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "右括弧または右角括弧の後にごみがあります" + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4493 +#, c-format +msgid "regular expression failed: %s" +msgstr "正規表現が失敗しました: %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%.*s\"" +msgstr "不正な正規表現オプション: \"%.*s\"" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "SQL正規表現はエスケープされたダブルクオートを2つより多く含むことはできません" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%sは\"global\"オプションをサポートしません" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "代わりにregexp_matchesを使ってください。" + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "正規表現のマッチが多過ぎます" + +#: utils/adt/regproc.c:105 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "\"%s\"という名前の関数が複数あります" + +#: utils/adt/regproc.c:542 +#, c-format +msgid "more than one operator named %s" +msgstr "%sという名前の演算子が複数あります" + +#: utils/adt/regproc.c:714 utils/adt/regproc.c:755 utils/adt/regproc.c:2054 utils/adt/ruleutils.c:9289 utils/adt/ruleutils.c:9458 +#, c-format +msgid "too many arguments" +msgstr "引数が多すぎます" + +#: utils/adt/regproc.c:715 utils/adt/regproc.c:756 +#, c-format +msgid "Provide two argument types for operator." +msgstr "演算子では2つの引数型を指定してください" + +#: utils/adt/regproc.c:1638 utils/adt/regproc.c:1662 utils/adt/regproc.c:1763 utils/adt/regproc.c:1787 utils/adt/regproc.c:1889 utils/adt/regproc.c:1894 utils/adt/varlena.c:3642 utils/adt/varlena.c:3647 +#, c-format +msgid "invalid name syntax" +msgstr "不正な名前の構文" + +#: utils/adt/regproc.c:1952 +#, c-format +msgid "expected a left parenthesis" +msgstr "左括弧を想定していました" + +#: utils/adt/regproc.c:1968 +#, c-format +msgid "expected a right parenthesis" +msgstr "右括弧を想定していました" + +#: utils/adt/regproc.c:1987 +#, c-format +msgid "expected a type name" +msgstr "型の名前を想定していました" + +#: utils/adt/regproc.c:2019 +#, c-format +msgid "improper type name" +msgstr "型の名前が不適切です" + +#: utils/adt/ri_triggers.c:296 utils/adt/ri_triggers.c:1537 utils/adt/ri_triggers.c:2470 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "テーブル\"%s\"への挿入、更新は外部キー制約\"%s\"に違反しています" + +#: utils/adt/ri_triggers.c:299 utils/adt/ri_triggers.c:1540 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MACTH FULLではNULLキー値と非NULLキー値を混在できません" + +#: utils/adt/ri_triggers.c:1940 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "関数\"%s\"をINSERTで発行しなければなりません" + +#: utils/adt/ri_triggers.c:1946 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "関数\"%s\"をUPDATEで発行しなければなりません" + +#: utils/adt/ri_triggers.c:1952 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "関数\"%s\"をDELETEで発行しなければなりません" + +#: utils/adt/ri_triggers.c:1975 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "テーブル\"%2$s\"のトリガ\"%1$s\"用のpg_constraint項目がありません" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "この参照整合性トリガとその対象を削除し、ALTER TABLE ADD CONSTRAINTを実行してください" + +#: utils/adt/ri_triggers.c:2295 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "\"%3$s\"の制約\"%2$s\"から\"%1$s\"に行われた参照整合性問い合わせが想定外の結果になりました" + +#: utils/adt/ri_triggers.c:2299 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "これは概ねこの問い合わせを書き換えるルールが原因です" + +#: utils/adt/ri_triggers.c:2460 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "子テーブル \"%s\"の削除は外部キー制約\"%s\"違反となります" + +#: utils/adt/ri_triggers.c:2463 utils/adt/ri_triggers.c:2488 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "キー(%s)=(%s)はまだテーブル\"%s\"から参照されています" + +#: utils/adt/ri_triggers.c:2474 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "テーブル\"%3$s\"にキー(%1$s)=(%2$s)がありません" + +#: utils/adt/ri_triggers.c:2477 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "テーブル\"%s\"にキーがありません。" + +#: utils/adt/ri_triggers.c:2483 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "テーブル\"%1$s\"の更新または削除は、テーブル\"%3$s\"の外部キー制約\"%2$s\"に違反します" + +#: utils/adt/ri_triggers.c:2491 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "テーブル\"%s\"からキーがまだ参照されています。" + +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "匿名複合型の入力は実装されていません" + +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "おかしなレコードリテラルです: \"%s\"" + +#: utils/adt/rowtypes.c:157 +#, c-format +msgid "Missing left parenthesis." +msgstr "左括弧がありません" + +#: utils/adt/rowtypes.c:186 +#, c-format +msgid "Too few columns." +msgstr "列が少なすぎます" + +#: utils/adt/rowtypes.c:269 +#, c-format +msgid "Too many columns." +msgstr "列が多すぎます" + +#: utils/adt/rowtypes.c:277 +#, c-format +msgid "Junk after right parenthesis." +msgstr "右括弧の後にごみがあります" + +#: utils/adt/rowtypes.c:531 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "列数が間違っています: %d。%dを想定していました" + +#: utils/adt/rowtypes.c:573 +#, c-format +msgid "binary data has type %u (%s) instead of expected %u (%s) in record column %d" +msgstr "バイナリデータのレコードカラム%5$dで予期していた%3$u(%4$s)の代わりに%1$u(%2$s)がありました" + +#: utils/adt/rowtypes.c:640 +#, c-format +msgid "improper binary format in record column %d" +msgstr "レコード列%dのバイナリ書式が不適切です" + +#: utils/adt/rowtypes.c:931 utils/adt/rowtypes.c:1177 utils/adt/rowtypes.c:1435 utils/adt/rowtypes.c:1681 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "レコードの列 %3$d において、全く異なる型 %1$s と %2$s では比較ができません" + +#: utils/adt/rowtypes.c:1022 utils/adt/rowtypes.c:1247 utils/adt/rowtypes.c:1532 utils/adt/rowtypes.c:1717 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "個数が異なる列同士ではレコード型の比較ができません" + +#: utils/adt/ruleutils.c:4811 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "ルール\"%s\"はサポートしていないイベントタイプ%dを持ちます" + +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "TIMESTAMP(%d)%s の精度は負であってはなりません" + +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIMESTAMP(%d)%sの位取りを許容最大値%dまで減らしました" + +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:434 utils/misc/guc.c:11933 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestampが範囲外です: \"%s\"" + +#: utils/adt/timestamp.c:372 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "timestamp(%d)の精度は%dから%dまででなければなりません" + +#: utils/adt/timestamp.c:496 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "数字タイムゾーンは先頭の文字が\"-\"または\"+\"でなければなりません。" + +#: utils/adt/timestamp.c:509 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "数値タイムゾーン\"%s\"が範囲外です" + +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 utils/adt/timestamp.c:619 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestampが範囲外です: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:720 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "タイムスタンプは NaN にはできません" + +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "timestampが範囲外です: \"%g\"" + +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1509 utils/adt/timestamp.c:1944 utils/adt/timestamp.c:3042 utils/adt/timestamp.c:3047 utils/adt/timestamp.c:3052 utils/adt/timestamp.c:3102 utils/adt/timestamp.c:3109 utils/adt/timestamp.c:3116 utils/adt/timestamp.c:3136 utils/adt/timestamp.c:3143 utils/adt/timestamp.c:3150 utils/adt/timestamp.c:3180 utils/adt/timestamp.c:3188 utils/adt/timestamp.c:3232 utils/adt/timestamp.c:3659 utils/adt/timestamp.c:3784 +#: utils/adt/timestamp.c:4244 +#, c-format +msgid "interval out of range" +msgstr "intervalが範囲外です" + +#: utils/adt/timestamp.c:1062 utils/adt/timestamp.c:1095 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "不正なINTERVAL型の修正子です" + +#: utils/adt/timestamp.c:1078 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d)の精度は負ではいけません" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d)の精度を許容最大値%dまで減らしました" + +#: utils/adt/timestamp.c:1466 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "interval(%d)の精度は%dから%dまででなければなりません" + +#: utils/adt/timestamp.c:2643 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "無限大のtimestampを減算できません" + +#: utils/adt/timestamp.c:3912 utils/adt/timestamp.c:4505 utils/adt/timestamp.c:4667 utils/adt/timestamp.c:4688 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "timestampの単位\"%s\"はサポートされていません" + +#: utils/adt/timestamp.c:3926 utils/adt/timestamp.c:4459 utils/adt/timestamp.c:4698 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "timestampの単位\"%s\"は不明です" + +#: utils/adt/timestamp.c:4056 utils/adt/timestamp.c:4500 utils/adt/timestamp.c:4863 utils/adt/timestamp.c:4885 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "timestamp with time zoneの単位\"%s\"はサポートされていません" + +#: utils/adt/timestamp.c:4073 utils/adt/timestamp.c:4454 utils/adt/timestamp.c:4894 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "timestamp with time zoneの単位\"%s\"は不明です" + +#: utils/adt/timestamp.c:4231 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "月は通常週を含んでいますので、intervalの単位\"%s\"はサポートされていません" + +#: utils/adt/timestamp.c:4237 utils/adt/timestamp.c:4988 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "intervalの単位\"%s\"はサポートされていません" + +#: utils/adt/timestamp.c:4253 utils/adt/timestamp.c:5011 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "intervalの単位\"%s\"は不明です" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: トリガーとして呼ばれなければなりません" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: update 時に呼ばれなければなりません" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: update 前に呼ばれなければなりません" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: 各行ごとに呼ばれなければなりません" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_inは実装されていません" + +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "フレーズ演算子で指定する距離は%d以下でなくてはなりません" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "tsquery内の構文エラー: \"%s\"" + +#: utils/adt/tsquery.c:334 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "tsquery内にオペランドがありません\"%s\"" + +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "tsquery内の値が大きすぎます: \"%s\"" + +#: utils/adt/tsquery.c:573 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "tsqueryのオペランドが長過ぎます: \"%s\"" + +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "tsquery内の単語が長すぎます: \"%s\"" + +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "テキスト検索問い合わせが字句要素を含みません: \"%s\"" + +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsqueryが大きすぎます" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "テキスト検索問い合わせはストップワードのみを含む、あるいは、字句要素を含みません。無視されます" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "フレーズ演算子で指定する距離は%dより小さい正の数でなければなりません" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "ts_rewrite問い合わせは2列のtsquery列を返さなければなりません" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "重み配列は1次元の配列でなければなりません" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "重み配列が短すぎます" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "重み配列にはNULL値を含めてはいけません" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:872 +#, c-format +msgid "weight out of range" +msgstr "重みが範囲外です" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "単語が長すぎます(%ldバイト、最大は%ldバイト)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "tsベクターのための文字列が長すぎます(%ldバイト、最大は%ldバイト)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "語彙素配列にはnullを含めてはいけません" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "重み付け配列にはnullを含めてはいけません" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "識別不能な重み付け: \"%c\"" + +#: utils/adt/tsvector_op.c:2414 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "ts_statは1つのtsvector列のみを返さなければなりません" + +#: utils/adt/tsvector_op.c:2603 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "tsvector列\"%s\"は存在しません" + +#: utils/adt/tsvector_op.c:2610 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "値\"%s\"は型tsvectorではありません" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "設定列\"%s\"は存在しません" + +#: utils/adt/tsvector_op.c:2628 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "%s列はregconfig型ではありません" + +#: utils/adt/tsvector_op.c:2635 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "設定列\"%s\"をNULLにすることはできません" + +#: utils/adt/tsvector_op.c:2648 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "テキスト検索設定名称\"%s\"はスキーマ修飾しなけれナバりません" + +#: utils/adt/tsvector_op.c:2673 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "列\"%s\"は文字型ではありません" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "tsvector内の構文エラー: %s" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "エスケープ文字がありません: \"%s\"" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "tsvector内の位置情報が間違っています: \"%s\"" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "乱数値を生成できませんでした" + +#: utils/adt/varbit.c:109 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "型%sの長さは最低でも1です" + +#: utils/adt/varbit.c:114 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "型%sの長さは%dを超えられません" + +#: utils/adt/varbit.c:197 utils/adt/varbit.c:498 utils/adt/varbit.c:993 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "ビット列の長さが上限値を超えています(%d)" + +#: utils/adt/varbit.c:211 utils/adt/varbit.c:355 utils/adt/varbit.c:405 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "ビット列長%dが型bit(%d)に一致しません" + +#: utils/adt/varbit.c:233 utils/adt/varbit.c:534 +#, c-format +msgid "\"%.*s\" is not a valid binary digit" +msgstr "\"%.*s\"は有効な2進数の数字ではありません" + +#: utils/adt/varbit.c:258 utils/adt/varbit.c:559 +#, c-format +msgid "\"%.*s\" is not a valid hexadecimal digit" +msgstr "\"%.*s\"は有効な16進数の数字ではありません" + +#: utils/adt/varbit.c:346 utils/adt/varbit.c:651 +#, c-format +msgid "invalid length in external bit string" +msgstr "ビット列の外部値の不正な長さ" + +#: utils/adt/varbit.c:512 utils/adt/varbit.c:660 utils/adt/varbit.c:756 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "ビット列は型bit varying(%d)には長すぎます" + +#: utils/adt/varbit.c:1086 utils/adt/varbit.c:1184 utils/adt/varlena.c:875 utils/adt/varlena.c:939 utils/adt/varlena.c:1083 utils/adt/varlena.c:3306 utils/adt/varlena.c:3373 +#, c-format +msgid "negative substring length not allowed" +msgstr "負の長さのsubstringは許可されません" + +#: utils/adt/varbit.c:1241 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "サイズが異なるビット列のANDはできません" + +#: utils/adt/varbit.c:1282 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "サイズが異なるビット列のORはできません" + +#: utils/adt/varbit.c:1322 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "サイズが異なるビット列のXORはできません" + +#: utils/adt/varbit.c:1804 utils/adt/varbit.c:1862 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "ビットのインデックス%dが有効範囲0..%dの間にありません" + +#: utils/adt/varbit.c:1813 utils/adt/varlena.c:3566 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "新しいビットは0か1でなければなりません" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "値は型character(%d)としては長すぎます" + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "値は型character varying(%d)としては長すぎます" + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1475 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "文字列比較で使用する照合順序を特定できませんでした" + +#: utils/adt/varlena.c:1182 utils/adt/varlena.c:1915 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "非決定的照合順序は部分文字列探索ではサポートされません" + +#: utils/adt/varlena.c:1574 utils/adt/varlena.c:1587 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "文字列をUTF-16に変換できませんでした: エラーコード %lu" + +#: utils/adt/varlena.c:1602 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "Unicode文字列を比較できませんでした: %m" + +#: utils/adt/varlena.c:1653 utils/adt/varlena.c:2367 +#, c-format +msgid "collation failed: %s" +msgstr "照合順序による比較に失敗しました: %s" + +#: utils/adt/varlena.c:2575 +#, c-format +msgid "sort key generation failed: %s" +msgstr "ソートキーの生成に失敗しました: %s" + +#: utils/adt/varlena.c:3450 utils/adt/varlena.c:3517 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "インデックス%dは有効範囲0..%dの間にありません" + +#: utils/adt/varlena.c:3481 utils/adt/varlena.c:3553 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "インデックス%lldは有効範囲0..%lldの間にありません" + +#: utils/adt/varlena.c:4590 +#, c-format +msgid "field position must be greater than zero" +msgstr "フィールド位置は0より大きくなければなりません" + +#: utils/adt/varlena.c:5456 +#, c-format +msgid "unterminated format() type specifier" +msgstr "終端されていないformat()型指定子" + +#: utils/adt/varlena.c:5457 utils/adt/varlena.c:5591 utils/adt/varlena.c:5712 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "一つの\"%%\"には\"%%%%\"を使ってください。" + +#: utils/adt/varlena.c:5589 utils/adt/varlena.c:5710 +#, c-format +msgid "unrecognized format() type specifier \"%.*s\"" +msgstr "認識できない format() の型指定子\"%.*s\"" + +#: utils/adt/varlena.c:5602 utils/adt/varlena.c:5659 +#, c-format +msgid "too few arguments for format()" +msgstr "format()の引数が少なすぎます" + +#: utils/adt/varlena.c:5755 utils/adt/varlena.c:5937 +#, c-format +msgid "number is out of range" +msgstr "数値が範囲外です" + +#: utils/adt/varlena.c:5818 utils/adt/varlena.c:5846 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "書式は引数0を指定していますが、引数が1から始まっています" + +#: utils/adt/varlena.c:5839 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "width引数の位置は\"$\"で終わらなければなりません" + +#: utils/adt/varlena.c:5884 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "NULLはSQL識別子として書式付けできません" + +#: utils/adt/varlena.c:6010 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "Unicode正規化はサーバエンコーディングがUTF-8の場合にのみ実行されます" + +#: utils/adt/varlena.c:6023 +#, c-format +msgid "invalid normalization form: %s" +msgstr "不正な正規化形式: %s" + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "ntileの値は0より大きくなければなりません" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "nth_valueの値0より大きくなければなりません" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "トランザクションID%sは未来の値です" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "不正な外部pg_snapshotデータ" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "非サポートのXML機能です。" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "この機能はlibxmlサポートを付けたサーバが必要です。" + +#: utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "--with-libxmlを使用してPostgreSQLを再構築する必要があります。" + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:570 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "不正な符号化方式名\"%s\"" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "無効なXMLコメント" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "XML文書ではありません" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "無効なXML処理命令です" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "XML処理命令の対象名を\"%s\"とすることができませんでした。" + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML処理命令には\"?>\"を含めることはできません。" + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "XML の妥当性検査は実装されていません" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "XMLライブラリを初期化できませんでした" + +#: utils/adt/xml.c:962 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2が互換性がない文字型を持ちます: sizeof(char)=%u、sizeof(xmlChar)=%u" + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "XMLエラーハンドラを設定できませんでした" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "これはおそらく使用するlibxml2のバージョンがPostgreSQLを構築する時に使用したlibxml2ヘッダと互換性がないことを示します。" + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "文字の値が有効ではありません" + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "スペースをあけてください。" + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "standalone には 'yes' か 'no' だけが有効です。" + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "不正な形式の宣言: バージョンがありません。" + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "テキスト宣言にエンコーディングの指定がありません。" + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "XML 宣言のパース中: '>?' が必要です。" + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "認識できないlibxml のエラーコード: %d" + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XMLはデータ値として無限をサポートしません。" + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XMLタイムスタンプ値としては無限をサポートしません。" + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "不正な無効な問い合わせ" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "XML名前空間マッピングに対する不正な配列" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "この配列は第2軸の長さが2である2次元配列でなければなりません。" + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "空のXPath式" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "名前空間名もURIもnullにはできません" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "\"%s\"という名前のXML名前空間およびURI\"%s\"を登録できませんでした" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "デフォルト名前空間は実装されていません" + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "行パスフィルタは空文字列であってはなりません" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "列パスフィルタ空文字列であってはなりません" + +#: utils/adt/xml.c:4661 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "列XPath式が2つ以上の値を返却しました" + +#: utils/cache/lsyscache.c:1015 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "型%sから型%sへのキャストは存在しません" + +#: utils/cache/lsyscache.c:2764 utils/cache/lsyscache.c:2797 utils/cache/lsyscache.c:2830 utils/cache/lsyscache.c:2863 +#, c-format +msgid "type %s is only a shell" +msgstr "型%sは単なるシェルです" + +#: utils/cache/lsyscache.c:2769 +#, c-format +msgid "no input function available for type %s" +msgstr "型%sの利用可能な入力関数がありません" + +#: utils/cache/lsyscache.c:2802 +#, c-format +msgid "no output function available for type %s" +msgstr "型%sの利用可能な出力関数がありません" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "アクセスメソッド %2$s の演算子クラス\"%1$s\"は%4$s型に対応するサポート関数%3$dを含んでいません" + +#: utils/cache/plancache.c:720 +#, c-format +msgid "cached plan must not change result type" +msgstr "キャッシュした実行計画は結果型を変更してはなりません" + +#: utils/cache/relcache.c:6072 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "リレーションキャッシュ初期化ファイル\"%sを作成できません: %m" + +#: utils/cache/relcache.c:6074 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "とりあえず続行しますが、何かがおかしいです。" + +#: utils/cache/relcache.c:6396 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "キャッシュファイル\"%s\"を削除できませんでした: %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "リレーションのマッピングを変更したトランザクションはPREPAREできません" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "リレーションマッピングファイル\"%s\"に不正なデータがあります" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "リレーションマッピングファイル\"%s\"の中に不正なチェックサムがあります" + +#: utils/cache/typcache.c:1692 utils/fmgr/funcapi.c:461 +#, c-format +msgid "record type has not been registered" +msgstr "レコード型は登録されていません" + +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "TRAP: ExceptionalCondition: 不正な引数\n" + +#: utils/error/assert.c:40 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "TRAP: %s(\"%s\", ファイル: \"%s\", 行: %d)\n" + +#: utils/error/elog.c:322 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "エラーメッセージの処理が可能になる前にエラーが発生しました\n" + +#: utils/error/elog.c:1868 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "ファイル\"%s\"の標準エラー出力としての再オープンに失敗しました: %m" + +#: utils/error/elog.c:1881 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "ファイル\"%s\"の標準出力としての再オープンに失敗しました: %m" + +#: utils/error/elog.c:2373 utils/error/elog.c:2407 utils/error/elog.c:2423 +msgid "[unknown]" +msgstr "[不明]" + +#: utils/error/elog.c:2931 utils/error/elog.c:3241 utils/error/elog.c:3349 +msgid "missing error text" +msgstr "エラーテキストがありません" + +#: utils/error/elog.c:2934 utils/error/elog.c:2937 utils/error/elog.c:3352 utils/error/elog.c:3355 +#, c-format +msgid " at character %d" +msgstr "(%d文字目)" + +#: utils/error/elog.c:2947 utils/error/elog.c:2954 +msgid "DETAIL: " +msgstr "詳細: " + +#: utils/error/elog.c:2961 +msgid "HINT: " +msgstr "ヒント: " + +#: utils/error/elog.c:2968 +msgid "QUERY: " +msgstr "問い合わせ: " + +#: utils/error/elog.c:2975 +msgid "CONTEXT: " +msgstr "文脈: " + +#: utils/error/elog.c:2985 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "場所: %s, %s:%d\n" + +#: utils/error/elog.c:2992 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "場所: %s:%d\n" + +#: utils/error/elog.c:2999 +msgid "BACKTRACE: " +msgstr "バックトレース: " + +#: utils/error/elog.c:3013 +msgid "STATEMENT: " +msgstr "文: " + +#: utils/error/elog.c:3402 +msgid "DEBUG" +msgstr "DEBUG" + +#: utils/error/elog.c:3406 +msgid "LOG" +msgstr "LOG" + +#: utils/error/elog.c:3409 +msgid "INFO" +msgstr "INFO" + +#: utils/error/elog.c:3412 +msgid "NOTICE" +msgstr "NOTICE" + +#: utils/error/elog.c:3415 +msgid "WARNING" +msgstr "WARNING" + +#: utils/error/elog.c:3418 +msgid "ERROR" +msgstr "ERROR" + +#: utils/error/elog.c:3421 +msgid "FATAL" +msgstr "FATAL" + +#: utils/error/elog.c:3424 +msgid "PANIC" +msgstr "PANIC" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "ファイル\"%2$s\"内に関数\"%1$s\"がありませんでした" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "ライブラリ\"%s\"をロードできませんでした: %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "\"%s\"は互換性がないライブラリです。マジックブロックの欠落" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "拡張ライブラリはPG_MODULE_MAGICマクロを使用しなければなりません。" + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "\"%s\"は互換性がないライブラリです: バージョンの不一致" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "サーバはバージョン%d、ライブラリはバージョン%sです。" + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "サーバ側は FUNC_MAX_ARGS = %d ですが、ライブラリ側は %d です" + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "サーバ側は INDEX_MAX_KEYS = %d ですが、ライブラリ側は %d です" + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "サーバ側は NAMEDATALEN = %d ですが、ライブラリ側は %d です" + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "サーバ側はFLOAT8PASSBYVAL = %sですが、ライブラリ側は%sです。" + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "マジックブロックが意図しない長さであるか、またはパディングが異なります。" + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "\"%s\"は互換性がないライブラリです: マジックブロックの不一致" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "ライブラリ\"%s\"へのアクセスは許可されません" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "ダイナミックライブラリパス内のマクロが不正です: %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "パラメータ\"dynamic_library_path\"内に長さが0の要素があります" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "パラメータ\"dynamic_library_path\"内の要素が絶対パスでありません" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "内部関数\"%s\"は内部用検索テーブルにありません" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "関数\"%s\"の関数情報が見つかりませんでした" + +#: utils/fmgr/fmgr.c:489 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "SQL呼び出し可能な関数にはPG_FUNCTION_INFO_V1(funcname)宣言が必要です" + +#: utils/fmgr/fmgr.c:507 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "info関数\"%2$s\"で報告されたAPIバージョン%1$dが不明です" + +#: utils/fmgr/fmgr.c:2003 +#, c-format +msgid "opclass options info is absent in function call context" +msgstr "関数呼び出しコンテクストに演算子オプション情報がありません" + +#: utils/fmgr/fmgr.c:2070 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "言語有効性検査関数%1$uが言語%3$uではなく%2$uに対して呼び出されました" + +#: utils/fmgr/funcapi.c:384 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "戻り値型%2$sとして宣言された関数\"%1$s\"の実際の結果型を特定できませんでした" + +#: utils/fmgr/funcapi.c:1651 utils/fmgr/funcapi.c:1683 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "別名の数が列の数と一致しません" + +#: utils/fmgr/funcapi.c:1677 +#, c-format +msgid "no column alias was provided" +msgstr "列の別名が提供されていませんでした" + +#: utils/fmgr/funcapi.c:1701 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "レコードを返す関数についての行定義を特定できませんでした" + +#: utils/init/miscinit.c:287 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "データディレクトリ\"%s\"は存在しません" + +#: utils/init/miscinit.c:292 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"の権限を読み取れませんでした: %m" + +#: utils/init/miscinit.c:300 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "指定されたデータディレクトリ\"%s\"はディレクトリではありません" + +#: utils/init/miscinit.c:316 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "データディレクトリ\"%s\"の所有者情報が間違っています" + +#: utils/init/miscinit.c:318 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "データディレクトリを所有するユーザがサーバを起動しなければなりません。" + +#: utils/init/miscinit.c:336 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "データディレクトリ\"%s\"の権限設定が不正です" + +#: utils/init/miscinit.c:338 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "権限は u=rwx(0700) または u=rwx,g=rx (0750) でなければなりません。" + +#: utils/init/miscinit.c:617 utils/misc/guc.c:7157 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "セキュリティー制限操作内でパラメーター\"%s\"を設定できません" + +#: utils/init/miscinit.c:685 +#, c-format +msgid "role with OID %u does not exist" +msgstr "OID が %u であるロールは存在しません" + +#: utils/init/miscinit.c:715 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "ロール\"%s\"はログインが許可されません" + +#: utils/init/miscinit.c:733 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "ロール\"%s\"からの接続が多すぎます" + +#: utils/init/miscinit.c:793 +#, c-format +msgid "permission denied to set session authorization" +msgstr "set session authorization用の権限がありません" + +#: utils/init/miscinit.c:876 +#, c-format +msgid "invalid role OID: %u" +msgstr "不正なロールID: %u" + +#: utils/init/miscinit.c:930 +#, c-format +msgid "database system is shut down" +msgstr "データベースシステムはシャットダウンしました" + +#: utils/init/miscinit.c:1017 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "ロックファイル\"%s\"を作成できませんでした: %m" + +#: utils/init/miscinit.c:1031 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "ロックファイル\"%s\"をオープンできませんでした: %m" + +#: utils/init/miscinit.c:1038 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "ロックファイル\"%s\"を読み取れませんでした: %m" + +#: utils/init/miscinit.c:1047 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "ロックファイル\"%s\"が空です" + +#: utils/init/miscinit.c:1048 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "他のサーバが稼働しているか、前回のサーバ起動失敗のためロックファイルが残っているかのいずれかです" + +#: utils/init/miscinit.c:1092 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "ロックファイル\"%s\"はすでに存在します" + +#: utils/init/miscinit.c:1096 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "他のpostgres(PID %d)がデータディレクトリ\"%s\"で稼動していませんか?" + +#: utils/init/miscinit.c:1098 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "他のpostmaster(PID %d)がデータディレクトリ\"%s\"で稼動していませんか?" + +#: utils/init/miscinit.c:1101 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "他のpostgres(PID %d)がソケットファイル\"%s\"を使用していませんか?" + +#: utils/init/miscinit.c:1103 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "他のpostmaster(PID %d)がソケットファイル\"%s\"を使用していませんか?" + +#: utils/init/miscinit.c:1154 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "古いロックファイル\"%s\"を削除できませんでした: %m" + +#: utils/init/miscinit.c:1156 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "このファイルは偶然残ってしまったようですが、削除できませんでした。手作業でこれを削除し再実行してください。" + +#: utils/init/miscinit.c:1193 utils/init/miscinit.c:1207 utils/init/miscinit.c:1218 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "ロックファイル\"%s\"に書き出せませんでした: %m" + +#: utils/init/miscinit.c:1329 utils/init/miscinit.c:1471 utils/misc/guc.c:10056 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "ファイル\"%s\"から読み取れませんでした: %m" + +#: utils/init/miscinit.c:1459 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "ファイル\"%s\"をオープンできませんでした: %m; とりあえず続けます" + +#: utils/init/miscinit.c:1484 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "ロックファイル\"%s\"が誤ったPIDをもっています: %ld、正しくは%ld" + +#: utils/init/miscinit.c:1523 utils/init/miscinit.c:1539 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\"は有効なデータディレクトリではありません" + +#: utils/init/miscinit.c:1525 +#, c-format +msgid "File \"%s\" is missing." +msgstr "ファイル\"%s\"が存在しません" + +#: utils/init/miscinit.c:1541 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "ファイル\"%s\"に有効なデータがありません。" + +#: utils/init/miscinit.c:1543 +#, c-format +msgid "You might need to initdb." +msgstr "initdbする必要があるかもしれません" + +#: utils/init/miscinit.c:1551 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "データディレクトリはPostgreSQLバージョン%sで初期化されましたが、これはバージョン%sとは互換性がありません" + +#: utils/init/miscinit.c:1618 +#, c-format +msgid "loaded library \"%s\"" +msgstr "ライブラリ\"%s\"をロードしました" + +#: utils/init/postinit.c:255 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "レプリケーション接続の認証完了: ユーザ=%s application_name=%s SSL有効 (プロトコル=%s、暗号方式=%s、ビット長=%d、圧縮=%s)" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "off" +msgstr "無効" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "on" +msgstr "有効" + +#: utils/init/postinit.c:262 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "レプリケーション接続の認証完了: ユーザ=%s SSL有効 (プロトコル=%s、暗号方式=%s、ビット長=%d、圧縮=%s)" + +#: utils/init/postinit.c:272 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s" +msgstr "レプリケーション接続の認証完了: ユーザ=%s application_name=%s" + +#: utils/init/postinit.c:275 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "レプリケーション接続の認証完了: ユーザ=%s" + +#: utils/init/postinit.c:284 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "接続の認証完了: ユーザ=%s データベース=%s application_name=%s SSL有効 (プロトコル=%s、暗号方式=%s、ビット長=%d、圧縮=%s)" + +#: utils/init/postinit.c:290 +#, c-format +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "接続の認証完了: ユーザ=%s データベース=%s SSL有効 (プロトコル=%s、暗号方式=%s、ビット長=%d、圧縮=%s)" + +#: utils/init/postinit.c:300 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s" +msgstr "接続の認証完了 ユーザ=%s データベース=%s application_name=%s" + +#: utils/init/postinit.c:302 +#, c-format +msgid "connection authorized: user=%s database=%s" +msgstr "接続の認証完了: ユーザ=%s データベース=%s" + +#: utils/init/postinit.c:334 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "データベース\"%s\"はpg_databaseから消失しました" + +#: utils/init/postinit.c:336 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "OID%uのデータベースは\"%s\"に属するようです。" + +#: utils/init/postinit.c:356 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "現在データベース\"%s\"は接続を受け付けません" + +#: utils/init/postinit.c:369 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "データベース\"%s\"へのアクセスが拒否されました" + +#: utils/init/postinit.c:370 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "ユーザはCONNECT権限を持ちません。" + +#: utils/init/postinit.c:387 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "データベース\"%s\"への接続が多すぎます" + +#: utils/init/postinit.c:409 utils/init/postinit.c:416 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "データベースのロケールがオペレーティングシステムと互換性がありません" + +#: utils/init/postinit.c:410 +#, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "データベースは LC_COLLATE \"%s\"で初期化されていますが、setlocale() でこれを認識されません" + +#: utils/init/postinit.c:412 utils/init/postinit.c:419 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "データベースを別のロケールで再生成するか、または不足しているロケールをインストールしてください" + +#: utils/init/postinit.c:417 +#, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "データベースは LC_CTYPE \"%s\"で初期化されていますが、setlocale()でこれを認識されません" + +#: utils/init/postinit.c:766 +#, c-format +msgid "no roles are defined in this database system" +msgstr "データベースシステム内でロールが定義されていません" + +#: utils/init/postinit.c:767 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "すぐに CREATE USER \"%s\" SUPERUSER; を実行してください。" + +#: utils/init/postinit.c:803 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "データベースのシャットダウン中は、新しいレプリケーション接続は許可されません" + +#: utils/init/postinit.c:807 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "データベースのシャットダウン中に接続するにはスーパユーザである必要があります" + +#: utils/init/postinit.c:817 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "バイナリアップグレードモード中に接続するにはスーパユーザである必要があります" + +#: utils/init/postinit.c:830 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "残りの接続スロットはレプリケーションユーザではないスーパユーザ用に予約されています" + +#: utils/init/postinit.c:840 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "walsenderを起動するにはスーパユーザまたはreplicationロールである必要があります" + +#: utils/init/postinit.c:909 +#, c-format +msgid "database %u does not exist" +msgstr "データベース %u は存在しません" + +#: utils/init/postinit.c:998 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "削除またはリネームされたばかりのようです。" + +#: utils/init/postinit.c:1016 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "データベースのサブディレクトリ\"%s\"がありません。" + +#: utils/init/postinit.c:1021 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m" + +#: utils/mb/conv.c:443 utils/mb/conv.c:635 +#, c-format +msgid "invalid encoding number: %d" +msgstr "不正な符号化方式番号: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "ISO8859文字セットに対する符号化方式ID %dは想定外です" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "WIN文字セットに対する符号化方式ID %dは想定外です<" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:842 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "%sと%s間の変換はサポートされていません" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "符号化方式\"%s\"から\"%s\"用のデフォルト変換関数は存在しません" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:429 utils/mb/mbutils.c:758 utils/mb/mbutils.c:784 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "%dバイトの文字列は符号化変換では長すぎます。" + +#: utils/mb/mbutils.c:511 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "不正な変換元符号化方式名: \"%s\"" + +#: utils/mb/mbutils.c:516 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "不正な変換先符号化方式名: \"%s\"" + +#: utils/mb/mbutils.c:656 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "符号化方式\"%s\"に対する不正なバイト値: 0x%02x" + +#: utils/mb/mbutils.c:819 +#, c-format +msgid "invalid Unicode code point" +msgstr "不正なUnicodeコードポイント" + +#: utils/mb/mbutils.c:1087 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codesetが失敗しました" + +#: utils/mb/mbutils.c:1595 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "符号化方式\"%s\"に対する不正なバイト列です: %s" + +#: utils/mb/mbutils.c:1628 +#, c-format +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "符号化方式\"%2$s\"においてバイト列%1$sである文字は符号化方式\"%3$s\"で等価な文字を持ちません" + +#: utils/misc/guc.c:675 +msgid "Ungrouped" +msgstr "その他" + +#: utils/misc/guc.c:677 +msgid "File Locations" +msgstr "ファイルの位置" + +#: utils/misc/guc.c:679 +msgid "Connections and Authentication" +msgstr "接続と認証" + +#: utils/misc/guc.c:681 +msgid "Connections and Authentication / Connection Settings" +msgstr "接続と認証/接続設定" + +#: utils/misc/guc.c:683 +msgid "Connections and Authentication / Authentication" +msgstr "接続と認証/認証" + +#: utils/misc/guc.c:685 +msgid "Connections and Authentication / SSL" +msgstr "接続と認証/SSL" + +#: utils/misc/guc.c:687 +msgid "Resource Usage" +msgstr "使用リソース" + +#: utils/misc/guc.c:689 +msgid "Resource Usage / Memory" +msgstr "使用リソース/メモリ" + +#: utils/misc/guc.c:691 +msgid "Resource Usage / Disk" +msgstr "使用リソース/ディスク" + +#: utils/misc/guc.c:693 +msgid "Resource Usage / Kernel Resources" +msgstr "使用リソース/カーネルリソース" + +#: utils/misc/guc.c:695 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "使用リソース / コストベースvacuum遅延" + +#: utils/misc/guc.c:697 +msgid "Resource Usage / Background Writer" +msgstr "使用リソース / バックグラウンド・ライタ" + +#: utils/misc/guc.c:699 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "使用リソース / 非同期動作" + +#: utils/misc/guc.c:701 +msgid "Write-Ahead Log" +msgstr "先行書き込みログ" + +#: utils/misc/guc.c:703 +msgid "Write-Ahead Log / Settings" +msgstr "先行書き込みログ / 設定" + +#: utils/misc/guc.c:705 +msgid "Write-Ahead Log / Checkpoints" +msgstr "先行書き込みログ / チェックポイント" + +#: utils/misc/guc.c:707 +msgid "Write-Ahead Log / Archiving" +msgstr "先行書き込みログ / アーカイビング" + +#: utils/misc/guc.c:709 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "先行書き込みログ / アーカイブリカバリ" + +#: utils/misc/guc.c:711 +msgid "Write-Ahead Log / Recovery Target" +msgstr "先行書き込みログ / チェックポイント" + +#: utils/misc/guc.c:713 +msgid "Replication" +msgstr "レプリケーション" + +#: utils/misc/guc.c:715 +msgid "Replication / Sending Servers" +msgstr "レプリケーション / 送信サーバ" + +#: utils/misc/guc.c:717 +msgid "Replication / Primary Server" +msgstr "レプリケーション / プライマリサーバ" + +#: utils/misc/guc.c:719 +msgid "Replication / Standby Servers" +msgstr "レプリケーション / スタンバイサーバ" + +#: utils/misc/guc.c:721 +msgid "Replication / Subscribers" +msgstr "レプリケーション / 購読サーバ" + +#: utils/misc/guc.c:723 +msgid "Query Tuning" +msgstr "問い合わせのチューニング" + +#: utils/misc/guc.c:725 +msgid "Query Tuning / Planner Method Configuration" +msgstr "問い合わせのチューニング / プランナ手法設定" + +#: utils/misc/guc.c:727 +msgid "Query Tuning / Planner Cost Constants" +msgstr "問い合わせのチューニング / プランナコスト定数" + +#: utils/misc/guc.c:729 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "問い合わせのチューニング / 遺伝的問い合わせオプティマイザ" + +#: utils/misc/guc.c:731 +msgid "Query Tuning / Other Planner Options" +msgstr "問い合わせのチューニング / その他のプランオプション" + +#: utils/misc/guc.c:733 +msgid "Reporting and Logging" +msgstr "レポートとログ出力" + +#: utils/misc/guc.c:735 +msgid "Reporting and Logging / Where to Log" +msgstr "レポートとログ出力 / ログの出力先" + +#: utils/misc/guc.c:737 +msgid "Reporting and Logging / When to Log" +msgstr "レポートとログ出力 / ログのタイミング" + +#: utils/misc/guc.c:739 +msgid "Reporting and Logging / What to Log" +msgstr "レポートとログ出力 / ログの内容" + +#: utils/misc/guc.c:741 +msgid "Process Title" +msgstr "プロセスタイトル" + +#: utils/misc/guc.c:743 +msgid "Statistics" +msgstr "統計情報" + +#: utils/misc/guc.c:745 +msgid "Statistics / Monitoring" +msgstr "統計情報 / 監視" + +#: utils/misc/guc.c:747 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "統計情報 / 問い合わせとインデックスの統計情報収集器" + +#: utils/misc/guc.c:749 +msgid "Autovacuum" +msgstr "自動VACUUM" + +#: utils/misc/guc.c:751 +msgid "Client Connection Defaults" +msgstr "クライアント接続のデフォルト設定" + +#: utils/misc/guc.c:753 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "クライアント接続のデフォルト設定 / 文の振舞い" + +#: utils/misc/guc.c:755 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "クライアント接続のデフォルト設定 / ロケールと整形" + +#: utils/misc/guc.c:757 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "クライアント接続のデフォルト設定 / ライブラリの事前読み込み" + +#: utils/misc/guc.c:759 +msgid "Client Connection Defaults / Other Defaults" +msgstr "クライアント接続のデフォルト設定 / その他のデフォルト設定" + +#: utils/misc/guc.c:761 +msgid "Lock Management" +msgstr "ロック管理" + +#: utils/misc/guc.c:763 +msgid "Version and Platform Compatibility" +msgstr "バージョンおよびプラットフォーム間の互換性" + +#: utils/misc/guc.c:765 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "バージョンおよびプラットフォーム間の互換性 / PostgreSQLの以前のバージョン" + +#: utils/misc/guc.c:767 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "バージョンおよびプラットフォーム間の互換性 / 他のプラットフォームおよびクライアント" + +#: utils/misc/guc.c:769 +msgid "Error Handling" +msgstr "エラーハンドリング" + +#: utils/misc/guc.c:771 +msgid "Preset Options" +msgstr "事前設定オプション" + +#: utils/misc/guc.c:773 +msgid "Customized Options" +msgstr "独自オプション" + +#: utils/misc/guc.c:775 +msgid "Developer Options" +msgstr "開発者向けオプション" + +#: utils/misc/guc.c:833 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "このパラメータで使用可能な単位は\"B\"、\"kB\"、\"MB\"、\"GB\"および\"TB\"です。" + +#: utils/misc/guc.c:870 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "このパラメータの有効単位は \"us\"、\"ms\"、\"s\"、\"min\"、\"h\"そして\"d\"です。" + +#: utils/misc/guc.c:932 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "プランナでのシーケンシャルスキャンプランの使用を有効にします。" + +#: utils/misc/guc.c:942 +msgid "Enables the planner's use of index-scan plans." +msgstr "プランナでのインデックススキャンプランの使用を有効にします。" + +#: utils/misc/guc.c:952 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "プランナでのインデックスオンリースキャンプランの使用を有効にします。" + +#: utils/misc/guc.c:962 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "プランナでのビットマップスキャンプランの使用を有効にします。" + +#: utils/misc/guc.c:972 +msgid "Enables the planner's use of TID scan plans." +msgstr "プランナでのTIDスキャンプランの使用を有効にします。" + +#: utils/misc/guc.c:982 +msgid "Enables the planner's use of explicit sort steps." +msgstr "プランナでの明示的ソートの使用を有効にします。" + +#: utils/misc/guc.c:992 +msgid "Enables the planner's use of incremental sort steps." +msgstr "プランナでの差分ソート処理の使用を有効にします。" + +#: utils/misc/guc.c:1001 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "プランナでのハッシュ集約プランの使用を有効にします。" + +#: utils/misc/guc.c:1011 +msgid "Enables the planner's use of materialization." +msgstr "プランナでの実体化の使用を有効にします。" + +#: utils/misc/guc.c:1021 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "プランナでのネストループジョインプランの使用を有効にします。" + +#: utils/misc/guc.c:1031 +msgid "Enables the planner's use of merge join plans." +msgstr "プランナでのマージジョインプランの使用を有効にします。" + +#: utils/misc/guc.c:1041 +msgid "Enables the planner's use of hash join plans." +msgstr "プランナでのハッシュジョインプランの使用を有効にします。" + +#: utils/misc/guc.c:1051 +msgid "Enables the planner's use of gather merge plans." +msgstr "プランナでのギャザーマージプランの使用を有効にします。" + +#: utils/misc/guc.c:1061 +msgid "Enables partitionwise join." +msgstr "パーティション単位ジョインを有効にします。" + +#: utils/misc/guc.c:1071 +msgid "Enables partitionwise aggregation and grouping." +msgstr "パーティション単位の集約およびグルーピングを有効にします。" + +#: utils/misc/guc.c:1081 +msgid "Enables the planner's use of parallel append plans." +msgstr "プランナでの並列アペンドプランの使用を有効にします。" + +#: utils/misc/guc.c:1091 +msgid "Enables the planner's use of parallel hash plans." +msgstr "プランナでの並列ハッシュプランの使用を有効にします。" + +#: utils/misc/guc.c:1101 +msgid "Enables plan-time and run-time partition pruning." +msgstr "実行計画作成時および実行時のパーティション除外処理を有効にします。" + +#: utils/misc/guc.c:1102 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "実行計画時と実行時の、クエリ中の条件とパーティション境界の比較に基づいたパーティション単位のスキャン除外処理を許可します。" + +#: utils/misc/guc.c:1113 +msgid "Enables genetic query optimization." +msgstr "遺伝的問い合わせ最適化を有効にします。" + +#: utils/misc/guc.c:1114 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "このアルゴリズムでは、全数探索を伴わずに行う実行計画の作成を試みます。" + +#: utils/misc/guc.c:1125 +msgid "Shows whether the current user is a superuser." +msgstr "現在のユーザがスーパユーザかどうかを表示します。" + +#: utils/misc/guc.c:1135 +msgid "Enables advertising the server via Bonjour." +msgstr "Bonjour を経由したサーバのアドバタイズを有効にします。" + +#: utils/misc/guc.c:1144 +msgid "Collects transaction commit time." +msgstr "トランザクションのコミット時刻を収集します。" + +#: utils/misc/guc.c:1153 +msgid "Enables SSL connections." +msgstr "SSL接続を有効にします。" + +#: utils/misc/guc.c:1162 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "サーバリロード時にも ssl_passphrase_command を使用します。" + +#: utils/misc/guc.c:1171 +msgid "Give priority to server ciphersuite order." +msgstr "サーバ側の暗号スイート順序を優先します。" + +#: utils/misc/guc.c:1180 +msgid "Forces synchronization of updates to disk." +msgstr "強制的に更新をディスクに同期します。" + +#: utils/misc/guc.c:1181 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "サーバは、確実に更新が物理的にディスクに書き込まれるように複数の場所でfsync()システムコールを使用します。これにより、オペレーティングシステムやハードウェアがクラッシュした後でもデータベースクラスタは一貫した状態に復旧することができます。" + +#: utils/misc/guc.c:1192 +msgid "Continues processing after a checksum failure." +msgstr "チェックサムエラーの発生時に処理を継続します。" + +#: utils/misc/guc.c:1193 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "チェックサムエラーを検知すると、通常PostgreSQLはエラーの報告を行ない、現在のトランザクションを中断させます。ignore_checksum_failureを真に設定することによりエラーを無視します(代わりに警告を報告します)この動作はクラッシュや他の深刻な問題を引き起こすかもしれません。チェックサムが有効な場合にのみ効果があります。" + +#: utils/misc/guc.c:1207 +msgid "Continues processing past damaged page headers." +msgstr "破損したページヘッダがあっても処理を継続します。" + +#: utils/misc/guc.c:1208 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "ページヘッダの障害が分かると、通常PostgreSQLはエラーの報告を行ない、現在のトランザクションを中断させます。zero_damaged_pagesを真に設定することにより、システムは代わりに警告を報告し、障害のあるページをゼロで埋め、処理を継続します。 この動作により、障害のあったページ上にある全ての行のデータを破壊されます。" + +#: utils/misc/guc.c:1221 +msgid "Continues recovery after an invalid pages failure." +msgstr "不正ページエラーの発生時に処理を継続します。" + +#: utils/misc/guc.c:1222 +msgid "Detection of WAL records having references to invalid pages during recovery causes PostgreSQL to raise a PANIC-level error, aborting the recovery. Setting ignore_invalid_pages to true causes the system to ignore invalid page references in WAL records (but still report a warning), and continue recovery. This behavior may cause crashes, data loss, propagate or hide corruption, or other serious problems. Only has an effect during recovery or in standby mode." +msgstr "リカバリ中に不正なページへの参照を行うWALレコードを検出した場合、PostgreSQLはPANICレベルのエラーを出力してリカバリを中断します。ignore_invalid_pagesをtrueに設定するとシステムはWALレコード中の不正なページへの参照を無視してリカバリを継続します(ただし、引き続き警告は出力します)。この挙動はクラッシュ、データ損失、破壊の伝播ないしは隠蔽または他の深刻な問題を引き起こします。リカバリモードもしくはスタンバイモードでのみ有効となります。" + +#: utils/misc/guc.c:1240 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "チェックポイントの後最初に変更された際にページ全体をWALに出力します。" + +#: utils/misc/guc.c:1241 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "ページ書き込み処理中にオペレーティングシステムがクラッシュすると、ディスクへの書き込みが一部分のみ行われる可能性があります。リカバリでは、WALに保存された行の変更だけでは完全に復旧させることができません。このオプションにより、チェックポイントの後の最初の更新時にWALにページを出力するため、完全な復旧が可能になります。" + +#: utils/misc/guc.c:1254 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "チェックポイントの後最初に更新された時に、重要な更新ではなくてもページ全体をWALに書き出します。" + +#: utils/misc/guc.c:1264 +msgid "Compresses full-page writes written in WAL file." +msgstr "WALファイルに出力される全ページ出力を圧縮します。" + +#: utils/misc/guc.c:1274 +msgid "Writes zeroes to new WAL files before first use." +msgstr "新しいWALファイルの使用前にゼロを書き込みます。" + +#: utils/misc/guc.c:1284 +msgid "Recycles WAL files by renaming them." +msgstr "WALファイルを名前を変更して再利用します。" + +#: utils/misc/guc.c:1294 +msgid "Logs each checkpoint." +msgstr "チェックポイントをログに記録します。" + +#: utils/misc/guc.c:1303 +msgid "Logs each successful connection." +msgstr "成功した接続を全てログに記録します。" + +#: utils/misc/guc.c:1312 +msgid "Logs end of a session, including duration." +msgstr "セッションの終了時刻とその期間をログに記録します。" + +#: utils/misc/guc.c:1321 +msgid "Logs each replication command." +msgstr "各レプリケーションコマンドをログに記録します。" + +#: utils/misc/guc.c:1330 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "起動中のサーバがアサーションチェックを有効にしているかどうかを表示します。" + +#: utils/misc/guc.c:1345 +msgid "Terminate session on any error." +msgstr "何からのエラーがあればセッションを終了します" + +#: utils/misc/guc.c:1354 +msgid "Reinitialize server after backend crash." +msgstr "バックエンドがクラッシュした後サーバを再初期化します" + +#: utils/misc/guc.c:1364 +msgid "Logs the duration of each completed SQL statement." +msgstr "完了したSQL全ての実行時間をログに記録します。" + +#: utils/misc/guc.c:1373 +msgid "Logs each query's parse tree." +msgstr "問い合わせのパースツリーをログに記録します。" + +#: utils/misc/guc.c:1382 +msgid "Logs each query's rewritten parse tree." +msgstr "リライト後の問い合わせのパースツリーをログを記録します。" + +#: utils/misc/guc.c:1391 +msgid "Logs each query's execution plan." +msgstr "問い合わせの実行計画をログに記録します。" + +#: utils/misc/guc.c:1400 +msgid "Indents parse and plan tree displays." +msgstr "パースツリーと実行計画ツリーの表示をインデントします。" + +#: utils/misc/guc.c:1409 +msgid "Writes parser performance statistics to the server log." +msgstr "パーサの性能統計情報をサーバログに出力します。" + +#: utils/misc/guc.c:1418 +msgid "Writes planner performance statistics to the server log." +msgstr "プランナの性能統計情報をサーバログに出力します。" + +#: utils/misc/guc.c:1427 +msgid "Writes executor performance statistics to the server log." +msgstr "エグゼキュータの性能統計情報をサーバログに出力します。" + +#: utils/misc/guc.c:1436 +msgid "Writes cumulative performance statistics to the server log." +msgstr "累積の性能統計情報をサーバログに出力します。" + +#: utils/misc/guc.c:1446 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "B-treeの各種操作に関するシステムリソース(メモリとCPU)の使用統計をログに記録します。" + +#: utils/misc/guc.c:1458 +msgid "Collects information about executing commands." +msgstr "実行中のコマンドに関する情報を収集します。" + +#: utils/misc/guc.c:1459 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "そのコマンドが実行を開始した時刻を伴った、各セッションでの現時点で実行中のコマンドに関する情報の収集を有効にします。" + +#: utils/misc/guc.c:1469 +msgid "Collects statistics on database activity." +msgstr "データベースの活動について統計情報を収集します。" + +#: utils/misc/guc.c:1478 +msgid "Collects timing statistics for database I/O activity." +msgstr "データベースのI/O動作に関する時間測定統計情報を収集します。" + +#: utils/misc/guc.c:1488 +msgid "Updates the process title to show the active SQL command." +msgstr "活動中のSQLコマンドを表示するようプロセスタイトルを更新します。" + +#: utils/misc/guc.c:1489 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "新しいSQLコマンドをサーバが受信する度に行うプロセスタイトルの更新を有効にします。" + +#: utils/misc/guc.c:1502 +msgid "Starts the autovacuum subprocess." +msgstr "autovacuumサブプロセスを起動します。" + +#: utils/misc/guc.c:1512 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "LISTENとNOTIFYコマンドのためのデバッグ出力を生成します。" + +#: utils/misc/guc.c:1524 +msgid "Emits information about lock usage." +msgstr "ロック使用状況に関する情報を出力します。" + +#: utils/misc/guc.c:1534 +msgid "Emits information about user lock usage." +msgstr "ユーザロックの使用状況に関する情報を出力します。" + +#: utils/misc/guc.c:1544 +msgid "Emits information about lightweight lock usage." +msgstr "軽量ロックの使用状況に関する情報を出力します。" + +#: utils/misc/guc.c:1554 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "デッドロックの発生時点の全てのロックについての情報をダンプします。" + +#: utils/misc/guc.c:1566 +msgid "Logs long lock waits." +msgstr "長時間のロック待機をログに記録します。" + +#: utils/misc/guc.c:1576 +msgid "Logs the host name in the connection logs." +msgstr "接続ログ内でホスト名を出力します。" + +#: utils/misc/guc.c:1577 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "デフォルトでは、接続ログメッセージには接続ホストのIPアドレスのみが表示されます。 このオプションを有効にすることで、ホスト名もログに表示されるようになります。 ホスト名解決の設定によってはで、無視できないほどの性能の悪化が起きうることに注意してください。" + +#: utils/misc/guc.c:1588 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "\"expr=NULL\"という形の式は\"expr IS NULL\"として扱います。" + +#: utils/misc/guc.c:1589 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "有効にした場合、expr = NULL(またはNULL = expr)という形の式はexpr IS NULLとして扱われます。つまり、exprの評価がNULL値の場合に真を、さもなくば偽を返します。expr = NULLのSQL仕様に基づいた正しい動作は常にNULL(未知)を返すことです。" + +#: utils/misc/guc.c:1601 +msgid "Enables per-database user names." +msgstr "データベース毎のユーザ名を許可します。" + +#: utils/misc/guc.c:1610 +msgid "Sets the default read-only status of new transactions." +msgstr "新しいトランザクションのリードオンリー設定のデフォルト値を設定。" + +#: utils/misc/guc.c:1619 +msgid "Sets the current transaction's read-only status." +msgstr "現在のトランザクションのリードオンリー設定を設定。" + +#: utils/misc/guc.c:1629 +msgid "Sets the default deferrable status of new transactions." +msgstr "新しいトランザクションの遅延可否設定のデフォルト値を設定。" + +#: utils/misc/guc.c:1638 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "リードオンリーのシリアライズ可能なトランザクションを、シリアライズに失敗することなく実行できるまで遅延させるかどうか" + +#: utils/misc/guc.c:1648 +msgid "Enable row security." +msgstr "行セキュリティを有効にします。" + +#: utils/misc/guc.c:1649 +msgid "When enabled, row security will be applied to all users." +msgstr "有効にすると、行セキュリティが全てのユーザに適用されます。" + +#: utils/misc/guc.c:1657 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "CREATE FUNCTION中に関数本体を検査します。" + +#: utils/misc/guc.c:1666 +msgid "Enable input of NULL elements in arrays." +msgstr "配列内のNULL要素入力を有効化。" + +#: utils/misc/guc.c:1667 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "有効にすると、配列入力値における引用符のないNULLはNULL値を意味するようになります。さもなくば文字通りに解釈されます。" + +#: utils/misc/guc.c:1683 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OIDS は今後サポートされません; false のみに設定可能です。" + +#: utils/misc/guc.c:1693 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "標準エラー出力、CSVログ、またはその両方をログファイルに捕捉するための子プロセスを開始します。" + +#: utils/misc/guc.c:1702 +msgid "Truncate existing log files of same name during log rotation." +msgstr "ログローテーション時に既存の同一名称のログファイルを切り詰めます。" + +#: utils/misc/guc.c:1713 +msgid "Emit information about resource usage in sorting." +msgstr "ソート中にリソース使用状況に関する情報を発行します。" + +#: utils/misc/guc.c:1727 +msgid "Generate debugging output for synchronized scanning." +msgstr "同期スキャン処理のデバッグ出力を生成します。" + +#: utils/misc/guc.c:1742 +msgid "Enable bounded sorting using heap sort." +msgstr "ヒープソートを使用した境界のソート処理を有効にします" + +#: utils/misc/guc.c:1755 +msgid "Emit WAL-related debugging output." +msgstr "WAL関連のデバッグ出力を出力します。" + +#: utils/misc/guc.c:1767 +msgid "Datetimes are integer based." +msgstr "日付時刻は整数ベースです。" + +#: utils/misc/guc.c:1778 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "KerberosおよびGSSAPIユーザ名を大文字小文字を区別して扱うかどうかを設定します。" + +#: utils/misc/guc.c:1788 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "普通の文字列リテラル内のバックスラッシュエスケープを警告します。" + +#: utils/misc/guc.c:1798 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "'...' 文字列はバックスラッシュをそのまま扱います。" + +#: utils/misc/guc.c:1809 +msgid "Enable synchronized sequential scans." +msgstr "同期シーケンシャルスキャンを有効にします。" + +#: utils/misc/guc.c:1819 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "リカバリ目標のトランザクションを含めるか除外するかを設定。" + +#: utils/misc/guc.c:1829 +msgid "Allows connections and queries during recovery." +msgstr "リカバリ中でも接続と問い合わせを受け付けます" + +#: utils/misc/guc.c:1839 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "問い合わせの衝突を避けるためのホットスタンバイからプライマリへのフィードバックを受け付けます" + +#: utils/misc/guc.c:1849 +msgid "Allows modifications of the structure of system tables." +msgstr "システムテーブル構造の変更を許可。" + +#: utils/misc/guc.c:1860 +msgid "Disables reading from system indexes." +msgstr "システムインデックスの読み取りを無効にします。" + +#: utils/misc/guc.c:1861 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "これはインデックスの更新は妨げないため使用しても安全です。最も大きな悪影響は低速化です。" + +#: utils/misc/guc.c:1872 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "ラージオブジェクトで権限チェックを行う際、後方互換性モードを有効にします。" + +#: utils/misc/guc.c:1873 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "9.0 より前のPostgreSQLとの互換のため、ラージオブジェクトを読んだり変更したりする際に権限チェックをスキップする。" + +#: utils/misc/guc.c:1883 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "PostgreSQL 9.4以降意味が変わっている構文に対して警告を出します。" + +#: utils/misc/guc.c:1893 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "SQL文を生成する時に、すべての識別子を引用符で囲みます。" + +#: utils/misc/guc.c:1903 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "データチェックサムがこのクラスタで有効になっているかどうかを表示します。" + +#: utils/misc/guc.c:1914 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "シーケンス番号を付加することでsyslogメッセージの重複を防ぎます。" + +#: utils/misc/guc.c:1924 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "syslogに送出するメッセージを行単位で分割して、1024バイトに収まるようにします。" + +#: utils/misc/guc.c:1934 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Gather および Gather Merge でも下位プランを実行するかどうかを制御します。" + +#: utils/misc/guc.c:1935 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "Gather ノードでも下位プランを実行しますか、もしくはただタプルの収集のみを行いますか?" + +#: utils/misc/guc.c:1945 +msgid "Allow JIT compilation." +msgstr "JITコンパイルを許可します。" + +#: utils/misc/guc.c:1956 +msgid "Register JIT compiled function with debugger." +msgstr "JITコンパイルされた関数をデバッガに登録します。" + +#: utils/misc/guc.c:1973 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "LLVMビットコードを出力して、JITデバッグを容易にします。" + +#: utils/misc/guc.c:1984 +msgid "Allow JIT compilation of expressions." +msgstr "式のJITコンパイルを許可します。" + +#: utils/misc/guc.c:1995 +msgid "Register JIT compiled function with perf profiler." +msgstr "perfプロファイラにJITコンパイルされた関数を登録します。" + +#: utils/misc/guc.c:2012 +msgid "Allow JIT compilation of tuple deforming." +msgstr "タプル分解処理のJITコンパイルを許可します。" + +#: utils/misc/guc.c:2023 +msgid "Whether to continue running after a failure to sync data files." +msgstr "データファイルの同期失敗の後に処理を継続するかどうか。" + +#: utils/misc/guc.c:2032 +msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." +msgstr "永続レプリケーションスロットがない場合にWALレシーバが一時スロットを作成するかどうかを設定します。" + +#: utils/misc/guc.c:2050 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "N秒以内に新しいファイルが始まらない場合には、次のWALファイルへの切り替えを強制します。" + +#: utils/misc/guc.c:2061 +msgid "Waits N seconds on connection startup after authentication." +msgstr "認証後、接続開始までN秒待機します。" + +#: utils/misc/guc.c:2062 utils/misc/guc.c:2631 +msgid "This allows attaching a debugger to the process." +msgstr "これによりデバッガがプロセスに接続できます。" + +#: utils/misc/guc.c:2071 +msgid "Sets the default statistics target." +msgstr "デフォルトの統計情報収集目標を設定。" + +#: utils/misc/guc.c:2072 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "ALTER TABLE SET STATISTICS経由で列固有の目標値を持たないテーブル列についての統計情報収集目標を設定します。" + +#: utils/misc/guc.c:2081 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "副問い合わせを展開する上限のFROMリストのサイズを設定。" + +#: utils/misc/guc.c:2083 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "最終的なFROMリストがこの値より多くの要素を持たない時に、プランナは副問い合わせを上位問い合わせにマージします。" + +#: utils/misc/guc.c:2094 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "JOIN式を平坦化する上限のFROMリストのサイズを設定。" + +#: utils/misc/guc.c:2096 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "最終的にFROMリストの項目数がこの値を超えない時には常に、プランナは明示的なJOIN構文をFROM項目のリストに組み込みます。" + +#: utils/misc/guc.c:2107 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "この数を超えるとGEQOを使用するFROM項目数の閾値を設定。" + +#: utils/misc/guc.c:2117 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: effortは他のGEQOパラメータのデフォルトを設定するために使用されます。" + +#: utils/misc/guc.c:2127 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: 集団内の個体数。" + +#: utils/misc/guc.c:2128 utils/misc/guc.c:2138 +msgid "Zero selects a suitable default value." +msgstr "0は適切なデフォルト値を選択します。" + +#: utils/misc/guc.c:2137 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: アルゴリズムの反復回数です。" + +#: utils/misc/guc.c:2149 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "デッドロック状態があるかどうかを調べる前にロックを待つ時間を設定。" + +#: utils/misc/guc.c:2160 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "ホットスタンバイサーバがアーカイブされた WAL データを処理している場合は、問い合わせをキャンセルする前に遅延秒数の最大値を設定。" + +#: utils/misc/guc.c:2171 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "ホットスタンバイサーバがストリームの WAL データを処理している場合は、問い合わせをキャンセルする前に遅延秒数の最大値を設定。" + +#: utils/misc/guc.c:2182 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "リカバリ中の変更の適用の最小遅延時間を設定します。" + +#: utils/misc/guc.c:2193 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "WAL受信プロセスが送出側サーバへ行う状況報告の最大間隔を設定。" + +#: utils/misc/guc.c:2204 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "送出側サーバからのデータ受信を待機する最長時間を設定。" + +#: utils/misc/guc.c:2215 +msgid "Sets the maximum number of concurrent connections." +msgstr "同時接続数の最大値を設定。" + +#: utils/misc/guc.c:2226 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "スーパユーザによる接続用に予約される接続スロットの数を設定。" + +#: utils/misc/guc.c:2236 +msgid "Amount of dynamic shared memory reserved at startup." +msgstr "起動時に予約される動的共有メモリの量。" + +#: utils/misc/guc.c:2251 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "サーバで使用される共有メモリのバッファ数を設定。" + +#: utils/misc/guc.c:2262 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "各セッションで使用される一時バッファの最大数を設定。" + +#: utils/misc/guc.c:2273 +msgid "Sets the TCP port the server listens on." +msgstr "サーバが接続を監視するTCPポートを設定。" + +#: utils/misc/guc.c:2283 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Unixドメインソケットのアクセス権限を設定。" + +#: utils/misc/guc.c:2284 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unixドメインソケットは、通常のUnixファイルシステム権限の設定を使います。 このパラメータ値は chmod と umask システムコールが受け付ける数値のモード指定を想定しています(慣習的な8進数書式を使うためには、0(ゼロ)で始めなくてはなりません)。 " + +#: utils/misc/guc.c:2298 +msgid "Sets the file permissions for log files." +msgstr "ログファイルのパーミッションを設定。" + +#: utils/misc/guc.c:2299 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "このパタメータ値は chmod や umask システムコールで使えるような数値モード指定であることが想定されます(慣習的な記法である8進数書式を使う場合は先頭に0(ゼロ) をつけてください)。 " + +#: utils/misc/guc.c:2313 +msgid "Mode of the data directory." +msgstr "データディレクトリのパーミッション値。" + +#: utils/misc/guc.c:2314 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "このパタメータ値は chmod や umask システムコールが受け付ける数値形式のモード指定です(慣習的な8進形式を使う場合は先頭に0(ゼロ) をつけてください)。 " + +#: utils/misc/guc.c:2327 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "問い合わせの作業用空間として使用されるメモリの最大値を設定。" + +#: utils/misc/guc.c:2328 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "内部ソート操作とハッシュテーブルで使われるメモリの量がこの量に達した時に一時ディスクファイルへの切替えを行います。" + +#: utils/misc/guc.c:2340 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "保守作業で使用される最大メモリ量を設定。" + +#: utils/misc/guc.c:2341 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "VACUUMやCREATE INDEXなどの作業が含まれます。" + +#: utils/misc/guc.c:2351 +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "論理デコーディングで使用するメモリ量の上限を設定します。" + +#: utils/misc/guc.c:2352 +msgid "This much memory can be used by each internal reorder buffer before spilling to disk." +msgstr "個々の内部リオーダバッファはディスクに書き出す前にこれだけの量のメモリを使用することができます。" + +#: utils/misc/guc.c:2368 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "スタック長の最大値をキロバイト単位で設定。" + +#: utils/misc/guc.c:2379 +msgid "Limits the total size of all temporary files used by each process." +msgstr "各プロセスで使用される全ての一時ファイルの合計サイズを制限します。" + +#: utils/misc/guc.c:2380 +msgid "-1 means no limit." +msgstr "-1は無制限を意味します。" + +#: utils/misc/guc.c:2390 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "バッファキャッシュにある1つのページをVACUUM処理する際のコスト。" + +#: utils/misc/guc.c:2400 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "バッファキャッシュにない1つのページをVACUUM処理する際のコスト。" + +#: utils/misc/guc.c:2410 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "VACUUM処理が1つのページをダーティにした際に課すコスト。" + +#: utils/misc/guc.c:2420 +msgid "Vacuum cost amount available before napping." +msgstr "VACUUM処理を一時休止させるまでに使用できるコスト。" + +#: utils/misc/guc.c:2430 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "自動VACUUM用のVACUUM処理を一時休止させるまでに使用できるコスト。" + +#: utils/misc/guc.c:2440 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "各サーバプロセスで同時にオープンできるファイルの最大数を設定。" + +#: utils/misc/guc.c:2453 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "同時に準備状態にできるトランザクションの最大数を設定。" + +#: utils/misc/guc.c:2464 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "ロックの追跡を行うテーブルの最小のOIDを設定。" + +#: utils/misc/guc.c:2465 +msgid "Is used to avoid output on system tables." +msgstr "システムテーブルに関するの出力を避けるために使います。" + +#: utils/misc/guc.c:2474 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "無条件でロックの追跡を行うテーブルのOIDを設定。" + +#: utils/misc/guc.c:2486 +msgid "Sets the maximum allowed duration of any statement." +msgstr "あらゆる文に対して実行時間として許容する上限値を設定。" + +#: utils/misc/guc.c:2487 utils/misc/guc.c:2498 utils/misc/guc.c:2509 +msgid "A value of 0 turns off the timeout." +msgstr "0でこのタイムアウトは無効になります。 " + +#: utils/misc/guc.c:2497 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "ロックの待機の最大許容時間を設定。" + +#: utils/misc/guc.c:2508 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "あらゆるアイドル状態のトランザクションの持続時間として許容する上限値を設定。" + +#: utils/misc/guc.c:2519 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "VACUUM にテーブル行の凍結をさせる最小のトランザクションID差分。" + +#: utils/misc/guc.c:2529 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "行の凍結のためのテーブル全体スキャンを強制させる時のトランザクションID差分。" + +#: utils/misc/guc.c:2539 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "テーブル行でのマルチトランザクションIDの凍結を強制する最小のマルチトランザクション差分。" + +#: utils/misc/guc.c:2549 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "行の凍結のためにテーブル全体スキャンを強制する時点のマルチトランザクション差分。" + +#: utils/misc/guc.c:2559 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "設定していれば、VACUUMやHOTのクリーンアップを遅延させるトランザクション数。" + +#: utils/misc/guc.c:2572 +msgid "Sets the maximum number of locks per transaction." +msgstr "1トランザクション当たりのロック数の上限を設定。" + +#: utils/misc/guc.c:2573 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "共有ロックテーブルの大きさは、最大max_locks_per_transaction * max_connections個の個別のオブジェクトがいかなる時点でもロックされる必要があるという仮定の下に決定されます。" + +#: utils/misc/guc.c:2584 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "1トランザクション当たりの述語ロック数の上限を設定。" + +#: utils/misc/guc.c:2585 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "共有ロックテーブルの大きさは、最大 max_pred_locks_per_transaction * max_connections 個の個別のオブジェクトがいかなる時点でもロックされる必要があるという仮定の下に決められます。" + +#: utils/misc/guc.c:2596 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "1リレーション当たりで述語ロックされるページとタプルの数の上限値を設定。" + +#: utils/misc/guc.c:2597 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "あるコネクションで、同じリレーション内でロックされるページ数とタプル数の合計がこの値を超えたときには、これらのロックはリレーションレベルのロックに置き換えられます。" + +#: utils/misc/guc.c:2607 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "1ページあたりで述語ロックされるタプル数の上限値を設定。" + +#: utils/misc/guc.c:2608 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "あるコネクションで 、同じページ上でロックされるタプルの数がこの値を超えたときには、これらのロックはページレベルのロックに置き換えられます。" + +#: utils/misc/guc.c:2618 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "クライアント認証の完了までの最大許容時間を設定。" + +#: utils/misc/guc.c:2630 +msgid "Waits N seconds on connection startup before authentication." +msgstr "接続開始の際、認証前にN秒待機します。" + +#: utils/misc/guc.c:2641 +msgid "Sets the size of WAL files held for standby servers." +msgstr "スタンバイサーバのために確保するWALの量を設定します。" + +#: utils/misc/guc.c:2652 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "WALを縮小させる際の最小のサイズを設定。" + +#: utils/misc/guc.c:2664 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "チェックポイントの契機となるWALのサイズを指定。" + +#: utils/misc/guc.c:2676 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "自動WALチェックポイントの最大間隔を設定。" + +#: utils/misc/guc.c:2687 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "チェックポイントセグメントがこの値よりも短い時間で使い切られた時に警告します。" + +#: utils/misc/guc.c:2689 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "チェックポイントセグメントファイルを使い切ることが原因で起きるチェックポイントが、ここで指定した秒数よりも頻繁に発生する場合、サーバログにメッセージを書き出します。 デフォルトは30秒です。 ゼロはこの警告を無効にします。 " + +#: utils/misc/guc.c:2701 utils/misc/guc.c:2917 utils/misc/guc.c:2964 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "すでに実行された書き込みがディスクに書き出されるまでのページ数。" + +#: utils/misc/guc.c:2712 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "共有メモリ内に割り当てられた、WALデータ用のディスクページバッファ数を設定。" + +#: utils/misc/guc.c:2723 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "WALライタで実行する書き出しの時間間隔。" + +#: utils/misc/guc.c:2734 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "書き出しが実行されるまでにWALライタで出力するWALの量。" + +#: utils/misc/guc.c:2745 +msgid "Size of new file to fsync instead of writing WAL." +msgstr "新しいファイルでWALを出力する代わりにfsyncするサイズ。" + +#: utils/misc/guc.c:2756 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "WAL送信プロセスの最大同時実行数を設定。" + +#: utils/misc/guc.c:2767 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "同時に定義できるレプリケーションスロットの数の最大値を設定。" + +#: utils/misc/guc.c:2777 +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "レプリケーションスロットで確保できるWALの量の最大値を設定します。" + +#: utils/misc/guc.c:2778 +msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "ディスク内のWALがこの量に達すると、レプリケーションスロットは停止とマークされ、セグメントは削除あるいは再利用のために解放されます。" + +#: utils/misc/guc.c:2790 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "WALレプリケーションを待つ時間の最大値を設定。" + +#: utils/misc/guc.c:2801 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "トランザクションのコミットからWALのディスク書き出しまでの遅延時間をマイクロ秒単位で設定。" + +#: utils/misc/guc.c:2813 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "commit_delay の実行の契機となる、同時に開いているトランザクション数の最小値を設定。" + +#: utils/misc/guc.c:2824 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "浮動小数点値の表示桁数を設定。" + +#: utils/misc/guc.c:2825 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "このパラメータは、real、double precision、幾何データ型に影響します。ゼロまたは負のパラメータ値は標準的な桁数(FLT_DIG もしくは DBL_DIGどちらか適切な方)に追加されます。正の値は直接出力形式を指定します。" + +#: utils/misc/guc.c:2837 +msgid "Sets the minimum execution time above which a sample of statements will be logged. Sampling is determined by log_statement_sample_rate." +msgstr "文がログに出力される最小の実行時間を設定します。サンプリングについてはlog_statement_sample_rateで決定されます。" + +#: utils/misc/guc.c:2840 +msgid "Zero log a sample of all queries. -1 turns this feature off." +msgstr "ゼロにすると全ての問い合わせからサンプリングして記録します。-1はこの機能を無効にします。" + +#: utils/misc/guc.c:2850 +msgid "Sets the minimum execution time above which all statements will be logged." +msgstr "全ての文のログを記録する最小の実行時間を設定。" + +#: utils/misc/guc.c:2852 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "ゼロにすると全ての問い合わせを出力します。-1はこの機能を無効にします。" + +#: utils/misc/guc.c:2862 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "自動VACUUMの活動のログを記録する最小の実行時間を設定。" + +#: utils/misc/guc.c:2864 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "ゼロはすべての活動を出力します。-1は自動VACUUMのログ記録を無効にします。" + +#: utils/misc/guc.c:2874 +msgid "When logging statements, limit logged parameter values to first N bytes." +msgstr "ステートメントをログに出力する際に、記録するパラメータの値を最初のNバイトに制限します。" + +#: utils/misc/guc.c:2875 utils/misc/guc.c:2886 +msgid "-1 to print values in full." +msgstr "-1 で値を全て出力します。" + +#: utils/misc/guc.c:2885 +msgid "When reporting an error, limit logged parameter values to first N bytes." +msgstr "エラー報告の際に、記録するパラメータの値を最初のNバイトに制限します。" + +#: utils/misc/guc.c:2896 +msgid "Background writer sleep time between rounds." +msgstr "バックグランドライタの周期毎の待機時間" + +#: utils/misc/guc.c:2907 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "バックグランドライタが1周期で書き出すLRUページ数の最大値。" + +#: utils/misc/guc.c:2930 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "ディスクサブシステムが効率的に処理可能な同時並行リクエスト数" + +#: utils/misc/guc.c:2931 +msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +msgstr "RAIDアレイでは、これはおおむねアレイ中のドライブのスピンドル数になります。" + +#: utils/misc/guc.c:2948 +msgid "A variant of effective_io_concurrency that is used for maintenance work." +msgstr " effective_io_concurrency の保守作業に使用される変種。" + +#: utils/misc/guc.c:2977 +msgid "Maximum number of concurrent worker processes." +msgstr "同時に実行されるワーカプロセス数の最大値です。" + +#: utils/misc/guc.c:2989 +msgid "Maximum number of logical replication worker processes." +msgstr "レプリケーションワーカプロセス数の最大値です。" + +#: utils/misc/guc.c:3001 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "サブスクリプション毎のテーブル同期ワーカ数の最大値です。" + +#: utils/misc/guc.c:3011 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "ログファイルの自動ローテーションはN秒経過の際に行われます。" + +#: utils/misc/guc.c:3022 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "ログファイルの自動ローテーションはNキロバイト書き込んだ際に行われます。" + +#: utils/misc/guc.c:3033 +msgid "Shows the maximum number of function arguments." +msgstr "関数の引数の最大数を示します。" + +#: utils/misc/guc.c:3044 +msgid "Shows the maximum number of index keys." +msgstr "インデックスキーの最大数を示します。" + +#: utils/misc/guc.c:3055 +msgid "Shows the maximum identifier length." +msgstr "識別子の最大長を示します。" + +#: utils/misc/guc.c:3066 +msgid "Shows the size of a disk block." +msgstr "ディスクブロックサイズを示します。" + +#: utils/misc/guc.c:3077 +msgid "Shows the number of pages per disk file." +msgstr "ディスクファイルごとのページ数を表示します。" + +#: utils/misc/guc.c:3088 +msgid "Shows the block size in the write ahead log." +msgstr "先行書き込みログ(WAL)におけるブロックサイズを表示します" + +#: utils/misc/guc.c:3099 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "WALの取り出しの失敗後に再試行する回数を設定。" + +#: utils/misc/guc.c:3111 +msgid "Shows the size of write ahead log segments." +msgstr "先行書き込みログ(WAL)セグメントのサイズを表示します" + +#: utils/misc/guc.c:3124 +msgid "Time to sleep between autovacuum runs." +msgstr "自動VACUUMの実行開始間隔。" + +#: utils/misc/guc.c:3134 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "VACUUMを行うまでの、タプルを更新または削除した回数の最小値。" + +#: utils/misc/guc.c:3143 +msgid "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums" +msgstr "VACUUMが実行されるまでの、タプル挿入回数の最小値、または-1で挿入VACUUMを無効化します" + +#: utils/misc/guc.c:3152 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "ANALYZEが実行されるまでの、タプルを挿入、更新、削除した回数の最小値。" + +#: utils/misc/guc.c:3162 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "トランザクションID周回を防ぐためにテーブルを自動VACUUMする時点のトランザクションID差分。" + +#: utils/misc/guc.c:3173 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "マルチトランザクション周回を防止するためにテーブルを自動VACUUMする、マルチトランザクション差分。" + +#: utils/misc/guc.c:3183 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "自動VACUUMのワーカプロセスの最大同時実行数を設定。" + +#: utils/misc/guc.c:3193 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "ひとつの保守作業に割り当てる並列処理プロセスの数の最大値を設定。" + +#: utils/misc/guc.c:3203 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "エグゼキュータノードあたりの並列処理プロセスの数の最大値を設定。" + +#: utils/misc/guc.c:3214 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "同時に活動可能な並列処理ワーカの数の最大値を設定。" + +#: utils/misc/guc.c:3225 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "自動VACUUMプロセスで使用するメモリ量の最大値を設定。" + +#: utils/misc/guc.c:3236 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "スナップショット取得後、更新されたページが読み取れなくなるまでの時間。" + +#: utils/misc/guc.c:3237 +msgid "A value of -1 disables this feature." +msgstr "-1でこの機能を無効にします。" + +#: utils/misc/guc.c:3247 +msgid "Time between issuing TCP keepalives." +msgstr "TCPキープアライブを発行する時間間隔。" + +#: utils/misc/guc.c:3248 utils/misc/guc.c:3259 utils/misc/guc.c:3383 +msgid "A value of 0 uses the system default." +msgstr "0でシステムのデフォルトを使用します。" + +#: utils/misc/guc.c:3258 +msgid "Time between TCP keepalive retransmits." +msgstr "TCPキープアライブの再送信の時間間隔。" + +#: utils/misc/guc.c:3269 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "SSLの再ネゴシエーションは今後サポートされません; 0のみに設定可能です。" + +#: utils/misc/guc.c:3280 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "TCPキープアライブの再送信回数の最大値です。" + +#: utils/misc/guc.c:3281 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "これは、接続が失われると判断するまでに再送信される、ひとつづきのキープアライブの数を制御します。0の時はでシステムのデフォルトを使用します。" + +#: utils/misc/guc.c:3292 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "GINによる正確な検索に対して許容する結果数の最大値を設定。" + +#: utils/misc/guc.c:3303 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "プランナが想定するデータキャッシュサイズを設定。" + +#: utils/misc/guc.c:3304 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "つまり、PostgreSQLのデータファイルで使用されるキャッシュ(カーネルおよび共有バッファ)の量です。これは通常8KBのディスクページを単位とします。" + +#: utils/misc/guc.c:3315 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "並列スキャンを検討するテーブルデータの量の最小値を設定。" + +#: utils/misc/guc.c:3316 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "この限度に到達できないような少ないテーブルページ数しか読み取らないとプランナが見積もった場合、並列スキャンは検討されません。" + +#: utils/misc/guc.c:3326 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "並列スキャンを検討するインデックスデータの量の最小値を設定。" + +#: utils/misc/guc.c:3327 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "この限度に到達できないような少ないページ数しか読み取らないとプランナが見積もった場合、並列スキャンは検討されません。" + +#: utils/misc/guc.c:3338 +msgid "Shows the server version as an integer." +msgstr "サーバのバージョンを整数値で表示します。" + +#: utils/misc/guc.c:3349 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "このキロバイト数よりも大きな一時ファイルの使用をログに記録します。" + +#: utils/misc/guc.c:3350 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "ゼロにすると、全てのファイルを記録します。デフォルトは-1です(この機能を無効にします)。" + +#: utils/misc/guc.c:3360 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "pg_stat_activity.queryのために予約するサイズをバイト単位で設定。" + +#: utils/misc/guc.c:3371 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "GINインデックスの保留リストの最大サイズを設定。" + +#: utils/misc/guc.c:3382 +msgid "TCP user timeout." +msgstr "TCPユーザタイムアウト。" + +#: utils/misc/guc.c:3393 +msgid "The size of huge page that should be requested." +msgstr "要求が見込まれるヒュージページのサイズ。" + +#: utils/misc/guc.c:3413 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "ひと続きに読み込むディスクページについてプランナで使用する見積もりコストを設定。" + +#: utils/misc/guc.c:3424 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "ひと続きでは読み込めないディスクページについてプランナで使用する見積もりコストを設定。" + +#: utils/misc/guc.c:3435 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "一つのタプル(行)の処理についてプランナで使用する見積もりコストを設定。" + +#: utils/misc/guc.c:3446 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "インデックススキャンにおける一つのインデックスエントリの処理についてプランナで使用する見積もりコストを設定。 " + +#: utils/misc/guc.c:3457 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "一つの演算子または関数の処理についてプランナで使用する見積もりコストを設定。" + +#: utils/misc/guc.c:3468 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to leader backend." +msgstr "並列処理ワーカからリーダーバックエンドへの一つのタプル(行)の受け渡しについてプランナが使用する見積もりコストを設定。" + +#: utils/misc/guc.c:3479 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "並列問い合わせ実行のためのワーカプロセスの起動についてプランナで使用する見積もりコストを設定。" + +#: utils/misc/guc.c:3491 +msgid "Perform JIT compilation if query is more expensive." +msgstr "問い合わせがこの値より高コストであればJITコンパイルを実行します。" + +#: utils/misc/guc.c:3492 +msgid "-1 disables JIT compilation." +msgstr "-1 でJITコンパイルを禁止します。" + +#: utils/misc/guc.c:3502 +msgid "Optimize JITed functions if query is more expensive." +msgstr "問い合わせがこの値より高コストであればJITコンパイルされた関数を最適化します。" + +#: utils/misc/guc.c:3503 +msgid "-1 disables optimization." +msgstr "-1で最適化を行わなくなります。" + +#: utils/misc/guc.c:3513 +msgid "Perform JIT inlining if query is more expensive." +msgstr "問い合わせがこの値より高コストであればJITコンパイルされた関数をインライン化します。" + +#: utils/misc/guc.c:3514 +msgid "-1 disables inlining." +msgstr "-1 でインライン化を禁止します。" + +#: utils/misc/guc.c:3524 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "カーソルから取り出される行数の全行に対する割合についてプランナで使用する値を設定。" + +#: utils/misc/guc.c:3536 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: 集合内の選択圧力。" + +#: utils/misc/guc.c:3547 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: ランダムパス選択用のシード" + +#: utils/misc/guc.c:3558 +msgid "Multiple of work_mem to use for hash tables." +msgstr "ハッシュテーブルで使用するwork_memの倍率。" + +#: utils/misc/guc.c:3569 +msgid "Multiple of the average buffer usage to free per round." +msgstr "周期ごとに解放するバッファ数の平均バッファ使用量に対する倍数" + +#: utils/misc/guc.c:3579 +msgid "Sets the seed for random-number generation." +msgstr "乱数生成用のシードを設定。" + +#: utils/misc/guc.c:3590 +msgid "Vacuum cost delay in milliseconds." +msgstr "ミリ秒単位のコストベースのVACUUM処理の遅延時間です。" + +#: utils/misc/guc.c:3601 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "自動VACUUM用のミリ秒単位のコストベースのVACUUM処理の遅延時間です。" + +#: utils/misc/guc.c:3612 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "VACUUMが実行されるまでのタプルの更新または削除回数のreltuplesに対する割合。" + +#: utils/misc/guc.c:3622 +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "VACUUMが実行されるまでのタプルの挿入行数のreltuplesに対する割合。" + +#: utils/misc/guc.c:3632 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "ANALYZEが実行されるまでのタプルの更新または削除回数のreltuplesに対する割合。" + +#: utils/misc/guc.c:3642 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "チェックポイント中にダーティバッファの書き出しに使う時間のチェックポイント間隔に対する割合。" + +#: utils/misc/guc.c:3652 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "インデックスクリーンアップが実行されるまでのインデックスタプルの挿入行数のreltuplesに対する割合。" + +#: utils/misc/guc.c:3662 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "log_min_duration_sampleを超過した文のうちログ出力を行う割合。" + +#: utils/misc/guc.c:3663 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "0.0(ログ出力しない)から1.0(すべてログ出力する)の間の値を指定してください。" + +#: utils/misc/guc.c:3672 +msgid "Set the fraction of transactions to log for new transactions." +msgstr "新規トランザクションのログを取得するトランザクションの割合を設定。" + +#: utils/misc/guc.c:3673 +msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "一部のトランザクションの全ての文をログ出力します。0.0 (ログ出力しない)から 1.0 (全てのトランザクションの全ての文をログ出力する)の間の値を指定してください。" + +# hoge +#: utils/misc/guc.c:3693 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "WALファイルの保管のために呼び出されるシェルスクリプトを設定。" + +# hoge +#: utils/misc/guc.c:3703 +msgid "Sets the shell command that will retrieve an archived WAL file." +msgstr "アーカイブされたWALファイルを取り出すシェルコマンドを設定。" + +# hoge +#: utils/misc/guc.c:3713 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "リスタートポイントの時に実行するシェルコマンドを設定。" + +# hoge +#: utils/misc/guc.c:3723 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "リカバリ終了時に1度だけ実行されるシェルコマンドを設定。" + +#: utils/misc/guc.c:3733 +msgid "Specifies the timeline to recover into." +msgstr "リカバリの目標タイムラインを指定します。" + +#: utils/misc/guc.c:3743 +msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." +msgstr "\"immediate\"を指定すると一貫性が確保できた時点でリカバリを終了します。" + +#: utils/misc/guc.c:3752 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "リカバリを指定したトランザクションIDまで進めます。" + +#: utils/misc/guc.c:3761 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "リカバリを指定したタイムスタンプの時刻まで進めます。" + +#: utils/misc/guc.c:3770 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "リカバリを指定した名前のリストアポイントまで進めます。" + +#: utils/misc/guc.c:3779 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "リカバリを先行書き込みログの指定したLSNまで進めます。" + +#: utils/misc/guc.c:3789 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "作成することでスタンバイでのリカバリを終了させるファイルの名前を指定します。" + +#: utils/misc/guc.c:3799 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "送出側サーバへの接続に使用する接続文字列をしています。" + +#: utils/misc/guc.c:3810 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "送出サーバで使用するレプリケーションスロットの名前を設定。" + +#: utils/misc/guc.c:3820 +msgid "Sets the client's character set encoding." +msgstr "クライアントの文字集合の符号化方式を設定。" + +#: utils/misc/guc.c:3831 +msgid "Controls information prefixed to each log line." +msgstr "各ログ行の前に付ける情報を制御します。" + +#: utils/misc/guc.c:3832 +msgid "If blank, no prefix is used." +msgstr "もし空であればなにも付加しません。" + +#: utils/misc/guc.c:3841 +msgid "Sets the time zone to use in log messages." +msgstr "ログメッセージ使用するタイムゾーンを設定。" + +#: utils/misc/guc.c:3851 +msgid "Sets the display format for date and time values." +msgstr "日付時刻値の表示用書式を設定。" + +#: utils/misc/guc.c:3852 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "曖昧な日付の入力の解釈も制御します。" + +#: utils/misc/guc.c:3863 +msgid "Sets the default table access method for new tables." +msgstr "新規テーブルで使用されるデフォルトテーブルアクセスメソッドを設定。" + +#: utils/misc/guc.c:3874 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "テーブルとインデックスの作成先となるデフォルトのテーブル空間を設定。" + +#: utils/misc/guc.c:3875 +msgid "An empty string selects the database's default tablespace." +msgstr "空文字列はデータベースのデフォルトのテーブル空間を選択します。" + +#: utils/misc/guc.c:3885 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "一時テーブルとファイルのソートで使用されるテーブル空間を設定。" + +#: utils/misc/guc.c:3896 +msgid "Sets the path for dynamically loadable modules." +msgstr "動的ロード可能モジュールのパスを設定。" + +#: utils/misc/guc.c:3897 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "オープンする必要がある動的ロード可能なモジュールについて、指定されたファイル名にディレクトリ要素がない(つまり、名前にスラッシュが含まれない)場合、システムは指定されたファイルをこのパスから検索します。 " + +#: utils/misc/guc.c:3910 +msgid "Sets the location of the Kerberos server key file." +msgstr "Kerberosサーバキーファイルの場所を設定。" + +#: utils/misc/guc.c:3921 +msgid "Sets the Bonjour service name." +msgstr "Bonjour サービス名を設定。" + +#: utils/misc/guc.c:3933 +msgid "Shows the collation order locale." +msgstr "テキストデータのソート時に使用されるロケールを表示します。" + +#: utils/misc/guc.c:3944 +msgid "Shows the character classification and case conversion locale." +msgstr "文字クラス分類、大文字小文字変換を決定するロケールを表示します。" + +#: utils/misc/guc.c:3955 +msgid "Sets the language in which messages are displayed." +msgstr "表示用メッセージの言語を設定。" + +#: utils/misc/guc.c:3965 +msgid "Sets the locale for formatting monetary amounts." +msgstr "通貨書式で使用するロケールを設定。 " + +#: utils/misc/guc.c:3975 +msgid "Sets the locale for formatting numbers." +msgstr "数字の書式で使用するロケールを設定。" + +#: utils/misc/guc.c:3985 +msgid "Sets the locale for formatting date and time values." +msgstr "日付と時間の書式で使用するロケールを設定。" + +#: utils/misc/guc.c:3995 +msgid "Lists shared libraries to preload into each backend." +msgstr "各バックエンドに事前ロードする共有ライブラリを列挙します。" + +#: utils/misc/guc.c:4006 +msgid "Lists shared libraries to preload into server." +msgstr "サーバに事前ロードする共有ライブラリを列挙します。" + +#: utils/misc/guc.c:4017 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "各バックエンドに事前読み込みする非特権共有ライブラリを列挙します。" + +#: utils/misc/guc.c:4028 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "スキーマ部を含まない名前に対するスキーマの検索順を設定。" + +#: utils/misc/guc.c:4040 +msgid "Sets the server (database) character set encoding." +msgstr "サーバ(データベース)文字セット符号化方式を設定。" + +#: utils/misc/guc.c:4052 +msgid "Shows the server version." +msgstr "サーバのバージョンを表示します。" + +#: utils/misc/guc.c:4064 +msgid "Sets the current role." +msgstr "現在のロールを設定。" + +#: utils/misc/guc.c:4076 +msgid "Sets the session user name." +msgstr "セッションユーザ名を設定。" + +#: utils/misc/guc.c:4087 +msgid "Sets the destination for server log output." +msgstr "サーバログの出力先を設定。" + +#: utils/misc/guc.c:4088 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "有効な値は、プラットフォームに依存しますが、\"stderr\"、\"syslog\"、\"csvlog\"、\"eventlog\"の組み合わせです。" + +#: utils/misc/guc.c:4099 +msgid "Sets the destination directory for log files." +msgstr "ログファイルの格納ディレクトリを設定。" + +#: utils/misc/guc.c:4100 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "データディレクトリからの相対パスでも絶対パスでも指定できます" + +#: utils/misc/guc.c:4110 +msgid "Sets the file name pattern for log files." +msgstr "ログファイルのファイル名パターンを設定。" + +#: utils/misc/guc.c:4121 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "syslog内でPostgreSQLのメッセージを識別するために使用されるプログラム名を設定。" + +#: utils/misc/guc.c:4132 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "イベントログ内でPostgreSQLのメッセージを識別するために使用されるアプリケーション名を設定。" + +#: utils/misc/guc.c:4143 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "タイムスタンプの表示と解釈に使用するタイムゾーンを設定。" + +#: utils/misc/guc.c:4153 +msgid "Selects a file of time zone abbreviations." +msgstr "タイムゾーン省略形用のファイルを選択します。" + +#: utils/misc/guc.c:4163 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Unixドメインソケットを所有するグループを設定。" + +#: utils/misc/guc.c:4164 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "ソケットを所有するユーザは常にサーバを開始したユーザです。" + +#: utils/misc/guc.c:4174 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Unixドメインソケットの作成先ディレクトリを設定。" + +#: utils/misc/guc.c:4189 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "接続を監視するホスト名またはIPアドレスを設定。" + +#: utils/misc/guc.c:4204 +msgid "Sets the server's data directory." +msgstr "サーバのデータディレクトリを設定。" + +#: utils/misc/guc.c:4215 +msgid "Sets the server's main configuration file." +msgstr "サーバのメイン設定ファイルを設定。" + +#: utils/misc/guc.c:4226 +msgid "Sets the server's \"hba\" configuration file." +msgstr "サーバの\"hba\"設定ファイルを設定。" + +#: utils/misc/guc.c:4237 +msgid "Sets the server's \"ident\" configuration file." +msgstr "サーバの\"ident\"設定ファイルを設定。" + +#: utils/misc/guc.c:4248 +msgid "Writes the postmaster PID to the specified file." +msgstr "postmasterのPIDを指定したファイルに書き込みます。" + +#: utils/misc/guc.c:4259 +msgid "Name of the SSL library." +msgstr "SSLライブラリの名前。" + +#: utils/misc/guc.c:4274 +msgid "Location of the SSL server certificate file." +msgstr "SSLサーバ証明書ファイルの場所です" + +#: utils/misc/guc.c:4284 +msgid "Location of the SSL server private key file." +msgstr "SSLサーバ秘密キーファイルの場所です。" + +#: utils/misc/guc.c:4294 +msgid "Location of the SSL certificate authority file." +msgstr "SSL認証局ファイルの場所です" + +#: utils/misc/guc.c:4304 +msgid "Location of the SSL certificate revocation list file." +msgstr "SSL証明書失効リストファイルの場所です。" + +#: utils/misc/guc.c:4314 +msgid "Writes temporary statistics files to the specified directory." +msgstr "一時的な統計情報ファイルを指定したディレクトリに書き込みます。" + +#: utils/misc/guc.c:4325 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "同期スタンバイの数と同期スタンバイ候補の名前の一覧。" + +#: utils/misc/guc.c:4336 +msgid "Sets default text search configuration." +msgstr "デフォルトのテキスト検索設定を設定します。" + +#: utils/misc/guc.c:4346 +msgid "Sets the list of allowed SSL ciphers." +msgstr "SSL暗号として許されるリストを設定。" + +#: utils/misc/guc.c:4361 +msgid "Sets the curve to use for ECDH." +msgstr "ECDHで使用する曲線を設定。" + +#: utils/misc/guc.c:4376 +msgid "Location of the SSL DH parameters file." +msgstr "SSLのDHパラメータファイルの場所です。" + +#: utils/misc/guc.c:4387 +msgid "Command to obtain passphrases for SSL." +msgstr "SSLのパスフレーズを取得するコマンド。" + +#: utils/misc/guc.c:4398 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "統計やログで報告されるアプリケーション名を設定。" + +#: utils/misc/guc.c:4409 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "プロセスのタイトルに含まれるクラスタ名を指定。" + +#: utils/misc/guc.c:4420 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "WALの整合性チェックを行う対象とするリソースマネージャを設定。" + +#: utils/misc/guc.c:4421 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "全ページイメージが全てのデータブロックに対して記録され、WAL再生の結果とクロスチェックされます。" + +#: utils/misc/guc.c:4431 +msgid "JIT provider to use." +msgstr "使用するJITプロバイダ。" + +#: utils/misc/guc.c:4442 +msgid "Log backtrace for errors in these functions." +msgstr "これらの関数でエラーが起きた場合にはバックトレースをログに出力します。" + +#: utils/misc/guc.c:4462 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "文字列リテラルで\"\\'\"が許可されるかどうかを設定。" + +#: utils/misc/guc.c:4472 +msgid "Sets the output format for bytea." +msgstr "bytea の出力フォーマットを設定。" + +#: utils/misc/guc.c:4482 +msgid "Sets the message levels that are sent to the client." +msgstr "クライアントに送信される最小のメッセージレベルを設定。" + +#: utils/misc/guc.c:4483 utils/misc/guc.c:4548 utils/misc/guc.c:4559 utils/misc/guc.c:4635 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr " 各レベルにはそのレベル以下の全てが含まれます。レベルを低くするほど、送信されるメッセージはより少なくなります。 " + +#: utils/misc/guc.c:4493 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "問い合わせの最適化の際にプランナに制約を利用させる。" + +#: utils/misc/guc.c:4494 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "制約により、問い合わせに一致する行がないことが保証されているテーブルをスキップします。" + +#: utils/misc/guc.c:4505 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "新規トランザクションのトランザクション分離レベルを設定。" + +#: utils/misc/guc.c:4515 +msgid "Sets the current transaction's isolation level." +msgstr "現在のトランザクションの分離レベルを設定。" + +#: utils/misc/guc.c:4526 +msgid "Sets the display format for interval values." +msgstr "インターバル値の表示フォーマットを設定。" + +#: utils/misc/guc.c:4537 +msgid "Sets the verbosity of logged messages." +msgstr "ログ出力メッセージの詳細度を設定。" + +#: utils/misc/guc.c:4547 +msgid "Sets the message levels that are logged." +msgstr "ログに出力するメッセージレベルを設定。" + +#: utils/misc/guc.c:4558 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "このレベル以上のエラーを発生させた全てのSQL文をログに記録します。" + +#: utils/misc/guc.c:4569 +msgid "Sets the type of statements logged." +msgstr "ログ出力する文の種類を設定。" + +#: utils/misc/guc.c:4579 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "syslogを有効にした場合に使用するsyslog \"facility\"を設定。" + +#: utils/misc/guc.c:4594 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "トリガと書き換えルールに関するセッションの動作を設定。" + +#: utils/misc/guc.c:4604 +msgid "Sets the current transaction's synchronization level." +msgstr "現在のトランザクションの同期レベルを設定。" + +#: utils/misc/guc.c:4614 +msgid "Allows archiving of WAL files using archive_command." +msgstr "archive_command を使用したWALファイルのアーカイブ処理を許可。" + +#: utils/misc/guc.c:4624 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "リカバリ目標に到達した際の動作を設定。" + +#: utils/misc/guc.c:4634 +msgid "Enables logging of recovery-related debugging information." +msgstr "リカバリ関連のデバッグ情報の記録を行う" + +#: utils/misc/guc.c:4650 +msgid "Collects function-level statistics on database activity." +msgstr "データベースの動作に関して、関数レベルの統計情報を収集します。" + +#: utils/misc/guc.c:4660 +msgid "Set the level of information written to the WAL." +msgstr "WALに書き出される情報のレベルを設定します。" + +#: utils/misc/guc.c:4670 +msgid "Selects the dynamic shared memory implementation used." +msgstr "動的共有メモリで使用する実装を選択します。" + +#: utils/misc/guc.c:4680 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "主共有メモリ領域に使用する共有メモリ実装を選択します。" + +#: utils/misc/guc.c:4690 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "WAL更新のディスクへの書き出しを強制するめの方法を選択します。" + +#: utils/misc/guc.c:4700 +msgid "Sets how binary values are to be encoded in XML." +msgstr "XMLでどのようにバイナリ値を符号化するかを設定します。" + +#: utils/misc/guc.c:4710 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "暗黙的なパースおよび直列化操作においてXMLデータを文書とみなすか断片とみなすかを設定します。" + +#: utils/misc/guc.c:4721 +msgid "Use of huge pages on Linux or Windows." +msgstr "LinuxおよびWindowsでヒュージページを使用。" + +#: utils/misc/guc.c:4731 +msgid "Forces use of parallel query facilities." +msgstr "並列問い合わせ機構を強制的に使用します。" + +#: utils/misc/guc.c:4732 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "可能であれば並列処理ワーカを使用し、問い合わせを並列処理による制限の下で実行します。" + +#: utils/misc/guc.c:4742 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "パスワードの暗号化に使用するアルゴリズムを選択する。" + +#: utils/misc/guc.c:4752 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "プランナでのカスタムプランと汎用プランの選択を制御。" + +#: utils/misc/guc.c:4753 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "プリペアド文は個別プランと一般プランを持ち、プランナはよりよいプランの選択を試みます。これを設定することでそのデフォルト動作を変更できます。" + +#: utils/misc/guc.c:4765 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "使用する SSL/TLSプロトコルの最小バージョンを設定。" + +#: utils/misc/guc.c:4777 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "使用可能な最大の SSL/TLS プロトコルバージョンを指定します。" + +#: utils/misc/guc.c:5580 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"にアクセスできませんでした: %s\n" + +#: utils/misc/guc.c:5585 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "initdbまたはpg_basebackupを実行して、PostgreSQLデータディレクトリを初期化してください。\n" + +#: utils/misc/guc.c:5605 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%sはサーバ設定ファイルの場所が認識できません。\n" +"--config-fileまたは-Dオプションを指定する、あるいはPGDATA環境変数を設\n" +"定する必要があります。\n" + +#: utils/misc/guc.c:5624 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: サーバ設定ファイル\"%s\"にアクセスできません: %s\n" + +#: utils/misc/guc.c:5650 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%sはデータベースシステムデータの場所を認識できません。\n" +"\"%s\"内で\"data_directory\"を指定する、-Dオプションを指定する、PGDATA環\n" +"境変数で設定することができます。\n" + +#: utils/misc/guc.c:5698 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%sは\"hba\"設定ファイルの場所を認識できません。\n" +"\"%s\"内で\"hba_directory\"を指定する、-Dオプションを指定する、PGDATA環\n" +"境変数で設定することができます。\n" + +#: utils/misc/guc.c:5721 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%sは\"ident\"設定ファイルの場所を認識できません。\n" +"\"%s\"内で\"ident_directory\"を指定する、-Dオプションを指定する、PGDATA環\n" +"境変数で設定することができます。\n" + +#: utils/misc/guc.c:6563 +msgid "Value exceeds integer range." +msgstr "値が整数範囲を超えています。" + +#: utils/misc/guc.c:6799 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s はパラメータ\"%s\"の有効範囲 (%d .. %d) を超えています" + +#: utils/misc/guc.c:6835 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s はパラメータ\"%s\"の有効範囲 (%g .. %g) を超えています" + +#: utils/misc/guc.c:6991 utils/misc/guc.c:8358 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "並列処理中はパラメータの設定はできません" + +#: utils/misc/guc.c:6998 utils/misc/guc.c:7750 utils/misc/guc.c:7803 utils/misc/guc.c:7854 utils/misc/guc.c:8187 utils/misc/guc.c:8954 utils/misc/guc.c:9216 utils/misc/guc.c:10882 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "設定パラメータ\"%s\"は不明です" + +#: utils/misc/guc.c:7013 utils/misc/guc.c:8199 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "パラメータ\"%s\"を変更できません" + +#: utils/misc/guc.c:7046 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "現在パラメータ\"%s\"を変更できません" + +#: utils/misc/guc.c:7064 utils/misc/guc.c:7111 utils/misc/guc.c:10898 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "パラメータ\"%s\"を設定する権限がありません" + +#: utils/misc/guc.c:7101 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "接続開始後にパラメータ\"%s\"を変更できません" + +#: utils/misc/guc.c:7149 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "セキュリティー定義用関数内でパラメーター\"%s\"を設定できません" + +#: utils/misc/guc.c:7758 utils/misc/guc.c:7808 utils/misc/guc.c:9223 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "\"%s\"の内容を見るにはスーパユーザまたはpg_read_all_settingsロールである必要があります" + +#: utils/misc/guc.c:7899 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %sは1つの引数のみを取ります" + +#: utils/misc/guc.c:8147 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "ALTER SYSTEM コマンドを実行するにはスーパユーザである必要があります" + +#: utils/misc/guc.c:8232 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "ALTER SYSTEMでのパラメータ値は改行を含んではいけません" + +#: utils/misc/guc.c:8277 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "ファイル\"%s\"の内容をパースできませんでした" + +#: utils/misc/guc.c:8434 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOTはまだ実装されていません" + +#: utils/misc/guc.c:8518 +#, c-format +msgid "SET requires parameter name" +msgstr "SETにはパラメータ名が必要です" + +#: utils/misc/guc.c:8651 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "パラメータ\"%s\"を再定義しようとしています" + +#: utils/misc/guc.c:10444 +#, c-format +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "パラメータ\"%s\"の\"%s\"への変更中" + +#: utils/misc/guc.c:10512 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "パラメータ\"%s\"を設定できません" + +#: utils/misc/guc.c:10602 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "パラメータ\"%s\"の設定をパースできません" + +#: utils/misc/guc.c:10960 utils/misc/guc.c:10994 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "パラメータ\"%s\"の値が無効です: %d" + +#: utils/misc/guc.c:11028 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "パラメータ\"%s\"の値が無効です: %g" + +#: utils/misc/guc.c:11298 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "当該セッションで何らかの一時テーブルがアクセスされた後は \"temp_buffers\"を変更できません" + +#: utils/misc/guc.c:11310 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "このビルドでは bonjour はサポートされていません" + +#: utils/misc/guc.c:11323 +#, c-format +msgid "SSL is not supported by this build" +msgstr "このインストレーションではSSLはサポートされていません" + +#: utils/misc/guc.c:11335 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "\"log_statement_stats\"が真の場合、パラメータを有効にできません" + +#: utils/misc/guc.c:11347 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "\"log_parser_stats\"、\"log_planner_stats\"、\"log_executor_stats\"のいずれかが真の場合は\"log_statement_stats\"を有効にできません" + +#: utils/misc/guc.c:11577 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "posix_fadvise() をもたないプラットフォームではeffective_io_concurrencyは0に設定する必要があります。" + +#: utils/misc/guc.c:11590 +#, c-format +msgid "maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "posix_fadvise() をもたないプラットフォームではmaintenance_io_concurrencyは0に設定する必要があります。" + +#: utils/misc/guc.c:11604 +#, c-format +msgid "huge_page_size must be 0 on this platform." +msgstr "このプラットフォームではhuge_page_sizeを0に設定する必要があります。" + +#: utils/misc/guc.c:11720 +#, c-format +msgid "invalid character" +msgstr "不正な文字" + +#: utils/misc/guc.c:11780 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timelineが妥当な数値ではありません。" + +#: utils/misc/guc.c:11820 +#, c-format +msgid "multiple recovery targets specified" +msgstr "複数のリカバリ目標が指定されています" + +#: utils/misc/guc.c:11821 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr " recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid はこの中の1つまで設定可能です。" + +#: utils/misc/guc.c:11829 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "\"immediate\"のみが指定可能です。" + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "内部エラー: 実行時のパラメータ型が認識できません\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "問い合わせで指定された返却タプルと関数の返り値の型が互換ではありません" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "算出されたCRCチェックサムがファイルに格納されている値と一致しません" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: ユーザ: %d.%02d秒、システム: %d.%02d秒、経過時間: %d.%02d秒" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "問い合わせはテーブル\"%s\"に対する行レベルセキュリティポリシの影響を受けます" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "テーブルの所有者に対するポリシを無効にするには、ALTER TABLE NO FORCE ROW LEVEL SECURITY を使ってください。" + +#: utils/misc/timeout.c:395 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "これ以上のタイムアウト要因を追加できません" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%3$s\"の%4$d行のタイムゾーン省略形\"%1$s\"が長すぎます(最大%2$d文字)" + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%2$s\"の%3$d行のタイムゾーンオフセット%1$dは範囲外です" + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%s\"の行%dでタイムゾーン省略形がありません" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%s\"の行%dでタイムゾーンオフセットがありません" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%s\"の行%dのタイムゾーンオフセット値が無効です" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%s\"の行%dで構文が無効です" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "タイムゾーン省略形\"%s\"が複数定義されています" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "タイムゾーンファイル\"%s\"の行%dの項目は、ファイル\"%s\"の行%dと競合します。" + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "タイムゾーンファイル名が無効です: \"%s\"" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "ファイル\"%s\"でタイムゾーンファイルの再帰の上限を超えました。" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "タイムゾーンファイル\"%s\"を読み込めませんでした: %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%s\"の行%dが長すぎます。" + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "タイムゾーンファイル\"%s\"の行%dにファイル名がない@INCLUDEがあります" + +#: utils/mmgr/aset.c:476 utils/mmgr/generation.c:234 utils/mmgr/slab.c:236 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "メモリコンテキスト\"%s\"の作成時に失敗しました" + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1329 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "動的共有エリアをアタッチできませんでした" + +#: utils/mmgr/mcxt.c:830 utils/mmgr/mcxt.c:866 utils/mmgr/mcxt.c:904 utils/mmgr/mcxt.c:942 utils/mmgr/mcxt.c:978 utils/mmgr/mcxt.c:1009 utils/mmgr/mcxt.c:1045 utils/mmgr/mcxt.c:1097 utils/mmgr/mcxt.c:1132 utils/mmgr/mcxt.c:1167 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "メモリコンテクスト\"%2$s\"でサイズ%1$zuの要求が失敗しました。" + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "カーソル\"%s\"はすでに存在します" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "既存のカーソル\"%s\"をクローズしています" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "ポータル\"%s\"を実行できません" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "固定されたポータル\"%s\"は削除できません" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "アクテイブなポータル\"%s\"を削除できません" + +#: utils/mmgr/portalmem.c:731 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "WITH HOLD 付きのカーソルを作成したトランザクションは PREPARE できません" + +#: utils/mmgr/portalmem.c:1270 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "読み込み専用ではないカーソルのループ内ではトランザクション命令は実行できません" + +#: utils/sort/logtape.c:268 utils/sort/logtape.c:291 +#, c-format +msgid "could not seek to block %ld of temporary file" +msgstr "一時ファイルのブロック%ldへのシークに失敗しました" + +#: utils/sort/logtape.c:297 +#, c-format +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "一時ファイルのブロック%1$ldの読み取りに失敗しました: %3$zuバイト中%2$zuバイトのみ読み取りました" + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "タプルストア共有一時ファイルからの読み込みに失敗しました" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "タプルストア共有一時ファイル内に予期しないチャンクがありました" + +#: utils/sort/sharedtuplestore.c:569 +#, c-format +msgid "could not seek block %u in shared tuplestore temporary file" +msgstr "共有タプルストア一時ファイルのブロック%uへのシークに失敗しました" + +#: utils/sort/sharedtuplestore.c:576 +#, c-format +msgid "could not read from shared tuplestore temporary file: read only %zu of %zu bytes" +msgstr "共有タプルストア一時ファイルからの読み込みに失敗しました: %2$zuバイト中%1$zuバイトのみ読み取りました" + +#: utils/sort/tuplesort.c:3140 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "外部ソートでは%d以上のラン数は扱えません" + +#: utils/sort/tuplesort.c:4221 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "一意インデックス\"%s\"を作成できませんでした" + +#: utils/sort/tuplesort.c:4223 +#, c-format +msgid "Key %s is duplicated." +msgstr "キー%sは重複しています。" + +#: utils/sort/tuplesort.c:4224 +#, c-format +msgid "Duplicate keys exist." +msgstr "重複したキーが存在します。" + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "タプルストア一時ファイルのシークに失敗しました" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 utils/sort/tuplestore.c:1548 +#, c-format +msgid "could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "タプルストア一時ファイルからの読み込みに失敗しました: %2$zuバイト中%1$zuバイトのみ読み取りました" + +#: utils/time/snapmgr.c:619 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "元となるトランザクションはすでに実行中ではありません。" + +#: utils/time/snapmgr.c:1198 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "サブトランザクションからスナップショットをエクスポートすることはできません" + +#: utils/time/snapmgr.c:1357 utils/time/snapmgr.c:1362 utils/time/snapmgr.c:1367 utils/time/snapmgr.c:1382 utils/time/snapmgr.c:1387 utils/time/snapmgr.c:1392 utils/time/snapmgr.c:1407 utils/time/snapmgr.c:1412 utils/time/snapmgr.c:1417 utils/time/snapmgr.c:1519 utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "ファイル\"%s\"内のスナップショットデータが不正です" + +#: utils/time/snapmgr.c:1454 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "SET TRANSACTION SNAPSHOTを全ての問い合わせの前に呼び出さなければなりません" + +#: utils/time/snapmgr.c:1463 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "スナップショットをインポートするトランザクションはSERIALIZABLEまたはREPEATABLE READ分離レベルでなければなりません" + +#: utils/time/snapmgr.c:1472 utils/time/snapmgr.c:1481 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "無効なスナップショット識別子: \"%s\"" + +#: utils/time/snapmgr.c:1573 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "シリアライザブルトランザクションはシリアライザブルではないトランザクションからのスナップショットをインポートできません" + +#: utils/time/snapmgr.c:1577 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "読み取りのみのシリアライザブルトランザクションでは、読み取り専用トランザクションからスナップショットを読み込むことができません" + +#: utils/time/snapmgr.c:1592 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "異なるデータベースからのスナップショットを読み込むことはできません" + +#~ msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +#~ msgstr "消されずに残ったプレースホルダータプルがBRINインデックス\"%s\"で見つかりました、削除します" + +#~ msgid "invalid value for \"buffering\" option" +#~ msgstr "不正な\"buffering\"オプションの値" + +#~ msgid "could not write block %ld of temporary file: %m" +#~ msgstr "一時ファイルのブロック%ldを書き込めませんでした: %m" + +#~ msgid "skipping redundant vacuum to prevent wraparound of table \"%s.%s.%s\"" +#~ msgstr "テーブル\"%s.%s.%s\"の周回防止vacuumは重複のためスキップします" + +#~ msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." +#~ msgstr "データベースクラスタは USE_FLOAT4_BYVAL なしで初期化されましたが、サーバ側は USE_FLOAT4_BYVAL 付きでコンパイルされています。" + +#~ msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." +#~ msgstr "データベースクラスタは USE_FLOAT4_BYVAL 付きで初期化されましたが、サーバ側は USE_FLOAT4_BYVAL なしでコンパイルされています。" + +#~ msgid "could not seek in log segment %s to offset %u: %m" +#~ msgstr "ログセグメント%sをオフセット%uまでシークできませんでした: %m" + +#~ msgid "could not read from log segment %s, offset %u, length %lu: %m" +#~ msgstr "ログセグメント %sのオフセット %uから長さ %lu で読み込めませんでした: %m" + +#~ msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." +#~ msgstr "遷移多様型を用いる集約は多様型の引数を少なくとも1つ取る必要があります。" + +#~ msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." +#~ msgstr "多様型を返す集約は少なくとも1つの多様型の引数を取る必要があります。" + +#~ msgid "A function returning \"internal\" must have at least one \"internal\" argument." +#~ msgstr "\"internal\"\"を返す関数は少なくとも1つの\"internal\"型の引数を取る必要があります。" + +#~ msgid "A function returning a polymorphic type must have at least one polymorphic argument." +#~ msgstr "多様型を返す関数は少なくとも1つの多様型の引数を取る必要があります。" + +#~ msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." +#~ msgstr "\"anyrange\"を返す関数は少なくとも1つの\"anyrange\"型の引数を取る必要があります。" + +#~ msgid "Adding partitioned tables to publications is not supported." +#~ msgstr "パブリケーションへのパーティションテーブルの追加はサポートされていません。" + +#~ msgid "You can add the table partitions individually." +#~ msgstr "各パーティション個別になら追加は可能です。" + +#~ msgid "must be superuser to drop access methods" +#~ msgstr "アクセスメソッドを削除するにはスーパユーザである必要があります" + +#~ msgid "FROM version must be different from installation target version \"%s\"" +#~ msgstr "FROM のバージョンはターゲットのバージョン\"%s\"と異なっていなければなりません" + +#~ msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" +#~ msgstr "CREATE LANGUAGEパラメータの代わりにpg_pltemplateの情報を使用しています" + +#~ msgid "must be superuser to create procedural language \"%s\"" +#~ msgstr "手続き言語\"%s\"を生成するにはスーパユーザである必要があります" + +#~ msgid "unsupported language \"%s\"" +#~ msgstr "言語\"%s\"はサポートされていません" + +#~ msgid "The supported languages are listed in the pg_pltemplate system catalog." +#~ msgstr "サポートされている言語はpg_pltemplateシステムカタログ内に列挙されています" + +#~ msgid "changing return type of function %s from %s to %s" +#~ msgstr "関数%sの戻り値型を%sから%sに変更します" + +#~ msgid "column \"%s\" contains null values" +#~ msgstr "列\"%s\"にはNULL値があります" + +#~ msgid "updated partition constraint for default partition would be violated by some row" +#~ msgstr "デフォルトパーティションの一部の行が更新後のパーティション制約に違反しています" + +#~ msgid "partition key expressions cannot contain whole-row references" +#~ msgstr "パーティションキー式は行全体参照を含むことはできません" + +#~ msgid "Found referenced table's UPDATE trigger." +#~ msgstr "被参照テーブルのUPDATEトリガが見つかりました。" + +#~ msgid "Found referenced table's DELETE trigger." +#~ msgstr "被参照テーブルのDELETEトリガが見つかりました。" + +#~ msgid "Found referencing table's trigger." +#~ msgstr "参照テーブルのトリガが見つかりました。" + +#~ msgid "ignoring incomplete trigger group for constraint \"%s\" %s" +#~ msgstr "制約\"%s\"%sに対する不完全なトリガグループを無視します。" + +#~ msgid "converting trigger group into constraint \"%s\" %s" +#~ msgstr "トリガグループを制約\"%s\"%sに変換しています" + +#~ msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" +#~ msgstr "関数%sの引数型を\"opaque\"から\"cstring\"に変更しています" + +#~ msgid "changing argument type of function %s from \"opaque\" to %s" +#~ msgstr "関数%sの引数型を\"opaque\"から%sに変更しています" + +#~ msgid "invalid value for \"check_option\" option" +#~ msgstr "\"check_option\"オプションの値が不正です" + +#~ msgid "\"%s.%s\" is a partitioned table." +#~ msgstr "\"%s.%s\"はパーティションテーブルです" + +#~ msgid "could not determine actual result type for function declared to return type %s" +#~ msgstr "戻り値型%sとして宣言された関数の実際の結果型を特定できませんでした" + +#~ msgid "could not write to hash-join temporary file: %m" +#~ msgstr "ハッシュ結合用一時ファイルを書き出せません: %m" + +#~ msgid "could not load wldap32.dll" +#~ msgstr "wldap32.dllが読み込めません" + +#~ msgid "SSL certificate revocation list file \"%s\" ignored" +#~ msgstr "SSL証明書失効リストファイル\"%s\"は無視されました" + +#~ msgid "SSL library does not support certificate revocation lists." +#~ msgstr "SSLライブラリが証明書失効リストをサポートしていません。" + +#~ msgid "could not find range type for data type %s" +#~ msgstr "データ型%sの範囲型がありませんでした" + +#~ msgid "could not create signal dispatch thread: error code %lu\n" +#~ msgstr "シグナルディスパッチ用スレッドを作成できませんでした: エラーコード %lu\n" + +#~ msgid "could not fseek in file \"%s\": %m" +#~ msgstr "ファイル\"%s\"をfseekできませんでした: %m" + +#~ msgid "could not reread block %d of file \"%s\": %m" +#~ msgstr "ファイル\"%2$s\"でブロック%1$dの再読み込みに失敗しました: %3$m" + +#~ msgid "only superusers can query or manipulate replication origins" +#~ msgstr "スーパユーザのみがレプリケーション基点の問い合わせや操作ができます" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +#~ msgstr "接続情報が変更されたため、サブスクリプション\"%s\"に対応する論理レプリケーション適用ワーカが再起動します" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +#~ msgstr "レプリケーションスロットの名前が変更されたため、サブスクリプション\"%s\"に対応する論理レプリケーション適用ワーカが再起動します" + +#~ msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +#~ msgstr "サブスクリプションが購読するパブリケーションが変更されたため、サブスクリプション\"%s\"に対応する論理レプリケーション適用ワーカが再起動します" + +#~ msgid "cannot advance replication slot that has not previously reserved WAL" +#~ msgstr "事前に WAL の留保をしていないレプリケーションスロットを進めることはできません" + +#~ msgid "could not read from log segment %s, offset %u, length %zu: %m" +#~ msgstr "ログセグメント %s、オフセット %uから長さ %zu が読み込めませんでした: %m" + +#~ msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" +#~ msgstr "サーバのエンコーディングが UTF-8 ではない場合、コードポイントの値が 007F 以上については Unicode のエスケープ値は使用できません" + +#~ msgid "wrong element type" +#~ msgstr "間違った要素型" + +#~ msgid "cannot use advisory locks during a parallel operation" +#~ msgstr "並列処理中は勧告的ロックは使用できません" + +#~ msgid "cannot output a value of type %s" +#~ msgstr "%s型の値は出力できません" + +#~ msgid "wrong data type: %u, expected %u" +#~ msgstr "データ型が間違っています: %u。%uを想定していました" + +#~ msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." +#~ msgstr "サーバ側はFLOAT4PASSBYVAL = %sですが、ライブラリ側は%sです。" + +#~ msgid "encoding name too long" +#~ msgstr "符号化方式名称が長すぎます" + +#~ msgid "Encrypt passwords." +#~ msgstr "パスワードを暗号化します。" + +#~ msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +#~ msgstr "ENCRYPTEDもしくはUNENCRYPTEDの指定無しにCREATE USERもしくはALTER USERでパスワードが指定された場合、このオプションがパスワードの暗号化を行なうかどうかを決定します。" + +#~ msgid "could not write to temporary file: %m" +#~ msgstr "一時ファイルへの書き出しに失敗しました: %m" + +#~ msgid "could not write to tuplestore temporary file: %m" +#~ msgstr "タプルストア一時ファイルへの書き込みに失敗しました: %m" + +#~ msgid "date/time value \"%s\" is no longer supported" +#~ msgstr "日付時刻の値\"%s\"はもうサポートされていません" + +#~ msgid "Key (%s)=(%s) still referenced from table \"%s\"." +#~ msgstr "キー(%s)=(%s)はまだテーブル\"%s\"から参照されています。" + +#~ msgid "date/time value \"current\" is no longer supported" +#~ msgstr "日付時刻の値\"current\"はもうサポートされていません" + +#~ msgid "could not rmdir directory \"%s\": %m" +#~ msgstr "ディレクトリ\"%s\"を rmdir できませんでした: %m" + +#~ msgid "replication identifier %d is already active for PID %d" +#~ msgstr "レプリケーション識別子%dはすでにPID%dで活動中です" + +#~ msgid "GSSAPI context error" +#~ msgstr "GSSAPIコンテクストエラー" + +#~ msgid "cannot alter type of column referenced in partition key expression" +#~ msgstr "パーティションキー式で参照されている列の型は変更できません" + +#~ msgid "cannot alter type of column named in partition key" +#~ msgstr "パーティションキーに指定されている列の型は変更できません" + +#~ msgid "cannot drop column referenced in partition key expression" +#~ msgstr "パーティションキー式で参照されている列は削除できません" + +#~ msgid "cannot drop column named in partition key" +#~ msgstr "パーティションキーに指定されている列は削除できません" + +#~ msgid "concurrent reindex is not supported for catalog relations, skipping all" +#~ msgstr "インデックス並行再構築はカタログリレーションではサポートされません、すべてスキップします" + +#~ msgid "concurrent reindex of system catalogs is not supported" +#~ msgstr "システムカタログのインデックス並行再構築はサポートされていません" + +#~ msgid "default_table_access_method may not be empty." +#~ msgstr "default_table_access_method は空文字列に設定できません。" + +#~ msgid "only heap AM is supported" +#~ msgstr "ヒープアクセスメソッドのみをサポートしています" diff --git a/src/backend/po/ko.po b/src/backend/po/ko.po new file mode 100644 index 000000000000..f330f3da7e24 --- /dev/null +++ b/src/backend/po/ko.po @@ -0,0 +1,29454 @@ +# Korean message translation file for PostgreSQL server +# Ioseph Kim , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: postgres (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:39+0000\n" +"PO-Revision-Date: 2020-10-27 14:19+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean Team \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 +#: ../common/config_info.c:150 ../common/config_info.c:158 +#: ../common/config_info.c:166 ../common/config_info.c:174 +#: ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "기록되어 있지 않음" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 +#: commands/copy.c:3495 commands/extension.c:3436 utils/adt/genfile.c:125 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" 파일 일기 모드로 열기 실패: %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 +#: access/transam/timeline.c:143 access/transam/timeline.c:362 +#: access/transam/twophase.c:1276 access/transam/xlog.c:3503 +#: access/transam/xlog.c:4728 access/transam/xlog.c:11121 +#: access/transam/xlog.c:11134 access/transam/xlog.c:11587 +#: access/transam/xlog.c:11667 access/transam/xlog.c:11706 +#: access/transam/xlog.c:11749 access/transam/xlogfuncs.c:662 +#: access/transam/xlogfuncs.c:681 commands/extension.c:3446 libpq/hba.c:499 +#: replication/logical/origin.c:717 replication/logical/origin.c:753 +#: replication/logical/reorderbuffer.c:3599 +#: replication/logical/snapbuild.c:1741 replication/logical/snapbuild.c:1783 +#: replication/logical/snapbuild.c:1811 replication/logical/snapbuild.c:1838 +#: replication/slot.c:1622 replication/slot.c:1663 replication/walsender.c:543 +#: storage/file/buffile.c:441 storage/file/copydir.c:195 +#: utils/adt/genfile.c:200 utils/adt/misc.c:763 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "\"%s\" 파일을 읽을 수 없음: %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 +#: access/transam/twophase.c:1279 access/transam/xlog.c:3508 +#: access/transam/xlog.c:4733 replication/logical/origin.c:722 +#: replication/logical/origin.c:761 replication/logical/snapbuild.c:1746 +#: replication/logical/snapbuild.c:1788 replication/logical/snapbuild.c:1816 +#: replication/logical/snapbuild.c:1843 replication/slot.c:1626 +#: replication/slot.c:1667 replication/walsender.c:548 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "\"%s\" 파일을 읽을 수 없음: %d 읽음, 전체 %zu" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 +#: ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 +#: access/heap/rewriteheap.c:1181 access/heap/rewriteheap.c:1284 +#: access/transam/timeline.c:392 access/transam/timeline.c:438 +#: access/transam/timeline.c:516 access/transam/twophase.c:1288 +#: access/transam/twophase.c:1676 access/transam/xlog.c:3375 +#: access/transam/xlog.c:3543 access/transam/xlog.c:3548 +#: access/transam/xlog.c:3876 access/transam/xlog.c:4698 +#: access/transam/xlog.c:5622 access/transam/xlogfuncs.c:687 +#: commands/copy.c:1810 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:533 +#: replication/logical/origin.c:655 replication/logical/origin.c:794 +#: replication/logical/reorderbuffer.c:3657 +#: replication/logical/snapbuild.c:1653 replication/logical/snapbuild.c:1851 +#: replication/slot.c:1513 replication/slot.c:1674 replication/walsender.c:558 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:704 +#: storage/file/fd.c:3425 storage/file/fd.c:3528 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "\"%s\" 파일을 닫을 수 없음: %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "바이트 순서 불일치" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"바이트 순서가 일치하지 않습니다.\n" +"pg_control 파일을 저장하는 데 사용된 바이트 순서는 \n" +"이 프로그램에서 사용하는 순서와 일치해야 합니다. 이 경우 아래 결과는 올바르" +"지 않으며\n" +"현재 PostgreSQL 설치본과 이 데이터 디렉터리가 호환하지 않습니다." + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 +#: ../common/file_utils.c:224 ../common/file_utils.c:283 +#: ../common/file_utils.c:357 access/heap/rewriteheap.c:1267 +#: access/transam/timeline.c:111 access/transam/timeline.c:251 +#: access/transam/timeline.c:348 access/transam/twophase.c:1232 +#: access/transam/xlog.c:3277 access/transam/xlog.c:3417 +#: access/transam/xlog.c:3458 access/transam/xlog.c:3656 +#: access/transam/xlog.c:3741 access/transam/xlog.c:3844 +#: access/transam/xlog.c:4718 access/transam/xlogutils.c:807 +#: postmaster/syslogger.c:1488 replication/basebackup.c:621 +#: replication/basebackup.c:1593 replication/logical/origin.c:707 +#: replication/logical/reorderbuffer.c:2465 +#: replication/logical/reorderbuffer.c:2825 +#: replication/logical/reorderbuffer.c:3579 +#: replication/logical/snapbuild.c:1608 replication/logical/snapbuild.c:1712 +#: replication/slot.c:1594 replication/walsender.c:516 +#: replication/walsender.c:2516 storage/file/copydir.c:161 +#: storage/file/fd.c:679 storage/file/fd.c:3412 storage/file/fd.c:3499 +#: storage/smgr/md.c:475 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1858 +#: utils/init/miscinit.c:1316 utils/init/miscinit.c:1450 +#: utils/init/miscinit.c:1527 utils/misc/guc.c:8252 utils/misc/guc.c:8284 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" 파일을 열 수 없음: %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 +#: access/transam/twophase.c:1649 access/transam/twophase.c:1658 +#: access/transam/xlog.c:10878 access/transam/xlog.c:10916 +#: access/transam/xlog.c:11329 access/transam/xlogfuncs.c:741 +#: postmaster/syslogger.c:1499 postmaster/syslogger.c:1512 +#: utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" 파일 쓰기 실패: %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 +#: ../common/file_utils.c:295 ../common/file_utils.c:365 +#: access/heap/rewriteheap.c:961 access/heap/rewriteheap.c:1175 +#: access/heap/rewriteheap.c:1278 access/transam/timeline.c:432 +#: access/transam/timeline.c:510 access/transam/twophase.c:1670 +#: access/transam/xlog.c:3368 access/transam/xlog.c:3537 +#: access/transam/xlog.c:4691 access/transam/xlog.c:10386 +#: access/transam/xlog.c:10413 replication/logical/snapbuild.c:1646 +#: replication/slot.c:1499 replication/slot.c:1604 storage/file/fd.c:696 +#: storage/file/fd.c:3520 storage/smgr/md.c:921 storage/smgr/md.c:962 +#: storage/sync/sync.c:396 utils/cache/relmapper.c:885 utils/misc/guc.c:8035 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "\"%s\" 파일 fsync 실패: %m" + +#: ../common/exec.c:137 ../common/exec.c:254 ../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "현재 디렉터리를 파악할 수 없음: %m" + +#: ../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "잘못된 바이너리 파일 \"%s\"" + +#: ../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" 바이너리 파일을 읽을 수 없음" + +# translator: %s is IPv4, IPv6, or Unix +#: ../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "\"%s\" 실행 파일을 찾을 수 없음" + +#: ../common/exec.c:270 ../common/exec.c:309 utils/init/miscinit.c:395 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" 이름의 디렉터리로 이동할 수 없습니다: %m" + +#: ../common/exec.c:287 access/transam/xlog.c:10750 +#: replication/basebackup.c:1418 utils/adt/misc.c:337 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "\"%s\" 심볼릭 링크 파일을 읽을 수 없음: %m" + +#: ../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose 실패: %m" + +#: ../common/exec.c:539 ../common/exec.c:584 ../common/exec.c:676 +#: ../common/psprintf.c:143 ../common/stringinfo.c:305 ../port/path.c:630 +#: ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1341 +#: access/transam/xlog.c:6493 lib/dshash.c:246 libpq/auth.c:1090 +#: libpq/auth.c:1491 libpq/auth.c:1559 libpq/auth.c:2089 +#: libpq/be-secure-gssapi.c:484 postmaster/bgworker.c:336 +#: postmaster/bgworker.c:893 postmaster/postmaster.c:2518 +#: postmaster/postmaster.c:2540 postmaster/postmaster.c:4166 +#: postmaster/postmaster.c:4868 postmaster/postmaster.c:4938 +#: postmaster/postmaster.c:5635 postmaster/postmaster.c:5995 +#: replication/libpqwalreceiver/libpqwalreceiver.c:276 +#: replication/logical/logical.c:176 replication/walsender.c:590 +#: storage/buffer/localbuf.c:442 storage/file/fd.c:834 storage/file/fd.c:1304 +#: storage/file/fd.c:1465 storage/file/fd.c:2270 storage/ipc/procarray.c:1045 +#: storage/ipc/procarray.c:1541 storage/ipc/procarray.c:1548 +#: storage/ipc/procarray.c:1972 storage/ipc/procarray.c:2597 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1700 utils/adt/formatting.c:1824 +#: utils/adt/formatting.c:1949 utils/adt/pg_locale.c:484 +#: utils/adt/pg_locale.c:648 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:450 utils/hash/dynahash.c:559 +#: utils/hash/dynahash.c:1071 utils/mb/mbutils.c:401 utils/mb/mbutils.c:428 +#: utils/mb/mbutils.c:757 utils/mb/mbutils.c:783 utils/misc/guc.c:4846 +#: utils/misc/guc.c:4862 utils/misc/guc.c:4875 utils/misc/guc.c:8013 +#: utils/misc/tzparser.c:467 utils/mmgr/aset.c:475 utils/mmgr/dsa.c:701 +#: utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:233 +#: utils/mmgr/mcxt.c:821 utils/mmgr/mcxt.c:857 utils/mmgr/mcxt.c:895 +#: utils/mmgr/mcxt.c:933 utils/mmgr/mcxt.c:969 utils/mmgr/mcxt.c:1000 +#: utils/mmgr/mcxt.c:1036 utils/mmgr/mcxt.c:1088 utils/mmgr/mcxt.c:1123 +#: utils/mmgr/mcxt.c:1158 utils/mmgr/slab.c:235 +#, c-format +msgid "out of memory" +msgstr "메모리 부족" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 +#: ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 +#: ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 +#: utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null 포인터를 중복할 수 없음 (내부 오류)\n" + +#: ../common/file_utils.c:79 ../common/file_utils.c:181 +#: access/transam/twophase.c:1244 access/transam/xlog.c:10854 +#: access/transam/xlog.c:10892 access/transam/xlog.c:11109 +#: access/transam/xlogarchive.c:110 access/transam/xlogarchive.c:226 +#: commands/copy.c:1938 commands/copy.c:3505 commands/extension.c:3425 +#: commands/tablespace.c:795 commands/tablespace.c:886 +#: replication/basebackup.c:444 replication/basebackup.c:627 +#: replication/basebackup.c:700 replication/logical/snapbuild.c:1522 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1816 +#: storage/file/fd.c:3096 storage/file/fd.c:3278 storage/file/fd.c:3364 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:416 utils/adt/genfile.c:642 guc-file.l:1061 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" 파일의 상태값을 알 수 없음: %m" + +#: ../common/file_utils.c:158 ../common/pgfnames.c:48 commands/tablespace.c:718 +#: commands/tablespace.c:728 postmaster/postmaster.c:1509 +#: storage/file/fd.c:2673 storage/file/reinit.c:122 utils/adt/misc.c:259 +#: utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 열 수 없음: %m" + +#: ../common/file_utils.c:192 ../common/pgfnames.c:69 storage/file/fd.c:2685 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 읽을 수 없음: %m" + +#: ../common/file_utils.c:375 access/transam/xlogarchive.c:411 +#: postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1665 +#: replication/slot.c:650 replication/slot.c:1385 replication/slot.c:1527 +#: storage/file/fd.c:714 utils/time/snapmgr.c:1350 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "\"%s\" 파일을 \"%s\" 파일로 이름을 바꿀 수 없음: %m" + +#: ../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "잘못된 이스케이프 조합: \"\\%s\"" + +#: ../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "0x%02x 값의 문자는 이스케이프 처리를 해야함." + +#: ../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "입력 자료의 끝을 기대했는데, \"%s\" 값이 더 있음." + +#: ../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "\"]\" 가 필요한데 \"%s\"이(가) 있음" + +#: ../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "\",\" 또는 \"]\"가 필요한데 \"%s\"이(가) 있음" + +#: ../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "\":\"가 필요한데 \"%s\"이(가) 있음" + +#: ../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "JSON 값을 기대했는데, \"%s\" 값임" + +#: ../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "입력 문자열이 예상치 않게 끝났음." + +#: ../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "\"}\"가 필요한데 \"%s\"이(가) 있음" + +#: ../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "\",\" 또는 \"}\"가 필요한데 \"%s\"이(가) 있음" + +#: ../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "문자열 값을 기대했는데, \"%s\" 값임" + +#: ../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "잘못된 토큰: \"%s\"" + +#: ../common/jsonapi.c:1099 jsonpath_scan.l:499 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 값은 text 형으로 변환할 수 없음." + +#: ../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\" 표기법은 뒤에 4개의 16진수가 와야합니다." + +#: ../common/jsonapi.c:1104 +msgid "" +"Unicode escape values cannot be used for code point values above 007F when " +"the encoding is not UTF8." +msgstr "" +"서버 인코딩이 UTF8이 아닌 경우 007F보다 큰 코드 지점 값에는 유니코드 이스케이" +"프 값을 사용할 수 없음" + +#: ../common/jsonapi.c:1106 jsonpath_scan.l:520 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "유니코드 상위 surrogate(딸림 코드)는 상위 딸림 코드 뒤에 오면 안됨." + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:531 jsonpath_scan.l:541 +#: jsonpath_scan.l:583 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "유니코드 상위 surrogate(딸림 코드) 뒤에는 하위 딸림 코드가 있어야 함." + +#: ../common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 닫을 수 없음: %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "잘못된 포크 이름" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "유효한 포크 이름은 \"main\", \"fsm\" 및 \"vm\"입니다." + +#: ../common/restricted_token.c:64 libpq/auth.c:1521 libpq/auth.c:2520 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "\"%s\" 라이브러리를 불러 올 수 없음: 오류 코드 %lu" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "이 운영체제에서 restricted 토큰을 만들 수 없음: 오류 코드 %lu" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "프로세스 토큰을 열 수 없음: 오류 코드 %lu" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SID를 할당할 수 없음: 오류 코드 %lu" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "restricted 토큰을 만들 수 없음: 오류 코드 %lu" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\" 명령용 프로세스를 시작할 수 없음: 오류 코드 %lu" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "restricted 토큰으로 재실행할 수 없음: 오류 코드 %lu" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "하위 프로세스의 종료 코드를 구할 수 없음: 오류 코드 %lu" + +#: ../common/rmtree.c:79 replication/basebackup.c:1171 +#: replication/basebackup.c:1347 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "파일 또는 디렉터리 \"%s\"의 상태를 확인할 수 없음: %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "\"%s\" 디렉터리나 파일을 삭제할 수 없음: %m" + +# # nonun 부분 begin +#: ../common/saslprep.c:1087 +#, c-format +msgid "password too long" +msgstr "비밀번호가 너무 깁니다." + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "%d바이트가 포함된 문자열 버퍼를 %d바이트 더 확장할 수 없습니다." + +#: ../common/stringinfo.c:310 +#, c-format +msgid "" +"out of memory\n" +"\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "" +"메모리 부족\n" +"\n" +"%d 바이트가 포함된 문자열 버퍼를 %d 바이트 더 확장할 수 없습니다.\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "%ld UID를 찾을 수 없음: %s" + +#: ../common/username.c:45 libpq/auth.c:2027 +msgid "user does not exist" +msgstr "사용자 없음" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "사용자 이름 찾기 실패: 오류 코드 %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "명령을 실행할 수 없음" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "해당 명령어 없음" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "하위 프로그램은 %d 코드로 마쳤습니다" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "0x%X 예외처리로 하위 프로세스가 종료되었습니다" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "하위 프로그램은 %d 신호에 의해서 종료되었습니다: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "하위 프로그램 프로그램은 예상치 못한 %d 상태값으로 종료되었습니다" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "\"%s\" 코드 세트 환경에 사용할 인코딩을 결정할 수 없습니다" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "" +"\"%s\" 로케일 환경에서 사용할 인코딩을 결정할 수 없습니다. 코드 세트: \"%s\"" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "\"%s\" 디렉터리 연결을 할 수 없음: %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "\"%s\" 디렉터리 연결을 할 수 없음: %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "\"%s\" 파일의 정션을 구할 수 없음: %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "\"%s\" 파일의 정션을 구할 수 없음: %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "\"%s\" 파일을 열 수 없음: %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "잠금 위반" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "공유 위반" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "30초 동안 계속해서 다시 시도합니다." + +#: ../port/open.c:129 +#, c-format +msgid "" +"You might have antivirus, backup, or similar software interfering with the " +"database system." +msgstr "" +"바이러스 백신 프로그램, 백업 또는 유사한 소프트웨어가 데이터베이스 시스템을 " +"방해할 수 있습니다." + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "현재 작업 디렉터리를 알 수 없음: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "운영체제 오류 %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "Administrators 그룹의 SID를 가져올 수 없음: 오류 코드 %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "PowerUsers 그룹의 SID를 가져올 수 없음: 오류 코드 %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "토큰 맴버쉽 접근을 확인 할 수 없음: 오류 코드 %lu\n" + +#: access/brin/brin.c:210 +#, c-format +msgid "" +"request for BRIN range summarization for index \"%s\" page %u was not " +"recorded" +msgstr "\"%s\" 인덱스에서 BRIN 범위 요약 요청이 기록되지 못함, 해당 페이지: %u" + +#: access/brin/brin.c:873 access/brin/brin.c:950 access/gin/ginfast.c:1035 +#: access/transam/xlog.c:10522 access/transam/xlog.c:11060 +#: access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 +#: access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 +#: access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 +#: access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "복구 작업 진행 중" + +#: access/brin/brin.c:874 access/brin/brin.c:951 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "BRIN 제어 함수는 복구 작업 중에는 실행 될 수 없음" + +#: access/brin/brin.c:882 access/brin/brin.c:959 +#, c-format +msgid "block number out of range: %s" +msgstr "블록 번호가 범위를 벗어남: %s" + +#: access/brin/brin.c:905 access/brin/brin.c:982 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\" 개체는 BRIN 인덱스가 아닙니다" + +#: access/brin/brin.c:921 access/brin/brin.c:998 +#, c-format +msgid "could not open parent table of index %s" +msgstr "%s 인덱스에 대한 상위 테이블을 열 수 없음" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 +#: access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1435 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "인덱스 행 크기 %zu이(가) 최대값 %zu(\"%s\" 인덱스)을(를) 초과함" + +#: access/brin/brin_revmap.c:392 access/brin/brin_revmap.c:398 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "BRIN 인덱스 속상: 범위 지도가 연결되지 않음" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "예상치 못한 0x%04X 페이지 타입: \"%s\" BRIN 인덱스 %u 블록" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 +#: access/gist/gistvalidate.c:149 access/hash/hashvalidate.c:136 +#: access/nbtree/nbtvalidate.c:117 access/spgist/spgvalidate.c:168 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains function %s with invalid " +"support number %d" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 포함된 %s 함수가 잘못된 지원 번호 %d " +"로 지정되었습니다." + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 +#: access/gist/gistvalidate.c:161 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:129 access/spgist/spgvalidate.c:180 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains function %s with wrong " +"signature for support number %d" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 포함된 %s 함수가 잘못된 signature 지원 " +"번호 %d 로 지정되었습니다." + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 +#: access/gist/gistvalidate.c:181 access/hash/hashvalidate.c:157 +#: access/nbtree/nbtvalidate.c:149 access/spgist/spgvalidate.c:200 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains operator %s with invalid " +"strategy number %d" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 포함된 %s 연산자의 %d 번 전략 번호가 잘" +"못되었습니다." + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 +#: access/hash/hashvalidate.c:170 access/nbtree/nbtvalidate.c:162 +#: access/spgist/spgvalidate.c:216 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains invalid ORDER BY " +"specification for operator %s" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 %s 연산자가 잘못된 ORDER BY 명세를 사용" +"합니다." + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 +#: access/gist/gistvalidate.c:229 access/hash/hashvalidate.c:183 +#: access/nbtree/nbtvalidate.c:175 access/spgist/spgvalidate.c:232 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains operator %s with wrong " +"signature" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 %s 연산자가 잘못된 기호를 사용합니다." + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:223 +#: access/nbtree/nbtvalidate.c:233 access/spgist/spgvalidate.c:259 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing operator(s) for types " +"%s and %s" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에는 %s, %s 자료형용 연산자가 없습니다" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing support function(s) " +"for types %s and %s" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에는 %s, %s 자료형용으로 쓸 함수가 없습니" +"다" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:237 +#: access/nbtree/nbtvalidate.c:257 access/spgist/spgvalidate.c:294 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "\"%s\" 연산자 클래스(접근 방법: %s)에 연산자가 빠졌습니다" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 +#: access/gist/gistvalidate.c:270 +#, c-format +msgid "" +"operator class \"%s\" of access method %s is missing support function %d" +msgstr "\"%s\" 연산자 클래스(접근 방법: %s)에 %d 지원 함수가 빠졌습니다." + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "" +"반환 자료형으로 %s 형을 지정했지만, 칼럼은 %s 자료형입니다. 해당 칼럼: %d 번" +"째 칼럼" + +#: access/common/attmap.c:150 +#, c-format +msgid "" +"Number of returned columns (%d) does not match expected column count (%d)." +msgstr "반환할 칼럼 수(%d)와 예상되는 칼럼수(%d)가 다릅니다." + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "로우 자료형을 변환 할 수 없음" + +#: access/common/attmap.c:230 +#, c-format +msgid "" +"Attribute \"%s\" of type %s does not match corresponding attribute of type " +"%s." +msgstr "" +" \"%s\" 속성(대상 자료형 %s)이 %s 자료형의 속성 가운데 관련된 것이 없습니다" + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "\"%s\" 속성(대상 자료형 %s)이 %s 자료형에는 없습니다." + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "칼럼 개수(%d)가 최대값(%d)을 초과했습니다" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "인덱스 칼럼 개수(%d)가 최대값(%d)을 초과했습니다" + +#: access/common/indextuple.c:187 access/spgist/spgutils.c:703 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "인덱스 행(row)은 %zu 바이트를 필요로 함, 최대 크기는 %zu" + +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1904 +#, c-format +msgid "unsupported format code: %d" +msgstr "지원하지 않는 포맷 코드: %d" + +#: access/common/reloptions.c:506 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "유효한 값: \"on\", \"off\", \"auto\"" + +#: access/common/reloptions.c:517 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "사용할 수 있는 값은 \"local\" 또는 \"cascaded\" 입니다" + +#: access/common/reloptions.c:665 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "사용자 정의 관계 매개 변수 형식 제한을 초과함" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "매개 변수의 값으로 RESET은 올 수 없음" + +#: access/common/reloptions.c:1240 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "\"%s\" 매개 변수 네임스페이스를 인식할 수 없음" + +#: access/common/reloptions.c:1277 utils/misc/guc.c:12004 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "WITH OIDS 테이블을 지원하지 않음" + +#: access/common/reloptions.c:1447 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "알 수 없는 환경 설정 이름입니다 \"%s\"" + +#: access/common/reloptions.c:1559 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "\"%s\" 매개 변수가 여러 번 지정됨" + +#: access/common/reloptions.c:1575 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "\"%s\" 부울 옵션 값이 잘못됨: %s" + +#: access/common/reloptions.c:1587 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "\"%s\" 정수 옵션 값이 잘못됨: %s" + +#: access/common/reloptions.c:1593 access/common/reloptions.c:1613 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "값 %s은(는) \"%s\" 옵션 범위를 벗어남" + +#: access/common/reloptions.c:1595 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "유효한 값은 \"%d\"에서 \"%d\" 사이입니다." + +#: access/common/reloptions.c:1607 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "\"%s\" 부동 소수점 옵션 값이 잘못됨: %s" + +#: access/common/reloptions.c:1615 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "유효한 값은 \"%f\"에서 \"%f\" 사이입니다." + +#: access/common/reloptions.c:1637 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "\"%s\" enum 옵션 값이 잘못됨: %s" + +#: access/common/tupdesc.c:842 parser/parse_clause.c:772 +#: parser/parse_relation.c:1803 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "\"%s\" 칼럼은 SETOF를 지정할 수 없습니다" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "포스팅 목록이 너무 깁니다" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "maintenance_work_mem 설정값을 줄이세요." + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "GIN 팬딩 목록은 복구 작업 중에는 정리될 수 없습니다." + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\" 개체는 GIN 인덱스가 아닙니다" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "다른 세션의 임시 인덱스는 접근할 수 없음" + +#: access/gin/ginget.c:270 access/nbtree/nbtinsert.c:745 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "\"%s\" 인덱스에서 튜플 재검색 실패" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "" +"GIN 인덱스가 옛날 버전이어서 인덱스 전체 탐색, null 탐색 기능을 사용할 수 없" +"습니다." + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "이 문제를 고치려면, 다음 명령을 수행하세요: REINDEX INDEX \"%s\"" + +#: access/gin/ginutil.c:144 executor/execExpr.c:1862 +#: utils/adt/arrayfuncs.c:3790 utils/adt/arrayfuncs.c:6418 +#: utils/adt/rowtypes.c:936 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "%s 자료형에서 사용할 비교함수를 찾을 수 없습니다." + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains support function %s with " +"different left and right input types" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 서로 다른 양쪽 입력 자료형 인자를 사용" +"할 수 있는 %s 지원 함수가 포함되어 있음" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "" +"operator class \"%s\" of access method %s is missing support function %d or " +"%d" +msgstr "" +"\"%s\" 연산자 클래스(접근 방법: %s)에는 %d 또는 %d 지원 함수가 빠졌습니다" + +#: access/gist/gist.c:753 access/gist/gistvacuum.c:408 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "\"%s\" 인덱스에 잘못된 내부 튜플이 있다고 확인되었습니다." + +#: access/gist/gist.c:755 access/gist/gistvacuum.c:410 +#, c-format +msgid "" +"This is caused by an incomplete page split at crash recovery before " +"upgrading to PostgreSQL 9.1." +msgstr "" +"이 문제는 PostgreSQL 9.1 버전으로 업그레이드 하기 전에 장애 복구 처리에서 잘" +"못된 페이지 분리 때문에 발생했습니다." + +#: access/gist/gist.c:756 access/gist/gistutil.c:786 access/gist/gistutil.c:797 +#: access/gist/gistvacuum.c:411 access/hash/hashutil.c:227 +#: access/hash/hashutil.c:238 access/hash/hashutil.c:250 +#: access/hash/hashutil.c:271 access/nbtree/nbtpage.c:741 +#: access/nbtree/nbtpage.c:752 +#, c-format +msgid "Please REINDEX it." +msgstr "REINDEX 명령으로 다시 인덱스를 만드세요" + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "%d 칼럼(\"%s\" 인덱스)에 대한 picksplit 메서드 실패" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "" +"The index is not optimal. To optimize it, contact a developer, or try to use " +"the column as the second one in the CREATE INDEX command." +msgstr "" +"인덱스가 최적화되지 않았습니다. 최적화하려면 개발자에게 문의하거나, CREATE " +"INDEX 명령에서 해당 칼럼을 두 번째 인덱스로 사용하십시오." + +#: access/gist/gistutil.c:783 access/hash/hashutil.c:224 +#: access/nbtree/nbtpage.c:738 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "\"%s\" 인덱스의 %u번째 블럭에서 예상치 않은 zero page가 있습니다" + +#: access/gist/gistutil.c:794 access/hash/hashutil.c:235 +#: access/hash/hashutil.c:247 access/nbtree/nbtpage.c:749 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "\"%s\" 인덱스트 %u번째 블럭이 속상되었습니다" + +#: access/gist/gistvalidate.c:199 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains unsupported ORDER BY " +"specification for operator %s" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 %s 연산자가 지원하지 않는 ORDER BY 명세" +"를 사용합니다." + +#: access/gist/gistvalidate.c:210 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains incorrect ORDER BY " +"opfamily specification for operator %s" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 %s 연산자가 잘못된 ORDER BY 명세를 사용" +"합니다." + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "문자열 해시 작업에 사용할 정렬규칙(collation)을 결정할 수 없음" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:702 +#: catalog/heap.c:708 commands/createas.c:206 commands/createas.c:489 +#: commands/indexcmds.c:1814 commands/tablecmds.c:16035 commands/view.c:86 +#: parser/parse_utilcmd.c:4203 regex/regc_pg_locale.c:263 +#: utils/adt/formatting.c:1667 utils/adt/formatting.c:1791 +#: utils/adt/formatting.c:1916 utils/adt/like.c:194 +#: utils/adt/like_support.c:1003 utils/adt/varchar.c:733 +#: utils/adt/varchar.c:994 utils/adt/varchar.c:1054 utils/adt/varlena.c:1476 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "명시적으로 정렬 규칙을 지정하려면 COLLATE 절을 사용하세요." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "인덱스 행 크기가 초과됨: 현재값 %zu, 최대값 %zu" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:764 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "버퍼 페이지보다 큰 값은 인덱싱할 수 없습니다." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "잘못된 오버플로우 블록 번호: %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "\"%s\" 해시 인덱스에서 오버플로우 페이지 초과" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "해시 인덱스는 whole-index scan을 지원하지 않음" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "\"%s\" 인덱스는 해시 인덱스가 아님" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "\"%s\" 인덱스는 잘못된 해시 버전임" + +#: access/hash/hashvalidate.c:195 +#, c-format +msgid "" +"operator family \"%s\" of access method %s lacks support function for " +"operator %s" +msgstr "\"%s\" 연산자 패밀리(접근 방법: %s)에 %s 연산자용 지원 함수가 없음" + +#: access/hash/hashvalidate.c:253 access/nbtree/nbtvalidate.c:273 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "%s 연산자 패밀리(접근 방법: %s)에 cross-type 연산자가 빠졌음" + +#: access/heap/heapam.c:2024 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "병렬 작업자는 튜플을 추가 할 수 없음" + +#: access/heap/heapam.c:2442 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "병렬 작업 중에는 튜플을 지울 수 없음" + +#: access/heap/heapam.c:2488 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "볼 수 없는 튜플을 삭제 하려고 함" + +#: access/heap/heapam.c:2914 access/heap/heapam.c:5703 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "병렬 작업 중에 튜플 갱신은 할 수 없음" + +#: access/heap/heapam.c:3047 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "볼 수 없는 튜플을 변경하려고 함" + +#: access/heap/heapam.c:4358 access/heap/heapam.c:4396 +#: access/heap/heapam.c:4653 access/heap/heapam_handler.c:450 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "\"%s\" 릴레이션의 잠금 정보를 구할 수 없음" + +#: access/heap/heapam_handler.c:399 +#, c-format +msgid "" +"tuple to be locked was already moved to another partition due to concurrent " +"update" +msgstr "잠글 튜플은 동시 업데이트로 다른 파티션으로 이미 옮겨졌음" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:662 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "로우가 너무 큽니다: 크기 %zu, 최대값 %zu" + +#: access/heap/rewriteheap.c:921 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "\"%s\" 파일 쓰기 실패, %d / %d 기록함: %m." + +#: access/heap/rewriteheap.c:1015 access/heap/rewriteheap.c:1134 +#: access/transam/timeline.c:329 access/transam/timeline.c:485 +#: access/transam/xlog.c:3300 access/transam/xlog.c:3472 +#: access/transam/xlog.c:4670 access/transam/xlog.c:10869 +#: access/transam/xlog.c:10907 access/transam/xlog.c:11312 +#: access/transam/xlogfuncs.c:735 postmaster/postmaster.c:4629 +#: replication/logical/origin.c:575 replication/slot.c:1446 +#: storage/file/copydir.c:167 storage/smgr/md.c:218 utils/time/snapmgr.c:1329 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "\"%s\" 파일을 만들 수 없음: %m" + +#: access/heap/rewriteheap.c:1144 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "\"%s\" 파일을 %u 크기로 정리할 수 없음: %m" + +#: access/heap/rewriteheap.c:1162 access/transam/timeline.c:384 +#: access/transam/timeline.c:424 access/transam/timeline.c:502 +#: access/transam/xlog.c:3356 access/transam/xlog.c:3528 +#: access/transam/xlog.c:4682 postmaster/postmaster.c:4639 +#: postmaster/postmaster.c:4649 replication/logical/origin.c:587 +#: replication/logical/origin.c:629 replication/logical/origin.c:648 +#: replication/logical/snapbuild.c:1622 replication/slot.c:1481 +#: storage/file/buffile.c:502 storage/file/copydir.c:207 +#: utils/init/miscinit.c:1391 utils/init/miscinit.c:1402 +#: utils/init/miscinit.c:1410 utils/misc/guc.c:7996 utils/misc/guc.c:8027 +#: utils/misc/guc.c:9947 utils/misc/guc.c:9961 utils/time/snapmgr.c:1334 +#: utils/time/snapmgr.c:1341 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "\"%s\" 파일 쓰기 실패: %m" + +#: access/heap/rewriteheap.c:1252 access/transam/twophase.c:1609 +#: access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:421 +#: postmaster/postmaster.c:1092 postmaster/syslogger.c:1465 +#: replication/logical/origin.c:563 replication/logical/reorderbuffer.c:3079 +#: replication/logical/snapbuild.c:1564 replication/logical/snapbuild.c:2006 +#: replication/slot.c:1578 storage/file/fd.c:754 storage/file/fd.c:3116 +#: storage/file/fd.c:3178 storage/file/reinit.c:255 storage/ipc/dsm.c:302 +#: storage/smgr/md.c:311 storage/smgr/md.c:367 storage/sync/sync.c:210 +#: utils/time/snapmgr.c:1674 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "\"%s\" 파일을 삭제할 수 없음: %m" + +#: access/heap/vacuumlazy.c:648 +#, c-format +msgid "" +"automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": " +"index scans: %d\n" +msgstr "" +"트랙젝션 ID 겹침 방지를 위한 적극적인 \"%s.%s.%s\" 테이블 자동 청소: 인덱스 " +"탐색: %d\n" + +#: access/heap/vacuumlazy.c:650 +#, c-format +msgid "" +"automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: " +"%d\n" +msgstr "" +"트랙젝션 ID 겹침 방지를 위한 \"%s.%s.%s\" 테이블 자동 청소: 인덱스 " +"탐색: %d\n" + +#: access/heap/vacuumlazy.c:655 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "적극적인 \"%s.%s.%s\" 테이블 자동 청소: 인덱스 탐색: %d\n" + +#: access/heap/vacuumlazy.c:657 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "\"%s.%s.%s\" 테이블 자동 청소: 인덱스 탐색: %d\n" + +#: access/heap/vacuumlazy.c:664 +#, c-format +msgid "" +"pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "페이지: %u 삭제됨, %u 남음, %u 핀닝으로 건너뜀, %u 동결되어 건너뜀\n" + +#: access/heap/vacuumlazy.c:670 +#, c-format +msgid "" +"tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, " +"oldest xmin: %u\n" +msgstr "" +"튜플: %.0f 삭제됨, %.0f 남음, %.0f 삭제할 수 없는 죽은 튜플, 제일 늙은 xmin: " +"%u\n" + +#: access/heap/vacuumlazy.c:676 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "버퍼 사용량: %lld 조회, %lld 놓침, %lld 변경됨\n" + +#: access/heap/vacuumlazy.c:680 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "평균 읽기 속도: %.3f MB/s, 평균 쓰기 속도: %.3f MB/s\n" + +#: access/heap/vacuumlazy.c:682 +#, c-format +msgid "system usage: %s\n" +msgstr "시스템 사용량: %s\n" + +#: access/heap/vacuumlazy.c:684 +#, c-format +msgid "WAL usage: %ld records, %ld full page images, %llu bytes" +msgstr "WAL 사용량: %ld 레코드, %ld 페이지 전체 이미지, %llu 바이트" + +#: access/heap/vacuumlazy.c:795 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "적극적으로 \"%s.%s\" 청소 중" + +#: access/heap/vacuumlazy.c:800 commands/cluster.c:874 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "\"%s.%s\" 청소 중" + +#: access/heap/vacuumlazy.c:837 +#, c-format +msgid "" +"disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary " +"tables in parallel" +msgstr "" +"\"%s\" 청소 작업에서의 병렬 옵션은 무시함 --- 임시 테이블은 병렬 처리로 " +"청소 할 수 없음" + +#: access/heap/vacuumlazy.c:1725 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%s\": %.0f개의 행 버전을 %u개 페이지에서 삭제했습니다." + +#: access/heap/vacuumlazy.c:1735 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f개의 죽은 로우 버전을 아직 지울 수 없습니다, 제일 늙은 xmin: %u\n" + +#: access/heap/vacuumlazy.c:1737 +#, c-format +msgid "There were %.0f unused item identifiers.\n" +msgstr "%.0f개의 사용되지 않은 아이템 식별자들이 있습니다.\n" + +#: access/heap/vacuumlazy.c:1739 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "%u 페이지를 버퍼 핀닝으로 건너 뛰었습니다, " + +#: access/heap/vacuumlazy.c:1743 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "" + +#: access/heap/vacuumlazy.c:1747 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "" + +#: access/heap/vacuumlazy.c:1751 commands/indexcmds.c:3487 +#: commands/indexcmds.c:3505 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1754 +#, c-format +msgid "" +"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u " +"pages" +msgstr "" +"\"%s\": 지울 수 있는 자료 %.0f개, 지울 수 없는 자료 %.0f개를 %u/%u개 페이지에" +"서 찾았음" + +#: access/heap/vacuumlazy.c:1888 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%s\": %d 개 자료를 %d 페이지에서 삭제했음" + +#: access/heap/vacuumlazy.c:2143 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "" +"launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "" + +#: access/heap/vacuumlazy.c:2149 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "" +"launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "" + +#: access/heap/vacuumlazy.c:2441 +#, c-format +msgid "" +"scanned index \"%s\" to remove %d row versions by parallel vacuum worker" +msgstr "" +"\"%s\" 인덱스를 스캔해서 %d개의 행 버전들을 병렬 vacuum 작업자가 지웠습니다" + +#: access/heap/vacuumlazy.c:2443 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "\"%s\" 인덱스를 스캔해서 %d개의 행 버전들을 지웠습니다" + +#: access/heap/vacuumlazy.c:2501 +#, c-format +msgid "" +"index \"%s\" now contains %.0f row versions in %u pages as reported by " +"parallel vacuum worker" +msgstr "" +"\"%s\" 인덱스는 %.0f 행 버전을 %u 페이지에서 포함있음을 " +"병렬 vacuum 작업자가 보고함" + +#: access/heap/vacuumlazy.c:2503 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "\"%s\" 인덱스는 %.0f 행 버전을 %u 페이지에서 포함하고 있습니다." + +#: access/heap/vacuumlazy.c:2510 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f개의 인덱스 행 버전을 삭제했습니다.\n" +"%u개 인덱스 페이지를 삭제해서, %u개 페이지를 다시 사용합니다.\n" +"%s." + +#: access/heap/vacuumlazy.c:2613 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\": 잠금 요청 충돌로 자료 비우기 작업을 중지합니다" + +#: access/heap/vacuumlazy.c:2679 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": %u 에서 %u 페이지로 정지했음" + +#: access/heap/vacuumlazy.c:2744 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\": 잠금 요청 충돌로 자료 비우기 작업을 지연합니다" + +#: access/heap/vacuumlazy.c:3583 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "%u 블록(해당 릴레이션: \"%s.%s\")을 탐색 중" + +#: access/heap/vacuumlazy.c:3586 +#, c-format +msgid "while scanning relation \"%s.%s\"" +msgstr "\"%s.%s\" 릴레이션을 탐색 중" + +#: access/heap/vacuumlazy.c:3592 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "%u 블록(해당 릴레이션: \"%s.%s\")을 청소 중" + +#: access/heap/vacuumlazy.c:3595 +#, c-format +msgid "while vacuuming relation \"%s.%s\"" +msgstr "\"%s.%s\" 릴레이션 청소 중" + +#: access/heap/vacuumlazy.c:3600 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "\"%s\" 인덱스(해당 릴레이션 \"%s.%s\") 청소 중" + +#: access/heap/vacuumlazy.c:3605 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "\"%s\" 인덱스 (해당 릴레이션 \"%s.%s\")을 정돈(clean up) 중" + +#: access/heap/vacuumlazy.c:3611 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "\"%s.%s\" 릴레이션을 %u 블럭으로 줄이는 중" + +#: access/index/amapi.c:83 commands/amcmds.c:170 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "\"%s\" 접근 방법은 %s 자료형에는 쓸 수 없음" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "\"%s\" 인덱스 접근 방법에 대한 핸들러가 없음" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1260 +#: commands/indexcmds.c:2516 commands/tablecmds.c:254 commands/tablecmds.c:278 +#: commands/tablecmds.c:15733 commands/tablecmds.c:17188 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\" 개체는 인덱스가 아닙니다" + +#: access/index/indexam.c:970 +#, c-format +msgid "operator class %s has no options" +msgstr "%s 연산자 클래스는 옵션이 없습니다" + +#: access/nbtree/nbtinsert.c:651 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "중복된 키 값이 \"%s\" 고유 제약 조건을 위반함" + +#: access/nbtree/nbtinsert.c:653 +#, c-format +msgid "Key %s already exists." +msgstr "%s 키가 이미 있습니다." + +#: access/nbtree/nbtinsert.c:747 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "이 문제는 non-immutable 인덱스 표현식 때문인듯 합니다." + +#: access/nbtree/nbtpage.c:150 access/nbtree/nbtpage.c:538 +#: parser/parse_utilcmd.c:2244 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "\"%s\" 인덱스는 btree 인덱스가 아닙니다" + +#: access/nbtree/nbtpage.c:157 access/nbtree/nbtpage.c:545 +#, c-format +msgid "" +"version mismatch in index \"%s\": file version %d, current version %d, " +"minimal supported version %d" +msgstr "" +"\"%s\" 인덱스의 버전이 틀립니다: 파일 버전 %d, 현재 버전 %d, 최소 지원 버전 " +"%d" + +#: access/nbtree/nbtpage.c:1501 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "\"%s\" 인덱스에 반쯤 죽은(half-dead) 내부 페이지가 있음" + +#: access/nbtree/nbtpage.c:1503 +#, c-format +msgid "" +"This can be caused by an interrupted VACUUM in version 9.3 or older, before " +"upgrade. Please REINDEX it." +msgstr "" +"이 문제는 9.3 버전 이하 환경에서 VACUUM 작업이 중지되고, 그 상태로 업그레이드" +"되었을 가능성이 큽니다. 해당 인덱스를 다시 만드십시오." + +#: access/nbtree/nbtutils.c:2664 +#, c-format +msgid "" +"index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "" +"인덱스 행 크기(%zu)가 btree(%u 버전)의 최대값(%zu)을 초과함 (해당 인덱스: " +"\"%s\")" + +#: access/nbtree/nbtutils.c:2670 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "인덱스 로우가 %u,%u 튜플(해당 릴레이션 \"%s\")을 참조함." + +#: access/nbtree/nbtutils.c:2674 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text " +"indexing." +msgstr "" +"버퍼 페이지의 1/3보다 큰 값은 인덱싱할 수 없습니다.\n" +"값의 MD5 해시 함수 인덱스를 고려하거나 전체 텍스트 인덱싱을 사용하십시오." + +#: access/nbtree/nbtvalidate.c:243 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing support function for " +"types %s and %s" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에는 %s 자료형과 %s 자료형용 지원 함수가 " +"빠졌음" + +#: access/spgist/spgutils.c:147 +#, c-format +msgid "" +"compress method must be defined when leaf type is different from input type" +msgstr "입력 자료형에서 리프 유형이 다를 때 압축 방법은 반드시 정의해야 함" + +#: access/spgist/spgutils.c:761 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "SP-GiST 내부 튜플 크기가 초과됨: 현재값 %zu, 최대값 %zu" + +#: access/spgist/spgvalidate.c:281 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing support function %d " +"for type %s" +msgstr "" +"\"%s\" 연산자 패밀리(접근 방법: %s)에 %d 지원 함수가 %s 자료형용으로 없습니" +"다." + +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 +#: catalog/aclchk.c:1806 +#, c-format +msgid "\"%s\" is an index" +msgstr "\"%s\" 개체는 인덱스임" + +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 +#: catalog/aclchk.c:1813 commands/tablecmds.c:12554 commands/tablecmds.c:15742 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "\"%s\" 개체는 복합 자료형입니다" + +#: access/table/tableam.c:244 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "tid (%u, %u)가 바르지 않음, 해당 릴레이션: \"%s\"" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "%s 값은 비워 둘 수 없음" + +#: access/table/tableamapi.c:122 utils/misc/guc.c:11928 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s 설정값이 너무 깁니다 (최대 %d 문자)" + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "\"%s\" 테이블 접근 방법이 없습니다" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "\"%s\" 테이블 접근 방법이 없습니다." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "샘플 퍼센트 값은 0에서 100 사이여야 함" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "%u 트랜잭션의 커밋 타임스탬프를 알 수 없음" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "커밋 타임스탬프 자료를 찾을 수 없음" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "" +"Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "운영 서버에서 \"%s\" 환경 설정 매개 변수값을 지정 하세요." + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "\"%s\" 환경 설정 매개 변수를 지정하세요." + +#: access/transam/multixact.c:1002 +#, c-format +msgid "" +"database is not accepting commands that generate new MultiXactIds to avoid " +"wraparound data loss in database \"%s\"" +msgstr "" +"\"%s\" 데이터베이스 자료 손실을 막기 위해 새로운 MultiXactId 만드는 작업을 " +"더 이상 할 수 없습니다." + +#: access/transam/multixact.c:1004 access/transam/multixact.c:1011 +#: access/transam/multixact.c:1035 access/transam/multixact.c:1044 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"해당 데이터베이스 단위로 VACUUM 작업을 진행하십시오.\n" +"또한 오래된 트랜잭션을 커밋또는 롤백하거나 잠긴 복제 슬롯을 지울 필요가 있습" +"니다." + +#: access/transam/multixact.c:1009 +#, c-format +msgid "" +"database is not accepting commands that generate new MultiXactIds to avoid " +"wraparound data loss in database with OID %u" +msgstr "" +"%u OID 데이터베이스 자료 손실을 막기 위해 새로운 MultiXactId 만드는 작업을 " +"더 이상 할 수 없습니다." + +#: access/transam/multixact.c:1030 access/transam/multixact.c:2320 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "" +"database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "" +"\"%s\" 데이터베이스는 %u번의 트랜잭션이 발생되기 전에 VACUUM 작업을 해야 합니" +"다." + +#: access/transam/multixact.c:1039 access/transam/multixact.c:2329 +#, c-format +msgid "" +"database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "" +"database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "" +"%u OID 데이터베이스는 %u번의 트랜잭션이 발생되기 전에 VACUUM 작업을 해야 합니" +"다." + +#: access/transam/multixact.c:1100 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "multixact \"회수\" 초과" + +#: access/transam/multixact.c:1101 +#, c-format +msgid "" +"This command would create a multixact with %u members, but the remaining " +"space is only enough for %u member." +msgid_plural "" +"This command would create a multixact with %u members, but the remaining " +"space is only enough for %u members." +msgstr[0] "" +"이 명령은 %u 개의 multixact를 써야하는데, 쓸 수 있는 공간은 %u 개 뿐입니다." + +#: access/transam/multixact.c:1106 +#, c-format +msgid "" +"Execute a database-wide VACUUM in database with OID %u with reduced " +"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " +"settings." +msgstr "" +"vacuum_multixact_freeze_min_age, vacuum_multixact_freeze_table_age 값을 조정" +"하고, %u OID 데이터베이스 대상으로 VACUUM 작업을 하십시오." + +#: access/transam/multixact.c:1137 +#, c-format +msgid "" +"database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "" +"database with OID %u must be vacuumed before %d more multixact members are " +"used" +msgstr[0] "" +"%u OID 데이터베이스는 %d 개의 멀티트랜잭션을 사용하기 전에 vacuum 작업을 해" +"야 합니다." + +#: access/transam/multixact.c:1142 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database with reduced " +"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " +"settings." +msgstr "" +"vacuum_multixact_freeze_min_age 설정값과 vacuum_multixact_freeze_table_age 값" +"을 줄여서 데이터베이스 단위로 VACUUM 작업을 진행하세요." + +#: access/transam/multixact.c:1279 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "%u번 MultiXactId 더이상 없음 -- 번호 겹침 현상 발생" + +#: access/transam/multixact.c:1287 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "%u번 MultiXactId를 만들 수 없음 -- 번호 겹침 현상 발생" + +#: access/transam/multixact.c:2270 +#, c-format +msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +msgstr "MultiXactId 겹침 한계는 %u 입니다. %u OID 데이터베이스에서 제한됨" + +#: access/transam/multixact.c:2325 access/transam/multixact.c:2334 +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/varsup.c:447 access/transam/varsup.c:454 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that " +"database.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"데이터베이스가 종료되지 않도록 하려면 데이터베이스 수준의 VACUUM을 실행하십시" +"오.\n" +"또한 오래된 트랜잭션을 커밋또는 롤백 하거나, 잠긴 복제 슬롯을 지울 필요가 있" +"습니다." + +#: access/transam/multixact.c:2604 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "제일 오래된 MultiXactId 값은 %u 위치에 있음" + +#: access/transam/multixact.c:2608 +#, c-format +msgid "" +"MultiXact member wraparound protections are disabled because oldest " +"checkpointed MultiXact %u does not exist on disk" +msgstr "" +"가장 오래된 체크포인트 작업이 완료된 %u 멀티 트랜잭션 번호가 디스크에 없기 때" +"문에, 멀티 트랜잭션 번호 겹침 방지 기능이 비활성화 되어 있습니다." + +#: access/transam/multixact.c:2630 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "멀티 트랜잭션 번호 겹침 방지 기능이 활성화 되었음" + +#: access/transam/multixact.c:2633 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "멀티 트랜잭션 중지 제한 번호는 %u 입니다. (%u 멀티트랜잭션에 기초함)" + +#: access/transam/multixact.c:3013 +#, c-format +msgid "" +"oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "" +"가장 오래된 멀티 트랜잭션 번호는 %u, 가장 최신 것은 %u, truncate 작업 건너뜀" + +#: access/transam/multixact.c:3031 +#, c-format +msgid "" +"cannot truncate up to MultiXact %u because it does not exist on disk, " +"skipping truncation" +msgstr "" +"디스크에 해당 멀티 트랜잭션 번호가 없어, %u 멀티 트랜잭션 번호로 truncate 못" +"함, truncate 작업 건너뜀" + +#: access/transam/multixact.c:3345 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "잘못된 MultiXactId: %u" + +#: access/transam/parallel.c:706 access/transam/parallel.c:825 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "병렬 작업자 초기화 실패" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "More details may be available in the server log." +msgstr "보다 자세한 내용은 서버 로그에 남겨졌을 수 있습니다." + +#: access/transam/parallel.c:887 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "병렬 트랜잭션 처리 중 postmaster 종료됨" + +#: access/transam/parallel.c:1074 +#, c-format +msgid "lost connection to parallel worker" +msgstr "병렬 처리 작업자 프로세스 연결 끊김" + +#: access/transam/parallel.c:1140 access/transam/parallel.c:1142 +msgid "parallel worker" +msgstr "병렬 처리 작업자" + +#: access/transam/parallel.c:1293 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "동적 공유 메모리 세그먼트를 할당할 수 없음" + +#: access/transam/parallel.c:1298 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "동적 공유 메모리 세그먼트에 잘못된 매직 번호가 있음" + +#: access/transam/slru.c:696 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "\"%s\" 파일 없음, 0으로 읽음" + +#: access/transam/slru.c:937 access/transam/slru.c:943 +#: access/transam/slru.c:951 access/transam/slru.c:956 +#: access/transam/slru.c:963 access/transam/slru.c:968 +#: access/transam/slru.c:975 access/transam/slru.c:982 +#, c-format +msgid "could not access status of transaction %u" +msgstr "%u 트랜잭션의 상태를 액세스할 수 없음" + +#: access/transam/slru.c:938 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "\"%s\" 파일을 열 수 없음: %m." + +#: access/transam/slru.c:944 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "\"%s\" 파일에서 %u 위치를 찾을 수 없음: %m." + +#: access/transam/slru.c:952 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "\"%s\" 파일에서 %u 위치를 읽을 수 없음: %m." + +#: access/transam/slru.c:957 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "\"%s\" 파일에서 %u 위치를 읽을 수 없음: 너무 적은 바이트를 읽음." + +#: access/transam/slru.c:964 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "\"%s\" 파일에서 %u 위치에 쓸 수 없음: %m." + +#: access/transam/slru.c:969 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "\"%s\" 파일에서 %u 위치에 쓸 수 없음: 너무 적은 바이트를 씀." + +#: access/transam/slru.c:976 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "\"%s\" 파일 fsync 실패: %m." + +#: access/transam/slru.c:983 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "\"%s\" 파일을 닫을 수 없음: %m." + +#: access/transam/slru.c:1258 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "\"%s\" 디렉터리를 비울 수 없음: 랩어라운드 발생" + +#: access/transam/slru.c:1313 access/transam/slru.c:1369 +#, c-format +msgid "removing file \"%s\"" +msgstr "\"%s\" 파일 삭제 중" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "히스토리 파일에서 문법오류: %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "숫자 타임라인 ID가 필요합니다." + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "트랜잭션 로그 전환 위치 값이 있어야 함" + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "작업내역 파일에 잘못된 자료가 있음: %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "타임라인 ID 값은 그 값이 증가하는 순번값이어야합니다." + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "작업내역 파일에 잘못된 자료가 있음: \"%s\"" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "타임라인 ID는 하위 타임라인 ID보다 작아야 합니다." + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "요청한 %u 타이라인이 이 서버 내역에는 없음" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "\"%s\" 트랜잭션 식별자가 너무 깁니다" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "준비된 트랜잭션이 비활성화됨" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "max_prepared_transactions 설정값을 0이 아닌 값으로 설정하십시오." + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "\"%s\" 이름의 트랜잭션 식별자가 이미 사용 중입니다" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2368 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "준비된 트랜잭션의 최대 개수를 모두 사용했습니다" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2369 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "max_prepared_transactions 값을 늘려주세요 (현재 %d)." + +#: access/transam/twophase.c:586 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "\"%s\" 이름의 준비된 트랜잭션 식별자가 여러 곳에서 쓰이고 있습니다" + +#: access/transam/twophase.c:592 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "준비된 트랜잭션 끝내기 작업 권한 없음" + +#: access/transam/twophase.c:593 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "해당 준비된 트랜잭션의 소유주이거나 superuser여야합니다" + +#: access/transam/twophase.c:604 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "준비된 트랜잭션이 다른 데이터베이스에 속해 있음" + +#: access/transam/twophase.c:605 +#, c-format +msgid "" +"Connect to the database where the transaction was prepared to finish it." +msgstr "작업을 마치려면 그 준비된 트랜잭션이 있는 데이터베이스에 연결하십시오." + +#: access/transam/twophase.c:620 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "\"%s\" 이름의 준비된 트랜잭션이 없습니다" + +#: access/transam/twophase.c:1098 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "2단계 상태 파일 최대 길이를 초과함" + +#: access/transam/twophase.c:1252 +#, c-format +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "\"%s\" 파일 크기가 이상함: %zu 바이트" + +#: access/transam/twophase.c:1261 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "\"%s\" 파일의 CRC 값 맞춤 실패" + +#: access/transam/twophase.c:1294 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "\"%s\" 파일에 잘못된 매직 번호가 저장되어 있음" + +#: access/transam/twophase.c:1300 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "\"%s\" 파일 크기가 이상함" + +#: access/transam/twophase.c:1312 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "계산된 CRC 체크섬 값이 파일에 \"%s\" 파일에 저장된 값과 다름" + +#: access/transam/twophase.c:1342 access/transam/xlog.c:6494 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "WAL 읽기 프로세서를 할당하는 중에 오류 발생" + +#: access/transam/twophase.c:1349 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "two-phase 상태정보을 읽을 수 없음 WAL 위치: %X/%X" + +#: access/transam/twophase.c:1357 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "WAL %X/%X 위치에 2단계 커밋 상태 자료가 없습니다" + +#: access/transam/twophase.c:1637 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "\"%s\" 파일을 다시 만들 수 없음: %m" + +#: access/transam/twophase.c:1764 +#, c-format +msgid "" +"%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "" +"%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "" +"긴 실행 미리 준비된 트랜잭션 용 %u 개의 2단계 상태 파일이 저장되었음" + +#: access/transam/twophase.c:1998 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "공유 메모리에서 %u 준비된 트랜잭션을 복구함" + +#: access/transam/twophase.c:2089 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "%u 트랜잭션에서 사용하는 오래된 two-phase 상태정보 파일을 삭제함" + +#: access/transam/twophase.c:2096 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "" +"%u 트랜잭션에서 사용하는 오래된 two-phase 상태정보를 공유 메모리에서 삭제함" + +#: access/transam/twophase.c:2109 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "%u 트랜잭션에서 사용하는 future two-phase 상태정보 파일을 삭제함" + +#: access/transam/twophase.c:2116 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "%u 트랜잭션에서 사용하는 future two-phase 상태정보를 메모리에서 삭제함" + +#: access/transam/twophase.c:2141 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "%u 트랜잭션에서 사용하는 two-phase 상태정보 파일이 손상되었음" + +#: access/transam/twophase.c:2146 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "%u 트랜잭션에서 사용하는 메모리에 있는 two-phase 상태정보가 손상되었음" + +#: access/transam/varsup.c:127 +#, c-format +msgid "" +"database is not accepting commands to avoid wraparound data loss in database " +"\"%s\"" +msgstr "" +"\"%s\" 데이터베이스 트랜잭션 ID 겹침에 의한 자료 손실을 방지하기 위해 더 이" +"상 자료 조작 작업을 허용하지 않습니다" + +#: access/transam/varsup.c:129 access/transam/varsup.c:136 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"postmaster를 중지하고 단일 사용자 모드로 서버를 실행한 뒤 VACUUM 작업을 하십" +"시오.\n" +"또한 오래된 트랜잭션을 커밋 또는 롤백하거나, 잠긴 복제 슬롯을 지울 필요가 있" +"습니다." + +#: access/transam/varsup.c:134 +#, c-format +msgid "" +"database is not accepting commands to avoid wraparound data loss in database " +"with OID %u" +msgstr "" +"%u OID 데이터베이스에서 자료 겹침으로 발생할 수 있는 자료 손실을 방지하기 위" +"해 명령을 수락하지 않음" + +#: access/transam/varsup.c:146 access/transam/varsup.c:444 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "\"%s\" 데이터베이스는 %u번의 트랜잭션이 발생되기 전에 청소해야 합니다" + +#: access/transam/varsup.c:153 access/transam/varsup.c:451 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "%u OID 데이터베이스는 %u번의 트랜잭션이 발생되기 전에 청소해야 합니다" + +#: access/transam/varsup.c:409 +#, c-format +msgid "transaction ID wrap limit is %u, limited by database with OID %u" +msgstr "트랜잭션 ID 겹침 제한은 %u번 입니다., %u OID 데이터베이스에서 제한됨" + +#: access/transam/xact.c:1030 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "하나의 트랜잭션 안에서는 2^32-2 개의 명령을 초과할 수 없음" + +#: access/transam/xact.c:1555 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "커밋된 하위 트랜잭션 수(%d)가 최대치를 초과함" + +#: access/transam/xact.c:2395 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "임시 개체 대해 실행된 트랜잭션을 PREPARE할 수 없음" + +#: access/transam/xact.c:2405 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "스냅샷으로 내보낸 트랜잭션은 PREPARE 작업을 할 수 없음" + +#: access/transam/xact.c:2414 +#, c-format +msgid "" +"cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "논리 복제 작업자를 사용하는 트랜잭션은 PREPARE 할 수 없음" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3359 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s 명령은 트랜잭션 블럭안에서 실행할 수 없음" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3369 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s 명령은 서브트랜잭션 블럭안에서 실행할 수 없음" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3379 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s 절은 함수에서 실행될 수 없음" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3448 access/transam/xact.c:3754 +#: access/transam/xact.c:3833 access/transam/xact.c:3956 +#: access/transam/xact.c:4107 access/transam/xact.c:4176 +#: access/transam/xact.c:4287 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s 명령은 트랜잭션 블럭에서만 사용될 수 있음" + +#: access/transam/xact.c:3640 +#, c-format +msgid "there is already a transaction in progress" +msgstr "이미 트랜잭션 작업이 진행 중입니다" + +#: access/transam/xact.c:3759 access/transam/xact.c:3838 +#: access/transam/xact.c:3961 +#, c-format +msgid "there is no transaction in progress" +msgstr "현재 트랜잭션 작업을 하지 않고 있습니다" + +#: access/transam/xact.c:3849 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "데이터베이스 트랜잭션을 commit 할 수 없음" + +#: access/transam/xact.c:3972 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "병렬 작업 중에는 중지 할 수 없음" + +#: access/transam/xact.c:4071 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "병렬 작업 중에는 savepoint 지정을 할 수 없음" + +#: access/transam/xact.c:4158 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "병렬 작업 중에는 savepoint를 지울 수 없음" + +#: access/transam/xact.c:4168 access/transam/xact.c:4219 +#: access/transam/xact.c:4279 access/transam/xact.c:4328 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "\"%s\" 이름의 저장위치가 없음" + +#: access/transam/xact.c:4225 access/transam/xact.c:4334 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "현재 저장위치 수준에서 \"%s\" 이름의 저장위치가 없음" + +#: access/transam/xact.c:4267 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "병렬 작업 중에는 savepoint 지정 취소 작업을 할 수 없음" + +#: access/transam/xact.c:4395 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "병렬 처리 중에는 하위트랜잭션을 시작할 수 없음" + +#: access/transam/xact.c:4463 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "병렬 처리 중에는 하위트랜잭션을 커밋할 수 없음" + +#: access/transam/xact.c:5103 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "하나의 트랜잭션 안에서는 2^32-1 개의 하위트랜잭션을 초과할 수 없음" + +#: access/transam/xlog.c:2554 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "%s 로그 파일 쓰기 실패, 위치 %u, 길이 %zu: %m" + +#: access/transam/xlog.c:2830 +#, c-format +msgid "updated min recovery point to %X/%X on timeline %u" +msgstr "최소 복구 지점: %X/%X, 타임라인: %u 변경 완료" + +#: access/transam/xlog.c:3944 access/transam/xlogutils.c:802 +#: replication/walsender.c:2510 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "요청한 %s WAL 조각 파일은 이미 지워졌음" + +#: access/transam/xlog.c:4187 +#, c-format +msgid "recycled write-ahead log file \"%s\"" +msgstr "\"%s\" 트랜잭션 로그 파일 재활용함" + +#: access/transam/xlog.c:4199 +#, c-format +msgid "removing write-ahead log file \"%s\"" +msgstr "\"%s\" 트랜잭션 로그 파일 삭제 중" + +#: access/transam/xlog.c:4219 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "\"%s\" 파일의 이름을 바꿀 수 없음: %m" + +#: access/transam/xlog.c:4261 access/transam/xlog.c:4271 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "필요한 WAL 디렉터리 \"%s\"이(가) 없음" + +#: access/transam/xlog.c:4277 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "누락된 WAL 디렉터리 \"%s\"을(를) 만드는 중" + +#: access/transam/xlog.c:4280 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "누락된 \"%s\" 디렉터리를 만들 수 없음: %m" + +#: access/transam/xlog.c:4383 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "예상치 못한 타임라인 ID %u, 로그 조각: %s, 위치: %u" + +#: access/transam/xlog.c:4521 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "요청한 %u 타임라인은 %u 데이터베이스 시스템 타임라인의 하위가 아님" + +#: access/transam/xlog.c:4535 +#, c-format +msgid "" +"new timeline %u forked off current database system timeline %u before " +"current recovery point %X/%X" +msgstr "" + +#: access/transam/xlog.c:4554 +#, c-format +msgid "new target timeline is %u" +msgstr "새 대상 타임라인: %u" + +#: access/transam/xlog.c:4590 +#, c-format +msgid "could not generate secret authorization token" +msgstr "비밀 인증 토큰을 만들 수 없음" + +#: access/transam/xlog.c:4749 access/transam/xlog.c:4758 +#: access/transam/xlog.c:4782 access/transam/xlog.c:4789 +#: access/transam/xlog.c:4796 access/transam/xlog.c:4801 +#: access/transam/xlog.c:4808 access/transam/xlog.c:4815 +#: access/transam/xlog.c:4822 access/transam/xlog.c:4829 +#: access/transam/xlog.c:4836 access/transam/xlog.c:4843 +#: access/transam/xlog.c:4852 access/transam/xlog.c:4859 +#: utils/init/miscinit.c:1548 +#, c-format +msgid "database files are incompatible with server" +msgstr "데이터베이스 파일들이 서버와 호환성이 없습니다" + +#: access/transam/xlog.c:4750 +#, c-format +msgid "" +"The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), " +"but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "" +"데이터베이스 클러스터는 PG_CONTROL_VERSION %d (0x%08x)(으)로 초기화되었지만 " +"서버는 PG_CONTROL_VERSION %d (0x%08x)(으)로 컴파일되었습니다." + +#: access/transam/xlog.c:4754 +#, c-format +msgid "" +"This could be a problem of mismatched byte ordering. It looks like you need " +"to initdb." +msgstr "" +"이것은 바이트 순서 불일치 문제일 수 있습니다. initdb 작업이 필요해 보입니다." + +#: access/transam/xlog.c:4759 +#, c-format +msgid "" +"The database cluster was initialized with PG_CONTROL_VERSION %d, but the " +"server was compiled with PG_CONTROL_VERSION %d." +msgstr "" +"이 데이터베이스 클러스터는 PG_CONTROL_VERSION %d 버전으로 초기화 되었지만, 서" +"버는 PG_CONTROL_VERSION %d 버전으로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4762 access/transam/xlog.c:4786 +#: access/transam/xlog.c:4793 access/transam/xlog.c:4798 +#, c-format +msgid "It looks like you need to initdb." +msgstr "initdb 명령이 필요한 듯 합니다" + +#: access/transam/xlog.c:4773 +#, c-format +msgid "incorrect checksum in control file" +msgstr "컨트롤 파일에 잘못된 체크섬 값이 있습니다" + +#: access/transam/xlog.c:4783 +#, c-format +msgid "" +"The database cluster was initialized with CATALOG_VERSION_NO %d, but the " +"server was compiled with CATALOG_VERSION_NO %d." +msgstr "" +"이 데이터베이스 클러스터는 CATALOG_VERSION_NO %d 버전으로 초기화 되었지만, 서" +"버는 CATALOG_VERSION_NO %d 버전으로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4790 +#, c-format +msgid "" +"The database cluster was initialized with MAXALIGN %d, but the server was " +"compiled with MAXALIGN %d." +msgstr "" +"이 데이터베이스 클러스터는 MAXALIGN %d (으)로 초기화 되었지만, 서버는 " +"MAXALIGN %d (으)로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4797 +#, c-format +msgid "" +"The database cluster appears to use a different floating-point number format " +"than the server executable." +msgstr "" +"데이터베이스 클러스터와 서버 실행 파일이 서로 다른 부동 소수점 숫자 형식을 사" +"용하고 있습니다." + +#: access/transam/xlog.c:4802 +#, c-format +msgid "" +"The database cluster was initialized with BLCKSZ %d, but the server was " +"compiled with BLCKSZ %d." +msgstr "" +"이 데이터베이스 클러스터는 BLCKSZ %d (으)로 초기화 되었지만, 서버는 BLCKSZ " +"%d (으)로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4805 access/transam/xlog.c:4812 +#: access/transam/xlog.c:4819 access/transam/xlog.c:4826 +#: access/transam/xlog.c:4833 access/transam/xlog.c:4840 +#: access/transam/xlog.c:4847 access/transam/xlog.c:4855 +#: access/transam/xlog.c:4862 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "" +"서버를 새로 컴파일 하거나 initdb 명령을 사용해 새로 데이터베이스 클러스터를 " +"다시 만들거나 해야할 것 같습니다." + +#: access/transam/xlog.c:4809 +#, c-format +msgid "" +"The database cluster was initialized with RELSEG_SIZE %d, but the server was " +"compiled with RELSEG_SIZE %d." +msgstr "" +"이 데이터베이스 클러스터는 RELSEG_SIZE %d (으)로 초기화 되었지만, 서버는 " +"RELSEG_SIZE %d (으)로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4816 +#, c-format +msgid "" +"The database cluster was initialized with XLOG_BLCKSZ %d, but the server was " +"compiled with XLOG_BLCKSZ %d." +msgstr "" +"이 데이터베이스 클러스터는 XLOG_BLCKSZ %d (으)로 초기화 되었지만, 서버는 " +"XLOG_BLCKSZ %d (으)로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4823 +#, c-format +msgid "" +"The database cluster was initialized with NAMEDATALEN %d, but the server was " +"compiled with NAMEDATALEN %d." +msgstr "" +"이 데이터베이스 클러스터는 NAMEDATALEN %d (으)로 초기화 되었지만, 서버는 " +"NAMEDATALEN %d (으)로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4830 +#, c-format +msgid "" +"The database cluster was initialized with INDEX_MAX_KEYS %d, but the server " +"was compiled with INDEX_MAX_KEYS %d." +msgstr "" +"이 데이터베이스 클러스터는 INDEX_MAX_KEYS %d (으)로 초기화 되었지만, 서버는 " +"INDEX_MAX_KEYS %d (으)로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4837 +#, c-format +msgid "" +"The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the " +"server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "" +"데이터베이스 클러스터는 TOAST_MAX_CHUNK_SIZE %d(으)로 초기화되었지만 서버는 " +"TOAST_MAX_CHUNK_SIZE %d(으)로 컴파일 되었습니다." + +#: access/transam/xlog.c:4844 +#, c-format +msgid "" +"The database cluster was initialized with LOBLKSIZE %d, but the server was " +"compiled with LOBLKSIZE %d." +msgstr "" +"이 데이터베이스 클러스터는 LOBLKSIZE %d(으)로 초기화 되었지만, 서버는 " +"LOBLKSIZE %d (으)로 컴파일 되어있습니다." + +#: access/transam/xlog.c:4853 +#, c-format +msgid "" +"The database cluster was initialized without USE_FLOAT8_BYVAL but the server " +"was compiled with USE_FLOAT8_BYVAL." +msgstr "" +"데이터베이스 클러스터는 USE_FLOAT8_BYVAL 없이 초기화되었지만, 서버는 " +"USE_FLOAT8_BYVAL을 사용하여 컴파일되었습니다." + +#: access/transam/xlog.c:4860 +#, c-format +msgid "" +"The database cluster was initialized with USE_FLOAT8_BYVAL but the server " +"was compiled without USE_FLOAT8_BYVAL." +msgstr "" +"데이터베이스 클러스터는 USE_FLOAT8_BYVAL을 사용하여 초기화되었지만, 서버는 " +"USE_FLOAT8_BYVAL 없이 컴파일되었습니다." + +#: access/transam/xlog.c:4869 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d bytes" +msgstr[0] "" +"WAL 조각 파일은 1MB부터 1GB 사이 2^n 크기여야 하지만, 컨트롤 파일에는 %d 바이" +"트로 지정되었음" + +#: access/transam/xlog.c:4881 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" 값은 \"wal_segment_size\" 값의 최소 2배 이상이어야 함" + +#: access/transam/xlog.c:4885 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" 값은 \"wal_segment_size\" 값의 최소 2배 이상이어야 함" + +#: access/transam/xlog.c:5318 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "bootstrap 트랜잭션 로그 파일을 쓸 수 없음: %m" + +#: access/transam/xlog.c:5326 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "bootstrap 트랜잭션 로그 파일을 fsync할 수 없음: %m" + +#: access/transam/xlog.c:5332 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "bootstrap 트랜잭션 로그 파일을 닫을 수 없음: %m" + +#: access/transam/xlog.c:5393 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "\"%s\" 복구 명령 파일을 사용하는 것을 지원하지 않습니다" + +#: access/transam/xlog.c:5458 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "단일 사용자 서버를 대상으로 대기 모드를 사용할 수 없습니다." + +#: access/transam/xlog.c:5475 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "primary_conninfo 설정도, restore_command 설정도 없음" + +#: access/transam/xlog.c:5476 +#, c-format +msgid "" +"The database server will regularly poll the pg_wal subdirectory to check for " +"files placed there." +msgstr "" +"데이터베이스 서버는 일반적으로 주 서버에서 발생한 트랜잭션 로그를 반영하기 위" +"해 pg_wal 하위 디렉터리를 조사할 것입니다." + +#: access/transam/xlog.c:5484 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "" +"대기 모드를 활성화 하지 않았다면(standby_mode = off), restore_command 설정은 " +"반드시 있어야 함" + +#: access/transam/xlog.c:5522 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "%u 복구 대상 타임라인이 없음" + +#: access/transam/xlog.c:5644 +#, c-format +msgid "archive recovery complete" +msgstr "아카이브 복구 완료" + +#: access/transam/xlog.c:5710 access/transam/xlog.c:5983 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "일관성을 다 맞추어 복구 작업을 중지합니다." + +#: access/transam/xlog.c:5731 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "복구 중지 위치(LSN): \"%X/%X\" 이전" + +#: access/transam/xlog.c:5817 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "%u 트랜잭션 커밋 전 복구 중지함, 시간 %s" + +#: access/transam/xlog.c:5824 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "%u 트랜잭션 중단 전 복구 중지함, 시간 %s" + +#: access/transam/xlog.c:5877 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "복구 중지함, 복구 위치 \"%s\", 시간 %s" + +#: access/transam/xlog.c:5895 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "복구 중지 위치(LSN): \"%X/%X\" 이후" + +#: access/transam/xlog.c:5963 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "%u 트랜잭션 커밋 후 복구 중지함, 시간 %s" + +#: access/transam/xlog.c:5971 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "%u 트랜잭션 중단 후 복구 중지함, 시간 %s" + +#: access/transam/xlog.c:6020 +#, c-format +msgid "pausing at the end of recovery" +msgstr "복구 끝에 기다리는 중" + +#: access/transam/xlog.c:6021 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "운영 서버로 바꾸려면, pg_wal_replay_resume() 함수를 호출하세요." + +#: access/transam/xlog.c:6024 +#, c-format +msgid "recovery has paused" +msgstr "복구 작업이 일시 중지 됨" + +#: access/transam/xlog.c:6025 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "계속 진행하려면, pg_wal_replay_resume() 함수를 호출하세요." + +#: access/transam/xlog.c:6242 +#, c-format +msgid "" +"hot standby is not possible because %s = %d is a lower setting than on the " +"master server (its value was %d)" +msgstr "" +"읽기 전용 대기 서버로 운영이 불가능합니다. 현재 %s = %d 설정은 주 서버의 설정" +"값(%d)보다 낮게 설정 되어 있기 때문입니다." + +#: access/transam/xlog.c:6266 +#, c-format +msgid "WAL was generated with wal_level=minimal, data may be missing" +msgstr "" +"WAL 내용이 wal_level=minimal 설정으로 만들여졌습니다. 자료가 손실 될 수 있습" +"니다." + +#: access/transam/xlog.c:6267 +#, c-format +msgid "" +"This happens if you temporarily set wal_level=minimal without taking a new " +"base backup." +msgstr "" +"이 문제는 새 베이스 백업을 받지 않은 상태에서 서버가 일시적으로 " +"wal_level=minimal 설정으로 운영된 적이 있다면 발생합니다." + +#: access/transam/xlog.c:6278 +#, c-format +msgid "" +"hot standby is not possible because wal_level was not set to \"replica\" or " +"higher on the master server" +msgstr "" +"주 서버 wal_level 설정이 \"replica\" 또는 그 이상 수준으로 설정되지 않아, 읽" +"기 전용 보조 서버로 운영될 수 없음" + +#: access/transam/xlog.c:6279 +#, c-format +msgid "" +"Either set wal_level to \"replica\" on the master, or turn off hot_standby " +"here." +msgstr "" +"운영 서버의 환경 설정에서 wal_leve = \"replica\" 형태로 지정하든가 " +"hot_standby = off 형태로 지정하십시오." + +#: access/transam/xlog.c:6341 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "컨트롤 파일에 잘못된 체크포인트 위치가 있습니다" + +#: access/transam/xlog.c:6352 +#, c-format +msgid "database system was shut down at %s" +msgstr "데이터베이스 시스템 마지막 가동 중지 시각: %s" + +#: access/transam/xlog.c:6358 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "복구 중 데이터베이스 시스템 마지막 가동 중지 시각: %s" + +#: access/transam/xlog.c:6364 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "" +"데이터베이스 시스템 셧다운 작업이 비정상적으로 종료되었음; 마지막 운영시간: " +"%s" + +#: access/transam/xlog.c:6370 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "데이터베이스 시스템 복구하는 도중 비정상적으로 가동 중지된 시각: %s" + +#: access/transam/xlog.c:6372 +#, c-format +msgid "" +"This probably means that some data is corrupted and you will have to use the " +"last backup for recovery." +msgstr "" +"이 사태는 몇몇 데이터가 손상되었을 의미할 수도 있습니다. 확인해 보고, 필요하" +"다면, 마지막 백업 자료로 복구해서 사용하세요." + +#: access/transam/xlog.c:6378 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "데이터베이스 시스템이 로그 시간 %s에 복구 도중 중지 되었음" + +#: access/transam/xlog.c:6380 +#, c-format +msgid "" +"If this has occurred more than once some data might be corrupted and you " +"might need to choose an earlier recovery target." +msgstr "" +"이 사태로 몇몇 자료가 손상되었을 수도 있는데, 이런 경우라면,확인해 보고, 필요" +"하다면, 마지막 백업 자료로 복구해서 사용하세요." + +#: access/transam/xlog.c:6386 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "데이터베이스 시스템이 비정상적으로 종료되었음; 마지막 운영시간: %s" + +#: access/transam/xlog.c:6392 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "컨트롤 파일에 잘못된 데이터베이스 클러스터 상태값이 있습니다" + +#: access/transam/xlog.c:6449 +#, c-format +msgid "entering standby mode" +msgstr "대기 모드로 전환합니다" + +#: access/transam/xlog.c:6452 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "%u XID까지 시점 기반 복구 작업을 시작합니다" + +#: access/transam/xlog.c:6456 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "%s 까지 시점 복구 작업을 시작합니다" + +#: access/transam/xlog.c:6460 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "\"%s\" 복구 대상 이름까지 시점 복구 작업을 시작합니다" + +#: access/transam/xlog.c:6464 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "\"%X/%X\" 위치(LSN)까지 시점 복구 작업을 시작합니다" + +#: access/transam/xlog.c:6469 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "동기화 할 수 있는 마지막 지점까지 시점 복구 작업을 시작합니다" + +#: access/transam/xlog.c:6472 +#, c-format +msgid "starting archive recovery" +msgstr "아카이브 복구 작업을 시작합니다" + +#: access/transam/xlog.c:6531 access/transam/xlog.c:6664 +#, c-format +msgid "checkpoint record is at %X/%X" +msgstr "체크포인트 레코드 위치: %X/%X" + +#: access/transam/xlog.c:6546 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "체크포인트 기록으로 참조하는 재실행 위치를 찾을 수 없음" + +#: access/transam/xlog.c:6547 access/transam/xlog.c:6557 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add " +"required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/" +"backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if " +"restoring from a backup." +msgstr "" + +#: access/transam/xlog.c:6556 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "요청된 체크포인트 레코드의 위치를 바르게 잡을 수 없음" + +#: access/transam/xlog.c:6585 commands/tablespace.c:654 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "\"%s\" 심벌릭 링크를 만들 수 없음: %m" + +#: access/transam/xlog.c:6617 access/transam/xlog.c:6623 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "\"%s\" 파일 무시함, \"%s\" 파일 없음" + +#: access/transam/xlog.c:6619 access/transam/xlog.c:11828 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "\"%s\" 파일을 \"%s\" 파일로 이름을 바꿨습니다." + +#: access/transam/xlog.c:6625 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "\"%s\" 파일을 \"%s\" 파일로 이름을 바꿀 수 없음: %m" + +#: access/transam/xlog.c:6676 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "체크포인트 레코드의 위치를 바르게 잡을 수 없음" + +#: access/transam/xlog.c:6714 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "요청한 %u 타임라인은 서버 타임라인의 하위가 아님" + +#: access/transam/xlog.c:6716 +#, c-format +msgid "" +"Latest checkpoint is at %X/%X on timeline %u, but in the history of the " +"requested timeline, the server forked off from that timeline at %X/%X." +msgstr "" +"마지막 체크포인트 위치는 %X/%X (%u 타임라인)입니다. 하지만, 요청받은 타임라" +"인 내역파일에는 그 타임라인 %X/%X 위치에서 분기되었습니다." + +#: access/transam/xlog.c:6732 +#, c-format +msgid "" +"requested timeline %u does not contain minimum recovery point %X/%X on " +"timeline %u" +msgstr "" +"요청한 %u 타임라인은 %X/%X 최소 복구 위치가 없습니다, 기존 타임라인: %u" + +#: access/transam/xlog.c:6763 +#, c-format +msgid "invalid next transaction ID" +msgstr "잘못된 다음 트랜잭션 ID" + +#: access/transam/xlog.c:6857 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "체크포인트 레코드 안에 잘못된 redo 정보가 있음" + +#: access/transam/xlog.c:6868 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "운영 중지 체크포인트에서 잘못된 재실행 정보 발견" + +#: access/transam/xlog.c:6902 +#, c-format +msgid "" +"database system was not properly shut down; automatic recovery in progress" +msgstr "" +"데이터베이스 시스템이 정상적으로 종료되지 못했습니다, 자동 복구 작업을 진행합" +"니다" + +#: access/transam/xlog.c:6906 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "" +"%u 타임라인으로 비정상 중지에 대한 복구작업을 시작함, 기존 타임라인: %u" + +#: access/transam/xlog.c:6953 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label 파일 안에 컨트롤 파일과 일관성이 맞지 않는 자료가 있음" + +#: access/transam/xlog.c:6954 +#, c-format +msgid "" +"This means that the backup is corrupted and you will have to use another " +"backup for recovery." +msgstr "" +"이 문제는 백업 자료 자체가 손상 되었음을 말합니다. 다른 백업본으로 복구 작업" +"을 진행해야 합니다." + +#: access/transam/xlog.c:7045 +#, c-format +msgid "initializing for hot standby" +msgstr "읽기 전용 보조 서버로 초기화 중입니다." + +#: access/transam/xlog.c:7178 +#, c-format +msgid "redo starts at %X/%X" +msgstr "%X/%X에서 redo 작업 시작됨" + +#: access/transam/xlog.c:7402 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "요청한 복구 중지 지점이 일치하는 복구 지점 앞에 있음" + +#: access/transam/xlog.c:7440 +#, c-format +msgid "redo done at %X/%X" +msgstr "%X/%X에서 redo 작업 완료" + +#: access/transam/xlog.c:7445 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "마지막 완료된 트랜잭션 기록 시간: %s" + +#: access/transam/xlog.c:7454 +#, c-format +msgid "redo is not required" +msgstr "재반영해야 할 트랜잭션이 없음" + +#: access/transam/xlog.c:7466 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "" + +#: access/transam/xlog.c:7545 access/transam/xlog.c:7549 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "온라인 백업 작업 끝나기전에 WAL 작업 종료됨" + +#: access/transam/xlog.c:7546 +#, c-format +msgid "" +"All WAL generated while online backup was taken must be available at " +"recovery." +msgstr "" +"온라인 백업 중 만들어진 WAL 조각 파일은 복구 작업에서 반드시 모두 있어야 합니" +"다." + +#: access/transam/xlog.c:7550 +#, c-format +msgid "" +"Online backup started with pg_start_backup() must be ended with " +"pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "" +"pg_start_backup() 함수를 호출해서 시작한 온라인 백업은 pg_stop_backup() 함수" +"로 종료되어야 하며, 그 사이 만들어진 WAL 조각 파일은 복구 작업에서 모두 필요" +"합니다." + +#: access/transam/xlog.c:7553 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL이 일치하는 복구 지점 앞에서 종료됨" + +#: access/transam/xlog.c:7588 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "지정한 새 타임라인 ID: %u" + +#: access/transam/xlog.c:8036 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "%X/%X 위치에서 복구 일관성을 맞춤" + +#: access/transam/xlog.c:8246 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "컨트롤 파일에서 잘못된 primary checkpoint 링크 발견" + +#: access/transam/xlog.c:8250 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "백업 라벨 파일에서 잘못된 체크포인트 링크 발견" + +#: access/transam/xlog.c:8268 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "잘못된 primary checkpoint 레코드" + +#: access/transam/xlog.c:8272 +#, c-format +msgid "invalid checkpoint record" +msgstr "잘못된 checkpoint 레코드" + +#: access/transam/xlog.c:8283 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "primary checkpoint 레코드에서 잘못된 자원 관리자 ID 발견" + +#: access/transam/xlog.c:8287 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "checkpoint 레코드에서 잘못된 자원 관리자 ID 발견" + +#: access/transam/xlog.c:8300 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "primary checkpoint 레코드에서 잘못된 xl_info 발견" + +#: access/transam/xlog.c:8304 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "checkpoint 레코드에서 잘못된 xl_info 발견" + +#: access/transam/xlog.c:8315 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "primary checkpoint 레코드 길이가 잘못되었음" + +#: access/transam/xlog.c:8319 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "checkpoint 레코드 길이가 잘못되었음" + +#: access/transam/xlog.c:8499 +#, c-format +msgid "shutting down" +msgstr "서비스를 멈추고 있습니다" + +#: access/transam/xlog.c:8819 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "시스템이 놀고 있어 체크포인트 작업 건너뜀" + +#: access/transam/xlog.c:9019 +#, c-format +msgid "" +"concurrent write-ahead log activity while database system is shutting down" +msgstr "데이터베이스 시스템이 중지되는 동안 동시 트랜잭션 로그가 활성화 되었음" + +#: access/transam/xlog.c:9276 +#, c-format +msgid "skipping restartpoint, recovery has already ended" +msgstr "다시 시작 지점을 건너뜀, 복구가 이미 종료됨" + +#: access/transam/xlog.c:9299 +#, c-format +msgid "skipping restartpoint, already performed at %X/%X" +msgstr "다시 시작 지점을 건너뜀, %X/%X에서 이미 수행됨" + +#: access/transam/xlog.c:9467 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "%X/%X에서 복구 작업 시작함" + +#: access/transam/xlog.c:9469 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "마지막 완료된 트랜잭션 기록 시간은 %s 입니다." + +#: access/transam/xlog.c:9711 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "\"%s\" 이름의 복구 위치는 %X/%X에 만들었음" + +#: access/transam/xlog.c:9856 +#, c-format +msgid "" +"unexpected previous timeline ID %u (current timeline ID %u) in checkpoint " +"record" +msgstr "" +"체크포인트 레코드에 예기치 않은 이전 타임라인ID %u(현재 타임라인ID: %u)" + +#: access/transam/xlog.c:9865 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "체크포인트 레코드에 예기치 않은 타임라인 ID %u이(가) 있음(%u 뒤)" + +#: access/transam/xlog.c:9881 +#, c-format +msgid "" +"unexpected timeline ID %u in checkpoint record, before reaching minimum " +"recovery point %X/%X on timeline %u" +msgstr "" +"체크포인트 내역 안에 %u 타임라인 ID가 기대한 것과 다릅니다. 발생 위치: %X/%X " +"(타임라인: %u) 최소 복구 위치 이전" + +#: access/transam/xlog.c:9957 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "온라인 백어이 취소되었음, 복구를 계속 할 수 없음" + +#: access/transam/xlog.c:10013 access/transam/xlog.c:10069 +#: access/transam/xlog.c:10092 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "체크포인트 레코드에 예기치 않은 타임라인 ID %u이(가) 있음(%u이어야 함)" + +#: access/transam/xlog.c:10418 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "\"%s\" write-through 파일을 fsync할 수 없음: %m" + +#: access/transam/xlog.c:10424 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "\"%s\" 파일 fdatasync 실패: %m" + +#: access/transam/xlog.c:10523 access/transam/xlog.c:11061 +#: access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 +#: access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 +#: access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "WAL 제어 함수는 복구 작업 중에는 실행 될 수 없음" + +#: access/transam/xlog.c:10532 access/transam/xlog.c:11070 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "온라인 백업 작업을 하기 위한 WAL 수준이 충분치 않습니다." + +#: access/transam/xlog.c:10533 access/transam/xlog.c:11071 +#: access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "" +"wal_level 값을 \"replica\" 또는 \"logical\"로 지정하고 서버를 실행하십시오." + +#: access/transam/xlog.c:10538 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "백업 라벨 이름이 너무 긺(최대 %d 바이트)" + +#: access/transam/xlog.c:10575 access/transam/xlog.c:10860 +#: access/transam/xlog.c:10898 +#, c-format +msgid "a backup is already in progress" +msgstr "이미 백업 작업이 진행 중입니다" + +#: access/transam/xlog.c:10576 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "pg_stop_backup() 함수를 실행하고 나서 다시 시도하세요." + +#: access/transam/xlog.c:10672 +#, c-format +msgid "" +"WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "" +"마지막 재시작 위치부터 재반영된 WAL 내용이 full_page_writes=off 설정으로 만들" +"어진 내용입니다." + +#: access/transam/xlog.c:10674 access/transam/xlog.c:11266 +#, c-format +msgid "" +"This means that the backup being taken on the standby is corrupt and should " +"not be used. Enable full_page_writes and run CHECKPOINT on the master, and " +"then try an online backup again." +msgstr "" +"이 경우 대기 서버의 자료가 손실되었을 가능성이 있습니다. full_page_writes 설" +"정을 활성화 하고, 주 서버에서 CHECKPOINT 명령을 실행하고, 온라인 백업을 다시 " +"해서 사용하세요." + +#: access/transam/xlog.c:10757 replication/basebackup.c:1423 +#: utils/adt/misc.c:342 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "\"%s\" 심볼릭 링크의 대상이 너무 긺" + +#: access/transam/xlog.c:10810 commands/tablespace.c:402 +#: commands/tablespace.c:566 replication/basebackup.c:1438 utils/adt/misc.c:350 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "테이블스페이스 기능은 이 플랫폼에서는 지원하지 않습니다." + +#: access/transam/xlog.c:10861 access/transam/xlog.c:10899 +#, c-format +msgid "" +"If you're sure there is no backup in progress, remove file \"%s\" and try " +"again." +msgstr "" +"실재로는 백업 작업을 안하고 있다고 확신한다면, \"%s\" 파일을 삭제하고 다시 시" +"도해 보십시오." + +#: access/transam/xlog.c:11086 +#, c-format +msgid "exclusive backup not in progress" +msgstr "exclusive 백업 작업을 하지 않고 있습니다" + +#: access/transam/xlog.c:11113 +#, c-format +msgid "a backup is not in progress" +msgstr "현재 백업 작업을 하지 않고 있습니다" + +#: access/transam/xlog.c:11199 access/transam/xlog.c:11212 +#: access/transam/xlog.c:11601 access/transam/xlog.c:11607 +#: access/transam/xlog.c:11655 access/transam/xlog.c:11728 +#: access/transam/xlogfuncs.c:692 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "\"%s\" 파일에 유효하지 않은 자료가 있습니다" + +#: access/transam/xlog.c:11216 replication/basebackup.c:1271 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "대기 서버가 온라인 백업 중 주 서버로 전환되었습니다" + +#: access/transam/xlog.c:11217 replication/basebackup.c:1272 +#, c-format +msgid "" +"This means that the backup being taken is corrupt and should not be used. " +"Try taking another online backup." +msgstr "" +"이런 경우, 해당 백업 자료가 손상되었을 가능성이 있습니다. 다른 백업본을 이용" +"하세요." + +#: access/transam/xlog.c:11264 +#, c-format +msgid "" +"WAL generated with full_page_writes=off was replayed during online backup" +msgstr "" +"온라인 백업 도중 full_page_writes=off 설정으로 만들어진 WAL 내용이 재반영되었" +"습니다." + +#: access/transam/xlog.c:11384 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "" +"베이스 백업이 끝났습니다. 필요한 WAL 조각 파일이 아카이브 되길 기다리고 있습" +"니다." + +#: access/transam/xlog.c:11396 +#, c-format +msgid "" +"still waiting for all required WAL segments to be archived (%d seconds " +"elapsed)" +msgstr "" +"필요한 WAL 조각 파일 아카이빙이 완료되기를 계속 기다리고 있음 (%d초 경과)" + +#: access/transam/xlog.c:11398 +#, c-format +msgid "" +"Check that your archive_command is executing properly. You can safely " +"cancel this backup, but the database backup will not be usable without all " +"the WAL segments." +msgstr "" +"archive_command 설정을 살펴보세요. 이 백업 작업은 안전하게 취소 할 수 있지" +"만, 데이터베이스 백업은 모든 WAL 조각 없이는 사용될 수 없습니다." + +#: access/transam/xlog.c:11405 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "모든 필요한 WAL 조각들이 아카이브 되었습니다." + +#: access/transam/xlog.c:11409 +#, c-format +msgid "" +"WAL archiving is not enabled; you must ensure that all required WAL segments " +"are copied through other means to complete the backup" +msgstr "" +"WAL 아카이브 기능이 비활성화 되어 있습니다; 이 경우는 백업 뒤 복구에 필요한 " +"모든 WAL 조각 파일들을 직접 찾아서 따로 보관해 두어야 바르게 복구 할 수 있습" +"니다." + +#: access/transam/xlog.c:11462 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "" +"pg_stop_backup 작업이 호출되기 전에 백엔드가 종료되어 백업을 중지합니다." + +#: access/transam/xlog.c:11638 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "백업 시간: %s, 저장된 파일: \"%s\"" + +#: access/transam/xlog.c:11643 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "백업 라벨: %s, 저장된 파일: \"%s\"" + +#: access/transam/xlog.c:11656 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "타임라인 ID가 %u 값으로 분석했지만, 기대값은 %u 임" + +#: access/transam/xlog.c:11660 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "백업 타임라인: %u, 저장된 파일: \"%s\"" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11768 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "WAL redo 위치: %X/%X, 대상: %s" + +#: access/transam/xlog.c:11817 +#, c-format +msgid "online backup mode was not canceled" +msgstr "온라인 백업 모드가 취소되지 않았음" + +#: access/transam/xlog.c:11818 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "\"%s\" 파일을 \"%s\" 파일로 이름을 바꿀 수 없음: %m." + +#: access/transam/xlog.c:11827 access/transam/xlog.c:11839 +#: access/transam/xlog.c:11849 +#, c-format +msgid "online backup mode canceled" +msgstr "온라인 백업 모드가 취소됨" + +#: access/transam/xlog.c:11840 +#, c-format +msgid "" +"Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "" +"예상한 것처럼, \"%s\", \"%s\" 파일을 \"%s\", \"%s\" 이름으로 바꿨습니다." + +#: access/transam/xlog.c:11850 +#, c-format +msgid "" +"File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to " +"\"%s\": %m." +msgstr "" +"\"%s\" 파일은 \"%s\" 이름으로 바꿨지만, \"%s\" 파일은 \"%s\" 이름으로 바꾸지 " +"못했습니다: %m." + +#: access/transam/xlog.c:11983 access/transam/xlogutils.c:971 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "%s 로그 조각에서 읽기 실패, 위치: %u: %m" + +#: access/transam/xlog.c:11989 access/transam/xlogutils.c:978 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "%s 로그 조각에서 읽기 실패, 위치: %u, %d / %zu 읽음" + +#: access/transam/xlog.c:12518 +#, c-format +msgid "WAL receiver process shutdown requested" +msgstr "WAL receiver 프로세스가 중지 요청을 받았습니다." + +#: access/transam/xlog.c:12624 +#, c-format +msgid "received promote request" +msgstr "운영 전환 신호를 받았습니다." + +#: access/transam/xlog.c:12637 +#, c-format +msgid "promote trigger file found: %s" +msgstr "마스터 전환 트리거 파일이 있음: %s" + +#: access/transam/xlog.c:12646 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "\"%s\" 마스터 전환 트리거 파일의 상태값을 알 수 없음: %m" + +#: access/transam/xlogarchive.c:205 +#, c-format +msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgstr "\"%s\" 기록 파일의 크기가 이상합니다: 현재값 %lu, 원래값 %lu" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "아카이브에서 \"%s\" 로그파일을 복구했음" + +#: access/transam/xlogarchive.c:259 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "아카이브에서 \"%s\" 파일 복원 실패: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:368 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" + +#: access/transam/xlogarchive.c:478 access/transam/xlogarchive.c:542 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "\"%s\" archive status 파일을 만들 수 없습니다: %m" + +#: access/transam/xlogarchive.c:486 access/transam/xlogarchive.c:550 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "\"%s\" archive status 파일에 쓸 수 없습니다: %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "이미 이 세션에서 백업 작업이 진행 중입니다" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "non-exclusive 백업 진행 중입니다" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "pg_stop_backup('f') 형태로 함수를 호출했나요?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1332 +#: commands/event_trigger.c:1890 commands/extension.c:1944 +#: commands/extension.c:2052 commands/extension.c:2337 commands/prepare.c:712 +#: executor/execExpr.c:2203 executor/execSRF.c:728 executor/functions.c:1046 +#: foreign/foreign.c:520 libpq/hba.c:2666 replication/logical/launcher.c:1086 +#: replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1486 +#: replication/slotfuncs.c:252 replication/walsender.c:3265 +#: storage/ipc/shmem.c:550 utils/adt/datetime.c:4765 utils/adt/genfile.c:505 +#: utils/adt/genfile.c:588 utils/adt/jsonfuncs.c:1792 +#: utils/adt/jsonfuncs.c:1904 utils/adt/jsonfuncs.c:2092 +#: utils/adt/jsonfuncs.c:2201 utils/adt/jsonfuncs.c:3663 utils/adt/misc.c:215 +#: utils/adt/pgstatfuncs.c:476 utils/adt/pgstatfuncs.c:584 +#: utils/adt/pgstatfuncs.c:1719 utils/fmgr/funcapi.c:72 utils/misc/guc.c:9648 +#: utils/mmgr/portalmem.c:1136 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "" +"set-values 함수(테이블 리턴 함수)가 set 정의 없이 사용되었습니다 (테이블과 해" +"당 열 alias 지정하세요)" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1336 +#: commands/event_trigger.c:1894 commands/extension.c:1948 +#: commands/extension.c:2056 commands/extension.c:2341 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2670 replication/logical/launcher.c:1090 +#: replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1490 +#: replication/slotfuncs.c:256 replication/walsender.c:3269 +#: storage/ipc/shmem.c:554 utils/adt/datetime.c:4769 utils/adt/genfile.c:509 +#: utils/adt/genfile.c:592 utils/adt/misc.c:219 utils/adt/pgstatfuncs.c:480 +#: utils/adt/pgstatfuncs.c:588 utils/adt/pgstatfuncs.c:1723 +#: utils/misc/guc.c:9652 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1140 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "materialize 모드가 필요합니다만, 이 구문에서는 허용되지 않습니다" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "non-exclusive 백업 상태가 아닙니다" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "pg_stop_backup('t') 형태로 함수를 호출했나요?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "WAL 수준이 복원 위치를 만들 수 없는 수준입니다" + +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "복원 위치 이름이 너무 깁니다. (최대값, %d 글자)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "복구 작업 중에는 %s 명령을 실행할 수 없습니다." + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:558 +#: access/transam/xlogfuncs.c:582 access/transam/xlogfuncs.c:722 +#, c-format +msgid "recovery is not in progress" +msgstr "현재 복구 작업 상태가 아닙니다" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:559 +#: access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "복구 제어 함수는 복구 작업일 때만 실행할 수 있습니다." + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:564 +#, c-format +msgid "standby promotion is ongoing" +msgstr "대기 서버가 운영 서버로 전환 중입니다." + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:565 +#, c-format +msgid "%s cannot be executed after promotion is triggered." +msgstr "%s 함수는 운영 전환 중에는 실행될 수 없음." + +#: access/transam/xlogfuncs.c:728 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "\"wait_seconds\" 값은 음수나 0을 사용할 수 없음" + +#: access/transam/xlogfuncs.c:748 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "postmaster로 시그널 보내기 실패: %m" + +#: access/transam/xlogfuncs.c:784 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "%d 초 이내에 운영 전환을 하지 못했습니다." + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "잘못된 레코드 위치: %X/%X" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "%X/%X에서 contrecord를 필요로 함" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "잘못된 레코드 길이: %X/%X, 기대값 %u, 실재값 %u" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "너무 긴 길이(%u)의 레코드가 %X/%X에 있음" + +#: access/transam/xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "%X/%X 위치에 contrecord 플래그가 없음" + +#: access/transam/xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "잘못된 contrecord 길이 %u, 위치 %X/%X" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "잘못된 자원 관리 ID %u, 위치: %X/%X" + +#: access/transam/xlogreader.c:717 access/transam/xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "레코드의 잘못된 프리링크 %X/%X, 해당 레코드 %X/%X" + +#: access/transam/xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "잘못된 자원관리자 데이터 체크섬, 위치: %X/%X 레코드" + +#: access/transam/xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "%04X 매직 번호가 잘못됨, 로그 파일 %s, 위치 %u" + +#: access/transam/xlogreader.c:822 access/transam/xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "잘못된 정보 비트 %04X, 로그 파일 %s, 위치 %u" + +#: access/transam/xlogreader.c:837 +#, c-format +msgid "" +"WAL file is from different database system: WAL file database system " +"identifier is %llu, pg_control database system identifier is %llu" +msgstr "" +"WAL 파일이 다른 시스템의 것입니다. WAL 파일의 시스템 식별자는 %llu, pg_control " +"의 식별자는 %llu" + +#: access/transam/xlogreader.c:845 +#, c-format +msgid "" +"WAL file is from different database system: incorrect segment size in page " +"header" +msgstr "" +"WAL 파일이 다른 데이터베이스 시스템의 것입니다: 페이지 헤더에 지정된 값이 잘" +"못된 조각 크기임" + +#: access/transam/xlogreader.c:851 +#, c-format +msgid "" +"WAL file is from different database system: incorrect XLOG_BLCKSZ in page " +"header" +msgstr "" +"WAL 파일이 다른 데이터베이스 시스템의 것입니다: 페이지 헤더의 XLOG_BLCKSZ 값" +"이 바르지 않음" + +#: access/transam/xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "잘못된 페이지 주소 %X/%X, 로그 파일 %s, 위치 %u" + +#: access/transam/xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "타임라인 범위 벗어남 %u (이전 번호 %u), 로그 파일 %s, 위치 %u" + +#: access/transam/xlogreader.c:1247 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "%u block_id는 범위를 벗어남, 위치 %X/%X" + +#: access/transam/xlogreader.c:1270 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA 지정했지만, %X/%X 에 자료가 없음" + +#: access/transam/xlogreader.c:1277 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA 지정 않았지만, %u 길이의 자료가 있음, 위치 %X/%X" + +#: access/transam/xlogreader.c:1313 +#, c-format +msgid "" +"BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " +"%X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE 설정이 되어 있지만, 옵셋: %u, 길이: %u, 블록 이미지 길이: " +"%u, 대상: %X/%X" + +#: access/transam/xlogreader.c:1329 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE 설정이 안되어 있지만, 옵셋: %u, 길이: %u, 대상: %X/%X" + +#: access/transam/xlogreader.c:1344 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "" +"BKPIMAGE_IS_COMPRESSED 설정이 되어 있지만, 블록 이미지 길이: %u, 대상: %X/%X" + +#: access/transam/xlogreader.c:1359 +#, c-format +msgid "" +"neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " +"length is %u at %X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE, BKPIMAGE_IS_COMPRESSED 지정 안되어 있으나, 블록 이미지 길" +"이는 %u, 대상: %X/%X" + +#: access/transam/xlogreader.c:1375 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL 설정이 되어 있지만, %X/%X 에 이전 릴레이션 없음" + +#: access/transam/xlogreader.c:1387 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "잘못된 block_id %u, 위치 %X/%X" + +#: access/transam/xlogreader.c:1476 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "잘못된 레코드 길이, 위치 %X/%X" + +#: access/transam/xlogreader.c:1565 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "잘못된 압축 이미지, 위치 %X/%X, 블록 %d" + +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X 값은 1 MB ~ 1 GB 사이 2^n 값이어야 함" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:842 tcop/postgres.c:3705 +#, c-format +msgid "--%s requires a value" +msgstr "--%s 옵션은 해당 값을 지정해야합니다" + +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:847 tcop/postgres.c:3710 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s 옵션은 해당 값을 지정해야합니다" + +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:859 +#: postmaster/postmaster.c:872 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "자제한 사항은 \"%s --help\" 명령으로 살펴보십시오.\n" + +#: bootstrap/bootstrap.c:313 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: 잘못된 명령행 인자\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "grant 옵션들은 롤에서만 지정될 수 있습니다" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")에 대한 권한이 부여되지 않았음" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "\"%s\"에 대한 권한이 부여되지 않았음" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")에 대한 일부 권한이 부여되지 않았음" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "\"%s\"에 대한 일부 권한이 부여되지 않았음" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")에 대한 권한을 취소할 수 없음" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "\"%s\"에 대한 권한을 취소할 수 없음" + +#: catalog/aclchk.c:342 +#, c-format +msgid "" +"not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")의 일부 권한을 박탈할 수 없음" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "\"%s\"에 대한 일부 권한을 취소할 수 없음" + +#: catalog/aclchk.c:430 catalog/aclchk.c:973 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "릴레이션의 %s 권한은 잘못된 종류임" + +#: catalog/aclchk.c:434 catalog/aclchk.c:977 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "시퀀스의 %s 권한은 잘못된 종류임" + +#: catalog/aclchk.c:438 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "%s 권한은 데이터베이스에는 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:442 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "%s 권한은 도메인에서 유효하지 않음" + +#: catalog/aclchk.c:446 catalog/aclchk.c:981 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "%s 권한은 함수에서 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:450 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "%s 권한은 프로시주얼 언어에서 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "%s 권한은 대형 개체에서 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:458 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "%s 권한은 스키마(schema)에서 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:462 catalog/aclchk.c:985 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "프로시져용 %s 권한 종류가 잘못됨" + +#: catalog/aclchk.c:466 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "루틴용 %s 권한 종류가 잘못됨" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "%s 권한은 테이블스페이스에서 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:474 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "%s 권한은 자료형에서 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:478 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "%s 권한 형식은 외부 데이터 래퍼에 유효하지 않음" + +#: catalog/aclchk.c:482 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "%s 권한 형식은 외부 서버에 유효하지 않음" + +#: catalog/aclchk.c:521 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "칼럼 권한은 릴레이션에서만 유효함" + +#: catalog/aclchk.c:681 catalog/aclchk.c:4100 catalog/aclchk.c:4882 +#: catalog/objectaddress.c:965 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "%u large object 없음" + +#: catalog/aclchk.c:910 catalog/aclchk.c:919 commands/collationcmds.c:118 +#: commands/copy.c:1134 commands/copy.c:1154 commands/copy.c:1163 +#: commands/copy.c:1172 commands/copy.c:1181 commands/copy.c:1190 +#: commands/copy.c:1199 commands/copy.c:1208 commands/copy.c:1226 +#: commands/copy.c:1242 commands/copy.c:1262 commands/copy.c:1279 +#: commands/dbcommands.c:157 commands/dbcommands.c:166 +#: commands/dbcommands.c:175 commands/dbcommands.c:184 +#: commands/dbcommands.c:193 commands/dbcommands.c:202 +#: commands/dbcommands.c:211 commands/dbcommands.c:220 +#: commands/dbcommands.c:229 commands/dbcommands.c:238 +#: commands/dbcommands.c:260 commands/dbcommands.c:1502 +#: commands/dbcommands.c:1511 commands/dbcommands.c:1520 +#: commands/dbcommands.c:1529 commands/extension.c:1735 +#: commands/extension.c:1745 commands/extension.c:1755 +#: commands/extension.c:3055 commands/foreigncmds.c:539 +#: commands/foreigncmds.c:548 commands/functioncmds.c:570 +#: commands/functioncmds.c:736 commands/functioncmds.c:745 +#: commands/functioncmds.c:754 commands/functioncmds.c:763 +#: commands/functioncmds.c:2014 commands/functioncmds.c:2022 +#: commands/publicationcmds.c:90 commands/publicationcmds.c:133 +#: commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 +#: commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 +#: commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:104 commands/subscriptioncmds.c:114 +#: commands/subscriptioncmds.c:124 commands/subscriptioncmds.c:134 +#: commands/subscriptioncmds.c:148 commands/subscriptioncmds.c:159 +#: commands/subscriptioncmds.c:173 commands/tablecmds.c:7102 +#: commands/typecmds.c:322 commands/typecmds.c:1355 commands/typecmds.c:1364 +#: commands/typecmds.c:1372 commands/typecmds.c:1380 commands/typecmds.c:1388 +#: commands/user.c:133 commands/user.c:147 commands/user.c:156 +#: commands/user.c:165 commands/user.c:174 commands/user.c:183 +#: commands/user.c:192 commands/user.c:201 commands/user.c:210 +#: commands/user.c:219 commands/user.c:228 commands/user.c:237 +#: commands/user.c:246 commands/user.c:582 commands/user.c:590 +#: commands/user.c:598 commands/user.c:606 commands/user.c:614 +#: commands/user.c:622 commands/user.c:630 commands/user.c:638 +#: commands/user.c:647 commands/user.c:655 commands/user.c:663 +#: parser/parse_utilcmd.c:387 replication/pgoutput/pgoutput.c:141 +#: replication/pgoutput/pgoutput.c:162 replication/walsender.c:886 +#: replication/walsender.c:897 replication/walsender.c:907 +#, c-format +msgid "conflicting or redundant options" +msgstr "상충하거나 중복된 옵션들" + +#: catalog/aclchk.c:1030 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "default privileges 설정은 칼럼 대상으로 할 수 없음" + +#: catalog/aclchk.c:1190 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "GRANT/REVOKE ON SCHEMAS 구문을 쓸 때는 IN SCHEMA 구문을 쓸 수 없음" + +#: catalog/aclchk.c:1558 catalog/catalog.c:506 catalog/objectaddress.c:1427 +#: commands/analyze.c:389 commands/copy.c:5080 commands/sequence.c:1702 +#: commands/tablecmds.c:6578 commands/tablecmds.c:6721 +#: commands/tablecmds.c:6771 commands/tablecmds.c:6845 +#: commands/tablecmds.c:6915 commands/tablecmds.c:7027 +#: commands/tablecmds.c:7121 commands/tablecmds.c:7180 +#: commands/tablecmds.c:7253 commands/tablecmds.c:7282 +#: commands/tablecmds.c:7437 commands/tablecmds.c:7519 +#: commands/tablecmds.c:7612 commands/tablecmds.c:7767 +#: commands/tablecmds.c:10972 commands/tablecmds.c:11154 +#: commands/tablecmds.c:11314 commands/tablecmds.c:12397 commands/trigger.c:876 +#: parser/analyze.c:2339 parser/parse_relation.c:713 parser/parse_target.c:1036 +#: parser/parse_type.c:144 parser/parse_utilcmd.c:3289 +#: parser/parse_utilcmd.c:3324 parser/parse_utilcmd.c:3366 utils/adt/acl.c:2870 +#: utils/adt/ruleutils.c:2535 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "\"%s\" 칼럼은 \"%s\" 릴레이션(relation)에 없음" + +#: catalog/aclchk.c:1821 catalog/objectaddress.c:1267 commands/sequence.c:1140 +#: commands/tablecmds.c:236 commands/tablecmds.c:15706 utils/adt/acl.c:2060 +#: utils/adt/acl.c:2090 utils/adt/acl.c:2122 utils/adt/acl.c:2154 +#: utils/adt/acl.c:2182 utils/adt/acl.c:2212 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "\"%s\" 시퀀스가 아님" + +#: catalog/aclchk.c:1859 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "\"%s\" 시퀀스는 USAGE, SELECT 및 UPDATE 권한만 지원함" + +#: catalog/aclchk.c:1876 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "%s 권한은 테이블에서 사용할 수 없은 권한 형태임" + +#: catalog/aclchk.c:2042 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "%s 권한 형식은 칼럼에서 유효하지 않음" + +#: catalog/aclchk.c:2055 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "\"%s\" 시퀀스는 SELECT 열 권한만 지원함" + +#: catalog/aclchk.c:2637 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "\"%s\" 프로시주얼 언어는 안전하지 못합니다" + +#: catalog/aclchk.c:2639 +#, c-format +msgid "" +"GRANT and REVOKE are not allowed on untrusted languages, because only " +"superusers can use untrusted languages." +msgstr "" +"안전하지 않은 프로시져 언어에 대해서는 GRANT 또는 REVOKE 작업을 허용하지 않습" +"니다, 안전하지 않은 프로시져 언어는 슈퍼유저만 사용할 수 있기 때문입니다." + +#: catalog/aclchk.c:3153 +#, c-format +msgid "cannot set privileges of array types" +msgstr "배열형 자료형에 권한 설정을 할 수 없음" + +#: catalog/aclchk.c:3154 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "그 배열 요소에 해당하는 자료형에 대해서 접근 권한 설정을 하세요." + +#: catalog/aclchk.c:3161 catalog/objectaddress.c:1561 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "\"%s\" 이름의 개체는 도메인이 아닙니다" + +#: catalog/aclchk.c:3281 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "알 수 없는 권한 타입 \"%s\"" + +#: catalog/aclchk.c:3342 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "%s 집계함수에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3345 +#, c-format +msgid "permission denied for collation %s" +msgstr "%s 정렬정의(collation) 접근 권한 없음" + +#: catalog/aclchk.c:3348 +#, c-format +msgid "permission denied for column %s" +msgstr "%s 칼럼에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3351 +#, c-format +msgid "permission denied for conversion %s" +msgstr "%s 문자코드변환규칙(conversion) 접근 권한 없음" + +#: catalog/aclchk.c:3354 +#, c-format +msgid "permission denied for database %s" +msgstr "%s 데이터베이스 접근 권한 없음" + +#: catalog/aclchk.c:3357 +#, c-format +msgid "permission denied for domain %s" +msgstr "%s 도메인에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3360 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "%s 이벤트 트리거 접근 권한 없음" + +#: catalog/aclchk.c:3363 +#, c-format +msgid "permission denied for extension %s" +msgstr "%s 확장 모듈 접근 권한 없음" + +#: catalog/aclchk.c:3366 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "%s 외부 데이터 래퍼 접근 권한 없음" + +#: catalog/aclchk.c:3369 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "%s 외부 서버 접근 권한 없음" + +#: catalog/aclchk.c:3372 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "%s 외부 테이블 접근 권한 없음" + +#: catalog/aclchk.c:3375 +#, c-format +msgid "permission denied for function %s" +msgstr "%s 함수 접근 권한 없음" + +#: catalog/aclchk.c:3378 +#, c-format +msgid "permission denied for index %s" +msgstr "%s 인덱스 접근 권한 없음" + +#: catalog/aclchk.c:3381 +#, c-format +msgid "permission denied for language %s" +msgstr "%s 프로시주얼 언어 접근 권한 없음" + +#: catalog/aclchk.c:3384 +#, c-format +msgid "permission denied for large object %s" +msgstr "%s 대형 개체 접근 권한 없음" + +#: catalog/aclchk.c:3387 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "%s 구체화된 뷰에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3390 +#, c-format +msgid "permission denied for operator class %s" +msgstr "%s 연산자 클래스 접근 권한 없음" + +#: catalog/aclchk.c:3393 +#, c-format +msgid "permission denied for operator %s" +msgstr "%s 연산자 접근 권한 없음" + +#: catalog/aclchk.c:3396 +#, c-format +msgid "permission denied for operator family %s" +msgstr "%s 연산자 패밀리 접근 권한 없음" + +#: catalog/aclchk.c:3399 +#, c-format +msgid "permission denied for policy %s" +msgstr "%s 정책에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3402 +#, c-format +msgid "permission denied for procedure %s" +msgstr "%s 프로시져에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3405 +#, c-format +msgid "permission denied for publication %s" +msgstr "%s 발행 접근 권한 없음" + +#: catalog/aclchk.c:3408 +#, c-format +msgid "permission denied for routine %s" +msgstr "%s 루틴에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3411 +#, c-format +msgid "permission denied for schema %s" +msgstr "%s 스키마(schema) 접근 권한 없음" + +#: catalog/aclchk.c:3414 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 +#: commands/sequence.c:1864 +#, c-format +msgid "permission denied for sequence %s" +msgstr "%s 시퀀스 접근 권한 없음" + +#: catalog/aclchk.c:3417 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "%s 개체 통계정보 접근 권한 없음" + +#: catalog/aclchk.c:3420 +#, c-format +msgid "permission denied for subscription %s" +msgstr "%s 구독 접근 권한 없음" + +#: catalog/aclchk.c:3423 +#, c-format +msgid "permission denied for table %s" +msgstr "%s 테이블에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3426 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "%s 테이블스페이스 접근 권한 없음" + +#: catalog/aclchk.c:3429 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "%s 전문 검색 구성 접근 권한 없음" + +#: catalog/aclchk.c:3432 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "%s 전문 검색 사전 접근 권한 없음" + +#: catalog/aclchk.c:3435 +#, c-format +msgid "permission denied for type %s" +msgstr "%s 자료형 접근 권한 없음" + +#: catalog/aclchk.c:3438 +#, c-format +msgid "permission denied for view %s" +msgstr "%s 뷰에 대한 접근 권한 없음" + +#: catalog/aclchk.c:3473 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "%s 집계함수의 소유주여야만 합니다" + +#: catalog/aclchk.c:3476 +#, c-format +msgid "must be owner of collation %s" +msgstr "%s 정렬정의(collation)의 소유주여야만 합니다" + +#: catalog/aclchk.c:3479 +#, c-format +msgid "must be owner of conversion %s" +msgstr "%s 문자코드변환규칙(conversion)의 소유주여야만 합니다" + +#: catalog/aclchk.c:3482 +#, c-format +msgid "must be owner of database %s" +msgstr "%s 데이터베이스의 소유주여야만 합니다" + +#: catalog/aclchk.c:3485 +#, c-format +msgid "must be owner of domain %s" +msgstr "%s 도메인의 소유주여야만 합니다" + +#: catalog/aclchk.c:3488 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "%s 이벤트 트리거의 소유주여야만 합니다" + +#: catalog/aclchk.c:3491 +#, c-format +msgid "must be owner of extension %s" +msgstr "%s 확장 모듈의 소유주여야만 합니다" + +#: catalog/aclchk.c:3494 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "%s 외부 데이터 래퍼의 소유주여야 함" + +#: catalog/aclchk.c:3497 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "%s 외부 서버의 소유주여야 함" + +#: catalog/aclchk.c:3500 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "%s 외부 테이블의 소유주여야 함" + +#: catalog/aclchk.c:3503 +#, c-format +msgid "must be owner of function %s" +msgstr "%s 함수의 소유주여야만 합니다" + +#: catalog/aclchk.c:3506 +#, c-format +msgid "must be owner of index %s" +msgstr "%s 인덱스의 소유주여야만 합니다" + +#: catalog/aclchk.c:3509 +#, c-format +msgid "must be owner of language %s" +msgstr "%s 프로시주얼 언어의 소유주여야만 합니다" + +#: catalog/aclchk.c:3512 +#, c-format +msgid "must be owner of large object %s" +msgstr "%s 대형 개체의 소유주여야만 합니다" + +#: catalog/aclchk.c:3515 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "%s 구체화된 뷰의 소유주여야만 합니다" + +#: catalog/aclchk.c:3518 +#, c-format +msgid "must be owner of operator class %s" +msgstr "%s 연산자 클래스의 소유주여야만 합니다" + +#: catalog/aclchk.c:3521 +#, c-format +msgid "must be owner of operator %s" +msgstr "%s 연산자의 소유주여야만 합니다" + +#: catalog/aclchk.c:3524 +#, c-format +msgid "must be owner of operator family %s" +msgstr "%s 연산자 패밀리의 소유주여야 함" + +#: catalog/aclchk.c:3527 +#, c-format +msgid "must be owner of procedure %s" +msgstr "%s 프로시져의 소유주여야만 합니다" + +#: catalog/aclchk.c:3530 +#, c-format +msgid "must be owner of publication %s" +msgstr "%s 발행의 소유주여야만 합니다" + +#: catalog/aclchk.c:3533 +#, c-format +msgid "must be owner of routine %s" +msgstr "%s 루틴의 소유주여야만 합니다" + +#: catalog/aclchk.c:3536 +#, c-format +msgid "must be owner of sequence %s" +msgstr "%s 시퀀스의 소유주여야만 합니다" + +#: catalog/aclchk.c:3539 +#, c-format +msgid "must be owner of subscription %s" +msgstr "%s 구독의 소유주여야만 합니다" + +#: catalog/aclchk.c:3542 +#, c-format +msgid "must be owner of table %s" +msgstr "%s 테이블의 소유주여야만 합니다" + +#: catalog/aclchk.c:3545 +#, c-format +msgid "must be owner of type %s" +msgstr "%s 자료형의 소유주여야만 합니다" + +#: catalog/aclchk.c:3548 +#, c-format +msgid "must be owner of view %s" +msgstr "%s 뷰의 소유주여야만 합니다" + +#: catalog/aclchk.c:3551 +#, c-format +msgid "must be owner of schema %s" +msgstr "%s 스키마(schema)의 소유주여야만 합니다" + +#: catalog/aclchk.c:3554 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "%s 통계정보 개체의 소유주여야만 합니다" + +#: catalog/aclchk.c:3557 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "%s 테이블스페이스의 소유주여야만 합니다" + +#: catalog/aclchk.c:3560 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "%s 전문 검색 구성의 소유주여야 함" + +#: catalog/aclchk.c:3563 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "%s 전문 검색 사전의 소유주여야 함" + +#: catalog/aclchk.c:3577 +#, c-format +msgid "must be owner of relation %s" +msgstr "%s 릴레이션(relation)의 소유주여야만 합니다" + +#: catalog/aclchk.c:3621 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\") 접근 권한 없음" + +#: catalog/aclchk.c:3742 catalog/aclchk.c:3750 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "%d번째 속성(해당 릴레이션 OID: %u)이 없음" + +#: catalog/aclchk.c:3823 catalog/aclchk.c:4733 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "OID %u 릴레이션(relation) 없음" + +#: catalog/aclchk.c:3913 catalog/aclchk.c:5151 +#, c-format +msgid "database with OID %u does not exist" +msgstr "OID %u 데이터베이스 없음" + +#: catalog/aclchk.c:3967 catalog/aclchk.c:4811 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2055 +#, c-format +msgid "function with OID %u does not exist" +msgstr "OID %u 함수 없음" + +#: catalog/aclchk.c:4021 catalog/aclchk.c:4837 +#, c-format +msgid "language with OID %u does not exist" +msgstr "OID %u 언어 없음" + +#: catalog/aclchk.c:4185 catalog/aclchk.c:4909 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "OID %u 스키마 없음" + +#: catalog/aclchk.c:4239 catalog/aclchk.c:4936 utils/adt/genfile.c:686 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "OID %u 테이블스페이스 없음" + +#: catalog/aclchk.c:4298 catalog/aclchk.c:5070 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "OID가 %u인 외부 데이터 래퍼가 없음" + +#: catalog/aclchk.c:4360 catalog/aclchk.c:5097 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "OID가 %u인 외부 서버가 없음" + +#: catalog/aclchk.c:4420 catalog/aclchk.c:4759 utils/cache/typcache.c:378 +#: utils/cache/typcache.c:432 +#, c-format +msgid "type with OID %u does not exist" +msgstr "OID %u 자료형 없음" + +#: catalog/aclchk.c:4785 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "OID %u 연산자 없음" + +#: catalog/aclchk.c:4962 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "OID %u 연산자 클래스 없음" + +#: catalog/aclchk.c:4989 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "OID가 %u인 연산자 패밀리가 없음" + +#: catalog/aclchk.c:5016 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "OID가 %u인 전문 검색 사전이 없음" + +#: catalog/aclchk.c:5043 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "OID가 %u인 텍스트 검색 구성이 없음" + +#: catalog/aclchk.c:5124 commands/event_trigger.c:475 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "OID %u 이벤트 트리거가 없음" + +#: catalog/aclchk.c:5177 commands/collationcmds.c:367 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "OID %u 정렬정의(collation) 없음" + +#: catalog/aclchk.c:5203 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "OID %u 인코딩 변환규칙(conversion) 없음" + +#: catalog/aclchk.c:5244 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "OID %u 확장 모듈이 없음" + +#: catalog/aclchk.c:5271 commands/publicationcmds.c:794 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "OID %u 발행 없음" + +#: catalog/aclchk.c:5297 commands/subscriptioncmds.c:1112 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "OID %u 구독 없음" + +#: catalog/aclchk.c:5323 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "OID %u 통계정보 개체 없음" + +#: catalog/catalog.c:485 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "pg_nextoid() 함수를 호출 하려면 슈퍼유져여야함" + +#: catalog/catalog.c:493 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() 함수는 시스템 카탈로그 대상 전용임" + +#: catalog/catalog.c:498 parser/parse_utilcmd.c:2191 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "\"%s\" 인덱스가 \"%s\" 테이블용이 아님" + +#: catalog/catalog.c:515 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "\"%s\" 칼럼은 oid 자료형이 아님" + +#: catalog/catalog.c:522 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "\"%s\" 인덱스는 \"%s\" 칼럼용 인덱스가 아님" + +#: catalog/dependency.c:823 catalog/dependency.c:1061 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "%s 삭제할 수 없음, %s에서 필요로함" + +#: catalog/dependency.c:825 catalog/dependency.c:1063 +#, c-format +msgid "You can drop %s instead." +msgstr "대신에, drop %s 명령을 사용할 수 있음." + +#: catalog/dependency.c:933 catalog/pg_shdepend.c:640 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "%s 개체는 데이터베이스 시스템에서 필요하기 때문에 삭제 될 수 없음" + +#: catalog/dependency.c:1129 +#, c-format +msgid "drop auto-cascades to %s" +msgstr "%s 개체가 자동으로 덩달아 삭제됨" + +#: catalog/dependency.c:1141 catalog/dependency.c:1150 +#, c-format +msgid "%s depends on %s" +msgstr "%s 의존대상: %s" + +#: catalog/dependency.c:1162 catalog/dependency.c:1171 +#, c-format +msgid "drop cascades to %s" +msgstr "%s 개체가 덩달아 삭제됨" + +#: catalog/dependency.c:1179 catalog/pg_shdepend.c:769 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"%d 개의 기타 개체들도 함께 처리함 (목록은 서버 로그에 기록됨)" + +#: catalog/dependency.c:1191 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "기타 다른 개체들이 이 개체에 의존하고 있어, %s 삭제할 수 없음" + +#: catalog/dependency.c:1193 catalog/dependency.c:1194 +#: catalog/dependency.c:1200 catalog/dependency.c:1201 +#: catalog/dependency.c:1212 catalog/dependency.c:1213 +#: commands/tablecmds.c:1249 commands/tablecmds.c:13016 commands/user.c:1093 +#: commands/view.c:495 libpq/auth.c:334 replication/syncrep.c:1032 +#: storage/lmgr/deadlock.c:1154 storage/lmgr/proc.c:1350 utils/adt/acl.c:5329 +#: utils/adt/jsonfuncs.c:614 utils/adt/jsonfuncs.c:620 utils/misc/guc.c:6771 +#: utils/misc/guc.c:6807 utils/misc/guc.c:6877 utils/misc/guc.c:10947 +#: utils/misc/guc.c:10981 utils/misc/guc.c:11015 utils/misc/guc.c:11049 +#: utils/misc/guc.c:11084 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1195 catalog/dependency.c:1202 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "" +"이 개체와 관계된 모든 개체들을 함께 삭제하려면 DROP ... CASCADE 명령을 사용하" +"십시오" + +#: catalog/dependency.c:1199 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "다른 개체가 원하는 개체를 사용하고 있으므로 해당 개체를 삭제할 수 없음" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1208 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "%d개의 다른 개체에 대한 관련 항목 삭제" + +#: catalog/dependency.c:1875 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "%s 자료형은 여기서 사용할 수 없음" + +#: catalog/heap.c:330 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "\"%s.%s\" 만들 권한이 없음" + +#: catalog/heap.c:332 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "시스템 카탈로그 변경은 현재 허용하지 않습니다." + +#: catalog/heap.c:500 commands/tablecmds.c:2145 commands/tablecmds.c:2745 +#: commands/tablecmds.c:6175 +#, c-format +msgid "tables can have at most %d columns" +msgstr "한 테이블에 지정할 수 있는 최대 열 수는 %d입니다" + +#: catalog/heap.c:518 commands/tablecmds.c:6468 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "\"%s\" 열 이름은 시스템 열 이름과 충돌합니다" + +#: catalog/heap.c:534 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "\"%s\" 칼럼 이름이 여러 번 지정됨" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:609 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "\"%s\" 파티션 키 칼럼은 %s 의사 자료형(pseudo-type)을 사용합니다" + +#: catalog/heap.c:614 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "\"%s\" 칼럼은 %s 의사 자료형(pseudo-type)을 사용합니다" + +#: catalog/heap.c:645 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "%s 복합 자료형은 자기 자신의 구성원으로 만들 수 없음" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:700 +#, c-format +msgid "" +"no collation was derived for partition key column %s with collatable type %s" +msgstr "" +"\"%s\" 파티션 키 칼럼에 사용하는 %s 자료형에서 사용할 정렬규칙을 결정할 수없" +"습니다." + +#: catalog/heap.c:706 commands/createas.c:203 commands/createas.c:486 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "" +"\"%s\" 칼럼에 사용하는 %s 자료형에서 사용할 정렬규칙을 결정할 수 없습니다." + +#: catalog/heap.c:1155 catalog/index.c:865 commands/tablecmds.c:3520 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "\"%s\" 이름의 릴레이션(relation)이 이미 있습니다" + +#: catalog/heap.c:1171 catalog/pg_type.c:428 catalog/pg_type.c:775 +#: commands/typecmds.c:238 commands/typecmds.c:250 commands/typecmds.c:719 +#: commands/typecmds.c:1125 commands/typecmds.c:1337 commands/typecmds.c:2124 +#, c-format +msgid "type \"%s\" already exists" +msgstr "\"%s\" 자료형이 이미 있습니다" + +#: catalog/heap.c:1172 +#, c-format +msgid "" +"A relation has an associated type of the same name, so you must use a name " +"that doesn't conflict with any existing type." +msgstr "" +"하나의 릴레이션은 그 이름과 같은 자료형과 관계합니다. 그래서, 이미 같은 이름" +"의 자료형이 있다면 해당 릴레이션을 만들 수 없습니다. 다른 이름을 사용하세요." + +#: catalog/heap.c:1201 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "이진 업그레이드 작업 때, pg_class 자료 OID 값이 지정되지 않았습니다" + +#: catalog/heap.c:2400 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "\"%s\" 파티션 테이블에는 NO INHERIT 조건을 사용할 수 없음" + +#: catalog/heap.c:2670 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "\"%s\" 이름의 체크 제약 조건이 이미 있습니다" + +#: catalog/heap.c:2840 catalog/index.c:879 catalog/pg_constraint.c:668 +#: commands/tablecmds.c:8117 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "" +"\"%s\" 제약 조건이 이미 \"%s\" 릴레이션(relation)에서 사용되고 있습니다" + +#: catalog/heap.c:2847 +#, c-format +msgid "" +"constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "" +"\"%s\" 제약 조건이 비상속 제약 조건과 충돌합니다, 해당 릴레이션: \"%s\"" + +#: catalog/heap.c:2858 +#, c-format +msgid "" +"constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "\"%s\" 제약 조건이 상속 제약 조건과 충돌합니다, 해당 릴레이션: \"%s\"" + +#: catalog/heap.c:2868 +#, c-format +msgid "" +"constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "" +"\"%s\" 제약 조건이 NOT VALID 제약 조건과 충돌합니다, 해당 릴레이션: \"%s\"" + +#: catalog/heap.c:2873 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "\"%s\" 제약 조건을 상속된 정의와 병합하는 중" + +#: catalog/heap.c:2975 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "\"%s\" 계산된 칼럼은 칼럼 생성 표현식에서는 사용될 수 없음" + +#: catalog/heap.c:2977 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "계산된 칼럼은 다른 계산된 칼럼을 참조할 수 없음" + +#: catalog/heap.c:3029 +#, c-format +msgid "generation expression is not immutable" +msgstr "생성 표현식은 불변형일 수 없음" + +#: catalog/heap.c:3057 rewrite/rewriteHandler.c:1192 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "" +"\"%s\" 칼럼의 자료형은 %s 인데, default 표현식에서는 %s 자료형을 사용했습니다" + +#: catalog/heap.c:3062 commands/prepare.c:367 parser/parse_node.c:412 +#: parser/parse_target.c:589 parser/parse_target.c:869 +#: parser/parse_target.c:879 rewrite/rewriteHandler.c:1197 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "다시 정의하거나 형변화자를 사용해보십시오" + +#: catalog/heap.c:3109 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "\"%s\" 테이블만이 체크 제약 조건에서 참조될 수 있습니다" + +#: catalog/heap.c:3366 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "ON COMMIT 및 외래 키 조합이 지원되지 않음" + +#: catalog/heap.c:3367 +#, c-format +msgid "" +"Table \"%s\" references \"%s\", but they do not have the same ON COMMIT " +"setting." +msgstr "" +"\"%s\" 테이블에서 \"%s\" 테이블을 참조하는데 ON COMMIT 설정이 같지 않습니다." + +#: catalog/heap.c:3372 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "" +"_^_ 테이블 내용을 모두 삭제할 수 없음, 참조키(foreign key) 제약 조건 안에서" + +#: catalog/heap.c:3373 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "\"%s\" 테이블은 \"%s\" 개체를 참조합니다." + +#: catalog/heap.c:3375 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "" +"\"%s\" 테이블도 함께 자료를 지우거나, TRUNCATE ... CASCADE 구문을 사용하세요." + +#: catalog/index.c:219 parser/parse_utilcmd.c:2097 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "\"%s\" 테이블에는 이미 기본키가 있습니다" + +#: catalog/index.c:237 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "기본기(primary key)를 표현할 수 없음" + +#: catalog/index.c:254 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "\"%s\" 파티션 키 칼럼에 NOT NULL 속성을 지정해야 함" + +#: catalog/index.c:764 catalog/index.c:1843 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "시스템 카탈로그 테이블에는 사용자 정의 인덱스를 지정할 수 없습니다" + +#: catalog/index.c:804 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "\"%s\" 연산자 클래스용으로 자동 결정 가능한 정렬 규칙은 지원하지 않음" + +#: catalog/index.c:819 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "시스템 카탈로그 테이블은 잠금 없는 인덱스 만들기는 지원하지 않습니다" + +#: catalog/index.c:828 catalog/index.c:1281 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "exclusion 제약 조건용 잠금 없는 인덱스 만들기는 지원하지 않습니다" + +#: catalog/index.c:837 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "" +"공유되는 인덱스들은 initdb 명령으로 데이터베이스 클러스터를 만든 다음에는 만" +"들 수 없습니다" + +#: catalog/index.c:857 commands/createas.c:252 commands/sequence.c:154 +#: parser/parse_utilcmd.c:210 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "\"%s\" 이름의 릴레이션(relation)이 이미 있습니다, 건너뜀" + +#: catalog/index.c:907 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "이진 업그레이드 작업 때, pg_class 인덱스 OID 값이 지정되지 않았습니다" + +#: catalog/index.c:2128 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY 명령은 트랜잭션 내 가장 처음에 있어야 합니다" + +#: catalog/index.c:2859 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "\"%s\" 인덱스를 \"%s\" 테이블에 이어 만드는 중" + +#: catalog/index.c:2864 +#, c-format +msgid "" +"building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "" +"building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "\"%s\" 인덱스를 \"%s\" 테이블에서 만드는 중, 병렬 작업자수: %d" + +#: catalog/index.c:3492 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "임시 테이블의 인덱스 재생성 작업은 다른 세션에서 할 수 없음" + +#: catalog/index.c:3503 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "TOAST 테이블에 딸린 잘못된 인덱스에 대해 재색인 작업을 할 수 없음" + +#: catalog/index.c:3625 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "\"%s\" 인덱스가 다시 만들어졌음" + +#: catalog/index.c:3701 commands/indexcmds.c:3023 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "파티션된 테이블의 REINDEX 작업은 아직 구현되지 않았음, \"%s\" 건너뜀" + +#: catalog/index.c:3756 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "" +"TOAST 테이블에 지정된 유효하지 않은 \"%s.%s\" 인덱스는 재색인 작업을 할 수 없음, 건너뜀" + +#: catalog/namespace.c:257 catalog/namespace.c:461 catalog/namespace.c:553 +#: commands/trigger.c:5043 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "서로 다른 데이터베이스간의 참조는 구현되어있지 않습니다: \"%s.%s.%s\"" + +#: catalog/namespace.c:314 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "임시 테이블은 스키마 이름을 지정할 수 없음" + +#: catalog/namespace.c:395 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "\"%s.%s\" 릴레이션의 잠금 정보를 구할 수 없음" + +#: catalog/namespace.c:400 commands/lockcmds.c:142 commands/lockcmds.c:227 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "\"%s\" 릴레이션의 잠금 정보를 구할 수 없음" + +#: catalog/namespace.c:428 parser/parse_relation.c:1357 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "\"%s.%s\" 이름의 릴레이션(relation)이 없습니다" + +#: catalog/namespace.c:433 parser/parse_relation.c:1370 +#: parser/parse_relation.c:1378 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "\"%s\" 이름의 릴레이션(relation)이 없습니다" + +#: catalog/namespace.c:499 catalog/namespace.c:3030 commands/extension.c:1519 +#: commands/extension.c:1525 +#, c-format +msgid "no schema has been selected to create in" +msgstr "선택된 스키마 없음, 대상:" + +#: catalog/namespace.c:651 catalog/namespace.c:664 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "다른 세션의 임시 스키마 안에는 릴레이션을 만들 수 없음" + +#: catalog/namespace.c:655 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "임시 스키마가 아닌 스키마에 임시 릴레이션을 만들 수 없음" + +#: catalog/namespace.c:670 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "임시 스키마 안에는 임시 릴레이션만 만들 수 있음" + +#: catalog/namespace.c:2222 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "\"%s\" 통계정보 개체가 없음" + +#: catalog/namespace.c:2345 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "\"%s\" 전문 검색 파서가 없음" + +#: catalog/namespace.c:2471 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "\"%s\" 전문 검색 사전이 없음" + +#: catalog/namespace.c:2598 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "\"%s\" 전문 검색 템플릿이 없음" + +#: catalog/namespace.c:2724 commands/tsearchcmds.c:1194 +#: utils/cache/ts_cache.c:617 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "\"%s\" 전문 검색 구성이 없음" + +#: catalog/namespace.c:2837 parser/parse_expr.c:872 parser/parse_target.c:1228 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "서로 다른 데이터베이스간의 참조는 구현되어있지 않습니다: %s" + +#: catalog/namespace.c:2843 parser/parse_expr.c:879 parser/parse_target.c:1235 +#: gram.y:14981 gram.y:16435 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "적당하지 않은 qualified 이름 입니다 (너무 많은 점이 있네요): %s" + +#: catalog/namespace.c:2973 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "임시 스키마로(에서) 개체를 이동할 수 없습니다" + +#: catalog/namespace.c:2979 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "TOAST 스키마로(에서) 개체를 이동할 수 없습니다" + +#: catalog/namespace.c:3052 commands/schemacmds.c:256 commands/schemacmds.c:336 +#: commands/tablecmds.c:1194 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "\"%s\" 스키마(schema) 없음" + +#: catalog/namespace.c:3083 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "" +"적당하지 않은 릴레이션(relation) 이름 입니다 (너무 많은 점이 있네요): %s" + +#: catalog/namespace.c:3646 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "\"%s\" 정렬정의(collation)가 \"%s\" 인코딩에서는 쓸 수 없음" + +#: catalog/namespace.c:3701 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "\"%s\" 문자코드변환규칙(conversion) 없음" + +#: catalog/namespace.c:3965 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "\"%s\" 데이터베이스에서 임시 파일을 만들 권한이 없음" + +#: catalog/namespace.c:3981 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "복구 작업 중에는 임시 테이블을 만들 수 없음" + +#: catalog/namespace.c:3987 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "병렬 작업 중에 임시 테이블을 만들 수 없음" + +#: catalog/namespace.c:4286 commands/tablespace.c:1205 commands/variable.c:64 +#: utils/misc/guc.c:11116 utils/misc/guc.c:11194 +#, c-format +msgid "List syntax is invalid." +msgstr "목록 문법이 틀렸습니다." + +#: catalog/objectaddress.c:1275 catalog/pg_publication.c:57 +#: commands/policy.c:95 commands/policy.c:375 commands/policy.c:465 +#: commands/tablecmds.c:230 commands/tablecmds.c:272 commands/tablecmds.c:1989 +#: commands/tablecmds.c:5626 commands/tablecmds.c:11089 +#, c-format +msgid "\"%s\" is not a table" +msgstr "\"%s\" 개체는 테이블이 아님" + +#: catalog/objectaddress.c:1282 commands/tablecmds.c:242 +#: commands/tablecmds.c:5656 commands/tablecmds.c:15711 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "\"%s\" 개체는 뷰가 아님" + +#: catalog/objectaddress.c:1289 commands/matview.c:175 commands/tablecmds.c:248 +#: commands/tablecmds.c:15716 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "\"%s\" 개체는 구체화된 뷰(materialized view)가 아닙니다" + +#: catalog/objectaddress.c:1296 commands/tablecmds.c:266 +#: commands/tablecmds.c:5659 commands/tablecmds.c:15721 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "\"%s\" 개체는 외부 테이블이 아님" + +#: catalog/objectaddress.c:1337 +#, c-format +msgid "must specify relation and object name" +msgstr "릴레이션과 개체 이름을 지정해야 합니다" + +#: catalog/objectaddress.c:1413 catalog/objectaddress.c:1466 +#, c-format +msgid "column name must be qualified" +msgstr "칼럼 이름으로 적당하지 않습니다" + +#: catalog/objectaddress.c:1513 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")의 기본값을 지정하지 않았음" + +#: catalog/objectaddress.c:1550 commands/functioncmds.c:133 +#: commands/tablecmds.c:258 commands/typecmds.c:263 commands/typecmds.c:3275 +#: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:845 +#: utils/adt/acl.c:4436 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "\"%s\" 자료형 없음" + +#: catalog/objectaddress.c:1669 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "%d (%s, %s) 연산자(대상 %s) 없음" + +#: catalog/objectaddress.c:1700 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "%d (%s, %s) 함수(대상 %s) 없음" + +#: catalog/objectaddress.c:1751 catalog/objectaddress.c:1777 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "\"%s\" 사용자에 대한 사용자 맵핑 정보(대상 서버: \"%s\")가 없음" + +#: catalog/objectaddress.c:1766 commands/foreigncmds.c:430 +#: commands/foreigncmds.c:1012 commands/foreigncmds.c:1395 +#: foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "\"%s\" 이름의 서버가 없음" + +#: catalog/objectaddress.c:1833 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "\"%s\" 발행 릴레이션은 \"%s\" 발행에 없습니다." + +#: catalog/objectaddress.c:1895 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "알 수 없는 기본 ACL 개체 타입 \"%c\"" + +#: catalog/objectaddress.c:1896 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "유효한 개체 형태는 \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." + +#: catalog/objectaddress.c:1947 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "\"%s\" 사용자용 기본 ACL 없음. (해당 스키마: \"%s\", 해당 개체: %s)" + +#: catalog/objectaddress.c:1952 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "\"%s\" 사용자용 기본 ACL 없음. (해당 개체: %s)" + +#: catalog/objectaddress.c:1979 catalog/objectaddress.c:2037 +#: catalog/objectaddress.c:2094 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "이름이나 인자 목록에는 null이 포함되지 않아야 함" + +#: catalog/objectaddress.c:2013 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "\"%s\" 형 지원하지 않음" + +#: catalog/objectaddress.c:2033 catalog/objectaddress.c:2051 +#: catalog/objectaddress.c:2192 +#, c-format +msgid "name list length must be exactly %d" +msgstr "이름 목록 길이는 %d 이어야 합니다." + +#: catalog/objectaddress.c:2055 +#, c-format +msgid "large object OID may not be null" +msgstr "대형 개체 OID는 null 값을 사용할 수 없음" + +#: catalog/objectaddress.c:2064 catalog/objectaddress.c:2127 +#: catalog/objectaddress.c:2134 +#, c-format +msgid "name list length must be at least %d" +msgstr "이름 목록 길이는 적어도 %d 개 이상이어야 함" + +#: catalog/objectaddress.c:2120 catalog/objectaddress.c:2141 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "인자 목록은 %d 개여야 함" + +#: catalog/objectaddress.c:2393 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "%u 대경 개체의 소유주여야만 합니다" + +#: catalog/objectaddress.c:2408 commands/functioncmds.c:1445 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "%s, %s 자료형의 소유주여야합니다" + +#: catalog/objectaddress.c:2458 catalog/objectaddress.c:2475 +#, c-format +msgid "must be superuser" +msgstr "슈퍼유져여야함" + +#: catalog/objectaddress.c:2465 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "CREATEROLE 권한이 있어야 함" + +#: catalog/objectaddress.c:2544 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "알 수 없는 개체 형태 \"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2772 +#, c-format +msgid "column %s of %s" +msgstr " %s 칼럼(%s 의)" + +#: catalog/objectaddress.c:2782 +#, c-format +msgid "function %s" +msgstr "%s 함수" + +#: catalog/objectaddress.c:2787 +#, c-format +msgid "type %s" +msgstr "%s 자료형" + +#: catalog/objectaddress.c:2817 +#, c-format +msgid "cast from %s to %s" +msgstr "%s 자료형을 %s 자료형으로 바꾸는 작업" + +#: catalog/objectaddress.c:2845 +#, c-format +msgid "collation %s" +msgstr "collation %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2871 +#, c-format +msgid "constraint %s on %s" +msgstr "%s 제약 조건(해당 개체: %s)" + +#: catalog/objectaddress.c:2877 +#, c-format +msgid "constraint %s" +msgstr "%s 제약 조건" + +#: catalog/objectaddress.c:2904 +#, c-format +msgid "conversion %s" +msgstr "%s 문자코드변환규칙" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2943 +#, c-format +msgid "default value for %s" +msgstr "%s 용 기본값" + +#: catalog/objectaddress.c:2952 +#, c-format +msgid "language %s" +msgstr "프로시주얼 언어 %s" + +#: catalog/objectaddress.c:2957 +#, c-format +msgid "large object %u" +msgstr "%u 대형 개체" + +#: catalog/objectaddress.c:2962 +#, c-format +msgid "operator %s" +msgstr "%s 연산자" + +#: catalog/objectaddress.c:2994 +#, c-format +msgid "operator class %s for access method %s" +msgstr "%s 연산자 클래스, %s 인덱스 액세스 방법" + +#: catalog/objectaddress.c:3017 +#, c-format +msgid "access method %s" +msgstr "%s 접근 방법" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3059 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "%d (%s, %s) 연산자 (연산자 패밀리: %s): %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3109 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "%d (%s, %s) 함수 (연산자 패밀리: %s): %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3153 +#, c-format +msgid "rule %s on %s" +msgstr "%s 룰(rule), 해당 테이블: %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3191 +#, c-format +msgid "trigger %s on %s" +msgstr "%s 트리거, 해당 테이블: %s" + +#: catalog/objectaddress.c:3207 +#, c-format +msgid "schema %s" +msgstr "%s 스키마" + +#: catalog/objectaddress.c:3230 +#, c-format +msgid "statistics object %s" +msgstr "%s 통계정보 개체" + +#: catalog/objectaddress.c:3257 +#, c-format +msgid "text search parser %s" +msgstr "%s 전문 검색 파서" + +#: catalog/objectaddress.c:3283 +#, c-format +msgid "text search dictionary %s" +msgstr "%s 전문 검색 사전" + +#: catalog/objectaddress.c:3309 +#, c-format +msgid "text search template %s" +msgstr "%s 전문 검색 템플릿" + +#: catalog/objectaddress.c:3335 +#, c-format +msgid "text search configuration %s" +msgstr "%s 전문 검색 구성" + +#: catalog/objectaddress.c:3344 +#, c-format +msgid "role %s" +msgstr "%s 롤" + +#: catalog/objectaddress.c:3357 +#, c-format +msgid "database %s" +msgstr "%s 데이터베이스" + +#: catalog/objectaddress.c:3369 +#, c-format +msgid "tablespace %s" +msgstr "%s 테이블스페이스" + +#: catalog/objectaddress.c:3378 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "%s 외부 데이터 래퍼" + +#: catalog/objectaddress.c:3387 +#, c-format +msgid "server %s" +msgstr "%s 서버" + +#: catalog/objectaddress.c:3415 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "%s에 대한 사용자 매핑, 해당 서버: %s" + +#: catalog/objectaddress.c:3460 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "" +"%s 롤(해당 스키마: %s)이 새 테이블을 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3464 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "%s 롤이 새 테이블을 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3470 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "" +"%s 롤(해당 스키마: %s)이 새 시퀀스를 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3474 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "%s 롤이 새 시퀀스를 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3480 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "%s 롤(해당 스키마: %s)이 새 함수를 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3484 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "%s 롤이 새 함수를 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3490 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "" +"%s 롤(해당 스키마: %s)이 새 자료형을 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3494 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "%s 롤이 새 자료형을 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3500 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "%s 롤이 새 시퀀스를 만들 때 기본적으로 지정할 접근 권한" + +#: catalog/objectaddress.c:3507 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "%s 롤(해당 스키마: %s)의 기본 접근 권한" + +#: catalog/objectaddress.c:3511 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "%s 롤의 기본 접근 권한" + +#: catalog/objectaddress.c:3529 +#, c-format +msgid "extension %s" +msgstr "%s 확장 모듈" + +#: catalog/objectaddress.c:3542 +#, c-format +msgid "event trigger %s" +msgstr "%s 이벤트 트리거" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3578 +#, c-format +msgid "policy %s on %s" +msgstr "%s 정책(%s 의)" + +#: catalog/objectaddress.c:3588 +#, c-format +msgid "publication %s" +msgstr "%s 발행" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3614 +#, c-format +msgid "publication of %s in publication %s" +msgstr "%s 발행 (해당 발행이름: %s)" + +#: catalog/objectaddress.c:3623 +#, c-format +msgid "subscription %s" +msgstr "%s 구독" + +#: catalog/objectaddress.c:3642 +#, c-format +msgid "transform for %s language %s" +msgstr "%s 형 변환자, 대상언어: %s" + +#: catalog/objectaddress.c:3705 +#, c-format +msgid "table %s" +msgstr "%s 테이블" + +#: catalog/objectaddress.c:3710 +#, c-format +msgid "index %s" +msgstr "%s 인덱스" + +#: catalog/objectaddress.c:3714 +#, c-format +msgid "sequence %s" +msgstr "%s 시퀀스" + +#: catalog/objectaddress.c:3718 +#, c-format +msgid "toast table %s" +msgstr "%s 토스트 테이블" + +#: catalog/objectaddress.c:3722 +#, c-format +msgid "view %s" +msgstr "%s 뷰" + +#: catalog/objectaddress.c:3726 +#, c-format +msgid "materialized view %s" +msgstr "%s 구체화된 뷰" + +#: catalog/objectaddress.c:3730 +#, c-format +msgid "composite type %s" +msgstr "%s 복합 자료형" + +#: catalog/objectaddress.c:3734 +#, c-format +msgid "foreign table %s" +msgstr "%s 외부 테이블" + +#: catalog/objectaddress.c:3739 +#, c-format +msgid "relation %s" +msgstr "%s 릴레이션" + +#: catalog/objectaddress.c:3776 +#, c-format +msgid "operator family %s for access method %s" +msgstr "%s 연산자 페밀리, 접근 방법: %s" + +#: catalog/pg_aggregate.c:128 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "집계 함수에는 %d개 이상의 인자를 사용할 수 없음" + +#: catalog/pg_aggregate.c:143 catalog/pg_aggregate.c:157 +#, c-format +msgid "cannot determine transition data type" +msgstr "처리할(변환할) 자료형을 결정할 수 없음" + +#: catalog/pg_aggregate.c:172 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "variadic 순서있는 세트 집계함수는 VARIADIC ANY 형을 사용해야 합니다" + +#: catalog/pg_aggregate.c:198 +#, c-format +msgid "" +"a hypothetical-set aggregate must have direct arguments matching its " +"aggregated arguments" +msgstr "" + +#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "%s 이름의 transition 함수의 리턴 자료형이 %s 형이 아닙니다" + +#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#, c-format +msgid "" +"must not omit initial value when transition function is strict and " +"transition type is not compatible with input type" +msgstr "" +"변환 함수가 엄격하고 변환 형식이 입력 형식과 호환되지 않는 경우 초기값을 생략" +"하면 안됨" + +#: catalog/pg_aggregate.c:334 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "%s inverse transition 함수의 반환 자료형이 %s 형이 아닙니다." + +#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2852 +#, c-format +msgid "" +"strictness of aggregate's forward and inverse transition functions must match" +msgstr "" + +#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:553 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "부가 인자를 쓰는 마침 함수는 STRICT 옵션이 없어야 함" + +#: catalog/pg_aggregate.c:426 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "%s combine 함수의 반환 자료형이 %s 형이 아닙니다" + +#: catalog/pg_aggregate.c:438 executor/nodeAgg.c:4177 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "" +"%s 자료형을 전달 값으로 사용하는 조합 함수는 STRICT 속성을 가져야 합니다" + +#: catalog/pg_aggregate.c:457 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "%s serialization 함수의 반환 자료형이 %s 형이 아닙니다." + +#: catalog/pg_aggregate.c:478 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "%s deserialization 함수의 반환 자료형이 %s 형이 아닙니다" + +#: catalog/pg_aggregate.c:497 catalog/pg_proc.c:186 catalog/pg_proc.c:220 +#, c-format +msgid "cannot determine result data type" +msgstr "결과 자료형을 결정할 수 없음" + +#: catalog/pg_aggregate.c:512 catalog/pg_proc.c:199 catalog/pg_proc.c:228 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "\"internal\" 의사-자료형의 사용이 안전하지 않습니다" + +#: catalog/pg_aggregate.c:566 +#, c-format +msgid "" +"moving-aggregate implementation returns type %s, but plain implementation " +"returns type %s" +msgstr "" + +#: catalog/pg_aggregate.c:577 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "정렬 연산자는 단일 인자 집계에만 지정할 수 있음" + +#: catalog/pg_aggregate.c:704 catalog/pg_proc.c:374 +#, c-format +msgid "cannot change routine kind" +msgstr "루틴 종류를 바꿀 수 없음" + +#: catalog/pg_aggregate.c:706 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "\"%s\" 개체는 ordinary 집계 함수입니다" + +#: catalog/pg_aggregate.c:708 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "\"%s\" 개체는 정렬된 집합 집계 함수입니다" + +#: catalog/pg_aggregate.c:710 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "" + +#: catalog/pg_aggregate.c:715 +#, c-format +msgid "cannot change number of direct arguments of an aggregate function" +msgstr "집계 함수의 direct 인자 번호는 바꿀 수 없음" + +#: catalog/pg_aggregate.c:870 commands/functioncmds.c:667 +#: commands/typecmds.c:1658 commands/typecmds.c:1704 commands/typecmds.c:1756 +#: commands/typecmds.c:1793 commands/typecmds.c:1827 commands/typecmds.c:1861 +#: commands/typecmds.c:1895 commands/typecmds.c:1972 commands/typecmds.c:2014 +#: parser/parse_func.c:414 parser/parse_func.c:443 parser/parse_func.c:468 +#: parser/parse_func.c:482 parser/parse_func.c:602 parser/parse_func.c:622 +#: parser/parse_func.c:2129 parser/parse_func.c:2320 +#, c-format +msgid "function %s does not exist" +msgstr "%s 이름의 함수가 없음" + +#: catalog/pg_aggregate.c:876 +#, c-format +msgid "function %s returns a set" +msgstr "%s 함수는 한 set을 리턴함" + +#: catalog/pg_aggregate.c:891 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "%s 함수가 이 집계작업에 사용되려면 VARIADIC ANY 형을 수용해야 합니다." + +#: catalog/pg_aggregate.c:915 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "%s 함수는 run-time type coercion을 필요로 함" + +#: catalog/pg_cast.c:67 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "%s 형에서 %s 형으로 변환하는 형변환 규칙(cast)이 이미 있습니다" + +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "\"%s\" 이름의 정렬규칙이 이미 있습니다, 건너뜀" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "\"%s\" 정렬규칙이 \"%s\" 인코딩에 이미 지정되어 있습니다, 건너뜀" + +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "\"%s\" 정렬규칙이 이미 있습니다" + +#: catalog/pg_collation.c:105 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "\"%s\" 정렬규칙이 \"%s\" 인코딩에 이미 지정되어 있습니다" + +#: catalog/pg_constraint.c:676 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "\"%s\" 제약 조건이 %s 도메인에 이미 지정되어 있습니다" + +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "\"%s\" 제약 조건은 \"%s\" 테이블에 없음" + +#: catalog/pg_constraint.c:1056 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "\"%s\" 제약 조건은 %s 도메인에 없음" + +#: catalog/pg_conversion.c:67 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "\"%s\" 이름의 변환규칙(conversion)이 이미 있음" + +#: catalog/pg_conversion.c:80 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "%s 코드에서 %s 코드로 변환하는 기본 변환규칙(conversion)은 이미 있음" + +#: catalog/pg_depend.c:162 commands/extension.c:3324 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "%s 개체는 \"%s\" 확장모듈에 이미 구성원입니다" + +#: catalog/pg_depend.c:538 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "%s 의존개체들은 시스템 개체이기 때문에 삭제 될 수 없습니다" + +#: catalog/pg_enum.c:127 catalog/pg_enum.c:230 catalog/pg_enum.c:525 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "\"%s\" 열거형 라벨이 잘못됨" + +#: catalog/pg_enum.c:128 catalog/pg_enum.c:231 catalog/pg_enum.c:526 +#, c-format +msgid "Labels must be %d characters or less." +msgstr "라벨은 %d자 이하여야 합니다." + +#: catalog/pg_enum.c:259 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "\"%s\" 이름의 열거형 라벨이 이미 있음, 건너뜀" + +#: catalog/pg_enum.c:266 catalog/pg_enum.c:569 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "\"%s\" 이름의 열거형 라벨이 이미 있음" + +#: catalog/pg_enum.c:321 catalog/pg_enum.c:564 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "\"%s\" 열거형 라벨이 없음" + +#: catalog/pg_enum.c:379 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "이진 업그레이드 작업 때 pg_enum OID 값이 지정되지 않았습니다" + +#: catalog/pg_enum.c:389 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "" +"ALTER TYPE ADD BEFORE/AFTER 구문은 이진 업그레이드 작업에서 호환하지 않습니다" + +#: catalog/pg_namespace.c:64 commands/schemacmds.c:265 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "\"%s\" 이름의 스키마(schema)가 이미 있음" + +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "\"%s\" 타당한 연산자 이름이 아님" + +#: catalog/pg_operator.c:370 +#, c-format +msgid "only binary operators can have commutators" +msgstr "_^_ 바이너리 연산자만이 commutator를 가질 수 있음" + +#: catalog/pg_operator.c:374 commands/operatorcmds.c:495 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "_^_ 바이너리 연산자만이 join selectivity를 가질 수 있음" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can merge join" +msgstr "_^_ 바이너리 연산자만이 merge join할 수 있음" + +#: catalog/pg_operator.c:382 +#, c-format +msgid "only binary operators can hash" +msgstr "_^_ 바이너리 연산자만이 해시할 수 있음" + +#: catalog/pg_operator.c:393 +#, c-format +msgid "only boolean operators can have negators" +msgstr "부울 연산자만 부정어를 포함할 수 있음" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:503 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "부울 연산자만 제한 선택을 포함할 수 있음" + +#: catalog/pg_operator.c:401 commands/operatorcmds.c:507 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "부울 연산자만 조인 선택을 포함할 수 있음" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can merge join" +msgstr "부울 연산자만 머지 조인을 지정할 수 있음" + +#: catalog/pg_operator.c:409 +#, c-format +msgid "only boolean operators can hash" +msgstr "부울 연산자만 해시를 지정할 수 있음" + +#: catalog/pg_operator.c:421 +#, c-format +msgid "operator %s already exists" +msgstr "%s 연산자가 이미 있음" + +#: catalog/pg_operator.c:621 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "연산자는 자신의 negator나 sort 연산자가 될 수 없습니다" + +#: catalog/pg_proc.c:127 parser/parse_func.c:2191 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "함수는 %d개 이상의 인자를 사용할 수 없음" + +#: catalog/pg_proc.c:364 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "이미 같은 인자 자료형을 사용하는 \"%s\" 함수가 있습니다" + +#: catalog/pg_proc.c:376 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" 개체는 집계 함수입니다" + +#: catalog/pg_proc.c:378 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\" 개체는 함수입니다." + +#: catalog/pg_proc.c:380 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\" 개체는 프로시져입니다." + +#: catalog/pg_proc.c:382 +#, c-format +msgid "\"%s\" is a window function." +msgstr "\"%s\" 개체는 윈도우 함수입니다." + +#: catalog/pg_proc.c:402 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "프로시져는 출력 매개 변수를 사용하도록 변경 할 수 없음" + +#: catalog/pg_proc.c:403 catalog/pg_proc.c:433 +#, c-format +msgid "cannot change return type of existing function" +msgstr "이미 있는 함수의 리턴 자료형은 바꿀 수 없습니다" + +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:409 catalog/pg_proc.c:436 catalog/pg_proc.c:481 +#: catalog/pg_proc.c:507 catalog/pg_proc.c:533 +#, c-format +msgid "Use %s %s first." +msgstr "먼저 %s %s 명령을 사용하세요." + +#: catalog/pg_proc.c:434 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "OUT 매개 변수에 정의된 행 형식이 다릅니다." + +#: catalog/pg_proc.c:478 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "\"%s\" 입력 매개 변수 이름을 바꿀 수 없음" + +#: catalog/pg_proc.c:505 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "기존 함수에서 매개 변수 기본 값을 제거할 수 없음" + +#: catalog/pg_proc.c:531 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "기존 매개 변수 기본 값의 데이터 형식을 바꿀 수 없음" + +#: catalog/pg_proc.c:748 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "\"%s\" 이름의 내장 함수가 없음" + +#: catalog/pg_proc.c:846 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "SQL 함수는 %s 자료형을 리턴할 수 없음" + +#: catalog/pg_proc.c:861 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "SQL 함수의 인자로 %s 자료형은 사용될 수 없습니다" + +#: catalog/pg_proc.c:954 executor/functions.c:1446 +#, c-format +msgid "SQL function \"%s\"" +msgstr "\"%s\" SQL 함수" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Only tables can be added to publications." +msgstr "테이블 개체만 발행에 추가할 수 있습니다." + +#: catalog/pg_publication.c:65 +#, c-format +msgid "\"%s\" is a system table" +msgstr "\"%s\" 개체는 시스템 테이블입니다." + +#: catalog/pg_publication.c:67 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "시스템 테이블은 발행에 추가할 수 없습니다." + +#: catalog/pg_publication.c:73 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "\"%s\" 테이블은 복제될 수 없음" + +#: catalog/pg_publication.c:75 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "임시 테이블, unlogged 테이블은 복제될 수 없음" + +#: catalog/pg_publication.c:174 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "\"%s\" 릴레이션은 이미 \"%s\" 발행에 포함되어 있습니다" + +#: catalog/pg_publication.c:470 commands/publicationcmds.c:451 +#: commands/publicationcmds.c:762 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "\"%s\" 이름의 발행은 없습니다" + +#: catalog/pg_shdepend.c:776 +#, c-format +msgid "" +"\n" +"and objects in %d other database (see server log for list)" +msgid_plural "" +"\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "" + +#: catalog/pg_shdepend.c:1082 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "%u 롤이 동시에 삭제되었음" + +#: catalog/pg_shdepend.c:1101 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "%u 테이블스페이스는 현재 삭제되었습니다" + +#: catalog/pg_shdepend.c:1116 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "%u 데이터베이스는 현재 삭제되었습니다" + +#: catalog/pg_shdepend.c:1161 +#, c-format +msgid "owner of %s" +msgstr "%s 개체의 소유주" + +#: catalog/pg_shdepend.c:1163 +#, c-format +msgid "privileges for %s" +msgstr "\"%s\"에 대한 권한" + +#: catalog/pg_shdepend.c:1165 +#, c-format +msgid "target of %s" +msgstr "%s 개체 대상" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1173 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%d 개체(데이터베이스: %s)" + +#: catalog/pg_shdepend.c:1284 +#, c-format +msgid "" +"cannot drop objects owned by %s because they are required by the database " +"system" +msgstr "" +"%s 소유주의 개체 삭제는 그 데이터베이스 시스템에서 필요하기 때문에 삭제 될 " +"수 없음" + +#: catalog/pg_shdepend.c:1431 +#, c-format +msgid "" +"cannot reassign ownership of objects owned by %s because they are required " +"by the database system" +msgstr "" +"%s 소유주의 개체 삭제는 그 데이터베이스 시스템에서 필요하기 때문에 삭제 될 " +"수 없음" + +#: catalog/pg_subscription.c:171 commands/subscriptioncmds.c:644 +#: commands/subscriptioncmds.c:858 commands/subscriptioncmds.c:1080 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "\"%s\" 이름의 구독은 없습니다." + +#: catalog/pg_type.c:131 catalog/pg_type.c:468 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "이진 업그레이드 작업 때 pg_type OID 값이 지정되지 않았습니다" + +#: catalog/pg_type.c:249 +#, c-format +msgid "invalid type internal size %d" +msgstr "잘못된 자료형의 내부 크기 %d" + +#: catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:281 +#: catalog/pg_type.c:290 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "\"%c\" 정렬은 크기가 %d인 전달 값 형식에 유효하지 않음" + +#: catalog/pg_type.c:297 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "내부 크기 %d은(는) 전달 값 형식에 유효하지 않음" + +#: catalog/pg_type.c:307 catalog/pg_type.c:313 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "\"%c\" 정렬은 가변 길이 형식에 유효하지 않음" + +#: catalog/pg_type.c:321 commands/typecmds.c:3727 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "_^_ 고정크기 자료형은 PLAIN 저장방법을 가져야만 합니다" + +#: catalog/pg_type.c:839 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "\"%s\" 형식의 배열 형식 이름을 생성할 수 없음" + +#: catalog/storage.c:449 storage/buffer/bufmgr.c:933 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "%u 블록(해당 릴레이션: %s)에 잘못된 페이지가 있음" + +#: catalog/toasting.c:106 commands/indexcmds.c:639 commands/tablecmds.c:5638 +#: commands/tablecmds.c:15576 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "\"%s\" 개체는 테이블도 구체화된 뷰도 아닙니다" + +#: commands/aggregatecmds.c:171 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "순서 있는 세트 집계함수만 가설적일 수 있습니다" + +#: commands/aggregatecmds.c:196 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "\"%s\" 속성을 aggregate에서 알 수 없음" + +#: commands/aggregatecmds.c:206 +#, c-format +msgid "aggregate stype must be specified" +msgstr "aggregate stype 값을 지정하셔야합니다" + +#: commands/aggregatecmds.c:210 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "aggregate sfunc 값을 지정하셔야합니다" + +#: commands/aggregatecmds.c:222 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "mstype 옵션을 사용하면 msfunc 옵션도 함께 지정 해야 함" + +#: commands/aggregatecmds.c:226 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "mstype 옵션을 사용하면 minvfunc 옵션도 함께 지정 해야 함" + +#: commands/aggregatecmds.c:233 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "msfunc 옵션은 mstype 옵션과 함께 사용해야 함" + +#: commands/aggregatecmds.c:237 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "minvfunc 옵션은 mstype 옵션과 함께 사용해야 함" + +#: commands/aggregatecmds.c:241 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "mfinalfunc 옵션은 mstype 옵션과 함께 사용해야 함" + +#: commands/aggregatecmds.c:245 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "msspace 옵션은 mstype 옵션과 함께 사용해야 함" + +#: commands/aggregatecmds.c:249 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "minitcond 옵션은 mstype 옵션과 함께 사용해야 함" + +#: commands/aggregatecmds.c:278 +#, c-format +msgid "aggregate input type must be specified" +msgstr "aggregate 입력 자료형을 지정해야 합니다" + +#: commands/aggregatecmds.c:308 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "집계 입력 형식 지정에서 basetype이 중복됨" + +#: commands/aggregatecmds.c:349 commands/aggregatecmds.c:390 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "%s 자료형은 aggregate transition 자료형으로 사용할 수 없습니다" + +#: commands/aggregatecmds.c:361 +#, c-format +msgid "" +"serialization functions may be specified only when the aggregate transition " +"data type is %s" +msgstr "" + +#: commands/aggregatecmds.c:371 +#, c-format +msgid "" +"must specify both or neither of serialization and deserialization functions" +msgstr "" + +#: commands/aggregatecmds.c:436 commands/functioncmds.c:615 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "\"parallel\" 옵션 값은 SAFE, RESTRICTED, UNSAFE 만 지정할 수 있음" + +#: commands/aggregatecmds.c:492 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "\"%s\" 인자값은 READ_ONLY, SHAREABLE, READ_WRITE 셋 중 하나여야 함" + +#: commands/alter.c:84 commands/event_trigger.c:174 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "\"%s\" 이름의 이벤트 트리거가 이미 있음" + +#: commands/alter.c:87 commands/foreigncmds.c:597 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "\"%s\" 이름의 외부 자료 래퍼가 이미 있음" + +#: commands/alter.c:90 commands/foreigncmds.c:903 +#, c-format +msgid "server \"%s\" already exists" +msgstr "\"%s\" 이름의 서버가 이미 있음" + +#: commands/alter.c:93 commands/proclang.c:132 +#, c-format +msgid "language \"%s\" already exists" +msgstr "\"%s\" 이름의 프로시주얼 언어가 이미 있습니다" + +#: commands/alter.c:96 commands/publicationcmds.c:183 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "\"%s\" 이름의 발행이 이미 있습니다" + +#: commands/alter.c:99 commands/subscriptioncmds.c:371 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "\"%s\" 이름의 구독이 이미 있습니다" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 이름의 변환규칙(conversin)이 \"%s\" 스키마에 이미 있습니다" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 이름의 통계정보 개체는 \"%s\" 스키마에 이미 있습니다" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 전문 검색 파서가 \"%s\" 스키마 안에 이미 있음" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 전문 검색 사전이 \"%s\" 스키마 안에 이미 있음" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 전문 검색 템플릿이 \"%s\" 스키마 안에 이미 있음" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 전문 검색 구성이 \"%s\" 스키마 안에 이미 있음" + +#: commands/alter.c:215 +#, c-format +msgid "must be superuser to rename %s" +msgstr "%s 이름 변경 작업은 슈퍼유저만 할 수 있음" + +#: commands/alter.c:744 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "%s의 스키마 지정은 슈퍼유져여야합니다" + +#: commands/amcmds.c:60 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "\"%s\" 접근 방법을 만들 권한이 없습니다." + +#: commands/amcmds.c:62 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "슈퍼유저만 접근 방법을 만들 수 있습니다." + +#: commands/amcmds.c:71 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "\"%s\" 이름의 인덱스 접근 방법이 이미 있습니다." + +#: commands/amcmds.c:130 +#, c-format +msgid "must be superuser to drop access methods" +msgstr "접근 방법은 슈퍼유저만 삭제할 수 있습니다." + +#: commands/amcmds.c:181 commands/indexcmds.c:188 commands/indexcmds.c:790 +#: commands/opclasscmds.c:373 commands/opclasscmds.c:793 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "\"%s\" 인덱스 접근 방법이 없습니다" + +#: commands/amcmds.c:270 +#, c-format +msgid "handler function is not specified" +msgstr "핸들러 함수 부분이 빠졌습니다" + +#: commands/amcmds.c:291 commands/event_trigger.c:183 +#: commands/foreigncmds.c:489 commands/proclang.c:79 commands/trigger.c:687 +#: parser/parse_clause.c:941 +#, c-format +msgid "function %s must return type %s" +msgstr "%s 함수는 %s 자료형을 반환해야 함" + +#: commands/analyze.c:226 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "\"%s\" 건너뜀 --- 외부 테이블은 분석할 수 없음" + +#: commands/analyze.c:243 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "" +"\"%s\" 건너뜀 --- 테이블이 아니거나, 특수 시스템 테이블들은 분석할 수 없음" + +#: commands/analyze.c:329 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "\"%s.%s\" 상속 관계 분석중" + +#: commands/analyze.c:334 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "\"%s.%s\" 자료 통계 수집 중" + +#: commands/analyze.c:394 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "\"%s\" 칼럼이 \"%s\" 릴레이션에서 두 번 이상 사용되었음" + +#: commands/analyze.c:700 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" +msgstr "\"%s.%s.%s\" 테이블의 시스템 사용 자동 분석: %s" + +#: commands/analyze.c:1169 +#, c-format +msgid "" +"\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead " +"rows; %d rows in sample, %.0f estimated total rows" +msgstr "" +"\"%s\": 탐색한 페이지: %d, 전체페이지: %u, 실자료: %.0f개, 쓰레기자료: %.0f" +"개; 표본 추출 자료: %d개, 예상한 총 자료: %.0f개" + +#: commands/analyze.c:1249 +#, c-format +msgid "" +"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " +"contains no child tables" +msgstr "" +"\"%s.%s\" 상속 나무의 통계 수집 건너뜀 --- 이 상속 나무에는 하위 테이블이 없" +"음" + +#: commands/analyze.c:1347 +#, c-format +msgid "" +"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " +"contains no analyzable child tables" +msgstr "" +"\"%s.%s\" 상속 나무의 통계 수집 건너뜀 --- 이 상속 나무에는 통계 수집할 하위 " +"테이블이 없음" + +#: commands/async.c:634 +#, c-format +msgid "channel name cannot be empty" +msgstr "채널 이름은 비워둘 수 없음" + +#: commands/async.c:640 +#, c-format +msgid "channel name too long" +msgstr "채널 이름이 너무 긺" + +# # nonun 부분 begin +#: commands/async.c:645 +#, c-format +msgid "payload string too long" +msgstr "payload 문자열이 너무 긺" + +#: commands/async.c:864 +#, c-format +msgid "" +"cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "" +"LISTEN, UNLISTEN 또는 NOTIFY 옵션으로 실행된 트랜잭션을 PREPARE할 수 없음" + +#: commands/async.c:970 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "NOTIFY 큐에 너무 많은 알림이 있습니다" + +#: commands/async.c:1636 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "NOTIFY 큐 사용률: %.0f%%" + +#: commands/async.c:1638 +#, c-format +msgid "" +"The server process with PID %d is among those with the oldest transactions." +msgstr "%d PID 서버 프로세스가 가장 오래된 트랜잭션을 사용하고 있습니다." + +#: commands/async.c:1641 +#, c-format +msgid "" +"The NOTIFY queue cannot be emptied until that process ends its current " +"transaction." +msgstr "" +"이 프로세스의 현재 트랜잭션을 종료하지 않으면, NOTIFY 큐를 비울 수 없습니다" + +#: commands/cluster.c:125 commands/cluster.c:362 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "다른 세션의 임시 테이블은 cluster 작업을 할 수 없습니다" + +#: commands/cluster.c:133 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "파티션 된 테이블은 클러스터 작업을 할 수 없음" + +#: commands/cluster.c:151 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "\"%s\" 테이블을 위한 previously clustered 인덱스가 없음" + +#: commands/cluster.c:165 commands/tablecmds.c:12853 commands/tablecmds.c:14659 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "\"%s\" 인덱스는 \"%s\" 테이블에 없음" + +#: commands/cluster.c:351 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "공유된 카탈로그는 클러스터 작업을 할 수 없음" + +#: commands/cluster.c:366 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "다른 세션의 임시 테이블은 vacuum 작업을 할 수 없음" + +#: commands/cluster.c:432 commands/tablecmds.c:14669 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "\"%s\" 개체는 \"%s\" 테이블을 위한 인덱스가 아님" + +#: commands/cluster.c:440 +#, c-format +msgid "" +"cannot cluster on index \"%s\" because access method does not support " +"clustering" +msgstr "" +"\"%s\" 인덱스는 자료 액세스 방법이 cluster 작업을 할 수 없는 방법입니다." + +#: commands/cluster.c:452 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "" +"\"%s\" 인덱스가 부분인덱스(partial index)라서 cluster 작업을 할 수 없습니다" + +#: commands/cluster.c:466 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "잘못된 \"%s\" 인덱스에 대해 클러스터링할 수 없음" + +#: commands/cluster.c:490 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "파티션된 테이블 대상으로 인덱스 클러스터 표시를 할 수 없음" + +#: commands/cluster.c:863 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr " \"%s.%s\" 클러스터링 중 (사용 인덱스: \"%s\")" + +#: commands/cluster.c:869 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "순차 탐색과 정렬을 이용해서 \"%s.%s\" 개체 클러스터링 중" + +#: commands/cluster.c:900 +#, c-format +msgid "" +"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "" +"\"%s\": 삭제가능한 %.0f개, 삭제불가능한 %.0f개의 행 버전을 %u 페이지에서 발견" +"했음." + +#: commands/cluster.c:904 +#, c-format +msgid "" +"%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "" +"%.0f 개의 사용하지 않는 로우 버전을 아직 지우지 못했음.\n" +"%s." + +#: commands/collationcmds.c:105 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "\"%s\" 연산자 속성을 처리할 수 없음" + +#: commands/collationcmds.c:148 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "\"default\" 정렬규칙은 복사될 수 없음" + +#: commands/collationcmds.c:181 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "알 수 없는 정렬규칙 제공자 이름: %s" + +#: commands/collationcmds.c:190 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "\"lc_collate\" 옵션을 지정해야 함" + +#: commands/collationcmds.c:195 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "\"lc_ctype\" 옵션을 지정해야 함" + +#: commands/collationcmds.c:205 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "" + +#: commands/collationcmds.c:265 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 정렬규칙(대상 인코딩: \"%s\")이 \"%s\" 스키마 안에 이미 있음" + +#: commands/collationcmds.c:276 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 정렬규칙이 \"%s\" 스키마에 이미 있습니다" + +#: commands/collationcmds.c:324 +#, c-format +msgid "changing version from %s to %s" +msgstr "%s에서 %s 버전으로 바꿉니다" + +#: commands/collationcmds.c:339 +#, c-format +msgid "version has not changed" +msgstr "버전이 바뀌지 않았습니다" + +#: commands/collationcmds.c:470 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "\"%s\" 로케일 이름을 언어 태그로 변환할 수 없음: %s" + +#: commands/collationcmds.c:531 +#, c-format +msgid "must be superuser to import system collations" +msgstr "시스템 정렬규칙을 가져오려면 슈퍼유저여야함" + +#: commands/collationcmds.c:554 commands/copy.c:1894 commands/copy.c:3480 +#: libpq/be-secure-common.c:81 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "\"%s\" 명령을 실행할 수 없음: %m" + +#: commands/collationcmds.c:685 +#, c-format +msgid "no usable system locales were found" +msgstr "사용할 수 있는 시스템 로케일이 없음" + +#: commands/comment.c:61 commands/dbcommands.c:841 commands/dbcommands.c:1037 +#: commands/dbcommands.c:1150 commands/dbcommands.c:1340 +#: commands/dbcommands.c:1588 commands/dbcommands.c:1702 +#: commands/dbcommands.c:2142 utils/init/postinit.c:888 +#: utils/init/postinit.c:993 utils/init/postinit.c:1010 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "\"%s\" 데이터베이스 없음" + +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:957 +#, c-format +msgid "" +"\"%s\" is not a table, view, materialized view, composite type, or foreign " +"table" +msgstr "" +"\"%s\" 개체는 테이블도, 뷰도, 구체화된 뷰도, 복합 자료형도, 외부 테이블도 아" +"닙니다." + +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1923 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "\"%s\" 함수가 트리거 관리자에서 호출되지 않았음" + +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1932 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "AFTER ROW에서 \"%s\" 함수를 실행해야 함" + +#: commands/constraint.c:84 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "INSERT 또는 UPDATE에 대해 \"%s\" 함수를 실행해야 함" + +#: commands/conversioncmds.c:66 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "\"%s\" 원본 인코딩 없음" + +#: commands/conversioncmds.c:73 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "\"%s\" 대상 인코딩 없음" + +#: commands/conversioncmds.c:86 +#, c-format +msgid "encoding conversion to or from \"SQL_ASCII\" is not supported" +msgstr "\"SQL_ASCII\" 인코딩 변환은 지원하지 않습니다." + +#: commands/conversioncmds.c:99 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "%s 인코딩 변환 함수는 %s 형을 반환해야 함" + +#: commands/copy.c:426 commands/copy.c:460 +#, c-format +msgid "COPY BINARY is not supported to stdout or from stdin" +msgstr "COPY BINARY 명령은 stdout, stdin 입출력을 지원하지 않습니다" + +#: commands/copy.c:560 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "COPY 프로그램으로 파일을 쓸 수 없습니다: %m" + +#: commands/copy.c:565 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "COPY 파일로로 파일을 쓸 수 없습니다: %m" + +#: commands/copy.c:578 +#, c-format +msgid "connection lost during COPY to stdout" +msgstr "COPY 명령에서 stdout으로 자료를 내보내는 동안 연결이 끊겼습니다" + +#: commands/copy.c:622 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "COPY 명령에 사용할 파일을 읽을 수 없습니다: %m" + +#: commands/copy.c:640 commands/copy.c:661 commands/copy.c:665 +#: tcop/postgres.c:344 tcop/postgres.c:380 tcop/postgres.c:407 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "열린 트랜잭션과 함께 클라이언트 연결에서 예상치 않은 EOF 발견됨" + +#: commands/copy.c:678 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "COPY 명령에서 stdin으로 자료 가져오기 실패: %s" + +#: commands/copy.c:694 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "" +"COPY 명령으로 stdin으로 자료를 가져오는 동안 예상치 않은 메시지 타입 0x%02X " +"발견됨" + +#: commands/copy.c:861 +#, c-format +msgid "" +"must be superuser or a member of the pg_execute_server_program role to COPY " +"to or from an external program" +msgstr "" +"외부 프로그램을 이용하는 COPY 작업은 슈퍼유저와 pg_execute_server_program 롤 " +"소속원만 허용합니다." + +#: commands/copy.c:862 commands/copy.c:871 commands/copy.c:878 +#, c-format +msgid "" +"Anyone can COPY to stdout or from stdin. psql's \\copy command also works " +"for anyone." +msgstr "일반 사용자인데, 이 작업이 필요하면, psql의 \\copy 명령을 이용하세요" + +#: commands/copy.c:870 +#, c-format +msgid "" +"must be superuser or a member of the pg_read_server_files role to COPY from " +"a file" +msgstr "" +"파일을 읽어 COPY 명령으로 자료를 저장하려면, 슈퍼유저이거나 " +"pg_read_server_files 롤 구성원이어야 합니다." + +#: commands/copy.c:877 +#, c-format +msgid "" +"must be superuser or a member of the pg_write_server_files role to COPY to a " +"file" +msgstr "" +"COPY 명령 결과를 파일로 저장하려면, 슈퍼유저이거나 pg_write_server_files 롤 " +"구성원이어야 합니다." + +#: commands/copy.c:963 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "로우 단위 보안 기능으로 COPY FROM 명령을 사용할 수 없음" + +#: commands/copy.c:964 +#, c-format +msgid "Use INSERT statements instead." +msgstr "대신에 INSERT 구문을 사용하십시오." + +#: commands/copy.c:1146 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "\"%s\" COPY 양식은 지원하지 않음" + +#: commands/copy.c:1217 commands/copy.c:1233 commands/copy.c:1248 +#: commands/copy.c:1270 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "\"%s\" 옵션에 대한 인자는 칼럼 이름 목록이어야 합니다." + +#: commands/copy.c:1285 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "\"%s\" 옵션에 대한 인자는 인코딩 이름이어야 합니다." + +#: commands/copy.c:1292 commands/dbcommands.c:253 commands/dbcommands.c:1536 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "\"%s\" 옵션은 타당하지 않습니다." + +#: commands/copy.c:1304 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "BINARY 모드에서는 DELIMITER 값을 지정할 수 없음" + +#: commands/copy.c:1309 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "BINARY 모드에서는 NULL 값을 지정할 수 없음" + +#: commands/copy.c:1331 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "COPY 구분자는 1바이트의 단일 문자여야 함" + +#: commands/copy.c:1338 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "COPY 명령에서 사용할 칼럼 구분자로 줄바꿈 문자들을 사용할 수 없습니다" + +#: commands/copy.c:1344 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "COPY null 표현에서 줄바꿈 또는 캐리지 리턴을 사용할 수 없음" + +#: commands/copy.c:1361 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "COPY 구분자는 \"%s\"일 수 없음" + +#: commands/copy.c:1367 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "COPY HEADER는 CSV 모드에서만 사용할 수 있음" + +#: commands/copy.c:1373 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "COPY 따옴표는 CSV 모드에서만 사용할 수 있음" + +#: commands/copy.c:1378 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "COPY 따옴표는 1바이트의 단일 문자여야 함" + +#: commands/copy.c:1383 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "COPY 구분자 및 따옴표는 서로 달라야 함" + +#: commands/copy.c:1389 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "COPY 이스케이프는 CSV 모드에서만 사용할 수 있음" + +#: commands/copy.c:1394 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "COPY 이스케이프는 1바이트의 단일 문자여야 함" + +#: commands/copy.c:1400 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "COPY force quote는 CSV 모드에서만 사용할 수 있음" + +#: commands/copy.c:1404 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "COPY force quote는 COPY TO에서만 사용할 수 있음" + +#: commands/copy.c:1410 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "COPY force not null은 CSV 모드에서만 사용할 수 있음" + +#: commands/copy.c:1414 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "COPY force not null은 COPY FROM에서만 사용할 수 있음" + +#: commands/copy.c:1420 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "COPY force null은 CSV 모드에서만 사용할 수 있음" + +#: commands/copy.c:1425 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "COPY force null은 COPY FROM에서만 사용할 수 있음" + +#: commands/copy.c:1431 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "COPY 구분자는 NULL 지정에 표시되지 않아야 함" + +#: commands/copy.c:1438 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "CSV 따옴표는 NULL 지정에 표시되지 않아야 함" + +#: commands/copy.c:1524 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "DO INSTEAD NOTHING 룰(rule)은 COPY 구문에서 지원하지 않습니다." + +#: commands/copy.c:1538 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "선택적 DO INSTEAD 룰은 COPY 구문에서 지원하지 않음" + +#: commands/copy.c:1542 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "DO ALSO 룰(rule)은 COPY 구문에서 지원하지 않습니다." + +#: commands/copy.c:1547 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "다중 구문 DO INSTEAD 룰은 COPY 구문에서 지원하지 않음" + +#: commands/copy.c:1557 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO) 지원하지 않음" + +#: commands/copy.c:1574 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "COPY 쿼리는 RETURNING 절이 있어야 합니다" + +#: commands/copy.c:1603 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "COPY 문에 의해 참조된 릴레이션이 변경 되었음" + +#: commands/copy.c:1662 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "\"%s\" FORCE_QUOTE 칼럼은 COPY에서 참조되지 않음" + +#: commands/copy.c:1685 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "\"%s\" FORCE_NOT_NULL 칼럼은 COPY에서 참조되지 않음" + +#: commands/copy.c:1708 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "\"%s\" FORCE_NULL 칼럼은 COPY에서 참조되지 않음" + +#: commands/copy.c:1774 libpq/be-secure-common.c:105 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "외부 명령으로 파이프를 닫을 수 없음: %m" + +#: commands/copy.c:1789 +#, c-format +msgid "program \"%s\" failed" +msgstr "\"%s\" 프로그램 실패" + +#: commands/copy.c:1840 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "\"%s\" 이름의 개체는 뷰(view)입니다. 자료를 내보낼 수 없습니다" + +#: commands/copy.c:1842 commands/copy.c:1848 commands/copy.c:1854 +#: commands/copy.c:1865 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "COPY (SELECT ...) TO 변형을 시도하십시오." + +#: commands/copy.c:1846 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "\"%s\" 이름의 개체는 구체화된 뷰입니다. 자료를 내보낼 수 없습니다" + +#: commands/copy.c:1852 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "\"%s\" 이름의 개체는 외부 테이블입니다. 자료를 내보낼 수 없습니다" + +#: commands/copy.c:1858 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "\"%s\" 이름의 개체는 시퀀스입니다. 자료를 내보낼 수 없습니다" + +#: commands/copy.c:1863 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "\"%s\" 파티션 된 테이블에서 복사할 수 없음" + +#: commands/copy.c:1869 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "" +"\"%s\" 개체는 테이블이 아닌 릴레이션(relation)이기에 자료를 내보낼 수 없습니" +"다" + +#: commands/copy.c:1909 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "COPY 명령에 사용할 파일 이름으로 상대경로는 사용할 수 없습니다" + +#: commands/copy.c:1928 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "\"%s\" 파일 열기 실패: %m" + +#: commands/copy.c:1931 +#, c-format +msgid "" +"COPY TO instructs the PostgreSQL server process to write a file. You may " +"want a client-side facility such as psql's \\copy." +msgstr "" +"COPY TO 명령은 PostgreSQL 서버 프로세스가 작업하기 때문에, 서버에 그 결과가 " +"저장된다. 클라이언트 쪽에서 그 결과를 저장하려면, psql \\copy 명령으로 처리" +"할 수 있다." + +#: commands/copy.c:1944 commands/copy.c:3511 +#, c-format +msgid "\"%s\" is a directory" +msgstr "\"%s\" 디렉터리임" + +#: commands/copy.c:2246 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "%s 복사, %s번째 줄, %s 열" + +#: commands/copy.c:2250 commands/copy.c:2297 +#, c-format +msgid "COPY %s, line %s" +msgstr "%s 복사, %s번째 줄" + +#: commands/copy.c:2261 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "%s 복사, %s번째 줄, %s 열: \"%s\"" + +#: commands/copy.c:2269 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, %s행, %s 열: null 입력" + +#: commands/copy.c:2291 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "%s 복사, %s번째 줄: \"%s\"" + +#: commands/copy.c:2692 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "\"%s\" 뷰로 복사할 수 없음" + +#: commands/copy.c:2694 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "뷰를 통해 자료를 입력하려면, INSTEAD OF INSERT 트리거를 사용하세요" + +#: commands/copy.c:2698 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "\"%s\" 구체화된 뷰(view)에 복사할 수 없음" + +#: commands/copy.c:2703 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "\"%s\" 시퀀스에 복사할 수 없음" + +#: commands/copy.c:2708 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "\"%s\" 개체는 테이블이 아닌 릴레이션(relation)이기에 복사할 수 없음" + +#: commands/copy.c:2748 +#, c-format +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "파티션 된 테이블에는 COPY FREEZE 수행할 수 없음" + +#: commands/copy.c:2763 +#, c-format +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "" +"먼저 시작한 다른 트랜잭션이 아직 활성 상태여서 COPY FREEZE 작업은 진행할 수 " +"없음" + +#: commands/copy.c:2769 +#, c-format +msgid "" +"cannot perform COPY FREEZE because the table was not created or truncated in " +"the current subtransaction" +msgstr "" +"현재 하위 트랜잭션에서 만들어지거나 비워진 테이블이 아니기 때문에 COPY " +"FREEZE 작업을 할 수 없음" + +#: commands/copy.c:3498 +#, c-format +msgid "" +"COPY FROM instructs the PostgreSQL server process to read a file. You may " +"want a client-side facility such as psql's \\copy." +msgstr "" +"COPY FROM 명령은 PostgreSQL 서버 프로세스가 한 파일을 읽어 처리합니다. 클라이" +"언트 쪽에 있는 파일을 읽어 처리 하려면, psql의 \\copy 내장 명령어를 사용하세" +"요." + +#: commands/copy.c:3526 +#, c-format +msgid "COPY file signature not recognized" +msgstr "COPY 파일 signature 인식되지 않았음" + +#: commands/copy.c:3531 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "COPY 명령에서 잘못된 파일 헤더를 사용함(플래그 빠졌음)" + +#: commands/copy.c:3535 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "COPY 파일 해더 잘못됨 (WITH OIDS)" + +#: commands/copy.c:3540 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "COPY 파일 헤더안에 critical flags 값들을 인식할 수 없음" + +#: commands/copy.c:3546 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "COPY 파일 헤더에 length 값이 빠졌음" + +#: commands/copy.c:3553 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "COPY 파일 헤더에 length 값이 잘못되었음" + +#: commands/copy.c:3672 commands/copy.c:4337 commands/copy.c:4567 +#, c-format +msgid "extra data after last expected column" +msgstr "마지막 칼럼을 초과해서 또 다른 데이터가 있음" + +#: commands/copy.c:3686 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "\"%s\" 칼럼의 자료가 빠졌음" + +#: commands/copy.c:3769 +#, c-format +msgid "received copy data after EOF marker" +msgstr "EOF 표시 뒤에도 복사 데이터를 받았음" + +#: commands/copy.c:3776 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "행(row) 필드 갯수가 %d 임, 예상값은 %d" + +#: commands/copy.c:4096 commands/copy.c:4113 +#, c-format +msgid "literal carriage return found in data" +msgstr "데이터에 carriage return 값이 잘못되었음" + +#: commands/copy.c:4097 commands/copy.c:4114 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "데이터에 carriage return 값 표기가 잘못 되었음" + +#: commands/copy.c:4099 commands/copy.c:4116 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "carriage return값으로 \"\\r\" 문자를 사용하세요" + +#: commands/copy.c:4100 commands/copy.c:4117 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "" +"carriage return 문자를 그대로 적용하려면, quoted CSV 필드를 사용하세요." + +#: commands/copy.c:4129 +#, c-format +msgid "literal newline found in data" +msgstr "데이터에 newline 값이 잘못되었음" + +#: commands/copy.c:4130 +#, c-format +msgid "unquoted newline found in data" +msgstr "데이터에 newline 값이 잘못 되었음" + +#: commands/copy.c:4132 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "newline 값으로 \"\\n\" 문자를 사용하세요" + +#: commands/copy.c:4133 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "newline 문자를 그대로 적용하려면, quoted CSV 필드를 사용하세요." + +#: commands/copy.c:4179 commands/copy.c:4215 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "end-of-copy 마크는 이전 newline 모양가 틀립니다" + +#: commands/copy.c:4188 commands/copy.c:4204 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "end-of-copy 마크가 잘못되었음" + +#: commands/copy.c:4651 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "종료되지 않은 CSV 따옴표 필드" + +#: commands/copy.c:4728 commands/copy.c:4747 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "복사 자료 안에 예상치 않은 EOF 발견" + +#: commands/copy.c:4737 +#, c-format +msgid "invalid field size" +msgstr "잘못된 필드 크기" + +#: commands/copy.c:4760 +#, c-format +msgid "incorrect binary data format" +msgstr "잘못된 바이너리 자료 포맷" + +#: commands/copy.c:5068 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "\"%s\" 칼럼은 미리 계산된 칼럼임" + +#: commands/copy.c:5070 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "미리 계산된 칼럼은 COPY 작업 대상이 아님" + +#: commands/copy.c:5085 commands/indexcmds.c:1699 commands/statscmds.c:217 +#: commands/tablecmds.c:2176 commands/tablecmds.c:2795 +#: commands/tablecmds.c:3182 parser/parse_relation.c:3507 +#: parser/parse_relation.c:3527 utils/adt/tsvector_op.c:2668 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "\"%s\" 이름의 칼럼은 없습니다" + +#: commands/copy.c:5092 commands/tablecmds.c:2202 commands/trigger.c:885 +#: parser/parse_target.c:1052 parser/parse_target.c:1063 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "\"%s\" 칼럼을 하나 이상 지정했음" + +#: commands/createas.c:215 commands/createas.c:497 +#, c-format +msgid "too many column names were specified" +msgstr "너무 많은 칼럼 이름을 지정했습니다." + +#: commands/createas.c:539 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "이 명령을 위한 정책은 아직 구현되어 있지 않습니다" + +#: commands/dbcommands.c:246 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATION 예약어는 이제 더이상 지원하지 않습니다" + +#: commands/dbcommands.c:247 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "대신에 테이블스페이스를 이용하세요." + +#: commands/dbcommands.c:261 +#, c-format +msgid "LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE." +msgstr "LOCALE 값은 LC_COLLATE 또는 LC_CTYPE 값과 함께 지정할 수 없음" + +#: commands/dbcommands.c:279 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%d 값은 잘못된 인코딩 코드임" + +#: commands/dbcommands.c:290 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%s 이름은 잘못된 인코딩 이름임" + +#: commands/dbcommands.c:314 commands/dbcommands.c:1569 commands/user.c:275 +#: commands/user.c:691 +#, c-format +msgid "invalid connection limit: %d" +msgstr "잘못된 연결 제한: %d" + +#: commands/dbcommands.c:333 +#, c-format +msgid "permission denied to create database" +msgstr "데이터베이스를 만들 권한이 없음" + +#: commands/dbcommands.c:356 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "\"%s\" 템플릿 데이터베이스 없음" + +#: commands/dbcommands.c:368 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "\"%s\" 데이터베이스를 복사할 권한이 없음" + +#: commands/dbcommands.c:384 +#, c-format +msgid "invalid server encoding %d" +msgstr "잘못된 서버 인코딩 %d" + +#: commands/dbcommands.c:390 commands/dbcommands.c:395 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "\"%s\" 로케일 이름이 잘못됨" + +#: commands/dbcommands.c:415 +#, c-format +msgid "" +"new encoding (%s) is incompatible with the encoding of the template database " +"(%s)" +msgstr "새 인코딩(%s)이 템플릿 데이터베이스의 인코딩(%s)과 호환되지 않음" + +#: commands/dbcommands.c:418 +#, c-format +msgid "" +"Use the same encoding as in the template database, or use template0 as " +"template." +msgstr "" +"템플릿 데이터베이스와 동일한 인코딩을 사용하거나 template0을 템플릿으로 사용" +"하십시오." + +#: commands/dbcommands.c:423 +#, c-format +msgid "" +"new collation (%s) is incompatible with the collation of the template " +"database (%s)" +msgstr "" +"새 데이터 정렬 규칙 (%s)이 템플릿 데이터베이스의 데이터 정렬 규칙(%s)과 호환" +"되지 않음" + +#: commands/dbcommands.c:425 +#, c-format +msgid "" +"Use the same collation as in the template database, or use template0 as " +"template." +msgstr "" +"템플릿 데이터베이스와 동일한 데이터 정렬 규칙을 사용하거나 template0을 템플릿" +"으로 사용하십시오." + +#: commands/dbcommands.c:430 +#, c-format +msgid "" +"new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database " +"(%s)" +msgstr "새 LC_CTYPE (%s)이 템플릿 데이터베이스의 LC_CTYPE (%s)과 호환되지 않음" + +#: commands/dbcommands.c:432 +#, c-format +msgid "" +"Use the same LC_CTYPE as in the template database, or use template0 as " +"template." +msgstr "" +"템플릿 데이터베이스와 동일한 LC_CTYPE을 사용하거나 template0을 템플릿으로 사" +"용하십시오." + +#: commands/dbcommands.c:454 commands/dbcommands.c:1196 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "pg_global을 기본 테이블스페이스로 사용할 수 없음" + +#: commands/dbcommands.c:480 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "새 \"%s\" 테이블스페이스를 지정할 수 없습니다." + +#: commands/dbcommands.c:482 +#, c-format +msgid "" +"There is a conflict because database \"%s\" already has some tables in this " +"tablespace." +msgstr "" +"\"%s\" 데이터베이스 소속 몇몇 테이블들이 이 테이블스페이스안에 있어서 충돌이 " +"일어납니다." + +#: commands/dbcommands.c:512 commands/dbcommands.c:1066 +#, c-format +msgid "database \"%s\" already exists" +msgstr "\"%s\" 이름의 데이터베이스는 이미 있음" + +#: commands/dbcommands.c:526 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "\"%s\" 원본 데이터베이스를 다른 사용자가 액세스하기 시작했습니다" + +#: commands/dbcommands.c:769 commands/dbcommands.c:784 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "\"%s\" 인코딩은 \"%s\" 로케일과 일치하지 않음" + +#: commands/dbcommands.c:772 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "선택한 LC_CTYPE 설정에는 \"%s\" 인코딩이 필요합니다." + +#: commands/dbcommands.c:787 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "선택한 LC_COLLATE 설정에는 \"%s\" 인코딩이 필요합니다." + +#: commands/dbcommands.c:848 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "\"%s\" 데이터베이스 없음, 건너 뜀" + +#: commands/dbcommands.c:872 +#, c-format +msgid "cannot drop a template database" +msgstr "템플릿 데이터베이스는 삭제할 수 없습니다" + +#: commands/dbcommands.c:878 +#, c-format +msgid "cannot drop the currently open database" +msgstr "현재 열려 있는 데이터베이스는 삭제할 수 없습니다" + +#: commands/dbcommands.c:891 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "\"%s\" 데이터베이스는 논리 복제 슬롯이 활성화 되어 있습니다" + +#: commands/dbcommands.c:893 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "%d 개의 활성 슬롯이 있습니다." + +#: commands/dbcommands.c:907 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "\"%s\" 데이터베이스가 논리 복제 구독으로 사용되었음" + +#: commands/dbcommands.c:909 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "%d 개의 구독이 있습니다." + +#: commands/dbcommands.c:930 commands/dbcommands.c:1088 +#: commands/dbcommands.c:1218 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "\"%s\" 데이터베이스를 다른 사용자가 액세스하기 시작했습니다" + +#: commands/dbcommands.c:1048 +#, c-format +msgid "permission denied to rename database" +msgstr "데이터베이스 이름을 바꿀 권한이 없습니다" + +#: commands/dbcommands.c:1077 +#, c-format +msgid "current database cannot be renamed" +msgstr "현재 데이터베이스의 이름을 바꿀 수 없음" + +#: commands/dbcommands.c:1174 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "현재 열려 있는 데이터베이스의 테이블스페이스를 바꿀 수 없음" + +#: commands/dbcommands.c:1277 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "" +"\"%s\" 데이터베이스의 일부 릴레이션들이 \"%s\" 테이블스페이스에 이미 있음" + +#: commands/dbcommands.c:1279 +#, c-format +msgid "" +"You must move them back to the database's default tablespace before using " +"this command." +msgstr "" +"이 명령을 사용하기 전에 데이터베이스의 기본 테이블스페이스로 다시 이동해야 합" +"니다." + +#: commands/dbcommands.c:1404 commands/dbcommands.c:1980 +#: commands/dbcommands.c:2203 commands/dbcommands.c:2261 +#: commands/tablespace.c:619 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "" +"불필요한 일부 파일이 이전 데이터베이스 디렉터리 \"%s\"에 남아 있을 수 있음" + +#: commands/dbcommands.c:1460 +#, c-format +msgid "unrecognized DROP DATABASE option \"%s\"" +msgstr "알 수 없는 DROP DATABASE 옵션: \"%s\"" + +#: commands/dbcommands.c:1550 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "\"%s\" 옵션은 다른 옵션들과 함께 사용할 수 없습니다." + +#: commands/dbcommands.c:1606 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "현재 데이터베이스 연결을 허용하지 않습니다." + +#: commands/dbcommands.c:1742 +#, c-format +msgid "permission denied to change owner of database" +msgstr "데이터베이스 소유주를 바꿀 권한이 없습니다" + +#: commands/dbcommands.c:2086 +#, c-format +msgid "" +"There are %d other session(s) and %d prepared transaction(s) using the " +"database." +msgstr "" +"데이터베이스를 사용하는 %d개의 다른 세션과 %d개의 준비된 트랜잭션이 있습니다." + +#: commands/dbcommands.c:2089 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "데이터베이스를 사용하는 %d개의 다른 세션이 있습니다." + +#: commands/dbcommands.c:2094 storage/ipc/procarray.c:3016 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "데이터베이스를 사용하는 %d개의 준비된 트랜잭션이 있습니다." + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 +#: commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%s 매개 변수를 필요로 함" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 +#: commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%s 숫자값을 필요로 함" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "%s 값은 boolean 값이어야합니다." + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%s 하나의 정수값이 필요함" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "%s의 인자는 이름이어야 합니다" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "%s의 인자는 자료형 이름이어야합니다" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "%s의 잘못된 인자: \"%s\"" + +#: commands/dropcmds.c:100 commands/functioncmds.c:1274 +#: utils/adt/ruleutils.c:2633 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "\"%s\" 함수는 집계 함수입니다" + +#: commands/dropcmds.c:102 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "집계 함수는 DROP AGGREGATE 명령으로 삭제할 수 있습니다" + +#: commands/dropcmds.c:158 commands/sequence.c:447 commands/tablecmds.c:3266 +#: commands/tablecmds.c:3424 commands/tablecmds.c:3469 +#: commands/tablecmds.c:15038 tcop/utility.c:1309 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "\"%s\" 릴레이션 없음, 건너뜀" + +#: commands/dropcmds.c:188 commands/dropcmds.c:287 commands/tablecmds.c:1199 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "\"%s\" 스키마(schema) 없음, 건너뜀" + +#: commands/dropcmds.c:228 commands/dropcmds.c:267 commands/tablecmds.c:259 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "\"%s\" 자료형 없음, 건너뜀" + +#: commands/dropcmds.c:257 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "\"%s\" 인덱스 접근 방법 없음, 건너뜀" + +#: commands/dropcmds.c:275 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "\"%s\" 정렬규칙 없음, 건너뜀" + +#: commands/dropcmds.c:282 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "\"%s\" 문자코드변환규칙(conversion) 없음, 건너뜀" + +#: commands/dropcmds.c:293 commands/statscmds.c:479 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "\"%s\" 통계정보 개체 없음, 무시함" + +#: commands/dropcmds.c:300 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr "\"%s\" 전문 검색 파서가 없음, 건너뜀" + +#: commands/dropcmds.c:307 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "\"%s\" 전문 검색 사전이 없음, 건너뜀" + +#: commands/dropcmds.c:314 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "\"%s\" 전문 검색 템플릿이 없음, 건너뜀" + +#: commands/dropcmds.c:321 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "\"%s\" 전문 검색 구성이 없음, 건너뜀" + +#: commands/dropcmds.c:326 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "\"%s\" 확장 모듈 없음, 건너 뜀" + +#: commands/dropcmds.c:336 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "%s(%s) 함수가 없음, 건너뜀" + +#: commands/dropcmds.c:349 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "%s(%s) 프로시져 없음, 건너뜀" + +#: commands/dropcmds.c:362 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "%s(%s) 루틴 없음, 건너뜀" + +#: commands/dropcmds.c:375 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "%s(%s) 집계 함수 없음, 건너뜀" + +#: commands/dropcmds.c:388 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "%s 연산자가 없음, 건너뜀" + +#: commands/dropcmds.c:394 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "\"%s\" 프로시주얼 언어 없음, 건너뜀" + +#: commands/dropcmds.c:403 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "%s 형에서 %s 형으로 바꾸는 형변환 규칙(cast)이 없음, 건너뜀" + +#: commands/dropcmds.c:412 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "%s 형변환자 (사용언어 \"%s\") 없음, 건너뜀" + +#: commands/dropcmds.c:420 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr " \"%s\" 트리거가 \"%s\" 릴레이션에 지정된 것이 없음, 건너뜀" + +#: commands/dropcmds.c:429 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr " \"%s\" 정책이 \"%s\" 릴레이션에 지정된 것이 없음, 건너뜀" + +#: commands/dropcmds.c:436 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "\"%s\" 이벤트 트리거 없음, 건너뜀" + +#: commands/dropcmds.c:442 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr " \"%s\" 룰(rule)이 \"%s\" 릴레이션에 지정된 것이 없음, 건너뜀" + +#: commands/dropcmds.c:449 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "\"%s\" 외부 자료 래퍼가 없음, 건너뜀" + +#: commands/dropcmds.c:453 commands/foreigncmds.c:1399 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "\"%s\" 서버가 없음, 건너뜀" + +#: commands/dropcmds.c:462 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "" +"\"%s\" 연산자 클래스는 \"%s\" 인덱스 접근 방법에서 사용할 수 없음, 건너뜀" + +#: commands/dropcmds.c:474 +#, c-format +msgid "" +"operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "\"%s\" 연산자 패밀리(\"%s\" 접근 방법)가 없음, 건너뜀" + +#: commands/dropcmds.c:481 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "\"%s\" 발행 없음, 건너뜀" + +#: commands/event_trigger.c:125 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "\"%s\" 이벤트 트리거를 만들 권한이 없음" + +#: commands/event_trigger.c:127 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "슈퍼유저만 이벤트 트리거를 만들 수 있습니다." + +#: commands/event_trigger.c:136 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "알 수 없는 이벤트 이름: \"%s\"" + +#: commands/event_trigger.c:153 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "알 수 없는 필터 변수: \"%s\"" + +#: commands/event_trigger.c:207 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "\"%s\" 필터값은 \"%s\" 필터 변수으로 쓸 수 없음" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:213 commands/event_trigger.c:235 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "%s 용 이벤트 트리거는 지원하지 않음" + +#: commands/event_trigger.c:248 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "\"%s\" 필터 변수가 한 번 이상 사용되었습니다." + +#: commands/event_trigger.c:399 commands/event_trigger.c:443 +#: commands/event_trigger.c:537 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "\"%s\" 이벤트 트리거 없음" + +#: commands/event_trigger.c:505 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "\"%s\" 이벤트 트리거 소유주를 변경할 권한이 없음" + +#: commands/event_trigger.c:507 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "이벤트 트리거 소유주는 슈퍼유저여야 합니다." + +#: commands/event_trigger.c:1325 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%s 개체는 sql_drop 이벤트 트리거 함수 안에서만 호출 되어야 합니다." + +#: commands/event_trigger.c:1445 commands/event_trigger.c:1466 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "" +"%s 개체는 table_rewrite 이벤트 트리거 함수 안에서만 호출 되어야 합니다." + +#: commands/event_trigger.c:1883 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%s 개체는 이벤트 트리거 함수 안에서만 호출 되어야 합니다." + +#: commands/explain.c:213 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "\"%s\" EXPLAIN 옵션에서 쓸 수 없는 값: \"%s\"" + +#: commands/explain.c:220 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "잘못된 EXPLAIN 옵션: \"%s\"" + +#: commands/explain.c:228 +#, c-format +msgid "EXPLAIN option WAL requires ANALYZE" +msgstr "WAL 옵션은 EXPLAIN ANALYZE에서만 쓸 수 있습니다." + +#: commands/explain.c:237 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "TIMING 옵션은 EXPLAIN ANALYZE에서만 쓸 수 있습니다." + +#: commands/extension.c:173 commands/extension.c:3013 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "\"%s\" 이름의 확장 모듈이 없습니다" + +#: commands/extension.c:272 commands/extension.c:281 commands/extension.c:293 +#: commands/extension.c:303 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "잘못된 확장 모듈 이름: \"%s\"" + +#: commands/extension.c:273 +#, c-format +msgid "Extension names must not be empty." +msgstr "확장 모듈 이름을 지정하세요." + +#: commands/extension.c:282 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "확장 모듈 이름에 \"--\" 문자가 포함될 수 없습니다." + +#: commands/extension.c:294 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "확장 모듈 이름의 시작과 끝에는 \"-\" 문자를 사용할 수 없습니다." + +#: commands/extension.c:304 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "확장 모듈 이름에는 디렉터리 구분 문자를 사용할 수 없습니다." + +#: commands/extension.c:319 commands/extension.c:328 commands/extension.c:337 +#: commands/extension.c:347 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "잘못된 확장 모듈 버전 이름: \"%s\"" + +#: commands/extension.c:320 +#, c-format +msgid "Version names must not be empty." +msgstr "버전 이름은 비어있으면 안됩니다" + +#: commands/extension.c:329 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "버전 이름에 \"--\" 문자가 포함될 수 없습니다." + +#: commands/extension.c:338 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "버전 이름의 앞 뒤에 \"-\" 문자를 쓸 수 없습니다." + +#: commands/extension.c:348 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "버전 이름에는 디렉터리 분리 문자를 쓸 수 없습니다." + +#: commands/extension.c:498 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "\"%s\" 확장 모듈 제어 파일 열기 실패: %m" + +#: commands/extension.c:520 commands/extension.c:530 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "\"%s\" 매개 변수는 이차 확장 모듈 제어 파일에서는 사용할 수 없습니다." + +#: commands/extension.c:552 commands/extension.c:560 commands/extension.c:568 +#: utils/misc/guc.c:6749 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "\"%s\" 매개 변수의 값은 boolean 값이어야합니다." + +#: commands/extension.c:577 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "\"%s\" 이름은 잘못된 인코딩 이름임" + +#: commands/extension.c:591 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "\"%s\" 매개 변수는 확장 모듈 이름 목록이어야 함" + +#: commands/extension.c:598 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "알 수 없는 \"%s\" 매개 변수가 \"%s\" 파일 안에 있습니다." + +#: commands/extension.c:607 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr "" +"\"relocatable\" 값이 true 인 경우 \"schema\" 매개 변수는 사용할 수 없습니다." + +#: commands/extension.c:785 +#, c-format +msgid "" +"transaction control statements are not allowed within an extension script" +msgstr "확장 모듈 스크립트 안에서는 트랜잭션 제어 구문은 사용할 수 없습니다." + +#: commands/extension.c:861 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "\"%s\" 확장 모듈을 만들 권한이 없습니다" + +#: commands/extension.c:864 +#, c-format +msgid "" +"Must have CREATE privilege on current database to create this extension." +msgstr "" +"이 확장 모듈을 설치하려면 현재 데이터베이스에 대해서 CREATE 권한이 있어야합니다." + +#: commands/extension.c:865 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "확장 모듈은 슈퍼유저만 만들 수 있습니다." + +#: commands/extension.c:869 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "\"%s\" 확장 모듈을 업데이트할 권한이 없습니다." + +#: commands/extension.c:872 +#, c-format +msgid "" +"Must have CREATE privilege on current database to update this extension." +msgstr "" +"이 확장 모듈을 업데이트 하려면 현재 데이터베이스에 대해서 CREATE 권한이 있어야합니다." + +#: commands/extension.c:873 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "슈퍼유저만 해당 모듈을 업데이트 할 수 있습니다." + +#: commands/extension.c:1200 +#, c-format +msgid "" +"extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "" +"\"%s\" 확장 모듈을 \"%s\" 버전에서 \"%s\" 버전으로 업데이트할 방법이 없습니" +"다." + +#: commands/extension.c:1408 commands/extension.c:3074 +#, c-format +msgid "version to install must be specified" +msgstr "설치할 버전을 지정해야 합니다." + +#: commands/extension.c:1445 +#, c-format +msgid "" +"extension \"%s\" has no installation script nor update path for version \"%s" +"\"" +msgstr "" +"\"%s\" 확장 모듈에는 \"%s\" 버전용 설치나 업데이트 스크립트가 없습니다." + +#: commands/extension.c:1479 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "\"%s\" 확장 모듈은 \"%s\" 스키마 안에 설치되어야 합니다." + +#: commands/extension.c:1639 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "\"%s\" 확장 모듈과 \"%s\" 확장 모듈이 서로 의존 관계입니다" + +#: commands/extension.c:1644 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "\"%s\" 확장 모듈이 필요해서 실치 하는 중" + +#: commands/extension.c:1667 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr "\"%s\" 확장 모듈이 필요한데, 설치되어 있지 않습니다." + +#: commands/extension.c:1670 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "" +"필요한 모듈을 함께 설치하려면, CREATE EXTENSION ... CASCADE 구문을 사용하세" +"요." + +#: commands/extension.c:1705 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "\"%s\" 확장 모듈이 이미 있음, 건너뜀" + +#: commands/extension.c:1712 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "\"%s\" 이름의 확장 모듈이 이미 있습니다" + +#: commands/extension.c:1723 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "중첩된 CREATE EXTENSION 구문은 지원하지 않습니다." + +#: commands/extension.c:1896 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "%s 의존개체들은 시스템 개체이기 때문에 삭제 될 수 없습니다" + +#: commands/extension.c:2457 +#, c-format +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "" +"%s 함수는 CREATE EXTENSION 명령에서 내부적으로 사용하는 SQL 스크립트 내에서" +"만 사용할 수 있습니다." + +#: commands/extension.c:2469 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "%u OID 자료가 테이블에 없습니다" + +#: commands/extension.c:2474 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "\"%s\" 테이블은 만들려고 하는 확장 모듈의 구성 요소가 아닙니다." + +#: commands/extension.c:2828 +#, c-format +msgid "" +"cannot move extension \"%s\" into schema \"%s\" because the extension " +"contains the schema" +msgstr "\"%s\" 확장 모듈이 \"%s\" 스키마에 이미 있어 옮길 수 없습니다." + +#: commands/extension.c:2869 commands/extension.c:2932 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "\"%s\" 확장 모듈은 SET SCHEMA 구문을 지원하지 않음" + +#: commands/extension.c:2934 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "%s 개체가 확장 모듈 스키마인 \"%s\" 안에 없음" + +#: commands/extension.c:2993 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "중첩된 ALTER EXTENSION 구문을 지원하지 않음" + +#: commands/extension.c:3085 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "\"%s\" 버전의 \"%s\" 확장 모듈이 이미 설치 되어 있음" + +#: commands/extension.c:3336 +#, c-format +msgid "" +"cannot add schema \"%s\" to extension \"%s\" because the schema contains the " +"extension" +msgstr "" +"\"%s\" 스키마에 \"%s\" 확장 모듈을 추가할 수 없음, 이미 해당 스키마 안에 포" +"함되어 있음" + +#: commands/extension.c:3364 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "\"%s\" 개체는 \"%s\" 확장 모듈의 구성 요소가 아닙니다" + +#: commands/extension.c:3430 +#, c-format +msgid "file \"%s\" is too large" +msgstr "\"%s\" 파일이 너무 큽니다." + +#: commands/foreigncmds.c:148 commands/foreigncmds.c:157 +#, c-format +msgid "option \"%s\" not found" +msgstr "\"%s\" 옵션을 찾을 수 없음" + +#: commands/foreigncmds.c:167 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "\"%s\" 옵션이 여러 번 제공되었음" + +#: commands/foreigncmds.c:221 commands/foreigncmds.c:229 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "\"%s\" 외부 자료 래퍼의 소유주를 변경할 권한이 없음" + +#: commands/foreigncmds.c:223 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "슈퍼유저만 외부 자료 래퍼의 소유주를 바꿀 수 있습니다." + +#: commands/foreigncmds.c:231 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "외부 자료 래퍼의 소유주는 슈퍼유저여야 합니다." + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:711 foreign/foreign.c:701 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "\"%s\" 외부 자료 래퍼가 없음" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "\"%s\" 외부 자료 래퍼를 만들 권한이 없음" + +#: commands/foreigncmds.c:586 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "슈퍼유저만 외부 자료 래퍼를 만들 수 있습니다." + +#: commands/foreigncmds.c:701 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "\"%s\" 외부 자료 래퍼를 변경할 권한이 없음" + +#: commands/foreigncmds.c:703 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "슈퍼유저만 외부 자료 래퍼를 변경할 수 있습니다." + +#: commands/foreigncmds.c:734 +#, c-format +msgid "" +"changing the foreign-data wrapper handler can change behavior of existing " +"foreign tables" +msgstr "" +"외부 자료 랩퍼 핸들러를 바꾸면, 그것을 사용하는 외부 테이블의 내용이 바뀔 수 " +"있습니다." + +#: commands/foreigncmds.c:749 +#, c-format +msgid "" +"changing the foreign-data wrapper validator can cause the options for " +"dependent objects to become invalid" +msgstr "" +"외부 자료 래퍼 유효성 검사기를 바꾸면 종속 개체에 대한 옵션이 유효하지 않을 " +"수 있음" + +#: commands/foreigncmds.c:895 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "\"%s\" 이름의 외부 서버가 이미 있음, 건너뜀" + +#: commands/foreigncmds.c:1183 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "\"%s\" 사용자 매핑이 \"%s\" 서버용으로 이미 있음, 건너뜀" + +#: commands/foreigncmds.c:1193 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "\"%s\" 사용자 매핑이 \"%s\" 서버용으로 이미 있음" + +#: commands/foreigncmds.c:1293 commands/foreigncmds.c:1413 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "\"%s\" 사용자 매핑이 \"%s\" 서버용으로 없음" + +#: commands/foreigncmds.c:1418 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "\"%s\" 사용자 매핑이 \"%s\" 서버용으로 없음, 건너뜀" + +#: commands/foreigncmds.c:1569 foreign/foreign.c:389 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "\"%s\" 외부 자료 래퍼용 핸들러가 없음" + +#: commands/foreigncmds.c:1575 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "\"%s\" 외부 자료 래퍼는 IMPORT FOREIGN SCHEMA 구문을 지원하지 않음" + +#: commands/foreigncmds.c:1678 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "\"%s\" 외부 테이블 가져 오는 중" + +#: commands/functioncmds.c:104 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "SQL 함수는 shell type %s 리턴할 수 없음" + +#: commands/functioncmds.c:109 +#, c-format +msgid "return type %s is only a shell" +msgstr "_^_ %s 리턴 자료형은 하나의 shell만 있습니다" + +#: commands/functioncmds.c:139 parser/parse_type.c:354 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "\"%s\" 셸 형식에 대해 형식 한정자를 지정할 수 없음" + +#: commands/functioncmds.c:145 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "\"%s\" 자료형이 아직 정의되지 않았음" + +#: commands/functioncmds.c:146 +#, c-format +msgid "Creating a shell type definition." +msgstr "셸 타입 정의를 만들고 있습니다" + +#: commands/functioncmds.c:238 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "SQL 함수는 셸 타입 %s 수용할 수 없음" + +#: commands/functioncmds.c:244 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "집계 함수는 셸 타입 %s 수용할 수 없음" + +#: commands/functioncmds.c:249 +#, c-format +msgid "argument type %s is only a shell" +msgstr "%s 인자 자료형은 단지 셸입니다" + +#: commands/functioncmds.c:259 +#, c-format +msgid "type %s does not exist" +msgstr "%s 자료형 없음" + +#: commands/functioncmds.c:273 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "집계 함수는 세트 인자를 입력 인자로 쓸 수 없음" + +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "프로시져에서는 집합 인자를 입력 인자로 쓸 수 없음" + +#: commands/functioncmds.c:281 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "함수는 세트 인자를 쓸 수 없음" + +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "프로시저는 OUT 인자를 쓸 수 없음" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "INOUT 인자가 허용됨" + +#: commands/functioncmds.c:300 +#, c-format +msgid "VARIADIC parameter must be the last input parameter" +msgstr "VARIADIC 매개 변수는 마지막 입력 매개 변수여야 함" + +#: commands/functioncmds.c:331 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "VARIADIC 매개 변수는 배열이어야 함" + +#: commands/functioncmds.c:371 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "\"%s\" 매개 변수가 여러 번 사용 됨" + +#: commands/functioncmds.c:386 +#, c-format +msgid "only input parameters can have default values" +msgstr "입력 매개 변수에서만 기본값을 사용할 수 있음" + +#: commands/functioncmds.c:401 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "입력 매개 변수 초기값으로 테이블 참조형은 사용할 수 없음" + +#: commands/functioncmds.c:425 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "" +"기본 값이 있는 입력 매개 변수 뒤에 오는 입력 매개 변수에도 기본 값이 있어야 " +"함" + +#: commands/functioncmds.c:577 commands/functioncmds.c:768 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "프로시져 정의에 잘못된 속성이 있음" + +#: commands/functioncmds.c:673 +#, c-format +msgid "support function %s must return type %s" +msgstr "%s support 함수는 %s 자료형을 반환해야 함" + +#: commands/functioncmds.c:684 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "support 함수를 지정하려면 슈퍼유져여야합니다" + +#: commands/functioncmds.c:800 +#, c-format +msgid "no function body specified" +msgstr "함수 본문(body) 부분이 빠졌습니다" + +#: commands/functioncmds.c:810 +#, c-format +msgid "no language specified" +msgstr "처리할 프로시주얼 언어를 지정하지 않았습니다" + +#: commands/functioncmds.c:835 commands/functioncmds.c:1319 +#, c-format +msgid "COST must be positive" +msgstr "COST는 양수여야 함" + +#: commands/functioncmds.c:843 commands/functioncmds.c:1327 +#, c-format +msgid "ROWS must be positive" +msgstr "ROWS는 양수여야 함" + +#: commands/functioncmds.c:897 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "\"%s\" 언어에는 하나의 AS 항목만 필요함" + +#: commands/functioncmds.c:995 commands/functioncmds.c:2048 +#: commands/proclang.c:259 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "\"%s\" 프로시주얼 언어 없음" + +#: commands/functioncmds.c:997 commands/functioncmds.c:2050 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "" +"데이터베이스 내에서 프로시주얼 언어를 사용하려면 먼저 CREATE EXTENSION 명령으" +"로 사용할 언어를 등록하세요." + +#: commands/functioncmds.c:1032 commands/functioncmds.c:1311 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "슈퍼유저만 leakproof 함수를 만들 수 있습니다" + +#: commands/functioncmds.c:1081 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "OUT 매개 변수로 인해 함수 결과 형식은 %s이어야 함" + +#: commands/functioncmds.c:1094 +#, c-format +msgid "function result type must be specified" +msgstr "함수의 리턴 자료형을 지정해야 합니다" + +#: commands/functioncmds.c:1146 commands/functioncmds.c:1331 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "함수에서 세트를 반환하지 않는 경우 ROWS를 적용할 수 없음" + +#: commands/functioncmds.c:1431 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "%s 원본 자료형이 의사자료형(pseudo-type) 입니다" + +#: commands/functioncmds.c:1437 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "%s 대상 자료형이 의사자료형(pseudo-type) 입니다" + +#: commands/functioncmds.c:1461 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "원본 자료형이 도메인이어서 자료형 변환을 무시합니다." + +#: commands/functioncmds.c:1466 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "대상 자료형이 도메인이어서 자료형 변환을 무시합니다." + +#: commands/functioncmds.c:1491 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "형변환 함수는 1-3개의 인자만 지정할 수 있습니다" + +#: commands/functioncmds.c:1495 +#, c-format +msgid "" +"argument of cast function must match or be binary-coercible from source data " +"type" +msgstr "" +"형변환 함수의 인자로 쓸 자료형은 원본 자료형과 일치하거나 바이너리 차원으로 " +"같은 자료형이어야 함" + +#: commands/functioncmds.c:1499 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "형변화 함수의 두번째 인자 자료형은 반드시 %s 형이여야합니다" + +#: commands/functioncmds.c:1504 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "형변화 함수의 세번째 인자 자료형은 반드시 %s 형이여야합니다" + +#: commands/functioncmds.c:1509 +#, c-format +msgid "" +"return data type of cast function must match or be binary-coercible to " +"target data type" +msgstr "" +"형변환 함수의 반환 자료형은 대상 자료형과 일치하거나 바이너리 차원으로 같은 " +"자료형이어야 함" + +#: commands/functioncmds.c:1520 +#, c-format +msgid "cast function must not be volatile" +msgstr "형변환 함수는 volatile 특성이 없어야합니다" + +#: commands/functioncmds.c:1525 +#, c-format +msgid "cast function must be a normal function" +msgstr "형변환 함수는 일반 함수여야 합니다" + +#: commands/functioncmds.c:1529 +#, c-format +msgid "cast function must not return a set" +msgstr "형변환 함수는 세트(set)를 리턴할 수 없습니다" + +#: commands/functioncmds.c:1555 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "CREATE CAST ... WITHOUT FUNCTION 명령은 슈퍼유저만 실행할 수 있습니다" + +#: commands/functioncmds.c:1570 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "원본 자료형과 대상 자료형이 서로 논리적인 호환성이 없습니다" + +#: commands/functioncmds.c:1585 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "복합 자료형은 바이너리와 호환되지 않음" + +#: commands/functioncmds.c:1591 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "열거 자료형은 바이너리와 호환되지 않음" + +#: commands/functioncmds.c:1597 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "배열 자료형은 바이너리와 호환되지 않음" + +#: commands/functioncmds.c:1614 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "도메인 자료형은 바이너리와 호환되지 않음" + +#: commands/functioncmds.c:1624 +#, c-format +msgid "source data type and target data type are the same" +msgstr "원본 자료형과 대상 자료형의 형태가 같습니다" + +#: commands/functioncmds.c:1682 +#, c-format +msgid "transform function must not be volatile" +msgstr "형변환 함수는 volatile 특성이 없어야합니다" + +#: commands/functioncmds.c:1686 +#, c-format +msgid "transform function must be a normal function" +msgstr "형변환 함수는 일반 함수여야합니다." + +#: commands/functioncmds.c:1690 +#, c-format +msgid "transform function must not return a set" +msgstr "형변환 함수는 세트(set)를 리턴할 수 없습니다" + +#: commands/functioncmds.c:1694 +#, c-format +msgid "transform function must take one argument" +msgstr "형변환 함수는 1개의 인자만 지정할 수 있습니다" + +#: commands/functioncmds.c:1698 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "형변화 함수의 첫번째 인자 자료형은 반드시 %s 형이여야합니다" + +#: commands/functioncmds.c:1736 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "%s 자료형은 의사자료형(pseudo-type) 입니다" + +#: commands/functioncmds.c:1742 +#, c-format +msgid "data type %s is a domain" +msgstr "%s 자료형은 도메인입니다" + +#: commands/functioncmds.c:1782 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "FROM SQL 함수의 반환 자료형은 %s 형이어야 함" + +#: commands/functioncmds.c:1808 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "TO SQL 함수의 반환 자료형은 변환 자료형이어야 함" + +#: commands/functioncmds.c:1837 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "%s 자료형(대상 언어: \"%s\")을 위한 형변환 규칙은 이미 있습니다." + +#: commands/functioncmds.c:1929 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "%s 자료형(대상 언어: \"%s\")을 위한 형변환 규칙은 없습니다." + +#: commands/functioncmds.c:1980 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "%s 함수는 이미 \"%s\" 스키마안에 있습니다" + +#: commands/functioncmds.c:2035 +#, c-format +msgid "no inline code specified" +msgstr "내장 코드가 빠졌습니다" + +#: commands/functioncmds.c:2081 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "\"%s\" 프로시주얼 언어는 내장 코드 실행 기능을 지원하지 않습니다" + +#: commands/functioncmds.c:2193 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "프로시져에 %d개의 인자 이상을 전달할 수 없음" + +#: commands/indexcmds.c:590 +#, c-format +msgid "must specify at least one column" +msgstr "적어도 하나 이상의 칼럼을 지정해 주십시오" + +#: commands/indexcmds.c:594 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "하나의 인덱스에서는 %d개보다 많은 칼럼을 사용할 수 없습니다" + +#: commands/indexcmds.c:633 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "\"%s\" 외부 테이블 대상으로 인덱스를 만들 수 없음" + +#: commands/indexcmds.c:664 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "\"%s\" 파티션된 테이블 대상으로 동시에 인덱스를 만들 수 없음" + +#: commands/indexcmds.c:669 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "\"%s\" 파티션된 테이블 대상으로 제외 제약조건을 만들 수 없음" + +#: commands/indexcmds.c:679 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "다른 세션의 임시 테이블에 인덱스를 만들 수는 없습니다" + +#: commands/indexcmds.c:717 commands/tablecmds.c:704 commands/tablespace.c:1173 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "파티션 테이블용 기본 테이블스페이스를 지정할 수 없습니다." + +#: commands/indexcmds.c:749 commands/tablecmds.c:739 commands/tablecmds.c:13162 +#: commands/tablecmds.c:13276 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "공유 관계만 pg_global 테이블스페이스에 배치할 수 있음" + +#: commands/indexcmds.c:782 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "사용하지 않는 \"rtree\" 방법을 \"gist\" 액세스 방법으로 대체하는 중" + +#: commands/indexcmds.c:803 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "\"%s\" 인덱스 접근 방법은 고유 인덱스를 지원하지 않습니다" + +#: commands/indexcmds.c:808 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "\"%s\" 인덱스 접근 방법은 포함된 칼럼을 지원하지 않습니다" + +#: commands/indexcmds.c:813 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "\"%s\" 인덱스 접근 방법은 다중 열 인덱스를 지원하지 않습니다" + +#: commands/indexcmds.c:818 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "\"%s\" 인덱스 접근 방법은 제외 제약 조건을 지원하지 않습니다" + +#: commands/indexcmds.c:941 +#, c-format +msgid "cannot match partition key to an index using access method \"%s\"" +msgstr "\"%s\" 접근 방법을 사용하는 인덱스와 파티션 키가 일치하지 않습니다" + +#: commands/indexcmds.c:951 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "파티션 키 정의에는 %s 제약조건을 지원하지 않음" + +#: commands/indexcmds.c:953 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "%s 제약조건은 파티션 키 포함 표현식에 사용할 수 없습니다" + +#: commands/indexcmds.c:992 +#, c-format +msgid "" +"unique constraint on partitioned table must include all partitioning columns" +msgstr "하위 테이블 용 유니크 제약조건에는 모든 파티션 칼럼이 포함되어야 함" + +#: commands/indexcmds.c:993 +#, c-format +msgid "" +"%s constraint on table \"%s\" lacks column \"%s\" which is part of the " +"partition key." +msgstr "" + +#: commands/indexcmds.c:1012 commands/indexcmds.c:1031 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "시스템 카탈로그 테이블에 대한 인덱스 만들기는 지원하지 않습니다" + +#: commands/indexcmds.c:1056 +#, c-format +msgid "%s %s will create implicit index \"%s\" for table \"%s\"" +msgstr "%s %s 명령으로 \"%s\" 인덱스를 \"%s\" 테이블에 자동으로 만들었음" + +#: commands/indexcmds.c:1197 tcop/utility.c:1495 +#, c-format +msgid "cannot create unique index on partitioned table \"%s\"" +msgstr "\"%s\" 파티션된 테이블 대상으로 유니크 인덱스를 만들 수 없음" + +#: commands/indexcmds.c:1199 tcop/utility.c:1497 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "\"%s\" 테이블은 하위 테이블로 외부 테이블을 사용함." + +#: commands/indexcmds.c:1628 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "" +"인덱스 술어(predicate)에서 사용하는 함수는 IMMUTABLE 특성이 있어야합니다" + +#: commands/indexcmds.c:1694 parser/parse_utilcmd.c:2440 +#: parser/parse_utilcmd.c:2575 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "키에서 지정한 \"%s\" 칼럼이 없습니다" + +#: commands/indexcmds.c:1718 parser/parse_utilcmd.c:1776 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "포함된 칼럼에 쓰인 표현식을 지원하지 않음" + +#: commands/indexcmds.c:1759 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "인덱스 식(expression)에 사용하는 함수는 IMMUTABLE 특성이 있어야합니다" + +#: commands/indexcmds.c:1774 +#, c-format +msgid "including column does not support a collation" +msgstr "포함된 칼럼은 문자정렬규칙을 지원하지 않음" + +#: commands/indexcmds.c:1778 +#, c-format +msgid "including column does not support an operator class" +msgstr "포함된 칼럼은 연산자 클래스를 지원하지 않음" + +#: commands/indexcmds.c:1782 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "포함된 칼럼은 ASC/DESC 옵션을 지원하지 않음" + +#: commands/indexcmds.c:1786 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "포함된 칼럼은 NULLS FIRST/LAST 옵션을 지원하지 않음" + +#: commands/indexcmds.c:1813 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "해당 인덱스에서 사용할 정렬규칙(collation)을 결정할 수 없습니다." + +#: commands/indexcmds.c:1821 commands/tablecmds.c:16042 commands/typecmds.c:771 +#: parser/parse_expr.c:2850 parser/parse_type.c:566 parser/parse_utilcmd.c:3649 +#: parser/parse_utilcmd.c:4210 utils/adt/misc.c:503 +#, c-format +msgid "collations are not supported by type %s" +msgstr "%s 자료형은 collation 지원 안함" + +#: commands/indexcmds.c:1859 +#, c-format +msgid "operator %s is not commutative" +msgstr "%s 연산자는 교환법칙이 성립하지 않습니다" + +#: commands/indexcmds.c:1861 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "" +"exclude 제약조건용 인덱스를 만들 때는 교환법칙이 성립하는 연산자만 사용할 수 " +"있습니다." + +#: commands/indexcmds.c:1887 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "%s 연산자는 \"%s\" 연산자 패밀리 구성원이 아닙니다." + +#: commands/indexcmds.c:1890 +#, c-format +msgid "" +"The exclusion operator must be related to the index operator class for the " +"constraint." +msgstr "" +"제외 연산자는 해당 제약 조건용 인덱스 연산자 클래스의 소속이어야 합니다." + +#: commands/indexcmds.c:1925 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "\"%s\" 접근 방법은 ASC/DESC 옵션을 지원하지 않음" + +#: commands/indexcmds.c:1930 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "\"%s\" 접근 방법은 NULLS FIRST/LAST 옵션을 지원하지 않음" + +#: commands/indexcmds.c:1976 commands/tablecmds.c:16067 +#: commands/tablecmds.c:16073 commands/typecmds.c:1945 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "" +"%s 자료형은 \"%s\" 인덱스 액세스 방법을 위한 기본 연산자 클래스(operator " +"class)가 없습니다. " + +#: commands/indexcmds.c:1978 +#, c-format +msgid "" +"You must specify an operator class for the index or define a default " +"operator class for the data type." +msgstr "" +"이 인덱스를 위한 연산자 클래스를 지정하거나 먼저 이 자료형을 위한 기본 연산" +"자 클래스를 정의해 두어야합니다" + +#: commands/indexcmds.c:2007 commands/indexcmds.c:2015 +#: commands/opclasscmds.c:208 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "" +"\"%s\" 연산자 클래스는 \"%s\" 인덱스 액세스 방법에서 사용할 수 없습니다" + +#: commands/indexcmds.c:2029 commands/typecmds.c:1933 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "\"%s\" 연산자 클래스는 %s 자료형을 사용할 수 없습니다" + +#: commands/indexcmds.c:2119 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "%s 자료형을 위한 기본 연산자 클래스가 여러개 있습니다" + +#: commands/indexcmds.c:2568 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "\"%s\" 테이블에는 잠금 없는 재색인 작업을 할 대상 인덱스가 없음" + +#: commands/indexcmds.c:2579 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "\"%s\" 테이블에는 재색인 작업을 할 인덱스가 없습니다" + +#: commands/indexcmds.c:2618 commands/indexcmds.c:2899 +#: commands/indexcmds.c:2992 +#, c-format +msgid "cannot reindex system catalogs concurrently" +msgstr "시스템 카탈로그 테이블 대상으로 잠금 없는 인덱스를 만들 수 없음" + +#: commands/indexcmds.c:2641 +#, c-format +msgid "can only reindex the currently open database" +msgstr "열려있는 현재 데이터베이스에서만 reindex 명령을 사용할 수 있습니다" + +#: commands/indexcmds.c:2732 +#, c-format +msgid "cannot reindex system catalogs concurrently, skipping all" +msgstr "" +"시스템 카탈로그 테이블 대상으로 잠금 없는 재색인 작업을 할 수 없음, 모두 건너" +"뜀" + +#: commands/indexcmds.c:2784 commands/indexcmds.c:3503 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "\"%s.%s\" 테이블의 인덱스들을 다시 만들었습니다." + +#: commands/indexcmds.c:2914 commands/indexcmds.c:2960 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "" +"유효하지 않은 \"%s.%s\" 인덱스는 잠금 없는 재색인 작업을 할 수 없음, 건너뜀" + +#: commands/indexcmds.c:2920 +#, c-format +msgid "" +"cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "" +"\"%s.%s\" exclusion 제약조건을 대상으로 잠금 없는 재색인 작업을 할 수 없음, " +"건너뜀" + +#: commands/indexcmds.c:3002 +#, c-format +msgid "cannot reindex invalid index on TOAST table concurrently" +msgstr "" +"TOAST 테이블에 지정된 유효하지 않은 인덱스는 잠금 없는 재색인 작업을 할 수 없음" + +#: commands/indexcmds.c:3030 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "해당 개체에 대해서는 잠금 없는 재색인 작업을 할 수 없음" + +#: commands/indexcmds.c:3485 commands/indexcmds.c:3496 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr "\"%s.%s\" 인덱스가 다시 만들어졌음" + +#: commands/indexcmds.c:3528 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "파티션 된 인덱스용 REINDEX 명령은 아직 구현되어 있지 않음" + +#: commands/lockcmds.c:91 commands/tablecmds.c:5629 commands/trigger.c:295 +#: rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:928 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "\"%s\" 개체는 테이블도 뷰도 아닙니다" + +#: commands/lockcmds.c:213 rewrite/rewriteHandler.c:1977 +#: rewrite/rewriteHandler.c:3782 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "" +"\"%s\" 릴레이션(relation)에서 지정된 룰에서 잘못된 재귀호출이 발견되었습니다" + +#: commands/matview.c:182 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "" +"구체화된 뷰의 자료가 정리되고 있을 때는 CONCURRENTLY 옵션을 사용할 수 없습니" +"다." + +#: commands/matview.c:188 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "CONCURRENTLY 옵션과, WITH NO DATA 옵션을 함께 사용할 수 없습니다." + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "\"%s\" 구체화된 뷰를 동시에 재갱신 할 수 없습니다." + +#: commands/matview.c:247 +#, c-format +msgid "" +"Create a unique index with no WHERE clause on one or more columns of the " +"materialized view." +msgstr "" +"구체화된 뷰의 하나 또는 하나 이상의 칼럼에 대한 WHERE 절 없는 고유 인덱스를 " +"만드세요." + +#: commands/matview.c:641 +#, c-format +msgid "" +"new data for materialized view \"%s\" contains duplicate rows without any " +"null columns" +msgstr "" +"\"%s\" 구체화된 뷰의 새 자료에 아무런 null 칼럼 없이 중복된 로우를 포함하고 " +"있습니다" + +#: commands/matview.c:643 +#, c-format +msgid "Row: %s" +msgstr "로우: %s" + +#: commands/opclasscmds.c:127 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "\"%s\" 연산자 없음, 해당 접근 방법: \"%s\"" + +#: commands/opclasscmds.c:269 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "\"%s\" 연산자 패밀리가 이미 있음, 해당 접근 방법: \"%s\"" + +#: commands/opclasscmds.c:414 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "연산자 클래스는 슈퍼유저만 만들 수 있습니다" + +#: commands/opclasscmds.c:487 commands/opclasscmds.c:869 +#: commands/opclasscmds.c:993 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "잘못된 연산자 번호: %d, 타당한 번호는 1부터 %d까지 입니다" + +#: commands/opclasscmds.c:531 commands/opclasscmds.c:913 +#: commands/opclasscmds.c:1008 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "잘못된 함수 번호: %d, 타당한 번호는 1부터 %d까지 입니다" + +#: commands/opclasscmds.c:559 +#, c-format +msgid "storage type specified more than once" +msgstr "저장 방법이 중복되었습니다" + +#: commands/opclasscmds.c:586 +#, c-format +msgid "" +"storage type cannot be different from data type for access method \"%s\"" +msgstr "스토리지 자료형은 \"%s\" 접근 방법의 자료형과 같아야 합니다." + +#: commands/opclasscmds.c:602 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "\"%s\" 연산자 클래스에는 이미 \"%s\" 액세스 방법이 사용되고 있습니다" + +#: commands/opclasscmds.c:630 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "\"%s\" 연산자 클래스를 %s 자료형의 기본값으로 지정할 수 없습니다" + +#: commands/opclasscmds.c:633 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "\"%s\" 연산자 클래스는 이미 기본 연산자 클래스입니다" + +#: commands/opclasscmds.c:761 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "슈퍼유저만 연산자 패밀리를 만들 수 있음" + +#: commands/opclasscmds.c:821 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "슈퍼유저만 연산자 패밀리를 변경할 수 있음" + +#: commands/opclasscmds.c:878 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "연산자 인자 형식이 ALTER OPERATOR FAMILY에 지정되어 있어야 함" + +#: commands/opclasscmds.c:941 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "ALTER OPERATOR FAMILY에서 STORAGE를 지정할 수 없음" + +#: commands/opclasscmds.c:1063 +#, c-format +msgid "one or two argument types must be specified" +msgstr "한두 개의 인자 형식을 지정해야 함" + +#: commands/opclasscmds.c:1089 +#, c-format +msgid "index operators must be binary" +msgstr "인덱스 연산자는 바이너리여야 함" + +#: commands/opclasscmds.c:1108 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "\"%s\" 접근 방법은 정렬 작업을 지원하지 않음" + +#: commands/opclasscmds.c:1119 +#, c-format +msgid "index search operators must return boolean" +msgstr "인덱스 검색 연산자는 부울형을 반환해야 함" + +#: commands/opclasscmds.c:1159 +#, c-format +msgid "" +"associated data types for operator class options parsing functions must " +"match opclass input type" +msgstr "" + +#: commands/opclasscmds.c:1166 +#, c-format +msgid "" +"left and right associated data types for operator class options parsing " +"functions must match" +msgstr "" + +#: commands/opclasscmds.c:1174 +#, c-format +msgid "invalid operator class options parsing function" +msgstr "잘못된 연산자 클래스 옵션 구문 분석 함수" + +#: commands/opclasscmds.c:1175 +#, c-format +msgid "Valid signature of operator class options parsing function is %s." +msgstr "바른 연산자 클래스 옵션 구문 분석 함수는 %s." + +#: commands/opclasscmds.c:1194 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "btree 비교 함수는 두 개의 인자가 있어야 함" + +#: commands/opclasscmds.c:1198 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "btree 비교 함수는 반드시 integer 자료형을 반환해야 함" + +#: commands/opclasscmds.c:1215 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "" +"btree 정렬 지원 함수는 반드시 \"internal\" 자료형 입력 인자로 사용해야함" + +#: commands/opclasscmds.c:1219 +#, c-format +msgid "btree sort support functions must return void" +msgstr "btree 정렬 지원 함수는 반드시 void 값을 반환해야 함" + +#: commands/opclasscmds.c:1230 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "btree in_range 함수는 다섯개의 인자가 필요합니다" + +#: commands/opclasscmds.c:1234 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "btree in_range 함수는 boolean 자료형을 반환해야합니다" + +#: commands/opclasscmds.c:1250 +#, c-format +msgid "btree equal image functions must have one argument" +msgstr "btree equal image 함수는 한 개의 인자가 필요합니다" + +#: commands/opclasscmds.c:1254 +#, c-format +msgid "btree equal image functions must return boolean" +msgstr "btree equal image 함수는 boolean 자료형을 반환해야합니다" + +#: commands/opclasscmds.c:1267 +#, c-format +msgid "btree equal image functions must not be cross-type" +msgstr "btree equal image 함수는 교차형(cross-type)이 아니여야 합니다" + +#: commands/opclasscmds.c:1277 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "해시 함수는 1개의 인자만 지정할 수 있습니다" + +#: commands/opclasscmds.c:1281 +#, c-format +msgid "hash function 1 must return integer" +msgstr "해시 프로시저는 정수를 반환해야 함" + +#: commands/opclasscmds.c:1288 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "해시 함수 2는 2개의 인자만 지정할 수 있습니다" + +#: commands/opclasscmds.c:1292 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "해시 함수 2는 bigint형을 반환해야 함" + +#: commands/opclasscmds.c:1317 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "인덱스 지원 함수에 대해 관련 데이터 형식을 지정해야 함" + +#: commands/opclasscmds.c:1342 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "함수 번호 %d이(가) (%s,%s)에 대해 여러 번 표시됨" + +#: commands/opclasscmds.c:1349 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "연산자 번호 %d이(가) (%s,%s)에 대해 여러 번 표시됨" + +#: commands/opclasscmds.c:1398 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "%d(%s,%s) 연산자가 \"%s\" 연산자 패밀리에 이미 있음" + +#: commands/opclasscmds.c:1515 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "%d(%s,%s) 함수가 \"%s\" 연산자 패밀리에 이미 있음" + +#: commands/opclasscmds.c:1606 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "%d(%s,%s) 연산자가 \"%s\" 연산자 패밀리에 없음" + +#: commands/opclasscmds.c:1646 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "%d(%s,%s) 함수가 \"%s\" 연산자 패밀리에 없음" + +#: commands/opclasscmds.c:1776 +#, c-format +msgid "" +"operator class \"%s\" for access method \"%s\" already exists in schema \"%s" +"\"" +msgstr "" +"\"%s\" 연산자 클래스(\"%s\" 액세스 방법을 사용하는)는 이미 \"%s\" 스키마 안" +"에 있습니다" + +#: commands/opclasscmds.c:1799 +#, c-format +msgid "" +"operator family \"%s\" for access method \"%s\" already exists in schema \"%s" +"\"" +msgstr "\"%s\" 연산자 패밀리(접근 방법: \"%s\")가 \"%s\" 스키마에 이미 있음" + +#: commands/operatorcmds.c:111 commands/operatorcmds.c:119 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "SETOF 형식은 연산자 인자에 허용되지 않음" + +#: commands/operatorcmds.c:152 commands/operatorcmds.c:467 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "\"%s\" 연산자 속성을 처리할 수 없음" + +#: commands/operatorcmds.c:163 +#, c-format +msgid "operator function must be specified" +msgstr "자료형 함수를 지정하십시오" + +#: commands/operatorcmds.c:174 +#, c-format +msgid "at least one of leftarg or rightarg must be specified" +msgstr "왼쪽 이나 오른쪽 중 적어도 하나의 인자는 지정해야 합니다" + +#: commands/operatorcmds.c:278 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "%s 제한 예상 함수는 %s 자료형을 반환해야 함" + +#: commands/operatorcmds.c:321 +#, c-format +msgid "join estimator function %s has multiple matches" +msgstr "%s 조인 예상 함수가 여러개 있습니다" + +#: commands/operatorcmds.c:336 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "%s 조인 예상 함수는 %s 자료형을 반환해야 함" + +#: commands/operatorcmds.c:461 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "\"%s\" 연산자 속성 바꿀 수 없음" + +#: commands/policy.c:88 commands/policy.c:381 commands/policy.c:471 +#: commands/tablecmds.c:1512 commands/tablecmds.c:1994 +#: commands/tablecmds.c:3076 commands/tablecmds.c:5608 +#: commands/tablecmds.c:8395 commands/tablecmds.c:15632 +#: commands/tablecmds.c:15667 commands/trigger.c:301 commands/trigger.c:1206 +#: commands/trigger.c:1315 rewrite/rewriteDefine.c:277 +#: rewrite/rewriteDefine.c:933 rewrite/rewriteRemove.c:80 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "액세스 권한 없음: \"%s\" 시스템 카탈로그임" + +#: commands/policy.c:171 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "PUBLIC 아닌 지정한 모든 롤 무시함" + +#: commands/policy.c:172 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "모든 롤이 PUBLIC 롤의 소속입니다." + +#: commands/policy.c:495 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "\"%s\" 롤을 \"%s\" 정책 (대상 릴레이션: \"%s\")에서 삭제될 수 없음" + +#: commands/policy.c:704 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "WITH CHECK 옵션은 SELECT나 DELETE 작업에 적용 될 수 없음" + +#: commands/policy.c:713 commands/policy.c:1018 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "INSERT 구문에 대해서만 WITH CHECK 옵션을 허용합니다" + +#: commands/policy.c:788 commands/policy.c:1241 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "\"%s\" 정책이 \"%s\" 테이블에 이미 지정되어있습니다" + +#: commands/policy.c:990 commands/policy.c:1269 commands/policy.c:1340 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "\"%s\" 정책이 \"%s\" 테이블에 없음" + +#: commands/policy.c:1008 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "USING 구문만 SELECT, DELETE 작업에 쓸 수 있음" + +#: commands/portalcmds.c:59 commands/portalcmds.c:182 commands/portalcmds.c:233 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "잘못된 커서 이름: 비어있으면 안됩니다" + +#: commands/portalcmds.c:190 commands/portalcmds.c:243 +#: executor/execCurrent.c:70 utils/adt/xml.c:2594 utils/adt/xml.c:2764 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "\"%s\" 이름의 커서가 없음" + +#: commands/prepare.c:76 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "잘못된 명령문 이름: 비어있으면 안됩니다" + +#: commands/prepare.c:134 parser/parse_param.c:304 tcop/postgres.c:1498 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "$%d 매개 변수의 자료형을 알수가 없습니다." + +#: commands/prepare.c:152 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "utility 명령문들은 미리 준비할 수 없습니다" + +#: commands/prepare.c:256 commands/prepare.c:261 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "준비된 명령문이 SELECT 구문이 아닙니다." + +#: commands/prepare.c:328 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "prepared statement \"%s\"에 매개 변수 수가 틀렸습니다" + +#: commands/prepare.c:330 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "%d 개의 매개 변수가 요구되는데 %d 개만이 존재합니다" + +#: commands/prepare.c:363 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "??? parameter $%d of type %s 는 expected type %s 로 강요할 수 없다" + +#: commands/prepare.c:449 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "\"%s\" 이름의 준비된 명령문(prepared statement)이 이미 있습니다" + +#: commands/prepare.c:488 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "\"%s\" 이름의 준비된 명령문(prepared statement) 없음" + +#: commands/proclang.c:67 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "슈퍼유저만 사용자 지정 프로시저 언어를 만들 수 있음" + +#: commands/publicationcmds.c:107 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "\"publish\" 옵션의 목록 문법이 잘못됨" + +#: commands/publicationcmds.c:125 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "알 수 없는 \"publish\" 값: \"%s\"" + +#: commands/publicationcmds.c:140 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "인식할 수 없는 발행 매개 변수: \"%s\"" + +#: commands/publicationcmds.c:172 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "FOR ALL TABLES 옵션의 발행을 만드려면 슈퍼유저여야만 합니다" + +#: commands/publicationcmds.c:248 +#, c-format +msgid "wal_level is insufficient to publish logical changes" +msgstr "wal_level 수준이 논리 변경 사항 발행을 하기에는 부족합니다" + +#: commands/publicationcmds.c:249 +#, c-format +msgid "Set wal_level to logical before creating subscriptions." +msgstr "wal_level 값을 logical로 바꾸고 구독을 만들세요" + +#: commands/publicationcmds.c:369 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "\"%s\" 발행은 FOR ALL TABLES 옵션으로 정의되어 있습니다." + +#: commands/publicationcmds.c:371 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "" +"FOR ALL TABLES 발행에 새 테이블을 추가하거나 한 테이블을 뺄 수 없습니다." + +#: commands/publicationcmds.c:683 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "\"%s\" 릴레이션은 해당 발행에 포함되어 있지 않습니다" + +#: commands/publicationcmds.c:726 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "\"%s\" 발행의 소유주를 바꿀 권한이 없습니다" + +#: commands/publicationcmds.c:728 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "FOR ALL TABLES 옵션용 발행의 소유주는 슈퍼유저여야만 합니다" + +#: commands/schemacmds.c:105 commands/schemacmds.c:281 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "\"%s\" 스키마 이름이 적당하지 못합니다" + +#: commands/schemacmds.c:106 commands/schemacmds.c:282 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "" +"\"pg_\" 문자로 시작하는 스키마는 시스템에서 사용하는 예약된 스키마입니다." + +#: commands/schemacmds.c:120 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "\"%s\" 이름의 스키마(schema)가 이미 있음, 건너뜀" + +#: commands/seclabel.c:60 +#, c-format +msgid "no security label providers have been loaded" +msgstr "로드된 보안 라벨 제공자가 없음" + +#: commands/seclabel.c:64 +#, c-format +msgid "" +"must specify provider when multiple security label providers have been loaded" +msgstr "다중 보안 레이블 제공자가 로드 될 때 제공자를 지정해야 합니다." + +#: commands/seclabel.c:82 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "\"%s\" 이름의 보안 라벨 제공자가 로드되어 있지 않음" + +#: commands/sequence.c:140 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "로그를 남기지 않는 시퀀스는 지원하지 않음" + +#: commands/sequence.c:709 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "nextval: \"%s\" 시퀀스의 최대값(%s)이 되었습니다" + +#: commands/sequence.c:732 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "nextval: \"%s\" 시퀀스의 최소값(%s)이 되었습니다" + +#: commands/sequence.c:850 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "\"%s\" 시퀀스의 currval 값이 현재 세션에 지정되어 있지 않습니다" + +#: commands/sequence.c:869 commands/sequence.c:875 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "이 세션에는 lastval 값이 아직까지 지정되지 않았습니다" + +#: commands/sequence.c:963 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "setval: %s 값은 \"%s\" 시퀀스의 범위(%s..%s)를 벗어났습니다" + +#: commands/sequence.c:1360 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "잘못된 SEQUENCE NAME 시퀀스 옵션" + +#: commands/sequence.c:1386 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "식별 칼럼에 쓸 자료형은 smallint, integer, bigint 자료형만 쓸 수 있음" + +#: commands/sequence.c:1387 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "시퀀스에 쓸 자료형은 smallint, integer, bigint 자료형만 쓸 수 있음" + +#: commands/sequence.c:1421 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "INCREMENT 값은 0(zero)이 될 수 없습니다" + +#: commands/sequence.c:1474 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) 값이 허용 범위 밖임, 해당 시퀀스 자료형: %s" + +#: commands/sequence.c:1511 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) 값이 허용 범위 밖임, 해당 시퀀스 자료형: %s" + +#: commands/sequence.c:1525 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "MINVALUE (%s) 값은 MAXVALUE (%s) 값보다 작아야합니다" + +#: commands/sequence.c:1552 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "START 값(%s)은 MINVALUE(%s)보다 작을 수 없음" + +#: commands/sequence.c:1564 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "START 값(%s)은 MAXVALUE(%s)보다 클 수 없음" + +#: commands/sequence.c:1594 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "RESTART 값(%s)은 MINVALUE(%s)보다 작을 수 없음" + +#: commands/sequence.c:1606 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "RESTART 값(%s)은 MAXVALUE(%s)보다 클 수 없음" + +#: commands/sequence.c:1621 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "CACHE (%s) 값은 0(zero)보다 커야합니다" + +#: commands/sequence.c:1658 +#, c-format +msgid "invalid OWNED BY option" +msgstr "잘못된 OWNED BY 옵션" + +#: commands/sequence.c:1659 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "OWNED BY 테이블.열 또는 OWNED BY NONE을 지정하십시오." + +#: commands/sequence.c:1684 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr "참조되는 \"%s\" 릴레이션은 테이블 또는 외부 테이블이 아닙니다" + +#: commands/sequence.c:1691 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "시퀀스 및 이 시퀀스가 연결된 테이블의 소유주가 같아야 함" + +#: commands/sequence.c:1695 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "시퀀스 및 이 시퀀스가 연결된 테이블이 같은 스키마에 있어야 함" + +#: commands/sequence.c:1717 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "식별 시퀀스의 소유주는 바꿀 수 없음" + +#: commands/sequence.c:1718 commands/tablecmds.c:12544 +#: commands/tablecmds.c:15058 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "\"%s\" 시퀀스는 \"%s\" 테이블에 종속되어 있습니다." + +#: commands/statscmds.c:104 commands/statscmds.c:113 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICS 명령에서는 하나의 릴레이션만 사용할 수 있음" + +#: commands/statscmds.c:131 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "\"%s\" 개체는 테이블도, 외부 테이블도, 구체화된 뷰도 아닙니다" + +#: commands/statscmds.c:174 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "\"%s\" 이름의 통계정보 개체가 이미 있습니다, 건너뜀" + +#: commands/statscmds.c:182 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "\"%s\" 이름의 통계정보 개체가 이미 있음" + +#: commands/statscmds.c:204 commands/statscmds.c:210 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICS 명령에서는 단순 칼럼 참조만 허용합니다." + +#: commands/statscmds.c:225 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "시스템 칼럼에 대한 통계정보 개체 만들기는 지원하지 않습니다" + +#: commands/statscmds.c:232 +#, c-format +msgid "" +"column \"%s\" cannot be used in statistics because its type %s has no " +"default btree operator class" +msgstr "" +"\"%s\" 칼럼은 사용자 통계정보 수집이 불가능합니다. %s 자료형은 기본 btree 연" +"산자 클래스를 정의하지 않았습니다" + +#: commands/statscmds.c:239 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "통계정보 개체에서는 %d개보다 많은 칼럼을 사용할 수 없습니다" + +#: commands/statscmds.c:254 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "확장된 통계정보는 두 개 이상의 칼럼이 필요합니다." + +#: commands/statscmds.c:272 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "통계정보 정의에서 사용하는 칼럼이 중복되었습니다" + +#: commands/statscmds.c:306 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "알 수 없는 통계정보 종류 \"%s\"" + +#: commands/statscmds.c:444 commands/tablecmds.c:7416 +#, c-format +msgid "statistics target %d is too low" +msgstr "대상 통계값(%d)이 너무 낮습니다" + +#: commands/statscmds.c:452 commands/tablecmds.c:7424 +#, c-format +msgid "lowering statistics target to %d" +msgstr "%d 값으로 대상 통계값을 낮춥니다" + +#: commands/statscmds.c:475 +#, c-format +msgid "statistics object \"%s.%s\" does not exist, skipping" +msgstr "\"%s.%s\" 통계정보 개체 없음, 무시함" + +#: commands/subscriptioncmds.c:181 +#, c-format +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "알 수 없는 구독 매개 변수: \"%s\"" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:195 commands/subscriptioncmds.c:201 +#: commands/subscriptioncmds.c:207 commands/subscriptioncmds.c:226 +#: commands/subscriptioncmds.c:232 +#, c-format +msgid "%s and %s are mutually exclusive options" +msgstr "%s 옵션과 %s 옵션은 함께 사용할 수 없음" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:239 commands/subscriptioncmds.c:245 +#, c-format +msgid "subscription with %s must also set %s" +msgstr "%s 구독하려면, %s 설정이 필요함" + +#: commands/subscriptioncmds.c:287 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "\"%s\" 발행 이름이 여러 번 사용 됨" + +#: commands/subscriptioncmds.c:351 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "구독 만들기는 슈퍼유져 권한이 필요합니다" + +#: commands/subscriptioncmds.c:442 commands/subscriptioncmds.c:530 +#: replication/logical/tablesync.c:857 replication/logical/worker.c:2096 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "발행 서버에 연결 할 수 없음: %s" + +#: commands/subscriptioncmds.c:484 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "\"%s\" 이름의 복제 슬롯이 없습니다" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:497 +#, c-format +msgid "" +"tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "" +"구독하고 있는 테이블이 없습니다, %s 명령으로 테이블을 구독할 수 있습니다" + +#: commands/subscriptioncmds.c:586 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "\"%s.%s\" 테이블을 \"%s\" 구독에 추가했습니다" + +#: commands/subscriptioncmds.c:610 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "\"%s.%s\" 테이블을 \"%s\" 구독에서 삭제했습니다" + +#: commands/subscriptioncmds.c:682 +#, c-format +msgid "cannot set %s for enabled subscription" +msgstr "구독 활성화를 위해서는 %s 설정은 할 수 없음" + +#: commands/subscriptioncmds.c:717 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "슬롯 이름 없이는 구독을 활성화 할 수 없음" + +#: commands/subscriptioncmds.c:763 +#, c-format +msgid "" +"ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "" +"비활성화 상태인 구독에 대해서는 ALTER SUBSCRIPTION 명령으로 갱신할 수 없습니" +"다" + +#: commands/subscriptioncmds.c:764 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "" +"ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false) 명령을 " +"사용하세요." + +#: commands/subscriptioncmds.c:782 +#, c-format +msgid "" +"ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "" +"비활성화 상태인 구독에 대해서는 ALTER SUBSCRIPTION ... REFRESH 명령을 허용하" +"지 않습니다." + +#: commands/subscriptioncmds.c:862 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "\"%s\" 구독 없음, 건너뜀" + +#: commands/subscriptioncmds.c:987 +#, c-format +msgid "" +"could not connect to publisher when attempting to drop the replication slot " +"\"%s\"" +msgstr "\"%s\" 복제 슬롯을 삭제하는 중에는 발행 서버로 접속할 수 없음" + +#: commands/subscriptioncmds.c:989 commands/subscriptioncmds.c:1004 +#: replication/logical/tablesync.c:906 replication/logical/tablesync.c:928 +#, c-format +msgid "The error was: %s" +msgstr "해당 오류: %s" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:991 +#, c-format +msgid "Use %s to disassociate the subscription from the slot." +msgstr "구독과 슬롯을 분리할 때는 %s 명령을 사용하세요." + +#: commands/subscriptioncmds.c:1002 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "발행용 \"%s\" 복제 슬롯을 삭제 할 수 없음" + +#: commands/subscriptioncmds.c:1007 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "발행에서 \"%s\" 복제 슬롯을 삭제했음" + +#: commands/subscriptioncmds.c:1044 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "\"%s\" 구독 소유주를 변경할 권한이 없음" + +#: commands/subscriptioncmds.c:1046 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "구독 소유주는 슈퍼유저여야 합니다." + +#: commands/subscriptioncmds.c:1161 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "구독에서 복제 테이블 목록을 구할 수 없음: %s" + +#: commands/tablecmds.c:228 commands/tablecmds.c:270 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "\"%s\" 테이블 없음" + +#: commands/tablecmds.c:229 commands/tablecmds.c:271 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "\"%s\" 테이블 없음, 무시함" + +#: commands/tablecmds.c:231 commands/tablecmds.c:273 +msgid "Use DROP TABLE to remove a table." +msgstr "테이블을 삭제하려면, DROP TABLE 명령을 사용하세요." + +#: commands/tablecmds.c:234 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "\"%s\" 시퀀스 없음" + +#: commands/tablecmds.c:235 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "\"%s\" 시퀀스 없음, 무시함" + +#: commands/tablecmds.c:237 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "시퀀스를 삭제하려면 DROP SEQUENCE 명령을 사용하세요." + +#: commands/tablecmds.c:240 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "\"%s\" 뷰(view) 없음" + +#: commands/tablecmds.c:241 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "\"%s\" 뷰(view) 없음, 무시함" + +#: commands/tablecmds.c:243 +msgid "Use DROP VIEW to remove a view." +msgstr "뷰를 삭제하려면, DROP VIEW 명령을 사용하세요." + +#: commands/tablecmds.c:246 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr "\"%s\" 이름의 구체화된 뷰가 없음" + +#: commands/tablecmds.c:247 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr "\"%s\" 구체화된 뷰 없음, 건너뜀" + +#: commands/tablecmds.c:249 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "구체화된 뷰를 삭제하려면, DROP MATERIALIZED VIEW 명령을 사용하세요." + +#: commands/tablecmds.c:252 commands/tablecmds.c:276 commands/tablecmds.c:17231 +#: parser/parse_utilcmd.c:2172 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "\"%s\" 인덱스 없음" + +#: commands/tablecmds.c:253 commands/tablecmds.c:277 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "\"%s\" 인덱스 없음, 무시함" + +#: commands/tablecmds.c:255 commands/tablecmds.c:279 +msgid "Use DROP INDEX to remove an index." +msgstr "인덱스를 삭제하려면, DROP INDEX 명령을 사용하세요." + +#: commands/tablecmds.c:260 +#, c-format +msgid "\"%s\" is not a type" +msgstr "\"%s\" 개체는 자료형이 아님" + +#: commands/tablecmds.c:261 +msgid "Use DROP TYPE to remove a type." +msgstr "자료형을 삭제하려면 DROP TYPE 명령을 사용하세요." + +#: commands/tablecmds.c:264 commands/tablecmds.c:12383 +#: commands/tablecmds.c:14838 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "\"%s\" 외부 테이블 없음" + +#: commands/tablecmds.c:265 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "\"%s\" 외부 테이블 없음, 건너뜀" + +#: commands/tablecmds.c:267 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "외부 테이블을 삭제하려면, DROP FOREIGN TABLE 명령을 사용하세요." + +#: commands/tablecmds.c:620 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMIT 옵션은 임시 테이블에서만 사용될 수 있습니다" + +#: commands/tablecmds.c:651 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "보안 제한 작업 내에서 임시 테이블을 만들 수 없음" + +#: commands/tablecmds.c:687 commands/tablecmds.c:13742 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "\"%s\" 테이블이 여러 번 상속됨" + +#: commands/tablecmds.c:868 +#, c-format +msgid "" +"specifying a table access method is not supported on a partitioned table" +msgstr "테이블 접근 방법은 파티션된 테이블에서는 사용할 수 없음" + +#: commands/tablecmds.c:964 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "\"%s\" 파티션 된 테이블 아님" + +#: commands/tablecmds.c:1058 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "%d개보다 많은 칼럼을 이용해서 파티션할 수 없음" + +#: commands/tablecmds.c:1114 +#, c-format +msgid "cannot create foreign partition of partitioned table \"%s\"" +msgstr "\"%s\" 파티션된 테이블의 외부 파티션을 만들 수 없음" + +#: commands/tablecmds.c:1116 +#, c-format +msgid "Table \"%s\" contains indexes that are unique." +msgstr "\"%s\" 테이블은 유니크 인덱스를 포함 하고 있음." + +#: commands/tablecmds.c:1279 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLY 명령은 하나의 인덱스만 지울 수 있습니다" + +#: commands/tablecmds.c:1283 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLY 명령에서는 CASCADE 옵션을 사용할 수 없음" + +#: commands/tablecmds.c:1384 +#, c-format +msgid "cannot drop partitioned index \"%s\" concurrently" +msgstr "\"%s\" 파티션된 테이블의 인덱스에 대해서는 CONCURRENTLY 옵션을 사용할 수 없음" + +#: commands/tablecmds.c:1654 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "파티션 된 테이블만 truncate 할 수 없음" + +#: commands/tablecmds.c:1655 +#, c-format +msgid "" +"Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions " +"directly." +msgstr "" +"ONLY 옵션을 빼고 사용하거나, 하위 파티션 테이블을 대상으로 직접 TRUNCATE " +"ONLY 명령을 사용하세요." + +#: commands/tablecmds.c:1724 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "\"%s\" 개체의 자료도 함께 삭제됨" + +#: commands/tablecmds.c:2031 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "다른 세션의 임시 테이블 자료는 비울(truncate) 수 없습니다" + +#: commands/tablecmds.c:2259 commands/tablecmds.c:13639 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "\"%s\" 파티션 된 테이블로부터 상속할 수 없습니다" + +#: commands/tablecmds.c:2264 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "\"%s\" 파티션 테이블입니다, 그래서 상속 대상이 될 수 없습니다" + +#: commands/tablecmds.c:2272 parser/parse_utilcmd.c:2402 +#: parser/parse_utilcmd.c:2544 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "상속할 \"%s\" 릴레이션(relation)은 테이블도, 외부 테이블도 아닙니다" + +#: commands/tablecmds.c:2284 +#, c-format +msgid "" +"cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "" +"\"%s\" 테이블은 일반 테이블입니다. 임시 테이블을 이것의 파티션 테이블로 만들 " +"수 없습니다" + +#: commands/tablecmds.c:2293 commands/tablecmds.c:13618 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "\"%s\" 임시 테이블입니다, 그래서 상속 대상이 될 수 없습니다" + +#: commands/tablecmds.c:2303 commands/tablecmds.c:13626 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "다른 세션의 임시 테이블입니다, 그래서 상속 대상이 될 수 없습니다" + +#: commands/tablecmds.c:2357 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "\"%s\" 칼럼이 중복되어 상속됩니다." + +#: commands/tablecmds.c:2365 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "상위 테이블에서 지정한 \"%s\" 칼럼의 자료형들이 일치하지 않습니다" + +#: commands/tablecmds.c:2367 commands/tablecmds.c:2390 +#: commands/tablecmds.c:2639 commands/tablecmds.c:2669 +#: parser/parse_coerce.c:1935 parser/parse_coerce.c:1955 +#: parser/parse_coerce.c:1975 parser/parse_coerce.c:2030 +#: parser/parse_coerce.c:2107 parser/parse_coerce.c:2141 +#: parser/parse_param.c:218 +#, c-format +msgid "%s versus %s" +msgstr "%s 형과 %s 형" + +#: commands/tablecmds.c:2376 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "상속 받은 \"%s\" 칼럼의 정렬규칙에서 충돌합니다." + +#: commands/tablecmds.c:2378 commands/tablecmds.c:2651 +#: commands/tablecmds.c:6106 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "\"%s\" 형과 \"%s\" 형" + +#: commands/tablecmds.c:2388 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "상속 받은 \"%s\" 칼럼의 스토리지 설정값에서 충돌합니다" + +#: commands/tablecmds.c:2404 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "" + +#: commands/tablecmds.c:2490 commands/tablecmds.c:2545 +#: commands/tablecmds.c:11188 parser/parse_utilcmd.c:1252 +#: parser/parse_utilcmd.c:1295 parser/parse_utilcmd.c:1703 +#: parser/parse_utilcmd.c:1812 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "전체 로우 테이블 참조형으로 변환할 수 없음" + +#: commands/tablecmds.c:2491 parser/parse_utilcmd.c:1253 +#, c-format +msgid "" +"Generation expression for column \"%s\" contains a whole-row reference to " +"table \"%s\"." +msgstr "\"%s\" 칼럼용 미리 계산된 칼럼 생성식에 \"%s\" 테이블 전체 로우 참조가 있습니다" + +#: commands/tablecmds.c:2546 parser/parse_utilcmd.c:1296 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "\"%s\" 제약조건에 \"%s\" 테이블 전체 로우 참조가 있습니다" + +#: commands/tablecmds.c:2625 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "\"%s\" 칼럼을 상속된 정의와 병합하는 중" + +#: commands/tablecmds.c:2629 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "\"%s\" 칼럼을 상속된 정의와 이동, 병합하는 중" + +#: commands/tablecmds.c:2630 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "사용자 지정 칼럼이 상속된 칼럼의 위치로 이동되었습니다" + +#: commands/tablecmds.c:2637 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "\"%s\" 칼럼의 자료형이 충돌합니다" + +#: commands/tablecmds.c:2649 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "\"%s\" 칼럼의 정렬규칙이 충돌합니다" + +#: commands/tablecmds.c:2667 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "\"%s\" 칼럼의 스토리지 설정값이 충돌합니다" + +#: commands/tablecmds.c:2695 +#, c-format +msgid "child column \"%s\" specifies generation expression" +msgstr "" +"\"%s\" 칼럼은 상속 받은 칼럼임. 미리 계산된 칼럼의 생성식을 사용할 수 없음" + +#: commands/tablecmds.c:2697 +#, c-format +msgid "" +"Omit the generation expression in the definition of the child table column " +"to inherit the generation expression from the parent table." +msgstr "" + +#: commands/tablecmds.c:2701 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies default" +msgstr "상속 받은 \"%s\" 칼럼은 미리 계산된 칼럼인데, 기본값이 설정되어 있음" + +#: commands/tablecmds.c:2706 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies identity" +msgstr "상속 받은 \"%s\" 칼럼은 미리 계산된 칼럼인데, 일련번호 식별 옵션이 있음" + +#: commands/tablecmds.c:2815 +#, c-format +msgid "column \"%s\" inherits conflicting generation expressions" +msgstr "" +"상속 받는 \"%s\" 칼럼에 지정된 미리 계산된 생성식이 충돌함" +"다" + +#: commands/tablecmds.c:2820 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "상속 받는 \"%s\" 칼럼의 default 값이 충돌함" + +#: commands/tablecmds.c:2822 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "이 충돌을 피하려면, default 값을 바르게 지정하십시오." + +#: commands/tablecmds.c:2868 +#, c-format +msgid "" +"check constraint name \"%s\" appears multiple times but with different " +"expressions" +msgstr "" +"\"%s\" 체크 제약 조건 이름이 여러 번 나타나지만, 각각 다른 식으로 되어있음" + +#: commands/tablecmds.c:3045 +#, c-format +msgid "cannot rename column of typed table" +msgstr "칼럼 이름을 바꿀 수 없음" + +#: commands/tablecmds.c:3064 +#, c-format +msgid "" +"\"%s\" is not a table, view, materialized view, composite type, index, or " +"foreign table" +msgstr "" +"\"%s\" 개체는 테이블도, 뷰도, 구체화된 뷰도, 복합 자료형도, 인덱스도, 외부 테" +"이블도 아닙니다." + +#: commands/tablecmds.c:3158 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "하위 테이블에서도 상속된 \"%s\" 칼럼의 이름을 바꾸어야 함" + +#: commands/tablecmds.c:3190 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "\"%s\" 이름의 칼럼은 시스템 칼럼입니다, 이름을 바꿀 수 없습니다" + +#: commands/tablecmds.c:3205 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "\"%s\" 이름의 칼럼은 상속 받은 칼럼입니다, 이름을 바꿀 수 없습니다" + +#: commands/tablecmds.c:3357 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "" +"하위 테이블에서도 상속된 \"%s\" 제약조건은 하위 테이블에서도 이름이 바뀌어야 " +"함" + +#: commands/tablecmds.c:3364 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "\"%s\" 상속된 제약조건은 이름을 바꿀 수 없습니다" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3597 +#, c-format +msgid "" +"cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "이 세션의 활성 쿼리에서 사용 중이므로 %s \"%s\" 작업을 할 수 없음" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3606 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "보류 중인 트리거 이벤트가 있으므로 %s \"%s\" 작업을 할 수 없음" + +#: commands/tablecmds.c:4237 commands/tablecmds.c:4252 +#, c-format +msgid "cannot change persistence setting twice" +msgstr "로그 사용/미사용 옵션을 중복 해서 지정했음" + +#: commands/tablecmds.c:4969 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "\"%s\" 시스템 릴레이션을 다시 쓰기(rewrite) 할 수 없음" + +#: commands/tablecmds.c:4975 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "카탈로그 테이블로 사용되어 \"%s\" 테이블을 rewrite 못함" + +#: commands/tablecmds.c:4985 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "다른 세션의 임시 테이블을 다시 쓰기(rewrite) 할 수 없음" + +#: commands/tablecmds.c:5274 +#, c-format +msgid "rewriting table \"%s\"" +msgstr "\"%s\" 파일 다시 쓰는 중" + +#: commands/tablecmds.c:5278 +#, c-format +msgid "verifying table \"%s\"" +msgstr "\"%s\" 파일 검사 중" + +#: commands/tablecmds.c:5443 +#, c-format +msgid "column \"%s\" of relation \"%s\" contains null values" +msgstr "\"%s\" 열(해당 릴레이션 \"%s\")의 자료 가운데 null 값이 있습니다" + +#: commands/tablecmds.c:5460 +#, c-format +msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" +msgstr "\"%s\" 체크 제약 조건(해당 릴레이션 \"%s\")을 위반하는 몇몇 자료가 있습니다" + +#: commands/tablecmds.c:5479 partitioning/partbounds.c:3235 +#, c-format +msgid "" +"updated partition constraint for default partition \"%s\" would be violated " +"by some row" +msgstr "" +"몇몇 자료가 \"%s\" 기본 파티션용에서 변경된 파티션 제약조건을 위배한 것 같음" + +#: commands/tablecmds.c:5485 +#, c-format +msgid "partition constraint of relation \"%s\" is violated by some row" +msgstr "\"%s\" 릴레이션의 파티션 제약 조건을 위반하는 몇몇 자료가 있습니다" + +#: commands/tablecmds.c:5632 commands/trigger.c:1200 commands/trigger.c:1306 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "\"%s\" 개체는 테이블, 뷰, 외부 테이블 그 어느 것도 아닙니다" + +#: commands/tablecmds.c:5635 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "\"%s\" 개체는 테이블, 뷰, 구체화된 뷰, 인덱스 그 어느 것도 아닙니다" + +#: commands/tablecmds.c:5641 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "\"%s\" 개체는 테이블, 구체화된 뷰, 인덱스 그 어느 것도 아닙니다" + +#: commands/tablecmds.c:5644 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "\"%s\" 개체는 테이블, 구체화된 뷰, 외부 테이블 그 어느 것도 아닙니다." + +#: commands/tablecmds.c:5647 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "\"%s\" 개체는 테이블도 외부 테이블도 아닙니다" + +#: commands/tablecmds.c:5650 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "\"%s\" 개체는 테이블, 복합 자료형, 외부 테이블 그 어느 것도 아닙니다." + +#: commands/tablecmds.c:5653 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "" +"\"%s\" 개체는 테이블, 구체화된 뷰, 인덱스, 외부 테이블 그 어느 것도 아닙니다." + +#: commands/tablecmds.c:5663 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "\"%s\" 개체는 잘못된 개체형입니다." + +#: commands/tablecmds.c:5866 commands/tablecmds.c:5873 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "\"%s\" 자료형 변경할 수 없음(\"%s.%s\" 칼럼에서 해당 형식을 사용함)" + +#: commands/tablecmds.c:5880 +#, c-format +msgid "" +"cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "" +"\"%s\" 외부 테이블을 변경할 수 없음(\"%s.%s\" 칼럼에서 해당 로우 형을 사용함)" + +#: commands/tablecmds.c:5887 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "" +"\"%s\" 테이블을 변경할 수 없음(\"%s.%s\" 칼럼에서 해당 로우 형식을 사용함)" + +#: commands/tablecmds.c:5943 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "" +"\"%s\" 자료형을 변경할 수 없음, 이 자료형은 typed 테이블의 자료형이기 때문" + +#: commands/tablecmds.c:5945 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "" +"이 개체와 관계된 모든 개체들을 함께 변경하려면 ALTER ... CASCADE 명령을 사용" +"하십시오" + +#: commands/tablecmds.c:5991 +#, c-format +msgid "type %s is not a composite type" +msgstr "%s 자료형은 복합 자료형이 아닙니다" + +#: commands/tablecmds.c:6018 +#, c-format +msgid "cannot add column to typed table" +msgstr "typed 테이블에는 칼럼을 추가 할 수 없음" + +#: commands/tablecmds.c:6069 +#, c-format +msgid "cannot add column to a partition" +msgstr "파티션 테이블에는 칼럼을 추가 할 수 없습니다" + +#: commands/tablecmds.c:6098 commands/tablecmds.c:13869 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "" +"\"%s\" 상속된 테이블의 \"%s\" 열 자료형이 상위 테이블의 자료형과 틀립니다" + +#: commands/tablecmds.c:6104 commands/tablecmds.c:13876 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "" +"\"%s\" 상속된 테이블의 \"%s\" 칼럼 정렬규칙이 상위 테이블의 정렬규칙과 틀립니" +"다" + +#: commands/tablecmds.c:6118 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "\"%s\" 열(\"%s\" 하위)의 정의를 병합하는 중" + +#: commands/tablecmds.c:6161 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "하위 테이블에 재귀적으로 식별 칼럼을 추가할 수는 없음" + +#: commands/tablecmds.c:6398 +#, c-format +msgid "column must be added to child tables too" +msgstr "하위 테이블에도 칼럼을 추가해야 함" + +#: commands/tablecmds.c:6476 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "\"%s\" 이름의 칼럼이 \"%s\" 릴레이션에 이미 있습니다, 건너뜀" + +#: commands/tablecmds.c:6483 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "\"%s\" 이름의 칼럼은 \"%s\" 릴레이션에 이미 있습니다" + +#: commands/tablecmds.c:6549 commands/tablecmds.c:10826 +#, c-format +msgid "" +"cannot remove constraint from only the partitioned table when partitions " +"exist" +msgstr "하위 테이블이 있는 경우, 상위 테이블의 제약조건만 지울 수는 없음" + +#: commands/tablecmds.c:6550 commands/tablecmds.c:6854 +#: commands/tablecmds.c:7834 commands/tablecmds.c:10827 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "ONLY 옵션을 빼고 사용하세요." + +#: commands/tablecmds.c:6587 commands/tablecmds.c:6780 +#: commands/tablecmds.c:6922 commands/tablecmds.c:7036 +#: commands/tablecmds.c:7130 commands/tablecmds.c:7189 +#: commands/tablecmds.c:7291 commands/tablecmds.c:7457 +#: commands/tablecmds.c:7527 commands/tablecmds.c:7620 +#: commands/tablecmds.c:10981 commands/tablecmds.c:12406 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "\"%s\" 칼럼은 시스템 칼럼입니다. 그래서 변경될 수 없습니다" + +#: commands/tablecmds.c:6593 commands/tablecmds.c:6928 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "\"%s\" 칼럼(해당 테이블: \"%s\")은 식별 칼럼입니다." + +#: commands/tablecmds.c:6629 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "\"%s\" 칼럼은 기본키 칼럼입니다" + +#: commands/tablecmds.c:6651 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "파티션 테이블에서 \"%s\" 칼럼은 NOT NULL 속성으로 되어 있습니다" + +#: commands/tablecmds.c:6851 commands/tablecmds.c:8293 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "하위 테이블에도 제약 조건을 추가해야 함" + +#: commands/tablecmds.c:6852 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")은 이미 NOT NULL 속성이 없습니다." + +#: commands/tablecmds.c:6887 +#, c-format +msgid "" +"existing constraints on column \"%s.%s\" are sufficient to prove that it " +"does not contain nulls" +msgstr "" + +#: commands/tablecmds.c:6930 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "" +"대신에, ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY 명령을 사용하세요." + +#: commands/tablecmds.c:6935 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "\"%s\" 칼럼(해당 테이블: \"%s\")은 계산된 칼럼입니다." + +#: commands/tablecmds.c:6938 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." +msgstr "" +"대신에, ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION 명령을 사용하세요." + +#: commands/tablecmds.c:7047 +#, c-format +msgid "" +"column \"%s\" of relation \"%s\" must be declared NOT NULL before identity " +"can be added" +msgstr "" +"식별자 옵션을 사용하려면, \"%s\" 칼럼(해당 릴레이션: \"%s\")에 NOT NULL " +"옵션이 있어야 합니다." + +#: commands/tablecmds.c:7053 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "\"%s\" 이름의 칼럼(해당 릴레이션: \"%s\")은 이미 식별 칼럼입니다" + +#: commands/tablecmds.c:7059 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "\"%s\" 이름의 칼럼(해당 릴레이션: \"%s\")은 이미 default 입니다" + +#: commands/tablecmds.c:7136 commands/tablecmds.c:7197 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "\"%s\" 이름의 칼럼(해당 릴레이션: \"%s\")은 식별 칼럼이 아닙니다" + +#: commands/tablecmds.c:7202 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "\"%s\" 이름의 칼럼(해당 릴레이션: \"%s\")은 식별 칼럼이 아님, 건너뜀" + +#: commands/tablecmds.c:7261 +#, c-format +msgid "cannot drop generation expression from inherited column" +msgstr "상속 받은 칼럼에서는 미리 계산된 표현식을 못 없앰" + +#: commands/tablecmds.c:7299 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")은 미리 계산된 칼럼이 아님" + +#: commands/tablecmds.c:7304 +#, c-format +msgid "" +"column \"%s\" of relation \"%s\" is not a stored generated column, skipping" +msgstr "\"%s\" 칼럼(해당 릴레이션: \"%s\")은 미리 계산된 칼럼이 아님, 건너뜀" + +#: commands/tablecmds.c:7404 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "" + +#: commands/tablecmds.c:7447 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "%d번째 칼럼이 없습니다. 해당 릴레이션: \"%s\"" + +#: commands/tablecmds.c:7466 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "" +"\"%s\" 포함된 칼럼 (해당 인덱스: \"%s\") 관련 통계정보를 수정할 수 없음" + +#: commands/tablecmds.c:7471 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "" +"\"%s\" 비표현식 칼럼 (해당 인덱스: \"%s\") 관련 통계정보를 수정할 수 없음" + +#: commands/tablecmds.c:7473 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "대신에 테이블 칼럼 대상으로 통계정보를 수정하세요." + +#: commands/tablecmds.c:7600 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "잘못된 STORAGE 값: \"%s\"" + +#: commands/tablecmds.c:7632 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "%s 자료형의 column의 STORAGE 값은 반드시 PLAIN 이어야합니다" + +#: commands/tablecmds.c:7714 +#, c-format +msgid "cannot drop column from typed table" +msgstr "typed 테이블에서 칼럼을 삭제할 수 없음" + +#: commands/tablecmds.c:7773 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "\"%s\" 칼럼은 \"%s\" 릴레이션에 없음, 건너뜀" + +#: commands/tablecmds.c:7786 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "\"%s\" 칼럼은 시스템 칼럼입니다, 삭제될 수 없습니다" + +#: commands/tablecmds.c:7796 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "\"%s\" 칼럼은 상속받은 칼럼입니다, 삭제될 수 없습니다" + +#: commands/tablecmds.c:7809 +#, c-format +msgid "" +"cannot drop column \"%s\" because it is part of the partition key of " +"relation \"%s\"" +msgstr "" +"\"%s\" 칼럼은 \"%s\" 릴레이션의 파티션 키로 사용되고 있어 삭제 될 수 없음" + +#: commands/tablecmds.c:7833 +#, c-format +msgid "" +"cannot drop column from only the partitioned table when partitions exist" +msgstr "" +"파티션 테이블이 있는 파티션된 테이블에서 그 테이블만 칼럼을 삭제 할 수 없음" + +#: commands/tablecmds.c:8014 +#, c-format +msgid "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned " +"tables" +msgstr "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX 작업은 파티션 된 테이블 대상으로는 " +"지원하지 않음" + +#: commands/tablecmds.c:8039 +#, c-format +msgid "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX 작업은 \"%s\" 인덱스를 \"%s\" 이름으" +"로 바꿀 것입니다." + +#: commands/tablecmds.c:8373 +#, c-format +msgid "" +"cannot use ONLY for foreign key on partitioned table \"%s\" referencing " +"relation \"%s\"" +msgstr "" + +#: commands/tablecmds.c:8379 +#, c-format +msgid "" +"cannot add NOT VALID foreign key on partitioned table \"%s\" referencing " +"relation \"%s\"" +msgstr "" +"\"%s\" 파타션된 테이블에 NOT VALID 참조키를 추가할 수 없음 (참조 하는 테이" +"블: \"%s\")" + +#: commands/tablecmds.c:8382 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "이 기능은 파티션 된 테이블 대상으로는 아직 지원하지 않습니다." + +#: commands/tablecmds.c:8389 commands/tablecmds.c:8794 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "참조된 \"%s\" 릴레이션은 테이블이 아닙니다" + +#: commands/tablecmds.c:8412 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "영구 저장용 테이블의 제약 조건은 영구 저장용 테이블을 참조 합니다." + +#: commands/tablecmds.c:8419 +#, c-format +msgid "" +"constraints on unlogged tables may reference only permanent or unlogged " +"tables" +msgstr "" +"unlogged 테이블의 제약 조건은 영구 저장용 테이블 또는 unlogged 테이블을 참조" +"합니다." + +#: commands/tablecmds.c:8425 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "임시 테이블의 제약 조건은 임시 테이블에 대해서만 참조할 것입니다." + +#: commands/tablecmds.c:8429 +#, c-format +msgid "" +"constraints on temporary tables must involve temporary tables of this session" +msgstr "" +"임시 테이블의 제약 조건은 이 세션용 임시 테이블에 대해서만 적용 됩니다." + +#: commands/tablecmds.c:8495 commands/tablecmds.c:8501 +#, c-format +msgid "" +"invalid %s action for foreign key constraint containing generated column" +msgstr "계산된 칼럼을 포함하는 참조키 제약조건용 %s 액션은 잘못 되었음" + +#: commands/tablecmds.c:8517 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "참조키(foreign key) disagree를 위한 참조하는, 또는 참조되는 열 수" + +#: commands/tablecmds.c:8624 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "\"%s\" 참조키(foreign key) 제약 조건은 구현되어질 수 없습니다" + +#: commands/tablecmds.c:8626 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "" +"\"%s\" 열과 \"%s\" 열 인덱스는 함께 사용할 수 없는 자료형입니다: %s and %s." + +#: commands/tablecmds.c:8989 commands/tablecmds.c:9382 +#: parser/parse_utilcmd.c:764 parser/parse_utilcmd.c:893 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "참조키 제약 조건은 외부 테이블에서는 사용할 수 없음" + +#: commands/tablecmds.c:9748 commands/tablecmds.c:9911 +#: commands/tablecmds.c:10783 commands/tablecmds.c:10858 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "\"%s\" 제약 조건이 \"%s\" 릴레이션에 없습니다." + +#: commands/tablecmds.c:9755 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "\"%s\" 제약 조건(해당 테이블: \"%s\")은 참조키 제약조건이 아닙니다." + +#: commands/tablecmds.c:9919 +#, c-format +msgid "" +"constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "" +"\"%s\" 제약 조건(해당 테이블: \"%s\")은 참조키도 체크 제약 조건도 아닙니다." + +#: commands/tablecmds.c:9997 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "하위 테이블에도 제약 조건이 유효해야 함" + +#: commands/tablecmds.c:10081 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "참조키(foreign key) 제약 조건에서 참조하는 \"%s\" 칼럼이 없음" + +#: commands/tablecmds.c:10086 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "참조키(foreign key)에서 %d 키 개수보다 많이 가질 수 없음" + +#: commands/tablecmds.c:10151 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "참조되는 \"%s\" 테이블의 지연 가능한 기본키를 사용할 수 없음" + +#: commands/tablecmds.c:10168 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "참조되는 \"%s\" 테이블에는 기본키(primary key)가 없습니다" + +#: commands/tablecmds.c:10233 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "참조키의 참조 칼럼 목록에 칼럼이 중복되면 안됩니다" + +#: commands/tablecmds.c:10327 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "참조되는 \"%s\" 테이블의 지연 가능한 유니크 제약 조건을 사용할 수 없음" + +#: commands/tablecmds.c:10332 +#, c-format +msgid "" +"there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "" +"참조되는 \"%s\" 테이블을 위한 주워진 키와 일치하는 고유 제약 조건이 없습니다" + +#: commands/tablecmds.c:10420 +#, c-format +msgid "validating foreign key constraint \"%s\"" +msgstr "\"%s\" 참조키 제약 조건 검사 중" + +#: commands/tablecmds.c:10739 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "상속된 \"%s\" 제약 조건(해당 테이블: \"%s\")을 삭제할 수 없음" + +#: commands/tablecmds.c:10789 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "\"%s\" 제약 조건(해당 테이블: \"%s\")이 없음, 건너뜀" + +#: commands/tablecmds.c:10965 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "typed 테이블의 칼럼 자료형은 변경할 수 없음" + +#: commands/tablecmds.c:10992 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "\"%s\" 이름의 칼럼은 상속 받은 칼럼입니다, 이름을 바꿀 수 없습니다" + +#: commands/tablecmds.c:11001 +#, c-format +msgid "" +"cannot alter column \"%s\" because it is part of the partition key of " +"relation \"%s\"" +msgstr "" +"\"%s\" 칼럼은 \"%s\" 테이블의 파티션 키 가운데 하나이기 때문에, alter 작업" +"을 할 수 없음" + +#: commands/tablecmds.c:11051 +#, c-format +msgid "" +"result of USING clause for column \"%s\" cannot be cast automatically to " +"type %s" +msgstr "" +"\"%s\" 칼럼에서 쓰인 USING 절의 결과가 %s 자료형으로 자동 형변환을 할 수 없음" + +#: commands/tablecmds.c:11054 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "명시적 형변환을 해야할 것 같습니다." + +#: commands/tablecmds.c:11058 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "\"%s\" 칼럼의 자료형을 %s 형으로 형변환할 수 없음" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:11061 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "\"USING %s::%s\" 구문을 추가해야 할 것 같습니다." + +#: commands/tablecmds.c:11161 +#, c-format +msgid "cannot alter inherited column \"%s\" of relation \"%s\"" +msgstr "" +"\"%s\" 칼럼은 \"%s\" 테이블의 상속된 칼럼이기에 alter 작업을 할 수 없음" + +#: commands/tablecmds.c:11189 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "USING 표현식에서 전체 로우 테이블 참조를 포함하고 있습니다." + +#: commands/tablecmds.c:11200 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "하위 테이블에서도 상속된 \"%s\" 칼럼의 형식을 바꾸어야 함" + +#: commands/tablecmds.c:11325 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "\"%s\" 칼럼은 시스템 칼럼입니다. 그래서 변경될 수 없습니다" + +#: commands/tablecmds.c:11363 +#, c-format +msgid "" +"generation expression for column \"%s\" cannot be cast automatically to type " +"%s" +msgstr "\"%s\" 칼럼의 생성 구문은 %s 형으로 자동 형변환할 수 없음" + +#: commands/tablecmds.c:11368 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "\"%s\" 칼럼의 기본 값을 %s 형으로 형변환할 수 없음" + +#: commands/tablecmds.c:11446 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "미리 계산된 칼럼의 자료형을 바꿀 수 없음" + +#: commands/tablecmds.c:11447 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "\"%s\" 칼럼은 미리 계산된 칼럼인 \"%s\"에서 사용되고 있음." + +#: commands/tablecmds.c:11468 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "뷰 또는 규칙에서 사용하는 칼럼의 형식을 변경할 수 없음" + +#: commands/tablecmds.c:11469 commands/tablecmds.c:11488 +#: commands/tablecmds.c:11506 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%s 의존대상 열: \"%s\"" + +#: commands/tablecmds.c:11487 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "트리거 정의에서 사용하는 칼럼의 자료형을 변경할 수 없음" + +#: commands/tablecmds.c:11505 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "정책 정의에서 사용하는 칼럼의 자료형을 변경할 수 없음" + +#: commands/tablecmds.c:12514 commands/tablecmds.c:12526 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "\"%s\" 인덱스의 소유주를 바꿀 수 없음" + +#: commands/tablecmds.c:12516 commands/tablecmds.c:12528 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "대신에 그 인덱스의 해당 테이블 소유자을 변경하세요." + +#: commands/tablecmds.c:12542 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "\"%s\" 시퀀스의 소유주를 바꿀 수 없음" + +#: commands/tablecmds.c:12556 commands/tablecmds.c:15743 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "대신 ALTER TYPE을 사용하십시오." + +#: commands/tablecmds.c:12565 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "\"%s\" 개체는 테이블, 뷰, 시퀀스, 외부 테이블 그 어느 것도 아닙니다" + +#: commands/tablecmds.c:12905 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "SET TABLESPACE 구문이 중복 사용되었습니다" + +#: commands/tablecmds.c:12982 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "" +"\"%s\" 개체는 테이블, 뷰, 구체화된 뷰, 인덱스, TOAST 테이블 그 어느 것도 아닙" +"니다." + +#: commands/tablecmds.c:13015 commands/view.c:494 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "" +"WITH CHECK OPTION 옵션은 자동 갱신 가능한 뷰에 대해서만 사용할 수 있습니다" + +#: commands/tablecmds.c:13155 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "\"%s\" 시스템 릴레이션입니다. 이동할 수 없습니다" + +#: commands/tablecmds.c:13171 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "다른 세션의 임시 테이블들은 이동할 수 없습니다" + +#: commands/tablecmds.c:13341 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "테이블스페이스에 테이블과 인덱스와 구체화된 뷰만 있습니다." + +#: commands/tablecmds.c:13353 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "" +"해당 개체를 pg_global 테이블스페이스로 옮기거나 그 반대로 작업할 수 없음" + +#: commands/tablecmds.c:13445 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "\"%s.%s\" 릴레이션을 잠글 수 없어 중지 중입니다" + +#: commands/tablecmds.c:13461 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "검색조건에 일치하는 릴레이션이 \"%s\" 테이블스페이스에 없음" + +#: commands/tablecmds.c:13577 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "typed 테이블의 상속 정보는 변경할 수 없음" + +#: commands/tablecmds.c:13582 commands/tablecmds.c:14078 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "파티션 테이블의 상속 정보는 바꿀 수 없음" + +#: commands/tablecmds.c:13587 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "파티션된 테이블의 상속 정보는 바꿀 수 없음" + +#: commands/tablecmds.c:13633 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "다른 세션의 임시 테이블을 상속할 수 없음" + +#: commands/tablecmds.c:13646 +#, c-format +msgid "cannot inherit from a partition" +msgstr "파티션 테이블에서 상속 할 수 없음" + +#: commands/tablecmds.c:13668 commands/tablecmds.c:16383 +#, c-format +msgid "circular inheritance not allowed" +msgstr "순환 되는 상속은 허용하지 않습니다" + +#: commands/tablecmds.c:13669 commands/tablecmds.c:16384 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "\"%s\" 개체는 이미 \"%s\" 개체로부터 상속받은 상태입니다." + +#: commands/tablecmds.c:13682 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "" +"\"%s\" 트리거(해당 테이블 \"%s\")은 하위테이블 상속과 관련되어 보호되고 있습" +"니다." + +#: commands/tablecmds.c:13684 +#, c-format +msgid "" +"ROW triggers with transition tables are not supported in inheritance " +"hierarchies." +msgstr "" +"transition 테이블의 ROW 트리거들은 계층적 상속 테이블에서는 지원하지 않음" + +#: commands/tablecmds.c:13887 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "자식 테이블의 \"%s\" 칼럼은 NOT NULL 속성이 있어야합니다" + +#: commands/tablecmds.c:13914 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "자식 테이블에는 \"%s\" 칼럼이 없습니다" + +#: commands/tablecmds.c:14002 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "\"%s\" 하위 테이블에 \"%s\" 체크 제약 조건에 대한 다른 정의가 있음" + +#: commands/tablecmds.c:14010 +#, c-format +msgid "" +"constraint \"%s\" conflicts with non-inherited constraint on child table \"%s" +"\"" +msgstr "" +"\"%s\" 제약 조건이 \"%s\" 하위 테이블에 있는 비 상속 제약 조건과 충돌합니다" + +#: commands/tablecmds.c:14021 +#, c-format +msgid "" +"constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "" +"\"%s\" 제약 조건이 \"%s\" 하위 테이블에 있는 NOT VALID 제약 조건과 충돌합니다" + +#: commands/tablecmds.c:14056 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "자식 테이블에 \"%s\" 제약 조건이 없습니다" + +#: commands/tablecmds.c:14145 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "\"%s\" 릴레이션은 \"%s\" 릴레이션의 파티션이 아닙니다" + +#: commands/tablecmds.c:14151 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "\"%s\" 릴레이션은 \"%s\" 릴레이션의 부모가 아닙니다" + +#: commands/tablecmds.c:14379 +#, c-format +msgid "typed tables cannot inherit" +msgstr "typed 테이블은 상속할 수 없음" + +#: commands/tablecmds.c:14409 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "테이블에는 \"%s\" 칼럼이 없습니다" + +#: commands/tablecmds.c:14420 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "\"%s\" 칼럼은 \"%s\" 자료형입니다." + +#: commands/tablecmds.c:14429 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "\"%s\" 테이블의 \"%s\" 칼럼 자료형 틀립니다" + +#: commands/tablecmds.c:14443 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "\"%s\" 칼럼은 확장형입니다" + +#: commands/tablecmds.c:14495 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "\"%s\" 테이블은 typed 테이블이 아닙니다" + +#: commands/tablecmds.c:14677 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "\"%s\" 인덱스는 유니크 인덱스가 아니여서, 복제 식별자로 사용할 수 없음" + +#: commands/tablecmds.c:14683 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "\"%s\" non-immediate 인덱스는 복제 식별자로 사용할 수 없음" + +#: commands/tablecmds.c:14689 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "\"%s\" 인덱스는 expression 인덱스여서, 복제 식별자로 사용할 수 없음" + +#: commands/tablecmds.c:14695 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "\"%s\" 인덱스가 부분인덱스여서, 복제 식별자로 사용할 수 없음" + +#: commands/tablecmds.c:14701 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "" +"\"%s\" 인덱스는 사용할 수 없는 인덱스여서, 복제 식별자로 사용할 수 없음" + +#: commands/tablecmds.c:14718 +#, c-format +msgid "" +"index \"%s\" cannot be used as replica identity because column %d is a " +"system column" +msgstr "" +"\"%s\" 인덱스는 복제 식별자로 사용할 수 없음, %d 번째 칼럼이 시스템 칼럼임" + +#: commands/tablecmds.c:14725 +#, c-format +msgid "" +"index \"%s\" cannot be used as replica identity because column \"%s\" is " +"nullable" +msgstr "" +"\"%s\" 인덱스는 복제 식별자로 사용할 수 없음, \"%s\" 칼럼이 null 값 사용가능 " +"속성임" + +#: commands/tablecmds.c:14918 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "\"%s\" 테이블은 임시 테이블이기에, 통계 정보를 변경 할 수 없음" + +#: commands/tablecmds.c:14942 +#, c-format +msgid "" +"cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "\"%s\" 테이블은 발생에 사용하고 있어, unlogged 속성으로 바꿀 수 없음" + +#: commands/tablecmds.c:14944 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "unlogged 릴레이션 복제할 수 없습니다." + +#: commands/tablecmds.c:14989 +#, c-format +msgid "" +"could not change table \"%s\" to logged because it references unlogged table " +"\"%s\"" +msgstr "" +"\"%s\" 테이블이 \"%s\" unlogged 테이블을 참조하고 있어 logged 속성으로 바꿀 " +"수 없음" + +#: commands/tablecmds.c:14999 +#, c-format +msgid "" +"could not change table \"%s\" to unlogged because it references logged table " +"\"%s\"" +msgstr "" +"\"%s\" 테이블이 \"%s\" logged 테이블을 참조하고 있어 unlogged 속성으로 바꿀 " +"수 없음" + +#: commands/tablecmds.c:15057 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "소유된 시퀀스를 다른 스키마로 이동할 수 없음" + +#: commands/tablecmds.c:15163 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" 릴레이션이 \"%s\" 스키마에 이미 있습니다" + +#: commands/tablecmds.c:15726 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "\"%s\" 개체는 복합 자료형입니다" + +#: commands/tablecmds.c:15758 +#, c-format +msgid "" +"\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "" +"\"%s\" 개체는 테이블, 뷰, 구체화된 뷰, 시퀀스, 외부 테이블 그 어느 것도 아닙" +"니다" + +#: commands/tablecmds.c:15793 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "알 수 없는 파티션 규칙 \"%s\"" + +#: commands/tablecmds.c:15801 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "둘 이상의 칼럼을 사용할 \"list\" 파티션은 사용할 수 없습니다" + +#: commands/tablecmds.c:15867 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "\"%s\" 칼럼이 파티션 키로 사용되고 있지 않습니다" + +#: commands/tablecmds.c:15875 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "\"%s\" 칼럼은 시스템 칼럼입니다. 그래서 파티션 키로 사용될 수 없습니다" + +#: commands/tablecmds.c:15886 commands/tablecmds.c:16000 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "미리 계산된 칼럼은 파티션 키로 사용할 수 없음" + +#: commands/tablecmds.c:15887 commands/tablecmds.c:16001 commands/trigger.c:641 +#: rewrite/rewriteHandler.c:829 rewrite/rewriteHandler.c:846 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "\"%s\" 칼럼은 미리 계산된 칼럼입니다." + +#: commands/tablecmds.c:15963 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "파티션 키로 사용할 함수는 IMMUTABLE 특성이 있어야합니다" + +#: commands/tablecmds.c:15983 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "파티션 키 표현식에서는 시스템 칼럼 참조를 포함할 수 없습니다" + +#: commands/tablecmds.c:16013 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "파티션 키로 상수는 쓸 수 없습니다" + +#: commands/tablecmds.c:16034 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "파티션 표현식에 쓸 문자 정렬 규칙을 결정할 수 없습니다" + +#: commands/tablecmds.c:16069 +#, c-format +msgid "" +"You must specify a hash operator class or define a default hash operator " +"class for the data type." +msgstr "" +"해당 자료형을 위한 해시 연산자 클래스를 지정하거나 기본 해시 연산자 클래스를 " +"정의해 두어야합니다" + +#: commands/tablecmds.c:16075 +#, c-format +msgid "" +"You must specify a btree operator class or define a default btree operator " +"class for the data type." +msgstr "" +"해당 자료형을 위한 btree 연산자 클래스를 지정하거나 기본 btree 연산자 클래스" +"를 정의해 두어야합니다" + +#: commands/tablecmds.c:16220 +#, c-format +msgid "" +"partition constraint for table \"%s\" is implied by existing constraints" +msgstr "" + +#: commands/tablecmds.c:16224 partitioning/partbounds.c:3129 +#: partitioning/partbounds.c:3180 +#, c-format +msgid "" +"updated partition constraint for default partition \"%s\" is implied by " +"existing constraints" +msgstr "" + +#: commands/tablecmds.c:16323 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\" 이름의 파티션 테이블이 이미 있습니다" + +#: commands/tablecmds.c:16329 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "파티션 테이블로 typed 테이블을 추가할 수 없음" + +#: commands/tablecmds.c:16345 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "파티션 테이블로 상속을 이용한 하위 테이블을 추가할 수 없음" + +#: commands/tablecmds.c:16359 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "파티션 테이블로 상속용 상위 테이블을 추가할 수 없음" + +#: commands/tablecmds.c:16393 +#, c-format +msgid "" +"cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "" +"\"%s\" 테이블은 일반 테이블입니다, 임시 파티션 테이블을 추가할 수 없습니다" + +#: commands/tablecmds.c:16401 +#, c-format +msgid "" +"cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "" +"\"%s\" 테이블은 임시 테이블입니다, 일반 파티션 테이블을 추가할 수 없습니다" + +#: commands/tablecmds.c:16409 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "다른 세션의 임시 테이블을 파티션 테이블로 추가할 수 없습니다" + +#: commands/tablecmds.c:16416 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "다른 세션의 임시 테이블을 파티션 테이블로 추가할 수 없습니다" + +#: commands/tablecmds.c:16436 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "\"%s\" 테이블의 \"%s\" 칼럼이 상위 테이블인 \"%s\"에 없음" + +#: commands/tablecmds.c:16439 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "새 파티션 테이블은 상위 테이블의 칼럼과 동일해야 합니다." + +#: commands/tablecmds.c:16451 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "" +"\"%s\" 트리거가 \"%s\" 테이블에 있어 파티션 테이블로 포함 될 수 없습니다" + +#: commands/tablecmds.c:16453 commands/trigger.c:447 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "" +"ROW 트리거들이 있는 테이블을 파티션 테이블로 포함하는 기능은 지원하지 않습니" +"다" + +#: commands/tablecmds.c:16616 +#, c-format +msgid "" +"cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" +msgstr "\"%s\" 외부 테이블을 파티션된 \"%s\" 테이블의 부분으로 추가 할 수 없음" + +#: commands/tablecmds.c:16619 +#, c-format +msgid "Table \"%s\" contains unique indexes." +msgstr "\"%s\" 테이블에 유니크 인덱스가 있습니다." + +#: commands/tablecmds.c:17265 commands/tablecmds.c:17285 +#: commands/tablecmds.c:17305 commands/tablecmds.c:17324 +#: commands/tablecmds.c:17366 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "\"%s\" 인덱스를 \"%s\" 인덱스의 파티션으로 추가할 수 없음" + +#: commands/tablecmds.c:17268 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "\"%s\" 인덱스는 이미 다른 인덱스에 추가되어 있음." + +#: commands/tablecmds.c:17288 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "\"%s\" 인덱스는 \"%s\" 테이블의 하위 파티션 대상 인덱스가 아닙니다." + +#: commands/tablecmds.c:17308 +#, c-format +msgid "The index definitions do not match." +msgstr "인덱스 정의가 일치하지 않습니다." + +#: commands/tablecmds.c:17327 +#, c-format +msgid "" +"The index \"%s\" belongs to a constraint in table \"%s\" but no constraint " +"exists for index \"%s\"." +msgstr "" + +#: commands/tablecmds.c:17369 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "\"%s\" 파티션 용으로 다른 인덱스가 추가되어 있습니다." + +#: commands/tablespace.c:162 commands/tablespace.c:179 +#: commands/tablespace.c:190 commands/tablespace.c:198 +#: commands/tablespace.c:638 replication/slot.c:1373 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 만들 수 없음: %m" + +#: commands/tablespace.c:209 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 상태를 파악할 수 없음: %m" + +#: commands/tablespace.c:218 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "\"%s\" 파일이 존재하지만 디렉터리가 아닙니다" + +#: commands/tablespace.c:249 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "\"%s\" 테이블스페이스를 만들 권한이 없습니다" + +#: commands/tablespace.c:251 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "테이블스페이스는 슈퍼유저만 만들 수 있습니다." + +#: commands/tablespace.c:267 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "테이블스페이스 위치에는 작은 따옴표를 사용할 수 없음" + +#: commands/tablespace.c:277 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "테이블스페이스 경로는 절대경로여야합니다" + +#: commands/tablespace.c:289 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "테이블스페이스 경로가 너무 깁니다: \"%s\"" + +#: commands/tablespace.c:296 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "테이블스페이스 경로는 데이터 디렉터리 안에 있으면 안됩니다" + +#: commands/tablespace.c:305 commands/tablespace.c:965 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "\"%s\" 테이블스페이스 이름은 적당치 않습니다" + +#: commands/tablespace.c:307 commands/tablespace.c:966 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "\"pg_\" 문자로 시작하는 테이블스페이스는 시스템 테이블스페이스입니다." + +#: commands/tablespace.c:326 commands/tablespace.c:987 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "\"%s\" 이름의 테이블스페이스는 이미 있음" + +#: commands/tablespace.c:442 commands/tablespace.c:948 +#: commands/tablespace.c:1037 commands/tablespace.c:1106 +#: commands/tablespace.c:1252 commands/tablespace.c:1455 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "\"%s\" 테이블스페이스 없음" + +#: commands/tablespace.c:448 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "\"%s\" 테이블스페이스 없음, 건너 뜀" + +#: commands/tablespace.c:525 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "\"%s\" 테이블스페이스는 비어있지 않음" + +#: commands/tablespace.c:597 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "\"%s\" 디렉터리 없음" + +#: commands/tablespace.c:598 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "이 서버를 재시작하기 전에 이 테이블스페이스 용 디렉터리를 만드세요." + +#: commands/tablespace.c:603 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 액세스 권한을 지정할 수 없음: %m" + +#: commands/tablespace.c:633 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "\"%s\" 디렉터리는 이미 테이블스페이스로 사용 중임" + +#: commands/tablespace.c:757 commands/tablespace.c:770 +#: commands/tablespace.c:806 commands/tablespace.c:898 storage/file/fd.c:3108 +#: storage/file/fd.c:3448 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 삭제할 수 없음: %m" + +#: commands/tablespace.c:819 commands/tablespace.c:907 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "\"%s\" 심벌릭 링크를 삭제할 수 없음: %m" + +#: commands/tablespace.c:829 commands/tablespace.c:916 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "\"%s\" 디렉터리도, 심볼릭 링크도 아님" + +#: commands/tablespace.c:1111 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "\"%s\" 테이블스페이스 없음" + +#: commands/tablespace.c:1554 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "%u OID 테이블스페이스용 디렉터리는 삭제될 수 없음" + +#: commands/tablespace.c:1556 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "필요하다면 OS 작업으로 그 디레터리를 삭제하세요" + +#: commands/trigger.c:204 commands/trigger.c:215 +#, c-format +msgid "\"%s\" is a table" +msgstr "\"%s\" 개체는 테이블입니다." + +#: commands/trigger.c:206 commands/trigger.c:217 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "테이블에 INSTEAD OF 트리거는 설정할 수 없음" + +#: commands/trigger.c:238 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\" 개체는 파티션된 테이블임" + +#: commands/trigger.c:240 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "파티션된 테이블에 지정된 트리거는 전달 테이블을 가질 수 없음." + +#: commands/trigger.c:252 commands/trigger.c:259 commands/trigger.c:429 +#, c-format +msgid "\"%s\" is a view" +msgstr "\"%s\" 개체는 뷰입니다." + +#: commands/trigger.c:254 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "뷰에 로우 단위 BEFORE, AFTER 트리거는 설정할 수 없음" + +#: commands/trigger.c:261 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "뷰에 TRUNCATE 트리거는 설정할 수 없음" + +#: commands/trigger.c:269 commands/trigger.c:276 commands/trigger.c:288 +#: commands/trigger.c:422 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "\"%s\" 개체는 외부 테이블입니다." + +#: commands/trigger.c:271 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "외부테이블에 INSTEAD OF 트리거는 설정할 수 없음" + +#: commands/trigger.c:278 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "외부 테이블에는 TRUNCATE 트리거를 사용할 수 없음" + +#: commands/trigger.c:290 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "외부 테이블에 제약 조건 트리거는 설정할 수 없음" + +#: commands/trigger.c:365 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "TRUNCATE FOR EACH ROW 트리거는 지원되지 않음" + +#: commands/trigger.c:373 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "INSTEAD OF 트리거는 FOR EACH ROW 옵션으로 설정해야 함" + +#: commands/trigger.c:377 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "INSTEAD OF 트리거는 WHEN 조건을 사용할 수 없음" + +#: commands/trigger.c:381 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "INSTEAD OF 트리거는 칼럼 목록을 사용할 수 없음" + +#: commands/trigger.c:410 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "" + +#: commands/trigger.c:411 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "" + +#: commands/trigger.c:424 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "외부 테이블의 트리거들은 전환 테이블을 가질 수 없음." + +#: commands/trigger.c:431 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "뷰에 정의한 트리거들은 전환 테이블을 가질 수 없음." + +#: commands/trigger.c:451 +#, c-format +msgid "" +"ROW triggers with transition tables are not supported on inheritance children" +msgstr "" + +#: commands/trigger.c:457 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "" + +#: commands/trigger.c:462 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "전환 테이블에서 TRUNCATE 트리거는 지원하지 않습니다" + +#: commands/trigger.c:479 +#, c-format +msgid "" +"transition tables cannot be specified for triggers with more than one event" +msgstr "전환 테이블은 하나 이상의 이벤트에 대한 트리거를 지정할 수 없습니다" + +#: commands/trigger.c:490 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "전환 테이블은 칼럼 목록들에 대한 트리거를 지정할 수 없습니다" + +#: commands/trigger.c:507 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "" + +#: commands/trigger.c:512 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "" + +#: commands/trigger.c:522 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "" + +#: commands/trigger.c:527 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "" + +#: commands/trigger.c:537 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "" + +#: commands/trigger.c:601 commands/trigger.c:614 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "트리거의 WHEN 조건에는 칼럼 값을 참조할 수는 없음" + +#: commands/trigger.c:606 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "INSERT 트리거에서의 WHEN 조건에는 OLD 값을 참조할 수 없음" + +#: commands/trigger.c:619 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "DELETE 트리거에서의 WHEN 조건에는 NEW 값을 참조할 수 없음" + +#: commands/trigger.c:624 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "WHEN 조건절이 있는 BEFORE 트리거는 NEW 시스템 칼럼을 참조할 수 없음" + +#: commands/trigger.c:632 commands/trigger.c:640 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "" +"WHEN 조건절이 있는 BEFORE 트리거는 NEW 미리 계산된 칼럼을 참조할 수 없음" + +#: commands/trigger.c:633 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "" + +#: commands/trigger.c:780 commands/trigger.c:1385 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "\"%s\" 이름의 트리거가 \"%s\" 테이블에 이미 있습니다" + +#: commands/trigger.c:1271 commands/trigger.c:1432 commands/trigger.c:1568 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "\"%s\" 트리거는 \"%s\" 테이블에 없음" + +#: commands/trigger.c:1515 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "액세스 권한 없음: \"%s\" 개체는 시스템 트리거임" + +#: commands/trigger.c:2116 +#, c-format +msgid "trigger function %u returned null value" +msgstr "%u 트리거 함수가 null 값을 리턴했습니다" + +#: commands/trigger.c:2176 commands/trigger.c:2390 commands/trigger.c:2625 +#: commands/trigger.c:2933 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "BEFORE STATEMENT 트리거는 리턴값이 있으면 안됩니다" + +#: commands/trigger.c:2250 +#, c-format +msgid "" +"moving row to another partition during a BEFORE FOR EACH ROW trigger is not " +"supported" +msgstr "" + +#: commands/trigger.c:2251 commands/trigger.c:2755 +#, c-format +msgid "" +"Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." +msgstr "" + +#: commands/trigger.c:2754 +#, c-format +msgid "" +"moving row to another partition during a BEFORE trigger is not supported" +msgstr "" + +#: commands/trigger.c:2996 executor/nodeModifyTable.c:1380 +#: executor/nodeModifyTable.c:1449 +#, c-format +msgid "" +"tuple to be updated was already modified by an operation triggered by the " +"current command" +msgstr "" +"현재 명령으로 실행된 트리거 작업으로 변경해야할 자료가 이미 바뀌었습니다." + +#: commands/trigger.c:2997 executor/nodeModifyTable.c:840 +#: executor/nodeModifyTable.c:914 executor/nodeModifyTable.c:1381 +#: executor/nodeModifyTable.c:1450 +#, c-format +msgid "" +"Consider using an AFTER trigger instead of a BEFORE trigger to propagate " +"changes to other rows." +msgstr "" +"다른 로우를 변경하는 일을 BEFORE 트리거 대신에 AFTER 트리거 사용을 고려해 보" +"십시오" + +#: commands/trigger.c:3026 executor/nodeLockRows.c:225 +#: executor/nodeLockRows.c:234 executor/nodeModifyTable.c:220 +#: executor/nodeModifyTable.c:856 executor/nodeModifyTable.c:1397 +#: executor/nodeModifyTable.c:1613 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "동시 업데이트 때문에 순차적 액세스가 불가능합니다" + +#: commands/trigger.c:3034 executor/nodeModifyTable.c:946 +#: executor/nodeModifyTable.c:1467 executor/nodeModifyTable.c:1637 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "동시 삭제 작업 때문에 순차적 액세스가 불가능합니다" + +#: commands/trigger.c:5094 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "\"%s\" 제약 조건은 DEFERRABLE 속성으로 만들어지지 않았습니다" + +#: commands/trigger.c:5117 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "\"%s\" 이름의 제약 조건이 없음" + +#: commands/tsearchcmds.c:118 commands/tsearchcmds.c:683 +#, c-format +msgid "function %s should return type %s" +msgstr "%s 함수는 %s 자료형을 반환해야 함" + +#: commands/tsearchcmds.c:195 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "슈퍼유저만 전문 검색 파서를 만들 수 있음" + +#: commands/tsearchcmds.c:248 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "\"%s\" 전문 검색 파서 매개 변수를 인식할 수 없음" + +#: commands/tsearchcmds.c:258 +#, c-format +msgid "text search parser start method is required" +msgstr "텍스트 검색 파서 start 메서드가 필요함" + +#: commands/tsearchcmds.c:263 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "텍스트 검색 파서 gettoken 메서드가 필요함" + +#: commands/tsearchcmds.c:268 +#, c-format +msgid "text search parser end method is required" +msgstr "텍스트 검색 파서 end 메서드가 필요함" + +#: commands/tsearchcmds.c:273 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "텍스트 검색 파서 lextypes 메서드가 필요함" + +#: commands/tsearchcmds.c:390 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "\"%s\" 전문 검색 템플릿이 옵션을 수락하지 않음" + +#: commands/tsearchcmds.c:464 +#, c-format +msgid "text search template is required" +msgstr "전문 검색 템플릿이 필요함" + +#: commands/tsearchcmds.c:750 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "슈퍼유저만 전문 검색 템플릿을 만들 수 있음" + +#: commands/tsearchcmds.c:792 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "\"%s\" 전문 검색 템플릿 매개 변수를 인식할 수 없음" + +#: commands/tsearchcmds.c:802 +#, c-format +msgid "text search template lexize method is required" +msgstr "전문 검색 템플릿 lexize 메서드가 필요함" + +#: commands/tsearchcmds.c:1006 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "\"%s\" 전문 검색 구성 매개 변수를 인식할 수 없음" + +#: commands/tsearchcmds.c:1013 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "PARSER 옵션과 COPY 옵션을 모두 지정할 수 없음" + +#: commands/tsearchcmds.c:1049 +#, c-format +msgid "text search parser is required" +msgstr "전문 검색 파서가 필요함" + +#: commands/tsearchcmds.c:1273 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "\"%s\" 토큰 형식이 없음" + +#: commands/tsearchcmds.c:1500 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "\"%s\" 토큰 형식에 대한 매핑이 없음" + +#: commands/tsearchcmds.c:1506 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "\"%s\" 토큰 형식에 대한 매핑이 없음, 건너뜀" + +#: commands/tsearchcmds.c:1669 commands/tsearchcmds.c:1784 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "잘못된 매개 변수 목록 형식: \"%s\"" + +#: commands/typecmds.c:206 +#, c-format +msgid "must be superuser to create a base type" +msgstr "슈퍼유저만 기본 형식을 만들 수 있음" + +#: commands/typecmds.c:264 +#, c-format +msgid "" +"Create the type as a shell type, then create its I/O functions, then do a " +"full CREATE TYPE." +msgstr "" + +#: commands/typecmds.c:314 commands/typecmds.c:1394 commands/typecmds.c:3832 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "잘못된 \"%s\" 속성의 자료형" + +#: commands/typecmds.c:370 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "\"%s\" 형식 범주가 잘못됨: 단순 ASCII여야 함" + +#: commands/typecmds.c:389 +#, c-format +msgid "array element type cannot be %s" +msgstr "배열 요소의 자료형으로 %s 자료형을 사용할 수 없습니다" + +#: commands/typecmds.c:421 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "잘못된 ALIGNMENT 값: \"%s\"" + +#: commands/typecmds.c:438 commands/typecmds.c:3718 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "잘못된 STORAGE 값: \"%s\"" + +#: commands/typecmds.c:449 +#, c-format +msgid "type input function must be specified" +msgstr "자료형 입력 함수를 지정하십시오" + +#: commands/typecmds.c:453 +#, c-format +msgid "type output function must be specified" +msgstr "자료형 출력 함수를 지정하십시오" + +#: commands/typecmds.c:458 +#, c-format +msgid "" +"type modifier output function is useless without a type modifier input " +"function" +msgstr "형식 한정자 입력 함수가 없으면 형식 한정자 출력 함수는 의미가 없음" + +#: commands/typecmds.c:745 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "\"%s\" 자료형은 도메인의 기반 자료형이 아닙니다" + +#: commands/typecmds.c:837 +#, c-format +msgid "multiple default expressions" +msgstr "default 표현식 여러개 있음" + +#: commands/typecmds.c:900 commands/typecmds.c:909 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "NULL/NOT NULL 조건이 함께 있음" + +#: commands/typecmds.c:925 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "도메인용 체크 제약 조건에는 NO INHERIT 옵션을 사용할 수 없음" + +#: commands/typecmds.c:934 commands/typecmds.c:2536 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "고유 제약 조건은 도메인 정의에 사용할 수 없음" + +#: commands/typecmds.c:940 commands/typecmds.c:2542 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "기본키 제약 조건을 도메인 정의에 사용할 수 없음" + +#: commands/typecmds.c:946 commands/typecmds.c:2548 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "exclusion 제약 조건은 도메인에는 사용할 수 없음" + +#: commands/typecmds.c:952 commands/typecmds.c:2554 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "참조키(foreign key) 제약 조건은 도메인(domain) 정의에 사용할 수 없음" + +#: commands/typecmds.c:961 commands/typecmds.c:2563 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "도메인에 대해 제약 조건 지연을 지정할 수 없음" + +#: commands/typecmds.c:1271 utils/cache/typcache.c:2430 +#, c-format +msgid "%s is not an enum" +msgstr "%s 개체는 나열형이 아님" + +#: commands/typecmds.c:1402 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "\"subtype\" 속성이 필요함" + +#: commands/typecmds.c:1407 +#, c-format +msgid "range subtype cannot be %s" +msgstr "range subtype은 %s 아니여야 함" + +#: commands/typecmds.c:1426 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "" +"range 형에 정렬 규칙을 지정했지만, 소속 자료형이 그 정렬 규칙을 지원하지 않습" +"니다" + +#: commands/typecmds.c:1436 +#, c-format +msgid "cannot specify a canonical function without a pre-created shell type" +msgstr "미리 만들어진 쉘 타입 없는 canonical 함수를 지정할 수 없음" + +#: commands/typecmds.c:1437 +#, c-format +msgid "" +"Create the type as a shell type, then create its canonicalization function, " +"then do a full CREATE TYPE." +msgstr "" + +#: commands/typecmds.c:1648 +#, c-format +msgid "type input function %s has multiple matches" +msgstr "자료형 %s 입력 함수가 여러 개 있습니다" + +#: commands/typecmds.c:1666 +#, c-format +msgid "type input function %s must return type %s" +msgstr "자료형 %s 입력 함수의 %s 자료형을 반환해야합니다" + +#: commands/typecmds.c:1682 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "%s 자료형 입력 함수는 volatile 특성이 없어야합니다" + +#: commands/typecmds.c:1710 +#, c-format +msgid "type output function %s must return type %s" +msgstr "%s 자료형 출력 함수는 %s 자료형을 반환해야합니다" + +#: commands/typecmds.c:1717 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "%s 자료형 출력 함수는 volatile 특성이 없어야합니다" + +#: commands/typecmds.c:1746 +#, c-format +msgid "type receive function %s has multiple matches" +msgstr "%s 자료형 receive 함수가 여러 개 있습니다" + +#: commands/typecmds.c:1764 +#, c-format +msgid "type receive function %s must return type %s" +msgstr "%s 자료형 receive 함수는 %s 자료형을 반환해야합니다" + +#: commands/typecmds.c:1771 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "%s 자료형 수신 함수는 volatile 특성이 없어야합니다" + +#: commands/typecmds.c:1799 +#, c-format +msgid "type send function %s must return type %s" +msgstr "%s 자료형 전송 함수는 %s 자료형을 반환해야합니다" + +#: commands/typecmds.c:1806 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "%s 자료형 송신 함수는 volatile 특성이 없어야합니다" + +#: commands/typecmds.c:1833 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr "%s typmod_in 함수는 %s 자료형을 반환해야 함" + +#: commands/typecmds.c:1840 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "%s 자료형 형변환 입력 함수는 volatile 특성이 없어야합니다" + +#: commands/typecmds.c:1867 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "%s typmod_out 함수는 %s 자료형을 반환해야 함" + +#: commands/typecmds.c:1874 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "%s 자료형 형변환 출력 함수는 volatile 특성이 없어야합니다" + +#: commands/typecmds.c:1901 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "%s 자료형 분석 함수는 %s 자료형을 반환해야 함" + +#: commands/typecmds.c:1947 +#, c-format +msgid "" +"You must specify an operator class for the range type or define a default " +"operator class for the subtype." +msgstr "" +"subtype을 위한 기본 연산자 클래스나 range 자료형을 위한 하나의 연산자 클래스" +"를 지정해야 합니다" + +#: commands/typecmds.c:1978 +#, c-format +msgid "range canonical function %s must return range type" +msgstr "%s 범위 기준 함수는 range 자료형을 반환해야합니다" + +#: commands/typecmds.c:1984 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "%s 범위 기준 함수는 immutable 속성이어야 합니다" + +#: commands/typecmds.c:2020 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "%s 범위 하위 자료 비교 함수는 %s 자료형을 반환해야합니다" + +#: commands/typecmds.c:2027 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "%s 범위 하위 자료 비교 함수는 immutable 속성이어야 합니다" + +#: commands/typecmds.c:2054 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "이진 업그레이드 작업 때 pg_type 배열 OID 값이 지정되지 않았습니다" + +#: commands/typecmds.c:2352 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "\"%s\" 열(해당 테이블 \"%s\")의 자료 가운데 null 값이 있습니다" + +#: commands/typecmds.c:2465 commands/typecmds.c:2667 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "\"%s\" 제약 조건 \"%s\" 도메인에 포함되어 있지 않습니다." + +#: commands/typecmds.c:2469 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "\"%s\" 제약 조건 \"%s\" 도메인에 포함되어 있지 않음, 건너뜀" + +#: commands/typecmds.c:2674 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "\"%s\" 제약 조건(해당 도메인: \"%s\")은 check 제약조건이 아님" + +#: commands/typecmds.c:2780 +#, c-format +msgid "" +"column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "" +"\"%s\" 열(해당 테이블 \"%s\")의 자료 중에, 새 제약 조건을 위반하는 자료가 있" +"습니다" + +#: commands/typecmds.c:3009 commands/typecmds.c:3207 commands/typecmds.c:3289 +#: commands/typecmds.c:3476 +#, c-format +msgid "%s is not a domain" +msgstr "\"%s\" 이름의 개체는 도메인이 아닙니다" + +#: commands/typecmds.c:3041 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "\"%s\" 제약 조건이 \"%s\" 도메인에 이미 지정되어 있습니다" + +#: commands/typecmds.c:3092 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "도메인 용 체크 제약 조건에서는 테이블 참조를 사용할 수 없습니다" + +#: commands/typecmds.c:3219 commands/typecmds.c:3301 commands/typecmds.c:3593 +#, c-format +msgid "%s is a table's row type" +msgstr "%s 자료형은 테이블의 행 자료형(row type)입니다" + +#: commands/typecmds.c:3221 commands/typecmds.c:3303 commands/typecmds.c:3595 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "대신 ALTER TABLE을 사용하십시오." + +#: commands/typecmds.c:3228 commands/typecmds.c:3310 commands/typecmds.c:3508 +#, c-format +msgid "cannot alter array type %s" +msgstr "%s 배열 형식을 변경할 수 없음" + +#: commands/typecmds.c:3230 commands/typecmds.c:3312 commands/typecmds.c:3510 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "%s 형식을 변경할 수 있으며, 이렇게 하면 배열 형식도 변경됩니다." + +#: commands/typecmds.c:3578 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "%s 자료형이 이미 \"%s\" 스키마 안에 있습니다" + +#: commands/typecmds.c:3746 +#, c-format +msgid "cannot change type's storage to PLAIN" +msgstr "저장 옵션을 PLAIN으로 바꿀 수 없음" + +#: commands/typecmds.c:3827 +#, c-format +msgid "type attribute \"%s\" cannot be changed" +msgstr "\"%s\" 자료형 속성 바꿀 수 없음" + +#: commands/typecmds.c:3845 +#, c-format +msgid "must be superuser to alter a type" +msgstr "슈퍼유저만 자료형 속성을 바꿀 수 있음" + +#: commands/typecmds.c:3866 commands/typecmds.c:3876 +#, c-format +msgid "%s is not a base type" +msgstr "\"%s\" 개체는 기본 자료형이 아님" + +#: commands/user.c:140 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSID는 더 이상 지정할 수 없음" + +#: commands/user.c:294 +#, c-format +msgid "must be superuser to create superusers" +msgstr "새 슈퍼유저를 만드려면 슈퍼유져여야만 합니다" + +#: commands/user.c:301 +#, c-format +msgid "must be superuser to create replication users" +msgstr "새 복제작업용 사용자를 만드려면 슈퍼유저여야만 합니다" + +#: commands/user.c:308 commands/user.c:734 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "슈퍼유저만 bypassrls 속성을 바꿀 수 있음" + +#: commands/user.c:315 +#, c-format +msgid "permission denied to create role" +msgstr "롤 만들 권한 없음" + +#: commands/user.c:325 commands/user.c:1224 commands/user.c:1231 +#: utils/adt/acl.c:5327 utils/adt/acl.c:5333 gram.y:15146 gram.y:15184 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "\"%s\" 롤 이름은 내부적으로 사용되고 있습니다" + +#: commands/user.c:327 commands/user.c:1226 commands/user.c:1233 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "\"pg_\"로 시작하는 롤 이름은 사용할 수 없습니다." + +#: commands/user.c:348 commands/user.c:1248 +#, c-format +msgid "role \"%s\" already exists" +msgstr "\"%s\" 롤 이름이 이미 있습니다" + +#: commands/user.c:414 commands/user.c:843 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "비밀번호로 빈 문자열을 사용할 수 없습니다. 비밀번호를 없앱니다" + +#: commands/user.c:443 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "이진 업그레이드 작업 때 pg_authid OID 값이 지정되지 않았습니다" + +#: commands/user.c:720 commands/user.c:944 commands/user.c:1485 +#: commands/user.c:1627 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "슈퍼유저의 속성을 변경하련 슈퍼유져여야만 합니다" + +#: commands/user.c:727 +#, c-format +msgid "must be superuser to alter replication users" +msgstr "복제작업용 사용자의 속성을 변경하련 슈퍼유져여야만 합니다" + +#: commands/user.c:750 commands/user.c:951 +#, c-format +msgid "permission denied" +msgstr "권한 없음" + +#: commands/user.c:981 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "슈퍼유저만 전역 환경 설정을 바꿀 수 있습니다." + +#: commands/user.c:1003 +#, c-format +msgid "permission denied to drop role" +msgstr "롤을 삭제할 권한이 없습니다" + +#: commands/user.c:1028 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "DROP ROLE 명령으로 삭제할 수 없는 특별한 롤입니다" + +#: commands/user.c:1038 commands/user.c:1195 commands/variable.c:770 +#: commands/variable.c:844 utils/adt/acl.c:5184 utils/adt/acl.c:5231 +#: utils/adt/acl.c:5259 utils/adt/acl.c:5277 utils/init/miscinit.c:675 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "\"%s\" 롤(role) 없음" + +#: commands/user.c:1043 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "\"%s\" 룰(rule) 없음, 건너 뜀" + +#: commands/user.c:1056 commands/user.c:1060 +#, c-format +msgid "current user cannot be dropped" +msgstr "현재 사용자는 삭제 될 수 없습니다" + +#: commands/user.c:1064 +#, c-format +msgid "session user cannot be dropped" +msgstr "세션 사용자는 삭제 될 수 없습니다" + +#: commands/user.c:1074 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "superuser를 사용자를 삭제하려면 superuser여야만 합니다" + +#: commands/user.c:1090 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "기타 다른 개체들이 이 롤에 의존하고 있어, \"%s\" 롤을 삭제할 수 없음" + +#: commands/user.c:1211 +#, c-format +msgid "session user cannot be renamed" +msgstr "세션 사용자의 이름은 바꿀 수 없습니다" + +#: commands/user.c:1215 +#, c-format +msgid "current user cannot be renamed" +msgstr "현재 사용자의 이름은 바꿀 수 없습니다" + +#: commands/user.c:1258 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "superuser의 이름을 바꾸려면 superuser여야 합니다" + +#: commands/user.c:1265 +#, c-format +msgid "permission denied to rename role" +msgstr "롤 이름 바꾸기 권한 없음" + +#: commands/user.c:1286 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "롤 이름이 변경 되어 MD5 암호를 지웠습니다" + +#: commands/user.c:1346 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "GRANT/REVOKE ROLE에 열 이름을 포함할 수 없음" + +#: commands/user.c:1384 +#, c-format +msgid "permission denied to drop objects" +msgstr "개체를 삭제할 권한이 없음" + +#: commands/user.c:1411 commands/user.c:1420 +#, c-format +msgid "permission denied to reassign objects" +msgstr "개체 권한을 재 지정할 권한이 없음" + +#: commands/user.c:1493 commands/user.c:1635 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "\"%s\" 역할에 admin 옵션이 있어야 함" + +#: commands/user.c:1510 +#, c-format +msgid "must be superuser to set grantor" +msgstr "grantor(?)를 지정하려면 슈퍼유져여야합니다" + +#: commands/user.c:1535 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "\"%s\" 롤은 \"%s\" 롤의 구성원입니다" + +#: commands/user.c:1550 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "role \"%s\" is already a member of role \"%s\"" + +#: commands/user.c:1657 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "\"%s\" 롤은 \"%s\"롤의 구성원이 아닙니다" + +#: commands/vacuum.c:129 +#, c-format +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "알 수 없는 ANALYZE 옵션: \"%s\"" + +#: commands/vacuum.c:151 +#, c-format +msgid "parallel option requires a value between 0 and %d" +msgstr "병렬 옵션은 0부터 %d까지 값만 사용할 수 있음" + +#: commands/vacuum.c:163 +#, c-format +msgid "parallel vacuum degree must be between 0 and %d" +msgstr "병렬 청소 작업수는 0부터 %d까지 값만 사용할 수 있음" + +#: commands/vacuum.c:180 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "알 수 없는 VACUUM 옵션 \"%s\"" + +#: commands/vacuum.c:203 +#, c-format +msgid "VACUUM FULL cannot be performed in parallel" +msgstr "" + +#: commands/vacuum.c:219 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "ANALYZE 옵션은 칼럼 목록이 제공될 때 사용할 수 있습니다" + +#: commands/vacuum.c:309 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s 명령은 VACUUM, ANALYZE 명령에서 실행 될 수 없음" + +#: commands/vacuum.c:319 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "" +"VACUUM 명령에서 DISABLE_PAGE_SKIPPING 옵션과 FULL 옵션을 함께 사용할 수 없습" +"니다." + +#: commands/vacuum.c:560 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "\"%s\" 건너뜀 --- 슈퍼유저만 청소할 수 있음" + +#: commands/vacuum.c:564 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "\"%s\" 건너뜀 --- 슈퍼유저 또는 데이터베이스 소유주만 청소할 수 있음" + +#: commands/vacuum.c:568 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "\"%s\" 건너뜀 --- 이 테이블이나 데이터베이스의 소유주만 청소할 수 있음" + +#: commands/vacuum.c:583 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "\"%s\" 분석 건너뜀 --- 슈퍼유저만 분석할 수 있음" + +#: commands/vacuum.c:587 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "" +"\"%s\" 분석 건너뜀 --- 슈퍼유저 또는 데이터베이스 소유주만 분석할 수 있음" + +#: commands/vacuum.c:591 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "\"%s\" 건너뜀 --- 테이블이나 데이터베이스 소유주만이 분석할 수 있음" + +#: commands/vacuum.c:670 commands/vacuum.c:766 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "\"%s\" 개체 vacuum 건너뜀 --- 사용 가능한 잠금이 없음" + +#: commands/vacuum.c:675 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "\"%s\" 개체 vacuum 건너뜀 --- 해당 릴레이션 없음" + +#: commands/vacuum.c:691 commands/vacuum.c:771 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "\"%s\" 분석 건너뜀 --- 잠글 수 없음" + +#: commands/vacuum.c:696 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "\"%s\" 분석 건너뜀 --- 릴레이션어 없음" + +# # search5 부분 +#: commands/vacuum.c:994 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "가장 오래된 xmin이 너무 옛날 것입니다." + +#: commands/vacuum.c:995 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"트랜잭션 겹침 문제를 피하기 위해서는 최대한 빨리 열려 있는 트랜잭션을 닫으십" +"시오.\n" +"또한 미리 준비된 트랜잭션들도 커밋 또는 롤백해야하며, 잠긴 복제 슬롯도 지워야" +"합니다." + +# # search5 부분 +#: commands/vacuum.c:1036 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "가장 오래된 multixact 값이 너무 옛날 것입니다." + +#: commands/vacuum.c:1037 +#, c-format +msgid "" +"Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "" +"멀티 트랜잭션 ID 겹침 사고를 막기 위해 빨리 열린 멀티 트랜잭션들을 닫으십시" +"오." + +#: commands/vacuum.c:1623 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "" +"몇몇 데이터베이스가 20억 이상의 트랜잭션을 처리했음에도 불구하고 청소가되지 " +"않았습니다" + +#: commands/vacuum.c:1624 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "이미 트래잭션 ID 겹침 현상으로 자료 손실이 발생했을 수도 있습니다." + +#: commands/vacuum.c:1784 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "" +"\"%s\" 건너뜀 --- 테이블이 아닌 것 또는 특별 시스템 테이블 등은 청소할 수 없" +"음" + +#: commands/variable.c:165 utils/misc/guc.c:11156 utils/misc/guc.c:11218 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "알 수 없는 키워드: \"%s\"" + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "\"datestyle\" 지정이 충돌함" + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "타임 존 간격에 달을 지정할 수 없음" + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "타임 존 간격에 일을 지정할 수 없음" + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "\"%s\" time zone 에서 leap second를 사용합니다" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQL에서는 leap second를 지원하지 않습니다" + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "UTC 타입존 오프세트 범위가 벗어남." + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "읽기 전용 트랜잭션 내에서 트랜잭션을 읽기/쓰기 모드로 설정할 수 없음" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "읽기/쓰기 모드 트랜잭션은 모든 쿼리 앞에 지정해야 합니다." + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "복구 작업 중에는 트랜잭션을 읽기/쓰기 모드로 설정할 수 없음" + +#: commands/variable.c:534 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "쿼리보다 먼저 SET TRANSACTION ISOLATION LEVEL을 호출해야 함" + +#: commands/variable.c:541 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "하위 트랜잭션에서 SET TRANSACTION ISOLATION LEVEL을 호출하지 않아야 함" + +#: commands/variable.c:548 storage/lmgr/predicate.c:1623 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "읽기 전용 보조 서버 상태에서는 serializable 모드를 사용할 수 없음" + +#: commands/variable.c:549 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "대신에, REPEATABLE READ 명령을 사용할 수 있음." + +#: commands/variable.c:567 +#, c-format +msgid "" +"SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "" +"하위 트랜잭션에서 SET TRANSACTION [NOT] DEFERRABLE 구문은 사용할 수 없음" + +#: commands/variable.c:573 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "모든 쿼리보다 먼저 SET TRANSACTION [NOT] DEFERRABLE 구문을 사용해야 함" + +#: commands/variable.c:655 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "%s 인코딩과 %s 인코딩 사이의 변환은 지원하지 않습니다" + +#: commands/variable.c:662 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "\"client_encoding\" 값을 지금은 바꿀 수 없음" + +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "병렬 작업 중에는 client_encoding 설정을 할 수 없음" + +#: commands/variable.c:863 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "\"%s\" 롤 권한을 지정할 수 없음" + +#: commands/view.c:84 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "\"%s\" 칼럼 자료 처리를 위한 정렬 규칙을 결정할 수 없음" + +#: commands/view.c:265 commands/view.c:276 +#, c-format +msgid "cannot drop columns from view" +msgstr "뷰에서 칼럼을 삭제할 수 없음" + +#: commands/view.c:281 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "뷰에서 \"%s\" 칼럼 이름을 \"%s\"(으)로 바꿀 수 없음" + +#: commands/view.c:284 +#, c-format +msgid "" +"Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead." +msgstr "" + +#: commands/view.c:290 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "뷰에서 \"%s\" 칼럼 자료형을을 %s에서 %s(으)로 바꿀 수 없음" + +#: commands/view.c:441 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "뷰에는 SELECT INTO 구문을 포함할 수 없음" + +#: commands/view.c:453 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "뷰로 사용될 쿼리의 WITH 절에는 자료 변경 구문이 있으면 안됩니다." + +#: commands/view.c:523 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "CREATE VIEW 는 columns 보다는 좀더 많은 열 이름을 명시해야 한다" + +#: commands/view.c:531 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "" +"뷰는 저장 공간을 사용하지 않기 때문에 unlogged 속성을 지정할 수 없습니다." + +#: commands/view.c:545 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "\"%s\" 뷰는 임시적인 뷰로 만들어집니다" + +#: executor/execCurrent.c:79 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "\"%s\" 커서는 SELECT 쿼리가 아님" + +#: executor/execCurrent.c:85 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "\"%s\" 커서는 이전 트랜잭션에서 보류됨" + +#: executor/execCurrent.c:118 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "" +"\"%s\" 커서에는 \"%s\" 테이블에 대한 FOR UPDATE/SHARE 참조가 여러 개 있음" + +#: executor/execCurrent.c:127 +#, c-format +msgid "" +"cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "\"%s\" 커서에 \"%s\" 테이블에 대한 FOR UPDATE/SHARE 참조가 없음" + +#: executor/execCurrent.c:137 executor/execCurrent.c:182 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr "\"%s\" 커서가 로우에 놓여 있지 않음" + +#: executor/execCurrent.c:169 executor/execCurrent.c:228 +#: executor/execCurrent.c:239 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "\"%s\" 커서는 \"%s\" 테이블의 단순 업데이트 가능한 스캔이 아님" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2404 +#, c-format +msgid "" +"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "" +"%d번째 매개 변수의 자료형(%s)이 미리 준비된 실행계획의 자료형(%s)과 다릅니다" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2416 +#, c-format +msgid "no value found for parameter %d" +msgstr "%d번째 매개 변수 값이 없습니다" + +#: executor/execExpr.c:859 parser/parse_agg.c:816 +#, c-format +msgid "window function calls cannot be nested" +msgstr "윈도우 함수 호출을 중첩할 수 없음" + +#: executor/execExpr.c:1318 +#, c-format +msgid "target type is not an array" +msgstr "대상 자료형이 배열이 아닙니다." + +#: executor/execExpr.c:1651 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW() 칼럼은 %s 자료형을 가집니다. %s 자료형 대신에" + +#: executor/execExpr.c:2176 executor/execSRF.c:708 parser/parse_func.c:135 +#: parser/parse_func.c:646 parser/parse_func.c:1020 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "함수에 최대 %d개의 인자를 전달할 수 있음" + +#: executor/execExpr.c:2587 executor/execExpr.c:2593 +#: executor/execExprInterp.c:2730 utils/adt/arrayfuncs.c:262 +#: utils/adt/arrayfuncs.c:560 utils/adt/arrayfuncs.c:1302 +#: utils/adt/arrayfuncs.c:3348 utils/adt/arrayfuncs.c:5308 +#: utils/adt/arrayfuncs.c:5821 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "지정한 배열 크기(%d)가 최대치(%d)를 초과했습니다" + +#: executor/execExprInterp.c:1894 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "%d 번째 속성(대상 자료형 %s)이 삭제되었음" + +#: executor/execExprInterp.c:1900 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "%d 번째 속성(대상 자료형 %s)의 자료형이 잘못되었음" + +#: executor/execExprInterp.c:1902 executor/execExprInterp.c:3002 +#: executor/execExprInterp.c:3049 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "테이블에는 %s 자료형이지만, 쿼리에서는 %s 자료형입니다." + +#: executor/execExprInterp.c:2494 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF 구문은 이 테이블 형 대상으로 지원하지 않습니다." + +#: executor/execExprInterp.c:2708 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "배열 형태가 서로 틀려 병합할 수 없습니다" + +#: executor/execExprInterp.c:2709 +#, c-format +msgid "" +"Array with element type %s cannot be included in ARRAY construct with " +"element type %s." +msgstr "" +"%s 자료형의 요소로 구성된 배열은 %s 자료형의 요소로 구성된 ARRAY 구문에 포함" +"될 수 없습니다." + +#: executor/execExprInterp.c:2750 executor/execExprInterp.c:2780 +#, c-format +msgid "" +"multidimensional arrays must have array expressions with matching dimensions" +msgstr "다차원 배열에는 일치하는 차원이 포함된 배열 식이 있어야 함" + +#: executor/execExprInterp.c:3001 executor/execExprInterp.c:3048 +#, c-format +msgid "attribute %d has wrong type" +msgstr "%d 속성의 형식이 잘못됨" + +#: executor/execExprInterp.c:3158 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "배열 하위 스크립트로 지정하는 값으로 null 값을 사용할 수 없습니다" + +#: executor/execExprInterp.c:3588 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "%s 도메인에서는 null 값을 허용하지 않습니다" + +#: executor/execExprInterp.c:3603 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "%s 도메인용 값이 \"%s\" 체크 제약 조건을 위반했습니다" + +#: executor/execExprInterp.c:3973 executor/execExprInterp.c:3990 +#: executor/execExprInterp.c:4091 executor/nodeModifyTable.c:109 +#: executor/nodeModifyTable.c:120 executor/nodeModifyTable.c:137 +#: executor/nodeModifyTable.c:145 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "테이블 행 형식과 쿼리 지정 행 형식이 일치하지 않음" + +#: executor/execExprInterp.c:3974 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "" +"테이블 행에는 %d개 속성이 포함되어 있는데 쿼리에는 %d개가 필요합니다." + +#: executor/execExprInterp.c:3991 executor/nodeModifyTable.c:121 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "" +"테이블에는 %s 형식이 있는데(서수 위치 %d) 쿼리에는 %s이(가) 필요합니다." + +#: executor/execExprInterp.c:4092 executor/execSRF.c:967 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "서수 위치 %d의 삭제된 속성에서 실제 스토리지 불일치가 발생합니다." + +#: executor/execIndexing.c:550 +#, c-format +msgid "" +"ON CONFLICT does not support deferrable unique constraints/exclusion " +"constraints as arbiters" +msgstr "" +"지연 가능한 고유 제약조건이나 제외 제약 조건은 ON CONFLICT 판별자로 사용할 " +"수 없습니다." + +#: executor/execIndexing.c:821 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "\"%s\" exclusion 제약 조건을 만들 수 없음" + +#: executor/execIndexing.c:824 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "%s 키와 %s 가 충돌함" + +#: executor/execIndexing.c:826 +#, c-format +msgid "Key conflicts exist." +msgstr "키 충돌 발생" + +#: executor/execIndexing.c:832 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "\"%s\" exclusion 제약 조건에 따라 키 값 충돌이 발생했습니다." + +#: executor/execIndexing.c:835 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "%s 키가 이미 있는 %s 키와 충돌합니다." + +#: executor/execIndexing.c:837 +#, c-format +msgid "Key conflicts with existing key." +msgstr "키가 기존 키와 충돌함" + +#: executor/execMain.c:1091 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "\"%s\" 시퀀스를 바꿀 수 없음" + +#: executor/execMain.c:1097 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "\"%s\" TOAST 릴레이션을 바꿀 수 없음" + +#: executor/execMain.c:1115 rewrite/rewriteHandler.c:2934 +#: rewrite/rewriteHandler.c:3708 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "\"%s\" 뷰에 자료를 입력할 수 없습니다" + +#: executor/execMain.c:1117 rewrite/rewriteHandler.c:2937 +#: rewrite/rewriteHandler.c:3711 +#, c-format +msgid "" +"To enable inserting into the view, provide an INSTEAD OF INSERT trigger or " +"an unconditional ON INSERT DO INSTEAD rule." +msgstr "" +"뷰를 통해 자료를 입력하려면, INSTEAD OF INSERT 트리거나 ON INSERT DO INSTEAD " +"룰을 사용하세요" + +#: executor/execMain.c:1123 rewrite/rewriteHandler.c:2942 +#: rewrite/rewriteHandler.c:3716 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "\"%s\" 뷰로는 자료를 갱신할 수 없습니다" + +#: executor/execMain.c:1125 rewrite/rewriteHandler.c:2945 +#: rewrite/rewriteHandler.c:3719 +#, c-format +msgid "" +"To enable updating the view, provide an INSTEAD OF UPDATE trigger or an " +"unconditional ON UPDATE DO INSTEAD rule." +msgstr "" +"뷰 자료 갱신 기능은 INSTEAD OF UPDATE 트리거를 사용하거나, ON UPDATE DO " +"INSTEAD 속성으로 룰을 만들어서 사용해 보세요." + +#: executor/execMain.c:1131 rewrite/rewriteHandler.c:2950 +#: rewrite/rewriteHandler.c:3724 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "\"%s\" 뷰로는 자료를 삭제할 수 없습니다" + +#: executor/execMain.c:1133 rewrite/rewriteHandler.c:2953 +#: rewrite/rewriteHandler.c:3727 +#, c-format +msgid "" +"To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an " +"unconditional ON DELETE DO INSTEAD rule." +msgstr "" +"뷰 자료 삭제 기능은 INSTEAD OF DELETE 트리거를 사용하거나, ON DELETE DO " +"INSTEAD 속성으로 룰을 만들어서 사용해 보세요." + +#: executor/execMain.c:1144 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "\"%s\" 구체화된 뷰를 바꿀 수 없음" + +#: executor/execMain.c:1156 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "\"%s\" 외부 테이블에 자료를 입력할 수 없음" + +#: executor/execMain.c:1162 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "\"%s\" 외부 테이블은 자료 입력을 허용하지 않음" + +#: executor/execMain.c:1169 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "\"%s\" 외부 테이블에 자료를 변경 할 수 없음" + +#: executor/execMain.c:1175 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "\"%s\" 외부 테이블은 자료 변경을 허용하지 않음" + +#: executor/execMain.c:1182 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "\"%s\" 외부 테이블에 자료를 삭제 할 수 없음" + +#: executor/execMain.c:1188 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "\"%s\" 외부 테이블은 자료 삭제를 허용하지 않음" + +#: executor/execMain.c:1199 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "\"%s\" 릴레이션을 바꿀 수 없음" + +#: executor/execMain.c:1226 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "\"%s\" 시퀀스에서 로우를 잠글 수 없음" + +#: executor/execMain.c:1233 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "\"%s\" TOAST 릴레이션에서 로우를 잠글 수 없음" + +#: executor/execMain.c:1240 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "\"%s\" 뷰에서 로우를 잠글 수 없음" + +#: executor/execMain.c:1248 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "\"%s\" 구체화된 뷰에서 로우를 잠글 수 없음" + +#: executor/execMain.c:1257 executor/execMain.c:2627 +#: executor/nodeLockRows.c:132 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "\"%s\" 외부 테이블에서 로우를 잠글 수 없음" + +#: executor/execMain.c:1263 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "\"%s\" 릴레이션에서 로우를 잠글 수 없음" + +#: executor/execMain.c:1879 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "새 자료가 \"%s\" 릴레이션의 파티션 제약 조건을 위반했습니다" + +#: executor/execMain.c:1881 executor/execMain.c:1964 executor/execMain.c:2012 +#: executor/execMain.c:2120 +#, c-format +msgid "Failing row contains %s." +msgstr "실패한 자료: %s" + +#: executor/execMain.c:1961 +#, c-format +msgid "" +"null value in column \"%s\" of relation \"%s\" violates not-null constraint" +msgstr "\"%s\" 칼럼(해당 릴레이션 \"%s\")의 null 값이 not null 제약조건을 위반했습니다." + +#: executor/execMain.c:2010 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "새 자료가 \"%s\" 릴레이션의 \"%s\" 체크 제약 조건을 위반했습니다" + +#: executor/execMain.c:2118 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "새 자료가 \"%s\" 뷰의 체크 제약 조건을 위반했습니다" + +#: executor/execMain.c:2128 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "" +"새 자료가 \"%s\" 로우 단위 보안 정책을 위반했습니다, 해당 테이블: \"%s\"" + +#: executor/execMain.c:2133 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "새 자료가 \"%s\" 테이블의 로우 단위 보안 정책을 위반했습니다." + +#: executor/execMain.c:2140 +#, c-format +msgid "" +"new row violates row-level security policy \"%s\" (USING expression) for " +"table \"%s\"" +msgstr "" +"새 자료가 \"%s\" 로우 단위 보안 정책(USING 절 사용)을 위반했습니다, 해당 테이" +"블: \"%s\"" + +#: executor/execMain.c:2145 +#, c-format +msgid "" +"new row violates row-level security policy (USING expression) for table \"%s" +"\"" +msgstr "" +"새 자료가 \"%s\" 테이블의 로우 단위 보안 정책(USING 절 사용)을 위반했습니다." + +#: executor/execPartition.c:341 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "해당 로우를 위한 \"%s\" 릴레이션용 파티션이 없음" + +#: executor/execPartition.c:344 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "실패한 로우의 파티션 키 값: %s" + +#: executor/execReplication.c:196 executor/execReplication.c:373 +#, c-format +msgid "" +"tuple to be locked was already moved to another partition due to concurrent " +"update, retrying" +msgstr "" +"다른 업데이트 작업으로 잠굴 튜플이 이미 다른 파티션으로 이동되었음, 재시도함" + +#: executor/execReplication.c:200 executor/execReplication.c:377 +#, c-format +msgid "concurrent update, retrying" +msgstr "동시 업데이트, 다시 시도 중" + +#: executor/execReplication.c:206 executor/execReplication.c:383 +#, c-format +msgid "concurrent delete, retrying" +msgstr "동시 삭제, 다시 시도 중" + +#: executor/execReplication.c:269 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3626 utils/adt/arrayfuncs.c:4146 +#: utils/adt/arrayfuncs.c:6132 utils/adt/rowtypes.c:1182 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "" +"%s 자료형에서 사용할 동등 연산자(equality operator)를 찾을 수 없습니다." + +#: executor/execReplication.c:586 +#, c-format +msgid "" +"cannot update table \"%s\" because it does not have a replica identity and " +"publishes updates" +msgstr "" +"\"%s\" 테이블 업데이트 실패, 이 테이블에는 복제용 식별자를 지정하지 않았거" +"나, updates 옵션 없이 발행했습니다" + +#: executor/execReplication.c:588 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "" +"업데이트를 하려면, ALTER TABLE 명령어에서 REPLICA IDENTITY 옵션을 사용하세요" + +#: executor/execReplication.c:592 +#, c-format +msgid "" +"cannot delete from table \"%s\" because it does not have a replica identity " +"and publishes deletes" +msgstr "\"%s\" 테이블 자료 삭제 실패, 복제 식별자와 deletes 발행을 안함" + +#: executor/execReplication.c:594 +#, c-format +msgid "" +"To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "삭제 하려면, ALTER TABLE 명령어에서 REPLICA IDENTITY 옵션을 사용하세요" + +#: executor/execReplication.c:613 executor/execReplication.c:621 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "\"%s.%s\" 릴레이션은 논리 복제 대상이 될 수 없음" + +#: executor/execReplication.c:615 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "\"%s.%s\" 개체는 외부 테이블입니다." + +#: executor/execReplication.c:623 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "\"%s.%s\" 개체는 테이블이 아닙니다." + +#: executor/execSRF.c:315 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "함수 호출로 반환되는 로우가 같은 로우형의 전부가 아닙니다" + +#: executor/execSRF.c:363 executor/execSRF.c:657 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "materialize 모드를 위한 테이블 함수 프로토콜이 뒤이어 오지 않았습니다" + +#: executor/execSRF.c:370 executor/execSRF.c:675 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "알 수 없는 테이블-함수 리턴모드: %d" + +#: executor/execSRF.c:884 +#, c-format +msgid "" +"function returning setof record called in context that cannot accept type " +"record" +msgstr "" +"setof 레코드 반환 함수가 type 레코드를 허용하지 않는 컨텍스트에서 호출됨" + +#: executor/execSRF.c:940 executor/execSRF.c:956 executor/execSRF.c:966 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "함수 반환 행과 쿼리 지정 반환 행이 일치하지 않음" + +#: executor/execSRF.c:941 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "" +"반환된 행에는 %d개 속성이 포함되어 있는데 쿼리에는 %d개가 필요합니다." + +#: executor/execSRF.c:957 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "반환된 형식은 %s인데(서수 위치 %d) 쿼리에는 %s이(가) 필요합니다." + +#: executor/execUtils.c:750 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "\"%s\" 구체화된 뷰가 아직 구체화되지 못했습니다." + +#: executor/execUtils.c:752 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "REFRESH MATERIALIZED VIEW 명령을 사용하세요." + +#: executor/functions.c:231 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "%s 인자의 자료형으로 지정한 자료형의 기본 자료형을 찾을 수 없습니다" + +#: executor/functions.c:528 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "SQL 함수에서 클라이언트 대상 COPY 작업을 할 수 없음" + +#. translator: %s is a SQL statement name +#: executor/functions.c:534 +#, c-format +msgid "%s is not allowed in a SQL function" +msgstr "SQL 함수에서 %s 지원되지 않음" + +#. translator: %s is a SQL statement name +#: executor/functions.c:542 executor/spi.c:1471 executor/spi.c:2257 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "%s 구문은 비휘발성 함수(non-volatile function)에서 허용하지 않습니다" + +#: executor/functions.c:1430 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "SQL 함수 \"%s\"의 문 %d" + +#: executor/functions.c:1456 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "시작 중 SQL 함수 \"%s\"" + +#: executor/functions.c:1549 +#, c-format +msgid "" +"calling procedures with output arguments is not supported in SQL functions" +msgstr "출력 인자를 포함한 프로시져 호출은 SQL 함수에서 지원하지 않습니다." + +#: executor/functions.c:1671 executor/functions.c:1708 +#: executor/functions.c:1722 executor/functions.c:1812 +#: executor/functions.c:1845 executor/functions.c:1859 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "리턴 자료형이 함수 정의에서 지정한 %s 리턴 자료형과 틀립니다" + +#: executor/functions.c:1673 +#, c-format +msgid "" +"Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "" +"함수 내용의 맨 마지막 구문은 SELECT 또는 INSERT/UPDATE/DELETE RETURNING이어" +"야 합니다." + +#: executor/functions.c:1710 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "맨 마지막 구문은 정확히 하나의 칼럼만 반환해야 합니다." + +#: executor/functions.c:1724 +#, c-format +msgid "Actual return type is %s." +msgstr "실재 반환 자료형은 %s" + +#: executor/functions.c:1814 +#, c-format +msgid "Final statement returns too many columns." +msgstr "맨 마지막 구문이 너무 많은 칼럼을 반환합니다." + +#: executor/functions.c:1847 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "" +"맨 마지막 구문이 %s(기대되는 자료형: %s) 자료형을 %d 번째 칼럼에서 반환합니" +"다." + +#: executor/functions.c:1861 +#, c-format +msgid "Final statement returns too few columns." +msgstr "맨 마지막 구문이 너무 적은 칼럼을 반환합니다." + +#: executor/functions.c:1889 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "반환 자료형인 %s 자료형은 SQL 함수에서 지원되지 않음" + +#: executor/nodeAgg.c:3075 executor/nodeAgg.c:3084 executor/nodeAgg.c:3096 +#, c-format +msgid "unexpected EOF for tape %d: requested %zu bytes, read %zu bytes" +msgstr "" + +#: executor/nodeAgg.c:4026 parser/parse_agg.c:655 parser/parse_agg.c:685 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "집계 함수는 중첩되어 호출 할 수 없음" + +#: executor/nodeAgg.c:4234 executor/nodeWindowAgg.c:2836 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "%u OID 집계함수에 호환 가능한 입력 형식과 변환 형식이 있어야 함" + +#: executor/nodeCustom.c:145 executor/nodeCustom.c:156 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "\"%s\" 이름의 칼럼 탐색은 MarkPos 기능을 지원하지 않음" + +#: executor/nodeHashjoin.c:1046 executor/nodeHashjoin.c:1076 +#, c-format +msgid "could not rewind hash-join temporary file" +msgstr "해시-조인 임시 파일을 되감을 수 없음" + +#: executor/nodeHashjoin.c:1272 executor/nodeHashjoin.c:1283 +#, c-format +msgid "" +"could not read from hash-join temporary file: read only %zu of %zu bytes" +msgstr "해시-조인 임시 파일을 읽을 수 없음: %zu / %zu 바이트만 읽음" + +#: executor/nodeIndexonlyscan.c:242 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "lossy distance 함수들은 인덱스 단독 탐색을 지원하지 않음" + +#: executor/nodeLimit.c:374 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET은 음수가 아니어야 함" + +#: executor/nodeLimit.c:400 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT는 음수가 아니어야 함" + +#: executor/nodeMergejoin.c:1570 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "RIGHT JOIN은 병합-조인 가능 조인 조건에서만 지원됨" + +#: executor/nodeMergejoin.c:1588 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "FULL JOIN은 병합-조인 가능 조인 조건에서만 지원됨" + +#: executor/nodeModifyTable.c:110 +#, c-format +msgid "Query has too many columns." +msgstr "쿼리에 칼럼이 너무 많습니다." + +#: executor/nodeModifyTable.c:138 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "쿼리에서 서수 위치 %d에 있는 삭제된 칼럼의 값을 제공합니다." + +#: executor/nodeModifyTable.c:146 +#, c-format +msgid "Query has too few columns." +msgstr "쿼리에 칼럼이 너무 적습니다." + +#: executor/nodeModifyTable.c:839 executor/nodeModifyTable.c:913 +#, c-format +msgid "" +"tuple to be deleted was already modified by an operation triggered by the " +"current command" +msgstr "현재 명령으로 실행된 트리거 작업으로 지울 자료가 이미 바뀌었습니다." + +#: executor/nodeModifyTable.c:1220 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "잘못된 ON UPDATE 옵션" + +#: executor/nodeModifyTable.c:1221 +#, c-format +msgid "" +"The result tuple would appear in a different partition than the original " +"tuple." +msgstr "" + +#: executor/nodeModifyTable.c:1592 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "" + +#: executor/nodeModifyTable.c:1593 +#, c-format +msgid "" +"Ensure that no rows proposed for insertion within the same command have " +"duplicate constrained values." +msgstr "" + +#: executor/nodeSamplescan.c:259 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "TABLESAMPLE 절에는 반드시 부가 옵션값들이 있어야 합니다" + +#: executor/nodeSamplescan.c:271 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "TABLESAMPLE REPEATABLE 절은 더 이상의 부가 옵션을 쓰면 안됩니다." + +#: executor/nodeSubplan.c:346 executor/nodeSubplan.c:385 +#: executor/nodeSubplan.c:1151 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "표현식에 사용된 서브쿼리 결과가 하나 이상의 행을 리턴했습니다" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "네임스페이스 URI 값은 null 일 수 없습니다." + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "로우 필터 표현식은 null값이 아니여야 함" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "칼럼 필터 표현식은 null값이 아니여야 함" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "\"%s\" 칼럼용 필터가 null입니다." + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "\"%s\" 칼럼은 null 값을 허용하지 않습니다" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "moving-aggregate transition 함수는 null 값을 반환하면 안됩니다." + +#: executor/nodeWindowAgg.c:2058 +#, c-format +msgid "frame starting offset must not be null" +msgstr "프래임 시작 위치값으로 null 값을 사용할 수 없습니다." + +#: executor/nodeWindowAgg.c:2071 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "프래임 시작 위치으로 음수 값을 사용할 수 없습니다." + +#: executor/nodeWindowAgg.c:2083 +#, c-format +msgid "frame ending offset must not be null" +msgstr "프래임 끝 위치값으로 null 값을 사용할 수 없습니다." + +#: executor/nodeWindowAgg.c:2096 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "프래임 끝 위치값으로 음수 값을 사용할 수 없습니다." + +#: executor/nodeWindowAgg.c:2752 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "%s 집계 함수는 윈도우 함수로 사용될 수 없습니다" + +#: executor/spi.c:228 executor/spi.c:297 +#, c-format +msgid "invalid transaction termination" +msgstr "잘못된 트랜잭션 마침" + +#: executor/spi.c:242 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "하위트랜잭션이 활성화 된 상태에서는 커밋 할 수 없음" + +#: executor/spi.c:303 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "하위트랜잭션이 활성화 된 상태에서는 롤백 할 수 없음" + +#: executor/spi.c:372 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "트랜잭션이 비어있지 않은 SPI 스택을 남겼습니다" + +#: executor/spi.c:373 executor/spi.c:435 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "\"SPI_finish\" 호출이 빠졌는지 확인하세요" + +#: executor/spi.c:434 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "하위 트랜잭션이 비어있지 않은 SPI 스택을 남겼습니다" + +#: executor/spi.c:1335 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "멀티 쿼리를 커서로 열 수는 없습니다" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1340 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "%s 쿼리로 커서를 열 수 없음." + +#: executor/spi.c:1445 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE는 지원되지 않음" + +#: executor/spi.c:1446 parser/analyze.c:2508 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "스크롤 가능 커서는 READ ONLY여야 합니다." + +#: executor/spi.c:2560 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "SQL 구문: \"%s\"" + +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "공유 메모리 큐로 튜플을 보낼 수 없음" + +#: foreign/foreign.c:220 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "\"%s\"에 대한 사용자 매핑을 찾을 수 없음" + +#: foreign/foreign.c:672 +#, c-format +msgid "invalid option \"%s\"" +msgstr "\"%s\" 옵션이 잘못됨" + +#: foreign/foreign.c:673 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "이 컨텍스트에서 유효한 옵션: %s" + +#: jit/jit.c:205 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:417 +#: utils/fmgr/dfmgr.c:465 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "\"%s\" 파일에 액세스할 수 없음: %m" + +#: jit/llvm/llvmjit.c:595 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "크기가 %zu인 DSA 요청에서 오류가 발생했습니다." + +#: libpq/auth-scram.c:248 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "클라이언트가 잘못된 SASL 인증 메카니즘을 선택했음" + +#: libpq/auth-scram.c:269 libpq/auth-scram.c:509 libpq/auth-scram.c:520 +#, c-format +msgid "invalid SCRAM secret for user \"%s\"" +msgstr "\"%s\" 사용자에 대한 잘못된 SCRAM secret" + +#: libpq/auth-scram.c:280 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM secret." +msgstr "\"%s\" 사용자용 바른 SCRAM secret이 없습니다." + +#: libpq/auth-scram.c:358 libpq/auth-scram.c:363 libpq/auth-scram.c:693 +#: libpq/auth-scram.c:701 libpq/auth-scram.c:806 libpq/auth-scram.c:819 +#: libpq/auth-scram.c:829 libpq/auth-scram.c:937 libpq/auth-scram.c:944 +#: libpq/auth-scram.c:959 libpq/auth-scram.c:974 libpq/auth-scram.c:988 +#: libpq/auth-scram.c:1006 libpq/auth-scram.c:1021 libpq/auth-scram.c:1321 +#: libpq/auth-scram.c:1329 +#, c-format +msgid "malformed SCRAM message" +msgstr "SCRAM 메시지가 형식에 맞지 않습니다" + +#: libpq/auth-scram.c:359 +#, c-format +msgid "The message is empty." +msgstr "메시지가 비었습니다." + +#: libpq/auth-scram.c:364 +#, c-format +msgid "Message length does not match input length." +msgstr "메시지 길이가 입력 길이와 같지 않습니다." + +#: libpq/auth-scram.c:396 +#, c-format +msgid "invalid SCRAM response" +msgstr "잘못된 SCRAM 응답" + +#: libpq/auth-scram.c:397 +#, c-format +msgid "Nonce does not match." +msgstr "토큰 불일치" + +#: libpq/auth-scram.c:471 +#, c-format +msgid "could not generate random salt" +msgstr "무작위 솔트 생성 실패" + +#: libpq/auth-scram.c:694 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "\"%c\" 속성이어야 하는데, \"%s\" 임." + +#: libpq/auth-scram.c:702 libpq/auth-scram.c:830 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "\"%c\" 속성에는 \"=\" 문자가 와야합니다." + +#: libpq/auth-scram.c:807 +#, c-format +msgid "Attribute expected, but found end of string." +msgstr "속성값이 와야하는데, 문자열 끝이 발견되었음." + +#: libpq/auth-scram.c:820 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "속성값이 와야하는데, \"%s\" 잘못된 문자가 발견되었음." + +#: libpq/auth-scram.c:938 libpq/auth-scram.c:960 +#, c-format +msgid "" +"The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not " +"include channel binding data." +msgstr "" + +#: libpq/auth-scram.c:945 libpq/auth-scram.c:975 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "쉼표가 와야하는데, \"%s\" 문자가 발견되었음." + +#: libpq/auth-scram.c:966 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "" + +#: libpq/auth-scram.c:967 +#, c-format +msgid "" +"The client supports SCRAM channel binding but thinks the server does not. " +"However, this server does support channel binding." +msgstr "" + +#: libpq/auth-scram.c:989 +#, c-format +msgid "" +"The client selected SCRAM-SHA-256 without channel binding, but the SCRAM " +"message includes channel binding data." +msgstr "" + +#: libpq/auth-scram.c:1000 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "지원하지 않는 SCRAM 채널 바인드 종류 \"%s\"" + +#: libpq/auth-scram.c:1007 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "예상치 못한 채널 바인딩 플래그 \"%s\"." + +#: libpq/auth-scram.c:1017 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "" + +#: libpq/auth-scram.c:1022 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "" + +#: libpq/auth-scram.c:1038 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "" + +#: libpq/auth-scram.c:1052 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "SCRAM 토큰에 인쇄할 수 없는 문자가 있음" + +#: libpq/auth-scram.c:1169 +#, c-format +msgid "could not generate random nonce" +msgstr "무작위 토큰을 만들 수 없음" + +#: libpq/auth-scram.c:1179 +#, c-format +msgid "could not encode random nonce" +msgstr "임의 nonce를 인코드할 수 없음" + +#: libpq/auth-scram.c:1285 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "" + +#: libpq/auth-scram.c:1303 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "" + +#: libpq/auth-scram.c:1322 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "" + +#: libpq/auth-scram.c:1330 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "" + +#: libpq/auth.c:280 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "사용자 \"%s\"의 인증을 실패했습니다: 호스트 거부됨" + +#: libpq/auth.c:283 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "사용자 \"%s\"의 \"trust\" 인증을 실패했습니다." + +#: libpq/auth.c:286 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "사용자 \"%s\"의 Ident 인증을 실패했습니다." + +#: libpq/auth.c:289 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "사용자 \"%s\"의 peer 인증을 실패했습니다." + +#: libpq/auth.c:294 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "사용자 \"%s\"의 password 인증을 실패했습니다" + +#: libpq/auth.c:299 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "\"%s\" 사용자에 대한 GSSAPI 인증을 실패했습니다." + +#: libpq/auth.c:302 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "\"%s\" 사용자에 대한 SSPI 인증을 실패했습니다." + +#: libpq/auth.c:305 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "사용자 \"%s\"의 PAM 인증을 실패했습니다." + +#: libpq/auth.c:308 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "\"%s\" 사용자에 대한 BSD 인증을 실패했습니다." + +#: libpq/auth.c:311 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "\"%s\" 사용자의 LDAP 인증을 실패했습니다." + +#: libpq/auth.c:314 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "사용자 \"%s\"의 인증서 인증을 실패했습니다" + +#: libpq/auth.c:317 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "사용자 \"%s\"의 RADIUS 인증을 실패했습니다." + +#: libpq/auth.c:320 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "사용자 \"%s\"의 인증을 실패했습니다: 잘못된 인증 방법" + +#: libpq/auth.c:324 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "pg_hba.conf 파일의 %d번째 줄에 지정한 인증 설정이 사용됨: \"%s\"" + +#: libpq/auth.c:371 +#, c-format +msgid "" +"client certificates can only be checked if a root certificate store is " +"available" +msgstr "" +"루트 인증서 저장소가 사용 가능한 경우에만 클라이언트 인증서를 검사할 수 있음" + +#: libpq/auth.c:382 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "연결에 유효한 클라이언트 인증서가 필요함" + +#: libpq/auth.c:392 +#, c-format +msgid "" +"GSSAPI encryption can only be used with gss, trust, or reject authentication " +"methods" +msgstr "" + +#: libpq/auth.c:426 +#, c-format +msgid "" +"pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\", %s 연결이 복제용 연결로는 pg_hba.conf 파일 설정" +"에 따라 거부됩니다" + +#: libpq/auth.c:428 libpq/auth.c:444 libpq/auth.c:502 libpq/auth.c:520 +msgid "SSL off" +msgstr "SSL 중지" + +#: libpq/auth.c:428 libpq/auth.c:444 libpq/auth.c:502 libpq/auth.c:520 +msgid "SSL on" +msgstr "SSL 동작" + +#: libpq/auth.c:432 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\" 연결이 복제용 연결로는 pg_hba.conf 파일 설정에 " +"따라 거부됩니다" + +#: libpq/auth.c:441 +#, c-format +msgid "" +"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s" +"\", %s" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\", 데이터베이스 \"%s\", %s 연결이 pg_hba.conf 파" +"일 설정에 따라 거부됩니다" + +#: libpq/auth.c:448 +#, c-format +msgid "" +"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\", 데이터베이스 \"%s\" 연결이 pg_hba.conf 파일 설" +"정에 따라 거부됩니다" + +#: libpq/auth.c:477 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "" +"클라이언트 IP 주소가 \"%s\" 이름으로 확인됨, 호스트 이름 확인 기능으로 맞음" + +#: libpq/auth.c:480 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "" +"클라이언트 IP 주소가 \"%s\" 이름으로 확인됨, 호스트 이름 확인 기능 사용안함" + +#: libpq/auth.c:483 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "" +"클라이언트 IP 주소가 \"%s\" 이름으로 확인됨, 호스트 이름 확인 기능으로 틀림" + +#: libpq/auth.c:486 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "\"%s\" 클라이언트 호스트 이름을 %s IP 주소로 전환할 수 없음." + +#: libpq/auth.c:491 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "클라이언트 IP 주소를 파악할 수 없음: 대상 호스트 이름: %s" + +#: libpq/auth.c:500 +#, c-format +msgid "" +"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s" +"\", %s" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\", %s 연결이 복제용 연결로 pg_hba.conf 파일에 설정" +"되어 있지 않습니다" + +#: libpq/auth.c:507 +#, c-format +msgid "" +"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\" 연결이 복제용 연결로 pg_hba.conf 파일에 설정되" +"어 있지 않습니다" + +#: libpq/auth.c:517 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\", 데이터베이스 \"%s\", %s 연결에 대한 설정이 " +"pg_hba.conf 파일에 없습니다." + +#: libpq/auth.c:525 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +msgstr "" +"호스트 \"%s\", 사용자 \"%s\", 데이터베이스 \"%s\" 연결에 대한 설정이 pg_hba." +"conf 파일에 없습니다." + +#: libpq/auth.c:688 +#, c-format +msgid "expected password response, got message type %d" +msgstr "메시지 타입 %d를 얻는 예상된 암호 응답" + +#: libpq/auth.c:716 +#, c-format +msgid "invalid password packet size" +msgstr "유효하지 않은 암호 패킷 사이즈" + +#: libpq/auth.c:734 +#, c-format +msgid "empty password returned by client" +msgstr "비어있는 암호는 클라이언트에 의해 돌려보냈습니다" + +#: libpq/auth.c:854 libpq/hba.c:1340 +#, c-format +msgid "" +"MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "\"db_user_namespace\"가 사용 가능한 경우 MD5 인증은 지원되지 않음" + +#: libpq/auth.c:860 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "무작위 MD5 솔트 생성 실패" + +#: libpq/auth.c:906 +#, c-format +msgid "SASL authentication is not supported in protocol version 2" +msgstr "프로토콜 버전 2에서는 SASL 인증을 지원되지 않음" + +#: libpq/auth.c:939 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "SASL 응답이 필요한데 메시지 형식 %d을(를) 받음" + +#: libpq/auth.c:1068 +#, c-format +msgid "GSSAPI is not supported in protocol version 2" +msgstr "프로토콜 버전 2에서는 GSSAPI가 지원되지 않음" + +#: libpq/auth.c:1128 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "GSS 응답이 필요한데 메시지 형식 %d을(를) 받음" + +#: libpq/auth.c:1189 +msgid "accepting GSS security context failed" +msgstr "GSS 보안 컨텍스트를 수락하지 못함" + +#: libpq/auth.c:1228 +msgid "retrieving GSS user name failed" +msgstr "GSS 사용자 이름을 검색하지 못함" + +#: libpq/auth.c:1359 +#, c-format +msgid "SSPI is not supported in protocol version 2" +msgstr "프로토콜 버전 2에서는 SSPI가 지원되지 않음" + +#: libpq/auth.c:1374 +msgid "could not acquire SSPI credentials" +msgstr "SSPI 자격 증명을 가져올 수 없음" + +#: libpq/auth.c:1399 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "SSPI 응답이 필요한데 메시지 형식 %d을(를) 받음" + +#: libpq/auth.c:1477 +msgid "could not accept SSPI security context" +msgstr "SSPI 보안 컨텍스트를 수락할 수 없음" + +#: libpq/auth.c:1539 +msgid "could not get token from SSPI security context" +msgstr "SSPI 보안 컨텍스트에서 토큰을 가져올 수 없음" + +#: libpq/auth.c:1658 libpq/auth.c:1677 +#, c-format +msgid "could not translate name" +msgstr "이름을 변환할 수 없음" + +#: libpq/auth.c:1690 +#, c-format +msgid "realm name too long" +msgstr "realm 이름이 너무 긺" + +#: libpq/auth.c:1705 +#, c-format +msgid "translated account name too long" +msgstr "변환된 접속자 이름이 너무 깁니다" + +#: libpq/auth.c:1886 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "Ident 연결에 소켓을 생성할 수 없습니다: %m" + +#: libpq/auth.c:1901 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "로컬 주소 \"%s\"에 바인드할 수 없습니다: %m" + +#: libpq/auth.c:1913 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "주소 \"%s\", 포트 %s의 Ident 서버에게 연결할 수 없습니다: %m" + +#: libpq/auth.c:1935 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "주소 \"%s\", 포트 %s의 Ident 서버에게 질의를 보낼 수 없습니다: %m" + +#: libpq/auth.c:1952 +#, c-format +msgid "" +"could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "주소 \"%s\", 포트 %s의 Ident 서버로부터 응답을 받지 못했습니다: %m" + +#: libpq/auth.c:1962 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "Ident 서버로부터 잘못된 형태의 응답를 보냈습니다: \"%s\"" + +#: libpq/auth.c:2009 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "이 플랫폼에서는 peer 인증이 지원되지 않음" + +#: libpq/auth.c:2013 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "신뢰성 피어를 얻을 수 없습니다: %m" + +#: libpq/auth.c:2025 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "UID %ld 해당하는 사용자를 찾을 수 없음: %s" + +#: libpq/auth.c:2124 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "잠재적인 PAM 레이어에서의 에러: %s" + +#: libpq/auth.c:2194 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "PAM 인증자를 생성할 수 없습니다: %s" + +#: libpq/auth.c:2205 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER) 실패: %s" + +#: libpq/auth.c:2237 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST) 실패: %s" + +#: libpq/auth.c:2249 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "pam_set_item(PAM_CONV) 실패: %s" + +#: libpq/auth.c:2262 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "PAM 인증 실패: %s" + +#: libpq/auth.c:2275 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmt 실패: %s" + +#: libpq/auth.c:2286 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "PAM 인증자를 릴리즈할 수 없습니다: %s" + +#: libpq/auth.c:2362 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "LDAP 초기화 실패: 오류번호 %d" + +#: libpq/auth.c:2399 +#, c-format +msgid "could not extract domain name from ldapbasedn" +msgstr "ldapbasedn에서 도메인 이름을 뽑을 수 없음" + +#: libpq/auth.c:2407 +#, c-format +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "\"%s\"용 LDAP 인증 작업에서 DNS SRV 레코드를 찾을 수 없음" + +#: libpq/auth.c:2409 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "명시적으로 LDAP 서버 이름을 지정하세요." + +#: libpq/auth.c:2461 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "LDAP 초기화 실패: %s" + +#: libpq/auth.c:2471 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ldap 인증으로 사용할 수 없는 LDAP 라이브러리" + +#: libpq/auth.c:2479 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "LDAP 초기화 실패: %m" + +#: libpq/auth.c:2489 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "LDAP 프로토콜 버전을 지정할 수 없음: %s" + +#: libpq/auth.c:2529 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "could not load function _ldap_start_tls_sA in wldap32.dll" + +#: libpq/auth.c:2530 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "이 플랫폼에서는 SSL을 이용한 LDAP 기능을 지원하지 않음." + +#: libpq/auth.c:2546 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "LDAP TLS 세션을 시작할 수 없음: %s" + +#: libpq/auth.c:2617 +#, c-format +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "LDAP 서버도 ldapbasedn도 지정하지 않았음" + +#: libpq/auth.c:2624 +#, c-format +msgid "LDAP server not specified" +msgstr "LDAP 서버가 지정되지 않음" + +#: libpq/auth.c:2686 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "LDAP 인증을 위한 사용자 이름에 사용할 수 없는 문자가 있습니다" + +#: libpq/auth.c:2703 +#, c-format +msgid "" +"could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": " +"%s" +msgstr "" +"\"%s\" ldapbinddn (해당 서버: \"%s\") 설정에 대한 LDAP 바인드 초기화를 할 수 " +"없음: %s" + +#: libpq/auth.c:2732 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "\"%s\" 필터로 LDAP 검색 실패함, 대상 서버: \"%s\": %s" + +#: libpq/auth.c:2746 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "\"%s\" LDAP 사용자가 없음" + +#: libpq/auth.c:2747 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "\"%s\" 필터로 \"%s\" 서버에서 LDAP 검색을 했으나, 해당 자료가 없음" + +#: libpq/auth.c:2751 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "\"%s\" LDAP 사용자가 유일하지 않습니다" + +#: libpq/auth.c:2752 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "" +"LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "\"%s\" 필터로 \"%s\" 서버에서 LDAP 검색 결과 %d 항목을 반환함" + +#: libpq/auth.c:2772 +#, c-format +msgid "" +"could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "\"%s\" 첫번째 항목 조회용 dn 값을 \"%s\" 서버에서 찾을 수 없음: %s" + +#: libpq/auth.c:2793 +#, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "\"%s\" 사용자 검색 후 unbind 작업을 \"%s\" 서버에서 할 수 없음" + +#: libpq/auth.c:2824 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "\"%s\" 사용자의 \"%s\" LDAP 서버 로그인 실패: %s" + +#: libpq/auth.c:2853 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "LDAP 진단: %s" + +#: libpq/auth.c:2880 +#, c-format +msgid "" +"certificate authentication failed for user \"%s\": client certificate " +"contains no user name" +msgstr "" +"\"%s\" 사용자에 대한 인증서 로그인 실패: 클라이언트 인증서에 사용자 이름이 없" +"음" + +#: libpq/auth.c:2897 +#, c-format +msgid "" +"certificate validation (clientcert=verify-full) failed for user \"%s\": CN " +"mismatch" +msgstr "\"%s\" 사용자를 위한 인증서 유효성 검사를 실패 함: CN 같지 않음" + +#: libpq/auth.c:2998 +#, c-format +msgid "RADIUS server not specified" +msgstr "RADIUS 서버가 지정되지 않음" + +#: libpq/auth.c:3005 +#, c-format +msgid "RADIUS secret not specified" +msgstr "RADIUS 비밀키가 지정되지 않음" + +#: libpq/auth.c:3019 +#, c-format +msgid "" +"RADIUS authentication does not support passwords longer than %d characters" +msgstr "RADIUS 인증은 %d 글자 보다 큰 비밀번호 인증을 지원하지 않습니다" + +#: libpq/auth.c:3124 libpq/hba.c:1954 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "\"%s\" RADIUS 서버 이름을 주소로 바꿀 수 없음: %s" + +#: libpq/auth.c:3138 +#, c-format +msgid "could not generate random encryption vector" +msgstr "무작위 암호화 벡터를 만들 수 없음" + +#: libpq/auth.c:3172 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "비밀번호의 MD5 암호를 만들 수 없음" + +# translator: %s is IPv4, IPv6, or Unix +#: libpq/auth.c:3198 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "RADIUS 소켓을 생성할 수 없습니다: %m" + +# translator: %s is IPv4, IPv6, or Unix +#: libpq/auth.c:3220 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "RADIUS 소켓에 바인드할 수 없습니다: %m" + +#: libpq/auth.c:3230 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "RADIUS 패킷을 보낼 수 없음: %m" + +#: libpq/auth.c:3263 libpq/auth.c:3289 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "%s 에서 RADIUS 응답 대기 시간 초과" + +# translator: %s is IPv4, IPv6, or Unix +#: libpq/auth.c:3282 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "RADIUS 소켓 상태를 확인할 수 없음: %m" + +#: libpq/auth.c:3312 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "RADIUS 응답을 읽을 수 없음: %m" + +#: libpq/auth.c:3325 libpq/auth.c:3329 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "%s에서 RADIUS 응답이 바르지 않은 포트로부터 보내졌음: %d" + +#: libpq/auth.c:3338 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "%s에서 RADIUS 응답이 너무 짧음: %d" + +#: libpq/auth.c:3345 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "%s에서 RADIUS 응답 길이가 이상함: %d (실재 길이: %d)" + +#: libpq/auth.c:3353 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "%s에서 RADIUS 응답이 요청과 다름: %d (기대값: %d)" + +#: libpq/auth.c:3378 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "받은 패킷을 대상으로 MD5 암호화 작업할 수 없음" + +#: libpq/auth.c:3387 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "%s에서 RADIUS 응답의 MD5 값이 이상함" + +#: libpq/auth.c:3405 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "%s에서 RADIUS 응답이 바르지 않은 값임 (%d), 대상 사용자: \"%s\"" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:553 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "유효하지 않은 대형 개체 설명: %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "%d번 대형 개체 기술자가 읽기 모드로 열려있지 않습니다" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:560 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "%d번 대형 개체 기술자가 쓰기 모드로 열려있지 않습니다" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "%d번 대형 개체 기술자에 대한 lo_lseek 반환값이 범위를 벗어남" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "%d번 대형 개체 기술자에 대한 lo_tell 반환값이 범위를 벗어남" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "서버 파일 \"%s\"을 열 수 없습니다: %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "서버 파일 \"%s\"을 읽을 수 없습니다: %m" + +#: libpq/be-fsstubs.c:514 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "서버 파일 \"%s\"의 생성을 할 수 없습니다: %m" + +#: libpq/be-fsstubs.c:526 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "서버 파일 \"%s\"에 쓸 수 없습니다: %m" + +#: libpq/be-fsstubs.c:760 +#, c-format +msgid "large object read request is too large" +msgstr "대형 개체 읽기 요청이 너무 큽니다" + +#: libpq/be-fsstubs.c:802 utils/adt/genfile.c:265 utils/adt/genfile.c:304 +#: utils/adt/genfile.c:340 +#, c-format +msgid "requested length cannot be negative" +msgstr "요청한 길이는 음수일 수 없음" + +#: libpq/be-fsstubs.c:855 storage/large_object/inv_api.c:297 +#: storage/large_object/inv_api.c:309 storage/large_object/inv_api.c:513 +#: storage/large_object/inv_api.c:624 storage/large_object/inv_api.c:814 +#, c-format +msgid "permission denied for large object %u" +msgstr "%u 대형 개체에 대한 접근 권한 없음" + +#: libpq/be-secure-common.c:93 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "\"%s\" 명령에서 읽을 수 없음: %m" + +#: libpq/be-secure-common.c:113 +#, c-format +msgid "command \"%s\" failed" +msgstr "\"%s\" 명령 실패" + +#: libpq/be-secure-common.c:141 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "비밀키 \"%s\"에 액세스할 수 없습니다: %m" + +#: libpq/be-secure-common.c:150 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "\"%s\" 개인 키 파일은 일반 파일이 아님" + +#: libpq/be-secure-common.c:165 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "" +"\"%s\" 개인 키 파일의 소유주는 데이터베이스 사용자이거나 root 여야 합니다." + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "\"%s\" 개인 키 파일에 그룹 또는 익명 액세스 권한이 있음" + +#: libpq/be-secure-common.c:190 +#, c-format +msgid "" +"File must have permissions u=rw (0600) or less if owned by the database " +"user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "" +"파일의 소유주가 데이터베이스 서버 운영 계정과 같다면, 접근 권한을 u=rw " +"(0600) 또는 더 작게 설정하고, root가 소유주라면 u=rw,g=r (0640) 권한으로 지정" +"하세요" + +#: libpq/be-secure-gssapi.c:195 +msgid "GSSAPI wrap error" +msgstr "" + +#: libpq/be-secure-gssapi.c:199 +#, c-format +msgid "outgoing GSSAPI message would not use confidentiality" +msgstr "" + +#: libpq/be-secure-gssapi.c:203 libpq/be-secure-gssapi.c:574 +#, c-format +msgid "server tried to send oversize GSSAPI packet (%zu > %zu)" +msgstr "" + +#: libpq/be-secure-gssapi.c:330 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "" + +#: libpq/be-secure-gssapi.c:364 +msgid "GSSAPI unwrap error" +msgstr "" + +#: libpq/be-secure-gssapi.c:369 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "" + +#: libpq/be-secure-gssapi.c:525 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "" + +#: libpq/be-secure-gssapi.c:547 +msgid "could not accept GSSAPI security context" +msgstr "GSSAPI 보안 내용을 받아드릴 수 없음" + +#: libpq/be-secure-gssapi.c:637 +msgid "GSSAPI size check error" +msgstr "GSSAPI 크기 검사 오류" + +#: libpq/be-secure-openssl.c:112 +#, c-format +msgid "could not create SSL context: %s" +msgstr "SSL 컨텍스트 정보를 생성할 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:138 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "서버 인증서 파일 \"%s\"을 불러들일 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:158 +#, c-format +msgid "" +"private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "" +"\"%s\" 개인 키 파일은 비밀번호를 입력해야 해서 자동으로 다시 불러올 수 없습니" +"다." + +#: libpq/be-secure-openssl.c:163 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "비밀키 파일 \"%s\"을 불러들일 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:172 +#, c-format +msgid "check of private key failed: %s" +msgstr "비밀키의 확인 실패: %s" + +#: libpq/be-secure-openssl.c:184 libpq/be-secure-openssl.c:206 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "\"%s\" 의 \"%s\" 설정 기능을 빼고 빌드 되었음" + +#: libpq/be-secure-openssl.c:194 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "최소 SSL 프로토콜 버전을 설정할 수 없음" + +#: libpq/be-secure-openssl.c:216 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "최대 SSL 프로토콜 버전을 설정할 수 없음" + +#: libpq/be-secure-openssl.c:232 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "SSL 프로토콜 버전 범위를 지정할 수 없음" + +#: libpq/be-secure-openssl.c:233 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "\"%s\" 값은 \"%s\" 보다 높을 수 없음" + +#: libpq/be-secure-openssl.c:257 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "cipher 목록을 설정할 수 없음 (유요한 cipher가 없음)" + +#: libpq/be-secure-openssl.c:275 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "root 인증서 파일 \"%s\"을 불러들일 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:302 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "\"%s\" SSL 인증서 회수 목록 파일을 불러들일 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:378 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "SSL연결을 초기화할 수 없습니다: SSL 컨텍스트를 설정 못함" + +#: libpq/be-secure-openssl.c:386 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "SSL연결을 초기화할 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:394 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "SSL 소켓을 지정할 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:449 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "SSL 연결을 받아드릴 수 없습니다: %m" + +#: libpq/be-secure-openssl.c:453 libpq/be-secure-openssl.c:506 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "SSL 연결을 받아드릴 수 없습니다: EOF 감지됨" + +#: libpq/be-secure-openssl.c:492 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "SSL 연결을 받아드릴 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:495 +#, c-format +msgid "" +"This may indicate that the client does not support any SSL protocol version " +"between %s and %s." +msgstr "" + +#: libpq/be-secure-openssl.c:511 libpq/be-secure-openssl.c:642 +#: libpq/be-secure-openssl.c:706 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "인식되지 않은 SSL 에러 코드 %d" + +#: libpq/be-secure-openssl.c:553 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "SSL 인증서의 일반 이름에 포함된 null이 있음" + +#: libpq/be-secure-openssl.c:631 libpq/be-secure-openssl.c:690 +#, c-format +msgid "SSL error: %s" +msgstr "SSL 에러: %s" + +#: libpq/be-secure-openssl.c:871 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "\"%s\" DH 매개 변수 파일을 열 수 없습니다: %m" + +#: libpq/be-secure-openssl.c:883 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "DH 매개 변수 파일을 불러들일 수 없습니다: %s" + +#: libpq/be-secure-openssl.c:893 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "잘못된 DH 매개 변수: %s" + +#: libpq/be-secure-openssl.c:901 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "잘못된 DH 매개 변수값: p는 prime 아님" + +#: libpq/be-secure-openssl.c:909 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "" + +#: libpq/be-secure-openssl.c:1065 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: DH 매개 변수 불러오기 실패" + +#: libpq/be-secure-openssl.c:1073 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: DH 매개 변수 설정 실패: %s" + +#: libpq/be-secure-openssl.c:1100 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: 알 수 없는 curve 이름: %s" + +#: libpq/be-secure-openssl.c:1109 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: 키 생성 실패" + +#: libpq/be-secure-openssl.c:1137 +msgid "no SSL error reported" +msgstr "SSL 오류 없음" + +#: libpq/be-secure-openssl.c:1141 +#, c-format +msgid "SSL error code %lu" +msgstr "SSL 오류 번호 %lu" + +#: libpq/be-secure.c:122 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "\"%s\" 로부터의 SSL 연결" + +#: libpq/be-secure.c:207 libpq/be-secure.c:303 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "postmaster의 예상치 못한 종료로 연결을 종료합니다" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "\"%s\" 롤 없음" + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "\"%s\" 사용자 비밀번호가 아직 할당되지 않음" + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "\"%s\" 사용자 비밀번호가 기한 만료되었습니다." + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "" + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "\"%s\" 사용자의 비밀번호가 틀립니다." + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "" + +#: libpq/hba.c:235 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "인증 파일의 토큰이 너무 길어서 건너뜁니다: \"%s\"" + +#: libpq/hba.c:407 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "2차 인증파일 \"%s\"으로 \"@%s\"를 열 수 없다: %m" + +#: libpq/hba.c:509 +#, c-format +msgid "authentication file line too long" +msgstr "인증 파일 줄이 너무 깁니다" + +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1013 libpq/hba.c:1022 +#: libpq/hba.c:1035 libpq/hba.c:1056 libpq/hba.c:1069 libpq/hba.c:1089 +#: libpq/hba.c:1111 libpq/hba.c:1123 libpq/hba.c:1179 libpq/hba.c:1199 +#: libpq/hba.c:1213 libpq/hba.c:1232 libpq/hba.c:1243 libpq/hba.c:1258 +#: libpq/hba.c:1276 libpq/hba.c:1292 libpq/hba.c:1304 libpq/hba.c:1341 +#: libpq/hba.c:1382 libpq/hba.c:1395 libpq/hba.c:1417 libpq/hba.c:1430 +#: libpq/hba.c:1442 libpq/hba.c:1460 libpq/hba.c:1510 libpq/hba.c:1554 +#: libpq/hba.c:1565 libpq/hba.c:1581 libpq/hba.c:1598 libpq/hba.c:1608 +#: libpq/hba.c:1666 libpq/hba.c:1704 libpq/hba.c:1726 libpq/hba.c:1738 +#: libpq/hba.c:1825 libpq/hba.c:1843 libpq/hba.c:1937 libpq/hba.c:1956 +#: libpq/hba.c:1985 libpq/hba.c:1998 libpq/hba.c:2021 libpq/hba.c:2043 +#: libpq/hba.c:2057 tsearch/ts_locale.c:217 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "%d번째 줄(\"%s\" 환경 설정 파일)" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:865 +#, c-format +msgid "" +"authentication option \"%s\" is only valid for authentication methods %s" +msgstr "\"%s\" 인증 옵션은 %s 인증 방법에만 유효함" + +#: libpq/hba.c:885 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "\"%s\" 인증 방법의 경우 \"%s\" 인자를 설정해야 함" + +#: libpq/hba.c:913 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "\"%s\" 파일의 %d번째 줄의 끝 라인에 빠진 엔트리가 있습니다 " + +#: libpq/hba.c:924 +#, c-format +msgid "multiple values in ident field" +msgstr "ident 자리에 여러 값이 있음" + +#: libpq/hba.c:973 +#, c-format +msgid "multiple values specified for connection type" +msgstr "연결 형식 자리에 여러 값이 있음" + +#: libpq/hba.c:974 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "한 줄에 하나의 연결 형태만 지정해야 합니다" + +#: libpq/hba.c:988 +#, c-format +msgid "local connections are not supported by this build" +msgstr "로컬 접속 기능을 뺀 채로 서버가 만들어졌습니다." + +#: libpq/hba.c:1011 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "" + +#: libpq/hba.c:1012 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "postgresql.conf 파일에 ssl = on 설정을 하세요." + +#: libpq/hba.c:1020 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "" +"이 서버는 ssl 접속 기능을 지원하지 않아 hostssl 인증을 지원하지 않습니다." + +#: libpq/hba.c:1021 +#, c-format +msgid "Compile with --with-openssl to use SSL connections." +msgstr "" +"SSL 연결을 사용하기 위해 --enable-ssl 옵션을 사용해서 서버를 다시 컴파일 하세" +"요" + +#: libpq/hba.c:1033 +#, c-format +msgid "" +"hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "" +"이 서버는 GSSAPI 접속 기능을 지원하지 않아 hostgssenc 레코드가 적당하지 않음" + +#: libpq/hba.c:1034 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "" +"GSSAPI 연결을 사용하기 위해 --with-gssapi 옵션을 사용해서 서버를 다시 컴파일 " +"하세요" + +#: libpq/hba.c:1054 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "\"%s\" 값은 잘못된 연결 형식입니다" + +#: libpq/hba.c:1068 +#, c-format +msgid "end-of-line before database specification" +msgstr "데이터베이스 지정 전에 줄 끝에 도달함" + +#: libpq/hba.c:1088 +#, c-format +msgid "end-of-line before role specification" +msgstr "롤 지정 전에 줄 끝에 도달함" + +#: libpq/hba.c:1110 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "IP 주소 지정 전에 줄 끝에 도달함" + +#: libpq/hba.c:1121 +#, c-format +msgid "multiple values specified for host address" +msgstr "호스트 주소 부분에 여러 값이 지정됨" + +#: libpq/hba.c:1122 +#, c-format +msgid "Specify one address range per line." +msgstr "한 줄에 하나의 주소 범위가 있어야 합니다." + +#: libpq/hba.c:1177 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "\"%s\" 형태는 잘못된 IP 주소 형태입니다: %s" + +#: libpq/hba.c:1197 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "호스트 이름과 CIDR 마스크는 함께 쓸 수 없습니다: \"%s\"" + +#: libpq/hba.c:1211 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "\"%s\" 주소에 잘못된 CIDR 마스크가 있음" + +#: libpq/hba.c:1230 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "넷마스크 지정 전에 줄 끝에 도달함" + +#: libpq/hba.c:1231 +#, c-format +msgid "" +"Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "주소 범위는 CIDR 표기법을 쓰거나 넷마스크 표기법을 쓰세요" + +#: libpq/hba.c:1242 +#, c-format +msgid "multiple values specified for netmask" +msgstr "넷마스크 부분에 여러 값이 지정됨" + +#: libpq/hba.c:1256 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "잘못된 IP 마스크, \"%s\": %s" + +#: libpq/hba.c:1275 +#, c-format +msgid "IP address and mask do not match" +msgstr "IP 주소와 마스크가 맞지 않습니다" + +#: libpq/hba.c:1291 +#, c-format +msgid "end-of-line before authentication method" +msgstr "인증 방법 전에 줄 끝에 도달함" + +#: libpq/hba.c:1302 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "인증 방법 부분에 여러 값이 지정됨" + +#: libpq/hba.c:1303 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "하나의 인증 방법에 대해서 한 줄씩 지정해야 합니다" + +#: libpq/hba.c:1380 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "\"%s\" 인증 방법이 잘못됨" + +#: libpq/hba.c:1393 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "\"%s\" 인증 방법이 잘못됨: 이 서버에서 지원되지 않음" + +#: libpq/hba.c:1416 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "gssapi 인증은 로컬 소켓에서 지원되지 않음" + +#: libpq/hba.c:1429 +#, c-format +msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +msgstr "" + +#: libpq/hba.c:1441 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "peer 인증은 로컬 소켓에서만 지원함" + +#: libpq/hba.c:1459 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "cert 인증은 hostssl 연결에서만 지원됨" + +#: libpq/hba.c:1509 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "인증 옵션이 이름=값 형태가 아님: %s" + +#: libpq/hba.c:1553 +#, c-format +msgid "" +"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, " +"ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "" +"ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, " +"ldapsearchfilter, ldapurl 옵션은 ldapprefix 옵션과 함께 사용할 수 없음" + +#: libpq/hba.c:1564 +#, c-format +msgid "" +"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix" +"\", or \"ldapsuffix\" to be set" +msgstr "" +"\"ldap\" 인증 방법의 경우 \"ldapbasedn\", \"ldapprefix\", \"ldapsuffix\"옵션" +"이 있어야 함" + +#: libpq/hba.c:1580 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ldapsearchattribute 옵션은 ldapsearchfilter 옵션과 함께 사용할 수 없음" + +#: libpq/hba.c:1597 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "RADIUS 서버 목록은 비어 있을 수 없음" + +#: libpq/hba.c:1607 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "RADIUS 비밀키 목록은 비어 있을 수 없음" + +#: libpq/hba.c:1660 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "서버 목록과 키 목록이 안 맞음: %s (%d) / %s (%d)" + +#: libpq/hba.c:1694 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi 및 cert" + +#: libpq/hba.c:1703 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert는 \"hostssl\" 행에 대해서만 구성할 수 있음" + +#: libpq/hba.c:1725 +#, c-format +msgid "" +"clientcert cannot be set to \"no-verify\" when using \"cert\" authentication" +msgstr "" +"\"cert\" 인증을 사용하는 경우 clientcert를 \"no-verify\"로 설정할 수 없음" + +#: libpq/hba.c:1737 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "잘못된 clientcert 값: \"%s\"" + +#: libpq/hba.c:1771 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "\"%s\" LDAP URL을 분석할 수 없음: %s" + +#: libpq/hba.c:1782 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "지원하지 않는 LDAP URL 스킴: %s" + +#: libpq/hba.c:1806 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "이 플랫폼에서는 LDAP URL 기능을 지원하지 않음." + +#: libpq/hba.c:1824 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "잘못된 ldapscheme 값: \"%s\"" + +#: libpq/hba.c:1842 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "LDAP 포트 번호가 잘못됨: \"%s\"" + +#: libpq/hba.c:1888 libpq/hba.c:1895 +msgid "gssapi and sspi" +msgstr "gssapi 및 sspi" + +#: libpq/hba.c:1904 libpq/hba.c:1913 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1935 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "RADIUS 서버 목록 분석 실패: \"%s\"" + +#: libpq/hba.c:1983 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "RADIUS 서버 포트 목록 분석 실패: \"%s\"" + +#: libpq/hba.c:1997 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "RADIUS 포트 번호가 잘못됨: \"%s\"" + +# translator: %s is IPv4, IPv6, or Unix +#: libpq/hba.c:2019 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "RADIUS 서버 비밀키 목록 분석 실패: \"%s\"" + +#: libpq/hba.c:2041 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "RADIUS 서버 식별자 목록 분석 실패: \"%s\"" + +#: libpq/hba.c:2055 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "알 수 없는 인증 옵션 이름: \"%s\"" + +#: libpq/hba.c:2199 libpq/hba.c:2613 guc-file.l:631 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "\"%s\" 설정 파일 을 열수 없습니다: %m" + +#: libpq/hba.c:2250 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "\"%s\" 설정 파일에 구성 항목이 없음" + +#: libpq/hba.c:2768 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "\"%s\" 정규식이 잘못됨: %s" + +#: libpq/hba.c:2828 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "\"%s\"에 대한 정규식 일치 실패: %s" + +#: libpq/hba.c:2847 +#, c-format +msgid "" +"regular expression \"%s\" has no subexpressions as requested by " +"backreference in \"%s\"" +msgstr "\"%s\" 정규식에는 \"%s\"의 backreference에서 요청된 하위 식이 없음" + +#: libpq/hba.c:2943 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "제공된 사용자 이름(%s) 및 인증된 사용자 이름(%s)이 일치하지 않음" + +#: libpq/hba.c:2963 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "" +"\"%s\" 사용자맵 파일에 \"%s\" 사용자를 \"%s\" 사용자로 인증할 설정이 없음" + +#: libpq/hba.c:2996 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "\"%s\" 사용자맵 파일을 열 수 없습니다: %m" + +#: libpq/pqcomm.c:218 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "소켓을 nonblocking 모드로 지정할 수 없음: %m" + +#: libpq/pqcomm.c:372 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "\"%s\" 유닉스 도메인 소켓 경로가 너무 깁니다 (최대 %d 바이트)" + +#: libpq/pqcomm.c:393 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "호스트 이름 \"%s\", 서비스 \"%s\"를 변환할 수 없습니다. 주소 : %s" + +#: libpq/pqcomm.c:397 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "서비스 \"%s\"를 변환할 수 없습니다. 주소 : %s" + +#: libpq/pqcomm.c:424 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "최대 접속자 수 MAXLISTEN (%d) 초과로 더 이상 접속이 불가능합니다" + +#: libpq/pqcomm.c:433 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:437 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:442 +msgid "Unix" +msgstr "유닉스" + +#: libpq/pqcomm.c:447 +#, c-format +msgid "unrecognized address family %d" +msgstr "%d는 인식되지 않는 가족 주소입니다" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:473 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "%s 소켓 만들기 실패, 대상 주소: \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:499 +#, c-format +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "%s setsockopt(SO_REUSEADDR) 실패, 대상 주소: \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:516 +#, c-format +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "%s setsockopt(IPV6_V6ONLY) 실패, 대상 주소: \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:536 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "%s 바인드 실패, 대상 주소: \"%s\": %m" + +#: libpq/pqcomm.c:539 +#, c-format +msgid "" +"Is another postmaster already running on port %d? If not, remove socket file " +"\"%s\" and retry." +msgstr "" +"다른 postmaster 가 포트 %d에서 이미 실행중인것 같습니다? 그렇지 않다면 소켓 " +"파일 \"%s\"을 제거하고 다시 시도해보십시오" + +#: libpq/pqcomm.c:542 +#, c-format +msgid "" +"Is another postmaster already running on port %d? If not, wait a few seconds " +"and retry." +msgstr "" +"다른 postmaster 가 포트 %d에서 이미 실행중인것 같습니다? 그렇지 않다면 몇 초" +"를 기다렸다가 다시 시도해보십시오." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:575 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "%s 리슨 실패, 대상 주소: \"%s\": %m" + +# translator: %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:584 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "\"%s\" 유닉스 도메인 소켓으로 접속을 허용합니다" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:590 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "%s, 주소: \"%s\", 포트 %d 번으로 접속을 허용합니다" + +#: libpq/pqcomm.c:673 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "\"%s\" 그룹 없음" + +#: libpq/pqcomm.c:683 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "파일 \"%s\" 의 그룹을 세팅할 수 없습니다: %m" + +#: libpq/pqcomm.c:694 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "파일 \"%s\" 의 퍼미션을 세팅할 수 없습니다: %m" + +#: libpq/pqcomm.c:724 +#, c-format +msgid "could not accept new connection: %m" +msgstr "새로운 연결을 생성할 수 없습니다: %m" + +#: libpq/pqcomm.c:914 +#, c-format +msgid "there is no client connection" +msgstr "클라이언트 연결이 없음" + +#: libpq/pqcomm.c:965 libpq/pqcomm.c:1061 +#, c-format +msgid "could not receive data from client: %m" +msgstr "클라이언트에게 데이터를 받을 수 없습니다: %m" + +#: libpq/pqcomm.c:1206 tcop/postgres.c:4142 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "프로토콜 동기화 작업 실패로 연결을 종료합니다" + +#: libpq/pqcomm.c:1272 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "예상치 못한 EOF가 메시지의 길이 워드안에서 발생했습니다." + +#: libpq/pqcomm.c:1283 +#, c-format +msgid "invalid message length" +msgstr "메시지의 길이가 유효하지 않습니다" + +#: libpq/pqcomm.c:1305 libpq/pqcomm.c:1318 +#, c-format +msgid "incomplete message from client" +msgstr "클라이언트으로부터의 완전하지 못한 메시지입니다" + +#: libpq/pqcomm.c:1451 +#, c-format +msgid "could not send data to client: %m" +msgstr "클라이언트에게 데이터를 보낼 수 없습니다: %m" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "메시지에 아무런 데이터가 없습니다" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1471 utils/adt/rowtypes.c:567 +#, c-format +msgid "insufficient data left in message" +msgstr "부족한 데이터는 메시지 안에 넣어져 있습니다" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "메시지안에 유효하지 않은 문자열이 있습니다" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "메시지 포맷이 유효하지 않습니다." + +# # search5 끝 +# # advance 부분 +#: main/main.c:246 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: WSAStartup 작업 실패: %d\n" + +#: main/main.c:310 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%s 프로그램은 PostgreSQL 서버입니다.\n" +"\n" + +#: main/main.c:311 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"사용법:\n" +" %s [옵션]...\n" +"\n" + +#: main/main.c:312 +#, c-format +msgid "Options:\n" +msgstr "옵션들:\n" + +#: main/main.c:313 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS 공유 버퍼 개수\n" + +#: main/main.c:314 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NAME=VALUE 실시간 매개 변수 지정\n" + +#: main/main.c:315 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NAME 실시간 매개 변수 값을 보여주고 마침\n" + +#: main/main.c:316 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 디버깅 수준\n" + +#: main/main.c:317 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D DATADIR 데이터 디렉터리\n" + +#: main/main.c:318 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e 날짜 입력 양식이 유럽형(DMY)을 사용함\n" + +#: main/main.c:319 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F fsync 기능 끔\n" + +#: main/main.c:320 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h HOSTNAME 서버로 사용할 호스트 이름 또는 IP\n" + +#: main/main.c:321 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i TCP/IP 연결 사용함\n" + +#: main/main.c:322 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k DIRECTORY 유닉스 도메인 소켓 위치\n" + +#: main/main.c:324 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l SSL 연결 기능 사용함\n" + +#: main/main.c:326 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-CONNECT 최대 동시 연결 개수\n" + +#: main/main.c:327 +#, c-format +msgid "" +" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr "" +" -o OPTIONS 개별 서버 프로세스를 \"OPTIONS\" 옵션으로 실행 (옛기" +"능)\n" + +#: main/main.c:328 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT 서버 포트 번호\n" + +#: main/main.c:329 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s 각 쿼리 뒤에 통계정보를 보여줌\n" + +#: main/main.c:330 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM 정렬작업에 사용할 메모리 크기(kb 단위)를 지정\n" + +#: main/main.c:331 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보 보여주고 마침\n" + +#: main/main.c:332 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NAME=VALUE 실시간 매개 변수 지정\n" + +#: main/main.c:333 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config 서버 환경 설정값에 대한 설명을 보여주고 마침\n" + +#: main/main.c:334 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: main/main.c:336 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"개발자 옵션들:\n" + +#: main/main.c:337 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h 쿼리최적화기의 기능을 제한 함\n" + +#: main/main.c:338 +#, c-format +msgid "" +" -n do not reinitialize shared memory after abnormal exit\n" +msgstr "" +" -n 비정상적 종료 뒤에 공유 메모리를 초기화 하지 않음\n" + +#: main/main.c:339 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O 시스템 테이블의 구조를 바꿀 수 있도록 함\n" + +#: main/main.c:340 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P 시스템 인덱스들을 사용하지 않음\n" + +#: main/main.c:341 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex 각 쿼리 다음 작업시간을 보여줌\n" + +#: main/main.c:342 +#, c-format +msgid "" +" -T send SIGSTOP to all backend processes if one dies\n" +msgstr "" +" -T 하나의 하위 서버 프로세스가 비정상으로 마치며 모든\n" +" 다른 서버 프로세스에게 SIGSTOP 신호를 보냄\n" + +#: main/main.c:343 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr "" +" -W NUM 디버그 작업을 위해 지정한 숫자의 초만큼 기다린다\n" + +#: main/main.c:345 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"단일사용자 모드에서 사용할 수 있는 옵션들:\n" + +#: main/main.c:346 +#, c-format +msgid "" +" --single selects single-user mode (must be first argument)\n" +msgstr " --single 단일 사용자 모드 선택 (인자의 첫번째로 와야함)\n" + +#: main/main.c:347 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAME 데이터베이스 이름 (초기값: 사용자이름)\n" + +#: main/main.c:348 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 디버깅 수준\n" + +#: main/main.c:349 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E 실행하기 전에 작업명령을 출력함\n" + +#: main/main.c:350 +#, c-format +msgid "" +" -j do not use newline as interactive query delimiter\n" +msgstr "" +" -j 대화형 쿼리의 명령 실행 구분 문자로 줄바꿈문자를 쓰지 않" +"음\n" + +#: main/main.c:351 main/main.c:356 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr "" +" -r FILENAME stdout, stderr 쪽으로 보내는 내용을 FILENAME 파일로 저장" +"함\n" + +#: main/main.c:353 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"부트스트랩 모드에서 사용할 수 있는 옵션들:\n" + +#: main/main.c:354 +#, c-format +msgid "" +" --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot 부트스트랩 모드로 실행 (첫번째 인자로 와야함)\n" + +#: main/main.c:355 +#, c-format +msgid "" +" DBNAME database name (mandatory argument in bootstrapping " +"mode)\n" +msgstr " DBNAME 데이터베이스 이름 (부트스트랩 모드에서 필수)\n" + +#: main/main.c:357 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM 내부적인 옵션\n" + +#: main/main.c:359 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"이 실시간 환경 변수용 설정값들의 자세한 사용법과\n" +"서버 환경 설정 파일에 어떻게 지정하고 사용하는지에 대한 사항은\n" +"PostgreSQL 문서를 참조하세요.\n" +"\n" +"문제점 보고 주소: <%s>\n" + +#: main/main.c:363 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: main/main.c:374 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"시스템 보안 관련 문제로, PostgreSQL server를 \"root\" ID로 실행할 수 없습니" +"다.\n" +"반드시 일반 사용자 ID(시스템 관리자 권한이 없는 ID)로 서버를 실행하십시오.\n" +"Server를 어떻게 안전하게 기동하는가 하는 것은 문서를 참조하시기 바랍니다.\n" + +#: main/main.c:391 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: real 또는 effective user ID 들은 반드시 일치되어야 한다.\n" + +#: main/main.c:398 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"시스템 보안 관련 문제로, PostgreSQL server를 시스템 관리자 ID로 실행할 수 없" +"습니다.\n" +"반드시 일반 사용자 ID(시스템 관리자 권한이 없는 ID)로 서버를 실행하십시오.\n" +"Server를 어떻게 안전하게 기동하는가 하는 것은 문서를 참조하시기 바랍니다.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "\"%s\" 이름의 확장가능한 노드 형이 이미 있습니다" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "\"%s\" ExtensibleNodeMethods가 등록되어 있지 않음" + +#: nodes/nodeFuncs.c:122 nodes/nodeFuncs.c:153 parser/parse_coerce.c:2208 +#: parser/parse_coerce.c:2317 parser/parse_coerce.c:2352 +#: parser/parse_expr.c:2207 parser/parse_func.c:701 parser/parse_oper.c:967 +#: utils/fmgr/funcapi.c:528 +#, c-format +msgid "could not find array type for data type %s" +msgstr "자료형 %s 에 대해서는 배열 자료형을 사용할 수 없습니다" + +#: nodes/params.c:359 +#, c-format +msgid "portal \"%s\" with parameters: %s" +msgstr "" + +#: nodes/params.c:362 +#, c-format +msgid "unnamed portal with parameters: %s" +msgstr "" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "" +"FULL JOIN is only supported with merge-joinable or hash-joinable join " +"conditions" +msgstr "" +"FULL JOIN 구문은 머지 조인이나, 해시 조인이 가능한 상황에서만 사용할 수 있습" +"니다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1193 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "" +"%s 구문은 outer 조인으로 null 값이 올 수 있는 쪽에 대해서는 적용할 수 없습니" +"다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1922 parser/analyze.c:1639 parser/analyze.c:1855 +#: parser/analyze.c:2715 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s 구문은 UNION/INTERSECT/EXCEPT 예약어들과 함께 사용할 수 없습니다." + +#: optimizer/plan/planner.c:2509 optimizer/plan/planner.c:4162 +#, c-format +msgid "could not implement GROUP BY" +msgstr "GROUP BY를 구현할 수 없음" + +#: optimizer/plan/planner.c:2510 optimizer/plan/planner.c:4163 +#: optimizer/plan/planner.c:4890 optimizer/prep/prepunion.c:1045 +#, c-format +msgid "" +"Some of the datatypes only support hashing, while others only support " +"sorting." +msgstr "해싱만 지원하는 자료형도 있고, 정렬만 지원하는 자료형도 있습니다." + +#: optimizer/plan/planner.c:4889 +#, c-format +msgid "could not implement DISTINCT" +msgstr "DISTINCT를 구현할 수 없음" + +#: optimizer/plan/planner.c:5737 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "창 PARTITION BY를 구현할 수 없음" + +#: optimizer/plan/planner.c:5738 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "창 분할 칼럼은 정렬 가능한 데이터 형식이어야 합니다." + +#: optimizer/plan/planner.c:5742 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "창 ORDER BY를 구현할 수 없음" + +#: optimizer/plan/planner.c:5743 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "창 순서 지정 칼럼은 정렬 가능한 데이터 형식이어야 합니다." + +#: optimizer/plan/setrefs.c:451 +#, c-format +msgid "too many range table entries" +msgstr "너무 많은 테이블이 사용되었습니다" + +#: optimizer/prep/prepunion.c:508 +#, c-format +msgid "could not implement recursive UNION" +msgstr "재귀 UNION을 구현할 수 없음" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "모든 열 데이터 형식은 해시 가능해야 합니다." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1044 +#, c-format +msgid "could not implement %s" +msgstr "%s 구문은 구현할 수 없음" + +#: optimizer/util/clauses.c:4746 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "" + +#: optimizer/util/plancat.c:132 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "복구 작업 중에는 임시 테이블이나, 언로그드 테이블을 접근할 수 없음" + +#: optimizer/util/plancat.c:662 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "" + +#: optimizer/util/plancat.c:679 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "ON CONFLICT 처리를 위해 관련된 인덱스가 없습니다" + +#: optimizer/util/plancat.c:729 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "제외 제약 조건이 있어 ON CONFLICT DO UPDATE 작업은 할 수 없습니다" + +#: optimizer/util/plancat.c:834 +#, c-format +msgid "" +"there is no unique or exclusion constraint matching the ON CONFLICT " +"specification" +msgstr "" +"ON CONFLICT 절을 사용하는 경우, unique 나 exclude 제약 조건이 있어야 함" + +#: parser/analyze.c:705 parser/analyze.c:1401 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "VALUES 목록은 모두 같은 길이여야 함" + +#: parser/analyze.c:904 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT 구문에 target columns 보다 더 많은 표현식이 존재하고 있다" + +#: parser/analyze.c:922 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "" +"INSERT 구문에 target columns 보다 더 많은 표현식(expressions)이 존재하고 있다" + +#: parser/analyze.c:926 +#, c-format +msgid "" +"The insertion source is a row expression containing the same number of " +"columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "" + +#: parser/analyze.c:1210 parser/analyze.c:1612 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO 구문은 여기서는 사용할 수 없음" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1542 parser/analyze.c:2894 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s 구문은 VALUES 에 적용할 수 없음" + +#: parser/analyze.c:1777 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "UNION/INTERSECT/EXCEPT ORDER BY 절이 잘못됨" + +#: parser/analyze.c:1778 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "결과 열 이름만 사용할 수 있고 식 또는 함수는 사용할 수 없습니다." + +#: parser/analyze.c:1779 +#, c-format +msgid "" +"Add the expression/function to every SELECT, or move the UNION into a FROM " +"clause." +msgstr "모든 SELECT에 식/함수를 추가하거나 UNION을 FROM 절로 이동하십시오." + +#: parser/analyze.c:1845 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO 는 UNION/INTERSECT/EXCEPT 의 첫번째 SELECT 에만 허용된다" + +#: parser/analyze.c:1917 +#, c-format +msgid "" +"UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of " +"same query level" +msgstr "" +"UNION/INTERSECT/EXCEPT 멤버 문에서 같은 쿼리 수준의 다른 관계를 참조할 수 없" +"음" + +#: parser/analyze.c:2004 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "각각의 %s query 는 같은 수의 columns 를 가져야 한다." + +#: parser/analyze.c:2426 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNING 절에는 적어도 하나 이상의 칼럼이 있어야 합니다" + +#: parser/analyze.c:2467 +#, c-format +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "SCROLL 과 NO SCROLL 둘다를 명시할 수 없다" + +#: parser/analyze.c:2486 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "" +"DECLARE CURSOR 구문에서 사용하는 WITH 절 안에는 자료 변경 구문이 없어야 합니" +"다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2494 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s 구문은 지원되지 않음" + +#: parser/analyze.c:2497 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "보류 가능 커서는 READ ONLY여야 합니다." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2505 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s 구문은 지원되지 않음" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2516 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %s 구문은 지원되지 않음" + +#: parser/analyze.c:2519 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "민감하지 않은 커서는 READ ONLY여야 합니다." + +#: parser/analyze.c:2585 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "" +"구체화된 뷰 정의에 사용한 WITH 절 안에는 자료 변경 구문이 없어야 합니다" + +#: parser/analyze.c:2595 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "구체화된 뷰는 임시 테이블이나 뷰를 사용할 수 없습니다" + +#: parser/analyze.c:2605 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "" + +#: parser/analyze.c:2617 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "구체화된 뷰는 UNLOGGED 옵션을 사용할 수 없습니다." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2722 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s 절은 DISTINCT 절과 함께 사용할 수 없습니다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2729 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s 절은 GROUP BY 절과 함께 사용할 수 없습니다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2736 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s 절은 HAVING 절과 함께 사용할 수 없습니다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2743 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s 절은 집계 함수와 함께 사용할 수 없습니다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2750 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s 절은 윈도우 함수와 함께 사용할 수 없습니다" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2757 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s 절은 대상 목록에서 세트 반환 함수와 함께 사용할 수 없습니다." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2836 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%s 절에는 unqualified 릴레이션 이름을 지정해야 합니다." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2867 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s 절은 조인을 적용할 수 없습니다." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2876 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s 절은 함수에 적용할 수 없습니다." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2885 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s 절은 테이블 함수에 적용할 수 없습니다." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2903 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s 절은 WITH 쿼리에 적용할 수 없음" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2912 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s 절은 named tuplestore에 적용할 수 없음" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2932 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "\"%s\" 릴레이션 (대상 구문: %s) 이 FROM 절 내에 없습니다" + +#: parser/parse_agg.c:220 parser/parse_oper.c:222 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "%s 자료형에서 사용할 순서 정하는 연산자를 찾을 수 없습니다." + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "" +"DISTINCT와 함께 작업하는 집계 작업은 그 입력 자료가 정렬될 수 있어야 합니다" + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING 인자로는 32개 이내로 지정해야 합니다" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "JOIN 조건문에서는 집계 함수가 허용되지 않습니다" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "JOIN 조건문에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:374 +msgid "" +"aggregate functions are not allowed in FROM clause of their own query level" +msgstr "집계 함수는 자신의 쿼리 수준의 FROM 절에서는 사용할 수 없습니다." + +#: parser/parse_agg.c:376 +msgid "" +"grouping operations are not allowed in FROM clause of their own query level" +msgstr "" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "FROM 절 내의 함수 표현식 내에서는 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "FROM 절 내의 함수 표현식 내에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "정책 표현식에서는 집계 함수 사용을 허용하지 않습니다" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "정책 표현식에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "윈도우 RANGE 안에서는 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "윈도우 RANGE 안에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "윈도우 ROWS 안에서는 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "윈도우 ROWS 안에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "윈도우 GROUPS 안에서는 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "윈도우 GROUPS 안에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "체크 제약 조건에서는 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "체크 제약 조건에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "DEFAULT 표현식에서는 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "DEFAULT 표현식에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "인덱스 표현식에서는 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "인덱스 표현식에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "집계 함수는 함수 기반 인덱스의 함수로 사용할 수 없습니다" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "그룹핑 작업은 함수 기반 인덱스의 함수로 사용할 수 없습니다" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "transform 식(expression)에 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in transform expressions" +msgstr "transform 식(expression)에 그룹핑 작업를 사용할 수 없습니다" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "EXECUTE 매개 변수로 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "EXECUTE 매개 변수로 그룹핑 작업을 사용할 수 없습니다" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "트리거의 WHEN 조건절에 집계 함수가 허용되지 않습니다" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "트리거의 WHEN 조건절에 그룹핑 작업이 허용되지 않습니다" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in partition bound" +msgstr "파티션 범위 표현식에는 집계 함수가 허용되지 않습니다" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in partition bound" +msgstr "파티션 범위 표현식에는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "파티션 키 표현식에서는 집계 함수가 허용되지 않습니다" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "파티션 키 표현식에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:526 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "미리 계산된 칼럼 표현식에서는 집계 함수 사용을 허용하지 않습니다" + +#: parser/parse_agg.c:528 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "미리 계산된 칼럼 표현식에서는 그룹핑 연산이 허용되지 않습니다" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "CALL 매개 변수로 집계 함수를 사용할 수 없습니다" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "CALL 매개 변수로 그룹핑 연산을 사용할 수 없습니다" + +#: parser/parse_agg.c:542 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "COPY FROM WHERE 조건문에서는 집계 함수가 허용되지 않습니다" + +#: parser/parse_agg.c:544 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "COPY FROM WHERE 조건문에서는 그룹핑 연산이 허용되지 않습니다" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:567 parser/parse_clause.c:1828 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "집계 함수는 %s 절에서 사용할 수 없습니다." + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:570 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "그룹핑 작업은 %s 절에서 사용할 수 없습니다." + +#: parser/parse_agg.c:678 +#, c-format +msgid "" +"outer-level aggregate cannot contain a lower-level variable in its direct " +"arguments" +msgstr "" + +#: parser/parse_agg.c:757 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "집계 함수 호출은 집합 반환 함수 호출을 포함할 수 없음" + +#: parser/parse_agg.c:758 parser/parse_expr.c:1845 parser/parse_expr.c:2332 +#: parser/parse_func.c:872 +#, c-format +msgid "" +"You might be able to move the set-returning function into a LATERAL FROM " +"item." +msgstr "집합 반환 함수를 LATERAL FROM 쪽으로 옮겨서 구현할 수도 있습니다." + +#: parser/parse_agg.c:763 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "집계 함수 호출은 윈도우 함수 호출을 포함할 수 없음" + +#: parser/parse_agg.c:842 +msgid "window functions are not allowed in JOIN conditions" +msgstr "윈도우 함수는 JOIN 조건에 사용할 수 없음" + +#: parser/parse_agg.c:849 +msgid "window functions are not allowed in functions in FROM" +msgstr "윈도우 함수는 FROM 절에 있는 함수로 사용할 수 없음" + +#: parser/parse_agg.c:855 +msgid "window functions are not allowed in policy expressions" +msgstr "윈도우 함수는 정책 식에 사용할 수 없음" + +#: parser/parse_agg.c:868 +msgid "window functions are not allowed in window definitions" +msgstr "윈도우 함수는 윈도우 함수 정의에 사용할 수 없음" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in check constraints" +msgstr "윈도우 함수는 check 제약조건에 사용할 수 없음" + +#: parser/parse_agg.c:904 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "윈도우 함수는 DEFAULT 식에서 사용할 수 없음" + +#: parser/parse_agg.c:907 +msgid "window functions are not allowed in index expressions" +msgstr "윈도우 함수는 인덱스 식에서 사용할 수 없음" + +#: parser/parse_agg.c:910 +msgid "window functions are not allowed in index predicates" +msgstr "윈도우 함수는 함수 기반 인덱스에서 사용할 수 없음" + +#: parser/parse_agg.c:913 +msgid "window functions are not allowed in transform expressions" +msgstr "윈도우 함수는 transform 식에서 사용할 수 없음" + +#: parser/parse_agg.c:916 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "윈도우 함수는 EXECUTE 매개 변수 설정 값으로 사용할 수 없음" + +#: parser/parse_agg.c:919 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "윈도우 함수는 트리거의 WHEN 조건절에서 사용할 수 없음" + +#: parser/parse_agg.c:922 +msgid "window functions are not allowed in partition bound" +msgstr "윈도우 함수는 파티션 범위 표현식에서 사용할 수 없음" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "윈도우 함수는 파티션 키 표현식에서 사용할 수 없음" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "윈도우 함수는 CALL 매개 변수 설정 값으로 사용할 수 없음" + +#: parser/parse_agg.c:931 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "윈도우 함수는 COPY FROM WHERE 조건에 사용할 수 없음" + +#: parser/parse_agg.c:934 +msgid "window functions are not allowed in column generation expressions" +msgstr "윈도우 함수는 미리 계산된 칼럼 생성 표현식에 사용할 수 없음" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:954 parser/parse_clause.c:1837 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "%s 안에서는 윈도우 함수를 사용할 수 없음" + +#: parser/parse_agg.c:988 parser/parse_clause.c:2671 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "\"%s\" 윈도우 함수가 없음" + +#: parser/parse_agg.c:1072 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "너무 많은 그룹핑 세트가 있습니다 (최대값 4096)" + +#: parser/parse_agg.c:1212 +#, c-format +msgid "" +"aggregate functions are not allowed in a recursive query's recursive term" +msgstr "집계 함수는 재귀 쿼리의 재귀 조건에 사용할 수 없음" + +#: parser/parse_agg.c:1405 +#, c-format +msgid "" +"column \"%s.%s\" must appear in the GROUP BY clause or be used in an " +"aggregate function" +msgstr "" +"column \"%s.%s\" 는 반드시 GROUP BY 절내에 있어야 하던지 또는 집계 함수 내에" +"서 사용되어져야 한다" + +#: parser/parse_agg.c:1408 +#, c-format +msgid "" +"Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "" + +#: parser/parse_agg.c:1413 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "" +"subquery 가 outer query 에서 그룹화 되지 않은 열인 \"%s.%s\"를 사용합니다" + +#: parser/parse_agg.c:1577 +#, c-format +msgid "" +"arguments to GROUPING must be grouping expressions of the associated query " +"level" +msgstr "" + +#: parser/parse_clause.c:191 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "\"%s\" 릴레이션은 자료 변경 구문의 대상이 될 수 없음" + +#: parser/parse_clause.c:571 parser/parse_clause.c:599 parser/parse_func.c:2424 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "" + +#: parser/parse_clause.c:611 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "다중 칼럼 정의 목록은 같은 함수용으로 허용하지 않음" + +#: parser/parse_clause.c:644 +#, c-format +msgid "" +"ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "" + +#: parser/parse_clause.c:645 +#, c-format +msgid "" +"Put a separate column definition list for each function inside ROWS FROM()." +msgstr "" + +#: parser/parse_clause.c:651 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "" + +#: parser/parse_clause.c:652 +#, c-format +msgid "" +"Use separate UNNEST() calls inside ROWS FROM(), and attach a column " +"definition list to each one." +msgstr "" + +#: parser/parse_clause.c:659 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY 구문은 칼럼 정의 목록과 함께 쓸 수 없습니다." + +#: parser/parse_clause.c:660 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "ROWS FROM() 안에 칼럼 정의 목록을 넣으세요." + +#: parser/parse_clause.c:760 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "" + +#: parser/parse_clause.c:821 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "\"%s\" 칼럼은 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_clause.c:863 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "\"%s\" 네임스페이스는 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_clause.c:873 +#, c-format +msgid "only one default namespace is allowed" +msgstr "기본 네임스페이스는 하나만 허용합니다" + +#: parser/parse_clause.c:933 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "\"%s\" 테이블 샘플링 방법이 없습니다" + +#: parser/parse_clause.c:955 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "\"%s\" 테이블 샘플링 방법 %d개 인자를 지정해야함, (현재 %d개)" + +#: parser/parse_clause.c:989 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "\"%s\" 테이블 샘플링 방법은 REPEATABLE 옵션을 지원하지 않음" + +#: parser/parse_clause.c:1135 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLE 절은 테이블과 구체화된 뷰에서만 사용할 수 있습니다" + +#: parser/parse_clause.c:1318 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "USING 절 내에 열 이름 \"%s\" 가 한번 이상 사용되었습니다" + +#: parser/parse_clause.c:1333 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "left table 내에 common column 이름 \"%s\" 가 한번 이상 사용되었다" + +#: parser/parse_clause.c:1342 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "USING 조건절에서 지정한 \"%s\" 칼럼이 왼쪽 테이블에 없음" + +#: parser/parse_clause.c:1357 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "common column name \"%s\"가 right table 에 한번 이상 사용되었다" + +#: parser/parse_clause.c:1366 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "USING 조건절에서 지정한 \"%s\" 칼럼이 오른쪽 테이블에 없음" + +#: parser/parse_clause.c:1447 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr " \"%s\" 를 위한 열 alias list 에 너무 많은 entry 가 포함되어 있다" + +#: parser/parse_clause.c:1773 +#, c-format +msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" +msgstr "" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1798 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "%s 의 인자로 변수를 포함할 수 없습니다." + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1963 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s \"%s\" 가 명확하지 않은 표현입니다." + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1992 +#, c-format +msgid "non-integer constant in %s" +msgstr "정수가 아닌 상수가 %s 에 포함되어 있습니다" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2014 +#, c-format +msgid "%s position %d is not in select list" +msgstr "%s position %d 가 select list 에 포함되어 있지 않습니다" + +#: parser/parse_clause.c:2453 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE 인자로는 12개 이하의 인자만 허용합니다" + +#: parser/parse_clause.c:2659 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "\"%s\" 이름의 윈도우 함수가 이미 정의됨" + +#: parser/parse_clause.c:2720 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "\"%s\" 창의 PARTITION BY 절을 재정의할 수 없음" + +#: parser/parse_clause.c:2732 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "\"%s\" 창의 ORDER BY 절을 재정의할 수 없음" + +#: parser/parse_clause.c:2762 parser/parse_clause.c:2768 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "프래임 절이 있어, \"%s\" 윈도우를 복사할 수 없음." + +#: parser/parse_clause.c:2770 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "OVER 절에 괄호가 빠졌음" + +#: parser/parse_clause.c:2790 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "" + +#: parser/parse_clause.c:2813 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPS 모드는 ORDER BY 구문이 필요함" + +#: parser/parse_clause.c:2883 +#, c-format +msgid "" +"in an aggregate with DISTINCT, ORDER BY expressions must appear in argument " +"list" +msgstr "" +"DISTINCT, ORDER BY 표현식을 집계 함수와 쓸 때는, 반드시 select list 에 나타나" +"야만 합니다" + +#: parser/parse_clause.c:2884 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "" +"SELECT DISTINCT, ORDER BY 표현식을 위해서 반드시 select list 에 나타나야만 합" +"니다" + +#: parser/parse_clause.c:2916 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "DISTINCT 예약어로 집계를 할 경우 적어도 하나의 인자는 있어야 함" + +#: parser/parse_clause.c:2917 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT 구문은 적어도 한 개 이상의 칼럼이 있어야 합니다" + +#: parser/parse_clause.c:2983 parser/parse_clause.c:3015 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "" +"SELECT DISTINCT ON 표현식은 반드시 초기 ORDER BY 표현식과 일치하여야 한다" + +#: parser/parse_clause.c:3093 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC 예약어는 ON CONFLICT 절과 함께 사용할 수 없습니다." + +#: parser/parse_clause.c:3099 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST 절은 ON CONFLICT 절과 함께 사용할 수 없습니다." + +#: parser/parse_clause.c:3178 +#, c-format +msgid "" +"ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "" + +#: parser/parse_clause.c:3179 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "사용예, ON CONFLICT (칼럼이름)." + +#: parser/parse_clause.c:3190 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT 절은 시스템 카탈로그 테이블에서는 사용할 수 없습니다" + +#: parser/parse_clause.c:3198 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "" +"\"%s\" 테이블에는 ON CONFLICT 기능을 사용할 수 없습니다. 이 테이블은 카탈로" +"그 테이블로 사용됩니다." + +#: parser/parse_clause.c:3341 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "%s 연산자는 유효한 순서 지정 연산자가 아님" + +#: parser/parse_clause.c:3343 +#, c-format +msgid "" +"Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "" +"순서 지정 연산자는 btree 연산자 패밀리의 \"<\" or \">\" 멤버여야 합니다." + +#: parser/parse_clause.c:3654 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "" + +#: parser/parse_clause.c:3660 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s " +"and offset type %s" +msgstr "" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "" + +#: parser/parse_clause.c:3668 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for " +"column type %s and offset type %s" +msgstr "" + +#: parser/parse_clause.c:3671 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "" + +#: parser/parse_coerce.c:1024 parser/parse_coerce.c:1062 +#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1095 +#: parser/parse_expr.c:2241 parser/parse_expr.c:2819 parser/parse_target.c:967 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "%s 자료형을 %s 자료형으로 형변환할 수 없습니다." + +#: parser/parse_coerce.c:1065 +#, c-format +msgid "Input has too few columns." +msgstr "입력에 너무 적은 칼럼을 지정했습니다." + +#: parser/parse_coerce.c:1083 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "%s 자료형을 %s 자료형으로 형변환할 수 없습니다 해당 열 %d." + +#: parser/parse_coerce.c:1098 +#, c-format +msgid "Input has too many columns." +msgstr "입력에 너무 많은 칼럼을 지정했습니다." + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1153 parser/parse_coerce.c:1201 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "%s의 인자는 %s 자료형이어야 함(%s 자료형이 아님)" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1164 parser/parse_coerce.c:1213 +#, c-format +msgid "argument of %s must not return a set" +msgstr "%s 의 인자는 set(집합) 을 return할수 없습니다." + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1353 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "%s 자료형 %s 와 %s 는 서로 매치되지 않습니다" + +#: parser/parse_coerce.c:1465 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "인자 자료형으로 %s 와 %s 는 서로 매치되지 않습니다" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1517 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%s 는 자료형 %s 자료형에서 %s 자료형으로 변환될 수 없습니다." + +#: parser/parse_coerce.c:1934 +#, c-format +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "\"anyelement\" 로 선언된 인자들이 모두 같지 않습니다" + +#: parser/parse_coerce.c:1954 +#, c-format +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "\"anyarray\" 로 선언된 인자들이 모두 같지 않습니다." + +#: parser/parse_coerce.c:1974 +#, c-format +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "\"anyarray\" 로 선언된 인자들이 모두 같지 않습니다." + +#: parser/parse_coerce.c:2008 parser/parse_coerce.c:2088 +#: utils/fmgr/funcapi.c:487 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "%s 이름으로 선언된 인자가 array가 아니고, %s 자료형입니다" + +#: parser/parse_coerce.c:2029 +#, c-format +msgid "arguments declared \"anycompatiblerange\" are not all alike" +msgstr "\"anycompatiblerange\" 로 선언된 인자들이 모두 같지 않습니다." + +#: parser/parse_coerce.c:2041 parser/parse_coerce.c:2122 +#: utils/fmgr/funcapi.c:501 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "%s 로 선언된 인자가 range 자료형이 아니고, %s 자료형입니다" + +#: parser/parse_coerce.c:2079 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "\"anyarray\" 인자의 각 요소 자료형을 확인할 수 없음" + +#: parser/parse_coerce.c:2105 parser/parse_coerce.c:2139 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "" +"%s 이름으로 선언된 인자가 %s 형으로 선언된 인자들과 일관성이 없습니다질 않습" +"니다" + +#: parser/parse_coerce.c:2163 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "입력에 %s 형이 있어 다변 형식을 확인할 수 없음" + +#: parser/parse_coerce.c:2177 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "anynonarray에 일치된 형식이 배열 형식임: %s" + +#: parser/parse_coerce.c:2187 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "anyenum에 일치된 형식이 열거 형식이 아님: %s" + +#: parser/parse_coerce.c:2218 parser/parse_coerce.c:2267 +#: parser/parse_coerce.c:2329 parser/parse_coerce.c:2365 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "%s 다형 자료형을 결정할 수 없음, 입력 자료형이 %s 임" + +#: parser/parse_coerce.c:2228 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "" +"%s 자료형이 anycompatiblerange인데, 해당 %s anycompatible 자료형을 찾을 수 없음" + +#: parser/parse_coerce.c:2242 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "일치한 anycompatiblenonarray 자료형이 배열 자료형임: %s" + +#: parser/parse_coerce.c:2433 +#, c-format +msgid "A result of type %s requires at least one input of type %s." +msgstr "%s 자료형의 결과가 적어도 하나의 %s 입력 자료형을 필요로 합니다." + +#: parser/parse_coerce.c:2445 +#, c-format +msgid "" +"A result of type %s requires at least one input of type anyelement, " +"anyarray, anynonarray, anyenum, or anyrange." +msgstr "" + +#: parser/parse_coerce.c:2457 +#, c-format +msgid "" +"A result of type %s requires at least one input of type anycompatible, " +"anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "" + +#: parser/parse_coerce.c:2487 +msgid "A result of type internal requires at least one input of type internal." +msgstr "" + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:981 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "" +"암묵적으로 선택된 \"%s\" 정렬 규칙와 \"%s\" 정렬 규칙이 매칭되지 않습니다" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:984 +#, c-format +msgid "" +"You can choose the collation by applying the COLLATE clause to one or both " +"expressions." +msgstr "한 쪽 또는 서로 COLLATE 절을 이용해 정렬 규칙을 지정하세요" + +#: parser/parse_collate.c:831 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "" +"명시적으로 지정한 \"%s\" 정렬규칙와 \"%s\" 정렬규칙이 매칭되지 않습니다" + +#: parser/parse_cte.c:42 +#, c-format +msgid "" +"recursive reference to query \"%s\" must not appear within its non-recursive " +"term" +msgstr "\"%s\" 쿼리에 대한 재귀 참조가 비재귀 구문 안에는 없어야 함" + +#: parser/parse_cte.c:44 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "\"%s\" 쿼리에 대한 재귀 참조가 하위 쿼리 내에 표시되지 않아야 함" + +#: parser/parse_cte.c:46 +#, c-format +msgid "" +"recursive reference to query \"%s\" must not appear within an outer join" +msgstr "\"%s\" 쿼리에 대한 재귀 참조가 outer join 구문 안에 없어야 함" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "\"%s\" 쿼리에 대한 재귀 참조가 INTERSECT 내에 표시되지 않아야 함" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "\"%s\" 쿼리에 대한 재귀 참조가 EXCEPT 내에 표시되지 않아야 함" + +#: parser/parse_cte.c:132 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "\"%s\" WITH 쿼리 이름이 여러 번 지정됨" + +#: parser/parse_cte.c:264 +#, c-format +msgid "" +"WITH clause containing a data-modifying statement must be at the top level" +msgstr "자료를 변경하는 구문이 있는 WITH 절은 최상위 수준에 있어야 합니다" + +#: parser/parse_cte.c:313 +#, c-format +msgid "" +"recursive query \"%s\" column %d has type %s in non-recursive term but type " +"%s overall" +msgstr "" +"\"%s\" 재귀 쿼리의 %d 번째 칼럼은 비재귀 조건에 %s 자료형을 포함하는데 전체적" +"으로는 %s 자료형임" + +#: parser/parse_cte.c:319 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "비재귀 조건의 출력을 올바른 형식으로 형변환하십시오." + +#: parser/parse_cte.c:324 +#, c-format +msgid "" +"recursive query \"%s\" column %d has collation \"%s\" in non-recursive term " +"but collation \"%s\" overall" +msgstr "" +"\"%s\" 재귀 쿼리의 %d 번째 칼럼은 비재귀 조건에 %s 자료형을 포함하는데 전체적" +"으로는 %s 자료형임" + +#: parser/parse_cte.c:328 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "" + +#: parser/parse_cte.c:418 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "" +"\"%s\" WITH 쿼리에는 %d개의 칼럼을 사용할 수 있는데 %d개의 칼럼이 지정됨" + +#: parser/parse_cte.c:598 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "WITH 항목 간의 상호 재귀가 구현되지 않음" + +#: parser/parse_cte.c:650 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "\"%s\" 재귀 쿼리에 자료 변경 구문이 포함될 수 없습니다." + +#: parser/parse_cte.c:658 +#, c-format +msgid "" +"recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] " +"recursive-term" +msgstr "\"%s\" 재귀 쿼리에 비재귀 조건 형태의 UNION [ALL] 재귀 조건이 없음" + +#: parser/parse_cte.c:702 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "재귀 쿼리의 ORDER BY가 구현되지 않음" + +#: parser/parse_cte.c:708 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "재귀 쿼리의 OFFSET이 구현되지 않음" + +#: parser/parse_cte.c:714 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "재귀 쿼리의 LIMIT가 구현되지 않음" + +#: parser/parse_cte.c:720 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "재귀 쿼리의 FOR UPDATE/SHARE가 구현되지 않음" + +#: parser/parse_cte.c:777 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "\"%s\" 쿼리에 대한 재귀 참조가 여러 번 표시되지 않아야 함" + +#: parser/parse_expr.c:349 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "이 영역에서는 DEFAULT를 사용할 수 없습니다" + +#: parser/parse_expr.c:402 parser/parse_relation.c:3506 +#: parser/parse_relation.c:3526 +#, c-format +msgid "column %s.%s does not exist" +msgstr "%s.%s 칼럼 없음" + +#: parser/parse_expr.c:414 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "\"%s\" 칼럼은 %s 자료형을 찾을 수 없음" + +#: parser/parse_expr.c:420 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "레코드 데이터 형식에서 \"%s\" 칼럼을 식별할 수 없음" + +#: parser/parse_expr.c:426 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "" +".%s 표현이 %s 자료형 사용되었는데, 이는 복소수형 (complex type)이 아닙니다" + +#: parser/parse_expr.c:457 parser/parse_target.c:729 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "\"*\"를 통한 칼럼 확장은 여기서 지원되지 않음" + +#: parser/parse_expr.c:578 +msgid "cannot use column reference in DEFAULT expression" +msgstr "DEFAULT 표현식에서는 열 reference를 사용할 수 없음" + +#: parser/parse_expr.c:581 +msgid "cannot use column reference in partition bound expression" +msgstr "파티션 범위 표현식에서 칼럼 참조를 사용할 수 없음" + +#: parser/parse_expr.c:850 parser/parse_relation.c:799 +#: parser/parse_relation.c:881 parser/parse_target.c:1207 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "칼럼 참조 \"%s\" 가 모호합니다." + +#: parser/parse_expr.c:906 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:199 parser/parse_param.c:298 +#, c-format +msgid "there is no parameter $%d" +msgstr "$%d 매개 변수가 없습니다" + +#: parser/parse_expr.c:1149 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULIF 절은 boolean 값을 얻기 위해서 = 연산자를 필요로 합니다" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1155 parser/parse_expr.c:3135 +#, c-format +msgid "%s must not return a set" +msgstr "%s에서는 집합을 반환할 수 없습니다." + +#: parser/parse_expr.c:1603 parser/parse_expr.c:1635 +#, c-format +msgid "number of columns does not match number of values" +msgstr "칼럼의 개수와, values의 개수가 틀립니다" + +#: parser/parse_expr.c:1649 +#, c-format +msgid "" +"source for a multiple-column UPDATE item must be a sub-SELECT or ROW() " +"expression" +msgstr "" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1843 parser/parse_expr.c:2330 parser/parse_func.c:2540 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "%s 안에서는 집합 반환 함수를 사용할 수 없음" + +#: parser/parse_expr.c:1904 +msgid "cannot use subquery in check constraint" +msgstr "체크 제약 조건에서는 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1908 +msgid "cannot use subquery in DEFAULT expression" +msgstr "DEFAULT 식에서는 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1911 +msgid "cannot use subquery in index expression" +msgstr "인덱스 식(expression)에 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1914 +msgid "cannot use subquery in index predicate" +msgstr "인덱스 술어(predicate)에 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1917 +msgid "cannot use subquery in transform expression" +msgstr "transform 식(expression)에 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1920 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "EXECUTE 매개 변수로 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1923 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "트리거 WHEN 조건절에서는 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in partition bound" +msgstr "파티션 범위 표현식에 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1929 +msgid "cannot use subquery in partition key expression" +msgstr "파티션 키 표현식에 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1932 +msgid "cannot use subquery in CALL argument" +msgstr "CALL 매개 변수로 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1935 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "COPY FROM WHERE 조건절에서는 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1938 +msgid "cannot use subquery in column generation expression" +msgstr "미리 계산된 칼럼 생성 표현식에 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1991 +#, c-format +msgid "subquery must return only one column" +msgstr "subquery는 오로지 한개의 열만을 돌려 주어야 합니다." + +#: parser/parse_expr.c:2075 +#, c-format +msgid "subquery has too many columns" +msgstr "subquery 에가 너무 많은 칼럼을 가집니다" + +#: parser/parse_expr.c:2080 +#, c-format +msgid "subquery has too few columns" +msgstr "subquery 에 명시된 열 수가 너무 적다" + +#: parser/parse_expr.c:2181 +#, c-format +msgid "cannot determine type of empty array" +msgstr "빈 배열의 자료형을 확인할 수 없음" + +#: parser/parse_expr.c:2182 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "원하는 형식으로 명시적으로 형변환하십시오(예: ARRAY[]::integer[])." + +#: parser/parse_expr.c:2196 +#, c-format +msgid "could not find element type for data type %s" +msgstr "%s 자료형의 요소 자료형을 찾을 수 없음" + +#: parser/parse_expr.c:2481 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "이름이 지정되지 않은 XML 속성 값은 열 참조여야 함" + +#: parser/parse_expr.c:2482 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "이름이 지정되지 않은 XML 요소 값은 열 참조여야 함" + +#: parser/parse_expr.c:2497 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "\"%s\" XML 속성 이름이 여러 번 표시됨" + +#: parser/parse_expr.c:2604 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "XMLSERIALIZE 결과를 %s 형으로 바꿀 수 없음" + +#: parser/parse_expr.c:2892 parser/parse_expr.c:3088 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "행 표현식에서 항목 수가 일치하지 않습니다" + +#: parser/parse_expr.c:2902 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "길이가 영(0)인 행들은 비교할 수 없습니다" + +#: parser/parse_expr.c:2927 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "" +"행 비교 연산자는 boolean형을 리턴해야합니다. %s 자료형을 사용할 수 없습니다" + +#: parser/parse_expr.c:2934 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "행 비교 연산자는 set을 리턴할 수 없습니다" + +#: parser/parse_expr.c:2993 parser/parse_expr.c:3034 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "%s 행 비교 연산자의 구문을 분석할 수 없습니다" + +#: parser/parse_expr.c:2995 +#, c-format +msgid "" +"Row comparison operators must be associated with btree operator families." +msgstr "로우 비교 연산자를 btree 연산자 패밀리와 연결해야 함" + +#: parser/parse_expr.c:3036 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "여러 가지 등식들이 성립할 수 있는 가능성이 있습니다" + +#: parser/parse_expr.c:3129 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "" +"IS DISTINCT FROM 절에서 boolean 값을 얻기 위해서 = 연산자를 필요로 합니다" + +#: parser/parse_expr.c:3448 parser/parse_expr.c:3466 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "연산자 우선순위 변경됨: %s 연산자 우선순위가 %s 연산보다 낮습니다" + +#: parser/parse_func.c:191 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "\"%s\" 이름의 매개 변수가 여러 번 사용 됨" + +#: parser/parse_func.c:202 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "" + +#: parser/parse_func.c:284 parser/parse_func.c:2243 +#, c-format +msgid "%s is not a procedure" +msgstr "%s 개체는 프로시져가 아님" + +#: parser/parse_func.c:288 +#, c-format +msgid "To call a function, use SELECT." +msgstr "" + +#: parser/parse_func.c:294 +#, c-format +msgid "%s is a procedure" +msgstr "%s 개체는 프로시져임" + +#: parser/parse_func.c:298 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "" + +#: parser/parse_func.c:312 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) 가 명시되어 있는데, 이 %s 함수는 집계 함수가 아닙니다." + +#: parser/parse_func.c:319 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT 가 명시되어 있는데, 그러나 이 %s 함수는 집계 함수가 아닙니다" + +#: parser/parse_func.c:325 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP 절이 명시되어 있는데, 이 %s 함수는 집계 함수가 아닙니다" + +#: parser/parse_func.c:331 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY 절이 명시되어 있는데, 이 %s 함수는 집계 함수가 아닙니다." + +#: parser/parse_func.c:337 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER 절이 명시되어 있는데, 이 %s 함수는 집계 함수가 아닙니다" + +#: parser/parse_func.c:343 +#, c-format +msgid "" +"OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER 절이 지정되었는데 %s 함수는 윈도우 함수 또는 집계 함수가 아님" + +#: parser/parse_func.c:381 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "순서가 있는 집계함수인 %s 때문에 WITHIN GROUP 절이 필요합니다" + +#: parser/parse_func.c:387 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "OVER 절에서 정렬된 세트 집계 %s 함수를 지원하지 않음" + +#: parser/parse_func.c:418 parser/parse_func.c:447 +#, c-format +msgid "" +"There is an ordered-set aggregate %s, but it requires %d direct arguments, " +"not %d." +msgstr "" + +#: parser/parse_func.c:472 +#, c-format +msgid "" +"To use the hypothetical-set aggregate %s, the number of hypothetical direct " +"arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "" + +#: parser/parse_func.c:486 +#, c-format +msgid "" +"There is an ordered-set aggregate %s, but it requires at least %d direct " +"arguments." +msgstr "" + +#: parser/parse_func.c:505 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "" +"%s 함수는 순사가 있는 세트 집계함수가 아니여서 WITHIN GROUP 절을 사용할 수 없" +"습니다" + +#: parser/parse_func.c:518 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "%s 윈도우 함수 호출에는 OVER 절이 필요함" + +#: parser/parse_func.c:525 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "%s 윈도우 함수는 WITHIN GROUP 절을 사용할 수 없음" + +#: parser/parse_func.c:554 +#, c-format +msgid "procedure %s is not unique" +msgstr "%s 프로시져는 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_func.c:557 +#, c-format +msgid "" +"Could not choose a best candidate procedure. You might need to add explicit " +"type casts." +msgstr "" +"가장 적당한 프로시져를 선택할 수 없습니다. 명시적 형변환자를 추가해야 할 수" +"도 있습니다." + +#: parser/parse_func.c:563 +#, c-format +msgid "function %s is not unique" +msgstr "함수 %s 는 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_func.c:566 +#, c-format +msgid "" +"Could not choose a best candidate function. You might need to add explicit " +"type casts." +msgstr "" +"제일 적당한 함수를 선택할 수 없습니다. 명시적 형변환자를 추가해야 할 수도 있" +"습니다." + +#: parser/parse_func.c:605 +#, c-format +msgid "" +"No aggregate function matches the given name and argument types. Perhaps you " +"misplaced ORDER BY; ORDER BY must appear after all regular arguments of the " +"aggregate." +msgstr "" +"지정된 이름 및 인자 자료형과 일치하는 집계 함수가 없습니다. ORDER BY 절을 바" +"른 위치에 쓰지 않은 것 같습니다. ORDER BY 절은 모든 집계용 인자들 맨 뒤에 있" +"어야 합니다." + +#: parser/parse_func.c:613 parser/parse_func.c:2286 +#, c-format +msgid "procedure %s does not exist" +msgstr "\"%s\" 프로시져 없음" + +#: parser/parse_func.c:616 +#, c-format +msgid "" +"No procedure matches the given name and argument types. You might need to " +"add explicit type casts." +msgstr "" +"지정된 이름 및 인자 형식과 일치하는 프로시져가 없습니다. 명시적 형변환자를 추" +"가해야 할 수도 있습니다." + +#: parser/parse_func.c:625 +#, c-format +msgid "" +"No function matches the given name and argument types. You might need to add " +"explicit type casts." +msgstr "" +"지정된 이름 및 인자 자료형과 일치하는 함수가 없습니다. 명시적 형변환자를 추가" +"해야 할 수도 있습니다." + +#: parser/parse_func.c:727 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "VARIADIC 매개 변수는 배열이어야 함" + +#: parser/parse_func.c:779 parser/parse_func.c:843 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*) 사용할 때는 이 함수가 매개 변수 없는 집계 함수여야 합니다" + +#: parser/parse_func.c:786 +#, c-format +msgid "aggregates cannot return sets" +msgstr "집계 함수는 세트를 반환할 수 없음" + +#: parser/parse_func.c:801 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "집계 함수는 인자 이름을 사용할 수 없음" + +#: parser/parse_func.c:833 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "윈도우 함수에 대해 DISTINCT가 구현되지 않음" + +#: parser/parse_func.c:853 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "윈도우 함수에 대해 집계용 ORDER BY가 구현되지 않음" + +#: parser/parse_func.c:862 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "비집계 윈도우 함수에 대해 FILTER가 구현되지 않음" + +#: parser/parse_func.c:871 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "윈도우 함수 호출에 집합 반환 함수 호출을 포함할 수 없음" + +#: parser/parse_func.c:879 +#, c-format +msgid "window functions cannot return sets" +msgstr "윈도우 함수는 세트를 반환할 수 없음" + +#: parser/parse_func.c:2124 parser/parse_func.c:2315 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "\"%s\" 함수를 찾을 수 없음" + +#: parser/parse_func.c:2138 parser/parse_func.c:2333 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "\"%s\" 함수 이름은 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_func.c:2140 parser/parse_func.c:2335 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "입력 인자를 다르게 해서 이 모호함을 피하세요." + +#: parser/parse_func.c:2184 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "프로시져는 %d개 이상의 인자를 사용할 수 없음" + +#: parser/parse_func.c:2233 +#, c-format +msgid "%s is not a function" +msgstr "%s 이름의 개체는 함수가 아닙니다" + +#: parser/parse_func.c:2253 +#, c-format +msgid "function %s is not an aggregate" +msgstr "%s 함수는 집계 함수가 아닙니다" + +#: parser/parse_func.c:2281 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "\"%s\" 이름의 프로시져를 찾을 수 없음" + +#: parser/parse_func.c:2295 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "\"%s\" 이름의 집계 함수를 찾을 수 없음" + +#: parser/parse_func.c:2300 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "%s(*) 집계 함수 없음" + +#: parser/parse_func.c:2305 +#, c-format +msgid "aggregate %s does not exist" +msgstr "%s 집계 함수 없음" + +#: parser/parse_func.c:2340 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "\"%s\" 프로시져는 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_func.c:2342 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "해당 프로시져의 입력 인자를 다르게 해서 이 모호함을 피하세요." + +#: parser/parse_func.c:2347 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "\"%s\" 집계 함수가 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_func.c:2349 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "해당 집계 함수의 입력 인자를 다르게 해서 이 모호함을 피하세요." + +#: parser/parse_func.c:2354 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "\"%s\" 루틴 이름은 유일성을 가지지 못합니다(not unique)" + +#: parser/parse_func.c:2356 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "해당 루틴의 입력 인자를 다르게 해서 이 모호함을 피하세요." + +#: parser/parse_func.c:2411 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "집합 반환 함수는 JOIN 조건에 사용할 수 없음" + +#: parser/parse_func.c:2432 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "집합 반환 함수는 정책 식에 사용할 수 없음" + +#: parser/parse_func.c:2448 +msgid "set-returning functions are not allowed in window definitions" +msgstr "집합 반환 함수는 윈도우 함수 정의에 사용할 수 없음" + +#: parser/parse_func.c:2486 +msgid "set-returning functions are not allowed in check constraints" +msgstr "집합 반환 함수는 check 제약조건에 사용할 수 없음" + +#: parser/parse_func.c:2490 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "집합 반환 함수는 DEFAULT 식에서 사용할 수 없음" + +#: parser/parse_func.c:2493 +msgid "set-returning functions are not allowed in index expressions" +msgstr "집합 반환 함수는 인덱스 식에서 사용할 수 없음" + +#: parser/parse_func.c:2496 +msgid "set-returning functions are not allowed in index predicates" +msgstr "집합 반환 함수는 함수 기반 인덱스에서 사용할 수 없음" + +#: parser/parse_func.c:2499 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "집합 반환 함수는 transform 식에서 사용할 수 없음" + +#: parser/parse_func.c:2502 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "집합 반환 함수는 EXECUTE 매개 변수 설정 값으로 사용할 수 없음" + +#: parser/parse_func.c:2505 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "집합 반환 함수는 트리거의 WHEN 조건절에서 사용할 수 없음" + +#: parser/parse_func.c:2508 +msgid "set-returning functions are not allowed in partition bound" +msgstr "집합 반환 함수는 파티션 범위 식에서 사용할 수 없음" + +#: parser/parse_func.c:2511 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "집합 반환 함수는 인덱스 식에서 사용할 수 없음" + +#: parser/parse_func.c:2514 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "집합 반환 함수는 CALL 명령의 인자로 사용할 수 없음" + +#: parser/parse_func.c:2517 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "집합 반환 함수는 COPY FROM WHERE 조건절에 사용할 수 없음" + +#: parser/parse_func.c:2520 +msgid "" +"set-returning functions are not allowed in column generation expressions" +msgstr "집합 반환 함수는 미리 계산된 칼럼의 생성식에 사용할 수 없음" + +#: parser/parse_node.c:86 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "대상 목록은 최대 %d 개의 항목을 지정할 수 있습니다" + +#: parser/parse_node.c:235 +#, c-format +msgid "cannot subscript type %s because it is not an array" +msgstr "" +"자료형 %s 는 배열이 아니기 때문에 배열 하위 스크립트를 기술할 수 없습니다." + +#: parser/parse_node.c:340 parser/parse_node.c:377 +#, c-format +msgid "array subscript must have type integer" +msgstr "배열 하위 스크립트는 반드시 정수형이어야 합니다." + +#: parser/parse_node.c:408 +#, c-format +msgid "array assignment requires type %s but expression is of type %s" +msgstr "배열할당은 자료형 %s 가 필요하지만, 현재 표현식이 %s 자료형입니다" + +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:521 +#: utils/adt/regproc.c:705 +#, c-format +msgid "operator does not exist: %s" +msgstr "연산자 없음: %s" + +#: parser/parse_oper.c:224 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "" +"명시적으로 순차연산자(ordering operator) 를 사용하던지, 또는 query 를 수정하" +"도록 하세요." + +#: parser/parse_oper.c:480 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "이 연산자는 실행시에 형 강제전화이 필요합니다: %s" + +#: parser/parse_oper.c:716 +#, c-format +msgid "operator is not unique: %s" +msgstr "연산자가 고유하지 않습니다: %s" + +#: parser/parse_oper.c:718 +#, c-format +msgid "" +"Could not choose a best candidate operator. You might need to add explicit " +"type casts." +msgstr "" +"가장 적당한 연산자를 선택할 수 없습니다. 명시적 형변환자를 추가해야 할 수도 " +"있습니다." + +#: parser/parse_oper.c:727 +#, c-format +msgid "" +"No operator matches the given name and argument type. You might need to add " +"an explicit type cast." +msgstr "" +"지정된 이름 및 인자 형식과 일치하는 연산자가 없습니다. 명시적 형변환자를 추가" +"해야 할 수도 있습니다." + +#: parser/parse_oper.c:729 +#, c-format +msgid "" +"No operator matches the given name and argument types. You might need to add " +"explicit type casts." +msgstr "" +"지정된 이름 및 인자 형식과 일치하는 연산자가 없습니다. 명시적 형변환자를 추가" +"해야 할 수도 있습니다." + +#: parser/parse_oper.c:790 parser/parse_oper.c:912 +#, c-format +msgid "operator is only a shell: %s" +msgstr "연산자는 셸일 뿐임: %s" + +#: parser/parse_oper.c:900 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (array) 는 우측에 배열이 있어야 합니다." + +#: parser/parse_oper.c:942 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (array) 는 boolean 을 얻기 위한 연산자가 필요합니다." + +#: parser/parse_oper.c:947 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (array) 는 set 을 return 하지 않는 연산자가 요구 됩니다." + +#: parser/parse_param.c:216 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "inconsistent types deduced for parameter $%d" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "테이블 참조 \"%s\" 가 명확하지 않습니다 (ambiguous)." + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "테이블 참조 %u 가 명확하지 않습니다 (ambiguous)." + +#: parser/parse_relation.c:444 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "테이블 이름 \"%s\" 가 한번 이상 명시되어 있습니다." + +#: parser/parse_relation.c:473 parser/parse_relation.c:3446 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "\"%s\" 테이블을 사용하는 FROM 절에 대한 참조가 잘못 되었습니다." + +#: parser/parse_relation.c:477 parser/parse_relation.c:3451 +#, c-format +msgid "" +"There is an entry for table \"%s\", but it cannot be referenced from this " +"part of the query." +msgstr "" +"\"%s\" 테이블에 대한 항목이 있지만 이 쿼리 부분에서 참조할 수 없습니다." + +#: parser/parse_relation.c:479 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "" + +#: parser/parse_relation.c:690 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "제약 조건에서 참조하는 \"%s\" 시스템 칼럼이 없음" + +#: parser/parse_relation.c:699 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "" +"\"%s\" 칼럼은 시스템 칼럼임. 미리 계산된 칼럼의 생성식에 사용할 수 없음" + +#: parser/parse_relation.c:1170 parser/parse_relation.c:1620 +#: parser/parse_relation.c:2262 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "" +"테이블 \"%s\" 에는 %d 개의 칼럼이 있는데, %d 개의 칼럼만 명시되었습니다." + +#: parser/parse_relation.c:1372 +#, c-format +msgid "" +"There is a WITH item named \"%s\", but it cannot be referenced from this " +"part of the query." +msgstr "\"%s\"(이)라는 WITH 항목이 있지만 이 쿼리 부분에서 참조할 수 없습니다." + +#: parser/parse_relation.c:1374 +#, c-format +msgid "" +"Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "" +"WITH RECURSIVE를 사용하거나 WITH 항목의 순서를 변경하여 정방향 참조를 제거하" +"십시오." + +#: parser/parse_relation.c:1747 +#, c-format +msgid "" +"a column definition list is only allowed for functions returning \"record\"" +msgstr "" +"열 정의 리스트 (column definition list) 는 오로지 \"record\" 를 리턴하는 함" +"수 내에서만 허용됩니다." + +#: parser/parse_relation.c:1756 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "" +"열 정의 리스트(column definition list)는 \"record\" 를 리턴하는 함수를 필요" +"로 합니다" + +#: parser/parse_relation.c:1845 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "" +"FROM 절 내의 함수 \"%s\" 에 지원되지 않는 return 자료형 %s 이 있습니다." + +#: parser/parse_relation.c:2054 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "" +"VALUES 뒤에 오는 \"%s\" 구문에는 %d개의 칼럼이 있는데, 지정한 칼럼은 %d개 입" +"니다" + +#: parser/parse_relation.c:2125 +#, c-format +msgid "joins can have at most %d columns" +msgstr "조인에는 최대 %d개의 칼럼을 포함할 수 있음" + +#: parser/parse_relation.c:2235 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "" + +#: parser/parse_relation.c:3221 parser/parse_relation.c:3231 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "%d번째 칼럼이 없습니다. 해당 릴레이션: \"%s\"" + +#: parser/parse_relation.c:3449 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "아 \"%s\" alias를 참조해야 할 것 같습니다." + +#: parser/parse_relation.c:3457 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "테이블 \"%s\"에 FROM 절이 빠져 있습니다." + +#: parser/parse_relation.c:3509 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "아마 \"%s.%s\" 칼럼을 참조하는 것 같습니다." + +#: parser/parse_relation.c:3511 +#, c-format +msgid "" +"There is a column named \"%s\" in table \"%s\", but it cannot be referenced " +"from this part of the query." +msgstr "" +"\"%s\" 이름의 칼럼이 \"%s\" 테이블에 있지만, 이 쿼리의 이 부분에서는 참조될 " +"수 없습니다." + +#: parser/parse_relation.c:3528 +#, c-format +msgid "" +"Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "아마 \"%s.%s\" 칼럼이나 \"%s.%s\" 칼럼을 참조하는 것 같습니다." + +#: parser/parse_target.c:478 parser/parse_target.c:792 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "시스템 열 \"%s\"에 할당할 수 없습니다." + +#: parser/parse_target.c:506 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "배열 요소를 DEFAULT 로 설정할 수 없습니다." + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "하위필드를 DEFAULT로 설정할 수 없습니다." + +#: parser/parse_target.c:584 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "열 \"%s\"은(는) %s 자료형인데 표현식은 %s 자료형입니다." + +#: parser/parse_target.c:776 +#, c-format +msgid "" +"cannot assign to field \"%s\" of column \"%s\" because its type %s is not a " +"composite type" +msgstr "" +"\"%s\" 필드 (대상 열 \"%s\")를 지정할 수 없음, %s 자료형은 복합자료형이 아니" +"기 때문" + +#: parser/parse_target.c:785 +#, c-format +msgid "" +"cannot assign to field \"%s\" of column \"%s\" because there is no such " +"column in data type %s" +msgstr "" +"\"%s\" 필드 (대상 열 \"%s\")를 지정할 수 없음, %s 자료형에서 그런 칼럼을 찾" +"을 수 없음" + +#: parser/parse_target.c:864 +#, c-format +msgid "" +"array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "" +"\"%s\" 열에 사용된 자료형은 %s 가 필요하지만, 현재 표현식이 %s 자료형입니다" + +#: parser/parse_target.c:874 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "하위필드 \"%s\" 는 %s 자료형인데 표현식은 %s 자료형입니다." + +#: parser/parse_target.c:1295 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "테이블이 명시되지 않은 SELECT * 구문은 유효하지 않습니다." + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "" +"적절하지 않은 %%TYPE reference 입니다 (dotted name 이 너무 적습니다): %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "" +"적절하지 않은 %%TYPE reference 입니다 (dotted name 이 너무 많습니다): %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "ype reference %s 가 %s 로 변환되었습니다." + +#: parser/parse_type.c:278 parser/parse_type.c:857 utils/cache/typcache.c:383 +#: utils/cache/typcache.c:437 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "자료형 \"%s\" 는 오로지 shell 에만 있습니다. " + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "\"%s\" 형식에는 형식 한정자를 사용할 수 없음" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "자료형 한정자는 단순 상수 또는 식별자여야 함" + +#: parser/parse_type.c:721 parser/parse_type.c:820 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "\"%s\" 자료형 이름은 유효하지 않은 자료형입니다." + +#: parser/parse_utilcmd.c:264 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "상속 하위 테이블로 파티션된 테이블을 만들 수 없음" + +#: parser/parse_utilcmd.c:428 +#, c-format +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "" +"%s 명령으로 \"%s\" 시퀀스가 자동으로 만들어짐 (\"%s.%s\" serial 열 때문)" + +#: parser/parse_utilcmd.c:559 +#, c-format +msgid "array of serial is not implemented" +msgstr "serial 배열이 구현되지 않음" + +#: parser/parse_utilcmd.c:637 parser/parse_utilcmd.c:649 +#, c-format +msgid "" +"conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "NULL/NOT NULL 선언이 서로 충돌합니다 : column \"%s\" of table \"%s\"" + +#: parser/parse_utilcmd.c:661 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "\"%s\" 칼럼(\"%s\" 테이블)에 대해 여러 개의 기본 값이 지정됨" + +#: parser/parse_utilcmd.c:678 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "" +"식별 칼럼은 타입드 테이블(typed table - 자료형으로써 테이블)에서는 쓸 수 없음" + +#: parser/parse_utilcmd.c:682 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "식별 칼럼은 파티션된 테이블에서는 사용할 수 없음" + +#: parser/parse_utilcmd.c:691 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "\"%s\" 칼럼(\"%s\" 테이블)에 대해 여러 개의 식별자 지정이 사용되었음" + +#: parser/parse_utilcmd.c:711 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "" +"미리 계산된 칼럼은 타입드 테이블(typed table - 자료형으로써 테이블)에서는 쓸 " +"수 없음" + +#: parser/parse_utilcmd.c:715 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "미리 계산된 칼럼은 파티션된 테이블에서는 사용할 수 없음" + +#: parser/parse_utilcmd.c:720 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "\"%s\" 칼럼(\"%s\" 테이블)에 대해 여러 개의 생성식이 지정됨" + +#: parser/parse_utilcmd.c:738 parser/parse_utilcmd.c:853 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "기본키 제약 조건을 외부 테이블에서는 사용할 수 없음" + +#: parser/parse_utilcmd.c:747 parser/parse_utilcmd.c:863 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "유니크 제약 조건은 외부 테이블에서는 사용할 수 없음" + +#: parser/parse_utilcmd.c:792 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "\"%s\" 칼럼(\"%s\" 테이블)에 대해 default와 식별자 정의가 함께 있음" + +#: parser/parse_utilcmd.c:800 +#, c-format +msgid "" +"both default and generation expression specified for column \"%s\" of table " +"\"%s\"" +msgstr "\"%s\" 칼럼(해당 테이블 \"%s\")에 대해 default 정의와 미리 계산된 표현식이 함께 있음" + +#: parser/parse_utilcmd.c:808 +#, c-format +msgid "" +"both identity and generation expression specified for column \"%s\" of table " +"\"%s\"" +msgstr "\"%s\" 칼럼(해당 테이블 \"%s\")에 대해 identity 정의와 미리 계산된 표현식이 함께 있음" + +#: parser/parse_utilcmd.c:873 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "제외 제약 조건은 외부 테이블에서는 사용할 수 없음" + +#: parser/parse_utilcmd.c:879 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "제외 제약 조건은 파티션된 테이블에서는 사용할 수 없음" + +#: parser/parse_utilcmd.c:944 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "외부 테이블을 만들 때는 LIKE 옵션을 쓸 수 없음" + +#: parser/parse_utilcmd.c:1704 parser/parse_utilcmd.c:1813 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "" + +#: parser/parse_utilcmd.c:2163 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "" + +#: parser/parse_utilcmd.c:2183 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "" + +#: parser/parse_utilcmd.c:2198 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "\"%s\" 인덱스는 사용가능 상태가 아님" + +#: parser/parse_utilcmd.c:2204 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "\"%s\" 개체는 유니크 인덱스가 아닙니다" + +#: parser/parse_utilcmd.c:2205 parser/parse_utilcmd.c:2212 +#: parser/parse_utilcmd.c:2219 parser/parse_utilcmd.c:2296 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "" + +#: parser/parse_utilcmd.c:2211 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "\"%s\" 인덱스에 표현식이 포함되어 있음" + +#: parser/parse_utilcmd.c:2218 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "\"%s\" 개체는 부분 인덱스임" + +#: parser/parse_utilcmd.c:2230 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\" 개체는 지연가능한 인덱스임" + +#: parser/parse_utilcmd.c:2231 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "" + +#: parser/parse_utilcmd.c:2295 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "\"%s\" 인덱스 %d 번째 칼럼의 기본 정렬 방법이 없음" + +#: parser/parse_utilcmd.c:2452 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "기본키 제약 조건에서 \"%s\" 칼럼이 두 번 지정되었습니다" + +#: parser/parse_utilcmd.c:2458 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "고유 제약 조건에서 \"%s\" 칼럼이 두 번 지정되었습니다" + +#: parser/parse_utilcmd.c:2811 +#, c-format +msgid "" +"index expressions and predicates can refer only to the table being indexed" +msgstr "인덱스 식 및 술어는 인덱싱되는 테이블만 참조할 수 있음" + +#: parser/parse_utilcmd.c:2857 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "구체화된 뷰에서의 룰은 지원하지 않음" + +#: parser/parse_utilcmd.c:2920 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "룰에서 지정한 WHERE 조건에 다른 릴레이션에 대한 참조를 포함할 수 없음" + +#: parser/parse_utilcmd.c:2994 +#, c-format +msgid "" +"rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE " +"actions" +msgstr "" +"룰에서 지정한 WHERE 조건이 있는 규칙에는 SELECT, INSERT, UPDATE 또는 DELETE " +"작업만 포함할 수 있음" + +#: parser/parse_utilcmd.c:3012 parser/parse_utilcmd.c:3113 +#: rewrite/rewriteHandler.c:502 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "conditional UNION/INTERSECT/EXCEPT 구문은 구현되어 있지 않다" + +#: parser/parse_utilcmd.c:3030 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "ON SELECT 룰은 OLD를 사용할 수 없음" + +#: parser/parse_utilcmd.c:3034 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "ON SELECT 룰은 NEW를 사용할 수 없음" + +#: parser/parse_utilcmd.c:3043 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "ON INSERT 룰은 OLD를 사용할 수 없음" + +#: parser/parse_utilcmd.c:3049 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "ON DELETE 룰은 NEW를 사용할 수 없음" + +#: parser/parse_utilcmd.c:3077 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "" + +#: parser/parse_utilcmd.c:3084 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "" + +#: parser/parse_utilcmd.c:3542 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "DEFERABLE 절이 잘못 놓여져 있습니다" + +#: parser/parse_utilcmd.c:3547 parser/parse_utilcmd.c:3562 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "여러 개의 DEFERRABLE/NOT DEFERRABLE절은 사용할 수 없습니다" + +#: parser/parse_utilcmd.c:3557 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "NOT DEFERABLE 절이 잘못 놓여 있습니다" + +#: parser/parse_utilcmd.c:3570 parser/parse_utilcmd.c:3596 gram.y:5593 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "INITIALLY DEFERRED 로 선언된 조건문은 반드시 DEFERABLE 여야만 한다" + +#: parser/parse_utilcmd.c:3578 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "INITIALLY DEFERRED 절이 잘못 놓여 있습니다" + +#: parser/parse_utilcmd.c:3583 parser/parse_utilcmd.c:3609 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "여러 개의 INITIALLY IMMEDIATE/DEFERRED 절은 허용되지 않습니다" + +#: parser/parse_utilcmd.c:3604 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "INITIALLY IMMEDIATE 절이 잘못 놓여 있습니다" + +#: parser/parse_utilcmd.c:3795 +#, c-format +msgid "" +"CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE 구문에 명시된 schema (%s) 가 생성된 (%s) 의 것과 다릅니다" + +#: parser/parse_utilcmd.c:3830 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "\"%s\" 개체는 파티션된 테이블이 아님" + +#: parser/parse_utilcmd.c:3837 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "\"%s\" 테이블은 파티션되어 있지 않음" + +#: parser/parse_utilcmd.c:3844 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "\"%s\" 인덱스는 파티션 된 인덱스가 아님" + +#: parser/parse_utilcmd.c:3884 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "해시 파티션된 테이블은 기본 파티션을 가질 수 없음" + +#: parser/parse_utilcmd.c:3901 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "해시 파티션용 범위 명세가 잘못됨" + +#: parser/parse_utilcmd.c:3907 partitioning/partbounds.c:4691 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "" + +#: parser/parse_utilcmd.c:3914 partitioning/partbounds.c:4699 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "해시 파티션용 나머지 처리기는 modulus 보다 작아야 함" + +#: parser/parse_utilcmd.c:3927 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "list 파티션을 위한 범위 설정이 잘못됨" + +#: parser/parse_utilcmd.c:3980 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "range 파티션을 위한 범위 설정이 잘못됨" + +#: parser/parse_utilcmd.c:3986 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM에는 파티션 칼럼 당 딱 하나의 값만 지정해야 함" + +#: parser/parse_utilcmd.c:3990 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO에는 파티션 칼럼 당 딱 하나의 값만 지정해야 함" + +#: parser/parse_utilcmd.c:4104 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "range 범위에는 NULL 값을 사용할 수 없음" + +#: parser/parse_utilcmd.c:4153 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "" + +#: parser/parse_utilcmd.c:4160 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "" + +#: parser/parse_utilcmd.c:4202 +#, c-format +msgid "" +"could not determine which collation to use for partition bound expression" +msgstr "파티션 범위 표현식에 쓸 문자 정렬 규칙을 결정할 수 없습니다" + +#: parser/parse_utilcmd.c:4219 +#, c-format +msgid "" +"collation of partition bound value for column \"%s\" does not match " +"partition key collation \"%s\"" +msgstr "" +"\"%s\" 칼럼의 파티션 범위값 정렬 규칙과 파티션 키 정렬 규칙(\"%s\")이 다름" + +#: parser/parse_utilcmd.c:4236 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "지정된 값은 %s 형으로 형변환 할 수 없음, 해당 칼럼: \"%s\"" + +#: parser/parser.c:228 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "" + +#: parser/parser.c:233 +msgid "invalid Unicode escape character" +msgstr "잘못된 유니코드 이스케이프 문자" + +#: parser/parser.c:302 scan.l:1329 +#, c-format +msgid "invalid Unicode escape value" +msgstr "잘못된 유니코드 이스케이프 값" + +#: parser/parser.c:449 scan.l:677 +#, c-format +msgid "invalid Unicode escape" +msgstr "잘못된 유니코드 이스케이프 값" + +#: parser/parser.c:450 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "유니코드 이스케이프는 \\XXXX 또는 \\+XXXXXX 형태여야 합니다." + +#: parser/parser.c:478 scan.l:638 scan.l:654 scan.l:670 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "잘못된 유니코드 대리 쌍" + +#: parser/scansup.c:203 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%s\"" +msgstr "\"%s\" 식별자는 \"%s\"(으)로 잘림" + +#: partitioning/partbounds.c:2831 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "\"%s\" 파티션이 \"%s\" 기본 파티션과 겹칩니다." + +#: partitioning/partbounds.c:2890 +#, c-format +msgid "" +"every hash partition modulus must be a factor of the next larger modulus" +msgstr "" + +#: partitioning/partbounds.c:2986 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "" + +#: partitioning/partbounds.c:2988 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "하한값(%s)은 상한값(%s)과 같거나 커야 합니다" + +#: partitioning/partbounds.c:3085 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "\"%s\" 파티션이 \"%s\" 파티션과 겹칩니다." + +#: partitioning/partbounds.c:3202 +#, c-format +msgid "" +"skipped scanning foreign table \"%s\" which is a partition of default " +"partition \"%s\"" +msgstr "" +"\"%s\" 외부 테이블 탐색은 생략함, 이 테이블은 \"%s\" 기본 파티션 테이블의 파" +"티션이기 때문" + +#: partitioning/partbounds.c:4695 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "" + +#: partitioning/partbounds.c:4722 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" 개체는 해시 파티션된 테이블이 아님" + +#: partitioning/partbounds.c:4733 partitioning/partbounds.c:4850 +#, c-format +msgid "" +"number of partitioning columns (%d) does not match number of partition keys " +"provided (%d)" +msgstr "파티션 칼럼 수: %d, 제공된 파티션 키 수: %d 서로 다름" + +#: partitioning/partbounds.c:4755 partitioning/partbounds.c:4787 +#, c-format +msgid "" +"column %d of the partition key has type \"%s\", but supplied value is of " +"type \"%s\"" +msgstr "" + +#: port/pg_sema.c:209 port/pg_shmem.c:640 port/posix_sema.c:209 +#: port/sysv_sema.c:327 port/sysv_shmem.c:640 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "\"%s\" 데이터 디렉터리 상태를 파악할 수 없음: %m" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "공유 메모리 세그먼트를 만들 수 없음: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "shmget(키=%lu, 크기=%zu, 0%o) 시스템 콜 실패" + +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory " +"segment exceeded your kernel's SHMMAX parameter, or possibly that it is less " +"than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory " +"configuration." +msgstr "" +"이 오류를 일반적으로 PostgreSQL에서 사용할 공유 메모리 크기가 커널의 SHMMAX " +"값보다 크거나, SHMMIN 값보다 적은 경우 발생합니다.\n" +"공유 메모리 설정에 대한 보다 자세한 내용은 PostgreSQL 문서를 참조하십시오." + +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory " +"segment exceeded your kernel's SHMALL parameter. You might need to " +"reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory " +"configuration." +msgstr "" +"이 오류를 일반적으로 PostgreSQL에서 사용할 공유 크기가 커널의 SHMALL 값보다 " +"큰 경우 발생합니다. 커널 환경 변수인 SHMALL 값을 좀 더 크게 설정하세요.\n" +"공유 메모리 설정에 대한 보다 자세한 내용은 PostgreSQL 문서를 참조하십시오." + +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs " +"either if all available shared memory IDs have been taken, in which case you " +"need to raise the SHMMNI parameter in your kernel, or because the system's " +"overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory " +"configuration." +msgstr "" +"이 오류는 서버를 실행하는데 필요한 디스크 공간이 부족해서 발생한 것이 아닙니" +"다. 이 오류는 서버가 사용할 공유 메모리 ID를 선점하지 못했을 때 발생합니" +"다. 커널 환경 설정값인 SHMMNI 값을 늘리거나, 시스템의 가용 공유 메모리량을 " +"확보하세요.\n" +"공유 메모리 설정에 대한 보다 자세한 내용은 PostgreSQL 문서를 참조하십시오." + +#: port/pg_shmem.c:578 port/sysv_shmem.c:578 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "가용 공유 메모리 확보 실패: %m" + +#: port/pg_shmem.c:580 port/sysv_shmem.c:580 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory " +"segment exceeded available memory, swap space, or huge pages. To reduce the " +"request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, " +"perhaps by reducing shared_buffers or max_connections." +msgstr "" +"이 오류는 일반적으로 PostgreSQL에서 사용할 공유 메모리를 확보하지 못 했을 때 " +"발생합니다(물리 메모리, 스왑, huge page). 현재 요구 크기(%zu 바이트)를 좀 줄" +"여 보십시오. 줄이는 방법은, shared_buffers 값을 줄이거나 max_connections 값" +"을 줄여 보십시오." + +#: port/pg_shmem.c:648 port/sysv_shmem.c:648 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "huge page 기능은 이 플랫폼에서 지원되지 않음" + +#: port/pg_shmem.c:709 port/sysv_shmem.c:709 utils/init/miscinit.c:1137 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "미리 확보된 공유 메모리 영역 (%lu 키, %lu ID)이 여전히 사용중입니다" + +#: port/pg_shmem.c:712 port/sysv_shmem.c:712 utils/init/miscinit.c:1139 +#, c-format +msgid "" +"Terminate any old server processes associated with data directory \"%s\"." +msgstr "" + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "세마포어를 만들 수 없음: %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "semget(%lu, %d, 0%o) 호출에 의한 시스템 콜 실패" + +#: port/sysv_sema.c:129 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs " +"when either the system limit for the maximum number of semaphore sets " +"(SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be " +"exceeded. You need to raise the respective kernel parameter. " +"Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its " +"max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring " +"your system for PostgreSQL." +msgstr "" +"이 오류는 서버를 실행하는데 필요한 디스크 공간이 부족해서 발생한 것이 아닙니" +"다.\n" +"이 오류는 시스템에서 지정한 최소 세마포어 수(SEMMNI)가 너무 크거나, 최대 세마" +"포어 수(SEMMNS)가 너무 적어서 서버를 실행할 수 없을 때 발생합니다. 이에 따" +"라, 정상적으로 서버가 실행되려면, 시스템 값들을 조정할 필요가 있습니다. 아니" +"면, 다른 방법으로, PostgreSQL의 환경 설정에서 max_connections 값을 줄여서 세" +"마포어 사용 수를 줄여보십시오.\n" +"보다 자세한 내용은 PostgreSQL 관리자 메뉴얼을 참조 하십시오." + +#: port/sysv_sema.c:159 +#, c-format +msgid "" +"You possibly need to raise your kernel's SEMVMX value to be at least %d. " +"Look into the PostgreSQL documentation for details." +msgstr "" +"커널의 SEMVMX 값을 적어도 %d 정도로 늘려야할 필요가 있는 것 같습니다. 자세" +"한 것은 PostgreSQL 문서를 참조하세요." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "" +"could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "\"%s\" 장애 덤프 파일을 쓰기 위해 열 수 없음: 오류 번호 %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "\"%s\" 장애 덤프 파일을 만들었습니다.\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "\"%s\" 장애 덤프 파일을 쓰기 실패: 오류 번호 %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "%d pid를 위한 시그널 리슨너 파이프를 만들 수 없음: 오류 번호 %lu" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "신호 수신기 파이프를 만들 수 없음: 오류 번호 %lu, 다시 시작 중\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "세마포어를 만들 수 없음: 오류 번호 %lu" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "세마포어를 잠글 수 없음: 오류 번호 %lu" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "세마포어 잠금을 해제할 수 없음: 오류 번호 %lu" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "세마포어 잠금 시도 실패: 오류 번호 %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "메모리 사용자 권리에서 페이지 잠금 활성화 못함: 오류 번호 %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "실패한 시스템 호출 %s" + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "메모리 사용자 권리에서 페이지 잠금 활성화 못함" + +#: port/win32_shmem.c:176 +#, c-format +msgid "" +"Assign Lock Pages in Memory user right to the Windows user account which " +"runs PostgreSQL." +msgstr "" + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "프로세스가 큰 페이지를 지원하지 않음" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "큰 페이지 비활성화" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "공유 메모리 세그먼트를 만들 수 없음: 오류 번호 %lu" + +#: port/win32_shmem.c:303 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "실패한 시스템 호출은 CreateFileMapping(크기=%zu, 이름=%s)입니다." + +#: port/win32_shmem.c:328 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "기존 공유 메모리 블록이 여전히 사용되고 있음" + +#: port/win32_shmem.c:329 +#, c-format +msgid "" +"Check if there are any old server processes still running, and terminate " +"them." +msgstr "실행 중인 이전 서버 프로세스가 있는지 확인하고 종료하십시오." + +#: port/win32_shmem.c:339 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "실패한 시스템 호출은 DuplicateHandle입니다." + +#: port/win32_shmem.c:357 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "실패한 시스템 호출은 MapViewOfFileEx입니다." + +#: postmaster/autovacuum.c:406 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "autovacuum 실행기 프로세스를 실행할 수 없음: %m" + +#: postmaster/autovacuum.c:442 +#, c-format +msgid "autovacuum launcher started" +msgstr "autovacuum 실행기가 시작됨" + +#: postmaster/autovacuum.c:839 +#, c-format +msgid "autovacuum launcher shutting down" +msgstr "autovacuum 실행기를 종료하는 중" + +#: postmaster/autovacuum.c:1477 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "autovacuum 작업자 프로세스를 실행할 수 없음: %m" + +#: postmaster/autovacuum.c:1686 +#, c-format +msgid "autovacuum: processing database \"%s\"" +msgstr "autovacuum: \"%s\" 데이터베이스 처리 중" + +#: postmaster/autovacuum.c:2256 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "" +"autovacuum: 더 이상 사용하지 않는 \"%s.%s.%s\" 임시 테이블을 삭제하는 중" + +#: postmaster/autovacuum.c:2485 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" 테이블 대상으로 자동 vacuum 작업 함" + +#: postmaster/autovacuum.c:2488 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" 테이블 자동 분석" + +#: postmaster/autovacuum.c:2681 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" 릴레이션 작업 항목 작업 중" + +#: postmaster/autovacuum.c:3285 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "서버 설정 정보가 잘못되어 자동 청소 작업이 실행되지 못했습니다." + +#: postmaster/autovacuum.c:3286 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "\"track_counts\" 옵션을 사용하십시오." + +#: postmaster/bgworker.c:394 postmaster/bgworker.c:841 +#, c-format +msgid "registering background worker \"%s\"" +msgstr "" + +#: postmaster/bgworker.c:426 +#, c-format +msgid "unregistering background worker \"%s\"" +msgstr "" + +#: postmaster/bgworker.c:591 +#, c-format +msgid "" +"background worker \"%s\": must attach to shared memory in order to request a " +"database connection" +msgstr "" + +#: postmaster/bgworker.c:600 +#, c-format +msgid "" +"background worker \"%s\": cannot request database access if starting at " +"postmaster start" +msgstr "" + +#: postmaster/bgworker.c:614 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "\"%s\" 백그라운드 작업자: 잘못된 재실행 간격" + +#: postmaster/bgworker.c:629 +#, c-format +msgid "" +"background worker \"%s\": parallel workers may not be configured for restart" +msgstr "\"%s\" 백그라운드 작업자: 이 병렬 작업자는 재실행 설정이 없음" + +#: postmaster/bgworker.c:653 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "관리자 명령에 의해 \"%s\" 백그라운드 작업자를 종료합니다." + +#: postmaster/bgworker.c:849 +#, c-format +msgid "" +"background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "" +"\"%s\" 백그라운드 작업자: 먼저 shared_preload_libraries 설정값으로 등록되어" +"야 합니다." + +#: postmaster/bgworker.c:861 +#, c-format +msgid "" +"background worker \"%s\": only dynamic background workers can request " +"notification" +msgstr "" +"\"%s\" 백그라운드 작업자: 동적 백그라운드 작업자만 알림을 요청할 수 있음" + +#: postmaster/bgworker.c:876 +#, c-format +msgid "too many background workers" +msgstr "백그라운드 작업자가 너무 많음" + +#: postmaster/bgworker.c:877 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "" +"Up to %d background workers can be registered with the current settings." +msgstr[0] "현재 설정으로는 %d개의 백그라운드 작업자를 사용할 수 있습니다." + +#: postmaster/bgworker.c:881 +#, c-format +msgid "" +"Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "\"max_worker_processes\" 환경 매개 변수 값을 좀 느려보십시오." + +#: postmaster/checkpointer.c:418 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "체크포인트가 너무 자주 발생함 (%d초 간격)" + +#: postmaster/checkpointer.c:422 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "\"max_wal_size\" 환경 매개 변수 값을 좀 느려보십시오." + +#: postmaster/checkpointer.c:1032 +#, c-format +msgid "checkpoint request failed" +msgstr "체크포인트 요청 실패" + +#: postmaster/checkpointer.c:1033 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "더 자세한 것은 서버 로그 파일을 살펴보십시오." + +#: postmaster/checkpointer.c:1217 +#, c-format +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "" + +#: postmaster/pgarch.c:155 +#, c-format +msgid "could not fork archiver: %m" +msgstr "archiver 할당(fork) 실패: %m" + +#: postmaster/pgarch.c:425 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode가 사용 설정되었는데 archive_command가 설정되지 않음" + +#: postmaster/pgarch.c:447 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "필요 없는 \"%s\" 아카이브 상태 파일이 삭제됨" + +#: postmaster/pgarch.c:457 +#, c-format +msgid "" +"removal of orphan archive status file \"%s\" failed too many times, will try " +"again later" +msgstr "" +"필요 없는 \"%s\" 아카이브 상태 파일 삭제 작업이 계속 실패하고 있습니다. 다음" +"에 또 시도할 것입니다." + +#: postmaster/pgarch.c:493 +#, c-format +msgid "" +"archiving write-ahead log file \"%s\" failed too many times, will try again " +"later" +msgstr "" +"\"%s\" 트랜잭션 로그 파일 아카이브 작업이 계속 실패하고 있습니다. 다음에 또 " +"시도할 것입니다." + +#: postmaster/pgarch.c:594 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "아카이브 명령 실패, 종료 코드: %d" + +#: postmaster/pgarch.c:596 postmaster/pgarch.c:606 postmaster/pgarch.c:612 +#: postmaster/pgarch.c:621 +#, c-format +msgid "The failed archive command was: %s" +msgstr "실패한 아카이브 명령: %s" + +#: postmaster/pgarch.c:603 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "0x%X 예외로 인해 아카이브 명령이 종료됨" + +#: postmaster/pgarch.c:605 postmaster/postmaster.c:3742 +#, c-format +msgid "" +"See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "16진수 값에 대한 설명은 C 포함 파일 \"ntstatus.h\"를 참조하십시오." + +#: postmaster/pgarch.c:610 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "%d번 시그널로 인해 아카이브 명령이 종료됨: %s" + +#: postmaster/pgarch.c:619 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "아카이브 명령이 인식할 수 없는 %d 상태로 종료됨" + +#: postmaster/pgstat.c:419 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "\"localhost\" 이름의 호스트 IP를 구할 수 없습니다: %s" + +#: postmaster/pgstat.c:442 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "통계 수집기에서 사용할 다른 주소를 찾습니다" + +#: postmaster/pgstat.c:451 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "통계 수집기에서 사용할 소켓을 만들 수 없습니다: %m" + +#: postmaster/pgstat.c:463 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "통계 수집기에서 사용할 소켓과 bind할 수 없습니다: %m" + +#: postmaster/pgstat.c:474 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "통계 수집기에서 사용할 소켓의 주소를 구할 수 없습니다: %m" + +#: postmaster/pgstat.c:490 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "통계 수집기에서 사용할 소켓에 연결할 수 없습니다: %m" + +#: postmaster/pgstat.c:511 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "통계 수집기에서 사용할 소켓으로 테스트 메시지를 보낼 수 없습니다: %m" + +#: postmaster/pgstat.c:537 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "통계 수집기에서 select() 작업 오류: %m" + +#: postmaster/pgstat.c:552 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "통계 수집기에서 사용할 소켓으로 테스트 메시지를 처리할 수 없습니다" + +#: postmaster/pgstat.c:567 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "통계 수집기에서 사용할 소켓으로 테스트 메시지를 받을 수 없습니다: %m" + +#: postmaster/pgstat.c:577 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "통계 수집기에서 사용할 소켓으로 잘못된 테스트 메시지가 전달 되었습니다" + +#: postmaster/pgstat.c:600 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "" +"통계 수집기에서 사용하는 소켓 모드를 nonblocking 모드로 지정할 수 없습니다: " +"%m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "현재 작업 소켓의 원할한 소통을 위해 통계 수집기 기능을 중지합니다" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "통계 수집기를 fork할 수 없습니다: %m" + +#: postmaster/pgstat.c:1376 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "알 수 없는 리셋 타겟: \"%s\"" + +#: postmaster/pgstat.c:1377 +#, c-format +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "사용 가능한 타겟은 \"archiver\" 또는 \"bgwriter\"" + +#: postmaster/pgstat.c:4561 +#, c-format +msgid "could not read statistics message: %m" +msgstr "통계 메시지를 읽을 수 없음: %m" + +#: postmaster/pgstat.c:4883 postmaster/pgstat.c:5046 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "\"%s\" 임시 통계 파일을 열 수 없음: %m" + +#: postmaster/pgstat.c:4956 postmaster/pgstat.c:5091 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "\"%s\" 임시 통계 파일에 쓰기 실패: %m" + +#: postmaster/pgstat.c:4965 postmaster/pgstat.c:5100 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "\"%s\" 임시 통계 파일을 닫을 수 없습니다: %m" + +#: postmaster/pgstat.c:4973 postmaster/pgstat.c:5108 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "\"%s\" 임시 통계 파일 이름을 \"%s\" (으)로 바꿀 수 없습니다: %m" + +#: postmaster/pgstat.c:5205 postmaster/pgstat.c:5422 postmaster/pgstat.c:5576 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "\"%s\" 통계 파일을 열 수 없음: %m" + +#: postmaster/pgstat.c:5217 postmaster/pgstat.c:5227 postmaster/pgstat.c:5248 +#: postmaster/pgstat.c:5259 postmaster/pgstat.c:5281 postmaster/pgstat.c:5296 +#: postmaster/pgstat.c:5359 postmaster/pgstat.c:5434 postmaster/pgstat.c:5454 +#: postmaster/pgstat.c:5472 postmaster/pgstat.c:5488 postmaster/pgstat.c:5506 +#: postmaster/pgstat.c:5522 postmaster/pgstat.c:5588 postmaster/pgstat.c:5600 +#: postmaster/pgstat.c:5612 postmaster/pgstat.c:5623 postmaster/pgstat.c:5648 +#: postmaster/pgstat.c:5670 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "\"%s\" 통계 파일이 손상되었음" + +#: postmaster/pgstat.c:5799 +#, c-format +msgid "" +"using stale statistics instead of current ones because stats collector is " +"not responding" +msgstr "" +"현재 통계 수집기가 반응하지 않아 부정확한 통계정보가 사용되고 있습니다." + +#: postmaster/pgstat.c:6129 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "정리하는 동안 데이터베이스 해시 테이블이 손상 되었습니다 --- 중지함" + +#: postmaster/postmaster.c:733 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: -f 옵션의 잘못된 인자: \"%s\"\n" + +#: postmaster/postmaster.c:819 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: -t 옵션의 잘못된 인자: \"%s\"\n" + +#: postmaster/postmaster.c:870 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: 잘못된 인자: \"%s\"\n" + +#: postmaster/postmaster.c:912 +#, c-format +msgid "" +"%s: superuser_reserved_connections (%d) must be less than max_connections " +"(%d)\n" +msgstr "" +"%s: superuser_reserved_connections (%d) 값은 max_connections(%d) 값보다 작아" +"야함\n" + +#: postmaster/postmaster.c:919 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "wal_level 값이 \"minimal\"일 때는 아카이브 작업을 할 수 없습니다." + +#: postmaster/postmaster.c:922 +#, c-format +msgid "" +"WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or " +"\"logical\"" +msgstr "" +"WAL 스트리밍 작업(max_wal_senders > 0 인경우)은 wal_level 값이 \"replica\" 또" +"는 \"logical\" 이어야 합니다." + +#: postmaster/postmaster.c:930 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: 잘못된 datetoken 테이블들, 복구하십시오.\n" + +#: postmaster/postmaster.c:1047 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "하위 대기열에 대해 I/O 완료 포트를 만들 수 없음" + +#: postmaster/postmaster.c:1113 +#, c-format +msgid "ending log output to stderr" +msgstr "stderr 쪽 로그 출력을 중지합니다." + +#: postmaster/postmaster.c:1114 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "자세한 로그는 \"%s\" 쪽으로 기록됩니다." + +#: postmaster/postmaster.c:1125 +#, c-format +msgid "starting %s" +msgstr "" + +#: postmaster/postmaster.c:1154 postmaster/postmaster.c:1252 +#: utils/init/miscinit.c:1597 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "\"%s\" 매개 변수 구문이 잘못 되었습니다" + +#: postmaster/postmaster.c:1185 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "\"%s\" 응당 소켓을 만들 수 없습니다" + +#: postmaster/postmaster.c:1191 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "TCP/IP 소켓을 만들 수 없습니다." + +#: postmaster/postmaster.c:1274 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "\"%s\" 디렉터리에 유닉스 도메인 소켓을 만들 수 없습니다" + +#: postmaster/postmaster.c:1280 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "유닉스 도메인 소켓을 만들 수 없습니다" + +#: postmaster/postmaster.c:1292 +#, c-format +msgid "no socket created for listening" +msgstr "서버 접속 대기 작업을 위한 소켓을 만들 수 없음" + +#: postmaster/postmaster.c:1323 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: \"%s\" 외부 PID 파일의 접근 권한을 바꿀 수 없음: %s\n" + +#: postmaster/postmaster.c:1327 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: 외부 pid 파일 \"%s\" 를 쓸 수 없음: %s\n" + +#: postmaster/postmaster.c:1360 utils/init/postinit.c:215 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "pg_hba.conf를 로드할 수 없음" + +#: postmaster/postmaster.c:1386 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "" + +#: postmaster/postmaster.c:1387 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "LC_ALL 환경 설정값으로 알맞은 로케일 이름을 지정하세요." + +#: postmaster/postmaster.c:1488 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: 실행가능한 postgres 프로그램을 찾을 수 없습니다" + +#: postmaster/postmaster.c:1511 utils/misc/tzparser.c:340 +#, c-format +msgid "" +"This may indicate an incomplete PostgreSQL installation, or that the file " +"\"%s\" has been moved away from its proper location." +msgstr "" +"이 문제는 PostgreSQL 설치가 불완전하게 되었거나, \"%s\" 파일이 올바른 위치에 " +"있지 않아서 발생했습니다." + +#: postmaster/postmaster.c:1538 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: 데이터베이스 시스템을 찾을 수 없습니다\n" +"\"%s\" 디렉터리 안에 해당 자료가 있기를 기대했는데,\n" +"\"%s\" 파일을 열 수가 없었습니다: %s\n" + +#: postmaster/postmaster.c:1715 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "postmaster에서 select() 작동 실패: %m" + +#: postmaster/postmaster.c:1870 +#, c-format +msgid "" +"performing immediate shutdown because data directory lock file is invalid" +msgstr "" + +#: postmaster/postmaster.c:1973 postmaster/postmaster.c:2004 +#, c-format +msgid "incomplete startup packet" +msgstr "아직 완료되지 않은 시작 패킷" + +#: postmaster/postmaster.c:1985 +#, c-format +msgid "invalid length of startup packet" +msgstr "시작 패킷의 길이가 잘못 되었습니다" + +#: postmaster/postmaster.c:2043 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "SSL 연결 작업에 오류가 발생했습니다: %m" + +#: postmaster/postmaster.c:2074 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "GSSAPI 협상 응답을 보내지 못했습니다: %m" + +#: postmaster/postmaster.c:2104 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "" +"지원하지 않는 frontend 프로토콜 %u.%u: 서버에서 지원하는 프로토콜 %u.0 .. %u." +"%u" + +#: postmaster/postmaster.c:2168 utils/misc/guc.c:6769 utils/misc/guc.c:6805 +#: utils/misc/guc.c:6875 utils/misc/guc.c:8198 utils/misc/guc.c:11044 +#: utils/misc/guc.c:11078 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "잘못된 \"%s\" 매개 변수의 값: \"%s\"" + +#: postmaster/postmaster.c:2171 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "" + +#: postmaster/postmaster.c:2216 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "잘못된 시작 패킷 레이아웃: 마지막 바이트로 종결문자가 발견되었음" + +#: postmaster/postmaster.c:2254 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "시작 패킷에서 지정한 사용자는 PostgreSQL 사용자 이름이 아닙니다" + +#: postmaster/postmaster.c:2318 +#, c-format +msgid "the database system is starting up" +msgstr "데이터베이스 시스템이 새로 가동 중입니다." + +#: postmaster/postmaster.c:2323 +#, c-format +msgid "the database system is shutting down" +msgstr "데이터베이스 시스템이 중지 중입니다" + +#: postmaster/postmaster.c:2328 +#, c-format +msgid "the database system is in recovery mode" +msgstr "데이터베이스 시스템이 자동 복구 작업 중입니다." + +#: postmaster/postmaster.c:2333 storage/ipc/procarray.c:293 +#: storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:362 +#, c-format +msgid "sorry, too many clients already" +msgstr "최대 동시 접속자 수를 초과했습니다." + +#: postmaster/postmaster.c:2423 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "프로세스 %d에 대한 취소 요청에 잘못된 키가 있음" + +#: postmaster/postmaster.c:2435 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "취소 요청의 PID %d과(와) 일치하는 프로세스가 없음" + +#: postmaster/postmaster.c:2706 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "SIGHUP 신호를 받아서, 환경설정파일을 다시 읽고 있습니다." + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2732 postmaster/postmaster.c:2736 +#, c-format +msgid "%s was not reloaded" +msgstr "%s 파일을 다시 불러오지 않았음" + +#: postmaster/postmaster.c:2746 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "SSL 설정이 다시 로드되지 않았음" + +#: postmaster/postmaster.c:2802 +#, c-format +msgid "received smart shutdown request" +msgstr "smart 중지 요청을 받았습니다." + +#: postmaster/postmaster.c:2848 +#, c-format +msgid "received fast shutdown request" +msgstr "fast 중지 요청을 받았습니다." + +#: postmaster/postmaster.c:2866 +#, c-format +msgid "aborting any active transactions" +msgstr "모든 활성화 되어있는 트랜잭션을 중지하고 있습니다." + +#: postmaster/postmaster.c:2890 +#, c-format +msgid "received immediate shutdown request" +msgstr "immediate 중지 요청을 받았습니다." + +#: postmaster/postmaster.c:2965 +#, c-format +msgid "shutdown at recovery target" +msgstr "복구 타겟에서 중지함" + +#: postmaster/postmaster.c:2983 postmaster/postmaster.c:3019 +msgid "startup process" +msgstr "시작 프로세스" + +#: postmaster/postmaster.c:2986 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "시작 프로세스 실패 때문에 서버 시작이 중지 되었습니다" + +#: postmaster/postmaster.c:3061 +#, c-format +msgid "database system is ready to accept connections" +msgstr "이제 데이터베이스 서버로 접속할 수 있습니다" + +#: postmaster/postmaster.c:3082 +msgid "background writer process" +msgstr "백그라운드 writer 프로세스" + +#: postmaster/postmaster.c:3136 +msgid "checkpointer process" +msgstr "체크포인트 프로세스" + +#: postmaster/postmaster.c:3152 +msgid "WAL writer process" +msgstr "WAL 쓰기 프로세스" + +#: postmaster/postmaster.c:3167 +msgid "WAL receiver process" +msgstr "WAL 수신 프로세스" + +#: postmaster/postmaster.c:3182 +msgid "autovacuum launcher process" +msgstr "autovacuum 실행기 프로세스" + +#: postmaster/postmaster.c:3197 +msgid "archiver process" +msgstr "archiver 프로세스" + +#: postmaster/postmaster.c:3213 +msgid "statistics collector process" +msgstr "통계 수집기 프로세스" + +#: postmaster/postmaster.c:3227 +msgid "system logger process" +msgstr "시스템 로그 프로세스" + +#: postmaster/postmaster.c:3291 +#, c-format +msgid "background worker \"%s\"" +msgstr "백그라운드 작업자 \"%s\"" + +#: postmaster/postmaster.c:3375 postmaster/postmaster.c:3395 +#: postmaster/postmaster.c:3402 postmaster/postmaster.c:3420 +msgid "server process" +msgstr "서버 프로세스" + +#: postmaster/postmaster.c:3474 +#, c-format +msgid "terminating any other active server processes" +msgstr "다른 활성화 되어있는 서버 프로세스를 마치고 있는 중입니다" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3729 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) 프로그램은 %d 코드로 마쳤습니다" + +#: postmaster/postmaster.c:3731 postmaster/postmaster.c:3743 +#: postmaster/postmaster.c:3753 postmaster/postmaster.c:3764 +#, c-format +msgid "Failed process was running: %s" +msgstr "" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3740 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) 프로세스가 0x%X 예외로 인해 종료됨" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3750 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) 프로세스가 %d번 시그널을 받아 종료됨: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3762 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) 프로세스가 인식할 수 없는 %d 상태로 종료됨" + +#: postmaster/postmaster.c:3970 +#, c-format +msgid "abnormal database system shutdown" +msgstr "비정상적인 데이터베이스 시스템 서비스를 중지" + +#: postmaster/postmaster.c:4010 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "모든 서버 프로세스가 중지 되었습니다; 재 초기화 중" + +#: postmaster/postmaster.c:4180 postmaster/postmaster.c:5599 +#: postmaster/postmaster.c:5986 +#, c-format +msgid "could not generate random cancel key" +msgstr "무작위 취소 키를 만들 수 없음" + +#: postmaster/postmaster.c:4234 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "연결을 위한 새 프로세스 할당(fork) 실패: %m" + +#: postmaster/postmaster.c:4276 +msgid "could not fork new process for connection: " +msgstr "연결을 위한 새 프로세스 할당(fork) 실패: " + +#: postmaster/postmaster.c:4393 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "접속 수락: host=%s port=%s" + +#: postmaster/postmaster.c:4398 +#, c-format +msgid "connection received: host=%s" +msgstr "접속 수락: host=%s" + +#: postmaster/postmaster.c:4668 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "\"%s\" 서버 프로세스를 실행할 수 없음: %m" + +#: postmaster/postmaster.c:4827 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "공유 메모리 확보 작업을 여러 번 시도했으나 실패 함" + +#: postmaster/postmaster.c:4828 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "이 현상은 ASLR 또는 바이러스 검사 소프트웨어 때문일 수 있습니다." + +#: postmaster/postmaster.c:5034 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "하위 프로세스에서 SSL 환경 설정을 못했음" + +#: postmaster/postmaster.c:5166 +#, c-format +msgid "Please report this to <%s>." +msgstr "이 내용을 <%s> 주소로 보고하십시오." + +#: postmaster/postmaster.c:5259 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "데이터베이스 시스템이 읽기 전용으로 연결을 수락할 준비가 되었습니다." + +#: postmaster/postmaster.c:5527 +#, c-format +msgid "could not fork startup process: %m" +msgstr "시작 프로세스 할당(fork) 실패: %m" + +#: postmaster/postmaster.c:5531 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "백그라운 writer 프로세스를 할당(fork)할 수 없습니다: %m" + +#: postmaster/postmaster.c:5535 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "체크포인트 프로세스를 할당(fork)할 수 없습니다: %m" + +#: postmaster/postmaster.c:5539 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "WAL 쓰기 프로세스를 할당(fork)할 수 없음: %m" + +#: postmaster/postmaster.c:5543 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "WAL 수신 프로세스를 할당(fork)할 수 없음: %m" + +#: postmaster/postmaster.c:5547 +#, c-format +msgid "could not fork process: %m" +msgstr "프로세스 할당(fork) 실패: %m" + +#: postmaster/postmaster.c:5744 postmaster/postmaster.c:5767 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "" + +#: postmaster/postmaster.c:5751 postmaster/postmaster.c:5774 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "백그라운드 작업자에서 잘못된 프로세싱 모드가 사용됨" + +#: postmaster/postmaster.c:5847 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "\"%s\" 백그라운드 작업자 프로세스를 시작합니다." + +#: postmaster/postmaster.c:5859 +#, c-format +msgid "could not fork worker process: %m" +msgstr "작업자 프로세스를 할당(fork)할 수 없음: %m" + +#: postmaster/postmaster.c:5972 +#, c-format +msgid "no slot available for new worker process" +msgstr "새 작업자 프로세스에서 쓸 슬롯이 없음" + +#: postmaster/postmaster.c:6307 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "백엔드에서 사용하기 위해 %d 소켓을 복사할 수 없음: 오류 코드 %d" + +#: postmaster/postmaster.c:6339 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "상속된 소켓을 만들 수 없음: 오류 코드 %d\n" + +#: postmaster/postmaster.c:6368 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "\"%s\" 백엔드 변수 파일을 열 수 없음: %s\n" + +#: postmaster/postmaster.c:6375 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "\"%s\" 백엔드 변수 파일을 읽을 수 없음: %s\n" + +#: postmaster/postmaster.c:6384 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "\"%s\" 파일을 삭제할 수 없음: %s\n" + +#: postmaster/postmaster.c:6401 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "백엔드 변수 파일의 view를 map할 수 없음: 오류 코드 %lu\n" + +#: postmaster/postmaster.c:6410 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "백엔드 변수 파일의 view를 unmap할 수 없음: 오류 코드 %lu\n" + +#: postmaster/postmaster.c:6417 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "백엔드 변수 파일을 닫을 수 없음: 오류 코드 %lu\n" + +#: postmaster/postmaster.c:6595 +#, c-format +msgid "could not read exit code for process\n" +msgstr "프로세스의 종료 코드를 읽을 수 없음\n" + +#: postmaster/postmaster.c:6600 +#, c-format +msgid "could not post child completion status\n" +msgstr "하위 완료 상태를 게시할 수 없음\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "로그 파이프에서 읽기 실패: %m" + +#: postmaster/syslogger.c:522 +#, c-format +msgid "logger shutting down" +msgstr "로그 작업 끝내는 중" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "syslog에서 사용할 파이프를 만들 수 없습니다: %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "시스템 로거(logger)를 확보하질 못 했습니다: %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "서버 로그를 로그 수집 프로세스로 보냅니다." + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "이제부터 서버 로그는 \"%s\" 디렉터리에 보관됩니다." + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "표준출력을 redirect 하지 못했습니다: %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "표준오류(stderr)를 redirect 하지 못했습니다: %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "로그파일 쓰기 실패: %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "\"%s\" 잠금파일을 열 수 없음: %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "" +"로그파일 자동 교체 기능을 금지합니다(교체하려면 SIGHUP 시그널을 사용함)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "정규식을 사용해서 사용할 정렬규칙(collation)을 찾을 수 없음" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "정규식을 사용해서 사용할 정렬규칙(collation)을 찾을 수 없음" + +#: replication/backup_manifest.c:231 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "%u 타임라인이 끝이어야하는데, %u 타임라인임" + +#: replication/backup_manifest.c:248 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "" +"시작 타임라인이 %u 여야하는데, %u 타임라인임" + +#: replication/backup_manifest.c:275 +#, c-format +msgid "start timeline %u not found in history of timeline %u" +msgstr "" +"%u 시작 타임라인이 %u 타임라인 내역안에 없음" + +#: replication/backup_manifest.c:322 +#, c-format +msgid "could not rewind temporary file" +msgstr "임시 파일을 되감을 수 없음" + +#: replication/backup_manifest.c:349 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "임시 파일을 읽을 수 없음: %m" + +#: replication/basebackup.c:108 +#, c-format +msgid "could not read from file \"%s\"" +msgstr "\"%s\" 파일을 읽을 수 없음" + +#: replication/basebackup.c:551 +#, c-format +msgid "could not find any WAL files" +msgstr "어떤 WAL 파일도 찾을 수 없음" + +#: replication/basebackup.c:566 replication/basebackup.c:582 +#: replication/basebackup.c:591 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "\"%s\" WAL 파일 찾기 실패" + +#: replication/basebackup.c:634 replication/basebackup.c:665 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "\"%s\" WAL 파일의 크기가 알맞지 않음" + +#: replication/basebackup.c:648 replication/basebackup.c:1752 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "베이스 백업에서 자료를 보낼 수 없음. 백업을 중지합니다." + +#: replication/basebackup.c:724 +#, c-format +msgid "%lld total checksum verification failure" +msgid_plural "%lld total checksum verification failures" +msgstr[0] "%lld 전체 체크섬 검사 실패" + +#: replication/basebackup.c:731 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "베이스 백업 중 체크섬 검사 실패" + +#: replication/basebackup.c:784 replication/basebackup.c:793 +#: replication/basebackup.c:802 replication/basebackup.c:811 +#: replication/basebackup.c:820 replication/basebackup.c:831 +#: replication/basebackup.c:848 replication/basebackup.c:857 +#: replication/basebackup.c:869 replication/basebackup.c:893 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "\"%s\" 옵션을 두 번 지정했습니다" + +#: replication/basebackup.c:837 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "" +"%d 값은 \"%s\" 매개 변수의 값으로 타당한 범위(%d .. %d)를 벗어났습니다." + +#: replication/basebackup.c:882 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "인식할 수 없는 메니페스트 옵션 \"%s\"" + +#: replication/basebackup.c:898 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "알 수 없는 체크섬 알고리즘: \"%s\"" + +#: replication/basebackup.c:913 +#, c-format +msgid "manifest checksums require a backup manifest" +msgstr "" + +#: replication/basebackup.c:1504 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "\"%s\" 특수 파일을 건너뜀" + +#: replication/basebackup.c:1623 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "잘못된 조각 번호 %d, 해당 파일: \"%s\"" + +#: replication/basebackup.c:1642 +#, c-format +msgid "" +"could not verify checksum in file \"%s\", block %d: read buffer size %d and " +"page size %d differ" +msgstr "" + +#: replication/basebackup.c:1686 replication/basebackup.c:1716 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "\"%s\" 파일에서 fseek 작업을 할 수 없음: %m" + +#: replication/basebackup.c:1708 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "%d 블럭을 \"%s\" 파일에서 다시 읽을 수 없음: %m" + +#: replication/basebackup.c:1732 +#, c-format +msgid "" +"checksum verification failed in file \"%s\", block %d: calculated %X but " +"expected %X" +msgstr "" +"\"%s\" 파일 체크섬 검사 실패(해당 블럭 %d): 계산된 체크섬은 %X 값이지만, 기" +"대값 %X" + +#: replication/basebackup.c:1739 +#, c-format +msgid "" +"further checksum verification failures in file \"%s\" will not be reported" +msgstr "" + +#: replication/basebackup.c:1807 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "\"%s\" 파일에서 전체 %d 건 체크섬 검사 실패" + +#: replication/basebackup.c:1843 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "tar 파일로 묶기에는 파일 이름이 너무 긺: \"%s\"" + +#: replication/basebackup.c:1848 +#, c-format +msgid "" +"symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "" +"tar 포멧을 사용하기에는 심볼릭 링크의 대상 경로가 너무 깁니다: 파일 이름 \"%s" +"\", 대상 \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, c-format +msgid "could not clear search path: %s" +msgstr "search path를 지울 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:251 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "잘못된 연결 문자열 구문: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:275 +#, c-format +msgid "could not parse connection string: %s" +msgstr "접속 문자열을 분석할 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:347 +#, c-format +msgid "" +"could not receive database system identifier and timeline ID from the " +"primary server: %s" +msgstr "" +"주 서버에서 데이터베이스 시스템 식별번호와 타임라인 번호를 받을 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:358 +#: replication/libpqwalreceiver/libpqwalreceiver.c:576 +#, c-format +msgid "invalid response from primary server" +msgstr "주 서버에서 잘못된 응답이 왔음" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:359 +#, c-format +msgid "" +"Could not identify system: got %d rows and %d fields, expected %d rows and " +"%d or more fields." +msgstr "" +"시스템을 식별할 수 없음: 로우수 %d, 필드수 %d, 예상값: 로우수 %d, 필드수 %d " +"이상" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:432 +#: replication/libpqwalreceiver/libpqwalreceiver.c:438 +#: replication/libpqwalreceiver/libpqwalreceiver.c:463 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "WAL 스트리밍 작업을 시작할 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:486 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "주 서버로 스트리밍 종료 메시지를 보낼 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:508 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "스트리밍 종료 요청에 대한 잘못된 응답을 받음" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:522 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "COPY 스트리밍 종료 중 오류 발생: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:531 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "스트리밍 명령에 대한 결과 처리에서 오류 발생: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 +#: replication/libpqwalreceiver/libpqwalreceiver.c:773 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "CommandComplete 작업 후 예상치 못한 결과를 받음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:565 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "주 서버에서 타임라인 내역 파일을 받을 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:577 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "2개의 칼럼으로 된 하나의 튜플을 예상하지만, %d 튜플 (%d 칼럼)을 수신함" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:737 +#: replication/libpqwalreceiver/libpqwalreceiver.c:788 +#: replication/libpqwalreceiver/libpqwalreceiver.c:794 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "WAL 스트림에서 자료 받기 실패: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:813 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "WAL 스트림에 데이터를 보낼 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:866 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "\"%s\" 복제 슬롯을 만들 수 없음: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:911 +#, c-format +msgid "invalid query response" +msgstr "잘못된 쿼리 응답" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:912 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "%d개의 칼럼을 예상하지만, %d개의 칼럼을 수신함" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:981 +#, c-format +msgid "the query interface requires a database connection" +msgstr "이 쿼리 인터페이스는 데이터베이스 연결이 필요합니다" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1012 +msgid "empty query" +msgstr "빈 쿼리" + +#: replication/logical/launcher.c:295 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "\"%s\" 구독을 위해 논리 복제 작업자를 시작합니다" + +#: replication/logical/launcher.c:302 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "" +"max_replication_slots = 0 설정 때문에 논리 복제 작업자를 시작 할 수 없습니다" + +#: replication/logical/launcher.c:382 +#, c-format +msgid "out of logical replication worker slots" +msgstr "더 이상의 논리 복제 작업자용 슬롯이 없습니다" + +#: replication/logical/launcher.c:383 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "max_logical_replication_workers 값을 늘리세요." + +#: replication/logical/launcher.c:438 +#, c-format +msgid "out of background worker slots" +msgstr "백그라운 작업자 슬롯이 모자랍니다" + +#: replication/logical/launcher.c:439 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "max_worker_processes 값을 늘리세요." + +#: replication/logical/launcher.c:638 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "" + +#: replication/logical/launcher.c:647 +#, c-format +msgid "" +"logical replication worker slot %d is already used by another worker, cannot " +"attach" +msgstr "" + +#: replication/logical/launcher.c:951 +#, c-format +msgid "logical replication launcher started" +msgstr "논리 복제 관리자가 시작됨" + +#: replication/logical/logical.c:87 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "논리적 디코딩 기능은 wal_level 값이 logical 이상이어야 함" + +#: replication/logical/logical.c:92 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "논리적 디코딩 기능은 데이터베이스 연결이 필요합니다" + +#: replication/logical/logical.c:110 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "논리적 디코딩 기능은 복구 상태에서는 사용할 수 없음" + +#: replication/logical/logical.c:258 replication/logical/logical.c:399 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "논리적 디코딩에서는 물리적 복제 슬롯을 사용할 수 없음" + +#: replication/logical/logical.c:263 replication/logical/logical.c:404 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "\"%s\" 복제 슬롯이 이 데이터베이스 만들어져있지 않음" + +#: replication/logical/logical.c:270 +#, c-format +msgid "" +"cannot create logical replication slot in transaction that has performed " +"writes" +msgstr "" +"자료 변경 작업이 있는 트랜잭션 안에서는 논리적 복제 슬롯을 만들 수 없음" + +#: replication/logical/logical.c:444 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "\"%s\" 이름의 논리적 복제 슬롯을 만드는 중" + +#: replication/logical/logical.c:446 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "" + +#: replication/logical/logical.c:593 +#, c-format +msgid "" +"slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "" + +#: replication/logical/logical.c:600 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "" +"복제 슬롯은 superuser 또는 replication 롤 옵션을 포함한 사용자만 사용할 수 있" +"습니다." + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "슬롯 이름으로 null 값을 사용할 수 없습니다" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "옵션 배열은 null 값을 사용할 수 없습니다." + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "배열은 일차원 배열이어야합니다" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "배열에는 null 값을 포함할 수 없습니다" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 +#: utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "배열은 그 요소의 개수가 짝수여야 함" + +#: replication/logical/logicalfuncs.c:251 +#, c-format +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "\"%s\" 복제 슬롯에서 변경 사항을 더 찾을 수 없음" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:648 +#, c-format +msgid "This slot has never previously reserved WAL, or has been invalidated." +msgstr "이 슬롯은 한 번도 WAL를 예약한 적이 없거나, 잘못된 것임" + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "" +"logical decoding output plugin \"%s\" produces binary output, but function " +"\"%s\" expects textual data" +msgstr "" +"\"%s\" 논리 복제 출력 플러그인은 이진 자료를 출력하지만, \"%s\" 함수는 " +"텍스트 자료를 사용함" + +#: replication/logical/origin.c:188 +#, c-format +msgid "only superusers can query or manipulate replication origins" +msgstr "슈퍼유저만 복제 원본에 대한 쿼리나, 관리를 할 수 있습니다." + +#: replication/logical/origin.c:193 +#, c-format +msgid "" +"cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "" + +#: replication/logical/origin.c:198 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "" + +#: replication/logical/origin.c:233 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "\"%s\" 이름의 복제 오리진이 없습니다" + +#: replication/logical/origin.c:324 +#, c-format +msgid "could not find free replication origin OID" +msgstr "비어있는 복제 오리진 OID를 찾을 수 없음" + +#: replication/logical/origin.c:372 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "" + +#: replication/logical/origin.c:464 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "OID %u 복제 오리진이 없음" + +#: replication/logical/origin.c:729 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "복제 체크포인트의 잘못된 매직 번호: %u, 기대값: %u" + +#: replication/logical/origin.c:770 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "" +"사용 가능한 복제 슬롯이 부족합니다. max_replication_slots 값을 늘리세요" + +#: replication/logical/origin.c:788 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "복제 슬롯 체크포인트의 체크섬 값이 잘못됨: %u, 기대값 %u" + +#: replication/logical/origin.c:916 replication/logical/origin.c:1102 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "" + +#: replication/logical/origin.c:927 replication/logical/origin.c:1114 +#, c-format +msgid "" +"could not find free replication state slot for replication origin with OID %u" +msgstr "%u OID 복제 오리진을 위한 여유 복제 슬롯을 찾을 수 없음" + +#: replication/logical/origin.c:929 replication/logical/origin.c:1116 +#: replication/slot.c:1762 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "max_replication_slots 값을 늘린 후 다시 시도해 보세요" + +#: replication/logical/origin.c:1073 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "하나가 이미 설정되어 더 이상 복제 오리진 설정을 할 수 없음" + +#: replication/logical/origin.c:1153 replication/logical/origin.c:1369 +#: replication/logical/origin.c:1389 +#, c-format +msgid "no replication origin is configured" +msgstr "복제 오리진 설정이 없습니다" + +#: replication/logical/origin.c:1236 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "\"%s\" 복제 오리진 이름은 사용할 수 없음" + +#: replication/logical/origin.c:1238 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "\"pg_\"로 시작하는 오리진 이름은 사용할 수 없습니다." + +#: replication/logical/relation.c:302 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "\"%s.%s\" 이름의 논리 복제 대상 릴레이션이 없습니다." + +#: replication/logical/relation.c:345 +#, c-format +msgid "" +"logical replication target relation \"%s.%s\" is missing some replicated " +"columns" +msgstr "" + +#: replication/logical/relation.c:385 +#, c-format +msgid "" +"logical replication target relation \"%s.%s\" uses system columns in REPLICA " +"IDENTITY index" +msgstr "" + +#: replication/logical/reorderbuffer.c:2663 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "%u XID 내용을 데이터 파일에 쓸 수 없음: %m" + +#: replication/logical/reorderbuffer.c:2850 +#: replication/logical/reorderbuffer.c:2875 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "reorderbuffer 처리용 파일에서 읽기 실패: %m" + +#: replication/logical/reorderbuffer.c:2854 +#: replication/logical/reorderbuffer.c:2879 +#, c-format +msgid "" +"could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "" +"reorderbuffer 처리용 파일에서 읽기 실패: %d 바이트 읽음, 기대값 %u 바이트" + +#: replication/logical/reorderbuffer.c:3114 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "\"%s\" 파일을 지울 수 없음, pg_replslot/%s/xid* 삭제 작업 중: %m" + +#: replication/logical/reorderbuffer.c:3606 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "\"%s\" 파일에서 읽기 실패: %d 바이트 읽음, 기대값 %d 바이트" + +#: replication/logical/snapbuild.c:606 +#, c-format +msgid "initial slot snapshot too large" +msgstr "초기 슬롯 스냅샷이 너무 큽니다." + +#: replication/logical/snapbuild.c:660 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "" +"exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "" + +#: replication/logical/snapbuild.c:1265 replication/logical/snapbuild.c:1358 +#: replication/logical/snapbuild.c:1912 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "논리적 디코딩 이어서 시작할 위치: %X/%X" + +#: replication/logical/snapbuild.c:1267 +#, c-format +msgid "There are no running transactions." +msgstr "실행할 트랜잭션이 없음" + +#: replication/logical/snapbuild.c:1309 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "논리적 디코딩 시작 위치: %X/%X" + +#: replication/logical/snapbuild.c:1311 replication/logical/snapbuild.c:1335 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "" + +#: replication/logical/snapbuild.c:1333 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "논리적 디코딩을 이어서 시작할 위치: %X/%X" + +#: replication/logical/snapbuild.c:1360 +#, c-format +msgid "There are no old transactions anymore." +msgstr "더이상 오래된 트랜잭션이 없습니다." + +#: replication/logical/snapbuild.c:1754 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "\"%s\" snapbuild 상태 파일의 매직 번호가 이상함: 현재값 %u, 기대값 %u" + +#: replication/logical/snapbuild.c:1760 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "\"%s\" snapbuild 상태 파일의 버전이 이상함: 현재값 %u, 기대값 %u" + +#: replication/logical/snapbuild.c:1859 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "" + +#: replication/logical/snapbuild.c:1914 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "" + +#: replication/logical/snapbuild.c:1986 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "\"%s\" 파일 이름을 분석할 수 없음" + +#: replication/logical/tablesync.c:132 +#, c-format +msgid "" +"logical replication table synchronization worker for subscription \"%s\", " +"table \"%s\" has finished" +msgstr "" + +#: replication/logical/tablesync.c:664 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "\"%s.%s\" 테이블용 테이블 정보를 구할 수 없습니다, 해당 발행: %s" + +#: replication/logical/tablesync.c:670 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "" + +#: replication/logical/tablesync.c:704 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "\"%s.%s\" 테이블용 테이블 정보를 구할 수 없습니다: %s" + +#: replication/logical/tablesync.c:791 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "\"%s.%s\" 테이블용 초기 자료 복사를 시작할 수 없습니다: %s" + +#: replication/logical/tablesync.c:905 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "발행 서버에서는 테이블 복사 트랜잭션을 시작할 수 없음" + +#: replication/logical/tablesync.c:927 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "" + +#: replication/logical/worker.c:313 +#, c-format +msgid "" +"processing remote data for replication target relation \"%s.%s\" column \"%s" +"\", remote type %s, local type %s" +msgstr "" + +#: replication/logical/worker.c:552 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "" + +#: replication/logical/worker.c:702 +#, c-format +msgid "" +"publisher did not send replica identity column expected by the logical " +"replication target relation \"%s.%s\"" +msgstr "" + +#: replication/logical/worker.c:709 +#, c-format +msgid "" +"logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY " +"index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY " +"FULL" +msgstr "" + +#: replication/logical/worker.c:1394 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "잘못된 논리 복제 메시지 형태 \"%c\"" + +#: replication/logical/worker.c:1537 +#, c-format +msgid "data stream from publisher has ended" +msgstr "" + +#: replication/logical/worker.c:1692 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "시간 제한으로 논리 복제 작업자를 중지합니다." + +#: replication/logical/worker.c:1837 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will stop because " +"the subscription was removed" +msgstr "" + +#: replication/logical/worker.c:1851 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will stop because " +"the subscription was disabled" +msgstr "" + +#: replication/logical/worker.c:1865 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because the connection information was changed" +msgstr "" + +#: replication/logical/worker.c:1879 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because subscription was renamed" +msgstr "" + +#: replication/logical/worker.c:1896 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because the replication slot name was changed" +msgstr "" + +#: replication/logical/worker.c:1910 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because subscription's publications were changed" +msgstr "" + +#: replication/logical/worker.c:2006 +#, c-format +msgid "" +"logical replication apply worker for subscription %u will not start because " +"the subscription was removed during startup" +msgstr "" + +#: replication/logical/worker.c:2018 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will not start " +"because the subscription was disabled during startup" +msgstr "" + +#: replication/logical/worker.c:2036 +#, c-format +msgid "" +"logical replication table synchronization worker for subscription \"%s\", " +"table \"%s\" has started" +msgstr "" + +#: replication/logical/worker.c:2040 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "" + +#: replication/logical/worker.c:2079 +#, c-format +msgid "subscription has no replication slot set" +msgstr "" + +#: replication/pgoutput/pgoutput.c:147 +#, c-format +msgid "invalid proto_version" +msgstr "잘못된 proto_version" + +#: replication/pgoutput/pgoutput.c:152 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_verson \"%s\" 범위 벗어남" + +#: replication/pgoutput/pgoutput.c:169 +#, c-format +msgid "invalid publication_names syntax" +msgstr "잘못된 publication_names 구문" + +#: replication/pgoutput/pgoutput.c:211 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "" + +#: replication/pgoutput/pgoutput.c:217 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "" + +#: replication/pgoutput/pgoutput.c:223 +#, c-format +msgid "publication_names parameter missing" +msgstr "publication_names 매개 변수가 빠졌음" + +#: replication/slot.c:183 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "\"%s\" 복제 슬롯 이름이 너무 짧음" + +#: replication/slot.c:192 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "\"%s\" 복제 슬롯 이름이 너무 긺" + +#: replication/slot.c:205 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "\"%s\" 복제 슬롯 이름에 사용할 수 없는 문자가 있음" + +#: replication/slot.c:207 +#, c-format +msgid "" +"Replication slot names may only contain lower case letters, numbers, and the " +"underscore character." +msgstr "" +"복제 슬롯 이름으로 사용할 수 있는 문자는 영문 소문자, 숫자, 밑줄(_) 문자입니" +"다." + +#: replication/slot.c:254 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "\"%s\" 이름의 복제 슬롯이 이미 있습니다." + +#: replication/slot.c:264 +#, c-format +msgid "all replication slots are in use" +msgstr "모든 복제 슬롯이 사용 중입니다." + +#: replication/slot.c:265 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "하나를 비우든지, max_replication_slots 설정값을 늘리세요." + +#: replication/slot.c:407 replication/slotfuncs.c:760 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "\"%s\" 이름의 복제 슬롯이 없습니다" + +#: replication/slot.c:445 replication/slot.c:1006 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "\"%s\" 이름의 복제 슬롯을 %d PID 프로세스가 사용중입니다." + +#: replication/slot.c:683 replication/slot.c:1314 replication/slot.c:1697 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "\"%s\" 디렉터리를 삭제할 수 없음" + +#: replication/slot.c:1041 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "복제 슬롯은 max_replication_slots > 0 상태에서 사용될 수 있습니다." + +#: replication/slot.c:1046 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "복제 슬롯은 wal_level >= replica 상태에서 사용될 수 있습니다." + +#: replication/slot.c:1202 +#, c-format +msgid "" +"terminating process %d because replication slot \"%s\" is too far behind" +msgstr "%d번 프로세스를 중지합니다. \"%s\" 복제 슬롯이 너무 옛날 것입니다." + +#: replication/slot.c:1221 +#, c-format +msgid "" +"invalidating slot \"%s\" because its restart_lsn %X/%X exceeds " +"max_slot_wal_keep_size" +msgstr "" +"\"%s\" 슬롯이 바르지 않음. %X/%X restart_lsn 값이 " +"max_slot_wal_keep_size 값을 초과했음" + +#: replication/slot.c:1635 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "\"%s\" 복제 슬롯 파일의 매직 번호가 이상합니다: 현재값 %u, 기대값 %u" + +#: replication/slot.c:1642 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "\"%s\" 복제 슬롯 파일은 지원하지 않는 %u 버전 파일입니다" + +#: replication/slot.c:1649 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "\"%s\" 복제 슬롯 파일이 %u 길이로 손상되었습니다." + +#: replication/slot.c:1685 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "\"%s\" 복제 슬롯 파일의 체크섬 값이 이상합니다: 현재값 %u, 기대값 %u" + +#: replication/slot.c:1719 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "\"%s\" 논리 복제 슬롯이 있지만, wal_level < logical" + +#: replication/slot.c:1721 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "" + +#: replication/slot.c:1725 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "\"%s\" 물리 복제 슬롯이 있지만, wal_level < replica " + +#: replication/slot.c:1727 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "" + +#: replication/slot.c:1761 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "서버 중지 전에 너무 많은 복제 슬롯이 활성화 상태입니다" + +#: replication/slotfuncs.c:624 +#, c-format +msgid "invalid target WAL LSN" +msgstr "잘못된 대상 WAL LSN" + +#: replication/slotfuncs.c:646 +#, c-format +msgid "replication slot \"%s\" cannot be advanced" +msgstr "\"%s\" 이름의 복제 슬롯은 사용할 수 없음" + +#: replication/slotfuncs.c:664 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "" + +#: replication/slotfuncs.c:772 +#, c-format +msgid "" +"cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "물리 복제 슬롯(\"%s\")을 논리 복제 슬롯으로 복사할 수 없음" + +#: replication/slotfuncs.c:774 +#, c-format +msgid "" +"cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "논리 복제 슬롯(\"%s\")을 물리 복제 슬롯으로 복사할 수 없음" + +#: replication/slotfuncs.c:781 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "WAL을 확보하지 않은 복제 슬롯은 복사할 수 없음" + +#: replication/slotfuncs.c:857 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "\"%s\" 복제 슬롯을 복사할 수 없음" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "" +"The source replication slot was modified incompatibly during the copy " +"operation." +msgstr "" + +#: replication/slotfuncs.c:865 +#, c-format +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "논리 복제가 끝나지 않은 \"%s\" 슬롯은 복사할 수 없음" + +#: replication/slotfuncs.c:867 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "" + +#: replication/syncrep.c:257 +#, c-format +msgid "" +"canceling the wait for synchronous replication and terminating connection " +"due to administrator command" +msgstr "" +"관리자 명령에 의해 동기식 복제의 대기 작업과 접속 끊기 작업을 취소합니다." + +#: replication/syncrep.c:258 replication/syncrep.c:275 +#, c-format +msgid "" +"The transaction has already committed locally, but might not have been " +"replicated to the standby." +msgstr "" +"주 서버에서는 이 트랜잭션이 커밋되었지만, 복제용 대기 서버에서는 아직 커밋 되" +"지 않았을 가능성이 있습니다." + +#: replication/syncrep.c:274 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "사용자 요청에 의해 동기식 복제 작업을 취소합니다." + +#: replication/syncrep.c:416 +#, c-format +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "\"%s\" 대기 서버의 동기식 복제 우선순위가 %u 입니다" + +#: replication/syncrep.c:483 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "\"%s\" 대기 서버의 동기식 복제 우선순위가 %u 로 변경되었습니다." + +#: replication/syncrep.c:487 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "\"%s\" 대기 서버가 동기식 대기 서버 후보가 되었습니다" + +#: replication/syncrep.c:1034 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names 값을 분석할 수 없음" + +#: replication/syncrep.c:1040 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "동기식 대기 서버 수 (%d)는 0보다 커야 합니다." + +#: replication/walreceiver.c:171 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "관리자 명령으로 인해 WAL 수신기를 종료합니다." + +#: replication/walreceiver.c:297 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "주 서버에 연결 할 수 없음: %s" + +#: replication/walreceiver.c:343 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "데이터베이스 시스템 식별번호가 주 서버와 대기 서버가 서로 다름" + +#: replication/walreceiver.c:344 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "주 서버: %s, 대기 서버: %s." + +#: replication/walreceiver.c:354 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "" +"주 서버의 제일 최신의 타임라인은 %u 인데, 복구 타임라인 %u 보다 옛것입니다" + +#: replication/walreceiver.c:408 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "주 서버의 WAL 스트리밍 시작 위치: %X/%X (타임라인 %u)" + +#: replication/walreceiver.c:413 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "WAL 스트리밍 재시작 위치: %X/%X (타임라인 %u)" + +#: replication/walreceiver.c:442 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "WAL 스트리밍 계속할 수 없음, 복구가 이미 종료됨" + +#: replication/walreceiver.c:479 +#, c-format +msgid "replication terminated by primary server" +msgstr "주 서버에 의해서 복제가 끝남" + +#: replication/walreceiver.c:480 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "타임라인 %u, 위치 %X/%X 에서 WAL 끝에 도달함" + +#: replication/walreceiver.c:568 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "시간 제한으로 wal 수신기를 중지합니다." + +#: replication/walreceiver.c:606 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "주 서버에는 요청 받은 %u 타임라인의 WAL가 더 이상 없습니다." + +#: replication/walreceiver.c:622 replication/walreceiver.c:938 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "%s 로그 조각 파일을 닫을 수 없음: %m" + +#: replication/walreceiver.c:742 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "주 서버에서 %u 타임라인용 타임라인 내역 파일을 가져옵니다." + +#: replication/walreceiver.c:985 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "%s 로그 조각 파일 쓰기 실패: 위치 %u, 길이 %lu: %m" + +#: replication/walsender.c:523 storage/smgr/md.c:1291 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "\"%s\" 파일의 끝을 찾을 수 없음: %m" + +#: replication/walsender.c:527 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "\"%s\" 파일에서 시작 위치를 찾을 수 없음: %m" + +#: replication/walsender.c:578 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "" + +#: replication/walsender.c:607 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "물리적 복제에서 논리적 복제 슬롯을 사용할 수 없음" + +#: replication/walsender.c:676 +#, c-format +msgid "" +"requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "요청된 %X/%X 시작 위치(타임라인 %u)가 이 서버 내역에 없습니다." + +#: replication/walsender.c:680 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "이 서버의 시작 위치: 타임라인 %u, 위치 %X/%X" + +#: replication/walsender.c:725 +#, c-format +msgid "" +"requested starting point %X/%X is ahead of the WAL flush position of this " +"server %X/%X" +msgstr "" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:976 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s 명령은 트랜잭션 블럭안에서 실행할 수 없음" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:986 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s 명령은 트랜잭션 블럭안에서 실행할 수 있음" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:992 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s 구문은 격리 수준이 REPEATABLE READ 일때만 사용할 수 있습니다." + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:998 +#, c-format +msgid "%s must be called before any query" +msgstr "어떤 쿼리보다 먼저 %s 명령을 호출해야 함" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1004 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s 명령은 서브트랜잭션 블럭안에서 실행할 수 없음" + +#: replication/walsender.c:1148 +#, c-format +msgid "cannot read from logical replication slot \"%s\"" +msgstr "\"%s\" 논리 복제 슬롯에서 읽기 실패" + +#: replication/walsender.c:1150 +#, c-format +msgid "" +"This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "" + +#: replication/walsender.c:1160 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "운영전환 뒤 wal 송신기 프로세스를 중지합니다." + +#: replication/walsender.c:1534 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "" + +#: replication/walsender.c:1567 +#, c-format +msgid "received replication command: %s" +msgstr "수신된 복제 명령: %s" + +#: replication/walsender.c:1583 tcop/fastpath.c:279 tcop/postgres.c:1103 +#: tcop/postgres.c:1455 tcop/postgres.c:1716 tcop/postgres.c:2174 +#: tcop/postgres.c:2535 tcop/postgres.c:2614 +#, c-format +msgid "" +"current transaction is aborted, commands ignored until end of transaction " +"block" +msgstr "" +"현재 트랜잭션은 중지되어 있습니다. 이 트랜잭션을 종료하기 전까지는 모든 명령" +"이 무시될 것입니다" + +#: replication/walsender.c:1669 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "물리적 복제를 위한 WAL 송신기에서 SQL 명령을 실행할 수 없음" + +#: replication/walsender.c:1714 replication/walsender.c:1730 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "대기 서버 연결에서 예상치 못한 EOF 발견함" + +#: replication/walsender.c:1744 +#, c-format +msgid "unexpected standby message type \"%c\", after receiving CopyDone" +msgstr "" + +#: replication/walsender.c:1782 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "잘못된 대기 서버 메시지 형태 \"%c\"" + +#: replication/walsender.c:1823 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "예상치 못한 메시지 형태: \"%c\"" + +#: replication/walsender.c:2241 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "복제 시간 제한으로 wal 송신기 프로세스를 종료합니다." + +#: replication/walsender.c:2318 +#, c-format +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\" 프로세스가 로그 전달 받을 서버와 접속했음" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:989 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "\"%s\" 이름의 룰(rule)이 \"%s\" 테이블에 이미 지정되어있습니다" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "OLD에 대한 실행 룰(rule)은 아직 구현되지 않았습니다" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "대신에 뷰나 트리거를 사용하십시오." + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "NEW에 대한 실행 룰(rule)은 아직 구현되지 않았습니다" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "대신에 트리거를 사용하십시오." + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "SELECT 에서 INSTEAD NOTHING 룰(rule)은 구현되지 않았습니다" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "대신에 뷰를 사용하십시오." + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "SELECT에 대한 다중 실행 룰(rule)은 구현되지 않았습니다" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "" +"SELECT에 대한 룰(rule)은 그 지정에 INSTEAD SELECT 실행규칙을 지정해야만합니다" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "" +"이벤트 자격(event qualifications)은 SELECT 룰(rule)에서 구현되지 않았습니다" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "\"%s\" 이름의 뷰가 이미 있습니다" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "\"%s\" 위한 뷰 룰(view rule)의 이름은 \"%s\" 여야만합니다" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "\"%s\" 파티션된 테이블은 뷰로 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:440 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "\"%s\" 파티션 테이블은 뷰로 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:449 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "\"%s\" 테이블에 자료가 있기 때문에, 테이블을 뷰로 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:458 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "\"%s\" 테이블에 트리거가 포함되어 있어 뷰로 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:460 +#, c-format +msgid "" +"In particular, the table cannot be involved in any foreign key relationships." +msgstr "특히 테이블은 참조키 관계에 관련될 수 없습니다." + +#: rewrite/rewriteDefine.c:465 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "\"%s\" 테이블에 인덱스가 포함되어 있어 뷰로 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:471 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "\"%s\" 테이블을 상속 받는 테이블이 있어 뷰로 변활할 수 없습니다" + +#: rewrite/rewriteDefine.c:477 +#, c-format +msgid "" +"could not convert table \"%s\" to a view because it has row security enabled" +msgstr "" +"로우단위 보안 기능을 사용하고 있어 \"%s\" 테이블을 뷰로 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:483 +#, c-format +msgid "" +"could not convert table \"%s\" to a view because it has row security policies" +msgstr "로우단위 보안 설정이 되어 있어 \"%s\" 테이블을 뷰로 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:510 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "하나의 rule에서 여러개의 RETURNING 목록을 지정할 수 없습니다" + +#: rewrite/rewriteDefine.c:515 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "RETURNING 목록은 conditional rule에서는 지원하지 않습니다" + +#: rewrite/rewriteDefine.c:519 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "RETURNING 목록은 non-INSTEAD rule에서는 지원하지 않습니다" + +#: rewrite/rewriteDefine.c:683 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "SELECT 룰(rule)의 대상 목록이 너무 많은 엔트리를 가지고 있습니다" + +#: rewrite/rewriteDefine.c:684 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "RETURNING 목록이 너무 많은 항목를 가지고 있습니다" + +#: rewrite/rewriteDefine.c:711 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "뷰에서 삭제된 칼럼을 포함하고 있는 릴레이션을 변환할 수 없습니다" + +#: rewrite/rewriteDefine.c:712 +#, c-format +msgid "" +"cannot create a RETURNING list for a relation containing dropped columns" +msgstr "" +"릴레이션에 삭제된 칼럼을 포함하고 있는 RETURNING 목록을 만들 수 없습니다." + +#: rewrite/rewriteDefine.c:718 +#, c-format +msgid "" +"SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "SELECT 룰(rule)의 대상 엔트리 번호가(%d)가 \"%s\" 칼럼 이름과 틀립니다" + +#: rewrite/rewriteDefine.c:720 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECT 대상 엔트리 이름은 \"%s\" 입니다." + +#: rewrite/rewriteDefine.c:729 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "SELECT 룰(rule)의 대상 엔트리 번호(%d)가 \"%s\" 칼럼 자료형과 틀립니다" + +#: rewrite/rewriteDefine.c:731 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "RETURNING 목록의 %d번째 항목의 자료형이 \"%s\" 칼럼 자료형과 틀립니다" + +#: rewrite/rewriteDefine.c:734 rewrite/rewriteDefine.c:758 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECT 대상 엔트리 자료형은 %s 형이지만, 칼럼 자료형은 %s 형입니다." + +#: rewrite/rewriteDefine.c:737 rewrite/rewriteDefine.c:762 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "RETURNING 목록은 %s 자료형이지만, 칼럼 자료형은 %s 형입니다." + +#: rewrite/rewriteDefine.c:753 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "SELECT 룰(rule)의 대상 엔트리 번호(%d)가 \"%s\" 칼럼 크기와 틀립니다" + +#: rewrite/rewriteDefine.c:755 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "RETURNING 목록의 %d번째 항목의 크기가 \"%s\" 칼럼 크기와 틀립니다" + +#: rewrite/rewriteDefine.c:772 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "SELECT 룰(rule)의 대상 목록이 너무 적은 엔트리를 가지고 있습니다" + +#: rewrite/rewriteDefine.c:773 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "RETURNING 목록에 너무 적은 항목이 있습니다" + +#: rewrite/rewriteDefine.c:866 rewrite/rewriteDefine.c:980 +#: rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr " \"%s\" 룰(rule)이 \"%s\" 관계(relation)에 지정된 것이 없음" + +#: rewrite/rewriteDefine.c:999 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "ON SELECT 룰의 이름 바꾸기는 허용하지 않습니다" + +#: rewrite/rewriteHandler.c:545 +#, c-format +msgid "" +"WITH query name \"%s\" appears in both a rule action and the query being " +"rewritten" +msgstr "" + +#: rewrite/rewriteHandler.c:605 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "multiple rule에 RETURNING 목록을 지정할 수 없습니다" + +#: rewrite/rewriteHandler.c:816 rewrite/rewriteHandler.c:828 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "\"%s\" 칼럼에 자료를 입력할 수 없습니다" + +#: rewrite/rewriteHandler.c:817 rewrite/rewriteHandler.c:839 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "" + +#: rewrite/rewriteHandler.c:819 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "" + +#: rewrite/rewriteHandler.c:838 rewrite/rewriteHandler.c:845 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "\"%s\" 칼럼은 DEFAULT 로만 업데이트 가능합니다" + +#: rewrite/rewriteHandler.c:1014 rewrite/rewriteHandler.c:1032 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "같은 \"%s\" 열에 지정값(assignment)이 중복되었습니다" + +#: rewrite/rewriteHandler.c:2062 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "\"%s\" 릴레이션의 정책에서 무한 재귀 호출이 발견 됨" + +#: rewrite/rewriteHandler.c:2382 +msgid "Junk view columns are not updatable." +msgstr "정크 뷰 칼럼은 업데이트할 수 없습니다." + +#: rewrite/rewriteHandler.c:2387 +msgid "" +"View columns that are not columns of their base relation are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2390 +msgid "View columns that refer to system columns are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2393 +msgid "View columns that return whole-row references are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2454 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2457 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2460 +msgid "Views containing HAVING are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2463 +msgid "" +"Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2466 +msgid "Views containing WITH are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2469 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2481 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2484 +msgid "Views that return window functions are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2487 +msgid "" +"Views that return set-returning functions are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2494 rewrite/rewriteHandler.c:2498 +#: rewrite/rewriteHandler.c:2506 +msgid "" +"Views that do not select from a single table or view are not automatically " +"updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2509 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2533 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:3010 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "\"%s\" 칼럼 (해당 뷰: \"%s\")에 자료를 입력할 수 없습니다" + +#: rewrite/rewriteHandler.c:3018 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "\"%s\" 칼럼 (해당 뷰: \"%s\")에 자료를 갱신할 수 없습니다" + +#: rewrite/rewriteHandler.c:3496 +#, c-format +msgid "" +"DO INSTEAD NOTHING rules are not supported for data-modifying statements in " +"WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3510 +#, c-format +msgid "" +"conditional DO INSTEAD rules are not supported for data-modifying statements " +"in WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3514 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3519 +#, c-format +msgid "" +"multi-statement DO INSTEAD rules are not supported for data-modifying " +"statements in WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3710 rewrite/rewriteHandler.c:3718 +#: rewrite/rewriteHandler.c:3726 +#, c-format +msgid "" +"Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "" +"선택적 DO INSTEAD 룰을 포함한 뷰는 자동 업데이트 기능을 사용할 수 없습니다." + +#: rewrite/rewriteHandler.c:3819 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "\"%s\" 릴레이션에서 INSERT RETURNING 관련을 구성할 수 없음" + +#: rewrite/rewriteHandler.c:3821 +#, c-format +msgid "" +"You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "" +"RETURNING 절에서는 무조건 ON INSERT DO INSTEAD 속성으로 rule이 사용되어야합니" +"다." + +#: rewrite/rewriteHandler.c:3826 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "\"%s\" 릴레이션에서 UPDATE RETURNING 관련을 구성할 수 없습니다." + +#: rewrite/rewriteHandler.c:3828 +#, c-format +msgid "" +"You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "" +"RETURNING 절에서는 무조건 ON UPDATE DO INSTEAD 속성으로 rule이 사용되어야합니" +"다." + +#: rewrite/rewriteHandler.c:3833 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "\"%s\" 릴레이션에서 DELETE RETURNING 관련을 구성할 수 없습니다." + +#: rewrite/rewriteHandler.c:3835 +#, c-format +msgid "" +"You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "" +"TURNING 절에서는 무조건 ON DELETE DO INSTEAD 속성으로 rule이 사용되어야합니다" + +#: rewrite/rewriteHandler.c:3853 +#, c-format +msgid "" +"INSERT with ON CONFLICT clause cannot be used with table that has INSERT or " +"UPDATE rules" +msgstr "" + +#: rewrite/rewriteHandler.c:3910 +#, c-format +msgid "" +"WITH cannot be used in a query that is rewritten by rules into multiple " +"queries" +msgstr "" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "" +"조건 유틸리티 명령 구문(conditional utility statement)은 구현되어있지 않습니" +"다" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "뷰에 대한 WHERE CURRENT OF 구문이 구현되지 않음" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "" +"NEW variables in ON UPDATE rules cannot reference columns that are part of a " +"multiple assignment in the subject UPDATE command" +msgstr "" + +#: snowball/dict_snowball.c:199 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "\"%s\" 언어 및 \"%s\" 인코딩에 사용 가능한 Snowball stemmer가 없음" + +#: snowball/dict_snowball.c:222 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "StopWords 매개 변수가 여러 개 있음" + +#: snowball/dict_snowball.c:231 +#, c-format +msgid "multiple Language parameters" +msgstr "여러 개의 언어 매개 변수가 있음" + +#: snowball/dict_snowball.c:238 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "인식할 수 없는 Snowball 매개 변수: \"%s\"" + +#: snowball/dict_snowball.c:246 +#, c-format +msgid "missing Language parameter" +msgstr "Language 매개 변수가 누락됨" + +#: statistics/dependencies.c:667 statistics/dependencies.c:720 +#: statistics/mcv.c:1477 statistics/mcv.c:1508 statistics/mvdistinct.c:348 +#: statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:42 +#: utils/adt/pseudotypes.c:76 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "%s 형식의 값은 사용할 수 없음" + +#: statistics/extended_stats.c:145 +#, c-format +msgid "" +"statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "\"%s.%s\" 통계정보 개체를 계산 할 수 없음: 대상 릴레이션: \"%s.%s\"" + +#: statistics/mcv.c:1365 utils/adt/jsonfuncs.c:1800 +#, c-format +msgid "" +"function returning record called in context that cannot accept type record" +msgstr "반환 자료형이 record인데 함수가 그 자료형으로 반환하지 않음" + +#: storage/buffer/bufmgr.c:588 storage/buffer/bufmgr.c:669 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "다른 세션의 임시 테이블에 액세스할 수 없음" + +#: storage/buffer/bufmgr.c:825 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "%u 블록(해당 릴레이션: %s)에 EOF 범위를 넘는 예기치 않은 데이터가 있음" + +#: storage/buffer/bufmgr.c:827 +#, c-format +msgid "" +"This has been seen to occur with buggy kernels; consider updating your " +"system." +msgstr "이 문제는 커널의 문제로 알려졌습니다. 시스템을 업데이트하십시오." + +#: storage/buffer/bufmgr.c:925 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "" +"%u 블록(해당 릴레이션: %s)에 잘못된 페이지 헤더가 있음, 페이지를 삭제하는 중" + +#: storage/buffer/bufmgr.c:4211 +#, c-format +msgid "could not write block %u of %s" +msgstr "%u/%s 블록을 쓸 수 없음" + +#: storage/buffer/bufmgr.c:4213 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "여러 번 실패 --- 쓰기 오류가 영구적일 수 있습니다." + +#: storage/buffer/bufmgr.c:4234 storage/buffer/bufmgr.c:4253 +#, c-format +msgid "writing block %u of relation %s" +msgstr "%u 블록(해당 릴레이션: %s)을 쓰는 중" + +#: storage/buffer/bufmgr.c:4556 +#, c-format +msgid "snapshot too old" +msgstr "" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "비어 있는 로컬 버퍼가 없습니다" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "병렬 작업 중에 임시 테이블에 액세스할 수 없음" + +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "\"%s\" 임시 파일을 열 수 없음, 버퍼파일: \"%s\": %m" + +#: storage/file/buffile.c:795 +#, c-format +msgid "" +"could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "\"%s\" 임시 파일의 크기를 알 수 없음, 버퍼파일: \"%s\": %m" + +#: storage/file/fd.c:508 storage/file/fd.c:580 storage/file/fd.c:616 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "dirty 자료를 flush 할 수 없음: %m" + +#: storage/file/fd.c:538 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "dirty 자료 크기를 확인할 수 없음: %m" + +#: storage/file/fd.c:590 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "자료 flush 작업 도중 munmap() 호출 실패: %m" + +#: storage/file/fd.c:798 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "\"%s\" 파일을 \"%s\" 파일로 링크할 수 없음: %m" + +#: storage/file/fd.c:881 +#, c-format +msgid "getrlimit failed: %m" +msgstr "getrlimit 실패: %m" + +#: storage/file/fd.c:971 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "" +"서버 프로세스를 실행하기 위해서 열어야할 파일들을 못 열고 있습니다. 다른 프로" +"그램에서 너무 많은 파일을 열어 두고 있습니다. 다른 프로그램들을 좀 닫고 다시 " +"시도해 보십시오" + +#: storage/file/fd.c:972 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "시스템 허용치 %d, 서버 최소 허용치 %d." + +#: storage/file/fd.c:1023 storage/file/fd.c:2357 storage/file/fd.c:2467 +#: storage/file/fd.c:2618 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "" +"열려 있는 파일이 너무 많습니다: %m; 다른 프로그램들을 좀 닫고 다시 시도해 보" +"십시오" + +#: storage/file/fd.c:1397 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "임시 파일: 경로 \"%s\", 크기 %lu" + +#: storage/file/fd.c:1528 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "\"%s\" 임시 디렉터리를 만들 수 없음: %m" + +#: storage/file/fd.c:1535 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "\"%s\" 임시 하위 디렉터리를 만들 수 없음: %m" + +#: storage/file/fd.c:1728 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "\"%s\" 임시 파일을 만들 수 없습니다: %m" + +#: storage/file/fd.c:1763 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "\"%s\" 임시 파일을 열 수 없음: %m" + +#: storage/file/fd.c:1804 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "\"%s\" 임시 파일을 지울 수 없음: %m" + +#: storage/file/fd.c:2068 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "임시 파일 크기가 temp_file_limit (%dkB)를 초과했습니다" + +#: storage/file/fd.c:2333 storage/file/fd.c:2392 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "" + +#: storage/file/fd.c:2437 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "" + +#: storage/file/fd.c:2594 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "" + +#: storage/file/fd.c:3122 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "임시 디렉터리에서 예상치 못한 파일 발견: \"%s\"" + +#: storage/file/sharedfileset.c:111 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "SharedFileSet 확보 실패, 이미 삭제되었음" + +#: storage/ipc/dsm.c:338 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "동적 공유 메모리 제어 조각이 손상되었음" + +#: storage/ipc/dsm.c:399 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "동적 공유 메모리 제어 조각이 타당하지 않음" + +#: storage/ipc/dsm.c:494 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "너무 많은 동적 공유 메모리 조각이 있음" + +#: storage/ipc/dsm_impl.c:230 storage/ipc/dsm_impl.c:526 +#: storage/ipc/dsm_impl.c:630 storage/ipc/dsm_impl.c:801 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 조각을 unmap 할 수 없음: %m" + +#: storage/ipc/dsm_impl.c:240 storage/ipc/dsm_impl.c:536 +#: storage/ipc/dsm_impl.c:640 storage/ipc/dsm_impl.c:811 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 조각을 삭제할 수 없음: %m" + +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:711 +#: storage/ipc/dsm_impl.c:825 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 조각을 열 수 없음: %m" + +#: storage/ipc/dsm_impl.c:289 storage/ipc/dsm_impl.c:552 +#: storage/ipc/dsm_impl.c:756 storage/ipc/dsm_impl.c:849 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 조각 파일의 상태를 알 수 없음: %m" + +#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:900 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "\"%s\" 공유 메모리 조각 파일을 %zu 바이트로 크기 조절 할 수 없음: %m" + +#: storage/ipc/dsm_impl.c:338 storage/ipc/dsm_impl.c:573 +#: storage/ipc/dsm_impl.c:732 storage/ipc/dsm_impl.c:922 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 조각을 map 할 수 없음: %m" + +#: storage/ipc/dsm_impl.c:508 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "공유 메모리 조각을 가져올 수 없음: %m" + +#: storage/ipc/dsm_impl.c:696 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 조각을 만들 수 없음: %m" + +#: storage/ipc/dsm_impl.c:933 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 조각을 닫을 수 없음: %m" + +#: storage/ipc/dsm_impl.c:972 storage/ipc/dsm_impl.c:1020 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "\"%s\" 용 헨들러를 이중화 할 수 없음: %m" + +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:940 storage/ipc/latch.c:1094 storage/ipc/latch.c:1307 +#: storage/ipc/latch.c:1457 storage/ipc/latch.c:1570 +#, c-format +msgid "%s failed: %m" +msgstr "%s 실패: %m" + +#: storage/ipc/procarray.c:3014 +#, c-format +msgid "database \"%s\" is being used by prepared transactions" +msgstr "\"%s\" 데이터베이스가 미리 준비된 트랜잭션에서 사용중임" + +#: storage/ipc/procarray.c:3046 storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "슈퍼유저의 세션을 정리하려면 슈퍼유저여야 합니다." + +#: storage/ipc/procarray.c:3053 storage/ipc/signalfuncs.c:147 +#, c-format +msgid "" +"must be a member of the role whose process is being terminated or member of " +"pg_signal_backend" +msgstr "" +"세션을 종료하려면 접속자의 소속 맴버이거나 pg_signal_backend 소속 맴버여야 합" +"니다" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:982 +#: storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 storage/lmgr/lock.c:4175 +#: storage/lmgr/lock.c:4240 storage/lmgr/lock.c:4532 +#: storage/lmgr/predicate.c:2401 storage/lmgr/predicate.c:2416 +#: storage/lmgr/predicate.c:3898 storage/lmgr/predicate.c:5009 +#: utils/hash/dynahash.c:1067 +#, c-format +msgid "out of shared memory" +msgstr "공유 메모리 부족" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "공유 메모리가 부족함 (%zu 바이트가 필요함)" + +#: storage/ipc/shmem.c:441 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "\"%s\" 자료 구조체용 ShmemIndex 항목을 만들 수 없음" + +#: storage/ipc/shmem.c:456 +#, c-format +msgid "" +"ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, " +"actual %zu" +msgstr "" +"\"%s\" 자료 구조체용 ShmemIndex 항목 크기가 잘못됨: 기대값 %zu, 현재값 %zu" + +#: storage/ipc/shmem.c:475 +#, c-format +msgid "" +"not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "\"%s\" 자료 구조체용 공유 메모리가 부족함 (%zu 바이트가 필요함)" + +#: storage/ipc/shmem.c:507 storage/ipc/shmem.c:526 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "지정한 공유 메모리 사이즈가 size_t 크기를 초과했습니다" + +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d 프로그램은 PostgreSQL 서버 프로세스가 아닙니다" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1366 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "%d 프로세스로 시스템신호(signal)를 보낼 수 없습니다: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "슈퍼유저의 쿼리를 중지하려면 슈퍼유저여야 합니다." + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "" +"must be a member of the role whose query is being canceled or member of " +"pg_signal_backend" +msgstr "" +"쿼리 작업 취소하려면 작업자의 소속 맴버이거나 pg_signal_backend 소속 맴버여" +"야 합니다" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "" +"adminpack 1.0 확장 모듈을 사용하면 로그 전환하려면 슈퍼유저여야 합니다." + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:253 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "대신에 %s 내장 함수를 사용할 것을 권고합니다." + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "로그 수집이 활성 상태가 아니므로 회전할 수 없음" + +#: storage/ipc/standby.c:580 tcop/postgres.c:3177 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "복구 작업 중 충돌이 발생해 작업을 중지합니다." + +#: storage/ipc/standby.c:581 tcop/postgres.c:2469 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "복구 작업 중 사용자 트랜잭션이 버퍼 데드락을 만들었습니다." + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "대형 개체를 열기 위한 플래그가 잘못 됨: %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "유효하지 않은 대형 개체의 쓰기 요청된 크기: %d" + +#: storage/lmgr/deadlock.c:1124 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "" +"%d 프로세스가 %s 상태로 지연되고 있음(해당 작업: %s); %d 프로세스에 의해 블록" +"킹되었음" + +#: storage/lmgr/deadlock.c:1143 +#, c-format +msgid "Process %d: %s" +msgstr "프로세스 %d: %s" + +#: storage/lmgr/deadlock.c:1152 +#, c-format +msgid "deadlock detected" +msgstr "deadlock 발생했음" + +#: storage/lmgr/deadlock.c:1155 +#, c-format +msgid "See server log for query details." +msgstr "쿼리 상세 정보는 서버 로그를 참조하십시오." + +#: storage/lmgr/lmgr.c:830 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플(해당 릴레이션 \"%s\")을 갱신하는 중에 발생" + +#: storage/lmgr/lmgr.c:833 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플(해당 릴레이션 \"%s\")을 삭제하는 중에 발생" + +#: storage/lmgr/lmgr.c:836 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플을 \"%s\" 릴레이션에서 잠그는 중에 발생" + +#: storage/lmgr/lmgr.c:839 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "%u,%u 업데이트된 버전 튜플(해당 릴레이션 \"%s\")을 잠그는 중에 발생" + +#: storage/lmgr/lmgr.c:842 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플 인덱스(해당 릴레이션 \"%s\")를 삽입하는 중에 발생" + +#: storage/lmgr/lmgr.c:845 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플(해당 릴레이션: \"%s\")의 고유성을 검사하는 중에 발생" + +#: storage/lmgr/lmgr.c:848 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 갱신된 튜플(해당 릴레이션: \"%s\")을 재확인하는 중에 발생" + +#: storage/lmgr/lmgr.c:851 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "" +"%u,%u 튜플(해당 릴레이션: \"%s\")의 제외 제약 조건을 검사하는 중에 발생" + +#: storage/lmgr/lmgr.c:1106 +#, c-format +msgid "relation %u of database %u" +msgstr "릴레이션 %u, 데이터베이스 %u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "%u 관계(%u 데이터베이스) 확장" + +#: storage/lmgr/lmgr.c:1118 +#, c-format +msgid "pg_database.datfrozenxid of database %u" +msgstr "데이터베이스 %u의 pg_database.datfrozenxid" + +#: storage/lmgr/lmgr.c:1123 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "페이지 %u, 릴레이션 %u, 데이터베이스 %u" + +#: storage/lmgr/lmgr.c:1130 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "튜플 (%u,%u), 릴레이션 %u, 데이터베이스 %u" + +#: storage/lmgr/lmgr.c:1138 +#, c-format +msgid "transaction %u" +msgstr "트랜잭션 %u" + +#: storage/lmgr/lmgr.c:1143 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "가상 트랜잭션 %d/%u" + +#: storage/lmgr/lmgr.c:1149 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "%u 위험한 토큰, 대상 트랜잭션 %u" + +#: storage/lmgr/lmgr.c:1155 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "개체 %u, 클래스 %u, 데이터베이스 %u" + +#: storage/lmgr/lmgr.c:1163 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "user lock [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1170 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "advisory lock [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1178 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "알 수 없는 locktag 형태 %d" + +#: storage/lmgr/lock.c:803 +#, c-format +msgid "" +"cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "" + +#: storage/lmgr/lock.c:805 +#, c-format +msgid "" +"Only RowExclusiveLock or less can be acquired on database objects during " +"recovery." +msgstr "" + +#: storage/lmgr/lock.c:983 storage/lmgr/lock.c:1021 storage/lmgr/lock.c:2846 +#: storage/lmgr/lock.c:4176 storage/lmgr/lock.c:4241 storage/lmgr/lock.c:4533 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "max_locks_per_transaction을 늘려야 할 수도 있습니다." + +#: storage/lmgr/lock.c:3292 storage/lmgr/lock.c:3408 +#, c-format +msgid "" +"cannot PREPARE while holding both session-level and transaction-level locks " +"on the same object" +msgstr "" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "" +"You might need to run fewer transactions at a time or increase " +"max_connections." +msgstr "" + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "" +"not enough elements in RWConflictPool to record a potential read/write " +"conflict" +msgstr "" + +#: storage/lmgr/predicate.c:1535 +#, c-format +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "" + +#: storage/lmgr/predicate.c:1624 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "" + +#: storage/lmgr/predicate.c:1625 +#, c-format +msgid "" +"You can use \"SET default_transaction_isolation = 'repeatable read'\" to " +"change the default." +msgstr "" + +#: storage/lmgr/predicate.c:1676 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "" + +#: storage/lmgr/predicate.c:1755 utils/time/snapmgr.c:623 +#: utils/time/snapmgr.c:629 +#, c-format +msgid "could not import the requested snapshot" +msgstr "" + +#: storage/lmgr/predicate.c:1756 utils/time/snapmgr.c:630 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "%d PID 소스 프로세스는 더이상 실행 중이지 않습니다." + +#: storage/lmgr/predicate.c:2402 storage/lmgr/predicate.c:2417 +#: storage/lmgr/predicate.c:3899 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "max_pred_locks_per_transaction 값을 늘려야 할 수도 있습니다." + +#: storage/lmgr/predicate.c:4030 storage/lmgr/predicate.c:4066 +#: storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4107 +#: storage/lmgr/predicate.c:4146 storage/lmgr/predicate.c:4388 +#: storage/lmgr/predicate.c:4725 storage/lmgr/predicate.c:4737 +#: storage/lmgr/predicate.c:4780 storage/lmgr/predicate.c:4818 +#, c-format +msgid "" +"could not serialize access due to read/write dependencies among transactions" +msgstr "트랜잭션간 읽기/쓰기 의존성 때문에 serialize 접근을 할 수 없음" + +#: storage/lmgr/predicate.c:4032 storage/lmgr/predicate.c:4068 +#: storage/lmgr/predicate.c:4101 storage/lmgr/predicate.c:4109 +#: storage/lmgr/predicate.c:4148 storage/lmgr/predicate.c:4390 +#: storage/lmgr/predicate.c:4727 storage/lmgr/predicate.c:4739 +#: storage/lmgr/predicate.c:4782 storage/lmgr/predicate.c:4820 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "재시도하면 그 트랜잭션이 성공할 것입니다." + +#: storage/lmgr/proc.c:358 +#, c-format +msgid "" +"number of requested standby connections exceeds max_wal_senders (currently " +"%d)" +msgstr "대기 서버 연결 수가 max_wal_senders 설정값(현재 %d)을 초과했습니다" + +#: storage/lmgr/proc.c:1337 +#, c-format +msgid "Process %d waits for %s on %s." +msgstr "%d 프로세스가 대기중, 잠금종류: %s, 내용: %s" + +#: storage/lmgr/proc.c:1348 +#, c-format +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "%d PID autovacuum 블럭킹하기 위해 취소 신호를 보냅니다" + +#: storage/lmgr/proc.c:1468 +#, c-format +msgid "" +"process %d avoided deadlock for %s on %s by rearranging queue order after " +"%ld.%03d ms" +msgstr "" +"%d PID 프로세스는 %s(%s)에 대해 교착 상태가 발생하지 않도록 %ld.%03dms 후에 " +"대기열 순서를 다시 조정함" + +#: storage/lmgr/proc.c:1483 +#, c-format +msgid "" +"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "%d PID 프로세스에서 %s(%s) 대기중 %ld.%03dms 후에 교착 상태를 감지함" + +#: storage/lmgr/proc.c:1492 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "%d PID 프로세스에서 여전히 %s(%s) 작업을 기다리고 있음(%ld.%03dms 후)" + +#: storage/lmgr/proc.c:1499 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "%d PID 프로세스가 %s(%s) 작업을 위해 잠금 취득함(%ld.%03dms 후)" + +#: storage/lmgr/proc.c:1515 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "프로세스 %d에서 %s(%s)을(를) 취득하지 못함(%ld.%03dms 후)" + +#: storage/page/bufpage.c:145 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "페이지 검사 실패, 계산된 체크섬은 %u, 기대값은 %u" + +#: storage/page/bufpage.c:209 storage/page/bufpage.c:503 +#: storage/page/bufpage.c:740 storage/page/bufpage.c:873 +#: storage/page/bufpage.c:969 storage/page/bufpage.c:1081 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "손상된 페이지 위치: 하위값 = %u, 상위값 = %u, 특수값 = %u" + +#: storage/page/bufpage.c:525 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "손상된 줄 위치: %u" + +#: storage/page/bufpage.c:552 storage/page/bufpage.c:924 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "손상된 아이템 길이: 전체 %u, 사용가능한 공간 %u" + +#: storage/page/bufpage.c:759 storage/page/bufpage.c:897 +#: storage/page/bufpage.c:985 storage/page/bufpage.c:1097 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "손상된 줄 위치: 오프셋 = %u, 크기 = %u" + +#: storage/smgr/md.c:333 storage/smgr/md.c:836 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "\"%s\" 파일을 비울 수 없음: %m" + +#: storage/smgr/md.c:407 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "\"%s\" 파일을 %u개 블록을 초과하여 확장할 수 없음" + +#: storage/smgr/md.c:422 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "\"%s\" 파일을 확장할 수 없음: %m" + +#: storage/smgr/md.c:424 storage/smgr/md.c:431 storage/smgr/md.c:719 +#, c-format +msgid "Check free disk space." +msgstr "디스크 여유 공간을 확인해 주십시오." + +#: storage/smgr/md.c:428 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "\"%s\" 파일을 확장할 수 없음: %d/%d바이트만 %u 블록에 썼음" + +#: storage/smgr/md.c:640 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "%u 블럭을 \"%s\" 파일에서 읽을 수 없음: %m" + +#: storage/smgr/md.c:656 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "%u 블럭을 \"%s\" 파일에서 읽을 수 없음: %d / %d 바이트만 읽음" + +#: storage/smgr/md.c:710 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "%u 블럭을 \"%s\" 파일에 쓸 수 없음: %m" + +#: storage/smgr/md.c:715 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "%u 블럭을 \"%s\" 파일에 쓸 수 없음: %d / %d 바이트만 씀" + +#: storage/smgr/md.c:807 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "\"%s\" 파일을 %u 블럭으로 비울 수 없음: 현재 %u 블럭 뿐 임" + +#: storage/smgr/md.c:862 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "\"%s\" 파일을 %u 블럭으로 정리할 수 없음: %m" + +#: storage/smgr/md.c:957 +#, c-format +msgid "could not forward fsync request because request queue is full" +msgstr "요청 큐가 가득차 forward fsync 요청을 처리할 수 없음" + +#: storage/smgr/md.c:1256 +#, c-format +msgid "" +"could not open file \"%s\" (target block %u): previous segment is only %u " +"blocks" +msgstr "\"%s\" 파일을 열기 실패(대상 블록: %u): 이전 조각은 %u 블럭 뿐임" + +#: storage/smgr/md.c:1270 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "\"%s\" 파일을 열기 실패(대상 블록: %u): %m" + +#: storage/sync/sync.c:401 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "\"%s\" 파일 fsync 실패, 재시도함: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "함수 호출 메시지 안에 있는 잘못된 %d 인자 크기" + +#: tcop/fastpath.c:307 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "fastpath 함수 호출: \"%s\" (OID %u)" + +#: tcop/fastpath.c:389 tcop/postgres.c:1323 tcop/postgres.c:1581 +#: tcop/postgres.c:2013 tcop/postgres.c:2250 +#, c-format +msgid "duration: %s ms" +msgstr "실행시간: %s ms" + +#: tcop/fastpath.c:393 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "작업시간: %s ms fastpath 함수 호출: \"%s\" (OID %u)" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "함수 호출 메시지는 %d 인자를 사용하지만, 함수는 %d 인자가 필요합니다" + +#: tcop/fastpath.c:437 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "함수 호출 메시지는 %d 인자를 사용하지만, 함수는 %d 인자가 필요합니다" + +#: tcop/fastpath.c:524 tcop/fastpath.c:607 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "함수 인자 %d 안에 잘못된 바이너리 자료 형식 발견됨" + +#: tcop/postgres.c:355 tcop/postgres.c:391 tcop/postgres.c:418 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "클라이언트 연결에서 예상치 않은 EOF 발견됨" + +#: tcop/postgres.c:441 tcop/postgres.c:453 tcop/postgres.c:464 +#: tcop/postgres.c:476 tcop/postgres.c:4539 +#, c-format +msgid "invalid frontend message type %d" +msgstr "잘못된 frontend 메시지 형태 %d" + +#: tcop/postgres.c:1042 +#, c-format +msgid "statement: %s" +msgstr "명령 구문: %s" + +#: tcop/postgres.c:1328 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "실행시간: %s ms 명령 구문: %s" + +#: tcop/postgres.c:1377 +#, c-format +msgid "parse %s: %s" +msgstr "구문 %s: %s" + +#: tcop/postgres.c:1434 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "준비된 명령 구문에는 다중 명령을 삽입할 수 없습니다" + +#: tcop/postgres.c:1586 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "실행시간: %s ms %s 구문분석: %s" + +#: tcop/postgres.c:1633 +#, c-format +msgid "bind %s to %s" +msgstr "바인드: %s -> %s" + +#: tcop/postgres.c:1652 tcop/postgres.c:2516 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "이름없는 준비된 명령 구문(unnamed prepared statement) 없음" + +#: tcop/postgres.c:1693 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "바인드 메시지는 %d 매개 변수 형태지만, %d 매개 변수여야함" + +#: tcop/postgres.c:1699 +#, c-format +msgid "" +"bind message supplies %d parameters, but prepared statement \"%s\" requires " +"%d" +msgstr "" +"바인드 메시지는 %d개의 매개 변수를 지원하지만, \"%s\" 준비된 명령 구문" +"(prepared statement)에서는%d 개의 매개 변수가 필요합니다" + +#: tcop/postgres.c:1897 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "바인드 매개 변수 %d 안에 잘못된 바이너리 자료 형태가 있음" + +#: tcop/postgres.c:2018 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "실행시간: %s ms %s%s%s 접속: %s" + +#: tcop/postgres.c:2068 tcop/postgres.c:2600 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "\"%s\" portal 없음" + +#: tcop/postgres.c:2153 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2155 tcop/postgres.c:2258 +msgid "execute fetch from" +msgstr "자료뽑기" + +#: tcop/postgres.c:2156 tcop/postgres.c:2259 +msgid "execute" +msgstr "쿼리실행" + +#: tcop/postgres.c:2255 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "수행시간: %s ms %s %s%s%s: %s" + +#: tcop/postgres.c:2401 +#, c-format +msgid "prepare: %s" +msgstr "prepare: %s" + +#: tcop/postgres.c:2426 +#, c-format +msgid "parameters: %s" +msgstr "매개 변수: %s" + +#: tcop/postgres.c:2441 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "중지 이유: 복구 충돌" + +#: tcop/postgres.c:2457 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "" + +#: tcop/postgres.c:2460 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "" + +#: tcop/postgres.c:2463 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "" + +#: tcop/postgres.c:2466 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "" + +#: tcop/postgres.c:2472 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "삭제 되어져야할 데이터베이스 사용자 접속해 있습니다." + +#: tcop/postgres.c:2796 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "다른 서버 프로세스가 손상을 입어 현재 연결을 중지합니다" + +#: tcop/postgres.c:2797 +#, c-format +msgid "" +"The postmaster has commanded this server process to roll back the current " +"transaction and exit, because another server process exited abnormally and " +"possibly corrupted shared memory." +msgstr "" +"postmaster 에서 현재 이서버 프로세스에게 현재 트랜잭션을 취소하고, 클라이언트" +"와의 연결을 끊으라는 명령을 보냈습니다. 왜냐하면, 다른 서버 프로세스가 비정상" +"적으로 중지되어 공유 메모리가 손상되었을 가능성이 있기 때문입니다" + +#: tcop/postgres.c:2801 tcop/postgres.c:3107 +#, c-format +msgid "" +"In a moment you should be able to reconnect to the database and repeat your " +"command." +msgstr "잠시 뒤에 다시 연결 해서 작업을 계속 하십시오" + +#: tcop/postgres.c:2883 +#, c-format +msgid "floating-point exception" +msgstr "부동소수점 예외발생" + +#: tcop/postgres.c:2884 +#, c-format +msgid "" +"An invalid floating-point operation was signaled. This probably means an out-" +"of-range result or an invalid operation, such as division by zero." +msgstr "" +"잘못된 부동소수점 작업이 감지 되었습니다. 이것은 아마도 결과값 범위초과나 0으" +"로 나누는 작업과 같은 잘못된 연산 때문에 발생한 것 같습니다" + +#: tcop/postgres.c:3037 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "시간 초과로 인증 작업을 취소합니다." + +#: tcop/postgres.c:3041 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "관리자 명령으로 인해 자동 청소 프로세스를 종료하는 중" + +#: tcop/postgres.c:3045 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "관리자 요청에 의해서 논리 복제 작업자를 끝냅니다" + +#: tcop/postgres.c:3049 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "논리 복제 관리자를 중지하고 있습니다" + +#: tcop/postgres.c:3062 tcop/postgres.c:3072 tcop/postgres.c:3105 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "복구 작업 중 충돌로 연결을 종료합니다." + +#: tcop/postgres.c:3078 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "관리자 요청에 의해서 연결을 끝냅니다" + +#: tcop/postgres.c:3088 +#, c-format +msgid "connection to client lost" +msgstr "서버로부터 연결이 끊어졌습니다." + +#: tcop/postgres.c:3154 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "잠금 대기 시간 초과로 작업을 취소합니다." + +#: tcop/postgres.c:3161 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "명령실행시간 초과로 작업을 취소합니다." + +#: tcop/postgres.c:3168 +#, c-format +msgid "canceling autovacuum task" +msgstr "자동 청소 작업을 취소하는 중" + +#: tcop/postgres.c:3191 +#, c-format +msgid "canceling statement due to user request" +msgstr "사용자 요청에 의해 작업을 취소합니다." + +#: tcop/postgres.c:3201 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "idle-in-transaction 시간 초과로 연결을 끝냅니다" + +#: tcop/postgres.c:3318 +#, c-format +msgid "stack depth limit exceeded" +msgstr "스택 깊이를 초과했습니다" + +#: tcop/postgres.c:3319 +#, c-format +msgid "" +"Increase the configuration parameter \"max_stack_depth\" (currently %dkB), " +"after ensuring the platform's stack depth limit is adequate." +msgstr "" +"먼저 OS에서 지원하는 스택 depth 최대값을 확인한 뒤, 허용범위 안에서 " +"\"max_stack_depth\" (현재값: %dkB) 매개 변수 값의 설정치를 증가시키세요." + +#: tcop/postgres.c:3382 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "\"max_stack_depth\" 값은 %ldkB를 초과할 수 없습니다" + +#: tcop/postgres.c:3384 +#, c-format +msgid "" +"Increase the platform's stack depth limit via \"ulimit -s\" or local " +"equivalent." +msgstr "OS의 \"ulimit -s\" 명령과 같은 것으로 스택 깊이를 늘려주십시오." + +#: tcop/postgres.c:3744 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "서버 프로세스의 명령행 인자가 잘못되었습니다: %s" + +#: tcop/postgres.c:3745 tcop/postgres.c:3751 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "자세한 사항은 \"%s --help\" 명령으로 살펴보세요." + +#: tcop/postgres.c:3749 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: 잘못된 명령행 인자: %s" + +#: tcop/postgres.c:3811 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: 데이터베이스와 사용자를 지정하지 않았습니다" + +#: tcop/postgres.c:4447 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "잘못된 CLOSE 메시지 서브타입 %d" + +#: tcop/postgres.c:4482 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "잘못된 DESCRIBE 메시지 서브타입 %d" + +#: tcop/postgres.c:4560 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "복제 연결에서는 fastpath 함수 호출을 지원하지 않습니다" + +#: tcop/postgres.c:4564 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "" + +#: tcop/postgres.c:4741 +#, c-format +msgid "" +"disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s" +"%s" +msgstr "" +"연결종료: 세션 시간: %d:%02d:%02d.%03d 사용자=%s 데이터베이스=%s 호스트=%s%s" +"%s" + +#: tcop/pquery.c:629 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "" +"바인드 메시지는 %d 결과 포멧을 가지고 있고, 쿼리는 %d 칼럼을 가지고 있습니다" + +#: tcop/pquery.c:932 +#, c-format +msgid "cursor can only scan forward" +msgstr "이 커서는 앞으로 이동 전용입니다" + +#: tcop/pquery.c:933 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "" +"뒤로 이동 가능한 커서를 만드려면 SCROLL 옵션을 추가해서 커서를 만드세요." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:413 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "읽기 전용 트랜잭션에서는 %s 명령을 실행할 수 없습니다." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:431 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "병렬 처리 작업에서는 %s 명령을 실행할 수 없습니다." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:450 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "복구 작업 중에는 %s 명령을 실행할 수 없습니다." + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:468 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "보안 제한 작업 내에서 %s을(를) 실행할 수 없음" + +#: tcop/utility.c:912 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "CHECKPOINT 명령은 슈퍼유저만 사용할 수 있습니다" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:620 +#, c-format +msgid "multiple DictFile parameters" +msgstr "DictFile 매개 변수가 여러 개 있음" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "AffFile 매개 변수가 여러 개 있음" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "인식할 수 없는 Ispell 매개 변수: \"%s\"" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "AffFile 매개 변수가 누락됨" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:644 +#, c-format +msgid "missing DictFile parameter" +msgstr "DictFile 매개 변수가 누락됨" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "Accept 매개 변수가 여러 개 있음" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "인식할 수 없는 simple 사전 매개 변수: \"%s\"" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "인식할 수 없는 synonym 매개 변수: \"%s\"" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "Synonyms 매개 변수가 누락됨" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "\"%s\" 동의어 파일을 열 수 없음: %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "\"%s\" 기준어 파일을 열 수 없음: %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "예기치 않은 구분자" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "예기치 않은 줄 끝 또는 어휘소" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "예기치 않은 줄 끝" + +#: tsearch/dict_thesaurus.c:297 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "기준어 항목에 너무 많은 어휘소가 있음" + +#: tsearch/dict_thesaurus.c:421 +#, c-format +msgid "" +"thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "\"%s\" 기준 단어는 하위 사전에서 인식할 수 없음(규칙 %d)" + +#: tsearch/dict_thesaurus.c:427 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "\"%s\" 동의어 사전 샘플 단어는 중지 단어임(규칙 %d)" + +#: tsearch/dict_thesaurus.c:430 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "샘플 구 내에서 중지 단어를 나타내려면 \"?\"를 사용하십시오." + +#: tsearch/dict_thesaurus.c:572 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "\"%s\" 동의어 사전 대체 단어는 중지 단어임(규칙 %d)" + +#: tsearch/dict_thesaurus.c:579 +#, c-format +msgid "" +"thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "\"%s\" 동의어 사전 대체 단어는 하위 사전에서 인식할 수 없음(규칙 %d)" + +#: tsearch/dict_thesaurus.c:591 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "동의어 사전 대체 구가 비어 있음(규칙 %d)" + +#: tsearch/dict_thesaurus.c:629 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "Dictionary 매개 변수가 여러 개 있음" + +#: tsearch/dict_thesaurus.c:636 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "인식할 수 없는 Thesaurus 매개 변수: \"%s\"" + +#: tsearch/dict_thesaurus.c:648 +#, c-format +msgid "missing Dictionary parameter" +msgstr "Dictionary 매개 변수가 누락됨" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1036 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "잘못된 affix 플래그: \"%s\"" + +#: tsearch/spell.c:384 tsearch/spell.c:1040 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "affix 플래그 범위 초과: \"%s\"" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "affix 플래그에 이상한 문자가 있음: \"%s\"" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "\"%s\" 사전 파일을 열 수 없음: %m" + +#: tsearch/spell.c:742 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "잘못된 정규식: %s" + +#: tsearch/spell.c:956 tsearch/spell.c:973 tsearch/spell.c:990 +#: tsearch/spell.c:1007 tsearch/spell.c:1072 gram.y:15993 gram.y:16010 +#, c-format +msgid "syntax error" +msgstr "구문 오류" + +#: tsearch/spell.c:1163 tsearch/spell.c:1175 tsearch/spell.c:1734 +#: tsearch/spell.c:1739 tsearch/spell.c:1744 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "잘못된 affix 별칭: \"%s\"" + +#: tsearch/spell.c:1216 tsearch/spell.c:1287 tsearch/spell.c:1436 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "\"%s\" affix 파일을 열 수 없음: %m" + +#: tsearch/spell.c:1270 +#, c-format +msgid "" +"Ispell dictionary supports only \"default\", \"long\", and \"num\" flag " +"values" +msgstr "Ispell 사전은 \"default\", \"long\", \"num\" 플래그 값만 지원함" + +#: tsearch/spell.c:1314 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "잘못된 플래그 백터 별칭 개수" + +#: tsearch/spell.c:1337 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "alias 수가 지정한 %d 개수를 초과함" + +#: tsearch/spell.c:1552 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "affix 파일에 옛방식과 새방식 명령이 함께 있습니다" + +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "" +"문자열이 너무 길어서 tsvector에 사용할 수 없음(%d바이트, 최대 %d바이트)" + +#: tsearch/ts_locale.c:212 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "%d번째 줄(해당 파일: \"%s\"): \"%s\"" + +#: tsearch/ts_locale.c:329 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "wchar_t에서 서버 인코딩으로 변환하지 못함: %m" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 +#: tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "단어가 너무 길어서 인덱싱할 수 없음" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 +#: tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "%d자보다 긴 단어는 무시됩니다." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "\"%s\" 전문 검색 구성 파일 이름이 잘못됨" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "\"%s\" 중지 단어 파일을 열 수 없음: %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "전문 검색 분석기에서 헤드라인 작성을 지원하지 않음" + +#: tsearch/wparser_def.c:2585 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "인식할 수 없는 headline 매개 변수: \"%s\"" + +#: tsearch/wparser_def.c:2604 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "MinWords는 MaxWords보다 작아야 함" + +#: tsearch/wparser_def.c:2608 +#, c-format +msgid "MinWords should be positive" +msgstr "MinWords는 양수여야 함" + +#: tsearch/wparser_def.c:2612 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "ShortWord는 0보다 크거나 같아야 함" + +#: tsearch/wparser_def.c:2616 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "MaxFragments는 0보다 크거나 같아야 함" + +# # nonun 부분 begin +#: utils/adt/acl.c:172 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "식별자(identifier)가 너무 깁니다." + +#: utils/adt/acl.c:173 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "식별자(Identifier)는 %d 글자 이상일 수 없습니다." + +#: utils/adt/acl.c:256 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "알 수 없는 않은 키워드: \"%s\"" + +#: utils/adt/acl.c:257 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "ACL 키워드는 \"group\" 또는 \"user\" 중에 하나여야 합니다." + +#: utils/adt/acl.c:262 +#, c-format +msgid "missing name" +msgstr "이름이 빠졌습니다." + +#: utils/adt/acl.c:263 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "이름은 \"group\" 또는 \"user\" 키워드 뒤에 있어야 합니다." + +#: utils/adt/acl.c:269 +#, c-format +msgid "missing \"=\" sign" +msgstr "\"=\" 기호가 빠졌습니다." + +#: utils/adt/acl.c:322 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "잘못된 조건: \"%s\" 중에 한 가지여야 합니다." + +#: utils/adt/acl.c:344 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "이름은 \"/\"기호 뒤에 있어야 합니다." + +#: utils/adt/acl.c:352 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "%u 사용자 ID에서 기본 권한자로 할당하고 있습니다" + +#: utils/adt/acl.c:538 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "ACL 배열에 잘못된 자료형을 사용하고 있습니다" + +#: utils/adt/acl.c:542 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "ACL 배열은 일차원 배열이어야합니다" + +#: utils/adt/acl.c:546 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "ACL 배열에는 null 값을 포함할 수 없습니다" + +#: utils/adt/acl.c:570 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "ACL 설정 정보 끝에 끝에 쓸모 없는 내용들이 더 포함되어있습니다" + +#: utils/adt/acl.c:1205 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "부여 옵션을 해당 부여자에게 다시 부여할 수 없음" + +#: utils/adt/acl.c:1266 +#, c-format +msgid "dependent privileges exist" +msgstr "???의존(적인) 권한이 존재합니다" + +#: utils/adt/acl.c:1267 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "그것들을 취소하려면 \"CASCADE\"를 사용하세요." + +#: utils/adt/acl.c:1521 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert 더이상 지원하지 않음" + +#: utils/adt/acl.c:1531 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremovie 더이상 지원하지 않음" + +#: utils/adt/acl.c:1617 utils/adt/acl.c:1671 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "알 수 없는 권한 타입: \"%s\"" + +#: utils/adt/acl.c:3471 utils/adt/regproc.c:103 utils/adt/regproc.c:278 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "\"%s\" 함수가 없습니다." + +#: utils/adt/acl.c:4943 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "\"%s\" 롤의 구성원이어야 함" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:933 +#: utils/adt/arrayfuncs.c:1533 utils/adt/arrayfuncs.c:3236 +#: utils/adt/arrayfuncs.c:3376 utils/adt/arrayfuncs.c:5911 +#: utils/adt/arrayfuncs.c:6252 utils/adt/arrayutils.c:93 +#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "배열 크기가 최대치 (%d)를 초과했습니다" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:645 utils/adt/json.c:740 +#: utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 +#: utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "입력 자료형을 결정할 수 없음" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "입력 자료형이 배열이 아닙니다." + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1336 utils/adt/float.c:1243 utils/adt/float.c:1317 +#: utils/adt/float.c:3960 utils/adt/float.c:3974 utils/adt/int.c:759 +#: utils/adt/int.c:781 utils/adt/int.c:795 utils/adt/int.c:809 +#: utils/adt/int.c:840 utils/adt/int.c:861 utils/adt/int.c:978 +#: utils/adt/int.c:992 utils/adt/int.c:1006 utils/adt/int.c:1039 +#: utils/adt/int.c:1053 utils/adt/int.c:1067 utils/adt/int.c:1098 +#: utils/adt/int.c:1180 utils/adt/int.c:1244 utils/adt/int.c:1312 +#: utils/adt/int.c:1318 utils/adt/int8.c:1292 utils/adt/numeric.c:1559 +#: utils/adt/numeric.c:3435 utils/adt/varbit.c:1188 utils/adt/varbit.c:1576 +#: utils/adt/varlena.c:1087 utils/adt/varlena.c:3377 +#, c-format +msgid "integer out of range" +msgstr "정수 범위를 벗어남" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "인자는 비어있거나 1차원 배열이어야 합니다." + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "연결할 수 없는 배열들 입니다." + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "" +"Arrays with element types %s and %s are not compatible for concatenation." +msgstr "%s 자료형의 배열과 %s 자료형의 배열은 연결할 수 없습니다." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "%d차원(배열 깊이) 배열과 %d차원 배열은 연결할 수 없습니다." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "" +"Arrays with differing element dimensions are not compatible for " +"concatenation." +msgstr "차원(배열 깊이)이 다른 배열들을 서로 합칠 수 없습니다" + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "차원(배열 깊이)이 다른 배열들을 서로 합칠 수 없습니다" + +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "다차원 배열에서 요소 검색 기능은 지원하지 않음" + +#: utils/adt/array_userfuncs.c:686 +#, c-format +msgid "initial position must not be null" +msgstr "초기 위치값은 null값이 아니여야 함" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 +#: utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:506 +#: utils/adt/arrayfuncs.c:517 utils/adt/arrayfuncs.c:532 +#: utils/adt/arrayfuncs.c:553 utils/adt/arrayfuncs.c:583 +#: utils/adt/arrayfuncs.c:590 utils/adt/arrayfuncs.c:598 +#: utils/adt/arrayfuncs.c:632 utils/adt/arrayfuncs.c:655 +#: utils/adt/arrayfuncs.c:675 utils/adt/arrayfuncs.c:787 +#: utils/adt/arrayfuncs.c:796 utils/adt/arrayfuncs.c:826 +#: utils/adt/arrayfuncs.c:841 utils/adt/arrayfuncs.c:894 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "비정상적인 배열 문자: \"%s\"" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "배열 차원 정의는 \"[\" 문자로 시작해야 합니다." + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "배열 차원(배열 깊이) 값이 빠졌습니다." + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "배열 차원(배열 깊이) 표현에서 \"%s\" 문자가 빠졌습니다." + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2884 +#: utils/adt/arrayfuncs.c:2916 utils/adt/arrayfuncs.c:2931 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "상한값은 하한값보다 작을 수 없습니다" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "배열값은 \"{\" 또는 배열 깊이 정보로 시작되어야 합니다" + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "배열형은 \"{\" 문자로 시작해야 합니다." + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "지정한 배열 차원에 해당하는 배열이 없습니다." + +#: utils/adt/arrayfuncs.c:491 utils/adt/arrayfuncs.c:518 +#: utils/adt/rangetypes.c:2181 utils/adt/rangetypes.c:2189 +#: utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 +#, c-format +msgid "Unexpected end of input." +msgstr "입력의 예상치 못한 종료." + +#: utils/adt/arrayfuncs.c:507 utils/adt/arrayfuncs.c:554 +#: utils/adt/arrayfuncs.c:584 utils/adt/arrayfuncs.c:633 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "예기치 않은 \"%c\" 문자" + +#: utils/adt/arrayfuncs.c:533 utils/adt/arrayfuncs.c:656 +#, c-format +msgid "Unexpected array element." +msgstr "예기치 않은 배열 요소" + +#: utils/adt/arrayfuncs.c:591 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "짝이 안 맞는 \"%c\" 문자" + +#: utils/adt/arrayfuncs.c:599 utils/adt/jsonfuncs.c:2452 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "다차원 배열에는 일치하는 차원이 포함된 배열 식이 있어야 함" + +#: utils/adt/arrayfuncs.c:676 +#, c-format +msgid "Junk after closing right brace." +msgstr "오른쪽 닫기 괄호 뒤에 정크" + +#: utils/adt/arrayfuncs.c:1298 utils/adt/arrayfuncs.c:3344 +#: utils/adt/arrayfuncs.c:5817 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "잘못된 배열 차원(배열 깊이): %d" + +#: utils/adt/arrayfuncs.c:1309 +#, c-format +msgid "invalid array flags" +msgstr "잘못된 배열 플래그" + +#: utils/adt/arrayfuncs.c:1317 +#, c-format +msgid "wrong element type" +msgstr "잘못된 요소 타입" + +#: utils/adt/arrayfuncs.c:1367 utils/adt/rangetypes.c:335 +#: utils/cache/lsyscache.c:2835 +#, c-format +msgid "no binary input function available for type %s" +msgstr "%s 자료형에서 사용할 바이너리 입력 함수가 없습니다." + +#: utils/adt/arrayfuncs.c:1507 +#, c-format +msgid "improper binary format in array element %d" +msgstr "%d 번째 배열 요소의 포맷이 부적절합니다." + +#: utils/adt/arrayfuncs.c:1588 utils/adt/rangetypes.c:340 +#: utils/cache/lsyscache.c:2868 +#, c-format +msgid "no binary output function available for type %s" +msgstr "%s 자료형에서 사용할 바이너리 출력 함수가 없습니다." + +#: utils/adt/arrayfuncs.c:2066 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "특정 크기로 배열을 절단하는 기능은 구현되지 않습니다." + +#: utils/adt/arrayfuncs.c:2244 utils/adt/arrayfuncs.c:2266 +#: utils/adt/arrayfuncs.c:2315 utils/adt/arrayfuncs.c:2551 +#: utils/adt/arrayfuncs.c:2862 utils/adt/arrayfuncs.c:5803 +#: utils/adt/arrayfuncs.c:5829 utils/adt/arrayfuncs.c:5840 +#: utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 +#: utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4340 utils/adt/jsonfuncs.c:4490 +#: utils/adt/jsonfuncs.c:4602 utils/adt/jsonfuncs.c:4648 +#, c-format +msgid "wrong number of array subscripts" +msgstr "잘못된 배열 하위 스크립트(1,2...차원 배열 표시 문제)" + +#: utils/adt/arrayfuncs.c:2249 utils/adt/arrayfuncs.c:2357 +#: utils/adt/arrayfuncs.c:2615 utils/adt/arrayfuncs.c:2921 +#, c-format +msgid "array subscript out of range" +msgstr "배열 하위 스크립트 범위를 초과했습니다" + +#: utils/adt/arrayfuncs.c:2254 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "고정 길이 배열의 요소에 null 값을 지정할 수 없음" + +#: utils/adt/arrayfuncs.c:2809 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "고정된 크기의 배열의 조각을 업데이트 하는 기능은 구현되지 않았습니다." + +#: utils/adt/arrayfuncs.c:2840 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "배열 나누기 서브스크립트는 반드시 둘다 범위안에 있어야 합니다" + +#: utils/adt/arrayfuncs.c:2841 +#, c-format +msgid "" +"When assigning to a slice of an empty array value, slice boundaries must be " +"fully specified." +msgstr "" + +#: utils/adt/arrayfuncs.c:2852 utils/adt/arrayfuncs.c:2947 +#, c-format +msgid "source array too small" +msgstr "원본 배열이 너무 작습니다." + +#: utils/adt/arrayfuncs.c:3500 +#, c-format +msgid "null array element not allowed in this context" +msgstr "이 구문에서는 배열의 null 요소를 허용하지 않습니다" + +#: utils/adt/arrayfuncs.c:3602 utils/adt/arrayfuncs.c:3773 +#: utils/adt/arrayfuncs.c:4129 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "배열 요소 자료형이 서로 틀린 배열은 비교할 수 없습니다." + +#: utils/adt/arrayfuncs.c:3951 utils/adt/rangetypes.c:1254 +#: utils/adt/rangetypes.c:1318 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "%s 자료형에서 사용할 해시 함수를 찾을 수 없습니다." + +#: utils/adt/arrayfuncs.c:4044 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "%s 자료형에서 사용할 확장된 해시 함수를 찾을 수 없습니다." + +#: utils/adt/arrayfuncs.c:5221 +#, c-format +msgid "data type %s is not an array type" +msgstr "%s 자료형은 배열이 아닙니다." + +#: utils/adt/arrayfuncs.c:5276 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "null 배열을 누적할 수 없음" + +#: utils/adt/arrayfuncs.c:5304 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "빈 배열을 누적할 수 없음" + +#: utils/adt/arrayfuncs.c:5331 utils/adt/arrayfuncs.c:5337 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "배열 차수가 서로 틀린 배열은 누적할 수 없음" + +#: utils/adt/arrayfuncs.c:5701 utils/adt/arrayfuncs.c:5741 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "차원 배열 또는 하한 배열은 NULL일 수 없음" + +#: utils/adt/arrayfuncs.c:5804 utils/adt/arrayfuncs.c:5830 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "차원 배열은 일차원 배열이어야 합니다." + +#: utils/adt/arrayfuncs.c:5809 utils/adt/arrayfuncs.c:5835 +#, c-format +msgid "dimension values cannot be null" +msgstr "차원 값은 null일 수 없음" + +#: utils/adt/arrayfuncs.c:5841 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "하한 배열의 크기가 차원 배열과 다릅니다." + +#: utils/adt/arrayfuncs.c:6117 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "다차원 배열에서 요소 삭제기능은 지원되지 않음" + +#: utils/adt/arrayfuncs.c:6394 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "threshold 값은 1차원 배열이어야 합니다." + +#: utils/adt/arrayfuncs.c:6399 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "threshold 배열에는 null이 포함되지 않아야 함" + +#: utils/adt/arrayutils.c:209 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "typmod 배열은 cstring[] 형식이어야 함" + +#: utils/adt/arrayutils.c:214 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "typmod 배열은 일차원 배열이어야 함" + +#: utils/adt/arrayutils.c:219 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "typmod 배열에는 null이 포함되지 않아야 함" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "%s 인코딩을 ASCII 인코딩으로의 변환은 지원하지 않습니다." + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3757 +#: utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:295 +#: utils/adt/float.c:412 utils/adt/float.c:497 utils/adt/float.c:525 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 +#: utils/adt/geo_ops.c:1421 utils/adt/geo_ops.c:3476 utils/adt/geo_ops.c:4645 +#: utils/adt/geo_ops.c:4660 utils/adt/geo_ops.c:4667 utils/adt/int8.c:126 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:601 +#: utils/adt/numeric.c:628 utils/adt/numeric.c:6001 utils/adt/numeric.c:6025 +#: utils/adt/numeric.c:6049 utils/adt/numeric.c:6882 utils/adt/numeric.c:6908 +#: utils/adt/numutils.c:116 utils/adt/numutils.c:126 utils/adt/numutils.c:170 +#: utils/adt/numutils.c:246 utils/adt/numutils.c:322 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:73 utils/adt/tid.c:74 utils/adt/tid.c:82 +#: utils/adt/tid.c:90 utils/adt/timestamp.c:494 utils/adt/uuid.c:136 +#: utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "%s 자료형 대한 잘못된 입력: \"%s\"" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 +#: utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "입력한 \"%s\" 값은 %s 자료형 범위를 초과했습니다" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:104 utils/adt/int.c:824 utils/adt/int.c:940 +#: utils/adt/int.c:1020 utils/adt/int.c:1082 utils/adt/int.c:1120 +#: utils/adt/int.c:1148 utils/adt/int8.c:593 utils/adt/int8.c:651 +#: utils/adt/int8.c:978 utils/adt/int8.c:1058 utils/adt/int8.c:1120 +#: utils/adt/int8.c:1200 utils/adt/numeric.c:7446 utils/adt/numeric.c:7736 +#: utils/adt/numeric.c:9318 utils/adt/timestamp.c:3264 +#, c-format +msgid "division by zero" +msgstr "0으로는 나눌수 없습니다." + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "\"char\" 범위를 벗어났습니다." + +#: utils/adt/date.c:61 utils/adt/timestamp.c:95 utils/adt/varbit.c:104 +#: utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "잘못된 자료형 한정자" + +#: utils/adt/date.c:73 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "TIME(%d)%s 정밀도로 음수를 사용할 수 없습니다" + +#: utils/adt/date.c:79 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%s 정밀도는 최대값(%d)으로 줄였습니다" + +#: utils/adt/date.c:158 utils/adt/date.c:166 utils/adt/formatting.c:4210 +#: utils/adt/formatting.c:4219 utils/adt/formatting.c:4325 +#: utils/adt/formatting.c:4335 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "날짜 범위가 벗어났음: \"%s\"" + +#: utils/adt/date.c:213 utils/adt/date.c:525 utils/adt/date.c:549 +#: utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "날짜가 범위를 벗어남" + +#: utils/adt/date.c:259 utils/adt/timestamp.c:574 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "날짜 필드의 값이 범위를 벗어남: %d-%02d-%02d" + +#: utils/adt/date.c:266 utils/adt/date.c:275 utils/adt/timestamp.c:580 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "날짜 범위가 벗어났음: %d-%02d-%02d" + +#: utils/adt/date.c:313 utils/adt/date.c:336 utils/adt/date.c:362 +#: utils/adt/date.c:1170 utils/adt/date.c:1216 utils/adt/date.c:1772 +#: utils/adt/date.c:1803 utils/adt/date.c:1832 utils/adt/date.c:2664 +#: utils/adt/datetime.c:1655 utils/adt/formatting.c:4067 +#: utils/adt/formatting.c:4099 utils/adt/formatting.c:4179 +#: utils/adt/formatting.c:4301 utils/adt/json.c:418 utils/adt/json.c:457 +#: utils/adt/timestamp.c:222 utils/adt/timestamp.c:254 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2843 utils/adt/timestamp.c:2864 +#: utils/adt/timestamp.c:2877 utils/adt/timestamp.c:2886 +#: utils/adt/timestamp.c:2894 utils/adt/timestamp.c:2949 +#: utils/adt/timestamp.c:2972 utils/adt/timestamp.c:2985 +#: utils/adt/timestamp.c:2996 utils/adt/timestamp.c:3004 +#: utils/adt/timestamp.c:3664 utils/adt/timestamp.c:3789 +#: utils/adt/timestamp.c:3830 utils/adt/timestamp.c:3920 +#: utils/adt/timestamp.c:3964 utils/adt/timestamp.c:4067 +#: utils/adt/timestamp.c:4552 utils/adt/timestamp.c:4748 +#: utils/adt/timestamp.c:5075 utils/adt/timestamp.c:5089 +#: utils/adt/timestamp.c:5094 utils/adt/timestamp.c:5108 +#: utils/adt/timestamp.c:5141 utils/adt/timestamp.c:5218 +#: utils/adt/timestamp.c:5259 utils/adt/timestamp.c:5263 +#: utils/adt/timestamp.c:5332 utils/adt/timestamp.c:5336 +#: utils/adt/timestamp.c:5350 utils/adt/timestamp.c:5384 utils/adt/xml.c:2232 +#: utils/adt/xml.c:2239 utils/adt/xml.c:2259 utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "타임스탬프 범위를 벗어남" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "무한 날짜를 뺄 수 없음" + +#: utils/adt/date.c:589 utils/adt/date.c:646 utils/adt/date.c:680 +#: utils/adt/date.c:2701 utils/adt/date.c:2711 +#, c-format +msgid "date out of range for timestamp" +msgstr "날짜가 타임스탬프 범위를 벗어남" + +#: utils/adt/date.c:1389 utils/adt/date.c:2159 utils/adt/formatting.c:4387 +#, c-format +msgid "time out of range" +msgstr "시간 범위를 벗어남" + +#: utils/adt/date.c:1441 utils/adt/timestamp.c:589 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "시간 필드의 값이 범위를 벗어남: %d:%02d:%02g" + +#: utils/adt/date.c:1961 utils/adt/date.c:2463 utils/adt/float.c:1071 +#: utils/adt/float.c:1140 utils/adt/int.c:616 utils/adt/int.c:663 +#: utils/adt/int.c:698 utils/adt/int8.c:492 utils/adt/numeric.c:2197 +#: utils/adt/timestamp.c:3313 utils/adt/timestamp.c:3344 +#: utils/adt/timestamp.c:3375 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "윈도우 함수에서 앞에 오거나 뒤에 따라오는 크기가 잘못됨" + +#: utils/adt/date.c:2046 utils/adt/date.c:2059 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "\"%s\" 는 \"time\" 자료형 단위가 아닙니다." + +#: utils/adt/date.c:2167 +#, c-format +msgid "time zone displacement out of range" +msgstr "타임 존 변위가 범위를 벗어남" + +#: utils/adt/date.c:2796 utils/adt/date.c:2809 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "\"%s\" 는 \"time with time zone\" 자료형의 단위가 아닙니다." + +#: utils/adt/date.c:2882 utils/adt/datetime.c:906 utils/adt/datetime.c:1813 +#: utils/adt/datetime.c:4601 utils/adt/timestamp.c:513 +#: utils/adt/timestamp.c:540 utils/adt/timestamp.c:4150 +#: utils/adt/timestamp.c:5100 utils/adt/timestamp.c:5342 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "\"%s\" 이름의 시간대는 없습니다." + +#: utils/adt/date.c:2914 utils/adt/timestamp.c:5130 utils/adt/timestamp.c:5373 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "" +"\"%s\" 시간대 간격(interval time zone) 값으로 달(month) 또는 일(day)을 포함" +"할 수 없습니다" + +#: utils/adt/datetime.c:3730 utils/adt/datetime.c:3737 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "날짜/시간 필드의 값이 범위를 벗어남: \"%s\"" + +#: utils/adt/datetime.c:3739 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "날짜 표현 방식(\"datestyle\")을 다른 것으로 사용하고 있는 듯 합니다." + +#: utils/adt/datetime.c:3744 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "interval 필드의 값이 범위를 벗어남: \"%s\"" + +#: utils/adt/datetime.c:3750 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "표준시간대 범위를 벗어남: \"%s\"" + +#: utils/adt/datetime.c:4603 +#, c-format +msgid "" +"This time zone name appears in the configuration file for time zone " +"abbreviation \"%s\"." +msgstr "" + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "잘못된 Datum 포인터" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "잘못된 크기: \"%s\"" + +#: utils/adt/dbsize.c:828 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "잘못된 크기 단위: \"%s\"" + +#: utils/adt/dbsize.c:829 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "" +"이 매개 변수에 유효한 단위는 \"bytes\",\"kB\", \"MB\", \"GB\", \"TB\"입니다." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "%s 자료형은 도메인이 아닙니다" + +#: utils/adt/encode.c:64 utils/adt/encode.c:112 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "알 수 없는 인코딩: \"%s\"" + +#: utils/adt/encode.c:78 +#, c-format +msgid "result of encoding conversion is too large" +msgstr "인코딩 변환 결과가 너무 깁니다" + +#: utils/adt/encode.c:126 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "디코딩 변환 결과가 너무 깁니다" + +#: utils/adt/encode.c:184 +#, c-format +msgid "invalid hexadecimal digit: \"%c\"" +msgstr "잘못된 16진수: \"%c\"" + +#: utils/adt/encode.c:212 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "잘못된 16진수 데이터: 데이터의 길이가 홀수 입니다." + +#: utils/adt/encode.c:329 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "base64 자료를 디코딩 하는 중 예상치 못한 \"=\" 문자 발견" + +#: utils/adt/encode.c:341 +#, c-format +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "base64 자료를 디코딩 하는 중 잘못된 \"%c\" 기호 발견" + +#: utils/adt/encode.c:361 +#, c-format +msgid "invalid base64 end sequence" +msgstr "base64 마침 조합이 잘못되었음" + +#: utils/adt/encode.c:362 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "입력값에 여백 처리값이 빠졌거나, 자료가 손상되었습니다." + +#: utils/adt/encode.c:476 utils/adt/encode.c:541 utils/adt/jsonfuncs.c:619 +#: utils/adt/varlena.c:319 utils/adt/varlena.c:360 jsonpath_gram.y:528 +#: jsonpath_scan.l:519 jsonpath_scan.l:530 jsonpath_scan.l:540 +#: jsonpath_scan.l:582 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "%s 자료형에 대한 잘못된 입력 구문" + +#: utils/adt/enum.c:100 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "" + +#: utils/adt/enum.c:103 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "" + +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 +#: utils/adt/enum.c:199 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "%s 열거형의 입력 값이 잘못됨: \"%s\"" + +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "열거형의 내부 값이 잘못됨: %u" + +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 +#: utils/adt/enum.c:535 +#, c-format +msgid "could not determine actual enum type" +msgstr "실제 열거형의 자료형을 확인할 수 없음" + +#: utils/adt/enum.c:454 utils/adt/enum.c:483 +#, c-format +msgid "enum %s contains no values" +msgstr "\"%s\" 열거형 자료에 값이 없음" + +#: utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 +#: utils/cache/typcache.c:1632 utils/cache/typcache.c:1788 +#: utils/cache/typcache.c:1918 utils/fmgr/funcapi.c:456 +#, c-format +msgid "type %s is not composite" +msgstr "%s 자료형은 복합 자료형이 아닙니다" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "값이 범위를 벗어남: 오버플로" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "값이 범위를 벗어남: 언더플로" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "\"%s\"는 real 자료형의 범위를 벗어납니다." + +#: utils/adt/float.c:489 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "\"%s\"는 double precision 자료형의 범위를 벗어납니다." + +#: utils/adt/float.c:1268 utils/adt/float.c:1342 utils/adt/int.c:336 +#: utils/adt/int.c:874 utils/adt/int.c:896 utils/adt/int.c:910 +#: utils/adt/int.c:924 utils/adt/int.c:956 utils/adt/int.c:1194 +#: utils/adt/int8.c:1313 utils/adt/numeric.c:3553 utils/adt/numeric.c:3562 +#, c-format +msgid "smallint out of range" +msgstr "smallint의 범위를 벗어났습니다." + +#: utils/adt/float.c:1468 utils/adt/numeric.c:8329 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "음수의 제곱근을 구할 수 없습니다." + +#: utils/adt/float.c:1536 utils/adt/numeric.c:3239 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "0의 음수 거듭제곱이 정의되어 있지 않음" + +#: utils/adt/float.c:1540 utils/adt/numeric.c:3245 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "음수의 비정수 거듭제곱을 계산하면 복잡한 결과가 생성됨" + +#: utils/adt/float.c:1614 utils/adt/float.c:1647 utils/adt/numeric.c:8993 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "0의 대수를 구할 수 없습니다." + +#: utils/adt/float.c:1618 utils/adt/float.c:1651 utils/adt/numeric.c:8997 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "음수의 대수를 구할 수 없습니다." + +#: utils/adt/float.c:1684 utils/adt/float.c:1715 utils/adt/float.c:1810 +#: utils/adt/float.c:1837 utils/adt/float.c:1865 utils/adt/float.c:1892 +#: utils/adt/float.c:2039 utils/adt/float.c:2076 utils/adt/float.c:2246 +#: utils/adt/float.c:2302 utils/adt/float.c:2367 utils/adt/float.c:2424 +#: utils/adt/float.c:2615 utils/adt/float.c:2639 +#, c-format +msgid "input is out of range" +msgstr "입력값이 범위를 벗어났습니다." + +#: utils/adt/float.c:2706 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "" + +#: utils/adt/float.c:3938 utils/adt/numeric.c:1509 +#, c-format +msgid "count must be greater than zero" +msgstr "카운트 값은 0 보다 커야합니다" + +#: utils/adt/float.c:3943 utils/adt/numeric.c:1516 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "피연산자, 하한 및 상한은 NaN일 수 없음" + +#: utils/adt/float.c:3949 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "하한 및 상한은 유한한 값이어야 함" + +#: utils/adt/float.c:3983 utils/adt/numeric.c:1529 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "하한값은 상한값과 같을 수 없습니다" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "간격 값에 대한 형식 지정이 잘못됨" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "간격이 특정 달력 날짜에 연결되어 있지 않습니다." + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "???\"9\"는 \"PR\" 앞이어야 한다." + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "???\"0\"은 \"PR\" 앞이어야 한다." + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "???여러개의 소숫점" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "\"V\" 와 소숫점을 함께 쓸 수 없습니다." + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "\"S\"를 두 번 사용할 수 없음" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "\"S\" 와 \"PL\"/\"MI\"/\"SG\"/\"PR\" 를 함께 쓸 수 없습니다." + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "\"S\" 와 \"MI\" 를 함께 쓸 수 없습니다." + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "\"S\" 와 \"PL\" 를 함께 쓸 수 없습니다." + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "\"S\" 와 \"SG\" 를 함께 쓸 수 없습니다." + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "\"PR\" 와 \"S\"/\"PL\"/\"MI\"/\"SG\" 를 함께 쓸 수 없습니다." + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "\"EEEE\"를 두 번 사용할 수 없음" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "\"EEEE\"는 다른 포맷과 호환하지 않습니다" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "" +"\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "" + +#: utils/adt/formatting.c:1394 +#, c-format +msgid "invalid datetime format separator: \"%s\"" +msgstr "잘못된 datetime 양식 구분자: \"%s\"" + +#: utils/adt/formatting.c:1522 +#, c-format +msgid "\"%s\" is not a number" +msgstr "\"%s\"는 숫자가 아닙니다." + +#: utils/adt/formatting.c:1600 +#, c-format +msgid "case conversion failed: %s" +msgstr "잘못된 형 변환 규칙: %s" + +#: utils/adt/formatting.c:1665 utils/adt/formatting.c:1789 +#: utils/adt/formatting.c:1914 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "%s 함수에서 사용할 정렬규칙(collation)을 결정할 수 없음" + +#: utils/adt/formatting.c:2286 +#, c-format +msgid "invalid combination of date conventions" +msgstr "날짜 변환을 위한 잘못된 조합" + +#: utils/adt/formatting.c:2287 +#, c-format +msgid "" +"Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "" +"형식 템플릿에 그레고리오력과 ISO week date 변환을 함께 사용하지 마십시오." + +#: utils/adt/formatting.c:2310 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "형식 문자열에서 \"%s\" 필드의 값이 충돌함" + +#: utils/adt/formatting.c:2313 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "이 값은 동일한 필드 형식의 이전 설정과 모순됩니다." + +#: utils/adt/formatting.c:2384 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "소스 문자열이 너무 짧아서 \"%s\" 형식 필드에 사용할 수 없음" + +#: utils/adt/formatting.c:2387 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "필드에 %d자가 필요한데 %d자만 남았습니다." + +#: utils/adt/formatting.c:2390 utils/adt/formatting.c:2405 +#, c-format +msgid "" +"If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "소스 문자열이 고정 너비가 아닌 경우 \"FM\" 한정자를 사용해 보십시오." + +#: utils/adt/formatting.c:2400 utils/adt/formatting.c:2414 +#: utils/adt/formatting.c:2637 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "\"%s\" 값은 \"%s\"에 유효하지 않음" + +#: utils/adt/formatting.c:2402 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "필드에 %d자가 필요한데 %d자만 구문 분석할 수 있습니다." + +#: utils/adt/formatting.c:2416 +#, c-format +msgid "Value must be an integer." +msgstr "값은 정수여야 합니다." + +#: utils/adt/formatting.c:2421 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "소스 문자열의 \"%s\" 값이 범위를 벗어남" + +#: utils/adt/formatting.c:2423 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "값은 %d에서 %d 사이의 범위에 있어야 합니다." + +#: utils/adt/formatting.c:2639 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "지정된 값이 이 필드에 허용되는 값과 일치하지 않습니다." + +#: utils/adt/formatting.c:2856 utils/adt/formatting.c:2876 +#: utils/adt/formatting.c:2896 utils/adt/formatting.c:2916 +#: utils/adt/formatting.c:2935 utils/adt/formatting.c:2954 +#: utils/adt/formatting.c:2978 utils/adt/formatting.c:2996 +#: utils/adt/formatting.c:3014 utils/adt/formatting.c:3032 +#: utils/adt/formatting.c:3049 utils/adt/formatting.c:3066 +#, c-format +msgid "localized string format value too long" +msgstr "" + +#: utils/adt/formatting.c:3300 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "" + +#: utils/adt/formatting.c:3361 +#, c-format +msgid "unmatched format character \"%s\"" +msgstr "짝이 안 맞는 \"%s\" 문자" + +#: utils/adt/formatting.c:3467 utils/adt/formatting.c:3811 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "\"%s\" 필드 양식은 to_char 함수에서만 지원합니다." + +#: utils/adt/formatting.c:3642 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "\"Y,YYY\"에 대한 입력 문자열이 잘못됨" + +#: utils/adt/formatting.c:3728 +#, c-format +msgid "input string is too short for datetime format" +msgstr "입력 문자열이 datetime 양식용으로는 너무 짧습니다" + +#: utils/adt/formatting.c:3736 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "" + +#: utils/adt/formatting.c:4281 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "" + +#: utils/adt/formatting.c:4287 +#, c-format +msgid "timestamptz out of range" +msgstr "timestamptz 범위를 벗어남" + +#: utils/adt/formatting.c:4315 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "datetime 양식이 지역시간대값이 있는데, 시간값이 아님" + +#: utils/adt/formatting.c:4367 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "" + +#: utils/adt/formatting.c:4373 +#, c-format +msgid "timetz out of range" +msgstr "timetz 범위를 벗어남" + +#: utils/adt/formatting.c:4399 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "" + +#: utils/adt/formatting.c:4532 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "시간 \"%d\"은(는) 12시간제에 유효하지 않음" + +#: utils/adt/formatting.c:4534 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "24시간제를 사용하거나 1에서 12 사이의 시간을 지정하십시오." + +#: utils/adt/formatting.c:4645 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "연도 정보 없이 몇번째 날(day of year) 인지 계산할 수 없습니다." + +#: utils/adt/formatting.c:5564 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "\"EEEE\" 입력 양식은 지원되지 않습니다." + +#: utils/adt/formatting.c:5576 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "\"RN\" 입력 양식은 지원되지 않습니다." + +#: utils/adt/genfile.c:75 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "상위 디렉터리(\"..\") 참조는 허용되지 않음" + +#: utils/adt/genfile.c:86 +#, c-format +msgid "absolute path not allowed" +msgstr "절대 경로는 허용하지 않음" + +#: utils/adt/genfile.c:91 +#, c-format +msgid "path must be in or below the current directory" +msgstr "경로는 현재 디렉터리와 그 하위 디렉터리여야 합니다." + +#: utils/adt/genfile.c:116 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 +#, c-format +msgid "requested length too large" +msgstr "요청된 길이가 너무 깁니다" + +#: utils/adt/genfile.c:133 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "\"%s\" 파일에서 seek 작업을 할 수 없음: %m" + +#: utils/adt/genfile.c:174 +#, c-format +msgid "file length too large" +msgstr "파일 길이가 너무 깁니다" + +#: utils/adt/genfile.c:251 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "adminpack 1.0 확장 모듈을 사용할 때는 파일을 읽으려면 슈퍼유져여야함" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "선 정의가 잘못됨: A와 B 둘다 0일 수는 없음" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "선 정의가 잘못된: 두 점은 서로 다른 위치여야 함" + +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3486 utils/adt/geo_ops.c:4354 +#: utils/adt/geo_ops.c:5248 +#, c-format +msgid "too many points requested" +msgstr "너무 많은 점들이 요청되었습니다." + +#: utils/adt/geo_ops.c:1461 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "???\"path\" 의 값에 잘못된 갯수의 point들" + +#: utils/adt/geo_ops.c:2537 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "\"dist_lb\" 함수는 구현되지 않았습니다." + +#: utils/adt/geo_ops.c:2556 +#, c-format +msgid "function \"dist_bl\" not implemented" +msgstr "\"dist_bl\" 함수는 구현되지 않았습니다." + +#: utils/adt/geo_ops.c:2975 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "\"close_sl\" 함수는 구현되지 않았습니다." + +#: utils/adt/geo_ops.c:3122 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "\"close_lb\" 함수는 구현되지 않았습니다." + +#: utils/adt/geo_ops.c:3533 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "???\"polygon\" 값에 잘못된 갯수의 point들" + +#: utils/adt/geo_ops.c:4069 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "\"poly_distance\" 함수는 구현되지 않았습니다." + +#: utils/adt/geo_ops.c:4446 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "\"path_center\" 함수는 구현되지 않았습니다." + +#: utils/adt/geo_ops.c:4463 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "닫히지 않은 path 는 폴리곤으로 변환할 수 없습니다." + +#: utils/adt/geo_ops.c:4713 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "부적절한 \"circle\" 값의 반지름" + +#: utils/adt/geo_ops.c:5234 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "반지름이 0인 원은 폴리곤으로 변환할 수 없습니다." + +#: utils/adt/geo_ops.c:5239 +#, c-format +msgid "must request at least 2 points" +msgstr "적어도 2개의 point들이 필요합니다." + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector 는 너무 많은 요소를 가지고 있습니다." + +#: utils/adt/int.c:239 +#, c-format +msgid "invalid int2vector data" +msgstr "잘못된 int2vector 자료" + +#: utils/adt/int.c:245 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector에 너무 많은 요소가 있습니다" + +#: utils/adt/int.c:1510 utils/adt/int8.c:1439 utils/adt/numeric.c:1417 +#: utils/adt/timestamp.c:5435 utils/adt/timestamp.c:5515 +#, c-format +msgid "step size cannot equal zero" +msgstr "단계 크기는 0일 수 없음" + +#: utils/adt/int8.c:527 utils/adt/int8.c:550 utils/adt/int8.c:564 +#: utils/adt/int8.c:578 utils/adt/int8.c:609 utils/adt/int8.c:633 +#: utils/adt/int8.c:715 utils/adt/int8.c:783 utils/adt/int8.c:789 +#: utils/adt/int8.c:815 utils/adt/int8.c:829 utils/adt/int8.c:853 +#: utils/adt/int8.c:866 utils/adt/int8.c:935 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:994 utils/adt/int8.c:1016 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1077 +#: utils/adt/int8.c:1091 utils/adt/int8.c:1105 utils/adt/int8.c:1136 +#: utils/adt/int8.c:1158 utils/adt/int8.c:1172 utils/adt/int8.c:1186 +#: utils/adt/int8.c:1348 utils/adt/int8.c:1383 utils/adt/numeric.c:3508 +#: utils/adt/varbit.c:1656 +#, c-format +msgid "bigint out of range" +msgstr "bigint의 범위를 벗어났습니다." + +#: utils/adt/int8.c:1396 +#, c-format +msgid "OID out of range" +msgstr "OID의 범위를 벗어났습니다." + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "" +"키 값은 스칼라 형이어야 함. 배열, 복합 자료형, json 형은 사용할 수 없음" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1812 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "%d번째 인자의 자료형을 알수가 없습니다." + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "필드 이름이 null 이면 안됩니다" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "인자 목록은 요소수의 짝수개여야 합니다." + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "%s 함수의 인자들은 각각 key, value 쌍으로 있어야 합니다." + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "%d 번째 인자는 null 이면 안됩니다" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "개체 키는 문자열이어야 합니다." + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "배열은 두개의 칼럼이어야 함" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 +#: utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "개체 키 값으로 null 을 허용하지 않음" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "배열 차수가 안맞음" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "jsonb 문자열로 길이를 초과함" + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "" +"Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "구현상 제한으로 jsonb 문자열은 %d 바이트를 넘을 수 없습니다." + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "%d 번째 인자: 키 값은 null이면 안됩니다." + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "개체 키는 문자열이어야 합니다" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "jsonb null 값을 %s 자료형으로 형 변환 할 수 없음" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "jsonb 문자열 값을 %s 자료형으로 형 변환 할 수 없음" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "jsonb 숫자 값을 %s 자료형으로 형 변환 할 수 없음" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "jsonb 불린 값을 %s 자료형으로 형 변환 할 수 없음" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "jsonb 배열 값을 %s 자료형으로 형 변환 할 수 없음" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "jsonb object 값을 %s 자료형으로 형 변환 할 수 없음" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "jsonb object나 배열 값을 %s 자료형으로 형 변환 할 수 없음" + +#: utils/adt/jsonb_util.c:699 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "jsonb 개체 쌍의 개수가 최대치를 초과함 (%zu)" + +#: utils/adt/jsonb_util.c:740 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "jsonb 배열 요소 개수가 최대치를 초과함 (%zu)" + +#: utils/adt/jsonb_util.c:1614 utils/adt/jsonb_util.c:1634 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "jsonb 배열 요소 총 크기가 최대치를 초과함 (%u 바이트)" + +#: utils/adt/jsonb_util.c:1695 utils/adt/jsonb_util.c:1730 +#: utils/adt/jsonb_util.c:1750 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "jsonb 개체 요소들의 총 크기가 최대치를 초과함 (%u 바이트)" + +#: utils/adt/jsonfuncs.c:551 utils/adt/jsonfuncs.c:796 +#: utils/adt/jsonfuncs.c:2330 utils/adt/jsonfuncs.c:2770 +#: utils/adt/jsonfuncs.c:3560 utils/adt/jsonfuncs.c:3891 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "스칼라형에서는 %s 호출 할 수 없음" + +#: utils/adt/jsonfuncs.c:556 utils/adt/jsonfuncs.c:783 +#: utils/adt/jsonfuncs.c:2772 utils/adt/jsonfuncs.c:3549 +#, c-format +msgid "cannot call %s on an array" +msgstr "배열형에서는 %s 호출 할 수 없음" + +#: utils/adt/jsonfuncs.c:613 jsonpath_scan.l:498 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "지원하지 않는 유니코드 이스케이프 조합" + +#: utils/adt/jsonfuncs.c:692 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "JSON 자료, %d 번째 줄: %s%s%s" + +#: utils/adt/jsonfuncs.c:1682 utils/adt/jsonfuncs.c:1717 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "스칼라형의 배열 길이를 구할 수 없음" + +#: utils/adt/jsonfuncs.c:1686 utils/adt/jsonfuncs.c:1705 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "비배열형 자료의 배열 길이를 구할 수 없음" + +#: utils/adt/jsonfuncs.c:1782 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "비개체형에서 %s 호출 할 수 없음" + +#: utils/adt/jsonfuncs.c:2021 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "" + +#: utils/adt/jsonfuncs.c:2033 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "스칼라형으로 재구축할 수 없음" + +#: utils/adt/jsonfuncs.c:2079 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "스칼라형에서 요소를 추출할 수 없음" + +#: utils/adt/jsonfuncs.c:2083 +#, c-format +msgid "cannot extract elements from an object" +msgstr "개체형에서 요소를 추출할 수 없음" + +#: utils/adt/jsonfuncs.c:2317 utils/adt/jsonfuncs.c:3775 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "비배열형에서 %s 호출 할 수 없음" + +#: utils/adt/jsonfuncs.c:2387 utils/adt/jsonfuncs.c:2392 +#: utils/adt/jsonfuncs.c:2409 utils/adt/jsonfuncs.c:2415 +#, c-format +msgid "expected JSON array" +msgstr "예기치 않은 json 배열" + +#: utils/adt/jsonfuncs.c:2388 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "\"%s\" 키의 값을 지정하세요" + +#: utils/adt/jsonfuncs.c:2410 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "%s 배열 요소, 해당 키: \"%s\" 참조" + +#: utils/adt/jsonfuncs.c:2416 +#, c-format +msgid "See the array element %s." +msgstr "배열 요소: %s 참조" + +#: utils/adt/jsonfuncs.c:2451 +#, c-format +msgid "malformed JSON array" +msgstr "잘못된 json 배열" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3278 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "%s의 첫번째 인자는 row 형이어야 합니다" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3302 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "%s 함수의 반환 로우 자료형을 알수가 없음" + +#: utils/adt/jsonfuncs.c:3304 +#, c-format +msgid "" +"Provide a non-null record argument, or call the function in the FROM clause " +"using a column definition list." +msgstr "" +"non-null 레코드 인자를 지정하거나, 함수를 호출 할 때 FROM 절에서 칼럼 정의 목" +"록도 함께 지정해야 합니다." + +#: utils/adt/jsonfuncs.c:3792 utils/adt/jsonfuncs.c:3873 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "%s의 인자는 개체의 배열이어야 합니다" + +#: utils/adt/jsonfuncs.c:3825 +#, c-format +msgid "cannot call %s on an object" +msgstr "개체에서 %s 호출할 수 없음" + +#: utils/adt/jsonfuncs.c:4286 utils/adt/jsonfuncs.c:4345 +#: utils/adt/jsonfuncs.c:4425 +#, c-format +msgid "cannot delete from scalar" +msgstr "스칼라형에서 삭제 할 수 없음" + +#: utils/adt/jsonfuncs.c:4430 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "인덱스 번호를 사용해서 개체에서 삭제 할 수 없음" + +#: utils/adt/jsonfuncs.c:4495 utils/adt/jsonfuncs.c:4653 +#, c-format +msgid "cannot set path in scalar" +msgstr "스칼라형에는 path 를 지정할 수 없음" + +#: utils/adt/jsonfuncs.c:4537 utils/adt/jsonfuncs.c:4579 +#, c-format +msgid "" +"null_value_treatment must be \"delete_key\", \"return_target\", " +"\"use_json_null\", or \"raise_exception\"" +msgstr "" + +#: utils/adt/jsonfuncs.c:4550 +#, c-format +msgid "JSON value must not be null" +msgstr "JSON 값으로 null을 사용할 수 없음" + +#: utils/adt/jsonfuncs.c:4551 +#, c-format +msgid "" +"Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "" + +#: utils/adt/jsonfuncs.c:4552 +#, c-format +msgid "" +"To avoid, either change the null_value_treatment argument or ensure that an " +"SQL NULL is not passed." +msgstr "" + +#: utils/adt/jsonfuncs.c:4607 +#, c-format +msgid "cannot delete path in scalar" +msgstr "스칼라형에서 path를 지울 수 없음" + +#: utils/adt/jsonfuncs.c:4776 +#, c-format +msgid "invalid concatenation of jsonb objects" +msgstr "jsonb 개체들의 잘못된 결합" + +#: utils/adt/jsonfuncs.c:4810 +#, c-format +msgid "path element at position %d is null" +msgstr "%d 위치의 path 요소는 null 입니다." + +#: utils/adt/jsonfuncs.c:4896 +#, c-format +msgid "cannot replace existing key" +msgstr "이미 있는 키로는 대체할 수 없음" + +#: utils/adt/jsonfuncs.c:4897 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "키 값을 변경하려면, jsonb_set 함수를 사용하세요." + +#: utils/adt/jsonfuncs.c:4979 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "%d 번째 위치의 path 요소는 정수가 아님: \"%s\"" + +#: utils/adt/jsonfuncs.c:5098 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "" + +#: utils/adt/jsonfuncs.c:5105 +#, c-format +msgid "flag array element is not a string" +msgstr "플래그 배열 요소가 문자열이 아님" + +#: utils/adt/jsonfuncs.c:5106 utils/adt/jsonfuncs.c:5128 +#, c-format +msgid "" +"Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all" +"\"." +msgstr "" + +#: utils/adt/jsonfuncs.c:5126 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ 기호는 루트 표현식에서는 사용할 수 없음" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST 키워드는 배열 하위 스크립트 전용임" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "단일 불리언 반환값이 예상 됨" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "" +"Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "" + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "jsonpath 배열 하위 스크립트 범위를 초과했습니다" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "" + +#: utils/adt/jsonpath_exec.c:874 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1004 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1059 +#, c-format +msgid "" +"numeric argument of jsonpath item method .%s() is out of range for type " +"double precision" +msgstr "" +"jsonpath 아이템 메서드 .%s() 의 숫자 인자가 double precision 형의 " +"범위를 벗어남" + +#: utils/adt/jsonpath_exec.c:1080 +#, c-format +msgid "" +"string argument of jsonpath item method .%s() is not a valid representation " +"of a double precision number" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1093 +#, c-format +msgid "" +"jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1583 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1590 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1658 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1756 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1796 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1890 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "알 수 없는 datetime 양식: \"%s\"" + +#: utils/adt/jsonpath_exec.c:1892 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "" + +#: utils/adt/jsonpath_exec.c:1960 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:2143 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "\"%s\" jsonpath 변수 찾기 실패" + +#: utils/adt/jsonpath_exec.c:2407 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:2419 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "jsonpath 배열 하위 스크립트가 정수 범위를 초과했음" + +#: utils/adt/jsonpath_exec.c:2596 +#, c-format +msgid "cannot convert value from %s to %s without time zone usage" +msgstr "" + +#: utils/adt/jsonpath_exec.c:2598 +#, c-format +msgid "Use *_tz() function for time zone support." +msgstr "" + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "levenshtein 인자값으로 그 길이가 %d 문자의 최대 길이를 초과했음" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "LIKE 연산에서 사용할 비결정 정렬규칙(collation)은 지원하지 않음" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "ILIKE 연산에서 사용할 정렬규칙(collation)을 결정할 수 없음" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "ILIKE 연산에서 사용할 비결정 정렬규칙(collation)은 지원하지 않음" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "LIKE 패턴은 이스케이프 문자로 끝나지 않아야 함" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "잘못된 이스케이프 문자열" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "이스케이프 문자열은 비어있거나 한개의 문자여야 합니다." + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "bytea 형식에서는 대/소문자를 구분하지 않는 일치가 지원되지 않음" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "bytea 형식에서는 정규식 일치가 지원되지 않음" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "\"macaddr\"에 대한 잘못된 옥텟(octet) 값: \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "" +"Only addresses that have FF and FE as values in the 4th and 5th bytes from " +"the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted " +"from macaddr8 to macaddr." +msgstr "" + +#: utils/adt/misc.c:240 +#, c-format +msgid "global tablespace never has databases" +msgstr "전역 테이블스페이스는 데이터베이스를 결코 포함하지 않습니다." + +#: utils/adt/misc.c:262 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u 테이블스페이스 OID가 아님" + +#: utils/adt/misc.c:448 +msgid "unreserved" +msgstr "예약되지 않음" + +#: utils/adt/misc.c:452 +msgid "unreserved (cannot be function or type name)" +msgstr "예약되지 않음(함수, 자료형 이름일 수 없음)" + +#: utils/adt/misc.c:456 +msgid "reserved (can be function or type name)" +msgstr "예약됨(함수, 자료형 이름일 수 있음)" + +#: utils/adt/misc.c:460 +msgid "reserved" +msgstr "예약됨" + +#: utils/adt/misc.c:634 utils/adt/misc.c:648 utils/adt/misc.c:687 +#: utils/adt/misc.c:693 utils/adt/misc.c:699 utils/adt/misc.c:722 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "문자열이 타당한 식별자가 아님: \"%s\"" + +#: utils/adt/misc.c:636 +#, c-format +msgid "String has unclosed double quotes." +msgstr "문자열 표기에서 큰따옴표 짝이 안맞습니다." + +#: utils/adt/misc.c:650 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "인용부호 있는 식별자: 비어있으면 안됩니다" + +#: utils/adt/misc.c:689 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "\".\" 전에 타당한 식별자가 없음" + +#: utils/adt/misc.c:695 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "\".\" 뒤에 타당한 식별자 없음" + +#: utils/adt/misc.c:753 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "\"%s\" 양식의 로그는 지원하지 않습니다" + +#: utils/adt/misc.c:754 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "" + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "cidr 자료형에 대한 잘못된 입력: \"%s\"" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "마스크 오른쪽에 설정된 비트가 값에 포함되어 있습니다." + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 +#: utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "inet 값의 형식을 지정할 수 없음: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "잘못 된 주소군 \"%s\"" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "\"%s\" 값에 잘못된 비트가 있음" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "외부 \"%s\" 값의 길이가 잘못 되었음" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "외부 \"cidr\" 값이 잘못됨" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "잘못된 마스크 길이: %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "cidr 값을 처리할 수 없음: %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "서로 다른 페밀리에서는 주소를 병합할 수 없음" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "서로 크기가 틀린 inet 값들은 AND 연산을 할 수 없습니다." + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "서로 크기가 틀린 inet 값들은 OR 연산을 할 수 없습니다." + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "결과가 범위를 벗어났습니다." + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "inet 값에서 서로 크기가 틀리게 부분 추출(subtract)할 수 없음" + +#: utils/adt/numeric.c:827 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "외부 \"numeric\" 값의 부호가 잘못됨" + +#: utils/adt/numeric.c:833 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "외부 \"numeric\" 값의 잘못된 스케일" + +#: utils/adt/numeric.c:842 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "외부 \"numeric\" 값의 숫자가 잘못됨" + +#: utils/adt/numeric.c:1040 utils/adt/numeric.c:1054 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "NUMERIC 정밀도 %d 값은 범위(1 .. %d)를 벗어났습니다." + +#: utils/adt/numeric.c:1045 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "NUMERIC 스케일 %d 값은 정밀도 범위(0 .. %d)를 벗어났습니다." + +#: utils/adt/numeric.c:1063 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "잘못된 NUMERIC 형식 한정자" + +#: utils/adt/numeric.c:1395 +#, c-format +msgid "start value cannot be NaN" +msgstr "시작값은 NaN 일 수 없음" + +#: utils/adt/numeric.c:1400 +#, c-format +msgid "stop value cannot be NaN" +msgstr "종료값은 NaN 일 수 없음" + +#: utils/adt/numeric.c:1410 +#, c-format +msgid "step size cannot be NaN" +msgstr "단계 크기는 NaN 일 수 없음" + +#: utils/adt/numeric.c:2958 utils/adt/numeric.c:6064 utils/adt/numeric.c:6522 +#: utils/adt/numeric.c:8802 utils/adt/numeric.c:9240 utils/adt/numeric.c:9354 +#: utils/adt/numeric.c:9427 +#, c-format +msgid "value overflows numeric format" +msgstr "값이 수치 형식에 넘처남" + +#: utils/adt/numeric.c:3417 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "NaN 값을 정수형으로 변환할 수 없습니다" + +#: utils/adt/numeric.c:3500 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "NaN 값을 bigint형으로 변환할 수 없습니다" + +#: utils/adt/numeric.c:3545 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "NaN 값을 smallint형으로 변환할 수 없습니다" + +#: utils/adt/numeric.c:3582 utils/adt/numeric.c:3653 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "무한(infinity)은 숫자로 변환할 수 없음" + +#: utils/adt/numeric.c:6606 +#, c-format +msgid "numeric field overflow" +msgstr "수치 필드 오버플로우" + +#: utils/adt/numeric.c:6607 +#, c-format +msgid "" +"A field with precision %d, scale %d must round to an absolute value less " +"than %s%d." +msgstr "" +"전체 자릿수 %d, 소수 자릿수 %d의 필드는 %s%d보다 작은 절대 값으로 반올림해야 " +"합니다." + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "값 \"%s\"은(는) 8비트 정수의 범위를 벗어남" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "잘못된 oidvector 자료" + +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "요청된 문자가 너무 큼" + +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "요청한 문자가 너무 커서 인코딩할 수 없음: %d" + +#: utils/adt/oracle_compat.c:987 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "요청한 문자가 인코딩용으로 타당치 않음: %d" + +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "null 문자는 허용되지 않음" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "%g 퍼센트 값이 0과 1사이가 아닙니다." + +#: utils/adt/pg_locale.c:1262 +#, c-format +msgid "Apply system library package updates." +msgstr "OS 라이브러리 패키지를 업데이트 하세요." + +#: utils/adt/pg_locale.c:1477 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "\"%s\" 로케일을 만들 수 없음: %m" + +#: utils/adt/pg_locale.c:1480 +#, c-format +msgid "" +"The operating system could not find any locale data for the locale name \"%s" +"\"." +msgstr "운영체제에서 \"%s\" 로케일 이름에 대한 로케일 파일을 찾을 수 없습니다." + +#: utils/adt/pg_locale.c:1582 +#, c-format +msgid "" +"collations with different collate and ctype values are not supported on this " +"platform" +msgstr "" +"이 플랫폼에서는 서로 다른 정렬규칙(collation)과 문자집합(ctype)을 함께 쓸 수 " +"없습니다." + +#: utils/adt/pg_locale.c:1591 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "이 플랫폼에서는 LIBC 문자 정렬 제공자 기능(ICU)을 지원하지 않음." + +#: utils/adt/pg_locale.c:1603 +#, c-format +msgid "" +"collations with different collate and ctype values are not supported by ICU" +msgstr "" +"ICU 지원 기능에서는 서로 다른 정렬규칙(collation)과 문자집합(ctype)을 함께 " +"쓸 수 없습니다." + +#: utils/adt/pg_locale.c:1609 utils/adt/pg_locale.c:1696 +#: utils/adt/pg_locale.c:1969 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "\"%s\" 로케일용 문자 정렬 규칙 열기 실패: %s" + +#: utils/adt/pg_locale.c:1623 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU 지원 기능을 뺀 채로 서버가 만들어졌습니다." + +#: utils/adt/pg_locale.c:1624 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "--with-icu 옵션을 사용하여 PostgreSQL을 다시 빌드해야 합니다." + +#: utils/adt/pg_locale.c:1644 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "\"%s\" 정렬규칙은 분명한 버전이 없는데 버전을 지정했음" + +#: utils/adt/pg_locale.c:1651 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "\"%s\" 정렬규칙은 버전이 맞지 않음" + +#: utils/adt/pg_locale.c:1653 +#, c-format +msgid "" +"The collation in the database was created using version %s, but the " +"operating system provides version %s." +msgstr "" + +#: utils/adt/pg_locale.c:1656 +#, c-format +msgid "" +"Rebuild all objects affected by this collation and run ALTER COLLATION %s " +"REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "" + +#: utils/adt/pg_locale.c:1747 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "\"%s\" 로케일용 정렬 변환 규칙을 구할 수 없음: 오류 코드 %lu" + +#: utils/adt/pg_locale.c:1784 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "\"%s\" 인코딩은 ICU 기능을 지원하지 않음" + +#: utils/adt/pg_locale.c:1791 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "\"%s\" 인코딩용 ICU 변환기 열기 실패: %s" + +#: utils/adt/pg_locale.c:1822 utils/adt/pg_locale.c:1831 +#: utils/adt/pg_locale.c:1860 utils/adt/pg_locale.c:1870 +#, c-format +msgid "%s failed: %s" +msgstr "%s 실패: %s" + +#: utils/adt/pg_locale.c:2142 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "로케일을 위한 잘못된 멀티바이트 문자" + +#: utils/adt/pg_locale.c:2143 +#, c-format +msgid "" +"The server's LC_CTYPE locale is probably incompatible with the database " +"encoding." +msgstr "서버의 LC_CTYPE 로케일은 이 데이터베이스 인코딩과 호환되지 않습니다." + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "함수는 서버가 이진 업그레이드 상태에서만 호출 될 수 있습니다" + +#: utils/adt/pgstatfuncs.c:500 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "잘못된 명령어 이름: \"%s\"" + +#: utils/adt/pseudotypes.c:57 utils/adt/pseudotypes.c:91 +#, c-format +msgid "cannot display a value of type %s" +msgstr "%s 자료형의 값은 표시할 수 없음" + +#: utils/adt/pseudotypes.c:283 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "셸 형태 값은 사용할 수 없음" + +#: utils/adt/pseudotypes.c:293 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "shell 형식의 값은 표시할 수 없음" + +#: utils/adt/rangetypes.c:406 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "range 자료형 구성자 플래그 인자로 null을 사용할 수 없음" + +#: utils/adt/rangetypes.c:993 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "" + +#: utils/adt/rangetypes.c:1054 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "" + +#: utils/adt/rangetypes.c:1600 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "range 자료형의 하한값은 상한값과 같거나 작아야 합니다" + +#: utils/adt/rangetypes.c:1983 utils/adt/rangetypes.c:1996 +#: utils/adt/rangetypes.c:2010 +#, c-format +msgid "invalid range bound flags" +msgstr "잘못된 range 구성 플래그" + +#: utils/adt/rangetypes.c:1984 utils/adt/rangetypes.c:1997 +#: utils/adt/rangetypes.c:2011 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "유효한 값은 \"[]\", \"[)\", \"(]\", \"()\"." + +#: utils/adt/rangetypes.c:2076 utils/adt/rangetypes.c:2093 +#: utils/adt/rangetypes.c:2106 utils/adt/rangetypes.c:2124 +#: utils/adt/rangetypes.c:2135 utils/adt/rangetypes.c:2179 +#: utils/adt/rangetypes.c:2187 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "비정상적인 range 문자: \"%s\"" + +#: utils/adt/rangetypes.c:2078 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr " \"empty\" 키워드 뒤에 정크가 있음" + +#: utils/adt/rangetypes.c:2095 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "왼쪽 괄호가 빠졌음" + +#: utils/adt/rangetypes.c:2108 +#, c-format +msgid "Missing comma after lower bound." +msgstr "하한값 뒤에 쉼표가 빠졌음" + +#: utils/adt/rangetypes.c:2126 +#, c-format +msgid "Too many commas." +msgstr "칼럼이 너무 많습니다." + +#: utils/adt/rangetypes.c:2137 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "오른쪽 괄호 다음에 정크가 있음" + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4493 +#, c-format +msgid "regular expression failed: %s" +msgstr "잘못된 정규식: %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%c\"" +msgstr "잘못된 정규식 옵션: \"%c\"" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "" +"SQL regular expression may not contain more than two escape-double-quote " +"separators" +msgstr "" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s 함수는 \"global\" 옵션을 지원하지 않음" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "대신에 regexp_matches 함수를 사용하세요." + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "너무 많음 정규식 매치" + +#: utils/adt/regproc.c:107 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "\"%s\"(이)라는 함수가 두 개 이상 있음" + +#: utils/adt/regproc.c:525 +#, c-format +msgid "more than one operator named %s" +msgstr "%s(이)라는 연산자가 두 개 이상 있음" + +#: utils/adt/regproc.c:692 utils/adt/regproc.c:733 gram.y:8223 +#, c-format +msgid "missing argument" +msgstr "인자가 빠졌음" + +#: utils/adt/regproc.c:693 utils/adt/regproc.c:734 gram.y:8224 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "단항 연산자에서 인자 없음을 표시할 때는 NONE 인자를 사용하세요." + +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 utils/adt/regproc.c:2018 +#: utils/adt/ruleutils.c:9297 utils/adt/ruleutils.c:9466 +#, c-format +msgid "too many arguments" +msgstr "인자가 너무 많습니다" + +#: utils/adt/regproc.c:698 utils/adt/regproc.c:739 +#, c-format +msgid "Provide two argument types for operator." +msgstr "연산자를 위해서는 두개의 인자 자료형을 지정하십시오." + +#: utils/adt/regproc.c:1602 utils/adt/regproc.c:1626 utils/adt/regproc.c:1727 +#: utils/adt/regproc.c:1751 utils/adt/regproc.c:1853 utils/adt/regproc.c:1858 +#: utils/adt/varlena.c:3642 utils/adt/varlena.c:3647 +#, c-format +msgid "invalid name syntax" +msgstr "잘못된 이름 구문" + +#: utils/adt/regproc.c:1916 +#, c-format +msgid "expected a left parenthesis" +msgstr "왼쪽 괄호가 필요합니다." + +#: utils/adt/regproc.c:1932 +#, c-format +msgid "expected a right parenthesis" +msgstr "오른쪽 괄호가 필요합니다." + +#: utils/adt/regproc.c:1951 +#, c-format +msgid "expected a type name" +msgstr "자료형 이름을 지정하십시오" + +#: utils/adt/regproc.c:1983 +#, c-format +msgid "improper type name" +msgstr "부적절한 형식 이름" + +#: utils/adt/ri_triggers.c:296 utils/adt/ri_triggers.c:1537 +#: utils/adt/ri_triggers.c:2470 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "" +"\"%s\" 테이블에서 자료 추가, 갱신 작업이 \"%s\" 참조키(foreign key) 제약 조건" +"을 위배했습니다" + +#: utils/adt/ri_triggers.c:299 utils/adt/ri_triggers.c:1540 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL에 null 키 값과 nonnull 키 값을 함께 사용할 수 없습니다." + +#: utils/adt/ri_triggers.c:1940 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "INSERT에 대해 \"%s\" 함수를 실행해야 함" + +#: utils/adt/ri_triggers.c:1946 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "UPDATE에 대해 \"%s\" 함수를 실행해야 함" + +#: utils/adt/ri_triggers.c:1952 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "DELETE에 대해 \"%s\" 함수를 실행해야 함" + +#: utils/adt/ri_triggers.c:1975 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "\"%s\" 트리거(해당 테이블: \"%s\")에 대한 pg_constraint 항목이 없음" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "" +"Remove this referential integrity trigger and its mates, then do ALTER TABLE " +"ADD CONSTRAINT." +msgstr "" +"해당 트리거 관련 개체를 제거한 후 ALTER TABLE ADD CONSTRAINT 명령으로 추가하" +"세요" + +#: utils/adt/ri_triggers.c:2007 gram.y:3818 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL 기능은 아직 구현 안되었습니다" + +#: utils/adt/ri_triggers.c:2295 +#, c-format +msgid "" +"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave " +"unexpected result" +msgstr "" +"\"%s\"에 대한 참조 무결성 쿼리(제약조건: \"%s\", 해당 릴레이션: \"%s\")를 실" +"행하면 예기치 않은 결과가 발생함" + +#: utils/adt/ri_triggers.c:2299 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "이 문제는 주로 룰이 재작성 되었을 때 발생합니다." + +#: utils/adt/ri_triggers.c:2460 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "\"%s\" 파티션 지우기는 \"%s\" 참조키 제약조건을 위반함" + +#: utils/adt/ri_triggers.c:2463 utils/adt/ri_triggers.c:2488 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "(%s)=(%s) 키가 \"%s\" 테이블에서 여전히 참조됩니다." + +#: utils/adt/ri_triggers.c:2474 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "(%s)=(%s) 키가 \"%s\" 테이블에 없습니다." + +#: utils/adt/ri_triggers.c:2477 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "\"%s\" 테이블에 키가 없습니다." + +#: utils/adt/ri_triggers.c:2483 +#, c-format +msgid "" +"update or delete on table \"%s\" violates foreign key constraint \"%s\" on " +"table \"%s\"" +msgstr "" +"\"%s\" 테이블의 자료 갱신, 삭제 작업이 \"%s\" 참조키(foreign key) 제약 조건 " +"- \"%s\" 테이블 - 을 위반했습니다" + +#: utils/adt/ri_triggers.c:2491 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "\"%s\" 테이블에서 키가 여전히 참조됩니다." + +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "익명 복합 형식의 입력이 구현되어 있지 않음" + +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 +#: utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "비정상적인 레코드 문자: \"%s\"" + +#: utils/adt/rowtypes.c:157 +#, c-format +msgid "Missing left parenthesis." +msgstr "왼쪽 괄호가 필요합니다." + +#: utils/adt/rowtypes.c:186 +#, c-format +msgid "Too few columns." +msgstr "칼럼이 너무 적습니다." + +#: utils/adt/rowtypes.c:269 +#, c-format +msgid "Too many columns." +msgstr "칼럼이 너무 많습니다." + +#: utils/adt/rowtypes.c:277 +#, c-format +msgid "Junk after right parenthesis." +msgstr "오른쪽 괄호가 필요합니다." + +#: utils/adt/rowtypes.c:531 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "열 수(%d)가 최대값(%d)을 초과했습니다" + +#: utils/adt/rowtypes.c:559 +#, c-format +msgid "wrong data type: %u, expected %u" +msgstr "잘못된 자료형: %u, 예상되는 자료형 %u" + +#: utils/adt/rowtypes.c:620 +#, c-format +msgid "improper binary format in record column %d" +msgstr "%d 번째 레코드 열에서 잘못된 바이너리 포맷이 있습니다" + +#: utils/adt/rowtypes.c:911 utils/adt/rowtypes.c:1157 utils/adt/rowtypes.c:1415 +#: utils/adt/rowtypes.c:1661 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "서로 다른 열 형식 %s과(와) %s(레코드 열 %d)을(를) 비교할 수 없음" + +#: utils/adt/rowtypes.c:1002 utils/adt/rowtypes.c:1227 +#: utils/adt/rowtypes.c:1512 utils/adt/rowtypes.c:1697 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "칼럼 수가 서로 다른 레코드 자료형을 비교할 수 없음" + +#: utils/adt/ruleutils.c:4821 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "\"%s\" 룰은 %d 이벤트 형태를 지원하지 않습니다" + +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "TIMESTAMP(%d)%s 정밀도로 음수를 사용할 수 없습니다" + +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIMESTAMP(%d)%s 정밀도는 최대값(%d)으로 줄였습니다" + +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:434 utils/misc/guc.c:11901 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "타임스탬프 값이 범위를 벗어났음: \"%s\"" + +#: utils/adt/timestamp.c:372 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "타임스탬프(%d) 정밀도는 %d에서 %d 사이여야 함" + +#: utils/adt/timestamp.c:496 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "숫자형 타임 존 형식은 처음에 \"-\" 또는 \"+\" 문자가 있어야 합니다." + +#: utils/adt/timestamp.c:509 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "\"%s\" 숫자형 타임 존 범위 벗어남" + +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "타임스탬프 값이 범위를 벗어났음: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:720 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "타임스탬프 값으로 NaN 값을 지정할 수 없음" + +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "타임스탬프 값이 범위를 벗어났음: \"%g\"" + +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1509 +#: utils/adt/timestamp.c:1944 utils/adt/timestamp.c:3042 +#: utils/adt/timestamp.c:3047 utils/adt/timestamp.c:3052 +#: utils/adt/timestamp.c:3102 utils/adt/timestamp.c:3109 +#: utils/adt/timestamp.c:3116 utils/adt/timestamp.c:3136 +#: utils/adt/timestamp.c:3143 utils/adt/timestamp.c:3150 +#: utils/adt/timestamp.c:3180 utils/adt/timestamp.c:3188 +#: utils/adt/timestamp.c:3232 utils/adt/timestamp.c:3659 +#: utils/adt/timestamp.c:3784 utils/adt/timestamp.c:4244 +#, c-format +msgid "interval out of range" +msgstr "간격이 범위를 벗어남" + +#: utils/adt/timestamp.c:1062 utils/adt/timestamp.c:1095 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "잘못된 INTERVAL 형식 한정자" + +#: utils/adt/timestamp.c:1078 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d) 정밀도로 음수값이 올 수 없습니다" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d) 정밀도는 허용 최대치(%d)로 감소 되었습니다" + +#: utils/adt/timestamp.c:1466 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "간격(%d) 정밀도는 %d에서 %d 사이여야 함" + +#: utils/adt/timestamp.c:2643 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "타임스탬프 무한값을 추출 할 수 없음" + +#: utils/adt/timestamp.c:3912 utils/adt/timestamp.c:4505 +#: utils/adt/timestamp.c:4667 utils/adt/timestamp.c:4688 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "\"%s\" timestamp 유닛은 지원하지 않습니다" + +#: utils/adt/timestamp.c:3926 utils/adt/timestamp.c:4459 +#: utils/adt/timestamp.c:4698 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "\"%s\" timestamp 유닛을 처리하지 못했습니다" + +#: utils/adt/timestamp.c:4056 utils/adt/timestamp.c:4500 +#: utils/adt/timestamp.c:4863 utils/adt/timestamp.c:4885 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "\"%s\" 시간대 유닛이 있는 timestamp 자료형은 지원하지 않습니다" + +#: utils/adt/timestamp.c:4073 utils/adt/timestamp.c:4454 +#: utils/adt/timestamp.c:4894 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "\"%s\" 시간대 유닛이 있는 timestamp 값을 처리하지 못했습니다" + +#: utils/adt/timestamp.c:4231 +#, c-format +msgid "" +"interval units \"%s\" not supported because months usually have fractional " +"weeks" +msgstr "" + +#: utils/adt/timestamp.c:4237 utils/adt/timestamp.c:4988 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "\"%s\" 유닛 간격(interval units)은 지원하지 않습니다" + +#: utils/adt/timestamp.c:4253 utils/adt/timestamp.c:5011 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "\"%s\" 유닛 간격(interval units)을 처리하지 못했습니다" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: 트리거로 호출되어야 함" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: 업데이트 시 호출되어야 함" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: 업데이트 전에 호출되어야 함" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: 각 행에 대해 호출되어야 함" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_in이 구현되어 있지 않음" + +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "분석 작업에서 사용한 거리값은 %d 보다 클 수 없습니다" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "tsquery에 구문 오류가 있음: \"%s\"" + +#: utils/adt/tsquery.c:334 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "tsquery에 피연산자가 없음: \"%s\"" + +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "tsquery의 값이 너무 큼: \"%s\"" + +#: utils/adt/tsquery.c:573 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "tsquery의 피연산자가 너무 긺: \"%s\"" + +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "tsquery의 단어가 너무 긺: \"%s\"" + +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "텍스트 검색 쿼리에 어휘소가 포함되어 있지 않음: \"%s\"" + +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsquery 길이가 너무 깁니다" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "" +"text-search query contains only stop words or doesn't contain lexemes, " +"ignored" +msgstr "" +"텍스트 검색 쿼리에 중지 단어만 포함되어 있거나 어휘소가 포함되어 있지 않음, " +"무시됨" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "분석 작업에서 사용한 거리값은 %d 보다 작고 양수값만 사용할 수 있습니다" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "ts_rewrite 쿼리는 두 개의 tsquery 칼럼을 반환해야 함" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "가중치 배열은 일차원 배열이어야 함" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "가중치 배열이 너무 짧음" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "가중치 배열에는 null이 포함되지 않아야 함" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:872 +#, c-format +msgid "weight out of range" +msgstr "가중치가 범위를 벗어남" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "단어가 너무 긺(%ld바이트, 최대 %ld바이트)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "" +"문자열이 너무 길어서 tsvector에 사용할 수 없음(%ld바이트, 최대 %ld바이트)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "어휘소 배열에는 null이 포함되지 않아야 함" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "가중치 배열에는 null이 포함되지 않아야 함" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "알 수 없는 가중치: \"%c\"" + +#: utils/adt/tsvector_op.c:2414 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "ts_stat 쿼리는 하나의 tsvector 칼럼을 반환해야 함" + +#: utils/adt/tsvector_op.c:2603 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "\"%s\" tsvector 칼럼이 없음" + +#: utils/adt/tsvector_op.c:2610 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "\"%s\" 칼럼은 tsvector 형식이 아님" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "\"%s\" 구성 칼럼이 없음" + +#: utils/adt/tsvector_op.c:2628 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "\"%s\" 칼럼은 regconfig 형이 아님" + +#: utils/adt/tsvector_op.c:2635 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "\"%s\" 구성 칼럼은 null이 아니어야 함" + +#: utils/adt/tsvector_op.c:2648 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "\"%s\" 텍스트 검색 구성 이름이 스키마로 한정되어야 함" + +#: utils/adt/tsvector_op.c:2673 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "\"%s\" 칼럼은 문자형이 아님" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "tsvector에 구문 오류가 있음: \"%s\"" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "이스케이프 문자가 없음: \"%s\"" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "tsvector에 잘못된 위치 정보가 있음: \"%s\"" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "무작위 값 생성 실패" + +#: utils/adt/varbit.c:109 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "%s 자료형의 길이는 최소 1 이상이어야합니다" + +#: utils/adt/varbit.c:114 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "%s 자료형의 길이는 최대 %d 이하여야합니다" + +#: utils/adt/varbit.c:197 utils/adt/varbit.c:498 utils/adt/varbit.c:993 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "비트 문자열 길이가 최대치 (%d)를 초과했습니다" + +#: utils/adt/varbit.c:211 utils/adt/varbit.c:355 utils/adt/varbit.c:405 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "" +"길이가 %d인 비트 문자열 자료는 bit(%d) 자료형의 길이와 일치하지 않습니다" + +#: utils/adt/varbit.c:233 utils/adt/varbit.c:534 +#, c-format +msgid "\"%c\" is not a valid binary digit" +msgstr "\"%c\" 문자는 2진수 문자가 아닙니다" + +#: utils/adt/varbit.c:258 utils/adt/varbit.c:559 +#, c-format +msgid "\"%c\" is not a valid hexadecimal digit" +msgstr "\"%c\" 문자는 16진수 문자가 아닙니다" + +#: utils/adt/varbit.c:346 utils/adt/varbit.c:651 +#, c-format +msgid "invalid length in external bit string" +msgstr "외부 비트 문자열의 길이가 잘못되었습니다" + +#: utils/adt/varbit.c:512 utils/adt/varbit.c:660 utils/adt/varbit.c:756 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "비트 문자열이 너무 깁니다(해당 자료형 bit varying(%d))" + +#: utils/adt/varbit.c:1086 utils/adt/varbit.c:1184 utils/adt/varlena.c:875 +#: utils/adt/varlena.c:939 utils/adt/varlena.c:1083 utils/adt/varlena.c:3306 +#: utils/adt/varlena.c:3373 +#, c-format +msgid "negative substring length not allowed" +msgstr "substring에서 음수 길이는 허용하지 않음" + +#: utils/adt/varbit.c:1241 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "서로 크기가 틀린 비트 문자열로 AND 연산을 할 수 없습니다." + +#: utils/adt/varbit.c:1282 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "서로 크기가 틀린 비트 문자열로 OR 연산을 할 수 없습니다." + +#: utils/adt/varbit.c:1322 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "서로 크기가 틀린 비트 문자열은 XOR 연산을 할 수 없습니다." + +#: utils/adt/varbit.c:1804 utils/adt/varbit.c:1862 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "비트 %d 인덱스의 범위를 벗어남 (0..%d)" + +#: utils/adt/varbit.c:1813 utils/adt/varlena.c:3566 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "새 비트값은 0 또는 1 이어야합니다" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "character(%d) 자료형에 너무 긴 자료를 담으려고 합니다." + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "character varying(%d) 자료형에 너무 긴 자료를 담으려고 합니다." + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1475 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "문자열 비교 작업에 사용할 정렬규칙(collation)을 결정할 수 없음" + +#: utils/adt/varlena.c:1182 utils/adt/varlena.c:1915 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "문자열 검색 작업에 사용할 비결정 정렬규칙(collation)을 지원하지 않음" + +#: utils/adt/varlena.c:1574 utils/adt/varlena.c:1587 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "UTF-16 인코딩으로 문자열을 변환할 수 없음: 오류번호 %lu" + +#: utils/adt/varlena.c:1602 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "유니코드 문자열 비교 실패: %m" + +#: utils/adt/varlena.c:1653 utils/adt/varlena.c:2367 +#, c-format +msgid "collation failed: %s" +msgstr "문자열 정렬: %s" + +#: utils/adt/varlena.c:2575 +#, c-format +msgid "sort key generation failed: %s" +msgstr "정렬 키 생성 실패: %s" + +#: utils/adt/varlena.c:3450 utils/adt/varlena.c:3517 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "%d 인덱스의 범위를 벗어남, 0..%d" + +#: utils/adt/varlena.c:3481 utils/adt/varlena.c:3553 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "%lld 인덱스의 범위를 벗어남, 0..%lld" + +#: utils/adt/varlena.c:4590 +#, c-format +msgid "field position must be greater than zero" +msgstr "필드 위치 값은 0 보다 커야합니다" + +#: utils/adt/varlena.c:5456 +#, c-format +msgid "unterminated format() type specifier" +msgstr "마무리 안된 format() 형 식별자" + +#: utils/adt/varlena.c:5457 utils/adt/varlena.c:5591 utils/adt/varlena.c:5712 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "하나의 \"%%\" 문자를 표시하려면, \"%%%%\" 형태로 사용하세요" + +#: utils/adt/varlena.c:5589 utils/adt/varlena.c:5710 +#, c-format +msgid "unrecognized format() type specifier \"%c\"" +msgstr "인식할 수 없는 format() 형 식별자 \"%c\"" + +#: utils/adt/varlena.c:5602 utils/adt/varlena.c:5659 +#, c-format +msgid "too few arguments for format()" +msgstr "format() 작업을 위한 인자가 너무 적음" + +#: utils/adt/varlena.c:5755 utils/adt/varlena.c:5937 +#, c-format +msgid "number is out of range" +msgstr "수치 범위를 벗어남" + +#: utils/adt/varlena.c:5818 utils/adt/varlena.c:5846 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "" +"format 함수에서 사용할 수 있는 인자 위치 번호는 0이 아니라, 1부터 시작합니다" + +#: utils/adt/varlena.c:5839 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "넓이 인자 위치값은 \"$\" 문자로 끝나야 합니다" + +#: utils/adt/varlena.c:5884 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "null 값은 SQL 식별자로 포멧될 수 없음" + +#: utils/adt/varlena.c:6010 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "" + +#: utils/adt/varlena.c:6023 +#, c-format +msgid "invalid normalization form: %s" +msgstr "잘못된 normalization 형식: %s" + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "ntile의 인자는 0보다 커야 함" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "nth_value의 인자는 0보다 커야 함" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "%s 트랜잭션 ID는 미래의 것입니다" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "외부 pg_snapshot 자료가 잘못됨" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "지원되지 않는 XML 기능" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "이 기능을 사용하려면 libxml 지원으로 서버를 빌드해야 합니다." + +#: utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "--with-libxml을 사용하여 PostgreSQL을 다시 빌드해야 합니다." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:570 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "\"%s\" 인코딩 이름이 잘못됨" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "잘못된 XML 주석" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "XML 문서가 아님" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "잘못된 XML 처리 명령" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "XML 처리 명령 대상 이름은 \"%s\"일 수 없습니다." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML 처리 명령에는 \"?>\"를 포함할 수 없습니다." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "xmlvalidate가 구현되어 있지 않음" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "XML 라이브러리를 초기화할 수 없음" + +#: utils/adt/xml.c:962 +#, c-format +msgid "" +"libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "" +"libxml2에 호환되지 않는 문자 자료형 있음: sizeof(char)=%u, sizeof(xmlChar)=%u" + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "XML 오류 핸들러를 설정할 수 없음" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "" +"This probably indicates that the version of libxml2 being used is not " +"compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "" +"이 문제는 PostgreSQL 서버를 만들 때 사용한 libxml2 헤더 파일이 호환성이 없는 " +"것 같습니다." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "잘못된 문자 값입니다." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "공간이 필요합니다." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "독립 실행형은 'yes' 또는 'no'만 허용합니다." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "선언 형식이 잘못됨: 버전이 누락되었습니다." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "텍스트 선언에서 인코딩이 누락되었습니다." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "XML 선언 구문 분석 중: '?>'가 필요합니다." + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "인식할 수 없는 libxml 오류 코드: %d." + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML은 무한 날짜 값을 지원하지 않습니다." + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML은 무한 타임스탬프 값을 지원하지 않습니다." + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "잘못된 쿼리" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "XML 네임스페이스 매핑에 사용할 배열이 잘못됨" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "" +"The array must be two-dimensional with length of the second axis equal to 2." +msgstr "" +"이 배열은 key, value로 구성된 배열을 요소로 하는 2차원 배열이어야 합니다." + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "XPath 식이 비어 있음" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "네임스페이스 이름 및 URI는 null일 수 없음" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "" +"이름 \"%s\" 및 URI \"%s\"을(를) 사용하여 XML 네임스페이스를 등록할 수 없음" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "DEFAULT 네임스페이스는 지원하지 않습니다." + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "로우 경로 필터는 비어있으면 안됩니다" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "칼럼 경로 필터는 비어있으면 안됩니다" + +#: utils/adt/xml.c:4661 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "칼럼 XPath 표현식에 사용된 결과가 하나 이상의 값을 사용합니다" + +#: utils/cache/lsyscache.c:1015 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "%s 형에서 %s 형으로 바꾸는 형변환 규칙(cast)가 없음" + +# # nonun 부분 end +#: utils/cache/lsyscache.c:2764 utils/cache/lsyscache.c:2797 +#: utils/cache/lsyscache.c:2830 utils/cache/lsyscache.c:2863 +#, c-format +msgid "type %s is only a shell" +msgstr "%s 형식은 셸일 뿐임" + +#: utils/cache/lsyscache.c:2769 +#, c-format +msgid "no input function available for type %s" +msgstr "%s 자료형을 위한 입력 함수가 없습니다" + +#: utils/cache/lsyscache.c:2802 +#, c-format +msgid "no output function available for type %s" +msgstr "%s 자료형을 위한 출력 함수가 없습니다" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "" +"operator class \"%s\" of access method %s is missing support function %d for " +"type %s" +msgstr "" +"\"%s\" 연산자 클래스(접근 방법: %s)에는 %d 개의 지원 지원 함수(해당 자료형 " +"%s)가 빠졌습니다" + +#: utils/cache/plancache.c:718 +#, c-format +msgid "cached plan must not change result type" +msgstr "캐시된 계획에서 결과 형식을 바꾸지 않아야 함" + +#: utils/cache/relcache.c:6078 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "\"%s\" 릴레이션-캐시 초기화 파일을 만들 수 없음: %m" + +#: utils/cache/relcache.c:6080 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "어쨌든 계속하는데, 뭔가 잘못 된 것이 있습니다." + +#: utils/cache/relcache.c:6402 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "\"%s\" 캐쉬 파일을 삭제할 수 없음: %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "릴레이션 맵핑을 변경하는 트랜잭셜을 PREPARE할 수 없음" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "\"%s\" 릴레이션 맵핑 파일에 잘못된 데이터가 있습니다" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "\"%s\" 릴레이션 맵핑 파일에 잘못된 checksum 값이 있음" + +#: utils/cache/typcache.c:1692 utils/fmgr/funcapi.c:461 +#, c-format +msgid "record type has not been registered" +msgstr "레코드 형식이 등록되지 않았음" + +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "TRAP: ExceptionalCondition: 잘못된 인자\n" + +#: utils/error/assert.c:40 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "TRAP: %s(\"%s\", 파일: \"%s\", 줄: %d)\n" + +#: utils/error/elog.c:322 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "오류 메시지 처리가 활성화 되기 전에 오류가 발생했습니다\n" + +#: utils/error/elog.c:1868 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "stderr 로 사용하기 위해 \"%s\" 파일 다시 열기 실패: %m" + +#: utils/error/elog.c:1881 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "표준출력(stdout)으로 사용하기 위해 \"%s\" 파일을 여는 도중 실패: %m" + +#: utils/error/elog.c:2373 utils/error/elog.c:2407 utils/error/elog.c:2423 +msgid "[unknown]" +msgstr "[알수없음]" + +#: utils/error/elog.c:2893 utils/error/elog.c:3203 utils/error/elog.c:3311 +msgid "missing error text" +msgstr "오류 내용을 뺍니다" + +#: utils/error/elog.c:2896 utils/error/elog.c:2899 utils/error/elog.c:3314 +#: utils/error/elog.c:3317 +#, c-format +msgid " at character %d" +msgstr " %d 번째 문자 부근" + +#: utils/error/elog.c:2909 utils/error/elog.c:2916 +msgid "DETAIL: " +msgstr "상세정보: " + +#: utils/error/elog.c:2923 +msgid "HINT: " +msgstr "힌트: " + +#: utils/error/elog.c:2930 +msgid "QUERY: " +msgstr "쿼리:" + +#: utils/error/elog.c:2937 +msgid "CONTEXT: " +msgstr "내용: " + +#: utils/error/elog.c:2947 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "위치: %s, %s:%d\n" + +#: utils/error/elog.c:2954 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "위치: %s:%d\n" + +#: utils/error/elog.c:2961 +msgid "BACKTRACE: " +msgstr "" + +#: utils/error/elog.c:2975 +msgid "STATEMENT: " +msgstr "명령 구문: " + +#: utils/error/elog.c:3364 +msgid "DEBUG" +msgstr "디버그" + +#: utils/error/elog.c:3368 +msgid "LOG" +msgstr "로그" + +#: utils/error/elog.c:3371 +msgid "INFO" +msgstr "정보" + +#: utils/error/elog.c:3374 +msgid "NOTICE" +msgstr "알림" + +#: utils/error/elog.c:3377 +msgid "WARNING" +msgstr "경고" + +#: utils/error/elog.c:3380 +msgid "ERROR" +msgstr "오류" + +#: utils/error/elog.c:3383 +msgid "FATAL" +msgstr "치명적오류" + +#: utils/error/elog.c:3386 +msgid "PANIC" +msgstr "손상" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "\"%s\" 함수를 \"%s\" 파일에서 찾을 수 없음" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "\"%s\" 라이브러리를 불러 올 수 없음: %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "\"%s\" 라이브러리는 사용할 수 없습니다: magic black 없음" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "확장 라이브러리를 만들 때, PG_MODULE_MAGIC 매크로를 사용해서 만드세요." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "\"%s\" 라이브러리는 사용할 수 없습니다: 버전이 틀림" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "서버 버전 = %d, 라이브러리 버전 %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "서버의 경우 FUNC_MAX_ARGS = %d인데 라이브러리에 %d이(가) 있습니다." + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "서버의 경우 INDEX_MAX_KEYS = %d인데 라이브러리에 %d이(가) 있습니다." + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "서버의 경우 NAMEDATALEN = %d인데 라이브러리에 %d이(가) 있습니다." + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "서버의 경우 FLOAT8PASSBYVAL = %s인데 라이브러리에 %s이(가) 있습니다." + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "매직 블록에 예기치 않은 길이 또는 여백 차이가 있습니다." + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "\"%s\" 라이브러리는 사용할 수 없습니다: magic black 틀림" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "\"%s\" 라이브러리 사용이 금지되어있습니다" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "동적 라이브러리 경로에서 잘못된 매크로 이름: %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "\"dynamic_library_path\" 매개 변수 값으로 길이가 0인 값을 사용했음" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "\"dynamic_library_path\" 매개 변수 값으로 절대 경로를 사용할 수 없음" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "\"%s\" 내부 함수를 내부 검색 테이블에서 찾을 수 없습니다" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "\"%s\" 함수의 함수 정보를 찾을 수 없음" + +#: utils/fmgr/fmgr.c:489 +#, c-format +msgid "" +"SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "" + +#: utils/fmgr/fmgr.c:507 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "_^_ %d 알수 없는 API 버전이 \"%s\" 함수에 의해서 보고되었음" + +#: utils/fmgr/fmgr.c:2003 +#, c-format +msgid "operator class options info is absent in function call context" +msgstr "" + +#: utils/fmgr/fmgr.c:2070 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "" +"%u OID 언어 유효성 검사 함수가 %u OID 프로시져 언어용으로 호출되었음, 원래 언" +"어는 %u" + +#: utils/fmgr/funcapi.c:384 +#, c-format +msgid "" +"could not determine actual result type for function \"%s\" declared to " +"return type %s" +msgstr "\"%s\" 함수의 실재 리턴 자료형을 알 수 없음, 정의된 리턴 자료형: %s" + +#: utils/fmgr/funcapi.c:1651 utils/fmgr/funcapi.c:1683 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "alias 수가 열 수와 틀립니다" + +#: utils/fmgr/funcapi.c:1677 +#, c-format +msgid "no column alias was provided" +msgstr "열 별칭이 제공되지 않았음" + +#: utils/fmgr/funcapi.c:1701 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "레코드를 리턴하는 함수를 위한 행(row) 구성 정보를 구할 수 없음" + +#: utils/init/miscinit.c:285 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "\"%s\" 데이터 디렉터리 없음" + +#: utils/init/miscinit.c:290 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 읽기 권한 없음: %m" + +#: utils/init/miscinit.c:298 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "지정한 \"%s\" 데이터 디렉터리는 디렉터리가 아님" + +#: utils/init/miscinit.c:314 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "\"%s\" 데이터 디렉터리 소유주가 잘못 되었습니다." + +#: utils/init/miscinit.c:316 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "서버는 지정한 데이터 디렉터리의 소유주 권한으로 시작되어야합니다." + +#: utils/init/miscinit.c:334 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "\"%s\" 데이터 디렉터리 접근 권한에 문제가 있습니다." + +#: utils/init/miscinit.c:336 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "액세스 권한은 u=rwx (0700) 또는 u=rwx,o=rx (0750) 값이어야 합니다." + +#: utils/init/miscinit.c:615 utils/misc/guc.c:7139 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "보안 제한 작업 내에서 \"%s\" 매개 변수를 설정할 수 없음" + +#: utils/init/miscinit.c:683 +#, c-format +msgid "role with OID %u does not exist" +msgstr "%u OID 롤이 없음" + +#: utils/init/miscinit.c:713 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "\"%s\" 롤은 접속을 허용하지 않음" + +#: utils/init/miscinit.c:731 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "\"%s\" 롤의 최대 동시 접속수를 초과했습니다" + +#: utils/init/miscinit.c:791 +#, c-format +msgid "permission denied to set session authorization" +msgstr "세션 인증을 지정하기 위한 권한이 없음" + +#: utils/init/miscinit.c:874 +#, c-format +msgid "invalid role OID: %u" +msgstr "잘못된 롤 OID: %u" + +#: utils/init/miscinit.c:928 +#, c-format +msgid "database system is shut down" +msgstr "데이터베이스 시스템 서비스를 중지했습니다" + +#: utils/init/miscinit.c:1015 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "\"%s\" 잠금 파일을 만들 수 없음: %m" + +#: utils/init/miscinit.c:1029 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "\"%s\" 잠금파일을 열 수 없음: %m" + +#: utils/init/miscinit.c:1036 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "\"%s\" 잠금 파일을 읽을 수 없음: %m" + +#: utils/init/miscinit.c:1045 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "\"%s\" 잠금 파일이 비었음" + +#: utils/init/miscinit.c:1046 +#, c-format +msgid "" +"Either another server is starting, or the lock file is the remnant of a " +"previous server startup crash." +msgstr "" + +#: utils/init/miscinit.c:1090 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "\"%s\" 잠금 파일이 이미 있음" + +#: utils/init/miscinit.c:1094 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "" +"다른 postgres 프로그램(PID %d)이 \"%s\" 데이터 디렉터리를 사용해서 실행중입니" +"까?" + +#: utils/init/miscinit.c:1096 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "" +"다른 postmaster 프로그램(PID %d)이 \"%s\" 데이터 디렉터리를 사용해서 실행중입" +"니까?" + +#: utils/init/miscinit.c:1099 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "" +"다른 postgres 프로그램(PID %d)이 \"%s\" 소켓 파일을 사용해서 실행중입니까?" + +#: utils/init/miscinit.c:1101 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "" +"다른 postmaster 프로그램(PID %d)이 \"%s\" 소켓 파일을 사용해서 실행중입니까?" + +#: utils/init/miscinit.c:1152 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "\"%s\" 옛 잠금 파일을 삭제할 수 없음: %m" + +#: utils/init/miscinit.c:1154 +#, c-format +msgid "" +"The file seems accidentally left over, but it could not be removed. Please " +"remove the file by hand and try again." +msgstr "" +"그파일은 우연찮게 왼쪽을 넘어간 것(?) 같습지만, 삭제될 수는 없습니다. 직접 " +"셸 명령을 이용해서 파일을 삭제 하고 다시 시도해 보십시오. - 내용 참 거시기 하" +"네" + +#: utils/init/miscinit.c:1191 utils/init/miscinit.c:1205 +#: utils/init/miscinit.c:1216 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "\"%s\" 잠금 파일에 쓸 수 없음: %m" + +#: utils/init/miscinit.c:1327 utils/init/miscinit.c:1469 utils/misc/guc.c:10038 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "\"%s\" 파일을 읽을 수 없음: %m" + +#: utils/init/miscinit.c:1457 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "\"%s\" 파일을 열 수 없음: %m; 어째든 계속 진행함" + +#: utils/init/miscinit.c:1482 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "\"%s\" 잠금 파일에 있는 PID 값이 이상합니다: 현재값 %ld, 원래값 %ld" + +#: utils/init/miscinit.c:1521 utils/init/miscinit.c:1537 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\" 값은 바른 데이터디렉터리가 아닙니다" + +#: utils/init/miscinit.c:1523 +#, c-format +msgid "File \"%s\" is missing." +msgstr "\"%s\" 파일이 없습니다." + +#: utils/init/miscinit.c:1539 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "\"%s\" 파일에 잘못된 자료가 기록되어 있습니다." + +#: utils/init/miscinit.c:1541 +#, c-format +msgid "You might need to initdb." +msgstr "initdb 명령을 실행해 새 클러스터를 만들어야 할 수도 있습니다." + +#: utils/init/miscinit.c:1549 +#, c-format +msgid "" +"The data directory was initialized by PostgreSQL version %s, which is not " +"compatible with this version %s." +msgstr "" +"이 데이터 디렉터리는 PostgreSQL %s 버전으로 초기화 되어있는데, 이 서버의 %s " +"버전은 이 버전과 호환성이 없습니다." + +#: utils/init/miscinit.c:1616 +#, c-format +msgid "loaded library \"%s\"" +msgstr "\"%s\" 라이브러리 로드 완료" + +#: utils/init/postinit.c:255 +#, c-format +msgid "" +"replication connection authorized: user=%s application_name=%s SSL enabled " +"(protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "" +"복제 연결 인증: 사용자=%s application_name=%s SSL 활성화 (프로토콜=%s, 알고리" +"즘=%s, 비트=%d, 압축=%s)" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "off" +msgstr "off" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "on" +msgstr "on" + +#: utils/init/postinit.c:262 +#, c-format +msgid "" +"replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=" +"%s, bits=%d, compression=%s)" +msgstr "" +"복제 연결 인증: 사용자=%s SSL 활성화 (프로토콜=%s, 알고리즘=%s, 비트=%d, 압축" +"=%s)" + +#: utils/init/postinit.c:272 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s" +msgstr "복제 연결 인증: 사용자=%s application_name=%s" + +#: utils/init/postinit.c:275 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "복제 연결 인증: 사용자=%s" + +#: utils/init/postinit.c:284 +#, c-format +msgid "" +"connection authorized: user=%s database=%s application_name=%s SSL enabled " +"(protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "" +"연결 인증: 사용자=%s 데이터베이스=%s application_name=%s SSL 활성화 (프로토콜" +"=%s, 알고리즘=%s, 비트=%d, 압축=%s)" + +#: utils/init/postinit.c:290 +#, c-format +msgid "" +"connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=" +"%s, bits=%d, compression=%s)" +msgstr "" +"연결 인증: 사용자=%s 데이터베이스=%s SSL 활성화 (프로토콜=%s, 알고리즘=%s, 비" +"트=%d, 압축=%s)" + +#: utils/init/postinit.c:300 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s" +msgstr "연결 인증: 사용자=%s 데이터베이스=%s application_name=%s" + +#: utils/init/postinit.c:302 +#, c-format +msgid "connection authorized: user=%s database=%s" +msgstr "연결 인증: 사용자=%s 데이터베이스=%s" + +#: utils/init/postinit.c:334 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "\"%s\" 데이터베이스는 pg_database 항목에 없습니다" + +#: utils/init/postinit.c:336 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "데이터베이스 OID %u이(가) 현재 \"%s\"에 속해 있는 것 같습니다." + +#: utils/init/postinit.c:356 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "\"%s\" 데이터베이스는 현재 접속을 허용하지 않습니다" + +#: utils/init/postinit.c:369 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "\"%s\" 데이터베이스 액세스 권한 없음" + +#: utils/init/postinit.c:370 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "사용자에게 CONNECT 권한이 없습니다." + +#: utils/init/postinit.c:387 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "\"%s\" 데이터베이스 최대 접속수를 초과했습니다" + +#: utils/init/postinit.c:409 utils/init/postinit.c:416 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "데이터베이스 로케일이 운영 체제와 호환되지 않음" + +#: utils/init/postinit.c:410 +#, c-format +msgid "" +"The database was initialized with LC_COLLATE \"%s\", which is not " +"recognized by setlocale()." +msgstr "" +"데이터베이스가 setlocale()에서 인식할 수 없는 LC_COLLATE \"%s\"(으)로 초기화" +"되었습니다." + +#: utils/init/postinit.c:412 utils/init/postinit.c:419 +#, c-format +msgid "" +"Recreate the database with another locale or install the missing locale." +msgstr "" +"다른 로케일로 데이터베이스를 다시 만들거나 누락된 로케일을 설치하십시오." + +#: utils/init/postinit.c:417 +#, c-format +msgid "" +"The database was initialized with LC_CTYPE \"%s\", which is not recognized " +"by setlocale()." +msgstr "" +"setlocale()에서 인식할 수 없는 \"%s\" LC_CTYPE 값으로 데이터베이스가 초기화되" +"었습니다." + +#: utils/init/postinit.c:762 +#, c-format +msgid "no roles are defined in this database system" +msgstr "이 데이터베이스에는 어떠한 롤 정의도 없습니다" + +#: utils/init/postinit.c:763 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "다음 명령을 먼저 실행하십시오: CREATE USER \"%s\" SUPERUSER;." + +#: utils/init/postinit.c:799 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "데이터베이스 중지 중에는 새로운 복제 연결을 할 수 없습니다." + +#: utils/init/postinit.c:803 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "슈퍼유저만 데이터베이스 종료 중에 연결할 수 있음" + +#: utils/init/postinit.c:813 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "슈퍼유저만 바이너리 업그레이드 모드 중에 연결 할 수 있음" + +#: utils/init/postinit.c:826 +#, c-format +msgid "" +"remaining connection slots are reserved for non-replication superuser " +"connections" +msgstr "남은 연결 슬롯은 non-replication 슈퍼유저 연결용으로 남겨 놓았음" + +#: utils/init/postinit.c:836 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "" +"superuser 또는 replication 권한을 가진 롤만 walsender 프로세스를 시작할 수 있" +"음" + +#: utils/init/postinit.c:905 +#, c-format +msgid "database %u does not exist" +msgstr "%u 데이터베이스가 없음" + +#: utils/init/postinit.c:994 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "삭제되었거나 이름이 바뀐 것 같습니다." + +#: utils/init/postinit.c:1012 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "데이터베이스 디렉터리에 \"%s\" 하위 디렉터리가 없습니다" + +#: utils/init/postinit.c:1017 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 액세스할 수 없습니다: %m" + +#: utils/mb/conv.c:443 utils/mb/conv.c:635 +#, c-format +msgid "invalid encoding number: %d" +msgstr "잘못된 인코딩 번호: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "%d은(는) ISO 8859 문자 집합에 대한 예기치 않은 인코딩 ID임" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "%d은(는) WIN 문자 집합에 대한 예기치 않은 인코딩 ID임" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:842 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "%s 인코딩과 %s 인코딩 사이의 변환은 지원하지 않습니다" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "" +"default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "" +"\"%s\" 인코딩을 \"%s\" 인코딩으로 변환할 기본 변환규칙(conversion)이 없음" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:429 utils/mb/mbutils.c:758 +#: utils/mb/mbutils.c:784 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "%d바이트의 문자열은 너무 길어서 인코딩 규칙에 맞지 않습니다." + +#: utils/mb/mbutils.c:511 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "\"%s\" 원본 인코딩 이름이 타당치 못함" + +#: utils/mb/mbutils.c:516 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "\"%s\" 대상 인코딩 이름이 타당치 못함" + +#: utils/mb/mbutils.c:656 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "\"%s\" 인코딩에서 사용할 수 없는 바이트: 0x%02x" + +#: utils/mb/mbutils.c:819 +#, c-format +msgid "invalid Unicode code point" +msgstr "잘못된 유니코드 코드 포인트" + +#: utils/mb/mbutils.c:1087 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codeset 실패" + +#: utils/mb/mbutils.c:1595 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "\"%s\" 인코딩에서 사용할 수 없는 문자가 있음: %s" + +#: utils/mb/mbutils.c:1628 +#, c-format +msgid "" +"character with byte sequence %s in encoding \"%s\" has no equivalent in " +"encoding \"%s\"" +msgstr "" +"%s 바이트로 조합된 문자(인코딩: \"%s\")와 대응되는 문자 코드가 \"%s\" 인코딩" +"에는 없습니다" + +#: utils/misc/guc.c:679 +msgid "Ungrouped" +msgstr "소속그룹없음" + +#: utils/misc/guc.c:681 +msgid "File Locations" +msgstr "파일 위치" + +#: utils/misc/guc.c:683 +msgid "Connections and Authentication" +msgstr "연결과 인증" + +#: utils/misc/guc.c:685 +msgid "Connections and Authentication / Connection Settings" +msgstr "연결과 인증 / 연결 설정값" + +#: utils/misc/guc.c:687 +msgid "Connections and Authentication / Authentication" +msgstr "연결과 인증 / 인증" + +#: utils/misc/guc.c:689 +msgid "Connections and Authentication / SSL" +msgstr "연결과 인증 / SSL" + +#: utils/misc/guc.c:691 +msgid "Resource Usage" +msgstr "자원 사용량" + +#: utils/misc/guc.c:693 +msgid "Resource Usage / Memory" +msgstr "자원 사용량 / 메모리" + +#: utils/misc/guc.c:695 +msgid "Resource Usage / Disk" +msgstr "자원 사용량 / 디스크" + +#: utils/misc/guc.c:697 +msgid "Resource Usage / Kernel Resources" +msgstr "자원 사용량 / 커널 자원" + +#: utils/misc/guc.c:699 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "자원 사용량 / 비용기반 청소 지연" + +#: utils/misc/guc.c:701 +msgid "Resource Usage / Background Writer" +msgstr "자원 사용량 / 백그라운드 쓰기" + +#: utils/misc/guc.c:703 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "자원 사용량 / 비동기 기능" + +#: utils/misc/guc.c:705 +msgid "Write-Ahead Log" +msgstr "Write-Ahead 로그" + +#: utils/misc/guc.c:707 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead 로그 / 설정값" + +#: utils/misc/guc.c:709 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead 로그 / 체크포인트" + +#: utils/misc/guc.c:711 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead 로그 / 아카이브" + +#: utils/misc/guc.c:713 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead 로그 / 아카이브 복구" + +#: utils/misc/guc.c:715 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead 로그 / 복구 대상" + +#: utils/misc/guc.c:717 +msgid "Replication" +msgstr "복제" + +#: utils/misc/guc.c:719 +msgid "Replication / Sending Servers" +msgstr "복제 / 보내기 서버" + +#: utils/misc/guc.c:721 +msgid "Replication / Master Server" +msgstr "복제 / 주 서버" + +#: utils/misc/guc.c:723 +msgid "Replication / Standby Servers" +msgstr "복제 / 대기 서버" + +#: utils/misc/guc.c:725 +msgid "Replication / Subscribers" +msgstr "복제 / 구독" + +#: utils/misc/guc.c:727 +msgid "Query Tuning" +msgstr "쿼리 튜닝" + +#: utils/misc/guc.c:729 +msgid "Query Tuning / Planner Method Configuration" +msgstr "쿼리 튜닝 / 실행계획기 메서드 설정" + +#: utils/misc/guc.c:731 +msgid "Query Tuning / Planner Cost Constants" +msgstr "쿼리 튜닝 / 실행계획기 비용 상수" + +#: utils/misc/guc.c:733 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "쿼리 튜닝 / 일반적인 쿼리 최적화기" + +#: utils/misc/guc.c:735 +msgid "Query Tuning / Other Planner Options" +msgstr "쿼리 튜닝 / 기타 실행계획기 옵션들" + +#: utils/misc/guc.c:737 +msgid "Reporting and Logging" +msgstr "보고와 로그" + +#: utils/misc/guc.c:739 +msgid "Reporting and Logging / Where to Log" +msgstr "보고와 로그 / 로그 위치" + +#: utils/misc/guc.c:741 +msgid "Reporting and Logging / When to Log" +msgstr "보고와 로그 / 로그 시점" + +#: utils/misc/guc.c:743 +msgid "Reporting and Logging / What to Log" +msgstr "보고와 로그 / 로그 내용" + +#: utils/misc/guc.c:745 +msgid "Process Title" +msgstr "프로세스 제목" + +#: utils/misc/guc.c:747 +msgid "Statistics" +msgstr "통계" + +#: utils/misc/guc.c:749 +msgid "Statistics / Monitoring" +msgstr "통계 / 모니터링" + +#: utils/misc/guc.c:751 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "통계 / 쿼리 및 인덱스 사용 통계 수집기" + +#: utils/misc/guc.c:753 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:755 +msgid "Client Connection Defaults" +msgstr "클라이언트 연결 초기값" + +#: utils/misc/guc.c:757 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "클라이언트 연결 초기값 / 구문 특성" + +#: utils/misc/guc.c:759 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "클라이언트 연결 초기값 / 로케일과 출력양식" + +#: utils/misc/guc.c:761 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "클라이언트 연결 초기값 / 공유 라이브러리 미리 로딩" + +#: utils/misc/guc.c:763 +msgid "Client Connection Defaults / Other Defaults" +msgstr "클라이언트 연결 초기값 / 기타 초기값" + +#: utils/misc/guc.c:765 +msgid "Lock Management" +msgstr "잠금 관리" + +#: utils/misc/guc.c:767 +msgid "Version and Platform Compatibility" +msgstr "버전과 플랫폼 호환성" + +#: utils/misc/guc.c:769 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "버전과 플랫폼 호환성 / 이전 PostgreSQL 버전" + +#: utils/misc/guc.c:771 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "버전과 플랫폼 호환성 / 다른 플랫폼과 클라이언트" + +#: utils/misc/guc.c:773 +msgid "Error Handling" +msgstr "오류 처리" + +#: utils/misc/guc.c:775 +msgid "Preset Options" +msgstr "프리셋 옵션들" + +#: utils/misc/guc.c:777 +msgid "Customized Options" +msgstr "사용자 정의 옵션들" + +#: utils/misc/guc.c:779 +msgid "Developer Options" +msgstr "개발자 옵션들" + +#: utils/misc/guc.c:837 +msgid "" +"Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "" +"이 매개 변수에 유효한 단위는 \"B\", \"kB\", \"MB\",\"GB\", \"TB\" 입니다." + +#: utils/misc/guc.c:874 +msgid "" +"Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", " +"and \"d\"." +msgstr "" +"이 매개 변수에 유효한 단위는 \"us\", \"ms\", \"s\", \"min\", \"h\", \"d\" 입" +"니다." + +#: utils/misc/guc.c:936 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "실행계획자가 순차적-스캔(sequential-sca) 계획을 사용함" + +#: utils/misc/guc.c:946 +msgid "Enables the planner's use of index-scan plans." +msgstr "실행계획자가 인덱스-스캔 계획을 사용함." + +#: utils/misc/guc.c:956 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "실행계획자가 인덱스-전용-탐색 계획을 사용함." + +#: utils/misc/guc.c:966 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "실행계획기가 bitmap-scan 계획을 사용하도록 함" + +#: utils/misc/guc.c:976 +msgid "Enables the planner's use of TID scan plans." +msgstr "실행계획자가 TID 스캔 계획을 사용함" + +#: utils/misc/guc.c:986 +msgid "Enables the planner's use of explicit sort steps." +msgstr "실행계획자가 명시 정렬 단계(explicit sort step)를 사용함" + +#: utils/misc/guc.c:996 +msgid "Enables the planner's use of incremental sort steps." +msgstr "실행계획자가 증분 정렬 단계(incremental sort step)를 사용함" + +#: utils/misc/guc.c:1005 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "실행계획자가 해시된 집계 계획을 사용함" + +#: utils/misc/guc.c:1015 +msgid "Enables the planner's use of materialization." +msgstr "실행계획자가 materialization 계획을 사용함" + +#: utils/misc/guc.c:1025 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "실행계획자가 근접순환 조인(nested-loop join) 계획을 사용함" + +#: utils/misc/guc.c:1035 +msgid "Enables the planner's use of merge join plans." +msgstr "실행계획자가 병합 조인(merge join) 계획을 사용함" + +#: utils/misc/guc.c:1045 +msgid "Enables the planner's use of hash join plans." +msgstr "실행계획자가 해시 조인(hash join) 계획을 사용함" + +#: utils/misc/guc.c:1055 +msgid "Enables the planner's use of gather merge plans." +msgstr "실행계획자가 병합 수집(gather merge) 계획을 사용함" + +#: utils/misc/guc.c:1065 +msgid "Enables partitionwise join." +msgstr "" + +#: utils/misc/guc.c:1075 +msgid "Enables partitionwise aggregation and grouping." +msgstr "" + +#: utils/misc/guc.c:1085 +msgid "Enables the planner's use of parallel append plans." +msgstr "실행계획자가 병렬 추가 계획을 사용함" + +#: utils/misc/guc.c:1095 +msgid "Enables the planner's use of parallel hash plans." +msgstr "실행계획자가 병렬 해시 계획을 사용함" + +#: utils/misc/guc.c:1105 +msgid "Enables plan-time and run-time partition pruning." +msgstr "" + +#: utils/misc/guc.c:1106 +msgid "" +"Allows the query planner and executor to compare partition bounds to " +"conditions in the query to determine which partitions must be scanned." +msgstr "" + +#: utils/misc/guc.c:1117 +msgid "Enables genetic query optimization." +msgstr "유전적 쿼리 최적화(GEQO)를 사용함" + +#: utils/misc/guc.c:1118 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "이 알고리즘은 실행계획기의 과도한 작업 비용을 낮춥니다" + +#: utils/misc/guc.c:1129 +msgid "Shows whether the current user is a superuser." +msgstr "현재 사용자가 슈퍼유저인지 보여줍니다." + +#: utils/misc/guc.c:1139 +msgid "Enables advertising the server via Bonjour." +msgstr "Bonjour 서버 사용" + +#: utils/misc/guc.c:1148 +msgid "Collects transaction commit time." +msgstr "트랜잭션 커밋 시간을 수집함" + +#: utils/misc/guc.c:1157 +msgid "Enables SSL connections." +msgstr "SSL 연결을 가능하게 함." + +#: utils/misc/guc.c:1166 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "" + +#: utils/misc/guc.c:1175 +msgid "Give priority to server ciphersuite order." +msgstr "SSL 인증 알고리즘 우선 순위를 정함" + +#: utils/misc/guc.c:1184 +msgid "Forces synchronization of updates to disk." +msgstr "강제로 변경된 버퍼 자료를 디스크와 동기화 시킴." + +#: utils/misc/guc.c:1185 +msgid "" +"The server will use the fsync() system call in several places to make sure " +"that updates are physically written to disk. This insures that a database " +"cluster will recover to a consistent state after an operating system or " +"hardware crash." +msgstr "" +"이 서버는 fsync() 시스템 콜 기능을 여러 곳에서 사용할 것입니다. 이 기능은 물" +"리적으로 디스크에 변경된 자료를 즉각적으로 기록함을 의미합니다. 이 기능은 시" +"스템의 비정상적인 동작이나, 하드웨어에서 오류가 발생되었을 경우에도 자료를 안" +"전하게 지킬 수 있도록 도와줄 것입니다." + +#: utils/misc/guc.c:1196 +msgid "Continues processing after a checksum failure." +msgstr "체크섬 실패 후 처리 계속 함" + +#: utils/misc/guc.c:1197 +msgid "" +"Detection of a checksum failure normally causes PostgreSQL to report an " +"error, aborting the current transaction. Setting ignore_checksum_failure to " +"true causes the system to ignore the failure (but still report a warning), " +"and continue processing. This behavior could cause crashes or other serious " +"problems. Only has an effect if checksums are enabled." +msgstr "" +"일반적으로 손상된 페이지 헤더를 발견하게 되면, PostgreSQL에서는 오류를 발생하" +"고, 현재 트랜잭션을 중지합니다. ignore_checksum_failure 값을 true로 지정하" +"면, 이런 손상된 페이지를 발견하면, 경고 메시지를 보여주고, 계속 진행합니다. " +"이 기능을 사용한다 함은 서버 비정상 종료나 기타 심각한 문제가 일어 날 수 있습" +"니다. 이 설정은 데이터 클러스터에서 체크섬 기능이 활성화 되어 있는 경우에만 " +"영향을 받습니다." + +#: utils/misc/guc.c:1211 +msgid "Continues processing past damaged page headers." +msgstr "손상된 자료 헤더 발견시 작업 진행 여부 선택" + +#: utils/misc/guc.c:1212 +msgid "" +"Detection of a damaged page header normally causes PostgreSQL to report an " +"error, aborting the current transaction. Setting zero_damaged_pages to true " +"causes the system to instead report a warning, zero out the damaged page, " +"and continue processing. This behavior will destroy data, namely all the " +"rows on the damaged page." +msgstr "" +"일반적으로 손상된 페이지 헤더를 발견하게 되면, PostgreSQL에서는 오류를 발생하" +"고, 현재 트랜잭션을 중지합니다. zero_damaged_pages 값을 true로 지정하면, 이런 손상된 페이지" +"를 발견하면, 경고 메시지를 보여주고, 그 페이지의 크기를 0으로 만들고 작업을 " +"계속 진행합니다. 이 기능을 사용한다 함은 손상된 자료를 없애겠다는 것을 의미합" +"니다. 이것은 곧 저장되어있는 자료가 삭제 될 수도 있음을 의미하기도 합니다." + +#: utils/misc/guc.c:1225 +msgid "Continues recovery after an invalid pages failure." +msgstr "잘못된 페이지 실패 후 복구 계속 함" + +#: utils/misc/guc.c:1226 +msgid "" +"Detection of WAL records having references to invalid pages during recovery " +"causes PostgreSQL to raise a PANIC-level error, aborting the recovery. " +"Setting ignore_invalid_pages to true causes the system to ignore invalid " +"page references in WAL records (but still report a warning), and continue " +"recovery. This behavior may cause crashes, data loss, propagate or hide " +"corruption, or other serious problems. Only has an effect during recovery or " +"in standby mode." +msgstr "" +"PostgreSQL은 WAL 기반 복구 작업에서 해당 페이지가 잘못되어 있으면, " +"PANIC 오류를 내고 복구 작업을 중지하고 멈춥니다. ignore_invalid_pages 값을 " +" true로 지정하면, 이런 손상된 페이지가 있을 때, 경고 메시지를 보여주고, " +"복구 작업 계속 진행합니다. 이 기능을 사용하면 서버 비정상 종료나 자료 손실 " +"숨은 손상, 기타 심각한 문제가 일어 날 수 있습니다. 이 설정은 복구 작업 때나 " +"대기 모드 상태에서만 작동합니다." + +#: utils/misc/guc.c:1244 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "체크포인트 후 처음 수정할 때 전체 페이지를 WAL에 씁니다." + +#: utils/misc/guc.c:1245 +msgid "" +"A page write in process during an operating system crash might be only " +"partially written to disk. During recovery, the row changes stored in WAL " +"are not enough to recover. This option writes pages when first modified " +"after a checkpoint to WAL so full recovery is possible." +msgstr "" +"운영 체제가 비정상 종료되는 경우 처리 중인 페이지 쓰기는 디스크에 일부만 기록" +"될 수도 있습니다. 복구 중 WAL에 저장된 로우 변경 내용이 부족하여 복구할 수 " +"없을 수도 있습니다. 이 옵션은 안전하게 복구가 가능하도록 체크포인트 후 처음 " +"수정한 페이지는 그 페이지 전체를 WAL에 씁니다." + +#: utils/misc/guc.c:1258 +msgid "" +"Writes full pages to WAL when first modified after a checkpoint, even for a " +"non-critical modifications." +msgstr "" +"체크포인트 작업 후 자료 페이지에 첫 변경이 있는 경우, WAL에 변경된 내용만 기" +"록하는 것이 아니라, 해당 페이지 전체를 기록합니다." + +#: utils/misc/guc.c:1268 +msgid "Compresses full-page writes written in WAL file." +msgstr "WAL 파일에 기록되는 전체 페이지를 압축함" + +#: utils/misc/guc.c:1278 +msgid "Writes zeroes to new WAL files before first use." +msgstr "" + +#: utils/misc/guc.c:1288 +msgid "Recycles WAL files by renaming them." +msgstr "" + +#: utils/misc/guc.c:1298 +msgid "Logs each checkpoint." +msgstr "체크포인트 관련 정보를 기록합니다." + +#: utils/misc/guc.c:1307 +msgid "Logs each successful connection." +msgstr "연결 성공한 정보들 모두를 기록함" + +#: utils/misc/guc.c:1316 +msgid "Logs end of a session, including duration." +msgstr "기간을 포함하여 세션의 끝을 기록합니다." + +#: utils/misc/guc.c:1325 +msgid "Logs each replication command." +msgstr "복제 관련 작업 내역을 기록합니다." + +#: utils/misc/guc.c:1334 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "서버가 assertion 검사 기능이 활성화 되어 실행되는지 보여 줌" + +#: utils/misc/guc.c:1349 +msgid "Terminate session on any error." +msgstr "어떤 오류가 생기면 세션을 종료함" + +#: utils/misc/guc.c:1358 +msgid "Reinitialize server after backend crash." +msgstr "백엔드가 비정상 종료되면 서버를 재초기화함" + +#: utils/misc/guc.c:1368 +msgid "Logs the duration of each completed SQL statement." +msgstr "SQL 명령 구문의 실행완료 시간을 기록함" + +#: utils/misc/guc.c:1377 +msgid "Logs each query's parse tree." +msgstr "각 쿼리의 구문 분석 트리를 기록합니다." + +#: utils/misc/guc.c:1386 +msgid "Logs each query's rewritten parse tree." +msgstr "각 쿼리의 재작성된 구문 분석 트리를 기록합니다." + +#: utils/misc/guc.c:1395 +msgid "Logs each query's execution plan." +msgstr "각 쿼리의 실행 계획을 기록합니다." + +#: utils/misc/guc.c:1404 +msgid "Indents parse and plan tree displays." +msgstr "구문과 실행계획을 보여 줄때, 들여쓰기를 함." + +#: utils/misc/guc.c:1413 +msgid "Writes parser performance statistics to the server log." +msgstr "구문분석 성능 통계를 서버 로그에 기록함." + +#: utils/misc/guc.c:1422 +msgid "Writes planner performance statistics to the server log." +msgstr "실행계획자 성능 통계를 서버 로그에 기록함." + +#: utils/misc/guc.c:1431 +msgid "Writes executor performance statistics to the server log." +msgstr "실행자 성능 통계를 서버 로그에 기록함." + +#: utils/misc/guc.c:1440 +msgid "Writes cumulative performance statistics to the server log." +msgstr "누적 성능 통계를 서버 로그에 기록함." + +#: utils/misc/guc.c:1450 +msgid "" +"Logs system resource usage statistics (memory and CPU) on various B-tree " +"operations." +msgstr "다양한 B트리 작업에 자원(메모리, CPU) 사용 통계를 기록에 남기" + +#: utils/misc/guc.c:1462 +msgid "Collects information about executing commands." +msgstr "명령 실행에 대한 정보를 수집함" + +#: utils/misc/guc.c:1463 +msgid "" +"Enables the collection of information on the currently executing command of " +"each session, along with the time at which that command began execution." +msgstr "" +"각 세션에서 사용하고 있는 현재 실행 중인 명령의 수행 시간, 명령 내용등에 대" +"한 정보를 수집하도록 함" + +#: utils/misc/guc.c:1473 +msgid "Collects statistics on database activity." +msgstr "데이터베이스 활동에 대한 통계를 수집합니다." + +#: utils/misc/guc.c:1482 +msgid "Collects timing statistics for database I/O activity." +msgstr "데이터베이스 I/O 활동에 대한 통계를 수집합니다." + +#: utils/misc/guc.c:1492 +msgid "Updates the process title to show the active SQL command." +msgstr "활성 SQL 명령을 표시하도록 프로세스 제목을 업데이트합니다." + +#: utils/misc/guc.c:1493 +msgid "" +"Enables updating of the process title every time a new SQL command is " +"received by the server." +msgstr "" +"서버가 새 SQL 명령을 받을 때마다 프로세스 제목이 업데이트될 수 있도록 합니다." + +#: utils/misc/guc.c:1506 +msgid "Starts the autovacuum subprocess." +msgstr "자동 청소 하위 프로세스를 실행함" + +#: utils/misc/guc.c:1516 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "LISTEN, NOTIFY 명령 사용을 위한 디버깅 출력을 만듦." + +#: utils/misc/guc.c:1528 +msgid "Emits information about lock usage." +msgstr "잠금 사용 정보를 로그로 남김" + +#: utils/misc/guc.c:1538 +msgid "Emits information about user lock usage." +msgstr "사용자 잠금 사용 정보를 로그로 남김" + +#: utils/misc/guc.c:1548 +msgid "Emits information about lightweight lock usage." +msgstr "가벼운 잠금 사용 정보를 로그로 남김" + +#: utils/misc/guc.c:1558 +msgid "" +"Dumps information about all current locks when a deadlock timeout occurs." +msgstr "교착 잠금 시간 제한 상황이 발생하면 그 때의 모든 잠금 정보를 보여줌" + +#: utils/misc/guc.c:1570 +msgid "Logs long lock waits." +msgstr "긴 잠금 대기를 기록합니다." + +#: utils/misc/guc.c:1580 +msgid "Logs the host name in the connection logs." +msgstr "연결 기록에서 호스트 이름을 기록함." + +#: utils/misc/guc.c:1581 +msgid "" +"By default, connection logs only show the IP address of the connecting host. " +"If you want them to show the host name you can turn this on, but depending " +"on your host name resolution setup it might impose a non-negligible " +"performance penalty." +msgstr "" +"이 기능은 기본적으로 연결기록에서 기본적으로 IP 주소만 기록합니다. 이 값을 " +"true로 바꾼다면, 이 IP의 호스트 이름을 구해서 이 이름을 사용합니다 이것의 성" +"능은 OS의 IP에서 이름구하기 성능과 관계됩니다." + +#: utils/misc/guc.c:1592 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "\"표현=NULL\" 식을 \"표현 IS NULL\"로 취급함." + +#: utils/misc/guc.c:1593 +msgid "" +"When turned on, expressions of the form expr = NULL (or NULL = expr) are " +"treated as expr IS NULL, that is, they return true if expr evaluates to the " +"null value, and false otherwise. The correct behavior of expr = NULL is to " +"always return null (unknown)." +msgstr "" +"표현 = NULL 의 바른 처리는 항상 null 값을 리턴해야하지만, 편의성을 위해서 " +"expr = NULL 구문을 expr IS NULL 구문으로 바꾸어서 처리하도록 함이렇게하면, " +"윗 구문은 true 를 리턴함" + +#: utils/misc/guc.c:1605 +msgid "Enables per-database user names." +msgstr "per-database 사용자 이름 활성화." + +#: utils/misc/guc.c:1614 +msgid "Sets the default read-only status of new transactions." +msgstr "새로운 트랜잭션의 상태를 초기값으로 읽기전용으로 설정합니다." + +#: utils/misc/guc.c:1623 +msgid "Sets the current transaction's read-only status." +msgstr "현재 트랜잭셕의 읽기 전용 상태를 지정합니다." + +#: utils/misc/guc.c:1633 +msgid "Sets the default deferrable status of new transactions." +msgstr "새 트랜잭션의 기본 지연 가능한 상태를 지정" + +#: utils/misc/guc.c:1642 +msgid "" +"Whether to defer a read-only serializable transaction until it can be " +"executed with no possible serialization failures." +msgstr "" +"읽기 전용 직렬화 가능한 트랜잭션이 직렬 처리에서 오류가 없을 때까지 그 트랜잭" +"션을 지연할 것이지 결정함" + +#: utils/misc/guc.c:1652 +msgid "Enable row security." +msgstr "로우 단위 보안 기능을 활성화" + +#: utils/misc/guc.c:1653 +msgid "When enabled, row security will be applied to all users." +msgstr "이 값이 활성화 되면 로우 단위 보안 기능이 모든 사용자 대상으로 적용됨" + +#: utils/misc/guc.c:1661 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "" +"CREATE FUNCTION 명령으로 함수를 만들 때, 함수 본문 부분의 구문을 검사합니다." + +#: utils/misc/guc.c:1670 +msgid "Enable input of NULL elements in arrays." +msgstr "배열에 NULL 요소가 입력될 수 있도록 합니다." + +#: utils/misc/guc.c:1671 +msgid "" +"When turned on, unquoted NULL in an array input value means a null value; " +"otherwise it is taken literally." +msgstr "" +"이 값이 on이면 배열 입력 값에 따옴표 없이 입력된 NULL이 null 값을 의미하고, " +"그렇지 않으면 문자 그대로 처리됩니다." + +#: utils/misc/guc.c:1687 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "" + +#: utils/misc/guc.c:1697 +msgid "" +"Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "" +"로그 기록 하위 프로세스를 시작하여 stderr 출력 및/또는 csvlog를 로그 파일에 " +"씁니다." + +#: utils/misc/guc.c:1706 +msgid "Truncate existing log files of same name during log rotation." +msgstr "로그 회전 중 동일한 이름의 기존 로그 파일을 자릅니다." + +#: utils/misc/guc.c:1717 +msgid "Emit information about resource usage in sorting." +msgstr "정렬 시 리소스 사용 정보를 내보냅니다." + +#: utils/misc/guc.c:1731 +msgid "Generate debugging output for synchronized scanning." +msgstr "동기화된 스캔을 위해 디버깅 출력을 생성합니다." + +#: utils/misc/guc.c:1746 +msgid "Enable bounded sorting using heap sort." +msgstr "힙 정렬을 통해 제한적 정렬을 사용합니다." + +#: utils/misc/guc.c:1759 +msgid "Emit WAL-related debugging output." +msgstr "WAL 관련 디버깅 출력을 내보냅니다." + +#: utils/misc/guc.c:1771 +msgid "Datetimes are integer based." +msgstr "datetime 형을 정수형으로 사용함" + +#: utils/misc/guc.c:1782 +msgid "" +"Sets whether Kerberos and GSSAPI user names should be treated as case-" +"insensitive." +msgstr "" +"Kerberos 및 GSSAPI 사용자 이름에서 대/소문자를 구분하지 않을지 여부를 설정합" +"니다." + +#: utils/misc/guc.c:1792 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "일반 문자열 리터럴의 백슬래시 이스케이프에 대해 경고합니다." + +#: utils/misc/guc.c:1802 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "'...' 문자열에서 백슬래시가 리터럴로 처리되도록 합니다." + +#: utils/misc/guc.c:1813 +msgid "Enable synchronized sequential scans." +msgstr "동기화된 순차적 스캔을 사용합니다." + +#: utils/misc/guc.c:1823 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "복구 대상에서 트랜잭션을 포함할지 제외할지 선택합니다." + +#: utils/misc/guc.c:1833 +msgid "Allows connections and queries during recovery." +msgstr "복구 중에서도 접속과 쿼리 사용을 허용함" + +#: utils/misc/guc.c:1843 +msgid "" +"Allows feedback from a hot standby to the primary that will avoid query " +"conflicts." +msgstr "" +"읽기 전용 보조 서버가 보내는 쿼리 충돌을 피하기 위한 피드백을 주 서버가 받음" + +#: utils/misc/guc.c:1853 +msgid "Allows modifications of the structure of system tables." +msgstr "시스템 테이블의 구조를 수정할 수 있도록 합니다." + +#: utils/misc/guc.c:1864 +msgid "Disables reading from system indexes." +msgstr "시스템 인덱스 읽기를 금지함" + +#: utils/misc/guc.c:1865 +msgid "" +"It does not prevent updating the indexes, so it is safe to use. The worst " +"consequence is slowness." +msgstr "" +"이 설정이 활성화 되어도 그 인덱스는 갱신되어 사용하는데는 안전합니다. 하지" +"만 서버가 전체적으로 늦어질 수 있습니다." + +#: utils/misc/guc.c:1876 +msgid "" +"Enables backward compatibility mode for privilege checks on large objects." +msgstr "대형 개체에 대한 접근 권한 검사를 위한 하위 호환성이 있게 함" + +#: utils/misc/guc.c:1877 +msgid "" +"Skips privilege checks when reading or modifying large objects, for " +"compatibility with PostgreSQL releases prior to 9.0." +msgstr "" +"PostgreSQL 9.0 이전 버전의 호환성을 위해 대형 개체에 대한 읽기, 변경 시 접근 " +"권한 검사를 안 하도록 설정함" + +#: utils/misc/guc.c:1887 +msgid "" +"Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "PostgreSQL 9.4 버전까지 사용되었던 우선 순위가 적용되면 경고를 보여줌" + +#: utils/misc/guc.c:1897 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "SQL 구문을 만들 때, 모든 식별자는 따옴표를 사용함" + +#: utils/misc/guc.c:1907 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "" + +#: utils/misc/guc.c:1918 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "syslog 사용시 메시지 중복을 방지하기 위해 일련 번호를 매깁니다." + +#: utils/misc/guc.c:1928 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "syslog 사용시 메시지를 한 줄에 1024 바이트만 쓰도록 나눕니다" + +#: utils/misc/guc.c:1938 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "" + +#: utils/misc/guc.c:1939 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "" + +#: utils/misc/guc.c:1949 +msgid "Allow JIT compilation." +msgstr "" + +#: utils/misc/guc.c:1960 +msgid "Register JIT compiled function with debugger." +msgstr "" + +#: utils/misc/guc.c:1977 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "" + +#: utils/misc/guc.c:1988 +msgid "Allow JIT compilation of expressions." +msgstr "" + +#: utils/misc/guc.c:1999 +msgid "Register JIT compiled function with perf profiler." +msgstr "" + +#: utils/misc/guc.c:2016 +msgid "Allow JIT compilation of tuple deforming." +msgstr "" + +#: utils/misc/guc.c:2027 +msgid "Whether to continue running after a failure to sync data files." +msgstr "" + +#: utils/misc/guc.c:2036 +msgid "" +"Sets whether a WAL receiver should create a temporary replication slot if no " +"permanent slot is configured." +msgstr "" + +#: utils/misc/guc.c:2054 +msgid "" +"Forces a switch to the next WAL file if a new file has not been started " +"within N seconds." +msgstr "" +"새 파일이 N초 내에 시작되지 않은 경우 강제로 다음 WAL 파일로 전환합니다." + +#: utils/misc/guc.c:2065 +msgid "Waits N seconds on connection startup after authentication." +msgstr "연결 작업에서 인증이 끝난 뒤 N초 기다림" + +#: utils/misc/guc.c:2066 utils/misc/guc.c:2624 +msgid "This allows attaching a debugger to the process." +msgstr "이렇게 하면 디버거를 프로세스에 연결할 수 있습니다." + +#: utils/misc/guc.c:2075 +msgid "Sets the default statistics target." +msgstr "기본 통계 대상을 지정합니다." + +#: utils/misc/guc.c:2076 +msgid "" +"This applies to table columns that have not had a column-specific target set " +"via ALTER TABLE SET STATISTICS." +msgstr "" +"특정 칼럼을 지정하지 않고 ALTER TABLE SET STATISTICS 명령을 사용했을 때, 통" +"계 대상이 될 칼럼을 지정합니다." + +#: utils/misc/guc.c:2085 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "" +"이 크기를 초과할 경우 하위 쿼리가 축소되지 않는 FROM 목록 크기를 설정합니다." + +#: utils/misc/guc.c:2087 +msgid "" +"The planner will merge subqueries into upper queries if the resulting FROM " +"list would have no more than this many items." +msgstr "" +"결과 FROM 목록에 포함된 항목이 이 개수를 넘지 않는 경우 계획 관리자가 하" +"위 쿼리를 상위 쿼리에 병합합니다." + +#: utils/misc/guc.c:2098 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "" +"이 크기를 초과할 경우 JOIN 구문이 결합되지 않는 FROM 목록 크기를 설정합니다." + +#: utils/misc/guc.c:2100 +msgid "" +"The planner will flatten explicit JOIN constructs into lists of FROM items " +"whenever a list of no more than this many items would result." +msgstr "" +"결과 목록에 포함된 항목이 이 개수를 넘지 않을 때마다 계획 관리자가 명시" +"적 JOIN 구문을 FROM 항목 목록에 결합합니다." + +#: utils/misc/guc.c:2111 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "" +"이 임계값을 초과할 경우 GEQO가 사용되는 FROM 항목의 임계값을 설정합니다." + +#: utils/misc/guc.c:2121 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: 다른 GEQO 매개 변수의 기본 값을 설정하는 데 사용됩니다." + +#: utils/misc/guc.c:2131 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: 모집단의 개인 수입니다." + +#: utils/misc/guc.c:2132 utils/misc/guc.c:2142 +msgid "Zero selects a suitable default value." +msgstr "0을 지정하면 적절한 기본 값이 선택됩니다." + +#: utils/misc/guc.c:2141 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: 알고리즘의 반복 수입니다." + +#: utils/misc/guc.c:2153 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "교착 상태를 확인하기 전에 잠금을 기다릴 시간을 설정합니다." + +#: utils/misc/guc.c:2164 +msgid "" +"Sets the maximum delay before canceling queries when a hot standby server is " +"processing archived WAL data." +msgstr "" +"읽기 전용 보조 서버가 아카이브된 WAL 자료를 처리할 때, 지연될 수 있는 최대 시" +"간" + +#: utils/misc/guc.c:2175 +msgid "" +"Sets the maximum delay before canceling queries when a hot standby server is " +"processing streamed WAL data." +msgstr "" +"읽기 전용 보조 서버가 스트림 WAL 자료를 처리할 때, 지연될 수 있는 최대 시간" + +#: utils/misc/guc.c:2186 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "" + +#: utils/misc/guc.c:2197 +msgid "" +"Sets the maximum interval between WAL receiver status reports to the sending " +"server." +msgstr "WAL 정보를 보내는 서버에게 WAL 수신기 상태를 보고하는 최대 간격" + +#: utils/misc/guc.c:2208 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "" +"WAL 정보를 보내는 서버로부터 보낸 자료를 받기위해 기다릴 수 있는 최대 허용 시" +"간을 설정합니다." + +#: utils/misc/guc.c:2219 +msgid "Sets the maximum number of concurrent connections." +msgstr "최대 동시 접속수를 지정합니다." + +#: utils/misc/guc.c:2230 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "superuser 동시 접속수를 지정합니다." + +#: utils/misc/guc.c:2244 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "서버에서 사용할 공유 메모리의 개수를 지정함" + +#: utils/misc/guc.c:2255 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "각 세션에서 사용하는 임시 버퍼의 최대 개수를 지정" + +#: utils/misc/guc.c:2266 +msgid "Sets the TCP port the server listens on." +msgstr "TCP 포트 번호를 지정함." + +#: utils/misc/guc.c:2276 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "유닉스 도메인 소켓 파일의 액세스 권한을 지정함" + +#: utils/misc/guc.c:2277 +msgid "" +"Unix-domain sockets use the usual Unix file system permission set. The " +"parameter value is expected to be a numeric mode specification in the form " +"accepted by the chmod and umask system calls. (To use the customary octal " +"format the number must start with a 0 (zero).)" +msgstr "" +"Unix 도메인 소켓은 일반적인 Unix 파일 시스템 권한 집합을 사용합니다. 매개 변" +"수 값은 chmod 및 umask 시스템 호출에서 수락되는 형태의 숫자 모드 지정이어야 " +"합니다. (일반적인 8진수 형식을 사용하려면 숫자가 0으로 시작해야 합니다.)" + +#: utils/misc/guc.c:2291 +msgid "Sets the file permissions for log files." +msgstr "로그 파일의 파일 접근 권한을 지정합니다." + +#: utils/misc/guc.c:2292 +msgid "" +"The parameter value is expected to be a numeric mode specification in the " +"form accepted by the chmod and umask system calls. (To use the customary " +"octal format the number must start with a 0 (zero).)" +msgstr "" +"매개 변수 값은 chmod 및 umask 시스템 호출에서 수락되는 형태의 숫자 모드 지정" +"이어야 합니다. (일반적인 8진수 형식을 사용하려면 숫자가 0으로 시작해야 합니" +"다.)" + +#: utils/misc/guc.c:2306 +msgid "Mode of the data directory." +msgstr "데이터 디렉터리의 모드" + +#: utils/misc/guc.c:2307 +msgid "" +"The parameter value is a numeric mode specification in the form accepted by " +"the chmod and umask system calls. (To use the customary octal format the " +"number must start with a 0 (zero).)" +msgstr "" +"매개 변수 값은 chmod 및 umask 시스템 호출에서 수락되는 형태의 숫자 모드 지정" +"이어야 합니다. (일반적인 8진수 형식을 사용하려면 숫자가 0으로 시작해야 합니" +"다.)" + +#: utils/misc/guc.c:2320 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "쿼리 작업공간을 위해 사용될 메모리의 최대값을 지정함." + +#: utils/misc/guc.c:2321 +msgid "" +"This much memory can be used by each internal sort operation and hash table " +"before switching to temporary disk files." +msgstr "" +"임시 디스크 파일로 전환하기 전에 각 내부 정렬 작업과 해시 테이블에서 이 크기" +"의 메모리를 사용할 수 있습니다." + +#: utils/misc/guc.c:2333 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "관리 작업을 위해 사용될 메모리의 최대값을 지정함." + +#: utils/misc/guc.c:2334 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "관리작업은 VACUUM, CREATE INDEX 같은 작업을 뜻합니다." + +#: utils/misc/guc.c:2344 +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "논리 디코딩 작업을 위해 사용될 메모리의 최대값을 지정함." + +#: utils/misc/guc.c:2345 +msgid "" +"This much memory can be used by each internal reorder buffer before spilling " +"to disk." +msgstr "" +"이 메모리는 디스크 기록 전에 각 내부 재정렬 버퍼로 사용될 수 있습니다." + +#: utils/misc/guc.c:2361 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "스택깊이(KB 단위) 최대값을 지정합니다." + +#: utils/misc/guc.c:2372 +msgid "Limits the total size of all temporary files used by each process." +msgstr "각 프로세스에서 사용하는 모든 임시 파일의 총 크기 제한" + +#: utils/misc/guc.c:2373 +msgid "-1 means no limit." +msgstr "-1은 제한 없음" + +#: utils/misc/guc.c:2383 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "버퍼 캐시에 있는 페이지의 청소 비용입니다." + +#: utils/misc/guc.c:2393 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "버퍼 캐시에 없는 페이지의 청소 비용입니다." + +#: utils/misc/guc.c:2403 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "청소로 페이지 변경 시 부과되는 비용입니다." + +#: utils/misc/guc.c:2413 +msgid "Vacuum cost amount available before napping." +msgstr "청소가 중지되는 청소 비용 합계입니다." + +#: utils/misc/guc.c:2423 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "자동 청소에 대한 청소가 중지되는 청소 비용 합계입니다." + +#: utils/misc/guc.c:2433 +msgid "" +"Sets the maximum number of simultaneously open files for each server process." +msgstr "각각의 서버 프로세스에서 동시에 열릴 수 있는 최대 파일 갯수를 지정함." + +#: utils/misc/guc.c:2446 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "동시에 준비된 트랜잭션 최대 개수 지정" + +#: utils/misc/guc.c:2457 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "잠금 추적을 위한 테이블의 최소 OID 지정" + +#: utils/misc/guc.c:2458 +msgid "Is used to avoid output on system tables." +msgstr "" + +#: utils/misc/guc.c:2467 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "" + +#: utils/misc/guc.c:2479 +msgid "Sets the maximum allowed duration of any statement." +msgstr "모든 쿼리문에 적용되는 허용되는 최대 수행시간" + +#: utils/misc/guc.c:2480 utils/misc/guc.c:2491 utils/misc/guc.c:2502 +msgid "A value of 0 turns off the timeout." +msgstr "이 값이 0이면 이런 제한이 없음." + +#: utils/misc/guc.c:2490 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "모든 잠금에 적용되는 기다리는 최대 대기 시간" + +#: utils/misc/guc.c:2501 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "idle-in-transaction 상태로 있을 수 있는 최대 시간" + +#: utils/misc/guc.c:2512 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "VACUUM에서 테이블 행을 동결할 때까지의 최소 기간입니다." + +#: utils/misc/guc.c:2522 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "" +"VACUUM에서 튜플을 동결하기 위해 전체 테이블을 스캔할 때까지의 기간입니다." + +#: utils/misc/guc.c:2532 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "VACUUM에서 테이블 MultiXactId 동결할 때까지의 최소 기간입니다." + +#: utils/misc/guc.c:2542 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "" +"VACUUM에서 튜플을 동결하기 위해 전체 테이블을 스캔할 때까지의 멀티트랜잭션 기" +"간입니다." + +#: utils/misc/guc.c:2552 +msgid "" +"Number of transactions by which VACUUM and HOT cleanup should be deferred, " +"if any." +msgstr "" + +#: utils/misc/guc.c:2565 +msgid "Sets the maximum number of locks per transaction." +msgstr "하나의 트랜잭션에서 사용할 수 있는 최대 잠금 횟수를 지정함." + +#: utils/misc/guc.c:2566 +msgid "" +"The shared lock table is sized on the assumption that at most " +"max_locks_per_transaction * max_connections distinct objects will need to be " +"locked at any one time." +msgstr "" +"공유 잠금 테이블은 한 번에 잠궈야 할 고유 개체 수가 " +"max_locks_per_transaction * max_connections를 넘지 않는다는 가정 하에 크기가 " +"지정됩니다." + +#: utils/misc/guc.c:2577 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "하나의 트랜잭션에서 사용할 수 있는 최대 잠금 횟수를 지정함." + +#: utils/misc/guc.c:2578 +msgid "" +"The shared predicate lock table is sized on the assumption that at most " +"max_pred_locks_per_transaction * max_connections distinct objects will need " +"to be locked at any one time." +msgstr "" +"공유 predicate 잠금 테이블은 한 번에 잠궈야 할 고유 개체 수가 " +"max_pred_locks_per_transaction * max_connections를 넘지 않는다는 가정 하에 크" +"기가 지정됩니다." + +#: utils/misc/guc.c:2589 +msgid "" +"Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "하나의 트랜잭션에서 사용할 수 있는 페이지와 튜플의 최대수 지정함." + +#: utils/misc/guc.c:2590 +msgid "" +"If more than this total of pages and tuples in the same relation are locked " +"by a connection, those locks are replaced by a relation-level lock." +msgstr "" + +#: utils/misc/guc.c:2600 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "페이지당 잠금 튜플 최대 수 지정." + +#: utils/misc/guc.c:2601 +msgid "" +"If more than this number of tuples on the same page are locked by a " +"connection, those locks are replaced by a page-level lock." +msgstr "" + +#: utils/misc/guc.c:2611 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "클라이언트 인증을 완료할 수 있는 최대 허용 시간을 설정합니다." + +#: utils/misc/guc.c:2623 +msgid "Waits N seconds on connection startup before authentication." +msgstr "인증 전에 연결이 시작되도록 N초 동안 기다립니다." + +#: utils/misc/guc.c:2634 +msgid "Sets the size of WAL files held for standby servers." +msgstr "대기 서버를 위해 보관하고 있을 WAL 파일 크기를 지정" + +#: utils/misc/guc.c:2645 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "WAL 최소 크기" + +#: utils/misc/guc.c:2657 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "체크포인트 작업을 할 WAL 크기 지정" + +#: utils/misc/guc.c:2669 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "자동 WAL 체크포인트 사이의 최대 간격을 설정합니다." + +#: utils/misc/guc.c:2680 +msgid "" +"Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "지정 시간 안에 체크포인트 조각이 모두 채워지면 경고를 냄" + +#: utils/misc/guc.c:2682 +msgid "" +"Write a message to the server log if checkpoints caused by the filling of " +"checkpoint segment files happens more frequently than this number of " +"seconds. Zero turns off the warning." +msgstr "" +"체크포인트 작업이 지금 지정한 시간(초)보다 자주 체크포인트 세그먼트 파일에 내" +"용이 꽉 차는 사태가 발생하면 경고 메시지를 서버 로그에 남깁니다. 이 값을 0으" +"로 지정하면 이 기능 없음" + +#: utils/misc/guc.c:2694 utils/misc/guc.c:2910 utils/misc/guc.c:2957 +msgid "" +"Number of pages after which previously performed writes are flushed to disk." +msgstr "" + +#: utils/misc/guc.c:2705 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "" +"WAL 기능을 위해 공유 메모리에서 사용할 디스크 페이지 버퍼 개수를 지정함." + +#: utils/misc/guc.c:2716 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "WAL 기록자가 지정 시간 만큼 쉬고 쓰기 작업을 반복함" + +#: utils/misc/guc.c:2727 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "" + +#: utils/misc/guc.c:2738 +msgid "Size of new file to fsync instead of writing WAL." +msgstr "" + +#: utils/misc/guc.c:2749 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "동시에 작동할 WAL 송신 프로세스 최대 수 지정" + +#: utils/misc/guc.c:2760 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "동시에 사용할 수 있는 복제 슬롯 최대 수 지정" + +#: utils/misc/guc.c:2770 +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "복제 슬롯을 위해 보관할 최대 WAL 크기 지정" + +#: utils/misc/guc.c:2771 +msgid "" +"Replication slots will be marked as failed, and segments released for " +"deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "" + +#: utils/misc/guc.c:2783 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "WAL 복제를 위해 기다릴 최대 시간 설정" + +#: utils/misc/guc.c:2794 +msgid "" +"Sets the delay in microseconds between transaction commit and flushing WAL " +"to disk." +msgstr "" +"트랜잭션과 트랜잭션 로그의 적용 사이의 간격을 microsecond 단위로 지정함" + +#: utils/misc/guc.c:2806 +msgid "" +"Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "commit_delay 처리하기 전에 있는 최소 동시 열려 있는 트랜잭션 개수." + +#: utils/misc/guc.c:2817 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "부동소수형 값을 표기할 때 " + +#: utils/misc/guc.c:2818 +msgid "" +"This affects real, double precision, and geometric data types. A zero or " +"negative parameter value is added to the standard number of digits (FLT_DIG " +"or DBL_DIG as appropriate). Any value greater than zero selects precise " +"output mode." +msgstr "" +"이 값은 real, duoble 부동 소숫점과 지리정보 자료형에 영향을 끼칩니다. 이 값" +"은 정수여야합니다(FLT_DIG or DBL_DIG as appropriate - 무슨 말인지). 음수면 " +"그 만큼 소숫점 자리를 더 많이 생략해서 정확도를 떨어뜨립니다." + +#: utils/misc/guc.c:2830 +msgid "" +"Sets the minimum execution time above which a sample of statements will be " +"logged. Sampling is determined by log_statement_sample_rate." +msgstr "" +"" + +#: utils/misc/guc.c:2833 +msgid "Zero logs a sample of all queries. -1 turns this feature off." +msgstr "" +"0을 지정하면 모든 쿼리를 로깅하고, -1을 지정하면 이 기능이 해제됩니다." + +#: utils/misc/guc.c:2843 +msgid "" +"Sets the minimum execution time above which all statements will be logged." +msgstr "" +"모든 실행 쿼리문을 로그로 남길 최소 실행 시간을 설정합니다." + +#: utils/misc/guc.c:2845 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "" +"0을 지정하면 모든 쿼리를 로깅하고, -1을 지정하면 이 기능이 해제됩니다." + +#: utils/misc/guc.c:2855 +msgid "" +"Sets the minimum execution time above which autovacuum actions will be " +"logged." +msgstr "" +"이 시간을 초과할 경우 자동 청소 작업 로그를 남길 최소 실행 시간을 설정합니" +"다." + +#: utils/misc/guc.c:2857 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "" +"0을 지정하면 모든 작업을 로깅하고, -1을 지정하면 자동 청소관련 로그를 남기지 않음" + +#: utils/misc/guc.c:2867 +msgid "" +"When logging statements, limit logged parameter values to first N bytes." +msgstr "" + +#: utils/misc/guc.c:2868 utils/misc/guc.c:2879 +msgid "-1 to print values in full." +msgstr "" + +#: utils/misc/guc.c:2878 +msgid "" +"When reporting an error, limit logged parameter values to first N bytes." +msgstr "" + +#: utils/misc/guc.c:2889 +msgid "Background writer sleep time between rounds." +msgstr "백그라운드 기록자의 잠자는 시간" + +#: utils/misc/guc.c:2900 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "라운드당 플러시할 백그라운드 작성기 최대 LRU 페이지 수입니다." + +#: utils/misc/guc.c:2923 +msgid "" +"Number of simultaneous requests that can be handled efficiently by the disk " +"subsystem." +msgstr "" +"디스크 하위 시스템에서 효율적으로 처리할 수 있는 동시 요청 수입니다." + +#: utils/misc/guc.c:2924 +msgid "" +"For RAID arrays, this should be approximately the number of drive spindles " +"in the array." +msgstr "RAID 배열의 경우 이 값은 대략 배열의 드라이브 스핀들 수입니다." + +#: utils/misc/guc.c:2941 +msgid "" +"A variant of effective_io_concurrency that is used for maintenance work." +msgstr "" + +#: utils/misc/guc.c:2970 +msgid "Maximum number of concurrent worker processes." +msgstr "동시 작업자 프로세스의 최대 수" + +#: utils/misc/guc.c:2982 +msgid "Maximum number of logical replication worker processes." +msgstr "논리 복제 작업자 프로세스의 최대 수" + +#: utils/misc/guc.c:2994 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "구독을 위한 테이블 동기화 작업자의 최대 수" + +#: utils/misc/guc.c:3004 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "N분 후에 자동 로그 파일 회전이 발생합니다." + +#: utils/misc/guc.c:3015 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "N킬로바이트 후에 자동 로그 파일 회전이 발생합니다." + +#: utils/misc/guc.c:3026 +msgid "Shows the maximum number of function arguments." +msgstr "함수 인자의 최대 갯수를 보여줍니다" + +#: utils/misc/guc.c:3037 +msgid "Shows the maximum number of index keys." +msgstr "인덱스 키의 최대개수를 보여줍니다." + +#: utils/misc/guc.c:3048 +msgid "Shows the maximum identifier length." +msgstr "최대 식별자 길이를 표시합니다." + +#: utils/misc/guc.c:3059 +msgid "Shows the size of a disk block." +msgstr "디스크 블록의 크기를 표시합니다." + +#: utils/misc/guc.c:3070 +msgid "Shows the number of pages per disk file." +msgstr "디스크 파일당 페이지 수를 표시합니다." + +#: utils/misc/guc.c:3081 +msgid "Shows the block size in the write ahead log." +msgstr "미리 쓰기 로그의 블록 크기를 표시합니다." + +#: utils/misc/guc.c:3092 +msgid "" +"Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "" + +#: utils/misc/guc.c:3104 +msgid "Shows the size of write ahead log segments." +msgstr "미리 쓰기 로그 세그먼트당 페이지 크기를 표시합니다." + +#: utils/misc/guc.c:3117 +msgid "Time to sleep between autovacuum runs." +msgstr "자동 청소 실행 사이의 절전 모드 시간입니다." + +#: utils/misc/guc.c:3127 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "청소 전의 최소 튜플 업데이트 또는 삭제 수입니다." + +#: utils/misc/guc.c:3136 +msgid "" +"Minimum number of tuple inserts prior to vacuum, or -1 to disable insert " +"vacuums." +msgstr "청소를 위한 최소 튜플 삽입 수입니다. -1은 insert는 vacuum에서 제외" + +#: utils/misc/guc.c:3145 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "통계 정보 수집을 위한 최소 튜플 삽입, 업데이트 또는 삭제 수입니다." + +#: utils/misc/guc.c:3155 +msgid "" +"Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "" +"트랜잭션 ID 겹침 방지를 위해 테이블에 대해 autovacuum 작업을 수행할 테이블 나" +"이를 지정합니다." + +#: utils/misc/guc.c:3166 +msgid "" +"Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "" +"멀티 트랜잭션 ID 겹침 방지를 위해 테이블에 대해 autovacuum 작업을 수행할 트랜" +"잭션 나이를 지정합니다." + +#: utils/misc/guc.c:3176 +msgid "" +"Sets the maximum number of simultaneously running autovacuum worker " +"processes." +msgstr "동시에 작업할 수 있는 autovacuum 작업자 최대 수 지정" + +#: utils/misc/guc.c:3186 +msgid "" +"Sets the maximum number of parallel processes per maintenance operation." +msgstr "유지보수 작업에서 사용할 병렬 프로세스 최대 수를 지정" + +#: utils/misc/guc.c:3196 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "실행 노드당 최대 병렬 처리 수 지정" + +#: utils/misc/guc.c:3207 +msgid "" +"Sets the maximum number of parallel workers that can be active at one time." +msgstr "한번에 작업할 수 있는 병렬 작업자 최대 수 지정" + +#: utils/misc/guc.c:3218 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "각 autovacuum 작업자 프로세스가 사용할 메모리 최대치" + +#: utils/misc/guc.c:3229 +msgid "" +"Time before a snapshot is too old to read pages changed after the snapshot " +"was taken." +msgstr "" + +#: utils/misc/guc.c:3230 +msgid "A value of -1 disables this feature." +msgstr "이 값이 -1 이면 이 기능 사용 안함" + +#: utils/misc/guc.c:3240 +msgid "Time between issuing TCP keepalives." +msgstr "TCP 연결 유지 실행 간격입니다." + +#: utils/misc/guc.c:3241 utils/misc/guc.c:3252 utils/misc/guc.c:3376 +msgid "A value of 0 uses the system default." +msgstr "이 값이 0이면 시스템 기본 값" + +#: utils/misc/guc.c:3251 +msgid "Time between TCP keepalive retransmits." +msgstr "TCP keepalive 시간 설정" + +#: utils/misc/guc.c:3262 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "" + +#: utils/misc/guc.c:3273 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "TCP keepalive 확인 최대 횟수" + +#: utils/misc/guc.c:3274 +msgid "" +"This controls the number of consecutive keepalive retransmits that can be " +"lost before a connection is considered dead. A value of 0 uses the system " +"default." +msgstr "" +"이 값은 연결이 중단된 것으로 간주되기 전에 손실될 수 있는 연속 연결 유" +"지 재전송 수를 제어합니다. 값 0을 지정하면 시스템 기본 값이 사용됩니다." + +#: utils/misc/guc.c:3285 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "정확한 GIN 기준 검색에 허용되는 최대 결과 수를 설정합니다." + +#: utils/misc/guc.c:3296 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "디스크 캐시 총 크기에 대한 계획 관리자의 가정을 설정합니다." + +#: utils/misc/guc.c:3297 +msgid "" +"That is, the total size of the caches (kernel cache and shared buffers) used " +"for PostgreSQL data files. This is measured in disk pages, which are " +"normally 8 kB each." +msgstr "" +"즉, PostgreSQL에서 사용하는 총 캐시 크기입니다(커널 캐시와 공유 버퍼 모두 포" +"함). 이 값은 디스크 페이지 단위로 측정되며, 일반적으로 각각 8kB입니다." + +#: utils/misc/guc.c:3308 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "병렬 조회를 위한 최소 테이블 자료량 지정" + +#: utils/misc/guc.c:3309 +msgid "" +"If the planner estimates that it will read a number of table pages too small " +"to reach this limit, a parallel scan will not be considered." +msgstr "" + +#: utils/misc/guc.c:3319 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "병렬 조회를 위한 최소 인덱스 자료량 지정" + +#: utils/misc/guc.c:3320 +msgid "" +"If the planner estimates that it will read a number of index pages too small " +"to reach this limit, a parallel scan will not be considered." +msgstr "" + +#: utils/misc/guc.c:3331 +msgid "Shows the server version as an integer." +msgstr "서버 버전을 정수형으로 보여줍니다" + +#: utils/misc/guc.c:3342 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "이 킬로바이트 수보다 큰 임시 파일의 사용을 기록합니다." + +#: utils/misc/guc.c:3343 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "" +"0을 지정하면 모든 파일이 기록됩니다. 기본 값은 -1로, 이 기능이 해제됩니다." + +#: utils/misc/guc.c:3353 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "pg_stat_activity.query에 예약되는 크기(바이트)를 설정합니다." + +#: utils/misc/guc.c:3364 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "GIN 인덱스를 위한 팬딩(pending) 목록의 최대 크기 지정" + +#: utils/misc/guc.c:3375 +msgid "TCP user timeout." +msgstr "" + +#: utils/misc/guc.c:3395 +msgid "" +"Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "" +"순차적으로 접근하는 디스크 페이지에 대한 계획 관리자의 예상 비용을 설정합니" +"다." + +#: utils/misc/guc.c:3406 +msgid "" +"Sets the planner's estimate of the cost of a nonsequentially fetched disk " +"page." +msgstr "" +"비순차적으로 접근하는 디스크 페이지에 대한 계획 관리자의 예상 비용을 설정합니" +"다." + +#: utils/misc/guc.c:3417 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "각 튜플(행)에 대한 계획 관리자의 예상 처리 비용을 설정합니다." + +#: utils/misc/guc.c:3428 +msgid "" +"Sets the planner's estimate of the cost of processing each index entry " +"during an index scan." +msgstr "" +"실행 계획기의 비용 계산에 사용될 인덱스 스캔으로 각 인덱스 항목을 처리하는 예" +"상 처리 비용을 설정합니다." + +#: utils/misc/guc.c:3439 +msgid "" +"Sets the planner's estimate of the cost of processing each operator or " +"function call." +msgstr "" +"실행 계획기의 비용 계산에 사용될 함수 호출이나 연산자 연산 처리하는 예상 처" +"리 비용을 설정합니다." + +#: utils/misc/guc.c:3450 +msgid "" +"Sets the planner's estimate of the cost of passing each tuple (row) from " +"worker to master backend." +msgstr "각 튜플(행)에 대한 계획 관리자의 예상 처리 비용을 설정합니다." + +#: utils/misc/guc.c:3461 +msgid "" +"Sets the planner's estimate of the cost of starting up worker processes for " +"parallel query." +msgstr "" + +#: utils/misc/guc.c:3473 +msgid "Perform JIT compilation if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3474 +msgid "-1 disables JIT compilation." +msgstr "" + +#: utils/misc/guc.c:3484 +msgid "Optimize JITed functions if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3485 +msgid "-1 disables optimization." +msgstr "-1 최적화 비활성화" + +#: utils/misc/guc.c:3495 +msgid "Perform JIT inlining if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3496 +msgid "-1 disables inlining." +msgstr "" + +#: utils/misc/guc.c:3506 +msgid "" +"Sets the planner's estimate of the fraction of a cursor's rows that will be " +"retrieved." +msgstr "검색될 커서 행에 대한 계획 관리자의 예상 분수 값을 설정합니다." + +#: utils/misc/guc.c:3518 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: 모집단 내의 선택 압력입니다." + +#: utils/misc/guc.c:3529 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: 무작위 경로 선택을 위한 씨드" + +#: utils/misc/guc.c:3540 +msgid "Multiple of work_mem to use for hash tables." +msgstr "" + +#: utils/misc/guc.c:3551 +msgid "Multiple of the average buffer usage to free per round." +msgstr "라운드당 해제할 평균 버퍼 사용의 배수입니다." + +#: utils/misc/guc.c:3561 +msgid "Sets the seed for random-number generation." +msgstr "난수 생성 속도를 설정합니다." + +#: utils/misc/guc.c:3572 +msgid "Vacuum cost delay in milliseconds." +msgstr "청소 비용 지연(밀리초)입니다." + +#: utils/misc/guc.c:3583 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "자동 청소에 대한 청소 비용 지연(밀리초)입니다." + +#: utils/misc/guc.c:3594 +msgid "" +"Number of tuple updates or deletes prior to vacuum as a fraction of " +"reltuples." +msgstr "" +"vacuum 작업을 진행할 update, delete 작업량을 전체 자료에 대한 분수값으로 지정" +"합니다." + +#: utils/misc/guc.c:3604 +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "" + +#: utils/misc/guc.c:3614 +msgid "" +"Number of tuple inserts, updates, or deletes prior to analyze as a fraction " +"of reltuples." +msgstr "" +"통계 수집 작업을 진행할 insert, update, delete 작업량을 전체 자료에 대한 분수" +"값으로 지정합니다." + +#: utils/misc/guc.c:3624 +msgid "" +"Time spent flushing dirty buffers during checkpoint, as fraction of " +"checkpoint interval." +msgstr "" +"체크포인트 반복 주기 안에 작업을 완료할 분수값(1=100%)" + +#: utils/misc/guc.c:3634 +msgid "" +"Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "" + +#: utils/misc/guc.c:3644 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "" + +#: utils/misc/guc.c:3645 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "" + +#: utils/misc/guc.c:3654 +msgid "Set the fraction of transactions to log for new transactions." +msgstr "새 트랜잭션에 대해서 로그에 남길 트랜잭션 비율을 설정합니다." + +#: utils/misc/guc.c:3655 +msgid "" +"Logs all statements from a fraction of transactions. Use a value between 0.0 " +"(never log) and 1.0 (log all statements for all transactions)." +msgstr "" + +#: utils/misc/guc.c:3675 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "WAL 파일을 아카이빙하기 위해 호출될 셸 명령을 설정합니다." + +#: utils/misc/guc.c:3685 +msgid "" +"Sets the shell command that will be called to retrieve an archived WAL file." +msgstr "아카이브된 WAL 파일을 재 반영할 쉘 명령어를 설정합니다." + +#: utils/misc/guc.c:3695 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "매 복구 작업이 끝난 다음 실행할 쉘 명령어를 설정합니다." + +#: utils/misc/guc.c:3705 +msgid "" +"Sets the shell command that will be executed once at the end of recovery." +msgstr "복구 작업 끝에 한 번 실행될 쉘 명령어를 설정합니다." + +#: utils/misc/guc.c:3715 +msgid "Specifies the timeline to recover into." +msgstr "복구할 타임라인을 지정합니다." + +#: utils/misc/guc.c:3725 +msgid "" +"Set to \"immediate\" to end recovery as soon as a consistent state is " +"reached." +msgstr "" + +#: utils/misc/guc.c:3734 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "" + +#: utils/misc/guc.c:3743 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "" + +#: utils/misc/guc.c:3752 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "" + +#: utils/misc/guc.c:3761 +msgid "" +"Sets the LSN of the write-ahead log location up to which recovery will " +"proceed." +msgstr "" + +#: utils/misc/guc.c:3771 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "" + +#: utils/misc/guc.c:3781 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "" + +#: utils/misc/guc.c:3792 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "복제 슬롯 이름을 지정합니다." + +#: utils/misc/guc.c:3802 +msgid "Sets the client's character set encoding." +msgstr "클라이언트 문자 세트 인코딩을 지정함" + +#: utils/misc/guc.c:3813 +msgid "Controls information prefixed to each log line." +msgstr "각 로그 줄 앞에 추가할 정보를 제어합니다." + +#: utils/misc/guc.c:3814 +msgid "If blank, no prefix is used." +msgstr "비워 두면 접두사가 사용되지 않습니다." + +#: utils/misc/guc.c:3823 +msgid "Sets the time zone to use in log messages." +msgstr "로그 메시지에 사용할 표준 시간대를 설정합니다." + +#: utils/misc/guc.c:3833 +msgid "Sets the display format for date and time values." +msgstr "날짜와 시간 값을 나타내는 모양을 지정합니다." + +#: utils/misc/guc.c:3834 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "또한 모호한 날짜 입력의 해석을 제어합니다." + +#: utils/misc/guc.c:3845 +msgid "Sets the default table access method for new tables." +msgstr "새 테이블에서 사용할 기본 테이블 접근 방법을 지정합니다." + +#: utils/misc/guc.c:3856 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "테이블 및 인덱스를 만들 기본 테이블스페이스를 설정합니다." + +#: utils/misc/guc.c:3857 +msgid "An empty string selects the database's default tablespace." +msgstr "빈 문자열을 지정하면 데이터베이스의 기본 테이블스페이스가 선택됩니다." + +#: utils/misc/guc.c:3867 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "임시 테이블 및 정렬 파일에 사용할 테이블스페이스를 설정합니다." + +#: utils/misc/guc.c:3878 +msgid "Sets the path for dynamically loadable modules." +msgstr "동적으로 불러올 수 있는 모듈들이 있는 경로를 지정함." + +#: utils/misc/guc.c:3879 +msgid "" +"If a dynamically loadable module needs to be opened and the specified name " +"does not have a directory component (i.e., the name does not contain a " +"slash), the system will search this path for the specified file." +msgstr "" +"동적으로 로드 가능한 모듈을 열어야 하는데 지정한 이름에 디렉터리 구성 요" +"소가 없는 경우(즉, 이름에 슬래시가 없음) 시스템은 이 경로에서 지정한 파일을 " +"검색합니다." + +#: utils/misc/guc.c:3892 +msgid "Sets the location of the Kerberos server key file." +msgstr "Kerberos 서버 키 파일의 위치를 지정함." + +#: utils/misc/guc.c:3903 +msgid "Sets the Bonjour service name." +msgstr "Bonjour 서비스 이름을 지정" + +#: utils/misc/guc.c:3915 +msgid "Shows the collation order locale." +msgstr "데이터 정렬 순서 로케일을 표시합니다." + +#: utils/misc/guc.c:3926 +msgid "Shows the character classification and case conversion locale." +msgstr "문자 분류 및 대/소문자 변환 로케일을 표시합니다." + +#: utils/misc/guc.c:3937 +msgid "Sets the language in which messages are displayed." +msgstr "보여질 메시지로 사용할 언어 지정." + +#: utils/misc/guc.c:3947 +msgid "Sets the locale for formatting monetary amounts." +msgstr "통화금액 표현 양식으로 사용할 로케일 지정." + +#: utils/misc/guc.c:3957 +msgid "Sets the locale for formatting numbers." +msgstr "숫자 표현 양식으로 사용할 로케일 지정." + +#: utils/misc/guc.c:3967 +msgid "Sets the locale for formatting date and time values." +msgstr "날짜와 시간 값을 표현할 양식으로 사용할 로케일 지정." + +#: utils/misc/guc.c:3977 +msgid "Lists shared libraries to preload into each backend." +msgstr "각각의 백엔드에 미리 불러올 공유 라이브러리들을 지정합니다" + +#: utils/misc/guc.c:3988 +msgid "Lists shared libraries to preload into server." +msgstr "서버에 미리 불러올 공유 라이브러리들을 지정합니다" + +#: utils/misc/guc.c:3999 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "" +"각각의 백엔드에 미리 불러올 접근제한 없는 공유 라이브러리들을 지정합니다" + +#: utils/misc/guc.c:4010 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "스키마로 한정되지 않은 이름의 스키마 검색 순서를 설정합니다." + +#: utils/misc/guc.c:4022 +msgid "Sets the server (database) character set encoding." +msgstr "서버 문자 코드 세트 인코딩 지정." + +#: utils/misc/guc.c:4034 +msgid "Shows the server version." +msgstr "서버 버전 보임." + +#: utils/misc/guc.c:4046 +msgid "Sets the current role." +msgstr "현재 롤을 지정" + +#: utils/misc/guc.c:4058 +msgid "Sets the session user name." +msgstr "세션 사용자 이름 지정." + +#: utils/misc/guc.c:4069 +msgid "Sets the destination for server log output." +msgstr "서버 로그 출력을 위한 대상을 지정합니다." + +#: utils/misc/guc.c:4070 +msgid "" +"Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and " +"\"eventlog\", depending on the platform." +msgstr "" +"유효한 값은 플랫폼에 따라 \"stderr\", \"syslog\", \"csvlog\" 및 \"eventlog" +"\"의 조합입니다." + +#: utils/misc/guc.c:4081 +msgid "Sets the destination directory for log files." +msgstr "로그 파일의 대상 디렉터리를 설정합니다." + +#: utils/misc/guc.c:4082 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "데이터 디렉터리의 상대 경로 또는 절대 경로로 지정할 수 있습니다." + +#: utils/misc/guc.c:4092 +msgid "Sets the file name pattern for log files." +msgstr "로그 파일의 파일 이름 패턴을 설정합니다." + +#: utils/misc/guc.c:4103 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "syslog에서 구분할 PostgreSQL 메시지에 사용될 프로그램 이름을 지정." + +#: utils/misc/guc.c:4114 +msgid "" +"Sets the application name used to identify PostgreSQL messages in the event " +"log." +msgstr "" +"이벤트 로그에서 PostgreSQL 메시지 식별자로 사용할 응용프로그램 이름 지정" + +#: utils/misc/guc.c:4125 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "시간대(time zone)를 지정함." + +#: utils/misc/guc.c:4135 +msgid "Selects a file of time zone abbreviations." +msgstr "표준 시간대 약어 파일을 선택합니다." + +#: utils/misc/guc.c:4145 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "유닉스 도메인 소켓의 소유주를 지정" + +#: utils/misc/guc.c:4146 +msgid "" +"The owning user of the socket is always the user that starts the server." +msgstr "소켓 소유자는 항상 서버를 시작하는 사용자입니다." + +#: utils/misc/guc.c:4156 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "유닉스 도메인 소켓을 만들 디렉터리를 지정합니다." + +#: utils/misc/guc.c:4171 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "서비스할 호스트이름이나, IP를 지정함." + +#: utils/misc/guc.c:4186 +msgid "Sets the server's data directory." +msgstr "서버의 데이터 디렉터리 위치를 지정합니다." + +#: utils/misc/guc.c:4197 +msgid "Sets the server's main configuration file." +msgstr "서버의 기본 환경설정 파일 경로를 지정합니다." + +#: utils/misc/guc.c:4208 +msgid "Sets the server's \"hba\" configuration file." +msgstr "서버의 \"hba\" 구성 파일을 설정합니다." + +#: utils/misc/guc.c:4219 +msgid "Sets the server's \"ident\" configuration file." +msgstr "서버의 \"ident\" 구성 파일을 설정합니다." + +#: utils/misc/guc.c:4230 +msgid "Writes the postmaster PID to the specified file." +msgstr "postmaster PID가 기록된 파일의 경로를 지정합니다." + +#: utils/misc/guc.c:4241 +msgid "Name of the SSL library." +msgstr "" + +#: utils/misc/guc.c:4256 +msgid "Location of the SSL server certificate file." +msgstr "서버 인증서 파일 위치를 지정함" + +#: utils/misc/guc.c:4266 +msgid "Location of the SSL server private key file." +msgstr "SSL 서버 개인 키 파일의 위치를 지정함." + +#: utils/misc/guc.c:4276 +msgid "Location of the SSL certificate authority file." +msgstr "" + +#: utils/misc/guc.c:4286 +msgid "Location of the SSL certificate revocation list file." +msgstr "SSL 인증서 파기 목록 파일의 위치" + +#: utils/misc/guc.c:4296 +msgid "Writes temporary statistics files to the specified directory." +msgstr "지정한 디렉터리에 임시 통계 파일을 씁니다." + +#: utils/misc/guc.c:4307 +msgid "" +"Number of synchronous standbys and list of names of potential synchronous " +"ones." +msgstr "" + +#: utils/misc/guc.c:4318 +msgid "Sets default text search configuration." +msgstr "기본 텍스트 검색 구성을 설정합니다." + +#: utils/misc/guc.c:4328 +msgid "Sets the list of allowed SSL ciphers." +msgstr "허용되는 SSL 암호 목록을 설정합니다." + +#: utils/misc/guc.c:4343 +msgid "Sets the curve to use for ECDH." +msgstr "ECDH에 사용할 curve 설정" + +#: utils/misc/guc.c:4358 +msgid "Location of the SSL DH parameters file." +msgstr "SSL DH 매개 변수 파일의 위치." + +#: utils/misc/guc.c:4369 +msgid "Command to obtain passphrases for SSL." +msgstr "" + +#: utils/misc/guc.c:4380 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "" + +#: utils/misc/guc.c:4391 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "" + +#: utils/misc/guc.c:4402 +msgid "" +"Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "" + +#: utils/misc/guc.c:4403 +msgid "" +"Full-page images will be logged for all data blocks and cross-checked " +"against the results of WAL replay." +msgstr "" + +#: utils/misc/guc.c:4413 +msgid "JIT provider to use." +msgstr "사용할 JIT 제공자" + +#: utils/misc/guc.c:4424 +msgid "Log backtrace for errors in these functions." +msgstr "이 함수들 안에 오류 추적용 로그를 남김" + +#: utils/misc/guc.c:4444 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "문자열에서 \"\\'\" 문자 사용을 허용할 것인지를 정하세요" + +#: utils/misc/guc.c:4454 +msgid "Sets the output format for bytea." +msgstr "bytea 값의 표시 형식을 설정합니다." + +#: utils/misc/guc.c:4464 +msgid "Sets the message levels that are sent to the client." +msgstr "클라이언트 측에 보여질 메시지 수준을 지정함." + +#: utils/misc/guc.c:4465 utils/misc/guc.c:4530 utils/misc/guc.c:4541 +#: utils/misc/guc.c:4617 +msgid "" +"Each level includes all the levels that follow it. The later the level, the " +"fewer messages are sent." +msgstr "" +"각 수준에는 이 수준 뒤에 있는 모든 수준이 포함됩니다. 수준이 뒤에 있을수" +"록 전송되는 메시지 수가 적습니다." + +#: utils/misc/guc.c:4475 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "실행계획기가 쿼리 최적화 작업에서 제약 조건을 사용하도록 함" + +#: utils/misc/guc.c:4476 +msgid "" +"Table scans will be skipped if their constraints guarantee that no rows " +"match the query." +msgstr "" +"제약 조건에 의해 쿼리와 일치하는 행이 없는 경우 테이블 스캔을 건너뜁니" +"다." + +#: utils/misc/guc.c:4487 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "각 새 트랜잭션의 트랜잭션 격리 수준을 설정합니다." + +#: utils/misc/guc.c:4497 +msgid "Sets the current transaction's isolation level." +msgstr "현재 트랜잭션 독립성 수준(isolation level)을 지정함." + +#: utils/misc/guc.c:4508 +msgid "Sets the display format for interval values." +msgstr "간격 값의 표시 형식을 설정합니다." + +#: utils/misc/guc.c:4519 +msgid "Sets the verbosity of logged messages." +msgstr "기록되는 메시지의 상세 정도를 지정합니다." + +#: utils/misc/guc.c:4529 +msgid "Sets the message levels that are logged." +msgstr "서버 로그에 기록될 메시지 수준을 지정함." + +#: utils/misc/guc.c:4540 +msgid "" +"Causes all statements generating error at or above this level to be logged." +msgstr "" +"오류가 있는 모든 쿼리문이나 지정한 로그 레벨 이상의 쿼리문을 로그로 남김" + +#: utils/misc/guc.c:4551 +msgid "Sets the type of statements logged." +msgstr "서버로그에 기록될 구문 종류를 지정합니다." + +#: utils/misc/guc.c:4561 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "syslog 기능을 사용할 때, 사용할 syslog \"facility\" 값을 지정." + +#: utils/misc/guc.c:4576 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "트리거 및 다시 쓰기 규칙에 대한 세션의 동작을 설정합니다." + +#: utils/misc/guc.c:4586 +msgid "Sets the current transaction's synchronization level." +msgstr "현재 트랜잭션 격리 수준(isolation level)을 지정함." + +#: utils/misc/guc.c:4596 +msgid "Allows archiving of WAL files using archive_command." +msgstr "archive_command를 사용하여 WAL 파일을 따로 보관하도록 설정합니다." + +#: utils/misc/guc.c:4606 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "" + +#: utils/misc/guc.c:4616 +msgid "Enables logging of recovery-related debugging information." +msgstr "복구 작업과 관련된 디버깅 정보를 기록하도록 합니다." + +#: utils/misc/guc.c:4632 +msgid "Collects function-level statistics on database activity." +msgstr "데이터베이스 활동에 대한 함수 수준 통계를 수집합니다." + +#: utils/misc/guc.c:4642 +msgid "Set the level of information written to the WAL." +msgstr "WAL에 저장할 내용 수준을 지정합니다." + +#: utils/misc/guc.c:4652 +msgid "Selects the dynamic shared memory implementation used." +msgstr "사용할 동적 공유 메모리 관리방식을 선택합니다." + +#: utils/misc/guc.c:4662 +msgid "" +"Selects the shared memory implementation used for the main shared memory " +"region." +msgstr "사용할 동적 공유 메모리 관리방식을 선택합니다." + +#: utils/misc/guc.c:4672 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "디스크에 대한 강제 WAL 업데이트에 사용되는 방법을 선택합니다." + +#: utils/misc/guc.c:4682 +msgid "Sets how binary values are to be encoded in XML." +msgstr "XML에서 바이너리 값이 인코딩되는 방식을 설정합니다." + +#: utils/misc/guc.c:4692 +msgid "" +"Sets whether XML data in implicit parsing and serialization operations is to " +"be considered as documents or content fragments." +msgstr "" +"암시적 구문 분석 및 직렬화 작업의 XML 데이터를 문서 또는 내용 조각으로 간주할" +"지 여부를 설정합니다." + +#: utils/misc/guc.c:4703 +msgid "Use of huge pages on Linux or Windows." +msgstr "리눅스 또는 Windows huge 페이지 사용 여부" + +#: utils/misc/guc.c:4713 +msgid "Forces use of parallel query facilities." +msgstr "병렬 쿼리 기능을 활성화" + +#: utils/misc/guc.c:4714 +msgid "" +"If possible, run query using a parallel worker and with parallel " +"restrictions." +msgstr "" + +#: utils/misc/guc.c:4724 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "" + +#: utils/misc/guc.c:4734 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "" + +#: utils/misc/guc.c:4735 +msgid "" +"Prepared statements can have custom and generic plans, and the planner will " +"attempt to choose which is better. This can be set to override the default " +"behavior." +msgstr "" + +#: utils/misc/guc.c:4747 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "사용할 최소 SSL/TLS 프로토콜 버전을 지정합니다." + +#: utils/misc/guc.c:4759 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "사용할 최대 SSL/TLS 프로토콜 버전을 지정합니다." + +#: utils/misc/guc.c:5562 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리에 액세스할 수 없음: %s\n" + +#: utils/misc/guc.c:5567 +#, c-format +msgid "" +"Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "" +"initdb 명령이나, pg_basebackup 명령으로 PostgreSQL 데이터 디렉터리를 초기화 " +"하세요.\n" + +#: utils/misc/guc.c:5587 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA " +"environment variable.\n" +msgstr "" +"%s 프로그램은 데이터베이스 시스템 환경 설정 파일을 찾지 못했습니다.\n" +"직접 --config-file 또는 -D 옵션을 이용해서 데이터 디렉터리를 지정하든지,\n" +"PGDATA 이름의 환경 변수를 만들고 그 값으로 해당 디렉터리를 지정한 뒤,\n" +"이 프로그램을 다시 실행해 보십시오.\n" + +#: utils/misc/guc.c:5606 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: \"%s\" 환경 설정 파일을 접근할 수 없습니다: %s\n" + +#: utils/misc/guc.c:5632 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D " +"invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s 프로그램은 데이터베이스 시스템 데이터 디렉터리를 찾지 못했습니다.\n" +"\"%s\" 파일에서 \"data_directory\" 값을 지정하든지,\n" +"직접 -D 옵션을 이용해서 데이터 디렉터리를 지정하든지,\n" +"PGDATA 이름의 환경 변수를 만들고 그 값으로 해당 디렉터리를 지정한 뒤,\n" +"이 프로그램을 다시 실행해 보십시오.\n" + +#: utils/misc/guc.c:5680 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation " +"option, or by the PGDATA environment variable.\n" +msgstr "" +"%s 프로그램은 \"hba\" 환경설정파일을 찾지 못했습니다.\n" +"\"%s\" 파일에서 \"hba_file\" 값을 지정하든지,\n" +"직접 -D 옵션을 이용해서 데이터 디렉터리를 지정하든지,\n" +"PGDATA 이름의 환경 변수를 만들고 그 값으로 해당 디렉터리를 지정한 뒤,\n" +"이 프로그램을 다시 실행해 보십시오.\n" + +#: utils/misc/guc.c:5703 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation " +"option, or by the PGDATA environment variable.\n" +msgstr "" +"%s 프로그램은 \"ident\" 환경설정파일을 찾지 못했습니다.\n" +"\"%s\" 파일에서 \"ident_file\" 값을 지정하든지,\n" +"직접 -D 옵션을 이용해서 데이터 디렉터리를 지정하든지,\n" +"PGDATA 이름의 환경 변수를 만들고 그 값으로 해당 디렉터리를 지정한 뒤,\n" +"이 프로그램을 다시 실행해 보십시오.\n" + +#: utils/misc/guc.c:6545 +msgid "Value exceeds integer range." +msgstr "값이 정수 범위를 초과합니다." + +#: utils/misc/guc.c:6781 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s 값은 \"%s\" 매개 변수의 값으로 타당한 범위(%d .. %d)를 벗어남" + +#: utils/misc/guc.c:6817 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s 값은 \"%s\" 매개 변수의 값으로 타당한 범위(%g .. %g)를 벗어남" + +#: utils/misc/guc.c:6973 utils/misc/guc.c:8340 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "병렬 작업 중에는 매개 변수를 설정할 수 없음" + +#: utils/misc/guc.c:6980 utils/misc/guc.c:7732 utils/misc/guc.c:7785 +#: utils/misc/guc.c:7836 utils/misc/guc.c:8169 utils/misc/guc.c:8936 +#: utils/misc/guc.c:9198 utils/misc/guc.c:10864 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "알 수 없는 환경 매개 변수 이름: \"%s\"" + +#: utils/misc/guc.c:6995 utils/misc/guc.c:8181 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "\"%s\" 매개 변수는 변경될 수 없음" + +#: utils/misc/guc.c:7018 utils/misc/guc.c:7212 utils/misc/guc.c:7302 +#: utils/misc/guc.c:7392 utils/misc/guc.c:7500 utils/misc/guc.c:7595 +#: guc-file.l:352 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "\"%s\" 매개 변수는 서버 재실행 없이 지금 변경 될 수 없음" + +#: utils/misc/guc.c:7028 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "\"%s\" 매개 변수는 지금 변경 될 수 없음" + +#: utils/misc/guc.c:7046 utils/misc/guc.c:7093 utils/misc/guc.c:10880 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "\"%s\" 매개 변수를 지정할 권한이 없습니다." + +#: utils/misc/guc.c:7083 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "\"%s\" 매개 변수값은 연결 시작한 뒤에는 변경할 수 없습니다" + +#: utils/misc/guc.c:7131 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "보안 정의자 함수 내에서 \"%s\" 매개 변수를 설정할 수 없음" + +#: utils/misc/guc.c:7740 utils/misc/guc.c:7790 utils/misc/guc.c:9205 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "\"%s\" 검사를 위한 pg_read_all_settings의 맴버는 superuser여야합니다" + +#: utils/misc/guc.c:7881 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s 명령은 하나의 값만 지정해야합니다" + +#: utils/misc/guc.c:8129 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "슈퍼유저만 ALTER SYSTEM 명령을 실행할 수 있음" + +#: utils/misc/guc.c:8214 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "" +"ALTER SYSTEM 명령으로 지정하는 매개 변수 값에는 줄바꿈 문자가 없어야 합니다" + +#: utils/misc/guc.c:8259 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "\"%s\" 파일의 내용을 분석할 수 없음" + +#: utils/misc/guc.c:8416 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT 명령은 아직 구현 되지 않았습니다" + +#: utils/misc/guc.c:8500 +#, c-format +msgid "SET requires parameter name" +msgstr "SET 명령은 매개 변수 이름이 필요합니다" + +#: utils/misc/guc.c:8633 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "\"%s\" 매개 변수를 다시 정의하려고 함" + +#: utils/misc/guc.c:10426 +#, c-format +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "\"%s\" 매개 변수 값을 \"%s\" (으)로 바꾸는 중" + +#: utils/misc/guc.c:10494 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "\"%s\" 매개 변수는 설정할 수 없음" + +#: utils/misc/guc.c:10584 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "지정한 \"%s\" 매개 변수값의 구문분석을 실패했습니다." + +#: utils/misc/guc.c:10942 utils/misc/guc.c:10976 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "잘못된 \"%s\" 매개 변수의 값: %d" + +#: utils/misc/guc.c:11010 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "잘못된 \"%s\" 매개 변수의 값: %g" + +#: utils/misc/guc.c:11280 +#, c-format +msgid "" +"\"temp_buffers\" cannot be changed after any temporary tables have been " +"accessed in the session." +msgstr "" +"해당 세션에서 어떤 임시 테이블도 사용하고 있지 않아야 \"temp_buffers\" 설정" +"을 변경할 수 있습니다." + +#: utils/misc/guc.c:11292 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour 기능을 뺀 채로 서버가 만들어졌습니다." + +#: utils/misc/guc.c:11305 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL 접속 기능을 뺀 채로 서버가 만들어졌습니다." + +#: utils/misc/guc.c:11317 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "\"log_statement_stats\" 값이 true 일 때는 이 값을 활성화할 수 없습니다" + +#: utils/misc/guc.c:11329 +#, c-format +msgid "" +"Cannot enable \"log_statement_stats\" when \"log_parser_stats\", " +"\"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "" +"\"log_parser_stats\", \"log_planner_stats\", \"log_executor_stats\" 설정값들 " +"중 하나가 true 일 때는 \"log_statement_stats\" 설정을 활성화할 수 없습니다" + +#: utils/misc/guc.c:11559 +#, c-format +msgid "" +"effective_io_concurrency must be set to 0 on platforms that lack " +"posix_fadvise()." +msgstr "" + +#: utils/misc/guc.c:11572 +#, c-format +msgid "" +"maintenance_io_concurrency must be set to 0 on platforms that lack " +"posix_fadvise()." +msgstr "" + +#: utils/misc/guc.c:11688 +#, c-format +msgid "invalid character" +msgstr "잘못된 문자" + +#: utils/misc/guc.c:11748 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline 값으로 잘못된 숫자입니다." + +#: utils/misc/guc.c:11788 +#, c-format +msgid "multiple recovery targets specified" +msgstr "복구 대상을 다중 지정했음" + +#: utils/misc/guc.c:11789 +#, c-format +msgid "" +"At most one of recovery_target, recovery_target_lsn, recovery_target_name, " +"recovery_target_time, recovery_target_xid may be set." +msgstr "" + +#: utils/misc/guc.c:11797 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "이 값으로는 \"immediate\" 만 허용합니다." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "내부 오류: 알 수 없는 실시간 서버 설정 변수\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "" +"query-specified return tuple and function return type are not compatible" +msgstr "" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "계산된 CRC 체크섬 값이 파일에 저장된 값과 다름" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "\"%s\" 테이블의 로우 단위 보안 정책에 의해 쿼리가 영향을 받음" + +#: utils/misc/rls.c:129 +#, c-format +msgid "" +"To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW " +"LEVEL SECURITY." +msgstr "" +"테이블 소유주를 위해 정책을 비활성하려면, ALTER TABLE NO FORCE ROW LEVEL " +"SECURITY 명령을 사용하세요" + +#: utils/misc/timeout.c:395 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "시간 초과로 더이상 추가할 수 없음" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "" +"time zone abbreviation \"%s\" is too long (maximum %d characters) in time " +"zone file \"%s\", line %d" +msgstr "" +"\"%s\" 타임 존 이름이 너무 깁니다(최대 %d자) (\"%s\" 타임 존 파일의 %d번째 줄" +"에 있음)." + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "" +"%d 타임 존 오프셋 값이 범위를 벗어났습니다(\"%s\" 타임 존 파일의 %d번째 줄에 " +"있음)." + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone 파일의 %d번째 줄에 time zone 생략형이 빠졌음" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone 파일의 %d번째 줄에 time zone 옵셋이 빠졌음" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "" +"\"%s\" 표준 시간대 파일의 %d번째 줄에서 표준 시간대 오프셋 숫자가 잘못됨" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone 파일의 %d번째 줄에 구문 오류" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "표준 시간대 약어 \"%s\"은(는) 배수로 정의됨" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "" +"Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s" +"\", line %d." +msgstr "" +"\"%s\" 타임 존 파일의 %d번째 줄에 있는 항목이 \"%s\" 파일의 %d번째 줄에 있는 " +"항목과 충돌합니다." + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "잘못된 time zone 파일 이름: \"%s\"" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "\"%s\" 파일에서 time zone 파일 재귀호출 최대치를 초과했음" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "\"%s\" time zone 파일을 읽을 수 없음: %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "\"%s\" 표준 시간대 파일의 %d번째 줄이 너무 깁니다." + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "\"%s\" 표준 시간대 파일의 %d번째 줄에 파일 이름이 없는 @INCLUDE가 있음" + +#: utils/mmgr/aset.c:476 utils/mmgr/generation.c:234 utils/mmgr/slab.c:236 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "\"%s\" 메모리 컨텍스트를 만드는 동안 오류가 발생했습니다." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "동적 공유 메모리 영역을 할당할 수 없음" + +#: utils/mmgr/mcxt.c:822 utils/mmgr/mcxt.c:858 utils/mmgr/mcxt.c:896 +#: utils/mmgr/mcxt.c:934 utils/mmgr/mcxt.c:970 utils/mmgr/mcxt.c:1001 +#: utils/mmgr/mcxt.c:1037 utils/mmgr/mcxt.c:1089 utils/mmgr/mcxt.c:1124 +#: utils/mmgr/mcxt.c:1159 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "크기가 %zu인 요청에서 오류가 발생했습니다. 해당 메모리 컨텍스트 \"%s\"" + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "\"%s\" 이름의 커서가 이미 있음" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "이미 있는 \"%s\" 커서를 닫습니다" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "\"%s\" portal 실행할 수 없음" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "\"%s\" 선점된 포털을 삭제할 수 없음" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "\"%s\" 활성 포털을 삭제할 수 없음" + +#: utils/mmgr/portalmem.c:731 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "WITH HOLD 옵션으로 커서를 만든 트랜잭션을 PREPARE할 수 없음" + +#: utils/mmgr/portalmem.c:1270 +#, c-format +msgid "" +"cannot perform transaction commands inside a cursor loop that is not read-" +"only" +msgstr "" + +#: utils/sort/logtape.c:266 utils/sort/logtape.c:289 +#, c-format +msgid "could not seek to block %ld of temporary file" +msgstr "임시 파일의 %ld 블럭을 찾을 수 없음" + +#: utils/sort/logtape.c:295 +#, c-format +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "%ld 블럭을 임시 파일에서 읽을 수 없음: %zu / %zu 바이트만 읽음" + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 +#: utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 +#: utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "tuplestore 임시 파일을 읽을 수 없음" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "공유된 tuplestore 임시 파일에서 예상치 못한 청크" + +#: utils/sort/sharedtuplestore.c:569 +#, c-format +msgid "could not seek to block %u in shared tuplestore temporary file" +msgstr "공유 tuplestore 임시 파일에서 %u 블록을 찾을 수 없음" + +#: utils/sort/sharedtuplestore.c:576 +#, c-format +msgid "" +"could not read from shared tuplestore temporary file: read only %zu of %zu " +"bytes" +msgstr "공유 tuplestore 임시 파일을 읽을 수 없음: %zu / %zu 바이트만 읽음" + +#: utils/sort/tuplesort.c:3140 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "외부 정렬을 위해 %d 개 이상의 런을 만들 수 없음" + +#: utils/sort/tuplesort.c:4221 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "\"%s\" 고유 인덱스를 만들 수 없음" + +#: utils/sort/tuplesort.c:4223 +#, c-format +msgid "Key %s is duplicated." +msgstr "%s 키가 중복됨" + +#: utils/sort/tuplesort.c:4224 +#, c-format +msgid "Duplicate keys exist." +msgstr "중복된 키가 있음" + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "tuplestore 임시 파일에서 seek 작업을 할 수 없음" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 +#: utils/sort/tuplestore.c:1548 +#, c-format +msgid "" +"could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "tuplestore 임시 파일을 읽을 수 없음: %zu / %zu 바이트만 읽음" + +#: utils/time/snapmgr.c:624 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "소스 트랜잭션이 더 이상 실행중이지 않음" + +#: utils/time/snapmgr.c:1232 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "서브트랜잭션에서 스냅샷을 내보낼 수 없음" + +#: utils/time/snapmgr.c:1391 utils/time/snapmgr.c:1396 +#: utils/time/snapmgr.c:1401 utils/time/snapmgr.c:1416 +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1426 +#: utils/time/snapmgr.c:1441 utils/time/snapmgr.c:1446 +#: utils/time/snapmgr.c:1451 utils/time/snapmgr.c:1553 +#: utils/time/snapmgr.c:1569 utils/time/snapmgr.c:1594 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "\"%s\" 파일에 유효하지 않은 스냅샷 자료가 있습니다" + +#: utils/time/snapmgr.c:1488 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "쿼리보다 먼저 SET TRANSACTION SNAPSHOP 명령을 호출해야 함" + +#: utils/time/snapmgr.c:1497 +#, c-format +msgid "" +"a snapshot-importing transaction must have isolation level SERIALIZABLE or " +"REPEATABLE READ" +msgstr "" +"스냅샷 가져오기 트랜잭션은 그 격리 수준이 SERIALIZABLE 또는 REPEATABLE READ " +"여야 함" + +#: utils/time/snapmgr.c:1506 utils/time/snapmgr.c:1515 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "잘못된 스냅샷 식별자: \"%s\"" + +#: utils/time/snapmgr.c:1607 +#, c-format +msgid "" +"a serializable transaction cannot import a snapshot from a non-serializable " +"transaction" +msgstr "" +"직렬화 가능한 트랜잭션은 직렬화 가능하지 않은 트랜잭션에서 스냅샷을 가져올 " +"수 없음" + +#: utils/time/snapmgr.c:1611 +#, c-format +msgid "" +"a non-read-only serializable transaction cannot import a snapshot from a " +"read-only transaction" +msgstr "" +"읽기-쓰기 직렬화된 트랜잭션이 읽기 전용 트랜잭션의 스냅샷을 가져올 수 없음" + +#: utils/time/snapmgr.c:1626 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "서로 다른 데이터베이스를 대상으로는 스냅샷을 가져올 수 없음" + +#: gram.y:1047 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD 옵션은 더이상 지원하지 않음" + +#: gram.y:1048 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "" + +#: gram.y:1110 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "인식할 수 없는 롤 옵션 \"%s\"" + +#: gram.y:1357 gram.y:1372 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "" +"CREATE SCHEMA IF NOT EXISTS 구문에서는 스키마 요소들을 포함할 수 없습니다." + +#: gram.y:1518 +#, c-format +msgid "current database cannot be changed" +msgstr "현재 데이터베이스를 바꿀 수 없음" + +#: gram.y:1642 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "" +"지역시간대 간격(time zone interval) 값은 시(HOUR) 또는 시분(HOUR TO MINUTE) " +"값이어야합니다" + +#: gram.y:2177 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "칼럼 번호는 1 - %d 사이의 범위에 있어야 합니다." + +#: gram.y:2709 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "\"%s\" 시퀀스 옵션은 지원되지 않음" + +#: gram.y:2738 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "해시 파티션용 모듈을 한 번 이상 지정했습니다" + +#: gram.y:2747 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "해시 파티션용 나머지 처리기를 한 번 이상 지정했습니다" + +#: gram.y:2754 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "잘못된 해시 파티션 범위 명세 \"%s\"" + +#: gram.y:2762 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "해시 파티션용 모듈을 지정하세요" + +#: gram.y:2766 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "해시 파티션용 나머지 처리기를 지정하세요" + +#: gram.y:2967 gram.y:3000 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "PROGRAM 옵션과 STDIN/STDOUT 옵션은 함께 쓸 수 없습니다" + +#: gram.y:2973 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "WHERE 절은 COPY TO 구문을 허용하지 않음" + +#: gram.y:3305 gram.y:3312 gram.y:11647 gram.y:11655 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "GLOBAL 예약어는 임시 테이블 만들기에서 더 이상 사용하지 않습니다" + +#: gram.y:3552 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "" + +#: gram.y:4512 +#, c-format +msgid "CREATE EXTENSION ... FROM is no longer supported" +msgstr "CREATE EXTENSION ... FROM 구문은 지원하지 않습니다." + +#: gram.y:5338 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "인식할 수 없는 로우 단위 보안 옵션 \"%s\"" + +#: gram.y:5339 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "" + +#: gram.y:5452 +msgid "duplicate trigger events specified" +msgstr "중복 트리거 이벤트가 지정됨" + +#: gram.y:5600 +#, c-format +msgid "conflicting constraint properties" +msgstr "제약조건 속성이 충돌함" + +#: gram.y:5696 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION 명령은 아직 구현 되지 않았습니다" + +#: gram.y:6079 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK는 더 이상 필요하지 않음" + +#: gram.y:6080 +#, c-format +msgid "Update your data type." +msgstr "자료형을 업데이트하십시오." + +#: gram.y:7831 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "집계 함수는 output 인자를 지정할 수 없음" + +#: gram.y:10153 gram.y:10171 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION 구문은 재귀적인 뷰에서 지원하지 않습니다" + +#: gram.y:11779 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "LIMIT #,# 구문은 지원하지 않습니다." + +#: gram.y:11780 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "LIMIT # OFFSET # 구문을 사용하세요." + +#: gram.y:12106 gram.y:12131 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "FROM 안의 VALUES는 반드시 alias가 있어야합니다" + +#: gram.y:12107 gram.y:12132 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "예, FROM (VALUES ...) [AS] foo." + +#: gram.y:12112 gram.y:12137 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "FROM 절 내의 subquery 에는 반드시 alias 를 가져야만 합니다" + +#: gram.y:12113 gram.y:12138 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "예, FROM (SELECT ...) [AS] foo." + +#: gram.y:12591 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "" + +#: gram.y:12600 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "" + +#: gram.y:12609 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "NULL/NOT NULL 선언이 서로 충돌합니다 : \"%s\" 칼럼" + +#: gram.y:12618 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "인식할 수 없는 칼럼 옵션 \"%s\"" + +#: gram.y:12872 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "실수형 자료의 정밀도 값으로는 적어도 1 bit 이상을 지정해야합니다." + +#: gram.y:12881 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "실수형 자료의 정밀도 값으로 최대 54 bit 까지입니다." + +#: gram.y:13372 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "OVERLAPS 식의 왼쪽에 있는 매개 변수 수가 잘못됨" + +#: gram.y:13377 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "OVERLAPS 식의 오른쪽에 있는 매개 변수 수가 잘못됨" + +#: gram.y:13552 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "UNIQUE 술어는 아직 구현되지 못했습니다" + +#: gram.y:13915 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "WITHIN GROUP 구문 안에서 중복된 ORDER BY 구문은 허용하지 않습니다" + +#: gram.y:13920 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "DISTINCT과 WITHIN GROUP을 함께 쓸 수 없습니다" + +#: gram.y:13925 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "VARIADIC과 WITHIN GROUP을 함께 쓸 수 없습니다" + +#: gram.y:14391 gram.y:14414 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "프레임 시작은 UNBOUNDED FOLLOWING일 수 없음" + +#: gram.y:14396 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "따라오는 로우의 프레임 시작은 현재 로우의 끝일 수 없습니다" + +#: gram.y:14419 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "프레임 끝은 UNBOUNDED PRECEDING일 수 없음" + +#: gram.y:14425 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "현재 로우의 프레임 시작은 선행하는 로우를 가질 수 없습니다" + +#: gram.y:14432 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "따라오는 로우의 프레임 시작은 선행하는 로우를 가질 수 없습니다" + +#: gram.y:15082 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "자료형 한정자는 매개 변수 이름을 사용할 수 없음" + +#: gram.y:15088 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "자료형 한정자는 ORDER BY 구문을 사용할 수 없음" + +#: gram.y:15153 gram.y:15160 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s 이름은 여기서 롤 이름으로 사용할 수 없음" + +#: gram.y:15841 gram.y:16030 +msgid "improper use of \"*\"" +msgstr "\"*\" 사용이 잘못됨" + +#: gram.y:16094 +#, c-format +msgid "" +"an ordered-set aggregate with a VARIADIC direct argument must have one " +"VARIADIC aggregated argument of the same data type" +msgstr "" + +#: gram.y:16131 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "중복된 ORDER BY 구문은 허용하지 않습니다" + +#: gram.y:16142 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "중복된 OFFSET 구문은 허용하지 않습니다" + +#: gram.y:16151 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "중복된 LIMIT 구문은 허용하지 않습니다" + +#: gram.y:16160 +#, c-format +msgid "multiple limit options not allowed" +msgstr "중복된 limit 옵션은 허용하지 않음" + +#: gram.y:16164 +#, c-format +msgid "WITH TIES cannot be specified without ORDER BY clause" +msgstr "" + +#: gram.y:16172 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "중복된 WITH 절은 허용하지 않음" + +#: gram.y:16376 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "OUT 및 INOUT 인자는 TABLE 함수에 사용할 수 없음" + +#: gram.y:16472 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "중복된 COLLATE 구문은 허용하지 않습니다" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16510 gram.y:16523 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "%s 제약조건에는 DEFERRABLE 옵션을 쓸 수 없음" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16536 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "%s 제약조건에는 NOT VALID 옵션을 쓸 수 없음" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16549 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "%s 제약조건에는 NO INHERIT 옵션을 쓸 수 없음" + +#: guc-file.l:315 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "알 수 없는 환경 매개 변수 이름: \"%s\", 해당 파일: \"%s\", 줄번호: %u" + +#: guc-file.l:388 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "환경설정 파일에 \"%s\" 매개 변수가 빠졌음, 초기값을 사용함" + +#: guc-file.l:454 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "\"%s\" 매개 변수 값을 \"%s\"(으)로 바꿨음" + +#: guc-file.l:496 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "\"%s\" 환경 설정파일에 오류가 있음" + +#: guc-file.l:501 +#, c-format +msgid "" +"configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "\"%s\" 환경 설정 파일에 오류가 있어 새로 변경될 설정이 없습니다" + +#: guc-file.l:506 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "\"%s\" 환경 설정 파일에 오류가 있어 아무 설정도 반영되지 않았습니다." + +#: guc-file.l:578 +#, c-format +msgid "empty configuration file name: \"%s\"" +msgstr "비어있는 환경 설정 파일 이름: \"%s\"" + +#: guc-file.l:595 +#, c-format +msgid "" +"could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "설정 파일 \"%s\"을 열 수 없습니다: 최대 디렉터리 깊이를 초과했음" + +#: guc-file.l:615 +#, c-format +msgid "configuration file recursion in \"%s\"" +msgstr "\"%s\" 안에 환경 설정파일이 서로 참조함" + +#: guc-file.l:642 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "\"%s\" 환경 설정파일이 없으나 건너뜀" + +#: guc-file.l:896 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "\"%s\" 파일 %u 줄 끝부분에서 구문 오류 있음" + +#: guc-file.l:906 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "\"%s\" 파일 %u 줄에서 구문 오류 있음, \"%s\" 토큰 부근" + +#: guc-file.l:926 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "구문 오류가 너무 많습니다. \"%s\" 파일을 무시합니다" + +#: guc-file.l:981 +#, c-format +msgid "empty configuration directory name: \"%s\"" +msgstr "비어 있는 환경 설정 디렉터리 이름: \"%s\"" + +#: guc-file.l:1000 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "\"%s\" 환경 설정 디렉터리를 열 수 없습니다: %m" + +#: jsonpath_gram.y:529 +#, c-format +msgid "unrecognized flag character \"%c\" in LIKE_REGEX predicate" +msgstr "LIKE_REGEX 한정자 안에, 알 수 없는 플래그 문자: \"%c\"" + +#: jsonpath_gram.y:583 +#, c-format +msgid "XQuery \"x\" flag (expanded regular expressions) is not implemented" +msgstr "" + +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:286 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "%s, jsonpath 입력 끝부분" + +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:293 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s, jsonpath 입력 \"%s\" 부근" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "잘못된 타임라인: %u" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "잘못된 스트리밍 시작 위치" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "마무리 안된 따옴표 안의 문자열" + +# # advance 끝 +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "마무리 안된 /* 주석" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "마무리 안된 비트 문자열 문자" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "마무리 안된 16진수 문자열 문자" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "유니코드 이스케이프와 함께 문자열 상수를 사용하는 것은 안전하지 않음" + +#: scan.l:543 +#, c-format +msgid "" +"String constants with Unicode escapes cannot be used when " +"standard_conforming_strings is off." +msgstr "" +"standard_conforming_strings = off 인 경우 문자열 상수 표기에서 유니코드 이스" +"케이프를 사용할 수 없습니다." + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "유니코드 이스케이프는 \\uXXXX 또는 \\UXXXXXXXX 형태여야 합니다." + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "문자열 안에 \\' 사용이 안전하지 않습니다" + +#: scan.l:690 +#, c-format +msgid "" +"Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "" +"작은 따옴표는 '' 형태로 사용하십시오. \\' 표기법은 클라이언트 전용 인코딩에" +"서 안전하지 않습니다." + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "마무리 안된 달러-따옴표 안의 문자열" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "길이가 0인 구분 식별자" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "마무리 안된 따옴표 안의 식별자" + +# # nonun 부분 begin +#: scan.l:963 +msgid "operator too long" +msgstr "연산자가 너무 깁니다." + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1171 +#, c-format +msgid "%s at end of input" +msgstr "%s, 입력 끝부분" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1179 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s, \"%s\" 부근" + +#: scan.l:1373 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "문자열 안에 있는 \\' 문자는 표준이 아닙니다" + +#: scan.l:1374 +#, c-format +msgid "" +"Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "작은 따옴표는 '' 형태니, 인용부호 표기법(E'...') 형태로 사용하십시오." + +#: scan.l:1383 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "문자열 안에 있는 \\\\ 문자는 표준이 아닙니다" + +#: scan.l:1384 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "백슬래시 표기는 인용부호 표기법으로 사용하세요, 예, E'\\\\'." + +#: scan.l:1398 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "문자열 안에 비표준 escape 문자를 사용하고 있습니다" + +#: scan.l:1399 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "인용부호 표기법을 사용하세요, 예, E'\\r\\n'." diff --git a/src/backend/po/ru.po b/src/backend/po/ru.po new file mode 100644 index 000000000000..700e66ba57ad --- /dev/null +++ b/src/backend/po/ru.po @@ -0,0 +1,33522 @@ +# Russian message translation file for postgres +# Copyright (C) 2001-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Serguei A. Mokhov , 2001-2005. +# Oleg Bartunov , 2004-2005. +# Dmitriy Olshevskiy , 2014. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020, 2021. +msgid "" +msgstr "" +"Project-Id-Version: postgres (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-02-08 07:28+0300\n" +"PO-Revision-Date: 2021-02-08 08:35+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 +#: ../common/config_info.c:150 ../common/config_info.c:158 +#: ../common/config_info.c:166 ../common/config_info.c:174 +#: ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "не записано" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 +#: commands/copy.c:3495 commands/extension.c:3436 utils/adt/genfile.c:125 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не удалось открыть файл \"%s\" для чтения: %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 +#: access/transam/timeline.c:143 access/transam/timeline.c:362 +#: access/transam/twophase.c:1276 access/transam/xlog.c:3503 +#: access/transam/xlog.c:4728 access/transam/xlog.c:11101 +#: access/transam/xlog.c:11114 access/transam/xlog.c:11567 +#: access/transam/xlog.c:11647 access/transam/xlog.c:11686 +#: access/transam/xlog.c:11729 access/transam/xlogfuncs.c:662 +#: access/transam/xlogfuncs.c:681 commands/extension.c:3446 libpq/hba.c:499 +#: replication/logical/origin.c:717 replication/logical/origin.c:753 +#: replication/logical/reorderbuffer.c:3599 +#: replication/logical/snapbuild.c:1744 replication/logical/snapbuild.c:1786 +#: replication/logical/snapbuild.c:1814 replication/logical/snapbuild.c:1841 +#: replication/slot.c:1622 replication/slot.c:1663 replication/walsender.c:547 +#: storage/file/buffile.c:441 storage/file/copydir.c:195 +#: utils/adt/genfile.c:200 utils/adt/misc.c:763 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 +#: access/transam/twophase.c:1279 access/transam/xlog.c:3508 +#: access/transam/xlog.c:4733 replication/logical/origin.c:722 +#: replication/logical/origin.c:761 replication/logical/snapbuild.c:1749 +#: replication/logical/snapbuild.c:1791 replication/logical/snapbuild.c:1819 +#: replication/logical/snapbuild.c:1846 replication/slot.c:1626 +#: replication/slot.c:1667 replication/walsender.c:552 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %zu)" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 +#: ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 +#: access/heap/rewriteheap.c:1181 access/heap/rewriteheap.c:1284 +#: access/transam/timeline.c:392 access/transam/timeline.c:438 +#: access/transam/timeline.c:516 access/transam/twophase.c:1288 +#: access/transam/twophase.c:1676 access/transam/xlog.c:3375 +#: access/transam/xlog.c:3543 access/transam/xlog.c:3548 +#: access/transam/xlog.c:3876 access/transam/xlog.c:4698 +#: access/transam/xlog.c:5622 access/transam/xlogfuncs.c:687 +#: commands/copy.c:1810 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:533 +#: replication/logical/origin.c:655 replication/logical/origin.c:794 +#: replication/logical/reorderbuffer.c:3657 +#: replication/logical/snapbuild.c:1653 replication/logical/snapbuild.c:1854 +#: replication/slot.c:1513 replication/slot.c:1674 replication/walsender.c:562 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:704 +#: storage/file/fd.c:3425 storage/file/fd.c:3528 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "не удалось закрыть файл \"%s\": %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "несоответствие порядка байт" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"возможно несоответствие порядка байт\n" +"Порядок байт в файле pg_control может не соответствовать используемому\n" +"этой программой. В этом случае результаты будут неверными и\n" +"установленный PostgreSQL будет несовместим с этим каталогом данных." + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 +#: ../common/file_utils.c:224 ../common/file_utils.c:283 +#: ../common/file_utils.c:357 access/heap/rewriteheap.c:1267 +#: access/transam/timeline.c:111 access/transam/timeline.c:251 +#: access/transam/timeline.c:348 access/transam/twophase.c:1232 +#: access/transam/xlog.c:3277 access/transam/xlog.c:3417 +#: access/transam/xlog.c:3458 access/transam/xlog.c:3656 +#: access/transam/xlog.c:3741 access/transam/xlog.c:3844 +#: access/transam/xlog.c:4718 access/transam/xlogutils.c:807 +#: postmaster/syslogger.c:1488 replication/basebackup.c:621 +#: replication/basebackup.c:1593 replication/logical/origin.c:707 +#: replication/logical/reorderbuffer.c:2465 +#: replication/logical/reorderbuffer.c:2825 +#: replication/logical/reorderbuffer.c:3579 +#: replication/logical/snapbuild.c:1608 replication/logical/snapbuild.c:1715 +#: replication/slot.c:1594 replication/walsender.c:520 +#: replication/walsender.c:2509 storage/file/copydir.c:161 +#: storage/file/fd.c:679 storage/file/fd.c:3412 storage/file/fd.c:3499 +#: storage/smgr/md.c:513 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1858 +#: utils/init/miscinit.c:1316 utils/init/miscinit.c:1450 +#: utils/init/miscinit.c:1527 utils/misc/guc.c:8280 utils/misc/guc.c:8312 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 +#: access/transam/twophase.c:1649 access/transam/twophase.c:1658 +#: access/transam/xlog.c:10858 access/transam/xlog.c:10896 +#: access/transam/xlog.c:11309 access/transam/xlogfuncs.c:741 +#: postmaster/syslogger.c:1499 postmaster/syslogger.c:1512 +#: utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не удалось записать файл \"%s\": %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 +#: ../common/file_utils.c:295 ../common/file_utils.c:365 +#: access/heap/rewriteheap.c:961 access/heap/rewriteheap.c:1175 +#: access/heap/rewriteheap.c:1278 access/transam/timeline.c:432 +#: access/transam/timeline.c:510 access/transam/twophase.c:1670 +#: access/transam/xlog.c:3368 access/transam/xlog.c:3537 +#: access/transam/xlog.c:4691 access/transam/xlog.c:10366 +#: access/transam/xlog.c:10393 replication/logical/snapbuild.c:1646 +#: replication/slot.c:1499 replication/slot.c:1604 storage/file/fd.c:696 +#: storage/file/fd.c:3520 storage/smgr/md.c:959 storage/smgr/md.c:1000 +#: storage/sync/sync.c:396 utils/cache/relmapper.c:885 utils/misc/guc.c:8063 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" + +#: ../common/exec.c:137 ../common/exec.c:254 ../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не удалось определить текущий каталог: %m" + +#: ../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "неверный исполняемый файл \"%s\"" + +#: ../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "не удалось прочитать исполняемый файл \"%s\"" + +#: ../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "не удалось найти запускаемый файл \"%s\"" + +#: ../common/exec.c:270 ../common/exec.c:309 utils/init/miscinit.c:395 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не удалось перейти в каталог \"%s\": %m" + +#: ../common/exec.c:287 access/transam/xlog.c:10730 +#: replication/basebackup.c:1418 utils/adt/misc.c:337 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не удалось прочитать символическую ссылку \"%s\": %m" + +#: ../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "ошибка pclose: %m" + +#: ../common/exec.c:539 ../common/exec.c:584 ../common/exec.c:676 +#: ../common/psprintf.c:143 ../common/stringinfo.c:305 ../port/path.c:630 +#: ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1341 +#: access/transam/xlog.c:6487 lib/dshash.c:246 libpq/auth.c:1469 +#: libpq/auth.c:1537 libpq/auth.c:2067 libpq/be-secure-gssapi.c:520 +#: postmaster/bgworker.c:347 postmaster/bgworker.c:952 +#: postmaster/postmaster.c:2519 postmaster/postmaster.c:4156 +#: postmaster/postmaster.c:4858 postmaster/postmaster.c:5615 +#: postmaster/postmaster.c:5975 +#: replication/libpqwalreceiver/libpqwalreceiver.c:276 +#: replication/logical/logical.c:176 replication/walsender.c:594 +#: storage/buffer/localbuf.c:442 storage/file/fd.c:834 storage/file/fd.c:1304 +#: storage/file/fd.c:1465 storage/file/fd.c:2270 storage/ipc/procarray.c:1045 +#: storage/ipc/procarray.c:1541 storage/ipc/procarray.c:1548 +#: storage/ipc/procarray.c:1972 storage/ipc/procarray.c:2597 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1700 utils/adt/formatting.c:1824 +#: utils/adt/formatting.c:1949 utils/adt/pg_locale.c:484 +#: utils/adt/pg_locale.c:648 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:450 utils/hash/dynahash.c:559 +#: utils/hash/dynahash.c:1071 utils/mb/mbutils.c:401 utils/mb/mbutils.c:428 +#: utils/mb/mbutils.c:757 utils/mb/mbutils.c:783 utils/misc/guc.c:4846 +#: utils/misc/guc.c:4862 utils/misc/guc.c:4875 utils/misc/guc.c:8041 +#: utils/misc/tzparser.c:467 utils/mmgr/aset.c:475 utils/mmgr/dsa.c:701 +#: utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:233 +#: utils/mmgr/mcxt.c:821 utils/mmgr/mcxt.c:857 utils/mmgr/mcxt.c:895 +#: utils/mmgr/mcxt.c:933 utils/mmgr/mcxt.c:969 utils/mmgr/mcxt.c:1000 +#: utils/mmgr/mcxt.c:1036 utils/mmgr/mcxt.c:1088 utils/mmgr/mcxt.c:1123 +#: utils/mmgr/mcxt.c:1158 utils/mmgr/slab.c:235 +#, c-format +msgid "out of memory" +msgstr "нехватка памяти" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 +#: ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 +#: ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 +#: utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../common/file_utils.c:79 ../common/file_utils.c:181 +#: access/transam/twophase.c:1244 access/transam/xlog.c:10834 +#: access/transam/xlog.c:10872 access/transam/xlog.c:11089 +#: access/transam/xlogarchive.c:110 access/transam/xlogarchive.c:226 +#: commands/copy.c:1938 commands/copy.c:3505 commands/extension.c:3425 +#: commands/tablespace.c:807 commands/tablespace.c:898 +#: replication/basebackup.c:444 replication/basebackup.c:627 +#: replication/basebackup.c:700 replication/logical/snapbuild.c:1522 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1816 +#: storage/file/fd.c:3096 storage/file/fd.c:3278 storage/file/fd.c:3364 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:416 utils/adt/genfile.c:642 guc-file.l:1061 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не удалось получить информацию о файле \"%s\": %m" + +#: ../common/file_utils.c:158 ../common/pgfnames.c:48 commands/tablespace.c:730 +#: commands/tablespace.c:740 postmaster/postmaster.c:1509 +#: storage/file/fd.c:2673 storage/file/reinit.c:122 utils/adt/misc.c:259 +#: utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалось открыть каталог \"%s\": %m" + +#: ../common/file_utils.c:192 ../common/pgfnames.c:69 storage/file/fd.c:2685 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не удалось прочитать каталог \"%s\": %m" + +#: ../common/file_utils.c:375 access/transam/xlogarchive.c:411 +#: postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1665 +#: replication/slot.c:650 replication/slot.c:1385 replication/slot.c:1527 +#: storage/file/fd.c:714 utils/time/snapmgr.c:1350 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "не удалось переименовать файл \"%s\" в \"%s\": %m" + +#: ../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Неверная спецпоследовательность: \"\\%s\"." + +#: ../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Символ с кодом 0x%02x необходимо экранировать." + +#: ../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Ожидался конец текста, но обнаружено продолжение \"%s\"." + +#: ../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Ожидался элемент массива или \"]\", но обнаружено \"%s\"." + +#: ../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Ожидалась \",\" или \"]\", но обнаружено \"%s\"." + +#: ../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Ожидалось \":\", но обнаружено \"%s\"." + +#: ../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Ожидалось значение JSON, но обнаружено \"%s\"." + +#: ../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "Неожиданный конец входной строки." + +#: ../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Ожидалась строка или \"}\", но обнаружено \"%s\"." + +#: ../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Ожидалась \",\" или \"}\", но обнаружено \"%s\"." + +#: ../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Ожидалась строка, но обнаружено \"%s\"." + +#: ../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Ошибочный элемент текста \"%s\"." + +#: ../common/jsonapi.c:1099 jsonpath_scan.l:499 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 нельзя преобразовать в текст." + +#: ../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "За \"\\u\" должны следовать четыре шестнадцатеричные цифры." + +#: ../common/jsonapi.c:1104 +msgid "" +"Unicode escape values cannot be used for code point values above 007F when " +"the encoding is not UTF8." +msgstr "" +"Спецкоды Unicode для значений выше 007F можно использовать только с " +"кодировкой UTF8." + +#: ../common/jsonapi.c:1106 jsonpath_scan.l:520 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "" +"Старшее слово суррогата Unicode не может следовать за другим старшим словом." + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:531 jsonpath_scan.l:541 +#: jsonpath_scan.l:583 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Младшее слово суррогата Unicode должно следовать за старшим словом." + +#: ../common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не удалось закрыть каталог \"%s\": %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "неверное имя слоя" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Допустимые имена слоёв: \"main\", \"fsm\", \"vm\" и \"init\"." + +#: ../common/restricted_token.c:64 libpq/auth.c:1499 libpq/auth.c:2498 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "не удалось загрузить библиотеку \"%s\" (код ошибки: %lu)" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "в этой ОС нельзя создавать ограниченные маркеры (код ошибки: %lu)" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "не удалось открыть маркер процесса (код ошибки: %lu)" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "не удалось подготовить структуры SID (код ошибки: %lu)" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "не удалось создать ограниченный маркер (код ошибки: %lu)" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "не удалось запустить процесс для команды \"%s\" (код ошибки: %lu)" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "не удалось перезапуститься с ограниченным маркером (код ошибки: %lu)" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "не удалось получить код выхода от подпроцесса (код ошибки: %lu)" + +#: ../common/rmtree.c:79 replication/basebackup.c:1171 +#: replication/basebackup.c:1347 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "не удалось получить информацию о файле или каталоге \"%s\": %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "ошибка при удалении файла или каталога \"%s\": %m" + +#: ../common/saslprep.c:1087 +#, c-format +msgid "password too long" +msgstr "слишком длинный пароль" + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "" +"Не удалось увеличить строковый буфер (в буфере байт: %d, требовалось ещё %d)." + +#: ../common/stringinfo.c:310 +#, c-format +msgid "" +"out of memory\n" +"\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "" +"нехватка памяти\n" +"\n" +"Не удалось увеличить строковый буфер (в буфере байт: %d, требовалось ещё " +"%d).\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "выяснить эффективный идентификатор пользователя (%ld) не удалось: %s" + +#: ../common/username.c:45 libpq/auth.c:2005 +msgid "user does not exist" +msgstr "пользователь не существует" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "распознать имя пользователя не удалось (код ошибки: %lu)" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "неисполняемая команда" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "команда не найдена" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "дочерний процесс завершился с кодом возврата %d" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "дочерний процесс прерван исключением 0x%X" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "дочерний процесс завершён по сигналу %d: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "дочерний процесс завершился с нераспознанным состоянием %d" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "не удалось определить кодировку для набора символов \"%s\"" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "" +"не удалось определить кодировку для локали \"%s\": набор символов - \"%s\"" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "не удалось создать связь для каталога \"%s\": %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "не удалось создать связь для каталога \"%s\": %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "не удалось получить связь для каталога \"%s\": %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "не удалось получить связь для каталога \"%s\": %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "не удалось открыть файл \"%s\": %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "нарушение блокировки" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "нарушение совместного доступа" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "Попытки будут продолжены в течение 30 секунд." + +#: ../port/open.c:129 +#, c-format +msgid "" +"You might have antivirus, backup, or similar software interfering with the " +"database system." +msgstr "" +"Возможно, работе СУБД мешает антивирус, программа резервного копирования или " +"что-то подобное." + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "не удалось определить текущий рабочий каталог: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "ошибка ОС %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "не удалось получить SID группы Администраторы (код ошибки: %lu)\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "" +"не удалось получить SID группы Опытные пользователи (код ошибки: %lu)\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "" +"не удалось проверить вхождение в маркере безопасности (код ошибки: %lu)\n" + +#: access/brin/brin.c:210 +#, c-format +msgid "" +"request for BRIN range summarization for index \"%s\" page %u was not " +"recorded" +msgstr "" +"запрос на расчёт сводки диапазона BRIN для индекса \"%s\" страницы %u не был " +"записан" + +#: access/brin/brin.c:873 access/brin/brin.c:950 access/gin/ginfast.c:1035 +#: access/transam/xlog.c:10502 access/transam/xlog.c:11040 +#: access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 +#: access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 +#: access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 +#: access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "идёт процесс восстановления" + +#: access/brin/brin.c:874 access/brin/brin.c:951 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Функции управления BRIN нельзя использовать в процессе восстановления." + +#: access/brin/brin.c:882 access/brin/brin.c:959 +#, c-format +msgid "block number out of range: %s" +msgstr "номер блока вне диапазона: %s" + +#: access/brin/brin.c:905 access/brin/brin.c:982 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\" - это не индекс BRIN" + +#: access/brin/brin.c:921 access/brin/brin.c:998 +#, c-format +msgid "could not open parent table of index %s" +msgstr "не удалось родительскую таблицу индекса %s" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 +#: access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1438 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "" +"размер строки индекса (%zu) больше предельного размера (%zu) (индекс \"%s\")" + +#: access/brin/brin_revmap.c:392 access/brin/brin_revmap.c:398 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "испорченный индекс BRIN: несогласованность в карте диапазонов" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "неожиданный тип страницы 0x%04X в BRIN-индексе \"%s\" (блок: %u)" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 +#: access/gist/gistvalidate.c:149 access/hash/hashvalidate.c:136 +#: access/nbtree/nbtvalidate.c:117 access/spgist/spgvalidate.c:168 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains function %s with invalid " +"support number %d" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит функцию %s с " +"неправильным опорным номером %d" + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 +#: access/gist/gistvalidate.c:161 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:129 access/spgist/spgvalidate.c:180 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains function %s with wrong " +"signature for support number %d" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит функцию %s с " +"неподходящим объявлением для опорного номера %d" + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 +#: access/gist/gistvalidate.c:181 access/hash/hashvalidate.c:157 +#: access/nbtree/nbtvalidate.c:149 access/spgist/spgvalidate.c:200 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains operator %s with invalid " +"strategy number %d" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит оператор %s с " +"неправильным номером стратегии %d" + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 +#: access/hash/hashvalidate.c:170 access/nbtree/nbtvalidate.c:162 +#: access/spgist/spgvalidate.c:216 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains invalid ORDER BY " +"specification for operator %s" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит некорректное " +"определение ORDER BY для оператора %s" + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 +#: access/gist/gistvalidate.c:229 access/hash/hashvalidate.c:183 +#: access/nbtree/nbtvalidate.c:175 access/spgist/spgvalidate.c:232 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains operator %s with wrong " +"signature" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит оператор %s с " +"неподходящим объявлением" + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:223 +#: access/nbtree/nbtvalidate.c:233 access/spgist/spgvalidate.c:259 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing operator(s) for types " +"%s and %s" +msgstr "" +"в семействе операторов \"%s\" метода доступа %s нет оператора(ов) для типов " +"%s и %s" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing support function(s) " +"for types %s and %s" +msgstr "" +"в семействе операторов \"%s\" метода доступа %s нет опорных функций для " +"типов %s и %s" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:237 +#: access/nbtree/nbtvalidate.c:257 access/spgist/spgvalidate.c:294 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "в классе операторов \"%s\" метода доступа %s нет оператора(ов)" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 +#: access/gist/gistvalidate.c:270 +#, c-format +msgid "" +"operator class \"%s\" of access method %s is missing support function %d" +msgstr "в классе операторов \"%s\" метода доступа %s нет опорной функции %d" + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "Возвращаемый тип %s не соответствует ожидаемому типу %s в столбце %d." + +#: access/common/attmap.c:150 +#, c-format +msgid "" +"Number of returned columns (%d) does not match expected column count (%d)." +msgstr "" +"Число возвращённых столбцов (%d) не соответствует ожидаемому числу (%d)." + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "не удалось преобразовать тип строки" + +#: access/common/attmap.c:230 +#, c-format +msgid "" +"Attribute \"%s\" of type %s does not match corresponding attribute of type " +"%s." +msgstr "" +"Атрибут \"%s\" типа %s несовместим с соответствующим атрибутом типа %s." + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "Атрибут \"%s\" типа %s не существует в типе %s." + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "число столбцов (%d) превышает предел (%d)" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "число столбцов индекса (%d) превышает предел (%d)" + +#: access/common/indextuple.c:187 access/spgist/spgutils.c:703 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "строка индекса требует байт: %zu, при максимуме: %zu" + +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1904 +#, c-format +msgid "unsupported format code: %d" +msgstr "неподдерживаемый код формата: %d" + +#: access/common/reloptions.c:506 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Допускаются только значения \"on\", \"off\" и \"auto\"." + +#: access/common/reloptions.c:517 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "Допускаются только значения \"local\" и \"cascaded\"." + +#: access/common/reloptions.c:665 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "превышен предел пользовательских типов реляционных параметров" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "В RESET не должно передаваться значение параметров" + +#: access/common/reloptions.c:1240 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "нераспознанное пространство имён параметров \"%s\"" + +#: access/common/reloptions.c:1277 utils/misc/guc.c:12032 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "таблицы со свойством WITH OIDS не поддерживаются" + +#: access/common/reloptions.c:1447 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "нераспознанный параметр \"%s\"" + +#: access/common/reloptions.c:1559 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "параметр \"%s\" указан неоднократно" + +#: access/common/reloptions.c:1575 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "неверное значение для логического параметра \"%s\": %s" + +#: access/common/reloptions.c:1587 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "неверное значение для целочисленного параметра \"%s\": %s" + +#: access/common/reloptions.c:1593 access/common/reloptions.c:1613 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "значение %s вне допустимых пределов параметра \"%s\"" + +#: access/common/reloptions.c:1595 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Допускаются значения только от \"%d\" до \"%d\"." + +#: access/common/reloptions.c:1607 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "неверное значение для численного параметра \"%s\": %s" + +#: access/common/reloptions.c:1615 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Допускаются значения только от \"%f\" до \"%f\"." + +#: access/common/reloptions.c:1637 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "неверное значение для параметра-перечисления \"%s\": %s" + +#: access/common/tupdesc.c:842 parser/parse_clause.c:772 +#: parser/parse_relation.c:1803 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "столбец \"%s\" не может быть объявлен как SETOF" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "слишком длинный список указателей" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "Уменьшите maintenance_work_mem." + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "Очередь записей GIN нельзя очистить в процессе восстановления." + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\" - это не индекс GIN" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "обращаться к временным индексам других сеансов нельзя" + +#: access/gin/ginget.c:270 access/nbtree/nbtinsert.c:745 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "не удалось повторно найти кортеж в индексе \"%s\"" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "" +"старые GIN-индексы не поддерживают сканирование всего индекса и поиск NULL" + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "Для исправления выполните REINDEX INDEX \"%s\"." + +#: access/gin/ginutil.c:144 executor/execExpr.c:1862 +#: utils/adt/arrayfuncs.c:3790 utils/adt/arrayfuncs.c:6418 +#: utils/adt/rowtypes.c:936 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "не удалось найти функцию сравнения для типа %s" + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains support function %s with " +"different left and right input types" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит опорную функцию %s с " +"межтиповой регистрацией" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "" +"operator class \"%s\" of access method %s is missing support function %d or " +"%d" +msgstr "" +"в классе операторов \"%s\" метода доступа %s нет опорной функции %d или %d" + +#: access/gist/gist.c:756 access/gist/gistvacuum.c:408 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "индекс \"%s\" содержит внутренний кортеж, отмеченный как ошибочный" + +#: access/gist/gist.c:758 access/gist/gistvacuum.c:410 +#, c-format +msgid "" +"This is caused by an incomplete page split at crash recovery before " +"upgrading to PostgreSQL 9.1." +msgstr "" +"Это вызвано неполным разделением страницы при восстановлении после сбоя в " +"PostgreSQL до версии 9.1." + +#: access/gist/gist.c:759 access/gist/gistutil.c:786 access/gist/gistutil.c:797 +#: access/gist/gistvacuum.c:411 access/hash/hashutil.c:227 +#: access/hash/hashutil.c:238 access/hash/hashutil.c:250 +#: access/hash/hashutil.c:271 access/nbtree/nbtpage.c:741 +#: access/nbtree/nbtpage.c:752 +#, c-format +msgid "Please REINDEX it." +msgstr "Пожалуйста, выполните REINDEX для него." + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "ошибка в методе picksplit для столбца %d индекса \"%s\"" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "" +"The index is not optimal. To optimize it, contact a developer, or try to use " +"the column as the second one in the CREATE INDEX command." +msgstr "" +"Данный индекс не оптимален. Чтобы оптимизировать его, свяжитесь с " +"разработчиками или попробуйте указать этот столбец в команде CREATE INDEX " +"вторым." + +#: access/gist/gistutil.c:783 access/hash/hashutil.c:224 +#: access/nbtree/nbtpage.c:738 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "в индексе \"%s\" неожиданно оказалась нулевая страница в блоке %u" + +#: access/gist/gistutil.c:794 access/hash/hashutil.c:235 +#: access/hash/hashutil.c:247 access/nbtree/nbtpage.c:749 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "индекс \"%s\" содержит испорченную страницу в блоке %u" + +#: access/gist/gistvalidate.c:199 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains unsupported ORDER BY " +"specification for operator %s" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит неподдерживаемое " +"определение ORDER BY для оператора %s" + +#: access/gist/gistvalidate.c:210 +#, c-format +msgid "" +"operator family \"%s\" of access method %s contains incorrect ORDER BY " +"opfamily specification for operator %s" +msgstr "" +"семейство операторов \"%s\" метода доступа %s содержит некорректное " +"определение ORDER BY для оператора %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "" +"не удалось определить, какое правило сортировки использовать для хеширования " +"строк" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:711 +#: catalog/heap.c:717 commands/createas.c:206 commands/createas.c:489 +#: commands/indexcmds.c:1816 commands/tablecmds.c:16057 commands/view.c:86 +#: parser/parse_utilcmd.c:4228 regex/regc_pg_locale.c:263 +#: utils/adt/formatting.c:1667 utils/adt/formatting.c:1791 +#: utils/adt/formatting.c:1916 utils/adt/like.c:194 +#: utils/adt/like_support.c:1003 utils/adt/varchar.c:733 +#: utils/adt/varchar.c:994 utils/adt/varchar.c:1054 utils/adt/varlena.c:1486 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Задайте правило сортировки явно в предложении COLLATE." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "размер строки индекса (%zu) больше предельного размера хеша (%zu)" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:764 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Значения, не умещающиеся в страницу буфера, нельзя проиндексировать." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "неверный номер блока переполнения: %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "в хеш-индексе \"%s\" не хватает страниц переполнения" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "хеш-индексы не поддерживают сканирование всего индекса" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "индекс \"%s\" не является хеш-индексом" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "индекс \"%s\" имеет неправильную версию хеша" + +#: access/hash/hashvalidate.c:195 +#, c-format +msgid "" +"operator family \"%s\" of access method %s lacks support function for " +"operator %s" +msgstr "" +"в семействе операторов \"%s\" метода доступа %s не хватает опорной функции " +"для оператора %s" + +#: access/hash/hashvalidate.c:253 access/nbtree/nbtvalidate.c:273 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "" +"в семействе операторов \"%s\" метода доступа %s нет межтипового оператора(ов)" + +#: access/heap/heapam.c:2036 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "вставлять кортежи в параллельном исполнителе нельзя" + +#: access/heap/heapam.c:2454 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "удалять кортежи во время параллельных операций нельзя" + +#: access/heap/heapam.c:2500 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "попытка удаления невидимого кортежа" + +#: access/heap/heapam.c:2926 access/heap/heapam.c:5715 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "изменять кортежи во время параллельных операций нельзя" + +#: access/heap/heapam.c:3059 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "попытка изменения невидимого кортежа" + +#: access/heap/heapam.c:4370 access/heap/heapam.c:4408 +#: access/heap/heapam.c:4665 access/heap/heapam_handler.c:450 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "не удалось получить блокировку строки в таблице \"%s\"" + +#: access/heap/heapam_handler.c:399 +#, c-format +msgid "" +"tuple to be locked was already moved to another partition due to concurrent " +"update" +msgstr "" +"кортеж, подлежащий блокировке, был перемещён в другую секцию в результате " +"параллельного изменения" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:662 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "размер строки (%zu) превышает предел (%zu)" + +#: access/heap/rewriteheap.c:921 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "не удалось записать в файл \"%s\" (записано байт: %d из %d): %m" + +#: access/heap/rewriteheap.c:1015 access/heap/rewriteheap.c:1134 +#: access/transam/timeline.c:329 access/transam/timeline.c:485 +#: access/transam/xlog.c:3300 access/transam/xlog.c:3472 +#: access/transam/xlog.c:4670 access/transam/xlog.c:10849 +#: access/transam/xlog.c:10887 access/transam/xlog.c:11292 +#: access/transam/xlogfuncs.c:735 postmaster/postmaster.c:4619 +#: replication/logical/origin.c:575 replication/slot.c:1446 +#: storage/file/copydir.c:167 storage/smgr/md.c:218 utils/time/snapmgr.c:1329 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "создать файл \"%s\" не удалось: %m" + +#: access/heap/rewriteheap.c:1144 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "не удалось обрезать файл \"%s\" до нужного размера (%u): %m" + +#: access/heap/rewriteheap.c:1162 access/transam/timeline.c:384 +#: access/transam/timeline.c:424 access/transam/timeline.c:502 +#: access/transam/xlog.c:3356 access/transam/xlog.c:3528 +#: access/transam/xlog.c:4682 postmaster/postmaster.c:4629 +#: postmaster/postmaster.c:4639 replication/logical/origin.c:587 +#: replication/logical/origin.c:629 replication/logical/origin.c:648 +#: replication/logical/snapbuild.c:1622 replication/slot.c:1481 +#: storage/file/buffile.c:502 storage/file/copydir.c:207 +#: utils/init/miscinit.c:1391 utils/init/miscinit.c:1402 +#: utils/init/miscinit.c:1410 utils/misc/guc.c:8024 utils/misc/guc.c:8055 +#: utils/misc/guc.c:9975 utils/misc/guc.c:9989 utils/time/snapmgr.c:1334 +#: utils/time/snapmgr.c:1341 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "записать в файл \"%s\" не удалось: %m" + +#: access/heap/rewriteheap.c:1252 access/transam/twophase.c:1609 +#: access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:421 +#: postmaster/postmaster.c:1092 postmaster/syslogger.c:1465 +#: replication/logical/origin.c:563 replication/logical/reorderbuffer.c:3079 +#: replication/logical/snapbuild.c:1564 replication/logical/snapbuild.c:2009 +#: replication/slot.c:1578 storage/file/fd.c:754 storage/file/fd.c:3116 +#: storage/file/fd.c:3178 storage/file/reinit.c:255 storage/ipc/dsm.c:302 +#: storage/smgr/md.c:355 storage/smgr/md.c:405 storage/sync/sync.c:210 +#: utils/time/snapmgr.c:1674 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "не удалось стереть файл \"%s\": %m" + +#: access/heap/vacuumlazy.c:648 +#, c-format +msgid "" +"automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": " +"index scans: %d\n" +msgstr "" +"автоматическая агрессивная очистка, предотвращающая зацикливание, таблицы " +"\"%s.%s.%s\": сканирований индекса: %d\n" + +#: access/heap/vacuumlazy.c:650 +#, c-format +msgid "" +"automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: " +"%d\n" +msgstr "" +"автоматическая очистка, предотвращающая зацикливание, таблицы \"%s.%s.%s\": " +"сканирований индекса: %d\n" + +#: access/heap/vacuumlazy.c:655 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "" +"автоматическая агрессивная очистка таблицы \"%s.%s.%s\": сканирований " +"индекса: %d\n" + +#: access/heap/vacuumlazy.c:657 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "" +"автоматическая очистка таблицы \"%s.%s.%s\": сканирований индекса: %d\n" + +#: access/heap/vacuumlazy.c:664 +#, c-format +msgid "" +"pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "" +"страниц удалено: %u, осталось: %u, пропущено закреплённых: %u, пропущено " +"замороженных: %u\n" + +#: access/heap/vacuumlazy.c:670 +#, c-format +msgid "" +"tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, " +"oldest xmin: %u\n" +msgstr "" +"версий строк: удалено: %.0f, осталось: %.0f, «мёртвых», но ещё не подлежащих " +"удалению: %.0f, старейший xmin: %u\n" + +#: access/heap/vacuumlazy.c:676 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "" +"использование буфера: попаданий: %lld, промахов: %lld, «грязных» записей: " +"%lld\n" + +#: access/heap/vacuumlazy.c:680 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "" +"средняя скорость чтения: %.3f МБ/с, средняя скорость записи: %.3f МБ/с\n" + +#: access/heap/vacuumlazy.c:682 +#, c-format +msgid "system usage: %s\n" +msgstr "нагрузка системы: %s\n" + +#: access/heap/vacuumlazy.c:684 +#, c-format +msgid "WAL usage: %ld records, %ld full page images, %llu bytes" +msgstr "" +"использование WAL: записей: %ld, полных образов страниц: %ld, байт: %llu" + +#: access/heap/vacuumlazy.c:795 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "агрессивная очистка \"%s.%s\"" + +#: access/heap/vacuumlazy.c:800 commands/cluster.c:874 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "очистка \"%s.%s\"" + +#: access/heap/vacuumlazy.c:837 +#, c-format +msgid "" +"disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary " +"tables in parallel" +msgstr "" +"отключение параллельного режима очистки \"%s\" --- создавать временные " +"таблицы в параллельном режиме нельзя" + +#: access/heap/vacuumlazy.c:1725 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%s\": удалено версий строк: %.0f, обработано страниц: %u" + +#: access/heap/vacuumlazy.c:1735 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "" +"В данный момент нельзя удалить \"мёртвых\" строк: %.0f, старейший xmin: %u\n" + +#: access/heap/vacuumlazy.c:1737 +#, c-format +msgid "There were %.0f unused item identifiers.\n" +msgstr "Найдено неиспользованных идентификаторов элементов: %.0f.\n" + +#: access/heap/vacuumlazy.c:1739 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Пропущено страниц, закреплённых в буфере: %u," +msgstr[1] "Пропущено страниц, закреплённых в буфере: %u," +msgstr[2] "Пропущено страниц, закреплённых в буфере: %u," + +#: access/heap/vacuumlazy.c:1743 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "замороженных страниц: %u.\n" +msgstr[1] "замороженных страниц: %u.\n" +msgstr[2] "замороженных страниц: %u.\n" + +#: access/heap/vacuumlazy.c:1747 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "Полностью пустых страниц: %u.\n" +msgstr[1] "Полностью пустых страниц: %u.\n" +msgstr[2] "Полностью пустых страниц: %u.\n" + +#: access/heap/vacuumlazy.c:1751 commands/indexcmds.c:3490 +#: commands/indexcmds.c:3508 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1754 +#, c-format +msgid "" +"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u " +"pages" +msgstr "" +"\"%s\": найдено удаляемых версий строк: %.0f, неудаляемых - %.0f, обработано " +"страниц: %u, всего страниц: %u" + +#: access/heap/vacuumlazy.c:1888 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%s\": удалено версий строк: %d, обработано страниц: %d" + +#: access/heap/vacuumlazy.c:2143 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "" +"launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "" +"запущен %d параллельный процесс очистки для уборки индекса (планировалось: " +"%d)" +msgstr[1] "" +"запущено %d параллельных процесса очистки для уборки индекса (планировалось: " +"%d)" +msgstr[2] "" +"запущено %d параллельных процессов очистки для уборки индекса " +"(планировалось: %d)" + +#: access/heap/vacuumlazy.c:2149 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "" +"launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "" +"запущен %d параллельный процесс очистки для очистки индекса (планировалось: " +"%d)" +msgstr[1] "" +"запущен %d параллельных процесса очистки для очистки индекса (планировалось: " +"%d)" +msgstr[2] "" +"запущено %d параллельных процессов очистки для очистки индекса " +"(планировалось: %d)" + +#: access/heap/vacuumlazy.c:2440 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "просканирован индекс \"%s\", удалено версий строк: %d" + +#: access/heap/vacuumlazy.c:2494 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "индекс \"%s\" теперь содержит версий строк: %.0f, в страницах: %u" + +#: access/heap/vacuumlazy.c:2498 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"Удалено версий строк индекса: %.0f.\n" +"Удалено индексных страниц: %u, пригодно для повторного использования: %u.\n" +"%s." + +#: access/heap/vacuumlazy.c:2601 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\": остановка усечения из-за конфликтующего запроса блокировки" + +#: access/heap/vacuumlazy.c:2667 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": усечение (было страниц: %u, стало: %u)" + +#: access/heap/vacuumlazy.c:2732 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\": приостановка усечения из-за конфликтующего запроса блокировки" + +#: access/heap/vacuumlazy.c:3581 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "при сканировании блока %u отношения \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3584 +#, c-format +msgid "while scanning relation \"%s.%s\"" +msgstr "при сканировании отношения \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3590 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "при очистке блока %u отношения \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3593 +#, c-format +msgid "while vacuuming relation \"%s.%s\"" +msgstr "при очистке отношения \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3598 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "при очистке индекса \"%s\" отношения \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3603 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "при уборке индекса \"%s\" отношения \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3609 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "при усечении отношения \"%s.%s\" до %u блок." + +#: access/index/amapi.c:83 commands/amcmds.c:170 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "метод доступа \"%s\" имеет не тип %s" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "для метода доступа индекса \"%s\" не задан обработчик" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1260 +#: commands/indexcmds.c:2518 commands/tablecmds.c:254 commands/tablecmds.c:278 +#: commands/tablecmds.c:15755 commands/tablecmds.c:17210 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\" - это не индекс" + +#: access/index/indexam.c:970 +#, c-format +msgid "operator class %s has no options" +msgstr "у класса операторов %s нет параметров" + +#: access/nbtree/nbtinsert.c:651 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "повторяющееся значение ключа нарушает ограничение уникальности \"%s\"" + +#: access/nbtree/nbtinsert.c:653 +#, c-format +msgid "Key %s already exists." +msgstr "Ключ \"%s\" уже существует." + +#: access/nbtree/nbtinsert.c:747 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Возможно, это вызвано переменной природой индексного выражения." + +#: access/nbtree/nbtpage.c:150 access/nbtree/nbtpage.c:538 +#: parser/parse_utilcmd.c:2268 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "индекс \"%s\" не является b-деревом" + +#: access/nbtree/nbtpage.c:157 access/nbtree/nbtpage.c:545 +#, c-format +msgid "" +"version mismatch in index \"%s\": file version %d, current version %d, " +"minimal supported version %d" +msgstr "" +"несовпадение версии в индексе \"%s\": версия файла: %d, версия кода: %d, " +"минимальная поддерживаемая версия: %d" + +#: access/nbtree/nbtpage.c:1501 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "индекс \"%s\" содержит полумёртвую внутреннюю страницу" + +#: access/nbtree/nbtpage.c:1503 +#, c-format +msgid "" +"This can be caused by an interrupted VACUUM in version 9.3 or older, before " +"upgrade. Please REINDEX it." +msgstr "" +"Причиной тому могло быть прерывание операции VACUUM в версии 9.3 или старее, " +"до обновления. Этот индекс нужно перестроить (REINDEX)." + +#: access/nbtree/nbtutils.c:2664 +#, c-format +msgid "" +"index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "" +"размер строки индекса (%zu) больше предельного для btree версии %u размера " +"(%zu) (индекс \"%s\")" + +#: access/nbtree/nbtutils.c:2670 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "Строка индекса ссылается на кортеж (%u,%u) в отношении \"%s\"." + +#: access/nbtree/nbtutils.c:2674 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text " +"indexing." +msgstr "" +"Значения, занимающие больше 1/3 страницы буфера, не могут быть " +"индексированы.\n" +"Возможно, вам стоит применить индекс функции с MD5-хешем значения или " +"полнотекстовую индексацию." + +#: access/nbtree/nbtvalidate.c:243 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing support function for " +"types %s and %s" +msgstr "" +"в семействе операторов \"%s\" метода доступа %s нет опорной функции для " +"типов %s и %s" + +#: access/spgist/spgutils.c:147 +#, c-format +msgid "" +"compress method must be defined when leaf type is different from input type" +msgstr "" +"метод сжатия должен быть определён, когда тип листьев отличается от входного " +"типа" + +#: access/spgist/spgutils.c:761 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "внутренний размер кортежа SP-GiST (%zu) превышает максимум (%zu)" + +#: access/spgist/spgvalidate.c:281 +#, c-format +msgid "" +"operator family \"%s\" of access method %s is missing support function %d " +"for type %s" +msgstr "" +"в семействе операторов \"%s\" метода доступа %s нет опорной функции %d для " +"типа %s" + +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 +#: catalog/aclchk.c:1809 +#, c-format +msgid "\"%s\" is an index" +msgstr "\"%s\" - это индекс" + +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 +#: catalog/aclchk.c:1816 commands/tablecmds.c:12572 commands/tablecmds.c:15764 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "\"%s\" - это составной тип" + +#: access/table/tableam.c:244 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "идентификатор кортежа (%u, %u) недопустим для отношения \"%s\"" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "Значение %s не может быть пустым." + +# well-spelled: симв +#: access/table/tableamapi.c:122 utils/misc/guc.c:11956 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "Длина %s превышает предел (%d симв.)." + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "табличный метод доступа \"%s\" не существует" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "Табличный метод доступа \"%s\" не существует." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "процент выборки должен задаваться числом от 0 до 100" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "не удалось получить метку времени фиксации транзакции %u" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "не удалось получить отметку времени фиксации" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "" +"Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "" +"Убедитесь, что в конфигурации главного сервера установлен параметр \"%s\"." + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "Убедитесь, что в конфигурации установлен параметр \"%s\"." + +#: access/transam/multixact.c:1002 +#, c-format +msgid "" +"database is not accepting commands that generate new MultiXactIds to avoid " +"wraparound data loss in database \"%s\"" +msgstr "" +"база данных не принимает команды, создающие новые MultiXactId, во избежание " +"потери данных из-за зацикливания в базе данных \"%s\"" + +#: access/transam/multixact.c:1004 access/transam/multixact.c:1011 +#: access/transam/multixact.c:1035 access/transam/multixact.c:1044 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"Выполните очистку (VACUUM) всей базы данных.\n" +"Возможно, вам также придётся зафиксировать или откатить старые " +"подготовленные транзакции и удалить неиспользуемые слоты репликации." + +#: access/transam/multixact.c:1009 +#, c-format +msgid "" +"database is not accepting commands that generate new MultiXactIds to avoid " +"wraparound data loss in database with OID %u" +msgstr "" +"база данных не принимает команды, создающие новые MultiXactId, во избежание " +"потери данных из-за зацикливания в базе данных с OID %u" + +#: access/transam/multixact.c:1030 access/transam/multixact.c:2322 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "" +"database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "" +"база данных \"%s\" должна быть очищена, прежде чем будут использованы " +"оставшиеся MultiXactId (%u)" +msgstr[1] "" +"база данных \"%s\" должна быть очищена, прежде чем будут использованы " +"оставшиеся MultiXactId (%u)" +msgstr[2] "" +"база данных \"%s\" должна быть очищена, прежде чем будут использованы " +"оставшиеся MultiXactId (%u)" + +#: access/transam/multixact.c:1039 access/transam/multixact.c:2331 +#, c-format +msgid "" +"database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "" +"database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "" +"база данных с OID %u должна быть очищена, прежде чем будут использованы " +"оставшиеся MultiXactId (%u)" +msgstr[1] "" +"база данных с OID %u должна быть очищена, прежде чем будут использованы " +"оставшиеся MultiXactId (%u)" +msgstr[2] "" +"база данных с OID %u должна быть очищена, прежде чем будут использованы " +"оставшиеся MultiXactId (%u)" + +#: access/transam/multixact.c:1100 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "слишком много членов мультитранзакции" + +#: access/transam/multixact.c:1101 +#, c-format +msgid "" +"This command would create a multixact with %u members, but the remaining " +"space is only enough for %u member." +msgid_plural "" +"This command would create a multixact with %u members, but the remaining " +"space is only enough for %u members." +msgstr[0] "" +"Мультитранзакция, создаваемая этой командой, должна включать членов: %u, но " +"оставшегося места хватает только для %u." +msgstr[1] "" +"Мультитранзакция, создаваемая этой командой, должна включать членов: %u, но " +"оставшегося места хватает только для %u." +msgstr[2] "" +"Мультитранзакция, создаваемая этой командой, должна включать членов: %u, но " +"оставшегося места хватает только для %u." + +#: access/transam/multixact.c:1106 +#, c-format +msgid "" +"Execute a database-wide VACUUM in database with OID %u with reduced " +"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " +"settings." +msgstr "" +"Выполните очистку (VACUUM) всей базы данных с OID %u, уменьшив значения " +"vacuum_multixact_freeze_min_age и vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1137 +#, c-format +msgid "" +"database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "" +"database with OID %u must be vacuumed before %d more multixact members are " +"used" +msgstr[0] "" +"база данных с OID %u должна быть очищена, пока не использованы оставшиеся " +"члены мультитранзакций (%d)" +msgstr[1] "" +"база данных с OID %u должна быть очищена, пока не использованы оставшиеся " +"члены мультитранзакций (%d)" +msgstr[2] "" +"база данных с OID %u должна быть очищена, пока не использованы оставшиеся " +"члены мультитранзакций (%d)" + +#: access/transam/multixact.c:1142 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database with reduced " +"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " +"settings." +msgstr "" +"Выполните очистку (VACUUM) всей этой базы данных, уменьшив значения " +"vacuum_multixact_freeze_min_age и vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1279 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "MultiXactId %u прекратил существование: видимо, произошло зацикливание" + +#: access/transam/multixact.c:1287 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "MultiXactId %u ещё не был создан: видимо, произошло зацикливание" + +#: access/transam/multixact.c:2272 +#, c-format +msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +msgstr "" +"предел зацикливания MultiXactId равен %u, источник ограничения - база данных " +"с OID %u" + +#: access/transam/multixact.c:2327 access/transam/multixact.c:2336 +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/varsup.c:447 access/transam/varsup.c:454 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that " +"database.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"Во избежание отключения базы данных выполните очистку (VACUUM) всей базы.\n" +"Возможно, вам также придётся зафиксировать или откатить старые " +"подготовленные транзакции и удалить неиспользуемые слоты репликации." + +#: access/transam/multixact.c:2606 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "смещение членов старейшей мультитранзакции: %u" + +#: access/transam/multixact.c:2610 +#, c-format +msgid "" +"MultiXact member wraparound protections are disabled because oldest " +"checkpointed MultiXact %u does not exist on disk" +msgstr "" +"Защита от зацикливания членов мультитранзакций отключена, так как старейшая " +"отмеченная мультитранзакция %u не найдена на диске" + +#: access/transam/multixact.c:2632 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "Защита от зацикливания мультитранзакций сейчас включена" + +#: access/transam/multixact.c:2635 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "" +"Граница членов мультитранзакции сейчас: %u (при старейшей мультитранзакции " +"%u)" + +#: access/transam/multixact.c:3023 +#, c-format +msgid "" +"oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "" +"старейшая мультитранзакция %u не найдена, новейшая мультитранзакция: %u, " +"усечение пропускается" + +#: access/transam/multixact.c:3041 +#, c-format +msgid "" +"cannot truncate up to MultiXact %u because it does not exist on disk, " +"skipping truncation" +msgstr "" +"выполнить усечение до мультитранзакции %u нельзя ввиду её отсутствия на " +"диске, усечение пропускается" + +#: access/transam/multixact.c:3355 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "неверный MultiXactId: %u" + +#: access/transam/parallel.c:706 access/transam/parallel.c:825 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "не удалось инициализировать параллельный исполнитель" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "More details may be available in the server log." +msgstr "Дополнительная информация может быть в журнале сервера." + +#: access/transam/parallel.c:887 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "postmaster завершился в процессе параллельной транзакции" + +#: access/transam/parallel.c:1074 +#, c-format +msgid "lost connection to parallel worker" +msgstr "потеряно подключение к параллельному исполнителю" + +#: access/transam/parallel.c:1140 access/transam/parallel.c:1142 +msgid "parallel worker" +msgstr "параллельный исполнитель" + +#: access/transam/parallel.c:1293 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "не удалось отобразить динамический сегмент разделяемой памяти" + +#: access/transam/parallel.c:1298 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "неверное магическое число в динамическом сегменте разделяемой памяти" + +#: access/transam/slru.c:696 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "файл \"%s\" не существует, считается нулевым" + +#: access/transam/slru.c:937 access/transam/slru.c:943 +#: access/transam/slru.c:951 access/transam/slru.c:956 +#: access/transam/slru.c:963 access/transam/slru.c:968 +#: access/transam/slru.c:975 access/transam/slru.c:982 +#, c-format +msgid "could not access status of transaction %u" +msgstr "не удалось получить состояние транзакции %u" + +#: access/transam/slru.c:938 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "Не удалось открыть файл \"%s\": %m." + +#: access/transam/slru.c:944 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "Не удалось переместиться в файле \"%s\" к смещению %u: %m." + +#: access/transam/slru.c:952 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "Не удалось прочитать файл \"%s\" (по смещению %u): %m." + +#: access/transam/slru.c:957 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "" +"Не удалось прочитать файл \"%s\" (по смещению %u): прочитаны не все байты." + +#: access/transam/slru.c:964 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "Не удалось записать в файл \"%s\" (по смещению %u): %m." + +#: access/transam/slru.c:969 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "" +"Не удалось записать в файл \"%s\" (по смещению %u): записаны не все байты." + +#: access/transam/slru.c:976 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "Не удалось синхронизировать с ФС файл \"%s\": %m." + +#: access/transam/slru.c:983 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "Не удалось закрыть файл \"%s\": %m." + +#: access/transam/slru.c:1251 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "не удалось очистить каталог \"%s\": видимо, произошло зацикливание" + +#: access/transam/slru.c:1309 access/transam/slru.c:1365 +#, c-format +msgid "removing file \"%s\"" +msgstr "удаляется файл \"%s\"" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "синтаксическая ошибка в файле истории: %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Ожидается числовой идентификатор линии времени." + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Ожидается положение точки переключения журнала предзаписи." + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "неверные данные в файле истории: %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Идентификаторы линий времени должны возрастать." + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "неверные данные в файле истории \"%s\"" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "" +"Идентификаторы линий времени должны быть меньше идентификатора линии-потомка." + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "в истории сервера нет запрошенной линии времени %u" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "идентификатор транзакции \"%s\" слишком длинный" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "подготовленные транзакции отключены" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "Установите ненулевое значение параметра max_prepared_transactions." + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "идентификатор транзакции \"%s\" уже используется" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2368 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "достигнут предел числа подготовленных транзакций" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2369 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "Увеличьте параметр max_prepared_transactions (текущее значение %d)." + +#: access/transam/twophase.c:586 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "подготовленная транзакция с идентификатором \"%s\" занята" + +#: access/transam/twophase.c:592 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "нет доступа для завершения подготовленной транзакции" + +#: access/transam/twophase.c:593 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "" +"Это разрешено только суперпользователю и пользователю, подготовившему " +"транзакцию." + +#: access/transam/twophase.c:604 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "подготовленная транзакция относится к другой базе данных" + +#: access/transam/twophase.c:605 +#, c-format +msgid "" +"Connect to the database where the transaction was prepared to finish it." +msgstr "" +"Чтобы завершить транзакцию, подключитесь к базе данных, где она была " +"подготовлена." + +# [SM]: TO REVIEW +#: access/transam/twophase.c:620 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "подготовленной транзакции с идентификатором \"%s\" нет" + +#: access/transam/twophase.c:1098 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "превышен предельный размер файла состояния 2PC" + +#: access/transam/twophase.c:1252 +#, c-format +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "некорректный размер файла \"%s\": %zu Б" +msgstr[1] "некорректный размер файла \"%s\": %zu Б" +msgstr[2] "некорректный размер файла \"%s\": %zu Б" + +#: access/transam/twophase.c:1261 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "некорректное выравнивание смещения CRC для файла \"%s\"" + +#: access/transam/twophase.c:1294 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "в файле \"%s\" содержится неверная сигнатура" + +#: access/transam/twophase.c:1300 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "в файле \"%s\" содержится неверный размер" + +#: access/transam/twophase.c:1312 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "" +"вычисленная контрольная сумма (CRC) не соответствует значению, сохранённому " +"в файле \"%s\"" + +#: access/transam/twophase.c:1342 access/transam/xlog.c:6488 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "Не удалось разместить обработчик журнала транзакций." + +#: access/transam/twophase.c:1349 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "не удалось прочитать состояние 2PC из WAL в позиции %X/%X" + +#: access/transam/twophase.c:1357 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "" +"ожидаемые данные состояния двухфазной фиксации отсутствуют в WAL в позиции " +"%X/%X" + +#: access/transam/twophase.c:1637 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "пересоздать файл \"%s\" не удалось: %m" + +#: access/transam/twophase.c:1764 +#, c-format +msgid "" +"%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "" +"%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "" +"для длительной подготовленной транзакции записано файлов состояния 2PC: %u" +msgstr[1] "" +"для длительных подготовленных транзакций записано файлов состояния 2PC: %u" +msgstr[2] "" +"для длительных подготовленных транзакций записано файлов состояния 2PC: %u" + +#: access/transam/twophase.c:1998 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "восстановление подготовленной транзакции %u из разделяемой памяти" + +#: access/transam/twophase.c:2089 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "удаление устаревшего файла состояния 2PC для транзакции %u" + +#: access/transam/twophase.c:2096 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "удаление из памяти устаревшего состояния 2PC для транзакции %u" + +#: access/transam/twophase.c:2109 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "удаление файла будущего состояния 2PC для транзакции %u" + +#: access/transam/twophase.c:2116 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "удаление из памяти будущего состояния 2PC для транзакции %u" + +#: access/transam/twophase.c:2141 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "испорчен файл состояния 2PC для транзакции %u" + +#: access/transam/twophase.c:2146 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "испорчено состояние 2PC в памяти для транзакции %u" + +#: access/transam/varsup.c:127 +#, c-format +msgid "" +"database is not accepting commands to avoid wraparound data loss in database " +"\"%s\"" +msgstr "" +"база данных не принимает команды во избежание потери данных из-за " +"зацикливания транзакций в базе данных \"%s\"" + +#: access/transam/varsup.c:129 access/transam/varsup.c:136 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"Остановите управляющий процесс (postmaster) и выполните очистку (VACUUM) " +"базы данных в монопольном режиме.\n" +"Возможно, вам также придётся зафиксировать или откатить старые " +"подготовленные транзакции и удалить неиспользуемые слоты репликации." + +#: access/transam/varsup.c:134 +#, c-format +msgid "" +"database is not accepting commands to avoid wraparound data loss in database " +"with OID %u" +msgstr "" +"база данных не принимает команды во избежание потери данных из-за " +"зацикливания транзакций в базе данных с OID %u" + +#: access/transam/varsup.c:146 access/transam/varsup.c:444 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "" +"база данных \"%s\" должна быть очищена (предельное число транзакций: %u)" + +#: access/transam/varsup.c:153 access/transam/varsup.c:451 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "" +"база данных с OID %u должна быть очищена (предельное число транзакций: %u)" + +#: access/transam/varsup.c:409 +#, c-format +msgid "transaction ID wrap limit is %u, limited by database with OID %u" +msgstr "" +"предел зацикливания ID транзакций равен %u, источник ограничения - база " +"данных с OID %u" + +#: access/transam/xact.c:1030 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "в одной транзакции не может быть больше 2^32-2 команд" + +#: access/transam/xact.c:1555 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "превышен предел числа зафиксированных подтранзакций (%d)" + +#: access/transam/xact.c:2396 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "" +"нельзя выполнить PREPARE для транзакции, оперирующей с временными объектами" + +#: access/transam/xact.c:2406 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "нельзя выполнить PREPARE для транзакции, снимки которой экспортированы" + +#: access/transam/xact.c:2415 +#, c-format +msgid "" +"cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "" +"нельзя выполнить PREPARE для транзакции, задействующей процессы логической " +"репликации" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3360 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s не может выполняться внутри блока транзакции" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3370 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s не может выполняться внутри подтранзакции" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3380 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s нельзя выполнять внутри функции" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3449 access/transam/xact.c:3755 +#: access/transam/xact.c:3834 access/transam/xact.c:3957 +#: access/transam/xact.c:4108 access/transam/xact.c:4177 +#: access/transam/xact.c:4288 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s может выполняться только внутри блоков транзакций" + +#: access/transam/xact.c:3641 +#, c-format +msgid "there is already a transaction in progress" +msgstr "транзакция уже выполняется" + +#: access/transam/xact.c:3760 access/transam/xact.c:3839 +#: access/transam/xact.c:3962 +#, c-format +msgid "there is no transaction in progress" +msgstr "нет незавершённой транзакции" + +#: access/transam/xact.c:3850 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "фиксировать транзакции во время параллельных операций нельзя" + +#: access/transam/xact.c:3973 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "прерывание во время параллельных операций невозможно" + +#: access/transam/xact.c:4072 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "определять точки сохранения во время параллельных операций нельзя" + +#: access/transam/xact.c:4159 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "высвобождать точки сохранения во время параллельных операций нельзя" + +#: access/transam/xact.c:4169 access/transam/xact.c:4220 +#: access/transam/xact.c:4280 access/transam/xact.c:4329 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "точка сохранения \"%s\" не существует" + +#: access/transam/xact.c:4226 access/transam/xact.c:4335 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "" +"точка сохранения \"%s\" на текущем уровне точек сохранения не существует" + +#: access/transam/xact.c:4268 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "откатиться к точке сохранения во время параллельных операций нельзя" + +#: access/transam/xact.c:4396 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "запускать подтранзакции во время параллельных операций нельзя" + +#: access/transam/xact.c:4464 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "фиксировать подтранзакции во время параллельных операций нельзя" + +#: access/transam/xact.c:5104 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "в одной транзакции не может быть больше 2^32-1 подтранзакций" + +#: access/transam/xlog.c:2554 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "не удалось записать в файл журнала %s (смещение: %u, длина: %zu): %m" + +#: access/transam/xlog.c:2830 +#, c-format +msgid "updated min recovery point to %X/%X on timeline %u" +msgstr "минимальная точка восстановления изменена на %X/%X на линии времени %u" + +#: access/transam/xlog.c:3944 access/transam/xlogutils.c:802 +#: replication/walsender.c:2503 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "запрошенный сегмент WAL %s уже удалён" + +#: access/transam/xlog.c:4187 +#, c-format +msgid "recycled write-ahead log file \"%s\"" +msgstr "файл журнала предзаписи \"%s\" используется повторно" + +#: access/transam/xlog.c:4199 +#, c-format +msgid "removing write-ahead log file \"%s\"" +msgstr "файл журнала предзаписи \"%s\" удаляется" + +#: access/transam/xlog.c:4219 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "не удалось переименовать файл \"%s\": %m" + +#: access/transam/xlog.c:4261 access/transam/xlog.c:4271 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "требуемый каталог WAL \"%s\" не существует" + +#: access/transam/xlog.c:4277 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "создаётся отсутствующий каталог WAL \"%s\"" + +#: access/transam/xlog.c:4280 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "не удалось создать отсутствующий каталог \"%s\": %m" + +#: access/transam/xlog.c:4383 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "неожиданный ID линии времени %u в сегменте журнала %s, смещение %u" + +#: access/transam/xlog.c:4521 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "" +"новая линия времени %u не является ответвлением линии времени системы БД %u" + +#: access/transam/xlog.c:4535 +#, c-format +msgid "" +"new timeline %u forked off current database system timeline %u before " +"current recovery point %X/%X" +msgstr "" +"новая линия времени %u ответвилась от текущей линии времени базы данных %u " +"до текущей точки восстановления %X/%X" + +#: access/transam/xlog.c:4554 +#, c-format +msgid "new target timeline is %u" +msgstr "новая целевая линия времени %u" + +#: access/transam/xlog.c:4590 +#, c-format +msgid "could not generate secret authorization token" +msgstr "не удалось сгенерировать случайное число для аутентификации" + +#: access/transam/xlog.c:4749 access/transam/xlog.c:4758 +#: access/transam/xlog.c:4782 access/transam/xlog.c:4789 +#: access/transam/xlog.c:4796 access/transam/xlog.c:4801 +#: access/transam/xlog.c:4808 access/transam/xlog.c:4815 +#: access/transam/xlog.c:4822 access/transam/xlog.c:4829 +#: access/transam/xlog.c:4836 access/transam/xlog.c:4843 +#: access/transam/xlog.c:4852 access/transam/xlog.c:4859 +#: utils/init/miscinit.c:1548 +#, c-format +msgid "database files are incompatible with server" +msgstr "файлы базы данных не совместимы с сервером" + +#: access/transam/xlog.c:4750 +#, c-format +msgid "" +"The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), " +"but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "" +"Кластер баз данных был инициализирован с PG_CONTROL_VERSION %d (0x%08x), но " +"сервер скомпилирован с PG_CONTROL_VERSION %d (0x%08x)." + +#: access/transam/xlog.c:4754 +#, c-format +msgid "" +"This could be a problem of mismatched byte ordering. It looks like you need " +"to initdb." +msgstr "" +"Возможно, проблема вызвана разным порядком байт. Кажется, вам надо выполнить " +"initdb." + +#: access/transam/xlog.c:4759 +#, c-format +msgid "" +"The database cluster was initialized with PG_CONTROL_VERSION %d, but the " +"server was compiled with PG_CONTROL_VERSION %d." +msgstr "" +"Кластер баз данных был инициализирован с PG_CONTROL_VERSION %d, но сервер " +"скомпилирован с PG_CONTROL_VERSION %d." + +#: access/transam/xlog.c:4762 access/transam/xlog.c:4786 +#: access/transam/xlog.c:4793 access/transam/xlog.c:4798 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Кажется, вам надо выполнить initdb." + +#: access/transam/xlog.c:4773 +#, c-format +msgid "incorrect checksum in control file" +msgstr "ошибка контрольной суммы в файле pg_control" + +#: access/transam/xlog.c:4783 +#, c-format +msgid "" +"The database cluster was initialized with CATALOG_VERSION_NO %d, but the " +"server was compiled with CATALOG_VERSION_NO %d." +msgstr "" +"Кластер баз данных был инициализирован с CATALOG_VERSION_NO %d, но сервер " +"скомпилирован с CATALOG_VERSION_NO %d." + +#: access/transam/xlog.c:4790 +#, c-format +msgid "" +"The database cluster was initialized with MAXALIGN %d, but the server was " +"compiled with MAXALIGN %d." +msgstr "" +"Кластер баз данных был инициализирован с MAXALIGN %d, но сервер " +"скомпилирован с MAXALIGN %d." + +#: access/transam/xlog.c:4797 +#, c-format +msgid "" +"The database cluster appears to use a different floating-point number format " +"than the server executable." +msgstr "" +"Кажется, в кластере баз данных и в программе сервера используются разные " +"форматы чисел с плавающей точкой." + +#: access/transam/xlog.c:4802 +#, c-format +msgid "" +"The database cluster was initialized with BLCKSZ %d, but the server was " +"compiled with BLCKSZ %d." +msgstr "" +"Кластер баз данных был инициализирован с BLCKSZ %d, но сервер скомпилирован " +"с BLCKSZ %d." + +#: access/transam/xlog.c:4805 access/transam/xlog.c:4812 +#: access/transam/xlog.c:4819 access/transam/xlog.c:4826 +#: access/transam/xlog.c:4833 access/transam/xlog.c:4840 +#: access/transam/xlog.c:4847 access/transam/xlog.c:4855 +#: access/transam/xlog.c:4862 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Кажется, вам надо перекомпилировать сервер или выполнить initdb." + +#: access/transam/xlog.c:4809 +#, c-format +msgid "" +"The database cluster was initialized with RELSEG_SIZE %d, but the server was " +"compiled with RELSEG_SIZE %d." +msgstr "" +"Кластер баз данных был инициализирован с RELSEG_SIZE %d, но сервер " +"скомпилирован с RELSEG_SIZE %d." + +#: access/transam/xlog.c:4816 +#, c-format +msgid "" +"The database cluster was initialized with XLOG_BLCKSZ %d, but the server was " +"compiled with XLOG_BLCKSZ %d." +msgstr "" +"Кластер баз данных был инициализирован с XLOG_BLCKSZ %d, но сервер " +"скомпилирован с XLOG_BLCKSZ %d." + +#: access/transam/xlog.c:4823 +#, c-format +msgid "" +"The database cluster was initialized with NAMEDATALEN %d, but the server was " +"compiled with NAMEDATALEN %d." +msgstr "" +"Кластер баз данных был инициализирован с NAMEDATALEN %d, но сервер " +"скомпилирован с NAMEDATALEN %d." + +#: access/transam/xlog.c:4830 +#, c-format +msgid "" +"The database cluster was initialized with INDEX_MAX_KEYS %d, but the server " +"was compiled with INDEX_MAX_KEYS %d." +msgstr "" +"Кластер баз данных был инициализирован с INDEX_MAX_KEYS %d, но сервер " +"скомпилирован с INDEX_MAX_KEYS %d." + +#: access/transam/xlog.c:4837 +#, c-format +msgid "" +"The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the " +"server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "" +"Кластер баз данных был инициализирован с TOAST_MAX_CHUNK_SIZE %d, но сервер " +"скомпилирован с TOAST_MAX_CHUNK_SIZE %d." + +#: access/transam/xlog.c:4844 +#, c-format +msgid "" +"The database cluster was initialized with LOBLKSIZE %d, but the server was " +"compiled with LOBLKSIZE %d." +msgstr "" +"Кластер баз данных был инициализирован с LOBLKSIZE %d, но сервер " +"скомпилирован с LOBLKSIZE %d." + +#: access/transam/xlog.c:4853 +#, c-format +msgid "" +"The database cluster was initialized without USE_FLOAT8_BYVAL but the server " +"was compiled with USE_FLOAT8_BYVAL." +msgstr "" +"Кластер баз данных был инициализирован без USE_FLOAT8_BYVAL, но сервер " +"скомпилирован с USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4860 +#, c-format +msgid "" +"The database cluster was initialized with USE_FLOAT8_BYVAL but the server " +"was compiled without USE_FLOAT8_BYVAL." +msgstr "" +"Кластер баз данных был инициализирован с USE_FLOAT8_BYVAL, но сервер был " +"скомпилирован без USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4869 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d bytes" +msgstr[0] "" +"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управляющем файле указано значение: %d" +msgstr[1] "" +"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управляющем файле указано значение: %d" +msgstr[2] "" +"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управляющем файле указано значение: %d" + +#: access/transam/xlog.c:4881 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" должен быть минимум вдвое больше \"wal_segment_size\"" + +#: access/transam/xlog.c:4885 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" должен быть минимум вдвое больше \"wal_segment_size\"" + +#: access/transam/xlog.c:5318 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "не удалось записать начальный файл журнала предзаписи: %m" + +#: access/transam/xlog.c:5326 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "не удалось сбросить на диск начальный файл журнала предзаписи: %m" + +#: access/transam/xlog.c:5332 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "не удалось закрыть начальный файл журнала предзаписи: %m" + +#: access/transam/xlog.c:5393 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "" +"использование файла с конфигурацией восстановления \"%s\" не поддерживается" + +#: access/transam/xlog.c:5458 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "" +"режим резервного сервера не поддерживается однопользовательским сервером" + +#: access/transam/xlog.c:5475 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "не указано ни primary_conninfo, ни restore_command" + +#: access/transam/xlog.c:5476 +#, c-format +msgid "" +"The database server will regularly poll the pg_wal subdirectory to check for " +"files placed there." +msgstr "" +"Сервер БД будет регулярно опрашивать подкаталог pg_wal и проверять " +"содержащиеся в нём файлы." + +#: access/transam/xlog.c:5484 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "" +"необходимо задать restore_command, если не выбран режим резервного сервера" + +#: access/transam/xlog.c:5522 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "целевая линия времени для восстановления %u не существует" + +#: access/transam/xlog.c:5644 +#, c-format +msgid "archive recovery complete" +msgstr "восстановление архива завершено" + +#: access/transam/xlog.c:5710 access/transam/xlog.c:5983 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "" +"восстановление останавливается после достижения согласованного состояния" + +#: access/transam/xlog.c:5731 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "восстановление останавливается перед позицией в WAL (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5817 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "" +"восстановление останавливается перед фиксированием транзакции %u, время %s" + +#: access/transam/xlog.c:5824 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "" +"восстановление останавливается перед прерыванием транзакции %u, время %s" + +#: access/transam/xlog.c:5877 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "восстановление останавливается в точке восстановления \"%s\", время %s" + +#: access/transam/xlog.c:5895 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "восстановление останавливается после позиции в WAL (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5963 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "" +"восстановление останавливается после фиксирования транзакции %u, время %s" + +#: access/transam/xlog.c:5971 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "" +"восстановление останавливается после прерывания транзакции %u, время %s" + +#: access/transam/xlog.c:6020 +#, c-format +msgid "pausing at the end of recovery" +msgstr "остановка в конце восстановления" + +#: access/transam/xlog.c:6021 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "Выполните pg_wal_replay_resume() для повышения." + +#: access/transam/xlog.c:6024 +#, c-format +msgid "recovery has paused" +msgstr "восстановление приостановлено" + +#: access/transam/xlog.c:6025 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Выполните pg_wal_replay_resume() для продолжения." + +#: access/transam/xlog.c:6236 +#, c-format +msgid "" +"hot standby is not possible because %s = %d is a lower setting than on the " +"master server (its value was %d)" +msgstr "" +"режим горячего резерва невозможен, так как параметр %s = %d, меньше чем на " +"главном сервере (на нём было значение %d)" + +#: access/transam/xlog.c:6260 +#, c-format +msgid "WAL was generated with wal_level=minimal, data may be missing" +msgstr "WAL был создан с параметром wal_level=minimal, возможна потеря данных" + +#: access/transam/xlog.c:6261 +#, c-format +msgid "" +"This happens if you temporarily set wal_level=minimal without taking a new " +"base backup." +msgstr "" +"Это происходит, если вы на время установили wal_level=minimal и не сделали " +"резервную копию базу данных." + +#: access/transam/xlog.c:6272 +#, c-format +msgid "" +"hot standby is not possible because wal_level was not set to \"replica\" or " +"higher on the master server" +msgstr "" +"режим горячего резерва невозможен, так как на главном сервере установлен " +"неподходящий wal_level (должен быть \"replica\" или выше)" + +#: access/transam/xlog.c:6273 +#, c-format +msgid "" +"Either set wal_level to \"replica\" on the master, or turn off hot_standby " +"here." +msgstr "" +"Либо установите для wal_level значение \"replica\" на главном сервере, либо " +"выключите hot_standby здесь." + +#: access/transam/xlog.c:6335 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "файл pg_control содержит неправильную позицию контрольной точки" + +#: access/transam/xlog.c:6346 +#, c-format +msgid "database system was shut down at %s" +msgstr "система БД была выключена: %s" + +#: access/transam/xlog.c:6352 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "система БД была выключена в процессе восстановления: %s" + +#: access/transam/xlog.c:6358 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "выключение системы БД было прервано; последний момент работы: %s" + +#: access/transam/xlog.c:6364 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "работа системы БД была прервана во время восстановления: %s" + +#: access/transam/xlog.c:6366 +#, c-format +msgid "" +"This probably means that some data is corrupted and you will have to use the " +"last backup for recovery." +msgstr "" +"Это скорее всего означает, что некоторые данные повреждены и вам придётся " +"восстановить БД из последней резервной копии." + +#: access/transam/xlog.c:6372 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "" +"работа системы БД была прервана в процессе восстановления, время в журнале: " +"%s" + +#: access/transam/xlog.c:6374 +#, c-format +msgid "" +"If this has occurred more than once some data might be corrupted and you " +"might need to choose an earlier recovery target." +msgstr "" +"Если это происходит постоянно, возможно, какие-то данные были испорчены и " +"для восстановления стоит выбрать более раннюю точку." + +#: access/transam/xlog.c:6380 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "работа системы БД была прервана; последний момент работы: %s" + +#: access/transam/xlog.c:6386 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "файл pg_control содержит неверный код состояния кластера" + +#: access/transam/xlog.c:6443 +#, c-format +msgid "entering standby mode" +msgstr "переход в режим резервного сервера" + +#: access/transam/xlog.c:6446 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "начинается восстановление точки во времени до XID %u" + +#: access/transam/xlog.c:6450 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "начинается восстановление точки во времени до %s" + +#: access/transam/xlog.c:6454 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "начинается восстановление точки во времени до \"%s\"" + +#: access/transam/xlog.c:6458 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "" +"начинается восстановление точки во времени до позиции в WAL (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:6463 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "" +"начинается восстановление точки во времени до первой точки согласованности" + +#: access/transam/xlog.c:6466 +#, c-format +msgid "starting archive recovery" +msgstr "начинается восстановление архива" + +#: access/transam/xlog.c:6525 access/transam/xlog.c:6658 +#, c-format +msgid "checkpoint record is at %X/%X" +msgstr "запись о контрольной точке по смещению %X/%X" + +#: access/transam/xlog.c:6540 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "не удалось найти положение REDO, указанное записью контрольной точки" + +#: access/transam/xlog.c:6541 access/transam/xlog.c:6551 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add " +"required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/" +"backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if " +"restoring from a backup." +msgstr "" +"Если вы восстанавливаете резервную копию, создайте \"%s/recovery.signal\" и " +"задайте обязательные параметры восстановления.\n" +"В других случаях попытайтесь удалить файл \"%s/backup_label\".\n" +"Будьте осторожны: при восстановлении резервной копии удаление \"%s/" +"backup_label\" приведёт к повреждению кластера." + +#: access/transam/xlog.c:6550 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "не удалось считать нужную запись контрольной точки" + +#: access/transam/xlog.c:6579 commands/tablespace.c:666 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "не удалось создать символическую ссылку \"%s\": %m" + +#: access/transam/xlog.c:6611 access/transam/xlog.c:6617 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "файл \"%s\" игнорируется ввиду отсутствия файла \"%s\"" + +#: access/transam/xlog.c:6613 access/transam/xlog.c:11808 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "Файл \"%s\" был переименован в \"%s\"." + +#: access/transam/xlog.c:6619 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "Не удалось переименовать файл \"%s\" в \"%s\" (%m)." + +#: access/transam/xlog.c:6670 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "не удалось считать правильную запись контрольной точки" + +#: access/transam/xlog.c:6708 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "в истории сервера нет ответвления запрошенной линии времени %u" + +#: access/transam/xlog.c:6710 +#, c-format +msgid "" +"Latest checkpoint is at %X/%X on timeline %u, but in the history of the " +"requested timeline, the server forked off from that timeline at %X/%X." +msgstr "" +"Последняя контрольная точка: %X/%X на линии времени %u, но в истории " +"запрошенной линии времени сервер ответвился с этой линии в %X/%X." + +#: access/transam/xlog.c:6726 +#, c-format +msgid "" +"requested timeline %u does not contain minimum recovery point %X/%X on " +"timeline %u" +msgstr "" +"запрошенная линия времени %u не содержит минимальную точку восстановления %X/" +"%X на линии времени %u" + +#: access/transam/xlog.c:6757 +#, c-format +msgid "invalid next transaction ID" +msgstr "неверный ID следующей транзакции" + +#: access/transam/xlog.c:6851 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "неверная запись REDO в контрольной точке" + +#: access/transam/xlog.c:6862 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "неверная запись REDO в контрольной точке выключения" + +#: access/transam/xlog.c:6896 +#, c-format +msgid "" +"database system was not properly shut down; automatic recovery in progress" +msgstr "" +"система БД была остановлена нештатно; производится автоматическое " +"восстановление" + +#: access/transam/xlog.c:6900 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "" +"восстановление после сбоя начинается на линии времени %u, целевая линия " +"времени: %u" + +#: access/transam/xlog.c:6947 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label содержит данные, не согласованные с файлом pg_control" + +#: access/transam/xlog.c:6948 +#, c-format +msgid "" +"This means that the backup is corrupted and you will have to use another " +"backup for recovery." +msgstr "" +"Это означает, что резервная копия повреждена и для восстановления БД " +"придётся использовать другую копию." + +#: access/transam/xlog.c:7039 +#, c-format +msgid "initializing for hot standby" +msgstr "инициализация для горячего резерва" + +#: access/transam/xlog.c:7172 +#, c-format +msgid "redo starts at %X/%X" +msgstr "запись REDO начинается со смещения %X/%X" + +#: access/transam/xlog.c:7396 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "" +"запрошенная точка остановки восстановления предшествует согласованной точке " +"восстановления" + +#: access/transam/xlog.c:7434 +#, c-format +msgid "redo done at %X/%X" +msgstr "записи REDO обработаны до смещения %X/%X" + +#: access/transam/xlog.c:7439 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "последняя завершённая транзакция была выполнена в %s" + +#: access/transam/xlog.c:7448 +#, c-format +msgid "redo is not required" +msgstr "данные REDO не требуются" + +#: access/transam/xlog.c:7460 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "восстановление окончилось до достижения заданной цели восстановления" + +#: access/transam/xlog.c:7539 access/transam/xlog.c:7543 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "WAL закончился без признака окончания копирования" + +#: access/transam/xlog.c:7540 +#, c-format +msgid "" +"All WAL generated while online backup was taken must be available at " +"recovery." +msgstr "" +"Все журналы WAL, созданные во время резервного копирования \"на ходу\", " +"должны быть в наличии для восстановления." + +#: access/transam/xlog.c:7544 +#, c-format +msgid "" +"Online backup started with pg_start_backup() must be ended with " +"pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "" +"Резервное копирование БД \"на ходу\", начатое командой pg_start_backup(), " +"должно закончиться pg_stop_backup(), и для восстановления должны быть " +"доступны все журналы WAL." + +#: access/transam/xlog.c:7547 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL закончился до согласованной точки восстановления" + +#: access/transam/xlog.c:7582 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "выбранный ID новой линии времени: %u" + +#: access/transam/xlog.c:8030 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "согласованное состояние восстановления достигнуто по смещению %X/%X" + +#: access/transam/xlog.c:8240 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "неверная ссылка на первичную контрольную точку в файле pg_control" + +#: access/transam/xlog.c:8244 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "неверная ссылка на контрольную точку в файле backup_label" + +#: access/transam/xlog.c:8262 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "неверная запись первичной контрольной точки" + +#: access/transam/xlog.c:8266 +#, c-format +msgid "invalid checkpoint record" +msgstr "неверная запись контрольной точки" + +#: access/transam/xlog.c:8277 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "неверный ID менеджера ресурсов в записи первичной контрольной точки" + +#: access/transam/xlog.c:8281 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "неверный ID менеджера ресурсов в записи контрольной точки" + +#: access/transam/xlog.c:8294 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "неверные флаги xl_info в записи первичной контрольной точки" + +#: access/transam/xlog.c:8298 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "неверные флаги xl_info в записи контрольной точки" + +#: access/transam/xlog.c:8309 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "неверная длина записи первичной контрольной точки" + +#: access/transam/xlog.c:8313 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "неверная длина записи контрольной точки" + +#: access/transam/xlog.c:8493 +#, c-format +msgid "shutting down" +msgstr "выключение" + +#: access/transam/xlog.c:8799 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "контрольная точка пропущена ввиду простоя системы" + +#: access/transam/xlog.c:8999 +#, c-format +msgid "" +"concurrent write-ahead log activity while database system is shutting down" +msgstr "" +"во время выключения системы баз данных отмечена активность в журнале " +"предзаписи" + +#: access/transam/xlog.c:9256 +#, c-format +msgid "skipping restartpoint, recovery has already ended" +msgstr "" +"создание точки перезапуска пропускается, восстановление уже закончилось" + +#: access/transam/xlog.c:9279 +#, c-format +msgid "skipping restartpoint, already performed at %X/%X" +msgstr "" +"создание точки перезапуска пропускается, она уже создана по смещению %X/%X" + +#: access/transam/xlog.c:9447 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "точка перезапуска восстановления по смещению %X/%X" + +#: access/transam/xlog.c:9449 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Последняя завершённая транзакция была выполнена в %s." + +#: access/transam/xlog.c:9691 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "точка восстановления \"%s\" создана по смещению %X/%X" + +#: access/transam/xlog.c:9836 +#, c-format +msgid "" +"unexpected previous timeline ID %u (current timeline ID %u) in checkpoint " +"record" +msgstr "" +"неожиданный ID предыдущей линии времени %u (ID текущей линии времени %u) в " +"записи контрольной точки" + +#: access/transam/xlog.c:9845 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "неожиданный ID линии времени %u (после %u) в записи контрольной точки" + +# skip-rule: capital-letter-first +#: access/transam/xlog.c:9861 +#, c-format +msgid "" +"unexpected timeline ID %u in checkpoint record, before reaching minimum " +"recovery point %X/%X on timeline %u" +msgstr "" +"неожиданный ID линии времени %u в записи контрольной точки, до достижения " +"минимальной к. т. %X/%X на линии времени %u" + +#: access/transam/xlog.c:9937 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "" +"резервное копирование \"на ходу\" было отменено, продолжить восстановление " +"нельзя" + +#: access/transam/xlog.c:9993 access/transam/xlog.c:10049 +#: access/transam/xlog.c:10072 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "" +"неожиданный ID линии времени %u (должен быть %u) в записи точки " +"восстановления" + +#: access/transam/xlog.c:10398 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "не удалось синхронизировать с ФС файл сквозной записи %s: %m" + +#: access/transam/xlog.c:10404 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "не удалось синхронизировать с ФС данные (fdatasync) файла \"%s\": %m" + +#: access/transam/xlog.c:10503 access/transam/xlog.c:11041 +#: access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 +#: access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 +#: access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "Функции управления WAL нельзя использовать в процессе восстановления." + +#: access/transam/xlog.c:10512 access/transam/xlog.c:11050 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "" +"Выбранный уровень WAL недостаточен для резервного копирования \"на ходу\"" + +#: access/transam/xlog.c:10513 access/transam/xlog.c:11051 +#: access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "Установите wal_level \"replica\" или \"logical\" при запуске сервера." + +#: access/transam/xlog.c:10518 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "длина метки резервной копии превышает предел (%d байт)" + +#: access/transam/xlog.c:10555 access/transam/xlog.c:10840 +#: access/transam/xlog.c:10878 +#, c-format +msgid "a backup is already in progress" +msgstr "резервное копирование уже выполняется" + +#: access/transam/xlog.c:10556 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "Выполните pg_stop_backup() и повторите операцию." + +#: access/transam/xlog.c:10652 +#, c-format +msgid "" +"WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "" +"После последней точки перезапуска был воспроизведён WAL, созданный в режиме " +"full_page_writes=off." + +#: access/transam/xlog.c:10654 access/transam/xlog.c:11246 +#, c-format +msgid "" +"This means that the backup being taken on the standby is corrupt and should " +"not be used. Enable full_page_writes and run CHECKPOINT on the master, and " +"then try an online backup again." +msgstr "" +"Это означает, что резервная копия, сделанная на дежурном сервере, испорчена " +"и использовать её не следует. Включите режим full_page_writes и выполните " +"CHECKPOINT на главном сервере, а затем попробуйте резервное копирование \"на " +"ходу\" ещё раз." + +#: access/transam/xlog.c:10737 replication/basebackup.c:1423 +#: utils/adt/misc.c:342 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "целевой путь символической ссылки \"%s\" слишком длинный" + +#: access/transam/xlog.c:10790 commands/tablespace.c:402 +#: commands/tablespace.c:578 replication/basebackup.c:1438 utils/adt/misc.c:350 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "табличные пространства не поддерживаются на этой платформе" + +#: access/transam/xlog.c:10841 access/transam/xlog.c:10879 +#, c-format +msgid "" +"If you're sure there is no backup in progress, remove file \"%s\" and try " +"again." +msgstr "" +"Если вы считаете, что информация о резервном копировании неверна, удалите " +"файл \"%s\" и попробуйте снова." + +#: access/transam/xlog.c:11066 +#, c-format +msgid "exclusive backup not in progress" +msgstr "монопольное резервное копирование не выполняется" + +#: access/transam/xlog.c:11093 +#, c-format +msgid "a backup is not in progress" +msgstr "резервное копирование не выполняется" + +#: access/transam/xlog.c:11179 access/transam/xlog.c:11192 +#: access/transam/xlog.c:11581 access/transam/xlog.c:11587 +#: access/transam/xlog.c:11635 access/transam/xlog.c:11708 +#: access/transam/xlogfuncs.c:692 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "неверные данные в файле \"%s\"" + +#: access/transam/xlog.c:11196 replication/basebackup.c:1271 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "" +"дежурный сервер был повышен в процессе резервного копирования \"на ходу\"" + +#: access/transam/xlog.c:11197 replication/basebackup.c:1272 +#, c-format +msgid "" +"This means that the backup being taken is corrupt and should not be used. " +"Try taking another online backup." +msgstr "" +"Это означает, что создаваемая резервная копия испорчена и использовать её не " +"следует. Попробуйте резервное копирование \"на ходу\" ещё раз." + +#: access/transam/xlog.c:11244 +#, c-format +msgid "" +"WAL generated with full_page_writes=off was replayed during online backup" +msgstr "" +"В процессе резервного копирования \"на ходу\" был воспроизведён WAL, " +"созданный в режиме full_page_writes=off" + +#: access/transam/xlog.c:11364 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "" +"базовое копирование выполнено, ожидается архивация нужных сегментов WAL" + +#: access/transam/xlog.c:11376 +#, c-format +msgid "" +"still waiting for all required WAL segments to be archived (%d seconds " +"elapsed)" +msgstr "" +"продолжается ожидание архивации всех нужных сегментов WAL (прошло %d сек.)" + +#: access/transam/xlog.c:11378 +#, c-format +msgid "" +"Check that your archive_command is executing properly. You can safely " +"cancel this backup, but the database backup will not be usable without all " +"the WAL segments." +msgstr "" +"Проверьте, правильно ли работает команда archive_command. Операцию " +"копирования можно отменить безопасно, но резервная копия базы будет " +"непригодна без всех сегментов WAL." + +#: access/transam/xlog.c:11385 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "все нужные сегменты WAL заархивированы" + +#: access/transam/xlog.c:11389 +#, c-format +msgid "" +"WAL archiving is not enabled; you must ensure that all required WAL segments " +"are copied through other means to complete the backup" +msgstr "" +"архивация WAL не настроена; вы должны обеспечить копирование всех требуемых " +"сегментов WAL другими средствами для получения резервной копии" + +#: access/transam/xlog.c:11442 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "" +"прерывание резервного копирования из-за завершения обслуживающего процесса " +"до вызова pg_stop_backup" + +#: access/transam/xlog.c:11618 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "время резервного копирования %s в файле \"%s\"" + +#: access/transam/xlog.c:11623 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "метка резервного копирования %s в файле \"%s\"" + +#: access/transam/xlog.c:11636 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "Получен идентификатор линии времени %u, но ожидался %u." + +#: access/transam/xlog.c:11640 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "линия времени резервной копии %u в файле \"%s\"" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11748 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "запись REDO в WAL в позиции %X/%X для %s" + +#: access/transam/xlog.c:11797 +#, c-format +msgid "online backup mode was not canceled" +msgstr "режим копирования \"на ходу\" не был отменён" + +#: access/transam/xlog.c:11798 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "Не удалось переименовать файл \"%s\" в \"%s\": %m." + +#: access/transam/xlog.c:11807 access/transam/xlog.c:11819 +#: access/transam/xlog.c:11829 +#, c-format +msgid "online backup mode canceled" +msgstr "режим копирования \"на ходу\" отменён" + +#: access/transam/xlog.c:11820 +#, c-format +msgid "" +"Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "" +"Файлы \"%s\" и \"%s\" были переименованы в \"%s\" и \"%s\", соответственно." + +#: access/transam/xlog.c:11830 +#, c-format +msgid "" +"File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to " +"\"%s\": %m." +msgstr "" +"Файл \"%s\" был переименован в \"%s\", но переименовать \"%s\" в \"%s\" не " +"удалось: %m." + +#: access/transam/xlog.c:11963 access/transam/xlogutils.c:971 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "не удалось прочитать сегмент журнала %s, смещение %u: %m" + +#: access/transam/xlog.c:11969 access/transam/xlogutils.c:978 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "" +"не удалось прочитать из сегмента журнала %s по смещению %u (прочитано байт: " +"%d из %zu)" + +#: access/transam/xlog.c:12495 +#, c-format +msgid "WAL receiver process shutdown requested" +msgstr "получен запрос на выключение процесса приёмника WAL" + +#: access/transam/xlog.c:12601 +#, c-format +msgid "received promote request" +msgstr "получен запрос повышения статуса" + +#: access/transam/xlog.c:12614 +#, c-format +msgid "promote trigger file found: %s" +msgstr "найден файл триггера повышения: %s" + +#: access/transam/xlog.c:12623 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "не удалось получить информацию о файле триггера повышения \"%s\": %m" + +#: access/transam/xlogarchive.c:205 +#, c-format +msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgstr "файл архива \"%s\" имеет неправильный размер: %lu вместо %lu" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "файл журнала \"%s\" восстановлен из архива" + +#: access/transam/xlogarchive.c:259 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "восстановить файл \"%s\" из архива не удалось: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:368 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" + +#: access/transam/xlogarchive.c:478 access/transam/xlogarchive.c:542 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "не удалось создать файл состояния архива \"%s\": %m" + +#: access/transam/xlogarchive.c:486 access/transam/xlogarchive.c:550 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "не удалось записать файл состояния архива \"%s\": %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "резервное копирование уже выполняется в этом сеансе" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "выполняется не монопольное резервное копирование" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "Вероятно, подразумевалось pg_stop_backup('f')?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1332 +#: commands/event_trigger.c:1890 commands/extension.c:1944 +#: commands/extension.c:2052 commands/extension.c:2337 commands/prepare.c:712 +#: executor/execExpr.c:2203 executor/execSRF.c:728 executor/functions.c:1040 +#: foreign/foreign.c:520 libpq/hba.c:2666 replication/logical/launcher.c:1086 +#: replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1486 +#: replication/slotfuncs.c:252 replication/walsender.c:3258 +#: storage/ipc/shmem.c:550 utils/adt/datetime.c:4765 utils/adt/genfile.c:505 +#: utils/adt/genfile.c:588 utils/adt/jsonfuncs.c:1792 +#: utils/adt/jsonfuncs.c:1904 utils/adt/jsonfuncs.c:2092 +#: utils/adt/jsonfuncs.c:2201 utils/adt/jsonfuncs.c:3663 utils/adt/misc.c:215 +#: utils/adt/pgstatfuncs.c:476 utils/adt/pgstatfuncs.c:584 +#: utils/adt/pgstatfuncs.c:1719 utils/fmgr/funcapi.c:72 utils/misc/guc.c:9676 +#: utils/mmgr/portalmem.c:1136 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "" +"функция, возвращающая множество, вызвана в контексте, где ему нет места" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1336 +#: commands/event_trigger.c:1894 commands/extension.c:1948 +#: commands/extension.c:2056 commands/extension.c:2341 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2670 replication/logical/launcher.c:1090 +#: replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1490 +#: replication/slotfuncs.c:256 replication/walsender.c:3262 +#: storage/ipc/shmem.c:554 utils/adt/datetime.c:4769 utils/adt/genfile.c:509 +#: utils/adt/genfile.c:592 utils/adt/misc.c:219 utils/adt/pgstatfuncs.c:480 +#: utils/adt/pgstatfuncs.c:588 utils/adt/pgstatfuncs.c:1723 +#: utils/misc/guc.c:9680 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1140 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "требуется режим материализации, но он недопустим в этом контексте" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "немонопольное резервное копирование не выполняется" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "Вероятно, подразумевалось pg_stop_backup('t')?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "Выбранный уровень WAL не достаточен для создания точки восстановления" + +# well-spelled: симв +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "значение для точки восстановления превышает предел (%d симв.)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "выполнить %s во время восстановления нельзя." + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:558 +#: access/transam/xlogfuncs.c:582 access/transam/xlogfuncs.c:722 +#, c-format +msgid "recovery is not in progress" +msgstr "восстановление не выполняется" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:559 +#: access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "" +"Функции управления восстановлением можно использовать только в процессе " +"восстановления." + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:564 +#, c-format +msgid "standby promotion is ongoing" +msgstr "производится повышение ведомого" + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:565 +#, c-format +msgid "%s cannot be executed after promotion is triggered." +msgstr "%s нельзя выполнять, когда производится повышение." + +#: access/transam/xlogfuncs.c:728 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "значение \"wait_seconds\" не должно быть отрицательным или нулевым" + +#: access/transam/xlogfuncs.c:748 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "отправить сигнал процессу postmaster не удалось: %m" + +#: access/transam/xlogfuncs.c:784 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "повышение сервера не завершилось за %d сек." + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "неверное смещение записи: %X/%X" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "по смещению %X/%X запрошено продолжение записи" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "неверная длина записи по смещению %X/%X: ожидалось %u, получено %u" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "длина записи %u по смещению %X/%X слишком велика" + +#: access/transam/xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "нет флага contrecord в позиции %X/%X" + +#: access/transam/xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "неверная длина contrecord (%u) в позиции %X/%X" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "неверный ID менеджера ресурсов %u по смещению %X/%X" + +#: access/transam/xlogreader.c:717 access/transam/xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "запись с неверной ссылкой назад %X/%X по смещению %X/%X" + +#: access/transam/xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "" +"некорректная контрольная сумма данных менеджера ресурсов в записи по " +"смещению %X/%X" + +#: access/transam/xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "неверное магическое число %04X в сегменте журнала %s, смещение %u" + +#: access/transam/xlogreader.c:822 access/transam/xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "неверные информационные биты %04X в сегменте журнала %s, смещение %u" + +#: access/transam/xlogreader.c:837 +#, c-format +msgid "" +"WAL file is from different database system: WAL file database system " +"identifier is %llu, pg_control database system identifier is %llu" +msgstr "" +"файл WAL принадлежит другой СУБД: в нём указан идентификатор системы БД " +"%llu, а идентификатор системы pg_control: %llu" + +#: access/transam/xlogreader.c:845 +#, c-format +msgid "" +"WAL file is from different database system: incorrect segment size in page " +"header" +msgstr "" +"файл WAL принадлежит другой СУБД: некорректный размер сегмента в заголовке " +"страницы" + +#: access/transam/xlogreader.c:851 +#, c-format +msgid "" +"WAL file is from different database system: incorrect XLOG_BLCKSZ in page " +"header" +msgstr "" +"файл WAL принадлежит другой СУБД: некорректный XLOG_BLCKSZ в заголовке " +"страницы" + +#: access/transam/xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "неожиданный pageaddr %X/%X в сегменте журнала %s, смещение %u" + +#: access/transam/xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "" +"нарушение последовательности ID линии времени %u (после %u) в сегменте " +"журнала %s, смещение %u" + +#: access/transam/xlogreader.c:1247 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "идентификатор блока %u идёт не по порядку в позиции %X/%X" + +#: access/transam/xlogreader.c:1270 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA установлен, но данных в позиции %X/%X нет" + +#: access/transam/xlogreader.c:1277 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "" +"BKPBLOCK_HAS_DATA не установлен, но длина данных равна %u в позиции %X/%X" + +#: access/transam/xlogreader.c:1313 +#, c-format +msgid "" +"BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " +"%X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE установлен, но для пропуска заданы смещение %u и длина %u " +"при длине образа блока %u в позиции %X/%X" + +#: access/transam/xlogreader.c:1329 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE не установлен, но для пропуска заданы смещение %u и длина " +"%u в позиции %X/%X" + +#: access/transam/xlogreader.c:1344 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "" +"BKPIMAGE_IS_COMPRESSED установлен, но длина образа блока равна %u в позиции " +"%X/%X" + +#: access/transam/xlogreader.c:1359 +#, c-format +msgid "" +"neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " +"length is %u at %X/%X" +msgstr "" +"ни BKPIMAGE_HAS_HOLE, ни BKPIMAGE_IS_COMPRESSED не установлены, но длина " +"образа блока равна %u в позиции %X/%X" + +#: access/transam/xlogreader.c:1375 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "" +"BKPBLOCK_SAME_REL установлен, но предыдущее значение не задано в позиции %X/" +"%X" + +#: access/transam/xlogreader.c:1387 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "неверный идентификатор блока %u в позиции %X/%X" + +#: access/transam/xlogreader.c:1476 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "запись с неверной длиной в позиции %X/%X" + +#: access/transam/xlogreader.c:1565 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "неверный сжатый образ в позиции %X/%X, блок %d" + +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "" +"для -X требуется число, равное степени двух, в интервале от 1 МБ до 1 ГБ" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:842 tcop/postgres.c:3717 +#, c-format +msgid "--%s requires a value" +msgstr "для --%s требуется значение" + +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:847 tcop/postgres.c:3722 +#, c-format +msgid "-c %s requires a value" +msgstr "для -c %s требуется значение" + +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:859 +#: postmaster/postmaster.c:872 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: bootstrap/bootstrap.c:313 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: неверные аргументы командной строки\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "право назначения прав можно давать только ролям" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "для столбца \"%s\" отношения \"%s\" не были назначены никакие права" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "для объекта \"%s\" не были назначены никакие права" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "" +"для столбца \"%s\" отношения \"%s\" были назначены не все запрошенные права" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "для объекта \"%s\" были назначены не все запрошенные права" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "для столбца \"%s\" отношения \"%s\" не были отозваны никакие права" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "для объекта \"%s\" не были отозваны никакие права" + +#: catalog/aclchk.c:342 +#, c-format +msgid "" +"not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "для столбца \"%s\" отношения \"%s\" были отозваны не все права" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "для объекта \"%s\" были отозваны не все права" + +#: catalog/aclchk.c:430 catalog/aclchk.c:973 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "право %s неприменимо для отношений" + +#: catalog/aclchk.c:434 catalog/aclchk.c:977 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "право %s неприменимо для последовательностей" + +#: catalog/aclchk.c:438 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "право %s неприменимо для баз данных" + +#: catalog/aclchk.c:442 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "право %s неприменимо для домена" + +#: catalog/aclchk.c:446 catalog/aclchk.c:981 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "право %s неприменимо для функций" + +#: catalog/aclchk.c:450 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "право %s неприменимо для языков" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "право %s неприменимо для больших объектов" + +#: catalog/aclchk.c:458 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "право %s неприменимо для схем" + +#: catalog/aclchk.c:462 catalog/aclchk.c:985 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "право %s неприменимо для процедур" + +#: catalog/aclchk.c:466 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "право %s неприменимо для подпрограмм" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "право %s неприменимо для табличных пространств" + +#: catalog/aclchk.c:474 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "право %s неприменимо для типа" + +#: catalog/aclchk.c:478 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "право %s неприменимо для обёрток сторонних данных" + +#: catalog/aclchk.c:482 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "право %s неприменимо для сторонних серверов" + +#: catalog/aclchk.c:521 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "права для столбцов применимы только к отношениям" + +#: catalog/aclchk.c:681 catalog/aclchk.c:4103 catalog/aclchk.c:4885 +#: catalog/objectaddress.c:965 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "большой объект %u не существует" + +#: catalog/aclchk.c:910 catalog/aclchk.c:919 commands/collationcmds.c:118 +#: commands/copy.c:1134 commands/copy.c:1154 commands/copy.c:1163 +#: commands/copy.c:1172 commands/copy.c:1181 commands/copy.c:1190 +#: commands/copy.c:1199 commands/copy.c:1208 commands/copy.c:1226 +#: commands/copy.c:1242 commands/copy.c:1262 commands/copy.c:1279 +#: commands/dbcommands.c:157 commands/dbcommands.c:166 +#: commands/dbcommands.c:175 commands/dbcommands.c:184 +#: commands/dbcommands.c:193 commands/dbcommands.c:202 +#: commands/dbcommands.c:211 commands/dbcommands.c:220 +#: commands/dbcommands.c:229 commands/dbcommands.c:238 +#: commands/dbcommands.c:260 commands/dbcommands.c:1502 +#: commands/dbcommands.c:1511 commands/dbcommands.c:1520 +#: commands/dbcommands.c:1529 commands/extension.c:1735 +#: commands/extension.c:1745 commands/extension.c:1755 +#: commands/extension.c:3055 commands/foreigncmds.c:539 +#: commands/foreigncmds.c:548 commands/functioncmds.c:570 +#: commands/functioncmds.c:736 commands/functioncmds.c:745 +#: commands/functioncmds.c:754 commands/functioncmds.c:763 +#: commands/functioncmds.c:2014 commands/functioncmds.c:2022 +#: commands/publicationcmds.c:90 commands/publicationcmds.c:133 +#: commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 +#: commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 +#: commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:104 commands/subscriptioncmds.c:114 +#: commands/subscriptioncmds.c:124 commands/subscriptioncmds.c:134 +#: commands/subscriptioncmds.c:148 commands/subscriptioncmds.c:159 +#: commands/subscriptioncmds.c:173 commands/tablecmds.c:7104 +#: commands/typecmds.c:322 commands/typecmds.c:1355 commands/typecmds.c:1364 +#: commands/typecmds.c:1372 commands/typecmds.c:1380 commands/typecmds.c:1388 +#: commands/user.c:133 commands/user.c:147 commands/user.c:156 +#: commands/user.c:165 commands/user.c:174 commands/user.c:183 +#: commands/user.c:192 commands/user.c:201 commands/user.c:210 +#: commands/user.c:219 commands/user.c:228 commands/user.c:237 +#: commands/user.c:246 commands/user.c:582 commands/user.c:590 +#: commands/user.c:598 commands/user.c:606 commands/user.c:614 +#: commands/user.c:622 commands/user.c:630 commands/user.c:638 +#: commands/user.c:647 commands/user.c:655 commands/user.c:663 +#: parser/parse_utilcmd.c:403 replication/pgoutput/pgoutput.c:141 +#: replication/pgoutput/pgoutput.c:162 replication/walsender.c:890 +#: replication/walsender.c:901 replication/walsender.c:911 +#, c-format +msgid "conflicting or redundant options" +msgstr "конфликтующие или избыточные параметры" + +#: catalog/aclchk.c:1030 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "права по умолчанию нельзя определить для столбцов" + +#: catalog/aclchk.c:1190 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "предложение IN SCHEMA нельзя использовать в GRANT/REVOKE ON SCHEMAS" + +#: catalog/aclchk.c:1561 catalog/catalog.c:506 catalog/objectaddress.c:1427 +#: commands/analyze.c:389 commands/copy.c:5087 commands/sequence.c:1702 +#: commands/tablecmds.c:6580 commands/tablecmds.c:6723 +#: commands/tablecmds.c:6773 commands/tablecmds.c:6847 +#: commands/tablecmds.c:6917 commands/tablecmds.c:7029 +#: commands/tablecmds.c:7123 commands/tablecmds.c:7182 +#: commands/tablecmds.c:7271 commands/tablecmds.c:7300 +#: commands/tablecmds.c:7455 commands/tablecmds.c:7537 +#: commands/tablecmds.c:7630 commands/tablecmds.c:7785 +#: commands/tablecmds.c:10990 commands/tablecmds.c:11172 +#: commands/tablecmds.c:11332 commands/tablecmds.c:12415 commands/trigger.c:876 +#: parser/analyze.c:2338 parser/parse_relation.c:713 parser/parse_target.c:1036 +#: parser/parse_type.c:144 parser/parse_utilcmd.c:3314 +#: parser/parse_utilcmd.c:3349 parser/parse_utilcmd.c:3391 utils/adt/acl.c:2869 +#: utils/adt/ruleutils.c:2535 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "столбец \"%s\" в таблице \"%s\" не существует" + +#: catalog/aclchk.c:1824 catalog/objectaddress.c:1267 commands/sequence.c:1140 +#: commands/tablecmds.c:236 commands/tablecmds.c:15728 utils/adt/acl.c:2059 +#: utils/adt/acl.c:2089 utils/adt/acl.c:2121 utils/adt/acl.c:2153 +#: utils/adt/acl.c:2181 utils/adt/acl.c:2211 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "\"%s\" - это не последовательность" + +#: catalog/aclchk.c:1862 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "" +"для последовательности \"%s\" применимы только права USAGE, SELECT и UPDATE" + +#: catalog/aclchk.c:1879 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "право %s неприменимо для таблиц" + +#: catalog/aclchk.c:2045 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "право %s неприменимо для столбцов" + +#: catalog/aclchk.c:2058 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "для последовательности \"%s\" применимо только право SELECT" + +# TO REVIEW +#: catalog/aclchk.c:2640 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "язык \"%s\" не является доверенным" + +#: catalog/aclchk.c:2642 +#, c-format +msgid "" +"GRANT and REVOKE are not allowed on untrusted languages, because only " +"superusers can use untrusted languages." +msgstr "" +"GRANT и REVOKE не допускаются для недоверенных языков, так как использовать " +"такие языки могут только суперпользователи." + +#: catalog/aclchk.c:3156 +#, c-format +msgid "cannot set privileges of array types" +msgstr "для типов массивов нельзя определить права" + +#: catalog/aclchk.c:3157 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Вместо этого установите права для типа элемента." + +#: catalog/aclchk.c:3164 catalog/objectaddress.c:1561 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "\"%s\" - это не домен" + +#: catalog/aclchk.c:3284 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "нераспознанное право: \"%s\"" + +#: catalog/aclchk.c:3345 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "нет доступа к агрегату %s" + +#: catalog/aclchk.c:3348 +#, c-format +msgid "permission denied for collation %s" +msgstr "нет доступа к правилу сортировки %s" + +#: catalog/aclchk.c:3351 +#, c-format +msgid "permission denied for column %s" +msgstr "нет доступа к столбцу %s" + +#: catalog/aclchk.c:3354 +#, c-format +msgid "permission denied for conversion %s" +msgstr "нет доступа к преобразованию %s" + +#: catalog/aclchk.c:3357 +#, c-format +msgid "permission denied for database %s" +msgstr "нет доступа к базе данных %s" + +#: catalog/aclchk.c:3360 +#, c-format +msgid "permission denied for domain %s" +msgstr "нет доступа к домену %s" + +#: catalog/aclchk.c:3363 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "нет доступа к событийному триггеру %s" + +#: catalog/aclchk.c:3366 +#, c-format +msgid "permission denied for extension %s" +msgstr "нет доступа к расширению %s" + +#: catalog/aclchk.c:3369 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "нет доступа к обёртке сторонних данных %s" + +#: catalog/aclchk.c:3372 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "нет доступа к стороннему серверу %s" + +#: catalog/aclchk.c:3375 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "нет доступа к сторонней таблице %s" + +#: catalog/aclchk.c:3378 +#, c-format +msgid "permission denied for function %s" +msgstr "нет доступа к функции %s" + +#: catalog/aclchk.c:3381 +#, c-format +msgid "permission denied for index %s" +msgstr "нет доступа к индексу %s" + +#: catalog/aclchk.c:3384 +#, c-format +msgid "permission denied for language %s" +msgstr "нет доступа к языку %s" + +#: catalog/aclchk.c:3387 +#, c-format +msgid "permission denied for large object %s" +msgstr "нет доступа к большому объекту %s" + +#: catalog/aclchk.c:3390 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "нет доступа к материализованному представлению %s" + +#: catalog/aclchk.c:3393 +#, c-format +msgid "permission denied for operator class %s" +msgstr "нет доступа к классу операторов %s" + +#: catalog/aclchk.c:3396 +#, c-format +msgid "permission denied for operator %s" +msgstr "нет доступа к оператору %s" + +#: catalog/aclchk.c:3399 +#, c-format +msgid "permission denied for operator family %s" +msgstr "нет доступа к семейству операторов %s" + +#: catalog/aclchk.c:3402 +#, c-format +msgid "permission denied for policy %s" +msgstr "нет доступа к политике %s" + +#: catalog/aclchk.c:3405 +#, c-format +msgid "permission denied for procedure %s" +msgstr "нет доступа к процедуре %s" + +#: catalog/aclchk.c:3408 +#, c-format +msgid "permission denied for publication %s" +msgstr "нет доступа к публикации %s" + +#: catalog/aclchk.c:3411 +#, c-format +msgid "permission denied for routine %s" +msgstr "нет доступа к подпрограмме %s" + +#: catalog/aclchk.c:3414 +#, c-format +msgid "permission denied for schema %s" +msgstr "нет доступа к схеме %s" + +#: catalog/aclchk.c:3417 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 +#: commands/sequence.c:1864 +#, c-format +msgid "permission denied for sequence %s" +msgstr "нет доступа к последовательности %s" + +#: catalog/aclchk.c:3420 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "нет доступа к объекту статистики %s" + +#: catalog/aclchk.c:3423 +#, c-format +msgid "permission denied for subscription %s" +msgstr "нет доступа к подписке %s" + +#: catalog/aclchk.c:3426 +#, c-format +msgid "permission denied for table %s" +msgstr "нет доступа к таблице %s" + +#: catalog/aclchk.c:3429 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "нет доступа к табличному пространству %s" + +#: catalog/aclchk.c:3432 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "нет доступа к конфигурации текстового поиска %s" + +#: catalog/aclchk.c:3435 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "нет доступа к словарю текстового поиска %s" + +#: catalog/aclchk.c:3438 +#, c-format +msgid "permission denied for type %s" +msgstr "нет доступа к типу %s" + +#: catalog/aclchk.c:3441 +#, c-format +msgid "permission denied for view %s" +msgstr "нет доступа к представлению %s" + +#: catalog/aclchk.c:3476 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "нужно быть владельцем агрегата %s" + +#: catalog/aclchk.c:3479 +#, c-format +msgid "must be owner of collation %s" +msgstr "нужно быть владельцем правила сортировки %s" + +#: catalog/aclchk.c:3482 +#, c-format +msgid "must be owner of conversion %s" +msgstr "нужно быть владельцем преобразования %s" + +#: catalog/aclchk.c:3485 +#, c-format +msgid "must be owner of database %s" +msgstr "нужно быть владельцем базы %s" + +#: catalog/aclchk.c:3488 +#, c-format +msgid "must be owner of domain %s" +msgstr "нужно быть владельцем домена %s" + +#: catalog/aclchk.c:3491 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "нужно быть владельцем событийного триггера %s" + +#: catalog/aclchk.c:3494 +#, c-format +msgid "must be owner of extension %s" +msgstr "нужно быть владельцем расширения %s" + +#: catalog/aclchk.c:3497 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "нужно быть владельцем обёртки сторонних данных %s" + +#: catalog/aclchk.c:3500 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "нужно быть \"владельцем\" стороннего сервера %s" + +#: catalog/aclchk.c:3503 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "нужно быть владельцем сторонней таблицы %s" + +#: catalog/aclchk.c:3506 +#, c-format +msgid "must be owner of function %s" +msgstr "нужно быть владельцем функции %s" + +#: catalog/aclchk.c:3509 +#, c-format +msgid "must be owner of index %s" +msgstr "нужно быть владельцем индекса %s" + +#: catalog/aclchk.c:3512 +#, c-format +msgid "must be owner of language %s" +msgstr "нужно быть владельцем языка %s" + +#: catalog/aclchk.c:3515 +#, c-format +msgid "must be owner of large object %s" +msgstr "нужно быть владельцем большого объекта %s" + +#: catalog/aclchk.c:3518 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "нужно быть владельцем материализованного представления %s" + +#: catalog/aclchk.c:3521 +#, c-format +msgid "must be owner of operator class %s" +msgstr "нужно быть владельцем класса операторов %s" + +#: catalog/aclchk.c:3524 +#, c-format +msgid "must be owner of operator %s" +msgstr "нужно быть владельцем оператора %s" + +#: catalog/aclchk.c:3527 +#, c-format +msgid "must be owner of operator family %s" +msgstr "нужно быть владельцем семейства операторов %s" + +#: catalog/aclchk.c:3530 +#, c-format +msgid "must be owner of procedure %s" +msgstr "нужно быть владельцем процедуры %s" + +#: catalog/aclchk.c:3533 +#, c-format +msgid "must be owner of publication %s" +msgstr "нужно быть владельцем публикации %s" + +#: catalog/aclchk.c:3536 +#, c-format +msgid "must be owner of routine %s" +msgstr "нужно быть владельцем подпрограммы %s" + +#: catalog/aclchk.c:3539 +#, c-format +msgid "must be owner of sequence %s" +msgstr "нужно быть владельцем последовательности %s" + +#: catalog/aclchk.c:3542 +#, c-format +msgid "must be owner of subscription %s" +msgstr "нужно быть владельцем подписки %s" + +#: catalog/aclchk.c:3545 +#, c-format +msgid "must be owner of table %s" +msgstr "нужно быть владельцем таблицы %s" + +#: catalog/aclchk.c:3548 +#, c-format +msgid "must be owner of type %s" +msgstr "нужно быть владельцем типа %s" + +#: catalog/aclchk.c:3551 +#, c-format +msgid "must be owner of view %s" +msgstr "нужно быть владельцем представления %s" + +#: catalog/aclchk.c:3554 +#, c-format +msgid "must be owner of schema %s" +msgstr "нужно быть владельцем схемы %s" + +#: catalog/aclchk.c:3557 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "нужно быть владельцем объекта статистики %s" + +#: catalog/aclchk.c:3560 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "нужно быть владельцем табличного пространства %s" + +#: catalog/aclchk.c:3563 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "нужно быть владельцем конфигурации текстового поиска %s" + +#: catalog/aclchk.c:3566 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "нужно быть владельцем словаря текстового поиска %s" + +#: catalog/aclchk.c:3580 +#, c-format +msgid "must be owner of relation %s" +msgstr "нужно быть владельцем отношения %s" + +#: catalog/aclchk.c:3624 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "нет доступа к столбцу \"%s\" отношения \"%s\"" + +#: catalog/aclchk.c:3745 catalog/aclchk.c:3753 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "атрибут %d отношения с OID %u не существует" + +#: catalog/aclchk.c:3826 catalog/aclchk.c:4736 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "отношение с OID %u не существует" + +#: catalog/aclchk.c:3916 catalog/aclchk.c:5154 +#, c-format +msgid "database with OID %u does not exist" +msgstr "база данных с OID %u не существует" + +#: catalog/aclchk.c:3970 catalog/aclchk.c:4814 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2055 +#, c-format +msgid "function with OID %u does not exist" +msgstr "функция с OID %u не существует" + +#: catalog/aclchk.c:4024 catalog/aclchk.c:4840 +#, c-format +msgid "language with OID %u does not exist" +msgstr "язык с OID %u не существует" + +#: catalog/aclchk.c:4188 catalog/aclchk.c:4912 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "схема с OID %u не существует" + +#: catalog/aclchk.c:4242 catalog/aclchk.c:4939 utils/adt/genfile.c:686 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "табличное пространство с OID %u не существует" + +#: catalog/aclchk.c:4301 catalog/aclchk.c:5073 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "обёртка сторонних данных с OID %u не существует" + +#: catalog/aclchk.c:4363 catalog/aclchk.c:5100 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "сторонний сервер с OID %u не существует" + +#: catalog/aclchk.c:4423 catalog/aclchk.c:4762 utils/cache/typcache.c:378 +#: utils/cache/typcache.c:432 +#, c-format +msgid "type with OID %u does not exist" +msgstr "тип с OID %u не существует" + +#: catalog/aclchk.c:4788 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "оператор с OID %u не существует" + +#: catalog/aclchk.c:4965 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "класс операторов с OID %u не существует" + +#: catalog/aclchk.c:4992 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "семейство операторов с OID %u не существует" + +#: catalog/aclchk.c:5019 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "словарь текстового поиска с OID %u не существует" + +#: catalog/aclchk.c:5046 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "конфигурация текстового поиска с OID %u не существует" + +#: catalog/aclchk.c:5127 commands/event_trigger.c:475 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "событийный триггер с OID %u не существует" + +#: catalog/aclchk.c:5180 commands/collationcmds.c:367 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "правило сортировки с OID %u не существует" + +#: catalog/aclchk.c:5206 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "преобразование с OID %u не существует" + +#: catalog/aclchk.c:5247 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "расширение с OID %u не существует" + +#: catalog/aclchk.c:5274 commands/publicationcmds.c:794 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "публикация с OID %u не существует" + +#: catalog/aclchk.c:5300 commands/subscriptioncmds.c:1112 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "подписка с OID %u не существует" + +#: catalog/aclchk.c:5326 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "объект статистики с OID %u не существует" + +#: catalog/catalog.c:485 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "выполнять pg_nextoid() может только суперпользователь" + +#: catalog/catalog.c:493 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() можно использовать только для системных каталогов" + +#: catalog/catalog.c:498 parser/parse_utilcmd.c:2215 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "индекс \"%s\" не принадлежит таблице \"%s\"" + +#: catalog/catalog.c:515 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "столбец \"%s\" имеет тип не oid" + +#: catalog/catalog.c:522 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "индекс \"%s\" не является индексом столбца \"%s\"" + +#: catalog/dependency.c:823 catalog/dependency.c:1061 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "удалить объект %s нельзя, так как он нужен объекту %s" + +#: catalog/dependency.c:825 catalog/dependency.c:1063 +#, c-format +msgid "You can drop %s instead." +msgstr "Однако можно удалить %s." + +#: catalog/dependency.c:933 catalog/pg_shdepend.c:696 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "удалить объект %s нельзя, так как он нужен системе баз данных" + +#: catalog/dependency.c:1129 +#, c-format +msgid "drop auto-cascades to %s" +msgstr "удаление автоматически распространяется на объект %s" + +#: catalog/dependency.c:1141 catalog/dependency.c:1150 +#, c-format +msgid "%s depends on %s" +msgstr "%s зависит от объекта %s" + +#: catalog/dependency.c:1162 catalog/dependency.c:1171 +#, c-format +msgid "drop cascades to %s" +msgstr "удаление распространяется на объект %s" + +#: catalog/dependency.c:1179 catalog/pg_shdepend.c:825 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"и ещё %d объект (см. список в протоколе сервера)" +msgstr[1] "" +"\n" +"и ещё %d объекта (см. список в протоколе сервера)" +msgstr[2] "" +"\n" +"и ещё %d объектов (см. список в протоколе сервера)" + +#: catalog/dependency.c:1191 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "удалить объект %s нельзя, так как от него зависят другие объекты" + +#: catalog/dependency.c:1193 catalog/dependency.c:1194 +#: catalog/dependency.c:1200 catalog/dependency.c:1201 +#: catalog/dependency.c:1212 catalog/dependency.c:1213 +#: commands/tablecmds.c:1249 commands/tablecmds.c:13034 +#: commands/tablespace.c:481 commands/user.c:1095 commands/view.c:495 +#: libpq/auth.c:334 replication/syncrep.c:1032 storage/lmgr/deadlock.c:1154 +#: storage/lmgr/proc.c:1350 utils/adt/acl.c:5332 utils/adt/jsonfuncs.c:614 +#: utils/adt/jsonfuncs.c:620 utils/misc/guc.c:6771 utils/misc/guc.c:6807 +#: utils/misc/guc.c:6877 utils/misc/guc.c:10975 utils/misc/guc.c:11009 +#: utils/misc/guc.c:11043 utils/misc/guc.c:11077 utils/misc/guc.c:11112 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1195 catalog/dependency.c:1202 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Для удаления зависимых объектов используйте DROP ... CASCADE." + +#: catalog/dependency.c:1199 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "" +"удалить запрошенные объекты нельзя, так как от них зависят другие объекты" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1208 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "удаление распространяется на ещё %d объект" +msgstr[1] "удаление распространяется на ещё %d объекта" +msgstr[2] "удаление распространяется на ещё %d объектов" + +#: catalog/dependency.c:1875 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "константу типа %s здесь использовать нельзя" + +#: catalog/heap.c:330 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "нет прав для создания отношения \"%s.%s\"" + +#: catalog/heap.c:332 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "Изменение системного каталога в текущем состоянии запрещено." + +#: catalog/heap.c:509 commands/tablecmds.c:2145 commands/tablecmds.c:2745 +#: commands/tablecmds.c:6177 +#, c-format +msgid "tables can have at most %d columns" +msgstr "максимальное число столбцов в таблице: %d" + +#: catalog/heap.c:527 commands/tablecmds.c:6470 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "имя столбца \"%s\" конфликтует с системным столбцом" + +#: catalog/heap.c:543 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "имя столбца \"%s\" указано неоднократно" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:618 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "столбец \"%s\" ключа разбиения имеет псевдотип %s" + +#: catalog/heap.c:623 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "столбец \"%s\" имеет псевдотип %s" + +#: catalog/heap.c:654 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "составной тип %s не может содержать себя же" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:709 +#, c-format +msgid "" +"no collation was derived for partition key column %s with collatable type %s" +msgstr "" +"для входящего в ключ разбиения столбца \"%s\" с сортируемым типом %s не " +"удалось получить правило сортировки" + +#: catalog/heap.c:715 commands/createas.c:203 commands/createas.c:486 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "" +"для столбца \"%s\" с сортируемым типом %s не удалось получить правило " +"сортировки" + +#: catalog/heap.c:1164 catalog/index.c:865 commands/tablecmds.c:3520 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "отношение \"%s\" уже существует" + +#: catalog/heap.c:1180 catalog/pg_type.c:428 catalog/pg_type.c:775 +#: commands/typecmds.c:238 commands/typecmds.c:250 commands/typecmds.c:719 +#: commands/typecmds.c:1125 commands/typecmds.c:1337 commands/typecmds.c:2124 +#, c-format +msgid "type \"%s\" already exists" +msgstr "тип \"%s\" уже существует" + +#: catalog/heap.c:1181 +#, c-format +msgid "" +"A relation has an associated type of the same name, so you must use a name " +"that doesn't conflict with any existing type." +msgstr "" +"С отношением уже связан тип с таким же именем; выберите имя, не " +"конфликтующее с существующими типами." + +#: catalog/heap.c:1210 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "значение OID кучи в pg_class не задано в режиме двоичного обновления" + +#: catalog/heap.c:2409 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "" +"добавить ограничение NO INHERIT к секционированной таблице \"%s\" нельзя" + +#: catalog/heap.c:2679 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "ограничение-проверка \"%s\" уже существует" + +#: catalog/heap.c:2849 catalog/index.c:879 catalog/pg_constraint.c:668 +#: commands/tablecmds.c:8135 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "ограничение \"%s\" для отношения \"%s\" уже существует" + +#: catalog/heap.c:2856 +#, c-format +msgid "" +"constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "" +"ограничение \"%s\" конфликтует с ненаследуемым ограничением таблицы \"%s\"" + +#: catalog/heap.c:2867 +#, c-format +msgid "" +"constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "" +"ограничение \"%s\" конфликтует с наследуемым ограничением таблицы \"%s\"" + +#: catalog/heap.c:2877 +#, c-format +msgid "" +"constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "" +"ограничение \"%s\" конфликтует с непроверенным (NOT VALID) ограничением " +"таблицы \"%s\"" + +#: catalog/heap.c:2882 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "слияние ограничения \"%s\" с унаследованным определением" + +#: catalog/heap.c:2984 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "" +"использовать генерируемый столбец \"%s\" в выражении генерируемого столбца " +"нельзя" + +#: catalog/heap.c:2986 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "" +"Генерируемый столбец не может ссылаться на другой генерируемый столбец." + +#: catalog/heap.c:3038 +#, c-format +msgid "generation expression is not immutable" +msgstr "генерирующее выражение не является постоянным" + +#: catalog/heap.c:3066 rewrite/rewriteHandler.c:1193 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "столбец \"%s\" имеет тип %s, но тип выражения по умолчанию %s" + +#: catalog/heap.c:3071 commands/prepare.c:367 parser/parse_node.c:412 +#: parser/parse_target.c:589 parser/parse_target.c:869 +#: parser/parse_target.c:879 rewrite/rewriteHandler.c:1198 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Перепишите выражение или преобразуйте его тип." + +#: catalog/heap.c:3118 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "в ограничении-проверке можно ссылаться только на таблицу \"%s\"" + +#: catalog/heap.c:3416 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "неподдерживаемое сочетание внешнего ключа с ON COMMIT" + +#: catalog/heap.c:3417 +#, c-format +msgid "" +"Table \"%s\" references \"%s\", but they do not have the same ON COMMIT " +"setting." +msgstr "" +"Таблица \"%s\" ссылается на \"%s\", и для них задан разный режим ON COMMIT." + +#: catalog/heap.c:3422 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "опустошить таблицу, на которую ссылается внешний ключ, нельзя" + +#: catalog/heap.c:3423 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "Таблица \"%s\" ссылается на \"%s\"." + +#: catalog/heap.c:3425 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "" +"Опустошите таблицу \"%s\" параллельно или используйте TRUNCATE ... CASCADE." + +#: catalog/index.c:219 parser/parse_utilcmd.c:2121 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "таблица \"%s\" не может иметь несколько первичных ключей" + +#: catalog/index.c:237 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "первичные ключи не могут быть выражениями" + +#: catalog/index.c:254 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "столбец первичного ключа \"%s\" не помечен как NOT NULL" + +#: catalog/index.c:764 catalog/index.c:1846 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "" +"пользовательские индексы в таблицах системного каталога не поддерживаются" + +#: catalog/index.c:804 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "" +"недетерминированные правила сортировки не поддерживаются для класса " +"операторов \"%s\"" + +#: catalog/index.c:819 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "" +"параллельное создание индекса в таблицах системного каталога не " +"поддерживается" + +#: catalog/index.c:828 catalog/index.c:1281 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "" +"параллельное создание индекса для ограничений-исключений не поддерживается" + +#: catalog/index.c:837 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "нельзя создать разделяемые индексы после initdb" + +#: catalog/index.c:857 commands/createas.c:252 commands/sequence.c:154 +#: parser/parse_utilcmd.c:211 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "отношение \"%s\" уже существует, пропускается" + +#: catalog/index.c:907 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "" +"значение OID индекса в pg_class не задано в режиме двоичного обновления" + +#: catalog/index.c:2131 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY должен быть первым действием в транзакции" + +#: catalog/index.c:2862 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "создание индекса \"%s\" для таблицы \"%s\" в непараллельном режиме" + +#: catalog/index.c:2867 +#, c-format +msgid "" +"building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "" +"building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "" +"создание индекса \"%s\" для таблицы \"%s\" с расчётом на %d параллельного " +"исполнителя" +msgstr[1] "" +"создание индекса \"%s\" для таблицы \"%s\" с расчётом на %d параллельных " +"исполнителей" +msgstr[2] "" +"создание индекса \"%s\" для таблицы \"%s\" с расчётом на %d параллельных " +"исполнителей" + +#: catalog/index.c:3495 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "переиндексировать временные таблицы других сеансов нельзя" + +#: catalog/index.c:3506 commands/indexcmds.c:3005 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "перестроить нерабочий индекс в таблице TOAST нельзя" + +#: catalog/index.c:3628 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "индекс \"%s\" был перестроен" + +#: catalog/index.c:3704 commands/indexcmds.c:3026 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "" +"REINDEX для секционированных таблицы ещё не реализован, \"%s\" пропускается" + +#: catalog/index.c:3759 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "" +"перестроить нерабочий индекс \"%s.%s\" в таблице TOAST нельзя, он " +"пропускается" + +#: catalog/namespace.c:257 catalog/namespace.c:461 catalog/namespace.c:553 +#: commands/trigger.c:5027 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "ссылки между базами не реализованы: \"%s.%s.%s\"" + +#: catalog/namespace.c:314 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "для временных таблиц имя схемы не указывается" + +#: catalog/namespace.c:395 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "не удалось получить блокировку таблицы \"%s.%s\"" + +#: catalog/namespace.c:400 commands/lockcmds.c:143 commands/lockcmds.c:228 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "не удалось получить блокировку таблицы \"%s\"" + +#: catalog/namespace.c:428 parser/parse_relation.c:1357 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "отношение \"%s.%s\" не существует" + +#: catalog/namespace.c:433 parser/parse_relation.c:1370 +#: parser/parse_relation.c:1378 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "отношение \"%s\" не существует" + +#: catalog/namespace.c:499 catalog/namespace.c:3030 commands/extension.c:1519 +#: commands/extension.c:1525 +#, c-format +msgid "no schema has been selected to create in" +msgstr "схема для создания объектов не выбрана" + +#: catalog/namespace.c:651 catalog/namespace.c:664 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "во временных схемах других сеансов нельзя создавать отношения" + +#: catalog/namespace.c:655 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "создавать временные отношения можно только во временных схемах" + +#: catalog/namespace.c:670 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "во временных схемах можно создавать только временные отношения" + +#: catalog/namespace.c:2222 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "объект статистики \"%s\" не существует" + +#: catalog/namespace.c:2345 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "анализатор текстового поиска \"%s\" не существует" + +#: catalog/namespace.c:2471 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "словарь текстового поиска \"%s\" не существует" + +#: catalog/namespace.c:2598 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "шаблон текстового поиска \"%s\" не существует" + +#: catalog/namespace.c:2724 commands/tsearchcmds.c:1194 +#: utils/cache/ts_cache.c:617 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "конфигурация текстового поиска \"%s\" не существует" + +#: catalog/namespace.c:2837 parser/parse_expr.c:872 parser/parse_target.c:1228 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "ссылки между базами не реализованы: %s" + +#: catalog/namespace.c:2843 parser/parse_expr.c:879 parser/parse_target.c:1235 +#: gram.y:14982 gram.y:16436 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "неверное полное имя (слишком много компонентов): %s" + +#: catalog/namespace.c:2973 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "перемещать объекты в/из внутренних схем нельзя" + +#: catalog/namespace.c:2979 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "перемещать объекты в/из схем TOAST нельзя" + +#: catalog/namespace.c:3052 commands/schemacmds.c:256 commands/schemacmds.c:336 +#: commands/tablecmds.c:1194 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "схема \"%s\" не существует" + +#: catalog/namespace.c:3083 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "неверное имя отношения (слишком много компонентов): %s" + +#: catalog/namespace.c:3646 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "правило сортировки \"%s\" для кодировки \"%s\" не существует" + +#: catalog/namespace.c:3701 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "преобразование \"%s\" не существует" + +#: catalog/namespace.c:3965 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "нет прав для создания временных таблиц в базе \"%s\"" + +#: catalog/namespace.c:3981 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "создавать временные таблицы в процессе восстановления нельзя" + +#: catalog/namespace.c:3987 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "создавать временные таблицы во время параллельных операций нельзя" + +#: catalog/namespace.c:4286 commands/tablespace.c:1217 commands/variable.c:64 +#: utils/misc/guc.c:11144 utils/misc/guc.c:11222 +#, c-format +msgid "List syntax is invalid." +msgstr "Ошибка синтаксиса в списке." + +#: catalog/objectaddress.c:1275 catalog/pg_publication.c:57 +#: commands/policy.c:95 commands/policy.c:375 commands/policy.c:465 +#: commands/tablecmds.c:230 commands/tablecmds.c:272 commands/tablecmds.c:1989 +#: commands/tablecmds.c:5628 commands/tablecmds.c:11107 +#, c-format +msgid "\"%s\" is not a table" +msgstr "\"%s\" - это не таблица" + +#: catalog/objectaddress.c:1282 commands/tablecmds.c:242 +#: commands/tablecmds.c:5658 commands/tablecmds.c:15733 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "\"%s\" - это не представление" + +#: catalog/objectaddress.c:1289 commands/matview.c:175 commands/tablecmds.c:248 +#: commands/tablecmds.c:15738 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "\"%s\" - это не материализованное представление" + +#: catalog/objectaddress.c:1296 commands/tablecmds.c:266 +#: commands/tablecmds.c:5661 commands/tablecmds.c:15743 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "\"%s\" - это не сторонняя таблица" + +#: catalog/objectaddress.c:1337 +#, c-format +msgid "must specify relation and object name" +msgstr "необходимо указать имя отношения и объекта" + +#: catalog/objectaddress.c:1413 catalog/objectaddress.c:1466 +#, c-format +msgid "column name must be qualified" +msgstr "имя столбца нужно указать в полной форме" + +#: catalog/objectaddress.c:1513 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "" +"значение по умолчанию для столбца \"%s\" отношения \"%s\" не существует" + +#: catalog/objectaddress.c:1550 commands/functioncmds.c:133 +#: commands/tablecmds.c:258 commands/typecmds.c:263 commands/typecmds.c:3275 +#: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:845 +#: utils/adt/acl.c:4435 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "тип \"%s\" не существует" + +#: catalog/objectaddress.c:1669 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "оператор %d (%s, %s) из семейства %s не существует" + +#: catalog/objectaddress.c:1700 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "функция %d (%s, %s) из семейства %s не существует" + +#: catalog/objectaddress.c:1751 catalog/objectaddress.c:1777 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "сопоставление для пользователя \"%s\" на сервере \"%s\" не существует" + +#: catalog/objectaddress.c:1766 commands/foreigncmds.c:430 +#: commands/foreigncmds.c:1012 commands/foreigncmds.c:1395 +#: foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "сервер \"%s\" не существует" + +#: catalog/objectaddress.c:1833 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "публикуемое отношение \"%s\" в публикации \"%s\" не существует" + +#: catalog/objectaddress.c:1895 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "нераспознанный тип объекта ACL по умолчанию: \"%c\"" + +#: catalog/objectaddress.c:1896 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Допустимые типы объектов: \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." + +#: catalog/objectaddress.c:1947 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "" +"ACL по умолчанию для пользователя \"%s\" в схеме \"%s\" для объекта %s не " +"существует" + +#: catalog/objectaddress.c:1952 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "" +"ACL по умолчанию для пользователя \"%s\" и для объекта %s не существует" + +#: catalog/objectaddress.c:1979 catalog/objectaddress.c:2037 +#: catalog/objectaddress.c:2094 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "списки имён и аргументов не должны содержать NULL" + +#: catalog/objectaddress.c:2013 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "неподдерживаемый тип объекта: \"%s\"" + +#: catalog/objectaddress.c:2033 catalog/objectaddress.c:2051 +#: catalog/objectaddress.c:2192 +#, c-format +msgid "name list length must be exactly %d" +msgstr "длина списка имён должна быть равна %d" + +#: catalog/objectaddress.c:2055 +#, c-format +msgid "large object OID may not be null" +msgstr "OID большого объекта не может быть NULL" + +#: catalog/objectaddress.c:2064 catalog/objectaddress.c:2127 +#: catalog/objectaddress.c:2134 +#, c-format +msgid "name list length must be at least %d" +msgstr "длина списка аргументов должна быть не меньше %d" + +#: catalog/objectaddress.c:2120 catalog/objectaddress.c:2141 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "длина списка аргументов должна быть равна %d" + +#: catalog/objectaddress.c:2393 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "нужно быть владельцем большого объекта %u" + +#: catalog/objectaddress.c:2408 commands/functioncmds.c:1445 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "это разрешено только владельцу типа %s или %s" + +#: catalog/objectaddress.c:2458 catalog/objectaddress.c:2475 +#, c-format +msgid "must be superuser" +msgstr "требуются права суперпользователя" + +#: catalog/objectaddress.c:2465 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "требуется право CREATEROLE" + +#: catalog/objectaddress.c:2544 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "нераспознанный тип объекта \"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2772 +#, c-format +msgid "column %s of %s" +msgstr "столбец %s отношения %s" + +#: catalog/objectaddress.c:2782 +#, c-format +msgid "function %s" +msgstr "функция %s" + +#: catalog/objectaddress.c:2787 +#, c-format +msgid "type %s" +msgstr "тип %s" + +#: catalog/objectaddress.c:2817 +#, c-format +msgid "cast from %s to %s" +msgstr "приведение %s к %s" + +#: catalog/objectaddress.c:2845 +#, c-format +msgid "collation %s" +msgstr "правило сортировки %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2871 +#, c-format +msgid "constraint %s on %s" +msgstr "ограничение %s в отношении %s" + +#: catalog/objectaddress.c:2877 +#, c-format +msgid "constraint %s" +msgstr "ограничение %s" + +#: catalog/objectaddress.c:2904 +#, c-format +msgid "conversion %s" +msgstr "преобразование %s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2943 +#, c-format +msgid "default value for %s" +msgstr "значение по умолчанию для %s" + +#: catalog/objectaddress.c:2952 +#, c-format +msgid "language %s" +msgstr "язык %s" + +#: catalog/objectaddress.c:2957 +#, c-format +msgid "large object %u" +msgstr "большой объект %u" + +#: catalog/objectaddress.c:2962 +#, c-format +msgid "operator %s" +msgstr "оператор %s" + +#: catalog/objectaddress.c:2994 +#, c-format +msgid "operator class %s for access method %s" +msgstr "класс операторов %s для метода доступа %s" + +#: catalog/objectaddress.c:3017 +#, c-format +msgid "access method %s" +msgstr "метод доступа %s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3059 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "оператор %d (%s, %s) из семейства \"%s\": %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3109 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "функция %d (%s, %s) из семейства \"%s\": %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3153 +#, c-format +msgid "rule %s on %s" +msgstr "правило %s для отношения %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3191 +#, c-format +msgid "trigger %s on %s" +msgstr "триггер %s в отношении %s" + +#: catalog/objectaddress.c:3207 +#, c-format +msgid "schema %s" +msgstr "схема %s" + +#: catalog/objectaddress.c:3230 +#, c-format +msgid "statistics object %s" +msgstr "объект статистики %s" + +#: catalog/objectaddress.c:3257 +#, c-format +msgid "text search parser %s" +msgstr "анализатор текстового поиска %s" + +#: catalog/objectaddress.c:3283 +#, c-format +msgid "text search dictionary %s" +msgstr "словарь текстового поиска %s" + +#: catalog/objectaddress.c:3309 +#, c-format +msgid "text search template %s" +msgstr "шаблон текстового поиска %s" + +#: catalog/objectaddress.c:3335 +#, c-format +msgid "text search configuration %s" +msgstr "конфигурация текстового поиска %s" + +#: catalog/objectaddress.c:3344 +#, c-format +msgid "role %s" +msgstr "роль %s" + +#: catalog/objectaddress.c:3357 +#, c-format +msgid "database %s" +msgstr "база данных %s" + +#: catalog/objectaddress.c:3369 +#, c-format +msgid "tablespace %s" +msgstr "табличное пространство %s" + +#: catalog/objectaddress.c:3378 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "обёртка сторонних данных %s" + +#: catalog/objectaddress.c:3387 +#, c-format +msgid "server %s" +msgstr "сервер %s" + +#: catalog/objectaddress.c:3415 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "сопоставление для пользователя %s на сервере %s" + +#: catalog/objectaddress.c:3460 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "" +"права по умолчанию для новых отношений, принадлежащих роли %s в схеме %s" + +#: catalog/objectaddress.c:3464 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "права по умолчанию для новых отношений, принадлежащих роли %s" + +#: catalog/objectaddress.c:3470 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "" +"права по умолчанию для новых последовательностей, принадлежащих роли %s в " +"схеме %s" + +#: catalog/objectaddress.c:3474 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "" +"права по умолчанию для новых последовательностей, принадлежащих роли %s" + +#: catalog/objectaddress.c:3480 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "права по умолчанию для новых функций, принадлежащих роли %s в схеме %s" + +#: catalog/objectaddress.c:3484 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "права по умолчанию для новых функций, принадлежащих роли %s" + +#: catalog/objectaddress.c:3490 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "права по умолчанию для новых типов, принадлежащих роли %s в схеме %s" + +#: catalog/objectaddress.c:3494 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "права по умолчанию для новых типов, принадлежащих роли %s" + +#: catalog/objectaddress.c:3500 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "права по умолчанию для новых схем, принадлежащих роли %s" + +#: catalog/objectaddress.c:3507 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "" +"права по умолчанию для новых объектов, принадлежащих роли %s в схеме %s" + +#: catalog/objectaddress.c:3511 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "права по умолчанию для новых объектов, принадлежащих роли %s" + +#: catalog/objectaddress.c:3529 +#, c-format +msgid "extension %s" +msgstr "расширение %s" + +#: catalog/objectaddress.c:3542 +#, c-format +msgid "event trigger %s" +msgstr "событийный триггер %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3578 +#, c-format +msgid "policy %s on %s" +msgstr "политика %s отношения %s" + +#: catalog/objectaddress.c:3588 +#, c-format +msgid "publication %s" +msgstr "публикация %s" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3614 +#, c-format +msgid "publication of %s in publication %s" +msgstr "публикуемое отношение %s в публикации %s" + +#: catalog/objectaddress.c:3623 +#, c-format +msgid "subscription %s" +msgstr "подписка %s" + +#: catalog/objectaddress.c:3642 +#, c-format +msgid "transform for %s language %s" +msgstr "преобразование для %s, языка %s" + +#: catalog/objectaddress.c:3705 +#, c-format +msgid "table %s" +msgstr "таблица %s" + +#: catalog/objectaddress.c:3710 +#, c-format +msgid "index %s" +msgstr "индекс %s" + +#: catalog/objectaddress.c:3714 +#, c-format +msgid "sequence %s" +msgstr "последовательность %s" + +#: catalog/objectaddress.c:3718 +#, c-format +msgid "toast table %s" +msgstr "TOAST-таблица %s" + +#: catalog/objectaddress.c:3722 +#, c-format +msgid "view %s" +msgstr "представление %s" + +#: catalog/objectaddress.c:3726 +#, c-format +msgid "materialized view %s" +msgstr "материализованное представление %s" + +#: catalog/objectaddress.c:3730 +#, c-format +msgid "composite type %s" +msgstr "составной тип %s" + +#: catalog/objectaddress.c:3734 +#, c-format +msgid "foreign table %s" +msgstr "сторонняя таблица %s" + +#: catalog/objectaddress.c:3739 +#, c-format +msgid "relation %s" +msgstr "отношение %s" + +#: catalog/objectaddress.c:3776 +#, c-format +msgid "operator family %s for access method %s" +msgstr "семейство операторов %s для метода доступа %s" + +#: catalog/pg_aggregate.c:128 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "агрегатные функции допускают не больше %d аргумента" +msgstr[1] "агрегатные функции допускают не больше %d аргументов" +msgstr[2] "агрегатные функции допускают не больше %d аргументов" + +#: catalog/pg_aggregate.c:143 catalog/pg_aggregate.c:157 +#, c-format +msgid "cannot determine transition data type" +msgstr "не удалось определить переходный тип данных" + +#: catalog/pg_aggregate.c:172 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "" +"сортирующая агрегатная функция с непостоянными аргументами должна " +"использовать тип VARIADIC ANY" + +#: catalog/pg_aggregate.c:198 +#, c-format +msgid "" +"a hypothetical-set aggregate must have direct arguments matching its " +"aggregated arguments" +msgstr "" +"гипотезирующая агрегатная функция должна иметь непосредственные аргументы, " +"соответствующие агрегатным" + +#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "функция перехода %s должна возвращать тип %s" + +#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#, c-format +msgid "" +"must not omit initial value when transition function is strict and " +"transition type is not compatible with input type" +msgstr "" +"нельзя опускать начальное значение, когда функция перехода объявлена как " +"STRICT и переходный тип несовместим с входным типом" + +#: catalog/pg_aggregate.c:334 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "обратная функция перехода %s должна возвращать тип %s" + +#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2852 +#, c-format +msgid "" +"strictness of aggregate's forward and inverse transition functions must match" +msgstr "" +"прямая и обратная функции перехода агрегата должны иметь одинаковую строгость" + +#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:553 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "" +"финальная функция с дополнительными аргументами не должна объявляться как " +"строгая (STRICT)" + +#: catalog/pg_aggregate.c:426 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "комбинирующая функция %s должна возвращать тип %s" + +#: catalog/pg_aggregate.c:438 executor/nodeAgg.c:4197 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "" +"комбинирующая функция с переходным типом %s не должна объявляться как " +"строгая (STRICT)" + +#: catalog/pg_aggregate.c:457 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "функция сериализации %s должна возвращать тип %s" + +#: catalog/pg_aggregate.c:478 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "функция десериализации %s должна возвращать тип %s" + +#: catalog/pg_aggregate.c:497 catalog/pg_proc.c:186 catalog/pg_proc.c:220 +#, c-format +msgid "cannot determine result data type" +msgstr "не удалось определить тип результата" + +#: catalog/pg_aggregate.c:512 catalog/pg_proc.c:199 catalog/pg_proc.c:228 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "небезопасное использование псевдотипа \"internal\"" + +#: catalog/pg_aggregate.c:566 +#, c-format +msgid "" +"moving-aggregate implementation returns type %s, but plain implementation " +"returns type %s" +msgstr "" +"реализация движимого агрегата возвращает тип %s, но простая реализация " +"возвращает %s" + +#: catalog/pg_aggregate.c:577 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "" +"оператор сортировки можно указать только для агрегатных функций с одним " +"аргументом" + +#: catalog/pg_aggregate.c:704 catalog/pg_proc.c:374 +#, c-format +msgid "cannot change routine kind" +msgstr "тип подпрограммы изменить нельзя" + +#: catalog/pg_aggregate.c:706 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "\"%s\" — обычная агрегатная функция." + +#: catalog/pg_aggregate.c:708 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "\"%s\" — сортирующая агрегатная функция." + +#: catalog/pg_aggregate.c:710 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "\"%s\" — гипотезирующая агрегатная функция." + +#: catalog/pg_aggregate.c:715 +#, c-format +msgid "cannot change number of direct arguments of an aggregate function" +msgstr "изменить число непосредственных аргументов агрегатной функции нельзя" + +#: catalog/pg_aggregate.c:870 commands/functioncmds.c:667 +#: commands/typecmds.c:1658 commands/typecmds.c:1704 commands/typecmds.c:1756 +#: commands/typecmds.c:1793 commands/typecmds.c:1827 commands/typecmds.c:1861 +#: commands/typecmds.c:1895 commands/typecmds.c:1972 commands/typecmds.c:2014 +#: parser/parse_func.c:414 parser/parse_func.c:443 parser/parse_func.c:468 +#: parser/parse_func.c:482 parser/parse_func.c:602 parser/parse_func.c:622 +#: parser/parse_func.c:2129 parser/parse_func.c:2320 +#, c-format +msgid "function %s does not exist" +msgstr "функция %s не существует" + +#: catalog/pg_aggregate.c:876 +#, c-format +msgid "function %s returns a set" +msgstr "функция %s возвращает множество" + +#: catalog/pg_aggregate.c:891 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "" +"для использования в этой агрегатной функции функция %s должна принимать " +"VARIADIC ANY" + +#: catalog/pg_aggregate.c:915 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "функции %s требуется приведение типов во время выполнения" + +#: catalog/pg_cast.c:67 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "приведение типа %s к типу %s уже существует" + +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "правило сортировки \"%s\" уже существует, пропускается" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "" +"правило сортировки \"%s\" для кодировки \"%s\" уже существует, пропускается" + +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "правило сортировки \"%s\" уже существует" + +#: catalog/pg_collation.c:105 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "правило сортировки \"%s\" для кодировки \"%s\" уже существует" + +#: catalog/pg_constraint.c:676 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "ограничение \"%s\" для домена %s уже существует" + +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "ограничение \"%s\" для таблицы \"%s\" не существует" + +#: catalog/pg_constraint.c:1056 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "ограничение \"%s\" для домена %s не существует" + +#: catalog/pg_conversion.c:67 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "преобразование \"%s\" уже существует" + +#: catalog/pg_conversion.c:80 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "преобразование по умолчанию из %s в %s уже существует" + +#: catalog/pg_depend.c:162 commands/extension.c:3324 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "%s уже относится к расширению \"%s\"" + +#: catalog/pg_depend.c:538 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "" +"ликвидировать зависимость от объекта %s нельзя, так как это системный объект" + +#: catalog/pg_enum.c:127 catalog/pg_enum.c:230 catalog/pg_enum.c:525 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "неверная метка в перечислении \"%s\"" + +#: catalog/pg_enum.c:128 catalog/pg_enum.c:231 catalog/pg_enum.c:526 +#, c-format +msgid "Labels must be %d characters or less." +msgstr "Длина метки не должна превышать %d байт." + +#: catalog/pg_enum.c:259 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "метка перечисления \"%s\" уже существует, пропускается" + +#: catalog/pg_enum.c:266 catalog/pg_enum.c:569 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "метка перечисления \"%s\" уже существует" + +#: catalog/pg_enum.c:321 catalog/pg_enum.c:564 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "в перечислении нет метки\"%s\"" + +#: catalog/pg_enum.c:379 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "значение OID в pg_enum не задано в режиме двоичного обновления" + +#: catalog/pg_enum.c:389 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "" +"конструкция ALTER TYPE ADD BEFORE/AFTER несовместима с двоичным обновлением " +"данных" + +#: catalog/pg_namespace.c:64 commands/schemacmds.c:265 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "схема \"%s\" уже существует" + +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "имя \"%s\" недопустимо для оператора" + +#: catalog/pg_operator.c:370 +#, c-format +msgid "only binary operators can have commutators" +msgstr "коммутативную операцию можно определить только для бинарных операторов" + +#: catalog/pg_operator.c:374 commands/operatorcmds.c:495 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "" +"функцию оценки соединения можно определить только для бинарных операторов" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can merge join" +msgstr "" +"поддержку соединения слиянием можно обозначить только для бинарных операторов" + +#: catalog/pg_operator.c:382 +#, c-format +msgid "only binary operators can hash" +msgstr "поддержку хеша можно обозначить только для бинарных операторов" + +#: catalog/pg_operator.c:393 +#, c-format +msgid "only boolean operators can have negators" +msgstr "обратную операцию можно определить только для логических операторов" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:503 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "" +"функцию оценки ограничения можно определить только для логических операторов" + +#: catalog/pg_operator.c:401 commands/operatorcmds.c:507 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "" +"функцию оценки соединения можно определить только для логических операторов" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can merge join" +msgstr "" +"поддержку соединения слиянием можно обозначить только для логических " +"операторов" + +#: catalog/pg_operator.c:409 +#, c-format +msgid "only boolean operators can hash" +msgstr "поддержку хеша можно обозначить только для логических операторов" + +#: catalog/pg_operator.c:421 +#, c-format +msgid "operator %s already exists" +msgstr "оператор %s уже существует" + +#: catalog/pg_operator.c:621 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "" +"оператор не может быть обратным к себе или собственным оператором сортировки" + +#: catalog/pg_proc.c:127 parser/parse_func.c:2191 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "функции не могут иметь больше %d аргумента" +msgstr[1] "функции не могут иметь больше %d аргументов" +msgstr[2] "функции не могут иметь больше %d аргументов" + +#: catalog/pg_proc.c:364 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "функция \"%s\" с аргументами таких типов уже существует" + +#: catalog/pg_proc.c:376 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" — агрегатная функция." + +#: catalog/pg_proc.c:378 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\" — функция." + +#: catalog/pg_proc.c:380 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\" — процедура." + +#: catalog/pg_proc.c:382 +#, c-format +msgid "\"%s\" is a window function." +msgstr "\"%s\" — оконная функция." + +#: catalog/pg_proc.c:402 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "определить выходные параметры для процедуры нельзя" + +#: catalog/pg_proc.c:403 catalog/pg_proc.c:433 +#, c-format +msgid "cannot change return type of existing function" +msgstr "изменить тип возврата существующей функции нельзя" + +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:409 catalog/pg_proc.c:436 catalog/pg_proc.c:481 +#: catalog/pg_proc.c:507 catalog/pg_proc.c:533 +#, c-format +msgid "Use %s %s first." +msgstr "Сначала выполните %s %s." + +#: catalog/pg_proc.c:434 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "Параметры OUT определяют другой тип строки." + +#: catalog/pg_proc.c:478 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "изменить имя входного параметра \"%s\" нельзя" + +#: catalog/pg_proc.c:505 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "" +"для существующей функции нельзя убрать значения параметров по умолчанию" + +#: catalog/pg_proc.c:531 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "" +"для существующего значения параметра по умолчанию нельзя изменить тип данных" + +#: catalog/pg_proc.c:748 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "встроенной функции \"%s\" нет" + +#: catalog/pg_proc.c:846 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "SQL-функции не могут возвращать тип %s" + +#: catalog/pg_proc.c:861 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "SQL-функции не могут иметь аргументы типа %s" + +#: catalog/pg_proc.c:954 executor/functions.c:1440 +#, c-format +msgid "SQL function \"%s\"" +msgstr "SQL-функция \"%s\"" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Only tables can be added to publications." +msgstr "В публикации можно добавлять только таблицы." + +#: catalog/pg_publication.c:65 +#, c-format +msgid "\"%s\" is a system table" +msgstr "\"%s\" - это системная таблица" + +#: catalog/pg_publication.c:67 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "Системные таблицы нельзя добавлять в публикации." + +#: catalog/pg_publication.c:73 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "реплицировать таблицу \"%s\" нельзя" + +#: catalog/pg_publication.c:75 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "Временные и нежурналируемые отношения не поддерживают репликацию." + +#: catalog/pg_publication.c:174 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "отношение \"%s\" уже включено в публикацию \"%s\"" + +#: catalog/pg_publication.c:470 commands/publicationcmds.c:451 +#: commands/publicationcmds.c:762 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "публикация \"%s\" не существует" + +#: catalog/pg_shdepend.c:832 +#, c-format +msgid "" +"\n" +"and objects in %d other database (see server log for list)" +msgid_plural "" +"\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "" +"\n" +"и объекты в %d базе данных (см. список в протоколе сервера)" +msgstr[1] "" +"\n" +"и объекты в %d других базах данных (см. список в протоколе сервера)" +msgstr[2] "" +"\n" +"и объекты в %d других базах данных (см. список в протоколе сервера)" + +#: catalog/pg_shdepend.c:1138 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "роль %u удалена другим процессом" + +#: catalog/pg_shdepend.c:1150 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "табличное пространство %u удалено другим процессом" + +#: catalog/pg_shdepend.c:1164 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "база данных %u удалена другим процессом" + +#: catalog/pg_shdepend.c:1209 +#, c-format +msgid "owner of %s" +msgstr "владелец объекта %s" + +#: catalog/pg_shdepend.c:1211 +#, c-format +msgid "privileges for %s" +msgstr "права доступа к объекту %s" + +#: catalog/pg_shdepend.c:1213 +#, c-format +msgid "target of %s" +msgstr "субъект политики %s" + +#: catalog/pg_shdepend.c:1215 +#, c-format +msgid "tablespace for %s" +msgstr "табличное пространство для %s" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1223 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%d объект (%s)" +msgstr[1] "%d объекта (%s)" +msgstr[2] "%d объектов (%s)" + +#: catalog/pg_shdepend.c:1334 +#, c-format +msgid "" +"cannot drop objects owned by %s because they are required by the database " +"system" +msgstr "" +"удалить объекты, принадлежащие роли %s, нельзя, так как они нужны системе " +"баз данных" + +#: catalog/pg_shdepend.c:1481 +#, c-format +msgid "" +"cannot reassign ownership of objects owned by %s because they are required " +"by the database system" +msgstr "" +"изменить владельца объектов, принадлежащих роли %s, нельзя, так как они " +"нужны системе баз данных" + +#: catalog/pg_subscription.c:171 commands/subscriptioncmds.c:644 +#: commands/subscriptioncmds.c:858 commands/subscriptioncmds.c:1080 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "подписка \"%s\" не существует" + +#: catalog/pg_type.c:131 catalog/pg_type.c:468 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "значение OID в pg_type не задано в режиме двоичного обновления" + +#: catalog/pg_type.c:249 +#, c-format +msgid "invalid type internal size %d" +msgstr "неверный внутренний размер типа: %d" + +#: catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:281 +#: catalog/pg_type.c:290 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "" +"выравнивание \"%c\" не подходит для типа, передаваемого по значению (с " +"размером: %d)" + +#: catalog/pg_type.c:297 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "внутренний размер %d не подходит для типа, передаваемого по значению" + +#: catalog/pg_type.c:307 catalog/pg_type.c:313 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "выравнивание \"%c\" не подходит для типа переменной длины" + +#: catalog/pg_type.c:321 commands/typecmds.c:3727 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "для типов постоянного размера применим только режим хранения PLAIN" + +#: catalog/pg_type.c:839 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "не удалось сформировать имя типа массива для типа \"%s\"" + +#: catalog/storage.c:450 storage/buffer/bufmgr.c:935 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "неверная страница в блоке %u отношения %s" + +#: catalog/toasting.c:106 commands/indexcmds.c:639 commands/tablecmds.c:5640 +#: commands/tablecmds.c:15598 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "\"%s\" - это не таблица и не материализованное представление" + +#: commands/aggregatecmds.c:171 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "гипотезирующими могут быть только сортирующие агрегатные функции" + +#: commands/aggregatecmds.c:196 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "нераспознанный атрибут \"%s\" в определении агрегатной функции" + +#: commands/aggregatecmds.c:206 +#, c-format +msgid "aggregate stype must be specified" +msgstr "в определении агрегата требуется stype" + +#: commands/aggregatecmds.c:210 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "в определении агрегата требуется sfunc" + +#: commands/aggregatecmds.c:222 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "в определении агрегата требуется msfunc, если указан mstype" + +#: commands/aggregatecmds.c:226 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "в определении агрегата требуется minvfunc, если указан mstype" + +#: commands/aggregatecmds.c:233 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "msfunc для агрегата не должна указываться без mstype" + +#: commands/aggregatecmds.c:237 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "minvfunc для агрегата не должна указываться без mstype" + +#: commands/aggregatecmds.c:241 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "mfinalfunc для агрегата не должна указываться без mstype" + +#: commands/aggregatecmds.c:245 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "msspace для агрегата не должна указываться без mstype" + +#: commands/aggregatecmds.c:249 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "minitcond для агрегата не должна указываться без mstype" + +#: commands/aggregatecmds.c:278 +#, c-format +msgid "aggregate input type must be specified" +msgstr "в определении агрегата требуется входной тип" + +#: commands/aggregatecmds.c:308 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "в определении агрегата с указанием входного типа не нужен базовый тип" + +#: commands/aggregatecmds.c:349 commands/aggregatecmds.c:390 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "переходным типом агрегата не может быть %s" + +#: commands/aggregatecmds.c:361 +#, c-format +msgid "" +"serialization functions may be specified only when the aggregate transition " +"data type is %s" +msgstr "" +"функции сериализации могут задаваться, только когда переходный тип данных " +"агрегата - %s" + +#: commands/aggregatecmds.c:371 +#, c-format +msgid "" +"must specify both or neither of serialization and deserialization functions" +msgstr "функции сериализации и десериализации должны задаваться совместно" + +#: commands/aggregatecmds.c:436 commands/functioncmds.c:615 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "" +"параметр \"parallel\" должен иметь значение SAFE, RESTRICTED или UNSAFE" + +#: commands/aggregatecmds.c:492 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "" +"параметр \"%s\" должен иметь характеристику READ_ONLY, SHAREABLE или " +"READ_WRITE" + +#: commands/alter.c:84 commands/event_trigger.c:174 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "событийный триггер \"%s\" уже существует" + +#: commands/alter.c:87 commands/foreigncmds.c:597 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "обёртка сторонних данных \"%s\" уже существует" + +#: commands/alter.c:90 commands/foreigncmds.c:903 +#, c-format +msgid "server \"%s\" already exists" +msgstr "сервер \"%s\" уже существует" + +#: commands/alter.c:93 commands/proclang.c:132 +#, c-format +msgid "language \"%s\" already exists" +msgstr "язык \"%s\" уже существует" + +#: commands/alter.c:96 commands/publicationcmds.c:183 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "публикация \"%s\" уже существует" + +#: commands/alter.c:99 commands/subscriptioncmds.c:371 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "подписка \"%s\" уже существует" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "преобразование \"%s\" уже существует в схеме \"%s\"" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "объект статистики \"%s\" уже существует в схеме \"%s\"" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr "анализатор текстового поиска \"%s\" уже существует в схеме \"%s\"" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "словарь текстового поиска \"%s\" уже существует в схеме \"%s\"" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "шаблон текстового поиска \"%s\" уже существует в схеме \"%s\"" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "конфигурация текстового поиска \"%s\" уже существует в схеме \"%s\"" + +#: commands/alter.c:215 +#, c-format +msgid "must be superuser to rename %s" +msgstr "переименовать \"%s\" может только суперпользователь" + +#: commands/alter.c:744 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "для назначения схемы объекта %s нужно быть суперпользователем" + +#: commands/amcmds.c:60 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "нет прав на создание метода доступа \"%s\"" + +#: commands/amcmds.c:62 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "Для создания метода доступа нужно быть суперпользователем." + +#: commands/amcmds.c:71 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "метод доступа \"%s\" уже существует" + +#: commands/amcmds.c:130 +#, c-format +msgid "must be superuser to drop access methods" +msgstr "для удаления методов доступа нужно быть суперпользователем" + +#: commands/amcmds.c:181 commands/indexcmds.c:188 commands/indexcmds.c:790 +#: commands/opclasscmds.c:373 commands/opclasscmds.c:793 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "метод доступа \"%s\" не существует" + +#: commands/amcmds.c:270 +#, c-format +msgid "handler function is not specified" +msgstr "не указана функция-обработчик" + +#: commands/amcmds.c:291 commands/event_trigger.c:183 +#: commands/foreigncmds.c:489 commands/proclang.c:79 commands/trigger.c:687 +#: parser/parse_clause.c:941 +#, c-format +msgid "function %s must return type %s" +msgstr "функция %s должна возвращать тип %s" + +#: commands/analyze.c:226 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "\"%s\" пропускается --- анализировать эту стороннюю таблицу нельзя" + +#: commands/analyze.c:243 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "" +"\"%s\" пропускается --- анализировать не таблицы или специальные системные " +"таблицы нельзя" + +#: commands/analyze.c:329 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "анализируется дерево наследования \"%s.%s\"" + +#: commands/analyze.c:334 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "анализируется \"%s.%s\"" + +#: commands/analyze.c:394 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "столбец \"%s\" отношения \"%s\" указан неоднократно" + +#: commands/analyze.c:700 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" +msgstr "автоматический анализ таблицы \"%s.%s.%s\"; нагрузка системы: %s" + +#: commands/analyze.c:1169 +#, c-format +msgid "" +"\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead " +"rows; %d rows in sample, %.0f estimated total rows" +msgstr "" +"\"%s\": просканировано страниц: %d из %u, они содержат \"живых\" строк: " +"%.0f, \"мёртвых\" строк: %.0f; строк в выборке: %d, примерное общее число " +"строк: %.0f" + +#: commands/analyze.c:1249 +#, c-format +msgid "" +"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " +"contains no child tables" +msgstr "" +"пропускается анализ дерева наследования \"%s.%s\" --- это дерево " +"наследования не содержит дочерних таблиц" + +#: commands/analyze.c:1347 +#, c-format +msgid "" +"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " +"contains no analyzable child tables" +msgstr "" +"пропускается анализ дерева наследования \"%s.%s\" --- это дерево " +"наследования не содержит анализируемых дочерних таблиц" + +#: commands/async.c:643 +#, c-format +msgid "channel name cannot be empty" +msgstr "имя канала не может быть пустым" + +#: commands/async.c:649 +#, c-format +msgid "channel name too long" +msgstr "слишком длинное имя канала" + +#: commands/async.c:654 +#, c-format +msgid "payload string too long" +msgstr "слишком длинная строка сообщения-нагрузки" + +#: commands/async.c:873 +#, c-format +msgid "" +"cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "" +"выполнить PREPARE для транзакции с командами LISTEN, UNLISTEN или NOTIFY " +"нельзя" + +#: commands/async.c:979 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "слишком много уведомлений в очереди NOTIFY" + +#: commands/async.c:1650 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "очередь NOTIFY заполнена на %.0f%%" + +#: commands/async.c:1652 +#, c-format +msgid "" +"The server process with PID %d is among those with the oldest transactions." +msgstr "" +"В число серверных процессов с самыми старыми транзакциями входит процесс с " +"PID %d." + +#: commands/async.c:1655 +#, c-format +msgid "" +"The NOTIFY queue cannot be emptied until that process ends its current " +"transaction." +msgstr "" +"Очередь NOTIFY можно будет освободить, только когда этот процесс завершит " +"текущую транзакцию." + +#: commands/cluster.c:125 commands/cluster.c:362 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "кластеризовать временные таблицы других сеансов нельзя" + +#: commands/cluster.c:133 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "кластеризовать секционированную таблицу нельзя" + +#: commands/cluster.c:151 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "таблица \"%s\" ранее не кластеризовалась по какому-либо индексу" + +#: commands/cluster.c:165 commands/tablecmds.c:12871 commands/tablecmds.c:14681 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "индекс \"%s\" для таблицы \"%s\" не существует" + +#: commands/cluster.c:351 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "кластеризовать разделяемый каталог нельзя" + +#: commands/cluster.c:366 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "очищать временные таблицы других сеансов нельзя" + +#: commands/cluster.c:432 commands/tablecmds.c:14691 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "\"%s\" не является индексом таблицы \"%s\"" + +#: commands/cluster.c:440 +#, c-format +msgid "" +"cannot cluster on index \"%s\" because access method does not support " +"clustering" +msgstr "" +"кластеризация по индексу \"%s\" невозможна, её не поддерживает метод доступа" + +#: commands/cluster.c:452 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "кластеризовать по частичному индексу \"%s\" нельзя" + +#: commands/cluster.c:466 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "нельзя кластеризовать таблицу по неверному индексу \"%s\"" + +#: commands/cluster.c:490 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "пометить индекс как кластеризованный в секционированной таблице нельзя" + +#: commands/cluster.c:863 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr "кластеризация \"%s.%s\" путём сканирования индекса \"%s\"" + +#: commands/cluster.c:869 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "" +"кластеризация \"%s.%s\" путём последовательного сканирования и сортировки" + +#: commands/cluster.c:900 +#, c-format +msgid "" +"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "" +"\"%s\": найдено удаляемых версий строк: %.0f, неудаляемых - %.0f, " +"просмотрено страниц: %u" + +#: commands/cluster.c:904 +#, c-format +msgid "" +"%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "" +"В данный момент нельзя удалить \"мёртвых\" строк %.0f.\n" +"%s." + +#: commands/collationcmds.c:105 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "атрибут COLLATION \"%s\" не распознан" + +#: commands/collationcmds.c:148 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "правило сортировки \"default\" нельзя скопировать" + +#: commands/collationcmds.c:181 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "нераспознанный поставщик правил сортировки: %s" + +#: commands/collationcmds.c:190 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "необходимо указать параметр \"lc_collate\"" + +#: commands/collationcmds.c:195 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "необходимо указать параметр \"lc_ctype\"" + +#: commands/collationcmds.c:205 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "" +"недетерминированные правила сортировки с этим провайдером не поддерживаются" + +#: commands/collationcmds.c:265 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "" +"правило сортировки \"%s\" для кодировки \"%s\" уже существует в схеме \"%s\"" + +#: commands/collationcmds.c:276 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "правило сортировки \"%s\" уже существует в схеме \"%s\"" + +#: commands/collationcmds.c:324 +#, c-format +msgid "changing version from %s to %s" +msgstr "изменение версии с %s на %s" + +#: commands/collationcmds.c:339 +#, c-format +msgid "version has not changed" +msgstr "версия не была изменена" + +#: commands/collationcmds.c:470 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "не удалось получить из названия локали \"%s\" метку языка: %s" + +#: commands/collationcmds.c:531 +#, c-format +msgid "must be superuser to import system collations" +msgstr "" +"импортировать системные правила сортировки может только суперпользователь" + +#: commands/collationcmds.c:554 commands/copy.c:1894 commands/copy.c:3480 +#: libpq/be-secure-common.c:81 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "не удалось выполнить команду \"%s\": %m" + +#: commands/collationcmds.c:685 +#, c-format +msgid "no usable system locales were found" +msgstr "пригодные системные локали не найдены" + +#: commands/comment.c:61 commands/dbcommands.c:841 commands/dbcommands.c:1037 +#: commands/dbcommands.c:1150 commands/dbcommands.c:1340 +#: commands/dbcommands.c:1588 commands/dbcommands.c:1702 +#: commands/dbcommands.c:2142 utils/init/postinit.c:877 +#: utils/init/postinit.c:982 utils/init/postinit.c:999 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "база данных \"%s\" не существует" + +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:973 +#, c-format +msgid "" +"\"%s\" is not a table, view, materialized view, composite type, or foreign " +"table" +msgstr "" +"\"%s\" - это не таблица, представление, мат. представление, составной тип " +"или сторонняя таблица" + +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1923 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "функция \"%s\" была вызвана не менеджером триггеров" + +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1932 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "функция \"%s\" должна запускаться в триггере AFTER для строк" + +#: commands/constraint.c:84 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "функция \"%s\" должна запускаться для INSERT или UPDATE" + +#: commands/conversioncmds.c:66 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "исходная кодировка \"%s\" не существует" + +#: commands/conversioncmds.c:73 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "целевая кодировка \"%s\" не существует" + +#: commands/conversioncmds.c:86 +#, c-format +msgid "encoding conversion to or from \"SQL_ASCII\" is not supported" +msgstr "преобразование кодировки из/в \"SQL_ASCII\" не поддерживается" + +#: commands/conversioncmds.c:99 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "функция преобразования кодировки %s должна возвращать тип %s" + +#: commands/copy.c:426 commands/copy.c:460 +#, c-format +msgid "COPY BINARY is not supported to stdout or from stdin" +msgstr "COPY BINARY не поддерживает стандартный вывод (stdout) и ввод (stdin)" + +#: commands/copy.c:560 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "не удалось записать в канал программы COPY: %m" + +#: commands/copy.c:565 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "не удалось записать в файл COPY: %m" + +#: commands/copy.c:578 +#, c-format +msgid "connection lost during COPY to stdout" +msgstr "в процессе вывода данных COPY в stdout потеряно соединение" + +#: commands/copy.c:622 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "не удалось прочитать файл COPY: %m" + +#: commands/copy.c:640 commands/copy.c:661 commands/copy.c:665 +#: tcop/postgres.c:344 tcop/postgres.c:380 tcop/postgres.c:407 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "неожиданный обрыв соединения с клиентом при открытой транзакции" + +#: commands/copy.c:678 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "ошибка при вводе данных COPY из stdin: %s" + +#: commands/copy.c:694 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "неожиданный тип сообщения 0x%02X при вводе данных COPY из stdin" + +#: commands/copy.c:861 +#, c-format +msgid "" +"must be superuser or a member of the pg_execute_server_program role to COPY " +"to or from an external program" +msgstr "" +"для использования COPY с внешними программами нужно быть суперпользователем " +"или членом роли pg_execute_server_program" + +#: commands/copy.c:862 commands/copy.c:871 commands/copy.c:878 +#, c-format +msgid "" +"Anyone can COPY to stdout or from stdin. psql's \\copy command also works " +"for anyone." +msgstr "" +"Не имея административных прав, можно использовать COPY с stdout и stdin (а " +"также команду psql \\copy)." + +#: commands/copy.c:870 +#, c-format +msgid "" +"must be superuser or a member of the pg_read_server_files role to COPY from " +"a file" +msgstr "" +"для выполнения COPY с чтением файла нужно быть суперпользователем или членом " +"роли pg_read_server_files" + +#: commands/copy.c:877 +#, c-format +msgid "" +"must be superuser or a member of the pg_write_server_files role to COPY to a " +"file" +msgstr "" +"для выполнения COPY с записью в файл нужно быть суперпользователем или " +"членом роли pg_write_server_files" + +#: commands/copy.c:963 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM не поддерживается с защитой на уровне строк." + +#: commands/copy.c:964 +#, c-format +msgid "Use INSERT statements instead." +msgstr "Используйте операторы INSERT." + +#: commands/copy.c:1146 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "формат \"%s\" для COPY не распознан" + +#: commands/copy.c:1217 commands/copy.c:1233 commands/copy.c:1248 +#: commands/copy.c:1270 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "аргументом параметра \"%s\" должен быть список имён столбцов" + +#: commands/copy.c:1285 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "аргументом параметра \"%s\" должно быть название допустимой кодировки" + +#: commands/copy.c:1292 commands/dbcommands.c:253 commands/dbcommands.c:1536 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "параметр \"%s\" не распознан" + +#: commands/copy.c:1304 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "в режиме BINARY нельзя указывать DELIMITER" + +#: commands/copy.c:1309 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "в режиме BINARY нельзя указывать NULL" + +#: commands/copy.c:1331 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "разделитель для COPY должен быть однобайтным символом" + +#: commands/copy.c:1338 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "" +"разделителем для COPY не может быть символ новой строки или возврата каретки" + +#: commands/copy.c:1344 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "" +"представление NULL для COPY не может включать символ новой строки или " +"возврата каретки" + +#: commands/copy.c:1361 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "\"%s\" не может быть разделителем для COPY" + +#: commands/copy.c:1367 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "COPY HEADER можно использовать только в режиме CSV" + +#: commands/copy.c:1373 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "определить кавычки для COPY можно только в режиме CSV" + +#: commands/copy.c:1378 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "символ кавычек для COPY должен быть однобайтным" + +#: commands/copy.c:1383 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "символ кавычек для COPY должен отличаться от разделителя" + +#: commands/copy.c:1389 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "определить спецсимвол для COPY можно только в режиме CSV" + +#: commands/copy.c:1394 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "спецсимвол для COPY должен быть однобайтным" + +#: commands/copy.c:1400 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "параметр force quote для COPY можно использовать только в режиме CSV" + +#: commands/copy.c:1404 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "параметр force quote для COPY можно использовать только с COPY TO" + +#: commands/copy.c:1410 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "" +"параметр force not null для COPY можно использовать только в режиме CSV" + +#: commands/copy.c:1414 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "параметр force not null для COPY можно использовать только с COPY FROM" + +#: commands/copy.c:1420 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "параметр force null для COPY можно использовать только в режиме CSV" + +#: commands/copy.c:1425 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "параметр force null для COPY можно использовать только с COPY FROM" + +#: commands/copy.c:1431 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "разделитель для COPY не должен присутствовать в представлении NULL" + +#: commands/copy.c:1438 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "символ кавычек в CSV не должен присутствовать в представлении NULL" + +#: commands/copy.c:1524 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "правила DO INSTEAD NOTHING не поддерживаются с COPY" + +#: commands/copy.c:1538 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "условные правила DO INSTEAD не поддерживаются с COPY" + +#: commands/copy.c:1542 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "правила DO ALSO не поддерживаются с COPY" + +#: commands/copy.c:1547 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "составные правила DO INSTEAD не поддерживаются с COPY" + +#: commands/copy.c:1557 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO) не поддерживается" + +#: commands/copy.c:1574 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "в запросе COPY должно быть предложение RETURNING" + +#: commands/copy.c:1603 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "отношение, задействованное в операторе COPY, изменилось" + +#: commands/copy.c:1662 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "столбец FORCE_QUOTE \"%s\" не фигурирует в COPY" + +#: commands/copy.c:1685 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "столбец FORCE_NOT_NULL \"%s\" не фигурирует в COPY" + +#: commands/copy.c:1708 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "столбец FORCE_NULL \"%s\" не фигурирует в COPY" + +#: commands/copy.c:1774 libpq/be-secure-common.c:105 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "не удалось закрыть канал сообщений с внешней командой: %m" + +#: commands/copy.c:1789 +#, c-format +msgid "program \"%s\" failed" +msgstr "сбой программы \"%s\"" + +#: commands/copy.c:1840 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "копировать из представления \"%s\" нельзя" + +#: commands/copy.c:1842 commands/copy.c:1848 commands/copy.c:1854 +#: commands/copy.c:1865 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "Попробуйте вариацию COPY (SELECT ...) TO." + +#: commands/copy.c:1846 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "копировать из материализованного представления \"%s\" нельзя" + +#: commands/copy.c:1852 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "копировать из сторонней таблицы \"%s\" нельзя" + +#: commands/copy.c:1858 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "копировать из последовательности \"%s\" нельзя" + +#: commands/copy.c:1863 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "копировать из секционированной таблицы \"%s\" нельзя" + +#: commands/copy.c:1869 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "копировать из отношения \"%s\", не являющегося таблицей, нельзя" + +#: commands/copy.c:1909 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "при выполнении COPY в файл нельзя указывать относительный путь" + +#: commands/copy.c:1928 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "не удалось открыть файл \"%s\" для записи: %m" + +#: commands/copy.c:1931 +#, c-format +msgid "" +"COPY TO instructs the PostgreSQL server process to write a file. You may " +"want a client-side facility such as psql's \\copy." +msgstr "" +"COPY TO указывает серверному процессу PostgreSQL записать данные в файл. " +"Возможно, на самом деле вам нужно клиентское средство, например, \\copy в " +"psql." + +#: commands/copy.c:1944 commands/copy.c:3511 +#, c-format +msgid "\"%s\" is a directory" +msgstr "\"%s\" - это каталог" + +#: commands/copy.c:2246 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, строка %s, столбец %s" + +#: commands/copy.c:2250 commands/copy.c:2297 +#, c-format +msgid "COPY %s, line %s" +msgstr "COPY %s, строка %s" + +#: commands/copy.c:2261 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, строка %s, столбец %s: \"%s\"" + +#: commands/copy.c:2269 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, строка %s, столбец %s: значение NULL" + +#: commands/copy.c:2291 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, строка %s: \"%s\"" + +#: commands/copy.c:2692 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "копировать в представление \"%s\" нельзя" + +#: commands/copy.c:2694 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "" +"Чтобы представление допускало копирование данных в него, установите триггер " +"INSTEAD OF INSERT." + +#: commands/copy.c:2698 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "копировать в материализованное представление \"%s\" нельзя" + +#: commands/copy.c:2703 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "копировать в последовательность \"%s\" нельзя" + +#: commands/copy.c:2708 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "копировать в отношение \"%s\", не являющееся таблицей, нельзя" + +#: commands/copy.c:2748 +#, c-format +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "выполнить COPY FREEZE в секционированной таблице нельзя" + +#: commands/copy.c:2763 +#, c-format +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "выполнить COPY FREEZE нельзя из-за предыдущей активности в транзакции" + +#: commands/copy.c:2769 +#, c-format +msgid "" +"cannot perform COPY FREEZE because the table was not created or truncated in " +"the current subtransaction" +msgstr "" +"выполнить COPY FREEZE нельзя, так как таблица не была создана или усечена в " +"текущей подтранзакции" + +#: commands/copy.c:3498 +#, c-format +msgid "" +"COPY FROM instructs the PostgreSQL server process to read a file. You may " +"want a client-side facility such as psql's \\copy." +msgstr "" +"COPY FROM указывает серверному процессу PostgreSQL прочитать данные из " +"файла. Возможно, на самом деле вам нужно клиентское средство, например, " +"\\copy в psql." + +#: commands/copy.c:3526 +#, c-format +msgid "COPY file signature not recognized" +msgstr "подпись COPY-файла не распознана" + +#: commands/copy.c:3531 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "неверный заголовок файла COPY (отсутствуют флаги)" + +#: commands/copy.c:3535 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "неверный заголовок файла COPY (WITH OIDS)" + +#: commands/copy.c:3540 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "не распознаны важные флаги в заголовке файла COPY" + +#: commands/copy.c:3546 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "неверный заголовок файла COPY (отсутствует длина)" + +#: commands/copy.c:3553 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "неверный заголовок файла COPY (неправильная длина)" + +#: commands/copy.c:3671 commands/copy.c:4344 commands/copy.c:4574 +#, c-format +msgid "extra data after last expected column" +msgstr "лишние данные после содержимого последнего столбца" + +#: commands/copy.c:3685 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "нет данных для столбца \"%s\"" + +#: commands/copy.c:3768 +#, c-format +msgid "received copy data after EOF marker" +msgstr "после маркера конца файла продолжаются данные COPY" + +#: commands/copy.c:3775 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "количество полей в строке: %d, ожидалось: %d" + +#: commands/copy.c:4095 commands/copy.c:4112 +#, c-format +msgid "literal carriage return found in data" +msgstr "в данных обнаружен явный возврат каретки" + +#: commands/copy.c:4096 commands/copy.c:4113 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "в данных обнаружен возврат каретки не в кавычках" + +#: commands/copy.c:4098 commands/copy.c:4115 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "Представьте возврат каретки как \"\\r\"." + +#: commands/copy.c:4099 commands/copy.c:4116 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "Заключите возврат каретки в кавычки CSV." + +#: commands/copy.c:4128 +#, c-format +msgid "literal newline found in data" +msgstr "в данных обнаружен явный символ новой строки" + +#: commands/copy.c:4129 +#, c-format +msgid "unquoted newline found in data" +msgstr "в данных обнаружен явный символ новой строки не в кавычках" + +#: commands/copy.c:4131 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "Представьте символ новой строки как \"\\n\"." + +#: commands/copy.c:4132 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "Заключите символ новой строки в кавычки CSV." + +#: commands/copy.c:4178 commands/copy.c:4214 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "маркер \"конец копии\" не соответствует предыдущему стилю новой строки" + +#: commands/copy.c:4187 commands/copy.c:4203 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "маркер \"конец копии\" испорчен" + +#: commands/copy.c:4658 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "незавершённое поле в кавычках CSV" + +#: commands/copy.c:4735 commands/copy.c:4754 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "неожиданный конец данных COPY" + +#: commands/copy.c:4744 +#, c-format +msgid "invalid field size" +msgstr "неверный размер поля" + +#: commands/copy.c:4767 +#, c-format +msgid "incorrect binary data format" +msgstr "неверный двоичный формат данных" + +#: commands/copy.c:5075 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "столбец \"%s\" — генерируемый" + +#: commands/copy.c:5077 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "Генерируемые столбцы нельзя использовать в COPY." + +#: commands/copy.c:5092 commands/indexcmds.c:1701 commands/statscmds.c:224 +#: commands/tablecmds.c:2176 commands/tablecmds.c:2795 +#: commands/tablecmds.c:3182 parser/parse_relation.c:3507 +#: parser/parse_relation.c:3527 utils/adt/tsvector_op.c:2668 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "столбец \"%s\" не существует" + +#: commands/copy.c:5099 commands/tablecmds.c:2202 commands/trigger.c:885 +#: parser/parse_target.c:1052 parser/parse_target.c:1063 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "столбец \"%s\" указан неоднократно" + +#: commands/createas.c:215 commands/createas.c:497 +#, c-format +msgid "too many column names were specified" +msgstr "указано слишком много имён столбцов" + +#: commands/createas.c:539 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "политики для этой команды ещё не реализованы" + +#: commands/dbcommands.c:246 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATION больше не поддерживается" + +#: commands/dbcommands.c:247 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "Рассмотрите возможность использования табличных пространств." + +#: commands/dbcommands.c:261 +#, c-format +msgid "LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE." +msgstr "LOCALE нельзя указать вместе с LC_COLLATE или LC_CTYPE." + +#: commands/dbcommands.c:279 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%d не является верным кодом кодировки" + +#: commands/dbcommands.c:290 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%s не является верным названием кодировки" + +#: commands/dbcommands.c:314 commands/dbcommands.c:1569 commands/user.c:275 +#: commands/user.c:691 +#, c-format +msgid "invalid connection limit: %d" +msgstr "неверный предел подключений: %d" + +#: commands/dbcommands.c:333 +#, c-format +msgid "permission denied to create database" +msgstr "нет прав на создание базы данных" + +#: commands/dbcommands.c:356 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "шаблон базы данных \"%s\" не существует" + +#: commands/dbcommands.c:368 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "нет прав на копирование базы данных \"%s\"" + +#: commands/dbcommands.c:384 +#, c-format +msgid "invalid server encoding %d" +msgstr "неверная кодировка для сервера: %d" + +#: commands/dbcommands.c:390 commands/dbcommands.c:395 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "неверное имя локали: \"%s\"" + +#: commands/dbcommands.c:415 +#, c-format +msgid "" +"new encoding (%s) is incompatible with the encoding of the template database " +"(%s)" +msgstr "" +"новая кодировка (%s) несовместима с кодировкой шаблона базы данных (%s)" + +#: commands/dbcommands.c:418 +#, c-format +msgid "" +"Use the same encoding as in the template database, or use template0 as " +"template." +msgstr "" +"Используйте кодировку шаблона базы данных или выберите в качестве шаблона " +"template0." + +#: commands/dbcommands.c:423 +#, c-format +msgid "" +"new collation (%s) is incompatible with the collation of the template " +"database (%s)" +msgstr "" +"новое правило сортировки (%s) несовместимо с правилом в шаблоне базы данных " +"(%s)" + +#: commands/dbcommands.c:425 +#, c-format +msgid "" +"Use the same collation as in the template database, or use template0 as " +"template." +msgstr "" +"Используйте то же правило сортировки, что и в шаблоне базы данных, или " +"выберите в качестве шаблона template0." + +#: commands/dbcommands.c:430 +#, c-format +msgid "" +"new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database " +"(%s)" +msgstr "" +"новый параметр LC_CTYPE (%s) несовместим с LC_CTYPE в шаблоне базы данных " +"(%s)" + +#: commands/dbcommands.c:432 +#, c-format +msgid "" +"Use the same LC_CTYPE as in the template database, or use template0 as " +"template." +msgstr "" +"Используйте тот же LC_CTYPE, что и в шаблоне базы данных, или выберите в " +"качестве шаблона template0." + +#: commands/dbcommands.c:454 commands/dbcommands.c:1196 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "" +"pg_global нельзя использовать в качестве табличного пространства по умолчанию" + +#: commands/dbcommands.c:480 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "не удалось назначить новое табличное пространство по умолчанию \"%s\"" + +#: commands/dbcommands.c:482 +#, c-format +msgid "" +"There is a conflict because database \"%s\" already has some tables in this " +"tablespace." +msgstr "" +"База данных \"%s\" содержит таблицы, которые уже находятся в этом табличном " +"пространстве." + +#: commands/dbcommands.c:512 commands/dbcommands.c:1066 +#, c-format +msgid "database \"%s\" already exists" +msgstr "база данных \"%s\" уже существует" + +#: commands/dbcommands.c:526 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "исходная база \"%s\" занята другими пользователями" + +#: commands/dbcommands.c:769 commands/dbcommands.c:784 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "кодировка \"%s\" не соответствует локали \"%s\"" + +#: commands/dbcommands.c:772 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "Для выбранного параметра LC_CTYPE требуется кодировка \"%s\"." + +#: commands/dbcommands.c:787 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "Для выбранного параметра LC_COLLATE требуется кодировка \"%s\"." + +#: commands/dbcommands.c:848 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "база данных \"%s\" не существует, пропускается" + +#: commands/dbcommands.c:872 +#, c-format +msgid "cannot drop a template database" +msgstr "удалить шаблон базы данных нельзя" + +#: commands/dbcommands.c:878 +#, c-format +msgid "cannot drop the currently open database" +msgstr "удалить базу данных, открытую в данный момент, нельзя" + +#: commands/dbcommands.c:891 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "база \"%s\" используется активным слотом логической репликации" + +#: commands/dbcommands.c:893 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "Обнаружен %d активный слот." +msgstr[1] "Обнаружены %d активных слота." +msgstr[2] "Обнаружено %d активных слотов." + +#: commands/dbcommands.c:907 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "база \"%s\" используется в подписке с логической репликацией" + +#: commands/dbcommands.c:909 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "Обнаружена %d подписка." +msgstr[1] "Обнаружены %d подписки." +msgstr[2] "Обнаружено %d подписок." + +#: commands/dbcommands.c:930 commands/dbcommands.c:1088 +#: commands/dbcommands.c:1218 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "база данных \"%s\" занята другими пользователями" + +#: commands/dbcommands.c:1048 +#, c-format +msgid "permission denied to rename database" +msgstr "нет прав на переименование базы данных" + +#: commands/dbcommands.c:1077 +#, c-format +msgid "current database cannot be renamed" +msgstr "нельзя переименовать текущую базу данных" + +#: commands/dbcommands.c:1174 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "" +"изменить табличное пространство открытой в данный момент базы данных нельзя" + +#: commands/dbcommands.c:1277 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "" +"некоторые отношения базы данных \"%s\" уже находятся в табличном " +"пространстве \"%s\"" + +#: commands/dbcommands.c:1279 +#, c-format +msgid "" +"You must move them back to the database's default tablespace before using " +"this command." +msgstr "" +"Прежде чем выполнять эту команду, вы должны вернуть их назад в табличное " +"пространство по умолчанию для этой базы данных." + +#: commands/dbcommands.c:1404 commands/dbcommands.c:1980 +#: commands/dbcommands.c:2203 commands/dbcommands.c:2261 +#: commands/tablespace.c:631 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "в старом каталоге базы данных \"%s\" могли остаться ненужные файлы" + +#: commands/dbcommands.c:1460 +#, c-format +msgid "unrecognized DROP DATABASE option \"%s\"" +msgstr "нераспознанный параметр DROP DATABASE: \"%s\"" + +#: commands/dbcommands.c:1550 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "параметр \"%s\" нельзя задать с другими параметрами" + +#: commands/dbcommands.c:1606 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "запретить подключения к текущей базе данных нельзя" + +#: commands/dbcommands.c:1742 +#, c-format +msgid "permission denied to change owner of database" +msgstr "нет прав на изменение владельца базы данных" + +#: commands/dbcommands.c:2086 +#, c-format +msgid "" +"There are %d other session(s) and %d prepared transaction(s) using the " +"database." +msgstr "" +"С этой базой данных связаны другие сеансы (%d) и подготовленные транзакции " +"(%d)." + +#: commands/dbcommands.c:2089 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "Эта база данных используется ещё в %d сеансе." +msgstr[1] "Эта база данных используется ещё в %d сеансах." +msgstr[2] "Эта база данных используется ещё в %d сеансах." + +#: commands/dbcommands.c:2094 storage/ipc/procarray.c:3023 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "С этой базой данных связана %d подготовленная транзакция." +msgstr[1] "С этой базой данных связаны %d подготовленные транзакции." +msgstr[2] "С этой базой данных связаны %d подготовленных транзакций." + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 +#: commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%s требует параметр" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 +#: commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%s требует числовое значение" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "%s требует логическое значение" + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%s требует целое значение" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "аргументом %s должно быть имя" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "аргументом %s должно быть имя типа" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "неверный аргумент для %s: \"%s\"" + +#: commands/dropcmds.c:100 commands/functioncmds.c:1274 +#: utils/adt/ruleutils.c:2633 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "функция \"%s\" является агрегатной" + +#: commands/dropcmds.c:102 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "Используйте DROP AGGREGATE для удаления агрегатных функций." + +#: commands/dropcmds.c:158 commands/sequence.c:447 commands/tablecmds.c:3266 +#: commands/tablecmds.c:3424 commands/tablecmds.c:3469 +#: commands/tablecmds.c:15060 tcop/utility.c:1307 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "отношение \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:188 commands/dropcmds.c:287 commands/tablecmds.c:1199 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "схема \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:228 commands/dropcmds.c:267 commands/tablecmds.c:259 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "тип \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:257 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "метод доступа \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:275 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "правило сортировки \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:282 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "преобразование \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:293 commands/statscmds.c:486 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "объект статистики \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:300 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr "анализатор текстового поиска \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:307 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "словарь текстового поиска \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:314 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "шаблон текстового поиска \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:321 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "конфигурация текстового поиска \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:326 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "расширение \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:336 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "функция %s(%s) не существует, пропускается" + +#: commands/dropcmds.c:349 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "процедура %s(%s) не существует, пропускается" + +#: commands/dropcmds.c:362 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "подпрограмма %s(%s) не существует, пропускается" + +#: commands/dropcmds.c:375 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "агрегатная функция %s(%s) не существует, пропускается" + +#: commands/dropcmds.c:388 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "оператор %s не существует, пропускается" + +#: commands/dropcmds.c:394 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "язык \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:403 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "приведение %s к типу %s не существует, пропускается" + +#: commands/dropcmds.c:412 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "преобразование для типа %s, языка \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:420 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "триггер \"%s\" для отношения \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:429 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "политика \"%s\" для отношения \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:436 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "событийный триггер \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:442 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "правило \"%s\" для отношения \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:449 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "обёртка сторонних данных \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:453 commands/foreigncmds.c:1399 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "сервер \"%s\" не существует, пропускается" + +#: commands/dropcmds.c:462 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "" +"класс операторов \"%s\" не существует для метода доступа \"%s\", пропускается" + +#: commands/dropcmds.c:474 +#, c-format +msgid "" +"operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "" +"семейство операторов \"%s\" не существует для метода доступа \"%s\", " +"пропускается" + +#: commands/dropcmds.c:481 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "публикация \"%s\" не существует, пропускается" + +#: commands/event_trigger.c:125 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "нет прав на создание событийного триггера \"%s\"" + +#: commands/event_trigger.c:127 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "Для создания событийного триггера нужно быть суперпользователем." + +#: commands/event_trigger.c:136 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "нераспознанное имя события \"%s\"" + +#: commands/event_trigger.c:153 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "нераспознанная переменная фильтра \"%s\"" + +#: commands/event_trigger.c:207 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "значение фильтра \"%s\" неприемлемо для переменной фильтра \"%s\"" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:213 commands/event_trigger.c:235 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "для %s событийные триггеры не поддерживаются" + +#: commands/event_trigger.c:248 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "переменная фильтра \"%s\" указана больше одного раза" + +#: commands/event_trigger.c:399 commands/event_trigger.c:443 +#: commands/event_trigger.c:537 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "событийный триггер \"%s\" не существует" + +#: commands/event_trigger.c:505 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "нет прав на изменение владельца событийного триггера \"%s\"" + +#: commands/event_trigger.c:507 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "Владельцем событийного триггера должен быть суперпользователь." + +#: commands/event_trigger.c:1325 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%s можно вызывать только в событийной триггерной функции sql_drop" + +#: commands/event_trigger.c:1445 commands/event_trigger.c:1466 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%s можно вызывать только в событийной триггерной функции table_rewrite" + +#: commands/event_trigger.c:1883 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%s можно вызывать только в событийной триггерной функции" + +#: commands/explain.c:213 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "нераспознанное значение параметра EXPLAIN \"%s\": \"%s\"" + +#: commands/explain.c:220 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "нераспознанный параметр EXPLAIN: \"%s\"" + +#: commands/explain.c:228 +#, c-format +msgid "EXPLAIN option WAL requires ANALYZE" +msgstr "параметр WAL оператора EXPLAIN требует указания ANALYZE" + +#: commands/explain.c:237 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "параметр TIMING оператора EXPLAIN требует указания ANALYZE" + +#: commands/extension.c:173 commands/extension.c:3013 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "расширение \"%s\" не существует" + +#: commands/extension.c:272 commands/extension.c:281 commands/extension.c:293 +#: commands/extension.c:303 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "неверное имя расширения: \"%s\"" + +#: commands/extension.c:273 +#, c-format +msgid "Extension names must not be empty." +msgstr "Имя расширения не может быть пустым." + +#: commands/extension.c:282 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "Имя расширения не может содержать \"--\"." + +#: commands/extension.c:294 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "Имя расширения не может начинаться или заканчиваться символом \"-\"." + +#: commands/extension.c:304 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "Имя расширения не может содержать разделители пути." + +#: commands/extension.c:319 commands/extension.c:328 commands/extension.c:337 +#: commands/extension.c:347 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "неверный идентификатор версии расширения: \"%s\"" + +#: commands/extension.c:320 +#, c-format +msgid "Version names must not be empty." +msgstr "Идентификатор версии не может быть пустым." + +#: commands/extension.c:329 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "Идентификатор версии не может содержать \"--\"." + +#: commands/extension.c:338 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "" +"Идентификатор версии не может начинаться или заканчиваться символом \"-\"." + +#: commands/extension.c:348 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "Идентификатор версии не может содержать разделители пути." + +#: commands/extension.c:498 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "не удалось открыть управляющий файл расширения \"%s\": %m" + +#: commands/extension.c:520 commands/extension.c:530 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "" +"параметр \"%s\" нельзя задавать в дополнительном управляющем файле расширения" + +#: commands/extension.c:552 commands/extension.c:560 commands/extension.c:568 +#: utils/misc/guc.c:6749 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "параметр \"%s\" требует логическое значение" + +#: commands/extension.c:577 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "неверное имя кодировки %s" + +#: commands/extension.c:591 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "параметр \"%s\" должен содержать список имён расширений" + +#: commands/extension.c:598 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "нераспознанный параметр \"%s\" в файле \"%s\"" + +#: commands/extension.c:607 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr "" +"параметр \"schema\" не может быть указан вместе с \"relocatable\" = true" + +#: commands/extension.c:785 +#, c-format +msgid "" +"transaction control statements are not allowed within an extension script" +msgstr "в скрипте расширения не должно быть операторов управления транзакциями" + +#: commands/extension.c:861 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "нет прав на создание расширения \"%s\"" + +#: commands/extension.c:864 +#, c-format +msgid "" +"Must have CREATE privilege on current database to create this extension." +msgstr "Для создания этого расширения нужно иметь право CREATE в текущей базе." + +#: commands/extension.c:865 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "Для создания этого расширения нужно быть суперпользователем." + +#: commands/extension.c:869 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "нет прав на изменение расширения \"%s\"" + +#: commands/extension.c:872 +#, c-format +msgid "" +"Must have CREATE privilege on current database to update this extension." +msgstr "" +"Для обновления этого расширения нужно иметь право CREATE в текущей базе." + +#: commands/extension.c:873 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "Для изменения этого расширения нужно быть суперпользователем." + +#: commands/extension.c:1200 +#, c-format +msgid "" +"extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "" +"для расширения \"%s\" не определён путь обновления с версии \"%s\" до версии " +"\"%s\"" + +#: commands/extension.c:1408 commands/extension.c:3074 +#, c-format +msgid "version to install must be specified" +msgstr "нужно указать версию для установки" + +#: commands/extension.c:1445 +#, c-format +msgid "" +"extension \"%s\" has no installation script nor update path for version \"%s" +"\"" +msgstr "" +"для расширения \"%s\" не определён путь установки или обновления для версии " +"\"%s\"" + +#: commands/extension.c:1479 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "расширение \"%s\" должно устанавливаться в схему \"%s\"" + +#: commands/extension.c:1639 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "выявлена циклическая зависимость между расширениями \"%s\" и \"%s\"" + +#: commands/extension.c:1644 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "установка требуемого расширения \"%s\"" + +#: commands/extension.c:1667 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr "требуемое расширение \"%s\" не установлено" + +#: commands/extension.c:1670 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "" +"Выполните CREATE EXTENSION ... CASCADE, чтобы установить также требуемые " +"расширения." + +#: commands/extension.c:1705 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "расширение \"%s\" уже существует, пропускается" + +#: commands/extension.c:1712 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "расширение \"%s\" уже существует" + +#: commands/extension.c:1723 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "вложенные операторы CREATE EXTENSION не поддерживаются" + +#: commands/extension.c:1896 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "удалить расширение \"%s\" нельзя, так как это модифицируемый объект" + +#: commands/extension.c:2457 +#, c-format +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "" +"%s можно вызывать только из SQL-скрипта, запускаемого командой CREATE " +"EXTENSION" + +#: commands/extension.c:2469 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "OID %u не относится к таблице" + +#: commands/extension.c:2474 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "таблица \"%s\" не относится к созданному расширению" + +#: commands/extension.c:2828 +#, c-format +msgid "" +"cannot move extension \"%s\" into schema \"%s\" because the extension " +"contains the schema" +msgstr "" +"переместить расширение \"%s\" в схему \"%s\" нельзя, так как оно содержит " +"схему" + +#: commands/extension.c:2869 commands/extension.c:2932 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "расширение \"%s\" не поддерживает SET SCHEMA" + +#: commands/extension.c:2934 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "объект %s не принадлежит схеме расширения \"%s\"" + +#: commands/extension.c:2993 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "вложенные операторы ALTER EXTENSION не поддерживаются" + +#: commands/extension.c:3085 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "версия \"%s\" расширения \"%s\" уже установлена" + +#: commands/extension.c:3336 +#, c-format +msgid "" +"cannot add schema \"%s\" to extension \"%s\" because the schema contains the " +"extension" +msgstr "" +"добавить схему \"%s\" к расширению \"%s\" нельзя, так как схема содержит " +"расширение" + +#: commands/extension.c:3364 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "%s не относится к расширению \"%s\"" + +#: commands/extension.c:3430 +#, c-format +msgid "file \"%s\" is too large" +msgstr "файл \"%s\" слишком большой" + +#: commands/foreigncmds.c:148 commands/foreigncmds.c:157 +#, c-format +msgid "option \"%s\" not found" +msgstr "нераспознанный параметр \"%s\"" + +#: commands/foreigncmds.c:167 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "параметр \"%s\" указан неоднократно" + +#: commands/foreigncmds.c:221 commands/foreigncmds.c:229 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "нет прав на изменение владельца обёртки сторонних данных \"%s\"" + +#: commands/foreigncmds.c:223 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "" +"Для смены владельца обёртки сторонних данных нужно быть суперпользователем." + +#: commands/foreigncmds.c:231 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "Владельцем обёртки сторонних данных должен быть суперпользователь." + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:711 foreign/foreign.c:701 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "обёртка сторонних данных \"%s\" не существует" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "нет прав на создание обёртки сторонних данных \"%s\"" + +#: commands/foreigncmds.c:586 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "Для создания обёртки сторонних данных нужно быть суперпользователем." + +#: commands/foreigncmds.c:701 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "нет прав на изменение обёртки сторонних данных \"%s\"" + +#: commands/foreigncmds.c:703 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "Для изменения обёртки сторонних данных нужно быть суперпользователем." + +#: commands/foreigncmds.c:734 +#, c-format +msgid "" +"changing the foreign-data wrapper handler can change behavior of existing " +"foreign tables" +msgstr "" +"при изменении обработчика в обёртке сторонних данных может измениться " +"поведение существующих сторонних таблиц" + +#: commands/foreigncmds.c:749 +#, c-format +msgid "" +"changing the foreign-data wrapper validator can cause the options for " +"dependent objects to become invalid" +msgstr "" +"при изменении функции проверки в обёртке сторонних данных параметры " +"зависимых объектов могут стать неверными" + +#: commands/foreigncmds.c:895 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "сервер \"%s\" уже существует, пропускается" + +#: commands/foreigncmds.c:1183 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "" +"сопоставление пользователя \"%s\" для сервера \"%s\" уже существует, " +"пропускается" + +#: commands/foreigncmds.c:1193 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "сопоставление пользователя \"%s\" для сервера \"%s\" уже существует" + +#: commands/foreigncmds.c:1293 commands/foreigncmds.c:1413 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "сопоставление пользователя \"%s\" для сервера \"%s\" не существует" + +#: commands/foreigncmds.c:1418 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "" +"сопоставление пользователя \"%s\" для сервера \"%s\" не существует, " +"пропускается" + +#: commands/foreigncmds.c:1569 foreign/foreign.c:389 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "обёртка сторонних данных \"%s\" не имеет обработчика" + +#: commands/foreigncmds.c:1575 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "обёртка сторонних данных \"%s\" не поддерживает IMPORT FOREIGN SCHEMA" + +#: commands/foreigncmds.c:1678 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "импорт сторонней таблицы \"%s\"" + +#: commands/functioncmds.c:104 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "SQL-функция не может возвращать тип-пустышку %s" + +#: commands/functioncmds.c:109 +#, c-format +msgid "return type %s is only a shell" +msgstr "возвращаемый тип %s - лишь пустышка" + +#: commands/functioncmds.c:139 parser/parse_type.c:354 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "для типа-пустышки \"%s\" нельзя указать модификатор типа" + +#: commands/functioncmds.c:145 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "тип \"%s\" ещё не определён" + +#: commands/functioncmds.c:146 +#, c-format +msgid "Creating a shell type definition." +msgstr "Создание определения типа-пустышки." + +#: commands/functioncmds.c:238 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "SQL-функция не может принимать значение типа-пустышки %s" + +#: commands/functioncmds.c:244 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "агрегатная функция не может принимать значение типа-пустышки %s" + +#: commands/functioncmds.c:249 +#, c-format +msgid "argument type %s is only a shell" +msgstr "тип аргумента %s - лишь пустышка" + +#: commands/functioncmds.c:259 +#, c-format +msgid "type %s does not exist" +msgstr "тип %s не существует" + +#: commands/functioncmds.c:273 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "агрегатные функции не принимают в аргументах множества" + +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "процедуры не принимают в аргументах множества" + +#: commands/functioncmds.c:281 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "функции не принимают аргументы-множества" + +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "у процедур не может быть аргументов OUT" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "Аргументы INOUT допускаются." + +#: commands/functioncmds.c:300 +#, c-format +msgid "VARIADIC parameter must be the last input parameter" +msgstr "параметр VARIADIC должен быть последним в списке входных параметров" + +#: commands/functioncmds.c:331 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "параметр VARIADIC должен быть массивом" + +#: commands/functioncmds.c:371 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "имя параметра \"%s\" указано неоднократно" + +#: commands/functioncmds.c:386 +#, c-format +msgid "only input parameters can have default values" +msgstr "значения по умолчанию могут быть только у входных параметров" + +#: commands/functioncmds.c:401 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "в значениях параметров по умолчанию нельзя ссылаться на таблицы" + +#: commands/functioncmds.c:425 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "" +"входные параметры, следующие за параметром со значением по умолчанию, также " +"должны иметь значения по умолчанию" + +#: commands/functioncmds.c:577 commands/functioncmds.c:768 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "некорректный атрибут в определении процедуры" + +#: commands/functioncmds.c:673 +#, c-format +msgid "support function %s must return type %s" +msgstr "вспомогательная функция %s должна возвращать тип %s" + +#: commands/functioncmds.c:684 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "для указания вспомогательной функции нужно быть суперпользователем" + +#: commands/functioncmds.c:800 +#, c-format +msgid "no function body specified" +msgstr "не указано тело функции" + +#: commands/functioncmds.c:810 +#, c-format +msgid "no language specified" +msgstr "язык не указан" + +#: commands/functioncmds.c:835 commands/functioncmds.c:1319 +#, c-format +msgid "COST must be positive" +msgstr "значение COST должно быть положительным" + +#: commands/functioncmds.c:843 commands/functioncmds.c:1327 +#, c-format +msgid "ROWS must be positive" +msgstr "значение ROWS должно быть положительным" + +#: commands/functioncmds.c:897 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "для языка \"%s\" нужно только одно выражение AS" + +#: commands/functioncmds.c:995 commands/functioncmds.c:2048 +#: commands/proclang.c:259 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "язык \"%s\" не существует" + +#: commands/functioncmds.c:997 commands/functioncmds.c:2050 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Выполните CREATE EXTENSION, чтобы загрузить язык в базу данных." + +#: commands/functioncmds.c:1032 commands/functioncmds.c:1311 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "" +"только суперпользователь может определить функцию с атрибутом LEAKPROOF" + +#: commands/functioncmds.c:1081 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "" +"результат функции должен иметь тип %s (в соответствии с параметрами OUT)" + +#: commands/functioncmds.c:1094 +#, c-format +msgid "function result type must be specified" +msgstr "необходимо указать тип результата функции" + +#: commands/functioncmds.c:1146 commands/functioncmds.c:1331 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "указание ROWS неприменимо, когда функция возвращает не множество" + +#: commands/functioncmds.c:1431 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "исходный тип данных %s является псевдотипом" + +#: commands/functioncmds.c:1437 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "целевой тип данных %s является псевдотипом" + +#: commands/functioncmds.c:1461 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "" +"приведение будет проигнорировано, так как исходные данные имеют тип домен" + +#: commands/functioncmds.c:1466 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "" +"приведение будет проигнорировано, так как целевые данные имеют тип домен" + +#: commands/functioncmds.c:1491 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "функция приведения должна принимать от одного до трёх аргументов" + +#: commands/functioncmds.c:1495 +#, c-format +msgid "" +"argument of cast function must match or be binary-coercible from source data " +"type" +msgstr "" +"аргумент функции приведения должен совпадать или быть двоично-совместимым с " +"исходным типом данных" + +#: commands/functioncmds.c:1499 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "второй аргумент функции приведения должен иметь тип %s" + +#: commands/functioncmds.c:1504 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "третий аргумент функции приведения должен иметь тип %s" + +#: commands/functioncmds.c:1509 +#, c-format +msgid "" +"return data type of cast function must match or be binary-coercible to " +"target data type" +msgstr "" +"тип возвращаемых данных функции приведения должен совпадать или быть двоично-" +"совместимым с целевым типом данных" + +#: commands/functioncmds.c:1520 +#, c-format +msgid "cast function must not be volatile" +msgstr "функция приведения не может быть изменчивой (volatile)" + +#: commands/functioncmds.c:1525 +#, c-format +msgid "cast function must be a normal function" +msgstr "функция приведения должна быть обычной функцией" + +#: commands/functioncmds.c:1529 +#, c-format +msgid "cast function must not return a set" +msgstr "функция приведения не может возвращать множество" + +#: commands/functioncmds.c:1555 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "для создания приведения WITHOUT FUNCTION нужно быть суперпользователем" + +#: commands/functioncmds.c:1570 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "исходный и целевой типы данных не совместимы физически" + +#: commands/functioncmds.c:1585 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "составные типы данных не совместимы на двоичном уровне" + +#: commands/functioncmds.c:1591 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "типы-перечисления не совместимы на двоичном уровне" + +#: commands/functioncmds.c:1597 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "типы-массивы не совместимы на двоичном уровне" + +#: commands/functioncmds.c:1614 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "типы-домены не могут считаться двоично-совместимыми" + +#: commands/functioncmds.c:1624 +#, c-format +msgid "source data type and target data type are the same" +msgstr "исходный тип данных совпадает с целевым" + +#: commands/functioncmds.c:1682 +#, c-format +msgid "transform function must not be volatile" +msgstr "функция преобразования не может быть изменчивой" + +#: commands/functioncmds.c:1686 +#, c-format +msgid "transform function must be a normal function" +msgstr "функция преобразования должна быть обычной функцией" + +#: commands/functioncmds.c:1690 +#, c-format +msgid "transform function must not return a set" +msgstr "функция преобразования не может возвращать множество" + +#: commands/functioncmds.c:1694 +#, c-format +msgid "transform function must take one argument" +msgstr "функция преобразования должна принимать один аргумент" + +#: commands/functioncmds.c:1698 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "первый аргумент функции преобразования должен иметь тип %s" + +#: commands/functioncmds.c:1736 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "тип данных %s является псевдотипом" + +#: commands/functioncmds.c:1742 +#, c-format +msgid "data type %s is a domain" +msgstr "тип данных \"%s\" является доменом" + +#: commands/functioncmds.c:1782 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "результат функции FROM SQL должен иметь тип %s" + +#: commands/functioncmds.c:1808 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "результат функции TO SQL должен иметь тип данных преобразования" + +#: commands/functioncmds.c:1837 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "преобразование для типа %s, языка \"%s\" уже существует" + +#: commands/functioncmds.c:1929 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "преобразование для типа %s, языка \"%s\" не существует" + +#: commands/functioncmds.c:1980 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "функция %s уже существует в схеме \"%s\"" + +#: commands/functioncmds.c:2035 +#, c-format +msgid "no inline code specified" +msgstr "нет внедрённого кода" + +#: commands/functioncmds.c:2081 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "язык \"%s\" не поддерживает выполнение внедрённого кода" + +#: commands/functioncmds.c:2193 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "процедуре нельзя передать больше %d аргумента" +msgstr[1] "процедуре нельзя передать больше %d аргументов" +msgstr[2] "процедуре нельзя передать больше %d аргументов" + +#: commands/indexcmds.c:590 +#, c-format +msgid "must specify at least one column" +msgstr "нужно указать минимум один столбец" + +#: commands/indexcmds.c:594 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "число столбцов в индексе не может превышать %d" + +#: commands/indexcmds.c:633 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "создать индекс в сторонней таблице \"%s\" нельзя" + +#: commands/indexcmds.c:664 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "" +"создать индекс в секционированной таблице \"%s\" параллельным способом нельзя" + +#: commands/indexcmds.c:669 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "" +"создать ограничение-исключение в секционированной таблице \"%s\" нельзя" + +#: commands/indexcmds.c:679 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "создавать индексы во временных таблицах других сеансов нельзя" + +#: commands/indexcmds.c:717 commands/tablecmds.c:704 commands/tablespace.c:1185 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "" +"для секционированных отношений нельзя назначить табличное пространство по " +"умолчанию" + +#: commands/indexcmds.c:749 commands/tablecmds.c:739 commands/tablecmds.c:13180 +#: commands/tablecmds.c:13294 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "" +"в табличное пространство pg_global можно поместить только разделяемые таблицы" + +#: commands/indexcmds.c:782 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "устаревший метод доступа \"rtree\" подменяется методом \"gist\"" + +#: commands/indexcmds.c:803 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "метод доступа \"%s\" не поддерживает уникальные индексы" + +#: commands/indexcmds.c:808 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "метод доступа \"%s\" не поддерживает включаемые столбцы" + +#: commands/indexcmds.c:813 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "метод доступа \"%s\" не поддерживает индексы по многим столбцам" + +#: commands/indexcmds.c:818 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "метод доступа \"%s\" не поддерживает ограничения-исключения" + +#: commands/indexcmds.c:941 +#, c-format +msgid "cannot match partition key to an index using access method \"%s\"" +msgstr "" +"сопоставить ключ секционирования с индексом, использующим метод доступа \"%s" +"\", нельзя" + +#: commands/indexcmds.c:951 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "" +"неподдерживаемое ограничение \"%s\" с определением ключа секционирования" + +#: commands/indexcmds.c:953 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "" +"Ограничения %s не могут использоваться, когда ключи секционирования включают " +"выражения." + +#: commands/indexcmds.c:992 +#, c-format +msgid "" +"unique constraint on partitioned table must include all partitioning columns" +msgstr "" +"ограничение уникальности в секционированной таблице должно включать все " +"секционирующие столбцы" + +#: commands/indexcmds.c:993 +#, c-format +msgid "" +"%s constraint on table \"%s\" lacks column \"%s\" which is part of the " +"partition key." +msgstr "" +"В ограничении %s таблицы \"%s\" не хватает столбца \"%s\", входящего в ключ " +"секционирования." + +#: commands/indexcmds.c:1012 commands/indexcmds.c:1031 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "создание индекса для системных столбцов не поддерживается" + +#: commands/indexcmds.c:1056 +#, c-format +msgid "%s %s will create implicit index \"%s\" for table \"%s\"" +msgstr "%s %s создаст неявный индекс \"%s\" для таблицы \"%s\"" + +#: commands/indexcmds.c:1199 tcop/utility.c:1493 +#, c-format +msgid "cannot create unique index on partitioned table \"%s\"" +msgstr "создать уникальный индекс в секционированной таблице \"%s\" нельзя" + +#: commands/indexcmds.c:1201 tcop/utility.c:1495 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "Таблица \"%s\" содержит секции, являющиеся сторонними таблицами." + +#: commands/indexcmds.c:1630 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "функции в предикате индекса должны быть помечены как IMMUTABLE" + +#: commands/indexcmds.c:1696 parser/parse_utilcmd.c:2464 +#: parser/parse_utilcmd.c:2599 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "указанный в ключе столбец \"%s\" не существует" + +#: commands/indexcmds.c:1720 parser/parse_utilcmd.c:1800 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "выражения во включаемых столбцах не поддерживаются" + +#: commands/indexcmds.c:1761 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "функции в индексном выражении должны быть помечены как IMMUTABLE" + +#: commands/indexcmds.c:1776 +#, c-format +msgid "including column does not support a collation" +msgstr "включаемые столбцы не поддерживают правила сортировки" + +#: commands/indexcmds.c:1780 +#, c-format +msgid "including column does not support an operator class" +msgstr "включаемые столбцы не поддерживают классы операторов" + +#: commands/indexcmds.c:1784 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "включаемые столбцы не поддерживают сортировку ASC/DESC" + +#: commands/indexcmds.c:1788 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "включаемые столбцы не поддерживают указания NULLS FIRST/LAST" + +#: commands/indexcmds.c:1815 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "не удалось определить правило сортировки для индексного выражения" + +#: commands/indexcmds.c:1823 commands/tablecmds.c:16064 commands/typecmds.c:771 +#: parser/parse_expr.c:2850 parser/parse_type.c:566 parser/parse_utilcmd.c:3674 +#: parser/parse_utilcmd.c:4235 utils/adt/misc.c:503 +#, c-format +msgid "collations are not supported by type %s" +msgstr "тип %s не поддерживает сортировку (COLLATION)" + +#: commands/indexcmds.c:1861 +#, c-format +msgid "operator %s is not commutative" +msgstr "оператор %s не коммутативен" + +#: commands/indexcmds.c:1863 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "" +"В ограничениях-исключениях могут использоваться только коммутативные " +"операторы." + +#: commands/indexcmds.c:1889 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "оператор \"%s\" не входит в семейство операторов \"%s\"" + +#: commands/indexcmds.c:1892 +#, c-format +msgid "" +"The exclusion operator must be related to the index operator class for the " +"constraint." +msgstr "" +"Оператор исключения для ограничения должен относиться к классу операторов " +"индекса." + +#: commands/indexcmds.c:1927 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "метод доступа \"%s\" не поддерживает сортировку ASC/DESC" + +#: commands/indexcmds.c:1932 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "метод доступа \"%s\" не поддерживает параметр NULLS FIRST/LAST" + +#: commands/indexcmds.c:1978 commands/tablecmds.c:16089 +#: commands/tablecmds.c:16095 commands/typecmds.c:1945 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "" +"для типа данных %s не определён класс операторов по умолчанию для метода " +"доступа \"%s\"" + +#: commands/indexcmds.c:1980 +#, c-format +msgid "" +"You must specify an operator class for the index or define a default " +"operator class for the data type." +msgstr "" +"Вы должны указать класс операторов для индекса или определить класс " +"операторов по умолчанию для этого типа данных." + +#: commands/indexcmds.c:2009 commands/indexcmds.c:2017 +#: commands/opclasscmds.c:208 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "класс операторов \"%s\" для метода доступа \"%s\" не существует" + +#: commands/indexcmds.c:2031 commands/typecmds.c:1933 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "класс операторов \"%s\" не принимает тип данных %s" + +#: commands/indexcmds.c:2121 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "" +"для типа данных %s определено несколько классов операторов по умолчанию" + +#: commands/indexcmds.c:2570 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "" +"в таблице \"%s\" нет индексов, которые можно переиндексировать неблокирующим " +"способом" + +#: commands/indexcmds.c:2581 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "в таблице \"%s\" нет индексов для переиндексации" + +#: commands/indexcmds.c:2620 commands/indexcmds.c:2901 +#: commands/indexcmds.c:2994 +#, c-format +msgid "cannot reindex system catalogs concurrently" +msgstr "Переиндексировать системные каталоги неблокирующим способом нельзя" + +#: commands/indexcmds.c:2643 +#, c-format +msgid "can only reindex the currently open database" +msgstr "переиндексировать можно только текущую базу данных" + +#: commands/indexcmds.c:2734 +#, c-format +msgid "cannot reindex system catalogs concurrently, skipping all" +msgstr "" +"все системные каталоги пропускаются, так как их нельзя переиндексировать " +"неблокирующим способом" + +#: commands/indexcmds.c:2786 commands/indexcmds.c:3506 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "таблица \"%s.%s\" переиндексирована" + +#: commands/indexcmds.c:2916 commands/indexcmds.c:2962 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "" +"перестроить нерабочий индекс \"%s.%s\" неблокирующим способом нельзя, он " +"пропускается" + +#: commands/indexcmds.c:2922 +#, c-format +msgid "" +"cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "" +"перестроить индекс ограничения-исключения \"%s.%s\" неблокирующим способом " +"нельзя, он пропускается" + +#: commands/indexcmds.c:3033 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "переиндексировать отношение такого типа неблокирующим способом нельзя" + +#: commands/indexcmds.c:3488 commands/indexcmds.c:3499 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr "индекс \"%s.%s\" был перестроен" + +#: commands/indexcmds.c:3531 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "REINDEX для секционированных индексов ещё не реализован" + +#: commands/lockcmds.c:92 commands/tablecmds.c:5631 commands/trigger.c:295 +#: rewrite/rewriteDefine.c:272 rewrite/rewriteDefine.c:939 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "\"%s\" - это не таблица и не представление" + +#: commands/matview.c:182 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "" +"CONCURRENTLY нельзя использовать, когда материализованное представление не " +"наполнено" + +#: commands/matview.c:188 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "параметры CONCURRENTLY и WITH NO DATA исключают друг друга" + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "обновить материализованное представление \"%s\" параллельно нельзя" + +#: commands/matview.c:247 +#, c-format +msgid "" +"Create a unique index with no WHERE clause on one or more columns of the " +"materialized view." +msgstr "" +"Создайте уникальный индекс без предложения WHERE для одного или нескольких " +"столбцов материализованного представления." + +#: commands/matview.c:641 +#, c-format +msgid "" +"new data for materialized view \"%s\" contains duplicate rows without any " +"null columns" +msgstr "" +"новые данные для материализованного представления \"%s\" содержат " +"дублирующиеся строки (без учёта столбцов с NULL)" + +#: commands/matview.c:643 +#, c-format +msgid "Row: %s" +msgstr "Строка: %s" + +#: commands/opclasscmds.c:127 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "семейство операторов \"%s\" для метода доступа \"%s\" не существует" + +#: commands/opclasscmds.c:269 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "семейство операторов \"%s\" для метода доступа \"%s\" уже существует" + +#: commands/opclasscmds.c:414 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "для создания класса операторов нужно быть суперпользователем" + +#: commands/opclasscmds.c:487 commands/opclasscmds.c:869 +#: commands/opclasscmds.c:993 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "неверный номер оператора (%d), требуется число от 1 до %d" + +#: commands/opclasscmds.c:531 commands/opclasscmds.c:913 +#: commands/opclasscmds.c:1008 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "неверный номер функции (%d), требуется число от 1 до %d" + +#: commands/opclasscmds.c:559 +#, c-format +msgid "storage type specified more than once" +msgstr "тип хранения указан неоднократно" + +#: commands/opclasscmds.c:586 +#, c-format +msgid "" +"storage type cannot be different from data type for access method \"%s\"" +msgstr "" +"тип хранения не может отличаться от типа данных для метода доступа \"%s\"" + +#: commands/opclasscmds.c:602 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "класс операторов \"%s\" для метода доступа \"%s\" уже существует" + +#: commands/opclasscmds.c:630 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "" +"класс операторов \"%s\" не удалось сделать классом по умолчанию для типа %s" + +#: commands/opclasscmds.c:633 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "Класс операторов \"%s\" уже является классом по умолчанию." + +#: commands/opclasscmds.c:761 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "для создания семейства операторов нужно быть суперпользователем" + +#: commands/opclasscmds.c:821 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "для изменения семейства операторов нужно быть суперпользователем" + +#: commands/opclasscmds.c:878 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "в ALTER OPERATOR FAMILY должны быть указаны типы аргументов оператора" + +#: commands/opclasscmds.c:941 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "в ALTER OPERATOR FAMILY нельзя указать STORAGE" + +#: commands/opclasscmds.c:1063 +#, c-format +msgid "one or two argument types must be specified" +msgstr "нужно указать один или два типа аргументов" + +#: commands/opclasscmds.c:1089 +#, c-format +msgid "index operators must be binary" +msgstr "индексные операторы должны быть бинарными" + +#: commands/opclasscmds.c:1108 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "метод доступа \"%s\" не поддерживает сортирующие операторы" + +#: commands/opclasscmds.c:1119 +#, c-format +msgid "index search operators must return boolean" +msgstr "операторы поиска по индексу должны возвращать логическое значение" + +#: commands/opclasscmds.c:1159 +#, c-format +msgid "" +"associated data types for operator class options parsing functions must " +"match opclass input type" +msgstr "" +"связанные типы данных для функций, разбирающих параметры класса операторов, " +"должны совпадать с входным типом класса" + +#: commands/opclasscmds.c:1166 +#, c-format +msgid "" +"left and right associated data types for operator class options parsing " +"functions must match" +msgstr "" +"левый и правый типы данных для функций, разбирающих параметры класса " +"операторов, должны совпадать" + +#: commands/opclasscmds.c:1174 +#, c-format +msgid "invalid operator class options parsing function" +msgstr "неправильная функция разбора параметров класса операторов" + +#: commands/opclasscmds.c:1175 +#, c-format +msgid "Valid signature of operator class options parsing function is %s." +msgstr "" +"Правильная сигнатура функции, осуществляющей разбор параметров класса " +"операторов: '%s'." + +#: commands/opclasscmds.c:1194 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "функции сравнения btree должны иметь два аргумента" + +#: commands/opclasscmds.c:1198 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "функции сравнения btree должны возвращать целое число" + +#: commands/opclasscmds.c:1215 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "опорные функции сортировки btree должны принимать тип \"internal\"" + +#: commands/opclasscmds.c:1219 +#, c-format +msgid "btree sort support functions must return void" +msgstr "опорные функции сортировки btree должны возвращать пустое (void)" + +#: commands/opclasscmds.c:1230 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "функции in_range для btree должны принимать пять аргументов" + +#: commands/opclasscmds.c:1234 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "функции in_range для btree должны возвращать логическое значение" + +#: commands/opclasscmds.c:1250 +#, c-format +msgid "btree equal image functions must have one argument" +msgstr "функции равенства образов btree должны иметь один аргумент" + +#: commands/opclasscmds.c:1254 +#, c-format +msgid "btree equal image functions must return boolean" +msgstr "функции равенства образов должны возвращать логическое значение" + +#: commands/opclasscmds.c:1267 +#, c-format +msgid "btree equal image functions must not be cross-type" +msgstr "функции равенства образов не должны быть межтиповыми" + +#: commands/opclasscmds.c:1277 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "функция хеширования 1 должна принимать один аргумент" + +#: commands/opclasscmds.c:1281 +#, c-format +msgid "hash function 1 must return integer" +msgstr "функция хеширования 1 должна возвращать целое число" + +#: commands/opclasscmds.c:1288 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "функция хеширования 2 должна принимать два аргумента" + +#: commands/opclasscmds.c:1292 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "функция хеширования 2 должна возвращать значение bigint" + +#: commands/opclasscmds.c:1317 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "для опорной функции индексов должны быть указаны связанные типы данных" + +#: commands/opclasscmds.c:1342 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "номер функции %d для (%s,%s) дублируется" + +#: commands/opclasscmds.c:1349 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "номер оператора %d для (%s,%s) дублируется" + +#: commands/opclasscmds.c:1398 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "оператор %d(%s,%s) уже существует в семействе \"%s\"" + +#: commands/opclasscmds.c:1515 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "функция %d(%s,%s) уже существует в семействе операторов \"%s\"" + +#: commands/opclasscmds.c:1606 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "оператор %d(%s,%s) не существует в семействе операторов \"%s\"" + +#: commands/opclasscmds.c:1646 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "функция %d(%s,%s) не существует в семействе операторов \"%s\"" + +#: commands/opclasscmds.c:1776 +#, c-format +msgid "" +"operator class \"%s\" for access method \"%s\" already exists in schema \"%s" +"\"" +msgstr "" +"класс операторов \"%s\" для метода доступа \"%s\" уже существует в схеме \"%s" +"\"" + +#: commands/opclasscmds.c:1799 +#, c-format +msgid "" +"operator family \"%s\" for access method \"%s\" already exists in schema \"%s" +"\"" +msgstr "" +"семейство операторов \"%s\" для метода доступа \"%s\" уже существует в схеме " +"\"%s\"" + +#: commands/operatorcmds.c:111 commands/operatorcmds.c:119 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "аргументом оператора не может быть тип SETOF" + +#: commands/operatorcmds.c:152 commands/operatorcmds.c:467 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "атрибут оператора \"%s\" не распознан" + +#: commands/operatorcmds.c:163 +#, c-format +msgid "operator function must be specified" +msgstr "необходимо указать функцию оператора" + +#: commands/operatorcmds.c:174 +#, c-format +msgid "at least one of leftarg or rightarg must be specified" +msgstr "необходимо указать левый и/или правый аргумент" + +#: commands/operatorcmds.c:278 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "функция оценки ограничения %s должна возвращать тип %s" + +#: commands/operatorcmds.c:321 +#, c-format +msgid "join estimator function %s has multiple matches" +msgstr "функция оценки соединения %s присутствует в нескольких экземплярах" + +#: commands/operatorcmds.c:336 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "функция оценки соединения %s должна возвращать тип %s" + +#: commands/operatorcmds.c:461 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "атрибут оператора \"%s\" нельзя изменить" + +#: commands/policy.c:88 commands/policy.c:381 commands/policy.c:471 +#: commands/statscmds.c:143 commands/tablecmds.c:1512 commands/tablecmds.c:1994 +#: commands/tablecmds.c:3076 commands/tablecmds.c:5610 +#: commands/tablecmds.c:8413 commands/tablecmds.c:15654 +#: commands/tablecmds.c:15689 commands/trigger.c:301 commands/trigger.c:1206 +#: commands/trigger.c:1315 rewrite/rewriteDefine.c:278 +#: rewrite/rewriteDefine.c:944 rewrite/rewriteRemove.c:80 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "доступ запрещён: \"%s\" - это системный каталог" + +#: commands/policy.c:171 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "все указанные роли, кроме PUBLIC, игнорируются" + +#: commands/policy.c:172 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "Роль PUBLIC включает в себя все остальные роли." + +#: commands/policy.c:495 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "роль \"%s\" нельзя удалить из политики \"%s\" отношения \"%s\"" + +#: commands/policy.c:704 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "WITH CHECK нельзя применить к SELECT или DELETE" + +#: commands/policy.c:713 commands/policy.c:1018 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "для INSERT допускается только выражение WITH CHECK" + +#: commands/policy.c:788 commands/policy.c:1241 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "политика \"%s\" для таблицы \"%s\" уже существует" + +#: commands/policy.c:990 commands/policy.c:1269 commands/policy.c:1340 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "политика \"%s\" для таблицы \"%s\" не существует" + +#: commands/policy.c:1008 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "для SELECT, DELETE допускается только выражение USING" + +#: commands/portalcmds.c:60 commands/portalcmds.c:187 commands/portalcmds.c:238 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "имя курсора не может быть пустым" + +#: commands/portalcmds.c:72 +#, c-format +msgid "cannot create a cursor WITH HOLD within security-restricted operation" +msgstr "" +"в рамках операции с ограничениями по безопасности нельзя создать курсор WITH " +"HOLD" + +#: commands/portalcmds.c:195 commands/portalcmds.c:248 +#: executor/execCurrent.c:70 utils/adt/xml.c:2594 utils/adt/xml.c:2764 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "курсор \"%s\" не существует" + +#: commands/prepare.c:76 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "неверный оператор: имя не должно быть пустым" + +#: commands/prepare.c:134 parser/parse_param.c:304 tcop/postgres.c:1498 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "не удалось определить тип данных параметра $%d" + +#: commands/prepare.c:152 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "служебные SQL-операторы нельзя подготовить" + +# [SM]: TO REVIEW +#: commands/prepare.c:256 commands/prepare.c:261 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "подготовленный оператор - не SELECT" + +#: commands/prepare.c:328 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "неверное число параметров для подготовленного оператора \"%s\"" + +#: commands/prepare.c:330 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "Ожидалось параметров: %d, получено: %d." + +#: commands/prepare.c:363 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "параметр $%d типа %s нельзя привести к ожидаемому типу %s" + +# [SM]: TO REVIEW +#: commands/prepare.c:449 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "подготовленный оператор \"%s\" уже существует" + +# [SM]: TO REVIEW +#: commands/prepare.c:488 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "подготовленный оператор \"%s\" не существует" + +#: commands/proclang.c:67 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "" +"для создания дополнительного процедурного языка нужно быть суперпользователем" + +#: commands/publicationcmds.c:107 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "неверный синтаксис параметра \"publish\"" + +#: commands/publicationcmds.c:125 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "нераспознанное значение \"publish\": \"%s\"" + +#: commands/publicationcmds.c:140 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "нераспознанный параметр репликации: \"%s\"" + +#: commands/publicationcmds.c:172 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "для создания публикации всех таблиц нужно быть суперпользователем" + +#: commands/publicationcmds.c:248 +#, c-format +msgid "wal_level is insufficient to publish logical changes" +msgstr "уровень wal_level недостаточен для публикации логических изменений" + +#: commands/publicationcmds.c:249 +#, c-format +msgid "Set wal_level to logical before creating subscriptions." +msgstr "Задайте для wal_level значение logical до создания подписок." + +#: commands/publicationcmds.c:369 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "публикация \"%s\" определена для всех таблиц (FOR ALL TABLES)" + +#: commands/publicationcmds.c:371 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "В публикации всех таблиц нельзя добавлять или удалять таблицы." + +#: commands/publicationcmds.c:683 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "отношение \"%s\" не включено в публикацию" + +#: commands/publicationcmds.c:726 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "нет прав на изменение владельца публикации \"%s\"" + +#: commands/publicationcmds.c:728 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "" +"Владельцем публикации всех таблиц (FOR ALL TABLES) должен быть " +"суперпользователь." + +#: commands/schemacmds.c:105 commands/schemacmds.c:281 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "неприемлемое имя схемы: \"%s\"" + +#: commands/schemacmds.c:106 commands/schemacmds.c:282 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "Префикс \"pg_\" зарезервирован для системных схем." + +#: commands/schemacmds.c:120 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "схема \"%s\" уже существует, пропускается" + +#: commands/seclabel.c:60 +#, c-format +msgid "no security label providers have been loaded" +msgstr "поставщики меток безопасности не загружены" + +#: commands/seclabel.c:64 +#, c-format +msgid "" +"must specify provider when multiple security label providers have been loaded" +msgstr "" +"когда загружено несколько поставщиков меток безопасности, нужный следует " +"указывать явно" + +#: commands/seclabel.c:82 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "поставщик меток безопасности \"%s\" не загружен" + +#: commands/sequence.c:140 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "нежурналируемые последовательности не поддерживаются" + +#: commands/sequence.c:709 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "функция nextval достигла максимума для последовательности \"%s\" (%s)" + +#: commands/sequence.c:732 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "функция nextval достигла минимума для последовательности \"%s\" (%s)" + +#: commands/sequence.c:850 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "" +"текущее значение (currval) для последовательности \"%s\" ещё не определено в " +"этом сеансе" + +#: commands/sequence.c:869 commands/sequence.c:875 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "последнее значение (lastval) ещё не определено в этом сеансе" + +#: commands/sequence.c:963 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "" +"setval передано значение %s вне пределов последовательности \"%s\" (%s..%s)" + +#: commands/sequence.c:1360 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "неверное свойство последовательности SEQUENCE NAME" + +#: commands/sequence.c:1386 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "" +"типом столбца идентификации может быть только smallint, integer или bigint" + +#: commands/sequence.c:1387 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "" +"типом последовательности может быть только smallint, integer или bigint" + +#: commands/sequence.c:1421 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "INCREMENT не может быть нулевым" + +#: commands/sequence.c:1474 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) выходит за пределы типа данных последовательности (%s)" + +#: commands/sequence.c:1511 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s) выходит за пределы типа данных последовательности (%s)" + +#: commands/sequence.c:1525 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "MINVALUE (%s) должно быть меньше MAXVALUE (%s)" + +#: commands/sequence.c:1552 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "значение START (%s) не может быть меньше MINVALUE (%s)" + +#: commands/sequence.c:1564 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "значение START (%s) не может быть больше MAXVALUE (%s)" + +#: commands/sequence.c:1594 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "значение RESTART (%s) не может быть меньше MINVALUE (%s)" + +#: commands/sequence.c:1606 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "значение RESTART (%s) не может быть больше MAXVALUE (%s)" + +#: commands/sequence.c:1621 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "значение CACHE (%s) должно быть больше нуля" + +#: commands/sequence.c:1658 +#, c-format +msgid "invalid OWNED BY option" +msgstr "неверное указание OWNED BY" + +# skip-rule: no-space-after-period +#: commands/sequence.c:1659 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "Укажите OWNED BY таблица.столбец или OWNED BY NONE." + +#: commands/sequence.c:1684 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr "указанный объект \"%s\" не является таблицей или сторонней таблицей" + +#: commands/sequence.c:1691 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "" +"последовательность должна иметь того же владельца, что и таблица, с которой " +"она связана" + +#: commands/sequence.c:1695 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "" +"последовательность должна быть в той же схеме, что и таблица, с которой она " +"связана" + +#: commands/sequence.c:1717 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "сменить владельца последовательности идентификации нельзя" + +#: commands/sequence.c:1718 commands/tablecmds.c:12562 +#: commands/tablecmds.c:15080 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "Последовательность \"%s\" связана с таблицей \"%s\"." + +#: commands/statscmds.c:104 commands/statscmds.c:113 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "в CREATE STATISTICS можно указать только одно отношение" + +#: commands/statscmds.c:131 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "" +"отношение \"%s\" - это не таблица, не сторонняя таблица и не " +"материализованное представление" + +#: commands/statscmds.c:181 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "объект статистики \"%s\" уже существует, пропускается" + +#: commands/statscmds.c:189 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "объект статистики \"%s\" уже существует" + +#: commands/statscmds.c:211 commands/statscmds.c:217 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "в CREATE STATISTICS допускаются только простые ссылки на столбцы" + +#: commands/statscmds.c:232 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "создание статистики для системных столбцов не поддерживается" + +#: commands/statscmds.c:239 +#, c-format +msgid "" +"column \"%s\" cannot be used in statistics because its type %s has no " +"default btree operator class" +msgstr "" +"столбец \"%s\" нельзя использовать в статистике, так как для его типа %s не " +"определён класс операторов B-дерева по умолчанию" + +#: commands/statscmds.c:246 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "в статистике не может быть больше %d столбцов" + +#: commands/statscmds.c:261 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "для расширенной статистики требуются минимум 2 столбца" + +#: commands/statscmds.c:279 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "повторяющееся имя столбца в определении статистики" + +#: commands/statscmds.c:313 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "нераспознанный вид статистики \"%s\"" + +#: commands/statscmds.c:451 commands/tablecmds.c:7434 +#, c-format +msgid "statistics target %d is too low" +msgstr "ориентир статистики слишком мал (%d)" + +#: commands/statscmds.c:459 commands/tablecmds.c:7442 +#, c-format +msgid "lowering statistics target to %d" +msgstr "ориентир статистики снижается до %d" + +#: commands/statscmds.c:482 +#, c-format +msgid "statistics object \"%s.%s\" does not exist, skipping" +msgstr "объект статистики \"%s.%s\" не существует, пропускается" + +#: commands/subscriptioncmds.c:181 +#, c-format +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "нераспознанный параметр подписки: \"%s\"" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:195 commands/subscriptioncmds.c:201 +#: commands/subscriptioncmds.c:207 commands/subscriptioncmds.c:226 +#: commands/subscriptioncmds.c:232 +#, c-format +msgid "%s and %s are mutually exclusive options" +msgstr "указания %s и %s являются взаимоисключающими" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:239 commands/subscriptioncmds.c:245 +#, c-format +msgid "subscription with %s must also set %s" +msgstr "для подписки с параметром %s необходимо также задать %s" + +#: commands/subscriptioncmds.c:287 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "имя публикации \"%s\" используется неоднократно" + +#: commands/subscriptioncmds.c:351 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "для создания подписок нужно быть суперпользователем" + +#: commands/subscriptioncmds.c:442 commands/subscriptioncmds.c:530 +#: replication/logical/tablesync.c:857 replication/logical/worker.c:2095 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "не удалось подключиться к серверу публикации: %s" + +#: commands/subscriptioncmds.c:484 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "на сервере публикации создан слот репликации \"%s\"" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:497 +#, c-format +msgid "" +"tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "" +"в подписке отсутствуют таблицы; потребуется выполнить %s, чтобы подписаться " +"на таблицы" + +#: commands/subscriptioncmds.c:586 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "таблица \"%s.%s\" добавлена в подписку \"%s\"" + +#: commands/subscriptioncmds.c:610 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "таблица \"%s.%s\" удалена из подписки \"%s\"" + +#: commands/subscriptioncmds.c:682 +#, c-format +msgid "cannot set %s for enabled subscription" +msgstr "для включённой подписки нельзя задать %s" + +#: commands/subscriptioncmds.c:717 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "включить подписку, для которой не задано имя слота, нельзя" + +#: commands/subscriptioncmds.c:763 +#, c-format +msgid "" +"ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "" +"ALTER SUBSCRIPTION с обновлением для отключённых подписок не допускается" + +#: commands/subscriptioncmds.c:764 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "" +"Выполните ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:782 +#, c-format +msgid "" +"ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESH для отключённых подписок не допускается" + +#: commands/subscriptioncmds.c:862 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "подписка \"%s\" не существует, пропускается" + +#: commands/subscriptioncmds.c:987 +#, c-format +msgid "" +"could not connect to publisher when attempting to drop the replication slot " +"\"%s\"" +msgstr "" +"не удалось подключиться к серверу публикации для удаления слота репликации " +"\"%s\"" + +#: commands/subscriptioncmds.c:989 commands/subscriptioncmds.c:1004 +#: replication/logical/tablesync.c:906 replication/logical/tablesync.c:928 +#, c-format +msgid "The error was: %s" +msgstr "Произошла ошибка: %s" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:991 +#, c-format +msgid "Use %s to disassociate the subscription from the slot." +msgstr "Выполните %s, чтобы отвязать подписку от слота." + +#: commands/subscriptioncmds.c:1002 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "слот репликации \"%s\" на сервере публикации не был удалён" + +#: commands/subscriptioncmds.c:1007 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "слот репликации \"%s\" удалён на сервере репликации" + +#: commands/subscriptioncmds.c:1044 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "нет прав на изменение владельца подписки \"%s\"" + +#: commands/subscriptioncmds.c:1046 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "Владельцем подписки должен быть суперпользователь." + +#: commands/subscriptioncmds.c:1161 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "" +"не удалось получить список реплицируемых таблиц с сервера репликации: %s" + +#: commands/tablecmds.c:228 commands/tablecmds.c:270 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "таблица \"%s\" не существует" + +#: commands/tablecmds.c:229 commands/tablecmds.c:271 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "таблица \"%s\" не существует, пропускается" + +#: commands/tablecmds.c:231 commands/tablecmds.c:273 +msgid "Use DROP TABLE to remove a table." +msgstr "Выполните DROP TABLE для удаления таблицы." + +#: commands/tablecmds.c:234 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "последовательность \"%s\" не существует" + +#: commands/tablecmds.c:235 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "последовательность \"%s\" не существует, пропускается" + +#: commands/tablecmds.c:237 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "Выполните DROP SEQUENCE для удаления последовательности." + +#: commands/tablecmds.c:240 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "представление \"%s\" не существует" + +#: commands/tablecmds.c:241 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "представление \"%s\" не существует, пропускается" + +#: commands/tablecmds.c:243 +msgid "Use DROP VIEW to remove a view." +msgstr "Выполните DROP VIEW для удаления представления." + +#: commands/tablecmds.c:246 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr "материализованное представление \"%s\" не существует" + +#: commands/tablecmds.c:247 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr "материализованное представление \"%s\" не существует, пропускается" + +#: commands/tablecmds.c:249 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "" +"Выполните DROP MATERIALIZED VIEW для удаления материализованного " +"представления." + +#: commands/tablecmds.c:252 commands/tablecmds.c:276 commands/tablecmds.c:17253 +#: parser/parse_utilcmd.c:2196 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "индекс \"%s\" не существует" + +#: commands/tablecmds.c:253 commands/tablecmds.c:277 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "индекс \"%s\" не существует, пропускается" + +#: commands/tablecmds.c:255 commands/tablecmds.c:279 +msgid "Use DROP INDEX to remove an index." +msgstr "Выполните DROP INDEX для удаления индекса." + +#: commands/tablecmds.c:260 +#, c-format +msgid "\"%s\" is not a type" +msgstr "\"%s\" - это не тип" + +#: commands/tablecmds.c:261 +msgid "Use DROP TYPE to remove a type." +msgstr "Выполните DROP TYPE для удаления типа." + +#: commands/tablecmds.c:264 commands/tablecmds.c:12401 +#: commands/tablecmds.c:14860 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "сторонняя таблица \"%s\" не существует" + +#: commands/tablecmds.c:265 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "сторонняя таблица \"%s\" не существует, пропускается" + +#: commands/tablecmds.c:267 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "Выполните DROP FOREIGN TABLE для удаления сторонней таблицы." + +#: commands/tablecmds.c:620 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMIT можно использовать только для временных таблиц" + +#: commands/tablecmds.c:651 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "" +"в рамках операции с ограничениями по безопасности нельзя создать временную " +"таблицу" + +#: commands/tablecmds.c:687 commands/tablecmds.c:13764 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "отношение \"%s\" наследуется неоднократно" + +#: commands/tablecmds.c:868 +#, c-format +msgid "" +"specifying a table access method is not supported on a partitioned table" +msgstr "" +"указание табличного метода доступа для секционированных таблиц не " +"поддерживаются" + +#: commands/tablecmds.c:964 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "отношение \"%s\" не является секционированным" + +#: commands/tablecmds.c:1058 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "число столбцов в ключе секционирования не может превышать %d" + +#: commands/tablecmds.c:1114 +#, c-format +msgid "cannot create foreign partition of partitioned table \"%s\"" +msgstr "создать стороннюю секцию для секционированной таблицы \"%s\" нельзя" + +#: commands/tablecmds.c:1116 +#, c-format +msgid "Table \"%s\" contains indexes that are unique." +msgstr "Таблица \"%s\" содержит индексы, являющиеся уникальными." + +#: commands/tablecmds.c:1279 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLY не поддерживает удаление нескольких объектов" + +#: commands/tablecmds.c:1283 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLY не поддерживает режим CASCADE" + +#: commands/tablecmds.c:1384 +#, c-format +msgid "cannot drop partitioned index \"%s\" concurrently" +msgstr "удалить секционированный индекс \"%s\" параллельным способом нельзя" + +#: commands/tablecmds.c:1654 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "опустошить собственно секционированную таблицу нельзя" + +#: commands/tablecmds.c:1655 +#, c-format +msgid "" +"Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions " +"directly." +msgstr "" +"Не указывайте ключевое слово ONLY или выполните TRUNCATE ONLY " +"непосредственно для секций." + +#: commands/tablecmds.c:1724 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "опустошение распространяется на таблицу %s" + +#: commands/tablecmds.c:2031 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "временные таблицы других сеансов нельзя опустошить" + +#: commands/tablecmds.c:2259 commands/tablecmds.c:13661 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "наследование от секционированной таблицы \"%s\" не допускается" + +#: commands/tablecmds.c:2264 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "наследование от секции \"%s\" не допускается" + +#: commands/tablecmds.c:2272 parser/parse_utilcmd.c:2426 +#: parser/parse_utilcmd.c:2568 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "" +"наследуемое отношение \"%s\" не является таблицей или сторонней таблицей" + +#: commands/tablecmds.c:2284 +#, c-format +msgid "" +"cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "" +"создать временное отношение в качестве секции постоянного отношения \"%s\" " +"нельзя" + +#: commands/tablecmds.c:2293 commands/tablecmds.c:13640 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "временное отношение \"%s\" не может наследоваться" + +#: commands/tablecmds.c:2303 commands/tablecmds.c:13648 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "наследование от временного отношения другого сеанса невозможно" + +#: commands/tablecmds.c:2357 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "слияние нескольких наследованных определений столбца \"%s\"" + +#: commands/tablecmds.c:2365 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "конфликт типов в наследованном столбце \"%s\"" + +#: commands/tablecmds.c:2367 commands/tablecmds.c:2390 +#: commands/tablecmds.c:2639 commands/tablecmds.c:2669 +#: parser/parse_coerce.c:1935 parser/parse_coerce.c:1955 +#: parser/parse_coerce.c:1975 parser/parse_coerce.c:2030 +#: parser/parse_coerce.c:2107 parser/parse_coerce.c:2141 +#: parser/parse_param.c:218 +#, c-format +msgid "%s versus %s" +msgstr "%s и %s" + +#: commands/tablecmds.c:2376 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "конфликт правил сортировки в наследованном столбце \"%s\"" + +#: commands/tablecmds.c:2378 commands/tablecmds.c:2651 +#: commands/tablecmds.c:6108 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "\"%s\" и \"%s\"" + +#: commands/tablecmds.c:2388 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "конфликт параметров хранения в наследованном столбце \"%s\"" + +#: commands/tablecmds.c:2404 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "конфликт свойства генерирования в наследованном столбце \"%s\"" + +#: commands/tablecmds.c:2490 commands/tablecmds.c:2545 +#: commands/tablecmds.c:11206 parser/parse_utilcmd.c:1276 +#: parser/parse_utilcmd.c:1319 parser/parse_utilcmd.c:1727 +#: parser/parse_utilcmd.c:1836 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "преобразовать ссылку на тип всей строки таблицы нельзя" + +#: commands/tablecmds.c:2491 parser/parse_utilcmd.c:1277 +#, c-format +msgid "" +"Generation expression for column \"%s\" contains a whole-row reference to " +"table \"%s\"." +msgstr "" +"Генерирующее выражение столбца \"%s\" ссылается на тип всей строки в таблице " +"\"%s\"." + +#: commands/tablecmds.c:2546 parser/parse_utilcmd.c:1320 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "Ограничение \"%s\" ссылается на тип всей строки в таблице \"%s\"." + +#: commands/tablecmds.c:2625 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "слияние столбца \"%s\" с наследованным определением" + +#: commands/tablecmds.c:2629 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "перемещение и слияние столбца \"%s\" с наследуемым определением" + +#: commands/tablecmds.c:2630 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "" +"Определённый пользователем столбец перемещён в позицию наследуемого столбца." + +#: commands/tablecmds.c:2637 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "конфликт типов в столбце \"%s\"" + +#: commands/tablecmds.c:2649 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "конфликт правил сортировки в столбце \"%s\"" + +#: commands/tablecmds.c:2667 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "конфликт параметров хранения в столбце \"%s\"" + +#: commands/tablecmds.c:2695 +#, c-format +msgid "child column \"%s\" specifies generation expression" +msgstr "для дочернего столбца \"%s\" указано генерирующее выражение" + +#: commands/tablecmds.c:2697 +#, c-format +msgid "" +"Omit the generation expression in the definition of the child table column " +"to inherit the generation expression from the parent table." +msgstr "" +"Уберите генерирующее выражение из определения столбца в дочерней таблице, " +"чтобы это выражение наследовалось из родительской." + +#: commands/tablecmds.c:2701 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies default" +msgstr "" +"столбец \"%s\" наследуется от генерируемого столбца, но для него задано " +"значение по умолчанию" + +#: commands/tablecmds.c:2706 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies identity" +msgstr "" +"столбец \"%s\" наследуется от генерируемого столбца, но для него задано " +"свойство идентификации" + +#: commands/tablecmds.c:2815 +#, c-format +msgid "column \"%s\" inherits conflicting generation expressions" +msgstr "столбец \"%s\" наследует конфликтующие генерирующие выражения" + +#: commands/tablecmds.c:2820 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "столбец \"%s\" наследует конфликтующие значения по умолчанию" + +#: commands/tablecmds.c:2822 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "Для решения конфликта укажите желаемое значение по умолчанию." + +#: commands/tablecmds.c:2868 +#, c-format +msgid "" +"check constraint name \"%s\" appears multiple times but with different " +"expressions" +msgstr "" +"имя ограничения-проверки \"%s\" фигурирует несколько раз, но с разными " +"выражениями" + +#: commands/tablecmds.c:3045 +#, c-format +msgid "cannot rename column of typed table" +msgstr "переименовать столбец типизированной таблицы нельзя" + +#: commands/tablecmds.c:3064 +#, c-format +msgid "" +"\"%s\" is not a table, view, materialized view, composite type, index, or " +"foreign table" +msgstr "" +"\"%s\" - это не таблица, представление, материализованное представление, " +"составной тип, индекс или сторонняя таблица" + +#: commands/tablecmds.c:3158 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "" +"наследованный столбец \"%s\" должен быть также переименован в дочерних " +"таблицах" + +#: commands/tablecmds.c:3190 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "нельзя переименовать системный столбец \"%s\"" + +#: commands/tablecmds.c:3205 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "нельзя переименовать наследованный столбец \"%s\"" + +#: commands/tablecmds.c:3357 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "" +"наследуемое ограничение \"%s\" должно быть также переименовано в дочерних " +"таблицах" + +#: commands/tablecmds.c:3364 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "нельзя переименовать наследованное ограничение \"%s\"" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3597 +#, c-format +msgid "" +"cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "" +"нельзя выполнить %s \"%s\", так как этот объект используется активными " +"запросами в данном сеансе" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3606 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "" +"нельзя выполнить %s \"%s\", так как с этим объектом связаны отложенные " +"события триггеров" + +#: commands/tablecmds.c:4237 commands/tablecmds.c:4252 +#, c-format +msgid "cannot change persistence setting twice" +msgstr "изменить характеристику хранения дважды нельзя" + +#: commands/tablecmds.c:4971 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "перезаписать системное отношение \"%s\" нельзя" + +#: commands/tablecmds.c:4977 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "перезаписать таблицу \"%s\", используемую как таблицу каталога, нельзя" + +#: commands/tablecmds.c:4987 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "перезаписывать временные таблицы других сеансов нельзя" + +#: commands/tablecmds.c:5276 +#, c-format +msgid "rewriting table \"%s\"" +msgstr "перезапись таблицы \"%s\"" + +#: commands/tablecmds.c:5280 +#, c-format +msgid "verifying table \"%s\"" +msgstr "проверка таблицы \"%s\"" + +#: commands/tablecmds.c:5445 +#, c-format +msgid "column \"%s\" of relation \"%s\" contains null values" +msgstr "столбец \"%s\" отношения \"%s\" содержит значения NULL" + +#: commands/tablecmds.c:5462 +#, c-format +msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" +msgstr "ограничение-проверку \"%s\" отношения \"%s\" нарушает некоторая строка" + +#: commands/tablecmds.c:5481 partitioning/partbounds.c:3225 +#, c-format +msgid "" +"updated partition constraint for default partition \"%s\" would be violated " +"by some row" +msgstr "" +"изменённое ограничение секции для секции по умолчанию \"%s\" будет нарушено " +"некоторыми строками" + +#: commands/tablecmds.c:5487 +#, c-format +msgid "partition constraint of relation \"%s\" is violated by some row" +msgstr "ограничение секции отношения \"%s\" нарушает некоторая строка" + +#: commands/tablecmds.c:5634 commands/trigger.c:1200 commands/trigger.c:1306 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "\"%s\" - это не таблица, представление и не сторонняя таблица" + +#: commands/tablecmds.c:5637 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "" +"\"%s\" - это не таблица, представление, материализованное представление или " +"индекс" + +#: commands/tablecmds.c:5643 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "\"%s\" - это не таблица, материализованное представление или индекс" + +#: commands/tablecmds.c:5646 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "" +"\"%s\" - это не таблица, материализованное представление или сторонняя " +"таблица" + +#: commands/tablecmds.c:5649 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "\"%s\" - это не таблица и не сторонняя таблица" + +#: commands/tablecmds.c:5652 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "\"%s\" - это не таблица, составной тип или сторонняя таблица" + +#: commands/tablecmds.c:5655 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "" +"\"%s\" - это не таблица, материализованное представление, индекс или " +"сторонняя таблица" + +#: commands/tablecmds.c:5665 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "неправильный тип \"%s\"" + +#: commands/tablecmds.c:5868 commands/tablecmds.c:5875 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "" +"изменить тип \"%s\" нельзя, так как он задействован в столбце \"%s.%s\"" + +#: commands/tablecmds.c:5882 +#, c-format +msgid "" +"cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "" +"изменить стороннюю таблицу \"%s\" нельзя, так как столбец \"%s.%s\" " +"задействует тип её строки" + +#: commands/tablecmds.c:5889 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "" +"изменить таблицу \"%s\" нельзя, так как столбец \"%s.%s\" задействует тип её " +"строки" + +#: commands/tablecmds.c:5945 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "изменить тип \"%s\", так как это тип типизированной таблицы" + +#: commands/tablecmds.c:5947 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "" +"Чтобы изменить также типизированные таблицы, выполните ALTER ... CASCADE." + +#: commands/tablecmds.c:5993 +#, c-format +msgid "type %s is not a composite type" +msgstr "тип %s не является составным" + +#: commands/tablecmds.c:6020 +#, c-format +msgid "cannot add column to typed table" +msgstr "добавить столбец в типизированную таблицу нельзя" + +#: commands/tablecmds.c:6071 +#, c-format +msgid "cannot add column to a partition" +msgstr "добавить столбец в секцию нельзя" + +#: commands/tablecmds.c:6100 commands/tablecmds.c:13891 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "дочерняя таблица \"%s\" имеет другой тип для столбца \"%s\"" + +#: commands/tablecmds.c:6106 commands/tablecmds.c:13898 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "" +"дочерняя таблица \"%s\" имеет другое правило сортировки для столбца \"%s\"" + +#: commands/tablecmds.c:6120 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "объединение определений столбца \"%s\" для потомка \"%s\"" + +#: commands/tablecmds.c:6163 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "" +"добавить столбец идентификации в таблицу, у которой есть дочерние, нельзя" + +#: commands/tablecmds.c:6400 +#, c-format +msgid "column must be added to child tables too" +msgstr "столбец также должен быть добавлен к дочерним таблицам" + +#: commands/tablecmds.c:6478 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "столбец \"%s\" отношения \"%s\" уже существует, пропускается" + +#: commands/tablecmds.c:6485 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "столбец \"%s\" отношения \"%s\" уже существует" + +#: commands/tablecmds.c:6551 commands/tablecmds.c:10844 +#, c-format +msgid "" +"cannot remove constraint from only the partitioned table when partitions " +"exist" +msgstr "" +"удалить ограничение только из секционированной таблицы, когда существуют " +"секции, нельзя" + +#: commands/tablecmds.c:6552 commands/tablecmds.c:6856 +#: commands/tablecmds.c:7852 commands/tablecmds.c:10845 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "Не указывайте ключевое слово ONLY." + +#: commands/tablecmds.c:6589 commands/tablecmds.c:6782 +#: commands/tablecmds.c:6924 commands/tablecmds.c:7038 +#: commands/tablecmds.c:7132 commands/tablecmds.c:7191 +#: commands/tablecmds.c:7309 commands/tablecmds.c:7475 +#: commands/tablecmds.c:7545 commands/tablecmds.c:7638 +#: commands/tablecmds.c:10999 commands/tablecmds.c:12424 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "системный столбец \"%s\" нельзя изменить" + +#: commands/tablecmds.c:6595 commands/tablecmds.c:6930 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "столбец \"%s\" отношения \"%s\" является столбцом идентификации" + +#: commands/tablecmds.c:6631 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "столбец \"%s\" входит в первичный ключ" + +#: commands/tablecmds.c:6653 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "столбец \"%s\" в родительской таблице помечен как NOT NULL" + +#: commands/tablecmds.c:6853 commands/tablecmds.c:8311 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "ограничение также должно быть добавлено к дочерним таблицам" + +#: commands/tablecmds.c:6854 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "Столбец \"%s\" отношения \"%s\" уже имеет свойство NOT NULL." + +#: commands/tablecmds.c:6889 +#, c-format +msgid "" +"existing constraints on column \"%s.%s\" are sufficient to prove that it " +"does not contain nulls" +msgstr "" +"существующие ограничения для столбца \"%s.%s\" гарантируют, что он не " +"содержит NULL" + +#: commands/tablecmds.c:6932 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "Вместо этого выполните ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." + +#: commands/tablecmds.c:6937 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "столбец \"%s\" отношения \"%s\" является генерируемым" + +#: commands/tablecmds.c:6940 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." +msgstr "" +"Вместо этого выполните ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION." + +#: commands/tablecmds.c:7049 +#, c-format +msgid "" +"column \"%s\" of relation \"%s\" must be declared NOT NULL before identity " +"can be added" +msgstr "" +"столбец \"%s\" отношения \"%s\" должен быть объявлен как NOT NULL, чтобы его " +"можно было сделать столбцом идентификации" + +#: commands/tablecmds.c:7055 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "столбец \"%s\" отношения \"%s\" уже является столбцом идентификации" + +#: commands/tablecmds.c:7061 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "столбец \"%s\" отношения \"%s\" уже имеет значение по умолчанию" + +#: commands/tablecmds.c:7138 commands/tablecmds.c:7199 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "столбец \"%s\" отношения \"%s\" не является столбцом идентификации" + +#: commands/tablecmds.c:7204 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "" +"столбец \"%s\" отношения \"%s\" не является столбцом идентификации, " +"пропускается" + +#: commands/tablecmds.c:7257 +#, c-format +msgid "ALTER TABLE / DROP EXPRESSION must be applied to child tables too" +msgstr "" +"ALTER TABLE / DROP EXPRESSION нужно применять также к дочерним таблицам" + +#: commands/tablecmds.c:7279 +#, c-format +msgid "cannot drop generation expression from inherited column" +msgstr "нельзя удалить генерирующее выражение из наследуемого столбца" + +#: commands/tablecmds.c:7317 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column" +msgstr "" +"столбец \"%s\" отношения \"%s\" не является сохранённым генерируемым столбцом" + +#: commands/tablecmds.c:7322 +#, c-format +msgid "" +"column \"%s\" of relation \"%s\" is not a stored generated column, skipping" +msgstr "" +"столбец \"%s\" отношения \"%s\" пропускается, так как не является " +"сохранённым генерируемым столбцом" + +#: commands/tablecmds.c:7422 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "по номеру можно ссылаться только на столбец в индексе" + +#: commands/tablecmds.c:7465 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "столбец с номером %d отношения \"%s\" не существует" + +#: commands/tablecmds.c:7484 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "изменить статистику включённого столбца \"%s\" индекса \"%s\" нельзя" + +#: commands/tablecmds.c:7489 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "" +"изменить статистику столбца \"%s\" (не выражения) индекса \"%s\" нельзя" + +#: commands/tablecmds.c:7491 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Вместо этого измените статистику для столбца в таблице." + +#: commands/tablecmds.c:7618 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "неверный тип хранилища \"%s\"" + +#: commands/tablecmds.c:7650 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "тип данных столбца %s совместим только с хранилищем PLAIN" + +#: commands/tablecmds.c:7732 +#, c-format +msgid "cannot drop column from typed table" +msgstr "нельзя удалить столбец в типизированной таблице" + +#: commands/tablecmds.c:7791 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "столбец \"%s\" в таблице\"%s\" не существует, пропускается" + +#: commands/tablecmds.c:7804 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "нельзя удалить системный столбец \"%s\"" + +#: commands/tablecmds.c:7814 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "нельзя удалить наследованный столбец \"%s\"" + +#: commands/tablecmds.c:7827 +#, c-format +msgid "" +"cannot drop column \"%s\" because it is part of the partition key of " +"relation \"%s\"" +msgstr "" +"удалить столбец \"%s\" нельзя, так как он входит в ключ разбиения отношения " +"\"%s\"" + +#: commands/tablecmds.c:7851 +#, c-format +msgid "" +"cannot drop column from only the partitioned table when partitions exist" +msgstr "" +"удалить столбец только из секционированной таблицы, когда существуют секции, " +"нельзя" + +#: commands/tablecmds.c:8032 +#, c-format +msgid "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned " +"tables" +msgstr "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX не поддерживается с " +"секционированными таблицами" + +#: commands/tablecmds.c:8057 +#, c-format +msgid "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX переименует индекс \"%s\" в \"%s\"" + +#: commands/tablecmds.c:8391 +#, c-format +msgid "" +"cannot use ONLY for foreign key on partitioned table \"%s\" referencing " +"relation \"%s\"" +msgstr "" +"нельзя использовать ONLY для стороннего ключа в секционированной таблице \"%s" +"\", ссылающегося на отношение \"%s\"" + +#: commands/tablecmds.c:8397 +#, c-format +msgid "" +"cannot add NOT VALID foreign key on partitioned table \"%s\" referencing " +"relation \"%s\"" +msgstr "" +"нельзя добавить с характеристикой NOT VALID сторонний ключ в " +"секционированной таблице \"%s\", ссылающийся на отношение \"%s\"" + +#: commands/tablecmds.c:8400 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "" +"Эта функциональность с секционированными таблицами пока не поддерживается." + +#: commands/tablecmds.c:8407 commands/tablecmds.c:8812 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "указанный объект \"%s\" не является таблицей" + +#: commands/tablecmds.c:8430 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "" +"ограничения в постоянных таблицах могут ссылаться только на постоянные " +"таблицы" + +#: commands/tablecmds.c:8437 +#, c-format +msgid "" +"constraints on unlogged tables may reference only permanent or unlogged " +"tables" +msgstr "" +"ограничения в нежурналируемых таблицах могут ссылаться только на постоянные " +"или нежурналируемые таблицы" + +#: commands/tablecmds.c:8443 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "" +"ограничения во временных таблицах могут ссылаться только на временные таблицы" + +#: commands/tablecmds.c:8447 +#, c-format +msgid "" +"constraints on temporary tables must involve temporary tables of this session" +msgstr "" +"ограничения во временных таблицах должны ссылаться только на временные " +"таблицы текущего сеанса" + +#: commands/tablecmds.c:8513 commands/tablecmds.c:8519 +#, c-format +msgid "" +"invalid %s action for foreign key constraint containing generated column" +msgstr "" +"некорректное действие %s для ограничения внешнего ключа, содержащего " +"генерируемый столбец" + +#: commands/tablecmds.c:8535 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "число столбцов в источнике и назначении внешнего ключа не совпадает" + +#: commands/tablecmds.c:8642 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "ограничение внешнего ключа \"%s\" нельзя реализовать" + +#: commands/tablecmds.c:8644 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "Столбцы ключа \"%s\" и \"%s\" имеют несовместимые типы: %s и %s." + +#: commands/tablecmds.c:9007 commands/tablecmds.c:9400 +#: parser/parse_utilcmd.c:780 parser/parse_utilcmd.c:909 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "ограничения внешнего ключа для сторонних таблиц не поддерживаются" + +#: commands/tablecmds.c:9766 commands/tablecmds.c:9929 +#: commands/tablecmds.c:10801 commands/tablecmds.c:10876 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "ограничение \"%s\" в таблице \"%s\" не существует" + +#: commands/tablecmds.c:9773 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "ограничение \"%s\" в таблице \"%s\" не является внешним ключом" + +#: commands/tablecmds.c:9937 +#, c-format +msgid "" +"constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "" +"ограничение \"%s\" в таблице \"%s\" не является внешним ключом или " +"ограничением-проверкой" + +#: commands/tablecmds.c:10015 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "ограничение также должно соблюдаться в дочерних таблицах" + +#: commands/tablecmds.c:10099 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "столбец \"%s\", указанный в ограничении внешнего ключа, не существует" + +#: commands/tablecmds.c:10104 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "во внешнем ключе не может быть больше %d столбцов" + +#: commands/tablecmds.c:10169 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "" +"использовать откладываемый первичный ключ в целевой внешней таблице \"%s\" " +"нельзя" + +#: commands/tablecmds.c:10186 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "в целевой внешней таблице \"%s\" нет первичного ключа" + +#: commands/tablecmds.c:10251 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "в списке столбцов внешнего ключа не должно быть повторений" + +#: commands/tablecmds.c:10345 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "" +"использовать откладываемое ограничение уникальности в целевой внешней " +"таблице \"%s\" нельзя" + +#: commands/tablecmds.c:10350 +#, c-format +msgid "" +"there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "" +"в целевой внешней таблице \"%s\" нет ограничения уникальности, " +"соответствующего данным ключам" + +#: commands/tablecmds.c:10438 +#, c-format +msgid "validating foreign key constraint \"%s\"" +msgstr "проверка ограничения внешнего ключа \"%s\"" + +#: commands/tablecmds.c:10757 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "удалить наследованное ограничение \"%s\" таблицы \"%s\" нельзя" + +#: commands/tablecmds.c:10807 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "ограничение \"%s\" в таблице \"%s\" не существует, пропускается" + +#: commands/tablecmds.c:10983 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "изменить тип столбца в типизированной таблице нельзя" + +#: commands/tablecmds.c:11010 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "изменить наследованный столбец \"%s\" нельзя" + +#: commands/tablecmds.c:11019 +#, c-format +msgid "" +"cannot alter column \"%s\" because it is part of the partition key of " +"relation \"%s\"" +msgstr "" +"изменить столбец \"%s\" нельзя, так как он входит в ключ разбиения отношения " +"\"%s\"" + +#: commands/tablecmds.c:11069 +#, c-format +msgid "" +"result of USING clause for column \"%s\" cannot be cast automatically to " +"type %s" +msgstr "" +"результат USING для столбца \"%s\" нельзя автоматически привести к типу %s" + +#: commands/tablecmds.c:11072 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "Возможно, необходимо добавить явное приведение." + +#: commands/tablecmds.c:11076 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "столбец \"%s\" нельзя автоматически привести к типу %s" + +# skip-rule: double-colons +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:11079 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "Возможно, необходимо указать \"USING %s::%s\"." + +#: commands/tablecmds.c:11179 +#, c-format +msgid "cannot alter inherited column \"%s\" of relation \"%s\"" +msgstr "изменить наследованный столбец \"%s\" отношения \"%s\" нельзя" + +#: commands/tablecmds.c:11207 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "Выражение USING ссылается на тип всей строки таблицы." + +#: commands/tablecmds.c:11218 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "" +"тип наследованного столбца \"%s\" должен быть изменён и в дочерних таблицах" + +#: commands/tablecmds.c:11343 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "нельзя изменить тип столбца \"%s\" дважды" + +#: commands/tablecmds.c:11381 +#, c-format +msgid "" +"generation expression for column \"%s\" cannot be cast automatically to type " +"%s" +msgstr "" +"генерирующее выражение для столбца \"%s\" нельзя автоматически привести к " +"типу %s" + +#: commands/tablecmds.c:11386 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "" +"значение по умолчанию для столбца \"%s\" нельзя автоматически привести к " +"типу %s" + +#: commands/tablecmds.c:11464 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "изменить тип столбца, задействованного в генерируемом столбце, нельзя" + +#: commands/tablecmds.c:11465 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "Столбец \"%s\" используется генерируемым столбцом \"%s\"." + +#: commands/tablecmds.c:11486 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "" +"изменить тип столбца, задействованного в представлении или правиле, нельзя" + +#: commands/tablecmds.c:11487 commands/tablecmds.c:11506 +#: commands/tablecmds.c:11524 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%s зависит от столбца \"%s\"" + +#: commands/tablecmds.c:11505 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "изменить тип столбца, задействованного в определении триггера, нельзя" + +#: commands/tablecmds.c:11523 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "изменить тип столбца, задействованного в определении политики, нельзя" + +#: commands/tablecmds.c:12532 commands/tablecmds.c:12544 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "сменить владельца индекса \"%s\" нельзя" + +#: commands/tablecmds.c:12534 commands/tablecmds.c:12546 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "Однако возможно сменить владельца таблицы, содержащей этот индекс." + +#: commands/tablecmds.c:12560 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "сменить владельца последовательности \"%s\" нельзя" + +#: commands/tablecmds.c:12574 commands/tablecmds.c:15765 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "Используйте ALTER TYPE." + +#: commands/tablecmds.c:12583 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "" +"\"%s\" - это не таблица, TOAST-таблица, индекс, представление или " +"последовательность" + +#: commands/tablecmds.c:12923 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "в одной инструкции не может быть несколько подкоманд SET TABLESPACE" + +#: commands/tablecmds.c:13000 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "" +"\"%s\" - это не таблица, представление, материализованное представление, " +"индекс или TOAST-таблица" + +#: commands/tablecmds.c:13033 commands/view.c:494 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "" +"WITH CHECK OPTION поддерживается только с автообновляемыми представлениями" + +#: commands/tablecmds.c:13173 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "переместить системную таблицу \"%s\" нельзя" + +#: commands/tablecmds.c:13189 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "перемещать временные таблицы других сеансов нельзя" + +#: commands/tablecmds.c:13363 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "" +"в табличных пространствах есть только таблицы, индексы и материализованные " +"представления" + +#: commands/tablecmds.c:13375 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "перемещать объекты в/из табличного пространства pg_global нельзя" + +#: commands/tablecmds.c:13467 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "" +"обработка прерывается из-за невозможности заблокировать отношение \"%s.%s\"" + +#: commands/tablecmds.c:13483 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "в табличном пространстве \"%s\" не найдены подходящие отношения" + +#: commands/tablecmds.c:13599 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "изменить наследование типизированной таблицы нельзя" + +#: commands/tablecmds.c:13604 commands/tablecmds.c:14100 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "изменить наследование секции нельзя" + +#: commands/tablecmds.c:13609 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "изменить наследование секционированной таблицы нельзя" + +#: commands/tablecmds.c:13655 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "наследование для временного отношения другого сеанса невозможно" + +#: commands/tablecmds.c:13668 +#, c-format +msgid "cannot inherit from a partition" +msgstr "наследование от секции невозможно" + +#: commands/tablecmds.c:13690 commands/tablecmds.c:16405 +#, c-format +msgid "circular inheritance not allowed" +msgstr "циклическое наследование недопустимо" + +#: commands/tablecmds.c:13691 commands/tablecmds.c:16406 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "\"%s\" уже является потомком \"%s\"." + +#: commands/tablecmds.c:13704 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "" +"триггер \"%s\" не позволяет таблице \"%s\" стать потомком в иерархии " +"наследования" + +#: commands/tablecmds.c:13706 +#, c-format +msgid "" +"ROW triggers with transition tables are not supported in inheritance " +"hierarchies." +msgstr "" +"Триггеры ROW с переходными таблицами не поддерживаются в иерархиях " +"наследования." + +#: commands/tablecmds.c:13909 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "столбец \"%s\" в дочерней таблице должен быть помечен как NOT NULL" + +#: commands/tablecmds.c:13936 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "в дочерней таблице не хватает столбца \"%s\"" + +#: commands/tablecmds.c:14024 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "" +"дочерняя таблица \"%s\" содержит другое определение ограничения-проверки \"%s" +"\"" + +#: commands/tablecmds.c:14032 +#, c-format +msgid "" +"constraint \"%s\" conflicts with non-inherited constraint on child table \"%s" +"\"" +msgstr "" +"ограничение \"%s\" конфликтует с ненаследуемым ограничением дочерней таблицы " +"\"%s\"" + +#: commands/tablecmds.c:14043 +#, c-format +msgid "" +"constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "" +"ограничение \"%s\" конфликтует с непроверенным (NOT VALID) ограничением " +"дочерней таблицы \"%s\"" + +#: commands/tablecmds.c:14078 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "в дочерней таблице не хватает ограничения \"%s\"" + +#: commands/tablecmds.c:14167 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "отношение \"%s\" не является секцией отношения \"%s\"" + +#: commands/tablecmds.c:14173 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "отношение \"%s\" не является предком отношения \"%s\"" + +#: commands/tablecmds.c:14401 +#, c-format +msgid "typed tables cannot inherit" +msgstr "типизированные таблицы не могут наследоваться" + +#: commands/tablecmds.c:14431 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "в таблице не хватает столбца \"%s\"" + +#: commands/tablecmds.c:14442 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "таблица содержит столбец \"%s\", тогда как тип требует \"%s\"" + +#: commands/tablecmds.c:14451 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "таблица \"%s\" содержит столбец \"%s\" другого типа" + +#: commands/tablecmds.c:14465 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "таблица содержит лишний столбец \"%s\"" + +#: commands/tablecmds.c:14517 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "\"%s\" - это не типизированная таблица" + +#: commands/tablecmds.c:14699 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "" +"для идентификации реплики нельзя использовать неуникальный индекс \"%s\"" + +#: commands/tablecmds.c:14705 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "" +"для идентификации реплики нельзя использовать не непосредственный индекс \"%s" +"\"" + +#: commands/tablecmds.c:14711 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "" +"для идентификации реплики нельзя использовать индекс с выражением \"%s\"" + +#: commands/tablecmds.c:14717 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "для идентификации реплики нельзя использовать частичный индекс \"%s\"" + +#: commands/tablecmds.c:14723 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "для идентификации реплики нельзя использовать нерабочий индекс \"%s\"" + +#: commands/tablecmds.c:14740 +#, c-format +msgid "" +"index \"%s\" cannot be used as replica identity because column %d is a " +"system column" +msgstr "" +"индекс \"%s\" нельзя использовать для идентификации реплики, так как столбец " +"%d - системный" + +#: commands/tablecmds.c:14747 +#, c-format +msgid "" +"index \"%s\" cannot be used as replica identity because column \"%s\" is " +"nullable" +msgstr "" +"индекс \"%s\" нельзя использовать для идентификации реплики, так как столбец " +"\"%s\" допускает NULL" + +#: commands/tablecmds.c:14940 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "" +"изменить состояние журналирования таблицы %s нельзя, так как она временная" + +#: commands/tablecmds.c:14964 +#, c-format +msgid "" +"cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "" +"таблицу \"%s\" нельзя сделать нежурналируемой, так как она включена в " +"публикацию" + +#: commands/tablecmds.c:14966 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "Нежурналируемые отношения не поддерживают репликацию." + +#: commands/tablecmds.c:15011 +#, c-format +msgid "" +"could not change table \"%s\" to logged because it references unlogged table " +"\"%s\"" +msgstr "" +"не удалось сделать таблицу \"%s\" журналируемой, так как она ссылается на " +"нежурналируемую таблицу \"%s\"" + +#: commands/tablecmds.c:15021 +#, c-format +msgid "" +"could not change table \"%s\" to unlogged because it references logged table " +"\"%s\"" +msgstr "" +"не удалось сделать таблицу \"%s\" нежурналируемой, так как она ссылается на " +"журналируемую таблицу \"%s\"" + +#: commands/tablecmds.c:15079 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "переместить последовательность с владельцем в другую схему нельзя" + +#: commands/tablecmds.c:15185 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "отношение \"%s\" уже существует в схеме \"%s\"" + +#: commands/tablecmds.c:15748 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "\"%s\" - это не составной тип" + +#: commands/tablecmds.c:15780 +#, c-format +msgid "" +"\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "" +"\"%s\" - это не таблица, представление, мат. представление, " +"последовательность или сторонняя таблица" + +#: commands/tablecmds.c:15815 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "нераспознанная стратегия секционирования \"%s\"" + +#: commands/tablecmds.c:15823 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "стратегия секционирования по списку не поддерживает несколько столбцов" + +#: commands/tablecmds.c:15889 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "столбец \"%s\", упомянутый в ключе секционирования, не существует" + +#: commands/tablecmds.c:15897 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "системный столбец \"%s\" нельзя использовать в ключе секционирования" + +#: commands/tablecmds.c:15908 commands/tablecmds.c:16022 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "генерируемый столбец нельзя использовать в ключе секционирования" + +#: commands/tablecmds.c:15909 commands/tablecmds.c:16023 commands/trigger.c:641 +#: rewrite/rewriteHandler.c:830 rewrite/rewriteHandler.c:847 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "Столбец \"%s\" является генерируемым." + +#: commands/tablecmds.c:15985 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "" +"функции в выражении ключа секционирования должны быть помечены как IMMUTABLE" + +#: commands/tablecmds.c:16005 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "" +"выражения ключей секционирования не могут содержать ссылки на системный " +"столбец" + +#: commands/tablecmds.c:16035 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "" +"в качестве ключа секционирования нельзя использовать константное выражение" + +#: commands/tablecmds.c:16056 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "не удалось определить правило сортировки для выражения секционирования" + +#: commands/tablecmds.c:16091 +#, c-format +msgid "" +"You must specify a hash operator class or define a default hash operator " +"class for the data type." +msgstr "" +"Вы должны указать класс операторов хеширования или определить класс " +"операторов хеширования по умолчанию для этого типа данных." + +#: commands/tablecmds.c:16097 +#, c-format +msgid "" +"You must specify a btree operator class or define a default btree operator " +"class for the data type." +msgstr "" +"Вы должны указать класс операторов B-дерева или определить класс операторов " +"B-дерева по умолчанию для этого типа данных." + +#: commands/tablecmds.c:16242 +#, c-format +msgid "" +"partition constraint for table \"%s\" is implied by existing constraints" +msgstr "" +"ограничение секции для таблицы \"%s\" подразумевается существующими " +"ограничениями" + +#: commands/tablecmds.c:16246 partitioning/partbounds.c:3119 +#: partitioning/partbounds.c:3170 +#, c-format +msgid "" +"updated partition constraint for default partition \"%s\" is implied by " +"existing constraints" +msgstr "" +"изменённое ограничение секции для секции по умолчанию \"%s\" подразумевается " +"существующими ограничениями" + +#: commands/tablecmds.c:16345 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\" уже является секцией" + +#: commands/tablecmds.c:16351 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "подключить типизированную таблицу в качестве секции нельзя" + +#: commands/tablecmds.c:16367 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "подключить потомок в иерархии наследования в качестве секции нельзя" + +#: commands/tablecmds.c:16381 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "подключить родитель в иерархии наследования в качестве секции нельзя" + +#: commands/tablecmds.c:16415 +#, c-format +msgid "" +"cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "" +"подключить временное отношение в качестве секции постоянного отношения \"%s" +"\" нельзя" + +#: commands/tablecmds.c:16423 +#, c-format +msgid "" +"cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "" +"подключить постоянное отношение в качестве секции временного отношения \"%s" +"\" нельзя" + +#: commands/tablecmds.c:16431 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "подключить секцию к временному отношению в другом сеансе нельзя" + +#: commands/tablecmds.c:16438 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "" +"подключить временное отношение из другого сеанса в качестве секции нельзя" + +#: commands/tablecmds.c:16458 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "" +"таблица \"%s\" содержит столбец \"%s\", отсутствующий в родителе \"%s\"" + +#: commands/tablecmds.c:16461 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "" +"Новая секция может содержать только столбцы, имеющиеся в родительской " +"таблице." + +#: commands/tablecmds.c:16473 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "триггер \"%s\" не позволяет сделать таблицу \"%s\" секцией" + +#: commands/tablecmds.c:16475 commands/trigger.c:447 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "триггеры ROW с переходными таблицами для секций не поддерживаются" + +#: commands/tablecmds.c:16638 +#, c-format +msgid "" +"cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" +msgstr "" +"нельзя присоединить стороннюю таблицу \"%s\" в качестве секции таблицы \"%s\"" + +#: commands/tablecmds.c:16641 +#, c-format +msgid "Table \"%s\" contains unique indexes." +msgstr "Таблица \"%s\" содержит уникальные индексы." + +#: commands/tablecmds.c:17287 commands/tablecmds.c:17307 +#: commands/tablecmds.c:17327 commands/tablecmds.c:17346 +#: commands/tablecmds.c:17388 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "нельзя присоединить индекс \"%s\" в качестве секции индекса \"%s\"" + +#: commands/tablecmds.c:17290 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "Индекс \"%s\" уже присоединён к другому индексу." + +#: commands/tablecmds.c:17310 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "Индекс \"%s\" не является индексом какой-либо секции таблицы \"%s\"." + +#: commands/tablecmds.c:17330 +#, c-format +msgid "The index definitions do not match." +msgstr "Определения индексов не совпадают." + +#: commands/tablecmds.c:17349 +#, c-format +msgid "" +"The index \"%s\" belongs to a constraint in table \"%s\" but no constraint " +"exists for index \"%s\"." +msgstr "" +"Индекс \"%s\" принадлежит ограничению в таблице \"%s\", но для индекса \"%s" +"\" ограничения нет." + +#: commands/tablecmds.c:17391 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "К секции \"%s\" уже присоединён другой индекс." + +#: commands/tablespace.c:162 commands/tablespace.c:179 +#: commands/tablespace.c:190 commands/tablespace.c:198 +#: commands/tablespace.c:650 replication/slot.c:1373 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не удалось создать каталог \"%s\": %m" + +#: commands/tablespace.c:209 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "не удалось получить информацию о каталоге \"%s\": %m" + +#: commands/tablespace.c:218 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "\"%s\" существует, но это не каталог" + +#: commands/tablespace.c:249 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "нет прав на создание табличного пространства \"%s\"" + +#: commands/tablespace.c:251 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "Для создания табличного пространства нужно быть суперпользователем." + +#: commands/tablespace.c:267 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "в пути к табличному пространству не должно быть одинарных кавычек" + +#: commands/tablespace.c:277 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "путь к табличному пространству должен быть абсолютным" + +#: commands/tablespace.c:289 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "путь к табличному пространству \"%s\" слишком длинный" + +#: commands/tablespace.c:296 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "табличное пространство не должно располагаться внутри каталога данных" + +#: commands/tablespace.c:305 commands/tablespace.c:977 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "неприемлемое имя табличного пространства: \"%s\"" + +#: commands/tablespace.c:307 commands/tablespace.c:978 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "Префикс \"pg_\" зарезервирован для системных табличных пространств." + +#: commands/tablespace.c:326 commands/tablespace.c:999 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "табличное пространство \"%s\" уже существует" + +#: commands/tablespace.c:444 commands/tablespace.c:960 +#: commands/tablespace.c:1049 commands/tablespace.c:1118 +#: commands/tablespace.c:1264 commands/tablespace.c:1467 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "табличное пространство \"%s\" не существует" + +#: commands/tablespace.c:450 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "табличное пространство \"%s\" не существует, пропускается" + +#: commands/tablespace.c:478 +#, c-format +msgid "tablespace \"%s\" cannot be dropped because some objects depend on it" +msgstr "" +"табличное пространство \"%s\" нельзя удалить, так как есть зависящие от него " +"объекты" + +#: commands/tablespace.c:537 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "табличное пространство \"%s\" не пусто" + +#: commands/tablespace.c:609 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "каталог \"%s\" не существует" + +#: commands/tablespace.c:610 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "" +"Создайте этот каталог для табличного пространства до перезапуска сервера." + +#: commands/tablespace.c:615 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "не удалось установить права для каталога \"%s\": %m" + +#: commands/tablespace.c:645 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "каталог \"%s\" уже используется как табличное пространство" + +#: commands/tablespace.c:769 commands/tablespace.c:782 +#: commands/tablespace.c:818 commands/tablespace.c:910 storage/file/fd.c:3108 +#: storage/file/fd.c:3448 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "ошибка при удалении каталога \"%s\": %m" + +#: commands/tablespace.c:831 commands/tablespace.c:919 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "ошибка при удалении символической ссылки \"%s\": %m" + +#: commands/tablespace.c:841 commands/tablespace.c:928 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "\"%s\" - это не каталог или символическая ссылка" + +#: commands/tablespace.c:1123 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "Табличное пространство \"%s\" не существует." + +#: commands/tablespace.c:1566 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "удалить каталоги табличного пространства %u не удалось" + +#: commands/tablespace.c:1568 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "При необходимости вы можете удалить их вручную." + +#: commands/trigger.c:204 commands/trigger.c:215 +#, c-format +msgid "\"%s\" is a table" +msgstr "\"%s\" - это таблица" + +#: commands/trigger.c:206 commands/trigger.c:217 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "У таблиц не может быть триггеров INSTEAD OF." + +#: commands/trigger.c:238 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\" - секционированная таблица" + +#: commands/trigger.c:240 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "" +"Триггеры секционированных таблиц не могут использовать переходные таблицы." + +#: commands/trigger.c:252 commands/trigger.c:259 commands/trigger.c:429 +#, c-format +msgid "\"%s\" is a view" +msgstr "\"%s\" - это представление" + +#: commands/trigger.c:254 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "У представлений не может быть строковых триггеров BEFORE/AFTER." + +#: commands/trigger.c:261 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "У представлений не может быть триггеров TRUNCATE." + +#: commands/trigger.c:269 commands/trigger.c:276 commands/trigger.c:288 +#: commands/trigger.c:422 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "\"%s\" - сторонняя таблица" + +#: commands/trigger.c:271 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "У сторонних таблиц не может быть триггеров INSTEAD OF." + +#: commands/trigger.c:278 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "У сторонних таблиц не может быть триггеров TRUNCATE." + +#: commands/trigger.c:290 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "У сторонних таблиц не может быть ограничивающих триггеров." + +#: commands/trigger.c:365 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "триггеры TRUNCATE FOR EACH ROW не поддерживаются" + +#: commands/trigger.c:373 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "триггеры INSTEAD OF должны иметь тип FOR EACH ROW" + +#: commands/trigger.c:377 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "триггеры INSTEAD OF несовместимы с условиями WHEN" + +#: commands/trigger.c:381 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "для триггеров INSTEAD OF нельзя задать список столбцов" + +#: commands/trigger.c:410 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "" +"указание переменной типа кортеж в предложении REFERENCING не поддерживается" + +#: commands/trigger.c:411 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "Используйте OLD TABLE или NEW TABLE для именования переходных таблиц." + +#: commands/trigger.c:424 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Триггеры сторонних таблиц не могут использовать переходные таблицы." + +#: commands/trigger.c:431 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Триггеры представлений не могут использовать переходные таблицы." + +#: commands/trigger.c:451 +#, c-format +msgid "" +"ROW triggers with transition tables are not supported on inheritance children" +msgstr "" +"триггеры ROW с переходными таблицами для потомков в иерархии наследования не " +"поддерживаются" + +#: commands/trigger.c:457 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "имя переходной таблицы можно задать только для триггера AFTER" + +#: commands/trigger.c:462 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "триггеры TRUNCATE с переходными таблицами не поддерживаются" + +#: commands/trigger.c:479 +#, c-format +msgid "" +"transition tables cannot be specified for triggers with more than one event" +msgstr "" +"переходные таблицы нельзя задать для триггеров, назначаемых для нескольких " +"событий" + +#: commands/trigger.c:490 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "переходные таблицы нельзя задать для триггеров со списками столбцов" + +#: commands/trigger.c:507 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "NEW TABLE можно задать только для триггеров INSERT или UPDATE" + +#: commands/trigger.c:512 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE нельзя задать несколько раз" + +#: commands/trigger.c:522 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE можно задать только для триггеров DELETE или UPDATE" + +#: commands/trigger.c:527 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE нельзя задать несколько раз" + +#: commands/trigger.c:537 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "имя OLD TABLE не должно совпадать с именем NEW TABLE" + +#: commands/trigger.c:601 commands/trigger.c:614 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "" +"в условии WHEN для операторного триггера нельзя ссылаться на значения " +"столбцов" + +#: commands/trigger.c:606 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "в условии WHEN для триггера INSERT нельзя ссылаться на значения OLD" + +#: commands/trigger.c:619 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "в условии WHEN для триггера DELETE нельзя ссылаться на значения NEW" + +#: commands/trigger.c:624 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "" +"в условии WHEN для триггера BEFORE нельзя ссылаться на системные столбцы NEW" + +#: commands/trigger.c:632 commands/trigger.c:640 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "" +"в условии WHEN для триггера BEFORE нельзя ссылаться на генерируемые столбцы " +"NEW" + +#: commands/trigger.c:633 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "" +"Используется ссылка на всю строку таблицы, а таблица содержит генерируемые " +"столбцы." + +#: commands/trigger.c:780 commands/trigger.c:1385 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "триггер \"%s\" для отношения \"%s\" уже существует" + +#: commands/trigger.c:1271 commands/trigger.c:1432 commands/trigger.c:1547 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "триггер \"%s\" для таблицы \"%s\" не существует" + +#: commands/trigger.c:1515 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "нет доступа: \"%s\" - это системный триггер" + +#: commands/trigger.c:2095 +#, c-format +msgid "trigger function %u returned null value" +msgstr "триггерная функция %u вернула значение NULL" + +#: commands/trigger.c:2155 commands/trigger.c:2369 commands/trigger.c:2604 +#: commands/trigger.c:2902 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "триггер BEFORE STATEMENT не может возвращать значение" + +#: commands/trigger.c:2229 +#, c-format +msgid "" +"moving row to another partition during a BEFORE FOR EACH ROW trigger is not " +"supported" +msgstr "" +"в триггере BEFORE FOR EACH ROW нельзя перемещать строку в другую секцию" + +#: commands/trigger.c:2230 +#, c-format +msgid "" +"Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." +msgstr "" +"До выполнения триггера \"%s\" строка должна была находиться в секции \"%s.%s" +"\"." + +#: commands/trigger.c:2968 executor/nodeModifyTable.c:1380 +#: executor/nodeModifyTable.c:1449 +#, c-format +msgid "" +"tuple to be updated was already modified by an operation triggered by the " +"current command" +msgstr "" +"кортеж, который должен быть изменён, уже модифицирован в операции, вызванной " +"текущей командой" + +#: commands/trigger.c:2969 executor/nodeModifyTable.c:840 +#: executor/nodeModifyTable.c:914 executor/nodeModifyTable.c:1381 +#: executor/nodeModifyTable.c:1450 +#, c-format +msgid "" +"Consider using an AFTER trigger instead of a BEFORE trigger to propagate " +"changes to other rows." +msgstr "" +"Возможно, для распространения изменений в другие строки следует использовать " +"триггер AFTER вместо BEFORE." + +#: commands/trigger.c:2998 executor/nodeLockRows.c:225 +#: executor/nodeLockRows.c:234 executor/nodeModifyTable.c:220 +#: executor/nodeModifyTable.c:856 executor/nodeModifyTable.c:1397 +#: executor/nodeModifyTable.c:1613 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "не удалось сериализовать доступ из-за параллельного изменения" + +#: commands/trigger.c:3006 executor/nodeModifyTable.c:946 +#: executor/nodeModifyTable.c:1467 executor/nodeModifyTable.c:1637 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "не удалось сериализовать доступ из-за параллельного удаления" + +#: commands/trigger.c:4065 +#, c-format +msgid "cannot fire deferred trigger within security-restricted operation" +msgstr "" +"в рамках операции с ограничениями по безопасности нельзя вызвать отложенный " +"триггер" + +#: commands/trigger.c:5078 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "ограничение \"%s\" не является откладываемым" + +#: commands/trigger.c:5101 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "ограничение \"%s\" не существует" + +#: commands/tsearchcmds.c:118 commands/tsearchcmds.c:683 +#, c-format +msgid "function %s should return type %s" +msgstr "функция %s должна возвращать тип %s" + +#: commands/tsearchcmds.c:195 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "" +"для создания анализаторов текстового поиска нужно быть суперпользователем" + +#: commands/tsearchcmds.c:248 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "параметр анализатора текстового поиска \"%s\" не распознан" + +#: commands/tsearchcmds.c:258 +#, c-format +msgid "text search parser start method is required" +msgstr "для анализатора текстового поиска требуется метод start" + +#: commands/tsearchcmds.c:263 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "для анализатора текстового поиска требуется метод gettoken" + +#: commands/tsearchcmds.c:268 +#, c-format +msgid "text search parser end method is required" +msgstr "для анализатора текстового поиска требуется метод end" + +#: commands/tsearchcmds.c:273 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "для анализатора текстового поиска требуется метод lextypes" + +#: commands/tsearchcmds.c:390 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "шаблон текстового поиска \"%s\" не принимает параметры" + +#: commands/tsearchcmds.c:464 +#, c-format +msgid "text search template is required" +msgstr "требуется шаблон текстового поиска" + +#: commands/tsearchcmds.c:750 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "для создания шаблонов текстового поиска нужно быть суперпользователем" + +#: commands/tsearchcmds.c:792 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "параметр шаблона текстового поиска \"%s\" не распознан" + +#: commands/tsearchcmds.c:802 +#, c-format +msgid "text search template lexize method is required" +msgstr "для шаблона текстового поиска требуется метод lexize" + +#: commands/tsearchcmds.c:1006 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "параметр конфигурации текстового поиска \"%s\" не распознан" + +#: commands/tsearchcmds.c:1013 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "указать и PARSER, и COPY одновременно нельзя" + +#: commands/tsearchcmds.c:1049 +#, c-format +msgid "text search parser is required" +msgstr "требуется анализатор текстового поиска" + +#: commands/tsearchcmds.c:1273 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "тип фрагмента \"%s\" не существует" + +#: commands/tsearchcmds.c:1500 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "сопоставление для типа фрагмента \"%s\" не существует" + +#: commands/tsearchcmds.c:1506 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "сопоставление для типа фрагмента \"%s\" не существует, пропускается" + +#: commands/tsearchcmds.c:1669 commands/tsearchcmds.c:1784 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "неверный формат списка параметров: \"%s\"" + +#: commands/typecmds.c:206 +#, c-format +msgid "must be superuser to create a base type" +msgstr "для создания базового типа нужно быть суперпользователем" + +#: commands/typecmds.c:264 +#, c-format +msgid "" +"Create the type as a shell type, then create its I/O functions, then do a " +"full CREATE TYPE." +msgstr "" +"Создайте тип в виде оболочки, затем определите для него функции ввода-вывода " +"и в завершение выполните полноценную команду CREATE TYPE." + +#: commands/typecmds.c:314 commands/typecmds.c:1394 commands/typecmds.c:3832 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "атрибут типа \"%s\" не распознан" + +#: commands/typecmds.c:370 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "неверная категория типа \"%s\": допустим только ASCII-символ" + +#: commands/typecmds.c:389 +#, c-format +msgid "array element type cannot be %s" +msgstr "типом элемента массива не может быть %s" + +#: commands/typecmds.c:421 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "тип выравнивания \"%s\" не распознан" + +#: commands/typecmds.c:438 commands/typecmds.c:3718 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "неизвестная стратегия хранения \"%s\"" + +#: commands/typecmds.c:449 +#, c-format +msgid "type input function must be specified" +msgstr "необходимо указать функцию ввода типа" + +#: commands/typecmds.c:453 +#, c-format +msgid "type output function must be specified" +msgstr "необходимо указать функцию вывода типа" + +#: commands/typecmds.c:458 +#, c-format +msgid "" +"type modifier output function is useless without a type modifier input " +"function" +msgstr "" +"функция вывода модификатора типа бесполезна без функции ввода модификатора " +"типа" + +#: commands/typecmds.c:745 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "\"%s\" - неподходящий базовый тип для домена" + +#: commands/typecmds.c:837 +#, c-format +msgid "multiple default expressions" +msgstr "неоднократное определение значения типа по умолчанию" + +#: commands/typecmds.c:900 commands/typecmds.c:909 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "конфликтующие ограничения NULL/NOT NULL" + +#: commands/typecmds.c:925 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "" +"ограничения-проверки для доменов не могут иметь характеристики NO INHERIT" + +#: commands/typecmds.c:934 commands/typecmds.c:2536 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "ограничения уникальности невозможны для доменов" + +#: commands/typecmds.c:940 commands/typecmds.c:2542 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "ограничения первичного ключа невозможны для доменов" + +#: commands/typecmds.c:946 commands/typecmds.c:2548 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "ограничения-исключения невозможны для доменов" + +#: commands/typecmds.c:952 commands/typecmds.c:2554 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "ограничения внешних ключей невозможны для доменов" + +#: commands/typecmds.c:961 commands/typecmds.c:2563 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "" +"возможность определения отложенных ограничений для доменов не поддерживается" + +#: commands/typecmds.c:1271 utils/cache/typcache.c:2430 +#, c-format +msgid "%s is not an enum" +msgstr "\"%s\" не является перечислением" + +#: commands/typecmds.c:1402 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "требуется атрибут типа \"subtype\"" + +#: commands/typecmds.c:1407 +#, c-format +msgid "range subtype cannot be %s" +msgstr "%s не может быть подтипом диапазона" + +#: commands/typecmds.c:1426 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "" +"указано правило сортировки для диапазона, но подтип не поддерживает " +"сортировку" + +#: commands/typecmds.c:1436 +#, c-format +msgid "cannot specify a canonical function without a pre-created shell type" +msgstr "" +"функцию получения канонического диапазона нельзя задать без предварительно " +"созданного типа-пустышки" + +#: commands/typecmds.c:1437 +#, c-format +msgid "" +"Create the type as a shell type, then create its canonicalization function, " +"then do a full CREATE TYPE." +msgstr "" +"Создайте тип в виде оболочки, затем определите для него функции приведения к " +"каноническому виду и в завершение выполните полноценную команду CREATE TYPE." + +#: commands/typecmds.c:1648 +#, c-format +msgid "type input function %s has multiple matches" +msgstr "функция ввода типа %s присутствует в нескольких экземплярах" + +#: commands/typecmds.c:1666 +#, c-format +msgid "type input function %s must return type %s" +msgstr "функция ввода типа %s должна возвращать тип %s" + +#: commands/typecmds.c:1682 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "функция ввода типа %s не должна быть изменчивой" + +#: commands/typecmds.c:1710 +#, c-format +msgid "type output function %s must return type %s" +msgstr "функция вывода типа %s должна возвращать тип %s" + +#: commands/typecmds.c:1717 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "функция вывода типа %s не должна быть изменчивой" + +#: commands/typecmds.c:1746 +#, c-format +msgid "type receive function %s has multiple matches" +msgstr "функция получения типа %s присутствует в нескольких экземплярах" + +#: commands/typecmds.c:1764 +#, c-format +msgid "type receive function %s must return type %s" +msgstr "функция получения типа %s должна возвращать тип %s" + +#: commands/typecmds.c:1771 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "функция получения типа %s не должна быть изменчивой" + +#: commands/typecmds.c:1799 +#, c-format +msgid "type send function %s must return type %s" +msgstr "функция отправки типа %s должна возвращать тип %s" + +#: commands/typecmds.c:1806 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "функция отправки типа %s не должна быть изменчивой" + +#: commands/typecmds.c:1833 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr "функция TYPMOD_IN %s должна возвращать тип %s" + +#: commands/typecmds.c:1840 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "функция ввода модификатора типа %s не должна быть изменчивой" + +#: commands/typecmds.c:1867 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "функция TYPMOD_OUT %s должна возвращать тип %s" + +#: commands/typecmds.c:1874 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "функция вывода модификатора типа %s не должна быть изменчивой" + +#: commands/typecmds.c:1901 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "функция анализа типа %s должна возвращать тип %s" + +#: commands/typecmds.c:1947 +#, c-format +msgid "" +"You must specify an operator class for the range type or define a default " +"operator class for the subtype." +msgstr "" +"Вы должны указать класс операторов для типа диапазона или определить класс " +"операторов по умолчанию для этого подтипа." + +#: commands/typecmds.c:1978 +#, c-format +msgid "range canonical function %s must return range type" +msgstr "" +"функция получения канонического диапазона %s должна возвращать диапазон" + +#: commands/typecmds.c:1984 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "" +"функция получения канонического диапазона %s должна быть постоянной " +"(IMMUTABLE)" + +#: commands/typecmds.c:2020 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "функция различий для подтипа диапазона (%s) должна возвращать тип %s" + +#: commands/typecmds.c:2027 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "" +"функция различий для подтипа диапазона (%s) должна быть постоянной " +"(IMMUTABLE)" + +#: commands/typecmds.c:2054 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "значение OID массива в pg_type не задано в режиме двоичного обновления" + +#: commands/typecmds.c:2352 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "столбец \"%s\" таблицы \"%s\" содержит значения NULL" + +#: commands/typecmds.c:2465 commands/typecmds.c:2667 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "ограничение \"%s\" для домена \"%s\" не существует" + +#: commands/typecmds.c:2469 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "ограничение \"%s\" для домена \"%s\" не существует, пропускается" + +#: commands/typecmds.c:2674 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "" +"ограничение \"%s\" для домена \"%s\" не является ограничением-проверкой" + +#: commands/typecmds.c:2780 +#, c-format +msgid "" +"column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "" +"столбец \"%s\" таблицы \"%s\" содержит значения, нарушающие новое ограничение" + +#: commands/typecmds.c:3009 commands/typecmds.c:3207 commands/typecmds.c:3289 +#: commands/typecmds.c:3476 +#, c-format +msgid "%s is not a domain" +msgstr "\"%s\" - это не домен" + +#: commands/typecmds.c:3041 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "ограничение \"%s\" для домена \"%s\" уже существует" + +#: commands/typecmds.c:3092 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "в ограничении-проверке для домена нельзя ссылаться на таблицы" + +#: commands/typecmds.c:3219 commands/typecmds.c:3301 commands/typecmds.c:3593 +#, c-format +msgid "%s is a table's row type" +msgstr "%s - это тип строк таблицы" + +#: commands/typecmds.c:3221 commands/typecmds.c:3303 commands/typecmds.c:3595 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "Изменить его можно с помощью ALTER TABLE." + +#: commands/typecmds.c:3228 commands/typecmds.c:3310 commands/typecmds.c:3508 +#, c-format +msgid "cannot alter array type %s" +msgstr "изменить тип массива \"%s\" нельзя" + +#: commands/typecmds.c:3230 commands/typecmds.c:3312 commands/typecmds.c:3510 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "Однако можно изменить тип %s, что повлечёт изменение типа массива." + +#: commands/typecmds.c:3578 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "тип \"%s\" уже существует в схеме \"%s\"" + +#: commands/typecmds.c:3746 +#, c-format +msgid "cannot change type's storage to PLAIN" +msgstr "сменить вариант хранения типа на PLAIN нельзя" + +#: commands/typecmds.c:3827 +#, c-format +msgid "type attribute \"%s\" cannot be changed" +msgstr "у типа нельзя изменить атрибут \"%s\"" + +#: commands/typecmds.c:3845 +#, c-format +msgid "must be superuser to alter a type" +msgstr "для модификации типа нужно быть суперпользователем" + +#: commands/typecmds.c:3866 commands/typecmds.c:3876 +#, c-format +msgid "%s is not a base type" +msgstr "%s — не базовый тип" + +#: commands/user.c:140 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSID уже не нужно указывать" + +#: commands/user.c:294 +#, c-format +msgid "must be superuser to create superusers" +msgstr "для создания суперпользователей нужно быть суперпользователем" + +#: commands/user.c:301 +#, c-format +msgid "must be superuser to create replication users" +msgstr "для создания пользователей-репликаторов нужно быть суперпользователем" + +#: commands/user.c:308 commands/user.c:736 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "для изменения атрибута bypassrls нужно быть суперпользователем" + +#: commands/user.c:315 +#, c-format +msgid "permission denied to create role" +msgstr "нет прав для создания роли" + +#: commands/user.c:325 commands/user.c:1226 commands/user.c:1233 +#: utils/adt/acl.c:5330 utils/adt/acl.c:5336 gram.y:15147 gram.y:15185 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "имя роли \"%s\" зарезервировано" + +#: commands/user.c:327 commands/user.c:1228 commands/user.c:1235 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "Имена ролей, начинающиеся с \"pg_\", зарезервированы." + +#: commands/user.c:348 commands/user.c:1250 +#, c-format +msgid "role \"%s\" already exists" +msgstr "роль \"%s\" уже существует" + +#: commands/user.c:414 commands/user.c:845 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "пустая строка не является допустимым паролем; пароль сбрасывается" + +#: commands/user.c:443 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "значение OID в pg_authid не задано в режиме двоичного обновления" + +#: commands/user.c:722 commands/user.c:946 commands/user.c:1487 +#: commands/user.c:1629 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "для модификации суперпользователей нужно быть суперпользователем" + +#: commands/user.c:729 +#, c-format +msgid "must be superuser to alter replication users" +msgstr "" +"для модификации пользователей-репликаторов нужно быть суперпользователем" + +#: commands/user.c:752 commands/user.c:953 +#, c-format +msgid "permission denied" +msgstr "нет доступа" + +#: commands/user.c:983 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "для глобального изменения параметров нужно быть суперпользователем" + +#: commands/user.c:1005 +#, c-format +msgid "permission denied to drop role" +msgstr "нет прав для удаления роли" + +#: commands/user.c:1030 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "использовать специальную роль в DROP ROLE нельзя" + +#: commands/user.c:1040 commands/user.c:1197 commands/variable.c:770 +#: commands/variable.c:844 utils/adt/acl.c:5187 utils/adt/acl.c:5234 +#: utils/adt/acl.c:5262 utils/adt/acl.c:5280 utils/init/miscinit.c:675 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "роль \"%s\" не существует" + +#: commands/user.c:1045 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "роль \"%s\" не существует, пропускается" + +#: commands/user.c:1058 commands/user.c:1062 +#, c-format +msgid "current user cannot be dropped" +msgstr "пользователь не может удалить сам себя" + +#: commands/user.c:1066 +#, c-format +msgid "session user cannot be dropped" +msgstr "пользователя текущего сеанса нельзя удалить" + +#: commands/user.c:1076 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "для удаления суперпользователей нужно быть суперпользователем" + +#: commands/user.c:1092 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "роль \"%s\" нельзя удалить, так как есть зависящие от неё объекты" + +#: commands/user.c:1213 +#, c-format +msgid "session user cannot be renamed" +msgstr "пользователя текущего сеанса нельзя переименовать" + +#: commands/user.c:1217 +#, c-format +msgid "current user cannot be renamed" +msgstr "пользователь не может переименовать сам себя" + +#: commands/user.c:1260 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "для переименования суперпользователей нужно быть суперпользователем" + +#: commands/user.c:1267 +#, c-format +msgid "permission denied to rename role" +msgstr "нет прав на переименование роли" + +#: commands/user.c:1288 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "в результате переименования роли очищен MD5-хеш пароля" + +#: commands/user.c:1348 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "в GRANT/REVOKE ROLE нельзя включать названия столбцов" + +#: commands/user.c:1386 +#, c-format +msgid "permission denied to drop objects" +msgstr "нет прав на удаление объектов" + +#: commands/user.c:1413 commands/user.c:1422 +#, c-format +msgid "permission denied to reassign objects" +msgstr "нет прав для переназначения объектов" + +#: commands/user.c:1495 commands/user.c:1637 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "требуется право admin для роли \"%s\"" + +#: commands/user.c:1512 +#, c-format +msgid "must be superuser to set grantor" +msgstr "для назначения права управления правами нужно быть суперпользователем" + +#: commands/user.c:1537 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "роль \"%s\" включена в роль \"%s\"" + +#: commands/user.c:1552 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "роль \"%s\" уже включена в роль \"%s\"" + +#: commands/user.c:1659 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "роль \"%s\" не включена в роль \"%s\"" + +#: commands/vacuum.c:129 +#, c-format +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "нераспознанный параметр ANALYZE: \"%s\"" + +#: commands/vacuum.c:151 +#, c-format +msgid "parallel option requires a value between 0 and %d" +msgstr "для параметра parallel требуется значение от 0 до %d" + +#: commands/vacuum.c:163 +#, c-format +msgid "parallel vacuum degree must be between 0 and %d" +msgstr "степень параллельности для очистки должна задаваться числом от 0 до %d" + +#: commands/vacuum.c:180 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "нераспознанный параметр VACUUM: \"%s\"" + +#: commands/vacuum.c:203 +#, c-format +msgid "VACUUM FULL cannot be performed in parallel" +msgstr "VACUUM FULL нельзя выполнять в параллельном режиме" + +#: commands/vacuum.c:219 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "если задаётся список столбцов, необходимо указать ANALYZE" + +#: commands/vacuum.c:309 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s нельзя выполнить в ходе VACUUM или ANALYZE" + +#: commands/vacuum.c:319 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "Параметр VACUUM DISABLE_PAGE_SKIPPING нельзя использовать с FULL" + +#: commands/vacuum.c:560 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "" +"\"%s\" пропускается --- только суперпользователь может очистить эту таблицу" + +#: commands/vacuum.c:564 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "" +"пропускается \"%s\" --- только суперпользователь или владелец БД может " +"очистить эту таблицу" + +#: commands/vacuum.c:568 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "" +"\"%s\" пропускается --- только владелец базы данных или этой таблицы может " +"очистить её" + +#: commands/vacuum.c:583 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "" +"\"%s\" пропускается --- только суперпользователь может анализировать этот " +"объект" + +#: commands/vacuum.c:587 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "" +"\"%s\" пропускается --- только суперпользователь или владелец БД может " +"анализировать этот объект" + +#: commands/vacuum.c:591 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "" +"\"%s\" пропускается --- только владелец таблицы или БД может анализировать " +"этот объект" + +#: commands/vacuum.c:670 commands/vacuum.c:766 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "очистка \"%s\" пропускается --- блокировка недоступна" + +#: commands/vacuum.c:675 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "очистка \"%s\" пропускается --- это отношение более не существует" + +#: commands/vacuum.c:691 commands/vacuum.c:771 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "анализ \"%s\" пропускается --- блокировка недоступна" + +#: commands/vacuum.c:696 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "анализ \"%s\" пропускается --- это отношение более не существует" + +#: commands/vacuum.c:994 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "самый старый xmin далеко в прошлом" + +#: commands/vacuum.c:995 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." +msgstr "" +"Завершите открытые транзакции как можно быстрее во избежание проблемы " +"зацикливания.\n" +"Возможно, вам также придётся зафиксировать или откатить старые " +"подготовленные транзакции и удалить неиспользуемые слоты репликации." + +#: commands/vacuum.c:1036 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "самый старый multixact далеко в прошлом" + +#: commands/vacuum.c:1037 +#, c-format +msgid "" +"Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "" +"Скорее закройте открытые транзакции в мультитранзакциях, чтобы избежать " +"проблемы зацикливания." + +#: commands/vacuum.c:1623 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "" +"есть базы данных, которые не очищались на протяжении более чем 2 миллиардов " +"транзакций" + +#: commands/vacuum.c:1624 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "" +"Возможно, вы уже потеряли данные в результате зацикливания ID транзакций." + +#: commands/vacuum.c:1784 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "" +"\"%s\" пропускается --- очищать не таблицы или специальные системные таблицы " +"нельзя" + +#: commands/variable.c:165 utils/misc/guc.c:11184 utils/misc/guc.c:11246 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "нераспознанное ключевое слово: \"%s\"." + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "Конфликтующие спецификации стиля дат." + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "В интервале, задающем часовой пояс, нельзя указывать месяцы." + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "В интервале, задающем часовой пояс, нельзя указывать дни." + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "часовой пояс \"%s\" видимо использует координационные секунды" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQL не поддерживает координационные секунды." + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "смещение часового пояса UTC вне диапазона" + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "" +"нельзя установить режим транзакции \"чтение-запись\" внутри транзакции " +"\"только чтение\"" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "" +"режим транзакции \"чтение-запись\" должен быть установлен до выполнения " +"запросов" + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "" +"нельзя установить режим транзакции \"чтение-запись\" в процессе " +"восстановления" + +#: commands/variable.c:534 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "команда SET TRANSACTION ISOLATION LEVEL должна выполняться до запросов" + +#: commands/variable.c:541 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "" +"команда SET TRANSACTION ISOLATION LEVEL не должна вызываться в подтранзакции" + +#: commands/variable.c:548 storage/lmgr/predicate.c:1698 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "использовать сериализуемый режим в горячем резерве нельзя" + +#: commands/variable.c:549 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "Используйте REPEATABLE READ." + +#: commands/variable.c:567 +#, c-format +msgid "" +"SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "" +"команда SET TRANSACTION [NOT] DEFERRABLE не может вызываться в подтранзакции" + +#: commands/variable.c:573 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "" +"команда SET TRANSACTION [NOT] DEFERRABLE должна выполняться до запросов" + +#: commands/variable.c:655 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "Преобразование кодировок %s <-> %s не поддерживается." + +#: commands/variable.c:662 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "Изменить клиентскую кодировку сейчас нельзя." + +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "изменить клиентскую кодировку во время параллельной операции нельзя" + +#: commands/variable.c:863 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "нет прав установить роль \"%s\"" + +#: commands/view.c:84 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "" +"не удалось определить правило сортировки для столбца представления \"%s\"" + +#: commands/view.c:265 commands/view.c:276 +#, c-format +msgid "cannot drop columns from view" +msgstr "удалять столбцы из представления нельзя" + +#: commands/view.c:281 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "изменить имя столбца \"%s\" на \"%s\" в представлении нельзя" + +# skip-rule: space-before-ellipsis +#: commands/view.c:284 +#, c-format +msgid "" +"Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead." +msgstr "" +"Чтобы изменить имя столбца представления, выполните ALTER VIEW ... RENAME " +"COLUMN ..." + +#: commands/view.c:290 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "изменить тип столбца представления \"%s\" с %s на %s нельзя" + +#: commands/view.c:441 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "представления не должны содержать SELECT INTO" + +#: commands/view.c:453 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "представления не должны содержать операторы, изменяющие данные в WITH" + +#: commands/view.c:523 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "в CREATE VIEW указано больше имён столбцов, чем самих столбцов" + +#: commands/view.c:531 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "" +"представления не могут быть нежурналируемыми, так как они нигде не хранятся" + +#: commands/view.c:545 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "представление \"%s\" будет создано как временное" + +#: executor/execCurrent.c:79 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "курсор \"%s\" не относится к запросу SELECT" + +#: executor/execCurrent.c:85 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "курсор \"%s\" сохранился с предыдущей транзакции" + +#: executor/execCurrent.c:118 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "в курсоре \"%s\" несколько ссылок FOR UPDATE/SHARE на таблицу \"%s\"" + +#: executor/execCurrent.c:127 +#, c-format +msgid "" +"cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "в курсоре \"%s\" нет ссылки FOR UPDATE/SHARE на таблицу \"%s\"" + +#: executor/execCurrent.c:137 executor/execCurrent.c:182 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr "курсор \"%s\" не указывает на строку" + +#: executor/execCurrent.c:169 executor/execCurrent.c:228 +#: executor/execCurrent.c:239 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "" +"для курсора \"%s\" не выполняется обновляемое сканирование таблицы \"%s\"" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2404 +#, c-format +msgid "" +"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "" +"тип параметра %d (%s) не соответствует тому, с которым подготавливался план " +"(%s)" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2416 +#, c-format +msgid "no value found for parameter %d" +msgstr "не найдено значение параметра %d" + +#: executor/execExpr.c:859 parser/parse_agg.c:816 +#, c-format +msgid "window function calls cannot be nested" +msgstr "вложенные вызовы оконных функций недопустимы" + +#: executor/execExpr.c:1318 +#, c-format +msgid "target type is not an array" +msgstr "целевой тип не является массивом" + +#: executor/execExpr.c:1651 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "столбец ROW() имеет тип %s, а должен - %s" + +#: executor/execExpr.c:2176 executor/execSRF.c:708 parser/parse_func.c:135 +#: parser/parse_func.c:646 parser/parse_func.c:1020 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "функции нельзя передать больше %d аргумента" +msgstr[1] "функции нельзя передать больше %d аргументов" +msgstr[2] "функции нельзя передать больше %d аргументов" + +#: executor/execExpr.c:2587 executor/execExpr.c:2593 +#: executor/execExprInterp.c:2730 utils/adt/arrayfuncs.c:262 +#: utils/adt/arrayfuncs.c:560 utils/adt/arrayfuncs.c:1302 +#: utils/adt/arrayfuncs.c:3348 utils/adt/arrayfuncs.c:5308 +#: utils/adt/arrayfuncs.c:5821 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "число размерностей массива (%d) превышает предел (%d)" + +#: executor/execExprInterp.c:1894 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "атрибут %d типа %s был удалён" + +#: executor/execExprInterp.c:1900 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "атрибут %d типа %s имеет неправильный тип" + +#: executor/execExprInterp.c:1902 executor/execExprInterp.c:3002 +#: executor/execExprInterp.c:3049 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "В таблице задан тип %s, а в запросе ожидается %s." + +#: executor/execExprInterp.c:2494 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF для таблиц такого типа не поддерживается" + +#: executor/execExprInterp.c:2708 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "не удалось объединить несовместимые массивы" + +#: executor/execExprInterp.c:2709 +#, c-format +msgid "" +"Array with element type %s cannot be included in ARRAY construct with " +"element type %s." +msgstr "" +"Массив с типом элементов %s нельзя включить в конструкцию ARRAY с типом " +"элементов %s." + +#: executor/execExprInterp.c:2750 executor/execExprInterp.c:2780 +#, c-format +msgid "" +"multidimensional arrays must have array expressions with matching dimensions" +msgstr "" +"для многомерных массивов должны задаваться выражения с соответствующими " +"размерностями" + +#: executor/execExprInterp.c:3001 executor/execExprInterp.c:3048 +#, c-format +msgid "attribute %d has wrong type" +msgstr "атрибут %d имеет неверный тип" + +#: executor/execExprInterp.c:3158 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "индекс элемента массива в присваивании не может быть NULL" + +#: executor/execExprInterp.c:3588 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "домен %s не допускает значения null" + +#: executor/execExprInterp.c:3603 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "значение домена %s нарушает ограничение-проверку \"%s\"" + +#: executor/execExprInterp.c:3973 executor/execExprInterp.c:3990 +#: executor/execExprInterp.c:4091 executor/nodeModifyTable.c:109 +#: executor/nodeModifyTable.c:120 executor/nodeModifyTable.c:137 +#: executor/nodeModifyTable.c:145 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "тип строки таблицы отличается от типа строки-результата запроса" + +#: executor/execExprInterp.c:3974 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "Строка таблицы содержит %d атрибут, а в запросе ожидается %d." +msgstr[1] "Строка таблицы содержит %d атрибута, а в запросе ожидается %d." +msgstr[2] "Строка таблицы содержит %d атрибутов, а в запросе ожидается %d." + +#: executor/execExprInterp.c:3991 executor/nodeModifyTable.c:121 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "" +"В таблице определён тип %s (номер столбца: %d), а в запросе предполагается " +"%s." + +#: executor/execExprInterp.c:4092 executor/execSRF.c:967 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "" +"Несоответствие параметров физического хранения удалённого атрибута (под " +"номером %d)." + +#: executor/execIndexing.c:550 +#, c-format +msgid "" +"ON CONFLICT does not support deferrable unique constraints/exclusion " +"constraints as arbiters" +msgstr "" +"ON CONFLICT не поддерживает откладываемые ограничения уникальности/" +"ограничения-исключения в качестве определяющего индекса" + +#: executor/execIndexing.c:821 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "не удалось создать ограничение-исключение \"%s\"" + +#: executor/execIndexing.c:824 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "Ключ %s конфликтует с ключом %s." + +#: executor/execIndexing.c:826 +#, c-format +msgid "Key conflicts exist." +msgstr "Обнаружен конфликт ключей." + +#: executor/execIndexing.c:832 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "конфликтующее значение ключа нарушает ограничение-исключение \"%s\"" + +#: executor/execIndexing.c:835 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "Ключ %s конфликтует с существующим ключом %s." + +#: executor/execIndexing.c:837 +#, c-format +msgid "Key conflicts with existing key." +msgstr "Ключ конфликтует с уже существующим." + +#: executor/execMain.c:1091 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "последовательность \"%s\" изменить нельзя" + +#: executor/execMain.c:1097 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "TOAST-отношение \"%s\" изменить нельзя" + +#: executor/execMain.c:1115 rewrite/rewriteHandler.c:2972 +#: rewrite/rewriteHandler.c:3749 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "вставить данные в представление \"%s\" нельзя" + +#: executor/execMain.c:1117 rewrite/rewriteHandler.c:2975 +#: rewrite/rewriteHandler.c:3752 +#, c-format +msgid "" +"To enable inserting into the view, provide an INSTEAD OF INSERT trigger or " +"an unconditional ON INSERT DO INSTEAD rule." +msgstr "" +"Чтобы представление допускало добавление данных, установите триггер INSTEAD " +"OF INSERT или безусловное правило ON INSERT DO INSTEAD." + +#: executor/execMain.c:1123 rewrite/rewriteHandler.c:2980 +#: rewrite/rewriteHandler.c:3757 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "изменить данные в представлении \"%s\" нельзя" + +#: executor/execMain.c:1125 rewrite/rewriteHandler.c:2983 +#: rewrite/rewriteHandler.c:3760 +#, c-format +msgid "" +"To enable updating the view, provide an INSTEAD OF UPDATE trigger or an " +"unconditional ON UPDATE DO INSTEAD rule." +msgstr "" +"Чтобы представление допускало изменение данных, установите триггер INSTEAD " +"OF UPDATE или безусловное правило ON UPDATE DO INSTEAD." + +#: executor/execMain.c:1131 rewrite/rewriteHandler.c:2988 +#: rewrite/rewriteHandler.c:3765 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "удалить данные из представления \"%s\" нельзя" + +#: executor/execMain.c:1133 rewrite/rewriteHandler.c:2991 +#: rewrite/rewriteHandler.c:3768 +#, c-format +msgid "" +"To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an " +"unconditional ON DELETE DO INSTEAD rule." +msgstr "" +"Чтобы представление допускало удаление данных, установите триггер INSTEAD OF " +"DELETE или безусловное правило ON DELETE DO INSTEAD." + +#: executor/execMain.c:1144 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "изменить материализованное представление \"%s\" нельзя" + +#: executor/execMain.c:1156 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "вставлять данные в стороннюю таблицу \"%s\" нельзя" + +#: executor/execMain.c:1162 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "сторонняя таблица \"%s\" не допускает добавления" + +#: executor/execMain.c:1169 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "изменять данные в сторонней таблице \"%s\"" + +#: executor/execMain.c:1175 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "сторонняя таблица \"%s\" не допускает изменения" + +#: executor/execMain.c:1182 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "удалять данные из сторонней таблицы \"%s\" нельзя" + +#: executor/execMain.c:1188 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "сторонняя таблица \"%s\" не допускает удаления" + +#: executor/execMain.c:1199 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "отношение \"%s\" изменить нельзя" + +#: executor/execMain.c:1226 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "блокировать строки в последовательности \"%s\" нельзя" + +#: executor/execMain.c:1233 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "блокировать строки в TOAST-отношении \"%s\" нельзя" + +#: executor/execMain.c:1240 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "блокировать строки в представлении \"%s\" нельзя" + +#: executor/execMain.c:1248 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "блокировать строки в материализованном представлении \"%s\" нельзя" + +#: executor/execMain.c:1257 executor/execMain.c:2627 +#: executor/nodeLockRows.c:132 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "блокировать строки в сторонней таблице \"%s\" нельзя" + +#: executor/execMain.c:1263 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "блокировать строки в отношении \"%s\" нельзя" + +#: executor/execMain.c:1879 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "новая строка в отношении \"%s\" нарушает ограничение секции" + +#: executor/execMain.c:1881 executor/execMain.c:1964 executor/execMain.c:2012 +#: executor/execMain.c:2120 +#, c-format +msgid "Failing row contains %s." +msgstr "Ошибочная строка содержит %s." + +#: executor/execMain.c:1961 +#, c-format +msgid "" +"null value in column \"%s\" of relation \"%s\" violates not-null constraint" +msgstr "" +"значение NULL в столбце \"%s\" отношения \"%s\" нарушает ограничение NOT NULL" + +#: executor/execMain.c:2010 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "новая строка в отношении \"%s\" нарушает ограничение-проверку \"%s\"" + +#: executor/execMain.c:2118 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "новая строка нарушает ограничение-проверку для представления \"%s\"" + +#: executor/execMain.c:2128 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "" +"новая строка нарушает политику защиты на уровне строк \"%s\" для таблицы \"%s" +"\"" + +#: executor/execMain.c:2133 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "" +"новая строка нарушает политику защиты на уровне строк для таблицы \"%s\"" + +#: executor/execMain.c:2140 +#, c-format +msgid "" +"new row violates row-level security policy \"%s\" (USING expression) for " +"table \"%s\"" +msgstr "" +"новая строка нарушает политику защиты на уровне строк \"%s\" (выражение " +"USING) для таблицы \"%s\"" + +#: executor/execMain.c:2145 +#, c-format +msgid "" +"new row violates row-level security policy (USING expression) for table \"%s" +"\"" +msgstr "" +"новая строка нарушает политику защиты на уровне строк (выражение USING) для " +"таблицы \"%s\"" + +#: executor/execPartition.c:341 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "для строки не найдена секция в отношении \"%s\"" + +#: executor/execPartition.c:344 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "Ключ секционирования для неподходящей строки содержит %s." + +#: executor/execReplication.c:196 executor/execReplication.c:373 +#, c-format +msgid "" +"tuple to be locked was already moved to another partition due to concurrent " +"update, retrying" +msgstr "" +"кортеж, подлежащий блокировке, был перемещён в другую секцию в результате " +"параллельного изменения; следует повторная попытка" + +#: executor/execReplication.c:200 executor/execReplication.c:377 +#, c-format +msgid "concurrent update, retrying" +msgstr "параллельное изменение; следует повторная попытка" + +#: executor/execReplication.c:206 executor/execReplication.c:383 +#, c-format +msgid "concurrent delete, retrying" +msgstr "параллельное удаление; следует повторная попытка" + +#: executor/execReplication.c:269 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3626 utils/adt/arrayfuncs.c:4146 +#: utils/adt/arrayfuncs.c:6132 utils/adt/rowtypes.c:1182 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "не удалось найти оператор равенства для типа %s" + +#: executor/execReplication.c:586 +#, c-format +msgid "" +"cannot update table \"%s\" because it does not have a replica identity and " +"publishes updates" +msgstr "" +"изменение в таблице \"%s\" невозможно, так как в ней отсутствует " +"идентификатор реплики, но она публикует изменения" + +#: executor/execReplication.c:588 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "" +"Чтобы эта таблица поддерживала изменение, установите REPLICA IDENTITY, " +"выполнив ALTER TABLE." + +#: executor/execReplication.c:592 +#, c-format +msgid "" +"cannot delete from table \"%s\" because it does not have a replica identity " +"and publishes deletes" +msgstr "" +"удаление из таблицы \"%s\" невозможно, так как в ней отсутствует " +"идентификатор реплики, но она публикует удаления" + +#: executor/execReplication.c:594 +#, c-format +msgid "" +"To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "" +"Чтобы эта таблица поддерживала удаление, установите REPLICA IDENTITY, " +"выполнив ALTER TABLE." + +#: executor/execReplication.c:613 executor/execReplication.c:621 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "" +"в качестве целевого отношения для логической репликации нельзя использовать " +"\"%s.%s\"" + +#: executor/execReplication.c:615 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "\"%s.%s\" — сторонняя таблица." + +#: executor/execReplication.c:623 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "\"%s.%s\" — не таблица." + +#: executor/execSRF.c:315 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "строки, возвращённые функцией, имеют разные типы" + +#: executor/execSRF.c:363 executor/execSRF.c:657 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "нарушение протокола табличной функции в режиме материализации" + +#: executor/execSRF.c:370 executor/execSRF.c:675 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "нераспознанный режим возврата табличной функции: %d" + +#: executor/execSRF.c:884 +#, c-format +msgid "" +"function returning setof record called in context that cannot accept type " +"record" +msgstr "" +"функция, возвращающая запись SET OF, вызвана в контексте, не допускающем " +"этот тип" + +#: executor/execSRF.c:940 executor/execSRF.c:956 executor/execSRF.c:966 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "тип результат функции отличается от типа строки-результата запроса" + +#: executor/execSRF.c:941 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "Возвращённая строка содержит %d атрибут, но запрос предполагает %d." +msgstr[1] "" +"Возвращённая строка содержит %d атрибутов, но запрос предполагает %d." +msgstr[2] "" +"Возвращённая строка содержит %d атрибутов, но запрос предполагает %d." + +#: executor/execSRF.c:957 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "Возвращён тип %s (номер столбца: %d), а в запросе предполагается %s." + +#: executor/execUtils.c:750 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "материализованное представление \"%s\" не было наполнено" + +#: executor/execUtils.c:752 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "Примените команду REFRESH MATERIALIZED VIEW." + +#: executor/functions.c:231 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "не удалось определить фактический тип аргумента, объявленного как %s" + +#: executor/functions.c:528 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "в функции SQL нельзя выполнить COPY с участием клиента" + +#. translator: %s is a SQL statement name +#: executor/functions.c:534 +#, c-format +msgid "%s is not allowed in a SQL function" +msgstr "%s нельзя использовать в SQL-функции" + +#. translator: %s is a SQL statement name +#: executor/functions.c:542 executor/spi.c:1471 executor/spi.c:2257 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "%s нельзя использовать в не изменчивой (volatile) функции" + +#: executor/functions.c:1424 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "SQL-функция \"%s\", оператор %d" + +#: executor/functions.c:1450 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "SQL-функция \"%s\" (при старте)" + +#: executor/functions.c:1553 +#, c-format +msgid "" +"calling procedures with output arguments is not supported in SQL functions" +msgstr "" +"вызов процедур с выходными аргументами в функциях SQL не поддерживается" + +#: executor/functions.c:1687 executor/functions.c:1724 +#: executor/functions.c:1738 executor/functions.c:1828 +#: executor/functions.c:1861 executor/functions.c:1875 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "несовпадение типа возврата в функции (в объявлении указан тип %s)" + +#: executor/functions.c:1689 +#, c-format +msgid "" +"Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "" +"Последним оператором в функции должен быть SELECT или INSERT/UPDATE/DELETE " +"RETURNING." + +#: executor/functions.c:1726 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "Последний оператор должен возвращать один столбец." + +#: executor/functions.c:1740 +#, c-format +msgid "Actual return type is %s." +msgstr "Фактический тип возврата: %s." + +#: executor/functions.c:1830 +#, c-format +msgid "Final statement returns too many columns." +msgstr "Последний оператор возвращает слишком много столбцов." + +#: executor/functions.c:1863 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "Последний оператор возвращает %s вместо %s для столбца %d." + +#: executor/functions.c:1877 +#, c-format +msgid "Final statement returns too few columns." +msgstr "Последний оператор возвращает слишком мало столбцов." + +#: executor/functions.c:1905 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "для SQL-функций тип возврата %s не поддерживается" + +#: executor/nodeAgg.c:3091 executor/nodeAgg.c:3100 executor/nodeAgg.c:3112 +#, c-format +msgid "unexpected EOF for tape %d: requested %zu bytes, read %zu bytes" +msgstr "" +"неожиданный конец файла для ленты %d: запрашивалось байт: %zu, прочитано: %zu" + +#: executor/nodeAgg.c:4046 parser/parse_agg.c:655 parser/parse_agg.c:685 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "вложенные вызовы агрегатных функций недопустимы" + +#: executor/nodeAgg.c:4254 executor/nodeWindowAgg.c:2836 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "" +"агрегатная функция %u должна иметь совместимые входной и переходный типы" + +#: executor/nodeCustom.c:145 executor/nodeCustom.c:156 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "нестандартное сканирование \"%s\" не поддерживает MarkPos" + +#: executor/nodeHashjoin.c:1046 executor/nodeHashjoin.c:1076 +#, c-format +msgid "could not rewind hash-join temporary file" +msgstr "не удалось переместиться во временном файле хеш-соединения" + +#: executor/nodeHashjoin.c:1272 executor/nodeHashjoin.c:1283 +#, c-format +msgid "" +"could not read from hash-join temporary file: read only %zu of %zu bytes" +msgstr "" +"не удалось прочитать временный файл хеш-соединения (прочитано байт: %zu из " +"%zu)" + +#: executor/nodeIndexonlyscan.c:242 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "" +"функции неточной дистанции не поддерживаются в сканировании только по индексу" + +#: executor/nodeLimit.c:374 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET не может быть отрицательным" + +#: executor/nodeLimit.c:400 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT не может быть отрицательным" + +#: executor/nodeMergejoin.c:1570 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "" +"RIGHT JOIN поддерживается только с условиями, допускающими соединение " +"слиянием" + +#: executor/nodeMergejoin.c:1588 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "" +"FULL JOIN поддерживается только с условиями, допускающими соединение слиянием" + +#: executor/nodeModifyTable.c:110 +#, c-format +msgid "Query has too many columns." +msgstr "Запрос возвращает больше столбцов." + +#: executor/nodeModifyTable.c:138 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "" +"Запрос выдаёт значение для удалённого столбца (с порядковым номером %d)." + +#: executor/nodeModifyTable.c:146 +#, c-format +msgid "Query has too few columns." +msgstr "Запрос возвращает меньше столбцов." + +#: executor/nodeModifyTable.c:839 executor/nodeModifyTable.c:913 +#, c-format +msgid "" +"tuple to be deleted was already modified by an operation triggered by the " +"current command" +msgstr "" +"кортеж, который должен быть удалён, уже модифицирован в операции, вызванной " +"текущей командой" + +#: executor/nodeModifyTable.c:1220 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "неверное указание ON UPDATE" + +#: executor/nodeModifyTable.c:1221 +#, c-format +msgid "" +"The result tuple would appear in a different partition than the original " +"tuple." +msgstr "" +"Результирующий кортеж окажется перемещённым из секции исходного кортежа в " +"другую." + +#: executor/nodeModifyTable.c:1592 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "команда ON CONFLICT DO UPDATE не может менять строку повторно" + +#: executor/nodeModifyTable.c:1593 +#, c-format +msgid "" +"Ensure that no rows proposed for insertion within the same command have " +"duplicate constrained values." +msgstr "" +"Проверьте, не содержат ли строки, которые должна добавить команда, " +"дублирующиеся значения, подпадающие под ограничения." + +#: executor/nodeSamplescan.c:259 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "параметр TABLESAMPLE не может быть NULL" + +#: executor/nodeSamplescan.c:271 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "параметр TABLESAMPLE REPEATABLE не может быть NULL" + +#: executor/nodeSubplan.c:346 executor/nodeSubplan.c:385 +#: executor/nodeSubplan.c:1159 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "подзапрос в выражении вернул больше одной строки" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "URI пространства имён должен быть не NULL" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "выражение отбора строк должно быть не NULL" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "выражение отбора столбца должно быть не NULL" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "Для столбца \"%s\" задано выражение NULL." + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "в столбце \"%s\" не допускается NULL" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "функция перехода движимого агрегата не должна возвращать NULL" + +#: executor/nodeWindowAgg.c:2058 +#, c-format +msgid "frame starting offset must not be null" +msgstr "смещение начала рамки не может быть NULL" + +#: executor/nodeWindowAgg.c:2071 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "смещение начала рамки не может быть отрицательным" + +#: executor/nodeWindowAgg.c:2083 +#, c-format +msgid "frame ending offset must not be null" +msgstr "смещение конца рамки не может быть NULL" + +#: executor/nodeWindowAgg.c:2096 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "смещение конца рамки не может быть отрицательным" + +#: executor/nodeWindowAgg.c:2752 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "" +"агрегатная функция %s не поддерживает использование в качестве оконной " +"функции" + +#: executor/spi.c:228 executor/spi.c:297 +#, c-format +msgid "invalid transaction termination" +msgstr "неверное завершение транзакции" + +#: executor/spi.c:242 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "фиксировать транзакцию при наличии активных подтранзакций нельзя" + +#: executor/spi.c:303 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "откатить транзакцию при наличии активных подтранзакций нельзя" + +#: executor/spi.c:372 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "после транзакции остался непустой стек SPI" + +#: executor/spi.c:373 executor/spi.c:435 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "Проверьте наличие вызова \"SPI_finish\"." + +#: executor/spi.c:434 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "после подтранзакции остался непустой стек SPI" + +#: executor/spi.c:1335 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "не удалось открыть план нескольких запросов как курсор" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1340 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "не удалось открыть запрос %s как курсор" + +#: executor/spi.c:1445 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE не поддерживается" + +#: executor/spi.c:1446 parser/analyze.c:2475 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "Прокручиваемые курсоры должны быть READ ONLY." + +#: executor/spi.c:2560 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "SQL-оператор: \"%s\"" + +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "не удалось передать кортеж в очередь в разделяемой памяти" + +#: foreign/foreign.c:220 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "сопоставление пользователя для \"%s\" не найдено" + +#: foreign/foreign.c:672 +#, c-format +msgid "invalid option \"%s\"" +msgstr "неверный параметр \"%s\"" + +#: foreign/foreign.c:673 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "В данном контексте допустимы параметры: %s" + +#: jit/jit.c:205 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:417 +#: utils/fmgr/dfmgr.c:465 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "нет доступа к файлу \"%s\": %m" + +#: jit/llvm/llvmjit.c:730 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "время внедрения: %.3fs, оптимизации: %.3fs, выдачи: %.3fs" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Ошибка при запросе памяти DSA (%zu Б)." + +#: libpq/auth-scram.c:248 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "клиент выбрал неверный механизм аутентификации SASL" + +#: libpq/auth-scram.c:269 libpq/auth-scram.c:509 libpq/auth-scram.c:520 +#, c-format +msgid "invalid SCRAM secret for user \"%s\"" +msgstr "неверная запись секрета SCRAM для пользователя \"%s\"" + +#: libpq/auth-scram.c:280 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM secret." +msgstr "Для пользователя \"%s\" нет подходящей записи секрета SCRAM." + +#: libpq/auth-scram.c:358 libpq/auth-scram.c:363 libpq/auth-scram.c:693 +#: libpq/auth-scram.c:701 libpq/auth-scram.c:806 libpq/auth-scram.c:819 +#: libpq/auth-scram.c:829 libpq/auth-scram.c:937 libpq/auth-scram.c:944 +#: libpq/auth-scram.c:959 libpq/auth-scram.c:974 libpq/auth-scram.c:988 +#: libpq/auth-scram.c:1006 libpq/auth-scram.c:1021 libpq/auth-scram.c:1321 +#: libpq/auth-scram.c:1329 +#, c-format +msgid "malformed SCRAM message" +msgstr "неправильное сообщение SCRAM" + +#: libpq/auth-scram.c:359 +#, c-format +msgid "The message is empty." +msgstr "Сообщение пустое." + +#: libpq/auth-scram.c:364 +#, c-format +msgid "Message length does not match input length." +msgstr "Длина сообщения не соответствует входной длине." + +#: libpq/auth-scram.c:396 +#, c-format +msgid "invalid SCRAM response" +msgstr "неверный ответ SCRAM" + +#: libpq/auth-scram.c:397 +#, c-format +msgid "Nonce does not match." +msgstr "Разовый код не совпадает." + +#: libpq/auth-scram.c:471 +#, c-format +msgid "could not generate random salt" +msgstr "не удалось сгенерировать случайную соль" + +#: libpq/auth-scram.c:694 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Ожидался атрибут \"%c\", но обнаружено \"%s\"." + +#: libpq/auth-scram.c:702 libpq/auth-scram.c:830 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Ожидался символ \"=\" для атрибута \"%c\"." + +#: libpq/auth-scram.c:807 +#, c-format +msgid "Attribute expected, but found end of string." +msgstr "Ожидался атрибут, но обнаружен конец строки." + +#: libpq/auth-scram.c:820 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Ожидался атрибут, но обнаружен неправильный символ \"%s\"." + +#: libpq/auth-scram.c:938 libpq/auth-scram.c:960 +#, c-format +msgid "" +"The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not " +"include channel binding data." +msgstr "" +"Клиент выбрал алгоритм SCRAM-SHA-256-PLUS, но в сообщении SCRAM отсутствуют " +"данные связывания каналов." + +#: libpq/auth-scram.c:945 libpq/auth-scram.c:975 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Ожидалась запятая, но обнаружен символ \"%s\"." + +#: libpq/auth-scram.c:966 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "Ошибка согласования связывания каналов SCRAM" + +#: libpq/auth-scram.c:967 +#, c-format +msgid "" +"The client supports SCRAM channel binding but thinks the server does not. " +"However, this server does support channel binding." +msgstr "" +"Клиент поддерживает связывание каналов SCRAM, но полагает, что оно не " +"поддерживается сервером. Однако сервер тоже поддерживает связывание каналов." + +#: libpq/auth-scram.c:989 +#, c-format +msgid "" +"The client selected SCRAM-SHA-256 without channel binding, but the SCRAM " +"message includes channel binding data." +msgstr "" +"Клиент выбрал алгоритм SCRAM-SHA-256 без связывания каналов, но сообщение " +"SCRAM содержит данные связывания каналов." + +#: libpq/auth-scram.c:1000 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "неподдерживаемый тип связывания каналов SCRAM \"%s\"" + +#: libpq/auth-scram.c:1007 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Неожиданный флаг связывания каналов \"%s\"." + +#: libpq/auth-scram.c:1017 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "клиент передал идентификатор для авторизации, но это не поддерживается" + +#: libpq/auth-scram.c:1022 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Неожиданный атрибут \"%s\" в первом сообщении клиента." + +#: libpq/auth-scram.c:1038 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "клиенту требуется неподдерживаемое расширение SCRAM" + +#: libpq/auth-scram.c:1052 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "непечатаемые символы в разовом коде SCRAM" + +#: libpq/auth-scram.c:1169 +#, c-format +msgid "could not generate random nonce" +msgstr "не удалось сгенерировать разовый код" + +#: libpq/auth-scram.c:1179 +#, c-format +msgid "could not encode random nonce" +msgstr "не удалось оформить разовый код" + +#: libpq/auth-scram.c:1285 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "ошибка проверки связывания каналов SCRAM" + +#: libpq/auth-scram.c:1303 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "" +"неожиданный атрибут связывания каналов в последнем сообщении клиента SCRAM" + +#: libpq/auth-scram.c:1322 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "Некорректное подтверждение в последнем сообщении клиента." + +#: libpq/auth-scram.c:1330 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Мусор в конце последнего сообщения клиента." + +#: libpq/auth.c:280 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "" +"пользователь \"%s\" не прошёл проверку подлинности: не разрешённый компьютер" + +#: libpq/auth.c:283 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (\"trust\")" + +#: libpq/auth.c:286 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (Ident)" + +#: libpq/auth.c:289 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (Peer)" + +#: libpq/auth.c:294 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (по паролю)" + +#: libpq/auth.c:299 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (GSSAPI)" + +#: libpq/auth.c:302 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (SSPI)" + +#: libpq/auth.c:305 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (PAM)" + +#: libpq/auth.c:308 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (BSD)" + +#: libpq/auth.c:311 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (LDAP)" + +#: libpq/auth.c:314 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (по сертификату)" + +#: libpq/auth.c:317 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "пользователь \"%s\" не прошёл проверку подлинности (RADIUS)" + +#: libpq/auth.c:320 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "" +"пользователь \"%s\" не прошёл проверку подлинности: неверный метод проверки" + +#: libpq/auth.c:324 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "Подключение соответствует строке %d в pg_hba.conf: \"%s\"" + +#: libpq/auth.c:371 +#, c-format +msgid "" +"client certificates can only be checked if a root certificate store is " +"available" +msgstr "" +"сертификаты клиентов могут проверяться, только если доступно хранилище " +"корневых сертификатов" + +#: libpq/auth.c:382 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "для подключения требуется годный сертификат клиента" + +#: libpq/auth.c:413 libpq/auth.c:459 +msgid "GSS encryption" +msgstr "Шифрование GSS" + +#: libpq/auth.c:416 libpq/auth.c:462 +msgid "SSL on" +msgstr "SSL вкл." + +#: libpq/auth.c:418 libpq/auth.c:464 +msgid "SSL off" +msgstr "SSL выкл." + +#. translator: last %s describes encryption state +#: libpq/auth.c:424 +#, c-format +msgid "" +"pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "" +"pg_hba.conf отвергает подключение для репликации: компьютер \"%s\", " +"пользователь \"%s\", \"%s\"" + +#. translator: last %s describes encryption state +#: libpq/auth.c:431 +#, c-format +msgid "" +"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s" +"\", %s" +msgstr "" +"pg_hba.conf отвергает подключение: компьютер \"%s\", пользователь \"%s\", " +"база данных \"%s\", %s" + +#: libpq/auth.c:469 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "" +"IP-адрес клиента разрешается в \"%s\", соответствует прямому преобразованию." + +#: libpq/auth.c:472 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "" +"IP-адрес клиента разрешается в \"%s\", прямое преобразование не проверялось." + +#: libpq/auth.c:475 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "" +"IP-адрес клиента разрешается в \"%s\", это не соответствует прямому " +"преобразованию." + +#: libpq/auth.c:478 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "" +"Преобразовать имя клиентского компьютера \"%s\" в IP-адрес не удалось: %s." + +#: libpq/auth.c:483 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "Получить имя компьютера из IP-адреса клиента не удалось: %s." + +#. translator: last %s describes encryption state +#: libpq/auth.c:491 +#, c-format +msgid "" +"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s" +"\", %s" +msgstr "" +"в pg_hba.conf нет записи, разрешающей подключение для репликации с " +"компьютера \"%s\" для пользователя \"%s\", %s" + +#. translator: last %s describes encryption state +#: libpq/auth.c:499 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "" +"в pg_hba.conf нет записи для компьютера \"%s\", пользователя \"%s\", базы " +"\"%s\", %s" + +#: libpq/auth.c:675 +#, c-format +msgid "expected password response, got message type %d" +msgstr "ожидался ответ с паролем, но получено сообщение %d" + +#: libpq/auth.c:703 +#, c-format +msgid "invalid password packet size" +msgstr "неверный размер пакета с паролем" + +#: libpq/auth.c:721 +#, c-format +msgid "empty password returned by client" +msgstr "клиент возвратил пустой пароль" + +#: libpq/auth.c:841 libpq/hba.c:1345 +#, c-format +msgid "" +"MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "" +"проверка подлинности MD5 не поддерживается, когда включён режим " +"\"db_user_namespace\"" + +#: libpq/auth.c:847 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "не удалось сгенерировать случайную соль для MD5" + +#: libpq/auth.c:893 +#, c-format +msgid "SASL authentication is not supported in protocol version 2" +msgstr "аутентификация SASL не поддерживается в протоколе версии 2" + +#: libpq/auth.c:926 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "ожидался ответ SASL, но получено сообщение %d" + +#: libpq/auth.c:1055 +#, c-format +msgid "GSSAPI is not supported in protocol version 2" +msgstr "GSSAPI не поддерживается в протоколе версии 2" + +#: libpq/auth.c:1068 libpq/be-secure-gssapi.c:535 +#, c-format +msgid "could not set environment: %m" +msgstr "не удалось задать переменную окружения: %m" + +#: libpq/auth.c:1104 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "ожидался ответ GSS, но получено сообщение %d" + +#: libpq/auth.c:1164 +msgid "accepting GSS security context failed" +msgstr "принять контекст безопасности GSS не удалось" + +#: libpq/auth.c:1204 +msgid "retrieving GSS user name failed" +msgstr "получить имя пользователя GSS не удалось" + +#: libpq/auth.c:1337 +#, c-format +msgid "SSPI is not supported in protocol version 2" +msgstr "SSPI не поддерживается в протоколе версии 2" + +#: libpq/auth.c:1352 +msgid "could not acquire SSPI credentials" +msgstr "не удалось получить удостоверение SSPI" + +#: libpq/auth.c:1377 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "ожидался ответ SSPI, но получено сообщение %d" + +#: libpq/auth.c:1455 +msgid "could not accept SSPI security context" +msgstr "принять контекст безопасности SSPI не удалось" + +#: libpq/auth.c:1517 +msgid "could not get token from SSPI security context" +msgstr "не удалось получить маркер из контекста безопасности SSPI" + +#: libpq/auth.c:1636 libpq/auth.c:1655 +#, c-format +msgid "could not translate name" +msgstr "не удалось преобразовать имя" + +#: libpq/auth.c:1668 +#, c-format +msgid "realm name too long" +msgstr "имя области слишком длинное" + +#: libpq/auth.c:1683 +#, c-format +msgid "translated account name too long" +msgstr "преобразованное имя учётной записи слишком длинное" + +#: libpq/auth.c:1864 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "не удалось создать сокет для подключения к серверу Ident: %m" + +#: libpq/auth.c:1879 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "не удалось привязаться к локальному адресу \"%s\": %m" + +#: libpq/auth.c:1891 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "не удалось подключиться к серверу Ident по адресу \"%s\", порт %s: %m" + +#: libpq/auth.c:1913 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "" +"не удалось отправить запрос серверу Ident по адресу \"%s\", порт %s: %m" + +#: libpq/auth.c:1930 +#, c-format +msgid "" +"could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "" +"не удалось получить ответ от сервера Ident по адресу \"%s\", порт %s: %m" + +#: libpq/auth.c:1940 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "неверно форматированный ответ от сервера Ident: \"%s\"" + +#: libpq/auth.c:1987 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "проверка подлинности peer в этой ОС не поддерживается" + +#: libpq/auth.c:1991 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "не удалось получить данные пользователя через механизм peer: %m" + +#: libpq/auth.c:2003 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "найти локального пользователя по идентификатору (%ld) не удалось: %s" + +#: libpq/auth.c:2102 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "ошибка в нижележащем слое PAM: %s" + +#: libpq/auth.c:2172 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "не удалось создать аутентификатор PAM: %s" + +#: libpq/auth.c:2183 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "ошибка в pam_set_item(PAM_USER): %s" + +#: libpq/auth.c:2215 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "ошибка в pam_set_item(PAM_RHOST): %s" + +#: libpq/auth.c:2227 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "ошибка в pam_set_item(PAM_CONV): %s" + +#: libpq/auth.c:2240 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "ошибка в pam_authenticate: %s" + +#: libpq/auth.c:2253 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "ошибка в pam_acct_mgmt: %s" + +#: libpq/auth.c:2264 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "не удалось освободить аутентификатор PAM: %s" + +#: libpq/auth.c:2340 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "не удалось инициализировать LDAP (код ошибки: %d)" + +#: libpq/auth.c:2377 +#, c-format +msgid "could not extract domain name from ldapbasedn" +msgstr "не удалось извлечь имя домена из ldapbasedn" + +#: libpq/auth.c:2385 +#, c-format +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "для аутентификации LDAP не удалось найти записи DNS SRV для \"%s\"" + +#: libpq/auth.c:2387 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "Задайте имя сервера LDAP явным образом." + +#: libpq/auth.c:2439 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "не удалось инициализировать LDAP: %s" + +#: libpq/auth.c:2449 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "протокол ldaps с текущей библиотекой LDAP не поддерживается" + +#: libpq/auth.c:2457 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "не удалось инициализировать LDAP: %m" + +#: libpq/auth.c:2467 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "не удалось задать версию протокола LDAP: %s" + +#: libpq/auth.c:2507 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "не удалось найти функцию _ldap_start_tls_sA в wldap32.dll" + +#: libpq/auth.c:2508 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "LDAP через SSL не поддерживается в этой ОС." + +#: libpq/auth.c:2524 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "не удалось начать сеанс LDAP TLS: %s" + +#: libpq/auth.c:2595 +#, c-format +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "LDAP-сервер не задан и значение ldapbasedn не определено" + +#: libpq/auth.c:2602 +#, c-format +msgid "LDAP server not specified" +msgstr "LDAP-сервер не определён" + +#: libpq/auth.c:2664 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "недопустимый символ в имени пользователя для проверки подлинности LDAP" + +#: libpq/auth.c:2681 +#, c-format +msgid "" +"could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": " +"%s" +msgstr "" +"не удалось выполнить начальную привязку LDAP для ldapbinddn \"%s\" на " +"сервере \"%s\": %s" + +#: libpq/auth.c:2710 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "" +"не удалось выполнить LDAP-поиск по фильтру \"%s\" на сервере \"%s\": %s" + +#: libpq/auth.c:2724 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "в LDAP нет пользователя \"%s\"" + +#: libpq/auth.c:2725 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "LDAP-поиск по фильтру \"%s\" на сервере \"%s\" не вернул результатов" + +#: libpq/auth.c:2729 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "пользователь LDAP \"%s\" не уникален" + +#: libpq/auth.c:2730 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "" +"LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "LDAP-поиск по фильтру \"%s\" на сервере \"%s\" вернул %d запись." +msgstr[1] "LDAP-поиск по фильтру \"%s\" на сервере \"%s\" вернул %d записи." +msgstr[2] "LDAP-поиск по фильтру \"%s\" на сервере \"%s\" вернул %d записей." + +#: libpq/auth.c:2750 +#, c-format +msgid "" +"could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "" +"не удалось получить dn для первого результата, соответствующего \"%s\" на " +"сервере \"%s\": %s" + +#: libpq/auth.c:2771 +#, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "" +"не удалось отвязаться после поиска пользователя \"%s\" на сервере \"%s\"" + +#: libpq/auth.c:2802 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "" +"ошибка при регистрации в LDAP пользователя \"%s\" на сервере \"%s\": %s" + +#: libpq/auth.c:2831 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "Диагностика LDAP: %s" + +#: libpq/auth.c:2858 +#, c-format +msgid "" +"certificate authentication failed for user \"%s\": client certificate " +"contains no user name" +msgstr "" +"ошибка проверки подлинности пользователя \"%s\" по сертификату: сертификат " +"клиента не содержит имя пользователя" + +#: libpq/auth.c:2875 +#, c-format +msgid "" +"certificate validation (clientcert=verify-full) failed for user \"%s\": CN " +"mismatch" +msgstr "" +"проверка сертификата (clientcert=verify-full) для пользователя \"%s\" не " +"прошла: отличается CN" + +#: libpq/auth.c:2976 +#, c-format +msgid "RADIUS server not specified" +msgstr "RADIUS-сервер не определён" + +#: libpq/auth.c:2983 +#, c-format +msgid "RADIUS secret not specified" +msgstr "секрет RADIUS не определён" + +# well-spelled: симв +#: libpq/auth.c:2997 +#, c-format +msgid "" +"RADIUS authentication does not support passwords longer than %d characters" +msgstr "проверка подлинности RADIUS не поддерживает пароли длиннее %d симв." + +#: libpq/auth.c:3102 libpq/hba.c:1946 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "не удалось преобразовать имя сервера RADIUS \"%s\" в адрес: %s" + +#: libpq/auth.c:3116 +#, c-format +msgid "could not generate random encryption vector" +msgstr "не удалось сгенерировать случайный вектор шифрования" + +#: libpq/auth.c:3150 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "не удалось вычислить MD5-хеш пароля" + +#: libpq/auth.c:3176 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "не удалось создать сокет RADIUS: %m" + +#: libpq/auth.c:3198 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "не удалось привязаться к локальному сокету RADIUS: %m" + +#: libpq/auth.c:3208 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "не удалось отправить пакет RADIUS: %m" + +#: libpq/auth.c:3241 libpq/auth.c:3267 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "превышено время ожидания ответа RADIUS от %s" + +#: libpq/auth.c:3260 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "не удалось проверить состояние сокета RADIUS: %m" + +#: libpq/auth.c:3290 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "не удалось прочитать ответ RADIUS: %m" + +#: libpq/auth.c:3303 libpq/auth.c:3307 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "ответ RADIUS от %s был отправлен с неверного порта: %d" + +#: libpq/auth.c:3316 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "слишком короткий ответ RADIUS от %s: %d" + +#: libpq/auth.c:3323 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "в ответе RADIUS от %s испорчена длина: %d (фактическая длина %d)" + +#: libpq/auth.c:3331 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "пришёл ответ RADIUS от %s на другой запрос: %d (ожидался %d)" + +#: libpq/auth.c:3356 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "не удалось вычислить MD5 для принятого пакета" + +#: libpq/auth.c:3365 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "ответ RADIUS от %s содержит неверную подпись MD5" + +#: libpq/auth.c:3383 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "ответ RADIUS от %s содержит неверный код (%d) для пользователя \"%s\"" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:553 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "неверный дескриптор большого объекта: %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "дескриптор большого объекта %d не был открыт для чтения" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:560 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "дескриптор большого объекта %d не был открыт для записи" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "" +"результат lo_lseek для дескриптора большого объекта %d вне допустимого " +"диапазона" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "" +"результат lo_tell для дескриптора большого объекта %d вне допустимого " +"диапазона" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "не удалось открыть файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "не удалось прочитать файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:514 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "не удалось создать файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:526 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "не удалось записать файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:760 +#, c-format +msgid "large object read request is too large" +msgstr "при чтении большого объекта запрошен чрезмерный размер" + +#: libpq/be-fsstubs.c:802 utils/adt/genfile.c:265 utils/adt/genfile.c:304 +#: utils/adt/genfile.c:340 +#, c-format +msgid "requested length cannot be negative" +msgstr "запрошенная длина не может быть отрицательной" + +#: libpq/be-fsstubs.c:855 storage/large_object/inv_api.c:297 +#: storage/large_object/inv_api.c:309 storage/large_object/inv_api.c:513 +#: storage/large_object/inv_api.c:624 storage/large_object/inv_api.c:814 +#, c-format +msgid "permission denied for large object %u" +msgstr "нет доступа к большому объекту %u" + +#: libpq/be-secure-common.c:93 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "не удалось прочитать вывод команды \"%s\": %m" + +#: libpq/be-secure-common.c:113 +#, c-format +msgid "command \"%s\" failed" +msgstr "ошибка команды \"%s\"" + +#: libpq/be-secure-common.c:141 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "не удалось обратиться к файлу закрытого ключа \"%s\": %m" + +#: libpq/be-secure-common.c:150 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "файл закрытого ключа \"%s\" не является обычным" + +#: libpq/be-secure-common.c:165 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "" +"файл закрытого ключа \"%s\" должен принадлежать пользователю, запускающему " +"сервер, или root" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "к файлу закрытого ключа \"%s\" имеют доступ все или группа" + +#: libpq/be-secure-common.c:190 +#, c-format +msgid "" +"File must have permissions u=rw (0600) or less if owned by the database " +"user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "" +"Для файла должны быть заданы разрешения u=rw (0600) или более строгие, если " +"он принадлежит пользователю сервера, либо u=rw,g=r (0640) или более строгие, " +"если он принадлежит root." + +#: libpq/be-secure-gssapi.c:204 +msgid "GSSAPI wrap error" +msgstr "ошибка обёртывания сообщения в GSSAPI" + +#: libpq/be-secure-gssapi.c:211 +#, c-format +msgid "outgoing GSSAPI message would not use confidentiality" +msgstr "исходящее сообщение GSSAPI не будет защищено" + +#: libpq/be-secure-gssapi.c:218 libpq/be-secure-gssapi.c:622 +#, c-format +msgid "server tried to send oversize GSSAPI packet (%zu > %zu)" +msgstr "сервер попытался передать чрезмерно большой пакет GSSAPI (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:351 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "клиент передал чрезмерно большой пакет GSSAPI (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:389 +msgid "GSSAPI unwrap error" +msgstr "ошибка развёртывания сообщения в GSSAPI" + +#: libpq/be-secure-gssapi.c:396 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "входящее сообщение GSSAPI не защищено" + +#: libpq/be-secure-gssapi.c:570 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "клиент передал чрезмерно большой пакет GSSAPI (%zu > %d)" + +#: libpq/be-secure-gssapi.c:594 +msgid "could not accept GSSAPI security context" +msgstr "принять контекст безопасности GSSAPI не удалось" + +#: libpq/be-secure-gssapi.c:689 +msgid "GSSAPI size check error" +msgstr "ошибка проверки размера в GSSAPI" + +#: libpq/be-secure-openssl.c:112 +#, c-format +msgid "could not create SSL context: %s" +msgstr "не удалось создать контекст SSL: %s" + +#: libpq/be-secure-openssl.c:138 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "не удалось загрузить сертификат сервера \"%s\": %s" + +#: libpq/be-secure-openssl.c:158 +#, c-format +msgid "" +"private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "" +"файл закрытого ключа \"%s\" нельзя перезагрузить, так как он защищён паролем" + +#: libpq/be-secure-openssl.c:163 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "не удалось загрузить файл закрытого ключа \"%s\": %s" + +#: libpq/be-secure-openssl.c:172 +#, c-format +msgid "check of private key failed: %s" +msgstr "ошибка при проверке закрытого ключа: %s" + +#. translator: first %s is a GUC option name, second %s is its value +#: libpq/be-secure-openssl.c:185 libpq/be-secure-openssl.c:208 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "для параметра \"%s\" значение \"%s\" не поддерживается в данной сборке" + +#: libpq/be-secure-openssl.c:195 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "не удалось задать минимальную версию протокола SSL" + +#: libpq/be-secure-openssl.c:218 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "не удалось задать максимальную версию протокола SSL" + +#: libpq/be-secure-openssl.c:234 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "не удалось задать диапазон версий протокола SSL" + +#: libpq/be-secure-openssl.c:235 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "Версия \"%s\" не может быть выше \"%s\"" + +#: libpq/be-secure-openssl.c:259 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "не удалось установить список шифров (подходящие шифры отсутствуют)" + +#: libpq/be-secure-openssl.c:277 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "не удалось загрузить файл корневых сертификатов \"%s\": %s" + +#: libpq/be-secure-openssl.c:304 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "" +"не удалось загрузить файл со списком отзыва сертификатов SSL \"%s\": %s" + +#: libpq/be-secure-openssl.c:380 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "" +"инициализировать SSL-подключение не удалось: контекст SSL не установлен" + +#: libpq/be-secure-openssl.c:388 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "инициализировать SSL-подключение не удалось: %s" + +#: libpq/be-secure-openssl.c:396 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "не удалось создать SSL-сокет: %s" + +#: libpq/be-secure-openssl.c:451 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "не удалось принять SSL-подключение: %m" + +#: libpq/be-secure-openssl.c:455 libpq/be-secure-openssl.c:508 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "не удалось принять SSL-подключение: обрыв данных" + +#: libpq/be-secure-openssl.c:494 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "не удалось принять SSL-подключение: %s" + +#: libpq/be-secure-openssl.c:497 +#, c-format +msgid "" +"This may indicate that the client does not support any SSL protocol version " +"between %s and %s." +msgstr "" +"Это может указывать на то, что клиент не поддерживает ни одну версию " +"протокола SSL между %s и %s." + +#: libpq/be-secure-openssl.c:513 libpq/be-secure-openssl.c:644 +#: libpq/be-secure-openssl.c:708 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "нераспознанный код ошибки SSL: %d" + +#: libpq/be-secure-openssl.c:555 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "Имя SSL-сертификата включает нулевой байт" + +#: libpq/be-secure-openssl.c:633 libpq/be-secure-openssl.c:692 +#, c-format +msgid "SSL error: %s" +msgstr "ошибка SSL: %s" + +#: libpq/be-secure-openssl.c:873 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "не удалось открыть файл параметров DH \"%s\": %m" + +#: libpq/be-secure-openssl.c:885 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "не удалось загрузить файл параметров DH: %s" + +#: libpq/be-secure-openssl.c:895 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "неверные параметры DH: %s" + +#: libpq/be-secure-openssl.c:903 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "неверные параметры DH: p - не простое число" + +#: libpq/be-secure-openssl.c:911 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "" +"неверные параметры DH: нет подходящего генератора или небезопасное простое " +"число" + +#: libpq/be-secure-openssl.c:1067 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: не удалось загрузить параметры DH" + +#: libpq/be-secure-openssl.c:1075 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: не удалось задать параметры DH: %s" + +#: libpq/be-secure-openssl.c:1102 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: нераспознанное имя кривой: %s" + +#: libpq/be-secure-openssl.c:1111 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: не удалось создать ключ" + +#: libpq/be-secure-openssl.c:1139 +msgid "no SSL error reported" +msgstr "нет сообщения об ошибке SSL" + +#: libpq/be-secure-openssl.c:1143 +#, c-format +msgid "SSL error code %lu" +msgstr "код ошибки SSL: %lu" + +#: libpq/be-secure.c:122 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "SSL-подключение от \"%s\"" + +#: libpq/be-secure.c:207 libpq/be-secure.c:303 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "закрытие подключения из-за неожиданного завершения главного процесса" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "Роль \"%s\" не существует." + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "Пользователь \"%s\" не имеет пароля." + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "Срок пароля пользователя \"%s\" истёк." + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "" +"Пользователь \"%s\" имеет пароль, неподходящий для аутентификации по MD5." + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "Пароль не подходит для пользователя \"%s\"." + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "Пароль пользователя \"%s\" представлен в неизвестном формате." + +#: libpq/hba.c:235 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "" +"слишком длинный элемент в файле конфигурации безопасности пропускается: \"%s" +"\"" + +#: libpq/hba.c:407 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "" +"не удалось открыть дополнительный файл конфигурации безопасности \"@%s\" как " +"\"%s\": %m" + +#: libpq/hba.c:509 +#, c-format +msgid "authentication file line too long" +msgstr "слишком длинная строка в файле конфигурации безопасности" + +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1013 libpq/hba.c:1022 +#: libpq/hba.c:1035 libpq/hba.c:1056 libpq/hba.c:1069 libpq/hba.c:1089 +#: libpq/hba.c:1111 libpq/hba.c:1123 libpq/hba.c:1182 libpq/hba.c:1202 +#: libpq/hba.c:1216 libpq/hba.c:1236 libpq/hba.c:1247 libpq/hba.c:1262 +#: libpq/hba.c:1281 libpq/hba.c:1297 libpq/hba.c:1309 libpq/hba.c:1346 +#: libpq/hba.c:1387 libpq/hba.c:1400 libpq/hba.c:1422 libpq/hba.c:1434 +#: libpq/hba.c:1452 libpq/hba.c:1502 libpq/hba.c:1546 libpq/hba.c:1557 +#: libpq/hba.c:1573 libpq/hba.c:1590 libpq/hba.c:1600 libpq/hba.c:1658 +#: libpq/hba.c:1696 libpq/hba.c:1718 libpq/hba.c:1730 libpq/hba.c:1817 +#: libpq/hba.c:1835 libpq/hba.c:1929 libpq/hba.c:1948 libpq/hba.c:1977 +#: libpq/hba.c:1990 libpq/hba.c:2013 libpq/hba.c:2035 libpq/hba.c:2049 +#: tsearch/ts_locale.c:217 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "строка %d файла конфигурации \"%s\"" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:865 +#, c-format +msgid "" +"authentication option \"%s\" is only valid for authentication methods %s" +msgstr "параметр проверки подлинности \"%s\" допускается только для методов %s" + +#: libpq/hba.c:885 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "" +"для метода проверки подлинности \"%s\" требуется определить аргумент \"%s\"" + +#: libpq/hba.c:913 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "отсутствует запись в файле \"%s\" в конце строки %d" + +#: libpq/hba.c:924 +#, c-format +msgid "multiple values in ident field" +msgstr "множественные значения в поле ident" + +#: libpq/hba.c:973 +#, c-format +msgid "multiple values specified for connection type" +msgstr "для типа подключения указано несколько значений" + +#: libpq/hba.c:974 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "Определите в строке единственный тип подключения." + +#: libpq/hba.c:988 +#, c-format +msgid "local connections are not supported by this build" +msgstr "локальные подключения не поддерживаются в этой сборке" + +#: libpq/hba.c:1011 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "запись с hostssl недействительна, так как поддержка SSL отключена" + +#: libpq/hba.c:1012 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "Установите ssl = on в postgresql.conf." + +#: libpq/hba.c:1020 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "" +"запись с hostssl недействительна, так как SSL не поддерживается в этой сборке" + +#: libpq/hba.c:1021 +#, c-format +msgid "Compile with --with-openssl to use SSL connections." +msgstr "Для работы с SSL скомпилируйте postgresql с ключом --with-openssl." + +#: libpq/hba.c:1033 +#, c-format +msgid "" +"hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "" +"запись с hostgssenc недействительна, так как GSSAPI не поддерживается в этой " +"сборке" + +#: libpq/hba.c:1034 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "Для работы с GSSAPI скомпилируйте postgresql с ключом --with-gssapi." + +#: libpq/hba.c:1054 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "неверный тип подключения \"%s\"" + +#: libpq/hba.c:1068 +#, c-format +msgid "end-of-line before database specification" +msgstr "конец строки перед определением базы данных" + +#: libpq/hba.c:1088 +#, c-format +msgid "end-of-line before role specification" +msgstr "конец строки перед определением роли" + +#: libpq/hba.c:1110 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "конец строки перед определением IP-адресов" + +#: libpq/hba.c:1121 +#, c-format +msgid "multiple values specified for host address" +msgstr "для адреса узла указано несколько значений" + +#: libpq/hba.c:1122 +#, c-format +msgid "Specify one address range per line." +msgstr "Определите в строке один диапазон адресов." + +#: libpq/hba.c:1180 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "неверный IP-адрес \"%s\": %s" + +#: libpq/hba.c:1200 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "указать одновременно и имя узла, и маску CIDR нельзя: \"%s\"" + +#: libpq/hba.c:1214 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "неверная маска CIDR в адресе \"%s\"" + +#: libpq/hba.c:1234 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "конец строки перед определением маски сети" + +#: libpq/hba.c:1235 +#, c-format +msgid "" +"Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "" +"Укажите диапазон адресов в формате CIDR или задайте отдельную маску сети." + +#: libpq/hba.c:1246 +#, c-format +msgid "multiple values specified for netmask" +msgstr "для сетевой маски указано несколько значений" + +#: libpq/hba.c:1260 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "неверная маска IP \"%s\": %s" + +#: libpq/hba.c:1280 +#, c-format +msgid "IP address and mask do not match" +msgstr "IP-адрес не соответствует маске" + +#: libpq/hba.c:1296 +#, c-format +msgid "end-of-line before authentication method" +msgstr "конец строки перед методом проверки подлинности" + +#: libpq/hba.c:1307 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "для типа проверки подлинности указано несколько значений" + +#: libpq/hba.c:1308 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "Определите в строке единственный тип проверки подлинности." + +#: libpq/hba.c:1385 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "неверный метод проверки подлинности \"%s\"" + +#: libpq/hba.c:1398 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "" +"неверный метод проверки подлинности \"%s\": не поддерживается в этой сборке" + +#: libpq/hba.c:1421 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "проверка подлинности gssapi для локальных сокетов не поддерживается" + +#: libpq/hba.c:1433 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "проверка подлинности peer поддерживается только для локальных сокетов" + +#: libpq/hba.c:1451 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "" +"проверка подлинности cert поддерживается только для подключений hostssl" + +#: libpq/hba.c:1501 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "параметр проверки подлинности указан не в формате имя=значение: %s" + +#: libpq/hba.c:1545 +#, c-format +msgid "" +"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, " +"ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "" +"нельзя использовать ldapbasedn, ldapbinddn, ldapbindpasswd, " +"ldapsearchattribute, ldapsearchfilter или ldapurl вместе с ldapprefix" + +#: libpq/hba.c:1556 +#, c-format +msgid "" +"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix" +"\", or \"ldapsuffix\" to be set" +msgstr "" +"для метода проверки подлинности \"ldap\" требуется установить аргументы " +"\"ldapbasedn\" и \"ldapprefix\" или \"ldapsuffix\"" + +#: libpq/hba.c:1572 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "нельзя использовать ldapsearchattribute вместе с ldapsearchfilter" + +#: libpq/hba.c:1589 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "список серверов RADIUS не может быть пустым" + +#: libpq/hba.c:1599 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "список секретов RADIUS не может быть пустым" + +#: libpq/hba.c:1652 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "" +"количество элементов %s (%d) должно равняться 1 или количеству элементов %s " +"(%d)" + +#: libpq/hba.c:1686 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi и cert" + +#: libpq/hba.c:1695 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert можно определить только в строках \"hostssl\"" + +#: libpq/hba.c:1717 +#, c-format +msgid "" +"clientcert cannot be set to \"no-verify\" when using \"cert\" authentication" +msgstr "" +"clientcert не может иметь значение \"no-verify\" при использовании проверки " +"подлинности \"cert\"" + +#: libpq/hba.c:1729 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "неверное значение для clientcert: \"%s\"" + +#: libpq/hba.c:1763 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "не удалось разобрать URL-адрес LDAP \"%s\": %s" + +#: libpq/hba.c:1774 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "неподдерживаемая схема в URL-адресе LDAP: %s" + +#: libpq/hba.c:1798 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "URL-адреса LDAP не поддерживаются в этой ОС" + +#: libpq/hba.c:1816 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "неверное значение ldapscheme: \"%s\"" + +#: libpq/hba.c:1834 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "неверный номер порта LDAP: \"%s\"" + +#: libpq/hba.c:1880 libpq/hba.c:1887 +msgid "gssapi and sspi" +msgstr "gssapi и sspi" + +#: libpq/hba.c:1896 libpq/hba.c:1905 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1927 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "не удалось разобрать список серверов RADIUS \"%s\"" + +#: libpq/hba.c:1975 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "не удалось разобрать список портов RADIUS \"%s\"" + +#: libpq/hba.c:1989 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "неверный номер порта RADIUS: \"%s\"" + +#: libpq/hba.c:2011 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "не удалось разобрать список секретов RADIUS \"%s\"" + +#: libpq/hba.c:2033 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "не удалось разобрать список идентификаторов RADIUS \"%s\"" + +#: libpq/hba.c:2047 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "нераспознанное имя атрибута проверки подлинности: \"%s\"" + +#: libpq/hba.c:2193 libpq/hba.c:2613 guc-file.l:631 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "открыть файл конфигурации \"%s\" не удалось: %m" + +#: libpq/hba.c:2244 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "файл конфигурации \"%s\" не содержит записей" + +#: libpq/hba.c:2768 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "неверное регулярное выражение \"%s\": %s" + +#: libpq/hba.c:2828 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "ошибка при поиске по регулярному выражению для \"%s\": %s" + +#: libpq/hba.c:2847 +#, c-format +msgid "" +"regular expression \"%s\" has no subexpressions as requested by " +"backreference in \"%s\"" +msgstr "" +"в регулярном выражении \"%s\" нет подвыражений, требуемых для обратной " +"ссылки в \"%s\"" + +#: libpq/hba.c:2943 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "" +"указанное имя пользователя (%s) не совпадает с именем прошедшего проверку " +"(%s)" + +#: libpq/hba.c:2963 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "" +"нет соответствия в файле сопоставлений \"%s\" для пользователя \"%s\", " +"прошедшего проверку как \"%s\"" + +#: libpq/hba.c:2996 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "не удалось открыть файл сопоставлений пользователей \"%s\": %m" + +#: libpq/pqcomm.c:218 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "не удалось перевести сокет в неблокирующий режим: %m" + +#: libpq/pqcomm.c:369 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "длина пути Unix-сокета \"%s\" превышает предел (%d байт)" + +#: libpq/pqcomm.c:390 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "перевести имя узла \"%s\", службы \"%s\" в адрес не удалось: %s" + +#: libpq/pqcomm.c:394 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "не удалось перевести имя службы \"%s\" в адрес: %s" + +#: libpq/pqcomm.c:421 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "" +"не удалось привязаться ко всем запрошенным адресам: превышен предел " +"MAXLISTEN (%d)" + +#: libpq/pqcomm.c:430 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:434 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:439 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:444 +#, c-format +msgid "unrecognized address family %d" +msgstr "нераспознанное семейство адресов: %d" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:470 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "не удалось создать сокет %s для адреса \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:496 +#, c-format +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "ошибка в setsockopt(SO_REUSEADDR) для адреса %s \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:513 +#, c-format +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "ошибка в setsockopt(IPV6_V6ONLY) для адреса %s \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:533 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "не удалось привязаться к адресу %s \"%s\": %m" + +#: libpq/pqcomm.c:536 +#, c-format +msgid "" +"Is another postmaster already running on port %d? If not, remove socket file " +"\"%s\" and retry." +msgstr "" +"Возможно порт %d занят другим процессом postmaster? Если нет, удалите файл " +"\"%s\" и повторите попытку." + +#: libpq/pqcomm.c:539 +#, c-format +msgid "" +"Is another postmaster already running on port %d? If not, wait a few seconds " +"and retry." +msgstr "" +"Возможно порт %d занят другим процессом postmaster? Если нет, повторите " +"попытку через несколько секунд." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:572 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "не удалось привязаться к адресу %s \"%s\": %m" + +#: libpq/pqcomm.c:581 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "для приёма подключений открыт Unix-сокет \"%s\"" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:587 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "для приёма подключений по адресу %s \"%s\" открыт порт %d" + +#: libpq/pqcomm.c:670 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "группа \"%s\" не существует" + +#: libpq/pqcomm.c:680 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "не удалось установить группу для файла \"%s\": %m" + +#: libpq/pqcomm.c:691 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "не удалось установить права доступа для файла \"%s\": %m" + +#: libpq/pqcomm.c:721 +#, c-format +msgid "could not accept new connection: %m" +msgstr "не удалось принять новое подключение: %m" + +#: libpq/pqcomm.c:911 +#, c-format +msgid "there is no client connection" +msgstr "нет клиентского подключения" + +#: libpq/pqcomm.c:962 libpq/pqcomm.c:1058 +#, c-format +msgid "could not receive data from client: %m" +msgstr "не удалось получить данные от клиента: %m" + +#: libpq/pqcomm.c:1203 tcop/postgres.c:4154 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "закрытие подключения из-за потери синхронизации протокола" + +#: libpq/pqcomm.c:1269 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "неожиданный обрыв данных в слове длины сообщения" + +#: libpq/pqcomm.c:1280 +#, c-format +msgid "invalid message length" +msgstr "неверная длина сообщения" + +#: libpq/pqcomm.c:1302 libpq/pqcomm.c:1315 +#, c-format +msgid "incomplete message from client" +msgstr "неполное сообщение от клиента" + +#: libpq/pqcomm.c:1448 +#, c-format +msgid "could not send data to client: %m" +msgstr "не удалось послать данные клиенту: %m" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "в сообщении не осталось данных" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1471 utils/adt/rowtypes.c:567 +#, c-format +msgid "insufficient data left in message" +msgstr "недостаточно данных осталось в сообщении" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "неверная строка в сообщении" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "неверный формат сообщения" + +#: main/main.c:246 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: ошибка WSAStartup: %d\n" + +#: main/main.c:310 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%s - сервер PostgreSQL.\n" +"\n" + +#: main/main.c:311 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Использование:\n" +" %s [ПАРАМЕТР]...\n" +"\n" + +#: main/main.c:312 +#, c-format +msgid "Options:\n" +msgstr "Параметры:\n" + +#: main/main.c:313 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B ЧИСЛО_БУФ число разделяемых буферов\n" + +#: main/main.c:314 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c ИМЯ=ЗНАЧЕНИЕ установить параметр выполнения\n" + +#: main/main.c:315 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C ИМЯ вывести значение параметра выполнения и выйти\n" + +#: main/main.c:316 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 уровень отладочных сообщений\n" + +#: main/main.c:317 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D КАТАЛОГ каталог с данными\n" + +# well-spelled: ДМГ +#: main/main.c:318 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e использовать европейский формат дат (ДМГ)\n" + +#: main/main.c:319 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F выключить синхронизацию с ФС\n" + +#: main/main.c:320 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h ИМЯ имя или IP-адрес для приёма сетевых соединений\n" + +#: main/main.c:321 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i включить соединения TCP/IP\n" + +#: main/main.c:322 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k КАТАЛОГ расположение Unix-сокетов\n" + +#: main/main.c:324 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l разрешить SSL-подключения\n" + +# well-spelled: ПОДКЛ +#: main/main.c:326 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N МАКС_ПОДКЛ предельное число подключений\n" + +#: main/main.c:327 +#, c-format +msgid "" +" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr "" +" -o ПАРАМЕТРЫ параметры для серверных процессов (уже неактуально)\n" + +#: main/main.c:328 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p ПОРТ номер порта для приёма подключений\n" + +#: main/main.c:329 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s показывать статистику после каждого запроса\n" + +#: main/main.c:330 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S РАБ_ПАМЯТЬ задать объём памяти для сортировки (в КБ)\n" + +#: main/main.c:331 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: main/main.c:332 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --ИМЯ=ЗНАЧЕНИЕ установить параметр выполнения\n" + +#: main/main.c:333 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config вывести параметры конфигурации и выйти\n" + +#: main/main.c:334 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: main/main.c:336 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"Параметры для разработчиков:\n" + +#: main/main.c:337 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h запретить некоторые типы планов\n" + +#: main/main.c:338 +#, c-format +msgid "" +" -n do not reinitialize shared memory after abnormal exit\n" +msgstr "" +" -n не переинициализировать разделяемую память после\n" +" аварийного выхода\n" + +#: main/main.c:339 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O разрешить изменять структуру системных таблиц\n" + +#: main/main.c:340 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P отключить системные индексы\n" + +#: main/main.c:341 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex показать время каждого запроса\n" + +#: main/main.c:342 +#, c-format +msgid "" +" -T send SIGSTOP to all backend processes if one dies\n" +msgstr "" +" -T посылать сигнал SIGSTOP всем серверным процессам\n" +" при отключении одного\n" + +#: main/main.c:343 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr "" +" -W СЕК ждать заданное число секунд для подключения отладчика\n" + +#: main/main.c:345 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"Параметры для монопольного режима:\n" + +#: main/main.c:346 +#, c-format +msgid "" +" --single selects single-user mode (must be first argument)\n" +msgstr "" +" --single включить монопольный режим\n" +" (этот аргумент должен быть первым)\n" + +#: main/main.c:347 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " ИМЯ_БД база данных (по умолчанию - имя пользователя)\n" + +#: main/main.c:348 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 переопределить уровень отладочных сообщений\n" + +#: main/main.c:349 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E выводить SQL-операторы перед выполнением\n" + +#: main/main.c:350 +#, c-format +msgid "" +" -j do not use newline as interactive query delimiter\n" +msgstr "" +" -j не считать конец строки разделителем интерактивных " +"запросов\n" + +#: main/main.c:351 main/main.c:356 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r ИМЯ_ФАЙЛА перенаправить STDOUT и STDERR в указанный файл\n" + +#: main/main.c:353 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"Параметры для режима инициализации:\n" + +#: main/main.c:354 +#, c-format +msgid "" +" --boot selects bootstrapping mode (must be first argument)\n" +msgstr "" +" --boot включить режим инициализации\n" +" (этот аргумент должен быть первым)\n" + +#: main/main.c:355 +#, c-format +msgid "" +" DBNAME database name (mandatory argument in bootstrapping " +"mode)\n" +msgstr "" +" ИМЯ_БД имя базы данных (необходимо в режиме инициализации)\n" + +#: main/main.c:357 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x ЧИСЛО параметр для внутреннего использования\n" + +#: main/main.c:359 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Полный список параметров конфигурации выполнения и варианты\n" +"их установки через командную строку или в файле конфигурации\n" +"вы можете найти в документации.\n" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: main/main.c:363 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: main/main.c:374 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Запускать сервер PostgreSQL под именем \"root\" не разрешается.\n" +"Для предотвращения возможной компрометации системы сервер\n" +"должен запускать обычный пользователь. Подробнее о том, как\n" +"правильно запускать сервер, вы можете узнать в документации.\n" + +#: main/main.c:391 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: фактический и эффективный ID пользователя должны совпадать\n" + +#: main/main.c:398 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Запускать PostgreSQL под именем пользователя с правами\n" +"администратора не разрешается.\n" +"Для предотвращения возможной компрометации системы сервер\n" +"должен запускать обычный пользователь. Подробнее о том, как\n" +"правильно запускать сервер, вы можете узнать в документации.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "расширенный тип узла \"%s\" уже существует" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "методы расширенного узла \"%s\" не зарегистрированы" + +#: nodes/nodeFuncs.c:122 nodes/nodeFuncs.c:153 parser/parse_coerce.c:2208 +#: parser/parse_coerce.c:2317 parser/parse_coerce.c:2352 +#: parser/parse_expr.c:2207 parser/parse_func.c:701 parser/parse_oper.c:967 +#: utils/fmgr/funcapi.c:528 +#, c-format +msgid "could not find array type for data type %s" +msgstr "тип массива для типа данных %s не найден" + +#: nodes/params.c:359 +#, c-format +msgid "portal \"%s\" with parameters: %s" +msgstr "портал \"%s\" с параметрами: %s" + +#: nodes/params.c:362 +#, c-format +msgid "unnamed portal with parameters: %s" +msgstr "неименованный портал с параметрами: %s" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "" +"FULL JOIN is only supported with merge-joinable or hash-joinable join " +"conditions" +msgstr "" +"FULL JOIN поддерживается только с условиями, допускающими соединение " +"слиянием или хеш-соединение" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1198 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s не может применяться к NULL-содержащей стороне внешнего соединения" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1922 parser/analyze.c:1639 parser/analyze.c:1855 +#: parser/analyze.c:2682 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s несовместимо с UNION/INTERSECT/EXCEPT" + +#: optimizer/plan/planner.c:2509 optimizer/plan/planner.c:4162 +#, c-format +msgid "could not implement GROUP BY" +msgstr "не удалось реализовать GROUP BY" + +#: optimizer/plan/planner.c:2510 optimizer/plan/planner.c:4163 +#: optimizer/plan/planner.c:4890 optimizer/prep/prepunion.c:1045 +#, c-format +msgid "" +"Some of the datatypes only support hashing, while others only support " +"sorting." +msgstr "" +"Одни типы данных поддерживают только хеширование, а другие - только " +"сортировку." + +#: optimizer/plan/planner.c:4889 +#, c-format +msgid "could not implement DISTINCT" +msgstr "не удалось реализовать DISTINCT" + +#: optimizer/plan/planner.c:5737 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "не удалось реализовать PARTITION BY для окна" + +#: optimizer/plan/planner.c:5738 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "Столбцы, разбивающие окна, должны иметь сортируемые типы данных." + +#: optimizer/plan/planner.c:5742 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "не удалось реализовать ORDER BY для окна" + +#: optimizer/plan/planner.c:5743 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Столбцы, сортирующие окна, должны иметь сортируемые типы данных." + +#: optimizer/plan/setrefs.c:451 +#, c-format +msgid "too many range table entries" +msgstr "слишком много элементов RTE" + +#: optimizer/prep/prepunion.c:508 +#, c-format +msgid "could not implement recursive UNION" +msgstr "не удалось реализовать рекурсивный UNION" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Все столбцы должны иметь хешируемые типы данных." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1044 +#, c-format +msgid "could not implement %s" +msgstr "не удалось реализовать %s" + +#: optimizer/util/clauses.c:4772 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "внедрённая в код SQL-функция \"%s\"" + +#: optimizer/util/plancat.c:133 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "" +"обращаться к временным или нежурналируемым отношениям в процессе " +"восстановления нельзя" + +#: optimizer/util/plancat.c:665 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "" +"указания со ссылкой на всю строку для выбора уникального индекса не " +"поддерживаются" + +#: optimizer/util/plancat.c:682 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "ограничению в ON CONFLICT не соответствует индекс" + +#: optimizer/util/plancat.c:732 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE не поддерживается с ограничениями-исключениями" + +#: optimizer/util/plancat.c:837 +#, c-format +msgid "" +"there is no unique or exclusion constraint matching the ON CONFLICT " +"specification" +msgstr "" +"нет уникального ограничения или ограничения-исключения, соответствующего " +"указанию ON CONFLICT" + +#: parser/analyze.c:705 parser/analyze.c:1401 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "списки VALUES должны иметь одинаковую длину" + +#: parser/analyze.c:904 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT содержит больше выражений, чем целевых столбцов" + +#: parser/analyze.c:922 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT содержит больше целевых столбцов, чем выражений" + +#: parser/analyze.c:926 +#, c-format +msgid "" +"The insertion source is a row expression containing the same number of " +"columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "" +"Источником данных является строка, включающая столько же столбцов, сколько " +"требуется для INSERT. Вы намеренно использовали скобки?" + +#: parser/analyze.c:1210 parser/analyze.c:1612 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO здесь не допускается" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1542 parser/analyze.c:2861 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s нельзя применять к VALUES" + +#: parser/analyze.c:1777 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "неверное предложение UNION/INTERSECT/EXCEPT ORDER BY" + +#: parser/analyze.c:1778 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "" +"Допустимо использование только имён столбцов, но не выражений или функций." + +#: parser/analyze.c:1779 +#, c-format +msgid "" +"Add the expression/function to every SELECT, or move the UNION into a FROM " +"clause." +msgstr "" +"Добавьте выражение/функцию в каждый SELECT или перенесите UNION в " +"предложение FROM." + +#: parser/analyze.c:1845 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO можно добавить только в первый SELECT в UNION/INTERSECT/EXCEPT" + +#: parser/analyze.c:1917 +#, c-format +msgid "" +"UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of " +"same query level" +msgstr "" +"оператор, составляющий UNION/INTERSECT/EXCEPT, не может ссылаться на другие " +"отношения на том же уровне запроса" + +#: parser/analyze.c:2004 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "все запросы в %s должны возвращать одинаковое число столбцов" + +#: parser/analyze.c:2393 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "в RETURNING должен быть минимум один столбец" + +#: parser/analyze.c:2434 +#, c-format +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "противоречивые указания SCROLL и NO SCROLL" + +#: parser/analyze.c:2453 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR не может содержать операторы, изменяющие данные, в WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2461 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s не поддерживается" + +#: parser/analyze.c:2464 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "Сохраняемые курсоры должны быть READ ONLY." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2472 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s не поддерживается" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2483 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %s не поддерживается" + +#: parser/analyze.c:2486 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Независимые курсоры должны быть READ ONLY." + +#: parser/analyze.c:2552 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "" +"в материализованных представлениях не должны использоваться операторы, " +"изменяющие данные в WITH" + +#: parser/analyze.c:2562 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "" +"в материализованных представлениях не должны использоваться временные " +"таблицы и представления" + +#: parser/analyze.c:2572 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "" +"определять материализованные представления со связанными параметрами нельзя" + +#: parser/analyze.c:2584 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "материализованные представления не могут быть нежурналируемыми" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2689 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s несовместимо с предложением DISTINCT" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2696 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s несовместимо с предложением GROUP BY" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2703 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s несовместимо с предложением HAVING" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2710 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s несовместимо с агрегатными функциями" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2717 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s несовместимо с оконными функциями" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2724 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "" +"%s не допускается с функциями, возвращающие множества, в списке результатов" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2803 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "для %s нужно указывать неполные имена отношений" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2834 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s нельзя применить к соединению" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2843 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s нельзя применить к функции" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2852 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s нельзя применить к табличной функции" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2870 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s нельзя применить к запросу WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2879 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s нельзя применить к именованному хранилищу кортежей" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2899 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "отношение \"%s\" в определении %s отсутствует в предложении FROM" + +#: parser/parse_agg.c:220 parser/parse_oper.c:222 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "для типа %s не удалось найти оператор сортировки" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "Агрегатным функциям с DISTINCT необходимо сортировать входные данные." + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "у GROUPING должно быть меньше 32 аргументов" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "агрегатные функции нельзя применять в условиях JOIN" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "операции группировки нельзя применять в условиях JOIN" + +#: parser/parse_agg.c:374 +msgid "" +"aggregate functions are not allowed in FROM clause of their own query level" +msgstr "" +"агрегатные функции нельзя применять в предложении FROM их уровня запроса" + +#: parser/parse_agg.c:376 +msgid "" +"grouping operations are not allowed in FROM clause of their own query level" +msgstr "" +"операции группировки нельзя применять в предложении FROM их уровня запроса" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "агрегатные функции нельзя применять в функциях во FROM" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "операции группировки нельзя применять в функциях во FROM" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "агрегатные функции нельзя применять в выражениях политик" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "операции группировки нельзя применять в выражениях политик" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "агрегатные функции нельзя применять в указании RANGE для окна" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "операции группировки нельзя применять в указании RANGE для окна" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "агрегатные функции нельзя применять в указании ROWS для окна" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "операции группировки нельзя применять в указании ROWS для окна" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "агрегатные функции нельзя применять в указании GROUPS для окна" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "операции группировки нельзя применять в указании GROUPS для окна" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "агрегатные функции нельзя применять в ограничениях-проверках" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "операции группировки нельзя применять в ограничениях-проверках" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "агрегатные функции нельзя применять в выражениях DEFAULT" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "операции группировки нельзя применять в выражениях DEFAULT" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "агрегатные функции нельзя применять в выражениях индексов" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "операции группировки нельзя применять в выражениях индексов" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "агрегатные функции нельзя применять в предикатах индексов" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "операции группировки нельзя применять в предикатах индексов" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "агрегатные функции нельзя применять в выражениях преобразований" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in transform expressions" +msgstr "операции группировки нельзя применять в выражениях преобразований" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "агрегатные функции нельзя применять в параметрах EXECUTE" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "операции группировки нельзя применять в параметрах EXECUTE" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "агрегатные функции нельзя применять в условиях WHEN для триггеров" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "операции группировки нельзя применять в условиях WHEN для триггеров" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in partition bound" +msgstr "агрегатные функции нельзя применять в выражении границы секции" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in partition bound" +msgstr "операции группировки нельзя применять в выражении границы секции" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "агрегатные функции нельзя применять в выражениях ключа секционирования" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "" +"операции группировки нельзя применять в выражениях ключа секционирования" + +#: parser/parse_agg.c:526 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "агрегатные функции нельзя применять в выражениях генерируемых столбцов" + +#: parser/parse_agg.c:528 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "" +"операции группировки нельзя применять в выражениях генерируемых столбцов" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "агрегатные функции нельзя применять в аргументах CALL" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "операции группировки нельзя применять в аргументах CALL" + +#: parser/parse_agg.c:542 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "агрегатные функции нельзя применять в условиях COPY FROM WHERE" + +#: parser/parse_agg.c:544 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "операции группировки нельзя применять в условиях COPY FROM WHERE" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:567 parser/parse_clause.c:1828 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "агрегатные функции нельзя применять в конструкции %s" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:570 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "операции группировки нельзя применять в конструкции %s" + +#: parser/parse_agg.c:678 +#, c-format +msgid "" +"outer-level aggregate cannot contain a lower-level variable in its direct " +"arguments" +msgstr "" +"агрегатная функция внешнего уровня не может содержать в своих аргументах " +"переменные нижнего уровня" + +#: parser/parse_agg.c:757 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "" +"вызовы агрегатных функций не могут включать вызовы функций, возвращающих " +"множества" + +#: parser/parse_agg.c:758 parser/parse_expr.c:1845 parser/parse_expr.c:2332 +#: parser/parse_func.c:872 +#, c-format +msgid "" +"You might be able to move the set-returning function into a LATERAL FROM " +"item." +msgstr "" +"Исправить ситуацию можно, переместив функцию, возвращающую множество, в " +"элемент LATERAL FROM." + +#: parser/parse_agg.c:763 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "вызовы агрегатных функций не могут включать вызовы оконных функции" + +#: parser/parse_agg.c:842 +msgid "window functions are not allowed in JOIN conditions" +msgstr "оконные функции нельзя применять в условиях JOIN" + +#: parser/parse_agg.c:849 +msgid "window functions are not allowed in functions in FROM" +msgstr "оконные функции нельзя применять в функциях во FROM" + +#: parser/parse_agg.c:855 +msgid "window functions are not allowed in policy expressions" +msgstr "оконные функции нельзя применять в выражениях политик" + +#: parser/parse_agg.c:868 +msgid "window functions are not allowed in window definitions" +msgstr "оконные функции нельзя применять в определении окна" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in check constraints" +msgstr "оконные функции нельзя применять в ограничениях-проверках" + +#: parser/parse_agg.c:904 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "оконные функции нельзя применять в выражениях DEFAULT" + +#: parser/parse_agg.c:907 +msgid "window functions are not allowed in index expressions" +msgstr "оконные функции нельзя применять в выражениях индексов" + +#: parser/parse_agg.c:910 +msgid "window functions are not allowed in index predicates" +msgstr "оконные функции нельзя применять в предикатах индексов" + +#: parser/parse_agg.c:913 +msgid "window functions are not allowed in transform expressions" +msgstr "оконные функции нельзя применять в выражениях преобразований" + +#: parser/parse_agg.c:916 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "оконные функции нельзя применять в параметрах EXECUTE" + +#: parser/parse_agg.c:919 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "оконные функции нельзя применять в условиях WHEN для триггеров" + +#: parser/parse_agg.c:922 +msgid "window functions are not allowed in partition bound" +msgstr "оконные функции нельзя применять в выражении границы секции" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "оконные функции нельзя применять в выражениях ключа секционирования" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "оконные функции нельзя применять в аргументах CALL" + +#: parser/parse_agg.c:931 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "оконные функции нельзя применять в условиях COPY FROM WHERE" + +#: parser/parse_agg.c:934 +msgid "window functions are not allowed in column generation expressions" +msgstr "оконные функции нельзя применять в выражениях генерируемых столбцов" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:954 parser/parse_clause.c:1837 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "оконные функции нельзя применять в конструкции %s" + +#: parser/parse_agg.c:988 parser/parse_clause.c:2671 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "окно \"%s\" не существует" + +#: parser/parse_agg.c:1072 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "слишком много наборов группирования (при максимуме 4096)" + +#: parser/parse_agg.c:1212 +#, c-format +msgid "" +"aggregate functions are not allowed in a recursive query's recursive term" +msgstr "" +"в рекурсивной части рекурсивного запроса агрегатные функции недопустимы" + +#: parser/parse_agg.c:1405 +#, c-format +msgid "" +"column \"%s.%s\" must appear in the GROUP BY clause or be used in an " +"aggregate function" +msgstr "" +"столбец \"%s.%s\" должен фигурировать в предложении GROUP BY или " +"использоваться в агрегатной функции" + +#: parser/parse_agg.c:1408 +#, c-format +msgid "" +"Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "" +"Прямые аргументы сортирующей агрегатной функции могут включать только " +"группируемые столбцы." + +#: parser/parse_agg.c:1413 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "" +"подзапрос использует негруппированный столбец \"%s.%s\" из внешнего запроса" + +#: parser/parse_agg.c:1577 +#, c-format +msgid "" +"arguments to GROUPING must be grouping expressions of the associated query " +"level" +msgstr "" +"аргументами GROUPING должны быть выражения группирования для " +"соответствующего уровня запроса" + +#: parser/parse_clause.c:191 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "отношение \"%s\" не может быть целевым в операторе, изменяющем данные" + +#: parser/parse_clause.c:571 parser/parse_clause.c:599 parser/parse_func.c:2424 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "" +"функции, возвращающие множества, должны находиться на верхнем уровне FROM" + +#: parser/parse_clause.c:611 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "" +"для одной и той же функции нельзя задать разные списки с определениями " +"столбцов" + +#: parser/parse_clause.c:644 +#, c-format +msgid "" +"ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "" +"у ROWS FROM() с несколькими функциями не может быть списка с определениями " +"столбцов" + +#: parser/parse_clause.c:645 +#, c-format +msgid "" +"Put a separate column definition list for each function inside ROWS FROM()." +msgstr "" +"Добавьте отдельные списки с определениями столбцов для каждой функции в ROWS " +"FROM()." + +#: parser/parse_clause.c:651 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "" +"у UNNEST() с несколькими аргументами не может быть списка с определениями " +"столбцов" + +#: parser/parse_clause.c:652 +#, c-format +msgid "" +"Use separate UNNEST() calls inside ROWS FROM(), and attach a column " +"definition list to each one." +msgstr "" +"Напишите отдельные вызовы UNNEST() внутри ROWS FROM() и добавьте список с " +"определениями столбцов к каждому." + +#: parser/parse_clause.c:659 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "" +"WITH ORDINALITY нельзя использовать со списком с определениями столбцов" + +#: parser/parse_clause.c:660 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Поместите список с определениями столбцов внутрь ROWS FROM()." + +#: parser/parse_clause.c:760 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "FOR ORDINALITY допускается только для одного столбца" + +#: parser/parse_clause.c:821 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "имя столбца \"%s\" не уникально" + +#: parser/parse_clause.c:863 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "имя пространства имён \"%s\" не уникально" + +#: parser/parse_clause.c:873 +#, c-format +msgid "only one default namespace is allowed" +msgstr "допускается только одно пространство имён по умолчанию" + +#: parser/parse_clause.c:933 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "метод %s для получения выборки не существует" + +#: parser/parse_clause.c:955 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "метод %s для получения выборки требует аргументов: %d, получено: %d" +msgstr[1] "метод %s для получения выборки требует аргументов: %d, получено: %d" +msgstr[2] "метод %s для получения выборки требует аргументов: %d, получено: %d" + +#: parser/parse_clause.c:989 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "метод %s для получения выборки не поддерживает REPEATABLE" + +#: parser/parse_clause.c:1135 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "" +"предложение TABLESAMPLE можно применять только к таблицам и " +"материализованным представлениям" + +#: parser/parse_clause.c:1318 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "имя столбца \"%s\" фигурирует в предложении USING неоднократно" + +#: parser/parse_clause.c:1333 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "имя общего столбца \"%s\" фигурирует в таблице слева неоднократно" + +#: parser/parse_clause.c:1342 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "в таблице слева нет столбца \"%s\", указанного в предложении USING" + +#: parser/parse_clause.c:1357 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "имя общего столбца \"%s\" фигурирует в таблице справа неоднократно" + +#: parser/parse_clause.c:1366 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "в таблице справа нет столбца \"%s\", указанного в предложении USING" + +#: parser/parse_clause.c:1447 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "слишком много записей в списке псевдонимов столбца \"%s\"" + +#: parser/parse_clause.c:1773 +#, c-format +msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" +msgstr "" +"количество строк в FETCH FIRST ... WITH TIES должно быть отличным от NULL" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1798 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "аргумент %s не может содержать переменные" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1963 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "выражение %s \"%s\" неоднозначно" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1992 +#, c-format +msgid "non-integer constant in %s" +msgstr "не целочисленная константа в %s" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2014 +#, c-format +msgid "%s position %d is not in select list" +msgstr "в списке выборки %s нет элемента %d" + +#: parser/parse_clause.c:2453 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE имеет ограничение в 12 элементов" + +#: parser/parse_clause.c:2659 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "окно \"%s\" уже определено" + +#: parser/parse_clause.c:2720 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "переопределить предложение PARTITION BY для окна \"%s\" нельзя" + +#: parser/parse_clause.c:2732 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "переопределить предложение ORDER BY для окна \"%s\" нельзя" + +#: parser/parse_clause.c:2762 parser/parse_clause.c:2768 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "скопировать окно \"%s\", имеющее предложение рамки, нельзя" + +#: parser/parse_clause.c:2770 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Уберите скобки в предложении OVER." + +#: parser/parse_clause.c:2790 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "" +"для RANGE со смещением PRECEDING/FOLLOWING требуется ровно один столбец в " +"ORDER BY" + +#: parser/parse_clause.c:2813 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "для режима GROUPS требуется предложение ORDER BY" + +#: parser/parse_clause.c:2883 +#, c-format +msgid "" +"in an aggregate with DISTINCT, ORDER BY expressions must appear in argument " +"list" +msgstr "" +"для агрегатной функции с DISTINCT, выражения ORDER BY должны быть в списке " +"аргументов" + +#: parser/parse_clause.c:2884 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "" +"в конструкции SELECT DISTINCT выражения ORDER BY должны быть в списке выборки" + +#: parser/parse_clause.c:2916 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "агрегатной функции с DISTINCT нужен минимум один аргумент" + +#: parser/parse_clause.c:2917 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "в SELECT DISTINCT нужен минимум один столбец" + +#: parser/parse_clause.c:2983 parser/parse_clause.c:3015 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "" +"выражения SELECT DISTINCT ON должны соответствовать начальным выражениям " +"ORDER BY" + +#: parser/parse_clause.c:3093 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC нельзя использовать в ON CONFLICT" + +#: parser/parse_clause.c:3099 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST нельзя использовать в ON CONFLICT" + +#: parser/parse_clause.c:3178 +#, c-format +msgid "" +"ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "" +"в ON CONFLICT DO UPDATE требуется наводящее указание или имя ограничения" + +#: parser/parse_clause.c:3179 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Например: ON CONFLICT (имя_столбца)." + +#: parser/parse_clause.c:3190 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT с таблицами системного каталога не поддерживается" + +#: parser/parse_clause.c:3198 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "" +"ON CONFLICT не поддерживается для таблицы \"%s\", служащей таблицей каталога" + +#: parser/parse_clause.c:3341 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "оператор %s не годится для сортировки" + +#: parser/parse_clause.c:3343 +#, c-format +msgid "" +"Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "" +"Операторы сортировки должны быть членами \"<\" или \">\" семейств операторов " +"btree." + +#: parser/parse_clause.c:3654 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "" +"RANGE со смещением PRECEDING/FOLLOWING не поддерживается для типа столбца %s" + +#: parser/parse_clause.c:3660 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s " +"and offset type %s" +msgstr "" +"RANGE со смещением PRECEDING/FOLLOWING не поддерживается для типа столбца %s " +"и типа смещения %s" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Приведите значение смещения к подходящему типу." + +#: parser/parse_clause.c:3668 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for " +"column type %s and offset type %s" +msgstr "" +"RANGE со смещением PRECEDING/FOLLOWING допускает несколько интерпретаций для " +"типа столбца %s и типа смещения %s" + +#: parser/parse_clause.c:3671 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Приведите значение смещения в точности к желаемому типу." + +#: parser/parse_coerce.c:1024 parser/parse_coerce.c:1062 +#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1095 +#: parser/parse_expr.c:2241 parser/parse_expr.c:2819 parser/parse_target.c:967 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "привести тип %s к %s нельзя" + +#: parser/parse_coerce.c:1065 +#, c-format +msgid "Input has too few columns." +msgstr "Во входных данных недостаточно столбцов." + +#: parser/parse_coerce.c:1083 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "Не удалось привести тип %s к %s в столбце %d." + +#: parser/parse_coerce.c:1098 +#, c-format +msgid "Input has too many columns." +msgstr "Во входных данных больше столбцов." + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1153 parser/parse_coerce.c:1201 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "аргумент конструкции %s должен иметь тип %s, а не %s" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1164 parser/parse_coerce.c:1213 +#, c-format +msgid "argument of %s must not return a set" +msgstr "аргумент конструкции %s не должен возвращать множество" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1353 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "в конструкции %s типы %s и %s не имеют общего" + +#: parser/parse_coerce.c:1465 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "типы аргументов %s и %s не имеют общего" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1517 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "в конструкции %s нельзя преобразовать тип %s в %s" + +#: parser/parse_coerce.c:1934 +#, c-format +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "аргументы, объявленные как \"anyelement\", должны быть однотипными" + +#: parser/parse_coerce.c:1954 +#, c-format +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "аргументы, объявленные как \"anyarray\", должны быть однотипными" + +#: parser/parse_coerce.c:1974 +#, c-format +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "аргументы, объявленные как \"anyrange\", должны быть однотипными" + +#: parser/parse_coerce.c:2008 parser/parse_coerce.c:2088 +#: utils/fmgr/funcapi.c:487 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "аргумент, объявленный как \"%s\", оказался не массивом, а типом %s" + +#: parser/parse_coerce.c:2029 +#, c-format +msgid "arguments declared \"anycompatiblerange\" are not all alike" +msgstr "" +"аргументы, объявленные как \"anycompatiblerange\", должны быть однотипными" + +#: parser/parse_coerce.c:2041 parser/parse_coerce.c:2122 +#: utils/fmgr/funcapi.c:501 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "аргумент, объявленный как \"%s\", имеет не диапазонный тип, а %s" + +#: parser/parse_coerce.c:2079 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "тип элемента аргумента \"anyarray\" определить нельзя" + +#: parser/parse_coerce.c:2105 parser/parse_coerce.c:2139 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "аргумент, объявленный как \"%s\", не согласуется с аргументом %s" + +#: parser/parse_coerce.c:2163 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "" +"не удалось определить полиморфный тип, так как входные аргументы имеют тип %s" + +#: parser/parse_coerce.c:2177 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "" +"в нарушение объявления \"anynonarray\" соответствующий аргумент оказался " +"массивом: %s" + +#: parser/parse_coerce.c:2187 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "" +"в нарушение объявления \"anyenum\" соответствующий аргумент оказался не " +"перечислением: %s" + +#: parser/parse_coerce.c:2218 parser/parse_coerce.c:2267 +#: parser/parse_coerce.c:2329 parser/parse_coerce.c:2365 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "" +"не удалось определить полиморфный тип %s, так как входные аргументы имеют " +"тип %s" + +#: parser/parse_coerce.c:2228 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "тип %s (anycompatiblerange) не соответствует типу %s (anycompatible)" + +#: parser/parse_coerce.c:2242 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "" +"в нарушение объявления \"anycompatiblenonarray\" соответствующий аргумент " +"оказался массивом: %s" + +#: parser/parse_coerce.c:2433 +#, c-format +msgid "A result of type %s requires at least one input of type %s." +msgstr "Для результата типа %s требуется минимум один аргумент типа %s." + +#: parser/parse_coerce.c:2445 +#, c-format +msgid "" +"A result of type %s requires at least one input of type anyelement, " +"anyarray, anynonarray, anyenum, or anyrange." +msgstr "" +"Для результата типа %s требуется минимум один аргумент типа anyelement, " +"anyarray, anynonarray, anyenum или anyrange." + +#: parser/parse_coerce.c:2457 +#, c-format +msgid "" +"A result of type %s requires at least one input of type anycompatible, " +"anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "" +"Для результата типа %s требуется минимум один аргумент типа anycompatible, " +"anycompatiblearray, anycompatiblenonarray или anycompatiblerange." + +#: parser/parse_coerce.c:2487 +msgid "A result of type internal requires at least one input of type internal." +msgstr "" +"Для результата типа internal требуется минимум один аргумент типа internal." + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:981 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "несовпадение правил сортировки для неявных правил \"%s\" и \"%s\"" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:984 +#, c-format +msgid "" +"You can choose the collation by applying the COLLATE clause to one or both " +"expressions." +msgstr "" +"Правило сортировки можно выбрать явно, применив предложение COLLATE к одному " +"или обоим выражениям." + +#: parser/parse_collate.c:831 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "явно указанные правила сортировки \"%s\" и \"%s\" несовместимы" + +#: parser/parse_cte.c:42 +#, c-format +msgid "" +"recursive reference to query \"%s\" must not appear within its non-recursive " +"term" +msgstr "" +"рекурсивная ссылка на запрос \"%s\" не должна фигурировать в его не " +"рекурсивной части" + +#: parser/parse_cte.c:44 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "" +"рекурсивная ссылка на запрос \"%s\" не должна фигурировать в подзапросе" + +#: parser/parse_cte.c:46 +#, c-format +msgid "" +"recursive reference to query \"%s\" must not appear within an outer join" +msgstr "" +"рекурсивная ссылка на запрос \"%s\" не должна фигурировать во внешнем " +"соединении" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "рекурсивная ссылка на запрос \"%s\" не должна фигурировать в INTERSECT" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "рекурсивная ссылка на запрос \"%s\" не должна фигурировать в EXCEPT" + +#: parser/parse_cte.c:132 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "имя запроса WITH \"%s\" указано неоднократно" + +#: parser/parse_cte.c:264 +#, c-format +msgid "" +"WITH clause containing a data-modifying statement must be at the top level" +msgstr "" +"предложение WITH, содержащее оператор, изменяющий данные, должно быть на " +"верхнем уровне" + +#: parser/parse_cte.c:313 +#, c-format +msgid "" +"recursive query \"%s\" column %d has type %s in non-recursive term but type " +"%s overall" +msgstr "" +"в рекурсивном запросе \"%s\" столбец %d имеет тип %s в нерекурсивной части, " +"но в результате тип %s" + +#: parser/parse_cte.c:319 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Приведите результат нерекурсивной части к правильному типу." + +#: parser/parse_cte.c:324 +#, c-format +msgid "" +"recursive query \"%s\" column %d has collation \"%s\" in non-recursive term " +"but collation \"%s\" overall" +msgstr "" +"в рекурсивном запросе \"%s\" у столбца %d правило сортировки \"%s\" в не " +"рекурсивной части, но в результате правило \"%s\"" + +#: parser/parse_cte.c:328 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "" +"Измените правило сортировки в нерекурсивной части, добавив предложение " +"COLLATE." + +#: parser/parse_cte.c:418 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "запрос WITH \"%s\" содержит столбцов: %d, но указано: %d" + +#: parser/parse_cte.c:598 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "взаимная рекурсия между элементами WITH не реализована" + +#: parser/parse_cte.c:650 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "" +"рекурсивный запрос \"%s\" не должен содержать операторов, изменяющих данные" + +#: parser/parse_cte.c:658 +#, c-format +msgid "" +"recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] " +"recursive-term" +msgstr "" +"рекурсивный запрос \"%s\" должен иметь форму {нерекурсивная часть} UNION " +"[ALL] {рекурсивная часть}" + +#: parser/parse_cte.c:702 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "ORDER BY в рекурсивном запросе не поддерживается" + +#: parser/parse_cte.c:708 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "OFFSET в рекурсивном запросе не поддерживается" + +#: parser/parse_cte.c:714 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "LIMIT в рекурсивном запросе не поддерживается" + +#: parser/parse_cte.c:720 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "FOR UPDATE/SHARE в рекурсивном запросе не поддерживается" + +#: parser/parse_cte.c:777 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "рекурсивная ссылка на запрос \"%s\" указана неоднократно" + +#: parser/parse_expr.c:349 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "DEFAULT не допускается в данном контексте" + +#: parser/parse_expr.c:402 parser/parse_relation.c:3506 +#: parser/parse_relation.c:3526 +#, c-format +msgid "column %s.%s does not exist" +msgstr "столбец %s.%s не существует" + +#: parser/parse_expr.c:414 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "столбец \"%s\" не найден в типе данных %s" + +#: parser/parse_expr.c:420 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "не удалось идентифицировать столбец \"%s\" в типе записи" + +# skip-rule: space-before-period +#: parser/parse_expr.c:426 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "" +"запись имени столбца .%s применена к типу %s, который не является составным" + +#: parser/parse_expr.c:457 parser/parse_target.c:729 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "расширение строки через \"*\" здесь не поддерживается" + +#: parser/parse_expr.c:578 +msgid "cannot use column reference in DEFAULT expression" +msgstr "в выражении DEFAULT (по умолчанию) нельзя ссылаться на столбцы" + +#: parser/parse_expr.c:581 +msgid "cannot use column reference in partition bound expression" +msgstr "в выражении границы секции нельзя ссылаться на столбцы" + +#: parser/parse_expr.c:850 parser/parse_relation.c:799 +#: parser/parse_relation.c:881 parser/parse_target.c:1207 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "неоднозначная ссылка на столбец \"%s\"" + +#: parser/parse_expr.c:906 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:199 parser/parse_param.c:298 +#, c-format +msgid "there is no parameter $%d" +msgstr "параметр $%d не существует" + +#: parser/parse_expr.c:1149 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "для NULLIF требуется, чтобы оператор = возвращал логическое значение" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1155 parser/parse_expr.c:3135 +#, c-format +msgid "%s must not return a set" +msgstr "%s не должна возвращать множество" + +#: parser/parse_expr.c:1603 parser/parse_expr.c:1635 +#, c-format +msgid "number of columns does not match number of values" +msgstr "число столбцов не равно числу значений" + +#: parser/parse_expr.c:1649 +#, c-format +msgid "" +"source for a multiple-column UPDATE item must be a sub-SELECT or ROW() " +"expression" +msgstr "" +"источником для элемента UPDATE с несколькими столбцами должен быть вложенный " +"SELECT или выражение ROW()" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1843 parser/parse_expr.c:2330 parser/parse_func.c:2540 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "функции, возвращающие множества, нельзя применять в конструкции %s" + +#: parser/parse_expr.c:1904 +msgid "cannot use subquery in check constraint" +msgstr "в ограничении-проверке нельзя использовать подзапросы" + +#: parser/parse_expr.c:1908 +msgid "cannot use subquery in DEFAULT expression" +msgstr "в выражении DEFAULT нельзя использовать подзапросы" + +#: parser/parse_expr.c:1911 +msgid "cannot use subquery in index expression" +msgstr "в индексном выражении нельзя использовать подзапросы" + +#: parser/parse_expr.c:1914 +msgid "cannot use subquery in index predicate" +msgstr "в предикате индекса нельзя использовать подзапросы" + +#: parser/parse_expr.c:1917 +msgid "cannot use subquery in transform expression" +msgstr "нельзя использовать подзапрос в выражении преобразования" + +#: parser/parse_expr.c:1920 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "в качестве параметра EXECUTE нельзя использовать подзапрос" + +#: parser/parse_expr.c:1923 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "в условии WHEN для триггера нельзя использовать подзапросы" + +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in partition bound" +msgstr "в выражении границы секции нельзя использовать подзапросы" + +#: parser/parse_expr.c:1929 +msgid "cannot use subquery in partition key expression" +msgstr "в выражении ключа секционирования нельзя использовать подзапросы" + +#: parser/parse_expr.c:1932 +msgid "cannot use subquery in CALL argument" +msgstr "в качестве аргумента CALL нельзя использовать подзапрос" + +#: parser/parse_expr.c:1935 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "в условии COPY FROM WHERE нельзя использовать подзапросы" + +#: parser/parse_expr.c:1938 +msgid "cannot use subquery in column generation expression" +msgstr "в выражении генерируемого столбца нельзя использовать подзапросы" + +#: parser/parse_expr.c:1991 +#, c-format +msgid "subquery must return only one column" +msgstr "подзапрос должен вернуть только один столбец" + +#: parser/parse_expr.c:2075 +#, c-format +msgid "subquery has too many columns" +msgstr "в подзапросе слишком много столбцов" + +#: parser/parse_expr.c:2080 +#, c-format +msgid "subquery has too few columns" +msgstr "в подзапросе недостаточно столбцов" + +#: parser/parse_expr.c:2181 +#, c-format +msgid "cannot determine type of empty array" +msgstr "тип пустого массива определить нельзя" + +#: parser/parse_expr.c:2182 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "" +"Приведите его к желаемому типу явным образом, например ARRAY[]::integer[]." + +#: parser/parse_expr.c:2196 +#, c-format +msgid "could not find element type for data type %s" +msgstr "не удалось определить тип элемента для типа данных %s" + +#: parser/parse_expr.c:2481 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "вместо значения XML-атрибута без имени должен указываться столбец" + +#: parser/parse_expr.c:2482 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "вместо значения XML-элемента без имени должен указываться столбец" + +#: parser/parse_expr.c:2497 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "имя XML-атрибута \"%s\" указано неоднократно" + +#: parser/parse_expr.c:2604 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "привести результат XMLSERIALIZE к типу %s нельзя" + +#: parser/parse_expr.c:2892 parser/parse_expr.c:3088 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "разное число элементов в строках" + +#: parser/parse_expr.c:2902 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "строки нулевой длины сравнивать нельзя" + +#: parser/parse_expr.c:2927 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "" +"оператор сравнения строк должен выдавать результат логического типа, а не %s" + +#: parser/parse_expr.c:2934 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "оператор сравнения строк не должен возвращать множество" + +#: parser/parse_expr.c:2993 parser/parse_expr.c:3034 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "не удалось выбрать интерпретацию оператора сравнения строк %s" + +#: parser/parse_expr.c:2995 +#, c-format +msgid "" +"Row comparison operators must be associated with btree operator families." +msgstr "" +"Операторы сравнения строк должны быть связаны с семейством операторов btree." + +#: parser/parse_expr.c:3036 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Оказалось несколько равноценных кандидатур." + +#: parser/parse_expr.c:3129 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "" +"для IS DISTINCT FROM требуется, чтобы оператор = возвращал логическое " +"значение" + +#: parser/parse_expr.c:3448 parser/parse_expr.c:3466 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "" +"приоритет операторов изменён: %s теперь имеет меньший приоритет, чем %s" + +#: parser/parse_func.c:191 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "имя аргумента \"%s\" используется неоднократно" + +#: parser/parse_func.c:202 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "нумерованный аргумент не может следовать за именованным аргументом" + +#: parser/parse_func.c:284 parser/parse_func.c:2243 +#, c-format +msgid "%s is not a procedure" +msgstr "\"%s\" — не процедура" + +#: parser/parse_func.c:288 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Для вызова функции используйте SELECT." + +#: parser/parse_func.c:294 +#, c-format +msgid "%s is a procedure" +msgstr "%s — процедура" + +#: parser/parse_func.c:298 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Для вызова процедуры используйте CALL." + +#: parser/parse_func.c:312 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "выражение %s(*) недопустимо, так как %s - не агрегатная функция" + +#: parser/parse_func.c:319 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "в аргументах %s указан DISTINCT, но это не агрегатная функция" + +#: parser/parse_func.c:325 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "в аргументах %s указано WITHIN GROUP, но это не агрегатная функция" + +#: parser/parse_func.c:331 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "в аргументах %s указан ORDER BY, но это не агрегатная функция" + +#: parser/parse_func.c:337 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "в аргументах %s указан FILTER, но это не агрегатная функция" + +#: parser/parse_func.c:343 +#, c-format +msgid "" +"OVER specified, but %s is not a window function nor an aggregate function" +msgstr "" +"вызов %s включает предложение OVER, но это не оконная и не агрегатная функция" + +#: parser/parse_func.c:381 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "для сортирующего агрегата %s требуется WITHIN GROUP" + +#: parser/parse_func.c:387 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "сортирующий агрегат %s не поддерживает OVER" + +#: parser/parse_func.c:418 parser/parse_func.c:447 +#, c-format +msgid "" +"There is an ordered-set aggregate %s, but it requires %d direct arguments, " +"not %d." +msgstr "" +"Есть сортирующий агрегат %s, но прямых аргументов у него должно быть %d, а " +"не %d." + +#: parser/parse_func.c:472 +#, c-format +msgid "" +"To use the hypothetical-set aggregate %s, the number of hypothetical direct " +"arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "" +"Для использования гипотезирующего агрегата %s число непосредственных " +"гипотетических аргументов (%d) должно равняться числу сортируемых столбцов " +"(здесь: %d)." + +#: parser/parse_func.c:486 +#, c-format +msgid "" +"There is an ordered-set aggregate %s, but it requires at least %d direct " +"arguments." +msgstr "" +"Есть сортирующий агрегат %s, но он требует минимум %d непосредственных " +"аргументов." + +#: parser/parse_func.c:505 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s - не сортирующая агрегатная функция, WITHIN GROUP к ней неприменимо" + +#: parser/parse_func.c:518 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "для оконной функции %s требуется предложение OVER" + +#: parser/parse_func.c:525 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "для оконной функции %s неприменимо WITHIN GROUP" + +#: parser/parse_func.c:554 +#, c-format +msgid "procedure %s is not unique" +msgstr "процедура %s не уникальна" + +#: parser/parse_func.c:557 +#, c-format +msgid "" +"Could not choose a best candidate procedure. You might need to add explicit " +"type casts." +msgstr "" +"Не удалось выбрать лучшую кандидатуру процедуры. Возможно, вам следует " +"добавить явные приведения типов." + +#: parser/parse_func.c:563 +#, c-format +msgid "function %s is not unique" +msgstr "функция %s не уникальна" + +#: parser/parse_func.c:566 +#, c-format +msgid "" +"Could not choose a best candidate function. You might need to add explicit " +"type casts." +msgstr "" +"Не удалось выбрать лучшую кандидатуру функции. Возможно, вам следует " +"добавить явные приведения типов." + +#: parser/parse_func.c:605 +#, c-format +msgid "" +"No aggregate function matches the given name and argument types. Perhaps you " +"misplaced ORDER BY; ORDER BY must appear after all regular arguments of the " +"aggregate." +msgstr "" +"Агрегатная функция с данными именем и типами аргументов не найдена. " +"Возможно, неверно расположено предложение ORDER BY - оно должно следовать за " +"всеми обычными аргументами функции." + +#: parser/parse_func.c:613 parser/parse_func.c:2286 +#, c-format +msgid "procedure %s does not exist" +msgstr "процедура %s не существует" + +#: parser/parse_func.c:616 +#, c-format +msgid "" +"No procedure matches the given name and argument types. You might need to " +"add explicit type casts." +msgstr "" +"Процедура с данными именем и типами аргументов не найдена. Возможно, вам " +"следует добавить явные приведения типов." + +#: parser/parse_func.c:625 +#, c-format +msgid "" +"No function matches the given name and argument types. You might need to add " +"explicit type casts." +msgstr "" +"Функция с данными именем и типами аргументов не найдена. Возможно, вам " +"следует добавить явные приведения типов." + +#: parser/parse_func.c:727 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "параметр VARIADIC должен быть массивом" + +#: parser/parse_func.c:779 parser/parse_func.c:843 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "агрегатная функция без параметров должна вызываться так: %s(*)" + +#: parser/parse_func.c:786 +#, c-format +msgid "aggregates cannot return sets" +msgstr "агрегатные функции не могут возвращать множества" + +#: parser/parse_func.c:801 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "у агрегатных функций не может быть именованных аргументов" + +#: parser/parse_func.c:833 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "предложение DISTINCT для оконных функций не реализовано" + +#: parser/parse_func.c:853 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "агрегатное предложение ORDER BY для оконных функций не реализовано" + +#: parser/parse_func.c:862 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "предложение FILTER для не агрегатных оконных функций не реализовано" + +#: parser/parse_func.c:871 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "" +"вызовы оконных функций не могут включать вызовы функций, возвращающих " +"множества" + +#: parser/parse_func.c:879 +#, c-format +msgid "window functions cannot return sets" +msgstr "оконные функции не могут возвращать множества" + +#: parser/parse_func.c:2124 parser/parse_func.c:2315 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "не удалось найти функцию с именем \"%s\"" + +#: parser/parse_func.c:2138 parser/parse_func.c:2333 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "имя функции \"%s\" не уникально" + +#: parser/parse_func.c:2140 parser/parse_func.c:2335 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Задайте список аргументов для однозначного выбора функции." + +#: parser/parse_func.c:2184 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "процедуры допускают не более %d аргумента" +msgstr[1] "процедуры допускают не более %d аргументов" +msgstr[2] "процедуры допускают не более %d аргументов" + +#: parser/parse_func.c:2233 +#, c-format +msgid "%s is not a function" +msgstr "%s — не функция" + +#: parser/parse_func.c:2253 +#, c-format +msgid "function %s is not an aggregate" +msgstr "функция \"%s\" не является агрегатной" + +#: parser/parse_func.c:2281 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "не удалось найти процедуру с именем \"%s\"" + +#: parser/parse_func.c:2295 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "не удалось найти агрегат с именем \"%s\"" + +#: parser/parse_func.c:2300 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "агрегатная функция %s(*) не существует" + +#: parser/parse_func.c:2305 +#, c-format +msgid "aggregate %s does not exist" +msgstr "агрегатная функция %s не существует" + +#: parser/parse_func.c:2340 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "имя процедуры \"%s\" не уникально" + +#: parser/parse_func.c:2342 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Задайте список аргументов для однозначного выбора процедуры." + +#: parser/parse_func.c:2347 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "имя агрегатной функции \"%s\" не уникально" + +#: parser/parse_func.c:2349 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Задайте список аргументов для однозначного выбора агрегатной функции." + +#: parser/parse_func.c:2354 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "имя подпрограммы \"%s\" не уникально" + +#: parser/parse_func.c:2356 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Задайте список аргументов для однозначного выбора подпрограммы." + +#: parser/parse_func.c:2411 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "функции, возвращающие множества, нельзя применять в условиях JOIN" + +#: parser/parse_func.c:2432 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "функции, возвращающие множества, нельзя применять в выражениях политик" + +#: parser/parse_func.c:2448 +msgid "set-returning functions are not allowed in window definitions" +msgstr "функции, возвращающие множества, нельзя применять в определении окна" + +#: parser/parse_func.c:2486 +msgid "set-returning functions are not allowed in check constraints" +msgstr "" +"функции, возвращающие множества, нельзя применять в ограничениях-проверках" + +#: parser/parse_func.c:2490 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "функции, возвращающие множества, нельзя применять в выражениях DEFAULT" + +#: parser/parse_func.c:2493 +msgid "set-returning functions are not allowed in index expressions" +msgstr "" +"функции, возвращающие множества, нельзя применять в выражениях индексов" + +#: parser/parse_func.c:2496 +msgid "set-returning functions are not allowed in index predicates" +msgstr "" +"функции, возвращающие множества, нельзя применять в предикатах индексов" + +#: parser/parse_func.c:2499 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "" +"функции, возвращающие множества, нельзя применять в выражениях преобразований" + +#: parser/parse_func.c:2502 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "функции, возвращающие множества, нельзя применять в параметрах EXECUTE" + +#: parser/parse_func.c:2505 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "" +"функции, возвращающие множества, нельзя применять в условиях WHEN для " +"триггеров" + +#: parser/parse_func.c:2508 +msgid "set-returning functions are not allowed in partition bound" +msgstr "" +"функции, возвращающие множества, нельзя применять в выражении границы секции" + +#: parser/parse_func.c:2511 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "" +"функции, возвращающие множества, нельзя применять в выражениях ключа " +"секционирования" + +#: parser/parse_func.c:2514 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "функции, возвращающие множества, нельзя применять в аргументах CALL" + +#: parser/parse_func.c:2517 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "" +"функции, возвращающие множества, нельзя применять в условиях COPY FROM WHERE" + +#: parser/parse_func.c:2520 +msgid "" +"set-returning functions are not allowed in column generation expressions" +msgstr "" +"функции, возвращающие множества, нельзя применять в выражениях генерируемых " +"столбцов" + +#: parser/parse_node.c:86 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "допустимое число элементов в целевом списке ограничено %d" + +#: parser/parse_node.c:235 +#, c-format +msgid "cannot subscript type %s because it is not an array" +msgstr "тип %s - не массив и для него нельзя указать индекс элемента" + +#: parser/parse_node.c:340 parser/parse_node.c:377 +#, c-format +msgid "array subscript must have type integer" +msgstr "индекс элемента массива должен быть целочисленным" + +#: parser/parse_node.c:408 +#, c-format +msgid "array assignment requires type %s but expression is of type %s" +msgstr "" +"для присваивания массива требуется тип %s, однако выражение имеет тип %s" + +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:521 +#: utils/adt/regproc.c:705 +#, c-format +msgid "operator does not exist: %s" +msgstr "оператор не существует: %s" + +#: parser/parse_oper.c:224 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Используйте явный оператор сортировки или измените запрос." + +#: parser/parse_oper.c:480 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "оператору требуется приведение типов во время выполнения: %s" + +#: parser/parse_oper.c:716 +#, c-format +msgid "operator is not unique: %s" +msgstr "оператор не уникален: %s" + +#: parser/parse_oper.c:718 +#, c-format +msgid "" +"Could not choose a best candidate operator. You might need to add explicit " +"type casts." +msgstr "" +"Не удалось выбрать лучшую кандидатуру оператора. Возможно, вам следует " +"добавить явные приведения типов." + +#: parser/parse_oper.c:727 +#, c-format +msgid "" +"No operator matches the given name and argument type. You might need to add " +"an explicit type cast." +msgstr "" +"Оператор с данным именем и типом аргумента не найден. Возможно, вам следует " +"добавить явное приведение типа." + +#: parser/parse_oper.c:729 +#, c-format +msgid "" +"No operator matches the given name and argument types. You might need to add " +"explicit type casts." +msgstr "" +"Оператор с данными именем и типами аргументов не найден. Возможно, вам " +"следует добавить явные приведения типов." + +#: parser/parse_oper.c:790 parser/parse_oper.c:912 +#, c-format +msgid "operator is only a shell: %s" +msgstr "оператор \"%s\" - лишь оболочка" + +#: parser/parse_oper.c:900 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "для операторов ANY/ALL (с массивом) требуется массив справа" + +#: parser/parse_oper.c:942 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "" +"для операторов ANY/ALL (с массивом) требуется, чтобы оператор = возвращал " +"логическое значение" + +#: parser/parse_oper.c:947 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "" +"для операторов ANY/ALL (с массивом) требуется, чтобы оператор возвращал не " +"множество" + +#: parser/parse_param.c:216 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "для параметра $%d выведены несогласованные типы" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "ссылка на таблицу \"%s\" неоднозначна" + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "ссылка на таблицу %u неоднозначна" + +#: parser/parse_relation.c:444 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "имя таблицы \"%s\" указано больше одного раза" + +#: parser/parse_relation.c:473 parser/parse_relation.c:3446 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "в элементе предложения FROM неверная ссылка на таблицу \"%s\"" + +#: parser/parse_relation.c:477 parser/parse_relation.c:3451 +#, c-format +msgid "" +"There is an entry for table \"%s\", but it cannot be referenced from this " +"part of the query." +msgstr "" +"Таблица \"%s\" присутствует в запросе, но сослаться на неё из этой части " +"запроса нельзя." + +#: parser/parse_relation.c:479 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "Для ссылки LATERAL тип JOIN должен быть INNER или LEFT." + +#: parser/parse_relation.c:690 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "в ограничении-проверке указан недопустимый системный столбец \"%s\"" + +#: parser/parse_relation.c:699 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "" +"системный столбец \"%s\" нельзя использовать в выражении генерируемого " +"столбца" + +#: parser/parse_relation.c:1170 parser/parse_relation.c:1620 +#: parser/parse_relation.c:2262 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "в таблице \"%s\" содержится столбцов: %d, но указано: %d" + +#: parser/parse_relation.c:1372 +#, c-format +msgid "" +"There is a WITH item named \"%s\", but it cannot be referenced from this " +"part of the query." +msgstr "" +"В WITH есть элемент \"%s\", но на него нельзя ссылаться из этой части " +"запроса." + +#: parser/parse_relation.c:1374 +#, c-format +msgid "" +"Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "" +"Используйте WITH RECURSIVE или исключите ссылки вперёд, переупорядочив " +"элементы WITH." + +#: parser/parse_relation.c:1747 +#, c-format +msgid "" +"a column definition list is only allowed for functions returning \"record\"" +msgstr "" +"список с определением столбцов может быть только у функций, возвращающих " +"запись" + +#: parser/parse_relation.c:1756 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "" +"у функций, возвращающих запись, должен быть список с определением столбцов" + +#: parser/parse_relation.c:1845 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "" +"функция \"%s\", используемая во FROM, возвращает неподдерживаемый тип %s" + +#: parser/parse_relation.c:2054 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "в списках VALUES \"%s\" содержится столбцов: %d, но указано: %d" + +#: parser/parse_relation.c:2125 +#, c-format +msgid "joins can have at most %d columns" +msgstr "число столбцов в соединениях ограничено %d" + +#: parser/parse_relation.c:2235 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "в запросе \"%s\" в WITH нет предложения RETURNING" + +#: parser/parse_relation.c:3221 parser/parse_relation.c:3231 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "столбец %d отношения \"%s\" не существует" + +#: parser/parse_relation.c:3449 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Возможно, предполагалась ссылка на псевдоним таблицы \"%s\"." + +#: parser/parse_relation.c:3457 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "таблица \"%s\" отсутствует в предложении FROM" + +#: parser/parse_relation.c:3509 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Возможно, предполагалась ссылка на столбец \"%s.%s\"." + +#: parser/parse_relation.c:3511 +#, c-format +msgid "" +"There is a column named \"%s\" in table \"%s\", but it cannot be referenced " +"from this part of the query." +msgstr "" +"Столбец \"%s\" есть в таблице \"%s\", но на него нельзя ссылаться из этой " +"части запроса." + +#: parser/parse_relation.c:3528 +#, c-format +msgid "" +"Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "" +"Возможно, предполагалась ссылка на столбец \"%s.%s\" или столбец \"%s.%s\"." + +#: parser/parse_target.c:478 parser/parse_target.c:792 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "присвоить значение системному столбцу \"%s\" нельзя" + +#: parser/parse_target.c:506 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "элементу массива нельзя присвоить значение по умолчанию" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "вложенному полю нельзя присвоить значение по умолчанию" + +#: parser/parse_target.c:584 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "столбец \"%s\" имеет тип %s, а выражение - %s" + +#: parser/parse_target.c:776 +#, c-format +msgid "" +"cannot assign to field \"%s\" of column \"%s\" because its type %s is not a " +"composite type" +msgstr "" +"присвоить значение полю \"%s\" столбца \"%s\" нельзя, так как тип %s не " +"является составным" + +#: parser/parse_target.c:785 +#, c-format +msgid "" +"cannot assign to field \"%s\" of column \"%s\" because there is no such " +"column in data type %s" +msgstr "" +"присвоить значение полю \"%s\" столбца \"%s\" нельзя, так как в типе данных " +"%s нет такого столбца" + +#: parser/parse_target.c:864 +#, c-format +msgid "" +"array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "" +"для присваивания массива полю \"%s\" требуется тип %s, однако выражение " +"имеет тип %s" + +#: parser/parse_target.c:874 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "вложенное поле \"%s\" имеет тип %s, а выражение - %s" + +#: parser/parse_target.c:1295 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "SELECT * должен ссылаться на таблицы" + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "неправильное указание %%TYPE (слишком мало компонентов): %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "неправильное указание %%TYPE (слишком много компонентов): %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "ссылка на тип %s преобразована в тип %s" + +#: parser/parse_type.c:278 parser/parse_type.c:857 utils/cache/typcache.c:383 +#: utils/cache/typcache.c:437 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "тип \"%s\" - лишь пустышка" + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "у типа \"%s\" не может быть модификаторов" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "модификатором типа должна быть простая константа или идентификатор" + +#: parser/parse_type.c:721 parser/parse_type.c:820 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "неверное имя типа \"%s\"" + +#: parser/parse_utilcmd.c:266 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "создать секционированную таблицу в виде потомка нельзя" + +#: parser/parse_utilcmd.c:444 +#, c-format +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s создаст последовательность \"%s\" для столбца serial \"%s.%s\"" + +#: parser/parse_utilcmd.c:575 +#, c-format +msgid "array of serial is not implemented" +msgstr "массивы с типом serial не реализованы" + +#: parser/parse_utilcmd.c:653 parser/parse_utilcmd.c:665 +#, c-format +msgid "" +"conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "конфликт NULL/NOT NULL в объявлении столбца \"%s\" таблицы \"%s\"" + +#: parser/parse_utilcmd.c:677 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "" +"для столбца \"%s\" таблицы \"%s\" указано несколько значений по умолчанию" + +#: parser/parse_utilcmd.c:694 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "столбцы идентификации не поддерживаются с типизированными таблицами" + +#: parser/parse_utilcmd.c:698 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "столбцы идентификации не поддерживаются с секциями" + +#: parser/parse_utilcmd.c:707 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "" +"для столбца \"%s\" таблицы \"%s\" свойство identity задано неоднократно" + +#: parser/parse_utilcmd.c:727 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "генерируемые столбцы не поддерживаются с типизированными таблицами" + +#: parser/parse_utilcmd.c:731 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "генерируемые столбцы не поддерживаются с секциями" + +#: parser/parse_utilcmd.c:736 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "" +"для столбца \"%s\" таблицы \"%s\" указано несколько генерирующих выражений" + +#: parser/parse_utilcmd.c:754 parser/parse_utilcmd.c:869 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "ограничения первичного ключа для сторонних таблиц не поддерживаются" + +#: parser/parse_utilcmd.c:763 parser/parse_utilcmd.c:879 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "ограничения уникальности для сторонних таблиц не поддерживаются" + +#: parser/parse_utilcmd.c:808 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "" +"для столбца \"%s\" таблицы \"%s\" задано и значение по умолчанию, и свойство " +"identity" + +#: parser/parse_utilcmd.c:816 +#, c-format +msgid "" +"both default and generation expression specified for column \"%s\" of table " +"\"%s\"" +msgstr "" +"для столбца \"%s\" таблицы \"%s\" задано и значение по умолчанию, и " +"генерирующее выражение" + +#: parser/parse_utilcmd.c:824 +#, c-format +msgid "" +"both identity and generation expression specified for column \"%s\" of table " +"\"%s\"" +msgstr "" +"для столбца \"%s\" таблицы \"%s\" задано и генерирующее выражение, и " +"свойство identity" + +#: parser/parse_utilcmd.c:889 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "ограничения-исключения для сторонних таблиц не поддерживаются" + +#: parser/parse_utilcmd.c:895 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "ограничения-исключения для секционированных таблиц не поддерживаются" + +#: parser/parse_utilcmd.c:960 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "LIKE при создании сторонних таблиц не поддерживается" + +#: parser/parse_utilcmd.c:1728 parser/parse_utilcmd.c:1837 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "Индекс \"%s\" ссылается на тип всей строки таблицы." + +#: parser/parse_utilcmd.c:2187 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "в CREATE TABLE нельзя использовать существующий индекс" + +#: parser/parse_utilcmd.c:2207 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "индекс \"%s\" уже связан с ограничением" + +#: parser/parse_utilcmd.c:2222 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "индекс \"%s\" - нерабочий" + +#: parser/parse_utilcmd.c:2228 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "\"%s\" не является уникальным индексом" + +#: parser/parse_utilcmd.c:2229 parser/parse_utilcmd.c:2236 +#: parser/parse_utilcmd.c:2243 parser/parse_utilcmd.c:2320 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "" +"Создать первичный ключ или ограничение уникальности для такого индекса " +"нельзя." + +#: parser/parse_utilcmd.c:2235 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "индекс \"%s\" содержит выражения" + +#: parser/parse_utilcmd.c:2242 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "\"%s\" - частичный индекс" + +#: parser/parse_utilcmd.c:2254 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\" - откладываемый индекс" + +#: parser/parse_utilcmd.c:2255 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "" +"Создать не откладываемое ограничение на базе откладываемого индекса нельзя." + +#: parser/parse_utilcmd.c:2319 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "" +"в индексе \"%s\" для столбца номер %d не определено поведение сортировки по " +"умолчанию" + +#: parser/parse_utilcmd.c:2476 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "столбец \"%s\" фигурирует в первичном ключе дважды" + +#: parser/parse_utilcmd.c:2482 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "столбец \"%s\" фигурирует в ограничении уникальности дважды" + +#: parser/parse_utilcmd.c:2835 +#, c-format +msgid "" +"index expressions and predicates can refer only to the table being indexed" +msgstr "" +"индексные выражения и предикаты могут ссылаться только на индексируемую " +"таблицу" + +#: parser/parse_utilcmd.c:2881 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "правила для материализованных представлений не поддерживаются" + +#: parser/parse_utilcmd.c:2944 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "в условиях WHERE для правил нельзя ссылаться на другие отношения" + +#: parser/parse_utilcmd.c:3018 +#, c-format +msgid "" +"rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE " +"actions" +msgstr "" +"правила с условиями WHERE могут содержать только действия SELECT, INSERT, " +"UPDATE или DELETE" + +#: parser/parse_utilcmd.c:3036 parser/parse_utilcmd.c:3137 +#: rewrite/rewriteHandler.c:503 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "условные операторы UNION/INTERSECT/EXCEPT не реализованы" + +#: parser/parse_utilcmd.c:3054 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "в правиле ON SELECT нельзя использовать OLD" + +#: parser/parse_utilcmd.c:3058 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "в правиле ON SELECT нельзя использовать NEW" + +#: parser/parse_utilcmd.c:3067 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "в правиле ON INSERT нельзя использовать OLD" + +#: parser/parse_utilcmd.c:3073 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "в правиле ON DELETE нельзя использовать NEW" + +#: parser/parse_utilcmd.c:3101 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "в запросе WITH нельзя ссылаться на OLD" + +#: parser/parse_utilcmd.c:3108 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "в запросе WITH нельзя ссылаться на NEW" + +#: parser/parse_utilcmd.c:3567 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "предложение DEFERRABLE расположено неправильно" + +#: parser/parse_utilcmd.c:3572 parser/parse_utilcmd.c:3587 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "DEFERRABLE/NOT DEFERRABLE можно указать только один раз" + +#: parser/parse_utilcmd.c:3582 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "предложение NOT DEFERRABLE расположено неправильно" + +#: parser/parse_utilcmd.c:3595 parser/parse_utilcmd.c:3621 gram.y:5594 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "" +"ограничение с характеристикой INITIALLY DEFERRED должно быть объявлено как " +"DEFERRABLE" + +#: parser/parse_utilcmd.c:3603 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "предложение INITIALLY DEFERRED расположено неправильно" + +#: parser/parse_utilcmd.c:3608 parser/parse_utilcmd.c:3634 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "INITIALLY IMMEDIATE/DEFERRED можно указать только один раз" + +#: parser/parse_utilcmd.c:3629 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "предложение INITIALLY IMMEDIATE расположено неправильно" + +#: parser/parse_utilcmd.c:3820 +#, c-format +msgid "" +"CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "в CREATE указана схема (%s), отличная от создаваемой (%s)" + +#: parser/parse_utilcmd.c:3855 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "\"%s\" — не секционированная таблица" + +#: parser/parse_utilcmd.c:3862 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "таблица \"%s\" не является секционированной" + +#: parser/parse_utilcmd.c:3869 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "индекс \"%s\" не секционирован" + +#: parser/parse_utilcmd.c:3909 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "у секционированной по хешу таблицы не может быть секции по умолчанию" + +#: parser/parse_utilcmd.c:3926 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "неправильное указание ограничения для хеш-секции" + +#: parser/parse_utilcmd.c:3932 partitioning/partbounds.c:4640 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "модуль для хеш-секции должен быть положительным целым" + +#: parser/parse_utilcmd.c:3939 partitioning/partbounds.c:4648 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "остаток для хеш-секции должен быть меньше модуля" + +#: parser/parse_utilcmd.c:3952 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "неправильное указание ограничения для секции по списку" + +#: parser/parse_utilcmd.c:4005 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "неправильное указание ограничения для секции по диапазону" + +#: parser/parse_utilcmd.c:4011 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "" +"во FROM должно указываться ровно одно значение для секционирующего столбца" + +#: parser/parse_utilcmd.c:4015 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "" +"в TO должно указываться ровно одно значение для секционирующего столбца" + +#: parser/parse_utilcmd.c:4129 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "указать NULL в диапазонном ограничении нельзя" + +#: parser/parse_utilcmd.c:4178 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "за границей MAXVALUE могут следовать только границы MAXVALUE" + +#: parser/parse_utilcmd.c:4185 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "за границей MINVALUE могут следовать только границы MINVALUE" + +#: parser/parse_utilcmd.c:4227 +#, c-format +msgid "" +"could not determine which collation to use for partition bound expression" +msgstr "не удалось определить правило сортировки для выражения границы секции" + +#: parser/parse_utilcmd.c:4244 +#, c-format +msgid "" +"collation of partition bound value for column \"%s\" does not match " +"partition key collation \"%s\"" +msgstr "" +"правило сортировки для выражения границы секции в столбце \"%s\" не " +"соответствует правилу сортировки для ключа секционирования \"%s\"" + +#: parser/parse_utilcmd.c:4261 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "указанное значение нельзя привести к типу %s столбца \"%s\"" + +#: parser/parser.c:228 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "За UESCAPE должна следовать простая строковая константа" + +#: parser/parser.c:233 +msgid "invalid Unicode escape character" +msgstr "неверный символ спецкода Unicode" + +#: parser/parser.c:302 scan.l:1329 +#, c-format +msgid "invalid Unicode escape value" +msgstr "неверное значение спецкода Unicode" + +#: parser/parser.c:449 scan.l:677 +#, c-format +msgid "invalid Unicode escape" +msgstr "неверный спецкод Unicode" + +#: parser/parser.c:450 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "Спецкоды Unicode должны иметь вид \\XXXX или \\+XXXXXX." + +#: parser/parser.c:478 scan.l:638 scan.l:654 scan.l:670 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "неверная суррогатная пара Unicode" + +#: parser/scansup.c:203 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%s\"" +msgstr "идентификатор \"%s\" будет усечён до \"%s\"" + +#: partitioning/partbounds.c:2821 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "секция \"%s\" конфликтует с существующей секцией по умолчанию \"%s\"" + +#: partitioning/partbounds.c:2880 +#, c-format +msgid "" +"every hash partition modulus must be a factor of the next larger modulus" +msgstr "" +"модуль каждой хеш-секции должен быть делителем модулей, превышающих его" + +#: partitioning/partbounds.c:2976 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "для секции \"%s\" заданы границы, образующие пустой диапазон" + +#: partitioning/partbounds.c:2978 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Указанная нижняя граница %s больше или равна верхней границе %s." + +#: partitioning/partbounds.c:3075 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "секция \"%s\" пересекается с секцией \"%s\"" + +#: partitioning/partbounds.c:3192 +#, c-format +msgid "" +"skipped scanning foreign table \"%s\" which is a partition of default " +"partition \"%s\"" +msgstr "" +"пропущено сканирование сторонней таблицы \"%s\", являющейся секцией секции " +"по умолчанию \"%s\"" + +#: partitioning/partbounds.c:4644 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "остаток для хеш-секции должен быть неотрицательным целым" + +#: partitioning/partbounds.c:4668 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" не является таблицей, секционированной по хешу" + +#: partitioning/partbounds.c:4679 partitioning/partbounds.c:4796 +#, c-format +msgid "" +"number of partitioning columns (%d) does not match number of partition keys " +"provided (%d)" +msgstr "" +"число секционирующих столбцов (%d) не равно числу представленных ключей " +"секционирования (%d)" + +#: partitioning/partbounds.c:4701 partitioning/partbounds.c:4733 +#, c-format +msgid "" +"column %d of the partition key has type \"%s\", but supplied value is of " +"type \"%s\"" +msgstr "" +"столбец %d ключа секционирования имеет тип \"%s\", но для него передано " +"значение типа \"%s\"" + +#: port/pg_sema.c:209 port/pg_shmem.c:640 port/posix_sema.c:209 +#: port/sysv_sema.c:327 port/sysv_shmem.c:640 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "не удалось получить информацию о каталоге данных \"%s\": %m" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "не удалось создать сегмент разделяемой памяти: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "Ошибка в системном вызове shmget(ключ=%lu, размер=%zu, 0%o)." + +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory " +"segment exceeded your kernel's SHMMAX parameter, or possibly that it is less " +"than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory " +"configuration." +msgstr "" +"Эта ошибка обычно возникает, когда PostgreSQL запрашивает сегмент " +"разделяемой памяти, выходя за пределы параметров ядра SHMMIN и SHMMAX.\n" +"Подробная информация о настройке разделяемой памяти содержится в " +"документации PostgreSQL." + +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory " +"segment exceeded your kernel's SHMALL parameter. You might need to " +"reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory " +"configuration." +msgstr "" +"Эта ошибка обычно возникает, когда PostgreSQL запрашивает сегмент " +"разделяемой памяти, превышая предел SHMALL, заданный в ядре. Возможно, вам " +"следует увеличить SHMALL в конфигурации ядра.\n" +"Подробная информация о настройке разделяемой памяти содержится в " +"документации PostgreSQL." + +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs " +"either if all available shared memory IDs have been taken, in which case you " +"need to raise the SHMMNI parameter in your kernel, or because the system's " +"overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory " +"configuration." +msgstr "" +"Эта ошибка НЕ означает, что на диске нет места. Вероятнее всего, были заняты " +"все доступные ID разделяемой памяти (в этом случае вам надо увеличить " +"параметр SHMMNI в ядре), либо превышен предельный размер разделяемой " +"памяти.\n" +"Подробная информация о настройке разделяемой памяти содержится в " +"документации PostgreSQL." + +#: port/pg_shmem.c:578 port/sysv_shmem.c:578 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "не удалось получить анонимную разделяемую память: %m" + +#: port/pg_shmem.c:580 port/sysv_shmem.c:580 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory " +"segment exceeded available memory, swap space, or huge pages. To reduce the " +"request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, " +"perhaps by reducing shared_buffers or max_connections." +msgstr "" +"Эта ошибка обычно возникает, когда PostgreSQL запрашивает сегмент " +"разделяемой памяти, превышая объём доступной физической либо виртуальной " +"памяти или гигантских страниц. Для уменьшения запроса (текущий размер: %zu " +"Б) можно снизить использование разделяемой памяти, возможно, уменьшив " +"shared_buffers или max_connections." + +#: port/pg_shmem.c:648 port/sysv_shmem.c:648 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "гигантские страницы на этой платформе не поддерживаются" + +#: port/pg_shmem.c:709 port/sysv_shmem.c:709 utils/init/miscinit.c:1137 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "" +"ранее выделенный блок разделяемой памяти (ключ %lu, ID %lu) по-прежнему " +"используется" + +#: port/pg_shmem.c:712 port/sysv_shmem.c:712 utils/init/miscinit.c:1139 +#, c-format +msgid "" +"Terminate any old server processes associated with data directory \"%s\"." +msgstr "" +"Завершите все старые серверные процессы, работающие с каталогом данных \"%s" +"\"." + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "не удалось создать семафоры: %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "Ошибка в системном вызове semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:129 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs " +"when either the system limit for the maximum number of semaphore sets " +"(SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be " +"exceeded. You need to raise the respective kernel parameter. " +"Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its " +"max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring " +"your system for PostgreSQL." +msgstr "" +"Эта ошибка НЕ означает, что на диске нет места. Вероятнее всего, превышен " +"предел числа установленных семафоров (SEMMNI), либо общего числа семафоров " +"(SEMMNS) в системе. Увеличьте соответствующий параметр ядра или уменьшите " +"потребность PostgreSQL в семафорах, уменьшив его параметр max_connections.\n" +"Подробная информация о настройке разделяемой памяти содержится в " +"документации PostgreSQL." + +#: port/sysv_sema.c:159 +#, c-format +msgid "" +"You possibly need to raise your kernel's SEMVMX value to be at least %d. " +"Look into the PostgreSQL documentation for details." +msgstr "" +"Возможно, вам следует увеличить параметр ядра SEMVMX минимум до %d. " +"Подробнее об этом написано в документации PostgreSQL." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "не удалось загрузить dbghelp.dll, сохранить аварийный дамп нельзя\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "" +"could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "" +"не удалось найти требуемые функции в dbghelp.dll, сохранить аварийный дамп " +"нельзя\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "не удалось открыть файл дампа \"%s\" для записи (код ошибки: %lu)\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "аварийный дамп записан в файл\"%s\"\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "не удалось записать аварийный дамп в файл \"%s\" (код ошибки: %lu)\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "" +"не удалось создать канал приёма сигналов для процесса с PID %d (код ошибки: " +"%lu)" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "" +"не удалось создать канал приёма сигналов (код ошибки: %lu); ещё одна " +"попытка...\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "не удалось создать семафор (код ошибки: %lu)" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "не удалось заблокировать семафор (код ошибки: %lu)" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "не удалось разблокировать семафор (код ошибки: %lu)" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "не удалось попытаться заблокировать семафор (код ошибки: %lu)" + +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "" +"не удалось активировать право пользователя на блокировку страниц в памяти: " +"код ошибки %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "Ошибка в системном вызове %s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "" +"не удалось активировать право пользователя на блокировку страниц в памяти" + +#: port/win32_shmem.c:176 +#, c-format +msgid "" +"Assign Lock Pages in Memory user right to the Windows user account which " +"runs PostgreSQL." +msgstr "" +"Назначьте право \"Блокировка страниц в памяти\" учётной записи пользователя, " +"используемой для запуска PostgreSQL." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "процессор не поддерживает большие страницы" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "отключение огромных страниц" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "не удалось создать сегмент разделяемой памяти (код ошибки: %lu)" + +#: port/win32_shmem.c:303 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "Ошибка в системном вызове CreateFileMapping (размер=%zu, имя=%s)." + +#: port/win32_shmem.c:328 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "ранее созданный блок разделяемой памяти всё ещё используется" + +#: port/win32_shmem.c:329 +#, c-format +msgid "" +"Check if there are any old server processes still running, and terminate " +"them." +msgstr "" +"Если по-прежнему работают какие-то старые серверные процессы, снимите их." + +#: port/win32_shmem.c:339 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "Ошибка в системном вызове DuplicateHandle." + +#: port/win32_shmem.c:357 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "Ошибка в системном вызове MapViewOfFileEx." + +#: postmaster/autovacuum.c:406 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "породить процесс запуска автоочистки не удалось: %m" + +#: postmaster/autovacuum.c:442 +#, c-format +msgid "autovacuum launcher started" +msgstr "процесс запуска автоочистки создан" + +#: postmaster/autovacuum.c:839 +#, c-format +msgid "autovacuum launcher shutting down" +msgstr "процесс запуска автоочистки завершается" + +#: postmaster/autovacuum.c:1477 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "не удалось породить рабочий процесс автоочистки: %m" + +#: postmaster/autovacuum.c:1686 +#, c-format +msgid "autovacuum: processing database \"%s\"" +msgstr "автоочистка: обработка базы данных \"%s\"" + +# skip-rule: capital-letter-first +#: postmaster/autovacuum.c:2256 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "автоочистка: удаление устаревшей врем. таблицы \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2485 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "автоматическая очистка таблицы \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2488 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "автоматический анализ таблицы \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2681 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "обработка рабочей записи для отношения \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:3285 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "автоочистка не запущена из-за неправильной конфигурации" + +#: postmaster/autovacuum.c:3286 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "Включите параметр \"track_counts\"." + +#: postmaster/bgworker.c:405 postmaster/bgworker.c:900 +#, c-format +msgid "registering background worker \"%s\"" +msgstr "регистрация фонового процесса \"%s\"" + +#: postmaster/bgworker.c:437 +#, c-format +msgid "unregistering background worker \"%s\"" +msgstr "разрегистрация фонового процесса \"%s\"" + +#: postmaster/bgworker.c:650 +#, c-format +msgid "" +"background worker \"%s\": must attach to shared memory in order to request a " +"database connection" +msgstr "" +"фоновый процесс \"%s\" должен иметь доступ к общей памяти, чтобы запросить " +"подключение к БД" + +#: postmaster/bgworker.c:659 +#, c-format +msgid "" +"background worker \"%s\": cannot request database access if starting at " +"postmaster start" +msgstr "" +"фоновый процесс \"%s\" не может получить доступ к БД, если он запущен при " +"старте главного процесса" + +#: postmaster/bgworker.c:673 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "фоновый процесс \"%s\": неправильный интервал перезапуска" + +#: postmaster/bgworker.c:688 +#, c-format +msgid "" +"background worker \"%s\": parallel workers may not be configured for restart" +msgstr "" +"фоновый процесс \"%s\": параллельные исполнители не могут быть настроены для " +"перезапуска" + +#: postmaster/bgworker.c:712 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "завершение фонового процесса \"%s\" по команде администратора" + +#: postmaster/bgworker.c:908 +#, c-format +msgid "" +"background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "" +"фоновой процесс \"%s\" должен быть зарегистрирован в shared_preload_libraries" + +#: postmaster/bgworker.c:920 +#, c-format +msgid "" +"background worker \"%s\": only dynamic background workers can request " +"notification" +msgstr "" +"фоновый процесс \"%s\": только динамические фоновые процессы могут " +"запрашивать уведомление" + +#: postmaster/bgworker.c:935 +#, c-format +msgid "too many background workers" +msgstr "слишком много фоновых процессов" + +#: postmaster/bgworker.c:936 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "" +"Up to %d background workers can be registered with the current settings." +msgstr[0] "" +"Максимально возможное число фоновых процессов при текущих параметрах: %d." +msgstr[1] "" +"Максимально возможное число фоновых процессов при текущих параметрах: %d." +msgstr[2] "" +"Максимально возможное число фоновых процессов при текущих параметрах: %d." + +#: postmaster/bgworker.c:940 +#, c-format +msgid "" +"Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "Возможно, стоит увеличить параметр \"max_worker_processes\"." + +#: postmaster/checkpointer.c:418 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "контрольные точки происходят слишком часто (через %d сек.)" +msgstr[1] "контрольные точки происходят слишком часто (через %d сек.)" +msgstr[2] "контрольные точки происходят слишком часто (через %d сек.)" + +#: postmaster/checkpointer.c:422 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "Возможно, стоит увеличить параметр \"max_wal_size\"." + +#: postmaster/checkpointer.c:1032 +#, c-format +msgid "checkpoint request failed" +msgstr "сбой при запросе контрольной точки" + +#: postmaster/checkpointer.c:1033 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "Смотрите подробности в протоколе сервера." + +#: postmaster/checkpointer.c:1217 +#, c-format +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "очередь запросов fsync сжата (было записей: %d, стало: %d)" + +#: postmaster/pgarch.c:155 +#, c-format +msgid "could not fork archiver: %m" +msgstr "не удалось породить процесс архивации: %m" + +#: postmaster/pgarch.c:425 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "режим архивации включён, но команда архивации не задана" + +#: postmaster/pgarch.c:447 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "удалён ненужный файл состояния архива \"%s\"" + +#: postmaster/pgarch.c:457 +#, c-format +msgid "" +"removal of orphan archive status file \"%s\" failed too many times, will try " +"again later" +msgstr "" +"удалить ненужный файл состояния архива \"%s\" не получилось много раз " +"подряд; следующая попытка будет сделана позже" + +#: postmaster/pgarch.c:493 +#, c-format +msgid "" +"archiving write-ahead log file \"%s\" failed too many times, will try again " +"later" +msgstr "" +"заархивировать файл журнала предзаписи \"%s\" не удалось много раз подряд; " +"следующая попытка будет сделана позже" + +#: postmaster/pgarch.c:594 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "команда архивации завершилась ошибкой с кодом %d" + +#: postmaster/pgarch.c:596 postmaster/pgarch.c:606 postmaster/pgarch.c:612 +#: postmaster/pgarch.c:621 +#, c-format +msgid "The failed archive command was: %s" +msgstr "Команда архивации с ошибкой: %s" + +#: postmaster/pgarch.c:603 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "команда архивации была прервана исключением 0x%X" + +#: postmaster/pgarch.c:605 postmaster/postmaster.c:3725 +#, c-format +msgid "" +"See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "" +"Описание этого шестнадцатеричного значения ищите во включаемом C-файле " +"\"ntstatus.h\"" + +#: postmaster/pgarch.c:610 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "команда архивации завершена по сигналу %d: %s" + +#: postmaster/pgarch.c:619 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "команда архивации завершилась с неизвестным кодом состояния %d" + +#: postmaster/pgstat.c:419 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "не удалось разрешить \"localhost\": %s" + +#: postmaster/pgstat.c:442 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "проба другого адреса для сборщика статистики" + +#: postmaster/pgstat.c:451 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "не удалось создать сокет для сборщика статистики: %m" + +#: postmaster/pgstat.c:463 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "не удалось привязаться к сокету для сборщика статистики: %m" + +#: postmaster/pgstat.c:474 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "не удалось получить адрес сокета для сборщика статистики: %m" + +#: postmaster/pgstat.c:490 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "не удалось подключить сокет для сборщика статистики: %m" + +#: postmaster/pgstat.c:511 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "" +"не удалось послать тестовое сообщение в сокет для сборщика статистики: %m" + +#: postmaster/pgstat.c:537 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "сбой select() в сборщике статистики: %m" + +#: postmaster/pgstat.c:552 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "тестовое сообщение не прошло через сокет для сборщика статистики" + +#: postmaster/pgstat.c:567 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "" +"тестовое сообщение через сокет для сборщика статистики получить не удалось: " +"%m" + +#: postmaster/pgstat.c:577 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "тестовое сообщение через сокет для сборщика статистики прошло неверно" + +#: postmaster/pgstat.c:600 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "" +"не удалось переключить сокет сборщика статистики в неблокирующий режим: %m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "сборщик статистики отключается из-за нехватки рабочего сокета" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "не удалось породить процесс сборщика статистики: %m" + +#: postmaster/pgstat.c:1376 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "запрошен сброс неизвестного счётчика: \"%s\"" + +#: postmaster/pgstat.c:1377 +#, c-format +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "Допустимый счётчик: \"archiver\" или \"bgwriter\"." + +#: postmaster/pgstat.c:4567 +#, c-format +msgid "could not read statistics message: %m" +msgstr "не удалось прочитать сообщение статистики: %m" + +#: postmaster/pgstat.c:4889 postmaster/pgstat.c:5052 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "не удалось открыть временный файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:4962 postmaster/pgstat.c:5097 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "не удалось записать во временный файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:4971 postmaster/pgstat.c:5106 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "не удалось закрыть временный файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:4979 postmaster/pgstat.c:5114 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "" +"не удалось переименовать временный файл статистики из \"%s\" в \"%s\": %m" + +#: postmaster/pgstat.c:5211 postmaster/pgstat.c:5428 postmaster/pgstat.c:5582 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "не удалось открыть файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:5223 postmaster/pgstat.c:5233 postmaster/pgstat.c:5254 +#: postmaster/pgstat.c:5265 postmaster/pgstat.c:5287 postmaster/pgstat.c:5302 +#: postmaster/pgstat.c:5365 postmaster/pgstat.c:5440 postmaster/pgstat.c:5460 +#: postmaster/pgstat.c:5478 postmaster/pgstat.c:5494 postmaster/pgstat.c:5512 +#: postmaster/pgstat.c:5528 postmaster/pgstat.c:5594 postmaster/pgstat.c:5606 +#: postmaster/pgstat.c:5618 postmaster/pgstat.c:5629 postmaster/pgstat.c:5654 +#: postmaster/pgstat.c:5676 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "файл статистики \"%s\" испорчен" + +#: postmaster/pgstat.c:5805 +#, c-format +msgid "" +"using stale statistics instead of current ones because stats collector is " +"not responding" +msgstr "" +"используется просроченная статистика вместо текущей, так как сборщик " +"статистики не отвечает" + +#: postmaster/pgstat.c:6135 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "таблица хеша базы данных испорчена при очистке --- прерывание" + +#: postmaster/postmaster.c:733 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: неверный аргумент для параметра -f: \"%s\"\n" + +#: postmaster/postmaster.c:819 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: неверный аргумент для параметра -t: \"%s\"\n" + +#: postmaster/postmaster.c:870 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: неверный аргумент: \"%s\"\n" + +#: postmaster/postmaster.c:912 +#, c-format +msgid "" +"%s: superuser_reserved_connections (%d) must be less than max_connections " +"(%d)\n" +msgstr "" +"%s: значение superuser_reserved_connections (%d) должно быть меньше " +"max_connections (%d)\n" + +#: postmaster/postmaster.c:919 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "Архивацию WAL нельзя включить, если установлен wal_level \"minimal\"" + +#: postmaster/postmaster.c:922 +#, c-format +msgid "" +"WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or " +"\"logical\"" +msgstr "" +"Для потоковой трансляции WAL (max_wal_senders > 0) wal_level должен быть " +"\"replica\" или \"logical\"" + +#: postmaster/postmaster.c:930 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: ошибка в таблицах маркеров времени, требуется исправление\n" + +#: postmaster/postmaster.c:1047 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "не удалось создать порт завершения ввода/вывода для очереди потомков" + +#: postmaster/postmaster.c:1113 +#, c-format +msgid "ending log output to stderr" +msgstr "завершение вывода в stderr" + +#: postmaster/postmaster.c:1114 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "В дальнейшем протокол будет выводиться в \"%s\"." + +#: postmaster/postmaster.c:1125 +#, c-format +msgid "starting %s" +msgstr "запускается %s" + +#: postmaster/postmaster.c:1154 postmaster/postmaster.c:1252 +#: utils/init/miscinit.c:1597 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "неверный формат списка в параметре \"%s\"" + +#: postmaster/postmaster.c:1185 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "не удалось создать принимающий сокет для \"%s\"" + +#: postmaster/postmaster.c:1191 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "не удалось создать сокеты TCP/IP" + +#: postmaster/postmaster.c:1274 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "не удалось создать Unix-сокет в каталоге \"%s\"" + +#: postmaster/postmaster.c:1280 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "ни один Unix-сокет создать не удалось" + +#: postmaster/postmaster.c:1292 +#, c-format +msgid "no socket created for listening" +msgstr "отсутствуют принимающие сокеты" + +#: postmaster/postmaster.c:1323 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: не удалось поменять права для внешнего файла PID \"%s\": %s\n" + +#: postmaster/postmaster.c:1327 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: не удалось записать внешний файл PID \"%s\": %s\n" + +#: postmaster/postmaster.c:1360 utils/init/postinit.c:215 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "не удалось загрузить pg_hba.conf" + +#: postmaster/postmaster.c:1386 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "процесс postmaster стал многопоточным при запуске" + +#: postmaster/postmaster.c:1387 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "Установите в переменной окружения LC_ALL правильную локаль." + +#: postmaster/postmaster.c:1488 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: подходящий исполняемый файл postgres не найден" + +#: postmaster/postmaster.c:1511 utils/misc/tzparser.c:340 +#, c-format +msgid "" +"This may indicate an incomplete PostgreSQL installation, or that the file " +"\"%s\" has been moved away from its proper location." +msgstr "" +"Возможно, PostgreSQL установлен не полностью или файла \"%s\" нет в " +"положенном месте." + +#: postmaster/postmaster.c:1538 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: не найдена система баз данных\n" +"Ожидалось найти её в каталоге \"%s\",\n" +"но открыть файл \"%s\" не удалось: %s\n" + +#: postmaster/postmaster.c:1715 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "сбой select() в postmaster'е: %m" + +#: postmaster/postmaster.c:1870 +#, c-format +msgid "" +"performing immediate shutdown because data directory lock file is invalid" +msgstr "" +"немедленное отключение из-за ошибочного файла блокировки каталога данных" + +#: postmaster/postmaster.c:1973 postmaster/postmaster.c:2004 +#, c-format +msgid "incomplete startup packet" +msgstr "неполный стартовый пакет" + +#: postmaster/postmaster.c:1985 +#, c-format +msgid "invalid length of startup packet" +msgstr "неверная длина стартового пакета" + +#: postmaster/postmaster.c:2043 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "не удалось отправить ответ в процессе SSL-согласования: %m" + +#: postmaster/postmaster.c:2075 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "не удалось отправить ответ в процессе согласования GSSAPI: %m" + +#: postmaster/postmaster.c:2105 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "" +"неподдерживаемый протокол клиентского приложения %u.%u; сервер поддерживает " +"%u.0 - %u.%u" + +#: postmaster/postmaster.c:2169 utils/misc/guc.c:6769 utils/misc/guc.c:6805 +#: utils/misc/guc.c:6875 utils/misc/guc.c:8226 utils/misc/guc.c:11072 +#: utils/misc/guc.c:11106 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "неверное значение для параметра \"%s\": \"%s\"" + +#: postmaster/postmaster.c:2172 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "Допустимые значения: \"false\", 0, \"true\", 1, \"database\"." + +#: postmaster/postmaster.c:2217 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "" +"неверная структура стартового пакета: последним байтом должен быть терминатор" + +#: postmaster/postmaster.c:2255 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "в стартовом пакете не указано имя пользователя PostgreSQL" + +#: postmaster/postmaster.c:2319 +#, c-format +msgid "the database system is starting up" +msgstr "система баз данных запускается" + +#: postmaster/postmaster.c:2324 +#, c-format +msgid "the database system is shutting down" +msgstr "система баз данных останавливается" + +#: postmaster/postmaster.c:2329 +#, c-format +msgid "the database system is in recovery mode" +msgstr "система баз данных в режиме восстановления" + +#: postmaster/postmaster.c:2334 storage/ipc/procarray.c:293 +#: storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:362 +#, c-format +msgid "sorry, too many clients already" +msgstr "извините, уже слишком много клиентов" + +#: postmaster/postmaster.c:2424 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "неправильный ключ в запросе на отмену процесса %d" + +#: postmaster/postmaster.c:2436 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "процесс с кодом %d, полученным в запросе на отмену, не найден" + +#: postmaster/postmaster.c:2689 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "получен SIGHUP, файлы конфигурации перезагружаются" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2715 postmaster/postmaster.c:2719 +#, c-format +msgid "%s was not reloaded" +msgstr "%s не был перезагружен" + +#: postmaster/postmaster.c:2729 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "конфигурация SSL не была перезагружена" + +#: postmaster/postmaster.c:2785 +#, c-format +msgid "received smart shutdown request" +msgstr "получен запрос на \"вежливое\" выключение" + +#: postmaster/postmaster.c:2831 +#, c-format +msgid "received fast shutdown request" +msgstr "получен запрос на быстрое выключение" + +#: postmaster/postmaster.c:2849 +#, c-format +msgid "aborting any active transactions" +msgstr "прерывание всех активных транзакций" + +#: postmaster/postmaster.c:2873 +#, c-format +msgid "received immediate shutdown request" +msgstr "получен запрос на немедленное выключение" + +#: postmaster/postmaster.c:2948 +#, c-format +msgid "shutdown at recovery target" +msgstr "выключение при достижении цели восстановления" + +#: postmaster/postmaster.c:2966 postmaster/postmaster.c:3002 +msgid "startup process" +msgstr "стартовый процесс" + +#: postmaster/postmaster.c:2969 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "прерывание запуска из-за ошибки в стартовом процессе" + +#: postmaster/postmaster.c:3044 +#, c-format +msgid "database system is ready to accept connections" +msgstr "система БД готова принимать подключения" + +#: postmaster/postmaster.c:3065 +msgid "background writer process" +msgstr "процесс фоновой записи" + +#: postmaster/postmaster.c:3119 +msgid "checkpointer process" +msgstr "процесс контрольных точек" + +#: postmaster/postmaster.c:3135 +msgid "WAL writer process" +msgstr "процесс записи WAL" + +#: postmaster/postmaster.c:3150 +msgid "WAL receiver process" +msgstr "процесс считывания WAL" + +#: postmaster/postmaster.c:3165 +msgid "autovacuum launcher process" +msgstr "процесс запуска автоочистки" + +#: postmaster/postmaster.c:3180 +msgid "archiver process" +msgstr "процесс архивации" + +#: postmaster/postmaster.c:3196 +msgid "statistics collector process" +msgstr "процесс сбора статистики" + +#: postmaster/postmaster.c:3210 +msgid "system logger process" +msgstr "процесс системного протоколирования" + +#: postmaster/postmaster.c:3274 +#, c-format +msgid "background worker \"%s\"" +msgstr "фоновый процесс \"%s\"" + +#: postmaster/postmaster.c:3358 postmaster/postmaster.c:3378 +#: postmaster/postmaster.c:3385 postmaster/postmaster.c:3403 +msgid "server process" +msgstr "процесс сервера" + +#: postmaster/postmaster.c:3457 +#, c-format +msgid "terminating any other active server processes" +msgstr "завершение всех остальных активных серверных процессов" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3712 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) завершился с кодом выхода %d" + +#: postmaster/postmaster.c:3714 postmaster/postmaster.c:3726 +#: postmaster/postmaster.c:3736 postmaster/postmaster.c:3747 +#, c-format +msgid "Failed process was running: %s" +msgstr "Завершившийся процесс выполнял действие: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3723 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) был прерван исключением 0x%X" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3733 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) был завершён по сигналу %d: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3745 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) завершился с неизвестным кодом состояния %d" + +#: postmaster/postmaster.c:3960 +#, c-format +msgid "abnormal database system shutdown" +msgstr "аварийное выключение системы БД" + +#: postmaster/postmaster.c:4000 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "все серверные процессы завершены... переинициализация" + +#: postmaster/postmaster.c:4170 postmaster/postmaster.c:5579 +#: postmaster/postmaster.c:5966 +#, c-format +msgid "could not generate random cancel key" +msgstr "не удалось сгенерировать случайный ключ отмены" + +#: postmaster/postmaster.c:4224 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "породить новый процесс для соединения не удалось: %m" + +#: postmaster/postmaster.c:4266 +msgid "could not fork new process for connection: " +msgstr "породить новый процесс для соединения не удалось: " + +#: postmaster/postmaster.c:4383 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "принято подключение: узел=%s порт=%s" + +#: postmaster/postmaster.c:4388 +#, c-format +msgid "connection received: host=%s" +msgstr "принято подключение: узел=%s" + +#: postmaster/postmaster.c:4658 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "запустить серверный процесс \"%s\" не удалось: %m" + +#: postmaster/postmaster.c:4817 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "" +"число повторных попыток резервирования разделяемой памяти достигло предела" + +#: postmaster/postmaster.c:4818 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Это может быть вызвано антивирусным ПО или механизмом ASLR." + +#: postmaster/postmaster.c:5012 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "не удалось загрузить конфигурацию SSL в дочерний процесс" + +#: postmaster/postmaster.c:5144 +#, c-format +msgid "Please report this to <%s>." +msgstr "Пожалуйста, напишите об этой ошибке по адресу <%s>." + +#: postmaster/postmaster.c:5231 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "система БД готова к подключениям в режиме \"только чтение\"" + +#: postmaster/postmaster.c:5507 +#, c-format +msgid "could not fork startup process: %m" +msgstr "породить стартовый процесс не удалось: %m" + +#: postmaster/postmaster.c:5511 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "породить процесс фоновой записи не удалось: %m" + +#: postmaster/postmaster.c:5515 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "породить процесс контрольных точек не удалось: %m" + +#: postmaster/postmaster.c:5519 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "породить процесс записи WAL не удалось: %m" + +#: postmaster/postmaster.c:5523 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "породить процесс считывания WAL не удалось: %m" + +#: postmaster/postmaster.c:5527 +#, c-format +msgid "could not fork process: %m" +msgstr "породить процесс не удалось: %m" + +#: postmaster/postmaster.c:5724 postmaster/postmaster.c:5747 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "" +"при регистрации фонового процесса не указывалось, что ему требуется " +"подключение к БД" + +#: postmaster/postmaster.c:5731 postmaster/postmaster.c:5754 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "неправильный режим обработки в фоновом процессе" + +#: postmaster/postmaster.c:5827 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "запуск фонового рабочего процесса \"%s\"" + +#: postmaster/postmaster.c:5839 +#, c-format +msgid "could not fork worker process: %m" +msgstr "породить рабочий процесс не удалось: %m" + +#: postmaster/postmaster.c:5952 +#, c-format +msgid "no slot available for new worker process" +msgstr "для нового рабочего процесса не нашлось свободного слота" + +#: postmaster/postmaster.c:6287 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "" +"продублировать сокет %d для серверного процесса не удалось (код ошибки: %d)" + +#: postmaster/postmaster.c:6319 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "создать наследуемый сокет не удалось (код ошибки: %d)\n" + +#: postmaster/postmaster.c:6348 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "открыть файл серверных переменных \"%s\" не удалось: %s\n" + +#: postmaster/postmaster.c:6355 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "прочитать файл серверных переменных \"%s\" не удалось: %s\n" + +#: postmaster/postmaster.c:6364 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "не удалось стереть файл \"%s\": %s\n" + +#: postmaster/postmaster.c:6381 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "отобразить файл серверных переменных не удалось (код ошибки: %lu)\n" + +#: postmaster/postmaster.c:6390 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "" +"отключить отображение файла серверных переменных не удалось (код ошибки: " +"%lu)\n" + +#: postmaster/postmaster.c:6397 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "" +"закрыть указатель файла серверных переменных не удалось (код ошибки: %lu)\n" + +#: postmaster/postmaster.c:6575 +#, c-format +msgid "could not read exit code for process\n" +msgstr "прочитать код завершения процесса не удалось\n" + +#: postmaster/postmaster.c:6580 +#, c-format +msgid "could not post child completion status\n" +msgstr "отправить состояние завершения потомка не удалось\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "не удалось прочитать из канала протоколирования: %m" + +#: postmaster/syslogger.c:522 +#, c-format +msgid "logger shutting down" +msgstr "остановка протоколирования" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "не удалось создать канал для syslog: %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "не удалось породить процесс системного протоколирования: %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "передача вывода в протокол процессу сбора протоколов" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "В дальнейшем протоколы будут выводиться в каталог \"%s\"." + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "не удалось перенаправить stdout: %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "не удалось перенаправить stderr: %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "не удалось записать в файл протокола: %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "не удалось открыть файл протокола \"%s\": %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "отключение автопрокрутки (чтобы включить, передайте SIGHUP)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "" +"не удалось определить, какое правило сортировки использовать для регулярного " +"выражения" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "" +"недетерминированные правила сортировки не поддерживаются для регулярных " +"выражений" + +#: replication/backup_manifest.c:236 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "ожидался конец линии времени %u, но обнаружена линия времени %u" + +#: replication/backup_manifest.c:253 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "ожидалось начало линии времени %u, но обнаружена линия времени %u" + +#: replication/backup_manifest.c:280 +#, c-format +msgid "start timeline %u not found in history of timeline %u" +msgstr "начальная линия времени %u не найдена в истории линии времени %u" + +#: replication/backup_manifest.c:327 +#, c-format +msgid "could not rewind temporary file" +msgstr "не удалось переместиться во временном файле" + +#: replication/backup_manifest.c:354 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "не удалось прочитать из временного файла: %m" + +#: replication/basebackup.c:108 +#, c-format +msgid "could not read from file \"%s\"" +msgstr "не удалось прочитать файл \"%s\"" + +#: replication/basebackup.c:551 +#, c-format +msgid "could not find any WAL files" +msgstr "не удалось найти ни одного файла WAL" + +#: replication/basebackup.c:566 replication/basebackup.c:582 +#: replication/basebackup.c:591 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "не удалось найти файл WAL \"%s\"" + +#: replication/basebackup.c:634 replication/basebackup.c:665 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "неприемлемый размер файла WAL \"%s\"" + +#: replication/basebackup.c:648 replication/basebackup.c:1752 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "" +"в процессе базового резервного копирования не удалось передать данные, " +"копирование прерывается" + +#: replication/basebackup.c:724 +#, c-format +msgid "%lld total checksum verification failure" +msgid_plural "%lld total checksum verification failures" +msgstr[0] "всего ошибок контрольных сумм: %lld" +msgstr[1] "всего ошибок контрольных сумм: %lld" +msgstr[2] "всего ошибок контрольных сумм: %lld" + +#: replication/basebackup.c:731 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "при базовом резервном копировании выявлены ошибки контрольных сумм" + +#: replication/basebackup.c:784 replication/basebackup.c:793 +#: replication/basebackup.c:802 replication/basebackup.c:811 +#: replication/basebackup.c:820 replication/basebackup.c:831 +#: replication/basebackup.c:848 replication/basebackup.c:857 +#: replication/basebackup.c:869 replication/basebackup.c:893 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "повторяющийся параметр \"%s\"" + +#: replication/basebackup.c:837 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d вне диапазона, допустимого для параметра \"%s\" (%d .. %d)" + +#: replication/basebackup.c:882 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "нераспознанный параметр в манифесте: \"%s\"" + +#: replication/basebackup.c:898 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "нераспознанный алгоритм расчёта контрольных сумм: \"%s\"" + +#: replication/basebackup.c:913 +#, c-format +msgid "manifest checksums require a backup manifest" +msgstr "контрольные суммы не могут рассчитываться без манифеста копии" + +#: replication/basebackup.c:1504 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "специальный файл \"%s\" пропускается" + +#: replication/basebackup.c:1623 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "неверный номер сегмента %d в файле \"%s\"" + +#: replication/basebackup.c:1642 +#, c-format +msgid "" +"could not verify checksum in file \"%s\", block %d: read buffer size %d and " +"page size %d differ" +msgstr "" +"не удалось проверить контрольную сумму в файле \"%s\", блоке %d: размер " +"прочитанного буфера (%d) отличается от размера страницы (%d)" + +#: replication/basebackup.c:1686 replication/basebackup.c:1716 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "не удалось переместиться в файле \"%s\": %m" + +#: replication/basebackup.c:1708 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "не удалось заново прочитать блок %d файла \"%s\": %m" + +#: replication/basebackup.c:1732 +#, c-format +msgid "" +"checksum verification failed in file \"%s\", block %d: calculated %X but " +"expected %X" +msgstr "" +"ошибка контрольной суммы в файле \"%s\", блоке %d: вычислено значение %X, но " +"ожидалось %X" + +#: replication/basebackup.c:1739 +#, c-format +msgid "" +"further checksum verification failures in file \"%s\" will not be reported" +msgstr "" +"о дальнейших ошибках контрольных сумм в файле \"%s\" сообщаться не будет" + +#: replication/basebackup.c:1807 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "всего в файле \"%s\" обнаружено ошибок контрольных сумм: %d" +msgstr[1] "всего в файле \"%s\" обнаружено ошибок контрольных сумм: %d" +msgstr[2] "всего в файле \"%s\" обнаружено ошибок контрольных сумм: %d" + +#: replication/basebackup.c:1843 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "слишком длинное имя файла для формата tar: \"%s\"" + +#: replication/basebackup.c:1848 +#, c-format +msgid "" +"symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "" +"цель символической ссылки слишком длинная для формата tar: имя файла \"%s\", " +"цель \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, c-format +msgid "could not clear search path: %s" +msgstr "не удалось очистить путь поиска: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:251 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "ошибочный синтаксис строки подключения: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:275 +#, c-format +msgid "could not parse connection string: %s" +msgstr "не удалось разобрать строку подключения: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:347 +#, c-format +msgid "" +"could not receive database system identifier and timeline ID from the " +"primary server: %s" +msgstr "" +"не удалось получить идентификатор СУБД и код линии времени с главного " +"сервера: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:358 +#: replication/libpqwalreceiver/libpqwalreceiver.c:576 +#, c-format +msgid "invalid response from primary server" +msgstr "неверный ответ главного сервера" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:359 +#, c-format +msgid "" +"Could not identify system: got %d rows and %d fields, expected %d rows and " +"%d or more fields." +msgstr "" +"Не удалось идентифицировать систему, получено строк: %d, полей: %d " +"(ожидалось: %d и %d (или более))." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:432 +#: replication/libpqwalreceiver/libpqwalreceiver.c:438 +#: replication/libpqwalreceiver/libpqwalreceiver.c:463 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "не удалось начать трансляцию WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:486 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "не удалось отправить главному серверу сообщение о конце передачи: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:508 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "неожиданный набор данных после конца передачи" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:522 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "ошибка при остановке потоковой операции COPY: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:531 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "ошибка при чтении результата команды передачи: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 +#: replication/libpqwalreceiver/libpqwalreceiver.c:773 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "неожиданный результат после CommandComplete: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:565 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "не удалось получить файл истории линии времени с главного сервера: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:577 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "Ожидался 1 кортеж с 2 полями, однако получено кортежей: %d, полей: %d." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:737 +#: replication/libpqwalreceiver/libpqwalreceiver.c:788 +#: replication/libpqwalreceiver/libpqwalreceiver.c:794 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "не удалось извлечь данные из потока WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:813 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "не удалось отправить данные в поток WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:866 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "не удалось создать слот репликации \"%s\": %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:911 +#, c-format +msgid "invalid query response" +msgstr "неверный ответ на запрос" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:912 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "Ожидалось полей: %d, получено: %d." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:981 +#, c-format +msgid "the query interface requires a database connection" +msgstr "для интерфейса запросов требуется подключение к БД" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1012 +msgid "empty query" +msgstr "пустой запрос" + +#: replication/logical/launcher.c:295 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "" +"запускается процесс-обработчик логической репликации для подписки \"%s\"" + +#: replication/logical/launcher.c:302 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "" +"нельзя запустить процессы-обработчики логической репликации при " +"max_replication_slots = 0" + +#: replication/logical/launcher.c:382 +#, c-format +msgid "out of logical replication worker slots" +msgstr "недостаточно слотов для процессов логической репликации" + +#: replication/logical/launcher.c:383 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "Возможно, следует увеличить параметр max_logical_replication_workers." + +#: replication/logical/launcher.c:438 +#, c-format +msgid "out of background worker slots" +msgstr "недостаточно слотов для фоновых рабочих процессов" + +#: replication/logical/launcher.c:439 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "Возможно, следует увеличить параметр max_worker_processes." + +#: replication/logical/launcher.c:638 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "" +"слот обработчика логической репликации %d пуст, подключиться к нему нельзя" + +#: replication/logical/launcher.c:647 +#, c-format +msgid "" +"logical replication worker slot %d is already used by another worker, cannot " +"attach" +msgstr "" +"слот обработчика логической репликации %d уже занят другим процессом, " +"подключиться к нему нельзя" + +#: replication/logical/launcher.c:951 +#, c-format +msgid "logical replication launcher started" +msgstr "процесс запуска логической репликации запущен" + +#: replication/logical/logical.c:87 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "для логического декодирования требуется wal_level >= logical" + +#: replication/logical/logical.c:92 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "для логического декодирования требуется подключение к БД" + +#: replication/logical/logical.c:110 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "логическое декодирование нельзя использовать в процессе восстановления" + +#: replication/logical/logical.c:258 replication/logical/logical.c:399 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "" +"физический слот репликации нельзя использовать для логического декодирования" + +#: replication/logical/logical.c:263 replication/logical/logical.c:404 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "слот репликации \"%s\" создан не в этой базе данных" + +#: replication/logical/logical.c:270 +#, c-format +msgid "" +"cannot create logical replication slot in transaction that has performed " +"writes" +msgstr "" +"нельзя создать слот логической репликации в транзакции, осуществляющей запись" + +#: replication/logical/logical.c:444 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "начинается логическое декодирование для слота \"%s\"" + +#: replication/logical/logical.c:446 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Передача транзакций, фиксируемых после %X/%X, чтение WAL с %X/%X." + +#: replication/logical/logical.c:593 +#, c-format +msgid "" +"slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "" +"слот \"%s\", модуль вывода \"%s\", в обработчике %s, связанный LSN: %X/%X" + +#: replication/logical/logical.c:600 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "слот \"%s\", модуль вывода \"%s\", в обработчике %s" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "" +"для использования слотов репликации требуется роль репликации или права " +"суперпользователя" + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "имя слота не может быть NULL" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "массив параметров не может быть NULL" + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "массив должен быть одномерным" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "массив не должен содержать элементы null" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 +#: utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "в массиве должно быть чётное число элементов" + +#: replication/logical/logicalfuncs.c:251 +#, c-format +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "из слота репликации \"%s\" больше нельзя получать изменения" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:648 +#, c-format +msgid "This slot has never previously reserved WAL, or has been invalidated." +msgstr "Для этого слота ранее не резервировался WAL либо слот был аннулирован." + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "" +"logical decoding output plugin \"%s\" produces binary output, but function " +"\"%s\" expects textual data" +msgstr "" +"модуль вывода логического декодирования \"%s\" выдаёт двоичные данные, но " +"функция \"%s\" ожидает текстовые" + +#: replication/logical/origin.c:188 +#, c-format +msgid "only superusers can query or manipulate replication origins" +msgstr "" +"запрашивать или модифицировать источники репликации могут только " +"суперпользователи" + +#: replication/logical/origin.c:193 +#, c-format +msgid "" +"cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "" +"запрашивать или модифицировать источники репликации при " +"max_replication_slots = 0 нельзя" + +#: replication/logical/origin.c:198 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "модифицировать источники репликации во время восстановления нельзя" + +#: replication/logical/origin.c:233 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "источник репликации \"%s\" не существует" + +#: replication/logical/origin.c:324 +#, c-format +msgid "could not find free replication origin OID" +msgstr "найти свободный OID для источника репликации не удалось" + +#: replication/logical/origin.c:372 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "" +"удалить источник репликации с OID %d нельзя, он используется процессом с PID " +"%d" + +#: replication/logical/origin.c:464 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "источник репликации с OID %u не существует" + +#: replication/logical/origin.c:729 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "" +"контрольная точка репликации имеет неправильную сигнатуру (%u вместо %u)" + +#: replication/logical/origin.c:770 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "" +"не удалось найти свободную ячейку для состояния репликации, увеличьте " +"max_replication_slots" + +#: replication/logical/origin.c:788 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "" +"неверная контрольная сумма файла контрольной точки для слота репликации (%u " +"вместо %u)" + +#: replication/logical/origin.c:916 replication/logical/origin.c:1102 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "источник репликации с OID %d уже занят процессом с PID %d" + +#: replication/logical/origin.c:927 replication/logical/origin.c:1114 +#, c-format +msgid "" +"could not find free replication state slot for replication origin with OID %u" +msgstr "" +"не удалось найти свободный слот состояния репликации для источника " +"репликации с OID %u" + +#: replication/logical/origin.c:929 replication/logical/origin.c:1116 +#: replication/slot.c:1762 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "Увеличьте параметр max_replication_slots и повторите попытку." + +#: replication/logical/origin.c:1073 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "нельзя настроить источник репликации, когда он уже настроен" + +#: replication/logical/origin.c:1153 replication/logical/origin.c:1369 +#: replication/logical/origin.c:1389 +#, c-format +msgid "no replication origin is configured" +msgstr "ни один источник репликации не настроен" + +#: replication/logical/origin.c:1236 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "имя источника репликации \"%s\" зарезервировано" + +#: replication/logical/origin.c:1238 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "Имена источников, начинающиеся с \"pg_\", зарезервированы." + +#: replication/logical/relation.c:302 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "целевое отношение логической репликации \"%s.%s\" не существует" + +#: replication/logical/relation.c:345 +#, c-format +msgid "" +"logical replication target relation \"%s.%s\" is missing some replicated " +"columns" +msgstr "" +"в целевом отношении логической репликации (\"%s.%s\") отсутствуют некоторые " +"реплицируемые столбцы" + +#: replication/logical/relation.c:385 +#, c-format +msgid "" +"logical replication target relation \"%s.%s\" uses system columns in REPLICA " +"IDENTITY index" +msgstr "" +"в целевом отношении логической репликации (\"%s.%s\") в индексе REPLICA " +"IDENTITY используются системные столбцы" + +#: replication/logical/reorderbuffer.c:2663 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "не удалось записать в файл данных для XID %u: %m" + +#: replication/logical/reorderbuffer.c:2850 +#: replication/logical/reorderbuffer.c:2875 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "не удалось прочитать из файла подкачки буфера пересортировки: %m" + +#: replication/logical/reorderbuffer.c:2854 +#: replication/logical/reorderbuffer.c:2879 +#, c-format +msgid "" +"could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "" +"не удалось прочитать из файла подкачки буфера пересортировки (прочитано " +"байт: %d, требовалось: %u)" + +#: replication/logical/reorderbuffer.c:3114 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "" +"ошибка при удалении файла \"%s\" в процессе удаления pg_replslot/%s/xid*: %m" + +#: replication/logical/reorderbuffer.c:3606 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "" +"не удалось прочитать из файла \"%s\" (прочитано байт: %d, требовалось: %d)" + +#: replication/logical/snapbuild.c:606 +#, c-format +msgid "initial slot snapshot too large" +msgstr "изначальный снимок слота слишком большой" + +# skip-rule: capital-letter-first +#: replication/logical/snapbuild.c:660 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "" +"exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "" +"экспортирован снимок логического декодирования: \"%s\" (ид. транзакций: %u)" +msgstr[1] "" +"экспортирован снимок логического декодирования: \"%s\" (ид. транзакций: %u)" +msgstr[2] "" +"экспортирован снимок логического декодирования: \"%s\" (ид. транзакций: %u)" + +#: replication/logical/snapbuild.c:1265 replication/logical/snapbuild.c:1358 +#: replication/logical/snapbuild.c:1915 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "процесс логического декодирования достиг точки согласованности в %X/%X" + +#: replication/logical/snapbuild.c:1267 +#, c-format +msgid "There are no running transactions." +msgstr "Больше активных транзакций нет." + +#: replication/logical/snapbuild.c:1309 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "" +"процесс логического декодирования нашёл начальную стартовую точку в %X/%X" + +#: replication/logical/snapbuild.c:1311 replication/logical/snapbuild.c:1335 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Ожидание транзакций (примерно %d), старее %u до конца." + +#: replication/logical/snapbuild.c:1333 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "" +"при логическом декодировании найдена начальная точка согласованности в %X/%X" + +#: replication/logical/snapbuild.c:1360 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Больше старых транзакций нет." + +#: replication/logical/snapbuild.c:1757 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "" +"файл состояния snapbuild \"%s\" имеет неправильную сигнатуру (%u вместо %u)" + +#: replication/logical/snapbuild.c:1763 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "" +"файл состояния snapbuild \"%s\" имеет неправильную версию (%u вместо %u)" + +#: replication/logical/snapbuild.c:1862 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "" +"в файле состояния snapbuild \"%s\" неверная контрольная сумма (%u вместо %u)" + +#: replication/logical/snapbuild.c:1917 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "Логическое декодирование начнётся с сохранённого снимка." + +#: replication/logical/snapbuild.c:1989 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "не удалось разобрать имя файла \"%s\"" + +#: replication/logical/tablesync.c:132 +#, c-format +msgid "" +"logical replication table synchronization worker for subscription \"%s\", " +"table \"%s\" has finished" +msgstr "" +"процесс синхронизации таблицы при логической репликации для подписки \"%s\", " +"таблицы \"%s\" закончил обработку" + +#: replication/logical/tablesync.c:664 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "" +"не удалось получить информацию о таблице \"%s.%s\" с сервера публикации: %s" + +#: replication/logical/tablesync.c:670 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "таблица \"%s.%s\" не найдена на сервере публикации" + +#: replication/logical/tablesync.c:704 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "не удалось получить информацию о таблице \"%s.%s\": %s" + +#: replication/logical/tablesync.c:791 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "" +"не удалось начать копирование начального содержимого таблицы \"%s.%s\": %s" + +#: replication/logical/tablesync.c:905 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "" +"при копировании таблицы не удалось начать транзакцию на сервере публикации" + +#: replication/logical/tablesync.c:927 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "" +"при копировании таблицы не удалось завершить транзакцию на сервере публикации" + +#: replication/logical/worker.c:311 +#, c-format +msgid "" +"processing remote data for replication target relation \"%s.%s\" column \"%s" +"\", remote type %s, local type %s" +msgstr "" +"обработка внешних данных для целевого отношения репликации \"%s.%s\" столбца " +"\"%s\", удалённый тип %s, локальный тип %s" + +#: replication/logical/worker.c:550 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "сообщение ORIGIN отправлено неуместно" + +#: replication/logical/worker.c:700 +#, c-format +msgid "" +"publisher did not send replica identity column expected by the logical " +"replication target relation \"%s.%s\"" +msgstr "" +"сервер публикации не передал столбец идентификации реплики, ожидаемый для " +"целевого отношения логической репликации \"%s.%s\"" + +#: replication/logical/worker.c:707 +#, c-format +msgid "" +"logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY " +"index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY " +"FULL" +msgstr "" +"в целевом отношении логической репликации (\"%s.%s\") нет ни индекса REPLICA " +"IDENTITY, ни ключа PRIMARY KEY, и публикуемое отношение не имеет " +"характеристики REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:1393 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "неверный тип сообщения логической репликации \"%c\"" + +#: replication/logical/worker.c:1536 +#, c-format +msgid "data stream from publisher has ended" +msgstr "поток данных с сервера публикации закончился" + +#: replication/logical/worker.c:1691 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "завершение обработчика логической репликации из-за тайм-аута" + +#: replication/logical/worker.c:1836 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will stop because " +"the subscription was removed" +msgstr "" +"применяющий процесс логической репликации для подписки \"%s\" будет " +"остановлен, так как подписка была удалена" + +#: replication/logical/worker.c:1850 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will stop because " +"the subscription was disabled" +msgstr "" +"применяющий процесс логической репликации для подписки \"%s\" будет " +"остановлен, так как подписка была отключена" + +#: replication/logical/worker.c:1864 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because the connection information was changed" +msgstr "" +"применяющий процесс логической репликации для подписки \"%s\" будет " +"перезапущен из-за изменения информации о подключении" + +#: replication/logical/worker.c:1878 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because subscription was renamed" +msgstr "" +"применяющий процесс логической репликации для подписки \"%s\" будет " +"перезапущен, так как подписка была переименована" + +#: replication/logical/worker.c:1895 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because the replication slot name was changed" +msgstr "" +"применяющий процесс логической репликации для подписки \"%s\" будет " +"перезапущен, так как было изменено имя слота репликации" + +#: replication/logical/worker.c:1909 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will restart " +"because subscription's publications were changed" +msgstr "" +"применяющий процесс логической репликации для подписки \"%s\" будет " +"перезапущен из-за изменения публикаций подписки" + +#: replication/logical/worker.c:2005 +#, c-format +msgid "" +"logical replication apply worker for subscription %u will not start because " +"the subscription was removed during startup" +msgstr "" +"применяющий процесс логической репликации для подписки %u не будет запущен, " +"так как подписка была удалена при старте" + +#: replication/logical/worker.c:2017 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will not start " +"because the subscription was disabled during startup" +msgstr "" +"применяющий процесс логической репликации для подписки \"%s\" не будет " +"запущен, так как подписка была отключена при старте" + +#: replication/logical/worker.c:2035 +#, c-format +msgid "" +"logical replication table synchronization worker for subscription \"%s\", " +"table \"%s\" has started" +msgstr "" +"процесс синхронизации таблицы при логической репликации для подписки \"%s\", " +"таблицы \"%s\" запущен" + +#: replication/logical/worker.c:2039 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "" +"запускается применяющий процесс логической репликации для подписки \"%s\"" + +#: replication/logical/worker.c:2078 +#, c-format +msgid "subscription has no replication slot set" +msgstr "для подписки не задан слот репликации" + +#: replication/pgoutput/pgoutput.c:147 +#, c-format +msgid "invalid proto_version" +msgstr "неверное значение proto_version" + +#: replication/pgoutput/pgoutput.c:152 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "значение proto_verson \"%s\" вне диапазона" + +#: replication/pgoutput/pgoutput.c:169 +#, c-format +msgid "invalid publication_names syntax" +msgstr "неверный синтаксис publication_names" + +#: replication/pgoutput/pgoutput.c:211 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "" +"клиент передал proto_version=%d, но мы поддерживаем только протокол %d и ниже" + +#: replication/pgoutput/pgoutput.c:217 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "" +"клиент передал proto_version=%d, но мы поддерживает только протокол %d и выше" + +#: replication/pgoutput/pgoutput.c:223 +#, c-format +msgid "publication_names parameter missing" +msgstr "отсутствует параметр publication_names" + +#: replication/slot.c:183 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "имя слота репликации \"%s\" слишком короткое" + +#: replication/slot.c:192 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "имя слота репликации \"%s\" слишком длинное" + +#: replication/slot.c:205 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "имя слота репликации \"%s\" содержит недопустимый символ" + +#: replication/slot.c:207 +#, c-format +msgid "" +"Replication slot names may only contain lower case letters, numbers, and the " +"underscore character." +msgstr "" +"Имя слота репликации может содержать только буквы в нижнем регистре, цифры и " +"знак подчёркивания." + +#: replication/slot.c:254 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "слот репликации \"%s\" уже существует" + +#: replication/slot.c:264 +#, c-format +msgid "all replication slots are in use" +msgstr "используются все слоты репликации" + +#: replication/slot.c:265 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Освободите ненужные или увеличьте параметр max_replication_slots." + +#: replication/slot.c:407 replication/slotfuncs.c:760 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "слот репликации \"%s\" не существует" + +#: replication/slot.c:445 replication/slot.c:1006 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "слот репликации \"%s\" занят процессом с PID %d" + +#: replication/slot.c:683 replication/slot.c:1314 replication/slot.c:1697 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "ошибка при удалении каталога \"%s\"" + +#: replication/slot.c:1041 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "" +"слоты репликации можно использовать, только если max_replication_slots > 0" + +#: replication/slot.c:1046 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "слоты репликации можно использовать, только если wal_level >= replica" + +#: replication/slot.c:1202 +#, c-format +msgid "" +"terminating process %d because replication slot \"%s\" is too far behind" +msgstr "" +"завершение процесса %d из-за слишком большого отставания слота репликации " +"\"%s\"" + +#: replication/slot.c:1221 +#, c-format +msgid "" +"invalidating slot \"%s\" because its restart_lsn %X/%X exceeds " +"max_slot_wal_keep_size" +msgstr "" +"слот \"%s\" аннулируется, так как его позиция restart_lsn %X/%X превышает " +"max_slot_wal_keep_size" + +#: replication/slot.c:1635 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "" +"файл слота репликации \"%s\" имеет неправильную сигнатуру (%u вместо %u)" + +#: replication/slot.c:1642 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "файл состояния snapbuild \"%s\" имеет неподдерживаемую версию %u" + +#: replication/slot.c:1649 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "у файла слота репликации \"%s\" неверная длина: %u" + +#: replication/slot.c:1685 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "" +"в файле слота репликации \"%s\" неверная контрольная сумма (%u вместо %u)" + +#: replication/slot.c:1719 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "существует слот логической репликации \"%s\", но wal_level < logical" + +#: replication/slot.c:1721 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Смените wal_level на logical или более высокий уровень." + +#: replication/slot.c:1725 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "существует слот физической репликации \"%s\", но wal_level < replica" + +#: replication/slot.c:1727 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Смените wal_level на replica или более высокий уровень." + +#: replication/slot.c:1761 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "перед завершением активно слишком много слотов репликации" + +#: replication/slotfuncs.c:624 +#, c-format +msgid "invalid target WAL LSN" +msgstr "неверный целевой LSN" + +#: replication/slotfuncs.c:646 +#, c-format +msgid "replication slot \"%s\" cannot be advanced" +msgstr "слот репликации \"%s\" нельзя продвинуть вперёд" + +#: replication/slotfuncs.c:664 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "" +"продвинуть слот репликации к позиции %X/%X нельзя, минимальная позиция: %X/%X" + +#: replication/slotfuncs.c:772 +#, c-format +msgid "" +"cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "" +"слот физической репликации \"%s\" нельзя скопировать как слот логической " +"репликации" + +#: replication/slotfuncs.c:774 +#, c-format +msgid "" +"cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "" +"слот логической репликации \"%s\" нельзя скопировать как слот физической " +"репликации" + +#: replication/slotfuncs.c:781 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "скопировать слот репликации, для которого не резервируется WAL, нельзя" + +#: replication/slotfuncs.c:857 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "не удалось скопировать слот репликации \"%s\"" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "" +"The source replication slot was modified incompatibly during the copy " +"operation." +msgstr "" +"Исходный слот репликации был модифицирован несовместимым образом во время " +"копирования." + +#: replication/slotfuncs.c:865 +#, c-format +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "" +"скопировать слот логической репликации \"%s\" в незавершённом состоянии " +"нельзя" + +#: replication/slotfuncs.c:867 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "" +"Повторите попытку, когда для исходного слота репликации будет определена " +"позиция confirmed_flush_lsn." + +#: replication/syncrep.c:257 +#, c-format +msgid "" +"canceling the wait for synchronous replication and terminating connection " +"due to administrator command" +msgstr "" +"отмена ожидания синхронной репликации и закрытие соединения по команде " +"администратора" + +#: replication/syncrep.c:258 replication/syncrep.c:275 +#, c-format +msgid "" +"The transaction has already committed locally, but might not have been " +"replicated to the standby." +msgstr "" +"Транзакция уже была зафиксирована локально, но возможно не была " +"реплицирована на резервный сервер." + +#: replication/syncrep.c:274 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "отмена ожидания синхронной репликации по запросу пользователя" + +#: replication/syncrep.c:416 +#, c-format +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "" +"резервный сервер \"%s\" теперь имеет приоритет синхронной репликации %u" + +#: replication/syncrep.c:483 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "резервный сервер \"%s\" стал синхронным с приоритетом %u" + +#: replication/syncrep.c:487 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "" +"резервный сервер \"%s\" стал кандидатом для включения в кворум синхронных " +"резервных" + +#: replication/syncrep.c:1034 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "ошибка при разборе synchronous_standby_names" + +#: replication/syncrep.c:1040 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "число синхронных резервных серверов (%d) должно быть больше нуля" + +#: replication/walreceiver.c:171 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "завершение процесса считывания журнала по команде администратора" + +#: replication/walreceiver.c:297 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "не удалось подключиться к главному серверу: %s" + +#: replication/walreceiver.c:343 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "идентификаторы СУБД на главном и резервном серверах различаются" + +#: replication/walreceiver.c:344 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "Идентификатор на главном сервере: %s, на резервном: %s." + +#: replication/walreceiver.c:354 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "" +"последняя линия времени %u на главном сервере отстаёт от восстанавливаемой " +"линии времени %u" + +#: replication/walreceiver.c:408 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "" +"начало передачи журнала с главного сервера, с позиции %X/%X на линии времени " +"%u" + +#: replication/walreceiver.c:413 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "перезапуск передачи журнала с позиции %X/%X на линии времени %u" + +#: replication/walreceiver.c:442 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "продолжить передачу WAL нельзя, восстановление уже окончено" + +#: replication/walreceiver.c:479 +#, c-format +msgid "replication terminated by primary server" +msgstr "репликация прекращена главным сервером" + +#: replication/walreceiver.c:480 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "На линии времени %u в %X/%X достигнут конец журнала." + +#: replication/walreceiver.c:568 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "завершение приёма журнала из-за тайм-аута" + +#: replication/walreceiver.c:606 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "" +"на главном сервере больше нет журналов для запрошенной линии времени %u" + +#: replication/walreceiver.c:622 replication/walreceiver.c:938 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "не удалось закрыть сегмент журнала %s: %m" + +#: replication/walreceiver.c:742 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "загрузка файла истории для линии времени %u с главного сервера" + +#: replication/walreceiver.c:985 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "не удалось записать в сегмент журнала %s (смещение %u, длина %lu): %m" + +#: replication/walsender.c:527 storage/smgr/md.c:1329 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "не удалось перейти к концу файла \"%s\": %m" + +#: replication/walsender.c:531 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "не удалось перейти к началу файла \"%s\": %m" + +#: replication/walsender.c:582 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "Команда IDENTIFY_SYSTEM не выполнялась до START_REPLICATION" + +#: replication/walsender.c:611 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "" +"слот логической репликации нельзя использовать для физической репликации" + +#: replication/walsender.c:680 +#, c-format +msgid "" +"requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "" +"в истории сервера нет запрошенной начальной точки %X/%X на линии времени %u" + +#: replication/walsender.c:684 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "История этого сервера ответвилась от линии времени %u в %X/%X." + +#: replication/walsender.c:729 +#, c-format +msgid "" +"requested starting point %X/%X is ahead of the WAL flush position of this " +"server %X/%X" +msgstr "" +"запрошенная начальная точка %X/%X впереди позиции сброшенных данных журнала " +"на этом сервере (%X/%X)" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:980 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s требуется выполнять не в транзакции" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:990 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s требуется выполнять внутри транзакции" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:996 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s требуется выполнять в транзакции уровня изоляции REPEATABLE READ" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1002 +#, c-format +msgid "%s must be called before any query" +msgstr "%s требуется выполнять до каких-либо запросов" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1008 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s требуется вызывать не в подтранзакции" + +#: replication/walsender.c:1152 +#, c-format +msgid "cannot read from logical replication slot \"%s\"" +msgstr "прочитать из слота логической репликации \"%s\" нельзя" + +#: replication/walsender.c:1154 +#, c-format +msgid "" +"This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "" +"Этот слот был аннулирован из-за превышения максимального зарезервированного " +"размера." + +#: replication/walsender.c:1164 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "завершение процесса передачи журнала после повышения" + +#: replication/walsender.c:1538 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "" +"нельзя выполнять новые команды, пока процесс передачи WAL находится в режиме " +"остановки" + +#: replication/walsender.c:1571 +#, c-format +msgid "received replication command: %s" +msgstr "получена команда репликации: %s" + +#: replication/walsender.c:1587 tcop/fastpath.c:279 tcop/postgres.c:1103 +#: tcop/postgres.c:1455 tcop/postgres.c:1716 tcop/postgres.c:2174 +#: tcop/postgres.c:2535 tcop/postgres.c:2614 +#, c-format +msgid "" +"current transaction is aborted, commands ignored until end of transaction " +"block" +msgstr "" +"текущая транзакция прервана, команды до конца блока транзакции игнорируются" + +#: replication/walsender.c:1674 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "" +"нельзя выполнять команды SQL в процессе, передающем WAL для физической " +"репликации" + +#: replication/walsender.c:1724 replication/walsender.c:1740 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "неожиданный обрыв соединения с резервным сервером" + +#: replication/walsender.c:1779 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "неверный тип сообщения резервного сервера: \"%c\"" + +#: replication/walsender.c:1820 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "неожиданный тип сообщения \"%c\"" + +#: replication/walsender.c:2232 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "завершение процесса передачи журнала из-за тайм-аута репликации" + +#: replication/walsender.c:2309 +#, c-format +msgid "\"%s\" has now caught up with upstream server" +msgstr "ведомый сервер \"%s\" нагнал ведущий" + +#: rewrite/rewriteDefine.c:113 rewrite/rewriteDefine.c:1000 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "правило \"%s\" для отношения \"%s\" уже существует" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "действия правил для OLD не реализованы" + +#: rewrite/rewriteDefine.c:303 +#, c-format +msgid "Use views or triggers instead." +msgstr "Воспользуйтесь представлениями или триггерами." + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "действия правил для NEW не реализованы" + +#: rewrite/rewriteDefine.c:308 +#, c-format +msgid "Use triggers instead." +msgstr "Воспользуйтесь триггерами." + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "правила INSTEAD NOTHING для SELECT не реализованы" + +#: rewrite/rewriteDefine.c:322 +#, c-format +msgid "Use views instead." +msgstr "Воспользуйтесь представлениями." + +#: rewrite/rewriteDefine.c:330 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "множественные действия в правилах для SELECT не поддерживаются" + +#: rewrite/rewriteDefine.c:340 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "в правилах для SELECT должно быть действие INSTEAD SELECT" + +#: rewrite/rewriteDefine.c:348 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "" +"правила для SELECT не должны содержать операторы, изменяющие данные, в WITH" + +#: rewrite/rewriteDefine.c:356 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "в правилах для SELECT не может быть условий" + +#: rewrite/rewriteDefine.c:383 +#, c-format +msgid "\"%s\" is already a view" +msgstr "\"%s\" уже является представлением" + +#: rewrite/rewriteDefine.c:407 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "правило представления для \"%s\" должно называться \"%s\"" + +#: rewrite/rewriteDefine.c:436 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "преобразовать секционированную таблицу \"%s\" в представление нельзя" + +#: rewrite/rewriteDefine.c:445 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "преобразовать секцию \"%s\" в представление нельзя" + +#: rewrite/rewriteDefine.c:454 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "" +"не удалось преобразовать таблицу \"%s\" в представление, так как она не " +"пуста1" + +#: rewrite/rewriteDefine.c:463 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "" +"не удалось преобразовать таблицу \"%s\" в представление, так как она " +"содержит триггеры" + +#: rewrite/rewriteDefine.c:465 +#, c-format +msgid "" +"In particular, the table cannot be involved in any foreign key relationships." +msgstr "" +"Кроме того, таблица не может быть задействована в ссылках по внешнему ключу." + +#: rewrite/rewriteDefine.c:470 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "" +"не удалось преобразовать таблицу \"%s\" в представление, так как она имеет " +"индексы" + +#: rewrite/rewriteDefine.c:476 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "" +"не удалось преобразовать таблицу \"%s\" в представление, так как она имеет " +"подчинённые таблицы" + +#: rewrite/rewriteDefine.c:482 +#, c-format +msgid "could not convert table \"%s\" to a view because it has parent tables" +msgstr "" +"не удалось преобразовать таблицу \"%s\" в представление, так как она имеет " +"родительские таблицы" + +#: rewrite/rewriteDefine.c:488 +#, c-format +msgid "" +"could not convert table \"%s\" to a view because it has row security enabled" +msgstr "" +"не удалось преобразовать таблицу \"%s\" в представление, так как для неё " +"включена защита на уровне строк" + +#: rewrite/rewriteDefine.c:494 +#, c-format +msgid "" +"could not convert table \"%s\" to a view because it has row security policies" +msgstr "" +"не удалось преобразовать таблицу \"%s\" в представление, так как к ней " +"применены политики защиты строк" + +#: rewrite/rewriteDefine.c:521 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "в правиле нельзя указать несколько списков RETURNING" + +#: rewrite/rewriteDefine.c:526 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "списки RETURNING в условных правилах не поддерживаются" + +#: rewrite/rewriteDefine.c:530 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "списки RETURNING поддерживаются только в правилах INSTEAD" + +#: rewrite/rewriteDefine.c:694 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "список результата правила для SELECT содержит слишком много столбцов" + +#: rewrite/rewriteDefine.c:695 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "список RETURNING содержит слишком много столбцов" + +#: rewrite/rewriteDefine.c:722 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "" +"преобразовать отношение, содержащее удалённые столбцы, в представление нельзя" + +#: rewrite/rewriteDefine.c:723 +#, c-format +msgid "" +"cannot create a RETURNING list for a relation containing dropped columns" +msgstr "" +"создать список RETURNING для отношения, содержащего удалённые столбцы, нельзя" + +#: rewrite/rewriteDefine.c:729 +#, c-format +msgid "" +"SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "" +"элементу %d результата правила для SELECT присвоено имя, отличное от имени " +"столбца \"%s\"" + +#: rewrite/rewriteDefine.c:731 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "Имя элемента результата SELECT: \"%s\"." + +#: rewrite/rewriteDefine.c:740 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "" +"элемент %d результата правила для SELECT имеет тип, отличный от типа столбца " +"\"%s\"" + +#: rewrite/rewriteDefine.c:742 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "элемент %d списка RETURNING имеет тип, отличный от типа столбца \"%s\"" + +#: rewrite/rewriteDefine.c:745 rewrite/rewriteDefine.c:769 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "Элемент результата SELECT имеет тип %s, тогда как тип столбца - %s." + +#: rewrite/rewriteDefine.c:748 rewrite/rewriteDefine.c:773 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "Элемент списка RETURNING имеет тип %s, тогда как тип столбца - %s." + +#: rewrite/rewriteDefine.c:764 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "" +"элемент %d результата правила для SELECT имеет размер, отличный от столбца " +"\"%s\"" + +#: rewrite/rewriteDefine.c:766 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "элемент %d списка RETURNING имеет размер, отличный от столбца \"%s\"" + +#: rewrite/rewriteDefine.c:783 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "список результата правила для SELECT содержит недостаточно элементов" + +#: rewrite/rewriteDefine.c:784 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "список RETURNING содержит недостаточно элементов" + +#: rewrite/rewriteDefine.c:877 rewrite/rewriteDefine.c:991 +#: rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "правило \"%s\" для отношения\"%s\" не существует" + +#: rewrite/rewriteDefine.c:1010 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "переименовывать правило ON SELECT нельзя" + +#: rewrite/rewriteHandler.c:546 +#, c-format +msgid "" +"WITH query name \"%s\" appears in both a rule action and the query being " +"rewritten" +msgstr "" +"имя запроса WITH \"%s\" оказалось и в действии правила, и в переписываемом " +"запросе" + +#: rewrite/rewriteHandler.c:606 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "RETURNING можно определить только для одного правила" + +#: rewrite/rewriteHandler.c:817 rewrite/rewriteHandler.c:829 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "вставить данные в столбец \"%s\" нельзя" + +#: rewrite/rewriteHandler.c:818 rewrite/rewriteHandler.c:840 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "" +"Столбец \"%s\" является столбцом идентификации со свойством GENERATED ALWAYS." + +#: rewrite/rewriteHandler.c:820 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Для переопределения укажите OVERRIDING SYSTEM VALUE." + +#: rewrite/rewriteHandler.c:839 rewrite/rewriteHandler.c:846 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "столбцу \"%s\" можно присвоить только значение DEFAULT" + +#: rewrite/rewriteHandler.c:1015 rewrite/rewriteHandler.c:1033 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "многочисленные присвоения одному столбцу \"%s\"" + +#: rewrite/rewriteHandler.c:2015 rewrite/rewriteHandler.c:3823 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "обнаружена бесконечная рекурсия в правилах для отношения \"%s\"" + +#: rewrite/rewriteHandler.c:2100 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "обнаружена бесконечная рекурсия в политике для отношения \"%s\"" + +#: rewrite/rewriteHandler.c:2420 +msgid "Junk view columns are not updatable." +msgstr "Утилизируемые столбцы представлений не обновляются." + +#: rewrite/rewriteHandler.c:2425 +msgid "" +"View columns that are not columns of their base relation are not updatable." +msgstr "" +"Столбцы представлений, не являющиеся столбцами базовых отношений, не " +"обновляются." + +#: rewrite/rewriteHandler.c:2428 +msgid "View columns that refer to system columns are not updatable." +msgstr "" +"Столбцы представлений, ссылающиеся на системные столбцы, не обновляются." + +#: rewrite/rewriteHandler.c:2431 +msgid "View columns that return whole-row references are not updatable." +msgstr "" +"Столбцы представлений, возвращающие ссылки на всю строку, не обновляются." + +#: rewrite/rewriteHandler.c:2492 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "Представления с DISTINCT не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2495 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "Представления с GROUP BY не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2498 +msgid "Views containing HAVING are not automatically updatable." +msgstr "Представления с HAVING не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2501 +msgid "" +"Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "" +"Представления с UNION, INTERSECT или EXCEPT не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2504 +msgid "Views containing WITH are not automatically updatable." +msgstr "Представления с WITH не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2507 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "Представления с LIMIT или OFFSET не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2519 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "" +"Представления, возвращающие агрегатные функции, не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2522 +msgid "Views that return window functions are not automatically updatable." +msgstr "" +"Представления, возвращающие оконные функции, не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2525 +msgid "" +"Views that return set-returning functions are not automatically updatable." +msgstr "" +"Представления, возвращающие функции с результатом-множеством, не обновляются " +"автоматически." + +#: rewrite/rewriteHandler.c:2532 rewrite/rewriteHandler.c:2536 +#: rewrite/rewriteHandler.c:2544 +msgid "" +"Views that do not select from a single table or view are not automatically " +"updatable." +msgstr "" +"Представления, выбирающие данные не из одной таблицы или представления, не " +"обновляются автоматически." + +#: rewrite/rewriteHandler.c:2547 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "Представления, содержащие TABLESAMPLE, не обновляются автоматически." + +#: rewrite/rewriteHandler.c:2571 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "" +"Представления, не содержащие обновляемых столбцов, не обновляются " +"автоматически." + +#: rewrite/rewriteHandler.c:3048 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "вставить данные в столбец \"%s\" представления \"%s\" нельзя" + +#: rewrite/rewriteHandler.c:3056 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "изменить данные в столбце \"%s\" представления \"%s\" нельзя" + +#: rewrite/rewriteHandler.c:3534 +#, c-format +msgid "" +"DO INSTEAD NOTHING rules are not supported for data-modifying statements in " +"WITH" +msgstr "" +"правила DO INSTEAD NOTHING не поддерживаются в операторах, изменяющих " +"данные, в WITH" + +#: rewrite/rewriteHandler.c:3548 +#, c-format +msgid "" +"conditional DO INSTEAD rules are not supported for data-modifying statements " +"in WITH" +msgstr "" +"условные правила DO INSTEAD не поддерживаются для операторов, изменяющих " +"данные, в WITH" + +#: rewrite/rewriteHandler.c:3552 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "" +"правила DO ALSO не поддерживаются для операторов, изменяющих данные, в WITH" + +#: rewrite/rewriteHandler.c:3557 +#, c-format +msgid "" +"multi-statement DO INSTEAD rules are not supported for data-modifying " +"statements in WITH" +msgstr "" +"составные правила DO INSTEAD не поддерживаются для операторов, изменяющих " +"данные, в WITH" + +#: rewrite/rewriteHandler.c:3751 rewrite/rewriteHandler.c:3759 +#: rewrite/rewriteHandler.c:3767 +#, c-format +msgid "" +"Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "" +"Представления в сочетании с правилами DO INSTEAD с условиями не обновляются " +"автоматически." + +#: rewrite/rewriteHandler.c:3860 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "выполнить INSERT RETURNING для отношения \"%s\" нельзя" + +#: rewrite/rewriteHandler.c:3862 +#, c-format +msgid "" +"You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "" +"Необходимо безусловное правило ON INSERT DO INSTEAD с предложением RETURNING." + +#: rewrite/rewriteHandler.c:3867 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "выполнить UPDATE RETURNING для отношения \"%s\" нельзя" + +#: rewrite/rewriteHandler.c:3869 +#, c-format +msgid "" +"You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "" +"Необходимо безусловное правило ON UPDATE DO INSTEAD с предложением RETURNING." + +#: rewrite/rewriteHandler.c:3874 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "выполнить DELETE RETURNING для отношения \"%s\" нельзя" + +#: rewrite/rewriteHandler.c:3876 +#, c-format +msgid "" +"You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "" +"Необходимо безусловное правило ON DELETE DO INSTEAD с предложением RETURNING." + +#: rewrite/rewriteHandler.c:3894 +#, c-format +msgid "" +"INSERT with ON CONFLICT clause cannot be used with table that has INSERT or " +"UPDATE rules" +msgstr "" +"INSERT c предложением ON CONFLICT нельзя использовать с таблицей, для " +"которой заданы правила INSERT или UPDATE" + +#: rewrite/rewriteHandler.c:3951 +#, c-format +msgid "" +"WITH cannot be used in a query that is rewritten by rules into multiple " +"queries" +msgstr "" +"WITH нельзя использовать в запросе, преобразованном правилами в несколько " +"запросов" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "условные служебные операторы не реализованы" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "условие WHERE CURRENT OF для представлений не реализовано" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "" +"NEW variables in ON UPDATE rules cannot reference columns that are part of a " +"multiple assignment in the subject UPDATE command" +msgstr "" +"переменные NEW в правилах ON UPDATE не могут ссылаться на столбцы, " +"фигурирующие во множественном присваивании в исходной команде UPDATE" + +#: snowball/dict_snowball.c:199 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "стеммер Snowball для языка \"%s\" и кодировки \"%s\" не найден" + +#: snowball/dict_snowball.c:222 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "повторяющийся параметр StopWords" + +#: snowball/dict_snowball.c:231 +#, c-format +msgid "multiple Language parameters" +msgstr "повторяющийся параметр Language" + +#: snowball/dict_snowball.c:238 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "нераспознанный параметр Snowball: \"%s\"" + +#: snowball/dict_snowball.c:246 +#, c-format +msgid "missing Language parameter" +msgstr "отсутствует параметр Language" + +#: statistics/dependencies.c:667 statistics/dependencies.c:720 +#: statistics/mcv.c:1477 statistics/mcv.c:1508 statistics/mvdistinct.c:348 +#: statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:42 +#: utils/adt/pseudotypes.c:76 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "значение типа %s нельзя ввести" + +#: statistics/extended_stats.c:145 +#, c-format +msgid "" +"statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "" +"объект статистики \"%s.%s\" не может быть вычислен для отношения \"%s.%s\"" + +#: statistics/mcv.c:1365 utils/adt/jsonfuncs.c:1800 +#, c-format +msgid "" +"function returning record called in context that cannot accept type record" +msgstr "" +"функция, возвращающая запись, вызвана в контексте, не допускающем этот тип" + +#: storage/buffer/bufmgr.c:588 storage/buffer/bufmgr.c:670 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "обращаться к временным таблицам других сеансов нельзя" + +#: storage/buffer/bufmgr.c:826 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "неожиданные данные после EOF в блоке %u отношения %s" + +#: storage/buffer/bufmgr.c:828 +#, c-format +msgid "" +"This has been seen to occur with buggy kernels; consider updating your " +"system." +msgstr "" +"Эта ситуация может возникать из-за ошибок в ядре; возможно, вам следует " +"обновить ОС." + +#: storage/buffer/bufmgr.c:927 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "неверная страница в блоке %u отношения %s; страница обнуляется" + +#: storage/buffer/bufmgr.c:4213 +#, c-format +msgid "could not write block %u of %s" +msgstr "не удалось запись блок %u файла %s" + +#: storage/buffer/bufmgr.c:4215 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Множественные сбои - возможно, постоянная ошибка записи." + +#: storage/buffer/bufmgr.c:4236 storage/buffer/bufmgr.c:4255 +#, c-format +msgid "writing block %u of relation %s" +msgstr "запись блока %u отношения %s" + +#: storage/buffer/bufmgr.c:4558 +#, c-format +msgid "snapshot too old" +msgstr "снимок слишком стар" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "нет пустого локального буфера" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "обращаться к временным таблицам во время параллельных операций нельзя" + +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "" +"не удалось открыть временный файл \"%s\", входящий в BufFile \"%s\": %m" + +#: storage/file/buffile.c:795 +#, c-format +msgid "" +"could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "" +"не удалось определить размер временного файла \"%s\", входящего в BufFile " +"\"%s\": %m" + +#: storage/file/fd.c:508 storage/file/fd.c:580 storage/file/fd.c:616 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "не удалось сбросить грязные данные: %m" + +#: storage/file/fd.c:538 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "не удалось определить размер грязных данных: %m" + +#: storage/file/fd.c:590 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "ошибка в munmap() при сбросе данных на диск: %m" + +#: storage/file/fd.c:798 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "для файла \"%s\" не удалось создать ссылку \"%s\": %m" + +#: storage/file/fd.c:881 +#, c-format +msgid "getrlimit failed: %m" +msgstr "ошибка в getrlimit(): %m" + +#: storage/file/fd.c:971 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "недостаточно дескрипторов файлов для запуска серверного процесса" + +#: storage/file/fd.c:972 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "Система выделяет: %d, а требуется минимум: %d." + +#: storage/file/fd.c:1023 storage/file/fd.c:2357 storage/file/fd.c:2467 +#: storage/file/fd.c:2618 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "нехватка дескрипторов файлов: %m; освободите их и повторите попытку" + +#: storage/file/fd.c:1397 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "временный файл: путь \"%s\", размер %lu" + +#: storage/file/fd.c:1528 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "не удалось создать временный каталог \"%s\": %m" + +#: storage/file/fd.c:1535 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "не удалось создать временный подкаталог \"%s\": %m" + +#: storage/file/fd.c:1728 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "не удалось создать временный файл \"%s\": %m" + +#: storage/file/fd.c:1763 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "не удалось открыть временный файл \"%s\": %m" + +#: storage/file/fd.c:1804 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "ошибка удаления временного файла \"%s\": %m" + +#: storage/file/fd.c:2068 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "размер временного файла превышает предел temp_file_limit (%d КБ)" + +#: storage/file/fd.c:2333 storage/file/fd.c:2392 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "превышен предел maxAllocatedDescs (%d) при попытке открыть файл \"%s\"" + +#: storage/file/fd.c:2437 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "" +"превышен предел maxAllocatedDescs (%d) при попытке выполнить команду \"%s\"" + +#: storage/file/fd.c:2594 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "" +"превышен предел maxAllocatedDescs (%d) при попытке открыть каталог \"%s\"" + +#: storage/file/fd.c:3122 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "в каталоге временных файлов обнаружен неуместный файл: \"%s\"" + +#: storage/file/sharedfileset.c:111 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "не удалось подключиться к уже уничтоженному набору SharedFileSet" + +#: storage/ipc/dsm.c:338 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "сегмент управления динамической разделяемой памятью испорчен" + +#: storage/ipc/dsm.c:399 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "сегмент управления динамической разделяемой памятью не в порядке" + +#: storage/ipc/dsm.c:494 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "слишком много сегментов динамической разделяемой памяти" + +#: storage/ipc/dsm_impl.c:230 storage/ipc/dsm_impl.c:526 +#: storage/ipc/dsm_impl.c:630 storage/ipc/dsm_impl.c:801 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "не удалось освободить сегмент разделяемой памяти %s: %m" + +#: storage/ipc/dsm_impl.c:240 storage/ipc/dsm_impl.c:536 +#: storage/ipc/dsm_impl.c:640 storage/ipc/dsm_impl.c:811 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "ошибка при удалении сегмента разделяемой памяти \"%s\": %m" + +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:711 +#: storage/ipc/dsm_impl.c:825 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "не удалось открыть сегмент разделяемой памяти \"%s\": %m" + +#: storage/ipc/dsm_impl.c:289 storage/ipc/dsm_impl.c:552 +#: storage/ipc/dsm_impl.c:756 storage/ipc/dsm_impl.c:849 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "не удалось обратиться к сегменту разделяемой памяти \"%s\": %m" + +#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:900 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "" +"не удалось изменить размер сегмента разделяемой памяти \"%s\" до %zu байт: %m" + +#: storage/ipc/dsm_impl.c:338 storage/ipc/dsm_impl.c:573 +#: storage/ipc/dsm_impl.c:732 storage/ipc/dsm_impl.c:922 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "не удалось отобразить сегмент разделяемой памяти \"%s\": %m" + +#: storage/ipc/dsm_impl.c:508 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "не удалось получить сегмент разделяемой памяти: %m" + +#: storage/ipc/dsm_impl.c:696 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "не удалось создать сегмент разделяемой памяти \"%s\": %m" + +#: storage/ipc/dsm_impl.c:933 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "не удалось закрыть сегмент разделяемой памяти \"%s\": %m" + +#: storage/ipc/dsm_impl.c:972 storage/ipc/dsm_impl.c:1020 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "не удалось продублировать указатель для \"%s\": %m" + +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:940 storage/ipc/latch.c:1095 storage/ipc/latch.c:1308 +#: storage/ipc/latch.c:1461 storage/ipc/latch.c:1581 +#, c-format +msgid "%s failed: %m" +msgstr "ошибка в %s: %m" + +#: storage/ipc/procarray.c:3021 +#, c-format +msgid "database \"%s\" is being used by prepared transactions" +msgstr "база \"%s\" используется подготовленными транзакциями" + +#: storage/ipc/procarray.c:3053 storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "прерывать процесс суперпользователя может только суперпользователь" + +#: storage/ipc/procarray.c:3060 storage/ipc/signalfuncs.c:147 +#, c-format +msgid "" +"must be a member of the role whose process is being terminated or member of " +"pg_signal_backend" +msgstr "" +"необходимо быть членом роли, процесс которой прерывается, или роли " +"pg_signal_backend" + +#: storage/ipc/shm_mq.c:368 +#, c-format +msgid "cannot send a message of size %zu via shared memory queue" +msgstr "" +"не удалось передать сообщение размером %zu через очередь в разделяемой памяти" + +#: storage/ipc/shm_mq.c:694 +#, c-format +msgid "invalid message size %zu in shared memory queue" +msgstr "неверный размер сообщения %zu в очереди в разделяемой памяти" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:982 +#: storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 storage/lmgr/lock.c:4167 +#: storage/lmgr/lock.c:4232 storage/lmgr/lock.c:4539 +#: storage/lmgr/predicate.c:2476 storage/lmgr/predicate.c:2491 +#: storage/lmgr/predicate.c:3973 storage/lmgr/predicate.c:5084 +#: utils/hash/dynahash.c:1067 +#, c-format +msgid "out of shared memory" +msgstr "нехватка разделяемой памяти" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "нехватка разделяемой памяти (требовалось байт: %zu)" + +#: storage/ipc/shmem.c:441 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "не удалось создать запись ShmemIndex для структуры данных \"%s\"" + +#: storage/ipc/shmem.c:456 +#, c-format +msgid "" +"ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, " +"actual %zu" +msgstr "" +"размер записи ShmemIndex не соответствует структуре данных \"%s" +"\" (ожидалось: %zu, фактически: %zu)" + +#: storage/ipc/shmem.c:475 +#, c-format +msgid "" +"not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "" +"недостаточно разделяемой памяти для структуры данных \"%s\" (требовалось " +"байт: %zu)" + +#: storage/ipc/shmem.c:507 storage/ipc/shmem.c:526 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "запрошенный размер разделяемой памяти не умещается в size_t" + +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d не относится к серверному процессу PostgreSQL" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1366 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "отправить сигнал процессу %d не удалось: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "для отмены запроса суперпользователя нужно быть суперпользователем" + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "" +"must be a member of the role whose query is being canceled or member of " +"pg_signal_backend" +msgstr "" +"необходимо быть членом роли, запрос которой отменяется, или роли " +"pg_signal_backend" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "" +"прокручивать файлы протоколов, используя adminpack 1.0, может только " +"суперпользователь" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:253 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Рассмотрите возможность использования функции %s, включённой в ядро." + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "прокрутка невозможна, так как протоколирование отключено" + +#: storage/ipc/standby.c:668 tcop/postgres.c:3189 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "" +"выполнение оператора отменено из-за конфликта с процессом восстановления" + +#: storage/ipc/standby.c:669 tcop/postgres.c:2469 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "" +"Транзакция пользователя привела к взаимоблокировке с процессом " +"восстановления." + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "" +"в записи pg_largeobject для OID %u, стр. %d неверный размер поля данных (%d)" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "неверные флаги для открытия большого объекта: %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "неверное значение ориентира: %d" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "неверный размер записи большого объекта: %d" + +#: storage/lmgr/deadlock.c:1124 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "" +"Процесс %d ожидает в режиме %s блокировку \"%s\"; заблокирован процессом %d." + +#: storage/lmgr/deadlock.c:1143 +#, c-format +msgid "Process %d: %s" +msgstr "Процесс %d: %s" + +#: storage/lmgr/deadlock.c:1152 +#, c-format +msgid "deadlock detected" +msgstr "обнаружена взаимоблокировка" + +#: storage/lmgr/deadlock.c:1155 +#, c-format +msgid "See server log for query details." +msgstr "Подробности запроса смотрите в протоколе сервера." + +#: storage/lmgr/lmgr.c:830 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "при изменении кортежа (%u,%u) в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:833 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "при удалении кортежа (%u,%u) в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:836 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "при блокировке кортежа (%u,%u) в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:839 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "при блокировке изменённой версии (%u,%u) кортежа в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:842 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "при добавлении кортежа индекса (%u,%u) в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:845 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "при проверке уникальности кортежа (%u,%u) в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:848 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "при перепроверке изменённого кортежа (%u,%u) в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:851 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "" +"при проверке ограничения-исключения для кортежа (%u,%u) в отношении \"%s\"" + +#: storage/lmgr/lmgr.c:1105 +#, c-format +msgid "relation %u of database %u" +msgstr "отношение %u базы данных %u" + +#: storage/lmgr/lmgr.c:1111 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "расширение отношения %u базы данных %u" + +#: storage/lmgr/lmgr.c:1117 +#, c-format +msgid "pg_database.datfrozenxid of database %u" +msgstr "pg_database.datfrozenxid базы %u" + +#: storage/lmgr/lmgr.c:1122 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "страница %u отношения %u базы данных %u" + +#: storage/lmgr/lmgr.c:1129 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "кортеж (%u,%u) отношения %u базы данных %u" + +#: storage/lmgr/lmgr.c:1137 +#, c-format +msgid "transaction %u" +msgstr "транзакция %u" + +#: storage/lmgr/lmgr.c:1142 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "виртуальная транзакция %d/%u" + +#: storage/lmgr/lmgr.c:1148 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "спекулятивный маркер %u транзакции %u" + +#: storage/lmgr/lmgr.c:1154 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "объект %u класса %u базы данных %u" + +#: storage/lmgr/lmgr.c:1162 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "пользовательская блокировка [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1169 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "рекомендательная блокировка [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1177 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "нераспознанный тип блокировки %d" + +#: storage/lmgr/lock.c:803 +#, c-format +msgid "" +"cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "" +"пока выполняется восстановление, нельзя получить блокировку объектов базы " +"данных в режиме %s" + +#: storage/lmgr/lock.c:805 +#, c-format +msgid "" +"Only RowExclusiveLock or less can be acquired on database objects during " +"recovery." +msgstr "" +"В процессе восстановления для объектов базы данных может быть получена " +"только блокировка RowExclusiveLock или менее сильная." + +#: storage/lmgr/lock.c:983 storage/lmgr/lock.c:1021 storage/lmgr/lock.c:2846 +#: storage/lmgr/lock.c:4168 storage/lmgr/lock.c:4233 storage/lmgr/lock.c:4540 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "Возможно, следует увеличить параметр max_locks_per_transaction." + +#: storage/lmgr/lock.c:3284 storage/lmgr/lock.c:3400 +#, c-format +msgid "" +"cannot PREPARE while holding both session-level and transaction-level locks " +"on the same object" +msgstr "" +"нельзя выполнить PREPARE, удерживая блокировки на уровне сеанса и на уровне " +"транзакции для одного объекта" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "в пуле недостаточно элементов для записи о конфликте чтения/записи" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "" +"You might need to run fewer transactions at a time or increase " +"max_connections." +msgstr "" +"Попробуйте уменьшить число транзакций в секунду или увеличить параметр " +"max_connections." + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "" +"not enough elements in RWConflictPool to record a potential read/write " +"conflict" +msgstr "" +"в пуле недостаточно элементов для записи о потенциальном конфликте чтения/" +"записи" + +#: storage/lmgr/predicate.c:1610 +#, c-format +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "откладываемый снимок был небезопасен; пробуем более новый" + +#: storage/lmgr/predicate.c:1699 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "" +"Параметр \"default_transaction_isolation\" имеет значение \"serializable\"." + +#: storage/lmgr/predicate.c:1700 +#, c-format +msgid "" +"You can use \"SET default_transaction_isolation = 'repeatable read'\" to " +"change the default." +msgstr "" +"Чтобы изменить режим по умолчанию, выполните \"SET " +"default_transaction_isolation = 'repeatable read'\"." + +#: storage/lmgr/predicate.c:1751 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "транзакция, импортирующая снимок, не должна быть READ ONLY DEFERRABLE" + +#: storage/lmgr/predicate.c:1830 utils/time/snapmgr.c:623 +#: utils/time/snapmgr.c:629 +#, c-format +msgid "could not import the requested snapshot" +msgstr "не удалось импортировать запрошенный снимок" + +#: storage/lmgr/predicate.c:1831 utils/time/snapmgr.c:630 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "Исходный процесс с PID %d уже не работает." + +#: storage/lmgr/predicate.c:2477 storage/lmgr/predicate.c:2492 +#: storage/lmgr/predicate.c:3974 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "" +"Возможно, следует увеличить значение параметра max_locks_per_transaction." + +#: storage/lmgr/predicate.c:4105 storage/lmgr/predicate.c:4141 +#: storage/lmgr/predicate.c:4174 storage/lmgr/predicate.c:4182 +#: storage/lmgr/predicate.c:4221 storage/lmgr/predicate.c:4463 +#: storage/lmgr/predicate.c:4800 storage/lmgr/predicate.c:4812 +#: storage/lmgr/predicate.c:4855 storage/lmgr/predicate.c:4893 +#, c-format +msgid "" +"could not serialize access due to read/write dependencies among transactions" +msgstr "" +"не удалось сериализовать доступ из-за зависимостей чтения/записи между " +"транзакциями" + +#: storage/lmgr/predicate.c:4107 storage/lmgr/predicate.c:4143 +#: storage/lmgr/predicate.c:4176 storage/lmgr/predicate.c:4184 +#: storage/lmgr/predicate.c:4223 storage/lmgr/predicate.c:4465 +#: storage/lmgr/predicate.c:4802 storage/lmgr/predicate.c:4814 +#: storage/lmgr/predicate.c:4857 storage/lmgr/predicate.c:4895 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "Транзакция может завершиться успешно при следующей попытке." + +#: storage/lmgr/proc.c:358 +#, c-format +msgid "" +"number of requested standby connections exceeds max_wal_senders (currently " +"%d)" +msgstr "" +"число запрошенных подключений резервных серверов превосходит max_wal_senders " +"(сейчас: %d)" + +#: storage/lmgr/proc.c:1337 +#, c-format +msgid "Process %d waits for %s on %s." +msgstr "Процесс %d ожидает в режиме %s блокировку %s." + +#: storage/lmgr/proc.c:1348 +#, c-format +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "снятие блокирующего процесса автоочистки (PID %d)" + +#: storage/lmgr/proc.c:1468 +#, c-format +msgid "" +"process %d avoided deadlock for %s on %s by rearranging queue order after " +"%ld.%03d ms" +msgstr "" +"процесс %d избежал взаимоблокировки, ожидая в режиме %s блокировку \"%s\", " +"изменив порядок очереди через %ld.%03d мс" + +#: storage/lmgr/proc.c:1483 +#, c-format +msgid "" +"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "" +"процесс %d обнаружил взаимоблокировку, ожидая в режиме %s блокировку \"%s\" " +"в течение %ld.%03d мс" + +#: storage/lmgr/proc.c:1492 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "" +"процесс %d продолжает ожидать в режиме %s блокировку \"%s\" в течение %ld." +"%03d мс" + +#: storage/lmgr/proc.c:1499 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "процесс %d получил в режиме %s блокировку \"%s\" через %ld.%03d мс" + +#: storage/lmgr/proc.c:1515 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "" +"процесс %d не смог получить в режиме %s блокировку \"%s\" за %ld.%03d мс" + +#: storage/page/bufpage.c:164 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "" +"ошибка проверки страницы: получена контрольная сумма %u, а ожидалась - %u" + +#: storage/page/bufpage.c:229 storage/page/bufpage.c:523 +#: storage/page/bufpage.c:760 storage/page/bufpage.c:893 +#: storage/page/bufpage.c:989 storage/page/bufpage.c:1101 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "" +"испорченные указатели страницы: нижний = %u, верхний = %u, спецобласть = %u" + +#: storage/page/bufpage.c:545 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "испорченный линейный указатель: %u" + +#: storage/page/bufpage.c:572 storage/page/bufpage.c:944 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "испорченный размер элемента (общий размер: %u, доступно: %u)" + +#: storage/page/bufpage.c:779 storage/page/bufpage.c:917 +#: storage/page/bufpage.c:1005 storage/page/bufpage.c:1117 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "испорченный линейный указатель: смещение = %u, размер = %u" + +#: storage/smgr/md.c:317 storage/smgr/md.c:874 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "не удалось обрезать файл \"%s\": %m" + +#: storage/smgr/md.c:445 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "не удалось увеличить файл \"%s\" до блока %u" + +#: storage/smgr/md.c:460 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "не удалось увеличить файл \"%s\": %m" + +#: storage/smgr/md.c:462 storage/smgr/md.c:469 storage/smgr/md.c:757 +#, c-format +msgid "Check free disk space." +msgstr "Проверьте, есть ли место на диске." + +#: storage/smgr/md.c:466 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "не удалось увеличить файл \"%s\" (записано байт: %d из %d) в блоке %u" + +#: storage/smgr/md.c:678 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "не удалось прочитать блок %u в файле \"%s\": %m" + +#: storage/smgr/md.c:694 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "не удалось прочитать блок %u в файле \"%s\" (прочитано байт: %d из %d)" + +#: storage/smgr/md.c:748 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "не удалось записать блок %u в файл \"%s\": %m" + +#: storage/smgr/md.c:753 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "не удалось записать блок %u в файл \"%s\" (записано байт: %d из %d)" + +#: storage/smgr/md.c:845 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "" +"не удалось обрезать файл \"%s\" (требуемая длина в блоках: %u, но сейчас он " +"содержит %u)" + +#: storage/smgr/md.c:900 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "не удалось обрезать файл \"%s\" до нужного числа блоков (%u): %m" + +#: storage/smgr/md.c:995 +#, c-format +msgid "could not forward fsync request because request queue is full" +msgstr "" +"не удалось отправить запрос синхронизации с ФС (очередь запросов переполнена)" + +#: storage/smgr/md.c:1294 +#, c-format +msgid "" +"could not open file \"%s\" (target block %u): previous segment is only %u " +"blocks" +msgstr "" +"не удалось открыть файл file \"%s\" (целевой блок %u): недостаточно блоков в " +"предыдущем сегменте (всего %u)" + +#: storage/smgr/md.c:1308 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "не удалось открыть файл file \"%s\" (целевой блок %u): %m" + +#: storage/sync/sync.c:401 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "" +"не удалось синхронизировать с ФС файл \"%s\", последует повторная попытка: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "неверный размер аргумента (%d) в сообщении вызова функции" + +#: tcop/fastpath.c:307 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "вызов функции fastpath: \"%s\" (OID %u)" + +#: tcop/fastpath.c:389 tcop/postgres.c:1323 tcop/postgres.c:1581 +#: tcop/postgres.c:2013 tcop/postgres.c:2250 +#, c-format +msgid "duration: %s ms" +msgstr "продолжительность: %s мс" + +#: tcop/fastpath.c:393 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "продолжительность %s мс, вызов функции fastpath: \"%s\" (OID %u)" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "" +"сообщение вызова функции содержит неверное число аргументов (%d, а требуется " +"%d)" + +#: tcop/fastpath.c:437 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "" +"сообщение вызова функции содержит неверное число форматов (%d, а аргументов " +"%d)" + +#: tcop/fastpath.c:524 tcop/fastpath.c:607 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "неправильный формат двоичных данных в аргументе функции %d" + +#: tcop/postgres.c:355 tcop/postgres.c:391 tcop/postgres.c:418 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "неожиданный обрыв соединения с клиентом" + +#: tcop/postgres.c:441 tcop/postgres.c:453 tcop/postgres.c:464 +#: tcop/postgres.c:476 tcop/postgres.c:4553 +#, c-format +msgid "invalid frontend message type %d" +msgstr "неправильный тип клиентского сообщения %d" + +#: tcop/postgres.c:1042 +#, c-format +msgid "statement: %s" +msgstr "оператор: %s" + +#: tcop/postgres.c:1328 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "продолжительность: %s мс, оператор: %s" + +#: tcop/postgres.c:1377 +#, c-format +msgid "parse %s: %s" +msgstr "разбор %s: %s" + +#: tcop/postgres.c:1434 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "в подготовленный оператор нельзя вставить несколько команд" + +#: tcop/postgres.c:1586 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "продолжительность: %s мс, разбор %s: %s" + +#: tcop/postgres.c:1633 +#, c-format +msgid "bind %s to %s" +msgstr "привязка %s к %s" + +# [SM]: TO REVIEW +#: tcop/postgres.c:1652 tcop/postgres.c:2516 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "безымянный подготовленный оператор не существует" + +#: tcop/postgres.c:1693 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "" +"неверное число форматов параметров в сообщении Bind (%d, а параметров %d)" + +#: tcop/postgres.c:1699 +#, c-format +msgid "" +"bind message supplies %d parameters, but prepared statement \"%s\" requires " +"%d" +msgstr "" +"в сообщении Bind передано неверное число параметров (%d, а подготовленный " +"оператор \"%s\" требует %d)" + +#: tcop/postgres.c:1897 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "неверный формат двоичных данных в параметре Bind %d" + +#: tcop/postgres.c:2018 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "продолжительность: %s мс, сообщение Bind %s%s%s: %s" + +#: tcop/postgres.c:2068 tcop/postgres.c:2600 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "портал \"%s\" не существует" + +#: tcop/postgres.c:2153 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2155 tcop/postgres.c:2258 +msgid "execute fetch from" +msgstr "выборка из" + +#: tcop/postgres.c:2156 tcop/postgres.c:2259 +msgid "execute" +msgstr "выполнение" + +#: tcop/postgres.c:2255 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "продолжительность: %s мс %s %s%s%s: %s" + +#: tcop/postgres.c:2401 +#, c-format +msgid "prepare: %s" +msgstr "подготовка: %s" + +#: tcop/postgres.c:2426 +#, c-format +msgid "parameters: %s" +msgstr "параметры: %s" + +#: tcop/postgres.c:2441 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "причина прерывания: конфликт при восстановлении" + +#: tcop/postgres.c:2457 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "Пользователь удерживал фиксатор разделяемого буфера слишком долго." + +#: tcop/postgres.c:2460 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "Пользователь удерживал блокировку таблицы слишком долго." + +#: tcop/postgres.c:2463 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "" +"Пользователь использовал табличное пространство, которое должно быть удалено." + +#: tcop/postgres.c:2466 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "" +"Запросу пользователя нужно было видеть версии строк, которые должны быть " +"удалены." + +#: tcop/postgres.c:2472 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "Пользователь был подключён к базе данных, которая должна быть удалена." + +#: tcop/postgres.c:2796 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "закрытие подключения из-за краха другого серверного процесса" + +#: tcop/postgres.c:2797 +#, c-format +msgid "" +"The postmaster has commanded this server process to roll back the current " +"transaction and exit, because another server process exited abnormally and " +"possibly corrupted shared memory." +msgstr "" +"Управляющий процесс отдал команду этому серверному процессу откатить текущую " +"транзакцию и завершиться, так как другой серверный процесс завершился " +"аварийно и возможно разрушил разделяемую память." + +#: tcop/postgres.c:2801 tcop/postgres.c:3119 +#, c-format +msgid "" +"In a moment you should be able to reconnect to the database and repeat your " +"command." +msgstr "" +"Вы сможете переподключиться к базе данных и повторить вашу команду сию " +"минуту." + +#: tcop/postgres.c:2883 +#, c-format +msgid "floating-point exception" +msgstr "исключение в операции с плавающей точкой" + +#: tcop/postgres.c:2884 +#, c-format +msgid "" +"An invalid floating-point operation was signaled. This probably means an out-" +"of-range result or an invalid operation, such as division by zero." +msgstr "" +"Поступил сигнал о неверной операции с плавающей точкой. Возможно, результат " +"оказался вне допустимых рамок или произошла ошибка вычисления, например, " +"деление на ноль." + +#: tcop/postgres.c:3049 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "отмена проверки подлинности из-за тайм-аута" + +#: tcop/postgres.c:3053 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "прекращение процесса автоочистки по команде администратора" + +#: tcop/postgres.c:3057 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "завершение обработчика логической репликации по команде администратора" + +#: tcop/postgres.c:3061 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "процесс запуска логической репликации остановлен" + +#: tcop/postgres.c:3074 tcop/postgres.c:3084 tcop/postgres.c:3117 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "закрытие подключения из-за конфликта с процессом восстановления" + +#: tcop/postgres.c:3090 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "закрытие подключения по команде администратора" + +#: tcop/postgres.c:3100 +#, c-format +msgid "connection to client lost" +msgstr "подключение к клиенту потеряно" + +#: tcop/postgres.c:3166 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "выполнение оператора отменено из-за тайм-аута блокировки" + +#: tcop/postgres.c:3173 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "выполнение оператора отменено из-за тайм-аута" + +#: tcop/postgres.c:3180 +#, c-format +msgid "canceling autovacuum task" +msgstr "отмена задачи автоочистки" + +#: tcop/postgres.c:3203 +#, c-format +msgid "canceling statement due to user request" +msgstr "выполнение оператора отменено по запросу пользователя" + +#: tcop/postgres.c:3213 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "закрытие подключения из-за тайм-аута простоя в транзакции" + +#: tcop/postgres.c:3330 +#, c-format +msgid "stack depth limit exceeded" +msgstr "превышен предел глубины стека" + +#: tcop/postgres.c:3331 +#, c-format +msgid "" +"Increase the configuration parameter \"max_stack_depth\" (currently %dkB), " +"after ensuring the platform's stack depth limit is adequate." +msgstr "" +"Увеличьте параметр конфигурации \"max_stack_depth\" (текущее значение %d " +"КБ), предварительно убедившись, что ОС предоставляет достаточный размер " +"стека." + +#: tcop/postgres.c:3394 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "Значение \"max_stack_depth\" не должно превышать %ld КБ." + +#: tcop/postgres.c:3396 +#, c-format +msgid "" +"Increase the platform's stack depth limit via \"ulimit -s\" or local " +"equivalent." +msgstr "" +"Увеличьте предел глубины стека в системе с помощью команды \"ulimit -s\" или " +"эквивалента в вашей ОС." + +#: tcop/postgres.c:3756 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "неверный аргумент командной строки для серверного процесса: %s" + +#: tcop/postgres.c:3757 tcop/postgres.c:3763 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Для дополнительной информации попробуйте \"%s --help\"." + +#: tcop/postgres.c:3761 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: неверный аргумент командной строки: %s" + +#: tcop/postgres.c:3823 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: не указаны ни база данных, ни пользователь" + +#: tcop/postgres.c:4461 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "неверный подтип сообщения CLOSE: %d" + +#: tcop/postgres.c:4496 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "неверный подтип сообщения DESCRIBE: %d" + +#: tcop/postgres.c:4574 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "вызовы функции fastpath не поддерживаются для реплицирующих соединений" + +#: tcop/postgres.c:4578 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "" +"протокол расширенных запросов не поддерживается для реплицирующих соединений" + +#: tcop/postgres.c:4755 +#, c-format +msgid "" +"disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s" +"%s" +msgstr "" +"отключение: время сеанса: %d:%02d:%02d.%03d пользователь=%s база данных=%s " +"компьютер=%s%s%s" + +#: tcop/pquery.c:629 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "" +"число форматов результатов в сообщении Bind (%d) не равно числу столбцов в " +"запросе (%d)" + +#: tcop/pquery.c:932 +#, c-format +msgid "cursor can only scan forward" +msgstr "курсор может сканировать только вперёд" + +#: tcop/pquery.c:933 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Добавьте в его объявление SCROLL, чтобы он мог перемещаться назад." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:413 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "в транзакции в режиме \"только чтение\" нельзя выполнить %s" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:431 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "выполнить %s во время параллельных операций нельзя" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:450 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "выполнить %s во время восстановления нельзя" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:468 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "в рамках операции с ограничениями по безопасности нельзя выполнить %s" + +#: tcop/utility.c:912 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "для выполнения CHECKPOINT нужно быть суперпользователем" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:620 +#, c-format +msgid "multiple DictFile parameters" +msgstr "повторяющийся параметр DictFile" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "повторяющийся параметр AffFile" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "нераспознанный параметр ispell: \"%s\"" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "отсутствует параметр AffFile" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:644 +#, c-format +msgid "missing DictFile parameter" +msgstr "отсутствует параметр DictFile" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "повторяющийся параметр Accept" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "нераспознанный параметр словаря simple: \"%s\"" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "нераспознанный параметр функции синонимов: \"%s\"" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "отсутствует параметр Synonyms" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "не удалось открыть файл синонимов \"%s\": %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "не удалось открыть файл тезауруса \"%s\": %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "неожиданный разделитель" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "неожиданный конец строки или лексемы" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "неожиданный конец строки" + +#: tsearch/dict_thesaurus.c:297 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "слишком много лексем в элементе тезауруса" + +#: tsearch/dict_thesaurus.c:421 +#, c-format +msgid "" +"thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "" +"Слова-образца в тезаурусе \"%s\" нет во внутреннем словаре (правило %d)" + +#: tsearch/dict_thesaurus.c:427 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "Образец в тезаурусе содержит стоп-слово \"%s\" (правило %d)" + +#: tsearch/dict_thesaurus.c:430 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Для представления стоп-слова внутри образца используйте \"?\"." + +#: tsearch/dict_thesaurus.c:572 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "Подстановка в тезаурусе содержит стоп-слово \"%s\" (правило %d)" + +#: tsearch/dict_thesaurus.c:579 +#, c-format +msgid "" +"thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "" +"Слова-подстановки в тезаурусе \"%s\" нет во внутреннем словаре (правило %d)" + +#: tsearch/dict_thesaurus.c:591 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "Фраза подстановки в тезаурусе не определена (правило %d)" + +#: tsearch/dict_thesaurus.c:629 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "повторяющийся параметр Dictionary" + +#: tsearch/dict_thesaurus.c:636 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "нераспознанный параметр тезауруса: \"%s\"" + +#: tsearch/dict_thesaurus.c:648 +#, c-format +msgid "missing Dictionary parameter" +msgstr "отсутствует параметр Dictionary" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1036 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "неверный флаг аффиксов \"%s\"" + +#: tsearch/spell.c:384 tsearch/spell.c:1040 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "флаг аффикса \"%s\" вне диапазона" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "неверный символ во флаге аффикса \"%s\"" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "неверный флаг аффиксов \"%s\" со значением флага \"long\"" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "не удалось открыть файл словаря \"%s\": %m" + +#: tsearch/spell.c:742 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "неверное регулярное выражение: %s" + +#: tsearch/spell.c:956 tsearch/spell.c:973 tsearch/spell.c:990 +#: tsearch/spell.c:1007 tsearch/spell.c:1072 gram.y:15994 gram.y:16011 +#, c-format +msgid "syntax error" +msgstr "ошибка синтаксиса" + +#: tsearch/spell.c:1163 tsearch/spell.c:1175 tsearch/spell.c:1734 +#: tsearch/spell.c:1739 tsearch/spell.c:1744 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "неверное указание аффикса \"%s\"" + +#: tsearch/spell.c:1216 tsearch/spell.c:1287 tsearch/spell.c:1436 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "не удалось открыть файл аффиксов \"%s\": %m" + +#: tsearch/spell.c:1270 +#, c-format +msgid "" +"Ispell dictionary supports only \"default\", \"long\", and \"num\" flag " +"values" +msgstr "" +"словарь Ispell поддерживает для флага только значения \"default\", \"long\" " +"и \"num\"" + +#: tsearch/spell.c:1314 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "неверное количество векторов флагов" + +#: tsearch/spell.c:1337 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "количество псевдонимов превышает заданное число %d" + +#: tsearch/spell.c:1552 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "файл аффиксов содержит команды и в старом, и в новом стиле" + +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "строка слишком длинна для tsvector (%d Б, при максимуме %d)" + +#: tsearch/ts_locale.c:212 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "строка %d файла конфигурации \"%s\": \"%s\"" + +#: tsearch/ts_locale.c:329 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "преобразовать wchar_t в кодировку сервера не удалось: %m" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 +#: tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "слишком длинное слово для индексации" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 +#: tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "Слова длиннее %d символов игнорируются." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "неверное имя файла конфигурации текстового поиска \"%s\"" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "не удалось открыть файл стоп-слов \"%s\": %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "анализатор текстового поиска не поддерживает создание выдержек" + +#: tsearch/wparser_def.c:2585 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "нераспознанный параметр функции выдержки: \"%s\"" + +#: tsearch/wparser_def.c:2604 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "Значение MinWords должно быть меньше MaxWords" + +#: tsearch/wparser_def.c:2608 +#, c-format +msgid "MinWords should be positive" +msgstr "Значение MinWords должно быть положительным" + +#: tsearch/wparser_def.c:2612 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "Значение ShortWord должно быть >= 0" + +#: tsearch/wparser_def.c:2616 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "Значение MaxFragments должно быть >= 0" + +#: utils/adt/acl.c:171 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "слишком длинный идентификатор" + +#: utils/adt/acl.c:172 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "Идентификатор должен быть короче %d байт." + +#: utils/adt/acl.c:255 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "нераспознанное ключевое слово: \"%s\"" + +#: utils/adt/acl.c:256 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "Ключевым словом ACL должно быть \"group\" или \"user\"." + +#: utils/adt/acl.c:261 +#, c-format +msgid "missing name" +msgstr "отсутствует имя" + +#: utils/adt/acl.c:262 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "За ключевыми словами \"group\" или \"user\" должно следовать имя." + +#: utils/adt/acl.c:268 +#, c-format +msgid "missing \"=\" sign" +msgstr "отсутствует знак \"=\"" + +#: utils/adt/acl.c:321 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "неверный символ режима: должен быть один из \"%s\"" + +#: utils/adt/acl.c:343 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "за знаком \"/\" должно следовать имя" + +#: utils/adt/acl.c:351 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "назначившим права считается пользователь с ID %u" + +#: utils/adt/acl.c:537 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "Массив ACL содержит неверный тип данных" + +#: utils/adt/acl.c:541 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "Массивы ACL должны быть одномерными" + +#: utils/adt/acl.c:545 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "Массивы ACL не должны содержать значения null" + +#: utils/adt/acl.c:569 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "лишний мусор в конце спецификации ACL" + +#: utils/adt/acl.c:1204 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "привилегию назначения прав нельзя вернуть тому, кто назначил её вам" + +#: utils/adt/acl.c:1265 +#, c-format +msgid "dependent privileges exist" +msgstr "существуют зависимые права" + +#: utils/adt/acl.c:1266 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Используйте CASCADE, чтобы отозвать и их." + +#: utils/adt/acl.c:1520 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert больше не поддерживается" + +#: utils/adt/acl.c:1530 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove больше не поддерживается" + +#: utils/adt/acl.c:1616 utils/adt/acl.c:1670 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "нераспознанный тип прав: \"%s\"" + +#: utils/adt/acl.c:3470 utils/adt/regproc.c:103 utils/adt/regproc.c:278 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "функция \"%s\" не существует" + +#: utils/adt/acl.c:4946 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "нужно быть членом роли \"%s\"" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:933 +#: utils/adt/arrayfuncs.c:1533 utils/adt/arrayfuncs.c:3236 +#: utils/adt/arrayfuncs.c:3376 utils/adt/arrayfuncs.c:5911 +#: utils/adt/arrayfuncs.c:6252 utils/adt/arrayutils.c:93 +#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "размер массива превышает предел (%d)" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:645 utils/adt/json.c:740 +#: utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 +#: utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "не удалось определить тип входных данных" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "тип входных данных не является массивом" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1336 utils/adt/float.c:1243 utils/adt/float.c:1317 +#: utils/adt/float.c:3960 utils/adt/float.c:3974 utils/adt/int.c:759 +#: utils/adt/int.c:781 utils/adt/int.c:795 utils/adt/int.c:809 +#: utils/adt/int.c:840 utils/adt/int.c:861 utils/adt/int.c:978 +#: utils/adt/int.c:992 utils/adt/int.c:1006 utils/adt/int.c:1039 +#: utils/adt/int.c:1053 utils/adt/int.c:1067 utils/adt/int.c:1098 +#: utils/adt/int.c:1180 utils/adt/int.c:1244 utils/adt/int.c:1312 +#: utils/adt/int.c:1318 utils/adt/int8.c:1292 utils/adt/numeric.c:1559 +#: utils/adt/numeric.c:3435 utils/adt/varbit.c:1194 utils/adt/varbit.c:1582 +#: utils/adt/varlena.c:1097 utils/adt/varlena.c:3395 +#, c-format +msgid "integer out of range" +msgstr "целое вне диапазона" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "аргумент должен быть одномерным массивом или пустым" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "соединять несовместимые массивы нельзя" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "" +"Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Массивы с элементами типов %s и %s несовместимы для соединения." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Массивы с размерностями %d и %d несовместимы для соединения." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "" +"Arrays with differing element dimensions are not compatible for " +"concatenation." +msgstr "Массивы с разными размерностями элементов несовместимы для соединения." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Массивы с разными размерностями несовместимы для соединения." + +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "поиск элементов в многомерных массивах не поддерживается" + +#: utils/adt/array_userfuncs.c:686 +#, c-format +msgid "initial position must not be null" +msgstr "начальная позиция не может быть NULL" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 +#: utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:506 +#: utils/adt/arrayfuncs.c:517 utils/adt/arrayfuncs.c:532 +#: utils/adt/arrayfuncs.c:553 utils/adt/arrayfuncs.c:583 +#: utils/adt/arrayfuncs.c:590 utils/adt/arrayfuncs.c:598 +#: utils/adt/arrayfuncs.c:632 utils/adt/arrayfuncs.c:655 +#: utils/adt/arrayfuncs.c:675 utils/adt/arrayfuncs.c:787 +#: utils/adt/arrayfuncs.c:796 utils/adt/arrayfuncs.c:826 +#: utils/adt/arrayfuncs.c:841 utils/adt/arrayfuncs.c:894 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "ошибочный литерал массива: \"%s\"" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "За \"[\" должны следовать явно задаваемые размерности массива." + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "Отсутствует значение размерности массива." + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "После размерностей массива отсутствует \"%s\"." + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2884 +#: utils/adt/arrayfuncs.c:2916 utils/adt/arrayfuncs.c:2931 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "верхняя граница не может быть меньше нижней" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "Значение массива должно начинаться с \"{\" или указания размерности." + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "Содержимое массива должно начинаться с \"{\"." + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "Указанные размерности массива не соответствуют его содержимому." + +#: utils/adt/arrayfuncs.c:491 utils/adt/arrayfuncs.c:518 +#: utils/adt/rangetypes.c:2181 utils/adt/rangetypes.c:2189 +#: utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 +#, c-format +msgid "Unexpected end of input." +msgstr "Неожиданный конец ввода." + +#: utils/adt/arrayfuncs.c:507 utils/adt/arrayfuncs.c:554 +#: utils/adt/arrayfuncs.c:584 utils/adt/arrayfuncs.c:633 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "Неожиданный знак \"%c\"." + +#: utils/adt/arrayfuncs.c:533 utils/adt/arrayfuncs.c:656 +#, c-format +msgid "Unexpected array element." +msgstr "Неожиданный элемент массива." + +#: utils/adt/arrayfuncs.c:591 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "Непарный знак \"%c\"." + +#: utils/adt/arrayfuncs.c:599 utils/adt/jsonfuncs.c:2452 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "" +"Для многомерных массивов должны задаваться вложенные массивы с " +"соответствующими размерностями." + +#: utils/adt/arrayfuncs.c:676 +#, c-format +msgid "Junk after closing right brace." +msgstr "Мусор после закрывающей фигурной скобки." + +#: utils/adt/arrayfuncs.c:1298 utils/adt/arrayfuncs.c:3344 +#: utils/adt/arrayfuncs.c:5817 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "неверное число размерностей: %d" + +#: utils/adt/arrayfuncs.c:1309 +#, c-format +msgid "invalid array flags" +msgstr "неверные флаги массива" + +#: utils/adt/arrayfuncs.c:1317 +#, c-format +msgid "wrong element type" +msgstr "неверный тип элемента" + +#: utils/adt/arrayfuncs.c:1367 utils/adt/rangetypes.c:335 +#: utils/cache/lsyscache.c:2835 +#, c-format +msgid "no binary input function available for type %s" +msgstr "для типа %s нет функции ввода двоичных данных" + +#: utils/adt/arrayfuncs.c:1507 +#, c-format +msgid "improper binary format in array element %d" +msgstr "неподходящий двоичный формат в элементе массива %d" + +#: utils/adt/arrayfuncs.c:1588 utils/adt/rangetypes.c:340 +#: utils/cache/lsyscache.c:2868 +#, c-format +msgid "no binary output function available for type %s" +msgstr "для типа %s нет функции вывода двоичных данных" + +#: utils/adt/arrayfuncs.c:2066 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "разрезание массивов постоянной длины не поддерживается" + +#: utils/adt/arrayfuncs.c:2244 utils/adt/arrayfuncs.c:2266 +#: utils/adt/arrayfuncs.c:2315 utils/adt/arrayfuncs.c:2551 +#: utils/adt/arrayfuncs.c:2862 utils/adt/arrayfuncs.c:5803 +#: utils/adt/arrayfuncs.c:5829 utils/adt/arrayfuncs.c:5840 +#: utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 +#: utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4340 utils/adt/jsonfuncs.c:4490 +#: utils/adt/jsonfuncs.c:4602 utils/adt/jsonfuncs.c:4648 +#, c-format +msgid "wrong number of array subscripts" +msgstr "неверное число индексов массива" + +#: utils/adt/arrayfuncs.c:2249 utils/adt/arrayfuncs.c:2357 +#: utils/adt/arrayfuncs.c:2615 utils/adt/arrayfuncs.c:2921 +#, c-format +msgid "array subscript out of range" +msgstr "индекс массива вне диапазона" + +#: utils/adt/arrayfuncs.c:2254 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "нельзя присвоить значение null элементу массива фиксированной длины" + +#: utils/adt/arrayfuncs.c:2809 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "изменения в срезах массивов фиксированной длины не поддерживаются" + +#: utils/adt/arrayfuncs.c:2840 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "в указании среза массива должны быть заданы обе границы" + +#: utils/adt/arrayfuncs.c:2841 +#, c-format +msgid "" +"When assigning to a slice of an empty array value, slice boundaries must be " +"fully specified." +msgstr "" +"При присвоении значений срезу в пустом массиве, должны полностью задаваться " +"обе границы." + +#: utils/adt/arrayfuncs.c:2852 utils/adt/arrayfuncs.c:2947 +#, c-format +msgid "source array too small" +msgstr "исходный массив слишком мал" + +#: utils/adt/arrayfuncs.c:3500 +#, c-format +msgid "null array element not allowed in this context" +msgstr "элемент массива null недопустим в данном контексте" + +#: utils/adt/arrayfuncs.c:3602 utils/adt/arrayfuncs.c:3773 +#: utils/adt/arrayfuncs.c:4129 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "нельзя сравнивать массивы с элементами разных типов" + +#: utils/adt/arrayfuncs.c:3951 utils/adt/rangetypes.c:1254 +#: utils/adt/rangetypes.c:1318 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "не удалось найти функцию хеширования для типа %s" + +#: utils/adt/arrayfuncs.c:4044 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "не удалось найти функцию расширенного хеширования для типа %s" + +#: utils/adt/arrayfuncs.c:5221 +#, c-format +msgid "data type %s is not an array type" +msgstr "тип данных %s не является типом массива" + +#: utils/adt/arrayfuncs.c:5276 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "аккумулировать NULL-массивы нельзя" + +#: utils/adt/arrayfuncs.c:5304 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "аккумулировать пустые массивы нельзя" + +#: utils/adt/arrayfuncs.c:5331 utils/adt/arrayfuncs.c:5337 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "аккумулировать массивы различной размерности нельзя" + +#: utils/adt/arrayfuncs.c:5701 utils/adt/arrayfuncs.c:5741 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "массив размерностей или массив нижних границ не может быть null" + +#: utils/adt/arrayfuncs.c:5804 utils/adt/arrayfuncs.c:5830 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "Массив размерностей должен быть одномерным." + +#: utils/adt/arrayfuncs.c:5809 utils/adt/arrayfuncs.c:5835 +#, c-format +msgid "dimension values cannot be null" +msgstr "значения размерностей не могут быть null" + +#: utils/adt/arrayfuncs.c:5841 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "Массив нижних границ и массив размерностей имеют разные размеры." + +#: utils/adt/arrayfuncs.c:6117 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "удаление элементов из многомерных массивов не поддерживается" + +#: utils/adt/arrayfuncs.c:6394 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "границы должны задаваться одномерным массивом" + +#: utils/adt/arrayfuncs.c:6399 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "массив границ не должен содержать NULL" + +#: utils/adt/arrayutils.c:209 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "массив typmod должен иметь тип cstring[]" + +#: utils/adt/arrayutils.c:214 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "массив typmod должен быть одномерным" + +#: utils/adt/arrayutils.c:219 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "массив typmod не должен содержать элементы null" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "преобразование кодировки из %s в ASCII не поддерживается" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3757 +#: utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:295 +#: utils/adt/float.c:412 utils/adt/float.c:497 utils/adt/float.c:525 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 +#: utils/adt/geo_ops.c:1421 utils/adt/geo_ops.c:3476 utils/adt/geo_ops.c:4645 +#: utils/adt/geo_ops.c:4660 utils/adt/geo_ops.c:4667 utils/adt/int8.c:126 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:601 +#: utils/adt/numeric.c:628 utils/adt/numeric.c:6001 utils/adt/numeric.c:6025 +#: utils/adt/numeric.c:6049 utils/adt/numeric.c:6882 utils/adt/numeric.c:6908 +#: utils/adt/numutils.c:116 utils/adt/numutils.c:126 utils/adt/numutils.c:170 +#: utils/adt/numutils.c:246 utils/adt/numutils.c:322 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:73 utils/adt/tid.c:74 utils/adt/tid.c:82 +#: utils/adt/tid.c:90 utils/adt/timestamp.c:494 utils/adt/uuid.c:136 +#: utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "неверный синтаксис для типа %s: \"%s\"" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 +#: utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "значение \"%s\" вне диапазона для типа %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:104 utils/adt/int.c:824 utils/adt/int.c:940 +#: utils/adt/int.c:1020 utils/adt/int.c:1082 utils/adt/int.c:1120 +#: utils/adt/int.c:1148 utils/adt/int8.c:593 utils/adt/int8.c:651 +#: utils/adt/int8.c:978 utils/adt/int8.c:1058 utils/adt/int8.c:1120 +#: utils/adt/int8.c:1200 utils/adt/numeric.c:7446 utils/adt/numeric.c:7736 +#: utils/adt/numeric.c:9318 utils/adt/timestamp.c:3275 +#, c-format +msgid "division by zero" +msgstr "деление на ноль" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "значение \"char\" вне диапазона" + +#: utils/adt/date.c:61 utils/adt/timestamp.c:95 utils/adt/varbit.c:104 +#: utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "неверный модификатор типа" + +#: utils/adt/date.c:73 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "TIME(%d)%s: точность должна быть неотрицательной" + +#: utils/adt/date.c:79 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%s: точность уменьшена до дозволенного максимума: %d" + +#: utils/adt/date.c:158 utils/adt/date.c:166 utils/adt/formatting.c:4210 +#: utils/adt/formatting.c:4219 utils/adt/formatting.c:4325 +#: utils/adt/formatting.c:4335 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "дата вне диапазона: \"%s\"" + +#: utils/adt/date.c:213 utils/adt/date.c:525 utils/adt/date.c:549 +#: utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "дата вне диапазона" + +#: utils/adt/date.c:259 utils/adt/timestamp.c:574 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "значение поля типа date вне диапазона: %d-%02d-%02d" + +#: utils/adt/date.c:266 utils/adt/date.c:275 utils/adt/timestamp.c:580 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "дата вне диапазона: %d-%02d-%02d" + +#: utils/adt/date.c:313 utils/adt/date.c:336 utils/adt/date.c:362 +#: utils/adt/date.c:1142 utils/adt/date.c:1188 utils/adt/date.c:1744 +#: utils/adt/date.c:1775 utils/adt/date.c:1804 utils/adt/date.c:2636 +#: utils/adt/datetime.c:1655 utils/adt/formatting.c:4067 +#: utils/adt/formatting.c:4099 utils/adt/formatting.c:4179 +#: utils/adt/formatting.c:4301 utils/adt/json.c:418 utils/adt/json.c:457 +#: utils/adt/timestamp.c:222 utils/adt/timestamp.c:254 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2854 utils/adt/timestamp.c:2875 +#: utils/adt/timestamp.c:2888 utils/adt/timestamp.c:2897 +#: utils/adt/timestamp.c:2905 utils/adt/timestamp.c:2960 +#: utils/adt/timestamp.c:2983 utils/adt/timestamp.c:2996 +#: utils/adt/timestamp.c:3007 utils/adt/timestamp.c:3015 +#: utils/adt/timestamp.c:3675 utils/adt/timestamp.c:3800 +#: utils/adt/timestamp.c:3841 utils/adt/timestamp.c:3931 +#: utils/adt/timestamp.c:3975 utils/adt/timestamp.c:4078 +#: utils/adt/timestamp.c:4563 utils/adt/timestamp.c:4759 +#: utils/adt/timestamp.c:5086 utils/adt/timestamp.c:5100 +#: utils/adt/timestamp.c:5105 utils/adt/timestamp.c:5119 +#: utils/adt/timestamp.c:5152 utils/adt/timestamp.c:5239 +#: utils/adt/timestamp.c:5280 utils/adt/timestamp.c:5284 +#: utils/adt/timestamp.c:5353 utils/adt/timestamp.c:5357 +#: utils/adt/timestamp.c:5371 utils/adt/timestamp.c:5405 utils/adt/xml.c:2232 +#: utils/adt/xml.c:2239 utils/adt/xml.c:2259 utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "timestamp вне диапазона" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "вычитать бесконечные даты нельзя" + +#: utils/adt/date.c:598 utils/adt/date.c:661 utils/adt/date.c:697 +#: utils/adt/date.c:2673 utils/adt/date.c:2683 +#, c-format +msgid "date out of range for timestamp" +msgstr "дата вне диапазона для типа timestamp" + +#: utils/adt/date.c:1361 utils/adt/date.c:2131 utils/adt/formatting.c:4387 +#, c-format +msgid "time out of range" +msgstr "время вне диапазона" + +#: utils/adt/date.c:1413 utils/adt/timestamp.c:589 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "значение поля типа time вне диапазона: %d:%02d:%02g" + +#: utils/adt/date.c:1933 utils/adt/date.c:2435 utils/adt/float.c:1071 +#: utils/adt/float.c:1140 utils/adt/int.c:616 utils/adt/int.c:663 +#: utils/adt/int.c:698 utils/adt/int8.c:492 utils/adt/numeric.c:2197 +#: utils/adt/timestamp.c:3324 utils/adt/timestamp.c:3355 +#: utils/adt/timestamp.c:3386 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "неверное смещение PRECEDING или FOLLOWING в оконной функции" + +#: utils/adt/date.c:2018 utils/adt/date.c:2031 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "\"время\" содержит нераспознанные единицы \"%s\"" + +#: utils/adt/date.c:2139 +#, c-format +msgid "time zone displacement out of range" +msgstr "смещение часового пояса вне диапазона" + +#: utils/adt/date.c:2768 utils/adt/date.c:2781 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "\"время с часовым поясом\" содержит нераспознанные единицы \"%s\"" + +#: utils/adt/date.c:2854 utils/adt/datetime.c:906 utils/adt/datetime.c:1813 +#: utils/adt/datetime.c:4601 utils/adt/timestamp.c:513 +#: utils/adt/timestamp.c:540 utils/adt/timestamp.c:4161 +#: utils/adt/timestamp.c:5111 utils/adt/timestamp.c:5363 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "часовой пояс \"%s\" не распознан" + +#: utils/adt/date.c:2886 utils/adt/timestamp.c:5141 utils/adt/timestamp.c:5394 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "" +"интервал \"%s\", задающий часовой пояс, не должен содержать дней или месяцев" + +#: utils/adt/datetime.c:3730 utils/adt/datetime.c:3737 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "значение поля типа date/time вне диапазона: \"%s\"" + +#: utils/adt/datetime.c:3739 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Возможно, вам нужно изменить настройку \"datestyle\"." + +#: utils/adt/datetime.c:3744 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "значение поля interval вне диапазона: \"%s\"" + +#: utils/adt/datetime.c:3750 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "смещение часового пояса вне диапазона: \"%s\"" + +#: utils/adt/datetime.c:4603 +#, c-format +msgid "" +"This time zone name appears in the configuration file for time zone " +"abbreviation \"%s\"." +msgstr "" +"Это имя часового пояса фигурирует в файле конфигурации часового пояса с " +"кодом \"%s\"." + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "неверный указатель Datum" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "некорректная величина: \"%s\"" + +#: utils/adt/dbsize.c:828 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "Неверная единица измерения величины: \"%s\"." + +#: utils/adt/dbsize.c:829 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "" +"Допустимые единицы измерения: \"bytes\", \"kB\", \"MB\", \"GB\" и \"TB\"." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "тип \"%s\" не является доменом" + +#: utils/adt/encode.c:64 utils/adt/encode.c:112 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "нераспознанная кодировка: \"%s\"" + +#: utils/adt/encode.c:78 +#, c-format +msgid "result of encoding conversion is too large" +msgstr "результат кодирования слишком объёмный" + +#: utils/adt/encode.c:126 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "результат декодирования слишком объёмный" + +#: utils/adt/encode.c:184 +#, c-format +msgid "invalid hexadecimal digit: \"%c\"" +msgstr "неверная шестнадцатеричная цифра: \"%c\"" + +#: utils/adt/encode.c:212 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "неверные шестнадцатеричные данные: нечётное число цифр" + +#: utils/adt/encode.c:329 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "неожиданный знак \"=\" при декодировании base64" + +#: utils/adt/encode.c:341 +#, c-format +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "неверный символ \"%c\" при декодировании base64" + +#: utils/adt/encode.c:361 +#, c-format +msgid "invalid base64 end sequence" +msgstr "неверная конечная последовательность base64" + +#: utils/adt/encode.c:362 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "" +"Входные данные лишены выравнивания, обрезаны или повреждены иным образом." + +#: utils/adt/encode.c:476 utils/adt/encode.c:541 utils/adt/jsonfuncs.c:619 +#: utils/adt/varlena.c:319 utils/adt/varlena.c:360 jsonpath_gram.y:528 +#: jsonpath_scan.l:519 jsonpath_scan.l:530 jsonpath_scan.l:540 +#: jsonpath_scan.l:582 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "неверный синтаксис для типа %s" + +#: utils/adt/enum.c:100 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "небезопасное использование нового значения \"%s\" типа-перечисления %s" + +#: utils/adt/enum.c:103 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "" +"Новые значения перечисления должны быть зафиксированы перед использованием." + +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 +#: utils/adt/enum.c:199 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "неверное значение для перечисления %s: \"%s\"" + +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "неверное внутреннее значение для перечисления: %u" + +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 +#: utils/adt/enum.c:535 +#, c-format +msgid "could not determine actual enum type" +msgstr "не удалось определить фактический тип перечисления" + +#: utils/adt/enum.c:454 utils/adt/enum.c:483 +#, c-format +msgid "enum %s contains no values" +msgstr "перечисление %s не содержит значений" + +#: utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 +#: utils/cache/typcache.c:1632 utils/cache/typcache.c:1788 +#: utils/cache/typcache.c:1918 utils/fmgr/funcapi.c:456 +#, c-format +msgid "type %s is not composite" +msgstr "тип %s не является составным" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "значение вне диапазона: переполнение" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "значение вне диапазона: антипереполнение" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "\"%s\" вне диапазона для типа real" + +#: utils/adt/float.c:489 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "\"%s\" вне диапазона для типа double precision" + +#: utils/adt/float.c:1268 utils/adt/float.c:1342 utils/adt/int.c:336 +#: utils/adt/int.c:874 utils/adt/int.c:896 utils/adt/int.c:910 +#: utils/adt/int.c:924 utils/adt/int.c:956 utils/adt/int.c:1194 +#: utils/adt/int8.c:1313 utils/adt/numeric.c:3553 utils/adt/numeric.c:3562 +#, c-format +msgid "smallint out of range" +msgstr "smallint вне диапазона" + +#: utils/adt/float.c:1468 utils/adt/numeric.c:8329 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "извлечь квадратный корень отрицательного числа нельзя" + +#: utils/adt/float.c:1536 utils/adt/numeric.c:3239 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "ноль в отрицательной степени даёт неопределённость" + +#: utils/adt/float.c:1540 utils/adt/numeric.c:3245 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "отрицательное число в дробной степени даёт комплексный результат" + +#: utils/adt/float.c:1614 utils/adt/float.c:1647 utils/adt/numeric.c:8993 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "вычислить логарифм нуля нельзя" + +#: utils/adt/float.c:1618 utils/adt/float.c:1651 utils/adt/numeric.c:8997 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "вычислить логарифм отрицательного числа нельзя" + +#: utils/adt/float.c:1684 utils/adt/float.c:1715 utils/adt/float.c:1810 +#: utils/adt/float.c:1837 utils/adt/float.c:1865 utils/adt/float.c:1892 +#: utils/adt/float.c:2039 utils/adt/float.c:2076 utils/adt/float.c:2246 +#: utils/adt/float.c:2302 utils/adt/float.c:2367 utils/adt/float.c:2424 +#: utils/adt/float.c:2615 utils/adt/float.c:2639 +#, c-format +msgid "input is out of range" +msgstr "введённое значение вне диапазона" + +#: utils/adt/float.c:2706 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "параметр setseed %g вне допустимого диапазона [-1,1]" + +#: utils/adt/float.c:3938 utils/adt/numeric.c:1509 +#, c-format +msgid "count must be greater than zero" +msgstr "счётчик должен быть больше нуля" + +#: utils/adt/float.c:3943 utils/adt/numeric.c:1516 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "операнд, нижняя и верхняя границы не могут быть NaN" + +#: utils/adt/float.c:3949 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "нижняя и верхняя границы должны быть конечными" + +#: utils/adt/float.c:3983 utils/adt/numeric.c:1529 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "нижняя граница не может равняться верхней" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "неправильная спецификация формата для целого числа" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "Интервалы не привязываются к определённым календарным датам." + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "\"EEEE\" может быть только последним шаблоном" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "\"9\" должна стоять до \"PR\"" + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "\"0\" должен стоять до \"PR\"" + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "многочисленные десятичные точки" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "нельзя использовать \"V\" вместе с десятичной точкой" + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "нельзя использовать \"S\" дважды" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "нельзя использовать \"S\" вместе с \"PL\"/\"MI\"/\"SG\"/\"PR\"" + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "нельзя использовать \"S\" вместе с \"MI\"" + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "нельзя использовать \"S\" вместе с \"PL\"" + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "нельзя использовать \"S\" вместе с \"SG\"" + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "нельзя использовать \"PR\" вместе с \"S\"/\"PL\"/\"MI\"/\"SG\"" + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "нельзя использовать \"EEEE\" дважды" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "\"EEEE\" несовместим с другими форматами" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "" +"\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "" +"\"EEEE\" может использоваться только с шаблонами цифр и десятичной точки." + +#: utils/adt/formatting.c:1394 +#, c-format +msgid "invalid datetime format separator: \"%s\"" +msgstr "неверный разделитель в формате datetime: \"%s\"" + +#: utils/adt/formatting.c:1522 +#, c-format +msgid "\"%s\" is not a number" +msgstr "\"%s\" не является числом" + +#: utils/adt/formatting.c:1600 +#, c-format +msgid "case conversion failed: %s" +msgstr "преобразовать регистр не удалось: %s" + +#: utils/adt/formatting.c:1665 utils/adt/formatting.c:1789 +#: utils/adt/formatting.c:1914 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "" +"не удалось определить, какое правило сортировки использовать для функции %s" + +#: utils/adt/formatting.c:2286 +#, c-format +msgid "invalid combination of date conventions" +msgstr "неверное сочетание стилей дат" + +#: utils/adt/formatting.c:2287 +#, c-format +msgid "" +"Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "" +"Не смешивайте Григорианский стиль дат (недель) с ISO в одном шаблоне " +"форматирования." + +#: utils/adt/formatting.c:2310 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "конфликтующие значения поля \"%s\" в строке форматирования" + +#: utils/adt/formatting.c:2313 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "Это значение противоречит предыдущему значению поля того же типа." + +#: utils/adt/formatting.c:2384 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "входная строка короче, чем требует поле форматирования \"%s\"" + +#: utils/adt/formatting.c:2387 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "Требуется символов: %d, а осталось только %d." + +#: utils/adt/formatting.c:2390 utils/adt/formatting.c:2405 +#, c-format +msgid "" +"If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "" +"Если входная строка имеет переменную длину, попробуйте использовать " +"модификатор \"FM\"." + +#: utils/adt/formatting.c:2400 utils/adt/formatting.c:2414 +#: utils/adt/formatting.c:2637 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "неверное значение \"%s\" для \"%s\"" + +#: utils/adt/formatting.c:2402 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "Поле должно поглотить символов: %d, но удалось разобрать только %d." + +#: utils/adt/formatting.c:2416 +#, c-format +msgid "Value must be an integer." +msgstr "Значение должно быть целым числом." + +#: utils/adt/formatting.c:2421 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "значение \"%s\" во входной строке вне диапазона" + +#: utils/adt/formatting.c:2423 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "Значение должно быть в интервале %d..%d." + +#: utils/adt/formatting.c:2639 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "" +"Данное значение не соответствует ни одному из допустимых значений для этого " +"поля." + +#: utils/adt/formatting.c:2856 utils/adt/formatting.c:2876 +#: utils/adt/formatting.c:2896 utils/adt/formatting.c:2916 +#: utils/adt/formatting.c:2935 utils/adt/formatting.c:2954 +#: utils/adt/formatting.c:2978 utils/adt/formatting.c:2996 +#: utils/adt/formatting.c:3014 utils/adt/formatting.c:3032 +#: utils/adt/formatting.c:3049 utils/adt/formatting.c:3066 +#, c-format +msgid "localized string format value too long" +msgstr "слишком длинное значение формата локализованной строки" + +#: utils/adt/formatting.c:3300 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "нет соответствия для заданного в формате разделителя \"%c\"" + +#: utils/adt/formatting.c:3361 +#, c-format +msgid "unmatched format character \"%s\"" +msgstr "нет соответствия для заданного в формате символа \"%s\"" + +#: utils/adt/formatting.c:3467 utils/adt/formatting.c:3811 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "поле форматирования \"%s\" поддерживается только в функции to_char" + +#: utils/adt/formatting.c:3642 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "ошибка синтаксиса в значении для шаблона \"Y,YYY\"" + +#: utils/adt/formatting.c:3728 +#, c-format +msgid "input string is too short for datetime format" +msgstr "входная строка короче, чем требует формат datetime" + +#: utils/adt/formatting.c:3736 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "" +"после разбора формата datetime во входной строке остались дополнительные " +"символы" + +#: utils/adt/formatting.c:4281 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "во входной строке для типа timestamptz нет указания часового пояса" + +#: utils/adt/formatting.c:4287 +#, c-format +msgid "timestamptz out of range" +msgstr "значение timestamptz вне диапазона" + +#: utils/adt/formatting.c:4315 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "в формате datetime указан часовой пояс, но отсутствует время" + +#: utils/adt/formatting.c:4367 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "во входной строке для типа timetz нет указания часового пояса" + +#: utils/adt/formatting.c:4373 +#, c-format +msgid "timetz out of range" +msgstr "значение timetz вне диапазона" + +#: utils/adt/formatting.c:4399 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "в формате datetime нет ни даты, ни времени" + +#: utils/adt/formatting.c:4532 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "час \"%d\" не соответствует 12-часовому формату времени" + +#: utils/adt/formatting.c:4534 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Используйте 24-часовой формат или передавайте часы от 1 до 12." + +#: utils/adt/formatting.c:4645 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "нельзя рассчитать день года без информации о годе" + +#: utils/adt/formatting.c:5564 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "\"EEEE\" не поддерживается при вводе" + +#: utils/adt/formatting.c:5576 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "\"RN\" не поддерживается при вводе" + +#: utils/adt/genfile.c:75 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "ссылка на родительский каталог (\"..\") недопустима" + +#: utils/adt/genfile.c:86 +#, c-format +msgid "absolute path not allowed" +msgstr "абсолютный путь недопустим" + +#: utils/adt/genfile.c:91 +#, c-format +msgid "path must be in or below the current directory" +msgstr "путь должен указывать в текущий или вложенный каталог" + +#: utils/adt/genfile.c:116 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 +#, c-format +msgid "requested length too large" +msgstr "запрошенная длина слишком велика" + +#: utils/adt/genfile.c:133 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "не удалось переместиться в файле \"%s\": %m" + +#: utils/adt/genfile.c:174 +#, c-format +msgid "file length too large" +msgstr "длина файла слишком велика" + +#: utils/adt/genfile.c:251 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "читать файлы, используя adminpack 1.0, может только суперпользователь" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "неверное определение линии: A и B вдвоём не могут быть нулевыми" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "неверное определение линии: требуются две различных точки" + +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3486 utils/adt/geo_ops.c:4354 +#: utils/adt/geo_ops.c:5248 +#, c-format +msgid "too many points requested" +msgstr "запрошено слишком много точек" + +#: utils/adt/geo_ops.c:1461 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "недопустимое число точек во внешнем представлении типа \"path\"" + +#: utils/adt/geo_ops.c:2537 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "функция \"dist_lb\" не реализована" + +#: utils/adt/geo_ops.c:2556 +#, c-format +msgid "function \"dist_bl\" not implemented" +msgstr "функция \"dist_bl\" не реализована" + +#: utils/adt/geo_ops.c:2975 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "функция \"close_sl\" не реализована" + +#: utils/adt/geo_ops.c:3122 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "функция \"close_lb\" не реализована" + +#: utils/adt/geo_ops.c:3533 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "недопустимое число точек во внешнем представлении типа \"polygon\"" + +#: utils/adt/geo_ops.c:4069 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "функция \"poly_distance\" не реализована" + +#: utils/adt/geo_ops.c:4446 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "функция \"path_center\" не реализована" + +#: utils/adt/geo_ops.c:4463 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "открытый путь нельзя преобразовать во многоугольник" + +#: utils/adt/geo_ops.c:4713 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "недопустимый радиус во внешнем представлении типа \"circle\"" + +#: utils/adt/geo_ops.c:5234 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "круг с нулевым радиусом нельзя преобразовать в многоугольник" + +#: utils/adt/geo_ops.c:5239 +#, c-format +msgid "must request at least 2 points" +msgstr "точек должно быть минимум 2" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector содержит слишком много элементов" + +#: utils/adt/int.c:239 +#, c-format +msgid "invalid int2vector data" +msgstr "неверные данные int2vector" + +#: utils/adt/int.c:245 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector содержит слишком много элементов" + +#: utils/adt/int.c:1510 utils/adt/int8.c:1439 utils/adt/numeric.c:1417 +#: utils/adt/timestamp.c:5456 utils/adt/timestamp.c:5536 +#, c-format +msgid "step size cannot equal zero" +msgstr "размер шага не может быть нулевым" + +#: utils/adt/int8.c:527 utils/adt/int8.c:550 utils/adt/int8.c:564 +#: utils/adt/int8.c:578 utils/adt/int8.c:609 utils/adt/int8.c:633 +#: utils/adt/int8.c:715 utils/adt/int8.c:783 utils/adt/int8.c:789 +#: utils/adt/int8.c:815 utils/adt/int8.c:829 utils/adt/int8.c:853 +#: utils/adt/int8.c:866 utils/adt/int8.c:935 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:994 utils/adt/int8.c:1016 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1077 +#: utils/adt/int8.c:1091 utils/adt/int8.c:1105 utils/adt/int8.c:1136 +#: utils/adt/int8.c:1158 utils/adt/int8.c:1172 utils/adt/int8.c:1186 +#: utils/adt/int8.c:1348 utils/adt/int8.c:1383 utils/adt/numeric.c:3508 +#: utils/adt/varbit.c:1662 +#, c-format +msgid "bigint out of range" +msgstr "bigint вне диапазона" + +#: utils/adt/int8.c:1396 +#, c-format +msgid "OID out of range" +msgstr "OID вне диапазона" + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "" +"значением ключа должен быть скаляр (не массив, композитный тип или json)" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1813 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "не удалось определить тип данных аргумента %d" + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "имя поля не может быть NULL" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "в списке аргументов должно быть чётное число элементов" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "Аргументы %s должны состоять из пар ключ-значение." + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "аргумент %d не может быть NULL" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "Ключи объектов должны быть текстовыми." + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "массив должен иметь два столбца" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 +#: utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "значение null не может быть ключом объекта" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "неподходящие размерности массива" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "слишком длинная строка для представления в виде строки jsonb" + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "" +"Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "" +"Из-за ограничений реализации строки jsonb не могут быть длиннее %d байт." + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "аргумент %d: ключ не может быть NULL" + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "ключи объектов должны быть строковыми" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "привести значение jsonb null к типу %s нельзя" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "привести строку jsonb к типу %s нельзя" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "привести числовое значение jsonb к типу %s нельзя" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "привести логическое значение jsonb к типу %s нельзя" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "привести массив jsonb к типу %s нельзя" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "привести объект jsonb к типу %s нельзя" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "привести массив или объект jsonb к типу %s нельзя" + +#: utils/adt/jsonb_util.c:699 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "число пар объекта jsonb превышает предел (%zu)" + +#: utils/adt/jsonb_util.c:740 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "число элементов массива jsonb превышает предел (%zu)" + +#: utils/adt/jsonb_util.c:1614 utils/adt/jsonb_util.c:1634 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "общий размер элементов массива jsonb превышает предел (%u байт)" + +#: utils/adt/jsonb_util.c:1695 utils/adt/jsonb_util.c:1730 +#: utils/adt/jsonb_util.c:1750 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "общий размер элементов объекта jsonb превышает предел (%u байт)" + +#: utils/adt/jsonfuncs.c:551 utils/adt/jsonfuncs.c:796 +#: utils/adt/jsonfuncs.c:2330 utils/adt/jsonfuncs.c:2770 +#: utils/adt/jsonfuncs.c:3560 utils/adt/jsonfuncs.c:3891 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "вызывать %s со скаляром нельзя" + +#: utils/adt/jsonfuncs.c:556 utils/adt/jsonfuncs.c:783 +#: utils/adt/jsonfuncs.c:2772 utils/adt/jsonfuncs.c:3549 +#, c-format +msgid "cannot call %s on an array" +msgstr "вызывать %s с массивом нельзя" + +#: utils/adt/jsonfuncs.c:613 jsonpath_scan.l:498 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "неподдерживаемая спецпоследовательность Unicode" + +#: utils/adt/jsonfuncs.c:692 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "данные JSON, строка %d: %s%s%s" + +#: utils/adt/jsonfuncs.c:1682 utils/adt/jsonfuncs.c:1717 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "получить длину скаляра нельзя" + +#: utils/adt/jsonfuncs.c:1686 utils/adt/jsonfuncs.c:1705 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "получить длину массива для не массива нельзя" + +#: utils/adt/jsonfuncs.c:1782 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "вызывать %s с не объектом нельзя" + +#: utils/adt/jsonfuncs.c:2021 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "извлечь массив в виде объекта нельзя" + +#: utils/adt/jsonfuncs.c:2033 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "извлечь скаляр нельзя" + +#: utils/adt/jsonfuncs.c:2079 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "извлечь элементы из скаляра нельзя" + +#: utils/adt/jsonfuncs.c:2083 +#, c-format +msgid "cannot extract elements from an object" +msgstr "извлечь элементы из объекта нельзя" + +#: utils/adt/jsonfuncs.c:2317 utils/adt/jsonfuncs.c:3775 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "вызывать %s с не массивом нельзя" + +#: utils/adt/jsonfuncs.c:2387 utils/adt/jsonfuncs.c:2392 +#: utils/adt/jsonfuncs.c:2409 utils/adt/jsonfuncs.c:2415 +#, c-format +msgid "expected JSON array" +msgstr "ожидался массив JSON" + +#: utils/adt/jsonfuncs.c:2388 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Проверьте значение ключа \"%s\"." + +#: utils/adt/jsonfuncs.c:2410 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Проверьте элемент массива %s ключа \"%s\"." + +#: utils/adt/jsonfuncs.c:2416 +#, c-format +msgid "See the array element %s." +msgstr "Проверьте элемент массива %s." + +#: utils/adt/jsonfuncs.c:2451 +#, c-format +msgid "malformed JSON array" +msgstr "неправильный массив JSON" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3278 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "первым аргументом %s должен быть кортеж" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3302 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "не удалось определить тип строки для результата %s" + +#: utils/adt/jsonfuncs.c:3304 +#, c-format +msgid "" +"Provide a non-null record argument, or call the function in the FROM clause " +"using a column definition list." +msgstr "" +"Передайте отличный от NULL аргумент-запись или вызовите эту функцию в " +"предложении FROM, используя список с определениями столбцов." + +#: utils/adt/jsonfuncs.c:3792 utils/adt/jsonfuncs.c:3873 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "аргументом %s должен быть массив объектов" + +#: utils/adt/jsonfuncs.c:3825 +#, c-format +msgid "cannot call %s on an object" +msgstr "вызывать %s с объектом нельзя" + +#: utils/adt/jsonfuncs.c:4286 utils/adt/jsonfuncs.c:4345 +#: utils/adt/jsonfuncs.c:4425 +#, c-format +msgid "cannot delete from scalar" +msgstr "удаление из скаляра невозможно" + +#: utils/adt/jsonfuncs.c:4430 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "удаление из объекта по числовому индексу невозможно" + +#: utils/adt/jsonfuncs.c:4495 utils/adt/jsonfuncs.c:4653 +#, c-format +msgid "cannot set path in scalar" +msgstr "задать путь в скаляре нельзя" + +#: utils/adt/jsonfuncs.c:4537 utils/adt/jsonfuncs.c:4579 +#, c-format +msgid "" +"null_value_treatment must be \"delete_key\", \"return_target\", " +"\"use_json_null\", or \"raise_exception\"" +msgstr "" +"значением null_value_treatment должно быть \"delete_key\", \"return_target" +"\", \"use_json_null\" или \"raise_exception\"" + +#: utils/adt/jsonfuncs.c:4550 +#, c-format +msgid "JSON value must not be null" +msgstr "значение JSON не может быть NULL" + +#: utils/adt/jsonfuncs.c:4551 +#, c-format +msgid "" +"Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "" +"Выдано исключение, так как значением null_value_treatment является " +"\"raise_exception\"." + +#: utils/adt/jsonfuncs.c:4552 +#, c-format +msgid "" +"To avoid, either change the null_value_treatment argument or ensure that an " +"SQL NULL is not passed." +msgstr "" +"Чтобы исключения не было, либо измените аргумент null_value_treatment, либо " +"не допускайте передачи SQL NULL." + +#: utils/adt/jsonfuncs.c:4607 +#, c-format +msgid "cannot delete path in scalar" +msgstr "удалить путь в скаляре нельзя" + +#: utils/adt/jsonfuncs.c:4805 +#, c-format +msgid "path element at position %d is null" +msgstr "элемент пути в позиции %d равен NULL" + +#: utils/adt/jsonfuncs.c:4891 +#, c-format +msgid "cannot replace existing key" +msgstr "заменить существующий ключ нельзя" + +#: utils/adt/jsonfuncs.c:4892 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "Попробуйте применить функцию jsonb_set для замены значения ключа." + +#: utils/adt/jsonfuncs.c:4974 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "элемент пути в позиции %d - не целочисленный: \"%s\"" + +#: utils/adt/jsonfuncs.c:5093 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "неверный тип флага, допускаются только массивы и скаляры" + +#: utils/adt/jsonfuncs.c:5100 +#, c-format +msgid "flag array element is not a string" +msgstr "элемент массива флагов не является строкой" + +#: utils/adt/jsonfuncs.c:5101 utils/adt/jsonfuncs.c:5123 +#, c-format +msgid "" +"Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all" +"\"." +msgstr "" +"Допустимые значения: \"string\", \"numeric\", \"boolean\", \"key\" и \"all\"." + +#: utils/adt/jsonfuncs.c:5121 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "неверный флаг в массиве флагов: \"%s\"" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ не допускается в корневых выражениях" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST принимается только в качестве индекса массива" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "ожидался единственный булевский результат" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "аргумент \"vars\" не является объектом" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "" +"Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "" +"Параметры jsonpath должны передаваться в виде пар ключ-значение в объекте " +"\"vars\"." + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "JSON-объект не содержит ключ \"%s\"" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "" +"выражение обращения к члену в jsonpath может применяться только к объекту" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "" +"выражение обращения по звёздочке в jsonpath может применяться только к " +"массиву" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "индекс массива в jsonpath вне диапазона" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "" +"выражение обращения к массиву в jsonpath может применяться только к массиву" + +#: utils/adt/jsonpath_exec.c:874 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "" +"выражение обращения по звёздочке в jsonpath может применяться только к " +"объекту" + +# skip-rule: space-before-period +#: utils/adt/jsonpath_exec.c:1004 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "метод .%s() в jsonpath может применяться только к массиву" + +#: utils/adt/jsonpath_exec.c:1059 +#, c-format +msgid "" +"numeric argument of jsonpath item method .%s() is out of range for type " +"double precision" +msgstr "" +"числовой аргумент метода элемента jsonpath .%s() вне диапазона для типа " +"double precision" + +#: utils/adt/jsonpath_exec.c:1080 +#, c-format +msgid "" +"string argument of jsonpath item method .%s() is not a valid representation " +"of a double precision number" +msgstr "" +"строковый аргумент метода элемента jsonpath .%s() не является представлением " +"значения double precision" + +# skip-rule: space-before-period +#: utils/adt/jsonpath_exec.c:1093 +#, c-format +msgid "" +"jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "" +"метод .%s() в jsonpath может применяться только к строковому или числовому " +"значению" + +#: utils/adt/jsonpath_exec.c:1583 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "" +"левый операнд оператора %s в jsonpath не является одним числовым значением" + +#: utils/adt/jsonpath_exec.c:1590 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "" +"правый операнд оператора %s в jsonpath не является одним числовым значением" + +#: utils/adt/jsonpath_exec.c:1658 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "" +"операнд унарного оператора %s в jsonpath не является числовым значением" + +# skip-rule: space-before-period +#: utils/adt/jsonpath_exec.c:1756 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "метод .%s() в jsonpath может применяться только к числовому значению" + +# skip-rule: space-before-period +#: utils/adt/jsonpath_exec.c:1796 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "метод .%s() в jsonpath может применяться только к строке" + +#: utils/adt/jsonpath_exec.c:1890 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "формат datetime не распознан: \"%s\"" + +#: utils/adt/jsonpath_exec.c:1892 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "" +"Воспользуйтесь аргументом datetime для указания формата входных данных." + +# skip-rule: space-before-period +#: utils/adt/jsonpath_exec.c:1960 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "метод .%s() в jsonpath может применяться только к объекту" + +#: utils/adt/jsonpath_exec.c:2143 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "не удалось найти в jsonpath переменную \"%s\"" + +#: utils/adt/jsonpath_exec.c:2407 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "индекс элемента в jsonpath не является одним числовым значением" + +#: utils/adt/jsonpath_exec.c:2419 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "индекс массива в jsonpath вне целочисленного диапазона" + +#: utils/adt/jsonpath_exec.c:2596 +#, c-format +msgid "cannot convert value from %s to %s without time zone usage" +msgstr "значение %s нельзя преобразовать в %s без сведений о часовом поясе" + +#: utils/adt/jsonpath_exec.c:2598 +#, c-format +msgid "Use *_tz() function for time zone support." +msgstr "Для передачи часового пояса используйте функцию *_tz()." + +# well-spelled: симв +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "длина аргумента levenshtein() превышает максимум (%d симв.)" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "недетерминированные правила сортировки не поддерживаются для LIKE" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "не удалось определить, какой порядок сортировки использовать для ILIKE" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "недетерминированные правила сортировки не поддерживаются для ILIKE" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "шаблон LIKE не должен заканчиваться защитным символом" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "неверный защитный символ" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "Защитный символ должен быть пустым или состоять из одного байта." + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "регистронезависимое сравнение не поддерживается для типа bytea" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "сравнение с регулярными выражениями не поддерживается для типа bytea" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "неверный октет в значении типа macaddr: \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "значение в macaddr8 не допускает преобразование в macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "" +"Only addresses that have FF and FE as values in the 4th and 5th bytes from " +"the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted " +"from macaddr8 to macaddr." +msgstr "" +"Преобразование из macaddr8 в macaddr возможно только для адресов, содержащих " +"FF и FE в 4-ом и 5-ом байтах слева, например xx:xx:xx:ff:fe:xx:xx:xx." + +#: utils/adt/misc.c:240 +#, c-format +msgid "global tablespace never has databases" +msgstr "в табличном пространстве global никогда не было баз данных" + +#: utils/adt/misc.c:262 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u - это не OID табличного пространства" + +#: utils/adt/misc.c:448 +msgid "unreserved" +msgstr "не зарезервировано" + +#: utils/adt/misc.c:452 +msgid "unreserved (cannot be function or type name)" +msgstr "не зарезервировано (но не может быть именем типа или функции)" + +#: utils/adt/misc.c:456 +msgid "reserved (can be function or type name)" +msgstr "зарезервировано (но может быть именем типа или функции)" + +#: utils/adt/misc.c:460 +msgid "reserved" +msgstr "зарезервировано" + +#: utils/adt/misc.c:634 utils/adt/misc.c:648 utils/adt/misc.c:687 +#: utils/adt/misc.c:693 utils/adt/misc.c:699 utils/adt/misc.c:722 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "строка не является допустимым идентификатором: \"%s\"" + +#: utils/adt/misc.c:636 +#, c-format +msgid "String has unclosed double quotes." +msgstr "В строке не закрыты кавычки." + +#: utils/adt/misc.c:650 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "Идентификатор в кавычках не может быть пустым." + +#: utils/adt/misc.c:689 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "Перед \".\" нет допустимого идентификатора." + +#: utils/adt/misc.c:695 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "После \".\" нет допустимого идентификатора." + +#: utils/adt/misc.c:753 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "формат журнала \"%s\" не поддерживается" + +#: utils/adt/misc.c:754 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "Поддерживаются форматы журналов \"stderr\" и \"csvlog\"." + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "неверное значение cidr: \"%s\"" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "Значение содержит установленные биты правее маски." + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 +#: utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "не удалось отформатировать значение inet: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "неверное семейство адресов во внешнем представлении \"%s\"" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "неверные биты во внешнем представлении \"%s\"" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "неверная длина во внешнем представлении \"%s\"" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "неверное внешнее представление \"cidr\"" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "неверная длина маски: %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "не удалось отформатировать значение cidr: %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "объединять адреса разных семейств нельзя" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "нельзя использовать \"И\" (AND) для значений inet разного размера" + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "нельзя использовать \"ИЛИ\" (OR) для значений inet разного размера" + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "результат вне диапазона" + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "нельзя вычитать значения inet разного размера" + +#: utils/adt/numeric.c:827 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "неверный знак во внешнем значении \"numeric\"" + +#: utils/adt/numeric.c:833 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "неверный порядок числа во внешнем значении \"numeric\"" + +#: utils/adt/numeric.c:842 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "неверная цифра во внешнем значении \"numeric\"" + +#: utils/adt/numeric.c:1040 utils/adt/numeric.c:1054 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "точность NUMERIC %d должна быть между 1 и %d" + +#: utils/adt/numeric.c:1045 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "порядок NUMERIC %d должен быть между 0 и точностью (%d)" + +#: utils/adt/numeric.c:1063 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "неверный модификатор типа NUMERIC" + +#: utils/adt/numeric.c:1395 +#, c-format +msgid "start value cannot be NaN" +msgstr "начальное значение не может быть NaN" + +#: utils/adt/numeric.c:1400 +#, c-format +msgid "stop value cannot be NaN" +msgstr "конечное значение не может быть NaN" + +#: utils/adt/numeric.c:1410 +#, c-format +msgid "step size cannot be NaN" +msgstr "размер шага не может быть NaN" + +#: utils/adt/numeric.c:2958 utils/adt/numeric.c:6064 utils/adt/numeric.c:6522 +#: utils/adt/numeric.c:8802 utils/adt/numeric.c:9240 utils/adt/numeric.c:9354 +#: utils/adt/numeric.c:9427 +#, c-format +msgid "value overflows numeric format" +msgstr "значение переполняет формат numeric" + +#: utils/adt/numeric.c:3417 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "нельзя преобразовать NaN в integer" + +#: utils/adt/numeric.c:3500 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "нельзя преобразовать NaN в bigint" + +#: utils/adt/numeric.c:3545 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "нельзя преобразовать NaN в smallint" + +#: utils/adt/numeric.c:3582 utils/adt/numeric.c:3653 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "нельзя представить бесконечность в numeric" + +#: utils/adt/numeric.c:6606 +#, c-format +msgid "numeric field overflow" +msgstr "переполнение поля numeric" + +#: utils/adt/numeric.c:6607 +#, c-format +msgid "" +"A field with precision %d, scale %d must round to an absolute value less " +"than %s%d." +msgstr "" +"Поле с точностью %d, порядком %d должно округляться до абсолютного значения " +"меньше чем %s%d." + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "значение \"%s\" вне диапазона для 8-битового integer" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "неверные данные oidvector" + +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "запрошенный символ больше допустимого" + +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "код запрошенного символа слишком велик для кодировки: %d" + +#: utils/adt/oracle_compat.c:987 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "запрошенный символ не подходит для кодировки: %d" + +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "символ не может быть null" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "значение перцентиля %g лежит не в диапазоне 0..1" + +#: utils/adt/pg_locale.c:1262 +#, c-format +msgid "Apply system library package updates." +msgstr "Обновите пакет с системной библиотекой." + +#: utils/adt/pg_locale.c:1477 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "не удалось создать локаль \"%s\": %m" + +#: utils/adt/pg_locale.c:1480 +#, c-format +msgid "" +"The operating system could not find any locale data for the locale name \"%s" +"\"." +msgstr "Операционная система не может найти данные локали с именем \"%s\"." + +#: utils/adt/pg_locale.c:1582 +#, c-format +msgid "" +"collations with different collate and ctype values are not supported on this " +"platform" +msgstr "" +"правила сортировки с разными значениями collate и ctype не поддерживаются на " +"этой платформе" + +#: utils/adt/pg_locale.c:1591 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "поставщик правил сортировки LIBC не поддерживается на этой платформе" + +#: utils/adt/pg_locale.c:1603 +#, c-format +msgid "" +"collations with different collate and ctype values are not supported by ICU" +msgstr "" +"ICU не поддерживает правила сортировки с разными значениями collate и ctype" + +#: utils/adt/pg_locale.c:1609 utils/adt/pg_locale.c:1696 +#: utils/adt/pg_locale.c:1969 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "не удалось открыть сортировщик для локали \"%s\": %s" + +#: utils/adt/pg_locale.c:1623 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU не поддерживается в данной сборке" + +#: utils/adt/pg_locale.c:1624 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "Необходимо перекомпилировать PostgreSQL с ключом --with-icu." + +#: utils/adt/pg_locale.c:1644 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "для правила сортировки \"%s\", лишённого версии, была задана версия" + +#: utils/adt/pg_locale.c:1651 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "несовпадение версии для правила сортировки \"%s\"" + +#: utils/adt/pg_locale.c:1653 +#, c-format +msgid "" +"The collation in the database was created using version %s, but the " +"operating system provides version %s." +msgstr "" +"Правило сортировки в базе данных было создано с версией %s, но операционная " +"версия предоставляет версию %s." + +#: utils/adt/pg_locale.c:1656 +#, c-format +msgid "" +"Rebuild all objects affected by this collation and run ALTER COLLATION %s " +"REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "" +"Перестройте все объекты, задействующие это правило сортировки, и выполните " +"ALTER COLLATION %s REFRESH VERSION либо соберите PostgreSQL с правильной " +"версией библиотеки." + +#: utils/adt/pg_locale.c:1747 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "" +"не удалось получить версию правила сортировки для локали \"%s\" (код ошибки: " +"%lu)" + +#: utils/adt/pg_locale.c:1784 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "ICU не поддерживает кодировку \"%s\"" + +#: utils/adt/pg_locale.c:1791 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "не удалось открыть преобразователь ICU для кодировки \"%s\": %s" + +#: utils/adt/pg_locale.c:1822 utils/adt/pg_locale.c:1831 +#: utils/adt/pg_locale.c:1860 utils/adt/pg_locale.c:1870 +#, c-format +msgid "%s failed: %s" +msgstr "ошибка %s: %s" + +#: utils/adt/pg_locale.c:2142 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "неверный многобайтный символ для локали" + +#: utils/adt/pg_locale.c:2143 +#, c-format +msgid "" +"The server's LC_CTYPE locale is probably incompatible with the database " +"encoding." +msgstr "" +"Параметр локали сервера LC_CTYPE, возможно, несовместим с кодировкой БД." + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "" +"функцию можно вызывать только когда сервер в режиме двоичного обновления" + +#: utils/adt/pgstatfuncs.c:500 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "неверное имя команды: \"%s\"" + +#: utils/adt/pseudotypes.c:57 utils/adt/pseudotypes.c:91 +#, c-format +msgid "cannot display a value of type %s" +msgstr "значение типа %s нельзя вывести" + +#: utils/adt/pseudotypes.c:283 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "значение типа shell нельзя ввести" + +#: utils/adt/pseudotypes.c:293 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "значение типа shell нельзя вывести" + +#: utils/adt/rangetypes.c:406 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "аргумент flags конструктора диапазона не может быть NULL" + +#: utils/adt/rangetypes.c:993 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "результат вычитания диапазонов будет не непрерывным" + +#: utils/adt/rangetypes.c:1054 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "результат объединения диапазонов будет не непрерывным" + +#: utils/adt/rangetypes.c:1600 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "нижняя граница диапазона должна быть меньше или равна верхней" + +#: utils/adt/rangetypes.c:1983 utils/adt/rangetypes.c:1996 +#: utils/adt/rangetypes.c:2010 +#, c-format +msgid "invalid range bound flags" +msgstr "неверные флаги границ диапазона" + +#: utils/adt/rangetypes.c:1984 utils/adt/rangetypes.c:1997 +#: utils/adt/rangetypes.c:2011 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Допустимые значения: \"[]\", \"[)\", \"(]\" и \"()\"." + +#: utils/adt/rangetypes.c:2076 utils/adt/rangetypes.c:2093 +#: utils/adt/rangetypes.c:2106 utils/adt/rangetypes.c:2124 +#: utils/adt/rangetypes.c:2135 utils/adt/rangetypes.c:2179 +#: utils/adt/rangetypes.c:2187 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "ошибочный литерал диапазона: \"%s\"" + +#: utils/adt/rangetypes.c:2078 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "Мусор после ключевого слова \"empty\"." + +#: utils/adt/rangetypes.c:2095 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Отсутствует левая скобка (круглая или квадратная)." + +#: utils/adt/rangetypes.c:2108 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Отсутствует запятая после нижней границы." + +#: utils/adt/rangetypes.c:2126 +#, c-format +msgid "Too many commas." +msgstr "Слишком много запятых." + +#: utils/adt/rangetypes.c:2137 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "Мусор после правой скобки." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4511 +#, c-format +msgid "regular expression failed: %s" +msgstr "ошибка в регулярном выражении: %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%c\"" +msgstr "неверный параметр регулярного выражения: \"%c\"" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "" +"SQL regular expression may not contain more than two escape-double-quote " +"separators" +msgstr "" +"Регулярное выражение SQL не может содержать больше двух разделителей " +"(экранированных кавычек)" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s не поддерживает режим \"global\"" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "Вместо неё используйте функцию regexp_matches." + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "слишком много совпадений для регулярного выражения" + +#: utils/adt/regproc.c:107 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "имя \"%s\" имеют несколько функций" + +#: utils/adt/regproc.c:525 +#, c-format +msgid "more than one operator named %s" +msgstr "имя %s имеют несколько операторов" + +#: utils/adt/regproc.c:692 utils/adt/regproc.c:733 gram.y:8224 +#, c-format +msgid "missing argument" +msgstr "отсутствует аргумент" + +#: utils/adt/regproc.c:693 utils/adt/regproc.c:734 gram.y:8225 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "" +"Чтобы обозначить отсутствующий аргумент унарного оператора, укажите NONE." + +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 utils/adt/regproc.c:2018 +#: utils/adt/ruleutils.c:9298 utils/adt/ruleutils.c:9467 +#, c-format +msgid "too many arguments" +msgstr "слишком много аргументов" + +#: utils/adt/regproc.c:698 utils/adt/regproc.c:739 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Предоставьте для оператора два типа аргументов." + +#: utils/adt/regproc.c:1602 utils/adt/regproc.c:1626 utils/adt/regproc.c:1727 +#: utils/adt/regproc.c:1751 utils/adt/regproc.c:1853 utils/adt/regproc.c:1858 +#: utils/adt/varlena.c:3660 utils/adt/varlena.c:3665 +#, c-format +msgid "invalid name syntax" +msgstr "ошибка синтаксиса в имени" + +#: utils/adt/regproc.c:1916 +#, c-format +msgid "expected a left parenthesis" +msgstr "ожидалась левая скобка" + +#: utils/adt/regproc.c:1932 +#, c-format +msgid "expected a right parenthesis" +msgstr "ожидалась правая скобка" + +#: utils/adt/regproc.c:1951 +#, c-format +msgid "expected a type name" +msgstr "ожидалось имя типа" + +#: utils/adt/regproc.c:1983 +#, c-format +msgid "improper type name" +msgstr "ошибочное имя типа" + +#: utils/adt/ri_triggers.c:296 utils/adt/ri_triggers.c:1537 +#: utils/adt/ri_triggers.c:2467 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "" +"INSERT или UPDATE в таблице \"%s\" нарушает ограничение внешнего ключа \"%s\"" + +#: utils/adt/ri_triggers.c:299 utils/adt/ri_triggers.c:1540 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL не позволяет смешивать в значении ключа null и не null." + +#: utils/adt/ri_triggers.c:1940 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "функция \"%s\" должна запускаться для INSERT" + +#: utils/adt/ri_triggers.c:1946 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "функция \"%s\" должна запускаться для UPDATE" + +#: utils/adt/ri_triggers.c:1952 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "функция \"%s\" должна запускаться для DELETE" + +#: utils/adt/ri_triggers.c:1975 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "для триггера \"%s\" таблицы \"%s\" нет записи pg_constraint" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "" +"Remove this referential integrity trigger and its mates, then do ALTER TABLE " +"ADD CONSTRAINT." +msgstr "" +"Удалите этот триггер ссылочной целостности и связанные объекты, а затем " +"выполните ALTER TABLE ADD CONSTRAINT." + +#: utils/adt/ri_triggers.c:2007 gram.y:3819 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "выражение MATCH PARTIAL ещё не реализовано" + +#: utils/adt/ri_triggers.c:2292 +#, c-format +msgid "" +"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave " +"unexpected result" +msgstr "" +"неожиданный результат запроса ссылочной целостности к \"%s\" из ограничения " +"\"%s\" таблицы \"%s\"" + +#: utils/adt/ri_triggers.c:2296 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Скорее всего это вызвано правилом, переписавшим запрос." + +#: utils/adt/ri_triggers.c:2457 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "" +"при удалении секции \"%s\" нарушается ограничение внешнего ключа \"%s\"" + +#: utils/adt/ri_triggers.c:2460 utils/adt/ri_triggers.c:2485 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "На ключ (%s)=(%s) всё ещё есть ссылки в таблице \"%s\"." + +#: utils/adt/ri_triggers.c:2471 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "Ключ (%s)=(%s) отсутствует в таблице \"%s\"." + +#: utils/adt/ri_triggers.c:2474 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "Ключ отсутствует в таблице \"%s\"." + +#: utils/adt/ri_triggers.c:2480 +#, c-format +msgid "" +"update or delete on table \"%s\" violates foreign key constraint \"%s\" on " +"table \"%s\"" +msgstr "" +"UPDATE или DELETE в таблице \"%s\" нарушает ограничение внешнего ключа \"%s" +"\" таблицы \"%s\"" + +#: utils/adt/ri_triggers.c:2488 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "На ключ всё ещё есть ссылки в таблице \"%s\"." + +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "ввод анонимных составных типов не реализован" + +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 +#: utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "ошибка в литерале записи: \"%s\"" + +#: utils/adt/rowtypes.c:157 +#, c-format +msgid "Missing left parenthesis." +msgstr "Отсутствует левая скобка." + +#: utils/adt/rowtypes.c:186 +#, c-format +msgid "Too few columns." +msgstr "Слишком мало столбцов." + +#: utils/adt/rowtypes.c:269 +#, c-format +msgid "Too many columns." +msgstr "Слишком много столбцов." + +#: utils/adt/rowtypes.c:277 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Мусор после правой скобки." + +#: utils/adt/rowtypes.c:531 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "неверное число столбцов: %d, ожидалось: %d" + +#: utils/adt/rowtypes.c:559 +#, c-format +msgid "wrong data type: %u, expected %u" +msgstr "неверный тип данных: %u, ожидался %u" + +#: utils/adt/rowtypes.c:620 +#, c-format +msgid "improper binary format in record column %d" +msgstr "неподходящий двоичный формат в столбце записи %d" + +#: utils/adt/rowtypes.c:911 utils/adt/rowtypes.c:1157 utils/adt/rowtypes.c:1415 +#: utils/adt/rowtypes.c:1661 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "не удалось сравнить различные типы столбцов %s и %s, столбец записи %d" + +#: utils/adt/rowtypes.c:1002 utils/adt/rowtypes.c:1227 +#: utils/adt/rowtypes.c:1512 utils/adt/rowtypes.c:1697 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "сравнивать типы записей с разным числом столбцов нельзя" + +#: utils/adt/ruleutils.c:4822 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "правило \"%s\" имеет неподдерживаемый тип событий %d" + +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "TIMESTAMP(%d)%s: точность должна быть неотрицательна" + +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIMESTAMP(%d)%s: точность уменьшена до дозволенного максимума: %d" + +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:434 utils/misc/guc.c:11929 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestamp вне диапазона: \"%s\"" + +#: utils/adt/timestamp.c:372 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "точность timestamp(%d) должна быть между %d и %d" + +#: utils/adt/timestamp.c:496 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "" +"Запись числового часового пояса должна начинаться с символа \"-\" или \"+\"." + +#: utils/adt/timestamp.c:509 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "числовой часовой пояс \"%s\" вне диапазона" + +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestamp вне диапазона: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:720 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "timestamp не может быть NaN" + +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "timestamp вне диапазона: \"%g\"" + +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1509 +#: utils/adt/timestamp.c:1976 utils/adt/timestamp.c:3053 +#: utils/adt/timestamp.c:3058 utils/adt/timestamp.c:3063 +#: utils/adt/timestamp.c:3113 utils/adt/timestamp.c:3120 +#: utils/adt/timestamp.c:3127 utils/adt/timestamp.c:3147 +#: utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3161 +#: utils/adt/timestamp.c:3191 utils/adt/timestamp.c:3199 +#: utils/adt/timestamp.c:3243 utils/adt/timestamp.c:3670 +#: utils/adt/timestamp.c:3795 utils/adt/timestamp.c:4255 +#, c-format +msgid "interval out of range" +msgstr "interval вне диапазона" + +#: utils/adt/timestamp.c:1062 utils/adt/timestamp.c:1095 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "неверный модификатор типа INTERVAL" + +#: utils/adt/timestamp.c:1078 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d): точность должна быть неотрицательна" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d): точность уменьшена до максимально возможной: %d" + +#: utils/adt/timestamp.c:1466 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "точность interval(%d) должна быть между %d и %d" + +#: utils/adt/timestamp.c:2654 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "вычитать бесконечные значения timestamp нельзя" + +#: utils/adt/timestamp.c:3923 utils/adt/timestamp.c:4516 +#: utils/adt/timestamp.c:4678 utils/adt/timestamp.c:4699 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "единицы timestamp \"%s\" не поддерживаются" + +#: utils/adt/timestamp.c:3937 utils/adt/timestamp.c:4470 +#: utils/adt/timestamp.c:4709 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "единицы timestamp \"%s\" не распознаны" + +#: utils/adt/timestamp.c:4067 utils/adt/timestamp.c:4511 +#: utils/adt/timestamp.c:4874 utils/adt/timestamp.c:4896 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "единицы timestamp с часовым поясом \"%s\" не поддерживаются" + +#: utils/adt/timestamp.c:4084 utils/adt/timestamp.c:4465 +#: utils/adt/timestamp.c:4905 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "единицы timestamp с часовым поясом \"%s\" не распознаны" + +#: utils/adt/timestamp.c:4242 +#, c-format +msgid "" +"interval units \"%s\" not supported because months usually have fractional " +"weeks" +msgstr "" +"единицы интервала \"%s\" не поддерживаются, так как в месяцах дробное число " +"недель" + +#: utils/adt/timestamp.c:4248 utils/adt/timestamp.c:4999 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "единицы interval \"%s\" не поддерживаются" + +#: utils/adt/timestamp.c:4264 utils/adt/timestamp.c:5022 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "единицы interval \"%s\" не распознаны" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "" +"функция suppress_redundant_updates_trigger должна вызываться как триггер" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "" +"функция suppress_redundant_updates_trigger должна вызываться при обновлении" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "" +"функция suppress_redundant_updates_trigger должна вызываться перед " +"обновлением" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "" +"функция suppress_redundant_updates_trigger должна вызываться для каждой " +"строки" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "функция gtsvector_in не реализована" + +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "дистанция во фразовом операторе должна быть не больше %d" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "ошибка синтаксиса в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:334 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "нет оператора в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "слишком большое значение в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:573 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "слишком длинный операнд в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "слишком длинное слово в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "запрос поиска текста не содержит лексемы: \"%s\"" + +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsquery слишком большой" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "" +"text-search query contains only stop words or doesn't contain lexemes, " +"ignored" +msgstr "" +"запрос поиска текста игнорируется, так как содержит только стоп-слова или не " +"содержит лексем" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "" +"дистанция во фразовом операторе должна быть неотрицательной и меньше %d" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "запрос ts_rewrite должен вернуть два столбца типа tsquery" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "массив весов должен быть одномерным" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "массив весов слишком мал" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "массив весов не может содержать null" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:872 +#, c-format +msgid "weight out of range" +msgstr "вес вне диапазона" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "слово слишком длинное (%ld Б, при максимуме %ld)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "строка слишком длинна для tsvector (%ld Б, при максимуме %ld)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "массив лексем не может содержать элементы null" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "массив весов не может содержать элементы null" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "нераспознанный вес: \"%c\"" + +#: utils/adt/tsvector_op.c:2414 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "запрос ts_stat должен вернуть один столбец tsvector" + +#: utils/adt/tsvector_op.c:2603 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "столбец \"%s\" типа tsvector не существует" + +#: utils/adt/tsvector_op.c:2610 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "столбец \"%s\" должен иметь тип tsvector" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "столбец конфигурации \"%s\" не существует" + +#: utils/adt/tsvector_op.c:2628 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "столбец \"%s\" должен иметь тип regconfig" + +#: utils/adt/tsvector_op.c:2635 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "значение столбца конфигурации \"%s\" не должно быть null" + +#: utils/adt/tsvector_op.c:2648 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "имя конфигурации текстового поиска \"%s\" должно указываться со схемой" + +#: utils/adt/tsvector_op.c:2673 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "столбец \"%s\" имеет не символьный тип" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "ошибка синтаксиса в tsvector: \"%s\"" + +# skip-rule: capital-letter-first +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "нет спец. символа \"%s\"" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "неверная информация о позиции в tsvector: \"%s\"" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "не удалось сгенерировать случайные значения" + +#: utils/adt/varbit.c:109 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "длина значения типа %s должна быть как минимум 1" + +#: utils/adt/varbit.c:114 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "длина значения типа %s не может превышать %d" + +#: utils/adt/varbit.c:197 utils/adt/varbit.c:498 utils/adt/varbit.c:993 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "длина битовой строки превышает предел (%d)" + +#: utils/adt/varbit.c:211 utils/adt/varbit.c:355 utils/adt/varbit.c:405 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "длина битовой строки (%d) не соответствует типу bit(%d)" + +#: utils/adt/varbit.c:233 utils/adt/varbit.c:534 +#, c-format +msgid "\"%c\" is not a valid binary digit" +msgstr "\"%c\" - не двоичная цифра" + +#: utils/adt/varbit.c:258 utils/adt/varbit.c:559 +#, c-format +msgid "\"%c\" is not a valid hexadecimal digit" +msgstr "\"%c\" - не шестнадцатеричная цифра" + +#: utils/adt/varbit.c:346 utils/adt/varbit.c:651 +#, c-format +msgid "invalid length in external bit string" +msgstr "неверная длина во внешней строке битов" + +#: utils/adt/varbit.c:512 utils/adt/varbit.c:660 utils/adt/varbit.c:756 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "строка битов не умещается в тип bit varying(%d)" + +#: utils/adt/varbit.c:1080 utils/adt/varbit.c:1190 utils/adt/varlena.c:873 +#: utils/adt/varlena.c:936 utils/adt/varlena.c:1093 utils/adt/varlena.c:3313 +#: utils/adt/varlena.c:3391 +#, c-format +msgid "negative substring length not allowed" +msgstr "подстрока должна иметь неотрицательную длину" + +#: utils/adt/varbit.c:1247 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "нельзя использовать \"И\" (AND) для битовых строк разной длины" + +#: utils/adt/varbit.c:1288 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "нельзя использовать \"ИЛИ\" (OR) для битовых строк разной длины" + +#: utils/adt/varbit.c:1328 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "" +"нельзя использовать \"ИСКЛЮЧАЮЩЕЕ ИЛИ\" (XOR) для битовых строк разной длины" + +#: utils/adt/varbit.c:1810 utils/adt/varbit.c:1868 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "индекс бита %d вне диапазона 0..%d" + +#: utils/adt/varbit.c:1819 utils/adt/varlena.c:3584 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "значением бита должен быть 0 или 1" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "значение не умещается в тип character(%d)" + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "значение не умещается в тип character varying(%d)" + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1485 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "" +"не удалось определить, какое правило сортировки использовать для сравнения " +"строк" + +#: utils/adt/varlena.c:1192 utils/adt/varlena.c:1925 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "" +"недетерминированные правила сортировки не поддерживаются для поиска подстрок" + +#: utils/adt/varlena.c:1584 utils/adt/varlena.c:1597 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "не удалось преобразовать строку в UTF-16 (код ошибки: %lu)" + +#: utils/adt/varlena.c:1612 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "не удалось сравнить строки в Unicode: %m" + +#: utils/adt/varlena.c:1663 utils/adt/varlena.c:2377 +#, c-format +msgid "collation failed: %s" +msgstr "ошибка в библиотеке сортировки: %s" + +#: utils/adt/varlena.c:2585 +#, c-format +msgid "sort key generation failed: %s" +msgstr "не удалось сгенерировать ключ сортировки: %s" + +#: utils/adt/varlena.c:3468 utils/adt/varlena.c:3535 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "индекс %d вне диапазона 0..%d" + +#: utils/adt/varlena.c:3499 utils/adt/varlena.c:3571 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "индекс %lld вне диапазона 0..%lld" + +#: utils/adt/varlena.c:4608 +#, c-format +msgid "field position must be greater than zero" +msgstr "позиция поля должна быть больше нуля" + +#: utils/adt/varlena.c:5474 +#, c-format +msgid "unterminated format() type specifier" +msgstr "незавершённый спецификатор типа format()" + +#: utils/adt/varlena.c:5475 utils/adt/varlena.c:5609 utils/adt/varlena.c:5730 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "Для представления одного знака \"%%\" запишите \"%%%%\"." + +#: utils/adt/varlena.c:5607 utils/adt/varlena.c:5728 +#, c-format +msgid "unrecognized format() type specifier \"%c\"" +msgstr "нераспознанный спецификатор типа format(): \"%c\"" + +#: utils/adt/varlena.c:5620 utils/adt/varlena.c:5677 +#, c-format +msgid "too few arguments for format()" +msgstr "мало аргументов для format()" + +#: utils/adt/varlena.c:5773 utils/adt/varlena.c:5955 +#, c-format +msgid "number is out of range" +msgstr "число вне диапазона" + +#: utils/adt/varlena.c:5836 utils/adt/varlena.c:5864 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "формат ссылается на аргумент 0, но аргументы нумеруются с 1" + +#: utils/adt/varlena.c:5857 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "указание аргумента ширины должно оканчиваться \"$\"" + +#: utils/adt/varlena.c:5902 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "значения null нельзя представить в виде SQL-идентификатора" + +#: utils/adt/varlena.c:6028 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "" +"нормализацию Unicode можно выполнять, только если кодировка сервера — UTF8" + +#: utils/adt/varlena.c:6041 +#, c-format +msgid "invalid normalization form: %s" +msgstr "неверная форма нормализации: %s" + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "аргумент ntile должен быть больше нуля" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "аргумент nth_value должен быть больше нуля" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "идентификатор транзакции %s относится к будущему" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "неверное внешнее представление pg_snapshot" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "XML-функции не поддерживаются" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Для этой функциональности в сервере не хватает поддержки libxml." + +#: utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "Необходимо перекомпилировать PostgreSQL с ключом --with-libxml." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:570 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "неверное имя кодировки: \"%s\"" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "ошибка в XML-комментарии" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "не XML-документ" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "неправильная XML-инструкция обработки (PI)" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "назначением XML-инструкции обработки (PI) не может быть \"%s\"." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML-инструкция обработки (PI) не может содержать \"?>\"." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "функция xmlvalidate не реализована" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "не удалось инициализировать библиотеку XML" + +#: utils/adt/xml.c:962 +#, c-format +msgid "" +"libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "другой тип char в libxml2: sizeof(char)=%u, sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "не удалось установить обработчик XML-ошибок" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "" +"This probably indicates that the version of libxml2 being used is not " +"compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "" +"Возможно это означает, что используемая версия libxml2 не совместима с " +"заголовочными файлами libxml2, с которыми был собран PostgreSQL." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "Неверный символ." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "Требуется пробел." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "значениями атрибута standalone могут быть только 'yes' и 'no'." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "Ошибочное объявление: не указана версия." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "В объявлении не указана кодировка." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "Ошибка при разборе XML-объявления: ожидается '?>'." + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "Нераспознанный код ошибки libxml: %d." + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML не поддерживает бесконечность в датах." + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML не поддерживает бесконечность в timestamp." + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "неверный запрос" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "неправильный массив с сопоставлениями пространств имён XML" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "" +"The array must be two-dimensional with length of the second axis equal to 2." +msgstr "Массив должен быть двухмерным и содержать 2 элемента по второй оси." + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "пустое выражение XPath" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "ни префикс, ни URI пространства имён не может быть null" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "" +"не удалось зарегистрировать пространство имён XML с префиксом \"%s\" и URI " +"\"%s\"" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "пространство имён DEFAULT не поддерживается" + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "путь отбираемых строк не должен быть пустым" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "путь отбираемого столбца не должен быть пустым" + +#: utils/adt/xml.c:4661 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "выражение XPath, отбирающее столбец, возвратило более одного значения" + +#: utils/cache/lsyscache.c:1015 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "приведение типа %s к типу %s не существует" + +#: utils/cache/lsyscache.c:2764 utils/cache/lsyscache.c:2797 +#: utils/cache/lsyscache.c:2830 utils/cache/lsyscache.c:2863 +#, c-format +msgid "type %s is only a shell" +msgstr "тип %s - лишь оболочка" + +#: utils/cache/lsyscache.c:2769 +#, c-format +msgid "no input function available for type %s" +msgstr "для типа %s нет функции ввода" + +#: utils/cache/lsyscache.c:2802 +#, c-format +msgid "no output function available for type %s" +msgstr "для типа %s нет функции вывода" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "" +"operator class \"%s\" of access method %s is missing support function %d for " +"type %s" +msgstr "" +"в классе операторов \"%s\" метода доступа %s нет опорной функции %d для типа " +"%s" + +#: utils/cache/plancache.c:718 +#, c-format +msgid "cached plan must not change result type" +msgstr "в кешированном плане не должен изменяться тип результата" + +#: utils/cache/relcache.c:6078 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "создать файл инициализации для кеша отношений \"%s\" не удалось: %m" + +#: utils/cache/relcache.c:6080 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Продолжаем всё равно, хотя что-то не так." + +#: utils/cache/relcache.c:6402 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "не удалось стереть файл кеша \"%s\": %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "" +"выполнить PREPARE для транзакции, изменившей сопоставление отношений, нельзя" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "файл сопоставления отношений \"%s\" содержит неверные данные" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "ошибка контрольной суммы в файле сопоставления отношений \"%s\"" + +#: utils/cache/typcache.c:1692 utils/fmgr/funcapi.c:461 +#, c-format +msgid "record type has not been registered" +msgstr "тип записи не зарегистрирован" + +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "ЛОВУШКА: Исключительное условие: неверные аргументы\n" + +#: utils/error/assert.c:40 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "ЛОВУШКА: %s(\"%s\", файл: \"%s\", строка: %d)\n" + +#: utils/error/elog.c:322 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "произошла ошибка до готовности подсистемы обработки сообщений\n" + +#: utils/error/elog.c:1868 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "открыть файл \"%s\" как stderr не удалось: %m" + +#: utils/error/elog.c:1881 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "открыть файл \"%s\" как stdout не удалось: %m" + +#: utils/error/elog.c:2373 utils/error/elog.c:2407 utils/error/elog.c:2423 +msgid "[unknown]" +msgstr "[н/д]" + +#: utils/error/elog.c:2893 utils/error/elog.c:3203 utils/error/elog.c:3311 +msgid "missing error text" +msgstr "отсутствует текст ошибки" + +#: utils/error/elog.c:2896 utils/error/elog.c:2899 utils/error/elog.c:3314 +#: utils/error/elog.c:3317 +#, c-format +msgid " at character %d" +msgstr " (символ %d)" + +#: utils/error/elog.c:2909 utils/error/elog.c:2916 +msgid "DETAIL: " +msgstr "ПОДРОБНОСТИ: " + +#: utils/error/elog.c:2923 +msgid "HINT: " +msgstr "ПОДСКАЗКА: " + +#: utils/error/elog.c:2930 +msgid "QUERY: " +msgstr "ЗАПРОС: " + +#: utils/error/elog.c:2937 +msgid "CONTEXT: " +msgstr "КОНТЕКСТ: " + +#: utils/error/elog.c:2947 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "ПОЛОЖЕНИЕ: %s, %s:%d\n" + +#: utils/error/elog.c:2954 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "ПОЛОЖЕНИЕ: %s:%d\n" + +#: utils/error/elog.c:2961 +msgid "BACKTRACE: " +msgstr "СТЕК: " + +#: utils/error/elog.c:2975 +msgid "STATEMENT: " +msgstr "ОПЕРАТОР: " + +#: utils/error/elog.c:3364 +msgid "DEBUG" +msgstr "ОТЛАДКА" + +#: utils/error/elog.c:3368 +msgid "LOG" +msgstr "СООБЩЕНИЕ" + +#: utils/error/elog.c:3371 +msgid "INFO" +msgstr "ИНФОРМАЦИЯ" + +#: utils/error/elog.c:3374 +msgid "NOTICE" +msgstr "ЗАМЕЧАНИЕ" + +#: utils/error/elog.c:3377 +msgid "WARNING" +msgstr "ПРЕДУПРЕЖДЕНИЕ" + +#: utils/error/elog.c:3380 +msgid "ERROR" +msgstr "ОШИБКА" + +#: utils/error/elog.c:3383 +msgid "FATAL" +msgstr "ВАЖНО" + +#: utils/error/elog.c:3386 +msgid "PANIC" +msgstr "ПАНИКА" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "не удалось найти функцию \"%s\" в файле \"%s\"" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "загрузить библиотеку \"%s\" не удалось: %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "несовместимая библиотека \"%s\": нет отличительного блока" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "Внешние библиотеки должны использовать макрос PG_MODULE_MAGIC." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "несовместимая библиотека \"%s\": несовпадение версий" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "Версия сервера: %d, версия библиотеки: %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "В сервере FUNC_MAX_ARGS = %d, в библиотеке: %d." + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "В сервере INDEX_MAX_KEYS = %d, в библиотеке: %d." + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "В сервере NAMEDATALEN = %d, в библиотеке: %d." + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "В сервере FLOAT8PASSBYVAL = %s, в библиотеке: %s." + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "Отличительный блок имеет неверную длину или дополнен по-другому." + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "несовместимая библиотека \"%s\": несоответствие отличительного блока" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "доступ к библиотеке \"%s\" не разрешён" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "неправильный макрос в пути динамической библиотеки: %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "параметр dynamic_library_path содержит компонент нулевой длины" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "" +"параметр dynamic_library_path содержит компонент, не являющийся абсолютным " +"путём" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "внутренней функции \"%s\" нет во внутренней поисковой таблице" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "не удалось найти информацию о функции \"%s\"" + +#: utils/fmgr/fmgr.c:489 +#, c-format +msgid "" +"SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "" +"Функциям, вызываемым из SQL, требуется дополнительное объявление " +"PG_FUNCTION_INFO_V1(имя_функции)." + +#: utils/fmgr/fmgr.c:507 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "" +"версия API (%d), выданная информационной функцией \"%s\", не поддерживается" + +#: utils/fmgr/fmgr.c:2003 +#, c-format +msgid "operator class options info is absent in function call context" +msgstr "" +"информация о параметрах класса операторов отсутствует в контексте вызова " +"функции" + +#: utils/fmgr/fmgr.c:2070 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "функция языковой проверки %u вызвана для языка %u (а не %u)" + +#: utils/fmgr/funcapi.c:384 +#, c-format +msgid "" +"could not determine actual result type for function \"%s\" declared to " +"return type %s" +msgstr "" +"не удалось определить действительный тип результата для функции \"%s\", " +"объявленной как возвращающая тип %s" + +#: utils/fmgr/funcapi.c:1652 utils/fmgr/funcapi.c:1684 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "число псевдонимов не совпадает с числом столбцов" + +#: utils/fmgr/funcapi.c:1678 +#, c-format +msgid "no column alias was provided" +msgstr "псевдоним столбца не указан" + +#: utils/fmgr/funcapi.c:1702 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "не удалось определить описание строки для функции, возвращающей запись" + +#: utils/init/miscinit.c:285 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "каталог данных \"%s\" не существует" + +#: utils/init/miscinit.c:290 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "не удалось считать права на каталог \"%s\": %m" + +#: utils/init/miscinit.c:298 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "указанный каталог данных \"%s\" не существует" + +#: utils/init/miscinit.c:314 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "владелец каталога данных \"%s\" определён неверно" + +#: utils/init/miscinit.c:316 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "" +"Сервер должен запускать пользователь, являющийся владельцем каталога данных." + +#: utils/init/miscinit.c:334 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "для каталога данных \"%s\" установлены неправильные права доступа" + +#: utils/init/miscinit.c:336 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Маска прав должна быть u=rwx (0700) или u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:615 utils/misc/guc.c:7139 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "" +"параметр \"%s\" нельзя задать в рамках операции с ограничениями по " +"безопасности" + +#: utils/init/miscinit.c:683 +#, c-format +msgid "role with OID %u does not exist" +msgstr "роль с OID %u не существует" + +#: utils/init/miscinit.c:713 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "для роли \"%s\" вход запрещён" + +#: utils/init/miscinit.c:731 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "слишком много подключений для роли \"%s\"" + +#: utils/init/miscinit.c:791 +#, c-format +msgid "permission denied to set session authorization" +msgstr "нет прав для смены объекта авторизации в сеансе" + +#: utils/init/miscinit.c:874 +#, c-format +msgid "invalid role OID: %u" +msgstr "неверный OID роли: %u" + +#: utils/init/miscinit.c:928 +#, c-format +msgid "database system is shut down" +msgstr "система БД выключена" + +#: utils/init/miscinit.c:1015 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "не удалось создать файл блокировки \"%s\": %m" + +#: utils/init/miscinit.c:1029 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "не удалось открыть файл блокировки \"%s\": %m" + +#: utils/init/miscinit.c:1036 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "не удалось прочитать файл блокировки \"%s\": %m" + +#: utils/init/miscinit.c:1045 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "файл блокировки \"%s\" пуст" + +#: utils/init/miscinit.c:1046 +#, c-format +msgid "" +"Either another server is starting, or the lock file is the remnant of a " +"previous server startup crash." +msgstr "" +"Либо сейчас запускается другой сервер, либо этот файл остался в результате " +"сбоя при предыдущем запуске." + +#: utils/init/miscinit.c:1090 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "файл блокировки \"%s\" уже существует" + +#: utils/init/miscinit.c:1094 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "Другой экземпляр postgres (PID %d) работает с каталогом данных \"%s\"?" + +#: utils/init/miscinit.c:1096 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "" +"Другой экземпляр postmaster (PID %d) работает с каталогом данных \"%s\"?" + +#: utils/init/miscinit.c:1099 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "Другой экземпляр postgres (PID %d) использует файл сокета \"%s\"?" + +#: utils/init/miscinit.c:1101 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "Другой экземпляр postmaster (PID %d) использует файл сокета \"%s\"?" + +#: utils/init/miscinit.c:1152 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "не удалось стереть старый файл блокировки \"%s\": %m" + +#: utils/init/miscinit.c:1154 +#, c-format +msgid "" +"The file seems accidentally left over, but it could not be removed. Please " +"remove the file by hand and try again." +msgstr "" +"Кажется, файл сохранился по ошибке, но удалить его не получилось. " +"Пожалуйста, удалите файл вручную и повторите попытку." + +#: utils/init/miscinit.c:1191 utils/init/miscinit.c:1205 +#: utils/init/miscinit.c:1216 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "не удалось записать файл блокировки \"%s\": %m" + +#: utils/init/miscinit.c:1327 utils/init/miscinit.c:1469 utils/misc/guc.c:10066 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: utils/init/miscinit.c:1457 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "не удалось открыть файл \"%s\": %m; ошибка игнорируется" + +#: utils/init/miscinit.c:1482 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "файл блокировки \"%s\" содержит неверный PID: %ld вместо %ld" + +#: utils/init/miscinit.c:1521 utils/init/miscinit.c:1537 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\" не является каталогом данных" + +#: utils/init/miscinit.c:1523 +#, c-format +msgid "File \"%s\" is missing." +msgstr "Файл \"%s\" отсутствует." + +#: utils/init/miscinit.c:1539 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "Файл \"%s\" содержит неприемлемые данные." + +#: utils/init/miscinit.c:1541 +#, c-format +msgid "You might need to initdb." +msgstr "Возможно, вам нужно выполнить initdb." + +#: utils/init/miscinit.c:1549 +#, c-format +msgid "" +"The data directory was initialized by PostgreSQL version %s, which is not " +"compatible with this version %s." +msgstr "" +"Каталог данных инициализирован сервером PostgreSQL версии %s, не совместимой " +"с данной версией (%s)." + +#: utils/init/miscinit.c:1616 +#, c-format +msgid "loaded library \"%s\"" +msgstr "загружена библиотека \"%s\"" + +#: utils/init/postinit.c:253 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "подключение для репликации авторизовано: пользователь=%s" + +#: utils/init/postinit.c:256 +#, c-format +msgid "connection authorized: user=%s" +msgstr "подключение авторизовано: пользователь=%s" + +#: utils/init/postinit.c:259 +#, c-format +msgid " database=%s" +msgstr " база=%s" + +#: utils/init/postinit.c:262 +#, c-format +msgid " application_name=%s" +msgstr " приложение=%s" + +#: utils/init/postinit.c:267 +#, c-format +msgid " SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr " SSL включён (протокол=%s, шифр=%s, битов=%d, сжатие=%s)" + +#: utils/init/postinit.c:271 +msgid "off" +msgstr "выкл." + +#: utils/init/postinit.c:271 +msgid "on" +msgstr "вкл." + +#: utils/init/postinit.c:280 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s, principal=%s)" +msgstr " GSS (аутентификация=%s, шифрование=%s, принципал=%s)" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 +#: utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "no" +msgstr "нет" + +#: utils/init/postinit.c:281 utils/init/postinit.c:282 +#: utils/init/postinit.c:287 utils/init/postinit.c:288 +msgid "yes" +msgstr "да" + +#: utils/init/postinit.c:286 +#, c-format +msgid " GSS (authenticated=%s, encrypted=%s)" +msgstr " GSS (аутентификация=%s, шифрование=%s)" + +#: utils/init/postinit.c:323 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "база данных \"%s\" исчезла из pg_database" + +#: utils/init/postinit.c:325 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "Похоже, базой данных с OID %u теперь владеет \"%s\"." + +#: utils/init/postinit.c:345 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "база \"%s\" не принимает подключения в данный момент" + +#: utils/init/postinit.c:358 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "доступ к базе \"%s\" запрещён" + +#: utils/init/postinit.c:359 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "Пользователь не имеет привилегии CONNECT." + +#: utils/init/postinit.c:376 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "слишком много подключений к БД \"%s\"" + +#: utils/init/postinit.c:398 utils/init/postinit.c:405 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "локаль БД несовместима с операционной системой" + +#: utils/init/postinit.c:399 +#, c-format +msgid "" +"The database was initialized with LC_COLLATE \"%s\", which is not " +"recognized by setlocale()." +msgstr "" +"База данных была инициализирована с параметром LC_COLLATE \"%s\", но сейчас " +"setlocale() не воспринимает его." + +#: utils/init/postinit.c:401 utils/init/postinit.c:408 +#, c-format +msgid "" +"Recreate the database with another locale or install the missing locale." +msgstr "" +"Пересоздайте базу данных с другой локалью или установите поддержку нужной " +"локали." + +#: utils/init/postinit.c:406 +#, c-format +msgid "" +"The database was initialized with LC_CTYPE \"%s\", which is not recognized " +"by setlocale()." +msgstr "" +"База данных была инициализирована с параметром LC_CTYPE \"%s\", но сейчас " +"setlocale() не воспринимает его." + +#: utils/init/postinit.c:751 +#, c-format +msgid "no roles are defined in this database system" +msgstr "в этой системе баз данных не создано ни одной роли" + +#: utils/init/postinit.c:752 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Вы должны немедленно выполнить CREATE USER \"%s\" CREATEUSER;." + +#: utils/init/postinit.c:788 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "" +"новые подключения для репликации не допускаются в процессе остановки БД" + +#: utils/init/postinit.c:792 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "" +"нужно быть суперпользователем, чтобы подключиться в процессе остановки БД" + +#: utils/init/postinit.c:802 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "" +"нужно быть суперпользователем, чтобы подключиться в режиме двоичного " +"обновления" + +#: utils/init/postinit.c:815 +#, c-format +msgid "" +"remaining connection slots are reserved for non-replication superuser " +"connections" +msgstr "" +"оставшиеся слоты подключений зарезервированы для подключений " +"суперпользователя (не для репликации)" + +#: utils/init/postinit.c:825 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "" +"для запуска процесса walsender требуется роль репликации или права " +"суперпользователя" + +#: utils/init/postinit.c:894 +#, c-format +msgid "database %u does not exist" +msgstr "база данных %u не существует" + +#: utils/init/postinit.c:983 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Похоже, она только что была удалена или переименована." + +#: utils/init/postinit.c:1001 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Подкаталог базы данных \"%s\" отсутствует." + +#: utils/init/postinit.c:1006 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "ошибка доступа к каталогу \"%s\": %m" + +#: utils/mb/conv.c:443 utils/mb/conv.c:635 +#, c-format +msgid "invalid encoding number: %d" +msgstr "неверный номер кодировки: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "неожиданный ID кодировки %d для наборов символов ISO 8859" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "неожиданный ID кодировки %d для наборов символов WIN" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:842 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "преобразование %s <-> %s не поддерживается" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "" +"default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "" +"стандартной функции преобразования из кодировки \"%s\" в \"%s\" не существует" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:429 utils/mb/mbutils.c:758 +#: utils/mb/mbutils.c:784 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "Строка из %d байт слишком длинна для преобразования кодировки." + +#: utils/mb/mbutils.c:511 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "неверное имя исходной кодировки: \"%s\"" + +#: utils/mb/mbutils.c:516 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "неверное имя кодировки результата: \"%s\"" + +#: utils/mb/mbutils.c:656 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "недопустимое байтовое значение для кодировки \"%s\": 0x%02x" + +#: utils/mb/mbutils.c:819 +#, c-format +msgid "invalid Unicode code point" +msgstr "неверный код Unicode" + +#: utils/mb/mbutils.c:1087 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "ошибка в bind_textdomain_codeset" + +#: utils/mb/mbutils.c:1595 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "неверная последовательность байт для кодировки \"%s\": %s" + +#: utils/mb/mbutils.c:1628 +#, c-format +msgid "" +"character with byte sequence %s in encoding \"%s\" has no equivalent in " +"encoding \"%s\"" +msgstr "" +"для символа с последовательностью байт %s из кодировки \"%s\" нет " +"эквивалента в \"%s\"" + +#: utils/misc/guc.c:679 +msgid "Ungrouped" +msgstr "Разное" + +#: utils/misc/guc.c:681 +msgid "File Locations" +msgstr "Расположения файлов" + +#: utils/misc/guc.c:683 +msgid "Connections and Authentication" +msgstr "Подключения и аутентификация" + +#: utils/misc/guc.c:685 +msgid "Connections and Authentication / Connection Settings" +msgstr "Подключения и аутентификация / Параметры подключений" + +#: utils/misc/guc.c:687 +msgid "Connections and Authentication / Authentication" +msgstr "Подключения и аутентификация / Аутентификация" + +#: utils/misc/guc.c:689 +msgid "Connections and Authentication / SSL" +msgstr "Подключения и аутентификация / SSL" + +#: utils/misc/guc.c:691 +msgid "Resource Usage" +msgstr "Использование ресурсов" + +#: utils/misc/guc.c:693 +msgid "Resource Usage / Memory" +msgstr "Использование ресурсов / Память" + +#: utils/misc/guc.c:695 +msgid "Resource Usage / Disk" +msgstr "Использование ресурсов / Диск" + +#: utils/misc/guc.c:697 +msgid "Resource Usage / Kernel Resources" +msgstr "Использование ресурсов / Ресурсы ядра" + +#: utils/misc/guc.c:699 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Использование ресурсов / Задержка очистки по стоимости" + +#: utils/misc/guc.c:701 +msgid "Resource Usage / Background Writer" +msgstr "Использование ресурсов / Фоновая запись" + +#: utils/misc/guc.c:703 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Использование ресурсов / Асинхронное поведение" + +#: utils/misc/guc.c:705 +msgid "Write-Ahead Log" +msgstr "Журнал WAL" + +#: utils/misc/guc.c:707 +msgid "Write-Ahead Log / Settings" +msgstr "Журнал WAL / Параметры" + +#: utils/misc/guc.c:709 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Журнал WAL / Контрольные точки" + +#: utils/misc/guc.c:711 +msgid "Write-Ahead Log / Archiving" +msgstr "Журнал WAL / Архивация" + +#: utils/misc/guc.c:713 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Журнал WAL / Восстановление из архива" + +#: utils/misc/guc.c:715 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Журнал WAL / Цель восстановления" + +#: utils/misc/guc.c:717 +msgid "Replication" +msgstr "Репликация" + +#: utils/misc/guc.c:719 +msgid "Replication / Sending Servers" +msgstr "Репликация / Передающие серверы" + +#: utils/misc/guc.c:721 +msgid "Replication / Master Server" +msgstr "Репликация / Главный сервер" + +#: utils/misc/guc.c:723 +msgid "Replication / Standby Servers" +msgstr "Репликация / Резервные серверы" + +#: utils/misc/guc.c:725 +msgid "Replication / Subscribers" +msgstr "Репликация / Подписчики" + +#: utils/misc/guc.c:727 +msgid "Query Tuning" +msgstr "Настройка запросов" + +#: utils/misc/guc.c:729 +msgid "Query Tuning / Planner Method Configuration" +msgstr "Настройка запросов / Конфигурация методов планировщика" + +#: utils/misc/guc.c:731 +msgid "Query Tuning / Planner Cost Constants" +msgstr "Настройка запросов / Константы стоимости для планировщика" + +#: utils/misc/guc.c:733 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "Настройка запросов / Генетический оптимизатор запросов" + +#: utils/misc/guc.c:735 +msgid "Query Tuning / Other Planner Options" +msgstr "Настройка запросов / Другие параметры планировщика" + +#: utils/misc/guc.c:737 +msgid "Reporting and Logging" +msgstr "Отчёты и протоколы" + +#: utils/misc/guc.c:739 +msgid "Reporting and Logging / Where to Log" +msgstr "Отчёты и протоколы / Куда записывать" + +#: utils/misc/guc.c:741 +msgid "Reporting and Logging / When to Log" +msgstr "Отчёты и протоколы / Когда записывать" + +#: utils/misc/guc.c:743 +msgid "Reporting and Logging / What to Log" +msgstr "Отчёты и протоколы / Что записывать" + +#: utils/misc/guc.c:745 +msgid "Process Title" +msgstr "Заголовок процесса" + +#: utils/misc/guc.c:747 +msgid "Statistics" +msgstr "Статистика" + +#: utils/misc/guc.c:749 +msgid "Statistics / Monitoring" +msgstr "Статистика / Мониторинг" + +#: utils/misc/guc.c:751 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "Статистика / Сбор статистики по запросам и индексам" + +#: utils/misc/guc.c:753 +msgid "Autovacuum" +msgstr "Автоочистка" + +#: utils/misc/guc.c:755 +msgid "Client Connection Defaults" +msgstr "Параметры клиентских сеансов по умолчанию" + +#: utils/misc/guc.c:757 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "Параметры клиентских подключений по умолчанию / Поведение команд" + +#: utils/misc/guc.c:759 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "" +"Параметры клиентских подключений по умолчанию / Языковая среда и форматы" + +#: utils/misc/guc.c:761 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "" +"Параметры клиентских подключений по умолчанию / Предзагрузка разделяемых " +"библиотек" + +#: utils/misc/guc.c:763 +msgid "Client Connection Defaults / Other Defaults" +msgstr "Параметры клиентских подключений по умолчанию / Другие параметры" + +#: utils/misc/guc.c:765 +msgid "Lock Management" +msgstr "Управление блокировками" + +#: utils/misc/guc.c:767 +msgid "Version and Platform Compatibility" +msgstr "Совместимость с разными версиями и платформами" + +#: utils/misc/guc.c:769 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Версия и совместимость платформ / Предыдущие версии PostgreSQL" + +#: utils/misc/guc.c:771 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Версия и совместимость платформ / Другие платформы и клиенты" + +#: utils/misc/guc.c:773 +msgid "Error Handling" +msgstr "Обработка ошибок" + +#: utils/misc/guc.c:775 +msgid "Preset Options" +msgstr "Предопределённые параметры" + +#: utils/misc/guc.c:777 +msgid "Customized Options" +msgstr "Внесистемные параметры" + +#: utils/misc/guc.c:779 +msgid "Developer Options" +msgstr "Параметры для разработчиков" + +#: utils/misc/guc.c:837 +msgid "" +"Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "" +"Допустимые единицы измерения для этого параметра: \"B\", \"kB\", \"MB\", \"GB" +"\" и \"TB\"." + +#: utils/misc/guc.c:874 +msgid "" +"Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", " +"and \"d\"." +msgstr "" +"Допустимые единицы измерения для этого параметра: \"us\", \"ms\", \"s\", " +"\"min\", \"h\" и \"d\"." + +#: utils/misc/guc.c:936 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "" +"Разрешает планировщику использовать планы последовательного сканирования." + +#: utils/misc/guc.c:946 +msgid "Enables the planner's use of index-scan plans." +msgstr "Разрешает планировщику использовать планы сканирования по индексу." + +#: utils/misc/guc.c:956 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Разрешает планировщику использовать планы сканирования только индекса." + +#: utils/misc/guc.c:966 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "" +"Разрешает планировщику использовать планы сканирования по битовой карте." + +#: utils/misc/guc.c:976 +msgid "Enables the planner's use of TID scan plans." +msgstr "Разрешает планировщику использовать планы сканирования TID." + +#: utils/misc/guc.c:986 +msgid "Enables the planner's use of explicit sort steps." +msgstr "Разрешает планировщику использовать шаги с явной сортировкой." + +#: utils/misc/guc.c:996 +msgid "Enables the planner's use of incremental sort steps." +msgstr "" +"Разрешает планировщику использовать шаги с инкрементальной сортировкой." + +#: utils/misc/guc.c:1005 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Разрешает планировщику использовать планы агрегирования по хешу." + +#: utils/misc/guc.c:1015 +msgid "Enables the planner's use of materialization." +msgstr "Разрешает планировщику использовать материализацию." + +#: utils/misc/guc.c:1025 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "" +"Разрешает планировщику использовать планы соединения с вложенными циклами." + +#: utils/misc/guc.c:1035 +msgid "Enables the planner's use of merge join plans." +msgstr "Разрешает планировщику использовать планы соединения слиянием." + +#: utils/misc/guc.c:1045 +msgid "Enables the planner's use of hash join plans." +msgstr "Разрешает планировщику использовать планы соединения по хешу." + +#: utils/misc/guc.c:1055 +msgid "Enables the planner's use of gather merge plans." +msgstr "Разрешает планировщику использовать планы сбора слиянием." + +#: utils/misc/guc.c:1065 +msgid "Enables partitionwise join." +msgstr "Включает соединения с учётом секционирования." + +#: utils/misc/guc.c:1075 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Включает агрегирование и группировку с учётом секционирования." + +#: utils/misc/guc.c:1085 +msgid "Enables the planner's use of parallel append plans." +msgstr "Разрешает планировщику использовать планы параллельного добавления." + +#: utils/misc/guc.c:1095 +msgid "Enables the planner's use of parallel hash plans." +msgstr "" +"Разрешает планировщику использовать планы параллельного соединения по хешу." + +#: utils/misc/guc.c:1105 +msgid "Enables plan-time and run-time partition pruning." +msgstr "" +"Включает устранение секций во время планирования и выполнения запросов." + +#: utils/misc/guc.c:1106 +msgid "" +"Allows the query planner and executor to compare partition bounds to " +"conditions in the query to determine which partitions must be scanned." +msgstr "" +"Разрешает планировщику и исполнителю запросов сопоставлять границы секций с " +"условиями в запросе и выделять отдельные секции для сканирования." + +#: utils/misc/guc.c:1117 +msgid "Enables genetic query optimization." +msgstr "Включает генетическую оптимизацию запросов." + +#: utils/misc/guc.c:1118 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Этот алгоритм пытается построить план без полного перебора." + +#: utils/misc/guc.c:1129 +msgid "Shows whether the current user is a superuser." +msgstr "Показывает, является ли текущий пользователь суперпользователем." + +#: utils/misc/guc.c:1139 +msgid "Enables advertising the server via Bonjour." +msgstr "Включает объявление сервера посредством Bonjour." + +#: utils/misc/guc.c:1148 +msgid "Collects transaction commit time." +msgstr "Записывает время фиксации транзакций." + +#: utils/misc/guc.c:1157 +msgid "Enables SSL connections." +msgstr "Разрешает SSL-подключения." + +#: utils/misc/guc.c:1166 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Также использовать ssl_passphrase_command при перезагрузке сервера." + +#: utils/misc/guc.c:1175 +msgid "Give priority to server ciphersuite order." +msgstr "Назначает более приоритетным набор шифров сервера." + +#: utils/misc/guc.c:1184 +msgid "Forces synchronization of updates to disk." +msgstr "Принудительная запись изменений на диск." + +#: utils/misc/guc.c:1185 +msgid "" +"The server will use the fsync() system call in several places to make sure " +"that updates are physically written to disk. This insures that a database " +"cluster will recover to a consistent state after an operating system or " +"hardware crash." +msgstr "" +"Сервер будет вызывать системную функцию fsync() в разных местах для гарантии " +"физической записи данных на диск. Это позволит привести кластер БД в " +"целостное состояние после отказа ОС или оборудования." + +#: utils/misc/guc.c:1196 +msgid "Continues processing after a checksum failure." +msgstr "Продолжает обработку при ошибке контрольной суммы." + +#: utils/misc/guc.c:1197 +msgid "" +"Detection of a checksum failure normally causes PostgreSQL to report an " +"error, aborting the current transaction. Setting ignore_checksum_failure to " +"true causes the system to ignore the failure (but still report a warning), " +"and continue processing. This behavior could cause crashes or other serious " +"problems. Only has an effect if checksums are enabled." +msgstr "" +"Обнаруживая ошибку контрольной суммы, PostgreSQL обычно сообщает об этом и " +"прерывает текущую транзакцию. Но если ignore_checksum_failure равно true, " +"система проигнорирует ошибку (но выдаст предупреждение) и продолжит работу, " +"что может привести к сбоям или другим серьёзным проблемам. Это имеет место, " +"только если включён контроль целостности страниц." + +#: utils/misc/guc.c:1211 +msgid "Continues processing past damaged page headers." +msgstr "Продолжает обработку при повреждении заголовков страниц." + +#: utils/misc/guc.c:1212 +msgid "" +"Detection of a damaged page header normally causes PostgreSQL to report an " +"error, aborting the current transaction. Setting zero_damaged_pages to true " +"causes the system to instead report a warning, zero out the damaged page, " +"and continue processing. This behavior will destroy data, namely all the " +"rows on the damaged page." +msgstr "" +"Обнаруживая повреждённый заголовок страницы, PostgreSQL обычно сообщает об " +"ошибке и прерывает текущую транзакцию. Но если zero_damaged_pages равен " +"true, система выдаст предупреждение, обнулит повреждённую страницу и " +"продолжит работу. Это приведёт к потере данных, а именно строк в " +"повреждённой странице." + +#: utils/misc/guc.c:1225 +msgid "Continues recovery after an invalid pages failure." +msgstr "" +"Продолжает восстановление после ошибок, связанных с неправильными страницами." + +#: utils/misc/guc.c:1226 +msgid "" +"Detection of WAL records having references to invalid pages during recovery " +"causes PostgreSQL to raise a PANIC-level error, aborting the recovery. " +"Setting ignore_invalid_pages to true causes the system to ignore invalid " +"page references in WAL records (but still report a warning), and continue " +"recovery. This behavior may cause crashes, data loss, propagate or hide " +"corruption, or other serious problems. Only has an effect during recovery or " +"in standby mode." +msgstr "" +"Обнаруживая в записях WAL ссылки на неправильные страницы во время " +"восстановления, PostgreSQL выдаёт ошибку уровня ПАНИКА и прерывает " +"восстановление. Если ignore_invalid_pages равен true, система игнорирует " +"такие некорректные ссылки (но всё же выдаёт предупреждение) и продолжает " +"восстановление. Это может привести к краху сервера, потере данных, " +"распространению или сокрытию повреждения данных и другим серьёзным " +"проблемам. Данный параметр действует только при восстановлении или в режиме " +"резервного сервера." + +#: utils/misc/guc.c:1244 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "" +"Запись полных страниц в WAL при первом изменении после контрольной точки." + +#: utils/misc/guc.c:1245 +msgid "" +"A page write in process during an operating system crash might be only " +"partially written to disk. During recovery, the row changes stored in WAL " +"are not enough to recover. This option writes pages when first modified " +"after a checkpoint to WAL so full recovery is possible." +msgstr "" +"Страница, записываемая в момент отказа ОС, может сохраниться на диске не " +"полностью. При этом журнала изменений строк в WAL будет недостаточно для " +"восстановления. С этим параметром в WAL также записывается полная страница " +"при первом изменении после контрольной точки, что позволяет полностью " +"восстановить данные." + +#: utils/misc/guc.c:1258 +msgid "" +"Writes full pages to WAL when first modified after a checkpoint, even for a " +"non-critical modifications." +msgstr "" +"Запись полных страниц в WAL при первом изменении после контрольной точки, " +"даже при некритических изменениях." + +#: utils/misc/guc.c:1268 +msgid "Compresses full-page writes written in WAL file." +msgstr "Сжимать данные при записи полных страниц в журнал." + +#: utils/misc/guc.c:1278 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Записывать нули в новые файлы WAL перед первым использованием." + +#: utils/misc/guc.c:1288 +msgid "Recycles WAL files by renaming them." +msgstr "Перерабатывать файлы WAL, производя переименование." + +#: utils/misc/guc.c:1298 +msgid "Logs each checkpoint." +msgstr "Протоколировать каждую контрольную точку." + +#: utils/misc/guc.c:1307 +msgid "Logs each successful connection." +msgstr "Протоколировать устанавливаемые соединения." + +#: utils/misc/guc.c:1316 +msgid "Logs end of a session, including duration." +msgstr "Протоколировать конец сеанса, отмечая длительность." + +#: utils/misc/guc.c:1325 +msgid "Logs each replication command." +msgstr "Протоколировать каждую команду репликации." + +#: utils/misc/guc.c:1334 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Показывает, включены ли проверки истинности на работающем сервере." + +#: utils/misc/guc.c:1349 +msgid "Terminate session on any error." +msgstr "Завершать сеансы при любой ошибке." + +#: utils/misc/guc.c:1358 +msgid "Reinitialize server after backend crash." +msgstr "Перезапускать систему БД при аварии серверного процесса." + +#: utils/misc/guc.c:1368 +msgid "Logs the duration of each completed SQL statement." +msgstr "Протоколировать длительность каждого выполненного SQL-оператора." + +#: utils/misc/guc.c:1377 +msgid "Logs each query's parse tree." +msgstr "Протоколировать дерево разбора для каждого запроса." + +#: utils/misc/guc.c:1386 +msgid "Logs each query's rewritten parse tree." +msgstr "Протоколировать перезаписанное дерево разбора для каждого запроса." + +#: utils/misc/guc.c:1395 +msgid "Logs each query's execution plan." +msgstr "Протоколировать план выполнения каждого запроса." + +#: utils/misc/guc.c:1404 +msgid "Indents parse and plan tree displays." +msgstr "Отступы при отображении деревьев разбора и плана запросов." + +#: utils/misc/guc.c:1413 +msgid "Writes parser performance statistics to the server log." +msgstr "Запись статистики разбора запросов в протокол сервера." + +#: utils/misc/guc.c:1422 +msgid "Writes planner performance statistics to the server log." +msgstr "Запись статистики планирования в протокол сервера." + +#: utils/misc/guc.c:1431 +msgid "Writes executor performance statistics to the server log." +msgstr "Запись статистики выполнения запросов в протокол сервера." + +#: utils/misc/guc.c:1440 +msgid "Writes cumulative performance statistics to the server log." +msgstr "Запись общей статистики производительности в протокол сервера." + +#: utils/misc/guc.c:1450 +msgid "" +"Logs system resource usage statistics (memory and CPU) on various B-tree " +"operations." +msgstr "" +"Фиксировать статистику использования системных ресурсов (памяти и " +"процессора) при различных операциях с b-деревом." + +#: utils/misc/guc.c:1462 +msgid "Collects information about executing commands." +msgstr "Собирает информацию о выполняющихся командах." + +#: utils/misc/guc.c:1463 +msgid "" +"Enables the collection of information on the currently executing command of " +"each session, along with the time at which that command began execution." +msgstr "" +"Включает сбор информации о командах, выполняющихся во всех сеансах, а также " +"время запуска команды." + +#: utils/misc/guc.c:1473 +msgid "Collects statistics on database activity." +msgstr "Собирает статистику активности в БД." + +#: utils/misc/guc.c:1482 +msgid "Collects timing statistics for database I/O activity." +msgstr "Собирает статистику по времени активности ввода/вывода." + +#: utils/misc/guc.c:1492 +msgid "Updates the process title to show the active SQL command." +msgstr "Выводит в заголовок процесса активную SQL-команду." + +#: utils/misc/guc.c:1493 +msgid "" +"Enables updating of the process title every time a new SQL command is " +"received by the server." +msgstr "Отражает в заголовке процесса каждую SQL-команду, поступающую серверу." + +#: utils/misc/guc.c:1506 +msgid "Starts the autovacuum subprocess." +msgstr "Запускает подпроцесс автоочистки." + +#: utils/misc/guc.c:1516 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "Генерирует отладочные сообщения для LISTEN и NOTIFY." + +#: utils/misc/guc.c:1528 +msgid "Emits information about lock usage." +msgstr "Выдавать информацию о применяемых блокировках." + +#: utils/misc/guc.c:1538 +msgid "Emits information about user lock usage." +msgstr "Выдавать информацию о применяемых пользовательских блокировках." + +#: utils/misc/guc.c:1548 +msgid "Emits information about lightweight lock usage." +msgstr "Выдавать информацию о применяемых лёгких блокировках." + +#: utils/misc/guc.c:1558 +msgid "" +"Dumps information about all current locks when a deadlock timeout occurs." +msgstr "" +"Выводить информацию обо всех текущих блокировках в случае тайм-аута при " +"взаимоблокировке." + +#: utils/misc/guc.c:1570 +msgid "Logs long lock waits." +msgstr "Протоколировать длительные ожидания в блокировках." + +#: utils/misc/guc.c:1580 +msgid "Logs the host name in the connection logs." +msgstr "Записывать имя узла в протоколы подключений." + +#: utils/misc/guc.c:1581 +msgid "" +"By default, connection logs only show the IP address of the connecting host. " +"If you want them to show the host name you can turn this on, but depending " +"on your host name resolution setup it might impose a non-negligible " +"performance penalty." +msgstr "" +"По умолчанию в протоколах подключений показываются только IP-адреса " +"клиентов. Если вы хотите видеть также имена компьютеров, включите этот " +"параметр, но учтите, что это может значительно повлиять на " +"производительность." + +#: utils/misc/guc.c:1592 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "Обрабатывать \"expr=NULL\" как \"expr IS NULL\"." + +#: utils/misc/guc.c:1593 +msgid "" +"When turned on, expressions of the form expr = NULL (or NULL = expr) are " +"treated as expr IS NULL, that is, they return true if expr evaluates to the " +"null value, and false otherwise. The correct behavior of expr = NULL is to " +"always return null (unknown)." +msgstr "" +"Когда этот параметр включён, выражения вида expr = NULL (или NULL = expr) " +"обрабатываются как expr IS NULL, то есть возвращают true, если expr " +"совпадает с NULL, и false в противном случае. По правилам expr = NULL всегда " +"должно возвращать null (неопределённость)." + +#: utils/misc/guc.c:1605 +msgid "Enables per-database user names." +msgstr "Включает связывание имён пользователей с базами данных." + +#: utils/misc/guc.c:1614 +msgid "Sets the default read-only status of new transactions." +msgstr "" +"Устанавливает режим \"только чтение\" по умолчанию для новых транзакций." + +#: utils/misc/guc.c:1623 +msgid "Sets the current transaction's read-only status." +msgstr "Устанавливает режим \"только чтение\" для текущей транзакции." + +#: utils/misc/guc.c:1633 +msgid "Sets the default deferrable status of new transactions." +msgstr "" +"Устанавливает режим отложенного выполнения по умолчанию для новых транзакций." + +#: utils/misc/guc.c:1642 +msgid "" +"Whether to defer a read-only serializable transaction until it can be " +"executed with no possible serialization failures." +msgstr "" +"Определяет, откладывать ли сериализуемую транзакцию \"только чтение\" до " +"момента, когда сбой сериализации будет исключён." + +#: utils/misc/guc.c:1652 +msgid "Enable row security." +msgstr "Включает защиту на уровне строк." + +#: utils/misc/guc.c:1653 +msgid "When enabled, row security will be applied to all users." +msgstr "" +"Когда включена, защита на уровне строк распространяется на всех " +"пользователей." + +#: utils/misc/guc.c:1661 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "Проверять тело функций в момент CREATE FUNCTION." + +#: utils/misc/guc.c:1670 +msgid "Enable input of NULL elements in arrays." +msgstr "Разрешать ввод элементов NULL в массивах." + +#: utils/misc/guc.c:1671 +msgid "" +"When turned on, unquoted NULL in an array input value means a null value; " +"otherwise it is taken literally." +msgstr "" +"Когда этот параметр включён, NULL без кавычек при вводе в массив " +"воспринимается как значение NULL, иначе — как строка." + +#: utils/misc/guc.c:1687 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "" +"WITH OIDS более не поддерживается; единственное допустимое значение — false." + +#: utils/misc/guc.c:1697 +msgid "" +"Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "" +"Запускает подпроцесс для чтения stderr и/или csv-файлов и записи в файлы " +"протоколов." + +#: utils/misc/guc.c:1706 +msgid "Truncate existing log files of same name during log rotation." +msgstr "" +"Очищать уже существующий файл с тем же именем при прокручивании протокола." + +#: utils/misc/guc.c:1717 +msgid "Emit information about resource usage in sorting." +msgstr "Выдавать сведения об использовании ресурсов при сортировке." + +#: utils/misc/guc.c:1731 +msgid "Generate debugging output for synchronized scanning." +msgstr "Выдавать отладочные сообщения для синхронного сканирования." + +#: utils/misc/guc.c:1746 +msgid "Enable bounded sorting using heap sort." +msgstr "" +"Разрешить ограниченную сортировку с применением пирамидальной сортировки." + +#: utils/misc/guc.c:1759 +msgid "Emit WAL-related debugging output." +msgstr "Выдавать отладочные сообщения, связанные с WAL." + +#: utils/misc/guc.c:1771 +msgid "Datetimes are integer based." +msgstr "Целочисленная реализация даты/времени." + +#: utils/misc/guc.c:1782 +msgid "" +"Sets whether Kerberos and GSSAPI user names should be treated as case-" +"insensitive." +msgstr "" +"Включает регистронезависимую обработку имён пользователей Kerberos и GSSAPI." + +#: utils/misc/guc.c:1792 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Предупреждения о спецсимволах '\\' в обычных строках." + +#: utils/misc/guc.c:1802 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "Включает буквальную обработку символов '\\' в строках '...'." + +#: utils/misc/guc.c:1813 +msgid "Enable synchronized sequential scans." +msgstr "Включить синхронизацию последовательного сканирования." + +#: utils/misc/guc.c:1823 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Определяет, включать ли транзакцию в целевую точку восстановления." + +#: utils/misc/guc.c:1833 +msgid "Allows connections and queries during recovery." +msgstr "" +"Разрешает принимать новые подключения и запросы в процессе восстановления." + +#: utils/misc/guc.c:1843 +msgid "" +"Allows feedback from a hot standby to the primary that will avoid query " +"conflicts." +msgstr "" +"Разрешает обратную связь сервера горячего резерва с основным для " +"предотвращения конфликтов при длительных запросах." + +#: utils/misc/guc.c:1853 +msgid "Allows modifications of the structure of system tables." +msgstr "Разрешает модифицировать структуру системных таблиц." + +#: utils/misc/guc.c:1864 +msgid "Disables reading from system indexes." +msgstr "Запрещает использование системных индексов." + +#: utils/misc/guc.c:1865 +msgid "" +"It does not prevent updating the indexes, so it is safe to use. The worst " +"consequence is slowness." +msgstr "" +"При этом индексы продолжают обновляться, так что данное поведение безопасно. " +"Худшее следствие - замедление." + +#: utils/misc/guc.c:1876 +msgid "" +"Enables backward compatibility mode for privilege checks on large objects." +msgstr "" +"Включает режим обратной совместимости при проверке привилегий для больших " +"объектов." + +#: utils/misc/guc.c:1877 +msgid "" +"Skips privilege checks when reading or modifying large objects, for " +"compatibility with PostgreSQL releases prior to 9.0." +msgstr "" +"Пропускает проверки привилегий при чтении или изменении больших объектов " +"(для совместимости с версиями PostgreSQL до 9.0)." + +#: utils/misc/guc.c:1887 +msgid "" +"Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "" +"Выдаёт предупреждение о конструкциях, поведение которых изменилось после " +"PostgreSQL 9.4." + +#: utils/misc/guc.c:1897 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "" +"Генерируя SQL-фрагменты, заключать все идентификаторы в двойные кавычки." + +#: utils/misc/guc.c:1907 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Показывает, включён ли в этом кластере контроль целостности данных." + +#: utils/misc/guc.c:1918 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "" +"Добавлять последовательный номер в сообщения syslog во избежание подавления " +"повторов." + +#: utils/misc/guc.c:1928 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "" +"Разбивать сообщения, передаваемые в syslog, по строкам размером не больше " +"1024 байт." + +#: utils/misc/guc.c:1938 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "" +"Определяет, будут ли узлы сбора и сбора слиянием также выполнять подпланы." + +#: utils/misc/guc.c:1939 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "" +"Должны ли узлы сбора также выполнять подпланы или только собирать кортежи?" + +#: utils/misc/guc.c:1949 +msgid "Allow JIT compilation." +msgstr "Включить JIT-компиляцию." + +#: utils/misc/guc.c:1960 +msgid "Register JIT compiled function with debugger." +msgstr "Регистрировать JIT-скомпилированные функции в отладчике." + +#: utils/misc/guc.c:1977 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Выводить битовый код LLVM для облегчения отладки JIT." + +#: utils/misc/guc.c:1988 +msgid "Allow JIT compilation of expressions." +msgstr "Включить JIT-компиляцию выражений." + +#: utils/misc/guc.c:1999 +msgid "Register JIT compiled function with perf profiler." +msgstr "Регистрировать JIT-компилируемые функции в профилировщике perf." + +#: utils/misc/guc.c:2016 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Разрешить JIT-компиляцию кода преобразования кортежей." + +#: utils/misc/guc.c:2027 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Продолжать работу после ошибки при сохранении файлов данных на диске." + +#: utils/misc/guc.c:2036 +msgid "" +"Sets whether a WAL receiver should create a temporary replication slot if no " +"permanent slot is configured." +msgstr "" +"Определяет, должен ли приёмник WAL создавать временный слот репликации, если " +"не настроен постоянный слот." + +#: utils/misc/guc.c:2054 +msgid "" +"Forces a switch to the next WAL file if a new file has not been started " +"within N seconds." +msgstr "" +"Принудительно переключаться на следующий файл WAL, если начать новый файл за " +"N секунд не удалось." + +#: utils/misc/guc.c:2065 +msgid "Waits N seconds on connection startup after authentication." +msgstr "Ждать N секунд при подключении после проверки подлинности." + +#: utils/misc/guc.c:2066 utils/misc/guc.c:2624 +msgid "This allows attaching a debugger to the process." +msgstr "Это позволяет подключить к процессу отладчик." + +#: utils/misc/guc.c:2075 +msgid "Sets the default statistics target." +msgstr "Устанавливает ориентир статистики по умолчанию." + +#: utils/misc/guc.c:2076 +msgid "" +"This applies to table columns that have not had a column-specific target set " +"via ALTER TABLE SET STATISTICS." +msgstr "" +"Это значение распространяется на столбцы таблицы, для которых ориентир " +"статистики не задан явно через ALTER TABLE SET STATISTICS." + +#: utils/misc/guc.c:2085 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "" +"Задаёт предел для списка FROM, при превышении которого подзапросы не " +"сворачиваются." + +#: utils/misc/guc.c:2087 +msgid "" +"The planner will merge subqueries into upper queries if the resulting FROM " +"list would have no more than this many items." +msgstr "" +"Планировщик объединит вложенные запросы с внешними, если в полученном списке " +"FROM будет не больше заданного числа элементов." + +#: utils/misc/guc.c:2098 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "" +"Задаёт предел для списка FROM, при превышении которого конструкции JOIN " +"сохраняются." + +#: utils/misc/guc.c:2100 +msgid "" +"The planner will flatten explicit JOIN constructs into lists of FROM items " +"whenever a list of no more than this many items would result." +msgstr "" +"Планировщик будет сносить явные конструкции JOIN в списки FROM, пока в " +"результирующем списке не больше заданного числа элементов." + +#: utils/misc/guc.c:2111 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "" +"Задаёт предел для списка FROM, при превышении которого применяется GEQO." + +#: utils/misc/guc.c:2121 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "" +"GEQO: оценка усилий для планирования, задающая значения по умолчанию для " +"других параметров GEQO." + +#: utils/misc/guc.c:2131 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: число особей в популяции." + +#: utils/misc/guc.c:2132 utils/misc/guc.c:2142 +msgid "Zero selects a suitable default value." +msgstr "При нуле выбирается подходящее значение по умолчанию." + +#: utils/misc/guc.c:2141 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: число итераций алгоритма." + +#: utils/misc/guc.c:2153 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Задаёт интервал ожидания в блокировке до проверки на взаимоблокировку." + +#: utils/misc/guc.c:2164 +msgid "" +"Sets the maximum delay before canceling queries when a hot standby server is " +"processing archived WAL data." +msgstr "" +"Задаёт максимальную задержку до отмены запроса, когда сервер горячего " +"резерва обрабатывает данные WAL из архива." + +#: utils/misc/guc.c:2175 +msgid "" +"Sets the maximum delay before canceling queries when a hot standby server is " +"processing streamed WAL data." +msgstr "" +"Задаёт максимальную задержку до отмены запроса, когда сервер горячего " +"резерва обрабатывает данные WAL из потока." + +#: utils/misc/guc.c:2186 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "" +"Задаёт минимальную задержку для применения изменений в процессе " +"восстановления." + +#: utils/misc/guc.c:2197 +msgid "" +"Sets the maximum interval between WAL receiver status reports to the sending " +"server." +msgstr "" +"Задаёт максимальный интервал между отчётами о состоянии приёмника WAL, " +"отправляемыми передающему серверу." + +#: utils/misc/guc.c:2208 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "" +"Задаёт предельное время ожидания для получения данных от передающего сервера." + +#: utils/misc/guc.c:2219 +msgid "Sets the maximum number of concurrent connections." +msgstr "Задаёт максимально возможное число подключений." + +#: utils/misc/guc.c:2230 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "" +"Определяет, сколько слотов подключений забронировано для суперпользователей." + +#: utils/misc/guc.c:2244 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Задаёт количество буферов в разделяемой памяти, используемых сервером." + +#: utils/misc/guc.c:2255 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Задаёт предельное число временных буферов на один сеанс." + +#: utils/misc/guc.c:2266 +msgid "Sets the TCP port the server listens on." +msgstr "Задаёт TCP-порт для работы сервера." + +#: utils/misc/guc.c:2276 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Задаёт права доступа для Unix-сокета." + +#: utils/misc/guc.c:2277 +msgid "" +"Unix-domain sockets use the usual Unix file system permission set. The " +"parameter value is expected to be a numeric mode specification in the form " +"accepted by the chmod and umask system calls. (To use the customary octal " +"format the number must start with a 0 (zero).)" +msgstr "" +"Для Unix-сокетов используется обычный набор разрешений, как в файловых " +"системах Unix. Значение параметра указывается в числовом виде, " +"воспринимаемом системными функциями chmod и umask. (Чтобы использовать " +"привычный восьмеричный формат, добавьте в начало ноль (0).)" + +#: utils/misc/guc.c:2291 +msgid "Sets the file permissions for log files." +msgstr "Задаёт права доступа к файлам протоколов." + +#: utils/misc/guc.c:2292 +msgid "" +"The parameter value is expected to be a numeric mode specification in the " +"form accepted by the chmod and umask system calls. (To use the customary " +"octal format the number must start with a 0 (zero).)" +msgstr "" +"Значение параметра указывается в числовом виде, воспринимаемом системными " +"функциями chmod и umask. (Чтобы использовать привычный восьмеричный формат, " +"добавьте в начало ноль (0).)" + +#: utils/misc/guc.c:2306 +msgid "Mode of the data directory." +msgstr "Режим каталога данных." + +#: utils/misc/guc.c:2307 +msgid "" +"The parameter value is a numeric mode specification in the form accepted by " +"the chmod and umask system calls. (To use the customary octal format the " +"number must start with a 0 (zero).)" +msgstr "" +"Значение параметра указывается в числовом виде, воспринимаемом системными " +"функциями chmod и umask. (Чтобы использовать привычный восьмеричный формат, " +"добавьте в начало ноль (0).)" + +#: utils/misc/guc.c:2320 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Задаёт предельный объём памяти для рабочих пространств запросов." + +#: utils/misc/guc.c:2321 +msgid "" +"This much memory can be used by each internal sort operation and hash table " +"before switching to temporary disk files." +msgstr "" +"Такой объём памяти может использоваться каждой внутренней операцией " +"сортировки и таблицей хешей до переключения на временные файлы на диске." + +#: utils/misc/guc.c:2333 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Задаёт предельный объём памяти для операций по обслуживанию." + +#: utils/misc/guc.c:2334 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Подразумеваются в частности операции VACUUM и CREATE INDEX." + +#: utils/misc/guc.c:2344 +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "Задаёт предельный объём памяти для логического декодирования." + +#: utils/misc/guc.c:2345 +msgid "" +"This much memory can be used by each internal reorder buffer before spilling " +"to disk." +msgstr "" +"Такой объём памяти может использоваться каждым внутренним буфером " +"пересортировки до вымещения данных на диск." + +#: utils/misc/guc.c:2361 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Задаёт максимальную глубину стека (в КБ)." + +#: utils/misc/guc.c:2372 +msgid "Limits the total size of all temporary files used by each process." +msgstr "" +"Ограничивает общий размер всех временных файлов, доступный для каждого " +"процесса." + +#: utils/misc/guc.c:2373 +msgid "-1 means no limit." +msgstr "-1 отключает ограничение." + +#: utils/misc/guc.c:2383 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Стоимость очистки для страницы, найденной в кеше." + +#: utils/misc/guc.c:2393 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Стоимость очистки для страницы, не найденной в кеше." + +#: utils/misc/guc.c:2403 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Стоимость очистки для страницы, которая не была \"грязной\"." + +#: utils/misc/guc.c:2413 +msgid "Vacuum cost amount available before napping." +msgstr "Суммарная стоимость очистки, при которой нужна передышка." + +#: utils/misc/guc.c:2423 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "" +"Суммарная стоимость очистки, при которой нужна передышка, для автоочистки." + +#: utils/misc/guc.c:2433 +msgid "" +"Sets the maximum number of simultaneously open files for each server process." +msgstr "" +"Задаёт предельное число одновременно открытых файлов для каждого серверного " +"процесса." + +#: utils/misc/guc.c:2446 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Задаёт предельное число одновременно подготовленных транзакций." + +#: utils/misc/guc.c:2457 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Задаёт минимальный OID таблиц, для которых отслеживаются блокировки." + +#: utils/misc/guc.c:2458 +msgid "Is used to avoid output on system tables." +msgstr "Применяется для игнорирования системных таблиц." + +#: utils/misc/guc.c:2467 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "Задаёт OID таблицы для безусловного отслеживания блокировок." + +#: utils/misc/guc.c:2479 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Задаёт предельную длительность для любого оператора." + +#: utils/misc/guc.c:2480 utils/misc/guc.c:2491 utils/misc/guc.c:2502 +msgid "A value of 0 turns off the timeout." +msgstr "Нулевое значение отключает тайм-аут." + +#: utils/misc/guc.c:2490 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Задаёт максимальную продолжительность ожидания блокировок." + +#: utils/misc/guc.c:2501 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "Задаёт предельно допустимую длительность для простаивающих транзакций." + +#: utils/misc/guc.c:2512 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "" +"Минимальный возраст строк таблицы, при котором VACUUM может их заморозить." + +#: utils/misc/guc.c:2522 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "" +"Возраст, при котором VACUUM должен сканировать всю таблицу с целью " +"заморозить кортежи." + +#: utils/misc/guc.c:2532 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "" +"Минимальный возраст, при котором VACUUM будет замораживать MultiXactId в " +"строке таблицы." + +#: utils/misc/guc.c:2542 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "" +"Возраст multixact, при котором VACUUM должен сканировать всю таблицу с целью " +"заморозить кортежи." + +#: utils/misc/guc.c:2552 +msgid "" +"Number of transactions by which VACUUM and HOT cleanup should be deferred, " +"if any." +msgstr "" +"Определяет, на сколько транзакций следует задержать старые строки, выполняя " +"VACUUM или \"горячее\" обновление." + +#: utils/misc/guc.c:2565 +msgid "Sets the maximum number of locks per transaction." +msgstr "Задаёт предельное число блокировок на транзакцию." + +#: utils/misc/guc.c:2566 +msgid "" +"The shared lock table is sized on the assumption that at most " +"max_locks_per_transaction * max_connections distinct objects will need to be " +"locked at any one time." +msgstr "" +"Размер разделяемой таблицы блокировок выбирается из предположения, что в " +"один момент времени потребуется заблокировать не больше чем " +"max_locks_per_transaction * max_connections различных объектов." + +#: utils/misc/guc.c:2577 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Задаёт предельное число предикатных блокировок на транзакцию." + +#: utils/misc/guc.c:2578 +msgid "" +"The shared predicate lock table is sized on the assumption that at most " +"max_pred_locks_per_transaction * max_connections distinct objects will need " +"to be locked at any one time." +msgstr "" +"Размер разделяемой таблицы предикатных блокировок выбирается из " +"предположения, что в один момент времени потребуется заблокировать не больше " +"чем max_pred_locks_per_transaction * max_connections различных объектов." + +#: utils/misc/guc.c:2589 +msgid "" +"Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "" +"Задаёт максимальное число страниц и кортежей, блокируемых предикатными " +"блокировками в одном отношении." + +#: utils/misc/guc.c:2590 +msgid "" +"If more than this total of pages and tuples in the same relation are locked " +"by a connection, those locks are replaced by a relation-level lock." +msgstr "" +"Если одним соединением блокируется больше этого общего числа страниц и " +"кортежей, эти блокировки заменяются блокировкой на уровне отношения." + +#: utils/misc/guc.c:2600 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "" +"Задаёт максимальное число кортежей, блокируемых предикатными блокировками в " +"одной странице." + +#: utils/misc/guc.c:2601 +msgid "" +"If more than this number of tuples on the same page are locked by a " +"connection, those locks are replaced by a page-level lock." +msgstr "" +"Если одним соединением блокируется больше этого числа кортежей на одной " +"странице, эти блокировки заменяются блокировкой на уровне страницы." + +#: utils/misc/guc.c:2611 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "Ограничивает время, за которое клиент должен пройти аутентификацию." + +#: utils/misc/guc.c:2623 +msgid "Waits N seconds on connection startup before authentication." +msgstr "Ждать N секунд при подключении до проверки подлинности." + +#: utils/misc/guc.c:2634 +msgid "Sets the size of WAL files held for standby servers." +msgstr "" +"Определяет предельный объём файлов WAL, сохраняемых для резервных серверов." + +#: utils/misc/guc.c:2645 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "Задаёт минимальный размер WAL при сжатии." + +#: utils/misc/guc.c:2657 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Задаёт размер WAL, при котором инициируется контрольная точка." + +#: utils/misc/guc.c:2669 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "" +"Задаёт максимальное время между автоматическими контрольными точками WAL." + +#: utils/misc/guc.c:2680 +msgid "" +"Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "" +"Выдаёт предупреждения, когда сегменты контрольных точек заполняются за это " +"время." + +#: utils/misc/guc.c:2682 +msgid "" +"Write a message to the server log if checkpoints caused by the filling of " +"checkpoint segment files happens more frequently than this number of " +"seconds. Zero turns off the warning." +msgstr "" +"Записывает в протокол сервера сообщения, когда контрольные точки, вызванные " +"переполнением файлов сегментов, происходят за столько секунд. Нулевое " +"значение отключает эти предупреждения." + +#: utils/misc/guc.c:2694 utils/misc/guc.c:2910 utils/misc/guc.c:2957 +msgid "" +"Number of pages after which previously performed writes are flushed to disk." +msgstr "" +"Число страниц, по достижении которого ранее выполненные операции записи " +"сбрасываются на диск." + +#: utils/misc/guc.c:2705 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "Задаёт число буферов дисковых страниц в разделяемой памяти для WAL." + +#: utils/misc/guc.c:2716 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "Задержка между сбросом WAL в процессе, записывающем WAL." + +#: utils/misc/guc.c:2727 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "" +"Объём WAL, обработанный пишущим WAL процессом, при котором инициируется " +"сброс журнала на диск." + +#: utils/misc/guc.c:2738 +msgid "Size of new file to fsync instead of writing WAL." +msgstr "" +"Объём нового файла, при достижении которого файл не пишется в WAL, а " +"сбрасывается на диск." + +#: utils/misc/guc.c:2749 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "" +"Задаёт предельное число одновременно работающих процессов передачи WAL." + +#: utils/misc/guc.c:2760 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Задаёт предельное число одновременно существующих слотов репликации." + +#: utils/misc/guc.c:2770 +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "" +"Задаёт максимальный размер WAL, который могут резервировать слоты репликации." + +#: utils/misc/guc.c:2771 +msgid "" +"Replication slots will be marked as failed, and segments released for " +"deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "" +"Если объём WAL на диске достигнет этого значения, слоты репликации будут " +"помечены как нерабочие, а сегменты будут освобождены для удаления или " +"переработки." + +#: utils/misc/guc.c:2783 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "Задаёт предельное время ожидания репликации WAL." + +#: utils/misc/guc.c:2794 +msgid "" +"Sets the delay in microseconds between transaction commit and flushing WAL " +"to disk." +msgstr "" +"Задаёт задержку в микросекундах между фиксированием транзакций и сбросом WAL " +"на диск." + +#: utils/misc/guc.c:2806 +msgid "" +"Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "" +"Задаёт минимальное число одновременно открытых транзакций для применения " +"commit_delay." + +#: utils/misc/guc.c:2817 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Задаёт число выводимых цифр для чисел с плавающей точкой." + +#: utils/misc/guc.c:2818 +msgid "" +"This affects real, double precision, and geometric data types. A zero or " +"negative parameter value is added to the standard number of digits (FLT_DIG " +"or DBL_DIG as appropriate). Any value greater than zero selects precise " +"output mode." +msgstr "" +"Этот параметр относится к типам real, double и geometric. Нулевое или " +"отрицательное значение параметра прибавляется к стандартному числу цифр " +"(FLT_DIG или DBL_DIG соответственно). Положительное значение включает режим " +"точного вывода." + +#: utils/misc/guc.c:2830 +msgid "" +"Sets the minimum execution time above which a sample of statements will be " +"logged. Sampling is determined by log_statement_sample_rate." +msgstr "" +"Задаёт предельное время выполнения оператора из выборки, при превышении " +"которого он выводится в журнал. Выборка определяется параметром " +"log_statement_sample_rate." + +#: utils/misc/guc.c:2833 +msgid "Zero logs a sample of all queries. -1 turns this feature off." +msgstr "При 0 выводятся все запросы в выборке; -1 отключает эти сообщения." + +#: utils/misc/guc.c:2843 +msgid "" +"Sets the minimum execution time above which all statements will be logged." +msgstr "" +"Задаёт предельное время выполнения любого оператора, при превышении которого " +"он выводится в журнал." + +#: utils/misc/guc.c:2845 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "При 0 выводятся все запросы; -1 отключает эти сообщения." + +#: utils/misc/guc.c:2855 +msgid "" +"Sets the minimum execution time above which autovacuum actions will be " +"logged." +msgstr "" +"Задаёт предельное время выполнения автоочистки, при превышении которого эта " +"операция протоколируется в журнале." + +#: utils/misc/guc.c:2857 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "" +"При 0 протоколируются все операции автоочистки; -1 отключает эти сообщения." + +#: utils/misc/guc.c:2867 +msgid "" +"When logging statements, limit logged parameter values to first N bytes." +msgstr "" +"Обрезать длинные значения параметров выводимых в журнал операторов до первых " +"N байт." + +#: utils/misc/guc.c:2868 utils/misc/guc.c:2879 +msgid "-1 to print values in full." +msgstr "При -1 значения выводятся полностью." + +#: utils/misc/guc.c:2878 +msgid "" +"When reporting an error, limit logged parameter values to first N bytes." +msgstr "" +"Обрезать значения параметров, выводимые в сообщениях об ошибках, до первых N " +"байт." + +#: utils/misc/guc.c:2889 +msgid "Background writer sleep time between rounds." +msgstr "Время простоя в процессе фоновой записи между подходами." + +#: utils/misc/guc.c:2900 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "" +"Максимальное число LRU-страниц, сбрасываемых за один подход, в процессе " +"фоновой записи." + +#: utils/misc/guc.c:2923 +msgid "" +"Number of simultaneous requests that can be handled efficiently by the disk " +"subsystem." +msgstr "" +"Число одновременных запросов, которые могут быть эффективно обработаны " +"дисковой подсистемой." + +#: utils/misc/guc.c:2924 +msgid "" +"For RAID arrays, this should be approximately the number of drive spindles " +"in the array." +msgstr "" +"Для RAID-массивов это примерно равно числу физических дисков в массиве." + +#: utils/misc/guc.c:2941 +msgid "" +"A variant of effective_io_concurrency that is used for maintenance work." +msgstr "" +"Вариация параметра effective_io_concurrency, предназначенная для операций " +"обслуживания БД." + +#: utils/misc/guc.c:2970 +msgid "Maximum number of concurrent worker processes." +msgstr "Задаёт максимально возможное число рабочих процессов." + +#: utils/misc/guc.c:2982 +msgid "Maximum number of logical replication worker processes." +msgstr "" +"Задаёт максимально возможное число рабочих процессов логической репликации." + +#: utils/misc/guc.c:2994 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "" +"Задаёт максимально возможное число процессов синхронизации таблиц для одной " +"подписки." + +#: utils/misc/guc.c:3004 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "Автоматическая прокрутка файла протокола через каждые N минут." + +#: utils/misc/guc.c:3015 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "" +"Автоматическая прокрутка файла протокола при выходе за предел N килобайт." + +#: utils/misc/guc.c:3026 +msgid "Shows the maximum number of function arguments." +msgstr "Показывает максимально возможное число аргументов функций." + +#: utils/misc/guc.c:3037 +msgid "Shows the maximum number of index keys." +msgstr "Показывает максимально возможное число ключей в индексе." + +#: utils/misc/guc.c:3048 +msgid "Shows the maximum identifier length." +msgstr "Показывает максимально возможную длину идентификатора." + +#: utils/misc/guc.c:3059 +msgid "Shows the size of a disk block." +msgstr "Показывает размер дискового блока." + +#: utils/misc/guc.c:3070 +msgid "Shows the number of pages per disk file." +msgstr "Показывает число страниц в одном файле." + +#: utils/misc/guc.c:3081 +msgid "Shows the block size in the write ahead log." +msgstr "Показывает размер блока в журнале WAL." + +#: utils/misc/guc.c:3092 +msgid "" +"Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "" +"Задаёт время задержки перед повторной попыткой обращения к WAL после неудачи." + +#: utils/misc/guc.c:3104 +msgid "Shows the size of write ahead log segments." +msgstr "Показывает размер сегментов журнала предзаписи." + +#: utils/misc/guc.c:3117 +msgid "Time to sleep between autovacuum runs." +msgstr "Время простоя между запусками автоочистки." + +#: utils/misc/guc.c:3127 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Минимальное число изменений или удалений кортежей, вызывающее очистку." + +#: utils/misc/guc.c:3136 +msgid "" +"Minimum number of tuple inserts prior to vacuum, or -1 to disable insert " +"vacuums." +msgstr "" +"Минимальное число добавлений кортежей, вызывающее очистку; при -1 такая " +"очистка отключается." + +#: utils/misc/guc.c:3145 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "" +"Минимальное число добавлений, изменений или удалений кортежей, вызывающее " +"анализ." + +#: utils/misc/guc.c:3155 +msgid "" +"Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "" +"Возраст, при котором необходима автоочистка таблицы для предотвращения " +"зацикливания ID транзакций." + +#: utils/misc/guc.c:3166 +msgid "" +"Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "" +"Возраст multixact, при котором необходима автоочистка таблицы для " +"предотвращения зацикливания multixact." + +#: utils/misc/guc.c:3176 +msgid "" +"Sets the maximum number of simultaneously running autovacuum worker " +"processes." +msgstr "" +"Задаёт предельное число одновременно выполняющихся рабочих процессов " +"автоочистки." + +#: utils/misc/guc.c:3186 +msgid "" +"Sets the maximum number of parallel processes per maintenance operation." +msgstr "" +"Задаёт максимальное число параллельных процессов на одну операцию " +"обслуживания." + +#: utils/misc/guc.c:3196 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Задаёт максимальное число параллельных процессов на узел исполнителя." + +#: utils/misc/guc.c:3207 +msgid "" +"Sets the maximum number of parallel workers that can be active at one time." +msgstr "" +"Задаёт максимальное число параллельных процессов, которые могут быть активны " +"одновременно." + +#: utils/misc/guc.c:3218 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "" +"Задаёт предельный объём памяти для каждого рабочего процесса автоочистки." + +#: utils/misc/guc.c:3229 +msgid "" +"Time before a snapshot is too old to read pages changed after the snapshot " +"was taken." +msgstr "" +"Срок, по истечении которого снимок считается слишком старым для получения " +"страниц, изменённых после создания снимка." + +#: utils/misc/guc.c:3230 +msgid "A value of -1 disables this feature." +msgstr "Значение -1 отключает это поведение." + +#: utils/misc/guc.c:3240 +msgid "Time between issuing TCP keepalives." +msgstr "Интервал между TCP-пакетами пульса (keep-alive)." + +#: utils/misc/guc.c:3241 utils/misc/guc.c:3252 utils/misc/guc.c:3376 +msgid "A value of 0 uses the system default." +msgstr "При нулевом значении действует системный параметр." + +#: utils/misc/guc.c:3251 +msgid "Time between TCP keepalive retransmits." +msgstr "Интервал между повторениями TCP-пакетов пульса (keep-alive)." + +#: utils/misc/guc.c:3262 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "" +"Повторное согласование SSL более не поддерживается; единственное допустимое " +"значение - 0." + +#: utils/misc/guc.c:3273 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "Максимальное число повторений TCP-пакетов пульса (keep-alive)." + +#: utils/misc/guc.c:3274 +msgid "" +"This controls the number of consecutive keepalive retransmits that can be " +"lost before a connection is considered dead. A value of 0 uses the system " +"default." +msgstr "" +"Этот параметр определяет, сколько пакетов пульса подряд может быть потеряно, " +"прежде чем соединение будет считаться пропавшим. При нулевом значении " +"действует системный параметр." + +#: utils/misc/guc.c:3285 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "Ограничивает результат точного поиска с использованием GIN." + +#: utils/misc/guc.c:3296 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Подсказывает планировщику примерный общий размер кешей данных." + +#: utils/misc/guc.c:3297 +msgid "" +"That is, the total size of the caches (kernel cache and shared buffers) used " +"for PostgreSQL data files. This is measured in disk pages, which are " +"normally 8 kB each." +msgstr "" +"Подразумевается общий размер кешей (кеша ядра и общих буферов), в которые " +"попадают файлы данных PostgreSQL. Размер задаётся в дисковых страницах " +"(обычно это 8 КБ)." + +#: utils/misc/guc.c:3308 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "" +"Задаёт минимальный объём данных в таблице для параллельного сканирования." + +#: utils/misc/guc.c:3309 +msgid "" +"If the planner estimates that it will read a number of table pages too small " +"to reach this limit, a parallel scan will not be considered." +msgstr "" +"Если планировщик полагает, что он прочитает меньше страниц таблицы, чем " +"задано этим ограничением, он исключает параллельное сканирование из " +"рассмотрения." + +#: utils/misc/guc.c:3319 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "" +"Задаёт минимальный объём данных в индексе для параллельного сканирования." + +#: utils/misc/guc.c:3320 +msgid "" +"If the planner estimates that it will read a number of index pages too small " +"to reach this limit, a parallel scan will not be considered." +msgstr "" +"Если планировщик полагает, что он прочитает меньше страниц индекса, чем " +"задано этим ограничением, он исключает параллельное сканирование из " +"рассмотрения." + +#: utils/misc/guc.c:3331 +msgid "Shows the server version as an integer." +msgstr "Показывает версию сервера в виде целого числа." + +#: utils/misc/guc.c:3342 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "" +"Фиксирует в протоколе превышение временными файлами заданного размера (в КБ)." + +#: utils/misc/guc.c:3343 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "" +"При 0 отмечаются все файлы; при -1 эти сообщения отключаются (по умолчанию)." + +#: utils/misc/guc.c:3353 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "Задаёт размер, резервируемый для pg_stat_activity.query (в байтах)." + +#: utils/misc/guc.c:3364 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "Задаёт максимальный размер списка-очереди для GIN-индекса." + +#: utils/misc/guc.c:3375 +msgid "TCP user timeout." +msgstr "Пользовательский таймаут TCP." + +#: utils/misc/guc.c:3395 +msgid "" +"Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "" +"Задаёт для планировщика ориентир стоимости последовательного чтения страницы." + +#: utils/misc/guc.c:3406 +msgid "" +"Sets the planner's estimate of the cost of a nonsequentially fetched disk " +"page." +msgstr "" +"Задаёт для планировщика ориентир стоимости непоследовательного чтения " +"страницы." + +#: utils/misc/guc.c:3417 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "" +"Задаёт для планировщика ориентир стоимости обработки каждого кортежа " +"(строки)." + +#: utils/misc/guc.c:3428 +msgid "" +"Sets the planner's estimate of the cost of processing each index entry " +"during an index scan." +msgstr "" +"Задаёт для планировщика ориентир стоимости обработки каждого элемента " +"индекса в процессе сканирования индекса." + +#: utils/misc/guc.c:3439 +msgid "" +"Sets the planner's estimate of the cost of processing each operator or " +"function call." +msgstr "" +"Задаёт для планировщика ориентир стоимости обработки каждого оператора или " +"вызова функции." + +#: utils/misc/guc.c:3450 +msgid "" +"Sets the planner's estimate of the cost of passing each tuple (row) from " +"worker to master backend." +msgstr "" +"Задаёт для планировщика ориентир стоимости передачи каждого кортежа (строки) " +"от рабочего процесса обслуживающему." + +#: utils/misc/guc.c:3461 +msgid "" +"Sets the planner's estimate of the cost of starting up worker processes for " +"parallel query." +msgstr "" +"Задаёт для планировщика ориентир стоимости запуска рабочих процессов для " +"параллельного выполнения запроса." + +#: utils/misc/guc.c:3473 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Стоимость запроса, при превышении которой производится JIT-компиляция." + +#: utils/misc/guc.c:3474 +msgid "-1 disables JIT compilation." +msgstr "-1 отключает JIT-компиляцию." + +#: utils/misc/guc.c:3484 +msgid "Optimize JITed functions if query is more expensive." +msgstr "" +"Стоимость запроса, при превышении которой оптимизируются JIT-" +"скомпилированные функции." + +#: utils/misc/guc.c:3485 +msgid "-1 disables optimization." +msgstr "-1 отключает оптимизацию." + +#: utils/misc/guc.c:3495 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Стоимость запроса, при которой выполняется встраивание JIT." + +#: utils/misc/guc.c:3496 +msgid "-1 disables inlining." +msgstr "-1 отключает встраивание кода." + +#: utils/misc/guc.c:3506 +msgid "" +"Sets the planner's estimate of the fraction of a cursor's rows that will be " +"retrieved." +msgstr "" +"Задаёт для планировщика ориентир доли требуемых строк курсора в общем числе." + +#: utils/misc/guc.c:3518 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: селективное давление в популяции." + +#: utils/misc/guc.c:3529 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: отправное значение для случайного выбора пути." + +#: utils/misc/guc.c:3540 +msgid "Multiple of work_mem to use for hash tables." +msgstr "Множитель work_mem, определяющий объём памяти для хеш-таблиц." + +#: utils/misc/guc.c:3551 +msgid "Multiple of the average buffer usage to free per round." +msgstr "" +"Множитель для среднего числа использованных буферов, определяющий число " +"буферов, освобождаемых за один подход." + +#: utils/misc/guc.c:3561 +msgid "Sets the seed for random-number generation." +msgstr "Задаёт отправное значение для генератора случайных чисел." + +#: utils/misc/guc.c:3572 +msgid "Vacuum cost delay in milliseconds." +msgstr "Задержка очистки (в миллисекундах)." + +#: utils/misc/guc.c:3583 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Задержка очистки для автоочистки (в миллисекундах)." + +#: utils/misc/guc.c:3594 +msgid "" +"Number of tuple updates or deletes prior to vacuum as a fraction of " +"reltuples." +msgstr "" +"Отношение числа обновлений или удалений кортежей к reltuples, определяющее " +"потребность в очистке." + +#: utils/misc/guc.c:3604 +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "" +"Отношение числа добавлений кортежей к reltuples, определяющее потребность в " +"очистке." + +#: utils/misc/guc.c:3614 +msgid "" +"Number of tuple inserts, updates, or deletes prior to analyze as a fraction " +"of reltuples." +msgstr "" +"Отношение числа добавлений, обновлений или удалений кортежей к reltuples, " +"определяющее потребность в анализе." + +#: utils/misc/guc.c:3624 +msgid "" +"Time spent flushing dirty buffers during checkpoint, as fraction of " +"checkpoint interval." +msgstr "" +"Отношение продолжительности сброса \"грязных\" буферов во время контрольной " +"точки к интервалу контрольных точек." + +#: utils/misc/guc.c:3634 +msgid "" +"Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "" +"Отношение числа добавлений кортежей к reltuples, определяющее потребность в " +"уборке индекса." + +#: utils/misc/guc.c:3644 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "" +"Доля записываемых в журнал операторов с длительностью, превышающей " +"log_min_duration_sample." + +#: utils/misc/guc.c:3645 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "" +"Может задаваться значением от 0.0 (не записывать никакие операторы) и 1.0 " +"(записывать все)." + +#: utils/misc/guc.c:3654 +msgid "Set the fraction of transactions to log for new transactions." +msgstr "Задаёт долю транзакций, которая будет записываться в журнал сервера." + +#: utils/misc/guc.c:3655 +msgid "" +"Logs all statements from a fraction of transactions. Use a value between 0.0 " +"(never log) and 1.0 (log all statements for all transactions)." +msgstr "" +"Записываться будут все операторы заданной доли транзакций. Значение 0.0 " +"означает — не записывать никакие транзакции, а значение 1.0 — записывать все " +"операторы всех транзакций." + +#: utils/misc/guc.c:3675 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "Задаёт команду оболочки, вызываемую для архивации файла WAL." + +#: utils/misc/guc.c:3685 +msgid "" +"Sets the shell command that will be called to retrieve an archived WAL file." +msgstr "" +"Задаёт команду оболочки, которая будет вызываться для извлечения из архива " +"файла WAL." + +#: utils/misc/guc.c:3695 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "" +"Задаёт команду оболочки, которая будет выполняться при каждой точке " +"перезапуска." + +#: utils/misc/guc.c:3705 +msgid "" +"Sets the shell command that will be executed once at the end of recovery." +msgstr "" +"Задаёт команду оболочки, которая будет выполняться в конце восстановления." + +#: utils/misc/guc.c:3715 +msgid "Specifies the timeline to recover into." +msgstr "Указывает линию времени для выполнения восстановления." + +#: utils/misc/guc.c:3725 +msgid "" +"Set to \"immediate\" to end recovery as soon as a consistent state is " +"reached." +msgstr "" +"Задайте значение \"immediate\", чтобы восстановление остановилось сразу " +"после достижения согласованного состояния." + +#: utils/misc/guc.c:3734 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "" +"Задаёт идентификатор транзакции, вплоть до которой будет производиться " +"восстановление." + +#: utils/misc/guc.c:3743 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "" +"Задаёт момент времени, вплоть до которого будет производиться восстановление." + +#: utils/misc/guc.c:3752 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "" +"Задаёт именованную точку восстановления, до которой будет производиться " +"восстановление." + +#: utils/misc/guc.c:3761 +msgid "" +"Sets the LSN of the write-ahead log location up to which recovery will " +"proceed." +msgstr "" +"Задаёт в виде LSN позицию в журнале предзаписи, до которой будет " +"производиться восстановление." + +#: utils/misc/guc.c:3771 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "" +"Задаёт имя файла, присутствие которого выводит ведомый из режима " +"восстановления." + +#: utils/misc/guc.c:3781 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "" +"Задаёт строку соединения, которая будет использоваться для подключения к " +"передающему серверу." + +#: utils/misc/guc.c:3792 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "" +"Задаёт имя слота репликации, который будет использоваться на передающем " +"сервере." + +#: utils/misc/guc.c:3802 +msgid "Sets the client's character set encoding." +msgstr "Задаёт кодировку символов, используемую клиентом." + +#: utils/misc/guc.c:3813 +msgid "Controls information prefixed to each log line." +msgstr "Определяет содержимое префикса каждой строки протокола." + +#: utils/misc/guc.c:3814 +msgid "If blank, no prefix is used." +msgstr "При пустом значении префикс также отсутствует." + +#: utils/misc/guc.c:3823 +msgid "Sets the time zone to use in log messages." +msgstr "Задаёт часовой пояс для вывода времени в сообщениях протокола." + +#: utils/misc/guc.c:3833 +msgid "Sets the display format for date and time values." +msgstr "Устанавливает формат вывода дат и времени." + +#: utils/misc/guc.c:3834 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "Также помогает разбирать неоднозначно заданные вводимые даты." + +#: utils/misc/guc.c:3845 +msgid "Sets the default table access method for new tables." +msgstr "Задаёт табличный метод доступа по умолчанию для новых таблиц." + +#: utils/misc/guc.c:3856 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "" +"Задаёт табличное пространство по умолчанию для новых таблиц и индексов." + +#: utils/misc/guc.c:3857 +msgid "An empty string selects the database's default tablespace." +msgstr "При пустом значении используется табличное пространство базы данных." + +#: utils/misc/guc.c:3867 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "" +"Задаёт табличное пространство(а) для временных таблиц и файлов сортировки." + +#: utils/misc/guc.c:3878 +msgid "Sets the path for dynamically loadable modules." +msgstr "Задаёт путь для динамически загружаемых модулей." + +#: utils/misc/guc.c:3879 +msgid "" +"If a dynamically loadable module needs to be opened and the specified name " +"does not have a directory component (i.e., the name does not contain a " +"slash), the system will search this path for the specified file." +msgstr "" +"Когда требуется открыть динамически загружаемый модуль и в его имени не " +"указан путь (нет символа '/'), система будет искать этот файл в заданном " +"пути." + +#: utils/misc/guc.c:3892 +msgid "Sets the location of the Kerberos server key file." +msgstr "Задаёт размещение файла с ключом Kerberos для данного сервера." + +#: utils/misc/guc.c:3903 +msgid "Sets the Bonjour service name." +msgstr "Задаёт название службы Bonjour." + +#: utils/misc/guc.c:3915 +msgid "Shows the collation order locale." +msgstr "Показывает правило сортировки." + +#: utils/misc/guc.c:3926 +msgid "Shows the character classification and case conversion locale." +msgstr "Показывает правило классификации символов и преобразования регистра." + +#: utils/misc/guc.c:3937 +msgid "Sets the language in which messages are displayed." +msgstr "Задаёт язык выводимых сообщений." + +#: utils/misc/guc.c:3947 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Задаёт локаль для форматирования денежных сумм." + +#: utils/misc/guc.c:3957 +msgid "Sets the locale for formatting numbers." +msgstr "Задаёт локаль для форматирования чисел." + +#: utils/misc/guc.c:3967 +msgid "Sets the locale for formatting date and time values." +msgstr "Задаёт локаль для форматирования дат и времени." + +#: utils/misc/guc.c:3977 +msgid "Lists shared libraries to preload into each backend." +msgstr "" +"Список разделяемых библиотек, заранее загружаемых в каждый обслуживающий " +"процесс." + +#: utils/misc/guc.c:3988 +msgid "Lists shared libraries to preload into server." +msgstr "Список разделяемых библиотек, заранее загружаемых в память сервера." + +#: utils/misc/guc.c:3999 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "" +"Список непривилегированных разделяемых библиотек, заранее загружаемых в " +"каждый обслуживающий процесс." + +#: utils/misc/guc.c:4010 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "Задаёт порядок просмотра схемы при поиске неполных имён." + +#: utils/misc/guc.c:4022 +msgid "Sets the server (database) character set encoding." +msgstr "Задаёт кодировку символов сервера (баз данных)." + +#: utils/misc/guc.c:4034 +msgid "Shows the server version." +msgstr "Показывает версию сервера." + +#: utils/misc/guc.c:4046 +msgid "Sets the current role." +msgstr "Задаёт текущую роль." + +#: utils/misc/guc.c:4058 +msgid "Sets the session user name." +msgstr "Задаёт имя пользователя в сеансе." + +#: utils/misc/guc.c:4069 +msgid "Sets the destination for server log output." +msgstr "Определяет, куда будет выводиться протокол сервера." + +#: utils/misc/guc.c:4070 +msgid "" +"Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and " +"\"eventlog\", depending on the platform." +msgstr "" +"Значение может включать сочетание слов \"stderr\", \"syslog\", \"csvlog\" и " +"\"eventlog\", в зависимости от платформы." + +#: utils/misc/guc.c:4081 +msgid "Sets the destination directory for log files." +msgstr "Задаёт целевой каталог для файлов протоколов." + +#: utils/misc/guc.c:4082 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "" +"Путь может быть абсолютным или указываться относительно каталога данных." + +#: utils/misc/guc.c:4092 +msgid "Sets the file name pattern for log files." +msgstr "Задаёт шаблон имени для файлов протоколов." + +#: utils/misc/guc.c:4103 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "Задаёт имя программы для идентификации сообщений PostgreSQL в syslog." + +#: utils/misc/guc.c:4114 +msgid "" +"Sets the application name used to identify PostgreSQL messages in the event " +"log." +msgstr "" +"Задаёт имя приложения для идентификации сообщений PostgreSQL в журнале " +"событий." + +#: utils/misc/guc.c:4125 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "" +"Задаёт часовой пояс для вывода и разбора строкового представления времени." + +#: utils/misc/guc.c:4135 +msgid "Selects a file of time zone abbreviations." +msgstr "Выбирает файл с сокращёнными названиями часовых поясов." + +#: utils/misc/guc.c:4145 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Задаёт группу-владельца Unix-сокета." + +#: utils/misc/guc.c:4146 +msgid "" +"The owning user of the socket is always the user that starts the server." +msgstr "" +"Собственно владельцем сокета всегда будет пользователь, запускающий сервер." + +#: utils/misc/guc.c:4156 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Задаёт каталоги, где будут создаваться Unix-сокеты." + +#: utils/misc/guc.c:4171 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Задаёт имя узла или IP-адрес(а) для привязки." + +#: utils/misc/guc.c:4186 +msgid "Sets the server's data directory." +msgstr "Определяет каталог данных сервера." + +#: utils/misc/guc.c:4197 +msgid "Sets the server's main configuration file." +msgstr "Определяет основной файл конфигурации сервера." + +#: utils/misc/guc.c:4208 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Задаёт путь к файлу конфигурации \"hba\"." + +#: utils/misc/guc.c:4219 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Задаёт путь к файлу конфигурации \"ident\"." + +#: utils/misc/guc.c:4230 +msgid "Writes the postmaster PID to the specified file." +msgstr "Файл, в который будет записан код процесса postmaster." + +#: utils/misc/guc.c:4241 +msgid "Name of the SSL library." +msgstr "Имя библиотеки SSL." + +#: utils/misc/guc.c:4256 +msgid "Location of the SSL server certificate file." +msgstr "Размещение файла сертификата сервера для SSL." + +#: utils/misc/guc.c:4266 +msgid "Location of the SSL server private key file." +msgstr "Размещение файла с закрытым ключом сервера для SSL." + +#: utils/misc/guc.c:4276 +msgid "Location of the SSL certificate authority file." +msgstr "Размещение файла центра сертификации для SSL." + +#: utils/misc/guc.c:4286 +msgid "Location of the SSL certificate revocation list file." +msgstr "Размещение файла со списком отзыва сертификатов для SSL." + +#: utils/misc/guc.c:4296 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Каталог, в который будут записываться временные файлы статистики." + +#: utils/misc/guc.c:4307 +msgid "" +"Number of synchronous standbys and list of names of potential synchronous " +"ones." +msgstr "" +"Количество потенциально синхронных резервных серверов и список их имён." + +#: utils/misc/guc.c:4318 +msgid "Sets default text search configuration." +msgstr "Задаёт конфигурацию текстового поиска по умолчанию." + +#: utils/misc/guc.c:4328 +msgid "Sets the list of allowed SSL ciphers." +msgstr "Задаёт список допустимых алгоритмов шифрования для SSL." + +#: utils/misc/guc.c:4343 +msgid "Sets the curve to use for ECDH." +msgstr "Задаёт кривую для ECDH." + +#: utils/misc/guc.c:4358 +msgid "Location of the SSL DH parameters file." +msgstr "Размещение файла с параметрами SSL DH." + +#: utils/misc/guc.c:4369 +msgid "Command to obtain passphrases for SSL." +msgstr "Команда, позволяющая получить пароль для SSL." + +#: utils/misc/guc.c:4380 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "" +"Задаёт имя приложения, которое будет выводиться в статистике и протоколах." + +#: utils/misc/guc.c:4391 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Задаёт имя кластера, которое будет добавляться в название процесса." + +#: utils/misc/guc.c:4402 +msgid "" +"Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "" +"Задаёт перечень менеджеров ресурсов WAL, для которых выполняются проверки " +"целостности WAL." + +#: utils/misc/guc.c:4403 +msgid "" +"Full-page images will be logged for all data blocks and cross-checked " +"against the results of WAL replay." +msgstr "" +"При этом в журнал будут записываться образы полных страниц для всех блоков " +"данных для сверки с результатами воспроизведения WAL." + +#: utils/misc/guc.c:4413 +msgid "JIT provider to use." +msgstr "Используемый провайдер JIT." + +#: utils/misc/guc.c:4424 +msgid "Log backtrace for errors in these functions." +msgstr "Записывать в журнал стек в случае ошибок в перечисленных функциях." + +#: utils/misc/guc.c:4444 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Определяет, можно ли использовать \"\\'\" в текстовых строках." + +#: utils/misc/guc.c:4454 +msgid "Sets the output format for bytea." +msgstr "Задаёт формат вывода данных типа bytea." + +#: utils/misc/guc.c:4464 +msgid "Sets the message levels that are sent to the client." +msgstr "Ограничивает уровень сообщений, передаваемых клиенту." + +#: utils/misc/guc.c:4465 utils/misc/guc.c:4530 utils/misc/guc.c:4541 +#: utils/misc/guc.c:4617 +msgid "" +"Each level includes all the levels that follow it. The later the level, the " +"fewer messages are sent." +msgstr "" +"Каждый уровень включает все последующие. Чем выше уровень, тем меньше " +"сообщений." + +#: utils/misc/guc.c:4475 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "" +"Разрешает планировщику оптимизировать запросы, полагаясь на ограничения." + +#: utils/misc/guc.c:4476 +msgid "" +"Table scans will be skipped if their constraints guarantee that no rows " +"match the query." +msgstr "" +"Сканирование таблицы не будет выполняться, если её ограничения гарантируют, " +"что запросу не удовлетворяют никакие строки." + +#: utils/misc/guc.c:4487 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Задаёт уровень изоляции транзакций для новых транзакций." + +#: utils/misc/guc.c:4497 +msgid "Sets the current transaction's isolation level." +msgstr "Задаёт текущий уровень изоляции транзакций." + +#: utils/misc/guc.c:4508 +msgid "Sets the display format for interval values." +msgstr "Задаёт формат отображения для внутренних значений." + +#: utils/misc/guc.c:4519 +msgid "Sets the verbosity of logged messages." +msgstr "Задаёт детализацию протоколируемых сообщений." + +#: utils/misc/guc.c:4529 +msgid "Sets the message levels that are logged." +msgstr "Ограничивает уровни протоколируемых сообщений." + +#: utils/misc/guc.c:4540 +msgid "" +"Causes all statements generating error at or above this level to be logged." +msgstr "" +"Включает протоколирование для SQL-операторов, выполненных с ошибкой этого " +"или большего уровня." + +#: utils/misc/guc.c:4551 +msgid "Sets the type of statements logged." +msgstr "Задаёт тип протоколируемых операторов." + +#: utils/misc/guc.c:4561 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "Задаёт получателя сообщений, отправляемых в syslog." + +#: utils/misc/guc.c:4576 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "" +"Задаёт режим срабатывания триггеров и правил перезаписи для текущего сеанса." + +#: utils/misc/guc.c:4586 +msgid "Sets the current transaction's synchronization level." +msgstr "Задаёт уровень синхронизации текущей транзакции." + +#: utils/misc/guc.c:4596 +msgid "Allows archiving of WAL files using archive_command." +msgstr "Разрешает архивацию файлов WAL командой archive_command." + +#: utils/misc/guc.c:4606 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "" +"Задаёт действие, которое будет выполняться по достижении цели восстановления." + +#: utils/misc/guc.c:4616 +msgid "Enables logging of recovery-related debugging information." +msgstr "" +"Включает протоколирование отладочной информации, связанной с репликацией." + +#: utils/misc/guc.c:4632 +msgid "Collects function-level statistics on database activity." +msgstr "Включает сбор статистики активности в БД на уровне функций." + +#: utils/misc/guc.c:4642 +msgid "Set the level of information written to the WAL." +msgstr "Задаёт уровень информации, записываемой в WAL." + +#: utils/misc/guc.c:4652 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Выбирает используемую реализацию динамической разделяемой памяти." + +#: utils/misc/guc.c:4662 +msgid "" +"Selects the shared memory implementation used for the main shared memory " +"region." +msgstr "" +"Выбирает реализацию разделяемой памяти для управления основным блоком " +"разделяемой памяти." + +#: utils/misc/guc.c:4672 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "Выбирает метод принудительной записи изменений в WAL на диск." + +#: utils/misc/guc.c:4682 +msgid "Sets how binary values are to be encoded in XML." +msgstr "Определяет, как должны кодироваться двоичные значения в XML." + +#: utils/misc/guc.c:4692 +msgid "" +"Sets whether XML data in implicit parsing and serialization operations is to " +"be considered as documents or content fragments." +msgstr "" +"Определяет, следует ли рассматривать XML-данные в неявных операциях разбора " +"и сериализации как документы или как фрагменты содержания." + +#: utils/misc/guc.c:4703 +msgid "Use of huge pages on Linux or Windows." +msgstr "Включает использование гигантских страниц в Linux и в Windows." + +#: utils/misc/guc.c:4713 +msgid "Forces use of parallel query facilities." +msgstr "Принудительно включает режим параллельного выполнения запросов." + +#: utils/misc/guc.c:4714 +msgid "" +"If possible, run query using a parallel worker and with parallel " +"restrictions." +msgstr "" +"Если возможно, запрос выполняется параллельными исполнителями и с " +"ограничениями параллельности." + +#: utils/misc/guc.c:4724 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "Выбирает алгоритм шифрования паролей." + +#: utils/misc/guc.c:4734 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Управляет выбором специализированных или общих планов планировщиком." + +#: utils/misc/guc.c:4735 +msgid "" +"Prepared statements can have custom and generic plans, and the planner will " +"attempt to choose which is better. This can be set to override the default " +"behavior." +msgstr "" +"Для подготовленных операторов могут иметься специализированные и общие " +"планы, и планировщик пытается выбрать лучший вариант. Этот параметр " +"позволяет переопределить поведение по умолчанию." + +#: utils/misc/guc.c:4747 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "" +"Задаёт минимальную версию протокола SSL/TLS, которая может использоваться." + +#: utils/misc/guc.c:4759 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "" +"Задаёт максимальную версию протокола SSL/TLS, которая может использоваться." + +#: utils/misc/guc.c:5562 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: ошибка доступа к каталогу \"%s\": %s\n" + +#: utils/misc/guc.c:5567 +#, c-format +msgid "" +"Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "" +"Запустите initdb или pg_basebackup для инициализации каталога данных " +"PostgreSQL.\n" + +#: utils/misc/guc.c:5587 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA " +"environment variable.\n" +msgstr "" +"%s не знает, где найти файл конфигурации сервера.\n" +"Вы должны указать его расположение в параметре --config-file или -D, либо " +"установить переменную окружения PGDATA.\n" + +#: utils/misc/guc.c:5606 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s не может открыть файл конфигурации сервера \"%s\": %s\n" + +#: utils/misc/guc.c:5632 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D " +"invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s не знает, где найти данные СУБД.\n" +"Их расположение можно задать как значение \"data_directory\" в файле \"%s\", " +"либо передать в параметре -D, либо установить переменную окружения PGDATA.\n" + +#: utils/misc/guc.c:5680 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation " +"option, or by the PGDATA environment variable.\n" +msgstr "" +"%s не знает, где найти файл конфигурации \"hba\".\n" +"Его расположение можно задать как значение \"hba_file\" в файле \"%s\", либо " +"передать в параметре -D, либо установить переменную окружения PGDATA.\n" + +#: utils/misc/guc.c:5703 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation " +"option, or by the PGDATA environment variable.\n" +msgstr "" +"%s не знает, где найти файл конфигурации \"ident\".\n" +"Его расположение можно задать как значение \"ident_file\" в файле \"%s\", " +"либо передать в параметре -D, либо установить переменную окружения PGDATA.\n" + +#: utils/misc/guc.c:6545 +msgid "Value exceeds integer range." +msgstr "Значение выходит за рамки целых чисел." + +#: utils/misc/guc.c:6781 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s вне диапазона, допустимого для параметра \"%s\" (%d .. %d)" + +#: utils/misc/guc.c:6817 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s вне диапазона, допустимого для параметра \"%s\" (%g .. %g)" + +#: utils/misc/guc.c:6973 utils/misc/guc.c:8368 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "устанавливать параметры во время параллельных операций нельзя" + +#: utils/misc/guc.c:6980 utils/misc/guc.c:7760 utils/misc/guc.c:7813 +#: utils/misc/guc.c:7864 utils/misc/guc.c:8197 utils/misc/guc.c:8964 +#: utils/misc/guc.c:9226 utils/misc/guc.c:10892 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "нераспознанный параметр конфигурации: \"%s\"" + +#: utils/misc/guc.c:6995 utils/misc/guc.c:8209 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "параметр \"%s\" нельзя изменить" + +#: utils/misc/guc.c:7018 utils/misc/guc.c:7216 utils/misc/guc.c:7310 +#: utils/misc/guc.c:7404 utils/misc/guc.c:7524 utils/misc/guc.c:7623 +#: guc-file.l:352 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "параметр \"%s\" изменяется только при перезапуске сервера" + +#: utils/misc/guc.c:7028 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "параметр \"%s\" нельзя изменить сейчас" + +#: utils/misc/guc.c:7046 utils/misc/guc.c:7093 utils/misc/guc.c:10908 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "нет прав для изменения параметра \"%s\"" + +#: utils/misc/guc.c:7083 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "параметр \"%s\" нельзя задать после установления соединения" + +#: utils/misc/guc.c:7131 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "" +"параметр \"%s\" нельзя задать в функции с контекстом безопасности " +"определившего" + +#: utils/misc/guc.c:7768 utils/misc/guc.c:7818 utils/misc/guc.c:9233 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "" +"прочитать \"%s\" может только суперпользователь или член роли " +"pg_read_all_settings" + +#: utils/misc/guc.c:7909 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s принимает только один аргумент" + +#: utils/misc/guc.c:8157 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "выполнить команду ALTER SYSTEM может только суперпользователь" + +#: utils/misc/guc.c:8242 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "значение параметра для ALTER SYSTEM не должно быть многострочным" + +#: utils/misc/guc.c:8287 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "не удалось разобрать содержимое файла \"%s\"" + +#: utils/misc/guc.c:8444 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT не реализовано" + +#: utils/misc/guc.c:8528 +#, c-format +msgid "SET requires parameter name" +msgstr "SET требует имя параметра" + +#: utils/misc/guc.c:8661 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "попытка переопределить параметр \"%s\"" + +#: utils/misc/guc.c:10454 +#, c-format +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "при назначении параметру \"%s\" значения \"%s\"" + +#: utils/misc/guc.c:10522 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "параметр \"%s\" нельзя установить" + +#: utils/misc/guc.c:10612 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "не удалось разобрать значение параметра \"%s\"" + +#: utils/misc/guc.c:10970 utils/misc/guc.c:11004 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "неверное значение параметра \"%s\": %d" + +#: utils/misc/guc.c:11038 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "неверное значение параметра \"%s\": %g" + +#: utils/misc/guc.c:11308 +#, c-format +msgid "" +"\"temp_buffers\" cannot be changed after any temporary tables have been " +"accessed in the session." +msgstr "" +"параметр \"temp_buffers\" нельзя изменить после обращения к временным " +"таблицам в текущем сеансе." + +#: utils/misc/guc.c:11320 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour не поддерживается в данной сборке" + +#: utils/misc/guc.c:11333 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL не поддерживается в данной сборке" + +#: utils/misc/guc.c:11345 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "" +"Этот параметр нельзя включить, когда \"log_statement_stats\" равен true." + +#: utils/misc/guc.c:11357 +#, c-format +msgid "" +"Cannot enable \"log_statement_stats\" when \"log_parser_stats\", " +"\"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "" +"Параметр \"log_statement_stats\" нельзя включить, когда \"log_parser_stats" +"\", \"log_planner_stats\" или \"log_executor_stats\" равны true." + +#: utils/misc/guc.c:11587 +#, c-format +msgid "" +"effective_io_concurrency must be set to 0 on platforms that lack " +"posix_fadvise()." +msgstr "" +"Значение effective_io_concurrency должно равняться 0 на платформах, где " +"отсутствует lack posix_fadvise()." + +#: utils/misc/guc.c:11600 +#, c-format +msgid "" +"maintenance_io_concurrency must be set to 0 on platforms that lack " +"posix_fadvise()." +msgstr "" +"Значение maintenance_io_concurrency должно равняться 0 на платформах, где " +"отсутствует lack posix_fadvise()." + +#: utils/misc/guc.c:11716 +#, c-format +msgid "invalid character" +msgstr "неверный символ" + +#: utils/misc/guc.c:11776 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline не является допустимым числом." + +#: utils/misc/guc.c:11816 +#, c-format +msgid "multiple recovery targets specified" +msgstr "указано несколько целей восстановления" + +#: utils/misc/guc.c:11817 +#, c-format +msgid "" +"At most one of recovery_target, recovery_target_lsn, recovery_target_name, " +"recovery_target_time, recovery_target_xid may be set." +msgstr "" +"Может быть указана только одна из целей: recovery_target, " +"recovery_target_lsn, recovery_target_name, recovery_target_time, " +"recovery_target_xid." + +#: utils/misc/guc.c:11825 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "Единственное допустимое значение: \"immediate\"." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "внутренняя ошибка: нераспознанный тип параметра времени выполнения\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "" +"query-specified return tuple and function return type are not compatible" +msgstr "" +"заданный в запросе кортеж результата несовместим с типом результата функции" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "" +"вычисленная контрольная сумма (CRC) не соответствует значению, сохранённому " +"в файле" + +# well-spelled: пользов +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: пользов.: %d.%02d с, система: %d.%02d с, прошло: %d.%02d с" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "" +"запрос будет ограничен политикой безопасности на уровне строк для таблицы " +"\"%s\"" + +#: utils/misc/rls.c:129 +#, c-format +msgid "" +"To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW " +"LEVEL SECURITY." +msgstr "" +"Чтобы отключить политику для владельца таблицы, воспользуйтесь командой " +"ALTER TABLE NO FORCE ROW LEVEL SECURITY." + +#: utils/misc/timeout.c:395 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "добавить другие причины тайм-аута нельзя" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "" +"time zone abbreviation \"%s\" is too long (maximum %d characters) in time " +"zone file \"%s\", line %d" +msgstr "" +"краткое обозначение часового пояса \"%s\" должно содержать меньше символов " +"(максимум %d) (файл часовых поясов \"%s\", строка %d)" + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "" +"смещение часового пояса %d выходит за рамки (файл часовых поясов \"%s\", " +"строка %d)" + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "" +"отсутствует краткое обозначение часового пояса (файл часовых поясов \"%s\", " +"строка %d)" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "" +"отсутствует смещение часового пояса (файл часовых поясов \"%s\", строка %d)" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "" +"смещение часового пояса должно быть числом (файл часовых поясов \"%s\", " +"строка %d)" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "ошибка синтаксиса в файле часовых поясов \"%s\", строке %d" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "краткое обозначение часового пояса \"%s\" определено неоднократно" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "" +"Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s" +"\", line %d." +msgstr "" +"Запись в файле часовых поясов \"%s\", строке %d, противоречит записи в файле " +"\"%s\", строке %d." + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "неправильное имя файла часовых поясов: \"%s\"" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "предел вложенности файлов часовых поясов превышен в файле \"%s\"" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "прочитать файл часовых поясов \"%s\" не удалось: %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "слишком длинная строка в файле часовых поясов \"%s\" (строка %d)" + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "" +"в @INCLUDE не указано имя файла (файл часовых поясов \"%s\", строка %d)" + +#: utils/mmgr/aset.c:476 utils/mmgr/generation.c:234 utils/mmgr/slab.c:236 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Ошибка при создании контекста памяти \"%s\"." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "не удалось подключиться к динамической разделяемой области" + +#: utils/mmgr/mcxt.c:822 utils/mmgr/mcxt.c:858 utils/mmgr/mcxt.c:896 +#: utils/mmgr/mcxt.c:934 utils/mmgr/mcxt.c:970 utils/mmgr/mcxt.c:1001 +#: utils/mmgr/mcxt.c:1037 utils/mmgr/mcxt.c:1089 utils/mmgr/mcxt.c:1124 +#: utils/mmgr/mcxt.c:1159 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Ошибка при запросе блока размером %zu в контексте памяти \"%s\"." + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "курсор \"%s\" уже существует" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "существующий курсор (\"%s\") закрывается" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "портал \"%s\" не может быть запущен" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "удалить закреплённый портал \"%s\" нельзя" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "удалить активный портал \"%s\" нельзя" + +#: utils/mmgr/portalmem.c:731 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "нельзя выполнить PREPARE для транзакции, создавшей курсор WITH HOLD" + +#: utils/mmgr/portalmem.c:1270 +#, c-format +msgid "" +"cannot perform transaction commands inside a cursor loop that is not read-" +"only" +msgstr "" +"транзакционные команды нельзя выполнять внутри цикла с курсором, " +"производящим изменения" + +#: utils/sort/logtape.c:266 utils/sort/logtape.c:289 +#, c-format +msgid "could not seek to block %ld of temporary file" +msgstr "не удалось переместиться к блоку %ld временного файла" + +#: utils/sort/logtape.c:295 +#, c-format +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "" +"не удалось прочитать блок %ld временного файла (прочитано байт: %zu из %zu)" + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 +#: utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 +#: utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "не удалось прочитать файл общего временного хранилища кортежей" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "неожиданный фрагмент в файле общего временного хранилища кортежей" + +#: utils/sort/sharedtuplestore.c:569 +#, c-format +msgid "could not seek to block %u in shared tuplestore temporary file" +msgstr "" +"не удалось переместиться к блоку %u в файле общего временного хранилища " +"кортежей" + +#: utils/sort/sharedtuplestore.c:576 +#, c-format +msgid "" +"could not read from shared tuplestore temporary file: read only %zu of %zu " +"bytes" +msgstr "" +"не удалось прочитать файл общего временного хранилища кортежей (прочитано " +"байт: %zu из %zu)" + +#: utils/sort/tuplesort.c:3140 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "число потоков данных для внешней сортировки не может превышать %d" + +#: utils/sort/tuplesort.c:4221 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "создать уникальный индекс \"%s\" не удалось" + +#: utils/sort/tuplesort.c:4223 +#, c-format +msgid "Key %s is duplicated." +msgstr "Ключ %s дублируется." + +#: utils/sort/tuplesort.c:4224 +#, c-format +msgid "Duplicate keys exist." +msgstr "Данные содержат дублирующиеся ключи." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "не удалось переместиться во временном файле хранилища кортежей" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 +#: utils/sort/tuplestore.c:1548 +#, c-format +msgid "" +"could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "" +"не удалось прочитать временный файл хранилища кортежей (прочитано байт: %zu " +"из %zu)" + +#: utils/time/snapmgr.c:624 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "Исходная транзакция уже не выполняется." + +#: utils/time/snapmgr.c:1232 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "экспортировать снимок из вложенной транзакции нельзя" + +#: utils/time/snapmgr.c:1391 utils/time/snapmgr.c:1396 +#: utils/time/snapmgr.c:1401 utils/time/snapmgr.c:1416 +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1426 +#: utils/time/snapmgr.c:1441 utils/time/snapmgr.c:1446 +#: utils/time/snapmgr.c:1451 utils/time/snapmgr.c:1553 +#: utils/time/snapmgr.c:1569 utils/time/snapmgr.c:1594 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "неверные данные снимка в файле \"%s\"" + +#: utils/time/snapmgr.c:1488 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "команда SET TRANSACTION SNAPSHOT должна выполняться до запросов" + +#: utils/time/snapmgr.c:1497 +#, c-format +msgid "" +"a snapshot-importing transaction must have isolation level SERIALIZABLE or " +"REPEATABLE READ" +msgstr "" +"транзакция, импортирующая снимок, должна иметь уровень изоляции SERIALIZABLE " +"или REPEATABLE READ" + +#: utils/time/snapmgr.c:1506 utils/time/snapmgr.c:1515 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "неверный идентификатор снимка: \"%s\"" + +#: utils/time/snapmgr.c:1607 +#, c-format +msgid "" +"a serializable transaction cannot import a snapshot from a non-serializable " +"transaction" +msgstr "" +"сериализуемая транзакция не может импортировать снимок из не сериализуемой" + +#: utils/time/snapmgr.c:1611 +#, c-format +msgid "" +"a non-read-only serializable transaction cannot import a snapshot from a " +"read-only transaction" +msgstr "" +"сериализуемая транзакция в режиме \"чтение-запись\" не может импортировать " +"снимок из транзакции в режиме \"только чтение\"" + +#: utils/time/snapmgr.c:1626 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "нельзя импортировать снимок из другой базы данных" + +#: gram.y:1047 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "вариант UNENCRYPTED PASSWORD более не поддерживается" + +#: gram.y:1048 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "" +"Удалите слово UNENCRYPTED, чтобы сохранить пароль в зашифрованном виде." + +#: gram.y:1110 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "нераспознанный параметр роли \"%s\"" + +#: gram.y:1357 gram.y:1372 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS не может включать элементы схемы" + +#: gram.y:1518 +#, c-format +msgid "current database cannot be changed" +msgstr "сменить текущую базу данных нельзя" + +#: gram.y:1642 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "" +"интервал, задающий часовой пояс, должен иметь точность HOUR или HOUR TO " +"MINUTE" + +#: gram.y:2177 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "номер столбца должен быть в диапазоне от 1 до %d" + +#: gram.y:2709 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "параметр последовательности \"%s\" здесь не поддерживается" + +#: gram.y:2738 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "модуль для хеш-секции указан неоднократно" + +#: gram.y:2747 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "остаток для хеш-секции указан неоднократно" + +#: gram.y:2754 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "нераспознанное указание ограничения хеш-секции \"%s\"" + +#: gram.y:2762 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "необходимо указать модуль для хеш-секции" + +#: gram.y:2766 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "необходимо указать остаток для хеш-секции" + +#: gram.y:2967 gram.y:3000 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "указания STDIN/STDOUT несовместимы с PROGRAM" + +#: gram.y:2973 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "предложение WHERE не допускается с COPY TO" + +#: gram.y:3305 gram.y:3312 gram.y:11648 gram.y:11656 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "указание GLOBAL при создании временных таблиц устарело" + +#: gram.y:3552 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "для генерируемого столбца должно указываться GENERATED ALWAYS" + +#: gram.y:4513 +#, c-format +msgid "CREATE EXTENSION ... FROM is no longer supported" +msgstr "CREATE EXTENSION ... FROM более не поддерживается" + +#: gram.y:5339 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "нераспознанный вариант политики безопасности строк \"%s\"" + +#: gram.y:5340 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "" +"В настоящее время поддерживаются только политики PERMISSIVE и RESTRICTIVE." + +#: gram.y:5453 +msgid "duplicate trigger events specified" +msgstr "события триггера повторяются" + +#: gram.y:5601 +#, c-format +msgid "conflicting constraint properties" +msgstr "противоречащие характеристики ограничения" + +#: gram.y:5697 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "оператор CREATE ASSERTION ещё не реализован" + +#: gram.y:6080 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK более не требуется" + +#: gram.y:6081 +#, c-format +msgid "Update your data type." +msgstr "Обновите тип данных." + +#: gram.y:7832 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "у агрегатных функций не может быть выходных аргументов" + +#: gram.y:10154 gram.y:10172 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "" +"предложение WITH CHECK OPTION не поддерживается для рекурсивных представлений" + +#: gram.y:11780 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "синтаксис LIMIT #,# не поддерживается" + +#: gram.y:11781 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "Используйте отдельные предложения LIMIT и OFFSET." + +#: gram.y:12107 gram.y:12132 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "список VALUES во FROM должен иметь псевдоним" + +#: gram.y:12108 gram.y:12133 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "Например, FROM (VALUES ...) [AS] foo." + +#: gram.y:12113 gram.y:12138 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "подзапрос во FROM должен иметь псевдоним" + +#: gram.y:12114 gram.y:12139 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "Например, FROM (SELECT ...) [AS] foo." + +#: gram.y:12592 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "допускается только одно значение DEFAULT" + +#: gram.y:12601 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "для столбца допускается только одно значение PATH" + +#: gram.y:12610 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "" +"конфликтующие или избыточные объявления NULL/NOT NULL для столбца \"%s\"" + +#: gram.y:12619 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "нераспознанный параметр столбца \"%s\"" + +#: gram.y:12873 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "тип float должен иметь точность минимум 1 бит" + +#: gram.y:12882 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "тип float должен иметь точность меньше 54 бит" + +#: gram.y:13373 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "неверное число параметров в левой части выражения OVERLAPS" + +#: gram.y:13378 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "неверное число параметров в правой части выражения OVERLAPS" + +#: gram.y:13553 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "предикат UNIQUE ещё не реализован" + +#: gram.y:13916 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "ORDER BY с WITHIN GROUP можно указать только один раз" + +#: gram.y:13921 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "DISTINCT нельзя использовать с WITHIN GROUP" + +#: gram.y:13926 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "VARIADIC нельзя использовать с WITHIN GROUP" + +#: gram.y:14392 gram.y:14415 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "началом рамки не может быть UNBOUNDED FOLLOWING" + +#: gram.y:14397 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "" +"рамка, начинающаяся со следующей строки, не может заканчиваться текущей" + +#: gram.y:14420 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "концом рамки не может быть UNBOUNDED PRECEDING" + +#: gram.y:14426 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "" +"рамка, начинающаяся с текущей строки, не может иметь предшествующих строк" + +#: gram.y:14433 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "" +"рамка, начинающаяся со следующей строки, не может иметь предшествующих строк" + +#: gram.y:15083 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "параметр функции-модификатора типа должен быть безымянным" + +#: gram.y:15089 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "модификатор типа не может включать ORDER BY" + +#: gram.y:15154 gram.y:15161 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s нельзя использовать здесь как имя роли" + +#: gram.y:15842 gram.y:16031 +msgid "improper use of \"*\"" +msgstr "недопустимое использование \"*\"" + +#: gram.y:16095 +#, c-format +msgid "" +"an ordered-set aggregate with a VARIADIC direct argument must have one " +"VARIADIC aggregated argument of the same data type" +msgstr "" +"сортирующая агрегатная функция с непосредственным аргументом VARIADIC должна " +"иметь один агрегатный аргумент VARIADIC того же типа данных" + +#: gram.y:16132 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "ORDER BY можно указать только один раз" + +#: gram.y:16143 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "OFFSET можно указать только один раз" + +#: gram.y:16152 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "LIMIT можно указать только один раз" + +#: gram.y:16161 +#, c-format +msgid "multiple limit options not allowed" +msgstr "параметры LIMIT можно указать только один раз" + +#: gram.y:16165 +#, c-format +msgid "WITH TIES cannot be specified without ORDER BY clause" +msgstr "WITH TIES нельзя задать без предложения ORDER BY" + +#: gram.y:16173 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "WITH можно указать только один раз" + +#: gram.y:16377 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "в табличных функциях не может быть аргументов OUT и INOUT" + +#: gram.y:16473 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "COLLATE можно указать только один раз" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16511 gram.y:16524 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "ограничения %s не могут иметь характеристики DEFERRABLE" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16537 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "ограничения %s не могут иметь характеристики NOT VALID" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16550 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "ограничения %s не могут иметь характеристики NO INHERIT" + +#: guc-file.l:315 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "нераспознанный параметр конфигурации \"%s\" в файле \"%s\", строке %u" + +#: guc-file.l:388 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "" +"параметр \"%s\" удалён из файла конфигурации, он принимает значение по " +"умолчанию" + +#: guc-file.l:454 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "параметр \"%s\" принял значение \"%s\"" + +#: guc-file.l:496 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "файл конфигурации \"%s\" содержит ошибки" + +#: guc-file.l:501 +#, c-format +msgid "" +"configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "" +"файл конфигурации \"%s\" содержит ошибки; были применены не зависимые " +"изменения" + +#: guc-file.l:506 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "файл конфигурации \"%s\" содержит ошибки; изменения не были применены" + +#: guc-file.l:578 +#, c-format +msgid "empty configuration file name: \"%s\"" +msgstr "пустое имя файла конфигурации: \"%s\"" + +#: guc-file.l:595 +#, c-format +msgid "" +"could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "" +"открыть файл конфигурации \"%s\" не удалось: превышен предел вложенности" + +#: guc-file.l:615 +#, c-format +msgid "configuration file recursion in \"%s\"" +msgstr "рекурсивная вложенность файла конфигурации в \"%s\"" + +#: guc-file.l:642 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "отсутствующий файл конфигурации \"%s\" пропускается" + +#: guc-file.l:896 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "ошибка синтаксиса в файле \"%s\", в конце строки %u" + +#: guc-file.l:906 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "ошибка синтаксиса в файле \"%s\", в строке %u, рядом с \"%s\"" + +#: guc-file.l:926 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "" +"обнаружено слишком много синтаксических ошибок, обработка файла \"%s\" " +"прекращается" + +#: guc-file.l:981 +#, c-format +msgid "empty configuration directory name: \"%s\"" +msgstr "пустое имя каталога конфигурации: \"%s\"" + +#: guc-file.l:1000 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "открыть каталог конфигурации \"%s\" не удалось: %m" + +#: jsonpath_gram.y:529 +#, c-format +msgid "unrecognized flag character \"%c\" in LIKE_REGEX predicate" +msgstr "нераспознанный символ флага \"%c\" в предикате LIKE_REGEX" + +#: jsonpath_gram.y:583 +#, c-format +msgid "XQuery \"x\" flag (expanded regular expressions) is not implemented" +msgstr "" +"флаг \"x\" языка XQuery (расширенные регулярные выражения) не реализован" + +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:286 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "%s в конце аргумента jsonpath" + +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:293 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s в строке jsonpath (примерное положение: \"%s\")" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "неверная линия времени %u" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "неверная позиция начала потока" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "незавершённая строка в кавычках" + +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "незавершённый комментарий /*" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "оборванная битовая строка" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "оборванная шестнадцатеричная строка" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "небезопасное использование строковой константы со спецкодами Unicode" + +#: scan.l:543 +#, c-format +msgid "" +"String constants with Unicode escapes cannot be used when " +"standard_conforming_strings is off." +msgstr "" +"Строки со спецкодами Unicode нельзя использовать, когда параметр " +"standard_conforming_strings выключен." + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "" +"необрабатываемое предыдущее состояние при обнаружении закрывающего апострофа" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Спецкоды Unicode должны иметь вид \\uXXXX или \\UXXXXXXXX." + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "небезопасное использование символа \\' в строке" + +#: scan.l:690 +#, c-format +msgid "" +"Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "" +"Записывайте апостроф в строке в виде ''. Запись \\' небезопасна для " +"исключительно клиентских кодировок." + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "незавершённая спецстрока с $" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "пустой идентификатор в кавычках" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "незавершённый идентификатор в кавычках" + +#: scan.l:963 +msgid "operator too long" +msgstr "слишком длинный оператор" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1171 +#, c-format +msgid "%s at end of input" +msgstr "%s в конце" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1179 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s (примерное положение: \"%s\")" + +#: scan.l:1373 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "нестандартное применение \\' в строке" + +#: scan.l:1374 +#, c-format +msgid "" +"Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "" +"Записывайте апостроф в строках в виде '' или используйте синтаксис спецстрок " +"(E'...')." + +#: scan.l:1383 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "нестандартное применение \\\\ в строке" + +#: scan.l:1384 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "" +"Используйте для записи обратных слэшей синтаксис спецстрок, например E'\\\\'." + +#: scan.l:1398 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "нестандартное использование спецсимвола в строке" + +#: scan.l:1399 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Используйте для записи спецсимволов синтаксис спецстрок E'\\r\\n'." + +#~ msgid "" +#~ "moving row to another partition during a BEFORE trigger is not supported" +#~ msgstr "в триггере BEFORE нельзя перемещать строку в другую секцию" + +#~ msgid "" +#~ "GSSAPI encryption can only be used with gss, trust, or reject " +#~ "authentication methods" +#~ msgstr "" +#~ "шифрование GSSAPI может применяться только с методами аутентификации gss, " +#~ "trust и reject" + +#~ msgid "" +#~ "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +#~ msgstr "" +#~ "pg_hba.conf отвергает подключение для репликации: компьютер \"%s\", " +#~ "пользователь \"%s\"" + +#~ msgid "" +#~ "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s" +#~ "\"" +#~ msgstr "" +#~ "pg_hba.conf отвергает подключение: компьютер \"%s\", пользователь \"%s\", " +#~ "база данных \"%s\"" + +#~ msgid "" +#~ "no pg_hba.conf entry for replication connection from host \"%s\", user " +#~ "\"%s\"" +#~ msgstr "" +#~ "в pg_hba.conf нет записи, разрешающей подключение для репликации с " +#~ "компьютера \"%s\" для пользователя \"%s\"" + +#~ msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +#~ msgstr "" +#~ "в pg_hba.conf нет записи для компьютера \"%s\", пользователя \"%s\", базы " +#~ "\"%s\"" + +#~ msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +#~ msgstr "" +#~ "шифрование GSSAPI поддерживается только с методами аутентификации gss, " +#~ "trust и reject" + +#~ msgid "invalid concatenation of jsonb objects" +#~ msgstr "неверная конкатенация объектов jsonb" + +#~ msgid "" +#~ "replication connection authorized: user=%s application_name=%s SSL " +#~ "enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "" +#~ "подключение для репликации авторизовано: пользователь=%s, имя_приложения=" +#~ "%s, SSL включён (протокол=%s, шифр=%s, битов=%d, сжатие=%s)" + +#~ msgid "replication connection authorized: user=%s application_name=%s" +#~ msgstr "" +#~ "подключение для репликации авторизовано: пользователь=%s, имя_приложения=" +#~ "%s" + +#~ msgid "" +#~ "connection authorized: user=%s database=%s application_name=%s SSL " +#~ "enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +#~ msgstr "" +#~ "подключение авторизовано: пользователь=%s, база=%s, имя_приложения=%s, " +#~ "SSL включён (протокол=%s, шифр=%s, битов=%d, сжатие=%s)" + +#~ msgid "" +#~ "connection authorized: user=%s database=%s SSL enabled (protocol=%s, " +#~ "cipher=%s, bits=%d, compression=%s)" +#~ msgstr "" +#~ "подключение авторизовано: пользователь=%s, база=%s, SSL включён (протокол=" +#~ "%s, шифр=%s, битов=%d, сжатие=%s)" + +#~ msgid "connection authorized: user=%s database=%s application_name=%s" +#~ msgstr "" +#~ "подключение авторизовано: пользователь=%s, база=%s, имя_приложения=%s" + +#~ msgid "connection authorized: user=%s database=%s" +#~ msgstr "подключение авторизовано: пользователь=%s, база=%s" + +#~ msgid "unexpected standby message type \"%c\", after receiving CopyDone" +#~ msgstr "" +#~ "после CopyDone резервный сервер передал сообщение неожиданного типа \"%c\"" + +#~ msgid "" +#~ "scanned index \"%s\" to remove %d row versions by parallel vacuum worker" +#~ msgstr "" +#~ "просканирован индекс \"%s\", параллельным процессом очистки удалено " +#~ "версий строк: %d" + +#~ msgid "" +#~ "index \"%s\" now contains %.0f row versions in %u pages as reported by " +#~ "parallel vacuum worker" +#~ msgstr "" +#~ "индекс \"%s\" теперь содержит версий строк: %.0f, в страницах: %u (по " +#~ "информации параллельного процесса очистки)" + +#~ msgid "insufficient columns in %s constraint definition" +#~ msgstr "недостаточно столбцов в определении ограничения %s" + +#~ msgid "cannot reindex invalid index on TOAST table concurrently" +#~ msgstr "" +#~ "перестроить нерабочий индекс в таблице TOAST неблокирующим способом нельзя" + +#~ msgid "starting parallel vacuum worker for %s" +#~ msgstr "запуск параллельного процесса очистки \"%s\"" + +#~ msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +#~ msgstr "" +#~ "в BRIN-индексе \"%s\" обнаружен оставшийся кортеж-местозаполнитель, он " +#~ "удаляется" + +#~ msgid "invalid value for \"buffering\" option" +#~ msgstr "неверное значение для параметра \"buffering\"" + +#~ msgid "could not write block %ld of temporary file: %m" +#~ msgstr "не удалось записать блок %ld временного файла: %m" + +# skip-rule: capital-letter-first +#~ msgid "" +#~ "skipping redundant vacuum to prevent wraparound of table \"%s.%s.%s\"" +#~ msgstr "" +#~ "пропускается очистка, предотвращающая зацикливание, для таблицы \"%s.%s.%s" +#~ "\"" + +#~ msgid "" +#~ "The database cluster was initialized without USE_FLOAT4_BYVAL but the " +#~ "server was compiled with USE_FLOAT4_BYVAL." +#~ msgstr "" +#~ "Кластер баз данных был инициализирован без USE_FLOAT4_BYVAL, но сервер " +#~ "скомпилирован с USE_FLOAT4_BYVAL." + +#~ msgid "" +#~ "The database cluster was initialized with USE_FLOAT4_BYVAL but the server " +#~ "was compiled without USE_FLOAT4_BYVAL." +#~ msgstr "" +#~ "Кластер баз данных был инициализирован с USE_FLOAT4_BYVAL, но сервер " +#~ "скомпилирован без USE_FLOAT4_BYVAL." + +#~ msgid "could not seek in log segment %s to offset %u: %m" +#~ msgstr "не удалось переместиться в сегменте журнала %s к смещению %u: %m" + +#~ msgid "could not read from log segment %s, offset %u, length %lu: %m" +#~ msgstr "" +#~ "не удалось прочитать сегмент журнала %s (смещение %u, длина %lu): %m" + +#~ msgid "" +#~ "An aggregate using a polymorphic transition type must have at least one " +#~ "polymorphic argument." +#~ msgstr "" +#~ "Агрегатная функция, использующая полиморфный переходный тип, должна иметь " +#~ "минимум один полиморфный аргумент." + +#~ msgid "" +#~ "An aggregate returning a polymorphic type must have at least one " +#~ "polymorphic argument." +#~ msgstr "" +#~ "Агрегатная функция, возвращающая полиморфный тип, должна иметь минимум " +#~ "один полиморфный аргумент." + +#~ msgid "" +#~ "A function returning \"internal\" must have at least one \"internal\" " +#~ "argument." +#~ msgstr "" +#~ "Функция, возвращающая \"internal\", должна иметь минимум один аргумент " +#~ "\"internal\"." + +#~ msgid "" +#~ "A function returning a polymorphic type must have at least one " +#~ "polymorphic argument." +#~ msgstr "" +#~ "Функция, возвращающая полиморфный тип, должна иметь минимум один " +#~ "полиморфный аргумент." + +#~ msgid "" +#~ "A function returning \"anyrange\" must have at least one \"anyrange\" " +#~ "argument." +#~ msgstr "" +#~ "Функция, возвращающая \"anyrange\", должна иметь минимум один аргумент " +#~ "\"anyrange\"." + +#~ msgid "Adding partitioned tables to publications is not supported." +#~ msgstr "Добавление секционированных таблиц в публикации не поддерживается." + +#~ msgid "You can add the table partitions individually." +#~ msgstr "Но вы можете добавить секции таблицы по одной." + +#~ msgid "EXPLAIN option BUFFERS requires ANALYZE" +#~ msgstr "параметр BUFFERS оператора EXPLAIN требует указания ANALYZE" + +#~ msgid "" +#~ "FROM version must be different from installation target version \"%s\"" +#~ msgstr "версия FROM должна отличаться от устанавливаемой версии \"%s\"" + +#~ msgid "" +#~ "using pg_pltemplate information instead of CREATE LANGUAGE parameters" +#~ msgstr "" +#~ "вместо параметров CREATE LANGUAGE используется информация pg_pltemplate" + +#~ msgid "must be superuser to create procedural language \"%s\"" +#~ msgstr "" +#~ "для создания процедурного языка \"%s\" нужно быть суперпользователем" + +#~ msgid "unsupported language \"%s\"" +#~ msgstr "неподдерживаемый язык: \"%s\"" + +#~ msgid "" +#~ "The supported languages are listed in the pg_pltemplate system catalog." +#~ msgstr "" +#~ "Список поддерживаемых языков содержится в системном каталоге " +#~ "pg_pltemplate." + +#~ msgid "changing return type of function %s from %s to %s" +#~ msgstr "изменение типа возврата функции %s с %s на %s" + +#~ msgid "column \"%s\" contains null values" +#~ msgstr "столбец \"%s\" содержит значения NULL" + +#~ msgid "" +#~ "updated partition constraint for default partition would be violated by " +#~ "some row" +#~ msgstr "" +#~ "изменённое ограничение секции для секции по умолчанию будет нарушено " +#~ "некоторыми строками" + +#~ msgid "partition key expressions cannot contain whole-row references" +#~ msgstr "" +#~ "выражения ключей секционирования не могут содержать ссылки на кортеж " +#~ "целиком" + +#~ msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +#~ msgstr "" +#~ "В секционированных таблицах не может быть триггеров BEFORE / FOR EACH ROW." + +#~ msgid "Found referenced table's UPDATE trigger." +#~ msgstr "Найден триггер UPDATE в главной таблице." + +#~ msgid "Found referenced table's DELETE trigger." +#~ msgstr "Найден триггер DELETE в главной таблице." + +#~ msgid "Found referencing table's trigger." +#~ msgstr "Найден триггер в подчинённой таблице." + +#~ msgid "ignoring incomplete trigger group for constraint \"%s\" %s" +#~ msgstr "неполный набор триггеров для ограничения \"%s\" %s игнорируется" + +#~ msgid "converting trigger group into constraint \"%s\" %s" +#~ msgstr "преобразование набора триггеров в ограничение \"%s\" %s" + +#~ msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" +#~ msgstr "изменение типа аргумента функции %s с \"opaque\" на \"cstring\"" + +#~ msgid "changing argument type of function %s from \"opaque\" to %s" +#~ msgstr "изменение типа аргумента функции %s с \"opaque\" на %s" + +#~ msgid "invalid value for \"check_option\" option" +#~ msgstr "неверное значение для параметра \"check_option\"" + +#~ msgid "\"%s.%s\" is a partitioned table." +#~ msgstr "\"%s.%s\" — секционированная таблица." + +#~ msgid "" +#~ "could not determine actual result type for function declared to return " +#~ "type %s" +#~ msgstr "" +#~ "не удалось определить фактический тип результата для функции (в " +#~ "объявлении указан тип %s)" + +#~ msgid "could not write to hash-join temporary file: %m" +#~ msgstr "не удалось записать во временный файл хеш-соединения: %m" + +#~ msgid "could not load wldap32.dll" +#~ msgstr "не удалось загрузить wldap32.dll" + +#~ msgid "SSL certificate revocation list file \"%s\" ignored" +#~ msgstr "файл со списком отзыва сертификатов SSL \"%s\" игнорируется" + +#~ msgid "SSL library does not support certificate revocation lists." +#~ msgstr "Библиотека SSL не поддерживает списки отзыва сертификатов." + +#~ msgid "could not find range type for data type %s" +#~ msgstr "тип диапазона для типа данных %s не найден" + +#~ msgid "could not create signal dispatch thread: error code %lu\n" +#~ msgstr "не удалось создать поток распределения сигналов (код ошибки: %lu)\n" + +#~ msgid "cannot advance replication slot that has not previously reserved WAL" +#~ msgstr "" +#~ "продвинуть слот репликации, для которого ранее не был зарезервирован WAL, " +#~ "нельзя" + +#~ msgid "could not read from log segment %s, offset %u, length %zu: %m" +#~ msgstr "" +#~ "не удалось прочитать сегмент журнала %s (смещение %u, длина %zu): %m" + +#~ msgid "cannot use advisory locks during a parallel operation" +#~ msgstr "" +#~ "использовать рекомендательные блокировки во время параллельных операций " +#~ "нельзя" + +#~ msgid "cannot output a value of type %s" +#~ msgstr "значение типа %s нельзя вывести" + +#~ msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." +#~ msgstr "В сервере FLOAT4PASSBYVAL = %s, в библиотеке: %s." + +#~ msgid "encoding name too long" +#~ msgstr "слишком длинное имя кодировки" + +#~ msgid "Encrypt passwords." +#~ msgstr "Шифровать пароли." + +#~ msgid "" +#~ "When a password is specified in CREATE USER or ALTER USER without writing " +#~ "either ENCRYPTED or UNENCRYPTED, this parameter determines whether the " +#~ "password is to be encrypted." +#~ msgstr "" +#~ "Этот параметр определяет, нужно ли шифровать пароли, заданные в CREATE " +#~ "USER или ALTER USER без указания ENCRYPTED или UNENCRYPTED." + +#~ msgid "\"%s\" cannot be lower than \"%s\"." +#~ msgstr "Версия \"%s\" не может быть ниже \"%s\"." + +#~ msgid "could not write to temporary file: %m" +#~ msgstr "не удалось записать во временный файл: %m" + +#~ msgid "could not write to tuplestore temporary file: %m" +#~ msgstr "не удалось записать во временный файл источника кортежей: %m" + +#~ msgid "" +#~ "Unicode escape values cannot be used for code point values above 007F " +#~ "when the server encoding is not UTF8" +#~ msgstr "" +#~ "Спецкоды Unicode для значений выше 007F можно использовать только с " +#~ "серверной кодировкой UTF8" + +#~ msgid "replication origin %d is already active for PID %d" +#~ msgstr "источник репликации %d уже занят процессом с PID %d" + +#~ msgid "could not rmdir directory \"%s\": %m" +#~ msgstr "ошибка удаления каталога \"%s\": %m" + +#~ msgid "Key (%s)=(%s) still referenced from table \"%s\"." +#~ msgstr "Ссылки на ключ (%s)=(%s) остаются в таблице \"%s\"." + +#~ msgid "GSSAPI context error" +#~ msgstr "ошибка контекста GSSAPI" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: не удалось открыть файл \"%s\" для чтения: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: не удалось прочитать файл \"%s\": %s\n" + +#~ msgid "could not read file \"%s\": read %d of %d" +#~ msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %d)" + +#~ msgid "%s: could not read file \"%s\": read %d of %d\n" +#~ msgstr "%s: не удалось прочитать файл \"%s\" (прочитано байт: %d из %d)\n" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "не удалось перейти в каталог \"%s\": %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "не удалось прочитать символическую ссылку \"%s\"" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: не удалось получить информацию о файле \"%s\": %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: не удалось открыть каталог \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: не удалось прочитать каталог \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: не удалось открыть файл \"%s\": %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: не удалось синхронизировать с ФС файл \"%s\": %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s: не удалось переименовать файл \"%s\" в \"%s\": %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "не удалось открыть каталог \"%s\": %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "не удалось прочитать каталог \"%s\": %s\n" + +#~ msgid "could not stat file or directory \"%s\": %s\n" +#~ msgstr "не удалось получить информацию о файле или каталоге \"%s\": %s\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "дочерний процесс завершён по сигналу %s" + +#~ msgid "unrecognized error %d" +#~ msgstr "нераспознанная ошибка %d" + +#~ msgid "could not open two-phase state file \"%s\": %m" +#~ msgstr "не удалось открыть файл состояния 2PC \"%s\": %m" + +#~ msgid "could not stat two-phase state file \"%s\": %m" +#~ msgstr "не удалось получить информацию о файле состояния 2PC \"%s\": %m" + +#~ msgid "could not read two-phase state file \"%s\": %m" +#~ msgstr "не удалось прочитать файл состояния 2PC \"%s\": %m" + +#~ msgid "could not remove two-phase state file \"%s\": %m" +#~ msgstr "не удалось стереть файл состояния 2PC \"%s\": %m" + +#~ msgid "could not recreate two-phase state file \"%s\": %m" +#~ msgstr "не удалось пересоздать файл состояния 2PC \"%s\": %m" + +#~ msgid "could not write two-phase state file: %m" +#~ msgstr "не удалось записать в файл состояния 2PC: %m" + +#~ msgid "could not fsync two-phase state file: %m" +#~ msgstr "не удалось синхронизировать с ФС файл состояния 2PC: %m" + +#~ msgid "could not close two-phase state file: %m" +#~ msgstr "не удалось закрыть файл состояния 2PC: %m" + +#~ msgid "cannot PREPARE a transaction that has operated on temporary tables" +#~ msgstr "" +#~ "нельзя выполнить PREPARE для транзакции, оперирующей с временными " +#~ "таблицами" + +#~ msgid "could not seek in log file %s to offset %u: %m" +#~ msgstr "не удалось переместиться в файле журнала %s к смещению %u: %m" + +#~ msgid "not enough data in file \"%s\"" +#~ msgstr "недостаточно данных в файле\"%s\"" + +#~ msgid "could not open write-ahead log file \"%s\": %m" +#~ msgstr "не удалось открыть файл журнала предзаписи \"%s\": %m" + +#~ msgid "could not close log file %s: %m" +#~ msgstr "не удалось закрыть файл журнала \"%s\": %m" + +#~ msgid "could not rename old write-ahead log file \"%s\": %m" +#~ msgstr "не удалось переименовать старый файл журнала предзаписи \"%s\": %m" + +#~ msgid "could not create control file \"%s\": %m" +#~ msgstr "не удалось создать файл \"%s\": %m" + +#~ msgid "could not write to control file: %m" +#~ msgstr "не удалось записать в файл pg_control: %m" + +#~ msgid "could not fsync control file: %m" +#~ msgstr "не удалось синхронизировать с ФС файл pg_control: %m" + +#~ msgid "could not close control file: %m" +#~ msgstr "не удалось закрыть файл pg_control: %m" + +#~ msgid "could not open control file \"%s\": %m" +#~ msgstr "не удалось открыть файл \"%s\": %m" + +#~ msgid "could not read from control file: %m" +#~ msgstr "не удалось прочитать файл pg_control: %m" + +#~ msgid "could not read from control file: read %d bytes, expected %d" +#~ msgstr "" +#~ "не удалось прочитать файл pg_control (прочитано байт: %d, ожидалось: %d)" + +#~ msgid "could not open recovery command file \"%s\": %m" +#~ msgstr "не удалось открыть файл команд восстановления \"%s\": %m" + +#~ msgid "invalid value for recovery parameter \"%s\": \"%s\"" +#~ msgstr "неверное значение для параметра восстановления \"%s\": \"%s\"" + +#~ msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." +#~ msgstr "Допустимые значения: \"pause\", \"promote\" и \"shutdown\"." + +#~ msgid "recovery_target_xid is not a valid number: \"%s\"" +#~ msgstr "recovery_target_xid не является допустимым числом: \"%s\"" + +#~ msgid "recovery_target_time is not a valid timestamp: \"%s\"" +#~ msgstr "" +#~ "значение recovery_target_time не представляет допустимое время: \"%s\"" + +#~ msgid "parameter \"%s\" requires a temporal value" +#~ msgstr "параметр \"%s\" требует временное значение" + +#~ msgid "unrecognized recovery parameter \"%s\"" +#~ msgstr "нераспознанный параметр восстановления \"%s\"" + +#~ msgid "" +#~ "If you are not restoring from a backup, try removing the file \"%s/" +#~ "backup_label\"." +#~ msgstr "" +#~ "Если вы не восстанавливаете БД из резервной копии, попробуйте удалить " +#~ "файл \"%s/backup_label\"." + +#~ msgid "could not fsync log segment %s: %m" +#~ msgstr "не удалось синхронизировать с ФС сегмент журнала %s: %m" + +#~ msgid "could not fsync log file %s: %m" +#~ msgstr "не удалось синхронизировать с ФС файл журнала %s: %m" + +#~ msgid "could not fdatasync log file %s: %m" +#~ msgstr "" +#~ "не удалось синхронизировать с ФС данные (fdatasync) файла журнала %s: %m" + +#~ msgid "pg_walfile_name_offset() cannot be executed during recovery." +#~ msgstr "" +#~ "Функцию pg_walfile_name_offset() нельзя вызывать во время восстановления." + +#~ msgid "pg_walfile_name() cannot be executed during recovery." +#~ msgstr "" +#~ "Функцию pg_walfile_name() нельзя вызывать в процессе восстановления." + +#~ msgid "shared tables cannot be toasted after initdb" +#~ msgstr "в разделяемые таблицы нельзя добавить TOAST после initdb" + +#~ msgid "table \"%s\" does not have OIDs" +#~ msgstr "таблица \"%s\" не содержит OID" + +#~ msgid "missing data for OID column" +#~ msgstr "нет данных для столбца OID" + +#~ msgid "null OID in COPY data" +#~ msgstr "неверное значение OID (NULL) в данных COPY" + +#~ msgid "invalid OID in COPY data" +#~ msgstr "неверный OID в данных COPY" + +#~ msgid "server does not exist, skipping" +#~ msgstr "сервер не существует, пропускается" + +#~ msgid "\"%s\" is not a table or a view" +#~ msgstr "\"%s\" — не таблица и не представление" + +#~ msgid "" +#~ "connect = false and create_slot = true are mutually exclusive options" +#~ msgstr "" +#~ "указания connect = false и create_slot = true являются взаимоисключающими" + +#~ msgid "connect = false and copy_data = true are mutually exclusive options" +#~ msgstr "" +#~ "указания connect = false и copy_data = true являются взаимоисключающими" + +#~ msgid "slot_name = NONE and enabled = true are mutually exclusive options" +#~ msgstr "" +#~ "указания slot_name = NONE и enabled = true являются взаимоисключающими" + +#~ msgid "" +#~ "slot_name = NONE and create_slot = true are mutually exclusive options" +#~ msgstr "" +#~ "указания slot_name = NONE и create_slot = true являются взаимоисключающими" + +#~ msgid "subscription with slot_name = NONE must also set create_slot = false" +#~ msgstr "" +#~ "для подписки с параметром slot_name = NONE необходимо также задать " +#~ "create_slot = false" + +#~ msgid "cannot create table with OIDs as partition of table without OIDs" +#~ msgstr "создать таблицу с OID в виде секции таблицы без OID нельзя" + +#~ msgid "child table \"%s\" has a conflicting \"%s\" column" +#~ msgstr "дочерняя таблица \"%s\" содержит конфликтующий столбец \"%s\"" + +#, fuzzy +#~ msgid "cannot drop column named in partition key" +#~ msgstr "нельзя удалить столбец, входящий в ключ секционирования" + +#~ msgid "cannot reference partitioned table \"%s\"" +#~ msgstr "ссылаться на секционированную таблицу \"%s\" нельзя" + +#, fuzzy +#~ msgid "cannot alter type of column named in partition key" +#~ msgstr "нельзя изменить тип столбца, составляющего ключ секционирования" + +#, fuzzy +#~ msgid "cannot alter type of column referenced in partition key expression" +#~ msgstr "" +#~ "нельзя изменить тип столбца, задействованного в выражении ключа " +#~ "секционирования" + +#~ msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +#~ msgstr "" +#~ "таблица \"%s\" без OID не может наследоваться от таблицы \"%s\" с OID" + +#~ msgid "data type %s has no default hash operator class" +#~ msgstr "" +#~ "для типа данных %s не определён класс операторов хеширования по умолчанию" + +#~ msgid "data type %s has no default btree operator class" +#~ msgstr "" +#~ "для типа данных %s не определён класс операторов B-дерева по умолчанию" + +#~ msgid "" +#~ "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with " +#~ "OIDs" +#~ msgstr "" +#~ "нельзя подключить таблицу \"%s\" без OID в качестве секции таблицы \"%s\" " +#~ "с OID" + +#~ msgid "" +#~ "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without " +#~ "OIDs" +#~ msgstr "" +#~ "нельзя подключить таблицу \"%s\" с OID в качестве секции таблицы \"%s\" " +#~ "без OID" + +#~ msgid "relation \"%s\" page %u is uninitialized --- fixing" +#~ msgstr "" +#~ "в отношении \"%s\" не инициализирована страница %u --- ситуация " +#~ "исправляется" + +#~ msgid "logical replication target relation \"%s.%s\" is not a table" +#~ msgstr "" +#~ "целевое отношение логической репликации \"%s.%s\" не является таблицей" + +#~ msgid "" +#~ "tuple to be deleted was already moved to another partition due to " +#~ "concurrent update" +#~ msgstr "" +#~ "кортеж, подлежащий удалению, был перемещён в другую секцию в результате " +#~ "параллельного изменения" + +#~ msgid "" +#~ "tuple to be updated was already moved to another partition due to " +#~ "concurrent update" +#~ msgstr "" +#~ "кортеж, подлежащий изменению, был перемещён в другую секцию в результате " +#~ "параллельного изменения" + +#~ msgid "The cast requires a non-immutable conversion." +#~ msgstr "Для этого приведения требуется непостоянное преобразование." + +#~ msgid "Try putting the literal value in single quotes." +#~ msgstr "Попробуйте заключить буквальное значение в апострофы." + +#~ msgid "archive command was terminated by signal %d" +#~ msgstr "команда архивации завершена по сигналу %d" + +#~ msgid "pg_ident.conf was not reloaded" +#~ msgstr "pg_ident.conf не был перезагружен" + +#~ msgid "%s (PID %d) was terminated by signal %d" +#~ msgstr "%s (PID %d) был завершён по сигналу %d" + +#~ msgid "could not stat control file \"%s\": %m" +#~ msgstr "не удалось найти управляющий файл \"%s\": %m" + +#, fuzzy +#~ msgid "replication identifier %d is already active for PID %d" +#~ msgstr "идентификатор репликации %d уже занят процессом с PID %d" + +#~ msgid "could not read file \"%s\", read %d of %d: %m" +#~ msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %d): %m" + +#~ msgid "could not read file \"%s\", read %d of %u: %m" +#~ msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %u): %m" + +#~ msgid "" +#~ "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a " +#~ "transaction" +#~ msgstr "" +#~ "Команда CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT не должна вызываться " +#~ "внутри транзакции" + +#~ msgid "" +#~ "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a " +#~ "transaction" +#~ msgstr "" +#~ "Команда CREATE_REPLICATION_SLOT ... USE_SNAPSHOT должна вызываться внутри " +#~ "транзакции" + +#~ msgid "" +#~ "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" +#~ msgstr "" +#~ "Команда CREATE_REPLICATION_SLOT ... USE_SNAPSHOT должна вызываться до " +#~ "каких-либо запросов" + +#~ msgid "" +#~ "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a " +#~ "subtransaction" +#~ msgstr "" +#~ "Команда CREATE_REPLICATION_SLOT ... USE_SNAPSHOT не должна вызываться в " +#~ "подтранзакции" + +#, fuzzy +#~ msgid "invalid zero-length item array in MVDependencies" +#~ msgstr "недопустимый массив нулевой длины в MVDependencies" + +#, fuzzy +#~ msgid "invalid ndistinct magic %08x (expected %08x)" +#~ msgstr "неверное магическое число ndistinct: %08x (ожидалось: %08x)" + +#, fuzzy +#~ msgid "invalid ndistinct type %d (expected %d)" +#~ msgstr "неверный тип ndistinct: %d (ожидался: %d)" + +#, fuzzy +#~ msgid "invalid zero-length item array in MVNDistinct" +#~ msgstr "недопустимый массив нулевой длины в MVNDistinct" + +#, fuzzy +#~ msgid "invalid MVNDistinct size %zd (expected at least %zd)" +#~ msgstr "неправильный размер MVNDistinct: %zd (ожидался не меньше %zd)" + +#~ msgid "dynamic shared memory is disabled" +#~ msgstr "динамическая разделяемая память отключена" + +#~ msgid "Set dynamic_shared_memory_type to a value other than \"none\"." +#~ msgstr "" +#~ "Установите для dynamic_shared_memory_type значение, отличное от \"none\"." + +#~ msgid "epoll_ctl() failed: %m" +#~ msgstr "ошибка в epoll_ctl(): %m" + +#~ msgid "epoll_wait() failed: %m" +#~ msgstr "ошибка в epoll_wait(): %m" + +#~ msgid "poll() failed: %m" +#~ msgstr "ошибка в poll(): %m" + +#~ msgid "corrupted item pointer: offset = %u, length = %u" +#~ msgstr "испорченный указатель элемента: смещение = %u, длина = %u" + +#~ msgid "could not seek to block %u in file \"%s\": %m" +#~ msgstr "не удалось перейти к блоку %u в файле \"%s\": %m" + +#~ msgid "date/time value \"current\" is no longer supported" +#~ msgstr "значение \"current\" для даты/времени больше не поддерживается" + +#~ msgid "cannot convert reserved abstime value to date" +#~ msgstr "преобразовать зарезервированное значение abstime в дату нельзя" + +#~ msgid "abstime out of range for date" +#~ msgstr "abstime вне диапазона для типа даты" + +#~ msgid "could not determine which collation to use for upper() function" +#~ msgstr "" +#~ "не удалось определить, какое правило сортировки использовать для функции " +#~ "upper()" + +#~ msgid "could not determine which collation to use for initcap() function" +#~ msgstr "" +#~ "не удалось определить, какое правило сортировки использовать для функции " +#~ "initcap()" + +#~ msgid "cannot create bounding box for empty polygon" +#~ msgstr "" +#~ "построить окружающий прямоугольник для пустого многоугольника нельзя" + +#~ msgid "cannot convert empty polygon to circle" +#~ msgstr "пустой многоугольник нельзя преобразовать в круг" + +#~ msgid "invalid input syntax for integer: \"%s\"" +#~ msgstr "неверное значение для целого числа: \"%s\"" + +#~ msgid "" +#~ "The arguments of jsonb_build_object() must consist of alternating keys " +#~ "and values." +#~ msgstr "" +#~ "Аргументы json_build_object() должны состоять из перемежающихся ключей и " +#~ "значений." + +#~ msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +#~ msgstr "" +#~ "Рассмотрите возможность использования функции pg_logfile_rotate(), " +#~ "включённой в ядро." + +#~ msgid "invalid time zone name: \"%s\"" +#~ msgstr "неверное название часового пояса: \"%s\"" + +#~ msgid "cannot convert abstime \"invalid\" to timestamp" +#~ msgstr "преобразовать значение \"invalid\" типа abstime в timestamp нельзя" + +#~ msgid "invalid status in external \"tinterval\" value" +#~ msgstr "неверное состояние во внешнем представлении \"tinterval\"" + +#~ msgid "cannot convert reltime \"invalid\" to interval" +#~ msgstr "преобразовать значение \"invalid\" типа reltime в interval нельзя" + +#~ msgid "ucnv_toUChars failed: %s" +#~ msgstr "ошибка ucnv_toUChars: %s" + +#~ msgid "ucnv_fromUChars failed: %s" +#~ msgstr "ошибка ucnv_fromUChars: %s" + +# skip-rule: capital-letter-first +# well-spelled: рег +#~ msgid "invalid regexp option: \"%c\"" +#~ msgstr "неверный элемент рег. выражения: \"%c\"" + +#~ msgid "regexp_split_to_table does not support the global option" +#~ msgstr "regexp_split_to_table не поддерживает глобальный поиск" + +#~ msgid "regexp_split_to_array does not support the global option" +#~ msgstr "regexp_split_to_array не поддерживает глобальный поиск" + +#~ msgid "date/time value \"%s\" is no longer supported" +#~ msgstr "значение даты/времени \"%s\" более не поддерживается" + +#~ msgid "invalid input syntax for numeric time zone: \"%s\"" +#~ msgstr "неверный синтаксис для числового часового пояса: \"%s\"" + +#~ msgid "could not open relation mapping file \"%s\": %m" +#~ msgstr "открыть файл сопоставления отношений \"%s\" не удалось: %m" + +#~ msgid "could not read relation mapping file \"%s\": %m" +#~ msgstr "прочитать файл сопоставления отношений \"%s\" не удалось: %m" + +#~ msgid "could not write to relation mapping file \"%s\": %m" +#~ msgstr "записать в файл сопоставления отношений \"%s\" не удалось: %m" + +#~ msgid "could not fsync relation mapping file \"%s\": %m" +#~ msgstr "" +#~ "синхронизировать файл сопоставления отношений \"%s\" с ФС не удалось: %m" + +#~ msgid "could not close relation mapping file \"%s\": %m" +#~ msgstr "закрыть файл сопоставления отношений \"%s\" не удалось: %m" + +#~ msgid "Create new tables with OIDs by default." +#~ msgstr "По умолчанию создавать новые таблицы со столбцом OID." + +#~ msgid "parameter \"%s\" requires a numeric value" +#~ msgstr "параметр \"%s\" требует числовое значение" + +#~ msgid "DROP ASSERTION is not yet implemented" +#~ msgstr "оператор DROP ASSERTION ещё не реализован" + +#~ msgid "view must have at least one column" +#~ msgstr "в представлении должен быть минимум один столбец" + +#~ msgid "" +#~ "If you're sure there are no old server processes still running, remove " +#~ "the shared memory block or just delete the file \"%s\"." +#~ msgstr "" +#~ "Если вы уверены, что процессов старого сервера уже не осталось, " +#~ "освободите этот блок разделяемой памяти или просто удалите файл \"%s\"." + +#~ msgid "" +#~ "cannot PREPARE a transaction that has operated on temporary namespace" +#~ msgstr "" +#~ "нельзя выполнить PREPARE для транзакции, оперирующей с временным " +#~ "пространством имён" + +#~ msgid "could not open BufFile \"%s\"" +#~ msgstr "не удалось открыть буферный файл \"%s\"" + +#~ msgid "foreign key referencing partitioned table \"%s\" must not be ONLY" +#~ msgstr "" +#~ "внешний ключ секционированной таблицы \"%s\" не может добавляться с ONLY" + +#~ msgid "%s cannot be executed from a function or multi-command string" +#~ msgstr "" +#~ "%s не может выполняться внутри функции или строки, включающей несколько " +#~ "команд" + +#~ msgid "no such savepoint" +#~ msgstr "нет такой точки сохранения" + +#~ msgid "could not open write-ahead log directory \"%s\": %m" +#~ msgstr "не удалось открыть каталог журнала предзаписи \"%s\": %m" + +#~ msgid "" +#~ "The database cluster was initialized with XLOG_SEG_SIZE %d, but the " +#~ "server was compiled with XLOG_SEG_SIZE %d." +#~ msgstr "" +#~ "Кластер баз данных был инициализирован с XLOG_SEG_SIZE %d, но сервер " +#~ "скомпилирован с XLOG_SEG_SIZE %d." + +#~ msgid "using previous checkpoint record at %X/%X" +#~ msgstr "используется предыдущая запись контрольной точки по смещению %X/%X" + +#~ msgid "invalid secondary checkpoint link in control file" +#~ msgstr "неверная ссылка на вторичную контрольную точку в файле pg_control" + +#~ msgid "invalid secondary checkpoint record" +#~ msgstr "неверная запись вторичной контрольной точки" + +#~ msgid "invalid resource manager ID in secondary checkpoint record" +#~ msgstr "неверный ID менеджера ресурсов в записи вторичной контрольной точки" + +#~ msgid "invalid xl_info in secondary checkpoint record" +#~ msgstr "неверные флаги xl_info в записи вторичной контрольной точки" + +#~ msgid "invalid length of secondary checkpoint record" +#~ msgstr "неверная длина записи вторичной контрольной точки" + +#~ msgid "" +#~ "WAL file is from different database system: incorrect XLOG_SEG_SIZE in " +#~ "page header" +#~ msgstr "" +#~ "файл WAL принадлежит другой СУБД: некорректный XLOG_SEG_SIZE в заголовке " +#~ "страницы" + +#~ msgid " in schema %s" +#~ msgstr " в схеме %s" + +#~ msgid "%s in publication %s" +#~ msgstr "%s в публикации %s" + +#~ msgid "table \"%s\" has multiple constraints named \"%s\"" +#~ msgstr "таблица \"%s\" содержит несколько ограничений с именем \"%s\"" + +#~ msgid "domain %s has multiple constraints named \"%s\"" +#~ msgstr "домен %s содержит несколько ограничений с именем \"%s\"" + +#~ msgid "\"%s\" is already an attribute of type %s" +#~ msgstr "\"%s\" уже является атрибутом типа %s" + +#~ msgid "function \"%s\" is an aggregate function" +#~ msgstr "\"%s\" - это агрегатная функция" + +#~ msgid "function \"%s\" is not an aggregate function" +#~ msgstr "\"%s\" - это не агрегатная функция" + +#~ msgid "function \"%s\" is not a window function" +#~ msgstr "\"%s\" - это не оконная функция" + +#~ msgid "must be superuser to COPY to or from a file" +#~ msgstr "для использования COPY с файлами нужно быть суперпользователем" + +#~ msgid "cannot copy to foreign table \"%s\"" +#~ msgstr "копировать в стороннюю таблицу \"%s\" нельзя" + +#~ msgid "cannot route inserted tuples to a foreign table" +#~ msgstr "направить вставляемые кортежи в стороннюю таблицу нельзя" + +#~ msgid "unrecognized function attribute \"%s\" ignored" +#~ msgstr "нераспознанный атрибут функции \"%s\" --- игнорируется" + +#~ msgid "cast function must not be an aggregate function" +#~ msgstr "функция приведения не может быть агрегатной" + +#~ msgid "transform function must not be an aggregate function" +#~ msgstr "функция преобразования не может быть агрегатной" + +#~ msgid "invalid procedure number %d, must be between 1 and %d" +#~ msgstr "неверный номер процедуры (%d), должен быть между 1 и %d" + +#~ msgid "procedure number %d for (%s,%s) appears more than once" +#~ msgstr "номер процедуры %d для (%s,%s) дублируется" + +#~ msgid "operator procedure must be specified" +#~ msgstr "должна быть указана процедура оператора" + +#~ msgid "column \"%s\" appears more than once in partition key" +#~ msgstr "столбец \"%s\" фигурирует в ключе разбиения неоднократно" + +#~ msgid "Close open transactions soon to avoid wraparound problems." +#~ msgstr "" +#~ "Скорее закройте открытые транзакции, чтобы избежать проблемы наложения." + +#~ msgid "combine function for aggregate %u must be declared as STRICT" +#~ msgstr "" +#~ "комбинирующая функция для агрегата %u должна объявляться как строгая " +#~ "(STRICT)" + +#~ msgid "client requires SCRAM channel binding, but it is not supported" +#~ msgstr "клиенту требуется привязка канала SCRAM, но она не поддерживается" + +#~ msgid "must be superuser to use server-side lo_import()" +#~ msgstr "" +#~ "для использования lo_import() на сервере нужно быть суперпользователем" + +#~ msgid "Anyone can use the client-side lo_import() provided by libpq." +#~ msgstr "Использовать lo_import() на стороне клиента через libpq могут все." + +#~ msgid "must be superuser to use server-side lo_export()" +#~ msgstr "" +#~ "для использования lo_export() на сервере нужно быть суперпользователем" + +#~ msgid "Anyone can use the client-side lo_export() provided by libpq." +#~ msgstr "Использовать lo_export() на стороне клиента через libpq могут все." + +#~ msgid "ON CONFLICT clause is not supported with partitioned tables" +#~ msgstr "" +#~ "предложение ON CONFLICT с секционированными таблицами не поддерживается" + +#~ msgid "foreign key constraints are not supported on partitioned tables" +#~ msgstr "" +#~ "ограничения внешнего ключа для секционированных таблиц не поддерживаются" + +#~ msgid "could not open archive status directory \"%s\": %m" +#~ msgstr "не удалось открыть каталог состояния архива \"%s\": %m" + +#~ msgid "%s: max_wal_senders must be less than max_connections\n" +#~ msgstr "%s: параметр max_wal_senders должен быть меньше max_connections\n" + +#~ msgid "data directory \"%s\" has group or world access" +#~ msgstr "к каталогу данных \"%s\" имеют доступ все или группа" + +#~ msgid "worker process" +#~ msgstr "рабочий процесс" + +#~ msgid "built-in type %u not found" +#~ msgstr "встроенный тип %u не найден" + +#~ msgid "" +#~ "This can be caused by having a publisher with a higher PostgreSQL major " +#~ "version than the subscriber." +#~ msgstr "" +#~ "Это может быть вызвано тем, что на сервере публикации установлена более " +#~ "новая основная версия PostgreSQL, чем на подписчике." + +#~ msgid "data type \"%s.%s\" required for logical replication does not exist" +#~ msgstr "" +#~ "тип данных \"%s.%s\", требуемый для логической репликации, не существует" + +#~ msgid "" +#~ "logical replication could not find row for delete in replication target " +#~ "relation \"%s\"" +#~ msgstr "" +#~ "при логической репликации не удалось найти строку для удаления в целевом " +#~ "отношении репликации \"%s\"" + +#~ msgid "memory for serializable conflict tracking is nearly exhausted" +#~ msgstr "" +#~ "память для отслеживания конфликтов сериализации практически исчерпана" + +#~ msgid "" +#~ "There might be an idle transaction or a forgotten prepared transaction " +#~ "causing this." +#~ msgstr "" +#~ "Вероятно, эта ситуация вызвана забытой подготовленной транзакцией или " +#~ "транзакцией, простаивающей долгое время." + +#~ msgid "could not open tablespace directory \"%s\": %m" +#~ msgstr "не удалось открыть каталог табличного пространства \"%s\": %m" + +#~ msgid "must be superuser to get file information" +#~ msgstr "получать информацию о файлах может только суперпользователь" + +#~ msgid "must be superuser to get directory listings" +#~ msgstr "читать содержимое каталогов может только суперпользователь" + +#~ msgid "" +#~ "Sets the maximum number of tuples to be sorted using replacement " +#~ "selection." +#~ msgstr "" +#~ "Задаёт предельное число кортежей, сортируемое посредством алгоритма " +#~ "выбора с замещением." + +#~ msgid "When more tuples than this are present, quicksort will be used." +#~ msgstr "" +#~ "Когда кортежей больше этого количества, будет применяться quicksort." + +#~ msgid "RANGE PRECEDING is only supported with UNBOUNDED" +#~ msgstr "RANGE PRECEDING поддерживается только с UNBOUNDED" + +#~ msgid "RANGE FOLLOWING is only supported with UNBOUNDED" +#~ msgstr "RANGE FOLLOWING поддерживается только с UNBOUNDED" + +#~ msgid "invalid number of arguments: object must be matched key value pairs" +#~ msgstr "" +#~ "неверное число аргументов: объект должен составляться из пар ключ-значение" + +#~ msgid "invalid publish list" +#~ msgstr "неверный список публикации" + +#~ msgid "column \"%s\" referenced in statistics does not exist" +#~ msgstr "столбец \"%s\", указанный в статистике, не существует" + +#~ msgid "not connected to database" +#~ msgstr "нет подключения к базе данных" + +#~ msgid "invalid input syntax for %s: \"%s\"" +#~ msgstr "неверный синтаксис для %s: \"%s\"" + +#~ msgid "transaction ID " +#~ msgstr "идентификатор транзакции " + +#~ msgid "in progress" +#~ msgstr "выполняется" + +#~ msgid "committed" +#~ msgstr "зафиксирована" + +#~ msgid "aborted" +#~ msgstr "прервана" + +#~ msgid "could not get keyword values for locale \"%s\": %s" +#~ msgstr "не удалось получить значения ключевых слов для локали \"%s\": %s" + +#~ msgid "index row size %lu exceeds maximum %lu for index \"%s\"" +#~ msgstr "" +#~ "размер строки индекса (%lu) больше предельного размера (%lu) (индекс \"%s" +#~ "\")" + +#~ msgid "" +#~ "brin operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов brin \"%s\" содержит функцию %s с неправильным " +#~ "опорным номером %d" + +#~ msgid "" +#~ "brin operator family \"%s\" contains function %s with wrong signature for " +#~ "support number %d" +#~ msgstr "" +#~ "семейство операторов brin \"%s\" содержит функцию %s с неподходящим " +#~ "объявлением для опорного номера %d" + +#~ msgid "" +#~ "brin operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов brin \"%s\" содержит оператор %s с неправильным " +#~ "номером стратегии %d" + +#~ msgid "" +#~ "brin operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "семейство операторов brin \"%s\" содержит некорректное определение ORDER " +#~ "BY для оператора %s" + +#~ msgid "" +#~ "brin operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "семейство операторов brin \"%s\" содержит оператор %s с неподходящим " +#~ "объявлением" + +#~ msgid "brin operator class \"%s\" is missing support function %d" +#~ msgstr "в классе операторов brin \"%s\" нет опорной функции %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains support procedure %s with cross-type " +#~ "registration" +#~ msgstr "" +#~ "семейство операторов gist \"%s\" содержит опорную процедуру %s с " +#~ "межтиповой регистрацией" + +#~ msgid "" +#~ "gist operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов gist \"%s\" содержит функцию %s с неправильным " +#~ "опорным номером %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains function %s with wrong signature for " +#~ "support number %d" +#~ msgstr "" +#~ "семейство операторов gist \"%s\" содержит функцию %s с неподходящим " +#~ "объявлением для опорного номера %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов gist \"%s\" содержит оператор %s с неправильным " +#~ "номером стратегии %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "семейство операторов gist \"%s\" содержит оператор %s с неподходящим " +#~ "объявлением" + +#~ msgid "gist operator class \"%s\" is missing support function %d" +#~ msgstr "в классе операторов gist \"%s\" нет опорной функции %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains support procedure %s with cross-type " +#~ "registration" +#~ msgstr "" +#~ "семейство операторов hash \"%s\" содержит опорную процедуру %s с " +#~ "межтиповой регистрацией" + +#~ msgid "" +#~ "hash operator family \"%s\" contains function %s with wrong signature for " +#~ "support number %d" +#~ msgstr "" +#~ "семейство операторов hash \"%s\" содержит функцию %s с неподходящим " +#~ "объявлением для опорного номера %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов hash \"%s\" содержит функцию %s с неправильным " +#~ "опорным номером %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов hash \"%s\" содержит оператор %s с неправильным " +#~ "номером стратегии %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "семейство операторов hash \"%s\" содержит некорректное определение ORDER " +#~ "BY для оператора %s" + +#~ msgid "" +#~ "hash operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "семейство операторов hash \"%s\" содержит оператор %s с неподходящим " +#~ "объявлением" + +#~ msgid "" +#~ "hash operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "в семействе операторов hash \"%s\" нет оператора(ов) для типов %s и %s" + +#~ msgid "hash operator class \"%s\" is missing operator(s)" +#~ msgstr "в классе операторов hash \"%s\" нет оператора(ов)" + +#~ msgid "" +#~ "btree operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов btree \"%s\" содержит функцию %s с неправильным " +#~ "опорным номером %d" + +#~ msgid "" +#~ "btree operator family \"%s\" contains function %s with wrong signature " +#~ "for support number %d" +#~ msgstr "" +#~ "семейство операторов btree \"%s\" содержит функцию %s с неподходящим " +#~ "объявлением для опорного номера %d" + +#~ msgid "" +#~ "btree operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов btree \"%s\" содержит оператор %s с неправильным " +#~ "номером стратегии %d" + +#~ msgid "" +#~ "btree operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "семейство операторов btree \"%s\" содержит некорректное определение ORDER " +#~ "BY для оператора %s" + +#~ msgid "" +#~ "btree operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "семейство операторов btree \"%s\" содержит оператор %s с неподходящим " +#~ "объявлением" + +#~ msgid "" +#~ "btree operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "в семействе операторов btree \"%s\" нет оператора(ов) для типов %s и %s" + +#~ msgid "btree operator class \"%s\" is missing operator(s)" +#~ msgstr "в классе операторов btree \"%s\" нет оператора(ов)" + +#~ msgid "btree operator family \"%s\" is missing cross-type operator(s)" +#~ msgstr "в семействе операторов btree \"%s\" нет межтипового оператора(ов)" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains support procedure %s with cross-" +#~ "type registration" +#~ msgstr "" +#~ "семейство операторов spgist \"%s\" содержит опорную процедуру %s с " +#~ "межтиповой регистрацией" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов spgist \"%s\" содержит функцию %s с неправильным " +#~ "опорным номером %d" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains function %s with wrong signature " +#~ "for support number %d" +#~ msgstr "" +#~ "семейство операторов spgist \"%s\" содержит функцию %s с неподходящим " +#~ "объявлением для опорного номера %d" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "семейство операторов spgist \"%s\" содержит оператор %s с неправильным " +#~ "номером стратегии %d" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "семейство операторов spgist \"%s\" содержит некорректное определение " +#~ "ORDER BY для оператора %s" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "семейство операторов spgist \"%s\" содержит оператор %s с неподходящим " +#~ "объявлением" + +#~ msgid "" +#~ "spgist operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "в семействе операторов spgist \"%s\" нет оператора(ов) для типов %s и %s" + +#~ msgid "spgist operator class \"%s\" is missing operator(s)" +#~ msgstr "в классе операторов spgist \"%s\" нет оператора(ов)" + +#~ msgid "cannot create temporary tables in parallel mode" +#~ msgstr "создавать временные таблицы в параллельном режиме нельзя" + +#~ msgid "cannot create range partition with empty range" +#~ msgstr "создать диапазонную секцию с пустым диапазоном нельзя" + +#~ msgid "could get display name for locale \"%s\": %s" +#~ msgstr "не удалось получить отображаемое название локали \"%s\": %s" + +#~ msgid "synchronized table states" +#~ msgstr "состояние таблиц синхронизировано" + +#~ msgid "added subscription for table %s.%s" +#~ msgstr "добавлена подписка на таблицу %s.%s" + +#~ msgid "removed subscription for table %s.%s" +#~ msgstr "удалена подписка на таблицу %s.%s" + +#~ msgid "malformed SCRAM message (length mismatch)" +#~ msgstr "неправильное сообщение SCRAM (некорректная длина)" + +#~ msgid "invalid SCRAM response (nonce mismatch)" +#~ msgstr "неверный ответ SCRAM (несовпадение проверочного кода)" + +#~ msgid "malformed SCRAM message (attribute '%c' expected, %s found)" +#~ msgstr "неправильное сообщение SCRAM (ожидался атрибут '%c', получено: %s)" + +#~ msgid "malformed SCRAM message (expected = in attr %c)" +#~ msgstr "неправильное сообщение SCRAM (в атрибуте %c ожидалось =)" + +#~ msgid "malformed SCRAM message (attribute expected, invalid char %s found)" +#~ msgstr "" +#~ "неправильное сообщение SCRAM (ожидался атрибут, получен некорректный " +#~ "символ %s)" + +#~ msgid "malformed SCRAM message (comma expected, got %s)" +#~ msgstr "неправильное сообщение SCRAM (ожидалась запятая, получено: %s)" + +#~ msgid "User \"%s\" has an empty password." +#~ msgstr "У пользователя \"%s\" пустой пароль." + +#~ msgid "cannot specify finite value after UNBOUNDED" +#~ msgstr "указать конечное значение после UNBOUNDED нельзя" + +#~ msgid "could not determine data type for argument 1" +#~ msgstr "не удалось определить тип данных аргумента 1" + +#~ msgid "could not determine data type for argument 2" +#~ msgstr "не удалось определить тип данных аргумента 2" + +#~ msgid "argument %d: could not determine data type" +#~ msgstr "аргумент %d: не удалось определить тип данных" + +#~ msgid "could not open transaction log file \"%s\": %m" +#~ msgstr "не удалось открыть файл журнала транзакций \"%s\": %m" + +#~ msgid "removing transaction log backup history file \"%s\"" +#~ msgstr "удаляется файл истории копирования журнала: \"%s\"" + +#~ msgid "range partition key of row contains null" +#~ msgstr "ключ разбиения по диапазонам в строке таблицы содержит NULL" + +#~ msgid "extended statistics \"%s\" do not exist, skipping" +#~ msgstr "расширенная статистика \"%s\" не существует, пропускается" + +#~ msgid "only scalar types can be used in extended statistics" +#~ msgstr "в расширенной статистике могут использоваться только скалярные типы" + +#~ msgid "unrecognized STATISTICS option \"%s\"" +#~ msgstr "нераспознанное указание для STATISTICS: \"%s\"" + +#~ msgid "must truncate child tables too" +#~ msgstr "опустошаться должны также и дочерние таблицы" + +#~ msgid "constraint must be dropped from child tables too" +#~ msgstr "ограничение также должно удаляться из дочерних таблиц" + +#~ msgid "column \"%s\" is in range partition key" +#~ msgstr "столбец \"%s\" входит в ключ разбиения по диапазонам" + +#~ msgid "column must be dropped from child tables too" +#~ msgstr "столбец также должен удаляться из дочерних таблиц" + +#~ msgid "transaction log switch forced (archive_timeout=%d)" +#~ msgstr "принудительное переключение журнала транзакций (archive_timeout=%d)" + +#~ msgid "archived transaction log file \"%s\"" +#~ msgstr "файл архива журнала транзакций \"%s\"" + +#~ msgid "Transaction ID %u finished; no more running transactions." +#~ msgstr "Транзакция %u завершена, больше активных транзакций нет." + +#~ msgid "%u transaction needs to finish." +#~ msgid_plural "%u transactions need to finish." +#~ msgstr[0] "Необходимо дождаться завершения транзакций (%u)." +#~ msgstr[1] "Необходимо дождаться завершения транзакций (%u)." +#~ msgstr[2] "Необходимо дождаться завершения транзакций (%u)." + +#~ msgid "Consider ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1" +#~ msgstr "Попробуйте ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1" + +#~ msgid "could not attach to dsa_handle" +#~ msgstr "не удалось подключиться к dsa" + +#~ msgid "could not remove old transaction log file \"%s\": %m" +#~ msgstr "не удалось стереть старый файл журнала транзакций \"%s\": %m" + +#~ msgid "function %u has too many arguments (%d, maximum is %d)" +#~ msgstr "у функции %u слишком много аргументов (%d, при максимуме %d)" + +#~ msgid "" +#~ "WARNING: Calculated CRC checksum does not match value stored in file.\n" +#~ "Either the file is corrupt, or it has a different layout than this " +#~ "program\n" +#~ "is expecting. The results below are untrustworthy.\n" +#~ "\n" +#~ msgstr "" +#~ "ПРЕДУПРЕЖДЕНИЕ: Вычисленная контрольная сумма не совпадает со значением в " +#~ "файле.\n" +#~ "Либо файл повреждён, либо его формат отличается от ожидаемого.\n" +#~ "Следующая информация может быть недостоверной.\n" +#~ "\n" + +#~ msgid "" +#~ "The database cluster was initialized without HAVE_INT64_TIMESTAMP but the " +#~ "server was compiled with HAVE_INT64_TIMESTAMP." +#~ msgstr "" +#~ "Кластер баз данных был инициализирован без HAVE_INT64_TIMESTAMP, но " +#~ "сервер скомпилирован с HAVE_INT64_TIMESTAMP." + +#~ msgid "" +#~ "The database cluster was initialized with HAVE_INT64_TIMESTAMP but the " +#~ "server was compiled without HAVE_INT64_TIMESTAMP." +#~ msgstr "" +#~ "Кластер баз данных был инициализирован с HAVE_INT64_TIMESTAMP, но сервер " +#~ "скомпилирован без HAVE_INT64_TIMESTAMP." + +#~ msgid "invalid privilege type USAGE for table" +#~ msgstr "право USAGE неприменимо для таблиц" + +#~ msgid "column \"%s\" has type \"unknown\"" +#~ msgstr "столбец \"%s\" имеет неизвестный тип (UNKNOWN)" + +#~ msgid "Proceeding with relation creation anyway." +#~ msgstr "Несмотря на это, создание отношения продолжается." + +#~ msgid "default expression must not return a set" +#~ msgstr "выражение по умолчанию не может возвращать множество" + +#~ msgid "access method name cannot be qualified" +#~ msgstr "имя метода доступа не может быть составным" + +#~ msgid "database name cannot be qualified" +#~ msgstr "имя базы данных не может быть составным" + +#~ msgid "extension name cannot be qualified" +#~ msgstr "имя расширения не может быть составным" + +#~ msgid "tablespace name cannot be qualified" +#~ msgstr "имя табличного пространства не может быть составным" + +#~ msgid "role name cannot be qualified" +#~ msgstr "имя роли не может быть составным" + +#~ msgid "schema name cannot be qualified" +#~ msgstr "имя схемы не может быть составным" + +#~ msgid "language name cannot be qualified" +#~ msgstr "имя языка не может быть составным" + +#~ msgid "foreign-data wrapper name cannot be qualified" +#~ msgstr "имя обёртки сторонних данных не может быть составным" + +#~ msgid "server name cannot be qualified" +#~ msgstr "имя сервера не может быть составным" + +#~ msgid "event trigger name cannot be qualified" +#~ msgstr "имя событийного триггера не может быть составным" + +#~ msgid "hash indexes are not WAL-logged and their use is discouraged" +#~ msgstr "" +#~ "хеш-индексы не записываются в журнал, использовать их не рекомендуется" + +#~ msgid "" +#~ "changing return type of function %s from \"opaque\" to \"language_handler" +#~ "\"" +#~ msgstr "" +#~ "тип возврата функции %s меняется с \"opaque\" на \"language_handler\"" + +#~ msgid "changing return type of function %s from \"opaque\" to \"trigger\"" +#~ msgstr "изменение типа возврата функции %s с \"opaque\" на \"trigger\"" + +#~ msgid "functions and operators can take at most one set argument" +#~ msgstr "функции и операторы принимают только один аргумент-множество" + +#~ msgid "IS DISTINCT FROM does not support set arguments" +#~ msgstr "IS DISTINCT FROM не поддерживает аргументы-множества" + +#~ msgid "op ANY/ALL (array) does not support set arguments" +#~ msgstr "операторы ANY/ALL (с массивом) не поддерживают аргументы-множества" + +#~ msgid "NULLIF does not support set arguments" +#~ msgstr "NULLIF не поддерживает аргументы-множества" + +#~ msgid "hostssl requires SSL to be turned on" +#~ msgstr "для использования hostssl необходимо включить SSL" + +#~ msgid "could not create %s socket: %m" +#~ msgstr "не удалось создать сокет %s: %m" + +#~ msgid "could not bind %s socket: %m" +#~ msgstr "не удалось привязаться к сокету %s: %m" + +#~ msgid "" +#~ "WHERE CURRENT OF is not supported on a view with no underlying relation" +#~ msgstr "" +#~ "WHERE CURRENT OF поддерживается только для представлений, основанных на " +#~ "таблицах" + +#~ msgid "" +#~ "WHERE CURRENT OF is not supported on a view with more than one underlying " +#~ "relation" +#~ msgstr "" +#~ "WHERE CURRENT OF не поддерживается для представлений, основанных на " +#~ "нескольких таблицах" + +#~ msgid "" +#~ "WHERE CURRENT OF is not supported on a view with grouping or aggregation" +#~ msgstr "" +#~ "WHERE CURRENT OF не поддерживается для представлений с группированием или " +#~ "агрегированием" + +#~ msgid "DEFAULT can only appear in a VALUES list within INSERT" +#~ msgstr "" +#~ "DEFAULT может присутствовать в списке VALUES только в контексте INSERT" + +#~ msgid "argument of %s must be type boolean, not type %s" +#~ msgstr "аргумент конструкции %s должен иметь логический тип, а не %s" + +#~ msgid "" +#~ "argument declared \"anyrange\" is not consistent with argument declared " +#~ "\"anyelement\"" +#~ msgstr "" +#~ "аргумент, объявленный как \"anyrange\", не согласуется с аргументом " +#~ "\"anyelement\"" + +#~ msgid "index expression cannot return a set" +#~ msgstr "индексное выражение не может возвращать множество" + +#~ msgid "transform expression must not return a set" +#~ msgstr "выражение преобразования не должно возвращать множество" + +# skip-rule: capital-letter-first +#~ msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" +#~ msgstr "" +#~ "автоочистка: найдена устаревшая врем. таблица \"%s\".\"%s\" в базе \"%s\"" + +#~ msgid "invalid socket: %s" +#~ msgstr "неверный сокет: %s" + +#~ msgid "rule \"%s\" does not exist" +#~ msgstr "правило \"%s\" не существует" + +#~ msgid "there are multiple rules named \"%s\"" +#~ msgstr "имя \"%s\" имеют несколько правил" + +#~ msgid "Specify a relation name as well as a rule name." +#~ msgstr "Дополните имя правила именем таблицы." + +#~ msgid "" +#~ "not enough shared memory for elements of data structure \"%s\" (%zu bytes " +#~ "requested)" +#~ msgstr "" +#~ "недостаточно разделяемой памяти для элементов структуры данных \"%s" +#~ "\" (запрошено байт: %zu)" + +#~ msgid "invalid input syntax for type boolean: \"%s\"" +#~ msgstr "неверное значение для логического типа: \"%s\"" + +#~ msgid "invalid input syntax for type money: \"%s\"" +#~ msgstr "неверный синтаксис для типа money: \"%s\"" + +#~ msgid "invalid input syntax for type bytea" +#~ msgstr "неверный синтаксис для типа bytea" + +#~ msgid "invalid input syntax for type real: \"%s\"" +#~ msgstr "неверный синтаксис для типа real: \"%s\"" + +#~ msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" +#~ msgstr "шаблоны формата \"TZ\"/\"tz\"/\"OF\" не поддерживаются в to_date" + +#~ msgid "value \"%s\" is out of range for type bigint" +#~ msgstr "значение \"%s\" вне диапазона для типа bigint" + +#~ msgid "invalid input syntax for type macaddr: \"%s\"" +#~ msgstr "неверный синтаксис для типа macaddr: \"%s\"" + +#~ msgid "invalid input syntax for type tinterval: \"%s\"" +#~ msgstr "неверный синтаксис для типа tinterval: \"%s\"" + +#~ msgid "invalid input syntax for type numeric: \"%s\"" +#~ msgstr "неверный синтаксис для типа numeric: \"%s\"" + +#~ msgid "invalid input syntax for type double precision: \"%s\"" +#~ msgstr "неверный синтаксис для типа double precision: \"%s\"" + +#~ msgid "value \"%s\" is out of range for type integer" +#~ msgstr "значение \"%s\" вне диапазона для типа integer" + +#~ msgid "value \"%s\" is out of range for type smallint" +#~ msgstr "значение \"%s\" вне диапазона для типа smallint" + +#~ msgid "invalid input syntax for type oid: \"%s\"" +#~ msgstr "неверный синтаксис для типа oid: \"%s\"" + +#~ msgid "invalid input syntax for type pg_lsn: \"%s\"" +#~ msgstr "неверный синтаксис для типа pg_lsn: \"%s\"" + +#~ msgid "cannot accept a value of type any" +#~ msgstr "значение типа any нельзя ввести" + +#~ msgid "cannot accept a value of type anyarray" +#~ msgstr "значение типа anyarray нельзя ввести" + +#~ msgid "cannot accept a value of type anyenum" +#~ msgstr "значение типа anyenum нельзя ввести" + +#~ msgid "cannot accept a value of type anyrange" +#~ msgstr "значение типа anyrange нельзя ввести" + +#~ msgid "cannot accept a value of type trigger" +#~ msgstr "значение типа trigger нельзя ввести" + +#~ msgid "cannot display a value of type trigger" +#~ msgstr "значение типа trigger нельзя вывести" + +#~ msgid "cannot accept a value of type event_trigger" +#~ msgstr "значение типа event_trigger нельзя ввести" + +#~ msgid "cannot display a value of type event_trigger" +#~ msgstr "значение типа event_trigger нельзя вывести" + +#~ msgid "cannot accept a value of type language_handler" +#~ msgstr "значение типа language_handler нельзя ввести" + +#~ msgid "cannot display a value of type language_handler" +#~ msgstr "значение типа language_handler нельзя вывести" + +#~ msgid "cannot accept a value of type fdw_handler" +#~ msgstr "значение типа fdw_handler нельзя ввести" + +#~ msgid "cannot display a value of type fdw_handler" +#~ msgstr "значение типа fdw_handler нельзя вывести" + +#~ msgid "cannot accept a value of type index_am_handler" +#~ msgstr "значение типа index_am_handler нельзя ввести" + +#~ msgid "cannot display a value of type index_am_handler" +#~ msgstr "значение типа index_am_handler нельзя вывести" + +#~ msgid "cannot accept a value of type tsm_handler" +#~ msgstr "значение типа tsm_handler нельзя ввести" + +#~ msgid "cannot display a value of type tsm_handler" +#~ msgstr "значение типа tsm_handler нельзя вывести" + +#~ msgid "cannot accept a value of type internal" +#~ msgstr "значение типа internal нельзя ввести" + +#~ msgid "cannot display a value of type internal" +#~ msgstr "значение типа internal нельзя вывести" + +#~ msgid "cannot accept a value of type opaque" +#~ msgstr "значение типа opaque нельзя ввести" + +#~ msgid "cannot display a value of type opaque" +#~ msgstr "значение типа opaque нельзя вывести" + +#~ msgid "cannot accept a value of type anyelement" +#~ msgstr "значение типа anyelement нельзя ввести" + +#~ msgid "cannot display a value of type anyelement" +#~ msgstr "значение типа anyelement нельзя вывести" + +#~ msgid "cannot accept a value of type anynonarray" +#~ msgstr "значение типа anynonarray нельзя ввести" + +#~ msgid "cannot display a value of type anynonarray" +#~ msgstr "значение типа anynonarray нельзя вывести" + +#~ msgid "invalid input syntax for type tid: \"%s\"" +#~ msgstr "неверный синтаксис для типа tid: \"%s\"" + +#~ msgid "invalid input syntax for type txid_snapshot: \"%s\"" +#~ msgstr "неверный синтаксис для типа txid_snapshot: \"%s\"" + +#~ msgid "invalid input syntax for uuid: \"%s\"" +#~ msgstr "неверный синтаксис для uuid: \"%s\"" + +#~ msgid "Causes subtables to be included by default in various commands." +#~ msgstr "Выбирает режим включения подчинённых таблиц по умолчанию." + +#~ msgid "syntax error: unexpected character \"%s\"" +#~ msgstr "ошибка синтаксиса: неожиданный символ \"%s\"" + +#~ msgid "Lower bound of dimension array must be one." +#~ msgstr "Нижняя граница массива размерностей должна быть равна 1." + +#~ msgid "huge TLB pages not supported on this platform" +#~ msgstr "гигантские страницы TLB на этой платформе не поддерживаются" + +#~ msgid "time zone abbreviation \"%s\" is not used in time zone \"%s\"" +#~ msgstr "" +#~ "краткое обозначение часового пояса \"%s\" отсутствует в данных часового " +#~ "пояса \"%s\"" + +#~ msgid "invalid length in external \"numeric\" value" +#~ msgstr "неверная длина во внешнем значении \"numeric\"" + +#~ msgid "Only superusers can use untrusted languages." +#~ msgstr "Использовать недоверенные языки могут только суперпользователи." + +#~ msgid "aggregate serialization data type cannot be %s" +#~ msgstr "сериализуемым типом агрегата не может быть %s" + +#~ msgid "" +#~ "aggregate serialization function must be specified when serialization " +#~ "type is specified" +#~ msgstr "" +#~ "в определении агрегата требуется функция сериализации, если указан " +#~ "сериализуемый тип" + +#~ msgid "" +#~ "aggregate deserialization function must be specified when serialization " +#~ "type is specified" +#~ msgstr "" +#~ "в определении агрегата требуется функция десериализации, если указан " +#~ "сериализуемый тип" + +#~ msgid "" +#~ "must specify serialization type when specifying serialization function" +#~ msgstr "" +#~ "при указании функции сериализации должен быть указан сериализуемый тип" + +#~ msgid "function returning set of rows cannot return null value" +#~ msgstr "функция, возвращающая множество строк, не может возвращать NULL" + +#~ msgid "unable to send tuples" +#~ msgstr "не удалось передать кортежи" + +#~ msgid "role \"%s\" is reserved" +#~ msgstr "роль \"%s\" зарезервирована" + +#~ msgid "too few arguments for format" +#~ msgstr "мало аргументов для формата" + +#~ msgid "aggregate serialization type cannot be \"%s\"" +#~ msgstr "сериализуемым типом данных агрегата не может быть \"%s\"" + +#~ msgid "Enables use of foreign keys for estimating joins." +#~ msgstr "Разрешает использовать внешние ключи для оценивания соединений." + +#~ msgid "could not create two-phase state file \"%s\": %m" +#~ msgstr "не удалось создать файл состояния 2PC \"%s\": %m" + +#~ msgid "could not seek in two-phase state file: %m" +#~ msgstr "не удалось переместиться в файле состояния 2PC: %m" + +#~ msgid "two-phase state file for transaction %u is corrupt" +#~ msgstr "в файле состояния 2PC испорчена информация о транзакции %u" + +#~ msgid "could not fsync two-phase state file \"%s\": %m" +#~ msgstr "не удалось синхронизировать с ФС файл состояния 2PC \"%s\": %m" + +#~ msgid "could not close two-phase state file \"%s\": %m" +#~ msgstr "не удалось закрыть файл состояния 2PC \"%s\": %m" + +#~ msgid "" +#~ "could not link file \"%s\" to \"%s\" (initialization of log file): %m" +#~ msgstr "" +#~ "для файла \"%s\" не удалось создать ссылку \"%s\" (при инициализации " +#~ "файла журнала): %m" + +#~ msgid "" +#~ "could not rename file \"%s\" to \"%s\" (initialization of log file): %m" +#~ msgstr "" +#~ "не удалось переименовать файл \"%s\" в \"%s\" (при инициализации файла " +#~ "журнала): %m" + +#~ msgid "ignoring \"%s\" file because no \"%s\" file exists" +#~ msgstr "файл \"%s\" игнорируется ввиду отсутствия файла \"%s\"" + +#~ msgid "must be superuser or replication role to run a backup" +#~ msgstr "" +#~ "запускать резервное копирование может только суперпользователь или роль " +#~ "репликации" + +#~ msgid "must be superuser to switch transaction log files" +#~ msgstr "" +#~ "для переключения файлов журнала транзакций нужно быть суперпользователем" + +#~ msgid "must be superuser to create a restore point" +#~ msgstr "для создания точки восстановления нужно быть суперпользователем" + +#~ msgid "must be superuser to control recovery" +#~ msgstr "для управления восстановлением нужно быть суперпользователем" + +#~ msgid "%s is already in schema \"%s\"" +#~ msgstr "объект %s уже существует в схеме \"%s\"" + +#~ msgid "function \"%s\" must return type \"event_trigger\"" +#~ msgstr "функция \"%s\" должна возвращать тип \"event_trigger\"" + +#~ msgid "function %s must return type \"fdw_handler\"" +#~ msgstr "функция %s должна возвращать тип \"fdw_handler\"" + +#~ msgid "could not reposition held cursor" +#~ msgstr "передвинуть сохранённый курсор не удалось" + +#~ msgid "function %s must return type \"language_handler\"" +#~ msgstr "функция %s должна возвращать тип \"language_handler\"" + +#~ msgid "function %s must return type \"trigger\"" +#~ msgstr "функция %s должна возвращать тип \"trigger\"" + +#~ msgid "changing return type of function %s from \"opaque\" to \"cstring\"" +#~ msgstr "изменение типа возврата функции %s с \"opaque\" на \"cstring\"" + +#~ msgid "type output function %s must return type \"cstring\"" +#~ msgstr "функция вывода типа %s должна возвращать тип \"cstring\"" + +#~ msgid "type send function %s must return type \"bytea\"" +#~ msgstr "функция отправки типа %s должна возвращать тип \"bytea\"" + +#~ msgid "typmod_in function %s must return type \"integer\"" +#~ msgstr "функция TYPMOD_IN %s должна возвращать тип \"integer\"" + +#~ msgid "Permissions should be u=rw (0600) or less." +#~ msgstr "Права должны быть u=rw (0600) или более ограниченные." + +#~ msgid "function %s must return type \"tsm_handler\"" +#~ msgstr "функция %s должна возвращать тип \"tsm_handler\"" + +#~ msgid "must be superuser to reset statistics counters" +#~ msgstr "для сброса счётчиков статистики нужно быть суперпользователем" + +#~ msgid "socket not open" +#~ msgstr "сокет не открыт" + +#~ msgid "multibyte flag character is not allowed" +#~ msgstr "многобайтные символы флагов не допускаются" + +#~ msgid "could not format \"path\" value" +#~ msgstr "не удалось отформатировать значение \"path\"" + +#~ msgid "invalid input syntax for type box: \"%s\"" +#~ msgstr "неверный синтаксис для типа box: \"%s\"" + +#~ msgid "invalid input syntax for type line: \"%s\"" +#~ msgstr "неверный синтаксис для типа line: \"%s\"" + +#~ msgid "invalid input syntax for type path: \"%s\"" +#~ msgstr "неверный синтаксис для типа path: \"%s\"" + +#~ msgid "invalid input syntax for type point: \"%s\"" +#~ msgstr "неверный синтаксис для типа point: \"%s\"" + +#~ msgid "invalid input syntax for type lseg: \"%s\"" +#~ msgstr "неверный синтаксис для типа lseg: \"%s\"" + +#~ msgid "invalid input syntax for type polygon: \"%s\"" +#~ msgstr "неверный синтаксис для типа polygon: \"%s\"" + +#~ msgid "invalid input syntax for type circle: \"%s\"" +#~ msgstr "неверный синтаксис для типа circle: \"%s\"" + +#~ msgid "could not format \"circle\" value" +#~ msgstr "не удалось отформатировать значение \"circle\"" + +#~ msgid "must be superuser to signal the postmaster" +#~ msgstr "сигнализировать процессу postmaster может только суперпользователь" + +#~ msgid "argument for function \"exp\" too big" +#~ msgstr "аргумент функции \"exp\" слишком велик" + +#~ msgid "could not convert to time zone \"%s\"" +#~ msgstr "не удалось пересчитать время в часовой пояс \"%s\"" + +#~ msgid "WAL writer sleep time between WAL flushes." +#~ msgstr "Время простоя в процессе записи WAL после сброса буферов на диск." + +#~ msgid "insufficient privilege to bypass row-level security" +#~ msgstr "недостаточно прав для обхода защиты на уровне строк" + +#~ msgid "name list must be of length at least %d" +#~ msgstr "длина списка имён должна быть не меньше %d" + +#~ msgid "arg %d: could not determine data type" +#~ msgstr "аргумент %d: не удалось определить тип данных" + +#~ msgid "mapped win32 error code %lu to %d" +#~ msgstr "код ошибки win32 %lu преобразован в %d" + +#~ msgid "unrecognized win32 error code: %lu" +#~ msgstr "нераспознанный код ошибки win32: %lu" + +#~ msgid "invalid value for recovery parameter \"recovery_target\"" +#~ msgstr "неверное значение параметра \"recovery_target\"" + +#~ msgid "redo record is at %X/%X; shutdown %s" +#~ msgstr "запись REDO по смещению %X/%X; выключение: %s" + +#~ msgid "next transaction ID: %u/%u; next OID: %u" +#~ msgstr "ID следующей транзакции: %u/%u; следующий OID: %u" + +#~ msgid "next MultiXactId: %u; next MultiXactOffset: %u" +#~ msgstr "следующий MultiXactId: %u; следующий MultiXactOffset: %u" + +#~ msgid "oldest unfrozen transaction ID: %u, in database %u" +#~ msgstr "ID старейшей незамороженной транзакции: %u, база данных %u" + +#~ msgid "oldest MultiXactId: %u, in database %u" +#~ msgstr "старейший MultiXactId: %u, база данных %u" + +#~ msgid "commit timestamp Xid oldest/newest: %u/%u" +#~ msgstr "старейшая/новейшая транзакция с меткой времени: %u/%u" + +#~ msgid "cannot change status of table %s to logged" +#~ msgstr "сделать таблицу %s журналируемой нельзя" + +#~ msgid "Table %s references unlogged table %s." +#~ msgstr "Таблица %s ссылается на нежурналируемую таблицу %s." + +#~ msgid "cannot change status of table %s to unlogged" +#~ msgstr "сделать таблицу %s нежурналируемой нельзя" + +#~ msgid "Logged table %s is referenced by table %s." +#~ msgstr "На журналируемую таблицу %s ссылается таблица %s." + +#~ msgid "received password packet" +#~ msgstr "получен пакет с паролем" + +#~ msgid "terminating connection because protocol sync was lost" +#~ msgstr "закрытие подключения из-за потери синхронизации протокола" + +#~ msgid "invalid value for parameter \"replication\"" +#~ msgstr "неверное значение параметра \"replication\"" + +#~ msgid "archive member \"%s\" too large for tar format" +#~ msgstr "архивируемый файл \"%s\" слишком велик для формата tar" + +#~ msgid "%d: %s(%s %d): excl %u shared %u haswaiters %u waiters %u rOK %d" +#~ msgstr "" +#~ "%d: %s(%s %d): искл. %u разделяем. %u есть_ждущие %u ждут %u осв. %d" + +#~ msgid "%s(%s %d): %s" +#~ msgstr "%s(%s %d): %s" + +#~ msgid "arg %d: key cannot be null" +#~ msgstr "аргумент %d: ключ не может быть NULL" + +#~ msgid "" +#~ "\"%s\" is not a table, materialized view, composite type, or foreign table" +#~ msgstr "" +#~ "\"%s\" - это не таблица, материализованное представление, составной тип " +#~ "или сторонняя таблица" + +#~ msgid "could not stat \"%s\": %m" +#~ msgstr "не удалось получить информацию о \"%s\": %m" + +#~ msgid "new row violates WITH CHECK OPTION for \"%s\"" +#~ msgstr "новая строка нарушает ограничение WITH CHECK OPTION для \"%s\"" + +#~ msgid "no free replication origin oid could be found" +#~ msgstr "найти свободный oid для источника репликации не удалось" + +#~ msgid "key value must be scalar, not array, composite or json" +#~ msgstr "" +#~ "значением ключа должен быть скаляр, не массив, составное значение или json" + +#~ msgid "oldest MultiXactId member offset unknown" +#~ msgstr "смещение членов старейшей мультитранзакции неизвестно" + +#~ msgid "" +#~ "hot standby is not possible because it requires \"%s\" to be same on " +#~ "master and standby (master has \"%s\", standby has \"%s\")" +#~ msgstr "" +#~ "горячий резерв невозможен, так как значения параметра \"%s\" на главном и " +#~ "резервном серверах различаются (на главном: \"%s\", на резервном: \"%s\")" + +#~ msgid "parallel option \"%s\" not recognized" +#~ msgstr "параметр \"%s\" указания PARALLEL не распознан" + +#~ msgid "%d: %s(%s): excl %u shared %u haswaiters %u waiters %u rOK %d" +#~ msgstr "%d: %s(%s): искл. %u разделяем. %u есть_ждущие %u ждут %u осв. %d" + +#~ msgid "%s(%s): %s" +#~ msgstr "%s(%s): %s" + +#~ msgid "" +#~ "brin_summarize_new_values() cannot run in a transaction that has already " +#~ "obtained a snapshot" +#~ msgstr "" +#~ "brin_summarize_new_values() не может работать в транзакции, в которой уже " +#~ "получен снимок" + +#~ msgid "Could not rename \"%s\" to \"%s\": %m." +#~ msgstr "Не удалось переименовать файл \"%s\" в \"%s\": %m." + +#~ msgid "SSL failure during renegotiation start" +#~ msgstr "сбой SSL при попытке переподключения" + +#~ msgid "SSL failed to renegotiate connection before limit expired" +#~ msgstr "ошибка при согласовании SSL-соединения (превышен лимит)" + +#~ msgid "" +#~ "Set the amount of traffic to send and receive before renegotiating the " +#~ "encryption keys." +#~ msgstr "" +#~ "Ограничивает объём трафика, передаваемого и принимаемого до повторного " +#~ "согласования ключей шифрования." + +#~ msgid "invalid sample size" +#~ msgstr "неверный размер выборки" + +#~ msgid "Sample size must be numeric value between 0 and 100 (inclusive)." +#~ msgstr "Размер выборки должен задаваться числом от 0 до 100 (включительно)." + +#~ msgid "REPEATABLE clause must be NOT NULL numeric value" +#~ msgstr "для REPEATABLE требуется числовое значение NOT NULL" + +#~ msgid "wrong parameter %d for tablesample method \"%s\"" +#~ msgstr "неверный параметр %d для метода получения выборки \"%s\"" + +#~ msgid "Expected type %s got %s." +#~ msgstr "Ожидался тип: %s, получено: %s." + +#~ msgid "cache lookup failed for tablesample method %u" +#~ msgstr "ошибка поиска в кеше для метода получения выборки %u" + +#~ msgid "invalid xlog switch record at %X/%X" +#~ msgstr "неверная запись переключения xlog по смещению %X/%X" + +#~ msgid "invalid backup block size in record at %X/%X" +#~ msgstr "неверный размер блока копии в позиции %X/%X" + +#~ msgid "incorrect hole size in record at %X/%X" +#~ msgstr "неправильный размер пропуска в записи по смещению %X/%X" + +#~ msgid "incorrect total length in record at %X/%X" +#~ msgstr "некорректная общая длина в записи по смещению %X/%X" + +#~ msgid "=> is deprecated as an operator name" +#~ msgstr "=> как имя оператора считается устаревшим" + +#~ msgid "" +#~ "This name may be disallowed altogether in future versions of PostgreSQL." +#~ msgstr "Это имя может быть вовсе запрещено в будущих версиях PostgreSQL." + +#~ msgid "Specify a USING expression to perform the conversion." +#~ msgstr "Укажите выражение USING, чтобы выполнить преобразование." + +#~ msgid "" +#~ "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +#~ "pages: %d removed, %d remain\n" +#~ "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n" +#~ "buffer usage: %d hits, %d misses, %d dirtied\n" +#~ "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +#~ "system usage: %s" +#~ msgstr "" +#~ "автоматическая очистка таблицы \"%s.%s.%s\": сканирований индекса: %d\n" +#~ "страниц удалено: %d, осталось: %d\n" +#~ "кортежей удалено: %.0f, осталось: %.0f, мёртвых (но пока неудаляемых): " +#~ "%.0f\n" +#~ "использование буфера: попаданий: %d, промахов: %d, загрязнено: %d\n" +#~ "средняя скорость чтения: %.3f МБ/сек, средняя скорость записи: %.3f МБ/" +#~ "сек\n" +#~ "нагрузка системы: %s" + +#~ msgid "" +#~ "%.0f dead row versions cannot be removed yet.\n" +#~ "There were %.0f unused item pointers.\n" +#~ "%u pages are entirely empty.\n" +#~ "%s." +#~ msgstr "" +#~ "В данный момент нельзя удалить версий \"мёртвых\" строк: %.0f.\n" +#~ "Неиспользованных указателей: %.0f.\n" +#~ "Полностью пустых страниц: %u.\n" +#~ "%s." + +#~ msgid "SSL handshake failure on renegotiation, retrying" +#~ msgstr "" +#~ "сбой согласования SSL при переподключении, следует повторная попытка" + +#~ msgid "could not complete SSL handshake on renegotiation, too many failures" +#~ msgstr "" +#~ "не удалось выполнить согласование SSL при переподключении (слишком много " +#~ "ошибок)" + +#~ msgid "could not set socket to blocking mode: %m" +#~ msgstr "не удалось перевести сокет в блокирующий режим: %m" + +#~ msgid "%s: setsysinfo failed: %s\n" +#~ msgstr "%s: ошибка setsysinfo: %s\n" + +#~ msgid " -A 1|0 enable/disable run-time assert checking\n" +#~ msgstr "" +#~ " -A 1|0 включить/выключить проверки истинности во время " +#~ "выполнения\n" + +#~ msgid "subquery must return a column" +#~ msgstr "подзапрос должен вернуть столбец" + +#~ msgid "" +#~ "Consider increasing the configuration parameter \"checkpoint_segments\"." +#~ msgstr "Возможно, стоит увеличить параметр \"checkpoint_segments\"." + +#~ msgid "" +#~ "WAL archival (archive_mode=on) requires wal_level \"archive\", " +#~ "\"hot_standby\", or \"logical\"" +#~ msgstr "" +#~ "Для архивации WAL (archive_mode=on) wal_level должен быть \"archive\", " +#~ "\"hot_standby\" или \"logical\"" + +#~ msgid "postmaster became multithreaded" +#~ msgstr "процесс postmaster стал многопоточным" + +#~ msgid "could not determine input data types" +#~ msgstr "не удалось определить типы входных данных" + +#~ msgid "neither input type is an array" +#~ msgstr "входной тип так же не является массивом" + +#~ msgid "unexpected \"=\"" +#~ msgstr "неожиданный знак \"=\"" + +#~ msgid "invalid symbol" +#~ msgstr "неверный символ" + +#~ msgid "" +#~ "must be superuser or have the same role to cancel queries running in " +#~ "other server processes" +#~ msgstr "" +#~ "отменять запросы в других серверных процессах может только " +#~ "суперпользователь или пользователь той же роли" + +#~ msgid "" +#~ "must be superuser or have the same role to terminate other server " +#~ "processes" +#~ msgstr "" +#~ "завершать другие серверные процессы может только суперпользователь или " +#~ "пользователь той же роли" + +#~ msgid "cannot accept a value of type pg_node_tree" +#~ msgstr "значение типа pg_node_tree нельзя ввести" + +#~ msgid "Turns on various assertion checks." +#~ msgstr "Включает различные проверки истинности." + +#~ msgid "This is a debugging aid." +#~ msgstr "Полезно при отладке." + +#~ msgid "This parameter doesn't do anything." +#~ msgstr "Этот параметр ничего не делает." + +#~ msgid "" +#~ "It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-" +#~ "vintage clients." +#~ msgstr "" +#~ "Он сохранён только для того, чтобы не обидеть винтажных клиентов 7.3-, " +#~ "пожелавших SET AUTOCOMMIT TO ON." + +#~ msgid "" +#~ "Sets the maximum distance in log segments between automatic WAL " +#~ "checkpoints." +#~ msgstr "" +#~ "Задаёт максимальное расстояние в сегментах журнала между автоматическими " +#~ "контрольными точками WAL." + +#~ msgid "assertion checking is not supported by this build" +#~ msgstr "в данной сборке не поддерживаются проверки истинности" + +#~ msgid "interval precision specified twice" +#~ msgstr "точность интервала указана дважды" + +#~ msgid "JSON does not support infinite date values." +#~ msgstr "JSON не поддерживает бесконечность в датах." + +#~ msgid "JSON does not support infinite timestamp values." +#~ msgstr "JSON не поддерживает бесконечность в timestamp." + +#~ msgid "missing assignment operator" +#~ msgstr "отсутствует оператор присваивания" + +#~ msgid "failed to look up local user id %ld: %s" +#~ msgstr "" +#~ "распознать идентификатор локального пользователя (%ld) не удалось: %s" + +#~ msgid "cannot use physical replication slot created for logical decoding" +#~ msgstr "" +#~ "для логического декодирования нельзя использовать созданный физический " +#~ "слот репликации" + +#~ msgid "" +#~ "incomplete read from reorderbuffer spill file: read %d instead of %u bytes" +#~ msgstr "" +#~ "неполное чтение из файла подкачки буфера пересортировки (прочитано байт: " +#~ "%d, требовалось: %u)" + +#~ msgid "" +#~ "skipping snapshot at %X/%X while building logical decoding snapshot, xmin " +#~ "horizon too low" +#~ msgstr "" +#~ "при построении снимка логического декодирования пропускается снимок в %X/" +#~ "%X -- слишком низкий горизонт xmin" + +#~ msgid "initial xmin horizon of %u vs the snapshot's %u" +#~ msgstr "начальный горизонт xmin: %u, xid в снимке: %u" + +#~ msgid "running xacts with xcnt == 0" +#~ msgstr "число активных транзакций равно 0" + +#~ msgid "found initial snapshot in snapbuild file" +#~ msgstr "в файле snapbuild найден начальный снимок" + +#~ msgid "performing replication slot checkpoint" +#~ msgstr "сброс слотов репликации на диск" + +#~ msgid "failed to write to \"%s\" file" +#~ msgstr "записать в файл \"%s\" не удалось" + +#~ msgid "failed to open auto conf temp file \"%s\": %m " +#~ msgstr "не удалось открыть временный файл auto.conf \"%s\": %m" + +#~ msgid "failed to open auto conf file \"%s\": %m " +#~ msgstr "не удалось открыть файл auto.conf \"%s\": %m" + +#~ msgid "invalid recovery_target parameter" +#~ msgstr "нераспознанный параметр recovery_target" + +#~ msgid "recovery_min_apply_delay = '%s'" +#~ msgstr "recovery_min_apply_delay = '%s'" + +#~ msgid "unable to complete SSL handshake" +#~ msgstr "завершить согласование SSL не удалось" + +#~ msgid "output plugin cannot produce binary output" +#~ msgstr "модуль вывода не может выдавать двоичные данные" + +#~ msgid "wrong affix file format for flag" +#~ msgstr "неправильный формат файла аффиксов при разборе флага" + +#~ msgid "key value must not be empty" +#~ msgstr "значение ключа не может быть пустым" + +#~ msgid "Sets the number of locks used for concurrent xlog insertions." +#~ msgstr "" +#~ "Задаёт число блокировок, используемых для параллельных добавлений в xlog." + +#~ msgid "" +#~ "time zone offset %d is not a multiple of 900 sec (15 min) in time zone " +#~ "file \"%s\", line %d" +#~ msgstr "" +#~ "смещение часового пояса %d не кратно 15 мин. (900 сек.) (файл часовых " +#~ "поясов \"%s\", строка %d)" + +#~ msgid "could not seek to the end of file \"%s\": %m" +#~ msgstr "не удалось перейти к концу файла \"%s\": %m" + +#~ msgid "cannot call %s with null path elements" +#~ msgstr "вызывать %s с элементами пути, равными NULL, нельзя" + +#~ msgid "cannot call %s with empty path elements" +#~ msgstr "вызывать %s с пустыми элементами пути нельзя" + +#~ msgid "cannot extract array element from a non-array" +#~ msgstr "извлечь элемент массива из не массива нельзя" + +#~ msgid "cannot extract field from a non-object" +#~ msgstr "извлечь поле из не объекта нельзя" + +#~ msgid "cannot extract element from a scalar" +#~ msgstr "извлечь элемент из скаляра нельзя" + +#~ msgid "could not rename file \"%s\" to \"%s\" : %m" +#~ msgstr "не удалось переименовать файл \"%s\" в \"%s\": %m" + +#~ msgid "%s \"%s\": return code %d" +#~ msgstr "%s \"%s\": код возврата %d" + +#~ msgid "invalid input syntax for transaction log location: \"%s\"" +#~ msgstr "" +#~ "неверный синтаксис строки, задающей положение в журнале транзакций: \"%s\"" + +#~ msgid "trigger \"%s\" for table \"%s\" does not exist, skipping" +#~ msgstr "триггер \"%s\" для таблицы \"%s\" не существует, пропускается" + +#~ msgid "Kerberos 5 authentication failed for user \"%s\"" +#~ msgstr "пользователь \"%s\" не прошёл проверку подлинности (Kerberos 5)" + +#~ msgid "Kerberos initialization returned error %d" +#~ msgstr "ошибка при инициализации Kerberos: %d" + +#~ msgid "Kerberos keytab resolving returned error %d" +#~ msgstr "ошибка при разрешении имени таблицы ключей Kerberos: %d" + +#~ msgid "Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d" +#~ msgstr "ошибка в функции Kerberos sname_to_principal(\"%s\", \"%s\"): %d" + +#~ msgid "Kerberos recvauth returned error %d" +#~ msgstr "ошибка в функции Kerberos recvauth: %d" + +#~ msgid "Kerberos unparse_name returned error %d" +#~ msgstr "ошибка в функции Kerberos unparse_name: %d" + +#~ msgid "local user with ID %d does not exist" +#~ msgstr "локальный пользователь с ID %d не существует" + +#~ msgid "SSL renegotiation failure" +#~ msgstr "ошибка повторного согласования SSL" + +#~ msgid "krb5 authentication is not supported on local sockets" +#~ msgstr "проверка подлинности krb5 для локальных сокетов не поддерживается" + +#~ msgid "%s: invalid effective UID: %d\n" +#~ msgstr "%s: неверный эффективный UID: %d\n" + +#~ msgid "%s: could not determine user name (GetUserName failed)\n" +#~ msgstr "%s: не удалось определить имя пользователя (ошибка в GetUserName)\n" + +#~ msgid "Expected 1 tuple with 3 fields, got %d tuples with %d fields." +#~ msgstr "" +#~ "Ожидался 1 кортеж с 3 полями, однако получено кортежей: %d, полей: %d." + +#~ msgid "Security-barrier views are not automatically updatable." +#~ msgstr "" +#~ "Представления с барьерами безопасности не обновляются автоматически." + +#~ msgid "" +#~ "Views that return the same column more than once are not automatically " +#~ "updatable." +#~ msgstr "" +#~ "Представления, возвращающие один столбец несколько раз, не обновляются " +#~ "автоматически." + +#~ msgid "cannot call json_object_keys on an array" +#~ msgstr "вызывать json_object_keys с массивом нельзя" + +#~ msgid "cannot call json_array_elements on a non-array" +#~ msgstr "json_array_elements можно вызывать только для массива" + +#~ msgid "cannot call json_array_elements on a scalar" +#~ msgstr "вызывать json_array_elements со скаляром нельзя" + +#~ msgid "first argument of json_populate_record must be a row type" +#~ msgstr "первым аргументом json_populate_record должен быть кортеж" + +#~ msgid "first argument of json_populate_recordset must be a row type" +#~ msgstr "первым аргументом json_populate_recordset должен быть кортеж" + +#~ msgid "cannot call json_populate_recordset on an object" +#~ msgstr "вызывать json_populate_recordset с объектом нельзя" + +#~ msgid "cannot call json_populate_recordset with nested objects" +#~ msgstr "вызывать json_populate_recordset с вложенными объектами нельзя" + +#~ msgid "must call json_populate_recordset on an array of objects" +#~ msgstr "json_populate_recordset нужно вызывать с массивом объектов" + +#~ msgid "cannot call json_populate_recordset with nested arrays" +#~ msgstr "вызывать json_populate_recordset с вложенными массивами нельзя" + +#~ msgid "cannot call json_populate_recordset on a scalar" +#~ msgstr "вызывать json_populate_recordset со скаляром нельзя" + +#~ msgid "cannot call json_populate_recordset on a nested object" +#~ msgstr "вызывать json_populate_recordset с вложенным объектом нельзя" + +#~ msgid "No description available." +#~ msgstr "Без описания." + +#~ msgid "Sets the name of the Kerberos service." +#~ msgstr "Задаёт название службы Kerberos." + +#~ msgid "Perhaps out of disk space?" +#~ msgstr "Возможно нет места на диске?" + +#~ msgid "cannot override frame clause of window \"%s\"" +#~ msgstr "переопределить описание рамки для окна \"%s\" нельзя" + +#~ msgid "window functions cannot use named arguments" +#~ msgstr "у оконных функций не может быть именованных аргументов" + +#~ msgid "invalid list syntax for \"unix_socket_directories\"" +#~ msgstr "неверный формат списка для \"unix_socket_directories\"" + +#~ msgid "" +#~ "To make the view insertable, provide an unconditional ON INSERT DO " +#~ "INSTEAD rule or an INSTEAD OF INSERT trigger." +#~ msgstr "" +#~ "Чтобы представление допускало добавление данных, определите безусловное " +#~ "правило ON INSERT DO INSTEAD или триггер INSTEAD OF INSERT." + +#~ msgid "" +#~ "To make the view updatable, provide an unconditional ON DELETE DO INSTEAD " +#~ "rule or an INSTEAD OF DELETE trigger." +#~ msgstr "" +#~ "Чтобы представление допускало удаление данных, определите безусловное " +#~ "правило ON DELETE DO INSTEAD или триггер INSTEAD OF DELETE." + +#~ msgid "" +#~ "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +#~ msgstr "" +#~ "база данных \"%s\" должна быть очищена, прежде чем будут использованы " +#~ "оставшиеся MultiXactId (%u)" + +#~ msgid "could not open xlog file \"%s\": %m" +#~ msgstr "не удалось открыть файл журнала \"%s\": %m" + +#~ msgid "\"%s\" is not a table, view, composite type, or foreign table" +#~ msgstr "" +#~ "\"%s\" - это не таблица, представление, составной тип или сторонняя " +#~ "таблица" + +#~ msgid "SELECT FOR UPDATE/SHARE cannot be applied to VALUES" +#~ msgstr "SELECT FOR UPDATE/SHARE нельзя применять к VALUES" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT" +#~ msgstr "SELECT FOR UPDATE/SHARE не допускается с UNION/INTERSECT/EXCEPT" + +#~ msgid "row-level locks are not allowed with window functions" +#~ msgstr "блокировки на уровне строк несовместимы с оконными функциями" + +#~ msgid "could not seek in log segment %s, to offset %u: %m" +#~ msgstr "не удалось переместиться в сегменте журнала %s к смещению %u: %m" + +#~ msgid "" +#~ "Unicode escape for code points higher than U+007F not permitted in non-" +#~ "UTF8 encoding" +#~ msgstr "" +#~ "Спецкоды Unicode для значений выше U+007F допускаются только с кодировкой " +#~ "UTF8" + +#~ msgid "arguments of row IN must all be row expressions" +#~ msgstr "все аргументы IN со строкой должны быть строковыми выражениями" + +#~ msgid "Use ALTER FOREIGN TABLE instead." +#~ msgstr "Изменить её можно с помощью ALTER FOREIGN TABLE." + +#~ msgid "" +#~ "automatic vacuum of table \"%s.%s.%s\": could not (re)acquire exclusive " +#~ "lock for truncate scan" +#~ msgstr "" +#~ "автоматическая очистка таблицы \"%s.%s.%s\": получить исключительную " +#~ "блокировку для сканирования отсекаемых страниц не удалось" + +#~ msgid "received fast promote request" +#~ msgstr "получен запрос быстрого повышения статуса" + +#~ msgid "argument number is out of range" +#~ msgstr "номер аргумента вне диапазона" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "не удалось перейти в каталог \"%s\"" + +#~ msgid "unlogged GiST indexes are not supported" +#~ msgstr "GiST-индексы без журналирования не поддерживаются" + +#~ msgid "could not open file \"%s\" (log file %u, segment %u): %m" +#~ msgstr "не удалось открыть файл \"%s\" (файл журнала: %u, сегмент: %u): %m" + +#~ msgid "there is no contrecord flag in log file %u, segment %u, offset %u" +#~ msgstr "" +#~ "отсутствует флаг contrecord в файле журнала %u, сегмент %u, смещение %u" + +#~ msgid "invalid contrecord length %u in log file %u, segment %u, offset %u" +#~ msgstr "" +#~ "неверная длина продолжения записи %u в файле журнала %u, сегмент %u, " +#~ "смещение %u" + +#~ msgid "Incorrect XLOG_SEG_SIZE in page header." +#~ msgstr "Неверный XLOG_SEG_SIZE в заголовке страницы." + +#~ msgid "Incorrect XLOG_BLCKSZ in page header." +#~ msgstr "Неверный XLOG_BLCKSZ в заголовке страницы." + +#~ msgid "xrecoff \"%X\" is out of valid range, 0..%X" +#~ msgstr "xrecoff \"%X\" вне диапазона 0..%X" + +#~ msgid "uncataloged table %s" +#~ msgstr "таблица не в каталоге %s" + +#~ msgid "cannot use window function in default expression" +#~ msgstr "в выражении по умолчанию нельзя использовать оконные функции" + +#~ msgid "cannot use window function in check constraint" +#~ msgstr "в ограничении-проверке нельзя использовать оконные функции" + +#~ msgid "" +#~ "A function returning ANYRANGE must have at least one ANYRANGE argument." +#~ msgstr "" +#~ "Функция, возвращающая ANYRANGE, должна иметь минимум один аргумент " +#~ "ANYRANGE." + +#~ msgid "%s already exists in schema \"%s\"" +#~ msgstr "\"%s\" уже существует в схеме \"%s\"" + +#~ msgid "CREATE TABLE AS specifies too many column names" +#~ msgstr "в CREATE TABLE AS указаны лишние имена столбцов" + +#~ msgid "cannot use subquery in parameter default value" +#~ msgstr "в значениях параметров по умолчанию нельзя использовать подзапросы" + +#~ msgid "cannot use aggregate function in parameter default value" +#~ msgstr "" +#~ "в значениях параметров по умолчанию нельзя использовать агрегатные функции" + +#~ msgid "cannot use window function in parameter default value" +#~ msgstr "" +#~ "в значениях параметров по умолчанию нельзя использовать оконные функции" + +#~ msgid "Use ALTER AGGREGATE to rename aggregate functions." +#~ msgstr "Используйте ALTER AGGREGATE для переименования агрегатных функций." + +#~ msgid "Use ALTER AGGREGATE to change owner of aggregate functions." +#~ msgstr "Используйте ALTER AGGREGATE для смены владельца агрегатных функций." + +#~ msgid "function \"%s\" already exists in schema \"%s\"" +#~ msgstr "функция %s уже существует в схеме \"%s\"" + +#~ msgid "cannot use aggregate in index predicate" +#~ msgstr "в предикате индекса нельзя использовать агрегатные функции" + +#~ msgid "cannot use window function in EXECUTE parameter" +#~ msgstr "в качестве параметра EXECUTE нельзя использовать оконную функцию" + +#~ msgid "constraints on foreign tables are not supported" +#~ msgstr "ограничения для внешних таблиц не поддерживаются" + +#~ msgid "cannot use window function in transform expression" +#~ msgstr "нельзя использовать оконную функцию в выражении преобразования" + +#~ msgid "cannot use window function in trigger WHEN condition" +#~ msgstr "в условии WHEN для триггера нельзя использоваться оконные функции" + +#~ msgid "must be superuser to rename text search parsers" +#~ msgstr "" +#~ "для переименования анализаторов текстового поиска нужно быть " +#~ "суперпользователем" + +#~ msgid "must be superuser to rename text search templates" +#~ msgstr "" +#~ "для переименования шаблонов текстового поиска нужно быть " +#~ "суперпользователем" + +#~ msgid "" +#~ "LDAP search failed for filter \"%s\" on server \"%s\": user is not unique " +#~ "(%ld matches)" +#~ msgstr "" +#~ "ошибка при LDAP-поиске по фильтру \"%s\" на сервере \"%s\": пользователь " +#~ "не уникален (результатов: %ld)" + +#~ msgid "VALUES must not contain table references" +#~ msgstr "в списке VALUES нельзя ссылаться на таблицы" + +#~ msgid "VALUES must not contain OLD or NEW references" +#~ msgstr "в списке VALUES нельзя ссылаться на OLD или NEW" + +#~ msgid "Use SELECT ... UNION ALL ... instead." +#~ msgstr "Воспользуйтесь конструкцией SELECT ... UNION ALL ..." + +#~ msgid "cannot use aggregate function in VALUES" +#~ msgstr "в списке VALUES нельзя использовать агрегатные функции" + +#~ msgid "cannot use window function in VALUES" +#~ msgstr "в списке VALUES нельзя использовать оконные функции" + +#~ msgid "cannot use aggregate function in UPDATE" +#~ msgstr "в UPDATE нельзя использовать агрегатные функции" + +#~ msgid "cannot use window function in UPDATE" +#~ msgstr "в UPDATE нельзя использовать оконные функции" + +#~ msgid "cannot use aggregate function in RETURNING" +#~ msgstr "в RETURNING нельзя использовать агрегатные функции" + +#~ msgid "cannot use window function in RETURNING" +#~ msgstr "в RETURNING нельзя использовать оконные функции" + +#~ msgid "RETURNING cannot contain references to other relations" +#~ msgstr "в RETURNING нельзя ссылаться на другие отношения" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with GROUP BY clause" +#~ msgstr "SELECT FOR UPDATE/SHARE несовместим с предложением GROUP BY" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with HAVING clause" +#~ msgstr "SELECT FOR UPDATE/SHARE несовместим с предложением HAVING" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with window functions" +#~ msgstr "SELECT FOR UPDATE/SHARE несовместим с оконными функциями" + +#~ msgid "SELECT FOR UPDATE/SHARE cannot be used with foreign table \"%s\"" +#~ msgstr "" +#~ "в SELECT FOR UPDATE/SHARE нельзя использовать стороннюю таблицу \"%s\"" + +#~ msgid "aggregates not allowed in WHERE clause" +#~ msgstr "в предложении WHERE агрегатные функции недопустимы" + +#~ msgid "window functions not allowed in GROUP BY clause" +#~ msgstr "в предложении GROUP BY оконные функции недопустимы" + +#~ msgid "JOIN/ON clause refers to \"%s\", which is not part of JOIN" +#~ msgstr "\"%s\" фигурирует в предложении JOIN/ON, но отсутствует в JOIN" + +#~ msgid "subquery in FROM cannot refer to other relations of same query level" +#~ msgstr "" +#~ "подзапрос во FROM не может ссылаться на другие отношения на том же уровне " +#~ "запроса" + +#~ msgid "" +#~ "function expression in FROM cannot refer to other relations of same query " +#~ "level" +#~ msgstr "" +#~ "в выражении с функцией во FROM нельзя ссылаться на другие отношения на " +#~ "том же уровне запроса" + +#~ msgid "cannot use window function in function expression in FROM" +#~ msgstr "в выражении с функцией во FROM нельзя использовать оконные функции" + +#~ msgid "argument of %s must not contain aggregate functions" +#~ msgstr "аргумент %s не может содержать агрегатные функции" + +#~ msgid "argument of %s must not contain window functions" +#~ msgstr "аргумент %s не может содержать оконные функции" + +#~ msgid "cannot use aggregate function in rule WHERE condition" +#~ msgstr "в условиях WHERE для правил нельзя использовать агрегатные функции" + +#~ msgid "cannot use window function in rule WHERE condition" +#~ msgstr "в условиях WHERE для правил нельзя использовать оконные функции" + +#~ msgid "" +#~ "This error usually means that PostgreSQL's request for a shared memory " +#~ "segment exceeded your kernel's SHMMAX parameter. You can either reduce " +#~ "the request size or reconfigure the kernel with larger SHMMAX. To reduce " +#~ "the request size (currently %lu bytes), reduce PostgreSQL's shared memory " +#~ "usage, perhaps by reducing shared_buffers or max_connections.\n" +#~ "If the request size is already small, it's possible that it is less than " +#~ "your kernel's SHMMIN parameter, in which case raising the request size or " +#~ "reconfiguring SHMMIN is called for.\n" +#~ "The PostgreSQL documentation contains more information about shared " +#~ "memory configuration." +#~ msgstr "" +#~ "Эта ошибка обычно возникает, когда PostgreSQL запрашивает сегмент " +#~ "разделяемой памяти, превышая предел SHMMAX, заданный в ядре. Вы можете " +#~ "либо уменьшить запрашиваемый размер, либо увеличить SHMMAX в конфигурации " +#~ "ядра. Для уменьшения запроса (текущий размер: %lu Б) можно снизить " +#~ "использование разделяемой памяти, возможно, уменьшив shared_buffers или " +#~ "max_connections.\n" +#~ "Если запрашиваемый размер и без того мал, возможно также, что он меньше " +#~ "параметра ядра SHMMIN - в этом случае поможет увеличение запроса или " +#~ "переконфигурация SHMMIN.\n" +#~ "Подробная информация о настройке разделяемой памяти содержится в " +#~ "документации PostgreSQL." + +#~ msgid "" +#~ "terminating all walsender processes to force cascaded standby(s) to " +#~ "update timeline and reconnect" +#~ msgstr "" +#~ "завершение всех процессов передачи журнала для принуждения связанных с " +#~ "ними дежурных серверов обновить линию времени и переподключиться" + +#~ msgid "shutdown requested, aborting active base backup" +#~ msgstr "" +#~ "запрошено выключение, активный процесс базового резервного копирования " +#~ "прерывается" + +#~ msgid "streaming replication successfully connected to primary" +#~ msgstr "приёмник потоковой репликации успешно подключен к главному серверу" + +#~ msgid "invalid standby handshake message type %d" +#~ msgstr "неверный тип сообщения согласования: %d" + +#~ msgid "" +#~ "terminating walsender process to force cascaded standby to update " +#~ "timeline and reconnect" +#~ msgstr "" +#~ "завершение процесса передачи журнала для принуждения связанного с ним " +#~ "дежурного сервера обновить линию времени и переподключиться" + +#~ msgid "invalid standby query string: %s" +#~ msgstr "неверная строка запроса резервного сервера: %s" + +#~ msgid "large object %u was not opened for writing" +#~ msgstr "большой объект %u не был открыт для записи" + +#~ msgid "large object %u was already dropped" +#~ msgstr "большой объект %u уже удалён" + +#~ msgid "Not enough memory for reassigning the prepared transaction's locks." +#~ msgstr "" +#~ "Недостаточно памяти для переназначения блокировок подготовленных " +#~ "транзакций." + +#~ msgid "\"interval\" time zone \"%s\" not valid" +#~ msgstr "\"интервал\" содержит неверный часовой пояс \"%s\"" + +#~ msgid "inconsistent use of year %04d and \"BC\"" +#~ msgstr "несогласованное использование в годе %04d и \"BC\"" + +#~ msgid "No rows were found in \"%s\"." +#~ msgstr "Таблица \"%s\" не содержит строк." + +#~ msgid "index \"%s\" is not ready" +#~ msgstr "индекс \"%s\" не готов" + +#~ msgid "You can cancel your own processes with pg_cancel_backend()." +#~ msgstr "Свои процессы можно отменить с помощью pg_cancel_backend()." + +#~ msgid "" +#~ "Sets the application name used to identifyPostgreSQL messages in the " +#~ "event log." +#~ msgstr "" +#~ "Задаёт имя приложения для идентификации сообщений PostgreSQL в журнале " +#~ "событий." + +#~ msgid "poll() failed in statistics collector: %m" +#~ msgstr "сбой poll() в сборщике статистики: %m" + +#~ msgid "select() failed in logger process: %m" +#~ msgstr "сбой select() в процессе протоколирования: %m" + +#~ msgid "%s: could not open log file \"%s/%s\": %s\n" +#~ msgstr "%s: не удалось открыть файл протокола \"%s/%s\": %s\n" + +#~ msgid "%s: could not fork background process: %s\n" +#~ msgstr "%s: не удалось породить фоновый процесс: %s\n" + +#~ msgid "%s: could not dissociate from controlling TTY: %s\n" +#~ msgstr "%s: не удалось отключиться от управления TTY: %s\n" + +#~ msgid "Runs the server silently." +#~ msgstr "Включает скрытый режим сервера." + +#~ msgid "" +#~ "If this parameter is set, the server will automatically run in the " +#~ "background and any controlling terminals are dissociated." +#~ msgstr "" +#~ "При включении этого параметра сервер автоматически переходит в фоновый " +#~ "режим и отличается от всех управляющих терминалов." + +#~ msgid "WAL sender sleep time between WAL replications." +#~ msgstr "Время простоя в процессе передачи WAL после репликации." + +#~ msgid "Sets the list of known custom variable classes." +#~ msgstr "Задаёт список известных классов дополнительных переменных." + +#~ msgid "foreign key constraint \"%s\" of relation \"%s\" does not exist" +#~ msgstr "ограничение внешнего ключа \"%s\" в таблице\"%s\" не существует" + +#~ msgid "removing built-in function \"%s\"" +#~ msgstr "удаление встроенной функции \"%s\"" + +#~ msgid "permission denied to drop foreign-data wrapper \"%s\"" +#~ msgstr "нет прав на удаление обёртки сторонних данных \"%s\"" + +#~ msgid "Must be superuser to drop a foreign-data wrapper." +#~ msgstr "" +#~ "Для удаления обёртки сторонних данных нужно быть суперпользователем." + +#~ msgid "must be superuser to drop text search parsers" +#~ msgstr "" +#~ "для удаления анализатора текстового поиска нужно быть суперпользователем" + +#~ msgid "must be superuser to drop text search templates" +#~ msgstr "" +#~ "для удаления шаблонов текстового поиска нужно быть суперпользователем" + +#~ msgid "" +#~ "recovery is still in progress, can't accept WAL streaming connections" +#~ msgstr "" +#~ "восстановление ещё не завершено, подключения для передачи WAL не " +#~ "принимаются" + +#~ msgid "standby connections not allowed because wal_level=minimal" +#~ msgstr "" +#~ "подключения резервных серверов не разрешены, так как wal_level=minimal" + +#~ msgid "could not open directory \"pg_tblspc\": %m" +#~ msgstr "не удалось открыть каталог \"pg_tblspc\": %m" + +#~ msgid "could not access root certificate file \"%s\": %m" +#~ msgstr "не удалось обратиться к файлу корневых сертификатов \"%s\": %m" + +#~ msgid "SSL certificate revocation list file \"%s\" not found, skipping: %s" +#~ msgstr "" +#~ "файл со списком отзыва сертификатов SSL \"%s\" не найден, пропускается: %s" + +#~ msgid "Certificates will not be checked against revocation list." +#~ msgstr "Сертификаты не будут проверяться по списку отзыва." + +#~ msgid "missing or erroneous pg_hba.conf file" +#~ msgstr "файл pg_hba.conf отсутствует или испорчен" + +#~ msgid "See server log for details." +#~ msgstr "Смотрите подробности в протоколе сервера." + +#~ msgid "Make sure the root.crt file is present and readable." +#~ msgstr "Убедитесь в наличии и доступности файла root.crt." + +#~ msgid "CREATE TABLE AS cannot specify INTO" +#~ msgstr "в CREATE TABLE AS нельзя указать INTO" + +#~ msgid "column name list not allowed in CREATE TABLE / AS EXECUTE" +#~ msgstr "в CREATE TABLE / AS EXECUTE нельзя указать список имён столбцов" + +#~ msgid "INSERT ... SELECT cannot specify INTO" +#~ msgstr "в INSERT ... SELECT нельзя указывать INTO" + +#~ msgid "DECLARE CURSOR cannot specify INTO" +#~ msgstr "в DECLARE CURSOR нельзя указать INTO" + +#~ msgid "subquery in FROM cannot have SELECT INTO" +#~ msgstr "подзапрос во FROM не может содержать SELECT INTO" + +#~ msgid "subquery cannot have SELECT INTO" +#~ msgstr "подзапрос не может содержать SELECT INTO" + +#~ msgid "subquery in WITH cannot have SELECT INTO" +#~ msgstr "подзапрос в WITH не может содержать SELECT INTO" diff --git a/src/backend/po/sv.po b/src/backend/po/sv.po new file mode 100644 index 000000000000..2191b63a4c55 --- /dev/null +++ b/src/backend/po/sv.po @@ -0,0 +1,27448 @@ +# Swedish message translation file for postgresql +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019, 2020. +# +# Många av termerna är tekniska termer som refererar till begrepp i SQL-satser och liknande. Om man +# översätter vissa av dessa så kommer det bli väldigt svårt för användaren att förstå vad vi menar. +# För många av dessa har jag valt att behålla det engelska ordet som ett begrepp. Det är en svår +# balansgång. +# +# T.ex. ett integritetsvillkor som deklarerats med flaggan DEFERRABLE har jag i text som +# tar upp det lämnat kvar begreppet deferrable. T.ex: +# +# att ange deferrable för integritetsvillkor stöds inte för domäner +# +# På många ställen är det svårt att avgöra. Ta t.ex. integer som ibland refererar till typen integer och +# ibland refererar mer allmänt till heltal. +# +# Andra exempel är att i engelskan används cleanup och vacuum på olika ställen nedan. Jag har valt att +# behålla vacuum på svenska för att göra tydligt att det är kommandon VACUUM och den processen det +# hänvisas till och inte någon annan städning. +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-20 16:43+0000\n" +"PO-Revision-Date: 2020-10-20 19:40+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 +#: ../common/config_info.c:150 ../common/config_info.c:158 +#: ../common/config_info.c:166 ../common/config_info.c:174 +#: ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "ej sparad" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 +#: commands/copy.c:3495 commands/extension.c:3436 utils/adt/genfile.c:125 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "kunde inte öppna filen \"%s\" för läsning: %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 +#: access/transam/timeline.c:143 access/transam/timeline.c:362 +#: access/transam/twophase.c:1276 access/transam/xlog.c:3503 +#: access/transam/xlog.c:4728 access/transam/xlog.c:11121 +#: access/transam/xlog.c:11134 access/transam/xlog.c:11587 +#: access/transam/xlog.c:11667 access/transam/xlog.c:11706 +#: access/transam/xlog.c:11749 access/transam/xlogfuncs.c:662 +#: access/transam/xlogfuncs.c:681 commands/extension.c:3446 libpq/hba.c:499 +#: replication/logical/origin.c:717 replication/logical/origin.c:753 +#: replication/logical/reorderbuffer.c:3599 +#: replication/logical/snapbuild.c:1741 replication/logical/snapbuild.c:1783 +#: replication/logical/snapbuild.c:1811 replication/logical/snapbuild.c:1838 +#: replication/slot.c:1622 replication/slot.c:1663 replication/walsender.c:543 +#: storage/file/buffile.c:441 storage/file/copydir.c:195 +#: utils/adt/genfile.c:200 utils/adt/misc.c:763 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "kunde inte läsa fil \"%s\": %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 +#: access/transam/twophase.c:1279 access/transam/xlog.c:3508 +#: access/transam/xlog.c:4733 replication/logical/origin.c:722 +#: replication/logical/origin.c:761 replication/logical/snapbuild.c:1746 +#: replication/logical/snapbuild.c:1788 replication/logical/snapbuild.c:1816 +#: replication/logical/snapbuild.c:1843 replication/slot.c:1626 +#: replication/slot.c:1667 replication/walsender.c:548 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 +#: ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 +#: access/heap/rewriteheap.c:1181 access/heap/rewriteheap.c:1284 +#: access/transam/timeline.c:392 access/transam/timeline.c:438 +#: access/transam/timeline.c:516 access/transam/twophase.c:1288 +#: access/transam/twophase.c:1676 access/transam/xlog.c:3375 +#: access/transam/xlog.c:3543 access/transam/xlog.c:3548 +#: access/transam/xlog.c:3876 access/transam/xlog.c:4698 +#: access/transam/xlog.c:5622 access/transam/xlogfuncs.c:687 +#: commands/copy.c:1810 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:533 +#: replication/logical/origin.c:655 replication/logical/origin.c:794 +#: replication/logical/reorderbuffer.c:3657 +#: replication/logical/snapbuild.c:1653 replication/logical/snapbuild.c:1851 +#: replication/slot.c:1513 replication/slot.c:1674 replication/walsender.c:558 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:704 +#: storage/file/fd.c:3425 storage/file/fd.c:3528 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "kunde inte stänga fil \"%s\": %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "byte-ordning stämmer inte" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"möjligt fel i byteordning\n" +"Den byteordning som filen från pg_control lagrats med passar kanske\n" +"inte detta program. I så fall kan nedanstående resultat vara felaktiga\n" +"och PostgreSQL-installationen vara inkompatibel med databaskatalogen." + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 +#: ../common/file_utils.c:224 ../common/file_utils.c:283 +#: ../common/file_utils.c:357 access/heap/rewriteheap.c:1267 +#: access/transam/timeline.c:111 access/transam/timeline.c:251 +#: access/transam/timeline.c:348 access/transam/twophase.c:1232 +#: access/transam/xlog.c:3277 access/transam/xlog.c:3417 +#: access/transam/xlog.c:3458 access/transam/xlog.c:3656 +#: access/transam/xlog.c:3741 access/transam/xlog.c:3844 +#: access/transam/xlog.c:4718 access/transam/xlogutils.c:807 +#: postmaster/syslogger.c:1488 replication/basebackup.c:621 +#: replication/basebackup.c:1593 replication/logical/origin.c:707 +#: replication/logical/reorderbuffer.c:2465 +#: replication/logical/reorderbuffer.c:2825 +#: replication/logical/reorderbuffer.c:3579 +#: replication/logical/snapbuild.c:1608 replication/logical/snapbuild.c:1712 +#: replication/slot.c:1594 replication/walsender.c:516 +#: replication/walsender.c:2517 storage/file/copydir.c:161 +#: storage/file/fd.c:679 storage/file/fd.c:3412 storage/file/fd.c:3499 +#: storage/smgr/md.c:475 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1858 +#: utils/init/miscinit.c:1316 utils/init/miscinit.c:1450 +#: utils/init/miscinit.c:1527 utils/misc/guc.c:8280 utils/misc/guc.c:8312 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 +#: access/transam/twophase.c:1649 access/transam/twophase.c:1658 +#: access/transam/xlog.c:10878 access/transam/xlog.c:10916 +#: access/transam/xlog.c:11329 access/transam/xlogfuncs.c:741 +#: postmaster/syslogger.c:1499 postmaster/syslogger.c:1512 +#: utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "kunde inte skriva fil \"%s\": %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 +#: ../common/file_utils.c:295 ../common/file_utils.c:365 +#: access/heap/rewriteheap.c:961 access/heap/rewriteheap.c:1175 +#: access/heap/rewriteheap.c:1278 access/transam/timeline.c:432 +#: access/transam/timeline.c:510 access/transam/twophase.c:1670 +#: access/transam/xlog.c:3368 access/transam/xlog.c:3537 +#: access/transam/xlog.c:4691 access/transam/xlog.c:10386 +#: access/transam/xlog.c:10413 replication/logical/snapbuild.c:1646 +#: replication/slot.c:1499 replication/slot.c:1604 storage/file/fd.c:696 +#: storage/file/fd.c:3520 storage/smgr/md.c:921 storage/smgr/md.c:962 +#: storage/sync/sync.c:396 utils/cache/relmapper.c:885 utils/misc/guc.c:8063 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "kunde inte fsync:a fil \"%s\": %m" + +#: ../common/exec.c:137 ../common/exec.c:254 ../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" + +#: ../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ogiltig binär \"%s\"" + +#: ../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "kunde inte läsa binär \"%s\"" + +#: ../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "kunde inte hitta en \"%s\" att köra" + +#: ../common/exec.c:270 ../common/exec.c:309 utils/init/miscinit.c:395 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" + +#: ../common/exec.c:287 access/transam/xlog.c:10750 +#: replication/basebackup.c:1418 utils/adt/misc.c:337 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" + +#: ../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../common/exec.c:539 ../common/exec.c:584 ../common/exec.c:676 +#: ../common/psprintf.c:143 ../common/stringinfo.c:305 ../port/path.c:630 +#: ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1341 +#: access/transam/xlog.c:6493 lib/dshash.c:246 libpq/auth.c:1090 +#: libpq/auth.c:1491 libpq/auth.c:1559 libpq/auth.c:2089 +#: libpq/be-secure-gssapi.c:484 postmaster/bgworker.c:336 +#: postmaster/bgworker.c:893 postmaster/postmaster.c:2518 +#: postmaster/postmaster.c:2540 postmaster/postmaster.c:4166 +#: postmaster/postmaster.c:4868 postmaster/postmaster.c:4938 +#: postmaster/postmaster.c:5635 postmaster/postmaster.c:5995 +#: replication/libpqwalreceiver/libpqwalreceiver.c:276 +#: replication/logical/logical.c:176 replication/walsender.c:590 +#: storage/buffer/localbuf.c:442 storage/file/fd.c:834 storage/file/fd.c:1304 +#: storage/file/fd.c:1465 storage/file/fd.c:2270 storage/ipc/procarray.c:1045 +#: storage/ipc/procarray.c:1541 storage/ipc/procarray.c:1548 +#: storage/ipc/procarray.c:1972 storage/ipc/procarray.c:2597 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1700 utils/adt/formatting.c:1824 +#: utils/adt/formatting.c:1949 utils/adt/pg_locale.c:484 +#: utils/adt/pg_locale.c:648 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:450 utils/hash/dynahash.c:559 +#: utils/hash/dynahash.c:1071 utils/mb/mbutils.c:401 utils/mb/mbutils.c:428 +#: utils/mb/mbutils.c:757 utils/mb/mbutils.c:783 utils/misc/guc.c:4846 +#: utils/misc/guc.c:4862 utils/misc/guc.c:4875 utils/misc/guc.c:8041 +#: utils/misc/tzparser.c:467 utils/mmgr/aset.c:475 utils/mmgr/dsa.c:701 +#: utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:233 +#: utils/mmgr/mcxt.c:821 utils/mmgr/mcxt.c:857 utils/mmgr/mcxt.c:895 +#: utils/mmgr/mcxt.c:933 utils/mmgr/mcxt.c:969 utils/mmgr/mcxt.c:1000 +#: utils/mmgr/mcxt.c:1036 utils/mmgr/mcxt.c:1088 utils/mmgr/mcxt.c:1123 +#: utils/mmgr/mcxt.c:1158 utils/mmgr/slab.c:235 +#, c-format +msgid "out of memory" +msgstr "slut på minne" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 +#: ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 +#: ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 +#: utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "slut på minne\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kan inte duplicera null-pekare (internt fel)\n" + +#: ../common/file_utils.c:79 ../common/file_utils.c:181 +#: access/transam/twophase.c:1244 access/transam/xlog.c:10854 +#: access/transam/xlog.c:10892 access/transam/xlog.c:11109 +#: access/transam/xlogarchive.c:110 access/transam/xlogarchive.c:226 +#: commands/copy.c:1938 commands/copy.c:3505 commands/extension.c:3425 +#: commands/tablespace.c:795 commands/tablespace.c:886 guc-file.l:1061 +#: replication/basebackup.c:444 replication/basebackup.c:627 +#: replication/basebackup.c:700 replication/logical/snapbuild.c:1522 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1816 +#: storage/file/fd.c:3096 storage/file/fd.c:3278 storage/file/fd.c:3364 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:416 utils/adt/genfile.c:642 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() på fil \"%s\": %m" + +#: ../common/file_utils.c:158 ../common/pgfnames.c:48 commands/tablespace.c:718 +#: commands/tablespace.c:728 postmaster/postmaster.c:1509 +#: storage/file/fd.c:2673 storage/file/reinit.c:122 utils/adt/misc.c:259 +#: utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "kunde inte öppna katalog \"%s\": %m" + +#: ../common/file_utils.c:192 ../common/pgfnames.c:69 storage/file/fd.c:2685 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" + +#: ../common/file_utils.c:375 access/transam/xlogarchive.c:411 +#: postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1665 +#: replication/slot.c:650 replication/slot.c:1385 replication/slot.c:1527 +#: storage/file/fd.c:714 utils/time/snapmgr.c:1350 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m" + +#: ../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Escape-sekvens \"\\%s\" är ogiltig." + +#: ../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Tecken med värde 0x%02x måste escape:as." + +#: ../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Förväntade slut på indata, men hittade \"%s\"." + +#: ../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Färväntade array-element eller \"]\", men hittade \"%s\"." + +#: ../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Förväntade \",\" eller \"]\", men hittade \"%s\"." + +#: ../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Förväntade sig \":\" men hittade \"%s\"." + +#: ../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Förväntade JSON-värde, men hittade \"%s\"." + +#: ../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "Indatasträngen avslutades oväntat." + +#: ../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Färväntade sträng eller \"}\", men hittade \"%s\"." + +#: ../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Förväntade sig \",\" eller \"}\" men hittade \"%s\"." + +#: ../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Förväntade sträng, men hittade \"%s\"." + +#: ../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Token \"%s\" är ogiltig." + +#: ../common/jsonapi.c:1099 jsonpath_scan.l:499 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 kan inte konverteras till text." + +#: ../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\" måste följas av fyra hexdecimala siffror." + +#: ../common/jsonapi.c:1104 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Escape-värden för unicode kan inte användas för kodpunkter med värde över 007F när kodningen inte är UTF8." + +#: ../common/jsonapi.c:1106 jsonpath_scan.l:520 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Unicodes övre surrogathalva får inte komma efter en övre surrogathalva." + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:531 jsonpath_scan.l:541 +#: jsonpath_scan.l:583 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Unicodes lägre surrogathalva måste följa en övre surrogathalva." + +#: ../common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../common/logging.c:243 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "ogiltigt fork-namn" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Giltiga fork-värden är \"main\", \"fsm\", \"vm\" och \"init\"." + +#: ../common/restricted_token.c:64 libpq/auth.c:1521 libpq/auth.c:2520 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "kunde inte ladda länkbibliotek \"%s\": felkod %lu" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "kan inte skapa token för begränsad åtkomst på denna plattorm: felkod %lu" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "kunde inte öppna process-token: felkod %lu" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "kunde inte allokera SID: felkod %lu" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "kunde inte skapa token för begränsad åtkomst: felkod %lu" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "kunde inte starta process för kommando \"%s\": felkod %lu" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "kunde inte köra igen med token för begränsad åtkomst: felkod %lu" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "kunde inte hämta statuskod för underprocess: felkod %lu" + +#: ../common/rmtree.c:79 replication/basebackup.c:1171 +#: replication/basebackup.c:1347 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "kunde inte ta status på fil eller katalog \"%s\": %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "kunde inte ta bort fil eller katalog \"%s\": %m" + +#: ../common/saslprep.c:1087 +#, c-format +msgid "password too long" +msgstr "lösenorder är för långt" + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "Kan inte utöka strängbuffer som innehåller %d byte med ytterligare %d bytes." + +#: ../common/stringinfo.c:310 +#, c-format +msgid "" +"out of memory\n" +"\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "" +"slut på minne\n" +"\n" +"Kan inte utöka strängbuffer som innehåller %d byte med ytterligare %d bytes.\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "kunde inte slå upp effektivt användar-id %ld: %s" + +#: ../common/username.c:45 libpq/auth.c:2027 +msgid "user does not exist" +msgstr "användaren finns inte" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "misslyckad sökning efter användarnamn: felkod %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "kommandot är inte körbart" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "kommandot kan ej hittas" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "barnprocess avslutade med kod %d" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "barnprocess terminerades med avbrott 0x%X" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "barnprocess avslutade med okänd statuskod %d" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "kunde inte bestämma kodning för teckentabell \"%s\"" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "kunde inte bestämma kodning för lokal \"%s\": teckentabellen är \"%s\"" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "kunde inte sätta knutpunkt (junction) för \"%s\": %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "kunde inte sätta knutpunkt (junktion) för \"%s\": %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "kunde inte hämta knutpunkt (junction) för \"%s\": %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "kunde inte hämta knutpunkt (junction) för \"%s\": %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "kunde inte öppna fil \"%s\": %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "lås-överträdelse" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "sharing-överträdelse" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "Fortsätter att försöka i 30 sekunder." + +#: ../port/open.c:129 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "Du kan ha antivirus, backup eller liknande mjukvara som stör databassystemet" + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "kunde inte fastställa nuvarande arbetskatalog: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "operativsystemfel %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "kunde inte hämta SID för Administratörsgrupp: felkod %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "kunde inte hämta SID för PowerUser-grupp: felkod %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "kunde inte kontrollera access-token-medlemskap: felkod %lu\n" + +#: access/brin/brin.c:210 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "förfrågan efter BRIN-intervallsummering för index \"%s\" sida %u har inte spelats in" + +#: access/brin/brin.c:873 access/brin/brin.c:950 access/gin/ginfast.c:1035 +#: access/transam/xlog.c:10522 access/transam/xlog.c:11060 +#: access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 +#: access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 +#: access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 +#: access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "återställning pågår" + +#: access/brin/brin.c:874 access/brin/brin.c:951 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "BRIN-kontrollfunktioner kan inte köras under återställning." + +#: access/brin/brin.c:882 access/brin/brin.c:959 +#, c-format +msgid "block number out of range: %s" +msgstr "blocknummer är utanför giltigt intervall: %s" + +#: access/brin/brin.c:905 access/brin/brin.c:982 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\" är inte ett BRIN-index" + +#: access/brin/brin.c:921 access/brin/brin.c:998 +#, c-format +msgid "could not open parent table of index %s" +msgstr "kunde inte öppna föräldratabell för index %s" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 +#: access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1435 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "indexradstorlek %zu överstiger maximum %zu för index \"%s\"" + +#: access/brin/brin_revmap.c:392 access/brin/brin_revmap.c:398 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "trasigt BRIN-index: inkonsistent intervall-map" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "oväntad sidtyp 0x%04X i BRIN-index \"%s\" block %u" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 +#: access/gist/gistvalidate.c:149 access/hash/hashvalidate.c:136 +#: access/nbtree/nbtvalidate.c:117 access/spgist/spgvalidate.c:168 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehåller funktion %s med ogiltigt supportnummer %d" + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 +#: access/gist/gistvalidate.c:161 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:129 access/spgist/spgvalidate.c:180 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehåller funktion %s med felaktig signatur för supportnummer %d" + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 +#: access/gist/gistvalidate.c:181 access/hash/hashvalidate.c:157 +#: access/nbtree/nbtvalidate.c:149 access/spgist/spgvalidate.c:200 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehåller operator %s med ogiltigt strateginummer %d" + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 +#: access/hash/hashvalidate.c:170 access/nbtree/nbtvalidate.c:162 +#: access/spgist/spgvalidate.c:216 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehåller ogiltig ORDER BY-specifikatioon för operator %s" + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 +#: access/gist/gistvalidate.c:229 access/hash/hashvalidate.c:183 +#: access/nbtree/nbtvalidate.c:175 access/spgist/spgvalidate.c:232 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehåller operator %s med felaktig signatur" + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:223 +#: access/nbtree/nbtvalidate.c:233 access/spgist/spgvalidate.c:259 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar operator(er) för typerna %s och %s" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknas supportfunktion(er) för typerna %s och %s" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:237 +#: access/nbtree/nbtvalidate.c:257 access/spgist/spgvalidate.c:294 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "operatorklass \"%s\" för accessmetoden %s saknar operator(er)" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 +#: access/gist/gistvalidate.c:270 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "operatorklass \"%s\" för accessmetod %s saknar supportfunktion %d" + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "Returnerad typ %s matchar inte förväntad type %s i kolumn %d." + +#: access/common/attmap.c:150 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "Antalet returnerade kolumner (%d) matchar inte förväntat antal kolumner (%d)." + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "kunde inte konvertera radtypen" + +#: access/common/attmap.c:230 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "Attribut \"%s\" för typ %s matchar inte motsvarande attribut för typ %s." + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "Attribut \"%s\" i typ %s finns inte i typ %s." + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "antalet kolumner (%d) överskrider gränsen (%d)" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "antalet indexerade kolumner (%d) överskrider gränsen (%d)" + +#: access/common/indextuple.c:187 access/spgist/spgutils.c:703 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "indexrad kräver %zu byte, maximal storlek är %zu" + +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1904 +#, c-format +msgid "unsupported format code: %d" +msgstr "ej stödd formatkod: %d" + +#: access/common/reloptions.c:506 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Giltiga värden är \"on\", \"off\" och \"auto\"." + +#: access/common/reloptions.c:517 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "Giltiga värden är \"local\" och \"cascaded\"." + +#: access/common/reloptions.c:665 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "överskriden gräns för användardefinierade relationsparametertyper" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESET får inte ha med värden på parametrar" + +#: access/common/reloptions.c:1240 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "okänd parameternamnrymd \"%s\"" + +#: access/common/reloptions.c:1277 utils/misc/guc.c:12032 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "tabeller deklarerade med WITH OIDS stöds inte" + +#: access/common/reloptions.c:1447 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "okänd parameter \"%s\"" + +#: access/common/reloptions.c:1559 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "parameter \"%s\" angiven mer än en gång" + +#: access/common/reloptions.c:1575 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "ogiltigt värde för booleansk flagga \"%s\": \"%s\"" + +#: access/common/reloptions.c:1587 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "ogiltigt värde för heltalsflagga \"%s\": \"%s\"" + +#: access/common/reloptions.c:1593 access/common/reloptions.c:1613 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "värdet %s är utanför sitt intervall för flaggan \"%s\"" + +#: access/common/reloptions.c:1595 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Giltiga värden är mellan \"%d\" och \"%d\"." + +#: access/common/reloptions.c:1607 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "ogiltigt värde för flyttalsflagga \"%s\": %s" + +#: access/common/reloptions.c:1615 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Giltiga värden är mellan \"%f\" och \"%f\"." + +#: access/common/reloptions.c:1637 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "ogiltigt värde för enum-flagga \"%s\": %s" + +#: access/common/tupdesc.c:842 parser/parse_clause.c:772 +#: parser/parse_relation.c:1803 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "kolumn \"%s\" kan inte deklareras som SETOF" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "post-listan är för lång" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "Minska maintenance_work_mem." + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "väntande GIN-lista kan inte städas upp under återställning." + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\" är inte ett GIN-index" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "kan inte flytta temporära index tillhörande andra sessioner" + +#: access/gin/ginget.c:270 access/nbtree/nbtinsert.c:745 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "misslyckades att återfinna tuple i index \"%s\"" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "gamla GIN-index stöder inte hela-index-scan eller sökningar efter null" + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "För att fixa detta, kör REINDEX INDEX \"%s\"." + +#: access/gin/ginutil.c:144 executor/execExpr.c:1862 +#: utils/adt/arrayfuncs.c:3790 utils/adt/arrayfuncs.c:6418 +#: utils/adt/rowtypes.c:936 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "kunde inte hitta någon jämförelsefunktion för typen %s" + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehåller supportfunktion %s med olika vänster- och höger-inputtyper" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "operatorklass \"%s\" för accessmetod \"%s\" saknar supportfunktion %d eller %d" + +#: access/gist/gist.c:753 access/gist/gistvacuum.c:408 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "index \"%s\" innehåller en inre tupel som är markerad ogiltig" + +#: access/gist/gist.c:755 access/gist/gistvacuum.c:410 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "Detta orsakas av en inkomplett siduppdelning under krashåterställning körd innan uppdatering till PostgreSQL 9.1." + +#: access/gist/gist.c:756 access/gist/gistutil.c:786 access/gist/gistutil.c:797 +#: access/gist/gistvacuum.c:411 access/hash/hashutil.c:227 +#: access/hash/hashutil.c:238 access/hash/hashutil.c:250 +#: access/hash/hashutil.c:271 access/nbtree/nbtpage.c:741 +#: access/nbtree/nbtpage.c:752 +#, c-format +msgid "Please REINDEX it." +msgstr "Var vänlig och kör REINDEX på det." + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "picksplit-metod för kolumn %d i index \"%s\" misslyckades" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "Indexet är inte optimalt. För att optimera det, kontakta en utvecklare eller försök använda kolumnen som det andra värdet i CREATE INDEX-kommandot." + +#: access/gist/gistutil.c:783 access/hash/hashutil.c:224 +#: access/nbtree/nbtpage.c:738 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "index \"%s\" innehåller en oväntad nollställd sida vid block %u" + +#: access/gist/gistutil.c:794 access/hash/hashutil.c:235 +#: access/hash/hashutil.c:247 access/nbtree/nbtpage.c:749 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "index \"%s\" har en trasig sida vid block %u" + +#: access/gist/gistvalidate.c:199 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "operatorfamiljen \"%s\" för accessmetod %s innehåller en ORDER BY som inte stöds för operator %s" + +#: access/gist/gistvalidate.c:210 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "operatorfamiljen \"%s\" för accessmetod %s innehåller en inkorrekt ORDER BY \"opfamiily\"-specifikation för operator %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för sträng-hashning" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:702 +#: catalog/heap.c:708 commands/createas.c:206 commands/createas.c:489 +#: commands/indexcmds.c:1814 commands/tablecmds.c:16035 commands/view.c:86 +#: parser/parse_utilcmd.c:4203 regex/regc_pg_locale.c:263 +#: utils/adt/formatting.c:1667 utils/adt/formatting.c:1791 +#: utils/adt/formatting.c:1916 utils/adt/like.c:194 +#: utils/adt/like_support.c:1003 utils/adt/varchar.c:733 +#: utils/adt/varchar.c:994 utils/adt/varchar.c:1054 utils/adt/varlena.c:1476 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Använd en COLLATE-klausul för att sätta jämförelsen explicit." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "indexradstorlek %zu överstiger hash-maximum %zu" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:764 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Värden större än en buffert-sida kan inte indexeras." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "ogiltigt overflow-blocknummer %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "slut på överspillsidor i hash-index \"%s\"" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "hash-index stöder inte hela-index-scans" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "index \"%s\" är inte ett hashträd" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "index \"%s\" har fel hash-version" + +#: access/hash/hashvalidate.c:195 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar supportfunktion för operator %s" + +#: access/hash/hashvalidate.c:253 access/nbtree/nbtvalidate.c:273 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar mellan-typ-operator(er)" + +#: access/heap/heapam.c:2024 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "kan inte lägga till tupler i en parellell arbetare" + +#: access/heap/heapam.c:2442 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "kan inte radera tupler under en parallell operation" + +#: access/heap/heapam.c:2488 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "försökte ta bort en osynlig tuple" + +#: access/heap/heapam.c:2914 access/heap/heapam.c:5703 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "kan inte uppdatera tupler under en parallell operation" + +#: access/heap/heapam.c:3047 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "försökte uppdatera en osynlig tuple" + +#: access/heap/heapam.c:4358 access/heap/heapam.c:4396 +#: access/heap/heapam.c:4653 access/heap/heapam_handler.c:450 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "kunde inte låsa rad i relationen \"%s\"" + +#: access/heap/heapam_handler.c:399 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "tupel som skall låsas har redan flyttats till en annan partition av en samtida uppdatering" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:662 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "raden är för stor: storlek %zu, maximal storlek %zu" + +#: access/heap/rewriteheap.c:921 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "kunde inte skriva till fil \"%s\", skrev %d av %d: %m." + +#: access/heap/rewriteheap.c:1015 access/heap/rewriteheap.c:1134 +#: access/transam/timeline.c:329 access/transam/timeline.c:485 +#: access/transam/xlog.c:3300 access/transam/xlog.c:3472 +#: access/transam/xlog.c:4670 access/transam/xlog.c:10869 +#: access/transam/xlog.c:10907 access/transam/xlog.c:11312 +#: access/transam/xlogfuncs.c:735 postmaster/postmaster.c:4629 +#: replication/logical/origin.c:575 replication/slot.c:1446 +#: storage/file/copydir.c:167 storage/smgr/md.c:218 utils/time/snapmgr.c:1329 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "kan inte skapa fil \"%s\": %m" + +#: access/heap/rewriteheap.c:1144 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "kunde inte trunkera fil \"%s\" till %u: %m" + +#: access/heap/rewriteheap.c:1162 access/transam/timeline.c:384 +#: access/transam/timeline.c:424 access/transam/timeline.c:502 +#: access/transam/xlog.c:3356 access/transam/xlog.c:3528 +#: access/transam/xlog.c:4682 postmaster/postmaster.c:4639 +#: postmaster/postmaster.c:4649 replication/logical/origin.c:587 +#: replication/logical/origin.c:629 replication/logical/origin.c:648 +#: replication/logical/snapbuild.c:1622 replication/slot.c:1481 +#: storage/file/buffile.c:502 storage/file/copydir.c:207 +#: utils/init/miscinit.c:1391 utils/init/miscinit.c:1402 +#: utils/init/miscinit.c:1410 utils/misc/guc.c:8024 utils/misc/guc.c:8055 +#: utils/misc/guc.c:9975 utils/misc/guc.c:9989 utils/time/snapmgr.c:1334 +#: utils/time/snapmgr.c:1341 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "kunde inte skriva till fil \"%s\": %m" + +#: access/heap/rewriteheap.c:1252 access/transam/twophase.c:1609 +#: access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:421 +#: postmaster/postmaster.c:1092 postmaster/syslogger.c:1465 +#: replication/logical/origin.c:563 replication/logical/reorderbuffer.c:3079 +#: replication/logical/snapbuild.c:1564 replication/logical/snapbuild.c:2006 +#: replication/slot.c:1578 storage/file/fd.c:754 storage/file/fd.c:3116 +#: storage/file/fd.c:3178 storage/file/reinit.c:255 storage/ipc/dsm.c:302 +#: storage/smgr/md.c:311 storage/smgr/md.c:367 storage/sync/sync.c:210 +#: utils/time/snapmgr.c:1674 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "kunde inte ta bort fil \"%s\": %m" + +#: access/heap/vacuumlazy.c:648 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisk aggressiv vacuum för att förhindra \"wraparound\" av tabell \"%s.%s.%s\": indexskanningar: %d\n" + +#: access/heap/vacuumlazy.c:650 +#, c-format +msgid "automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisk vacuum för att förhindra \"wraparound\" av tabell \"%s.%s.%s\": indexskanningar: %d\n" + +#: access/heap/vacuumlazy.c:655 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisk vacuum av tabell \"%s.%s.%s\": indexskanningar: %d\n" + +#: access/heap/vacuumlazy.c:657 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisk vacuum av tabell \"%s.%s.%s\": indexskanningar: %d\n" + +#: access/heap/vacuumlazy.c:664 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "sidor: %u borttagna, %u kvar, %u överhoppade pga pins, %u överhoppade frysta\n" + +#: access/heap/vacuumlazy.c:670 +#, c-format +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "tupler: %.0f borttagna, %.0f kvar, %.0f är döda men ännu inte möjliga att ta bort, äldsta xmin: %u\n" + +#: access/heap/vacuumlazy.c:676 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "bufferanvändning: %lld träffar, %lld missar, %lld nersmutsade\n" + +#: access/heap/vacuumlazy.c:680 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "snitt läshastighet: %.3f MB/s, snitt skrivhastighet: %.3f MB/s\n" + +#: access/heap/vacuumlazy.c:682 +#, c-format +msgid "system usage: %s\n" +msgstr "systemanvändning: %s\n" + +#: access/heap/vacuumlazy.c:684 +#, c-format +msgid "WAL usage: %ld records, %ld full page images, %llu bytes" +msgstr "WAL-användning: %ld poster, %ld hela sidor, %llu bytes" + +#: access/heap/vacuumlazy.c:795 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "aggressiv vaccum av \"%s.%s\"" + +#: access/heap/vacuumlazy.c:800 commands/cluster.c:874 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "kör vaccum på \"%s.%s\"" + +#: access/heap/vacuumlazy.c:837 +#, c-format +msgid "disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel" +msgstr "stänger av parallell-flaggan för vacuumn på \"%s\" --- kan inte köra vacuum på temporära tabeller parallellt" + +#: access/heap/vacuumlazy.c:1725 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%s\": tog bort %.0f radversioner i %u sidor" + +#: access/heap/vacuumlazy.c:1735 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f döda radversioner kan inte tas bort än, äldsta xmin: %u\n" + +#: access/heap/vacuumlazy.c:1737 +#, c-format +msgid "There were %.0f unused item identifiers.\n" +msgstr "Det fanns %.0f oanvända post-identifierare.\n" + +#: access/heap/vacuumlazy.c:1739 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Hoppade över %u sida på grund av fastnålade buffrar, " +msgstr[1] "Hoppade över %u sidor på grund av fastnålade buffrar, " + +#: access/heap/vacuumlazy.c:1743 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u fryst sida.\n" +msgstr[1] "%u frysta sidor.\n" + +#: access/heap/vacuumlazy.c:1747 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%u sida är helt tom.\n" +msgstr[1] "%u sidor är helt tomma.\n" + +#: access/heap/vacuumlazy.c:1751 commands/indexcmds.c:3487 +#: commands/indexcmds.c:3505 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1754 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%s\": hittade %.0f borttagbara, %.0f ej borttagbara radversioner i %u av %u sidor" + +#: access/heap/vacuumlazy.c:1888 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%s\": tog bort %d radversioner i %d sidor" + +#: access/heap/vacuumlazy.c:2143 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "startade %d parallell städarbetare för indexupprensning (planerat: %d)" +msgstr[1] "startade %d parallella städarbetare för indexupprensning (planerat: %d)" + +#: access/heap/vacuumlazy.c:2149 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "startade %d parallell städarbetare för index-vacuum (planerat: %d)" +msgstr[1] "startade %d parallella städarbetare för index-vacuum (planerat: %d)" + +#: access/heap/vacuumlazy.c:2441 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions by parallel vacuum worker" +msgstr "genomsökte index \"%s\" och tog bort %d radversioner med parallell vacuum-arbetsprocess" + +#: access/heap/vacuumlazy.c:2443 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "genomsökte index \"%s\" och tog bort %d radversioner" + +#: access/heap/vacuumlazy.c:2501 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages as reported by parallel vacuum worker" +msgstr "index \"%s\" innehåller nu %.0f radversioner i %u sidor enligt raoport från parallell vacuum-arbetsprocess" + +#: access/heap/vacuumlazy.c:2503 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "index \"%s\" innehåller nu %.0f radversioner i %u sidor" + +#: access/heap/vacuumlazy.c:2510 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f indexradversioner togs bort.\n" +"%u indexsidor har raderats, %u är nu återanvändningsbara.\n" +"%s." + +#: access/heap/vacuumlazy.c:2613 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\": stoppar trunkering pga konfliktande låskrav" + +#: access/heap/vacuumlazy.c:2679 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": trunkerade %u till %u sidor" + +#: access/heap/vacuumlazy.c:2744 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\": pausar trunkering pga konfliktande låskrav" + +#: access/heap/vacuumlazy.c:3583 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "vid skanning av block %u i relation \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3586 +#, c-format +msgid "while scanning relation \"%s.%s\"" +msgstr "vid skanning av relation \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3592 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "vid vacuum av block %u i relation \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3595 +#, c-format +msgid "while vacuuming relation \"%s.%s\"" +msgstr "vid vacuum av relation \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3600 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "vid vaccum av index \"%s\" i relation \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3605 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "vid uppstädning av index \"%s\" i relation \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3611 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "vid trunkering av relation \"%s.%s\" till %u block" + +#: access/index/amapi.c:83 commands/amcmds.c:170 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "accessmetod \"%s\" har inte typ %s" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "indexaccessmetod \"%s\" har ingen hanterare" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1260 +#: commands/indexcmds.c:2516 commands/tablecmds.c:254 commands/tablecmds.c:278 +#: commands/tablecmds.c:15733 commands/tablecmds.c:17188 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\" är inte ett index" + +#: access/index/indexam.c:970 +#, c-format +msgid "operator class %s has no options" +msgstr "operatorklass %s har inga flaggor" + +#: access/nbtree/nbtinsert.c:651 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "duplicerat nyckelvärde bryter mot unik-villkor \"%s\"" + +#: access/nbtree/nbtinsert.c:653 +#, c-format +msgid "Key %s already exists." +msgstr "Nyckeln %s existerar redan." + +#: access/nbtree/nbtinsert.c:747 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Det kan bero på ett icke-immutable indexuttryck." + +#: access/nbtree/nbtpage.c:150 access/nbtree/nbtpage.c:538 +#: parser/parse_utilcmd.c:2244 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "index \"%s\" är inte ett btree" + +#: access/nbtree/nbtpage.c:157 access/nbtree/nbtpage.c:545 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "versionsfel i index \"%s\": filversion %d, aktuell version %d, minsta supportade version %d" + +#: access/nbtree/nbtpage.c:1501 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "index \"%s\" innehåller en halvdöd intern sida" + +#: access/nbtree/nbtpage.c:1503 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "Detta kan ha orsakats av en avbruten VACUUM i version 9.3 eller äldre, innan uppdatering. Vänligen REINDEX:era det." + +#: access/nbtree/nbtutils.c:2664 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "indexradstorlek %zu överstiger btree version %u maximum %zu för index \"%s\"" + +#: access/nbtree/nbtutils.c:2670 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "Indexrad refererar tupel (%u,%u) i relation \"%s\"." + +#: access/nbtree/nbtutils.c:2674 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"Värden större än 1/3 av en buffer-sida kan inte indexeras.\n" +"Kanske kan du använda ett funktionsindex av ett MD5-hashvärde istället\n" +"eller möjligen full-text-indexering." + +#: access/nbtree/nbtvalidate.c:243 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar supportfunktioner för typerna %s och %s" + +#: access/spgist/spgutils.c:147 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "komprimeringsmetod måste definieras när lövtypen skiljer sig från indatatypen" + +#: access/spgist/spgutils.c:761 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "SP-GiST inre tuplestorlek %zu överstiger maximala %zu" + +#: access/spgist/spgvalidate.c:281 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar supportfunktion %d för typ %s" + +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 +#: catalog/aclchk.c:1806 +#, c-format +msgid "\"%s\" is an index" +msgstr "\"%s\" är ett index" + +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 +#: catalog/aclchk.c:1813 commands/tablecmds.c:12554 commands/tablecmds.c:15742 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "\"%s\" är en composite-typ" + +#: access/table/tableam.c:244 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "tid (%u, %u) är inte giltigt för relation \"%s\"" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "%s får inte vara tom." + +#: access/table/tableamapi.c:122 utils/misc/guc.c:11956 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s är för lång (maximalt %d tecken)." + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "tabellaccessmetod \"%s\" existerar inte" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "Tabellaccessmetod \"%s\" existerar inte." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "urvalsprocent måste vara mellan 0 och 100" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "kan inte hämta commit-tidsstämpel för transaktion %u" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "kunde inte hämta commit-tidsstämpeldata" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "Se till att konfigurationsparametern \"%s\" är satt på master-servern." + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "Se till att konfigurationsparametern \"%s\" är satt." + +#: access/transam/multixact.c:1002 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "databasen tar inte emot kommandon som genererar nya MultiXactId:er för att förhinda dataförlust vid \"wraparound\" i databasen \"%s\"" + +#: access/transam/multixact.c:1004 access/transam/multixact.c:1011 +#: access/transam/multixact.c:1035 access/transam/multixact.c:1044 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Utför en hela databasen-VACUUM i den databasen.\n" +"Du kan också behöva commit:a eller rulla tillbaka gamla förberedda transaktioner eller slänga gamla replikeringsslottar." + +#: access/transam/multixact.c:1009 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "databasen tar inte emot kommandon som genererar nya MultiXactId:er för att förhinda dataförlust vid \"wraparound\" i databasen med OID %u" + +#: access/transam/multixact.c:1030 access/transam/multixact.c:2320 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "databasen \"%s\" måste städas innan ytterligare %u MultiXactId används" +msgstr[1] "databasen \"%s\" måste städas innan ytterligare %u MultiXactId:er används" + +#: access/transam/multixact.c:1039 access/transam/multixact.c:2329 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "databas med OID %u måste städas (vacuum) innan %u till MultiXactId används" +msgstr[1] "databas med OID %u måste städas (vacuum) innan %u till MultiXactId:er används" + +#: access/transam/multixact.c:1100 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "multixact \"members\"-gräns överskriden" + +#: access/transam/multixact.c:1101 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "Detta kommando skapar en multixact med %u medlemmar, men återstående utrymmer räcker bara till %u medlem." +msgstr[1] "Detta kommando skapar en multixact med %u medlemmar, men återstående utrymmer räcker bara till %u medlemmar." + +#: access/transam/multixact.c:1106 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Kör en hela-databas-VACUUM i databas med OID %u med reducerade iställningar vacuum_multixact_freeze_min_age och vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1137 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "databas med OID %u måste städas innan %d mer multixact-medlem används" +msgstr[1] "databas med OID %u måste städas innan %d fler multixact-medlemmar används" + +#: access/transam/multixact.c:1142 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Kör en hela-databas-VACUUM i den databasen med reducerade inställningar för vacuum_multixact_freeze_min_age och vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1279 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "MultiXactId %u finns inte längre -- troligen en wraparound" + +#: access/transam/multixact.c:1287 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "MultiXactId %u har inte skapats än -- troligen en wraparound" + +#: access/transam/multixact.c:2270 +#, c-format +msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +msgstr "MultiXactId wrap-gräns är %u, begränsad av databasen med OID %u" + +#: access/transam/multixact.c:2325 access/transam/multixact.c:2334 +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/varsup.c:447 access/transam/varsup.c:454 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"För att undvika att databasen stängs ner, utför en hela databas-VACCUM i den databasen.\n" +"Du kan också behöva commit:a eller rulla tillbaka gamla förberedda transaktioner eller slänga gamla replikeringsslottar." + +#: access/transam/multixact.c:2604 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "äldsta MultiXactId-medlemmen är vid offset %u" + +#: access/transam/multixact.c:2608 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "MultiXact-medlems wraparound-skydd är avslagen eftersom äldsta checkpoint:ade MultiXact %u inte finns på disk" + +#: access/transam/multixact.c:2630 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "MultiXact-medlems wraparound-skydd är nu påslagen" + +#: access/transam/multixact.c:2633 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "MultiXact-medlems stoppgräns är nu %u baserad på MultiXact %u" + +#: access/transam/multixact.c:3013 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "äldsta MultiXact %u hittas inte, tidigast MultiXact %u, skippar trunkering" + +#: access/transam/multixact.c:3031 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "kan inte trunkera upp till %u eftersom den inte finns på disk, skippar trunkering" + +#: access/transam/multixact.c:3345 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "ogiltig MultiXactId: %u" + +#: access/transam/parallel.c:706 access/transam/parallel.c:825 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "parallell arbetare misslyckades med initiering" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "More details may be available in the server log." +msgstr "Fler detaljer kan finnas i serverloggen." + +#: access/transam/parallel.c:887 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "postmaster avslutade under en parallell transaktion" + +#: access/transam/parallel.c:1074 +#, c-format +msgid "lost connection to parallel worker" +msgstr "tappad kopplingen till parallell arbetare" + +#: access/transam/parallel.c:1140 access/transam/parallel.c:1142 +msgid "parallel worker" +msgstr "parallell arbetare" + +#: access/transam/parallel.c:1293 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "kunde inte skapa dynamiskt delat minnessegment: %m" + +#: access/transam/parallel.c:1298 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "ogiltigt magiskt nummer i dynamiskt delat minnessegment" + +#: access/transam/slru.c:696 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "filen \"%s\" existerar inte, läses som nollor" + +#: access/transam/slru.c:937 access/transam/slru.c:943 +#: access/transam/slru.c:951 access/transam/slru.c:956 +#: access/transam/slru.c:963 access/transam/slru.c:968 +#: access/transam/slru.c:975 access/transam/slru.c:982 +#, c-format +msgid "could not access status of transaction %u" +msgstr "kunde inte läsa status på transaktion %u" + +#: access/transam/slru.c:938 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "Kunde inte öppna fil \"%s\": %m." + +#: access/transam/slru.c:944 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "Kunde inte söka i fil \"%s\" till offset %u: %m." + +#: access/transam/slru.c:952 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "Kunde inte läsa från fil \"%s\" på offset %u: %m." + +#: access/transam/slru.c:957 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "Kunde inte läsa från fil \"%s\" på offset %u: läste för få bytes." + +#: access/transam/slru.c:964 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "Kunde inte skriva till fil \"%s\" på offset %u: %m." + +#: access/transam/slru.c:969 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "Kunde inte skriva till fil \"%s\" på offset %u: skrev för få bytes." + +#: access/transam/slru.c:976 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "Kunde inte fsync:a fil \"%s\": %m." + +#: access/transam/slru.c:983 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "Kunde inte stänga fil \"%s\": %m." + +#: access/transam/slru.c:1258 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "Kunde inte trunkera katalog \"%s\": trolig wraparound" + +#: access/transam/slru.c:1313 access/transam/slru.c:1369 +#, c-format +msgid "removing file \"%s\"" +msgstr "tar bort fil \"%s\"" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "syntaxfel i history-fil: %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Förväntade ett numeriskt tidslinje-ID." + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Förväntade en write-ahead-logg:s switchpoint-position." + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "felaktig data i history-fil: %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Tidslinje-ID måste komma i en stigande sekvens." + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "felaktig data i history-fil \"%s\"" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Tidslinje-ID:er måste vara mindre än barnens tidslinje-ID:er." + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "efterfrågad tidslinje %u finns inte i denna servers historik" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "transaktionsidentifierare \"%s\" är för lång" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "förberedda transaktioner är avslagna" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "Sätt max_prepared_transactions till ett ickenollvärde." + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "transaktionsidentifierare \"%s\" används redan" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2368 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "maximalt antal förberedda transaktioner har uppnåtts" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2369 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "Öka max_prepared_transactions (nu %d)." + +#: access/transam/twophase.c:586 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "förberedd transaktion med identifierare \"%s\" är upptagen" + +#: access/transam/twophase.c:592 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "rättighet saknas för att slutföra förberedd transaktion" + +#: access/transam/twophase.c:593 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "Måste vara superanvändare eller den användare som förberedde transaktionen" + +#: access/transam/twophase.c:604 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "förberedda transaktionen tillhör en annan databas" + +#: access/transam/twophase.c:605 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "Anslut till databasen där transaktionen var förberedd för att slutföra den." + +#: access/transam/twophase.c:620 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "förberedd transaktion med identifierare \"%s\" finns inte" + +#: access/transam/twophase.c:1098 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "tvåfas-statusfilens maximala längd överskriden" + +#: access/transam/twophase.c:1252 +#, c-format +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "felaktig storlek på fil \"%s\": %zu byte" +msgstr[1] "felaktig storlek på fil \"%s\": %zu byte" + +#: access/transam/twophase.c:1261 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "inkorrekt justering (alignment) av CRC-offset för fil \"%s\"" + +#: access/transam/twophase.c:1294 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "felaktigt magiskt nummer lagrat i fil \"%s\"" + +#: access/transam/twophase.c:1300 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "felaktig storlek lagrad i fil \"%s\"" + +#: access/transam/twophase.c:1312 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "beräknad CRC-checksumma matchar inte värdet som är lagrat i filen \"%s\"" + +#: access/transam/twophase.c:1342 access/transam/xlog.c:6494 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "Millslyckades vid allokering av en WAL-läs-processor." + +#: access/transam/twophase.c:1349 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "kunde inte läsa tvåfas-status från WAL vid %X/%X" + +#: access/transam/twophase.c:1357 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "förväntad tvåfas-statusdata finns inte i WAL vid %X/%X" + +#: access/transam/twophase.c:1637 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "kan inte återskapa fil \"%s\": %m" + +#: access/transam/twophase.c:1764 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "%u tvåfas-statusfil skrevs för långkörande förberedd transkation" +msgstr[1] "%u tvåfas-statusfiler skrevs för långkörande förberedda transaktioner" + +#: access/transam/twophase.c:1998 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "återskapar förberedd transaktion %u från delat minne" + +#: access/transam/twophase.c:2089 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "tar bort död tvåfas-statusfil för transaktioon %u" + +#: access/transam/twophase.c:2096 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "tar bort död tvåfas-statusfil från minne för transaktion %u" + +#: access/transam/twophase.c:2109 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "tar bort framtida tvåfas-statusfil för transaktion %u" + +#: access/transam/twophase.c:2116 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "tar bort framtida tvåfas-statusfil från minne för transaktion %u" + +#: access/transam/twophase.c:2141 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "korrupt tvåfas-statusfil för transaktion %u" + +#: access/transam/twophase.c:2146 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "korrupt tvåfas-status i minnet för transaktion %u" + +#: access/transam/varsup.c:127 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "databasen tar inte emot kommandon för att förhinda dataförlust vid \"wraparound\" i databasen \"%s\"" + +#: access/transam/varsup.c:129 access/transam/varsup.c:136 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Stoppa postmaster och städa (vacuum) den databasen i enanvändarläge.\n" +"Du kan också behöva commit:a eller rulla tillbaka förberedda transaktioner eller slänga gamla replikeringsslottar." + +#: access/transam/varsup.c:134 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "databasen tar inte emot kommandon för att förhinda dataförlust vid wraparound i databas med OID %u" + +#: access/transam/varsup.c:146 access/transam/varsup.c:444 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "databas \"%s\" måste städas (vacuum) inom %u transaktioner" + +#: access/transam/varsup.c:153 access/transam/varsup.c:451 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "databas med OID %u måste städas (vacuum) inom %u transaktioner" + +#: access/transam/varsup.c:409 +#, c-format +msgid "transaction ID wrap limit is %u, limited by database with OID %u" +msgstr "transaktions-ID wrap-gräns är %u, begränsad av databas med OID %u" + +#: access/transam/xact.c:1030 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "kan inte ha mer än 2^32-2 kommandon i en transaktion" + +#: access/transam/xact.c:1555 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "maximalt antal commit:ade undertransaktioner (%d) överskridet" + +#: access/transam/xact.c:2395 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "kan inte göra PREPARE på en transaktion som har arbetat med temporära objekt" + +#: access/transam/xact.c:2405 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "kan inte göra PREPARE på en transaktion som har exporterade snapshots" + +#: access/transam/xact.c:2414 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "kan inte göra PREPARE på en transaktion som har förändrat logiska replikeringsarbetare" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3359 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s kan inte köras i ett transaktionsblock" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3369 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s kan inte köras i ett undertransaktionsblock" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3379 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s kan inte köras från en funktion" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3448 access/transam/xact.c:3754 +#: access/transam/xact.c:3833 access/transam/xact.c:3956 +#: access/transam/xact.c:4107 access/transam/xact.c:4176 +#: access/transam/xact.c:4287 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s kan bara användas i transaktionsblock" + +#: access/transam/xact.c:3640 +#, c-format +msgid "there is already a transaction in progress" +msgstr "det är redan en transaktion igång" + +#: access/transam/xact.c:3759 access/transam/xact.c:3838 +#: access/transam/xact.c:3961 +#, c-format +msgid "there is no transaction in progress" +msgstr "ingen transaktion pågår" + +#: access/transam/xact.c:3849 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "kan inte commit:a under en parallell operation" + +#: access/transam/xact.c:3972 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "can inte avbryta under en parallell operation" + +#: access/transam/xact.c:4071 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "kan inte definiera sparpunkter under en parallell operation" + +#: access/transam/xact.c:4158 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "kan inte frigöra en sparpunkt under en parallell operation" + +#: access/transam/xact.c:4168 access/transam/xact.c:4219 +#: access/transam/xact.c:4279 access/transam/xact.c:4328 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "sparpunkt \"%s\" existerar inte" + +#: access/transam/xact.c:4225 access/transam/xact.c:4334 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "sparpunkt \"%s\" finns inte inom aktuell sparpunktsnivå" + +#: access/transam/xact.c:4267 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "kan inte rulla tillbaka till sparpunkt under en parallell operation" + +#: access/transam/xact.c:4395 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "kan inte starta subtransaktioner under en parallell operation" + +#: access/transam/xact.c:4463 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "kan inte commit:a subtransaktioner undert en parallell operation" + +#: access/transam/xact.c:5103 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "kan inte ha mer än 2^32-1 subtransaktioner i en transaktion" + +#: access/transam/xlog.c:2554 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "kunde inte skriva till loggfil %s vid offset %u, längd %zu: %m" + +#: access/transam/xlog.c:2830 +#, c-format +msgid "updated min recovery point to %X/%X on timeline %u" +msgstr "updaterade minsta återställningspunkt till %X/%X på tidslinje %u" + +#: access/transam/xlog.c:3944 access/transam/xlogutils.c:802 +#: replication/walsender.c:2511 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "efterfrågat WAL-segment %s har redan tagits bort" + +#: access/transam/xlog.c:4187 +#, c-format +msgid "recycled write-ahead log file \"%s\"" +msgstr "återanvände write-ahead-loggfil \"%s\"" + +#: access/transam/xlog.c:4199 +#, c-format +msgid "removing write-ahead log file \"%s\"" +msgstr "tar bort write-ahead-loggfil \"%s\"" + +#: access/transam/xlog.c:4219 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "kunde inte byta namn på fil \"%s\": %m" + +#: access/transam/xlog.c:4261 access/transam/xlog.c:4271 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "krävd WAL-katalog \"%s\" finns inte" + +#: access/transam/xlog.c:4277 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "skapar saknad WAL-katalog \"%s\"" + +#: access/transam/xlog.c:4280 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "kunde inte skapa saknad katalog \"%s\": %m" + +#: access/transam/xlog.c:4383 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "oväntad tidslinje-ID %u i loggsegment %s, offset %u" + +#: access/transam/xlog.c:4521 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "ny tidslinje %u är inte ett barn till databasens systemtidslinje %u" + +#: access/transam/xlog.c:4535 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "ny tidslinje %u skapad från aktuella databasens systemtidslinje %u innan nuvarande återställningspunkt %X/%X" + +#: access/transam/xlog.c:4554 +#, c-format +msgid "new target timeline is %u" +msgstr "ny måltidslinje är %u" + +#: access/transam/xlog.c:4590 +#, c-format +msgid "could not generate secret authorization token" +msgstr "kunde inte generera hemligt auktorisationstoken" + +#: access/transam/xlog.c:4749 access/transam/xlog.c:4758 +#: access/transam/xlog.c:4782 access/transam/xlog.c:4789 +#: access/transam/xlog.c:4796 access/transam/xlog.c:4801 +#: access/transam/xlog.c:4808 access/transam/xlog.c:4815 +#: access/transam/xlog.c:4822 access/transam/xlog.c:4829 +#: access/transam/xlog.c:4836 access/transam/xlog.c:4843 +#: access/transam/xlog.c:4852 access/transam/xlog.c:4859 +#: utils/init/miscinit.c:1548 +#, c-format +msgid "database files are incompatible with server" +msgstr "databasfilerna är inkompatibla med servern" + +#: access/transam/xlog.c:4750 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "Databasklustret initierades med PG_CONTROL_VERSION %d (0x%08x), men servern kompilerades med PG_CONTROL_VERSION %d (0x%08x)." + +#: access/transam/xlog.c:4754 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "Detta kan orsakas av en felaktig byte-ordning. Du behöver troligen köra initdb." + +#: access/transam/xlog.c:4759 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "Databasklustret initierades med PG_CONTROL_VERSION %d, men servern kompilerades med PG_CONTROL_VERSION %d." + +#: access/transam/xlog.c:4762 access/transam/xlog.c:4786 +#: access/transam/xlog.c:4793 access/transam/xlog.c:4798 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Du behöver troligen köra initdb." + +#: access/transam/xlog.c:4773 +#, c-format +msgid "incorrect checksum in control file" +msgstr "ogiltig kontrollsumma kontrollfil" + +#: access/transam/xlog.c:4783 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "Databasklustret initierades med CATALOG_VERSION_NO %d, men servern kompilerades med CATALOG_VERSION_NO %d." + +#: access/transam/xlog.c:4790 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "Databasklustret initierades med MAXALIGN %d, men servern kompilerades med MAXALIGN %d." + +#: access/transam/xlog.c:4797 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "Databasklustret verkar använda en annan flyttalsrepresentation än vad serverprogrammet gör." + +#: access/transam/xlog.c:4802 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "Databasklustret initierades med BLCKSZ %d, men servern kompilerades med BLCKSZ %d." + +#: access/transam/xlog.c:4805 access/transam/xlog.c:4812 +#: access/transam/xlog.c:4819 access/transam/xlog.c:4826 +#: access/transam/xlog.c:4833 access/transam/xlog.c:4840 +#: access/transam/xlog.c:4847 access/transam/xlog.c:4855 +#: access/transam/xlog.c:4862 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Det verkar som om du måste kompilera om eller köra initdb." + +#: access/transam/xlog.c:4809 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "Databasklustret initierades med RELSEG_SIZE %d, men servern kompilerades med RELSEG_SIZE %d." + +#: access/transam/xlog.c:4816 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "Databasklustret initierades med XLOG_BLCKSZ %d, men servern kompilerades med XLOG_BLCKSZ %d." + +#: access/transam/xlog.c:4823 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "Databasklustret initierades med NAMEDATALEN %d, men servern kompilerades med NAMEDATALEN %d." + +#: access/transam/xlog.c:4830 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "Databasklustret initierades med INDEX_MAX_KEYS %d, men servern kompilerades med INDEX_MAX_KEYS %d." + +#: access/transam/xlog.c:4837 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "Databasklustret initierades med TOAST_MAX_CHUNK_SIZE %d, men servern kompilerades med TOAST_MAX_CHUNK_SIZE %d." + +#: access/transam/xlog.c:4844 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "Databasklustret initierades med LOBLKSIZE %d, men servern kompilerades med LOBLKSIZE %d." + +#: access/transam/xlog.c:4853 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "Databasklustret initierades utan USE_FLOAT8_BYVAL, men servern kompilerades med USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4860 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "Databasklustret initierades med USE_FLOAT8_BYVAL, men servern kompilerades utan USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4869 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-segmentstorlek måste vara en tvåpotens mellan 1MB och 1GB men kontrollfilen anger %d byte" +msgstr[1] "WAL-segmentstorlek måste vara en tvåpotens mellan 1MB och 1GB men kontrollfilen anger %d byte" + +#: access/transam/xlog.c:4881 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" måste vara minst dubbla \"wal_segment_size\"" + +#: access/transam/xlog.c:4885 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" måste vara minst dubbla \"wal_segment_size\"" + +#: access/transam/xlog.c:5318 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "kunde inte skriva bootstrap-write-ahead-loggfil: %m" + +#: access/transam/xlog.c:5326 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "kunde inte fsync:a bootstrap-write-ahead-loggfil: %m" + +#: access/transam/xlog.c:5332 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "kunde inte stänga bootstrap-write-ahead-loggfil: %m" + +#: access/transam/xlog.c:5393 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "använda återställningskommandofil \"%s\" stöds inte" + +#: access/transam/xlog.c:5458 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "standby-läge stöd inte av enanvändarservrar" + +#: access/transam/xlog.c:5475 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "angav varken primary_conninfo eller restore_command" + +#: access/transam/xlog.c:5476 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "Databasservern kommer med jämna mellanrum att poll:a pg_wal-underkatalogen för att se om filer placerats där." + +#: access/transam/xlog.c:5484 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "måste ange restore_command när standby-läge inte är påslaget" + +#: access/transam/xlog.c:5522 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "återställningsmåltidslinje %u finns inte" + +#: access/transam/xlog.c:5644 +#, c-format +msgid "archive recovery complete" +msgstr "arkivåterställning klar" + +#: access/transam/xlog.c:5710 access/transam/xlog.c:5983 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "återställning stoppad efter att ha uppnått konsistens" + +#: access/transam/xlog.c:5731 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "återställning stoppad före WAL-position (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5817 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "återställning stoppad före commit av transaktion %u, tid %s" + +#: access/transam/xlog.c:5824 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "återställning stoppad före abort av transaktion %u, tid %s" + +#: access/transam/xlog.c:5877 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "återställning stoppad vid återställningspunkt \"%s\", tid %s" + +#: access/transam/xlog.c:5895 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "återställning stoppad efter WAL-position (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5963 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "återställning stoppad efter commit av transaktion %u, tid %s" + +#: access/transam/xlog.c:5971 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "återställning stoppad efter abort av transaktion %u, tid %s" + +#: access/transam/xlog.c:6020 +#, c-format +msgid "pausing at the end of recovery" +msgstr "pausar vid slutet av återställning" + +#: access/transam/xlog.c:6021 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "Kör pg_wal_replay_resume() för att befordra." + +#: access/transam/xlog.c:6024 +#, c-format +msgid "recovery has paused" +msgstr "återställning har pausats" + +#: access/transam/xlog.c:6025 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Kör pg_wal_replay_resume() för att fortsätta." + +#: access/transam/xlog.c:6242 +#, c-format +msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" +msgstr "hot standby är inte möjligt då %s = %d har ett lägre värde än på masterservern (dess värde var %d)" + +#: access/transam/xlog.c:6266 +#, c-format +msgid "WAL was generated with wal_level=minimal, data may be missing" +msgstr "WAL genererades med wal_level=minimal, data kan saknas" + +#: access/transam/xlog.c:6267 +#, c-format +msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgstr "Detta händer om du temporärt sätter wal_level=minimal utan att ta en ny basbackup." + +#: access/transam/xlog.c:6278 +#, c-format +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgstr "hot standby är inte möjligt då wal_level inte satts till \"replica\" eller högre på masterservern" + +#: access/transam/xlog.c:6279 +#, c-format +msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +msgstr "Antingen sätt wal_level till \"replica\" på mastern eller stäng av hot_standby här." + +#: access/transam/xlog.c:6341 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "kontrollfil innehåller ogiltig checkpoint-position" + +#: access/transam/xlog.c:6352 +#, c-format +msgid "database system was shut down at %s" +msgstr "databassystemet stängdes ner vid %s" + +#: access/transam/xlog.c:6358 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "databassystemet stängdes ner under återställning vid %s" + +#: access/transam/xlog.c:6364 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "nedstängning av databasen avbröts; senast kända upptidpunkt vid %s" + +#: access/transam/xlog.c:6370 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "databassystemet avbröts under återställning vid %s" + +#: access/transam/xlog.c:6372 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "Det betyder troligen att en del data är förstörd och du behöver återställa databasen från den senaste backup:en." + +#: access/transam/xlog.c:6378 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "databassystemet avbröts under återställning vid loggtid %s" + +#: access/transam/xlog.c:6380 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "Om detta har hänt mer än en gång så kan data vara korrupt och du kanske måste återställa till ett tidigare återställningsmål." + +#: access/transam/xlog.c:6386 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "databassystemet avbröts; senast kända upptidpunkt vid %s" + +#: access/transam/xlog.c:6392 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "kontrollfil innehåller ogiltigt databasklustertillstånd" + +#: access/transam/xlog.c:6449 +#, c-format +msgid "entering standby mode" +msgstr "går in i standby-läge" + +#: access/transam/xlog.c:6452 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "startar point-in-time-återställning till XID %u" + +#: access/transam/xlog.c:6456 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "startar point-in-time-återställning till %s" + +#: access/transam/xlog.c:6460 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "startar point-in-time-återställning till \"%s\"" + +#: access/transam/xlog.c:6464 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "startar point-in-time-återställning till WAL-position (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:6469 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "startar point-in-time-återställning till tidigast konsistenta punkt" + +#: access/transam/xlog.c:6472 +#, c-format +msgid "starting archive recovery" +msgstr "Startar arkivåterställning" + +#: access/transam/xlog.c:6531 access/transam/xlog.c:6664 +#, c-format +msgid "checkpoint record is at %X/%X" +msgstr "checkpoint-posten är vid %X/%X" + +#: access/transam/xlog.c:6546 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "kunde inte hitta redo-position refererad av checkpoint-post" + +#: access/transam/xlog.c:6547 access/transam/xlog.c:6557 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" +"Om du återställer från en backup, gör touch på \"%s/recovery.signal\" och lägg till\n" +"önskade återställningsalternativ. Om du inte återställer från en backup, försök ta\n" +"bort filen \"%s/backup_label\". Var försiktig: borttagning av \"%s/backup_label\"\n" +"kommer resultera i ett trasigt kluster om du återställer från en backup." + +#: access/transam/xlog.c:6556 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "kunde inte hitta den checkpoint-post som krävs" + +#: access/transam/xlog.c:6585 commands/tablespace.c:654 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "kan inte skapa symbolisk länk \"%s\": %m" + +#: access/transam/xlog.c:6617 access/transam/xlog.c:6623 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "hoppar över fil \"%s\" då ingen fil \"%s\" finns" + +#: access/transam/xlog.c:6619 access/transam/xlog.c:11828 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "Filen \"%s\" döptes om till \"%s\"." + +#: access/transam/xlog.c:6625 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "Kunde inte döpa om fil \"%s\" till \"%s\": %m" + +#: access/transam/xlog.c:6676 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "kunde inte hitta en giltig checkpoint-post" + +#: access/transam/xlog.c:6714 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "efterfrågad tidslinje %u är inte ett barn till denna servers historik" + +#: access/transam/xlog.c:6716 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "Senaste checkpoint är vid %X/%X på tidslinje %u, men i historiken för efterfrågad tidslinje så avvek servern från den tidslinjen vid %X/%X." + +#: access/transam/xlog.c:6732 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "efterfågan tidslinje %u innehåller inte minimal återställningspunkt %X/%X på tidslinje %u" + +#: access/transam/xlog.c:6763 +#, c-format +msgid "invalid next transaction ID" +msgstr "nästa transaktions-ID ogiltig" + +#: access/transam/xlog.c:6857 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "ogiltig redo i checkpoint-post" + +#: access/transam/xlog.c:6868 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "ogiltig redo-post i nedstängnings-checkpoint" + +#: access/transam/xlog.c:6902 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "databassystemet stängdes inte ned korrekt; automatisk återställning pågår" + +#: access/transam/xlog.c:6906 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "krashåterställning startar i tidslinje %u och har måltidslinje %u" + +#: access/transam/xlog.c:6953 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label innehåller data som inte stämmer med kontrollfil" + +#: access/transam/xlog.c:6954 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "Det betyder att backup:en är trasig och du behöver använda en annan backup för att återställa." + +#: access/transam/xlog.c:7045 +#, c-format +msgid "initializing for hot standby" +msgstr "initierar för hot standby" + +#: access/transam/xlog.c:7178 +#, c-format +msgid "redo starts at %X/%X" +msgstr "redo startar vid %X/%X" + +#: access/transam/xlog.c:7402 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "efterfrågad återställningsstoppunkt är före en konsistent återställningspunkt" + +#: access/transam/xlog.c:7440 +#, c-format +msgid "redo done at %X/%X" +msgstr "redo gjord vid %X/%X" + +#: access/transam/xlog.c:7445 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "senaste kompletta transaktionen var vid loggtid %s" + +#: access/transam/xlog.c:7454 +#, c-format +msgid "redo is not required" +msgstr "redo behövs inte" + +#: access/transam/xlog.c:7466 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "återställning avslutades innan det konfigurerade återställningsmålet nåddes" + +#: access/transam/xlog.c:7545 access/transam/xlog.c:7549 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "WAL slutar före sluttiden av online-backup:en" + +#: access/transam/xlog.c:7546 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "Alla genererade WAL under tiden online-backup:en togs måste vara tillgängliga vid återställning." + +#: access/transam/xlog.c:7550 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "Online-backup startad med pg_start_backup() måste avslutas med pg_stop_backup() och alla WAL fram till den punkten måste vara tillgängliga vid återställning." + +#: access/transam/xlog.c:7553 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL avslutas innan konstistent återställningspunkt" + +#: access/transam/xlog.c:7588 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "valt nytt tidslinje-ID: %u" + +#: access/transam/xlog.c:8036 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "konsistent återställningstillstånd uppnått vid %X/%X" + +#: access/transam/xlog.c:8246 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "ogiltig primär checkpoint-länk i kontrollfil" + +#: access/transam/xlog.c:8250 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "ogiltig checkpoint-länk i \"backup_label\"-fil" + +#: access/transam/xlog.c:8268 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "ogiltig primär checkpoint-post" + +#: access/transam/xlog.c:8272 +#, c-format +msgid "invalid checkpoint record" +msgstr "ogiltig checkpoint-post" + +#: access/transam/xlog.c:8283 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "ogiltig resurshanterar-ID i primär checkpoint-post" + +#: access/transam/xlog.c:8287 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "ogiltig resurshanterar-ID i checkpoint-post" + +#: access/transam/xlog.c:8300 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "ogiltig xl_info i primär checkpoint-post" + +#: access/transam/xlog.c:8304 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "ogiltig xl_info i checkpoint-post" + +#: access/transam/xlog.c:8315 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "ogiltig längd i primär checkpoint-post" + +#: access/transam/xlog.c:8319 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "ogiltig längd på checkpoint-post" + +#: access/transam/xlog.c:8499 +#, c-format +msgid "shutting down" +msgstr "stänger ner" + +#: access/transam/xlog.c:8819 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "checkpoint överhoppad på grund av att systemet är olastat" + +#: access/transam/xlog.c:9019 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "samtidig write-ahead-logg-aktivitet när databassystemet stängs ner" + +#: access/transam/xlog.c:9276 +#, c-format +msgid "skipping restartpoint, recovery has already ended" +msgstr "hoppar över omstartpunkt, återställning har redan avslutats" + +#: access/transam/xlog.c:9299 +#, c-format +msgid "skipping restartpoint, already performed at %X/%X" +msgstr "hoppar över omstartpunkt, redan gjorde vid %X/%X" + +#: access/transam/xlog.c:9467 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "återställningens omstartspunkt vid %X/%X" + +#: access/transam/xlog.c:9469 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Senaste kompletta transaktionen var vid loggtid %s" + +#: access/transam/xlog.c:9711 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "återställningspunkt \"%s\" skapad vid %X/%X" + +#: access/transam/xlog.c:9856 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "oväntad föregående tidslinje-ID %u (nuvarande tidslinje-ID %u) i checkpoint-post" + +#: access/transam/xlog.c:9865 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "oväntad tidslinje-ID %u (efter %u) i checkpoint-post" + +#: access/transam/xlog.c:9881 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "oväntad tidslinje-ID %u i checkpoint-post, innan vi nått minimal återställningspunkt %X/%X på tidslinje %u" + +#: access/transam/xlog.c:9957 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "online-backup avbröts, återställning kan inte fortsätta" + +#: access/transam/xlog.c:10013 access/transam/xlog.c:10069 +#: access/transam/xlog.c:10092 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "oväntad tidslinje-ID %u (skall vara %u) i checkpoint-post" + +#: access/transam/xlog.c:10418 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "kunde inte fsync:a skriv-igenom-loggfil \"%s\": %m" + +#: access/transam/xlog.c:10424 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "kunde inte fdatasync:a fil \"%s\": %m" + +#: access/transam/xlog.c:10523 access/transam/xlog.c:11061 +#: access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 +#: access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 +#: access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "WAL-kontrollfunktioner kan inte köras under återställning." + +#: access/transam/xlog.c:10532 access/transam/xlog.c:11070 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "WAL-nivå inte tillräcklig för att kunna skapa en online-backup" + +#: access/transam/xlog.c:10533 access/transam/xlog.c:11071 +#: access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "wal_level måste vara satt till \"replica\" eller \"logical\" vid serverstart." + +#: access/transam/xlog.c:10538 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "backup-etikett för lång (max %d byte)" + +#: access/transam/xlog.c:10575 access/transam/xlog.c:10860 +#: access/transam/xlog.c:10898 +#, c-format +msgid "a backup is already in progress" +msgstr "en backup är redan på gång" + +#: access/transam/xlog.c:10576 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "Kör pg_stop_backup() och försök igen." + +#: access/transam/xlog.c:10672 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "WAL skapad med full_page_writes=off har återspelats sedab senaste omstartpunkten" + +#: access/transam/xlog.c:10674 access/transam/xlog.c:11266 +#, c-format +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." +msgstr "Det betyder att backup:en som tas på standby:en är trasig och inte skall användas. Slå på full_page_writes och kör CHECKPOINT på master och försök sedan ta en ny online-backup igen." + +#: access/transam/xlog.c:10757 replication/basebackup.c:1423 +#: utils/adt/misc.c:342 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "mål för symbolisk länk \"%s\" är för lång" + +#: access/transam/xlog.c:10810 commands/tablespace.c:402 +#: commands/tablespace.c:566 replication/basebackup.c:1438 utils/adt/misc.c:350 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "tabellutrymmen stöds inte på denna plattform" + +#: access/transam/xlog.c:10861 access/transam/xlog.c:10899 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "Om du är säker på att det inte pågår någon backup så ta bort filen \"%s\" och försök igen." + +#: access/transam/xlog.c:11086 +#, c-format +msgid "exclusive backup not in progress" +msgstr "exklusiv backup är inte på gång" + +#: access/transam/xlog.c:11113 +#, c-format +msgid "a backup is not in progress" +msgstr "ingen backup är på gång" + +#: access/transam/xlog.c:11199 access/transam/xlog.c:11212 +#: access/transam/xlog.c:11601 access/transam/xlog.c:11607 +#: access/transam/xlog.c:11655 access/transam/xlog.c:11728 +#: access/transam/xlogfuncs.c:692 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "felaktig data i fil \"%s\"" + +#: access/transam/xlog.c:11216 replication/basebackup.c:1271 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "standby:en befordrades under online-backup" + +#: access/transam/xlog.c:11217 replication/basebackup.c:1272 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "Det betyder att backupen som tas är trasig och inte skall användas. Försök ta en ny online-backup." + +#: access/transam/xlog.c:11264 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "WAL skapad med full_page_writes=off återspelades under online-backup" + +#: access/transam/xlog.c:11384 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "base_backup klar, väntar på att de WAL-segment som krävs blir arkiverade" + +#: access/transam/xlog.c:11396 +#, c-format +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "väntar fortfarande på att alla krävda WAL-segments skall bli arkiverade (%d sekunder har gått)" + +#: access/transam/xlog.c:11398 +#, c-format +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "Kontrollera att ditt archive_command kör som det skall. Du kan avbryta denna backup på ett säkert sätt men databasbackup:en kommer inte vara användbart utan att alla WAL-segment finns." + +#: access/transam/xlog.c:11405 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "alla krävda WAL-segments har arkiverats" + +#: access/transam/xlog.c:11409 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "WAL-arkivering är inte påslagen; du måste se till att alla krävda WAL-segment har kopierats på annat sätt för att backup:en skall vara komplett" + +#: access/transam/xlog.c:11462 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "avbryter backup på grund av att backend:en stoppades innan pg_stop_backup anropades" + +#: access/transam/xlog.c:11638 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "backuptid %s i fil \"%s\"" + +#: access/transam/xlog.c:11643 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "backup-etikett %s i fil \"%s\"" + +#: access/transam/xlog.c:11656 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "Parsad tidslinje-ID är %u men förväntade sig %u." + +#: access/transam/xlog.c:11660 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "backuptidslinje %u i fil \"%s\"" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11768 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "WAL-redo vid %X/%X för %s" + +#: access/transam/xlog.c:11817 +#, c-format +msgid "online backup mode was not canceled" +msgstr "online backupläge har ej avbrutits" + +#: access/transam/xlog.c:11818 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "Filen \"%s\" kunde inte döpas om till \"%s\": %m." + +#: access/transam/xlog.c:11827 access/transam/xlog.c:11839 +#: access/transam/xlog.c:11849 +#, c-format +msgid "online backup mode canceled" +msgstr "online backupläge avbrutet" + +#: access/transam/xlog.c:11840 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "Filer \"%s\" och \"%s\" döptes om till \"%s\" och \"%s\", var för sig." + +#: access/transam/xlog.c:11850 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "Filen \"%s\" dötes om till \"%s\", men filen \"%s\" kunde inte döpas om till \"%s\": %m." + +#: access/transam/xlog.c:11983 access/transam/xlogutils.c:971 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "kunde inte läsa från loggsegment %s, offset %u: %m" + +#: access/transam/xlog.c:11989 access/transam/xlogutils.c:978 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "kunde inte läsa från loggsegment %s, offset %u, läste %d av %zu" + +#: access/transam/xlog.c:12518 +#, c-format +msgid "WAL receiver process shutdown requested" +msgstr "nedstängning av WAL-mottagarprocess efterfrågad" + +#: access/transam/xlog.c:12624 +#, c-format +msgid "received promote request" +msgstr "tog emot förfrågan om befordring" + +#: access/transam/xlog.c:12637 +#, c-format +msgid "promote trigger file found: %s" +msgstr "utlösarfil för befordring hittad: %s" + +#: access/transam/xlog.c:12646 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "kunde inte göra stat() på utlösarfil för befordring \"%s\": %m" + +#: access/transam/xlogarchive.c:205 +#, c-format +msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgstr "arkivfil \"%s\" har fel storlek: %lu istället för %lu" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "återställd logfil \"%s\" från arkiv" + +#: access/transam/xlogarchive.c:259 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "kunde inte återställa fil \"%s\" från arkiv: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:368 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" + +#: access/transam/xlogarchive.c:478 access/transam/xlogarchive.c:542 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "kunde inte skapa arkiveringsstatusfil \"%s\": %m" + +#: access/transam/xlogarchive.c:486 access/transam/xlogarchive.c:550 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "kunde inte skriva arkiveringsstatusfil \"%s\": %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "en backup är redan på gång i denna session" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "icke-exklusiv backup är på gång" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "Menade du att använda pg_stop_backup('f')?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1332 +#: commands/event_trigger.c:1890 commands/extension.c:1944 +#: commands/extension.c:2052 commands/extension.c:2337 commands/prepare.c:712 +#: executor/execExpr.c:2203 executor/execSRF.c:728 executor/functions.c:1040 +#: foreign/foreign.c:520 libpq/hba.c:2666 replication/logical/launcher.c:1086 +#: replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1486 +#: replication/slotfuncs.c:252 replication/walsender.c:3266 +#: storage/ipc/shmem.c:550 utils/adt/datetime.c:4765 utils/adt/genfile.c:505 +#: utils/adt/genfile.c:588 utils/adt/jsonfuncs.c:1792 +#: utils/adt/jsonfuncs.c:1904 utils/adt/jsonfuncs.c:2092 +#: utils/adt/jsonfuncs.c:2201 utils/adt/jsonfuncs.c:3663 utils/adt/misc.c:215 +#: utils/adt/pgstatfuncs.c:476 utils/adt/pgstatfuncs.c:584 +#: utils/adt/pgstatfuncs.c:1719 utils/fmgr/funcapi.c:72 utils/misc/guc.c:9676 +#: utils/mmgr/portalmem.c:1136 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "en funktion som returnerar en mängd anropades i kontext som inte godtar en mängd" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1336 +#: commands/event_trigger.c:1894 commands/extension.c:1948 +#: commands/extension.c:2056 commands/extension.c:2341 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2670 replication/logical/launcher.c:1090 +#: replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1490 +#: replication/slotfuncs.c:256 replication/walsender.c:3270 +#: storage/ipc/shmem.c:554 utils/adt/datetime.c:4769 utils/adt/genfile.c:509 +#: utils/adt/genfile.c:592 utils/adt/misc.c:219 utils/adt/pgstatfuncs.c:480 +#: utils/adt/pgstatfuncs.c:588 utils/adt/pgstatfuncs.c:1723 +#: utils/misc/guc.c:9680 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1140 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "materialiserat läge krävs, men stöds inte i detta kontext" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "icke-exklusiv backup är inte på gång" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "Menade du att använda pg_stop_backup('t')?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "WAL-nivån är inte tillräcklig för att skapa en återställningspunkt" + +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "värdet för långt för en återställningspunkt (maximalt %d tecken)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "%s kan inte köras under återställning" + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:558 +#: access/transam/xlogfuncs.c:582 access/transam/xlogfuncs.c:722 +#, c-format +msgid "recovery is not in progress" +msgstr "återställning är inte i gång" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:559 +#: access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "Återställningskontrollfunktioner kan bara köras under återställning." + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:564 +#, c-format +msgid "standby promotion is ongoing" +msgstr "standby-befordring pågår" + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:565 +#, c-format +msgid "%s cannot be executed after promotion is triggered." +msgstr "%s kan inte köras efter att befordran startats." + +#: access/transam/xlogfuncs.c:728 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "\"wait_seconds\" får inte vara negativ eller noll" + +#: access/transam/xlogfuncs.c:748 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "misslyckades med att sända en signal till postmaster: %m" + +#: access/transam/xlogfuncs.c:784 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "servern befordrades inte inom %d sekunder" + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "ogiltig postoffset vid %X/%X" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "contrecord är begärd vid %X/%X" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "ogiltig postlängd vid %X/%X: förväntade %u, fick %u" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "postlängd %u vid %X/%X är för lång" + +#: access/transam/xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "det finns ingen contrecord-flagga vid %X/%X" + +#: access/transam/xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "ogiltig contrecord-längd %u vid %X/%X" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "ogiltigt resurshanterar-ID %u vid %X/%X" + +#: access/transam/xlogreader.c:717 access/transam/xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "post med inkorrekt prev-link %X/%X vid %X/%X" + +#: access/transam/xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%X" + +#: access/transam/xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "felaktigt magiskt nummer %04X i loggsegment %s, offset %u" + +#: access/transam/xlogreader.c:822 access/transam/xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ogiltiga infobitar %04X i loggsegment %s, offset %u" + +#: access/transam/xlogreader.c:837 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL-fil är från ett annat databassystem: WAL-filens databassystemidentifierare är %llu, pg_control databassystemidentifierare är %llu" + +#: access/transam/xlogreader.c:845 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-fil är från ett annat databassystem: inkorrekt segmentstorlek i sidhuvuid" + +#: access/transam/xlogreader.c:851 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL-fil är från ett annat databassystem: inkorrekt XLOG_BLCKSZ i sidhuvuid" + +#: access/transam/xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "oväntad sidadress %X/%X i loggsegment %s, offset %u" + +# FIXME +#: access/transam/xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "\"ej i sekvens\"-fel på tidslinje-ID %u (efter %u) i loggsegment %s, offset %u" + +#: access/transam/xlogreader.c:1247 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "\"ej i sekvens\"-block_id %u vid %X/%X" + +#: access/transam/xlogreader.c:1270 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA satt, men ingen data inkluderad vid %X/%X" + +#: access/transam/xlogreader.c:1277 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA ej satt, men datalängd är %u vid %X/%X" + +#: access/transam/xlogreader.c:1313 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE satt, men håloffset %u längd %u block-image-längd %u vid %X/%X" + +#: access/transam/xlogreader.c:1329 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ej satt, men håloffset %u längd %u vid %X/%X" + +#: access/transam/xlogreader.c:1344 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED satt, men block-image-längd %u vid %X/%X" + +#: access/transam/xlogreader.c:1359 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_IS_COMPRESSED satt, men block-image-längd är %u vid %X/%X" + +#: access/transam/xlogreader.c:1375 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL satt men ingen tidigare rel vid %X/%X" + +#: access/transam/xlogreader.c:1387 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "ogiltig block_id %u vid %X/%X" + +#: access/transam/xlogreader.c:1476 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "post med ogiltig längd vid %X/%X" + +#: access/transam/xlogreader.c:1565 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "ogiltig komprimerad image vid %X/%X, block %d" + +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X kräver ett tvåpotensvärde mellan 1 MB och 1 GB" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:842 tcop/postgres.c:3705 +#, c-format +msgid "--%s requires a value" +msgstr "--%s kräver ett värde" + +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:847 tcop/postgres.c:3710 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s kräver ett värde" + +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:859 +#: postmaster/postmaster.c:872 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: bootstrap/bootstrap.c:313 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: ogiltigt kommandoradsargument\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "\"grant option\" kan bara ges till roller" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "inga rättigheter givna för kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "inga rättigheter gavs till \"%s\"" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "inte alla rättigheter givna för kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "inte alla rättigheter givna för \"%s\"" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "inga rättigheter kunde tas tillbaka från kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "inga rättigheter kunde tas tillbaka från \"%s\"" + +#: catalog/aclchk.c:342 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "inte alla rättigheter kunde tas tillbaka från kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "inte alla rättigheter kunde tas tillbaka från \"%s\"" + +#: catalog/aclchk.c:430 catalog/aclchk.c:973 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "ogiltig privilegietyp %s för relation" + +#: catalog/aclchk.c:434 catalog/aclchk.c:977 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "ogiltig privilegietyp %s för sekvens" + +#: catalog/aclchk.c:438 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "ogiltig privilegietyp %s för databas" + +#: catalog/aclchk.c:442 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "ogiltig privilegietyp %s för domän" + +#: catalog/aclchk.c:446 catalog/aclchk.c:981 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "ogiltig privilegietyp %s för funktion" + +#: catalog/aclchk.c:450 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "ogiltig privilegietyp %s för språk" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "ogiltig privilegietyp %s för stort objekt" + +#: catalog/aclchk.c:458 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "ogiltig privilegietyp %s för schema" + +#: catalog/aclchk.c:462 catalog/aclchk.c:985 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "ogiltig rättighetstyp %s för procedur" + +#: catalog/aclchk.c:466 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "ogiltig rättighetstyp %s för rutin" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "ogiltig privilegietyp %s för tabellutrymme" + +#: catalog/aclchk.c:474 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "ogiltig privilegietyp %s för typ" + +#: catalog/aclchk.c:478 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "ogiltig privilegietyp %s för främmande data-omvandlare" + +#: catalog/aclchk.c:482 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "ogiltig privilegietyp %s för främmande server" + +#: catalog/aclchk.c:521 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "kolumnprivilegier är bara giltiga för relationer" + +#: catalog/aclchk.c:681 catalog/aclchk.c:4100 catalog/aclchk.c:4882 +#: catalog/objectaddress.c:965 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "stort objekt %u existerar inte" + +#: catalog/aclchk.c:910 catalog/aclchk.c:919 commands/collationcmds.c:118 +#: commands/copy.c:1134 commands/copy.c:1154 commands/copy.c:1163 +#: commands/copy.c:1172 commands/copy.c:1181 commands/copy.c:1190 +#: commands/copy.c:1199 commands/copy.c:1208 commands/copy.c:1226 +#: commands/copy.c:1242 commands/copy.c:1262 commands/copy.c:1279 +#: commands/dbcommands.c:157 commands/dbcommands.c:166 +#: commands/dbcommands.c:175 commands/dbcommands.c:184 +#: commands/dbcommands.c:193 commands/dbcommands.c:202 +#: commands/dbcommands.c:211 commands/dbcommands.c:220 +#: commands/dbcommands.c:229 commands/dbcommands.c:238 +#: commands/dbcommands.c:260 commands/dbcommands.c:1502 +#: commands/dbcommands.c:1511 commands/dbcommands.c:1520 +#: commands/dbcommands.c:1529 commands/extension.c:1735 +#: commands/extension.c:1745 commands/extension.c:1755 +#: commands/extension.c:3055 commands/foreigncmds.c:539 +#: commands/foreigncmds.c:548 commands/functioncmds.c:570 +#: commands/functioncmds.c:736 commands/functioncmds.c:745 +#: commands/functioncmds.c:754 commands/functioncmds.c:763 +#: commands/functioncmds.c:2014 commands/functioncmds.c:2022 +#: commands/publicationcmds.c:90 commands/publicationcmds.c:133 +#: commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 +#: commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 +#: commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:104 commands/subscriptioncmds.c:114 +#: commands/subscriptioncmds.c:124 commands/subscriptioncmds.c:134 +#: commands/subscriptioncmds.c:148 commands/subscriptioncmds.c:159 +#: commands/subscriptioncmds.c:173 commands/tablecmds.c:7102 +#: commands/typecmds.c:322 commands/typecmds.c:1355 commands/typecmds.c:1364 +#: commands/typecmds.c:1372 commands/typecmds.c:1380 commands/typecmds.c:1388 +#: commands/user.c:133 commands/user.c:147 commands/user.c:156 +#: commands/user.c:165 commands/user.c:174 commands/user.c:183 +#: commands/user.c:192 commands/user.c:201 commands/user.c:210 +#: commands/user.c:219 commands/user.c:228 commands/user.c:237 +#: commands/user.c:246 commands/user.c:582 commands/user.c:590 +#: commands/user.c:598 commands/user.c:606 commands/user.c:614 +#: commands/user.c:622 commands/user.c:630 commands/user.c:638 +#: commands/user.c:647 commands/user.c:655 commands/user.c:663 +#: parser/parse_utilcmd.c:387 replication/pgoutput/pgoutput.c:141 +#: replication/pgoutput/pgoutput.c:162 replication/walsender.c:886 +#: replication/walsender.c:897 replication/walsender.c:907 +#, c-format +msgid "conflicting or redundant options" +msgstr "motstridiga eller redundanta inställningar" + +#: catalog/aclchk.c:1030 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "standardrättigheter kan inte sättas för kolumner" + +#: catalog/aclchk.c:1190 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "kan inte använda IN SCHEMA-klausul samtidigt som GRANT/REVOKE ON SCHEMAS" + +#: catalog/aclchk.c:1558 catalog/catalog.c:506 catalog/objectaddress.c:1427 +#: commands/analyze.c:389 commands/copy.c:5080 commands/sequence.c:1702 +#: commands/tablecmds.c:6578 commands/tablecmds.c:6721 +#: commands/tablecmds.c:6771 commands/tablecmds.c:6845 +#: commands/tablecmds.c:6915 commands/tablecmds.c:7027 +#: commands/tablecmds.c:7121 commands/tablecmds.c:7180 +#: commands/tablecmds.c:7253 commands/tablecmds.c:7282 +#: commands/tablecmds.c:7437 commands/tablecmds.c:7519 +#: commands/tablecmds.c:7612 commands/tablecmds.c:7767 +#: commands/tablecmds.c:10972 commands/tablecmds.c:11154 +#: commands/tablecmds.c:11314 commands/tablecmds.c:12397 commands/trigger.c:876 +#: parser/analyze.c:2339 parser/parse_relation.c:713 parser/parse_target.c:1036 +#: parser/parse_type.c:144 parser/parse_utilcmd.c:3289 +#: parser/parse_utilcmd.c:3324 parser/parse_utilcmd.c:3366 utils/adt/acl.c:2870 +#: utils/adt/ruleutils.c:2535 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "kolumn \"%s\" i relation \"%s\" existerar inte" + +#: catalog/aclchk.c:1821 catalog/objectaddress.c:1267 commands/sequence.c:1140 +#: commands/tablecmds.c:236 commands/tablecmds.c:15706 utils/adt/acl.c:2060 +#: utils/adt/acl.c:2090 utils/adt/acl.c:2122 utils/adt/acl.c:2154 +#: utils/adt/acl.c:2182 utils/adt/acl.c:2212 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "\"%s\" är inte en sekvens" + +#: catalog/aclchk.c:1859 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "sekvensen \"%s\" stöder bara USAGE-, SELECT- och UPDATE-rättigheter" + +#: catalog/aclchk.c:1876 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "ogiltig rättighetstyp %s för tabell" + +#: catalog/aclchk.c:2042 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "ogitligt rättighetstyp %s för kolumn" + +#: catalog/aclchk.c:2055 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "sekvensen \"%s\" stöder bara kolumnrättigheten SELECT" + +#: catalog/aclchk.c:2637 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "språket \"%s\" är inte betrott" + +#: catalog/aclchk.c:2639 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "GRANT och REVOKE är inte tillåtna på icke betrodda språk då bara superanvändare kan använda icke betrodda språk." + +#: catalog/aclchk.c:3153 +#, c-format +msgid "cannot set privileges of array types" +msgstr "kan inte sätta privilegier för array-typer" + +#: catalog/aclchk.c:3154 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Sätt rättigheter för elementtypen istället." + +#: catalog/aclchk.c:3161 catalog/objectaddress.c:1561 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "\"%s\" är inte en domän" + +#: catalog/aclchk.c:3281 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "okänd privilegietyp \"%s\"" + +#: catalog/aclchk.c:3342 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "rättighet saknas för aggregat %s" + +#: catalog/aclchk.c:3345 +#, c-format +msgid "permission denied for collation %s" +msgstr "rättighet saknas för jämförelse %s" + +#: catalog/aclchk.c:3348 +#, c-format +msgid "permission denied for column %s" +msgstr "rättighet saknas för kolumn %s" + +#: catalog/aclchk.c:3351 +#, c-format +msgid "permission denied for conversion %s" +msgstr "rättighet saknas för konvertering %s" + +#: catalog/aclchk.c:3354 +#, c-format +msgid "permission denied for database %s" +msgstr "rättighet saknas för databas %s" + +#: catalog/aclchk.c:3357 +#, c-format +msgid "permission denied for domain %s" +msgstr "rättighet saknas för domän %s" + +#: catalog/aclchk.c:3360 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "rättighet saknas för händelseutlösare %s" + +#: catalog/aclchk.c:3363 +#, c-format +msgid "permission denied for extension %s" +msgstr "rättighet saknas för utökning %s" + +#: catalog/aclchk.c:3366 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "rättighet saknas för främmande data-omvandlare %s" + +#: catalog/aclchk.c:3369 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "rättighet saknas för främmande server %s" + +#: catalog/aclchk.c:3372 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "rättighet saknas för främmande tabell %s" + +#: catalog/aclchk.c:3375 +#, c-format +msgid "permission denied for function %s" +msgstr "rättighet saknas för funktion %s" + +#: catalog/aclchk.c:3378 +#, c-format +msgid "permission denied for index %s" +msgstr "rättighet saknas för index %s" + +#: catalog/aclchk.c:3381 +#, c-format +msgid "permission denied for language %s" +msgstr "rättighet saknas för språk %s" + +#: catalog/aclchk.c:3384 +#, c-format +msgid "permission denied for large object %s" +msgstr "rättighet saknas för stort objekt %s" + +#: catalog/aclchk.c:3387 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "rättighet saknas för materialiserad vy %s" + +#: catalog/aclchk.c:3390 +#, c-format +msgid "permission denied for operator class %s" +msgstr "rättighet saknas för operatorklasss %s" + +#: catalog/aclchk.c:3393 +#, c-format +msgid "permission denied for operator %s" +msgstr "rättighet saknas för operator %s" + +#: catalog/aclchk.c:3396 +#, c-format +msgid "permission denied for operator family %s" +msgstr "rättighet saknas för operatorfamilj %s" + +#: catalog/aclchk.c:3399 +#, c-format +msgid "permission denied for policy %s" +msgstr "rättighet saknas för policy %s" + +#: catalog/aclchk.c:3402 +#, c-format +msgid "permission denied for procedure %s" +msgstr "rättighet saknas för procedur %s" + +#: catalog/aclchk.c:3405 +#, c-format +msgid "permission denied for publication %s" +msgstr "rättighet saknas för publicering %s" + +#: catalog/aclchk.c:3408 +#, c-format +msgid "permission denied for routine %s" +msgstr "rättighet saknas för rutin %s" + +#: catalog/aclchk.c:3411 +#, c-format +msgid "permission denied for schema %s" +msgstr "rättighet saknas för schema %s" + +#: catalog/aclchk.c:3414 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 +#: commands/sequence.c:1864 +#, c-format +msgid "permission denied for sequence %s" +msgstr "rättighet saknas för sekvens %s" + +#: catalog/aclchk.c:3417 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "rättighet saknas för statistikobjekt %s" + +#: catalog/aclchk.c:3420 +#, c-format +msgid "permission denied for subscription %s" +msgstr "rättighet saknas för prenumeration %s" + +#: catalog/aclchk.c:3423 +#, c-format +msgid "permission denied for table %s" +msgstr "rättighet saknas för tabell %s" + +#: catalog/aclchk.c:3426 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "rättighet saknas för tabellutrymme %s" + +#: catalog/aclchk.c:3429 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "rättighet saknas för textsökkonfigurering %s" + +#: catalog/aclchk.c:3432 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "rättighet saknas för textsökordlista %s" + +#: catalog/aclchk.c:3435 +#, c-format +msgid "permission denied for type %s" +msgstr "rättighet saknas för typ %s" + +#: catalog/aclchk.c:3438 +#, c-format +msgid "permission denied for view %s" +msgstr "rättighet saknas för vy %s" + +#: catalog/aclchk.c:3473 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "måste vara ägaren till aggregatet %s" + +#: catalog/aclchk.c:3476 +#, c-format +msgid "must be owner of collation %s" +msgstr "måste vara ägaren till jämförelsen %s" + +#: catalog/aclchk.c:3479 +#, c-format +msgid "must be owner of conversion %s" +msgstr "måste vara ägaren till konverteringen %s" + +#: catalog/aclchk.c:3482 +#, c-format +msgid "must be owner of database %s" +msgstr "måste vara ägaren till databasen %s" + +#: catalog/aclchk.c:3485 +#, c-format +msgid "must be owner of domain %s" +msgstr "måste vara ägaren av domänen %s" + +#: catalog/aclchk.c:3488 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "måste vara ägaren till händelseutlösaren %s" + +#: catalog/aclchk.c:3491 +#, c-format +msgid "must be owner of extension %s" +msgstr "måste vara ägaren till utökningen %s" + +#: catalog/aclchk.c:3494 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "måste vara ägaren till främmande data-omvandlaren %s" + +#: catalog/aclchk.c:3497 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "måste vara ägaren till främmande servern %s" + +#: catalog/aclchk.c:3500 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "måste vara ägaren till främmande tabellen %s" + +#: catalog/aclchk.c:3503 +#, c-format +msgid "must be owner of function %s" +msgstr "måste vara ägaren till funktionen %s" + +#: catalog/aclchk.c:3506 +#, c-format +msgid "must be owner of index %s" +msgstr "måste vara ägaren till indexet %s" + +#: catalog/aclchk.c:3509 +#, c-format +msgid "must be owner of language %s" +msgstr "måste vara ägaren till språket %s" + +#: catalog/aclchk.c:3512 +#, c-format +msgid "must be owner of large object %s" +msgstr "måste vara ägaren till stora objektet %s" + +#: catalog/aclchk.c:3515 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "måste vara ägaren till den materialiserade vyn %s" + +#: catalog/aclchk.c:3518 +#, c-format +msgid "must be owner of operator class %s" +msgstr "måste vara ägaren till operatorklassen %s" + +#: catalog/aclchk.c:3521 +#, c-format +msgid "must be owner of operator %s" +msgstr "måste vara ägaren till operatorn %s" + +#: catalog/aclchk.c:3524 +#, c-format +msgid "must be owner of operator family %s" +msgstr "måste vara ägaren till operatorfamiljen %s" + +#: catalog/aclchk.c:3527 +#, c-format +msgid "must be owner of procedure %s" +msgstr "måste vara ägaren till proceduren %s" + +#: catalog/aclchk.c:3530 +#, c-format +msgid "must be owner of publication %s" +msgstr "måste vara ägaren till publiceringen %s" + +#: catalog/aclchk.c:3533 +#, c-format +msgid "must be owner of routine %s" +msgstr "måste vara ägaren till rutinen %s" + +#: catalog/aclchk.c:3536 +#, c-format +msgid "must be owner of sequence %s" +msgstr "måste vara ägaren till sekvensen %s" + +#: catalog/aclchk.c:3539 +#, c-format +msgid "must be owner of subscription %s" +msgstr "måste vara ägaren till prenumerationen %s" + +#: catalog/aclchk.c:3542 +#, c-format +msgid "must be owner of table %s" +msgstr "måste vara ägaren till tabellen %s" + +#: catalog/aclchk.c:3545 +#, c-format +msgid "must be owner of type %s" +msgstr "måste vara ägaren till typen %s" + +#: catalog/aclchk.c:3548 +#, c-format +msgid "must be owner of view %s" +msgstr "måste vara ägaren till vyn %s" + +#: catalog/aclchk.c:3551 +#, c-format +msgid "must be owner of schema %s" +msgstr "måste vara ägaren till schemat %s" + +#: catalog/aclchk.c:3554 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "måste vara ägaren till statistikobjektet %s" + +#: catalog/aclchk.c:3557 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "måste vara ägaren till tabellutrymmet %s" + +#: catalog/aclchk.c:3560 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "måste vara ägaren till textsökkonfigurationen %s" + +#: catalog/aclchk.c:3563 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "måste vara ägaren till textsökordlistan %s" + +#: catalog/aclchk.c:3577 +#, c-format +msgid "must be owner of relation %s" +msgstr "måste vara ägaren till relationen %s" + +#: catalog/aclchk.c:3621 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "rättighet saknas för kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:3742 catalog/aclchk.c:3750 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "attribut %d i relation med OID %u existerar inte" + +#: catalog/aclchk.c:3823 catalog/aclchk.c:4733 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "relation med OID %u existerar inte" + +#: catalog/aclchk.c:3913 catalog/aclchk.c:5151 +#, c-format +msgid "database with OID %u does not exist" +msgstr "databas med OID %u finns inte" + +#: catalog/aclchk.c:3967 catalog/aclchk.c:4811 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2055 +#, c-format +msgid "function with OID %u does not exist" +msgstr "funktionen med OID %u existerar inte" + +#: catalog/aclchk.c:4021 catalog/aclchk.c:4837 +#, c-format +msgid "language with OID %u does not exist" +msgstr "språk med OID %u existerar inte" + +#: catalog/aclchk.c:4185 catalog/aclchk.c:4909 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "schema med OID %u existerar inte" + +#: catalog/aclchk.c:4239 catalog/aclchk.c:4936 utils/adt/genfile.c:686 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "tabellutrymme med OID %u finns inte" + +#: catalog/aclchk.c:4298 catalog/aclchk.c:5070 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "främmande data-omvandlare med OID %u finns inte" + +#: catalog/aclchk.c:4360 catalog/aclchk.c:5097 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "främmande server med OID %u finns inte" + +#: catalog/aclchk.c:4420 catalog/aclchk.c:4759 utils/cache/typcache.c:378 +#: utils/cache/typcache.c:432 +#, c-format +msgid "type with OID %u does not exist" +msgstr "typ med OID %u existerar inte" + +#: catalog/aclchk.c:4785 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "operator med OID %u existerar inte" + +#: catalog/aclchk.c:4962 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "operatorklass med OID %u existerar inte" + +#: catalog/aclchk.c:4989 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "operatorfamilj med OID %u existerar inte" + +#: catalog/aclchk.c:5016 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "textsökordlista med OID %u existerar inte" + +#: catalog/aclchk.c:5043 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "textsökkonfiguration med OID %u existerar inte" + +#: catalog/aclchk.c:5124 commands/event_trigger.c:475 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "händelseutlösare med OID %u existerar inte" + +#: catalog/aclchk.c:5177 commands/collationcmds.c:367 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "jämförelse med OID %u existerar inte" + +#: catalog/aclchk.c:5203 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "konvertering med OID %u existerar inte" + +#: catalog/aclchk.c:5244 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "utökning med OID %u existerar inte" + +#: catalog/aclchk.c:5271 commands/publicationcmds.c:794 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "publicering med OID %u existerar inte" + +#: catalog/aclchk.c:5297 commands/subscriptioncmds.c:1112 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "prenumeration med OID %u existerar inte" + +#: catalog/aclchk.c:5323 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "statistikobjekt med OID %u finns inte" + +#: catalog/catalog.c:485 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "måste vara superanvändare för att anropa pg_nextoid()" + +#: catalog/catalog.c:493 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() kan bara användas på systemkataloger" + +#: catalog/catalog.c:498 parser/parse_utilcmd.c:2191 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "index \"%s\" tillhör inte tabell \"%s\"" + +#: catalog/catalog.c:515 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "kolumnen \"%s\" är inte av typen oid" + +#: catalog/catalog.c:522 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "index \"%s\" är inte indexet för kolumnen \"%s\"" + +#: catalog/dependency.c:823 catalog/dependency.c:1061 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "kan inte ta bort %s eftersom %s behöver den" + +#: catalog/dependency.c:825 catalog/dependency.c:1063 +#, c-format +msgid "You can drop %s instead." +msgstr "Du kan ta bort %s i stället." + +#: catalog/dependency.c:933 catalog/pg_shdepend.c:640 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "kan inte ta bort %s eftersom den krävs av databassystemet" + +#: catalog/dependency.c:1129 +#, c-format +msgid "drop auto-cascades to %s" +msgstr "drop svämmar automatiskt över (cascades) till %s" + +#: catalog/dependency.c:1141 catalog/dependency.c:1150 +#, c-format +msgid "%s depends on %s" +msgstr "%s beror på %s" + +#: catalog/dependency.c:1162 catalog/dependency.c:1171 +#, c-format +msgid "drop cascades to %s" +msgstr "drop svämmar över (cascades) till %s" + +#: catalog/dependency.c:1179 catalog/pg_shdepend.c:769 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"och %d annat objekt (se serverloggen för en lista)" +msgstr[1] "" +"\n" +"och %d andra objekt (se serverloggen för en lista)" + +#: catalog/dependency.c:1191 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "kan inte ta bort %s eftersom andra objekt beror på den" + +#: catalog/dependency.c:1193 catalog/dependency.c:1194 +#: catalog/dependency.c:1200 catalog/dependency.c:1201 +#: catalog/dependency.c:1212 catalog/dependency.c:1213 +#: commands/tablecmds.c:1249 commands/tablecmds.c:13016 commands/user.c:1093 +#: commands/view.c:495 libpq/auth.c:334 replication/syncrep.c:1032 +#: storage/lmgr/deadlock.c:1154 storage/lmgr/proc.c:1350 utils/adt/acl.c:5329 +#: utils/adt/jsonfuncs.c:614 utils/adt/jsonfuncs.c:620 utils/misc/guc.c:6771 +#: utils/misc/guc.c:6807 utils/misc/guc.c:6877 utils/misc/guc.c:10975 +#: utils/misc/guc.c:11009 utils/misc/guc.c:11043 utils/misc/guc.c:11077 +#: utils/misc/guc.c:11112 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1195 catalog/dependency.c:1202 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Använd DROP ... CASCADE för att ta bort de beroende objekten också." + +#: catalog/dependency.c:1199 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "kan inte ta bort önskade objekt eftersom andra objekt beror på dem" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1208 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "drop svämmar över (cascades) till %d andra objekt" +msgstr[1] "drop svämmar över (cascades) till %d andra objekt" + +#: catalog/dependency.c:1875 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "konstant av typen %s kan inte användas här" + +#: catalog/heap.c:330 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "rättighet saknas för att skapa \"%s.%s\"" + +#: catalog/heap.c:332 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "Systemkatalogändringar är för tillfället inte tillåtna." + +#: catalog/heap.c:500 commands/tablecmds.c:2145 commands/tablecmds.c:2745 +#: commands/tablecmds.c:6175 +#, c-format +msgid "tables can have at most %d columns" +msgstr "tabeller kan ha som mest %d kolumner" + +#: catalog/heap.c:518 commands/tablecmds.c:6468 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "kolumnnamn \"%s\" står i konflikt med ett systemkolumnnamn" + +#: catalog/heap.c:534 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "kolumnnamn \"%s\" angiven mer än en gång" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:609 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "partitionsnyckelkolumn \"%s\" har pseudo-typ %s" + +#: catalog/heap.c:614 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "kolumn \"%s\" har pseudo-typ %s" + +#: catalog/heap.c:645 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "composite-typ %s kan inte vara en del av sig själv" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:700 +#, c-format +msgid "no collation was derived for partition key column %s with collatable type %s" +msgstr "ingen jämförelse kunde härledas för partitionsnyckelkolumn %s med jämförelsetyp %s" + +#: catalog/heap.c:706 commands/createas.c:203 commands/createas.c:486 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "ingen jämförelse kunde härledas för kolumn \"%s\" med jämförelsetyp %s" + +#: catalog/heap.c:1155 catalog/index.c:865 commands/tablecmds.c:3520 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "relationen \"%s\" finns redan" + +#: catalog/heap.c:1171 catalog/pg_type.c:428 catalog/pg_type.c:775 +#: commands/typecmds.c:238 commands/typecmds.c:250 commands/typecmds.c:719 +#: commands/typecmds.c:1125 commands/typecmds.c:1337 commands/typecmds.c:2124 +#, c-format +msgid "type \"%s\" already exists" +msgstr "typen \"%s\" existerar redan" + +#: catalog/heap.c:1172 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "En relation har en associerad typ med samma namn så du måste använda ett namn som inte krockar med någon existerande typ." + +#: catalog/heap.c:1201 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "pg_class heap OID-värde är inte satt i binärt uppgraderingsläge" + +#: catalog/heap.c:2400 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "kan inte lägga till NO INHERIT-villkor till partitionerad tabell \"%s\"" + +#: catalog/heap.c:2670 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "check-villkor \"%s\" finns redan" + +#: catalog/heap.c:2840 catalog/index.c:879 catalog/pg_constraint.c:668 +#: commands/tablecmds.c:8117 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "integritetsvillkor \"%s\" för relation \"%s\" finns redan" + +#: catalog/heap.c:2847 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "villkor \"%s\" står i konflikt med icke-ärvt villkor på relation \"%s\"" + +#: catalog/heap.c:2858 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "villkor \"%s\" står i konflikt med ärvt villkor på relation \"%s\"" + +#: catalog/heap.c:2868 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "villkor \"%s\" står i konflikt med NOT VALID-villkor på relation \"%s\"" + +#: catalog/heap.c:2873 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "slår samman villkor \"%s\" med ärvd definition" + +#: catalog/heap.c:2975 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "kan inte använda genererad kolumn \"%s\" i kolumngenereringsuttryck" + +#: catalog/heap.c:2977 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "En genererad kolumn kan inte referera till en annan genererad kolumn." + +#: catalog/heap.c:3029 +#, c-format +msgid "generation expression is not immutable" +msgstr "genereringsuttryck är inte immutable" + +#: catalog/heap.c:3057 rewrite/rewriteHandler.c:1192 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "kolumn \"%s\" har typ %s men default-uttryck har typen %s" + +#: catalog/heap.c:3062 commands/prepare.c:367 parser/parse_node.c:412 +#: parser/parse_target.c:589 parser/parse_target.c:869 +#: parser/parse_target.c:879 rewrite/rewriteHandler.c:1197 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Du måste skriva om eller typomvandla uttrycket." + +#: catalog/heap.c:3109 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "bara tabell \"%s\" kan refereras i check-villkoret" + +#: catalog/heap.c:3366 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "inget stöd för kombinationen ON COMMIT och främmande nyckel" + +#: catalog/heap.c:3367 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "Tabell \"%s\" refererar till \"%s\", men de har inte samma ON COMMIT-inställning." + +#: catalog/heap.c:3372 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "kan inte trunkera en tabell som refererars till i ett främmande nyckelvillkor" + +#: catalog/heap.c:3373 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "Tabell \"%s\" refererar till \"%s\"." + +#: catalog/heap.c:3375 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "Trunkera tabellen \"%s\" samtidigt, eller använd TRUNCATE ... CASCADE." + +#: catalog/index.c:219 parser/parse_utilcmd.c:2097 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "multipla primärnycklar för tabell \"%s\" tillåts inte" + +#: catalog/index.c:237 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "primärnycklar kan inte vara uttryck" + +#: catalog/index.c:254 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "primärnyckelkolumn \"%s\" är inte markerad NOT NULL" + +#: catalog/index.c:764 catalog/index.c:1843 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "användardefinierade index på systemkatalogen är inte möjligt" + +#: catalog/index.c:804 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för operatorklass \"%s\"" + +#: catalog/index.c:819 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "samtida indexskapande på systemkatalogtabeller stöds inte" + +#: catalog/index.c:828 catalog/index.c:1281 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "samtida indexskapande för uteslutningsvillkor stöds inte" + +#: catalog/index.c:837 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "delade index kan inte skapas efter initdb" + +#: catalog/index.c:857 commands/createas.c:252 commands/sequence.c:154 +#: parser/parse_utilcmd.c:210 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "relationen \"%s\" finns redan, hoppar över" + +#: catalog/index.c:907 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "pg_class index OID-värde är inte satt i binärt uppgraderingsläge" + +#: catalog/index.c:2128 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY måste vara första operationen i transaktion" + +#: catalog/index.c:2859 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "bygger index \"%s\" på tabell \"%s\" seriellt" + +#: catalog/index.c:2864 +#, c-format +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "bygger index \"%s\" på tabell \"%s\" och efterfrågar %d parallell arbetare" +msgstr[1] "bygger index \"%s\" på tabell \"%s\" och efterfrågar %d parallella arbetare" + +#: catalog/index.c:3492 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "kan inte omindexera temporära tabeller som tillhör andra sessioner" + +#: catalog/index.c:3503 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "kan inte omindexera angivet index i TOAST-tabell" + +#: catalog/index.c:3625 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "index \"%s\" omindexerades" + +#: catalog/index.c:3701 commands/indexcmds.c:3023 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "REINDEX på partitionerade tabeller är inte implementerat ännu, hoppar över \"%s\"" + +#: catalog/index.c:3756 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "kan inte omindexera ogiltigt index \"%s.%s\" på TOAST-tabell, hoppar över" + +#: catalog/namespace.c:257 catalog/namespace.c:461 catalog/namespace.c:553 +#: commands/trigger.c:5043 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "referenser till andra databaser är inte implementerat: \"%s.%s.%s\"" + +#: catalog/namespace.c:314 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "temporära tabeller kan inte anges med ett schemanamn" + +#: catalog/namespace.c:395 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "kunde inte ta lås på relationen \"%s.%s\"" + +#: catalog/namespace.c:400 commands/lockcmds.c:142 commands/lockcmds.c:227 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "kunde inte ta lås på relationen \"%s\"" + +#: catalog/namespace.c:428 parser/parse_relation.c:1357 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "relationen \"%s.%s\" existerar inte" + +#: catalog/namespace.c:433 parser/parse_relation.c:1370 +#: parser/parse_relation.c:1378 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "relationen \"%s\" existerar inte" + +#: catalog/namespace.c:499 catalog/namespace.c:3030 commands/extension.c:1519 +#: commands/extension.c:1525 +#, c-format +msgid "no schema has been selected to create in" +msgstr "inget schema har valts för att skapa i" + +#: catalog/namespace.c:651 catalog/namespace.c:664 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "kan inte skapa relationer i temporära scheman som tillhör andra sessioner" + +#: catalog/namespace.c:655 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "kan inte skapa temporär relation i icke-temporärt schema" + +#: catalog/namespace.c:670 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "bara temporära relationer får skapas i temporära scheman" + +#: catalog/namespace.c:2222 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "statistikobjektet \"%s\" existerar inte" + +#: catalog/namespace.c:2345 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "textsökparser \"%s\" finns inte" + +#: catalog/namespace.c:2471 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "textsökkatalog \"%s\" finns inte" + +#: catalog/namespace.c:2598 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "textsökmall \"%s\" finns inte" + +#: catalog/namespace.c:2724 commands/tsearchcmds.c:1194 +#: utils/cache/ts_cache.c:617 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "textsökkonfiguration \"%s\" finns inte" + +#: catalog/namespace.c:2837 parser/parse_expr.c:872 parser/parse_target.c:1228 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "referenser till andra databaser är inte implementerat: %s" + +#: catalog/namespace.c:2843 gram.y:14981 gram.y:16435 parser/parse_expr.c:879 +#: parser/parse_target.c:1235 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "ej korrekt kvalificerat namn (för många namn med punkt): %s" + +#: catalog/namespace.c:2973 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "kan inte flytta objekt in eller ut från temporära scheman" + +#: catalog/namespace.c:2979 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "kan inte flytta objekt in eller ut från TOAST-schema" + +#: catalog/namespace.c:3052 commands/schemacmds.c:256 commands/schemacmds.c:336 +#: commands/tablecmds.c:1194 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "schema \"%s\" existerar inte" + +#: catalog/namespace.c:3083 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "ej korrekt relationsnamn (för många namn med punkt): %s" + +#: catalog/namespace.c:3646 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "jämförelse \"%s\" för kodning \"%s\" finns inte" + +#: catalog/namespace.c:3701 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "konvertering \"%s\" finns inte" + +#: catalog/namespace.c:3965 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "rättighet saknas för att skapa temporära tabeller i databasen \"%s\"" + +#: catalog/namespace.c:3981 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "kan inte skapa temptabeller under återställning" + +#: catalog/namespace.c:3987 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "kan inte skapa temporära tabeller under en parallell operation" + +#: catalog/namespace.c:4286 commands/tablespace.c:1205 commands/variable.c:64 +#: utils/misc/guc.c:11144 utils/misc/guc.c:11222 +#, c-format +msgid "List syntax is invalid." +msgstr "List-syntaxen är ogiltig." + +#: catalog/objectaddress.c:1275 catalog/pg_publication.c:57 +#: commands/policy.c:95 commands/policy.c:375 commands/policy.c:465 +#: commands/tablecmds.c:230 commands/tablecmds.c:272 commands/tablecmds.c:1989 +#: commands/tablecmds.c:5626 commands/tablecmds.c:11089 +#, c-format +msgid "\"%s\" is not a table" +msgstr "\"%s\" är inte en tabell" + +#: catalog/objectaddress.c:1282 commands/tablecmds.c:242 +#: commands/tablecmds.c:5656 commands/tablecmds.c:15711 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "\"%s\" är inte en vy" + +#: catalog/objectaddress.c:1289 commands/matview.c:175 commands/tablecmds.c:248 +#: commands/tablecmds.c:15716 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "\"%s\" är inte en materialiserad vy" + +#: catalog/objectaddress.c:1296 commands/tablecmds.c:266 +#: commands/tablecmds.c:5659 commands/tablecmds.c:15721 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "\"%s\" är inte en främmande tabell" + +#: catalog/objectaddress.c:1337 +#, c-format +msgid "must specify relation and object name" +msgstr "måste ange relation och objektnamn" + +#: catalog/objectaddress.c:1413 catalog/objectaddress.c:1466 +#, c-format +msgid "column name must be qualified" +msgstr "kolumnnamn måste vara kvalificerat" + +#: catalog/objectaddress.c:1513 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "standardvärde för kolumn \"%s\" i relation \"%s\" existerar inte" + +#: catalog/objectaddress.c:1550 commands/functioncmds.c:133 +#: commands/tablecmds.c:258 commands/typecmds.c:263 commands/typecmds.c:3275 +#: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:845 +#: utils/adt/acl.c:4436 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "typen \"%s\" existerar inte" + +#: catalog/objectaddress.c:1669 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "operator %d (%s, %s) för %s finns inte" + +#: catalog/objectaddress.c:1700 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "funktion %d (%s, %s) för %s finns inte" + +#: catalog/objectaddress.c:1751 catalog/objectaddress.c:1777 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "användarmappning för användare \"%s\" på server \"%s\" finns inte" + +#: catalog/objectaddress.c:1766 commands/foreigncmds.c:430 +#: commands/foreigncmds.c:1012 commands/foreigncmds.c:1395 +#: foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "server \"%s\" finns inte" + +#: catalog/objectaddress.c:1833 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "publiceringsrelation \"%s\" i publicering \"%s\" finns inte" + +#: catalog/objectaddress.c:1895 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "okänd standard-ACL-objekttyp \"%c\"" + +#: catalog/objectaddress.c:1896 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Giltiga objekttyper är \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." + +#: catalog/objectaddress.c:1947 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "standard ACL för användare \"%s\" i schema \"%s\" på %s finns inte" + +#: catalog/objectaddress.c:1952 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "standard ACL för användare \"%s\" på %s finns inte" + +#: catalog/objectaddress.c:1979 catalog/objectaddress.c:2037 +#: catalog/objectaddress.c:2094 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "namn eller argumentlistor får inte innehålla null" + +#: catalog/objectaddress.c:2013 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "ej stöd för objekttyp \"%s\"" + +#: catalog/objectaddress.c:2033 catalog/objectaddress.c:2051 +#: catalog/objectaddress.c:2192 +#, c-format +msgid "name list length must be exactly %d" +msgstr "namnlistlängen måste vara exakt %d" + +#: catalog/objectaddress.c:2055 +#, c-format +msgid "large object OID may not be null" +msgstr "stort objekt-OID får inte vara null" + +#: catalog/objectaddress.c:2064 catalog/objectaddress.c:2127 +#: catalog/objectaddress.c:2134 +#, c-format +msgid "name list length must be at least %d" +msgstr "namnlistlängden måste vara minst %d" + +#: catalog/objectaddress.c:2120 catalog/objectaddress.c:2141 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "argumentlistans längd måste vara exakt %d" + +#: catalog/objectaddress.c:2393 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "måste vara ägaren till stort objekt %u" + +#: catalog/objectaddress.c:2408 commands/functioncmds.c:1445 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "måste vara ägaren till typ %s eller typ %s" + +#: catalog/objectaddress.c:2458 catalog/objectaddress.c:2475 +#, c-format +msgid "must be superuser" +msgstr "måste vara superanvändare" + +#: catalog/objectaddress.c:2465 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "måste ha rättigheten CREATEROLE" + +#: catalog/objectaddress.c:2544 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "okänd objekttyp \"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2772 +#, c-format +msgid "column %s of %s" +msgstr "kolumn %s av %s" + +#: catalog/objectaddress.c:2782 +#, c-format +msgid "function %s" +msgstr "funktion %s" + +#: catalog/objectaddress.c:2787 +#, c-format +msgid "type %s" +msgstr "typ %s" + +#: catalog/objectaddress.c:2817 +#, c-format +msgid "cast from %s to %s" +msgstr "typomvandling från %s till %s" + +#: catalog/objectaddress.c:2845 +#, c-format +msgid "collation %s" +msgstr "jämförelse %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2871 +#, c-format +msgid "constraint %s on %s" +msgstr "villkor %s på %s" + +#: catalog/objectaddress.c:2877 +#, c-format +msgid "constraint %s" +msgstr "villkor %s" + +#: catalog/objectaddress.c:2904 +#, c-format +msgid "conversion %s" +msgstr "konvertering %s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2943 +#, c-format +msgid "default value for %s" +msgstr "default-värde för %s" + +#: catalog/objectaddress.c:2952 +#, c-format +msgid "language %s" +msgstr "språk %s" + +#: catalog/objectaddress.c:2957 +#, c-format +msgid "large object %u" +msgstr "stort objekt %u" + +#: catalog/objectaddress.c:2962 +#, c-format +msgid "operator %s" +msgstr "operator %s" + +#: catalog/objectaddress.c:2994 +#, c-format +msgid "operator class %s for access method %s" +msgstr "operatorklass %s för accessmetod %s" + +#: catalog/objectaddress.c:3017 +#, c-format +msgid "access method %s" +msgstr "accessmetod %s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3059 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "operator %d (%s, %s) för %s: %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3109 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "funktion %d (%s, %s) för %s: %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3153 +#, c-format +msgid "rule %s on %s" +msgstr "regel %s på %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3191 +#, c-format +msgid "trigger %s on %s" +msgstr "utlösare %s på %s" + +#: catalog/objectaddress.c:3207 +#, c-format +msgid "schema %s" +msgstr "schema %s" + +#: catalog/objectaddress.c:3230 +#, c-format +msgid "statistics object %s" +msgstr "statistikobjekt %s" + +#: catalog/objectaddress.c:3257 +#, c-format +msgid "text search parser %s" +msgstr "textsökparser %s" + +#: catalog/objectaddress.c:3283 +#, c-format +msgid "text search dictionary %s" +msgstr "textsökordlista %s" + +#: catalog/objectaddress.c:3309 +#, c-format +msgid "text search template %s" +msgstr "textsökmall %s" + +#: catalog/objectaddress.c:3335 +#, c-format +msgid "text search configuration %s" +msgstr "textsökkonfiguration %s" + +#: catalog/objectaddress.c:3344 +#, c-format +msgid "role %s" +msgstr "roll %s" + +#: catalog/objectaddress.c:3357 +#, c-format +msgid "database %s" +msgstr "databas %s" + +#: catalog/objectaddress.c:3369 +#, c-format +msgid "tablespace %s" +msgstr "tabellutrymme %s" + +#: catalog/objectaddress.c:3378 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "främmande data-omvandlare %s" + +#: catalog/objectaddress.c:3387 +#, c-format +msgid "server %s" +msgstr "server %s" + +#: catalog/objectaddress.c:3415 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "användarmappning för %s på server %s" + +#: catalog/objectaddress.c:3460 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "standardrättigheter för nya relationer som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3464 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "standardrättigheter för nya relationer som tillhör rollen %s" + +#: catalog/objectaddress.c:3470 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "standardrättigheter för nya sekvenser som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3474 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "standardrättigheter för nya sekvenser som tillhör rollen %s" + +#: catalog/objectaddress.c:3480 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "standardrättigheter för nya funktioner som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3484 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "standardrättigheter för nya funktioner som tillhör rollen %s" + +#: catalog/objectaddress.c:3490 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "standardrättigheter för nya typer som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3494 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "standardrättigheter för nya typer som tillhör rollen %s" + +#: catalog/objectaddress.c:3500 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr " %zu)" +msgstr "servern försöke skicka för stort GSSAPI-paket (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:330 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "för stort GSSAPI-paket skickat av klienten (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:364 +msgid "GSSAPI unwrap error" +msgstr "GSSAPI-fel vid uppackning" + +#: libpq/be-secure-gssapi.c:369 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "inkommande GSSAPI-meddelande använde inte sekretess" + +#: libpq/be-secure-gssapi.c:525 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "för stort GSSAPI-paket skickat av klienten (%zu > %d)" + +#: libpq/be-secure-gssapi.c:547 +msgid "could not accept GSSAPI security context" +msgstr "kunde inte acceptera GSSSPI-säkerhetskontext" + +#: libpq/be-secure-gssapi.c:637 +msgid "GSSAPI size check error" +msgstr "GSSAPI-fel vid kontroll av storlek" + +#: libpq/be-secure-openssl.c:112 +#, c-format +msgid "could not create SSL context: %s" +msgstr "kunde inte skapa SSL-kontext: %s" + +#: libpq/be-secure-openssl.c:138 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "kunde inte ladda serverns certifikatfil \"%s\": %s" + +#: libpq/be-secure-openssl.c:158 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "privat nyckelfil \"%s\" kan inte laddas om eftersom den kräver en lösenordsfras" + +#: libpq/be-secure-openssl.c:163 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "kunde inte läsa in privata nyckelfilen \"%s\": %s" + +#: libpq/be-secure-openssl.c:172 +#, c-format +msgid "check of private key failed: %s" +msgstr "kontroll av privat nyckel misslyckades: %s" + +#: libpq/be-secure-openssl.c:184 libpq/be-secure-openssl.c:206 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "\"%s\"-inställning \"%s\" stöds inte av detta bygge" + +#: libpq/be-secure-openssl.c:194 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "kunde inte sätta minimal SSL-protokollversion" + +#: libpq/be-secure-openssl.c:216 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "kunde inte sätta maximal SSL-protokollversion" + +#: libpq/be-secure-openssl.c:232 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "kunde inte sätta SSL-protokollversionsintervall" + +#: libpq/be-secure-openssl.c:233 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "\"%s\" får inte vara högre än \"%s\"" + +#: libpq/be-secure-openssl.c:257 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "kunde inte sätta kryptolistan (inga giltiga krypton är tillgängliga)" + +#: libpq/be-secure-openssl.c:275 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "kunde inte ladda root-certifikatfilen \"%s\": %s" + +#: libpq/be-secure-openssl.c:302 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "kunde inte ladda certifikatåterkallningslistfil \"%s\" för SSL-certifikat: %s" + +#: libpq/be-secure-openssl.c:378 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "kunde inte initiera SSL-uppkoppling: SSL-kontex ej uppsatt" + +#: libpq/be-secure-openssl.c:386 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "kunde inte initiera SSL-uppkoppling: %s" + +#: libpq/be-secure-openssl.c:394 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "kunde inte sätta SSL-uttag (socket): %s" + +#: libpq/be-secure-openssl.c:449 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "kunde inte acceptera SSL-uppkoppling: %m" + +#: libpq/be-secure-openssl.c:453 libpq/be-secure-openssl.c:506 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "kunde inte starta SSL-anslutning: hittade EOF" + +#: libpq/be-secure-openssl.c:492 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "kunde inte acceptera SSL-uppkoppling: %s" + +#: libpq/be-secure-openssl.c:495 +#, c-format +msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." +msgstr "Detta kan tyda på att servern inte stöder någon SSL-protokolversion mellan %s och %s." + +#: libpq/be-secure-openssl.c:511 libpq/be-secure-openssl.c:642 +#: libpq/be-secure-openssl.c:706 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "okänd SSL-felkod: %d" + +#: libpq/be-secure-openssl.c:553 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "SSL-certifikatets \"comman name\" innehåller null-värden" + +#: libpq/be-secure-openssl.c:631 libpq/be-secure-openssl.c:690 +#, c-format +msgid "SSL error: %s" +msgstr "SSL-fel: %s" + +#: libpq/be-secure-openssl.c:871 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "kunde inte öppna DH-parameterfil \"%s\": %m" + +#: libpq/be-secure-openssl.c:883 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "kunde inte ladda DH-parameterfil: %s" + +#: libpq/be-secure-openssl.c:893 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "ogiltiga DH-parametrar: %s" + +#: libpq/be-secure-openssl.c:901 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "ogiltiga DH-parametrar: p är inte ett primtal" + +#: libpq/be-secure-openssl.c:909 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "ogiltiga DH-parametrar: varken lämplig generator eller säkert primtal" + +#: libpq/be-secure-openssl.c:1065 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: kunde inte ladda DH-parametrar" + +#: libpq/be-secure-openssl.c:1073 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: kunde inte sätta DH-parametrar: %s" + +#: libpq/be-secure-openssl.c:1100 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: okänt kurvnamn: %s" + +#: libpq/be-secure-openssl.c:1109 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: kunde inte skapa nyckel" + +#: libpq/be-secure-openssl.c:1137 +msgid "no SSL error reported" +msgstr "inget SSL-fel rapporterat" + +#: libpq/be-secure-openssl.c:1141 +#, c-format +msgid "SSL error code %lu" +msgstr "SSL-felkod %lu" + +#: libpq/be-secure.c:122 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "SSL-uppkoppling från \"%s\"" + +#: libpq/be-secure.c:207 libpq/be-secure.c:303 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "avslutar anslutning på grund av att postmaster stängde oväntat ner" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "Rollen \"%s\" finns inte." + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "Användaren \"%s\" har inget lösenord satt." + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "Användaren \"%s\" har ett utgånget lösenord." + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "Användaren \"%s\" har ett lösenord som inte kan användas med MD5-autentisering." + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "Lösenordet matchar inte för användare \"%s\"." + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "Lösenordet för användare \"%s\" är på ett okänt format." + +#: libpq/hba.c:235 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "autentiseringsfil-token för lång, hoppar över: \"%s\"" + +#: libpq/hba.c:407 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "kunde inte öppna sekundär autentiseringsfil \"@%s\" som \"%s\": %m" + +#: libpq/hba.c:509 +#, c-format +msgid "authentication file line too long" +msgstr "autentiseringsfilrad är för lång" + +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1013 libpq/hba.c:1022 +#: libpq/hba.c:1035 libpq/hba.c:1056 libpq/hba.c:1069 libpq/hba.c:1089 +#: libpq/hba.c:1111 libpq/hba.c:1123 libpq/hba.c:1179 libpq/hba.c:1199 +#: libpq/hba.c:1213 libpq/hba.c:1232 libpq/hba.c:1243 libpq/hba.c:1258 +#: libpq/hba.c:1276 libpq/hba.c:1292 libpq/hba.c:1304 libpq/hba.c:1341 +#: libpq/hba.c:1382 libpq/hba.c:1395 libpq/hba.c:1417 libpq/hba.c:1430 +#: libpq/hba.c:1442 libpq/hba.c:1460 libpq/hba.c:1510 libpq/hba.c:1554 +#: libpq/hba.c:1565 libpq/hba.c:1581 libpq/hba.c:1598 libpq/hba.c:1608 +#: libpq/hba.c:1666 libpq/hba.c:1704 libpq/hba.c:1726 libpq/hba.c:1738 +#: libpq/hba.c:1825 libpq/hba.c:1843 libpq/hba.c:1937 libpq/hba.c:1956 +#: libpq/hba.c:1985 libpq/hba.c:1998 libpq/hba.c:2021 libpq/hba.c:2043 +#: libpq/hba.c:2057 tsearch/ts_locale.c:217 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "rad %d i konfigurationsfil \"%s\"" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:865 +#, c-format +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "autentiseringsflagga \"%s\" är bara giltig för autentiseringsmetoder %s" + +#: libpq/hba.c:885 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "autentiseringsmetod \"%s\" kräver att argumentet \"%s\" är satt" + +#: libpq/hba.c:913 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "saknar post i fil \"%s\" vid slutet av rad %d" + +#: libpq/hba.c:924 +#, c-format +msgid "multiple values in ident field" +msgstr "multipla värden i ident-fält" + +#: libpq/hba.c:973 +#, c-format +msgid "multiple values specified for connection type" +msgstr "multipla värden angivna för anslutningstyp" + +#: libpq/hba.c:974 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "Ange exakt en anslutningstyp per rad." + +#: libpq/hba.c:988 +#, c-format +msgid "local connections are not supported by this build" +msgstr "lokala anslutningar stöds inte av detta bygge" + +#: libpq/hba.c:1011 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "hostssl-post kan inte matcha då SSL är avslaget" + +#: libpq/hba.c:1012 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "Sätt ssl = on i postgresql.conf." + +#: libpq/hba.c:1020 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "hostssl-post kan inte matcha då SSL inte stöds i detta bygge" + +#: libpq/hba.c:1021 +#, c-format +msgid "Compile with --with-openssl to use SSL connections." +msgstr "Kompilera med --with-openssl för att använda SSL-anslutningar." + +#: libpq/hba.c:1033 +#, c-format +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "hostgssenc-post kan inte matcha då GSSAPI inte stöds i detta bygge" + +#: libpq/hba.c:1034 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "Kompilera med --with-gssapi för att använda GSSAPI-anslutningar." + +#: libpq/hba.c:1054 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "ogiltig anslutningstyp \"%s\"" + +#: libpq/hba.c:1068 +#, c-format +msgid "end-of-line before database specification" +msgstr "slut-på-rad innan databasspecifikation" + +#: libpq/hba.c:1088 +#, c-format +msgid "end-of-line before role specification" +msgstr "slut-på-rad innan rollspecifikation" + +#: libpq/hba.c:1110 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "slut-på-rad före IP-adressangivelse" + +#: libpq/hba.c:1121 +#, c-format +msgid "multiple values specified for host address" +msgstr "multipla värden angivna för värdnamn" + +#: libpq/hba.c:1122 +#, c-format +msgid "Specify one address range per line." +msgstr "Ange ett adressintervall per rad." + +#: libpq/hba.c:1177 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "ogiltig IP-adress \"%s\": %s" + +#: libpq/hba.c:1197 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "får inte ange både värdnamn och CIDR-mask: \"%s\"" + +#: libpq/hba.c:1211 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "ogiltig CIDR-mask i adress \"%s\"" + +#: libpq/hba.c:1230 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "slut-på-fil innan nätmask-angivelse" + +#: libpq/hba.c:1231 +#, c-format +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "Ange adressintervall på CIDR-format eller ange en separat nätmask." + +#: libpq/hba.c:1242 +#, c-format +msgid "multiple values specified for netmask" +msgstr "multipla värden angivna för nätmask" + +#: libpq/hba.c:1256 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "ogiltig IP-mask \"%s\": %s" + +#: libpq/hba.c:1275 +#, c-format +msgid "IP address and mask do not match" +msgstr "IP-adress och mask matchar inte varandra" + +#: libpq/hba.c:1291 +#, c-format +msgid "end-of-line before authentication method" +msgstr "slut-på-rad innan autentiseringsmetod" + +#: libpq/hba.c:1302 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "multipla värden angivna för autentiseringstyp" + +#: libpq/hba.c:1303 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "Ange exakt en autentiseringstyp per rad." + +#: libpq/hba.c:1380 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "ogiltig autentiseringsmetod \"%s\"" + +#: libpq/hba.c:1393 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "ogiltig autentiseringsmetod \"%s\": stöds inte av detta bygge" + +#: libpq/hba.c:1416 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "gssapi-autentisering stöds ej på lokala uttag (socket)" + +#: libpq/hba.c:1429 +#, c-format +msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +msgstr "GSSAPI-kryptering stöder bara gss-, trust- eller reject-autentisering" + +#: libpq/hba.c:1441 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "peer-autentisering stöds bara på logala uttag (socket)" + +#: libpq/hba.c:1459 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "cert-autentisering stöds bara för hostssl-anslutningar" + +#: libpq/hba.c:1509 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "autentiseringsflagga et på formatet namn=värde: %s" + +#: libpq/hba.c:1553 +#, c-format +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "kan inte använda ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter eller ldapurl tillsammans med ldapprefix" + +#: libpq/hba.c:1564 +#, c-format +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "autentiseringsmetoden \"ldap\" kräver att argumenten \"ldapbasedn\", \"ldapprefix\" eller \"ldapsuffix\" är satta" + +#: libpq/hba.c:1580 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "kan inte använda ldapsearchattribute tillsammans med ldapsearchfilter" + +#: libpq/hba.c:1597 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "listan med RADIUS-servrar kan inte vara tom" + +#: libpq/hba.c:1607 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "listan med RADIUS-hemligheter kan inte vara tom" + +#: libpq/hba.c:1660 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "antalet %s (%d) måste vara 1 eller samma som antalet %s (%d)" + +#: libpq/hba.c:1694 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi och cert" + +#: libpq/hba.c:1703 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert kan bara konfigureras för \"hostssl\"-rader" + +#: libpq/hba.c:1725 +#, c-format +msgid "clientcert cannot be set to \"no-verify\" when using \"cert\" authentication" +msgstr "clientcert kan inte vara satt till \"no-verify\" när man använder \"cert\"-autentisering" + +#: libpq/hba.c:1737 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "ogiltigt värde för clientcert: \"%s\"" + +#: libpq/hba.c:1771 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "kunde inte parsa LDAP-URL \"%s\": %s" + +#: libpq/hba.c:1782 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "ej stöd för LDAP-URL-schema: %s" + +#: libpq/hba.c:1806 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "LDAP-URL:er stöds inte på denna platform" + +#: libpq/hba.c:1824 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "ogiltigt ldap-schema-värde: \"%s\"" + +#: libpq/hba.c:1842 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "ogiltigt LDAP-portnummer \"%s\"" + +#: libpq/hba.c:1888 libpq/hba.c:1895 +msgid "gssapi and sspi" +msgstr "gssapi och sspi" + +#: libpq/hba.c:1904 libpq/hba.c:1913 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1935 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "kunde inte parsa RADIUS-serverlista \"%s\"" + +#: libpq/hba.c:1983 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "kunde inte parsa RADIUS-portlista \"%s\"" + +#: libpq/hba.c:1997 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "ogiltigt RADIUS-portnummer: \"%s\"" + +#: libpq/hba.c:2019 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "kunde inte parsa RADIUS-hemlighetlista: \"%s\"" + +#: libpq/hba.c:2041 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "kunde inte parsa RADIUS-identifierarlista: \"%s\"" + +#: libpq/hba.c:2055 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "okänd autentiseringsflaggnamn: \"%s\"" + +#: libpq/hba.c:2250 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "konfigurationsfil \"%s\" innehåller inga poster" + +#: libpq/hba.c:2768 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "ogiltigt reguljärt uttryck \"%s\": %s" + +#: libpq/hba.c:2828 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "matchning av reguljärt uttryck för \"%s\" misslyckades: %s" + +#: libpq/hba.c:2847 +#, c-format +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "reguljärt uttryck \"%s\" har inga deluttryck som krävs för bakåtreferens i \"%s\"" + +#: libpq/hba.c:2943 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "givet användarnamn (%s) och autentiserat användarnamn (%s) matchar inte" + +#: libpq/hba.c:2963 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "ingen träff i användarmappning \"%s\" för användare \"%s\" autentiserad som \"%s\"" + +#: libpq/hba.c:2996 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "kunde inte öppna användarmappningsfil \"%s\": %m" + +#: libpq/pqcomm.c:218 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "kunde inte sätta uttag (socket) till ickeblockerande läge: %m" + +#: libpq/pqcomm.c:372 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "Sökväg till unixdomänuttag \"%s\" är för lång (maximalt %d byte)" + +#: libpq/pqcomm.c:393 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "kunde inte översätta värdnamn \"%s\", service \"%s\" till adress: %s" + +#: libpq/pqcomm.c:397 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "kunde inte översätta service \"%s\" till adress: %s" + +#: libpq/pqcomm.c:424 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "kunde inte binda till alla efterfrågade adresser: MAXLISTEN (%d) överskriden" + +#: libpq/pqcomm.c:433 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:437 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:442 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:447 +#, c-format +msgid "unrecognized address family %d" +msgstr "ej igenkänd adressfamilj %d" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:473 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "kunde inte skapa %s-uttag för adress \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:499 +#, c-format +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "setsockopt(SO_REUSEADDR) misslyckades för %s-adress \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:516 +#, c-format +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "setsockopt(IPV6_V6ONLY) misslyckades för %s-adress \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:536 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "kunde inte binda %s-adress \"%s\": %m" + +#: libpq/pqcomm.c:539 +#, c-format +msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +msgstr "Kör en annan postmaster redan på port %d? Om inte, ta bort uttagsfil \"%s\" och försök igen." + +#: libpq/pqcomm.c:542 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "Kör en annan postmaster redan på port %d? Om inte, vänta några sekunder och försök igen." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:575 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "kunde inte lyssna på %s-adress \"%s\": %m" + +#: libpq/pqcomm.c:584 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "lyssnar på Unix-uttag (socket) \"%s\"" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:590 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "lyssnar på %s-adress \"%s\", port %d" + +#: libpq/pqcomm.c:673 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "gruppen \"%s\" existerar inte" + +#: libpq/pqcomm.c:683 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "kunde inte sätta gruppen på filen \"%s\": %m" + +#: libpq/pqcomm.c:694 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "kunde inte sätta rättigheter på filen \"%s\": %m" + +#: libpq/pqcomm.c:724 +#, c-format +msgid "could not accept new connection: %m" +msgstr "kunde inte acceptera ny uppkoppling: %m" + +#: libpq/pqcomm.c:914 +#, c-format +msgid "there is no client connection" +msgstr "det finns ingen klientanslutning" + +#: libpq/pqcomm.c:965 libpq/pqcomm.c:1061 +#, c-format +msgid "could not receive data from client: %m" +msgstr "kunde inte ta emot data från klient: %m" + +#: libpq/pqcomm.c:1206 tcop/postgres.c:4142 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "stänger anslutning då protokollsynkroniseringen tappades" + +#: libpq/pqcomm.c:1272 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "oväntat EOF inom meddelandelängdord" + +#: libpq/pqcomm.c:1283 +#, c-format +msgid "invalid message length" +msgstr "ogiltig meddelandelängd" + +#: libpq/pqcomm.c:1305 libpq/pqcomm.c:1318 +#, c-format +msgid "incomplete message from client" +msgstr "inkomplett meddelande från klient" + +#: libpq/pqcomm.c:1451 +#, c-format +msgid "could not send data to client: %m" +msgstr "kunde inte skicka data till klient: %m" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "ingen data kvar i meddelandet" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1471 utils/adt/rowtypes.c:567 +#, c-format +msgid "insufficient data left in message" +msgstr "otillräckligt med data kvar i meddelande" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "ogiltig sträng i meddelande" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "ogiltigt meddelandeformat" + +#: main/main.c:246 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: WSAStartup misslyckades: %d\n" + +#: main/main.c:310 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%s är PostgreSQL-servern.\n" +"\n" + +#: main/main.c:311 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Användning:\n" +" %s [FLAGGA]...\n" +"\n" + +#: main/main.c:312 +#, c-format +msgid "Options:\n" +msgstr "Flaggor:\n" + +#: main/main.c:313 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS antalet delade buffertar\n" + +#: main/main.c:314 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NAMN=VÄRDE sätt körparameter\n" + +#: main/main.c:315 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NAMN skriv ut värde av runtime-parameter, avsluta sen\n" + +#: main/main.c:316 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 debug-nivå\n" + +#: main/main.c:317 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D DATADIR databaskatalog\n" + +#: main/main.c:318 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e använd europeiskt datumformat för indata (DMY)\n" + +#: main/main.c:319 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F slå av fsync\n" + +#: main/main.c:320 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h VÄRDNAMN värdnamn eller IP-adress att lyssna på\n" + +#: main/main.c:321 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i tillåt TCP/IP-uppkopplingar\n" + +#: main/main.c:322 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k KATALOG plats för unix-domän-uttag (socket)\n" + +#: main/main.c:324 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l tillåt SSL-anslutningar\n" + +#: main/main.c:326 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-ANSLUT maximalt antal tillåtna anslutningar\n" + +#: main/main.c:327 +#, c-format +msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr " -o FLAGGOR skicka \"FLAGGOR\" till varje serverprocess (obsolet)\n" + +#: main/main.c:328 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT portnummer att lyssna på\n" + +#: main/main.c:329 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s visa statistik efter varje fråga\n" + +#: main/main.c:330 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM ställ in mängden minne för sorteringar (i kB)\n" + +#: main/main.c:331 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: main/main.c:332 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NAMN=VÄRDE sätt parameter (som används under körning)\n" + +#: main/main.c:333 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config beskriv konfigurationsparametrar, avsluta sedan\n" + +#: main/main.c:334 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denna hjälp, avsluta sedan\n" + +#: main/main.c:336 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"Utvecklarflaggor:\n" + +#: main/main.c:337 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h förbjud användning av vissa plan-typer\n" + +#: main/main.c:338 +#, c-format +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr " -n initiera inte delat minne på nytt efter onormal avstängning\n" + +#: main/main.c:339 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O tillåt strukturändring av systemtabeller\n" + +#: main/main.c:340 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P stäng av systemindex\n" + +#: main/main.c:341 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex visa tidtagning efter varje fråga\n" + +#: main/main.c:342 +#, c-format +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr " -T skicka SIGSTOP till alla serverprocesser om en dör\n" + +#: main/main.c:343 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr " -W NUM vänta NUM sekunder för att tillåta att en debugger kopplas in\n" + +#: main/main.c:345 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"Flaggor för enanvändarläge:\n" + +#: main/main.c:346 +#, c-format +msgid " --single selects single-user mode (must be first argument)\n" +msgstr " --single väljer enanvändarläge (måste vara första argumentet)\n" + +#: main/main.c:347 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAMN databasnamn (standard är användarnamnet)\n" + +#: main/main.c:348 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 överskugga debug-nivå\n" + +#: main/main.c:349 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E skriv ut sats före körning\n" + +#: main/main.c:350 +#, c-format +msgid " -j do not use newline as interactive query delimiter\n" +msgstr " -j använd inte nyrad som en interaktiv frågeavskiljare\n" + +#: main/main.c:351 main/main.c:356 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r FILNAMN skicka stdout och stderr till angiven fil\n" + +#: main/main.c:353 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"Flaggor för bootstrap-läge:\n" + +#: main/main.c:354 +#, c-format +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot väljer bootstrap-läge (måste vara första argumentet)\n" + +#: main/main.c:355 +#, c-format +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr " DBNAMN databasnamn (krävs i bootstrap-läge)\n" + +#: main/main.c:357 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM intern användning\n" + +#: main/main.c:359 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Vänligen läs dokumentationen för en komplett lista av körningsinställningar\n" +"och hur man anger dem på kommandoraden eller i konfigurationsfilen.\n" +"\n" +"Rapportera buggar till <%s>.\n" + +#: main/main.c:363 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "hemsida för %s: <%s>\n" + +#: main/main.c:374 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Att köra PostgreSQL-servern som \"root\" tillåts inte.\n" +"Servern måste starts av ett icke priviligerat användare-ID för att förhindra\n" +"ev. säkehetsproblem. Se dokumentationen för mer information om hur man\n" +"startar servern på rätt sätt.\n" + +#: main/main.c:391 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: riktig och effektiv användar-ID måste matcha varandra\n" + +#: main/main.c:398 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Det är inte tillåtet för en användare med administratörsrättigheter att köra\n" +"PostgreSQL.\n" +"Servern måste starts av ett icke priviligerat användare-ID för att förhindra\n" +"ev. säkehetsproblem. Se dokumentationen för mer information om hur man startar\n" +"servern på rätt sätt.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "utökningsbar nodtyp \"%s\" finns redan" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "ExtensibleNodeMethods \"%s\" har inte registerats" + +#: nodes/nodeFuncs.c:122 nodes/nodeFuncs.c:153 parser/parse_coerce.c:2208 +#: parser/parse_coerce.c:2317 parser/parse_coerce.c:2352 +#: parser/parse_expr.c:2207 parser/parse_func.c:701 parser/parse_oper.c:967 +#: utils/fmgr/funcapi.c:528 +#, c-format +msgid "could not find array type for data type %s" +msgstr "kunde inte hitta array-typ för datatyp %s" + +#: nodes/params.c:359 +#, c-format +msgid "portal \"%s\" with parameters: %s" +msgstr "portal \"%s\" med parametrar: %s" + +#: nodes/params.c:362 +#, c-format +msgid "unnamed portal with parameters: %s" +msgstr "ej namngiven portal med parametrar: %s" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN stöds bara med villkor som är merge-joinbara eller hash-joinbara" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1193 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s kan inte appliceras på den nullbara sidan av en outer join" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1922 parser/analyze.c:1639 parser/analyze.c:1855 +#: parser/analyze.c:2715 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s tillåẗs inte med UNION/INTERSECT/EXCEPT" + +#: optimizer/plan/planner.c:2509 optimizer/plan/planner.c:4162 +#, c-format +msgid "could not implement GROUP BY" +msgstr "kunde inte implementera GROUP BY" + +#: optimizer/plan/planner.c:2510 optimizer/plan/planner.c:4163 +#: optimizer/plan/planner.c:4890 optimizer/prep/prepunion.c:1045 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "Några av datatyperna stöder bara hash:ning medan andra bara stöder sortering." + +#: optimizer/plan/planner.c:4889 +#, c-format +msgid "could not implement DISTINCT" +msgstr "kunde inte implementera DISTINCT" + +#: optimizer/plan/planner.c:5737 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "kunde inte implementera fönster-PARTITION BY" + +#: optimizer/plan/planner.c:5738 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "Fönsterpartitioneringskolumner måsta ha en sorterbar datatyp." + +#: optimizer/plan/planner.c:5742 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "kunde inte implementera fönster-ORDER BY" + +#: optimizer/plan/planner.c:5743 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Fönsterordningskolumner måste ha en sorterbar datatyp." + +#: optimizer/plan/setrefs.c:451 +#, c-format +msgid "too many range table entries" +msgstr "för många element i \"range table\"" + +#: optimizer/prep/prepunion.c:508 +#, c-format +msgid "could not implement recursive UNION" +msgstr "kunde inte implementera rekursiv UNION" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Alla kolumndatatyper måsta vara hash-bara." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1044 +#, c-format +msgid "could not implement %s" +msgstr "kunde inte implementera %s" + +#: optimizer/util/clauses.c:4747 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "SQL-funktion \"%s\" vid inline:ing" + +#: optimizer/util/plancat.c:132 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "kan inte accessa temporära eller ologgade relationer under återställning" + +#: optimizer/util/plancat.c:662 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "inferens av unikt index för hel rad stöds inte" + +#: optimizer/util/plancat.c:679 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "villkor för ON CONFLICT-klausul har inget associerat index" + +#: optimizer/util/plancat.c:729 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE stöds inte med uteslutningsvillkor" + +#: optimizer/util/plancat.c:834 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "finns inget unik eller uteslutningsvillkor som matchar ON CONFLICT-specifikationen" + +#: parser/analyze.c:705 parser/analyze.c:1401 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "VÄRDE-listor måste alla ha samma längd" + +#: parser/analyze.c:904 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT har fler uttryck än målkolumner" + +#: parser/analyze.c:922 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT har fler målkolumner än uttryck" + +#: parser/analyze.c:926 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "Imatningskällan är ett raduttryck som innehåller samma antal kolumner som INSERT:en förväntade sig. Glömde du använda extra parenteser?" + +#: parser/analyze.c:1210 parser/analyze.c:1612 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO tillåts inte här" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1542 parser/analyze.c:2894 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s kan inte appliceras på VÄRDEN" + +#: parser/analyze.c:1777 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "ogiltig UNION/INTERSECT/EXCEPT ORDER BY-klausul" + +#: parser/analyze.c:1778 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "Bara kolumnnamn i resultatet kan användas, inte uttryck eller funktioner." + +#: parser/analyze.c:1779 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "Lägg till uttrycket/funktionen till varje SELECT eller flytta UNION:en in i en FROM-klausul." + +#: parser/analyze.c:1845 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO tillåts bara i den första SELECT i UNION/INTERSECT/EXCEPT" + +#: parser/analyze.c:1917 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "UNION/INTERSECT/EXCEPT-medlemssats kan inte referera till andra relationer på samma frågenivå" + +#: parser/analyze.c:2004 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "varje %s-fråga måste ha samma antal kolumner" + +#: parser/analyze.c:2426 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNING måste ha minst en kolumn" + +#: parser/analyze.c:2467 +#, c-format +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "kan inte ange både SCROLL och NO SCROLL" + +#: parser/analyze.c:2486 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR får inte innehålla datamodifierande satser i WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2494 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s stöds inte" + +#: parser/analyze.c:2497 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "Hållbara markörer måste vara READ ONLY." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2505 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s stöds inte" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2516 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %s stöds inte" + +#: parser/analyze.c:2519 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Okänsliga markörer måste vara READ ONLY." + +#: parser/analyze.c:2585 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "materialiserade vyer får inte innehålla datamodifierande satser i WITH" + +#: parser/analyze.c:2595 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "materialiserade vyer får inte använda temporära tabeller eller vyer" + +#: parser/analyze.c:2605 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "materialiserade vyer kan inte defineras med bundna parametrar" + +#: parser/analyze.c:2617 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "materialiserad vyer kan inte vara ologgade" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2722 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s tillåts inte med DISTINCT-klausul" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2729 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s tillåts inte med GROUP BY-klausul" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2736 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s tillåts inte med HAVING-klausul" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2743 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s tillåts inte med aggregatfunktioner" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2750 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s tillåts inte med fönsterfunktioner" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2757 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s tillåts inte med mängdreturnerande funktioner i mållistan" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2836 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%s: måste ange okvalificerade relationsnamn" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2867 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s kan inte appliceras på en join" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2876 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s kan inte appliceras på en funktion" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2885 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s kan inte appliceras på tabellfunktion" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2903 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s kan inte appliceras på en WITH-fråga" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2912 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s kan inte appliceras på en namngiven tupellagring" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2932 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "relationen \"%s\" i %s-klausul hittades inte i FROM-klausul" + +#: parser/parse_agg.c:220 parser/parse_oper.c:222 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "kunde inte identifiera en jämförelseoperator för typ %s" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "Aggregat med DISTINCT måste kunna sortera sina indata." + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING måste ha färre än 32 argument" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "aggregatfunktioner tillåts inte i JOIN-villkor" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "gruppoperationer tillåts inte i JOIN-villkor" + +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "aggregatfunktioner tillåts inte i FROM-klausul på sin egen frågenivå" + +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "gruppoperationer tillåts inte i FROM-klausul på sin egen frågenivå" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "aggregatfunktioner tillåts inte i funktioner i FROM" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "gruppoperationer tillåts inte i funktioner i FROM" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "aggregatfunktioner tillåts inte i policyuttryck" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "gruppoperationer tillåts inte i policyuttryck" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "aggregatfunktioner tillåts inte i fönster-RANGE" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "grupperingsoperationer tillåts inte i fönster-RANGE" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "aggregatfunktioner tillåts inte i fönster-RADER" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "grupperingsfunktioner tillåts inte i fönster-RADER" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "aggregatfunktioner tillåts inte i fönster-GROUPS" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "grupperingsfunktioner tillåts inte i fönster-GROUPS" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "aggregatfunktioner tillåts inte i check-villkor" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "gruppoperationer tillåts inte i check-villkor" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "aggregatfunktioner tillåts inte i DEFAULT-uttryck" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "grupperingsoperationer tillåts inte i DEFAULT-uttryck" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "aggregatfunktioner tillåts inte i indexuttryck" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "gruppoperationer tillåts inte i indexuttryck" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "aggregatfunktionsanrop tillåts inte i indexpredikat" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "gruppoperationer tillåts inte i indexpredikat" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "aggregatfunktioner tillåts inte i transform-uttryck" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in transform expressions" +msgstr "gruppoperationer tillåts inte i transforme-uttryck" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "aggregatfunktioner tillåts inte i EXECUTE-parametrar" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "gruppoperationer tillåts inte i EXECUTE-parametrar" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "aggregatfunktioner tillåts inte i WHEN-utlösarvillkor" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "gruppoperationer tillåts inte i WHEN-utlösarvillkor" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in partition bound" +msgstr "aggregatfunktioner tillåts inte i partitionsgräns" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in partition bound" +msgstr "gruppoperationer tillåts inte i partitionsgräns" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "aggregatfunktioner tillåts inte i partitionsnyckeluttryck" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "gruppoperationer tillåts inte i partitionsnyckeluttryck" + +#: parser/parse_agg.c:526 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "aggregatfunktioner tillåts inte i kolumngenereringsuttryck" + +#: parser/parse_agg.c:528 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "gruppoperationer tillåts inte i kolumngenereringsuttryck" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "aggregatfunktioner tillåts inte i CALL-argument" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "gruppoperationer tillåts inte i CALL-argument" + +#: parser/parse_agg.c:542 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "aggregatfunktioner tillåts inte i COPY FROM WHERE-villkor" + +#: parser/parse_agg.c:544 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "gruppoperationer tillåts inte i COPY FROM WHERE-villkor" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:567 parser/parse_clause.c:1828 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "aggregatfunktioner tillåts inte i %s" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:570 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "gruppoperationer tillåts inte i %s" + +#: parser/parse_agg.c:678 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "yttre aggregat kan inte innehålla inre variabel i sitt direkta argument" + +#: parser/parse_agg.c:757 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "aggregatfunktionsanrop kan inte innehålla mängdreturnerande funktionsanrop" + +#: parser/parse_agg.c:758 parser/parse_expr.c:1845 parser/parse_expr.c:2332 +#: parser/parse_func.c:872 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Du kanske kan flytta den mängdreturnerande funktionen in i en LATERAL FROM-konstruktion." + +#: parser/parse_agg.c:763 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "aggregatfunktionsanrop kan inte innehålla fönsterfunktionanrop" + +#: parser/parse_agg.c:842 +msgid "window functions are not allowed in JOIN conditions" +msgstr "fönsterfunktioner tillåts inte i JOIN-villkor" + +#: parser/parse_agg.c:849 +msgid "window functions are not allowed in functions in FROM" +msgstr "fönsterfunktioner tillåts inte i funktioner i FROM" + +#: parser/parse_agg.c:855 +msgid "window functions are not allowed in policy expressions" +msgstr "fönsterfunktioner tillåts inte i policy-uttryck" + +#: parser/parse_agg.c:868 +msgid "window functions are not allowed in window definitions" +msgstr "fönsterfunktioner tillåts inte i fönsterdefinitioner" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in check constraints" +msgstr "fönsterfunktioner tillåts inte i check-villkor" + +#: parser/parse_agg.c:904 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "fönsterfunktioner tillåts inte i DEFAULT-uttryck" + +#: parser/parse_agg.c:907 +msgid "window functions are not allowed in index expressions" +msgstr "fönsterfunktioner tillåts inte i indexuttryck" + +#: parser/parse_agg.c:910 +msgid "window functions are not allowed in index predicates" +msgstr "fönsterfunktioner tillåts inte i indexpredikat" + +#: parser/parse_agg.c:913 +msgid "window functions are not allowed in transform expressions" +msgstr "fönsterfunktioner tillåts inte i transform-uttrycket" + +#: parser/parse_agg.c:916 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "fönsterfunktioner tillåts inte i EXECUTE-parametrar" + +#: parser/parse_agg.c:919 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "fönsterfunktioner tillåts inte i WHEN-utlösarvillkor" + +#: parser/parse_agg.c:922 +msgid "window functions are not allowed in partition bound" +msgstr "fönsterfunktioner tillåts inte i partitiongräns" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "fönsterfunktioner tillåts inte i partitionsnyckeluttryck" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "fönsterfunktioner tillåts inte i CALL-argument" + +#: parser/parse_agg.c:931 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "fönsterfunktioner tillåts inte i COPY FROM WHERE-villkor" + +#: parser/parse_agg.c:934 +msgid "window functions are not allowed in column generation expressions" +msgstr "fönsterfunktioner tillåts inte i kolumngenereringsuttryck" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:954 parser/parse_clause.c:1837 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "fönsterfunktioner tillåts inte i %s" + +#: parser/parse_agg.c:988 parser/parse_clause.c:2671 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "fönster \"%s\" finns inte" + +#: parser/parse_agg.c:1072 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "för många grupperingsmängder (maximalt 4096)" + +#: parser/parse_agg.c:1212 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "aggregatfunktioner tillåts inte i en rekursiv frågas rekursiva term" + +#: parser/parse_agg.c:1405 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "kolumn \"%s.%s\" måste stå med i GROUP BY-klausulen eller användas i en aggregatfunktion" + +#: parser/parse_agg.c:1408 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "Direkta argument till en sorterad-mängd-aggregat får bara använda grupperade kolumner." + +#: parser/parse_agg.c:1413 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "underfråga använder ogrupperad kolumn \"%s.%s\" från yttre fråga" + +#: parser/parse_agg.c:1577 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "argument till GROUPING måste vare grupputtryck på den tillhörande frågenivån" + +#: parser/parse_clause.c:191 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "relationen \"%s\" kan inte vara målet för en modifierande sats" + +#: parser/parse_clause.c:571 parser/parse_clause.c:599 parser/parse_func.c:2424 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "mängdreturnerande funktioner måste vara på toppnivå i FROM" + +#: parser/parse_clause.c:611 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "multipla kolumndefinitionslistor tillåts inte i samma funktion" + +#: parser/parse_clause.c:644 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "ROWS FROM() med multipla funktioner kan inte ha en kolumndefinitionslista" + +#: parser/parse_clause.c:645 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "Lägg till en separat kolumndefinitionslista för varje funktion inne i ROWS FROM()." + +#: parser/parse_clause.c:651 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "UNNEST() med multipla argument kan inte ha en kolumndefinitionslista" + +#: parser/parse_clause.c:652 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "Använd separata UNNEST()-anrop inne i ROWS FROM() och koppla en kolumndefinitionslista till varje." + +#: parser/parse_clause.c:659 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY kan inte användas tillsammans med en kolumndefinitionslista" + +#: parser/parse_clause.c:660 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Placera kolumndefinitionslistan inne i ROWS FROM()." + +#: parser/parse_clause.c:760 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "bara en FOR ORDINALITY-kolumn tillåts" + +#: parser/parse_clause.c:821 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "kolumnnamn \"%s\" är inte unikt" + +#: parser/parse_clause.c:863 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "namespace-namn \"%s\" är inte unikt" + +#: parser/parse_clause.c:873 +#, c-format +msgid "only one default namespace is allowed" +msgstr "bara ett standard-namespace tillåts" + +#: parser/parse_clause.c:933 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "tabellsamplingsmetod \"%s\" existerar inte" + +#: parser/parse_clause.c:955 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "tabellsamplingsmetod %s kräver %d argument, inte %d" +msgstr[1] "tabellsamplingsmetod %s kräver %d argument, inte %d" + +#: parser/parse_clause.c:989 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "tabellsamplingsmetod %s stöder inte REPEATABLE" + +#: parser/parse_clause.c:1135 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLE-klausul kan bara appliceras på tabeller och materialiserade vyer" + +#: parser/parse_clause.c:1318 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "kolumnnamn \"%s\" angivet mer än en gång i USING-klausul" + +#: parser/parse_clause.c:1333 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "gemensamt kolumnnamn \"%s\" finns mer än en gång i vänstra tabellen" + +#: parser/parse_clause.c:1342 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "kolumn \"%s\" angiven i USING-klausul finns inte i den vänstra tabellen" + +#: parser/parse_clause.c:1357 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "gemensamt kolumnnamn \"%s\" finns mer än en gång i högra tabellen" + +#: parser/parse_clause.c:1366 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "kolumn \"%s\" angiven i USING-klausul finns inte i den högra tabellen" + +#: parser/parse_clause.c:1447 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "kolumnaliaslista för \"%s\" har för många element" + +#: parser/parse_clause.c:1773 +#, c-format +msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" +msgstr "radantal kan inte vara null i FETCH FIRST ... WITH TIES-klausul" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1798 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "argumentet till %s får inte innehålla variabler" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1963 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s \"%s\" är tvetydig" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1992 +#, c-format +msgid "non-integer constant in %s" +msgstr "ej heltalskonstant i %s" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2014 +#, c-format +msgid "%s position %d is not in select list" +msgstr "%s-position %d finns inte i select-listan" + +#: parser/parse_clause.c:2453 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE är begränsad till 12 element" + +#: parser/parse_clause.c:2659 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "fönster \"%s\" är redan definierad" + +#: parser/parse_clause.c:2720 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "kan inte övertrumfa PARTITION BY-klausul för fönster \"%s\"" + +#: parser/parse_clause.c:2732 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "kan inte övertrumfa ORDER BY-klausul för fönster \"%s\"" + +#: parser/parse_clause.c:2762 parser/parse_clause.c:2768 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "kan inte kopiera fönster \"%s\" då det har en fönsterramklausul" + +#: parser/parse_clause.c:2770 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Ta bort parenteserna i denna OVER-klausul." + +#: parser/parse_clause.c:2790 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE med offset PRECEDING/FOLLOWING kräver exakt en ORDER BY-kolumn" + +#: parser/parse_clause.c:2813 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPS-läge kräver en ORDER BY-klausul" + +#: parser/parse_clause.c:2883 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "i ett aggregat med DISTINCT så måste ORDER BY-uttryck finnas i argumentlistan" + +#: parser/parse_clause.c:2884 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "i SELECT DISTINCT så måste ORDER BY-uttryck finnas i select-listan" + +#: parser/parse_clause.c:2916 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "ett aggregat med DISTINCT måste ha minst ett argument" + +#: parser/parse_clause.c:2917 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT måste ha minst en kolumn" + +#: parser/parse_clause.c:2983 parser/parse_clause.c:3015 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "SELECT DISTINCT ON-uttrycken måste matcha de initiala ORDER BY-uttrycken" + +#: parser/parse_clause.c:3093 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC tillåts inte i ON CONFLICT-klausul" + +#: parser/parse_clause.c:3099 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST tillåts inte i ON CONFLICT-klausul" + +#: parser/parse_clause.c:3178 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE kräver inferensangivelse eller villkorsnamn" + +#: parser/parse_clause.c:3179 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Till exempel, ON CONFLICT (kolumnnamn)." + +#: parser/parse_clause.c:3190 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT stöds inte för systemkatalogtabeller" + +#: parser/parse_clause.c:3198 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT stöds inte på tabell \"%s\" som används som katalogtabell" + +#: parser/parse_clause.c:3341 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "operator %s är inte en giltig sorteringsoperator" + +#: parser/parse_clause.c:3343 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "Sorteringsoperationer måste vara \"<\"- eller \">\"-medlemmar i btree-operatorfamiljer." + +#: parser/parse_clause.c:3654 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE med offset PRECEDING/FOLLOWING stöds inte för kolumntyp %s" + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE med offset PRECEDING/FOLLOWING stöd inte av kolumntyp %s och offset-typ %s" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Typomvandla offset-värdet till lämplig typ." + +#: parser/parse_clause.c:3668 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE med offset PRECEDING/FOLLOWING har multipla tolkingar för kolumntyp %s och offset-typ %s" + +#: parser/parse_clause.c:3671 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Typomvandla offset-värdet till exakt den önskade typen." + +#: parser/parse_coerce.c:1024 parser/parse_coerce.c:1062 +#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1095 +#: parser/parse_expr.c:2241 parser/parse_expr.c:2819 parser/parse_target.c:967 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "kan inte omvandla typ %s till %s" + +#: parser/parse_coerce.c:1065 +#, c-format +msgid "Input has too few columns." +msgstr "Indata har för få kolumner" + +#: parser/parse_coerce.c:1083 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "Kan inte typomvandla typ %s till %s i kolumn %d." + +#: parser/parse_coerce.c:1098 +#, c-format +msgid "Input has too many columns." +msgstr "Indata har för många kolumner" + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1153 parser/parse_coerce.c:1201 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "argumentet till %s måste vara av typ %s, inte av typ %s" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1164 parser/parse_coerce.c:1213 +#, c-format +msgid "argument of %s must not return a set" +msgstr "argumentet till %s får inte returnera en mängd" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1353 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "%s typer %s och %s matchar inte" + +#: parser/parse_coerce.c:1465 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "argumenttyperna %s och %s matchar inte" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1517 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%s kan inte konvertera typ %s till %s" + +#: parser/parse_coerce.c:1934 +#, c-format +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "argument deklarerade som \"anyelement\" är inte alla likadana" + +#: parser/parse_coerce.c:1954 +#, c-format +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "argument deklarerade \"anyarray\" är inte alla likadana" + +#: parser/parse_coerce.c:1974 +#, c-format +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "argument deklarerade \"anyrange\" är inte alla likadana" + +#: parser/parse_coerce.c:2008 parser/parse_coerce.c:2088 +#: utils/fmgr/funcapi.c:487 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "argumentet deklarerad %s är inte en array utan typ %s" + +#: parser/parse_coerce.c:2029 +#, c-format +msgid "arguments declared \"anycompatiblerange\" are not all alike" +msgstr "argument deklarerade \"anycompatiblerange\" är inte alla likadana" + +#: parser/parse_coerce.c:2041 parser/parse_coerce.c:2122 +#: utils/fmgr/funcapi.c:501 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "argumentet deklarerad %s är inte en intervalltyp utan typ %s" + +#: parser/parse_coerce.c:2079 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "kan inte bestämma elementtypen av \"anyarray\"-argument" + +#: parser/parse_coerce.c:2105 parser/parse_coerce.c:2139 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "argument deklarerad %s är inte konsistent med argument deklarerad %s" + +#: parser/parse_coerce.c:2163 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "kunde inte bestämma en polymorf typ då indata har typ %s" + +#: parser/parse_coerce.c:2177 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "typen som matchar anynonarray är en array-typ: %s" + +#: parser/parse_coerce.c:2187 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "typen som matchar anyenum är inte en enum-typ: %s" + +#: parser/parse_coerce.c:2218 parser/parse_coerce.c:2267 +#: parser/parse_coerce.c:2329 parser/parse_coerce.c:2365 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "kunde inte bestämma en polymorf typ %s då indata har typ %s" + +#: parser/parse_coerce.c:2228 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "anycompatiblerange-typ %s matchar inte anycompatiblerange-typ %s" + +#: parser/parse_coerce.c:2242 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "typen som matchar anycompatiblenonarray är en array-typ: %s" + +#: parser/parse_coerce.c:2433 +#, c-format +msgid "A result of type %s requires at least one input of type %s." +msgstr "Ett resultat av typen %s kräver minst en indata med typ %s." + +#: parser/parse_coerce.c:2445 +#, c-format +msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange." +msgstr "Ett resultat av typ %s kräver minst en indata av typen anyelement, anyarray, anynonarray, anyenum eller anyrange." + +#: parser/parse_coerce.c:2457 +#, c-format +msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "Ett resultat av typ %s kräver minst en indata av typ anycompatible, anycompatiblearray, anycompatiblenonarray eller anycompatiblerange." + +#: parser/parse_coerce.c:2487 +msgid "A result of type internal requires at least one input of type internal." +msgstr "Ett resultat av typ internal kräver minst en indata av typ internal." + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:981 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "jämförelser (collation) matchar inte mellan implicita jämförelser \"%s\" och \"%s\"" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:984 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "Du kan välja jämförelse genom att applicera en COLLATE-klausul till ett eller båda uttrycken." + +#: parser/parse_collate.c:831 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "jämförelser (collation) matchar inte mellan explicita jämförelser \"%s\" och \"%s\"" + +#: parser/parse_cte.c:42 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "rekursiv referens till fråga \"%s\" får inte finnas inom dess ickerekursiva term" + +#: parser/parse_cte.c:44 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "rekursiv referens till fråga \"%s\" får inte finnas i en subfråga" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "rekursiv referens till fråga \"%s\" får inte finnas i en outer join" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "rekursiv referens till fråga \"%s\" får inte finnas i en INTERSECT" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "rekursiv referens till fråga \"%s\" får inte finnas i en EXCEPT" + +#: parser/parse_cte.c:132 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "WITH-frågenamn \"%s\" angivet mer än en gång" + +#: parser/parse_cte.c:264 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "WITH-klausul som innehåller en datamodifierande sats måste vara på toppnivå" + +#: parser/parse_cte.c:313 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "rekursiv fråga \"%s\" kolumn %d har typ %s i den ickerekursiva termen med typ %s totalt sett" + +#: parser/parse_cte.c:319 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Typomvandla utdatan för den ickerekursiva termen till korrekt typ." + +#: parser/parse_cte.c:324 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "rekursiv fråga \"%s\" kolumn %d har jämförelse (collation) \"%s\" i en icke-rekursiv term men jämförelse \"%s\" totalt sett" + +#: parser/parse_cte.c:328 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "Använd en COLLATE-klausul för att sätta jämförelse för den icke-rekursiva termen." + +#: parser/parse_cte.c:418 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "WITH-fråga \"%s\" har %d kolumner tillgängliga men %d kolumner angivna" + +#: parser/parse_cte.c:598 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "ömsesidig rekursion mellan WITH-poster är inte implementerat" + +#: parser/parse_cte.c:650 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "rekursiv fråga \"%s\" får inte innehålla datamodifierande satser" + +#: parser/parse_cte.c:658 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "rekursiv fråga \"%s\" är inte på formen icke-rekursiv-term UNION [ALL] rekursiv-term" + +#: parser/parse_cte.c:702 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "ORDER BY i en rekursiv fråga är inte implementerat" + +#: parser/parse_cte.c:708 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "OFFSET i en rekursiv fråga är inte implementerat" + +#: parser/parse_cte.c:714 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "LIMIT i en rekursiv fråga är inte implementerat" + +#: parser/parse_cte.c:720 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "FOR UPDATE/SHARE i en rekursiv fråga är inte implementerat" + +#: parser/parse_cte.c:777 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "rekursiv referens till fråga \"%s\" får inte finnas med mer än en gång" + +#: parser/parse_expr.c:349 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "DEFAULT tillåts inte i detta kontext" + +#: parser/parse_expr.c:402 parser/parse_relation.c:3506 +#: parser/parse_relation.c:3526 +#, c-format +msgid "column %s.%s does not exist" +msgstr "kolumnen %s.%s finns inte" + +#: parser/parse_expr.c:414 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "kolumn \"%s\" fanns inte i datatypen %s" + +#: parser/parse_expr.c:420 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "kunde inte hitta kolumnen \"%s\" i record-datatyp" + +#: parser/parse_expr.c:426 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "kolumnotation .%s använd på typ %s som inte är en sammanslagen typ" + +#: parser/parse_expr.c:457 parser/parse_target.c:729 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "radexpansion via \"*\" stöds inte här" + +#: parser/parse_expr.c:578 +msgid "cannot use column reference in DEFAULT expression" +msgstr "kan inte använda kolumnreferenser i DEFAULT-uttryck" + +#: parser/parse_expr.c:581 +msgid "cannot use column reference in partition bound expression" +msgstr "kan inte använda kolumnreferenser i partitionsgränsuttryck" + +#: parser/parse_expr.c:850 parser/parse_relation.c:799 +#: parser/parse_relation.c:881 parser/parse_target.c:1207 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "kolumnreferens \"%s\" är tvetydig" + +#: parser/parse_expr.c:906 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:199 parser/parse_param.c:298 +#, c-format +msgid "there is no parameter $%d" +msgstr "det finns ingen parameter $%d" + +#: parser/parse_expr.c:1149 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULLIF kräver att =-operatorn returnerar boolean" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1155 parser/parse_expr.c:3135 +#, c-format +msgid "%s must not return a set" +msgstr "%s får inte returnera en mängd" + +#: parser/parse_expr.c:1603 parser/parse_expr.c:1635 +#, c-format +msgid "number of columns does not match number of values" +msgstr "antalet kolumner matchar inte antalet värden" + +#: parser/parse_expr.c:1649 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "källa till en multiple-kolumn-UPDATE-post måste vara en sub-SELECT eller ROW()-uttryck" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1843 parser/parse_expr.c:2330 parser/parse_func.c:2540 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "mängdreturnerande funktioner tillåts inte i %s" + +#: parser/parse_expr.c:1904 +msgid "cannot use subquery in check constraint" +msgstr "kan inte använda subfråga i check-villkor" + +#: parser/parse_expr.c:1908 +msgid "cannot use subquery in DEFAULT expression" +msgstr "kan inte använda underfråga i DEFAULT-uttryck" + +#: parser/parse_expr.c:1911 +msgid "cannot use subquery in index expression" +msgstr "kan inte använda subfråga i indexuttryck" + +#: parser/parse_expr.c:1914 +msgid "cannot use subquery in index predicate" +msgstr "kan inte använda subfråga i indexpredikat" + +#: parser/parse_expr.c:1917 +msgid "cannot use subquery in transform expression" +msgstr "kan inte använda underfråga i transformeringsuttrycket" + +#: parser/parse_expr.c:1920 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "kan inte använda subfråga i EXECUTE-parameter" + +#: parser/parse_expr.c:1923 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "kan inte använda subfråga i utlösares WHEN-villkor" + +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in partition bound" +msgstr "kan inte använda underfråga i partitionsgräns" + +#: parser/parse_expr.c:1929 +msgid "cannot use subquery in partition key expression" +msgstr "kan inte använda underfråga i partitionsnyckeluttryck" + +#: parser/parse_expr.c:1932 +msgid "cannot use subquery in CALL argument" +msgstr "kan inte använda subfråga i CALL-argument" + +#: parser/parse_expr.c:1935 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "kan inte använda subfråga i COPY FROM WHERE-villkor" + +#: parser/parse_expr.c:1938 +msgid "cannot use subquery in column generation expression" +msgstr "kan inte använda subfråga i kolumngenereringsuttryck" + +#: parser/parse_expr.c:1991 +#, c-format +msgid "subquery must return only one column" +msgstr "underfråga kan bara returnera en kolumn" + +#: parser/parse_expr.c:2075 +#, c-format +msgid "subquery has too many columns" +msgstr "underfråga har för många kolumner" + +#: parser/parse_expr.c:2080 +#, c-format +msgid "subquery has too few columns" +msgstr "underfråga har för få kolumner" + +#: parser/parse_expr.c:2181 +#, c-format +msgid "cannot determine type of empty array" +msgstr "kan inte bestämma typen av en tom array" + +#: parser/parse_expr.c:2182 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "Typomvandla explicit till den önskade typen, till exempel ARRAY[]::integer[]." + +#: parser/parse_expr.c:2196 +#, c-format +msgid "could not find element type for data type %s" +msgstr "kunde inte hitta elementtyp för datatyp %s" + +#: parser/parse_expr.c:2481 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "onamnat XML-attributvärde måste vara en kolumnreferens" + +#: parser/parse_expr.c:2482 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "onamnat XML-elementvärde måste vara en kolumnreferens" + +#: parser/parse_expr.c:2497 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "XML-attributnamn \"%s\" finns med mer än en gång" + +#: parser/parse_expr.c:2604 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "kan inte typomvandla XMLSERIALIZE-resultat till %s" + +#: parser/parse_expr.c:2892 parser/parse_expr.c:3088 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "olika antal element i raduttryck" + +#: parser/parse_expr.c:2902 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "kan inte jämföra rader med längden noll" + +#: parser/parse_expr.c:2927 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "operator för radjämförelse måste resultera i typen boolean, inte %s" + +#: parser/parse_expr.c:2934 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "radjämförelseoperator får inte returnera en mängd" + +#: parser/parse_expr.c:2993 parser/parse_expr.c:3034 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "kunde inte lista ut tolkning av radjämförelseoperator %s" + +#: parser/parse_expr.c:2995 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "Radjämförelseoperatorer måste vara associerade med btreee-operatorfamiljer." + +#: parser/parse_expr.c:3036 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Det finns flera lika sannolika kandidater." + +#: parser/parse_expr.c:3129 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROM kräver att operatorn = ger tillbaka en boolean" + +#: parser/parse_expr.c:3448 parser/parse_expr.c:3466 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "operator-precedence-ändring: %s har nu lägre precedence än %s" + +#: parser/parse_func.c:191 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "argumentnamn \"%s\" angivet mer än en gång" + +#: parser/parse_func.c:202 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "positionella argument kan inte komma efter namngivna argument" + +#: parser/parse_func.c:284 parser/parse_func.c:2243 +#, c-format +msgid "%s is not a procedure" +msgstr "%s är inte en procedur" + +#: parser/parse_func.c:288 +#, c-format +msgid "To call a function, use SELECT." +msgstr "För att anropa en funktion, använd SELECT." + +#: parser/parse_func.c:294 +#, c-format +msgid "%s is a procedure" +msgstr "\"%s\" är en procedur" + +#: parser/parse_func.c:298 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "För att anropa en procedur, använd CALL" + +#: parser/parse_func.c:312 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) angivet, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:319 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:325 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:331 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:337 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:343 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER angiven, men %s är inte en fönsterfunktion eller en aggregatfunktion" + +#: parser/parse_func.c:381 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "WITHIN GROUP krävs för sorterad-mängd-aggregat %s" + +#: parser/parse_func.c:387 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "DISTINCT stöds inte för sorterad-mängd-aggregat %s" + +#: parser/parse_func.c:418 parser/parse_func.c:447 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr "Det finns ett sorterad-mängd-aggregat %s, men det kräver %d direkta argument, inte %d." + +#: parser/parse_func.c:472 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "För att använda hypotetiskt mängdaggregat %s så måste antalet direkta hypotetiska argument (här %d) matcha antalet sorteringskolumner (här %d)." + +#: parser/parse_func.c:486 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr "Det finns ett sorterad-mängd-aggregat %s, men det kräver minst %d direkta argument." + +#: parser/parse_func.c:505 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s är inte en sorterad-mängd-aggregat, så den kan inte ha WITHIN GROUP" + +#: parser/parse_func.c:518 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "fönsterfunktion %s kräver en OVER-klausul" + +#: parser/parse_func.c:525 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "fönsterfunktion %s kan inte ha en WITHIN GROUP" + +#: parser/parse_func.c:554 +#, c-format +msgid "procedure %s is not unique" +msgstr "proceduren \"%s\" är inte unik" + +#: parser/parse_func.c:557 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "Kunde inte välja en bästa kandidatprocedur. Du behöver troligen lägga till en explicit typomvandling." + +#: parser/parse_func.c:563 +#, c-format +msgid "function %s is not unique" +msgstr "funktionen %s är inte unik" + +#: parser/parse_func.c:566 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "Kunde inte välja en bästa kandidatfunktion: Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_func.c:605 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "Ingen aggregatfunktion matchar det givna namnet och argumenttyperna. Kanske har du placerat ORDER BY på fel plats; ORDER BY måste komma efter alla vanliga argument till aggregatet." + +#: parser/parse_func.c:613 parser/parse_func.c:2286 +#, c-format +msgid "procedure %s does not exist" +msgstr "proceduren \"%s\" finns inte" + +#: parser/parse_func.c:616 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ingen procedur matchar det angivna namnet och argumenttyperna. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_func.c:625 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ingen funktion matchar det angivna namnet och argumenttyperna. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_func.c:727 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "VARIADIC-argument måste vara en array" + +#: parser/parse_func.c:779 parser/parse_func.c:843 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*) måste användas för att anropa en parameterlös aggregatfunktion" + +#: parser/parse_func.c:786 +#, c-format +msgid "aggregates cannot return sets" +msgstr "aggregat kan inte returnera mängder" + +#: parser/parse_func.c:801 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "aggregat kan inte använda namngivna argument" + +#: parser/parse_func.c:833 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "DISTINCT är inte implementerad för fönsterfunktioner" + +#: parser/parse_func.c:853 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "aggregat-ORDER BY är inte implementerat för fönsterfunktioner" + +#: parser/parse_func.c:862 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "FILTER är inte implementerat för icke-aggregat-fönsterfunktioner" + +#: parser/parse_func.c:871 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "fönsterfunktioner kan inte innehålla funtionsanrop till funktioner som returnerar mängder" + +#: parser/parse_func.c:879 +#, c-format +msgid "window functions cannot return sets" +msgstr "fönsterfunktioner kan inte returnera mängder" + +#: parser/parse_func.c:2124 parser/parse_func.c:2315 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "kunde inte hitta funktion med namn \"%s\"" + +#: parser/parse_func.c:2138 parser/parse_func.c:2333 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "funktionsnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2140 parser/parse_func.c:2335 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Ange argumentlistan för att välja funktionen entydigt." + +#: parser/parse_func.c:2184 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "procedurer kan inte ha mer än %d argument" +msgstr[1] "procedurer kan inte ha mer än %d argument" + +#: parser/parse_func.c:2233 +#, c-format +msgid "%s is not a function" +msgstr "%s är inte en funktion" + +#: parser/parse_func.c:2253 +#, c-format +msgid "function %s is not an aggregate" +msgstr "funktionen %s är inte en aggregatfunktion" + +#: parser/parse_func.c:2281 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "kunde inte hitta en procedur med namn \"%s\"" + +#: parser/parse_func.c:2295 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "kunde inte hitta ett aggregat med namn \"%s\"" + +#: parser/parse_func.c:2300 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "aggregatfunktion %s(*) existerar inte" + +#: parser/parse_func.c:2305 +#, c-format +msgid "aggregate %s does not exist" +msgstr "aggregatfunktion %s existerar inte" + +#: parser/parse_func.c:2340 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "procedurnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2342 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Ange argumentlistan för att välja proceduren entydigt." + +#: parser/parse_func.c:2347 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "aggregatnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2349 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Ange argumentlistan för att välja aggregatet entydigt." + +#: parser/parse_func.c:2354 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "rutinnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2356 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Ange argumentlistan för att välja rutinen entydigt." + +#: parser/parse_func.c:2411 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "mängdreturnerande funktioner tillåts inte i JOIN-villkor" + +#: parser/parse_func.c:2432 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "mängdreturnerande funktioner tillåts inte i policy-uttryck" + +#: parser/parse_func.c:2448 +msgid "set-returning functions are not allowed in window definitions" +msgstr "mängdreturnerande funktioner tillåts inte i fönsterdefinitioner" + +#: parser/parse_func.c:2486 +msgid "set-returning functions are not allowed in check constraints" +msgstr "mängdreturnerande funktioner tillåts inte i check-villkor" + +#: parser/parse_func.c:2490 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "mängdreturnerande funktioner tillåts inte i DEFAULT-uttryck" + +#: parser/parse_func.c:2493 +msgid "set-returning functions are not allowed in index expressions" +msgstr "mängdreturnerande funktioner tillåts inte i indexuttryck" + +#: parser/parse_func.c:2496 +msgid "set-returning functions are not allowed in index predicates" +msgstr "mängdreturnerande funktioner tillåts inte i indexpredukat" + +#: parser/parse_func.c:2499 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "mängdreturnerande funktioner tillåts inte i transformuttryck" + +#: parser/parse_func.c:2502 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "mängdreturnerande funktioner tillåts inte i EXECUTE-parametrar" + +#: parser/parse_func.c:2505 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "mängdreturnerande funktioner tillåts inte i WHEN-utlösarvillkor" + +#: parser/parse_func.c:2508 +msgid "set-returning functions are not allowed in partition bound" +msgstr "mängdreturnerande funktioner tillåts inte i partitionsgräns" + +#: parser/parse_func.c:2511 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "mängdreturnerande funktioner tillåts inte i partitionsnyckeluttryck" + +#: parser/parse_func.c:2514 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "mängdreturnerande funktioner tillåts inte i CALL-argument" + +#: parser/parse_func.c:2517 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "mängdreturnerande funktioner tillåts inte i COPY FROM WHERE-villkor" + +#: parser/parse_func.c:2520 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "mängdreturnerande funktioner tillåts inte i kolumngenereringsuttryck" + +#: parser/parse_node.c:86 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "mållista kan ha som mest %d poster" + +#: parser/parse_node.c:235 +#, c-format +msgid "cannot subscript type %s because it is not an array" +msgstr "kan inte indexera typ %s då det inte är en array" + +#: parser/parse_node.c:340 parser/parse_node.c:377 +#, c-format +msgid "array subscript must have type integer" +msgstr "arrayindex måste ha typen integer" + +#: parser/parse_node.c:408 +#, c-format +msgid "array assignment requires type %s but expression is of type %s" +msgstr "array-tilldelning kräver typ %s men uttrycket har typ %s" + +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:521 +#: utils/adt/regproc.c:705 +#, c-format +msgid "operator does not exist: %s" +msgstr "operator existerar inte: %s" + +#: parser/parse_oper.c:224 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Använd en explicit ordningsoperator eller ändra frågan." + +#: parser/parse_oper.c:480 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "operator kräver run-time-typomvandling: %s" + +#: parser/parse_oper.c:716 +#, c-format +msgid "operator is not unique: %s" +msgstr "operatorn är inte unik: %s" + +#: parser/parse_oper.c:718 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "Kunde inte välja en bästa kandidatoperator. Du behöver troligen lägga till en explicit typomvandling." + +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Ingen operator matchar det angivna namnet och argumenttyp. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_oper.c:729 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ingen operator matchar det angivna namnet och argumenttyperna. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_oper.c:790 parser/parse_oper.c:912 +#, c-format +msgid "operator is only a shell: %s" +msgstr "operator är bara en shell-typ: %s" + +#: parser/parse_oper.c:900 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (array) kräver en array på höger sida" + +#: parser/parse_oper.c:942 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (array) kräver att operatorn returnerar en boolean" + +#: parser/parse_oper.c:947 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (array) kräver att operatorn inte returnerar en mängd" + +#: parser/parse_param.c:216 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "inkonsistenta typer härledda för parameter $%d" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "tabellreferens \"%s\" är tvetydig" + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "tabellreferens %u är tvetydig" + +#: parser/parse_relation.c:444 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "tabellnamn \"%s\" angivet mer än en gång" + +#: parser/parse_relation.c:473 parser/parse_relation.c:3446 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "ogiltig referens till FROM-klausulpost för tabell \"%s\"" + +#: parser/parse_relation.c:477 parser/parse_relation.c:3451 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Det finns en post för tabell \"%s\" men den kan inte refereras till från denna del av frågan." + +#: parser/parse_relation.c:479 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "JOIN-typen måste vara INNER eller LEFT för att fungera med LATERAL." + +#: parser/parse_relation.c:690 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "systemkolumn \"%s\" som refereras till i check-villkor är ogiltigt" + +#: parser/parse_relation.c:699 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "kan inte använda systemkolumn \"%s\" i kolumngenereringsuttryck" + +#: parser/parse_relation.c:1170 parser/parse_relation.c:1620 +#: parser/parse_relation.c:2262 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "tabell \"%s\" har %d kolumner tillgängliga men %d kolumner angivna" + +#: parser/parse_relation.c:1372 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "Det finns en WITH-post med namn \"%s\" men den kan inte refereras till från denna del av frågan." + +#: parser/parse_relation.c:1374 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "Använd WITH RECURSIVE eller ändra ordning på WITH-posterna för att ta bort framåt-referenser." + +#: parser/parse_relation.c:1747 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "en kolumndefinitionslista tillåts bara för funktioner som returnerar \"record\"" + +#: parser/parse_relation.c:1756 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "en kolumndefinitionslista krävs för funktioner som returnerar \"record\"" + +#: parser/parse_relation.c:1845 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "funktion \"%s\" i FROM har en icke stödd returtyp %s" + +#: parser/parse_relation.c:2054 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "VALUES-lista \"%s\" har %d kolumner tillgängliga men %d kolumner angivna" + +#: parser/parse_relation.c:2125 +#, c-format +msgid "joins can have at most %d columns" +msgstr "joins kan ha som mest %d kolumner" + +#: parser/parse_relation.c:2235 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "WITH-fråga \"%s\" har ingen RETURNING-klausul" + +#: parser/parse_relation.c:3221 parser/parse_relation.c:3231 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "kolumn %d i relation \"%s\" finns inte" + +#: parser/parse_relation.c:3449 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Kanske tänkte du referera till tabellaliaset \"%s\"." + +#: parser/parse_relation.c:3457 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "saknar FROM-klausulpost för tabell \"%s\"" + +#: parser/parse_relation.c:3509 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Kanske tänkte du referera till kolumnen \"%s.%s\"." + +#: parser/parse_relation.c:3511 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Det finns en kolumn med namn \"%s\" i tabell \"%s\" men den kan inte refereras till från denna del av frågan." + +#: parser/parse_relation.c:3528 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "Kanske tänkte du referera till kolumnen \"%s.%s\" eller kolumnen \"%s.%s\"." + +#: parser/parse_target.c:478 parser/parse_target.c:792 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "kan inte skriva till systemkolumn \"%s\"" + +#: parser/parse_target.c:506 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "kan inte sätta ett array-element till DEFAULT" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "kan inte sätta ett underfält till DEFAULT" + +#: parser/parse_target.c:584 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "kolumn \"%s\" har typ %s men uttrycket är av typ %s" + +#: parser/parse_target.c:776 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "kan inte tilldela till fält \"%s\" i kolumn \"%s\" då dess typ %s inte är en composit-typ" + +#: parser/parse_target.c:785 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "kan inte tilldela till fält \"%s\" i kolumn \"%s\" då det inte finns någon sådan kolumn i datatypen %s" + +#: parser/parse_target.c:864 +#, c-format +msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "array-tilldelning till \"%s\" kräver typ %s men uttrycket har typ %s" + +#: parser/parse_target.c:874 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "underfält \"%s\" har typ %s men uttrycket har typ %s" + +#: parser/parse_target.c:1295 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "SELECT * utan tabeller angivna är inte giltigt" + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "dålig %%TYPE-referens (för får punktade namn): %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "dålig %%TYPE-referens (för många punktade namn): %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "typreferens %s konverterad till %s" + +#: parser/parse_type.c:278 parser/parse_type.c:857 utils/cache/typcache.c:383 +#: utils/cache/typcache.c:437 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "typ \"%s\" är bara ett skal" + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "typmodifierare tillåts inte för typ \"%s\"" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "typmodifierare måste vare enkla konstanter eller identifierare" + +#: parser/parse_type.c:721 parser/parse_type.c:820 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "ogiltigt typnamn \"%s\"" + +#: parser/parse_utilcmd.c:264 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "kan inte skapa partitionerad tabell som barnarv" + +#: parser/parse_utilcmd.c:428 +#, c-format +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s kommer skapa en implicit sekvens \"%s\" för \"serial\"-kolumnen \"%s.%s\"" + +#: parser/parse_utilcmd.c:559 +#, c-format +msgid "array of serial is not implemented" +msgstr "array med serial är inte implementerat" + +#: parser/parse_utilcmd.c:637 parser/parse_utilcmd.c:649 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "motstridiga NULL/NOT NULL-villkor för kolumnen \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:661 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "multipla default-värden angivna för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:678 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "identitetskolumner stöds inte på typade tabeller" + +#: parser/parse_utilcmd.c:682 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "identitetskolumner stöds inte för partitioner" + +#: parser/parse_utilcmd.c:691 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "multipla identitetspecifikationer för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:711 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "genererade kolumner stöds inte på typade tabeller" + +#: parser/parse_utilcmd.c:715 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "genererade kolumner stöds inte för partitioner" + +#: parser/parse_utilcmd.c:720 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "multipla genereringsklausuler angivna för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:738 parser/parse_utilcmd.c:853 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "primärnyckelvillkor stöds inte på främmande tabeller" + +#: parser/parse_utilcmd.c:747 parser/parse_utilcmd.c:863 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "unika villkor stöds inte på främmande tabeller" + +#: parser/parse_utilcmd.c:792 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "både default och identity angiven för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:800 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "både default och genereringsuttryck angiven för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:808 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "både identity och genereringsuttryck angiven för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:873 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "uteslutningsvillkor stöds inte på främmande tabeller" + +#: parser/parse_utilcmd.c:879 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "uteslutningsvillkor stöds inte för partitionerade tabeller" + +#: parser/parse_utilcmd.c:944 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "LIKE stöds inte för att skapa främmande tabeller" + +#: parser/parse_utilcmd.c:1704 parser/parse_utilcmd.c:1813 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "Index \"%s\" innehåller en hela-raden-referens." + +#: parser/parse_utilcmd.c:2163 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "kan inte använda ett existerande index i CREATE TABLE" + +#: parser/parse_utilcmd.c:2183 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "index \"%s\" är redan associerad med ett villkor" + +#: parser/parse_utilcmd.c:2198 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "index \"%s\" är inte giltigt" + +#: parser/parse_utilcmd.c:2204 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "\"%s\" är inte ett unikt index" + +#: parser/parse_utilcmd.c:2205 parser/parse_utilcmd.c:2212 +#: parser/parse_utilcmd.c:2219 parser/parse_utilcmd.c:2296 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "Kan inte skapa en primärnyckel eller ett unikt villkor med hjälp av ett sådant index." + +#: parser/parse_utilcmd.c:2211 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "index \"%s\" innehåller uttryck" + +#: parser/parse_utilcmd.c:2218 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "\"%s\" är ett partiellt index" + +#: parser/parse_utilcmd.c:2230 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\" är ett \"deferrable\" index" + +#: parser/parse_utilcmd.c:2231 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "Kan inte skapa ett icke-\"deferrable\" integritetsvillkor från ett \"deferrable\" index." + +#: parser/parse_utilcmd.c:2295 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "index \"%s\" kolumn nummer %d har ingen standard för sorteringsbeteende" + +#: parser/parse_utilcmd.c:2452 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "kolumn \"%s\" finns med två gånger i primära nyckel-villkoret" + +#: parser/parse_utilcmd.c:2458 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "kolumn \"%s\" finns med två gånger i unique-villkoret" + +#: parser/parse_utilcmd.c:2811 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "indexuttryck och predikat kan bara referera till tabellen som indexeras" + +#: parser/parse_utilcmd.c:2857 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "regler på materialiserade vyer stöds inte" + +#: parser/parse_utilcmd.c:2920 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "WHERE-villkor i regel kan inte innehålla referenser till andra relationer" + +#: parser/parse_utilcmd.c:2994 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "regler med WHERE-villkor kan bara innehålla SELECT-, INSERT-, UPDATE- eller DELETE-handlingar" + +#: parser/parse_utilcmd.c:3012 parser/parse_utilcmd.c:3113 +#: rewrite/rewriteHandler.c:502 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "UNION-/INTERSECT-/EXCEPT-satser med villkor är inte implementerat" + +#: parser/parse_utilcmd.c:3030 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "ON SELECT-regel kan inte använda OLD" + +#: parser/parse_utilcmd.c:3034 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "ON SELECT-regel kan inte använda NEW" + +#: parser/parse_utilcmd.c:3043 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "ON INSERT-regel kan inte använda OLD" + +#: parser/parse_utilcmd.c:3049 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "ON DELETE-regel kan inte använda NEW" + +#: parser/parse_utilcmd.c:3077 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "kan inte referera till OLD i WITH-fråga" + +#: parser/parse_utilcmd.c:3084 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "kan inte referera till NEW i WITH-fråga" + +#: parser/parse_utilcmd.c:3542 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "felplacerad DEFERRABLE-klausul" + +#: parser/parse_utilcmd.c:3547 parser/parse_utilcmd.c:3562 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "multipla DEFERRABLE/NOT DEFERRABLE-klausuler tillåts inte" + +#: parser/parse_utilcmd.c:3557 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "felplacerad NOT DEFERRABLE-klausul" + +#: parser/parse_utilcmd.c:3578 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "felplacerad INITIALLY DEFERRED-klausul" + +#: parser/parse_utilcmd.c:3583 parser/parse_utilcmd.c:3609 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "multipla INITIALLY IMMEDIATE/DEFERRED-klausuler tillåts inte" + +#: parser/parse_utilcmd.c:3604 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "felplacerad klausul INITIALLY IMMEDIATE" + +#: parser/parse_utilcmd.c:3795 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE anger ett schema (%s) som skiljer sig från det som skapas (%s)" + +#: parser/parse_utilcmd.c:3830 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "\"%s\" är inte en partitionerad tabell" + +#: parser/parse_utilcmd.c:3837 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "tabell \"%s\" är inte partitionerad" + +#: parser/parse_utilcmd.c:3844 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "index \"%s\" är inte partitionerad" + +#: parser/parse_utilcmd.c:3884 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "en hash-partitionerad tabell får inte ha en standardpartition" + +#: parser/parse_utilcmd.c:3901 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "ogiltig gränsangivelse för hash-partition" + +#: parser/parse_utilcmd.c:3907 partitioning/partbounds.c:4691 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "modulo för hash-partition vara ett positivt integer" + +#: parser/parse_utilcmd.c:3914 partitioning/partbounds.c:4699 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "rest för hash-partition måste vara lägre än modulo" + +#: parser/parse_utilcmd.c:3927 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "ogiltig gränsangivelse för listpartition" + +#: parser/parse_utilcmd.c:3980 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "ogiltig gränsangivelse för range-partition" + +#: parser/parse_utilcmd.c:3986 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM måste ge exakt ett värde per partitionerande kolumn" + +#: parser/parse_utilcmd.c:3990 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO måste ge exakt ett värde per partitionerande kolumn" + +#: parser/parse_utilcmd.c:4104 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "kan inte ange NULL i range-gräns" + +#: parser/parse_utilcmd.c:4153 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "varje gräns efter MAXVALUE måste också vara MAXVALUE" + +#: parser/parse_utilcmd.c:4160 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "varje gräns efter MINVALUE måste också vara MINVALUE" + +#: parser/parse_utilcmd.c:4202 +#, c-format +msgid "could not determine which collation to use for partition bound expression" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skulle användas för partitionsgränsuttryck" + +#: parser/parse_utilcmd.c:4219 +#, c-format +msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +msgstr "jämförelse (collation) av partitioneringsgränsvärde \"%s\" matchar inte partitioneringsnyckelns jämförelse \"%s\"" + +#: parser/parse_utilcmd.c:4236 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "angivet värde kan inte typomvandlas till typ %s för kolumn \"%s\"" + +#: parser/parser.c:228 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "UESCAPE måste följas av en enkel stränglitteral" + +#: parser/parser.c:233 +msgid "invalid Unicode escape character" +msgstr "ogiltigt Unicode-escapetecken" + +#: parser/parser.c:302 scan.l:1329 +#, c-format +msgid "invalid Unicode escape value" +msgstr "ogiltigt Unicode-escapevärde" + +#: parser/parser.c:449 scan.l:677 +#, c-format +msgid "invalid Unicode escape" +msgstr "ogiltig Unicode-escapesekvens" + +#: parser/parser.c:450 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "Unicode-escapesekvenser måste vara \\XXXX eller \\+XXXXXX." + +#: parser/parser.c:478 scan.l:638 scan.l:654 scan.l:670 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "ogiltigt Unicode-surrogatpar" + +#: parser/scansup.c:203 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%s\"" +msgstr "identifierare \"%s\" kommer trunkeras till \"%s\"" + +#: partitioning/partbounds.c:2831 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "partition \"%s\" står i konflikt med existerande default-partition \"%s\"" + +#: partitioning/partbounds.c:2890 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "varje hash-partition-modulo måste vara en faktror av näste högre modulo" + +#: partitioning/partbounds.c:2986 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "tom intervallsgräns angiven för partition \"%s\"" + +#: partitioning/partbounds.c:2988 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Angiven lägre gräns %s är större än eller lika med övre gräns %s." + +#: partitioning/partbounds.c:3085 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "partition \"%s\" skulle överlappa partition \"%s\"" + +#: partitioning/partbounds.c:3202 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "hoppade över skanning av främmand tabell \"%s\" som er en partition för standardpartitionen \"%s\"" + +#: partitioning/partbounds.c:4695 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "rest för hash-partition måste vara ett icke-negativt heltal" + +#: partitioning/partbounds.c:4722 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" är inte en hash-partitionerad tabell" + +#: partitioning/partbounds.c:4733 partitioning/partbounds.c:4850 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "antalet partitioneringskolumner (%d) stämmer inte med antalet partioneringsnycklas som angivits (%d)" + +#: partitioning/partbounds.c:4755 partitioning/partbounds.c:4787 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "kolumn %d i partitioneringsnyckeln har typ \"%s\" men använt värde har typ \"%s\"" + +#: port/pg_sema.c:209 port/pg_shmem.c:640 port/posix_sema.c:209 +#: port/sysv_sema.c:327 port/sysv_shmem.c:640 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "kunde inte göra stat() på datakatalog \"%s\": %m" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "kunde inte skapa delat minnessegment: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "Misslyckade systemanropet var semget(key=%lu, size=%zu, 0%o)." + +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Felet betyder vanligen att PostgreSQLs begäran av delat minnessegment överskred kärnans SHMMAX-parameter eller möjligen att det är lägre än kärnans SHMMIN-parameter.\n" +"PostgreSQLs dokumentation innehåller mer information om konfigueration av delat minne." + +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Felet betyder vanligen att PostgreSQLs begäran av delat minnessegment överskred kärnans SHMALL-parameter. Du kan behöva rekonfigurera kärnan med ett större SHMALL.\n" +"PostgreSQLs dokumentation innehåller mer information om konfigueration av delat minne." + +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Felet betyder *inte* att diskutrymmet tagit slut. Felet sker aningen om alla tillgängliga ID-nummer för delat minne tagit slut och då behöver du öka kärnans SHMMNI-parameter eller för att systemets totala gräns för delat minne ha nåtts.\n" +"PostgreSQLs dokumentation innehåller mer information om konfigueration av delat minne." + +#: port/pg_shmem.c:578 port/sysv_shmem.c:578 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "kunde inte mappa anonymt delat minne: %m" + +#: port/pg_shmem.c:580 port/sysv_shmem.c:580 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "Detta fel betyder vanligtvis att PostgreSQL:s begäran av delat minnessegment överskrider mängden tillgängligt minne, swap eller stora sidor. För att minska begärd storlek (nu %zu byte) minska PostgreSQL:s användning av delat minne t.ex. genom att dra ner på shared_buffers eller max_connections." + +#: port/pg_shmem.c:648 port/sysv_shmem.c:648 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "stora sidor stöds inte på denna plattform" + +#: port/pg_shmem.c:709 port/sysv_shmem.c:709 utils/init/miscinit.c:1137 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "redan existerande delat minnesblock (nyckel %lu, ID %lu) används fortfarande" + +#: port/pg_shmem.c:712 port/sysv_shmem.c:712 utils/init/miscinit.c:1139 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Stäng ner gamla serverprocesser som hör ihop med datakatalogen \"%s\"." + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "kan inte skapa semafor: %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "Misslyckade systemanropet var semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:129 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "Detta fel betyder *inte* att disken blivit full. Detta fel kommer när systemgränsen för maximalt antal semaforvektorer (SEMMNI) överskridits eller när systemets globala maximum för semaforer (SEMMNS) överskridits. Du behöver öka respektive kernel-parameter. Alternativt kan du minska PostgreSQL:s användning av semaforer genom att dra ner på parametern max_connections. PostgreSQL:s dokumentation innehåller mer information om hur du konfigurerar systemet för PostgreSQL." + +#: port/sysv_sema.c:159 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "Du kan behöva öka kärnans SEMVMX-värde till minst %d. Se PostgreSQL:s dokumentation för mer information." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "kunde inte ladda dbghelp.dll, kan inte skiva krash-dump\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "kunde inte ladda behövda funktioner i dbghelp.dll, kan inte skriva krash-dump\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "kunde inte öppna krashdumpfil \"%s\" för skrivning: felkod %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "skrev krashdump till fil \"%s\".\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "kunde inte skriva krashdump till fil \"%s\": felkod %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "kunde inte skapa signallyssnarrör (pipe) för PID %d: felkod %lu" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "kunde inte skapa signallyssnar-pipe: felkod %lu; försöker igen\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "kan inte skapa semafor: felkod %lu" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "kunde inte låsa semafor: felkod %lu" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "kunde inte låsa upp semafor: felkod %lu" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "kunde inte utföra \"try-lock\" på semafor: felkod %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "kunde inte aktivera användarrättigheten \"Lock Pages in Memory\": felkod %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "Misslyckat systemanrop var %s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "kunde inte aktivera användarrättigheten \"Lock Pages in Memory\"" + +#: port/win32_shmem.c:176 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "Tilldela användarrättigheten \"Lock Pages in Memory\" till Windows-användarkontot som kör PostgreSQL." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "processorn stöder inte stora sidor" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "stänger av stora sidor" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "kunde inte skapa delat minnessegment: felkod %lu" + +#: port/win32_shmem.c:303 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "Misslyckade systemanropet var CreateFileMapping(size=%zu, name=%s)." + +#: port/win32_shmem.c:328 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "redan existerande delat minnesblock används fortfarande" + +#: port/win32_shmem.c:329 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "Kontrollera om det finns några gamla serverprocesser som fortfarande kör och stäng ner dem." + +#: port/win32_shmem.c:339 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "Misslyckat systemanrop var DuplicateHandle." + +#: port/win32_shmem.c:357 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "Misslyckat systemanrop var MapViewOfFileEx." + +#: postmaster/autovacuum.c:406 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "kunde inte starta autovacuum-process: %m" + +#: postmaster/autovacuum.c:442 +#, c-format +msgid "autovacuum launcher started" +msgstr "autovacuum-startare startad" + +#: postmaster/autovacuum.c:839 +#, c-format +msgid "autovacuum launcher shutting down" +msgstr "autovacuum-startare stänger ner" + +#: postmaster/autovacuum.c:1477 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "kunde inte starta autovacuum-arbetsprocess: %m" + +#: postmaster/autovacuum.c:1686 +#, c-format +msgid "autovacuum: processing database \"%s\"" +msgstr "autovacuum: processar databas \"%s\"" + +#: postmaster/autovacuum.c:2256 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "autovacuum: slänger övergiven temptabell \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2485 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "automatisk vacuum av tabell \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2488 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "automatisk analys av tabell \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2681 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "processar arbetspost för relation \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:3285 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "autovacuum har inte startats på grund av en felkonfigurering" + +#: postmaster/autovacuum.c:3286 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "Slå på flaggan \"track_counts\"." + +#: postmaster/bgworker.c:394 postmaster/bgworker.c:841 +#, c-format +msgid "registering background worker \"%s\"" +msgstr "registrerar bakgrundsarbetare \"%s\"" + +#: postmaster/bgworker.c:426 +#, c-format +msgid "unregistering background worker \"%s\"" +msgstr "avregistrerar bakgrundsarbetare \"%s\"" + +#: postmaster/bgworker.c:591 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "bakgrundsarbetare \"%s\": måste ansluta till delat minne för att kunna få en databasanslutning" + +#: postmaster/bgworker.c:600 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "bakgrundsarbetare \"%s\" kan inte få databasaccess om den startar när postmaster startar" + +#: postmaster/bgworker.c:614 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "bakgrundsarbetare \"%s\": ogiltigt omstartsintervall" + +#: postmaster/bgworker.c:629 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "bakgrundsarbetare \"%s\": parallella arbetare kan inte konfigureras för omstart" + +#: postmaster/bgworker.c:653 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "terminerar bakgrundsarbetare \"%s\" pga administratörskommando" + +#: postmaster/bgworker.c:849 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "bakgrundsarbetare \"%s\": måste vara registrerad i shared_preload_libraries" + +#: postmaster/bgworker.c:861 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "bakgrundsarbetare \"%s\": bara dynamiska bakgrundsarbetare kan be om notifiering" + +#: postmaster/bgworker.c:876 +#, c-format +msgid "too many background workers" +msgstr "för många bakgrundsarbetare" + +#: postmaster/bgworker.c:877 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "Upp till %d bakgrundsarbetare kan registreras med nuvarande inställning." +msgstr[1] "Upp till %d bakgrundsarbetare kan registreras med nuvarande inställning." + +#: postmaster/bgworker.c:881 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "Överväg att öka konfigurationsparametern \"max_worker_processes\"." + +#: postmaster/checkpointer.c:418 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "checkpoint:s sker för ofta (%d sekund emellan)" +msgstr[1] "checkpoint:s sker för ofta (%d sekunder emellan)" + +#: postmaster/checkpointer.c:422 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "Överväg att öka konfigurationsparametern \"max_wal_size\"." + +#: postmaster/checkpointer.c:1032 +#, c-format +msgid "checkpoint request failed" +msgstr "checkpoint-behgäran misslyckades" + +#: postmaster/checkpointer.c:1033 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "Se senaste meddelanden i serverloggen för mer information." + +#: postmaster/checkpointer.c:1217 +#, c-format +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "minskade fsync-kön från %d poster till %d poster" + +#: postmaster/pgarch.c:155 +#, c-format +msgid "could not fork archiver: %m" +msgstr "kunde inte fork():a arkiveraren: %m" + +#: postmaster/pgarch.c:425 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode är påslagen, men ändå är archive_command inte satt" + +#: postmaster/pgarch.c:447 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "tog bort övergiven arkivstatusfil \"%s\": %m" + +#: postmaster/pgarch.c:457 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "borttagning av övergiven arkivstatusfil \"%s\" misslyckades för många gånger, kommer försöka igen senare" + +#: postmaster/pgarch.c:493 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "arkivering av write-ahead-logg-fil \"%s\" misslyckades för många gånger, kommer försöka igen senare" + +#: postmaster/pgarch.c:594 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "arkiveringskommando misslyckades med felkod %d" + +#: postmaster/pgarch.c:596 postmaster/pgarch.c:606 postmaster/pgarch.c:612 +#: postmaster/pgarch.c:621 +#, c-format +msgid "The failed archive command was: %s" +msgstr "Det misslyckade arkiveringskommandot var: %s" + +#: postmaster/pgarch.c:603 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "arkiveringskommandot terminerades med avbrott 0x%X" + +#: postmaster/pgarch.c:605 postmaster/postmaster.c:3742 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "Se C-include-fil \"ntstatus.h\" för en beskrivning av det hexdecimala värdet." + +#: postmaster/pgarch.c:610 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "arkiveringskommandot terminerades av signal %d: %s" + +#: postmaster/pgarch.c:619 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "arkiveringskommandot avslutade med okänd statuskod %d" + +#: postmaster/pgstat.c:419 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "kunde inte slå upp \"localhost\": %s" + +#: postmaster/pgstat.c:442 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "försöker med en annan adress till statistikinsamlare" + +#: postmaster/pgstat.c:451 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "kunde inte skapa uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:463 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "kunde inte göra bind på uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:474 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "kunde inte få adress till uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:490 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "kunde inte ansluta uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:511 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "kunde inte skicka testmeddelande till uttag (socket) för statistikinsamlaren: %m" + +#: postmaster/pgstat.c:537 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "select() misslyckades i statistikinsamlaren: %m" + +#: postmaster/pgstat.c:552 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "testmeddelande kom inte igenom på uttag (socket) för statistikinsamlare" + +#: postmaster/pgstat.c:567 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "kunde inte ta emot testmeddelande på uttag (socket) för statistikinsamlaren: %m" + +#: postmaster/pgstat.c:577 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "inkorrekt överföring av testmeddelande på uttag (socket) till statistikinsamlare" + +#: postmaster/pgstat.c:600 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "kunde inte sätta statistikinsamlarens uttag (socket) till ickeblockerande läge: %m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "stänger av statistikinsamlare då arbetsuttag (socket) saknas" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "kunde inte fork():a statistikinsamlaren: %m" + +#: postmaster/pgstat.c:1376 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "okänt återställningsmål \"%s\"" + +#: postmaster/pgstat.c:1377 +#, c-format +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "Målet måste vara \"archiver\" eller \"bgwriter\"." + +#: postmaster/pgstat.c:4561 +#, c-format +msgid "could not read statistics message: %m" +msgstr "kunde inte läsa statistikmeddelande: %m" + +#: postmaster/pgstat.c:4883 postmaster/pgstat.c:5046 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "kunde inte öppna temporär statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:4956 postmaster/pgstat.c:5091 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "kunde inte skriva temporär statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:4965 postmaster/pgstat.c:5100 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "kunde inte stänga temporär statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:4973 postmaster/pgstat.c:5108 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "kunde inte döpa om temporär statistikfil \"%s\" till \"%s\": %m" + +#: postmaster/pgstat.c:5205 postmaster/pgstat.c:5422 postmaster/pgstat.c:5576 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "kunde inte öppna statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:5217 postmaster/pgstat.c:5227 postmaster/pgstat.c:5248 +#: postmaster/pgstat.c:5259 postmaster/pgstat.c:5281 postmaster/pgstat.c:5296 +#: postmaster/pgstat.c:5359 postmaster/pgstat.c:5434 postmaster/pgstat.c:5454 +#: postmaster/pgstat.c:5472 postmaster/pgstat.c:5488 postmaster/pgstat.c:5506 +#: postmaster/pgstat.c:5522 postmaster/pgstat.c:5588 postmaster/pgstat.c:5600 +#: postmaster/pgstat.c:5612 postmaster/pgstat.c:5623 postmaster/pgstat.c:5648 +#: postmaster/pgstat.c:5670 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "korrupt statistikfil \"%s\"" + +#: postmaster/pgstat.c:5799 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "använder gammal statistik istället för aktuell data då statistikinsamlaren inte svarar" + +#: postmaster/pgstat.c:6129 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "databasens hashtabell har blivit korrupt vid uppstädning --- avbryter" + +#: postmaster/postmaster.c:733 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: ogiltigt argument till flagga -f: \"%s\"\n" + +#: postmaster/postmaster.c:819 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: ogiltigt argument till flagga -t: \"%s\"\n" + +#: postmaster/postmaster.c:870 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: ogiltigt argument: \"%s\"\n" + +#: postmaster/postmaster.c:912 +#, c-format +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) måste vara mindre än max_connections (%d)\n" + +#: postmaster/postmaster.c:919 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "WAL-arkivering kan inte slås på när wal_level är \"minimal\"" + +#: postmaster/postmaster.c:922 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WAL-strömning (max_wal_senders > 0) kräver wal_level \"replica\" eller \"logical\"" + +#: postmaster/postmaster.c:930 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: ogiltiga datumtokentabeller, det behöver lagas\n" + +#: postmaster/postmaster.c:1047 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "kunde inte skapa \"I/O completion port\" för barnkö" + +#: postmaster/postmaster.c:1113 +#, c-format +msgid "ending log output to stderr" +msgstr "avslutar loggutmatning till stderr" + +#: postmaster/postmaster.c:1114 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "Framtida loggutmatning kommer gå till logg-destination \"%s\"." + +#: postmaster/postmaster.c:1125 +#, c-format +msgid "starting %s" +msgstr "startar %s" + +#: postmaster/postmaster.c:1154 postmaster/postmaster.c:1252 +#: utils/init/miscinit.c:1597 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "ogiltigt listsyntax för parameter \"%s\"" + +#: postmaster/postmaster.c:1185 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "kunde inte skapa lyssnande uttag (socket) för \"%s\"" + +#: postmaster/postmaster.c:1191 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "kunde inte skapa TCP/IP-uttag (socket)" + +#: postmaster/postmaster.c:1274 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "kunde inte skapa unix-domän-uttag (socket) i katalog \"%s\"" + +#: postmaster/postmaster.c:1280 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "kunde inte skapa något Unix-domän-uttag (socket)" + +#: postmaster/postmaster.c:1292 +#, c-format +msgid "no socket created for listening" +msgstr "inget uttag (socket) skapat för lyssnande" + +#: postmaster/postmaster.c:1323 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: kunde inte ändra rättigheter på extern PID-fil \"%s\": %s\n" + +#: postmaster/postmaster.c:1327 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: kunde inte skriva extern PID-fil \"%s\": %s\n" + +#: postmaster/postmaster.c:1360 utils/init/postinit.c:215 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "kunde inte ladda pg_hba.conf" + +#: postmaster/postmaster.c:1386 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "postmaster blev flertrådad under uppstart" + +#: postmaster/postmaster.c:1387 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "Sätt omgivningsvariabeln LC_ALL till en giltig lokal." + +#: postmaster/postmaster.c:1488 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: kunde inte hitta matchande postgres-binär" + +#: postmaster/postmaster.c:1511 utils/misc/tzparser.c:340 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "Detta tyder på en inkomplett PostgreSQL-installation alternativt att filen \"%s\" har flyttats bort från sin korrekta plats." + +#: postmaster/postmaster.c:1538 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: kunde inte hitta databassystemet\n" +"Förväntade mig att hitta det i katalogen \"%s\",\n" +"men kunde inte öppna filen \"%s\": %s\n" + +#: postmaster/postmaster.c:1715 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "select() misslyckades i postmaster: %m" + +#: postmaster/postmaster.c:1870 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "stänger ner omedelbart då datakatalogens låsfil är ogiltig" + +#: postmaster/postmaster.c:1973 postmaster/postmaster.c:2004 +#, c-format +msgid "incomplete startup packet" +msgstr "ofullständigt startuppaket" + +#: postmaster/postmaster.c:1985 +#, c-format +msgid "invalid length of startup packet" +msgstr "ogiltig längd på startuppaket" + +#: postmaster/postmaster.c:2043 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "misslyckades att skicka SSL-förhandlingssvar: %m" + +#: postmaster/postmaster.c:2074 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "misslyckades att skicka GSSAPI-förhandlingssvar: %m" + +#: postmaster/postmaster.c:2104 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "inget stöd för framändans protokoll %u.%u: servern stöder %u.0 till %u.%u" + +#: postmaster/postmaster.c:2168 utils/misc/guc.c:6769 utils/misc/guc.c:6805 +#: utils/misc/guc.c:6875 utils/misc/guc.c:8226 utils/misc/guc.c:11072 +#: utils/misc/guc.c:11106 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "ogiltigt värde för parameter \"%s\": \"%s\"" + +#: postmaster/postmaster.c:2171 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "Giltiga värden är: \"false\", 0, \"true\", 1, \"database\"." + +#: postmaster/postmaster.c:2216 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "ogiltig startpaketlayout: förväntade en terminator som sista byte" + +#: postmaster/postmaster.c:2254 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "inget PostgreSQL-användarnamn angivet i startuppaketet" + +#: postmaster/postmaster.c:2318 +#, c-format +msgid "the database system is starting up" +msgstr "databassystemet startar upp" + +#: postmaster/postmaster.c:2323 +#, c-format +msgid "the database system is shutting down" +msgstr "databassystemet stänger ner" + +#: postmaster/postmaster.c:2328 +#, c-format +msgid "the database system is in recovery mode" +msgstr "databassystemet är återställningsläge" + +#: postmaster/postmaster.c:2333 storage/ipc/procarray.c:293 +#: storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:362 +#, c-format +msgid "sorry, too many clients already" +msgstr "ledsen, för många klienter" + +#: postmaster/postmaster.c:2423 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "fel nyckel i avbrytbegäran för process %d" + +#: postmaster/postmaster.c:2435 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "PID %d i avbrytbegäran matchade inte någon process" + +#: postmaster/postmaster.c:2706 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "mottog SIGHUP, läser om konfigurationsfiler" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2732 postmaster/postmaster.c:2736 +#, c-format +msgid "%s was not reloaded" +msgstr "%s laddades inte om" + +#: postmaster/postmaster.c:2746 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "SSL-konfiguration laddades inte om" + +#: postmaster/postmaster.c:2802 +#, c-format +msgid "received smart shutdown request" +msgstr "tog emot förfrågan om att stänga ner smart" + +#: postmaster/postmaster.c:2848 +#, c-format +msgid "received fast shutdown request" +msgstr "tog emot förfrågan om att stänga ner snabbt" + +#: postmaster/postmaster.c:2866 +#, c-format +msgid "aborting any active transactions" +msgstr "avbryter aktiva transaktioner" + +#: postmaster/postmaster.c:2890 +#, c-format +msgid "received immediate shutdown request" +msgstr "mottog begäran för omedelbar nedstängning" + +#: postmaster/postmaster.c:2965 +#, c-format +msgid "shutdown at recovery target" +msgstr "nedstängs vid återställningsmål" + +#: postmaster/postmaster.c:2983 postmaster/postmaster.c:3019 +msgid "startup process" +msgstr "uppstartprocess" + +#: postmaster/postmaster.c:2986 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "avbryter uppstart på grund av fel i startprocessen" + +#: postmaster/postmaster.c:3061 +#, c-format +msgid "database system is ready to accept connections" +msgstr "databassystemet är redo att ta emot anslutningar" + +#: postmaster/postmaster.c:3082 +msgid "background writer process" +msgstr "bakgrundsskrivarprocess" + +#: postmaster/postmaster.c:3136 +msgid "checkpointer process" +msgstr "checkpoint-process" + +#: postmaster/postmaster.c:3152 +msgid "WAL writer process" +msgstr "WAL-skrivarprocess" + +#: postmaster/postmaster.c:3167 +msgid "WAL receiver process" +msgstr "WAL-mottagarprocess" + +#: postmaster/postmaster.c:3182 +msgid "autovacuum launcher process" +msgstr "autovacuum-startprocess" + +#: postmaster/postmaster.c:3197 +msgid "archiver process" +msgstr "arkiveringsprocess" + +#: postmaster/postmaster.c:3213 +msgid "statistics collector process" +msgstr "statistikinsamlingsprocess" + +#: postmaster/postmaster.c:3227 +msgid "system logger process" +msgstr "system-logg-process" + +#: postmaster/postmaster.c:3291 +#, c-format +msgid "background worker \"%s\"" +msgstr "bakgrundsarbetare \"%s\"" + +#: postmaster/postmaster.c:3375 postmaster/postmaster.c:3395 +#: postmaster/postmaster.c:3402 postmaster/postmaster.c:3420 +msgid "server process" +msgstr "serverprocess" + +#: postmaster/postmaster.c:3474 +#, c-format +msgid "terminating any other active server processes" +msgstr "avslutar andra aktiva serverprocesser" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3729 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) avslutade med felkod %d" + +#: postmaster/postmaster.c:3731 postmaster/postmaster.c:3743 +#: postmaster/postmaster.c:3753 postmaster/postmaster.c:3764 +#, c-format +msgid "Failed process was running: %s" +msgstr "Misslyckad process körde: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3740 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) terminerades av avbrott 0x%X" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3750 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) terminerades av signal %d: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3762 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) avslutade med okänd status %d" + +#: postmaster/postmaster.c:3970 +#, c-format +msgid "abnormal database system shutdown" +msgstr "ej normal databasnedstängning" + +#: postmaster/postmaster.c:4010 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "alla serverprocesser är avslutade; initierar på nytt" + +#: postmaster/postmaster.c:4180 postmaster/postmaster.c:5599 +#: postmaster/postmaster.c:5986 +#, c-format +msgid "could not generate random cancel key" +msgstr "kunde inte skapa slumpad avbrytningsnyckel" + +#: postmaster/postmaster.c:4234 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "kunde inte fork():a ny process for uppkoppling: %m" + +#: postmaster/postmaster.c:4276 +msgid "could not fork new process for connection: " +msgstr "kunde inte fork():a ny process for uppkoppling: " + +#: postmaster/postmaster.c:4393 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "ansluting mottagen: värd=%s port=%s" + +#: postmaster/postmaster.c:4398 +#, c-format +msgid "connection received: host=%s" +msgstr "ansluting mottagen: värd=%s" + +#: postmaster/postmaster.c:4668 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "kunde inte köra serverprocess \"%s\": %m" + +#: postmaster/postmaster.c:4827 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "ger upp efter för många försök att reservera delat minne" + +#: postmaster/postmaster.c:4828 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Detta kan orsakas av ASLR eller antivirusprogram." + +#: postmaster/postmaster.c:5034 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "SSL-konfigurering kunde inte laddas i barnprocess" + +#: postmaster/postmaster.c:5166 +#, c-format +msgid "Please report this to <%s>." +msgstr "Rapportera gärna detta till <%s>." + +#: postmaster/postmaster.c:5259 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "databassystemet är redo att ta emot read-only-anslutningar" + +#: postmaster/postmaster.c:5527 +#, c-format +msgid "could not fork startup process: %m" +msgstr "kunde inte starta startup-processen: %m" + +#: postmaster/postmaster.c:5531 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "kunde inte starta process för bakgrundsskrivare: %m" + +#: postmaster/postmaster.c:5535 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "kunde inte fork:a bakgrundsprocess: %m" + +#: postmaster/postmaster.c:5539 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "kunde inte fork:a WAL-skrivprocess: %m" + +#: postmaster/postmaster.c:5543 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "kunde inte fork:a WAL-mottagarprocess: %m" + +#: postmaster/postmaster.c:5547 +#, c-format +msgid "could not fork process: %m" +msgstr "kunde inte fork:a process: %m" + +#: postmaster/postmaster.c:5744 postmaster/postmaster.c:5767 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "krav på databasanslutning fanns inte med vid registering" + +#: postmaster/postmaster.c:5751 postmaster/postmaster.c:5774 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "ogiltigt processläge i bakgrundsarbetare" + +#: postmaster/postmaster.c:5847 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "startar bakgrundsarbetarprocess \"%s\"" + +#: postmaster/postmaster.c:5859 +#, c-format +msgid "could not fork worker process: %m" +msgstr "kunde inte starta (fork) arbetarprocess: %m" + +#: postmaster/postmaster.c:5972 +#, c-format +msgid "no slot available for new worker process" +msgstr "ingen slot tillgänglig för ny arbetsprocess" + +#: postmaster/postmaster.c:6307 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "kunde inte duplicera uttag (socket) %d för att använda i backend: felkod %d" + +#: postmaster/postmaster.c:6339 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "kunde inte skapa ärvt uttag (socket): felkod %d\n" + +#: postmaster/postmaster.c:6368 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "kunde inte öppna bakändans variabelfil \"%s\": %s\n" + +#: postmaster/postmaster.c:6375 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "kunde inte läsa från bakändans variabelfil \"%s\": %s\n" + +#: postmaster/postmaster.c:6384 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "kunde inte ta bort fil \"%s\": %s\n" + +#: postmaster/postmaster.c:6401 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "kunde inte mappa in vy för bakgrundsvariabler: felkod %lu\n" + +#: postmaster/postmaster.c:6410 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "kunde inte avmappa vy för bakgrundsvariabler: felkod %lu\n" + +#: postmaster/postmaster.c:6417 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "kunde inte stänga \"handle\" till backend:ens parametervariabler: felkod %lu\n" + +#: postmaster/postmaster.c:6595 +#, c-format +msgid "could not read exit code for process\n" +msgstr "kunde inte läsa avslutningskod för process\n" + +#: postmaster/postmaster.c:6600 +#, c-format +msgid "could not post child completion status\n" +msgstr "kunde inte skicka barnets avslutningsstatus\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "kunde inte läsa från loggrör (pipe): %m" + +#: postmaster/syslogger.c:522 +#, c-format +msgid "logger shutting down" +msgstr "loggaren stänger ner" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "kunde inte skapa rör (pipe) för syslog: %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "kunde inte fork:a systemloggaren: %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "omdirigerar loggutmatning till logginsamlingsprocess" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "Framtida loggutmatning kommer dyka upp i katalog \"%s\"." + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "kunde inte omdirigera stdout: %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "kunde inte omdirigera stderr: %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "kunde inte skriva till loggfil: %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "kunde inte öppna loggfil \"%s\": %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "stänger av automatisk rotation (använd SIGHUP för att slå på igen)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för reguljära uttryck" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för reguljära uttryck" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "ogiltig tidslinje %u" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "ogiltig startposition för strömning" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "icketerminerad citerad sträng" + +#: replication/backup_manifest.c:231 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "förväntade sluttidslinje %u men hittade tidslinje %u" + +#: replication/backup_manifest.c:248 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "förväntade starttidslinje %u men hittade tidslinje %u" + +#: replication/backup_manifest.c:275 +#, c-format +msgid "start timeline %u not found in history of timeline %u" +msgstr "starttidslinje %u hittades inte i historiken för tidslinje %u" + +#: replication/backup_manifest.c:322 +#, c-format +msgid "could not rewind temporary file" +msgstr "kunde inte spola tillbaka temporär fil" + +#: replication/backup_manifest.c:349 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "kunde inte läsa från temporär fil: %m" + +#: replication/basebackup.c:108 +#, c-format +msgid "could not read from file \"%s\"" +msgstr "kunde inte läsa från fil \"%s\"" + +#: replication/basebackup.c:551 +#, c-format +msgid "could not find any WAL files" +msgstr "kunde inte hitta några WAL-filer" + +#: replication/basebackup.c:566 replication/basebackup.c:582 +#: replication/basebackup.c:591 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "kunde inte hitta WAL-fil \"%s\"" + +#: replication/basebackup.c:634 replication/basebackup.c:665 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "oväntad WAL-filstorlek \"%s\"" + +#: replication/basebackup.c:648 replication/basebackup.c:1752 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "basbackup kunde inte skicka data, avbryter backup" + +#: replication/basebackup.c:724 +#, c-format +msgid "%lld total checksum verification failure" +msgid_plural "%lld total checksum verification failures" +msgstr[0] "totalt %lld verifieringsfel av checksumma" +msgstr[1] "totalt %lld verifieringsfel av checksumma" + +#: replication/basebackup.c:731 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "misslyckad verifiering av checksumma under basbackup" + +#: replication/basebackup.c:784 replication/basebackup.c:793 +#: replication/basebackup.c:802 replication/basebackup.c:811 +#: replication/basebackup.c:820 replication/basebackup.c:831 +#: replication/basebackup.c:848 replication/basebackup.c:857 +#: replication/basebackup.c:869 replication/basebackup.c:893 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "duplicerad flagga \"%s\"" + +#: replication/basebackup.c:837 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d är utanför giltigt intervall för parameter \"%s\" (%d .. %d)" + +#: replication/basebackup.c:882 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "okänd manifestflagga: \"%s\"" + +#: replication/basebackup.c:898 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "okänd checksum-algoritm: \"%s\"" + +#: replication/basebackup.c:913 +#, c-format +msgid "manifest checksums require a backup manifest" +msgstr "manifestchecksummor kräver ett backup-manifest" + +#: replication/basebackup.c:1504 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "hoppar över specialfil \"%s\"" + +#: replication/basebackup.c:1623 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "ogiltigt segmentnummer %d i fil \"%s\"" + +#: replication/basebackup.c:1642 +#, c-format +msgid "could not verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "kunde inte verifiera checksumma i fil \"%s\", block %d: läsbufferstorlek %d och sidstorlek %d skiljer sig åt" + +#: replication/basebackup.c:1686 replication/basebackup.c:1716 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "kunde inte gör fseek i fil \"%s\": %m" + +#: replication/basebackup.c:1708 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "kunde inte läsa tillbaka block %d i fil \"%s\": %m" + +#: replication/basebackup.c:1732 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "checksumkontroll misslyckades i fil \"%s\", block %d: beräknade %X men förväntade %X" + +#: replication/basebackup.c:1739 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "ytterligare kontroller av checksummor i fil \"%s\" kommer inte rapporteras" + +#: replication/basebackup.c:1807 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "filen \"%s\" har totalt %d kontrollerad felaktiga checksumma" +msgstr[1] "filen \"%s\" har totalt %d kontrollerade felaktiga checksummor" + +#: replication/basebackup.c:1843 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "filnamnet är för långt för tar-format: \"%s\"" + +#: replication/basebackup.c:1848 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "mål för symbolisk länk är för långt för tar-format: filnamn \"%s\", mål \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, c-format +msgid "could not clear search path: %s" +msgstr "kunde inte nollställa sökväg: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:251 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "ogiltig anslutningssträngsyntax %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:275 +#, c-format +msgid "could not parse connection string: %s" +msgstr "kunde inte parsa anslutningssträng: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:347 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "kunde inte hämta databassystemidentifierare och tidslinje-ID från primära servern: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:358 +#: replication/libpqwalreceiver/libpqwalreceiver.c:576 +#, c-format +msgid "invalid response from primary server" +msgstr "ogiltigt svar från primär server" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:359 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "Kunde inte identifiera system: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:432 +#: replication/libpqwalreceiver/libpqwalreceiver.c:438 +#: replication/libpqwalreceiver/libpqwalreceiver.c:463 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "kunde inte starta WAL-strömning: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:486 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "kunde inte skicka meddelandet end-of-streaming till primären: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:508 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "oväntad resultatmängd efter end-of-streaming" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:522 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "fel vid nestängning av strömmande COPY: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:531 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "fel vid läsning av resultat från strömmningskommando: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 +#: replication/libpqwalreceiver/libpqwalreceiver.c:773 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "oväntat resultat efter CommandComplete: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:565 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "kan inte ta emot fil med tidslinjehistorik från primära servern: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:577 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "Förväntade 1 tupel med 2 fält, fick %d tupler med %d fält." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:737 +#: replication/libpqwalreceiver/libpqwalreceiver.c:788 +#: replication/libpqwalreceiver/libpqwalreceiver.c:794 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "kunde inte ta emot data från WAL-ström: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:813 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "kunde inte skicka data till WAL-ström: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:866 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "kunde inte skapa replikeringsslot \"%s\": %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:911 +#, c-format +msgid "invalid query response" +msgstr "ogiltigt frågerespons" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:912 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "Förväntade %d fält, fick %d fält." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:981 +#, c-format +msgid "the query interface requires a database connection" +msgstr "frågeinterface:et kräver en databasanslutning" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1012 +msgid "empty query" +msgstr "tom fråga" + +#: replication/logical/launcher.c:295 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "startar logisk replikeringsarbetare för prenumeration \"%s\"" + +#: replication/logical/launcher.c:302 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "kan inte starta logisk replikeringsarbetare när max_replication_slots = 0" + +#: replication/logical/launcher.c:382 +#, c-format +msgid "out of logical replication worker slots" +msgstr "slut på logiska replikeringsarbetarslots" + +#: replication/logical/launcher.c:383 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "Du kan behöva öka max_logical_replication_workers." + +#: replication/logical/launcher.c:438 +#, c-format +msgid "out of background worker slots" +msgstr "slut på bakgrundsarbetarslots" + +#: replication/logical/launcher.c:439 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "Du kan behöva öka max_worker_processes." + +#: replication/logical/launcher.c:638 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "logisk replikeringsarbetarslot %d är tom, kan inte ansluta" + +#: replication/logical/launcher.c:647 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "logiisk replikeringsarbetarslot %d används redan av en annan arbetare, kan inte ansluta" + +#: replication/logical/launcher.c:951 +#, c-format +msgid "logical replication launcher started" +msgstr "logisk replikeringsstartare startad" + +#: replication/logical/logical.c:87 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "logisk avkodning kräver wal_level >= logical" + +#: replication/logical/logical.c:92 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "logisk avkodning kräver en databasanslutning" + +#: replication/logical/logical.c:110 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "logisk avkodning kan inte användas under återställning" + +#: replication/logical/logical.c:258 replication/logical/logical.c:399 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "kan inte använda fysisk replikeringsslot för logisk avkodning" + +#: replication/logical/logical.c:263 replication/logical/logical.c:404 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "replikeringsslot \"%s\" har inte skapats i denna databasen" + +#: replication/logical/logical.c:270 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "kan inte skapa logisk replikeringsslot i transaktion som redan har utfört skrivningar" + +#: replication/logical/logical.c:444 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "startar logisk avkodning för slot \"%s\"" + +#: replication/logical/logical.c:446 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Strömmar transaktioner commit:ade efter %X/%X, läser WAL från %X/%X" + +#: replication/logical/logical.c:593 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "slot \"%s\", utdata-plugin \"%s\", i callback:en %s, associerad LSN %X/%X" + +#: replication/logical/logical.c:600 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "slot \"%s\", utdata-plugin \"%s\", i callback:en %s" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "måste vara superanvändare eller replikeringsroll för att använda replikeringsslottar" + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "slot-namn får inte vara null" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "flagg-array får inte vara null" + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "array:en måste vara endimensionell" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "array:en får inte innehålla null" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 +#: utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "array:en måste ha ett jämnt antal element" + +#: replication/logical/logicalfuncs.c:251 +#, c-format +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "kan inte längre få ändringar från replikeringsslot \"%s\"" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:648 +#, c-format +msgid "This slot has never previously reserved WAL, or has been invalidated." +msgstr "Denna slot har aldrig tidigare reserverat WAL eller har invaliderats." + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "utdata-plugin \"%s\" för logisk avkodning producerar binär utdata men funktionen \"%s\" förväntar sig textdata" + +#: replication/logical/origin.c:188 +#, c-format +msgid "only superusers can query or manipulate replication origins" +msgstr "bara superanvändare kan läsa eller ändra replikeringskällor" + +#: replication/logical/origin.c:193 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "kan inte se eller ändra replikeringskällor när max_replication_slots = 0" + +#: replication/logical/origin.c:198 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "kan inte ändra replikeringskällor under tiden återställning sker" + +#: replication/logical/origin.c:233 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "replikeringskälla \"%s\" finns inte" + +#: replication/logical/origin.c:324 +#, c-format +msgid "could not find free replication origin OID" +msgstr "kunde inte hitta ledig replikering-origin-OID" + +#: replication/logical/origin.c:372 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "kunde inte slänga replikeringskälla med OID %d som används av PID %d" + +#: replication/logical/origin.c:464 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "replikeringskälla med OID %u finns inte" + +#: replication/logical/origin.c:729 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "replikeringscheckpoint har fel magiskt tal %u istället för %u" + +#: replication/logical/origin.c:770 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "kunde inte hitta ledig replikeringsplats, öka max_replication_slots" + +#: replication/logical/origin.c:788 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "replikeringsslot-checkpoint har felaktig kontrollsumma %u, förväntade %u" + +#: replication/logical/origin.c:916 replication/logical/origin.c:1102 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "replikeringskälla med OID %d är redan aktiv för PID %d" + +#: replication/logical/origin.c:927 replication/logical/origin.c:1114 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "kunde inte hitta ledig replikerings-state-slot för replikerings-origin med OID %u" + +#: replication/logical/origin.c:929 replication/logical/origin.c:1116 +#: replication/slot.c:1762 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "Öka max_replication_slots och försök igen." + +#: replication/logical/origin.c:1073 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "kan inte ställa in replikeringskälla när en redan är inställd" + +#: replication/logical/origin.c:1153 replication/logical/origin.c:1369 +#: replication/logical/origin.c:1389 +#, c-format +msgid "no replication origin is configured" +msgstr "ingen replikeringskälla är konfigurerad" + +#: replication/logical/origin.c:1236 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "replikeringskällnamn \"%s\" är reserverat" + +#: replication/logical/origin.c:1238 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "Källnamn som startar med \"pg_\" är reserverade." + +#: replication/logical/relation.c:302 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "logisk replikeringsmålrelation \"%s.%s\" finns inte" + +#: replication/logical/relation.c:345 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "logisk replikeringsmålrelation \"%s.%s\" saknar några replikerade kolumner" + +#: replication/logical/relation.c:385 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "logisk replikeringsmålrelation \"%s.%s\" använder systemkolumner i REPLICA IDENTITY-index" + +#: replication/logical/reorderbuffer.c:2663 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "kunde inte skriva till datafil för XID %u: %m" + +#: replication/logical/reorderbuffer.c:2850 +#: replication/logical/reorderbuffer.c:2875 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "kunde inte läsa från reorderbuffer spill-fil: %m" + +#: replication/logical/reorderbuffer.c:2854 +#: replication/logical/reorderbuffer.c:2879 +#, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "kunde inte läsa från reorderbuffer spill-fil: läste %d istället för %u byte" + +#: replication/logical/reorderbuffer.c:3114 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "kunde inte radera fil \"%s\" vid borttagning av pg_replslot/%s/xid*: %m" + +#: replication/logical/reorderbuffer.c:3606 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "kunde inte läsa från fil \"%s\": läste %d istället för %d byte" + +#: replication/logical/snapbuild.c:606 +#, c-format +msgid "initial slot snapshot too large" +msgstr "initialt slot-snapshot är för stort" + +#: replication/logical/snapbuild.c:660 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "exporterade logisk avkodnings-snapshot: \"%s\" med %u transaktions-ID" +msgstr[1] "exporterade logisk avkodnings-snapshot: \"%s\" med %u transaktions-ID" + +#: replication/logical/snapbuild.c:1265 replication/logical/snapbuild.c:1358 +#: replication/logical/snapbuild.c:1912 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "logisk avkodning hittade konsistent punkt vid %X/%X" + +#: replication/logical/snapbuild.c:1267 +#, c-format +msgid "There are no running transactions." +msgstr "Det finns inga körande transaktioner." + +#: replication/logical/snapbuild.c:1309 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "logisk avkodning hittade initial startpunkt vid %X/%X" + +#: replication/logical/snapbuild.c:1311 replication/logical/snapbuild.c:1335 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Väntar på att transaktioner (cirka %d) äldre än %u skall gå klart." + +#: replication/logical/snapbuild.c:1333 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "logisk avkodning hittade initial konsistent punkt vid %X/%X" + +#: replication/logical/snapbuild.c:1360 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Det finns inte längre några gamla transaktioner." + +#: replication/logical/snapbuild.c:1754 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "snapbuild-state-fil \"%s\" har fel magiskt tal: %u istället för %u" + +#: replication/logical/snapbuild.c:1760 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "snapbuild-state-fil \"%s\" har en ej stödd version: %u istället för %u" + +#: replication/logical/snapbuild.c:1859 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "checksumma stämmer inte för snapbuild-state-fil \"%s\": är %u, skall vara %u" + +#: replication/logical/snapbuild.c:1914 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "Logisk avkodning kommer starta med sparat snapshot." + +#: replication/logical/snapbuild.c:1986 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "kunde inte parsa filnamn \"%s\"" + +#: replication/logical/tablesync.c:132 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "logisk replikerings tabellsynkroniseringsarbetare för prenumeration \"%s\", tabell \"%s\" är klar" + +#: replication/logical/tablesync.c:664 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "kunde inte hämta tabellinfo för tabell \"%s.%s\" från publicerare: %s" + +#: replication/logical/tablesync.c:670 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "tabell \"%s.%s\" hittades inte hos publicerare" + +#: replication/logical/tablesync.c:704 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "kunde inte hämta tabellinfo för tabell \"%s.%s\": %s" + +#: replication/logical/tablesync.c:791 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "kunde inte starta initial innehållskopiering för tabell \"%s.%s\": %s" + +#: replication/logical/tablesync.c:905 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "tabellkopiering kunde inte starta transaktion på publiceraren" + +#: replication/logical/tablesync.c:927 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "tabellkopiering kunde inte slutföra transaktion på publiceraren" + +#: replication/logical/worker.c:313 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "processar fjärrdata för replikeringsmålrelation \"%s.%s\" kolumn \"%s\", fjärrtyp %s, lokal typ %s" + +#: replication/logical/worker.c:552 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "ORIGIN-meddelande skickat i fel ordning" + +#: replication/logical/worker.c:702 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "publicerare skickade inte identitetskolumn för replika som förväntades av den logiska replikeringens målrelation \"%s.%s\"" + +#: replication/logical/worker.c:709 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "logisk replikeringsmålrelation \"%s.%s\" har varken REPLICA IDENTITY-index eller PRIMARY KEY och den publicerade relationen har inte REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:1394 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "ogiltig logisk replikeringsmeddelandetyp \"%c\"" + +#: replication/logical/worker.c:1537 +#, c-format +msgid "data stream from publisher has ended" +msgstr "dataströmmen från publiceraren har avslutats" + +#: replication/logical/worker.c:1692 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "avslutar logisk replikeringsarbetare på grund av timeout" + +#: replication/logical/worker.c:1837 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer stoppa då prenumerationen har tagits bort" + +#: replication/logical/worker.c:1851 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer stoppa då prenumerationen har stängts av" + +#: replication/logical/worker.c:1865 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om då uppkopplingsinformationen ändrats" + +#: replication/logical/worker.c:1879 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om då prenumerationen bytt namn" + +#: replication/logical/worker.c:1896 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om då replikeringsslotten bytt namn" + +#: replication/logical/worker.c:1910 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om då prenumerationens publiceringar ändrats" + +#: replication/logical/worker.c:2006 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration %u kommer inte starta då prenumerationen togs bort under uppstart" + +#: replication/logical/worker.c:2018 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer inte starta då prenumerationen stänges av under uppstart" + +#: replication/logical/worker.c:2036 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "logisk replikerings tabellsynkroniseringsarbetare för prenumeration \"%s\", tabell \"%s\" har startat" + +#: replication/logical/worker.c:2040 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" har startat" + +#: replication/logical/worker.c:2079 +#, c-format +msgid "subscription has no replication slot set" +msgstr "prenumeration har ingen replikeringsslot angiven" + +#: replication/pgoutput/pgoutput.c:147 +#, c-format +msgid "invalid proto_version" +msgstr "ogiltig proto_version" + +#: replication/pgoutput/pgoutput.c:152 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version \"%s\" är utanför giltigt intervall" + +#: replication/pgoutput/pgoutput.c:169 +#, c-format +msgid "invalid publication_names syntax" +msgstr "ogiltig publication_names-syntax" + +#: replication/pgoutput/pgoutput.c:211 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "klienten skickade proto_version=%d men vi stöder bara protokoll %d eller lägre" + +#: replication/pgoutput/pgoutput.c:217 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "klienten skickade proto_version=%d men vi stöder bara protokoll %d eller högre" + +#: replication/pgoutput/pgoutput.c:223 +#, c-format +msgid "publication_names parameter missing" +msgstr "saknar parameter publication_names" + +#: replication/slot.c:183 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "replikeringsslotnamn \"%s\" är för kort" + +#: replication/slot.c:192 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "replikeringsslotnamn \"%s\" är för långt" + +#: replication/slot.c:205 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "replikeringsslotnamn \"%s\" innehåller ogiltiga tecken" + +#: replication/slot.c:207 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "Replikeringsslotnamn får bara innehålla små bokstäver, nummer och understreck." + +#: replication/slot.c:254 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "replikeringsslot \"%s\" finns redan" + +#: replication/slot.c:264 +#, c-format +msgid "all replication slots are in use" +msgstr "alla replikeringsslots används" + +#: replication/slot.c:265 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Frigör en eller öka max_replication_slots." + +#: replication/slot.c:407 replication/slotfuncs.c:760 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "replikeringsslot \"%s\" existerar inte" + +#: replication/slot.c:445 replication/slot.c:1006 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "replikeringsslot \"%s\" är aktiv för PID %d" + +#: replication/slot.c:683 replication/slot.c:1314 replication/slot.c:1697 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "kunde inte ta bort katalog \"%s\"" + +#: replication/slot.c:1041 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "replikeringsslots kan bara användas om max_replication_slots > 0" + +#: replication/slot.c:1046 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "replikeringsslots kan bara användas om wal_level >= replica" + +#: replication/slot.c:1202 +#, c-format +msgid "terminating process %d because replication slot \"%s\" is too far behind" +msgstr "avslutar process %d då replikeringsslot \"%s\" är för långt efter" + +#: replication/slot.c:1221 +#, c-format +msgid "invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size" +msgstr "invaliderar slot \"%s\" då dess restart_lsn %X/%X överskrider max_slot_wal_keep_size" + +#: replication/slot.c:1635 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "replikeringsslotfil \"%s\" har fel magiskt nummer: %u istället för %u" + +#: replication/slot.c:1642 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "replikeringsslotfil \"%s\" har en icke stödd version %u" + +#: replication/slot.c:1649 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "replikeringsslotfil \"%s\" har felaktig längd %u" + +#: replication/slot.c:1685 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "kontrollsummefel för replikeringsslot-fil \"%s\": är %u, skall vara %u" + +#: replication/slot.c:1719 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "logisk replikeringsslot \"%s\" finns men wal_level < replica" + +#: replication/slot.c:1721 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Ändra wal_level till logical eller högre." + +#: replication/slot.c:1725 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "fysisk replikeringsslot \"%s\" finns men wal_level < replica" + +#: replication/slot.c:1727 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Ändra wal_level till replica eller högre." + +#: replication/slot.c:1761 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "för många aktiva replikeringsslottar innan nerstängning" + +#: replication/slotfuncs.c:624 +#, c-format +msgid "invalid target WAL LSN" +msgstr "ogiltig mål-LSN för WAL" + +#: replication/slotfuncs.c:646 +#, c-format +msgid "replication slot \"%s\" cannot be advanced" +msgstr "replikeringsslot \"%s\" kan inte avanceras" + +#: replication/slotfuncs.c:664 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "kan inte flytta fram replikeringsslot till %X/%X, minimum är %X/%X" + +#: replication/slotfuncs.c:772 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "kan inte kopiera fysisk replikeringsslot \"%s\" som en logisk replikeringsslot" + +#: replication/slotfuncs.c:774 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "kan inte kopiera logisk replikeringsslot \"%s\" som en fysisk replikeringsslot" + +#: replication/slotfuncs.c:781 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "kan inte kopiera en replikeringsslot som inte tidigare har reserverat WAL" + +#: replication/slotfuncs.c:857 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "kunde inte kopiera replikeringsslot \"%s\"" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "Källreplikeringsslotten ändrades på ett inkompatibelt sätt under copy-operationen." + +#: replication/slotfuncs.c:865 +#, c-format +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "kan inte kopiera ej slutförd replikeringsslot \"%s\"" + +#: replication/slotfuncs.c:867 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "Försök igen när källreplikeringsslottens confirmed_flush_lsn är giltig." + +#: replication/syncrep.c:257 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "avbryter väntan på synkron replikering samt avslutar anslutning på grund av ett administratörskommando" + +#: replication/syncrep.c:258 replication/syncrep.c:275 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "Transaktionen har redan commit:ats lokalt men har kanske inte replikerats till standby:en." + +#: replication/syncrep.c:274 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "avbryter väntan på synkron replikering efter användarens önskemål" + +#: replication/syncrep.c:416 +#, c-format +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "standby \"%s\" har nu synkron standby-prioritet %u" + +#: replication/syncrep.c:483 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "standby \"%s\" är nu en synkron standby med prioritet %u" + +#: replication/syncrep.c:487 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "standby \"%s\" är nu en kvorumkandidat för synkron standby" + +#: replication/syncrep.c:1034 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names-parser misslyckades" + +#: replication/syncrep.c:1040 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "antal synkrona standbys (%d) måste vara fler än noll" + +#: replication/walreceiver.c:171 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "avslutar wal-mottagarprocessen på grund av ett administratörskommando" + +#: replication/walreceiver.c:297 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "kunde inte ansluta till primärserver: %s" + +#: replication/walreceiver.c:343 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "databassystemets identifierare skiljer sig åt mellan primären och standby:en" + +#: replication/walreceiver.c:344 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "Primärens identifierare är %s, standby:ens identifierare är %s." + +#: replication/walreceiver.c:354 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "högsta tidslinjen %u i primären är efter återställningstidslinjen %u" + +#: replication/walreceiver.c:408 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "startade strömning av WAL från primären vid %X/%X på tidslinje %u" + +#: replication/walreceiver.c:413 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "återstartade WAL-strömning vid %X/%X på tidslinje %u" + +#: replication/walreceiver.c:442 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "kan inte fortsätta WAL-strömning, återställning har redan avslutats" + +#: replication/walreceiver.c:479 +#, c-format +msgid "replication terminated by primary server" +msgstr "replikering avslutad av primär server" + +#: replication/walreceiver.c:480 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "Slut på WAL nådd på tidslinje %u vid %X/%X." + +#: replication/walreceiver.c:568 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "avslutar wal-mottagare på grund av timeout" + +#: replication/walreceiver.c:606 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "primär server har ingen mer WAL på efterfrågad tidslinje %u" + +#: replication/walreceiver.c:622 replication/walreceiver.c:938 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "kunde inte stänga loggsegment %s: %m" + +#: replication/walreceiver.c:742 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "hämtar tidslinjehistorikfil för tidslinje %u från primära servern" + +#: replication/walreceiver.c:985 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "kunde inte skriva till loggfilsegment %s på offset %u, längd %lu: %m" + +#: replication/walsender.c:523 storage/smgr/md.c:1291 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "kunde inte söka (seek) till slutet av filen \"%s\": %m" + +#: replication/walsender.c:527 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "kunde inte söka till början av filen \"%s\": %m" + +#: replication/walsender.c:578 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM har inte körts före START_REPLICATION" + +#: replication/walsender.c:607 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "kan inte använda logisk replikeringsslot för fysisk replikering" + +#: replication/walsender.c:676 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "efterfrågad startpunkt %X/%X på tidslinje %u finns inte i denna servers historik" + +#: replication/walsender.c:680 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "Denna servers historik delade sig från tidslinje %u vid %X/%X." + +#: replication/walsender.c:725 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "efterfrågad startpunkt %X/%X är längre fram än denna servers flush:ade WAL-skrivposition %X/%X" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:976 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s får inte anropas i en transaktion" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:986 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s måste anropas i en transaktion" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:992 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s måste anropas i transaktions REPEATABLE READ-isolationsläge" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:998 +#, c-format +msgid "%s must be called before any query" +msgstr "%s måste anropas innan någon fråga" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1004 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s får inte anropas i en undertransaktion" + +#: replication/walsender.c:1148 +#, c-format +msgid "cannot read from logical replication slot \"%s\"" +msgstr "kan inte läsa från logisk replikeringsslot \"%s\"" + +#: replication/walsender.c:1150 +#, c-format +msgid "This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "Denna slot har invaliderats då den överskred maximal reserverad storlek." + +#: replication/walsender.c:1160 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "stänger ner walsender-process efter befordring" + +#: replication/walsender.c:1534 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "kan inte utföra nya kommandon när WAL-sändare är i stopp-läge" + +#: replication/walsender.c:1567 +#, c-format +msgid "received replication command: %s" +msgstr "tog emot replikeringskommando: %s" + +#: replication/walsender.c:1583 tcop/fastpath.c:279 tcop/postgres.c:1103 +#: tcop/postgres.c:1455 tcop/postgres.c:1716 tcop/postgres.c:2174 +#: tcop/postgres.c:2535 tcop/postgres.c:2614 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "aktuella transaktionen har avbrutits, alla kommandon ignoreras tills slutet på transaktionen" + +#: replication/walsender.c:1670 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "kan inte köra SQL-kommandon i WAL-sändare för fysisk replikering" + +#: replication/walsender.c:1715 replication/walsender.c:1731 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "oväntat EOF från standby-anslutning" + +#: replication/walsender.c:1745 +#, c-format +msgid "unexpected standby message type \"%c\", after receiving CopyDone" +msgstr "oväntat standby-meddelandetyp \"%c\" efter att vi tagit emot CopyDone" + +#: replication/walsender.c:1783 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "ogiltigt standby-meddelandetyp \"%c\"" + +#: replication/walsender.c:1824 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "oväntad meddelandetyp \"%c\"" + +#: replication/walsender.c:2242 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "avslutar walsender-process på grund av replikerings-timeout" + +#: replication/walsender.c:2319 +#, c-format +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\" har nu kommit ikapp servern uppströms" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:989 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "regel \"%s\" för relation \"%s\" existerar redan" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "regelhandlingar på OLD är inte implementerat" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "Använd vyer eller utlösare (trigger) istället." + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "regelhandlingar på NEW är inte implementerat" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "Använd utlösare (trigger) istället." + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "INSTEAD NOTHING-regler på SELECT är inte implementerat ännu" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "Använd vyer istället." + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "flera regelhandlingar på SELECT är inte implementerat" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "regler på SELECT måste ha handlingen INSTEAD SELECT" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "regler på SELECT får inte innehålla datamodifierande satser i WITH" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "händelsebegränsningar är inte implementerat för regler på SELECT" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "\"%s\" är redan en vy" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "vy-regel (rule) för \"%s\" måste ha namnet \"%s\"" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "kan inte konvertera partitionerad tabell \"%s\" till en vy" + +#: rewrite/rewriteDefine.c:440 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "kan inte konvertera partition \"%s\" till en vy" + +#: rewrite/rewriteDefine.c:449 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "kunde inte konvertera tabell \"%s\" till en vy då den inte är tom" + +#: rewrite/rewriteDefine.c:458 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "kunde inte konvertera tabell \"%s\" till en vy då den har utlösare" + +#: rewrite/rewriteDefine.c:460 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "Mer specifikt, tabellen kan inte vare inblandad i främmande-nyckelberoenden." + +#: rewrite/rewriteDefine.c:465 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "kunde inte konvertera tabell \"%s\" till en vy eftersom den har index" + +#: rewrite/rewriteDefine.c:471 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "kunde inte konvertera tabell \"%s\" till en vy då den har barntabeller" + +#: rewrite/rewriteDefine.c:477 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "kunde inte konvertera tabell \"%s\" till en vy eftersom den har radsäkerhet påslagen" + +#: rewrite/rewriteDefine.c:483 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "kunde inte konvertera tabell \"%s\" till en vy eftersom den har radsäkerhetspolicy" + +#: rewrite/rewriteDefine.c:510 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "kan inte ha flera RETURNING-listor i en regel" + +#: rewrite/rewriteDefine.c:515 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "RETURNING-listor stöds inte i villkorade regler" + +#: rewrite/rewriteDefine.c:519 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "RETURNING-listor stöds inte i icke-INSTEAD-regler" + +#: rewrite/rewriteDefine.c:683 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "SELECT-regelns mållista har för många poster" + +#: rewrite/rewriteDefine.c:684 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "RETURNING-lista har för många element" + +#: rewrite/rewriteDefine.c:711 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "kan inte konvertera en relation som har borttagna kolumner till en vy" + +#: rewrite/rewriteDefine.c:712 +#, c-format +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "kan inte skapa en RETURNING-lista för relationer som innehåller borttagna kolumner" + +#: rewrite/rewriteDefine.c:718 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "SELECT-regels målpost %d har ett annat kolumnnamn än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:720 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECT-målpost har namn \"%s\"." + +#: rewrite/rewriteDefine.c:729 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "SELECT-regels målpot %d har en annan typ än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:731 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "RETURNING-listans post %d har en annan typ än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:734 rewrite/rewriteDefine.c:758 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECT-målpost har typ %s men kolumnen har typ %s." + +#: rewrite/rewriteDefine.c:737 rewrite/rewriteDefine.c:762 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "RETURNING-listpost har typ %s men kolumnen har typ %s." + +#: rewrite/rewriteDefine.c:753 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "SELECT-regelns målpost %d har en annan storlek än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:755 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "RETURNING-listpost %d har en annan storlek än kolumnen\"%s\"" + +#: rewrite/rewriteDefine.c:772 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "SELECT-regels mållista har för få element" + +#: rewrite/rewriteDefine.c:773 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "RETURNING-lista har för få element" + +#: rewrite/rewriteDefine.c:866 rewrite/rewriteDefine.c:980 +#: rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "regel \"%s\" för relation \"%s\" existerar inte" + +#: rewrite/rewriteDefine.c:999 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "byta namn på en ON SELECT-regel tillåts inte" + +#: rewrite/rewriteHandler.c:545 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "WITH-frågenamn \"%s\" finns både i en regelhändelse och i frågan som skrivs om" + +#: rewrite/rewriteHandler.c:605 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "kan inte ha RETURNING-listor i multipla regler" + +#: rewrite/rewriteHandler.c:816 rewrite/rewriteHandler.c:828 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "kan inte sätta in i kolumn \"%s\"" + +#: rewrite/rewriteHandler.c:817 rewrite/rewriteHandler.c:839 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "Kolumn \"%s\" är en identitetskolumn definierad som GENERATED ALWAYS." + +#: rewrite/rewriteHandler.c:819 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Använd OVERRIDING SYSTEM VALUE för att överskugga." + +#: rewrite/rewriteHandler.c:838 rewrite/rewriteHandler.c:845 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "kolumn \"%s\" kan bara uppdateras till DEFAULT" + +#: rewrite/rewriteHandler.c:1014 rewrite/rewriteHandler.c:1032 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "flera tilldelningar till samma kolumn \"%s\"" + +#: rewrite/rewriteHandler.c:2062 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "oändlig rekursion detekterad i policy för relation \"%s\"" + +#: rewrite/rewriteHandler.c:2382 +msgid "Junk view columns are not updatable." +msgstr "Skräpkolumner i vy är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2387 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "Vykolumner som inte är kolumner i dess basrelation är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2390 +msgid "View columns that refer to system columns are not updatable." +msgstr "Vykolumner som refererar till systemkolumner är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2393 +msgid "View columns that return whole-row references are not updatable." +msgstr "Vykolumner som returnerar hel-rad-referenser är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2454 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "Vyer som innehåller DISTINCT är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2457 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "Vyer som innehåller GROUP BY är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2460 +msgid "Views containing HAVING are not automatically updatable." +msgstr "Vyer som innehåller HAVING är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2463 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "Vyer som innehåller UNION, INTERSECT eller EXCEPT är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2466 +msgid "Views containing WITH are not automatically updatable." +msgstr "Vyer som innehåller WITH är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2469 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "Vyer som innehåller LIMIT eller OFFSET är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2481 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "Vyer som returnerar aggregatfunktioner är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2484 +msgid "Views that return window functions are not automatically updatable." +msgstr "Vyer som returnerar fönsterfunktioner uppdateras inte automatiskt." + +#: rewrite/rewriteHandler.c:2487 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "Vyer som returnerar mängd-returnerande funktioner är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2494 rewrite/rewriteHandler.c:2498 +#: rewrite/rewriteHandler.c:2506 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "Vyer som inte läser från en ensam tabell eller vy är inte automatiskt uppdateringsbar." + +#: rewrite/rewriteHandler.c:2509 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "Vyer som innehåller TABLESAMPLE är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2533 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "Vyer som inte har några uppdateringsbara kolumner är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:3010 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "kan inte insert:a i kolumn \"%s\" i vy \"%s\"" + +#: rewrite/rewriteHandler.c:3018 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "kan inte uppdatera kolumn \"%s\" i view \"%s\"" + +#: rewrite/rewriteHandler.c:3496 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "DO INSTEAD NOTHING-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3510 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "villkorliga DO INSTEAD-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3514 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "DO ALSO-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3519 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "fler-satsiga DO INSTEAD-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3710 rewrite/rewriteHandler.c:3718 +#: rewrite/rewriteHandler.c:3726 +#, c-format +msgid "Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "Vyer med villkorliga DO INSTEAD-regler är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:3819 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "kan inte utföra INSERT RETURNING på relation \"%s\"" + +#: rewrite/rewriteHandler.c:3821 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "Du behöver en villkorslös ON INSERT DO INSTEAD-regel med en RETURNING-klausul." + +#: rewrite/rewriteHandler.c:3826 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "kan inte utföra UPDATE RETURNING på relation \"%s\"" + +#: rewrite/rewriteHandler.c:3828 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "Du behöver en villkorslös ON UPDATE DO INSTEAD-regel med en RETURNING-klausul." + +#: rewrite/rewriteHandler.c:3833 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "kan inte utföra DELETE RETURNING på relation \"%s\"" + +#: rewrite/rewriteHandler.c:3835 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "Du behöver en villkorslös ON DELETE DO INSTEAD-regel med en RETURNING-klausul." + +#: rewrite/rewriteHandler.c:3853 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "INSERT med ON CONFLICT-klausul kan inte användas med tabell som har INSERT- eller UPDATE-regler" + +#: rewrite/rewriteHandler.c:3910 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "WITH kan inte användas i en fråga där regler skrivit om den till flera olika frågor" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "villkorliga hjälpsatser är inte implementerat" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "WHERE CURRENT OF för en vy är inte implementerat" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "NEW-variabler i ON UPDATE-regler kan inte referera till kolumner som är del av en multiple uppdatering i subjektets UPDATE-kommando" + +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "ej avslutad /*-kommentar" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "ej avslutad bitsträngslitteral" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "ej avslutad hexadecimal stränglitteral" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "osäker användning av strängkonstand med Unicode-escape:r" + +#: scan.l:543 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "Strängkonstanter som innehåller Unicode-escapesekvenser kan inte användas när standard_conforming_strings är av." + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "tidigare state i xqs som ej kan hanteras" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Unicode-escapesekvenser måste vara \\uXXXX eller \\UXXXXXXXX." + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "osäker användning av \\' i stränglitteral" + +#: scan.l:690 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "Använd '' för att inkludera ett enkelcitattecken i en sträng. \\' är inte säkert i klient-teckenkodning." + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "icke terminerad dollarciterad sträng" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "noll-längds avdelad identifierare" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "icke terminerad citerad identifierare" + +#: scan.l:963 +msgid "operator too long" +msgstr "operatorn är för lång" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1171 +#, c-format +msgid "%s at end of input" +msgstr "%s vid slutet av indatan" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1179 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s vid eller nära \"%s\"" + +#: scan.l:1373 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "ickestandard användning av \\' i stränglitteral" + +#: scan.l:1374 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "Använd '' för att skriva citattecken i strängar eller använd escape-strängsyntac (E'...')." + +#: scan.l:1383 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "ickestandard användning av \\\\ i strängslitteral" + +#: scan.l:1384 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Använd escape-strängsyntax för bakstreck, dvs. E'\\\\'." + +#: scan.l:1398 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "ickestandard användning av escape i stränglitteral" + +#: scan.l:1399 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Använd escape-strängsyntax, dvs E'\\r\\n'." + +#: snowball/dict_snowball.c:199 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "det finns ingen Snowball-stemmer för språk \"%s\" och kodning \"%s\"" + +#: snowball/dict_snowball.c:222 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "multipla StoppOrd-parametrar" + +#: snowball/dict_snowball.c:231 +#, c-format +msgid "multiple Language parameters" +msgstr "multipla parametrar \"Language\"" + +#: snowball/dict_snowball.c:238 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "okänd Snowball-parameter: \"%s\"" + +#: snowball/dict_snowball.c:246 +#, c-format +msgid "missing Language parameter" +msgstr "saknar parameter \"Language\"" + +#: statistics/dependencies.c:667 statistics/dependencies.c:720 +#: statistics/mcv.c:1477 statistics/mcv.c:1508 statistics/mvdistinct.c:348 +#: statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:42 +#: utils/adt/pseudotypes.c:76 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "kan inte acceptera ett värde av type %s" + +#: statistics/extended_stats.c:145 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "statistikobjekt \"%s.%s\" kunde inte beräknas för relation \"%s.%s\"" + +#: statistics/mcv.c:1365 utils/adt/jsonfuncs.c:1800 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "en funktion med post som värde anropades i sammanhang där poster inte kan godtagas." + +#: storage/buffer/bufmgr.c:588 storage/buffer/bufmgr.c:669 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "får inte röra temporära tabeller som tillhör andra sessioner" + +#: storage/buffer/bufmgr.c:825 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "oväntad data efter EOF i block %u för relation %s" + +#: storage/buffer/bufmgr.c:827 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "Detta beteende har observerats med buggiga kärnor; fundera på att uppdatera ditt system." + +#: storage/buffer/bufmgr.c:925 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "felaktig sida i block %u för relation %s; nollställer sidan" + +#: storage/buffer/bufmgr.c:4211 +#, c-format +msgid "could not write block %u of %s" +msgstr "kunde inte skriva block %u av %s" + +#: storage/buffer/bufmgr.c:4213 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Multipla fel --- skrivfelet kan vara permanent." + +#: storage/buffer/bufmgr.c:4234 storage/buffer/bufmgr.c:4253 +#, c-format +msgid "writing block %u of relation %s" +msgstr "skriver block %u i relation %s" + +#: storage/buffer/bufmgr.c:4556 +#, c-format +msgid "snapshot too old" +msgstr "snapshot för gammal" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "ingen tom lokal buffer tillgänglig" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "kan inte komma åt temporära tabeller under en parallell operation" + +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "kunde inte öppna temporär fil \"%s\" från BufFile \"%s\": %m" + +#: storage/file/buffile.c:795 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "kunde inte bestämma storlek på temporär fil \"%s\" från BufFile \"%s\": %m" + +#: storage/file/fd.c:508 storage/file/fd.c:580 storage/file/fd.c:616 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "kunde inte flush:a smutsig data: %m" + +#: storage/file/fd.c:538 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "kunde inte lista ut storlek på smutsig data: %m" + +#: storage/file/fd.c:590 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "kunde inte göra munmap() vid flush:ning av data: %m" + +#: storage/file/fd.c:798 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "kunde inte länka fil \"%s\" till \"%s\": %m" + +#: storage/file/fd.c:881 +#, c-format +msgid "getrlimit failed: %m" +msgstr "getrlimit misslyckades: %m" + +#: storage/file/fd.c:971 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "otillräckligt antal fildeskriptorer tillgängligt för att starta serverprocessen" + +#: storage/file/fd.c:972 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "Systemet tillåter %d, vi behöver minst %d." + +#: storage/file/fd.c:1023 storage/file/fd.c:2357 storage/file/fd.c:2467 +#: storage/file/fd.c:2618 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "slut på fildeskriptorer: %m; frigör och försök igen" + +#: storage/file/fd.c:1397 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "temporär fil: sökväg \"%s\", storlek %lu" + +#: storage/file/fd.c:1528 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "kunde inte skapa temporär katalog \"%s\": %m" + +#: storage/file/fd.c:1535 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "kunde inte skapa temporär underkatalog \"%s\": %m" + +#: storage/file/fd.c:1728 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "kan inte skapa temporär fil \"%s\": %m" + +#: storage/file/fd.c:1763 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "kunde inte öppna temporär fil \"%s\": %m" + +# unlink refererar till unix-funktionen unlink() så den översätter vi inte +#: storage/file/fd.c:1804 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "kunde inte unlink:a temporär fil \"%s\": %m" + +#: storage/file/fd.c:2068 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "storlek på temporär fil överskrider temp_file_limit (%dkB)" + +#: storage/file/fd.c:2333 storage/file/fd.c:2392 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "överskred maxAllocatedDescs (%d) vid försök att öppna fil \"%s\"" + +#: storage/file/fd.c:2437 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "överskred maxAllocatedDescs (%d) vid försök att köra kommando \"%s\"" + +#: storage/file/fd.c:2594 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "överskred maxAllocatedDescs (%d) vid försök att öppna katalog \"%s\"" + +#: storage/file/fd.c:3122 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "oväntad fil hittades i katalogen för temporära filer: \"%s\"" + +#: storage/file/sharedfileset.c:111 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "kunde inte koppla till en SharedFileSet som redan tagits bort" + +#: storage/ipc/dsm.c:338 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "dynamiskt delat minnes kontrollsegment är korrupt" + +#: storage/ipc/dsm.c:399 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "dynamiskt delat minnes kontrollsegment är inte giltigt" + +#: storage/ipc/dsm.c:494 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "för många dynamiska delade minnessegment" + +#: storage/ipc/dsm_impl.c:230 storage/ipc/dsm_impl.c:526 +#: storage/ipc/dsm_impl.c:630 storage/ipc/dsm_impl.c:801 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "kunde inte avmappa delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:240 storage/ipc/dsm_impl.c:536 +#: storage/ipc/dsm_impl.c:640 storage/ipc/dsm_impl.c:811 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "kunde inte ta bort delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:711 +#: storage/ipc/dsm_impl.c:825 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "kunde inte öppna delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:289 storage/ipc/dsm_impl.c:552 +#: storage/ipc/dsm_impl.c:756 storage/ipc/dsm_impl.c:849 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "kunde inte göra stat() på delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:900 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "kunde inte ändra storlek på delat minnessegment \"%s\" till %zu byte: %m" + +#: storage/ipc/dsm_impl.c:338 storage/ipc/dsm_impl.c:573 +#: storage/ipc/dsm_impl.c:732 storage/ipc/dsm_impl.c:922 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "kunde inte mappa delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:508 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "kunde inte hämta delat minnessegment: %m" + +#: storage/ipc/dsm_impl.c:696 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "kunde inte skapa delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:933 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "kunde inte stänga delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:972 storage/ipc/dsm_impl.c:1020 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "kunde inte duplicera handle för \"%s\": %m" + +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:940 storage/ipc/latch.c:1095 storage/ipc/latch.c:1308 +#: storage/ipc/latch.c:1461 storage/ipc/latch.c:1581 +#, c-format +msgid "%s failed: %m" +msgstr "%s misslyckades: %m" + +#: storage/ipc/procarray.c:3014 +#, c-format +msgid "database \"%s\" is being used by prepared transactions" +msgstr "databasen \"%s\" används av förberedda transationer" + +#: storage/ipc/procarray.c:3046 storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "måste vara superanvändare för stoppa superanvändares process" + +#: storage/ipc/procarray.c:3053 storage/ipc/signalfuncs.c:147 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "måste vara medlem i den roll vars process håller på att avslutas eller medlem i pg_signal_backend" + +#: storage/ipc/shm_mq.c:368 +#, c-format +msgid "cannot send a message of size %zu via shared memory queue" +msgstr "kan inte skicka ett meddelande med storlek %zu via kö i delat minne" + +#: storage/ipc/shm_mq.c:694 +#, c-format +msgid "invalid message size %zu in shared memory queue" +msgstr "ogiltig meddelandestorlek %zu i kö i delat minne" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:982 +#: storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 storage/lmgr/lock.c:4175 +#: storage/lmgr/lock.c:4240 storage/lmgr/lock.c:4532 +#: storage/lmgr/predicate.c:2401 storage/lmgr/predicate.c:2416 +#: storage/lmgr/predicate.c:3898 storage/lmgr/predicate.c:5009 +#: utils/hash/dynahash.c:1067 +#, c-format +msgid "out of shared memory" +msgstr "slut på delat minne" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "slut på delat minne (%zu byte efterfrågat)" + +#: storage/ipc/shmem.c:441 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "kunde inte skapa ShmemIndex-post för datastrukturen \"%s\"" + +#: storage/ipc/shmem.c:456 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "ShmemIndex-poststorlek är fel för datastruktur \"%s\": förväntade %zu var %zu" + +#: storage/ipc/shmem.c:475 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "otillräckligt delat minne för datastruktur \"%s\" (efterfrågade %zu byte)" + +#: storage/ipc/shmem.c:507 storage/ipc/shmem.c:526 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "efterfrågad delat minnesstorlek överskrider size_t" + +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d är inte en PostgreSQL serverprocess" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1366 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "kunde inte skicka signal till process %d: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "måste vara superanvändare för att avbryta superanvändares fråga" + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "måste vara medlem i den roll vars fråga håller på att avbrytas eller medlem i pg_signal_backend" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "måste vara superanvändare för att rotera loggfiler med adminpack 1.0" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:253 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Du kanske kan använda %s istället som är en del av core." + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "rotering är inte möjligt då logginsamling inte är aktiverad" + +#: storage/ipc/standby.c:580 tcop/postgres.c:3177 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "avbryter sats på grund av konflikt med återställning" + +#: storage/ipc/standby.c:581 tcop/postgres.c:2469 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "Användartransaktion orsakade deadlock för buffer vid återställning." + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "pg_largeobject-post för OID %u, sida %d har ogiltig datafältstorlek %d" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "ogiltiga flaggor för att öppna stort objekt: %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "ogiltig whence-inställning: %d" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "ogiltig storlek för stort objects skrivningbegäran: %d" + +#: storage/lmgr/deadlock.c:1124 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "Process %d väntar på %s för %s; blockerad av process %d." + +#: storage/lmgr/deadlock.c:1143 +#, c-format +msgid "Process %d: %s" +msgstr "Process %d: %s" + +#: storage/lmgr/deadlock.c:1152 +#, c-format +msgid "deadlock detected" +msgstr "deadlock upptäckt" + +#: storage/lmgr/deadlock.c:1155 +#, c-format +msgid "See server log for query details." +msgstr "Se server-logg för frågedetaljer." + +#: storage/lmgr/lmgr.c:830 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "vid uppdatering av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:833 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "vid borttagning av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:836 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "vid låsning av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:839 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "vid låsning av uppdaterad version (%u,%u) av tupel i relation \"%s\"" + +#: storage/lmgr/lmgr.c:842 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "vid insättning av indextupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:845 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "vid kontroll av unikhet av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:848 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "vid återkontroll av uppdaterad tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:851 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "vid kontroll av uteslutningsvillkor av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:1106 +#, c-format +msgid "relation %u of database %u" +msgstr "relation %u i databasen %u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "utökning av relation %u i databas %u" + +#: storage/lmgr/lmgr.c:1118 +#, c-format +msgid "pg_database.datfrozenxid of database %u" +msgstr "pg_database.datfrozenxid för databas %u" + +#: storage/lmgr/lmgr.c:1123 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "sida %u i relation %u i databas %u" + +#: storage/lmgr/lmgr.c:1130 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "tuple (%u,%u) i relation %u i databas %u" + +#: storage/lmgr/lmgr.c:1138 +#, c-format +msgid "transaction %u" +msgstr "transaktion %u" + +#: storage/lmgr/lmgr.c:1143 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "vituell transaktion %d/%u" + +#: storage/lmgr/lmgr.c:1149 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "spekulativ token %u för transaktion %u" + +#: storage/lmgr/lmgr.c:1155 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "objekt %u av klass %u i databas %u" + +#: storage/lmgr/lmgr.c:1163 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "användarlås [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1170 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "rådgivande lås [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1178 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "okänd låsetikettyp %d" + +#: storage/lmgr/lock.c:803 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "kan inte ta låsläge %s på databasobjekt när återställning pågår" + +#: storage/lmgr/lock.c:805 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "Bara RowExclusiveLock eller lägre kan tas på databasobjekt under återställning." + +#: storage/lmgr/lock.c:983 storage/lmgr/lock.c:1021 storage/lmgr/lock.c:2846 +#: storage/lmgr/lock.c:4176 storage/lmgr/lock.c:4241 storage/lmgr/lock.c:4533 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "Du kan behöva öka parametern max_locks_per_transaction." + +#: storage/lmgr/lock.c:3292 storage/lmgr/lock.c:3408 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "kan inte göra PREPARE samtidigt som vi håller lås på sessionsnivå och transaktionsnivå för samma objekt" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "ej tillräckligt med element i RWConflictPool för att spara ner en läs/skriv-konflikt" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "Du kan behöva köra färre samtidiga transaktioner eller öka max_connections." + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "ej tillräckligt med element i RWConflictPool för att spara ner en potentiell läs/skriv-konflikt" + +#: storage/lmgr/predicate.c:1535 +#, c-format +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "deferrable-snapshot var osäklert; försöker med ett nytt" + +#: storage/lmgr/predicate.c:1624 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "\"default_transaction_isolation\" är satt till \"serializable\"." + +#: storage/lmgr/predicate.c:1625 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "Du kan använda \"SET default_transaction_isolation = 'repeatable read'\" för att ändra standardvärdet." + +#: storage/lmgr/predicate.c:1676 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "en snapshot-importerande transaktion får inte vara READ ONLY DEFERRABLE" + +#: storage/lmgr/predicate.c:1755 utils/time/snapmgr.c:623 +#: utils/time/snapmgr.c:629 +#, c-format +msgid "could not import the requested snapshot" +msgstr "kunde inte importera efterfrågat snapshot" + +#: storage/lmgr/predicate.c:1756 utils/time/snapmgr.c:630 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "Källprocessen med PID %d kör inte längre." + +#: storage/lmgr/predicate.c:2402 storage/lmgr/predicate.c:2417 +#: storage/lmgr/predicate.c:3899 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "Du kan behöva öka parametern max_pred_locks_per_transaction." + +#: storage/lmgr/predicate.c:4030 storage/lmgr/predicate.c:4066 +#: storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4107 +#: storage/lmgr/predicate.c:4146 storage/lmgr/predicate.c:4388 +#: storage/lmgr/predicate.c:4725 storage/lmgr/predicate.c:4737 +#: storage/lmgr/predicate.c:4780 storage/lmgr/predicate.c:4818 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "kunde inte serialisera åtkomst på grund av läs/skriv-beroenden bland transaktionerna" + +#: storage/lmgr/predicate.c:4032 storage/lmgr/predicate.c:4068 +#: storage/lmgr/predicate.c:4101 storage/lmgr/predicate.c:4109 +#: storage/lmgr/predicate.c:4148 storage/lmgr/predicate.c:4390 +#: storage/lmgr/predicate.c:4727 storage/lmgr/predicate.c:4739 +#: storage/lmgr/predicate.c:4782 storage/lmgr/predicate.c:4820 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "Transaktionen kan lyckas om den körs igen." + +#: storage/lmgr/proc.c:358 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "antalet efterfrågade standby-anslutningar överskrider max_wal_senders (nu %d)" + +#: storage/lmgr/proc.c:1337 +#, c-format +msgid "Process %d waits for %s on %s." +msgstr "Process %d väntar på %s för %s." + +#: storage/lmgr/proc.c:1348 +#, c-format +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "skickar avbryt till blockerande autovacuum-PID %d" + +#: storage/lmgr/proc.c:1468 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "process %d undvek deadlock på %s för %s genom att kasta om köordningen efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1483 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "process %d upptäckte deadlock medan den väntade på %s för %s efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1492 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "process %d väntar fortfarande på %s för %s efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1499 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "process %d fick %s på %s efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1515 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "process %d misslyckades att ta %s på %s efter %ld.%03d ms" + +#: storage/page/bufpage.c:145 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "sidverifiering misslyckades, beräknade kontrollsumma %u men förväntade %u" + +#: storage/page/bufpage.c:209 storage/page/bufpage.c:503 +#: storage/page/bufpage.c:740 storage/page/bufpage.c:873 +#: storage/page/bufpage.c:969 storage/page/bufpage.c:1081 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "korrupta sidpekare: lägre = %u, övre = %u, special = %u" + +#: storage/page/bufpage.c:525 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "korrupt radpekare: %u" + +#: storage/page/bufpage.c:552 storage/page/bufpage.c:924 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "trasiga postlängder: totalt %u, tillgänglig plats %u" + +#: storage/page/bufpage.c:759 storage/page/bufpage.c:897 +#: storage/page/bufpage.c:985 storage/page/bufpage.c:1097 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "korrupt radpekare: offset = %u, storlek = %u" + +#: storage/smgr/md.c:333 storage/smgr/md.c:836 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "kunde inte trunkera fil \"%s\": %m" + +#: storage/smgr/md.c:407 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "kan inte utöka fil \"%s\" utöver %u block" + +#: storage/smgr/md.c:422 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "kunde inte utöka fil \"%s\": %m" + +#: storage/smgr/md.c:424 storage/smgr/md.c:431 storage/smgr/md.c:719 +#, c-format +msgid "Check free disk space." +msgstr "Kontrollera ledigt diskutrymme." + +#: storage/smgr/md.c:428 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "kunde inte utöka fil \"%s\": skrev bara %d av %d byte vid block %u" + +#: storage/smgr/md.c:640 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "kunde inte läsa block %u i fil \"%s\": %m" + +#: storage/smgr/md.c:656 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "kunde inte läsa block %u i fil \"%s\": läste bara %d av %d byte" + +#: storage/smgr/md.c:710 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "kunde inte skriva block %u i fil \"%s\": %m" + +#: storage/smgr/md.c:715 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "kunde inte skriva block %u i fil \"%s\": skrev bara %d av %d byte" + +#: storage/smgr/md.c:807 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "kunde inte trunkera fil \"%s\" till %u block: den är bara %u block nu" + +#: storage/smgr/md.c:862 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "kunde inte trunkera fil \"%s\" till %u block: %m" + +#: storage/smgr/md.c:957 +#, c-format +msgid "could not forward fsync request because request queue is full" +msgstr "kunde inte skicka vidare fsync-förfrågan då kön för förfrågningar är full" + +#: storage/smgr/md.c:1256 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "kunde inte öppna fil \"%s\" (målblock %u): föregående segment är bara %u block" + +#: storage/smgr/md.c:1270 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "kunde inte öppna fil \"%s\" (målblock %u): %m" + +#: storage/sync/sync.c:401 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "kunde inte fsync:a fil \"%s\" men försöker igen: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "ogiltig argumentstorlek %d i funktionsaropsmeddelande" + +#: tcop/fastpath.c:307 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "fastpath funktionsanrop: \"%s\" (OID %u)" + +#: tcop/fastpath.c:389 tcop/postgres.c:1323 tcop/postgres.c:1581 +#: tcop/postgres.c:2013 tcop/postgres.c:2250 +#, c-format +msgid "duration: %s ms" +msgstr "varaktighet %s ms" + +#: tcop/fastpath.c:393 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "varaktighet: %s ms fastpath funktionsanrop: \"%s\" (OID %u)" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "meddelande för funktionsanrop innehåller %d argument men funktionen kräver %d" + +#: tcop/fastpath.c:437 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "meddelande för funktioonsanrop innehåller %d argumentformat men %d argument" + +#: tcop/fastpath.c:524 tcop/fastpath.c:607 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "inkorrekt binärt dataformat i funktionsargument %d" + +#: tcop/postgres.c:355 tcop/postgres.c:391 tcop/postgres.c:418 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "oväntat EOF från klienten" + +#: tcop/postgres.c:441 tcop/postgres.c:453 tcop/postgres.c:464 +#: tcop/postgres.c:476 tcop/postgres.c:4539 +#, c-format +msgid "invalid frontend message type %d" +msgstr "ogiltig frontend-meddelandetyp %d" + +#: tcop/postgres.c:1042 +#, c-format +msgid "statement: %s" +msgstr "sats: %s" + +#: tcop/postgres.c:1328 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "varaktighet: %s ms sats: %s" + +#: tcop/postgres.c:1377 +#, c-format +msgid "parse %s: %s" +msgstr "parse %s: %s" + +#: tcop/postgres.c:1434 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "kan inte stoppa in multipla kommandon i en förberedd sats" + +#: tcop/postgres.c:1586 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "varaktighet: %s ms parse %s: %s" + +#: tcop/postgres.c:1633 +#, c-format +msgid "bind %s to %s" +msgstr "bind %s till %s" + +#: tcop/postgres.c:1652 tcop/postgres.c:2516 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "förberedd sats utan namn existerar inte" + +#: tcop/postgres.c:1693 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "bind-meddelande har %d parameterformat men %d parametrar" + +#: tcop/postgres.c:1699 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "bind-meddelande ger %d parametrar men förberedd sats \"%s\" kräver %d" + +#: tcop/postgres.c:1897 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "inkorrekt binärdataformat i bind-parameter %d" + +#: tcop/postgres.c:2018 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "varaktighet: %s ms bind %s%s%s: %s" + +#: tcop/postgres.c:2068 tcop/postgres.c:2600 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "portal \"%s\" existerar inte" + +#: tcop/postgres.c:2153 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2155 tcop/postgres.c:2258 +msgid "execute fetch from" +msgstr "kör hämtning från" + +#: tcop/postgres.c:2156 tcop/postgres.c:2259 +msgid "execute" +msgstr "kör" + +#: tcop/postgres.c:2255 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "varaktighet: %s ms %s %s%s%s: %s" + +#: tcop/postgres.c:2401 +#, c-format +msgid "prepare: %s" +msgstr "prepare: %s" + +#: tcop/postgres.c:2426 +#, c-format +msgid "parameters: %s" +msgstr "parametrar: %s" + +#: tcop/postgres.c:2441 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "abortskäl: återställningskonflikt" + +#: tcop/postgres.c:2457 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "Användaren höll delad bufferfastlåsning för länge." + +#: tcop/postgres.c:2460 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "Användare höll ett relationslås för länge." + +#: tcop/postgres.c:2463 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "Användaren använde eller har använt ett tablespace som tagits bort." + +#: tcop/postgres.c:2466 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "Användarfrågan kan ha behövt se radversioner som har tagits bort." + +#: tcop/postgres.c:2472 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "Användare var ansluten till databas som måste slängas." + +#: tcop/postgres.c:2796 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "avbryter anslutning på grund av en krash i en annan serverprocess" + +#: tcop/postgres.c:2797 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "Postmastern har sagt åt denna serverprocess att rulla tillbaka den aktuella transaktionen och avsluta då en annan process har avslutats onormalt och har eventuellt trasat sönder delat minne." + +#: tcop/postgres.c:2801 tcop/postgres.c:3107 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "Du kan strax återansluta till databasen och upprepa kommandot." + +#: tcop/postgres.c:2883 +#, c-format +msgid "floating-point exception" +msgstr "flyttalsavbrott" + +#: tcop/postgres.c:2884 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "En ogiltig flyttalsoperation har signalerats. Detta beror troligen på ett resultat som är utanför giltigt intervall eller en ogiltig operation så som division med noll." + +#: tcop/postgres.c:3037 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "avbryter autentisering på grund av timeout" + +#: tcop/postgres.c:3041 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "avslutar autovacuum-process på grund av ett administratörskommando" + +#: tcop/postgres.c:3045 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "avslutar logisk replikeringsarbetare på grund av ett administratörskommando" + +#: tcop/postgres.c:3049 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "logisk replikeringsuppstartare stänger ner" + +#: tcop/postgres.c:3062 tcop/postgres.c:3072 tcop/postgres.c:3105 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "avslutar anslutning på grund av konflikt med återställning" + +#: tcop/postgres.c:3078 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "avslutar anslutning på grund av ett administratörskommando" + +#: tcop/postgres.c:3088 +#, c-format +msgid "connection to client lost" +msgstr "anslutning till klient har brutits" + +#: tcop/postgres.c:3154 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "avbryter sats på grund av lås-timeout" + +#: tcop/postgres.c:3161 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "avbryter sats på grund av sats-timeout" + +#: tcop/postgres.c:3168 +#, c-format +msgid "canceling autovacuum task" +msgstr "avbryter autovacuum-uppgift" + +#: tcop/postgres.c:3191 +#, c-format +msgid "canceling statement due to user request" +msgstr "avbryter sats på användares begäran" + +#: tcop/postgres.c:3201 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "terminerar anslutning på grund av idle-in-transaction-timeout" + +#: tcop/postgres.c:3318 +#, c-format +msgid "stack depth limit exceeded" +msgstr "maximalt stackdjup överskridet" + +#: tcop/postgres.c:3319 +#, c-format +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "Öka konfigurationsparametern \"max_stack_depth\" (nu %dkB) efter att ha undersökt att plattformens gräns för stackdjup är tillräcklig." + +#: tcop/postgres.c:3382 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "\"max_stack_depth\" får ej överskrida %ldkB." + +#: tcop/postgres.c:3384 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "Öka plattformens stackdjupbegränsning via \"ulimit -s\" eller motsvarande." + +#: tcop/postgres.c:3744 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "ogiltigt kommandoradsargument för serverprocess: %s" + +#: tcop/postgres.c:3745 tcop/postgres.c:3751 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Försök med \"%s --help\" för mer information." + +#: tcop/postgres.c:3749 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: ogiltigt kommandoradsargument: %s" + +#: tcop/postgres.c:3811 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: ingen databas eller användarnamn angivet" + +#: tcop/postgres.c:4447 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "ogiltig subtyp %d för CLOSE-meddelande" + +#: tcop/postgres.c:4482 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "ogiltig subtyp %d för DESCRIBE-meddelande" + +#: tcop/postgres.c:4560 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "fastpath-funktionsanrop stöds inte i en replikeringsanslutning" + +#: tcop/postgres.c:4564 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "utökat frågeprotokoll stöds inte i en replikeringsanslutning" + +#: tcop/postgres.c:4741 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "nedkoppling: sessionstid: %d:%02d:%02d.%03d användare=%s databas=%s värd=%s%s%s" + +#: tcop/pquery.c:629 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "bind-meddelande har %d resultatformat men frågan har %d kolumner" + +#: tcop/pquery.c:932 +#, c-format +msgid "cursor can only scan forward" +msgstr "markör kan bara hoppa framåt" + +#: tcop/pquery.c:933 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Deklarera den med flaggan SCROLL för att kunna traversera bakåt." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:413 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "kan inte köra %s i read-only-transaktion" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:431 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "kan inte köra %s under parallell operation" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:450 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "kan inte köra %s under återställning" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:468 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "kan inte köra %s inom säkerhetsbegränsad operation" + +#: tcop/utility.c:912 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "måste vara superanvändare för att göra CHECKPOINT" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:620 +#, c-format +msgid "multiple DictFile parameters" +msgstr "multipla DictFile-parametrar" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "multipla AffFile-parametrar" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "okänd Ispell-parameter: \"%s\"" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "saknar AffFile-parameter" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:644 +#, c-format +msgid "missing DictFile parameter" +msgstr "saknar DictFile-parameter" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "multipla Accept-parametrar" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "okänd parameter för \"simple dictionary\": \"%s\"" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "okänd synonymparameter: \"%s\"" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "saknar Synonym-prameter" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "kunde inte öppna synonymfil \"%s\": %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "kunde inte öppna synonymordboksfil \"%s\": %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "oväntad avdelare" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "oväntat slut på raden eller lexem" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "oväntat slut på raden" + +#: tsearch/dict_thesaurus.c:297 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "för många lexem i synonymordbokspost" + +#: tsearch/dict_thesaurus.c:421 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "synonymordbokens exempelord \"%s\" känns inte igen av underordbok (regel %d)" + +#: tsearch/dict_thesaurus.c:427 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "synonymordbokens exempelord \"%s\" är ett stoppord (regel %d)" + +#: tsearch/dict_thesaurus.c:430 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Använd \"?\" för att representera ett stoppord i en exempelfras." + +#: tsearch/dict_thesaurus.c:572 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "synonymordbokens ersättningsord \"%s\" är ett stoppord (regel %d)" + +#: tsearch/dict_thesaurus.c:579 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "synonymordbokens ersättningsord \"%s\" känns inte igen av underordbok (regel %d)" + +#: tsearch/dict_thesaurus.c:591 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "synonymordbokens ersättningsfras är tim (regel %d)" + +#: tsearch/dict_thesaurus.c:629 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "multipla ordboksparametrar" + +#: tsearch/dict_thesaurus.c:636 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "okänd synonymordboksparameter: \"%s\"" + +#: tsearch/dict_thesaurus.c:648 +#, c-format +msgid "missing Dictionary parameter" +msgstr "saknar ordlistparameter" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1036 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "ogiltig affix-flagga \"%s\"" + +#: tsearch/spell.c:384 tsearch/spell.c:1040 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "affix-flaggan \"%s\" är utanför giltigt intervall" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "ogiltigt tecken i affix-flagga \"%s\"" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "ogiltig affix-flagga \"%s\" med flaggvärdet \"long\"" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "kunde inte öppna ordboksfil \"%s\": %m" + +#: tsearch/spell.c:742 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "ogiltigt reguljärt uttryck: %s" + +#: tsearch/spell.c:1163 tsearch/spell.c:1175 tsearch/spell.c:1734 +#: tsearch/spell.c:1739 tsearch/spell.c:1744 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "ogiltigt affix-alias \"%s\"" + +#: tsearch/spell.c:1216 tsearch/spell.c:1287 tsearch/spell.c:1436 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "kunde inte öppna affix-fil \"%s\": %m" + +#: tsearch/spell.c:1270 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Ispell-ordbok stöder bara flaggorna \"default\", \"long\" och \"num\"" + +#: tsearch/spell.c:1314 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "ogiltigt antal alias i flaggvektor" + +#: tsearch/spell.c:1337 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "antalet alias överskriver angivet antal %d" + +#: tsearch/spell.c:1552 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "affix-fil innehåller kommandon på gammalt och nytt format" + +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "strängen är för lång för tsvector (%d byte, max %d byte)" + +#: tsearch/ts_locale.c:212 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "rad %d i konfigureringsfil \"%s\": \"%s\"" + +#: tsearch/ts_locale.c:329 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "konvertering från wchar_t till serverkodning misslyckades: %m" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 +#: tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "ordet är för långt för att indexeras" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 +#: tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "Ord längre än %d tecken hoppas över." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "ogiltigt filnamn \"%s\" till textsökkonfiguration" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "kunde inte öppna stoppordsfil \"%s\": %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "textsökparsern stöder inte skapande av rubriker" + +#: tsearch/wparser_def.c:2585 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "okänd rubrikparameter: \"%s\"" + +#: tsearch/wparser_def.c:2604 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "MinWords skall vara mindre än MaxWords" + +#: tsearch/wparser_def.c:2608 +#, c-format +msgid "MinWords should be positive" +msgstr "MinWords skall vara positiv" + +#: tsearch/wparser_def.c:2612 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "ShortWord skall vara >= 0" + +#: tsearch/wparser_def.c:2616 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "MaxFragments skall vara >= 0" + +#: utils/adt/acl.c:172 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "identifieraren för lång" + +#: utils/adt/acl.c:173 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "Identifierare måste vara mindre än %d tecken." + +#: utils/adt/acl.c:256 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "okänt nyckelord: \"%s\"" + +#: utils/adt/acl.c:257 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "ACL-nyckelord måste vara \"group\" eller \"user\"." + +#: utils/adt/acl.c:262 +#, c-format +msgid "missing name" +msgstr "namn saknas" + +#: utils/adt/acl.c:263 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "Ett namn måste följa efter nyckelorden \"group\" resp. \"user\"." + +#: utils/adt/acl.c:269 +#, c-format +msgid "missing \"=\" sign" +msgstr "saknar \"=\"-tecken" + +#: utils/adt/acl.c:322 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "ogiltigt lägestecken: måste vara en av \"%s\"" + +#: utils/adt/acl.c:344 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "ett namn måste följa på tecknet \"/\"" + +#: utils/adt/acl.c:352 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "sätter fullmaktsgivaranvändar-ID till standardvärdet %u" + +#: utils/adt/acl.c:538 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "ACL-array innehåller fel datatyp" + +#: utils/adt/acl.c:542 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "ACL-array:er måste vara endimensionella" + +#: utils/adt/acl.c:546 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "ACL-array:er får inte innehålla null-värden" + +#: utils/adt/acl.c:570 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "skräp vid slutet av ACL-angivelse" + +#: utils/adt/acl.c:1205 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "fullmaksgivarflaggor kan inte ges tillbaka till den som givit det till dig" + +#: utils/adt/acl.c:1266 +#, c-format +msgid "dependent privileges exist" +msgstr "det finns beroende privilegier" + +#: utils/adt/acl.c:1267 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Använd CASCADE för att återkalla dem med." + +#: utils/adt/acl.c:1521 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert stöds inte länge" + +#: utils/adt/acl.c:1531 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove stöds inte längre" + +#: utils/adt/acl.c:1617 utils/adt/acl.c:1671 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "okänd privilegietyp: \"%s\"" + +#: utils/adt/acl.c:3471 utils/adt/regproc.c:103 utils/adt/regproc.c:278 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "funktionen \"%s\" finns inte" + +#: utils/adt/acl.c:4943 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "måste vara medlem i rollen \"%s\"" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:933 +#: utils/adt/arrayfuncs.c:1533 utils/adt/arrayfuncs.c:3236 +#: utils/adt/arrayfuncs.c:3376 utils/adt/arrayfuncs.c:5911 +#: utils/adt/arrayfuncs.c:6252 utils/adt/arrayutils.c:93 +#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "array-storlek överskrider maximalt tillåtna (%d)" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:645 utils/adt/json.c:740 +#: utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 +#: utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "kan inte bestämma indatatyp" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "indatatyp är inte en array" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1336 utils/adt/float.c:1243 utils/adt/float.c:1317 +#: utils/adt/float.c:3960 utils/adt/float.c:3974 utils/adt/int.c:759 +#: utils/adt/int.c:781 utils/adt/int.c:795 utils/adt/int.c:809 +#: utils/adt/int.c:840 utils/adt/int.c:861 utils/adt/int.c:978 +#: utils/adt/int.c:992 utils/adt/int.c:1006 utils/adt/int.c:1039 +#: utils/adt/int.c:1053 utils/adt/int.c:1067 utils/adt/int.c:1098 +#: utils/adt/int.c:1180 utils/adt/int.c:1244 utils/adt/int.c:1312 +#: utils/adt/int.c:1318 utils/adt/int8.c:1292 utils/adt/numeric.c:1559 +#: utils/adt/numeric.c:3435 utils/adt/varbit.c:1188 utils/adt/varbit.c:1576 +#: utils/adt/varlena.c:1087 utils/adt/varlena.c:3377 +#, c-format +msgid "integer out of range" +msgstr "heltal utanför giltigt intervall" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "argumentet måste vara tomt eller en endimensionell array" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "kan inte konkatenera inkompatibla arrayer" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Array:er med elementtyper %s och %s är inte kompatibla för sammaslagning." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Array:er med dimensioner %d och %d är inte kompatibla för sammaslagning." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "Array:er med olika elementdimensioner är inte kompatibla för sammaslagning." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Array:er med olika dimensioner fungerar inte vid konkatenering." + +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "sökning efter element i en multidimensionell array stöds inte" + +#: utils/adt/array_userfuncs.c:686 +#, c-format +msgid "initial position must not be null" +msgstr "initiala positionen får ej vara null" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 +#: utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:506 +#: utils/adt/arrayfuncs.c:517 utils/adt/arrayfuncs.c:532 +#: utils/adt/arrayfuncs.c:553 utils/adt/arrayfuncs.c:583 +#: utils/adt/arrayfuncs.c:590 utils/adt/arrayfuncs.c:598 +#: utils/adt/arrayfuncs.c:632 utils/adt/arrayfuncs.c:655 +#: utils/adt/arrayfuncs.c:675 utils/adt/arrayfuncs.c:787 +#: utils/adt/arrayfuncs.c:796 utils/adt/arrayfuncs.c:826 +#: utils/adt/arrayfuncs.c:841 utils/adt/arrayfuncs.c:894 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "felaktig array-literal: \"%s\"" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "\"[\" måste införa explicit angivna array-dimensioner." + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "Saknar värde i array-dimension." + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "Saknar \"%s\" efter array-dimensioner." + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2884 +#: utils/adt/arrayfuncs.c:2916 utils/adt/arrayfuncs.c:2931 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "övre gränsen kan inte vara lägre än undre gränsen" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "Array-värde måste starta med \"{\" eller dimensionsinformation" + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "Array-innehåll måste starta med \"{\"." + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "Angivna array-dimensioner matchar inte array-innehållet." + +#: utils/adt/arrayfuncs.c:491 utils/adt/arrayfuncs.c:518 +#: utils/adt/rangetypes.c:2181 utils/adt/rangetypes.c:2189 +#: utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 +#, c-format +msgid "Unexpected end of input." +msgstr "oväntat slut på indata." + +#: utils/adt/arrayfuncs.c:507 utils/adt/arrayfuncs.c:554 +#: utils/adt/arrayfuncs.c:584 utils/adt/arrayfuncs.c:633 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "oväntat tecken \"%c\"." + +#: utils/adt/arrayfuncs.c:533 utils/adt/arrayfuncs.c:656 +#, c-format +msgid "Unexpected array element." +msgstr "Oväntat array-element." + +#: utils/adt/arrayfuncs.c:591 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "Icke matchat tecken \"%c\"." + +#: utils/adt/arrayfuncs.c:599 utils/adt/jsonfuncs.c:2452 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "Flerdimensionella array:er måste ha underarray:er med matchande dimensioner." + +#: utils/adt/arrayfuncs.c:676 +#, c-format +msgid "Junk after closing right brace." +msgstr "Skräp efter avslutande höger parentes." + +#: utils/adt/arrayfuncs.c:1298 utils/adt/arrayfuncs.c:3344 +#: utils/adt/arrayfuncs.c:5817 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "felaktigt antal dimensioner: %d" + +#: utils/adt/arrayfuncs.c:1309 +#, c-format +msgid "invalid array flags" +msgstr "ogiltiga array-flaggor" + +#: utils/adt/arrayfuncs.c:1317 +#, c-format +msgid "wrong element type" +msgstr "fel elementtyp" + +#: utils/adt/arrayfuncs.c:1367 utils/adt/rangetypes.c:335 +#: utils/cache/lsyscache.c:2835 +#, c-format +msgid "no binary input function available for type %s" +msgstr "ingen binär indatafunktion finns för typen %s" + +#: utils/adt/arrayfuncs.c:1507 +#, c-format +msgid "improper binary format in array element %d" +msgstr "felaktigt binärt format i array-element %d" + +#: utils/adt/arrayfuncs.c:1588 utils/adt/rangetypes.c:340 +#: utils/cache/lsyscache.c:2868 +#, c-format +msgid "no binary output function available for type %s" +msgstr "det saknas en binär output-funktion för typen %s" + +#: utils/adt/arrayfuncs.c:2066 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "slice av fixlängd-array är inte implementerat" + +#: utils/adt/arrayfuncs.c:2244 utils/adt/arrayfuncs.c:2266 +#: utils/adt/arrayfuncs.c:2315 utils/adt/arrayfuncs.c:2551 +#: utils/adt/arrayfuncs.c:2862 utils/adt/arrayfuncs.c:5803 +#: utils/adt/arrayfuncs.c:5829 utils/adt/arrayfuncs.c:5840 +#: utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 +#: utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4340 utils/adt/jsonfuncs.c:4490 +#: utils/adt/jsonfuncs.c:4602 utils/adt/jsonfuncs.c:4648 +#, c-format +msgid "wrong number of array subscripts" +msgstr "fel antal array-indexeringar" + +#: utils/adt/arrayfuncs.c:2249 utils/adt/arrayfuncs.c:2357 +#: utils/adt/arrayfuncs.c:2615 utils/adt/arrayfuncs.c:2921 +#, c-format +msgid "array subscript out of range" +msgstr "array-index utanför giltigt område" + +#: utils/adt/arrayfuncs.c:2254 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "kan inte tilldela null-värde till ett element i en array med fast längd" + +#: utils/adt/arrayfuncs.c:2809 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "uppdatering av slice på fixlängd-array är inte implementerat" + +#: utils/adt/arrayfuncs.c:2840 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "array-slice-index måste inkludera båda gränser" + +#: utils/adt/arrayfuncs.c:2841 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "Vid tilldelning till en slice av en tom array så måste slice-gränserna anges" + +#: utils/adt/arrayfuncs.c:2852 utils/adt/arrayfuncs.c:2947 +#, c-format +msgid "source array too small" +msgstr "käll-array för liten" + +#: utils/adt/arrayfuncs.c:3500 +#, c-format +msgid "null array element not allowed in this context" +msgstr "null-element i arrayer stöds inte i detta kontext" + +#: utils/adt/arrayfuncs.c:3602 utils/adt/arrayfuncs.c:3773 +#: utils/adt/arrayfuncs.c:4129 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "kan inte jämföra arrayer med olika elementtyper" + +#: utils/adt/arrayfuncs.c:3951 utils/adt/rangetypes.c:1254 +#: utils/adt/rangetypes.c:1318 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "kunde inte hitta en hash-funktion för typ %s" + +#: utils/adt/arrayfuncs.c:4044 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "kunde inte hitta en utökad hash-funktion för typ %s" + +#: utils/adt/arrayfuncs.c:5221 +#, c-format +msgid "data type %s is not an array type" +msgstr "datatypen %s är inte en arraytyp" + +#: utils/adt/arrayfuncs.c:5276 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "kan inte ackumulera null-array:er" + +#: utils/adt/arrayfuncs.c:5304 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "kan inte ackumulera tomma array:er" + +#: utils/adt/arrayfuncs.c:5331 utils/adt/arrayfuncs.c:5337 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "kan inte ackumulera arrayer med olika dimensioner" + +#: utils/adt/arrayfuncs.c:5701 utils/adt/arrayfuncs.c:5741 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "dimensionsarray eller undre gränsarray kan inte vara null" + +#: utils/adt/arrayfuncs.c:5804 utils/adt/arrayfuncs.c:5830 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "Dimensionsarray måste vara endimensionell." + +#: utils/adt/arrayfuncs.c:5809 utils/adt/arrayfuncs.c:5835 +#, c-format +msgid "dimension values cannot be null" +msgstr "dimensionsvärden kan inte vara null" + +#: utils/adt/arrayfuncs.c:5841 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "Undre arraygräns har annan storlek än dimensionsarray." + +#: utils/adt/arrayfuncs.c:6117 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "borttagning av element från en multidimensionell array stöds inte" + +#: utils/adt/arrayfuncs.c:6394 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "gränsvärden måste vara en endimensionell array" + +#: utils/adt/arrayfuncs.c:6399 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "gränsvärdesarray får inte innehålla NULLL-värden" + +#: utils/adt/arrayutils.c:209 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "typmod-array måste ha typ cstring[]" + +#: utils/adt/arrayutils.c:214 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "typmod-array måste vara endimensionell" + +#: utils/adt/arrayutils.c:219 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "typmod-arrayen får inte innehålla null-värden" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "kodningskonvertering från %s till ASCII stöds inte" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3757 +#: utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:295 +#: utils/adt/float.c:412 utils/adt/float.c:497 utils/adt/float.c:525 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 +#: utils/adt/geo_ops.c:1421 utils/adt/geo_ops.c:3476 utils/adt/geo_ops.c:4645 +#: utils/adt/geo_ops.c:4660 utils/adt/geo_ops.c:4667 utils/adt/int8.c:126 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:601 +#: utils/adt/numeric.c:628 utils/adt/numeric.c:6001 utils/adt/numeric.c:6025 +#: utils/adt/numeric.c:6049 utils/adt/numeric.c:6882 utils/adt/numeric.c:6908 +#: utils/adt/numutils.c:116 utils/adt/numutils.c:126 utils/adt/numutils.c:170 +#: utils/adt/numutils.c:246 utils/adt/numutils.c:322 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:73 utils/adt/tid.c:74 utils/adt/tid.c:82 +#: utils/adt/tid.c:90 utils/adt/timestamp.c:494 utils/adt/uuid.c:136 +#: utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "ogiltig indatasyntax för type %s: \"%s\"" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 +#: utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "värdet \"%s\" är utanför giltigt intervall för typen %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:104 utils/adt/int.c:824 utils/adt/int.c:940 +#: utils/adt/int.c:1020 utils/adt/int.c:1082 utils/adt/int.c:1120 +#: utils/adt/int.c:1148 utils/adt/int8.c:593 utils/adt/int8.c:651 +#: utils/adt/int8.c:978 utils/adt/int8.c:1058 utils/adt/int8.c:1120 +#: utils/adt/int8.c:1200 utils/adt/numeric.c:7446 utils/adt/numeric.c:7736 +#: utils/adt/numeric.c:9318 utils/adt/timestamp.c:3243 +#, c-format +msgid "division by zero" +msgstr "division med noll" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "\"char\" utanför sitt intervall" + +#: utils/adt/date.c:61 utils/adt/timestamp.c:95 utils/adt/varbit.c:104 +#: utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "ogiltig typmodifierare" + +#: utils/adt/date.c:73 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "TIME(%d)%s-precisionen får inte vara negativ" + +#: utils/adt/date.c:79 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%s-precisionen reducerad till maximalt tillåtna, %d" + +#: utils/adt/date.c:158 utils/adt/date.c:166 utils/adt/formatting.c:4210 +#: utils/adt/formatting.c:4219 utils/adt/formatting.c:4325 +#: utils/adt/formatting.c:4335 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "datum utanför giltigt intervall \"%s\"" + +#: utils/adt/date.c:213 utils/adt/date.c:525 utils/adt/date.c:549 +#: utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "datum utanför giltigt intervall" + +#: utils/adt/date.c:259 utils/adt/timestamp.c:574 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "datumfältvärde utanför giltigt område: %d-%02d-%02d" + +#: utils/adt/date.c:266 utils/adt/date.c:275 utils/adt/timestamp.c:580 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "datum utanför giltigt område: %d-%02d-%02d" + +#: utils/adt/date.c:313 utils/adt/date.c:336 utils/adt/date.c:362 +#: utils/adt/date.c:1142 utils/adt/date.c:1188 utils/adt/date.c:1744 +#: utils/adt/date.c:1775 utils/adt/date.c:1804 utils/adt/date.c:2636 +#: utils/adt/datetime.c:1655 utils/adt/formatting.c:4067 +#: utils/adt/formatting.c:4099 utils/adt/formatting.c:4179 +#: utils/adt/formatting.c:4301 utils/adt/json.c:418 utils/adt/json.c:457 +#: utils/adt/timestamp.c:222 utils/adt/timestamp.c:254 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2822 utils/adt/timestamp.c:2843 +#: utils/adt/timestamp.c:2856 utils/adt/timestamp.c:2865 +#: utils/adt/timestamp.c:2873 utils/adt/timestamp.c:2928 +#: utils/adt/timestamp.c:2951 utils/adt/timestamp.c:2964 +#: utils/adt/timestamp.c:2975 utils/adt/timestamp.c:2983 +#: utils/adt/timestamp.c:3643 utils/adt/timestamp.c:3768 +#: utils/adt/timestamp.c:3809 utils/adt/timestamp.c:3899 +#: utils/adt/timestamp.c:3943 utils/adt/timestamp.c:4046 +#: utils/adt/timestamp.c:4531 utils/adt/timestamp.c:4727 +#: utils/adt/timestamp.c:5054 utils/adt/timestamp.c:5068 +#: utils/adt/timestamp.c:5073 utils/adt/timestamp.c:5087 +#: utils/adt/timestamp.c:5120 utils/adt/timestamp.c:5207 +#: utils/adt/timestamp.c:5248 utils/adt/timestamp.c:5252 +#: utils/adt/timestamp.c:5321 utils/adt/timestamp.c:5325 +#: utils/adt/timestamp.c:5339 utils/adt/timestamp.c:5373 utils/adt/xml.c:2232 +#: utils/adt/xml.c:2239 utils/adt/xml.c:2259 utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "timestamp utanför giltigt intervall" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "kan inte subtrahera oändliga datum" + +#: utils/adt/date.c:598 utils/adt/date.c:661 utils/adt/date.c:697 +#: utils/adt/date.c:2673 utils/adt/date.c:2683 +#, c-format +msgid "date out of range for timestamp" +msgstr "datum utanför filtigt område för timestamp" + +#: utils/adt/date.c:1361 utils/adt/date.c:2131 utils/adt/formatting.c:4387 +#, c-format +msgid "time out of range" +msgstr "time utanför giltigt intervall" + +#: utils/adt/date.c:1413 utils/adt/timestamp.c:589 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "time-värde utanför giltigt område: %d:%02d:%02g" + +#: utils/adt/date.c:1933 utils/adt/date.c:2435 utils/adt/float.c:1071 +#: utils/adt/float.c:1140 utils/adt/int.c:616 utils/adt/int.c:663 +#: utils/adt/int.c:698 utils/adt/int8.c:492 utils/adt/numeric.c:2197 +#: utils/adt/timestamp.c:3292 utils/adt/timestamp.c:3323 +#: utils/adt/timestamp.c:3354 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "ogiltig föregående eller efterföljande storlek i fönsterfunktion" + +#: utils/adt/date.c:2018 utils/adt/date.c:2031 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "känner inte igen \"time\"-enhet \"%s\"" + +#: utils/adt/date.c:2139 +#, c-format +msgid "time zone displacement out of range" +msgstr "tidszonförskjutning utanför giltigt intervall" + +#: utils/adt/date.c:2768 utils/adt/date.c:2781 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "känner inte igen \"time with time zone\" enhet \"%s\"" + +#: utils/adt/date.c:2854 utils/adt/datetime.c:906 utils/adt/datetime.c:1813 +#: utils/adt/datetime.c:4601 utils/adt/timestamp.c:513 +#: utils/adt/timestamp.c:540 utils/adt/timestamp.c:4129 +#: utils/adt/timestamp.c:5079 utils/adt/timestamp.c:5331 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "tidszon \"%s\" känns inte igen" + +#: utils/adt/date.c:2886 utils/adt/timestamp.c:5109 utils/adt/timestamp.c:5362 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "intervalltidszonen \"%s\" kan inte inkludera månader eller år" + +#: utils/adt/datetime.c:3730 utils/adt/datetime.c:3737 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "datum/tid-värde utanför giltigt område: \"%s\"" + +#: utils/adt/datetime.c:3739 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Du kanske behöver en annan inställning av variabeln \"datestyle\"." + +#: utils/adt/datetime.c:3744 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "intervall-värde utanför giltigt område: \"%s\"" + +#: utils/adt/datetime.c:3750 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "tidszonförskjutning itanför sitt intervall: \"%s\"" + +#: utils/adt/datetime.c:4603 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "Detta tidszonsnamn finns i konfigurationsfilen för tidszonsförkortning \"%s\"." + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "ogiltigt Datum-pekare" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "ogiltig storlek: \"%s\"" + +#: utils/adt/dbsize.c:828 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "Ogiltig storleksenhet: \"%s\"." + +#: utils/adt/dbsize.c:829 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Giltiga enheter är \"bytes\", \"kB\", \"MB\", \"GB\" och \"TB\"." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "typen %s är inte en domän" + +#: utils/adt/encode.c:64 utils/adt/encode.c:112 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "okänd kodning: \"%s\"" + +#: utils/adt/encode.c:78 +#, c-format +msgid "result of encoding conversion is too large" +msgstr "resultat från kodningskonvertering är för stort" + +#: utils/adt/encode.c:126 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "resultatet av avkodningskonverteringen är för stort" + +#: utils/adt/encode.c:184 +#, c-format +msgid "invalid hexadecimal digit: \"%c\"" +msgstr "ogiltigt hexdecimal siffra: \"%c\"" + +#: utils/adt/encode.c:212 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "ogiltig hexadecimal data: udda antal siffror" + +#: utils/adt/encode.c:329 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "oväntat \"=\" vid avkodning av base64-sekvens" + +#: utils/adt/encode.c:341 +#, c-format +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "ogiltig symbol \"%c\" vid avkodning av base64-sekvens" + +#: utils/adt/encode.c:361 +#, c-format +msgid "invalid base64 end sequence" +msgstr "ogiltig base64-slutsekvens" + +#: utils/adt/encode.c:362 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "Indata saknar paddning, är trunkerad eller är trasig på annat sätt." + +#: utils/adt/enum.c:100 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "osäker användning av nytt värde \"%s\" i enum typ %s" + +#: utils/adt/enum.c:103 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "Nya enum-värden måste commit:as innan de kan användas." + +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 +#: utils/adt/enum.c:199 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "ogiltigt indata-värde för enum %s: \"%s\"" + +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "ogiltigt internt värde för enum: %u" + +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 +#: utils/adt/enum.c:535 +#, c-format +msgid "could not determine actual enum type" +msgstr "kunde inte bestämma den verkliga enum-typen" + +#: utils/adt/enum.c:454 utils/adt/enum.c:483 +#, c-format +msgid "enum %s contains no values" +msgstr "enum %s innehåller inga värden" + +#: utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 +#: utils/cache/typcache.c:1632 utils/cache/typcache.c:1788 +#: utils/cache/typcache.c:1918 utils/fmgr/funcapi.c:456 +#, c-format +msgid "type %s is not composite" +msgstr "typen %s är inte composite" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "värde utanför giltigt intervall: overflow" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "värde utanför giltigt intervall: underflow" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "\"%s\" är utanför giltigt intervall för typen real" + +#: utils/adt/float.c:489 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "\"%s\" är utanför giltigt intervall för typen double precision" + +#: utils/adt/float.c:1268 utils/adt/float.c:1342 utils/adt/int.c:336 +#: utils/adt/int.c:874 utils/adt/int.c:896 utils/adt/int.c:910 +#: utils/adt/int.c:924 utils/adt/int.c:956 utils/adt/int.c:1194 +#: utils/adt/int8.c:1313 utils/adt/numeric.c:3553 utils/adt/numeric.c:3562 +#, c-format +msgid "smallint out of range" +msgstr "smallint utanför sitt intervall" + +#: utils/adt/float.c:1468 utils/adt/numeric.c:8329 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "kan inte ta kvadratroten av ett negativt tal" + +#: utils/adt/float.c:1536 utils/adt/numeric.c:3239 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "noll upphöjt med ett negativt tal är odefinierat" + +#: utils/adt/float.c:1540 utils/adt/numeric.c:3245 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "ett negativt tal upphöjt i en icke-negativ potens ger ett komplext resultat" + +#: utils/adt/float.c:1614 utils/adt/float.c:1647 utils/adt/numeric.c:8993 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "kan inte ta logartimen av noll" + +#: utils/adt/float.c:1618 utils/adt/float.c:1651 utils/adt/numeric.c:8997 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "kan inte ta logaritmen av ett negativt tal" + +#: utils/adt/float.c:1684 utils/adt/float.c:1715 utils/adt/float.c:1810 +#: utils/adt/float.c:1837 utils/adt/float.c:1865 utils/adt/float.c:1892 +#: utils/adt/float.c:2039 utils/adt/float.c:2076 utils/adt/float.c:2246 +#: utils/adt/float.c:2302 utils/adt/float.c:2367 utils/adt/float.c:2424 +#: utils/adt/float.c:2615 utils/adt/float.c:2639 +#, c-format +msgid "input is out of range" +msgstr "indata är utanför giltigt intervall" + +#: utils/adt/float.c:2706 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "setseed-parameter %g är utanför giltigt intervall [-1,1]" + +#: utils/adt/float.c:3938 utils/adt/numeric.c:1509 +#, c-format +msgid "count must be greater than zero" +msgstr "antal måste vara större än noll" + +#: utils/adt/float.c:3943 utils/adt/numeric.c:1516 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "operand, lägre gräns och övre gräns kan inte vara NaN" + +#: utils/adt/float.c:3949 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "lägre och övre gräns måste vara ändliga" + +#: utils/adt/float.c:3983 utils/adt/numeric.c:1529 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "lägre gräns kan inte vara samma som övre gräns" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "ogiltig formatspecifikation för ett intervallvärdei" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "Intervaller är inte kopplade till specifika kalenderdatum." + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "\"EEEE\" måste vara det sista mönstret som används" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "\"9\" måste vara före \"PR\"" + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "\"0\" måste vara före \"PR\"" + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "multipla decimalpunkter" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "kan inte använda \"V\" ach decimalpunkt tillsammans" + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "kan inte använda \"S\" två gånger" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "kan inte använda \"S\" och \"PL\"/\"MI\"/\"SG\"/\"PR\" tillsammans" + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "kan inte använda \"S\" och \"MI\" tillsammans." + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "kan inte använda \"S\" och \"PL\" tillsammans." + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "kan inte använda \"S\" och \"SG\" tillsammans." + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "kan inte använda \"PR\" och \"S\"/\"PL\"/\"MI\"/\"SG\" tillsammans." + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "kan inte använda \"EEEE\" två gånger" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "\"EEEE\" är inkompatibel med andra format" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "\"EEEE\" får bara användas tillsammans med siffror- och decimalpunkts-mönster." + +#: utils/adt/formatting.c:1394 +#, c-format +msgid "invalid datetime format separator: \"%s\"" +msgstr "ogiltigt formatseparator för datetime: \"%s\"" + +#: utils/adt/formatting.c:1522 +#, c-format +msgid "\"%s\" is not a number" +msgstr "\"%s\" är inte ett nummer" + +#: utils/adt/formatting.c:1600 +#, c-format +msgid "case conversion failed: %s" +msgstr "case-konvertering misslyckades: %s" + +#: utils/adt/formatting.c:1665 utils/adt/formatting.c:1789 +#: utils/adt/formatting.c:1914 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "kunde inte bestämma jämförelse (collation) för funktionen %s" + +#: utils/adt/formatting.c:2286 +#, c-format +msgid "invalid combination of date conventions" +msgstr "ogiltig kombination av datumkonventioner" + +#: utils/adt/formatting.c:2287 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "Blanda inte datumkonventionerna Gregoriansk och ISO-veckor i formatteringsmall." + +#: utils/adt/formatting.c:2310 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "värden för \"%s\" i formatsträng står i konflikt med varandra" + +#: utils/adt/formatting.c:2313 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "Detta värde motsäger en tidigare inställning för samma fälttyp." + +#: utils/adt/formatting.c:2384 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "källsträngen är för kort för formatfält \"%s\"" + +#: utils/adt/formatting.c:2387 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "Fältet kräver %d tecken men bara %d återstår." + +#: utils/adt/formatting.c:2390 utils/adt/formatting.c:2405 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "Om din källsträng inte är av fast längd så testa med modifieraren \"FM\"." + +#: utils/adt/formatting.c:2400 utils/adt/formatting.c:2414 +#: utils/adt/formatting.c:2637 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "ogiltigt värde \"%s\" för \"%s\"" + +#: utils/adt/formatting.c:2402 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "Fältet kräver %d tecken men bara %d kunde parsas." + +#: utils/adt/formatting.c:2416 +#, c-format +msgid "Value must be an integer." +msgstr "Värdet måste vara ett heltal." + +#: utils/adt/formatting.c:2421 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "värdet för \"%s\" i källsträng är utanför giltigt intervall" + +#: utils/adt/formatting.c:2423 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "Värdet måste vara i intervallet %d till %d." + +#: utils/adt/formatting.c:2639 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "Det givna värdet matchar inget av de tillåtna värdena för detta fält." + +#: utils/adt/formatting.c:2856 utils/adt/formatting.c:2876 +#: utils/adt/formatting.c:2896 utils/adt/formatting.c:2916 +#: utils/adt/formatting.c:2935 utils/adt/formatting.c:2954 +#: utils/adt/formatting.c:2978 utils/adt/formatting.c:2996 +#: utils/adt/formatting.c:3014 utils/adt/formatting.c:3032 +#: utils/adt/formatting.c:3049 utils/adt/formatting.c:3066 +#, c-format +msgid "localized string format value too long" +msgstr "lokaliserat strängformatvärde är för långt" + +#: utils/adt/formatting.c:3300 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "ej matchande formatteringsseparator \"%c\"" + +#: utils/adt/formatting.c:3361 +#, c-format +msgid "unmatched format character \"%s\"" +msgstr "ej matchande formatteringstecken \"%s\"" + +#: utils/adt/formatting.c:3467 utils/adt/formatting.c:3811 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "formateringsfält \"%s\" stöds bara i to_char" + +#: utils/adt/formatting.c:3642 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "ogiltig indatasträng för \"Y,YYY\"" + +#: utils/adt/formatting.c:3728 +#, c-format +msgid "input string is too short for datetime format" +msgstr "indatasträngen är för kort för datetime-formatet" + +#: utils/adt/formatting.c:3736 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "efterföljande tecken finns kvar i indatasträngen efter datetime-formattering" + +#: utils/adt/formatting.c:4281 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "saknar tidszon i indatasträngen för typen timestamptz" + +#: utils/adt/formatting.c:4287 +#, c-format +msgid "timestamptz out of range" +msgstr "timestamptz utanför giltigt intervall" + +#: utils/adt/formatting.c:4315 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "datetime-format har zon men inte tid" + +#: utils/adt/formatting.c:4367 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "saknar tidszon i indatasträng för typ timetz" + +#: utils/adt/formatting.c:4373 +#, c-format +msgid "timetz out of range" +msgstr "timetz utanför giltigt intervall" + +#: utils/adt/formatting.c:4399 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "datetime-format har inte datum och inte tid" + +#: utils/adt/formatting.c:4532 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "timmen \"%d\" är ogiltigt för en 12-timmars-klocka" + +#: utils/adt/formatting.c:4534 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Använd en 24-timmars-klocka eller ange en timme mellan 1 och 12." + +#: utils/adt/formatting.c:4645 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "kan inte beräkna dag på året utan årsinformation" + +#: utils/adt/formatting.c:5564 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "\"EEEE\" stöds inte för indata" + +#: utils/adt/formatting.c:5576 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "\"RN\" stöds inte för indata" + +#: utils/adt/genfile.c:75 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "referens till föräldrakatalog (\"..\") tillåts inte" + +#: utils/adt/genfile.c:86 +#, c-format +msgid "absolute path not allowed" +msgstr "absolut sökväg tillåts inte" + +#: utils/adt/genfile.c:91 +#, c-format +msgid "path must be in or below the current directory" +msgstr "sökväg måste vara i eller under den aktuella katalogen" + +#: utils/adt/genfile.c:116 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 +#, c-format +msgid "requested length too large" +msgstr "efterfrågad längd är för lång" + +#: utils/adt/genfile.c:133 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "kunde inte söka (seek) i fil \"%s\": %m" + +#: utils/adt/genfile.c:174 +#, c-format +msgid "file length too large" +msgstr "fillängd är för stor" + +#: utils/adt/genfile.c:251 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "måste vara superanvändare för att läsa filer med adminpack 1.0" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "ogiltig radangivelse: A och B kan inte båda vara noll" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "ogiltig linjeangivelse: måste vara två enskilda punkter" + +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3486 utils/adt/geo_ops.c:4354 +#: utils/adt/geo_ops.c:5248 +#, c-format +msgid "too many points requested" +msgstr "för många punkter efterfrågade" + +#: utils/adt/geo_ops.c:1461 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "ogiltigt antal punkter i externt \"path\"-värde" + +#: utils/adt/geo_ops.c:2537 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "funktionen \"dist_lb\" är inte implementerad" + +#: utils/adt/geo_ops.c:2556 +#, c-format +msgid "function \"dist_bl\" not implemented" +msgstr "funktionen \"dist_bl\" är inte implementerad" + +#: utils/adt/geo_ops.c:2975 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "funktionen \"close_sl\" är inte implementerad" + +#: utils/adt/geo_ops.c:3122 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "funktionen \"close_lb\" är inte implementerad" + +#: utils/adt/geo_ops.c:3533 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "ogiltigt antal punkter i ett externt \"polygon\"-värde" + +#: utils/adt/geo_ops.c:4069 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "funktionen \"poly_distance\" är inte implementerad" + +#: utils/adt/geo_ops.c:4446 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "funktionen \"path_center\" är inte implementerad" + +#: utils/adt/geo_ops.c:4463 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "öppen väg kan inte konverteras till en polygon" + +#: utils/adt/geo_ops.c:4713 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "ogiltig radie i ett externt cirkelvärde" + +#: utils/adt/geo_ops.c:5234 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "kan inte konvertera en cirkel med radie noll till en polygon" + +#: utils/adt/geo_ops.c:5239 +#, c-format +msgid "must request at least 2 points" +msgstr "måste efterfråga minst 2 punkter" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector har för många element" + +#: utils/adt/int.c:239 +#, c-format +msgid "invalid int2vector data" +msgstr "ogiltig int2vector-data" + +#: utils/adt/int.c:245 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector har för många element" + +#: utils/adt/int.c:1510 utils/adt/int8.c:1439 utils/adt/numeric.c:1417 +#: utils/adt/timestamp.c:5424 utils/adt/timestamp.c:5504 +#, c-format +msgid "step size cannot equal zero" +msgstr "stegstorleken kan inte vara noll" + +#: utils/adt/int8.c:527 utils/adt/int8.c:550 utils/adt/int8.c:564 +#: utils/adt/int8.c:578 utils/adt/int8.c:609 utils/adt/int8.c:633 +#: utils/adt/int8.c:715 utils/adt/int8.c:783 utils/adt/int8.c:789 +#: utils/adt/int8.c:815 utils/adt/int8.c:829 utils/adt/int8.c:853 +#: utils/adt/int8.c:866 utils/adt/int8.c:935 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:994 utils/adt/int8.c:1016 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1077 +#: utils/adt/int8.c:1091 utils/adt/int8.c:1105 utils/adt/int8.c:1136 +#: utils/adt/int8.c:1158 utils/adt/int8.c:1172 utils/adt/int8.c:1186 +#: utils/adt/int8.c:1348 utils/adt/int8.c:1383 utils/adt/numeric.c:3508 +#: utils/adt/varbit.c:1656 +#, c-format +msgid "bigint out of range" +msgstr "bigint utanför sitt intervall" + +#: utils/adt/int8.c:1396 +#, c-format +msgid "OID out of range" +msgstr "OID utanför sitt intervall" + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "nyckelvärde måste vara skalär, inte array, composite eller json" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1812 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "kunde inte lista ut datatypen för argument %d" + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "fältnamnet får inte vara null" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "argumentlistan måste ha ett jämt antal element" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "Argumenten till %s måste bestå av varannan nyckel och varannat värde." + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "argument %d kan inte vara null" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "Objektnycklar skall vara text." + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "array:en måste ha två kolumner" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 +#: utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "null-värde tillåts inte som objektnyckel" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "array-dimensionerna stämmer inte" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "strängen är för lång för att representeras som en jsonb-sträng" + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "På grund av en implementationsbegränsning så kan jsonb-strängar inte överstiga %d byte." + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "argument %d: nyckeln får inte vara null" + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "objektnycklar måste vara strängar" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "kan inte typomvandla jsonb-null till type %s" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "kan inte typomvandla jsonb-sträng till typ %s" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "kan inte typomvandla jsonb-numeric till typ %s" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "kan inte typomvandla jsonb-boolean till typ %s" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "kan inte typomvandla jsonb-array till typ %s" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "kan inte typomvandla jsonb-objekt till typ %s" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "kan inte typomvandla jsonb-array eller objekt till typ %s" + +#: utils/adt/jsonb_util.c:699 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "antalet jsonb-objektpar överskrider det maximalt tillåtna (%zu)" + +#: utils/adt/jsonb_util.c:740 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "antalet jsonb-array-element överskrider det maximalt tillåtna (%zu)" + +#: utils/adt/jsonb_util.c:1614 utils/adt/jsonb_util.c:1634 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "total storlek på elementen i jsonb-array överskrider maximala %u byte" + +#: utils/adt/jsonb_util.c:1695 utils/adt/jsonb_util.c:1730 +#: utils/adt/jsonb_util.c:1750 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "total storlek på element i jsonb-objekt överskrider maximum på %u byte" + +#: utils/adt/jsonfuncs.c:551 utils/adt/jsonfuncs.c:796 +#: utils/adt/jsonfuncs.c:2330 utils/adt/jsonfuncs.c:2770 +#: utils/adt/jsonfuncs.c:3560 utils/adt/jsonfuncs.c:3891 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "kan inte anropa %s på en skalär" + +#: utils/adt/jsonfuncs.c:556 utils/adt/jsonfuncs.c:783 +#: utils/adt/jsonfuncs.c:2772 utils/adt/jsonfuncs.c:3549 +#, c-format +msgid "cannot call %s on an array" +msgstr "kan inte anropa %s på en array" + +#: utils/adt/jsonfuncs.c:692 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "JSON-data, rad %d: %s%s%s" + +#: utils/adt/jsonfuncs.c:1682 utils/adt/jsonfuncs.c:1717 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "kan inte hämta array-längd på skalär" + +#: utils/adt/jsonfuncs.c:1686 utils/adt/jsonfuncs.c:1705 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "kan inte hämta array-längd på icke-array" + +#: utils/adt/jsonfuncs.c:1782 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "kan inte anropa %s på ett icke-objekt" + +#: utils/adt/jsonfuncs.c:2021 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "kan inte dekonstruera en array som ett objekt" + +#: utils/adt/jsonfuncs.c:2033 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "kan inte dekonstruera en skalär" + +#: utils/adt/jsonfuncs.c:2079 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "kan inte extrahera element från en skalär" + +#: utils/adt/jsonfuncs.c:2083 +#, c-format +msgid "cannot extract elements from an object" +msgstr "kan inte extrahera element från ett objekt" + +#: utils/adt/jsonfuncs.c:2317 utils/adt/jsonfuncs.c:3775 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "kan inte anropa %s på icke-array" + +#: utils/adt/jsonfuncs.c:2387 utils/adt/jsonfuncs.c:2392 +#: utils/adt/jsonfuncs.c:2409 utils/adt/jsonfuncs.c:2415 +#, c-format +msgid "expected JSON array" +msgstr "förväntade JSON-array" + +#: utils/adt/jsonfuncs.c:2388 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Se värdetypen för nyckel \"%s\"" + +#: utils/adt/jsonfuncs.c:2410 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Se array-element %s för nyckel \"%s\"." + +#: utils/adt/jsonfuncs.c:2416 +#, c-format +msgid "See the array element %s." +msgstr "Se array-element %s." + +#: utils/adt/jsonfuncs.c:2451 +#, c-format +msgid "malformed JSON array" +msgstr "felaktig JSON-array" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3278 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "första argumentet till %s måste vara en radtyp" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3302 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "kunde inte lista ut radtyp för resultat av %s" + +#: utils/adt/jsonfuncs.c:3304 +#, c-format +msgid "Provide a non-null record argument, or call the function in the FROM clause using a column definition list." +msgstr "Ange en icke-null record som argument eller anropa funktionen i FROM-klausulen med en kolumndefinitionslista." + +#: utils/adt/jsonfuncs.c:3792 utils/adt/jsonfuncs.c:3873 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "argumentet till %s måste vara en array med objekt" + +#: utils/adt/jsonfuncs.c:3825 +#, c-format +msgid "cannot call %s on an object" +msgstr "kan inte anropa %s på ett objekt" + +#: utils/adt/jsonfuncs.c:4286 utils/adt/jsonfuncs.c:4345 +#: utils/adt/jsonfuncs.c:4425 +#, c-format +msgid "cannot delete from scalar" +msgstr "kan inte radera från en skalär" + +#: utils/adt/jsonfuncs.c:4430 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "kan inte radera från objekt genom att använda heltalsindex" + +#: utils/adt/jsonfuncs.c:4495 utils/adt/jsonfuncs.c:4653 +#, c-format +msgid "cannot set path in scalar" +msgstr "kan inte sätta sökväg i skalär" + +#: utils/adt/jsonfuncs.c:4537 utils/adt/jsonfuncs.c:4579 +#, c-format +msgid "null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"" +msgstr "null_value_treatment måste vara \"delete_key\", \"return_target\", \"use_json_null\" eller \"raise_exception\"" + +#: utils/adt/jsonfuncs.c:4550 +#, c-format +msgid "JSON value must not be null" +msgstr "JSON-värde får inte vara null" + +#: utils/adt/jsonfuncs.c:4551 +#, c-format +msgid "Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "Avbrott utlöstes då null_value_treatment är \"raise_exception\"." + +#: utils/adt/jsonfuncs.c:4552 +#, c-format +msgid "To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed." +msgstr "För att undvika detta så ändra null_value_treatment-argumentet eller se till att ett SQL-NULL inte skickas." + +#: utils/adt/jsonfuncs.c:4607 +#, c-format +msgid "cannot delete path in scalar" +msgstr "kan inte radera sökväg i skalär" + +#: utils/adt/jsonfuncs.c:4776 +#, c-format +msgid "invalid concatenation of jsonb objects" +msgstr "ogiltig sammanslagning av jsonb-objekt" + +#: utils/adt/jsonfuncs.c:4810 +#, c-format +msgid "path element at position %d is null" +msgstr "sökvägselement vid position %d är null" + +#: utils/adt/jsonfuncs.c:4896 +#, c-format +msgid "cannot replace existing key" +msgstr "kan inte ersätta befintlig nyckel" + +#: utils/adt/jsonfuncs.c:4897 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "Försök använda funktionen jsonb_set för att ersätta nyckelvärde." + +#: utils/adt/jsonfuncs.c:4979 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "sökvägselement vid position %d är inte ett heltal: \"%s\"" + +#: utils/adt/jsonfuncs.c:5098 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "fel flaggtyp, bara array:er och skalärer tillåts" + +#: utils/adt/jsonfuncs.c:5105 +#, c-format +msgid "flag array element is not a string" +msgstr "flaggelement i arrayen är inte en sträng" + +#: utils/adt/jsonfuncs.c:5106 utils/adt/jsonfuncs.c:5128 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "Möjliga värden är: \"string\", \"numeric\", \"boolean\", \"key\" samt \"all\"." + +#: utils/adt/jsonfuncs.c:5126 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "fel flagga i flagg-array: \"%s\"" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ är inte tillåten i rotuttryck" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST tillåts bara i array-indexeringar" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "förväntade ett booleanskt resultat" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "\"variabel\"-argumentet är inte ett objekt" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "Jsonpath-parametrar skall kodas som nyckel-värde-par av \"variabel\"-objekt." + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "JSON-objekt innehåller inte nyckeln \"%s\"" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "jsonpaths medlemsväljare kan bara appliceras på ett objekt" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "jsonpaths arrayväljare med wildcard kan bara applcieras på en array" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "jsonpaths array-index är utanför giltigt område" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "jsonpaths arrayväljare kan bara appliceras på en array" + +#: utils/adt/jsonpath_exec.c:874 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "jsonpaths medlemsväljare med wildcard kan bara appliceras på ett objekt" + +#: utils/adt/jsonpath_exec.c:1004 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "jsonpaths elementmetod .%s() lkan bara applicerar på en array" + +#: utils/adt/jsonpath_exec.c:1059 +#, c-format +msgid "numeric argument of jsonpath item method .%s() is out of range for type double precision" +msgstr "numeriskt argument till jsonpaths elementmetod .%s() är utanför giltigt intervall för typen double precision" + +#: utils/adt/jsonpath_exec.c:1080 +#, c-format +msgid "string argument of jsonpath item method .%s() is not a valid representation of a double precision number" +msgstr "strängargument till jsonpaths elementmetod .%s() är inte en giltig representation av ett double precision-nummer" + +#: utils/adt/jsonpath_exec.c:1093 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "jsonpaths elementmetod .%s() kan bara applicerar på en sträng eller ett numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1583 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "vänster operand på jsonpath-operator %s är inte ett ensamt numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1590 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "höger operand på jsonpath-operator %s är inte ett ensamt numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1658 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "operand till unär jsonpath-operator %s är inte ett numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1756 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "jsonpaths elementmetod .%s() kan bara appliceras på ett numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1796 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "jsonpaths elementmetod .%s() lkan bara applicerar på en sträng" + +#: utils/adt/jsonpath_exec.c:1890 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "datetime-format känns inte igen: \"%s\"" + +#: utils/adt/jsonpath_exec.c:1892 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "Använd ett datetime-mallargument för att ange indataformatet." + +#: utils/adt/jsonpath_exec.c:1960 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "jsonpaths elementmetod .%s() kan bara appliceras på ett objekt" + +#: utils/adt/jsonpath_exec.c:2143 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "kunde inte hitta jsonpath-variabel \"%s\"" + +#: utils/adt/jsonpath_exec.c:2407 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "jsonpaths array-index är inte ett ensamt numeriskt värde" + +#: utils/adt/jsonpath_exec.c:2419 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "jsonpaths array-index är utanför giltigt interval för integer" + +#: utils/adt/jsonpath_exec.c:2596 +#, c-format +msgid "cannot convert value from %s to %s without time zone usage" +msgstr "kan inte konvertera värde från %s till %s utan att använda tidszon" + +#: utils/adt/jsonpath_exec.c:2598 +#, c-format +msgid "Use *_tz() function for time zone support." +msgstr "ANvända *_tz()-funktioner som stöder tidszon." + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "levenshtein-argument överskrider maximala längden på %d tecken" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för LIKE" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för ILIKE" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för ILIKE" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "LIKE-mönster för inte sluta med ett escape-tecken" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "ogiltig escape-sträng" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "Escape-sträng måste vara tom eller ett tecken." + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "matchning utan skiftlägeskänslighet stöds inte för typen bytea" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "matching med reguljär-uttryck stöds inte för typen bytea" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "ogiltigt oktet-värde i \"macaddr\"-värde: \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "macaddr8-data utanför giltigt intervall för att konverteras till macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Bara adresser som har FF och FE som värden i 4:e och 5:e byten från vänster, till exempel xx:xx:xx:ff:fe:xx:xx:xx, är möjliga att konvertera från macaddr8 till macaddr." + +#: utils/adt/misc.c:240 +#, c-format +msgid "global tablespace never has databases" +msgstr "globala tablespace:t innehåller aldrig databaser" + +#: utils/adt/misc.c:262 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u är inte ett tabelespace-OID" + +#: utils/adt/misc.c:448 +msgid "unreserved" +msgstr "oreserverad" + +#: utils/adt/misc.c:452 +msgid "unreserved (cannot be function or type name)" +msgstr "ej reserverad (kan inte vara funktion eller typnamn)" + +#: utils/adt/misc.c:456 +msgid "reserved (can be function or type name)" +msgstr "reserverad (kan vara funktion eller typnamn)" + +#: utils/adt/misc.c:460 +msgid "reserved" +msgstr "reserverad" + +#: utils/adt/misc.c:634 utils/adt/misc.c:648 utils/adt/misc.c:687 +#: utils/adt/misc.c:693 utils/adt/misc.c:699 utils/adt/misc.c:722 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "sträng är inte en giltig identifierare: \"%s\"" + +#: utils/adt/misc.c:636 +#, c-format +msgid "String has unclosed double quotes." +msgstr "Sträng har ej avslutade dubbla citattecken." + +#: utils/adt/misc.c:650 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "Citerad identifierare får inte vara tom." + +#: utils/adt/misc.c:689 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "Ingen giltig indentifierare innan \".\"." + +#: utils/adt/misc.c:695 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "Ingen giltig identifierare efter \".\"." + +#: utils/adt/misc.c:753 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "loggformat \"%s\" stöds inte" + +#: utils/adt/misc.c:754 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "Loggformat som stöds är \"stderr\" och \"csvlog\"." + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "ogiltigt cidr-värde: \"%s\"" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "Värdet har bitar till höger om masken." + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 +#: utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "kunde inte formattera inet-värde: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "ogiltig adressfamilj i externt \"%s\"-värde" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "ogiltig bitar i externt \"%s\"-värde" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "ogiltig längd i extern \"%s\"-värde" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "ogiltigt externt \"cidr\"-värde" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "ogiltig masklängd: %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "kunde inte formattera \"cidr\"-värde: %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "kan inte slå samman adresser från olika familjer" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "kan inte AND:a inet-värden av olika storlek" + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "kan inte OR:a inet-värden av olika storlek" + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "resultatet är utanför giltigt intervall" + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "kan inte subtrahera inet-värden av olika storlek" + +#: utils/adt/numeric.c:827 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "ogiltigt tecken i externt \"numric\"-värde" + +#: utils/adt/numeric.c:833 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "ogiltig skala i externt \"numeric\"-värde" + +#: utils/adt/numeric.c:842 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "felaktig siffra i externt numeriskt (\"numeric\") värde " + +#: utils/adt/numeric.c:1040 utils/adt/numeric.c:1054 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "Precisionen %d för NUMERIC måste vara mellan 1 och %d" + +#: utils/adt/numeric.c:1045 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "Skalan %d för NUMERIC måste vara mellan 0 och precisionen %d" + +#: utils/adt/numeric.c:1063 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "ogiltig typmodifierare för NUMERIC" + +#: utils/adt/numeric.c:1395 +#, c-format +msgid "start value cannot be NaN" +msgstr "startvärde får inte vara NaN" + +#: utils/adt/numeric.c:1400 +#, c-format +msgid "stop value cannot be NaN" +msgstr "stoppvärde får inte vara NaN" + +#: utils/adt/numeric.c:1410 +#, c-format +msgid "step size cannot be NaN" +msgstr "stegstorlek får inte vara NaN" + +#: utils/adt/numeric.c:2958 utils/adt/numeric.c:6064 utils/adt/numeric.c:6522 +#: utils/adt/numeric.c:8802 utils/adt/numeric.c:9240 utils/adt/numeric.c:9354 +#: utils/adt/numeric.c:9427 +#, c-format +msgid "value overflows numeric format" +msgstr "overflow på värde i formatet numeric" + +#: utils/adt/numeric.c:3417 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "kan inte konvertera NaN till ett integer" + +#: utils/adt/numeric.c:3500 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "kan inte konvertera NaN till ett bigint" + +#: utils/adt/numeric.c:3545 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "kan inte konvertera NaN till ett smallint" + +#: utils/adt/numeric.c:3582 utils/adt/numeric.c:3653 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "kan inte konvertera oändlighet till numeric" + +#: utils/adt/numeric.c:6606 +#, c-format +msgid "numeric field overflow" +msgstr "overflow i numeric-fält" + +#: utils/adt/numeric.c:6607 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "Ett fält med precision %d, skala %d måste avrundas till ett absolut värde mindre än %s%d." + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "värdet \"%s\" är utanför intervallet för ett 8-bitars heltal" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "ogiltig oidvector-data" + +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "efterfrågat tecken är för stort" + +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "efterfrågat tecken är för stort för kodning: %d" + +#: utils/adt/oracle_compat.c:987 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "efterfrågat tecken är inte giltigt för kodning: %d" + +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "nolltecken tillåts inte" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "percentil-värde %g är inte mellan 0 och 1" + +#: utils/adt/pg_locale.c:1262 +#, c-format +msgid "Apply system library package updates." +msgstr "Applicera paketuppdateringar för systembibliotek." + +#: utils/adt/pg_locale.c:1477 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "kunde inte skapa locale \"%s\": %m" + +#: utils/adt/pg_locale.c:1480 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "Operativsystemet kunde inte hitta någon lokaldata för lokalnamnet \"%s\"." + +#: utils/adt/pg_locale.c:1582 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "jämförelser (collations) med olika collate- och ctype-värden stöds inte på denna plattform" + +#: utils/adt/pg_locale.c:1591 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "leverantören LIBC för jämförelse (collation) stöds inte på denna plattform" + +#: utils/adt/pg_locale.c:1603 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "jämförelser (collation) med olika collate- och ctype-värden stöds inte av ICU" + +#: utils/adt/pg_locale.c:1609 utils/adt/pg_locale.c:1696 +#: utils/adt/pg_locale.c:1969 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "kunde inte öppna jämförelse för lokal \"%s\": %s" + +#: utils/adt/pg_locale.c:1623 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU stöds inte av detta bygge" + +#: utils/adt/pg_locale.c:1624 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "Du behöver bygga om PostgreSQL med --with-icu." + +#: utils/adt/pg_locale.c:1644 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "jämförelse (collation) \"%s\" har ingen version men en version angavs" + +#: utils/adt/pg_locale.c:1651 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "jämförelse (collation) \"%s\" har en version som inte matchar" + +#: utils/adt/pg_locale.c:1653 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "Jämförelsen (collation) i databasen har skapats med version %s men operativsystemet har version %s." + +#: utils/adt/pg_locale.c:1656 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "Bygg om alla objekt som påverkas av denna jämförelse (collation) och kör ALTER COLLATION %s REFRESH VERSION eller bygg PostgreSQL med rätt bibliotekversion." + +#: utils/adt/pg_locale.c:1747 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "kunde inte hitta jämförelseversion (collation) för lokal \"%s\": felkod %lu" + +#: utils/adt/pg_locale.c:1784 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "kodning \"%s\" stöds inte av ICU" + +#: utils/adt/pg_locale.c:1791 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "kunde inte öppna ICU-konverterare för kodning \"%s\": %s" + +#: utils/adt/pg_locale.c:1822 utils/adt/pg_locale.c:1831 +#: utils/adt/pg_locale.c:1860 utils/adt/pg_locale.c:1870 +#, c-format +msgid "%s failed: %s" +msgstr "%s misslyckades: %s" + +#: utils/adt/pg_locale.c:2142 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "ogiltigt multibyte-tecken för lokalen" + +#: utils/adt/pg_locale.c:2143 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "Serverns LC_CTYPE-lokal är troligen inkompatibel med databasens teckenkodning." + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "funktionen kan bara anropas när servern är i binärt uppgraderingsläge" + +#: utils/adt/pgstatfuncs.c:500 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "ogiltigt kommandonamn: \"%s\"" + +#: utils/adt/pseudotypes.c:57 utils/adt/pseudotypes.c:91 +#, c-format +msgid "cannot display a value of type %s" +msgstr "kan inte visa ett värde av typ %s" + +#: utils/adt/pseudotypes.c:283 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "kan inte acceptera ett värde av typen shell" + +#: utils/adt/pseudotypes.c:293 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "kan inte visa ett värde av typen shell" + +#: utils/adt/rangetypes.c:406 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "konstruktorflaggargument till range får inte vara null" + +#: utils/adt/rangetypes.c:993 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "resultatet av range-skillnad skulle inte vara angränsande" + +#: utils/adt/rangetypes.c:1054 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "resultatet av range-union skulle inte vara angränsande" + +#: utils/adt/rangetypes.c:1600 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "lägre gräns för range måste vara lägre eller lika med övre gräns för range" + +#: utils/adt/rangetypes.c:1983 utils/adt/rangetypes.c:1996 +#: utils/adt/rangetypes.c:2010 +#, c-format +msgid "invalid range bound flags" +msgstr "ogiltig gränsflagga för range" + +#: utils/adt/rangetypes.c:1984 utils/adt/rangetypes.c:1997 +#: utils/adt/rangetypes.c:2011 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Giltiga värden är \"[]\", \"[)\", \"(]\" och \"()\"." + +#: utils/adt/rangetypes.c:2076 utils/adt/rangetypes.c:2093 +#: utils/adt/rangetypes.c:2106 utils/adt/rangetypes.c:2124 +#: utils/adt/rangetypes.c:2135 utils/adt/rangetypes.c:2179 +#: utils/adt/rangetypes.c:2187 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "trasig range-litteral: \"%s\"" + +#: utils/adt/rangetypes.c:2078 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "Skräp efter nyckelordet \"empty\"." + +#: utils/adt/rangetypes.c:2095 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Saknar vänster parentes eller hakparentes." + +#: utils/adt/rangetypes.c:2108 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Saknar komma efter lägre gräns." + +#: utils/adt/rangetypes.c:2126 +#, c-format +msgid "Too many commas." +msgstr "För många komman." + +#: utils/adt/rangetypes.c:2137 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "Skräp efter höger parentes eller hakparentes." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4493 +#, c-format +msgid "regular expression failed: %s" +msgstr "reguljärt uttryck misslyckades: %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%c\"" +msgstr "ogiltigt flagga till reguljärt uttryck: \"%c\"" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "Regulart uttryck i SQL får inte innehålla mer än två dubbelcitat-escape-separatorer" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s stöder inte \"global\"-flaggan" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "Använd regexp_matches-funktionen istället." + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "för många reguljära uttryck matchar" + +#: utils/adt/regproc.c:107 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "mer än en funktion med namn %s" + +#: utils/adt/regproc.c:525 +#, c-format +msgid "more than one operator named %s" +msgstr "mer än en operator med namn %s" + +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 utils/adt/regproc.c:2018 +#: utils/adt/ruleutils.c:9297 utils/adt/ruleutils.c:9466 +#, c-format +msgid "too many arguments" +msgstr "för många argument" + +#: utils/adt/regproc.c:698 utils/adt/regproc.c:739 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Ange två argumenttyper för operatorn." + +#: utils/adt/regproc.c:1602 utils/adt/regproc.c:1626 utils/adt/regproc.c:1727 +#: utils/adt/regproc.c:1751 utils/adt/regproc.c:1853 utils/adt/regproc.c:1858 +#: utils/adt/varlena.c:3642 utils/adt/varlena.c:3647 +#, c-format +msgid "invalid name syntax" +msgstr "ogiltig namnsyntax" + +#: utils/adt/regproc.c:1916 +#, c-format +msgid "expected a left parenthesis" +msgstr "förväntade en vänsterparentes" + +#: utils/adt/regproc.c:1932 +#, c-format +msgid "expected a right parenthesis" +msgstr "förväntade en högreparentes" + +#: utils/adt/regproc.c:1951 +#, c-format +msgid "expected a type name" +msgstr "förväntade ett typnamn" + +#: utils/adt/regproc.c:1983 +#, c-format +msgid "improper type name" +msgstr "olämpligt typnamn" + +#: utils/adt/ri_triggers.c:296 utils/adt/ri_triggers.c:1537 +#: utils/adt/ri_triggers.c:2470 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "insert eller update på tabell \"%s\" bryter mot främmande nyckel-villkoret \"%s\"" + +#: utils/adt/ri_triggers.c:299 utils/adt/ri_triggers.c:1540 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL tillåter inte att man blandar null och icke-null-värden." + +#: utils/adt/ri_triggers.c:1940 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "funktionen \"%s\" måste köras för INSERT" + +#: utils/adt/ri_triggers.c:1946 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "funktionen \"%s\" måste köras för UPDATE" + +#: utils/adt/ri_triggers.c:1952 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "funktionen \"%s\" måste köras för DELETE" + +#: utils/adt/ri_triggers.c:1975 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "ingen pg_constraint-post för utlösare \"%s\" på tabell \"%s\"" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "Ta bort denna utlösare för referensiell integritet och dess kollegor, gör sen ALTER TABLE ADD CONSTRAINT." + +#: utils/adt/ri_triggers.c:2295 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "referentiell integritetsfråga på \"%s\" från villkor \"%s\" på \"%s\" gav oväntat resultat" + +#: utils/adt/ri_triggers.c:2299 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Detta beror troligen på att en regel har skrivit om frågan." + +#: utils/adt/ri_triggers.c:2460 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "borttagning av partition \"%s\" bryter mot främmande nyckel-villkoret \"%s\"" + +#: utils/adt/ri_triggers.c:2463 utils/adt/ri_triggers.c:2488 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "Nyckeln (%s)=(%s) refereras fortfarande till från tabell \"%s\"." + +#: utils/adt/ri_triggers.c:2474 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "Nyckel (%s)=(%s) finns inte i tabellen \"%s\"." + +#: utils/adt/ri_triggers.c:2477 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "Nyckeln finns inte i tabellen \"%s\"." + +#: utils/adt/ri_triggers.c:2483 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "update eller delete på tabell \"%s\" bryter mot främmande nyckel-villkoret \"%s\" för tabell \"%s\"" + +#: utils/adt/ri_triggers.c:2491 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "Nyckel refereras fortfarande till från tabell \"%s\"." + +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "inläsning av annonym composite-typ är inte implementerat" + +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 +#: utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "felaktig postliteral: \"%s\"" + +#: utils/adt/rowtypes.c:157 +#, c-format +msgid "Missing left parenthesis." +msgstr "Saknar vänster parentes" + +#: utils/adt/rowtypes.c:186 +#, c-format +msgid "Too few columns." +msgstr "För få kolumner." + +#: utils/adt/rowtypes.c:269 +#, c-format +msgid "Too many columns." +msgstr "För många kolumner." + +#: utils/adt/rowtypes.c:277 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Skräp efter höger parentes" + +#: utils/adt/rowtypes.c:531 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "fel antal kolumner: %d, förväntade %d" + +#: utils/adt/rowtypes.c:559 +#, c-format +msgid "wrong data type: %u, expected %u" +msgstr "fel datatyp: %u, förväntade %u" + +#: utils/adt/rowtypes.c:620 +#, c-format +msgid "improper binary format in record column %d" +msgstr "felaktigt binärt format i postkolumn %d" + +#: utils/adt/rowtypes.c:911 utils/adt/rowtypes.c:1157 utils/adt/rowtypes.c:1415 +#: utils/adt/rowtypes.c:1661 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "kan inte jämföra olika kolumntyper %s och %s vid postkolumn %d" + +#: utils/adt/rowtypes.c:1002 utils/adt/rowtypes.c:1227 +#: utils/adt/rowtypes.c:1512 utils/adt/rowtypes.c:1697 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "kan inte jämföra record-typer med olika antal kolumner" + +#: utils/adt/ruleutils.c:4821 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "regel \"%s\" har en icke stödd händelsetyp %d" + +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "prceision för TIMESTAMP(%d)%s kan inte vara negativ" + +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "precision för TIMESTAMP(%d)%s reducerad till högsta tillåtna, %d" + +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:434 utils/misc/guc.c:11929 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestamp utanför giltigt intervall: \"%s\"" + +#: utils/adt/timestamp.c:372 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "timestamp(%d)-precision måste vara mellan %d och %d" + +#: utils/adt/timestamp.c:496 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "Numeriska tidszoner måste ha \"-\" eller \"+\" som sitt första tecken." + +#: utils/adt/timestamp.c:509 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "numerisk tidszon \"%s\" utanför giltigt intervall" + +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestamp utanför giltigt intervall: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:720 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "timestamp kan inte vara NaN" + +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "timestamp utanför giltigt intervall: \"%g\"" + +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1509 +#: utils/adt/timestamp.c:1944 utils/adt/timestamp.c:3021 +#: utils/adt/timestamp.c:3026 utils/adt/timestamp.c:3031 +#: utils/adt/timestamp.c:3081 utils/adt/timestamp.c:3088 +#: utils/adt/timestamp.c:3095 utils/adt/timestamp.c:3115 +#: utils/adt/timestamp.c:3122 utils/adt/timestamp.c:3129 +#: utils/adt/timestamp.c:3159 utils/adt/timestamp.c:3167 +#: utils/adt/timestamp.c:3211 utils/adt/timestamp.c:3638 +#: utils/adt/timestamp.c:3763 utils/adt/timestamp.c:4223 +#, c-format +msgid "interval out of range" +msgstr "interval utanför giltigt intervall" + +#: utils/adt/timestamp.c:1062 utils/adt/timestamp.c:1095 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "ogitligt modifierare för typen INTERVAL" + +#: utils/adt/timestamp.c:1078 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d)-precision kan inte vara negativ" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d)-precision reducerad till maximalt tillåtna, %d" + +#: utils/adt/timestamp.c:1466 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "interval(%d)-precision måste vara mellan %d och %d" + +#: utils/adt/timestamp.c:2622 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "kan inte subtrahera oändliga tider (timestamp)" + +#: utils/adt/timestamp.c:3891 utils/adt/timestamp.c:4484 +#: utils/adt/timestamp.c:4646 utils/adt/timestamp.c:4667 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "timestamp-enhet \"%s\" stöds inte" + +#: utils/adt/timestamp.c:3905 utils/adt/timestamp.c:4438 +#: utils/adt/timestamp.c:4677 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "timestamp-enhet \"%s\" känns inte igen" + +#: utils/adt/timestamp.c:4035 utils/adt/timestamp.c:4479 +#: utils/adt/timestamp.c:4842 utils/adt/timestamp.c:4864 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "timestamp with time zone, enhet \"%s\" stöds inte" + +#: utils/adt/timestamp.c:4052 utils/adt/timestamp.c:4433 +#: utils/adt/timestamp.c:4873 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "timestamp with time zone, enhet \"%s\" känns inte igen" + +#: utils/adt/timestamp.c:4210 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "intervallenhet \"%s\" stöds inte då månader typiskt har veckor på bråkform" + +#: utils/adt/timestamp.c:4216 utils/adt/timestamp.c:4967 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "intervallenhet \"%s\" stöds inte" + +#: utils/adt/timestamp.c:4232 utils/adt/timestamp.c:4990 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "intervallenhet \"%s\" känns inte igen" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: måste anropas som utlösare" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: måste anropas vid update" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: måste anropas innan update" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: måste anropas för varje rad" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_in är inte implementerad" + +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "distans i frasoperator skall inte vara större än %d" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "syntaxfel i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:334 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "ingen operand i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "värdet är för stort i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:573 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "operanden är för lång i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "ord för långt i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "textsökfråga innehåller inte lexem: \"%s\"" + +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsquery är för stor" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "textsökfråga innehåller bara stoppord eller innehåller inga lexem, hoppar över" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "distans i frasoperator skall vara icke-negativ och mindre än %d" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "ts_rewrite-fråga måste returnera två tsquery-kolumner" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "array med vikter måste vara endimensionell" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "array med vikter är för kort" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "array med vikter får inte innehålla null-värden" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:872 +#, c-format +msgid "weight out of range" +msgstr "vikten är utanför giltigt intervall" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "ordet är för långt (%ld byte, max %ld byte)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "strängen är för lång för tsvector (%ld byte, max %ld byte)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "lexem-array:en får inte innehålla null-värden" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "vikt-array:en får inte innehålla null-värden" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "okänd vikt: \"%c\"" + +#: utils/adt/tsvector_op.c:2414 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "ts_stat-frågan måste returnera en tsvector-kolumn" + +#: utils/adt/tsvector_op.c:2603 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "tsvector-kolumnen \"%s\" existerar inte" + +#: utils/adt/tsvector_op.c:2610 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "kolumnen \"%s\" är inte av typen tsvector" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "konfigurationskolumnen \"%s\" existerar inte" + +#: utils/adt/tsvector_op.c:2628 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "kolumn \"%s\" har inte regconfig-typ" + +#: utils/adt/tsvector_op.c:2635 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "konfigurationskolumn \"%s\" får inte vara null" + +#: utils/adt/tsvector_op.c:2648 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "Textsökkonfigurationsnamn \"%s\" måste vara angivet med schema" + +#: utils/adt/tsvector_op.c:2673 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "kolumnen \"%s\" är inte av typen character" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "syntaxfel i tsvector: \"%s\"" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "det finns inget escape-tecken: \"%s\"" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "fel positionsinfo i tsvector: \"%s\"" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "kunde inte generera slumpmässiga värden" + +#: utils/adt/varbit.c:109 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "längden för typ %s måste vara minst 1" + +#: utils/adt/varbit.c:114 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "längden för typ %s kan inte överstiga %d" + +#: utils/adt/varbit.c:197 utils/adt/varbit.c:498 utils/adt/varbit.c:993 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "bitstränglängden överskrider det maximalt tillåtna (%d)" + +#: utils/adt/varbit.c:211 utils/adt/varbit.c:355 utils/adt/varbit.c:405 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "bitsträngslängden %d matchar inte typen bit(%d)" + +#: utils/adt/varbit.c:233 utils/adt/varbit.c:534 +#, c-format +msgid "\"%c\" is not a valid binary digit" +msgstr "\"%c\" är inte en giltig binär siffra" + +#: utils/adt/varbit.c:258 utils/adt/varbit.c:559 +#, c-format +msgid "\"%c\" is not a valid hexadecimal digit" +msgstr "\"%c\" är inte en giltig hexdecimal siffra" + +#: utils/adt/varbit.c:346 utils/adt/varbit.c:651 +#, c-format +msgid "invalid length in external bit string" +msgstr "ogiltig längd på extern bitsträng" + +#: utils/adt/varbit.c:512 utils/adt/varbit.c:660 utils/adt/varbit.c:756 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "bitsträngen för lång för typen bit varying(%d)" + +#: utils/adt/varbit.c:1086 utils/adt/varbit.c:1184 utils/adt/varlena.c:875 +#: utils/adt/varlena.c:939 utils/adt/varlena.c:1083 utils/adt/varlena.c:3306 +#: utils/adt/varlena.c:3373 +#, c-format +msgid "negative substring length not allowed" +msgstr "negativ substräng-läng tillåts inte" + +#: utils/adt/varbit.c:1241 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "kan inte AND:a bitsträngar av olika storlek" + +#: utils/adt/varbit.c:1282 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "kan inte OR:a bitsträngar av olika storlek" + +#: utils/adt/varbit.c:1322 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "kan inte XOR:a bitsträngar av olika storlek" + +#: utils/adt/varbit.c:1804 utils/adt/varbit.c:1862 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "bitindex %d utanför giltigt intervall (0..%d)" + +#: utils/adt/varbit.c:1813 utils/adt/varlena.c:3566 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "nya biten måste vara 0 eller 1" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "värdet för långt för typen character (%d)" + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "värdet för långt för typen character varying(%d)" + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1475 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för strängjämförelse" + +#: utils/adt/varlena.c:1182 utils/adt/varlena.c:1915 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för substrängsökningar" + +#: utils/adt/varlena.c:1574 utils/adt/varlena.c:1587 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "kunde inte konvertera sträng till UTF-16: felkod %lu" + +#: utils/adt/varlena.c:1602 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "kunde inte jämföra Unicode-strängar: %m" + +#: utils/adt/varlena.c:1653 utils/adt/varlena.c:2367 +#, c-format +msgid "collation failed: %s" +msgstr "jämförelse misslyckades: %s" + +#: utils/adt/varlena.c:2575 +#, c-format +msgid "sort key generation failed: %s" +msgstr "generering av sorteringsnyckel misslyckades: %s" + +#: utils/adt/varlena.c:3450 utils/adt/varlena.c:3517 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "index %d utanför giltigt intervall, 0..%d" + +#: utils/adt/varlena.c:3481 utils/adt/varlena.c:3553 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "index %lld utanför giltigt intervall, 0..%lld" + +#: utils/adt/varlena.c:4590 +#, c-format +msgid "field position must be greater than zero" +msgstr "fältpositionen måste vara större än noll" + +#: utils/adt/varlena.c:5456 +#, c-format +msgid "unterminated format() type specifier" +msgstr "icketerminerad typangivelse för format()" + +#: utils/adt/varlena.c:5457 utils/adt/varlena.c:5591 utils/adt/varlena.c:5712 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "För ett ensamt \"%%\" använd \"%%%%\"." + +#: utils/adt/varlena.c:5589 utils/adt/varlena.c:5710 +#, c-format +msgid "unrecognized format() type specifier \"%c\"" +msgstr "okänd typspecifierare \"%c\" för format()" + +#: utils/adt/varlena.c:5602 utils/adt/varlena.c:5659 +#, c-format +msgid "too few arguments for format()" +msgstr "för få argument till format()" + +#: utils/adt/varlena.c:5755 utils/adt/varlena.c:5937 +#, c-format +msgid "number is out of range" +msgstr "numret är utanför giltigt intervall" + +#: utils/adt/varlena.c:5818 utils/adt/varlena.c:5846 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "formatet anger argument 0 men argumenten är numrerade från 1" + +#: utils/adt/varlena.c:5839 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "argumentposition för bredd måste avslutas med \"$\"" + +#: utils/adt/varlena.c:5884 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "null-värden kan inte formatteras som SQL-identifierare" + +#: utils/adt/varlena.c:6010 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "Unicode-normalisering kan bara utföras om server-kodningen är UTF8" + +#: utils/adt/varlena.c:6023 +#, c-format +msgid "invalid normalization form: %s" +msgstr "ogiltigt normaliseringsform: %s" + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "argumentet till ntile måste vara större än noll" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "argumentet till nth_value måste vara större än noll" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "transaktions-ID %s är från framtiden" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "ogiltig extern pg_snapshot-data" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "ej stödd XML-finess" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Denna funktionalitet kräver att servern byggts med libxml-support." + +#: utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "Du behöver bygga om PostgreSQL med flaggan --with-libxml." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:570 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "ogiltigt kodningsnamn \"%s\"" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "ogiltigt XML-kommentar" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "inget XML-dokument" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "ogiltig XML-processinstruktion" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "XML-processinstruktions målnamn kan inte vara \"%s\"." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML-processinstruktion kan inte innehålla \"?>\"." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "xmlvalidate är inte implementerat" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "kunde inte initiera XML-bibliotek" + +#: utils/adt/xml.c:962 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2 har inkompatibel char-typ: sizeof(char)=%u, sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "kunde inte ställa in XML-felhanterare" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "Detta tyder på att libxml2-versionen som används inte är kompatibel med libxml2-header-filerna som PostgreSQL byggts med." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "Ogiltigt teckenvärde." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "Mellanslag krävs." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "standalone tillåter bara 'yes' eller 'no'." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "Felaktig deklaration: saknar version." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "Saknar kodning i textdeklaration." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "Parsar XML-deklaration: förväntade sig '?>'" + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "Okänd libxml-felkod: %d." + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML stöder inte oändliga datumvärden." + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML stöder inte oändliga timestamp-värden." + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "ogiltig fråga" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "ogiltig array till XML-namnrymdmappning" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "Arrayen måste vara tvådimensionell där längden på andra axeln är 2." + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "tomt XPath-uttryck" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "varken namnrymdnamn eller URI får vara null" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "kunde inte registrera XML-namnrymd med namn \"%s\" och URL \"%s\"" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "namnrymden DEFAULT stöds inte" + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "sökvägsfilter för rad får inte vara tomma strängen" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "sokvägsfilter för kolumn får inte vara tomma strängen" + +#: utils/adt/xml.c:4661 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "mer än ett värde returnerades från kolumns XPath-uttryck" + +#: utils/cache/lsyscache.c:1015 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "typomvandling från typ %s till typ %s finns inte" + +#: utils/cache/lsyscache.c:2764 utils/cache/lsyscache.c:2797 +#: utils/cache/lsyscache.c:2830 utils/cache/lsyscache.c:2863 +#, c-format +msgid "type %s is only a shell" +msgstr "typ %s är bara en shell-typ" + +#: utils/cache/lsyscache.c:2769 +#, c-format +msgid "no input function available for type %s" +msgstr "ingen inläsningsfunktion finns för typ %s" + +#: utils/cache/lsyscache.c:2802 +#, c-format +msgid "no output function available for type %s" +msgstr "ingen utmatningsfunktion finns för typ %s" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "operatorklass \"%s\" för accessmetod %s saknar supportfunktion %d för typ %s" + +#: utils/cache/plancache.c:718 +#, c-format +msgid "cached plan must not change result type" +msgstr "cache:ad plan får inte ändra resultattyp" + +#: utils/cache/relcache.c:6078 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "kunde inte skapa initieringsfil \"%s\" för relations-cache: %m" + +#: utils/cache/relcache.c:6080 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Fortsätter ändå, trots att något är fel." + +#: utils/cache/relcache.c:6402 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "kunde inte ta bort cache-fil \"%s\": %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "kan inte göra PREPARE på en transaktion som ändrat relationsmappningen" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "relationsmappningsfilen \"%s\" innehåller ogiltig data" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "relationsmappningsfilen \"%s\" innehåller en felaktig checksumma" + +#: utils/cache/typcache.c:1692 utils/fmgr/funcapi.c:461 +#, c-format +msgid "record type has not been registered" +msgstr "posttypen har inte registrerats" + +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "TRAP: ExceptionalCondition: fel argument\n" + +#: utils/error/assert.c:40 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "TRAP: %s(\"%s\", Fil: \"%s\", Rad: %d)\n" + +#: utils/error/elog.c:322 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "fel uppstod innan processning av felmeddelande är tillgängligt\n" + +#: utils/error/elog.c:1868 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "kunde inte återöppna filen \"%s\" som stderr: %m" + +#: utils/error/elog.c:1881 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "kunde inte återöppna filen \"%s\" som stdout: %m" + +#: utils/error/elog.c:2373 utils/error/elog.c:2407 utils/error/elog.c:2423 +msgid "[unknown]" +msgstr "[okänd]" + +#: utils/error/elog.c:2893 utils/error/elog.c:3203 utils/error/elog.c:3311 +msgid "missing error text" +msgstr "saknar feltext" + +#: utils/error/elog.c:2896 utils/error/elog.c:2899 utils/error/elog.c:3314 +#: utils/error/elog.c:3317 +#, c-format +msgid " at character %d" +msgstr " vid tecken %d" + +#: utils/error/elog.c:2909 utils/error/elog.c:2916 +msgid "DETAIL: " +msgstr "DETALJ: " + +#: utils/error/elog.c:2923 +msgid "HINT: " +msgstr "TIPS: " + +#: utils/error/elog.c:2930 +msgid "QUERY: " +msgstr "FRÅGA: " + +#: utils/error/elog.c:2937 +msgid "CONTEXT: " +msgstr "KONTEXT: " + +#: utils/error/elog.c:2947 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "PLATS: %s, %s:%d\n" + +#: utils/error/elog.c:2954 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "PLATS: %s:%d\n" + +#: utils/error/elog.c:2961 +msgid "BACKTRACE: " +msgstr "BACKTRACE: " + +#: utils/error/elog.c:2975 +msgid "STATEMENT: " +msgstr "SATS: " + +#: utils/error/elog.c:3364 +msgid "DEBUG" +msgstr "DEBUG" + +#: utils/error/elog.c:3368 +msgid "LOG" +msgstr "LOGG" + +#: utils/error/elog.c:3371 +msgid "INFO" +msgstr "INFO" + +#: utils/error/elog.c:3374 +msgid "NOTICE" +msgstr "NOTIS" + +#: utils/error/elog.c:3377 +msgid "WARNING" +msgstr "VARNING" + +#: utils/error/elog.c:3380 +msgid "ERROR" +msgstr "FEL" + +#: utils/error/elog.c:3383 +msgid "FATAL" +msgstr "FATALT" + +#: utils/error/elog.c:3386 +msgid "PANIC" +msgstr "PANIK" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "kunde inte hitta funktionen \"%s\" i filen \"%s\"" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "kunde inte ladda länkbibliotek \"%s\": %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "inkompatibelt bibliotek \"%s\": saknar magiskt block" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "Utökningsbibliotek krävs för att använda macro:t PG_MODULE_MAGIC." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "inkompatibelt bibliotek \"%s\": versionen stämmer inte" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "Servern är version %d, biblioteket är version %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "Servern har FUNC_MAX_ARGS = %d, biblioteket har %d." + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "Servern har INDEX_MAX_KEYS = %d, biblioteket har %d." + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "Servern har NAMEDATALEN = %d, biblioteket har %d." + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "Servern har FLOAT8PASSBYVAL = %s, biblioteket har %s." + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "Magiskt block har oväntad längd eller annan paddning." + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "inkompatibelt bibliotek \"%s\": magiskt block matchar inte" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "åtkomst till biblioteket \"%s\" tillåts inte" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "ogiltigt macro-namn i dynamisk biblioteksökväg: %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "komponent med längden noll i parameter \"dynamic_library_path\"" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "komponent som inte är en absolut sökväg i parameter \"dynamic_library_path\"" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "interna funktionen \"%s\" finns inte i den interna uppslagstabellen" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "kunde inte hitta funktionsinformation för funktion \"%s\"" + +#: utils/fmgr/fmgr.c:489 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "SQL-anropbara funktioner kräver en medföljande PG_FUNCTION_INFO_V1(funknamn)." + +#: utils/fmgr/fmgr.c:507 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "okänd API-version %d rapporterad av infofunktion \"%s\"" + +#: utils/fmgr/fmgr.c:2003 +#, c-format +msgid "operator class options info is absent in function call context" +msgstr "info om operatorklassflaggor saknas i funktionens anropskontext" + +#: utils/fmgr/fmgr.c:2070 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "språkvalideringsfunktion %u anropad för språk %u istället för %u" + +#: utils/fmgr/funcapi.c:384 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "kunde inte bestämma resultattyp för funktion \"%s\" som deklarerats att returnera typ %s" + +#: utils/fmgr/funcapi.c:1651 utils/fmgr/funcapi.c:1683 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "antalet alias matchar inte antalet kolumner" + +#: utils/fmgr/funcapi.c:1677 +#, c-format +msgid "no column alias was provided" +msgstr "inget kolumnalias angivet" + +#: utils/fmgr/funcapi.c:1701 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "kunde inte få radbeskrivning för funktion som returnerar en record" + +#: utils/init/miscinit.c:285 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "databaskatalogen \"%s\" existerar inte" + +#: utils/init/miscinit.c:290 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "kunde inte läsa rättigheter på katalog \"%s\": %m" + +#: utils/init/miscinit.c:298 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "angiven datakatalog \"%s\" är inte en katalog" + +#: utils/init/miscinit.c:314 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "datakatalogen \"%s\" har fel ägare" + +#: utils/init/miscinit.c:316 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "Servern måste startas av den användare som äger datakatalogen." + +#: utils/init/miscinit.c:334 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "datakatalogen \"%s\" har felaktiga rättigheter" + +#: utils/init/miscinit.c:336 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Rättigheterna skall vara u=rwx (0700) eller u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:615 utils/misc/guc.c:7139 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "kan inte sätta parameter \"%s\" från en säkerhetsbegränsad operation" + +#: utils/init/miscinit.c:683 +#, c-format +msgid "role with OID %u does not exist" +msgstr "roll med OID %u existerar inte" + +#: utils/init/miscinit.c:713 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "roll \"%s\" tillåts inte logga in" + +#: utils/init/miscinit.c:731 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "för många uppkopplingar för roll \"%s\"" + +#: utils/init/miscinit.c:791 +#, c-format +msgid "permission denied to set session authorization" +msgstr "rättighet saknas för att sätta sessionsauktorisation" + +#: utils/init/miscinit.c:874 +#, c-format +msgid "invalid role OID: %u" +msgstr "ogiltigt roll-OID: %u" + +#: utils/init/miscinit.c:928 +#, c-format +msgid "database system is shut down" +msgstr "databassystemet är nedstängt" + +#: utils/init/miscinit.c:1015 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "kan inte skapa låsfil \"%s\": %m" + +#: utils/init/miscinit.c:1029 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "kunde inte öppna låsfil \"%s\": %m" + +#: utils/init/miscinit.c:1036 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "kunde inte läsa låsfil \"%s\": %m" + +#: utils/init/miscinit.c:1045 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "låsfilen \"%s\" är tom" + +#: utils/init/miscinit.c:1046 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "Antingen startar en annan server eller så är låsfilen kvar från en tidigare serverkrash vid uppstart." + +#: utils/init/miscinit.c:1090 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "låsfil med namn \"%s\" finns redan" + +#: utils/init/miscinit.c:1094 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "Kör en annan postgres (PID %d) i datakatalogen \"%s\"?" + +#: utils/init/miscinit.c:1096 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "Kör en annan postmaster (PID %d) i datakatalogen \"%s\"?" + +#: utils/init/miscinit.c:1099 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "Använder en annan postgres (PID %d) uttagesfilen (socket) \"%s\"?" + +#: utils/init/miscinit.c:1101 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "Använder en annan postmaster (PID %d) uttagesfilen (socket) \"%s\"?" + +#: utils/init/miscinit.c:1152 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "kunde inte ta bort gammal låsfil \"%s\": %m" + +#: utils/init/miscinit.c:1154 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "Filen verkar ha lämnats kvar av misstag, men kan inte tas bort. Ta bort den för hand och försök igen.>" + +#: utils/init/miscinit.c:1191 utils/init/miscinit.c:1205 +#: utils/init/miscinit.c:1216 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "kunde inte skriva låsfil \"%s\": %m" + +#: utils/init/miscinit.c:1327 utils/init/miscinit.c:1469 utils/misc/guc.c:10066 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "kunde inte läsa från fil \"%s\": %m" + +#: utils/init/miscinit.c:1457 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "kunde inte öppna fil \"%s\": %m: fortsätter ändå" + +#: utils/init/miscinit.c:1482 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "låsfil \"%s\" innehåller fel PID: %ld istället för %ld" + +#: utils/init/miscinit.c:1521 utils/init/miscinit.c:1537 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\" är inte en giltigt datakatalog" + +#: utils/init/miscinit.c:1523 +#, c-format +msgid "File \"%s\" is missing." +msgstr "Filen \"%s\" saknas." + +#: utils/init/miscinit.c:1539 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "Filen \"%s\" innehåller inte giltig data." + +#: utils/init/miscinit.c:1541 +#, c-format +msgid "You might need to initdb." +msgstr "Du kan behöva köra initdb." + +#: utils/init/miscinit.c:1549 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "Datakatalogen har skapats av PostgreSQL version %s, som inte är kompatibel med version %s." + +#: utils/init/miscinit.c:1616 +#, c-format +msgid "loaded library \"%s\"" +msgstr "laddat bibliotek \"%s\"" + +#: utils/init/postinit.c:255 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "replikeringsanslutning auktoriserad: användare=%s application_name=%s SSL påslagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "off" +msgstr "av" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "on" +msgstr "på" + +#: utils/init/postinit.c:262 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "replikeringsanslutning auktoriserad: användare=%s SSL påslagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:272 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s" +msgstr "replikeringsanslutning auktoriserad: användare=%s application_name=%s" + +#: utils/init/postinit.c:275 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "replikeringsanslutning auktoriserad: användare=%s" + +#: utils/init/postinit.c:284 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "anslutning auktoriserad: användare=%s databas=%s application_name=%s SSL påslagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:290 +#, c-format +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "anslutning auktoriserad: användare=%s databas=%s SSL påslagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:300 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s" +msgstr "anslutning auktoriserad: användare=%s databas=%s application_name=%s" + +#: utils/init/postinit.c:302 +#, c-format +msgid "connection authorized: user=%s database=%s" +msgstr "anslutning auktoriserad: användare=%s databas=%s" + +#: utils/init/postinit.c:334 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "databasen \"%s\" har försvunnit från pg_database" + +#: utils/init/postinit.c:336 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "Databasen med OID %u verkar nu höra till \"%s\"." + +#: utils/init/postinit.c:356 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "databasen \"%s\" tar för närvarande inte emot uppkopplingar" + +#: utils/init/postinit.c:369 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "rättighet saknas för databas \"%s\"" + +#: utils/init/postinit.c:370 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "Användaren har inte rättigheten CONNECT." + +#: utils/init/postinit.c:387 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "för många uppkopplingar till databasen \"%s\"" + +#: utils/init/postinit.c:409 utils/init/postinit.c:416 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "databaslokalen är inkompatibel med operativsystemet" + +#: utils/init/postinit.c:410 +#, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "Databasen initierades med LC_COLLATE \"%s\" vilket inte känns igen av setlocale()." + +#: utils/init/postinit.c:412 utils/init/postinit.c:419 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "Återskapa databasen med en annan lokal eller installera den saknade lokalen." + +#: utils/init/postinit.c:417 +#, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "Databasen initierades med LC_CTYPE \"%s\", vilket inte känns igen av setlocale()." + +#: utils/init/postinit.c:762 +#, c-format +msgid "no roles are defined in this database system" +msgstr "inga roller är definierade i detta databassystem" + +#: utils/init/postinit.c:763 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Du borde direkt köra CREATE USER \"%s\" SUPERUSER;." + +#: utils/init/postinit.c:799 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "nya replikeringsanslutningar tillåts inte under databasnedstängning" + +#: utils/init/postinit.c:803 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "måste vara superanvändare för att ansluta när databasen håller på att stängas ner" + +#: utils/init/postinit.c:813 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "måste vara superanvändare för att ansluta i binärt uppgraderingsläger" + +#: utils/init/postinit.c:826 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "resterande anslutningsslottar är reserverade för superanvändaranslutningar utan replikering" + +#: utils/init/postinit.c:836 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "måste vara superanvändare eller replikeringsroll för att starta \"walsender\"" + +#: utils/init/postinit.c:905 +#, c-format +msgid "database %u does not exist" +msgstr "databasen %u existerar inte" + +#: utils/init/postinit.c:994 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Det verkar precis ha tagits bort eller döpts om." + +#: utils/init/postinit.c:1012 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Databasens underbibliotek \"%s\" saknas." + +#: utils/init/postinit.c:1017 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "kunde inte komma åt katalog \"%s\": %m" + +#: utils/mb/conv.c:443 utils/mb/conv.c:635 +#, c-format +msgid "invalid encoding number: %d" +msgstr "ogiltigt kodningsnummer: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "oväntat kodnings-ID %d för ISO 8859-teckenuppsättningarna" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "oväntat kodnings-ID %d för WIN-teckenuppsättningarna" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:842 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "konvertering mellan %s och %s stöds inte" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "standardkonverteringsfunktion för kodning \"%s\" till \"%s\" finns inte" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:429 utils/mb/mbutils.c:758 +#: utils/mb/mbutils.c:784 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "Sträng på %d byte är för lång för kodningskonvertering." + +#: utils/mb/mbutils.c:511 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "ogiltigt källkodningsnamn \"%s\"" + +#: utils/mb/mbutils.c:516 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "ogiltigt målkodningsnamn \"%s\"" + +#: utils/mb/mbutils.c:656 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "ogiltigt byte-sekvens för kodning \"%s\": 0x%02x\"" + +#: utils/mb/mbutils.c:819 +#, c-format +msgid "invalid Unicode code point" +msgstr "ogiltig Unicode-kodpunkt" + +#: utils/mb/mbutils.c:1087 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codeset misslyckades" + +#: utils/mb/mbutils.c:1595 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "ogiltigt byte-sekvens för kodning \"%s\": %s" + +#: utils/mb/mbutils.c:1628 +#, c-format +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "tecken med byte-sekvens %s i kodning \"%s\" har inget motsvarande i kodning \"%s\"" + +#: utils/misc/guc.c:679 +msgid "Ungrouped" +msgstr "Ej grupperad" + +#: utils/misc/guc.c:681 +msgid "File Locations" +msgstr "Filplatser" + +#: utils/misc/guc.c:683 +msgid "Connections and Authentication" +msgstr "Uppkopplingar och Autentisering" + +#: utils/misc/guc.c:685 +msgid "Connections and Authentication / Connection Settings" +msgstr "Uppkopplingar och Autentisering / Uppkopplingsinställningar" + +#: utils/misc/guc.c:687 +msgid "Connections and Authentication / Authentication" +msgstr "Uppkopplingar och Autentisering / Autentisering" + +#: utils/misc/guc.c:689 +msgid "Connections and Authentication / SSL" +msgstr "Uppkopplingar och Autentisering / SSL" + +#: utils/misc/guc.c:691 +msgid "Resource Usage" +msgstr "Resursanvändning" + +#: utils/misc/guc.c:693 +msgid "Resource Usage / Memory" +msgstr "Resursanvändning / Minne" + +#: utils/misc/guc.c:695 +msgid "Resource Usage / Disk" +msgstr "Resursanvändning / Disk" + +#: utils/misc/guc.c:697 +msgid "Resource Usage / Kernel Resources" +msgstr "Resursanvändning / Kärnresurser" + +#: utils/misc/guc.c:699 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Resursanvändning / Kostnadsbaserad Vacuum-fördröjning" + +#: utils/misc/guc.c:701 +msgid "Resource Usage / Background Writer" +msgstr "Resursanvändning / Bakgrundskrivare" + +#: utils/misc/guc.c:703 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Resursanvändning / Asynkront beteende" + +#: utils/misc/guc.c:705 +msgid "Write-Ahead Log" +msgstr "Write-Ahead Log" + +#: utils/misc/guc.c:707 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead Log / Inställningar" + +#: utils/misc/guc.c:709 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead Log / Checkpoint:er" + +#: utils/misc/guc.c:711 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead Log / Arkivering" + +#: utils/misc/guc.c:713 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead Log / Återställning från arkiv" + +#: utils/misc/guc.c:715 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead Log / Återställningsmål" + +#: utils/misc/guc.c:717 +msgid "Replication" +msgstr "Replikering" + +#: utils/misc/guc.c:719 +msgid "Replication / Sending Servers" +msgstr "Replilering / Skickande servrar" + +#: utils/misc/guc.c:721 +msgid "Replication / Master Server" +msgstr "Replikering / Master-server" + +#: utils/misc/guc.c:723 +msgid "Replication / Standby Servers" +msgstr "Replikering / Standby-servrar" + +#: utils/misc/guc.c:725 +msgid "Replication / Subscribers" +msgstr "Replikering / Prenumeranter" + +#: utils/misc/guc.c:727 +msgid "Query Tuning" +msgstr "Frågeoptimering" + +#: utils/misc/guc.c:729 +msgid "Query Tuning / Planner Method Configuration" +msgstr "Frågeoptimering / Planeringsmetodinställningar" + +#: utils/misc/guc.c:731 +msgid "Query Tuning / Planner Cost Constants" +msgstr "Frågeoptimering / Plannerarens kostnadskonstanter" + +#: utils/misc/guc.c:733 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "Frågeoptimering / Genetisk frågeoptimerare" + +#: utils/misc/guc.c:735 +msgid "Query Tuning / Other Planner Options" +msgstr "Frågeoptimering / Andra planeringsinställningar" + +#: utils/misc/guc.c:737 +msgid "Reporting and Logging" +msgstr "Rapportering och loggning" + +#: utils/misc/guc.c:739 +msgid "Reporting and Logging / Where to Log" +msgstr "Rapportering och loggning / Logga var?" + +#: utils/misc/guc.c:741 +msgid "Reporting and Logging / When to Log" +msgstr "Rapportering och loggning / Logga när?" + +#: utils/misc/guc.c:743 +msgid "Reporting and Logging / What to Log" +msgstr "Rapportering och loggning / Logga vad?" + +#: utils/misc/guc.c:745 +msgid "Process Title" +msgstr "Processtitel" + +#: utils/misc/guc.c:747 +msgid "Statistics" +msgstr "Statistik" + +#: utils/misc/guc.c:749 +msgid "Statistics / Monitoring" +msgstr "Statistik / Övervakning" + +#: utils/misc/guc.c:751 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "Statistik / Insamlare av fråge- och index-statistik" + +#: utils/misc/guc.c:753 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:755 +msgid "Client Connection Defaults" +msgstr "Standard för klientanslutning" + +#: utils/misc/guc.c:757 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "Standard för klientanslutning / Satsbeteende" + +#: utils/misc/guc.c:759 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "Standard för klientanslutning / Lokal och formattering" + +#: utils/misc/guc.c:761 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "Standard för klientanslutning / Förladdning av delat bibliotek" + +#: utils/misc/guc.c:763 +msgid "Client Connection Defaults / Other Defaults" +msgstr "Standard för klientanslutning / Övriga standardvärden" + +#: utils/misc/guc.c:765 +msgid "Lock Management" +msgstr "Låshantering" + +#: utils/misc/guc.c:767 +msgid "Version and Platform Compatibility" +msgstr "Version och plattformskompabilitet" + +#: utils/misc/guc.c:769 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Version och plattformskompabilitet / Tidigare PostrgreSQL-versioner" + +#: utils/misc/guc.c:771 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Version och plattformskompabilitet / Andra plattformar och klienter" + +#: utils/misc/guc.c:773 +msgid "Error Handling" +msgstr "Felhantering" + +#: utils/misc/guc.c:775 +msgid "Preset Options" +msgstr "Förinställningsflaggor" + +#: utils/misc/guc.c:777 +msgid "Customized Options" +msgstr "Ändrade flaggor" + +#: utils/misc/guc.c:779 +msgid "Developer Options" +msgstr "Utvecklarflaggor" + +#: utils/misc/guc.c:837 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Giltiga enheter för denna parameter är \"B\", \"kB\", \"MB\", \"GB\" och \"TB\"." + +#: utils/misc/guc.c:874 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Giltiga enheter för denna parameter är \"us\", \"ms\", \"s\", \"min\", \"h\" och \"d\"." + +#: utils/misc/guc.c:936 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "Aktiverar planerarens användning av planer med sekvensiell skanning." + +#: utils/misc/guc.c:946 +msgid "Enables the planner's use of index-scan plans." +msgstr "Aktiverar planerarens användning av planer med indexskanning." + +#: utils/misc/guc.c:956 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Aktiverar planerarens användning av planer med skanning av enbart index." + +#: utils/misc/guc.c:966 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "Aktiverar planerarens användning av planer med bitmapskanning." + +#: utils/misc/guc.c:976 +msgid "Enables the planner's use of TID scan plans." +msgstr "Aktiverar planerarens användning av planer med TID-skanning." + +#: utils/misc/guc.c:986 +msgid "Enables the planner's use of explicit sort steps." +msgstr "Slår på planerarens användning av explicita sorteringssteg." + +#: utils/misc/guc.c:996 +msgid "Enables the planner's use of incremental sort steps." +msgstr "Aktiverar planerarens användning av inkrementella sorteringssteg." + +#: utils/misc/guc.c:1005 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Aktiverar planerarens användning av planer med hash-aggregering" + +#: utils/misc/guc.c:1015 +msgid "Enables the planner's use of materialization." +msgstr "Aktiverar planerarens användning av materialisering." + +#: utils/misc/guc.c:1025 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "Aktiverar planerarens användning av planer med nästlad loop-join," + +#: utils/misc/guc.c:1035 +msgid "Enables the planner's use of merge join plans." +msgstr "Aktiverar planerarens användning av merge-join-planer." + +#: utils/misc/guc.c:1045 +msgid "Enables the planner's use of hash join plans." +msgstr "Aktiverar planerarens användning av hash-join-planer." + +#: utils/misc/guc.c:1055 +msgid "Enables the planner's use of gather merge plans." +msgstr "Aktiverar planerarens användning av planer med gather-merge." + +#: utils/misc/guc.c:1065 +msgid "Enables partitionwise join." +msgstr "Aktiverar join per partition." + +#: utils/misc/guc.c:1075 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Aktiverar aggregering och gruppering per partition." + +#: utils/misc/guc.c:1085 +msgid "Enables the planner's use of parallel append plans." +msgstr "Aktiverar planerarens användning av planer med parallell append." + +#: utils/misc/guc.c:1095 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Aktiverar planerarens användning av planer med parallell hash." + +#: utils/misc/guc.c:1105 +msgid "Enables plan-time and run-time partition pruning." +msgstr "Aktiverar partitionsbeskärning vid planering och vid körning." + +#: utils/misc/guc.c:1106 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Tillåter att frågeplaneraren och exekveraren jämför partitionsgränser med villkor i frågan för att bestämma vilka partitioner som skall skannas." + +#: utils/misc/guc.c:1117 +msgid "Enables genetic query optimization." +msgstr "Aktiverar genetisk frågeoptimering." + +#: utils/misc/guc.c:1118 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Denna algoritm försöker utföra planering utan fullständig sökning." + +#: utils/misc/guc.c:1129 +msgid "Shows whether the current user is a superuser." +msgstr "Visar om den aktuella användaren är en superanvändare." + +#: utils/misc/guc.c:1139 +msgid "Enables advertising the server via Bonjour." +msgstr "Aktiverar annonsering av servern via Bonjour." + +#: utils/misc/guc.c:1148 +msgid "Collects transaction commit time." +msgstr "Samlar in tid för transaktions-commit." + +#: utils/misc/guc.c:1157 +msgid "Enables SSL connections." +msgstr "Tillåter SSL-anslutningar." + +#: utils/misc/guc.c:1166 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Använd ssl_passphrase_command även vid server-reload." + +#: utils/misc/guc.c:1175 +msgid "Give priority to server ciphersuite order." +msgstr "Ge prioritet till serverns ordning av kryptometoder." + +#: utils/misc/guc.c:1184 +msgid "Forces synchronization of updates to disk." +msgstr "Tvingar synkronisering av uppdateringar till disk." + +#: utils/misc/guc.c:1185 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "Servern kommer använda systemanropet fsync() på ett antal platser för att se till att uppdateringar fysiskt skrivs till disk. Detta för att säkerställa att databasklustret kan starta i ett konsistent tillstånd efter en operativsystemkrash eller hårdvarukrash." + +#: utils/misc/guc.c:1196 +msgid "Continues processing after a checksum failure." +msgstr "Fortsätter processande efter checksummefel." + +#: utils/misc/guc.c:1197 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "Normalt vid detektion av checksummefel så rapporterar PostgreSQL felet och avbryter den aktuella transaktionen. Sätts ignore_checksum_failure till true så kommer systemet hoppa över felet (men fortfarande rapportera en varning). Detta beteende kan orsaka krasher eller andra allvarliga problem. Detta påverkas bara om checksummor är påslaget." + +#: utils/misc/guc.c:1211 +msgid "Continues processing past damaged page headers." +msgstr "Fortsätter processande efter trasiga sidhuvuden." + +#: utils/misc/guc.c:1212 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "Normalt vid detektion av trasiga sidhuvuden så rapporterar PostgreSQL felet och avbryter den aktuella transaktionen. Sätts zero_damaged_pages till true så kommer systemet istället rapportera en varning, nollställa den trasiga sidan samt fortsätta processa. Detta kommer förstöra data (alla rader i den trasiga sidan)." + +#: utils/misc/guc.c:1225 +msgid "Continues recovery after an invalid pages failure." +msgstr "Fortsätter återställande efter fel på grund av ogiltiga sidor." + +#: utils/misc/guc.c:1226 +msgid "Detection of WAL records having references to invalid pages during recovery causes PostgreSQL to raise a PANIC-level error, aborting the recovery. Setting ignore_invalid_pages to true causes the system to ignore invalid page references in WAL records (but still report a warning), and continue recovery. This behavior may cause crashes, data loss, propagate or hide corruption, or other serious problems. Only has an effect during recovery or in standby mode." +msgstr "Normalt vid detektion av WAL-poster som refererar till ogiltiga sidor under återställning så kommer PostgreSQL att signalera ett fel på PANIC-nivå och avbryta återställningen. Sätts ignore_invalid_pages till true så kommer systemet hoppa över ogiltiga sidreferenser i WAL-poster (men fortfarande rapportera en varning) och fortsätta återställningen. Detta beteende kan orsaka krasher, dataförluster, sprida eller dölja korruption eller ge andra allvarliga problem. Detta påverkar bara under återställning eller i standby-läge." + +#: utils/misc/guc.c:1244 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "Skriver fulla sidor till WAL första gången de ändras efter en checkpoint." + +#: utils/misc/guc.c:1245 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "En sidskrivning som sker vid en operativsystemkrash kan bli delvis utskriven till disk. Under återställning så kommer radändringar i WAL:en inte vara tillräckligt för att återställa datan. Denna flagga skriver ut sidor först efter att en WAL-checkpoint gjorts vilket gör att full återställning kan ske." + +#: utils/misc/guc.c:1258 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "Skriver fulla sidor till WAL första gången de ändras efter en checkpoint, även för ickekritiska ändringar." + +#: utils/misc/guc.c:1268 +msgid "Compresses full-page writes written in WAL file." +msgstr "Komprimerar skrivning av hela sidor som skrivs i WAL-fil." + +#: utils/misc/guc.c:1278 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Skriv nollor till nya WAL-filer innan första användning." + +#: utils/misc/guc.c:1288 +msgid "Recycles WAL files by renaming them." +msgstr "Återanvänder WAL-filer genom att byta namn på dem." + +#: utils/misc/guc.c:1298 +msgid "Logs each checkpoint." +msgstr "Logga varje checkpoint." + +#: utils/misc/guc.c:1307 +msgid "Logs each successful connection." +msgstr "Logga varje lyckad anslutning." + +#: utils/misc/guc.c:1316 +msgid "Logs end of a session, including duration." +msgstr "Loggar slut på session, inklusive längden." + +#: utils/misc/guc.c:1325 +msgid "Logs each replication command." +msgstr "Loggar alla replikeringskommanon." + +#: utils/misc/guc.c:1334 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Visar om den körande servern har assert-kontroller påslagna." + +#: utils/misc/guc.c:1349 +msgid "Terminate session on any error." +msgstr "Avbryt sessionen vid fel." + +#: utils/misc/guc.c:1358 +msgid "Reinitialize server after backend crash." +msgstr "Återinitiera servern efter en backend-krash." + +#: utils/misc/guc.c:1368 +msgid "Logs the duration of each completed SQL statement." +msgstr "Loggar tiden för varje avslutad SQL-sats." + +#: utils/misc/guc.c:1377 +msgid "Logs each query's parse tree." +msgstr "Loggar alla frågors parse-träd." + +#: utils/misc/guc.c:1386 +msgid "Logs each query's rewritten parse tree." +msgstr "Logga alla frågors omskrivet parse-träd." + +#: utils/misc/guc.c:1395 +msgid "Logs each query's execution plan." +msgstr "Logga alla frågors körningsplan." + +#: utils/misc/guc.c:1404 +msgid "Indents parse and plan tree displays." +msgstr "Indentera parse och planeringsträdutskrifter" + +#: utils/misc/guc.c:1413 +msgid "Writes parser performance statistics to the server log." +msgstr "Skriver parserns prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1422 +msgid "Writes planner performance statistics to the server log." +msgstr "Skriver planerarens prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1431 +msgid "Writes executor performance statistics to the server log." +msgstr "Skrivere exekverarens prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1440 +msgid "Writes cumulative performance statistics to the server log." +msgstr "Skriver ackumulerad prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1450 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "Loggar statisik för användning av systemresurser (minne och CPU) för olika B-tree-operationer." + +#: utils/misc/guc.c:1462 +msgid "Collects information about executing commands." +msgstr "Samla information om körda kommanon." + +#: utils/misc/guc.c:1463 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "Slår på insamling av information om det nu körande kommandot för varje session, tillsammans med klockslaget när det kommandot började köra." + +#: utils/misc/guc.c:1473 +msgid "Collects statistics on database activity." +msgstr "Samla in statistik om databasaktivitet." + +#: utils/misc/guc.c:1482 +msgid "Collects timing statistics for database I/O activity." +msgstr "Samla in timingstatistik om databasens I/O-aktivitet." + +#: utils/misc/guc.c:1492 +msgid "Updates the process title to show the active SQL command." +msgstr "Uppdaterar processtitel till att visa aktivt SQL-kommando." + +#: utils/misc/guc.c:1493 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "Slår på uppdatering av processtiteln varje gång ett nytt SQL-kommando tas emot av servern." + +#: utils/misc/guc.c:1506 +msgid "Starts the autovacuum subprocess." +msgstr "Starta autovacuum-barnprocess." + +#: utils/misc/guc.c:1516 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "Skapar debug-output för LISTEN och NOTIFY." + +#: utils/misc/guc.c:1528 +msgid "Emits information about lock usage." +msgstr "Visar information om låsanvändning." + +#: utils/misc/guc.c:1538 +msgid "Emits information about user lock usage." +msgstr "Visar information om användares låsanvändning." + +#: utils/misc/guc.c:1548 +msgid "Emits information about lightweight lock usage." +msgstr "Visar information om lättviktig låsanvändning." + +#: utils/misc/guc.c:1558 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "Dumpar information om alla aktuella lås när en deadlock-timeout sker." + +#: utils/misc/guc.c:1570 +msgid "Logs long lock waits." +msgstr "Loggar långa väntetider på lås." + +#: utils/misc/guc.c:1580 +msgid "Logs the host name in the connection logs." +msgstr "Loggar hostnamnet i anslutningsloggen." + +#: utils/misc/guc.c:1581 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "Som standard visar anslutningsloggen bara IP-adressen för den anslutande värden. Om du vill att värdnamnet skall visas så kan du slå på detta men beroende på hur uppsättningen av namnuppslag är gjored så kan detta ha en markant prestandapåverkan." + +#: utils/misc/guc.c:1592 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "Tolkar \"uttryck=NULL\" som \"uttryck IS NULL\"." + +#: utils/misc/guc.c:1593 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "Om påslagen så kommer uttryck på formen uttryck = NULL (eller NULL = uttryck) att behandlas som uttryck IS NULL, det vill säga returnera true om uttryck evalueras till värdet null eller evalueras till false annars. Det korrekta beteendet för uttryck = NULL är att alltid returnera null (okänt)." + +#: utils/misc/guc.c:1605 +msgid "Enables per-database user names." +msgstr "Aktiverar användarnamn per databas." + +#: utils/misc/guc.c:1614 +msgid "Sets the default read-only status of new transactions." +msgstr "Ställer in standard read-only-status för nya transaktioner." + +#: utils/misc/guc.c:1623 +msgid "Sets the current transaction's read-only status." +msgstr "Ställer in nuvarande transaktions read-only-status." + +#: utils/misc/guc.c:1633 +msgid "Sets the default deferrable status of new transactions." +msgstr "Ställer in standard deferrable-status för nya transaktioner." + +#: utils/misc/guc.c:1642 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "Bestämmer om en serialiserbar transaktion för läsning kommer fördröjas tills den kan köras utan serialiseringsfel." + +#: utils/misc/guc.c:1652 +msgid "Enable row security." +msgstr "Aktiverar radsäkerhet." + +#: utils/misc/guc.c:1653 +msgid "When enabled, row security will be applied to all users." +msgstr "Om aktiv så kommer radsäkerhet användas för alla användare." + +#: utils/misc/guc.c:1661 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "Kontrollera funktionskroppen vid CREATE FUNCTION." + +#: utils/misc/guc.c:1670 +msgid "Enable input of NULL elements in arrays." +msgstr "Aktiverar inmatning av NULL-element i arrayer." + +#: utils/misc/guc.c:1671 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "Om påslagen så kommer ej citerade NULL i indatavärden för en array betyda värdet null, annars tolkas det bokstavligt." + +#: utils/misc/guc.c:1687 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OIDS stöds inte längre; denna kan bara vara false." + +#: utils/misc/guc.c:1697 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "Starta en subprocess för att fånga output från stderr och/eller csv-loggar till loggfiler." + +#: utils/misc/guc.c:1706 +msgid "Truncate existing log files of same name during log rotation." +msgstr "Trunkera existerande loggfiler med samma namn under loggrotering." + +#: utils/misc/guc.c:1717 +msgid "Emit information about resource usage in sorting." +msgstr "Skicka ut information om resursanvändning vid sortering." + +#: utils/misc/guc.c:1731 +msgid "Generate debugging output for synchronized scanning." +msgstr "Generera debug-output för synkroniserad skanning." + +#: utils/misc/guc.c:1746 +msgid "Enable bounded sorting using heap sort." +msgstr "Slår på begränsad sortering med heap-sort." + +#: utils/misc/guc.c:1759 +msgid "Emit WAL-related debugging output." +msgstr "Skicka ut WAL-relaterad debug-data." + +#: utils/misc/guc.c:1771 +msgid "Datetimes are integer based." +msgstr "Datetime är heltalsbaserad" + +#: utils/misc/guc.c:1782 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "Anger hurvida Kerberos- och GSSAPI-användarnamn skall tolkas skiftlägesokänsligt." + +#: utils/misc/guc.c:1792 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Varna om backåtstreck-escape i vanliga stränglitteraler." + +#: utils/misc/guc.c:1802 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "Gör att '...'-stängar tolkar bakåtstreck bokstavligt." + +#: utils/misc/guc.c:1813 +msgid "Enable synchronized sequential scans." +msgstr "Slå på synkroniserad sekvensiell skanning." + +#: utils/misc/guc.c:1823 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Anger hurvida man skall inkludera eller exkludera transaktion för återställningmål." + +#: utils/misc/guc.c:1833 +msgid "Allows connections and queries during recovery." +msgstr "Tillåt anslutningar och frågor under återställning." + +#: utils/misc/guc.c:1843 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "Tillåter feedback från en hot standby till primären för att undvika frågekonflikter." + +#: utils/misc/guc.c:1853 +msgid "Allows modifications of the structure of system tables." +msgstr "Tillåter strukturförändringar av systemtabeller." + +#: utils/misc/guc.c:1864 +msgid "Disables reading from system indexes." +msgstr "Stänger av läsning från systemindex." + +#: utils/misc/guc.c:1865 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "Det förhindrar inte uppdatering av index så det är helt säkert att använda. Det värsta som kan hända är att det är långsamt." + +#: utils/misc/guc.c:1876 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "Slår på bakåtkompabilitetsläge för rättighetskontroller på stora objekt." + +#: utils/misc/guc.c:1877 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "Hoppar över rättighetskontroller vid läsning eller modifiering av stora objekt, för kompabilitet med PostgreSQL-releaser innan 9.0." + +#: utils/misc/guc.c:1887 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "Skicka ut varning för konstruktioner som ändrat semantik sedan PostgreSQL 9.4." + +#: utils/misc/guc.c:1897 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "När SQL-fragment genereras så citera alla identifierare." + +#: utils/misc/guc.c:1907 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Visar om datachecksummor är påslagna för detta kluster." + +#: utils/misc/guc.c:1918 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "Lägg till sekvensnummer till syslog-meddelanden för att undvika att duplikat tas bort." + +#: utils/misc/guc.c:1928 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "Dela meddelanden som skickas till syslog till egna rader och begränsa till 1024 byte." + +#: utils/misc/guc.c:1938 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Bestämmer om \"Gather\" och \"Gather Merge\" också exekverar subplaner." + +#: utils/misc/guc.c:1939 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "Skall gather-noder också exekvera subplaner eller bara samla in tupler?" + +#: utils/misc/guc.c:1949 +msgid "Allow JIT compilation." +msgstr "Tillåt JIT-kompilering." + +#: utils/misc/guc.c:1960 +msgid "Register JIT compiled function with debugger." +msgstr "Registrera JIT-kompilerad funktion hos debuggern." + +#: utils/misc/guc.c:1977 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Skriv ut LLVM-bitkod för att möjliggöra JIT-debuggning." + +#: utils/misc/guc.c:1988 +msgid "Allow JIT compilation of expressions." +msgstr "Tillåt JIT-kompilering av uttryck." + +#: utils/misc/guc.c:1999 +msgid "Register JIT compiled function with perf profiler." +msgstr "Registrera JIT-kompilerad funktion med perf-profilerare." + +#: utils/misc/guc.c:2016 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Tillåt JIT-kompilering av tupeluppdelning." + +#: utils/misc/guc.c:2027 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Hurvida vi skall fortsätta efter ett fel att synka datafiler." + +#: utils/misc/guc.c:2036 +msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." +msgstr "Anger hurvida en WAL-mottagare skall skapa en temporär replikeringsslot om ingen permanent slot är konfigurerad." + +#: utils/misc/guc.c:2054 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "Tvingar byte till nästa WAL-fil om en ny fil inte har startats inom N sekunder." + +#: utils/misc/guc.c:2065 +msgid "Waits N seconds on connection startup after authentication." +msgstr "Väntar N sekunder vid anslutningsstart efter authentisering." + +#: utils/misc/guc.c:2066 utils/misc/guc.c:2624 +msgid "This allows attaching a debugger to the process." +msgstr "Detta tillåter att man ansluter en debugger till processen." + +#: utils/misc/guc.c:2075 +msgid "Sets the default statistics target." +msgstr "Sätter standardstatistikmålet." + +#: utils/misc/guc.c:2076 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "Detta gäller tabellkolumner som inte har ett kolumnspecifikt mål satt med ALTER TABLE SET STATISTICS." + +#: utils/misc/guc.c:2085 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "Sätter en övre gräns på FROM-listans storlek där subfrågor slås isär." + +#: utils/misc/guc.c:2087 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "Planeraren kommer slå samman subfrågor med yttre frågor om den resulterande FROM-listan inte har fler än så här många poster." + +#: utils/misc/guc.c:2098 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "Sätter en övre gräns på FROM-listans storlek där JOIN-konstruktioner plattas till." + +#: utils/misc/guc.c:2100 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "Planeraren kommer platta till explicita JOIN-konstruktioner till listor av FROM-poster när resultatet blir en lista med max så här många poster." + +#: utils/misc/guc.c:2111 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "Sätter en undre gräns på antal FROM-poster när GEQO används." + +#: utils/misc/guc.c:2121 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: effort används som standard för andra GEQO-parametrar." + +#: utils/misc/guc.c:2131 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: antal individer i populationen." + +#: utils/misc/guc.c:2132 utils/misc/guc.c:2142 +msgid "Zero selects a suitable default value." +msgstr "Noll väljer ett lämpligt standardvärde." + +#: utils/misc/guc.c:2141 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: antal iterationer för algoritmen." + +#: utils/misc/guc.c:2153 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Sätter tiden som väntas på ett lås innan kontroll av deadlock sker." + +#: utils/misc/guc.c:2164 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "Sätter maximal fördröjning innan frågor avbryts när en \"hot standby\"-server processar arkiverad WAL-data." + +#: utils/misc/guc.c:2175 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "Sätter maximal fördröjning innan frågor avbryts när en \"hot stanby\"-server processar strömmad WAL-data." + +#: utils/misc/guc.c:2186 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "Ställer in minsta fördröjning för att applicera ändringar under återställning." + +#: utils/misc/guc.c:2197 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "Sätter maximalt intervall mellan statusrapporter till skickande server från WAL-mottagaren." + +#: utils/misc/guc.c:2208 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "Sätter maximal väntetid för att ta emot data från skickande server." + +#: utils/misc/guc.c:2219 +msgid "Sets the maximum number of concurrent connections." +msgstr "Sätter maximalt antal samtidiga anslutningar." + +#: utils/misc/guc.c:2230 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "Sätter antalet anslutningsslottar som reserverats för superanvändare." + +#: utils/misc/guc.c:2244 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Sätter antalet delade minnesbuffrar som används av servern." + +#: utils/misc/guc.c:2255 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Sätter maximalt antal temporära buffertar som används per session." + +#: utils/misc/guc.c:2266 +msgid "Sets the TCP port the server listens on." +msgstr "Sätter TCP-porten som servern lyssnar på." + +#: utils/misc/guc.c:2276 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Sätter accessrättigheter för Unix-domainuttag (socket)." + +#: utils/misc/guc.c:2277 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unixdomänuttag (socket) använder unix vanliga filsystemsrättigheter. Parametervärdet förväntas vara en numerisk rättighetsangivelse så som accepteras av systemanropen chmod och umask. (För att använda det vanliga oktala formatet så måste numret börja med 0 (noll).)" + +#: utils/misc/guc.c:2291 +msgid "Sets the file permissions for log files." +msgstr "Sätter filrättigheter för loggfiler." + +#: utils/misc/guc.c:2292 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Parametervärdet förväntas vara en numerisk rättighetsangivelse så som accepteras av systemanropen chmod och umask. (För att använda det vanliga oktala formatet så måste numret börja med 0 (noll).)" + +#: utils/misc/guc.c:2306 +msgid "Mode of the data directory." +msgstr "Läge för datakatalog." + +#: utils/misc/guc.c:2307 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Parametervärdet är en numerisk rättighetsangivelse så som accepteras av systemanropen chmod och umask. (För att använda det vanliga oktala formatet så måste numret börja med 0 (noll).)" + +#: utils/misc/guc.c:2320 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Sätter maximalt minne som används för frågors arbetsyta." + +#: utils/misc/guc.c:2321 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "Så här mycket minne kan användas av varje intern sorteringsoperation resp. hash-tabell innan temporära filer på disk börjar användas." + +#: utils/misc/guc.c:2333 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Sätter det maximala minnet som får användas för underhållsoperationer." + +#: utils/misc/guc.c:2334 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Detta inkluderar operationer som VACUUM och CREATE INDEX." + +#: utils/misc/guc.c:2344 +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "Sätter det maximala minnet som får användas för logisk avkodning." + +#: utils/misc/guc.c:2345 +msgid "This much memory can be used by each internal reorder buffer before spilling to disk." +msgstr "Så här mycket minne kan användas av varje intern omsorteringsbuffer innan data spills till disk." + +#: utils/misc/guc.c:2361 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Sätter det maximala stackdjupet, i kilobyte." + +#: utils/misc/guc.c:2372 +msgid "Limits the total size of all temporary files used by each process." +msgstr "Begränsar den totala storleken för alla temporära filer som används i en process." + +#: utils/misc/guc.c:2373 +msgid "-1 means no limit." +msgstr "-1 betyder ingen gräns." + +#: utils/misc/guc.c:2383 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Vacuum-kostnad för en sida som hittas i buffer-cache:n." + +#: utils/misc/guc.c:2393 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Vacuum-kostnad för en sida som inte hittas i buffer-cache:n." + +#: utils/misc/guc.c:2403 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Vacuum-kostnad för sidor som smutsats ner vid vacuum." + +#: utils/misc/guc.c:2413 +msgid "Vacuum cost amount available before napping." +msgstr "Vacuum-kostnad kvar innan pausande." + +#: utils/misc/guc.c:2423 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "Vacuum-kostnad kvar innan pausande, för autovacuum." + +#: utils/misc/guc.c:2433 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "Sätter det maximala antalet filer som en serverprocess kan ha öppna på en gång." + +#: utils/misc/guc.c:2446 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Sätter det maximala antalet förberedda transaktioner man får ha på en gång." + +#: utils/misc/guc.c:2457 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Sätter minsta tabell-OID för spårning av lås." + +#: utils/misc/guc.c:2458 +msgid "Is used to avoid output on system tables." +msgstr "Används för att undvika utdata för systemtabeller." + +#: utils/misc/guc.c:2467 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "Sätter OID för tabellen med ovillkorlig låsspårning." + +#: utils/misc/guc.c:2479 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Sätter den maximala tiden som en sats får köra." + +#: utils/misc/guc.c:2480 utils/misc/guc.c:2491 utils/misc/guc.c:2502 +msgid "A value of 0 turns off the timeout." +msgstr "Värdet 0 stänger av timeout:en." + +#: utils/misc/guc.c:2490 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Sätter den maximala tiden som man får vänta på ett lås." + +#: utils/misc/guc.c:2501 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "Sätter den maximala tiden som en transaktion tillås vara \"idle\"." + +#: utils/misc/guc.c:2512 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "Minimal ålder där VACUUM skall frysa en tabellrad." + +#: utils/misc/guc.c:2522 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "Ålder där VACUUM skall skanna hela tabellen för att frysa tupler." + +#: utils/misc/guc.c:2532 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "Minsta ålder där VACUUM skall frysa en MultiXactId i en tabellrad." + +#: utils/misc/guc.c:2542 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "Multixact-ålder där VACUUM skall skanna hela tabellen för att frysa tupler." + +#: utils/misc/guc.c:2552 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "Antalet transaktioner som VACUUM och HOT-städning skall fördröjas (om någon)." + +#: utils/misc/guc.c:2565 +msgid "Sets the maximum number of locks per transaction." +msgstr "Sätter det maximala antalet lås per transaktion." + +#: utils/misc/guc.c:2566 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Den delade låstabellen har storlek efter antagandet att maximalt max_locks_per_transaction * max_connections olika objekt kommer behöva låsas vid en tidpunkt." + +#: utils/misc/guc.c:2577 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Sätter det maximala antalet predikatlås per transaktion." + +#: utils/misc/guc.c:2578 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Den delade predikatlåstabellen har storlek efter antagandet att maximalt max_pred_locks_per_transaction * max_connections olika objekt kommer behöva låsas vid en tidpunkt." + +#: utils/misc/guc.c:2589 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Sätter det maximala antalet predikatlåsta sidor och tupler per relation." + +#: utils/misc/guc.c:2590 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Om fler än detta totala antal sidor och tupler för samma relation är låsta av en anslutning så ersätts dessa lås med ett lås på relationen." + +#: utils/misc/guc.c:2600 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Sätter det maximala antalet predikatlåsta tupler per sida." + +#: utils/misc/guc.c:2601 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Om fler än detta antal tupler på samma sida är låsta av en anslutning så ersätts dessa lås med ett lås på sidan." + +#: utils/misc/guc.c:2611 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "Sätter maximalt tillåten tid att slutföra klientautentisering." + +#: utils/misc/guc.c:2623 +msgid "Waits N seconds on connection startup before authentication." +msgstr "Väntar N sekunder efter anslutning innan autentisering." + +#: utils/misc/guc.c:2634 +msgid "Sets the size of WAL files held for standby servers." +msgstr "Sätter storlek på WAL-filer som sparas för standby-servrar." + +#: utils/misc/guc.c:2645 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "Sätter maximal storlek som WAL kan krympas till." + +#: utils/misc/guc.c:2657 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Sätter WAL-storlek som utlöser en checkpoint." + +#: utils/misc/guc.c:2669 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "Sätter maximal tid mellan två automatiska WAL-checkpoint:er." + +#: utils/misc/guc.c:2680 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "Slår på varning om checkpoint-segment fylls oftare än det här." + +#: utils/misc/guc.c:2682 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "Skriv ett meddelande i serverloggen om checkpoint:er som orsakas av fulla checkpoint-segmentfiler händer oftare än detta antal sekunder. Noll stänger av varningen." + +#: utils/misc/guc.c:2694 utils/misc/guc.c:2910 utils/misc/guc.c:2957 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "Antal sidor varefter tidigare skrivningar flush:as till disk." + +#: utils/misc/guc.c:2705 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "Sätter antal buffrar för disksidor i delat minne för WAL." + +#: utils/misc/guc.c:2716 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "Tid mellan WAL-flush:ar utförda i WAL-skrivaren." + +#: utils/misc/guc.c:2727 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "Mängden WAL utskrivna av WAL-skrivaren som utlöser en flush." + +#: utils/misc/guc.c:2738 +msgid "Size of new file to fsync instead of writing WAL." +msgstr "Storlek på ny fil som skall fsync:as istället för att skriva till WAL." + +#: utils/misc/guc.c:2749 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "Sätter maximalt antal samtidigt körande WAL-sändarprocesser." + +#: utils/misc/guc.c:2760 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Sätter maximalt antal samtidigt definierade replikeringsslottar." + +#: utils/misc/guc.c:2770 +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "Sätter maximalt WAL-storlek som kan reserveras av replikeringsslottar." + +#: utils/misc/guc.c:2771 +msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "Replikeringsslottar kommer markeras som misslyckade och segment kommer släppas till borttagning eller återanvändning när så här mycket plats används av WAL på disk." + +#: utils/misc/guc.c:2783 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "Sätter maximal tid att vänta på WAL-replikering." + +#: utils/misc/guc.c:2794 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "Sätter fördröjning i mikrosekunder mellan transaktions-commit ochj flush:ning av WAL till disk." + +#: utils/misc/guc.c:2806 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "Sätter minsta antal samtida öppna transaktioner innan vi utför en commit_delay." + +#: utils/misc/guc.c:2817 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Sätter antal siffror som visas för flyttalsvärden." + +#: utils/misc/guc.c:2818 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "Detta påverkar real, double precision och geometriska datatyper. Noll eller negativt parametervärde läggs till standard antal siffror (FLT_DIG eller DBL_DIG respektive). Ett värde större än noll väljer ett exakt utmatningsläge." + +#: utils/misc/guc.c:2830 +msgid "Sets the minimum execution time above which a sample of statements will be logged. Sampling is determined by log_statement_sample_rate." +msgstr "Sätter minimal körtid där ett urval av långsammare satser kommer loggas. Urvalet bestämms av log_statement_sample_rate." + +#: utils/misc/guc.c:2833 +msgid "Zero logs a sample of all queries. -1 turns this feature off." +msgstr "Noll loggar ett urval som inkluderar alla frågor. -1 stänger av denna funktion." + +#: utils/misc/guc.c:2843 +msgid "Sets the minimum execution time above which all statements will be logged." +msgstr "Sätter minimal körtid där alla långsammare satser kommer loggas." + +#: utils/misc/guc.c:2845 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "Noll skriver ut alla frågor. -1 stänger av denna finess." + +#: utils/misc/guc.c:2855 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "Sätter minimal körtid där långsammare autovacuum-operationer kommer loggas." + +#: utils/misc/guc.c:2857 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "Noll skriver ut alla operationer. -1 stänger av autovacuum." + +#: utils/misc/guc.c:2867 +msgid "When logging statements, limit logged parameter values to first N bytes." +msgstr "När satser loggas så begränsa loggade parametervärden till de första N byten." + +#: utils/misc/guc.c:2868 utils/misc/guc.c:2879 +msgid "-1 to print values in full." +msgstr "-1 för att skriva ut hela värden." + +#: utils/misc/guc.c:2878 +msgid "When reporting an error, limit logged parameter values to first N bytes." +msgstr "Vid rapportering av fel så begränsa loggade parametervärden till de första N byten." + +#: utils/misc/guc.c:2889 +msgid "Background writer sleep time between rounds." +msgstr "Bakgrundsskrivarens sleep-tid mellan körningar." + +#: utils/misc/guc.c:2900 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "Bakgrundsskrivarens maximala antal LRU-sidor som flush:as per omgång." + +#: utils/misc/guc.c:2923 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "Antal samtidiga förfrågningar som kan effektivt kan hanteras av disksystemet." + +#: utils/misc/guc.c:2924 +msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +msgstr "För RAID-array:er så borde det vara ungerfär så många som antalet spindlar i array:en." + +#: utils/misc/guc.c:2941 +msgid "A variant of effective_io_concurrency that is used for maintenance work." +msgstr "En variant av effective_io_concurrency som används för underhållsarbete." + +#: utils/misc/guc.c:2970 +msgid "Maximum number of concurrent worker processes." +msgstr "Maximalt antal samtidiga arbetsprocesser." + +#: utils/misc/guc.c:2982 +msgid "Maximum number of logical replication worker processes." +msgstr "Maximalt antal arbetsprocesser för logisk replikering." + +#: utils/misc/guc.c:2994 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Maximalt antal tabellsynkroniseringsarbetare per prenumeration." + +#: utils/misc/guc.c:3004 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "Automatisk loggfilsrotering kommer ske efter N minuter." + +#: utils/misc/guc.c:3015 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "Automatisk loggfilsrotering kommer ske efter N kilobyte." + +#: utils/misc/guc.c:3026 +msgid "Shows the maximum number of function arguments." +msgstr "Visar maximalt antal funktionsargument." + +#: utils/misc/guc.c:3037 +msgid "Shows the maximum number of index keys." +msgstr "Visar maximalt antal indexnycklar." + +#: utils/misc/guc.c:3048 +msgid "Shows the maximum identifier length." +msgstr "Visar den maximala identifierarlängden." + +#: utils/misc/guc.c:3059 +msgid "Shows the size of a disk block." +msgstr "Visar storleken på ett diskblock." + +#: utils/misc/guc.c:3070 +msgid "Shows the number of pages per disk file." +msgstr "Visar antal sidor per diskfil." + +#: utils/misc/guc.c:3081 +msgid "Shows the block size in the write ahead log." +msgstr "Visar blockstorleken i the write-ahead-loggen." + +#: utils/misc/guc.c:3092 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "Sätter väntetiden innan databasen försöker ta emot WAL efter ett misslyckat försök." + +#: utils/misc/guc.c:3104 +msgid "Shows the size of write ahead log segments." +msgstr "Visar storleken på write-ahead-log-segment." + +#: utils/misc/guc.c:3117 +msgid "Time to sleep between autovacuum runs." +msgstr "Tid att sova mellan körningar av autovacuum." + +#: utils/misc/guc.c:3127 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Minst antal tupel-uppdateringar eller raderingar innan vacuum." + +#: utils/misc/guc.c:3136 +msgid "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums." +msgstr "Minsta antal tupel-insert innnan vacuum eller -1 för att stänga av insert-vacuum." + +#: utils/misc/guc.c:3145 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "Minsta antal tupel-insert, -update eller -delete innan analyze." + +#: utils/misc/guc.c:3155 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "Ålder då autovacuum körs på en tabell för att förhindra wrapaound på transaktions-ID." + +#: utils/misc/guc.c:3166 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "Ålder på multixact då autovacuum körs på en tabell för att förhindra wrapaound på multixact." + +#: utils/misc/guc.c:3176 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "Sätter maximalt antal samtidigt körande arbetsprocesser för autovacuum." + +#: utils/misc/guc.c:3186 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Sätter maximalt antal parallella processer per underhållsoperation." + +#: utils/misc/guc.c:3196 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Sätter maximalt antal parallella processer per exekveringsnod." + +#: utils/misc/guc.c:3207 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Sätter maximalt antal parallella arbetare som kan vara aktiva på en gång." + +#: utils/misc/guc.c:3218 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "Sätter maximalt minne som kan användas av varje arbetsprocess för autovacuum." + +#: utils/misc/guc.c:3229 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "Tid innan ett snapshot är för gammalt för att läsa sidor som ändrats efter snapshot:en tagits." + +#: utils/misc/guc.c:3230 +msgid "A value of -1 disables this feature." +msgstr "Värdet -1 stänger av denna funktion." + +#: utils/misc/guc.c:3240 +msgid "Time between issuing TCP keepalives." +msgstr "Tid mellan skickande av TCP-keepalive." + +#: utils/misc/guc.c:3241 utils/misc/guc.c:3252 utils/misc/guc.c:3376 +msgid "A value of 0 uses the system default." +msgstr "Värdet 0 anger systemets standardvärde." + +#: utils/misc/guc.c:3251 +msgid "Time between TCP keepalive retransmits." +msgstr "Tid mellan omsändning av TCP-keepalive." + +#: utils/misc/guc.c:3262 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "SSL-förhandling stöds inte längre; denna kan bara vara 0." + +#: utils/misc/guc.c:3273 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "Maximalt antal omsändningar av TCP-keepalive." + +#: utils/misc/guc.c:3274 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "Detta bestämmer antalet keepalive-omsändingar i rad som kan försvinna innan en anslutning anses vara död. Värdet 0 betyder systemstandardvärdet." + +#: utils/misc/guc.c:3285 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "Sätter maximalt tillåtna resultat för exakt sökning med GIN." + +#: utils/misc/guc.c:3296 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Sätter planerarens antagande om totala storleken på datacachen." + +#: utils/misc/guc.c:3297 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Det är totala storleken på cachen (kernelcache och delade buffertar) som användas för PostgreSQLs datafiler. Det mäts i disksidor som normalt är 8 kb styck." + +#: utils/misc/guc.c:3308 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "Sätter minsta mängd tabelldata för en parallell skanning." + +#: utils/misc/guc.c:3309 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Om planeraren beräknar att den kommer läsa för få tabellsidor för att nå denna gräns så kommer den inte försöka med en parallell skanning." + +#: utils/misc/guc.c:3319 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "Anger minimala mängden indexdata för en parallell scan." + +#: utils/misc/guc.c:3320 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Om planeraren beräknar att den kommer läsa för få indexsidor för att nå denna gräns så kommer den inte försöka med en parallell skanning." + +#: utils/misc/guc.c:3331 +msgid "Shows the server version as an integer." +msgstr "Visar serverns version som ett heltal." + +#: utils/misc/guc.c:3342 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "Logga användning av temporära filer som är större än detta antal kilobyte." + +#: utils/misc/guc.c:3343 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "Noll loggar alla filer. Standard är -1 (stänger av denna finess)." + +#: utils/misc/guc.c:3353 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "Ställer in storleken reserverad för pg_stat_activity.query, i byte." + +#: utils/misc/guc.c:3364 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "Sätter maximal storlek på väntelistan för GIN-index." + +#: utils/misc/guc.c:3375 +msgid "TCP user timeout." +msgstr "Användartimeout för TCP." + +#: utils/misc/guc.c:3395 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "Ställer in planerarens estimat av kostnaden för att hämta en disksida sekvensiellt." + +#: utils/misc/guc.c:3406 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "Ställer in planerarens estimat av kostnaden för att hämta en disksida icke-sekvensiellt." + +#: utils/misc/guc.c:3417 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "Ställer in planerarens estimat av kostnaden för att processa varje tupel (rad)." + +#: utils/misc/guc.c:3428 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "Sätter planerarens kostnadsuppskattning för att processa varje indexpost under en indexskanning." + +#: utils/misc/guc.c:3439 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "Sätter planerarens kostnadsuppskattning för att processa varje operator- eller funktions-anrop." + +#: utils/misc/guc.c:3450 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgstr "Sätter planerarens kostnadsuppskattning för att skicka varje tupel (rad) från en arbetare till huvud-backend:en. " + +#: utils/misc/guc.c:3461 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "Sätter planerarens kostnadsuppskattning för att starta upp en arbetsprocess för en parallell fråga." + +#: utils/misc/guc.c:3473 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Utför JIT-kompilering om frågan är dyrare." + +#: utils/misc/guc.c:3474 +msgid "-1 disables JIT compilation." +msgstr "-1 stänger av JIT-kompilering." + +#: utils/misc/guc.c:3484 +msgid "Optimize JITed functions if query is more expensive." +msgstr "Optimera JIT-funktioner om frågan är dyrare." + +#: utils/misc/guc.c:3485 +msgid "-1 disables optimization." +msgstr "-1 stänger av optimering." + +#: utils/misc/guc.c:3495 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Utför JIT-\"inlining\" om frågan är dyrare." + +#: utils/misc/guc.c:3496 +msgid "-1 disables inlining." +msgstr "-1 stänger av \"inlining\"" + +#: utils/misc/guc.c:3506 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "Sätter planerarens uppskattning av hur stor del av markörens rader som kommer hämtas. " + +#: utils/misc/guc.c:3518 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: selektionstryck inom populationen." + +#: utils/misc/guc.c:3529 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: slumptalsfrö för val av slumpad sökväg." + +#: utils/misc/guc.c:3540 +msgid "Multiple of work_mem to use for hash tables." +msgstr "Multipel av work_mem för att använda till hash-tabeller." + +#: utils/misc/guc.c:3551 +msgid "Multiple of the average buffer usage to free per round." +msgstr "Multipel av genomsnittlig bufferanvändning som frias per runda." + +#: utils/misc/guc.c:3561 +msgid "Sets the seed for random-number generation." +msgstr "Sätter fröet för slumptalsgeneratorn." + +#: utils/misc/guc.c:3572 +msgid "Vacuum cost delay in milliseconds." +msgstr "Städkostfördröjning i millisekunder." + +#: utils/misc/guc.c:3583 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Städkostfördröjning i millisekunder, för autovacuum." + +#: utils/misc/guc.c:3594 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "Antalet tupeluppdateringar eller borttagningar innan vacuum relativt reltuples." + +#: utils/misc/guc.c:3604 +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "Antal tupelinsättningar innan vacuum relativt reltuples." + +#: utils/misc/guc.c:3614 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "Antalet tupelinsättningar, uppdateringar eller borttagningar innan analyze relativt reltuples." + +#: utils/misc/guc.c:3624 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "Tid lagd på att flusha nedsmutsade buffrar vid checkpoint relativt checkpoint-intervallet." + +#: utils/misc/guc.c:3634 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "Antal tupelinsättningar innan indexuppstädning relativt reltuples." + +#: utils/misc/guc.c:3644 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "Bråkdel av satser som överskrider log_min_duration_sample som skall loggas." + +#: utils/misc/guc.c:3645 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "Använd ett värde mellan 0.0 (logga aldrig) och 1.0 (logga alltid)." + +#: utils/misc/guc.c:3654 +msgid "Set the fraction of transactions to log for new transactions." +msgstr "Ställer in bråkdel av transaktioner som skall loggas av nya transaktioner." + +#: utils/misc/guc.c:3655 +msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "Loggar all satser från en bråkdel av transaktionerna. Använd ett värde mellan 0.0 (logga aldrig) till 1.0 (logga all satser i alla transaktioner)." + +#: utils/misc/guc.c:3675 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "Sätter shell-kommandot som kommer anropas för att arkivera en WAL-fil." + +#: utils/misc/guc.c:3685 +msgid "Sets the shell command that will be called to retrieve an archived WAL file." +msgstr "Sätter shell-kommandot som kommer anropas för att få en arkiverad WAL-fil." + +#: utils/misc/guc.c:3695 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "Sätter shell-kommandot som kommer anropas vid varje omstartspunkt." + +#: utils/misc/guc.c:3705 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "Sätter shell-kommandot som kommer anropas en gång i slutet av en återställning." + +#: utils/misc/guc.c:3715 +msgid "Specifies the timeline to recover into." +msgstr "Anger tidslinjen att återställa till." + +#: utils/misc/guc.c:3725 +msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." +msgstr "Sätt till \"immediate\" för att avsluta återställning så snart ett konsistent tillstånd uppnås." + +#: utils/misc/guc.c:3734 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "Sätter transaktions-ID som återställning kommer gå till." + +#: utils/misc/guc.c:3743 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "Sätter tidsstämpel som återställning kommer gå till." + +#: utils/misc/guc.c:3752 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "Sätter namngiven återställningspunkt som återställning kommer gå till." + +#: utils/misc/guc.c:3761 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "Sätter LSN för write-ahead-logg-position som återställning kommer få till." + +#: utils/misc/guc.c:3771 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "Anger ett filnamn vars närvaro gör att återställning avslutas i en standby." + +#: utils/misc/guc.c:3781 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "Sätter anslutningssträng som anvönds för att ansluta till skickande server." + +#: utils/misc/guc.c:3792 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "Sätter namnet på replikeringsslotten som skall användas av den skickande servern." + +#: utils/misc/guc.c:3802 +msgid "Sets the client's character set encoding." +msgstr "Ställer in klientens teckenkodning." + +#: utils/misc/guc.c:3813 +msgid "Controls information prefixed to each log line." +msgstr "Styr information prefixat till varje loggrad." + +#: utils/misc/guc.c:3814 +msgid "If blank, no prefix is used." +msgstr "Om tom så används inget prefix." + +#: utils/misc/guc.c:3823 +msgid "Sets the time zone to use in log messages." +msgstr "Sätter tidszonen som används i loggmeddelanden." + +#: utils/misc/guc.c:3833 +msgid "Sets the display format for date and time values." +msgstr "Sätter displayformat för datum och tidvärden." + +#: utils/misc/guc.c:3834 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "Styr också tolkning av tvetydig datumindata." + +#: utils/misc/guc.c:3845 +msgid "Sets the default table access method for new tables." +msgstr "Ställer in standard tabellaccessmetod för nya tabeller." + +#: utils/misc/guc.c:3856 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "Ställer in standard tabellutrymme där tabeller och index skapas." + +#: utils/misc/guc.c:3857 +msgid "An empty string selects the database's default tablespace." +msgstr "En tom sträng väljer databasens standardtabellutrymme." + +#: utils/misc/guc.c:3867 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "Ställer in tablespace för temporära tabeller och sorteringsfiler." + +#: utils/misc/guc.c:3878 +msgid "Sets the path for dynamically loadable modules." +msgstr "Sätter sökvägen till dynamiskt laddade moduler." + +#: utils/misc/guc.c:3879 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "Om en dynamiskt laddad modul behöver öppnas och det angivna namnet inte har en katalogkomponent (dvs, namnet inte innehåller snedstreck) så kommer systemet använda denna sökväg för filen." + +#: utils/misc/guc.c:3892 +msgid "Sets the location of the Kerberos server key file." +msgstr "Ställer in platsen för Kerberos servernyckelfil." + +#: utils/misc/guc.c:3903 +msgid "Sets the Bonjour service name." +msgstr "Sätter Bonjour-tjänstens namn." + +#: utils/misc/guc.c:3915 +msgid "Shows the collation order locale." +msgstr "Visar lokal för jämförelseordning." + +#: utils/misc/guc.c:3926 +msgid "Shows the character classification and case conversion locale." +msgstr "Visar lokal för teckenklassificering samt skiftlägeskonvertering." + +#: utils/misc/guc.c:3937 +msgid "Sets the language in which messages are displayed." +msgstr "Sätter språket som meddelanden visas i." + +#: utils/misc/guc.c:3947 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Sätter lokalen för att formattera monetära belopp." + +#: utils/misc/guc.c:3957 +msgid "Sets the locale for formatting numbers." +msgstr "Ställer in lokalen för att formattera nummer." + +#: utils/misc/guc.c:3967 +msgid "Sets the locale for formatting date and time values." +msgstr "Sätter lokalen för att formattera datum och tider." + +#: utils/misc/guc.c:3977 +msgid "Lists shared libraries to preload into each backend." +msgstr "Listar delade bibliotek som skall förladdas i varje backend." + +#: utils/misc/guc.c:3988 +msgid "Lists shared libraries to preload into server." +msgstr "Listar delade bibliotek som skall förladdas i servern." + +#: utils/misc/guc.c:3999 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "Listar ej priviligerade delade bibliotek som förladdas in i varje backend." + +#: utils/misc/guc.c:4010 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "Sätter schemats sökordning för namn som inte är schema-prefixade." + +#: utils/misc/guc.c:4022 +msgid "Sets the server (database) character set encoding." +msgstr "Ställer in serverns (databasens) teckenkodning." + +#: utils/misc/guc.c:4034 +msgid "Shows the server version." +msgstr "Visar serverversionen" + +#: utils/misc/guc.c:4046 +msgid "Sets the current role." +msgstr "Ställer in den aktiva rollen." + +#: utils/misc/guc.c:4058 +msgid "Sets the session user name." +msgstr "Sätter sessionens användarnamn." + +#: utils/misc/guc.c:4069 +msgid "Sets the destination for server log output." +msgstr "Sätter serverloggens destination." + +#: utils/misc/guc.c:4070 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "Giltiga värden är kombinationer av \"stderr\", \"syslog\", \"csvlog\" och \"eventlog\", beroende på plattform." + +#: utils/misc/guc.c:4081 +msgid "Sets the destination directory for log files." +msgstr "Sätter destinationskatalogen för loggfiler." + +#: utils/misc/guc.c:4082 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "Kan anges relativt datakatalogen eller som en absolut sökväg." + +#: utils/misc/guc.c:4092 +msgid "Sets the file name pattern for log files." +msgstr "Sätter filnamnsmallen för loggfiler." + +#: utils/misc/guc.c:4103 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "Sätter programnamnet som används för att identifiera PostgreSQLs meddelanden i syslog." + +#: utils/misc/guc.c:4114 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "Sätter applikationsnamnet som används för att identifiera PostgreSQLs meddelanden i händelseloggen." + +#: utils/misc/guc.c:4125 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "Ställer in tidszon för visande och tolkande av tidsstämplar." + +#: utils/misc/guc.c:4135 +msgid "Selects a file of time zone abbreviations." +msgstr "Väljer en fil för tidszonsförkortningar." + +#: utils/misc/guc.c:4145 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Sätter ägande grupp för Unix-domainuttaget (socket)." + +#: utils/misc/guc.c:4146 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "Ägaren av uttaget (socker) är alltid användaren som startar servern." + +#: utils/misc/guc.c:4156 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Ställer in kataloger där Unix-domän-uttag (socket) kommer skapas." + +#: utils/misc/guc.c:4171 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Sätter värdnamn eller IP-adress(er) att lyssna på." + +#: utils/misc/guc.c:4186 +msgid "Sets the server's data directory." +msgstr "Ställer in serverns datakatalog." + +#: utils/misc/guc.c:4197 +msgid "Sets the server's main configuration file." +msgstr "Sätter serverns huvudkonfigurationsfil." + +#: utils/misc/guc.c:4208 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Sätter serverns \"hba\"-konfigurationsfil." + +#: utils/misc/guc.c:4219 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Sätter serverns \"ident\"-konfigurationsfil." + +#: utils/misc/guc.c:4230 +msgid "Writes the postmaster PID to the specified file." +msgstr "Skriver postmaster-PID till angiven fil." + +#: utils/misc/guc.c:4241 +msgid "Name of the SSL library." +msgstr "Namn på SSL-biblioteket." + +#: utils/misc/guc.c:4256 +msgid "Location of the SSL server certificate file." +msgstr "Plats för serverns SSL-certifikatfil." + +#: utils/misc/guc.c:4266 +msgid "Location of the SSL server private key file." +msgstr "Plats för serverns privata SSL-nyckelfil." + +#: utils/misc/guc.c:4276 +msgid "Location of the SSL certificate authority file." +msgstr "Plats för SSL-certifikats auktoritetsfil." + +#: utils/misc/guc.c:4286 +msgid "Location of the SSL certificate revocation list file." +msgstr "Plats för SSL-certifikats återkallningsfil." + +#: utils/misc/guc.c:4296 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Skriver temporära statistikfiler till angiven katalog." + +#: utils/misc/guc.c:4307 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "Antalet synkrona standby och en lista med namn på potentiellt synkrona sådana." + +#: utils/misc/guc.c:4318 +msgid "Sets default text search configuration." +msgstr "Ställer in standard textsökkonfiguration." + +#: utils/misc/guc.c:4328 +msgid "Sets the list of allowed SSL ciphers." +msgstr "Ställer in listan med tillåtna SSL-krypton." + +#: utils/misc/guc.c:4343 +msgid "Sets the curve to use for ECDH." +msgstr "Ställer in kurvan att använda för ECDH." + +#: utils/misc/guc.c:4358 +msgid "Location of the SSL DH parameters file." +msgstr "Plats för SSL DH-parameterfil." + +#: utils/misc/guc.c:4369 +msgid "Command to obtain passphrases for SSL." +msgstr "Kommando för att hämta lösenfraser för SSL." + +#: utils/misc/guc.c:4380 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "Sätter applikationsnamn som rapporteras i statistik och loggar." + +#: utils/misc/guc.c:4391 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Sätter namnet på klustret som inkluderas i processtiteln." + +#: utils/misc/guc.c:4402 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "Sätter WAL-resurshanterare som WAL-konsistenskontoller görs med." + +#: utils/misc/guc.c:4403 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "Hela sidkopior kommer loggas för alla datablock och kontrolleras mot resultatet av en WAL-uppspelning." + +#: utils/misc/guc.c:4413 +msgid "JIT provider to use." +msgstr "JIT-leverantör som används." + +#: utils/misc/guc.c:4424 +msgid "Log backtrace for errors in these functions." +msgstr "Loggar backtrace vid fel i dessa funktioner." + +#: utils/misc/guc.c:4444 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Anger hurvida \"\\'\" tillåts i sträng-literaler." + +#: utils/misc/guc.c:4454 +msgid "Sets the output format for bytea." +msgstr "Ställer in output-format för bytea." + +#: utils/misc/guc.c:4464 +msgid "Sets the message levels that are sent to the client." +msgstr "Ställer in meddelandenivåer som skickas till klienten." + +#: utils/misc/guc.c:4465 utils/misc/guc.c:4530 utils/misc/guc.c:4541 +#: utils/misc/guc.c:4617 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "Varje nivå inkluderar de efterföljande nivåerna. Ju senare nivå destå färre meddlanden skickas." + +#: utils/misc/guc.c:4475 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "Slår på planerarens användning av integritetsvillkor för att optimera frågor." + +#: utils/misc/guc.c:4476 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "Tabellskanningar kommer hoppas över om dess integritetsvillkor garanterar att inga rader komma matchas av frågan." + +#: utils/misc/guc.c:4487 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Ställer in isolationsnivån för nya transaktioner." + +#: utils/misc/guc.c:4497 +msgid "Sets the current transaction's isolation level." +msgstr "Sätter den aktuella transaktionsisolationsnivån." + +#: utils/misc/guc.c:4508 +msgid "Sets the display format for interval values." +msgstr "Ställer in visningsformat för intervallvärden." + +#: utils/misc/guc.c:4519 +msgid "Sets the verbosity of logged messages." +msgstr "Ställer in pratighet för loggade meddelanden." + +#: utils/misc/guc.c:4529 +msgid "Sets the message levels that are logged." +msgstr "Ställer in meddelandenivåer som loggas." + +#: utils/misc/guc.c:4540 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "Gör att alla satser som genererar fel vid eller över denna nivå kommer loggas." + +#: utils/misc/guc.c:4551 +msgid "Sets the type of statements logged." +msgstr "Ställer in vilken sorts satser som loggas." + +#: utils/misc/guc.c:4561 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "Ställer in syslog-\"facility\" som används när syslog är påslagen." + +#: utils/misc/guc.c:4576 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "Sätter sessionens beteende för utlösare och omskrivningsregler." + +#: utils/misc/guc.c:4586 +msgid "Sets the current transaction's synchronization level." +msgstr "Ställer in den nuvarande transaktionens synkroniseringsnivå." + +#: utils/misc/guc.c:4596 +msgid "Allows archiving of WAL files using archive_command." +msgstr "Tillåter arkivering av WAL-filer med hjälp av archive_command." + +#: utils/misc/guc.c:4606 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "Sätter handling som skall utföras när återställningsmål nås." + +#: utils/misc/guc.c:4616 +msgid "Enables logging of recovery-related debugging information." +msgstr "Slår på loggning av återställningsrelaterad debug-information." + +#: utils/misc/guc.c:4632 +msgid "Collects function-level statistics on database activity." +msgstr "Samlar in statistik på funktionsnivå över databasaktivitet." + +#: utils/misc/guc.c:4642 +msgid "Set the level of information written to the WAL." +msgstr "Ställer in mängden information som skrivs till WAL." + +#: utils/misc/guc.c:4652 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Väljer implementation som används för dynamiskt delat minne." + +#: utils/misc/guc.c:4662 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "Väljer implementation för delat minne som används för det delade minnets huvudregionen." + +#: utils/misc/guc.c:4672 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "Väljer metod för att tvinga WAL-uppdateringar till disk." + +#: utils/misc/guc.c:4682 +msgid "Sets how binary values are to be encoded in XML." +msgstr "Ställer in hur binära värden kodas i XML." + +#: utils/misc/guc.c:4692 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "Anger hurvida XML-data vid implicit parsning och serialiseringsoperationer ses som dokument eller innehållsfragment." + +#: utils/misc/guc.c:4703 +msgid "Use of huge pages on Linux or Windows." +msgstr "Använd stora sidor på Linux resp. Windows." + +#: utils/misc/guc.c:4713 +msgid "Forces use of parallel query facilities." +msgstr "Tvingar användning av parallella frågefinesser." + +#: utils/misc/guc.c:4714 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "Om det är möjligt så kör fråga med en parallell arbetare och med parallella begränsningar." + +#: utils/misc/guc.c:4724 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "Väljer algoritm för att kryptera lösenord." + +#: utils/misc/guc.c:4734 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Styr planerarens användning av egendefinierad eller generell plan." + +#: utils/misc/guc.c:4735 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "Preparerade satser kan ha egendefinierade och generella planer och planeraren kommer försöka välja den som är bäst. Detta kan anges att övertrumfa standardbeteendet." + +#: utils/misc/guc.c:4747 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "Sätter minsta SSL/TLS-protokollversion som skall användas." + +#: utils/misc/guc.c:4759 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "Sätter högsta SSL/TLS-protokollversion som skall användas." + +#: utils/misc/guc.c:5562 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: kunde inte komma åt katalogen \"%s\": %s\n" + +#: utils/misc/guc.c:5567 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "Kör initdb eller pg_basebackup för att initiera en PostgreSQL-datakatalog.\n" + +#: utils/misc/guc.c:5587 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var servens konfigurationsfil är.\n" +"Du måste ange flaggan --config-file eller -D alternativt sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:5606 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: har inte åtkomst till serverns konfigureringsfil \"%s\": %s\n" + +#: utils/misc/guc.c:5632 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var databasens systemdata är.\n" +"Det kan anges med \"data_directory\" i \"%s\" eller med flaggan -D alternativt genom att sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:5680 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var \"hba\"-konfigurationsfilen är.\n" +"Detta kan anges som \"hba_file\" i \"%s\" eller med flaggan -D alternativt genom att sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:5703 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var \"ident\"-konfigurationsfilen är.\n" +"Detta kan anges som \"ident_file\" i \"%s\" eller med flaggan -D alternativt genom att sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:6545 +msgid "Value exceeds integer range." +msgstr "Värde överskriver heltalsintervall." + +#: utils/misc/guc.c:6781 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s är utanför giltigt intervall för parameter \"%s\" (%d .. %d)" + +#: utils/misc/guc.c:6817 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s är utanför giltigt intervall för parameter \"%s\" (%g .. %g)" + +#: utils/misc/guc.c:6973 utils/misc/guc.c:8368 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "kan inte sätta parametrar under en parallell operation" + +#: utils/misc/guc.c:6980 utils/misc/guc.c:7760 utils/misc/guc.c:7813 +#: utils/misc/guc.c:7864 utils/misc/guc.c:8197 utils/misc/guc.c:8964 +#: utils/misc/guc.c:9226 utils/misc/guc.c:10892 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "okänd konfigurationsparameter \"%s\"" + +#: utils/misc/guc.c:6995 utils/misc/guc.c:8209 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "parameter \"%s\" kan inte ändras" + +#: utils/misc/guc.c:7028 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "parameter \"%s\" kan inte ändras nu" + +#: utils/misc/guc.c:7046 utils/misc/guc.c:7093 utils/misc/guc.c:10908 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "rättighet saknas för att sätta parameter \"%s\"" + +#: utils/misc/guc.c:7083 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "parameter \"%s\" kan inte ändras efter uppkopplingen startats" + +#: utils/misc/guc.c:7131 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "kan inte sätta parameter \"%s\" inom en security-definer-funktion" + +#: utils/misc/guc.c:7768 utils/misc/guc.c:7818 utils/misc/guc.c:9233 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "måste vara superanvändare eller medlem i pg_read_all_settings för att undersöka \"%s\"" + +#: utils/misc/guc.c:7909 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s tar bara ett argument" + +#: utils/misc/guc.c:8157 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "måste vara superanvändare för att köra kommandot ALTER SYSTEM" + +#: utils/misc/guc.c:8242 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "parametervärde till ALTER SYSTEM kan inte innehålla nyradstecken" + +#: utils/misc/guc.c:8287 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "kunde inte parsa innehållet i fil \"%s\"" + +#: utils/misc/guc.c:8444 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT är inte implementerat ännu" + +#: utils/misc/guc.c:8528 +#, c-format +msgid "SET requires parameter name" +msgstr "SET kräver ett parameternamn" + +#: utils/misc/guc.c:8661 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "försök att omdefiniera parameter \"%s\"" + +#: utils/misc/guc.c:10454 +#, c-format +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "vid sättande av parameter \"%s\" till \"%s\"" + +#: utils/misc/guc.c:10522 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "parameter \"%s\" kunde inte sättas" + +#: utils/misc/guc.c:10612 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "kunde inte tolka inställningen för parameter \"%s\"" + +#: utils/misc/guc.c:10970 utils/misc/guc.c:11004 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "ogiltigt värde för parameter \"%s\": %d" + +#: utils/misc/guc.c:11038 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "ogiltigt värde för parameter \"%s\": %g" + +#: utils/misc/guc.c:11308 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "\"temp_buffers\" kan inte ändras efter att man använt temporära tabeller i sessionen." + +#: utils/misc/guc.c:11320 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour stöds inte av detta bygge" + +#: utils/misc/guc.c:11333 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL stöds inte av detta bygge" + +#: utils/misc/guc.c:11345 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "Kan inte slå på parameter när \"log_statement_stats\" är satt." + +#: utils/misc/guc.c:11357 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "Kan inte slå på \"log_statement_stats\" när \"log_parser_stats\", \"log_planner_stats\" eller \"log_executor_stats\" är satta." + +#: utils/misc/guc.c:11587 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "effective_io_concurrency måste sättas till 0 på plattformar som saknar posix_fadvise()." + +#: utils/misc/guc.c:11600 +#, c-format +msgid "maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "maintenance_io_concurrency måste sättas till 0 på plattformar som saknar posix_fadvise()." + +#: utils/misc/guc.c:11716 +#, c-format +msgid "invalid character" +msgstr "ogiltigt tecken" + +#: utils/misc/guc.c:11776 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline är inte ett giltigt nummer." + +#: utils/misc/guc.c:11816 +#, c-format +msgid "multiple recovery targets specified" +msgstr "multipla återställningsmål angivna" + +#: utils/misc/guc.c:11817 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr "Som mest en av recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time och recovery_target_xid kan sättas." + +#: utils/misc/guc.c:11825 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "Det enda tillåtna värdet är \"immediate\"." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "internt fel: okänd parametertyp\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "fråge-angiven typ för retur-tupel och funktions returtyp är inte kompatibla" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "beräknad CRC-checksumma matchar inte värdet som är lagrat i fil" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: användare: %d.%02d s, system: %d.%02d s, förflutit: %d.%02d s" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "frågan påverkas av radsäkerhetspolicyn för tabell \"%s\"" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "För att slå av policyn för tabellens ägare, använd ALTER TABLE NO FORCE ROW LEVEL SECURITY." + +#: utils/misc/timeout.c:395 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "kan inte lägga till fler timeoutskäl" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "tidszonförkortningen \"%s\" är för lång (max %d tecken) i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "tidszonoffset %d är otanför giltigt intervall i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "tidszonförkortning saknas i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "tidszonoffset saknas i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "felaktigt nummer för tidszonsoffset i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "felaktig syntax i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "tidszonförkortningen \"%s\" är definierad flera gånger" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "Post i tidszonfilen \"%s\", rad %d, står i konflikt med post i filen \"%s\", rad %d." + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "ogiltigt tidszonfilnamn: \"%s\"" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "tidszonfilens rekursiva maxtak överskridet i filen \"%s\"" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "kunde inte läsa tidszonfil \"%s\": %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "raden är för lång i tidszonfil \"%s\", rad %d" + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "@INCLUDE utan filnamn i tidszonfil \"%s\", rad %d" + +#: utils/mmgr/aset.c:476 utils/mmgr/generation.c:234 utils/mmgr/slab.c:236 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Misslyckades vid skapande av minneskontext \"%s\"." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "kunde inte ansluta till dynamisk delad area" + +#: utils/mmgr/mcxt.c:822 utils/mmgr/mcxt.c:858 utils/mmgr/mcxt.c:896 +#: utils/mmgr/mcxt.c:934 utils/mmgr/mcxt.c:970 utils/mmgr/mcxt.c:1001 +#: utils/mmgr/mcxt.c:1037 utils/mmgr/mcxt.c:1089 utils/mmgr/mcxt.c:1124 +#: utils/mmgr/mcxt.c:1159 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Misslyckades med förfrågan av storlek %zu i minneskontext \"%s\"." + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "markör \"%s\" finns redan" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "stänger existerande markör \"%s\"" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "portal \"%s\" kan inte köras" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "kan inte ta bort fastsatt portal \"%s\"" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "kan inte ta bort aktiv portal \"%s\"" + +#: utils/mmgr/portalmem.c:731 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "kan inte göra PREPARE på en transaktion som skapat en markör med WITH HOLD" + +#: utils/mmgr/portalmem.c:1270 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "kan inte utföra transaktionskommandon i en markörloop som inte är read-only" + +#: utils/sort/logtape.c:266 utils/sort/logtape.c:289 +#, c-format +msgid "could not seek to block %ld of temporary file" +msgstr "kunde inte söka (seek) till block %ld i temporärfil" + +#: utils/sort/logtape.c:295 +#, c-format +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "kunde inte läsa block %ld i temporärfil: läste bara %zu av %zu byte" + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 +#: utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 +#: utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "kunde inte läsa från delad temporär lagringsfil för tupler" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "oväntad chunk i delad temporär lagringsfil för tupler" + +#: utils/sort/sharedtuplestore.c:569 +#, c-format +msgid "could not seek to block %u in shared tuplestore temporary file" +msgstr "kunde inte söka (seek) till block %u i delad temporär lagringsfil för tupler" + +#: utils/sort/sharedtuplestore.c:576 +#, c-format +msgid "could not read from shared tuplestore temporary file: read only %zu of %zu bytes" +msgstr "kunde inte läsa från delad temporär lagringsfil för tupler: läste bara %zu av %zu byte" + +#: utils/sort/tuplesort.c:3140 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "kan inte ha mer än %d körningar för en extern sortering" + +#: utils/sort/tuplesort.c:4221 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "kunde inte skapa unikt index \"%s\"" + +#: utils/sort/tuplesort.c:4223 +#, c-format +msgid "Key %s is duplicated." +msgstr "Nyckeln %s är duplicerad." + +#: utils/sort/tuplesort.c:4224 +#, c-format +msgid "Duplicate keys exist." +msgstr "Duplicerade nycklar existerar." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "kunde inte söka i temporär lagringsfil för tupler" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 +#: utils/sort/tuplestore.c:1548 +#, c-format +msgid "could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "kunde inte läsa från temporär lagringsfil för tupler: läste bara %zu av %zu byte" + +#: utils/time/snapmgr.c:624 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "Källtransaktionen kör inte längre." + +#: utils/time/snapmgr.c:1232 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "kan inte exportera ett snapshot från en subtransaktion" + +#: utils/time/snapmgr.c:1391 utils/time/snapmgr.c:1396 +#: utils/time/snapmgr.c:1401 utils/time/snapmgr.c:1416 +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1426 +#: utils/time/snapmgr.c:1441 utils/time/snapmgr.c:1446 +#: utils/time/snapmgr.c:1451 utils/time/snapmgr.c:1553 +#: utils/time/snapmgr.c:1569 utils/time/snapmgr.c:1594 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "ogiltig snapshot-data i fil \"%s\"" + +#: utils/time/snapmgr.c:1488 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "SET TRANSACTION SNAPSHOT måste anropas innan någon fråga" + +#: utils/time/snapmgr.c:1497 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "en snapshot-importerande transaktion måste ha isoleringsnivå SERIALIZABLE eller REPEATABLE READ" + +#: utils/time/snapmgr.c:1506 utils/time/snapmgr.c:1515 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "ogiltig snapshot-identifierare: \"%s\"" + +#: utils/time/snapmgr.c:1607 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "en serialiserbar transaktion kan inte importera ett snapshot från en icke-serialiserbar transaktion" + +#: utils/time/snapmgr.c:1611 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "en serialiserbar transaktion som inte är read-only kan inte importera en snapshot från en read-only-transaktion." + +#: utils/time/snapmgr.c:1626 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "kan inte importera en snapshot från en annan databas" + +#~ msgid "starting parallel vacuum worker for %s" +#~ msgstr "startar parallell vacuum-arbetsprocess för %s" + +#~ msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +#~ msgstr "kvarlämnad platshållartuple hittad i BRIN-index \"%s\", raderar" + +#~ msgid "EXPLAIN option BUFFERS requires ANALYZE" +#~ msgstr "EXPLAIN-flagga BUFFERS kräver ANALYZE" + +#~ msgid "could not write to file \"%s\" : %m" +#~ msgstr "kunde inte skriva till fil \"%s\" : %m" + +#~ msgid "Causes the planner to avoid hashed aggregation plans that are expected to use the disk." +#~ msgstr "Gör så att planeraren unviker planer med hash-aggregering som förväntas använda disk." + +#~ msgid "cannot specify both FULL and PARALLEL options" +#~ msgstr "kan inte ange både flaggan FULL och PARALLEL" + +#~ msgid "could not load wldap32.dll" +#~ msgstr "kunde inte ladda wldap32.dll" + +#~ msgid "could not load advapi32.dll: error code %lu" +#~ msgstr "kunde inte ladda advapi32.dll: felkod %lu" + +#~ msgid "cannot advance replication slot that has not previously reserved WAL" +#~ msgstr "kan inte flytta fram replikeringsslot som inte en tidigare reserverad WAL" + +#~ msgid "could not write to tuplestore temporary file: %m" +#~ msgstr "kunde inte skriva till temporär lagringsfil för tupler: %m" + +#~ msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +#~ msgstr "När ett lösenord anges i CREATE USER eller ALTER USER utan man skrivit varken ENCRYPTED eller UNENCRYPTED så bestämmer denna parameter om lösenordet kommer krypteras." + +#~ msgid "Encrypt passwords." +#~ msgstr "Kryptera lösenord." + +#~ msgid "Enables the planner's use of hashed aggregation plans for groupingsets when the total size of the hash tables is expected to exceed work_mem." +#~ msgstr "Aktiverar planerarens användning av planer med hash-aggregering för grupperingsmängder när totala storleken på hash-tabellerna förväntas överstiga work_mem." + +#~ msgid "could not write to temporary file: %m" +#~ msgstr "kunde inte skriva till temporär fil: %m" + +#~ msgid "could not write to hash-join temporary file: %m" +#~ msgstr "kunde inte skriva till hash-join-temporärfil: %m" + +#~ msgid "could not write block %ld of temporary file: %m" +#~ msgstr "kunde inte skriva block %ld i temporär fil: %m" + +#~ msgid "could not restore file \"%s\" from archive" +#~ msgstr "kunde inte återställa fil \"%s\" från arkiv" + +#~ msgid "restore_command failed due to the signal: %s" +#~ msgstr "restore_command misslyckades på grund av signal: %s" + +#~ msgid "could not open file \"%s\" restored from archive: %m" +#~ msgstr "kunde inte öppna fil \"%s\" återställd från arkiv: %m" + +#~ msgid "unexpected file size for \"%s\": %lu instead of %lu" +#~ msgstr "oväntad filstorlek på \"%s\": %lu istället för %lu" + +#~ msgid "could not use restore_command with %%r alias" +#~ msgstr "kunde inte använda restore_command med %%r-alias" + +#~ msgid "insufficient columns in %s constraint definition" +#~ msgstr "otillräckligt med kolumner i villkorsdefinitionen %s" diff --git a/src/backend/po/uk.po b/src/backend/po/uk.po new file mode 100644 index 000000000000..48f9d1f3f8ed --- /dev/null +++ b/src/backend/po/uk.po @@ -0,0 +1,27348 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:10+0000\n" +"PO-Revision-Date: 2020-09-22 13:45\n" +"Last-Translator: \n" +"Language-Team: Ukrainian\n" +"Language: uk_UA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/postgres.pot\n" +"X-Crowdin-File-ID: 524\n" + +#: ../common/config_info.c:134 ../common/config_info.c:142 +#: ../common/config_info.c:150 ../common/config_info.c:158 +#: ../common/config_info.c:166 ../common/config_info.c:174 +#: ../common/config_info.c:182 ../common/config_info.c:190 +msgid "not recorded" +msgstr "не записано" + +#: ../common/controldata_utils.c:68 ../common/controldata_utils.c:73 +#: commands/copy.c:3495 commands/extension.c:3436 utils/adt/genfile.c:125 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не вдалося відкрити файл \"%s\" для читання: %m" + +#: ../common/controldata_utils.c:86 ../common/controldata_utils.c:89 +#: access/transam/timeline.c:143 access/transam/timeline.c:362 +#: access/transam/twophase.c:1276 access/transam/xlog.c:3503 +#: access/transam/xlog.c:4728 access/transam/xlog.c:11121 +#: access/transam/xlog.c:11134 access/transam/xlog.c:11587 +#: access/transam/xlog.c:11667 access/transam/xlog.c:11706 +#: access/transam/xlog.c:11749 access/transam/xlogfuncs.c:662 +#: access/transam/xlogfuncs.c:681 commands/extension.c:3446 libpq/hba.c:499 +#: replication/logical/origin.c:717 replication/logical/origin.c:753 +#: replication/logical/reorderbuffer.c:3599 +#: replication/logical/snapbuild.c:1741 replication/logical/snapbuild.c:1783 +#: replication/logical/snapbuild.c:1811 replication/logical/snapbuild.c:1838 +#: replication/slot.c:1622 replication/slot.c:1663 replication/walsender.c:543 +#: storage/file/buffile.c:441 storage/file/copydir.c:195 +#: utils/adt/genfile.c:200 utils/adt/misc.c:763 utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не вдалося прочитати файл \"%s\": %m" + +#: ../common/controldata_utils.c:97 ../common/controldata_utils.c:101 +#: access/transam/twophase.c:1279 access/transam/xlog.c:3508 +#: access/transam/xlog.c:4733 replication/logical/origin.c:722 +#: replication/logical/origin.c:761 replication/logical/snapbuild.c:1746 +#: replication/logical/snapbuild.c:1788 replication/logical/snapbuild.c:1816 +#: replication/logical/snapbuild.c:1843 replication/slot.c:1626 +#: replication/slot.c:1667 replication/walsender.c:548 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не вдалося прочитати файл \"%s\": прочитано %d з %zu" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:117 +#: ../common/controldata_utils.c:256 ../common/controldata_utils.c:259 +#: access/heap/rewriteheap.c:1181 access/heap/rewriteheap.c:1284 +#: access/transam/timeline.c:392 access/transam/timeline.c:438 +#: access/transam/timeline.c:516 access/transam/twophase.c:1288 +#: access/transam/twophase.c:1676 access/transam/xlog.c:3375 +#: access/transam/xlog.c:3543 access/transam/xlog.c:3548 +#: access/transam/xlog.c:3876 access/transam/xlog.c:4698 +#: access/transam/xlog.c:5622 access/transam/xlogfuncs.c:687 +#: commands/copy.c:1810 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:533 +#: replication/logical/origin.c:655 replication/logical/origin.c:794 +#: replication/logical/reorderbuffer.c:3657 +#: replication/logical/snapbuild.c:1653 replication/logical/snapbuild.c:1851 +#: replication/slot.c:1513 replication/slot.c:1674 replication/walsender.c:558 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:704 +#: storage/file/fd.c:3425 storage/file/fd.c:3528 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "неможливо закрити файл \"%s\": %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "неправильний порядок байтів" + +#: ../common/controldata_utils.c:137 +#, c-format +msgid "possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "можлива помилка у послідовності байтів.\n" +"Порядок байтів, що використовують для зберігання файлу pg_control, може не відповідати тому, який використовується цією програмою. У такому випадку результати нижче будуть неправильним, і інсталяція PostgreSQL буде несумісною з цим каталогом даних." + +#: ../common/controldata_utils.c:197 ../common/controldata_utils.c:203 +#: ../common/file_utils.c:224 ../common/file_utils.c:283 +#: ../common/file_utils.c:357 access/heap/rewriteheap.c:1267 +#: access/transam/timeline.c:111 access/transam/timeline.c:251 +#: access/transam/timeline.c:348 access/transam/twophase.c:1232 +#: access/transam/xlog.c:3277 access/transam/xlog.c:3417 +#: access/transam/xlog.c:3458 access/transam/xlog.c:3656 +#: access/transam/xlog.c:3741 access/transam/xlog.c:3844 +#: access/transam/xlog.c:4718 access/transam/xlogutils.c:807 +#: postmaster/syslogger.c:1488 replication/basebackup.c:621 +#: replication/basebackup.c:1593 replication/logical/origin.c:707 +#: replication/logical/reorderbuffer.c:2465 +#: replication/logical/reorderbuffer.c:2825 +#: replication/logical/reorderbuffer.c:3579 +#: replication/logical/snapbuild.c:1608 replication/logical/snapbuild.c:1712 +#: replication/slot.c:1594 replication/walsender.c:516 +#: replication/walsender.c:2516 storage/file/copydir.c:161 +#: storage/file/fd.c:679 storage/file/fd.c:3412 storage/file/fd.c:3499 +#: storage/smgr/md.c:475 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1858 +#: utils/init/miscinit.c:1316 utils/init/miscinit.c:1450 +#: utils/init/miscinit.c:1527 utils/misc/guc.c:8252 utils/misc/guc.c:8284 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" + +#: ../common/controldata_utils.c:221 ../common/controldata_utils.c:224 +#: access/transam/twophase.c:1649 access/transam/twophase.c:1658 +#: access/transam/xlog.c:10878 access/transam/xlog.c:10916 +#: access/transam/xlog.c:11329 access/transam/xlogfuncs.c:741 +#: postmaster/syslogger.c:1499 postmaster/syslogger.c:1512 +#: utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не вдалося записати файл \"%s\": %m" + +#: ../common/controldata_utils.c:239 ../common/controldata_utils.c:245 +#: ../common/file_utils.c:295 ../common/file_utils.c:365 +#: access/heap/rewriteheap.c:961 access/heap/rewriteheap.c:1175 +#: access/heap/rewriteheap.c:1278 access/transam/timeline.c:432 +#: access/transam/timeline.c:510 access/transam/twophase.c:1670 +#: access/transam/xlog.c:3368 access/transam/xlog.c:3537 +#: access/transam/xlog.c:4691 access/transam/xlog.c:10386 +#: access/transam/xlog.c:10413 replication/logical/snapbuild.c:1646 +#: replication/slot.c:1499 replication/slot.c:1604 storage/file/fd.c:696 +#: storage/file/fd.c:3520 storage/smgr/md.c:921 storage/smgr/md.c:962 +#: storage/sync/sync.c:396 utils/cache/relmapper.c:885 utils/misc/guc.c:8035 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "не вдалося fsync файл \"%s\": %m" + +#: ../common/exec.c:137 ../common/exec.c:254 ../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не вдалося визначити поточний каталог: %m" + +#: ../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "невірний бінарний файл \"%s\"" + +#: ../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "неможливо прочитати бінарний файл \"%s\"" + +#: ../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "неможливо знайти \"%s\" для виконання" + +#: ../common/exec.c:270 ../common/exec.c:309 utils/init/miscinit.c:395 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не вдалося змінити каталог на \"%s\": %m" + +#: ../common/exec.c:287 access/transam/xlog.c:10750 +#: replication/basebackup.c:1418 utils/adt/misc.c:337 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не можливо прочитати символічне послання \"%s\": %m" + +#: ../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "помилка pclose: %m" + +#: ../common/exec.c:539 ../common/exec.c:584 ../common/exec.c:676 +#: ../common/psprintf.c:143 ../common/stringinfo.c:305 ../port/path.c:630 +#: ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1341 +#: access/transam/xlog.c:6493 lib/dshash.c:246 libpq/auth.c:1090 +#: libpq/auth.c:1491 libpq/auth.c:1559 libpq/auth.c:2089 +#: libpq/be-secure-gssapi.c:484 postmaster/bgworker.c:336 +#: postmaster/bgworker.c:893 postmaster/postmaster.c:2518 +#: postmaster/postmaster.c:2540 postmaster/postmaster.c:4166 +#: postmaster/postmaster.c:4868 postmaster/postmaster.c:4938 +#: postmaster/postmaster.c:5635 postmaster/postmaster.c:5995 +#: replication/libpqwalreceiver/libpqwalreceiver.c:276 +#: replication/logical/logical.c:176 replication/walsender.c:590 +#: storage/buffer/localbuf.c:442 storage/file/fd.c:834 storage/file/fd.c:1304 +#: storage/file/fd.c:1465 storage/file/fd.c:2270 storage/ipc/procarray.c:1045 +#: storage/ipc/procarray.c:1541 storage/ipc/procarray.c:1548 +#: storage/ipc/procarray.c:1972 storage/ipc/procarray.c:2597 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1698 utils/adt/formatting.c:1822 +#: utils/adt/formatting.c:1947 utils/adt/pg_locale.c:484 +#: utils/adt/pg_locale.c:648 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:450 utils/hash/dynahash.c:559 +#: utils/hash/dynahash.c:1071 utils/mb/mbutils.c:401 utils/mb/mbutils.c:428 +#: utils/mb/mbutils.c:757 utils/mb/mbutils.c:783 utils/misc/guc.c:4846 +#: utils/misc/guc.c:4862 utils/misc/guc.c:4875 utils/misc/guc.c:8013 +#: utils/misc/tzparser.c:467 utils/mmgr/aset.c:475 utils/mmgr/dsa.c:701 +#: utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:233 +#: utils/mmgr/mcxt.c:821 utils/mmgr/mcxt.c:857 utils/mmgr/mcxt.c:895 +#: utils/mmgr/mcxt.c:933 utils/mmgr/mcxt.c:969 utils/mmgr/mcxt.c:1000 +#: utils/mmgr/mcxt.c:1036 utils/mmgr/mcxt.c:1088 utils/mmgr/mcxt.c:1123 +#: utils/mmgr/mcxt.c:1158 utils/mmgr/slab.c:235 +#, c-format +msgid "out of memory" +msgstr "недостатньо пам'яті" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/fe_memutils.c:162 +#: ../common/psprintf.c:145 ../port/path.c:632 ../port/path.c:670 +#: ../port/path.c:687 utils/misc/ps_status.c:181 utils/misc/ps_status.c:189 +#: utils/misc/ps_status.c:219 utils/misc/ps_status.c:227 +#, c-format +msgid "out of memory\n" +msgstr "недостатньо пам'яті\n" + +#: ../common/fe_memutils.c:92 ../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" + +#: ../common/file_utils.c:79 ../common/file_utils.c:181 +#: access/transam/twophase.c:1244 access/transam/xlog.c:10854 +#: access/transam/xlog.c:10892 access/transam/xlog.c:11109 +#: access/transam/xlogarchive.c:110 access/transam/xlogarchive.c:226 +#: commands/copy.c:1938 commands/copy.c:3505 commands/extension.c:3425 +#: commands/tablespace.c:795 commands/tablespace.c:886 +#: replication/basebackup.c:444 replication/basebackup.c:627 +#: replication/basebackup.c:700 replication/logical/snapbuild.c:1522 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1816 +#: storage/file/fd.c:3096 storage/file/fd.c:3278 storage/file/fd.c:3364 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:416 utils/adt/genfile.c:642 guc-file.l:1061 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не вдалося отримати інформацію від файлу \"%s\": %m" + +#: ../common/file_utils.c:158 ../common/pgfnames.c:48 commands/tablespace.c:718 +#: commands/tablespace.c:728 postmaster/postmaster.c:1509 +#: storage/file/fd.c:2673 storage/file/reinit.c:122 utils/adt/misc.c:259 +#: utils/misc/tzparser.c:338 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не вдалося відкрити каталог \"%s\": %m" + +#: ../common/file_utils.c:192 ../common/pgfnames.c:69 storage/file/fd.c:2685 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не вдалося прочитати каталог \"%s\": %m" + +#: ../common/file_utils.c:375 access/transam/xlogarchive.c:411 +#: postmaster/syslogger.c:1523 replication/logical/snapbuild.c:1665 +#: replication/slot.c:650 replication/slot.c:1385 replication/slot.c:1527 +#: storage/file/fd.c:714 utils/time/snapmgr.c:1350 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "не вдалося перейменувати файл \"%s\" на \"%s\": %m" + +#: ../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Неприпустима спеціальна послідовність \"\\%s\"." + +#: ../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Символ зі значенням 0x%02x повинен бути пропущений." + +#: ../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Очікувався кінець введення, але знайдено \"%s\"." + +#: ../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Очікувався елемент масиву або \"]\", але знайдено \"%s\"." + +#: ../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Очікувалось \",\" або \"]\", але знайдено \"%s\"." + +#: ../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Очікувалось \":\", але знайдено \"%s\"." + +#: ../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Очікувалось значення JSON, але знайдено \"%s\"." + +#: ../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "Несподіваний кінець вхідного рядка." + +#: ../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Очікувався рядок або \"}\", але знайдено \"%s\"." + +#: ../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Очікувалось \",\" або \"}\", але знайдено \"%s\"." + +#: ../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Очікувався рядок, але знайдено \"%s\"." + +#: ../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Неприпустимий маркер \"%s\"." + +#: ../common/jsonapi.c:1099 jsonpath_scan.l:499 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 не можна перетворити в текст." + +#: ../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "За \"\\u\" повинні прямувати чотири шістнадцяткових числа." + +#: ../common/jsonapi.c:1104 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Значення виходу Unicode не можна використовувати для значень кодових точок більше 007F, якщо кодування не UTF8." + +#: ../common/jsonapi.c:1106 jsonpath_scan.l:520 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Старший сурогат Unicode не повинен прямувати за іншим старшим сурогатом." + +#: ../common/jsonapi.c:1108 jsonpath_scan.l:531 jsonpath_scan.l:541 +#: jsonpath_scan.l:583 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Молодший сурогат Unicode не повинен прямувати за іншим молодшим сурогатом." + +#: ../common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: ../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не вдалося закрити каталог \"%s\": %m" + +#: ../common/relpath.c:61 +#, c-format +msgid "invalid fork name" +msgstr "неприпустима назва відгалуження" + +#: ../common/relpath.c:62 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Дозволені назви відгалуження: \"main\", \"fsm\", \"vm\" або \"init\"." + +#: ../common/restricted_token.c:64 libpq/auth.c:1521 libpq/auth.c:2520 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "не вдалося завантажити бібліотеку \"%s\": код помилки %lu" + +#: ../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "не вдалося створити обмежені токени на цій платформі: код помилки %lu" + +#: ../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "не вдалося відкрити токен процесу: код помилки %lu" + +#: ../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "не вдалося виділити SID: код помилки %lu" + +#: ../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "не вдалося створити обмежений токен: код помилки %lu" + +#: ../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "не вдалося запустити процес для команди \"%s\": код помилки %lu" + +#: ../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "не вдалося перезапустити з обмеженим токеном: код помилки %lu" + +#: ../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "не вдалося отримати код завершення підпроцесу: код помилки %lu" + +#: ../common/rmtree.c:79 replication/basebackup.c:1171 +#: replication/basebackup.c:1347 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "не вдалося отримати інформацію про файл або каталог \"%s\": %m" + +#: ../common/rmtree.c:101 ../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "не вдалося видалити файл або каталог \"%s\": %m" + +#: ../common/saslprep.c:1087 +#, c-format +msgid "password too long" +msgstr "пароль задовгий" + +#: ../common/stringinfo.c:306 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "Не вдалося збільшити рядковий буфер (містить: %d байтів, потребувалось: %d байтів)." + +#: ../common/stringinfo.c:310 +#, c-format +msgid "out of memory\n\n" +"Cannot enlarge string buffer containing %d bytes by %d more bytes.\n" +msgstr "недостатньо пам'яті\n\n" +"Неможливо збільшити рядковий буфер (містить: %d байт, потребувалось: %d байт).\n" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "не можу знайти користувача з ефективним ID %ld: %s" + +#: ../common/username.c:45 libpq/auth.c:2027 +msgid "user does not exist" +msgstr "користувача не існує" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "невдала підстановка імені користувача: код помилки %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "неможливо виконати команду" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "команду не знайдено" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "дочірній процес завершився з кодом виходу %d" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "дочірній процес перервано через помилку 0х%X" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "дочірній процес перервано через сигнал %d: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "дочірній процес завершився з невизнаним статусом %d" + +#: ../port/chklocale.c:307 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "не вдалося визначити кодування для набору символів \"%s\"" + +#: ../port/chklocale.c:428 ../port/chklocale.c:434 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "не вдалося визначити кодування для докалі \"%s\": набір символів \"%s\"" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "не вдалося встановити сполучення для \"%s\": %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "не вдалося встановити сполучення для \"%s\": %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "не вдалося встановити сполучення для \"%s\": %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "не вдалося встановити сполучення для \"%s\": %s\n" + +#: ../port/open.c:126 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "не вдалося відкрити файл \"%s\": %s" + +#: ../port/open.c:127 +msgid "lock violation" +msgstr "порушення блокування" + +#: ../port/open.c:127 +msgid "sharing violation" +msgstr "порушення спільного доступу" + +#: ../port/open.c:128 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "Продовжую спроби протягом 30 секунд." + +#: ../port/open.c:129 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "Ви можливо маєте антивірус, резервне копіювання або аналогічне програмне забезпечення, що втручається у роботу системи бази даних." + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "не вдалося отримати поточний робочий каталог: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "помилка операційної системи %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "не вдалося отримати SID для групи адміністраторів: код помилки %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "не вдалося отримати SID для групи PowerUsers: код помилки %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "не вдається перевірити членство токену доступу: код помилки %lu\n" + +#: access/brin/brin.c:210 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "запит на підсумок діапазону BRIN для індексу «%s» сторінки %u не вдалося записати" + +#: access/brin/brin.c:873 access/brin/brin.c:950 access/gin/ginfast.c:1035 +#: access/transam/xlog.c:10522 access/transam/xlog.c:11060 +#: access/transam/xlogfuncs.c:274 access/transam/xlogfuncs.c:301 +#: access/transam/xlogfuncs.c:340 access/transam/xlogfuncs.c:361 +#: access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:452 +#: access/transam/xlogfuncs.c:509 +#, c-format +msgid "recovery is in progress" +msgstr "відновлення у процесі" + +#: access/brin/brin.c:874 access/brin/brin.c:951 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Контрольна функція BRIN не може бути виконана під час відновлення." + +#: access/brin/brin.c:882 access/brin/brin.c:959 +#, c-format +msgid "block number out of range: %s" +msgstr "заблоковане число за межами діапазону: %s" + +#: access/brin/brin.c:905 access/brin/brin.c:982 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\" не є індексом BRIN" + +#: access/brin/brin.c:921 access/brin/brin.c:998 +#, c-format +msgid "could not open parent table of index %s" +msgstr "не вдалося відкрити батьківську таблицю індексу %s" + +#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 +#: access/brin/brin_pageops.c:843 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1435 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "розмір рядка індексу %zu перевищує максимальний %zu для індексу \"%s\"" + +#: access/brin/brin_revmap.c:392 access/brin/brin_revmap.c:398 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "пошкоджений BRIN індекс: несумісна карта діапазонів" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "неочікуваний тип сторінки 0x%04X в BRIN індексі \"%s\" блокує %u" + +#: access/brin/brin_validate.c:118 access/gin/ginvalidate.c:151 +#: access/gist/gistvalidate.c:149 access/hash/hashvalidate.c:136 +#: access/nbtree/nbtvalidate.c:117 access/spgist/spgvalidate.c:168 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "сімейство операторів \"%s\" методу доступу %s містить функцію %s з недопустимим номером підтримки %d" + +#: access/brin/brin_validate.c:134 access/gin/ginvalidate.c:163 +#: access/gist/gistvalidate.c:161 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:129 access/spgist/spgvalidate.c:180 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "сімейство операторів \"%s\" з доступом %s містить функцію %s з неправильним підписом для номеру підтримки %d" + +#: access/brin/brin_validate.c:156 access/gin/ginvalidate.c:182 +#: access/gist/gistvalidate.c:181 access/hash/hashvalidate.c:157 +#: access/nbtree/nbtvalidate.c:149 access/spgist/spgvalidate.c:200 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "сімейство операторів \"%s\" з доступом %s містить оператор %s з недопустимим стратегічним номером %d" + +#: access/brin/brin_validate.c:185 access/gin/ginvalidate.c:195 +#: access/hash/hashvalidate.c:170 access/nbtree/nbtvalidate.c:162 +#: access/spgist/spgvalidate.c:216 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "сімейство операторів \"%s\" з доступом %s містить некоректну специфікацію ORDER BY для оператора %s" + +#: access/brin/brin_validate.c:198 access/gin/ginvalidate.c:208 +#: access/gist/gistvalidate.c:229 access/hash/hashvalidate.c:183 +#: access/nbtree/nbtvalidate.c:175 access/spgist/spgvalidate.c:232 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "сімейство операторів \"%s\" з доступом %s містить оператор %s з неправильним підписом" + +#: access/brin/brin_validate.c:236 access/hash/hashvalidate.c:223 +#: access/nbtree/nbtvalidate.c:233 access/spgist/spgvalidate.c:259 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "сімейство операторів \"%s\" методу доступу %s не містить операторів для типів %s і %s" + +#: access/brin/brin_validate.c:246 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "сімейство операторів \"%s\" з методом доступа %s не містить функцію підтримки для типів %s і %s" + +#: access/brin/brin_validate.c:259 access/hash/hashvalidate.c:237 +#: access/nbtree/nbtvalidate.c:257 access/spgist/spgvalidate.c:294 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "клас операторів \"%s\" з методом доступа %s не має операторів" + +#: access/brin/brin_validate.c:270 access/gin/ginvalidate.c:250 +#: access/gist/gistvalidate.c:270 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "клас операторів \"%s\" з доступом %s немає функції підтримки %d" + +#: access/common/attmap.c:122 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "Повернений тип %s не відповідає очікуваному типу %s в стовпці %d." + +#: access/common/attmap.c:150 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "Кількість повернених стовпців (%d) не відповідає очікуваній кількості стовпців (%d)." + +#: access/common/attmap.c:229 access/common/attmap.c:241 +#, c-format +msgid "could not convert row type" +msgstr "неможливо конвертувати тип рядка" + +#: access/common/attmap.c:230 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "Атрибут \"%s\" типу %s не збігається з відповідним атрибутом типу %s." + +#: access/common/attmap.c:242 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "Атрибут \"%s\" типу %s не існує в типі %s." + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "кількість стовпців (%d) перевищує обмеження (%d)" + +#: access/common/indextuple.c:70 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "кількість індексних стовпців (%d) перевищує обмеження (%d)" + +#: access/common/indextuple.c:187 access/spgist/spgutils.c:703 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "індексний рядок вимагає %zu байтів, максимальний розмір %zu" + +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1904 +#, c-format +msgid "unsupported format code: %d" +msgstr "цей формат коду не підтримується:%d" + +#: access/common/reloptions.c:506 +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Дійсні значення \"увімкнено\", \"вимкнено\" та \"автоматично\"." + +#: access/common/reloptions.c:517 +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "Припустимі значення лише \"local\" і \"cascaded\"." + +#: access/common/reloptions.c:665 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "перевищено встановлене користувачем обмеження типу параметрів відношення" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESET не має містити значення для параметрів" + +#: access/common/reloptions.c:1240 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "нерозпізнаний параметр простору імен \"%s\"" + +#: access/common/reloptions.c:1277 utils/misc/guc.c:12004 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "таблиці, позначені WITH OIDS, не підтримуються" + +#: access/common/reloptions.c:1447 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "нерозпізнаний параметр \"%s\"" + +#: access/common/reloptions.c:1559 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "параметр «%s» вказано кілька разів" + +#: access/common/reloptions.c:1575 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "неприпустиме значення для булевого параметра \"%s\": %s" + +#: access/common/reloptions.c:1587 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "неприпустиме значення для цілого параметра \"%s\": %s" + +#: access/common/reloptions.c:1593 access/common/reloptions.c:1613 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "значення %s поза допустимими межами для параметра \"%s\"" + +#: access/common/reloptions.c:1595 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Припустимі значення знаходяться між \"%d\" і \"%d\"." + +#: access/common/reloptions.c:1607 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "неприпустиме значення для числа з плавучою точкою параметра \"%s\": %s" + +#: access/common/reloptions.c:1615 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Припустимі значення знаходяться між \"%f\" і \"%f\"." + +#: access/common/reloptions.c:1637 +#, c-format +msgid "invalid value for enum option \"%s\": %s" +msgstr "неприпустиме значення для параметра переліку \"%s\": %s" + +#: access/common/tupdesc.c:842 parser/parse_clause.c:772 +#: parser/parse_relation.c:1803 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "стовпець\"%s\" не може бути оголошений SETOF" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "список вказівників задовгий" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "Зменшіть maintenance_work_mem." + +#: access/gin/ginfast.c:1036 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "Черга записів GIN не може бути очищена під час відновлення." + +#: access/gin/ginfast.c:1043 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\" не є індексом GIN" + +#: access/gin/ginfast.c:1054 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "доступ до тимчасових індексів з інших сесій заблокований" + +#: access/gin/ginget.c:270 access/nbtree/nbtinsert.c:745 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "не вдалося повторно знайти кортеж в межах індексу \"%s\"" + +#: access/gin/ginscan.c:431 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "старі індекси GIN не підтримують сканування цілого індексу й пошуки значення null" + +#: access/gin/ginscan.c:432 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "Щоб виправити це, зробіть REINDEX INDEX \"%s\"." + +#: access/gin/ginutil.c:144 executor/execExpr.c:1862 +#: utils/adt/arrayfuncs.c:3790 utils/adt/arrayfuncs.c:6418 +#: utils/adt/rowtypes.c:936 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "не вдалося визначити порівняльну функцію для типу %s" + +#: access/gin/ginvalidate.c:92 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "сімейство операторів \"%s\" з методом доступу %s містить функцію підтримки %s з різними типами вводу зліва і справа" + +#: access/gin/ginvalidate.c:260 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "клас операторів \"%s\" з методом доступу %s не має функції підтримки %d або %d" + +#: access/gist/gist.c:753 access/gist/gistvacuum.c:408 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "індекс \"%s\" містить внутрішній кортеж, позначений як неправильний" + +#: access/gist/gist.c:755 access/gist/gistvacuum.c:410 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "Це викликано неповним поділом сторінки під час відновлення перед покращенням до версії PostgreSQL 9.1." + +#: access/gist/gist.c:756 access/gist/gistutil.c:786 access/gist/gistutil.c:797 +#: access/gist/gistvacuum.c:411 access/hash/hashutil.c:227 +#: access/hash/hashutil.c:238 access/hash/hashutil.c:250 +#: access/hash/hashutil.c:271 access/nbtree/nbtpage.c:741 +#: access/nbtree/nbtpage.c:752 +#, c-format +msgid "Please REINDEX it." +msgstr "Будь ласка, виконайте REINDEX." + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "помилка методу picksplit для стовпця %d індекса \"%s\"" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "Індекс не є оптимальним. Щоб оптимізувати його, зв'яжіться з розробником або спробуйте використати стовпець як другий індекс у команді CREATE INDEX." + +#: access/gist/gistutil.c:783 access/hash/hashutil.c:224 +#: access/nbtree/nbtpage.c:738 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "індекс \"%s\" містить неочікувану нульову сторінку в блоці %u" + +#: access/gist/gistutil.c:794 access/hash/hashutil.c:235 +#: access/hash/hashutil.c:247 access/nbtree/nbtpage.c:749 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "індекс \"%s\" містить пошкоджену сторінку в блоці %u" + +#: access/gist/gistvalidate.c:199 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "сімейство операторів \"%s\" з методом доступу %s містить непідтримувану для оператора специфікацію ORDER BY %s" + +#: access/gist/gistvalidate.c:210 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "сімейство операторів \"%s\" з методом доступу %s містить некоректну для оператора специфікацію ORDER BY opfamily %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:993 utils/adt/varchar.c:1053 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "не вдалося визначити, який параметр сортування використати для обчислення хешу рядків" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:702 +#: catalog/heap.c:708 commands/createas.c:206 commands/createas.c:489 +#: commands/indexcmds.c:1815 commands/tablecmds.c:16035 commands/view.c:86 +#: parser/parse_utilcmd.c:4203 regex/regc_pg_locale.c:263 +#: utils/adt/formatting.c:1665 utils/adt/formatting.c:1789 +#: utils/adt/formatting.c:1914 utils/adt/like.c:194 +#: utils/adt/like_support.c:1003 utils/adt/varchar.c:733 +#: utils/adt/varchar.c:994 utils/adt/varchar.c:1054 utils/adt/varlena.c:1476 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Використайте опцію COLLATE для задання параметрів сортування." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "індексний рядок розміру %zu перевищує максимальний хеш %zu" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:764 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Значення, що перевищують буфер сторінки, не можна індексувати." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "недійсний номер блока переповнення %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "закінчились переповнені сторінки в хеш-індексі \"%s\"" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "хеш-індекси не підтримують сканування цілого індексу" + +#: access/hash/hashutil.c:263 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "індекс \"%s\" не є хеш-індексом" + +#: access/hash/hashutil.c:269 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "індекс \"%s\" має неправильну версію хешу" + +#: access/hash/hashvalidate.c:195 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "сімейство операторів \"%s\" з методом доступу %s не містить функції підтримки для оператора %s" + +#: access/hash/hashvalidate.c:253 access/nbtree/nbtvalidate.c:273 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "сімейство операторів \"%s\" з методом доступу %s не містить міжтипового оператора (ів)" + +#: access/heap/heapam.c:2024 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "не вдалося вставити кортежі в паралельного працівника" + +#: access/heap/heapam.c:2442 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "не вдалося видалити кортежі під час паралельної операції" + +#: access/heap/heapam.c:2488 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "спроба видалити невидимий кортеж" + +#: access/heap/heapam.c:2914 access/heap/heapam.c:5703 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "неможливо оновити кортежі під час паралельної операції" + +#: access/heap/heapam.c:3047 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "спроба оновити невидимий кортеж" + +#: access/heap/heapam.c:4358 access/heap/heapam.c:4396 +#: access/heap/heapam.c:4653 access/heap/heapam_handler.c:450 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "не вдалося отримати блокування у рядку стосовно \"%s\"" + +#: access/heap/heapam_handler.c:399 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "кортеж, який підлягає блокуванню, вже був переміщений до іншої секції в результаті паралельного оновлення" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:662 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "рядок завеликий: розмір %zu, максимальний розмір %zu" + +#: access/heap/rewriteheap.c:921 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "не вдалося записати до файлу \"%s\", записано %d з %d: %m" + +#: access/heap/rewriteheap.c:1015 access/heap/rewriteheap.c:1134 +#: access/transam/timeline.c:329 access/transam/timeline.c:485 +#: access/transam/xlog.c:3300 access/transam/xlog.c:3472 +#: access/transam/xlog.c:4670 access/transam/xlog.c:10869 +#: access/transam/xlog.c:10907 access/transam/xlog.c:11312 +#: access/transam/xlogfuncs.c:735 postmaster/postmaster.c:4629 +#: replication/logical/origin.c:575 replication/slot.c:1446 +#: storage/file/copydir.c:167 storage/smgr/md.c:218 utils/time/snapmgr.c:1329 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "неможливо створити файл \"%s\": %m" + +#: access/heap/rewriteheap.c:1144 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "не вдалося скоротити файл \"%s\" до потрібного розміру %u: %m" + +#: access/heap/rewriteheap.c:1162 access/transam/timeline.c:384 +#: access/transam/timeline.c:424 access/transam/timeline.c:502 +#: access/transam/xlog.c:3356 access/transam/xlog.c:3528 +#: access/transam/xlog.c:4682 postmaster/postmaster.c:4639 +#: postmaster/postmaster.c:4649 replication/logical/origin.c:587 +#: replication/logical/origin.c:629 replication/logical/origin.c:648 +#: replication/logical/snapbuild.c:1622 replication/slot.c:1481 +#: storage/file/buffile.c:502 storage/file/copydir.c:207 +#: utils/init/miscinit.c:1391 utils/init/miscinit.c:1402 +#: utils/init/miscinit.c:1410 utils/misc/guc.c:7996 utils/misc/guc.c:8027 +#: utils/misc/guc.c:9947 utils/misc/guc.c:9961 utils/time/snapmgr.c:1334 +#: utils/time/snapmgr.c:1341 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "неможливо записати до файлу \"%s\": %m" + +#: access/heap/rewriteheap.c:1252 access/transam/twophase.c:1609 +#: access/transam/xlogarchive.c:118 access/transam/xlogarchive.c:421 +#: postmaster/postmaster.c:1092 postmaster/syslogger.c:1465 +#: replication/logical/origin.c:563 replication/logical/reorderbuffer.c:3079 +#: replication/logical/snapbuild.c:1564 replication/logical/snapbuild.c:2006 +#: replication/slot.c:1578 storage/file/fd.c:754 storage/file/fd.c:3116 +#: storage/file/fd.c:3178 storage/file/reinit.c:255 storage/ipc/dsm.c:302 +#: storage/smgr/md.c:311 storage/smgr/md.c:367 storage/sync/sync.c:210 +#: utils/time/snapmgr.c:1674 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "не можливо видалити файл \"%s\": %m" + +#: access/heap/vacuumlazy.c:648 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "автоматичний агресивний вакуум для запобігання зацикленню таблиці \"%s.%s.%s\": сканування індексу: %d\n" + +#: access/heap/vacuumlazy.c:650 +#, c-format +msgid "automatic vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "автоматичне очищення для запобігання зацикленню таблиці \"%s.%s.%s\": сканування індексу: %d\n" + +#: access/heap/vacuumlazy.c:655 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "автоматична агресивне очищення таблиці \"%s.%s.%s\": сканувань індексу: %d\n" + +#: access/heap/vacuumlazy.c:657 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "автоматичне очищення таблиці \"%s.%s.%s\": сканувань індексу: %d\n" + +#: access/heap/vacuumlazy.c:664 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "сторінок: %u видалено, %u залишилось, %u пропущено закріплених, %u пропущено заморожених\n" + +#: access/heap/vacuumlazy.c:670 +#, c-format +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "кортежів: %.0f видалено, %.0f залишилось, %.0fв мертвих, але все ще не підлягають видаленню, найстарший xmin: %u\n" + +#: access/heap/vacuumlazy.c:676 +#, c-format +msgid "buffer usage: %lld hits, %lld misses, %lld dirtied\n" +msgstr "використання буферу: %lld збігів, %lld пропусків, %lld брудних записів\n" + +#: access/heap/vacuumlazy.c:680 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "середня швидкість читання: %.3f МБ/с, середня швидкість запису: %.3f МБ/с\n" + +#: access/heap/vacuumlazy.c:682 +#, c-format +msgid "system usage: %s\n" +msgstr "використання системи: %s\n" + +#: access/heap/vacuumlazy.c:684 +#, c-format +msgid "WAL usage: %ld records, %ld full page images, %llu bytes" +msgstr "Використання WAL: %ld записів, %ld зображень на повну сторінку, %llu байтів" + +#: access/heap/vacuumlazy.c:795 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "агресивне очищення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:800 commands/cluster.c:874 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "очищення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:837 +#, c-format +msgid "disabling parallel option of vacuum on \"%s\" --- cannot vacuum temporary tables in parallel" +msgstr "вимкнення паралельної опції очищення на \"%s\" --- не можна паралельно очистити тимчасові таблиці" + +#: access/heap/vacuumlazy.c:1725 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%s\": видалено %.0f версій рядків, в %u сторінок" + +#: access/heap/vacuumlazy.c:1735 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "Все ще не можна видалити мертві рядки %.0f, найстарший xmin: %u\n" + +#: access/heap/vacuumlazy.c:1737 +#, c-format +msgid "There were %.0f unused item identifiers.\n" +msgstr "Знайдено %.0f невикористаних ідентифікаторів елементів.\n" + +#: access/heap/vacuumlazy.c:1739 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Пропущено %u сторінку, закріплену в буфері " +msgstr[1] "Пропущено %u сторінки, закріплені в буфері " +msgstr[2] "Пропущено %u сторінок, закріплених в буфері " +msgstr[3] "Пропущено %u сторінок, закріплених в буфері " + +#: access/heap/vacuumlazy.c:1743 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u заморожена сторінка.\n" +msgstr[1] "%u заморожені сторінки.\n" +msgstr[2] "%u заморожених сторінок.\n" +msgstr[3] "%u заморожених сторінок.\n" + +#: access/heap/vacuumlazy.c:1747 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%u сторінка повністю порожня.\n" +msgstr[1] "%u сторінки повністю порожні.\n" +msgstr[2] "%u сторінок повністю порожні.\n" +msgstr[3] "%u сторінок повністю порожні.\n" + +#: access/heap/vacuumlazy.c:1751 commands/indexcmds.c:3450 +#: commands/indexcmds.c:3468 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1754 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%s\": знайдено %.0f видалених, %.0f невидалених версій рядків у %u з %u сторінок" + +#: access/heap/vacuumlazy.c:1888 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%s\": видалено %d версій рядків у %d сторінках" + +#: access/heap/vacuumlazy.c:2143 +#, c-format +msgid "launched %d parallel vacuum worker for index cleanup (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index cleanup (planned: %d)" +msgstr[0] "запущений %d паралельний виконавець очистки для очищення індексу (заплановано: %d)" +msgstr[1] "запущено %d паралельних виконавців очистки для очищення індексу (заплановано: %d)" +msgstr[2] "запущено %d паралельних виконавців очистки для очищення індексу (заплановано: %d)" +msgstr[3] "запущено %d паралельних виконавців очистки для очищення індексу (заплановано: %d)" + +#: access/heap/vacuumlazy.c:2149 +#, c-format +msgid "launched %d parallel vacuum worker for index vacuuming (planned: %d)" +msgid_plural "launched %d parallel vacuum workers for index vacuuming (planned: %d)" +msgstr[0] "запущений %d паралельний виконавець очистки для очищення індексу (заплановано: %d)" +msgstr[1] "запущено %d паралельних виконавців очистки для очищення індексу (заплановано: %d)" +msgstr[2] "запущено %d паралельних виконавців очистки для очищення індексу (заплановано: %d)" +msgstr[3] "запущено %d паралельних виконавців очистки для очищення індексу (заплановано: %d)" + +#: access/heap/vacuumlazy.c:2441 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions by parallel vacuum worker" +msgstr "відсканований індекс \"%s\" видалити %d версії рядків паралельним виконавцем очистки" + +#: access/heap/vacuumlazy.c:2443 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "просканований індекс \"%s\", видалено версій рядків %d" + +#: access/heap/vacuumlazy.c:2501 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages as reported by parallel vacuum worker" +msgstr "індекс \"%s\" тепер містить %.0f версій рядків у %u сторінках, як повідомлено паралельним виконавцем очистки" + +#: access/heap/vacuumlazy.c:2503 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "індекс \"%s\" наразі містить %.0f версій рядків у %u сторінках" + +#: access/heap/vacuumlazy.c:2510 +#, c-format +msgid "%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "Видалено версій рядків індексу: %.0f.\n" +"Видалено індексних сторінок %u, придатні для повторного користування: %u.\n" +"%s." + +#: access/heap/vacuumlazy.c:2613 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\": зупинка скорочення через конфліктний запит блокування" + +#: access/heap/vacuumlazy.c:2679 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": скорочено (було: %u, стало: %u сторінок)" + +#: access/heap/vacuumlazy.c:2744 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\" припинення скорочення через конфліктний запит блокування" + +#: access/heap/vacuumlazy.c:3583 +#, c-format +msgid "while scanning block %u of relation \"%s.%s\"" +msgstr "під час сканування блоку %u відношення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3586 +#, c-format +msgid "while scanning relation \"%s.%s\"" +msgstr "під час сканування відношення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3592 +#, c-format +msgid "while vacuuming block %u of relation \"%s.%s\"" +msgstr "під час очищення блоку %u відношення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3595 +#, c-format +msgid "while vacuuming relation \"%s.%s\"" +msgstr "під час очищення відношення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3600 +#, c-format +msgid "while vacuuming index \"%s\" of relation \"%s.%s\"" +msgstr "під час очищення індексу \"%s\" відношення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3605 +#, c-format +msgid "while cleaning up index \"%s\" of relation \"%s.%s\"" +msgstr "під час очищення індексу \"%s\" відношення \"%s.%s\"" + +#: access/heap/vacuumlazy.c:3611 +#, c-format +msgid "while truncating relation \"%s.%s\" to %u blocks" +msgstr "під час скорочення відношення \"%s.%s\" до %u блоків" + +#: access/index/amapi.c:83 commands/amcmds.c:170 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "метод доступу \"%s\" не є типу %s" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "для методу доступу індекса \"%s\" не заданий обробник" + +#: access/index/indexam.c:142 catalog/objectaddress.c:1260 +#: commands/indexcmds.c:2517 commands/tablecmds.c:254 commands/tablecmds.c:278 +#: commands/tablecmds.c:15733 commands/tablecmds.c:17188 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\" не є індексом" + +#: access/index/indexam.c:970 +#, c-format +msgid "operator class %s has no options" +msgstr "клас операторів %s не має параметрів" + +#: access/nbtree/nbtinsert.c:651 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "повторювані значення ключа порушують обмеження унікальності \"%s\"" + +#: access/nbtree/nbtinsert.c:653 +#, c-format +msgid "Key %s already exists." +msgstr "Ключ %s вже існує." + +#: access/nbtree/nbtinsert.c:747 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Можливо, це викликано змінною природою індексного вираження." + +#: access/nbtree/nbtpage.c:150 access/nbtree/nbtpage.c:538 +#: parser/parse_utilcmd.c:2244 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "індекс \"%s\" не є b-деревом" + +#: access/nbtree/nbtpage.c:157 access/nbtree/nbtpage.c:545 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "невідповідність версії в індексі \"%s\": версія файла %d, поточна версія %d, мінімальна підтримувана версія %d" + +#: access/nbtree/nbtpage.c:1501 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "індекс \"%s\" містить наполовину мертву внутрішню сторінку" + +#: access/nbtree/nbtpage.c:1503 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "Це могло статися через переривання VACUUM у версії 9.3 або старше перед оновленням. Будь ласка, виконайте REINDEX." + +#: access/nbtree/nbtutils.c:2664 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "розмір рядка індексу %zu перевищує максимальний розмір для версії %u btree %zu для індексу \"%s\"" + +#: access/nbtree/nbtutils.c:2670 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "Рядок індексу посилається на кортеж (%u,,%u) у відношенні \"%s\"." + +#: access/nbtree/nbtutils.c:2674 +#, c-format +msgid "Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "Значення, що займають більше, ніж 1/3 сторінки буферу, не можуть бути індексовані.\n" +"Радимо застосувати індекс MD5-хеш значення або використати повнотекстове індексування." + +#: access/nbtree/nbtvalidate.c:243 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "сімейство операторів \"%s\" методу доступу %s не має опорної функції для типів %s та %s" + +#: access/spgist/spgutils.c:147 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "метод стиснення повинен бути визначений, коли тип листів відрізняється від вхідного типу" + +#: access/spgist/spgutils.c:761 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "Внутрішній розмір кортежу SP-GiST %zu перевищує максимальний %zu" + +#: access/spgist/spgvalidate.c:281 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "сімейство операторів \"%s\" методу доступу %s не має опорної функції для типів %d для типу %s" + +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 +#: catalog/aclchk.c:1806 +#, c-format +msgid "\"%s\" is an index" +msgstr "\"%s\" є індексом" + +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 +#: catalog/aclchk.c:1813 commands/tablecmds.c:12554 commands/tablecmds.c:15742 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "\"%s\" це складений тип" + +#: access/table/tableam.c:244 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "невірний tid (%u, %u) для відношення \"%s\"" + +#: access/table/tableamapi.c:115 +#, c-format +msgid "%s cannot be empty." +msgstr "%s не може бути пустим." + +#: access/table/tableamapi.c:122 utils/misc/guc.c:11928 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s занадто довгий (максимум %d символів)." + +#: access/table/tableamapi.c:145 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "табличного методу доступу \"%s\" не існує" + +#: access/table/tableamapi.c:150 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "Табличного методу доступу \"%s\" не існує." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "відсоток вибірки повинен задаватися числом від 0 до 100" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "не вдалося отримати мітку позначки часу транзакції %u" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "не вдалося отримати позначку часу фіксації" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "Переконайтесь, що в конфігурації головного серверу встановлений параметр \"%s\"." + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "Переконайтесь, що в конфігурації встановлений параметр \"%s\"." + +#: access/transam/multixact.c:1002 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "щоб уникнути втрат даних у базі даних \"%s\", база даних не приймає команди, що створюють нові MultiXactIds" + +#: access/transam/multixact.c:1004 access/transam/multixact.c:1011 +#: access/transam/multixact.c:1035 access/transam/multixact.c:1044 +#, c-format +msgid "Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "Виконати очистку (VACUUM) по всій базі даних.\n" +"Можливо, вам доведеться зафіксувати, відкотити назад старі підготовані транзакції або видалити застарілі слоти реплікації." + +#: access/transam/multixact.c:1009 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "щоб уникнути втрат даних в базі даних з OID %u, база даних не приймає команди, що створюють нові MultiXactIds" + +#: access/transam/multixact.c:1030 access/transam/multixact.c:2320 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "база даних \"%s\" повинна бути очищена (vacuumed), перед тим як більшість MultiXactId буде використана (%u)" +msgstr[1] "бази даних \"%s\" повинні бути очищені (vacuumed) перед тим, як більшість MultiXactId буде використано (%u)" +msgstr[2] "баз даних \"%s\" повинні бути очищені (vacuumed) перед тим, як більшість MultiXactIds буде використано (%u)" +msgstr[3] "баз даних \"%s\" повинні бути очищені (vacuumed) перед тим, як більшість MultiXactId буде використано (%u)" + +#: access/transam/multixact.c:1039 access/transam/multixact.c:2329 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "база даних з OID %u повинна бути очищена (vacuumed), перед тим як більшість MultiXactId буде використано (%u)" +msgstr[1] "бази даних з OID %u повинні бути очищені (vacuumed), перед тим як більшість MultiXactIds буде використано (%u)" +msgstr[2] "баз даних з OID %u повинні бути очищені (vacuumed), перед тим як більшість MultiXactIds буде використано (%u)" +msgstr[3] "баз даних з OID %u повинні бути очищені (vacuumed), перед тим як більшість MultiXactId буде використано (%u)" + +#: access/transam/multixact.c:1100 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "перевищено ліміт членів мультитранзакції" + +#: access/transam/multixact.c:1101 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "Мультитранзакція створена цією командою з %u членів, але місця вистачає лише для %u члена." +msgstr[1] "Мультитранзакція створена цією командою з %u членів, але місця вистачає лише для %u членів." +msgstr[2] "Мультитранзакція створена цією командою з %u членів, але місця вистачає лише для %u членів." +msgstr[3] "Мультитранзакція створена цією командою з %u членів, але місця вистачає лише для %u членів." + +#: access/transam/multixact.c:1106 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Виконати очистку (VACUUM) по всій базі даних з OID %u зі зменшенням значення vacuum_multixact_freeze_min_age та vacuum_multixact_freeze_table_age settings." + +#: access/transam/multixact.c:1137 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "база даних з OID %u повинна бути очищена перед використанням додаткового члена мультитранзакції (%d)" +msgstr[1] "база даних з OID %u повинна бути очищена перед використанням додаткових членів мультитранзакції (%d)" +msgstr[2] "база даних з OID %u повинна бути очищена перед використанням додаткових членів мультитранзакції (%d)" +msgstr[3] "база даних з OID %u повинна бути очищена перед використанням додаткових членів мультитранзакції (%d)" + +#: access/transam/multixact.c:1142 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Виконати очищення (VACUUM) по всій цій базі даних зі зменшенням значення vacuum_multixact_freeze_min_age та vacuum_multixact_freeze_table_age settings." + +#: access/transam/multixact.c:1279 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "MultiXactId %u припинив існування -- очевидно відбулося зациклення" + +#: access/transam/multixact.c:1287 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "MultiXactId %u ще не був створений -- очевидно відбулося зациклення" + +#: access/transam/multixact.c:2270 +#, c-format +msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +msgstr "Межа зациклення MultiXactId дорівнює %u. Обмежено базою даних з OID %u" + +#: access/transam/multixact.c:2325 access/transam/multixact.c:2334 +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/varsup.c:447 access/transam/varsup.c:454 +#, c-format +msgid "To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "Щоб уникнути вимкнення бази даних, виконайте VACUUM для всієї бази даних.\n" +"Можливо, вам доведеться зафіксувати або відкотити назад старі підготовленні транзакції або видалити застарілі слоти реплікації." + +#: access/transam/multixact.c:2604 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "зсув члену найстарішої MultiXactId: %u" + +#: access/transam/multixact.c:2608 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "Захист від зациклення члену MultiXact вимкнена, оскільки найстаріша контрольна точка MultiXact %u не існує на диску" + +#: access/transam/multixact.c:2630 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "Захист від зациклення члену MultiXact наразі ввімкнена" + +#: access/transam/multixact.c:2633 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "Межа зупинки члену MultiXact %u заснована на MultiXact %u" + +#: access/transam/multixact.c:3013 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "найстарішу MultiXact %u не знайдено, найновіша MultiXact %u, скорочення пропускається" + +#: access/transam/multixact.c:3031 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "неможливо виконати скорочення до MultiXact %u, оскільки її не існує на диску, скорочення пропускається" + +#: access/transam/multixact.c:3345 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "неприпустимий MultiXactId: %u" + +#: access/transam/parallel.c:706 access/transam/parallel.c:825 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "не вдалося виконати ініціалізацію паралельного виконавця" + +#: access/transam/parallel.c:707 access/transam/parallel.c:826 +#, c-format +msgid "More details may be available in the server log." +msgstr "Більше деталей можуть бути доступні в журналі серверу." + +#: access/transam/parallel.c:887 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "postmaster завершився під час паралельної транзакції" + +#: access/transam/parallel.c:1074 +#, c-format +msgid "lost connection to parallel worker" +msgstr "втрачено зв'язок з паралельним виконавцем" + +#: access/transam/parallel.c:1140 access/transam/parallel.c:1142 +msgid "parallel worker" +msgstr "паралельний виконавець" + +#: access/transam/parallel.c:1293 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "не вдалося відобразити динамічний сегмент спільної пам'яті" + +#: access/transam/parallel.c:1298 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "неприпустиме магічне число в динамічному сегменті спільної пам'яті" + +#: access/transam/slru.c:696 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "файл \"%s\" не існує, вважається нульовим" + +#: access/transam/slru.c:937 access/transam/slru.c:943 +#: access/transam/slru.c:951 access/transam/slru.c:956 +#: access/transam/slru.c:963 access/transam/slru.c:968 +#: access/transam/slru.c:975 access/transam/slru.c:982 +#, c-format +msgid "could not access status of transaction %u" +msgstr "не можливо отримати статус транзакції %u" + +#: access/transam/slru.c:938 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "Не можливо відкрити файл \"%s\": %m." + +#: access/transam/slru.c:944 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "Не вдалося переміститися у файлі \"%s\" до зсуву %u: %m." + +#: access/transam/slru.c:952 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "Не вдалося прочитати файл \"%s\" по зсуву %u: %m." + +#: access/transam/slru.c:957 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: read too few bytes." +msgstr "Не вдалося прочитати з файлу \"%s\" із зсувом %u: прочитано занадто мало байтів." + +#: access/transam/slru.c:964 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "Не вдалося записати файл \"%s\" по зсуву %u: %m." + +#: access/transam/slru.c:969 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: wrote too few bytes." +msgstr "Не вдалося записати файл \"%s\" із зсувом %u: записано занадто мало байтів." + +#: access/transam/slru.c:976 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "Не вдалося синхронізувати файл \"%s\": %m." + +#: access/transam/slru.c:983 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "Не можливо закрити файл \"%s\": %m." + +#: access/transam/slru.c:1254 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "не вдалося спустошити каталог \"%s\": очевидно сталося зациклення" + +#: access/transam/slru.c:1309 access/transam/slru.c:1365 +#, c-format +msgid "removing file \"%s\"" +msgstr "видалення файлу \"%s\"" + +#: access/transam/timeline.c:163 access/transam/timeline.c:168 +#, c-format +msgid "syntax error in history file: %s" +msgstr "синтаксична помилка у файлі історії: %s" + +#: access/transam/timeline.c:164 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Очікується числовий ідентифікатор лінії часу." + +#: access/transam/timeline.c:169 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Очікується положення точки випереджувального журналювання." + +#: access/transam/timeline.c:173 +#, c-format +msgid "invalid data in history file: %s" +msgstr "неприпустимі дані у файлу історії: %s" + +#: access/transam/timeline.c:174 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Ідентифікатори ліній часу повинні збільшуватись." + +#: access/transam/timeline.c:194 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "неприпустимі дані у файлу історії \"%s\"" + +#: access/transam/timeline.c:195 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Ідентифікатори ліній часу повинні бути меншими від ідентифікатора дочірньої лінії." + +#: access/transam/timeline.c:597 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "в історії даного серверу немає запитаної лінії часу %u" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "ідентифікатор транзакції \"%s\" задовгий" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "підготовлені транзакції вимкнено" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "Встановіть ненульове значення параметра max_prepared_transactions." + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "ідентифікатор транзакції \"%s\" вже використовується" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2368 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "досягнуто максимального числа підготованих транзакцій" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2369 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "Збільшіть max_prepared_transactions (наразі %d)." + +#: access/transam/twophase.c:586 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "підготовлена транзакція з ідентифікатором \"%s\" зайнята" + +#: access/transam/twophase.c:592 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "немає дозволу для завершення підготовлених транзакцій" + +#: access/transam/twophase.c:593 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "Треба пути суперкористувачем або користувачем, який підготував транзакцію." + +#: access/transam/twophase.c:604 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "підготовлена транзакція належить до іншої бази даних" + +#: access/transam/twophase.c:605 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "З'єднайтесь з базою даних, де була підготовлена транзакція, щоб завершити її." + +#: access/transam/twophase.c:620 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "підготовленої транзакції з ідентифікатором \"%s\" не існує" + +#: access/transam/twophase.c:1098 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "перевищено граничний розмір файла у 2-фазовому стані" + +#: access/transam/twophase.c:1252 +#, c-format +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "неправильний розмір файлу \"%s\": %zu байт" +msgstr[1] "неправильний розмір файлу \"%s\": %zu байти" +msgstr[2] "неправильний розмір файлу \"%s\": %zu байтів" +msgstr[3] "неправильний розмір файлу \"%s\": %zu байтів" + +#: access/transam/twophase.c:1261 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "неправильне вирівнювання зсуву CRC для файлу \"%s\"" + +#: access/transam/twophase.c:1294 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "неприпустиме магічне число, збережене у файлі\"%s\"" + +#: access/transam/twophase.c:1300 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "неприпустимий розмір, збережений у файлі \"%s\"" + +#: access/transam/twophase.c:1312 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "обчислена контрольна сума CRC не відповідає значенню, збереженому у файлі \"%s\"" + +#: access/transam/twophase.c:1342 access/transam/xlog.c:6494 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "Не вдалося розмістити обробник журналу транзакцій." + +#: access/transam/twophase.c:1349 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "не вдалося прочитати 2-фазовий стан з WAL при %X/%X" + +#: access/transam/twophase.c:1357 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "очікувані дані 2-фазного стану відсутні в WAL при %X/%X" + +#: access/transam/twophase.c:1637 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "не вдалося відтворити файл \"%s\": %m" + +#: access/transam/twophase.c:1764 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "%u 2-фазовий стан файлу був записаний завдяки довготривалій підготовленій транзакції" +msgstr[1] "%u 2-фазовий стан файлів був записаний завдяки довготривалим підготовленим транзакціям" +msgstr[2] "%u 2-фазовий стан файлів був записаний завдяки довготривалим підготовленим транзакціям" +msgstr[3] "%u 2-фазовий стан файлів був записаний завдяки довготривалим підготовленим транзакціям" + +#: access/transam/twophase.c:1998 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "відновлення підготовленої транзакції %u із спільної пам'яті" + +#: access/transam/twophase.c:2089 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "видалення застарілого файла 2-фазового стану для транзакції %u" + +#: access/transam/twophase.c:2096 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "видалення з пам'яті застарілого 2-фазового стану для транзакції %u" + +#: access/transam/twophase.c:2109 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "видалення файлу майбутнього 2-фазового стану для транзакції %u" + +#: access/transam/twophase.c:2116 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "видалення з пам'яті майбутнього 2-фазового стану для транзакції %u" + +#: access/transam/twophase.c:2141 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "пошкоджений файл двофазного стану для транзакції %u" + +#: access/transam/twophase.c:2146 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "пошкоджена пам'ять двофазного стану для транзакції %u" + +#: access/transam/varsup.c:127 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "база даних не приймає команди, щоб уникнути втрати даних через зациклення транзакцій в БД \"%s\"" + +#: access/transam/varsup.c:129 access/transam/varsup.c:136 +#, c-format +msgid "Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "Зупиніть postmaster і виконайте очищення (vacuum) бази даних в однокористувацькому режимі.\n" +"Можливо, також доведеться зафіксувати або відкотити назад старі підготовлені транзакції, або розірвати застарілі реплікаційні слоти." + +#: access/transam/varsup.c:134 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "база даних не приймає команди задля уникнення втрати даних через зациклення транзакцій в базі даних з OID %u" + +#: access/transam/varsup.c:146 access/transam/varsup.c:444 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "база даних \"%s\" повинна бути очищена (граничне число транзакцій: %u)" + +#: access/transam/varsup.c:153 access/transam/varsup.c:451 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "база даних з OID %u повинна бути очищена (граничне число транзакцій: %u)" + +#: access/transam/varsup.c:409 +#, c-format +msgid "transaction ID wrap limit is %u, limited by database with OID %u" +msgstr "обмеження зациклення транзакції ID %u, обмежена за допомогою бази даних з OID %u" + +#: access/transam/xact.c:1030 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "в одній транзакції не може бути більше 2^32-2 команд" + +#: access/transam/xact.c:1555 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "перевищено межу числа зафіксованих підтранзакцій (%d)" + +#: access/transam/xact.c:2395 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "неможливо виконати PREPARE для транзакції, що здійснювалася на тимчасових об'єктах" + +#: access/transam/xact.c:2405 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "не можна виконати PREPARE для транзакції, яка має експортовані знімки" + +#: access/transam/xact.c:2414 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "не можна виконати PREPARE для транзакції, яка маніпулює процесами логічної реплікації" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3359 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s неможливо запустити всередині блоку транзакції" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3369 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s неможливо запустити всередині підтранзакції" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3379 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s неможливо виконати з функції" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3448 access/transam/xact.c:3754 +#: access/transam/xact.c:3833 access/transam/xact.c:3956 +#: access/transam/xact.c:4107 access/transam/xact.c:4176 +#: access/transam/xact.c:4287 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s може використовуватися тільки в блоках транзакції" + +#: access/transam/xact.c:3640 +#, c-format +msgid "there is already a transaction in progress" +msgstr "транзакція вже виконується" + +#: access/transam/xact.c:3759 access/transam/xact.c:3838 +#: access/transam/xact.c:3961 +#, c-format +msgid "there is no transaction in progress" +msgstr "немає незавершеної транзакції" + +#: access/transam/xact.c:3849 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "не можна фіксувати транзакції під час паралельних операцій" + +#: access/transam/xact.c:3972 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "не можна перервати під час паралельних операцій" + +#: access/transam/xact.c:4071 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "не можна визначати точки збереження під час паралельних операцій" + +#: access/transam/xact.c:4158 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "не можна вивільняти точки збереження під час паралельних транзакцій" + +#: access/transam/xact.c:4168 access/transam/xact.c:4219 +#: access/transam/xact.c:4279 access/transam/xact.c:4328 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "точка збереження \"%s\" не існує" + +#: access/transam/xact.c:4225 access/transam/xact.c:4334 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "точка збереження \"%s\" не існує на поточному рівні збереження точок" + +#: access/transam/xact.c:4267 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "не можна відкотити назад до точки збереження під час паралельних операцій" + +#: access/transam/xact.c:4395 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "не можна запустити підтранзакцію під час паралельних операцій" + +#: access/transam/xact.c:4463 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "не можна визначити підтранзакцію під час паралельних операцій" + +#: access/transam/xact.c:5103 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "в одній транзакції не може бути більше 2^32-1 підтранзакцій" + +#: access/transam/xlog.c:2554 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "не вдалося записати у файл журналу %s (зсув: %u, довжина: %zu): %m" + +#: access/transam/xlog.c:2830 +#, c-format +msgid "updated min recovery point to %X/%X on timeline %u" +msgstr "мінімальна точка відновлення змінена на %X/%X на лінії часу %u" + +#: access/transam/xlog.c:3944 access/transam/xlogutils.c:802 +#: replication/walsender.c:2510 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "запитуваний сегмент WAL %s вже видалений" + +#: access/transam/xlog.c:4187 +#, c-format +msgid "recycled write-ahead log file \"%s\"" +msgstr "файл випереджувального журналювання \"%s\" використовується повторно" + +#: access/transam/xlog.c:4199 +#, c-format +msgid "removing write-ahead log file \"%s\"" +msgstr "файл випереджувального журналювання \"%s\" видаляється" + +#: access/transam/xlog.c:4219 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "не вдалося перейменувати файл \"%s\": %m" + +#: access/transam/xlog.c:4261 access/transam/xlog.c:4271 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "необхідний каталог WAL \"%s\" не існує" + +#: access/transam/xlog.c:4277 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "створюється відсутній каталог WAL \"%s\"" + +#: access/transam/xlog.c:4280 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "не вдалося створити відстуній каталог \"%s\": %m" + +#: access/transam/xlog.c:4383 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "неочіукваний ID лінії часу %u в сегменті журналу %s, зсув %u" + +#: access/transam/xlog.c:4521 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "нова лінія часу %u не є дочірньою для лінії часу системи бази даних %u" + +#: access/transam/xlog.c:4535 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "нова лінія часу %u відгалузилась від поточної лінії часу бази даних %u до поточної точки відновлення %X/%X" + +#: access/transam/xlog.c:4554 +#, c-format +msgid "new target timeline is %u" +msgstr "нова цільова лінія часу %u" + +#: access/transam/xlog.c:4590 +#, c-format +msgid "could not generate secret authorization token" +msgstr "не вдалося згенерувати секретний токен для авторизації" + +#: access/transam/xlog.c:4749 access/transam/xlog.c:4758 +#: access/transam/xlog.c:4782 access/transam/xlog.c:4789 +#: access/transam/xlog.c:4796 access/transam/xlog.c:4801 +#: access/transam/xlog.c:4808 access/transam/xlog.c:4815 +#: access/transam/xlog.c:4822 access/transam/xlog.c:4829 +#: access/transam/xlog.c:4836 access/transam/xlog.c:4843 +#: access/transam/xlog.c:4852 access/transam/xlog.c:4859 +#: utils/init/miscinit.c:1548 +#, c-format +msgid "database files are incompatible with server" +msgstr "файли бази даних є несумісними з даним сервером" + +#: access/transam/xlog.c:4750 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "Кластер бази даних було ініціалізовано з PG_CONTROL_VERSION %d (0x%08x), але сервер було скомпільовано з PG_CONTROL_VERSION %d (0x%08x)." + +#: access/transam/xlog.c:4754 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "Можливо, проблема викликана різним порядком байту. Здається, вам потрібно виконати команду \"initdb\"." + +#: access/transam/xlog.c:4759 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "Кластер баз даних був ініціалізований з PG_CONTROL_VERSION %d, але сервер скомпільований з PG_CONTROL_VERSION %d." + +#: access/transam/xlog.c:4762 access/transam/xlog.c:4786 +#: access/transam/xlog.c:4793 access/transam/xlog.c:4798 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Здається, Вам треба виконати initdb." + +#: access/transam/xlog.c:4773 +#, c-format +msgid "incorrect checksum in control file" +msgstr "помилка контрольної суми у файлі pg_control" + +#: access/transam/xlog.c:4783 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "Кластер бази даних було ініціалізовано з CATALOG_VERSION_NO %d, але сервер було скомпільовано з CATALOG_VERSION_NO %d." + +#: access/transam/xlog.c:4790 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "Кластер бази даних було ініціалізовано з MAXALIGN %d, але сервер було скомпільовано з MAXALIGN %d." + +#: access/transam/xlog.c:4797 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "Здається, в кластері баз даних і в програмі сервера використовуються різні формати чисел з плаваючою точкою." + +#: access/transam/xlog.c:4802 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "Кластер бази даних було ініціалізовано з BLCKSZ %d, але сервер було скомпільовано з BLCKSZ %d." + +#: access/transam/xlog.c:4805 access/transam/xlog.c:4812 +#: access/transam/xlog.c:4819 access/transam/xlog.c:4826 +#: access/transam/xlog.c:4833 access/transam/xlog.c:4840 +#: access/transam/xlog.c:4847 access/transam/xlog.c:4855 +#: access/transam/xlog.c:4862 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Здається, вам потрібно перекомпілювати сервер або виконати initdb." + +#: access/transam/xlog.c:4809 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "Кластер бази даних було ініціалізовано з ELSEG_SIZE %d, але сервер було скомпільовано з ELSEG_SIZE %d." + +#: access/transam/xlog.c:4816 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "Кластер бази даних було ініціалізовано з XLOG_BLCKSZ %d, але сервер було скомпільовано з XLOG_BLCKSZ %d." + +#: access/transam/xlog.c:4823 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "Кластер бази даних було ініціалізовано з NAMEDATALEN %d, але сервер було скомпільовано з NAMEDATALEN %d." + +#: access/transam/xlog.c:4830 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "Кластер бази даних було ініціалізовано з INDEX_MAX_KEYS %d, але сервер було скомпільовано з INDEX_MAX_KEYS %d." + +#: access/transam/xlog.c:4837 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "Кластер бази даних було ініціалізовано з TOAST_MAX_CHUNK_SIZE %d, але сервер було скомпільовано з TOAST_MAX_CHUNK_SIZE %d." + +#: access/transam/xlog.c:4844 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "Кластер бази даних було ініціалізовано з LOBLKSIZE %d, але сервер було скомпільовано з LOBLKSIZE %d." + +#: access/transam/xlog.c:4853 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "Кластер бази даних було ініціалізовано без USE_FLOAT8_BYVAL, але сервер було скомпільовано з USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4860 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "Кластер бази даних було ініціалізовано з USE_FLOAT8_BYVAL, але сервер було скомпільовано без USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4869 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" +msgstr[1] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" +msgstr[2] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" +msgstr[3] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" + +#: access/transam/xlog.c:4881 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" має бути мінімум у 2 рази більше, ніж \"wal_segment_size\"" + +#: access/transam/xlog.c:4885 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" має бути мінімум у 2 рази більше, ніж \"wal_segment_size\"" + +#: access/transam/xlog.c:5318 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "не вдалося записати початкове завантаження випереджувального журналювання: %m" + +#: access/transam/xlog.c:5326 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "не вдалося скинути на диск початкове завантаження випереджувального журналювання: %m" + +#: access/transam/xlog.c:5332 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "не вдалося закрити початкове завантаження випереджувального журналювання: %m" + +#: access/transam/xlog.c:5393 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "використання файлу команд відновлення \"%s\" не підтримується" + +#: access/transam/xlog.c:5458 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "режим очікування не підтримується однокористувацьким сервером" + +#: access/transam/xlog.c:5475 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "не заззначено ані параметр primary_conninfo, ані параметр restore_command" + +#: access/transam/xlog.c:5476 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "Сервер бази даних буде регулярно опитувати підкатолог pg_wal і перевіряти файли, що містяться у ньому." + +#: access/transam/xlog.c:5484 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "необхідно вказати restore_command, якщо не ввімкнено режиму очікування" + +#: access/transam/xlog.c:5522 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "цільова лінія часу відновлення %u не існує" + +#: access/transam/xlog.c:5644 +#, c-format +msgid "archive recovery complete" +msgstr "відновлення архіву завершено" + +#: access/transam/xlog.c:5710 access/transam/xlog.c:5983 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "відновлення зупиняється після досягнення узгодженості" + +#: access/transam/xlog.c:5731 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "відновлення зупиняється перед позицією WAL (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5817 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "відновлення припиняється до підтвердження транзакції %u, час %s" + +#: access/transam/xlog.c:5824 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "відновлення припиняється до скасування транзакції %u, час %s" + +#: access/transam/xlog.c:5877 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "відновлення припиняється в точці відновлення\"%s\", час %s" + +#: access/transam/xlog.c:5895 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "відновлення припиняється пісня локації WAL (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5963 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "відновлення припиняється після підтвердження транзакції %u, час %s" + +#: access/transam/xlog.c:5971 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "відновлення припиняється після скасування транзакції %u, час %s" + +#: access/transam/xlog.c:6020 +#, c-format +msgid "pausing at the end of recovery" +msgstr "призупинення в кінці відновлення" + +#: access/transam/xlog.c:6021 +#, c-format +msgid "Execute pg_wal_replay_resume() to promote." +msgstr "Виконайте pg_wal_replay_resume() для просування." + +#: access/transam/xlog.c:6024 +#, c-format +msgid "recovery has paused" +msgstr "відновлення зупинено" + +#: access/transam/xlog.c:6025 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Виконайте pg_wal_replay_resume(), щоб продовжити." + +#: access/transam/xlog.c:6242 +#, c-format +msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" +msgstr "hot standby неможливий, так як параметр %s = %d менший, ніж на головному сервері (його значення було %d)" + +#: access/transam/xlog.c:6266 +#, c-format +msgid "WAL was generated with wal_level=minimal, data may be missing" +msgstr "WAL був створений з параметром wal_level=minimal, можлива втрата даних" + +#: access/transam/xlog.c:6267 +#, c-format +msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgstr "Це трапляється, якщо ви тимчасово встановили wal_level=minimal і не зробили резервну копію бази даних." + +#: access/transam/xlog.c:6278 +#, c-format +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgstr "hot standby неможливий, так як на головному сервері встановлений невідповідний wal_level (повинен бути \"replica\" або вище)" + +#: access/transam/xlog.c:6279 +#, c-format +msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +msgstr "Або встановіть для wal_level значення \"replica\" на головному сервері, або вимкніть hot_standby тут." + +#: access/transam/xlog.c:6341 +#, c-format +msgid "control file contains invalid checkpoint location" +msgstr "контрольний файл містить неприпустиме розташування контрольної точки" + +#: access/transam/xlog.c:6352 +#, c-format +msgid "database system was shut down at %s" +msgstr "система бази даних була вимкнена %s" + +#: access/transam/xlog.c:6358 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "система бази даних завершила роботу у процесі відновлення %s" + +#: access/transam/xlog.c:6364 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "завершення роботи бази даних було перервано; останній момент роботи %s" + +#: access/transam/xlog.c:6370 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "система бази даних була перервана в процесі відновлення %s" + +#: access/transam/xlog.c:6372 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "Це, ймовірно, означає, що деякі дані були пошкоджені, і вам доведеться відновити базу даних з останнього збереження." + +#: access/transam/xlog.c:6378 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "робота системи бази даних була перервана в процесі відновлення, час в журналі %s" + +#: access/transam/xlog.c:6380 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "Якщо це відбувається більше, ніж один раз, можливо, якісь дані були зіпсовані, і для відновлення треба вибрати більш ранню точку." + +#: access/transam/xlog.c:6386 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "робота системи бази даних була перервана; останній момент роботи %s" + +#: access/transam/xlog.c:6392 +#, c-format +msgid "control file contains invalid database cluster state" +msgstr "контрольний файл містить неприпустимий стан кластеру бази даних" + +#: access/transam/xlog.c:6449 +#, c-format +msgid "entering standby mode" +msgstr "перехід у режим очікування" + +#: access/transam/xlog.c:6452 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "починається відновлення точки в часі до XID %u" + +#: access/transam/xlog.c:6456 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "починається відновлення точки в часі до %s" + +#: access/transam/xlog.c:6460 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "починається відновлення точки в часі до \"%s\"" + +#: access/transam/xlog.c:6464 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "починається відновлення точки в часі до локації WAL (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:6469 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "починається відновлення даних до першої точки домовленості" + +#: access/transam/xlog.c:6472 +#, c-format +msgid "starting archive recovery" +msgstr "початок відновлення архіву" + +#: access/transam/xlog.c:6531 access/transam/xlog.c:6664 +#, c-format +msgid "checkpoint record is at %X/%X" +msgstr "запис контрольної точки є на %X/%X" + +#: access/transam/xlog.c:6546 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "не вдалося знайти положення REDO, вказане записом контрольної точки" + +#: access/transam/xlog.c:6547 access/transam/xlog.c:6557 +#, c-format +msgid "If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "Якщо ви відновлюєте з резервної копії, оновіть файл \"%s/recovery.signal\" та додайте необхідні параметри відновлення.\n" +"Якщо ви не відновлюєте з резервної копії, спробуйте видалити файл \"%s/backup_label\".\n" +"Будьте обережні: видалення \"%s/backup_label\" призведе до пошкодження кластеру при відновленні з резервної копії." + +#: access/transam/xlog.c:6556 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "не вдалося знайти запис потрібної контрольної точки" + +#: access/transam/xlog.c:6585 commands/tablespace.c:654 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "не вдалося створити символічне послання \"%s\": %m" + +#: access/transam/xlog.c:6617 access/transam/xlog.c:6623 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "файл \"%s\" ігнорується, тому що файлу \"%s\" не існує" + +#: access/transam/xlog.c:6619 access/transam/xlog.c:11828 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "Файл \"%s\" був перейменований на \"%s\"." + +#: access/transam/xlog.c:6625 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "Неможливо перейменувати файл \"%s\" на \"%s\": %m." + +#: access/transam/xlog.c:6676 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "не вдалося знайти запис допустимої контрольної точки" + +#: access/transam/xlog.c:6714 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "запитувана лінія часу %u не є відгалуженням історії цього серверу" + +#: access/transam/xlog.c:6716 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "Остання контрольна точка %X/%X на лінії часу %u, але в історії запитуваної лінії часу сервер відгалузився з цієї лінії в %X/%X." + +#: access/transam/xlog.c:6732 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "запитувана лінія часу %u не містить мінімальну точку відновлення %X/%X на лінії часу %u" + +#: access/transam/xlog.c:6763 +#, c-format +msgid "invalid next transaction ID" +msgstr "невірний ID наступної транзакції" + +#: access/transam/xlog.c:6857 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "невірний запис REDO в контрольній точці" + +#: access/transam/xlog.c:6868 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "невірний запис REDO в контрольній точці вимкнення" + +#: access/transam/xlog.c:6902 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "робота системи бази даних не була завершена належним чином; відбувається автоматичне відновлення" + +#: access/transam/xlog.c:6906 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "відновлення після збою починається на лінії часу %u і має цільову лінію часу: %u" + +#: access/transam/xlog.c:6953 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label містить дані, які не узгоджені з файлом pg_control" + +#: access/transam/xlog.c:6954 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "Це означає, що резервна копія була пошкоджена і вам доведеться використати іншу резервну копію для відновлення." + +#: access/transam/xlog.c:7045 +#, c-format +msgid "initializing for hot standby" +msgstr "ініціалізація для hot standby" + +#: access/transam/xlog.c:7178 +#, c-format +msgid "redo starts at %X/%X" +msgstr "запис REDO починається з %X/%X" + +#: access/transam/xlog.c:7402 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "запитувана точка відновлення передує узгодженій точці відновлення" + +#: access/transam/xlog.c:7440 +#, c-format +msgid "redo done at %X/%X" +msgstr "записи REDO оброблені до %X/%X" + +#: access/transam/xlog.c:7445 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "остання завершена транзакція була в %s" + +#: access/transam/xlog.c:7454 +#, c-format +msgid "redo is not required" +msgstr "дані REDO не потрібні" + +#: access/transam/xlog.c:7466 +#, c-format +msgid "recovery ended before configured recovery target was reached" +msgstr "відновлення завершилось до досягення налаштованої мети відновлення" + +#: access/transam/xlog.c:7545 access/transam/xlog.c:7549 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "WAL завершився до завершення онлайн резервного копіювання" + +#: access/transam/xlog.c:7546 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "Всі журнали WAL, створені під час резервного копіювання \"на ходу\", повинні бути в наявності для відновлення." + +#: access/transam/xlog.c:7550 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "Резервне копіювання БД \"на ходу\", розпочате за допомогою команди \"pg_start_backup()\", повинне завершуватися командою \"pg_stop_backup()\", і для відновлення повинні бути доступні усі журнали WAL. " + +#: access/transam/xlog.c:7553 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL завершився до узгодженої точки відновлення" + +#: access/transam/xlog.c:7588 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "вибрано новий ID часової лінії: %u" + +#: access/transam/xlog.c:8036 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "узгоджений стан відновлення досягнутий %X/%X" + +#: access/transam/xlog.c:8246 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "невірне посилання на первинну контрольну точку в контрольному файлі" + +#: access/transam/xlog.c:8250 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "невірне посилання на контрольну точку в файлі backup_label" + +#: access/transam/xlog.c:8268 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "невірний запис первинної контрольної точки" + +#: access/transam/xlog.c:8272 +#, c-format +msgid "invalid checkpoint record" +msgstr "невірний запис контрольної точки" + +#: access/transam/xlog.c:8283 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "невірний ID менеджера ресурсів в записі первинної контрольної точки" + +#: access/transam/xlog.c:8287 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "невірний ID менеджера ресурсів в записі контрольної точки" + +#: access/transam/xlog.c:8300 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "невірний xl_info у записі первинної контрольної точки" + +#: access/transam/xlog.c:8304 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "невірний xl_info у записі контрольної точки" + +#: access/transam/xlog.c:8315 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "невірна довжина запису первинної контрольної очки" + +#: access/transam/xlog.c:8319 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "невірна довжина запису контрольної точки" + +#: access/transam/xlog.c:8499 +#, c-format +msgid "shutting down" +msgstr "завершення роботи" + +#: access/transam/xlog.c:8819 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "контрольну точку пропущено, тому що система перебуває в режимі простоювання" + +#: access/transam/xlog.c:9019 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "під час того вимкнення БД помічено конкурентну активність у випереджувальному журналюванні" + +#: access/transam/xlog.c:9276 +#, c-format +msgid "skipping restartpoint, recovery has already ended" +msgstr "пропуск контрольної точки, відновлення вже завершено" + +#: access/transam/xlog.c:9299 +#, c-format +msgid "skipping restartpoint, already performed at %X/%X" +msgstr "створення точки перезапуску пропускається, вона вже створена в %X/%X" + +#: access/transam/xlog.c:9467 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "відновлення збереженої точки %X/%X" + +#: access/transam/xlog.c:9469 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Остання завершена транзакція була в %s." + +#: access/transam/xlog.c:9711 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "точка відновлення \"%s\" створена в %X/%X" + +#: access/transam/xlog.c:9856 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "несподіваний ID попередньої лінії часу %u (ID теперішньої лінії часу %u) в записі контрольної точки" + +#: access/transam/xlog.c:9865 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "неочікуваний ID лінії часу %u (після %u) в записі контрольної точки" + +#: access/transam/xlog.c:9881 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "неочікуваний ID лінії часу %u в записі контрольної точки, до досягнення мінімальної точки відновлення %X/%X на лінії часу %u" + +#: access/transam/xlog.c:9957 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "онлайн резервне копіювання скасовано, неможливо продовжити відновлення" + +#: access/transam/xlog.c:10013 access/transam/xlog.c:10069 +#: access/transam/xlog.c:10092 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "несподіваний ID лінії часу %u (повинен бути %u) в записі контрольної точки" + +#: access/transam/xlog.c:10418 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "не вдалосьясинхронізувати файл наскрізного запису %s: %m" + +#: access/transam/xlog.c:10424 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "не вдалося fdatasync файл \"%s\": %m" + +#: access/transam/xlog.c:10523 access/transam/xlog.c:11061 +#: access/transam/xlogfuncs.c:275 access/transam/xlogfuncs.c:302 +#: access/transam/xlogfuncs.c:341 access/transam/xlogfuncs.c:362 +#: access/transam/xlogfuncs.c:383 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "Функції управління WAL не можна використовувати під час відновлення." + +#: access/transam/xlog.c:10532 access/transam/xlog.c:11070 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "Обраний рівень WAL недостатній для резервного копіювання \"на ходу\"" + +#: access/transam/xlog.c:10533 access/transam/xlog.c:11071 +#: access/transam/xlogfuncs.c:308 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "встановіть wal_level \"replica\" або \"logical\" при запуску серверу." + +#: access/transam/xlog.c:10538 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "мітка резервного копіювання задовга (максимум %d байт)" + +#: access/transam/xlog.c:10575 access/transam/xlog.c:10860 +#: access/transam/xlog.c:10898 +#, c-format +msgid "a backup is already in progress" +msgstr "резервне копіювання вже триває" + +#: access/transam/xlog.c:10576 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "Запустіть pg_stop_backup() і спробуйте знову." + +#: access/transam/xlog.c:10672 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "Після останньої точки відновлення був відтворений WAL, створений в режимі full_page_writes=off" + +#: access/transam/xlog.c:10674 access/transam/xlog.c:11266 +#, c-format +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." +msgstr "Це означає, що резервна копія, зроблена на резервному сервері, зіпсована і її не слід використовувати. Активуйте режим full_page_writes та запустіть CHECKPOINT на головному сервері, а потім спробуйте резервне копіювання \"на ходу\" ще раз." + +#: access/transam/xlog.c:10757 replication/basebackup.c:1423 +#: utils/adt/misc.c:342 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "таргет символічного посилання \"%s\" задовгий" + +#: access/transam/xlog.c:10810 commands/tablespace.c:402 +#: commands/tablespace.c:566 replication/basebackup.c:1438 utils/adt/misc.c:350 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "табличний простір не підтримується на цій платформі" + +#: access/transam/xlog.c:10861 access/transam/xlog.c:10899 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "Якщо ви вважаєте, що жодне резервне копіювання не триває, видаліть файл \"%s\" і спробуйте знову." + +#: access/transam/xlog.c:11086 +#, c-format +msgid "exclusive backup not in progress" +msgstr "ексклюзивне резервне копіювання не виконується" + +#: access/transam/xlog.c:11113 +#, c-format +msgid "a backup is not in progress" +msgstr "резервне копіювання не виконується" + +#: access/transam/xlog.c:11199 access/transam/xlog.c:11212 +#: access/transam/xlog.c:11601 access/transam/xlog.c:11607 +#: access/transam/xlog.c:11655 access/transam/xlog.c:11728 +#: access/transam/xlogfuncs.c:692 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "невірні дані у файлі \"%s\"" + +#: access/transam/xlog.c:11216 replication/basebackup.c:1271 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "режим очікування було підвищено у процесі резервного копіювання \"на ходу\"" + +#: access/transam/xlog.c:11217 replication/basebackup.c:1272 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "Це означає, що вибрана резервна копія є пошкодженою і її не слід використовувати. Спробуйте використати іншу онлайн резервну копію." + +#: access/transam/xlog.c:11264 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "У процесі резервного копіювання \"на ходу\" був відтворений WAL, створений в режимі full_page_writes=off" + +#: access/transam/xlog.c:11384 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "резервне копіювання виконане, очікуються необхідні сегменти WAL для архівації" + +#: access/transam/xlog.c:11396 +#, c-format +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "все ще чекає на необхідні сегменти WAL для архівації (%d секунд пройшло)" + +#: access/transam/xlog.c:11398 +#, c-format +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "Перевірте, чи правильно виконується команда archive_command. Ви можете безпечно скасувати це резервне копіювання, але резервна копія БД буде непридатна без усіх сегментів WAL." + +#: access/transam/xlog.c:11405 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "усі необхідні сегменти WAL архівовані" + +#: access/transam/xlog.c:11409 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "архівація WAL не налаштована; ви повинні забезпечити копіювання всіх необхідних сегментів WAL іншими засобами для отримання резервної копії" + +#: access/transam/xlog.c:11462 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "припинення резервного копіювання через завершення обслуговуючого процесу до виклику pg_stop_backup" + +#: access/transam/xlog.c:11638 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "час резервного копіювання %s у файлі \"%s\"" + +#: access/transam/xlog.c:11643 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "мітка резервного копіювання %s у файлі \"%s\"" + +#: access/transam/xlog.c:11656 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u." +msgstr "Проаналізовано ID часової лінії %u, очіувалося %u." + +#: access/transam/xlog.c:11660 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "лінія часу резервного копіювання %u у файлі \"%s\"" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11768 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "запис REDO в WAL в позиції %X/%X для %s" + +#: access/transam/xlog.c:11817 +#, c-format +msgid "online backup mode was not canceled" +msgstr "режим копіювання онлайн не був відмінений" + +#: access/transam/xlog.c:11818 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "Файл \"%s\" не може бути перейменований на \"%s\": %m." + +#: access/transam/xlog.c:11827 access/transam/xlog.c:11839 +#: access/transam/xlog.c:11849 +#, c-format +msgid "online backup mode canceled" +msgstr "режим копіювання онлайн був відмінений" + +#: access/transam/xlog.c:11840 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "Файли \"%s\" і \"%s\" було перейменовано на \"%s\" і \"%s\" відповідно." + +#: access/transam/xlog.c:11850 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "Файл \"%s\" було перейменовано на \"%s\", але файл \"%s\" не можливо перейменувати на \"%s\": %m." + +#: access/transam/xlog.c:11983 access/transam/xlogutils.c:971 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "не вдалося прочитати сегмент журналу %s, зсув %u: %m" + +#: access/transam/xlog.c:11989 access/transam/xlogutils.c:978 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "не вдалося прочитати сегмент журналу %s, зсув %u: прочитано %d з %zu" + +#: access/transam/xlog.c:12518 +#, c-format +msgid "WAL receiver process shutdown requested" +msgstr "Запитано відключення процесу приймача WAL" + +#: access/transam/xlog.c:12624 +#, c-format +msgid "received promote request" +msgstr "отримано запит підвищення статусу" + +#: access/transam/xlog.c:12637 +#, c-format +msgid "promote trigger file found: %s" +msgstr "знайдено файл тригера підвищення: %s" + +#: access/transam/xlog.c:12646 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "не вдалося отримати інформацію про файл тригера підвищення \"%s\": %m" + +#: access/transam/xlogarchive.c:205 +#, c-format +msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgstr "файл архіву \"%s\" має неправильний розмір: %lu замість %lu" + +#: access/transam/xlogarchive.c:214 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "відновлений файл журналу \"%s\" з архіву" + +#: access/transam/xlogarchive.c:259 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "неможливо відновити файл \"%s\" з архіву: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:368 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" + +#: access/transam/xlogarchive.c:478 access/transam/xlogarchive.c:542 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "неможливо створити файл статусу архіву \"%s\": %m" + +#: access/transam/xlogarchive.c:486 access/transam/xlogarchive.c:550 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "неможливо записати файл архівного статусу \"%s\": %m" + +#: access/transam/xlogfuncs.c:74 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "резервне копіювання наразі триває в цьому сеансі" + +#: access/transam/xlogfuncs.c:132 access/transam/xlogfuncs.c:213 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "виконується не ексклюзивне резервне копіювання" + +#: access/transam/xlogfuncs.c:133 access/transam/xlogfuncs.c:214 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "Ви мали на увазі використаня pg_stop_backup('f')?" + +#: access/transam/xlogfuncs.c:185 commands/event_trigger.c:1332 +#: commands/event_trigger.c:1890 commands/extension.c:1944 +#: commands/extension.c:2052 commands/extension.c:2337 commands/prepare.c:712 +#: executor/execExpr.c:2203 executor/execSRF.c:728 executor/functions.c:1046 +#: foreign/foreign.c:520 libpq/hba.c:2666 replication/logical/launcher.c:1086 +#: replication/logical/logicalfuncs.c:157 replication/logical/origin.c:1486 +#: replication/slotfuncs.c:252 replication/walsender.c:3265 +#: storage/ipc/shmem.c:550 utils/adt/datetime.c:4765 utils/adt/genfile.c:505 +#: utils/adt/genfile.c:588 utils/adt/jsonfuncs.c:1792 +#: utils/adt/jsonfuncs.c:1904 utils/adt/jsonfuncs.c:2092 +#: utils/adt/jsonfuncs.c:2201 utils/adt/jsonfuncs.c:3663 utils/adt/misc.c:215 +#: utils/adt/pgstatfuncs.c:476 utils/adt/pgstatfuncs.c:584 +#: utils/adt/pgstatfuncs.c:1719 utils/fmgr/funcapi.c:72 utils/misc/guc.c:9648 +#: utils/mmgr/portalmem.c:1136 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "функція \"set-valued\" викликана в контексті, де йому немає місця" + +#: access/transam/xlogfuncs.c:189 commands/event_trigger.c:1336 +#: commands/event_trigger.c:1894 commands/extension.c:1948 +#: commands/extension.c:2056 commands/extension.c:2341 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2670 replication/logical/launcher.c:1090 +#: replication/logical/logicalfuncs.c:161 replication/logical/origin.c:1490 +#: replication/slotfuncs.c:256 replication/walsender.c:3269 +#: storage/ipc/shmem.c:554 utils/adt/datetime.c:4769 utils/adt/genfile.c:509 +#: utils/adt/genfile.c:592 utils/adt/misc.c:219 utils/adt/pgstatfuncs.c:480 +#: utils/adt/pgstatfuncs.c:588 utils/adt/pgstatfuncs.c:1723 +#: utils/misc/guc.c:9652 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1140 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "необхідний режим матеріалізації (materialize mode), але він неприпустимий у цьому контексті" + +#: access/transam/xlogfuncs.c:230 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "не ексклюзивне резервне копіювання не виконується" + +#: access/transam/xlogfuncs.c:231 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "Ви мали на увазі використаня pg_stop_backup('t')?" + +#: access/transam/xlogfuncs.c:307 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "Обраний рівень WAL не достатній для створення точки відновлення" + +#: access/transam/xlogfuncs.c:315 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "значення для точки відновлення перевищує межу (%d симв.)" + +#: access/transam/xlogfuncs.c:453 access/transam/xlogfuncs.c:510 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "%s не можна використовувати під час відновлення." + +#: access/transam/xlogfuncs.c:531 access/transam/xlogfuncs.c:558 +#: access/transam/xlogfuncs.c:582 access/transam/xlogfuncs.c:722 +#, c-format +msgid "recovery is not in progress" +msgstr "відновлення не виконується" + +#: access/transam/xlogfuncs.c:532 access/transam/xlogfuncs.c:559 +#: access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "Функції управління відновленням можна використовувати тільки під час відновлення." + +#: access/transam/xlogfuncs.c:537 access/transam/xlogfuncs.c:564 +#, c-format +msgid "standby promotion is ongoing" +msgstr "триває просування в режимі очікування" + +#: access/transam/xlogfuncs.c:538 access/transam/xlogfuncs.c:565 +#, c-format +msgid "%s cannot be executed after promotion is triggered." +msgstr "%s не може бути виконаний після того як просування запущено." + +#: access/transam/xlogfuncs.c:728 +#, c-format +msgid "\"wait_seconds\" must not be negative or zero" +msgstr "\"wait_seconds\" не має бути від'ємним чи нулем" + +#: access/transam/xlogfuncs.c:748 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "надіслати сигнал процесу postmaster не вдалося: %m" + +#: access/transam/xlogfuncs.c:784 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "сервер не підвищено протягом %d секунд" + +#: access/transam/xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "невірний зсув запису: %X/%X" + +#: access/transam/xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "по зсуву %X/%X запитано продовження запису" + +#: access/transam/xlogreader.c:398 access/transam/xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "невірна довжина запису по зсуву %X/%X: очікувалось %u, отримано %u" + +#: access/transam/xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "довжина запису %u на %X/%X є задовгою" + +#: access/transam/xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "немає флага contrecord в позиції %X/%X" + +#: access/transam/xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "невірна довижна contrecord (%u) в позиції %X/%X" + +#: access/transam/xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "невірний ID менеджера ресурсів %u в %X/%X" + +#: access/transam/xlogreader.c:717 access/transam/xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "запис з неправильним попереднім посиланням %X/%X на %X/%X" + +#: access/transam/xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "некоректна контрольна сума даних менеджера ресурсів у запису по зсуву %X/%X" + +#: access/transam/xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "невірне магічне число %04X в сегменті журналу %s, зсув %u" + +#: access/transam/xlogreader.c:822 access/transam/xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "невірні інформаційні біти %04X в сегменті журналу %s, зсув %u" + +#: access/transam/xlogreader.c:837 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL файл належить іншій системі баз даних: ідентифікатор системи баз даних де міститься WAL файл - %llu, а ідентифікатор системи баз даних pg_control - %llu" + +#: access/transam/xlogreader.c:845 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "Файл WAL належить іншій системі баз даних: некоректний розмір сегменту в заголовку сторінки" + +#: access/transam/xlogreader.c:851 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "Файл WAL належить іншій системі баз даних: некоректний XLOG_BLCKSZ в заголовку сторінки" + +#: access/transam/xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "неочікуваний pageaddr %X/%X в сегменті журналу %s, зсув %u" + +#: access/transam/xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "порушення послідовності ID лінії часу %u (після %u) в сегменті журналу %s, зсув %u" + +#: access/transam/xlogreader.c:1247 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "ідентифікатор блока %u out-of-order в позиції %X/%X" + +#: access/transam/xlogreader.c:1270 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA встановлений, але немає даних в позиції %X/%X" + +#: access/transam/xlogreader.c:1277 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA встановлений, але довжина даних дорівнює %u в позиції %X/%X" + +#: access/transam/xlogreader.c:1313 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE встановлений, але для пропуску задані: зсув %u, довжина %u, при довжині образу блока %u в позиції %X/%X" + +#: access/transam/xlogreader.c:1329 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE не встановлений, але для пропуску задані: зсув %u, довжина %u в позиції %X/%X" + +#: access/transam/xlogreader.c:1344 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED встановлений, але довжина образу блока дорівнює %u в позиції %X/%X" + +#: access/transam/xlogreader.c:1359 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "ні BKPIMAGE_HAS_HOLE, ні BKPIMAGE_IS_COMPRESSED не встановлені, але довжина образу блока дорвінює %u в позиції %X/%X" + +#: access/transam/xlogreader.c:1375 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL встановлений, але попереднє значення не задано в позиції %X/%X" + +#: access/transam/xlogreader.c:1387 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "невірний ідентифікатор блоку %u в позиції %X/%X" + +#: access/transam/xlogreader.c:1476 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "запис з невірною довжиною на %X/%X" + +#: access/transam/xlogreader.c:1565 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "невірно стиснутий образ в позиції %X/%X, блок %d" + +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "для -X необхідне число, яке дорівнює ступеню 2 в інтервалі від 1 МБ до 1 ГБ" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:842 tcop/postgres.c:3705 +#, c-format +msgid "--%s requires a value" +msgstr "--%s необхідне значення" + +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:847 tcop/postgres.c:3710 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s необхідне значення" + +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:859 +#: postmaster/postmaster.c:872 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: bootstrap/bootstrap.c:313 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: невірні аргументи командного рядка\n" + +#: catalog/aclchk.c:181 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "право надання прав можна надавати тільки ролям" + +#: catalog/aclchk.c:300 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "для стовпця \"%s\" відношення \"%s\" не призначено ніяких прав" + +#: catalog/aclchk.c:305 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "для \"%s\" не призначено ніяких прав" + +#: catalog/aclchk.c:313 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "для стовпця \"%s\" відношення \"%s\" призначено не всі права" + +#: catalog/aclchk.c:318 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "для \"%s\" призначено не всі права" + +#: catalog/aclchk.c:329 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "для стовпця \"%s\" відношення \"%s\" жодні права не можуть бути відкликані" + +#: catalog/aclchk.c:334 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "для \"%s\" жодні права не можуть бути відкликані" + +#: catalog/aclchk.c:342 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "для стовпця \"%s\" відношення \"%s\" не всі права можуть бути відкликані" + +#: catalog/aclchk.c:347 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "для \"%s\" не всі права можуть бути відкликані" + +#: catalog/aclchk.c:430 catalog/aclchk.c:973 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "недійсний тип права %s для відношення" + +#: catalog/aclchk.c:434 catalog/aclchk.c:977 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "невірний тип права %s для послідовності" + +#: catalog/aclchk.c:438 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "недійсний тип права %s для бази даних" + +#: catalog/aclchk.c:442 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "недійсний тип права %s для домену" + +#: catalog/aclchk.c:446 catalog/aclchk.c:981 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "недійсний тип права %s для функції" + +#: catalog/aclchk.c:450 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "недійсний тип права %s для мови" + +#: catalog/aclchk.c:454 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "недійсний тип права %s для великого об'єкту" + +#: catalog/aclchk.c:458 catalog/aclchk.c:997 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "недійсний тип права %s для схеми" + +#: catalog/aclchk.c:462 catalog/aclchk.c:985 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "недійсний тип права %s для процедури" + +#: catalog/aclchk.c:466 catalog/aclchk.c:989 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "недійсний тип права %s для підпрограми" + +#: catalog/aclchk.c:470 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "недійсний тип права %s для табличного простору" + +#: catalog/aclchk.c:474 catalog/aclchk.c:993 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "недійсний тип права %s для типу" + +#: catalog/aclchk.c:478 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "недійсний тип права %s для джерела сторонніх даних" + +#: catalog/aclchk.c:482 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "недійсний тип права %s для стороннього серверу" + +#: catalog/aclchk.c:521 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "права стовпця дійсні тільки для відношень" + +#: catalog/aclchk.c:681 catalog/aclchk.c:4100 catalog/aclchk.c:4882 +#: catalog/objectaddress.c:965 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:285 +#, c-format +msgid "large object %u does not exist" +msgstr "великий об'єкт %u не існує" + +#: catalog/aclchk.c:910 catalog/aclchk.c:919 commands/collationcmds.c:118 +#: commands/copy.c:1134 commands/copy.c:1154 commands/copy.c:1163 +#: commands/copy.c:1172 commands/copy.c:1181 commands/copy.c:1190 +#: commands/copy.c:1199 commands/copy.c:1208 commands/copy.c:1226 +#: commands/copy.c:1242 commands/copy.c:1262 commands/copy.c:1279 +#: commands/dbcommands.c:157 commands/dbcommands.c:166 +#: commands/dbcommands.c:175 commands/dbcommands.c:184 +#: commands/dbcommands.c:193 commands/dbcommands.c:202 +#: commands/dbcommands.c:211 commands/dbcommands.c:220 +#: commands/dbcommands.c:229 commands/dbcommands.c:238 +#: commands/dbcommands.c:260 commands/dbcommands.c:1502 +#: commands/dbcommands.c:1511 commands/dbcommands.c:1520 +#: commands/dbcommands.c:1529 commands/extension.c:1735 +#: commands/extension.c:1745 commands/extension.c:1755 +#: commands/extension.c:3055 commands/foreigncmds.c:539 +#: commands/foreigncmds.c:548 commands/functioncmds.c:570 +#: commands/functioncmds.c:736 commands/functioncmds.c:745 +#: commands/functioncmds.c:754 commands/functioncmds.c:763 +#: commands/functioncmds.c:2014 commands/functioncmds.c:2022 +#: commands/publicationcmds.c:90 commands/publicationcmds.c:133 +#: commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 +#: commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 +#: commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:104 commands/subscriptioncmds.c:114 +#: commands/subscriptioncmds.c:124 commands/subscriptioncmds.c:134 +#: commands/subscriptioncmds.c:148 commands/subscriptioncmds.c:159 +#: commands/subscriptioncmds.c:173 commands/tablecmds.c:7102 +#: commands/typecmds.c:322 commands/typecmds.c:1355 commands/typecmds.c:1364 +#: commands/typecmds.c:1372 commands/typecmds.c:1380 commands/typecmds.c:1388 +#: commands/user.c:133 commands/user.c:147 commands/user.c:156 +#: commands/user.c:165 commands/user.c:174 commands/user.c:183 +#: commands/user.c:192 commands/user.c:201 commands/user.c:210 +#: commands/user.c:219 commands/user.c:228 commands/user.c:237 +#: commands/user.c:246 commands/user.c:582 commands/user.c:590 +#: commands/user.c:598 commands/user.c:606 commands/user.c:614 +#: commands/user.c:622 commands/user.c:630 commands/user.c:638 +#: commands/user.c:647 commands/user.c:655 commands/user.c:663 +#: parser/parse_utilcmd.c:387 replication/pgoutput/pgoutput.c:141 +#: replication/pgoutput/pgoutput.c:162 replication/walsender.c:886 +#: replication/walsender.c:897 replication/walsender.c:907 +#, c-format +msgid "conflicting or redundant options" +msgstr "конфліктуючі або надлишкові параметри" + +#: catalog/aclchk.c:1030 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "права за замовчуванням не можна встановити для стовпців" + +#: catalog/aclchk.c:1190 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "речення IN SCHEMA не можна використати в GRANT/REVOKE ON SCHEMAS" + +#: catalog/aclchk.c:1558 catalog/catalog.c:506 catalog/objectaddress.c:1427 +#: commands/analyze.c:389 commands/copy.c:5080 commands/sequence.c:1702 +#: commands/tablecmds.c:6578 commands/tablecmds.c:6721 +#: commands/tablecmds.c:6771 commands/tablecmds.c:6845 +#: commands/tablecmds.c:6915 commands/tablecmds.c:7027 +#: commands/tablecmds.c:7121 commands/tablecmds.c:7180 +#: commands/tablecmds.c:7253 commands/tablecmds.c:7282 +#: commands/tablecmds.c:7437 commands/tablecmds.c:7519 +#: commands/tablecmds.c:7612 commands/tablecmds.c:7767 +#: commands/tablecmds.c:10972 commands/tablecmds.c:11154 +#: commands/tablecmds.c:11314 commands/tablecmds.c:12397 commands/trigger.c:876 +#: parser/analyze.c:2339 parser/parse_relation.c:713 parser/parse_target.c:1036 +#: parser/parse_type.c:144 parser/parse_utilcmd.c:3289 +#: parser/parse_utilcmd.c:3324 parser/parse_utilcmd.c:3366 utils/adt/acl.c:2870 +#: utils/adt/ruleutils.c:2535 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "стовпець \"%s\" відношення \"%s\" не існує" + +#: catalog/aclchk.c:1821 catalog/objectaddress.c:1267 commands/sequence.c:1140 +#: commands/tablecmds.c:236 commands/tablecmds.c:15706 utils/adt/acl.c:2060 +#: utils/adt/acl.c:2090 utils/adt/acl.c:2122 utils/adt/acl.c:2154 +#: utils/adt/acl.c:2182 utils/adt/acl.c:2212 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "\"%s\" не є послідовністю" + +#: catalog/aclchk.c:1859 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "послідовність \"%s\" підтримує тільки права USAGE, SELECT і UPDATE" + +#: catalog/aclchk.c:1876 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "недійсний тип права %s для таблиці" + +#: catalog/aclchk.c:2042 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "недійсний тип права %s для стовпця" + +#: catalog/aclchk.c:2055 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "послідовність \"%s\" підтримує тільки право стовпця SELECT" + +#: catalog/aclchk.c:2637 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "мова \"%s\" не є довіреною" + +#: catalog/aclchk.c:2639 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "GRANT і REVOKE не допустимі для недовірених мов, тому що тільки суперкористувачі можуть використовувати недовірені мови." + +#: catalog/aclchk.c:3153 +#, c-format +msgid "cannot set privileges of array types" +msgstr "не можна встановити права для типів масивів" + +#: catalog/aclchk.c:3154 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Замість цього встановіть права для типу елементу." + +#: catalog/aclchk.c:3161 catalog/objectaddress.c:1561 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "\"%s\" не є доменом" + +#: catalog/aclchk.c:3281 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "нерозпізнане право \"%s\"" + +#: catalog/aclchk.c:3342 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "немає дозволу для агрегату %s" + +#: catalog/aclchk.c:3345 +#, c-format +msgid "permission denied for collation %s" +msgstr "немає дозволу для сортування %s" + +#: catalog/aclchk.c:3348 +#, c-format +msgid "permission denied for column %s" +msgstr "немає дозволу для стовпця %s" + +#: catalog/aclchk.c:3351 +#, c-format +msgid "permission denied for conversion %s" +msgstr "немає дозволу для перетворення %s" + +#: catalog/aclchk.c:3354 +#, c-format +msgid "permission denied for database %s" +msgstr "немає доступу для бази даних %s" + +#: catalog/aclchk.c:3357 +#, c-format +msgid "permission denied for domain %s" +msgstr "немає дозволу для домену %s" + +#: catalog/aclchk.c:3360 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "немає дозволу для тригера подій %s" + +#: catalog/aclchk.c:3363 +#, c-format +msgid "permission denied for extension %s" +msgstr "немає дозволу для розширення %s" + +#: catalog/aclchk.c:3366 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "немає дозволу для джерела сторонніх даних %s" + +#: catalog/aclchk.c:3369 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "немає дозволу для стороннього серверу %s" + +#: catalog/aclchk.c:3372 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "немає дозволу для сторонньої таблиці %s" + +#: catalog/aclchk.c:3375 +#, c-format +msgid "permission denied for function %s" +msgstr "немає дозволу для функції %s" + +#: catalog/aclchk.c:3378 +#, c-format +msgid "permission denied for index %s" +msgstr "немає дозволу для індексу %s" + +#: catalog/aclchk.c:3381 +#, c-format +msgid "permission denied for language %s" +msgstr "немає дозволу для мови %s" + +#: catalog/aclchk.c:3384 +#, c-format +msgid "permission denied for large object %s" +msgstr "немає дозволу для великого об'єкту %s" + +#: catalog/aclchk.c:3387 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "немає дозволу для матеріалізованого подання %s" + +#: catalog/aclchk.c:3390 +#, c-format +msgid "permission denied for operator class %s" +msgstr "немає дозволу для класу операторів %s" + +#: catalog/aclchk.c:3393 +#, c-format +msgid "permission denied for operator %s" +msgstr "немає дозволу для оператора %s" + +#: catalog/aclchk.c:3396 +#, c-format +msgid "permission denied for operator family %s" +msgstr "немає дозволу для сімейства операторів %s" + +#: catalog/aclchk.c:3399 +#, c-format +msgid "permission denied for policy %s" +msgstr "немає дозволу для політики %s" + +#: catalog/aclchk.c:3402 +#, c-format +msgid "permission denied for procedure %s" +msgstr "немає дозволу для процедури %s" + +#: catalog/aclchk.c:3405 +#, c-format +msgid "permission denied for publication %s" +msgstr "немає дозволу для публікації %s" + +#: catalog/aclchk.c:3408 +#, c-format +msgid "permission denied for routine %s" +msgstr "немає дозволу для підпрограми %s" + +#: catalog/aclchk.c:3411 +#, c-format +msgid "permission denied for schema %s" +msgstr "немає дозволу для схеми %s" + +#: catalog/aclchk.c:3414 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 +#: commands/sequence.c:1864 +#, c-format +msgid "permission denied for sequence %s" +msgstr "немає дозволу для послідовності %s" + +#: catalog/aclchk.c:3417 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "немає дозволу для об'єкту статистики %s" + +#: catalog/aclchk.c:3420 +#, c-format +msgid "permission denied for subscription %s" +msgstr "немає дозволу для підписки %s" + +#: catalog/aclchk.c:3423 +#, c-format +msgid "permission denied for table %s" +msgstr "немає дозволу для таблиці %s" + +#: catalog/aclchk.c:3426 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "немає дозволу для табличного простору %s" + +#: catalog/aclchk.c:3429 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "немає дозволу для конфігурації текстового пошуку %s" + +#: catalog/aclchk.c:3432 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "немає дозволу для словника текстового пошуку %s" + +#: catalog/aclchk.c:3435 +#, c-format +msgid "permission denied for type %s" +msgstr "немає дозволу для типу %s" + +#: catalog/aclchk.c:3438 +#, c-format +msgid "permission denied for view %s" +msgstr "немає дозволу для подання %s" + +#: catalog/aclchk.c:3473 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "треба бути власником агрегату %s" + +#: catalog/aclchk.c:3476 +#, c-format +msgid "must be owner of collation %s" +msgstr "треба бути власником правил сортування %s" + +#: catalog/aclchk.c:3479 +#, c-format +msgid "must be owner of conversion %s" +msgstr "треба бути власником перетворення %s" + +#: catalog/aclchk.c:3482 +#, c-format +msgid "must be owner of database %s" +msgstr "треба бути власником бази даних %s" + +#: catalog/aclchk.c:3485 +#, c-format +msgid "must be owner of domain %s" +msgstr "треба бути власником домену %s" + +#: catalog/aclchk.c:3488 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "треба бути власником тригеру подій %s" + +#: catalog/aclchk.c:3491 +#, c-format +msgid "must be owner of extension %s" +msgstr "треба бути власником розширення %s" + +#: catalog/aclchk.c:3494 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "треба бути власником джерела сторонніх даних %s" + +#: catalog/aclchk.c:3497 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "треба бути власником стороннього серверу %s" + +#: catalog/aclchk.c:3500 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "треба бути власником сторонньої таблиці %s" + +#: catalog/aclchk.c:3503 +#, c-format +msgid "must be owner of function %s" +msgstr "треба бути власником функції %s" + +#: catalog/aclchk.c:3506 +#, c-format +msgid "must be owner of index %s" +msgstr "треба бути власником індексу %s" + +#: catalog/aclchk.c:3509 +#, c-format +msgid "must be owner of language %s" +msgstr "треба бути власником мови %s" + +#: catalog/aclchk.c:3512 +#, c-format +msgid "must be owner of large object %s" +msgstr "треба бути власником великого об'єкту %s" + +#: catalog/aclchk.c:3515 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "треба бути власником матеріалізованого подання %s" + +#: catalog/aclchk.c:3518 +#, c-format +msgid "must be owner of operator class %s" +msgstr "треба бути власником класу операторів %s" + +#: catalog/aclchk.c:3521 +#, c-format +msgid "must be owner of operator %s" +msgstr "треба бути власником оператора %s" + +#: catalog/aclchk.c:3524 +#, c-format +msgid "must be owner of operator family %s" +msgstr "треба бути власником сімейства операторів %s" + +#: catalog/aclchk.c:3527 +#, c-format +msgid "must be owner of procedure %s" +msgstr "треба бути власником процедури %s" + +#: catalog/aclchk.c:3530 +#, c-format +msgid "must be owner of publication %s" +msgstr "треба бути власником публікації %s" + +#: catalog/aclchk.c:3533 +#, c-format +msgid "must be owner of routine %s" +msgstr "треба бути власником підпрограми %s" + +#: catalog/aclchk.c:3536 +#, c-format +msgid "must be owner of sequence %s" +msgstr "треба бути власником послідовності %s" + +#: catalog/aclchk.c:3539 +#, c-format +msgid "must be owner of subscription %s" +msgstr "треба бути власником підписки %s" + +#: catalog/aclchk.c:3542 +#, c-format +msgid "must be owner of table %s" +msgstr "треба бути власником таблиці %s" + +#: catalog/aclchk.c:3545 +#, c-format +msgid "must be owner of type %s" +msgstr "треба бути власником типу %s" + +#: catalog/aclchk.c:3548 +#, c-format +msgid "must be owner of view %s" +msgstr "треба бути власником подання %s" + +#: catalog/aclchk.c:3551 +#, c-format +msgid "must be owner of schema %s" +msgstr "треба бути власником схеми %s" + +#: catalog/aclchk.c:3554 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "треба бути власником об'єкту статистики %s" + +#: catalog/aclchk.c:3557 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "треба бути власником табличного простору %s" + +#: catalog/aclchk.c:3560 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "треба бути власником конфігурації текстового пошуку %s" + +#: catalog/aclchk.c:3563 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "треба бути власником словника текстового пошуку %s" + +#: catalog/aclchk.c:3577 +#, c-format +msgid "must be owner of relation %s" +msgstr "треба бути власником відношення %s" + +#: catalog/aclchk.c:3621 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "немає дозволу для стовпця \"%s\" відношення \"%s\"" + +#: catalog/aclchk.c:3742 catalog/aclchk.c:3750 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "атрибут %d відношення з OID %u не існує" + +#: catalog/aclchk.c:3823 catalog/aclchk.c:4733 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "відношення з OID %u не існує" + +#: catalog/aclchk.c:3913 catalog/aclchk.c:5151 +#, c-format +msgid "database with OID %u does not exist" +msgstr "база даних з OID %u не існує" + +#: catalog/aclchk.c:3967 catalog/aclchk.c:4811 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2055 +#, c-format +msgid "function with OID %u does not exist" +msgstr "функція з OID %u не існує" + +#: catalog/aclchk.c:4021 catalog/aclchk.c:4837 +#, c-format +msgid "language with OID %u does not exist" +msgstr "мова з OID %u не існує" + +#: catalog/aclchk.c:4185 catalog/aclchk.c:4909 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "схема з OID %u не існує" + +#: catalog/aclchk.c:4239 catalog/aclchk.c:4936 utils/adt/genfile.c:686 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "табличний простір з OID %u не існує" + +#: catalog/aclchk.c:4298 catalog/aclchk.c:5070 commands/foreigncmds.c:325 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "джерело сторонніх даних з OID %u не існує" + +#: catalog/aclchk.c:4360 catalog/aclchk.c:5097 commands/foreigncmds.c:462 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "стороннього серверу з OID %u не усніє" + +#: catalog/aclchk.c:4420 catalog/aclchk.c:4759 utils/cache/typcache.c:378 +#: utils/cache/typcache.c:432 +#, c-format +msgid "type with OID %u does not exist" +msgstr "тип з OID %u не існує" + +#: catalog/aclchk.c:4785 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "оператора з OID %u не існує" + +#: catalog/aclchk.c:4962 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "класу операторів з OID %u не існує" + +#: catalog/aclchk.c:4989 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "сімейства операторів з OID %u не існує" + +#: catalog/aclchk.c:5016 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "словник текстового пошуку з OID %u не існує" + +#: catalog/aclchk.c:5043 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "конфігурація текстового пошуку %u з OID не існує" + +#: catalog/aclchk.c:5124 commands/event_trigger.c:475 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "тригер подій %u з OID не існує" + +#: catalog/aclchk.c:5177 commands/collationcmds.c:367 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "порядку сортування %u з OID не існує" + +#: catalog/aclchk.c:5203 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "перетворення %u з OID не існує" + +#: catalog/aclchk.c:5244 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "розширення %u з OID не існує" + +#: catalog/aclchk.c:5271 commands/publicationcmds.c:794 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "публікації %u з OID не існує" + +#: catalog/aclchk.c:5297 commands/subscriptioncmds.c:1112 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "підписки %u з OID не існує" + +#: catalog/aclchk.c:5323 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "об'єкту статистики %u з OID не існує" + +#: catalog/catalog.c:485 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "для виклику pg_nextoid() потрібно бути суперкористувачем" + +#: catalog/catalog.c:493 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() можна використовувати лише для системних каталогів" + +#: catalog/catalog.c:498 parser/parse_utilcmd.c:2191 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "індекс \"%s\" не належить таблиці \"%s\"" + +#: catalog/catalog.c:515 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "стовпець \"%s\" повинен мати тип oid" + +#: catalog/catalog.c:522 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "індекс \"%s\" не є індексом для стовпця \"%s\"" + +#: catalog/dependency.c:823 catalog/dependency.c:1061 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "не вдалося видалити %s, оскільки %s потребує його" + +#: catalog/dependency.c:825 catalog/dependency.c:1063 +#, c-format +msgid "You can drop %s instead." +msgstr "Ви можете видалити %s замість цього." + +#: catalog/dependency.c:933 catalog/pg_shdepend.c:640 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "не вдалося видалити %s, оскільки він потрібний системі бази даних" + +#: catalog/dependency.c:1129 +#, c-format +msgid "drop auto-cascades to %s" +msgstr "видалення автоматично поширюється (auto-cascades) на об'єкт %s" + +#: catalog/dependency.c:1141 catalog/dependency.c:1150 +#, c-format +msgid "%s depends on %s" +msgstr "%s залежить від %s" + +#: catalog/dependency.c:1162 catalog/dependency.c:1171 +#, c-format +msgid "drop cascades to %s" +msgstr "видалення поширюється (cascades) на об'єкт %s" + +#: catalog/dependency.c:1179 catalog/pg_shdepend.c:769 +#, c-format +msgid "\n" +"and %d other object (see server log for list)" +msgid_plural "\n" +"and %d other objects (see server log for list)" +msgstr[0] "\n" +"і ще %d інших об'єктів (див. список у протоколі серверу)" +msgstr[1] "\n" +"і ще %d інші об'єкти (див. список у протоколі серверу)" +msgstr[2] "\n" +"і ще %d інших об'єктів (див. список у протоколі серверу)" +msgstr[3] "\n" +"і ще %d інші об'єкти (див. список у протоколі сервера)" + +#: catalog/dependency.c:1191 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "неможливо видалити %s, тому що від нього залежать інші об'єкти" + +#: catalog/dependency.c:1193 catalog/dependency.c:1194 +#: catalog/dependency.c:1200 catalog/dependency.c:1201 +#: catalog/dependency.c:1212 catalog/dependency.c:1213 +#: commands/tablecmds.c:1249 commands/tablecmds.c:13016 commands/user.c:1093 +#: commands/view.c:495 libpq/auth.c:334 replication/syncrep.c:1032 +#: storage/lmgr/deadlock.c:1154 storage/lmgr/proc.c:1350 utils/adt/acl.c:5329 +#: utils/adt/jsonfuncs.c:614 utils/adt/jsonfuncs.c:620 utils/misc/guc.c:6771 +#: utils/misc/guc.c:6807 utils/misc/guc.c:6877 utils/misc/guc.c:10947 +#: utils/misc/guc.c:10981 utils/misc/guc.c:11015 utils/misc/guc.c:11049 +#: utils/misc/guc.c:11084 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1195 catalog/dependency.c:1202 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Використайте DROP ... CASCADE для видалення залежних об'єктів також." + +#: catalog/dependency.c:1199 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "не можна видалити бажаний(-і) об'єкт(-и) тому, що інші об'єкти залежні від нього(них)" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1208 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "видалення поширюється (cascades) на ще %d інший об'єкт" +msgstr[1] "видалення поширюється (cascades) на ще %d інші об'єкти" +msgstr[2] "видалення поширюється (cascades) на ще %d інших об'єктів" +msgstr[3] "видалення поширюється (cascades) на ще %d інших об'єктів" + +#: catalog/dependency.c:1875 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "константа типу %s не може бути використана тут" + +#: catalog/heap.c:330 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "немає дозволу для створення \"%s.%s\"" + +#: catalog/heap.c:332 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "Змінення системного каталогу наразі заборонено." + +#: catalog/heap.c:500 commands/tablecmds.c:2145 commands/tablecmds.c:2745 +#: commands/tablecmds.c:6175 +#, c-format +msgid "tables can have at most %d columns" +msgstr "таблиці можуть містити максимум %d стовпців" + +#: catalog/heap.c:518 commands/tablecmds.c:6468 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "ім'я стовпця \"%s\" конфліктує з системним іменем стовпця" + +#: catalog/heap.c:534 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "ім'я стовпця \"%s\" вказано кілька разів" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:609 +#, c-format +msgid "partition key column %s has pseudo-type %s" +msgstr "стовпець ключа секціонування %s має псевдотип %s" + +#: catalog/heap.c:614 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "стовпець \"%s\" має псевдо-тип %s" + +#: catalog/heap.c:645 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "складений тип %s не може містити сам себе" + +#. translator: first %s is an integer not a name +#: catalog/heap.c:700 +#, c-format +msgid "no collation was derived for partition key column %s with collatable type %s" +msgstr "для стовпця ключа секціонування \"%s\" з сортируючим типом %s не вдалося отримати параметри сортування" + +#: catalog/heap.c:706 commands/createas.c:203 commands/createas.c:486 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "для стовпця \"%s\" із сортувальним типом %s не вдалося отримати параметри сортування" + +#: catalog/heap.c:1155 catalog/index.c:865 commands/tablecmds.c:3520 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "відношення \"%s\" вже існує" + +#: catalog/heap.c:1171 catalog/pg_type.c:428 catalog/pg_type.c:775 +#: commands/typecmds.c:238 commands/typecmds.c:250 commands/typecmds.c:719 +#: commands/typecmds.c:1125 commands/typecmds.c:1337 commands/typecmds.c:2124 +#, c-format +msgid "type \"%s\" already exists" +msgstr "тип \"%s\" вже існує" + +#: catalog/heap.c:1172 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "З відношенням вже пов'язаний тип з таким самим іменем, тому виберіть ім'я, яке не буде конфліктувати з типами, що існують." + +#: catalog/heap.c:1201 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "значення OID в pg_class не задано в режимі двійкового оновлення" + +#: catalog/heap.c:2400 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "не можна додати обмеження NO INHERIT до секціонованої таблиці \"%s\"" + +#: catalog/heap.c:2670 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "обмеження перевірки \"%s\" вже інсує" + +#: catalog/heap.c:2840 catalog/index.c:879 catalog/pg_constraint.c:668 +#: commands/tablecmds.c:8117 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "обмеження \"%s\" відношення \"%s\" вже існує" + +#: catalog/heap.c:2847 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "обмеження \"%s\" конфліктує з неуспадкованим обмеженням відношення \"%s\"" + +#: catalog/heap.c:2858 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "обмеження \"%s\" конфліктує з успадкованим обмеженням відношення \"%s\"" + +#: catalog/heap.c:2868 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "обмеження \"%s\" конфліктує з обмеженням NOT VALID в відношенні \"%s\"" + +#: catalog/heap.c:2873 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "злиття обмеження \"%s\" з успадкованим визначенням" + +#: catalog/heap.c:2975 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "в виразі створення стовпця не можна використовувати згенерований стовпець \"%s\" " + +#: catalog/heap.c:2977 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "Згенерований стовпець не може посилатися на інший згенерований стовпець." + +#: catalog/heap.c:3029 +#, c-format +msgid "generation expression is not immutable" +msgstr "вираз генерації не є незмінним" + +#: catalog/heap.c:3057 rewrite/rewriteHandler.c:1192 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "стовпець \"%s\" має тип %s, але тип виразу за замовчуванням %s" + +#: catalog/heap.c:3062 commands/prepare.c:367 parser/parse_node.c:412 +#: parser/parse_target.c:589 parser/parse_target.c:869 +#: parser/parse_target.c:879 rewrite/rewriteHandler.c:1197 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Потрібно буде переписати або привести вираз." + +#: catalog/heap.c:3109 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "в обмеженні-перевірці можна посилатися лише на таблицю \"%s\"" + +#: catalog/heap.c:3366 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "непідтримуване поєднання зовнішнього ключа з ON COMMIT" + +#: catalog/heap.c:3367 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "Таблиця \"%s\" посилається на \"%s\", але вони не мають той же параметр ON COMMIT." + +#: catalog/heap.c:3372 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "скоротити таблицю, на яку посилається зовнішній ключ, не можливо" + +#: catalog/heap.c:3373 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "Таблиця \"%s\" посилається на \"%s\"." + +#: catalog/heap.c:3375 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "Скоротіть таблицю \"%s\" паралельно або використайте TRUNCATE ... CASCADE." + +#: catalog/index.c:219 parser/parse_utilcmd.c:2097 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "таблиця \"%s\" не може містити кілька первинних ключів" + +#: catalog/index.c:237 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "первинні ключі не можуть бути виразами" + +#: catalog/index.c:254 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "стовпець первинного ключа \"%s\" не позначений як NOT NULL" + +#: catalog/index.c:764 catalog/index.c:1843 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "користувацькі індекси в таблицях системного каталогу не підтримуються" + +#: catalog/index.c:804 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "недетерміновані правила сортування не підтримуються для класу операторів \"%s\"" + +#: catalog/index.c:819 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "паралельне створення індексу в таблицях системного каталогу не підтримується" + +#: catalog/index.c:828 catalog/index.c:1281 +#, c-format +msgid "concurrent index creation for exclusion constraints is not supported" +msgstr "парарельне створення індексу для обмежень-виключень не підтримується" + +#: catalog/index.c:837 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "не можливо створити спільні індекси після initdb" + +#: catalog/index.c:857 commands/createas.c:252 commands/sequence.c:154 +#: parser/parse_utilcmd.c:210 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "ввідношення \"%s\" вже існує, пропускаємо" + +#: catalog/index.c:907 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "значення OID індекса в pg_class не встановлено в режимі двійкового оновлення" + +#: catalog/index.c:2128 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY повинен бути першою дією в транзакції" + +#: catalog/index.c:2859 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "створення індексу \"%s\" в таблиці \"%s\" у непаралельному режимі (serially)" + +#: catalog/index.c:2864 +#, c-format +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "створення індексу \"%s\" в таблиці \"%s\" з розрахунком на %d паралельного виконавця" +msgstr[1] "створення індексу \"%s\" в таблиці \"%s\" з розрахунком на %d паралельних виконавців" +msgstr[2] "створення індексу \"%s\" в таблиці \"%s\" з розрахунком на %d паралельних виконавців" +msgstr[3] "створення індексу \"%s\" в таблиці \"%s\" з розрахунком на %d паралельних виконавців" + +#: catalog/index.c:3492 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "повторно індексувати тимчасові таблиці інших сеансів не можна" + +#: catalog/index.c:3503 +#, c-format +msgid "cannot reindex invalid index on TOAST table" +msgstr "переіндексувати неприпустимий індекс в таблиці TOAST не можна" + +#: catalog/index.c:3625 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "індекс \"%s\" був перебудований" + +#: catalog/index.c:3701 commands/indexcmds.c:3017 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "REINDEX для секціонованих таблиць ще не реалізовано, пропускається \"%s\"" + +#: catalog/index.c:3756 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" on TOAST table, skipping" +msgstr "переіндексувати неприпустимий індекс \"%s.%s\" в таблиці TOAST не можна, пропускається" + +#: catalog/namespace.c:257 catalog/namespace.c:461 catalog/namespace.c:553 +#: commands/trigger.c:5043 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "cross-database посилання не реалізовані: \"%s.%s.%s\"" + +#: catalog/namespace.c:314 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "для тимчасових таблиць ім'я схеми не вказується" + +#: catalog/namespace.c:395 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "не вдалося отримати блокування зв'язку \"%s.%s\"" + +#: catalog/namespace.c:400 commands/lockcmds.c:142 commands/lockcmds.c:227 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "не вдалося отримати блокування зв'язку \"%s\"" + +#: catalog/namespace.c:428 parser/parse_relation.c:1357 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "відношення \"%s.%s\" не існує" + +#: catalog/namespace.c:433 parser/parse_relation.c:1370 +#: parser/parse_relation.c:1378 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "відношення \"%s\" не існує" + +#: catalog/namespace.c:499 catalog/namespace.c:3030 commands/extension.c:1519 +#: commands/extension.c:1525 +#, c-format +msgid "no schema has been selected to create in" +msgstr "не вибрано схему для створення об'єктів" + +#: catalog/namespace.c:651 catalog/namespace.c:664 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "неможливо створити відношення в тимчасових схемах з інших сеансів" + +#: catalog/namespace.c:655 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "неможливо створити тимчасове відношення в не тимчасовій схемі" + +#: catalog/namespace.c:670 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "в тимчасових схемах можуть бути створені тільки тимчасові відношення" + +#: catalog/namespace.c:2222 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "об'єкт статистики \"%s\" не існує" + +#: catalog/namespace.c:2345 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "парсер текстового пошуку \"%s\" не існує" + +#: catalog/namespace.c:2471 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "словник текстового пошуку \"%s\" не існує" + +#: catalog/namespace.c:2598 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "шаблон текстового пошуку \"%s\" не існує" + +#: catalog/namespace.c:2724 commands/tsearchcmds.c:1194 +#: utils/cache/ts_cache.c:617 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "конфігурація текстового пошуку \"%s\" не існує" + +#: catalog/namespace.c:2837 parser/parse_expr.c:872 parser/parse_target.c:1228 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "міжбазові посилання не реалізовані: %s" + +#: catalog/namespace.c:2843 parser/parse_expr.c:879 parser/parse_target.c:1235 +#: gram.y:14981 gram.y:16435 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "неправильне повне ім'я (забагато компонентів): %s" + +#: catalog/namespace.c:2973 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "не можна переміщати об'єкти в або з тимчасових схем" + +#: catalog/namespace.c:2979 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "не можна переміщати об'єкти в або з схем TOAST" + +#: catalog/namespace.c:3052 commands/schemacmds.c:256 commands/schemacmds.c:336 +#: commands/tablecmds.c:1194 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "схема \"%s\" не існує" + +#: catalog/namespace.c:3083 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "неправильне ім'я зв'язку (забагато компонентів): %s" + +#: catalog/namespace.c:3646 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "правило сортування \"%s\" для кодування \"%s\" не існує" + +#: catalog/namespace.c:3701 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "перетворення\"%s\" не існує" + +#: catalog/namespace.c:3965 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "немає дозволу для створення тимчасових таблиць в базі даних \"%s\"" + +#: catalog/namespace.c:3981 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "не можна створити тимчасові таблиці під час відновлення" + +#: catalog/namespace.c:3987 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "не можна створити тимчасові таблиці під час паралельної операції" + +#: catalog/namespace.c:4286 commands/tablespace.c:1205 commands/variable.c:64 +#: utils/misc/guc.c:11116 utils/misc/guc.c:11194 +#, c-format +msgid "List syntax is invalid." +msgstr "Помилка синтаксису у списку." + +#: catalog/objectaddress.c:1275 catalog/pg_publication.c:57 +#: commands/policy.c:95 commands/policy.c:395 commands/policy.c:485 +#: commands/tablecmds.c:230 commands/tablecmds.c:272 commands/tablecmds.c:1989 +#: commands/tablecmds.c:5626 commands/tablecmds.c:11089 +#, c-format +msgid "\"%s\" is not a table" +msgstr "\"%s\" не є таблицею" + +#: catalog/objectaddress.c:1282 commands/tablecmds.c:242 +#: commands/tablecmds.c:5656 commands/tablecmds.c:15711 commands/view.c:119 +#, c-format +msgid "\"%s\" is not a view" +msgstr "\"%s\" не є поданням" + +#: catalog/objectaddress.c:1289 commands/matview.c:175 commands/tablecmds.c:248 +#: commands/tablecmds.c:15716 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "\"%s\" не є матеріалізованим поданням" + +#: catalog/objectaddress.c:1296 commands/tablecmds.c:266 +#: commands/tablecmds.c:5659 commands/tablecmds.c:15721 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "\"%s\" не є сторонньою таблицею" + +#: catalog/objectaddress.c:1337 +#, c-format +msgid "must specify relation and object name" +msgstr "треба вказати відношення й ім'я об'єкта" + +#: catalog/objectaddress.c:1413 catalog/objectaddress.c:1466 +#, c-format +msgid "column name must be qualified" +msgstr "слід вказати ім'я стовпця" + +#: catalog/objectaddress.c:1513 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "значення за замовчуванням для стовпця \"%s\" відношення \"%s\" не існує" + +#: catalog/objectaddress.c:1550 commands/functioncmds.c:133 +#: commands/tablecmds.c:258 commands/typecmds.c:263 commands/typecmds.c:3275 +#: parser/parse_type.c:243 parser/parse_type.c:272 parser/parse_type.c:845 +#: utils/adt/acl.c:4436 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "тип \"%s\" не існує" + +#: catalog/objectaddress.c:1669 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "оператор %d (%s, %s) з %s не існує" + +#: catalog/objectaddress.c:1700 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "функція %d (%s, %s) з %s не існує" + +#: catalog/objectaddress.c:1751 catalog/objectaddress.c:1777 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "відображення користувача для користувача \"%s\" на сервері \"%s\"не існує" + +#: catalog/objectaddress.c:1766 commands/foreigncmds.c:430 +#: commands/foreigncmds.c:1012 commands/foreigncmds.c:1395 +#: foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "сервер \"%s\" не існує" + +#: catalog/objectaddress.c:1833 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "відношення публікації \"%s\" в публікації \"%s\" не існує" + +#: catalog/objectaddress.c:1895 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "нерозпізнаний тип об'єкта ACL за замовчуванням \"%c\"" + +#: catalog/objectaddress.c:1896 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Припустимі типи об'єктів: \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." + +#: catalog/objectaddress.c:1947 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "ACL за замовчуванням для користувача \"%s\" в схемі \"%s\" для об'єкту %s не існує" + +#: catalog/objectaddress.c:1952 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "ACL за замовчуванням для користувача \"%s\" і для об'єкту %s не існує" + +#: catalog/objectaddress.c:1979 catalog/objectaddress.c:2037 +#: catalog/objectaddress.c:2094 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "списки імен та аргументів не повинні містити Null" + +#: catalog/objectaddress.c:2013 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "непідтримуваний тип об'єкта \"%s\"" + +#: catalog/objectaddress.c:2033 catalog/objectaddress.c:2051 +#: catalog/objectaddress.c:2192 +#, c-format +msgid "name list length must be exactly %d" +msgstr "довжина списку імен повинна бути точно %d" + +#: catalog/objectaddress.c:2055 +#, c-format +msgid "large object OID may not be null" +msgstr "OID великого об'єкта не повинно бути нулем" + +#: catalog/objectaddress.c:2064 catalog/objectaddress.c:2127 +#: catalog/objectaddress.c:2134 +#, c-format +msgid "name list length must be at least %d" +msgstr "довжина списку імен повинна бути щонайменше %d" + +#: catalog/objectaddress.c:2120 catalog/objectaddress.c:2141 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "довжина списку аргументів повинна бути точно %d" + +#: catalog/objectaddress.c:2393 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "треба бути власником великого об'єкта %u" + +#: catalog/objectaddress.c:2408 commands/functioncmds.c:1445 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "треба бути власником типу %s або типу %s" + +#: catalog/objectaddress.c:2458 catalog/objectaddress.c:2475 +#, c-format +msgid "must be superuser" +msgstr "треба бути суперкористувачем" + +#: catalog/objectaddress.c:2465 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "треба мати право CREATEROLE" + +#: catalog/objectaddress.c:2544 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "нерозпізнаний тип об'єкту \"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2772 +#, c-format +msgid "column %s of %s" +msgstr "стовпець %s з %s" + +#: catalog/objectaddress.c:2782 +#, c-format +msgid "function %s" +msgstr "функція %s" + +#: catalog/objectaddress.c:2787 +#, c-format +msgid "type %s" +msgstr "тип %s" + +#: catalog/objectaddress.c:2817 +#, c-format +msgid "cast from %s to %s" +msgstr "приведення від %s до %s" + +#: catalog/objectaddress.c:2845 +#, c-format +msgid "collation %s" +msgstr "сортування %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2871 +#, c-format +msgid "constraint %s on %s" +msgstr "обмеження %s на %s" + +#: catalog/objectaddress.c:2877 +#, c-format +msgid "constraint %s" +msgstr "обмеження %s" + +#: catalog/objectaddress.c:2904 +#, c-format +msgid "conversion %s" +msgstr "перетворення %s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2943 +#, c-format +msgid "default value for %s" +msgstr "значення за замовчуванням для %s" + +#: catalog/objectaddress.c:2952 +#, c-format +msgid "language %s" +msgstr "мова %s" + +#: catalog/objectaddress.c:2957 +#, c-format +msgid "large object %u" +msgstr "великий об'єкт %u" + +#: catalog/objectaddress.c:2962 +#, c-format +msgid "operator %s" +msgstr "оператор %s" + +#: catalog/objectaddress.c:2994 +#, c-format +msgid "operator class %s for access method %s" +msgstr "клас операторів %s для методу доступу %s" + +#: catalog/objectaddress.c:3017 +#, c-format +msgid "access method %s" +msgstr "метод доступу %s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3059 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "оператор %d (%s, %s) з %s: %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3109 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "функція %d (%s, %s) з %s: %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3153 +#, c-format +msgid "rule %s on %s" +msgstr "правило %s на %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3191 +#, c-format +msgid "trigger %s on %s" +msgstr "тригер %s на %s" + +#: catalog/objectaddress.c:3207 +#, c-format +msgid "schema %s" +msgstr "схема %s" + +#: catalog/objectaddress.c:3230 +#, c-format +msgid "statistics object %s" +msgstr "об'єкт статистики %s" + +#: catalog/objectaddress.c:3257 +#, c-format +msgid "text search parser %s" +msgstr "парсер текстового пошуку %s" + +#: catalog/objectaddress.c:3283 +#, c-format +msgid "text search dictionary %s" +msgstr "словник текстового пошуку %s" + +#: catalog/objectaddress.c:3309 +#, c-format +msgid "text search template %s" +msgstr "шаблон текстового пошуку %s" + +#: catalog/objectaddress.c:3335 +#, c-format +msgid "text search configuration %s" +msgstr "конфігурація текстового пошуку %s" + +#: catalog/objectaddress.c:3344 +#, c-format +msgid "role %s" +msgstr "роль %s" + +#: catalog/objectaddress.c:3357 +#, c-format +msgid "database %s" +msgstr "база даних %s" + +#: catalog/objectaddress.c:3369 +#, c-format +msgid "tablespace %s" +msgstr "табличний простір %s" + +#: catalog/objectaddress.c:3378 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "джерело сторонніх даних %s" + +#: catalog/objectaddress.c:3387 +#, c-format +msgid "server %s" +msgstr "сервер %s" + +#: catalog/objectaddress.c:3415 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "зіставлення користувача для %s на сервері %s" + +#: catalog/objectaddress.c:3460 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "права за замовчуванням для нових відношень, що належать ролі %s в схемі %s" + +#: catalog/objectaddress.c:3464 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "права за замовчуванням для нових відношень, що належать ролі %s" + +#: catalog/objectaddress.c:3470 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "права за замовчуванням для нових послідовностей, що належать ролі %s в схемі %s" + +#: catalog/objectaddress.c:3474 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "права за замовчуванням для нових послідовностей, що належать ролі %s" + +#: catalog/objectaddress.c:3480 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "права за замовчуванням для нових функцій, що належать ролі %s в схемі %s" + +#: catalog/objectaddress.c:3484 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "права за замовчуванням для нових функцій, що належать ролі %s" + +#: catalog/objectaddress.c:3490 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "права за замовчуванням для нових типів, що належать ролі %s в схемі %s" + +#: catalog/objectaddress.c:3494 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "права за замовчуванням для нових типів, що належать ролі %s" + +#: catalog/objectaddress.c:3500 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "права за замовчуванням для нових схем, що належать ролі %s" + +#: catalog/objectaddress.c:3507 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "права за замовчуванням, що належать ролі %s в схемі %s" + +#: catalog/objectaddress.c:3511 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "права за замовчуванням належать ролі %s" + +#: catalog/objectaddress.c:3529 +#, c-format +msgid "extension %s" +msgstr "розширення %s" + +#: catalog/objectaddress.c:3542 +#, c-format +msgid "event trigger %s" +msgstr "тригер подій %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3578 +#, c-format +msgid "policy %s on %s" +msgstr "політика %s на %s" + +#: catalog/objectaddress.c:3588 +#, c-format +msgid "publication %s" +msgstr "публікація %s" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3614 +#, c-format +msgid "publication of %s in publication %s" +msgstr "відношення публікації %s в публікації %s" + +#: catalog/objectaddress.c:3623 +#, c-format +msgid "subscription %s" +msgstr "підписка %s" + +#: catalog/objectaddress.c:3642 +#, c-format +msgid "transform for %s language %s" +msgstr "трансформація для %s мови %s" + +#: catalog/objectaddress.c:3705 +#, c-format +msgid "table %s" +msgstr "таблиця %s" + +#: catalog/objectaddress.c:3710 +#, c-format +msgid "index %s" +msgstr "індекс %s" + +#: catalog/objectaddress.c:3714 +#, c-format +msgid "sequence %s" +msgstr "послідовність %s" + +#: catalog/objectaddress.c:3718 +#, c-format +msgid "toast table %s" +msgstr "таблиця toast %s" + +#: catalog/objectaddress.c:3722 +#, c-format +msgid "view %s" +msgstr "подання %s" + +#: catalog/objectaddress.c:3726 +#, c-format +msgid "materialized view %s" +msgstr "матеріалізоване подання %s" + +#: catalog/objectaddress.c:3730 +#, c-format +msgid "composite type %s" +msgstr "складений тип %s" + +#: catalog/objectaddress.c:3734 +#, c-format +msgid "foreign table %s" +msgstr "зовнішня таблиця %s" + +#: catalog/objectaddress.c:3739 +#, c-format +msgid "relation %s" +msgstr "відношення %s" + +#: catalog/objectaddress.c:3776 +#, c-format +msgid "operator family %s for access method %s" +msgstr "сімейство операторів %s для методу доступу %s" + +#: catalog/pg_aggregate.c:128 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "агрегати не можуть мати більше ніж %d аргумент" +msgstr[1] "агрегати не можуть мати більше ніж %d аргументи" +msgstr[2] "агрегати не можуть мати більше ніж %d аргументів" +msgstr[3] "агрегати не можуть мати більше ніж %d аргументів" + +#: catalog/pg_aggregate.c:143 catalog/pg_aggregate.c:157 +#, c-format +msgid "cannot determine transition data type" +msgstr "неможливо визначити тип перехідних даних" + +#: catalog/pg_aggregate.c:172 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "сортувальна агрегатна функція з (variadic) повинна використовувати тип VARIADIC ANY" + +#: catalog/pg_aggregate.c:198 +#, c-format +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" +msgstr "hypothetical-set-функція повинна мати прямі аргументи, які відповідають агрегатним" + +#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "функція переходу %s повинна повертати тип %s" + +#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#, c-format +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" +msgstr "не можна пропустити початкове значення, коли перехідна функція сувора і перехідний тип не сумісний з типом введення" + +#: catalog/pg_aggregate.c:334 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "інвертована функція переходу %s повинна повертати тип %s" + +#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2852 +#, c-format +msgid "strictness of aggregate's forward and inverse transition functions must match" +msgstr "пряма й інвертована функції переходу агрегату повинні мати однакову суворість" + +#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:553 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "фінальна функція з додатковими аргументами не повинна оголошуватись як сувора (STRICT)" + +#: catalog/pg_aggregate.c:426 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "комбінуюча функція %s повинна повертати тип %s" + +#: catalog/pg_aggregate.c:438 executor/nodeAgg.c:4177 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "комбінуюча функція з перехідним типом %s не повинна оголошуватись як сувора (STRICT)" + +#: catalog/pg_aggregate.c:457 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "функція серіалізації %s повинна повертати тип %s" + +#: catalog/pg_aggregate.c:478 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "функція десеріалізації %s повинна повертати тип %s" + +#: catalog/pg_aggregate.c:497 catalog/pg_proc.c:186 catalog/pg_proc.c:220 +#, c-format +msgid "cannot determine result data type" +msgstr "не вдалося визначити тип результату" + +#: catalog/pg_aggregate.c:512 catalog/pg_proc.c:199 catalog/pg_proc.c:228 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "небезпечне використання псевдотипу (pseudo-type) \"internal\"" + +#: catalog/pg_aggregate.c:566 +#, c-format +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" +msgstr "реалізація рухомого агрегату повертає тип %s, але проста реалізація повертає %s" + +#: catalog/pg_aggregate.c:577 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "оператора сортування можна вказати лише для агрегатних функцій з одним аргументом" + +#: catalog/pg_aggregate.c:704 catalog/pg_proc.c:374 +#, c-format +msgid "cannot change routine kind" +msgstr "неможливо змінити тип підпрограми" + +#: catalog/pg_aggregate.c:706 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "\"%s\" є звичайною агрегатною функцією." + +#: catalog/pg_aggregate.c:708 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "\"%s\" є сортувальним агрегатом." + +#: catalog/pg_aggregate.c:710 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "\"%s\" є агрегатом для гіпотетичних наборів." + +#: catalog/pg_aggregate.c:715 +#, c-format +msgid "cannot change number of direct arguments of an aggregate function" +msgstr "змінити кількість прямих аргументів агрегатної функції не можна" + +#: catalog/pg_aggregate.c:870 commands/functioncmds.c:667 +#: commands/typecmds.c:1658 commands/typecmds.c:1704 commands/typecmds.c:1756 +#: commands/typecmds.c:1793 commands/typecmds.c:1827 commands/typecmds.c:1861 +#: commands/typecmds.c:1895 commands/typecmds.c:1972 commands/typecmds.c:2014 +#: parser/parse_func.c:414 parser/parse_func.c:443 parser/parse_func.c:468 +#: parser/parse_func.c:482 parser/parse_func.c:602 parser/parse_func.c:622 +#: parser/parse_func.c:2129 parser/parse_func.c:2320 +#, c-format +msgid "function %s does not exist" +msgstr "функції %s не існує" + +#: catalog/pg_aggregate.c:876 +#, c-format +msgid "function %s returns a set" +msgstr "функція %s повертає набір" + +#: catalog/pg_aggregate.c:891 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "функція %s повинна прийняти VARIADIC ANY для використання в цій агрегатній функції" + +#: catalog/pg_aggregate.c:915 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "функція %s потребує приведення типів під час виконання" + +#: catalog/pg_cast.c:67 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "приведення від типу %s до типу %s вже існує" + +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "сортування \"%s\" вже існує, пропускаємо" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "правило сортування \"%s \" для кодування \"%s\" вже існує, пропускаємо" + +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "правило сортування \"%s\" вже існує" + +#: catalog/pg_collation.c:105 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "правило сортування \"%s \" для кодування \"%s\" вже існує" + +#: catalog/pg_constraint.c:676 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "обмеження \"%s\" для домену %s вже існує" + +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "індексу \"%s\" для таблиці \"%s\" не існує" + +#: catalog/pg_constraint.c:1056 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "обмеження \"%s\" для домену \"%s\" не існує" + +#: catalog/pg_conversion.c:67 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "перетворення \"%s\" вже існує" + +#: catalog/pg_conversion.c:80 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "перетворення за замовчуванням від %s до %s вже існує" + +#: catalog/pg_depend.c:162 commands/extension.c:3324 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "%s вже є членом розширення \"%s\"" + +#: catalog/pg_depend.c:538 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "неможливо видалити залежність від об'єкта %s, тому що це системний об'єкт" + +#: catalog/pg_enum.c:127 catalog/pg_enum.c:230 catalog/pg_enum.c:525 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "неприпустима мітка перераховування \"%s\"" + +#: catalog/pg_enum.c:128 catalog/pg_enum.c:231 catalog/pg_enum.c:526 +#, c-format +msgid "Labels must be %d characters or less." +msgstr "Мітки повинні містити %d символів або менше." + +#: catalog/pg_enum.c:259 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "мітка перераховування \"%s\" вже існує, пропускаємо" + +#: catalog/pg_enum.c:266 catalog/pg_enum.c:569 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "мітка перераховування \"%s\" вже існує" + +#: catalog/pg_enum.c:321 catalog/pg_enum.c:564 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "\"%s\" не є існуючою міткою перераховування" + +#: catalog/pg_enum.c:379 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "значення OID в pg_enum не встановлено в режимі двійкового оновлення" + +#: catalog/pg_enum.c:389 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "Конструкція ALTER TYPE ADD BEFORE/AFTER несумісна з двійковим оновленням даних" + +#: catalog/pg_namespace.c:64 commands/schemacmds.c:265 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "схема \"%s\" вже існує" + +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "\"%s\" не є коректним оператором" + +#: catalog/pg_operator.c:370 +#, c-format +msgid "only binary operators can have commutators" +msgstr "(commutators) можна визначити лише для бінарних операторів" + +#: catalog/pg_operator.c:374 commands/operatorcmds.c:495 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "функцію оцінки з'єднання можливо визначити лише для бінарних операторів" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can merge join" +msgstr "підтримку з'єднання злиттям можливо позначити лише для бінарних операторів" + +#: catalog/pg_operator.c:382 +#, c-format +msgid "only binary operators can hash" +msgstr "підтримка хешу можливо позначити лише для бінарних операторів" + +#: catalog/pg_operator.c:393 +#, c-format +msgid "only boolean operators can have negators" +msgstr "зворотню операцію можливо визначити лише для логічних операторів" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:503 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "функцію оцінки обмеження можливо визначити лише для логічних операторів" + +#: catalog/pg_operator.c:401 commands/operatorcmds.c:507 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "функцію оцінки з'єднання можливо визначити лише для логічних операторів" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can merge join" +msgstr "підтримку з'єднання злиттям можливо позначити лише для логічних операторів" + +#: catalog/pg_operator.c:409 +#, c-format +msgid "only boolean operators can hash" +msgstr "підтримку хешу можливо позначити лише для логічних операторів" + +#: catalog/pg_operator.c:421 +#, c-format +msgid "operator %s already exists" +msgstr "оператор %s вже існує" + +#: catalog/pg_operator.c:621 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "оператор не може бути зворотнім до себе або власним оператором сортування" + +#: catalog/pg_proc.c:127 parser/parse_func.c:2191 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "функції не можуть мати більше %d аргументу" +msgstr[1] "функції не можуть мати більше %d аргументів" +msgstr[2] "функції не можуть мати більше %d аргументів" +msgstr[3] "функції не можуть мати більше %d аргументів" + +#: catalog/pg_proc.c:364 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "функція \"%s\" з аргументами таких типів вже існує" + +#: catalog/pg_proc.c:376 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" є функцією агрегату." + +#: catalog/pg_proc.c:378 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\" є функцією." + +#: catalog/pg_proc.c:380 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\" є процедурою." + +#: catalog/pg_proc.c:382 +#, c-format +msgid "\"%s\" is a window function." +msgstr "\"%s\" є функцією вікна." + +#: catalog/pg_proc.c:402 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "неможливо визначити вихідні параметри для процедури" + +#: catalog/pg_proc.c:403 catalog/pg_proc.c:433 +#, c-format +msgid "cannot change return type of existing function" +msgstr "неможливо змінити тип повернення існуючої функції" + +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:409 catalog/pg_proc.c:436 catalog/pg_proc.c:481 +#: catalog/pg_proc.c:507 catalog/pg_proc.c:533 +#, c-format +msgid "Use %s %s first." +msgstr "Використайте %s %s спочатку." + +#: catalog/pg_proc.c:434 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "Параметри OUT визначають другий тип рядку." + +#: catalog/pg_proc.c:478 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "неможливо змінити ім'я вхідного параметру \"%s\"" + +#: catalog/pg_proc.c:505 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "неможливо прибрати параметр за замовчуванням з існуючої функції" + +#: catalog/pg_proc.c:531 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "неможливо змінити тип даних для існуючого значення параметру за замовчуванням" + +#: catalog/pg_proc.c:748 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "немає вбудованої функції \"%s\"" + +#: catalog/pg_proc.c:846 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "Функції SQL не можуть повернути тип %s" + +#: catalog/pg_proc.c:861 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "функції SQL не можуть мати аргументи типу %s" + +#: catalog/pg_proc.c:954 executor/functions.c:1446 +#, c-format +msgid "SQL function \"%s\"" +msgstr "Функція SQL \"%s\"" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Only tables can be added to publications." +msgstr "Тільки системні таблиці можуть бути додані до публікацій." + +#: catalog/pg_publication.c:65 +#, c-format +msgid "\"%s\" is a system table" +msgstr "\"%s\" є системною таблицею" + +#: catalog/pg_publication.c:67 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "Системні таблиці не можуть бути додані до публікацій." + +#: catalog/pg_publication.c:73 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "таблиця \"%s\" не може бути реплікованою" + +#: catalog/pg_publication.c:75 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "Тимчасові і нежурнальованні відношення не можуть бути реплікованими." + +#: catalog/pg_publication.c:174 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "відношення \"%s\" вже є членом публікації \"%s\"" + +#: catalog/pg_publication.c:470 commands/publicationcmds.c:451 +#: commands/publicationcmds.c:762 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "публікація \"%s\" вже існує" + +#: catalog/pg_shdepend.c:776 +#, c-format +msgid "\n" +"and objects in %d other database (see server log for list)" +msgid_plural "\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "\n" +"і об'єкти в %d іншій базі даних (див. список в протоколі сервера)" +msgstr[1] "\n" +"і об'єкти в %d інших базах даних (див. список в протоколі сервера)" +msgstr[2] "\n" +"і об'єкти в %d інших базах даних (див. список в протоколі сервера)" +msgstr[3] "\n" +"і об'єкти в %d інших базах даних (див. список в протоколі сервера)" + +#: catalog/pg_shdepend.c:1082 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "роль %u було видалено паралельним способом" + +#: catalog/pg_shdepend.c:1101 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "табличний простір %u було видалено паралельним способом" + +#: catalog/pg_shdepend.c:1116 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "базу даних %u було видалено паралельним способом" + +#: catalog/pg_shdepend.c:1161 +#, c-format +msgid "owner of %s" +msgstr "власник об'єкту %s" + +#: catalog/pg_shdepend.c:1163 +#, c-format +msgid "privileges for %s" +msgstr "права для %s" + +#: catalog/pg_shdepend.c:1165 +#, c-format +msgid "target of %s" +msgstr "ціль %s" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1173 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%d об'єкт у%s" +msgstr[1] "%d об'єкти в %s" +msgstr[2] "%d об'єктів у %s" +msgstr[3] "%d об'єктів у %s" + +#: catalog/pg_shdepend.c:1284 +#, c-format +msgid "cannot drop objects owned by %s because they are required by the database system" +msgstr "не вдалося видалити об'єкти, що належать %s, оскільки вони потрібні системі бази даних" + +#: catalog/pg_shdepend.c:1431 +#, c-format +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" +msgstr "не вдалося змінити власника об'єктів, що належать ролі %s, тому що вони необхідні системі баз даних" + +#: catalog/pg_subscription.c:171 commands/subscriptioncmds.c:644 +#: commands/subscriptioncmds.c:858 commands/subscriptioncmds.c:1080 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "підписка \"%s\" не існує" + +#: catalog/pg_type.c:131 catalog/pg_type.c:468 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "значення OID в pg_type не задано в режимі двійкового оновлення" + +#: catalog/pg_type.c:249 +#, c-format +msgid "invalid type internal size %d" +msgstr "неприпустимий внутрішній розмір типу %d" + +#: catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:281 +#: catalog/pg_type.c:290 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "вирівнювання \"%c\" недійсне для типу переданого за значенням розміром: %d" + +#: catalog/pg_type.c:297 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "внутрішній розмір %d недійсний для типу, переданого за значенням" + +#: catalog/pg_type.c:307 catalog/pg_type.c:313 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "вирівнювання \"%c\" недійсне для типу змінної довжини" + +#: catalog/pg_type.c:321 commands/typecmds.c:3727 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "для типів фіксованого розміру застосовується лише режим зберігання PLAIN" + +#: catalog/pg_type.c:839 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "не вдалося сформувати ім'я типу масиву для типу \"%s\"" + +#: catalog/storage.c:449 storage/buffer/bufmgr.c:933 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "неприпустима сторінка в блоці %u відношення %s" + +#: catalog/toasting.c:106 commands/indexcmds.c:639 commands/tablecmds.c:5638 +#: commands/tablecmds.c:15576 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "\"%s\" не є таблицею або матеріалізованим поданням" + +#: commands/aggregatecmds.c:171 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "гіпотетичними можуть бути тільки впорядковані агрегати" + +#: commands/aggregatecmds.c:196 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "атрибут агрегату \"%s\" не розпізнано" + +#: commands/aggregatecmds.c:206 +#, c-format +msgid "aggregate stype must be specified" +msgstr "у визначенні агрегату необхідно вказати stype" + +#: commands/aggregatecmds.c:210 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "в визначенні агрегату потребується sfunc" + +#: commands/aggregatecmds.c:222 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "в визначенні агрегату потребується msfunc, коли mstype визначений" + +#: commands/aggregatecmds.c:226 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "в визначенні агрегату потребується minvfunc, коли mstype визначений" + +#: commands/aggregatecmds.c:233 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "msfunc для агрегату не повинна визначатись без mstype" + +#: commands/aggregatecmds.c:237 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "minvfunc для агрегату не повинна визначатись без mstype" + +#: commands/aggregatecmds.c:241 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "mfinalfunc для агрегату не повинна визначатись без mstype" + +#: commands/aggregatecmds.c:245 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "msspace для агрегату не повинна визначатись без mstype" + +#: commands/aggregatecmds.c:249 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "minitcond для агрегату не повинна визначатись без mstype" + +#: commands/aggregatecmds.c:278 +#, c-format +msgid "aggregate input type must be specified" +msgstr "слід указати тип агрегату вводу" + +#: commands/aggregatecmds.c:308 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "в визначенні агрегату з зазначенням вхідного типу не потрібен базовий тип" + +#: commands/aggregatecmds.c:349 commands/aggregatecmds.c:390 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "тип даних агрегату транзакції не може бути %s" + +#: commands/aggregatecmds.c:361 +#, c-format +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "функції серіалізації можуть визначатись, лише коли перехідний тип даних агрегату %s" + +#: commands/aggregatecmds.c:371 +#, c-format +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "повинні визначатись обидві або жодна з серіалізуючих та десеріалізуючих функцій" + +#: commands/aggregatecmds.c:436 commands/functioncmds.c:615 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "параметр \"parallel\" має мати значення SAFE, RESTRICTED, або UNSAFE" + +#: commands/aggregatecmds.c:492 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "параметр \"%s\" має мати значення READ_ONLY, SHAREABLE, або READ_WRITE" + +#: commands/alter.c:84 commands/event_trigger.c:174 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "тригер подій \"%s\" вже існує" + +#: commands/alter.c:87 commands/foreigncmds.c:597 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "джерело сторонніх даних \"%s\" вже існує" + +#: commands/alter.c:90 commands/foreigncmds.c:903 +#, c-format +msgid "server \"%s\" already exists" +msgstr "сервер \"%s\" вже існує" + +#: commands/alter.c:93 commands/proclang.c:132 +#, c-format +msgid "language \"%s\" already exists" +msgstr "мова \"%s\" вже існує" + +#: commands/alter.c:96 commands/publicationcmds.c:183 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "публікація \"%s\" вже існує" + +#: commands/alter.c:99 commands/subscriptioncmds.c:371 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "підписка \"%s\" вже існує" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "перетворення \"%s\" вже існує в схемі \"%s\"" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "об'єкт статистики \"%s\" вже існує в схемі \"%s\"" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr "парсер текстового пошуку \"%s\" вже існує в схемі \"%s\"" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "словник текстового пошуку \"%s\" вже існує в схемі \"%s\"" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "шаблон текстового пошуку \"%s\" вже існує в схемі \"%s\"" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "конфігурація текстового пошуку \"%s\" вже існує в схемі \"%s\"" + +#: commands/alter.c:215 +#, c-format +msgid "must be superuser to rename %s" +msgstr "перейменувати %s може тільки суперкористувач" + +#: commands/alter.c:744 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "встановити схему об'єкту %s може тільки суперкористувач" + +#: commands/amcmds.c:60 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "немає дозволу для створення методу доступу \"%s\"" + +#: commands/amcmds.c:62 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "Тільки суперкористувач може створити метод доступу." + +#: commands/amcmds.c:71 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "метод доступу \"%s\" вже існує" + +#: commands/amcmds.c:130 +#, c-format +msgid "must be superuser to drop access methods" +msgstr "тільки суперкористувач може видалити метод доступу" + +#: commands/amcmds.c:181 commands/indexcmds.c:188 commands/indexcmds.c:790 +#: commands/opclasscmds.c:373 commands/opclasscmds.c:793 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "методу доступу \"%s\" не існує" + +#: commands/amcmds.c:270 +#, c-format +msgid "handler function is not specified" +msgstr "функція-обробник не вказана" + +#: commands/amcmds.c:291 commands/event_trigger.c:183 +#: commands/foreigncmds.c:489 commands/proclang.c:79 commands/trigger.c:687 +#: parser/parse_clause.c:941 +#, c-format +msgid "function %s must return type %s" +msgstr "функція %s повинна повертати тип %s" + +#: commands/analyze.c:226 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "пропуск об'єкту \"%s\" --- неможливо аналізувати цю сторонню таблицю" + +#: commands/analyze.c:243 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "пропуск об'єкту \"%s\" --- неможливо аналізувати не-таблиці або спеціальні системні таблиці" + +#: commands/analyze.c:329 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "аналізується дерево наслідування \"%s.%s\"" + +#: commands/analyze.c:334 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "аналіз \"%s.%s\"" + +#: commands/analyze.c:394 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "стовпець \"%s\" відносно \"%s\" з'являється більше одного разу" + +#: commands/analyze.c:700 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" +msgstr "автоматичний аналіз таблиці \"%s.%s.%s\" використання системи: %s" + +#: commands/analyze.c:1169 +#, c-format +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "\"%s\": проскановано %d з %u сторінок, вони містять %.0f живих рядків і %.0f мертвих рядків; %d рядків вибрані; %.0f приблизне загальне число рядків" + +#: commands/analyze.c:1249 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "пропускається аналіз дерева наслідування \"%s.%s\" --- це дерево наслідування не містить дочірніх таблиць" + +#: commands/analyze.c:1347 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "пропускається аналіз дерева наслідування \"%s.%s\" --- це дерево наслідування не містить аналізуючих дочірніх таблиць" + +#: commands/async.c:634 +#, c-format +msgid "channel name cannot be empty" +msgstr "ім'я каналу не може бути пустим" + +#: commands/async.c:640 +#, c-format +msgid "channel name too long" +msgstr "ім'я каналу задовге" + +#: commands/async.c:645 +#, c-format +msgid "payload string too long" +msgstr "рядок навантаження задовгий" + +#: commands/async.c:864 +#, c-format +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "виконати PREPARE для транзакції, яка виконала LISTEN, UNLISTEN або NOTIFY неможливо" + +#: commands/async.c:970 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "занадто багато сповіщень у черзі NOTIFY" + +#: commands/async.c:1636 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "Черга NOTIFY заповнена на %.0f%%" + +#: commands/async.c:1638 +#, c-format +msgid "The server process with PID %d is among those with the oldest transactions." +msgstr "Серверний процес з PID %d серед процесів з найдавнішими транзакціями." + +#: commands/async.c:1641 +#, c-format +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." +msgstr "Черга NOTIFY не може бути спорожненою, поки цей процес не завершить поточну транзакцію." + +#: commands/cluster.c:125 commands/cluster.c:362 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "не можна кластеризувати тимчасові таблиці з інших сеансів" + +#: commands/cluster.c:133 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "не можна кластеризувати секційну таблицю" + +#: commands/cluster.c:151 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "немає попереднього кластеризованого індексу для таблиці \"%s\"" + +#: commands/cluster.c:165 commands/tablecmds.c:12853 commands/tablecmds.c:14659 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "індекс \"%s\" для таблці \"%s\" не існує" + +#: commands/cluster.c:351 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "не можна кластеризувати спільний каталог" + +#: commands/cluster.c:366 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "не можна очищати тимчасові таблиці з інших сеансів" + +#: commands/cluster.c:432 commands/tablecmds.c:14669 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "\"%s\" не є індексом для таблиці \"%s\"" + +#: commands/cluster.c:440 +#, c-format +msgid "cannot cluster on index \"%s\" because access method does not support clustering" +msgstr "кластеризація за індексом \"%s\" неможлива, тому що метод доступу не підтримує кластеризацію" + +#: commands/cluster.c:452 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "неможливо кластеризувати за секційним індексом \"%s\"" + +#: commands/cluster.c:466 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "неможливо кластеризувати за невірним індексом \"%s\"" + +#: commands/cluster.c:490 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "неможливо помітити індекс кластеризованим в секційній таблиці" + +#: commands/cluster.c:863 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr "кластеризація \"%s.%s\" з використанням сканування індексу \"%s\"" + +#: commands/cluster.c:869 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "кластеризація \"%s.%s\"з використанням послідовного сканування та сортування" + +#: commands/cluster.c:900 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "\"%s\": знайдено версій рядків, що можуть бути видалені: %.0f, що не можуть бути видалені - %.0f, переглянуто сторінок: %u" + +#: commands/cluster.c:904 +#, c-format +msgid "%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "%.0f \"мертві\" версії рядків досі не можуть бути видалені.\n" +"%s." + +#: commands/collationcmds.c:105 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "атрибут collation \"%s\" не розпізнаний" + +#: commands/collationcmds.c:148 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "сортування \"за замовчуванням\" не може бути скопійовано" + +#: commands/collationcmds.c:181 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "нерозпізнаний постачальник правил сортування: %s" + +#: commands/collationcmds.c:190 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "необхідно вказати параметр \"lc_collate\"" + +#: commands/collationcmds.c:195 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "необхідно вказати параметр \"lc_ctype\"" + +#: commands/collationcmds.c:205 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "недетерміновані правила сортування не підтримуються цим провайдером" + +#: commands/collationcmds.c:265 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "правило сортування \"%s\" для кодування \"%s\" вже існує в схемі \"%s\"" + +#: commands/collationcmds.c:276 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "правило сортування \"%s\" вже існує в схемі \"%s\"" + +#: commands/collationcmds.c:324 +#, c-format +msgid "changing version from %s to %s" +msgstr "зміна версії з %s на %s" + +#: commands/collationcmds.c:339 +#, c-format +msgid "version has not changed" +msgstr "версію не змінено" + +#: commands/collationcmds.c:470 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "не вдалося перетворити локальну назву \"%s\" на мітку мови: %s" + +#: commands/collationcmds.c:531 +#, c-format +msgid "must be superuser to import system collations" +msgstr "імпортувати систмені правила сортування може тільки суперкористувач" + +#: commands/collationcmds.c:554 commands/copy.c:1894 commands/copy.c:3480 +#: libpq/be-secure-common.c:81 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "не вдалося виконати команду \"%s\": %m" + +#: commands/collationcmds.c:685 +#, c-format +msgid "no usable system locales were found" +msgstr "придатні системні локалі не знайдені" + +#: commands/comment.c:61 commands/dbcommands.c:841 commands/dbcommands.c:1037 +#: commands/dbcommands.c:1150 commands/dbcommands.c:1340 +#: commands/dbcommands.c:1588 commands/dbcommands.c:1702 +#: commands/dbcommands.c:2142 utils/init/postinit.c:888 +#: utils/init/postinit.c:993 utils/init/postinit.c:1010 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "бази даних \"%s\" не існує" + +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:957 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "\"%s\" не є таблицею, поданням, матеріалізованим поданням, композитним типом або сторонньою таблицею" + +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1923 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "функція \"%s\" не була викликана менеджером тригерів" + +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1932 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "функція \"%s\" повинна запускатися в AFTER ROW" + +#: commands/constraint.c:84 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "функція \"%s\" повинна запускатися для INSERT або UPDATE" + +#: commands/conversioncmds.c:66 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "вихідного кодування \"%s\" не існує" + +#: commands/conversioncmds.c:73 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "цільового кодування \"%s\" не існує" + +#: commands/conversioncmds.c:86 +#, c-format +msgid "encoding conversion to or from \"SQL_ASCII\" is not supported" +msgstr "перетворення кодування в або з \"SQL_ASCII\" не підтримується" + +#: commands/conversioncmds.c:99 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "функція перетворення кодування %s повинна повертати тип %s" + +#: commands/copy.c:426 commands/copy.c:460 +#, c-format +msgid "COPY BINARY is not supported to stdout or from stdin" +msgstr "COPY BINARY не підтримує stdout або stdin" + +#: commands/copy.c:560 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "не вдалося записати в канал програми COPY: %m" + +#: commands/copy.c:565 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "не можливо записати в файл COPY: %m" + +#: commands/copy.c:578 +#, c-format +msgid "connection lost during COPY to stdout" +msgstr "втрачено з'єднання під час COPY в stdout" + +#: commands/copy.c:622 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "не вдалося прочитати файл COPY: %m" + +#: commands/copy.c:640 commands/copy.c:661 commands/copy.c:665 +#: tcop/postgres.c:344 tcop/postgres.c:380 tcop/postgres.c:407 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "неочікуваний обрив з'єднання з клієнтом при відкритій транзакції" + +#: commands/copy.c:678 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "помилка при stdin COPY: %s" + +#: commands/copy.c:694 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "неочікуваний тип повідомлення 0x%02X під час COPY з stdin" + +#: commands/copy.c:861 +#, c-format +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "для використання COPY із зовнішніми програмами потрібноно бути суперкористувачем або членом ролі pg_execute_server_program" + +#: commands/copy.c:862 commands/copy.c:871 commands/copy.c:878 +#, c-format +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." +msgstr "Будь-хто може використати COPY to stdout або from stdin, а також команду psql \\copy." + +#: commands/copy.c:870 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "потрібно бути суперкористувачем або членом ролі pg_read_server_files, щоб виконати COPY з читанням файлу" + +#: commands/copy.c:877 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "потрібно бути суперкористувачем або членом ролі pg_write_server_files, щоб виконати COPY з записом у файл" + +#: commands/copy.c:963 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM не підтримується із захистом на рівні рядків" + +#: commands/copy.c:964 +#, c-format +msgid "Use INSERT statements instead." +msgstr "Використайте оператори INSERT замість цього." + +#: commands/copy.c:1146 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "Формат \"%s\" для COPY не розпізнано" + +#: commands/copy.c:1217 commands/copy.c:1233 commands/copy.c:1248 +#: commands/copy.c:1270 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "аргументом функції \"%s\" повинен бути список імен стовпців" + +#: commands/copy.c:1285 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "аргументом функції \"%s\" повинне бути припустиме ім'я коду" + +#: commands/copy.c:1292 commands/dbcommands.c:253 commands/dbcommands.c:1536 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "параметр \"%s\" не розпізнано" + +#: commands/copy.c:1304 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "неможливо визначити DELIMITER в режимі BINARY" + +#: commands/copy.c:1309 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "неможливо визначити NULL в режимі BINARY" + +#: commands/copy.c:1331 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "роздільник для COPY повинен бути однобайтовим символом" + +#: commands/copy.c:1338 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "Роздільник для COPY не може бути символом нового рядка або повернення каретки" + +#: commands/copy.c:1344 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "Подання NULL для COPY не може включати символ нового рядка або повернення каретки" + +#: commands/copy.c:1361 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "роздільник COPY не може бути \"%s\"" + +#: commands/copy.c:1367 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "COPY HEADER доступний тільки в режимі CSV" + +#: commands/copy.c:1373 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "лапки для COPY доустпні тільки в режимі CSV" + +#: commands/copy.c:1378 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "лапки для COPY повинні бути однобайтовим символом" + +#: commands/copy.c:1383 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "роздільник і лапки для COPY повинні бути різними" + +#: commands/copy.c:1389 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "вихід для COPY доступний тільки в режимі CSV" + +#: commands/copy.c:1394 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "вихід для COPY повинен бути однобайтовим символом" + +#: commands/copy.c:1400 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "Параметр force quote для COPY можна використати тільки в режимі CSV" + +#: commands/copy.c:1404 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "Параметр force quote для COPY можна використати тільки з COPY TO" + +#: commands/copy.c:1410 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "Параметр force not null для COPY можна використати тільки в режимі CSV" + +#: commands/copy.c:1414 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "Параметр force not null для COPY можна використати тільки з COPY FROM" + +#: commands/copy.c:1420 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "Параметр force null для COPY можна використати тільки в режимі CSV" + +#: commands/copy.c:1425 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "Параметр force null only для COPY можна використати тільки з COPY FROM" + +#: commands/copy.c:1431 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "роздільник COPY не повинен з'являтися у специфікації NULL" + +#: commands/copy.c:1438 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "лапки CSV не повинні з'являтися у специфікації NULL" + +#: commands/copy.c:1524 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "правила DO INSTEAD NOTHING не підтримуються для COPY" + +#: commands/copy.c:1538 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "умовні правила DO INSTEAD не підтримуються для COPY" + +#: commands/copy.c:1542 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "правила DO ALSO не підтримуються для COPY" + +#: commands/copy.c:1547 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "складові правила DO INSTEAD не підтримуються з COPY" + +#: commands/copy.c:1557 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO) не підтримується" + +#: commands/copy.c:1574 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "В запиті COPY повинно бути речення RETURNING" + +#: commands/copy.c:1603 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "відношення, згадане в операторі COPY, змінилось" + +#: commands/copy.c:1662 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "Стовпець FORCE_QUOTE \"%s\" не фігурує в COPY" + +#: commands/copy.c:1685 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "Стовпець FORCE_NOT_NULL \"%s\" не фігурує в COPY" + +#: commands/copy.c:1708 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "Стовпець FORCE_NULL \"%s\" не фігурує в COPY" + +#: commands/copy.c:1774 libpq/be-secure-common.c:105 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "не вдалося закрити канал за допомогою зовнішньої команди: %m" + +#: commands/copy.c:1789 +#, c-format +msgid "program \"%s\" failed" +msgstr "збій програми \"%s\"" + +#: commands/copy.c:1840 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "неможливо скопіювати з подання \"%s\"" + +#: commands/copy.c:1842 commands/copy.c:1848 commands/copy.c:1854 +#: commands/copy.c:1865 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "Спробуйте варіацію COPY (SELECT ...) TO." + +#: commands/copy.c:1846 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "неможливо скопіювати з матеріалізованого подання \"%s\"" + +#: commands/copy.c:1852 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "неможливо скопіювати зі сторонньої таблиці \"%s\"" + +#: commands/copy.c:1858 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "не вдалося скопіювати з послідовності \"%s\"" + +#: commands/copy.c:1863 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "неможливо скопіювати з секційної таблиці \"%s\"" + +#: commands/copy.c:1869 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "не можна копіювати з відношення \"%s\", котре не є таблицею" + +#: commands/copy.c:1909 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "при виконанні COPY в файл не можна вказувати відносний шлях" + +#: commands/copy.c:1928 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "не вдалося відкрити файл \"%s\" для запису: %m" + +#: commands/copy.c:1931 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TO наказує серверному процесу PostgreSQL записати дані до файлу. Можливо, вам потрібна клієнтська команда, наприклад \\copy в psql." + +#: commands/copy.c:1944 commands/copy.c:3511 +#, c-format +msgid "\"%s\" is a directory" +msgstr "\"%s\" - каталог" + +#: commands/copy.c:2246 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, рядок%s, стовпець %s" + +#: commands/copy.c:2250 commands/copy.c:2297 +#, c-format +msgid "COPY %s, line %s" +msgstr "COPY %s, рядок %s" + +#: commands/copy.c:2261 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, рядок %s, стовпець %s: \"%s\"" + +#: commands/copy.c:2269 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, рядок %s, стовпець %s: значення нуль" + +#: commands/copy.c:2291 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, рядок %s: \"%s\"" + +#: commands/copy.c:2692 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "неможливо скопіювати до подання \"%s\"" + +#: commands/copy.c:2694 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "Щоб подання допускало копіювання даних у нього, встановіть тригер INSTEAD OF INSERT." + +#: commands/copy.c:2698 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "не можна копіювати матеріалізоване подання \"%s\"" + +#: commands/copy.c:2703 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "неможливо скопіювати послідовність \"%s\"" + +#: commands/copy.c:2708 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "неможливо копіювати у відношення \"%s\", яке не є таблицею" + +#: commands/copy.c:2748 +#, c-format +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "виконати COPY FREEZE в секціонованій таблиці не можна" + +#: commands/copy.c:2763 +#, c-format +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "виконати COPY FREEZE через попередню активність в транзакції не можна" + +#: commands/copy.c:2769 +#, c-format +msgid "cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "не можна виконати COPY FREEZE, тому, що таблиця не була створена або скорочена в поточній підтранзакції" + +#: commands/copy.c:3498 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY FROM наказує серверному процесу PostgreSQL прочитати дані з файлу. Можливо, вам потрібна клієнтська команда, наприклад \\copy в psql." + +#: commands/copy.c:3526 +#, c-format +msgid "COPY file signature not recognized" +msgstr "Підпис COPY-файлу не розпізнано" + +#: commands/copy.c:3531 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "невірний заголовок файлу COPY (відсутні прапори)" + +#: commands/copy.c:3535 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "невірний заголовок файла COPY (WITH OIDS)" + +#: commands/copy.c:3540 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "не розпізнано важливі прапори в заголовку файлу COPY" + +#: commands/copy.c:3546 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "невірний заголовок файлу COPY (відсутня довжина)" + +#: commands/copy.c:3553 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "невірний заголовок файлу COPY (невірна довжина)" + +#: commands/copy.c:3672 commands/copy.c:4337 commands/copy.c:4567 +#, c-format +msgid "extra data after last expected column" +msgstr "зайві дані після вмісту останнього стовпця" + +#: commands/copy.c:3686 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "відсутні дані для стовпця \"%s\"" + +#: commands/copy.c:3769 +#, c-format +msgid "received copy data after EOF marker" +msgstr "після маркера кінця файлу продовжуються дані COPY" + +#: commands/copy.c:3776 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "кількість полів у рядку: %d, очікувалось: %d" + +#: commands/copy.c:4096 commands/copy.c:4113 +#, c-format +msgid "literal carriage return found in data" +msgstr "в даних виявлено явне повернення каретки" + +#: commands/copy.c:4097 commands/copy.c:4114 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "в даних виявлено повернення каретки без лапок" + +#: commands/copy.c:4099 commands/copy.c:4116 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "Використайте \"\\r\", щоб позначити повернення каретки." + +#: commands/copy.c:4100 commands/copy.c:4117 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "Використайте CSV в лапках, щоб позначити повернення каретки." + +#: commands/copy.c:4129 +#, c-format +msgid "literal newline found in data" +msgstr "в даних знайдено явний новий рядок" + +#: commands/copy.c:4130 +#, c-format +msgid "unquoted newline found in data" +msgstr "в даних знайдено новий рядок без лапок" + +#: commands/copy.c:4132 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "Використайте \"\\n\", щоб представити новий рядок." + +#: commands/copy.c:4133 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "Використайте CSV в лапках, щоб позначити новий рядок." + +#: commands/copy.c:4179 commands/copy.c:4215 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "маркер \"кінець копії\" не відповідає попередньому стилю нового рядка" + +#: commands/copy.c:4188 commands/copy.c:4204 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "маркер \"кінець копії\" зіпсований" + +#: commands/copy.c:4651 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "незакінчене поле в лапках CSV" + +#: commands/copy.c:4728 commands/copy.c:4747 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "неочікуваний кінец файлу в даних COPY" + +#: commands/copy.c:4737 +#, c-format +msgid "invalid field size" +msgstr "невірний розмір поля" + +#: commands/copy.c:4760 +#, c-format +msgid "incorrect binary data format" +msgstr "невірний двійковий формат даних" + +#: commands/copy.c:5068 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "стовпець \"%s\" є згенерованим стовпцем" + +#: commands/copy.c:5070 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "Згенеровані стовпці не можна використовувати в COPY." + +#: commands/copy.c:5085 commands/indexcmds.c:1700 commands/statscmds.c:217 +#: commands/tablecmds.c:2176 commands/tablecmds.c:2795 +#: commands/tablecmds.c:3182 parser/parse_relation.c:3507 +#: parser/parse_relation.c:3527 utils/adt/tsvector_op.c:2668 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "стовпця \"%s\" не існує" + +#: commands/copy.c:5092 commands/tablecmds.c:2202 commands/trigger.c:885 +#: parser/parse_target.c:1052 parser/parse_target.c:1063 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "стовпець \"%s\" вказано більше чим один раз" + +#: commands/createas.c:215 commands/createas.c:497 +#, c-format +msgid "too many column names were specified" +msgstr "вказано забагато імен стовпців" + +#: commands/createas.c:539 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "політики для цієї команди все ще не реалізовані" + +#: commands/dbcommands.c:246 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATION більше не підтримується" + +#: commands/dbcommands.c:247 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "Розгляньте можливість використання табличних просторів." + +#: commands/dbcommands.c:261 +#, c-format +msgid "LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE." +msgstr "LOCALE не може вказуватись разом з LC_COLLATE або LC_CTYPE." + +#: commands/dbcommands.c:279 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%d не є вірним кодом кодування" + +#: commands/dbcommands.c:290 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%s не є вірним ім'ям кодування" + +#: commands/dbcommands.c:314 commands/dbcommands.c:1569 commands/user.c:275 +#: commands/user.c:691 +#, c-format +msgid "invalid connection limit: %d" +msgstr "недійсний ліміт з'єднання: %d" + +#: commands/dbcommands.c:333 +#, c-format +msgid "permission denied to create database" +msgstr "немає дозволу для створення бази даних" + +#: commands/dbcommands.c:356 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "шаблону бази даних \"%s\" не існує" + +#: commands/dbcommands.c:368 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "немає дозволу для копіювання бази даних \"%s\"" + +#: commands/dbcommands.c:384 +#, c-format +msgid "invalid server encoding %d" +msgstr "недійсний сервер кодування %d" + +#: commands/dbcommands.c:390 commands/dbcommands.c:395 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "неприпустиме ім'я локалі: \"%s\"" + +#: commands/dbcommands.c:415 +#, c-format +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" +msgstr "нове кодування (%s) несумісне з кодуванням шаблона бази даних (%s)" + +#: commands/dbcommands.c:418 +#, c-format +msgid "Use the same encoding as in the template database, or use template0 as template." +msgstr "Використайте кодування шаблона бази даних або виберіть template0 в якості шаблона." + +#: commands/dbcommands.c:423 +#, c-format +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" +msgstr "нове правило сортування (%s) несумісне з правилом в шаблоні бази даних (%s)" + +#: commands/dbcommands.c:425 +#, c-format +msgid "Use the same collation as in the template database, or use template0 as template." +msgstr "Використайте те ж саме правило сортування, що і в шаблоні бази даних, або виберіть template0 в якості шаблона." + +#: commands/dbcommands.c:430 +#, c-format +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" +msgstr "новий параметр LC_CTYPE (%s) несумісний з LC_CTYPE в шаблоні бази даних (%s)" + +#: commands/dbcommands.c:432 +#, c-format +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." +msgstr "Використайте той самий LC_CTYPE, що і в шаблоні бази даних, або виберіть template0 в якості шаблона." + +#: commands/dbcommands.c:454 commands/dbcommands.c:1196 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "pg_global не можна використати в якості табличного простору за замовчуванням" + +#: commands/dbcommands.c:480 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "не вдалося призначити новий табличний простір за замовчуванням \"%s\"" + +#: commands/dbcommands.c:482 +#, c-format +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." +msgstr "БД \"%s\" вже містить таблиці, що знаходяться в цьому табличному просторі." + +#: commands/dbcommands.c:512 commands/dbcommands.c:1066 +#, c-format +msgid "database \"%s\" already exists" +msgstr "база даних \"%s\" вже існує" + +#: commands/dbcommands.c:526 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "вихідна база даних \"%s\" зайнята іншими користувачами" + +#: commands/dbcommands.c:769 commands/dbcommands.c:784 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "кодування \"%s\" не відповідає локалі \"%s\"" + +#: commands/dbcommands.c:772 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "Обраний параметр LC_CTYPE потребує кодування \"%s\"." + +#: commands/dbcommands.c:787 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "Обраний параметр LC_COLLATE потребує кодування \"%s\"." + +#: commands/dbcommands.c:848 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "бази даних \"%s\" не існує, пропускаємо" + +#: commands/dbcommands.c:872 +#, c-format +msgid "cannot drop a template database" +msgstr "неможливо видалити шаблон бази даних" + +#: commands/dbcommands.c:878 +#, c-format +msgid "cannot drop the currently open database" +msgstr "неможливо видалити наразі відкриту базу даних" + +#: commands/dbcommands.c:891 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "база даних \"%s\" використовується активним слотом логічної реплікації" + +#: commands/dbcommands.c:893 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "Активний слот %d." +msgstr[1] "Активні слоти %d." +msgstr[2] "Активних слотів %d." +msgstr[3] "Активних слотів %d." + +#: commands/dbcommands.c:907 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "база даних \"%s\" використовується в підписці логічної реплікації" + +#: commands/dbcommands.c:909 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "Знайдено підписку %d." +msgstr[1] "Знайдено підписки %d." +msgstr[2] "Знайдено підписок %d." +msgstr[3] "Знайдено підписок %d." + +#: commands/dbcommands.c:930 commands/dbcommands.c:1088 +#: commands/dbcommands.c:1218 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "база даних \"%s\" зайнята іншими користувачами" + +#: commands/dbcommands.c:1048 +#, c-format +msgid "permission denied to rename database" +msgstr "немає дозволу для перейменування бази даних" + +#: commands/dbcommands.c:1077 +#, c-format +msgid "current database cannot be renamed" +msgstr "поточна база даних не може бути перейменована" + +#: commands/dbcommands.c:1174 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "неможливо змінити табличний простір наразі відкритої бази даних" + +#: commands/dbcommands.c:1277 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "деякі відношення бази даних \"%s\" вже є в табличному просторі \"%s\"" + +#: commands/dbcommands.c:1279 +#, c-format +msgid "You must move them back to the database's default tablespace before using this command." +msgstr "Перед тим, як виконувати цю команду, вам треба повернути їх в табличний простір за замовчуванням для цієї бази даних." + +#: commands/dbcommands.c:1404 commands/dbcommands.c:1980 +#: commands/dbcommands.c:2203 commands/dbcommands.c:2261 +#: commands/tablespace.c:619 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "у старому каталозі бази даних \"%s\" могли залишитися непотрібні файли" + +#: commands/dbcommands.c:1460 +#, c-format +msgid "unrecognized DROP DATABASE option \"%s\"" +msgstr "нерозпізнаний параметр DROP DATABASE \"%s\"" + +#: commands/dbcommands.c:1550 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "параметр \"%s\" не може бути вказаним з іншими параметрами" + +#: commands/dbcommands.c:1606 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "не можна заборонити з'єднання для поточної бази даних" + +#: commands/dbcommands.c:1742 +#, c-format +msgid "permission denied to change owner of database" +msgstr "немає дозволу для зміни власника бази даних" + +#: commands/dbcommands.c:2086 +#, c-format +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." +msgstr "Знайдено %d інших сеансів і %d підготованих транзакцій з використанням цієї бази даних." + +#: commands/dbcommands.c:2089 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "Є %d іншого сеансу з використанням цієї бази даних." +msgstr[1] "Є %d інші сеанси з використанням цієї бази даних." +msgstr[2] "Є %d інших сеансів з використанням цієї бази даних." +msgstr[3] "Є %d інших сеансів з використанням цієї бази даних." + +#: commands/dbcommands.c:2094 storage/ipc/procarray.c:3016 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "З цією базою даних пов'язана %d підготовлена транзакція." +msgstr[1] "З цією базою даних пов'язані %d підготовлені транзакції." +msgstr[2] "З цією базою даних пов'язані %d підготовлених транзакцій." +msgstr[3] "З цією базою даних пов'язані %d підготовлених транзакцій." + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 +#: commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%s потребує параметру" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 +#: commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%s потребує числового значення" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "%s потребує логічного значення" + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%s потребує ціле значення" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "аргументом %s повинно бути ім'я" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "аргументом %s повинно бути ім'я типу" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "невірний аргумент для %s: \"%s\"" + +#: commands/dropcmds.c:100 commands/functioncmds.c:1274 +#: utils/adt/ruleutils.c:2633 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "\"%s\" є функцією агрегату" + +#: commands/dropcmds.c:102 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "Використайте DROP AGGREGATE, щоб видалити агрегатні функції." + +#: commands/dropcmds.c:158 commands/sequence.c:447 commands/tablecmds.c:3266 +#: commands/tablecmds.c:3424 commands/tablecmds.c:3469 +#: commands/tablecmds.c:15038 tcop/utility.c:1309 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "відношення \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:188 commands/dropcmds.c:287 commands/tablecmds.c:1199 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "схеми \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:228 commands/dropcmds.c:267 commands/tablecmds.c:259 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "типу \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:257 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "методу доступу \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:275 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "правила сортування \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:282 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "перетворення \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:293 commands/statscmds.c:479 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "об'єкту статистики \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:300 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr "парсеру текстового пошуку \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:307 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "словника текстового пошуку \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:314 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "шаблону текстового пошуку \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:321 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "конфігурації текстового пошуку \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:326 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "розширення \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:336 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "функції %s(%s) не існує, пропускаємо" + +#: commands/dropcmds.c:349 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "процедури %s(%s) не існує, пропускаємо" + +#: commands/dropcmds.c:362 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "підпрограми %s(%s) не існує, пропускаємо" + +#: commands/dropcmds.c:375 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "агрегату %s(%s) не існує, пропускаємо" + +#: commands/dropcmds.c:388 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "оператора \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:394 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "мови \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:403 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "приведення від типу %s до типу %s не існує, пропускаємо" + +#: commands/dropcmds.c:412 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "трансформації для типу %s мови \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:420 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "тригеру \"%s\" для відношення \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:429 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "політики \"%s\" для відношення \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:436 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "тригеру подій \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:442 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "правила \"%s\" для відношення \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:449 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "джерела сторонніх даних \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:453 commands/foreigncmds.c:1399 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "серверу \"%s\" не існує, пропускаємо" + +#: commands/dropcmds.c:462 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "класу операторів \"%s\" не існує для методу доступу \"%s\", пропускаємо" + +#: commands/dropcmds.c:474 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "сімейства операторів \"%s\" не існує для методу доступу \"%s\", пропускаємо" + +#: commands/dropcmds.c:481 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "публікації \"%s\" не існує, пропускаємо" + +#: commands/event_trigger.c:125 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "немає дозволу для створення тригера подій %s\"" + +#: commands/event_trigger.c:127 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "Тільки суперкористувач може створити тригер подій." + +#: commands/event_trigger.c:136 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "нерозпізнане ім'я подій \"%s\"" + +#: commands/event_trigger.c:153 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "нерозпізнана змінна фільтру \"%s\"" + +#: commands/event_trigger.c:207 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "значення фільтру \"%s\" не розпізнано для змінної фільтру \"%s\"" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:213 commands/event_trigger.c:235 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "для %s тригери подій не підтримуються" + +#: commands/event_trigger.c:248 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "змінну фільтра \"%s\" вказано кілька разів" + +#: commands/event_trigger.c:399 commands/event_trigger.c:443 +#: commands/event_trigger.c:537 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "тригеру подій \"%s\" не існує" + +#: commands/event_trigger.c:505 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "немає дозволу для зміни власника тригера подій \"%s\"" + +#: commands/event_trigger.c:507 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "Власником тригеру подій може бути тільки суперкористувач." + +#: commands/event_trigger.c:1325 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%s можливо викликати лише в подієвій тригерній функції sql_drop" + +#: commands/event_trigger.c:1445 commands/event_trigger.c:1466 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%s можливо викликати лише в подієвій тригерній функції table_rewrite" + +#: commands/event_trigger.c:1883 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%s можливо викликати тільки в подієвій тригерній функції" + +#: commands/explain.c:213 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "нерозпізнане значення параметру EXPLAIN \"%s\": \"%s\"" + +#: commands/explain.c:220 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "нерозпізнаний параметр EXPLAIN \"%s\"" + +#: commands/explain.c:228 +#, c-format +msgid "EXPLAIN option WAL requires ANALYZE" +msgstr "Параметр WAL оператора EXPLAIN потребує вказівки ANALYZE" + +#: commands/explain.c:237 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "Параметр TIMING оператора EXPLAIN потребує вказівки ANALYZE" + +#: commands/extension.c:173 commands/extension.c:3013 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "розширення \"%s\" не існує" + +#: commands/extension.c:272 commands/extension.c:281 commands/extension.c:293 +#: commands/extension.c:303 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "невірне ім'я розширення: \"%s\"" + +#: commands/extension.c:273 +#, c-format +msgid "Extension names must not be empty." +msgstr "Імена розширення не повинні бути пустими." + +#: commands/extension.c:282 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "Імена розширення не повинні містити \"--\"." + +#: commands/extension.c:294 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "Імена розширення не повинні починатися або закінчуватися символом \"-\"." + +#: commands/extension.c:304 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "Імена розширення не повинні містити роздільники шляху." + +#: commands/extension.c:319 commands/extension.c:328 commands/extension.c:337 +#: commands/extension.c:347 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "невірне ім'я версії розширення: \"%s\"" + +#: commands/extension.c:320 +#, c-format +msgid "Version names must not be empty." +msgstr "Імена версії не повинні бути пустими." + +#: commands/extension.c:329 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "Імена версії не повинні містити \"--\"." + +#: commands/extension.c:338 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "Імена версії не повинні починатись або закінчуватись символом \"-\"." + +#: commands/extension.c:348 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "Імена версії не повинні містити роздільники шляху." + +#: commands/extension.c:498 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "не вдалося відкрити керуючий файл розширення \"%s\": %m" + +#: commands/extension.c:520 commands/extension.c:530 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "параметр \"%s\" не можна задавати в додатковому керуючому файлі розширення" + +#: commands/extension.c:552 commands/extension.c:560 commands/extension.c:568 +#: utils/misc/guc.c:6749 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "параметр \"%s\" потребує логічного значення" + +#: commands/extension.c:577 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "\"%s\" не є невірним ім'ям кодування" + +#: commands/extension.c:591 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "параметр \"%s\" повинен містити список імен розширень" + +#: commands/extension.c:598 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "нерозпізнаний параметр \"%s\" в файлі \"%s\"" + +#: commands/extension.c:607 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr "параметр \"schema\" не може бути вказаним, коли \"relocatable\" є дійсним" + +#: commands/extension.c:785 +#, c-format +msgid "transaction control statements are not allowed within an extension script" +msgstr "в скрипті розширення не повинно бути операторів управління транзакціями" + +#: commands/extension.c:861 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "немає дозволу для створення розширення %s\"" + +#: commands/extension.c:864 +#, c-format +msgid "Must have CREATE privilege on current database to create this extension." +msgstr "Необхідно мати право CREATE для поточної бази даних щоб створити це розширення." + +#: commands/extension.c:865 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "Тільки суперкористувач може створити це розширення." + +#: commands/extension.c:869 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "немає дозволу для оновлення розширення %s\"" + +#: commands/extension.c:872 +#, c-format +msgid "Must have CREATE privilege on current database to update this extension." +msgstr "Необхідно мати право CREATE для поточної бази даних щоб оновити це розширення." + +#: commands/extension.c:873 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "Тільки суперкористувач може оновити це розширення." + +#: commands/extension.c:1200 +#, c-format +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "розширення \"%s\" не має жодного шляху оновлення від версії \"%s\" до версії \"%s\"" + +#: commands/extension.c:1408 commands/extension.c:3074 +#, c-format +msgid "version to install must be specified" +msgstr "для інсталяції слід указати версію" + +#: commands/extension.c:1445 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "розширення \"%s\" не має ні скрипту для встановлення, ні шляху оновлення для версії \"%s\"" + +#: commands/extension.c:1479 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "розширення \"%s\" треба встановлювати в схемі \"%s\"" + +#: commands/extension.c:1639 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "виявлено циклічну залежність між розширеннями \"%s\" і \"%s\"" + +#: commands/extension.c:1644 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "встановлення необхідних розширень \"%s\"" + +#: commands/extension.c:1667 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr "необхідні розширення \"%s\" не встановлено" + +#: commands/extension.c:1670 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "Використайте CREATE EXTENSION ... CASCADE також для встановлення необхідних розширень." + +#: commands/extension.c:1705 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "розширення \"%s\" вже існує, пропускаємо" + +#: commands/extension.c:1712 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "розширення \"%s\" вже існує" + +#: commands/extension.c:1723 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "вкладенні оператори CREATE EXTENSION не підтримуються" + +#: commands/extension.c:1896 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "неможливо видалити розширення \"%s\", оскільки воно змінюється" + +#: commands/extension.c:2457 +#, c-format +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "%s можна викликати лише з SQL-скрипта, виконаного CREATE EXTENSION" + +#: commands/extension.c:2469 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "OID %u не посилається на таблицю" + +#: commands/extension.c:2474 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "таблиця \"%s\" не є членом створеного розширення" + +#: commands/extension.c:2828 +#, c-format +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" +msgstr "неможливо перемістити розширення \"%s\" в схему \"%s\", оскільки розширення містить схему" + +#: commands/extension.c:2869 commands/extension.c:2932 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "розширення \"%s\" не підтримує SET SCHEMA" + +#: commands/extension.c:2934 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "%s не є схемою розширення \"%s\"" + +#: commands/extension.c:2993 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "вкладенні оператори ALTER EXTENSION не підтримуються" + +#: commands/extension.c:3085 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "версія \"%s\" розширення \"%s\" вже встановлена" + +#: commands/extension.c:3336 +#, c-format +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" +msgstr "неможливо додати схему \"%s\" до розширення \"%s\", оскільки схема містить розширення" + +#: commands/extension.c:3364 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "%s не є членом розширення \"%s\"" + +#: commands/extension.c:3430 +#, c-format +msgid "file \"%s\" is too large" +msgstr "файл \"%s\" занадто великий" + +#: commands/foreigncmds.c:148 commands/foreigncmds.c:157 +#, c-format +msgid "option \"%s\" not found" +msgstr "параметр \"%s\" не знайдено" + +#: commands/foreigncmds.c:167 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "параметр \"%s\" надано більше одного разу" + +#: commands/foreigncmds.c:221 commands/foreigncmds.c:229 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "немає дозволу для зміни власника джерела сторонніх даних \"%s\"" + +#: commands/foreigncmds.c:223 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "Треба бути суперкористувачем, щоб змінити власника джерела сторонніх даних." + +#: commands/foreigncmds.c:231 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "Власником джерела сторонніх даних може бути тільки суперкористувач." + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:711 foreign/foreign.c:701 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "джерела сторонніх даних \"%s\" не існує" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "немає дозволу для створення джерела сторонніх даних %s\"" + +#: commands/foreigncmds.c:586 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "Треба бути суперкористувачем, щоб створити джерело сторонніх даних." + +#: commands/foreigncmds.c:701 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "немає дозволу на зміну джерела сторонніх даних \"%s\"" + +#: commands/foreigncmds.c:703 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "Треба бути суперкористувачем, щоб змінити джерело сторонніх даних." + +#: commands/foreigncmds.c:734 +#, c-format +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" +msgstr "при зміні обробника в обгортці сторонніх даних може змінитися поведінка існуючих сторонніх таблиць" + +#: commands/foreigncmds.c:749 +#, c-format +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +msgstr "при зміні функції перевірки в обгортці сторонніх даних параметри залежних об'єктів можуть стати невірними" + +#: commands/foreigncmds.c:895 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "сервер \"%s\" вже існує, пропускаємо" + +#: commands/foreigncmds.c:1183 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "зіставлення користувача \"%s\" для сервера \"%s\" вже існує, пропускаємо" + +#: commands/foreigncmds.c:1193 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "зіставлення користувача \"%s\" для сервера \"%s\" вже існує\"" + +#: commands/foreigncmds.c:1293 commands/foreigncmds.c:1413 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "зіставлення користувача \"%s\" не існує для сервера \"%s\"" + +#: commands/foreigncmds.c:1418 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "зіставлення користувача \"%s\" не існує для сервера \"%s\", пропускаємо" + +#: commands/foreigncmds.c:1569 foreign/foreign.c:389 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "джерело сторонніх даних \"%s\" не має обробника" + +#: commands/foreigncmds.c:1575 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "джерело сторонніх даних \"%s\" не підтримує IMPORT FOREIGN SCHEMA" + +#: commands/foreigncmds.c:1678 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "імпорт сторонньої таблиці \"%s\"" + +#: commands/functioncmds.c:104 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "SQL-функція не може повертати тип оболонки %s" + +#: commands/functioncmds.c:109 +#, c-format +msgid "return type %s is only a shell" +msgstr "тип, що повертається, %s - лише оболонка" + +#: commands/functioncmds.c:139 parser/parse_type.c:354 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "для типу оболонки \"%s\" неможливо вказати модифікатор типу" + +#: commands/functioncmds.c:145 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "тип \"%s\" все ще не визначений" + +#: commands/functioncmds.c:146 +#, c-format +msgid "Creating a shell type definition." +msgstr "Створення визначення типу оболонки." + +#: commands/functioncmds.c:238 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "SQL-функція не може приймати значення типу оболонки %s" + +#: commands/functioncmds.c:244 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "агрегатна функція не може приймати значення типу оболонки %s" + +#: commands/functioncmds.c:249 +#, c-format +msgid "argument type %s is only a shell" +msgstr "тип аргументу %s - лише оболонка" + +#: commands/functioncmds.c:259 +#, c-format +msgid "type %s does not exist" +msgstr "тип \"%s\" не існує" + +#: commands/functioncmds.c:273 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "агрегатні функції не приймають в аргументах набору" + +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "процедури не приймають в аргументах набору" + +#: commands/functioncmds.c:281 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "функції не приймають в аргументах набору" + +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "процедури не можуть мати OUT-аргументи" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "Аргументи INOUT дозволені." + +#: commands/functioncmds.c:300 +#, c-format +msgid "VARIADIC parameter must be the last input parameter" +msgstr "Параметр VARIADIC повинен бути останнім в списку вхідних параметрів" + +#: commands/functioncmds.c:331 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "Параметр VARIADIC повинен бути масивом" + +#: commands/functioncmds.c:371 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "ім'я параметру «%s» використано декілька разів" + +#: commands/functioncmds.c:386 +#, c-format +msgid "only input parameters can have default values" +msgstr "тільки ввідні параметри можуть мати значення за замовчуванням" + +#: commands/functioncmds.c:401 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "у значенні параметру за замовчуванням не можна посилатись на таблиці" + +#: commands/functioncmds.c:425 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "вхідні параметри, наступні за параметром зі значенням \"за замовчуванням\", також повинні мати значення \"за замовчуванням\"" + +#: commands/functioncmds.c:577 commands/functioncmds.c:768 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "некоректний атрибут у визначенні процедури" + +#: commands/functioncmds.c:673 +#, c-format +msgid "support function %s must return type %s" +msgstr "функція підтримки %s повинна повертати тип %s" + +#: commands/functioncmds.c:684 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "для уточнення функції підтримки потрібно бути суперкористувачем" + +#: commands/functioncmds.c:800 +#, c-format +msgid "no function body specified" +msgstr "не вказано тіло функції" + +#: commands/functioncmds.c:810 +#, c-format +msgid "no language specified" +msgstr "не вказано жодної мови" + +#: commands/functioncmds.c:835 commands/functioncmds.c:1319 +#, c-format +msgid "COST must be positive" +msgstr "COST має бути додатнім" + +#: commands/functioncmds.c:843 commands/functioncmds.c:1327 +#, c-format +msgid "ROWS must be positive" +msgstr "Значення ROWS повинно бути позитивним" + +#: commands/functioncmds.c:897 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "для мови \"%s\" потрібен лише один вираз AS" + +#: commands/functioncmds.c:995 commands/functioncmds.c:2048 +#: commands/proclang.c:259 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "мови \"%s\" не існує" + +#: commands/functioncmds.c:997 commands/functioncmds.c:2050 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Використайте CREATE EXTENSION, щоб завантажити мову в базу даних." + +#: commands/functioncmds.c:1032 commands/functioncmds.c:1311 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "лише суперкористувачі можуть визначити функцію з атрибутом leakproof" + +#: commands/functioncmds.c:1081 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "результат функції повинен мати тип %s відповідно з параметрами OUT" + +#: commands/functioncmds.c:1094 +#, c-format +msgid "function result type must be specified" +msgstr "необхідно вказати тип результату функції" + +#: commands/functioncmds.c:1146 commands/functioncmds.c:1331 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "ROWS не застосовується, коли функція не повертає набір" + +#: commands/functioncmds.c:1431 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "вихідний тип даних %s є псевдотипом" + +#: commands/functioncmds.c:1437 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "цільовий тип даних %s є псевдотипом" + +#: commands/functioncmds.c:1461 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "приведення буде ігноруватися, оскільки вихідні дані мають тип домену" + +#: commands/functioncmds.c:1466 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "приведення буде ігноруватися, оскільки цільові дані мають тип домену" + +#: commands/functioncmds.c:1491 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "функція приведення повинна приймати від одного до трьох аргументів" + +#: commands/functioncmds.c:1495 +#, c-format +msgid "argument of cast function must match or be binary-coercible from source data type" +msgstr "аргумент функції приведення повинен співпадати або бути двійково-сумісним з вихідним типом даних" + +#: commands/functioncmds.c:1499 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "другий аргумент функції приведення повинен мати тип %s" + +#: commands/functioncmds.c:1504 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "третій аргумент функції приведення повинен мати тип %s" + +#: commands/functioncmds.c:1509 +#, c-format +msgid "return data type of cast function must match or be binary-coercible to target data type" +msgstr "тип вертаючих даних функції приведення повинен співпадати або бути двійково-сумісним з цільовим типом даних" + +#: commands/functioncmds.c:1520 +#, c-format +msgid "cast function must not be volatile" +msgstr "функція приведення не може бути змінною (volatile)" + +#: commands/functioncmds.c:1525 +#, c-format +msgid "cast function must be a normal function" +msgstr "функція приведення повинна бути звичайною функцією" + +#: commands/functioncmds.c:1529 +#, c-format +msgid "cast function must not return a set" +msgstr "функція приведення не може вертати набір" + +#: commands/functioncmds.c:1555 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "тільки суперкористувач може створити приведення WITHOUT FUNCTION" + +#: commands/functioncmds.c:1570 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "вихідний та цільовий типи даних не сумісні фізично" + +#: commands/functioncmds.c:1585 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "складені типи даних не сумісні на двійковому рівні" + +#: commands/functioncmds.c:1591 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "типи переліку не сумісні на двійковому рівні" + +#: commands/functioncmds.c:1597 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "типи масивів не сумісні на двійковому рівні" + +#: commands/functioncmds.c:1614 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "типи доменів не можуть вважатись сумісними на двійковому рівні" + +#: commands/functioncmds.c:1624 +#, c-format +msgid "source data type and target data type are the same" +msgstr "вихідний тип даних співпадає з цільовим типом" + +#: commands/functioncmds.c:1682 +#, c-format +msgid "transform function must not be volatile" +msgstr "функція перетворення не може бути мінливою" + +#: commands/functioncmds.c:1686 +#, c-format +msgid "transform function must be a normal function" +msgstr "функція перетворення повинна бути нормальною функцією" + +#: commands/functioncmds.c:1690 +#, c-format +msgid "transform function must not return a set" +msgstr "функція перетворення не повинна повертати набір" + +#: commands/functioncmds.c:1694 +#, c-format +msgid "transform function must take one argument" +msgstr "функція перетворення повинна приймати один аргумент" + +#: commands/functioncmds.c:1698 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "перший аргумент функції перетворення повинен бути типу %s" + +#: commands/functioncmds.c:1736 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "тип даних %s є псевдотипом" + +#: commands/functioncmds.c:1742 +#, c-format +msgid "data type %s is a domain" +msgstr "тип даних %s є доменом" + +#: commands/functioncmds.c:1782 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "результат функції FROM SQL має бути типу %s" + +#: commands/functioncmds.c:1808 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "результат функції TO SQL повинен мати тип даних перетворення" + +#: commands/functioncmds.c:1837 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "перетворення для типу %s мови \"%s\" вже існує" + +#: commands/functioncmds.c:1929 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "перетворення для типу %s мови \"%s\" не існує" + +#: commands/functioncmds.c:1980 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "функція %s вже існує в схемі \"%s\"" + +#: commands/functioncmds.c:2035 +#, c-format +msgid "no inline code specified" +msgstr "не вказано жодного впровадженого коду" + +#: commands/functioncmds.c:2081 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "мова \"%s\" не підтримує виконання впровадженого коду" + +#: commands/functioncmds.c:2193 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "процедурі неможливо передати більше %d аргументу" +msgstr[1] "процедурі неможливо передати більше %d аргументів" +msgstr[2] "процедурі неможливо передати більше %d аргументів" +msgstr[3] "процедурі неможливо передати більше %d аргументів" + +#: commands/indexcmds.c:590 +#, c-format +msgid "must specify at least one column" +msgstr "треба вказати хоча б один стовпець" + +#: commands/indexcmds.c:594 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "не можна використовувати більше ніж %d стовпців в індексі" + +#: commands/indexcmds.c:633 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "неможливо створити індекс в сторонній таблиці \"%s\"" + +#: commands/indexcmds.c:664 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "неможливо створити індекс в секційній таблиці \"%s\" паралельним способом" + +#: commands/indexcmds.c:669 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "створити обмеження-виняток в секціонованій таблиці \"%s\" не можна" + +#: commands/indexcmds.c:679 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "неможливо створити індекси в тимчасових таблицях в інших сеансах" + +#: commands/indexcmds.c:717 commands/tablecmds.c:704 commands/tablespace.c:1173 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "для секціонованих відношень не можна вказати табличний простір за замовчуванням" + +#: commands/indexcmds.c:749 commands/tablecmds.c:739 commands/tablecmds.c:13162 +#: commands/tablecmds.c:13276 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "тільки спільні відношення можуть бути поміщені в табличний pg_global" + +#: commands/indexcmds.c:782 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "застарілий метод доступу \"rtree\" підміняється методом \"gist\"" + +#: commands/indexcmds.c:803 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "методу доступу \"%s\" не підтримує унікальні індекси" + +#: commands/indexcmds.c:808 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "методу доступу \"%s\" не підтримує включені стовпці" + +#: commands/indexcmds.c:813 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "метод доступу \"%s\" не підтримує багатостовпцеві індекси" + +#: commands/indexcmds.c:818 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "метод доступу \"%s\" не підтримує обмеження-винятки" + +#: commands/indexcmds.c:941 +#, c-format +msgid "cannot match partition key to an index using access method \"%s\"" +msgstr "не можна зіставити ключ розділу з індексом використовуючи метод доступу \"%s\"" + +#: commands/indexcmds.c:951 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "непідтримуване обмеження \"%s\" з визначенням ключа секціонування" + +#: commands/indexcmds.c:953 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "обмеження %s не можуть використовуватись, якщо ключі секціонування включають вирази." + +#: commands/indexcmds.c:992 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "недостатньо стовпців у визначенні обмеження %s" + +#: commands/indexcmds.c:994 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "в обмеженні %s таблиці\"%s\" не вистачає стовпця \"%s\", що є частиною ключа секціонування." + +#: commands/indexcmds.c:1013 commands/indexcmds.c:1032 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "створення індексу для системних стовпців не підтримується" + +#: commands/indexcmds.c:1057 +#, c-format +msgid "%s %s will create implicit index \"%s\" for table \"%s\"" +msgstr "%s %s створить неявний індекс \"%s\" для таблиці \"%s\"" + +#: commands/indexcmds.c:1198 tcop/utility.c:1495 +#, c-format +msgid "cannot create unique index on partitioned table \"%s\"" +msgstr "не можна створити унікальний індекс в секціонованій таблиці \"%s\"" + +#: commands/indexcmds.c:1200 tcop/utility.c:1497 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "Таблиця \"%s\" містить секції, які є зовнішніми таблицями." + +#: commands/indexcmds.c:1629 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "функції в предикаті індексу повинні бути позначені як IMMUTABLE" + +#: commands/indexcmds.c:1695 parser/parse_utilcmd.c:2440 +#: parser/parse_utilcmd.c:2575 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "вказаний у ключі стовпець \"%s\" не існує" + +#: commands/indexcmds.c:1719 parser/parse_utilcmd.c:1776 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "вирази не підтримуються у включених стовпцях " + +#: commands/indexcmds.c:1760 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "функції в індексному виразі повинні бути позначені як IMMUTABLE" + +#: commands/indexcmds.c:1775 +#, c-format +msgid "including column does not support a collation" +msgstr "включені стовпці не підтримують правила сортування" + +#: commands/indexcmds.c:1779 +#, c-format +msgid "including column does not support an operator class" +msgstr "включені стовпці не підтримують класи операторів" + +#: commands/indexcmds.c:1783 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "включені стовпці не підтримують параметри ASC/DESC" + +#: commands/indexcmds.c:1787 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "включені стовпці не підтримують параметри NULLS FIRST/LAST" + +#: commands/indexcmds.c:1814 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "не вдалося визначити, яке правило сортування використати для індексного виразу" + +#: commands/indexcmds.c:1822 commands/tablecmds.c:16042 commands/typecmds.c:771 +#: parser/parse_expr.c:2850 parser/parse_type.c:566 parser/parse_utilcmd.c:3649 +#: parser/parse_utilcmd.c:4210 utils/adt/misc.c:503 +#, c-format +msgid "collations are not supported by type %s" +msgstr "тип %s не підтримує правила сортування" + +#: commands/indexcmds.c:1860 +#, c-format +msgid "operator %s is not commutative" +msgstr "оператор %s не комутативний" + +#: commands/indexcmds.c:1862 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "В обмеженнях-виключеннях можуть використовуватись лише комутативні оператори." + +#: commands/indexcmds.c:1888 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "оператор %s не є членом сімейства операторів \"%s\"" + +#: commands/indexcmds.c:1891 +#, c-format +msgid "The exclusion operator must be related to the index operator class for the constraint." +msgstr "Оператор винятку для обмеження повинен відноситись до класу операторів індексу." + +#: commands/indexcmds.c:1926 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "метод доступу \"%s\" не підтримує параметри ASC/DESC" + +#: commands/indexcmds.c:1931 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "метод доступу \"%s\" не підтримує параметри NULLS FIRST/LAST" + +#: commands/indexcmds.c:1977 commands/tablecmds.c:16067 +#: commands/tablecmds.c:16073 commands/typecmds.c:1945 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "тип даних %s не має класу операторів за замовчуванням для методу доступу \"%s\"" + +#: commands/indexcmds.c:1979 +#, c-format +msgid "You must specify an operator class for the index or define a default operator class for the data type." +msgstr "Ви повинні вказати клас операторів для індексу або визначити клас операторів за замовчуванням для цього типу даних." + +#: commands/indexcmds.c:2008 commands/indexcmds.c:2016 +#: commands/opclasscmds.c:208 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "клас операторів \"%s\" не існує для методу доступу \"%s\"" + +#: commands/indexcmds.c:2030 commands/typecmds.c:1933 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "клас операторів \"%s\" не приймає тип даних %s" + +#: commands/indexcmds.c:2120 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "для типу даних %s є кілька класів операторів за замовчуванням" + +#: commands/indexcmds.c:2569 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "таблиця \"%s\" не має індексів, які можна переіндексувати паралельно" + +#: commands/indexcmds.c:2580 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "таблиця \"%s\" не має індексів для переіндексування" + +#: commands/indexcmds.c:2619 commands/indexcmds.c:2893 +#: commands/indexcmds.c:2986 +#, c-format +msgid "cannot reindex system catalogs concurrently" +msgstr "не можна конкурентно переіндексувати системні каталоги" + +#: commands/indexcmds.c:2642 +#, c-format +msgid "can only reindex the currently open database" +msgstr "переіндексувати можна тільки наразі відкриту базу даних" + +#: commands/indexcmds.c:2733 +#, c-format +msgid "cannot reindex system catalogs concurrently, skipping all" +msgstr "не можна конкурентно переіндексувати системні каталоги, пропускаємо" + +#: commands/indexcmds.c:2785 commands/indexcmds.c:3466 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "таблиця \"%s.%s\" була переіндексована" + +#: commands/indexcmds.c:2908 commands/indexcmds.c:2954 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "неможливо переіндексувати пошкоджений індекс \"%s.%s\" паралельно, пропускається" + +#: commands/indexcmds.c:2914 +#, c-format +msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "неможливо переіндексувати індекс обмеження-виключення \"%s.%s\" паралельно, пропускається" + +#: commands/indexcmds.c:2996 +#, c-format +msgid "cannot reindex invalid index on TOAST table concurrently" +msgstr "переіндексувати неприпустимий індекс в таблиці TOAST в даний час не можна" + +#: commands/indexcmds.c:3024 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "неможливо переіндексувати цей тип відношень паралельон" + +#: commands/indexcmds.c:3448 commands/indexcmds.c:3459 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr "індекс \"%s.%s\" був перебудований" + +#: commands/indexcmds.c:3491 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "REINDEX для секціонованих індексів ще не реалізований" + +#: commands/lockcmds.c:91 commands/tablecmds.c:5629 commands/trigger.c:295 +#: rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:928 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "\"%s\" - не таблиця або подання" + +#: commands/lockcmds.c:213 rewrite/rewriteHandler.c:1977 +#: rewrite/rewriteHandler.c:3782 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "виявлена безкінечна рекурсія у правилах для відносин \"%s\"" + +#: commands/matview.c:182 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "CONCURRENTLY не може використовуватись, коли матеріалізоване подання не наповнено" + +#: commands/matview.c:188 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "Параметри CONCURRENTLY і WITH NO DATA не можуть використовуватись разом" + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "оновити матеріалізоване подання \"%s\" паралельно не можна" + +#: commands/matview.c:247 +#, c-format +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "Створіть унікальний індекс без речення WHERE для одного або більше стовпців матеріалізованого подання." + +#: commands/matview.c:641 +#, c-format +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "нові дані для матеріалізованого подання \"%s\" містять рядки, які дублюються (без урахування стовпців з null)" + +#: commands/matview.c:643 +#, c-format +msgid "Row: %s" +msgstr "Рядок: %s" + +#: commands/opclasscmds.c:127 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "сімейство операторів \"%s\" не існує для методу доступу \"%s\"" + +#: commands/opclasscmds.c:269 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "сімейство операторів \"%s\" для методу доступу \"%s\" вже існує" + +#: commands/opclasscmds.c:414 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "тільки суперкористувач може створити клас операторів" + +#: commands/opclasscmds.c:487 commands/opclasscmds.c:869 +#: commands/opclasscmds.c:993 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "неприпустимий номер оператора %d, число має бути між 1 і %d" + +#: commands/opclasscmds.c:531 commands/opclasscmds.c:913 +#: commands/opclasscmds.c:1008 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "неприпустимий номер функції %d, число має бути між 1 і %d" + +#: commands/opclasscmds.c:559 +#, c-format +msgid "storage type specified more than once" +msgstr "тип сховища вказано більше одного разу" + +#: commands/opclasscmds.c:586 +#, c-format +msgid "storage type cannot be different from data type for access method \"%s\"" +msgstr "тип сховища не може відрізнятися від типу даних для методу доступу \"%s\"" + +#: commands/opclasscmds.c:602 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "клас операторів \"%s\" для методу доступу \"%s\" вже існує" + +#: commands/opclasscmds.c:630 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "клас операторів \"%s\" не вдалося зробити класом за замовчуванням для типу %s" + +#: commands/opclasscmds.c:633 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "Клас операторів \"%s\" вже є класом за замовчуванням." + +#: commands/opclasscmds.c:761 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "тільки суперкористувач може створити сімейство операторів" + +#: commands/opclasscmds.c:821 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "тільки суперкористувач може змінити сімейство операторів" + +#: commands/opclasscmds.c:878 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "типи аргументу оператора повинні бути вказані в ALTER OPERATOR FAMILY" + +#: commands/opclasscmds.c:941 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "STORAGE не може бути вказано в ALTER OPERATOR FAMILY" + +#: commands/opclasscmds.c:1063 +#, c-format +msgid "one or two argument types must be specified" +msgstr "треба вказати один або два типи аргументу" + +#: commands/opclasscmds.c:1089 +#, c-format +msgid "index operators must be binary" +msgstr "індексні оператори повинні бути бінарними" + +#: commands/opclasscmds.c:1108 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "метод доступу \"%s\" не підтримує сортувальних операторів" + +#: commands/opclasscmds.c:1119 +#, c-format +msgid "index search operators must return boolean" +msgstr "оператори пошуку по індексу повинні повертати логічне значення" + +#: commands/opclasscmds.c:1159 +#, c-format +msgid "associated data types for operator class options parsing functions must match opclass input type" +msgstr "пов'язані типи даних для функцій обробки параметрів класів операторів повинні відповідати типу вхідних даних opclass" + +#: commands/opclasscmds.c:1166 +#, c-format +msgid "left and right associated data types for operator class options parsing functions must match" +msgstr "ліві та праві пов'язані типи даних для функцій розбору параметрів класів операторів повинні збігатись" + +#: commands/opclasscmds.c:1174 +#, c-format +msgid "invalid operator class options parsing function" +msgstr "неприпустима функція розбору параметрів класів операторів" + +#: commands/opclasscmds.c:1175 +#, c-format +msgid "Valid signature of operator class options parsing function is %s." +msgstr "Допустимий підпис для функції розбору параметрів класів операторів: %s." + +#: commands/opclasscmds.c:1194 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "функції порівняння btree повинні мати два аргумента" + +#: commands/opclasscmds.c:1198 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "функції порівняння btree повинні повертати ціле число" + +#: commands/opclasscmds.c:1215 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "опорні функції сортування btree повинні приймати тип \"internal\"" + +#: commands/opclasscmds.c:1219 +#, c-format +msgid "btree sort support functions must return void" +msgstr "опорні функції сортування btree повинні повертати недійсне (void)" + +#: commands/opclasscmds.c:1230 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "функції in_range для btree повинні приймати п'ять аргументів" + +#: commands/opclasscmds.c:1234 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "функції in_range для btree повинні повертати логічне значення" + +#: commands/opclasscmds.c:1250 +#, c-format +msgid "btree equal image functions must have one argument" +msgstr "функції equal image для btree повинні приймати один аргумент" + +#: commands/opclasscmds.c:1254 +#, c-format +msgid "btree equal image functions must return boolean" +msgstr "функції equal image для btree повинні повертати логічне значення" + +#: commands/opclasscmds.c:1267 +#, c-format +msgid "btree equal image functions must not be cross-type" +msgstr "функції equal image для btree не можуть бути хрестоподібного типу" + +#: commands/opclasscmds.c:1277 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "геш-функція 1 повинна приймати один аргумент" + +#: commands/opclasscmds.c:1281 +#, c-format +msgid "hash function 1 must return integer" +msgstr "геш-функція 1 повинна повертати ціле число" + +#: commands/opclasscmds.c:1288 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "геш-функція 2 повинна приймати два аргументи" + +#: commands/opclasscmds.c:1292 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "геш-функція 2 повинна повертати велике ціле (bigint)" + +#: commands/opclasscmds.c:1317 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "для опорної функції індексів повинні бути вказані пов'язані типи даних" + +#: commands/opclasscmds.c:1342 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "номер функції %d для (%s,%s) з'являється більш ніж один раз" + +#: commands/opclasscmds.c:1349 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "номер оператора %d для (%s,%s) з'являється більш ніж один раз" + +#: commands/opclasscmds.c:1398 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "оператор %d(%s,%s) вже існує в сімействі операторів \"%s\"" + +#: commands/opclasscmds.c:1515 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "функція %d(%s,%s) вже існує в сімействі операторів \"%s\"" + +#: commands/opclasscmds.c:1606 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "оператора %d(%s,%s) не існує в сімействі операторів \"%s\"" + +#: commands/opclasscmds.c:1646 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "функції %d(%s,%s) не існує в сімействі операторів \"%s\"" + +#: commands/opclasscmds.c:1776 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "клас операторів \"%s\" для методу доступу \"%s\" вже існує в схемі \"%s\"" + +#: commands/opclasscmds.c:1799 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "сімейство операторів \"%s\" для методу доступу \"%s\" вже існує в схемі \"%s\"" + +#: commands/operatorcmds.c:111 commands/operatorcmds.c:119 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "Аргументом оператора не може бути тип SETOF" + +#: commands/operatorcmds.c:152 commands/operatorcmds.c:467 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "атрибут оператора \"%s\" не розпізнаний" + +#: commands/operatorcmds.c:163 +#, c-format +msgid "operator function must be specified" +msgstr "необхідно вказати функцію оператора" + +#: commands/operatorcmds.c:174 +#, c-format +msgid "at least one of leftarg or rightarg must be specified" +msgstr "як мінімум один лівий або правий аргумент повинні бути вказані" + +#: commands/operatorcmds.c:278 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "функція оцінювання обмеження %s повинна повертати тип %s" + +#: commands/operatorcmds.c:321 +#, c-format +msgid "join estimator function %s has multiple matches" +msgstr "функція оцінювання з'єднання %s має декілька збігів" + +#: commands/operatorcmds.c:336 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "функція оцінювання з'єднання %s повинна повертати тип %s" + +#: commands/operatorcmds.c:461 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "атрибут оператора \"%s\" неможливо змінити" + +#: commands/policy.c:88 commands/policy.c:401 commands/policy.c:491 +#: commands/tablecmds.c:1512 commands/tablecmds.c:1994 +#: commands/tablecmds.c:3076 commands/tablecmds.c:5608 +#: commands/tablecmds.c:8395 commands/tablecmds.c:15632 +#: commands/tablecmds.c:15667 commands/trigger.c:301 commands/trigger.c:1206 +#: commands/trigger.c:1315 rewrite/rewriteDefine.c:277 +#: rewrite/rewriteDefine.c:933 rewrite/rewriteRemove.c:80 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "доступ заборонений: \"%s\" - системний каталог" + +#: commands/policy.c:171 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "всі вказані ролі, крім PUBLIC, ігноруються" + +#: commands/policy.c:172 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "Роль PUBLIC включає в себе всі інші ролі." + +#: commands/policy.c:515 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "роль \"%s\" не можна видалити з політики \"%s\" відношення \"%s\"" + +#: commands/policy.c:724 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "WITH CHECK не можна застосувати до SELECT або DELETE" + +#: commands/policy.c:733 commands/policy.c:1038 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "для INSERT допускається лише вираз WITH CHECK" + +#: commands/policy.c:808 commands/policy.c:1261 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "політика \"%s\" для таблиці \"%s\" вже існує" + +#: commands/policy.c:1010 commands/policy.c:1289 commands/policy.c:1360 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "політика \"%s\" для таблиці \"%s\" не існує" + +#: commands/policy.c:1028 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "для SELECT, DELETE допускається лише вираз USING" + +#: commands/portalcmds.c:59 commands/portalcmds.c:182 commands/portalcmds.c:233 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "неприпустиме ім'я курсора: не повинне бути пустим" + +#: commands/portalcmds.c:190 commands/portalcmds.c:243 +#: executor/execCurrent.c:70 utils/adt/xml.c:2594 utils/adt/xml.c:2764 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "курсор \"%s\" не існує" + +#: commands/prepare.c:76 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "неприпустиме ім'я оператора: не повинне бути пустим" + +#: commands/prepare.c:134 parser/parse_param.c:304 tcop/postgres.c:1498 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "не вдалося визначити тип даних параметра $%d" + +#: commands/prepare.c:152 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "службових операторів не можна підготувати" + +#: commands/prepare.c:256 commands/prepare.c:261 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "підготовлений оператор не SELECT" + +#: commands/prepare.c:328 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "невірне число параметрів для підготовленого оператора \"%s\"" + +#: commands/prepare.c:330 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "Очікувалось %d параметрів, але отримано %d." + +#: commands/prepare.c:363 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "параметр $%d типу %s не можна привести до очікуваного типу %s" + +#: commands/prepare.c:449 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "підготовлений оператор \"%s\" вже існує" + +#: commands/prepare.c:488 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "підготовлений оператор \"%s\" не існує" + +#: commands/proclang.c:67 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "для створення користувацької мови потрібно бути суперкористувачем" + +#: commands/publicationcmds.c:107 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "неприпустимий список синтаксису параметру \"publish\"" + +#: commands/publicationcmds.c:125 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "нерозпізнане значення \"publish\": \"%s\"" + +#: commands/publicationcmds.c:140 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "нерозпізнаний параметр публікації: \"%s\"" + +#: commands/publicationcmds.c:172 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "для створення публікації УСІХ ТАБЛИЦЬ потрібно бути суперкористувачем" + +#: commands/publicationcmds.c:248 +#, c-format +msgid "wal_level is insufficient to publish logical changes" +msgstr "недостатній wal_level для публікації логічних змін" + +#: commands/publicationcmds.c:249 +#, c-format +msgid "Set wal_level to logical before creating subscriptions." +msgstr "Встановіть wal_level на \"logical\" перед створенням підписок." + +#: commands/publicationcmds.c:369 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "публікація \"%s\" визначена ДЛЯ ВСІХ ТАБЛИЦЬ" + +#: commands/publicationcmds.c:371 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "У публікації ВСІХ ТАБЛИЦЬ не можна додати або видалити таблиці." + +#: commands/publicationcmds.c:683 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "відносини \"%s\" не є частиною публікації" + +#: commands/publicationcmds.c:726 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "немає прав на зміну власника публікації \"%s\"" + +#: commands/publicationcmds.c:728 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "Власником публікації УСІХ ТАБЛИЦЬ повинен бути суперкористувач." + +#: commands/schemacmds.c:105 commands/schemacmds.c:281 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "непримустиме ім'я схеми \"%s\"" + +#: commands/schemacmds.c:106 commands/schemacmds.c:282 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "Префікс \"pg_\" зарезервований для системних схем." + +#: commands/schemacmds.c:120 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "схема \"%s\" вже існує, пропускається" + +#: commands/seclabel.c:60 +#, c-format +msgid "no security label providers have been loaded" +msgstr "постачальники міток безпеки не завантажені" + +#: commands/seclabel.c:64 +#, c-format +msgid "must specify provider when multiple security label providers have been loaded" +msgstr "коли завантажено кілька постачальників міток безпеки, потрібний слід вказати явно" + +#: commands/seclabel.c:82 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "постачальник міток безпеки \"%s\" не завантажений" + +#: commands/sequence.c:140 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "(unlogged) послідовності не підтримуються" + +#: commands/sequence.c:709 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "функція nextval досягла максимуму для послідовності \"%s\" (%s)" + +#: commands/sequence.c:732 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "функція nextval досягла мінімуму для послідовності \"%s\" (%s)" + +#: commands/sequence.c:850 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "поточне значення (currval) для послідовності \"%s\" ще не визначено у цьому сеансі" + +#: commands/sequence.c:869 commands/sequence.c:875 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "останнє значення ще не визначено в цьому сеансі" + +#: commands/sequence.c:963 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "setval: значення %s поза межами послідовності \"%s\" (%s..%s)" + +#: commands/sequence.c:1360 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "неприпустимий параметр послідовності SEQUENCE NAME" + +#: commands/sequence.c:1386 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "типом стовпця ідентифікації може бути тільки smallint, integer або bigint" + +#: commands/sequence.c:1387 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "типом послідовності може бути тільки smallint, integer або bigint" + +#: commands/sequence.c:1421 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "INCREMENT не повинен бути нулем" + +#: commands/sequence.c:1474 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) виходить за межі типу даних послідовності %s" + +#: commands/sequence.c:1511 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s) виходить за межі типу даних послідовності %s" + +#: commands/sequence.c:1525 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "MINVALUE (%s) повинно бути менше за MAXVALUE (%s)" + +#: commands/sequence.c:1552 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "Значення START (%s) не може бути менше за MINVALUE (%s)" + +#: commands/sequence.c:1564 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "Значення START (%s) не може бути більше за MAXVALUE (%s)" + +#: commands/sequence.c:1594 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "Значення RESTART (%s) не може бути менше за MINVALUE (%s)" + +#: commands/sequence.c:1606 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "Значення RESTART (%s) не може бути більше за MAXVALUE (%s)" + +#: commands/sequence.c:1621 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "Значення CACHE (%s) повинно бути більше нуля" + +#: commands/sequence.c:1658 +#, c-format +msgid "invalid OWNED BY option" +msgstr "неприпустимий параметр OWNED BY" + +#: commands/sequence.c:1659 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "Вкажіть OWNED BY таблиця.стовпець або OWNED BY NONE." + +#: commands/sequence.c:1684 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr "вказаний об'єкт \"%s\" не є таблицею або сторонньою таблицею" + +#: commands/sequence.c:1691 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "послідовність повинна мати того ж власника, що і таблиця, з якою вона зв'язана" + +#: commands/sequence.c:1695 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "послідовність повинна бути в тій самій схемі, що і таблиця, з якою вона зв'язана" + +#: commands/sequence.c:1717 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "змінити власника послідовності ідентифікації не можна" + +#: commands/sequence.c:1718 commands/tablecmds.c:12544 +#: commands/tablecmds.c:15058 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "Послідовність \"%s\" зв'язана з таблицею \"%s\"." + +#: commands/statscmds.c:104 commands/statscmds.c:113 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "в CREATE STATISTICS можна вказати лише одне відношення" + +#: commands/statscmds.c:131 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "відношення \"%s\" - не таблиця, не зовнішня таблиця і не матеріалізоване подання" + +#: commands/statscmds.c:174 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "об'єкт статистики \"%s\" вже існує, пропускається" + +#: commands/statscmds.c:182 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "об'єкт статистики \"%s\" вже існує" + +#: commands/statscmds.c:204 commands/statscmds.c:210 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "в CREATE STATISTICS допускаються лише прості посилання на стовпці" + +#: commands/statscmds.c:225 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "створення статистики для системних стовпців не підтримується" + +#: commands/statscmds.c:232 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "стовпець \"%s\" не можна використати в статистиці, тому що для його типу %s не визначений клас оператора (btree) за замовчуванням" + +#: commands/statscmds.c:239 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "в статистиці не може бути більше ніж %d стовпців" + +#: commands/statscmds.c:254 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "для розширеної статистики потрібно мінімум 2 стовпці" + +#: commands/statscmds.c:272 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "дублювання імені стовпця у визначенні статистики" + +#: commands/statscmds.c:306 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "нерозпізнаний вид статистики \"%s\"" + +#: commands/statscmds.c:444 commands/tablecmds.c:7416 +#, c-format +msgid "statistics target %d is too low" +msgstr "мета статистики занадто мала %d" + +#: commands/statscmds.c:452 commands/tablecmds.c:7424 +#, c-format +msgid "lowering statistics target to %d" +msgstr "мета статистики знижується до %d" + +#: commands/statscmds.c:475 +#, c-format +msgid "statistics object \"%s.%s\" does not exist, skipping" +msgstr "об'єкт статистики \"%s.%s\" не існує, пропускається" + +#: commands/subscriptioncmds.c:181 +#, c-format +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "нерозпізнаний параметр підписки: \"%s\"" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:195 commands/subscriptioncmds.c:201 +#: commands/subscriptioncmds.c:207 commands/subscriptioncmds.c:226 +#: commands/subscriptioncmds.c:232 +#, c-format +msgid "%s and %s are mutually exclusive options" +msgstr "%s та %s є взаємовиключними опціями" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:239 commands/subscriptioncmds.c:245 +#, c-format +msgid "subscription with %s must also set %s" +msgstr "підписка з %s повинна також встановити %s" + +#: commands/subscriptioncmds.c:287 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "ім'я публікації \"%s\" використовується більше ніж один раз" + +#: commands/subscriptioncmds.c:351 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "для створення підписок потрібно бути суперкористувачем" + +#: commands/subscriptioncmds.c:442 commands/subscriptioncmds.c:530 +#: replication/logical/tablesync.c:857 replication/logical/worker.c:2096 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "не вдалося підключитись до сервера публікації: %s" + +#: commands/subscriptioncmds.c:484 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "на сервері публікації створений слот реплікації \"%s\"" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:497 +#, c-format +msgid "tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "таблиці не були підписані, вам необхідно виконати %s, щоб підписати таблиці" + +#: commands/subscriptioncmds.c:586 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "таблиця \"%s.%s\" додана в підписку \"%s\"" + +#: commands/subscriptioncmds.c:610 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "таблиця \"%s.%s\" видалена з підписки \"%s\"" + +#: commands/subscriptioncmds.c:682 +#, c-format +msgid "cannot set %s for enabled subscription" +msgstr "неможливо встановити %s для увімкненої підписки" + +#: commands/subscriptioncmds.c:717 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "увімкнути підписку, для якої не задано ім'я слота, не можна" + +#: commands/subscriptioncmds.c:763 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION з оновленням для відключених підписок не допускається" + +#: commands/subscriptioncmds.c:764 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "Використайте ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:782 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESH для відключених підписок не допускається" + +#: commands/subscriptioncmds.c:862 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "підписка \"%s\" не існує, пропускається" + +#: commands/subscriptioncmds.c:987 +#, c-format +msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgstr "не вдалося з'єднатися з сервером публікації для видалення слота реплікації \"%s\"" + +#: commands/subscriptioncmds.c:989 commands/subscriptioncmds.c:1004 +#: replication/logical/tablesync.c:906 replication/logical/tablesync.c:928 +#, c-format +msgid "The error was: %s" +msgstr "Сталася помилка: %s" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:991 +#, c-format +msgid "Use %s to disassociate the subscription from the slot." +msgstr "Використовуйте %s , щоб відв'язати підписку від слоту." + +#: commands/subscriptioncmds.c:1002 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "не вдалося видалити слот реплікації \"%s\" на сервері публікації" + +#: commands/subscriptioncmds.c:1007 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "видалено слот реплікації \"%s\" на сервері публікації" + +#: commands/subscriptioncmds.c:1044 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "немає прав на зміну власника підписки \"%s\"" + +#: commands/subscriptioncmds.c:1046 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "Власником підписки повинен бути суперкористувач." + +#: commands/subscriptioncmds.c:1161 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "не вдалося отримати список реплікованих таблиць із сервера публікації: %s" + +#: commands/tablecmds.c:228 commands/tablecmds.c:270 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "таблиця \"%s\" не існує" + +#: commands/tablecmds.c:229 commands/tablecmds.c:271 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "таблиця \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:231 commands/tablecmds.c:273 +msgid "Use DROP TABLE to remove a table." +msgstr "Використайте DROP TABLE для видалення таблиці." + +#: commands/tablecmds.c:234 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "послідовність \"%s\" не існує" + +#: commands/tablecmds.c:235 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "послідовність \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:237 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "Використайте DROP SEQUENCE, щоб видалити послідовність." + +#: commands/tablecmds.c:240 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "подання \"%s\" не існує" + +#: commands/tablecmds.c:241 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "подання \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:243 +msgid "Use DROP VIEW to remove a view." +msgstr "Використайте DROP VIEW для видалення подання." + +#: commands/tablecmds.c:246 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr "матеріалізоване подання \"%s\" не існує" + +#: commands/tablecmds.c:247 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr "матеріалізоване подання \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:249 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "Використайте DROP MATERIALIZED VIEW, щоб видалити матеріалізоване подання." + +#: commands/tablecmds.c:252 commands/tablecmds.c:276 commands/tablecmds.c:17231 +#: parser/parse_utilcmd.c:2172 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "індекс \"%s\" не існує" + +#: commands/tablecmds.c:253 commands/tablecmds.c:277 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "індекс \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:255 commands/tablecmds.c:279 +msgid "Use DROP INDEX to remove an index." +msgstr "Використайте DROP INDEX, щоб видалити індекс." + +#: commands/tablecmds.c:260 +#, c-format +msgid "\"%s\" is not a type" +msgstr "\"%s\" не є типом" + +#: commands/tablecmds.c:261 +msgid "Use DROP TYPE to remove a type." +msgstr "Використайте DROP TYPE, щоб видалити тип." + +#: commands/tablecmds.c:264 commands/tablecmds.c:12383 +#: commands/tablecmds.c:14838 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "зовнішня таблиця \"%s\" не існує" + +#: commands/tablecmds.c:265 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "зовнішня таблиця \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:267 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "Використайте DROP FOREIGN TABLE щоб видалити сторонню таблицю." + +#: commands/tablecmds.c:620 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMIT можна використовувати лише для тимчасових таблиць" + +#: commands/tablecmds.c:651 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "неможливо створити тимчасову таблицю в межах операції з обмеженням безпеки" + +#: commands/tablecmds.c:687 commands/tablecmds.c:13742 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "відношення \"%s\" буде успадковуватись більш ніж один раз" + +#: commands/tablecmds.c:868 +#, c-format +msgid "specifying a table access method is not supported on a partitioned table" +msgstr "вказання методу доступу до таблиці не підтримується з секційною таблицею" + +#: commands/tablecmds.c:964 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "\"%s\" не секціоновано" + +#: commands/tablecmds.c:1058 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "число стовпців в ключі секціонування не може перевищувати %d" + +#: commands/tablecmds.c:1114 +#, c-format +msgid "cannot create foreign partition of partitioned table \"%s\"" +msgstr "не можна створити зовнішню секцію в секціонованій таблиці \"%s\"" + +#: commands/tablecmds.c:1116 +#, c-format +msgid "Table \"%s\" contains indexes that are unique." +msgstr "Таблиця \"%s\" містить індекси, які унікальні." + +#: commands/tablecmds.c:1279 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLY не підтримує видалення кількох об'єктів" + +#: commands/tablecmds.c:1283 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLY не підтримує режим CASCADE" + +#: commands/tablecmds.c:1384 +#, c-format +msgid "cannot drop partitioned index \"%s\" concurrently" +msgstr "неможливо видалити секціонований індекс \"%s\" паралельно" + +#: commands/tablecmds.c:1654 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "скоротити тільки секціоновану таблицю не можна" + +#: commands/tablecmds.c:1655 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "Не вказуйте ключове слово ONLY або використайте TRUNCATE ONLY безпосередньо для секцій." + +#: commands/tablecmds.c:1724 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "скорочення поширюється на таблицю \"%s\"" + +#: commands/tablecmds.c:2031 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "тимчасові таблиці інших сеансів не можна скоротити" + +#: commands/tablecmds.c:2259 commands/tablecmds.c:13639 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "успадкування від секціонованої таблиці \"%s\" не допускається" + +#: commands/tablecmds.c:2264 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "успадкування від розділу \"%s\" не допускається" + +#: commands/tablecmds.c:2272 parser/parse_utilcmd.c:2402 +#: parser/parse_utilcmd.c:2544 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "успадковане відношення \"%s\" не є таблицею або сторонньою таблицею" + +#: commands/tablecmds.c:2284 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "створити тимчасове відношення як секцію постійного відношення\"%s\" не можна" + +#: commands/tablecmds.c:2293 commands/tablecmds.c:13618 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "тимчасове відношення \"%s\" не може успадковуватись" + +#: commands/tablecmds.c:2303 commands/tablecmds.c:13626 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "успадкування від тимчасового відношення іншого сеансу неможливе" + +#: commands/tablecmds.c:2357 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "злиття декількох успадкованих визначень стовпця \"%s\"" + +#: commands/tablecmds.c:2365 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "конфлікт типів в успадкованому стовпці \"%s\"" + +#: commands/tablecmds.c:2367 commands/tablecmds.c:2390 +#: commands/tablecmds.c:2639 commands/tablecmds.c:2669 +#: parser/parse_coerce.c:1935 parser/parse_coerce.c:1955 +#: parser/parse_coerce.c:1975 parser/parse_coerce.c:2030 +#: parser/parse_coerce.c:2107 parser/parse_coerce.c:2141 +#: parser/parse_param.c:218 +#, c-format +msgid "%s versus %s" +msgstr "%s проти %s" + +#: commands/tablecmds.c:2376 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "конфлікт правил сортування в успадкованому стовпці \"%s\"" + +#: commands/tablecmds.c:2378 commands/tablecmds.c:2651 +#: commands/tablecmds.c:6106 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "\"%s\" проти \"%s\"" + +#: commands/tablecmds.c:2388 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "конфлікт параметрів зберігання в успадкованому стовпці \"%s\"" + +#: commands/tablecmds.c:2404 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "конфлікт генерування в успадкованому стовпці \"%s\"" + +#: commands/tablecmds.c:2490 commands/tablecmds.c:2545 +#: commands/tablecmds.c:11188 parser/parse_utilcmd.c:1252 +#: parser/parse_utilcmd.c:1295 parser/parse_utilcmd.c:1703 +#: parser/parse_utilcmd.c:1812 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "перетворити посилання на тип усього рядка таблиці не можна" + +#: commands/tablecmds.c:2491 parser/parse_utilcmd.c:1253 +#, c-format +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "Вираз генерації для стовпця \"%s\" містить посилання на весь рядок на таблицю \"%s\"." + +#: commands/tablecmds.c:2546 parser/parse_utilcmd.c:1296 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "Обмеження \"%s\" посилається на тип усього рядка в таблиці \"%s\"." + +#: commands/tablecmds.c:2625 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "злиття стовпця \"%s\" з успадкованим визначенням" + +#: commands/tablecmds.c:2629 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "переміщення і злиття стовпця \"%s\" з успадкованим визначенням" + +#: commands/tablecmds.c:2630 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "Визначений користувачем стовпець переміщений в позицію успадкованого стовпця." + +#: commands/tablecmds.c:2637 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "конфлікт типів в стовпці \"%s\"" + +#: commands/tablecmds.c:2649 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "конфлікт правил сортування в стовпці \"%s\"" + +#: commands/tablecmds.c:2667 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "конфлікт параметрів зберігання в стовпці \"%s\"" + +#: commands/tablecmds.c:2695 +#, c-format +msgid "child column \"%s\" specifies generation expression" +msgstr "дочірній стовпець \"%s\" визначає вираз генерації" + +#: commands/tablecmds.c:2697 +#, c-format +msgid "Omit the generation expression in the definition of the child table column to inherit the generation expression from the parent table." +msgstr "Пропустіть вираз генерації у визначенні стовпця дочірьної таблиці щоб успадкувати вираз генерації з батьківської таблиці." + +#: commands/tablecmds.c:2701 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies default" +msgstr "стовпець \"%s\" успадковується із згенерованого стовпця, але вказує за замовчуванням" + +#: commands/tablecmds.c:2706 +#, c-format +msgid "column \"%s\" inherits from generated column but specifies identity" +msgstr "стовпець \"%s\" успадковується із згенерованого стовпця, але вказує ідентичність" + +#: commands/tablecmds.c:2815 +#, c-format +msgid "column \"%s\" inherits conflicting generation expressions" +msgstr "стовпець \"%s\" успадковує конфліктуючи вирази генерації" + +#: commands/tablecmds.c:2820 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "стовпець \"%s\" успадковує конфліктні значення за замовчуванням" + +#: commands/tablecmds.c:2822 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "Для усунення конфлікту вкажіть бажане значення за замовчуванням." + +#: commands/tablecmds.c:2868 +#, c-format +msgid "check constraint name \"%s\" appears multiple times but with different expressions" +msgstr "ім'я перевірочного обмеження \"%s\" з'являється декілька разів, але з різними виразами" + +#: commands/tablecmds.c:3045 +#, c-format +msgid "cannot rename column of typed table" +msgstr "перейменувати стовпець типізованої таблиці не можна" + +#: commands/tablecmds.c:3064 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" +msgstr "\"%s\" - не таблиця, подання, матеріалізоване подання, складений тип, індекс або зовнішня таблиця" + +#: commands/tablecmds.c:3158 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "успадкований стовпець \"%s\" повинен бути перейменований в дочірніх таблицях також" + +#: commands/tablecmds.c:3190 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "не можна перейменувати системний стовпець \"%s\"" + +#: commands/tablecmds.c:3205 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "не можна перейменувати успадкований стовпець \"%s\"" + +#: commands/tablecmds.c:3357 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "успадковане обмеження \"%s\" повинно бути перейменовано в дочірніх таблицях також" + +#: commands/tablecmds.c:3364 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "не можна перейменувати успадковане обмеження \"%s\"" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3597 +#, c-format +msgid "cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "не можна виконати %s \"%s\", тому що цей об'єкт використовується активними запитами в цьому сеансі" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3606 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "не можна виконати %s \"%s\", тому що з цим об'єктом зв'язані очікуванні події тригерів" + +#: commands/tablecmds.c:4237 commands/tablecmds.c:4252 +#, c-format +msgid "cannot change persistence setting twice" +msgstr "неможливо двічі змінити параметр стійкості" + +#: commands/tablecmds.c:4969 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "перезаписати системне відношення \"%s\" не можна" + +#: commands/tablecmds.c:4975 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "перезаписати таблицю \"%s\", що використовується як таблиця каталогу, не можна" + +#: commands/tablecmds.c:4985 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "неможливо перезаписати тимчасові таблиці інших сеансів" + +#: commands/tablecmds.c:5274 +#, c-format +msgid "rewriting table \"%s\"" +msgstr "перезапис таблиці \"%s\"" + +#: commands/tablecmds.c:5278 +#, c-format +msgid "verifying table \"%s\"" +msgstr "перевірка таблиці \"%s\"" + +#: commands/tablecmds.c:5443 +#, c-format +msgid "column \"%s\" of relation \"%s\" contains null values" +msgstr "стовпець \"%s\" відношення \"%s\" містить null значення" + +#: commands/tablecmds.c:5460 +#, c-format +msgid "check constraint \"%s\" of relation \"%s\" is violated by some row" +msgstr "перевірка обмеження \"%s\" відношення \"%s\" порушується деяким рядком" + +#: commands/tablecmds.c:5479 partitioning/partbounds.c:3235 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "оновлене обмеження секції для секції за замовчуванням \"%s\" буде порушено деякими рядками" + +#: commands/tablecmds.c:5485 +#, c-format +msgid "partition constraint of relation \"%s\" is violated by some row" +msgstr "обмеження секції відношення \"%s\" порушується деяким рядком" + +#: commands/tablecmds.c:5632 commands/trigger.c:1200 commands/trigger.c:1306 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "\"%s\" - не таблиця, подання або зовнішня таблиця" + +#: commands/tablecmds.c:5635 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "\"%s\" - не таблиця, подання, матеріалізоване подання або індекс" + +#: commands/tablecmds.c:5641 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "\"%s\" - не таблиця, матеріалізоване подання або індекс" + +#: commands/tablecmds.c:5644 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "\"%s\" - не таблиця, матеріалізоване подання або зовнішня таблиця" + +#: commands/tablecmds.c:5647 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "\"%s\" - не таблиця або зовнішня таблиця" + +#: commands/tablecmds.c:5650 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "\"%s\" - не таблиця, складений тип або зовнішня таблиця" + +#: commands/tablecmds.c:5653 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "\"%s\" - не таблиця, матеріалізоване подання, індекс або зовнішня таблиця" + +#: commands/tablecmds.c:5663 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "\"%s\" - неправильний тип" + +#: commands/tablecmds.c:5866 commands/tablecmds.c:5873 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "неможливо змінити тип \"%s\", тому що стовпець \"%s.%s\" використовує його" + +#: commands/tablecmds.c:5880 +#, c-format +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "неможливо змінити сторонню таблицю \"%s\", тому що стовпець \"%s.%s\" використовує тип її рядка" + +#: commands/tablecmds.c:5887 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "неможливо змінити таблицю \"%s\", тому що стовпець \"%s.%s\" використовує тип її рядка" + +#: commands/tablecmds.c:5943 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "неможливо змінити тип \"%s\", тому що це тип типізованої таблиці" + +#: commands/tablecmds.c:5945 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "Щоб змінити типізовані таблиці, використайте також ALTER ... CASCADE." + +#: commands/tablecmds.c:5991 +#, c-format +msgid "type %s is not a composite type" +msgstr "тип %s не є складеним" + +#: commands/tablecmds.c:6018 +#, c-format +msgid "cannot add column to typed table" +msgstr "неможливо додати стовпець до типізованої таблиці" + +#: commands/tablecmds.c:6069 +#, c-format +msgid "cannot add column to a partition" +msgstr "неможливо додати стовпець до розділу" + +#: commands/tablecmds.c:6098 commands/tablecmds.c:13869 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "дочірня таблиця \"%s\" має інший тип для стовпця \"%s\"" + +#: commands/tablecmds.c:6104 commands/tablecmds.c:13876 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "дочірня таблиця \"%s\" має інше правило сортування для стовпця \"%s\"" + +#: commands/tablecmds.c:6118 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "об'єднання визначення стовпця \"%s\" для нащадка \"%s\"" + +#: commands/tablecmds.c:6161 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "неможливо додати стовпець ідентифікації в таблицю, яка має дочірні таблиці" + +#: commands/tablecmds.c:6398 +#, c-format +msgid "column must be added to child tables too" +msgstr "стовпець також повинен бути доданий до дочірніх таблиць" + +#: commands/tablecmds.c:6476 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "стовпець \"%s\" відношення \"%s\" вже існує, пропускається" + +#: commands/tablecmds.c:6483 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "стовпець \"%s\" відношення \"%s\" вже існує" + +#: commands/tablecmds.c:6549 commands/tablecmds.c:10826 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "неможливо видалити обмеження тільки з секціонованої таблиці, коли існують секції" + +#: commands/tablecmds.c:6550 commands/tablecmds.c:6854 +#: commands/tablecmds.c:7834 commands/tablecmds.c:10827 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "Не вказуйте ключове слово ONLY." + +#: commands/tablecmds.c:6587 commands/tablecmds.c:6780 +#: commands/tablecmds.c:6922 commands/tablecmds.c:7036 +#: commands/tablecmds.c:7130 commands/tablecmds.c:7189 +#: commands/tablecmds.c:7291 commands/tablecmds.c:7457 +#: commands/tablecmds.c:7527 commands/tablecmds.c:7620 +#: commands/tablecmds.c:10981 commands/tablecmds.c:12406 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "не можна змінити системний стовпець \"%s\"" + +#: commands/tablecmds.c:6593 commands/tablecmds.c:6928 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "стовпець \"%s\" відношення \"%s\" є стовпцем ідентифікації" + +#: commands/tablecmds.c:6629 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "стовпець \"%s\" входить до первинного ключа" + +#: commands/tablecmds.c:6651 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "стовпець \"%s\" в батьківській таблиці позначений як NOT NULL" + +#: commands/tablecmds.c:6851 commands/tablecmds.c:8293 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "обмеження повинно бути додано у дочірні таблиці також" + +#: commands/tablecmds.c:6852 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "Стовпець \"%s\" відношення \"%s\" вже не NOT NULL." + +#: commands/tablecmds.c:6887 +#, c-format +msgid "existing constraints on column \"%s.%s\" are sufficient to prove that it does not contain nulls" +msgstr "існуючих обмежень в стовпці \"%s.%s\" досить, щоб довести, що він не містить nulls" + +#: commands/tablecmds.c:6930 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "Замість цього використайте ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." + +#: commands/tablecmds.c:6935 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "стовпець \"%s\" відношення \"%s\" є згенерованим стовпцем" + +#: commands/tablecmds.c:6938 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION instead." +msgstr "Замість цього використайте ALTER TABLE ... ALTER COLUMN ... DROP EXPRESSION" + +#: commands/tablecmds.c:7047 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "стовпець \"%s\" відношення \"%s\" повинен бути оголошений як NOT NULL, щоб додати ідентифікацію" + +#: commands/tablecmds.c:7053 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "стовпець \"%s\" відношення \"%s\" вже є стовпцем ідентифікації" + +#: commands/tablecmds.c:7059 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "стовпець \"%s\" відношення \"%s\" вже має значення за замовчуванням" + +#: commands/tablecmds.c:7136 commands/tablecmds.c:7197 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "стовпець \"%s\" відношення \"%s\" не є стовпцем ідентифікації" + +#: commands/tablecmds.c:7202 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "стовпець \"%s\" відношення \"%s\" не є стовпцем ідентифікації, пропускається" + +#: commands/tablecmds.c:7261 +#, c-format +msgid "cannot drop generation expression from inherited column" +msgstr "не можна видалити вираз генерації з успадкованого стовпця" + +#: commands/tablecmds.c:7299 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column" +msgstr "стовпець \"%s\" відношення \"%s\" не є збереженим згенерованим стовпцем" + +#: commands/tablecmds.c:7304 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not a stored generated column, skipping" +msgstr "стовпець \"%s\" відношення \"%s\" не є збереженим згенерованим стовпцем, пропускається" + +#: commands/tablecmds.c:7404 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "не можна посилатись на неіндексований стовпець за номером" + +#: commands/tablecmds.c:7447 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "стовпець з номером %d відношення %s не існує" + +#: commands/tablecmds.c:7466 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "змінити статистику включеного стовпця \"%s\" індексу \"%s\" не можна" + +#: commands/tablecmds.c:7471 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "змінити статистику невираженого стовпця \"%s\" індексу \"%s\" не можна" + +#: commands/tablecmds.c:7473 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Замість цього змініть статистику стовпця в таблиці." + +#: commands/tablecmds.c:7600 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "неприпустимий тип сховища \"%s\"" + +#: commands/tablecmds.c:7632 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "тип даних стовпця %s може мати тільки сховище PLAIN" + +#: commands/tablecmds.c:7714 +#, c-format +msgid "cannot drop column from typed table" +msgstr "не можна видалити стовпець з типізованої таблиці" + +#: commands/tablecmds.c:7773 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "стовпець \"%s\" відношення \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:7786 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "не можна видалити системний стовпець \"%s\"" + +#: commands/tablecmds.c:7796 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "не можна видалити успадкований стовпець \"%s\"" + +#: commands/tablecmds.c:7809 +#, c-format +msgid "cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "не можна видалити стовпець \"%s\", тому що він є частиною ключа секції відношення \"%s\"" + +#: commands/tablecmds.c:7833 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "видалити стовпець тільки з секціонованої таблиці, коли існують секції, не можна" + +#: commands/tablecmds.c:8014 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX не підтримується із секціонованими таблицями" + +#: commands/tablecmds.c:8039 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX перейменує індекс \"%s\" в \"%s\"" + +#: commands/tablecmds.c:8373 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "не можна використати ONLY для стороннього ключа в секціонованій таблиці \"%s\", який посилається на відношення \"%s\"" + +#: commands/tablecmds.c:8379 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "не можна додати сторонній ключ з характеристикою NOT VALID в секціоновану таблицю \"%s\", який посилається на відношення \"%s\"" + +#: commands/tablecmds.c:8382 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Ця функція ще не підтримується з секціонованими таблицями." + +#: commands/tablecmds.c:8389 commands/tablecmds.c:8794 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "вказане відношення \"%s\" не є таблицею" + +#: commands/tablecmds.c:8412 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "обмеження в постійних таблицях можуть посилатись лише на постійні таблиці" + +#: commands/tablecmds.c:8419 +#, c-format +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" +msgstr "обмеження в нежурнальованих таблицях можуть посилатись тільки на постійні або нежурналюємі таблиці" + +#: commands/tablecmds.c:8425 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "обмеження в тимчасових таблицях можуть посилатись лише на тимчасові таблиці" + +#: commands/tablecmds.c:8429 +#, c-format +msgid "constraints on temporary tables must involve temporary tables of this session" +msgstr "обмеження в тимчасових таблицях повинні посилатись лише на тичасові таблиці поточного сеансу" + +#: commands/tablecmds.c:8495 commands/tablecmds.c:8501 +#, c-format +msgid "invalid %s action for foreign key constraint containing generated column" +msgstr "неприпустима дія %s для обмеження зовнішнього ключа, який містить згеренований стовпець" + +#: commands/tablecmds.c:8517 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "число стовпців в джерелі і призначенні зовнішнього ключа не збігається" + +#: commands/tablecmds.c:8624 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "обмеження зовнішнього ключа \"%s\" не можна реалізувати" + +#: commands/tablecmds.c:8626 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "Стовпці ключа \"%s\" і \"%s\" містять несумісні типи: %s і %s." + +#: commands/tablecmds.c:8989 commands/tablecmds.c:9382 +#: parser/parse_utilcmd.c:764 parser/parse_utilcmd.c:893 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "обмеження зовнішнього ключа для сторонніх таблиць не підтримуються" + +#: commands/tablecmds.c:9748 commands/tablecmds.c:9911 +#: commands/tablecmds.c:10783 commands/tablecmds.c:10858 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "обмеження \"%s\" відношення \"%s\" не існує" + +#: commands/tablecmds.c:9755 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "обмеження \"%s\" відношення \"%s\" не є обмеженням зовнішнього ключа" + +#: commands/tablecmds.c:9919 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "обмеження \"%s\" відношення \"%s\" не є зовнішнім ключем або перевіркою обмеженням " + +#: commands/tablecmds.c:9997 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "обмеження повинно дотримуватися в дочірніх таблицях також" + +#: commands/tablecmds.c:10081 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "стовпець \"%s\", вказаний в обмеженні зовнішнього ключа, не існує" + +#: commands/tablecmds.c:10086 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "у зовнішньому ключі не може бути більш ніж %d ключів" + +#: commands/tablecmds.c:10151 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "використовувати затримуваний первинний ключ в цільовій зовнішній таблиці \"%s\" не можна" + +#: commands/tablecmds.c:10168 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "у цільовій зовнішній таблиці \"%s\" немає первинного ключа" + +#: commands/tablecmds.c:10233 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "у списку стовпців зовнішнього ключа не повинно бути повторень" + +#: commands/tablecmds.c:10327 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "використовувати затримане обмеження унікальності в цільовій зовнішній таблиці \"%s\" не можна" + +#: commands/tablecmds.c:10332 +#, c-format +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "у цільовій зовнішній таблиці \"%s\" немає обмеження унікальності, відповідного даним ключам" + +#: commands/tablecmds.c:10420 +#, c-format +msgid "validating foreign key constraint \"%s\"" +msgstr "перевірка обмеження зовнішнього ключа \"%s\"" + +#: commands/tablecmds.c:10739 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "видалити успадковане обмеження \"%s\" відношення \"%s\" не можна" + +#: commands/tablecmds.c:10789 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "обмеження \"%s\" відношення \"%s\" не існує, пропускається" + +#: commands/tablecmds.c:10965 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "змінити тип стовпця в типізованій таблиці не можна" + +#: commands/tablecmds.c:10992 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "змінити успадкований стовпець \"%s\" не можна" + +#: commands/tablecmds.c:11001 +#, c-format +msgid "cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"" +msgstr "не можна змінити стовпець \"%s\", тому що він є частиною ключа секції відношення \"%s\"" + +#: commands/tablecmds.c:11051 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "результати речення USING для стовпця \"%s\" не можна автоматично наведено для типу %s" + +#: commands/tablecmds.c:11054 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "Можливо, необхідно додати явне приведення типу." + +#: commands/tablecmds.c:11058 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "стовпець \"%s\" не можна автоматично привести до типу %s" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:11061 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "Можливо, необхідно вказати \"USING %s::%s\"." + +#: commands/tablecmds.c:11161 +#, c-format +msgid "cannot alter inherited column \"%s\" of relation \"%s\"" +msgstr "не можна змінити успадкований стовпець \"%s\" відношення \"%s\"" + +#: commands/tablecmds.c:11189 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "Вираз USING містить посилання на тип усього рядка таблиці." + +#: commands/tablecmds.c:11200 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "тип успадкованого стовпця \"%s\" повинен бути змінений і в дочірніх таблицях" + +#: commands/tablecmds.c:11325 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "не можна змінити тип стовпця \"%s\" двічі" + +#: commands/tablecmds.c:11363 +#, c-format +msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" +msgstr "вираз генерації для стовпця \"%s\" не можна автоматично привести до типу %s" + +#: commands/tablecmds.c:11368 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "значення за замовчуванням для стовпця \"%s\" не можна автоматично привести до типу %s" + +#: commands/tablecmds.c:11446 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "змінити тип стовпця, який використовується згенерованим стовпцем, не можна" + +#: commands/tablecmds.c:11447 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "Стовпець \"%s\" використовується згенерованим стовпцем \"%s\"." + +#: commands/tablecmds.c:11468 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "змінити тип стовпця, залученого в поданні або правилі, не можна" + +#: commands/tablecmds.c:11469 commands/tablecmds.c:11488 +#: commands/tablecmds.c:11506 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%s залежить від стовпця \"%s\"" + +#: commands/tablecmds.c:11487 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "неможливо змінити тип стовпця, що використовується у визначенні тригеру" + +#: commands/tablecmds.c:11505 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "неможливо змінити тип стовпця, що використовується у визначенні політики" + +#: commands/tablecmds.c:12514 commands/tablecmds.c:12526 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "неможливо змінити власника індексу \"%s\"" + +#: commands/tablecmds.c:12516 commands/tablecmds.c:12528 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "Замість цього змініть власника таблиці, що містить цей індекс." + +#: commands/tablecmds.c:12542 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "неможливо змінити власника послідовності \"%s\"" + +#: commands/tablecmds.c:12556 commands/tablecmds.c:15743 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "Замість цього використайте ALTER TYPE." + +#: commands/tablecmds.c:12565 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "\"%s\" - не таблиця, подання, послідовність або зовнішня таблиця" + +#: commands/tablecmds.c:12905 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "в одній інструкції не може бути декілька підкоманд SET TABLESPACE" + +#: commands/tablecmds.c:12982 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "\"%s\" - не таблиця, подання, матеріалізоване подання, індекс або TOAST-таблиця" + +#: commands/tablecmds.c:13015 commands/view.c:494 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "WITH CHECK OPTION підтримується лише з автооновлюваними поданнями" + +#: commands/tablecmds.c:13155 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "перемістити системне відношення \"%s\" не можна" + +#: commands/tablecmds.c:13171 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "переміщувати тимчасові таблиці інших сеансів не можна" + +#: commands/tablecmds.c:13341 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "у табличних просторах існують лише таблиці, індекси та матеріалізовані подання" + +#: commands/tablecmds.c:13353 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "переміщувати відношення у або з табличного простору pg_global не можна" + +#: commands/tablecmds.c:13445 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "переривання через блокування відношення \"%s.%s\" неможливе" + +#: commands/tablecmds.c:13461 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr " табличному просторі \"%s\" не знайдені відповідні відносини" + +#: commands/tablecmds.c:13577 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "змінити успадкування типізованої таблиці не можна" + +#: commands/tablecmds.c:13582 commands/tablecmds.c:14078 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "змінити успадкування секції не можна" + +#: commands/tablecmds.c:13587 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "змінити успадкування секціонованої таблиці не можна" + +#: commands/tablecmds.c:13633 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "успадкування для тимчасового відношення іншого сеансу не можливе" + +#: commands/tablecmds.c:13646 +#, c-format +msgid "cannot inherit from a partition" +msgstr "успадкування від секції неможливе" + +#: commands/tablecmds.c:13668 commands/tablecmds.c:16383 +#, c-format +msgid "circular inheritance not allowed" +msgstr "циклічне успадкування неприпустиме" + +#: commands/tablecmds.c:13669 commands/tablecmds.c:16384 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "\"%s\" вже є нащадком \"%s\"." + +#: commands/tablecmds.c:13682 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "тригер \"%s\" не дозволяє таблиці \"%s\" стати нащадком успадкування" + +#: commands/tablecmds.c:13684 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." +msgstr "Тригери ROW з перехідними таблицями не підтримуються в ієрархіях успадкування." + +#: commands/tablecmds.c:13887 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "стовпець \"%s\" в дочірній таблиці має бути позначений як NOT NULL" + +#: commands/tablecmds.c:13914 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "у дочірній таблиці не вистачає стовпця \"%s\"" + +#: commands/tablecmds.c:14002 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "дочірня таблиця \"%s\" має інше визначення перевірочного обмеження \"%s\"" + +#: commands/tablecmds.c:14010 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" +msgstr "обмеження \"%s\" конфліктує з неуспадкованим обмеженням дочірньої таблиці \"%s\"" + +#: commands/tablecmds.c:14021 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "обмеження \"%s\" конфліктує з NOT VALID обмеженням дочірньої таблиці \"%s\"" + +#: commands/tablecmds.c:14056 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "у дочірній таблиці не вистачає обмеження \"%s\"" + +#: commands/tablecmds.c:14145 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "відношення \"%s\" не є секцією відношення \"%s\"" + +#: commands/tablecmds.c:14151 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "відношення \"%s\" не є предком відношення \"%s\"" + +#: commands/tablecmds.c:14379 +#, c-format +msgid "typed tables cannot inherit" +msgstr "типізовані таблиці не можуть успадковуватись" + +#: commands/tablecmds.c:14409 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "у таблиці не вистачає стовпця \"%s\"" + +#: commands/tablecmds.c:14420 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "таблиця містить стовпець \"%s\", а тип потребує \"%s\"" + +#: commands/tablecmds.c:14429 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "таблиця \"%s\" містить стовпець \"%s\" іншого типу" + +#: commands/tablecmds.c:14443 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "таблиця містить зайвий стовпець \"%s\"" + +#: commands/tablecmds.c:14495 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "\"%s\" - не типізована таблиця" + +#: commands/tablecmds.c:14677 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "для ідентифікації репліки не можна використати неунікальний індекс \"%s\"" + +#: commands/tablecmds.c:14683 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "для ідентифікації репліки не можна використати небезпосередній індекс \"%s\"" + +#: commands/tablecmds.c:14689 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "для ідентифікації репліки не можна використати індекс з виразом \"%s\"" + +#: commands/tablecmds.c:14695 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "для ідентифікації репліки не можна використати частковий індекс \"%s\"" + +#: commands/tablecmds.c:14701 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "для ідентифікації репліки не можна використати неприпустимий індекс \"%s\"" + +#: commands/tablecmds.c:14718 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "індекс \"%s\" не можна використати як ідентифікацію репліки, тому що стовпець %d - системний стовпець" + +#: commands/tablecmds.c:14725 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "індекс \"%s\" не можна використати як ідентифікацію репліки, тому що стовпець \"%s\" допускає Null" + +#: commands/tablecmds.c:14918 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "змінити стан журналювання таблиці \"%s\" не можна, тому що вона тимчасова" + +#: commands/tablecmds.c:14942 +#, c-format +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "таблицю \"%s\" не можна змінити на нежурнальовану, тому що вона є частиною публікації" + +#: commands/tablecmds.c:14944 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "Нежурнальовані відношення не підтримують реплікацію." + +#: commands/tablecmds.c:14989 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "не вдалося змінити таблицю \"%s\" на журнальовану, тому що вона посилається на нежурнальовану таблицю \"%s\"" + +#: commands/tablecmds.c:14999 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "не вдалося змінити таблицю \"%s\" на нежурнальовану, тому що вона посилається на журнальовану таблицю \"%s\"" + +#: commands/tablecmds.c:15057 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "перемістити послідовність з власником в іншу схему не можна" + +#: commands/tablecmds.c:15163 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "відношення \"%s\" вже існує в схемі \"%s\"" + +#: commands/tablecmds.c:15726 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "\"%s\" - не складений тип" + +#: commands/tablecmds.c:15758 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "\"%s\" - не таблиця, подання, матеріалізоване подання, послідовність або зовнішня таблиця" + +#: commands/tablecmds.c:15793 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "нерозпізнана стратегія секціонування \"%s\"" + +#: commands/tablecmds.c:15801 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "стратегія секціонування \"по списку\" не може використовувати декілька стовпців" + +#: commands/tablecmds.c:15867 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "стовпець \"%s\", згаданий в ключі секціонування, не існує" + +#: commands/tablecmds.c:15875 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "системний стовпець \"%s\" не можна використати в ключі секціонування" + +#: commands/tablecmds.c:15886 commands/tablecmds.c:16000 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "використати згенерований стовпець в ключі секції, не можна" + +#: commands/tablecmds.c:15887 commands/tablecmds.c:16001 commands/trigger.c:641 +#: rewrite/rewriteHandler.c:829 rewrite/rewriteHandler.c:846 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "Стовпець \"%s\" є згенерованим стовпцем." + +#: commands/tablecmds.c:15963 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "функції у виразі ключа секціонування повинні бути позначені як IMMUTABLE" + +#: commands/tablecmds.c:15983 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "вирази ключа секціонування не можуть містити посилання на системний стовпець" + +#: commands/tablecmds.c:16013 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "не можна використати константий вираз як ключ секціонування" + +#: commands/tablecmds.c:16034 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "не вдалося визначити, яке правило сортування використати для виразу секціонування" + +#: commands/tablecmds.c:16069 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "Ви повинні вказати клас операторів гешування або визначити клас операторів гешування за замовчуванням для цього типу даних." + +#: commands/tablecmds.c:16075 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "Ви повинні вказати клас операторів (btree) або визначити клас операторів (btree) за замовчуванням для цього типу даних." + +#: commands/tablecmds.c:16220 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "обмеження секції для таблиці \"%s\" має на увазі наявні обмеження" + +#: commands/tablecmds.c:16224 partitioning/partbounds.c:3129 +#: partitioning/partbounds.c:3180 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "оновлене обмеження секції для секції за замовчуванням \"%s\" має на увазі наявні обмеження" + +#: commands/tablecmds.c:16323 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\" вже є секцією" + +#: commands/tablecmds.c:16329 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "неможливо підключити типізовану таблицю в якості секції" + +#: commands/tablecmds.c:16345 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "неможливо підключити нащадка успадкування в якості секції" + +#: commands/tablecmds.c:16359 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "неможливо підключити предка успадкування в якості секції" + +#: commands/tablecmds.c:16393 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "неможливо підкючити тимчасове відношення в якості секції постійного відношення \"%s\"" + +#: commands/tablecmds.c:16401 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "неможливо підключити постійне відношення в якості секції тимчасового відношення \"%s\"" + +#: commands/tablecmds.c:16409 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "неможливо підключити секцію до тимчасового відношення в іншому сеансі" + +#: commands/tablecmds.c:16416 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "неможливо підключити тимчасове відношення з іншого сеансу в якості секції" + +#: commands/tablecmds.c:16436 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "таблиця \"%s\" містить стовпець \"%s\", відсутній в батьківській \"%s\"" + +#: commands/tablecmds.c:16439 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "Нова секція може містити лише стовпці, що є у батьківській таблиці." + +#: commands/tablecmds.c:16451 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "тригер \"%s\" не дозволяє зробити таблицю \"%s\" секцією" + +#: commands/tablecmds.c:16453 commands/trigger.c:447 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "Тригери ROW з перехідними таблицями для секцій не підтримуються" + +#: commands/tablecmds.c:16616 +#, c-format +msgid "cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"" +msgstr "не можна підключити зовнішню таблицю \"%s\" в якості секції секціонованої таблиці \"%s\"" + +#: commands/tablecmds.c:16619 +#, c-format +msgid "Table \"%s\" contains unique indexes." +msgstr "Таблиця \"%s\" містить унікальні індекси." + +#: commands/tablecmds.c:17265 commands/tablecmds.c:17285 +#: commands/tablecmds.c:17305 commands/tablecmds.c:17324 +#: commands/tablecmds.c:17366 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "неможливо підключити індекс \"%s\" в якості секції індексу \"%s\"" + +#: commands/tablecmds.c:17268 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "Індекс \"%s\" вже підключений до іншого індексу." + +#: commands/tablecmds.c:17288 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "Індекс \"%s\" не є індексом жодної секції таблиці \"%s\"." + +#: commands/tablecmds.c:17308 +#, c-format +msgid "The index definitions do not match." +msgstr "Визначення індексів не співпадають." + +#: commands/tablecmds.c:17327 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "Індекс \"%s\" належить обмеженню в таблиці \"%s\", але обмеження для індексу \"%s\" не існує." + +#: commands/tablecmds.c:17369 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "До секції \"%s\" вже підключений інший індекс." + +#: commands/tablespace.c:162 commands/tablespace.c:179 +#: commands/tablespace.c:190 commands/tablespace.c:198 +#: commands/tablespace.c:638 replication/slot.c:1373 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не вдалося створити каталог \"%s\": %m" + +#: commands/tablespace.c:209 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "не вдалося отримати інформацію про каталог \"%s\": %m" + +#: commands/tablespace.c:218 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "\"%s\" існує, але це не каталог" + +#: commands/tablespace.c:249 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "немає прав на створення табличного простору \"%s\"" + +#: commands/tablespace.c:251 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "Щоб створити табличний простір, потрібно бути суперкористувачем." + +#: commands/tablespace.c:267 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "у шляху до розташування табличного простіру не повинно бути одинарних лапок" + +#: commands/tablespace.c:277 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "шлях до розташування табличного простору повинен бути абсолютним" + +#: commands/tablespace.c:289 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "шлях до розташування табличного простору \"%s\" занадто довгий" + +#: commands/tablespace.c:296 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "табличний простір не повинен розташовуватись всередині каталогу даних" + +#: commands/tablespace.c:305 commands/tablespace.c:965 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "неприпустиме ім'я табличного простору \"%s\"" + +#: commands/tablespace.c:307 commands/tablespace.c:966 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "Префікс \"\"pg_\" зарезервований для системних табличних просторів." + +#: commands/tablespace.c:326 commands/tablespace.c:987 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "табличний простір \"%s\" вже існує" + +#: commands/tablespace.c:442 commands/tablespace.c:948 +#: commands/tablespace.c:1037 commands/tablespace.c:1106 +#: commands/tablespace.c:1252 commands/tablespace.c:1455 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "табличний простір \"%s\" не існує" + +#: commands/tablespace.c:448 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "табличний простір \"%s\" вже існує, пропускається" + +#: commands/tablespace.c:525 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "табличний простір \"%s\" не пустий" + +#: commands/tablespace.c:597 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "каталог \"%s\" не існує" + +#: commands/tablespace.c:598 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "Створіть цей каталог для табличного простору до перезапуску сервера." + +#: commands/tablespace.c:603 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "не вдалося встановити права для каталогу \"%s\": %m" + +#: commands/tablespace.c:633 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "каталог \"%s\" вже використовується в якості табличного простору" + +#: commands/tablespace.c:757 commands/tablespace.c:770 +#: commands/tablespace.c:806 commands/tablespace.c:898 storage/file/fd.c:3108 +#: storage/file/fd.c:3448 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "не вдалося видалити каталог \"%s\": %m" + +#: commands/tablespace.c:819 commands/tablespace.c:907 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "не вдалося видалити символьне посилання \"%s\": %m" + +#: commands/tablespace.c:829 commands/tablespace.c:916 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "\"%s\" - не каталог або символьне посилання" + +#: commands/tablespace.c:1111 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "Табличний простір \"%s\" не існує." + +#: commands/tablespace.c:1554 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "не вдалося видалити каталоги табличного простору %u" + +#: commands/tablespace.c:1556 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "За потреби ви можете видалити каталоги вручну." + +#: commands/trigger.c:204 commands/trigger.c:215 +#, c-format +msgid "\"%s\" is a table" +msgstr "\"%s\" - таблиця" + +#: commands/trigger.c:206 commands/trigger.c:217 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "Таблиці не можуть мати тригери INSTEAD OF." + +#: commands/trigger.c:238 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\" є секційною таблицею" + +#: commands/trigger.c:240 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Тригери секціонованих таблиць не можуть використовувати перехідні таблиці." + +#: commands/trigger.c:252 commands/trigger.c:259 commands/trigger.c:429 +#, c-format +msgid "\"%s\" is a view" +msgstr "\"%s\" - подання" + +#: commands/trigger.c:254 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "Подання не можуть мати рядкові тригери BEFORE або AFTER." + +#: commands/trigger.c:261 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "Подання не можуть мати тригери TRUNCATE." + +#: commands/trigger.c:269 commands/trigger.c:276 commands/trigger.c:288 +#: commands/trigger.c:422 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "\"%s\" - зовнішня таблиця" + +#: commands/trigger.c:271 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "Зовнішні таблиці не можуть мати тригери INSTEAD OF." + +#: commands/trigger.c:278 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "Зовнішні таблиці не можуть мати тригери TRUNCATE." + +#: commands/trigger.c:290 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "Зовнішні таблиці не можуть мати обмежувальні тригери." + +#: commands/trigger.c:365 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "Тригери TRUNCATE FOR EACH ROW не підтримуються" + +#: commands/trigger.c:373 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "Тригери INSTEAD OF повинні мати тип FOR EACH ROW" + +#: commands/trigger.c:377 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "Тригери INSTEAD OF не можуть мати умови WHEN" + +#: commands/trigger.c:381 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "Тригери INSTEAD OF не можуть мати список стовпців" + +#: commands/trigger.c:410 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "Змінна іменування ROW в реченні REFERENCING не підтримується" + +#: commands/trigger.c:411 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "Використайте OLD TABLE або NEW TABLE для іменування перехідних таблиць." + +#: commands/trigger.c:424 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Тригери зовнішніх таблиць не можуть використовувати перехідні таблиці." + +#: commands/trigger.c:431 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Тригери подань не можуть використовувати перехідні таблиці." + +#: commands/trigger.c:451 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "Тригери ROW з перехідними таблицями для нащадків успадкування не підтримуються" + +#: commands/trigger.c:457 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "ім'я перехідної таблиці можна задати лише для тригеру AFTER" + +#: commands/trigger.c:462 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "Тригери TRUNCATE з перехідними таблицями не підтримуються" + +#: commands/trigger.c:479 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "перехідні таблиці не можна задати для тригерів, призначених для кількох подій" + +#: commands/trigger.c:490 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "перехідні таблиці не можна задати для тригерів зі списками стовпців" + +#: commands/trigger.c:507 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "NEW TABLE можна задати лише для тригерів INSERT або UPDATE" + +#: commands/trigger.c:512 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE не можна задавати декілька разів" + +#: commands/trigger.c:522 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE можна задати лише для тригерів DELETE або UPDATE" + +#: commands/trigger.c:527 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE не можна задавати декілька разів" + +#: commands/trigger.c:537 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "Ім'я OLD TABLE та ім'я NEW TABLE не можуть бути однаковими" + +#: commands/trigger.c:601 commands/trigger.c:614 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "в умові WHEN операторного тригера не можна посилатись на значення стовпця" + +#: commands/trigger.c:606 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "В умові WHEN тригеру INSERT не можна посилатись на значення OLD" + +#: commands/trigger.c:619 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "В умові WHEN тригера DELETE не можна посилатись на значення NEW" + +#: commands/trigger.c:624 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "В умові WHEN тригера BEFORE не можна посилатись на системні стовпці NEW" + +#: commands/trigger.c:632 commands/trigger.c:640 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "В умові WHEN тригера BEFORE не можна посилатись на згенеровані стовпці NEW" + +#: commands/trigger.c:633 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "Використовується посилання на весь рядок і таблиця містить згенеровані стовпці." + +#: commands/trigger.c:780 commands/trigger.c:1385 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "тригер \"%s\" для відношення \"%s\" вже існує" + +#: commands/trigger.c:1271 commands/trigger.c:1432 commands/trigger.c:1568 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "тригер \"%s\" для таблиці \"%s\" не існує" + +#: commands/trigger.c:1515 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "немає доступу: \"%s\" - системний тригер" + +#: commands/trigger.c:2116 +#, c-format +msgid "trigger function %u returned null value" +msgstr "тригерна функція %u повернула значення null" + +#: commands/trigger.c:2176 commands/trigger.c:2390 commands/trigger.c:2625 +#: commands/trigger.c:2933 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "Тригер BEFORE STATEMENT не може повертати значення" + +#: commands/trigger.c:2250 +#, c-format +msgid "moving row to another partition during a BEFORE FOR EACH ROW trigger is not supported" +msgstr "переміщення рядка до іншої секції під час тригеру BEFORE FOR EACH ROW не підтримується" + +#: commands/trigger.c:2251 commands/trigger.c:2755 +#, c-format +msgid "Before executing trigger \"%s\", the row was to be in partition \"%s.%s\"." +msgstr "Перед виконанням тригера \"%s\", рядок повинен був бути в секції \"%s.%s\"." + +#: commands/trigger.c:2754 +#, c-format +msgid "moving row to another partition during a BEFORE trigger is not supported" +msgstr "переміщення рядка до іншої секції під час тригеру BEFORE не підтримується" + +#: commands/trigger.c:2996 executor/nodeModifyTable.c:1380 +#: executor/nodeModifyTable.c:1449 +#, c-format +msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgstr "кортеж, який повинен бути оновленим, вже змінений в операції, яка викликана поточною командою" + +#: commands/trigger.c:2997 executor/nodeModifyTable.c:840 +#: executor/nodeModifyTable.c:914 executor/nodeModifyTable.c:1381 +#: executor/nodeModifyTable.c:1450 +#, c-format +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." +msgstr "Можливо, для поширення змін в інші рядки слід використати тригер AFTER замість тригера BEFORE." + +#: commands/trigger.c:3026 executor/nodeLockRows.c:225 +#: executor/nodeLockRows.c:234 executor/nodeModifyTable.c:220 +#: executor/nodeModifyTable.c:856 executor/nodeModifyTable.c:1397 +#: executor/nodeModifyTable.c:1613 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "не вдалося серіалізувати доступ через паралельне оновлення" + +#: commands/trigger.c:3034 executor/nodeModifyTable.c:946 +#: executor/nodeModifyTable.c:1467 executor/nodeModifyTable.c:1637 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "не вдалося серіалізувати доступ через паралельне видалення" + +#: commands/trigger.c:5094 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "обмеження \"%s\" не є відкладеним" + +#: commands/trigger.c:5117 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "обмеження \"%s\" не існує" + +#: commands/tsearchcmds.c:118 commands/tsearchcmds.c:683 +#, c-format +msgid "function %s should return type %s" +msgstr "функція %s повинна повертати тип %s" + +#: commands/tsearchcmds.c:195 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "для створення аналізаторів текстового пошуку потрібно бути суперкористувачем" + +#: commands/tsearchcmds.c:248 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "параметр аналізатора текстового пошуку \"%s\" не розпізнаний" + +#: commands/tsearchcmds.c:258 +#, c-format +msgid "text search parser start method is required" +msgstr "для аналізатора текстового пошуку необхідний метод start" + +#: commands/tsearchcmds.c:263 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "для аналізатора текстового пошуку необхідний метод gettoken" + +#: commands/tsearchcmds.c:268 +#, c-format +msgid "text search parser end method is required" +msgstr "для аналізатора текстового пошуку необхідний метод end" + +#: commands/tsearchcmds.c:273 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "для аналізатора текстового пошуку необхідний метод lextypes" + +#: commands/tsearchcmds.c:390 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "шаблон текстового пошуку \"%s\" не приймає параметри" + +#: commands/tsearchcmds.c:464 +#, c-format +msgid "text search template is required" +msgstr "необхідний шаблон текстового пошуку" + +#: commands/tsearchcmds.c:750 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "для створення шаблонів текстового пошуку потрібно бути суперкористувачем" + +#: commands/tsearchcmds.c:792 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "параметр шаблону текстового пошуку \"%s\" не розпізнаний" + +#: commands/tsearchcmds.c:802 +#, c-format +msgid "text search template lexize method is required" +msgstr "для шаблону текстового пошуку необхідний метод lexize" + +#: commands/tsearchcmds.c:1006 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "параметр конфігурації текстового пошуку \"%s\" не розпізнаний" + +#: commands/tsearchcmds.c:1013 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "вказати параметри PARSER і COPY одночасно не можна" + +#: commands/tsearchcmds.c:1049 +#, c-format +msgid "text search parser is required" +msgstr "необхідний аналізатор текстового пошуку" + +#: commands/tsearchcmds.c:1273 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "тип маркера \"%s\" не існує" + +#: commands/tsearchcmds.c:1500 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "зіставлення для типу маркера \"%s\" не існує" + +#: commands/tsearchcmds.c:1506 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "зіставлення для типу маркера \"%s\" не існує, пропускається" + +#: commands/tsearchcmds.c:1669 commands/tsearchcmds.c:1784 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "неприпустимий формат списку параметрів: \"%s\"" + +#: commands/typecmds.c:206 +#, c-format +msgid "must be superuser to create a base type" +msgstr "для створення базового типу потрібно бути суперкористувачем" + +#: commands/typecmds.c:264 +#, c-format +msgid "Create the type as a shell type, then create its I/O functions, then do a full CREATE TYPE." +msgstr "Створіть тип в якості оболонки, потім створіть його функції вводу-виводу, а потім виконайте повну CREATE TYPE." + +#: commands/typecmds.c:314 commands/typecmds.c:1394 commands/typecmds.c:3832 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "атрибут типу \"%s\" не розпізнаний" + +#: commands/typecmds.c:370 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "неприпустима категорія типу \"%s\": повинен бути простий ASCII" + +#: commands/typecmds.c:389 +#, c-format +msgid "array element type cannot be %s" +msgstr "типом елементу масиву не може бути %s" + +#: commands/typecmds.c:421 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "тип вирівнювання \"%s\" не розпізнаний" + +#: commands/typecmds.c:438 commands/typecmds.c:3718 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "сховище \"%s\" не розпізнане" + +#: commands/typecmds.c:449 +#, c-format +msgid "type input function must be specified" +msgstr "необхідно вказати функцію вводу типу" + +#: commands/typecmds.c:453 +#, c-format +msgid "type output function must be specified" +msgstr "необхідно вказати функцію виводу типу" + +#: commands/typecmds.c:458 +#, c-format +msgid "type modifier output function is useless without a type modifier input function" +msgstr "функція виводу модифікатора типу недоцільна без функції вводу модифікатора типу" + +#: commands/typecmds.c:745 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "\"%s\" - невідповідний базовий тип для домену" + +#: commands/typecmds.c:837 +#, c-format +msgid "multiple default expressions" +msgstr "неодноразове визначення значення типу за замовчуванням" + +#: commands/typecmds.c:900 commands/typecmds.c:909 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "конфліктуючі обмеження NULL/NOT NULL" + +#: commands/typecmds.c:925 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "перевірки обмеження для доменів не можуть позначатись як NO INHERIT" + +#: commands/typecmds.c:934 commands/typecmds.c:2536 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "обмеження унікальності неможливе для доменів" + +#: commands/typecmds.c:940 commands/typecmds.c:2542 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "обмеження первинного ключа неможливі для доменів" + +#: commands/typecmds.c:946 commands/typecmds.c:2548 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "обмеження винятків неможливі для доменів" + +#: commands/typecmds.c:952 commands/typecmds.c:2554 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "обмеження зовнішніх ключів неможливі для доменів" + +#: commands/typecmds.c:961 commands/typecmds.c:2563 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "зазначення відкладення обмежень для доменів не підтримується" + +#: commands/typecmds.c:1271 utils/cache/typcache.c:2430 +#, c-format +msgid "%s is not an enum" +msgstr "%s не є переліком" + +#: commands/typecmds.c:1402 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "вимагається атрибут типу \"subtype\"" + +#: commands/typecmds.c:1407 +#, c-format +msgid "range subtype cannot be %s" +msgstr "%s не може бути підтипом діапазону" + +#: commands/typecmds.c:1426 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "вказано правило сортування для діапазону, але підтип не підтримує сортування" + +#: commands/typecmds.c:1436 +#, c-format +msgid "cannot specify a canonical function without a pre-created shell type" +msgstr "неможливо вказати канонічну функцію без попередньо створеного типу оболонки" + +#: commands/typecmds.c:1437 +#, c-format +msgid "Create the type as a shell type, then create its canonicalization function, then do a full CREATE TYPE." +msgstr "Створіть тип в якості оболонки, потім створіть його функцію канонізації, а потім виконайте повну CREATE TYPE." + +#: commands/typecmds.c:1648 +#, c-format +msgid "type input function %s has multiple matches" +msgstr "функція введення типу %s має декілька збігів" + +#: commands/typecmds.c:1666 +#, c-format +msgid "type input function %s must return type %s" +msgstr "функція вводу типу %s повинна повертати тип %s" + +#: commands/typecmds.c:1682 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "функція введення типу %s не повинна бути змінною" + +#: commands/typecmds.c:1710 +#, c-format +msgid "type output function %s must return type %s" +msgstr "функція виводу типу %s повинна повертати тип %s" + +#: commands/typecmds.c:1717 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "функція виводу типу %s не повинна бути змінною" + +#: commands/typecmds.c:1746 +#, c-format +msgid "type receive function %s has multiple matches" +msgstr "функція отримання типу %s має декілька збігів" + +#: commands/typecmds.c:1764 +#, c-format +msgid "type receive function %s must return type %s" +msgstr "функція отримання типу %s повинна повертати тип %s" + +#: commands/typecmds.c:1771 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "функція отримання типу %s не повинна бути змінною" + +#: commands/typecmds.c:1799 +#, c-format +msgid "type send function %s must return type %s" +msgstr "функція відправлення типу %s повинна повертати тип %s" + +#: commands/typecmds.c:1806 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "функція відправлення типу %s не повинна бути змінною" + +#: commands/typecmds.c:1833 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr "функція typmod_in %s повинна повертати тип %s" + +#: commands/typecmds.c:1840 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "функція вводу модифікатора типу %s не повинна бути змінною" + +#: commands/typecmds.c:1867 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "функція typmod_out %s повинна повертати тип %s" + +#: commands/typecmds.c:1874 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "функція виводу модифікатора типу %s не повинна бути змінною" + +#: commands/typecmds.c:1901 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "функція аналізу типу %s повинна повертати тип %s" + +#: commands/typecmds.c:1947 +#, c-format +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." +msgstr "Ви повинні вказати клас операторів для типу діапазону або визначити клас операторів за замовчуванням для цього підтипу." + +#: commands/typecmds.c:1978 +#, c-format +msgid "range canonical function %s must return range type" +msgstr "функція канонічного діапазону %s повинна вертати тип діапазону" + +#: commands/typecmds.c:1984 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "функція канонічного діапазону %s повинна бути незмінною" + +#: commands/typecmds.c:2020 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "функція розбіжностей для підтипу діапазону %s повинна повертати тип %s" + +#: commands/typecmds.c:2027 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "функція розбіжностей для підтипу діапазону %s повинна бути незмінною" + +#: commands/typecmds.c:2054 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "значення OID масиву pg_type не встановлено в режимі двійкового оновлення" + +#: commands/typecmds.c:2352 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "стовпець \"%s\" таблиці \"%s\" містить значення NULL" + +#: commands/typecmds.c:2465 commands/typecmds.c:2667 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "обмеження \"%s\" для домену \"%s\" не існує" + +#: commands/typecmds.c:2469 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "обмеження \"%s\" для домену \"%s\" не існує, пропускається" + +#: commands/typecmds.c:2674 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "обмеження \"%s\" для домену \"%s\" не є перевірочним обмеженням" + +#: commands/typecmds.c:2780 +#, c-format +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "стовпець \"%s\" таблиці \"%s\" містить значення, які порушують нове обмеження" + +#: commands/typecmds.c:3009 commands/typecmds.c:3207 commands/typecmds.c:3289 +#: commands/typecmds.c:3476 +#, c-format +msgid "%s is not a domain" +msgstr "%s - не домен" + +#: commands/typecmds.c:3041 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "обмеження \"%s\" для домену \"%s\" вже існує" + +#: commands/typecmds.c:3092 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "у перевірочному обмеженні для домену не можна посилатись на таблиці" + +#: commands/typecmds.c:3219 commands/typecmds.c:3301 commands/typecmds.c:3593 +#, c-format +msgid "%s is a table's row type" +msgstr "%s - тип рядків таблиці" + +#: commands/typecmds.c:3221 commands/typecmds.c:3303 commands/typecmds.c:3595 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "Замість цього використайте ALTER TABLE." + +#: commands/typecmds.c:3228 commands/typecmds.c:3310 commands/typecmds.c:3508 +#, c-format +msgid "cannot alter array type %s" +msgstr "змінити тип масиву \"%s\" не можна" + +#: commands/typecmds.c:3230 commands/typecmds.c:3312 commands/typecmds.c:3510 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "Ви можете змінити тип %s, який спричинить зміну типу масиву." + +#: commands/typecmds.c:3578 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "тип \"%s\" вже існує в схемі \"%s\"" + +#: commands/typecmds.c:3746 +#, c-format +msgid "cannot change type's storage to PLAIN" +msgstr "неможливо змінити сховище типу на PLAIN" + +#: commands/typecmds.c:3827 +#, c-format +msgid "type attribute \"%s\" cannot be changed" +msgstr "атрибут типу \"%s\" неможливо змінити" + +#: commands/typecmds.c:3845 +#, c-format +msgid "must be superuser to alter a type" +msgstr "для зміни типу потрібно бути суперкористувачем" + +#: commands/typecmds.c:3866 commands/typecmds.c:3876 +#, c-format +msgid "%s is not a base type" +msgstr "%s - не є базовим типом" + +#: commands/user.c:140 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSID вже не потрібно вказувати" + +#: commands/user.c:294 +#, c-format +msgid "must be superuser to create superusers" +msgstr "для створення суперкористувачів необхідно бути суперкористувачем" + +#: commands/user.c:301 +#, c-format +msgid "must be superuser to create replication users" +msgstr "для створення користувачів реплікацій потрібно бути суперкористувачем" + +#: commands/user.c:308 commands/user.c:734 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "для зміни атрибута bypassrls потрібно бути суперкористувачем" + +#: commands/user.c:315 +#, c-format +msgid "permission denied to create role" +msgstr "немає прав для створення ролі" + +#: commands/user.c:325 commands/user.c:1224 commands/user.c:1231 +#: utils/adt/acl.c:5327 utils/adt/acl.c:5333 gram.y:15146 gram.y:15184 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "ім'я ролі \"%s\" зарезервовано" + +#: commands/user.c:327 commands/user.c:1226 commands/user.c:1233 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "Імена ролей, які починаються на \"pg_\", зарезервовані." + +#: commands/user.c:348 commands/user.c:1248 +#, c-format +msgid "role \"%s\" already exists" +msgstr "роль \"%s\" вже існує" + +#: commands/user.c:414 commands/user.c:843 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "пустий рядок є неприпустимим паролем, пароль скидається" + +#: commands/user.c:443 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "значення OID в pg_authid не встановлено в режимі двійкового оновлення" + +#: commands/user.c:720 commands/user.c:944 commands/user.c:1485 +#: commands/user.c:1627 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "для зміни суперкористувачів потрібно бути суперкористувачем" + +#: commands/user.c:727 +#, c-format +msgid "must be superuser to alter replication users" +msgstr "для зміни користувачів реплікацій потрібно бути суперкористувачем" + +#: commands/user.c:750 commands/user.c:951 +#, c-format +msgid "permission denied" +msgstr "немає доступу" + +#: commands/user.c:981 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "для глобальної зміни параметрів потрібно бути суперкористувачем" + +#: commands/user.c:1003 +#, c-format +msgid "permission denied to drop role" +msgstr "немає прав для видалення ролі" + +#: commands/user.c:1028 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "використати спеціальну роль у DROP ROLE не можна" + +#: commands/user.c:1038 commands/user.c:1195 commands/variable.c:770 +#: commands/variable.c:844 utils/adt/acl.c:5184 utils/adt/acl.c:5231 +#: utils/adt/acl.c:5259 utils/adt/acl.c:5277 utils/init/miscinit.c:675 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "роль \"%s\" не існує" + +#: commands/user.c:1043 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "роль \"%s\" не існує, пропускається" + +#: commands/user.c:1056 commands/user.c:1060 +#, c-format +msgid "current user cannot be dropped" +msgstr "користувач не можна видалити сам себе" + +#: commands/user.c:1064 +#, c-format +msgid "session user cannot be dropped" +msgstr "користувача поточного сеансу не можна видалити" + +#: commands/user.c:1074 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "для видалення суперкористувачів потрібно бути суперкористувачем" + +#: commands/user.c:1090 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "роль \"%s\" не можна видалити, тому що деякі об'єкти залежать від неї" + +#: commands/user.c:1211 +#, c-format +msgid "session user cannot be renamed" +msgstr "користувача поточного сеансу не можна перейменувати" + +#: commands/user.c:1215 +#, c-format +msgid "current user cannot be renamed" +msgstr "користувач не може перейменувати сам себе" + +#: commands/user.c:1258 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "для перейменування суперкористувачів потрібно бути суперкористувачем" + +#: commands/user.c:1265 +#, c-format +msgid "permission denied to rename role" +msgstr "немає прав на перейменування ролі" + +#: commands/user.c:1286 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "У результаті перейменування ролі сума MD5 паролю очищена" + +#: commands/user.c:1346 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "в GRANT/REVOKE ROLE не можна включати назви стовпців" + +#: commands/user.c:1384 +#, c-format +msgid "permission denied to drop objects" +msgstr "немає прав на видалення об'єктів" + +#: commands/user.c:1411 commands/user.c:1420 +#, c-format +msgid "permission denied to reassign objects" +msgstr "немає прав на повторне призначення об'єктів" + +#: commands/user.c:1493 commands/user.c:1635 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "потрібно мати параметр admin для ролі \"%s\"" + +#: commands/user.c:1510 +#, c-format +msgid "must be superuser to set grantor" +msgstr "для встановлення права управління правами необхідно бути суперкористувачем" + +#: commands/user.c:1535 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "роль \"%s\" - учасник ролі \"%s\"" + +#: commands/user.c:1550 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "роль \"%s\" вже є учасником ролі \"%s\"" + +#: commands/user.c:1657 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "роль \"%s\" не є учасником ролі \"%s\"" + +#: commands/vacuum.c:129 +#, c-format +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "нерозпізнаний параметр ANALYZE \"%s\"" + +#: commands/vacuum.c:151 +#, c-format +msgid "parallel option requires a value between 0 and %d" +msgstr "паралельний параметр потребує значення між 0 і %d" + +#: commands/vacuum.c:163 +#, c-format +msgid "parallel vacuum degree must be between 0 and %d" +msgstr "ступінь паралельної очистки повинен бути між 0 і %d" + +#: commands/vacuum.c:180 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "нерозпізнаний параметр VACUUM \"%s\"" + +#: commands/vacuum.c:203 +#, c-format +msgid "VACUUM FULL cannot be performed in parallel" +msgstr "VACUUM FULL не можна виконати паралельно" + +#: commands/vacuum.c:219 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "Якщо задається список стовпців, необхідно вказати параметр ANALYZE" + +#: commands/vacuum.c:309 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s не можна виконати під час VACUUM або ANALYZE" + +#: commands/vacuum.c:319 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "Параметр VACUUM DISABLE_PAGE_SKIPPING не можна використовувати з FULL" + +#: commands/vacuum.c:560 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "\"%s\" пропускається --- лише суперкористувач може очистити" + +#: commands/vacuum.c:564 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "пропускається \"%s\" --- лише суперкористувач або власник БД може очистити" + +#: commands/vacuum.c:568 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "пропускається \"%s\" --- лише власник таблиці або бази даних може очистити" + +#: commands/vacuum.c:583 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "пропуск об'єкта \"%s\" --- тільки суперкористувач може його аналізувати" + +#: commands/vacuum.c:587 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "пропуск об'єкта \"%s\" --- тільки суперкористувач або власник бази даних може його аналізувати" + +#: commands/vacuum.c:591 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "пропуск об'єкта \"%s\" --- тільки власник таблиці або бази даних може його аналізувати" + +#: commands/vacuum.c:670 commands/vacuum.c:766 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "очистка \"%s\" пропускається --- блокування недоступне" + +#: commands/vacuum.c:675 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "очистка \"%s\" пропускається --- це відношення більше не існує" + +#: commands/vacuum.c:691 commands/vacuum.c:771 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "пропуск аналізу об'єкта \"%s\" --- блокування недоступне" + +#: commands/vacuum.c:696 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "пропуск аналізу об'єкта\"%s\" --- відношення більше не існує" + +#: commands/vacuum.c:994 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "найстарший xmin далеко в минулому" + +#: commands/vacuum.c:995 +#, c-format +msgid "Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "Завершіть відкриті транзакції якнайшвидше, щоб уникнути проблеми зациклення.\n" +"Можливо, вам також доведеться затвердити або відкотити старі підготовленні транзакції, або видалити застарілі слоти реплікації." + +#: commands/vacuum.c:1036 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "найстарший multixact далеко в минулому" + +#: commands/vacuum.c:1037 +#, c-format +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "Завершіть відкриті транзакції з multixacts якнайшвидше, щоб уникнути проблеми зациклення." + +#: commands/vacuum.c:1623 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "деякі бази даних не очищалися протягом більш ніж 2 мільярдів транзакцій" + +#: commands/vacuum.c:1624 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "Можливо, ви вже втратили дані в результаті зациклення транзакцій." + +#: commands/vacuum.c:1784 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "пропускається \"%s\" --- очищати не таблиці або спеціальні системні таблиці не можна" + +#: commands/variable.c:165 utils/misc/guc.c:11156 utils/misc/guc.c:11218 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "Нерозпізнане ключове слово: \"%s\"." + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "Суперечливі специфікації стилю дат." + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "В інтервалі, що задає часовий пояс, не можна вказувати місяці." + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "В інтервалі, що задає часовий пояс, не можна вказувати дні." + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "часовий пояс \"%s\", мабуть, використовує високосні секунди" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQL не підтримує високосні секунди." + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "Зсув часового поясу UTC поза діапазоном." + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "не можна встановити режим транзакції \"читання-запис\" всередині транзакції \"лише читання\"" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "режим транзакції \"читання-запис\" повинен бути встановлений до виконання запитів" + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "не можна встановити режим транзакції \"читання-запис\" під час відновлення" + +#: commands/variable.c:534 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "Команда SET TRANSACTION ISOLATION LEVEL повинна викликатися до будь-яких запитів" + +#: commands/variable.c:541 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "Команда SET TRANSACTION ISOLATION LEVEL не повинна викликатияь в підтранзакції" + +#: commands/variable.c:548 storage/lmgr/predicate.c:1623 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "використовувати серіалізований режим в hot standby не можна" + +#: commands/variable.c:549 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "Ви можете використати REPEATABLE READ замість цього." + +#: commands/variable.c:567 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "Команда SET TRANSACTION [NOT] DEFERRABLE не може викликатись в підтранзакції" + +#: commands/variable.c:573 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "Команда SET TRANSACTION [NOT] DEFERRABLE повинна викликатись до будь-яких запитів" + +#: commands/variable.c:655 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "Перетворення між %s і %s не підтримується." + +#: commands/variable.c:662 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "Змінити клієнтське кодування зараз неможливо." + +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "змінити клієнтське кодування під час паралельної операції неможливо" + +#: commands/variable.c:863 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "немає прав для встановлення ролі \"%s\"" + +#: commands/view.c:84 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "не вдалося визначити, яке правило сортування використати для стовпця подання \"%s\"" + +#: commands/view.c:265 commands/view.c:276 +#, c-format +msgid "cannot drop columns from view" +msgstr "видалити стовпці з подання неможливо" + +#: commands/view.c:281 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "змінити ім'я стовпця \"%s\" на \"%s\" в поданні неможливо" + +#: commands/view.c:284 +#, c-format +msgid "Use ALTER VIEW ... RENAME COLUMN ... to change name of view column instead." +msgstr "Щоб змінити назву стовпця подання, замість цього використайте ALTER VIEW ... RENAME COLUMN ..." + +#: commands/view.c:290 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "змінити тип стовпця подання \"%s\" з %s на %s неможливо" + +#: commands/view.c:441 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "подання не повинні містити SELECT INTO" + +#: commands/view.c:453 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "подання не повинні містити інструкції, які змінюють дані в WITH" + +#: commands/view.c:523 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "У CREATE VIEW вказано більше імен стовпців, ніж самих стовпців" + +#: commands/view.c:531 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "подання не можуть бути нежурнальованими, так як вони не мають сховища" + +#: commands/view.c:545 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "подання \"%s\" буде тичасовим поданням" + +#: executor/execCurrent.c:79 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "курсор \"%s\" не є запитом SELECT" + +#: executor/execCurrent.c:85 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "курсор \"%s\" утримується з минулої транзакції" + +#: executor/execCurrent.c:118 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "курсор \"%s\" має декілька посилань FOR UPDATE/SHARE на таблицю \"%s\"" + +#: executor/execCurrent.c:127 +#, c-format +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "курсор \"%s\" не має посилання FOR UPDATE/SHARE на таблицю \"%s\"" + +#: executor/execCurrent.c:137 executor/execCurrent.c:182 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr "курсор \"%s\" не розташовується у рядку" + +#: executor/execCurrent.c:169 executor/execCurrent.c:228 +#: executor/execCurrent.c:239 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "курсор \"%s\" - не просте оновлюване сканування таблиці \"%s\"" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2404 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "тип параметру %d (%s) не відповідає тому, з котрим тривала підготовка плану (%s)" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2416 +#, c-format +msgid "no value found for parameter %d" +msgstr "не знайдено значення для параметру %d" + +#: executor/execExpr.c:859 parser/parse_agg.c:816 +#, c-format +msgid "window function calls cannot be nested" +msgstr "виклики віконних функцій не можуть бути вкладеними" + +#: executor/execExpr.c:1318 +#, c-format +msgid "target type is not an array" +msgstr "цільовий тип не є масивом" + +#: executor/execExpr.c:1651 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "Стовпець ROW() має тип %s замість %s" + +#: executor/execExpr.c:2176 executor/execSRF.c:708 parser/parse_func.c:135 +#: parser/parse_func.c:646 parser/parse_func.c:1020 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "функції не можна передати більше ніж %d аргумент" +msgstr[1] "функції не можна передати більше ніж %d аргументи" +msgstr[2] "функції не можна передати більше ніж %d аргументів" +msgstr[3] "функції не можна передати більше ніж %d аргументів" + +#: executor/execExpr.c:2587 executor/execExpr.c:2593 +#: executor/execExprInterp.c:2730 utils/adt/arrayfuncs.c:262 +#: utils/adt/arrayfuncs.c:560 utils/adt/arrayfuncs.c:1302 +#: utils/adt/arrayfuncs.c:3348 utils/adt/arrayfuncs.c:5308 +#: utils/adt/arrayfuncs.c:5821 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "число вимірів масива (%d) перевищує ліміт (%d)" + +#: executor/execExprInterp.c:1894 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "атрибут %d типу %s був видалений" + +#: executor/execExprInterp.c:1900 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "атрибут %d типу %s має неправильний тип" + +#: executor/execExprInterp.c:1902 executor/execExprInterp.c:3002 +#: executor/execExprInterp.c:3049 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "Таблиця має тип %s, але запит очікував %s." + +#: executor/execExprInterp.c:2494 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF для таблиць такого типу не підтримується" + +#: executor/execExprInterp.c:2708 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "не можна об'єднати несумісні масиви" + +#: executor/execExprInterp.c:2709 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "Масив з типом елементів %s не може бути включений в конструкцію ARRAY з типом елементів %s." + +#: executor/execExprInterp.c:2750 executor/execExprInterp.c:2780 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "для багатовимірних масивів повинні задаватись вирази з відповідними вимірами" + +#: executor/execExprInterp.c:3001 executor/execExprInterp.c:3048 +#, c-format +msgid "attribute %d has wrong type" +msgstr "атрибут %d має неправильний тип" + +#: executor/execExprInterp.c:3158 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "підрядковий символ масиву у призначенні не може бути NULL" + +#: executor/execExprInterp.c:3588 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "домен %s не допускає значення null" + +#: executor/execExprInterp.c:3603 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "значення домену %s порушує перевірочнео бмеження \"%s\"" + +#: executor/execExprInterp.c:3973 executor/execExprInterp.c:3990 +#: executor/execExprInterp.c:4091 executor/nodeModifyTable.c:109 +#: executor/nodeModifyTable.c:120 executor/nodeModifyTable.c:137 +#: executor/nodeModifyTable.c:145 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "тип рядка таблиці відрізняється від типу рядка-результату запиту" + +#: executor/execExprInterp.c:3974 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "Рядок таблиці містить %d атрибут, але запит очікував %d." +msgstr[1] "Рядок таблиці містить %d атрибути, але запит очікував %d." +msgstr[2] "Рядок таблиці містить %d атрибутів, але запит очікував %d." +msgstr[3] "Рядок таблиці містить %d атрибутів, але запит очікував %d." + +#: executor/execExprInterp.c:3991 executor/nodeModifyTable.c:121 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "Таблиця має тип %s у порядковому розташуванні %d, але запит очікує %s." + +#: executor/execExprInterp.c:4092 executor/execSRF.c:967 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "Невідповідність параметрів фізичного зберігання видаленого атрибуту %d." + +#: executor/execIndexing.c:550 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "ON CONFLICT не підтримує відкладені обмеження унікальності/обмеження-виключення в якості визначального індексу" + +#: executor/execIndexing.c:821 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "не вдалося створити обмеження-виключення \"%s\"" + +#: executor/execIndexing.c:824 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "Ключ %s конфліктує з ключем %s." + +#: executor/execIndexing.c:826 +#, c-format +msgid "Key conflicts exist." +msgstr "Існують конфлікти ключей." + +#: executor/execIndexing.c:832 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "конфліктуюче значення ключа порушує обмеження-виключення \"%s\"" + +#: executor/execIndexing.c:835 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "Ключ %s конфліктує з існуючим ключем %s." + +#: executor/execIndexing.c:837 +#, c-format +msgid "Key conflicts with existing key." +msgstr "Ключ конфліктує з існуючим ключем." + +#: executor/execMain.c:1091 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "послідовність \"%s\" не можна змінити" + +#: executor/execMain.c:1097 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "TOAST-відношення \"%s\" не можна змінити" + +#: executor/execMain.c:1115 rewrite/rewriteHandler.c:2934 +#: rewrite/rewriteHandler.c:3708 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "вставити дані в подання \"%s\" не можна" + +#: executor/execMain.c:1117 rewrite/rewriteHandler.c:2937 +#: rewrite/rewriteHandler.c:3711 +#, c-format +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "Щоб подання допускало додавання даних, встановіть тригер INSTEAD OF INSERT або безумовне правило ON INSERT DO INSTEAD." + +#: executor/execMain.c:1123 rewrite/rewriteHandler.c:2942 +#: rewrite/rewriteHandler.c:3716 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "оновити подання \"%s\" не можна" + +#: executor/execMain.c:1125 rewrite/rewriteHandler.c:2945 +#: rewrite/rewriteHandler.c:3719 +#, c-format +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "Щоб подання допускало оновлення, встановіть тригер INSTEAD OF UPDATE або безумовне правило ON UPDATE DO INSTEAD." + +#: executor/execMain.c:1131 rewrite/rewriteHandler.c:2950 +#: rewrite/rewriteHandler.c:3724 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "видалити дані з подання \"%s\" не можна" + +#: executor/execMain.c:1133 rewrite/rewriteHandler.c:2953 +#: rewrite/rewriteHandler.c:3727 +#, c-format +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "Щоб подання допускало видалення даних, встановіть тригер INSTEAD OF DELETE або безумновне правило ON DELETE DO INSTEAD." + +#: executor/execMain.c:1144 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "змінити матеріалізоване подання \"%s\" не можна" + +#: executor/execMain.c:1156 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "вставляти дані в зовнішню таблицю \"%s\" не можна" + +#: executor/execMain.c:1162 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "зовнішня таблиця \"%s\" не допускає додавання даних" + +#: executor/execMain.c:1169 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "оновити зовнішню таблицю \"%s\" не можна" + +#: executor/execMain.c:1175 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "зовнішня таблиця \"%s\" не дозволяє оновлення" + +#: executor/execMain.c:1182 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "видаляти дані з зовнішньої таблиці \"%s\" не можна" + +#: executor/execMain.c:1188 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "зовнішня таблиця \"%s\" не дозволяє видалення даних" + +#: executor/execMain.c:1199 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "відношення \"%s\" не можна змінити" + +#: executor/execMain.c:1226 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "блокувати рядки в послідовності \"%s\" не можна" + +#: executor/execMain.c:1233 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "блокувати рядки в TOAST-відношенні \"%s\" не можна" + +#: executor/execMain.c:1240 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "блокувати рядки в поданні \"%s\" не можна" + +#: executor/execMain.c:1248 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "блокувати рядки в матеріалізованому поданні \"%s\" не можна" + +#: executor/execMain.c:1257 executor/execMain.c:2627 +#: executor/nodeLockRows.c:132 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "блокувати рядки в зовнішній таблиці \"%s\" не можна" + +#: executor/execMain.c:1263 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "блокувати рядки у відношенні \"%s\" не можна" + +#: executor/execMain.c:1879 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "новий рядок для відношення \"%s\" порушує обмеження секції" + +#: executor/execMain.c:1881 executor/execMain.c:1964 executor/execMain.c:2012 +#: executor/execMain.c:2120 +#, c-format +msgid "Failing row contains %s." +msgstr "Помилковий рядок містить %s." + +#: executor/execMain.c:1961 +#, c-format +msgid "null value in column \"%s\" of relation \"%s\" violates not-null constraint" +msgstr "null значення в стовпці \"%s\" відношення \"%s\" порушує not-null обмеження" + +#: executor/execMain.c:2010 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "новий рядок для відношення \"%s\" порушує перевірне обмеження перевірку \"%s\"" + +#: executor/execMain.c:2118 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "новий рядок порушує параметр перевірки для подання \"%s\"" + +#: executor/execMain.c:2128 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "новий рядок порушує політику захисту на рівні рядків \"%s\" для таблиці \"%s\"" + +#: executor/execMain.c:2133 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "новий рядок порушує політику захисту на рівні рядків для таблиці \"%s\"" + +#: executor/execMain.c:2140 +#, c-format +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "новий рядок порушує політику захисту на рівні рядків \"%s\" (вираз USING) для таблиці \"%s\"" + +#: executor/execMain.c:2145 +#, c-format +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "новий рядок порушує політику захисту на рівні рядків (вираз USING) для таблиці \"%s\"" + +#: executor/execPartition.c:341 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "для рядка не знайдено секції у відношенні \"%s\"" + +#: executor/execPartition.c:344 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "Ключ секціонування для невідповідного рядка містить %s." + +#: executor/execReplication.c:196 executor/execReplication.c:373 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "кортеж, що підлягає блокуванню, вже переміщено в іншу секцію в результаті паралельного оновлення, триває повторна спроба" + +#: executor/execReplication.c:200 executor/execReplication.c:377 +#, c-format +msgid "concurrent update, retrying" +msgstr "паралельне оновлення, триває повторна спроба" + +#: executor/execReplication.c:206 executor/execReplication.c:383 +#, c-format +msgid "concurrent delete, retrying" +msgstr "паралельне видалення, триває повторна спроба" + +#: executor/execReplication.c:269 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3626 utils/adt/arrayfuncs.c:4146 +#: utils/adt/arrayfuncs.c:6132 utils/adt/rowtypes.c:1182 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "не вдалося визначити оператора рівності для типу %s" + +#: executor/execReplication.c:586 +#, c-format +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "оновлення в таблиці \"%s\" неможливе, тому що в ній відсутній ідентифікатор репліки, і вона публікує оновлення" + +#: executor/execReplication.c:588 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Щоб ця таблиця підтримувала оновлення, встановіть REPLICA IDENTITY, використавши ALTER TABLE." + +#: executor/execReplication.c:592 +#, c-format +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "видалення з таблиці \"%s\" неможливе, тому що в ній відсутній ідентифікатор репліки, і вона публікує видалення" + +#: executor/execReplication.c:594 +#, c-format +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Щоб ця таблиця підтримувала видалення, встановіть REPLICA IDENTITY, використавши ALTER TABLE." + +#: executor/execReplication.c:613 executor/execReplication.c:621 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "використовувати відношення \"%s.%s\" як ціль логічної реплікації, не можна" + +#: executor/execReplication.c:615 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "\"%s.%s\" є зовнішньою таблицею." + +#: executor/execReplication.c:623 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "\"%s.%s\" не є таблицею." + +#: executor/execSRF.c:315 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "рядки, які повернула функція, не мають однаковий тип рядка" + +#: executor/execSRF.c:363 executor/execSRF.c:657 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "порушення протоколу табличної функції в режимі матеріалізації" + +#: executor/execSRF.c:370 executor/execSRF.c:675 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "нерозпізнаний режим повернення табличної функції: %d" + +#: executor/execSRF.c:884 +#, c-format +msgid "function returning setof record called in context that cannot accept type record" +msgstr "функція, що повертає набір записів, викликана в контексті, що не може прийняти тип запису" + +#: executor/execSRF.c:940 executor/execSRF.c:956 executor/execSRF.c:966 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "тип результату функції відрізняється від типу рядка-результату запиту" + +#: executor/execSRF.c:941 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "Повернений рядок містить %d атрибут, але запит очікував %d." +msgstr[1] "Повернений рядок містить %d атрибути, але запит очікував %d." +msgstr[2] "Повернений рядок містить %d атрибутів, але запит очікував %d." +msgstr[3] "Повернений рядок містить %d атрибутів, але запит очікував %d." + +#: executor/execSRF.c:957 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "Повернений тип %s у порядковій позиції %d, але запит очікував %s." + +#: executor/execUtils.c:750 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "матеріалізоване подання \"%s\" не було наповнене" + +#: executor/execUtils.c:752 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "Використайте команду REFRESH MATERIALIZED VIEW." + +#: executor/functions.c:231 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "не вдалося визначити фактичний тип аргументу, оголошеного як %s" + +#: executor/functions.c:528 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "у функції SQL не можна виконати COPY to/from client" + +#. translator: %s is a SQL statement name +#: executor/functions.c:534 +#, c-format +msgid "%s is not allowed in a SQL function" +msgstr "функція SQL не дозволяє використання %s" + +#. translator: %s is a SQL statement name +#: executor/functions.c:542 executor/spi.c:1471 executor/spi.c:2257 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "незмінна функція не дозволяє використання %s" + +#: executor/functions.c:1430 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "SQL функція \"%s\" оператор %d" + +#: executor/functions.c:1456 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "SQL функція \"%s\" під час запуску" + +#: executor/functions.c:1549 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "виклик процедур з вихідними аргументами в функціях SQL не підтримується" + +#: executor/functions.c:1671 executor/functions.c:1708 +#: executor/functions.c:1722 executor/functions.c:1812 +#: executor/functions.c:1845 executor/functions.c:1859 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "невідповідність типу повернення в функції, оголошеній як %s" + +#: executor/functions.c:1673 +#, c-format +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "Останнім оператором у функції повинен бути SELECT або INSERT/UPDATE/DELETE RETURNING." + +#: executor/functions.c:1710 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "Останній оператор повинен вертати один стовпець." + +#: executor/functions.c:1724 +#, c-format +msgid "Actual return type is %s." +msgstr "Фактичний тип повернення: %s." + +#: executor/functions.c:1814 +#, c-format +msgid "Final statement returns too many columns." +msgstr "Останній оператор вертає дуже багато стовпців." + +#: executor/functions.c:1847 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "Останній оператор поветрає %s замість %s для стовпця %d." + +#: executor/functions.c:1861 +#, c-format +msgid "Final statement returns too few columns." +msgstr "Останній оператор вертає дуже мало стовпців." + +#: executor/functions.c:1889 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "для SQL функцій тип повернення %s не підтримується" + +#: executor/nodeAgg.c:3075 executor/nodeAgg.c:3084 executor/nodeAgg.c:3096 +#, c-format +msgid "unexpected EOF for tape %d: requested %zu bytes, read %zu bytes" +msgstr "неочікуваний обрив для стрічки %d: запитано %zu байт, прочитано %zu байт" + +#: executor/nodeAgg.c:4026 parser/parse_agg.c:655 parser/parse_agg.c:685 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "виклики агрегатних функцій не можуть бути вкладеними" + +#: executor/nodeAgg.c:4234 executor/nodeWindowAgg.c:2836 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "агрегатна функція %u повинна мати сумісні тип введення і тип переходу" + +#: executor/nodeCustom.c:145 executor/nodeCustom.c:156 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "налаштовуване сканування \"%s\" не підтримує MarkPos" + +#: executor/nodeHashjoin.c:1046 executor/nodeHashjoin.c:1076 +#, c-format +msgid "could not rewind hash-join temporary file" +msgstr "не вдалося перемотати назад тимчасовий файл хеш-з'єднання" + +#: executor/nodeHashjoin.c:1272 executor/nodeHashjoin.c:1283 +#, c-format +msgid "could not read from hash-join temporary file: read only %zu of %zu bytes" +msgstr "не вдалося прочитати тимчасовий файл хеш-з'єднання: прочитано лише %zu з %zu байт" + +#: executor/nodeIndexonlyscan.c:242 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "функції неточної (lossy) дистанції не підтримуються в скануваннях лише по індексу" + +#: executor/nodeLimit.c:374 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET повинен бути не негативним" + +#: executor/nodeLimit.c:400 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT повинен бути не негативним" + +#: executor/nodeMergejoin.c:1570 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "RIGHT JOIN підтримується лише з умовами, які допускають з'єднання злиттям" + +#: executor/nodeMergejoin.c:1588 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "FULL JOIN підтримується лише з умовами, які допускають з'єднання злиттям" + +#: executor/nodeModifyTable.c:110 +#, c-format +msgid "Query has too many columns." +msgstr "Запит повертає дуже багато стовпців." + +#: executor/nodeModifyTable.c:138 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "Запит надає значення для видаленого стовпця з порядковим номером %d." + +#: executor/nodeModifyTable.c:146 +#, c-format +msgid "Query has too few columns." +msgstr "Запит повертає дуже мало стовпців." + +#: executor/nodeModifyTable.c:839 executor/nodeModifyTable.c:913 +#, c-format +msgid "tuple to be deleted was already modified by an operation triggered by the current command" +msgstr "кортеж, який підлягає видаленню, вже змінений в операції, яка викликана поточною командою." + +#: executor/nodeModifyTable.c:1220 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "неприпустима специфікація ON UPDATE" + +#: executor/nodeModifyTable.c:1221 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "Результуючий кортеж з'явиться в іншій секції в порівнянні з оригінальним кортежем." + +#: executor/nodeModifyTable.c:1592 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "Команда ON CONFLICT DO UPDATE не може змінювати рядок вдруге" + +#: executor/nodeModifyTable.c:1593 +#, c-format +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." +msgstr "Переконайтеся, що немає рядків для вставки з тією ж командою з дуплікованими обмежувальними значеннями." + +#: executor/nodeSamplescan.c:259 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "Параметр TABLESAMPLE не може бути null" + +#: executor/nodeSamplescan.c:271 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "Параметр TABLESAMPLE REPEATABLE не може бути null" + +#: executor/nodeSubplan.c:346 executor/nodeSubplan.c:385 +#: executor/nodeSubplan.c:1151 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "підзапит, використаний в якості вираження, повернув більше ніж один рядок" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "простір імен URI не повинен бути null" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "вираз фільтру рядків не повинен бути null" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "вираз фільтру стовпців не повинен бути null" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "Фільтр для стовпця \"%s\" є null." + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "у стовпці \"%s\" не допускається null" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "функція переходу рухомого агрегату не повинна вертати Null-значення" + +#: executor/nodeWindowAgg.c:2058 +#, c-format +msgid "frame starting offset must not be null" +msgstr "зсув початку рамки не повинен бути null" + +#: executor/nodeWindowAgg.c:2071 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "зсув початку рамки не повинен бути негативним" + +#: executor/nodeWindowAgg.c:2083 +#, c-format +msgid "frame ending offset must not be null" +msgstr "зсув кінця рамки не повинен бути null" + +#: executor/nodeWindowAgg.c:2096 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "зсув кінця рамки не повинен бути негативним" + +#: executor/nodeWindowAgg.c:2752 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "агрегатна функція %s не підтримує використання в якості віконної функції" + +#: executor/spi.c:228 executor/spi.c:297 +#, c-format +msgid "invalid transaction termination" +msgstr "неприпустиме завершення транзакції" + +#: executor/spi.c:242 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "неможливо затвердити, коли підтранзакції активні" + +#: executor/spi.c:303 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "неможливо відкотити, коли підтранзакції активні" + +#: executor/spi.c:372 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "транзакція залишила непорожню групу SPI" + +#: executor/spi.c:373 executor/spi.c:435 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "Перевірте наявність виклику \"SPI_finish\"." + +#: executor/spi.c:434 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "підтранзакція залишила непорожню групу SPI" + +#: executor/spi.c:1335 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "неможливо відкрити план декількох запитів як курсор" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1340 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "неможливо відкрити запит %s як курсор" + +#: executor/spi.c:1445 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE не підтримується" + +#: executor/spi.c:1446 parser/analyze.c:2508 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "Курсори з прокручуванням повинні бути READ ONLY." + +#: executor/spi.c:2560 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "SQL-оператор \"%s\"" + +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "не вдалося передати кортеж у чергу в спільну пам'ять" + +#: foreign/foreign.c:220 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "зіставлення користувача \"%s\" не знайдено" + +#: foreign/foreign.c:672 +#, c-format +msgid "invalid option \"%s\"" +msgstr "недійсний параметр \"%s\"" + +#: foreign/foreign.c:673 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "У цьому контексті припустимі параметри: %s" + +#: jit/jit.c:205 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:417 +#: utils/fmgr/dfmgr.c:465 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "немає доступу до файлу \"%s\": %m" + +#: jit/llvm/llvmjit.c:595 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "час впровадження: %.3fs, оптимізації: %.3fs, видачі: %.3fs" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Не вдалося виконати запит DSA розміру %zu." + +#: libpq/auth-scram.c:248 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "клієнт обрав неприпустимий механізм автентифікації SASL" + +#: libpq/auth-scram.c:269 libpq/auth-scram.c:509 libpq/auth-scram.c:520 +#, c-format +msgid "invalid SCRAM secret for user \"%s\"" +msgstr "неприпустимий секрет SCRAM для користувача \"%s\"" + +#: libpq/auth-scram.c:280 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM secret." +msgstr "Користувач \"%s\" не має припустимого секрету SCRAM." + +#: libpq/auth-scram.c:358 libpq/auth-scram.c:363 libpq/auth-scram.c:693 +#: libpq/auth-scram.c:701 libpq/auth-scram.c:806 libpq/auth-scram.c:819 +#: libpq/auth-scram.c:829 libpq/auth-scram.c:937 libpq/auth-scram.c:944 +#: libpq/auth-scram.c:959 libpq/auth-scram.c:974 libpq/auth-scram.c:988 +#: libpq/auth-scram.c:1006 libpq/auth-scram.c:1021 libpq/auth-scram.c:1321 +#: libpq/auth-scram.c:1329 +#, c-format +msgid "malformed SCRAM message" +msgstr "неправильне повідомлення SCRAM" + +#: libpq/auth-scram.c:359 +#, c-format +msgid "The message is empty." +msgstr "Повідомлення порожнє." + +#: libpq/auth-scram.c:364 +#, c-format +msgid "Message length does not match input length." +msgstr "Довжина повідомлення не відповідає довжині вводу." + +#: libpq/auth-scram.c:396 +#, c-format +msgid "invalid SCRAM response" +msgstr "неприпустима відповідь SCRAM" + +#: libpq/auth-scram.c:397 +#, c-format +msgid "Nonce does not match." +msgstr "Одноразовий ідентифікатор не збігається." + +#: libpq/auth-scram.c:471 +#, c-format +msgid "could not generate random salt" +msgstr "не вдалося згенерувати випадкову сіль" + +#: libpq/auth-scram.c:694 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Очікувався атрибут \"%c\", але знайдено \"%s\"." + +#: libpq/auth-scram.c:702 libpq/auth-scram.c:830 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Очікувався символ \"=\" для атрибуту \"%c\"." + +#: libpq/auth-scram.c:807 +#, c-format +msgid "Attribute expected, but found end of string." +msgstr "Очікувався атрибут, але знайдено кінець рядка." + +#: libpq/auth-scram.c:820 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Очікувався атрибут, але знайдено неприпустимий символ \"%s\"." + +#: libpq/auth-scram.c:938 libpq/auth-scram.c:960 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "Клієнт обрав алгоритм SCRAM-SHA-256-PLUS, але повідомлення SCRAM не містить даних зв’язування каналів." + +#: libpq/auth-scram.c:945 libpq/auth-scram.c:975 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Очікувалась кома, але знайдено символ \"%s\"." + +#: libpq/auth-scram.c:966 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "Помилка узгодження зв’язування каналів SCRAM" + +#: libpq/auth-scram.c:967 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "Клієнт підтримує зв’язування каналів SCRAM, але думає, що сервер не підтримує. Однак, сервер теж підтримує зв’язування каналів." + +#: libpq/auth-scram.c:989 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "Клієнт обрав алгоритм SCRAM-SHA-256 без зв’язування каналів, але повідомлення SCRAM містить дані зв’язування каналів." + +#: libpq/auth-scram.c:1000 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "непідтримуваний тип зв'язування каналів SCRAM \"%s\"" + +#: libpq/auth-scram.c:1007 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Неочікувана позначка зв'язування каналів \"%s\"." + +#: libpq/auth-scram.c:1017 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "клієнт використовує ідентифікатор для авторизації, але це не підтримується" + +#: libpq/auth-scram.c:1022 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Неочікуваний атрибут \"%s\" у першому повідомленні клієнта." + +#: libpq/auth-scram.c:1038 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "клієнт потребує непідтримуване розширення SCRAM" + +#: libpq/auth-scram.c:1052 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "недруковані символи в одноразовому ідентифікаторі SCRAM" + +#: libpq/auth-scram.c:1169 +#, c-format +msgid "could not generate random nonce" +msgstr "не вдалося згенерувати випадковий одноразовий ідентифікатор" + +#: libpq/auth-scram.c:1179 +#, c-format +msgid "could not encode random nonce" +msgstr "не вдалося кодувати випадковий одноразовий ідентифікатор" + +#: libpq/auth-scram.c:1285 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "Помилка перевірки зв'язування каналів SCRAM" + +#: libpq/auth-scram.c:1303 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "неочікуваний атрибут зв'язування каналів SCRAM в останньому повідомленні клієнта" + +#: libpq/auth-scram.c:1322 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "Неправильне підтвердження в останньому повідомленні клієнта." + +#: libpq/auth-scram.c:1330 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Сміття знайдено в кінці останнього повідомлення клієнта." + +#: libpq/auth.c:280 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "користувач \"%s\" не пройшов автентифікацію: відхилений хост" + +#: libpq/auth.c:283 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "користувач \"%s\" не пройшов автентифікацію \"trust\"" + +#: libpq/auth.c:286 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію Ident" + +#: libpq/auth.c:289 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію Peer" + +#: libpq/auth.c:294 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "користувач \"%s\" не пройшов автентифікацію за допомогою пароля" + +#: libpq/auth.c:299 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію GSSAPI" + +#: libpq/auth.c:302 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію SSPI" + +#: libpq/auth.c:305 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію PAM" + +#: libpq/auth.c:308 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію BSD" + +#: libpq/auth.c:311 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію LDAP" + +#: libpq/auth.c:314 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "користувач \"%s\" не пройшов автентифікацію за сертифікатом" + +#: libpq/auth.c:317 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "Користувач \"%s\" не пройшов автентифікацію RADIUS" + +#: libpq/auth.c:320 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "користувач \"%s\" не пройшов автентифікацію: неприпустимий метод автентифікації" + +#: libpq/auth.c:324 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "З'єднання відповідає рядку %d в pg_hba.conf: \"%s\"" + +#: libpq/auth.c:371 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "сертифікати клієнтів можуть перевірятися, лише якщо доступне сховище кореневих сертифікатів" + +#: libpq/auth.c:382 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "підключення потребує припустимий сертифікат клієнта" + +#: libpq/auth.c:392 +#, c-format +msgid "GSSAPI encryption can only be used with gss, trust, or reject authentication methods" +msgstr "Шифрування GSSAPI можна використовувати лише з методами gss, trust, або відхилення автентифікації" + +#: libpq/auth.c:426 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "pg_hba.conf відхиляє підключення реплікації для хосту \"%s\", користувача \"%s\", %s" + +#: libpq/auth.c:428 libpq/auth.c:444 libpq/auth.c:502 libpq/auth.c:520 +msgid "SSL off" +msgstr "SSL вимк" + +#: libpq/auth.c:428 libpq/auth.c:444 libpq/auth.c:502 libpq/auth.c:520 +msgid "SSL on" +msgstr "SSL увімк" + +#: libpq/auth.c:432 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +msgstr "pg_hba.conf відхиляє підключення реплікації для хосту \"%s\", користувача \"%s\"" + +#: libpq/auth.c:441 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf відхиляє підключення для хосту \"%s\", користувача \"%s\", бази даних \"%s\", %s" + +#: libpq/auth.c:448 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +msgstr "pg_hba.conf відхиляє підключення для хосту \"%s\", користувача \"%s\", бази даних \"%s\"" + +#: libpq/auth.c:477 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "IP-адреса клієнта дозволяється в \"%s\", відповідає прямому перетворенню." + +#: libpq/auth.c:480 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "IP-адреса клієнта дозволяється в \"%s\", пряме перетворення не перевірялося." + +#: libpq/auth.c:483 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "IP-адреса клієнта дозволяється в \"%s\", не відповідає прямому перетворенню." + +#: libpq/auth.c:486 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "Перекласти ім'я клієнтського хосту \"%s\" в IP-адресу: %s, не вдалося." + +#: libpq/auth.c:491 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "Отримати ім'я хосту з IP-адреси клієнта: %s, не вдалося." + +#: libpq/auth.c:500 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "в pg_hba.conf немає запису, що дозволяє підключення для реплікації з хосту \"%s\", користувача \"%s\", %s" + +#: libpq/auth.c:507 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +msgstr "в pg_hba.conf немає запису, що дозволяє підключення для реплікації з хосту \"%s\", користувача \"%s\"" + +#: libpq/auth.c:517 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "в pg_hba.conf немає запису для хосту \"%s\", користувача \"%s\", бази даних \"%s\", %s" + +#: libpq/auth.c:525 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +msgstr "в pg_hba.conf немає запису для хосту \"%s\", користувача \"%s\", бази даних \"%s\"" + +#: libpq/auth.c:688 +#, c-format +msgid "expected password response, got message type %d" +msgstr "очікувалася відповід з паролем, але отримано тип повідомлення %d" + +#: libpq/auth.c:716 +#, c-format +msgid "invalid password packet size" +msgstr "неприпустимий розмір пакету з паролем" + +#: libpq/auth.c:734 +#, c-format +msgid "empty password returned by client" +msgstr "клієнт повернув пустий пароль" + +#: libpq/auth.c:854 libpq/hba.c:1340 +#, c-format +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "Автентифікація MD5 не підтримується, коли увімкнуто режим \"db_user_namespace\"" + +#: libpq/auth.c:860 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "не вдалося створити випадкову сіль для MD5" + +#: libpq/auth.c:906 +#, c-format +msgid "SASL authentication is not supported in protocol version 2" +msgstr "Автентифікація SASL не підтримується в протоколі версії 2" + +#: libpq/auth.c:939 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "очікувалася відповідь SASL, але отримано тип повідомлення %d" + +#: libpq/auth.c:1068 +#, c-format +msgid "GSSAPI is not supported in protocol version 2" +msgstr "GSSAPI не підтримується в протоколі версії 2" + +#: libpq/auth.c:1128 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "очікувалася відповідь GSS, але отримано тип повідомлення %d" + +#: libpq/auth.c:1189 +msgid "accepting GSS security context failed" +msgstr "прийняти контекст безпеки GSS не вдалось" + +#: libpq/auth.c:1228 +msgid "retrieving GSS user name failed" +msgstr "отримання ім'я користувача GSS не виконано" + +#: libpq/auth.c:1359 +#, c-format +msgid "SSPI is not supported in protocol version 2" +msgstr "SSPI не підтримується в протоколі версії 2" + +#: libpq/auth.c:1374 +msgid "could not acquire SSPI credentials" +msgstr "не вдалось отримати облікові дані SSPI" + +#: libpq/auth.c:1399 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "очікувалась відповідь SSPI, але отримано тип повідомлення %d" + +#: libpq/auth.c:1477 +msgid "could not accept SSPI security context" +msgstr "прийняти контекст безпеки SSPI не вдалося" + +#: libpq/auth.c:1539 +msgid "could not get token from SSPI security context" +msgstr "не вдалося отримати маркер з контексту безпеки SSPI" + +#: libpq/auth.c:1658 libpq/auth.c:1677 +#, c-format +msgid "could not translate name" +msgstr "не вдалося перекласти ім'я" + +#: libpq/auth.c:1690 +#, c-format +msgid "realm name too long" +msgstr "ім'я області дуже довге" + +#: libpq/auth.c:1705 +#, c-format +msgid "translated account name too long" +msgstr "ім'я перекладеного облікового запису дуже довге" + +#: libpq/auth.c:1886 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "не вдалося створити сокет для підключення до серверу Ident: %m" + +#: libpq/auth.c:1901 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "не вдалося прив'язатися до локальної адреси \"%s\": %m" + +#: libpq/auth.c:1913 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "не вдалося підключитися до Ident-серверу за адресою \"%s\", порт %s: %m" + +#: libpq/auth.c:1935 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "не вдалося надіслати запит до Ident -серверу за адресою \"%s\", порт %s: %m" + +#: libpq/auth.c:1952 +#, c-format +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "не вдалося отримати відповідь від Ident-серверу за адресою \"%s\", порт %s: %m" + +#: libpq/auth.c:1962 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "неприпустимо форматована відповідь від Ident-серверу: \"%s\"" + +#: libpq/auth.c:2009 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "автентифікація peer не підтримується на цій платформі" + +#: libpq/auth.c:2013 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "не вдалося отримати облікові дані користувача через peer: %m" + +#: libpq/auth.c:2025 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "не вдалося знайти локального користувача за ідентифікатором (%ld): %s" + +#: libpq/auth.c:2124 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "помилка у нижчому шарі PAM: %s" + +#: libpq/auth.c:2194 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "не вдалося створити автентифікатор PAM: %s" + +#: libpq/auth.c:2205 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "помилка в pam_set_item(PAM_USER): %s" + +#: libpq/auth.c:2237 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "помилка в pam_set_item(PAM_RHOST): %s" + +#: libpq/auth.c:2249 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "помилка в pam_set_item(PAM_CONV): %s" + +#: libpq/auth.c:2262 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "помилка в pam_authenticate: %sв" + +#: libpq/auth.c:2275 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "помилка в pam_acct_mgmt: %s" + +#: libpq/auth.c:2286 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "не вдалося вивільнити автентифікатор PAM: %s" + +#: libpq/auth.c:2362 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "не вдалося ініціалізувати протокол LDAP: код помилки %d" + +#: libpq/auth.c:2399 +#, c-format +msgid "could not extract domain name from ldapbasedn" +msgstr "не вдалося отримати назву домена з ldapbasedn" + +#: libpq/auth.c:2407 +#, c-format +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "Автентифікація LDAP не змогла знайти записи DNS SRV для \"%s\"" + +#: libpq/auth.c:2409 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "Встановіть назву сервера LDAP, явно." + +#: libpq/auth.c:2461 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "не вдалося ініціалізувати протокол LDAP: %s" + +#: libpq/auth.c:2471 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "протокол ldaps з поточною бібліотекою LDAP не підтримується" + +#: libpq/auth.c:2479 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "не вдалося ініціалізувати протокол LDAP: %m" + +#: libpq/auth.c:2489 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "не вдалося встановити версію протоколу LDAP: %s" + +#: libpq/auth.c:2529 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "не вдалося завантажити функцію _ldap_start_tls_sA in wldap32.dll" + +#: libpq/auth.c:2530 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "Протокол LDAP через протокол SSL не підтримується на цій платформі." + +#: libpq/auth.c:2546 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "не вдалося почати сеанс протоколу LDAP TLS: %s" + +#: libpq/auth.c:2617 +#, c-format +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "Сервер LDAP не вказаний, і не ldapbasedn" + +#: libpq/auth.c:2624 +#, c-format +msgid "LDAP server not specified" +msgstr "LDAP-сервер не вказаний" + +#: libpq/auth.c:2686 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "неприпустимий символ в імені користувача для автентифікації LDAP" + +#: libpq/auth.c:2703 +#, c-format +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "не вдалося виконати початкову прив'язку LDAP для ldapbinddn \"%s\" на сервері \"%s\": %s" + +#: libpq/auth.c:2732 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "не вдалося виконати LDAP-пошук за фільтром \"%s\" на сервері \"%s\": %s" + +#: libpq/auth.c:2746 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "LDAP-користувач \"%s\" не існує" + +#: libpq/auth.c:2747 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "LDAP-пошук за фільтром \"%s\" на сервері \"%s\" не повернув записів." + +#: libpq/auth.c:2751 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "LDAP-користувач \"%s\" не унікальний" + +#: libpq/auth.c:2752 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "LDAP-пошук за фільтром \"%s\" на сервері \"%s\" повернув %d запис." +msgstr[1] "LDAP-пошук за фільтром \"%s\" на сервері \"%s\" повернув %d записів." +msgstr[2] "LDAP-пошук за фільтром \"%s\" на сервері \"%s\" повернув %d записів." +msgstr[3] "LDAP-пошук за фільтром \"%s\" на сервері \"%s\" повернув %d записів." + +#: libpq/auth.c:2772 +#, c-format +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "не вдалося отримати dn для першого результату, що відповідає \"%s\" на сервері \"%s\": %s" + +#: libpq/auth.c:2793 +#, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "не вдалося відв'язатись після пошуку користувача \"%s\" на сервері \"%s\"" + +#: libpq/auth.c:2824 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "Помилка під час реєстрації в протоколі LDAP користувача \"%s\" на сервері \"%s\": %s" + +#: libpq/auth.c:2853 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "Діагностика LDAP: %s" + +#: libpq/auth.c:2880 +#, c-format +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "помилка автентифікації сертифіката для користувача \"%s\": сертифікат клієнта не містить імені користувача" + +#: libpq/auth.c:2897 +#, c-format +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch" +msgstr "помилка перевірки сертифікату (clientcert=verify-full) для користувача \"%s\": CN невідповідність" + +#: libpq/auth.c:2998 +#, c-format +msgid "RADIUS server not specified" +msgstr "RADIUS-сервер не вказаний" + +#: libpq/auth.c:3005 +#, c-format +msgid "RADIUS secret not specified" +msgstr "Секрет RADIUS не вказаний" + +#: libpq/auth.c:3019 +#, c-format +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "Автентифікація RADIUS не підтримує паролі довші ніж %d символів" + +#: libpq/auth.c:3124 libpq/hba.c:1954 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "не вдалося перетворити ім'я серверу RADIUS \"%s\" в адресу: %s" + +#: libpq/auth.c:3138 +#, c-format +msgid "could not generate random encryption vector" +msgstr "не вдалося створити випадковий вектор шифрування" + +#: libpq/auth.c:3172 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "не вдалося виконати MD5 шифрування паролю" + +#: libpq/auth.c:3198 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "не вдалося створити сокет RADIUS: %m" + +#: libpq/auth.c:3220 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "не вдалося прив'язатися до локального сокету RADIUS: %m" + +#: libpq/auth.c:3230 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "не вдалося відправити пакет RADIUS: %m" + +#: libpq/auth.c:3263 libpq/auth.c:3289 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "перевищено час очікування відповіді RADIUS від %s" + +#: libpq/auth.c:3282 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "не вдалося перевірити статус сокету RADIUS: %m" + +#: libpq/auth.c:3312 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "не вдалося прочитати відповідь RADIUS: %m" + +#: libpq/auth.c:3325 libpq/auth.c:3329 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "Відповідь RADIUS від %s була відправлена з неправильного порту: %d" + +#: libpq/auth.c:3338 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "Занадто коротка відповідь RADIUS від %s: %d" + +#: libpq/auth.c:3345 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "У відповіді RADIUS від %s покшоджена довжина: %d (фактична довжина %d)" + +#: libpq/auth.c:3353 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "Прийшла відповідь RADIUS від %s на інший запит: %d (очікувалася %d)" + +#: libpq/auth.c:3378 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "не вдалося виконати шифрування MD5 для отриманого пакету" + +#: libpq/auth.c:3387 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "Відповідь RADIUS від %s має неправильний підпис MD5" + +#: libpq/auth.c:3405 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "Відповідь RADIUS від %s має неприпустимий код (%d) для користувача \"%s\"" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:553 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "неприпустимий дескриптор великого об'єкту: %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "дескриптор великого об'єкту %d не був відкритий для читання" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:560 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "дескриптор великого об’єкту %d не був відкритий для запису" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "результат lo_lseek для дескриптора великого об'єкту %d поза діапазоном" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "результат lo_tell для дескриптору\\а великого об'єкту %d поза діапазоном" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "не вдалося відкрити файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "не вдалося прочитати файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:514 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "не вдалося створити файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:526 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "не вдалося написати файл сервера \"%s\": %m" + +#: libpq/be-fsstubs.c:760 +#, c-format +msgid "large object read request is too large" +msgstr "запит на читання великого об'єкту має завеликий розмір" + +#: libpq/be-fsstubs.c:802 utils/adt/genfile.c:265 utils/adt/genfile.c:304 +#: utils/adt/genfile.c:340 +#, c-format +msgid "requested length cannot be negative" +msgstr "запитувана довжина не може бути негативною" + +#: libpq/be-fsstubs.c:855 storage/large_object/inv_api.c:297 +#: storage/large_object/inv_api.c:309 storage/large_object/inv_api.c:513 +#: storage/large_object/inv_api.c:624 storage/large_object/inv_api.c:814 +#, c-format +msgid "permission denied for large object %u" +msgstr "немає дозволу для великого об'єкта %u" + +#: libpq/be-secure-common.c:93 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "не вдалося прочитати висновок команди \"%s\": %m" + +#: libpq/be-secure-common.c:113 +#, c-format +msgid "command \"%s\" failed" +msgstr "помилка команди \"%s\"" + +#: libpq/be-secure-common.c:141 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "не вдалося отримати доступ до файлу приватного ключа \"%s\": %m" + +#: libpq/be-secure-common.c:150 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "файл приватного ключа \"%s\" не є звичайним" + +#: libpq/be-secure-common.c:165 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "файл приватного ключа \"%s\" повинен належати користувачу бази даних або кореня" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "до файлу приватного ключа \"%s\" мають доступ група або всі" + +#: libpq/be-secure-common.c:190 +#, c-format +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "Файл повинен мати дозволи u=rw (0600) або менше, якщо він належить користувачу бази даних, або u=rw,g=r (0640) або менше, якщо він належить кореню." + +#: libpq/be-secure-gssapi.c:195 +msgid "GSSAPI wrap error" +msgstr "помилка при згортанні GSSAPI" + +#: libpq/be-secure-gssapi.c:199 +#, c-format +msgid "outgoing GSSAPI message would not use confidentiality" +msgstr "вихідне повідомлення GSSAPI не буде використовувати конфіденційність" + +#: libpq/be-secure-gssapi.c:203 libpq/be-secure-gssapi.c:574 +#, c-format +msgid "server tried to send oversize GSSAPI packet (%zu > %zu)" +msgstr "сервер намагався надіслати переповнений пакет GSSAPI (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:330 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %zu)" +msgstr "переповнений пакет GSSAPI, надісланий клієнтом (%zu > %zu)" + +#: libpq/be-secure-gssapi.c:364 +msgid "GSSAPI unwrap error" +msgstr "помилка при розгортанні GSSAPI" + +#: libpq/be-secure-gssapi.c:369 +#, c-format +msgid "incoming GSSAPI message did not use confidentiality" +msgstr "вхідне повідомлення GSSAPI не використовувало конфіденційність" + +#: libpq/be-secure-gssapi.c:525 +#, c-format +msgid "oversize GSSAPI packet sent by the client (%zu > %d)" +msgstr "переповнений пакет GSSAPI, надісланий клієнтом (%zu > %d)" + +#: libpq/be-secure-gssapi.c:547 +msgid "could not accept GSSAPI security context" +msgstr "не вдалося прийняти контекст безпеки GSSAPI" + +#: libpq/be-secure-gssapi.c:637 +msgid "GSSAPI size check error" +msgstr "помилка перевірки розміру GSSAPI" + +#: libpq/be-secure-openssl.c:112 +#, c-format +msgid "could not create SSL context: %s" +msgstr "не вдалося створити контекст SSL: %s" + +#: libpq/be-secure-openssl.c:138 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "не вдалося завантажити сертифікат серверу \"%s\": %s" + +#: libpq/be-secure-openssl.c:158 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "файл закритого ключа \"%s\" не можна перезавантажити, тому що це потребує парольну фразу" + +#: libpq/be-secure-openssl.c:163 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "не вдалося завантажити файл приватного ключа \"%s\": %s" + +#: libpq/be-secure-openssl.c:172 +#, c-format +msgid "check of private key failed: %s" +msgstr "помилка під час перевірки приватного ключа: %s" + +#: libpq/be-secure-openssl.c:184 libpq/be-secure-openssl.c:206 +#, c-format +msgid "\"%s\" setting \"%s\" not supported by this build" +msgstr "\"%s\" налаштування \"%s\" не підтримується цією збіркою" + +#: libpq/be-secure-openssl.c:194 +#, c-format +msgid "could not set minimum SSL protocol version" +msgstr "не вдалося встановити мінімальну версію протоколу SSL" + +#: libpq/be-secure-openssl.c:216 +#, c-format +msgid "could not set maximum SSL protocol version" +msgstr "не вдалося встановити максимальну версію протоколу SSL" + +#: libpq/be-secure-openssl.c:232 +#, c-format +msgid "could not set SSL protocol version range" +msgstr "не вдалося встановити діапазон версій протоколу SSL" + +#: libpq/be-secure-openssl.c:233 +#, c-format +msgid "\"%s\" cannot be higher than \"%s\"" +msgstr "\"%s\" не може бути більше, ніж \"%s\"" + +#: libpq/be-secure-openssl.c:257 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "не вдалося встановити список шифрів (немає дійсних шифрів)" + +#: libpq/be-secure-openssl.c:275 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "не вдалося завантажити файл кореневого сертифікату \"%s\": %s" + +#: libpq/be-secure-openssl.c:302 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "не вдалося завантажити файл зі списком відкликаних сертифікатів SSL \"%s\": %s" + +#: libpq/be-secure-openssl.c:378 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "не вдалося ініціалізувати SSL-підключення: контекст SSL не встановлений" + +#: libpq/be-secure-openssl.c:386 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "не вдалося ініціалізувати SSL-підключення: %s" + +#: libpq/be-secure-openssl.c:394 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "не вдалося встановити SSL-сокет: %s" + +#: libpq/be-secure-openssl.c:449 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "не вдалося прийняти SSL-підключення: %m" + +#: libpq/be-secure-openssl.c:453 libpq/be-secure-openssl.c:506 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "не вдалося прийняти SSL-підключення: виявлений EOF" + +#: libpq/be-secure-openssl.c:492 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "не вдалося отримати підключення SSL: %s" + +#: libpq/be-secure-openssl.c:495 +#, c-format +msgid "This may indicate that the client does not support any SSL protocol version between %s and %s." +msgstr "Це може вказувати, що клієнт не підтримує жодної версії протоколу SSL між %s і %s." + +#: libpq/be-secure-openssl.c:511 libpq/be-secure-openssl.c:642 +#: libpq/be-secure-openssl.c:706 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "нерозпізнаний код помилки: %d" + +#: libpq/be-secure-openssl.c:553 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "Спільне ім'я SSL-сертифікату містить нульовий байт" + +#: libpq/be-secure-openssl.c:631 libpq/be-secure-openssl.c:690 +#, c-format +msgid "SSL error: %s" +msgstr "Помилка SSL: %s" + +#: libpq/be-secure-openssl.c:871 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "не вдалося відкрити файл параметрів DH \"%s\": %m" + +#: libpq/be-secure-openssl.c:883 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "не вдалося завантажити файл параметрів DH: %s" + +#: libpq/be-secure-openssl.c:893 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "неприпустимі параметри DH: %s" + +#: libpq/be-secure-openssl.c:901 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "неприпустимі параметри DH: р - не штрих" + +#: libpq/be-secure-openssl.c:909 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "неприпустимі параметри DH: немає придатного генератора або безпечного штриха" + +#: libpq/be-secure-openssl.c:1065 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: не вдалося завантажити параметри DH" + +#: libpq/be-secure-openssl.c:1073 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: не вдалося встановити параметри DH: %s" + +#: libpq/be-secure-openssl.c:1100 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: нерозпізнане ім'я кривої: %s" + +#: libpq/be-secure-openssl.c:1109 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: не вдалося створити ключ" + +#: libpq/be-secure-openssl.c:1137 +msgid "no SSL error reported" +msgstr "немає повідомлення про помилку SSL" + +#: libpq/be-secure-openssl.c:1141 +#, c-format +msgid "SSL error code %lu" +msgstr "Код помилки SSL %lu" + +#: libpq/be-secure.c:122 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "SSL-підключення від \"%s\"" + +#: libpq/be-secure.c:207 libpq/be-secure.c:303 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "завершення підключення через неочікуване закриття головного процесу" + +#: libpq/crypt.c:49 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "Роль \"%s\" не існує." + +#: libpq/crypt.c:59 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "Користувач \"%s\" не має пароля." + +#: libpq/crypt.c:77 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "Користувач \"%s\" має прострочений пароль." + +#: libpq/crypt.c:179 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "Користувач \"%s\" має пароль, який не можна використовувати з автентифікацією MD5." + +#: libpq/crypt.c:203 libpq/crypt.c:244 libpq/crypt.c:268 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "Пароль не підходить для користувача \"%s\"." + +#: libpq/crypt.c:287 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "Пароль користувача \"%s\" представлений в нерозпізнаному форматі." + +#: libpq/hba.c:235 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "занадто довгий маркер у файлі автентифікації, пропускається: \"%s\"" + +#: libpq/hba.c:407 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "не вдалося відкрити додатковий файл автентифікації \"@%s\" as \"%s\": %m" + +#: libpq/hba.c:509 +#, c-format +msgid "authentication file line too long" +msgstr "занадто довгий рядок у файлі автентифікації" + +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1013 libpq/hba.c:1022 +#: libpq/hba.c:1035 libpq/hba.c:1056 libpq/hba.c:1069 libpq/hba.c:1089 +#: libpq/hba.c:1111 libpq/hba.c:1123 libpq/hba.c:1179 libpq/hba.c:1199 +#: libpq/hba.c:1213 libpq/hba.c:1232 libpq/hba.c:1243 libpq/hba.c:1258 +#: libpq/hba.c:1276 libpq/hba.c:1292 libpq/hba.c:1304 libpq/hba.c:1341 +#: libpq/hba.c:1382 libpq/hba.c:1395 libpq/hba.c:1417 libpq/hba.c:1430 +#: libpq/hba.c:1442 libpq/hba.c:1460 libpq/hba.c:1510 libpq/hba.c:1554 +#: libpq/hba.c:1565 libpq/hba.c:1581 libpq/hba.c:1598 libpq/hba.c:1608 +#: libpq/hba.c:1666 libpq/hba.c:1704 libpq/hba.c:1726 libpq/hba.c:1738 +#: libpq/hba.c:1825 libpq/hba.c:1843 libpq/hba.c:1937 libpq/hba.c:1956 +#: libpq/hba.c:1985 libpq/hba.c:1998 libpq/hba.c:2021 libpq/hba.c:2043 +#: libpq/hba.c:2057 tsearch/ts_locale.c:190 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "рядок %d файла конфігурації \"%s\"" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:865 +#, c-format +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "параметр автентифікації \"%s\" припустимий лише для способів автентифікації %s" + +#: libpq/hba.c:885 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "спосіб автентифікації \"%s\" потребує аргумент \"%s\" для встановлення" + +#: libpq/hba.c:913 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "відсутнє введення в файлі \"%s\" в кінці рядка %d" + +#: libpq/hba.c:924 +#, c-format +msgid "multiple values in ident field" +msgstr "кілька значень в полі ident" + +#: libpq/hba.c:973 +#, c-format +msgid "multiple values specified for connection type" +msgstr "кілька значень вказано для типу підключення" + +#: libpq/hba.c:974 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "Вкажіть в рядку єдиний тип підключення." + +#: libpq/hba.c:988 +#, c-format +msgid "local connections are not supported by this build" +msgstr "локальні підключення не підтримуються цією збіркою" + +#: libpq/hba.c:1011 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "запис hostssl не збігається, тому що протокол SSL вимкнутий" + +#: libpq/hba.c:1012 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "Встановіть ssl = on в postgresql.conf." + +#: libpq/hba.c:1020 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "запис hostssl не збігається, тому що SSL не підтримується цією збіркою" + +#: libpq/hba.c:1021 +#, c-format +msgid "Compile with --with-openssl to use SSL connections." +msgstr "Щоб використовувати SSL-підключення, скомпілюйте з --with-openssl." + +#: libpq/hba.c:1033 +#, c-format +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "запис hostgssenc не може збігатись, оскільки GSSAPI не підтримується цією збіркою" + +#: libpq/hba.c:1034 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "Скомпілюйте з --with-gssapi, щоб використовувати GSSAPI з'єднання." + +#: libpq/hba.c:1054 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "неприпустимий тип підключення \"%s\"" + +#: libpq/hba.c:1068 +#, c-format +msgid "end-of-line before database specification" +msgstr "кінець рядка перед визначенням бази даних" + +#: libpq/hba.c:1088 +#, c-format +msgid "end-of-line before role specification" +msgstr "кінець рядка перед визначенням ролі" + +#: libpq/hba.c:1110 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "кінець рядка перед визначенням IP-адрес" + +#: libpq/hba.c:1121 +#, c-format +msgid "multiple values specified for host address" +msgstr "для адреси хоста вказано кілька значень" + +#: libpq/hba.c:1122 +#, c-format +msgid "Specify one address range per line." +msgstr "Вкажіть один діапазон адреси в рядку." + +#: libpq/hba.c:1177 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "неприпустима IP адреса \"%s\": %s" + +#: libpq/hba.c:1197 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "визначити одночасно ім’я хоста і маску CIDR не можна: \"%s\"" + +#: libpq/hba.c:1211 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "неприпустима маска CIDR в адресі \"%s\"" + +#: libpq/hba.c:1230 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "кінець рядка перед визначенням маски мережі" + +#: libpq/hba.c:1231 +#, c-format +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "Вкажіть діапазон адрес в нотації CIDR або надайте окрему маску мережі." + +#: libpq/hba.c:1242 +#, c-format +msgid "multiple values specified for netmask" +msgstr "для маски мережі вказано декілька значень" + +#: libpq/hba.c:1256 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "неприпустима маска IP \"%s\": %s" + +#: libpq/hba.c:1275 +#, c-format +msgid "IP address and mask do not match" +msgstr "IP-адреса і маска не збігаються" + +#: libpq/hba.c:1291 +#, c-format +msgid "end-of-line before authentication method" +msgstr "кінець рядка перед способом автентифікації" + +#: libpq/hba.c:1302 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "для типу автентифікації вказано декілька значень" + +#: libpq/hba.c:1303 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "Вкажіть у рядку єдиний тип автентифікації." + +#: libpq/hba.c:1380 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "неприпустимий спосіб автентифікації \"%s\"" + +#: libpq/hba.c:1393 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "неприпустимий спосіб автентифікації \"%s\": не підтримується цією збіркою" + +#: libpq/hba.c:1416 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "автентифікація gssapi для локальних сокетів не підтримується" + +#: libpq/hba.c:1429 +#, c-format +msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +msgstr "Шифрування GSSAPI підтримує лише gss, trust, або відхилення автентифікації" + +#: libpq/hba.c:1441 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "автентифікація peer підтримується лише для локальних сокетів" + +#: libpq/hba.c:1459 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "автентифікація cert підтримується лише для підключень hostssl" + +#: libpq/hba.c:1509 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "параметр автентифікації вказаний не в форматі ім’я=значення: %s" + +#: libpq/hba.c:1553 +#, c-format +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "не можна використовувати ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter або ldapurl разом з ldapprefix" + +#: libpq/hba.c:1564 +#, c-format +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "спосіб автентифікації \"ldap\" потребує встановити аргумент \"ldapbasedn\", \"ldapprefix\" або \"ldapsuffix\"" + +#: libpq/hba.c:1580 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "не можна використовувати ldapsearchattribute разом з ldapsearchfilter" + +#: libpq/hba.c:1597 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "список серверів RADIUS не може бути порожнім" + +#: libpq/hba.c:1607 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "список секретів RADIUS не може бути порожнім" + +#: libpq/hba.c:1660 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "кількість %s (%d) повинна дорівнювати 1 або кількості %s (%d)" + +#: libpq/hba.c:1694 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi і cert" + +#: libpq/hba.c:1703 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert може бути налаштовано лише для рядків \"hostssl\"" + +#: libpq/hba.c:1725 +#, c-format +msgid "clientcert cannot be set to \"no-verify\" when using \"cert\" authentication" +msgstr "clientcert не може бути встановлений на \"no-verify\", коли використовується автентифікація \"cert\"" + +#: libpq/hba.c:1737 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "неприпустиме значення для clientcert: \"%s\"" + +#: libpq/hba.c:1771 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "не вдалося аналізувати URL-адресу LDAP \"%s\": %s" + +#: libpq/hba.c:1782 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "непідтримувана схема в URL-адресі LDAP: %s" + +#: libpq/hba.c:1806 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "URL-адреса LDAP не підтримується на цій платформі" + +#: libpq/hba.c:1824 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "недійсне значення ldapscheme: \"%s\"" + +#: libpq/hba.c:1842 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "недійсний номер порту LDAP: \"%s\"" + +#: libpq/hba.c:1888 libpq/hba.c:1895 +msgid "gssapi and sspi" +msgstr "gssapi і sspi" + +#: libpq/hba.c:1904 libpq/hba.c:1913 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1935 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "не вдалося проаналізувати список серверів RADIUS \"%s\"" + +#: libpq/hba.c:1983 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "не вдалося проаналізувати список портів RADIUS \"%s\"" + +#: libpq/hba.c:1997 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "недійсний номер порту RADIUS: \"%s\"" + +#: libpq/hba.c:2019 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "не вдалося проаналізувати список секретів RADIUS \"%s\"" + +#: libpq/hba.c:2041 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "не вдалося проаналізувати список ідентифікаторів RADIUS \"%s\"" + +#: libpq/hba.c:2055 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "нерозпізнане ім’я параметра автентифікації: \"%s\"" + +#: libpq/hba.c:2199 libpq/hba.c:2613 guc-file.l:631 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "не вдалося відкрити файл конфігурації \"%s\": %m" + +#: libpq/hba.c:2250 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "файл конфігурації \"%s\" не містить елементів" + +#: libpq/hba.c:2768 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "недійсний регулярний вираз \"%s\": %s" + +#: libpq/hba.c:2828 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "помилка при пошуку за регулярним виразом для \"%s\": %s" + +#: libpq/hba.c:2847 +#, c-format +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "регулярний вираз \"%s не містить підвиразів, необхідних для зворотного посилання в \"%s\"" + +#: libpq/hba.c:2943 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "вказане ім'я користувача (%s) і автентифіковане ім'я користувача (%s) не збігаються" + +#: libpq/hba.c:2963 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "немає відповідності у файлі зіставлень \"%s\" для користувача \"%s\" автентифікованого як \"%s\"" + +#: libpq/hba.c:2996 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "не вдалося відкрити файл usermap: \"%s\": %m" + +#: libpq/pqcomm.c:218 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "не вдалося перевести сокет у неблокуючий режим: %m" + +#: libpq/pqcomm.c:372 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "Довжина шляху Unix-сокета \"%s\" перевищує ліміт (максимум %d байт)" + +#: libpq/pqcomm.c:393 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "не вдалось перекласти ім'я хоста \"%s\", служби \"%s\" в адресу: %s" + +#: libpq/pqcomm.c:397 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "не вдалось перекласти службу \"%s\" в адресу: %s" + +#: libpq/pqcomm.c:424 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "не вдалось прив'язатись до всіх запитаних адрес: MAXLISTEN (%d) перевищено" + +#: libpq/pqcomm.c:433 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:437 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:442 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:447 +#, c-format +msgid "unrecognized address family %d" +msgstr "нерозпізнане сімейство адресів %d" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:473 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "не вдалось створити сокет %s для адреси \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:499 +#, c-format +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "помилка в setsockopt(SO_REUSEADDR) для адреси %s \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:516 +#, c-format +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "помилка в setsockopt(IPV6_V6ONLY) для адреси %s \"%s\": %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:536 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "не вдалось прив'язатись до адреси %s \"%s\": %m" + +#: libpq/pqcomm.c:539 +#, c-format +msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +msgstr "Можливо порт %d вже зайнятий іншим процесом postmaster? Якщо ні, видаліть файл сокету \"%s\" і спробуйте знову." + +#: libpq/pqcomm.c:542 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "Можливо порт %d вже зайнятий іншим процесом postmaster? Якщо ні, почекайте пару секунд і спробуйте знову." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:575 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "не вдалось прослухати на адресі %s \"%s\": %m" + +#: libpq/pqcomm.c:584 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "прослуховувати UNIX сокет \"%s\"" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:590 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "прослуховувати %s адресу \"%s\", порт %d" + +#: libpq/pqcomm.c:673 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "група \"%s\" не існує" + +#: libpq/pqcomm.c:683 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "не вдалось встановити групу для файла \"%s\": %m" + +#: libpq/pqcomm.c:694 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "не вдалось встановити дозволи для файла \"%s\": %m" + +#: libpq/pqcomm.c:724 +#, c-format +msgid "could not accept new connection: %m" +msgstr "не вдалось прийняти нове підключення: %m" + +#: libpq/pqcomm.c:914 +#, c-format +msgid "there is no client connection" +msgstr "немає клієнтського підключення" + +#: libpq/pqcomm.c:965 libpq/pqcomm.c:1061 +#, c-format +msgid "could not receive data from client: %m" +msgstr "не вдалось отримати дані від клієнта: %m" + +#: libpq/pqcomm.c:1206 tcop/postgres.c:4142 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "завершення підключення через втрату синхронізації протоколу" + +#: libpq/pqcomm.c:1272 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "неочікуваний EOF в слові довжини повідомлення" + +#: libpq/pqcomm.c:1283 +#, c-format +msgid "invalid message length" +msgstr "неприпустима довжина повідомлення" + +#: libpq/pqcomm.c:1305 libpq/pqcomm.c:1318 +#, c-format +msgid "incomplete message from client" +msgstr "неповне повідомлення від клієнта" + +#: libpq/pqcomm.c:1451 +#, c-format +msgid "could not send data to client: %m" +msgstr "не вдалось надіслати дані клієнту: %m" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "у повідомлення не залишилось даних" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1471 utils/adt/rowtypes.c:567 +#, c-format +msgid "insufficient data left in message" +msgstr "недостатьно даних залишилось в повідомленні" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "неприпустимий рядок в повідомленні" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "неприпустимий формат повідомлення" + +#: main/main.c:246 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: помилка WSAStartup: %d\n" + +#: main/main.c:310 +#, c-format +msgid "%s is the PostgreSQL server.\n\n" +msgstr "%s - сервер PostgreSQL.\n\n" + +#: main/main.c:311 +#, c-format +msgid "Usage:\n" +" %s [OPTION]...\n\n" +msgstr "Використання:\n" +" %s [OPTION]...\n\n" + +#: main/main.c:312 +#, c-format +msgid "Options:\n" +msgstr "Параметри:\n" + +#: main/main.c:313 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS число спільних буферів\n" + +#: main/main.c:314 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NAME=VALUE встановити параметр під час виконання\n" + +#: main/main.c:315 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NAME вивести значення параметру під час виконання і вийти\n" + +#: main/main.c:316 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 рівень налагодження\n" + +#: main/main.c:317 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D DATADIR каталог бази даних\n" + +#: main/main.c:318 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e використати європейський формат дат (DMY)\n" + +#: main/main.c:319 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F вимкнути fsync\n" + +#: main/main.c:320 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h HOSTNAME ім’я хоста або IP-адреса для прослуховування\n" + +#: main/main.c:321 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i активувати підключення TCP/IP\n" + +#: main/main.c:322 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k DIRECTORY розташування Unix-сокетів\n" + +#: main/main.c:324 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l активувати SSL-підключення\n" + +#: main/main.c:326 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-CONNECT максимальне число дозволених підключень\n" + +#: main/main.c:327 +#, c-format +msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr " -o OPTIONS передати \"ПАРАМЕТРИ\" для кожного серверного процесу (застаріле)\n" + +#: main/main.c:328 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT номер порту для прослуховування\n" + +#: main/main.c:329 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s відображувати статистику після кожного запиту\n" + +#: main/main.c:330 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM вказати обсяг пам'яті для сортування (в КБ)\n" + +#: main/main.c:331 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію і вийти\n" + +#: main/main.c:332 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NAME=VALUE встановити параметр під час виконання\n" + +#: main/main.c:333 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config описати параметри конфігурації і вийти\n" + +#: main/main.c:334 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати довідку і вийти\n" + +#: main/main.c:336 +#, c-format +msgid "\n" +"Developer options:\n" +msgstr "\n" +"Параметри для розробників:\n" + +#: main/main.c:337 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h заборонити використання деяких типів плану\n" + +#: main/main.c:338 +#, c-format +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr " -n не повторювати ініціалізацію спільної пам'яті після ненормального виходу\n" + +#: main/main.c:339 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O дозволити змінювати структуру системних таблиць\n" + +#: main/main.c:340 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P вимкнути системні індекси\n" + +#: main/main.c:341 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex показувати час після кожного запиту\n" + +#: main/main.c:342 +#, c-format +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr " -T надіслати SIGSTOP усім внутрішнім процесам, якщо один вимкнеться\n" + +#: main/main.c:343 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr " -W NUM очікувати NUM секунд, щоб дозволити підключення від налагоджувача\n" + +#: main/main.c:345 +#, c-format +msgid "\n" +"Options for single-user mode:\n" +msgstr "\n" +"Параметри для однокористувацького режиму:\n" + +#: main/main.c:346 +#, c-format +msgid " --single selects single-user mode (must be first argument)\n" +msgstr " --single установка однокористувацького режиму (цей аргумент повинен бути першим)\n" + +#: main/main.c:347 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAME ім’я бази даних (за замовчуванням - ім'я користувача)\n" + +#: main/main.c:348 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 змінити рівень налагодження\n" + +#: main/main.c:349 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E інструкція відлуння перед виконанням\n" + +#: main/main.c:350 +#, c-format +msgid " -j do not use newline as interactive query delimiter\n" +msgstr " -j не використовувати новий рядок як роздільник інтерактивних запитів\n" + +#: main/main.c:351 main/main.c:356 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r FILENAME надіслати stdout і stderr до вказаного файлу\n" + +#: main/main.c:353 +#, c-format +msgid "\n" +"Options for bootstrapping mode:\n" +msgstr "\n" +"Параметри для режиму початкового завантаження:\n" + +#: main/main.c:354 +#, c-format +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot установка режиму початкового завантаження (цей аргумент повинен бути першим)\n" + +#: main/main.c:355 +#, c-format +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr " DBNAME ім'я бази даних (обов'язковий аргумент у режимі початкового завантаження)\n" + +#: main/main.c:357 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM внутрішнє використання\n" + +#: main/main.c:359 +#, c-format +msgid "\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n\n" +"Report bugs to <%s>.\n" +msgstr "\n" +"Будь-ласка прочитайте інструкцію для повного списку параметрів конфігурації виконання і їх встановлення у командний рядок або в файл конфігурації.\n\n" +"Про помилки повідомляйте <%s>.\n" + +#: main/main.c:363 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: main/main.c:374 +#, c-format +msgid "\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "Запускати сервер PostgreSQL під іменем \"root\" не дозволено.\n" +"Для запобігання компрометації системи безпеки сервер повинен запускати непривілейований користувач. Дивіться документацію, щоб дізнатися більше про те, як правильно запустити сервер.\n" + +#: main/main.c:391 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: дійсний і ефективний ID користувача повинні збігатися\n" + +#: main/main.c:398 +#, c-format +msgid "Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "Запускати PostgreSQL під іменем користувача з правами адміністратора не дозволено.\n" +"Для запобігання можливої компрометації системи безпеки сервер повинен запускати непривілейований користувач. Дивіться документацію, щоб дізнатися більше про те, як правильно запустити сервер.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "розширений тип вузла \"%s\" вже існує" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "Методи розширеного вузла \"%s\" не зареєстровані" + +#: nodes/nodeFuncs.c:122 nodes/nodeFuncs.c:153 parser/parse_coerce.c:2208 +#: parser/parse_coerce.c:2317 parser/parse_coerce.c:2352 +#: parser/parse_expr.c:2207 parser/parse_func.c:701 parser/parse_oper.c:967 +#: utils/fmgr/funcapi.c:528 +#, c-format +msgid "could not find array type for data type %s" +msgstr "не вдалося знайти тип масиву для типу даних %s" + +#: nodes/params.c:359 +#, c-format +msgid "portal \"%s\" with parameters: %s" +msgstr "портал \"%s\" з параметрами: %s" + +#: nodes/params.c:362 +#, c-format +msgid "unnamed portal with parameters: %s" +msgstr "портал без імені з параметрами: %s" + +#: optimizer/path/joinrels.c:855 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN підтримується лише з умовами, які допускають з'єднання злиттям або хеш-з'єднанням" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1193 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s не можна застосовувати до нульової сторони зовнішнього з’єднання" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1922 parser/analyze.c:1639 parser/analyze.c:1855 +#: parser/analyze.c:2715 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s несумісно з UNION/INTERSECT/EXCEPT" + +#: optimizer/plan/planner.c:2509 optimizer/plan/planner.c:4162 +#, c-format +msgid "could not implement GROUP BY" +msgstr "не вдалося реалізувати GROUP BY" + +#: optimizer/plan/planner.c:2510 optimizer/plan/planner.c:4163 +#: optimizer/plan/planner.c:4890 optimizer/prep/prepunion.c:1045 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "Деякі типи даних підтримують лише хешування, в той час як інші підтримують тільки сортування." + +#: optimizer/plan/planner.c:4889 +#, c-format +msgid "could not implement DISTINCT" +msgstr "не вдалося реалізувати DISTINCT" + +#: optimizer/plan/planner.c:5737 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "не вдалося реалізувати PARTITION BY для вікна" + +#: optimizer/plan/planner.c:5738 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "Стовпці, що розділяють вікна, повинні мати типи даних з можливістю сортування." + +#: optimizer/plan/planner.c:5742 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "не вдалося реалізувати ORDER BY для вікна" + +#: optimizer/plan/planner.c:5743 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Стовпці, що впорядковують вікна, повинні мати типи даних з можливістю сортування." + +#: optimizer/plan/setrefs.c:451 +#, c-format +msgid "too many range table entries" +msgstr "дуже багато елементів RTE" + +#: optimizer/prep/prepunion.c:508 +#, c-format +msgid "could not implement recursive UNION" +msgstr "не вдалося реалізувати рекурсивний UNION" + +#: optimizer/prep/prepunion.c:509 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Усі стовпці повинні мати типи даних з можливістю хешування." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1044 +#, c-format +msgid "could not implement %s" +msgstr "не вдалося реалізувати %s" + +#: optimizer/util/clauses.c:4746 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "Впроваджена в код SQL-функція \"%s\"" + +#: optimizer/util/plancat.c:132 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "отримати доступ до тимчасових або нежурнальованих відношень під час відновлення не можна" + +#: optimizer/util/plancat.c:662 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "вказівки з посиланням на весь рядок для вибору унікального індексу не підтримуються" + +#: optimizer/util/plancat.c:679 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "з обмеженням в реченні ON CONFLICT не пов'язаний індекс" + +#: optimizer/util/plancat.c:729 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE не підтримується з обмеженнями-винятками" + +#: optimizer/util/plancat.c:834 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "немає унікального обмеження або обмеження-виключення відповідного специфікації ON CONFLICT" + +#: parser/analyze.c:705 parser/analyze.c:1401 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "Списки VALUES повинні мати однакову довжину" + +#: parser/analyze.c:904 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT містить більше виразів, ніж цільових стовпців" + +#: parser/analyze.c:922 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT містить більше цільових стовпців, ніж виразів" + +#: parser/analyze.c:926 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "Джерелом даних є вираз рядка, який містить стільки ж стовпців, скільки потребується для INSERT. Ви випадково використовували додаткові дужки?" + +#: parser/analyze.c:1210 parser/analyze.c:1612 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO не дозволяється тут" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1542 parser/analyze.c:2894 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s не можна застосовувати до VALUES" + +#: parser/analyze.c:1777 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "неприпустиме речення UNION/INTERSECT/EXCEPT ORDER BY" + +#: parser/analyze.c:1778 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "Дозволено використання тільки імен стовпців, але не виразів або функцій." + +#: parser/analyze.c:1779 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "Додайте вираз/функція до кожного SELECT, або перемістіть UNION у речення FROM." + +#: parser/analyze.c:1845 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO дозволяється додати лише до першого SELECT в UNION/INTERSECT/EXCEPT" + +#: parser/analyze.c:1917 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "Учасник інструкції UNION/INTERSECT/EXCEPT не може посилатись на інші відносини на тому ж рівні" + +#: parser/analyze.c:2004 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "кожен %s запит повинен мати однакову кількість стовпців" + +#: parser/analyze.c:2426 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "В RETURNING повинен бути мінімум один стовпець" + +#: parser/analyze.c:2467 +#, c-format +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "не можна вказати SCROLL і NO SCROLL одночасно" + +#: parser/analyze.c:2486 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR не повинен містити операторів, які змінюють дані в WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2494 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s не підтримується" + +#: parser/analyze.c:2497 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "Курсори, що зберігаються повинні бути READ ONLY." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2505 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s не підтримується" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2516 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %s не підтримується" + +#: parser/analyze.c:2519 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Нечутливі курсори повинні бути READ ONLY." + +#: parser/analyze.c:2585 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "в матеріалізованих поданнях не повинні використовуватись оператори, які змінюють дані в WITH" + +#: parser/analyze.c:2595 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "в матеріалізованих поданнях не повинні використовуватись тимчасові таблиці або подання" + +#: parser/analyze.c:2605 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "визначати матеріалізовані подання з зв'язаними параметрами не можна" + +#: parser/analyze.c:2617 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "матеріалізовані подання не можуть бути нежурнальованими" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2722 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s не дозволяється з реченням DISTINCT" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2729 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s не дозволяється з реченням GROUP BY" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2736 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s не дозволяється з реченням HAVING" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2743 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s не дозволяється з агрегатними функціями" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2750 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s не дозволяється з віконними функціями" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2757 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s не дозволяється з функціями, які повертають безлічі, в цільовому списку" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2836 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "для %s потрібно вказати некваліфіковані імена відносин" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2867 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s не можна застосовувати до з'єднання" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2876 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s не можна застосовувати до функції" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2885 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s не можна застосовувати до табличної функції" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2903 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s не можна застосовувати до запиту WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2912 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s не можна застосовувати до іменованого джерела кортежів" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2932 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "відношення \"%s\" в реченні %s не знайдено в реченні FROM" + +#: parser/parse_agg.c:220 parser/parse_oper.c:222 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "для типу %s не вдалося визначити оператора сортування" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "Агрегатним функціям з DISTINCT необхідно сортувати їх вхідні дані." + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING повинно містити меньше, ніж 32 аргумента" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "агрегатні функції не дозволяються в умовах JOIN" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "операції групування не дозволяються в умовах JOIN" + +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "агрегатні функції не можна застосовувати в реченні FROM їх рівня запиту" + +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "операції групування не можна застосовувати в реченні FROM їх рівня запиту" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "агрегатні функції не можна застосовувати у функціях у FROM" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "операції групування не можна застосовувати у функціях у FROM" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "агрегатні функції не можна застосовувати у виразах політики" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "операції групування не можна застосовувати у виразах політики" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "агрегатні функції не можна застосовувати у вікні RANGE " + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "операції групування не можна застосовувати у вікні RANGE" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "агрегатні функції не можна застосовувати у вікні ROWS" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "операції групування не можна застосовувати у вікні ROWS" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "агрегатні функції не можна застосовувати у вікні GROUPS" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "операції групування не можна застосовувати у вікні GROUPS" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "агрегатні функції не можна застосовувати в перевірці обмежень" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "операції групування не можна застосовувати в перевірці обмежень" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "агрегатні функції не можна застосовувати у виразах DEFAULT" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "операції групування не можна застосовувати у виразах DEFAULT" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "агрегатні функції не можна застосовувати у виразах індексів" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "операції групування не можна застосовувати у виразах індексів" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "агрегатні функції не можна застосовувати в предикатах індексів" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "операції групування не можна застосовувати в предикатах індексів" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "агрегатні функції не можна застосовувати у виразах перетворювання" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in transform expressions" +msgstr "операції групування не можна застосовувати у виразах перетворювання" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "агрегатні функції не можна застосовувати в параметрах EXECUTE" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "операції групування не можна застосовувати в параметрах EXECUTE" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "агрегатні функції не можна застосовувати в умовах для тригерів WHEN" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "операції групування не можна застосовувати в умовах для тригерів WHEN" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in partition bound" +msgstr "агрегатні функції не можна застосовувати в границі секції" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in partition bound" +msgstr "операції групування не можна застосовувати в границі секції" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "агрегатні функції не можна застосовувати у виразах ключа секціонування" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "операції групування не можна застосовувати у виразах ключа секціонування" + +#: parser/parse_agg.c:526 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "агрегатні функції не можна застосовувати у виразах генерації стовпців" + +#: parser/parse_agg.c:528 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "операції групування не можна застосовувати у виразах генерації стовпців" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "агрегатні функції не можна застосовувати в аргументах CALL" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "операції групування не можна застосовувати в аргументах CALL" + +#: parser/parse_agg.c:542 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "агрегатні функції не можна застосовувати в умовах COPY FROM WHERE" + +#: parser/parse_agg.c:544 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "операції групування не можна застосовувати в умовах COPY FROM WHERE" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:567 parser/parse_clause.c:1828 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "агрегатні функції не можна застосовувати в %s" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:570 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "операції групування не можна застосовувати в %s" + +#: parser/parse_agg.c:678 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "агрегат зовнішнього рівня не може містити змінну нижчого рівня у своїх аргументах" + +#: parser/parse_agg.c:757 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "виклики агрегатної функції не можуть містити викликів функції, що повертають множину" + +#: parser/parse_agg.c:758 parser/parse_expr.c:1845 parser/parse_expr.c:2332 +#: parser/parse_func.c:872 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Можливо перемістити функцію, що повертає множину, в елемент LATERAL FROM." + +#: parser/parse_agg.c:763 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "виклики агрегатних функцій не можуть містити виклики віконних функцій" + +#: parser/parse_agg.c:842 +msgid "window functions are not allowed in JOIN conditions" +msgstr "віконні функції не можна застосовувати в умовах JOIN" + +#: parser/parse_agg.c:849 +msgid "window functions are not allowed in functions in FROM" +msgstr "віконні функції не можна застосовувати у функціях в FROM" + +#: parser/parse_agg.c:855 +msgid "window functions are not allowed in policy expressions" +msgstr "віконні функції не можна застосовувати у виразах політики" + +#: parser/parse_agg.c:868 +msgid "window functions are not allowed in window definitions" +msgstr "віконні функції не можна застосовувати у визначенні вікна" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in check constraints" +msgstr "віконні функції не можна застосовувати в перевірках обмежень" + +#: parser/parse_agg.c:904 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "віконні функції не можна застосовувати у виразах DEFAULT" + +#: parser/parse_agg.c:907 +msgid "window functions are not allowed in index expressions" +msgstr "віконні функції не можна застосовувати у виразах індексів" + +#: parser/parse_agg.c:910 +msgid "window functions are not allowed in index predicates" +msgstr "віконні функції не можна застосовувати в предикатах індексів" + +#: parser/parse_agg.c:913 +msgid "window functions are not allowed in transform expressions" +msgstr "віконні функції не можна застосовувати у виразах перетворювання" + +#: parser/parse_agg.c:916 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "віконні функції не можна застосовувати в параметрах EXECUTE" + +#: parser/parse_agg.c:919 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "віконні функції не можна застосовувати в умовах WHEN для тригерів" + +#: parser/parse_agg.c:922 +msgid "window functions are not allowed in partition bound" +msgstr "віконні функції не можна застосовувати в границі секції" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "віконні функції не можна застосовувати у виразах ключа секціонування" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "віконні функції не можна застосовувати в аргументах CALL" + +#: parser/parse_agg.c:931 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "віконні функції не можна застосовувати в умовах COPY FROM WHERE" + +#: parser/parse_agg.c:934 +msgid "window functions are not allowed in column generation expressions" +msgstr "віконні функції не можна застосовувати у виразах генерації стовпців" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:954 parser/parse_clause.c:1837 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "віконні функції не можна застосовувати в %s" + +#: parser/parse_agg.c:988 parser/parse_clause.c:2671 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "вікно \"%s\" не існує" + +#: parser/parse_agg.c:1072 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "забагато наборів групування (максимум 4096)" + +#: parser/parse_agg.c:1212 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "агрегатні функції не дозволені у рекурсивному терміні рекурсивного запиту" + +#: parser/parse_agg.c:1405 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "стовпець \"%s.%s\" повинен з'являтися у реченні Група BY або використовуватися в агрегатній функції" + +#: parser/parse_agg.c:1408 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "Прямі аргументи сортувального агрегату можуть використовувати лише згруповані стовпці." + +#: parser/parse_agg.c:1413 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "вкладений запит використовує не згруповані стовпці \"%s.%s\" з зовнішнього запиту" + +#: parser/parse_agg.c:1577 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "аргументами групування мають бути вирази групування пов'язаного рівня запиту" + +#: parser/parse_clause.c:191 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "відношення \"%s\" не може бути метою модифікованої інструкції" + +#: parser/parse_clause.c:571 parser/parse_clause.c:599 parser/parse_func.c:2424 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "функції, що повертають множину, мають з'являтися на вищому рівні FROM" + +#: parser/parse_clause.c:611 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "кілька списків з визначенням стовпців не дозволені для тої самої функції" + +#: parser/parse_clause.c:644 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "ROWS FROM() з декількома функціями не можуть мати список з визначенням стовпців" + +#: parser/parse_clause.c:645 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "Укладіть окремі списки з визначенням стовпців для кожної з функцій всередині ROWS FROM()." + +#: parser/parse_clause.c:651 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "UNNEST() з кількома аргументами не можуть мати список з визначенням стовпців" + +#: parser/parse_clause.c:652 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "Використайте окремі виклики UNNEST() всередині ROWS FROM() і підключіть список з визначенням стовпців до кожного." + +#: parser/parse_clause.c:659 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY не можна використовувати з списком з визначенням стовпців" + +#: parser/parse_clause.c:660 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Помістіть список з визначенням стовпців всередину ROWS FROM()." + +#: parser/parse_clause.c:760 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "FOR ORDINALITY дозволяється лише для одного стовпця" + +#: parser/parse_clause.c:821 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "ім'я стовпця \"%s\" не є унікальним" + +#: parser/parse_clause.c:863 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "ім'я простору імен \"%s\" не є унікальним" + +#: parser/parse_clause.c:873 +#, c-format +msgid "only one default namespace is allowed" +msgstr "дозволено тільки один простір імен за замовчуванням" + +#: parser/parse_clause.c:933 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "метод %s для отримання вибірки не існує" + +#: parser/parse_clause.c:955 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "метод %s для отримання вибірки потребує аргумента: %d, отримано: %d" +msgstr[1] "метод %s для отримання вибірки потребує аргументів: %d, отримано: %d" +msgstr[2] "метод %s для отримання вибірки потребує аргументів: %d, отримано: %d" +msgstr[3] "метод %s для отримання вибірки потребує аргументів: %d, отримано: %d" + +#: parser/parse_clause.c:989 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "метод %s для отримання вибірки не підтримує REPEATABLE" + +#: parser/parse_clause.c:1135 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "Речення TABLESAMPLE можна застосовувати лише до таблиць або матеріалізованих подань" + +#: parser/parse_clause.c:1318 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "ім’я стовпця \"%s\" з'являється у реченні USING неодноразово" + +#: parser/parse_clause.c:1333 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "ім’я спільного стовпця \"%s\" з'являється у таблиці зліва неодноразово" + +#: parser/parse_clause.c:1342 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "в таблиці зліва не існує стовпець \"%s\", вказаний в реченні USING" + +#: parser/parse_clause.c:1357 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "ім’я спільного стовпця \"%s\" з'являється в таблиці справа неодноразово" + +#: parser/parse_clause.c:1366 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "в таблиці справа не існує стовпець \"%s\", вказаний в реченні USING" + +#: parser/parse_clause.c:1447 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "занадто багато елементів у списку псевдонімів стовпця \"%s\"" + +#: parser/parse_clause.c:1773 +#, c-format +msgid "row count cannot be null in FETCH FIRST ... WITH TIES clause" +msgstr "кількість рядків не може бути NULL в операторі FETCH FIRST ... WITH TIES" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1798 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "аргумент %s не може містити змінні" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1963 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "вираз %s \"%s\" неоднозначний" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1992 +#, c-format +msgid "non-integer constant in %s" +msgstr "нецілочисельна константа в %s" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2014 +#, c-format +msgid "%s position %d is not in select list" +msgstr "в списку вибірки %s немає позиції %d" + +#: parser/parse_clause.c:2453 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE має обмеження в 12 елементів" + +#: parser/parse_clause.c:2659 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "вікно \"%s\" вже визначено" + +#: parser/parse_clause.c:2720 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "змінити речення PARTITION BY для вікна \"%s\" не можна" + +#: parser/parse_clause.c:2732 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "змінити речення ORDER BY для вікна \"%s\" не можна" + +#: parser/parse_clause.c:2762 parser/parse_clause.c:2768 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "скопіювати вікно \"%s\", яке має речення рамки, не можна" + +#: parser/parse_clause.c:2770 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Пропустіть дужки в реченні OVER." + +#: parser/parse_clause.c:2790 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "Для RANGE з зсувом PRECEDING/FOLLOWING потребується лише один стовпець в ORDER BY" + +#: parser/parse_clause.c:2813 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "Для режиму GROUPS потребується речення ORDER BY" + +#: parser/parse_clause.c:2883 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "для агрегатної функції з DISTINCT, вирази ORDER BY повинні з'являтись у списку аргументів" + +#: parser/parse_clause.c:2884 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "для SELECT DISTINCT вирази ORDER BY повинні бути в списку вибірки" + +#: parser/parse_clause.c:2916 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "агрегатна функція з DISTINCT повинна мати мінімум один аргумент" + +#: parser/parse_clause.c:2917 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT повинен мати мінімум один стовпець" + +#: parser/parse_clause.c:2983 parser/parse_clause.c:3015 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "Вирази SELECT DISTINCT ON повинні відповідати початковим виразам ORDER BY" + +#: parser/parse_clause.c:3093 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC не дозволяється в реченні ON CONFLICT" + +#: parser/parse_clause.c:3099 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST не довзоляється в реченні ON CONFLICT" + +#: parser/parse_clause.c:3178 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE вимагає специфікації висновку або імені обмеження" + +#: parser/parse_clause.c:3179 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Наприклад, ON CONFLICT (ім'я_стовпця)." + +#: parser/parse_clause.c:3190 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT не підтримується таблицями системного каталогу" + +#: parser/parse_clause.c:3198 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT не підтримується в таблиці \"%s\", що використовується як таблиця каталогу" + +#: parser/parse_clause.c:3341 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "оператор %s не є дійсним оператором сортування" + +#: parser/parse_clause.c:3343 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "Оператори сортування повинні бути учасниками \"<\" або \">\" сімейств операторів btree." + +#: parser/parse_clause.c:3654 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE зі зсувом PRECEDING/FOLLOWING не підтримується для типу стовпця %s" + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE зі зсувом PRECEDING/FOLLOWING не підтримується для типу стовпця %s і типу зсуву %s" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Приведіть значення зсуву до потрібного типу." + +#: parser/parse_clause.c:3668 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE зі зсувом PRECEDING/FOLLOWING має декілька інтерпретацій для типу стовпця %s і типу зсуву %s" + +#: parser/parse_clause.c:3671 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Приведіть значення зсуву в точності до призначеного типу." + +#: parser/parse_coerce.c:1024 parser/parse_coerce.c:1062 +#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1095 +#: parser/parse_expr.c:2241 parser/parse_expr.c:2819 parser/parse_target.c:967 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "неможливо транслювати тип %s в %s" + +#: parser/parse_coerce.c:1065 +#, c-format +msgid "Input has too few columns." +msgstr "У вхідних даних дуже мало стовпців." + +#: parser/parse_coerce.c:1083 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "Неможливо транслювати тип %s в %s у стовпці %d." + +#: parser/parse_coerce.c:1098 +#, c-format +msgid "Input has too many columns." +msgstr "У вхідних даних дуже багато стовпців." + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1153 parser/parse_coerce.c:1201 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "аргумент конструкції %s повинен бути типу %s, не типу %s" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1164 parser/parse_coerce.c:1213 +#, c-format +msgid "argument of %s must not return a set" +msgstr "аргумент конструкції %s не повинен повертати набір" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1353 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "у конструкції %s типи %s і %s не можуть бути відповідними" + +#: parser/parse_coerce.c:1465 +#, c-format +msgid "argument types %s and %s cannot be matched" +msgstr "типи аргументів %s і %s не можуть збігатись" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1517 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "у конструкції %s не можна перетворити тип %s в %s" + +#: parser/parse_coerce.c:1934 +#, c-format +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "аргументи, оголошенні як \"anyelement\", повинні бути схожими" + +#: parser/parse_coerce.c:1954 +#, c-format +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "аргументи, оголошенні як \"anyarray\", повинні бути схожими" + +#: parser/parse_coerce.c:1974 +#, c-format +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "аргументи, оголошенні як \"anyrange\", повинні бути схожими" + +#: parser/parse_coerce.c:2008 parser/parse_coerce.c:2088 +#: utils/fmgr/funcapi.c:487 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "аргумент, оголошений як %s , є не масивом, а типом %s" + +#: parser/parse_coerce.c:2029 +#, c-format +msgid "arguments declared \"anycompatiblerange\" are not all alike" +msgstr "аргументи, оголошенні як \"anycompatiblerange\", повинні бути схожими" + +#: parser/parse_coerce.c:2041 parser/parse_coerce.c:2122 +#: utils/fmgr/funcapi.c:501 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "аргумент, оголошений як %s, є не діапазонним типом, а типом %s" + +#: parser/parse_coerce.c:2079 +#, c-format +msgid "cannot determine element type of \"anyarray\" argument" +msgstr "не можна визначити тип елемента аргументу \"anyarray\"" + +#: parser/parse_coerce.c:2105 parser/parse_coerce.c:2139 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "аргумент, оголошений як %s, не узгоджується з аргументом, оголошеним як %s" + +#: parser/parse_coerce.c:2163 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "не вдалося визначити поліморфний тип, тому що вхідні аргументи мають тип %s" + +#: parser/parse_coerce.c:2177 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "тип, відповідний \"anynonarray\", є масивом: %s" + +#: parser/parse_coerce.c:2187 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "тип, відповідний \"anyenum\", не є переліком: %s" + +#: parser/parse_coerce.c:2218 parser/parse_coerce.c:2267 +#: parser/parse_coerce.c:2329 parser/parse_coerce.c:2365 +#, c-format +msgid "could not determine polymorphic type %s because input has type %s" +msgstr "не вдалося визначити поліморфний тип %s тому що вхідні дані мають тип %s" + +#: parser/parse_coerce.c:2228 +#, c-format +msgid "anycompatiblerange type %s does not match anycompatible type %s" +msgstr "тип anycompatiblerange %s не збігається з типом anycompatible %s" + +#: parser/parse_coerce.c:2242 +#, c-format +msgid "type matched to anycompatiblenonarray is an array type: %s" +msgstr "тип відповідний до anycompatiblenonarray є масивом: %s" + +#: parser/parse_coerce.c:2433 +#, c-format +msgid "A result of type %s requires at least one input of type %s." +msgstr "Результат типу %s потребує ввести як мінімум один тип %s." + +#: parser/parse_coerce.c:2445 +#, c-format +msgid "A result of type %s requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange." +msgstr "Результат типу %s потребує ввести як мінімум один тип anyelement, anyarray, anynonarray, anyenum, або anyrange." + +#: parser/parse_coerce.c:2457 +#, c-format +msgid "A result of type %s requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange." +msgstr "Результат типу %s потребує ввести як мінімум один тип anycompatible, anycompatiblearray, anycompatiblenonarray, або anycompatiblerange." + +#: parser/parse_coerce.c:2487 +msgid "A result of type internal requires at least one input of type internal." +msgstr "Результат внутрішнього типу потребує ввести як мінімум один внутрішній тип." + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:981 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "невідповідність параметрів сортування між неявними параметрами сортування \"%s\" і \"%s\"" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:984 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "Ви можете обрати параметри сортування, застосувавши речення COLLATE до одного або обох виразів." + +#: parser/parse_collate.c:831 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "невідповідність параметрів сортування між явними параметрами сортування \"%s\" і \"%s\"" + +#: parser/parse_cte.c:42 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "рекурсивне посилання на запит \"%s\" не повинне з'являтись в його не рекурсивній частині" + +#: parser/parse_cte.c:44 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "рекурсивне посилання на запит \"%s\" не повинне з'являтись у підзапиті" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "рекурсивне посилання на запит \"%s\" не повинне з'являтись у зовнішньому з’єднанні" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "рекурсивне посилання на запит \"%s\" не повинне з'являтись в INTERSECT" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "рекурсивне посилання на запит \"%s\" не повинне з'являтись в EXCEPT" + +#: parser/parse_cte.c:132 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "Ім’я запиту WITH \"%s\" вказано неодноразово" + +#: parser/parse_cte.c:264 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "Речення WITH, яке містить оператор, що змінює дані, повинне бути на верхньому рівні" + +#: parser/parse_cte.c:313 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "у рекурсивному запиті \"%s\" стовпець %d має тип %s у нерекурсивній частині, але загалом тип %s" + +#: parser/parse_cte.c:319 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Приведіть результат нерекурсивної частини до правильного типу." + +#: parser/parse_cte.c:324 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "у рекурсивному запиті \"%s\" стовпець %d має параметри сортування \"%s\" у нерекурсивній частині, але загалом параметри сортування \"%s\"" + +#: parser/parse_cte.c:328 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "Використайте речення COLLATE, щоб встановити параметри сортування в нерекурсивній частині." + +#: parser/parse_cte.c:418 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "Запит WITH \"%s\" має %d доступних стовпців, але %d стовпців вказано" + +#: parser/parse_cte.c:598 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "взаємна рекурсія між елементами WITH не реалізована" + +#: parser/parse_cte.c:650 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "рекурсивний запит \"%s\" не повинен містити оператори, які змінюють дані" + +#: parser/parse_cte.c:658 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "рекурсивний запит \"%s\" не має форми (нерекурсивна частина) UNION [ALL] (рекурсивна частина)" + +#: parser/parse_cte.c:702 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "ORDER BY в рекурсивному запиті не реалізовано" + +#: parser/parse_cte.c:708 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "OFFSET у рекурсивному запиті не реалізовано" + +#: parser/parse_cte.c:714 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "LIMIT у рекурсивному запиті не реалізовано" + +#: parser/parse_cte.c:720 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "FOR UPDATE/SHARE в рекурсивному запиті не реалізовано" + +#: parser/parse_cte.c:777 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "рекурсивне посилання на запит \"%s\" не повинне з'являтись неодноразово" + +#: parser/parse_expr.c:349 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "DEFAULT не допускається в цьому контексті" + +#: parser/parse_expr.c:402 parser/parse_relation.c:3506 +#: parser/parse_relation.c:3526 +#, c-format +msgid "column %s.%s does not exist" +msgstr "стовпець %s.%s не існує" + +#: parser/parse_expr.c:414 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "стовпець \"%s\" не знайдено в типі даних %s" + +#: parser/parse_expr.c:420 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "не вдалося ідентифікувати стовпець \"%s\" в типі запису" + +#: parser/parse_expr.c:426 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "запис імені стовпця .%s застосований до типу %s, котрий не є складеним типом" + +#: parser/parse_expr.c:457 parser/parse_target.c:729 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "розширення рядка через \"*\" тут не підтримується" + +#: parser/parse_expr.c:578 +msgid "cannot use column reference in DEFAULT expression" +msgstr "у виразі DEFAULT не можна використовувати посилання на стовпець" + +#: parser/parse_expr.c:581 +msgid "cannot use column reference in partition bound expression" +msgstr "у виразі границі секції не можна використовувати посилання на стовпці" + +#: parser/parse_expr.c:850 parser/parse_relation.c:799 +#: parser/parse_relation.c:881 parser/parse_target.c:1207 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "посилання на стовпець \"%s\" є неоднозначним" + +#: parser/parse_expr.c:906 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:199 parser/parse_param.c:298 +#, c-format +msgid "there is no parameter $%d" +msgstr "параметр $%d не існує" + +#: parser/parse_expr.c:1149 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULLIF потребує = щоб оператор повертав логічне значення" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1155 parser/parse_expr.c:3135 +#, c-format +msgid "%s must not return a set" +msgstr "%s не повинна повертати набір" + +#: parser/parse_expr.c:1603 parser/parse_expr.c:1635 +#, c-format +msgid "number of columns does not match number of values" +msgstr "кількість стовпців не відповідає кількості значень" + +#: parser/parse_expr.c:1649 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "джерелом для елементу UPDATE з декількома стовпцями повинен бути вкладений SELECT або вираз ROW()" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1843 parser/parse_expr.c:2330 parser/parse_func.c:2540 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "функції, повертаючі набори, не дозволяються в %s" + +#: parser/parse_expr.c:1904 +msgid "cannot use subquery in check constraint" +msgstr "в обмеженні-перевірці не можна використовувати підзапити" + +#: parser/parse_expr.c:1908 +msgid "cannot use subquery in DEFAULT expression" +msgstr "у виразі DEFAULT не можна використовувати підзапити" + +#: parser/parse_expr.c:1911 +msgid "cannot use subquery in index expression" +msgstr "в індексному виразі не можна використовувати підзапити" + +#: parser/parse_expr.c:1914 +msgid "cannot use subquery in index predicate" +msgstr "в предикаті індексу не можна використовувати підзапити" + +#: parser/parse_expr.c:1917 +msgid "cannot use subquery in transform expression" +msgstr "у виразі перетворення не можна використовувати підзапити" + +#: parser/parse_expr.c:1920 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "в параметрі EXECUTE не можна використовувати підзапити" + +#: parser/parse_expr.c:1923 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "в умові WHEN для тригеру не можна використовувати підзапити" + +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in partition bound" +msgstr "в границі секції не можна використовувати підзапити" + +#: parser/parse_expr.c:1929 +msgid "cannot use subquery in partition key expression" +msgstr "у виразі ключа секціонування не можна використовувати підзапити" + +#: parser/parse_expr.c:1932 +msgid "cannot use subquery in CALL argument" +msgstr "в аргументі CALL не можна використовувати підзапити" + +#: parser/parse_expr.c:1935 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "не можна використовувати підзапити в умові COPY FROM WHERE" + +#: parser/parse_expr.c:1938 +msgid "cannot use subquery in column generation expression" +msgstr "у виразі генерації стовпців не можна використовувати підзапити" + +#: parser/parse_expr.c:1991 +#, c-format +msgid "subquery must return only one column" +msgstr "підзапит повинен повертати лише один стовпець" + +#: parser/parse_expr.c:2075 +#, c-format +msgid "subquery has too many columns" +msgstr "підзапит має занадто багато стовпців" + +#: parser/parse_expr.c:2080 +#, c-format +msgid "subquery has too few columns" +msgstr "підзапит має занадто мало стовпців" + +#: parser/parse_expr.c:2181 +#, c-format +msgid "cannot determine type of empty array" +msgstr "тип пустого масиву визначити не можна" + +#: parser/parse_expr.c:2182 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "Приведіть його до бажаного типу явним чином, наприклад ARRAY[]::integer[]." + +#: parser/parse_expr.c:2196 +#, c-format +msgid "could not find element type for data type %s" +msgstr "не вдалося знайти тип елементу для типу даних %s" + +#: parser/parse_expr.c:2481 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "замість значення XML-атрибуту без імені повинен вказуватись стовпець" + +#: parser/parse_expr.c:2482 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "замість значення XML-елементу без імені повинен вказуватись стовпець" + +#: parser/parse_expr.c:2497 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "Ім'я XML-атрибуту \"%s\" з'являється неодноразово" + +#: parser/parse_expr.c:2604 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "привести результат XMLSERIALIZE до %s не можна" + +#: parser/parse_expr.c:2892 parser/parse_expr.c:3088 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "неоднакова кількість елементів у виразах рядка" + +#: parser/parse_expr.c:2902 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "рядки нульової довжини порівнювати не можна" + +#: parser/parse_expr.c:2927 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "оператор порівняння рядків повинен видавати логічний тип, а не %s" + +#: parser/parse_expr.c:2934 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "оператор порівняння рядків повинен вертати набір" + +#: parser/parse_expr.c:2993 parser/parse_expr.c:3034 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "не вдалося визначити інтерпретацію оператора порівняння рядків %s" + +#: parser/parse_expr.c:2995 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "Оператори порівняння рядків повинні бути пов'язанні з сімейством операторів btree." + +#: parser/parse_expr.c:3036 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Існує декілька рівноцінних кандидатів." + +#: parser/parse_expr.c:3129 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROM, потребує = щоб оператор повертав логічне значення" + +#: parser/parse_expr.c:3448 parser/parse_expr.c:3466 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "пріоритет оператора змінен: %s тепер має меньший пріоритет, ніж %s" + +#: parser/parse_func.c:191 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "ім’я аргументу \"%s\" використовується неодноразово" + +#: parser/parse_func.c:202 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "позиційний аргумент не може стежити за іменованим аргументомв" + +#: parser/parse_func.c:284 parser/parse_func.c:2243 +#, c-format +msgid "%s is not a procedure" +msgstr "%s не є процедурою" + +#: parser/parse_func.c:288 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Щоб викликати функцію, використайте SELECT." + +#: parser/parse_func.c:294 +#, c-format +msgid "%s is a procedure" +msgstr "%s - процедура" + +#: parser/parse_func.c:298 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Щоб викликати процедуру, використайте CALL." + +#: parser/parse_func.c:312 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) вказано, але %s не є агрегатною функцією" + +#: parser/parse_func.c:319 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT вказано, але %s не є агрегатною функцією" + +#: parser/parse_func.c:325 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP вказано, але %s не є агрегатною функцією" + +#: parser/parse_func.c:331 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY вказано, але %s не є агрегатною функцією" + +#: parser/parse_func.c:337 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER вказано, але %s не є агрегатною функцією" + +#: parser/parse_func.c:343 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER вказано, але %s не є ні віконною функцією, ні агрегатною функцією" + +#: parser/parse_func.c:381 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "Для сортувального агрегату %s необхідна WITHIN GROUP" + +#: parser/parse_func.c:387 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "Сортувальний агрегат %s не підтримує OVER" + +#: parser/parse_func.c:418 parser/parse_func.c:447 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr "Є сортувальний агрегат %s, але він потребує %d прямих аргументів, а не %d." + +#: parser/parse_func.c:472 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "Для використання гіпотетичного агрегату %s кількість прямих гіпотетичних аргументів (тут %d) повинна відповідати кількості сортувальних стовпців (тут %d)." + +#: parser/parse_func.c:486 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr "Є сортувальний агрегат %s, але він потребує мінімум %d прямих аргументів." + +#: parser/parse_func.c:505 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s не є сортувальним агрегатом, тому він не може мати WITHIN GROUP" + +#: parser/parse_func.c:518 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "віконна функція %s потребує речення OVER" + +#: parser/parse_func.c:525 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "віконна функція %s не може матив WITHIN GROUP" + +#: parser/parse_func.c:554 +#, c-format +msgid "procedure %s is not unique" +msgstr "процедура %s не є унікальною" + +#: parser/parse_func.c:557 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "Не вдалося обрати найкращу кандидатуру процедури. Можливо, вам слід додати явні приведення типів." + +#: parser/parse_func.c:563 +#, c-format +msgid "function %s is not unique" +msgstr "функція %s не є унікальною" + +#: parser/parse_func.c:566 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "Не вдалося обрати найкращу кандидатуру функції. Можливо, вам слід додати явні приведення типів." + +#: parser/parse_func.c:605 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "Агрегатну функцію з цим ім'ям і типами аргументів не знайдено. Можливо, ви невірно розмістили речення ORDER BY; речення ORDER BY повинно з'являтись після всіх звичайних аргументів агрегату." + +#: parser/parse_func.c:613 parser/parse_func.c:2286 +#, c-format +msgid "procedure %s does not exist" +msgstr "процедура %s не існує" + +#: parser/parse_func.c:616 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Процедуру з цим ім'ям і типами аргументів не знайдено. Можливо, вам слід додати явні приведення типів." + +#: parser/parse_func.c:625 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "Функцію з цим ім'ям і типами аргументів не знайдено. Можливо, вам слід додати явні приведення типів." + +#: parser/parse_func.c:727 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "Аргумент VARIADIC повинен бути масивом" + +#: parser/parse_func.c:779 parser/parse_func.c:843 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr " %s(*) треба використовувати для виклику агрегатної функції без параметрів" + +#: parser/parse_func.c:786 +#, c-format +msgid "aggregates cannot return sets" +msgstr "агрегатні функції не можуть повертати набори" + +#: parser/parse_func.c:801 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "агрегатні функції не можуть використовувати іменовані аргументи" + +#: parser/parse_func.c:833 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "DISTINCT для віконних функції не реалізовано" + +#: parser/parse_func.c:853 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "агрегатне речення ORDER BY для віконних функцій не реалізовано" + +#: parser/parse_func.c:862 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "FILTER для неагрегатних віконних функцій не реалізовано" + +#: parser/parse_func.c:871 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "виклики віконних функцій не можуть містити виклики функцій, які повертають набори" + +#: parser/parse_func.c:879 +#, c-format +msgid "window functions cannot return sets" +msgstr "віконні функції не можуть повертати набори" + +#: parser/parse_func.c:2124 parser/parse_func.c:2315 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "не вдалося знайти функцію з іменем \"%s\"" + +#: parser/parse_func.c:2138 parser/parse_func.c:2333 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "ім’я функції \"%s\" не є унікальним" + +#: parser/parse_func.c:2140 parser/parse_func.c:2335 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Укажіть список аргументів для однозначного вибору функції." + +#: parser/parse_func.c:2184 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "процедури не можуть мати більш ніж %d аргументу" +msgstr[1] "процедури не можуть мати більш ніж %d аргументів" +msgstr[2] "процедури не можуть мати більш ніж %d аргументів" +msgstr[3] "процедури не можуть мати більш ніж %d аргументів" + +#: parser/parse_func.c:2233 +#, c-format +msgid "%s is not a function" +msgstr "%s не є функцією" + +#: parser/parse_func.c:2253 +#, c-format +msgid "function %s is not an aggregate" +msgstr "функція %s не є агрегатною" + +#: parser/parse_func.c:2281 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "не вдалося знайти процедуру з іменем \"%s\"" + +#: parser/parse_func.c:2295 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "не вдалося знайти агрегат з ім'ям \"%s\"" + +#: parser/parse_func.c:2300 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "агрегат %s (*) не існує" + +#: parser/parse_func.c:2305 +#, c-format +msgid "aggregate %s does not exist" +msgstr "агрегат %s не існує" + +#: parser/parse_func.c:2340 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "назва процедури \"%s\" не є унікальною" + +#: parser/parse_func.c:2342 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Вкажіть список аргументів для однозначного вибору процедури." + +#: parser/parse_func.c:2347 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "назва агрегатної функції \"%s\" не є унікальною" + +#: parser/parse_func.c:2349 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Вкажіть список аргументів для однозначного вибору агрегатної функції." + +#: parser/parse_func.c:2354 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "назва підпрограми \"%s\" не є унікальною" + +#: parser/parse_func.c:2356 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Вкажіть список аргументів для однозначного вибору підпрограми." + +#: parser/parse_func.c:2411 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "функції, що повертають множину, не можна застосовувати в умовах групування" + +#: parser/parse_func.c:2432 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "функції, що повертають множину, не можна застосовувати у виразах політики" + +#: parser/parse_func.c:2448 +msgid "set-returning functions are not allowed in window definitions" +msgstr "функції, що повертають множину, не можна застосовувати у віконних визначеннях" + +#: parser/parse_func.c:2486 +msgid "set-returning functions are not allowed in check constraints" +msgstr "функції, що повертають множину, не можна застосовувати в обмеженнях Check" + +#: parser/parse_func.c:2490 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "функції, що повертають множину, не можна застосовувати у стандартних виразах" + +#: parser/parse_func.c:2493 +msgid "set-returning functions are not allowed in index expressions" +msgstr "функції, що повертають множину, не можна застосовувати в індексних виразах" + +#: parser/parse_func.c:2496 +msgid "set-returning functions are not allowed in index predicates" +msgstr "функції, що повертають множину, не можна застосовувати в індексних предикатах" + +#: parser/parse_func.c:2499 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "функції, що повертають множину, не можна застосовувати у виразах перетворення" + +#: parser/parse_func.c:2502 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "функції, що повертають множину, не можна застосовуватив параметрах виконання" + +#: parser/parse_func.c:2505 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "функції, що повертають множину, не можна застосовувати в умовах для тригерів WHEN" + +#: parser/parse_func.c:2508 +msgid "set-returning functions are not allowed in partition bound" +msgstr "функції, що повертають множину не можна застосовувати в границі секції" + +#: parser/parse_func.c:2511 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "функції, що повертають множину, не можна застосовувати у виразах ключа розділення" + +#: parser/parse_func.c:2514 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "функції, що повертають множину, не можна застосовувати в аргументах Відеовикликів" + +#: parser/parse_func.c:2517 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "функції, що повертають множину не можна застосовувати в умовах COPY FROM WHERE" + +#: parser/parse_func.c:2520 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "функції, що повертають множину не можна застосовувати у виразах генерації стовпців" + +#: parser/parse_node.c:86 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "цільові списки можуть мати максимум %d елементів" + +#: parser/parse_node.c:235 +#, c-format +msgid "cannot subscript type %s because it is not an array" +msgstr "не можливо вказати тип %s тому, що він не є масивом" + +#: parser/parse_node.c:340 parser/parse_node.c:377 +#, c-format +msgid "array subscript must have type integer" +msgstr "індекс елементу масиву має бути цілим числом" + +#: parser/parse_node.c:408 +#, c-format +msgid "array assignment requires type %s but expression is of type %s" +msgstr "для присвоєння масиву потрібен тип %s, але вираз має тип %s" + +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:521 +#: utils/adt/regproc.c:705 +#, c-format +msgid "operator does not exist: %s" +msgstr "оператор не існує: %s" + +#: parser/parse_oper.c:224 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Використати явний оператор сортування або змінити запит." + +#: parser/parse_oper.c:480 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "оператор вимагає приведення типів під час виконання: %s" + +#: parser/parse_oper.c:716 +#, c-format +msgid "operator is not unique: %s" +msgstr "оператор не є унікальним: %s" + +#: parser/parse_oper.c:718 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "Не вдалося вибрати найкращу кандидатуру оператора. Вам, можливо треба додати явні приведення типів." + +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Жодний оператор не відповідає даному імені та типу аргументу. Вам, можливо, треба додати явне приведення типу." + +#: parser/parse_oper.c:729 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "Жодний оператор не відповідає даному імені та типу аргументу. Вам, можливо, треба додати явні приведення типів." + +#: parser/parse_oper.c:790 parser/parse_oper.c:912 +#, c-format +msgid "operator is only a shell: %s" +msgstr "оператор є лише оболонкою: %s" + +#: parser/parse_oper.c:900 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (масив) вимагає масив справа" + +#: parser/parse_oper.c:942 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (масив) вимагає оператора для видання логічного типу" + +#: parser/parse_oper.c:947 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (масив) вимагає оператора не для повернення множини" + +#: parser/parse_param.c:216 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "для параметру $%d виведені неузгоджені типи" + +#: parser/parse_relation.c:201 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "посилання на таблицю \"%s\" неоднозначне" + +#: parser/parse_relation.c:245 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "посилання на таблицю %u неоднозначне" + +#: parser/parse_relation.c:444 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "ім'я таблиці \"%s\" вказано більше одного разу" + +#: parser/parse_relation.c:473 parser/parse_relation.c:3446 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "в елементі речення FROM неприпустиме посилання на таблицю \"%s\"" + +#: parser/parse_relation.c:477 parser/parse_relation.c:3451 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Таблиця \"%s\" присутня в запиті, але посилатися на неї з цієї частини запиту не можна." + +#: parser/parse_relation.c:479 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "Для посилання LATERAL тип JOIN повинен бути INNER або LEFT." + +#: parser/parse_relation.c:690 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "недопустиме посилання системи стовпців \"%s\" в обмеженні Check" + +#: parser/parse_relation.c:699 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "використовувати системний стовпець \"%s\" у виразах генерації стовпців, не можна" + +#: parser/parse_relation.c:1170 parser/parse_relation.c:1620 +#: parser/parse_relation.c:2262 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "таблиця \"%s\" має %d доступних стовпців, але вказано %d стовпців" + +#: parser/parse_relation.c:1372 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "Існує WITH елемент \"%s\" але на нього не можна посилатися з цієї частини запиту." + +#: parser/parse_relation.c:1374 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "Використовувати WITH RECURSIVE, або перевпорядкувати елементи WITH, щоб видалити попередні посилання." + +#: parser/parse_relation.c:1747 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "список з визначенням стовпців дозволений лише для функцій, що повертають \"запис\"" + +#: parser/parse_relation.c:1756 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "список з визначенням стовпців вимагається для функцій, що повертають \"запис\"" + +#: parser/parse_relation.c:1845 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "функція \"%s\" у FROM повертає тип, що не підтримується %s" + +#: parser/parse_relation.c:2054 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "VALUES списки \"%s\" мають %d доступних стовпців, але %d стовпців вказано" + +#: parser/parse_relation.c:2125 +#, c-format +msgid "joins can have at most %d columns" +msgstr "з'єднання можуть мати максимум %d стовпців" + +#: parser/parse_relation.c:2235 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "WITH запит \"%s\" не має речення RETURNING" + +#: parser/parse_relation.c:3221 parser/parse_relation.c:3231 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "стовпець %d відношення \"%s\" не існує" + +#: parser/parse_relation.c:3449 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Можливо, малося на увазі посилання на псевдонім таблиці \"%s\"." + +#: parser/parse_relation.c:3457 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "таблиця \"%s\" відсутня в реченні FROM" + +#: parser/parse_relation.c:3509 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Можливо, передбачалось посилання на стовпець \"%s.%s\"." + +#: parser/parse_relation.c:3511 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Є стовпець з іменем \"%s\" в таблиці \"%s\", але на нього не можна посилатись з цієї частини запиту." + +#: parser/parse_relation.c:3528 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "Можливо, передбачалось посилання на стовпець \"%s.%s\" або стовпець \"%s.%s\"." + +#: parser/parse_target.c:478 parser/parse_target.c:792 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "призначити значення системному стовпцю \"%s\" не можна" + +#: parser/parse_target.c:506 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "елементу масива не можна встановити значення DEFAULT" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "підполю не можна встановити значення DEFAULT" + +#: parser/parse_target.c:584 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "стовпець \"%s\" має тип %s, а вираз %s" + +#: parser/parse_target.c:776 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "призначити значення полю \"%s\" стовпця \"%s\" не можна, тому, що тип %s не є складеним типом" + +#: parser/parse_target.c:785 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "призначити значення полю \"%s\" стовпця \"%s\" не можна, тому, що в типі даних %s немає такого стовпця" + +#: parser/parse_target.c:864 +#, c-format +msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "для призначення масиву полю \"%s\" потрібен тип %s, але вираз має тип %s" + +#: parser/parse_target.c:874 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "підполе \"%s\" має тип %s, але вираз має тип %s" + +#: parser/parse_target.c:1295 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "SELECT * повинен посилатись на таблиці" + +#: parser/parse_type.c:100 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "неправильне посилання %%TYPE (занадто мало компонентів): %s" + +#: parser/parse_type.c:122 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "неправильне посилання %%TYPE (занадто багато компонентів): %s" + +#: parser/parse_type.c:157 +#, c-format +msgid "type reference %s converted to %s" +msgstr "посилання на тип %s перетворене на тип %s" + +#: parser/parse_type.c:278 parser/parse_type.c:857 utils/cache/typcache.c:383 +#: utils/cache/typcache.c:437 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "тип \"%s\" є лише оболонкою" + +#: parser/parse_type.c:363 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "тип \"%s\" не дозволяє використання модифікаторів" + +#: parser/parse_type.c:405 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "модифікатором типу повинна бути звичайна константа або ідентифікатор" + +#: parser/parse_type.c:721 parser/parse_type.c:820 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "невірне ім'я типу \"%s\"" + +#: parser/parse_utilcmd.c:264 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "створити секціоновану таблицю в якості нащадка не можна" + +#: parser/parse_utilcmd.c:428 +#, c-format +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s створить неявну послідовність \"%s\" для послідовного стовпця \"%s.%s\"" + +#: parser/parse_utilcmd.c:559 +#, c-format +msgid "array of serial is not implemented" +msgstr "масиви послідовності не реалізовані" + +#: parser/parse_utilcmd.c:637 parser/parse_utilcmd.c:649 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "несумісні оголошення NULL/NOT NULL для стовпця \"%s\" таблиці \"%s\"" + +#: parser/parse_utilcmd.c:661 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "для стовпця \"%s\" таблиці \"%s\" вказано декілька значень за замовчуванням" + +#: parser/parse_utilcmd.c:678 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "ідентифікаційні стовпці не підтримуються в типізованих таблицях" + +#: parser/parse_utilcmd.c:682 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "ідентифікаційні стовпці не підтримуються з секціями" + +#: parser/parse_utilcmd.c:691 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "для стовпця \"%s\" таблиці \"%s\" властивість identity вказана неодноразово" + +#: parser/parse_utilcmd.c:711 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "згенеровані стовпці не підтримуються в типізованих таблицях" + +#: parser/parse_utilcmd.c:715 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "згенеровані стовпці не підтримуються в секціях" + +#: parser/parse_utilcmd.c:720 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "для стовпця \"%s\" таблиці \"%s\" вказано декілька речень генерації" + +#: parser/parse_utilcmd.c:738 parser/parse_utilcmd.c:853 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "обмеження первинного ключа для сторонніх таблиць не підтримуються" + +#: parser/parse_utilcmd.c:747 parser/parse_utilcmd.c:863 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "обмеження унікальності для сторонніх таблиць не підтримуються" + +#: parser/parse_utilcmd.c:792 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "для стовпця \"%s\" таблиці \"%s\" вказано значення за замовчуванням і властивість identity" + +#: parser/parse_utilcmd.c:800 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "для стовпця \"%s\" таблиці \"%s\" вказано вираз за замовчуванням і вираз генерації" + +#: parser/parse_utilcmd.c:808 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "для стовпця \"%s\" таблиці \"%s\" вказано вираз ідентичності і вираз генерації" + +#: parser/parse_utilcmd.c:873 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "обмеження-виключення для сторонніх таблиць не підтримуються" + +#: parser/parse_utilcmd.c:879 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "обмеження-виключення для секціонованих таблиць не підтримуються" + +#: parser/parse_utilcmd.c:944 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "LIKE не підтримується при створенні сторонніх таблиць" + +#: parser/parse_utilcmd.c:1704 parser/parse_utilcmd.c:1813 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "Індекс \"%s\" містить посилання на таблицю на весь рядок." + +#: parser/parse_utilcmd.c:2163 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "у CREATE TABLE не можна використовувати існуючий індекс" + +#: parser/parse_utilcmd.c:2183 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "індекс \"%s\" вже пов'язаний з обмеженням" + +#: parser/parse_utilcmd.c:2198 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "індекс \"%s\" не є припустимим" + +#: parser/parse_utilcmd.c:2204 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "\"%s\" не є унікальним індексом" + +#: parser/parse_utilcmd.c:2205 parser/parse_utilcmd.c:2212 +#: parser/parse_utilcmd.c:2219 parser/parse_utilcmd.c:2296 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "Створити первинний ключ або обмеження унікальності, використовуючи такий індекс, не можна." + +#: parser/parse_utilcmd.c:2211 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "індекс \"%s\" містить вирази" + +#: parser/parse_utilcmd.c:2218 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "\"%s\" є частковим індексом" + +#: parser/parse_utilcmd.c:2230 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\" є індексом, що відкладається" + +#: parser/parse_utilcmd.c:2231 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "Створити обмеження, що не відкладається, використовуючи індекс, що відкладається, не можна." + +#: parser/parse_utilcmd.c:2295 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "індекс \"%s\" номер стовпця %d не має поведінки сортування за замовчуванням" + +#: parser/parse_utilcmd.c:2452 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "стовпець \"%s\" з'являється двічі в обмеженні первинного ключа" + +#: parser/parse_utilcmd.c:2458 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "стовпець \"%s\" з'являється двічі в обмеженні унікальності" + +#: parser/parse_utilcmd.c:2811 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "індекс-вирази й предикати можуть посилатись лише на індексовану таблицю" + +#: parser/parse_utilcmd.c:2857 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "правила для матеріалізованих подань не підтримуються" + +#: parser/parse_utilcmd.c:2920 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "в умовах WHERE правила не можуть містити посилання на інші зв'язки" + +#: parser/parse_utilcmd.c:2994 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "правила з умовами WHERE можуть мати лише дії SELECT, INSERT, UPDATE або DELETE" + +#: parser/parse_utilcmd.c:3012 parser/parse_utilcmd.c:3113 +#: rewrite/rewriteHandler.c:502 rewrite/rewriteManip.c:1018 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "умовні оператори UNION/INTERSECT/EXCEPT не реалізовані" + +#: parser/parse_utilcmd.c:3030 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "у правилі ON SELECT не можна використовувати OLD" + +#: parser/parse_utilcmd.c:3034 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "у правилі ON SELECT не можна використовувати NEW" + +#: parser/parse_utilcmd.c:3043 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "у правилі ON INSERT не можна використовувати OLD" + +#: parser/parse_utilcmd.c:3049 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "у правилі ON DELETE не можна використовувати NEW" + +#: parser/parse_utilcmd.c:3077 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "у запиті WITH не можна посилатися на OLD" + +#: parser/parse_utilcmd.c:3084 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "у запиті WITH не можна посилатися на NEW" + +#: parser/parse_utilcmd.c:3542 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "речення DEFERRABLE розташовано неправильно" + +#: parser/parse_utilcmd.c:3547 parser/parse_utilcmd.c:3562 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "декілька речень DEFERRABLE/NOT DEFERRABLE не допускаються" + +#: parser/parse_utilcmd.c:3557 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "речення NOT DEFERRABLE розташовано неправильно" + +#: parser/parse_utilcmd.c:3570 parser/parse_utilcmd.c:3596 gram.y:5593 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "обмеження, оголошене як INITIALLY DEFERRED, повинно бути оголошене як DEFERRABLE" + +#: parser/parse_utilcmd.c:3578 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "речення INITIALLY DEFERRED розташовано неправильно" + +#: parser/parse_utilcmd.c:3583 parser/parse_utilcmd.c:3609 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "декілька речень INITIALLY IMMEDIATE/DEFERRED не допускаються" + +#: parser/parse_utilcmd.c:3604 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "речення INITIALLY IMMEDIATE розташовано неправильно" + +#: parser/parse_utilcmd.c:3795 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "В CREATE вказана схема (%s), яка відрізняється від створюваної (%s)" + +#: parser/parse_utilcmd.c:3830 +#, c-format +msgid "\"%s\" is not a partitioned table" +msgstr "\"%s\" не є секціонованою таблицею" + +#: parser/parse_utilcmd.c:3837 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "таблиця \"%s\" не є секційною" + +#: parser/parse_utilcmd.c:3844 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "індекс \"%s\" не є секціонованим" + +#: parser/parse_utilcmd.c:3884 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "у геш-секціонованій таблиці не може бути розділу за замовчуванням" + +#: parser/parse_utilcmd.c:3901 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "неприпустима вказівка границі для геш-секції" + +#: parser/parse_utilcmd.c:3907 partitioning/partbounds.c:4691 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "модуль для геш-секції повинен бути додатним цілим" + +#: parser/parse_utilcmd.c:3914 partitioning/partbounds.c:4699 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "залишок для геш-секції повинен бути меньшим, ніж модуль" + +#: parser/parse_utilcmd.c:3927 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "нерипустима вказівка границі для секції по списку" + +#: parser/parse_utilcmd.c:3980 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "неприпустима вказівка границі для секції діапазону" + +#: parser/parse_utilcmd.c:3986 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "В FROM повинно вказуватися лише одне значення для стовпця секціонування" + +#: parser/parse_utilcmd.c:3990 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "В TO повинно вказуватися лише одне значення для стовпця секціонування" + +#: parser/parse_utilcmd.c:4104 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "вказати NULL в діапазоні границі не можна" + +#: parser/parse_utilcmd.c:4153 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "за кожною границею MAXVALUE повинні бути лише границі MAXVALUE" + +#: parser/parse_utilcmd.c:4160 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "за кожною границею MINVALUE повинні бути лише границі MINVALUE" + +#: parser/parse_utilcmd.c:4202 +#, c-format +msgid "could not determine which collation to use for partition bound expression" +msgstr "не вдалося визначити яке правило сортування використати для виразу границі розділу" + +#: parser/parse_utilcmd.c:4219 +#, c-format +msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +msgstr "значення параметру сортування границі секції для стовпця \"%s\" не відповідає параметру сортування ключа секціонування \"%s\"" + +#: parser/parse_utilcmd.c:4236 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "вказане значення не можна привести до типу %s для стовпця \"%s\"" + +#: parser/parser.c:228 +msgid "UESCAPE must be followed by a simple string literal" +msgstr "UESCAPE повинен відстежуватись простим літеральним рядком" + +#: parser/parser.c:233 +msgid "invalid Unicode escape character" +msgstr "неприпустимий символ спеціального коду Unicode" + +#: parser/parser.c:302 scan.l:1329 +#, c-format +msgid "invalid Unicode escape value" +msgstr "неприпустиме значення спеціального коду Unicode" + +#: parser/parser.c:449 scan.l:677 +#, c-format +msgid "invalid Unicode escape" +msgstr "неприпустимий спеціальний код Unicode" + +#: parser/parser.c:450 +#, c-format +msgid "Unicode escapes must be \\XXXX or \\+XXXXXX." +msgstr "Спеціальні символи Unicode повинні бути \\XXXX або \\+XXXXXX." + +#: parser/parser.c:478 scan.l:638 scan.l:654 scan.l:670 +#, c-format +msgid "invalid Unicode surrogate pair" +msgstr "неприпустима сурогатна пара Unicode" + +#: parser/scansup.c:203 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%s\"" +msgstr "ідентифікатор \"%s\" буде скорочено до \"%s\"" + +#: partitioning/partbounds.c:2831 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "існують конфлікти між розділом \"%s\" та існуючим розділом за замовчуванням \"%s\"" + +#: partitioning/partbounds.c:2890 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "модуль кожної геш-секції повинен бути дільником наступних більших модулів" + +#: partitioning/partbounds.c:2986 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "для секції \"%s\" вказані границі, які утворюють пустий діапазон" + +#: partitioning/partbounds.c:2988 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Вказана нижня границя %s більша або дорівнює верхній границі %s." + +#: partitioning/partbounds.c:3085 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "секція \"%s\" буде перекривати секцію \"%s\"" + +#: partitioning/partbounds.c:3202 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "пропущено сканування зовнішньої таблиці \"%s\" яка є секцією секції за замовчуванням \"%s\"" + +#: partitioning/partbounds.c:4695 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "залишок для геш-секції повинен бути не від'ємним цілим" + +#: partitioning/partbounds.c:4722 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" не є геш-секціонованою таблицею" + +#: partitioning/partbounds.c:4733 partitioning/partbounds.c:4850 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "кількість секціонованих стовпців (%d) не дорівнює кількості наданих ключів секціонування (%d)" + +#: partitioning/partbounds.c:4755 partitioning/partbounds.c:4787 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "стовпець %d ключа секціонування має тип \"%s\", але для нього вказано значення типу \"%s\"" + +#: port/pg_sema.c:209 port/pg_shmem.c:640 port/posix_sema.c:209 +#: port/sysv_sema.c:327 port/sysv_shmem.c:640 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "не вдалося встановити дані каталогу \"%s\": %m" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "не вдалося створити сегмент спільної пам'яті: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "Помилка в системному виклику shmget (ключ=%lu, розмір=%zu, 0%o)." + +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "Ця помилка зазвичай означає, що запит PostgreSQL для сегменту спільної пам'яті перевищує параметр SHMMAX вашого ядра, або можливо що він менший за параметр SHMMIN вашого ядра.\n" +"Більше інформації про налаштування спільної пам'яті міститься в інструкції PostgreSQL." + +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "Ця помилка зазвичай означає, що запит PostgreSQL для сегменту спільної пам'яті перевищує параметр SHMALL вашого ядра. Можливо, вам слід переналаштувати ваше ядро, збільшивши параметр SHMALL.\n" +"Більше інформації про налаштування спільної пам'яті міститься в інструкції PostgreSQL." + +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 +#, c-format +msgid "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "Ця помилка НЕ означає, що на диску немає місця. Ймовірніше за все, були зайняті всі доступні ID спільної пам'яті, в такому випадку вам потрібно підвищити параметр SHMMNI у вашому ядрі, або перевищено граничний розмір спільної пам'яті.\n" +"Детальна інформація про налаштування спільної пам'яті міститься в інструкції PostgreSQL." + +#: port/pg_shmem.c:578 port/sysv_shmem.c:578 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "не вдалося показати анонімну спільну пам'ять: %m" + +#: port/pg_shmem.c:580 port/sysv_shmem.c:580 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "Ця помилка зазвичай означає, що запит PostgreSQL для сегменту спільної пам'яті перевищує об'єм доступної фізичної або віртуальної пам'яті або гігантских сторінок. Щоб зменшити розмір запиту (поточний: %zu байтів), зменшіть використання спільної пам'яті PostgreSQL, можливо зменшив shared_buffers або max_connections." + +#: port/pg_shmem.c:648 port/sysv_shmem.c:648 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "величезні сторінки на цій плтаформі не підтримуються" + +#: port/pg_shmem.c:709 port/sysv_shmem.c:709 utils/init/miscinit.c:1137 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "раніше виділений блок спільної пам'яті (ключ %lu, ідентифікатор %lu) все ще використовується" + +#: port/pg_shmem.c:712 port/sysv_shmem.c:712 utils/init/miscinit.c:1139 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Припинити будь-які старі серверні процеси, пов'язані з каталогом даних \"%s\"." + +#: port/sysv_sema.c:124 +#, c-format +msgid "could not create semaphores: %m" +msgstr "не вдалося створити семафори: %m" + +#: port/sysv_sema.c:125 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "Помилка системного виклику semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:129 +#, c-format +msgid "This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "Ця помилка НЕ означає, що на диску немає місця. Ймовірніше за все перевищено ліміт числа встановлених семафорів (SEMMNI), або загального числа семафорів (SEMMNS) в системі. Вам потрібно збільшити відповідний параметр ядра. Інший спосіб - зменшити споживання PostgreSQL в семафорах, зменшивши параметр max_connections.\n" +"Більше інформації про налаштування вашої системи для PostgreSQL міститься в інструкції PostgreSQL." + +#: port/sysv_sema.c:159 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "Можливо, вам потрібно збілшити значення SEMVMX вашого ядра, мінімум до %d. Детальніше про це написано в інструкції PostgreSQL." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "не вдалося завантажити dbghelp.dll, записати аварійний дамп неможливо\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "не вдалося завантажити функції, що вимагалися, у dbghelp.dll, записати аварійний дамп неможливо\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "не вдалося відкрити файл аварійного дампу \"%s\" для написання: код помилки %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "аварійний дамп записано у фай \"%s\"\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "не вдалося записати аварійний дамп у файл \"%s\": код помилки %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "не вдалося створити канал сигнального прослуховувача для PID %d: код помилки %lu" + +#: port/win32/signal.c:251 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "не вдалося створити канал сигнального прослуховувача: код помилки %lu; триває повторна спроба\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "не вдалося створити семафори: код помилки %lu" + +#: port/win32_sema.c:180 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "не вдалося заблокувати семафор: код помилки %lu" + +#: port/win32_sema.c:200 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "не вдалося розблокувати семафор: код помилки %lu" + +#: port/win32_sema.c:230 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "не вдалося спробувати заблокувати семафор: код помилки %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "не вдалося активізувати право користувача на блокування сторінок у пам’яті: код помилки %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "Помилка системного виклику %s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "не вдалося активізувати право користувача на блокування сторінок в пам'яті" + +#: port/win32_shmem.c:176 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "Призначити право користувача на блокування сторінок в пам'яті для облікового запису користувача Windows, що запускає PostgreSQL." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "процесор не підтримує великі сторінки" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "відключення величезних сторінок" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "не вдалося створити сегмент спільної пам'яті: код помилки %lu" + +#: port/win32_shmem.c:303 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "Помилка системного виклику CreateFileMapping(розмір=%zu, ім'я=%s)." + +#: port/win32_shmem.c:328 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "раніше створений блок спільної пам'яті все ще використовується" + +#: port/win32_shmem.c:329 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "Перевірити, якщо будь-які старі серверні процеси все ще працюють, та завершити їх." + +#: port/win32_shmem.c:339 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "Помилка в системному виклику DuplicateHandle." + +#: port/win32_shmem.c:357 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "Помилка в системному виклику MapViewOfFileEx." + +#: postmaster/autovacuum.c:406 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "не вдалося породити процес запуску автоочистки: %m" + +#: postmaster/autovacuum.c:442 +#, c-format +msgid "autovacuum launcher started" +msgstr "процес запуску автоочистки почався" + +#: postmaster/autovacuum.c:839 +#, c-format +msgid "autovacuum launcher shutting down" +msgstr "процес запуску автоочитски завершується" + +#: postmaster/autovacuum.c:1477 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "не вдалося породити робочий процес автоочитски: %m" + +#: postmaster/autovacuum.c:1686 +#, c-format +msgid "autovacuum: processing database \"%s\"" +msgstr "автоочистка: обробка бази даних \"%s\"" + +#: postmaster/autovacuum.c:2256 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "автоочистка: видалення застарілої тимчасової таблиці \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2485 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "автоматична очистка таблиці \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2488 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "автоматичний аналіз таблиці \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2681 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "обробка робочого введення для відношення \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:3285 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "автоочистку не запущено через неправильну конфігурацію" + +#: postmaster/autovacuum.c:3286 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "Активувати параметр \"track_counts\"." + +#: postmaster/bgworker.c:394 postmaster/bgworker.c:841 +#, c-format +msgid "registering background worker \"%s\"" +msgstr "реєстрація фонового виконавця \"%s\"" + +#: postmaster/bgworker.c:426 +#, c-format +msgid "unregistering background worker \"%s\"" +msgstr "розреєстрація фонового виконавця \"%s\"" + +#: postmaster/bgworker.c:591 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "фоновий виконавець \"%s\": повинен підключатися до спільної пам'яті на замовлення для запиту підключення до бази даних" + +#: postmaster/bgworker.c:600 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "фоновий виконавець \"%s\": не може запитувати доступ до бази даних, якщо його запущено при старті адміністратора поштового сервісу" + +#: postmaster/bgworker.c:614 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "фоновий виконавець \"%s\": неприпустимий інтервал перезавантаження" + +#: postmaster/bgworker.c:629 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "фоновий виконавець\"%s\": паралельні виконавці не можуть бути налаштовані для перезавантаження" + +#: postmaster/bgworker.c:653 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "завершення фонового процесу \"%s\" по команді адміністратора" + +#: postmaster/bgworker.c:849 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "фоновий процес \"%s\": повинен бути зареєстрований в shared_preload_libraries" + +#: postmaster/bgworker.c:861 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "фоновий процес \"%s\": лише динамічні фонові процеси можуть запитувати сповіщення" + +#: postmaster/bgworker.c:876 +#, c-format +msgid "too many background workers" +msgstr "занадто багато фонових процесів" + +#: postmaster/bgworker.c:877 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "Максимальне можливе число фонового процесу при поточних параметрах: %d." +msgstr[1] "Максимальне можливе число фонових процесів при поточних параметрах: %d." +msgstr[2] "Максимальне можливе число фонових процесів при поточних параметрах: %d." +msgstr[3] "Максимальне можливе число фонових процесів при поточних параметрах: %d." + +#: postmaster/bgworker.c:881 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "Можливо, слід збільшити параметр конфігурації \"max_worker_processes\"." + +#: postmaster/checkpointer.c:418 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "контрольні точки відбуваються занадто часто (через %d сек.)" +msgstr[1] "контрольні точки відбуваються занадто часто (через %d сек.)" +msgstr[2] "контрольні точки відбуваються занадто часто (через %d сек.)" +msgstr[3] "контрольні точки відбуваються занадто часто (через %d сек.)" + +#: postmaster/checkpointer.c:422 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "Можливо, слід збільшити параметр конфігурації \"max_wal_size\"." + +#: postmaster/checkpointer.c:1032 +#, c-format +msgid "checkpoint request failed" +msgstr "збій при запиті контрольної точки" + +#: postmaster/checkpointer.c:1033 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "Для деталей, зверніться до останніх повідомлень в протоколі серверу." + +#: postmaster/checkpointer.c:1217 +#, c-format +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "чергу запитів fsync стиснуто з %d елементів, до %d елементів" + +#: postmaster/pgarch.c:155 +#, c-format +msgid "could not fork archiver: %m" +msgstr "не вдалося породити процес архівації: %m" + +#: postmaster/pgarch.c:425 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode активний, але archive_command не встановлена" + +#: postmaster/pgarch.c:447 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "видалено залишковий файл статусу архіву \"%s\"" + +#: postmaster/pgarch.c:457 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "видалення залишкового файлу статусу архіву \"%s\" не вдалося занадто багато разів, пізніже спробуємо знову" + +#: postmaster/pgarch.c:493 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "архівація файлу випереджувальног журналювання \"%s\" не виконана багато разів, наступна спроба буде пізніже" + +#: postmaster/pgarch.c:594 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "команда архівації завершилась помилкой з кодом %d" + +#: postmaster/pgarch.c:596 postmaster/pgarch.c:606 postmaster/pgarch.c:612 +#: postmaster/pgarch.c:621 +#, c-format +msgid "The failed archive command was: %s" +msgstr "Команда архівації з помилкою: %s" + +#: postmaster/pgarch.c:603 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "команда архівації була перервана винятком 0x%X" + +#: postmaster/pgarch.c:605 postmaster/postmaster.c:3742 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "Опис цього Шістнадцяткового значення дивіться у включаємому C-файлі \"ntstatus.h\"." + +#: postmaster/pgarch.c:610 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "команда архівації була перервана сигналом %d: %s" + +#: postmaster/pgarch.c:619 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "команда архівації завершена з нерозпізнаним статусом %d" + +#: postmaster/pgstat.c:419 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "не вдалося закрити \"localhost\": %s" + +#: postmaster/pgstat.c:442 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "спроба іншої адреси для збирача статистики" + +#: postmaster/pgstat.c:451 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "не вдалося створити сокет для збирача статистики: %m" + +#: postmaster/pgstat.c:463 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "не вдалося прив'язати сокет для збирача статистики: %m" + +#: postmaster/pgstat.c:474 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "не вдалося отримати адресу сокета для збирача статистики: %m" + +#: postmaster/pgstat.c:490 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "не вдалося підключити сокет для збирача статистики: %m" + +#: postmaster/pgstat.c:511 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "не вдалося надіслати тестове повідомлення в сокет для збирача статистики: %m" + +#: postmaster/pgstat.c:537 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "помилка select() в збирачі статистики: %m" + +#: postmaster/pgstat.c:552 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "тестове повідомлення не пройшло крізь сокет для збирача статистики" + +#: postmaster/pgstat.c:567 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "не вдалося отримати тестове повідомлення крізь сокет для збирача статистики: %m" + +#: postmaster/pgstat.c:577 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "неправильне передавання тестового повідомлення крізь сокет для збирача статистики" + +#: postmaster/pgstat.c:600 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "не вдалося встановити сокет збирача статистики в неблокуючий режим: %m" + +#: postmaster/pgstat.c:642 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "вимкнення збирача статистики відбувається через нестачі робочого сокету" + +#: postmaster/pgstat.c:789 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "не вдалося породити процес збирача статистики: %m" + +#: postmaster/pgstat.c:1376 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "нерозпізнане відновлення мети: \"%s\"" + +#: postmaster/pgstat.c:1377 +#, c-format +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "Мета повинна бути \"archiver\" або \"bgwriter\"." + +#: postmaster/pgstat.c:4561 +#, c-format +msgid "could not read statistics message: %m" +msgstr "не вдалося прочитати повідомлення статистики: %m" + +#: postmaster/pgstat.c:4883 postmaster/pgstat.c:5046 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "не вдалося відкрити тимчасовий файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:4956 postmaster/pgstat.c:5091 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "не вдалося записати в тимчасовий файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:4965 postmaster/pgstat.c:5100 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "не вдалося закрити тимчасовий файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:4973 postmaster/pgstat.c:5108 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "не вдалося перейменувати тимчасовий файл статистики з \"%s\" в \"%s\": %m" + +#: postmaster/pgstat.c:5205 postmaster/pgstat.c:5422 postmaster/pgstat.c:5576 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "не вдалося відкрити файл статистики \"%s\": %m" + +#: postmaster/pgstat.c:5217 postmaster/pgstat.c:5227 postmaster/pgstat.c:5248 +#: postmaster/pgstat.c:5259 postmaster/pgstat.c:5281 postmaster/pgstat.c:5296 +#: postmaster/pgstat.c:5359 postmaster/pgstat.c:5434 postmaster/pgstat.c:5454 +#: postmaster/pgstat.c:5472 postmaster/pgstat.c:5488 postmaster/pgstat.c:5506 +#: postmaster/pgstat.c:5522 postmaster/pgstat.c:5588 postmaster/pgstat.c:5600 +#: postmaster/pgstat.c:5612 postmaster/pgstat.c:5623 postmaster/pgstat.c:5648 +#: postmaster/pgstat.c:5670 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "пошкоджений файл статистики \"%s\"" + +#: postmaster/pgstat.c:5799 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "використовується застаріла статистика замість поточної, тому, що збирач статистики не відповідає" + +#: postmaster/pgstat.c:6129 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "таблиця гешування бази даних пошкоджена під час очищення --- переривання" + +#: postmaster/postmaster.c:733 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: неприпустимий аргумент для параметру -f: \"%s\"\n" + +#: postmaster/postmaster.c:819 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: неприпустимий аргумент для параметру -t: \"%s\"\n" + +#: postmaster/postmaster.c:870 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: неприпустимий аргумент: \"%s\"\n" + +#: postmaster/postmaster.c:912 +#, c-format +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) має бути меншим ніж max_connections (%d)\n" + +#: postmaster/postmaster.c:919 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "WAL архіватор не може бути активованим, коли wal_level \"мінімальний\"" + +#: postmaster/postmaster.c:922 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "Потокове передавання WAL (max_wal_senders > 0) вимагає wal_level \"replica\" або \"logical\"" + +#: postmaster/postmaster.c:930 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: неприпустимі таблиці маркерів часу, будь-ласка виправіть\n" + +#: postmaster/postmaster.c:1047 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "не вдалося створити завершений порт вводу-виводу для черги дітей" + +#: postmaster/postmaster.c:1113 +#, c-format +msgid "ending log output to stderr" +msgstr "завершення запису виводу Stderr" + +#: postmaster/postmaster.c:1114 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "В майбутньому запис виведення буде записуватися в призначення \"%s\"." + +#: postmaster/postmaster.c:1125 +#, c-format +msgid "starting %s" +msgstr "початок %s" + +#: postmaster/postmaster.c:1154 postmaster/postmaster.c:1252 +#: utils/init/miscinit.c:1597 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "неприпустимий синтаксис списку в параметрі \"%s\"" + +#: postmaster/postmaster.c:1185 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "не вдалося створити сокет прослуховування для \"%s\"" + +#: postmaster/postmaster.c:1191 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "не вдалося створити TCP/IP сокети" + +#: postmaster/postmaster.c:1274 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "не вдалося створити Unix-domain сокет в каталозі \"%s\"" + +#: postmaster/postmaster.c:1280 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "не вдалося створити Unix-domain сокети" + +#: postmaster/postmaster.c:1292 +#, c-format +msgid "no socket created for listening" +msgstr "не створено жодного сокету для прослуховування" + +#: postmaster/postmaster.c:1323 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: не вдалося змінити дозволи зовнішнього PID файлу \"%s\": %s\n" + +#: postmaster/postmaster.c:1327 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: не вдалося записати зовнішній PID файл \"%s\": %s\n" + +#: postmaster/postmaster.c:1360 utils/init/postinit.c:215 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "не вдалося завантажити pg_hba.conf" + +#: postmaster/postmaster.c:1386 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "адміністратор поштового сервера став багатопотоковим під час запуску" + +#: postmaster/postmaster.c:1387 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "Встановити в змінній середовища LC_ALL дійісну локаль." + +#: postmaster/postmaster.c:1488 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: не вдалося знайти відповідний postgres файл, що виконується" + +#: postmaster/postmaster.c:1511 utils/misc/tzparser.c:340 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "Це може означати неповне встановлення PostgreSQL, або те, що файл \"%s\" було переміщено з його правильного розташування." + +#: postmaster/postmaster.c:1538 +#, c-format +msgid "%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "%s: не вдалося знайти систему бази даних\n" +"Очікувалося знайти її у каталозі \"%s\",\n" +"але не вдалося відкрити файл \"%s\": %s\n" + +#: postmaster/postmaster.c:1715 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "помилка вибирати() в адміністраторі поштового сервера: %m" + +#: postmaster/postmaster.c:1870 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "виконується негайне припинення роботи через неприпустимий файл блокування каталогу даних" + +#: postmaster/postmaster.c:1973 postmaster/postmaster.c:2004 +#, c-format +msgid "incomplete startup packet" +msgstr "неповний стартовий пакет" + +#: postmaster/postmaster.c:1985 +#, c-format +msgid "invalid length of startup packet" +msgstr "неприпустима довжина стартового пакету" + +#: postmaster/postmaster.c:2043 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "помилка надсилання протоколу SSL в процесі відповіді зв'язування: %m" + +#: postmaster/postmaster.c:2074 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "помилка надсилання GSSAPI в процесі відповіді зв'язування: %m" + +#: postmaster/postmaster.c:2104 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "протокол інтерфейсу, що не підтримується, %u.%u: сервер підтримує %u.0 до %u.%u" + +#: postmaster/postmaster.c:2168 utils/misc/guc.c:6769 utils/misc/guc.c:6805 +#: utils/misc/guc.c:6875 utils/misc/guc.c:8198 utils/misc/guc.c:11044 +#: utils/misc/guc.c:11078 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "неприпустиме значення параметру \"%s\": \"%s\"" + +#: postmaster/postmaster.c:2171 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "Дійсні значення: \"false\", 0, \"true\", 1, \"database\"." + +#: postmaster/postmaster.c:2216 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "неприпустима структура стартового пакету: останнім байтом очікувався термінатор" + +#: postmaster/postmaster.c:2254 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "не вказано жодного ім'я користувача PostgreSQL у стартовому пакеті" + +#: postmaster/postmaster.c:2318 +#, c-format +msgid "the database system is starting up" +msgstr "система бази даних запускається" + +#: postmaster/postmaster.c:2323 +#, c-format +msgid "the database system is shutting down" +msgstr "система бази даних завершує роботу" + +#: postmaster/postmaster.c:2328 +#, c-format +msgid "the database system is in recovery mode" +msgstr "система бази даних у режимі відновлення" + +#: postmaster/postmaster.c:2333 storage/ipc/procarray.c:293 +#: storage/ipc/sinvaladt.c:297 storage/lmgr/proc.c:362 +#, c-format +msgid "sorry, too many clients already" +msgstr "вибачте, вже забагато клієнтів" + +#: postmaster/postmaster.c:2423 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "неправильний ключ в запиті скасування процесу %d" + +#: postmaster/postmaster.c:2435 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "PID %d в запиті на скасування не відповідає жодному процесу" + +#: postmaster/postmaster.c:2706 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "отримано SIGHUP, поновлення файлів конфігурацій" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2732 postmaster/postmaster.c:2736 +#, c-format +msgid "%s was not reloaded" +msgstr "%s не було перезавантажено" + +#: postmaster/postmaster.c:2746 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "Конфігурація протоколу SSL не була перезавантажена" + +#: postmaster/postmaster.c:2802 +#, c-format +msgid "received smart shutdown request" +msgstr "отримано smart запит на завершення роботи" + +#: postmaster/postmaster.c:2848 +#, c-format +msgid "received fast shutdown request" +msgstr "отримано швидкий запит на завершення роботи" + +#: postmaster/postmaster.c:2866 +#, c-format +msgid "aborting any active transactions" +msgstr "переривання будь-яких активних транзакцій" + +#: postmaster/postmaster.c:2890 +#, c-format +msgid "received immediate shutdown request" +msgstr "отримано запит на негайне завершення роботи" + +#: postmaster/postmaster.c:2965 +#, c-format +msgid "shutdown at recovery target" +msgstr "завершення роботи при відновленні мети" + +#: postmaster/postmaster.c:2983 postmaster/postmaster.c:3019 +msgid "startup process" +msgstr "стартовий процес" + +#: postmaster/postmaster.c:2986 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "переривання запуску через помилку в стартовому процесі" + +#: postmaster/postmaster.c:3061 +#, c-format +msgid "database system is ready to accept connections" +msgstr "система бази даних готова до отримання підключення" + +#: postmaster/postmaster.c:3082 +msgid "background writer process" +msgstr "процес фонового запису" + +#: postmaster/postmaster.c:3136 +msgid "checkpointer process" +msgstr "процес контрольних точок" + +#: postmaster/postmaster.c:3152 +msgid "WAL writer process" +msgstr "Процес запису WAL" + +#: postmaster/postmaster.c:3167 +msgid "WAL receiver process" +msgstr "Процес отримання WAL" + +#: postmaster/postmaster.c:3182 +msgid "autovacuum launcher process" +msgstr "процес запуску автоочистки" + +#: postmaster/postmaster.c:3197 +msgid "archiver process" +msgstr "процес архівації" + +#: postmaster/postmaster.c:3213 +msgid "statistics collector process" +msgstr "процес збору статистики" + +#: postmaster/postmaster.c:3227 +msgid "system logger process" +msgstr "процес системного журналювання" + +#: postmaster/postmaster.c:3291 +#, c-format +msgid "background worker \"%s\"" +msgstr "фоновий виконавець \"%s\"" + +#: postmaster/postmaster.c:3375 postmaster/postmaster.c:3395 +#: postmaster/postmaster.c:3402 postmaster/postmaster.c:3420 +msgid "server process" +msgstr "процес сервера" + +#: postmaster/postmaster.c:3474 +#, c-format +msgid "terminating any other active server processes" +msgstr "завершення будь-яких інших активних серверних процесів" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3729 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) завершився з кодом виходу %d" + +#: postmaster/postmaster.c:3731 postmaster/postmaster.c:3743 +#: postmaster/postmaster.c:3753 postmaster/postmaster.c:3764 +#, c-format +msgid "Failed process was running: %s" +msgstr "Процес що завершився виконував дію: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3740 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) був перерваний винятком 0x%X" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3750 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) був перерваний сигналом %d: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3762 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) завершився з нерозпізнаним статусом %d" + +#: postmaster/postmaster.c:3970 +#, c-format +msgid "abnormal database system shutdown" +msgstr "ненормальне завершення роботи системи бази даних" + +#: postmaster/postmaster.c:4010 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "усі серверні процеси перервано; повторна ініціалізація" + +#: postmaster/postmaster.c:4180 postmaster/postmaster.c:5599 +#: postmaster/postmaster.c:5986 +#, c-format +msgid "could not generate random cancel key" +msgstr "не вдалося згенерувати випадковий ключ скасування" + +#: postmaster/postmaster.c:4234 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "не вдалося породити нові процеси для з'єднання: %m" + +#: postmaster/postmaster.c:4276 +msgid "could not fork new process for connection: " +msgstr "не вдалося породити нові процеси для з'єднання: " + +#: postmaster/postmaster.c:4393 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "з'єднання отримано: хост=%s порт=%s" + +#: postmaster/postmaster.c:4398 +#, c-format +msgid "connection received: host=%s" +msgstr "з'єднання отримано: хост=%s" + +#: postmaster/postmaster.c:4668 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "не вдалося виконати серверні процеси \"%s\":%m" + +#: postmaster/postmaster.c:4827 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "кількість повторних спроб резервування спільної пам'яті досягло межі" + +#: postmaster/postmaster.c:4828 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Це може бути викликано антивірусним програмним забезпеченням або ASLR." + +#: postmaster/postmaster.c:5034 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "Не вдалося завантажити конфігурацію SSL в дочірній процес" + +#: postmaster/postmaster.c:5166 +#, c-format +msgid "Please report this to <%s>." +msgstr "Будь-ласка повідомте про це <%s>." + +#: postmaster/postmaster.c:5259 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "система бази даних готова до отримання підключення \"лише читати\"" + +#: postmaster/postmaster.c:5527 +#, c-format +msgid "could not fork startup process: %m" +msgstr "не вдалося породити стартовий процес: %m" + +#: postmaster/postmaster.c:5531 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "не вдалося породити фоновий процес запису: %m" + +#: postmaster/postmaster.c:5535 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "не вдалося породити процес контрольних точок: %m" + +#: postmaster/postmaster.c:5539 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "не вдалося породити процес запису WAL: %m" + +#: postmaster/postmaster.c:5543 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "не вдалося породити процес отримання WAL: %m" + +#: postmaster/postmaster.c:5547 +#, c-format +msgid "could not fork process: %m" +msgstr "не вдалося породити процес: %m" + +#: postmaster/postmaster.c:5744 postmaster/postmaster.c:5767 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "під час реєстрації не вказувалося, що вимагається підключення до бази даних" + +#: postmaster/postmaster.c:5751 postmaster/postmaster.c:5774 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "неприпустимий режим обробки у фоновому записі" + +#: postmaster/postmaster.c:5847 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "початок процесу фонового запису \"%s\"" + +#: postmaster/postmaster.c:5859 +#, c-format +msgid "could not fork worker process: %m" +msgstr "не вдалося породити процес запису: %m" + +#: postmaster/postmaster.c:5972 +#, c-format +msgid "no slot available for new worker process" +msgstr "немає доступного слоту для нового робочого процесу" + +#: postmaster/postmaster.c:6307 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "не вдалося продублювати сокет %d для використання: код помилки %d" + +#: postmaster/postmaster.c:6339 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "не вдалося створити успадкований сокет: код помилки %d\n" + +#: postmaster/postmaster.c:6368 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "не вдалося відкрити внутрішні змінні файли \"%s\": %s\n" + +#: postmaster/postmaster.c:6375 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "не вдалося прочитати внутрішні змінні файли \"%s\": %s\n" + +#: postmaster/postmaster.c:6384 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "не вдалося видалити файл \"%s\": %s\n" + +#: postmaster/postmaster.c:6401 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "не вдалося відобразити файл серверних змінних: код помилки %lu\n" + +#: postmaster/postmaster.c:6410 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "не вдалося вимкнути відображення файлу серверних змінних: код помилки %lu\n" + +#: postmaster/postmaster.c:6417 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "не вдалося закрити покажчик файлу серверних змінних: код помилки %lu\n" + +#: postmaster/postmaster.c:6595 +#, c-format +msgid "could not read exit code for process\n" +msgstr "не вдалося прочитати код завершення процесу\n" + +#: postmaster/postmaster.c:6600 +#, c-format +msgid "could not post child completion status\n" +msgstr "не вдалося надіслати статус завершення нащадка\n" + +#: postmaster/syslogger.c:474 postmaster/syslogger.c:1153 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "не вдалося прочитати з каналу журналювання: %m" + +#: postmaster/syslogger.c:522 +#, c-format +msgid "logger shutting down" +msgstr "завершення журналювання" + +#: postmaster/syslogger.c:571 postmaster/syslogger.c:585 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "не вдалося створити канал для syslog: %m" + +#: postmaster/syslogger.c:636 +#, c-format +msgid "could not fork system logger: %m" +msgstr "не вдалося породити процес системного журналювання: %m" + +#: postmaster/syslogger.c:672 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "переспрямовування виводу в протокол прочесу збирача протоколів" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "Наступні протоколи будуть виводитись в каталог \"%s\"." + +#: postmaster/syslogger.c:681 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "не вдалося переспрямувати stdout: %m" + +#: postmaster/syslogger.c:686 postmaster/syslogger.c:703 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "не вдалося переспрямувати stderr: %m" + +#: postmaster/syslogger.c:1108 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "не вдалося записати до файлу протокола: %s\n" + +#: postmaster/syslogger.c:1225 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "не вдалося відкрити файл протоколу \"%s\": %m" + +#: postmaster/syslogger.c:1287 postmaster/syslogger.c:1337 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "вимкнення автоматичного обертання (щоб повторно ввімкнути, використайте SIGHUP)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "не вдалося визначити які параметри сортування використати для регулярного виразу" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "недетерміновані правила сортування не підтримуються для регулярних виразів" + +#: replication/backup_manifest.c:231 +#, c-format +msgid "expected end timeline %u but found timeline %u" +msgstr "очікувався кінець часової шкали %u але знайдено часову шкалу %u" + +#: replication/backup_manifest.c:248 +#, c-format +msgid "expected start timeline %u but found timeline %u" +msgstr "очікувався початок часової шкали %u але знайдено часову шкалу %u" + +#: replication/backup_manifest.c:275 +#, c-format +msgid "start timeline %u not found in history of timeline %u" +msgstr "початок часової шкали %u не знайдено в історії часової шкали %u" + +#: replication/backup_manifest.c:322 +#, c-format +msgid "could not rewind temporary file" +msgstr "не вдалося перемотати назад тимчасовий файл" + +#: replication/backup_manifest.c:349 +#, c-format +msgid "could not read from temporary file: %m" +msgstr "не вдалося прочитати з тимчасового файлу: %m" + +#: replication/basebackup.c:108 +#, c-format +msgid "could not read from file \"%s\"" +msgstr "не вдалося прочитати з файлу \"%s\"" + +#: replication/basebackup.c:551 +#, c-format +msgid "could not find any WAL files" +msgstr "не вдалося знайти ні одного файла WAL" + +#: replication/basebackup.c:566 replication/basebackup.c:582 +#: replication/basebackup.c:591 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "не вдалося знайти файл WAL \"%s\"" + +#: replication/basebackup.c:634 replication/basebackup.c:665 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "неочікуаний розмір файлу WAL \"%s\"" + +#: replication/basebackup.c:648 replication/basebackup.c:1752 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "в процесі базового резервного копіювання не вдалося передати дані, копіювання переривається" + +#: replication/basebackup.c:724 +#, c-format +msgid "%lld total checksum verification failure" +msgid_plural "%lld total checksum verification failures" +msgstr[0] "всього помилок перевірки контрольних сум: %lld" +msgstr[1] "всього помилок перевірки контрольних сум: %lld" +msgstr[2] "всього помилок перевірки контрольних сум: %lld" +msgstr[3] "всього помилок перевірки контрольних сум: %lld" + +#: replication/basebackup.c:731 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "під час базового резервного копіювання виявлено неполадки контрольних сум" + +#: replication/basebackup.c:784 replication/basebackup.c:793 +#: replication/basebackup.c:802 replication/basebackup.c:811 +#: replication/basebackup.c:820 replication/basebackup.c:831 +#: replication/basebackup.c:848 replication/basebackup.c:857 +#: replication/basebackup.c:869 replication/basebackup.c:893 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "повторюваний параметр \"%s\"" + +#: replication/basebackup.c:837 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d за припустимим діапазномо для параметру \"%s\" (%d .. %d)" + +#: replication/basebackup.c:882 +#, c-format +msgid "unrecognized manifest option: \"%s\"" +msgstr "нерозпізнаний параметр маніфесту: \"%s\"" + +#: replication/basebackup.c:898 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "нерозпізнаний алгоритм контрольної суми: \"%s\"" + +#: replication/basebackup.c:913 +#, c-format +msgid "manifest checksums require a backup manifest" +msgstr "контрольні суми маніфесту потребують резервного копіювання маніфесту" + +#: replication/basebackup.c:1504 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "спеціальний файл \"%s\" пропускається" + +#: replication/basebackup.c:1623 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "неприпустимий номер сегменту %d в файлі \"%s\"" + +#: replication/basebackup.c:1642 +#, c-format +msgid "could not verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "не вдалося перевірити контрольну суму у файлі \"%s\", блок %d: зчитаний розмір буфера %d і розмір сторінки %d відрізняються" + +#: replication/basebackup.c:1686 replication/basebackup.c:1716 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "не вдалося переміститись в файлі \"%s\": %m" + +#: replication/basebackup.c:1708 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "не вдалося перечитати блок %d файлу \"%s\": %m" + +#: replication/basebackup.c:1732 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "помилка перевірки контрольної суми в файлі \"%s\", блоку %d: обчислено %X, але очікувалось %X" + +#: replication/basebackup.c:1739 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "про подальші помилки під час перевірки контрольної суми в файлі \"%s\" повідомлятись не буде" + +#: replication/basebackup.c:1807 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failure" +msgid_plural "file \"%s\" has a total of %d checksum verification failures" +msgstr[0] "файл \"%s\" має загальну кількість помилок перевірки контрольної суми: %d" +msgstr[1] "файл \"%s\" має загальну кількість помилок перевірки контрольної суми: %d" +msgstr[2] "файл \"%s\" має загальну кількість помилок перевірки контрольної суми: %d" +msgstr[3] "файл \"%s\" має загальну кількість помилок перевірки контрольної суми: %d" + +#: replication/basebackup.c:1843 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "ім'я файлу занадто довге для tar формату: \"%s\"" + +#: replication/basebackup.c:1848 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "мета символьного посилання занадто довга для формату tar: ім'я файлу \"%s\", мета \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:227 +#, c-format +msgid "could not clear search path: %s" +msgstr "не вдалося очистити шлях пошуку: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:251 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "неприпустимий синтаксис рядка підключення: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:275 +#, c-format +msgid "could not parse connection string: %s" +msgstr "не вдалося аналізувати рядок підключення: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:347 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "не вдалося отримати ідентифікатор системи бази даних та ідентифікатор часової шкали з основного серверу: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:358 +#: replication/libpqwalreceiver/libpqwalreceiver.c:576 +#, c-format +msgid "invalid response from primary server" +msgstr "неприпустима відповідь з основного серверу" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:359 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "Не вдалося ідентифікувати систему: отримано %d рядків і %d полів, очікувалось %d рядків і %d або більше полів." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:432 +#: replication/libpqwalreceiver/libpqwalreceiver.c:438 +#: replication/libpqwalreceiver/libpqwalreceiver.c:463 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "не вдалося почати потокове передавання WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:486 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "не вдалося передати основному серверу повідомлення про кінець передвання: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:508 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "неочікуваний набір результатів після кінця передачі" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:522 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "помилка при завершенні потокового передавання \"копіювати\": %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:531 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "помилка при читанні результату команди потокового передавання: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 +#: replication/libpqwalreceiver/libpqwalreceiver.c:773 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "неочікуваний результат CommandComplete: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:565 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "не вдалося отримати файл історії часової шкали з основного сервера: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:577 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "Очікувалося 1 кортеж з 2 поле, отримано %d кортежів з %d полями." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:737 +#: replication/libpqwalreceiver/libpqwalreceiver.c:788 +#: replication/libpqwalreceiver/libpqwalreceiver.c:794 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "не вдалося отримати дані з WAL потоку: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:813 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "не вдалося передати дані потоку WAL: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:866 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "не вдалося створити слот реплікації \"%s\": %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:911 +#, c-format +msgid "invalid query response" +msgstr "неприпустима відповідь на запит" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:912 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "Очікувалося %d полів, отримано %d полі." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:981 +#, c-format +msgid "the query interface requires a database connection" +msgstr "інтерфейс запитів вимагає підключення до бази даних" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:1012 +msgid "empty query" +msgstr "пустий запит" + +#: replication/logical/launcher.c:295 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "початок логічного запису реплікації для передплати \"%s\"" + +#: replication/logical/launcher.c:302 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "неможливо почати логічні записи реплікацій, коли max_replication_slots = 0" + +#: replication/logical/launcher.c:382 +#, c-format +msgid "out of logical replication worker slots" +msgstr "недостатньо слотів для процесів логічної реплікації" + +#: replication/logical/launcher.c:383 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "Можливо, вам слід збільшити max_logical_replication_workers." + +#: replication/logical/launcher.c:438 +#, c-format +msgid "out of background worker slots" +msgstr "недостатньо слотів для фонових робочих процесів" + +#: replication/logical/launcher.c:439 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "Можливо, вам слід збільшити max_worker_processes." + +#: replication/logical/launcher.c:638 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "слот запису логічної реплікації %d пустий, неможливо підключитися" + +#: replication/logical/launcher.c:647 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "слот запису логічної реплікації %d вже використовується іншим виконавцем, неможливо підключитися" + +#: replication/logical/launcher.c:951 +#, c-format +msgid "logical replication launcher started" +msgstr "запуск логічної реплікації почався" + +#: replication/logical/logical.c:87 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "логічне декодування вимагає wal_level >= logical" + +#: replication/logical/logical.c:92 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "логічне декодування вимагає підключення до бази даних" + +#: replication/logical/logical.c:110 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "логічне декодування неможливо використовувати під час відновлення" + +#: replication/logical/logical.c:258 replication/logical/logical.c:399 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "неможливо використовувати слот невідповідної реплікації для логічного кодування" + +#: replication/logical/logical.c:263 replication/logical/logical.c:404 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "слот реплікації \"%s\" був створений не в цій базі даних" + +#: replication/logical/logical.c:270 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "неможливо створити слот логічної реплікації у транзакції, що виконує записування" + +#: replication/logical/logical.c:444 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "початок логічного декодування для слоту \"%s\"" + +#: replication/logical/logical.c:446 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Потокове передавання транзакцій, що затверджені, після %X/%X, читання WAL з %X/%X." + +#: replication/logical/logical.c:593 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "слот \"%s\", плагін виходу \"%s\", у зворотньому виклику %s, пов'язаний номер LSN %X/%X" + +#: replication/logical/logical.c:600 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "слот \"%s\", плагін виходу \"%s\", у зворотньому виклику %s" + +#: replication/logical/logicalfuncs.c:104 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "має бути право суперкористувача або реплікації для використання реплікаційних слотів" + +#: replication/logical/logicalfuncs.c:134 +#, c-format +msgid "slot name must not be null" +msgstr "ім'я слоту має бути не Null-значення" + +#: replication/logical/logicalfuncs.c:150 +#, c-format +msgid "options array must not be null" +msgstr "масив параметрів має бути не Null-значення" + +#: replication/logical/logicalfuncs.c:181 +#, c-format +msgid "array must be one-dimensional" +msgstr "масив має бути одновимірним" + +#: replication/logical/logicalfuncs.c:187 +#, c-format +msgid "array must not contain nulls" +msgstr "масив не має включати nulls" + +#: replication/logical/logicalfuncs.c:203 utils/adt/json.c:1128 +#: utils/adt/jsonb.c:1303 +#, c-format +msgid "array must have even number of elements" +msgstr "масив повинен мати парну кількість елементів" + +#: replication/logical/logicalfuncs.c:251 +#, c-format +msgid "can no longer get changes from replication slot \"%s\"" +msgstr "більше не можна отримувати зміни з слоту реплікації \"%s\"" + +#: replication/logical/logicalfuncs.c:253 replication/slotfuncs.c:648 +#, c-format +msgid "This slot has never previously reserved WAL, or has been invalidated." +msgstr "Цей слот ніколи раніше не резервував WAL, або не був недійсним." + +#: replication/logical/logicalfuncs.c:265 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "плагін виходу логічного декодування \"%s\" виробляє бінарний вихід, але функція \"%s\" очікує текстові дані" + +#: replication/logical/origin.c:188 +#, c-format +msgid "only superusers can query or manipulate replication origins" +msgstr "лише суперкористувачі можуть вимагати або маніпулювати джерелами реплікації" + +#: replication/logical/origin.c:193 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "неможливо вимагати або маніпулювати джерелами реплікації, коли max_replication_slots = 0" + +#: replication/logical/origin.c:198 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "неможливо маніпулювати джерелами реплікації під час відновлення" + +#: replication/logical/origin.c:233 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "джерело реплікації \"%s\" не існує" + +#: replication/logical/origin.c:324 +#, c-format +msgid "could not find free replication origin OID" +msgstr "не вдалося знайти вільний ідентифікатор OID джерела реплікації" + +#: replication/logical/origin.c:372 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "не вдалося розірвати джерело реплікації з ідентифікатором OID %d, використовується PID %d" + +#: replication/logical/origin.c:464 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "джерело реплікації з ідентифікатором OID %u не існує" + +#: replication/logical/origin.c:729 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "контрольна точка реплікації має неправильну сигнатуру %u замість %u" + +#: replication/logical/origin.c:770 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "не вдалося знайти вільний слот для стану реплікації, збільшіть max_replication_slots" + +#: replication/logical/origin.c:788 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "неправильна контрольна сума файлу контрольної точки для слота реплікації %u, очікувалось %u" + +#: replication/logical/origin.c:916 replication/logical/origin.c:1102 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "джерело реплікації з OID %d вже активний для PID %d" + +#: replication/logical/origin.c:927 replication/logical/origin.c:1114 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "не вдалося знайти вільний слот стану реплікації для джерела реплікації з OID %u" + +#: replication/logical/origin.c:929 replication/logical/origin.c:1116 +#: replication/slot.c:1762 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "Збільшіть max_replication_slots і спробуйте знову." + +#: replication/logical/origin.c:1073 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "не можна налаштувати джерело реплікації, коли один вже налаштований" + +#: replication/logical/origin.c:1153 replication/logical/origin.c:1369 +#: replication/logical/origin.c:1389 +#, c-format +msgid "no replication origin is configured" +msgstr "жодне джерело реплікації не налаштоване" + +#: replication/logical/origin.c:1236 +#, c-format +msgid "replication origin name \"%s\" is reserved" +msgstr "назва джерела реплікації \"%s\" зарезервована" + +#: replication/logical/origin.c:1238 +#, c-format +msgid "Origin names starting with \"pg_\" are reserved." +msgstr "Назви джерел, які починаються на \"pg_\" зарезервовані." + +#: replication/logical/relation.c:302 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "цільове відношення логічної реплікації \"%s.%s\" не існує" + +#: replication/logical/relation.c:345 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "в цільовому відношенні логічної реплікації \"%s.%s\" пропущені деякі репліковані стовпці" + +#: replication/logical/relation.c:385 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "в цільовому відношенні логічної реплікації \"%s.%s\" в індексі REPLICA IDENTITY використовуються системні стовпці" + +#: replication/logical/reorderbuffer.c:2663 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "не вдалося записати у файл даних для XID %u: %m" + +#: replication/logical/reorderbuffer.c:2850 +#: replication/logical/reorderbuffer.c:2875 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "не вдалося прочитати з файлу розгортання буферу пересортування: %m" + +#: replication/logical/reorderbuffer.c:2854 +#: replication/logical/reorderbuffer.c:2879 +#, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "не вдалося прочитати з файлу розгортання буферу пересортування: прочитано %d замість %u байт" + +#: replication/logical/reorderbuffer.c:3114 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "не вдалося видалити файл \"%s\" під час видалення pg_replslot/%s/xid*: %m" + +#: replication/logical/reorderbuffer.c:3606 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "не вдалося прочитати з файлу \"%s\": прочитано %d замість %d байт" + +#: replication/logical/snapbuild.c:606 +#, c-format +msgid "initial slot snapshot too large" +msgstr "початковий знімок слота занадто великий" + +#: replication/logical/snapbuild.c:660 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "експортовано знімок логічного декодування \"%s\" з %u ID транзакцією" +msgstr[1] "експортовано знімок логічного декодування \"%s\" з %u ID транзакціями" +msgstr[2] "експортовано знімок логічного декодування \"%s\" з %u ID транзакціями" +msgstr[3] "експортовано знімок логічного декодування \"%s\" з %u ID транзакціями" + +#: replication/logical/snapbuild.c:1265 replication/logical/snapbuild.c:1358 +#: replication/logical/snapbuild.c:1912 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "узгодження процесу логічного кодування знайдено в точці %X/%X" + +#: replication/logical/snapbuild.c:1267 +#, c-format +msgid "There are no running transactions." +msgstr "Більше активних транзакцій немає." + +#: replication/logical/snapbuild.c:1309 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "початкова стартова точка процесу логічного декодування знайдена в точці %X/%X" + +#: replication/logical/snapbuild.c:1311 replication/logical/snapbuild.c:1335 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Очікування транзакцій (приблизно %d) старіше, ніж %u до кінця." + +#: replication/logical/snapbuild.c:1333 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "початкова точка узгодження процесу логічного кодування знайдена в точці %X/%X" + +#: replication/logical/snapbuild.c:1360 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Більше старих транзакцій немає." + +#: replication/logical/snapbuild.c:1754 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "файл стану snapbuild \"%s\" має неправильне магічне число: %u замість %u" + +#: replication/logical/snapbuild.c:1760 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "файл стану snapbuild \"%s\" має непідтримуючу версію: %u замість %u" + +#: replication/logical/snapbuild.c:1859 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "у файлі стану snapbuild \"%s\" невідповідність контрольної суми: %u, повинно бути %u" + +#: replication/logical/snapbuild.c:1914 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "Логічне декодування почнеться зі збереженого знімку." + +#: replication/logical/snapbuild.c:1986 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "не вдалося аналізувати ім'я файлу \"%s\"" + +#: replication/logical/tablesync.c:132 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "процес синхронізації таблиці при логічній реплікації для підписки \"%s\", таблиці \"%s\" закінчив обробку" + +#: replication/logical/tablesync.c:664 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "не вдалося отримати інформацію про таблицю \"%s.%s\" з серверу публікації: %s" + +#: replication/logical/tablesync.c:670 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "таблиця \"%s.%s\" не знайдена на сервері публікації" + +#: replication/logical/tablesync.c:704 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "не вдалося отримати інформацію про таблицю \"%s.%s\": %s" + +#: replication/logical/tablesync.c:791 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "не вдалося почати копіювання початкового змісту таблиці \"%s.%s\": %s" + +#: replication/logical/tablesync.c:905 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "під час копіювання таблиці не вдалося почати транзакцію на сервері публікації" + +#: replication/logical/tablesync.c:927 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "під час копіювання таблиці не вдалося завершити транзакцію на сервері публікації" + +#: replication/logical/worker.c:313 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "обробка віддалених даних для цільового зв'язку реплікації \"%s.%s\" стовпця \"%s\", віддалений тип %s, локальний тип %s" + +#: replication/logical/worker.c:552 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "Повідомлення ORIGIN відправлено недоречно" + +#: replication/logical/worker.c:702 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "сервер публікації не передав стовпець ідентифікації репліки очікуваний для цільового зв'язку логічної реплікації \"%s.%s\"" + +#: replication/logical/worker.c:709 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "в цільовому зв'язку логічної реплікації \"%s.%s\" немає ні індексу REPLICA IDENTITY, ні ключа PRIMARY KEY і публіковаий зв'язок не має REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:1394 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "неприпустимий тип повідомлення логічної реплікації \"%c\"" + +#: replication/logical/worker.c:1537 +#, c-format +msgid "data stream from publisher has ended" +msgstr "потік даних з серверу публікації завершився" + +#: replication/logical/worker.c:1692 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "завершення процесу логічної реплікації через тайм-аут" + +#: replication/logical/worker.c:1837 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" буде зупинено, тому, що підписка була видалена" + +#: replication/logical/worker.c:1851 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" буде зупинено, тому, що підписка була вимкнута" + +#: replication/logical/worker.c:1865 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" буде перезавантажено, тому, що інформація про підключення була змінена" + +#: replication/logical/worker.c:1879 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" буде перезавантажено, тому, що підписка була перейменована" + +#: replication/logical/worker.c:1896 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" буде перезавантажено, тому, що ім'я слоту реплікації було змінено" + +#: replication/logical/worker.c:1910 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" буде перезавантажено, тому, що публікації підписки були змінені" + +#: replication/logical/worker.c:2006 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "застосовуючий процес логічної реплікації для підписки %u не буде почато, тому, що підписка була видалена під час запуску" + +#: replication/logical/worker.c:2018 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" не буде почато, тому, що підписка була вимкнута під час запуску" + +#: replication/logical/worker.c:2036 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "просец синхронізації таблиці під час логічної реплікації для підписки \"%s\", таблиці \"%s\" запущений" + +#: replication/logical/worker.c:2040 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "застосовуючий процес логічної реплікації для підписки \"%s\" запущений" + +#: replication/logical/worker.c:2079 +#, c-format +msgid "subscription has no replication slot set" +msgstr "для підписки не встановлений слот реплікації" + +#: replication/pgoutput/pgoutput.c:147 +#, c-format +msgid "invalid proto_version" +msgstr "неприпустиме значення proto_version" + +#: replication/pgoutput/pgoutput.c:152 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "значення proto_version \"%s\" за межами діапазону" + +#: replication/pgoutput/pgoutput.c:169 +#, c-format +msgid "invalid publication_names syntax" +msgstr "неприпустимий синтаксис publication_names" + +#: replication/pgoutput/pgoutput.c:211 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "клієнт передав proto_version=%d, але ми підтримуємо лише протокол %d або нижче" + +#: replication/pgoutput/pgoutput.c:217 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "клієнт передав proto_version=%d, але ми підтримуємо лише протокол %d або вище" + +#: replication/pgoutput/pgoutput.c:223 +#, c-format +msgid "publication_names parameter missing" +msgstr "пропущено параметр publication_names" + +#: replication/slot.c:183 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "ім'я слоту реплікації \"%s\" занадто коротке" + +#: replication/slot.c:192 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "ім'я слоту реплікації \"%s\" занадто довге" + +#: replication/slot.c:205 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "ім'я слоту реплікації \"%s\" містить неприпустимий символ" + +#: replication/slot.c:207 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "Імена слота реплікації можуть містити лише букви в нижньому кейсі, числа, і символ підкреслення." + +#: replication/slot.c:254 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "слот реплікації \"%s\" вже існує" + +#: replication/slot.c:264 +#, c-format +msgid "all replication slots are in use" +msgstr "використовуються всі слоти реплікації" + +#: replication/slot.c:265 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Звільніть непотрібні або збільшіть max_replication_slots." + +#: replication/slot.c:407 replication/slotfuncs.c:760 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "слот реплікації \"%s\" не існує" + +#: replication/slot.c:445 replication/slot.c:1006 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "слот реплікації \"%s\" активний для PID %d" + +#: replication/slot.c:683 replication/slot.c:1314 replication/slot.c:1697 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "не вдалося видалити каталог \"%s\"" + +#: replication/slot.c:1041 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "слоти реплікації можна використовувати лише якщо max_replication_slots > 0" + +#: replication/slot.c:1046 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "слоти реплікації можна використовувати лише якщо wal_level >= replica" + +#: replication/slot.c:1202 +#, c-format +msgid "terminating process %d because replication slot \"%s\" is too far behind" +msgstr "завершення процесу %d тому, що слот реплікації \"%s\" занадто далеко позаду" + +#: replication/slot.c:1221 +#, c-format +msgid "invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size" +msgstr "припинення слоту \"%s\" тому, що його restart_lsn %X/%X перевищує max_slot_wal_keep_size" + +#: replication/slot.c:1635 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "файл слоту реплікації \"%s\" має неправильне магічне число: %u замість %u" + +#: replication/slot.c:1642 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "файл слоту реплікації \"%s\" має непідтримуючу версію %u" + +#: replication/slot.c:1649 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "файл слоту реплікації \"%s\" має пошкоджену довжину %u" + +#: replication/slot.c:1685 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "у файлі слоту реплікації \"%s\" невідповідність контрольної суми: %u, повинно бути %u" + +#: replication/slot.c:1719 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "слот логічної реплікації \"%s\" існує, але wal_level < logical" + +#: replication/slot.c:1721 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Змініть wal_level на logical або вище." + +#: replication/slot.c:1725 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "слот фізичної реплікації \"%s\" існує, але wal_level < replica" + +#: replication/slot.c:1727 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Змініть wal_level на replica або вище." + +#: replication/slot.c:1761 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "перед завершенням роботи активно занадто багато слотів реплікації" + +#: replication/slotfuncs.c:624 +#, c-format +msgid "invalid target WAL LSN" +msgstr "неприпустима ціль WAL LSN" + +#: replication/slotfuncs.c:646 +#, c-format +msgid "replication slot \"%s\" cannot be advanced" +msgstr "слот реплікації \"%s\" не може бути розширеним" + +#: replication/slotfuncs.c:664 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "просунути слот реплікації до позиції %X/%X не можна, мінімальна позиція %X/%X" + +#: replication/slotfuncs.c:772 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "не можна скопіювати слот фізичної реплікації \"%s\" як слот логічної реплікації" + +#: replication/slotfuncs.c:774 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "не можна скопіювати слот логічної реплікації \"%s\" як слот фізичної реплікації" + +#: replication/slotfuncs.c:781 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "не можна скопіювати слот реплікації, який не резервує WAL" + +#: replication/slotfuncs.c:857 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "не вдалося скопіювати слот реплікації \"%s\"" + +#: replication/slotfuncs.c:859 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "Слот реплікації джерела був змінений несумісно під час операції копіювання." + +#: replication/slotfuncs.c:865 +#, c-format +msgid "cannot copy unfinished logical replication slot \"%s\"" +msgstr "не можна скопіювати незавершений слот логічної реплікації \"%s\"" + +#: replication/slotfuncs.c:867 +#, c-format +msgid "Retry when the source replication slot's confirmed_flush_lsn is valid." +msgstr "Повторіть, коли confirmed_flush_lsn слоту джерела реплікації є дійсним." + +#: replication/syncrep.c:257 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "скасування очікування синхронної реплікації і завершення з'єднання по команді адміністратора" + +#: replication/syncrep.c:258 replication/syncrep.c:275 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "Транзакція вже була затверджена локально, але можливо не була реплікована до режиму очікування." + +#: replication/syncrep.c:274 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "скасування очікування синхронної реплікації по запиту користувача" + +#: replication/syncrep.c:416 +#, c-format +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "режим очікування \"%s\" зараз має пріоритет синхронної реплікації %u" + +#: replication/syncrep.c:483 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "режим очікування \"%s\" зараз є синхронним з пріоритетом %u" + +#: replication/syncrep.c:487 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "режим очікування \"%s\" зараз є кандидатом для включення в кворум синхронних" + +#: replication/syncrep.c:1034 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "помилка при аналізуванні synchronous_standby_names" + +#: replication/syncrep.c:1040 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "кількість синхронних режимів очікування (%d) повинно бути більше нуля" + +#: replication/walreceiver.c:171 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "завершення процесу walreceiver по команді адміністратора" + +#: replication/walreceiver.c:297 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "не вдалося підключитися до основного серверу: %s" + +#: replication/walreceiver.c:343 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "ідентифікатор системи бази даних на основному і резервному серверах відрізняються" + +#: replication/walreceiver.c:344 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "Ідентифікатор на основному сервері %s, на резервному %s." + +#: replication/walreceiver.c:354 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "остання часова шкала %u на основному сервері відстає від відновлюючої часової шкали %u" + +#: replication/walreceiver.c:408 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "запущено потокове передавання WAL з основного серверу з позиції %X/%X на часовій шкалі %u" + +#: replication/walreceiver.c:413 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "перезапуска потокового передавання WAL з позиції %X/%X на часовій шкалі %u" + +#: replication/walreceiver.c:442 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "продовжити потокове передавання WAL не можна, відновлення вже завершено" + +#: replication/walreceiver.c:479 +#, c-format +msgid "replication terminated by primary server" +msgstr "реплікація завершена основним сервером" + +#: replication/walreceiver.c:480 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "На часовій шкалі %u в позиції %X/%X WAL досяг кінця." + +#: replication/walreceiver.c:568 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "завершення процесу walreceiver через тайм-аут" + +#: replication/walreceiver.c:606 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "основний сервер більше не містить WAL для запитаної часової шкали %u" + +#: replication/walreceiver.c:622 replication/walreceiver.c:929 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "не вдалося закрити сегмент журналу %s: %m" + +#: replication/walreceiver.c:742 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "отримання файлу історії часової шкали для часової шкали %u з основного серверу" + +#: replication/walreceiver.c:976 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "не вдалося записати в сегмент журналу %s зсув %u, довжина %lu: %m" + +#: replication/walsender.c:523 storage/smgr/md.c:1291 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "не вдалося досягти кінця файлу \"%s\": %m" + +#: replication/walsender.c:527 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "не вдалося знайти початок файлу \"%s\": %m" + +#: replication/walsender.c:578 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "Команда IDENTIFY_SYSTEM не виконувалась до START_REPLICATION" + +#: replication/walsender.c:607 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "використовувати логічний слот реплікації для фізичної реплікації, не можна" + +#: replication/walsender.c:676 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "в історії серверу немає запитаної початкової точки %X/%X на часовій шкалі %u" + +#: replication/walsender.c:680 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "Історія цього серверу відгалузилась від часової шкали %u в позиції %X/%X." + +#: replication/walsender.c:725 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "запитана початкова точка %X/%X попереду позиція очищених даних WAL на цьому сервері %X/%X" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:976 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s не має викликатися всередині транзакції" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:986 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s має викликатися всередині транзакції" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:992 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s повинен бути викликаний в режимі ізоляції REPEATABLE READ" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:998 +#, c-format +msgid "%s must be called before any query" +msgstr "%s має викликатися до будь-якого запиту" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:1004 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s не має викликатися всередині підтранзакції" + +#: replication/walsender.c:1148 +#, c-format +msgid "cannot read from logical replication slot \"%s\"" +msgstr "не можна прочитати із слоту логічної реплікації \"%s\"" + +#: replication/walsender.c:1150 +#, c-format +msgid "This slot has been invalidated because it exceeded the maximum reserved size." +msgstr "Цей слот визнано недійсним, тому що він перевищив максимально зарезервований розмір." + +#: replication/walsender.c:1160 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "завершення процесу walsender після підвищення" + +#: replication/walsender.c:1534 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "не можна виконувати нові команди, поки процес відправки WAL знаходиться в режимі зупинки" + +#: replication/walsender.c:1567 +#, c-format +msgid "received replication command: %s" +msgstr "отримано команду реплікації: %s" + +#: replication/walsender.c:1583 tcop/fastpath.c:279 tcop/postgres.c:1103 +#: tcop/postgres.c:1455 tcop/postgres.c:1716 tcop/postgres.c:2174 +#: tcop/postgres.c:2535 tcop/postgres.c:2614 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "поточна транзакція перервана, команди до кінця блока транзакції пропускаються" + +#: replication/walsender.c:1669 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "не можна виконувати команди SQL в процесі відправки WAL для фізичної реплікації" + +#: replication/walsender.c:1714 replication/walsender.c:1730 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "неочікуваний обрив з'єднання з резервним сервером" + +#: replication/walsender.c:1744 +#, c-format +msgid "unexpected standby message type \"%c\", after receiving CopyDone" +msgstr "після отримання CopyDone резервний сервер передав повідомлення неочікуваного типу \"%c\"" + +#: replication/walsender.c:1782 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "неприпустимий тип повідомлення резервного серверу \"%c\"" + +#: replication/walsender.c:1823 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "неочікуваний тип повідомлення \"%c\"" + +#: replication/walsender.c:2241 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "завершення процесу walsender через тайм-аут реплікації" + +#: replication/walsender.c:2318 +#, c-format +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\" зараз надолужив висхідний сервер" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:989 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "правило \"%s\" для зв'язка \"%s\" вже існує" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "дії правил для OLD не реалізовані" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "Використайте подання або тригери замість." + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "дії правил для NEW не реалізовані" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "Використайте тригери замість." + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "Правила INSTEAD NOTHING для SELECT не реалізовані" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "Використайте подання замість." + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "декілька дій в правилах для SELECT не реалізовані" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "правила для SELECT повинні мати дію INSTEAD SELECT" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "правила для SELECT не повинні містити операторів, які змінюють дані в WITH" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "в правилах для SELECT не може бути умов" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "\"%s\" вже є поданням" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "правило подання для \"%s\" повинно називатися \"%s\"" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "перетворити секціоновану таблицю \"%s\" на подання, не можна" + +#: rewrite/rewriteDefine.c:440 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "перетворити секцію \"%s\" на подання, не можна" + +#: rewrite/rewriteDefine.c:449 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "не вдалося перетворити таблицю \"%s\" на подання, тому, що вона не пуста" + +#: rewrite/rewriteDefine.c:458 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "не вдалося перетворити таблицю \"%s\" на подання, тому, що вона має тригери" + +#: rewrite/rewriteDefine.c:460 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "Крім того, таблиця не може бути включена в зв'язок зовнішніх ключів." + +#: rewrite/rewriteDefine.c:465 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "не вдалося перетворити таблицю \"%s\" на подання, тому, що вона має індекси" + +#: rewrite/rewriteDefine.c:471 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "не вдалося перетворити таблицю \"%s\" на подання, тому, що вона має дочірні таблиці" + +#: rewrite/rewriteDefine.c:477 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "не вдалося перетворити таблицю \"%s\" на подання, тому, що для неї активований захист на рівні рядків" + +#: rewrite/rewriteDefine.c:483 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "не вдалося перетворити таблицю \"%s\" на подання, тому, що вона має політику захисту рядків" + +#: rewrite/rewriteDefine.c:510 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "правило не може мати декілька списків RETURNING" + +#: rewrite/rewriteDefine.c:515 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "Умовні правила не підтримують списки RETURNING" + +#: rewrite/rewriteDefine.c:519 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "Правила non-INSTEAD не підтримують списки RETURNING" + +#: rewrite/rewriteDefine.c:683 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "Список цілей правила для SELECT має занадто багато елементів" + +#: rewrite/rewriteDefine.c:684 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "Список RETURNING має занадто багато елементів" + +#: rewrite/rewriteDefine.c:711 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "перетворити зв'язок, який містить видаленні стовпці, на подання не можна" + +#: rewrite/rewriteDefine.c:712 +#, c-format +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "створити список RETURNING для зв'язка, який містить видаленні стовпці, не можна" + +#: rewrite/rewriteDefine.c:718 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "Елемент результата правила для SELECT %d відрізняється іменем стовпця від стовпця \"%s\"" + +#: rewrite/rewriteDefine.c:720 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "Ім'я елемента результату SELECT \"%s\"." + +#: rewrite/rewriteDefine.c:729 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "Елемент результата правила для SELECT %d відрізняється типом від стовпця \"%s\"" + +#: rewrite/rewriteDefine.c:731 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "Елемент списку RETURNING %d відрізняється типом від стовпця \"%s\"" + +#: rewrite/rewriteDefine.c:734 rewrite/rewriteDefine.c:758 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "Елемент результату SELECT має тип %s, але стовпець має тип %s." + +#: rewrite/rewriteDefine.c:737 rewrite/rewriteDefine.c:762 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "Елемент списку RETURNING має тип %s, але стовпець має тип %s." + +#: rewrite/rewriteDefine.c:753 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "Елемент результата правил для SELECT %d відрізняється розміром від стовпця \"%s\"" + +#: rewrite/rewriteDefine.c:755 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "Елемент списку RETURNING %d відрізняється розміром від стовпця \"%s\"" + +#: rewrite/rewriteDefine.c:772 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "Список результату правила для SELECT має занадто мало елементів" + +#: rewrite/rewriteDefine.c:773 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "Список RETURNING має занадто мало елементів" + +#: rewrite/rewriteDefine.c:866 rewrite/rewriteDefine.c:980 +#: rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "правило \"%s\" для відношення \"%s\" не існує" + +#: rewrite/rewriteDefine.c:999 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "не допускається перейменування правила ON SELECT" + +#: rewrite/rewriteHandler.c:545 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "Ім'я запиту WITH \"%s\" з'являється і в дії правила, і в переписаному запиті" + +#: rewrite/rewriteHandler.c:605 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "списки RETURNING може мати лише одне правило" + +#: rewrite/rewriteHandler.c:816 rewrite/rewriteHandler.c:828 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "вставити дані в стовпець \"%s\" не можна" + +#: rewrite/rewriteHandler.c:817 rewrite/rewriteHandler.c:839 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "Стовпець \"%s\" є ідентифікаційним стовпцем визначеним як GENERATED ALWAYS." + +#: rewrite/rewriteHandler.c:819 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Для зміни використайте OVERRIDING SYSTEM VALUE." + +#: rewrite/rewriteHandler.c:838 rewrite/rewriteHandler.c:845 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "стовпець \"%s\" може бути оновлено тільки до DEFAULT" + +#: rewrite/rewriteHandler.c:1014 rewrite/rewriteHandler.c:1032 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "кілька завдань для одного стовпця \"%s\"" + +#: rewrite/rewriteHandler.c:2062 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "виявлена безкінечна рекурсія в політиці для зв'язка \"%s\"" + +#: rewrite/rewriteHandler.c:2382 +msgid "Junk view columns are not updatable." +msgstr "Утилізовані стовпці подань не оновлюються." + +#: rewrite/rewriteHandler.c:2387 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "Стовпці подання, які не є стовпцями базового зв'язку, не оновлюються." + +#: rewrite/rewriteHandler.c:2390 +msgid "View columns that refer to system columns are not updatable." +msgstr "Стовпці подання, які посилаються на системні стовпці, не оновлюються." + +#: rewrite/rewriteHandler.c:2393 +msgid "View columns that return whole-row references are not updatable." +msgstr "Стовпці подання, що повертають посилання на весь рядок, не оновлюються." + +#: rewrite/rewriteHandler.c:2454 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "Подання які містять DISTINCT не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2457 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "Подання які містять GROUP BY не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2460 +msgid "Views containing HAVING are not automatically updatable." +msgstr "Подання які містять HAVING не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2463 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "Подання які містять UNION, INTERSECT, або EXCEPT не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2466 +msgid "Views containing WITH are not automatically updatable." +msgstr "Подання які містять WITH не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2469 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "Подання які містять LIMIT або OFFSET не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2481 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "Подання які повертають агрегатні функції не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2484 +msgid "Views that return window functions are not automatically updatable." +msgstr "Подання які повертають віконні функції не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2487 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "Подання які повертають set-returning функції не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2494 rewrite/rewriteHandler.c:2498 +#: rewrite/rewriteHandler.c:2506 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "Подання які обирають дані не з одної таблиці або подання не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2509 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "Подання які містять TABLESAMPLE не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:2533 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "Подання які не мають оновлюваних стовпців не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:3010 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "вставити дані в стовпець \"%s\" подання \"%s\" не можна" + +#: rewrite/rewriteHandler.c:3018 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "оновити дані в стовпці \"%s\" подання \"%s\" не можна" + +#: rewrite/rewriteHandler.c:3496 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "Правила DO INSTEAD NOTHING не підтримуються для операторів, які змінюють дані в WITH" + +#: rewrite/rewriteHandler.c:3510 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "умовні правила DO INSTEAD не підтримуються для операторів, які змінюють дані в WITH" + +#: rewrite/rewriteHandler.c:3514 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "Правила DO ALSO не підтримуються для операторів, які змінюють дані в WITH" + +#: rewrite/rewriteHandler.c:3519 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "складові правила DO INSTEAD не підтримуються операторами, які змінюють дані у WITH" + +#: rewrite/rewriteHandler.c:3710 rewrite/rewriteHandler.c:3718 +#: rewrite/rewriteHandler.c:3726 +#, c-format +msgid "Views with conditional DO INSTEAD rules are not automatically updatable." +msgstr "Подання з умовними правилами DO INSTEAD не оновлюються автоматично." + +#: rewrite/rewriteHandler.c:3819 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "виконати INSERT RETURNING для зв'язка \"%s\" не можна" + +#: rewrite/rewriteHandler.c:3821 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "Вам потрібне безумовне правило ON INSERT DO INSTEAD з реченням RETURNING." + +#: rewrite/rewriteHandler.c:3826 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "виконати UPDATE RETURNING для зв'язка \"%s\" не можна" + +#: rewrite/rewriteHandler.c:3828 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "Вам потрібне безумовне правило ON UPDATE DO INSTEAD з реченням RETURNING." + +#: rewrite/rewriteHandler.c:3833 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "виконати DELETE RETURNING для зв'язка \"%s\" не можна" + +#: rewrite/rewriteHandler.c:3835 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "Вам потрібне безумовне правило ON DELETE DO INSTEAD з реченням RETURNING." + +#: rewrite/rewriteHandler.c:3853 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "INSERT з реченням ON CONFLICT не можна використовувати з таблицею, яка має правила INSERT або UPDATE" + +#: rewrite/rewriteHandler.c:3910 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "WITH не можна використовувати в запиті, який переписаний правилами в декілька запитів" + +#: rewrite/rewriteManip.c:1006 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "умовні службові оператори не реалізовані" + +#: rewrite/rewriteManip.c:1172 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "Умова WHERE CURRENT OF для подання не реалізована" + +#: rewrite/rewriteManip.c:1507 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "Змінні NEW в правилах ON UPDATE не можуть посилатись на стовпці, які є частиною декілької призначень в команді UPDATE" + +#: snowball/dict_snowball.c:199 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "засіб визначення основи слова Snowball для мови \"%s\" і кодування \"%s\" не знайдено" + +#: snowball/dict_snowball.c:222 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "повторюваний параметр StopWords" + +#: snowball/dict_snowball.c:231 +#, c-format +msgid "multiple Language parameters" +msgstr "повторюваний параметр Language" + +#: snowball/dict_snowball.c:238 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "нерозпізнаний параметр Snowball: \"%s\"" + +#: snowball/dict_snowball.c:246 +#, c-format +msgid "missing Language parameter" +msgstr "пропущений параметр Language" + +#: statistics/dependencies.c:667 statistics/dependencies.c:720 +#: statistics/mcv.c:1477 statistics/mcv.c:1508 statistics/mvdistinct.c:348 +#: statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:42 +#: utils/adt/pseudotypes.c:76 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "не можна прийняти значення типу %s" + +#: statistics/extended_stats.c:145 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "об'єкт статистики \"%s.%s\" не вдалося обчислити для відношення \"%s.%s\"" + +#: statistics/mcv.c:1365 utils/adt/jsonfuncs.c:1800 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "функція, що повертає набір, викликана у контексті, що не приймає тип запис" + +#: storage/buffer/bufmgr.c:588 storage/buffer/bufmgr.c:669 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "доступ до тимчасових таблиць з інших сесій заблоковано" + +#: storage/buffer/bufmgr.c:825 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "неочікуванні дані після EOF в блоці %u відношення %s" + +#: storage/buffer/bufmgr.c:827 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "Ця ситуація може виникати через помилки в ядрі; можливо, вам слід оновити вашу систему." + +#: storage/buffer/bufmgr.c:925 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "неприпустима сторінка в блоці %u відношення %s; сторінка обнуляється" + +#: storage/buffer/bufmgr.c:4211 +#, c-format +msgid "could not write block %u of %s" +msgstr "неможливо записати блок %u файлу %s" + +#: storage/buffer/bufmgr.c:4213 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Кілька неполадок --- можливо, постійна помилка запису." + +#: storage/buffer/bufmgr.c:4234 storage/buffer/bufmgr.c:4253 +#, c-format +msgid "writing block %u of relation %s" +msgstr "записування блоку %u зв'язку %s" + +#: storage/buffer/bufmgr.c:4556 +#, c-format +msgid "snapshot too old" +msgstr "знімок є застарим" + +#: storage/buffer/localbuf.c:205 +#, c-format +msgid "no empty local buffer available" +msgstr "немає жодного пустого локального буферу" + +#: storage/buffer/localbuf.c:433 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "немає доступу до тимчасових таблиць під час паралельної операції" + +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "не вдалося відкрити тимчасовий файл \"%s\" з BufFile \"%s\": %m" + +#: storage/file/buffile.c:795 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "не вдалося визначити розмір тимчасового файлу \"%s\" з BufFile \"%s\": %m" + +#: storage/file/fd.c:508 storage/file/fd.c:580 storage/file/fd.c:616 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "не вдалося очистити \"брудні\" дані: %m" + +#: storage/file/fd.c:538 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "не вдалося визначити розмір \"брудних\" даних: %m" + +#: storage/file/fd.c:590 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "не вдалося munmap() під час очищення даних: %m" + +#: storage/file/fd.c:798 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "для файлу \"%s\" не вдалося створити посилання \"%s\": %m" + +#: storage/file/fd.c:881 +#, c-format +msgid "getrlimit failed: %m" +msgstr "помилка getrlimit: %m" + +#: storage/file/fd.c:971 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "недостатньо доступних дескрипторів файлу для запуску серверного процесу" + +#: storage/file/fd.c:972 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "Система дозволяє %d, потрібно щонайменше %d." + +#: storage/file/fd.c:1023 storage/file/fd.c:2357 storage/file/fd.c:2467 +#: storage/file/fd.c:2618 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "нестача дескрипторів файлу: %m; вивільніть і спробуйте знову" + +#: storage/file/fd.c:1397 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "тимчасовий файл: шлях \"%s\", розмір %lu" + +#: storage/file/fd.c:1528 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "неможливо створити тимчасовий каталог \"%s\": %m" + +#: storage/file/fd.c:1535 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "неможливо створити тимчасовий підкаталог \"%s\": %m" + +#: storage/file/fd.c:1728 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "неможливо створити тимчасовий файл \"%s\": %m" + +#: storage/file/fd.c:1763 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "неможливо відкрити тимчасовий файл \"%s\": %m" + +#: storage/file/fd.c:1804 +#, c-format +msgid "could not unlink temporary file \"%s\": %m" +msgstr "помилка видалення тимчасового файлу \"%s\": %m" + +#: storage/file/fd.c:2068 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "розмір тимчасового файлу перевищує temp_file_limit (%d Кб)" + +#: storage/file/fd.c:2333 storage/file/fd.c:2392 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "перевищено maxAllocatedDescs (%d) при спробі відкрити файл \"%s\"" + +#: storage/file/fd.c:2437 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "перевищено maxAllocatedDescs (%d) при спробі виконати команду \"%s\"" + +#: storage/file/fd.c:2594 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "перевищено maxAllocatedDescs (%d) при спробі відкрити каталог \"%s\"" + +#: storage/file/fd.c:3122 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "знайдено неочікуваний файл в каталозі тимчасових файлів: \"%s\"" + +#: storage/file/sharedfileset.c:111 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "не вдалося підключитися до вже знищеному набору SharedFileSet" + +#: storage/ipc/dsm.c:338 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "сегмент керування динамічної спільної пам'яті пошкоджений" + +#: storage/ipc/dsm.c:399 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "сегмент керування динамічної спільної пам'яті недійсний" + +#: storage/ipc/dsm.c:494 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "занадто багато сегментів динамічної спільної пам'яті" + +#: storage/ipc/dsm_impl.c:230 storage/ipc/dsm_impl.c:526 +#: storage/ipc/dsm_impl.c:630 storage/ipc/dsm_impl.c:801 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "не вдалося звільнити сегмент спільної пам'яті \"%s\": %m" + +#: storage/ipc/dsm_impl.c:240 storage/ipc/dsm_impl.c:536 +#: storage/ipc/dsm_impl.c:640 storage/ipc/dsm_impl.c:811 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "не вдалося видалити сегмент спільної пам'яті \"%s\": %m" + +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:711 +#: storage/ipc/dsm_impl.c:825 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "не вдалося відкрити сегмент спільної пам'яті \"%s\": %m" + +#: storage/ipc/dsm_impl.c:289 storage/ipc/dsm_impl.c:552 +#: storage/ipc/dsm_impl.c:756 storage/ipc/dsm_impl.c:849 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "не вдалося звернутися до сегменту спільної пам'яті \"%s\": %m" + +#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:900 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "не вдалося змінити розмір сегменту спільної пам'яті \"%s\" до %zu байтів: %m" + +#: storage/ipc/dsm_impl.c:338 storage/ipc/dsm_impl.c:573 +#: storage/ipc/dsm_impl.c:732 storage/ipc/dsm_impl.c:922 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "не вдалося показати сегмент спільної пам'яті \"%s\": %m" + +#: storage/ipc/dsm_impl.c:508 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "не вдалося отримати сегмент спільної пам'яті: %m" + +#: storage/ipc/dsm_impl.c:696 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "не вдалося створити сегмент спільної пам'яті \"%s\": %m" + +#: storage/ipc/dsm_impl.c:933 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "не вдалося закрити сегмент спільної пам'яті \"%s\": %m" + +#: storage/ipc/dsm_impl.c:972 storage/ipc/dsm_impl.c:1020 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "не вдалося продублювати маркер для \"%s\": %m" + +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:940 storage/ipc/latch.c:1094 storage/ipc/latch.c:1307 +#: storage/ipc/latch.c:1457 storage/ipc/latch.c:1570 +#, c-format +msgid "%s failed: %m" +msgstr "%s помилка: %m" + +#: storage/ipc/procarray.c:3014 +#, c-format +msgid "database \"%s\" is being used by prepared transactions" +msgstr "база даних \"%s\" використовується підготовленими транзакціями" + +#: storage/ipc/procarray.c:3046 storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "щоб припинити процес суперкористувача потрібно бути суперкористувачем" + +#: storage/ipc/procarray.c:3053 storage/ipc/signalfuncs.c:147 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "потрібно бути учасником ролі, процес котрої припиняється або учасником pg_signal_backend" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:982 +#: storage/lmgr/lock.c:1020 storage/lmgr/lock.c:2845 storage/lmgr/lock.c:4175 +#: storage/lmgr/lock.c:4240 storage/lmgr/lock.c:4532 +#: storage/lmgr/predicate.c:2401 storage/lmgr/predicate.c:2416 +#: storage/lmgr/predicate.c:3898 storage/lmgr/predicate.c:5009 +#: utils/hash/dynahash.c:1067 +#, c-format +msgid "out of shared memory" +msgstr "нестача спільної пам'яті" + +#: storage/ipc/shmem.c:170 storage/ipc/shmem.c:266 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "нестача спільної пам'яті (потребується %zu байт)" + +#: storage/ipc/shmem.c:441 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "не вдалося створити введення ShmemIndex для структури даних \"%s\"" + +#: storage/ipc/shmem.c:456 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "розмір введення ShmemIndex є неправильним для структури даних \"%s\": очікувано %zu, фактично %zu" + +#: storage/ipc/shmem.c:475 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "недостатньо спільної пам'яті для структури даних \"%s\" (потрібно було %zu байтів)" + +#: storage/ipc/shmem.c:507 storage/ipc/shmem.c:526 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "запитаний сегмент спільної пам'яті не вміщається в size_t" + +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d не є серверним процесом PostgreSQL" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1366 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "не вдалося надіслати сигнал процесу %d: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "щоб скасувати запит суперкористувача потрібно бути суперкористувачем" + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "потрібно бути учасником ролі, запит котрої скасовується, або учасником pg_signal_backend" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "прокручувати файли протоколів використовуючи adminpack 1.0, може лише суперкористувач" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:253 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Розгляньте використання %s, що є частиною ядра." + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "обертання неможливе тому, що записування колекції не активоване" + +#: storage/ipc/standby.c:580 tcop/postgres.c:3177 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "виконання оператора скасовано через конфлікт з процесом відновлення" + +#: storage/ipc/standby.c:581 tcop/postgres.c:2469 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "Транзакція користувача призвела до взаємного блокування з процесом відновлення." + +#: storage/large_object/inv_api.c:191 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "у введенні pg_largeobject для OID %u, сторінка %d має неприпустимий розмір поля даних %d" + +#: storage/large_object/inv_api.c:272 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "неприпустимі позначки для відкриття великого об'єкту: %d" + +#: storage/large_object/inv_api.c:462 +#, c-format +msgid "invalid whence setting: %d" +msgstr "неприпустиме значення орієнтиру: %d" + +#: storage/large_object/inv_api.c:634 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "неприпустимий розмір запису великого об'єкту: %d" + +#: storage/lmgr/deadlock.c:1124 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "Процес %d очікує в режимі %s блокування \"%s\"; заблокований процесом %d." + +#: storage/lmgr/deadlock.c:1143 +#, c-format +msgid "Process %d: %s" +msgstr "Процес %d: %s" + +#: storage/lmgr/deadlock.c:1152 +#, c-format +msgid "deadlock detected" +msgstr "виявлено взаємне блокування" + +#: storage/lmgr/deadlock.c:1155 +#, c-format +msgid "See server log for query details." +msgstr "Подробиці запиту перегляньте в записі серверу." + +#: storage/lmgr/lmgr.c:830 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "при оновленні кортежу (%u,%u) в зв'язку \"%s\"" + +#: storage/lmgr/lmgr.c:833 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "при видаленні кортежу (%u,%u) в зв'язку \"%s\"" + +#: storage/lmgr/lmgr.c:836 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "при блокуванні кортежу (%u,%u) в зв'язку \"%s\"" + +#: storage/lmgr/lmgr.c:839 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "при блокуванні оновленої версії (%u,%u) кортежу в зв'язку \"%s\"" + +#: storage/lmgr/lmgr.c:842 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "при вставці кортежу індексу (%u,%u) в зв'язку \"%s\"" + +#: storage/lmgr/lmgr.c:845 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "під час перевірки унікальності кортежа (%u,%u) у відношенні \"%s\"" + +#: storage/lmgr/lmgr.c:848 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "під час повторної перевірки оновленого кортежа (%u,%u) у відношенні \"%s\"" + +#: storage/lmgr/lmgr.c:851 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "під час перевірки обмеження-виключення для кортежа (%u,%u) у відношенні \"%s\"" + +#: storage/lmgr/lmgr.c:1106 +#, c-format +msgid "relation %u of database %u" +msgstr "відношення %u бази даних %u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "розширення відношення %u бази даних %u" + +#: storage/lmgr/lmgr.c:1118 +#, c-format +msgid "pg_database.datfrozenxid of database %u" +msgstr "pg_database.datfrozenxid бази даних %u" + +#: storage/lmgr/lmgr.c:1123 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "сторінка %u відношення %u бази даних %u" + +#: storage/lmgr/lmgr.c:1130 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "кортеж (%u,%u) відношення %u бази даних %u" + +#: storage/lmgr/lmgr.c:1138 +#, c-format +msgid "transaction %u" +msgstr "транзакція %u" + +#: storage/lmgr/lmgr.c:1143 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "віртуальна транзакція %d/%u" + +#: storage/lmgr/lmgr.c:1149 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "орієнтовний маркер %u транзакції %u" + +#: storage/lmgr/lmgr.c:1155 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "об’єкт %u класу %u бази даних %u" + +#: storage/lmgr/lmgr.c:1163 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "користувацьке блокування [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1170 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "рекомендаційне блокування [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1178 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "нерозпізнаний тип блокування %d" + +#: storage/lmgr/lock.c:803 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "поки виконується відновлення, не можна отримати блокування об'єктів бази даних в режимі %s" + +#: storage/lmgr/lock.c:805 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "Під час процесу відновлення для об'єктів бази даних може бути отримане лише блокування RowExclusiveLock або менш сильна." + +#: storage/lmgr/lock.c:983 storage/lmgr/lock.c:1021 storage/lmgr/lock.c:2846 +#: storage/lmgr/lock.c:4176 storage/lmgr/lock.c:4241 storage/lmgr/lock.c:4533 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "Можливо, слід збільшити параметр max_locks_per_transaction." + +#: storage/lmgr/lock.c:3292 storage/lmgr/lock.c:3408 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "не можна виконати PREPARE, під час утримання блокування на рівні сеансу і на рівні транзакції для одного об'єкта" + +#: storage/lmgr/predicate.c:700 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "в RWConflictPool недостатньо елементів для запису про конфлікт читання/запису" + +#: storage/lmgr/predicate.c:701 storage/lmgr/predicate.c:729 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "Можливо, вам слід виконувати менше транзакцій в секунду або збільшити параметр max_connections." + +#: storage/lmgr/predicate.c:728 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "в RWConflictPool недостатньо елементів для запису про потенціальний конфлікт читання/запису" + +#: storage/lmgr/predicate.c:1535 +#, c-format +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "знімок, який відкладається, був небезпечним; пробуємо новий" + +#: storage/lmgr/predicate.c:1624 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "параметр \"default_transaction_isolation\" має значення \"serializable\"." + +#: storage/lmgr/predicate.c:1625 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "Ви можете використати \"SET default_transaction_isolation = 'repeatable read'\" щоб змінити режим за замовчуванням." + +#: storage/lmgr/predicate.c:1676 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "транзакція, яка імпортує знімок не повинна бутив READ ONLY DEFERRABLE" + +#: storage/lmgr/predicate.c:1755 utils/time/snapmgr.c:623 +#: utils/time/snapmgr.c:629 +#, c-format +msgid "could not import the requested snapshot" +msgstr "не вдалося імпортувати запитаний знімок" + +#: storage/lmgr/predicate.c:1756 utils/time/snapmgr.c:630 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "Вихідний процес з PID %d вже не виконується." + +#: storage/lmgr/predicate.c:2402 storage/lmgr/predicate.c:2417 +#: storage/lmgr/predicate.c:3899 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "Можливо, вам слід збільшити параметр max_pred_locks_per_transaction." + +#: storage/lmgr/predicate.c:4030 storage/lmgr/predicate.c:4066 +#: storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4107 +#: storage/lmgr/predicate.c:4146 storage/lmgr/predicate.c:4388 +#: storage/lmgr/predicate.c:4725 storage/lmgr/predicate.c:4737 +#: storage/lmgr/predicate.c:4780 storage/lmgr/predicate.c:4818 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "не вдалося серіалізувати доступ через залежність читання/запису серед транзакцій" + +#: storage/lmgr/predicate.c:4032 storage/lmgr/predicate.c:4068 +#: storage/lmgr/predicate.c:4101 storage/lmgr/predicate.c:4109 +#: storage/lmgr/predicate.c:4148 storage/lmgr/predicate.c:4390 +#: storage/lmgr/predicate.c:4727 storage/lmgr/predicate.c:4739 +#: storage/lmgr/predicate.c:4782 storage/lmgr/predicate.c:4820 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "Транзакція може завершитися успішно, якщо повторити спробу." + +#: storage/lmgr/proc.c:358 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "кількість запитаних підключень резервного серверу перевищує max_wal_senders (поточна %d)" + +#: storage/lmgr/proc.c:1337 +#, c-format +msgid "Process %d waits for %s on %s." +msgstr "Процес %d очікує в режимі %s блокування %s." + +#: storage/lmgr/proc.c:1348 +#, c-format +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "зняття блокуючого процесу автоочистки PID %d" + +#: storage/lmgr/proc.c:1468 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "процес %d уникнув взаємного блокування, чекаючи в режимі %s блокування %s змінивши порядок черги після %ld.%03d мс" + +#: storage/lmgr/proc.c:1483 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "процес %d виявив взаємне блокування, чекаючи в режимі %s блокування %s після %ld.%03d мс" + +#: storage/lmgr/proc.c:1492 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "процес %d все ще чекає в режимі %s блокування %s після %ld.%03d мс" + +#: storage/lmgr/proc.c:1499 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "процес %d отримав в режимі %s блокування %s після %ld.%03d мс" + +#: storage/lmgr/proc.c:1515 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "процес %d не зміг отримати в режимі %s блокування %s після %ld.%03d мс" + +#: storage/page/bufpage.c:145 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "помилка перевірки сторінки, обчислена контрольна сума %u але очікувалось %u" + +#: storage/page/bufpage.c:209 storage/page/bufpage.c:503 +#: storage/page/bufpage.c:740 storage/page/bufpage.c:873 +#: storage/page/bufpage.c:969 storage/page/bufpage.c:1081 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "пошкоджені вказівники сторінки: нижній = %u, верхній = %u, спеціальний = %u" + +#: storage/page/bufpage.c:525 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "пошкоджений вказівник рядка: %u" + +#: storage/page/bufpage.c:552 storage/page/bufpage.c:924 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "пошкоджена довжина елементу: загальний розмір %u, доступний розмір %u" + +#: storage/page/bufpage.c:759 storage/page/bufpage.c:897 +#: storage/page/bufpage.c:985 storage/page/bufpage.c:1097 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "пошкоджений вказівник рядка: зсув = %u, розмір = %u" + +#: storage/smgr/md.c:333 storage/smgr/md.c:836 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "не вдалося скоротити файл \"%s\": %m" + +#: storage/smgr/md.c:407 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "не можна розширити файл \"%s\" до блоку %u" + +#: storage/smgr/md.c:422 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "не вдалося розширити файл \"%s\": %m" + +#: storage/smgr/md.c:424 storage/smgr/md.c:431 storage/smgr/md.c:719 +#, c-format +msgid "Check free disk space." +msgstr "Перевірьте вільний дисковий простір." + +#: storage/smgr/md.c:428 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "не вдалося розширити файл \"%s\" записано лише %d з %d байт в блоку %u" + +#: storage/smgr/md.c:640 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "не вдалося прочитати блок %u в файлі \"%s\": %m" + +#: storage/smgr/md.c:656 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "не вдалося прочитати блок %u в файлі \"%s\": прочитано лише %d з %d байт" + +#: storage/smgr/md.c:710 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "не вдалося записати блок %u у файл \"%s\": %m" + +#: storage/smgr/md.c:715 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "не вдалося записати блок %u в файл \"%s\": записано лише %d з %d байт" + +#: storage/smgr/md.c:807 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "не вдалося скоротити файл \"%s\" до %u блоків: лише %u блоків зараз" + +#: storage/smgr/md.c:862 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "не вдалося скоротити файл \"%s\" до %u блоків: %m" + +#: storage/smgr/md.c:957 +#, c-format +msgid "could not forward fsync request because request queue is full" +msgstr "не вдалося переслати запит синхронізації, тому, що черга запитів переповнена" + +#: storage/smgr/md.c:1256 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "не вдалося відкрити файл \"%s\" (цільовий блок %u): попередній сегмент має лише %u блоків" + +#: storage/smgr/md.c:1270 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "не вдалося відкрити файл \"%s\" (цільовий блок %u): %m" + +#: storage/sync/sync.c:401 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "не вдалося синхронізувати файл \"%s\" але триває повторна спроба: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "неприпустимий розмір аргументу %d в повідомленні виклику функції" + +#: tcop/fastpath.c:307 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "виклик функції fastpath: \"%s\" (OID %u)" + +#: tcop/fastpath.c:389 tcop/postgres.c:1323 tcop/postgres.c:1581 +#: tcop/postgres.c:2013 tcop/postgres.c:2250 +#, c-format +msgid "duration: %s ms" +msgstr "тривалість: %s мс" + +#: tcop/fastpath.c:393 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "тривалість: %s мс, виклик функції fastpath: \"%s\" (OID %u)" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "повідомлення виклику функції містить %d аргументів, але функція потребує %d" + +#: tcop/fastpath.c:437 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "повідомлення виклику функції містить %d форматів, але %d аргументів" + +#: tcop/fastpath.c:524 tcop/fastpath.c:607 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "неправильний формат двійкових даних в аргументі функції %d" + +#: tcop/postgres.c:355 tcop/postgres.c:391 tcop/postgres.c:418 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "неочікуваний обрив з'єднання з клієнтом" + +#: tcop/postgres.c:441 tcop/postgres.c:453 tcop/postgres.c:464 +#: tcop/postgres.c:476 tcop/postgres.c:4539 +#, c-format +msgid "invalid frontend message type %d" +msgstr "неприпустимий тип клієнтського повідомлення %d" + +#: tcop/postgres.c:1042 +#, c-format +msgid "statement: %s" +msgstr "оператор: %s" + +#: tcop/postgres.c:1328 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "тривалість: %s мс, оператор: %s" + +#: tcop/postgres.c:1377 +#, c-format +msgid "parse %s: %s" +msgstr "аналізування %s: %s" + +#: tcop/postgres.c:1434 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "до підтготовленого оператору не можна вставити декілька команд" + +#: tcop/postgres.c:1586 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "тривалість: %s мс, аналізування %s: %s" + +#: tcop/postgres.c:1633 +#, c-format +msgid "bind %s to %s" +msgstr "прив'язка %s до %s" + +#: tcop/postgres.c:1652 tcop/postgres.c:2516 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "підготовлений оператор без імені не існує" + +#: tcop/postgres.c:1693 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "повідомлення bind має %d форматів, але %d параметрів" + +#: tcop/postgres.c:1699 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "в повідомленні bind передано %d параметрів, але підготовлений оператор \"%s\" потребує %d" + +#: tcop/postgres.c:1897 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "невірний формат двійкових даних в параметрі bind %d" + +#: tcop/postgres.c:2018 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "тривалість: %s мс, повідомлення bind %s%s%s: %s" + +#: tcop/postgres.c:2068 tcop/postgres.c:2600 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "портал \"%s\" не існує" + +#: tcop/postgres.c:2153 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2155 tcop/postgres.c:2258 +msgid "execute fetch from" +msgstr "виконати витягнення з" + +#: tcop/postgres.c:2156 tcop/postgres.c:2259 +msgid "execute" +msgstr "виконувати" + +#: tcop/postgres.c:2255 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "тривалість: %s мс %s %s%s%s: %s" + +#: tcop/postgres.c:2401 +#, c-format +msgid "prepare: %s" +msgstr "підготовка: %s" + +#: tcop/postgres.c:2426 +#, c-format +msgid "parameters: %s" +msgstr "параметри: %s" + +#: tcop/postgres.c:2441 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "причина переривання: конфлікт під час відновлення" + +#: tcop/postgres.c:2457 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "Користувач утримував позначку спільного буферу занадто довго." + +#: tcop/postgres.c:2460 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "Користувач утримував блокування відношення занадто довго." + +#: tcop/postgres.c:2463 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "Користувач використовував табличний простір який повинен бути видаленим." + +#: tcop/postgres.c:2466 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "Запиту користувача потрібно було бачити версії рядків, які повинні бути видалені." + +#: tcop/postgres.c:2472 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "Користувач був підключен до бази даних, яка повинна бути видалена." + +#: tcop/postgres.c:2796 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "завершення підключення через аварійне завершення роботи іншого серверного процесу" + +#: tcop/postgres.c:2797 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "Керуючий процес віддав команду цьому серверному процесу відкотити поточну транзакцію і завершитися, тому, що інший серверний процес завершився неправильно і можливо пошкодив спільну пам'ять." + +#: tcop/postgres.c:2801 tcop/postgres.c:3107 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "В цей момент ви можете повторно підключитися до бази даних і повторити вашу команду." + +#: tcop/postgres.c:2883 +#, c-format +msgid "floating-point exception" +msgstr "виняток в операції з рухомою комою" + +#: tcop/postgres.c:2884 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "Надійшло повідомлення про неприпустиму операцію з рухомою комою. Можливо, це значить, що результат виявився за діапазоном або виникла неприпустима операція, така як ділення на нуль." + +#: tcop/postgres.c:3037 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "скасування автентифікації через тайм-аут" + +#: tcop/postgres.c:3041 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "завершення процесу автоочистки по команді адміністратора" + +#: tcop/postgres.c:3045 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "завершення обробника логічної реплікації по команді адміністратора" + +#: tcop/postgres.c:3049 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "процес запуску логічної реплікації зупинен" + +#: tcop/postgres.c:3062 tcop/postgres.c:3072 tcop/postgres.c:3105 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "завершення підключення через конфлікт з процесом відновлення" + +#: tcop/postgres.c:3078 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "завершення підключення по команді адміністратора" + +#: tcop/postgres.c:3088 +#, c-format +msgid "connection to client lost" +msgstr "підключення до клієнта втрачено" + +#: tcop/postgres.c:3154 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "виконання оператора скасовано через тайм-аут блокування" + +#: tcop/postgres.c:3161 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "виконання оператора скасовано через тайм-аут" + +#: tcop/postgres.c:3168 +#, c-format +msgid "canceling autovacuum task" +msgstr "скасування завдання автоочистки" + +#: tcop/postgres.c:3191 +#, c-format +msgid "canceling statement due to user request" +msgstr "виконання оператора скасовано по запиту користувача" + +#: tcop/postgres.c:3201 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "завершення підключення через тайм-аут бездіяльності в транзакції" + +#: tcop/postgres.c:3318 +#, c-format +msgid "stack depth limit exceeded" +msgstr "перевищено ліміт глибини стека" + +#: tcop/postgres.c:3319 +#, c-format +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "Збільште параметр конфігурації \"max_stack_depth\" (поточне значення %d КБ), попередньо переконавшись, що ОС надає достатній розмір стеку." + +#: tcop/postgres.c:3382 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "Значення \"max_stack_depth\" не повинно перевищувати %ld КБ." + +#: tcop/postgres.c:3384 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "Збільшіть ліміт глибини стека в системі через команду \"ulimit -s\" або через локальний еквівалент." + +#: tcop/postgres.c:3744 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "неприпустимий аргумент командного рядка для серверного процесу: %s" + +#: tcop/postgres.c:3745 tcop/postgres.c:3751 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Спробуйте \"%s --help\" для додаткової інформації." + +#: tcop/postgres.c:3749 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: неприпустимий аргумент командного рядка: %s" + +#: tcop/postgres.c:3811 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: ні база даних, ні ім'я користувача не вказані" + +#: tcop/postgres.c:4447 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "неприпустимий підтип повідомлення CLOSE %d" + +#: tcop/postgres.c:4482 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "неприпустимий підтип повідомлення DESCRIBE %d" + +#: tcop/postgres.c:4560 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "виклики функції fastpath не підтримуються в підключенні реплікації" + +#: tcop/postgres.c:4564 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "протокол розширених запитів не підтримується в підключенні реплікації" + +#: tcop/postgres.c:4741 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "відключення: час сеансу: %d:%02d:%02d.%03d користувач = %s база даних = %s хост = %s%s%s" + +#: tcop/pquery.c:629 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "повідомлення bind має %d форматів, але запит має %d стовпців" + +#: tcop/pquery.c:932 +#, c-format +msgid "cursor can only scan forward" +msgstr "курсор може сканувати лише вперед" + +#: tcop/pquery.c:933 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Оголосити з параметром SCROLL, щоб активувати зворотню розгортку." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:413 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "не можна виконати %s в транзакції \"лише для читання\"" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:431 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "не можна виконати %s під час паралельних операцій" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:450 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "не можна виконати %s під час відновлення" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:468 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "не можна виконати %s в межах операції з обмеженнями безпеки" + +#: tcop/utility.c:912 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "для виконання CHECKPOINT потрібно бути суперкористувачем" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:620 +#, c-format +msgid "multiple DictFile parameters" +msgstr "повторюваний параметр DictFile" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "повторюваний параметр AffFile" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "нерозпізнаний параметр Ispell: \"%s\"" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "пропущено параметр AffFile" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:644 +#, c-format +msgid "missing DictFile parameter" +msgstr "пропущено параметр DictFile" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "повторюваний параметр Accept" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "нерозпізнаний параметр простого словника: \"%s\"" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "нерозпізнаний параметр функціїї синонімів: \"%s\"" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "пропущено параметр Synonyms" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "не вдалося відкрити файл синонімів \"%s\": %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "не вдалося відкрити файл тезаурусу \"%s\": %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "неочікуваний роздільник" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "неочікуваний конець рядка або лексеми" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "неочікуваний кінець рядка" + +#: tsearch/dict_thesaurus.c:297 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "занадто багато лексем в елементі тезаурусу" + +#: tsearch/dict_thesaurus.c:421 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "слова-зразка в тезаурусі \"%s\" немає у внутрішньому словнику (правило %d)" + +#: tsearch/dict_thesaurus.c:427 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "слово-зразок в тезаурусі \"%s\" має стоп-слово (правило %d)" + +#: tsearch/dict_thesaurus.c:430 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Для представлення стоп-слова в межах зразка використайте \"?\"." + +#: tsearch/dict_thesaurus.c:572 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "слово-замінник в тезаурусі \"%s\" має стоп-слово (правило %d)" + +#: tsearch/dict_thesaurus.c:579 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "слова-замінника в тезаурусі \"%s\" немає у внутрішньому словнику (правило %d)" + +#: tsearch/dict_thesaurus.c:591 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "фраза-замінник в тезаурусі пуста (правило %d)" + +#: tsearch/dict_thesaurus.c:629 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "повторюваний параметр Dictionary" + +#: tsearch/dict_thesaurus.c:636 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "нерозпізнаний параметр тезаурусу: \"%s\"" + +#: tsearch/dict_thesaurus.c:648 +#, c-format +msgid "missing Dictionary parameter" +msgstr "пропущено параметр Dictionary" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1036 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "неприпустимиа позначка affix \"%s\"" + +#: tsearch/spell.c:384 tsearch/spell.c:1040 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "позначка affix \"%s\" поза діапазоном" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "неприпустимий символ в позначці affix \"%s\"" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "неприпустима позначка affix \"%s\" зі значенням позначки \"long\"" + +#: tsearch/spell.c:524 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "не вдалося відкрити файл словника \"%s\": %m" + +#: tsearch/spell.c:742 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "неприпустимий регулярний вираз: %s" + +#: tsearch/spell.c:956 tsearch/spell.c:973 tsearch/spell.c:990 +#: tsearch/spell.c:1007 tsearch/spell.c:1072 gram.y:15993 gram.y:16010 +#, c-format +msgid "syntax error" +msgstr "синтаксична помилка" + +#: tsearch/spell.c:1163 tsearch/spell.c:1175 tsearch/spell.c:1734 +#: tsearch/spell.c:1739 tsearch/spell.c:1744 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "неприпустимий псевдонім affix \"%s\"" + +#: tsearch/spell.c:1216 tsearch/spell.c:1287 tsearch/spell.c:1436 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "не вдалося відкрити файл affix \"%s\": %m" + +#: tsearch/spell.c:1270 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Словник Ispell підтримує для позначки лише значення \"default\", \"long\", і\"num\"" + +#: tsearch/spell.c:1314 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "неприпустима кількість векторів позначок" + +#: tsearch/spell.c:1337 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "кількість псевдонімів перевищує вказане число %d" + +#: tsearch/spell.c:1552 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "файл affix містить команди і в старому, і в новому стилі" + +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:272 utils/adt/tsvector_op.c:1121 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "рядок занадто довгий для tsvector (%d байт, максимум %d байт)" + +#: tsearch/ts_locale.c:185 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "рядок %d файлу конфігурації \"%s\": \"%s\"" + +#: tsearch/ts_locale.c:302 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "перетворити wchar_t в кодування серверу не вдалося: %mв" + +#: tsearch/ts_parse.c:386 tsearch/ts_parse.c:393 tsearch/ts_parse.c:562 +#: tsearch/ts_parse.c:569 +#, c-format +msgid "word is too long to be indexed" +msgstr "слово занадто довге для індексування" + +#: tsearch/ts_parse.c:387 tsearch/ts_parse.c:394 tsearch/ts_parse.c:563 +#: tsearch/ts_parse.c:570 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "Слова довші за %d символів пропускаються." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "неприпустиме ім'я файлу конфігурації текстового пошуку \"%s\"" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "не вдалося відкрити файл стоп-слова \"%s\": %m" + +#: tsearch/wparser.c:313 tsearch/wparser.c:401 tsearch/wparser.c:478 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "аналізатор текстового пошуку не підтримує створення заголовку" + +#: tsearch/wparser_def.c:2585 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "нерозпізнаний параметр заголовку: \"%s\"" + +#: tsearch/wparser_def.c:2604 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "Значення MinWords повинно бути меньшим за MaxWords" + +#: tsearch/wparser_def.c:2608 +#, c-format +msgid "MinWords should be positive" +msgstr "Значення MinWords повинно бути позитивним" + +#: tsearch/wparser_def.c:2612 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "Значення ShortWord повинно бути >= 0" + +#: tsearch/wparser_def.c:2616 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "Значення MaxFragments повинно бути >= 0" + +#: utils/adt/acl.c:172 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "занадто довгий ідентифікатор" + +#: utils/adt/acl.c:173 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "Ідентифікатор повинен бути короче ніж %d символів." + +#: utils/adt/acl.c:256 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "нерозпізнане ключове слово: \"%s\"" + +#: utils/adt/acl.c:257 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "Ключовим словом ACL повинно бути \"group\" або \"user\"." + +#: utils/adt/acl.c:262 +#, c-format +msgid "missing name" +msgstr "пропущено ім'я" + +#: utils/adt/acl.c:263 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "За ключовими словами \"group\" або \"user\" повинно йти ім'я." + +#: utils/adt/acl.c:269 +#, c-format +msgid "missing \"=\" sign" +msgstr "пропущено знак \"=\"" + +#: utils/adt/acl.c:322 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "неприпустимий символ режиму: повинен бути один з \"%s\"" + +#: utils/adt/acl.c:344 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "за знаком \"/\" повинно прямувати ім'я" + +#: utils/adt/acl.c:352 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "призначив права користувач з ідентифікатором %u" + +#: utils/adt/acl.c:538 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "Масив ACL містить неправильний тип даних" + +#: utils/adt/acl.c:542 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "Масиви ACL повинні бути одновимірними" + +#: utils/adt/acl.c:546 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "Масиви ACL не повинні містити значення null" + +#: utils/adt/acl.c:570 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "зайве сміття в кінці специфікації ACL" + +#: utils/adt/acl.c:1205 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "параметри призначення прав не можна повернути тому, хто призначив їх вам" + +#: utils/adt/acl.c:1266 +#, c-format +msgid "dependent privileges exist" +msgstr "залежні права існують" + +#: utils/adt/acl.c:1267 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Використайте CASCADE, щоб відкликати їх." + +#: utils/adt/acl.c:1521 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert більше не підтримується" + +#: utils/adt/acl.c:1531 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove більше не підтримується" + +#: utils/adt/acl.c:1617 utils/adt/acl.c:1671 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "нерозпізнаний тип прав: \"%s\"" + +#: utils/adt/acl.c:3471 utils/adt/regproc.c:103 utils/adt/regproc.c:278 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "функція \"%s\" не існує" + +#: utils/adt/acl.c:4943 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "потрібно бути учасником ролі \"%s\"" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:933 +#: utils/adt/arrayfuncs.c:1533 utils/adt/arrayfuncs.c:3236 +#: utils/adt/arrayfuncs.c:3376 utils/adt/arrayfuncs.c:5911 +#: utils/adt/arrayfuncs.c:6252 utils/adt/arrayutils.c:93 +#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "розмір масиву перевищує максимальний допустимий розмір (%d)" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:645 utils/adt/json.c:740 +#: utils/adt/json.c:778 utils/adt/jsonb.c:1115 utils/adt/jsonb.c:1144 +#: utils/adt/jsonb.c:1538 utils/adt/jsonb.c:1702 utils/adt/jsonb.c:1712 +#, c-format +msgid "could not determine input data type" +msgstr "не вдалося визначити тип вхідних даних" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "тип вхідних даних не є масивом" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1336 utils/adt/float.c:1243 utils/adt/float.c:1317 +#: utils/adt/float.c:3960 utils/adt/float.c:3974 utils/adt/int.c:759 +#: utils/adt/int.c:781 utils/adt/int.c:795 utils/adt/int.c:809 +#: utils/adt/int.c:840 utils/adt/int.c:861 utils/adt/int.c:978 +#: utils/adt/int.c:992 utils/adt/int.c:1006 utils/adt/int.c:1039 +#: utils/adt/int.c:1053 utils/adt/int.c:1067 utils/adt/int.c:1098 +#: utils/adt/int.c:1180 utils/adt/int.c:1244 utils/adt/int.c:1312 +#: utils/adt/int.c:1318 utils/adt/int8.c:1292 utils/adt/numeric.c:1559 +#: utils/adt/numeric.c:3435 utils/adt/varbit.c:1188 utils/adt/varbit.c:1576 +#: utils/adt/varlena.c:1087 utils/adt/varlena.c:3377 +#, c-format +msgid "integer out of range" +msgstr "ціле число поза діапазоном" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "аргумент повинен бути пустим або одновимірним масивом" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "об'єднувати несумісні масиви не можна" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Масиви з елементами типів %s і %s не є сумісними для об'єднання." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Масиви з вимірами %d і %d не є сумісними для об'єднання." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "Масиви з різними вимірами елементів не є сумісними для об'єднання." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Масиви з різними вимірами не є сумісними для об'єднання." + +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "пошук елементів у багатовимірних масивах не підтримується" + +#: utils/adt/array_userfuncs.c:686 +#, c-format +msgid "initial position must not be null" +msgstr "початкова позиція не повинна бути null" + +#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:284 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:317 +#: utils/adt/arrayfuncs.c:332 utils/adt/arrayfuncs.c:346 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:506 +#: utils/adt/arrayfuncs.c:517 utils/adt/arrayfuncs.c:532 +#: utils/adt/arrayfuncs.c:553 utils/adt/arrayfuncs.c:583 +#: utils/adt/arrayfuncs.c:590 utils/adt/arrayfuncs.c:598 +#: utils/adt/arrayfuncs.c:632 utils/adt/arrayfuncs.c:655 +#: utils/adt/arrayfuncs.c:675 utils/adt/arrayfuncs.c:787 +#: utils/adt/arrayfuncs.c:796 utils/adt/arrayfuncs.c:826 +#: utils/adt/arrayfuncs.c:841 utils/adt/arrayfuncs.c:894 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "неправильний літерал масиву: \"%s\"" + +#: utils/adt/arrayfuncs.c:271 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "\"[\" повинно представляти явно вказані виміри масиву." + +#: utils/adt/arrayfuncs.c:285 +#, c-format +msgid "Missing array dimension value." +msgstr "Пропущено значення виміру масиву." + +#: utils/adt/arrayfuncs.c:296 utils/adt/arrayfuncs.c:333 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "Пропущено \"%s\" після вимірів масиву." + +#: utils/adt/arrayfuncs.c:305 utils/adt/arrayfuncs.c:2884 +#: utils/adt/arrayfuncs.c:2916 utils/adt/arrayfuncs.c:2931 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "верхня границя не може бути меньше нижньої границі" + +#: utils/adt/arrayfuncs.c:318 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "Значення масиву повинно починатись з \"{\" або з інформації про вимір." + +#: utils/adt/arrayfuncs.c:347 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "Вміст масиву повинен починатись з \"{\"." + +#: utils/adt/arrayfuncs.c:353 utils/adt/arrayfuncs.c:360 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "Вказані виміри масиву не відповідають його вмісту." + +#: utils/adt/arrayfuncs.c:491 utils/adt/arrayfuncs.c:518 +#: utils/adt/rangetypes.c:2181 utils/adt/rangetypes.c:2189 +#: utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 +#, c-format +msgid "Unexpected end of input." +msgstr "Неочікуваний кінец введення." + +#: utils/adt/arrayfuncs.c:507 utils/adt/arrayfuncs.c:554 +#: utils/adt/arrayfuncs.c:584 utils/adt/arrayfuncs.c:633 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "Неочікуваний символ \"%c\"." + +#: utils/adt/arrayfuncs.c:533 utils/adt/arrayfuncs.c:656 +#, c-format +msgid "Unexpected array element." +msgstr "Неочікуваний елемент масиву." + +#: utils/adt/arrayfuncs.c:591 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "Невідповідний символ \"%c\"." + +#: utils/adt/arrayfuncs.c:599 utils/adt/jsonfuncs.c:2452 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "Багатовимірні масиви повинні мати вкладені масиви з відповідними вимірами." + +#: utils/adt/arrayfuncs.c:676 +#, c-format +msgid "Junk after closing right brace." +msgstr "Сміття після закриття правої дужки." + +#: utils/adt/arrayfuncs.c:1298 utils/adt/arrayfuncs.c:3344 +#: utils/adt/arrayfuncs.c:5817 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "неприпустима кількість вимірів: %d" + +#: utils/adt/arrayfuncs.c:1309 +#, c-format +msgid "invalid array flags" +msgstr "неприпустимі позначки масиву" + +#: utils/adt/arrayfuncs.c:1317 +#, c-format +msgid "wrong element type" +msgstr "неправильний тип елементу" + +#: utils/adt/arrayfuncs.c:1367 utils/adt/rangetypes.c:335 +#: utils/cache/lsyscache.c:2835 +#, c-format +msgid "no binary input function available for type %s" +msgstr "для типу %s немає функції введення двійкових даних" + +#: utils/adt/arrayfuncs.c:1507 +#, c-format +msgid "improper binary format in array element %d" +msgstr "неправильний двійковий формат в елементі масиву %d" + +#: utils/adt/arrayfuncs.c:1588 utils/adt/rangetypes.c:340 +#: utils/cache/lsyscache.c:2868 +#, c-format +msgid "no binary output function available for type %s" +msgstr "для типу %s немає функції виводу двійкових даних" + +#: utils/adt/arrayfuncs.c:2066 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "розрізання масивів постійної довжини не реалізовано" + +#: utils/adt/arrayfuncs.c:2244 utils/adt/arrayfuncs.c:2266 +#: utils/adt/arrayfuncs.c:2315 utils/adt/arrayfuncs.c:2551 +#: utils/adt/arrayfuncs.c:2862 utils/adt/arrayfuncs.c:5803 +#: utils/adt/arrayfuncs.c:5829 utils/adt/arrayfuncs.c:5840 +#: utils/adt/json.c:1141 utils/adt/json.c:1216 utils/adt/jsonb.c:1316 +#: utils/adt/jsonb.c:1402 utils/adt/jsonfuncs.c:4340 utils/adt/jsonfuncs.c:4490 +#: utils/adt/jsonfuncs.c:4602 utils/adt/jsonfuncs.c:4648 +#, c-format +msgid "wrong number of array subscripts" +msgstr "невірне число верхніх індексів масива" + +#: utils/adt/arrayfuncs.c:2249 utils/adt/arrayfuncs.c:2357 +#: utils/adt/arrayfuncs.c:2615 utils/adt/arrayfuncs.c:2921 +#, c-format +msgid "array subscript out of range" +msgstr "верхній індекс масиву поза діапазоном" + +#: utils/adt/arrayfuncs.c:2254 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "не можна призначати значення null значення елементу масива постійної довжини" + +#: utils/adt/arrayfuncs.c:2809 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "оновлення в зрізах масивів постійної довжини не реалізовані" + +#: utils/adt/arrayfuncs.c:2840 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "у вказівці зрізу масива повинні бути задані обидві межі" + +#: utils/adt/arrayfuncs.c:2841 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "Під час присвоєння значень зрізу в пустому масиві, межі зрізу повинні вказуватися повністю." + +#: utils/adt/arrayfuncs.c:2852 utils/adt/arrayfuncs.c:2947 +#, c-format +msgid "source array too small" +msgstr "вихідний масив занадто малий" + +#: utils/adt/arrayfuncs.c:3500 +#, c-format +msgid "null array element not allowed in this context" +msgstr "елемент масиву null не дозволений в цьому контексті" + +#: utils/adt/arrayfuncs.c:3602 utils/adt/arrayfuncs.c:3773 +#: utils/adt/arrayfuncs.c:4129 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "не можна порівнювати масиви з елементами різних типів" + +#: utils/adt/arrayfuncs.c:3951 utils/adt/rangetypes.c:1254 +#: utils/adt/rangetypes.c:1318 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "не вдалося визначити геш-функцію для типу %s" + +#: utils/adt/arrayfuncs.c:4044 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "не вдалося визначити розширену геш-функцію для типу %s" + +#: utils/adt/arrayfuncs.c:5221 +#, c-format +msgid "data type %s is not an array type" +msgstr "тип даних %s не є типом масиву" + +#: utils/adt/arrayfuncs.c:5276 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "накопичувати null-масиви не можна" + +#: utils/adt/arrayfuncs.c:5304 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "накопичувати пусті масиви не можна" + +#: utils/adt/arrayfuncs.c:5331 utils/adt/arrayfuncs.c:5337 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "накопичувати масиви різної розмірності не можна" + +#: utils/adt/arrayfuncs.c:5701 utils/adt/arrayfuncs.c:5741 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "масив розмірності або масив нижніх границь не може бути null" + +#: utils/adt/arrayfuncs.c:5804 utils/adt/arrayfuncs.c:5830 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "Масив розмірності повинен бути одновимірним." + +#: utils/adt/arrayfuncs.c:5809 utils/adt/arrayfuncs.c:5835 +#, c-format +msgid "dimension values cannot be null" +msgstr "значення розмірностей не можуть бути null" + +#: utils/adt/arrayfuncs.c:5841 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "Масив нижніх границь відрізняється за розміром від масиву розмірностей." + +#: utils/adt/arrayfuncs.c:6117 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "видалення елементів з багатовимірних масивів не підтримується" + +#: utils/adt/arrayfuncs.c:6394 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "граничне значення повинно вказуватись одновимірним масивом" + +#: utils/adt/arrayfuncs.c:6399 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "масив границь не повинен містити NULL" + +#: utils/adt/arrayutils.c:209 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "масив typmod повинен мати тип cstring[]" + +#: utils/adt/arrayutils.c:214 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "масив typmod повинен бути одновимірним" + +#: utils/adt/arrayutils.c:219 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "масив typmod не повинен містити елементи nulls" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "перетворення кодування з %s в ASCII не підтримується" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3757 +#: utils/adt/float.c:187 utils/adt/float.c:271 utils/adt/float.c:295 +#: utils/adt/float.c:412 utils/adt/float.c:497 utils/adt/float.c:525 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 +#: utils/adt/geo_ops.c:1421 utils/adt/geo_ops.c:3476 utils/adt/geo_ops.c:4645 +#: utils/adt/geo_ops.c:4660 utils/adt/geo_ops.c:4667 utils/adt/int8.c:126 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:100 utils/adt/numeric.c:601 +#: utils/adt/numeric.c:628 utils/adt/numeric.c:6001 utils/adt/numeric.c:6025 +#: utils/adt/numeric.c:6049 utils/adt/numeric.c:6882 utils/adt/numeric.c:6908 +#: utils/adt/numutils.c:116 utils/adt/numutils.c:126 utils/adt/numutils.c:170 +#: utils/adt/numutils.c:246 utils/adt/numutils.c:322 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:73 utils/adt/tid.c:74 utils/adt/tid.c:82 +#: utils/adt/tid.c:90 utils/adt/timestamp.c:494 utils/adt/uuid.c:136 +#: utils/adt/xid8funcs.c:346 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "неприпустимий синтаксис для типу %s: \"%s\"" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:118 utils/adt/numutils.c:140 +#: utils/adt/numutils.c:147 utils/adt/numutils.c:240 utils/adt/numutils.c:316 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "значення \"%s\" поза діапазоном для типу %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:104 utils/adt/int.c:824 utils/adt/int.c:940 +#: utils/adt/int.c:1020 utils/adt/int.c:1082 utils/adt/int.c:1120 +#: utils/adt/int.c:1148 utils/adt/int8.c:593 utils/adt/int8.c:651 +#: utils/adt/int8.c:978 utils/adt/int8.c:1058 utils/adt/int8.c:1120 +#: utils/adt/int8.c:1200 utils/adt/numeric.c:7446 utils/adt/numeric.c:7736 +#: utils/adt/numeric.c:9318 utils/adt/timestamp.c:3264 +#, c-format +msgid "division by zero" +msgstr "ділення на нуль" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "значення \"char\" поза діапазоном" + +#: utils/adt/date.c:61 utils/adt/timestamp.c:95 utils/adt/varbit.c:104 +#: utils/adt/varchar.c:48 +#, c-format +msgid "invalid type modifier" +msgstr "неприпустимий тип модифікатора" + +#: utils/adt/date.c:73 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "TIME(%d)%s точність не повинна бути від'ємною" + +#: utils/adt/date.c:79 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%s точність зменшена до дозволеного максимуму, %d" + +#: utils/adt/date.c:158 utils/adt/date.c:166 utils/adt/formatting.c:4196 +#: utils/adt/formatting.c:4205 utils/adt/formatting.c:4311 +#: utils/adt/formatting.c:4321 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "дата поза діапазоном: \"%s\"" + +#: utils/adt/date.c:213 utils/adt/date.c:525 utils/adt/date.c:549 +#: utils/adt/xml.c:2210 +#, c-format +msgid "date out of range" +msgstr "дата поза діапазоном" + +#: utils/adt/date.c:259 utils/adt/timestamp.c:574 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "значення поля типу date поза діапазоном: %d-%02d-%02d" + +#: utils/adt/date.c:266 utils/adt/date.c:275 utils/adt/timestamp.c:580 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "дата поза діапазоном: %d-%02d-%02d" + +#: utils/adt/date.c:313 utils/adt/date.c:336 utils/adt/date.c:362 +#: utils/adt/date.c:1170 utils/adt/date.c:1216 utils/adt/date.c:1772 +#: utils/adt/date.c:1803 utils/adt/date.c:1832 utils/adt/date.c:2664 +#: utils/adt/datetime.c:1655 utils/adt/formatting.c:4053 +#: utils/adt/formatting.c:4085 utils/adt/formatting.c:4165 +#: utils/adt/formatting.c:4287 utils/adt/json.c:418 utils/adt/json.c:457 +#: utils/adt/timestamp.c:222 utils/adt/timestamp.c:254 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2843 utils/adt/timestamp.c:2864 +#: utils/adt/timestamp.c:2877 utils/adt/timestamp.c:2886 +#: utils/adt/timestamp.c:2894 utils/adt/timestamp.c:2949 +#: utils/adt/timestamp.c:2972 utils/adt/timestamp.c:2985 +#: utils/adt/timestamp.c:2996 utils/adt/timestamp.c:3004 +#: utils/adt/timestamp.c:3664 utils/adt/timestamp.c:3789 +#: utils/adt/timestamp.c:3830 utils/adt/timestamp.c:3920 +#: utils/adt/timestamp.c:3964 utils/adt/timestamp.c:4067 +#: utils/adt/timestamp.c:4552 utils/adt/timestamp.c:4748 +#: utils/adt/timestamp.c:5075 utils/adt/timestamp.c:5089 +#: utils/adt/timestamp.c:5094 utils/adt/timestamp.c:5108 +#: utils/adt/timestamp.c:5141 utils/adt/timestamp.c:5218 +#: utils/adt/timestamp.c:5259 utils/adt/timestamp.c:5263 +#: utils/adt/timestamp.c:5332 utils/adt/timestamp.c:5336 +#: utils/adt/timestamp.c:5350 utils/adt/timestamp.c:5384 utils/adt/xml.c:2232 +#: utils/adt/xml.c:2239 utils/adt/xml.c:2259 utils/adt/xml.c:2266 +#, c-format +msgid "timestamp out of range" +msgstr "позначка часу поза діапазоном" + +#: utils/adt/date.c:500 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "віднімати безкінечні дати не можна" + +#: utils/adt/date.c:589 utils/adt/date.c:646 utils/adt/date.c:680 +#: utils/adt/date.c:2701 utils/adt/date.c:2711 +#, c-format +msgid "date out of range for timestamp" +msgstr "для позначки часу дата поза діапазоном" + +#: utils/adt/date.c:1389 utils/adt/date.c:2159 utils/adt/formatting.c:4373 +#, c-format +msgid "time out of range" +msgstr "час поза діапазоном" + +#: utils/adt/date.c:1441 utils/adt/timestamp.c:589 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "значення поля типу time поза діапазоном: %d:%02d:%02g" + +#: utils/adt/date.c:1961 utils/adt/date.c:2463 utils/adt/float.c:1071 +#: utils/adt/float.c:1140 utils/adt/int.c:616 utils/adt/int.c:663 +#: utils/adt/int.c:698 utils/adt/int8.c:492 utils/adt/numeric.c:2197 +#: utils/adt/timestamp.c:3313 utils/adt/timestamp.c:3344 +#: utils/adt/timestamp.c:3375 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "неприпустимий розмір preceding або following у віконній функції" + +#: utils/adt/date.c:2046 utils/adt/date.c:2059 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "\"час\" містить нерозпізанін одиниці \"%s\"" + +#: utils/adt/date.c:2167 +#, c-format +msgid "time zone displacement out of range" +msgstr "зсув часового поясу поза діапазоном" + +#: utils/adt/date.c:2796 utils/adt/date.c:2809 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "\"час з часовим поясом\" містить нерозпізнані одиниці \"%s\"" + +#: utils/adt/date.c:2882 utils/adt/datetime.c:906 utils/adt/datetime.c:1813 +#: utils/adt/datetime.c:4601 utils/adt/timestamp.c:513 +#: utils/adt/timestamp.c:540 utils/adt/timestamp.c:4150 +#: utils/adt/timestamp.c:5100 utils/adt/timestamp.c:5342 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "часовий пояс \"%s\" не розпізнаний" + +#: utils/adt/date.c:2914 utils/adt/timestamp.c:5130 utils/adt/timestamp.c:5373 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "інтервал \"%s\", який задає часовий пояс, не повинен включати місяці або дні" + +#: utils/adt/datetime.c:3730 utils/adt/datetime.c:3737 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "значення поля типу дата/час поза діапазоном: \"%s\"" + +#: utils/adt/datetime.c:3739 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Можливо, вам потрібні інші налаштування \"datestyle\"." + +#: utils/adt/datetime.c:3744 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "значення поля типу інтервал, поза діапазоном: \"%s\"" + +#: utils/adt/datetime.c:3750 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "зміщення часового поясу, поза діапазоном: \"%s\"" + +#: utils/adt/datetime.c:4603 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "Це ім'я часового поясу з'являється у файлі конфігурації часового поясу з кодом \"%s\"." + +#: utils/adt/datum.c:89 utils/adt/datum.c:101 +#, c-format +msgid "invalid Datum pointer" +msgstr "неприпустимий вказівник Datum" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "неприпустимий розмір: \"%s\"" + +#: utils/adt/dbsize.c:828 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "Неприпустима одиниця вимірювання розміру: \"%s\"." + +#: utils/adt/dbsize.c:829 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Припустимі одиниці вимірювання: \"bytes\", \"kB\", \"MB\", \"GB\", і \"TB\"." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "тип %s не є доменом" + +#: utils/adt/encode.c:64 utils/adt/encode.c:112 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "нерозпізнане кодування: \"%s\"" + +#: utils/adt/encode.c:78 +#, c-format +msgid "result of encoding conversion is too large" +msgstr "результат перетворення кодування занадто великий" + +#: utils/adt/encode.c:126 +#, c-format +msgid "result of decoding conversion is too large" +msgstr "результат перетворення декодування занадто великий" + +#: utils/adt/encode.c:184 +#, c-format +msgid "invalid hexadecimal digit: \"%c\"" +msgstr "неприпустиме шістнадцяткове число: \"%c\"" + +#: utils/adt/encode.c:212 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "неприпустимі шістнадцядкові дані: непарна кількість чисел" + +#: utils/adt/encode.c:329 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "неочікуваний символ \"=\" під час декодування послідовності base64" + +#: utils/adt/encode.c:341 +#, c-format +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "неприпустимий символ \"%c\" під час декодування послідовності base64" + +#: utils/adt/encode.c:361 +#, c-format +msgid "invalid base64 end sequence" +msgstr "неприпустима скінченна послідовність base64" + +#: utils/adt/encode.c:362 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "Вхідні дані позбавлені можливості заповнення, скорочені, або пошкоджені іншим чином." + +#: utils/adt/encode.c:476 utils/adt/encode.c:541 utils/adt/jsonfuncs.c:619 +#: utils/adt/varlena.c:319 utils/adt/varlena.c:360 jsonpath_gram.y:528 +#: jsonpath_scan.l:519 jsonpath_scan.l:530 jsonpath_scan.l:540 +#: jsonpath_scan.l:582 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "неприпустимий вхідний синтаксис для типу %s" + +#: utils/adt/enum.c:100 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "небезпечне використання нового значення \"%s\" типу переліку %s" + +#: utils/adt/enum.c:103 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "Нові значення переліку повинні бути затверджені, перш ніж їх можна використовувати." + +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 +#: utils/adt/enum.c:199 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "неприпустиме вхідне значення для переліку %s: \"%s\"" + +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "неприпустиме внутрішнє значення для переліку: %u" + +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 +#: utils/adt/enum.c:535 +#, c-format +msgid "could not determine actual enum type" +msgstr "не вдалося визначити фактичний тип переліку" + +#: utils/adt/enum.c:454 utils/adt/enum.c:483 +#, c-format +msgid "enum %s contains no values" +msgstr "перелік %s не містить значень" + +#: utils/adt/expandedrecord.c:99 utils/adt/expandedrecord.c:231 +#: utils/cache/typcache.c:1632 utils/cache/typcache.c:1788 +#: utils/cache/typcache.c:1918 utils/fmgr/funcapi.c:456 +#, c-format +msgid "type %s is not composite" +msgstr "тип %s не є складеним" + +#: utils/adt/float.c:88 +#, c-format +msgid "value out of range: overflow" +msgstr "значення поза діапазоном: надлишок" + +#: utils/adt/float.c:96 +#, c-format +msgid "value out of range: underflow" +msgstr "значення поза діапазоном: недостача" + +#: utils/adt/float.c:265 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "\"%s\" поза діапазоном для дійсного типу" + +#: utils/adt/float.c:489 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "\"%s\" поза діапазоном для типу double precision" + +#: utils/adt/float.c:1268 utils/adt/float.c:1342 utils/adt/int.c:336 +#: utils/adt/int.c:874 utils/adt/int.c:896 utils/adt/int.c:910 +#: utils/adt/int.c:924 utils/adt/int.c:956 utils/adt/int.c:1194 +#: utils/adt/int8.c:1313 utils/adt/numeric.c:3553 utils/adt/numeric.c:3562 +#, c-format +msgid "smallint out of range" +msgstr "двобайтове ціле поза діапазоном" + +#: utils/adt/float.c:1468 utils/adt/numeric.c:8329 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "вилучити квадратний корінь від'ємного числа не можна" + +#: utils/adt/float.c:1536 utils/adt/numeric.c:3239 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "нуль у від'ємному ступені дає невизначеність" + +#: utils/adt/float.c:1540 utils/adt/numeric.c:3245 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "від'ємне число у не цілому ступені дає комплексний результат" + +#: utils/adt/float.c:1614 utils/adt/float.c:1647 utils/adt/numeric.c:8993 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "обчислити логарифм нуля не можна" + +#: utils/adt/float.c:1618 utils/adt/float.c:1651 utils/adt/numeric.c:8997 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "обчислити логарифм від'ємного числа не можна" + +#: utils/adt/float.c:1684 utils/adt/float.c:1715 utils/adt/float.c:1810 +#: utils/adt/float.c:1837 utils/adt/float.c:1865 utils/adt/float.c:1892 +#: utils/adt/float.c:2039 utils/adt/float.c:2076 utils/adt/float.c:2246 +#: utils/adt/float.c:2302 utils/adt/float.c:2367 utils/adt/float.c:2424 +#: utils/adt/float.c:2615 utils/adt/float.c:2639 +#, c-format +msgid "input is out of range" +msgstr "введене значення поза діапазоном" + +#: utils/adt/float.c:2706 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "параметр setseed %g поза допустимим діапазоном [-1,1]" + +#: utils/adt/float.c:3938 utils/adt/numeric.c:1509 +#, c-format +msgid "count must be greater than zero" +msgstr "лічильник повинен бути більше нуля" + +#: utils/adt/float.c:3943 utils/adt/numeric.c:1516 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "операнд, нижня границя і верхня границя не можуть бути NaN" + +#: utils/adt/float.c:3949 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "нижня і верхня границі повинні бути скінченними" + +#: utils/adt/float.c:3983 utils/adt/numeric.c:1529 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "нижня границя не може дорівнювати верхній границі" + +#: utils/adt/formatting.c:532 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "неприпустима специфікація формату для цілого значення" + +#: utils/adt/formatting.c:533 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "Інтервали не зв'язуються з певними календарними датами." + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "\"EEEE\" повинно бути останнім використаним шаблоном" + +#: utils/adt/formatting.c:1165 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "\"9\" повинна бути до \"PR\"" + +#: utils/adt/formatting.c:1181 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "\"0\" повинен бути до \"PR\"" + +#: utils/adt/formatting.c:1208 +#, c-format +msgid "multiple decimal points" +msgstr "численні десяткові точки" + +#: utils/adt/formatting.c:1212 utils/adt/formatting.c:1295 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "використовувати \"V\" і десяткову точку разом, не можна" + +#: utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "використовувати \"S\" двічі, не можна" + +#: utils/adt/formatting.c:1228 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "використовувати \"S\" і \"PL\"/\"MI\"/\"SG\"/\"PR\" разом, не можна" + +#: utils/adt/formatting.c:1248 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "використовувати \"S\" і \"MI\" разом, не можна" + +#: utils/adt/formatting.c:1258 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "не можна використовувати \"S\" і \"PL\" разом" + +#: utils/adt/formatting.c:1268 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "не можна використовувати \"S\" і \"SG\" разом" + +#: utils/adt/formatting.c:1277 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "не можна використовувати \"PR\" і \"S\"/\"PL\"/\"MI\"/\"SG\" разом" + +#: utils/adt/formatting.c:1303 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "не можна використовувати \"EEEE\" двічі" + +#: utils/adt/formatting.c:1309 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "\"EEEE\" є несумісним з іншими форматами" + +#: utils/adt/formatting.c:1310 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "\"EEEE\" може використовуватись лише разом з шаблонами цифр і десяткової точки." + +#: utils/adt/formatting.c:1392 +#, c-format +msgid "invalid datetime format separator: \"%s\"" +msgstr "неприпустимий роздільник формату дати й часу: \"%s\"" + +#: utils/adt/formatting.c:1520 +#, c-format +msgid "\"%s\" is not a number" +msgstr "\"%s\" не є числом" + +#: utils/adt/formatting.c:1598 +#, c-format +msgid "case conversion failed: %s" +msgstr "помилка при перетворенні регістру: %s" + +#: utils/adt/formatting.c:1663 utils/adt/formatting.c:1787 +#: utils/adt/formatting.c:1912 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "не вдалося визначити який параметр сортування використати для функції %s" + +#: utils/adt/formatting.c:2284 +#, c-format +msgid "invalid combination of date conventions" +msgstr "неприпустиме поєднання стилів дат" + +#: utils/adt/formatting.c:2285 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "Не змішуйте Gregorian і ISO стилі дат (тижнів) в одному шаблоні форматування." + +#: utils/adt/formatting.c:2308 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "конфліктуючі значення для \"%s\" поля в рядку форматування" + +#: utils/adt/formatting.c:2311 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "Це значення суперечить попередньому параметри для поля того ж типу." + +#: utils/adt/formatting.c:2382 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "вихідний рядок занадто короткий для \"%s\" поля форматування" + +#: utils/adt/formatting.c:2385 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "Поле потребує %d символів, але залишилось лише %d." + +#: utils/adt/formatting.c:2388 utils/adt/formatting.c:2403 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "Якщо ваш вихідний рядок не має постійної ширини, спробуйте використати \"FM\" модифікатор." + +#: utils/adt/formatting.c:2398 utils/adt/formatting.c:2412 +#: utils/adt/formatting.c:2635 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "неприпустиме значення \"%s\" для \"%s\"" + +#: utils/adt/formatting.c:2400 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "Поле потребує %d символів, але вдалося аналізувати лише %d." + +#: utils/adt/formatting.c:2414 +#, c-format +msgid "Value must be an integer." +msgstr "Значення повинне бути цілим числом." + +#: utils/adt/formatting.c:2419 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "значення для \"%s\" у вихідному рядку поза діапазоном" + +#: utils/adt/formatting.c:2421 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "Значення повинне бути в діапазоні %d до %d." + +#: utils/adt/formatting.c:2637 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "Дане значення не відповідає жодному з доступних значень для цього поля." + +#: utils/adt/formatting.c:2854 utils/adt/formatting.c:2874 +#: utils/adt/formatting.c:2894 utils/adt/formatting.c:2914 +#: utils/adt/formatting.c:2933 utils/adt/formatting.c:2952 +#: utils/adt/formatting.c:2976 utils/adt/formatting.c:2994 +#: utils/adt/formatting.c:3012 utils/adt/formatting.c:3030 +#: utils/adt/formatting.c:3047 utils/adt/formatting.c:3064 +#, c-format +msgid "localized string format value too long" +msgstr "занадто довге значення формату локалізованого рядка" + +#: utils/adt/formatting.c:3298 +#, c-format +msgid "unmatched format separator \"%c\"" +msgstr "невідповідний роздільник формату \"%c\"" + +#: utils/adt/formatting.c:3453 utils/adt/formatting.c:3797 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "поле форматування \"%s\" підтримується лише в функції to_char" + +#: utils/adt/formatting.c:3628 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "неприпустимий вхідний рядок для \"Y,YYY\"" + +#: utils/adt/formatting.c:3714 +#, c-format +msgid "input string is too short for datetime format" +msgstr "вхідний рядок занадто короткий для формату дати й часу" + +#: utils/adt/formatting.c:3722 +#, c-format +msgid "trailing characters remain in input string after datetime format" +msgstr "символи наприкінці залишаються у вхідному рядку після формату дати й часу" + +#: utils/adt/formatting.c:4267 +#, c-format +msgid "missing time zone in input string for type timestamptz" +msgstr "пропущено часовий пояс у вхідному рядку для типу timestamptz" + +#: utils/adt/formatting.c:4273 +#, c-format +msgid "timestamptz out of range" +msgstr "timestamptz поза діапазоном" + +#: utils/adt/formatting.c:4301 +#, c-format +msgid "datetime format is zoned but not timed" +msgstr "формат дати й часу зоновано, але не приурочено" + +#: utils/adt/formatting.c:4353 +#, c-format +msgid "missing time zone in input string for type timetz" +msgstr "пропущено часовий пояс у вхідному рядку для типу timetz" + +#: utils/adt/formatting.c:4359 +#, c-format +msgid "timetz out of range" +msgstr "timetz поза діапазоном" + +#: utils/adt/formatting.c:4385 +#, c-format +msgid "datetime format is not dated and not timed" +msgstr "формат дати й часу не датований і не приурочений" + +#: utils/adt/formatting.c:4518 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "година \"%d\" неприпустима для 12-часового годинника" + +#: utils/adt/formatting.c:4520 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Використайте 24-часовий годинник, або передавайте години від 1 до 12." + +#: utils/adt/formatting.c:4628 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "не можна обчислити день року без інформації про рік" + +#: utils/adt/formatting.c:5547 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "\"EEEE\" не підтримується при введенні" + +#: utils/adt/formatting.c:5559 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "\"RN\" не підтримується при введенні" + +#: utils/adt/genfile.c:75 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "посилання на батьківський каталог (\"..\") не дозволене" + +#: utils/adt/genfile.c:86 +#, c-format +msgid "absolute path not allowed" +msgstr "абсолютний шлях не дозволений" + +#: utils/adt/genfile.c:91 +#, c-format +msgid "path must be in or below the current directory" +msgstr "шлях повинен вказувати поточний або вкладений каталог" + +#: utils/adt/genfile.c:116 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 +#, c-format +msgid "requested length too large" +msgstr "запитана довжина занадто велика" + +#: utils/adt/genfile.c:133 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "не вдалося знайти в файлі \"%s\": %m" + +#: utils/adt/genfile.c:174 +#, c-format +msgid "file length too large" +msgstr "довжина файлу завелика" + +#: utils/adt/genfile.c:251 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "щоб читати файли, використовуючи adminpack 1.0 потрібно бути суперкористувачем" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "неприпустима специфікація рядка: A і B не можуть бути нульовими" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "неприпустима специфікація рядка: повинно бути дві різних точки" + +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3486 utils/adt/geo_ops.c:4354 +#: utils/adt/geo_ops.c:5248 +#, c-format +msgid "too many points requested" +msgstr "запитано занадто багато точок" + +#: utils/adt/geo_ops.c:1461 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "неприпустима кількість точок у зовнішньому значенні \"path\"" + +#: utils/adt/geo_ops.c:2537 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "функція \"dist_lb\" не реалізована" + +#: utils/adt/geo_ops.c:2556 +#, c-format +msgid "function \"dist_bl\" not implemented" +msgstr "функція \"dist_bl\" не реалізована" + +#: utils/adt/geo_ops.c:2975 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "функція \"close_sl\" не реалізована" + +#: utils/adt/geo_ops.c:3122 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "функція \"close_lb\" не реалізована" + +#: utils/adt/geo_ops.c:3533 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "неприпустима кількість точок в зовнішньому значенні \"polygon\"" + +#: utils/adt/geo_ops.c:4069 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "функція \"poly_distance\" не реалізована" + +#: utils/adt/geo_ops.c:4446 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "функція \"path_center\" не реалізована" + +#: utils/adt/geo_ops.c:4463 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "відкритий шлях не можна перетворити в багатокутник" + +#: utils/adt/geo_ops.c:4713 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "неприпустимий радіус у зовнішньому значенні \"circle\"" + +#: utils/adt/geo_ops.c:5234 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "круг з нульовим радіусом не можна перетворити в багатокутник" + +#: utils/adt/geo_ops.c:5239 +#, c-format +msgid "must request at least 2 points" +msgstr "повинно бути запитано мінімум 2 точки" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector має занадто багато елементів" + +#: utils/adt/int.c:239 +#, c-format +msgid "invalid int2vector data" +msgstr "неприпустимі дані int2vector" + +#: utils/adt/int.c:245 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector має занадто багато елементів" + +#: utils/adt/int.c:1510 utils/adt/int8.c:1439 utils/adt/numeric.c:1417 +#: utils/adt/timestamp.c:5435 utils/adt/timestamp.c:5515 +#, c-format +msgid "step size cannot equal zero" +msgstr "розмір кроку не може дорівнювати нулю" + +#: utils/adt/int8.c:527 utils/adt/int8.c:550 utils/adt/int8.c:564 +#: utils/adt/int8.c:578 utils/adt/int8.c:609 utils/adt/int8.c:633 +#: utils/adt/int8.c:715 utils/adt/int8.c:783 utils/adt/int8.c:789 +#: utils/adt/int8.c:815 utils/adt/int8.c:829 utils/adt/int8.c:853 +#: utils/adt/int8.c:866 utils/adt/int8.c:935 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:994 utils/adt/int8.c:1016 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1077 +#: utils/adt/int8.c:1091 utils/adt/int8.c:1105 utils/adt/int8.c:1136 +#: utils/adt/int8.c:1158 utils/adt/int8.c:1172 utils/adt/int8.c:1186 +#: utils/adt/int8.c:1348 utils/adt/int8.c:1383 utils/adt/numeric.c:3508 +#: utils/adt/varbit.c:1656 +#, c-format +msgid "bigint out of range" +msgstr "bigint поза діапазоном" + +#: utils/adt/int8.c:1396 +#, c-format +msgid "OID out of range" +msgstr "OID поза діапазоном" + +#: utils/adt/json.c:271 utils/adt/jsonb.c:757 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "значенням ключа повинен бути скаляр, не масив, композитний тип, або json" + +#: utils/adt/json.c:892 utils/adt/json.c:902 utils/fmgr/funcapi.c:1812 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "не вдалося визначити тип даних для аргументу %d" + +#: utils/adt/json.c:926 utils/adt/jsonb.c:1728 +#, c-format +msgid "field name must not be null" +msgstr "ім'я поля не повинно бути null" + +#: utils/adt/json.c:1010 utils/adt/jsonb.c:1178 +#, c-format +msgid "argument list must have even number of elements" +msgstr "список аргументів повинен мати парну кількість елементів" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:1012 utils/adt/jsonb.c:1180 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "Аргументи %s повинні складатись з альтернативних ключей і значень." + +#: utils/adt/json.c:1028 +#, c-format +msgid "argument %d cannot be null" +msgstr "аргумент %d не може бути null" + +#: utils/adt/json.c:1029 +#, c-format +msgid "Object keys should be text." +msgstr "Ключі об'єктів повинні бути текстовими." + +#: utils/adt/json.c:1135 utils/adt/jsonb.c:1310 +#, c-format +msgid "array must have two columns" +msgstr "масив повинен мати два стовпця" + +#: utils/adt/json.c:1159 utils/adt/json.c:1243 utils/adt/jsonb.c:1334 +#: utils/adt/jsonb.c:1429 +#, c-format +msgid "null value not allowed for object key" +msgstr "значення null не дозволене для ключа об'єкту" + +#: utils/adt/json.c:1232 utils/adt/jsonb.c:1418 +#, c-format +msgid "mismatched array dimensions" +msgstr "невідповідні виміри масиву" + +#: utils/adt/jsonb.c:287 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "рядок занадто довгий для представлення в якості рядка jsonb" + +#: utils/adt/jsonb.c:288 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "Через обмеження упровадження, рядки jsonb не можуть перевищувати %d байт." + +#: utils/adt/jsonb.c:1193 +#, c-format +msgid "argument %d: key must not be null" +msgstr "аргумент %d: ключ не повинен бути null" + +#: utils/adt/jsonb.c:1781 +#, c-format +msgid "object keys must be strings" +msgstr "ключі об'єктів повинні бути рядками" + +#: utils/adt/jsonb.c:1944 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "привести значення jsonb null до типу %s не можна" + +#: utils/adt/jsonb.c:1945 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "привести рядок jsonb до типу %s не можна" + +#: utils/adt/jsonb.c:1946 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "привести число jsonb до типу %s не можна" + +#: utils/adt/jsonb.c:1947 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "привести логічне значення jsonb до типу %s не можна" + +#: utils/adt/jsonb.c:1948 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "привести масив jsonb до типу %s не можна" + +#: utils/adt/jsonb.c:1949 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "привести об'єкт jsonb до типу %s не можна" + +#: utils/adt/jsonb.c:1950 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "привести масив або об'єкт jsonb до типу %s не можна" + +#: utils/adt/jsonb_util.c:699 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "кількість пар об'єкта jsonb перевищує максимально дозволену (%zu)" + +#: utils/adt/jsonb_util.c:740 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "кількість елементів масиву jsonb перевищує максимально дозволену(%zu)" + +#: utils/adt/jsonb_util.c:1614 utils/adt/jsonb_util.c:1634 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "загальний розмір елементів масиву jsonb перевищує максимум (%u байт)" + +#: utils/adt/jsonb_util.c:1695 utils/adt/jsonb_util.c:1730 +#: utils/adt/jsonb_util.c:1750 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "загальний розмір елементів об'єкту jsonb перевищує максимум (%u байт)" + +#: utils/adt/jsonfuncs.c:551 utils/adt/jsonfuncs.c:796 +#: utils/adt/jsonfuncs.c:2330 utils/adt/jsonfuncs.c:2770 +#: utils/adt/jsonfuncs.c:3560 utils/adt/jsonfuncs.c:3891 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "викликати %s зі скаляром, не можна" + +#: utils/adt/jsonfuncs.c:556 utils/adt/jsonfuncs.c:783 +#: utils/adt/jsonfuncs.c:2772 utils/adt/jsonfuncs.c:3549 +#, c-format +msgid "cannot call %s on an array" +msgstr "викликати %s з масивом, не можна" + +#: utils/adt/jsonfuncs.c:613 jsonpath_scan.l:498 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "непідтримувана спеціальна послідовність Unicode" + +#: utils/adt/jsonfuncs.c:692 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "Дані JSON, рядок %d: %s%s%s" + +#: utils/adt/jsonfuncs.c:1682 utils/adt/jsonfuncs.c:1717 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "отримати довжину скаляра масиву не можна" + +#: utils/adt/jsonfuncs.c:1686 utils/adt/jsonfuncs.c:1705 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "отримати довжину масива для не масиву не можна" + +#: utils/adt/jsonfuncs.c:1782 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "викликати %s з не об'єктом, не можна" + +#: utils/adt/jsonfuncs.c:2021 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "вилучити масив у вигляді об'єкту не можна" + +#: utils/adt/jsonfuncs.c:2033 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "вилучити скаляр не можна" + +#: utils/adt/jsonfuncs.c:2079 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "вилучити елементи зі скаляру не можна" + +#: utils/adt/jsonfuncs.c:2083 +#, c-format +msgid "cannot extract elements from an object" +msgstr "вилучити елементи з об'єкту не можна" + +#: utils/adt/jsonfuncs.c:2317 utils/adt/jsonfuncs.c:3775 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "викликати %s з не масивом не можна" + +#: utils/adt/jsonfuncs.c:2387 utils/adt/jsonfuncs.c:2392 +#: utils/adt/jsonfuncs.c:2409 utils/adt/jsonfuncs.c:2415 +#, c-format +msgid "expected JSON array" +msgstr "очікувався масив JSON" + +#: utils/adt/jsonfuncs.c:2388 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Перевірте значення ключа \"%s\"." + +#: utils/adt/jsonfuncs.c:2410 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Перевірте елемент масиву %s ключа \"%s\"." + +#: utils/adt/jsonfuncs.c:2416 +#, c-format +msgid "See the array element %s." +msgstr "Перевірте елемент масиву %s." + +#: utils/adt/jsonfuncs.c:2451 +#, c-format +msgid "malformed JSON array" +msgstr "неправильний масив JSON" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3278 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "першим аргументом %s повинен бути тип рядка" + +#. translator: %s is a function name, eg json_to_record +#: utils/adt/jsonfuncs.c:3302 +#, c-format +msgid "could not determine row type for result of %s" +msgstr "не вдалося визначити тип рядка для результату %s" + +#: utils/adt/jsonfuncs.c:3304 +#, c-format +msgid "Provide a non-null record argument, or call the function in the FROM clause using a column definition list." +msgstr "Надайте аргумент ненульового запису, або викличте функцію в реченні FROM, використовуючи список визначення стовпців." + +#: utils/adt/jsonfuncs.c:3792 utils/adt/jsonfuncs.c:3873 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "аргументом %s повинен бути масив об'єктів" + +#: utils/adt/jsonfuncs.c:3825 +#, c-format +msgid "cannot call %s on an object" +msgstr "викликати %s з об'єктом не можна" + +#: utils/adt/jsonfuncs.c:4286 utils/adt/jsonfuncs.c:4345 +#: utils/adt/jsonfuncs.c:4425 +#, c-format +msgid "cannot delete from scalar" +msgstr "видалити зі скаляру не можна" + +#: utils/adt/jsonfuncs.c:4430 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "видалити з об'єкту по числовому індексу не можна" + +#: utils/adt/jsonfuncs.c:4495 utils/adt/jsonfuncs.c:4653 +#, c-format +msgid "cannot set path in scalar" +msgstr "встановити шлях в скалярі не можна" + +#: utils/adt/jsonfuncs.c:4537 utils/adt/jsonfuncs.c:4579 +#, c-format +msgid "null_value_treatment must be \"delete_key\", \"return_target\", \"use_json_null\", or \"raise_exception\"" +msgstr "null_value_treatment має бути \"delete_key\", \"return_target\", \"use_json_null\", або \"raise_exception\"" + +#: utils/adt/jsonfuncs.c:4550 +#, c-format +msgid "JSON value must not be null" +msgstr "Значення JSON не повинне бути null" + +#: utils/adt/jsonfuncs.c:4551 +#, c-format +msgid "Exception was raised because null_value_treatment is \"raise_exception\"." +msgstr "Виняток було запущено через те, що null_value_treatment дорівнює \"raise_exception\"." + +#: utils/adt/jsonfuncs.c:4552 +#, c-format +msgid "To avoid, either change the null_value_treatment argument or ensure that an SQL NULL is not passed." +msgstr "Щоб уникнути, або змініть аргумент null_value_treatment або переконайтесь що SQL NULL не передано." + +#: utils/adt/jsonfuncs.c:4607 +#, c-format +msgid "cannot delete path in scalar" +msgstr "видалити шлях в скалярі не можна" + +#: utils/adt/jsonfuncs.c:4776 +#, c-format +msgid "invalid concatenation of jsonb objects" +msgstr "неприпустиме злиття об'єктів jsonb" + +#: utils/adt/jsonfuncs.c:4810 +#, c-format +msgid "path element at position %d is null" +msgstr "елемент шляху в позиції %d є null" + +#: utils/adt/jsonfuncs.c:4896 +#, c-format +msgid "cannot replace existing key" +msgstr "замініти існуючий ключ не можна" + +#: utils/adt/jsonfuncs.c:4897 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "Спробуйте, використати функцію jsonb_set, щоб замінити значення ключа." + +#: utils/adt/jsonfuncs.c:4979 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "елмент шляху в позиції %d не є цілим числом: \"%s\"" + +#: utils/adt/jsonfuncs.c:5098 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "неправильний тип позначки, дозволені лише масиви і скаляри" + +#: utils/adt/jsonfuncs.c:5105 +#, c-format +msgid "flag array element is not a string" +msgstr "елемент масиву позначок не є рядком" + +#: utils/adt/jsonfuncs.c:5106 utils/adt/jsonfuncs.c:5128 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "Можливі значення: \"string\", \"numeric\", \"boolean\", \"key\", і \"all\"." + +#: utils/adt/jsonfuncs.c:5126 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "неправильна позначка в масиві позначок: \"%s\"" + +#: utils/adt/jsonpath.c:362 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ не дозволяється в кореневих виразах" + +#: utils/adt/jsonpath.c:368 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST дозволяється лише в підрядкових символах масиву" + +#: utils/adt/jsonpath_exec.c:360 +#, c-format +msgid "single boolean result is expected" +msgstr "очікується один логічний результат" + +#: utils/adt/jsonpath_exec.c:556 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "аргумент \"vars\" не є об'єктом" + +#: utils/adt/jsonpath_exec.c:557 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "Параметри Jsonpath повинні бути закодовані в якості пар \"ключ-значення\" об'єкту \"vars\"." + +#: utils/adt/jsonpath_exec.c:674 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "Об'єкт JSON не містить ключа \"%s\"" + +#: utils/adt/jsonpath_exec.c:686 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "доступ для елемента jsonpath може бути застосований лише до об'єкта" + +#: utils/adt/jsonpath_exec.c:715 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "доступ до підстановочного масиву jsonpath може бути застосований лише до масиву" + +#: utils/adt/jsonpath_exec.c:763 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "підрядковий символ масиву jsonpath поза межами" + +#: utils/adt/jsonpath_exec.c:820 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "доступ до масиву jsonpath може бути застосований лише до масиву" + +#: utils/adt/jsonpath_exec.c:874 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "доступ до підстановочного елемента jsonpath може бути застосований лише до об'єкта" + +#: utils/adt/jsonpath_exec.c:1004 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "метод елемента jsonpath .%s() може бути застосований лише до масиву" + +#: utils/adt/jsonpath_exec.c:1059 +#, c-format +msgid "numeric argument of jsonpath item method .%s() is out of range for type double precision" +msgstr "числовий аргумент методу елемента jsonpath .%s() поза діапазоном для типу double precision" + +#: utils/adt/jsonpath_exec.c:1080 +#, c-format +msgid "string argument of jsonpath item method .%s() is not a valid representation of a double precision number" +msgstr "строковий аргумент методу елемента jsonpath .%s() не є представленням числа double precision" + +#: utils/adt/jsonpath_exec.c:1093 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "метод елемента jsonpath .%s() може бути застосований лише до рядка або числового значення" + +#: utils/adt/jsonpath_exec.c:1583 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "лівий операнд оператора jsonpath %s не є єдиним числовим значенням" + +#: utils/adt/jsonpath_exec.c:1590 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "правий операнд оператора jsonpath %s не є єдиним числовим значенням" + +#: utils/adt/jsonpath_exec.c:1658 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "операнд унарного оператора jsonpath %s не є єдиним числовим значенням" + +#: utils/adt/jsonpath_exec.c:1756 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "метод елемента jsonpath .%s() може бути застосований лише до числового значення" + +#: utils/adt/jsonpath_exec.c:1796 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string" +msgstr "метод елемента jsonpath .%s() може бути застосований лише до рядку" + +#: utils/adt/jsonpath_exec.c:1884 +#, c-format +msgid "datetime format is not recognized: \"%s\"" +msgstr "формат дати й часу не розпізнано: \"%s\"" + +#: utils/adt/jsonpath_exec.c:1886 +#, c-format +msgid "Use a datetime template argument to specify the input data format." +msgstr "Використайте аргумент шаблону дати й часу щоб вказати формат вхідних даних." + +#: utils/adt/jsonpath_exec.c:1954 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "метод елемента jsonpath .%s() може бути застосований лише до об'єкта" + +#: utils/adt/jsonpath_exec.c:2137 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "не вдалося знайти змінну jsonpath \"%s\"" + +#: utils/adt/jsonpath_exec.c:2401 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "підрядковий символ масиву jsonpath не є єдиним числовим значенням" + +#: utils/adt/jsonpath_exec.c:2413 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "підрядковий символ масиву jsonpath поза цілим діапазоном" + +#: utils/adt/jsonpath_exec.c:2590 +#, c-format +msgid "cannot convert value from %s to %s without time zone usage" +msgstr "не можна перетворити значення з %s в %s без використання часового поясу" + +#: utils/adt/jsonpath_exec.c:2592 +#, c-format +msgid "Use *_tz() function for time zone support." +msgstr "Використовуйте функцію *_tz() для підтримки часового поясу." + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "довжина аргументу levenshtein перевищує максимальну довжину, %d символів" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "недетерміновані параметри сортування не підтримуються для LIKE" + +#: utils/adt/like.c:193 utils/adt/like_support.c:1002 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "не вдалося визначити який параметр сортування використати для ILIKE" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "недетерміновані параметри сортування не підтримуються для ILIKE" + +#: utils/adt/like_match.c:108 utils/adt/like_match.c:168 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "Шаблон LIKE не повинен закінчуватись символом виходу" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:700 +#, c-format +msgid "invalid escape string" +msgstr "неприпустимий рядок виходу" + +#: utils/adt/like_match.c:294 utils/adt/regexp.c:701 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "Рядок виходу повинен бути пустим або складатися з одного символу." + +#: utils/adt/like_support.c:987 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "порівняння без урахування регістру не підтримується для типу bytea" + +#: utils/adt/like_support.c:1089 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "порівняння з регулярними виразами не підтримується для типу bytea" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "неприпустиме значення октету в значенні типу \"macaddr\": \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "дані macaddr8 поза діапазоном, для перетворення в macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Лише адреси, які мають FF і FE в якості значень в четвертому і п'ятому байті зліва, наприклад xx:xx:xx:ff:fe:xx:xx:xx можуть бути перетворені з macaddr8 в macaddr." + +#: utils/adt/misc.c:240 +#, c-format +msgid "global tablespace never has databases" +msgstr "в табличному просторі global николи не було баз даних" + +#: utils/adt/misc.c:262 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u не є OID табличного простору" + +#: utils/adt/misc.c:448 +msgid "unreserved" +msgstr "не зарезервовано" + +#: utils/adt/misc.c:452 +msgid "unreserved (cannot be function or type name)" +msgstr "не зарезервовано (не може бути іменем типу або функції)" + +#: utils/adt/misc.c:456 +msgid "reserved (can be function or type name)" +msgstr "зарезервовано (може бути іменем типу або функції)" + +#: utils/adt/misc.c:460 +msgid "reserved" +msgstr "зарезервовано" + +#: utils/adt/misc.c:634 utils/adt/misc.c:648 utils/adt/misc.c:687 +#: utils/adt/misc.c:693 utils/adt/misc.c:699 utils/adt/misc.c:722 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "рядок не є припустимим ідентифікатором: \"%s\"" + +#: utils/adt/misc.c:636 +#, c-format +msgid "String has unclosed double quotes." +msgstr "Рядок має не закриті лапки." + +#: utils/adt/misc.c:650 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "Ідентифікатор в лапках не повинен бути пустим." + +#: utils/adt/misc.c:689 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "Перед \".\" немає припустимого ідентифікатору." + +#: utils/adt/misc.c:695 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "Після \".\" немає припустимого ідентифікатора." + +#: utils/adt/misc.c:753 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "формат журналу \"%s\" не підтримується" + +#: utils/adt/misc.c:754 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "Підтримуються формати журналів \"stderr\" і \"csvlog\"." + +#: utils/adt/network.c:111 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "неприпустиме значення cidr: \"%s\"" + +#: utils/adt/network.c:112 utils/adt/network.c:242 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "Значення має встановленні біти правіше маски." + +#: utils/adt/network.c:153 utils/adt/network.c:1199 utils/adt/network.c:1224 +#: utils/adt/network.c:1249 +#, c-format +msgid "could not format inet value: %m" +msgstr "не вдалося форматувати значення inet: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:210 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "неприпустиме сімейство адресів у зовнішньому значенні \"%s\"" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:217 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "неприпустимі біти в зовнішньому значенні \"%s\"" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:226 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "неприпустима довжина в зовнішньому значенні \"%s\"" + +#: utils/adt/network.c:241 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "неприпустиме зовнішнє значення \"cidr\"" + +#: utils/adt/network.c:337 utils/adt/network.c:360 +#, c-format +msgid "invalid mask length: %d" +msgstr "неприпустима довжина маски: %d" + +#: utils/adt/network.c:1267 +#, c-format +msgid "could not format cidr value: %m" +msgstr "не вдалося форматувати значення cidr: %m" + +#: utils/adt/network.c:1500 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "об'єднати адреси з різних сімейств не можна" + +#: utils/adt/network.c:1916 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "не можна використовувати \"І\" (AND) для значень inet різного розміру" + +#: utils/adt/network.c:1948 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "не можна використовувати \"АБО\" (OR) для значень inet різного розміру" + +#: utils/adt/network.c:2009 utils/adt/network.c:2085 +#, c-format +msgid "result is out of range" +msgstr "результат поза діапазоном" + +#: utils/adt/network.c:2050 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "не можна віднімати значення inet різного розміру" + +#: utils/adt/numeric.c:827 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "неприпустимий знак у зовнішньому значенні \"numeric\"" + +#: utils/adt/numeric.c:833 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "неприпустимий масштаб у зовнішньому значенні \"numeric\"" + +#: utils/adt/numeric.c:842 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "неприпустиме число у зовнішньому значенні \"numeric\"" + +#: utils/adt/numeric.c:1040 utils/adt/numeric.c:1054 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "Точність NUMERIC %d повинна бути між 1 і %d" + +#: utils/adt/numeric.c:1045 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "Масштаб NUMERIC %d повинен бути між 0 і точністю %d" + +#: utils/adt/numeric.c:1063 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "неприпустимий модифікатор типу NUMERIC" + +#: utils/adt/numeric.c:1395 +#, c-format +msgid "start value cannot be NaN" +msgstr "початкове значення не може бути NaN" + +#: utils/adt/numeric.c:1400 +#, c-format +msgid "stop value cannot be NaN" +msgstr "кінцеве значення не може бути NaN" + +#: utils/adt/numeric.c:1410 +#, c-format +msgid "step size cannot be NaN" +msgstr "розмір кроку не може бути NaN" + +#: utils/adt/numeric.c:2958 utils/adt/numeric.c:6064 utils/adt/numeric.c:6522 +#: utils/adt/numeric.c:8802 utils/adt/numeric.c:9240 utils/adt/numeric.c:9354 +#: utils/adt/numeric.c:9427 +#, c-format +msgid "value overflows numeric format" +msgstr "значення переповнюють формат numeric" + +#: utils/adt/numeric.c:3417 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "перетворити NaN в ціле число не можна" + +#: utils/adt/numeric.c:3500 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "перетворити NaN в велике ціле не можна" + +#: utils/adt/numeric.c:3545 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "перетворити NaN в двобайтове ціле не можна" + +#: utils/adt/numeric.c:3582 utils/adt/numeric.c:3653 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "перетворити безкінченість в число не можна" + +#: utils/adt/numeric.c:6606 +#, c-format +msgid "numeric field overflow" +msgstr "надлишок поля numeric" + +#: utils/adt/numeric.c:6607 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "Поле з точністю %d, масштабом %d повинне округлятись до абсолютного значення меньше, ніж %s%d." + +#: utils/adt/numutils.c:154 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "значення \"%s\" поза діапазоном для 8-бітного integer" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "неприпустимі дані oidvector" + +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "запитаний символ занадто великий" + +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "запитаний символ занадто великий для кодування: %d" + +#: utils/adt/oracle_compat.c:987 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "запитаний символ не припустимий для кодування: %d" + +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "символ не може бути null" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "значення процентиля %g не є між 0 і 1" + +#: utils/adt/pg_locale.c:1262 +#, c-format +msgid "Apply system library package updates." +msgstr "Застосуйте оновлення для пакету з системною бібліотекою." + +#: utils/adt/pg_locale.c:1477 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "не вдалося створити локалізацію \"%s\": %m" + +#: utils/adt/pg_locale.c:1480 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "Операційній системі не вдалося знайти дані локалізації з іменем \"%s\"." + +#: utils/adt/pg_locale.c:1582 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "параметри сортування з різними значеннями collate і ctype не підтримуються на цій платформі" + +#: utils/adt/pg_locale.c:1591 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "провайдер параметрів сортування LIBC не підтримується на цій платформі" + +#: utils/adt/pg_locale.c:1603 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "ICU не підтримує параметри сортування з різними значеннями collate і ctype" + +#: utils/adt/pg_locale.c:1609 utils/adt/pg_locale.c:1696 +#: utils/adt/pg_locale.c:1969 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "не вдалося відкрити сортувальник для локалізації \"%s\": %s" + +#: utils/adt/pg_locale.c:1623 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU не підтримується в цій збірці" + +#: utils/adt/pg_locale.c:1624 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "Необхідно перебудувати PostgreSQL з ключем --with-icu." + +#: utils/adt/pg_locale.c:1644 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "для параметру сортування \"%s\" який не має фактичної версії, була вказана версія" + +#: utils/adt/pg_locale.c:1651 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "невідповідність версій для параметру сортування \"%s\"" + +#: utils/adt/pg_locale.c:1653 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "Параметр сортування в базі даних був створений з версією %s, але операційна система надає версію %s." + +#: utils/adt/pg_locale.c:1656 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "Перебудуйте всі об'єкти, які стосуються цього параметру сортування і виконайте ALTER COLLATION %s REFRESH VERSION, або побудуйте PostgreSQL з правильною версією бібліотеки." + +#: utils/adt/pg_locale.c:1747 +#, c-format +msgid "could not get collation version for locale \"%s\": error code %lu" +msgstr "не вдалося отримати версію параметрів сортування для локалізації \"%s\": код помилки %lu" + +#: utils/adt/pg_locale.c:1784 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "ICU не підтримує кодування \"%s\"" + +#: utils/adt/pg_locale.c:1791 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "не вдалося відкрити перетворювач ICU для кодування \"%s\": %s" + +#: utils/adt/pg_locale.c:1822 utils/adt/pg_locale.c:1831 +#: utils/adt/pg_locale.c:1860 utils/adt/pg_locale.c:1870 +#, c-format +msgid "%s failed: %s" +msgstr "%s помилка: %s" + +#: utils/adt/pg_locale.c:2142 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "неприпустимий мультибайтний символ для локалізації" + +#: utils/adt/pg_locale.c:2143 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "Параметр локалізації серверу LC_CTYPE, можливо, несумісний з кодуванням бази даних." + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "функцію можна викликати тільки коли сервер знаходиться в режимі двійкового оновлення" + +#: utils/adt/pgstatfuncs.c:500 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "неприпустиме ім’я команди: \"%s\"" + +#: utils/adt/pseudotypes.c:57 utils/adt/pseudotypes.c:91 +#, c-format +msgid "cannot display a value of type %s" +msgstr "значення типу %s не можна відобразити" + +#: utils/adt/pseudotypes.c:283 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "не можна прийняти значення типу shell" + +#: utils/adt/pseudotypes.c:293 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "не можна відобразити значення типу shell" + +#: utils/adt/rangetypes.c:406 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "аргумент позначок конструктору діапазону не може бути null" + +#: utils/adt/rangetypes.c:993 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "результат різниці діапазонів не буде безперервним" + +#: utils/adt/rangetypes.c:1054 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "результат об'єднання діапазонів не буде безперервним" + +#: utils/adt/rangetypes.c:1600 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "нижня границя діапазону повинна бути менше або дорівнювати верхній границі діапазону" + +#: utils/adt/rangetypes.c:1983 utils/adt/rangetypes.c:1996 +#: utils/adt/rangetypes.c:2010 +#, c-format +msgid "invalid range bound flags" +msgstr "неприпустимі позначки границь діапазону" + +#: utils/adt/rangetypes.c:1984 utils/adt/rangetypes.c:1997 +#: utils/adt/rangetypes.c:2011 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Припустимі значення \"[]\", \"[)\", \"(]\", і \"()\"." + +#: utils/adt/rangetypes.c:2076 utils/adt/rangetypes.c:2093 +#: utils/adt/rangetypes.c:2106 utils/adt/rangetypes.c:2124 +#: utils/adt/rangetypes.c:2135 utils/adt/rangetypes.c:2179 +#: utils/adt/rangetypes.c:2187 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "неправильний літерал діапазону: \"%s\"" + +#: utils/adt/rangetypes.c:2078 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "Сміття після ключового слова \"empty\"." + +#: utils/adt/rangetypes.c:2095 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Пропущено ліву дужку (круглу або квадратну)." + +#: utils/adt/rangetypes.c:2108 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Пропущено кому після нижньої границі." + +#: utils/adt/rangetypes.c:2126 +#, c-format +msgid "Too many commas." +msgstr "Занадто багато ком." + +#: utils/adt/rangetypes.c:2137 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "Сміття після правої дужки." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1543 utils/adt/varlena.c:4493 +#, c-format +msgid "regular expression failed: %s" +msgstr "помилка в регулярному виразі: %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%c\"" +msgstr "неприпустимий параметр регулярного виразу: \"%c\"" + +#: utils/adt/regexp.c:836 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "Регулярний вираз SQL не може містити більше двох роздільників escape-double-quote" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:981 utils/adt/regexp.c:1363 utils/adt/regexp.c:1418 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s не підтримує параметр \"global\"" + +#: utils/adt/regexp.c:983 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "Використайте функцію regexp_matches замість." + +#: utils/adt/regexp.c:1165 +#, c-format +msgid "too many regular expression matches" +msgstr "занадто багато відповідностей для регулярного виразу" + +#: utils/adt/regproc.c:107 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "ім'я \"%s\" мають декілька функцій" + +#: utils/adt/regproc.c:525 +#, c-format +msgid "more than one operator named %s" +msgstr "ім'я %s мають декілька операторів" + +#: utils/adt/regproc.c:692 utils/adt/regproc.c:733 gram.y:8223 +#, c-format +msgid "missing argument" +msgstr "пропущено аргумент" + +#: utils/adt/regproc.c:693 utils/adt/regproc.c:734 gram.y:8224 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "Щоб позначити пропущений аргумент унарного оператору, використайте NONE." + +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 utils/adt/regproc.c:2018 +#: utils/adt/ruleutils.c:9299 utils/adt/ruleutils.c:9468 +#, c-format +msgid "too many arguments" +msgstr "занадто багато аргументів" + +#: utils/adt/regproc.c:698 utils/adt/regproc.c:739 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Надайте для оператора два типи аргументів." + +#: utils/adt/regproc.c:1602 utils/adt/regproc.c:1626 utils/adt/regproc.c:1727 +#: utils/adt/regproc.c:1751 utils/adt/regproc.c:1853 utils/adt/regproc.c:1858 +#: utils/adt/varlena.c:3642 utils/adt/varlena.c:3647 +#, c-format +msgid "invalid name syntax" +msgstr "неприпустимий синтаксис в імені" + +#: utils/adt/regproc.c:1916 +#, c-format +msgid "expected a left parenthesis" +msgstr "очікувалась ліва дужка" + +#: utils/adt/regproc.c:1932 +#, c-format +msgid "expected a right parenthesis" +msgstr "очікувалась права дужка" + +#: utils/adt/regproc.c:1951 +#, c-format +msgid "expected a type name" +msgstr "очікувалось ім'я типу" + +#: utils/adt/regproc.c:1983 +#, c-format +msgid "improper type name" +msgstr "неправильне ім'я типу" + +#: utils/adt/ri_triggers.c:296 utils/adt/ri_triggers.c:1537 +#: utils/adt/ri_triggers.c:2470 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "insert або update в таблиці \"%s\" порушує обмеження зовнішнього ключа \"%s\"" + +#: utils/adt/ri_triggers.c:299 utils/adt/ri_triggers.c:1540 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL не дозволяє змішувати в значенні ключа null і nonnull." + +#: utils/adt/ri_triggers.c:1940 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "функція \"%s\" повинна запускатись для INSERT" + +#: utils/adt/ri_triggers.c:1946 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "функція \"%s\" повинна запускатись для UPDATE" + +#: utils/adt/ri_triggers.c:1952 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "функція \"%s\" повинна запускатись для DELETE" + +#: utils/adt/ri_triggers.c:1975 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "для тригеру \"%s\" таблиці \"%s\" немає введення pg_constraint" + +#: utils/adt/ri_triggers.c:1977 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "Видаліть цей тригер цілісності зв’язків і пов'язані об'єкти, а потім виконайте ALTER TABLE ADD CONSTRAINT." + +#: utils/adt/ri_triggers.c:2007 gram.y:3818 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "Вираз MATCH PARTIAL все ще не реалізований" + +#: utils/adt/ri_triggers.c:2295 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "неочікуваний результат запиту цілісності зв’язків до \"%s\" з обмеження \"%s\" таблиці \"%s\"" + +#: utils/adt/ri_triggers.c:2299 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Скоріше за все, це викликано правилом, яке переписало запит." + +#: utils/adt/ri_triggers.c:2460 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "видалення секції \"%s\" порушує обмеження зовнішнього ключа \"%s" + +#: utils/adt/ri_triggers.c:2463 utils/adt/ri_triggers.c:2488 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "На ключ (%s)=(%s) все ще є посилання в таблиці \"%s\"." + +#: utils/adt/ri_triggers.c:2474 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "Ключ (%s)=(%s) не присутній в таблиці \"%s\"." + +#: utils/adt/ri_triggers.c:2477 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "Ключ не присутній в таблиці \"%s\"." + +#: utils/adt/ri_triggers.c:2483 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "update або delete в таблиці \"%s\" порушує обмеження зовнішнього ключа \"%s\" таблиці \"%s\"" + +#: utils/adt/ri_triggers.c:2491 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "На ключ все ще є посилання в таблиці \"%s\"." + +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "введення анонімних складених типів не реалізовано" + +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 +#: utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "невірно сформований літерал запису: \"%s\"" + +#: utils/adt/rowtypes.c:157 +#, c-format +msgid "Missing left parenthesis." +msgstr "Відсутня ліва дужка." + +#: utils/adt/rowtypes.c:186 +#, c-format +msgid "Too few columns." +msgstr "Занадто мало стовпців." + +#: utils/adt/rowtypes.c:269 +#, c-format +msgid "Too many columns." +msgstr "Занадто багато стовпців." + +#: utils/adt/rowtypes.c:277 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Сміття післа правої дужки." + +#: utils/adt/rowtypes.c:531 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "неправильна кількість стовпців: %d, очікувалось %d" + +#: utils/adt/rowtypes.c:559 +#, c-format +msgid "wrong data type: %u, expected %u" +msgstr "неправильний тип даних: %u, очікувався %u" + +#: utils/adt/rowtypes.c:620 +#, c-format +msgid "improper binary format in record column %d" +msgstr "неправильний двійковий формат у стовпці запису %d" + +#: utils/adt/rowtypes.c:911 utils/adt/rowtypes.c:1157 utils/adt/rowtypes.c:1415 +#: utils/adt/rowtypes.c:1661 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "не можна порівнювати неподібні типи стовпців %s і %s, стовпець запису %d" + +#: utils/adt/rowtypes.c:1002 utils/adt/rowtypes.c:1227 +#: utils/adt/rowtypes.c:1512 utils/adt/rowtypes.c:1697 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "не можна порівнювати типи записів з різної кількістю стовпців" + +#: utils/adt/ruleutils.c:4821 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "правило \"%s\" має непідтримуваний тип подій %d" + +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "TIMESTAMP(%d)%s точність не повинна бути від'ємною" + +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIMESTAMP(%d)%s точність зменшена до дозволеного максимуму, %d" + +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:434 utils/misc/guc.c:11901 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "позначка часу поза діапазоном: \"%s\"" + +#: utils/adt/timestamp.c:372 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "точність позначки часу (%d) повинна бути між %d і %d" + +#: utils/adt/timestamp.c:496 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "Числові часові пояси повинні мати \"-\" або \"+\" в якості першого символу." + +#: utils/adt/timestamp.c:509 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "числовий часовий пояс \"%s\" поза діапазоном" + +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "позначка часу поза діапазоном: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:720 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "позначка часу не може бути NaN" + +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "позначка часу поза діапазоном: \"%g\"" + +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1509 +#: utils/adt/timestamp.c:1944 utils/adt/timestamp.c:3042 +#: utils/adt/timestamp.c:3047 utils/adt/timestamp.c:3052 +#: utils/adt/timestamp.c:3102 utils/adt/timestamp.c:3109 +#: utils/adt/timestamp.c:3116 utils/adt/timestamp.c:3136 +#: utils/adt/timestamp.c:3143 utils/adt/timestamp.c:3150 +#: utils/adt/timestamp.c:3180 utils/adt/timestamp.c:3188 +#: utils/adt/timestamp.c:3232 utils/adt/timestamp.c:3659 +#: utils/adt/timestamp.c:3784 utils/adt/timestamp.c:4244 +#, c-format +msgid "interval out of range" +msgstr "інтервал поза діапазоном" + +#: utils/adt/timestamp.c:1062 utils/adt/timestamp.c:1095 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "неприпустимий модифікатор типу INTERVAL" + +#: utils/adt/timestamp.c:1078 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d) точність не повинна бути від'ємною" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d) точність зменшена до максимально можливої, %d" + +#: utils/adt/timestamp.c:1466 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "interval(%d) точність повинна бути між %d і %d" + +#: utils/adt/timestamp.c:2643 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "віднімати безкінечні позначки часу не можна" + +#: utils/adt/timestamp.c:3912 utils/adt/timestamp.c:4505 +#: utils/adt/timestamp.c:4667 utils/adt/timestamp.c:4688 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "одиниці позначки часу \"%s\" не підтримуються" + +#: utils/adt/timestamp.c:3926 utils/adt/timestamp.c:4459 +#: utils/adt/timestamp.c:4698 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "одиниці позначки часу \"%s\" не розпізнані" + +#: utils/adt/timestamp.c:4056 utils/adt/timestamp.c:4500 +#: utils/adt/timestamp.c:4863 utils/adt/timestamp.c:4885 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "одиниці позначки часу з часовим поясом \"%s\" не підтримуються" + +#: utils/adt/timestamp.c:4073 utils/adt/timestamp.c:4454 +#: utils/adt/timestamp.c:4894 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "одиниці позначки часу з часовим поясом \"%s\" не розпізнані" + +#: utils/adt/timestamp.c:4231 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "одиниці інтервалу \"%s\" не підтримуються, тому, що місяці зазвичай мають дробове число тижнів" + +#: utils/adt/timestamp.c:4237 utils/adt/timestamp.c:4988 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "одиниці інтервалу \"%s\" не підтримуються" + +#: utils/adt/timestamp.c:4253 utils/adt/timestamp.c:5011 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "одиниці інтервалу \"%s\" не розпізнані" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: повинна викликатись як тригер" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: повинна викликатись при оновленні" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: повинна викликатись перед оновленням" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: повинна викликатис перед кожним рядком" + +#: utils/adt/tsgistidx.c:92 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "функція gtsvector_in не реалізована" + +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "дистанція у фразовому операторі повинна бути не більше %d" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "синтаксична помилка в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:334 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "немає оператора в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "занадто велике значення в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:573 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "занадто довгий операнд в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "занадто довге слово в tsquery: \"%s\"" + +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "запит пошуку тексту не містить лексем: \"%s\"" + +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsquery занадто великий" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "запит пошуку тексту ігнорується, тому, що містить лише стоп-слова або не містить лексем" + +#: utils/adt/tsquery_op.c:124 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "дистанція у фразовому операторі повинна бути невід'ємною і менше %d" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "запит ts_rewrite повинен повернути два стовпця типу tsquery" + +#: utils/adt/tsrank.c:412 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "масив значимості повинен бути одновимірним" + +#: utils/adt/tsrank.c:417 +#, c-format +msgid "array of weight is too short" +msgstr "масив значимості занадто малий" + +#: utils/adt/tsrank.c:422 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "масив значимості не повинен містити null" + +#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:872 +#, c-format +msgid "weight out of range" +msgstr "значимість поза діапазоном" + +#: utils/adt/tsvector.c:215 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "слово занадто довге (%ld байт, при максимумі %ld)" + +#: utils/adt/tsvector.c:222 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "рядок занадто довгий для tsvector (%ld байт, при максимумі %ld)" + +#: utils/adt/tsvector_op.c:328 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:770 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "масив лексем не може містити null" + +#: utils/adt/tsvector_op.c:840 +#, c-format +msgid "weight array may not contain nulls" +msgstr "масив значимості не може містити null" + +#: utils/adt/tsvector_op.c:864 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "нерозпізнана значимість: \"%c\"" + +#: utils/adt/tsvector_op.c:2414 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "запит ts_stat повинен повернути один стовпець tsvector" + +#: utils/adt/tsvector_op.c:2603 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "стовпець типу tsvector \"%s\" не існує" + +#: utils/adt/tsvector_op.c:2610 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "стовпець \"%s\" повинен мати тип tsvector" + +#: utils/adt/tsvector_op.c:2622 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "стовпець конфігурації \"%s\" не існує" + +#: utils/adt/tsvector_op.c:2628 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "стовпець \"%s\" повинен мати тип regconfig" + +#: utils/adt/tsvector_op.c:2635 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "значення стовпця конфігурації \"%s\" не повинне бути null" + +#: utils/adt/tsvector_op.c:2648 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "ім'я конфігурації текстового пошуку \"%s\" повинно вказуватися зі схемою" + +#: utils/adt/tsvector_op.c:2673 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "стовпець \"%s\" має не символьний тип" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "синтаксична помилка в tsvector: \"%s\"" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "немає пропущеного символу: \"%s\"" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "неправильна інформація про позицію в tsvector: \"%s\"" + +#: utils/adt/uuid.c:428 +#, c-format +msgid "could not generate random values" +msgstr "не вдалося згенерувати випадкові значення" + +#: utils/adt/varbit.c:109 utils/adt/varchar.c:53 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "довжина для типу %s повинна бути мінімум 1" + +#: utils/adt/varbit.c:114 utils/adt/varchar.c:57 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "довжина для типу %s не може перевищувати %d" + +#: utils/adt/varbit.c:197 utils/adt/varbit.c:498 utils/adt/varbit.c:993 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "довжина бітового рядка перевищує максимально допустиму (%d)" + +#: utils/adt/varbit.c:211 utils/adt/varbit.c:355 utils/adt/varbit.c:405 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "довжина бітового рядка %d не відповідає типу bit(%d)" + +#: utils/adt/varbit.c:233 utils/adt/varbit.c:534 +#, c-format +msgid "\"%c\" is not a valid binary digit" +msgstr "\"%c\" не є припустимою двійковою цифрою" + +#: utils/adt/varbit.c:258 utils/adt/varbit.c:559 +#, c-format +msgid "\"%c\" is not a valid hexadecimal digit" +msgstr "\"%c\" не є припустимою шістнадцятковою цифрою" + +#: utils/adt/varbit.c:346 utils/adt/varbit.c:651 +#, c-format +msgid "invalid length in external bit string" +msgstr "неприпустима довжина у зовнішньому рядку бітів" + +#: utils/adt/varbit.c:512 utils/adt/varbit.c:660 utils/adt/varbit.c:756 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "рядок бітів занадто довгий для типу bit varying(%d)" + +#: utils/adt/varbit.c:1086 utils/adt/varbit.c:1184 utils/adt/varlena.c:875 +#: utils/adt/varlena.c:939 utils/adt/varlena.c:1083 utils/adt/varlena.c:3306 +#: utils/adt/varlena.c:3373 +#, c-format +msgid "negative substring length not allowed" +msgstr "від'ємна довжина підрядка не дозволена" + +#: utils/adt/varbit.c:1241 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "не можна використовувати \"І\" (AND) для бітових рядків різного розміру" + +#: utils/adt/varbit.c:1282 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "не можна використовувати \"АБО\" (OR) для бітових рядків різного розміру" + +#: utils/adt/varbit.c:1322 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "не можна використовувати (XOR) для бітових рядків різного розміру" + +#: utils/adt/varbit.c:1804 utils/adt/varbit.c:1862 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "індекс біту %d поза припустимим діапазоном (0..%d)" + +#: utils/adt/varbit.c:1813 utils/adt/varlena.c:3566 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "новий біт повинен бути 0 або 1" + +#: utils/adt/varchar.c:157 utils/adt/varchar.c:310 +#, c-format +msgid "value too long for type character(%d)" +msgstr "значення занадто довге для типу character(%d)" + +#: utils/adt/varchar.c:472 utils/adt/varchar.c:634 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "значення занадто довге для типу character varying(%d)" + +#: utils/adt/varchar.c:732 utils/adt/varlena.c:1475 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "не вдалося визначити, який параметр сортування використати для порівняння рядків" + +#: utils/adt/varlena.c:1182 utils/adt/varlena.c:1915 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "недетерміновані параметри сортування не підтримуються для пошуку підрядків" + +#: utils/adt/varlena.c:1574 utils/adt/varlena.c:1587 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "не вдалося перетворити рядок в UTF-16: код помилки %lu" + +#: utils/adt/varlena.c:1602 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "не вдалося порівняти рядки в Unicode: %m" + +#: utils/adt/varlena.c:1653 utils/adt/varlena.c:2367 +#, c-format +msgid "collation failed: %s" +msgstr "помилка в бібліотеці сортування: %s" + +#: utils/adt/varlena.c:2575 +#, c-format +msgid "sort key generation failed: %s" +msgstr "не вдалося згенерувати ключ сортування: %s" + +#: utils/adt/varlena.c:3450 utils/adt/varlena.c:3517 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "індекс %d поза припустимим діапазоном, 0..%d" + +#: utils/adt/varlena.c:3481 utils/adt/varlena.c:3553 +#, c-format +msgid "index %lld out of valid range, 0..%lld" +msgstr "індекс %lld поза допустимим діапазоном, 0..%lld" + +#: utils/adt/varlena.c:4590 +#, c-format +msgid "field position must be greater than zero" +msgstr "позиція поля повинна бути більше нуля" + +#: utils/adt/varlena.c:5456 +#, c-format +msgid "unterminated format() type specifier" +msgstr "незавершений специфікатор типу format()" + +#: utils/adt/varlena.c:5457 utils/adt/varlena.c:5591 utils/adt/varlena.c:5712 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "Для представлення одного знаку \"%%\", використайте \"%%%%\"." + +#: utils/adt/varlena.c:5589 utils/adt/varlena.c:5710 +#, c-format +msgid "unrecognized format() type specifier \"%c\"" +msgstr "нерозпізнаний специфікатор типу format() \"%c\"" + +#: utils/adt/varlena.c:5602 utils/adt/varlena.c:5659 +#, c-format +msgid "too few arguments for format()" +msgstr "занадто мало аргументів для format()" + +#: utils/adt/varlena.c:5755 utils/adt/varlena.c:5937 +#, c-format +msgid "number is out of range" +msgstr "число поза діапазоном" + +#: utils/adt/varlena.c:5818 utils/adt/varlena.c:5846 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "формат посилається на аргумент 0, але аргументи нумеруются з 1" + +#: utils/adt/varlena.c:5839 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "вказівка аргументу ширини повинно закінчуватися \"$\"" + +#: utils/adt/varlena.c:5884 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "значення null не можна форматувати у вигляді SQL-ідентифікатору" + +#: utils/adt/varlena.c:6010 +#, c-format +msgid "Unicode normalization can only be performed if server encoding is UTF8" +msgstr "Нормалізація Unicode може виконуватись лише тоді, коли кодування серверу - UTF8" + +#: utils/adt/varlena.c:6023 +#, c-format +msgid "invalid normalization form: %s" +msgstr "неприпустима форма нормалізації: %s" + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "аргумент ntile повинен бути більше нуля" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "аргумент nth_value повинен бути більше нуля" + +#: utils/adt/xid8funcs.c:116 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "ідентифікатор транзакції %s відноситься до майбутнього" + +#: utils/adt/xid8funcs.c:547 +#, c-format +msgid "invalid external pg_snapshot data" +msgstr "неприпустимі зовнішні дані pg_snapshot" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "XML-функції не підтримуються" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Ця функціональність потребує, щоб сервер був побудований з підтримкою libxml." + +#: utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "Необхідно перебудувати PostgreSQL з ключем --with-libxml." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:570 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "неприпустиме ім’я кодування \"%s\"" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "неприпустимий XML-коментар" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "не XML-документ" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "неприпустима XML-команда обробки" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "Метою XML-команди обробки не може бути \"%s\"." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML-команда обробки не може містити \"?>\"." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "функція xmlvalidate не реалізована" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "не вдалося ініціалізувати бібліотеку XML" + +#: utils/adt/xml.c:962 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2 має несумісний тип char: sizeof(char)=%u, sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "не вдалося встановити обробник XML-помилок" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "Можливо це означає, що використовувана версія libxml2 несумісна з файлами-заголовками libxml2, з котрими був зібраний PostgreSQL." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "Неприпустиме значення символу." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "Потребується пробіл." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "значеннями атрибуту standalone можуть бути лише 'yes' або 'no'." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "Неправильне оголошення: пропущена версія." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "В оголошенні пропущене кодування." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "Аналіз XML-оголошення: '?>' очікується." + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "Нерозпізнаний код помилки libxml: %d." + +#: utils/adt/xml.c:2211 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML не підтримує безкінечні значення в датах." + +#: utils/adt/xml.c:2233 utils/adt/xml.c:2260 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML не підтримує безкінченні значення в позначках часу." + +#: utils/adt/xml.c:2676 +#, c-format +msgid "invalid query" +msgstr "неприпустимий запит" + +#: utils/adt/xml.c:4016 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "неприпустимий масив з зіставленням простіру імен XML" + +#: utils/adt/xml.c:4017 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "Масив повинен бути двовимірним і містити 2 елемента по другій вісі." + +#: utils/adt/xml.c:4041 +#, c-format +msgid "empty XPath expression" +msgstr "пустий вираз XPath" + +#: utils/adt/xml.c:4093 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "ні ім'я простіру імен ні URI не можуть бути null" + +#: utils/adt/xml.c:4100 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "не вдалося зареєструвати простір імен XML з ім'ям \"%s\" і URI \"%s\"" + +#: utils/adt/xml.c:4451 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "Простір імен DEFAULT не підтримується" + +#: utils/adt/xml.c:4480 +#, c-format +msgid "row path filter must not be empty string" +msgstr "шлях фільтруючих рядків не повинен бути пустим" + +#: utils/adt/xml.c:4511 +#, c-format +msgid "column path filter must not be empty string" +msgstr "шлях фільтруючого стовпця не повинен бути пустим" + +#: utils/adt/xml.c:4661 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "вираз XPath, який відбирає стовпець, повернув більше одного значення" + +#: utils/cache/lsyscache.c:1015 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "приведення від типу %s до типу %s не існує" + +#: utils/cache/lsyscache.c:2764 utils/cache/lsyscache.c:2797 +#: utils/cache/lsyscache.c:2830 utils/cache/lsyscache.c:2863 +#, c-format +msgid "type %s is only a shell" +msgstr "тип %s лише оболонка" + +#: utils/cache/lsyscache.c:2769 +#, c-format +msgid "no input function available for type %s" +msgstr "для типу %s немає доступної функції введення" + +#: utils/cache/lsyscache.c:2802 +#, c-format +msgid "no output function available for type %s" +msgstr "для типу %s немає доступної функції виводу" + +#: utils/cache/partcache.c:215 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "в класі операторів \"%s\" методу доступу %s пропущено опорну функцію %d для типу %s" + +#: utils/cache/plancache.c:718 +#, c-format +msgid "cached plan must not change result type" +msgstr "в кешованому плані не повинен змінюватись тип результату" + +#: utils/cache/relcache.c:6078 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "не вдалося створити файл ініціалізації для кешу відношень \"%s\": %m" + +#: utils/cache/relcache.c:6080 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Продовжуємо усе одно, але щось не так." + +#: utils/cache/relcache.c:6402 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "не вдалося видалити файл кешу \"%s\": %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "виконати PREPARE для транзакції, яка змінила зіставлення відношень, не можна" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "файл зіставлень відношень \"%s\" містить неприпустимі дані" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "файл зіставлень відношень \"%s\" містить неправильну контрольну суму" + +#: utils/cache/typcache.c:1692 utils/fmgr/funcapi.c:461 +#, c-format +msgid "record type has not been registered" +msgstr "тип запису не зареєстрований" + +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "TRAP: ExceptionalCondition: невірні аргументи\n" + +#: utils/error/assert.c:40 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "TRAP: %s(\"%s\", Файл: \"%s\", Рядок: %d)\n" + +#: utils/error/elog.c:322 +#, c-format +msgid "error occurred before error message processing is available\n" +msgstr "сталася помилка перед тим, як обробка повідомлення про помилку була доступна\n" + +#: utils/error/elog.c:1868 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "не вдалося повторно відкрити файл \"%s\" як stderr: %m" + +#: utils/error/elog.c:1881 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "не вдалося повторно відкрити файл \"%s\" як stdout: %m" + +#: utils/error/elog.c:2373 utils/error/elog.c:2407 utils/error/elog.c:2423 +msgid "[unknown]" +msgstr "[unknown]" + +#: utils/error/elog.c:2893 utils/error/elog.c:3203 utils/error/elog.c:3311 +msgid "missing error text" +msgstr "пропущено текст помилки" + +#: utils/error/elog.c:2896 utils/error/elog.c:2899 utils/error/elog.c:3314 +#: utils/error/elog.c:3317 +#, c-format +msgid " at character %d" +msgstr " символ %d" + +#: utils/error/elog.c:2909 utils/error/elog.c:2916 +msgid "DETAIL: " +msgstr "ВІДОМОСТІ: " + +#: utils/error/elog.c:2923 +msgid "HINT: " +msgstr "УКАЗІВКА: " + +#: utils/error/elog.c:2930 +msgid "QUERY: " +msgstr "ЗАПИТ: " + +#: utils/error/elog.c:2937 +msgid "CONTEXT: " +msgstr "КОНТЕКСТ: " + +#: utils/error/elog.c:2947 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "РОЗТАШУВАННЯ: %s, %s:%d\n" + +#: utils/error/elog.c:2954 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "РОЗТАШУВАННЯ: %s:%d\n" + +#: utils/error/elog.c:2961 +msgid "BACKTRACE: " +msgstr "ВІДСТЕЖУВАТИ: " + +#: utils/error/elog.c:2975 +msgid "STATEMENT: " +msgstr "ІНСТРУКЦІЯ: " + +#: utils/error/elog.c:3364 +msgid "DEBUG" +msgstr "НАЛАГОДЖЕННЯ" + +#: utils/error/elog.c:3368 +msgid "LOG" +msgstr "ЗАПИСУВАННЯ" + +#: utils/error/elog.c:3371 +msgid "INFO" +msgstr "ІНФОРМАЦІЯ" + +#: utils/error/elog.c:3374 +msgid "NOTICE" +msgstr "ПОВІДОМЛЕННЯ" + +#: utils/error/elog.c:3377 +msgid "WARNING" +msgstr "ПОПЕРЕДЖЕННЯ" + +#: utils/error/elog.c:3380 +msgid "ERROR" +msgstr "ПОМИЛКА" + +#: utils/error/elog.c:3383 +msgid "FATAL" +msgstr "ФАТАЛЬНО" + +#: utils/error/elog.c:3386 +msgid "PANIC" +msgstr "ПАНІКА" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "не вдалося знайти функцію \"%s\" у файлі \"%s\"" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "не вдалося завантажити бібліотеку \"%s\": %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "несумісная бібліотека \"%s\": пропущено магічний блок" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "Бібліотеки розширення потребують використання макросу PG_MODULE_MAGIC." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "несумісна бібліотека \"%s\": невідповідність версій" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "Версія серверу %d, версія бібліотеки %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "Сервер має FUNC_MAX_ARGS = %d, бібліотека має %d." + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "Сервер має INDEX_MAX_KEYS = %d, бібліотека має %d." + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "Сервер має NAMEDATALEN = %d, бібліотека має %d." + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "Сервер має FLOAT8PASSBYVAL = %s, бібліотека має %s." + +#: utils/fmgr/dfmgr.c:380 +msgid "Magic block has unexpected length or padding difference." +msgstr "Магічний блок має неочікувану довжину або інше заповнення." + +#: utils/fmgr/dfmgr.c:383 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "несумісна бібліотка \"%s\": невідповідність магічного блоку" + +#: utils/fmgr/dfmgr.c:547 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "доступ до бібліотеки \"%s\" не дозволений" + +#: utils/fmgr/dfmgr.c:573 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "неприпустиме ім'я макросу в шляху динамічної бібліотеки: %s" + +#: utils/fmgr/dfmgr.c:613 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "параметр \"dynamic_library_path\" містить компонент нульової довжини" + +#: utils/fmgr/dfmgr.c:632 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "параметр \"dynamic_library_path\" містить компонент, який не є абсолютним шляхом" + +#: utils/fmgr/fmgr.c:238 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "внутрішньої функції \"%s\" немає у внутрішній таблиці підстановки" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "не вдалося знайти інформацію про функцію \"%s\"" + +#: utils/fmgr/fmgr.c:489 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "Функції, які викликаються з SQL, потребують додаткове оголошення PG_FUNCTION_INFO_V1(ім'я_функції)." + +#: utils/fmgr/fmgr.c:507 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "нерозпізнана версія API %d, повідомлена інформаційною функцією \"%s\"" + +#: utils/fmgr/fmgr.c:2003 +#, c-format +msgid "operator class options info is absent in function call context" +msgstr "в контексті виклику функції відсутня інформація стосовно параметрів класів операторів" + +#: utils/fmgr/fmgr.c:2070 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "функція мовної перевірки %u викликана для мови %u замість %u" + +#: utils/fmgr/funcapi.c:384 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "не вдалося визначити фактичний тип результату для функції \"%s\" оголошеної як, та, котра повертає тип %s" + +#: utils/fmgr/funcapi.c:1651 utils/fmgr/funcapi.c:1683 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "кількість псевдонімів не відповідає кількості стовпців" + +#: utils/fmgr/funcapi.c:1677 +#, c-format +msgid "no column alias was provided" +msgstr "жодного псевдоніму для стовпця не було надано" + +#: utils/fmgr/funcapi.c:1701 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "не вдалося визначити опис рядка для функції, що повертає запис" + +#: utils/init/miscinit.c:285 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "каталог даних \"%s\" не існує" + +#: utils/init/miscinit.c:290 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "не вдалося прочитати дозволи на каталог \"%s\": %m" + +#: utils/init/miscinit.c:298 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "вказаний каталог даних \"%s\" не є каталогом" + +#: utils/init/miscinit.c:314 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "власник каталогу даних \"%s\" визначений неправильно" + +#: utils/init/miscinit.c:316 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "Сервер повинен запускати користувач, який володіє каталогом даних." + +#: utils/init/miscinit.c:334 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "каталог даних \"%s\" має неприпустимі дозволи" + +#: utils/init/miscinit.c:336 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Дозволи повинні бути u=rwx (0700) або u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:615 utils/misc/guc.c:7139 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "встановити параметр \"%s\" в межах операції з обмеженнями по безпеці, не можна" + +#: utils/init/miscinit.c:683 +#, c-format +msgid "role with OID %u does not exist" +msgstr "роль з OID %u не існує" + +#: utils/init/miscinit.c:713 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "для ролі \"%s\" вхід не дозволений" + +#: utils/init/miscinit.c:731 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "занадто багато підключень для ролі \"%s\"" + +#: utils/init/miscinit.c:791 +#, c-format +msgid "permission denied to set session authorization" +msgstr "немає прав для встановлення авторизації в сеансі" + +#: utils/init/miscinit.c:874 +#, c-format +msgid "invalid role OID: %u" +msgstr "неприпустимий OID ролі: %u" + +#: utils/init/miscinit.c:928 +#, c-format +msgid "database system is shut down" +msgstr "система бази даних вимкнена" + +#: utils/init/miscinit.c:1015 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "не вдалося створити файл блокування \"%s\": %m" + +#: utils/init/miscinit.c:1029 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "не вдалося відкрити файл блокування \"%s\": %m" + +#: utils/init/miscinit.c:1036 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "не вдалося прочитати файл блокування \"%s\": %m" + +#: utils/init/miscinit.c:1045 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "файл блокування \"%s\" пустий" + +#: utils/init/miscinit.c:1046 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "Або зараз запускається інший сервер, або цей файл блокування залишився в результаті збою під час попереднього запуску." + +#: utils/init/miscinit.c:1090 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "файл блокування \"%s\" вже існує" + +#: utils/init/miscinit.c:1094 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "Інший postgres (PID %d) працює з каталогом даних \"%s\"?" + +#: utils/init/miscinit.c:1096 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "Інший postmaster (PID %d) працює з каталогом даних \"%s\"?" + +#: utils/init/miscinit.c:1099 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "Інший postgres (PID %d) використовує файл сокету \"%s\"?" + +#: utils/init/miscinit.c:1101 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "Інший postmaster (PID %d) використовує файл сокету \"%s\"?" + +#: utils/init/miscinit.c:1152 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "не вдалося видалити старий файл блокування \"%s\": %m" + +#: utils/init/miscinit.c:1154 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "Здається, файл залишився випадково, але видалити його не вийшло. Будь-ласка, видаліть файл вручну або спробуйте знову." + +#: utils/init/miscinit.c:1191 utils/init/miscinit.c:1205 +#: utils/init/miscinit.c:1216 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "не вдалося записати файл блокування \"%s\": %m" + +#: utils/init/miscinit.c:1327 utils/init/miscinit.c:1469 utils/misc/guc.c:10038 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "не вдалося прочитати з файлу \"%s\": %m" + +#: utils/init/miscinit.c:1457 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "не вдалося відкрити файл \"%s\": %m; все одно продовжується" + +#: utils/init/miscinit.c:1482 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "файл блокування \"%s\" містить неправильний PID: %ld замість %ld" + +#: utils/init/miscinit.c:1521 utils/init/miscinit.c:1537 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\" не є припустимим каталогом даних" + +#: utils/init/miscinit.c:1523 +#, c-format +msgid "File \"%s\" is missing." +msgstr "Файл \"%s\" пропущено." + +#: utils/init/miscinit.c:1539 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "Файл \"%s\" не містить припустимих даних." + +#: utils/init/miscinit.c:1541 +#, c-format +msgid "You might need to initdb." +msgstr "Можливо, вам слід виконати initdb." + +#: utils/init/miscinit.c:1549 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "Каталог даних ініціалізований сервером PostgreSQL версії %s, не сумісною з цією версією %s." + +#: utils/init/miscinit.c:1616 +#, c-format +msgid "loaded library \"%s\"" +msgstr "завантажена бібліотека \"%s\"" + +#: utils/init/postinit.c:255 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "авторизовано підключення реплікації: користувач=%s назва_програми=%s SSL активовано (протокол=%s, шифр=%s, біти=%d, стискання=%s)" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "off" +msgstr "вимк" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "on" +msgstr "увімк" + +#: utils/init/postinit.c:262 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "підключення для реплікації авторизовано: користувач=%s SSL активований (протокол=%s, шифр=%s, біти=%d, стискання=%s)" + +#: utils/init/postinit.c:272 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s" +msgstr "авторизовано підключення реплікації: користувач=%s назва_програми=%s" + +#: utils/init/postinit.c:275 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "підключення для реплікації авторизовано: користувач=%s" + +#: utils/init/postinit.c:284 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "підключення авторизовано: користувач=%s база даних=%s назва_програми=%s SSL активовано (протокол=%s, шифр=%s, біти=%d, стискання=%s)" + +#: utils/init/postinit.c:290 +#, c-format +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "підключення для реплікації авторизовано: користувач=%s база даних=%s SSL активований (протокол=%s, шифр=%s, біти=%d, стискання=%s)" + +#: utils/init/postinit.c:300 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s" +msgstr "підключення авторизовано: користувач=%s база даних=%s назва_програми=%s" + +#: utils/init/postinit.c:302 +#, c-format +msgid "connection authorized: user=%s database=%s" +msgstr "підключення авторизовано: користувач=%s база даних=%s" + +#: utils/init/postinit.c:334 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "база даних \"%s\" зникла з pg_database" + +#: utils/init/postinit.c:336 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "Здається, база даних з OID %u тепер належить \"%s\"." + +#: utils/init/postinit.c:356 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "база даних \"%s\" не приймає підключення в даний момент" + +#: utils/init/postinit.c:369 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "доступ до бази даних \"%s\" відхилений" + +#: utils/init/postinit.c:370 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "Користувач не має права CONNECT." + +#: utils/init/postinit.c:387 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "занадто багато підключень до бази даних \"%s\"" + +#: utils/init/postinit.c:409 utils/init/postinit.c:416 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "локалізація бази даних несумісна з операційною системою" + +#: utils/init/postinit.c:410 +#, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "База даних була ініціалізована з параметром LC_COLLATE \"%s\", але зараз setlocale() не розпізнає його." + +#: utils/init/postinit.c:412 utils/init/postinit.c:419 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "Повторно створіть базу даних з іншою локалізацією або встановіть пропущену локалізацію." + +#: utils/init/postinit.c:417 +#, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "База даних була ініціалізована з параметром LC_CTYPE \"%s\", але зараз setlocale() не розпізнає його." + +#: utils/init/postinit.c:762 +#, c-format +msgid "no roles are defined in this database system" +msgstr "в цій системі баз даних не визначено жодної ролі" + +#: utils/init/postinit.c:763 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Ви повинні негайно виконати CREATE USER \"%s\" SUPERUSER;." + +#: utils/init/postinit.c:799 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "нові підключення для реплікації не дозволені під час завершення роботи бази даних" + +#: utils/init/postinit.c:803 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "потрібно бути суперкористувачем, щоб підключитись під час завершення роботи бази даних" + +#: utils/init/postinit.c:813 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "потрібно бути суперкористувачем, щоб підключитись в режимі двійкового оновлення" + +#: utils/init/postinit.c:826 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "слоти підключень, які залишились, зарезервовані для підключень суперкористувача (не для реплікації)" + +#: utils/init/postinit.c:836 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "для запуску процесу walsender потребується роль реплікації або бути суперкористувачем" + +#: utils/init/postinit.c:905 +#, c-format +msgid "database %u does not exist" +msgstr "база даних %u не існує" + +#: utils/init/postinit.c:994 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Схоже, вона щойно була видалена або перейменована." + +#: utils/init/postinit.c:1012 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Підкаталог бази даних \"%s\" пропущений." + +#: utils/init/postinit.c:1017 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "немає доступу до каталогу \"%s\": %m" + +#: utils/mb/conv.c:443 utils/mb/conv.c:635 +#, c-format +msgid "invalid encoding number: %d" +msgstr "неприпустимий номер кодування: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "неочікуваний ідентифікатор кодування %d для наборів символів ISO 8859" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "неочікуваний ідентифікатор кодування %d для наборів символів WIN" + +#: utils/mb/mbutils.c:297 utils/mb/mbutils.c:842 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "перетворення між %s і %s не підтримується" + +#: utils/mb/mbutils.c:385 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "функції за замовчуванням перетворення з кодування \"%s\" в \"%s\" не існує" + +#: utils/mb/mbutils.c:402 utils/mb/mbutils.c:429 utils/mb/mbutils.c:758 +#: utils/mb/mbutils.c:784 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "Рядок з %d байт занадто довгий для перетворення кодування." + +#: utils/mb/mbutils.c:511 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "неприпустиме ім’я вихідного кодування \"%s\"" + +#: utils/mb/mbutils.c:516 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "неприпустиме ім’я кодування результату \"%s\"" + +#: utils/mb/mbutils.c:656 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "неприпустиме значення байту для кодування \"%s\": 0x%02x" + +#: utils/mb/mbutils.c:819 +#, c-format +msgid "invalid Unicode code point" +msgstr "неприпустима кодова точка Unicode" + +#: utils/mb/mbutils.c:1087 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "помилка в bind_textdomain_codeset" + +#: utils/mb/mbutils.c:1595 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "неприпустима послідовність байтів для кодування \"%s\": %s" + +#: utils/mb/mbutils.c:1628 +#, c-format +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "символ з послідовністю байтів %s в кодуванні \"%s\" не має еквіваленту в кодуванні \"%s\"" + +#: utils/misc/guc.c:679 +msgid "Ungrouped" +msgstr "Розгруповано" + +#: utils/misc/guc.c:681 +msgid "File Locations" +msgstr "Розташування файлів" + +#: utils/misc/guc.c:683 +msgid "Connections and Authentication" +msgstr "Підключення і автентифікація" + +#: utils/misc/guc.c:685 +msgid "Connections and Authentication / Connection Settings" +msgstr "Підключення і автентифікація / Параметри підключень" + +#: utils/misc/guc.c:687 +msgid "Connections and Authentication / Authentication" +msgstr "Підключення і автентифікація / Автентифікація" + +#: utils/misc/guc.c:689 +msgid "Connections and Authentication / SSL" +msgstr "Підключення і автентифікація / SSL" + +#: utils/misc/guc.c:691 +msgid "Resource Usage" +msgstr "Використання ресурсу" + +#: utils/misc/guc.c:693 +msgid "Resource Usage / Memory" +msgstr "Використання ресурсу / Пам'ять" + +#: utils/misc/guc.c:695 +msgid "Resource Usage / Disk" +msgstr "Використання ресурсу / Диск" + +#: utils/misc/guc.c:697 +msgid "Resource Usage / Kernel Resources" +msgstr "Використання ресурсу / Ресурси ядра" + +#: utils/misc/guc.c:699 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Використання ресурсу / Затримка очистки по вартості" + +#: utils/misc/guc.c:701 +msgid "Resource Usage / Background Writer" +msgstr "Використання ресурсу / Фоновий запис" + +#: utils/misc/guc.c:703 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Використання ресурсу / Асинхронна поведінка" + +#: utils/misc/guc.c:705 +msgid "Write-Ahead Log" +msgstr "Журнал WAL" + +#: utils/misc/guc.c:707 +msgid "Write-Ahead Log / Settings" +msgstr "Журнал WAL / Параметри" + +#: utils/misc/guc.c:709 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Журнал WAL / Контрольні точки" + +#: utils/misc/guc.c:711 +msgid "Write-Ahead Log / Archiving" +msgstr "Журнал WAL / Архівація" + +#: utils/misc/guc.c:713 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Журнал WAL / Відновлення архіву" + +#: utils/misc/guc.c:715 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Журнал WAL / Мета відновлення" + +#: utils/misc/guc.c:717 +msgid "Replication" +msgstr "Реплікація" + +#: utils/misc/guc.c:719 +msgid "Replication / Sending Servers" +msgstr "Реплікація / Надсилання серверів" + +#: utils/misc/guc.c:721 +msgid "Replication / Master Server" +msgstr "Реплікація / Головний сервер" + +#: utils/misc/guc.c:723 +msgid "Replication / Standby Servers" +msgstr "Реплікація / Резервні сервера" + +#: utils/misc/guc.c:725 +msgid "Replication / Subscribers" +msgstr "Реплікація / Підписники" + +#: utils/misc/guc.c:727 +msgid "Query Tuning" +msgstr "Налаштування запитів" + +#: utils/misc/guc.c:729 +msgid "Query Tuning / Planner Method Configuration" +msgstr "Налаштування запитів / Конфігурація методів планувальника" + +#: utils/misc/guc.c:731 +msgid "Query Tuning / Planner Cost Constants" +msgstr "Налаштування запитів / Константи вартості для планувальника" + +#: utils/misc/guc.c:733 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "Налаштування запитів / Генетичний оптимізатор запитів" + +#: utils/misc/guc.c:735 +msgid "Query Tuning / Other Planner Options" +msgstr "Налаштування запитів / Інші параметри планувальника" + +#: utils/misc/guc.c:737 +msgid "Reporting and Logging" +msgstr "Звіти і журналювання" + +#: utils/misc/guc.c:739 +msgid "Reporting and Logging / Where to Log" +msgstr "Звіти і журналювання / Куди записувати" + +#: utils/misc/guc.c:741 +msgid "Reporting and Logging / When to Log" +msgstr "Звіти і журналювання / Коли записувати" + +#: utils/misc/guc.c:743 +msgid "Reporting and Logging / What to Log" +msgstr "Звіти і журналювання / Що записувати" + +#: utils/misc/guc.c:745 +msgid "Process Title" +msgstr "Заголовок процесу" + +#: utils/misc/guc.c:747 +msgid "Statistics" +msgstr "Статистика" + +#: utils/misc/guc.c:749 +msgid "Statistics / Monitoring" +msgstr "Статистика / Моніторинг" + +#: utils/misc/guc.c:751 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "Статистика / Збирач статистики по запитам і індексам" + +#: utils/misc/guc.c:753 +msgid "Autovacuum" +msgstr "Автоочистка" + +#: utils/misc/guc.c:755 +msgid "Client Connection Defaults" +msgstr "Параметри клієнтських сеансів за замовчуванням" + +#: utils/misc/guc.c:757 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "Параметри клієнтських сеансів за замовчуванням / Поведінка декларацій" + +#: utils/misc/guc.c:759 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "Параметри клієнтських сеансів за замовчуванням / Локалізація і форматування" + +#: utils/misc/guc.c:761 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "Параметри клієнтських сеансів за замовчуванням / Попереднє завантаження спільних бібліотек" + +#: utils/misc/guc.c:763 +msgid "Client Connection Defaults / Other Defaults" +msgstr "Параметри клієнтських сеансів за замовчуванням / Інші параметри за замовчуванням" + +#: utils/misc/guc.c:765 +msgid "Lock Management" +msgstr "Керування блокуванням" + +#: utils/misc/guc.c:767 +msgid "Version and Platform Compatibility" +msgstr "Сумісність версій і платформ" + +#: utils/misc/guc.c:769 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Сумісність версій і платформ / Попередні версії PostgreSQL" + +#: utils/misc/guc.c:771 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Сумісність версій і платформ / Інші платформи і клієнти" + +#: utils/misc/guc.c:773 +msgid "Error Handling" +msgstr "Обробка помилок" + +#: utils/misc/guc.c:775 +msgid "Preset Options" +msgstr "Визначені параметри" + +#: utils/misc/guc.c:777 +msgid "Customized Options" +msgstr "Настроєні параметри" + +#: utils/misc/guc.c:779 +msgid "Developer Options" +msgstr "Параметри для розробників" + +#: utils/misc/guc.c:837 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Припустимі одиниці для цього параметру: \"B\", \"kB\", \"MB\", \"GB\", і \"TB\"." + +#: utils/misc/guc.c:874 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Припустимі одиниці для цього параметру: \"us\", \"ms\", \"s\", \"min\", \"h\", і \"d\"." + +#: utils/misc/guc.c:936 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "Дає змогу планувальнику використати плани послідовного сканування." + +#: utils/misc/guc.c:946 +msgid "Enables the planner's use of index-scan plans." +msgstr "Дає змогу планувальнику використати плани сканування по індексу." + +#: utils/misc/guc.c:956 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Дає змогу планувальнику використати плани сканування лише індекса." + +#: utils/misc/guc.c:966 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "Дає змогу планувальнику використати плани сканування по точковому рисунку." + +#: utils/misc/guc.c:976 +msgid "Enables the planner's use of TID scan plans." +msgstr "Дає змогу планувальнику використати плани сканування TID." + +#: utils/misc/guc.c:986 +msgid "Enables the planner's use of explicit sort steps." +msgstr "Дає змогу планувальнику використати кроки з явним сортуванням." + +#: utils/misc/guc.c:996 +msgid "Enables the planner's use of incremental sort steps." +msgstr "Дає змогу планувальнику використати кроки інкрементного сортування." + +#: utils/misc/guc.c:1005 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Дає змогу планувальнику використовувати плани агрегації по гешу." + +#: utils/misc/guc.c:1015 +msgid "Enables the planner's use of materialization." +msgstr "Дає змогу планувальнику використовувати матеріалізацію." + +#: utils/misc/guc.c:1025 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "Дає змогу планувальнику використовувати плани з'єднання з вкладеними циклами." + +#: utils/misc/guc.c:1035 +msgid "Enables the planner's use of merge join plans." +msgstr "Дає змогу планувальнику використовувати плани з'єднання об'єднанням." + +#: utils/misc/guc.c:1045 +msgid "Enables the planner's use of hash join plans." +msgstr "Дає змогу планувальнику використовувати плани з'єднання по гешу." + +#: utils/misc/guc.c:1055 +msgid "Enables the planner's use of gather merge plans." +msgstr "Дає змогу планувальнику використовувати плани збору об'єднанням." + +#: utils/misc/guc.c:1065 +msgid "Enables partitionwise join." +msgstr "Вмикає з'єднання з урахуванням секціонування." + +#: utils/misc/guc.c:1075 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Вмикає агрегацію і групування з урахуванням секціонування." + +#: utils/misc/guc.c:1085 +msgid "Enables the planner's use of parallel append plans." +msgstr "Дає змогу планувальнику використовувати плани паралельного додавання." + +#: utils/misc/guc.c:1095 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Дає змогу планувальнику використовувати плани паралельного з'єднання по гешу." + +#: utils/misc/guc.c:1105 +msgid "Enables plan-time and run-time partition pruning." +msgstr "Вмикає видалення секцій під час планування і виконання запитів." + +#: utils/misc/guc.c:1106 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Дозволяє планувальнику і виконавцю запитів порівнювати границі секцій з умовами в запиті і визначати які секції повинні бути відскановані." + +#: utils/misc/guc.c:1117 +msgid "Enables genetic query optimization." +msgstr "Вмикає генетичну оптимізацію запитів." + +#: utils/misc/guc.c:1118 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Цей алгоритм намагається побудувати план без повного перебору." + +#: utils/misc/guc.c:1129 +msgid "Shows whether the current user is a superuser." +msgstr "Показує, чи є поточний користувач суперкористувачем." + +#: utils/misc/guc.c:1139 +msgid "Enables advertising the server via Bonjour." +msgstr "Вмикає оголошення серверу через Bonjour." + +#: utils/misc/guc.c:1148 +msgid "Collects transaction commit time." +msgstr "Збирає час затвердження транзакцій." + +#: utils/misc/guc.c:1157 +msgid "Enables SSL connections." +msgstr "Вмикає SSL-підключення." + +#: utils/misc/guc.c:1166 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Також використовувати ssl_passphrase_command під час перезавантаження серверу." + +#: utils/misc/guc.c:1175 +msgid "Give priority to server ciphersuite order." +msgstr "Віддавати перевагу замовленню набору шрифтів сервера." + +#: utils/misc/guc.c:1184 +msgid "Forces synchronization of updates to disk." +msgstr "Примусова синхронізація оновлень на диск." + +#: utils/misc/guc.c:1185 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "Сервер буде використовувати системний виклик fsync() в декількох місцях, щоб впевнитись, що оновлення фізично записані на диск. Це дозволить привести кластер бази даних в узгоджений стан після аварійного завершення роботи операційної системи або апаратного забезпечення." + +#: utils/misc/guc.c:1196 +msgid "Continues processing after a checksum failure." +msgstr "Продовжує обробку після помилки контрольної суми." + +#: utils/misc/guc.c:1197 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "Виявляючи помилку контрольної суми, PostgreSQL звичайно повідомляє про помилку і перериває поточну транзакцію. Але якщо ignore_checksum_failure дорівнює true, система пропустить помилку (але видасть попередження) і продовжить обробку. Ця поведінка може бути причиною аварійних завершень роботи або інших серйозних проблем. Це має місце, лише якщо ввімкнен контроль цілосності сторінок." + +#: utils/misc/guc.c:1211 +msgid "Continues processing past damaged page headers." +msgstr "Продовжує обробку при пошкоджені заголовків сторінок." + +#: utils/misc/guc.c:1212 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "Виявляючи пошкоджений заголовок сторінки, PostgreSQL звичайно повідомляє про помилку, перериваючи поточну транзакцію. Але якщо zero_damaged_pages дорівнює true система видасть попередження, обнулить пошкоджену сторінку, і продовжить обробку. Ця поведінка знищить дані, а саме рядків в пошкодженій сторінці." + +#: utils/misc/guc.c:1225 +msgid "Continues recovery after an invalid pages failure." +msgstr "Продовжує відновлення після помилки неприпустимих сторінок." + +#: utils/misc/guc.c:1226 +msgid "Detection of WAL records having references to invalid pages during recovery causes PostgreSQL to raise a PANIC-level error, aborting the recovery. Setting ignore_invalid_pages to true causes the system to ignore invalid page references in WAL records (but still report a warning), and continue recovery. This behavior may cause crashes, data loss, propagate or hide corruption, or other serious problems. Only has an effect during recovery or in standby mode." +msgstr "Виявлення WAL записів, які мають посилання на неприпустимі сторінки під час відновлення, змушує PostgreSQL підняти помилку на рівень PANIC, перериваючи відновлення. Встановлення параметру ignore_invalid_pages на true змусить систему ігнорувати неприпустимі посилання на сторінки в WAL записах (але все ще буде повідомляти про попередження), і продовжити відновлення. Ця поведінка може викликати збої, втрату даних, розповсюдження або приховання пошкоджень, або інші серйозні проблеми. Діє лише під час відновлення або в режимі очікування." + +#: utils/misc/guc.c:1244 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "Запис повних сторінок до WAL при першій зміні після контрольної точки." + +#: utils/misc/guc.c:1245 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "Сторінка, записувана під час аварійного завершення роботи операційної системи може бути записаною на диск частково. Під час відновлення, журналу змін рядків в WAL буде недостатньо для відновлення. Цей параметр записує повні сторінки після першої зміни після контрольної точки, тож відновлення можливе." + +#: utils/misc/guc.c:1258 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "Запис повних сторінок до WAL при першій зміні після контрольної точки, навіть при некритичних змінах." + +#: utils/misc/guc.c:1268 +msgid "Compresses full-page writes written in WAL file." +msgstr "Стискати дані під час запису повних сторінок до файлу WAL." + +#: utils/misc/guc.c:1278 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Перед першим використанням записує нулі до нових файлів WAL." + +#: utils/misc/guc.c:1288 +msgid "Recycles WAL files by renaming them." +msgstr "Перезаписує файли WAL, перейменувавши їх." + +#: utils/misc/guc.c:1298 +msgid "Logs each checkpoint." +msgstr "Журналювати кожну контрольну точку." + +#: utils/misc/guc.c:1307 +msgid "Logs each successful connection." +msgstr "Журналювати кожне успішне підключення." + +#: utils/misc/guc.c:1316 +msgid "Logs end of a session, including duration." +msgstr "Журналювати кінець сеансу, зокрема тривалість." + +#: utils/misc/guc.c:1325 +msgid "Logs each replication command." +msgstr "Журналювати кожну команду реплікації." + +#: utils/misc/guc.c:1334 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Показує, чи активовані перевірки твердження на працюючому сервері." + +#: utils/misc/guc.c:1349 +msgid "Terminate session on any error." +msgstr "Припиняти сеанси при будь-якій помилці." + +#: utils/misc/guc.c:1358 +msgid "Reinitialize server after backend crash." +msgstr "Повторити ініціалізацію сервера, після внутрішнього аварійного завершення роботи." + +#: utils/misc/guc.c:1368 +msgid "Logs the duration of each completed SQL statement." +msgstr "Журналювати тривалість кожного виконаного SQL-оператора." + +#: utils/misc/guc.c:1377 +msgid "Logs each query's parse tree." +msgstr "Журналювати дерево аналізу для кожного запиту." + +#: utils/misc/guc.c:1386 +msgid "Logs each query's rewritten parse tree." +msgstr "Журналювати переписане дерево аналізу для кожного запиту." + +#: utils/misc/guc.c:1395 +msgid "Logs each query's execution plan." +msgstr "Журналювати план виконання кожного запиту." + +#: utils/misc/guc.c:1404 +msgid "Indents parse and plan tree displays." +msgstr "Відступи при відображенні дерев аналізу і плану запитів." + +#: utils/misc/guc.c:1413 +msgid "Writes parser performance statistics to the server log." +msgstr "Запис статистики продуктивності аналізу до запису сервера." + +#: utils/misc/guc.c:1422 +msgid "Writes planner performance statistics to the server log." +msgstr "Запис статистики продуктивності планувальника до запису сервера." + +#: utils/misc/guc.c:1431 +msgid "Writes executor performance statistics to the server log." +msgstr "Запис статистики продуктивності виконувача до запису сервера." + +#: utils/misc/guc.c:1440 +msgid "Writes cumulative performance statistics to the server log." +msgstr "Запис сукупної статистики продуктивності до запису сервера." + +#: utils/misc/guc.c:1450 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "Журналювати статистику використання системних ресурсів (пам'яті і ЦП) при різноманітних операціях з B-tree." + +#: utils/misc/guc.c:1462 +msgid "Collects information about executing commands." +msgstr "Збирати інформацію про команди які виконуються." + +#: utils/misc/guc.c:1463 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "Активує збір інформації про поточні команди, які виконуються в кожному сеансі, разом з часом запуску команди." + +#: utils/misc/guc.c:1473 +msgid "Collects statistics on database activity." +msgstr "Збирати статистику про активність бази даних." + +#: utils/misc/guc.c:1482 +msgid "Collects timing statistics for database I/O activity." +msgstr "Збирати статистику за часом активності введення/виведення для бази даних." + +#: utils/misc/guc.c:1492 +msgid "Updates the process title to show the active SQL command." +msgstr "Оновлення виводить в заголовок процесу активну SQL-команду." + +#: utils/misc/guc.c:1493 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "Відображає в заголовку процеса кожну SQL-команду, отриману сервером." + +#: utils/misc/guc.c:1506 +msgid "Starts the autovacuum subprocess." +msgstr "Запускає підпроцес автоочистки." + +#: utils/misc/guc.c:1516 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "Генерує налагодженні повідомлення для LISTEN і NOTIFY." + +#: utils/misc/guc.c:1528 +msgid "Emits information about lock usage." +msgstr "Видає інформацію про блокування, які використовуються." + +#: utils/misc/guc.c:1538 +msgid "Emits information about user lock usage." +msgstr "Видає інформацію про користувацькі блокування, які використовуються." + +#: utils/misc/guc.c:1548 +msgid "Emits information about lightweight lock usage." +msgstr "Видає інформацію про спрощені блокування, які використовуються." + +#: utils/misc/guc.c:1558 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "Виводить інформацію про всі поточні блокування, при тайм-ауті взаємного блокування." + +#: utils/misc/guc.c:1570 +msgid "Logs long lock waits." +msgstr "Журналювати тривалі очікування в блокуваннях." + +#: utils/misc/guc.c:1580 +msgid "Logs the host name in the connection logs." +msgstr "Журналювати ім’я хоста до записів підключення." + +#: utils/misc/guc.c:1581 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "За замовчуванням, записи підключень показують лише IP-адреси хостів, які підключилися. Якщо ви хочете бачити імена хостів ви можете ввімкнути цей параметр, але врахуйте, що це може значно вплинути на продуктивність." + +#: utils/misc/guc.c:1592 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "Вважати \"expr=NULL\" як \"expr IS NULL\"." + +#: utils/misc/guc.c:1593 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "Коли цей параметр ввімкнений, вирази форми expr = NULL (або NULL = expr) вважаються як expr IS NULL, тобто, повертають true, якщо expr співпадає зі значенням null, і false в іншому разі. Правильна поведінка expr = NULL - завжди повертати null (невідомо)." + +#: utils/misc/guc.c:1605 +msgid "Enables per-database user names." +msgstr "Вмикає зв'язування імен користувачів з базами даних." + +#: utils/misc/guc.c:1614 +msgid "Sets the default read-only status of new transactions." +msgstr "Встановлює статус \"лише читання\" за замовчуванням для нових транзакцій." + +#: utils/misc/guc.c:1623 +msgid "Sets the current transaction's read-only status." +msgstr "Встановлює статус \"лише читання\" для поточної транзакції." + +#: utils/misc/guc.c:1633 +msgid "Sets the default deferrable status of new transactions." +msgstr "Встановлює статус відкладеного виконання за замовчуванням для нових транзакцій." + +#: utils/misc/guc.c:1642 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "Визначає, чи відкладати серіалізовану транзакцію \"лише читання\" до моменту, коли збій серіалізації буде виключений." + +#: utils/misc/guc.c:1652 +msgid "Enable row security." +msgstr "Вмикає захист на рівні рядків." + +#: utils/misc/guc.c:1653 +msgid "When enabled, row security will be applied to all users." +msgstr "Коли ввімкнено, захист на рівні рядків буде застосовано до всіх користувачів." + +#: utils/misc/guc.c:1661 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "Перевіряти тіло функції під час CREATE FUNCTION." + +#: utils/misc/guc.c:1670 +msgid "Enable input of NULL elements in arrays." +msgstr "Дозволяє введення NULL елементів у масивах." + +#: utils/misc/guc.c:1671 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "Коли цей параметр ввімкнений, NULL без лапок при введенні до масиву сприймається як значення null; в іншому разі як рядок." + +#: utils/misc/guc.c:1687 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OIDS більше не підтримується; це може бути помилковим." + +#: utils/misc/guc.c:1697 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "Запускає підпроцес записування виводу stderr і/або csvlogs до файлів журналу." + +#: utils/misc/guc.c:1706 +msgid "Truncate existing log files of same name during log rotation." +msgstr "Скорочувати існуючі файли журналу з тим самим іменем під час обертання журналу." + +#: utils/misc/guc.c:1717 +msgid "Emit information about resource usage in sorting." +msgstr "Виводити інформацію про використання ресурсу при сортуванні." + +#: utils/misc/guc.c:1731 +msgid "Generate debugging output for synchronized scanning." +msgstr "Створює налагодженні повідомлення для синхронного сканування." + +#: utils/misc/guc.c:1746 +msgid "Enable bounded sorting using heap sort." +msgstr "Вмикає обмежене сортування використовуючи динамічне сортування." + +#: utils/misc/guc.c:1759 +msgid "Emit WAL-related debugging output." +msgstr "Виводити налагодженні повідомлення пов'язані з WAL." + +#: utils/misc/guc.c:1771 +msgid "Datetimes are integer based." +msgstr "Дата й час на базі цілого числа." + +#: utils/misc/guc.c:1782 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "Встановлює обробку без урахування регістру імен користувачів Kerberos і GSSAPI." + +#: utils/misc/guc.c:1792 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Попередження про спецсимволи \"\\\" в звичайних рядках." + +#: utils/misc/guc.c:1802 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "Вмикає буквальну обробку символів \"\\\" в рядках '...'." + +#: utils/misc/guc.c:1813 +msgid "Enable synchronized sequential scans." +msgstr "Вмикає синхронізацію послідовного сканування." + +#: utils/misc/guc.c:1823 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Встановлює, включати чи виключати транзакції з метою відновлення." + +#: utils/misc/guc.c:1833 +msgid "Allows connections and queries during recovery." +msgstr "Дозволяє підключення і запити під час відновлення." + +#: utils/misc/guc.c:1843 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "Дозволяє зворотній зв'язок серверу hot standby з основним для уникнення конфліктів запитів." + +#: utils/misc/guc.c:1853 +msgid "Allows modifications of the structure of system tables." +msgstr "Дозволяє модифікації структури системних таблиць." + +#: utils/misc/guc.c:1864 +msgid "Disables reading from system indexes." +msgstr "Вимикає читання з системних індексів." + +#: utils/misc/guc.c:1865 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "Це не забороняє оновлення індексів, тож дана поведінка безпечна. Найгірший наслідок це сповільнення." + +#: utils/misc/guc.c:1876 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "Вмикає режим зворотньої сумісності при перевірці прав для великих об'єктів." + +#: utils/misc/guc.c:1877 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "Пропускає перевірки прав при читанні або зміненні великих об'єктів, для сумісності з версіями PostgreSQL до 9.0." + +#: utils/misc/guc.c:1887 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "Видає попередження для конструкцій, значення яких змінилось після PostgreSQL 9.4." + +#: utils/misc/guc.c:1897 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "Генеруючи SQL-фрагменти, включати всі ідентифікатори в лапки." + +#: utils/misc/guc.c:1907 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Показує, чи ввімкнена контрольна сума даних для цього кластеру." + +#: utils/misc/guc.c:1918 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "Додає послідовне число до повідомлень syslog, щоб уникнути ігнорування дублікатів." + +#: utils/misc/guc.c:1928 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "Розділяє повідомлення, які передаються в syslog, рядками розміром не більше 1024 байт." + +#: utils/misc/guc.c:1938 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Визначає, чи вузли зібрання і зібрання об'єднанням також виконають підплани." + +#: utils/misc/guc.c:1939 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "Чи повинні вузли зібрання також виконувати підплани, або тільки збирати кортежі?" + +#: utils/misc/guc.c:1949 +msgid "Allow JIT compilation." +msgstr "Дозволити JIT-компіляцію." + +#: utils/misc/guc.c:1960 +msgid "Register JIT compiled function with debugger." +msgstr "Реєструвати JIT-скомпільовані функції в налагоджувачі." + +#: utils/misc/guc.c:1977 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Виводити бітовий код LLVM для полегшення налагодження JIT." + +#: utils/misc/guc.c:1988 +msgid "Allow JIT compilation of expressions." +msgstr "Дозволити JIT-компіляцію виразів." + +#: utils/misc/guc.c:1999 +msgid "Register JIT compiled function with perf profiler." +msgstr "Реєструвати JIT-скомпільовані функції в профілювальнику perf." + +#: utils/misc/guc.c:2016 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Дозволити JIT-компіляцію перетворення кортежів." + +#: utils/misc/guc.c:2027 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Чи продовжувати виконання після помилки синхронізації файлів даних на диску." + +#: utils/misc/guc.c:2036 +msgid "Sets whether a WAL receiver should create a temporary replication slot if no permanent slot is configured." +msgstr "Встановлює чи повинен одержувач WAL створити тимчасовий слот реплікації, якщо постійний слот не налаштований." + +#: utils/misc/guc.c:2054 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "Примусово переключитися на наступний файл WAL, якщо новий файл не був розпочат за N секунд." + +#: utils/misc/guc.c:2065 +msgid "Waits N seconds on connection startup after authentication." +msgstr "Чекати N секунд при підключенні після автентифікації." + +#: utils/misc/guc.c:2066 utils/misc/guc.c:2624 +msgid "This allows attaching a debugger to the process." +msgstr "Це дозволяє підключити налагоджувач до процесу." + +#: utils/misc/guc.c:2075 +msgid "Sets the default statistics target." +msgstr "Встановлює мету статистики за замовчуванням." + +#: utils/misc/guc.c:2076 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "Це застосовується до стовпців таблиці, для котрих мета статистики не встановлена явно через ALTER TABLE SET STATISTICS." + +#: utils/misc/guc.c:2085 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "Встановлює розмір для списку FROM, при перевищені котрого вкладені запити не згортаються." + +#: utils/misc/guc.c:2087 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "Планувальник об'єднає вкладені запити з зовнішніми, якщо в отриманому списку FROM буде не більше заданої кількості елементів." + +#: utils/misc/guc.c:2098 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "Встановлює розмір для списку FROM, при перевищенні котрого конструкції JOIN не подаються у вигляді рядка." + +#: utils/misc/guc.c:2100 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "Планувальник буде подавати у вигляді рядка явні конструкції JOIN в списки FROM, допоки в отриманому списку не більше заданої кількості елементів." + +#: utils/misc/guc.c:2111 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "Встановлює граничне значення для елементів FROM, при перевищенні котрого використовується GEQO." + +#: utils/misc/guc.c:2121 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: зусилля використовувались щоб встановити значення за замовчуванням для інших параметрів GEQO." + +#: utils/misc/guc.c:2131 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: кількість користувачів у популяції." + +#: utils/misc/guc.c:2132 utils/misc/guc.c:2142 +msgid "Zero selects a suitable default value." +msgstr "Нуль вибирає придатне значення за замовчуванням." + +#: utils/misc/guc.c:2141 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: кількість ітерацій в алгоритмі." + +#: utils/misc/guc.c:2153 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Встановлює час очікування в блокуванні до перевірки на взаємне блокування." + +#: utils/misc/guc.c:2164 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "Встановлює максимальну затримку до скасування запитів, коли hot standby сервер обробляє архівні дані WAL." + +#: utils/misc/guc.c:2175 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "Встановлює максимальну затримку до скасування запитів, коли hot standby сервер обробляє дані WAL з потоку." + +#: utils/misc/guc.c:2186 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "Встановлює мінімальну затримку для застосування змін під час відновлення." + +#: utils/misc/guc.c:2197 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "Встановлює максимальний інтервал між звітами про стан одержувачів WAL для серверу надсилання." + +#: utils/misc/guc.c:2208 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "Встановлює максимальний час очікування для отримання даних з серверу надсилання." + +#: utils/misc/guc.c:2219 +msgid "Sets the maximum number of concurrent connections." +msgstr "Встановлює максимальну кілкість паралельних підключень." + +#: utils/misc/guc.c:2230 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "Встановлює кількість зарезервованих слотів підключень для суперкористувачів." + +#: utils/misc/guc.c:2244 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Встановлює кількість буферів спільної пам'яті, використовуваних сервером." + +#: utils/misc/guc.c:2255 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Встановлює максимальну кількість використовуваних тимчасових буферів, для кожного сеансу." + +#: utils/misc/guc.c:2266 +msgid "Sets the TCP port the server listens on." +msgstr "Встановлює TCP-порт для роботи серверу." + +#: utils/misc/guc.c:2276 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Встановлює дозволи на доступ для Unix-сокету." + +#: utils/misc/guc.c:2277 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Для Unix-сокетів використовується звичний набір дозволів, як у файлових системах Unix. Очікується, що значення параметра вказується у формі, яка прийнята для системних викликів chmod і umask. (Щоб використати звичний вісімковий формат, додайте в початок 0 (нуль).)" + +#: utils/misc/guc.c:2291 +msgid "Sets the file permissions for log files." +msgstr "Встановлює права дозволу для файлів журналу." + +#: utils/misc/guc.c:2292 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Очікується, що значення параметру буде вказано в числовому форматі, який сприймається системними викликами chmod і umask. (Щоб використати звичний вісімковий формат, додайте в початок 0 (нуль).)" + +#: utils/misc/guc.c:2306 +msgid "Mode of the data directory." +msgstr "Режим каталогу даних." + +#: utils/misc/guc.c:2307 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Значення параметру вказується в числовому форматі, який сприймається системними викликами chmod і umask. (Щоб використати звичний вісімковий формат, додайте в початок 0 (нуль).)" + +#: utils/misc/guc.c:2320 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Встановлює максимальний об'єм пам'яті для робочих просторів запитів." + +#: utils/misc/guc.c:2321 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "Такий об'єм пам'яті може використовуватись кожною внутрішньою операцією сортування і таблицею гешування до переключення на тимчасові файли на диску." + +#: utils/misc/guc.c:2333 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Встановлює максимальний об'єм пам'яті для операцій по обслуговуванню." + +#: utils/misc/guc.c:2334 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Це включає такі операції як VACUUM і CREATE INDEX." + +#: utils/misc/guc.c:2344 +msgid "Sets the maximum memory to be used for logical decoding." +msgstr "Встановлює максимальний об'єм пам'яті для логічного декодування." + +#: utils/misc/guc.c:2345 +msgid "This much memory can be used by each internal reorder buffer before spilling to disk." +msgstr "Ця велика кількість пам'яті може бути використана кожним внутрішнім перевпорядковуючим буфером перед записом на диск." + +#: utils/misc/guc.c:2361 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Встановлює максимальну глибину стека, в КБ." + +#: utils/misc/guc.c:2372 +msgid "Limits the total size of all temporary files used by each process." +msgstr "Обмежує загальний розмір всіх тимчасових файлів, які використовуються кожним процесом." + +#: utils/misc/guc.c:2373 +msgid "-1 means no limit." +msgstr "-1 вимикає обмеження." + +#: utils/misc/guc.c:2383 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Вартість очистки для сторінки, яка була знайдена в буферному кеші." + +#: utils/misc/guc.c:2393 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Вартість очистки для сторінки, яка не була знайдена в буферному кеші." + +#: utils/misc/guc.c:2403 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Вартість очистки для сторінки, яка не була \"брудною\"." + +#: utils/misc/guc.c:2413 +msgid "Vacuum cost amount available before napping." +msgstr "Кількість доступних витрат вакууму перед від'єднанням." + +#: utils/misc/guc.c:2423 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "Кількість доступних витрат вакууму перед від'єднанням, для автовакууму." + +#: utils/misc/guc.c:2433 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "Встановлює максимальну кількість одночасно відкритих файлів для кожного процесу." + +#: utils/misc/guc.c:2446 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Встановлює максимальну кількість одночасно підготовлених транзакцій." + +#: utils/misc/guc.c:2457 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Встановлює мінімальний OID таблиць, для яких відстежуються блокування." + +#: utils/misc/guc.c:2458 +msgid "Is used to avoid output on system tables." +msgstr "Використовується для уникнення системних таблиць." + +#: utils/misc/guc.c:2467 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "Встановлює OID таблиці для безумовного трасування блокувань." + +#: utils/misc/guc.c:2479 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Встановлює максимальну тривалість для будь-якого оператору." + +#: utils/misc/guc.c:2480 utils/misc/guc.c:2491 utils/misc/guc.c:2502 +msgid "A value of 0 turns off the timeout." +msgstr "Значення 0 (нуль) вимикає тайм-аут." + +#: utils/misc/guc.c:2490 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Встановлює максимально дозволену тривалість очікування блокувань." + +#: utils/misc/guc.c:2501 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "Встановлює максимально дозволену тривалість для транзакцій, які простоюють." + +#: utils/misc/guc.c:2512 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "Мінімальний вік рядків таблиці, при котрому VACUUM зможе їх закріпити." + +#: utils/misc/guc.c:2522 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "Вік, при котрому VACUUM повинен сканувати всю таблицю, щоб закріпити кортежі." + +#: utils/misc/guc.c:2532 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "Мінімальний вік, при котрому VACUUM повинен закріпити MultiXactId в рядку таблиці." + +#: utils/misc/guc.c:2542 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "Вік Multixact, при котрому VACUUM повинен сканувати всю таблицю, щоб закріпити кортежі." + +#: utils/misc/guc.c:2552 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "Визначає, кількість транзакцій які потрібно буде відкласти, виконуючи VACUUM і HOT очищення." + +#: utils/misc/guc.c:2565 +msgid "Sets the maximum number of locks per transaction." +msgstr "Встановлює максимальну кілкість блокувань на транзакцію." + +#: utils/misc/guc.c:2566 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Розмір спільної таблиці блокувань вибирається з припущення, що в один момент часу буде потрібно заблокувати не більше ніж max_locks_per_transaction * max_connections різних об'єктів." + +#: utils/misc/guc.c:2577 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Встановлює максимальну кількість предикатних блокувань на транзакцію." + +#: utils/misc/guc.c:2578 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Розмір спільної таблиці предикатних блокувань вибирається з припущення, що в один момент часу буде потрібно заблокувати не більше ніж max_locks_per_transaction * max_connections різних об'єктів." + +#: utils/misc/guc.c:2589 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Встановлює максимальну кількість сторінок і кортежів, блокованих предикатними блокуваннями в одному відношенні." + +#: utils/misc/guc.c:2590 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Якщо одним підключенням блокується більше цієї загальної кількості сторінок і кортежів, ці блокування замінюються блокуванням на рівні відношення." + +#: utils/misc/guc.c:2600 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Встановлює максимальну кількість кортежів, блокованих предикатними блокуваннями в одній сторінці." + +#: utils/misc/guc.c:2601 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Якщо одним підключенням блокується більше цієї кількості кортежів на одній і тій же сторінці, ці блокування замінюються блокуванням на рівні сторінки." + +#: utils/misc/guc.c:2611 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "Встановлює максимально допустимий час, за котрий клієнт повинен завершити автентифікацію." + +#: utils/misc/guc.c:2623 +msgid "Waits N seconds on connection startup before authentication." +msgstr "Чекати N секунд при підключенні до автентифікації." + +#: utils/misc/guc.c:2634 +msgid "Sets the size of WAL files held for standby servers." +msgstr "Встановлює розмір WAL файлів, які потрібно зберігати для резервних серверів." + +#: utils/misc/guc.c:2645 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "Встановлює мінімальний розмір WAL при стисканні." + +#: utils/misc/guc.c:2657 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Встановлює розмір WAL, при котрому ініціюється контрольна точка." + +#: utils/misc/guc.c:2669 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "Встановлює максимальний час між автоматичними контрольними точками WAL." + +#: utils/misc/guc.c:2680 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "Видає попередження, якщо сегменти контрольних точок заповнуються частіше." + +#: utils/misc/guc.c:2682 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "Записує в запис серверу повідомлення, якщо контрольні точки, викликані переповненням файлів сегментів контрольних точок, з'являються частіше. 0 (нуль) вимикає попередження." + +#: utils/misc/guc.c:2694 utils/misc/guc.c:2910 utils/misc/guc.c:2957 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "Число сторінок, після досягнення якого раніше виконані операції запису скидаються на диск." + +#: utils/misc/guc.c:2705 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "Встановлює кількість буферів дискових сторінок в спільній пам'яті для WAL." + +#: utils/misc/guc.c:2716 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "Час між скиданням WAL в процесі, записуючого WAL." + +#: utils/misc/guc.c:2727 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "Обсяг WAL, оброблений пишучим WAL процесом, при котрому ініціюється скидання журналу на диск." + +#: utils/misc/guc.c:2738 +msgid "Size of new file to fsync instead of writing WAL." +msgstr "Розмір нового файлу для fsync замість записування WAL." + +#: utils/misc/guc.c:2749 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "Встановлює максимальну кількість одночасно працюючих процесів передачі WAL." + +#: utils/misc/guc.c:2760 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Встановлює максимальну кількість одночасно визначених слотів реплікації." + +#: utils/misc/guc.c:2770 +msgid "Sets the maximum WAL size that can be reserved by replication slots." +msgstr "Встановлює максимальний розмір WAL, який може бути зарезервований слотами реплікації." + +#: utils/misc/guc.c:2771 +msgid "Replication slots will be marked as failed, and segments released for deletion or recycling, if this much space is occupied by WAL on disk." +msgstr "Слоти реплікації будуть позначені як невдалі, і розблоковані сегменти для видалення або переробки, якщо цю кількість місця на диску займає WAL." + +#: utils/misc/guc.c:2783 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "Встановлює максимальний час очікування реплікації WAL." + +#: utils/misc/guc.c:2794 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "Встановлює затримку в мілісекундах між затвердженням транзакцій і скиданням WAL на диск." + +#: utils/misc/guc.c:2806 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "Встановлює мінімальну кількість одночасно відкритих транзакцій до виконання commit_delay." + +#: utils/misc/guc.c:2817 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Встановлює кількість виведених чисел для значень з плаваючою точкою." + +#: utils/misc/guc.c:2818 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "Це впливає на типи реальних, подвійної точності та геометричних даних. Нульове або від'ємне значення параметру додається до стандартної кількості цифр (FLT_DIG або DBL_DIG у відповідних випадках). Будь-яке значення більше нуля, обирає точний режим виводу." + +#: utils/misc/guc.c:2830 +msgid "Sets the minimum execution time above which a sample of statements will be logged. Sampling is determined by log_statement_sample_rate." +msgstr "Встановлює мінімальний час виконання, понад якого вибірка тверджень буде записуватись. Вибірка визначається log_statement_sample_rate." + +#: utils/misc/guc.c:2833 +msgid "Zero logs a sample of all queries. -1 turns this feature off." +msgstr "При 0 (нуль) фіксує зразок всіх запитів. -1 вимикає цю функцію." + +#: utils/misc/guc.c:2843 +msgid "Sets the minimum execution time above which all statements will be logged." +msgstr "Встановлює мінімальний час виконання, понад якого всі твердження будуть записуватись." + +#: utils/misc/guc.c:2845 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "При 0 (нуль) протоколюються всі запити. -1 вимикає цю функцію." + +#: utils/misc/guc.c:2855 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "Встановлює мінімальний час виконання автоочистки, при перевищенні котрого ця дія фіксується в протоколі." + +#: utils/misc/guc.c:2857 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "При 0 (нуль) протоколюються всі дії автоочистки. -1 вимикає журналювання автоочистки." + +#: utils/misc/guc.c:2867 +msgid "When logging statements, limit logged parameter values to first N bytes." +msgstr "Під час журналювання тверджень, обмежте записуваних параметрів до перших N байт." + +#: utils/misc/guc.c:2868 utils/misc/guc.c:2879 +msgid "-1 to print values in full." +msgstr "-1 для друку значень в повному вигляді." + +#: utils/misc/guc.c:2878 +msgid "When reporting an error, limit logged parameter values to first N bytes." +msgstr "Під час звітування про помилку, обмежте значення записуваних параметрів до перших N байт." + +#: utils/misc/guc.c:2889 +msgid "Background writer sleep time between rounds." +msgstr "Час призупинення в процесі фонового запису між підходами." + +#: utils/misc/guc.c:2900 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "Максимальна кількість LRU-сторінок, які скидаються за один підхід, в процесі фонового запису." + +#: utils/misc/guc.c:2923 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "Кількість одночасних запитів, які можуть бути ефективно оброблені дисковою підсистемою." + +#: utils/misc/guc.c:2924 +msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +msgstr "Для RAID-масивів це повинно приблизно дорівнювати кількості фізичних дисків у масиві." + +#: utils/misc/guc.c:2941 +msgid "A variant of effective_io_concurrency that is used for maintenance work." +msgstr "Варіант effective_io_concurrency, що використовується для роботи з обслуговування." + +#: utils/misc/guc.c:2970 +msgid "Maximum number of concurrent worker processes." +msgstr "Максимальна кількість одночасно працюючих процесів." + +#: utils/misc/guc.c:2982 +msgid "Maximum number of logical replication worker processes." +msgstr "Максимальна кількість працюючих процесів логічної реплікації." + +#: utils/misc/guc.c:2994 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Максимальна кількість процесів синхронізації таблиць для однієї підписки." + +#: utils/misc/guc.c:3004 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "Автоматичне обертання файлу протоколу буде здійснюватись через кожні N хвилин." + +#: utils/misc/guc.c:3015 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "Автоматичне обертання файлу протоколу буде здійснюватись після кожних N кілобайт." + +#: utils/misc/guc.c:3026 +msgid "Shows the maximum number of function arguments." +msgstr "Показує максимальну кількість аргументів функції." + +#: utils/misc/guc.c:3037 +msgid "Shows the maximum number of index keys." +msgstr "Показує максимальну кількість ключів в індексі." + +#: utils/misc/guc.c:3048 +msgid "Shows the maximum identifier length." +msgstr "Показує максимальну довжину ідентифікатора." + +#: utils/misc/guc.c:3059 +msgid "Shows the size of a disk block." +msgstr "Показує розмір дискового блоку." + +#: utils/misc/guc.c:3070 +msgid "Shows the number of pages per disk file." +msgstr "Показує кількість сторінок в одному дисковому файлі." + +#: utils/misc/guc.c:3081 +msgid "Shows the block size in the write ahead log." +msgstr "Показує розмір блоку в журналі WAL." + +#: utils/misc/guc.c:3092 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "Встановлює час очікування перед повторною спробою звертання до WAL після невдачі." + +#: utils/misc/guc.c:3104 +msgid "Shows the size of write ahead log segments." +msgstr "Показує розмір сегментів WAL." + +#: utils/misc/guc.c:3117 +msgid "Time to sleep between autovacuum runs." +msgstr "Час призупинення між запусками автоочистки." + +#: utils/misc/guc.c:3127 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Мінімальна кількість оновлень або видалень кортежів перед очисткою." + +#: utils/misc/guc.c:3136 +msgid "Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums." +msgstr "Мінімальна кількість вставлених кортежів перед очищенням, або -1 щоб вимкнути очищення після вставки." + +#: utils/misc/guc.c:3145 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "Мінімальна кількість вставлень, оновлень або видалень кортежів перед аналізом." + +#: utils/misc/guc.c:3155 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "Вік, при котрому необхідна автоочистка таблиці для запобігання зациклення ID транзакцій." + +#: utils/misc/guc.c:3166 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "Вік Multixact, при котрому необхідна автоочистка таблиці для запобігання зациклення multixact." + +#: utils/misc/guc.c:3176 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "Встановлює максимальну кількість одночасно працюючих робочих процесів автоочистки." + +#: utils/misc/guc.c:3186 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Встановлює максимальну кількість паралельних процесів на одну операцію обслуговування." + +#: utils/misc/guc.c:3196 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Встановлює максимальну кількість паралельних процесів на вузол виконавця." + +#: utils/misc/guc.c:3207 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Встановлює максимальну кількість паралельних процесів, які можуть бути активні в один момент." + +#: utils/misc/guc.c:3218 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "Встановлює максимальний об'єм пам'яті для кожного робочого процесу автоочистки." + +#: utils/misc/guc.c:3229 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "Термін, після закінчення котрого знімок вважається занадто старим для отримання сторінок, змінених після створення знімку." + +#: utils/misc/guc.c:3230 +msgid "A value of -1 disables this feature." +msgstr "Значення -1 вимикає цю функцію." + +#: utils/misc/guc.c:3240 +msgid "Time between issuing TCP keepalives." +msgstr "Час між видачею TCP keepalives." + +#: utils/misc/guc.c:3241 utils/misc/guc.c:3252 utils/misc/guc.c:3376 +msgid "A value of 0 uses the system default." +msgstr "Значення 0 (нуль) використовує систему за замовчуванням." + +#: utils/misc/guc.c:3251 +msgid "Time between TCP keepalive retransmits." +msgstr "Час між повтореннями TCP keepalive." + +#: utils/misc/guc.c:3262 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "Повторне узгодження SSL більше не підтримується; єдине допустиме значення - 0 (нуль)." + +#: utils/misc/guc.c:3273 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "Максимальна кількість повторень TCP keepalive." + +#: utils/misc/guc.c:3274 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "Цей параметр визначає, яка кількість послідовних повторень keepalive може бути втрачена, перед тим як підключення буде вважатись \"мертвим\". Значення 0 (нуль) використовує систему за замовчуванням." + +#: utils/misc/guc.c:3285 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "Встановлює максимально допустимий результат для точного пошуку з використанням GIN." + +#: utils/misc/guc.c:3296 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Встановлює планувальнику припустимий загальний розмір кешей даних." + +#: utils/misc/guc.c:3297 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Мається на увазі загальний розмір кешей (кеша ядра і спільних буферів), які використовуються для файлів даних PostgreSQL. Розмір задається в дискових сторінках, звичайно це 8 КБ." + +#: utils/misc/guc.c:3308 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "Встановлює мінімальний обсяг даних в таблиці для паралельного сканування." + +#: utils/misc/guc.c:3309 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Якщо планувальник вважає, що він прочитає меньше сторінок таблиці, ніж задано цим обмеженням, паралельне сканування не буде розглядатись." + +#: utils/misc/guc.c:3319 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "Встановлює мінімальний обсяг даних в індексі для паралельного сканування." + +#: utils/misc/guc.c:3320 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Якщо планувальник вважає, що він прочитає меньше сторінок індексу, ніж задано цим обмеженням, паралельне сканування не буде розглядатись." + +#: utils/misc/guc.c:3331 +msgid "Shows the server version as an integer." +msgstr "Показує версію сервера у вигляді цілого числа." + +#: utils/misc/guc.c:3342 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "Записує до протоколу перевищення тимчасовими файлами заданого розміру в КБ." + +#: utils/misc/guc.c:3343 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "0 (нуль) фіксує всі файли. -1 вимикає цю функцію (за замовчуванням)." + +#: utils/misc/guc.c:3353 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "Встановлює розмір, зарезервований для pg_stat_activity.query, в байтах." + +#: utils/misc/guc.c:3364 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "Встановлює максимальний розмір списку-очікування для GIN-індексу." + +#: utils/misc/guc.c:3375 +msgid "TCP user timeout." +msgstr "Таймаут користувача TCP." + +#: utils/misc/guc.c:3395 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "Встановлює для планувальника орієнтир вартості послідовного читання дискових сторінок." + +#: utils/misc/guc.c:3406 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "Встановлює для планувальника орієнтир вартості непослідовного читання дискових сторінок." + +#: utils/misc/guc.c:3417 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "Встановлює для планувальника орієнтир вартості обробки кожного кортежу (рядка)." + +#: utils/misc/guc.c:3428 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "Встановлює для планувальника орієнтир вартості обробки кожного елементу індекса під час сканування індексу." + +#: utils/misc/guc.c:3439 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "Встановлює для планувальника орієнтир вартості обробки кожного оператора або виклику функції." + +#: utils/misc/guc.c:3450 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgstr "Встановлює для планувальника орієнтир вартості передавання кожного кортежу (рядка) від робочого процесу обслуговуючому процесу." + +#: utils/misc/guc.c:3461 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "Встановлює для планувальника орієнтир вартості запуску робочих процесів для паралельного запиту." + +#: utils/misc/guc.c:3473 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Якщо запит дорожчий, виконується JIT-компіляція." + +#: utils/misc/guc.c:3474 +msgid "-1 disables JIT compilation." +msgstr "-1 вимикає JIT-компіляцію." + +#: utils/misc/guc.c:3484 +msgid "Optimize JITed functions if query is more expensive." +msgstr "Якщо запит дорожчий, оптимізуютьсяв JITed-функції." + +#: utils/misc/guc.c:3485 +msgid "-1 disables optimization." +msgstr "-1 вимикає оптимізацію." + +#: utils/misc/guc.c:3495 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Якщо запит дорожчий, виконується вбудовування JIT." + +#: utils/misc/guc.c:3496 +msgid "-1 disables inlining." +msgstr "-1 вимикає вбудовування." + +#: utils/misc/guc.c:3506 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "Встановлює для планувальника орієнтир частки необхідних рядків курсора в загальній кількості." + +#: utils/misc/guc.c:3518 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: вибірковий тиск в популяції." + +#: utils/misc/guc.c:3529 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: відправна значення для випадкового вибору шляху." + +#: utils/misc/guc.c:3540 +msgid "Multiple of work_mem to use for hash tables." +msgstr "Декілька work_mem для використання геш-таблиць." + +#: utils/misc/guc.c:3551 +msgid "Multiple of the average buffer usage to free per round." +msgstr "Множник для середньої кількості використаних буферів, який визначає кількість буферів, які звільняються за один підхід." + +#: utils/misc/guc.c:3561 +msgid "Sets the seed for random-number generation." +msgstr "Встановлює відправне значення для генератора випадкових чисел." + +#: utils/misc/guc.c:3572 +msgid "Vacuum cost delay in milliseconds." +msgstr "Затримка вартості очистки в мілісекундах." + +#: utils/misc/guc.c:3583 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Затримка вартості очистки в мілісекундах, для автоочистки." + +#: utils/misc/guc.c:3594 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "Кількість оновлень або видалень кортежів до reltuples, яка визначає потребу в очистці." + +#: utils/misc/guc.c:3604 +msgid "Number of tuple inserts prior to vacuum as a fraction of reltuples." +msgstr "Кількість вставлень кортежів до reltuples, яка визначає потребу в очистці." + +#: utils/misc/guc.c:3614 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "Кількість вставлень, оновлень або видалень кортежів до reltuples, яка визначає потребу в аналізі." + +#: utils/misc/guc.c:3624 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "Час тривалості очищення \"брудних\" буферів під час контрольної точки до інтервалу контрольних точок." + +#: utils/misc/guc.c:3634 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "Кількість вставлень кортежів до reltuples, яка визначає потребу в очистці індекса." + +#: utils/misc/guc.c:3644 +msgid "Fraction of statements exceeding log_min_duration_sample to be logged." +msgstr "Частка тверджень, перевищує log_min_duration_sample, що підлягає запису." + +#: utils/misc/guc.c:3645 +msgid "Use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "Використайте значення між 0.0 (ніколи не записувати) і 1.0 (завжди записувати)." + +#: utils/misc/guc.c:3654 +msgid "Set the fraction of transactions to log for new transactions." +msgstr "Встановіть частину транзакцій для запису нових транзакцій." + +#: utils/misc/guc.c:3655 +msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "Журналює всі вирази з частини транзакцій. Використайте значення між 0.0 (ніколи не записувати) і 1.0 (записувати всі вирази для всіх транзакцій)." + +#: utils/misc/guc.c:3675 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "Встановлює команду оболонки, яка буде викликатись для архівації файлу WAL." + +#: utils/misc/guc.c:3685 +msgid "Sets the shell command that will be called to retrieve an archived WAL file." +msgstr "Встановлює команду оболонки, яка буде викликана для отримання архівованого файлу WAL." + +#: utils/misc/guc.c:3695 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "Встановлює команду оболонки, яка буде виконуватися в кожній точці перезапуску." + +#: utils/misc/guc.c:3705 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "Встановлює команду оболонки, яка буде виконуватися один раз в кінці відновлення." + +#: utils/misc/guc.c:3715 +msgid "Specifies the timeline to recover into." +msgstr "Вказує лінію часу для відновлення." + +#: utils/misc/guc.c:3725 +msgid "Set to \"immediate\" to end recovery as soon as a consistent state is reached." +msgstr "Встановіть на \"негайно\" щоб закінчити відновлення як тільки буде досягнуто узгодженого стану." + +#: utils/misc/guc.c:3734 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "Встановлює ідентифікатор транзакції, до якої буде продовжуватися відновлення." + +#: utils/misc/guc.c:3743 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "Встановлює позначку часу, до якої буде продовжуватися відновлення." + +#: utils/misc/guc.c:3752 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "Встановлює назву точки відновлення, до якої буде продовжуватися відновлення." + +#: utils/misc/guc.c:3761 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "Встановлює номер LSN розташування випереджувального журналювання, до якого буде продовжуватися відновлення." + +#: utils/misc/guc.c:3771 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "Вказує назву файлу, наявність якого закінчує відновлення в режимі очікування." + +#: utils/misc/guc.c:3781 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "Встановлює рядок підключення який буде використовуватися для підключення до серверу надсилання." + +#: utils/misc/guc.c:3792 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "Встановлює назву слота реплікації, для використання на сервері надсилання." + +#: utils/misc/guc.c:3802 +msgid "Sets the client's character set encoding." +msgstr "Встановлює кодування символів, використовуване клієнтом." + +#: utils/misc/guc.c:3813 +msgid "Controls information prefixed to each log line." +msgstr "Визначає інформацію префікса кожного рядка протокола." + +#: utils/misc/guc.c:3814 +msgid "If blank, no prefix is used." +msgstr "При пустому значенні, префікс також відсутній." + +#: utils/misc/guc.c:3823 +msgid "Sets the time zone to use in log messages." +msgstr "Встановлює часовий пояс для виведення часу в повідомленях протокола." + +#: utils/misc/guc.c:3833 +msgid "Sets the display format for date and time values." +msgstr "Встановлює формат виведення значень часу і дат." + +#: utils/misc/guc.c:3834 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "Також визначає багатозначні задані дати, які вводяться." + +#: utils/misc/guc.c:3845 +msgid "Sets the default table access method for new tables." +msgstr "Встановлює метод доступу до таблиці за замовчуванням для нових таблиць." + +#: utils/misc/guc.c:3856 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "Встановлює табличний простір за замовчуванням, для створення таблиць і індексів." + +#: utils/misc/guc.c:3857 +msgid "An empty string selects the database's default tablespace." +msgstr "Пустий рядок вибирає табличний простір за замовчуванням бази даних." + +#: utils/misc/guc.c:3867 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "Встановлює табличний простір(простори) для використання в тимчасових таблицях і файлах сортування." + +#: utils/misc/guc.c:3878 +msgid "Sets the path for dynamically loadable modules." +msgstr "Встановлює шлях для динамічно завантажуваних модулів." + +#: utils/misc/guc.c:3879 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "Якщо динамічно завантажений модуль потрібно відкрити і у вказаному імені немає компонента каталогу (наприклад, ім'я не містить символ \"/\"), система буде шукати цей шлях у вказаному файлі." + +#: utils/misc/guc.c:3892 +msgid "Sets the location of the Kerberos server key file." +msgstr "Встановлює розташування файлу з ключем Kerberos для даного сервера." + +#: utils/misc/guc.c:3903 +msgid "Sets the Bonjour service name." +msgstr "Встановлює ім'я служби Bonjour." + +#: utils/misc/guc.c:3915 +msgid "Shows the collation order locale." +msgstr "Показує порядок локалізації параметра сортування." + +#: utils/misc/guc.c:3926 +msgid "Shows the character classification and case conversion locale." +msgstr "Показує класифікацію символу і перетворення локалізації." + +#: utils/misc/guc.c:3937 +msgid "Sets the language in which messages are displayed." +msgstr "Встановлює мову виведених повідомлень." + +#: utils/misc/guc.c:3947 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Встановлює локалізацію для форматування грошових сум." + +#: utils/misc/guc.c:3957 +msgid "Sets the locale for formatting numbers." +msgstr "Встановлює локалізацію для форматування чисел." + +#: utils/misc/guc.c:3967 +msgid "Sets the locale for formatting date and time values." +msgstr "Встановлює локалізацію для форматування значень дати і часу." + +#: utils/misc/guc.c:3977 +msgid "Lists shared libraries to preload into each backend." +msgstr "Список спільних бібліотек, попередньо завантажених до кожного внутрішнього серверу." + +#: utils/misc/guc.c:3988 +msgid "Lists shared libraries to preload into server." +msgstr "Список спільних бібліотек, попередньо завантажених до серверу." + +#: utils/misc/guc.c:3999 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "Список непривілейованих спільних бібліотек, попередньо завантажених до кожного внутрішнього серверу." + +#: utils/misc/guc.c:4010 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "Встановлює порядок пошуку схеми для імен, які не є схемо-кваліфікованими." + +#: utils/misc/guc.c:4022 +msgid "Sets the server (database) character set encoding." +msgstr "Встановлює кодування символів сервера (бази даних)." + +#: utils/misc/guc.c:4034 +msgid "Shows the server version." +msgstr "Показує версію сервера." + +#: utils/misc/guc.c:4046 +msgid "Sets the current role." +msgstr "Встановлює чинну роль." + +#: utils/misc/guc.c:4058 +msgid "Sets the session user name." +msgstr "Встановлює ім'я користувача в сеансі." + +#: utils/misc/guc.c:4069 +msgid "Sets the destination for server log output." +msgstr "Встановлює, куди буде виводитися протокол серверу." + +#: utils/misc/guc.c:4070 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "Дійсними значеннями є комбінації \"stderr\", \"syslog\", \"csvlog\", і \"eventlog\" в залежності від платформи." + +#: utils/misc/guc.c:4081 +msgid "Sets the destination directory for log files." +msgstr "Встановлює каталог призначення для файлів журналу." + +#: utils/misc/guc.c:4082 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "Шлях може бути абсолютним або вказуватися відносно каталогу даних." + +#: utils/misc/guc.c:4092 +msgid "Sets the file name pattern for log files." +msgstr "Встановлює шаблон імені для файлів журналу." + +#: utils/misc/guc.c:4103 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "Встановлює ім'я програми для ідентифікації повідомлень PostgreSQL в syslog." + +#: utils/misc/guc.c:4114 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "Встановлює ім'я програми для ідентифікації повідомлень PostgreSQL в журналі подій." + +#: utils/misc/guc.c:4125 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "Встановлює часовий пояс для відображення та інтерпретації позначок часу." + +#: utils/misc/guc.c:4135 +msgid "Selects a file of time zone abbreviations." +msgstr "Вибирає файл з скороченими іменами часових поясів." + +#: utils/misc/guc.c:4145 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Встановлює відповідальну групу Unix-сокету." + +#: utils/misc/guc.c:4146 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "Відповідальний користувач сокету це завжди той користувач який запустив сервер." + +#: utils/misc/guc.c:4156 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Встановлює каталоги, де будуть створюватись Unix-сокети." + +#: utils/misc/guc.c:4171 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Встановлює ім'я хосту або IP-адресу для прив'язки." + +#: utils/misc/guc.c:4186 +msgid "Sets the server's data directory." +msgstr "Встановлює каталог даних серверу." + +#: utils/misc/guc.c:4197 +msgid "Sets the server's main configuration file." +msgstr "Встановлює основний файл конфігурації серверу." + +#: utils/misc/guc.c:4208 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Встановлює \"hba\" файл конфігурації серверу." + +#: utils/misc/guc.c:4219 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Встановлює \"ident\" файл конфігурації серверу." + +#: utils/misc/guc.c:4230 +msgid "Writes the postmaster PID to the specified file." +msgstr "Записує ідентифікатор процесу (PID) postmaster у вказаний файл." + +#: utils/misc/guc.c:4241 +msgid "Name of the SSL library." +msgstr "Назва бібліотеки SSL." + +#: utils/misc/guc.c:4256 +msgid "Location of the SSL server certificate file." +msgstr "Розташування файла сертифікату сервера для SSL." + +#: utils/misc/guc.c:4266 +msgid "Location of the SSL server private key file." +msgstr "Розташування файла з закритим ключем сервера для SSL." + +#: utils/misc/guc.c:4276 +msgid "Location of the SSL certificate authority file." +msgstr "Розташування файла центру сертифікації для SSL." + +#: utils/misc/guc.c:4286 +msgid "Location of the SSL certificate revocation list file." +msgstr "Розташування файла зі списком відкликаних сертфікатів для SSL." + +#: utils/misc/guc.c:4296 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Записує тимчасові файли статистики у вказаний каталог." + +#: utils/misc/guc.c:4307 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "Кількість потенційно синхронних режимів очікування і список їх імен." + +#: utils/misc/guc.c:4318 +msgid "Sets default text search configuration." +msgstr "Встановлює конфігурацію текстового пошуку за замовчуванням." + +#: utils/misc/guc.c:4328 +msgid "Sets the list of allowed SSL ciphers." +msgstr "Встановлює список дозволених шифрів для SSL." + +#: utils/misc/guc.c:4343 +msgid "Sets the curve to use for ECDH." +msgstr "Встановлює криву для ECDH." + +#: utils/misc/guc.c:4358 +msgid "Location of the SSL DH parameters file." +msgstr "Розташування файла з параметрами SSL DH." + +#: utils/misc/guc.c:4369 +msgid "Command to obtain passphrases for SSL." +msgstr "Команда, що дозволяє отримати парольну фразу для SSL." + +#: utils/misc/guc.c:4380 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "Встановлює ім'я програми, яке буде повідомлятись у статистиці і протоколах." + +#: utils/misc/guc.c:4391 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Встановлює ім'я кластеру, яке буде включене до заголовка процесу." + +#: utils/misc/guc.c:4402 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "Встановлює менеджерів ресурсу WAL, для яких виконано перевірки узгодженості WAL." + +#: utils/misc/guc.c:4403 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "При цьому до журналу будуть записуватись зображення повнихс сторінок для всіх блоків даних для перевірки з результатами відтворення WAL." + +#: utils/misc/guc.c:4413 +msgid "JIT provider to use." +msgstr "Використовувати провайдер JIT." + +#: utils/misc/guc.c:4424 +msgid "Log backtrace for errors in these functions." +msgstr "Відстежувати записи помилок у ціх функціях." + +#: utils/misc/guc.c:4444 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Встановлює, чи дозволене використання \"\\\" в текстових рядках." + +#: utils/misc/guc.c:4454 +msgid "Sets the output format for bytea." +msgstr "Встановлює формат виводу для типу bytea." + +#: utils/misc/guc.c:4464 +msgid "Sets the message levels that are sent to the client." +msgstr "Встановлює рівень повідомлень, переданих клієнту." + +#: utils/misc/guc.c:4465 utils/misc/guc.c:4530 utils/misc/guc.c:4541 +#: utils/misc/guc.c:4617 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "Кожен рівень включає всі наступні рівні. Чим вище рівень, тим менше повідомлень надіслано." + +#: utils/misc/guc.c:4475 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "Дає змогу планувальнику оптимізувати запити, використовуючи обмеження." + +#: utils/misc/guc.c:4476 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "Сканування таблиці буде пропущено, якщо її обмеження гарантують, що запиту не відповідають ніякі рядки." + +#: utils/misc/guc.c:4487 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Встановлює рівень ізоляції транзакції для кожної нової транзакції." + +#: utils/misc/guc.c:4497 +msgid "Sets the current transaction's isolation level." +msgstr "Встановлює чинний рівень ізоляції транзакцій." + +#: utils/misc/guc.c:4508 +msgid "Sets the display format for interval values." +msgstr "Встановлює формат відображення внутрішніх значень." + +#: utils/misc/guc.c:4519 +msgid "Sets the verbosity of logged messages." +msgstr "Встановлює детальність повідомлень, які протоколюються." + +#: utils/misc/guc.c:4529 +msgid "Sets the message levels that are logged." +msgstr "Встанолвює рівні повідомлень, які протоколюються." + +#: utils/misc/guc.c:4540 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "Вмикає протоколювання для всіх операторів, виконаних з помилкою цього або вище рівня." + +#: utils/misc/guc.c:4551 +msgid "Sets the type of statements logged." +msgstr "Встановлює тип операторів, які протоколюються." + +#: utils/misc/guc.c:4561 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "Встановлює отримувача повідомлень, які відправляються до syslog." + +#: utils/misc/guc.c:4576 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "Встановлює поведінку для тригерів і правил перезапису для сеансу." + +#: utils/misc/guc.c:4586 +msgid "Sets the current transaction's synchronization level." +msgstr "Встановлює рівень синхронізації поточної транзакції." + +#: utils/misc/guc.c:4596 +msgid "Allows archiving of WAL files using archive_command." +msgstr "Дозволяє архівацію файлів WAL, використовуючи archive_command." + +#: utils/misc/guc.c:4606 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "Встновлює дію яку потрібно виконати в разі досягнення мети відновлення." + +#: utils/misc/guc.c:4616 +msgid "Enables logging of recovery-related debugging information." +msgstr "Вмикає протоколювання налагодженної інформації, пов'язаної з відновленням." + +#: utils/misc/guc.c:4632 +msgid "Collects function-level statistics on database activity." +msgstr "Збирає статистику активності в базі даних на рівні функцій." + +#: utils/misc/guc.c:4642 +msgid "Set the level of information written to the WAL." +msgstr "Встановити рівень інформації, яка записується до WAL." + +#: utils/misc/guc.c:4652 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Вибирає використовуване впровадження динамічної спільної пам'яті." + +#: utils/misc/guc.c:4662 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "Вибирає впровадження спільної пам'яті, що використовується для основної області спільної пам'яті." + +#: utils/misc/guc.c:4672 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "Вибирає метод примусового запису оновлень в WAL на диск." + +#: utils/misc/guc.c:4682 +msgid "Sets how binary values are to be encoded in XML." +msgstr "Встановлює, як повинні кодуватись двійкові значення в XML." + +#: utils/misc/guc.c:4692 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "Встановлює, чи слід розглядати XML-дані в неявних операціях аналізу і серіалізації як документи або як фрагменти змісту." + +#: utils/misc/guc.c:4703 +msgid "Use of huge pages on Linux or Windows." +msgstr "Використовувати величезні сторінки в Linux або Windows." + +#: utils/misc/guc.c:4713 +msgid "Forces use of parallel query facilities." +msgstr "Примусово використовувати паралельне виконання запитів." + +#: utils/misc/guc.c:4714 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "Якщо можливо, виконувати запит використовуючи паралельного працівника і з обмеженнями паралельності." + +#: utils/misc/guc.c:4724 +msgid "Chooses the algorithm for encrypting passwords." +msgstr "Виберіть алгоритм для шифрування паролів." + +#: utils/misc/guc.c:4734 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Контролює вибір планувальником спеціального або загального плану." + +#: utils/misc/guc.c:4735 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "Підготовлені оператори можуть мати спеціальні або загальні плани, і планувальник спробує вибрати, який краще. Це може бути встановлено для зміни поведінки за замовчуванням." + +#: utils/misc/guc.c:4747 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "Встановлює мінімальну версію протоколу SSL/TLS для використання." + +#: utils/misc/guc.c:4759 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "Встановлює максимальну версію протоколу SSL/TLS для використання." + +#: utils/misc/guc.c:5562 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: немає доступу до каталогу \"%s\": %s\n" + +#: utils/misc/guc.c:5567 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "Запустіть initdb або pg_basebackup для ініціалізації каталогу даних PostgreSQL.\n" + +#: utils/misc/guc.c:5587 +#, c-format +msgid "%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "%s не знає де знайти файл конфігурації сервера.\n" +"Ви повинні вказати його розташування в параметрі --config-file або -D, або встановити змінну середовища PGDATA.\n" + +#: utils/misc/guc.c:5606 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: не вдалося отримати доступ до файлу конфігурації сервера \"%s\": %s\n" + +#: utils/misc/guc.c:5632 +#, c-format +msgid "%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "%s не знає де знайти дані системи бази даних.\n" +"Їх розташування може бути вказано як \"data_directory\" в \"%s\", або передано в параметрі -D, або встановлено змінну середовища PGDATA.\n" + +#: utils/misc/guc.c:5680 +#, c-format +msgid "%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "%s не знає де знайти файл конфігурації \"hba\".\n" +"Його розташування може бути вказано як \"hba_file\" в \"%s\", або передано в параметрі -D, або встановлено змінну середовища PGDATA.\n" + +#: utils/misc/guc.c:5703 +#, c-format +msgid "%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "%s не знає де знайти файл конфігурації \"ident\".\n" +"Його розташування може бути вказано як \"ident_file\" в \"%s\", або передано в параметрі -D, або встановлено змінну середовища PGDATA.\n" + +#: utils/misc/guc.c:6545 +msgid "Value exceeds integer range." +msgstr "Значення перевищує діапазон цілих чисел." + +#: utils/misc/guc.c:6781 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s поза припустимим діапазоном для параметру \"%s\" (%d .. %d)" + +#: utils/misc/guc.c:6817 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s поза припустимим діапазоном для параметру \"%s\" (%g .. %g)" + +#: utils/misc/guc.c:6973 utils/misc/guc.c:8340 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "встановити параметри під час паралельної операції не можна" + +#: utils/misc/guc.c:6980 utils/misc/guc.c:7732 utils/misc/guc.c:7785 +#: utils/misc/guc.c:7836 utils/misc/guc.c:8169 utils/misc/guc.c:8936 +#: utils/misc/guc.c:9198 utils/misc/guc.c:10864 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "нерозпізнаний параметр конфігурації \"%s\"" + +#: utils/misc/guc.c:6995 utils/misc/guc.c:8181 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "параметр \"%s\" не може бути змінений" + +#: utils/misc/guc.c:7018 utils/misc/guc.c:7212 utils/misc/guc.c:7302 +#: utils/misc/guc.c:7392 utils/misc/guc.c:7500 utils/misc/guc.c:7595 +#: guc-file.l:352 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "параметр \"%s\" не може бути змінений, без перезавантаження сервера" + +#: utils/misc/guc.c:7028 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "параметр \"%s\" не може бути змінений зараз" + +#: utils/misc/guc.c:7046 utils/misc/guc.c:7093 utils/misc/guc.c:10880 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "немає прав для встановлення параметру \"%s\"" + +#: utils/misc/guc.c:7083 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "параметр \"%s\" не можна встановити після встановлення підключення" + +#: utils/misc/guc.c:7131 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "параметр \"%s\" не можна встановити в межах функції безпеки" + +#: utils/misc/guc.c:7740 utils/misc/guc.c:7790 utils/misc/guc.c:9205 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "щоб дослідити \"%s\" потрібно бути суперкористувачем або учасником ролі pg_read_all_settings" + +#: utils/misc/guc.c:7881 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s приймає лише один аргумент" + +#: utils/misc/guc.c:8129 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "щоб виконати команду ALTER SYSTEM потрібно бути суперкористувачем" + +#: utils/misc/guc.c:8214 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "значення параметру для ALTER SYSTEM не повинне містити нового рядка" + +#: utils/misc/guc.c:8259 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "не вдалося аналізувати зміст файла \"%s\"" + +#: utils/misc/guc.c:8416 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT не реалізовано" + +#: utils/misc/guc.c:8500 +#, c-format +msgid "SET requires parameter name" +msgstr "SET потребує ім'я параметра" + +#: utils/misc/guc.c:8633 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "спроба перевизначити параметр \"%s\"" + +#: utils/misc/guc.c:10426 +#, c-format +msgid "while setting parameter \"%s\" to \"%s\"" +msgstr "під час налаштування параметру \"%s\" на \"%s\"" + +#: utils/misc/guc.c:10494 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "параметр \"%s\" не вдалося встановити" + +#: utils/misc/guc.c:10584 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "не вдалося аналізувати налаштування параметру \"%s\"" + +#: utils/misc/guc.c:10942 utils/misc/guc.c:10976 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "неприпустиме значення для параметра \"%s\": %d" + +#: utils/misc/guc.c:11010 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "неприпустиме значення для параметра \"%s\": %g" + +#: utils/misc/guc.c:11280 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "параметр \"temp_buffers\" не можна змінити після того, як тимчасові таблиці отримали доступ в сеансі." + +#: utils/misc/guc.c:11292 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour не підтримується даною збіркою" + +#: utils/misc/guc.c:11305 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL не підтримується даною збіркою" + +#: utils/misc/guc.c:11317 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "Не можна ввімкнути параметр, коли \"log_statement_stats\" дорівнює true." + +#: utils/misc/guc.c:11329 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "Не можна ввімкнути \"log_statement_stats\", коли \"log_parser_stats\", \"log_planner_stats\", або \"log_executor_stats\" дорівнюють true." + +#: utils/misc/guc.c:11559 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "значення effective_io_concurrency повинне дорівнювати 0 (нулю) на платформах, де відсутній posix_fadvise()." + +#: utils/misc/guc.c:11572 +#, c-format +msgid "maintenance_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "maintenance_io_concurrency повинне бути встановлене на 0, на платформах які не мають posix_fadvise()." + +#: utils/misc/guc.c:11688 +#, c-format +msgid "invalid character" +msgstr "неприпустимий символ" + +#: utils/misc/guc.c:11748 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline не є допустимим числом." + +#: utils/misc/guc.c:11788 +#, c-format +msgid "multiple recovery targets specified" +msgstr "вказано декілька цілей відновлення" + +#: utils/misc/guc.c:11789 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr "Максимум один із recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid може бути встановлений." + +#: utils/misc/guc.c:11797 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "Єдиним дозволеним значенням є \"immediate\"." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "внутрішня помилка: нерозпізнаний тип параметра часу виконання\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "вказаний у запиті кортеж і функція повертаючого типу несумісні" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:306 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "обчислена контрольна сума CRC не відповідає значенню, збереженому у файлі" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "ЦП: користувач: %d.%02d с, система: %d.%02d с, минуло: %d.%02d с" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "запит буде обмежений політикою безпеки на рівні рядків для таблиці \"%s\"" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "Щоб вимкнути політику для власника таблиці, використайте ALTER TABLE NO FORCE ROW LEVEL SECURITY." + +#: utils/misc/timeout.c:395 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "додати більше причин тайм-ауту не можна" + +#: utils/misc/tzparser.c:60 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "скорочення часового поясу \"%s\" занадто довге (максимум %d символів) у файлі часового поясу \"%s\", рядок %d" + +#: utils/misc/tzparser.c:72 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "зсув часового поясу %d поза діапазоном у файлі часового поясу \"%s\", рядок %d" + +#: utils/misc/tzparser.c:111 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "пропущено скорочення часового поясу в файлі часового поясу \"%s\", рядок %d" + +#: utils/misc/tzparser.c:120 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "пропущено зсув часового поясу в файлі часового поясу \"%s\", рядок %d" + +#: utils/misc/tzparser.c:132 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "неприпустиме число зсуву часового поясу в файлі часового поясу \"%s\", рядок %d" + +#: utils/misc/tzparser.c:168 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "неприпустимий синтаксис у файлі часового поясу \"%s\", рядок %d" + +#: utils/misc/tzparser.c:236 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "скорочення часового поясу \"%s\" визначено неодноразово" + +#: utils/misc/tzparser.c:238 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "Запис у файлі часового поясу \"%s\", рядок %d, конфліктує з записом у файлі \"%s\", рядок %d." + +#: utils/misc/tzparser.c:300 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "неприпустиме ім'я файла часового поясу \"%s\"" + +#: utils/misc/tzparser.c:313 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "ліміт рекурсії файла часового поясу перевищено у файлі \"%s\"" + +#: utils/misc/tzparser.c:352 utils/misc/tzparser.c:365 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "не вдалося прочитати файл часового поясу \"%s\": %m" + +#: utils/misc/tzparser.c:375 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "занадто довгий рядок у файлі часового поясу \"%s\", рядок %d" + +#: utils/misc/tzparser.c:398 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "в @INCLUDE не вказано ім'я файла у файлі часового поясу \"%s\", рядок %d" + +#: utils/mmgr/aset.c:476 utils/mmgr/generation.c:234 utils/mmgr/slab.c:236 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Помилка під час створення контексту пам'яті \"%s\"." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "не вдалося підключитись до динамічно-спільної області" + +#: utils/mmgr/mcxt.c:822 utils/mmgr/mcxt.c:858 utils/mmgr/mcxt.c:896 +#: utils/mmgr/mcxt.c:934 utils/mmgr/mcxt.c:970 utils/mmgr/mcxt.c:1001 +#: utils/mmgr/mcxt.c:1037 utils/mmgr/mcxt.c:1089 utils/mmgr/mcxt.c:1124 +#: utils/mmgr/mcxt.c:1159 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Помилка в запиті розміру %zu в контексті пам'яті \"%s\"." + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "курсор \"%s\" вже існує" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "існуючий курсор \"%s\" закривається" + +#: utils/mmgr/portalmem.c:400 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "портал \"%s\" не можна запустити" + +#: utils/mmgr/portalmem.c:478 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "видалити закріплений портал \"%s\" не можна" + +#: utils/mmgr/portalmem.c:486 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "видалити активний портал \"%s\" не можна" + +#: utils/mmgr/portalmem.c:731 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "не можна виконати PREPARE для транзакції, яка створила курсор WITH HOLD" + +#: utils/mmgr/portalmem.c:1270 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "виконати команди транзакції всередині циклу з курсором, який не є \"лише для читання\", не можна" + +#: utils/sort/logtape.c:266 utils/sort/logtape.c:289 +#, c-format +msgid "could not seek to block %ld of temporary file" +msgstr "не вдалося знайти шлях до блокування %ld тимчасового файлу" + +#: utils/sort/logtape.c:295 +#, c-format +msgid "could not read block %ld of temporary file: read only %zu of %zu bytes" +msgstr "не вдалося прочитати блок %ld тимчасового файлу: прочитано лише %zu з %zu байт." + +#: utils/sort/sharedtuplestore.c:430 utils/sort/sharedtuplestore.c:439 +#: utils/sort/sharedtuplestore.c:462 utils/sort/sharedtuplestore.c:479 +#: utils/sort/sharedtuplestore.c:496 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "не вдалося прочитати тимчасовий файл зі зпільного сховища кортежів" + +#: utils/sort/sharedtuplestore.c:485 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "неочікуваний блок у тимчасовому файлі спільного сховища кортежів" + +#: utils/sort/sharedtuplestore.c:569 +#, c-format +msgid "could not seek to block %u in shared tuplestore temporary file" +msgstr "не вдалося знайти для блокування %u у тимчасовому файлі зі спільного сховища кортежів" + +#: utils/sort/sharedtuplestore.c:576 +#, c-format +msgid "could not read from shared tuplestore temporary file: read only %zu of %zu bytes" +msgstr "не вдалося прочитати з тимчасового файлу зі спільного сховища кортежів: прочитано лише %zu з %zu байт" + +#: utils/sort/tuplesort.c:3140 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "кількість виконуючих процесів для зовнішнього сортування не може перевищувати %d" + +#: utils/sort/tuplesort.c:4221 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "не вдалося створити унікальний індекс \"%s\"" + +#: utils/sort/tuplesort.c:4223 +#, c-format +msgid "Key %s is duplicated." +msgstr "Ключ %s дублюється." + +#: utils/sort/tuplesort.c:4224 +#, c-format +msgid "Duplicate keys exist." +msgstr "Дублікати ключів існують." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file" +msgstr "не вдалося знайти у тимчасовому файлі зі сховища кортежів" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1540 +#: utils/sort/tuplestore.c:1548 +#, c-format +msgid "could not read from tuplestore temporary file: read only %zu of %zu bytes" +msgstr "не вдалося прочитати з тимчасового файлу зі сховища кортежів: прочитано лише %zu з %zu байт" + +#: utils/time/snapmgr.c:624 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "Вихідна транзакція вже не виконується." + +#: utils/time/snapmgr.c:1232 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "експортувати знімок з підтранзакції не можна" + +#: utils/time/snapmgr.c:1391 utils/time/snapmgr.c:1396 +#: utils/time/snapmgr.c:1401 utils/time/snapmgr.c:1416 +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1426 +#: utils/time/snapmgr.c:1441 utils/time/snapmgr.c:1446 +#: utils/time/snapmgr.c:1451 utils/time/snapmgr.c:1553 +#: utils/time/snapmgr.c:1569 utils/time/snapmgr.c:1594 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "неприпустимі дані знімку в файлі \"%s\"" + +#: utils/time/snapmgr.c:1488 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "SET TRANSACTION SNAPSHOT повинна викликатись перед будь-яким запитом" + +#: utils/time/snapmgr.c:1497 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "транзакція, яка імпортує знімок, повинна мати рівень ізоляції SERIALIZABLE або REPEATABLE READ" + +#: utils/time/snapmgr.c:1506 utils/time/snapmgr.c:1515 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "неприпустимий ідентифікатор знімка: \"%s\"" + +#: utils/time/snapmgr.c:1607 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "серіалізована транзакція не може імпортувати знімок з не серіалізованої транзакції" + +#: utils/time/snapmgr.c:1611 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "серіалізована транзакція в режимі \"читання-запис\" не може імпортувати знімок з транзакції в режимі \"тільки читання\"" + +#: utils/time/snapmgr.c:1626 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "імпортувати знімок з іншої бази даних не можна" + +#: gram.y:1047 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD більше не підтримується" + +#: gram.y:1048 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "Видаліть UNENCRYPTED, щоб зберегти пароль у зашифрованій формі." + +#: gram.y:1110 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "нерозпізнаний параметр ролі \"%s\"" + +#: gram.y:1357 gram.y:1372 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS не може включати елементи схеми" + +#: gram.y:1518 +#, c-format +msgid "current database cannot be changed" +msgstr "поточна база даних не може бути змінена" + +#: gram.y:1642 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "інтервал, який задає часовий пояс, повинен бути HOUR або HOUR TO MINUTE" + +#: gram.y:2177 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "номер стовпця повинен бути в діапазоні від 1 до %d" + +#: gram.y:2709 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "параметр послідовності \"%s\" тут не підтримується" + +#: gram.y:2738 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "модуль для геш-секції вказано неодноразово" + +#: gram.y:2747 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "решта для геш-секції вказана неодноразово" + +#: gram.y:2754 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "нерозпізнана специфікація границі геш-секції \"%s\"" + +#: gram.y:2762 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "потрібно вказати модуль для геш-секції" + +#: gram.y:2766 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "потрібно вказати решту для геш-секції" + +#: gram.y:2967 gram.y:3000 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "STDIN/STDOUT не допускається з PROGRAM" + +#: gram.y:2973 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "Речення WHERE не дозволяється використовувати з COPY TO" + +#: gram.y:3305 gram.y:3312 gram.y:11647 gram.y:11655 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "GLOBAL при створенні тимчасових таблиць застаріло" + +#: gram.y:3552 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "для згенерованого стовпця, потрібно вказати GENERATED ALWAYS" + +#: gram.y:4512 +#, c-format +msgid "CREATE EXTENSION ... FROM is no longer supported" +msgstr "CREATE EXTENSION ... FROM більше не підтримується" + +#: gram.y:5338 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "нерозпізнаний параметр безпеки рядка \"%s\"" + +#: gram.y:5339 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "Наразі підтримуються лише політики PERMISSIVE або RESTRICTIVE." + +#: gram.y:5452 +msgid "duplicate trigger events specified" +msgstr "вказані події тригера повторюються" + +#: gram.y:5600 +#, c-format +msgid "conflicting constraint properties" +msgstr "конфліктуючі властивості обмеження" + +#: gram.y:5696 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION ще не реалізований" + +#: gram.y:6079 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK більше не потребується" + +#: gram.y:6080 +#, c-format +msgid "Update your data type." +msgstr "Поновіть ваш тип даних." + +#: gram.y:7831 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "агрегатні функції не можуть мати вихідних аргументів" + +#: gram.y:10153 gram.y:10171 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION не підтримується для рекурсивних подань" + +#: gram.y:11779 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "Синтаксис LIMIT #,# не підтримується" + +#: gram.y:11780 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "Використайте окремі речення LIMIT і OFFSET." + +#: gram.y:12106 gram.y:12131 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "VALUES в FROM повинен мати псевдонім" + +#: gram.y:12107 gram.y:12132 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "Наприклад, FROM (VALUES ...) [AS] foo." + +#: gram.y:12112 gram.y:12137 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "підзапит в FROM повинен мати псевдонім" + +#: gram.y:12113 gram.y:12138 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "Наприклад, FROM (SELECT ...) [AS] foo." + +#: gram.y:12591 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "допускається лише одне значення DEFAULT" + +#: gram.y:12600 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "для стовпця допускається лише одне значення PATH" + +#: gram.y:12609 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "конфліктуючі або надлишкові оголошення NULL / NOT NULL для стовпця \"%s\"" + +#: gram.y:12618 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "нерозпізнаний параметр стовпця \"%s\"" + +#: gram.y:12872 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "точність для типу float повинна бути мінімум 1 біт" + +#: gram.y:12881 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "точність для типу float повинна бути меньше 54 біт" + +#: gram.y:13372 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "неправильна кількість параметрів у лівій частині виразу OVERLAPS" + +#: gram.y:13377 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "неправильна кількість параметрів у правій частині виразу OVERLAPS" + +#: gram.y:13552 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "Предикат UNIQUE ще не реалізований" + +#: gram.y:13915 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "використовувати речення ORDER BY з WITHIN GROUP неодноразово, не можна" + +#: gram.y:13920 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "використовувати DISTINCT з WITHIN GROUP не можна" + +#: gram.y:13925 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "використовувати VARIADIC з WITHIN GROUP не можна" + +#: gram.y:14391 gram.y:14414 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "початком рамки не може бути UNBOUNDED FOLLOWING" + +#: gram.y:14396 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "рамка, яка починається з наступного рядка не можна закінчуватись поточним рядком" + +#: gram.y:14419 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "кінцем рамки не може бути UNBOUNDED PRECEDING" + +#: gram.y:14425 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "рамка, яка починається з поточного рядка не може мати попередніх рядків" + +#: gram.y:14432 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "рамка, яка починається з наступного рядка не може мати попередніх рядків" + +#: gram.y:15082 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "тип modifier не може мати ім'я параметра" + +#: gram.y:15088 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "тип modifier не може мати ORDER BY" + +#: gram.y:15153 gram.y:15160 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s не можна використовувати тут як ім'я ролі" + +#: gram.y:15841 gram.y:16030 +msgid "improper use of \"*\"" +msgstr "неправильне використання \"*\"" + +#: gram.y:16094 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "сортувальна агрегатна функція з прямим аргументом VARIADIC повинна мати один агрегатний аргумент VARIADIC того ж типу даних" + +#: gram.y:16131 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "кілька речень ORDER BY не допускається" + +#: gram.y:16142 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "кілька речень OFFSET не допускається" + +#: gram.y:16151 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "кілька речень LIMIT не допускається" + +#: gram.y:16160 +#, c-format +msgid "multiple limit options not allowed" +msgstr "використання декількох параметрів обмеження не дозволяється" + +#: gram.y:16164 +#, c-format +msgid "WITH TIES cannot be specified without ORDER BY clause" +msgstr "WITH TIES не можна задати без оператора ORDER BY" + +#: gram.y:16172 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "кілька речень WITH не допускається" + +#: gram.y:16376 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "В табличних функціях аргументи OUT і INOUT не дозволяються" + +#: gram.y:16472 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "кілька речень COLLATE не допускається" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16510 gram.y:16523 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "обмеження %s не можуть бути позначені DEFERRABLE" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16536 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "обмеження %s не можуть бути позначені NOT VALID" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16549 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "обмеження %s не можуть бути позначені NO INHERIT" + +#: guc-file.l:315 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "нерозпізнаний параметр конфігурації \"%s\" у файлі \"%s\" рядок %u" + +#: guc-file.l:388 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "параметр \"%s\" видалений з файла конфігурації, значення скинуто до \"за замовчуванням\"" + +#: guc-file.l:454 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "параметр \"%s\" змінено на \"%s\"" + +#: guc-file.l:496 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "файл конфігурації \"%s\" містить помилки" + +#: guc-file.l:501 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "файл конфігурації \"%s\" містить помилки; були застосовані не залежні зміни" + +#: guc-file.l:506 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "файл конфігурації \"%s\" містить помилки; зміни не були застосовані" + +#: guc-file.l:578 +#, c-format +msgid "empty configuration file name: \"%s\"" +msgstr "пуста назва файлу конфігурації: \"%s\"" + +#: guc-file.l:595 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "не вдалося відкрити файл конфігурації \"%s\": максимальну глибину вкладення перевищено" + +#: guc-file.l:615 +#, c-format +msgid "configuration file recursion in \"%s\"" +msgstr "рекурсія файлу конфігурації в \"%s\"" + +#: guc-file.l:642 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "відсутній файл конфігурації \"%s\" пропускається" + +#: guc-file.l:896 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "синтаксична помилка у файлі \"%s\" поблизу кінця рядка %u" + +#: guc-file.l:906 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "синтаксична помилка у файлі \"%s\" рядок %u, поблизу маркера \"%s\"" + +#: guc-file.l:926 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "знайдено занадто багато синтаксичних помилок, переривання файла \"%s\"" + +#: guc-file.l:981 +#, c-format +msgid "empty configuration directory name: \"%s\"" +msgstr "пуста назва каталогу конфігурації: \"%s\"" + +#: guc-file.l:1000 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "не вдалося відкрити каталог конфігурації \"%s\": %m" + +#: jsonpath_gram.y:529 +#, c-format +msgid "unrecognized flag character \"%c\" in LIKE_REGEX predicate" +msgstr "нерозпізнаний символ позначки \"%c\" в предикаті LIKE_REGEX" + +#: jsonpath_gram.y:583 +#, c-format +msgid "XQuery \"x\" flag (expanded regular expressions) is not implemented" +msgstr "XQuery \"x\" позначка (розширені регулярні вирази) не реалізовано" + +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:286 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "%s в кінці введення jsonpath" + +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:293 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s в або біля \"%s\" введення jsonpath" + +#: repl_gram.y:349 repl_gram.y:381 +#, c-format +msgid "invalid timeline %u" +msgstr "неприпустима часова шкала %u" + +#: repl_scanner.l:131 +msgid "invalid streaming start location" +msgstr "неприпустиме розташування початку потокового передавання" + +#: repl_scanner.l:182 scan.l:717 +msgid "unterminated quoted string" +msgstr "незавершений рядок в лапках" + +#: scan.l:458 +msgid "unterminated /* comment" +msgstr "незавершений коментар /*" + +#: scan.l:478 +msgid "unterminated bit string literal" +msgstr "незавершений бітовий рядок" + +#: scan.l:492 +msgid "unterminated hexadecimal string literal" +msgstr "незавершений шістнадцятковий рядок" + +#: scan.l:542 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "небезпечне використання рядкової констани зі спеціальними кодами Unicode" + +#: scan.l:543 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "Константи рядка зі спеціальними кодами Unicode не можна використовувати, коли параметр standard_conforming_strings вимкнений." + +#: scan.l:604 +msgid "unhandled previous state in xqs" +msgstr "необроблений попередній стан у xqs" + +#: scan.l:678 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Спеціальні коди Unicode повинні бути \\uXXXX або \\UXXXXXXXX." + +#: scan.l:689 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "небезпечне використання символу \\' в рядку" + +#: scan.l:690 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "Використайте \" щоб записати лапки в рядку. Запис \\' небезпечний лише для клієнтських кодувань." + +#: scan.l:762 +msgid "unterminated dollar-quoted string" +msgstr "незавершений рядок з $" + +#: scan.l:779 scan.l:789 +msgid "zero-length delimited identifier" +msgstr "пустий ідентифікатор із роздільниками" + +#: scan.l:800 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "незавершений ідентифікатор в лапках" + +#: scan.l:963 +msgid "operator too long" +msgstr "занадто довгий оператор" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1171 +#, c-format +msgid "%s at end of input" +msgstr "%s в кінці введення" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1179 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s в або поблизу \"%s\"" + +#: scan.l:1373 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "нестандартне використання \\' в рядку" + +#: scan.l:1374 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "Щоб записати лапки у рядку використовуйте \" або синтаксис спеціальних рядків (E'...')." + +#: scan.l:1383 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "нестандартне використання \\\\ в рядку" + +#: scan.l:1384 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Для запису зворотніх скісних рисок \"\\\" використовуйте синтаксис спеціальних рядків, наприклад E'\\\\'." + +#: scan.l:1398 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "нестандартне використання спеціального символу в рядку" + +#: scan.l:1399 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Для запису спеціальних символів використовуйте синтаксис спеціальних рядків E'\\r\\n'." + diff --git a/src/backend/port/atomics.c b/src/backend/port/atomics.c index c4f83706b43b..f9f8b098a52a 100644 --- a/src/backend/port/atomics.c +++ b/src/backend/port/atomics.c @@ -3,7 +3,7 @@ * atomics.c * Non-Inline parts of the atomics implementation * - * Portions Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/port/posix_sema.c b/src/backend/port/posix_sema.c index 4598eafbe142..29a60147dce1 100644 --- a/src/backend/port/posix_sema.c +++ b/src/backend/port/posix_sema.c @@ -15,7 +15,7 @@ * forked backends, but they could not be accessed by exec'd backends. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/port/sysv_sema.c b/src/backend/port/sysv_sema.c index 891649ecd3ef..71659704d7ad 100644 --- a/src/backend/port/sysv_sema.c +++ b/src/backend/port/sysv_sema.c @@ -4,7 +4,7 @@ * Implement PGSemaphores using SysV semaphore facilities * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index 203555822d9a..0cc83ffc16af 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -9,7 +9,7 @@ * exist, though, because mmap'd shmem provides no way to find out how * many processes are attached, which we need for interlocking purposes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/port/tas/sunstudio_sparc.s b/src/backend/port/tas/sunstudio_sparc.s index 4bebf079de3f..b13ca7937cd0 100644 --- a/src/backend/port/tas/sunstudio_sparc.s +++ b/src/backend/port/tas/sunstudio_sparc.s @@ -3,7 +3,7 @@ ! sunstudio_sparc.s ! compare and swap for Sun Studio on Sparc ! -! Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +! Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group ! Portions Copyright (c) 1994, Regents of the University of California ! ! IDENTIFICATION diff --git a/src/backend/port/tas/sunstudio_x86.s b/src/backend/port/tas/sunstudio_x86.s index d95e17384965..21d6c636412d 100644 --- a/src/backend/port/tas/sunstudio_x86.s +++ b/src/backend/port/tas/sunstudio_x86.s @@ -3,7 +3,7 @@ / sunstudio_x86.s / compare and swap for Sun Studio on x86 / -/ Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +/ Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group / Portions Copyright (c) 1994, Regents of the University of California / / IDENTIFICATION diff --git a/src/backend/port/win32/crashdump.c b/src/backend/port/win32/crashdump.c index e6c68379b20e..45b6696ba17e 100644 --- a/src/backend/port/win32/crashdump.c +++ b/src/backend/port/win32/crashdump.c @@ -28,7 +28,7 @@ * be added, though at the cost of a greater chance of the crash dump failing. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/crashdump.c @@ -122,7 +122,7 @@ crashDumpHandler(struct _EXCEPTION_POINTERS *pExceptionInfo) return EXCEPTION_CONTINUE_SEARCH; } - pDump = (MINIDUMPWRITEDUMP) GetProcAddress(hDll, "MiniDumpWriteDump"); + pDump = (MINIDUMPWRITEDUMP) (pg_funcptr_t) GetProcAddress(hDll, "MiniDumpWriteDump"); if (pDump == NULL) { diff --git a/src/backend/port/win32/signal.c b/src/backend/port/win32/signal.c index 3218b38240c2..580a517f3f56 100644 --- a/src/backend/port/win32/signal.c +++ b/src/backend/port/win32/signal.c @@ -3,7 +3,7 @@ * signal.c * Microsoft Windows Win32 Signal Emulation Functions * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/signal.c diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c index 6fbd1ed6fb49..af151e847093 100644 --- a/src/backend/port/win32/socket.c +++ b/src/backend/port/win32/socket.c @@ -3,7 +3,7 @@ * socket.c * Microsoft Windows Win32 Socket Functions * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/socket.c @@ -120,13 +120,21 @@ TranslateSocketError(void) case WSAEADDRNOTAVAIL: errno = EADDRNOTAVAIL; break; - case WSAEHOSTUNREACH: case WSAEHOSTDOWN: + errno = EHOSTDOWN; + break; + case WSAEHOSTUNREACH: case WSAHOST_NOT_FOUND: + errno = EHOSTUNREACH; + break; case WSAENETDOWN: + errno = ENETDOWN; + break; case WSAENETUNREACH: + errno = ENETUNREACH; + break; case WSAENETRESET: - errno = EHOSTUNREACH; + errno = ENETRESET; break; case WSAENOTCONN: case WSAESHUTDOWN: @@ -627,7 +635,7 @@ pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, c { ZeroMemory(&resEvents, sizeof(resEvents)); if (WSAEnumNetworkEvents(sockets[i], events[i], &resEvents) != 0) - elog(ERROR, "failed to enumerate network events: error code %u", + elog(ERROR, "failed to enumerate network events: error code %d", WSAGetLastError()); /* Read activity? */ if (readfds && FD_ISSET(sockets[i], readfds)) diff --git a/src/backend/port/win32/timer.c b/src/backend/port/win32/timer.c index bb98178fe1d0..53fdae9468b7 100644 --- a/src/backend/port/win32/timer.c +++ b/src/backend/port/win32/timer.c @@ -8,7 +8,7 @@ * - Does not support interval timer (value->it_interval) * - Only supports ITIMER_REAL * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/timer.c diff --git a/src/backend/port/win32_sema.c b/src/backend/port/win32_sema.c index d15c4c1dc425..858b88adae8b 100644 --- a/src/backend/port/win32_sema.c +++ b/src/backend/port/win32_sema.c @@ -3,7 +3,7 @@ * win32_sema.c * Microsoft Windows Win32 Semaphores Emulation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32_sema.c diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index 30b07303ff7c..d7a71992d81a 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -3,7 +3,7 @@ * win32_shmem.c * Implement shared memory using win32 facilities * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32_shmem.c @@ -141,7 +141,14 @@ EnableLockPagesPrivilege(int elevel) if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { ereport(elevel, - (errmsg("could not enable Lock Pages in Memory user right: error code %lu", GetLastError()), + (errmsg("could not enable user right \"%s\": error code %lu", + + /* + * translator: This is a term from Windows and should be translated to + * match the Windows localization. + */ + _("Lock pages in memory"), + GetLastError()), errdetail("Failed system call was %s.", "OpenProcessToken"))); return FALSE; } @@ -149,7 +156,7 @@ EnableLockPagesPrivilege(int elevel) if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &luid)) { ereport(elevel, - (errmsg("could not enable Lock Pages in Memory user right: error code %lu", GetLastError()), + (errmsg("could not enable user right \"%s\": error code %lu", _("Lock pages in memory"), GetLastError()), errdetail("Failed system call was %s.", "LookupPrivilegeValue"))); CloseHandle(hToken); return FALSE; @@ -161,7 +168,7 @@ EnableLockPagesPrivilege(int elevel) if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL)) { ereport(elevel, - (errmsg("could not enable Lock Pages in Memory user right: error code %lu", GetLastError()), + (errmsg("could not enable user right \"%s\": error code %lu", _("Lock pages in memory"), GetLastError()), errdetail("Failed system call was %s.", "AdjustTokenPrivileges"))); CloseHandle(hToken); return FALSE; @@ -172,11 +179,12 @@ EnableLockPagesPrivilege(int elevel) if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) ereport(elevel, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("could not enable Lock Pages in Memory user right"), - errhint("Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL."))); + errmsg("could not enable user right \"%s\"", _("Lock pages in memory")), + errhint("Assign user right \"%s\" to the Windows user account which runs PostgreSQL.", + _("Lock pages in memory")))); else ereport(elevel, - (errmsg("could not enable Lock Pages in Memory user right: error code %lu", GetLastError()), + (errmsg("could not enable user right \"%s\": error code %lu", _("Lock pages in memory"), GetLastError()), errdetail("Failed system call was %s.", "AdjustTokenPrivileges"))); CloseHandle(hToken); return FALSE; @@ -232,12 +240,12 @@ PGSharedMemoryCreate(Size size, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("the processor does not support large pages"))); ereport(DEBUG1, - (errmsg("disabling huge pages"))); + (errmsg_internal("disabling huge pages"))); } else if (!EnableLockPagesPrivilege(huge_pages == HUGE_PAGES_ON ? FATAL : DEBUG1)) { ereport(DEBUG1, - (errmsg("disabling huge pages"))); + (errmsg_internal("disabling huge pages"))); } else { diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 03458f53d61f..a07ff1f0f2a0 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -50,7 +50,7 @@ * there is a window (caused by pgstat delay) on which a worker may choose a * table that was already vacuumed; this is a bug in the current design. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -123,6 +123,7 @@ #include "catalog/dependency.h" #include "catalog/namespace.h" #include "catalog/pg_database.h" +#include "catalog/pg_inherits.h" #include "commands/dbcommands.h" #include "commands/vacuum.h" #include "lib/ilist.h" @@ -380,6 +381,10 @@ static void FreeWorkerInfo(int code, Datum arg); static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map, TupleDesc pg_class_desc, int effective_multixact_freeze_max_age); +static void recheck_relation_needs_vacanalyze(Oid relid, AutoVacOpts *avopts, + Form_pg_class classForm, + int effective_multixact_freeze_max_age, + bool *dovacuum, bool *doanalyze, bool *wraparound); static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts, Form_pg_class classForm, PgStat_StatTabEntry *tabentry, @@ -491,7 +496,7 @@ AutoVacLauncherMain(int argc, char *argv[]) init_ps_display(NULL); ereport(DEBUG1, - (errmsg("autovacuum launcher started"))); + (errmsg_internal("autovacuum launcher started"))); if (PostAuthDelay) pg_usleep(PostAuthDelay * 1000000L); @@ -506,8 +511,8 @@ AutoVacLauncherMain(int argc, char *argv[]) pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, StatementCancelHandler); pqsignal(SIGTERM, SignalHandlerForShutdownRequest); + /* SIGQUIT handler was already set up by InitPostmasterChild */ - pqsignal(SIGQUIT, quickdie); InitializeTimeouts(); /* establishes SIGALRM handler */ pqsignal(SIGPIPE, SIG_IGN); @@ -547,6 +552,13 @@ AutoVacLauncherMain(int argc, char *argv[]) * If an exception is encountered, processing resumes here. * * This code is a stripped down version of PostgresMain error recovery. + * + * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask + * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus, + * signals other than SIGQUIT will be blocked until we complete error + * recovery. It might seem that this policy makes the HOLD_INTERRUPTS() + * call redundant, but it is not since InterruptPending might be set + * already. */ if (sigsetjmp(local_sigjmp_buf, 1) != 0) { @@ -901,7 +913,7 @@ static void AutoVacLauncherShutdown(void) { ereport(DEBUG1, - (errmsg("autovacuum launcher shutting down"))); + (errmsg_internal("autovacuum launcher shutting down"))); AutoVacuumShmem->av_launcherpid = 0; proc_exit(0); /* done */ @@ -1244,7 +1256,7 @@ do_start_worker(void) * pass without forcing a vacuum. (This limit can be tightened for * particular tables, but not loosened.) */ - recentXid = ReadNewTransactionId(); + recentXid = ReadNextTransactionId(); xidForceLimit = recentXid - autovacuum_freeze_max_age; /* ensure it's a "normal" XID, else TransactionIdPrecedes misbehaves */ /* this can cause the limit to go backwards by 3, but that's OK */ @@ -1603,7 +1615,8 @@ AutoVacWorkerMain(int argc, char *argv[]) */ pqsignal(SIGINT, StatementCancelHandler); pqsignal(SIGTERM, die); - pqsignal(SIGQUIT, quickdie); + /* SIGQUIT handler was already set up by InitPostmasterChild */ + InitializeTimeouts(); /* establishes SIGALRM handler */ pqsignal(SIGPIPE, SIG_IGN); @@ -1628,7 +1641,15 @@ AutoVacWorkerMain(int argc, char *argv[]) /* * If an exception is encountered, processing resumes here. * - * See notes in postgres.c about the design of this coding. + * Unlike most auxiliary processes, we don't attempt to continue + * processing after an error; we just clean up and exit. The autovac + * launcher is responsible for spawning another worker later. + * + * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask + * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus, + * signals other than SIGQUIT will be blocked until we exit. It might + * seem that this policy makes the HOLD_INTERRUPTS() call redundant, but + * it is not since InterruptPending might be set already. */ if (sigsetjmp(local_sigjmp_buf, 1) != 0) { @@ -1760,8 +1781,8 @@ AutoVacWorkerMain(int argc, char *argv[]) InitPostgres(NULL, dbid, NULL, InvalidOid, dbname, false); SetProcessingMode(NormalProcessing); set_ps_display(dbname); - ereport(LOG, - (errmsg("autovacuum: processing database \"%s\"", dbname))); + ereport(DEBUG1, + (errmsg_internal("autovacuum: processing database \"%s\"", dbname))); #ifdef FAULT_INJECTOR FaultInjector_InjectFaultIfSet( @@ -1773,7 +1794,7 @@ AutoVacWorkerMain(int argc, char *argv[]) pg_usleep(PostAuthDelay * 1000000L); /* And do an appropriate amount of work */ - recentXid = ReadNewTransactionId(); + recentXid = ReadNextTransactionId(); recentMulti = ReadNextMultiXactId(); do_autovacuum(); @@ -1924,7 +1945,7 @@ autovac_balance_cost(void) } if (worker->wi_proc != NULL) - elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%g)", + elog(DEBUG2, "autovac_balance_cost(pid=%d db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%g)", worker->wi_proc->pid, worker->wi_dboid, worker->wi_tableoid, worker->wi_dobalance ? "yes" : "no", worker->wi_cost_limit, worker->wi_cost_limit_base, @@ -2035,6 +2056,7 @@ do_autovacuum(void) int effective_multixact_freeze_max_age; bool did_vacuum = false; bool found_concurrent_worker = false; + bool updated = false; int i; /* @@ -2109,7 +2131,6 @@ do_autovacuum(void) pg_class_desc = CreateTupleDescCopy(RelationGetDescr(classRel)); /* create hash table for toast <-> main relid mapping */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(av_relation); @@ -2121,12 +2142,19 @@ do_autovacuum(void) /* * Scan pg_class to determine which tables to vacuum. * - * We do this in two passes: on the first one we collect the list of plain - * relations and materialized views, and on the second one we collect - * TOAST tables. The reason for doing the second pass is that during it we - * want to use the main relation's pg_class.reloptions entry if the TOAST - * table does not have any, and we cannot obtain it unless we know - * beforehand what's the main table OID. + * We do this in three passes: First we let pgstat collector know about + * the partitioned table ancestors of all partitions that have recently + * acquired rows for analyze. This informs the second pass about the + * total number of tuple count in partitioning hierarchies. + * + * On the second pass, we collect the list of plain relations, + * materialized views and partitioned tables. On the third one we collect + * TOAST tables. + * + * The reason for doing the third pass is that during it we want to use + * the main relation's pg_class.reloptions entry if the TOAST table does + * not have any, and we cannot obtain it unless we know beforehand what's + * the main table OID. * * We need to check TOAST tables separately because in cases with short, * wide tables there might be proportionally much more activity in the @@ -2135,7 +2163,44 @@ do_autovacuum(void) relScan = table_beginscan_catalog(classRel, 0, NULL); /* - * On the first pass, we collect main tables to vacuum, and also the main + * First pass: before collecting the list of tables to vacuum, let stat + * collector know about partitioned-table ancestors of each partition. + */ + while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) + { + Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); + Oid relid = classForm->oid; + PgStat_StatTabEntry *tabentry; + + /* Only consider permanent leaf partitions */ + if (!classForm->relispartition || + classForm->relkind == RELKIND_PARTITIONED_TABLE || + classForm->relpersistence == RELPERSISTENCE_TEMP) + continue; + + /* + * No need to do this for partitions that haven't acquired any rows. + */ + tabentry = pgstat_fetch_stat_tabentry(relid); + if (tabentry && + tabentry->changes_since_analyze - + tabentry->changes_since_analyze_reported > 0) + { + pgstat_report_anl_ancestors(relid); + updated = true; + } + } + + /* Acquire fresh stats for the next passes, if needed */ + if (updated) + { + autovac_refresh_stats(); + dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId); + shared = pgstat_fetch_stat_dbentry(InvalidOid); + } + + /* + * On the second pass, we collect main tables to vacuum, and also the main * table relid to TOAST relid mapping. */ while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) @@ -2152,7 +2217,8 @@ do_autovacuum(void) classForm->relkind != RELKIND_MATVIEW && classForm->relkind != RELKIND_AOSEGMENTS && classForm->relkind != RELKIND_AOBLOCKDIR && - classForm->relkind != RELKIND_AOVISIMAP) + classForm->relkind != RELKIND_AOVISIMAP && + classForm->relkind != RELKIND_PARTITIONED_TABLE) continue; relid = classForm->oid; @@ -2234,7 +2300,7 @@ do_autovacuum(void) table_endscan(relScan); - /* second pass: check TOAST tables */ + /* third pass: check TOAST tables */ ScanKeyInit(&key, Anum_pg_class_relkind, BTEqualStrategyNumber, F_CHAREQ, @@ -2589,7 +2655,7 @@ do_autovacuum(void) tab->at_datname, tab->at_nspname, tab->at_relname); EmitErrorReport(); - /* this resets ProcGlobal->vacuumFlags[i] too */ + /* this resets ProcGlobal->statusFlags[i] too */ AbortOutOfAnyTransaction(); FlushErrorState(); MemoryContextResetAndDeleteChildren(PortalContext); @@ -2611,7 +2677,7 @@ do_autovacuum(void) did_vacuum = true; - /* ProcGlobal->vacuumFlags[i] are reset at the next end of xact */ + /* ProcGlobal->statusFlags[i] are reset at the next end of xact */ /* be tidy */ deleted: @@ -2788,7 +2854,7 @@ perform_work_item(AutoVacuumWorkItem *workitem) cur_datname, cur_nspname, cur_relname); EmitErrorReport(); - /* this resets ProcGlobal->vacuumFlags[i] too */ + /* this resets ProcGlobal->statusFlags[i] too */ AbortOutOfAnyTransaction(); FlushErrorState(); MemoryContextResetAndDeleteChildren(PortalContext); @@ -2819,6 +2885,11 @@ perform_work_item(AutoVacuumWorkItem *workitem) * * Given a relation's pg_class tuple, return the AutoVacOpts portion of * reloptions, if set; otherwise, return NULL. + * + * Note: callers do not have a relation lock on the table at this point, + * so the table could have been dropped, and its catalog rows gone, after + * we acquired the pg_class row. If pg_class had a TOAST table, this would + * be a risk; fortunately, it doesn't. */ static AutoVacOpts * extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc) @@ -2831,8 +2902,8 @@ extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc) ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE || ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOSEGMENTS || ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOBLOCKDIR || - ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOVISIMAP); - + ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_AOVISIMAP || + ((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_PARTITIONED_TABLE); relopts = extractRelOptions(tup, pg_class_desc, NULL); if (relopts == NULL) @@ -2887,17 +2958,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool dovacuum; bool doanalyze; autovac_table *tab = NULL; - PgStat_StatTabEntry *tabentry; - PgStat_StatDBEntry *shared; - PgStat_StatDBEntry *dbentry; bool wraparound; AutoVacOpts *avopts; - - /* use fresh stats */ - autovac_refresh_stats(); - - shared = pgstat_fetch_stat_dbentry(InvalidOid); - dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId); + static bool reuse_stats = false; /* fetch the relation's relcache entry */ classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); @@ -2921,17 +2984,38 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, avopts = &hentry->ar_reloptions; } - /* fetch the pgstat table entry */ - tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared, - shared, dbentry); + /* + * Reuse the stats to recheck whether a relation needs to be vacuumed or + * analyzed if it was reloaded before and has not been cleared yet. This + * is necessary to avoid frequent refresh of stats, especially when there + * are very large number of relations and the refresh can cause lots of + * overhead. + * + * If we determined that a relation needs to be vacuumed or analyzed, + * based on the old stats, we refresh stats and recheck the necessity + * again. Because a relation may have already been vacuumed or analyzed by + * someone since the last reload of stats. + */ + if (reuse_stats) + { + recheck_relation_needs_vacanalyze(relid, avopts, classForm, + effective_multixact_freeze_max_age, + &dovacuum, &doanalyze, &wraparound); - relation_needs_vacanalyze(relid, avopts, classForm, tabentry, - effective_multixact_freeze_max_age, - &dovacuum, &doanalyze, &wraparound); + /* Quick exit if a relation doesn't need to be vacuumed or analyzed */ + if (!doanalyze && !dovacuum) + { + heap_freetuple(classTup); + return NULL; + } + } - /* ignore ANALYZE for toast tables */ - if (classForm->relkind == RELKIND_TOASTVALUE) - doanalyze = false; + /* Use fresh stats and recheck again */ + autovac_refresh_stats(); + + recheck_relation_needs_vacanalyze(relid, avopts, classForm, + effective_multixact_freeze_max_age, + &dovacuum, &doanalyze, &wraparound); /* OK, it needs something done */ if (doanalyze || dovacuum) @@ -2992,12 +3076,19 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, tab = palloc(sizeof(autovac_table)); tab->at_relid = relid; tab->at_sharedrel = classForm->relisshared; - tab->at_params.options = VACOPT_SKIPTOAST | - (dovacuum ? VACOPT_VACUUM : 0) | + + /* Note that this skips toast relations */ + tab->at_params.options = (dovacuum ? VACOPT_VACUUM : 0) | (doanalyze ? VACOPT_ANALYZE : 0) | (!wraparound ? VACOPT_SKIP_LOCKED : 0); - tab->at_params.index_cleanup = VACOPT_TERNARY_DEFAULT; - tab->at_params.truncate = VACOPT_TERNARY_DEFAULT; + + /* + * index_cleanup and truncate are unspecified at first in autovacuum. + * They will be filled in with usable values using their reloptions + * (or reloption defaults) later. + */ + tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED; + tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED; /* As of now, we don't support parallel vacuum for autovacuum */ tab->at_params.nworkers = -1; tab->at_params.freeze_min_age = freeze_min_age; @@ -3020,13 +3111,66 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, tab->at_dobalance = !(avopts && (avopts->vacuum_cost_limit > 0 || avopts->vacuum_cost_delay > 0)); + + /* + * When we decide to do vacuum or analyze, the existing stats cannot + * be reused in the next cycle because it's cleared at the end of + * vacuum or analyze (by AtEOXact_PgStat()). + */ + reuse_stats = false; + } + else + { + /* + * If neither vacuum nor analyze is necessary, the existing stats is + * not cleared and can be reused in the next cycle. + */ + reuse_stats = true; } heap_freetuple(classTup); - return tab; } +/* + * recheck_relation_needs_vacanalyze + * + * Subroutine for table_recheck_autovac. + * + * Fetch the pgstat of a relation and recheck whether a relation + * needs to be vacuumed or analyzed. + */ +static void +recheck_relation_needs_vacanalyze(Oid relid, + AutoVacOpts *avopts, + Form_pg_class classForm, + int effective_multixact_freeze_max_age, + bool *dovacuum, + bool *doanalyze, + bool *wraparound) +{ + PgStat_StatTabEntry *tabentry; + PgStat_StatDBEntry *shared = NULL; + PgStat_StatDBEntry *dbentry = NULL; + + if (classForm->relisshared) + shared = pgstat_fetch_stat_dbentry(InvalidOid); + else + dbentry = pgstat_fetch_stat_dbentry(MyDatabaseId); + + /* fetch the pgstat table entry */ + tabentry = get_pgstat_tabentry_relid(relid, classForm->relisshared, + shared, dbentry); + + relation_needs_vacanalyze(relid, avopts, classForm, tabentry, + effective_multixact_freeze_max_age, + dovacuum, doanalyze, wraparound); + + /* ignore ANALYZE for toast tables */ + if (classForm->relkind == RELKIND_TOASTVALUE) + *doanalyze = false; +} + /* * relation_needs_vacanalyze * @@ -3193,6 +3337,10 @@ relation_needs_vacanalyze(Oid relid, instuples = tabentry->inserts_since_vacuum; anltuples = tabentry->changes_since_analyze; + /* If the table hasn't yet been vacuumed, take reltuples as zero */ + if (reltuples < 0) + reltuples = 0; + vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples; vacinsthresh = (float4) vac_ins_base_thresh + vac_ins_scale_factor * reltuples; anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples; diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 5b4ed8858634..ba19ffd5a3fb 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -2,7 +2,7 @@ * bgworker.c * POSTGRES pluggable background workers implementation * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/postmaster/bgworker.c @@ -258,13 +258,15 @@ FindRegisteredWorkerBySlotNumber(int slotno) } /* - * Notice changes to shared memory made by other backends. This code - * runs in the postmaster, so we must be very careful not to assume that - * shared memory contents are sane. Otherwise, a rogue backend could take - * out the postmaster. + * Notice changes to shared memory made by other backends. + * Accept new worker requests only if allow_new_workers is true. + * + * This code runs in the postmaster, so we must be very careful not to assume + * that shared memory contents are sane. Otherwise, a rogue backend could + * take out the postmaster. */ void -BackgroundWorkerStateChange(void) +BackgroundWorkerStateChange(bool allow_new_workers) { int slotno; @@ -277,10 +279,10 @@ BackgroundWorkerStateChange(void) */ if (max_worker_processes != BackgroundWorkerData->total_slots) { - elog(LOG, - "inconsistent background worker state (max_worker_processes=%d, total_slots=%d", - max_worker_processes, - BackgroundWorkerData->total_slots); + ereport(LOG, + (errmsg("inconsistent background worker state (max_worker_processes=%d, total_slots=%d)", + max_worker_processes, + BackgroundWorkerData->total_slots))); return; } @@ -324,6 +326,15 @@ BackgroundWorkerStateChange(void) continue; } + /* + * If we aren't allowing new workers, then immediately mark it for + * termination; the next stanza will take care of cleaning it up. + * Doing this ensures that any process waiting for the worker will get + * awoken, even though the worker will never be allowed to run. + */ + if (!allow_new_workers) + slot->terminate = true; + /* * If the worker is marked for termination, we don't need to add it to * the registered workers list; we can just free the slot. However, if @@ -343,9 +354,11 @@ BackgroundWorkerStateChange(void) notify_pid = slot->worker.bgw_notify_pid; if ((slot->worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0) BackgroundWorkerData->parallel_terminate_count++; - pg_memory_barrier(); slot->pid = 0; + + pg_memory_barrier(); slot->in_use = false; + if (notify_pid != 0) kill(notify_pid, SIGUSR1); @@ -403,7 +416,7 @@ BackgroundWorkerStateChange(void) rw->rw_worker.bgw_notify_pid = slot->worker.bgw_notify_pid; if (!PostmasterMarkPIDForWorkerNotify(rw->rw_worker.bgw_notify_pid)) { - elog(DEBUG1, "worker notification PID %lu is not valid", + elog(DEBUG1, "worker notification PID %ld is not valid", (long) rw->rw_worker.bgw_notify_pid); rw->rw_worker.bgw_notify_pid = 0; } @@ -418,8 +431,8 @@ BackgroundWorkerStateChange(void) /* Log it! */ ereport(DEBUG1, - (errmsg("registering background worker \"%s\"", - rw->rw_worker.bgw_name))); + (errmsg_internal("registering background worker \"%s\"", + rw->rw_worker.bgw_name))); slist_push_head(&BackgroundWorkerList, &rw->rw_lnode); } @@ -432,6 +445,8 @@ BackgroundWorkerStateChange(void) * points to it. This convention allows deletion of workers during * searches of the worker list, and saves having to search the list again. * + * Caller is responsible for notifying bgw_notify_pid, if appropriate. + * * This function must be invoked only in the postmaster. */ void @@ -444,14 +459,21 @@ ForgetBackgroundWorker(slist_mutable_iter *cur) Assert(rw->rw_shmem_slot < max_worker_processes); slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot]; + Assert(slot->in_use); + + /* + * We need a memory barrier here to make sure that the update of + * parallel_terminate_count completes before the store to in_use. + */ if ((rw->rw_worker.bgw_flags & BGWORKER_CLASS_PARALLEL) != 0) BackgroundWorkerData->parallel_terminate_count++; + pg_memory_barrier(); slot->in_use = false; ereport(DEBUG1, - (errmsg("unregistering background worker \"%s\"", - rw->rw_worker.bgw_name))); + (errmsg_internal("unregistering background worker \"%s\"", + rw->rw_worker.bgw_name))); slist_delete_current(cur); free(rw); @@ -530,12 +552,55 @@ BackgroundWorkerStopNotifications(pid_t pid) } } +/* + * Cancel any not-yet-started worker requests that have waiting processes. + * + * This is called during a normal ("smart" or "fast") database shutdown. + * After this point, no new background workers will be started, so anything + * that might be waiting for them needs to be kicked off its wait. We do + * that by cancelling the bgworker registration entirely, which is perhaps + * overkill, but since we're shutting down it does not matter whether the + * registration record sticks around. + * + * This function should only be called from the postmaster. + */ +void +ForgetUnstartedBackgroundWorkers(void) +{ + slist_mutable_iter iter; + + slist_foreach_modify(iter, &BackgroundWorkerList) + { + RegisteredBgWorker *rw; + BackgroundWorkerSlot *slot; + + rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur); + Assert(rw->rw_shmem_slot < max_worker_processes); + slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot]; + + /* If it's not yet started, and there's someone waiting ... */ + if (slot->pid == InvalidPid && + rw->rw_worker.bgw_notify_pid != 0) + { + /* ... then zap it, and notify the waiter */ + int notify_pid = rw->rw_worker.bgw_notify_pid; + + ForgetBackgroundWorker(&iter); + if (notify_pid != 0) + kill(notify_pid, SIGUSR1); + } + } +} + /* * Reset background worker crash state. * * We assume that, after a crash-and-restart cycle, background workers without * the never-restart flag should be restarted immediately, instead of waiting - * for bgw_restart_time to elapse. + * for bgw_restart_time to elapse. On the other hand, workers with that flag + * should be forgotten immediately, since we won't ever restart them. + * + * This function should only be called from the postmaster. */ void ResetBackgroundWorkerCrashTimes(void) @@ -575,6 +640,11 @@ ResetBackgroundWorkerCrashTimes(void) * resetting. */ rw->rw_crashed_at = 0; + + /* + * If there was anyone waiting for it, they're history. + */ + rw->rw_worker.bgw_notify_pid = 0; } } } @@ -698,22 +768,6 @@ bgworker_die(SIGNAL_ARGS) MyBgworkerEntry->bgw_type))); } -/* - * Standard SIGUSR1 handler for unconnected workers - * - * Here, we want to make sure an unconnected worker will at least heed - * latch activity. - */ -static void -bgworker_sigusr1_handler(SIGNAL_ARGS) -{ - int save_errno = errno; - - latch_sigusr1_handler(); - - errno = save_errno; -} - /* * Start a new background worker * @@ -744,6 +798,7 @@ StartBackgroundWorker(void) */ if ((worker->bgw_flags & BGWORKER_SHMEM_ACCESS) == 0) { + ShutdownLatchSupport(); dsm_detach_all(); PGSharedMemoryDetach(); } @@ -771,13 +826,13 @@ StartBackgroundWorker(void) else { pqsignal(SIGINT, SIG_IGN); - pqsignal(SIGUSR1, bgworker_sigusr1_handler); + pqsignal(SIGUSR1, SIG_IGN); pqsignal(SIGFPE, SIG_IGN); } pqsignal(SIGTERM, bgworker_die); + /* SIGQUIT handler was already set up by InitPostmasterChild */ pqsignal(SIGHUP, SIG_IGN); - pqsignal(SIGQUIT, SignalHandlerForCrashExit); InitializeTimeouts(); /* establishes SIGALRM handler */ pqsignal(SIGPIPE, SIG_IGN); @@ -787,7 +842,7 @@ StartBackgroundWorker(void) /* * If an exception is encountered, processing resumes here. * - * See notes in postgres.c about the design of this coding. + * We just need to clean up, report the error, and go away. */ if (sigsetjmp(local_sigjmp_buf, 1) != 0) { @@ -797,7 +852,14 @@ StartBackgroundWorker(void) /* Prevent interrupts while cleaning up */ HOLD_INTERRUPTS(); - /* Report the error to the server log */ + /* + * sigsetjmp will have blocked all signals, but we may need to accept + * signals while communicating with our parallel leader. Once we've + * done HOLD_INTERRUPTS() it should be safe to unblock signals. + */ + BackgroundWorkerUnblockSignals(); + + /* Report the error to the parallel leader and the server log */ EmitErrorReport(); /* @@ -876,7 +938,7 @@ RegisterBackgroundWorker(BackgroundWorker *worker) if (!IsUnderPostmaster) ereport(DEBUG1, - (errmsg("registering background worker \"%s\"", worker->bgw_name))); + (errmsg_internal("registering background worker \"%s\"", worker->bgw_name))); auxworker = isAuxiliaryBgWorker(worker); @@ -1117,6 +1179,9 @@ GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, pid_t *pidp) * returned. However, if the postmaster has died, we give up and return * BGWH_POSTMASTER_DIED, since it that case we know that startup will not * take place. + * + * The caller *must* have set our PID as the worker's bgw_notify_pid, + * else we will not be awoken promptly when the worker's state changes. */ BgwHandleStatus WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp) @@ -1159,6 +1224,9 @@ WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp) * and then return BGWH_STOPPED. However, if the postmaster has died, we give * up and return BGWH_POSTMASTER_DIED, because it's the postmaster that * notifies us when a worker's state changes. + * + * The caller *must* have set our PID as the worker's bgw_notify_pid, + * else we will not be awoken promptly when the worker's state changes. */ BgwHandleStatus WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle) diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index 3b6f7f8b784c..abb6f75a219d 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -24,7 +24,7 @@ * should be killed by SIGQUIT and then a recovery cycle started. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -107,6 +107,14 @@ BackgroundWriterMain(void) pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, SIG_IGN); pqsignal(SIGTERM, SignalHandlerForShutdownRequest); + /* + * GPDB: PG14's InitPostmasterChild set up SignalHandlerForCrashExit as the + * SIGQUIT handler. Override it with bg_quickdie, which wraps the same crash + * exit with a fault injection point (fault_in_background_writer_quickdie) + * that tests such as fts_segment_reset use to delay the bgwriter's death + * (and thus the segment's reset). Without this the GPDB handler is dead + * code and the fault never fires. + */ pqsignal(SIGQUIT, bg_quickdie); pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); @@ -118,9 +126,6 @@ BackgroundWriterMain(void) */ pqsignal(SIGCHLD, SIG_DFL); - /* We allow SIGQUIT (quickdie) at all times */ - sigdelset(&BlockSig, SIGQUIT); - /* * We just started, assume there has been either a shutdown or * end-of-recovery snapshot. @@ -143,7 +148,20 @@ BackgroundWriterMain(void) /* * If an exception is encountered, processing resumes here. * - * See notes in postgres.c about the design of this coding. + * You might wonder why this isn't coded as an infinite loop around a + * PG_TRY construct. The reason is that this is the bottom of the + * exception stack, and so with PG_TRY there would be no exception handler + * in force at all during the CATCH part. By leaving the outermost setjmp + * always active, we have at least some chance of recovering from an error + * during error recovery. (If we get into an infinite loop thereby, it + * will soon be stopped by overflow of elog.c's internal state stack.) + * + * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask + * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus, + * signals other than SIGQUIT will be blocked until we complete error + * recovery. It might seem that this policy makes the HOLD_INTERRUPTS() + * call redundant, but it is not since InterruptPending might be set + * already. */ if (sigsetjmp(local_sigjmp_buf, 1) != 0) { diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 9ae26ca338a1..45e1aeb460ff 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -26,7 +26,7 @@ * restart needs to be forced.) * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -146,7 +146,7 @@ static CheckpointerShmemStruct *CheckpointerShmem; */ int CheckPointTimeout = 300; int CheckPointWarning = 30; -double CheckPointCompletionTarget = 0.5; +double CheckPointCompletionTarget = 0.9; /* * Private state @@ -199,7 +199,7 @@ CheckpointerMain(void) pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, ReqCheckpointHandler); /* request checkpoint */ pqsignal(SIGTERM, SIG_IGN); /* ignore SIGTERM */ - pqsignal(SIGQUIT, SignalHandlerForCrashExit); + /* SIGQUIT handler was already set up by InitPostmasterChild */ pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); @@ -210,9 +210,6 @@ CheckpointerMain(void) */ pqsignal(SIGCHLD, SIG_DFL); - /* We allow SIGQUIT (quickdie) at all times */ - sigdelset(&BlockSig, SIGQUIT); - /* * Initialize so that first time-driven event happens at the correct time. */ @@ -232,7 +229,20 @@ CheckpointerMain(void) /* * If an exception is encountered, processing resumes here. * - * See notes in postgres.c about the design of this coding. + * You might wonder why this isn't coded as an infinite loop around a + * PG_TRY construct. The reason is that this is the bottom of the + * exception stack, and so with PG_TRY there would be no exception handler + * in force at all during the CATCH part. By leaving the outermost setjmp + * always active, we have at least some chance of recovering from an error + * during error recovery. (If we get into an infinite loop thereby, it + * will soon be stopped by overflow of elog.c's internal state stack.) + * + * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask + * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus, + * signals other than SIGQUIT will be blocked until we complete error + * recovery. It might seem that this policy makes the HOLD_INTERRUPTS() + * call redundant, but it is not since InterruptPending might be set + * already. */ if (sigsetjmp(local_sigjmp_buf, 1) != 0) { @@ -495,6 +505,9 @@ CheckpointerMain(void) */ pgstat_send_bgwriter(); + /* Send WAL statistics to the stats collector. */ + pgstat_send_wal(true); + /* * If any checkpoint flags have been set, redo the loop to handle the * checkpoint without sleeping. @@ -560,8 +573,19 @@ HandleCheckpointerInterrupts(void) * back to the sigsetjmp block above */ ExitOnAnyError = true; - /* Close down the database */ + + /* + * Close down the database. + * + * Since ShutdownXLOG() creates restartpoint or checkpoint, and + * updates the statistics, increment the checkpoint request and send + * the statistics to the stats collector. + */ + BgWriterStats.m_requested_checkpoints++; ShutdownXLOG(0, 0); + pgstat_send_bgwriter(); + pgstat_send_wal(true); + /* Normal exit from the checkpointer is here */ proc_exit(0); /* done */ } @@ -1149,7 +1173,6 @@ CompactCheckpointerRequestQueue(void) skip_slot = palloc0(sizeof(bool) * CheckpointerShmem->num_requests); /* Initialize temporary hash table */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(CheckpointerRequest); ctl.entrysize = sizeof(struct CheckpointerSlotMapping); ctl.hcxt = CurrentMemoryContext; @@ -1215,8 +1238,8 @@ CompactCheckpointerRequestQueue(void) CheckpointerShmem->requests[preserve_count++] = CheckpointerShmem->requests[n]; } ereport(DEBUG1, - (errmsg("compacted fsync request queue from %d entries to %d entries", - CheckpointerShmem->num_requests, preserve_count))); + (errmsg_internal("compacted fsync request queue from %d entries to %d entries", + CheckpointerShmem->num_requests, preserve_count))); CheckpointerShmem->num_requests = preserve_count; /* Cleanup. */ diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c index 15d634080078..62d068bc1e2e 100644 --- a/src/backend/postmaster/fork_process.c +++ b/src/backend/postmaster/fork_process.c @@ -4,7 +4,7 @@ * EXEC_BACKEND case; it might be extended to do so, but it would be * considerably more complex. * - * Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/postmaster/fork_process.c @@ -16,9 +16,6 @@ #include #include #include -#ifdef USE_OPENSSL -#include -#endif #include "postmaster/fork_process.h" @@ -108,14 +105,8 @@ fork_process(void) } } - /* - * Make sure processes do not share OpenSSL randomness state. This is - * no longer required in OpenSSL 1.1.1 and later versions, but until - * we drop support for version < 1.1.1 we need to do this. - */ -#ifdef USE_OPENSSL - RAND_poll(); -#endif + /* do post-fork initialization for random number generation */ + pg_strong_random_init(); } return result; diff --git a/src/backend/postmaster/interrupt.c b/src/backend/postmaster/interrupt.c index 3d02439b79ce..dd9136a942b6 100644 --- a/src/backend/postmaster/interrupt.c +++ b/src/backend/postmaster/interrupt.c @@ -3,7 +3,7 @@ * interrupt.c * Interrupt handling routines. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -92,7 +92,7 @@ SignalHandlerForCrashExit(SIGNAL_ARGS) * Simple signal handler for triggering a long-running background process to * shut down and exit. * - * Typically, this handler would be used for SIGTERM, but some procesess use + * Typically, this handler would be used for SIGTERM, but some processes use * other signals. In particular, the checkpointer exits on SIGUSR2, the * stats collector on SIGQUIT, and the WAL writer exits on either SIGINT * or SIGTERM. diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index a5a64855db3c..15b91b7a956d 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -14,7 +14,7 @@ * * Initial author: Simon Riggs simon@2ndquadrant.com * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -38,16 +38,15 @@ #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" -#include "postmaster/fork_process.h" #include "postmaster/interrupt.h" #include "postmaster/pgarch.h" -#include "postmaster/postmaster.h" -#include "storage/dsm.h" #include "storage/fd.h" #include "storage/ipc.h" #include "storage/latch.h" -#include "storage/pg_shmem.h" #include "storage/pmsignal.h" +#include "storage/proc.h" +#include "storage/procsignal.h" +#include "storage/shmem.h" #include "utils/guc.h" #include "utils/ps_status.h" @@ -78,154 +77,100 @@ */ #define NUM_ORPHAN_CLEANUP_RETRIES 3 +/* Shared memory area for archiver process */ +typedef struct PgArchData +{ + int pgprocno; /* pgprocno of archiver process */ +} PgArchData; + /* ---------- * Local data * ---------- */ -static time_t last_pgarch_start_time; static time_t last_sigterm_time = 0; +static PgArchData *PgArch = NULL; /* * Flags set by interrupt handlers for later service in the main loop. */ -static volatile sig_atomic_t wakened = false; static volatile sig_atomic_t ready_to_stop = false; /* ---------- * Local function forward declarations * ---------- */ -#ifdef EXEC_BACKEND -static pid_t pgarch_forkexec(void); -#endif - -NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn(); -static void pgarch_exit(SIGNAL_ARGS); -static void pgarch_waken(SIGNAL_ARGS); static void pgarch_waken_stop(SIGNAL_ARGS); static void pgarch_MainLoop(void); static void pgarch_ArchiverCopyLoop(void); static bool pgarch_archiveXlog(char *xlog); static bool pgarch_readyXlog(char *xlog); static void pgarch_archiveDone(char *xlog); +static void pgarch_die(int code, Datum arg); +static void HandlePgArchInterrupts(void); - -/* ------------------------------------------------------------ - * Public functions called from postmaster follow - * ------------------------------------------------------------ - */ - -/* - * pgarch_start - * - * Called from postmaster at startup or after an existing archiver - * died. Attempt to fire up a fresh archiver process. - * - * Returns PID of child process, or 0 if fail. - * - * Note: if fail, we will be called again from the postmaster main loop. - */ -int -pgarch_start(void) +/* Report shared memory space needed by PgArchShmemInit */ +Size +PgArchShmemSize(void) { - time_t curtime; - pid_t pgArchPid; - - /* - * Do nothing if no archiver needed - */ - if (!XLogArchivingActive()) - return 0; - - /* - * Do nothing if too soon since last archiver start. This is a safety - * valve to protect against continuous respawn attempts if the archiver is - * dying immediately at launch. Note that since we will be re-called from - * the postmaster main loop, we will get another chance later. - */ - curtime = time(NULL); - if ((unsigned int) (curtime - last_pgarch_start_time) < - (unsigned int) PGARCH_RESTART_INTERVAL) - return 0; - last_pgarch_start_time = curtime; - -#ifdef EXEC_BACKEND - switch ((pgArchPid = pgarch_forkexec())) -#else - switch ((pgArchPid = fork_process())) -#endif - { - case -1: - ereport(LOG, - (errmsg("could not fork archiver: %m"))); - return 0; + Size size = 0; -#ifndef EXEC_BACKEND - case 0: - /* in postmaster child ... */ - InitPostmasterChild(); + size = add_size(size, sizeof(PgArchData)); - /* Close the postmaster's sockets */ - ClosePostmasterPorts(false); + return size; +} - /* Drop our connection to postmaster's shared memory, as well */ - dsm_detach_all(); - PGSharedMemoryDetach(); +/* Allocate and initialize archiver-related shared memory */ +void +PgArchShmemInit(void) +{ + bool found; - PgArchiverMain(0, NULL); - break; -#endif + PgArch = (PgArchData *) + ShmemInitStruct("Archiver Data", PgArchShmemSize(), &found); - default: - return (int) pgArchPid; + if (!found) + { + /* First time through, so initialize */ + MemSet(PgArch, 0, PgArchShmemSize()); + PgArch->pgprocno = INVALID_PGPROCNO; } - - /* shouldn't get here */ - return 0; } -/* ------------------------------------------------------------ - * Local functions called by archiver follow - * ------------------------------------------------------------ - */ - - -#ifdef EXEC_BACKEND - /* - * pgarch_forkexec() - + * PgArchCanRestart + * + * Return true and archiver is allowed to restart if enough time has + * passed since it was launched last to reach PGARCH_RESTART_INTERVAL. + * Otherwise return false. * - * Format up the arglist for, then fork and exec, archive process + * This is a safety valve to protect against continuous respawn attempts if the + * archiver is dying immediately at launch. Note that since we will retry to + * launch the archiver from the postmaster main loop, we will get another + * chance later. */ -static pid_t -pgarch_forkexec(void) +bool +PgArchCanRestart(void) { - char *av[10]; - int ac = 0; - - av[ac++] = "postgres"; + static time_t last_pgarch_start_time = 0; + time_t curtime = time(NULL); - av[ac++] = "--forkarch"; - - av[ac++] = NULL; /* filled in by postmaster_forkexec */ - - av[ac] = NULL; - Assert(ac < lengthof(av)); + /* + * Return false and don't restart archiver if too soon since last archiver + * start. + */ + if ((unsigned int) (curtime - last_pgarch_start_time) < + (unsigned int) PGARCH_RESTART_INTERVAL) + return false; - return postmaster_forkexec(ac, av); + last_pgarch_start_time = curtime; + return true; } -#endif /* EXEC_BACKEND */ -/* - * PgArchiverMain - * - * The argc/argv parameters are valid only in EXEC_BACKEND case. However, - * since we don't use 'em, it hardly matters... - */ -NON_EXEC_STATIC void -PgArchiverMain(int argc, char *argv[]) +/* Main entry point for archiver process */ +void +PgArchiverMain(void) { /* * Ignore all signals usually bound to some action in the postmaster, @@ -234,44 +179,54 @@ PgArchiverMain(int argc, char *argv[]) pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, SIG_IGN); pqsignal(SIGTERM, SignalHandlerForShutdownRequest); - pqsignal(SIGQUIT, pgarch_exit); + /* SIGQUIT handler was already set up by InitPostmasterChild */ pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); - pqsignal(SIGUSR1, pgarch_waken); + pqsignal(SIGUSR1, procsignal_sigusr1_handler); pqsignal(SIGUSR2, pgarch_waken_stop); + /* Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); + + /* Unblock signals (they were blocked when the postmaster forked us) */ PG_SETMASK(&UnBlockSig); - MyBackendType = B_ARCHIVER; - init_ps_display(NULL); + /* We shouldn't be launched unnecessarily. */ + Assert(XLogArchivingActive()); - pgarch_MainLoop(); + /* Arrange to clean up at archiver exit */ + on_shmem_exit(pgarch_die, 0); - exit(0); -} + /* + * Advertise our pgprocno so that backends can use our latch to wake us up + * while we're sleeping. + */ + PgArch->pgprocno = MyProc->pgprocno; -/* SIGQUIT signal handler for archiver process */ -static void -pgarch_exit(SIGNAL_ARGS) -{ - /* SIGQUIT means curl up and die ... */ - exit(1); + pgarch_MainLoop(); + + proc_exit(0); } -/* SIGUSR1 signal handler for archiver process */ -static void -pgarch_waken(SIGNAL_ARGS) +/* + * Wake up the archiver + */ +void +PgArchWakeup(void) { - int save_errno = errno; - - /* set flag that there is work to be done */ - wakened = true; - SetLatch(MyLatch); + int arch_pgprocno = PgArch->pgprocno; - errno = save_errno; + /* + * We don't acquire ProcArrayLock here. It's actually fine because + * procLatch isn't ever freed, so we just can potentially set the wrong + * process' (or no process') latch. Even in that case the archiver will + * be relaunched shortly and will start archiving. + */ + if (arch_pgprocno != INVALID_PGPROCNO) + SetLatch(&ProcGlobal->allProcs[arch_pgprocno].procLatch); } + /* SIGUSR2 signal handler for archiver process */ static void pgarch_waken_stop(SIGNAL_ARGS) @@ -296,14 +251,6 @@ pgarch_MainLoop(void) pg_time_t last_copy_time = 0; bool time_to_stop; - /* - * We run the copy loop immediately upon entry, in case there are - * unarchived files left over from a previous database run (or maybe the - * archiver died unexpectedly). After that we wait for a signal or - * timeout before doing more. - */ - wakened = true; - /* * There shouldn't be anything for the archiver to do except to wait for a * signal ... however, the archiver exists to protect our data, so she @@ -316,12 +263,8 @@ pgarch_MainLoop(void) /* When we get SIGUSR2, we do one more archive cycle, then exit */ time_to_stop = ready_to_stop; - /* Check for config update */ - if (ConfigReloadPending) - { - ConfigReloadPending = false; - ProcessConfigFile(PGC_SIGHUP); - } + /* Check for barrier events and config update */ + HandlePgArchInterrupts(); /* * If we've gotten SIGTERM, we normally just sit and do nothing until @@ -342,12 +285,8 @@ pgarch_MainLoop(void) } /* Do what we're here for */ - if (wakened || time_to_stop) - { - wakened = false; - pgarch_ArchiverCopyLoop(); - last_copy_time = time(NULL); - } + pgarch_ArchiverCopyLoop(); + last_copy_time = time(NULL); /* * Sleep until a signal is received, or until a poll is forced by @@ -368,13 +307,9 @@ pgarch_MainLoop(void) WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, timeout * 1000L, WAIT_EVENT_ARCHIVER_MAIN); - if (rc & WL_TIMEOUT) - wakened = true; if (rc & WL_POSTMASTER_DEATH) time_to_stop = true; } - else - wakened = true; } /* @@ -422,15 +357,11 @@ pgarch_ArchiverCopyLoop(void) return; /* - * Check for config update. This is so that we'll adopt a new - * setting for archive_command as soon as possible, even if there - * is a backlog of files to be archived. + * Check for barrier events and config update. This is so that + * we'll adopt a new setting for archive_command as soon as + * possible, even if there is a backlog of files to be archived. */ - if (ConfigReloadPending) - { - ConfigReloadPending = false; - ProcessConfigFile(PGC_SIGHUP); - } + HandlePgArchInterrupts(); /* can't do anything if no command ... */ if (!XLogArchiveCommandSet()) @@ -768,3 +699,35 @@ pgarch_archiveDone(char *xlog) StatusFilePath(rlogdone, xlog, ".done"); (void) durable_rename(rlogready, rlogdone, WARNING); } + + +/* + * pgarch_die + * + * Exit-time cleanup handler + */ +static void +pgarch_die(int code, Datum arg) +{ + PgArch->pgprocno = INVALID_PGPROCNO; +} + +/* + * Interrupt handler for WAL archiver process. + * + * This is called in the loops pgarch_MainLoop and pgarch_ArchiverCopyLoop. + * It checks for barrier events and config update, but not shutdown request + * because how to handle shutdown request is different between those loops. + */ +static void +HandlePgArchInterrupts(void) +{ + if (ProcSignalBarrierPending) + ProcessProcSignalBarrier(); + + if (ConfigReloadPending) + { + ConfigReloadPending = false; + ProcessConfigFile(PGC_SIGHUP); + } +} diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 580a270439b0..82d64517eaa0 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -11,7 +11,7 @@ * - Add a pgstat config column to pg_database, so this * entire thing can be enabled/disabled on a per db basis. * - * Copyright (c) 2001-2020, PostgreSQL Global Development Group + * Copyright (c) 2001-2021, PostgreSQL Global Development Group * * src/backend/postmaster/pgstat.c * ---------- @@ -39,20 +39,21 @@ #include "access/twophase_rmgr.h" #include "access/xact.h" #include "access/xlog.h" +#include "catalog/partition.h" #include "catalog/pg_database.h" #include "catalog/pg_proc.h" -#include "executor/instrument.h" #include "common/ip.h" +#include "executor/instrument.h" #include "libpq/libpq.h" #include "libpq/pqsignal.h" #include "mb/pg_wchar.h" #include "miscadmin.h" -#include "pg_trace.h" #include "pgstat.h" #include "postmaster/autovacuum.h" #include "postmaster/fork_process.h" #include "postmaster/interrupt.h" #include "postmaster/postmaster.h" +#include "replication/slot.h" #include "replication/walsender.h" #include "storage/backendid.h" #include "storage/dsm.h" @@ -61,9 +62,9 @@ #include "storage/latch.h" #include "storage/lmgr.h" #include "storage/pg_shmem.h" +#include "storage/proc.h" #include "storage/procsignal.h" -#include "storage/sinvaladt.h" -#include "utils/ascii.h" +#include "utils/builtins.h" #include "utils/guc.h" #include "utils/memutils.h" #include "utils/ps_status.h" @@ -116,28 +117,15 @@ #define PGSTAT_TAB_HASH_SIZE 512 #define PGSTAT_QUEUE_HASH_SIZE 8 #define PGSTAT_FUNCTION_HASH_SIZE 512 - - -/* ---------- - * Total number of backends including auxiliary - * - * We reserve a slot for each possible BackendId, plus one for each - * possible auxiliary process type. (This scheme assumes there is not - * more than one of any auxiliary process type at a time.) MaxBackends - * includes autovacuum workers and background workers as well. - * ---------- - */ -#define NumBackendStatSlots (MaxBackends + NUM_AUXPROCTYPES) +#define PGSTAT_REPLSLOT_HASH_SIZE 32 /* ---------- * GUC parameters * ---------- */ -bool pgstat_track_activities = false; bool pgstat_track_counts = false; int pgstat_track_functions = TRACK_FUNC_OFF; -int pgstat_track_activity_query_size = 1024; bool pgstat_collect_queuelevel = false; @@ -150,11 +138,20 @@ char *pgstat_stat_filename = NULL; char *pgstat_stat_tmpname = NULL; /* - * BgWriter global statistics counters (unused in other processes). - * Stored directly in a stats message structure so it can be sent - * without needing to copy things around. We assume this inits to zeroes. + * BgWriter and WAL global statistics counters. + * Stored directly in a stats message structure so they can be sent + * without needing to copy things around. We assume these init to zeroes. */ PgStat_MsgBgWriter BgWriterStats; +PgStat_MsgWal WalStats; + +/* + * WAL usage counters saved from pgWALUsage at the previous call to + * pgstat_send_wal(). This is used to calculate how much WAL usage + * happens between pgstat_send_wal() calls, by substracting + * the previous counters from the current ones. + */ +static WalUsage prevWalUsage; /* * List of SLRU names that we keep stats for. There is no central registry of @@ -262,6 +259,9 @@ static int pgStatXactCommit = 0; static int pgStatXactRollback = 0; PgStat_Counter pgStatBlockReadTime = 0; PgStat_Counter pgStatBlockWriteTime = 0; +PgStat_Counter pgStatActiveTime = 0; +PgStat_Counter pgStatTransactionIdleTime = 0; +SessionEndType pgStatSessionEndCause = DISCONNECT_NORMAL; /* Record that's written to 2PC state file when pgstat state is persisted */ typedef struct TwoPhasePgStatRecord @@ -305,7 +305,9 @@ static int localNumBackends = 0; */ static PgStat_ArchiverStats archiverStats; static PgStat_GlobalStats globalStats; +static PgStat_WalStats walStats; static PgStat_SLRUStats slruStats[SLRU_NUM_ELEMENTS]; +static HTAB *replSlotStatHash = NULL; /* * List of OIDs of databases we need to write out. If an entry is InvalidOid, @@ -321,13 +323,6 @@ static List *pending_write_requests = NIL; */ static instr_time total_func_time; -/* - * Total time charged to functions so far in the current backend. - * We use this to help separate "self" and "other" time charges. - * (We assume this initializes to zero.) - */ -static instr_time total_func_time; - /* ---------- * Local function forward declarations @@ -338,7 +333,6 @@ static pid_t pgstat_forkexec(void); #endif NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn(); -static void pgstat_beshutdown_hook(int code, Datum arg); static PgStat_StatDBEntry *pgstat_get_db_entry(Oid databaseid, bool create); static PgStat_StatTabEntry *pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, @@ -350,26 +344,23 @@ static void pgstat_write_db_statsfile(PgStat_StatDBEntry *dbentry, bool permanen static HTAB *pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep); static void pgstat_read_db_statsfile(Oid databaseid, HTAB *tabhash, HTAB *funchash, bool permanent); static void backend_read_statsfile(void); -static void pgstat_read_current_status(void); static bool pgstat_write_statsfile_needed(void); static bool pgstat_db_requested(Oid databaseid); +static PgStat_StatReplSlotEntry *pgstat_get_replslot_entry(NameData name, bool create_it); +static void pgstat_reset_replslot(PgStat_StatReplSlotEntry *slotstats, TimestampTz ts); + static void pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg); static void pgstat_send_funcstats(void); static void pgstat_send_slru(void); static HTAB *pgstat_collect_oids(Oid catalogid, AttrNumber anum_oid); +static void pgstat_send_connstats(bool disconnect, TimestampTz last_report); static PgStat_TableStatus *get_tabstat_entry(Oid rel_id, bool isshared); static void pgstat_setup_memcxt(void); -static const char *pgstat_get_wait_activity(WaitEventActivity w); -static const char *pgstat_get_wait_client(WaitEventClient w); -static const char *pgstat_get_wait_ipc(WaitEventIPC w); -static const char *pgstat_get_wait_timeout(WaitEventTimeout w); -static const char *pgstat_get_wait_io(WaitEventIO w); - static void pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype); static void pgstat_send(void *msg, int len); @@ -381,18 +372,23 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len); static void pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len); static void pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, int len); static void pgstat_recv_resetslrucounter(PgStat_MsgResetslrucounter *msg, int len); +static void pgstat_recv_resetreplslotcounter(PgStat_MsgResetreplslotcounter *msg, int len); static void pgstat_recv_autovac(PgStat_MsgAutovacStart *msg, int len); static void pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len); static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len); +static void pgstat_recv_anl_ancestors(PgStat_MsgAnlAncestors *msg, int len); static void pgstat_recv_archiver(PgStat_MsgArchiver *msg, int len); static void pgstat_recv_queuestat(PgStat_MsgQueuestat *msg, int len); /* GPDB */ static void pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len); +static void pgstat_recv_wal(PgStat_MsgWal *msg, int len); static void pgstat_recv_slru(PgStat_MsgSLRU *msg, int len); static void pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len); static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len); static void pgstat_recv_recoveryconflict(PgStat_MsgRecoveryConflict *msg, int len); static void pgstat_recv_deadlock(PgStat_MsgDeadlock *msg, int len); static void pgstat_recv_checksum_failure(PgStat_MsgChecksumFailure *msg, int len); +static void pgstat_recv_connstat(PgStat_MsgConn *msg, int len); +static void pgstat_recv_replslot(PgStat_MsgReplSlot *msg, int len); static void pgstat_recv_tempfile(PgStat_MsgTempFile *msg, int len); /* ------------------------------------------------------------ @@ -650,7 +646,8 @@ pgstat_init(void) if (getsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF, (char *) &old_rcvbuf, &rcvbufsize) < 0) { - elog(LOG, "getsockopt(SO_RCVBUF) failed: %m"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "getsockopt", "SO_RCVBUF"))); /* if we can't get existing size, always try to set it */ old_rcvbuf = 0; } @@ -660,7 +657,8 @@ pgstat_init(void) { if (setsockopt(pgStatSock, SOL_SOCKET, SO_RCVBUF, (char *) &new_rcvbuf, sizeof(new_rcvbuf)) < 0) - elog(LOG, "setsockopt(SO_RCVBUF) failed: %m"); + ereport(LOG, + (errmsg("%s(%s) failed: %m", "setsockopt", "SO_RCVBUF"))); } } @@ -868,10 +866,14 @@ allow_immediate_pgstat_restart(void) * per-table and function usage statistics to the collector. Note that this * is called only when not within a transaction, so it is fair to use * transaction stop time as an approximation of current time. + * + * "disconnect" is "true" only for the last call before the backend + * exits. This makes sure that no data is lost and that interrupted + * sessions are reported correctly. * ---------- */ void -pgstat_report_stat(bool force) +pgstat_report_stat(bool disconnect) { /* we assume this inits to all zeroes: */ static const PgStat_TableCounts all_zeroes; @@ -883,20 +885,35 @@ pgstat_report_stat(bool force) TabStatusArray *tsa; int i; - /* Don't expend a clock check if nothing to do */ + /* + * Don't expend a clock check if nothing to do. + * + * To determine whether any WAL activity has occurred since last time, not + * only the number of generated WAL records but also the numbers of WAL + * writes and syncs need to be checked. Because even transaction that + * generates no WAL records can write or sync WAL data when flushing the + * data pages. + */ if ((pgStatTabList == NULL || pgStatTabList->tsa_used == 0) && pgStatXactCommit == 0 && pgStatXactRollback == 0 && - !have_function_stats) + pgWalUsage.wal_records == prevWalUsage.wal_records && + WalStats.m_wal_write == 0 && WalStats.m_wal_sync == 0 && + !have_function_stats && !disconnect) return; /* * Don't send a message unless it's been at least PGSTAT_STAT_INTERVAL - * msec since we last sent one, or the caller wants to force stats out. + * msec since we last sent one, or the backend is about to exit. */ now = GetCurrentTransactionStopTimestamp(); - if (!force && + if (!disconnect && !TimestampDifferenceExceeds(last_report, now, PGSTAT_STAT_INTERVAL)) return; + + /* for backends, send connection statistics */ + if (MyBackendType == B_BACKEND) + pgstat_send_connstats(disconnect, last_report); + last_report = now; /* @@ -973,6 +990,9 @@ pgstat_report_stat(bool force) /* Now, send function statistics */ pgstat_send_funcstats(); + /* Send WAL statistics */ + pgstat_send_wal(true); + /* Finally send SLRU statistics */ pgstat_send_slru(); } @@ -1129,6 +1149,24 @@ pgstat_vacuum_stat(void) /* Clean up */ hash_destroy(htab); + /* + * Search for all the dead replication slots in stats hashtable and tell + * the stats collector to drop them. + */ + if (replSlotStatHash) + { + PgStat_StatReplSlotEntry *slotentry; + + hash_seq_init(&hstat, replSlotStatHash); + while ((slotentry = (PgStat_StatReplSlotEntry *) hash_seq_search(&hstat)) != NULL) + { + CHECK_FOR_INTERRUPTS(); + + if (SearchNamedReplicationSlot(NameStr(slotentry->slotname), true) == NULL) + pgstat_report_replslot_drop(NameStr(slotentry->slotname)); + } + } + /* * Lookup our own database entry; if not found, nothing more to do. */ @@ -1275,7 +1313,6 @@ pgstat_collect_oids(Oid catalogid, AttrNumber anum_oid) HeapTuple tup; Snapshot snapshot; - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(Oid); hash_ctl.hcxt = CurrentMemoryContext; @@ -1362,6 +1399,48 @@ pgstat_drop_relation(Oid relid) #endif /* NOT_USED */ +/* ---------- + * pgstat_send_connstats() - + * + * Tell the collector about session statistics. + * The parameter "disconnect" will be true when the backend exits. + * "last_report" is the last time we were called (0 if never). + * ---------- + */ +static void +pgstat_send_connstats(bool disconnect, TimestampTz last_report) +{ + PgStat_MsgConn msg; + long secs; + int usecs; + + if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts) + return; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_CONNECTION); + msg.m_databaseid = MyDatabaseId; + + /* session time since the last report */ + TimestampDifference(((last_report == 0) ? MyStartTimestamp : last_report), + GetCurrentTimestamp(), + &secs, &usecs); + msg.m_session_time = secs * 1000000 + usecs; + + msg.m_disconnect = disconnect ? pgStatSessionEndCause : DISCONNECT_NOT_YET; + + msg.m_active_time = pgStatActiveTime; + pgStatActiveTime = 0; + + msg.m_idle_in_xact_time = pgStatTransactionIdleTime; + pgStatTransactionIdleTime = 0; + + /* report a new session only the first time */ + msg.m_count = (last_report == 0) ? 1 : 0; + + pgstat_send(&msg, sizeof(PgStat_MsgConn)); +} + + /* ---------- * pgstat_reset_counters() - * @@ -1405,11 +1484,13 @@ pgstat_reset_shared_counters(const char *target) msg.m_resettarget = RESET_ARCHIVER; else if (strcmp(target, "bgwriter") == 0) msg.m_resettarget = RESET_BGWRITER; + else if (strcmp(target, "wal") == 0) + msg.m_resettarget = RESET_WAL; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unrecognized reset target: \"%s\"", target), - errhint("Target must be \"archiver\" or \"bgwriter\"."))); + errhint("Target must be \"archiver\", \"bgwriter\", or \"wal\"."))); pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSHAREDCOUNTER); pgstat_send(&msg, sizeof(msg)); @@ -1464,6 +1545,37 @@ pgstat_reset_slru_counter(const char *name) pgstat_send(&msg, sizeof(msg)); } +/* ---------- + * pgstat_reset_replslot_counter() - + * + * Tell the statistics collector to reset a single replication slot + * counter, or all replication slots counters (when name is null). + * + * Permission checking for this function is managed through the normal + * GRANT system. + * ---------- + */ +void +pgstat_reset_replslot_counter(const char *name) +{ + PgStat_MsgResetreplslotcounter msg; + + if (pgStatSock == PGINVALID_SOCKET) + return; + + if (name) + { + namestrcpy(&msg.m_slotname, name); + msg.clearall = false; + } + else + msg.clearall = true; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETREPLSLOTCOUNTER); + + pgstat_send(&msg, sizeof(msg)); +} + /* ---------- * pgstat_report_autovac() - * @@ -1520,6 +1632,9 @@ pgstat_report_vacuum(Oid tableoid, bool shared, * * Caller must provide new live- and dead-tuples estimates, as well as a * flag indicating whether to reset the changes_since_analyze counter. + * Exceptional support only changes_since_analyze for partitioned tables, + * though they don't have any data. This counter will tell us whether + * partitioned tables need autoanalyze or not. * -------- */ void @@ -1541,21 +1656,31 @@ pgstat_report_analyze(Relation rel, * be double-counted after commit. (This approach also ensures that the * collector ends up with the right numbers if we abort instead of * committing.) + * + * For partitioned tables, we don't report live and dead tuples, because + * such tables don't have any data. */ if (rel->pgstat_info != NULL) { PgStat_TableXactStatus *trans; - for (trans = rel->pgstat_info->trans; trans; trans = trans->upper) + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + /* If this rel is partitioned, skip modifying */ + livetuples = deadtuples = 0; + else { - livetuples -= trans->tuples_inserted - trans->tuples_deleted; - deadtuples -= trans->tuples_updated + trans->tuples_deleted; + for (trans = rel->pgstat_info->trans; trans; trans = trans->upper) + { + livetuples -= trans->tuples_inserted - trans->tuples_deleted; + deadtuples -= trans->tuples_updated + trans->tuples_deleted; + } + /* count stuff inserted by already-aborted subxacts, too */ + deadtuples -= rel->pgstat_info->t_counts.t_delta_dead_tuples; + /* Since ANALYZE's counts are estimates, we could have underflowed */ + livetuples = Max(livetuples, 0); + deadtuples = Max(deadtuples, 0); } - /* count stuff inserted by already-aborted subxacts, too */ - deadtuples -= rel->pgstat_info->t_counts.t_delta_dead_tuples; - /* Since ANALYZE's counts are estimates, we could have underflowed */ - livetuples = Max(livetuples, 0); - deadtuples = Max(deadtuples, 0); + } pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANALYZE); @@ -1567,6 +1692,48 @@ pgstat_report_analyze(Relation rel, msg.m_live_tuples = livetuples; msg.m_dead_tuples = deadtuples; pgstat_send(&msg, sizeof(msg)); + +} + +/* + * pgstat_report_anl_ancestors + * + * Send list of partitioned table ancestors of the given partition to the + * collector. The collector is in charge of propagating the analyze tuple + * counts from the partition to its ancestors. This is necessary so that + * other processes can decide whether to analyze the partitioned tables. + */ +void +pgstat_report_anl_ancestors(Oid relid) +{ + PgStat_MsgAnlAncestors msg; + List *ancestors; + ListCell *lc; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_ANL_ANCESTORS); + msg.m_databaseid = MyDatabaseId; + msg.m_tableoid = relid; + msg.m_nancestors = 0; + + ancestors = get_partition_ancestors(relid); + foreach(lc, ancestors) + { + Oid ancestor = lfirst_oid(lc); + + msg.m_ancestors[msg.m_nancestors] = ancestor; + if (++msg.m_nancestors >= PGSTAT_NUM_ANCESTORENTRIES) + { + pgstat_send(&msg, offsetof(PgStat_MsgAnlAncestors, m_ancestors[0]) + + msg.m_nancestors * sizeof(Oid)); + msg.m_nancestors = 0; + } + } + + if (msg.m_nancestors > 0) + pgstat_send(&msg, offsetof(PgStat_MsgAnlAncestors, m_ancestors[0]) + + msg.m_nancestors * sizeof(Oid)); + + list_free(ancestors); } /* -------- @@ -1664,6 +1831,70 @@ pgstat_report_tempfile(size_t filesize) pgstat_send(&msg, sizeof(msg)); } +/* ---------- + * pgstat_report_replslot() - + * + * Tell the collector about replication slot statistics. + * ---------- + */ +void +pgstat_report_replslot(const PgStat_StatReplSlotEntry *repSlotStat) +{ + PgStat_MsgReplSlot msg; + + /* + * Prepare and send the message + */ + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_REPLSLOT); + namestrcpy(&msg.m_slotname, NameStr(repSlotStat->slotname)); + msg.m_create = false; + msg.m_drop = false; + msg.m_spill_txns = repSlotStat->spill_txns; + msg.m_spill_count = repSlotStat->spill_count; + msg.m_spill_bytes = repSlotStat->spill_bytes; + msg.m_stream_txns = repSlotStat->stream_txns; + msg.m_stream_count = repSlotStat->stream_count; + msg.m_stream_bytes = repSlotStat->stream_bytes; + msg.m_total_txns = repSlotStat->total_txns; + msg.m_total_bytes = repSlotStat->total_bytes; + pgstat_send(&msg, sizeof(PgStat_MsgReplSlot)); +} + +/* ---------- + * pgstat_report_replslot_create() - + * + * Tell the collector about creating the replication slot. + * ---------- + */ +void +pgstat_report_replslot_create(const char *slotname) +{ + PgStat_MsgReplSlot msg; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_REPLSLOT); + namestrcpy(&msg.m_slotname, slotname); + msg.m_create = true; + msg.m_drop = false; + pgstat_send(&msg, sizeof(PgStat_MsgReplSlot)); +} + +/* ---------- + * pgstat_report_replslot_drop() - + * + * Tell the collector about dropping the replication slot. + * ---------- + */ +void +pgstat_report_replslot_drop(const char *slotname) +{ + PgStat_MsgReplSlot msg; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_REPLSLOT); + namestrcpy(&msg.m_slotname, slotname); + msg.m_create = false; + msg.m_drop = true; + pgstat_send(&msg, sizeof(PgStat_MsgReplSlot)); +} /* ---------- * pgstat_ping() - @@ -1725,7 +1956,6 @@ pgstat_init_function_usage(FunctionCallInfo fcinfo, /* First time through - initialize function stat table */ HASHCTL hash_ctl; - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(PgStat_BackendFunctionEntry); pgStatFunctions = hash_create("Function stat entries", @@ -1842,7 +2072,8 @@ pgstat_initstats(Relation rel) char relkind = rel->rd_rel->relkind; /* We only count stats for things that have storage */ - if (!RELKIND_HAS_STORAGE(relkind)) + if (!RELKIND_HAS_STORAGE(relkind) && + relkind != RELKIND_PARTITIONED_TABLE) { rel->pgstat_info = NULL; return; @@ -1885,7 +2116,6 @@ get_tabstat_entry(Oid rel_id, bool isshared) { HASHCTL ctl; - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(TabStatHashEntry); @@ -2617,65 +2847,6 @@ pgstat_fetch_stat_funcentry(Oid func_id) } -/* ---------- - * pgstat_fetch_stat_beentry() - - * - * Support function for the SQL-callable pgstat* functions. Returns - * our local copy of the current-activity entry for one backend. - * - * NB: caller is responsible for a check if the user is permitted to see - * this info (especially the querystring). - * ---------- - */ -PgBackendStatus * -pgstat_fetch_stat_beentry(int beid) -{ - pgstat_read_current_status(); - - if (beid < 1 || beid > localNumBackends) - return NULL; - - return &localBackendStatusTable[beid - 1].backendStatus; -} - - -/* ---------- - * pgstat_fetch_stat_local_beentry() - - * - * Like pgstat_fetch_stat_beentry() but with locally computed additions (like - * xid and xmin values of the backend) - * - * NB: caller is responsible for a check if the user is permitted to see - * this info (especially the querystring). - * ---------- - */ -LocalPgBackendStatus * -pgstat_fetch_stat_local_beentry(int beid) -{ - pgstat_read_current_status(); - - if (beid < 1 || beid > localNumBackends) - return NULL; - - return &localBackendStatusTable[beid - 1]; -} - - -/* ---------- - * pgstat_fetch_stat_numbackends() - - * - * Support function for the SQL-callable pgstat* functions. Returns - * the maximum current backend id. - * ---------- - */ -int -pgstat_fetch_stat_numbackends(void) -{ - pgstat_read_current_status(); - - return localNumBackends; -} - /* * --------- * pgstat_fetch_stat_archiver() - @@ -2709,6 +2880,21 @@ pgstat_fetch_global(void) return &globalStats; } +/* + * --------- + * pgstat_fetch_stat_wal() - + * + * Support function for the SQL-callable pgstat* functions. Returns + * a pointer to the WAL statistics struct. + * --------- + */ +PgStat_WalStats * +pgstat_fetch_stat_wal(void) +{ + backend_read_statsfile(); + + return &walStats; +} /* * --------- @@ -2726,1770 +2912,155 @@ pgstat_fetch_slru(void) return slruStats; } - -/* ------------------------------------------------------------ - * Functions for management of the shared-memory PgBackendStatus array - * ------------------------------------------------------------ +/* + * --------- + * pgstat_fetch_replslot() - + * + * Support function for the SQL-callable pgstat* functions. Returns + * a pointer to the replication slot statistics struct. + * --------- */ +PgStat_StatReplSlotEntry * +pgstat_fetch_replslot(NameData slotname) +{ + backend_read_statsfile(); -static PgBackendStatus *BackendStatusArray = NULL; -static PgBackendStatus *MyBEEntry = NULL; -static char *BackendAppnameBuffer = NULL; -static char *BackendClientHostnameBuffer = NULL; -static char *BackendActivityBuffer = NULL; -static Size BackendActivityBufferSize = 0; -#ifdef USE_SSL -static PgBackendSSLStatus *BackendSslStatusBuffer = NULL; -#endif -#ifdef ENABLE_GSS -static PgBackendGSSStatus *BackendGssStatusBuffer = NULL; -#endif - + return pgstat_get_replslot_entry(slotname, false); +} /* - * Report shared-memory space needed by CreateSharedBackendStatus. - */ -Size -BackendStatusShmemSize(void) -{ - Size size; - - /* BackendStatusArray: */ - size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots); - /* BackendAppnameBuffer: */ - size = add_size(size, - mul_size(NAMEDATALEN, NumBackendStatSlots)); - /* BackendClientHostnameBuffer: */ - size = add_size(size, - mul_size(NAMEDATALEN, NumBackendStatSlots)); - /* BackendActivityBuffer: */ - size = add_size(size, - mul_size(pgstat_track_activity_query_size, NumBackendStatSlots)); -#ifdef USE_SSL - /* BackendSslStatusBuffer: */ - size = add_size(size, - mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots)); -#endif - return size; + * Shut down a single backend's statistics reporting at process exit. + * + * Flush any remaining statistics counts out to the collector. + * Without this, operations triggered during backend exit (such as + * temp table deletions) won't be counted. + */ +static void +pgstat_shutdown_hook(int code, Datum arg) +{ + /* + * If we got as far as discovering our own database ID, we can report what + * we did to the collector. Otherwise, we'd be sending an invalid + * database ID, so forget it. (This means that accesses to pg_database + * during failed backend starts might never get counted.) + */ + if (OidIsValid(MyDatabaseId)) + pgstat_report_stat(true); } -/* - * Initialize the shared status array and several string buffers - * during postmaster startup. +/* ---------- + * pgstat_initialize() - + * + * Initialize pgstats state, and set up our on-proc-exit hook. + * Called from InitPostgres and AuxiliaryProcessMain. + * + * NOTE: MyDatabaseId isn't set yet; so the shutdown hook has to be careful. + * ---------- */ void -CreateSharedBackendStatus(void) +pgstat_initialize(void) { - Size size; - bool found; - int i; - char *buffer; - - /* Create or attach to the shared array */ - size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots); - BackendStatusArray = (PgBackendStatus *) - ShmemInitStruct("Backend Status Array", size, &found); - - if (!found) - { - /* - * We're the first - initialize. - */ - MemSet(BackendStatusArray, 0, size); - } - - /* Create or attach to the shared appname buffer */ - size = mul_size(NAMEDATALEN, NumBackendStatSlots); - BackendAppnameBuffer = (char *) - ShmemInitStruct("Backend Application Name Buffer", size, &found); + /* + * Initialize prevWalUsage with pgWalUsage so that pgstat_send_wal() can + * calculate how much pgWalUsage counters are increased by substracting + * prevWalUsage from pgWalUsage. + */ + prevWalUsage = pgWalUsage; - if (!found) - { - MemSet(BackendAppnameBuffer, 0, size); + /* Set up a process-exit hook to clean up */ + on_shmem_exit(pgstat_shutdown_hook, 0); +} - /* Initialize st_appname pointers. */ - buffer = BackendAppnameBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_appname = buffer; - buffer += NAMEDATALEN; - } - } +/* ------------------------------------------------------------ + * Local support functions follow + * ------------------------------------------------------------ + */ - /* Create or attach to the shared client hostname buffer */ - size = mul_size(NAMEDATALEN, NumBackendStatSlots); - BackendClientHostnameBuffer = (char *) - ShmemInitStruct("Backend Client Host Name Buffer", size, &found); - if (!found) - { - MemSet(BackendClientHostnameBuffer, 0, size); +/* ---------- + * pgstat_setheader() - + * + * Set common header fields in a statistics message + * ---------- + */ +static void +pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype) +{ + hdr->m_type = mtype; +} - /* Initialize st_clienthostname pointers. */ - buffer = BackendClientHostnameBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_clienthostname = buffer; - buffer += NAMEDATALEN; - } - } - - /* Create or attach to the shared activity buffer */ - BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size, - NumBackendStatSlots); - BackendActivityBuffer = (char *) - ShmemInitStruct("Backend Activity Buffer", - BackendActivityBufferSize, - &found); - - if (!found) - { - MemSet(BackendActivityBuffer, 0, BackendActivityBufferSize); - - /* Initialize st_activity pointers. */ - buffer = BackendActivityBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_activity_raw = buffer; - buffer += pgstat_track_activity_query_size; - } - } - -#ifdef USE_SSL - /* Create or attach to the shared SSL status buffer */ - size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots); - BackendSslStatusBuffer = (PgBackendSSLStatus *) - ShmemInitStruct("Backend SSL Status Buffer", size, &found); - - if (!found) - { - PgBackendSSLStatus *ptr; - - MemSet(BackendSslStatusBuffer, 0, size); - - /* Initialize st_sslstatus pointers. */ - ptr = BackendSslStatusBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_sslstatus = ptr; - ptr++; - } - } -#endif - -#ifdef ENABLE_GSS - /* Create or attach to the shared GSSAPI status buffer */ - size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots); - BackendGssStatusBuffer = (PgBackendGSSStatus *) - ShmemInitStruct("Backend GSS Status Buffer", size, &found); - - if (!found) - { - PgBackendGSSStatus *ptr; - - MemSet(BackendGssStatusBuffer, 0, size); - - /* Initialize st_gssstatus pointers. */ - ptr = BackendGssStatusBuffer; - for (i = 0; i < NumBackendStatSlots; i++) - { - BackendStatusArray[i].st_gssstatus = ptr; - ptr++; - } - } -#endif -} - - -/* ---------- - * pgstat_initialize() - - * - * Initialize pgstats state, and set up our on-proc-exit hook. - * Called from InitPostgres and AuxiliaryProcessMain. For auxiliary process, - * MyBackendId is invalid. Otherwise, MyBackendId must be set, - * but we must not have started any transaction yet (since the - * exit hook must run after the last transaction exit). - * NOTE: MyDatabaseId isn't set yet; so the shutdown hook has to be careful. - * ---------- - */ -void -pgstat_initialize(void) -{ - /* Initialize MyBEEntry */ - if (MyBackendId != InvalidBackendId) - { - Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends); - MyBEEntry = &BackendStatusArray[MyBackendId - 1]; - } - else - { - /* Must be an auxiliary process */ - Assert(MyAuxProcType != NotAnAuxProcess); - - /* - * Assign the MyBEEntry for an auxiliary process. Since it doesn't - * have a BackendId, the slot is statically allocated based on the - * auxiliary process type (MyAuxProcType). Backends use slots indexed - * in the range from 1 to MaxBackends (inclusive), so we use - * MaxBackends + AuxBackendType + 1 as the index of the slot for an - * auxiliary process. - */ - MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType]; - } - - /* Set up a process-exit hook to clean up */ - on_shmem_exit(pgstat_beshutdown_hook, 0); -} /* ---------- - * pgstat_bestart() - - * - * Initialize this backend's entry in the PgBackendStatus array. - * Called from InitPostgres. + * pgstat_send() - * - * Apart from auxiliary processes, MyBackendId, MyDatabaseId, - * session userid, and application_name must be set for a - * backend (hence, this cannot be combined with pgstat_initialize). - * Note also that we must be inside a transaction if this isn't an aux - * process, as we may need to do encoding conversion on some strings. + * Send out one statistics message to the collector * ---------- */ -void -pgstat_bestart(void) -{ - volatile PgBackendStatus *vbeentry = MyBEEntry; - PgBackendStatus lbeentry; -#ifdef USE_SSL - PgBackendSSLStatus lsslstatus; -#endif -#ifdef ENABLE_GSS - PgBackendGSSStatus lgssstatus; -#endif - - /* pgstats state must be initialized from pgstat_initialize() */ - Assert(vbeentry != NULL); - - /* - * To minimize the time spent modifying the PgBackendStatus entry, and - * avoid risk of errors inside the critical section, we first copy the - * shared-memory struct to a local variable, then modify the data in the - * local variable, then copy the local variable back to shared memory. - * Only the last step has to be inside the critical section. - * - * Most of the data we copy from shared memory is just going to be - * overwritten, but the struct's not so large that it's worth the - * maintenance hassle to copy only the needful fields. - */ - memcpy(&lbeentry, - unvolatize(PgBackendStatus *, vbeentry), - sizeof(PgBackendStatus)); - - /* These structs can just start from zeroes each time, though */ -#ifdef USE_SSL - memset(&lsslstatus, 0, sizeof(lsslstatus)); -#endif -#ifdef ENABLE_GSS - memset(&lgssstatus, 0, sizeof(lgssstatus)); -#endif - - /* - * Now fill in all the fields of lbeentry, except for strings that are - * out-of-line data. Those have to be handled separately, below. - */ - lbeentry.st_procpid = MyProcPid; - lbeentry.st_backendType = MyBackendType; - lbeentry.st_proc_start_timestamp = MyStartTimestamp; - lbeentry.st_activity_start_timestamp = 0; - lbeentry.st_state_start_timestamp = 0; - lbeentry.st_xact_start_timestamp = 0; - lbeentry.st_databaseid = MyDatabaseId; - - /* We have userid for client-backends, wal-sender and bgworker processes */ - if (lbeentry.st_backendType == B_BACKEND - || lbeentry.st_backendType == B_WAL_SENDER - || lbeentry.st_backendType == B_BG_WORKER) - lbeentry.st_userid = GetSessionUserId(); - else - lbeentry.st_userid = InvalidOid; - - lbeentry.st_session_id = gp_session_id; /* GPDB only */ - - /* - * We may not have a MyProcPort (eg, if this is the autovacuum process). - * If so, use all-zeroes client address, which is dealt with specially in - * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port. - */ - if (MyProcPort) - memcpy(&lbeentry.st_clientaddr, &MyProcPort->raddr, - sizeof(lbeentry.st_clientaddr)); - else - MemSet(&lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr)); - -#ifdef USE_SSL - if (MyProcPort && MyProcPort->ssl_in_use) - { - lbeentry.st_ssl = true; - lsslstatus.ssl_bits = be_tls_get_cipher_bits(MyProcPort); - lsslstatus.ssl_compression = be_tls_get_compression(MyProcPort); - strlcpy(lsslstatus.ssl_version, be_tls_get_version(MyProcPort), NAMEDATALEN); - strlcpy(lsslstatus.ssl_cipher, be_tls_get_cipher(MyProcPort), NAMEDATALEN); - be_tls_get_peer_subject_name(MyProcPort, lsslstatus.ssl_client_dn, NAMEDATALEN); - be_tls_get_peer_serial(MyProcPort, lsslstatus.ssl_client_serial, NAMEDATALEN); - be_tls_get_peer_issuer_name(MyProcPort, lsslstatus.ssl_issuer_dn, NAMEDATALEN); - } - else - { - lbeentry.st_ssl = false; - } -#else - lbeentry.st_ssl = false; -#endif - -#ifdef ENABLE_GSS - if (MyProcPort && MyProcPort->gss != NULL) - { - lbeentry.st_gss = true; - lgssstatus.gss_auth = be_gssapi_get_auth(MyProcPort); - lgssstatus.gss_enc = be_gssapi_get_enc(MyProcPort); - - if (lgssstatus.gss_auth) - strlcpy(lgssstatus.gss_princ, be_gssapi_get_princ(MyProcPort), NAMEDATALEN); - } - else - { - lbeentry.st_gss = false; - } -#else - lbeentry.st_gss = false; -#endif - - lbeentry.st_state = STATE_UNDEFINED; - lbeentry.st_progress_command = PROGRESS_COMMAND_INVALID; - lbeentry.st_progress_command_target = InvalidOid; - lbeentry.st_rsgid = InvalidOid; - - /* - * we don't zero st_progress_param here to save cycles; nobody should - * examine it until st_progress_command has been set to something other - * than PROGRESS_COMMAND_INVALID - */ - - /* - * We're ready to enter the critical section that fills the shared-memory - * status entry. We follow the protocol of bumping st_changecount before - * and after; and make sure it's even afterwards. We use a volatile - * pointer here to ensure the compiler doesn't try to get cute. - */ - PGSTAT_BEGIN_WRITE_ACTIVITY(vbeentry); - - /* make sure we'll memcpy the same st_changecount back */ - lbeentry.st_changecount = vbeentry->st_changecount; - - memcpy(unvolatize(PgBackendStatus *, vbeentry), - &lbeentry, - sizeof(PgBackendStatus)); - - /* - * We can write the out-of-line strings and structs using the pointers - * that are in lbeentry; this saves some de-volatilizing messiness. - */ - lbeentry.st_appname[0] = '\0'; - if (MyProcPort && MyProcPort->remote_hostname) - strlcpy(lbeentry.st_clienthostname, MyProcPort->remote_hostname, - NAMEDATALEN); - else - lbeentry.st_clienthostname[0] = '\0'; - lbeentry.st_activity_raw[0] = '\0'; - /* Also make sure the last byte in each string area is always 0 */ - lbeentry.st_appname[NAMEDATALEN - 1] = '\0'; - lbeentry.st_clienthostname[NAMEDATALEN - 1] = '\0'; - lbeentry.st_activity_raw[pgstat_track_activity_query_size - 1] = '\0'; - -#ifdef USE_SSL - memcpy(lbeentry.st_sslstatus, &lsslstatus, sizeof(PgBackendSSLStatus)); -#endif -#ifdef ENABLE_GSS - memcpy(lbeentry.st_gssstatus, &lgssstatus, sizeof(PgBackendGSSStatus)); -#endif - - PGSTAT_END_WRITE_ACTIVITY(vbeentry); - - /* - * GPDB: Initialize per-portal statistics hash for resource queues. - */ - pgstat_init_localportalhash(); - - /* Update app name to current GUC setting */ - if (application_name) - pgstat_report_appname(application_name); -} - -/* - * Shut down a single backend's statistics reporting at process exit. - * - * Flush any remaining statistics counts out to the collector. - * Without this, operations triggered during backend exit (such as - * temp table deletions) won't be counted. - * - * Lastly, clear out our entry in the PgBackendStatus array. - */ static void -pgstat_beshutdown_hook(int code, Datum arg) -{ - volatile PgBackendStatus *beentry = MyBEEntry; - - /* - * If we got as far as discovering our own database ID, we can report what - * we did to the collector. Otherwise, we'd be sending an invalid - * database ID, so forget it. (This means that accesses to pg_database - * during failed backend starts might never get counted.) - */ - if (OidIsValid(MyDatabaseId)) - pgstat_report_stat(true); - - /* - * Clear my status entry, following the protocol of bumping st_changecount - * before and after. We use a volatile pointer here to ensure the - * compiler doesn't try to get cute. - */ - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - - beentry->st_procpid = 0; /* mark invalid */ - beentry->st_session_id = 0; - - PGSTAT_END_WRITE_ACTIVITY(beentry); -} - - -/* ---------- - * pgstat_report_activity() - - * - * Called from tcop/postgres.c to report what the backend is actually doing - * (but note cmd_str can be NULL for certain cases). - * - * All updates of the status entry follow the protocol of bumping - * st_changecount before and after. We use a volatile pointer here to - * ensure the compiler doesn't try to get cute. - * ---------- - */ -void -pgstat_report_activity(BackendState state, const char *cmd_str) -{ - volatile PgBackendStatus *beentry = MyBEEntry; - TimestampTz start_timestamp; - TimestampTz current_timestamp; - int len = 0; - - TRACE_POSTGRESQL_STATEMENT_STATUS(cmd_str); - - if (!beentry) - return; - - if (!pgstat_track_activities) - { - if (beentry->st_state != STATE_DISABLED) - { - volatile PGPROC *proc = MyProc; - - /* - * track_activities is disabled, but we last reported a - * non-disabled state. As our final update, change the state and - * clear fields we will not be updating anymore. - */ - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - beentry->st_state = STATE_DISABLED; - beentry->st_state_start_timestamp = 0; - beentry->st_activity_raw[0] = '\0'; - beentry->st_activity_start_timestamp = 0; - /* st_xact_start_timestamp and wait_event_info are also disabled */ - beentry->st_xact_start_timestamp = 0; - proc->wait_event_info = 0; - PGSTAT_END_WRITE_ACTIVITY(beentry); - } - return; - } - - /* - * To minimize the time spent modifying the entry, and avoid risk of - * errors inside the critical section, fetch all the needed data first. - */ - start_timestamp = GetCurrentStatementStartTimestamp(); - if (cmd_str != NULL) - { - /* - * Compute length of to-be-stored string unaware of multi-byte - * characters. For speed reasons that'll get corrected on read, rather - * than computed every write. - */ - len = Min(strlen(cmd_str), pgstat_track_activity_query_size - 1); - } - current_timestamp = GetCurrentTimestamp(); - - /* - * Now update the status entry - */ - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - - beentry->st_state = state; - beentry->st_state_start_timestamp = current_timestamp; - - if (cmd_str != NULL) - { - memcpy((char *) beentry->st_activity_raw, cmd_str, len); - beentry->st_activity_raw[len] = '\0'; - beentry->st_activity_start_timestamp = start_timestamp; - } - - PGSTAT_END_WRITE_ACTIVITY(beentry); -} - -/*----------- - * pgstat_progress_start_command() - - * - * Set st_progress_command (and st_progress_command_target) in own backend - * entry. Also, zero-initialize st_progress_param array. - *----------- - */ -void -pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid) -{ - volatile PgBackendStatus *beentry = MyBEEntry; - - if (!beentry || !pgstat_track_activities) - return; - - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - beentry->st_progress_command = cmdtype; - beentry->st_progress_command_target = relid; - MemSet(&beentry->st_progress_param, 0, sizeof(beentry->st_progress_param)); - PGSTAT_END_WRITE_ACTIVITY(beentry); -} - -/*----------- - * pgstat_progress_update_param() - - * - * Update index'th member in st_progress_param[] of own backend entry. - *----------- - */ -void -pgstat_progress_update_param(int index, int64 val) -{ - volatile PgBackendStatus *beentry = MyBEEntry; - - Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM); - - if (!beentry || !pgstat_track_activities) - return; - - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - beentry->st_progress_param[index] = val; - PGSTAT_END_WRITE_ACTIVITY(beentry); -} - -/*----------- - * pgstat_progress_update_multi_param() - - * - * Update multiple members in st_progress_param[] of own backend entry. - * This is atomic; readers won't see intermediate states. - *----------- - */ -void -pgstat_progress_update_multi_param(int nparam, const int *index, - const int64 *val) +pgstat_send(void *msg, int len) { - volatile PgBackendStatus *beentry = MyBEEntry; - int i; + int rc; - if (!beentry || !pgstat_track_activities || nparam == 0) + if (pgStatSock == PGINVALID_SOCKET) return; - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + ((PgStat_MsgHdr *) msg)->m_size = len; - for (i = 0; i < nparam; ++i) + /* We'll retry after EINTR, but ignore all other failures */ + do { - Assert(index[i] >= 0 && index[i] < PGSTAT_NUM_PROGRESS_PARAM); - - beentry->st_progress_param[index[i]] = val[i]; - } - - PGSTAT_END_WRITE_ACTIVITY(beentry); -} - -/*----------- - * pgstat_progress_end_command() - - * - * Reset st_progress_command (and st_progress_command_target) in own backend - * entry. This signals the end of the command. - *----------- - */ -void -pgstat_progress_end_command(void) -{ - volatile PgBackendStatus *beentry = MyBEEntry; - - if (!beentry || !pgstat_track_activities) - return; - - if (beentry->st_progress_command == PROGRESS_COMMAND_INVALID) - return; + rc = send(pgStatSock, msg, len, 0); + } while (rc < 0 && errno == EINTR); - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - beentry->st_progress_command = PROGRESS_COMMAND_INVALID; - beentry->st_progress_command_target = InvalidOid; - PGSTAT_END_WRITE_ACTIVITY(beentry); +#ifdef USE_ASSERT_CHECKING + /* In debug builds, log send failures ... */ + if (rc < 0) + elog(LOG, "could not send to statistics collector: %m"); +#endif } -/* ---------- - * pgstat_report_appname() - - * - * Called to update our application name. - * ---------- +/* + * Report the timestamp of transaction start queueing on the resource group. */ void -pgstat_report_appname(const char *appname) +pgstat_report_resgroup(Oid groupid) { volatile PgBackendStatus *beentry = MyBEEntry; - int len; if (!beentry) return; - /* This should be unnecessary if GUC did its job, but be safe */ - len = pg_mbcliplen(appname, strlen(appname), NAMEDATALEN - 1); - /* * Update my status entry, following the protocol of bumping * st_changecount before and after. We use a volatile pointer here to * ensure the compiler doesn't try to get cute. */ - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - - memcpy((char *) beentry->st_appname, appname, len); - beentry->st_appname[len] = '\0'; + beentry->st_changecount++; - PGSTAT_END_WRITE_ACTIVITY(beentry); + beentry->st_rsgid = groupid; + beentry->st_changecount++; + Assert((beentry->st_changecount & 1) == 0); } -/* - * Report current transaction start timestamp as the specified value. - * Zero means there is no active transaction. +/* ---------- + * pgstat_report_sessionid() - + * + * Called from cdbgang to report a session is reset. + * + * ---------- */ void -pgstat_report_xact_timestamp(TimestampTz tstamp) +pgstat_report_sessionid(int new_sessionid) { volatile PgBackendStatus *beentry = MyBEEntry; - if (!pgstat_track_activities || !beentry) - return; - - /* - * Update my status entry, following the protocol of bumping - * st_changecount before and after. We use a volatile pointer here to - * ensure the compiler doesn't try to get cute. - */ - PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - - beentry->st_xact_start_timestamp = tstamp; - - PGSTAT_END_WRITE_ACTIVITY(beentry); -} - -/* - * Report the timestamp of transaction start queueing on the resource group. - */ -void -pgstat_report_resgroup(Oid groupid) -{ - volatile PgBackendStatus *beentry = MyBEEntry; - - if (!beentry) - return; - - /* - * Update my status entry, following the protocol of bumping - * st_changecount before and after. We use a volatile pointer here to - * ensure the compiler doesn't try to get cute. - */ - beentry->st_changecount++; - - beentry->st_rsgid = groupid; - beentry->st_changecount++; - Assert((beentry->st_changecount & 1) == 0); -} - -/* ---------- - * pgstat_report_sessionid() - - * - * Called from cdbgang to report a session is reset. - * - * ---------- - */ -void -pgstat_report_sessionid(int new_sessionid) -{ - volatile PgBackendStatus *beentry = MyBEEntry; - - if (!beentry) - return; - - beentry->st_changecount++; - beentry->st_session_id = new_sessionid; - beentry->st_changecount++; - Assert((beentry->st_changecount & 1) == 0); -} - -/* ---------- - * pgstat_read_current_status() - - * - * Copy the current contents of the PgBackendStatus array to local memory, - * if not already done in this transaction. - * ---------- - */ -static void -pgstat_read_current_status(void) -{ - volatile PgBackendStatus *beentry; - LocalPgBackendStatus *localtable; - LocalPgBackendStatus *localentry; - char *localappname, - *localclienthostname, - *localactivity; -#ifdef USE_SSL - PgBackendSSLStatus *localsslstatus; -#endif -#ifdef ENABLE_GSS - PgBackendGSSStatus *localgssstatus; -#endif - int i; - - Assert(!pgStatRunningInCollector); - if (localBackendStatusTable) - return; /* already done */ - - pgstat_setup_memcxt(); - - /* - * Allocate storage for local copy of state data. We can presume that - * none of these requests overflow size_t, because we already calculated - * the same values using mul_size during shmem setup. However, with - * probably-silly values of pgstat_track_activity_query_size and - * max_connections, the localactivity buffer could exceed 1GB, so use - * "huge" allocation for that one. - */ - localtable = (LocalPgBackendStatus *) - MemoryContextAlloc(pgStatLocalContext, - sizeof(LocalPgBackendStatus) * NumBackendStatSlots); - localappname = (char *) - MemoryContextAlloc(pgStatLocalContext, - NAMEDATALEN * NumBackendStatSlots); - localclienthostname = (char *) - MemoryContextAlloc(pgStatLocalContext, - NAMEDATALEN * NumBackendStatSlots); - localactivity = (char *) - MemoryContextAllocHuge(pgStatLocalContext, - pgstat_track_activity_query_size * NumBackendStatSlots); -#ifdef USE_SSL - localsslstatus = (PgBackendSSLStatus *) - MemoryContextAlloc(pgStatLocalContext, - sizeof(PgBackendSSLStatus) * NumBackendStatSlots); -#endif -#ifdef ENABLE_GSS - localgssstatus = (PgBackendGSSStatus *) - MemoryContextAlloc(pgStatLocalContext, - sizeof(PgBackendGSSStatus) * NumBackendStatSlots); -#endif - - localNumBackends = 0; - - beentry = BackendStatusArray; - localentry = localtable; - for (i = 1; i <= NumBackendStatSlots; i++) - { - /* - * Follow the protocol of retrying if st_changecount changes while we - * copy the entry, or if it's odd. (The check for odd is needed to - * cover the case where we are able to completely copy the entry while - * the source backend is between increment steps.) We use a volatile - * pointer here to ensure the compiler doesn't try to get cute. - */ - for (;;) - { - int before_changecount; - int after_changecount; - - pgstat_begin_read_activity(beentry, before_changecount); - - localentry->backendStatus.st_procpid = beentry->st_procpid; - /* Skip all the data-copying work if entry is not in use */ - if (localentry->backendStatus.st_procpid > 0) - { - memcpy(&localentry->backendStatus, unvolatize(PgBackendStatus *, beentry), sizeof(PgBackendStatus)); - - /* - * For each PgBackendStatus field that is a pointer, copy the - * pointed-to data, then adjust the local copy of the pointer - * field to point at the local copy of the data. - * - * strcpy is safe even if the string is modified concurrently, - * because there's always a \0 at the end of the buffer. - */ - strcpy(localappname, (char *) beentry->st_appname); - localentry->backendStatus.st_appname = localappname; - strcpy(localclienthostname, (char *) beentry->st_clienthostname); - localentry->backendStatus.st_clienthostname = localclienthostname; - strcpy(localactivity, (char *) beentry->st_activity_raw); - localentry->backendStatus.st_activity_raw = localactivity; -#ifdef USE_SSL - if (beentry->st_ssl) - { - memcpy(localsslstatus, beentry->st_sslstatus, sizeof(PgBackendSSLStatus)); - localentry->backendStatus.st_sslstatus = localsslstatus; - } -#endif -#ifdef ENABLE_GSS - if (beentry->st_gss) - { - memcpy(localgssstatus, beentry->st_gssstatus, sizeof(PgBackendGSSStatus)); - localentry->backendStatus.st_gssstatus = localgssstatus; - } -#endif - } - - pgstat_end_read_activity(beentry, after_changecount); - - if (pgstat_read_activity_complete(before_changecount, - after_changecount)) - break; - - /* Make sure we can break out of loop if stuck... */ - CHECK_FOR_INTERRUPTS(); - } - - beentry++; - /* Only valid entries get included into the local array */ - if (localentry->backendStatus.st_procpid > 0) - { - BackendIdGetTransactionIds(i, - &localentry->backend_xid, - &localentry->backend_xmin); - - localentry++; - localappname += NAMEDATALEN; - localclienthostname += NAMEDATALEN; - localactivity += pgstat_track_activity_query_size; -#ifdef USE_SSL - localsslstatus++; -#endif -#ifdef ENABLE_GSS - localgssstatus++; -#endif - localNumBackends++; - } - } - - /* Set the pointer only after completion of a valid table */ - localBackendStatusTable = localtable; -} - -/* ---------- - * pgstat_get_wait_event_type() - - * - * Return a string representing the current wait event type, backend is - * waiting on. - */ -const char * -pgstat_get_wait_event_type(uint32 wait_event_info) -{ - uint32 classId; - const char *event_type; - - /* report process as not waiting. */ - if (wait_event_info == 0) - return NULL; - - classId = wait_event_info & 0xFF000000; - - switch (classId) - { - case PG_WAIT_LWLOCK: - event_type = "LWLock"; - break; - case PG_WAIT_LOCK: - event_type = "Lock"; - break; - case PG_WAIT_BUFFER_PIN: - event_type = "BufferPin"; - break; - case PG_WAIT_ACTIVITY: - event_type = "Activity"; - break; - case PG_WAIT_CLIENT: - event_type = "Client"; - break; - case PG_WAIT_EXTENSION: - event_type = "Extension"; - break; - case PG_WAIT_IPC: - event_type = "IPC"; - break; - case PG_WAIT_TIMEOUT: - event_type = "Timeout"; - break; - case PG_WAIT_IO: - event_type = "IO"; - break; - case PG_WAIT_RESOURCE_GROUP: - event_type = "ResourceGroup"; - break; - case PG_WAIT_RESOURCE_QUEUE: - event_type = "ResourceQueue"; - break; - case PG_WAIT_REPLICATION: - event_type = "Replication"; - break; - default: - event_type = "???"; - break; - } - - return event_type; -} - -/* ---------- - * pgstat_get_wait_event() - - * - * Return a string representing the current wait event, backend is - * waiting on. - */ -const char * -pgstat_get_wait_event(uint32 wait_event_info) -{ - uint32 classId; - uint16 eventId; - const char *event_name; - - /* report process as not waiting. */ - if (wait_event_info == 0) - return NULL; - - classId = wait_event_info & 0xFF000000; - eventId = wait_event_info & 0x0000FFFF; - - switch (classId) - { - case PG_WAIT_LWLOCK: - event_name = GetLWLockIdentifier(classId, eventId); - break; - case PG_WAIT_LOCK: - event_name = GetLockNameFromTagType(eventId); - break; - case PG_WAIT_BUFFER_PIN: - event_name = "BufferPin"; - break; - case PG_WAIT_ACTIVITY: - { - WaitEventActivity w = (WaitEventActivity) wait_event_info; - - event_name = pgstat_get_wait_activity(w); - break; - } - case PG_WAIT_CLIENT: - { - WaitEventClient w = (WaitEventClient) wait_event_info; - - event_name = pgstat_get_wait_client(w); - break; - } - case PG_WAIT_EXTENSION: - event_name = "Extension"; - break; - case PG_WAIT_IPC: - { - WaitEventIPC w = (WaitEventIPC) wait_event_info; - - event_name = pgstat_get_wait_ipc(w); - break; - } - case PG_WAIT_TIMEOUT: - { - WaitEventTimeout w = (WaitEventTimeout) wait_event_info; - - event_name = pgstat_get_wait_timeout(w); - break; - } - case PG_WAIT_IO: - { - WaitEventIO w = (WaitEventIO) wait_event_info; - - event_name = pgstat_get_wait_io(w); - break; - } - case PG_WAIT_RESOURCE_GROUP: - /* - * We don't pass details for resource groups via event id, since - * it's an uint16 and resource group id is an Oid. - * - * Here should be never used, pg_stat_get_activity() will get the - * information from backend entry. - */ - event_name = "ResourceGroup"; - break; - case PG_WAIT_RESOURCE_QUEUE: - event_name = "ResourceQueue"; - break; - case PG_WAIT_REPLICATION: - event_name = "Replication"; - break; - default: - event_name = "unknown wait event"; - break; - } - - return event_name; -} - -/* ---------- - * pgstat_get_wait_activity() - - * - * Convert WaitEventActivity to string. - * ---------- - */ -static const char * -pgstat_get_wait_activity(WaitEventActivity w) -{ - const char *event_name = "unknown wait event"; - - switch (w) - { - case WAIT_EVENT_ARCHIVER_MAIN: - event_name = "ArchiverMain"; - break; - case WAIT_EVENT_AUTOVACUUM_MAIN: - event_name = "AutoVacuumMain"; - break; - case WAIT_EVENT_BGWRITER_HIBERNATE: - event_name = "BgWriterHibernate"; - break; - case WAIT_EVENT_BGWRITER_MAIN: - event_name = "BgWriterMain"; - break; - case WAIT_EVENT_CHECKPOINTER_MAIN: - event_name = "CheckpointerMain"; - break; - case WAIT_EVENT_LOGICAL_APPLY_MAIN: - event_name = "LogicalApplyMain"; - break; - case WAIT_EVENT_LOGICAL_LAUNCHER_MAIN: - event_name = "LogicalLauncherMain"; - break; - case WAIT_EVENT_PGSTAT_MAIN: - event_name = "PgStatMain"; - break; - case WAIT_EVENT_RECOVERY_WAL_STREAM: - event_name = "RecoveryWalStream"; - break; - case WAIT_EVENT_SYSLOGGER_MAIN: - event_name = "SysLoggerMain"; - break; - case WAIT_EVENT_WAL_RECEIVER_MAIN: - event_name = "WalReceiverMain"; - break; - case WAIT_EVENT_WAL_SENDER_MAIN: - event_name = "WalSenderMain"; - break; - case WAIT_EVENT_WAL_WRITER_MAIN: - event_name = "WalWriterMain"; - break; - - case WAIT_EVENT_BACKOFF_MAIN: - event_name = "BackoffSweeperMain"; - break; - case WAIT_EVENT_FTS_PROBE_MAIN: - event_name = "FtsProbeMain"; - break; - case WAIT_EVENT_GLOBAL_DEADLOCK_DETECTOR_MAIN: - event_name = "GlobalDeadLockDetectorMain"; - break; - /* no default case, so that compiler will warn */ - } - - return event_name; -} - -/* ---------- - * pgstat_get_wait_client() - - * - * Convert WaitEventClient to string. - * ---------- - */ -static const char * -pgstat_get_wait_client(WaitEventClient w) -{ - const char *event_name = "unknown wait event"; - - switch (w) - { - case WAIT_EVENT_CLIENT_READ: - event_name = "ClientRead"; - break; - case WAIT_EVENT_CLIENT_WRITE: - event_name = "ClientWrite"; - break; - case WAIT_EVENT_GSS_OPEN_SERVER: - event_name = "GSSOpenServer"; - break; - case WAIT_EVENT_LIBPQWALRECEIVER_CONNECT: - event_name = "LibPQWalReceiverConnect"; - break; - case WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE: - event_name = "LibPQWalReceiverReceive"; - break; - case WAIT_EVENT_SSL_OPEN_SERVER: - event_name = "SSLOpenServer"; - break; - case WAIT_EVENT_WAL_RECEIVER_WAIT_START: - event_name = "WalReceiverWaitStart"; - break; - case WAIT_EVENT_WAL_SENDER_WAIT_WAL: - event_name = "WalSenderWaitForWAL"; - break; - case WAIT_EVENT_WAL_SENDER_WRITE_DATA: - event_name = "WalSenderWriteData"; - break; - /* no default case, so that compiler will warn */ - } - - return event_name; -} - -/* ---------- - * pgstat_get_wait_ipc() - - * - * Convert WaitEventIPC to string. - * ---------- - */ -static const char * -pgstat_get_wait_ipc(WaitEventIPC w) -{ - const char *event_name = "unknown wait event"; - - switch (w) - { - case WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE: - event_name = "BackupWaitWalArchive"; - break; - case WAIT_EVENT_BGWORKER_SHUTDOWN: - event_name = "BgWorkerShutdown"; - break; - case WAIT_EVENT_BGWORKER_STARTUP: - event_name = "BgWorkerStartup"; - break; - case WAIT_EVENT_BTREE_PAGE: - event_name = "BtreePage"; - break; - case WAIT_EVENT_CHECKPOINT_DONE: - event_name = "CheckpointDone"; - break; - case WAIT_EVENT_CHECKPOINT_START: - event_name = "CheckpointStart"; - break; - case WAIT_EVENT_EXECUTE_GATHER: - event_name = "ExecuteGather"; - break; - case WAIT_EVENT_HASH_BATCH_ALLOCATE: - event_name = "HashBatchAllocate"; - break; - case WAIT_EVENT_HASH_BATCH_ELECT: - event_name = "HashBatchElect"; - break; - case WAIT_EVENT_HASH_BATCH_LOAD: - event_name = "HashBatchLoad"; - break; - case WAIT_EVENT_HASH_BUILD_ALLOCATE: - event_name = "HashBuildAllocate"; - break; - case WAIT_EVENT_HASH_BUILD_ELECT: - event_name = "HashBuildElect"; - break; - case WAIT_EVENT_HASH_BUILD_HASH_INNER: - event_name = "HashBuildHashInner"; - break; - case WAIT_EVENT_HASH_BUILD_HASH_OUTER: - event_name = "HashBuildHashOuter"; - break; - case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE: - event_name = "HashGrowBatchesAllocate"; - break; - case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE: - event_name = "HashGrowBatchesDecide"; - break; - case WAIT_EVENT_HASH_GROW_BATCHES_ELECT: - event_name = "HashGrowBatchesElect"; - break; - case WAIT_EVENT_HASH_GROW_BATCHES_FINISH: - event_name = "HashGrowBatchesFinish"; - break; - case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION: - event_name = "HashGrowBatchesRepartition"; - break; - case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE: - event_name = "HashGrowBucketsAllocate"; - break; - case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT: - event_name = "HashGrowBucketsElect"; - break; - case WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT: - event_name = "HashGrowBucketsReinsert"; - break; - case WAIT_EVENT_LOGICAL_SYNC_DATA: - event_name = "LogicalSyncData"; - break; - case WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE: - event_name = "LogicalSyncStateChange"; - break; - case WAIT_EVENT_MQ_INTERNAL: - event_name = "MessageQueueInternal"; - break; - case WAIT_EVENT_MQ_PUT_MESSAGE: - event_name = "MessageQueuePutMessage"; - break; - case WAIT_EVENT_MQ_RECEIVE: - event_name = "MessageQueueReceive"; - break; - case WAIT_EVENT_MQ_SEND: - event_name = "MessageQueueSend"; - break; - case WAIT_EVENT_PARALLEL_BITMAP_SCAN: - event_name = "ParallelBitmapScan"; - break; - case WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN: - event_name = "ParallelCreateIndexScan"; - break; - case WAIT_EVENT_PARALLEL_FINISH: - event_name = "ParallelFinish"; - break; - case WAIT_EVENT_PROCARRAY_GROUP_UPDATE: - event_name = "ProcArrayGroupUpdate"; - break; - case WAIT_EVENT_PROC_SIGNAL_BARRIER: - event_name = "ProcSignalBarrier"; - break; - case WAIT_EVENT_PROMOTE: - event_name = "Promote"; - break; - case WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT: - event_name = "RecoveryConflictSnapshot"; - break; - case WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE: - event_name = "RecoveryConflictTablespace"; - break; - case WAIT_EVENT_RECOVERY_PAUSE: - event_name = "RecoveryPause"; - break; - case WAIT_EVENT_REPLICATION_ORIGIN_DROP: - event_name = "ReplicationOriginDrop"; - break; - case WAIT_EVENT_REPLICATION_SLOT_DROP: - event_name = "ReplicationSlotDrop"; - break; - case WAIT_EVENT_SAFE_SNAPSHOT: - event_name = "SafeSnapshot"; - break; - case WAIT_EVENT_SYNC_REP: - event_name = "SyncRep"; - break; - case WAIT_EVENT_XACT_GROUP_UPDATE: - event_name = "XactGroupUpdate"; - break; - - case WAIT_EVENT_INTERCONNECT: - event_name = "Interconnect"; - break; - case WAIT_EVENT_SHAREINPUT_SCAN: - event_name = "ShareInputScan"; - break; - case WAIT_EVENT_GANG_ASSIGN: - event_name = "Dispatch/Gang-Assign"; - break; - case WAIT_EVENT_DISP_FINISH: - event_name = "Dispatch/Finish"; - break; - case WAIT_EVENT_DISP_RESULT: - event_name = "Dispatch/Result"; - break; - case WAIT_EVENT_DTX_RECOVERY: - event_name = "DtxRecovery"; - break; - /* no default case, so that compiler will warn */ - } - - return event_name; -} - -/* ---------- - * pgstat_get_wait_timeout() - - * - * Convert WaitEventTimeout to string. - * ---------- - */ -static const char * -pgstat_get_wait_timeout(WaitEventTimeout w) -{ - const char *event_name = "unknown wait event"; - - switch (w) - { - case WAIT_EVENT_BASE_BACKUP_THROTTLE: - event_name = "BaseBackupThrottle"; - break; - case WAIT_EVENT_PG_SLEEP: - event_name = "PgSleep"; - break; - case WAIT_EVENT_RECOVERY_APPLY_DELAY: - event_name = "RecoveryApplyDelay"; - break; - case WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL: - event_name = "RecoveryRetrieveRetryInterval"; - break; - case WAIT_EVENT_VACUUM_DELAY: - event_name = "VacuumDelay"; - break; - /* no default case, so that compiler will warn */ - } - - return event_name; -} - -/* ---------- - * pgstat_get_wait_io() - - * - * Convert WaitEventIO to string. - * ---------- - */ -static const char * -pgstat_get_wait_io(WaitEventIO w) -{ - const char *event_name = "unknown wait event"; - - switch (w) - { - case WAIT_EVENT_BASEBACKUP_READ: - event_name = "BaseBackupRead"; - break; - case WAIT_EVENT_BUFFILE_READ: - event_name = "BufFileRead"; - break; - case WAIT_EVENT_BUFFILE_WRITE: - event_name = "BufFileWrite"; - break; - case WAIT_EVENT_CONTROL_FILE_READ: - event_name = "ControlFileRead"; - break; - case WAIT_EVENT_CONTROL_FILE_SYNC: - event_name = "ControlFileSync"; - break; - case WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE: - event_name = "ControlFileSyncUpdate"; - break; - case WAIT_EVENT_CONTROL_FILE_WRITE: - event_name = "ControlFileWrite"; - break; - case WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE: - event_name = "ControlFileWriteUpdate"; - break; - case WAIT_EVENT_COPY_FILE_READ: - event_name = "CopyFileRead"; - break; - case WAIT_EVENT_COPY_FILE_WRITE: - event_name = "CopyFileWrite"; - break; - case WAIT_EVENT_DATA_FILE_EXTEND: - event_name = "DataFileExtend"; - break; - case WAIT_EVENT_DATA_FILE_FLUSH: - event_name = "DataFileFlush"; - break; - case WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC: - event_name = "DataFileImmediateSync"; - break; - case WAIT_EVENT_DATA_FILE_PREFETCH: - event_name = "DataFilePrefetch"; - break; - case WAIT_EVENT_DATA_FILE_READ: - event_name = "DataFileRead"; - break; - case WAIT_EVENT_DATA_FILE_SYNC: - event_name = "DataFileSync"; - break; - case WAIT_EVENT_DATA_FILE_TRUNCATE: - event_name = "DataFileTruncate"; - break; - case WAIT_EVENT_DATA_FILE_WRITE: - event_name = "DataFileWrite"; - break; - case WAIT_EVENT_DSM_FILL_ZERO_WRITE: - event_name = "DSMFillZeroWrite"; - break; - case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ: - event_name = "LockFileAddToDataDirRead"; - break; - case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC: - event_name = "LockFileAddToDataDirSync"; - break; - case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE: - event_name = "LockFileAddToDataDirWrite"; - break; - case WAIT_EVENT_LOCK_FILE_CREATE_READ: - event_name = "LockFileCreateRead"; - break; - case WAIT_EVENT_LOCK_FILE_CREATE_SYNC: - event_name = "LockFileCreateSync"; - break; - case WAIT_EVENT_LOCK_FILE_CREATE_WRITE: - event_name = "LockFileCreateWrite"; - break; - case WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ: - event_name = "LockFileReCheckDataDirRead"; - break; - case WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC: - event_name = "LogicalRewriteCheckpointSync"; - break; - case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC: - event_name = "LogicalRewriteMappingSync"; - break; - case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE: - event_name = "LogicalRewriteMappingWrite"; - break; - case WAIT_EVENT_LOGICAL_REWRITE_SYNC: - event_name = "LogicalRewriteSync"; - break; - case WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE: - event_name = "LogicalRewriteTruncate"; - break; - case WAIT_EVENT_LOGICAL_REWRITE_WRITE: - event_name = "LogicalRewriteWrite"; - break; - case WAIT_EVENT_RELATION_MAP_READ: - event_name = "RelationMapRead"; - break; - case WAIT_EVENT_RELATION_MAP_SYNC: - event_name = "RelationMapSync"; - break; - case WAIT_EVENT_RELATION_MAP_WRITE: - event_name = "RelationMapWrite"; - break; - case WAIT_EVENT_REORDER_BUFFER_READ: - event_name = "ReorderBufferRead"; - break; - case WAIT_EVENT_REORDER_BUFFER_WRITE: - event_name = "ReorderBufferWrite"; - break; - case WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ: - event_name = "ReorderLogicalMappingRead"; - break; - case WAIT_EVENT_REPLICATION_SLOT_READ: - event_name = "ReplicationSlotRead"; - break; - case WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC: - event_name = "ReplicationSlotRestoreSync"; - break; - case WAIT_EVENT_REPLICATION_SLOT_SYNC: - event_name = "ReplicationSlotSync"; - break; - case WAIT_EVENT_REPLICATION_SLOT_WRITE: - event_name = "ReplicationSlotWrite"; - break; - case WAIT_EVENT_SLRU_FLUSH_SYNC: - event_name = "SLRUFlushSync"; - break; - case WAIT_EVENT_SLRU_READ: - event_name = "SLRURead"; - break; - case WAIT_EVENT_SLRU_SYNC: - event_name = "SLRUSync"; - break; - case WAIT_EVENT_SLRU_WRITE: - event_name = "SLRUWrite"; - break; - case WAIT_EVENT_SNAPBUILD_READ: - event_name = "SnapbuildRead"; - break; - case WAIT_EVENT_SNAPBUILD_SYNC: - event_name = "SnapbuildSync"; - break; - case WAIT_EVENT_SNAPBUILD_WRITE: - event_name = "SnapbuildWrite"; - break; - case WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC: - event_name = "TimelineHistoryFileSync"; - break; - case WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE: - event_name = "TimelineHistoryFileWrite"; - break; - case WAIT_EVENT_TIMELINE_HISTORY_READ: - event_name = "TimelineHistoryRead"; - break; - case WAIT_EVENT_TIMELINE_HISTORY_SYNC: - event_name = "TimelineHistorySync"; - break; - case WAIT_EVENT_TIMELINE_HISTORY_WRITE: - event_name = "TimelineHistoryWrite"; - break; - case WAIT_EVENT_TWOPHASE_FILE_READ: - event_name = "TwophaseFileRead"; - break; - case WAIT_EVENT_TWOPHASE_FILE_SYNC: - event_name = "TwophaseFileSync"; - break; - case WAIT_EVENT_TWOPHASE_FILE_WRITE: - event_name = "TwophaseFileWrite"; - break; - case WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ: - event_name = "WALSenderTimelineHistoryRead"; - break; - case WAIT_EVENT_WAL_BOOTSTRAP_SYNC: - event_name = "WALBootstrapSync"; - break; - case WAIT_EVENT_WAL_BOOTSTRAP_WRITE: - event_name = "WALBootstrapWrite"; - break; - case WAIT_EVENT_WAL_COPY_READ: - event_name = "WALCopyRead"; - break; - case WAIT_EVENT_WAL_COPY_SYNC: - event_name = "WALCopySync"; - break; - case WAIT_EVENT_WAL_COPY_WRITE: - event_name = "WALCopyWrite"; - break; - case WAIT_EVENT_WAL_INIT_SYNC: - event_name = "WALInitSync"; - break; - case WAIT_EVENT_WAL_INIT_WRITE: - event_name = "WALInitWrite"; - break; - case WAIT_EVENT_WAL_READ: - event_name = "WALRead"; - break; - case WAIT_EVENT_WAL_SYNC: - event_name = "WALSync"; - break; - case WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN: - event_name = "WALSyncMethodAssign"; - break; - case WAIT_EVENT_WAL_WRITE: - event_name = "WALWrite"; - break; - - /* no default case, so that compiler will warn */ - } - - return event_name; -} - - -/* ---------- - * pgstat_get_backend_current_activity() - - * - * Return a string representing the current activity of the backend with - * the specified PID. This looks directly at the BackendStatusArray, - * and so will provide current information regardless of the age of our - * transaction's snapshot of the status array. - * - * It is the caller's responsibility to invoke this only for backends whose - * state is expected to remain stable while the result is in use. The - * only current use is in deadlock reporting, where we can expect that - * the target backend is blocked on a lock. (There are corner cases - * where the target's wait could get aborted while we are looking at it, - * but the very worst consequence is to return a pointer to a string - * that's been changed, so we won't worry too much.) - * - * Note: return strings for special cases match pg_stat_get_backend_activity. - * ---------- - */ -const char * -pgstat_get_backend_current_activity(int pid, bool checkUser) -{ - PgBackendStatus *beentry; - int i; - - beentry = BackendStatusArray; - for (i = 1; i <= MaxBackends; i++) - { - /* - * Although we expect the target backend's entry to be stable, that - * doesn't imply that anyone else's is. To avoid identifying the - * wrong backend, while we check for a match to the desired PID we - * must follow the protocol of retrying if st_changecount changes - * while we examine the entry, or if it's odd. (This might be - * unnecessary, since fetching or storing an int is almost certainly - * atomic, but let's play it safe.) We use a volatile pointer here to - * ensure the compiler doesn't try to get cute. - */ - volatile PgBackendStatus *vbeentry = beentry; - bool found; - - for (;;) - { - int before_changecount; - int after_changecount; - - pgstat_begin_read_activity(vbeentry, before_changecount); - - found = (vbeentry->st_procpid == pid); - - pgstat_end_read_activity(vbeentry, after_changecount); - - if (pgstat_read_activity_complete(before_changecount, - after_changecount)) - break; - - /* Make sure we can break out of loop if stuck... */ - CHECK_FOR_INTERRUPTS(); - } - - if (found) - { - /* Now it is safe to use the non-volatile pointer */ - if (checkUser && !superuser() && beentry->st_userid != GetUserId()) - return ""; - else if (*(beentry->st_activity_raw) == '\0') - return ""; - else - { - /* this'll leak a bit of memory, but that seems acceptable */ - return pgstat_clip_activity(beentry->st_activity_raw); - } - } - - beentry++; - } - - /* If we get here, caller is in error ... */ - return ""; -} - -/* ---------- - * pgstat_get_crashed_backend_activity() - - * - * Return a string representing the current activity of the backend with - * the specified PID. Like the function above, but reads shared memory with - * the expectation that it may be corrupt. On success, copy the string - * into the "buffer" argument and return that pointer. On failure, - * return NULL. - * - * This function is only intended to be used by the postmaster to report the - * query that crashed a backend. In particular, no attempt is made to - * follow the correct concurrency protocol when accessing the - * BackendStatusArray. But that's OK, in the worst case we'll return a - * corrupted message. We also must take care not to trip on ereport(ERROR). - * ---------- - */ -const char * -pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen) -{ - volatile PgBackendStatus *beentry; - int i; - - beentry = BackendStatusArray; - - /* - * We probably shouldn't get here before shared memory has been set up, - * but be safe. - */ - if (beentry == NULL || BackendActivityBuffer == NULL) - return NULL; - - for (i = 1; i <= MaxBackends; i++) - { - if (beentry->st_procpid == pid) - { - /* Read pointer just once, so it can't change after validation */ - const char *activity = beentry->st_activity_raw; - const char *activity_last; - - /* - * We mustn't access activity string before we verify that it - * falls within the BackendActivityBuffer. To make sure that the - * entire string including its ending is contained within the - * buffer, subtract one activity length from the buffer size. - */ - activity_last = BackendActivityBuffer + BackendActivityBufferSize - - pgstat_track_activity_query_size; - - if (activity < BackendActivityBuffer || - activity > activity_last) - return NULL; - - /* If no string available, no point in a report */ - if (activity[0] == '\0') - return NULL; - - /* - * Copy only ASCII-safe characters so we don't run into encoding - * problems when reporting the message; and be sure not to run off - * the end of memory. As only ASCII characters are reported, it - * doesn't seem necessary to perform multibyte aware clipping. - */ - ascii_safe_strlcpy(buffer, activity, - Min(buflen, pgstat_track_activity_query_size)); - - return buffer; - } - - beentry++; - } - - /* PID not found */ - return NULL; -} - -/* ------------------------------------------------------------ - * Local support functions follow - * ------------------------------------------------------------ - */ - - -/* ---------- - * pgstat_setheader() - - * - * Set common header fields in a statistics message - * ---------- - */ -static void -pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype) -{ - hdr->m_type = mtype; -} - - -/* ---------- - * pgstat_send() - - * - * Send out one statistics message to the collector - * ---------- - */ -static void -pgstat_send(void *msg, int len) -{ - int rc; - - if (pgStatSock == PGINVALID_SOCKET) - return; - - ((PgStat_MsgHdr *) msg)->m_size = len; - - /* We'll retry after EINTR, but ignore all other failures */ - do - { - rc = send(pgStatSock, msg, len, 0); - } while (rc < 0 && errno == EINTR); + if (!beentry) + return; -#ifdef USE_ASSERT_CHECKING - /* In debug builds, log send failures ... */ - if (rc < 0) - elog(LOG, "could not send to statistics collector: %m"); -#endif + beentry->st_changecount++; + beentry->st_session_id = new_sessionid; + beentry->st_changecount++; + Assert((beentry->st_changecount & 1) == 0); } /* ---------- @@ -4794,6 +3365,100 @@ pgstat_combine_from_qe(CdbDispatchResults *results, int writerSliceIndex) } } +/* ---------- + * pgstat_send_wal() - + * + * Send WAL statistics to the collector. + * + * If 'force' is not set, WAL stats message is only sent if enough time has + * passed since last one was sent to reach PGSTAT_STAT_INTERVAL. + * ---------- + */ +void +pgstat_send_wal(bool force) +{ + static TimestampTz sendTime = 0; + + /* + * This function can be called even if nothing at all has happened. In + * this case, avoid sending a completely empty message to the stats + * collector. + * + * Check wal_records counter to determine whether any WAL activity has + * happened since last time. Note that other WalUsage counters don't need + * to be checked because they are incremented always together with + * wal_records counter. + * + * m_wal_buffers_full also doesn't need to be checked because it's + * incremented only when at least one WAL record is generated (i.e., + * wal_records counter is incremented). But for safely, we assert that + * m_wal_buffers_full is always zero when no WAL record is generated + * + * This function can be called by a process like walwriter that normally + * generates no WAL records. To determine whether any WAL activity has + * happened at that process since the last time, the numbers of WAL writes + * and syncs are also checked. + */ + if (pgWalUsage.wal_records == prevWalUsage.wal_records && + WalStats.m_wal_write == 0 && WalStats.m_wal_sync == 0) + { + Assert(WalStats.m_wal_buffers_full == 0); + return; + } + + if (!force) + { + TimestampTz now = GetCurrentTimestamp(); + + /* + * Don't send a message unless it's been at least PGSTAT_STAT_INTERVAL + * msec since we last sent one to avoid overloading the stats + * collector. + */ + if (!TimestampDifferenceExceeds(sendTime, now, PGSTAT_STAT_INTERVAL)) + return; + sendTime = now; + } + + /* + * Set the counters related to generated WAL data if the counters were + * updated. + */ + if (pgWalUsage.wal_records != prevWalUsage.wal_records) + { + WalUsage walusage; + + /* + * Calculate how much WAL usage counters were increased by + * substracting the previous counters from the current ones. Fill the + * results in WAL stats message. + */ + MemSet(&walusage, 0, sizeof(WalUsage)); + WalUsageAccumDiff(&walusage, &pgWalUsage, &prevWalUsage); + + WalStats.m_wal_records = walusage.wal_records; + WalStats.m_wal_fpi = walusage.wal_fpi; + WalStats.m_wal_bytes = walusage.wal_bytes; + + /* + * Save the current counters for the subsequent calculation of WAL + * usage. + */ + prevWalUsage = pgWalUsage; + } + + /* + * Prepare and send the message + */ + pgstat_setheader(&WalStats.m_hdr, PGSTAT_MTYPE_WAL); + pgstat_send(&WalStats, sizeof(WalStats)); + + /* + * Clear out the statistics buffer, so it can be re-used. + */ + MemSet(&WalStats, 0, sizeof(WalStats)); +} + /* ---------- * pgstat_send_slru() - * @@ -5013,6 +3678,11 @@ PgstatCollectorMain(int argc, char *argv[]) len); break; + case PGSTAT_MTYPE_RESETREPLSLOTCOUNTER: + pgstat_recv_resetreplslotcounter(&msg.msg_resetreplslotcounter, + len); + break; + case PGSTAT_MTYPE_AUTOVAC_START: pgstat_recv_autovac(&msg.msg_autovacuum_start, len); break; @@ -5025,6 +3695,10 @@ PgstatCollectorMain(int argc, char *argv[]) pgstat_recv_analyze(&msg.msg_analyze, len); break; + case PGSTAT_MTYPE_ANL_ANCESTORS: + pgstat_recv_anl_ancestors(&msg.msg_anl_ancestors, len); + break; + case PGSTAT_MTYPE_ARCHIVER: pgstat_recv_archiver(&msg.msg_archiver, len); break; @@ -5037,6 +3711,10 @@ PgstatCollectorMain(int argc, char *argv[]) pgstat_recv_queuestat((PgStat_MsgQueuestat *) &msg, len); break; + case PGSTAT_MTYPE_WAL: + pgstat_recv_wal(&msg.msg_wal, len); + break; + case PGSTAT_MTYPE_SLRU: pgstat_recv_slru(&msg.msg_slru, len); break; @@ -5067,6 +3745,14 @@ PgstatCollectorMain(int argc, char *argv[]) len); break; + case PGSTAT_MTYPE_REPLSLOT: + pgstat_recv_replslot(&msg.msg_replslot, len); + break; + + case PGSTAT_MTYPE_CONNECTION: + pgstat_recv_connstat(&msg.msg_conn, len); + break; + default: break; } @@ -5141,11 +3827,17 @@ reset_dbentry_counters(PgStat_StatDBEntry *dbentry) dbentry->last_checksum_failure = 0; dbentry->n_block_read_time = 0; dbentry->n_block_write_time = 0; + dbentry->n_sessions = 0; + dbentry->total_session_time = 0; + dbentry->total_active_time = 0; + dbentry->total_idle_in_xact_time = 0; + dbentry->n_sessions_abandoned = 0; + dbentry->n_sessions_fatal = 0; + dbentry->n_sessions_killed = 0; dbentry->stat_reset_timestamp = GetCurrentTimestamp(); dbentry->stats_timestamp = 0; - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(PgStat_StatTabEntry); dbentry->tables = hash_create("Per-database table", @@ -5225,6 +3917,7 @@ pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, Oid tableoid, bool create) result->n_live_tuples = 0; result->n_dead_tuples = 0; result->changes_since_analyze = 0; + result->changes_since_analyze_reported = 0; result->inserts_since_vacuum = 0; result->blocks_fetched = 0; result->blocks_hit = 0; @@ -5308,6 +4001,12 @@ pgstat_write_statsfiles(bool permanent, bool allDbs) rc = fwrite(&archiverStats, sizeof(archiverStats), 1, fpout); (void) rc; /* we'll check for error with ferror */ + /* + * Write WAL stats struct + */ + rc = fwrite(&walStats, sizeof(walStats), 1, fpout); + (void) rc; /* we'll check for error with ferror */ + /* * Write SLRU stats struct */ @@ -5350,6 +4049,21 @@ pgstat_write_statsfiles(bool permanent, bool allDbs) fputc('Q', fpout); fwrite(queueentry, sizeof(PgStat_StatQueueEntry), 1, fpout); } + /* + * Write replication slot stats struct + */ + if (replSlotStatHash) + { + PgStat_StatReplSlotEntry *slotent; + + hash_seq_init(&hstat, replSlotStatHash); + while ((slotent = (PgStat_StatReplSlotEntry *) hash_seq_search(&hstat)) != NULL) + { + fputc('R', fpout); + rc = fwrite(slotent, sizeof(PgStat_StatReplSlotEntry), 1, fpout); + (void) rc; /* we'll check for error with ferror */ + } + } /* * No more output to be done. Close the temp file and replace the old @@ -5572,7 +4286,6 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) /* * Create the DB hashtable */ - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(PgStat_StatDBEntry); hash_ctl.hcxt = pgStatLocalContext; @@ -5592,11 +4305,12 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) pgStatQueueHash = queuehash; /* - * Clear out global and archiver statistics so they start from zero in - * case we can't load an existing statsfile. + * Clear out global, archiver, WAL and SLRU statistics so they start from + * zero in case we can't load an existing statsfile. */ memset(&globalStats, 0, sizeof(globalStats)); memset(&archiverStats, 0, sizeof(archiverStats)); + memset(&walStats, 0, sizeof(walStats)); memset(&slruStats, 0, sizeof(slruStats)); /* @@ -5605,6 +4319,7 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) */ globalStats.stat_reset_timestamp = GetCurrentTimestamp(); archiverStats.stat_reset_timestamp = globalStats.stat_reset_timestamp; + walStats.stat_reset_timestamp = globalStats.stat_reset_timestamp; /* * Set the same reset timestamp for all SLRU items too. @@ -5674,6 +4389,17 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) goto done; } + /* + * Read WAL stats struct + */ + if (fread(&walStats, 1, sizeof(walStats), fpin) != sizeof(walStats)) + { + ereport(pgStatRunningInCollector ? LOG : WARNING, + (errmsg("corrupted statistics file \"%s\"", statfile))); + memset(&walStats, 0, sizeof(walStats)); + goto done; + } + /* * Read SLRU stats struct */ @@ -5746,7 +4472,6 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) break; } - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(PgStat_StatTabEntry); hash_ctl.hcxt = pgStatLocalContext; @@ -5810,6 +4535,45 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep) memcpy(queueentry, &queuebuf, sizeof(PgStat_StatQueueEntry)); break; + /* + * 'R' A PgStat_StatReplSlotEntry struct describing a + * replication slot follows. + */ + case 'R': + { + PgStat_StatReplSlotEntry slotbuf; + PgStat_StatReplSlotEntry *slotent; + + if (fread(&slotbuf, 1, sizeof(PgStat_StatReplSlotEntry), fpin) + != sizeof(PgStat_StatReplSlotEntry)) + { + ereport(pgStatRunningInCollector ? LOG : WARNING, + (errmsg("corrupted statistics file \"%s\"", + statfile))); + goto done; + } + + /* Create hash table if we don't have it already. */ + if (replSlotStatHash == NULL) + { + HASHCTL hash_ctl; + + hash_ctl.keysize = sizeof(NameData); + hash_ctl.entrysize = sizeof(PgStat_StatReplSlotEntry); + hash_ctl.hcxt = pgStatLocalContext; + replSlotStatHash = hash_create("Replication slots hash", + PGSTAT_REPLSLOT_HASH_SIZE, + &hash_ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + } + + slotent = (PgStat_StatReplSlotEntry *) hash_search(replSlotStatHash, + (void *) &slotbuf.slotname, + HASH_ENTER, NULL); + memcpy(slotent, &slotbuf, sizeof(PgStat_StatReplSlotEntry)); + break; + } + case 'E': goto done; @@ -5998,7 +4762,8 @@ pgstat_read_db_statsfile(Oid databaseid, HTAB *tabhash, HTAB *funchash, * pgstat_read_db_statsfile_timestamp() - * * Attempt to determine the timestamp of the last db statfile write. - * Returns true if successful; the timestamp is stored in *ts. + * Returns true if successful; the timestamp is stored in *ts. The caller must + * rely on timestamp stored in *ts iff the function returns true. * * This needs to be careful about handling databases for which no stats file * exists, such as databases without a stat entry or those not yet written: @@ -6019,7 +4784,9 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent, PgStat_StatQueueEntry queuebuf; /* GPDB */ PgStat_GlobalStats myGlobalStats; PgStat_ArchiverStats myArchiverStats; + PgStat_WalStats myWalStats; PgStat_SLRUStats mySLRUStats[SLRU_NUM_ELEMENTS]; + PgStat_StatReplSlotEntry myReplSlotStats; FILE *fpin; int32 format_id; const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename; @@ -6074,6 +4841,17 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent, return false; } + /* + * Read WAL stats struct + */ + if (fread(&myWalStats, 1, sizeof(myWalStats), fpin) != sizeof(myWalStats)) + { + ereport(pgStatRunningInCollector ? LOG : WARNING, + (errmsg("corrupted statistics file \"%s\"", statfile))); + FreeFile(fpin); + return false; + } + /* * Read SLRU stats struct */ @@ -6107,7 +4885,8 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent, ereport(pgStatRunningInCollector ? LOG : WARNING, (errmsg("corrupted statistics file \"%s\"", statfile))); - goto done; + FreeFile(fpin); + return false; } /* @@ -6132,7 +4911,24 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent, ereport(pgStatRunningInCollector ? LOG : WARNING, (errmsg("corrupted statistics file \"%s\"", statfile))); - goto done; + FreeFile(fpin); + return false; + } + break; + + /* + * 'R' A PgStat_StatReplSlotEntry struct describing a + * replication slot follows. + */ + case 'R': + if (fread(&myReplSlotStats, 1, sizeof(PgStat_StatReplSlotEntry), fpin) + != sizeof(PgStat_StatReplSlotEntry)) + { + ereport(pgStatRunningInCollector ? LOG : WARNING, + (errmsg("corrupted statistics file \"%s\"", + statfile))); + FreeFile(fpin); + return false; } break; @@ -6140,10 +4936,13 @@ pgstat_read_db_statsfile_timestamp(Oid databaseid, bool permanent, goto done; default: - ereport(pgStatRunningInCollector ? LOG : WARNING, - (errmsg("corrupted statistics file \"%s\"", - statfile))); - goto done; + { + ereport(pgStatRunningInCollector ? LOG : WARNING, + (errmsg("corrupted statistics file \"%s\"", + statfile))); + FreeFile(fpin); + return false; + } } } @@ -6247,8 +5046,9 @@ backend_read_statsfile(void) /* Copy because timestamptz_to_str returns a static buffer */ filetime = pstrdup(timestamptz_to_str(file_ts)); mytime = pstrdup(timestamptz_to_str(cur_ts)); - elog(LOG, "stats collector's time %s is later than backend local time %s", - filetime, mytime); + ereport(LOG, + (errmsg("statistics collector's time %s is later than backend local time %s", + filetime, mytime))); pfree(filetime); pfree(mytime); } @@ -6321,8 +5121,14 @@ pgstat_clear_snapshot(void) /* Reset variables */ pgStatLocalContext = NULL; pgStatDBHash = NULL; - localBackendStatusTable = NULL; - localNumBackends = 0; + replSlotStatHash = NULL; + + /* + * Historically the backend_status.c facilities lived in this file, and + * were reset with the same function. For now keep it that way, and + * forward the reset request. + */ + pgstat_clear_backend_activity_snapshot(); } @@ -6390,9 +5196,9 @@ pgstat_recv_inquiry(PgStat_MsgInquiry *msg, int len) /* Copy because timestamptz_to_str returns a static buffer */ writetime = pstrdup(timestamptz_to_str(dbentry->stats_timestamp)); mytime = pstrdup(timestamptz_to_str(cur_ts)); - elog(LOG, - "stats_timestamp %s is later than collector's time %s for database %u", - writetime, mytime, dbentry->databaseid); + ereport(LOG, + (errmsg("stats_timestamp %s is later than collector's time %s for database %u", + writetime, mytime, dbentry->databaseid))); pfree(writetime); pfree(mytime); } @@ -6470,6 +5276,7 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) tabentry->n_live_tuples = tabmsg->t_counts.t_delta_live_tuples; tabentry->n_dead_tuples = tabmsg->t_counts.t_delta_dead_tuples; tabentry->changes_since_analyze = tabmsg->t_counts.t_changed_tuples; + tabentry->changes_since_analyze_reported = 0; tabentry->inserts_since_vacuum = tabmsg->t_counts.t_tuples_inserted; tabentry->blocks_fetched = tabmsg->t_counts.t_blocks_fetched; tabentry->blocks_hit = tabmsg->t_counts.t_blocks_hit; @@ -6664,6 +5471,12 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len) memset(&archiverStats, 0, sizeof(archiverStats)); archiverStats.stat_reset_timestamp = GetCurrentTimestamp(); } + else if (msg->m_resettarget == RESET_WAL) + { + /* Reset the WAL statistics for the cluster. */ + memset(&walStats, 0, sizeof(walStats)); + walStats.stat_reset_timestamp = GetCurrentTimestamp(); + } /* * Presumably the sender of this message validated the target, don't @@ -6722,6 +5535,52 @@ pgstat_recv_resetslrucounter(PgStat_MsgResetslrucounter *msg, int len) } } +/* ---------- + * pgstat_recv_resetreplslotcounter() - + * + * Reset some replication slot statistics of the cluster. + * ---------- + */ +static void +pgstat_recv_resetreplslotcounter(PgStat_MsgResetreplslotcounter *msg, + int len) +{ + PgStat_StatReplSlotEntry *slotent; + TimestampTz ts; + + /* Return if we don't have replication slot statistics */ + if (replSlotStatHash == NULL) + return; + + ts = GetCurrentTimestamp(); + if (msg->clearall) + { + HASH_SEQ_STATUS sstat; + + hash_seq_init(&sstat, replSlotStatHash); + while ((slotent = (PgStat_StatReplSlotEntry *) hash_seq_search(&sstat)) != NULL) + pgstat_reset_replslot(slotent, ts); + } + else + { + /* Get the slot statistics to reset */ + slotent = pgstat_get_replslot_entry(msg->m_slotname, false); + + /* + * Nothing to do if the given slot entry is not found. This could + * happen when the slot with the given name is removed and the + * corresponding statistics entry is also removed before receiving the + * reset message. + */ + if (!slotent) + return; + + /* Reset the stats for the requested replication slot */ + pgstat_reset_replslot(slotent, ts); + } +} + + /* ---------- * pgstat_recv_autovac() - * @@ -6815,7 +5674,10 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len) * have no good way to estimate how many of those there were. */ if (msg->m_resetcounter) + { tabentry->changes_since_analyze = 0; + tabentry->changes_since_analyze_reported = 0; + } if (msg->m_autovacuum) { @@ -6829,6 +5691,29 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len) } } +static void +pgstat_recv_anl_ancestors(PgStat_MsgAnlAncestors *msg, int len) +{ + PgStat_StatDBEntry *dbentry; + PgStat_StatTabEntry *tabentry; + + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); + + tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); + + for (int i = 0; i < msg->m_nancestors; i++) + { + Oid ancestor_relid = msg->m_ancestors[i]; + PgStat_StatTabEntry *ancestor; + + ancestor = pgstat_get_tab_entry(dbentry, ancestor_relid, true); + ancestor->changes_since_analyze += + tabentry->changes_since_analyze - tabentry->changes_since_analyze_reported; + } + + tabentry->changes_since_analyze_reported = tabentry->changes_since_analyze; + +} /* ---------- * pgstat_recv_archiver() - @@ -7070,6 +5955,25 @@ pgstat_fetch_stat_queueentry(Oid queueid) } +/* ---------- + * pgstat_recv_wal() - + * + * Process a WAL message. + * ---------- + */ +static void +pgstat_recv_wal(PgStat_MsgWal *msg, int len) +{ + walStats.wal_records += msg->m_wal_records; + walStats.wal_fpi += msg->m_wal_fpi; + walStats.wal_bytes += msg->m_wal_bytes; + walStats.wal_buffers_full += msg->m_wal_buffers_full; + walStats.wal_write += msg->m_wal_write; + walStats.wal_sync += msg->m_wal_sync; + walStats.wal_write_time += msg->m_wal_write_time; + walStats.wal_sync_time += msg->m_wal_sync_time; +} + /* ---------- * pgstat_recv_slru() - * @@ -7161,6 +6065,92 @@ pgstat_recv_checksum_failure(PgStat_MsgChecksumFailure *msg, int len) dbentry->last_checksum_failure = msg->m_failure_time; } +/* ---------- + * pgstat_recv_replslot() - + * + * Process a REPLSLOT message. + * ---------- + */ +static void +pgstat_recv_replslot(PgStat_MsgReplSlot *msg, int len) +{ + if (msg->m_drop) + { + Assert(!msg->m_create); + + /* Remove the replication slot statistics with the given name */ + if (replSlotStatHash != NULL) + (void) hash_search(replSlotStatHash, + (void *) &(msg->m_slotname), + HASH_REMOVE, + NULL); + } + else + { + PgStat_StatReplSlotEntry *slotent; + + slotent = pgstat_get_replslot_entry(msg->m_slotname, true); + Assert(slotent); + + if (msg->m_create) + { + /* + * If the message for dropping the slot with the same name gets + * lost, slotent has stats for the old slot. So we initialize all + * counters at slot creation. + */ + pgstat_reset_replslot(slotent, 0); + } + else + { + /* Update the replication slot statistics */ + slotent->spill_txns += msg->m_spill_txns; + slotent->spill_count += msg->m_spill_count; + slotent->spill_bytes += msg->m_spill_bytes; + slotent->stream_txns += msg->m_stream_txns; + slotent->stream_count += msg->m_stream_count; + slotent->stream_bytes += msg->m_stream_bytes; + slotent->total_txns += msg->m_total_txns; + slotent->total_bytes += msg->m_total_bytes; + } + } +} + +/* ---------- + * pgstat_recv_connstat() - + * + * Process connection information. + * ---------- + */ +static void +pgstat_recv_connstat(PgStat_MsgConn *msg, int len) +{ + PgStat_StatDBEntry *dbentry; + + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); + + dbentry->n_sessions += msg->m_count; + dbentry->total_session_time += msg->m_session_time; + dbentry->total_active_time += msg->m_active_time; + dbentry->total_idle_in_xact_time += msg->m_idle_in_xact_time; + switch (msg->m_disconnect) + { + case DISCONNECT_NOT_YET: + case DISCONNECT_NORMAL: + /* we don't collect these */ + break; + case DISCONNECT_CLIENT_EOF: + dbentry->n_sessions_abandoned++; + break; + case DISCONNECT_FATAL: + dbentry->n_sessions_fatal++; + break; + case DISCONNECT_KILLED: + dbentry->n_sessions_killed++; + break; + } +} + /* ---------- * pgstat_recv_tempfile() - * @@ -7299,48 +6289,81 @@ pgstat_db_requested(Oid databaseid) return false; } -/* - * Convert a potentially unsafely truncated activity string (see - * PgBackendStatus.st_activity_raw's documentation) into a correctly truncated - * one. +/* ---------- + * pgstat_replslot_entry + * + * Return the entry of replication slot stats with the given name. Return + * NULL if not found and the caller didn't request to create it. * - * The returned string is allocated in the caller's memory context and may be - * freed. + * create tells whether to create the new slot entry if it is not found. + * ---------- */ -char * -pgstat_clip_activity(const char *raw_activity) +static PgStat_StatReplSlotEntry * +pgstat_get_replslot_entry(NameData name, bool create) { - char *activity; - int rawlen; - int cliplen; + PgStat_StatReplSlotEntry *slotent; + bool found; - /* - * Some callers, like pgstat_get_backend_current_activity(), do not - * guarantee that the buffer isn't concurrently modified. We try to take - * care that the buffer is always terminated by a NUL byte regardless, but - * let's still be paranoid about the string's length. In those cases the - * underlying buffer is guaranteed to be pgstat_track_activity_query_size - * large. - */ - activity = pnstrdup(raw_activity, pgstat_track_activity_query_size - 1); + if (replSlotStatHash == NULL) + { + HASHCTL hash_ctl; + + /* + * Quick return NULL if the hash table is empty and the caller didn't + * request to create the entry. + */ + if (!create) + return NULL; + + hash_ctl.keysize = sizeof(NameData); + hash_ctl.entrysize = sizeof(PgStat_StatReplSlotEntry); + replSlotStatHash = hash_create("Replication slots hash", + PGSTAT_REPLSLOT_HASH_SIZE, + &hash_ctl, + HASH_ELEM | HASH_BLOBS); + } - /* now double-guaranteed to be NUL terminated */ - rawlen = strlen(activity); + slotent = (PgStat_StatReplSlotEntry *) hash_search(replSlotStatHash, + (void *) &name, + create ? HASH_ENTER : HASH_FIND, + &found); - /* - * All supported server-encodings make it possible to determine the length - * of a multi-byte character from its first byte (this is not the case for - * client encodings, see GB18030). As st_activity is always stored using - * server encoding, this allows us to perform multi-byte aware truncation, - * even if the string earlier was truncated in the middle of a multi-byte - * character. - */ - cliplen = pg_mbcliplen(activity, rawlen, - pgstat_track_activity_query_size - 1); + if (!slotent) + { + /* not found */ + Assert(!create && !found); + return NULL; + } + + /* initialize the entry */ + if (create && !found) + { + namestrcpy(&(slotent->slotname), NameStr(name)); + pgstat_reset_replslot(slotent, 0); + } - activity[cliplen] = '\0'; + return slotent; +} - return activity; +/* ---------- + * pgstat_reset_replslot + * + * Reset the given replication slot stats. + * ---------- + */ +static void +pgstat_reset_replslot(PgStat_StatReplSlotEntry *slotent, TimestampTz ts) +{ + /* reset only counters. Don't clear slot name */ + slotent->spill_txns = 0; + slotent->spill_count = 0; + slotent->spill_bytes = 0; + slotent->stream_txns = 0; + slotent->stream_count = 0; + slotent->stream_bytes = 0; + slotent->total_txns = 0; + slotent->total_bytes = 0; + slotent->stat_reset_timestamp = ts; } /* diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 7e13799866f2..399f54c61321 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -34,7 +34,7 @@ * * Portions Copyright (c) 2005-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -113,7 +113,6 @@ #include "libpq/libpq.h" #include "libpq/pqformat.h" #include "libpq/pqsignal.h" -#include "miscadmin.h" #include "pg_getopt.h" #include "pgstat.h" #include "port/pg_bswap.h" @@ -121,6 +120,7 @@ #include "postmaster/bgworker_internals.h" #include "postmaster/bgwriter.h" #include "postmaster/fork_process.h" +#include "postmaster/interrupt.h" #include "postmaster/pgarch.h" #include "postmaster/postmaster.h" #include "postmaster/fts.h" @@ -143,6 +143,7 @@ #include "utils/memutils.h" #include "utils/pidfile.h" #include "utils/ps_status.h" +#include "utils/queryjumble.h" #include "utils/timeout.h" #include "utils/timestamp.h" #include "utils/varlena.h" @@ -250,11 +251,6 @@ int ReservedBackends; #define MAXLISTEN 64 static pgsocket ListenSocket[MAXLISTEN]; -/* - * Set by the -o option - */ -static char ExtraOptions[MAXPGPATH]; - /* * These globals control the behavior of the postmaster in case some * backend dumps core. Normally, it kills all peers of the dead backend @@ -278,6 +274,7 @@ bool Db_user_namespace = false; bool enable_bonjour = false; char *bonjour_name; bool restart_after_crash = true; +bool remove_temp_files_after_crash = true; /* * PIDs of special child processes; 0 when not running. When adding a new PID @@ -499,7 +496,7 @@ static void SIGHUP_handler(SIGNAL_ARGS); static void pmdie(SIGNAL_ARGS); static void reaper(SIGNAL_ARGS); static void sigusr1_handler(SIGNAL_ARGS); -static void startup_die(SIGNAL_ARGS); +static void process_startup_packet_die(SIGNAL_ARGS); static void dummy_handler(SIGNAL_ARGS); static void StartupPacketTimeoutHandler(void); static void CleanupBackend(int pid, int exitstatus); @@ -544,9 +541,10 @@ static void setProcAffinity(int id); * even during recovery. */ #define PgArchStartupAllowed() \ - ((XLogArchivingActive() && pmState == PM_RUN) || \ - (XLogArchivingAlways() && \ - (pmState == PM_RECOVERY || pmState == PM_HOT_STANDBY))) + (((XLogArchivingActive() && pmState == PM_RUN) || \ + (XLogArchivingAlways() && \ + (pmState == PM_RECOVERY || pmState == PM_HOT_STANDBY))) && \ + PgArchCanRestart()) bool isAuxiliaryBgWorker(BackgroundWorker *worker); @@ -623,6 +621,7 @@ typedef struct bool redirection_done; bool IsBinaryUpgrade; bool ConvertMasterDataDirToSegment; + bool query_id_enabled; int max_safe_fds; int MaxBackends; #ifdef WIN32 @@ -635,7 +634,6 @@ typedef struct #endif char my_exec_path[MAXPGPATH]; char pkglib_path[MAXPGPATH]; - char ExtraOptions[MAXPGPATH]; } BackendParameters; static void read_backend_variables(char *id, Port *port); @@ -653,6 +651,7 @@ static void ShmemBackendArrayRemove(Backend *bn); #endif /* EXEC_BACKEND */ #define StartupDataBase() StartChildProcess(StartupProcess) +#define StartArchiver() StartChildProcess(ArchiverProcess) #define StartBackgroundWriter() StartChildProcess(BgWriterProcess) #define StartCheckpointer() StartChildProcess(CheckpointerProcess) #define StartWalWriter() StartChildProcess(WalWriterProcess) @@ -777,6 +776,16 @@ PostmasterMain(int argc, char *argv[]) pqsignal_pm(SIGUSR2, dummy_handler); /* unused, reserve for children */ pqsignal_pm(SIGCHLD, reaper); /* handle child termination */ +#ifdef SIGURG + + /* + * Ignore SIGURG for now. Child processes may change this (see + * InitializeLatchSupport), but they will not receive any such signals + * until they wait on a latch. + */ + pqsignal_pm(SIGURG, SIG_IGN); /* ignored */ +#endif + /* * No other place in Postgres should touch SIGTTIN/SIGTTOU handling. We * ignore those signals in a postmaster environment, so that there is no @@ -808,7 +817,7 @@ PostmasterMain(int argc, char *argv[]) * tcop/postgres.c (the option sets should not conflict) and with the * common help() function in main/main.c. */ - while ((opt = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lMmN:nOo:Pp:r:S:sTt:W:-:")) != -1) + while ((opt = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lMmN:nOPp:r:S:sTt:W:-:")) != -1) { switch (opt) { @@ -909,13 +918,6 @@ PostmasterMain(int argc, char *argv[]) SetConfigOption("allow_system_table_mods", "true", PGC_POSTMASTER, PGC_S_ARGV); break; - case 'o': - /* Other options to pass to the backend on the command line */ - snprintf(ExtraOptions + strlen(ExtraOptions), - sizeof(ExtraOptions) - strlen(ExtraOptions), - " %s", optarg); - break; - case 'P': SetConfigOption("ignore_system_indexes", "true", PGC_POSTMASTER, PGC_S_ARGV); break; @@ -1443,8 +1445,9 @@ PostmasterMain(int argc, char *argv[]) NULL, NULL); if (err != kDNSServiceErr_NoError) - elog(LOG, "DNSServiceRegister() failed: error code %ld", - (long) err); + ereport(LOG, + (errmsg("DNSServiceRegister() failed: error code %ld", + (long) err))); /* * We don't bother to read the mDNS daemon's reply, and we expect that @@ -1703,7 +1706,8 @@ getInstallationPaths(const char *argv0) /* Locate the postgres executable itself */ if (find_my_exec(argv0, my_exec_path) < 0) - elog(FATAL, "%s: could not locate my own executable path", argv0); + ereport(FATAL, + (errmsg("%s: could not locate my own executable path", argv0))); #ifdef EXEC_BACKEND /* Locate executable backend before we change working directory */ @@ -2069,7 +2073,7 @@ ServerLoop(void) /* If we have lost the archiver, try to start a new one. */ if (PgArchPID == 0 && PgArchStartupAllowed()) - PgArchPID = pgarch_start(); + PgArchPID = StartArchiver(); /* If we need to signal the autovacuum launcher, do so now */ if (avlauncher_needs_signal) @@ -2132,6 +2136,8 @@ ServerLoop(void) } #endif /* We were gentle with them before. Not anymore */ + ereport(LOG, + (errmsg("issuing SIGKILL to recalcitrant children"))); TerminateChildren(SIGKILL); /* reset flag so we don't SIGKILL again */ AbortStartTime = 0; @@ -2246,7 +2252,7 @@ static int ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) { int32 len; - void *buf; + char *buf; ProtocolVersion proto; MemoryContext oldcontext; char *gpqeid = NULL; @@ -2298,15 +2304,12 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) } /* - * Allocate at least the size of an old-style startup packet, plus one - * extra byte, and make sure all are zeroes. This ensures we will have - * null termination of all strings, in both fixed- and variable-length - * packet layouts. + * Allocate space to hold the startup packet, plus one extra byte that's + * initialized to be zero. This ensures we will have null termination of + * all strings inside the packet. */ - if (len <= (int32) sizeof(StartupPacket)) - buf = palloc0(sizeof(StartupPacket) + 1); - else - buf = palloc0(len + 1); + buf = palloc(len + 1); + buf[len] = '\0'; if (pq_getbytes(buf, len) == EOF) { @@ -2370,6 +2373,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) else if (proto == NEGOTIATE_GSS_CODE && !gss_done) { char GSSok = 'N'; + #ifdef ENABLE_GSS /* No GSSAPI encryption when on Unix socket */ if (!IS_AF_UNIX(port->laddr.addr.ss_family)) @@ -2428,7 +2432,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) */ oldcontext = MemoryContextSwitchTo(TopMemoryContext); - if (PG_PROTOCOL_MAJOR(proto) >= 3) + /* Handle protocol version 3 startup packet */ { int32 offset = sizeof(ProtocolVersion); List *unrecognized_protocol_options = NIL; @@ -2442,7 +2446,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) while (offset < len) { - char *nameptr = ((char *) buf) + offset; + char *nameptr = buf + offset; int32 valoffset; char *valptr; @@ -2451,7 +2455,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) valoffset = offset + strlen(nameptr) + 1; if (valoffset >= len) break; /* missing value, will complain below */ - valptr = ((char *) buf) + valoffset; + valptr = buf + valoffset; if (strcmp(nameptr, "database") == 0) port->database_name = pstrdup(valptr); @@ -2605,27 +2609,6 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) unrecognized_protocol_options != NIL) SendNegotiateProtocolVersion(unrecognized_protocol_options); } - else - { - /* - * Get the parameters from the old-style, fixed-width-fields startup - * packet as C strings. The packet destination was cleared first so a - * short packet has zeros silently added. We have to be prepared to - * truncate the pstrdup result for oversize fields, though. - */ - StartupPacket *packet = (StartupPacket *) buf; - - port->database_name = pstrdup(packet->database); - if (strlen(port->database_name) > sizeof(packet->database)) - port->database_name[sizeof(packet->database)] = '\0'; - port->user_name = pstrdup(packet->user); - if (strlen(port->user_name) > sizeof(packet->user)) - port->user_name[sizeof(packet->user)] = '\0'; - port->cmdline_options = pstrdup(packet->options); - if (strlen(port->cmdline_options) > sizeof(packet->options)) - port->cmdline_options[sizeof(packet->options)] = '\0'; - port->guc_options = NIL; - } /* Check a user name was given. */ if (port->user_name == NULL || port->user_name[0] == '\0') @@ -2710,6 +2693,18 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done) errdetail(POSTMASTER_IN_RECOVERY_DETAIL_MSG " %X/%X", (uint32) (recptr >> 32), (uint32) recptr))); break; + case CAC_NOTCONSISTENT: + if (EnableHotStandby) + ereport(FATAL, + (errcode(ERRCODE_CANNOT_CONNECT_NOW), + errmsg("the database system is not yet accepting connections"), + errdetail("Consistent recovery state has not been yet reached."))); + else + ereport(FATAL, + (errcode(ERRCODE_CANNOT_CONNECT_NOW), + errmsg("the database system is not accepting connections"), + errdetail("Hot standby mode is disabled."))); + break; case CAC_SHUTDOWN: ereport(FATAL, (errcode(ERRCODE_CANNOT_CONNECT_NOW), @@ -2917,16 +2912,32 @@ canAcceptConnections(int backend_type) { if (Shutdown > NoShutdown) return CAC_SHUTDOWN; /* shutdown is pending */ + else if (!FatalError && pmState == PM_STARTUP) + return CAC_STARTUP; /* normal startup */ + + /* + * GPDB: a mirror runs with hot_standby off and stays in PM_RECOVERY + * for its whole life, so the upstream PM_RECOVERY -> + * CAC_NOTCONSISTENT branch below would shadow the mirror-ready state + * for good. CAC_NOTCONSISTENT has no FTS exemption in + * ProcessStartupPacket, so FTS could neither probe nor promote a + * mirror, and gprecoverseg could not read the version it expects + * from the CAC_MIRROR_READY error. Once the wal receiver has been + * launched at least once, report the mirror as ready. Keep the + * upstream fail-fast CAC_NOTCONSISTENT behavior for genuine hot + * standby servers that just haven't reached consistency yet. + */ + else if (!EnableHotStandby && GetMirrorReadyFlag()) + return CAC_MIRROR_READY; + else if (!FatalError && pmState == PM_RECOVERY) + return CAC_NOTCONSISTENT; /* not yet at consistent recovery + * state */ /* * If the wal receiver has been launched at least once, return that * the mirror is ready. */ else if (GetMirrorReadyFlag()) return CAC_MIRROR_READY; - else if (!FatalError && - (pmState == PM_STARTUP || - pmState == PM_RECOVERY)) - return CAC_STARTUP; /* normal startup */ else if (pmState == PM_STARTUP || pmState == PM_RECOVERY) return CAC_RECOVERY; /* else must be crash recovery */ else @@ -2998,37 +3009,19 @@ ConnCreate(int serverFd) return NULL; } - /* - * Allocate GSSAPI specific state struct - */ -#ifndef EXEC_BACKEND -#if defined(ENABLE_GSS) || defined(ENABLE_SSPI) - port->gss = (pg_gssinfo *) calloc(1, sizeof(pg_gssinfo)); - if (!port->gss) - { - ereport(LOG, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - ExitPostmaster(1); - } -#endif -#endif - return port; } /* * ConnFree -- free a local connection data structure + * + * Caller has already closed the socket if any, so there's not much + * to do here. */ static void ConnFree(Port *conn) { -#ifdef USE_SSL - secure_close(conn); -#endif - if (conn->gss) - free(conn->gss); free(conn); } @@ -3383,6 +3376,8 @@ pmdie(SIGNAL_ARGS) sd_notify(0, "STOPPING=1"); #endif + /* tell children to shut down ASAP */ + SetQuitSignalReason(PMQUIT_FOR_STOP); TerminateChildren(SIGQUIT); pmState = PM_WAIT_BACKENDS; @@ -3537,7 +3532,7 @@ reaper(SIGNAL_ARGS) if (!IsBinaryUpgrade && AutoVacuumingActive() && AutoVacPID == 0) AutoVacPID = StartAutoVacLauncher(); if (PgArchStartupAllowed() && PgArchPID == 0) - PgArchPID = pgarch_start(); + PgArchPID = StartArchiver(); if (PgStatPID == 0) PgStatPID = pgstat_start(); @@ -3687,20 +3682,22 @@ reaper(SIGNAL_ARGS) } /* - * Was it the archiver? If so, just try to start a new one; no need - * to force reset of the rest of the system. (If fail, we'll try - * again in future cycles of the main loop.). Unless we were waiting - * for it to shut down; don't restart it in that case, and + * Was it the archiver? If exit status is zero (normal) or one (FATAL + * exit), we assume everything is all right just like normal backends + * and just try to restart a new one so that we immediately retry + * archiving remaining files. (If fail, we'll try again in future + * cycles of the postmaster's main loop.) Unless we were waiting for + * it to shut down; don't restart it in that case, and * PostmasterStateMachine() will advance to the next shutdown step. */ if (pid == PgArchPID) { PgArchPID = 0; - if (!EXIT_STATUS_0(exitstatus)) - LogChildExit(LOG, _("archiver process"), - pid, exitstatus); + if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus)) + HandleChildCrash(pid, exitstatus, + _("archiver process")); if (PgArchStartupAllowed()) - PgArchPID = pgarch_start(); + PgArchPID = StartArchiver(); continue; } @@ -3948,7 +3945,7 @@ CleanupBackend(int pid, /* * HandleChildCrash -- cleanup after failed backend, bgwriter, checkpointer, - * walwriter, autovacuum, or background worker. + * walwriter, autovacuum, archiver or background worker. * * The objectives here are to clean up our local state about the child * process, and to signal all other remaining children to quickdie. @@ -3975,6 +3972,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) LogChildExit(LOG, procname, pid, exitstatus); ereport(LOG, (errmsg("terminating any other active server processes"))); + SetQuitSignalReason(PMQUIT_FOR_CRASH); } /* Process background workers. */ @@ -4011,7 +4009,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) * * SIGQUIT is the special signal that says exit without proc_exit * and let the user know what's going on. But if SendStop is set - * (-s on command line), then we send SIGSTOP instead, so that we + * (-T on command line), then we send SIGSTOP instead, so that we * can get core dumps from all backends by hand. */ if (take_action) @@ -4054,7 +4052,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) * * SIGQUIT is the special signal that says exit without proc_exit * and let the user know what's going on. But if SendStop is set - * (-s on command line), then we send SIGSTOP instead, so that we + * (-T on command line), then we send SIGSTOP instead, so that we * can get core dumps from all backends by hand. * * We could exclude dead_end children here, but at least in the @@ -4153,19 +4151,16 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) signal_child(AutoVacPID, (SendStop ? SIGSTOP : SIGQUIT)); } - /* - * Force a power-cycle of the pgarch process too. (This isn't absolutely - * necessary, but it seems like a good idea for robustness, and it - * simplifies the state-machine logic in the case where a shutdown request - * arrives during crash processing.) - */ - if (PgArchPID != 0 && take_action) + /* Take care of the archiver too */ + if (pid == PgArchPID) + PgArchPID = 0; + else if (PgArchPID != 0 && take_action) { ereport(DEBUG2, (errmsg_internal("sending %s to process %d", - "SIGQUIT", + (SendStop ? "SIGSTOP" : "SIGQUIT"), (int) PgArchPID))); - signal_child(PgArchPID, SIGQUIT); + signal_child(PgArchPID, (SendStop ? SIGSTOP : SIGQUIT)); } /* @@ -4316,6 +4311,13 @@ PostmasterStateMachine(void) */ if (pmState == PM_STOP_BACKENDS) { + /* + * Forget any pending requests for background workers, since we're no + * longer willing to launch any new workers. (If additional requests + * arrive, BackgroundWorkerStateChange will reject them.) + */ + ForgetUnstartedBackgroundWorkers(); + /* Signal all backend children except walsenders */ SignalSomeChildren(SIGTERM, BACKEND_TYPE_ALL - BACKEND_TYPE_WALSND); @@ -4350,12 +4352,11 @@ PostmasterStateMachine(void) * (including autovac workers), no bgworkers (including unconnected * ones), and no walwriter, autovac launcher or bgwriter. If we are * doing crash recovery or an immediate shutdown then we expect the - * checkpointer to exit as well, otherwise not. The archiver, stats, - * and syslogger processes are disregarded since they are not - * connected to shared memory; we also disregard dead_end children - * here. Walsenders are also disregarded, they will be terminated - * later after writing the checkpoint record, like the archiver - * process. + * checkpointer to exit as well, otherwise not. The stats and + * syslogger processes are disregarded since they are not connected to + * shared memory; we also disregard dead_end children here. Walsenders + * and archiver are also disregarded, they will be terminated later + * after writing the checkpoint record. */ if (CountChildren(BACKEND_TYPE_ALL - BACKEND_TYPE_WALSND) == 0 && StartupPID == 0 && @@ -4458,6 +4459,7 @@ PostmasterStateMachine(void) Assert(CheckpointerPID == 0); Assert(WalWriterPID == 0); Assert(AutoVacPID == 0); + Assert(PgArchPID == 0); /* syslogger is not considered here */ pmState = PM_NO_CHILDREN; } @@ -4496,7 +4498,11 @@ PostmasterStateMachine(void) if (ReachedNormalRunning) CancelBackup(); - /* Normal exit from the postmaster is here */ + /* + * Normal exit from the postmaster is here. We don't need to log + * anything here, since the UnlinkLockFiles proc_exit callback + * will do so, and that should be the last user-visible action. + */ ExitPostmaster(0); } } @@ -4508,9 +4514,21 @@ PostmasterStateMachine(void) * startup process fails, because more than likely it will just fail again * and we will keep trying forever. */ - if (pmState == PM_NO_CHILDREN && - (StartupStatus == STARTUP_CRASHED || !restart_after_crash)) - ExitPostmaster(1); + if (pmState == PM_NO_CHILDREN) + { + if (StartupStatus == STARTUP_CRASHED) + { + ereport(LOG, + (errmsg("shutting down due to startup process failure"))); + ExitPostmaster(1); + } + if (!restart_after_crash) + { + ereport(LOG, + (errmsg("shutting down because restart_after_crash is off"))); + ExitPostmaster(1); + } + } /* * If we need to recover from a crash, wait for all non-syslogger children @@ -4521,6 +4539,9 @@ PostmasterStateMachine(void) ereport(LOG, (errmsg("all server processes terminated; reinitializing"))); + /* remove leftover temporary files after a crash */ + if (remove_temp_files_after_crash) + RemovePgTempFiles(); /* CDB: reload all auxiliary workers like FTS and DTX recover or GDD */ load_auxiliary_libraries(); @@ -4811,6 +4832,8 @@ report_fork_failure_to_client(Port *port, int errnum) * returns: nothing. Will not return at all if there's any failure. * * Note: this code does not depend on having any access to shared memory. + * Indeed, our approach to SIGTERM/timeout handling *requires* that + * shared memory not have been touched yet; see comments within. * In the EXEC_BACKEND case, we are physically attached to shared memory * but have not yet set up most of our local pointers to shmem structures. */ @@ -4854,22 +4877,17 @@ BackendInitialize(Port *port) whereToSendOutput = DestRemote; /* now safe to ereport to client */ /* - * We arrange for a simple exit(1) if we receive SIGTERM or SIGQUIT or - * timeout while trying to collect the startup packet. Otherwise the - * postmaster cannot shutdown the database FAST or IMMED cleanly if a - * buggy client fails to send the packet promptly. XXX it follows that - * the remainder of this function must tolerate losing control at any - * instant. Likewise, any pg_on_exit_callback registered before or during - * this function must be prepared to execute at any instant between here - * and the end of this function. Furthermore, affected callbacks execute - * partially or not at all when a second exit-inducing signal arrives - * after proc_exit_prepare() decrements on_proc_exit_index. (Thanks to - * that mechanic, callbacks need not anticipate more than one call.) This - * is fragile; it ought to instead follow the norm of handling interrupts - * at selected, safe opportunities. - */ - pqsignal(SIGTERM, startup_die); - pqsignal(SIGQUIT, startup_die); + * We arrange to do _exit(1) if we receive SIGTERM or timeout while trying + * to collect the startup packet; while SIGQUIT results in _exit(2). + * Otherwise the postmaster cannot shutdown the database FAST or IMMED + * cleanly if a buggy client fails to send the packet promptly. + * + * Exiting with _exit(1) is only possible because we have not yet touched + * shared memory; therefore no outside-the-process state needs to get + * cleaned up. + */ + pqsignal(SIGTERM, process_startup_packet_die); + /* SIGQUIT handler was already set up by InitPostmasterChild */ InitializeTimeouts(); /* establishes SIGALRM handler */ PG_SETMASK(&StartupBlockSig); @@ -4925,8 +4943,8 @@ BackendInitialize(Port *port) port->remote_hostname = strdup(remote_host); /* - * Ready to begin client interaction. We will give up and exit(1) after a - * time delay, so that a broken client can't hog a connection + * Ready to begin client interaction. We will give up and _exit(1) after + * a time delay, so that a broken client can't hog a connection * indefinitely. PreAuthDelay and any DNS interactions above don't count * against the time limit. * @@ -4948,6 +4966,23 @@ BackendInitialize(Port *port) */ status = ProcessStartupPacket(port, false, false); + /* + * Disable the timeout, and prevent SIGTERM again. + */ + disable_timeout(STARTUP_PACKET_TIMEOUT, false); + PG_SETMASK(&BlockSig); + + /* + * As a safety check that nothing in startup has yet performed + * shared-memory modifications that would need to be undone if we had + * exited through SIGTERM or timeout above, check that no on_shmem_exit + * handlers have been registered yet. (This isn't terribly bulletproof, + * since someone might misuse an on_proc_exit handler for shmem cleanup, + * but it's a cheap and helpful check. We cannot disallow on_proc_exit + * handlers unfortunately, since pq_init() already registered one.) + */ + check_on_shmem_exit_lists_are_empty(); + /* * Stop here if it was bad or a cancel packet. ProcessStartupPacket * already did any appropriate error reporting. @@ -4979,12 +5014,6 @@ BackendInitialize(Port *port) pfree(ps_data.data); set_ps_display("initializing"); - - /* - * Disable the timeout, and prevent SIGTERM/SIGQUIT again. - */ - disable_timeout(STARTUP_PACKET_TIMEOUT, false); - PG_SETMASK(&BlockSig); } @@ -4992,54 +5021,16 @@ BackendInitialize(Port *port) * BackendRun -- set up the backend's argument list and invoke PostgresMain() * * returns: - * Shouldn't return at all. - * If PostgresMain() fails, return status. + * Doesn't return at all. */ static void BackendRun(Port *port) { - char **av; - int maxac; - int ac; - int i; - - /* - * Now, build the argv vector that will be given to PostgresMain. - * - * The maximum possible number of commandline arguments that could come - * from ExtraOptions is (strlen(ExtraOptions) + 1) / 2; see - * pg_split_opts(). - */ - maxac = 2; /* for fixed args supplied below */ - maxac += (strlen(ExtraOptions) + 1) / 2; - - av = (char **) MemoryContextAlloc(TopMemoryContext, - maxac * sizeof(char *)); - ac = 0; - - av[ac++] = "postgres"; + char *av[2]; + const int ac = 1; - /* - * Pass any backend switches specified with -o on the postmaster's own - * command line. We assume these are secure. - */ - pg_split_opts(av, &ac, ExtraOptions); - - av[ac] = NULL; - - Assert(ac < maxac); - - /* - * Debug: print arguments being passed to backend - */ - ereport(DEBUG3, - (errmsg_internal("%s child[%d]: starting with (", - progname, (int) getpid()))); - for (i = 0; i < ac; ++i) - ereport(DEBUG3, - (errmsg_internal("\t%s", av[i]))); - ereport(DEBUG3, - (errmsg_internal(")"))); + av[0] = "postgres"; + av[1] = NULL; /* * Make sure we aren't in PostmasterContext anymore. (We can't delete it @@ -5236,16 +5227,18 @@ internal_forkexec(int argc, char *argv[], Port *port) NULL); if (paramHandle == INVALID_HANDLE_VALUE) { - elog(LOG, "could not create backend parameter file mapping: error code %lu", - GetLastError()); + ereport(LOG, + (errmsg("could not create backend parameter file mapping: error code %lu", + GetLastError()))); return -1; } param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, sizeof(BackendParameters)); if (!param) { - elog(LOG, "could not map backend parameter memory: error code %lu", - GetLastError()); + ereport(LOG, + (errmsg("could not map backend parameter memory: error code %lu", + GetLastError()))); CloseHandle(paramHandle); return -1; } @@ -5270,7 +5263,8 @@ internal_forkexec(int argc, char *argv[], Port *port) } if (cmdLine[sizeof(cmdLine) - 2] != '\0') { - elog(LOG, "subprocess command line too long"); + ereport(LOG, + (errmsg("subprocess command line too long"))); UnmapViewOfFile(param); CloseHandle(paramHandle); return -1; @@ -5287,8 +5281,9 @@ internal_forkexec(int argc, char *argv[], Port *port) if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { - elog(LOG, "CreateProcess call failed: %m (error code %lu)", - GetLastError()); + ereport(LOG, + (errmsg("CreateProcess() call failed: %m (error code %lu)", + GetLastError()))); UnmapViewOfFile(param); CloseHandle(paramHandle); return -1; @@ -5313,11 +5308,13 @@ internal_forkexec(int argc, char *argv[], Port *port) /* Drop the parameter shared memory that is now inherited to the backend */ if (!UnmapViewOfFile(param)) - elog(LOG, "could not unmap view of backend parameter file: error code %lu", - GetLastError()); + ereport(LOG, + (errmsg("could not unmap view of backend parameter file: error code %lu", + GetLastError()))); if (!CloseHandle(paramHandle)) - elog(LOG, "could not close handle to backend parameter file: error code %lu", - GetLastError()); + ereport(LOG, + (errmsg("could not close handle to backend parameter file: error code %lu", + GetLastError()))); /* * Reserve the memory region used by our main shared memory segment before @@ -5448,18 +5445,6 @@ SubPostmasterMain(int argc, char *argv[]) /* Setup as postmaster child */ InitPostmasterChild(); - /* - * Set up memory area for GSS information. Mirrors the code in ConnCreate - * for the non-exec case. - */ -#if defined(ENABLE_GSS) || defined(ENABLE_SSPI) - port.gss = (pg_gssinfo *) calloc(1, sizeof(pg_gssinfo)); - if (!port.gss) - ereport(FATAL, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); -#endif - /* * If appropriate, physically re-attach to shared memory segment. We want * to do this before going any further to ensure that we can attach at the @@ -5493,10 +5478,6 @@ SubPostmasterMain(int argc, char *argv[]) if (strcmp(argv[1], "--forkavworker") == 0) AutovacuumWorkerIAm(); - /* In EXEC_BACKEND case we will not have inherited these settings */ - pqinitmask(); - PG_SETMASK(&BlockSig); - /* Read in remaining GUC variables */ read_nondefault_variables(); @@ -5641,12 +5622,6 @@ SubPostmasterMain(int argc, char *argv[]) StartBackgroundWorker(); } - if (strcmp(argv[1], "--forkarch") == 0) - { - /* Do not want to attach to shared memory */ - - PgArchiverMain(argc, argv); /* does not return */ - } if (strcmp(argv[1], "--forkcol") == 0) { /* Do not want to attach to shared memory */ @@ -5716,13 +5691,6 @@ sigusr1_handler(SIGNAL_ARGS) PG_SETMASK(&BlockSig); #endif - /* Process background worker state change. */ - if (CheckPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE)) - { - BackgroundWorkerStateChange(); - StartWorkerNeeded = true; - } - /* * RECOVERY_STARTED and BEGIN_HOT_STANDBY signals are ignored in * unexpected states. If the startup process quickly starts up, completes @@ -5753,7 +5721,7 @@ sigusr1_handler(SIGNAL_ARGS) */ Assert(PgArchPID == 0); if (XLogArchivingAlways()) - PgArchPID = pgarch_start(); + PgArchPID = StartArchiver(); /* * GPDB: if promote trigger file exist we don't wish to convey @@ -5795,6 +5763,7 @@ sigusr1_handler(SIGNAL_ARGS) pmState = PM_RECOVERY; } + if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) && pmState == PM_RECOVERY && Shutdown == NoShutdown) { @@ -5820,19 +5789,17 @@ sigusr1_handler(SIGNAL_ARGS) StartWorkerNeeded = true; } - if (StartWorkerNeeded || HaveCrashedWorker) - maybe_start_bgworkers(); - - if (CheckPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER) && - PgArchPID != 0) + /* Process background worker state changes. */ + if (CheckPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE)) { - /* - * Send SIGUSR1 to archiver process, to wake it up and begin archiving - * next WAL file. - */ - signal_child(PgArchPID, SIGUSR1); + /* Accept new worker requests only if not stopping. */ + BackgroundWorkerStateChange(pmState < PM_STOP_BACKENDS); + StartWorkerNeeded = true; } + if (StartWorkerNeeded || HaveCrashedWorker) + maybe_start_bgworkers(); + /* Tell syslogger to rotate logfile if requested */ if (SysLoggerPID != 0) { @@ -5930,18 +5897,22 @@ sigusr1_handler(SIGNAL_ARGS) } /* - * SIGTERM or SIGQUIT while processing startup packet. - * Clean up and exit(1). + * SIGTERM while processing startup packet. + * + * Running proc_exit() from a signal handler would be quite unsafe. + * However, since we have not yet touched shared memory, we can just + * pull the plug and exit without running any atexit handlers. * - * XXX: possible future improvement: try to send a message indicating - * why we are disconnecting. Problem is to be sure we don't block while - * doing so, nor mess up SSL initialization. In practice, if the client - * has wedged here, it probably couldn't do anything with the message anyway. + * One might be tempted to try to send a message, or log one, indicating + * why we are disconnecting. However, that would be quite unsafe in itself. + * Also, it seems undesirable to provide clues about the database's state + * to a client that has not yet completed authentication, or even sent us + * a startup packet. */ static void -startup_die(SIGNAL_ARGS) +process_startup_packet_die(SIGNAL_ARGS) { - proc_exit(1); + _exit(1); } /* @@ -5960,12 +5931,12 @@ dummy_handler(SIGNAL_ARGS) /* * Timeout while processing startup packet. - * As for startup_die(), we clean up and exit(1). + * As for process_startup_packet_die(), we exit via _exit(1). */ static void StartupPacketTimeoutHandler(void) { - proc_exit(1); + _exit(1); } @@ -6069,8 +6040,7 @@ StartChildProcess(AuxProcType type) MemoryContextDelete(PostmasterContext); PostmasterContext = NULL; - AuxiliaryProcessMain(ac, av); - ExitPostmaster(0); + AuxiliaryProcessMain(ac, av); /* does not return */ } #endif /* EXEC_BACKEND */ @@ -6086,6 +6056,10 @@ StartChildProcess(AuxProcType type) ereport(LOG, (errmsg("could not fork startup process: %m"))); break; + case ArchiverProcess: + ereport(LOG, + (errmsg("could not fork archiver process: %m"))); + break; case BgWriterProcess: ereport(LOG, (errmsg("could not fork background writer process: %m"))); @@ -6257,7 +6231,9 @@ CreateOptsFile(int argc, char *argv[], char *fullprogname) if ((fp = fopen(OPTS_FILE, "w")) == NULL) { - elog(LOG, "could not create file \"%s\": %m", OPTS_FILE); + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not create file \"%s\": %m", OPTS_FILE))); return false; } @@ -6268,7 +6244,9 @@ CreateOptsFile(int argc, char *argv[], char *fullprogname) if (fclose(fp)) { - elog(LOG, "could not write file \"%s\": %m", OPTS_FILE); + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not write file \"%s\": %m", OPTS_FILE))); return false; } @@ -6409,8 +6387,8 @@ do_start_bgworker(RegisteredBgWorker *rw) } ereport(DEBUG1, - (errmsg("starting background worker process \"%s\"", - rw->rw_worker.bgw_name))); + (errmsg_internal("starting background worker process \"%s\"", + rw->rw_worker.bgw_name))); #ifdef EXEC_BACKEND switch ((worker_pid = bgworker_forkexec(rw->rw_shmem_slot))) @@ -6829,6 +6807,7 @@ save_backend_variables(BackendParameters *param, Port *port, param->redirection_done = redirection_done; param->IsBinaryUpgrade = IsBinaryUpgrade; param->ConvertMasterDataDirToSegment = ConvertMasterDataDirToSegment; + param->query_id_enabled = query_id_enabled; param->max_safe_fds = max_safe_fds; param->MaxBackends = MaxBackends; @@ -6850,8 +6829,6 @@ save_backend_variables(BackendParameters *param, Port *port, strlcpy(param->pkglib_path, pkglib_path, MAXPGPATH); - strlcpy(param->ExtraOptions, ExtraOptions, MAXPGPATH); - return true; } @@ -7065,6 +7042,7 @@ restore_backend_variables(BackendParameters *param, Port *port) redirection_done = param->redirection_done; IsBinaryUpgrade = param->IsBinaryUpgrade; ConvertMasterDataDirToSegment = param->ConvertMasterDataDirToSegment; + query_id_enabled = param->query_id_enabled; max_safe_fds = param->max_safe_fds; MaxBackends = param->MaxBackends; @@ -7083,8 +7061,6 @@ restore_backend_variables(BackendParameters *param, Port *port) strlcpy(pkglib_path, param->pkglib_path, MAXPGPATH); - strlcpy(ExtraOptions, param->ExtraOptions, MAXPGPATH); - /* * We need to restore fd.c's counts of externally-opened FDs; to avoid * confusion, be sure to do this after restoring max_safe_fds. (Note: diff --git a/src/backend/postmaster/startup.c b/src/backend/postmaster/startup.c index 24fb076ec0ec..050561b2bf83 100644 --- a/src/backend/postmaster/startup.c +++ b/src/backend/postmaster/startup.c @@ -9,7 +9,7 @@ * though.) * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -35,6 +35,17 @@ bool am_startup = false; +#ifndef USE_POSTMASTER_DEATH_SIGNAL +/* + * On systems that need to make a system call to find out if the postmaster has + * gone away, we'll do so only every Nth call to HandleStartupProcInterrupts(). + * This only affects how long it takes us to detect the condition while we're + * busy replaying WAL. Latch waits and similar which should react immediately + * through the usual techniques. + */ +#define POSTMASTER_POLL_RATE_LIMIT 1024 +#endif + /* * Flags set by interrupt handlers for later service in the redo loop. */ @@ -52,6 +63,9 @@ static volatile sig_atomic_t in_restore_command = false; static void StartupProcTriggerHandler(SIGNAL_ARGS); static void StartupProcSigHupHandler(SIGNAL_ARGS); +/* Callbacks */ +static void StartupProcExit(int code, Datum arg); + /* -------------------------------- * signal handler routines @@ -135,6 +149,10 @@ StartupRereadConfig(void) void HandleStartupProcInterrupts(void) { +#ifdef POSTMASTER_POLL_RATE_LIMIT + static uint32 postmaster_poll_count = 0; +#endif + /* * Process any requests or signals received recently. */ @@ -152,9 +170,15 @@ HandleStartupProcInterrupts(void) /* * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. + * necessity for manual cleanup of all postmaster children. Do this less + * frequently on systems for which we don't have signals to make that + * cheap. */ - if (IsUnderPostmaster && !PostmasterIsAlive()) + if (IsUnderPostmaster && +#ifdef POSTMASTER_POLL_RATE_LIMIT + postmaster_poll_count++ % POSTMASTER_POLL_RATE_LIMIT == 0 && +#endif + !PostmasterIsAlive()) exit(1); /* Process barrier events */ @@ -175,6 +199,19 @@ HandleCrash(SIGNAL_ARGS) } +/* -------------------------------- + * signal handler routines + * -------------------------------- + */ +static void +StartupProcExit(int code, Datum arg) +{ + /* Shutdown the recovery environment */ + if (standbyState != STANDBY_DISABLED) + ShutdownRecoveryTransactionEnvironment(); +} + + /* ---------------------------------- * Startup Process main entry point * ---------------------------------- @@ -183,13 +220,16 @@ void StartupProcessMain(void) { am_startup = true; + /* Arrange to clean up at startup process exit */ + on_shmem_exit(StartupProcExit, 0); + /* * Properly accept or ignore signals the postmaster might send us. */ pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */ pqsignal(SIGINT, SIG_IGN); /* ignore query cancel */ pqsignal(SIGTERM, StartupProcShutdownHandler); /* request shutdown */ - pqsignal(SIGQUIT, SignalHandlerForCrashExit); + /* SIGQUIT handler was already set up by InitPostmasterChild */ InitializeTimeouts(); /* establishes SIGALRM handler */ pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index ef0c1a3cc133..6acb5d5bcd68 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -13,7 +13,7 @@ * * Author: Andreas Pflug * - * Copyright (c) 2004-2020, PostgreSQL Global Development Group + * Copyright (c) 2004-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -39,6 +39,7 @@ #include "pgstat.h" #include "pgtime.h" #include "postmaster/fork_process.h" +#include "postmaster/interrupt.h" #include "postmaster/postmaster.h" #include "postmaster/syslogger.h" #include "storage/dsm.h" @@ -146,7 +147,6 @@ static void syslogger_flush_chunks(void); /* * Flags set by interrupt handlers for later service in the main loop. */ -static volatile sig_atomic_t got_SIGHUP = false; static volatile sig_atomic_t rotation_requested = false; @@ -171,7 +171,6 @@ static bool logfile_rotate(bool time_based_rotation, bool size_based_rotation, c FILE **fh, char **last_log_file_name); static char *logfile_getname(pg_time_t timestamp, const char *suffix, const char *log_directory, const char *log_file_pattern); static void set_next_rotation_time(void); -static void sigHupHandler(SIGNAL_ARGS); static void sigUsr1Handler(SIGNAL_ARGS); static void update_metainfo_datafile(void); @@ -339,7 +338,8 @@ SysLoggerMain(int argc, char *argv[]) * broken backends... */ - pqsignal(SIGHUP, sigHupHandler); /* set flag to read config file */ + pqsignal(SIGHUP, SignalHandlerForConfigReload); /* set flag to read config + * file */ pqsignal(SIGINT, SIG_IGN); pqsignal(SIGTERM, SIG_IGN); pqsignal(SIGQUIT, SIG_IGN); @@ -433,9 +433,9 @@ SysLoggerMain(int argc, char *argv[]) /* * Process any requests or signals received recently. */ - if (got_SIGHUP) + if (ConfigReloadPending) { - got_SIGHUP = false; + ConfigReloadPending = false; ProcessConfigFile(PGC_SIGHUP); /* @@ -774,7 +774,7 @@ SysLoggerMain(int argc, char *argv[]) * it DEBUG1 to suppress in normal use. */ ereport(DEBUG1, - (errmsg("logger shutting down"))); + (errmsg_internal("logger shutting down"))); /* * Normal exit from the syslogger is here. Note that we @@ -2598,18 +2598,6 @@ RemoveLogrotateSignalFiles(void) unlink(LOGROTATE_SIGNAL_FILE); } -/* SIGHUP: set flag to reload config file */ -static void -sigHupHandler(SIGNAL_ARGS) -{ - int save_errno = errno; - - got_SIGHUP = true; - SetLatch(MyLatch); - - errno = save_errno; -} - /* SIGUSR1: set flag to rotate logfile */ static void sigUsr1Handler(SIGNAL_ARGS) diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c index 45a2757969be..626fae8454ca 100644 --- a/src/backend/postmaster/walwriter.c +++ b/src/backend/postmaster/walwriter.c @@ -31,7 +31,7 @@ * should be killed by SIGQUIT and then a recovery cycle started. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -78,6 +78,9 @@ int WalWriterFlushAfter = 128; #define LOOPS_UNTIL_HIBERNATE 50 #define HIBERNATE_FACTOR 25 +/* Prototypes for private functions */ +static void HandleWalWriterInterrupts(void); + /* * Main entry point for walwriter process * @@ -101,7 +104,7 @@ WalWriterMain(void) pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, SignalHandlerForShutdownRequest); pqsignal(SIGTERM, SignalHandlerForShutdownRequest); - pqsignal(SIGQUIT, SignalHandlerForCrashExit); + /* SIGQUIT handler was already set up by InitPostmasterChild */ pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); @@ -112,9 +115,6 @@ WalWriterMain(void) */ pqsignal(SIGCHLD, SIG_DFL); - /* We allow SIGQUIT (quickdie) at all times */ - sigdelset(&BlockSig, SIGQUIT); - /* * Create a memory context that we will do all our work in. We do this so * that we can reset the context during error recovery and thereby avoid @@ -129,7 +129,20 @@ WalWriterMain(void) /* * If an exception is encountered, processing resumes here. * - * This code is heavily based on bgwriter.c, q.v. + * You might wonder why this isn't coded as an infinite loop around a + * PG_TRY construct. The reason is that this is the bottom of the + * exception stack, and so with PG_TRY there would be no exception handler + * in force at all during the CATCH part. By leaving the outermost setjmp + * always active, we have at least some chance of recovering from an error + * during error recovery. (If we get into an infinite loop thereby, it + * will soon be stopped by overflow of elog.c's internal state stack.) + * + * Note that we use sigsetjmp(..., 1), so that the prevailing signal mask + * (to wit, BlockSig) will be restored when longjmp'ing to here. Thus, + * signals other than SIGQUIT will be blocked until we complete error + * recovery. It might seem that this policy makes the HOLD_INTERRUPTS() + * call redundant, but it is not since InterruptPending might be set + * already. */ if (sigsetjmp(local_sigjmp_buf, 1) != 0) { @@ -232,7 +245,8 @@ WalWriterMain(void) /* Clear any already-pending wakeups */ ResetLatch(MyLatch); - HandleMainLoopInterrupts(); + /* Process any signals received recently */ + HandleWalWriterInterrupts(); /* * Do what we're here for; then, if XLogBackgroundFlush() found useful @@ -243,6 +257,9 @@ WalWriterMain(void) else if (left_till_hibernate > 0) left_till_hibernate--; + /* Send WAL statistics to the stats collector */ + pgstat_send_wal(false); + /* * Sleep until we are signaled or WalWriterDelay has elapsed. If we * haven't done anything useful for quite some time, lengthen the @@ -259,3 +276,34 @@ WalWriterMain(void) WAIT_EVENT_WAL_WRITER_MAIN); } } + +/* + * Interrupt handler for main loops of WAL writer process. + */ +static void +HandleWalWriterInterrupts(void) +{ + if (ProcSignalBarrierPending) + ProcessProcSignalBarrier(); + + if (ConfigReloadPending) + { + ConfigReloadPending = false; + ProcessConfigFile(PGC_SIGHUP); + } + + if (ShutdownRequestPending) + { + /* + * Force to send remaining WAL statistics to the stats collector at + * process exit. + * + * Since pgstat_send_wal is invoked with 'force' is false in main loop + * to avoid overloading to the stats collector, there may exist unsent + * stats counters for the WAL writer. + */ + pgstat_send_wal(true); + + proc_exit(0); + } +} diff --git a/src/backend/regex/README b/src/backend/regex/README index f08aab69e376..e4b083664f21 100644 --- a/src/backend/regex/README +++ b/src/backend/regex/README @@ -129,9 +129,9 @@ If not, we can reject the match immediately without iterating through many possibilities. As an example, consider the regex "(a[bc]+)\1". The compiled -representation will have a top-level concatenation subre node. Its left -child is a capture node, and the child of that is a plain DFA node for -"a[bc]+". The concatenation's right child is a backref node for \1. +representation will have a top-level concatenation subre node. Its first +child is a plain DFA node for "a[bc]+" (which is marked as being a capture +node). The concatenation's second child is a backref node for \1. The DFA associated with the concatenation node will be "a[bc]+a[bc]+", where the backref has been replaced by a copy of the DFA for its referent expression. When executed, the concatenation node will have to search for @@ -147,6 +147,17 @@ run much faster than a pure NFA engine could do. It is this behavior that justifies using the phrase "hybrid DFA/NFA engine" to describe Spencer's library. +It's perhaps worth noting that separate capture subre nodes are a rarity: +normally, we just mark a subre as capturing and that's it. However, it's +legal to write a regex like "((x))" in which the same substring has to be +captured by multiple sets of parentheses. Since a subre has room for only +one "capno" field, a single subre can't handle that. We handle such cases +by wrapping the base subre (which captures the innermost parens) in a +no-op capture node, or even more than one for "(((x)))" etc. This is a +little bit inefficient because we end up with multiple identical NFAs, +but since the case is pointless and infrequent, it's not worth working +harder. + Colors and colormapping ----------------------- @@ -261,6 +272,18 @@ and the NFA has these arcs: states 4 -> 5 on color 2 ("x" only) which can be seen to be a correct representation of the regex. +There is one more complexity, which is how to handle ".", that is a +match-anything atom. We used to do that by generating a "rainbow" +of arcs of all live colors between the two NFA states before and after +the dot. That's expensive in itself when there are lots of colors, +and it also typically adds lots of follow-on arc-splitting work for the +color splitting logic. Now we handle this case by generating a single arc +labeled with the special color RAINBOW, meaning all colors. Such arcs +never need to be split, so they help keep NFAs small in this common case. +(Note: this optimization doesn't help in REG_NLSTOP mode, where "." is +not supposed to match newline. In that case we still handle "." by +generating an almost-rainbow of all colors except newline's color.) + Given this summary, we can see we need the following operations for colors: @@ -349,6 +372,8 @@ The possible arc types are: PLAIN arcs, which specify matching of any character of a given "color" (see above). These are dumped as "[color_number]->to_state". + In addition there can be "rainbow" PLAIN arcs, which are dumped as + "[*]->to_state". EMPTY arcs, which specify a no-op transition to another state. These are dumped as "->to_state". @@ -356,11 +381,11 @@ The possible arc types are: AHEAD constraints, which represent a "next character must be of this color" constraint. AHEAD differs from a PLAIN arc in that the input character is not consumed when crossing the arc. These are dumped as - ">color_number>->to_state". + ">color_number>->to_state", or possibly ">*>->to_state". BEHIND constraints, which represent a "previous character must be of this color" constraint, which likewise consumes no input. These are - dumped as "to_state". + dumped as "to_state", or possibly "<*<->to_state". '^' arcs, which specify a beginning-of-input constraint. These are dumped as "^0->to_state" or "^1->to_state" for beginning-of-string and @@ -396,14 +421,20 @@ substring, or an imaginary following EOS character if the substring is at the end of the input. 3. If the NFA is (or can be) in the goal state at this point, it matches. +This definition is necessary to support regexes that begin or end with +constraints such as \m and \M, which imply requirements on the adjacent +character if any. The executor implements that by checking if the +adjacent character (or BOS/BOL/EOS/EOL pseudo-character) is of the +right color, and it does that in the same loop that checks characters +within the match. + So one can mentally execute an untransformed NFA by taking ^ and $ as ordinary constraints that match at start and end of input; but plain arcs out of the start state should be taken as matches for the character before the target substring, and similarly, plain arcs leading to the post state are matches for the character after the target substring. -This definition is necessary to support regexes that begin or end with -constraints such as \m and \M, which imply requirements on the adjacent -character if any. NFAs for simple unanchored patterns will usually have -pre-state outarcs for all possible character colors as well as BOS and -BOL, and post-state inarcs for all possible character colors as well as -EOS and EOL, so that the executor's behavior will work. +After the optimize() transformation, there are explicit arcs mentioning +BOS/BOL/EOS/EOL adjacent to the pre-state and post-state. So a finished +NFA for a pattern without anchors or adjacent-character constraints will +have pre-state outarcs for RAINBOW (all possible character colors) as well +as BOS and BOL, and likewise post-state inarcs for RAINBOW, EOS, and EOL. diff --git a/src/backend/regex/re_syntax.n b/src/backend/regex/re_syntax.n deleted file mode 100644 index 4621bfc25f46..000000000000 --- a/src/backend/regex/re_syntax.n +++ /dev/null @@ -1,979 +0,0 @@ -'\" -'\" Copyright (c) 1998 Sun Microsystems, Inc. -'\" Copyright (c) 1999 Scriptics Corporation -'\" -'\" This software is copyrighted by the Regents of the University of -'\" California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState -'\" Corporation and other parties. The following terms apply to all files -'\" associated with the software unless explicitly disclaimed in -'\" individual files. -'\" -'\" The authors hereby grant permission to use, copy, modify, distribute, -'\" and license this software and its documentation for any purpose, provided -'\" that existing copyright notices are retained in all copies and that this -'\" notice is included verbatim in any distributions. No written agreement, -'\" license, or royalty fee is required for any of the authorized uses. -'\" Modifications to this software may be copyrighted by their authors -'\" and need not follow the licensing terms described here, provided that -'\" the new terms are clearly indicated on the first page of each file where -'\" they apply. -'\" -'\" IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -'\" FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -'\" ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -'\" DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -'\" POSSIBILITY OF SUCH DAMAGE. -'\" -'\" THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -'\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -'\" FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -'\" IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -'\" NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -'\" MODIFICATIONS. -'\" -'\" GOVERNMENT USE: If you are acquiring this software on behalf of the -'\" U.S. government, the Government shall have only "Restricted Rights" -'\" in the software and related documentation as defined in the Federal -'\" Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -'\" are acquiring the software on behalf of the Department of Defense, the -'\" software shall be classified as "Commercial Computer Software" and the -'\" Government shall have only "Restricted Rights" as defined in Clause -'\" 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the -'\" authors grant the U.S. Government and others acting in its behalf -'\" permission to use and distribute the software in accordance with the -'\" terms specified in this license. -'\" -'\" RCS: @(#) Id: re_syntax.n,v 1.3 1999/07/14 19:09:36 jpeek Exp -'\" -.so man.macros -.TH re_syntax n "8.1" Tcl "Tcl Built-In Commands" -.BS -.SH NAME -re_syntax \- Syntax of Tcl regular expressions. -.BE - -.SH DESCRIPTION -.PP -A \fIregular expression\fR describes strings of characters. -It's a pattern that matches certain strings and doesn't match others. - -.SH "DIFFERENT FLAVORS OF REs" -Regular expressions (``RE''s), as defined by POSIX, come in two -flavors: \fIextended\fR REs (``EREs'') and \fIbasic\fR REs (``BREs''). -EREs are roughly those of the traditional \fIegrep\fR, while BREs are -roughly those of the traditional \fIed\fR. This implementation adds -a third flavor, \fIadvanced\fR REs (``AREs''), basically EREs with -some significant extensions. -.PP -This manual page primarily describes AREs. BREs mostly exist for -backward compatibility in some old programs; they will be discussed at -the end. POSIX EREs are almost an exact subset of AREs. Features of -AREs that are not present in EREs will be indicated. - -.SH "REGULAR EXPRESSION SYNTAX" -.PP -Tcl regular expressions are implemented using the package written by -Henry Spencer, based on the 1003.2 spec and some (not quite all) of -the Perl5 extensions (thanks, Henry!). Much of the description of -regular expressions below is copied verbatim from his manual entry. -.PP -An ARE is one or more \fIbranches\fR, -separated by `\fB|\fR', -matching anything that matches any of the branches. -.PP -A branch is zero or more \fIconstraints\fR or \fIquantified atoms\fR, -concatenated. -It matches a match for the first, followed by a match for the second, etc; -an empty branch matches the empty string. -.PP -A quantified atom is an \fIatom\fR possibly followed -by a single \fIquantifier\fR. -Without a quantifier, it matches a match for the atom. -The quantifiers, -and what a so-quantified atom matches, are: -.RS 2 -.TP 6 -\fB*\fR -a sequence of 0 or more matches of the atom -.TP -\fB+\fR -a sequence of 1 or more matches of the atom -.TP -\fB?\fR -a sequence of 0 or 1 matches of the atom -.TP -\fB{\fIm\fB}\fR -a sequence of exactly \fIm\fR matches of the atom -.TP -\fB{\fIm\fB,}\fR -a sequence of \fIm\fR or more matches of the atom -.TP -\fB{\fIm\fB,\fIn\fB}\fR -a sequence of \fIm\fR through \fIn\fR (inclusive) matches of the atom; -\fIm\fR may not exceed \fIn\fR -.TP -\fB*? +? ?? {\fIm\fB}? {\fIm\fB,}? {\fIm\fB,\fIn\fB}?\fR -\fInon-greedy\fR quantifiers, -which match the same possibilities, -but prefer the smallest number rather than the largest number -of matches (see MATCHING) -.RE -.PP -The forms using -\fB{\fR and \fB}\fR -are known as \fIbound\fRs. -The numbers -\fIm\fR and \fIn\fR are unsigned decimal integers -with permissible values from 0 to 255 inclusive. -.PP -An atom is one of: -.RS 2 -.TP 6 -\fB(\fIre\fB)\fR -(where \fIre\fR is any regular expression) -matches a match for -\fIre\fR, with the match noted for possible reporting -.TP -\fB(?:\fIre\fB)\fR -as previous, -but does no reporting -(a ``non-capturing'' set of parentheses) -.TP -\fB()\fR -matches an empty string, -noted for possible reporting -.TP -\fB(?:)\fR -matches an empty string, -without reporting -.TP -\fB[\fIchars\fB]\fR -a \fIbracket expression\fR, -matching any one of the \fIchars\fR (see BRACKET EXPRESSIONS for more detail) -.TP - \fB.\fR -matches any single character -.TP -\fB\e\fIk\fR -(where \fIk\fR is a non-alphanumeric character) -matches that character taken as an ordinary character, -e.g. \e\e matches a backslash character -.TP -\fB\e\fIc\fR -where \fIc\fR is alphanumeric -(possibly followed by other characters), -an \fIescape\fR (AREs only), -see ESCAPES below -.TP -\fB{\fR -when followed by a character other than a digit, -matches the left-brace character `\fB{\fR'; -when followed by a digit, it is the beginning of a -\fIbound\fR (see above) -.TP -\fIx\fR -where \fIx\fR is -a single character with no other significance, matches that character. -.RE -.PP -A \fIconstraint\fR matches an empty string when specific conditions -are met. -A constraint may not be followed by a quantifier. -The simple constraints are as follows; some more constraints are -described later, under ESCAPES. -.RS 2 -.TP 8 -\fB^\fR -matches at the beginning of a line -.TP -\fB$\fR -matches at the end of a line -.TP -\fB(?=\fIre\fB)\fR -\fIpositive lookahead\fR (AREs only), matches at any point -where a substring matching \fIre\fR begins -.TP -\fB(?!\fIre\fB)\fR -\fInegative lookahead\fR (AREs only), matches at any point -where no substring matching \fIre\fR begins -.TP -\fB(?<=\fIre\fB)\fR -\fIpositive lookbehind\fR (AREs only), matches at any point -where a substring matching \fIre\fR ends -.TP -\fB(?:]]\fR -are constraints, matching empty strings at -the beginning and end of a word respectively. -'\" note, discussion of escapes below references this definition of word -A word is defined as a sequence of -word characters -that is neither preceded nor followed by -word characters. -A word character is an -\fIalnum\fR -character -or an underscore -(\fB_\fR). -These special bracket expressions are deprecated; -users of AREs should use constraint escapes instead (see below). -.SH ESCAPES -Escapes (AREs only), which begin with a -\fB\e\fR -followed by an alphanumeric character, -come in several varieties: -character entry, class shorthands, constraint escapes, and back references. -A -\fB\e\fR -followed by an alphanumeric character but not constituting -a valid escape is illegal in AREs. -In EREs, there are no escapes: -outside a bracket expression, -a -\fB\e\fR -followed by an alphanumeric character merely stands for that -character as an ordinary character, -and inside a bracket expression, -\fB\e\fR -is an ordinary character. -(The latter is the one actual incompatibility between EREs and AREs.) -.PP -Character-entry escapes (AREs only) exist to make it easier to specify -non-printing and otherwise inconvenient characters in REs: -.RS 2 -.TP 5 -\fB\ea\fR -alert (bell) character, as in C -.TP -\fB\eb\fR -backspace, as in C -.TP -\fB\eB\fR -synonym for -\fB\e\fR -to help reduce backslash doubling in some -applications where there are multiple levels of backslash processing -.TP -\fB\ec\fIX\fR -(where X is any character) the character whose -low-order 5 bits are the same as those of -\fIX\fR, -and whose other bits are all zero -.TP -\fB\ee\fR -the character whose collating-sequence name -is `\fBESC\fR', -or failing that, the character with octal value 033 -.TP -\fB\ef\fR -formfeed, as in C -.TP -\fB\en\fR -newline, as in C -.TP -\fB\er\fR -carriage return, as in C -.TP -\fB\et\fR -horizontal tab, as in C -.TP -\fB\eu\fIwxyz\fR -(where -\fIwxyz\fR -is exactly four hexadecimal digits) -the Unicode character -\fBU+\fIwxyz\fR -in the local byte ordering -.TP -\fB\eU\fIstuvwxyz\fR -(where -\fIstuvwxyz\fR -is exactly eight hexadecimal digits) -reserved for a somewhat-hypothetical Unicode extension to 32 bits -.TP -\fB\ev\fR -vertical tab, as in C -are all available. -.TP -\fB\ex\fIhhh\fR -(where -\fIhhh\fR -is any sequence of hexadecimal digits) -the character whose hexadecimal value is -\fB0x\fIhhh\fR -(a single character no matter how many hexadecimal digits are used). -.TP -\fB\e0\fR -the character whose value is -\fB0\fR -.TP -\fB\e\fIxy\fR -(where -\fIxy\fR -is exactly two octal digits, -and is not a -\fIback reference\fR (see below)) -the character whose octal value is -\fB0\fIxy\fR -.TP -\fB\e\fIxyz\fR -(where -\fIxyz\fR -is exactly three octal digits, -and is not a -back reference (see below)) -the character whose octal value is -\fB0\fIxyz\fR -.RE -.PP -Hexadecimal digits are `\fB0\fR'-`\fB9\fR', `\fBa\fR'-`\fBf\fR', -and `\fBA\fR'-`\fBF\fR'. -Octal digits are `\fB0\fR'-`\fB7\fR'. -.PP -The character-entry escapes are always taken as ordinary characters. -For example, -\fB\e135\fR -is -\fB]\fR -in ASCII, -but -\fB\e135\fR -does not terminate a bracket expression. -Beware, however, that some applications (e.g., C compilers) interpret -such sequences themselves before the regular-expression package -gets to see them, which may require doubling (quadrupling, etc.) the `\fB\e\fR'. -.PP -Class-shorthand escapes (AREs only) provide shorthands for certain commonly-used -character classes: -.RS 2 -.TP 10 -\fB\ed\fR -\fB[[:digit:]]\fR -.TP -\fB\es\fR -\fB[[:space:]]\fR -.TP -\fB\ew\fR -\fB[[:alnum:]_]\fR -(note underscore) -.TP -\fB\eD\fR -\fB[^[:digit:]]\fR -.TP -\fB\eS\fR -\fB[^[:space:]]\fR -.TP -\fB\eW\fR -\fB[^[:alnum:]_]\fR -(note underscore) -.RE -.PP -Within bracket expressions, `\fB\ed\fR', `\fB\es\fR', -and `\fB\ew\fR'\& -lose their outer brackets, -and `\fB\eD\fR', `\fB\eS\fR', -and `\fB\eW\fR'\& -are illegal. -.VS 8.2 -(So, for example, \fB[a-c\ed]\fR is equivalent to \fB[a-c[:digit:]]\fR. -Also, \fB[a-c\eD]\fR, which is equivalent to \fB[a-c^[:digit:]]\fR, is illegal.) -.VE 8.2 -.PP -A constraint escape (AREs only) is a constraint, -matching the empty string if specific conditions are met, -written as an escape: -.RS 2 -.TP 6 -\fB\eA\fR -matches only at the beginning of the string -(see MATCHING, below, for how this differs from `\fB^\fR') -.TP -\fB\em\fR -matches only at the beginning of a word -.TP -\fB\eM\fR -matches only at the end of a word -.TP -\fB\ey\fR -matches only at the beginning or end of a word -.TP -\fB\eY\fR -matches only at a point that is not the beginning or end of a word -.TP -\fB\eZ\fR -matches only at the end of the string -(see MATCHING, below, for how this differs from `\fB$\fR') -.TP -\fB\e\fIm\fR -(where -\fIm\fR -is a nonzero digit) a \fIback reference\fR, see below -.TP -\fB\e\fImnn\fR -(where -\fIm\fR -is a nonzero digit, and -\fInn\fR -is some more digits, -and the decimal value -\fImnn\fR -is not greater than the number of closing capturing parentheses seen so far) -a \fIback reference\fR, see below -.RE -.PP -A word is defined as in the specification of -\fB[[:<:]]\fR -and -\fB[[:>:]]\fR -above. -Constraint escapes are illegal within bracket expressions. -.PP -A back reference (AREs only) matches the same string matched by the parenthesized -subexpression specified by the number, -so that (e.g.) -\fB([bc])\e1\fR -matches -\fBbb\fR -or -\fBcc\fR -but not `\fBbc\fR'. -The subexpression must entirely precede the back reference in the RE. -Subexpressions are numbered in the order of their leading parentheses. -Non-capturing parentheses do not define subexpressions. -.PP -There is an inherent historical ambiguity between octal character-entry -escapes and back references, which is resolved by heuristics, -as hinted at above. -A leading zero always indicates an octal escape. -A single non-zero digit, not followed by another digit, -is always taken as a back reference. -A multi-digit sequence not starting with a zero is taken as a back -reference if it comes after a suitable subexpression -(i.e. the number is in the legal range for a back reference), -and otherwise is taken as octal. -.SH "METASYNTAX" -In addition to the main syntax described above, there are some special -forms and miscellaneous syntactic facilities available. -.PP -Normally the flavor of RE being used is specified by -application-dependent means. -However, this can be overridden by a \fIdirector\fR. -If an RE of any flavor begins with `\fB***:\fR', -the rest of the RE is an ARE. -If an RE of any flavor begins with `\fB***=\fR', -the rest of the RE is taken to be a literal string, -with all characters considered ordinary characters. -.PP -An ARE may begin with \fIembedded options\fR: -a sequence -\fB(?\fIxyz\fB)\fR -(where -\fIxyz\fR -is one or more alphabetic characters) -specifies options affecting the rest of the RE. -These supplement, and can override, -any options specified by the application. -The available option letters are: -.RS 2 -.TP 3 -\fBb\fR -rest of RE is a BRE -.TP 3 -\fBc\fR -case-sensitive matching (usual default) -.TP 3 -\fBe\fR -rest of RE is an ERE -.TP 3 -\fBi\fR -case-insensitive matching (see MATCHING, below) -.TP 3 -\fBm\fR -historical synonym for -\fBn\fR -.TP 3 -\fBn\fR -newline-sensitive matching (see MATCHING, below) -.TP 3 -\fBp\fR -partial newline-sensitive matching (see MATCHING, below) -.TP 3 -\fBq\fR -rest of RE is a literal (``quoted'') string, all ordinary characters -.TP 3 -\fBs\fR -non-newline-sensitive matching (usual default) -.TP 3 -\fBt\fR -tight syntax (usual default; see below) -.TP 3 -\fBw\fR -inverse partial newline-sensitive (``weird'') matching (see MATCHING, below) -.TP 3 -\fBx\fR -expanded syntax (see below) -.RE -.PP -Embedded options take effect at the -\fB)\fR -terminating the sequence. -They are available only at the start of an ARE, -and may not be used later within it. -.PP -In addition to the usual (\fItight\fR) RE syntax, in which all characters are -significant, there is an \fIexpanded\fR syntax, -available in all flavors of RE -with the \fB-expanded\fR switch, or in AREs with the embedded x option. -In the expanded syntax, -white-space characters are ignored -and all characters between a -\fB#\fR -and the following newline (or the end of the RE) are ignored, -permitting paragraphing and commenting a complex RE. -There are three exceptions to that basic rule: -.RS 2 -.PP -a white-space character or `\fB#\fR' preceded by `\fB\e\fR' is retained -.PP -white space or `\fB#\fR' within a bracket expression is retained -.PP -white space and comments are illegal within multi-character symbols -like the ARE `\fB(?:\fR' or the BRE `\fB\e(\fR' -.RE -.PP -Expanded-syntax white-space characters are blank, tab, newline, and -.VS 8.2 -any character that belongs to the \fIspace\fR character class. -.VE 8.2 -.PP -Finally, in an ARE, -outside bracket expressions, the sequence `\fB(?#\fIttt\fB)\fR' -(where -\fIttt\fR -is any text not containing a `\fB)\fR') -is a comment, -completely ignored. -Again, this is not allowed between the characters of -multi-character symbols like `\fB(?:\fR'. -Such comments are more a historical artifact than a useful facility, -and their use is deprecated; -use the expanded syntax instead. -.PP -\fINone\fR of these metasyntax extensions is available if the application -(or an initial -\fB***=\fR -director) -has specified that the user's input be treated as a literal string -rather than as an RE. -.SH MATCHING -In the event that an RE could match more than one substring of a given -string, -the RE matches the one starting earliest in the string. -If the RE could match more than one substring starting at that point, -its choice is determined by its \fIpreference\fR: -either the longest substring, or the shortest. -.PP -Most atoms, and all constraints, have no preference. -A parenthesized RE has the same preference (possibly none) as the RE. -A quantified atom with quantifier -\fB{\fIm\fB}\fR -or -\fB{\fIm\fB}?\fR -has the same preference (possibly none) as the atom itself. -A quantified atom with other normal quantifiers (including -\fB{\fIm\fB,\fIn\fB}\fR -with -\fIm\fR -equal to -\fIn\fR) -prefers longest match. -A quantified atom with other non-greedy quantifiers (including -\fB{\fIm\fB,\fIn\fB}?\fR -with -\fIm\fR -equal to -\fIn\fR) -prefers shortest match. -A branch has the same preference as the first quantified atom in it -which has a preference. -An RE consisting of two or more branches connected by the -\fB|\fR -operator prefers longest match. -.PP -Subject to the constraints imposed by the rules for matching the whole RE, -subexpressions also match the longest or shortest possible substrings, -based on their preferences, -with subexpressions starting earlier in the RE taking priority over -ones starting later. -Note that outer subexpressions thus take priority over -their component subexpressions. -.PP -Note that the quantifiers -\fB{1,1}\fR -and -\fB{1,1}?\fR -can be used to force longest and shortest preference, respectively, -on a subexpression or a whole RE. -.PP -Match lengths are measured in characters, not collating elements. -An empty string is considered longer than no match at all. -For example, -\fBbb*\fR -matches the three middle characters of `\fBabbbc\fR', -\fB(week|wee)(night|knights)\fR -matches all ten characters of `\fBweeknights\fR', -when -\fB(.*).*\fR -is matched against -\fBabc\fR -the parenthesized subexpression -matches all three characters, and -when -\fB(a*)*\fR -is matched against -\fBbc\fR -both the whole RE and the parenthesized -subexpression match an empty string. -.PP -If case-independent matching is specified, -the effect is much as if all case distinctions had vanished from the -alphabet. -When an alphabetic that exists in multiple cases appears as an -ordinary character outside a bracket expression, it is effectively -transformed into a bracket expression containing both cases, -so that -\fBx\fR -becomes `\fB[xX]\fR'. -When it appears inside a bracket expression, all case counterparts -of it are added to the bracket expression, so that -\fB[x]\fR -becomes -\fB[xX]\fR -and -\fB[^x]\fR -becomes `\fB[^xX]\fR'. -.PP -If newline-sensitive matching is specified, \fB.\fR -and bracket expressions using -\fB^\fR -will never match the newline character -(so that matches will never cross newlines unless the RE -explicitly arranges it) -and -\fB^\fR -and -\fB$\fR -will match the empty string after and before a newline -respectively, in addition to matching at beginning and end of string -respectively. -ARE -\fB\eA\fR -and -\fB\eZ\fR -continue to match beginning or end of string \fIonly\fR. -.PP -If partial newline-sensitive matching is specified, -this affects \fB.\fR -and bracket expressions -as with newline-sensitive matching, but not -\fB^\fR -and `\fB$\fR'. -.PP -If inverse partial newline-sensitive matching is specified, -this affects -\fB^\fR -and -\fB$\fR -as with -newline-sensitive matching, -but not \fB.\fR -and bracket expressions. -This isn't very useful but is provided for symmetry. -.SH "LIMITS AND COMPATIBILITY" -No particular limit is imposed on the length of REs. -Programs intended to be highly portable should not employ REs longer -than 256 bytes, -as a POSIX-compliant implementation can refuse to accept such REs. -.PP -The only feature of AREs that is actually incompatible with -POSIX EREs is that -\fB\e\fR -does not lose its special -significance inside bracket expressions. -All other ARE features use syntax which is illegal or has -undefined or unspecified effects in POSIX EREs; -the -\fB***\fR -syntax of directors likewise is outside the POSIX -syntax for both BREs and EREs. -.PP -Many of the ARE extensions are borrowed from Perl, but some have -been changed to clean them up, and a few Perl extensions are not present. -Incompatibilities of note include `\fB\eb\fR', `\fB\eB\fR', -the lack of special treatment for a trailing newline, -the addition of complemented bracket expressions to the things -affected by newline-sensitive matching, -the restrictions on parentheses and back references in lookahead/lookbehind -constraints, -and the longest/shortest-match (rather than first-match) matching semantics. -.PP -The matching rules for REs containing both normal and non-greedy quantifiers -have changed since early beta-test versions of this package. -(The new rules are much simpler and cleaner, -but don't work as hard at guessing the user's real intentions.) -.PP -Henry Spencer's original 1986 \fIregexp\fR package, -still in widespread use (e.g., in pre-8.1 releases of Tcl), -implemented an early version of today's EREs. -There are four incompatibilities between \fIregexp\fR's near-EREs -(`RREs' for short) and AREs. -In roughly increasing order of significance: -.PP -.RS -In AREs, -\fB\e\fR -followed by an alphanumeric character is either an -escape or an error, -while in RREs, it was just another way of writing the -alphanumeric. -This should not be a problem because there was no reason to write -such a sequence in RREs. -.PP -\fB{\fR -followed by a digit in an ARE is the beginning of a bound, -while in RREs, -\fB{\fR -was always an ordinary character. -Such sequences should be rare, -and will often result in an error because following characters -will not look like a valid bound. -.PP -In AREs, -\fB\e\fR -remains a special character within `\fB[\|]\fR', -so a literal -\fB\e\fR -within -\fB[\|]\fR -must be written `\fB\e\e\fR'. -\fB\e\e\fR -also gives a literal -\fB\e\fR -within -\fB[\|]\fR -in RREs, -but only truly paranoid programmers routinely doubled the backslash. -.PP -AREs report the longest/shortest match for the RE, -rather than the first found in a specified search order. -This may affect some RREs which were written in the expectation that -the first match would be reported. -(The careful crafting of RREs to optimize the search order for fast -matching is obsolete (AREs examine all possible matches -in parallel, and their performance is largely insensitive to their -complexity) but cases where the search order was exploited to deliberately -find a match which was \fInot\fR the longest/shortest will need rewriting.) -.RE - -.SH "BASIC REGULAR EXPRESSIONS" -BREs differ from EREs in several respects. `\fB|\fR', `\fB+\fR', -and -\fB?\fR -are ordinary characters and there is no equivalent -for their functionality. -The delimiters for bounds are -\fB\e{\fR -and `\fB\e}\fR', -with -\fB{\fR -and -\fB}\fR -by themselves ordinary characters. -The parentheses for nested subexpressions are -\fB\e(\fR -and `\fB\e)\fR', -with -\fB(\fR -and -\fB)\fR -by themselves ordinary characters. -\fB^\fR -is an ordinary character except at the beginning of the -RE or the beginning of a parenthesized subexpression, -\fB$\fR -is an ordinary character except at the end of the -RE or the end of a parenthesized subexpression, -and -\fB*\fR -is an ordinary character if it appears at the beginning of the -RE or the beginning of a parenthesized subexpression -(after a possible leading `\fB^\fR'). -Finally, -single-digit back references are available, -and -\fB\e<\fR -and -\fB\e>\fR -are synonyms for -\fB[[:<:]]\fR -and -\fB[[:>:]]\fR -respectively; -no other escapes are available. - -.SH "SEE ALSO" -RegExp(3), regexp(n), regsub(n), lsearch(n), switch(n), text(n) - -.SH KEYWORDS -match, regular expression, string diff --git a/src/backend/regex/regc_color.c b/src/backend/regex/regc_color.c index f5a4151757dd..30bda0e5ad0f 100644 --- a/src/backend/regex/regc_color.c +++ b/src/backend/regex/regc_color.c @@ -936,7 +936,16 @@ okcolors(struct nfa *nfa, } else if (cd->nschrs == 0 && cd->nuchrs == 0) { - /* parent empty, its arcs change color to subcolor */ + /* + * Parent is now empty, so just change all its arcs to the + * subcolor, then free the parent. + * + * It is not obvious that simply relabeling the arcs like this is + * OK; it appears to risk creating duplicate arcs. We are + * basically relying on the assumption that processing of a + * bracket expression can't create arcs of both a color and its + * subcolor between the bracket's endpoints. + */ cd->sub = NOSUB; scd = &cm->cd[sco]; assert(scd->nschrs > 0 || scd->nuchrs > 0); @@ -977,6 +986,7 @@ colorchain(struct colormap *cm, { struct colordesc *cd = &cm->cd[a->co]; + assert(a->co >= 0); if (cd->arcs != NULL) cd->arcs->colorchainRev = a; a->colorchain = cd->arcs; @@ -994,6 +1004,7 @@ uncolorchain(struct colormap *cm, struct colordesc *cd = &cm->cd[a->co]; struct arc *aa = a->colorchainRev; + assert(a->co >= 0); if (aa == NULL) { assert(cd->arcs == a); @@ -1012,6 +1023,9 @@ uncolorchain(struct colormap *cm, /* * rainbow - add arcs of all full colors (but one) between specified states + * + * If there isn't an exception color, we now generate just a single arc + * labeled RAINBOW, saving lots of arc-munging later on. */ static void rainbow(struct nfa *nfa, @@ -1025,6 +1039,13 @@ rainbow(struct nfa *nfa, struct colordesc *end = CDEND(cm); color co; + if (but == COLORLESS) + { + newarc(nfa, type, RAINBOW, from, to); + return; + } + + /* Gotta do it the hard way. Skip subcolors, pseudocolors, and "but" */ for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++) if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but && !(cd->flags & PSEUDO)) @@ -1034,25 +1055,50 @@ rainbow(struct nfa *nfa, /* * colorcomplement - add arcs of complementary colors * + * We add arcs of all colors that are not pseudocolors and do not match + * any of the "of" state's PLAIN outarcs. + * * The calling sequence ought to be reconciled with cloneouts(). */ static void colorcomplement(struct nfa *nfa, struct colormap *cm, int type, - struct state *of, /* complements of this guy's PLAIN outarcs */ + struct state *of, struct state *from, struct state *to) { struct colordesc *cd; struct colordesc *end = CDEND(cm); color co; + struct arc *a; assert(of != from); + + /* A RAINBOW arc matches all colors, making the complement empty */ + if (findarc(of, PLAIN, RAINBOW) != NULL) + return; + + /* Otherwise, transiently mark the colors that appear in of's out-arcs */ + for (a = of->outs; a != NULL; a = a->outchain) + { + if (a->type == PLAIN) + { + assert(a->co >= 0); + cd = &cm->cd[a->co]; + assert(!UNUSEDCOLOR(cd)); + cd->flags |= COLMARK; + } + } + + /* Scan colors, clear transient marks, add arcs for unmarked colors */ for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++) - if (!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO)) - if (findarc(of, PLAIN, co) == NULL) - newarc(nfa, type, co, from, to); + { + if (cd->flags & COLMARK) + cd->flags &= ~COLMARK; + else if (!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO)) + newarc(nfa, type, co, from, to); + } } diff --git a/src/backend/regex/regc_lex.c b/src/backend/regex/regc_lex.c index 38617b79fd14..7673dab76f48 100644 --- a/src/backend/regex/regc_lex.c +++ b/src/backend/regex/regc_lex.c @@ -193,83 +193,6 @@ prefixes(struct vars *v) } } -/* - * lexnest - "call a subroutine", interpolating string at the lexical level - * - * Note, this is not a very general facility. There are a number of - * implicit assumptions about what sorts of strings can be subroutines. - */ -static void -lexnest(struct vars *v, - const chr *beginp, /* start of interpolation */ - const chr *endp) /* one past end of interpolation */ -{ - assert(v->savenow == NULL); /* only one level of nesting */ - v->savenow = v->now; - v->savestop = v->stop; - v->now = beginp; - v->stop = endp; -} - -/* - * string constants to interpolate as expansions of things like \d - */ -static const chr backd[] = { /* \d */ - CHR('['), CHR('['), CHR(':'), - CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'), - CHR(':'), CHR(']'), CHR(']') -}; -static const chr backD[] = { /* \D */ - CHR('['), CHR('^'), CHR('['), CHR(':'), - CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'), - CHR(':'), CHR(']'), CHR(']') -}; -static const chr brbackd[] = { /* \d within brackets */ - CHR('['), CHR(':'), - CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'), - CHR(':'), CHR(']') -}; -static const chr backs[] = { /* \s */ - CHR('['), CHR('['), CHR(':'), - CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'), - CHR(':'), CHR(']'), CHR(']') -}; -static const chr backS[] = { /* \S */ - CHR('['), CHR('^'), CHR('['), CHR(':'), - CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'), - CHR(':'), CHR(']'), CHR(']') -}; -static const chr brbacks[] = { /* \s within brackets */ - CHR('['), CHR(':'), - CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'), - CHR(':'), CHR(']') -}; -static const chr backw[] = { /* \w */ - CHR('['), CHR('['), CHR(':'), - CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'), - CHR(':'), CHR(']'), CHR('_'), CHR(']') -}; -static const chr backW[] = { /* \W */ - CHR('['), CHR('^'), CHR('['), CHR(':'), - CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'), - CHR(':'), CHR(']'), CHR('_'), CHR(']') -}; -static const chr brbackw[] = { /* \w within brackets */ - CHR('['), CHR(':'), - CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'), - CHR(':'), CHR(']'), CHR('_') -}; - -/* - * lexword - interpolate a bracket expression for word characters - * Possibly ought to inquire whether there is a "word" character class. - */ -static void -lexword(struct vars *v) -{ - lexnest(v, backw, ENDOF(backw)); -} - /* * next - get next token */ @@ -292,14 +215,6 @@ next(struct vars *v) RETV(SBEGIN, 0); /* same as \A */ } - /* if we're nested and we've hit end, return to outer level */ - if (v->savenow != NULL && ATEOS()) - { - v->now = v->savenow; - v->stop = v->savestop; - v->savenow = v->savestop = NULL; - } - /* skip white space etc. if appropriate (not in literal or []) */ if (v->cflags & REG_EXPANDED) switch (v->lexcon) @@ -389,7 +304,7 @@ next(struct vars *v) { v->now++; INTOCON(L_BRE); - RET('}'); + RETV('}', 1); } else FAILW(REG_BADBR); @@ -420,32 +335,15 @@ next(struct vars *v) NOTE(REG_UNONPOSIX); if (ATEOS()) FAILW(REG_EESCAPE); - (DISCARD) lexescape(v); + if (!lexescape(v)) + return 0; switch (v->nexttype) { /* not all escapes okay here */ case PLAIN: + case CCLASSS: + case CCLASSC: return 1; break; - case CCLASS: - switch (v->nextvalue) - { - case 'd': - lexnest(v, brbackd, ENDOF(brbackd)); - break; - case 's': - lexnest(v, brbacks, ENDOF(brbacks)); - break; - case 'w': - lexnest(v, brbackw, ENDOF(brbackw)); - break; - default: - FAILW(REG_EESCAPE); - break; - } - /* lexnest done, back up and try again */ - v->nexttype = v->lasttype; - return next(v); - break; } /* not one of the acceptable escapes */ FAILW(REG_EESCAPE); @@ -691,49 +589,17 @@ next(struct vars *v) } RETV(PLAIN, *v->now++); } - (DISCARD) lexescape(v); - if (ISERR()) - FAILW(REG_EESCAPE); - if (v->nexttype == CCLASS) - { /* fudge at lexical level */ - switch (v->nextvalue) - { - case 'd': - lexnest(v, backd, ENDOF(backd)); - break; - case 'D': - lexnest(v, backD, ENDOF(backD)); - break; - case 's': - lexnest(v, backs, ENDOF(backs)); - break; - case 'S': - lexnest(v, backS, ENDOF(backS)); - break; - case 'w': - lexnest(v, backw, ENDOF(backw)); - break; - case 'W': - lexnest(v, backW, ENDOF(backW)); - break; - default: - assert(NOTREACHED); - FAILW(REG_ASSERT); - break; - } - /* lexnest done, back up and try again */ - v->nexttype = v->lasttype; - return next(v); - } - /* otherwise, lexescape has already done the work */ - return !ISERR(); + return lexescape(v); } /* * lexescape - parse an ARE backslash escape (backslash already eaten) - * Note slightly nonstandard use of the CCLASS type code. + * + * This is used for ARE backslashes both normally and inside bracket + * expressions. In the latter case, not all escape types are allowed, + * but the caller must reject unwanted ones after we return. */ -static int /* not actually used, but convenient for RETV */ +static int lexescape(struct vars *v) { chr c; @@ -775,11 +641,11 @@ lexescape(struct vars *v) break; case CHR('d'): NOTE(REG_ULOCALE); - RETV(CCLASS, 'd'); + RETV(CCLASSS, CC_DIGIT); break; case CHR('D'): NOTE(REG_ULOCALE); - RETV(CCLASS, 'D'); + RETV(CCLASSC, CC_DIGIT); break; case CHR('e'): NOTE(REG_UUNPORT); @@ -802,11 +668,11 @@ lexescape(struct vars *v) break; case CHR('s'): NOTE(REG_ULOCALE); - RETV(CCLASS, 's'); + RETV(CCLASSS, CC_SPACE); break; case CHR('S'): NOTE(REG_ULOCALE); - RETV(CCLASS, 'S'); + RETV(CCLASSC, CC_SPACE); break; case CHR('t'): RETV(PLAIN, CHR('\t')); @@ -828,11 +694,11 @@ lexescape(struct vars *v) break; case CHR('w'): NOTE(REG_ULOCALE); - RETV(CCLASS, 'w'); + RETV(CCLASSS, CC_WORD); break; case CHR('W'): NOTE(REG_ULOCALE); - RETV(CCLASS, 'W'); + RETV(CCLASSC, CC_WORD); break; case CHR('x'): NOTE(REG_UUNPORT); @@ -994,7 +860,7 @@ brenext(struct vars *v, case CHR('*'): if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^')) RETV(PLAIN, c); - RET('*'); + RETV('*', 1); break; case CHR('['): if (HAVE(6) && *(v->now + 0) == CHR('[') && diff --git a/src/backend/regex/regc_locale.c b/src/backend/regex/regc_locale.c index 047abc3e1e74..b5f3a73b1bb2 100644 --- a/src/backend/regex/regc_locale.c +++ b/src/backend/regex/regc_locale.c @@ -350,17 +350,13 @@ static const struct cname }; /* - * The following arrays define the valid character class names. + * The following array defines the valid character class names. + * The entries must match enum char_classes in regguts.h. */ static const char *const classNames[NUM_CCLASSES + 1] = { "alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph", - "lower", "print", "punct", "space", "upper", "xdigit", NULL -}; - -enum classes -{ - CC_ALNUM, CC_ALPHA, CC_ASCII, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH, - CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_XDIGIT + "lower", "print", "punct", "space", "upper", "xdigit", "word", + NULL }; /* @@ -536,54 +532,58 @@ eclass(struct vars *v, /* context */ } /* - * cclass - supply cvec for a character class - * - * Must include case counterparts if "cases" is true. + * lookupcclass - lookup a character class identified by name * - * The returned cvec might be either a transient cvec gotten from getcvec(), - * or a permanently cached one from pg_ctype_get_cache(). This is okay - * because callers are not supposed to explicitly free the result either way. + * On failure, sets an error code in *v; the result is then garbage. */ -static struct cvec * -cclass(struct vars *v, /* context */ - const chr *startp, /* where the name starts */ - const chr *endp, /* just past the end of the name */ - int cases) /* case-independent? */ +static enum char_classes +lookupcclass(struct vars *v, /* context (for returning errors) */ + const chr *startp, /* where the name starts */ + const chr *endp) /* just past the end of the name */ { size_t len; - struct cvec *cv = NULL; const char *const *namePtr; - int i, - index; + int i; /* * Map the name to the corresponding enumerated value. */ len = endp - startp; - index = -1; for (namePtr = classNames, i = 0; *namePtr != NULL; namePtr++, i++) { if (strlen(*namePtr) == len && pg_char_and_wchar_strncmp(*namePtr, startp, len) == 0) - { - index = i; - break; - } - } - if (index == -1) - { - ERR(REG_ECTYPE); - return NULL; + return (enum char_classes) i; } + ERR(REG_ECTYPE); + return (enum char_classes) 0; +} + +/* + * cclasscvec - supply cvec for a character class + * + * Must include case counterparts if "cases" is true. + * + * The returned cvec might be either a transient cvec gotten from getcvec(), + * or a permanently cached one from pg_ctype_get_cache(). This is okay + * because callers are not supposed to explicitly free the result either way. + */ +static struct cvec * +cclasscvec(struct vars *v, /* context */ + enum char_classes cclasscode, /* class to build a cvec for */ + int cases) /* case-independent? */ +{ + struct cvec *cv = NULL; + /* * Remap lower and upper to alpha if the match is case insensitive. */ if (cases && - ((enum classes) index == CC_LOWER || - (enum classes) index == CC_UPPER)) - index = (int) CC_ALPHA; + (cclasscode == CC_LOWER || + cclasscode == CC_UPPER)) + cclasscode = CC_ALPHA; /* * Now compute the character class contents. For classes that are based @@ -595,16 +595,19 @@ cclass(struct vars *v, /* context */ * NB: keep this code in sync with cclass_column_index(), below. */ - switch ((enum classes) index) + switch (cclasscode) { case CC_PRINT: - cv = pg_ctype_get_cache(pg_wc_isprint, index); + cv = pg_ctype_get_cache(pg_wc_isprint, cclasscode); break; case CC_ALNUM: - cv = pg_ctype_get_cache(pg_wc_isalnum, index); + cv = pg_ctype_get_cache(pg_wc_isalnum, cclasscode); break; case CC_ALPHA: - cv = pg_ctype_get_cache(pg_wc_isalpha, index); + cv = pg_ctype_get_cache(pg_wc_isalpha, cclasscode); + break; + case CC_WORD: + cv = pg_ctype_get_cache(pg_wc_isword, cclasscode); break; case CC_ASCII: /* hard-wired meaning */ @@ -625,10 +628,10 @@ cclass(struct vars *v, /* context */ addrange(cv, 0x7f, 0x9f); break; case CC_DIGIT: - cv = pg_ctype_get_cache(pg_wc_isdigit, index); + cv = pg_ctype_get_cache(pg_wc_isdigit, cclasscode); break; case CC_PUNCT: - cv = pg_ctype_get_cache(pg_wc_ispunct, index); + cv = pg_ctype_get_cache(pg_wc_ispunct, cclasscode); break; case CC_XDIGIT: @@ -646,16 +649,16 @@ cclass(struct vars *v, /* context */ } break; case CC_SPACE: - cv = pg_ctype_get_cache(pg_wc_isspace, index); + cv = pg_ctype_get_cache(pg_wc_isspace, cclasscode); break; case CC_LOWER: - cv = pg_ctype_get_cache(pg_wc_islower, index); + cv = pg_ctype_get_cache(pg_wc_islower, cclasscode); break; case CC_UPPER: - cv = pg_ctype_get_cache(pg_wc_isupper, index); + cv = pg_ctype_get_cache(pg_wc_isupper, cclasscode); break; case CC_GRAPH: - cv = pg_ctype_get_cache(pg_wc_isgraph, index); + cv = pg_ctype_get_cache(pg_wc_isgraph, cclasscode); break; } @@ -678,7 +681,7 @@ cclass_column_index(struct colormap *cm, chr c) /* * Note: we should not see requests to consider cclasses that are not - * treated as locale-specific by cclass(), above. + * treated as locale-specific by cclasscvec(), above. */ if (cm->classbits[CC_PRINT] && pg_wc_isprint(c)) colnum |= cm->classbits[CC_PRINT]; @@ -686,6 +689,8 @@ cclass_column_index(struct colormap *cm, chr c) colnum |= cm->classbits[CC_ALNUM]; if (cm->classbits[CC_ALPHA] && pg_wc_isalpha(c)) colnum |= cm->classbits[CC_ALPHA]; + if (cm->classbits[CC_WORD] && pg_wc_isword(c)) + colnum |= cm->classbits[CC_WORD]; assert(cm->classbits[CC_ASCII] == 0); assert(cm->classbits[CC_BLANK] == 0); assert(cm->classbits[CC_CNTRL] == 0); diff --git a/src/backend/regex/regc_nfa.c b/src/backend/regex/regc_nfa.c index 92c9c4d795d1..6d77c59e1213 100644 --- a/src/backend/regex/regc_nfa.c +++ b/src/backend/regex/regc_nfa.c @@ -57,18 +57,27 @@ newnfa(struct vars *v, return NULL; } + /* Make the NFA minimally valid, so freenfa() will behave sanely */ nfa->states = NULL; nfa->slast = NULL; - nfa->free = NULL; + nfa->freestates = NULL; + nfa->freearcs = NULL; + nfa->lastsb = NULL; + nfa->lastab = NULL; + nfa->lastsbused = 0; + nfa->lastabused = 0; nfa->nstates = 0; nfa->cm = cm; nfa->v = v; nfa->bos[0] = nfa->bos[1] = COLORLESS; nfa->eos[0] = nfa->eos[1] = COLORLESS; + nfa->flags = 0; + nfa->minmatchall = nfa->maxmatchall = -1; nfa->parent = parent; /* Precedes newfstate so parent is valid. */ + + /* Create required infrastructure */ nfa->post = newfstate(nfa, '@'); /* number 0 */ nfa->pre = newfstate(nfa, '>'); /* number 1 */ - nfa->init = newstate(nfa); /* may become invalid later */ nfa->final = newstate(nfa); if (ISERR()) @@ -97,23 +106,27 @@ newnfa(struct vars *v, static void freenfa(struct nfa *nfa) { - struct state *s; + struct statebatch *sb; + struct statebatch *sbnext; + struct arcbatch *ab; + struct arcbatch *abnext; - while ((s = nfa->states) != NULL) + for (sb = nfa->lastsb; sb != NULL; sb = sbnext) { - s->nins = s->nouts = 0; /* don't worry about arcs */ - freestate(nfa, s); + sbnext = sb->next; + nfa->v->spaceused -= STATEBATCHSIZE(sb->nstates); + FREE(sb); } - while ((s = nfa->free) != NULL) + nfa->lastsb = NULL; + for (ab = nfa->lastab; ab != NULL; ab = abnext) { - nfa->free = s->next; - destroystate(nfa, s); + abnext = ab->next; + nfa->v->spaceused -= ARCBATCHSIZE(ab->narcs); + FREE(ab); } + nfa->lastab = NULL; - nfa->slast = NULL; nfa->nstates = -1; - nfa->pre = NULL; - nfa->post = NULL; FREE(nfa); } @@ -136,28 +149,43 @@ newstate(struct nfa *nfa) return NULL; } - if (nfa->free != NULL) + /* first, recycle anything that's on the freelist */ + if (nfa->freestates != NULL) { - s = nfa->free; - nfa->free = s->next; + s = nfa->freestates; + nfa->freestates = s->next; } + /* otherwise, is there anything left in the last statebatch? */ + else if (nfa->lastsb != NULL && nfa->lastsbused < nfa->lastsb->nstates) + { + s = &nfa->lastsb->s[nfa->lastsbused++]; + } + /* otherwise, need to allocate a new statebatch */ else { + struct statebatch *newSb; + size_t nstates; + if (nfa->v->spaceused >= REG_MAX_COMPILE_SPACE) { NERR(REG_ETOOBIG); return NULL; } - s = (struct state *) MALLOC(sizeof(struct state)); - if (s == NULL) + nstates = (nfa->lastsb != NULL) ? nfa->lastsb->nstates * 2 : FIRSTSBSIZE; + if (nstates > MAXSBSIZE) + nstates = MAXSBSIZE; + newSb = (struct statebatch *) MALLOC(STATEBATCHSIZE(nstates)); + if (newSb == NULL) { NERR(REG_ESPACE); return NULL; } - nfa->v->spaceused += sizeof(struct state); - s->oas.next = NULL; - s->free = NULL; - s->noas = 0; + nfa->v->spaceused += STATEBATCHSIZE(nstates); + newSb->nstates = nstates; + newSb->next = nfa->lastsb; + nfa->lastsb = newSb; + nfa->lastsbused = 1; + s = &newSb->s[0]; } assert(nfa->nstates >= 0); @@ -238,32 +266,8 @@ freestate(struct nfa *nfa, nfa->states = s->next; } s->prev = NULL; - s->next = nfa->free; /* don't delete it, put it on the free list */ - nfa->free = s; -} - -/* - * destroystate - really get rid of an already-freed state - */ -static void -destroystate(struct nfa *nfa, - struct state *s) -{ - struct arcbatch *ab; - struct arcbatch *abnext; - - assert(s->no == FREESTATE); - for (ab = s->oas.next; ab != NULL; ab = abnext) - { - abnext = ab->next; - FREE(ab); - nfa->v->spaceused -= sizeof(struct arcbatch); - } - s->ins = NULL; - s->outs = NULL; - s->next = NULL; - FREE(s); - nfa->v->spaceused -= sizeof(struct state); + s->next = nfa->freestates; /* don't delete it, put it on the free list */ + nfa->freestates = s; } /* @@ -271,6 +275,11 @@ destroystate(struct nfa *nfa, * * This function checks to make sure that no duplicate arcs are created. * In general we never want duplicates. + * + * However: in principle, a RAINBOW arc is redundant with any plain arc + * (unless that arc is for a pseudocolor). But we don't try to recognize + * that redundancy, either here or in allied operations such as moveins(). + * The pseudocolor consideration makes that more costly than it seems worth. */ static void newarc(struct nfa *nfa, @@ -327,8 +336,7 @@ createarc(struct nfa *nfa, { struct arc *a; - /* the arc is physically allocated within its from-state */ - a = allocarc(nfa, from); + a = allocarc(nfa); if (NISERR()) return; assert(a != NULL); @@ -362,55 +370,52 @@ createarc(struct nfa *nfa, } /* - * allocarc - allocate a new out-arc within a state + * allocarc - allocate a new arc within an NFA */ static struct arc * /* NULL for failure */ -allocarc(struct nfa *nfa, - struct state *s) +allocarc(struct nfa *nfa) { struct arc *a; - /* shortcut */ - if (s->free == NULL && s->noas < ABSIZE) + /* first, recycle anything that's on the freelist */ + if (nfa->freearcs != NULL) { - a = &s->oas.a[s->noas]; - s->noas++; - return a; + a = nfa->freearcs; + nfa->freearcs = a->freechain; } - - /* if none at hand, get more */ - if (s->free == NULL) + /* otherwise, is there anything left in the last arcbatch? */ + else if (nfa->lastab != NULL && nfa->lastabused < nfa->lastab->narcs) + { + a = &nfa->lastab->a[nfa->lastabused++]; + } + /* otherwise, need to allocate a new arcbatch */ + else { struct arcbatch *newAb; - int i; + size_t narcs; if (nfa->v->spaceused >= REG_MAX_COMPILE_SPACE) { NERR(REG_ETOOBIG); return NULL; } - newAb = (struct arcbatch *) MALLOC(sizeof(struct arcbatch)); + narcs = (nfa->lastab != NULL) ? nfa->lastab->narcs * 2 : FIRSTABSIZE; + if (narcs > MAXABSIZE) + narcs = MAXABSIZE; + newAb = (struct arcbatch *) MALLOC(ARCBATCHSIZE(narcs)); if (newAb == NULL) { NERR(REG_ESPACE); return NULL; } - nfa->v->spaceused += sizeof(struct arcbatch); - newAb->next = s->oas.next; - s->oas.next = newAb; - - for (i = 0; i < ABSIZE; i++) - { - newAb->a[i].type = 0; - newAb->a[i].freechain = &newAb->a[i + 1]; - } - newAb->a[ABSIZE - 1].freechain = NULL; - s->free = &newAb->a[0]; + nfa->v->spaceused += ARCBATCHSIZE(narcs); + newAb->narcs = narcs; + newAb->next = nfa->lastab; + nfa->lastab = newAb; + nfa->lastabused = 1; + a = &newAb->a[0]; } - assert(s->free != NULL); - a = s->free; - s->free = a->freechain; return a; } @@ -471,7 +476,7 @@ freearc(struct nfa *nfa, } to->nins--; - /* clean up and place on from-state's free list */ + /* clean up and place on NFA's free list */ victim->type = 0; victim->from = NULL; /* precautions... */ victim->to = NULL; @@ -479,17 +484,58 @@ freearc(struct nfa *nfa, victim->inchainRev = NULL; victim->outchain = NULL; victim->outchainRev = NULL; - victim->freechain = from->free; - from->free = victim; + victim->freechain = nfa->freearcs; + nfa->freearcs = victim; } /* - * changearctarget - flip an arc to have a different to state + * changearcsource - flip an arc to have a different from state * * Caller must have verified that there is no pre-existing duplicate arc. + */ +static void +changearcsource(struct arc *a, struct state *newfrom) +{ + struct state *oldfrom = a->from; + struct arc *predecessor; + + assert(oldfrom != newfrom); + + /* take it off old source's out-chain */ + assert(oldfrom != NULL); + predecessor = a->outchainRev; + if (predecessor == NULL) + { + assert(oldfrom->outs == a); + oldfrom->outs = a->outchain; + } + else + { + assert(predecessor->outchain == a); + predecessor->outchain = a->outchain; + } + if (a->outchain != NULL) + { + assert(a->outchain->outchainRev == a); + a->outchain->outchainRev = predecessor; + } + oldfrom->nouts--; + + a->from = newfrom; + + /* prepend it to new source's out-chain */ + a->outchain = newfrom->outs; + a->outchainRev = NULL; + if (newfrom->outs) + newfrom->outs->outchainRev = a; + newfrom->outs = a; + newfrom->nouts++; +} + +/* + * changearctarget - flip an arc to have a different to state * - * Note that because we store arcs in their from state, we can't easily have - * a similar changearcsource function. + * Caller must have verified that there is no pre-existing duplicate arc. */ static void changearctarget(struct arc *a, struct state *newto) @@ -1002,6 +1048,8 @@ mergeins(struct nfa *nfa, /* * moveouts - move all out arcs of a state to another state + * + * See comments for moveins() */ static void moveouts(struct nfa *nfa, @@ -1024,9 +1072,9 @@ moveouts(struct nfa *nfa, else { /* - * With many arcs, use a sort-merge approach. Note that createarc() - * will put new arcs onto the front of newState's chain, so it does - * not break our walk through the sorted part of the chain. + * With many arcs, use a sort-merge approach. Note changearcsource() + * will put the arc onto the front of newState's chain, so it does not + * break our walk through the sorted part of the chain. */ struct arc *oa; struct arc *na; @@ -1056,8 +1104,12 @@ moveouts(struct nfa *nfa, case -1: /* newState does not have anything matching oa */ oa = oa->outchain; - createarc(nfa, a->type, a->co, newState, a->to); - freearc(nfa, a); + + /* + * Rather than doing createarc+freearc, we can just unlink + * and relink the existing arc struct. + */ + changearcsource(a, newState); break; case 0: /* match, advance in both lists */ @@ -1080,8 +1132,7 @@ moveouts(struct nfa *nfa, struct arc *a = oa; oa = oa->outchain; - createarc(nfa, a->type, a->co, newState, a->to); - freearc(nfa, a); + changearcsource(a, newState); } } @@ -1170,6 +1221,9 @@ copyouts(struct nfa *nfa, /* * cloneouts - copy out arcs of a state to another state pair, modifying type + * + * This is only used to convert PLAIN arcs to AHEAD/BEHIND arcs, which share + * the same interpretation of "co". It wouldn't be sensible with LACONs. */ static void cloneouts(struct nfa *nfa, @@ -1181,9 +1235,13 @@ cloneouts(struct nfa *nfa, struct arc *a; assert(old != from); + assert(type == AHEAD || type == BEHIND); for (a = old->outs; a != NULL; a = a->outchain) + { + assert(a->type == PLAIN); newarc(nfa, type, a->co, from, to); + } } /* @@ -1324,6 +1382,77 @@ duptraverse(struct nfa *nfa, } } +/* + * removeconstraints - remove any constraints in an NFA + * + * Constraint arcs are replaced by empty arcs, essentially treating all + * constraints as automatically satisfied. + */ +static void +removeconstraints(struct nfa *nfa, + struct state *start, /* process subNFA starting here */ + struct state *stop) /* and stopping here */ +{ + if (start == stop) + return; + + stop->tmp = stop; + removetraverse(nfa, start); + /* done, except for clearing out the tmp pointers */ + + stop->tmp = NULL; + cleartraverse(nfa, start); +} + +/* + * removetraverse - recursive heart of removeconstraints + */ +static void +removetraverse(struct nfa *nfa, + struct state *s) +{ + struct arc *a; + struct arc *oa; + + /* Since this is recursive, it could be driven to stack overflow */ + if (STACK_TOO_DEEP(nfa->v->re)) + { + NERR(REG_ETOOBIG); + return; + } + + if (s->tmp != NULL) + return; /* already done */ + + s->tmp = s; + for (a = s->outs; a != NULL && !NISERR(); a = oa) + { + removetraverse(nfa, a->to); + if (NISERR()) + break; + oa = a->outchain; + switch (a->type) + { + case PLAIN: + case EMPTY: + /* nothing to do */ + break; + case AHEAD: + case BEHIND: + case '^': + case '$': + case LACON: + /* replace it */ + newarc(nfa, EMPTY, 0, s, a->to); + freearc(nfa, a); + break; + default: + NERR(REG_ASSERT); + break; + } + } +} + /* * cleartraverse - recursive cleanup for algorithms that leave tmp ptrs set */ @@ -1597,7 +1726,7 @@ pull(struct nfa *nfa, for (a = from->ins; a != NULL && !NISERR(); a = nexta) { nexta = a->inchain; - switch (combine(con, a)) + switch (combine(nfa, con, a)) { case INCOMPATIBLE: /* destroy the arc */ freearc(nfa, a); @@ -1624,6 +1753,10 @@ pull(struct nfa *nfa, cparc(nfa, a, s, to); freearc(nfa, a); break; + case REPLACEARC: /* replace arc's color */ + newarc(nfa, a->type, con->co, a->from, to); + freearc(nfa, a); + break; default: assert(NOTREACHED); break; @@ -1764,7 +1897,7 @@ push(struct nfa *nfa, for (a = to->outs; a != NULL && !NISERR(); a = nexta) { nexta = a->outchain; - switch (combine(con, a)) + switch (combine(nfa, con, a)) { case INCOMPATIBLE: /* destroy the arc */ freearc(nfa, a); @@ -1791,6 +1924,10 @@ push(struct nfa *nfa, cparc(nfa, a, from, s); freearc(nfa, a); break; + case REPLACEARC: /* replace arc's color */ + newarc(nfa, a->type, con->co, from, a->to); + freearc(nfa, a); + break; default: assert(NOTREACHED); break; @@ -1810,9 +1947,11 @@ push(struct nfa *nfa, * #def INCOMPATIBLE 1 // destroys arc * #def SATISFIED 2 // constraint satisfied * #def COMPATIBLE 3 // compatible but not satisfied yet + * #def REPLACEARC 4 // replace arc's color with constraint color */ static int -combine(struct arc *con, +combine(struct nfa *nfa, + struct arc *con, struct arc *a) { #define CA(ct,at) (((ct)<co == a->co) return SATISFIED; + if (con->co == RAINBOW) + { + /* con is satisfied unless arc's color is a pseudocolor */ + if (!(nfa->cm->cd[a->co].flags & PSEUDO)) + return SATISFIED; + } + else if (a->co == RAINBOW) + { + /* con is incompatible if it's for a pseudocolor */ + if (nfa->cm->cd[con->co].flags & PSEUDO) + return INCOMPATIBLE; + /* otherwise, constraint constrains arc to be only its color */ + return REPLACEARC; + } return INCOMPATIBLE; break; case CA('^', '^'): /* collision, similar constraints */ case CA('$', '$'): - case CA(AHEAD, AHEAD): + if (con->co == a->co) /* true duplication */ + return SATISFIED; + return INCOMPATIBLE; + break; + case CA(AHEAD, AHEAD): /* collision, similar constraints */ case CA(BEHIND, BEHIND): if (con->co == a->co) /* true duplication */ return SATISFIED; + if (con->co == RAINBOW) + { + /* con is satisfied unless arc's color is a pseudocolor */ + if (!(nfa->cm->cd[a->co].flags & PSEUDO)) + return SATISFIED; + } + else if (a->co == RAINBOW) + { + /* con is incompatible if it's for a pseudocolor */ + if (nfa->cm->cd[con->co].flags & PSEUDO) + return INCOMPATIBLE; + /* otherwise, constraint constrains arc to be only its color */ + return REPLACEARC; + } return INCOMPATIBLE; break; case CA('^', BEHIND): /* collision, dissimilar constraints */ @@ -2821,8 +2992,14 @@ analyze(struct nfa *nfa) if (NISERR()) return 0; + /* Detect whether NFA can't match anything */ if (nfa->pre->outs == NULL) return REG_UIMPOSSIBLE; + + /* Detect whether NFA matches all strings (possibly with length bounds) */ + checkmatchall(nfa); + + /* Detect whether NFA can possibly match a zero-length string */ for (a = nfa->pre->outs; a != NULL; a = a->outchain) for (aa = a->to->outs; aa != NULL; aa = aa->outchain) if (aa->to == nfa->post) @@ -2830,6 +3007,446 @@ analyze(struct nfa *nfa) return 0; } +/* + * checkmatchall - does the NFA represent no more than a string length test? + * + * If so, set nfa->minmatchall and nfa->maxmatchall correctly (they are -1 + * to begin with) and set the MATCHALL bit in nfa->flags. + * + * To succeed, we require all arcs to be PLAIN RAINBOW arcs, except for those + * for pseudocolors (i.e., BOS/BOL/EOS/EOL). We must be able to reach the + * post state via RAINBOW arcs, and if there are any loops in the graph, they + * must be loop-to-self arcs, ensuring that each loop iteration consumes + * exactly one character. (Longer loops are problematic because they create + * non-consecutive possible match lengths; we have no good way to represent + * that situation for lengths beyond the DUPINF limit.) + * + * Pseudocolor arcs complicate things a little. We know that they can only + * appear as pre-state outarcs (for BOS/BOL) or post-state inarcs (for + * EOS/EOL). There, they must exactly replicate the parallel RAINBOW arcs, + * e.g. if the pre state has one RAINBOW outarc to state 2, it must have BOS + * and BOL outarcs to state 2, and no others. Missing or extra pseudocolor + * arcs can occur, meaning that the NFA involves some constraint on the + * adjacent characters, which makes it not a matchall NFA. + */ +static void +checkmatchall(struct nfa *nfa) +{ + bool **haspaths; + struct state *s; + int i; + + /* + * If there are too many states, don't bother trying to detect matchall. + * This limit serves to bound the time and memory we could consume below. + * Note that even if the graph is all-RAINBOW, if there are significantly + * more than DUPINF states then it's likely that there are paths of length + * more than DUPINF, which would force us to fail anyhow. In practice, + * plausible ways of writing a matchall regex with maximum finite path + * length K tend not to have very many more than K states. + */ + if (nfa->nstates > DUPINF * 2) + return; + + /* + * First, scan all the states to verify that only RAINBOW arcs appear, + * plus pseudocolor arcs adjacent to the pre and post states. This lets + * us quickly eliminate most cases that aren't matchall NFAs. + */ + for (s = nfa->states; s != NULL; s = s->next) + { + struct arc *a; + + for (a = s->outs; a != NULL; a = a->outchain) + { + if (a->type != PLAIN) + return; /* any LACONs make it non-matchall */ + if (a->co != RAINBOW) + { + if (nfa->cm->cd[a->co].flags & PSEUDO) + { + /* + * Pseudocolor arc: verify it's in a valid place (this + * seems quite unlikely to fail, but let's be sure). + */ + if (s == nfa->pre && + (a->co == nfa->bos[0] || a->co == nfa->bos[1])) + /* okay BOS/BOL arc */ ; + else if (a->to == nfa->post && + (a->co == nfa->eos[0] || a->co == nfa->eos[1])) + /* okay EOS/EOL arc */ ; + else + return; /* unexpected pseudocolor arc */ + /* We'll check these arcs some more below. */ + } + else + return; /* any other color makes it non-matchall */ + } + } + /* Also, assert that the tmp fields are available for use. */ + assert(s->tmp == NULL); + } + + /* + * The next cheapest check we can make is to verify that the BOS/BOL + * outarcs of the pre state reach the same states as its RAINBOW outarcs. + * If they don't, the NFA expresses some constraints on the character + * before the matched string, making it non-matchall. Likewise, the + * EOS/EOL inarcs of the post state must match its RAINBOW inarcs. + */ + if (!check_out_colors_match(nfa->pre, RAINBOW, nfa->bos[0]) || + !check_out_colors_match(nfa->pre, RAINBOW, nfa->bos[1]) || + !check_in_colors_match(nfa->post, RAINBOW, nfa->eos[0]) || + !check_in_colors_match(nfa->post, RAINBOW, nfa->eos[1])) + return; + + /* + * Initialize an array of path-length arrays, in which + * checkmatchall_recurse will return per-state results. This lets us + * memo-ize the recursive search and avoid exponential time consumption. + */ + haspaths = (bool **) MALLOC(nfa->nstates * sizeof(bool *)); + if (haspaths == NULL) + return; /* fail quietly */ + memset(haspaths, 0, nfa->nstates * sizeof(bool *)); + + /* + * Recursively search the graph for all-RAINBOW paths to the "post" state, + * starting at the "pre" state, and computing the lengths of the paths. + * (Given the preceding checks, there should be at least one such path. + * However we could get back a false result anyway, in case there are + * multi-state loops, paths exceeding DUPINF+1 length, or non-algorithmic + * failures such as ENOMEM.) + */ + if (checkmatchall_recurse(nfa, nfa->pre, haspaths)) + { + /* The useful result is the path length array for the pre state */ + bool *haspath = haspaths[nfa->pre->no]; + int minmatch, + maxmatch, + morematch; + + assert(haspath != NULL); + + /* + * haspath[] now represents the set of possible path lengths; but we + * want to reduce that to a min and max value, because it doesn't seem + * worth complicating regexec.c to deal with nonconsecutive possible + * match lengths. Find min and max of first run of lengths, then + * verify there are no nonconsecutive lengths. + */ + for (minmatch = 0; minmatch <= DUPINF + 1; minmatch++) + { + if (haspath[minmatch]) + break; + } + assert(minmatch <= DUPINF + 1); /* else checkmatchall_recurse lied */ + for (maxmatch = minmatch; maxmatch < DUPINF + 1; maxmatch++) + { + if (!haspath[maxmatch + 1]) + break; + } + for (morematch = maxmatch + 1; morematch <= DUPINF + 1; morematch++) + { + if (haspath[morematch]) + { + haspath = NULL; /* fail, there are nonconsecutive lengths */ + break; + } + } + + if (haspath != NULL) + { + /* + * Success, so record the info. Here we have a fine point: the + * path length from the pre state includes the pre-to-initial + * transition, so it's one more than the actually matched string + * length. (We avoided counting the final-to-post transition + * within checkmatchall_recurse, but not this one.) This is why + * checkmatchall_recurse allows one more level of path length than + * might seem necessary. This decrement also takes care of + * converting checkmatchall_recurse's definition of "infinity" as + * "DUPINF+1" to our normal representation as "DUPINF". + */ + assert(minmatch > 0); /* else pre and post states were adjacent */ + nfa->minmatchall = minmatch - 1; + nfa->maxmatchall = maxmatch - 1; + nfa->flags |= MATCHALL; + } + } + + /* Clean up */ + for (i = 0; i < nfa->nstates; i++) + { + if (haspaths[i] != NULL) + FREE(haspaths[i]); + } + FREE(haspaths); +} + +/* + * checkmatchall_recurse - recursive search for checkmatchall + * + * s is the state to be examined in this recursion level. + * haspaths[] is an array of per-state exit path length arrays. + * + * We return true if the search was performed successfully, false if + * we had to fail because of multi-state loops or other internal reasons. + * (Because "dead" states that can't reach the post state have been + * eliminated, and we already verified that only RAINBOW and matching + * pseudocolor arcs exist, every state should have RAINBOW path(s) to + * the post state. Hence we take a false result from recursive calls + * as meaning that we'd better fail altogether, not just that that + * particular state can't reach the post state.) + * + * On success, we store a malloc'd result array in haspaths[s->no], + * showing the possible path lengths from s to the post state. + * Each state's haspath[] array is of length DUPINF+2. The entries from + * k = 0 to DUPINF are true if there is an all-RAINBOW path of length k + * from this state to the string end. haspath[DUPINF+1] is true if all + * path lengths >= DUPINF+1 are possible. (Situations that cannot be + * represented under these rules cause failure.) + * + * checkmatchall is responsible for eventually freeing the haspath[] arrays. + */ +static bool +checkmatchall_recurse(struct nfa *nfa, struct state *s, bool **haspaths) +{ + bool result = false; + bool foundloop = false; + bool *haspath; + struct arc *a; + + /* + * Since this is recursive, it could be driven to stack overflow. But we + * need not treat that as a hard failure; just deem the NFA non-matchall. + */ + if (STACK_TOO_DEEP(nfa->v->re)) + return false; + + /* In case the search takes a long time, check for cancel */ + if (CANCEL_REQUESTED(nfa->v->re)) + { + NERR(REG_CANCEL); + return false; + } + + /* Create a haspath array for this state */ + haspath = (bool *) MALLOC((DUPINF + 2) * sizeof(bool)); + if (haspath == NULL) + return false; /* again, treat as non-matchall */ + memset(haspath, 0, (DUPINF + 2) * sizeof(bool)); + + /* Mark this state as being visited */ + assert(s->tmp == NULL); + s->tmp = s; + + for (a = s->outs; a != NULL; a = a->outchain) + { + if (a->co != RAINBOW) + continue; /* ignore pseudocolor arcs */ + if (a->to == nfa->post) + { + /* We found an all-RAINBOW path to the post state */ + result = true; + + /* + * Mark this state as being zero steps away from the string end + * (the transition to the post state isn't counted). + */ + haspath[0] = true; + } + else if (a->to == s) + { + /* We found a cycle of length 1, which we'll deal with below. */ + foundloop = true; + } + else if (a->to->tmp != NULL) + { + /* It's busy, so we found a cycle of length > 1, so fail. */ + result = false; + break; + } + else + { + /* Consider paths forward through this to-state. */ + bool *nexthaspath; + int i; + + /* If to-state was not already visited, recurse */ + if (haspaths[a->to->no] == NULL) + { + result = checkmatchall_recurse(nfa, a->to, haspaths); + /* Fail if any recursive path fails */ + if (!result) + break; + } + else + { + /* The previous visit must have found path(s) to the end */ + result = true; + } + assert(a->to->tmp == NULL); + nexthaspath = haspaths[a->to->no]; + assert(nexthaspath != NULL); + + /* + * Now, for every path of length i from a->to to the string end, + * there is a path of length i + 1 from s to the string end. + */ + if (nexthaspath[DUPINF] != nexthaspath[DUPINF + 1]) + { + /* + * a->to has a path of length exactly DUPINF, but not longer; + * or it has paths of all lengths > DUPINF but not one of + * exactly that length. In either case, we cannot represent + * the possible path lengths from s correctly, so fail. + */ + result = false; + break; + } + /* Merge knowledge of these path lengths into what we have */ + for (i = 0; i < DUPINF; i++) + haspath[i + 1] |= nexthaspath[i]; + /* Infinity + 1 is still infinity */ + haspath[DUPINF + 1] |= nexthaspath[DUPINF + 1]; + } + } + + if (result && foundloop) + { + /* + * If there is a length-1 loop at this state, then find the shortest + * known path length to the end. The loop means that every larger + * path length is possible, too. (It doesn't matter whether any of + * the longer lengths were already known possible.) + */ + int i; + + for (i = 0; i <= DUPINF; i++) + { + if (haspath[i]) + break; + } + for (i++; i <= DUPINF + 1; i++) + haspath[i] = true; + } + + /* Report out the completed path length map */ + assert(s->no < nfa->nstates); + assert(haspaths[s->no] == NULL); + haspaths[s->no] = haspath; + + /* Mark state no longer busy */ + s->tmp = NULL; + + return result; +} + +/* + * check_out_colors_match - subroutine for checkmatchall + * + * Check whether the set of states reachable from s by arcs of color co1 + * is equivalent to the set reachable by arcs of color co2. + * checkmatchall already verified that all of the NFA's arcs are PLAIN, + * so we need not examine arc types here. + */ +static bool +check_out_colors_match(struct state *s, color co1, color co2) +{ + bool result = true; + struct arc *a; + + /* + * To do this in linear time, we assume that the NFA contains no duplicate + * arcs. Run through the out-arcs, marking states reachable by arcs of + * color co1. Run through again, un-marking states reachable by arcs of + * color co2; if we see a not-marked state, we know this co2 arc is + * unmatched. Then run through again, checking for still-marked states, + * and in any case leaving all the tmp fields reset to NULL. + */ + for (a = s->outs; a != NULL; a = a->outchain) + { + if (a->co == co1) + { + assert(a->to->tmp == NULL); + a->to->tmp = a->to; + } + } + for (a = s->outs; a != NULL; a = a->outchain) + { + if (a->co == co2) + { + if (a->to->tmp != NULL) + a->to->tmp = NULL; + else + result = false; /* unmatched co2 arc */ + } + } + for (a = s->outs; a != NULL; a = a->outchain) + { + if (a->co == co1) + { + if (a->to->tmp != NULL) + { + result = false; /* unmatched co1 arc */ + a->to->tmp = NULL; + } + } + } + return result; +} + +/* + * check_in_colors_match - subroutine for checkmatchall + * + * Check whether the set of states that can reach s by arcs of color co1 + * is equivalent to the set that can reach s by arcs of color co2. + * checkmatchall already verified that all of the NFA's arcs are PLAIN, + * so we need not examine arc types here. + */ +static bool +check_in_colors_match(struct state *s, color co1, color co2) +{ + bool result = true; + struct arc *a; + + /* + * Identical algorithm to check_out_colors_match, except examine the + * from-states of s' inarcs. + */ + for (a = s->ins; a != NULL; a = a->inchain) + { + if (a->co == co1) + { + assert(a->from->tmp == NULL); + a->from->tmp = a->from; + } + } + for (a = s->ins; a != NULL; a = a->inchain) + { + if (a->co == co2) + { + if (a->from->tmp != NULL) + a->from->tmp = NULL; + else + result = false; /* unmatched co2 arc */ + } + } + for (a = s->ins; a != NULL; a = a->inchain) + { + if (a->co == co1) + { + if (a->from->tmp != NULL) + { + result = false; /* unmatched co1 arc */ + a->from->tmp = NULL; + } + } + } + return result; +} + /* * compact - construct the compact representation of an NFA */ @@ -2876,7 +3493,9 @@ compact(struct nfa *nfa, cnfa->eos[0] = nfa->eos[0]; cnfa->eos[1] = nfa->eos[1]; cnfa->ncolors = maxcolor(nfa->cm) + 1; - cnfa->flags = 0; + cnfa->flags = nfa->flags; + cnfa->minmatchall = nfa->minmatchall; + cnfa->maxmatchall = nfa->maxmatchall; ca = cnfa->arcs; for (s = nfa->states; s != NULL; s = s->next) @@ -2895,6 +3514,7 @@ compact(struct nfa *nfa, break; case LACON: assert(s->no != cnfa->pre); + assert(a->co >= 0); ca->co = (color) (cnfa->ncolors + a->co); ca->to = a->to->no; ca++; @@ -2902,7 +3522,7 @@ compact(struct nfa *nfa, break; default: NERR(REG_ASSERT); - break; + return; } carcsort(first, ca - first); ca->co = COLORLESS; @@ -2951,11 +3571,11 @@ carc_cmp(const void *a, const void *b) static void freecnfa(struct cnfa *cnfa) { - assert(cnfa->nstates != 0); /* not empty already */ - cnfa->nstates = 0; + assert(!NULLCNFA(*cnfa)); /* not empty already */ FREE(cnfa->stflags); FREE(cnfa->states); FREE(cnfa->arcs); + ZAPCNFA(*cnfa); } /* @@ -2979,6 +3599,11 @@ dumpnfa(struct nfa *nfa, fprintf(f, ", eos [%ld]", (long) nfa->eos[0]); if (nfa->eos[1] != COLORLESS) fprintf(f, ", eol [%ld]", (long) nfa->eos[1]); + if (nfa->flags & HASLACONS) + fprintf(f, ", haslacons"); + if (nfa->flags & MATCHALL) + fprintf(f, ", minmatchall %d, maxmatchall %d", + nfa->minmatchall, nfa->maxmatchall); fprintf(f, "\n"); for (s = nfa->states; s != NULL; s = s->next) { @@ -3012,13 +3637,13 @@ dumpstate(struct state *s, fprintf(f, "\tno out arcs\n"); else dumparcs(s, f); - fflush(f); for (a = s->ins; a != NULL; a = a->inchain) { if (a->to != s) fprintf(f, "\tlink from %d to %d on %d's in-chain\n", a->from->no, a->to->no, s->no); } + fflush(f); } /* @@ -3062,19 +3687,27 @@ dumparc(struct arc *a, FILE *f) { struct arc *aa; - struct arcbatch *ab; fprintf(f, "\t"); switch (a->type) { case PLAIN: - fprintf(f, "[%ld]", (long) a->co); + if (a->co == RAINBOW) + fprintf(f, "[*]"); + else + fprintf(f, "[%ld]", (long) a->co); break; case AHEAD: - fprintf(f, ">%ld>", (long) a->co); + if (a->co == RAINBOW) + fprintf(f, ">*>"); + else + fprintf(f, ">%ld>", (long) a->co); break; case BEHIND: - fprintf(f, "<%ld<", (long) a->co); + if (a->co == RAINBOW) + fprintf(f, "<*<"); + else + fprintf(f, "<%ld<", (long) a->co); break; case LACON: fprintf(f, ":%ld:", (long) a->co); @@ -3091,16 +3724,11 @@ dumparc(struct arc *a, } if (a->from != s) fprintf(f, "?%d?", a->from->no); - for (ab = &a->from->oas; ab != NULL; ab = ab->next) - { - for (aa = &ab->a[0]; aa < &ab->a[ABSIZE]; aa++) - if (aa == a) - break; /* NOTE BREAK OUT */ - if (aa < &ab->a[ABSIZE]) /* propagate break */ + for (aa = a->from->outs; aa != NULL; aa = aa->outchain) + if (aa == a) break; /* NOTE BREAK OUT */ - } - if (ab == NULL) - fprintf(f, "?!?"); /* not in allocated space */ + if (aa == NULL) + fprintf(f, "?!?"); /* missing from out-chain */ fprintf(f, "->"); if (a->to == NULL) { @@ -3137,6 +3765,9 @@ dumpcnfa(struct cnfa *cnfa, fprintf(f, ", eol [%ld]", (long) cnfa->eos[1]); if (cnfa->flags & HASLACONS) fprintf(f, ", haslacons"); + if (cnfa->flags & MATCHALL) + fprintf(f, ", minmatchall %d, maxmatchall %d", + cnfa->minmatchall, cnfa->maxmatchall); fprintf(f, "\n"); for (st = 0; st < cnfa->nstates; st++) dumpcstate(st, cnfa, f); @@ -3161,7 +3792,9 @@ dumpcstate(int st, pos = 1; for (ca = cnfa->states[st]; ca->co != COLORLESS; ca++) { - if (ca->co < cnfa->ncolors) + if (ca->co == RAINBOW) + fprintf(f, "\t[*]->%d", ca->to); + else if (ca->co < cnfa->ncolors) fprintf(f, "\t[%ld]->%d", (long) ca->co, ca->to); else fprintf(f, "\t:%ld:->%d", (long) (ca->co - cnfa->ncolors), ca->to); diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c index 3cc2d4d36277..bbbd61c604ae 100644 --- a/src/backend/regex/regc_pg_locale.c +++ b/src/backend/regex/regc_pg_locale.c @@ -6,7 +6,7 @@ * * This file is #included by regcomp.c; it's not meant to compile standalone. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -400,6 +400,15 @@ pg_wc_isalnum(pg_wchar c) return 0; /* can't get here, but keep compiler quiet */ } +static int +pg_wc_isword(pg_wchar c) +{ + /* We define word characters as alnum class plus underscore */ + if (c == CHR('_')) + return 1; + return pg_wc_isalnum(c); +} + static int pg_wc_isupper(pg_wchar c) { diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c index 91078dcd8064..9f71177d3180 100644 --- a/src/backend/regex/regcomp.c +++ b/src/backend/regex/regcomp.c @@ -46,18 +46,24 @@ static struct subre *parsebranch(struct vars *, int, int, struct state *, struct static void parseqatom(struct vars *, int, int, struct state *, struct state *, struct subre *); static void nonword(struct vars *, int, struct state *, struct state *); static void word(struct vars *, int, struct state *, struct state *); +static void charclass(struct vars *, enum char_classes, + struct state *, struct state *); +static void charclasscomplement(struct vars *, enum char_classes, + struct state *, struct state *); static int scannum(struct vars *); static void repeat(struct vars *, struct state *, struct state *, int, int); static void bracket(struct vars *, struct state *, struct state *); static void cbracket(struct vars *, struct state *, struct state *); -static void brackpart(struct vars *, struct state *, struct state *); +static void brackpart(struct vars *, struct state *, struct state *, bool *); static const chr *scanplain(struct vars *); static void onechr(struct vars *, chr, struct state *, struct state *); +static void optimizebracket(struct vars *, struct state *, struct state *); static void wordchrs(struct vars *); static void processlacon(struct vars *, struct state *, struct state *, int, struct state *, struct state *); static struct subre *subre(struct vars *, int, int, struct state *, struct state *); static void freesubre(struct vars *, struct subre *); +static void freesubreandsiblings(struct vars *, struct subre *); static void freesrnode(struct vars *, struct subre *); static void optst(struct vars *, struct subre *); static int numst(struct subre *, int); @@ -80,8 +86,6 @@ static const char *stid(struct subre *, char *, size_t); /* === regc_lex.c === */ static void lexstart(struct vars *); static void prefixes(struct vars *); -static void lexnest(struct vars *, const chr *, const chr *); -static void lexword(struct vars *); static int next(struct vars *); static int lexescape(struct vars *); static chr lexdigits(struct vars *, int, int, int); @@ -123,11 +127,11 @@ static struct state *newstate(struct nfa *); static struct state *newfstate(struct nfa *, int flag); static void dropstate(struct nfa *, struct state *); static void freestate(struct nfa *, struct state *); -static void destroystate(struct nfa *, struct state *); static void newarc(struct nfa *, int, color, struct state *, struct state *); static void createarc(struct nfa *, int, color, struct state *, struct state *); -static struct arc *allocarc(struct nfa *, struct state *); +static struct arc *allocarc(struct nfa *); static void freearc(struct nfa *, struct arc *); +static void changearcsource(struct arc *, struct state *); static void changearctarget(struct arc *, struct state *); static int hasnonemptyout(struct state *); static struct arc *findarc(struct state *, int, color); @@ -146,6 +150,8 @@ static void delsub(struct nfa *, struct state *, struct state *); static void deltraverse(struct nfa *, struct state *, struct state *); static void dupnfa(struct nfa *, struct state *, struct state *, struct state *, struct state *); static void duptraverse(struct nfa *, struct state *, struct state *); +static void removeconstraints(struct nfa *, struct state *, struct state *); +static void removetraverse(struct nfa *, struct state *); static void cleartraverse(struct nfa *, struct state *); static struct state *single_color_transition(struct state *, struct state *); static void specialcolors(struct nfa *); @@ -158,7 +164,8 @@ static int push(struct nfa *, struct arc *, struct state **); #define INCOMPATIBLE 1 /* destroys arc */ #define SATISFIED 2 /* constraint satisfied */ #define COMPATIBLE 3 /* compatible but not satisfied yet */ -static int combine(struct arc *, struct arc *); +#define REPLACEARC 4 /* replace arc's color with constraint color */ +static int combine(struct nfa *nfa, struct arc *con, struct arc *a); static void fixempties(struct nfa *, FILE *); static struct state *emptyreachable(struct nfa *, struct state *, struct state *, struct arc **); @@ -174,6 +181,10 @@ static void cleanup(struct nfa *); static void markreachable(struct nfa *, struct state *, struct state *, struct state *); static void markcanreach(struct nfa *, struct state *, struct state *, struct state *); static long analyze(struct nfa *); +static void checkmatchall(struct nfa *); +static bool checkmatchall_recurse(struct nfa *, struct state *, bool **); +static bool check_out_colors_match(struct state *, color, color); +static bool check_in_colors_match(struct state *, color, color); static void compact(struct nfa *, struct cnfa *); static void carcsort(struct carc *, size_t); static int carc_cmp(const void *, const void *); @@ -199,6 +210,7 @@ static void freecvec(struct cvec *); static int pg_wc_isdigit(pg_wchar c); static int pg_wc_isalpha(pg_wchar c); static int pg_wc_isalnum(pg_wchar c); +static int pg_wc_isword(pg_wchar c); static int pg_wc_isupper(pg_wchar c); static int pg_wc_islower(pg_wchar c); static int pg_wc_isgraph(pg_wchar c); @@ -213,7 +225,8 @@ static chr element(struct vars *, const chr *, const chr *); static struct cvec *range(struct vars *, chr, chr, int); static int before(chr, chr); static struct cvec *eclass(struct vars *, chr, int); -static struct cvec *cclass(struct vars *, const chr *, const chr *, int); +static enum char_classes lookupcclass(struct vars *, const chr *, const chr *); +static struct cvec *cclasscvec(struct vars *, enum char_classes, int); static int cclass_column_index(struct colormap *, chr); static struct cvec *allcases(struct vars *, chr); static int cmp(const chr *, const chr *, size_t); @@ -226,14 +239,12 @@ struct vars regex_t *re; const chr *now; /* scan pointer into string */ const chr *stop; /* end of string */ - const chr *savenow; /* saved now and stop for "subroutine call" */ - const chr *savestop; int err; /* error code (0 if none) */ int cflags; /* copy of compile flags */ int lasttype; /* type of previous token */ int nexttype; /* type of next token */ chr nextvalue; /* value (if any) of next token */ - int lexcon; /* lexical context type (see lex.c) */ + int lexcon; /* lexical context type (see regc_lex.c) */ int nsubexp; /* subexpression count */ struct subre **subs; /* subRE pointer vector */ size_t nsubs; /* length of vector */ @@ -280,6 +291,8 @@ struct vars #define ECLASS 'E' /* start of [= */ #define CCLASS 'C' /* start of [: */ #define END 'X' /* end of [. [= [: */ +#define CCLASSS 's' /* char class shorthand escape */ +#define CCLASSC 'c' /* complement char class shorthand escape */ #define RANGE 'R' /* - within [] which might be range delim. */ #define LACON 'L' /* lookaround constraint subRE */ #define AHEAD 'a' /* color-lookahead arc */ @@ -289,9 +302,11 @@ struct vars #define SBEGIN 'A' /* beginning of string (even if not BOL) */ #define SEND 'Z' /* end of string (even if not EOL) */ -/* is an arc colored, and hence on a color chain? */ +/* is an arc colored, and hence should belong to a color chain? */ +/* the test on "co" eliminates RAINBOW arcs, which we don't bother to chain */ #define COLORED(a) \ - ((a)->type == PLAIN || (a)->type == AHEAD || (a)->type == BEHIND) + ((a)->co >= 0 && \ + ((a)->type == PLAIN || (a)->type == AHEAD || (a)->type == BEHIND)) /* static function list */ @@ -347,7 +362,6 @@ pg_regcomp(regex_t *re, v->re = re; v->now = string; v->stop = v->now + len; - v->savenow = v->savestop = NULL; v->err = 0; v->cflags = flags; v->nsubexp = 0; @@ -443,7 +457,7 @@ pg_regcomp(regex_t *re, #endif /* Prepend .* to pattern if it's a lookbehind LACON */ - nfanode(v, lasub, !LATYPE_IS_AHEAD(lasub->subno), debug); + nfanode(v, lasub, !LATYPE_IS_AHEAD(lasub->latype), debug); } CNOERR(); if (v->tree->flags & SHORTER) @@ -479,7 +493,10 @@ pg_regcomp(regex_t *re, #ifdef REG_DEBUG if (flags & REG_DUMP) + { dump(re, stdout); + fflush(stdout); + } #endif assert(v->err == 0); @@ -641,8 +658,8 @@ makesearch(struct vars *v, * parse - parse an RE * * This is actually just the top level, which parses a bunch of branches - * tied together with '|'. They appear in the tree as the left children - * of a chain of '|' subres. + * tied together with '|'. If there's more than one, they appear in the + * tree as the children of a '|' subre. */ static struct subre * parse(struct vars *v, @@ -651,41 +668,34 @@ parse(struct vars *v, struct state *init, /* initial state */ struct state *final) /* final state */ { - struct state *left; /* scaffolding for branch */ - struct state *right; struct subre *branches; /* top level */ - struct subre *branch; /* current branch */ - struct subre *t; /* temporary */ - int firstbranch; /* is this the first branch? */ + struct subre *lastbranch; /* latest branch */ assert(stopper == ')' || stopper == EOS); branches = subre(v, '|', LONGER, init, final); NOERRN(); - branch = branches; - firstbranch = 1; + lastbranch = NULL; do { /* a branch */ - if (!firstbranch) - { - /* need a place to hang it */ - branch->right = subre(v, '|', LONGER, init, final); - NOERRN(); - branch = branch->right; - } - firstbranch = 0; + struct subre *branch; + struct state *left; /* scaffolding for branch */ + struct state *right; + left = newstate(v->nfa); right = newstate(v->nfa); NOERRN(); EMPTYARC(init, left); EMPTYARC(right, final); NOERRN(); - branch->left = parsebranch(v, stopper, type, left, right, 0); + branch = parsebranch(v, stopper, type, left, right, 0); NOERRN(); - branch->flags |= UP(branch->flags | branch->left->flags); - if ((branch->flags & ~branches->flags) != 0) /* new flags */ - for (t = branches; t != branch; t = t->right) - t->flags |= branch->flags; + if (lastbranch) + lastbranch->sibling = branch; + else + branches->child = branch; + branches->flags |= UP(branches->flags | branch->flags); + lastbranch = branch; } while (EAT('|')); assert(SEE(stopper) || SEE(EOS)); @@ -696,20 +706,16 @@ parse(struct vars *v, } /* optimize out simple cases */ - if (branch == branches) + if (lastbranch == branches->child) { /* only one branch */ - assert(branch->right == NULL); - t = branch->left; - branch->left = NULL; - freesubre(v, branches); - branches = t; + assert(lastbranch->sibling == NULL); + freesrnode(v, branches); + branches = lastbranch; } else if (!MESSY(branches->flags)) { /* no interesting innards */ - freesubre(v, branches->left); - branches->left = NULL; - freesubre(v, branches->right); - branches->right = NULL; + freesubreandsiblings(v, branches->child); + branches->child = NULL; branches->op = '='; } @@ -721,7 +727,7 @@ parse(struct vars *v, * * This mostly manages concatenation, working closely with parseqatom(). * Concatenated things are bundled up as much as possible, with separate - * ',' nodes introduced only when necessary due to substructure. + * '.' nodes introduced only when necessary due to substructure. */ static struct subre * parsebranch(struct vars *v, @@ -834,23 +840,25 @@ parseqatom(struct vars *v, return; break; case '<': - wordchrs(v); /* does NEXT() */ + wordchrs(v); s = newstate(v->nfa); NOERR(); nonword(v, BEHIND, lp, s); word(v, AHEAD, s, rp); + NEXT(); return; break; case '>': - wordchrs(v); /* does NEXT() */ + wordchrs(v); s = newstate(v->nfa); NOERR(); word(v, BEHIND, lp, s); nonword(v, AHEAD, s, rp); + NEXT(); return; break; case WBDRY: - wordchrs(v); /* does NEXT() */ + wordchrs(v); s = newstate(v->nfa); NOERR(); nonword(v, BEHIND, lp, s); @@ -859,10 +867,11 @@ parseqatom(struct vars *v, NOERR(); word(v, BEHIND, lp, s); nonword(v, AHEAD, s, rp); + NEXT(); return; break; case NWBDRY: - wordchrs(v); /* does NEXT() */ + wordchrs(v); s = newstate(v->nfa); NOERR(); word(v, BEHIND, lp, s); @@ -871,6 +880,7 @@ parseqatom(struct vars *v, NOERR(); nonword(v, BEHIND, lp, s); nonword(v, AHEAD, s, rp); + NEXT(); return; break; case LACON: /* lookaround constraint */ @@ -924,6 +934,16 @@ parseqatom(struct vars *v, assert(SEE(']') || ISERR()); NEXT(); break; + case CCLASSS: + charclass(v, (enum char_classes) v->nextvalue, lp, rp); + okcolors(v->nfa, v->cm); + NEXT(); + break; + case CCLASSC: + charclasscomplement(v, (enum char_classes) v->nextvalue, lp, rp); + /* charclasscomplement() did okcolors() internally */ + NEXT(); + break; case '.': rainbow(v->nfa, v->cm, PLAIN, (v->cflags & REG_NLSTOP) ? v->nlcolor : COLORLESS, @@ -939,12 +959,17 @@ parseqatom(struct vars *v, subno = v->nsubexp; if ((size_t) subno >= v->nsubs) moresubs(v, subno); - assert((size_t) subno < v->nsubs); } else atomtype = PLAIN; /* something that's not '(' */ NEXT(); - /* need new endpoints because tree will contain pointers */ + + /* + * Make separate endpoints to ensure we keep this sub-NFA cleanly + * separate from what surrounds it. We need to be sure that when + * we duplicate the sub-NFA for a backref, we get the right states + * and no others. + */ s = newstate(v->nfa); s2 = newstate(v->nfa); NOERR(); @@ -957,12 +982,23 @@ parseqatom(struct vars *v, NOERR(); if (cap) { + assert(v->subs[subno] == NULL); v->subs[subno] = atom; - t = subre(v, '(', atom->flags | CAP, lp, rp); - NOERR(); - t->subno = subno; - t->left = atom; - atom = t; + if (atom->capno == 0) + { + /* normal case: just mark the atom as capturing */ + atom->flags |= CAP; + atom->capno = subno; + } + else + { + /* generate no-op wrapper node to handle "((x))" */ + t = subre(v, '(', atom->flags | CAP, lp, rp); + NOERR(); + t->capno = subno; + t->child = atom; + atom = t; + } } /* postpone everything else pending possible {0} */ break; @@ -975,7 +1011,7 @@ parseqatom(struct vars *v, atom = subre(v, 'b', BACKR, lp, rp); NOERR(); subno = v->nextvalue; - atom->subno = subno; + atom->backno = subno; EMPTYARC(lp, rp); /* temporarily, so there's something */ NEXT(); break; @@ -1109,17 +1145,28 @@ parseqatom(struct vars *v, /* break remaining subRE into x{...} and what follows */ t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp); NOERR(); - t->left = atom; - atomp = &t->left; + t->child = atom; + atomp = &t->child; - /* here we should recurse... but we must postpone that to the end */ + /* + * Here we should recurse to fill t->child->sibling ... but we must + * postpone that to the end. One reason is that t->child may be replaced + * below, and we don't want to worry about its sibling link. + */ - /* split top into prefix and remaining */ - assert(top->op == '=' && top->left == NULL && top->right == NULL); - top->left = subre(v, '=', top->flags, top->begin, lp); + /* + * Convert top node to a concatenation of the prefix (top->child, covering + * whatever we parsed previously) and remaining (t). Note that the prefix + * could be empty, in which case this concatenation node is unnecessary. + * To keep things simple, we operate in a general way for now, and get rid + * of unnecessary subres below. + */ + assert(top->op == '=' && top->child == NULL); + top->child = subre(v, '=', top->flags, top->begin, lp); NOERR(); top->op = '.'; - top->right = t; + top->child->sibling = t; + /* top->flags will get updated later */ /* if it's a backref, now is the time to replicate the subNFA */ if (atomtype == BACKREF) @@ -1136,6 +1183,10 @@ parseqatom(struct vars *v, dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end, atom->begin, atom->end); NOERR(); + + /* The backref node's NFA should not enforce any constraints */ + removeconstraints(v->nfa, atom->begin, atom->end); + NOERR(); } /* @@ -1164,6 +1215,23 @@ parseqatom(struct vars *v, /* rest of branch can be strung starting from atom->end */ s2 = atom->end; } + else if (!(atom->flags & (CAP | BACKR))) + { + /* + * If there's no captures nor backrefs in the atom being repeated, we + * don't really care where the submatches of the iteration are, so we + * don't need an iteration node. Make a plain DFA node instead. + */ + EMPTYARC(s, atom->begin); /* empty prefix */ + repeat(v, atom->begin, atom->end, m, n); + f = COMBINE(qprefer, atom->flags); + t = subre(v, '=', f, atom->begin, atom->end); + NOERR(); + freesubre(v, atom); + *atomp = t; + /* rest of branch can be strung starting from t->end */ + s2 = t->end; + } else if (m > 0 && !(atom->flags & BACKR)) { /* @@ -1180,9 +1248,9 @@ parseqatom(struct vars *v, f = COMBINE(qprefer, atom->flags); t = subre(v, '.', f, s, atom->end); /* prefix and atom */ NOERR(); - t->left = subre(v, '=', PREF(f), s, atom->begin); + t->child = subre(v, '=', PREF(f), s, atom->begin); NOERR(); - t->right = atom; + t->child->sibling = atom; *atomp = t; /* rest of branch can be strung starting from atom->end */ s2 = atom->end; @@ -1201,24 +1269,103 @@ parseqatom(struct vars *v, NOERR(); t->min = (short) m; t->max = (short) n; - t->left = atom; + t->child = atom; *atomp = t; /* rest of branch is to be strung from iteration's end state */ } /* and finally, look after that postponed recursion */ - t = top->right; + t = top->child->sibling; if (!(SEE('|') || SEE(stopper) || SEE(EOS))) - t->right = parsebranch(v, stopper, type, s2, rp, 1); + { + /* parse all the rest of the branch, and insert in t->child->sibling */ + t->child->sibling = parsebranch(v, stopper, type, s2, rp, 1); + NOERR(); + assert(SEE('|') || SEE(stopper) || SEE(EOS)); + + /* here's the promised update of the flags */ + t->flags |= COMBINE(t->flags, t->child->sibling->flags); + top->flags |= COMBINE(top->flags, t->flags); + + /* neither t nor top could be directly marked for capture as yet */ + assert(t->capno == 0); + assert(top->capno == 0); + + /* + * At this point both top and t are concatenation (op == '.') subres, + * and we have top->child = prefix of branch, top->child->sibling = t, + * t->child = messy atom (with quantification superstructure if + * needed), t->child->sibling = rest of branch. + * + * If the messy atom was the first thing in the branch, then + * top->child is vacuous and we can get rid of one level of + * concatenation. Since the caller is holding a pointer to the top + * node, we can't remove that node; but we're allowed to change its + * properties. + */ + assert(top->child->op == '='); + if (top->child->begin == top->child->end) + { + assert(!MESSY(top->child->flags)); + freesubre(v, top->child); + top->child = t->child; + freesrnode(v, t); + } + + /* + * Otherwise, it's possible that t->child is not messy in itself, but + * we considered it messy because its greediness conflicts with what + * preceded it. Then it could be that the combination of t->child and + * the rest of the branch is also not messy, in which case we can get + * rid of the child concatenation by merging t->child and the rest of + * the branch into one plain DFA node. + */ + else if (t->child->op == '=' && + t->child->sibling->op == '=' && + !MESSY(UP(t->child->flags | t->child->sibling->flags))) + { + t->op = '='; + t->flags = COMBINE(t->child->flags, t->child->sibling->flags); + freesubreandsiblings(v, t->child); + t->child = NULL; + } + } else { + /* + * There's nothing left in the branch, so we don't need the second + * concatenation node 't'. Just link s2 straight to rp. + */ EMPTYARC(s2, rp); - t->right = subre(v, '=', 0, s2, rp); + top->child->sibling = t->child; + top->flags |= COMBINE(top->flags, top->child->sibling->flags); + freesrnode(v, t); + + /* + * Again, it could be that top->child is vacuous (if the messy atom + * was in fact the only thing in the branch). In that case we need no + * concatenation at all; just replace top with top->child->sibling. + */ + assert(top->child->op == '='); + if (top->child->begin == top->child->end) + { + assert(!MESSY(top->child->flags)); + t = top->child->sibling; + freesubre(v, top->child); + top->op = t->op; + top->flags = t->flags; + top->latype = t->latype; + top->id = t->id; + top->capno = t->capno; + top->backno = t->backno; + top->min = t->min; + top->max = t->max; + top->child = t->child; + top->begin = t->begin; + top->end = t->end; + freesrnode(v, t); + } } - NOERR(); - assert(SEE('|') || SEE(stopper) || SEE(EOS)); - t->flags |= COMBINE(t->flags, t->right->flags); - top->flags |= COMBINE(top->flags, t->flags); } /* @@ -1253,6 +1400,71 @@ word(struct vars *v, /* (no need for special attention to \n) */ } +/* + * charclass - generate arcs for a character class + * + * This is used for both atoms (\w and sibling escapes) and for elements + * of bracket expressions. The caller is responsible for calling okcolors() + * at the end of processing the atom or bracket. + */ +static void +charclass(struct vars *v, + enum char_classes cls, + struct state *lp, + struct state *rp) +{ + struct cvec *cv; + + /* obtain possibly-cached cvec for char class */ + NOTE(REG_ULOCALE); + cv = cclasscvec(v, cls, (v->cflags & REG_ICASE)); + NOERR(); + + /* build the arcs; this may cause color splitting */ + subcolorcvec(v, cv, lp, rp); +} + +/* + * charclasscomplement - generate arcs for a complemented character class + * + * This is used for both atoms (\W and sibling escapes) and for elements + * of bracket expressions. In bracket expressions, it is the caller's + * responsibility that there not be any open subcolors when this is called. + */ +static void +charclasscomplement(struct vars *v, + enum char_classes cls, + struct state *lp, + struct state *rp) +{ + struct state *cstate; + struct cvec *cv; + + /* make dummy state to hang temporary arcs on */ + cstate = newstate(v->nfa); + NOERR(); + + /* obtain possibly-cached cvec for char class */ + NOTE(REG_ULOCALE); + cv = cclasscvec(v, cls, (v->cflags & REG_ICASE)); + NOERR(); + + /* build arcs for char class; this may cause color splitting */ + subcolorcvec(v, cv, cstate, cstate); + NOERR(); + + /* clean up any subcolors in the arc set */ + okcolors(v->nfa, v->cm); + NOERR(); + + /* now build output arcs for the complement of the char class */ + colorcomplement(v->nfa, v->cm, PLAIN, cstate, lp, rp); + NOERR(); + + /* clean up dummy state */ + dropstate(v->nfa, cstate); +} + /* * scannum - scan a number */ @@ -1371,6 +1583,7 @@ repeat(struct vars *v, /* * bracket - handle non-complemented bracket expression + * * Also called from cbracket for complemented bracket expressions. */ static void @@ -1378,19 +1591,56 @@ bracket(struct vars *v, struct state *lp, struct state *rp) { + /* + * We can't process complemented char classes (e.g. \W) immediately while + * scanning the bracket expression, else color bookkeeping gets confused. + * Instead, remember whether we saw any in have_cclassc[], and process + * them at the end. + */ + bool have_cclassc[NUM_CCLASSES]; + bool any_cclassc; + int i; + + memset(have_cclassc, false, sizeof(have_cclassc)); + assert(SEE('[')); NEXT(); while (!SEE(']') && !SEE(EOS)) - brackpart(v, lp, rp); + brackpart(v, lp, rp, have_cclassc); assert(SEE(']') || ISERR()); + + /* close up open subcolors from the positive bracket elements */ okcolors(v->nfa, v->cm); + NOERR(); + + /* now handle any complemented elements */ + any_cclassc = false; + for (i = 0; i < NUM_CCLASSES; i++) + { + if (have_cclassc[i]) + { + charclasscomplement(v, (enum char_classes) i, lp, rp); + NOERR(); + any_cclassc = true; + } + } + + /* + * If we had any complemented elements, see if we can optimize the bracket + * into a rainbow. Since a complemented element is the only way a WHITE + * arc could get into the result, there's no point in checking otherwise. + */ + if (any_cclassc) + optimizebracket(v, lp, rp); } /* * cbracket - handle complemented bracket expression + * * We do it by calling bracket() with dummy endpoints, and then complementing * the result. The alternative would be to invoke rainbow(), and then delete - * arcs as the b.e. is seen... but that gets messy. + * arcs as the b.e. is seen... but that gets messy, and is really quite + * infeasible now that rainbow() just puts out one RAINBOW arc. */ static void cbracket(struct vars *v, @@ -1402,6 +1652,8 @@ cbracket(struct vars *v, NOERR(); bracket(v, left, right); + + /* in NLSTOP mode, ensure newline is not part of the result set */ if (v->cflags & REG_NLSTOP) newarc(v->nfa, PLAIN, v->nlcolor, left, right); NOERR(); @@ -1410,7 +1662,9 @@ cbracket(struct vars *v, /* * Easy part of complementing, and all there is to do since the MCCE code - * was removed. + * was removed. Note that the result of colorcomplement() cannot be a + * rainbow, since we don't allow empty brackets; so there's no point in + * calling optimizebracket() again. */ colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp); NOERR(); @@ -1425,14 +1679,15 @@ cbracket(struct vars *v, static void brackpart(struct vars *v, struct state *lp, - struct state *rp) + struct state *rp, + bool *have_cclassc) { chr startc; chr endc; struct cvec *cv; + enum char_classes cls; const chr *startp; const chr *endp; - chr c[1]; /* parse something, get rid of special cases, take shortcuts */ switch (v->nexttype) @@ -1442,15 +1697,14 @@ brackpart(struct vars *v, return; break; case PLAIN: - c[0] = v->nextvalue; + startc = v->nextvalue; NEXT(); /* shortcut for ordinary chr (not range) */ if (!SEE(RANGE)) { - onechr(v, c[0], lp, rp); + onechr(v, startc, lp, rp); return; } - startc = element(v, c, c + 1); NOERR(); break; case COLLEL: @@ -1478,9 +1732,20 @@ brackpart(struct vars *v, endp = scanplain(v); INSIST(startp < endp, REG_ECTYPE); NOERR(); - cv = cclass(v, startp, endp, (v->cflags & REG_ICASE)); + cls = lookupcclass(v, startp, endp); NOERR(); - subcolorcvec(v, cv, lp, rp); + charclass(v, cls, lp, rp); + return; + break; + case CCLASSS: + charclass(v, (enum char_classes) v->nextvalue, lp, rp); + NEXT(); + return; + break; + case CCLASSC: + /* we cannot call charclasscomplement() immediately */ + have_cclassc[v->nextvalue] = true; + NEXT(); return; break; default: @@ -1496,9 +1761,8 @@ brackpart(struct vars *v, { case PLAIN: case RANGE: - c[0] = v->nextvalue; + endc = v->nextvalue; NEXT(); - endc = element(v, c, c + 1); NOERR(); break; case COLLEL: @@ -1532,7 +1796,7 @@ brackpart(struct vars *v, /* * scanplain - scan PLAIN contents of [. etc. * - * Certain bits of trickery in lex.c know that this code does not try + * Certain bits of trickery in regc_lex.c know that this code does not try * to look past the final bracket of the [. etc. */ static const chr * /* just after end of sequence */ @@ -1578,39 +1842,98 @@ onechr(struct vars *v, subcolorcvec(v, allcases(v, c), lp, rp); } +/* + * optimizebracket - see if bracket expression can be converted to RAINBOW + * + * Cases such as "[\s\S]" can produce a set of arcs of all colors, which we + * can replace by a single RAINBOW arc for efficiency. (This might seem + * like a silly way to write ".", but it's seemingly a common locution in + * some other flavors of regex, so take the trouble to support it well.) + */ +static void +optimizebracket(struct vars *v, + struct state *lp, + struct state *rp) +{ + struct colordesc *cd; + struct colordesc *end = CDEND(v->cm); + struct arc *a; + bool israinbow; + + /* + * Scan lp's out-arcs and transiently mark the mentioned colors. We + * expect that all of lp's out-arcs are plain, non-RAINBOW arcs to rp. + * (Note: there shouldn't be any pseudocolors yet, but check anyway.) + */ + for (a = lp->outs; a != NULL; a = a->outchain) + { + assert(a->type == PLAIN); + assert(a->co >= 0); /* i.e. not RAINBOW */ + assert(a->to == rp); + cd = &v->cm->cd[a->co]; + assert(!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO)); + cd->flags |= COLMARK; + } + + /* Scan colors, clear transient marks, check for unmarked live colors */ + israinbow = true; + for (cd = v->cm->cd; cd < end; cd++) + { + if (cd->flags & COLMARK) + cd->flags &= ~COLMARK; + else if (!UNUSEDCOLOR(cd) && !(cd->flags & PSEUDO)) + israinbow = false; + } + + /* Can't do anything if not all colors have arcs */ + if (!israinbow) + return; + + /* OK, drop existing arcs and replace with a rainbow */ + while ((a = lp->outs) != NULL) + freearc(v->nfa, a); + newarc(v->nfa, PLAIN, RAINBOW, lp, rp); +} + /* * wordchrs - set up word-chr list for word-boundary stuff, if needed * - * The list is kept as a bunch of arcs between two dummy states; it's - * disposed of by the unreachable-states sweep in NFA optimization. - * Does NEXT(). Must not be called from any unusual lexical context. - * This should be reconciled with the \w etc. handling in lex.c, and - * should be cleaned up to reduce dependencies on input scanning. + * The list is kept as a bunch of circular arcs on an otherwise-unused state. + * + * Note that this must not be called while we have any open subcolors, + * else construction of the list would confuse color bookkeeping. + * Hence, we can't currently apply a similar optimization in + * charclass[complement](), as those need to be usable within bracket + * expressions. */ static void wordchrs(struct vars *v) { - struct state *left; - struct state *right; + struct state *cstate; + struct cvec *cv; if (v->wordchrs != NULL) - { - NEXT(); /* for consistency */ - return; - } + return; /* done already */ - left = newstate(v->nfa); - right = newstate(v->nfa); + /* make dummy state to hang the cache arcs on */ + cstate = newstate(v->nfa); NOERR(); - /* fine point: implemented with [::], and lexer will set REG_ULOCALE */ - lexword(v); - NEXT(); - assert(v->savenow != NULL && SEE('[')); - bracket(v, left, right); - assert((v->savenow != NULL && SEE(']')) || ISERR()); - NEXT(); + + /* obtain possibly-cached cvec for \w characters */ + NOTE(REG_ULOCALE); + cv = cclasscvec(v, CC_WORD, (v->cflags & REG_ICASE)); + NOERR(); + + /* build the arcs; this may cause color splitting */ + subcolorcvec(v, cv, cstate, cstate); NOERR(); - v->wordchrs = left; + + /* close new open subcolors to ensure the cache entry is self-contained */ + okcolors(v->nfa, v->cm); + NOERR(); + + /* success! save the cache pointer */ + v->wordchrs = cstate; } /* @@ -1705,7 +2028,7 @@ subre(struct vars *v, } if (ret != NULL) - v->treefree = ret->left; + v->treefree = ret->child; else { ret = (struct subre *) MALLOC(sizeof(struct subre)); @@ -1722,11 +2045,13 @@ subre(struct vars *v, ret->op = op; ret->flags = flags; + ret->latype = (char) -1; ret->id = 0; /* will be assigned later */ - ret->subno = 0; + ret->capno = 0; + ret->backno = 0; ret->min = ret->max = 1; - ret->left = NULL; - ret->right = NULL; + ret->child = NULL; + ret->sibling = NULL; ret->begin = begin; ret->end = end; ZAPCNFA(ret->cnfa); @@ -1736,6 +2061,9 @@ subre(struct vars *v, /* * freesubre - free a subRE subtree + * + * This frees child node(s) of the given subRE too, + * but not its siblings. */ static void freesubre(struct vars *v, /* might be NULL */ @@ -1744,14 +2072,31 @@ freesubre(struct vars *v, /* might be NULL */ if (sr == NULL) return; - if (sr->left != NULL) - freesubre(v, sr->left); - if (sr->right != NULL) - freesubre(v, sr->right); + if (sr->child != NULL) + freesubreandsiblings(v, sr->child); freesrnode(v, sr); } +/* + * freesubreandsiblings - free a subRE subtree + * + * This frees child node(s) of the given subRE too, + * as well as any following siblings. + */ +static void +freesubreandsiblings(struct vars *v, /* might be NULL */ + struct subre *sr) +{ + while (sr != NULL) + { + struct subre *next = sr->sibling; + + freesubre(v, sr); + sr = next; + } +} + /* * freesrnode - free one node in a subRE subtree */ @@ -1769,7 +2114,7 @@ freesrnode(struct vars *v, /* might be NULL */ if (v != NULL && v->treechain != NULL) { /* we're still parsing, maybe we can reuse the subre */ - sr->left = v->treefree; + sr->child = v->treefree; v->treefree = sr; } else @@ -1800,15 +2145,14 @@ numst(struct subre *t, int start) /* starting point for subtree numbers */ { int i; + struct subre *t2; assert(t != NULL); i = start; - t->id = (short) i++; - if (t->left != NULL) - i = numst(t->left, i); - if (t->right != NULL) - i = numst(t->right, i); + t->id = i++; + for (t2 = t->child; t2 != NULL; t2 = t2->sibling) + i = numst(t2, i); return i; } @@ -1832,13 +2176,13 @@ numst(struct subre *t, static void markst(struct subre *t) { + struct subre *t2; + assert(t != NULL); t->flags |= INUSE; - if (t->left != NULL) - markst(t->left); - if (t->right != NULL) - markst(t->right); + for (t2 = t->child; t2 != NULL; t2 = t2->sibling) + markst(t2); } /* @@ -1868,12 +2212,12 @@ nfatree(struct vars *v, struct subre *t, FILE *f) /* for debug output */ { + struct subre *t2; + assert(t != NULL && t->begin != NULL); - if (t->left != NULL) - (DISCARD) nfatree(v, t->left, f); - if (t->right != NULL) - (DISCARD) nfatree(v, t->right, f); + for (t2 = t->child; t2 != NULL; t2 = t2->sibling) + (DISCARD) nfatree(v, t2, f); return nfanode(v, t, 0, f); } @@ -1953,7 +2297,7 @@ newlacon(struct vars *v, sub = &v->lacons[n]; sub->begin = begin; sub->end = end; - sub->subno = latype; + sub->latype = latype; ZAPCNFA(sub->cnfa); return n; } @@ -2076,7 +2420,7 @@ dump(regex_t *re, struct subre *lasub = &g->lacons[i]; const char *latype; - switch (lasub->subno) + switch (lasub->latype) { case LATYPE_AHEAD_POS: latype = "positive lookahead"; @@ -2125,6 +2469,7 @@ stdump(struct subre *t, int nfapresent) /* is the original NFA still around? */ { char idbuf[50]; + struct subre *t2; fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op); if (t->flags & LONGER) @@ -2139,8 +2484,12 @@ stdump(struct subre *t, fprintf(f, " hasbackref"); if (!(t->flags & INUSE)) fprintf(f, " UNUSED"); - if (t->subno != 0) - fprintf(f, " (#%d)", t->subno); + if (t->latype != (char) -1) + fprintf(f, " latype(%d)", t->latype); + if (t->capno != 0) + fprintf(f, " capture(%d)", t->capno); + if (t->backno != 0) + fprintf(f, " backref(%d)", t->backno); if (t->min != 1 || t->max != 1) { fprintf(f, " {%d,", t->min); @@ -2150,20 +2499,21 @@ stdump(struct subre *t, } if (nfapresent) fprintf(f, " %ld-%ld", (long) t->begin->no, (long) t->end->no); - if (t->left != NULL) - fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf))); - if (t->right != NULL) - fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf))); + if (t->child != NULL) + fprintf(f, " C:%s", stid(t->child, idbuf, sizeof(idbuf))); + /* printing second child isn't necessary, but it is often helpful */ + if (t->child != NULL && t->child->sibling != NULL) + fprintf(f, " C2:%s", stid(t->child->sibling, idbuf, sizeof(idbuf))); + if (t->sibling != NULL) + fprintf(f, " S:%s", stid(t->sibling, idbuf, sizeof(idbuf))); if (!NULLCNFA(t->cnfa)) { fprintf(f, "\n"); dumpcnfa(&t->cnfa, f); } fprintf(f, "\n"); - if (t->left != NULL) - stdump(t->left, f, nfapresent); - if (t->right != NULL) - stdump(t->right, f, nfapresent); + for (t2 = t->child; t2 != NULL; t2 = t2->sibling) + stdump(t2, f, nfapresent); } /* diff --git a/src/backend/regex/rege_dfa.c b/src/backend/regex/rege_dfa.c index 41bf6efb2716..1d56a108bdee 100644 --- a/src/backend/regex/rege_dfa.c +++ b/src/backend/regex/rege_dfa.c @@ -58,6 +58,42 @@ longest(struct vars *v, if (hitstopp != NULL) *hitstopp = 0; + /* if this is a backref to a known string, just match against that */ + if (d->backno >= 0) + { + assert((size_t) d->backno < v->nmatch); + if (v->pmatch[d->backno].rm_so >= 0) + { + cp = dfa_backref(v, d, start, start, stop, false); + if (cp == v->stop && stop == v->stop && hitstopp != NULL) + *hitstopp = 1; + return cp; + } + } + + /* fast path for matchall NFAs */ + if (d->cnfa->flags & MATCHALL) + { + size_t nchr = stop - start; + size_t maxmatchall = d->cnfa->maxmatchall; + + if (nchr < d->cnfa->minmatchall) + return NULL; + if (maxmatchall == DUPINF) + { + if (stop == v->stop && hitstopp != NULL) + *hitstopp = 1; + } + else + { + if (stop == v->stop && nchr <= maxmatchall + 1 && hitstopp != NULL) + *hitstopp = 1; + if (nchr > maxmatchall) + return start + maxmatchall; + } + return stop; + } + /* initialize */ css = initialize(v, d, start); if (css == NULL) @@ -187,6 +223,38 @@ shortest(struct vars *v, if (hitstopp != NULL) *hitstopp = 0; + /* if this is a backref to a known string, just match against that */ + if (d->backno >= 0) + { + assert((size_t) d->backno < v->nmatch); + if (v->pmatch[d->backno].rm_so >= 0) + { + cp = dfa_backref(v, d, start, min, max, true); + if (cp != NULL && coldp != NULL) + *coldp = start; + /* there is no case where we should set *hitstopp */ + return cp; + } + } + + /* fast path for matchall NFAs */ + if (d->cnfa->flags & MATCHALL) + { + size_t nchr = min - start; + + if (d->cnfa->maxmatchall != DUPINF && + nchr > d->cnfa->maxmatchall) + return NULL; + if ((max - start) < d->cnfa->minmatchall) + return NULL; + if (nchr < d->cnfa->minmatchall) + min = start + d->cnfa->minmatchall; + if (coldp != NULL) + *coldp = start; + /* there is no case where we should set *hitstopp */ + return min; + } + /* initialize */ css = initialize(v, d, start); if (css == NULL) @@ -312,6 +380,22 @@ matchuntil(struct vars *v, struct sset *ss; struct colormap *cm = d->cm; + /* fast path for matchall NFAs */ + if (d->cnfa->flags & MATCHALL) + { + size_t nchr = probe - v->start; + + /* + * It might seem that we should check maxmatchall too, but the .* at + * the front of the pattern absorbs any extra characters (and it was + * tacked on *after* computing minmatchall/maxmatchall). Thus, we + * should match if there are at least minmatchall characters. + */ + if (nchr < d->cnfa->minmatchall) + return 0; + return 1; + } + /* initialize and startup, or restart, if necessary */ if (cp == NULL || cp > probe) { @@ -410,6 +494,94 @@ matchuntil(struct vars *v, return 1; } +/* + * dfa_backref - find best match length for a known backref string + * + * When the backref's referent is already available, we can deliver an exact + * answer with considerably less work than running the backref node's NFA. + * + * Return match endpoint for longest or shortest valid repeated match, + * or NULL if there is no valid match. + * + * Should be in sync with cbrdissect(), although that has the different task + * of checking a match to a predetermined section of the string. + */ +static chr * +dfa_backref(struct vars *v, + struct dfa *d, + chr *start, /* where the match should start */ + chr *min, /* match must end at or after here */ + chr *max, /* match must end at or before here */ + bool shortest) +{ + int n = d->backno; + int backmin = d->backmin; + int backmax = d->backmax; + size_t numreps; + size_t minreps; + size_t maxreps; + size_t brlen; + chr *brstring; + chr *p; + + /* get the backreferenced string (caller should have checked this) */ + if (v->pmatch[n].rm_so == -1) + return NULL; + brstring = v->start + v->pmatch[n].rm_so; + brlen = v->pmatch[n].rm_eo - v->pmatch[n].rm_so; + + /* special-case zero-length backreference to avoid divide by zero */ + if (brlen == 0) + { + /* + * matches only a zero-length string, but any number of repetitions + * can be considered to be present + */ + if (min == start && backmin <= backmax) + return start; + return NULL; + } + + /* + * convert min and max into numbers of possible repetitions of the backref + * string, rounding appropriately + */ + if (min <= start) + minreps = 0; + else + minreps = (min - start - 1) / brlen + 1; + maxreps = (max - start) / brlen; + + /* apply bounds, then see if there is any allowed match length */ + if (minreps < backmin) + minreps = backmin; + if (backmax != DUPINF && maxreps > backmax) + maxreps = backmax; + if (maxreps < minreps) + return NULL; + + /* quick exit if zero-repetitions match is valid and preferred */ + if (shortest && minreps == 0) + return start; + + /* okay, compare the actual string contents */ + p = start; + numreps = 0; + while (numreps < maxreps) + { + if ((*v->g->compare) (brstring, p, brlen) != 0) + break; + p += brlen; + numreps++; + if (shortest && numreps >= minreps) + break; + } + + if (numreps >= minreps) + return p; + return NULL; +} + /* * lastcold - determine last point at which no progress had been made */ @@ -432,6 +604,8 @@ lastcold(struct vars *v, /* * newdfa - set up a fresh DFA + * + * Returns NULL (and sets v->err) on failure. */ static struct dfa * newdfa(struct vars *v, @@ -442,7 +616,7 @@ newdfa(struct vars *v, struct dfa *d; size_t nss = cnfa->nstates * 2; int wordsper = (cnfa->nstates + UBITS - 1) / UBITS; - struct smalldfa *smallwas = sml; + bool ismalloced = false; assert(cnfa != NULL && cnfa->nstates != 0); @@ -457,6 +631,7 @@ newdfa(struct vars *v, ERR(REG_ESPACE); return NULL; } + ismalloced = true; } d = &sml->dfa; d->ssets = sml->ssets; @@ -464,8 +639,8 @@ newdfa(struct vars *v, d->work = &d->statesarea[nss]; d->outsarea = sml->outsarea; d->incarea = sml->incarea; - d->cptsmalloced = 0; - d->mallocarea = (smallwas == NULL) ? (char *) sml : NULL; + d->ismalloced = ismalloced; + d->arraysmalloced = false; /* not separately allocated, anyway */ } else { @@ -483,8 +658,9 @@ newdfa(struct vars *v, sizeof(struct sset *)); d->incarea = (struct arcp *) MALLOC(nss * cnfa->ncolors * sizeof(struct arcp)); - d->cptsmalloced = 1; - d->mallocarea = (char *) d; + d->ismalloced = true; + d->arraysmalloced = true; + /* now freedfa() will behave sanely */ if (d->ssets == NULL || d->statesarea == NULL || d->outsarea == NULL || d->incarea == NULL) { @@ -504,6 +680,8 @@ newdfa(struct vars *v, d->lastpost = NULL; d->lastnopr = NULL; d->search = d->ssets; + d->backno = -1; /* may be set by caller */ + d->backmin = d->backmax = 0; /* initialization of sset fields is done as needed */ @@ -516,7 +694,7 @@ newdfa(struct vars *v, static void freedfa(struct dfa *d) { - if (d->cptsmalloced) + if (d->arraysmalloced) { if (d->ssets != NULL) FREE(d->ssets); @@ -528,8 +706,8 @@ freedfa(struct dfa *d) FREE(d->incarea); } - if (d->mallocarea != NULL) - FREE(d->mallocarea); + if (d->ismalloced) + FREE(d); } /* @@ -612,6 +790,7 @@ miss(struct vars *v, unsigned h; struct carc *ca; struct sset *p; + int ispseudocolor; int ispost; int noprogress; int gotstate; @@ -643,13 +822,15 @@ miss(struct vars *v, */ for (i = 0; i < d->wordsper; i++) d->work[i] = 0; /* build new stateset bitmap in d->work */ + ispseudocolor = d->cm->cd[co].flags & PSEUDO; ispost = 0; noprogress = 1; gotstate = 0; for (i = 0; i < d->nstates; i++) if (ISBSET(css->states, i)) for (ca = cnfa->states[i]; ca->co != COLORLESS; ca++) - if (ca->co == co) + if (ca->co == co || + (ca->co == RAINBOW && !ispseudocolor)) { BSET(d->work, ca->to); gotstate = 1; @@ -772,12 +953,12 @@ lacon(struct vars *v, d = getladfa(v, n); if (d == NULL) return 0; - if (LATYPE_IS_AHEAD(sub->subno)) + if (LATYPE_IS_AHEAD(sub->latype)) { /* used to use longest() here, but shortest() could be much cheaper */ end = shortest(v, d, cp, cp, v->stop, (chr **) NULL, (int *) NULL); - satisfied = LATYPE_IS_POS(sub->subno) ? (end != NULL) : (end == NULL); + satisfied = LATYPE_IS_POS(sub->latype) ? (end != NULL) : (end == NULL); } else { @@ -790,7 +971,7 @@ lacon(struct vars *v, * nominal match. */ satisfied = matchuntil(v, d, cp, &v->lblastcss[n], &v->lblastcp[n]); - if (!LATYPE_IS_POS(sub->subno)) + if (!LATYPE_IS_POS(sub->latype)) satisfied = !satisfied; } FDEBUG(("=== lacon %d satisfied %d\n", n, satisfied)); diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c index f7eaa76b02c2..5b9a08782032 100644 --- a/src/backend/regex/regexec.c +++ b/src/backend/regex/regexec.c @@ -77,8 +77,11 @@ struct dfa chr *lastpost; /* location of last cache-flushed success */ chr *lastnopr; /* location of last cache-flushed NOPROGRESS */ struct sset *search; /* replacement-search-pointer memory */ - int cptsmalloced; /* were the areas individually malloced? */ - char *mallocarea; /* self, or master malloced area, or NULL */ + int backno; /* if DFA for a backref, subno it refers to */ + short backmin; /* min repetitions for backref */ + short backmax; /* max repetitions for backref */ + bool ismalloced; /* should this struct dfa be freed? */ + bool arraysmalloced; /* should its subsidiary arrays be freed? */ }; #define WORK 1 /* number of work bitvectors needed */ @@ -88,7 +91,7 @@ struct dfa #define FEWCOLORS 15 struct smalldfa { - struct dfa dfa; + struct dfa dfa; /* must be first */ struct sset ssets[FEWSTATES * 2]; unsigned statesarea[FEWSTATES * 2 + WORK]; struct sset *outsarea[FEWSTATES * 2 * FEWCOLORS]; @@ -154,6 +157,7 @@ static int creviterdissect(struct vars *, struct subre *, chr *, chr *); static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *); static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *, chr **, int *); static int matchuntil(struct vars *, struct dfa *, chr *, struct sset **, chr **); +static chr *dfa_backref(struct vars *, struct dfa *, chr *, chr *, chr *, bool); static chr *lastcold(struct vars *, struct dfa *); static struct dfa *newdfa(struct vars *, struct cnfa *, struct colormap *, struct smalldfa *); static void freedfa(struct dfa *); @@ -324,6 +328,11 @@ pg_regexec(regex_t *re, if (v->lblastcp != NULL) FREE(v->lblastcp); +#ifdef REG_DEBUG + if (v->eflags & (REG_FTRACE | REG_MTRACE)) + fflush(stdout); +#endif + return st; } @@ -337,13 +346,23 @@ static struct dfa * getsubdfa(struct vars *v, struct subre *t) { - if (v->subdfas[t->id] == NULL) + struct dfa *d = v->subdfas[t->id]; + + if (d == NULL) { - v->subdfas[t->id] = newdfa(v, &t->cnfa, &v->g->cmap, DOMALLOC); - if (ISERR()) + d = newdfa(v, &t->cnfa, &v->g->cmap, DOMALLOC); + if (d == NULL) return NULL; + /* set up additional info if this is a backref node */ + if (t->op == 'b') + { + d->backno = t->backno; + d->backmin = t->min; + d->backmax = t->max; + } + v->subdfas[t->id] = d; } - return v->subdfas[t->id]; + return d; } /* @@ -362,8 +381,7 @@ getladfa(struct vars *v, struct subre *sub = &v->g->lacons[n]; v->ladfas[n] = newdfa(v, &sub->cnfa, &v->g->cmap, DOMALLOC); - if (ISERR()) - return NULL; + /* a LACON can't contain a backref, so nothing else to do */ } return v->ladfas[n]; } @@ -388,8 +406,8 @@ find(struct vars *v, /* first, a shot with the search RE */ s = newdfa(v, &v->g->search, cm, &v->dfa1); - assert(!(ISERR() && s != NULL)); - NOERR(); + if (s == NULL) + return v->err; MDEBUG(("\nsearch at %ld\n", LOFF(v->start))); cold = NULL; close = shortest(v, s, v->search_start, v->search_start, v->stop, @@ -416,8 +434,8 @@ find(struct vars *v, cold = NULL; MDEBUG(("between %ld and %ld\n", LOFF(open), LOFF(close))); d = newdfa(v, cnfa, cm, &v->dfa1); - assert(!(ISERR() && d != NULL)); - NOERR(); + if (d == NULL) + return v->err; for (begin = open; begin <= close; begin++) { MDEBUG(("\nfind trying at %ld\n", LOFF(begin))); @@ -473,11 +491,11 @@ cfind(struct vars *v, int ret; s = newdfa(v, &v->g->search, cm, &v->dfa1); - NOERR(); + if (s == NULL) + return v->err; d = newdfa(v, cnfa, cm, &v->dfa2); - if (ISERR()) + if (d == NULL) { - assert(d == NULL); freedfa(s); return v->err; } @@ -635,11 +653,11 @@ static void zaptreesubs(struct vars *v, struct subre *t) { - if (t->op == '(') - { - int n = t->subno; + int n = t->capno; + struct subre *t2; - assert(n > 0); + if (n > 0) + { if ((size_t) n < v->nmatch) { v->pmatch[n].rm_so = -1; @@ -647,10 +665,8 @@ zaptreesubs(struct vars *v, } } - if (t->left != NULL) - zaptreesubs(v, t->left); - if (t->right != NULL) - zaptreesubs(v, t->right); + for (t2 = t->child; t2 != NULL; t2 = t2->sibling) + zaptreesubs(v, t2); } /* @@ -662,13 +678,13 @@ subset(struct vars *v, chr *begin, chr *end) { - int n = sub->subno; + int n = sub->capno; assert(n > 0); if ((size_t) n >= v->nmatch) return; - MDEBUG(("setting %d\n", n)); + MDEBUG(("%d: setting %d = %ld-%ld\n", sub->id, n, LOFF(begin), LOFF(end))); v->pmatch[n].rm_so = OFF(begin); v->pmatch[n].rm_eo = OFF(end); } @@ -697,7 +713,7 @@ cdissect(struct vars *v, int er; assert(t != NULL); - MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op)); + MDEBUG(("%d: cdissect %c %ld-%ld\n", t->id, t->op, LOFF(begin), LOFF(end))); /* handy place to check for operation cancel */ if (CANCEL_REQUESTED(v->re)) @@ -709,37 +725,35 @@ cdissect(struct vars *v, switch (t->op) { case '=': /* terminal node */ - assert(t->left == NULL && t->right == NULL); + assert(t->child == NULL); er = REG_OKAY; /* no action, parent did the work */ break; case 'b': /* back reference */ - assert(t->left == NULL && t->right == NULL); + assert(t->child == NULL); er = cbrdissect(v, t, begin, end); break; case '.': /* concatenation */ - assert(t->left != NULL && t->right != NULL); - if (t->left->flags & SHORTER) /* reverse scan */ + assert(t->child != NULL); + if (t->child->flags & SHORTER) /* reverse scan */ er = crevcondissect(v, t, begin, end); else er = ccondissect(v, t, begin, end); break; case '|': /* alternation */ - assert(t->left != NULL); + assert(t->child != NULL); er = caltdissect(v, t, begin, end); break; case '*': /* iteration */ - assert(t->left != NULL); - if (t->left->flags & SHORTER) /* reverse scan */ + assert(t->child != NULL); + if (t->child->flags & SHORTER) /* reverse scan */ er = creviterdissect(v, t, begin, end); else er = citerdissect(v, t, begin, end); break; - case '(': /* capturing */ - assert(t->left != NULL && t->right == NULL); - assert(t->subno > 0); - er = cdissect(v, t->left, begin, end); - if (er == REG_OKAY) - subset(v, t, begin, end); + case '(': /* no-op capture node */ + assert(t->child != NULL); + assert(t->capno > 0); + er = cdissect(v, t->child, begin, end); break; default: er = REG_ASSERT; @@ -753,6 +767,12 @@ cdissect(struct vars *v, */ assert(er != REG_NOMATCH || (t->flags & BACKR)); + /* + * If this node is marked as capturing, save successful match's location. + */ + if (t->capno > 0 && er == REG_OKAY) + subset(v, t, begin, end); + return er; } @@ -765,28 +785,31 @@ ccondissect(struct vars *v, chr *begin, /* beginning of relevant substring */ chr *end) /* end of same */ { + struct subre *left = t->child; + struct subre *right = left->sibling; struct dfa *d; struct dfa *d2; chr *mid; int er; assert(t->op == '.'); - assert(t->left != NULL && t->left->cnfa.nstates > 0); - assert(t->right != NULL && t->right->cnfa.nstates > 0); - assert(!(t->left->flags & SHORTER)); + assert(left != NULL && left->cnfa.nstates > 0); + assert(right != NULL && right->cnfa.nstates > 0); + assert(right->sibling == NULL); + assert(!(left->flags & SHORTER)); - d = getsubdfa(v, t->left); + d = getsubdfa(v, left); NOERR(); - d2 = getsubdfa(v, t->right); + d2 = getsubdfa(v, right); NOERR(); - MDEBUG(("cconcat %d\n", t->id)); + MDEBUG(("%d: ccondissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end))); /* pick a tentative midpoint */ mid = longest(v, d, begin, end, (int *) NULL); NOERR(); if (mid == NULL) return REG_NOMATCH; - MDEBUG(("tentative midpoint %ld\n", LOFF(mid))); + MDEBUG(("%d: tentative midpoint %ld\n", t->id, LOFF(mid))); /* iterate until satisfaction or failure */ for (;;) @@ -794,14 +817,14 @@ ccondissect(struct vars *v, /* try this midpoint on for size */ if (longest(v, d2, mid, end, (int *) NULL) == end) { - er = cdissect(v, t->left, begin, mid); + er = cdissect(v, left, begin, mid); if (er == REG_OKAY) { - er = cdissect(v, t->right, mid, end); + er = cdissect(v, right, mid, end); if (er == REG_OKAY) { /* satisfaction */ - MDEBUG(("successful\n")); + MDEBUG(("%d: successful\n", t->id)); return REG_OKAY; } } @@ -814,7 +837,7 @@ ccondissect(struct vars *v, if (mid == begin) { /* all possibilities exhausted */ - MDEBUG(("%d no midpoint\n", t->id)); + MDEBUG(("%d: no midpoint\n", t->id)); return REG_NOMATCH; } mid = longest(v, d, begin, mid - 1, (int *) NULL); @@ -822,12 +845,12 @@ ccondissect(struct vars *v, if (mid == NULL) { /* failed to find a new one */ - MDEBUG(("%d failed midpoint\n", t->id)); + MDEBUG(("%d: failed midpoint\n", t->id)); return REG_NOMATCH; } MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid))); - zaptreesubs(v, t->left); - zaptreesubs(v, t->right); + zaptreesubs(v, left); + zaptreesubs(v, right); } /* can't get here */ @@ -843,28 +866,31 @@ crevcondissect(struct vars *v, chr *begin, /* beginning of relevant substring */ chr *end) /* end of same */ { + struct subre *left = t->child; + struct subre *right = left->sibling; struct dfa *d; struct dfa *d2; chr *mid; int er; assert(t->op == '.'); - assert(t->left != NULL && t->left->cnfa.nstates > 0); - assert(t->right != NULL && t->right->cnfa.nstates > 0); - assert(t->left->flags & SHORTER); + assert(left != NULL && left->cnfa.nstates > 0); + assert(right != NULL && right->cnfa.nstates > 0); + assert(right->sibling == NULL); + assert(left->flags & SHORTER); - d = getsubdfa(v, t->left); + d = getsubdfa(v, left); NOERR(); - d2 = getsubdfa(v, t->right); + d2 = getsubdfa(v, right); NOERR(); - MDEBUG(("crevcon %d\n", t->id)); + MDEBUG(("%d: crevcondissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end))); /* pick a tentative midpoint */ mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL); NOERR(); if (mid == NULL) return REG_NOMATCH; - MDEBUG(("tentative midpoint %ld\n", LOFF(mid))); + MDEBUG(("%d: tentative midpoint %ld\n", t->id, LOFF(mid))); /* iterate until satisfaction or failure */ for (;;) @@ -872,14 +898,14 @@ crevcondissect(struct vars *v, /* try this midpoint on for size */ if (longest(v, d2, mid, end, (int *) NULL) == end) { - er = cdissect(v, t->left, begin, mid); + er = cdissect(v, left, begin, mid); if (er == REG_OKAY) { - er = cdissect(v, t->right, mid, end); + er = cdissect(v, right, mid, end); if (er == REG_OKAY) { /* satisfaction */ - MDEBUG(("successful\n")); + MDEBUG(("%d: successful\n", t->id)); return REG_OKAY; } } @@ -892,7 +918,7 @@ crevcondissect(struct vars *v, if (mid == end) { /* all possibilities exhausted */ - MDEBUG(("%d no midpoint\n", t->id)); + MDEBUG(("%d: no midpoint\n", t->id)); return REG_NOMATCH; } mid = shortest(v, d, begin, mid + 1, end, (chr **) NULL, (int *) NULL); @@ -900,12 +926,12 @@ crevcondissect(struct vars *v, if (mid == NULL) { /* failed to find a new one */ - MDEBUG(("%d failed midpoint\n", t->id)); + MDEBUG(("%d: failed midpoint\n", t->id)); return REG_NOMATCH; } MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid))); - zaptreesubs(v, t->left); - zaptreesubs(v, t->right); + zaptreesubs(v, left); + zaptreesubs(v, right); } /* can't get here */ @@ -914,6 +940,9 @@ crevcondissect(struct vars *v, /* * cbrdissect - dissect match for backref node + * + * The backref match might already have been verified by dfa_backref(), + * but we don't know that for sure so must check it here. */ static int /* regexec return code */ cbrdissect(struct vars *v, @@ -921,7 +950,7 @@ cbrdissect(struct vars *v, chr *begin, /* beginning of relevant substring */ chr *end) /* end of same */ { - int n = t->subno; + int n = t->backno; size_t numreps; size_t tlen; size_t brlen; @@ -935,7 +964,8 @@ cbrdissect(struct vars *v, assert(n >= 0); assert((size_t) n < v->nmatch); - MDEBUG(("cbackref n%d %d{%d-%d}\n", t->id, n, min, max)); + MDEBUG(("%d: cbrdissect %d{%d-%d} %ld-%ld\n", t->id, n, min, max, + LOFF(begin), LOFF(end))); /* get the backreferenced string */ if (v->pmatch[n].rm_so == -1) @@ -952,7 +982,7 @@ cbrdissect(struct vars *v, */ if (begin == end && min <= max) { - MDEBUG(("cbackref matched trivially\n")); + MDEBUG(("%d: backref matched trivially\n", t->id)); return REG_OKAY; } return REG_NOMATCH; @@ -962,7 +992,7 @@ cbrdissect(struct vars *v, /* matches only if zero repetitions are okay */ if (min == 0) { - MDEBUG(("cbackref matched trivially\n")); + MDEBUG(("%d: backref matched trivially\n", t->id)); return REG_OKAY; } return REG_NOMATCH; @@ -989,7 +1019,7 @@ cbrdissect(struct vars *v, p += brlen; } - MDEBUG(("cbackref matched\n")); + MDEBUG(("%d: backref matched\n", t->id)); return REG_OKAY; } @@ -1005,26 +1035,30 @@ caltdissect(struct vars *v, struct dfa *d; int er; - /* We loop, rather than tail-recurse, to handle a chain of alternatives */ + assert(t->op == '|'); + + t = t->child; + /* there should be at least 2 alternatives */ + assert(t != NULL && t->sibling != NULL); + while (t != NULL) { - assert(t->op == '|'); - assert(t->left != NULL && t->left->cnfa.nstates > 0); + assert(t->cnfa.nstates > 0); - MDEBUG(("calt n%d\n", t->id)); + MDEBUG(("%d: caltdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end))); - d = getsubdfa(v, t->left); + d = getsubdfa(v, t); NOERR(); if (longest(v, d, begin, end, (int *) NULL) == end) { - MDEBUG(("calt matched\n")); - er = cdissect(v, t->left, begin, end); + MDEBUG(("%d: caltdissect matched\n", t->id)); + er = cdissect(v, t, begin, end); if (er != REG_NOMATCH) return er; } NOERR(); - t = t->right; + t = t->sibling; } return REG_NOMATCH; @@ -1050,10 +1084,12 @@ citerdissect(struct vars *v, int er; assert(t->op == '*'); - assert(t->left != NULL && t->left->cnfa.nstates > 0); - assert(!(t->left->flags & SHORTER)); + assert(t->child != NULL && t->child->cnfa.nstates > 0); + assert(!(t->child->flags & SHORTER)); assert(begin <= end); + MDEBUG(("%d: citerdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end))); + /* * For the moment, assume the minimum number of matches is 1. If zero * matches are allowed, and the target string is empty, we are allowed to @@ -1086,13 +1122,12 @@ citerdissect(struct vars *v, return REG_ESPACE; endpts[0] = begin; - d = getsubdfa(v, t->left); + d = getsubdfa(v, t->child); if (ISERR()) { FREE(endpts); return v->err; } - MDEBUG(("citer %d\n", t->id)); /* * Our strategy is to first find a set of sub-match endpoints that are @@ -1165,8 +1200,8 @@ citerdissect(struct vars *v, for (i = nverified + 1; i <= k; i++) { - zaptreesubs(v, t->left); - er = cdissect(v, t->left, endpts[i - 1], endpts[i]); + zaptreesubs(v, t->child); + er = cdissect(v, t->child, endpts[i - 1], endpts[i]); if (er == REG_OKAY) { nverified = i; @@ -1182,7 +1217,7 @@ citerdissect(struct vars *v, if (i > k) { /* satisfaction */ - MDEBUG(("%d successful\n", t->id)); + MDEBUG(("%d: successful\n", t->id)); FREE(endpts); return REG_OKAY; } @@ -1223,11 +1258,11 @@ citerdissect(struct vars *v, */ if (t->min == 0 && begin == end) { - MDEBUG(("%d allowing zero matches\n", t->id)); + MDEBUG(("%d: allowing zero matches\n", t->id)); return REG_OKAY; } - MDEBUG(("%d failed\n", t->id)); + MDEBUG(("%d: failed\n", t->id)); return REG_NOMATCH; } @@ -1251,10 +1286,12 @@ creviterdissect(struct vars *v, int er; assert(t->op == '*'); - assert(t->left != NULL && t->left->cnfa.nstates > 0); - assert(t->left->flags & SHORTER); + assert(t->child != NULL && t->child->cnfa.nstates > 0); + assert(t->child->flags & SHORTER); assert(begin <= end); + MDEBUG(("%d: creviterdissect %ld-%ld\n", t->id, LOFF(begin), LOFF(end))); + /* * If zero matches are allowed, and target string is empty, just declare * victory. OTOH, if target string isn't empty, zero matches can't work @@ -1264,7 +1301,10 @@ creviterdissect(struct vars *v, if (min_matches <= 0) { if (begin == end) + { + MDEBUG(("%d: allowing zero matches\n", t->id)); return REG_OKAY; + } min_matches = 1; } @@ -1287,13 +1327,12 @@ creviterdissect(struct vars *v, return REG_ESPACE; endpts[0] = begin; - d = getsubdfa(v, t->left); + d = getsubdfa(v, t->child); if (ISERR()) { FREE(endpts); return v->err; } - MDEBUG(("creviter %d\n", t->id)); /* * Our strategy is to first find a set of sub-match endpoints that are @@ -1372,8 +1411,8 @@ creviterdissect(struct vars *v, for (i = nverified + 1; i <= k; i++) { - zaptreesubs(v, t->left); - er = cdissect(v, t->left, endpts[i - 1], endpts[i]); + zaptreesubs(v, t->child); + er = cdissect(v, t->child, endpts[i - 1], endpts[i]); if (er == REG_OKAY) { nverified = i; @@ -1389,7 +1428,7 @@ creviterdissect(struct vars *v, if (i > k) { /* satisfaction */ - MDEBUG(("%d successful\n", t->id)); + MDEBUG(("%d: successful\n", t->id)); FREE(endpts); return REG_OKAY; } @@ -1415,7 +1454,7 @@ creviterdissect(struct vars *v, } /* all possibilities exhausted */ - MDEBUG(("%d failed\n", t->id)); + MDEBUG(("%d: failed\n", t->id)); FREE(endpts); return REG_NOMATCH; } diff --git a/src/backend/regex/regexport.c b/src/backend/regex/regexport.c index a925a9f9a003..a493dbe88c1a 100644 --- a/src/backend/regex/regexport.c +++ b/src/backend/regex/regexport.c @@ -15,7 +15,7 @@ * allows the caller to decide how big is too big to bother with. * * - * Portions Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1998, 1999 Henry Spencer * * IDENTIFICATION @@ -222,7 +222,8 @@ pg_reg_colorisend(const regex_t *regex, int co) * Get number of member chrs of color number "co". * * Note: we return -1 if the color number is invalid, or if it is a special - * color (WHITE or a pseudocolor), or if the number of members is uncertain. + * color (WHITE, RAINBOW, or a pseudocolor), or if the number of members is + * uncertain. * Callers should not try to extract the members if -1 is returned. */ int @@ -233,7 +234,7 @@ pg_reg_getnumcharacters(const regex_t *regex, int co) assert(regex != NULL && regex->re_magic == REMAGIC); cm = &((struct guts *) regex->re_guts)->cmap; - if (co <= 0 || co > cm->max) /* we reject 0 which is WHITE */ + if (co <= 0 || co > cm->max) /* <= 0 rejects WHITE and RAINBOW */ return -1; if (cm->cd[co].flags & PSEUDO) /* also pseudocolors (BOS etc) */ return -1; @@ -257,7 +258,7 @@ pg_reg_getnumcharacters(const regex_t *regex, int co) * whose length chars_len must be at least as long as indicated by * pg_reg_getnumcharacters(), else not all chars will be returned. * - * Fetching the members of WHITE or a pseudocolor is not supported. + * Fetching the members of WHITE, RAINBOW, or a pseudocolor is not supported. * * Caution: this is a relatively expensive operation. */ diff --git a/src/backend/regex/regprefix.c b/src/backend/regex/regprefix.c index 991b8689bef4..ec435b6f5f64 100644 --- a/src/backend/regex/regprefix.c +++ b/src/backend/regex/regprefix.c @@ -4,7 +4,7 @@ * Extract a common prefix, if any, from a compiled regex. * * - * Portions Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1998, 1999 Henry Spencer * * IDENTIFICATION @@ -77,6 +77,10 @@ pg_regprefix(regex_t *re, assert(g->tree != NULL); cnfa = &g->tree->cnfa; + /* matchall NFAs never have a fixed prefix */ + if (cnfa->flags & MATCHALL) + return REG_NOMATCH; + /* * Since a correct NFA should never contain any exit-free loops, it should * not be possible for our traversal to return to a previously visited NFA @@ -165,9 +169,13 @@ findprefix(struct cnfa *cnfa, /* We can ignore BOS/BOL arcs */ if (ca->co == cnfa->bos[0] || ca->co == cnfa->bos[1]) continue; - /* ... but EOS/EOL arcs terminate the search, as do LACONs */ + + /* + * ... but EOS/EOL arcs terminate the search, as do RAINBOW arcs + * and LACONs + */ if (ca->co == cnfa->eos[0] || ca->co == cnfa->eos[1] || - ca->co >= cnfa->ncolors) + ca->co == RAINBOW || ca->co >= cnfa->ncolors) { thiscolor = COLORLESS; break; diff --git a/src/backend/replication/backup_manifest.c b/src/backend/replication/backup_manifest.c index 1ef1effd465a..274a2a99dc27 100644 --- a/src/backend/replication/backup_manifest.c +++ b/src/backend/replication/backup_manifest.c @@ -3,7 +3,7 @@ * backup_manifest.c * code for generating and sending a backup manifest * - * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/backup_manifest.c @@ -13,11 +13,11 @@ #include "postgres.h" #include "access/timeline.h" +#include "common/hex.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" #include "mb/pg_wchar.h" #include "replication/backup_manifest.h" -#include "utils/builtins.h" #include "utils/json.h" static void AppendStringToManifest(backup_manifest_info *manifest, char *s); @@ -57,12 +57,19 @@ InitializeBackupManifest(backup_manifest_info *manifest, backup_manifest_option want_manifest, pg_checksum_type manifest_checksum_type) { + memset(manifest, 0, sizeof(backup_manifest_info)); + manifest->checksum_type = manifest_checksum_type; + if (want_manifest == MANIFEST_OPTION_NO) manifest->buffile = NULL; else - manifest->buffile = BufFileCreateTemp("InitializeBackupManifest", false); - manifest->checksum_type = manifest_checksum_type; - pg_sha256_init(&manifest->manifest_ctx); + { + manifest->buffile = BufFileCreateTemp("backup_manifest", false); + manifest->manifest_ctx = pg_cryptohash_create(PG_SHA256); + if (pg_cryptohash_init(manifest->manifest_ctx) < 0) + elog(ERROR, "failed to initialize checksum of backup manifest"); + } + manifest->manifest_size = UINT64CONST(0); manifest->force_encode = (want_manifest == MANIFEST_OPTION_FORCE_ENCODE); manifest->first_file = true; @@ -74,6 +81,16 @@ InitializeBackupManifest(backup_manifest_info *manifest, "\"Files\": ["); } +/* + * Free resources assigned to a backup manifest constructed. + */ +void +FreeBackupManifest(backup_manifest_info *manifest) +{ + pg_cryptohash_free(manifest->manifest_ctx); + manifest->manifest_ctx = NULL; +} + /* * Add an entry to the backup manifest for a file. */ @@ -112,7 +129,7 @@ AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid, initStringInfo(&buf); if (manifest->first_file) { - appendStringInfoString(&buf, "\n"); + appendStringInfoChar(&buf, '\n'); manifest->first_file = false; } else @@ -133,10 +150,12 @@ AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid, } else { + uint64 dstlen = pg_hex_enc_len(pathlen); + appendStringInfoString(&buf, "{ \"Encoded-Path\": \""); - enlargeStringInfo(&buf, 2 * pathlen); - buf.len += hex_encode(pathname, pathlen, - &buf.data[buf.len]); + enlargeStringInfo(&buf, dstlen); + buf.len += pg_hex_encode(pathname, pathlen, + &buf.data[buf.len], dstlen); appendStringInfoString(&buf, "\", "); } @@ -152,23 +171,28 @@ AddFileToBackupManifest(backup_manifest_info *manifest, const char *spcoid, enlargeStringInfo(&buf, 128); buf.len += pg_strftime(&buf.data[buf.len], 128, "%Y-%m-%d %H:%M:%S %Z", pg_gmtime(&mtime)); - appendStringInfoString(&buf, "\""); + appendStringInfoChar(&buf, '"'); /* Add checksum information. */ if (checksum_ctx->type != CHECKSUM_TYPE_NONE) { uint8 checksumbuf[PG_CHECKSUM_MAX_LENGTH]; int checksumlen; + uint64 dstlen; checksumlen = pg_checksum_final(checksum_ctx, checksumbuf); + if (checksumlen < 0) + elog(ERROR, "could not finalize checksum of file \"%s\"", + pathname); appendStringInfo(&buf, ", \"Checksum-Algorithm\": \"%s\", \"Checksum\": \"", pg_checksum_type_name(checksum_ctx->type)); - enlargeStringInfo(&buf, 2 * checksumlen); - buf.len += hex_encode((char *) checksumbuf, checksumlen, - &buf.data[buf.len]); - appendStringInfoString(&buf, "\""); + dstlen = pg_hex_enc_len(checksumlen); + enlargeStringInfo(&buf, dstlen); + buf.len += pg_hex_encode((char *) checksumbuf, checksumlen, + &buf.data[buf.len], dstlen); + appendStringInfoChar(&buf, '"'); } /* Close out the object. */ @@ -253,8 +277,8 @@ AddWALInfoToBackupManifest(backup_manifest_info *manifest, XLogRecPtr startptr, "%s{ \"Timeline\": %u, \"Start-LSN\": \"%X/%X\", \"End-LSN\": \"%X/%X\" }", first_wal_range ? "" : ",\n", entry->tli, - (uint32) (tl_beginptr >> 32), (uint32) tl_beginptr, - (uint32) (endptr >> 32), (uint32) endptr); + LSN_FORMAT_ARGS(tl_beginptr), + LSN_FORMAT_ARGS(endptr)); if (starttli == entry->tli) { @@ -272,7 +296,7 @@ AddWALInfoToBackupManifest(backup_manifest_info *manifest, XLogRecPtr startptr, */ if (!found_start_timeline) ereport(ERROR, - errmsg("start timeline %u not found history of timeline %u", + errmsg("start timeline %u not found in history of timeline %u", starttli, endtli)); /* Terminate the list of WAL ranges. */ @@ -287,8 +311,9 @@ SendBackupManifest(backup_manifest_info *manifest) { StringInfoData protobuf; uint8 checksumbuf[PG_SHA256_DIGEST_LENGTH]; - char checksumstringbuf[PG_SHA256_DIGEST_STRING_LENGTH]; + char *checksumstringbuf; size_t manifest_bytes_done = 0; + uint64 dstlen; if (!IsManifestEnabled(manifest)) return; @@ -305,10 +330,15 @@ SendBackupManifest(backup_manifest_info *manifest) * twice. */ manifest->still_checksumming = false; - pg_sha256_final(&manifest->manifest_ctx, checksumbuf); + if (pg_cryptohash_final(manifest->manifest_ctx, checksumbuf, + sizeof(checksumbuf)) < 0) + elog(ERROR, "failed to finalize checksum of backup manifest"); AppendStringToManifest(manifest, "\"Manifest-Checksum\": \""); - hex_encode((char *) checksumbuf, sizeof checksumbuf, checksumstringbuf); - checksumstringbuf[PG_SHA256_DIGEST_STRING_LENGTH - 1] = '\0'; + dstlen = pg_hex_enc_len(sizeof(checksumbuf)); + checksumstringbuf = palloc0(dstlen + 1); /* includes \0 */ + pg_hex_encode((char *) checksumbuf, sizeof(checksumbuf), + checksumstringbuf, dstlen); + checksumstringbuf[dstlen] = '\0'; AppendStringToManifest(manifest, checksumstringbuf); AppendStringToManifest(manifest, "\"}\n"); @@ -368,7 +398,10 @@ AppendStringToManifest(backup_manifest_info *manifest, char *s) Assert(manifest != NULL); if (manifest->still_checksumming) - pg_sha256_update(&manifest->manifest_ctx, (uint8 *) s, len); + { + if (pg_cryptohash_update(manifest->manifest_ctx, (uint8 *) s, len) < 0) + elog(ERROR, "failed to update checksum of backup manifest"); + } BufFileWrite(manifest->buffile, s, len); manifest->manifest_size += len; } diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 287792ab5951..9159729089d1 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -3,7 +3,7 @@ * basebackup.c * code for taking a base backup and streaming it to a standby * - * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/basebackup.c @@ -330,20 +330,15 @@ perform_base_backup(basebackup_options *opt) PROGRESS_BASEBACKUP_PHASE_WAIT_CHECKPOINT); startptr = do_pg_start_backup(opt->label, opt->fastcheckpoint, &starttli, labelfile, &tablespaces, - tblspc_map_file, opt->sendtblspcmapfile); - Assert(!XLogRecPtrIsInvalid(startptr)); - - elogif(!debug_basebackup, LOG, - "basebackup perform -- " - "Basebackup start xlog location = %X/%X", - (uint32) (startptr >> 32), (uint32) startptr); + tblspc_map_file); /* - * Set xlogCleanUpTo so that checkpoint process knows - * which old xlog files should not be cleaned + * GPDB: do_pg_start_backup() has just created the backup checkpoint. This + * fault point lets tests (e.g. segwalrep/master_wal_switch) suspend the + * base backup right after the checkpoint, while the backup is in progress, + * to exercise concurrent WAL activity. The PG14 base backup refactor + * dropped it; restore it in the equivalent spot. */ - WalSndSetXLogCleanUpTo(startptr); - SIMPLE_FAULT_INJECTOR("base_backup_post_create_checkpoint"); /* @@ -459,7 +454,7 @@ perform_base_backup(basebackup_options *opt) if (ti->path == NULL) { struct stat statbuf; - bool sendtblspclinks = true; + bool sendtblspclinks = true; /* In the main tar, include the backup_label first... */ sendFileWithContent(BACKUP_LABEL_FILE, labelfile->data, @@ -767,13 +762,23 @@ perform_base_backup(basebackup_options *opt) { if (total_checksum_failures > 1) ereport(WARNING, - (errmsg("%lld total checksum verification failures", total_checksum_failures))); + (errmsg_plural("%lld total checksum verification failure", + "%lld total checksum verification failures", + total_checksum_failures, + total_checksum_failures))); ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("checksum verification failure during base backup"))); } + /* + * Make sure to free the manifest before the resource owners as manifests + * use cryptohash contexts that may depend on resource owners (like + * OpenSSL). + */ + FreeBackupManifest(&manifest); + /* clean up the resource owner we created */ WalSndResourceCleanup(true); @@ -1217,7 +1222,7 @@ SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli) pq_sendint16(&buf, 2); /* number of columns */ len = snprintf(str, sizeof(str), - "%X/%X", (uint32) (ptr >> 32), (uint32) ptr); + "%X/%X", LSN_FORMAT_ARGS(ptr)); pq_sendint32(&buf, len); pq_sendbytes(&buf, str, len); @@ -1243,7 +1248,9 @@ sendFileWithContent(const char *filename, const char *content, len; pg_checksum_context checksum_ctx; - pg_checksum_init(&checksum_ctx, manifest->checksum_type); + if (pg_checksum_init(&checksum_ctx, manifest->checksum_type) < 0) + elog(ERROR, "could not initialize checksum of file \"%s\"", + filename); len = strlen(content); @@ -1279,6 +1286,10 @@ sendFileWithContent(const char *filename, const char *content, update_basebackup_progress(pad); } + if (pg_checksum_update(&checksum_ctx, (uint8 *) content, len) < 0) + elog(ERROR, "could not update checksum of file \"%s\"", + filename); + elogif(debug_basebackup, LOG, "basebackup send file -- Sent file '%s' with content \n%s.", filename, content); @@ -1770,7 +1781,9 @@ sendFile(const char *readfilename, const char *tarfilename, bool verify_checksum = false; pg_checksum_context checksum_ctx; - pg_checksum_init(&checksum_ctx, manifest->checksum_type); + if (pg_checksum_init(&checksum_ctx, manifest->checksum_type) < 0) + elog(ERROR, "could not initialize checksum of file \"%s\"", + readfilename); fd = OpenTransientFile(readfilename, O_RDONLY | PG_BINARY); if (fd < 0) @@ -1848,7 +1861,7 @@ sendFile(const char *readfilename, const char *tarfilename, { ereport(WARNING, (errmsg("could not verify checksum in file \"%s\", block " - "%d: read buffer size %d and page size %d " + "%u: read buffer size %d and page size %d " "differ", readfilename, blkno, (int) cnt, BLCKSZ))); verify_checksum = false; @@ -1921,7 +1934,7 @@ sendFile(const char *readfilename, const char *tarfilename, if (checksum_failures <= 5) ereport(WARNING, (errmsg("checksum verification failed in " - "file \"%s\", block %d: calculated " + "file \"%s\", block %u: calculated " "%X but expected %X", readfilename, blkno, checksum, phdr->pd_checksum))); @@ -1944,7 +1957,8 @@ sendFile(const char *readfilename, const char *tarfilename, update_basebackup_progress(cnt); /* Also feed it to the checksum machinery. */ - pg_checksum_update(&checksum_ctx, (uint8 *) buf, cnt); + if (pg_checksum_update(&checksum_ctx, (uint8 *) buf, cnt) < 0) + elog(ERROR, "could not update checksum of base backup"); len += cnt; throttle(cnt); @@ -1958,7 +1972,8 @@ sendFile(const char *readfilename, const char *tarfilename, { cnt = Min(sizeof(buf), statbuf->st_size - len); pq_putmessage('d', buf, cnt); - pg_checksum_update(&checksum_ctx, (uint8 *) buf, cnt); + if (pg_checksum_update(&checksum_ctx, (uint8 *) buf, cnt) < 0) + elog(ERROR, "could not update checksum of base backup"); update_basebackup_progress(cnt); len += cnt; throttle(cnt); @@ -1966,8 +1981,8 @@ sendFile(const char *readfilename, const char *tarfilename, } /* - * Pad to a block boundary, per tar format requirements. (This small - * piece of data is probably not worth throttling, and is not checksummed + * Pad to a block boundary, per tar format requirements. (This small piece + * of data is probably not worth throttling, and is not checksummed * because it's not actually part of the file.) */ pad = tarPaddingBytesRequired(len); diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index 0ce5318cf3b2..717c7ca9481a 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -6,7 +6,7 @@ * loaded as a dynamic module to avoid linking the main server binary with * libpq. * - * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -254,9 +254,15 @@ libpqrcv_check_conninfo(const char *conninfo) opts = PQconninfoParse(conninfo, &err); if (opts == NULL) + { + /* The error string is malloc'd, so we must free it explicitly */ + char *errcopy = err ? pstrdup(err) : "out of memory"; + + PQfreemem(err); ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("invalid connection string syntax: %s", err))); + errmsg("invalid connection string syntax: %s", errcopy))); + } PQconninfoFree(opts); } @@ -280,7 +286,8 @@ libpqrcv_get_conninfo(WalReceiverConn *conn) if (conn_opts == NULL) ereport(ERROR, - (errmsg("could not parse connection string: %s", + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("could not parse connection string: %s", _("out of memory")))); /* build a clean connection string from pieces */ @@ -352,7 +359,8 @@ libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli) { PQclear(res); ereport(ERROR, - (errmsg("could not receive database system identifier and timeline ID from " + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("could not receive database system identifier and timeline ID from " "the primary server: %s", pchomp(PQerrorMessage(conn->streamConn))))); } @@ -363,7 +371,8 @@ libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli) PQclear(res); ereport(ERROR, - (errmsg("invalid response from primary server"), + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("invalid response from primary server"), errdetail("Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields.", ntuples, nfields, 3, 1))); } @@ -414,9 +423,7 @@ libpqrcv_startstreaming(WalReceiverConn *conn, if (options->logical) appendStringInfoString(&cmd, " LOGICAL"); - appendStringInfo(&cmd, " %X/%X", - (uint32) (options->startpoint >> 32), - (uint32) options->startpoint); + appendStringInfo(&cmd, " %X/%X", LSN_FORMAT_ARGS(options->startpoint)); /* * Additional options are different depending on if we are doing logical @@ -433,17 +440,23 @@ libpqrcv_startstreaming(WalReceiverConn *conn, appendStringInfo(&cmd, "proto_version '%u'", options->proto.logical.proto_version); + if (options->proto.logical.streaming && + PQserverVersion(conn->streamConn) >= 140000) + appendStringInfoString(&cmd, ", streaming 'on'"); + pubnames = options->proto.logical.publication_names; pubnames_str = stringlist_to_identifierstr(conn->streamConn, pubnames); if (!pubnames_str) ereport(ERROR, - (errmsg("could not start WAL streaming: %s", + (errcode(ERRCODE_OUT_OF_MEMORY), /* likely guess */ + errmsg("could not start WAL streaming: %s", pchomp(PQerrorMessage(conn->streamConn))))); pubnames_literal = PQescapeLiteral(conn->streamConn, pubnames_str, strlen(pubnames_str)); if (!pubnames_literal) ereport(ERROR, - (errmsg("could not start WAL streaming: %s", + (errcode(ERRCODE_OUT_OF_MEMORY), /* likely guess */ + errmsg("could not start WAL streaming: %s", pchomp(PQerrorMessage(conn->streamConn))))); appendStringInfo(&cmd, ", publication_names %s", pubnames_literal); PQfreemem(pubnames_literal); @@ -472,7 +485,8 @@ libpqrcv_startstreaming(WalReceiverConn *conn, { PQclear(res); ereport(ERROR, - (errmsg("could not start WAL streaming: %s", + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("could not start WAL streaming: %s", pchomp(PQerrorMessage(conn->streamConn))))); } PQclear(res); @@ -495,7 +509,8 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) if (PQputCopyEnd(conn->streamConn, NULL) <= 0 || PQflush(conn->streamConn)) ereport(ERROR, - (errmsg("could not send end-of-streaming message to primary: %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not send end-of-streaming message to primary: %s", pchomp(PQerrorMessage(conn->streamConn))))); *next_tli = 0; @@ -517,7 +532,8 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) */ if (PQnfields(res) < 2 || PQntuples(res) != 1) ereport(ERROR, - (errmsg("unexpected result set after end-of-streaming"))); + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("unexpected result set after end-of-streaming"))); *next_tli = pg_strtoint32(PQgetvalue(res, 0, 0)); PQclear(res); @@ -531,7 +547,8 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) /* End the copy */ if (PQendcopy(conn->streamConn)) ereport(ERROR, - (errmsg("error while shutting down streaming COPY: %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("error while shutting down streaming COPY: %s", pchomp(PQerrorMessage(conn->streamConn))))); /* CommandComplete should follow */ @@ -540,7 +557,8 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) if (PQresultStatus(res) != PGRES_COMMAND_OK) ereport(ERROR, - (errmsg("error reading result of streaming command: %s", + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("error reading result of streaming command: %s", pchomp(PQerrorMessage(conn->streamConn))))); PQclear(res); @@ -548,7 +566,8 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) res = libpqrcv_PQgetResult(conn->streamConn); if (res != NULL) ereport(ERROR, - (errmsg("unexpected result after CommandComplete: %s", + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("unexpected result after CommandComplete: %s", pchomp(PQerrorMessage(conn->streamConn))))); } @@ -574,7 +593,8 @@ libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn, { PQclear(res); ereport(ERROR, - (errmsg("could not receive timeline history file from " + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("could not receive timeline history file from " "the primary server: %s", pchomp(PQerrorMessage(conn->streamConn))))); } @@ -585,7 +605,8 @@ libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn, PQclear(res); ereport(ERROR, - (errmsg("invalid response from primary server"), + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("invalid response from primary server"), errdetail("Expected 1 tuple with 2 fields, got %d tuples with %d fields.", ntuples, nfields))); } @@ -746,7 +767,8 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer, /* Try consuming some data. */ if (PQconsumeInput(conn->streamConn) == 0) ereport(ERROR, - (errmsg("could not receive data from WAL stream: %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not receive data from WAL stream: %s", pchomp(PQerrorMessage(conn->streamConn))))); /* Now that we've consumed some input, try again */ @@ -782,7 +804,8 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer, return -1; ereport(ERROR, - (errmsg("unexpected result after CommandComplete: %s", + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("unexpected result after CommandComplete: %s", PQerrorMessage(conn->streamConn)))); } @@ -797,13 +820,15 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer, { PQclear(res); ereport(ERROR, - (errmsg("could not receive data from WAL stream: %s", + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("could not receive data from WAL stream: %s", pchomp(PQerrorMessage(conn->streamConn))))); } } if (rawlen < -1) ereport(ERROR, - (errmsg("could not receive data from WAL stream: %s", + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("could not receive data from WAL stream: %s", pchomp(PQerrorMessage(conn->streamConn))))); /* Return received messages to caller */ @@ -822,7 +847,8 @@ libpqrcv_send(WalReceiverConn *conn, const char *buffer, int nbytes) if (PQputCopyData(conn->streamConn, buffer, nbytes) <= 0 || PQflush(conn->streamConn)) ereport(ERROR, - (errmsg("could not send data to WAL stream: %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not send data to WAL stream: %s", pchomp(PQerrorMessage(conn->streamConn))))); } @@ -875,7 +901,8 @@ libpqrcv_create_slot(WalReceiverConn *conn, const char *slotname, { PQclear(res); ereport(ERROR, - (errmsg("could not create replication slot \"%s\": %s", + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("could not create replication slot \"%s\": %s", slotname, pchomp(PQerrorMessage(conn->streamConn))))); } @@ -920,7 +947,8 @@ libpqrcv_processTuples(PGresult *pgres, WalRcvExecResult *walres, /* Make sure we got expected number of fields. */ if (nfields != nRetTypes) ereport(ERROR, - (errmsg("invalid query response"), + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("invalid query response"), errdetail("Expected %d fields, got %d fields.", nRetTypes, nfields))); @@ -986,6 +1014,7 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query, { PGresult *pgres = NULL; WalRcvExecResult *walres = palloc0(sizeof(WalRcvExecResult)); + char *diag_sqlstate; if (MyDatabaseId == InvalidOid) ereport(ERROR, @@ -1024,11 +1053,24 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query, walres->err = _("empty query"); break; + case PGRES_PIPELINE_SYNC: + case PGRES_PIPELINE_ABORTED: + walres->status = WALRCV_ERROR; + walres->err = _("unexpected pipeline mode"); + break; + case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: case PGRES_BAD_RESPONSE: walres->status = WALRCV_ERROR; walres->err = pchomp(PQerrorMessage(conn->streamConn)); + diag_sqlstate = PQresultErrorField(pgres, PG_DIAG_SQLSTATE); + if (diag_sqlstate) + walres->sqlstate = MAKE_SQLSTATE(diag_sqlstate[0], + diag_sqlstate[1], + diag_sqlstate[2], + diag_sqlstate[3], + diag_sqlstate[4]); break; } diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index 84666bd90c72..16ed3e837d84 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -16,7 +16,7 @@ * contents of records in here except turning them into a more usable * format. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -67,13 +67,25 @@ static void DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf static void DecodeSpecConfirm(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); static void DecodeCommit(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, - xl_xact_parsed_commit *parsed, TransactionId xid); + xl_xact_parsed_commit *parsed, TransactionId xid, + bool two_phase); static void DecodeAbort(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, - xl_xact_parsed_abort *parsed, TransactionId xid); + xl_xact_parsed_abort *parsed, TransactionId xid, + bool two_phase); +static void DecodePrepare(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, + xl_xact_parsed_prepare *parsed); + /* common function to decode tuples */ static void DecodeXLogTuple(char *data, Size len, ReorderBufferTupleBuf *tup); +/* helper functions for decoding transactions */ +static inline bool FilterPrepare(LogicalDecodingContext *ctx, + TransactionId xid, const char *gid); +static bool DecodeTXNNeedSkip(LogicalDecodingContext *ctx, + XLogRecordBuffer *buf, Oid dbId, + RepOriginId origin_id); + /* * Take every XLogReadRecord()ed record and perform the actions required to * decode it using the output plugin already setup in the logical decoding @@ -256,6 +268,7 @@ DecodeXactOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) xl_xact_commit *xlrec; xl_xact_parsed_commit parsed; TransactionId xid; + bool two_phase = false; xlrec = (xl_xact_commit *) XLogRecGetData(r); ParseCommitRecord(XLogRecGetInfo(buf->record), xlrec, &parsed); @@ -265,7 +278,16 @@ DecodeXactOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) else xid = parsed.twophase_xid; - DecodeCommit(ctx, buf, &parsed, xid); + /* + * We would like to process the transaction in a two-phase + * manner iff output plugin supports two-phase commits and + * doesn't filter the transaction at prepare time. + */ + if (info == XLOG_XACT_COMMIT_PREPARED) + two_phase = !(FilterPrepare(ctx, xid, + parsed.twophase_gid)); + + DecodeCommit(ctx, buf, &parsed, xid, two_phase); break; } case XLOG_XACT_ABORT: @@ -274,6 +296,7 @@ DecodeXactOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) xl_xact_abort *xlrec; xl_xact_parsed_abort parsed; TransactionId xid; + bool two_phase = false; xlrec = (xl_xact_abort *) XLogRecGetData(r); ParseAbortRecord(XLogRecGetInfo(buf->record), xlrec, &parsed); @@ -283,7 +306,16 @@ DecodeXactOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) else xid = parsed.twophase_xid; - DecodeAbort(ctx, buf, &parsed, xid); + /* + * We would like to process the transaction in a two-phase + * manner iff output plugin supports two-phase commits and + * doesn't filter the transaction at prepare time. + */ + if (info == XLOG_XACT_ABORT_PREPARED) + two_phase = !(FilterPrepare(ctx, xid, + parsed.twophase_gid)); + + DecodeAbort(ctx, buf, &parsed, xid, two_phase); break; } case XLOG_XACT_ASSIGNMENT: @@ -324,17 +356,45 @@ DecodeXactOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) } break; case XLOG_XACT_PREPARE: + { + xl_xact_parsed_prepare parsed; + xl_xact_prepare *xlrec; - /* - * Currently decoding ignores PREPARE TRANSACTION and will just - * decode the transaction when the COMMIT PREPARED is sent or - * throw away the transaction's contents when a ROLLBACK PREPARED - * is received. In the future we could add code to expose prepared - * transactions in the changestream allowing for a kind of - * distributed 2PC. - */ - ReorderBufferProcessXid(reorder, XLogRecGetXid(r), buf->origptr); - break; + /* ok, parse it */ + xlrec = (xl_xact_prepare *) XLogRecGetData(r); + ParsePrepareRecord(XLogRecGetInfo(buf->record), + xlrec, &parsed); + + /* + * We would like to process the transaction in a two-phase + * manner iff output plugin supports two-phase commits and + * doesn't filter the transaction at prepare time. + */ + if (FilterPrepare(ctx, parsed.twophase_xid, + parsed.twophase_gid)) + { + ReorderBufferProcessXid(reorder, parsed.twophase_xid, + buf->origptr); + break; + } + + /* + * Note that if the prepared transaction has locked [user] + * catalog tables exclusively then decoding prepare can block + * till the main transaction is committed because it needs to + * lock the catalog tables. + * + * XXX Now, this can even lead to a deadlock if the prepare + * transaction is waiting to get it logically replicated for + * distributed 2PC. Currently, we don't have an in-core + * implementation of prepares for distributed 2PC but some + * out-of-core logical replication solution can have such an + * implementation. They need to inform users to not have locks + * on catalog tables in such transactions. + */ + DecodePrepare(ctx, buf, &parsed); + break; + } default: elog(ERROR, "unexpected RM_XACT_ID record type: %u", info); } @@ -436,8 +496,8 @@ DecodeHeap2Op(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) * interested in. */ case XLOG_HEAP2_FREEZE_PAGE: - case XLOG_HEAP2_CLEAN: - case XLOG_HEAP2_CLEANUP_INFO: + case XLOG_HEAP2_PRUNE: + case XLOG_HEAP2_VACUUM: case XLOG_HEAP2_VISIBLE: case XLOG_HEAP2_LOCK_UPDATED: break; @@ -532,6 +592,33 @@ DecodeHeapOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) } } +/* + * Ask output plugin whether we want to skip this PREPARE and send + * this transaction as a regular commit later. + */ +static inline bool +FilterPrepare(LogicalDecodingContext *ctx, TransactionId xid, + const char *gid) +{ + /* + * Skip if decoding of two-phase transactions at PREPARE time is not + * enabled. In that case, all two-phase transactions are considered + * filtered out and will be applied as regular transactions at COMMIT + * PREPARED. + */ + if (!ctx->twophase) + return true; + + /* + * The filter_prepare callback is optional. When not supplied, all + * prepared transactions should go through. + */ + if (ctx->callbacks.filter_prepare_cb == NULL) + return false; + + return filter_prepare_cb_wrapper(ctx, xid, gid); +} + static inline bool FilterByOrigin(LogicalDecodingContext *ctx, RepOriginId origin_id) { @@ -594,10 +681,15 @@ DecodeLogicalMsgOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) /* * Consolidated commit record handling between the different form of commit * records. + * + * 'two_phase' indicates that caller wants to process the transaction in two + * phases, first process prepare if not already done and then process + * commit_prepared. */ static void DecodeCommit(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, - xl_xact_parsed_commit *parsed, TransactionId xid) + xl_xact_parsed_commit *parsed, TransactionId xid, + bool two_phase) { XLogRecPtr origin_lsn = InvalidXLogRecPtr; TimestampTz commit_time = parsed->xact_time; @@ -618,30 +710,19 @@ DecodeCommit(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, * the reorderbuffer to forget the content of the (sub-)transactions * if not. * - * There can be several reasons we might not be interested in this - * transaction: - * 1) We might not be interested in decoding transactions up to this - * LSN. This can happen because we previously decoded it and now just - * are restarting or if we haven't assembled a consistent snapshot yet. - * 2) The transaction happened in another database. - * 3) The output plugin is not interested in the origin. - * 4) We are doing fast-forwarding - * * We can't just use ReorderBufferAbort() here, because we need to execute * the transaction's invalidations. This currently won't be needed if * we're just skipping over the transaction because currently we only do * so during startup, to get to the first transaction the client needs. As * we have reset the catalog caches before starting to read WAL, and we * haven't yet touched any catalogs, there can't be anything to invalidate. - * But if we're "forgetting" this commit because it's it happened in - * another database, the invalidations might be important, because they - * could be for shared catalogs and we might have loaded data into the - * relevant syscaches. + * But if we're "forgetting" this commit because it happened in another + * database, the invalidations might be important, because they could be + * for shared catalogs and we might have loaded data into the relevant + * syscaches. * --- */ - if (SnapBuildXactNeedsSkip(ctx->snapshot_builder, buf->origptr) || - (parsed->dbId != InvalidOid && parsed->dbId != ctx->slot->data.database) || - ctx->fast_forward || FilterByOrigin(ctx, origin_id)) + if (DecodeTXNNeedSkip(ctx, buf, parsed->dbId, origin_id)) { for (i = 0; i < parsed->nsubxacts; i++) { @@ -659,28 +740,170 @@ DecodeCommit(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, buf->origptr, buf->endptr); } + /* + * Send the final commit record if the transaction data is already + * decoded, otherwise, process the entire transaction. + */ + if (two_phase) + { + ReorderBufferFinishPrepared(ctx->reorder, xid, buf->origptr, buf->endptr, + SnapBuildInitialConsistentPoint(ctx->snapshot_builder), + commit_time, origin_id, origin_lsn, + parsed->twophase_gid, true); + } + else + { + ReorderBufferCommit(ctx->reorder, xid, buf->origptr, buf->endptr, + commit_time, origin_id, origin_lsn); + } + + /* + * Update the decoding stats at transaction prepare/commit/abort. + * Additionally we send the stats when we spill or stream the changes to + * avoid losing them in case the decoding is interrupted. It is not clear + * that sending more or less frequently than this would be better. + */ + UpdateDecodingStats(ctx); +} + +/* + * Decode PREPARE record. Similar logic as in DecodeCommit. + * + * Note that we don't skip prepare even if have detected concurrent abort + * because it is quite possible that we had already sent some changes before we + * detect abort in which case we need to abort those changes in the subscriber. + * To abort such changes, we do send the prepare and then the rollback prepared + * which is what happened on the publisher-side as well. Now, we can invent a + * new abort API wherein in such cases we send abort and skip sending prepared + * and rollback prepared but then it is not that straightforward because we + * might have streamed this transaction by that time in which case it is + * handled when the rollback is encountered. It is not impossible to optimize + * the concurrent abort case but it can introduce design complexity w.r.t + * handling different cases so leaving it for now as it doesn't seem worth it. + */ +static void +DecodePrepare(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, + xl_xact_parsed_prepare *parsed) +{ + SnapBuild *builder = ctx->snapshot_builder; + XLogRecPtr origin_lsn = parsed->origin_lsn; + TimestampTz prepare_time = parsed->xact_time; + XLogRecPtr origin_id = XLogRecGetOrigin(buf->record); + int i; + TransactionId xid = parsed->twophase_xid; + + if (parsed->origin_timestamp != 0) + prepare_time = parsed->origin_timestamp; + + /* + * Remember the prepare info for a txn so that it can be used later in + * commit prepared if required. See ReorderBufferFinishPrepared. + */ + if (!ReorderBufferRememberPrepareInfo(ctx->reorder, xid, buf->origptr, + buf->endptr, prepare_time, origin_id, + origin_lsn)) + return; + + /* We can't start streaming unless a consistent state is reached. */ + if (SnapBuildCurrentState(builder) < SNAPBUILD_CONSISTENT) + { + ReorderBufferSkipPrepare(ctx->reorder, xid); + return; + } + + /* + * Check whether we need to process this transaction. See + * DecodeTXNNeedSkip for the reasons why we sometimes want to skip the + * transaction. + * + * We can't call ReorderBufferForget as we did in DecodeCommit as the txn + * hasn't yet been committed, removing this txn before a commit might + * result in the computation of an incorrect restart_lsn. See + * SnapBuildProcessRunningXacts. But we need to process cache + * invalidations if there are any for the reasons mentioned in + * DecodeCommit. + */ + if (DecodeTXNNeedSkip(ctx, buf, parsed->dbId, origin_id)) + { + ReorderBufferSkipPrepare(ctx->reorder, xid); + ReorderBufferInvalidate(ctx->reorder, xid, buf->origptr); + return; + } + + /* Tell the reorderbuffer about the surviving subtransactions. */ + for (i = 0; i < parsed->nsubxacts; i++) + { + ReorderBufferCommitChild(ctx->reorder, xid, parsed->subxacts[i], + buf->origptr, buf->endptr); + } + /* replay actions of all transaction + subtransactions in order */ - ReorderBufferCommit(ctx->reorder, xid, buf->origptr, buf->endptr, - commit_time, origin_id, origin_lsn); + ReorderBufferPrepare(ctx->reorder, xid, parsed->twophase_gid); + + /* + * Update the decoding stats at transaction prepare/commit/abort. + * Additionally we send the stats when we spill or stream the changes to + * avoid losing them in case the decoding is interrupted. It is not clear + * that sending more or less frequently than this would be better. + */ + UpdateDecodingStats(ctx); } + /* * Get the data from the various forms of abort records and pass it on to - * snapbuild.c and reorderbuffer.c + * snapbuild.c and reorderbuffer.c. + * + * 'two_phase' indicates to finish prepared transaction. */ static void DecodeAbort(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, - xl_xact_parsed_abort *parsed, TransactionId xid) + xl_xact_parsed_abort *parsed, TransactionId xid, + bool two_phase) { int i; + XLogRecPtr origin_lsn = InvalidXLogRecPtr; + TimestampTz abort_time = parsed->xact_time; + XLogRecPtr origin_id = XLogRecGetOrigin(buf->record); + bool skip_xact; - for (i = 0; i < parsed->nsubxacts; i++) + if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN) { - ReorderBufferAbort(ctx->reorder, parsed->subxacts[i], - buf->record->EndRecPtr); + origin_lsn = parsed->origin_lsn; + abort_time = parsed->origin_timestamp; } - ReorderBufferAbort(ctx->reorder, xid, buf->record->EndRecPtr); + /* + * Check whether we need to process this transaction. See + * DecodeTXNNeedSkip for the reasons why we sometimes want to skip the + * transaction. + */ + skip_xact = DecodeTXNNeedSkip(ctx, buf, parsed->dbId, origin_id); + + /* + * Send the final rollback record for a prepared transaction unless we + * need to skip it. For non-two-phase xacts, simply forget the xact. + */ + if (two_phase && !skip_xact) + { + ReorderBufferFinishPrepared(ctx->reorder, xid, buf->origptr, buf->endptr, + abort_time, origin_id, origin_lsn, + InvalidXLogRecPtr, + parsed->twophase_gid, false); + } + else + { + for (i = 0; i < parsed->nsubxacts; i++) + { + ReorderBufferAbort(ctx->reorder, parsed->subxacts[i], + buf->record->EndRecPtr); + } + + ReorderBufferAbort(ctx->reorder, xid, buf->record->EndRecPtr); + } + + /* update the decoding stats */ + UpdateDecodingStats(ctx); } /* @@ -829,19 +1052,17 @@ DecodeDelete(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) if (target_node.dbNode != ctx->slot->data.database) return; - /* - * Super deletions are irrelevant for logical decoding, it's driven by the - * confirmation records. - */ - if (xlrec->flags & XLH_DELETE_IS_SUPER) - return; - /* output plugin doesn't look for this origin, no need to queue */ if (FilterByOrigin(ctx, XLogRecGetOrigin(r))) return; change = ReorderBufferGetChange(ctx->reorder); - change->action = REORDER_BUFFER_CHANGE_DELETE; + + if (xlrec->flags & XLH_DELETE_IS_SUPER) + change->action = REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT; + else + change->action = REORDER_BUFFER_CHANGE_DELETE; + change->origin_id = XLogRecGetOrigin(r); memcpy(&change->data.tp.relnode, &target_node, sizeof(RelFileNode)); @@ -1083,3 +1304,24 @@ DecodeXLogTuple(char *data, Size len, ReorderBufferTupleBuf *tuple) header->t_infomask2 = xlhdr.t_infomask2; header->t_hoff = xlhdr.t_hoff; } + +/* + * Check whether we are interested in this specific transaction. + * + * There can be several reasons we might not be interested in this + * transaction: + * 1) We might not be interested in decoding transactions up to this + * LSN. This can happen because we previously decoded it and now just + * are restarting or if we haven't assembled a consistent snapshot yet. + * 2) The transaction happened in another database. + * 3) The output plugin is not interested in the origin. + * 4) We are doing fast-forwarding + */ +static bool +DecodeTXNNeedSkip(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, + Oid txn_dbid, RepOriginId origin_id) +{ + return (SnapBuildXactNeedsSkip(ctx->snapshot_builder, buf->origptr) || + (txn_dbid != InvalidOid && txn_dbid != ctx->slot->data.database) || + ctx->fast_forward || FilterByOrigin(ctx, origin_id)); +} diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index bdaf0312d63d..e3b11daa897f 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -2,7 +2,7 @@ * launcher.c * PostgreSQL logical replication worker launcher process * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/launcher.c @@ -67,26 +67,6 @@ typedef struct LogicalRepCtxStruct LogicalRepCtxStruct *LogicalRepCtx; -typedef struct LogicalRepWorkerId -{ - Oid subid; - Oid relid; -} LogicalRepWorkerId; - -typedef struct StopWorkersData -{ - int nestDepth; /* Sub-transaction nest level */ - List *workers; /* List of LogicalRepWorkerId */ - struct StopWorkersData *parent; /* This need not be an immediate - * subtransaction parent */ -} StopWorkersData; - -/* - * Stack of StopWorkersData elements. Each stack element contains the workers - * to be stopped for that subtransaction. - */ -static StopWorkersData *on_commit_stop_workers = NULL; - static void ApplyLauncherWakeup(void); static void logicalrep_launcher_onexit(int code, Datum arg); static void logicalrep_worker_onexit(int code, Datum arg); @@ -296,8 +276,8 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid, TimestampTz now; ereport(DEBUG1, - (errmsg("starting logical replication worker for subscription \"%s\"", - subname))); + (errmsg_internal("starting logical replication worker for subscription \"%s\"", + subname))); /* Report this after the initial starting message for consistency. */ if (max_replication_slots == 0) @@ -546,51 +526,6 @@ logicalrep_worker_stop(Oid subid, Oid relid) LWLockRelease(LogicalRepWorkerLock); } -/* - * Request worker for specified sub/rel to be stopped on commit. - */ -void -logicalrep_worker_stop_at_commit(Oid subid, Oid relid) -{ - int nestDepth = GetCurrentTransactionNestLevel(); - LogicalRepWorkerId *wid; - MemoryContext oldctx; - - /* Make sure we store the info in context that survives until commit. */ - oldctx = MemoryContextSwitchTo(TopTransactionContext); - - /* Check that previous transactions were properly cleaned up. */ - Assert(on_commit_stop_workers == NULL || - nestDepth >= on_commit_stop_workers->nestDepth); - - /* - * Push a new stack element if we don't already have one for the current - * nestDepth. - */ - if (on_commit_stop_workers == NULL || - nestDepth > on_commit_stop_workers->nestDepth) - { - StopWorkersData *newdata = palloc(sizeof(StopWorkersData)); - - newdata->nestDepth = nestDepth; - newdata->workers = NIL; - newdata->parent = on_commit_stop_workers; - on_commit_stop_workers = newdata; - } - - /* - * Finally add a new worker into the worker list of the current - * subtransaction. - */ - wid = palloc(sizeof(LogicalRepWorkerId)); - wid->subid = subid; - wid->relid = relid; - on_commit_stop_workers->workers = - lappend(on_commit_stop_workers->workers, wid); - - MemoryContextSwitchTo(oldctx); -} - /* * Wake up (using latch) any logical replication worker for specified sub/rel. */ @@ -708,8 +643,8 @@ static void logicalrep_worker_onexit(int code, Datum arg) { /* Disconnect gracefully from the remote side. */ - if (wrconn) - walrcv_disconnect(wrconn); + if (LogRepWorkerWalRcvConn) + walrcv_disconnect(LogRepWorkerWalRcvConn); logicalrep_worker_detach(); @@ -819,109 +754,21 @@ ApplyLauncherShmemInit(void) } } -/* - * Check whether current transaction has manipulated logical replication - * workers. - */ -bool -XactManipulatesLogicalReplicationWorkers(void) -{ - return (on_commit_stop_workers != NULL); -} - /* * Wakeup the launcher on commit if requested. */ void AtEOXact_ApplyLauncher(bool isCommit) { - - Assert(on_commit_stop_workers == NULL || - (on_commit_stop_workers->nestDepth == 1 && - on_commit_stop_workers->parent == NULL)); - if (isCommit) { - ListCell *lc; - - if (on_commit_stop_workers != NULL) - { - List *workers = on_commit_stop_workers->workers; - - foreach(lc, workers) - { - LogicalRepWorkerId *wid = lfirst(lc); - - logicalrep_worker_stop(wid->subid, wid->relid); - } - } - if (on_commit_launcher_wakeup) ApplyLauncherWakeup(); } - /* - * No need to pfree on_commit_stop_workers. It was allocated in - * transaction memory context, which is going to be cleaned soon. - */ - on_commit_stop_workers = NULL; on_commit_launcher_wakeup = false; } -/* - * On commit, merge the current on_commit_stop_workers list into the - * immediate parent, if present. - * On rollback, discard the current on_commit_stop_workers list. - * Pop out the stack. - */ -void -AtEOSubXact_ApplyLauncher(bool isCommit, int nestDepth) -{ - StopWorkersData *parent; - - /* Exit immediately if there's no work to do at this level. */ - if (on_commit_stop_workers == NULL || - on_commit_stop_workers->nestDepth < nestDepth) - return; - - Assert(on_commit_stop_workers->nestDepth == nestDepth); - - parent = on_commit_stop_workers->parent; - - if (isCommit) - { - /* - * If the upper stack element is not an immediate parent - * subtransaction, just decrement the notional nesting depth without - * doing any real work. Else, we need to merge the current workers - * list into the parent. - */ - if (!parent || parent->nestDepth < nestDepth - 1) - { - on_commit_stop_workers->nestDepth--; - return; - } - - parent->workers = - list_concat(parent->workers, on_commit_stop_workers->workers); - } - else - { - /* - * Abandon everything that was done at this nesting level. Explicitly - * free memory to avoid a transaction-lifespan leak. - */ - list_free_deep(on_commit_stop_workers->workers); - } - - /* - * We have taken care of the current subtransaction workers list for both - * abort or commit. So we are ready to pop the stack. - */ - pfree(on_commit_stop_workers); - on_commit_stop_workers = parent; -} - /* * Request wakeup of the launcher on commit of the transaction. * @@ -952,7 +799,7 @@ ApplyLauncherMain(Datum main_arg) TimestampTz last_start_time = 0; ereport(DEBUG1, - (errmsg("logical replication launcher started"))); + (errmsg_internal("logical replication launcher started"))); before_shmem_exit(logicalrep_launcher_onexit, (Datum) 0); diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index 0f6af952f939..d536a5f3ba3b 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -2,7 +2,7 @@ * logical.c * PostgreSQL logical decoding coordination * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/logical.c @@ -32,6 +32,7 @@ #include "access/xlog_internal.h" #include "fmgr.h" #include "miscadmin.h" +#include "pgstat.h" #include "replication/decode.h" #include "replication/logical.h" #include "replication/origin.h" @@ -58,6 +59,13 @@ static void shutdown_cb_wrapper(LogicalDecodingContext *ctx); static void begin_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn); static void commit_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr commit_lsn); +static void begin_prepare_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn); +static void prepare_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); +static void commit_prepared_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); +static void rollback_prepared_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, TimestampTz prepare_time); static void change_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change); static void truncate_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, @@ -73,6 +81,8 @@ static void stream_stop_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr last_lsn); static void stream_abort_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr abort_lsn); +static void stream_prepare_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn); static void stream_commit_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr commit_lsn); static void stream_change_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, @@ -181,8 +191,8 @@ StartupDecodingContext(List *output_plugin_options, if (!IsTransactionOrTransactionBlock()) { LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); - MyProc->vacuumFlags |= PROC_IN_LOGICAL_DECODING; - ProcGlobal->vacuumFlags[MyProc->pgxactoff] = MyProc->vacuumFlags; + MyProc->statusFlags |= PROC_IN_LOGICAL_DECODING; + ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; LWLockRelease(ProcArrayLock); } @@ -197,7 +207,7 @@ StartupDecodingContext(List *output_plugin_options, ctx->reorder = ReorderBufferAllocate(); ctx->snapshot_builder = AllocateSnapshotBuilder(ctx->reorder, xmin_horizon, start_lsn, - need_full_snapshot); + need_full_snapshot, slot->data.initial_consistent_point); ctx->reorder->private_data = ctx; @@ -236,11 +246,37 @@ StartupDecodingContext(List *output_plugin_options, ctx->reorder->stream_start = stream_start_cb_wrapper; ctx->reorder->stream_stop = stream_stop_cb_wrapper; ctx->reorder->stream_abort = stream_abort_cb_wrapper; + ctx->reorder->stream_prepare = stream_prepare_cb_wrapper; ctx->reorder->stream_commit = stream_commit_cb_wrapper; ctx->reorder->stream_change = stream_change_cb_wrapper; ctx->reorder->stream_message = stream_message_cb_wrapper; ctx->reorder->stream_truncate = stream_truncate_cb_wrapper; + + /* + * To support two-phase logical decoding, we require + * begin_prepare/prepare/commit-prepare/abort-prepare callbacks. The + * filter_prepare callback is optional. We however enable two-phase + * logical decoding when at least one of the methods is enabled so that we + * can easily identify missing methods. + * + * We decide it here, but only check it later in the wrappers. + */ + ctx->twophase = (ctx->callbacks.begin_prepare_cb != NULL) || + (ctx->callbacks.prepare_cb != NULL) || + (ctx->callbacks.commit_prepared_cb != NULL) || + (ctx->callbacks.rollback_prepared_cb != NULL) || + (ctx->callbacks.stream_prepare_cb != NULL) || + (ctx->callbacks.filter_prepare_cb != NULL); + + /* + * Callback to support decoding at prepare time. + */ + ctx->reorder->begin_prepare = begin_prepare_cb_wrapper; + ctx->reorder->prepare = prepare_cb_wrapper; + ctx->reorder->commit_prepared = commit_prepared_cb_wrapper; + ctx->reorder->rollback_prepared = rollback_prepared_cb_wrapper; + ctx->out = makeStringInfo(); ctx->prepare_write = prepare_write; ctx->write = do_write; @@ -395,6 +431,12 @@ CreateInitDecodingContext(const char *plugin, startup_cb_wrapper(ctx, &ctx->options, true); MemoryContextSwitchTo(old_context); + /* + * We allow decoding of prepared transactions iff the two_phase option is + * enabled at the time of slot creation. + */ + ctx->twophase &= MyReplicationSlot->data.two_phase; + ctx->reorder->output_rewrites = ctx->options.receive_rewrites; return ctx; @@ -478,9 +520,8 @@ CreateDecodingContext(XLogRecPtr start_lsn, * replication. */ elog(DEBUG1, "cannot stream from %X/%X, minimum is %X/%X, forwarding", - (uint32) (start_lsn >> 32), (uint32) start_lsn, - (uint32) (slot->data.confirmed_flush >> 32), - (uint32) slot->data.confirmed_flush); + LSN_FORMAT_ARGS(start_lsn), + LSN_FORMAT_ARGS(slot->data.confirmed_flush)); start_lsn = slot->data.confirmed_flush; } @@ -496,16 +537,20 @@ CreateDecodingContext(XLogRecPtr start_lsn, startup_cb_wrapper(ctx, &ctx->options, false); MemoryContextSwitchTo(old_context); + /* + * We allow decoding of prepared transactions iff the two_phase option is + * enabled at the time of slot creation. + */ + ctx->twophase &= MyReplicationSlot->data.two_phase; + ctx->reorder->output_rewrites = ctx->options.receive_rewrites; ereport(LOG, (errmsg("starting logical decoding for slot \"%s\"", NameStr(slot->data.name)), errdetail("Streaming transactions committing after %X/%X, reading WAL from %X/%X.", - (uint32) (slot->data.confirmed_flush >> 32), - (uint32) slot->data.confirmed_flush, - (uint32) (slot->data.restart_lsn >> 32), - (uint32) slot->data.restart_lsn))); + LSN_FORMAT_ARGS(slot->data.confirmed_flush), + LSN_FORMAT_ARGS(slot->data.restart_lsn)))); return ctx; } @@ -531,8 +576,7 @@ DecodingContextFindStartpoint(LogicalDecodingContext *ctx) XLogBeginRead(ctx->reader, slot->data.restart_lsn); elog(DEBUG1, "searching for logical decoding starting point, starting at %X/%X", - (uint32) (slot->data.restart_lsn >> 32), - (uint32) slot->data.restart_lsn); + LSN_FORMAT_ARGS(slot->data.restart_lsn)); /* Wait for a consistent starting point */ for (;;) @@ -558,6 +602,7 @@ DecodingContextFindStartpoint(LogicalDecodingContext *ctx) SpinLockAcquire(&slot->mutex); slot->data.confirmed_flush = ctx->reader->EndRecPtr; + slot->data.initial_consistent_point = ctx->reader->EndRecPtr; SpinLockRelease(&slot->mutex); } @@ -652,8 +697,7 @@ output_plugin_error_callback(void *arg) NameStr(state->ctx->slot->data.name), NameStr(state->ctx->slot->data.plugin), state->callback_name, - (uint32) (state->report_location >> 32), - (uint32) state->report_location); + LSN_FORMAT_ARGS(state->report_location)); else errcontext("slot \"%s\", output plugin \"%s\", in the %s callback", NameStr(state->ctx->slot->data.name), @@ -781,6 +825,190 @@ commit_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, error_context_stack = errcallback.previous; } +/* + * The functionality of begin_prepare is quite similar to begin with the + * exception that this will have gid (global transaction id) information which + * can be used by plugin. Now, we thought about extending the existing begin + * but that would break the replication protocol and additionally this looks + * cleaner. + */ +static void +begin_prepare_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn) +{ + LogicalDecodingContext *ctx = cache->private_data; + LogicalErrorCallbackState state; + ErrorContextCallback errcallback; + + Assert(!ctx->fast_forward); + + /* We're only supposed to call this when two-phase commits are supported */ + Assert(ctx->twophase); + + /* Push callback + info on the error context stack */ + state.ctx = ctx; + state.callback_name = "begin_prepare"; + state.report_location = txn->first_lsn; + errcallback.callback = output_plugin_error_callback; + errcallback.arg = (void *) &state; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + + /* set output state */ + ctx->accept_writes = true; + ctx->write_xid = txn->xid; + ctx->write_location = txn->first_lsn; + + /* + * If the plugin supports two-phase commits then begin prepare callback is + * mandatory + */ + if (ctx->callbacks.begin_prepare_cb == NULL) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("logical replication at prepare time requires a %s callback", + "begin_prepare_cb"))); + + /* do the actual work: call callback */ + ctx->callbacks.begin_prepare_cb(ctx, txn); + + /* Pop the error context stack */ + error_context_stack = errcallback.previous; +} + +static void +prepare_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn) +{ + LogicalDecodingContext *ctx = cache->private_data; + LogicalErrorCallbackState state; + ErrorContextCallback errcallback; + + Assert(!ctx->fast_forward); + + /* We're only supposed to call this when two-phase commits are supported */ + Assert(ctx->twophase); + + /* Push callback + info on the error context stack */ + state.ctx = ctx; + state.callback_name = "prepare"; + state.report_location = txn->final_lsn; /* beginning of prepare record */ + errcallback.callback = output_plugin_error_callback; + errcallback.arg = (void *) &state; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + + /* set output state */ + ctx->accept_writes = true; + ctx->write_xid = txn->xid; + ctx->write_location = txn->end_lsn; /* points to the end of the record */ + + /* + * If the plugin supports two-phase commits then prepare callback is + * mandatory + */ + if (ctx->callbacks.prepare_cb == NULL) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("logical replication at prepare time requires a %s callback", + "prepare_cb"))); + + /* do the actual work: call callback */ + ctx->callbacks.prepare_cb(ctx, txn, prepare_lsn); + + /* Pop the error context stack */ + error_context_stack = errcallback.previous; +} + +static void +commit_prepared_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn) +{ + LogicalDecodingContext *ctx = cache->private_data; + LogicalErrorCallbackState state; + ErrorContextCallback errcallback; + + Assert(!ctx->fast_forward); + + /* We're only supposed to call this when two-phase commits are supported */ + Assert(ctx->twophase); + + /* Push callback + info on the error context stack */ + state.ctx = ctx; + state.callback_name = "commit_prepared"; + state.report_location = txn->final_lsn; /* beginning of commit record */ + errcallback.callback = output_plugin_error_callback; + errcallback.arg = (void *) &state; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + + /* set output state */ + ctx->accept_writes = true; + ctx->write_xid = txn->xid; + ctx->write_location = txn->end_lsn; /* points to the end of the record */ + + /* + * If the plugin support two-phase commits then commit prepared callback + * is mandatory + */ + if (ctx->callbacks.commit_prepared_cb == NULL) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("logical replication at prepare time requires a %s callback", + "commit_prepared_cb"))); + + /* do the actual work: call callback */ + ctx->callbacks.commit_prepared_cb(ctx, txn, commit_lsn); + + /* Pop the error context stack */ + error_context_stack = errcallback.previous; +} + +static void +rollback_prepared_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr prepare_end_lsn, + TimestampTz prepare_time) +{ + LogicalDecodingContext *ctx = cache->private_data; + LogicalErrorCallbackState state; + ErrorContextCallback errcallback; + + Assert(!ctx->fast_forward); + + /* We're only supposed to call this when two-phase commits are supported */ + Assert(ctx->twophase); + + /* Push callback + info on the error context stack */ + state.ctx = ctx; + state.callback_name = "rollback_prepared"; + state.report_location = txn->final_lsn; /* beginning of commit record */ + errcallback.callback = output_plugin_error_callback; + errcallback.arg = (void *) &state; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + + /* set output state */ + ctx->accept_writes = true; + ctx->write_xid = txn->xid; + ctx->write_location = txn->end_lsn; /* points to the end of the record */ + + /* + * If the plugin support two-phase commits then rollback prepared callback + * is mandatory + */ + if (ctx->callbacks.rollback_prepared_cb == NULL) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("logical replication at prepare time requires a %s callback", + "rollback_prepared_cb"))); + + /* do the actual work: call callback */ + ctx->callbacks.rollback_prepared_cb(ctx, txn, prepare_end_lsn, + prepare_time); + + /* Pop the error context stack */ + error_context_stack = errcallback.previous; +} + static void change_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change) @@ -858,6 +1086,37 @@ truncate_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, error_context_stack = errcallback.previous; } +bool +filter_prepare_cb_wrapper(LogicalDecodingContext *ctx, TransactionId xid, + const char *gid) +{ + LogicalErrorCallbackState state; + ErrorContextCallback errcallback; + bool ret; + + Assert(!ctx->fast_forward); + + /* Push callback + info on the error context stack */ + state.ctx = ctx; + state.callback_name = "filter_prepare"; + state.report_location = InvalidXLogRecPtr; + errcallback.callback = output_plugin_error_callback; + errcallback.arg = (void *) &state; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + + /* set output state */ + ctx->accept_writes = false; + + /* do the actual work: call callback */ + ret = ctx->callbacks.filter_prepare_cb(ctx, xid, gid); + + /* Pop the error context stack */ + error_context_stack = errcallback.previous; + + return ret; +} + bool filter_by_origin_cb_wrapper(LogicalDecodingContext *ctx, RepOriginId origin_id) { @@ -962,7 +1221,8 @@ stream_start_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, if (ctx->callbacks.stream_start_cb == NULL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("logical streaming requires a stream_start_cb callback"))); + errmsg("logical streaming requires a %s callback", + "stream_start_cb"))); ctx->callbacks.stream_start_cb(ctx, txn); @@ -1008,7 +1268,8 @@ stream_stop_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, if (ctx->callbacks.stream_stop_cb == NULL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("logical streaming requires a stream_stop_cb callback"))); + errmsg("logical streaming requires a %s callback", + "stream_stop_cb"))); ctx->callbacks.stream_stop_cb(ctx, txn); @@ -1047,7 +1308,8 @@ stream_abort_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, if (ctx->callbacks.stream_abort_cb == NULL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("logical streaming requires a stream_abort_cb callback"))); + errmsg("logical streaming requires a %s callback", + "stream_abort_cb"))); ctx->callbacks.stream_abort_cb(ctx, txn, abort_lsn); @@ -1055,6 +1317,50 @@ stream_abort_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, error_context_stack = errcallback.previous; } +static void +stream_prepare_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, + XLogRecPtr prepare_lsn) +{ + LogicalDecodingContext *ctx = cache->private_data; + LogicalErrorCallbackState state; + ErrorContextCallback errcallback; + + Assert(!ctx->fast_forward); + + /* + * We're only supposed to call this when streaming and two-phase commits + * are supported. + */ + Assert(ctx->streaming); + Assert(ctx->twophase); + + /* Push callback + info on the error context stack */ + state.ctx = ctx; + state.callback_name = "stream_prepare"; + state.report_location = txn->final_lsn; + errcallback.callback = output_plugin_error_callback; + errcallback.arg = (void *) &state; + errcallback.previous = error_context_stack; + error_context_stack = &errcallback; + + /* set output state */ + ctx->accept_writes = true; + ctx->write_xid = txn->xid; + ctx->write_location = txn->end_lsn; + + /* in streaming mode with two-phase commits, stream_prepare_cb is required */ + if (ctx->callbacks.stream_prepare_cb == NULL) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("logical streaming at prepare time requires a %s callback", + "stream_prepare_cb"))); + + ctx->callbacks.stream_prepare_cb(ctx, txn, prepare_lsn); + + /* Pop the error context stack */ + error_context_stack = errcallback.previous; +} + static void stream_commit_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, XLogRecPtr commit_lsn) @@ -1082,11 +1388,12 @@ stream_commit_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, ctx->write_xid = txn->xid; ctx->write_location = txn->end_lsn; - /* in streaming mode, stream_abort_cb is required */ + /* in streaming mode, stream_commit_cb is required */ if (ctx->callbacks.stream_commit_cb == NULL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("logical streaming requires a stream_commit_cb callback"))); + errmsg("logical streaming requires a %s callback", + "stream_commit_cb"))); ctx->callbacks.stream_commit_cb(ctx, txn, commit_lsn); @@ -1132,7 +1439,8 @@ stream_change_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, if (ctx->callbacks.stream_change_cb == NULL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("logical streaming requires a stream_change_cb callback"))); + errmsg("logical streaming requires a %s callback", + "stream_change_cb"))); ctx->callbacks.stream_change_cb(ctx, txn, relation, change); @@ -1334,8 +1642,8 @@ LogicalIncreaseRestartDecodingForSlot(XLogRecPtr current_lsn, XLogRecPtr restart SpinLockRelease(&slot->mutex); elog(DEBUG1, "got new restart lsn %X/%X at %X/%X", - (uint32) (restart_lsn >> 32), (uint32) restart_lsn, - (uint32) (current_lsn >> 32), (uint32) current_lsn); + LSN_FORMAT_ARGS(restart_lsn), + LSN_FORMAT_ARGS(current_lsn)); } else { @@ -1349,14 +1657,11 @@ LogicalIncreaseRestartDecodingForSlot(XLogRecPtr current_lsn, XLogRecPtr restart SpinLockRelease(&slot->mutex); elog(DEBUG1, "failed to increase restart lsn: proposed %X/%X, after %X/%X, current candidate %X/%X, current after %X/%X, flushed up to %X/%X", - (uint32) (restart_lsn >> 32), (uint32) restart_lsn, - (uint32) (current_lsn >> 32), (uint32) current_lsn, - (uint32) (candidate_restart_lsn >> 32), - (uint32) candidate_restart_lsn, - (uint32) (candidate_restart_valid >> 32), - (uint32) candidate_restart_valid, - (uint32) (confirmed_flush >> 32), - (uint32) confirmed_flush); + LSN_FORMAT_ARGS(restart_lsn), + LSN_FORMAT_ARGS(current_lsn), + LSN_FORMAT_ARGS(candidate_restart_lsn), + LSN_FORMAT_ARGS(candidate_restart_valid), + LSN_FORMAT_ARGS(confirmed_flush)); } /* candidates are already valid with the current flush position, apply */ @@ -1460,3 +1765,49 @@ ResetLogicalStreamingState(void) CheckXidAlive = InvalidTransactionId; bsysscan = false; } + +/* + * Report stats for a slot. + */ +void +UpdateDecodingStats(LogicalDecodingContext *ctx) +{ + ReorderBuffer *rb = ctx->reorder; + PgStat_StatReplSlotEntry repSlotStat; + + /* Nothing to do if we don't have any replication stats to be sent. */ + if (rb->spillBytes <= 0 && rb->streamBytes <= 0 && rb->totalBytes <= 0) + return; + + elog(DEBUG2, "UpdateDecodingStats: updating stats %p %lld %lld %lld %lld %lld %lld %lld %lld", + rb, + (long long) rb->spillTxns, + (long long) rb->spillCount, + (long long) rb->spillBytes, + (long long) rb->streamTxns, + (long long) rb->streamCount, + (long long) rb->streamBytes, + (long long) rb->totalTxns, + (long long) rb->totalBytes); + + namestrcpy(&repSlotStat.slotname, NameStr(ctx->slot->data.name)); + repSlotStat.spill_txns = rb->spillTxns; + repSlotStat.spill_count = rb->spillCount; + repSlotStat.spill_bytes = rb->spillBytes; + repSlotStat.stream_txns = rb->streamTxns; + repSlotStat.stream_count = rb->streamCount; + repSlotStat.stream_bytes = rb->streamBytes; + repSlotStat.total_txns = rb->totalTxns; + repSlotStat.total_bytes = rb->totalBytes; + + pgstat_report_replslot(&repSlotStat); + + rb->spillTxns = 0; + rb->spillCount = 0; + rb->spillBytes = 0; + rb->streamTxns = 0; + rb->streamCount = 0; + rb->streamBytes = 0; + rb->totalTxns = 0; + rb->totalBytes = 0; +} diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c index ce04c0adeacc..0805c7080f28 100644 --- a/src/backend/replication/logical/logicalfuncs.c +++ b/src/backend/replication/logical/logicalfuncs.c @@ -6,7 +6,7 @@ * logical replication slots via SQL. * * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logicalfuncs.c @@ -225,7 +225,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin else end_of_wal = GetXLogReplayRecPtr(&ThisTimeLineID); - (void) ReplicationSlotAcquire(NameStr(*name), SAB_Error); + ReplicationSlotAcquire(NameStr(*name), true); PG_TRY(); { @@ -250,7 +250,7 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("can no longer get changes from replication slot \"%s\"", NameStr(*name)), - errdetail("This slot has never previously reserved WAL, or has been invalidated."))); + errdetail("This slot has never previously reserved WAL, or it has been invalidated."))); MemoryContextSwitchTo(oldcontext); diff --git a/src/backend/replication/logical/message.c b/src/backend/replication/logical/message.c index db33cbe5a7a2..93bd372421a6 100644 --- a/src/backend/replication/logical/message.c +++ b/src/backend/replication/logical/message.c @@ -3,7 +3,7 @@ * message.c * Generic logical messages. * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Copyright (c) 2013-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/message.c @@ -32,7 +32,6 @@ #include "postgres.h" #include "access/xact.h" -#include "catalog/indexing.h" #include "miscadmin.h" #include "nodes/execnodes.h" #include "replication/logical.h" @@ -59,6 +58,7 @@ LogLogicalMessage(const char *prefix, const char *message, size_t size, xlrec.dbId = MyDatabaseId; xlrec.transactional = transactional; + /* trailing zero is critical; see logicalmsg_desc */ xlrec.prefix_size = strlen(prefix) + 1; xlrec.message_size = size; diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index 1b220315dff8..cb42fcb34d12 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -3,7 +3,7 @@ * origin.c * Logical replication progress tracking support. * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Copyright (c) 2013-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/origin.c @@ -206,7 +206,7 @@ replorigin_check_prerequisites(bool check_slots, bool recoveryOK) * Returns InvalidOid if the node isn't known yet and missing_ok is true. */ RepOriginId -replorigin_by_name(char *roname, bool missing_ok) +replorigin_by_name(const char *roname, bool missing_ok) { Form_pg_replication_origin ident; Oid roident = InvalidOid; @@ -237,7 +237,7 @@ replorigin_by_name(char *roname, bool missing_ok) * Needs to be called in a transaction. */ RepOriginId -replorigin_create(char *roname) +replorigin_create(const char *roname) { Oid roident; HeapTuple tuple = NULL; @@ -322,27 +322,15 @@ replorigin_create(char *roname) return roident; } - /* - * Drop replication origin. - * - * Needs to be called in a transaction. + * Helper function to drop a replication origin. */ -void -replorigin_drop(RepOriginId roident, bool nowait) +static void +replorigin_drop_guts(Relation rel, RepOriginId roident, bool nowait) { HeapTuple tuple; - Relation rel; int i; - Assert(IsTransactionState()); - - /* - * To interlock against concurrent drops, we hold ExclusiveLock on - * pg_replication_origin throughout this function. - */ - rel = table_open(ReplicationOriginRelationId, ExclusiveLock); - /* * First, clean up the slot state info, if there is any matching slot. */ @@ -415,11 +403,40 @@ replorigin_drop(RepOriginId roident, bool nowait) ReleaseSysCache(tuple); CommandCounterIncrement(); - - /* now release lock again */ - table_close(rel, ExclusiveLock); } +/* + * Drop replication origin (by name). + * + * Needs to be called in a transaction. + */ +void +replorigin_drop_by_name(const char *name, bool missing_ok, bool nowait) +{ + RepOriginId roident; + Relation rel; + + Assert(IsTransactionState()); + + /* + * To interlock against concurrent drops, we hold ExclusiveLock on + * pg_replication_origin till xact commit. + * + * XXX We can optimize this by acquiring the lock on a specific origin by + * using LockSharedObject if required. However, for that, we first to + * acquire a lock on ReplicationOriginRelationId, get the origin_id, lock + * the specific origin and then re-check if the origin still exists. + */ + rel = table_open(ReplicationOriginRelationId, ExclusiveLock); + + roident = replorigin_by_name(name, missing_ok); + + if (OidIsValid(roident)) + replorigin_drop_guts(rel, roident, nowait); + + /* We keep the lock on pg_replication_origin until commit */ + table_close(rel, NoLock); +} /* * Lookup replication origin via its oid and return the name. @@ -559,8 +576,8 @@ CheckPointReplicationOrigin(void) tmppath))); /* - * no other backend can perform this at the same time, we're protected by - * CheckpointLock. + * no other backend can perform this at the same time; only one checkpoint + * can happen at a time. */ tmpfd = OpenTransientFile(tmppath, O_CREAT | O_EXCL | O_WRONLY | PG_BINARY); @@ -769,10 +786,10 @@ StartupReplicationOrigin(void) replication_states[last_state].remote_lsn = disk_state.remote_lsn; last_state++; - elog(LOG, "recovered replication state of node %u to %X/%X", - disk_state.roident, - (uint32) (disk_state.remote_lsn >> 32), - (uint32) disk_state.remote_lsn); + ereport(LOG, + (errmsg("recovered replication state of node %u to %X/%X", + disk_state.roident, + LSN_FORMAT_ARGS(disk_state.remote_lsn)))); } /* now check checksum */ @@ -842,7 +859,7 @@ replorigin_redo(XLogReaderState *record) * that originated at the LSN remote_commit on the remote node was replayed * successfully and that we don't need to do so again. In combination with * setting up replorigin_session_origin_lsn and replorigin_session_origin - * that ensures we won't loose knowledge about that after a crash if the + * that ensures we won't lose knowledge about that after a crash if the * transaction had a persistent effect (think of asynchronous commits). * * local_commit needs to be a local LSN of the commit so that we can make sure @@ -1255,16 +1272,12 @@ Datum pg_replication_origin_drop(PG_FUNCTION_ARGS) { char *name; - RepOriginId roident; replorigin_check_prerequisites(false, false); name = text_to_cstring((text *) DatumGetPointer(PG_GETARG_DATUM(0))); - roident = replorigin_by_name(name, false); - Assert(OidIsValid(roident)); - - replorigin_drop(roident, true); + replorigin_drop_by_name(name, false, true); pfree(name); diff --git a/src/backend/replication/logical/proto.c b/src/backend/replication/logical/proto.c index 9ff8097bf5fd..1cf59e0fb0fa 100644 --- a/src/backend/replication/logical/proto.c +++ b/src/backend/replication/logical/proto.c @@ -3,7 +3,7 @@ * proto.c * logical replication protocol functions * - * Copyright (c) 2015-2020, PostgreSQL Global Development Group + * Copyright (c) 2015-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/proto.c @@ -25,6 +25,7 @@ */ #define LOGICALREP_IS_REPLICA_IDENTITY 1 +#define MESSAGE_TRANSACTIONAL (1<<0) #define TRUNCATE_CASCADE (1<<0) #define TRUNCATE_RESTART_SEQS (1<<1) @@ -44,7 +45,7 @@ static const char *logicalrep_read_namespace(StringInfo in); void logicalrep_write_begin(StringInfo out, ReorderBufferTXN *txn) { - pq_sendbyte(out, 'B'); /* BEGIN */ + pq_sendbyte(out, LOGICAL_REP_MSG_BEGIN); /* fixed fields */ pq_sendint64(out, txn->final_lsn); @@ -76,7 +77,7 @@ logicalrep_write_commit(StringInfo out, ReorderBufferTXN *txn, { uint8 flags = 0; - pq_sendbyte(out, 'C'); /* sending COMMIT */ + pq_sendbyte(out, LOGICAL_REP_MSG_COMMIT); /* send the flags field (unused for now) */ pq_sendbyte(out, flags); @@ -112,7 +113,7 @@ void logicalrep_write_origin(StringInfo out, const char *origin, XLogRecPtr origin_lsn) { - pq_sendbyte(out, 'O'); /* ORIGIN */ + pq_sendbyte(out, LOGICAL_REP_MSG_ORIGIN); /* fixed fields */ pq_sendint64(out, origin_lsn); @@ -138,9 +139,14 @@ logicalrep_read_origin(StringInfo in, XLogRecPtr *origin_lsn) * Write INSERT to the output stream. */ void -logicalrep_write_insert(StringInfo out, Relation rel, HeapTuple newtuple, bool binary) +logicalrep_write_insert(StringInfo out, TransactionId xid, Relation rel, + HeapTuple newtuple, bool binary) { - pq_sendbyte(out, 'I'); /* action INSERT */ + pq_sendbyte(out, LOGICAL_REP_MSG_INSERT); + + /* transaction ID (if not valid, we're not streaming) */ + if (TransactionIdIsValid(xid)) + pq_sendint32(out, xid); /* use Oid as relation identifier */ pq_sendint32(out, RelationGetRelid(rel)); @@ -177,15 +183,19 @@ logicalrep_read_insert(StringInfo in, LogicalRepTupleData *newtup) * Write UPDATE to the output stream. */ void -logicalrep_write_update(StringInfo out, Relation rel, HeapTuple oldtuple, - HeapTuple newtuple, bool binary) +logicalrep_write_update(StringInfo out, TransactionId xid, Relation rel, + HeapTuple oldtuple, HeapTuple newtuple, bool binary) { - pq_sendbyte(out, 'U'); /* action UPDATE */ + pq_sendbyte(out, LOGICAL_REP_MSG_UPDATE); Assert(rel->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT || rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL || rel->rd_rel->relreplident == REPLICA_IDENTITY_INDEX); + /* transaction ID (if not valid, we're not streaming) */ + if (TransactionIdIsValid(xid)) + pq_sendint32(out, xid); + /* use Oid as relation identifier */ pq_sendint32(out, RelationGetRelid(rel)); @@ -247,13 +257,18 @@ logicalrep_read_update(StringInfo in, bool *has_oldtuple, * Write DELETE to the output stream. */ void -logicalrep_write_delete(StringInfo out, Relation rel, HeapTuple oldtuple, bool binary) +logicalrep_write_delete(StringInfo out, TransactionId xid, Relation rel, + HeapTuple oldtuple, bool binary) { Assert(rel->rd_rel->relreplident == REPLICA_IDENTITY_DEFAULT || rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL || rel->rd_rel->relreplident == REPLICA_IDENTITY_INDEX); - pq_sendbyte(out, 'D'); /* action DELETE */ + pq_sendbyte(out, LOGICAL_REP_MSG_DELETE); + + /* transaction ID (if not valid, we're not streaming) */ + if (TransactionIdIsValid(xid)) + pq_sendint32(out, xid); /* use Oid as relation identifier */ pq_sendint32(out, RelationGetRelid(rel)); @@ -295,6 +310,7 @@ logicalrep_read_delete(StringInfo in, LogicalRepTupleData *oldtup) */ void logicalrep_write_truncate(StringInfo out, + TransactionId xid, int nrelids, Oid relids[], bool cascade, bool restart_seqs) @@ -302,7 +318,11 @@ logicalrep_write_truncate(StringInfo out, int i; uint8 flags = 0; - pq_sendbyte(out, 'T'); /* action TRUNCATE */ + pq_sendbyte(out, LOGICAL_REP_MSG_TRUNCATE); + + /* transaction ID (if not valid, we're not streaming) */ + if (TransactionIdIsValid(xid)) + pq_sendint32(out, xid); pq_sendint32(out, nrelids); @@ -342,15 +362,46 @@ logicalrep_read_truncate(StringInfo in, return relids; } +/* + * Write MESSAGE to stream + */ +void +logicalrep_write_message(StringInfo out, TransactionId xid, XLogRecPtr lsn, + bool transactional, const char *prefix, Size sz, + const char *message) +{ + uint8 flags = 0; + + pq_sendbyte(out, LOGICAL_REP_MSG_MESSAGE); + + /* encode and send message flags */ + if (transactional) + flags |= MESSAGE_TRANSACTIONAL; + + /* transaction ID (if not valid, we're not streaming) */ + if (TransactionIdIsValid(xid)) + pq_sendint32(out, xid); + + pq_sendint8(out, flags); + pq_sendint64(out, lsn); + pq_sendstring(out, prefix); + pq_sendint32(out, sz); + pq_sendbytes(out, message, sz); +} + /* * Write relation description to the output stream. */ void -logicalrep_write_rel(StringInfo out, Relation rel) +logicalrep_write_rel(StringInfo out, TransactionId xid, Relation rel) { char *relname; - pq_sendbyte(out, 'R'); /* sending RELATION */ + pq_sendbyte(out, LOGICAL_REP_MSG_RELATION); + + /* transaction ID (if not valid, we're not streaming) */ + if (TransactionIdIsValid(xid)) + pq_sendint32(out, xid); /* use Oid as relation identifier */ pq_sendint32(out, RelationGetRelid(rel)); @@ -396,13 +447,17 @@ logicalrep_read_rel(StringInfo in) * This function will always write base type info. */ void -logicalrep_write_typ(StringInfo out, Oid typoid) +logicalrep_write_typ(StringInfo out, TransactionId xid, Oid typoid) { Oid basetypoid = getBaseType(typoid); HeapTuple tup; Form_pg_type typtup; - pq_sendbyte(out, 'Y'); /* sending TYPE */ + pq_sendbyte(out, LOGICAL_REP_MSG_TYPE); + + /* transaction ID (if not valid, we're not streaming) */ + if (TransactionIdIsValid(xid)) + pq_sendint32(out, xid); tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(basetypoid)); if (!HeapTupleIsValid(tup)) @@ -466,7 +521,6 @@ logicalrep_write_tuple(StringInfo out, Relation rel, HeapTuple tuple, bool binar HeapTuple typtup; Form_pg_type typclass; Form_pg_attribute att = TupleDescAttr(desc, i); - char *outputstr; if (att->attisdropped || att->attgenerated) continue; @@ -510,6 +564,8 @@ logicalrep_write_tuple(StringInfo out, Relation rel, HeapTuple tuple, bool binar } else { + char *outputstr; + pq_sendbyte(out, LOGICALREP_COLUMN_TEXT); outputstr = OidOutputFunctionCall(typclass->typoutput, values[i]); pq_sendcountedtext(out, outputstr, strlen(outputstr), false); @@ -612,8 +668,7 @@ logicalrep_write_attrs(StringInfo out, Relation rel) /* fetch bitmap of REPLICATION IDENTITY attributes */ replidentfull = (rel->rd_rel->relreplident == REPLICA_IDENTITY_FULL); if (!replidentfull) - idattrs = RelationGetIndexAttrBitmap(rel, - INDEX_ATTR_BITMAP_IDENTITY_KEY); + idattrs = RelationGetIdentityKeyBitmap(rel); /* send the attributes */ for (i = 0; i < desc->natts; i++) @@ -720,3 +775,126 @@ logicalrep_read_namespace(StringInfo in) return nspname; } + +/* + * Write the information for the start stream message to the output stream. + */ +void +logicalrep_write_stream_start(StringInfo out, + TransactionId xid, bool first_segment) +{ + pq_sendbyte(out, LOGICAL_REP_MSG_STREAM_START); + + Assert(TransactionIdIsValid(xid)); + + /* transaction ID (we're starting to stream, so must be valid) */ + pq_sendint32(out, xid); + + /* 1 if this is the first streaming segment for this xid */ + pq_sendbyte(out, first_segment ? 1 : 0); +} + +/* + * Read the information about the start stream message from output stream. + */ +TransactionId +logicalrep_read_stream_start(StringInfo in, bool *first_segment) +{ + TransactionId xid; + + Assert(first_segment); + + xid = pq_getmsgint(in, 4); + *first_segment = (pq_getmsgbyte(in) == 1); + + return xid; +} + +/* + * Write the stop stream message to the output stream. + */ +void +logicalrep_write_stream_stop(StringInfo out) +{ + pq_sendbyte(out, LOGICAL_REP_MSG_STREAM_END); +} + +/* + * Write STREAM COMMIT to the output stream. + */ +void +logicalrep_write_stream_commit(StringInfo out, ReorderBufferTXN *txn, + XLogRecPtr commit_lsn) +{ + uint8 flags = 0; + + pq_sendbyte(out, LOGICAL_REP_MSG_STREAM_COMMIT); + + Assert(TransactionIdIsValid(txn->xid)); + + /* transaction ID */ + pq_sendint32(out, txn->xid); + + /* send the flags field (unused for now) */ + pq_sendbyte(out, flags); + + /* send fields */ + pq_sendint64(out, commit_lsn); + pq_sendint64(out, txn->end_lsn); + pq_sendint64(out, txn->commit_time); +} + +/* + * Read STREAM COMMIT from the output stream. + */ +TransactionId +logicalrep_read_stream_commit(StringInfo in, LogicalRepCommitData *commit_data) +{ + TransactionId xid; + uint8 flags; + + xid = pq_getmsgint(in, 4); + + /* read flags (unused for now) */ + flags = pq_getmsgbyte(in); + + if (flags != 0) + elog(ERROR, "unrecognized flags %u in commit message", flags); + + /* read fields */ + commit_data->commit_lsn = pq_getmsgint64(in); + commit_data->end_lsn = pq_getmsgint64(in); + commit_data->committime = pq_getmsgint64(in); + + return xid; +} + +/* + * Write STREAM ABORT to the output stream. Note that xid and subxid will be + * same for the top-level transaction abort. + */ +void +logicalrep_write_stream_abort(StringInfo out, TransactionId xid, + TransactionId subxid) +{ + pq_sendbyte(out, LOGICAL_REP_MSG_STREAM_ABORT); + + Assert(TransactionIdIsValid(xid) && TransactionIdIsValid(subxid)); + + /* transaction ID */ + pq_sendint32(out, xid); + pq_sendint32(out, subxid); +} + +/* + * Read STREAM ABORT from the output stream. + */ +void +logicalrep_read_stream_abort(StringInfo in, TransactionId *xid, + TransactionId *subxid) +{ + Assert(xid && subxid); + + *xid = pq_getmsgint(in, 4); + *subxid = pq_getmsgint(in, 4); +} diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index a60c73d74d5b..12be5f259b71 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -1,15 +1,16 @@ /*------------------------------------------------------------------------- * relation.c - * PostgreSQL logical replication + * PostgreSQL logical replication relation mapping cache * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/relation.c * * NOTES - * This file contains helper functions for logical replication relation - * mapping cache. + * Routines in this file mainly have to do with mapping the properties + * of local replication target relations to the properties of their + * remote counterpart. * *------------------------------------------------------------------------- */ @@ -77,7 +78,7 @@ logicalrep_relmap_invalidate_cb(Datum arg, Oid reloid) { if (entry->localreloid == reloid) { - entry->localreloid = InvalidOid; + entry->localrelvalid = false; hash_seq_term(&status); break; } @@ -91,7 +92,7 @@ logicalrep_relmap_invalidate_cb(Datum arg, Oid reloid) hash_seq_init(&status, LogicalRepRelMap); while ((entry = (LogicalRepRelMapEntry *) hash_seq_search(&status)) != NULL) - entry->localreloid = InvalidOid; + entry->localrelvalid = false; } } @@ -110,7 +111,6 @@ logicalrep_relmap_init(void) ALLOCSET_DEFAULT_SIZES); /* Initialize the relation hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(LogicalRepRelId); ctl.entrysize = sizeof(LogicalRepRelMapEntry); ctl.hcxt = LogicalRepRelMapContext; @@ -119,7 +119,6 @@ logicalrep_relmap_init(void) HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); /* Initialize the type hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(LogicalRepTyp); ctl.hcxt = LogicalRepRelMapContext; @@ -227,18 +226,53 @@ logicalrep_rel_att_by_name(LogicalRepRelation *remoterel, const char *attname) return -1; } +/* + * Report error with names of the missing local relation column(s), if any. + */ +static void +logicalrep_report_missing_attrs(LogicalRepRelation *remoterel, + Bitmapset *missingatts) +{ + if (!bms_is_empty(missingatts)) + { + StringInfoData missingattsbuf; + int missingattcnt = 0; + int i; + + initStringInfo(&missingattsbuf); + + while ((i = bms_first_member(missingatts)) >= 0) + { + missingattcnt++; + if (missingattcnt == 1) + appendStringInfo(&missingattsbuf, _("\"%s\""), + remoterel->attnames[i]); + else + appendStringInfo(&missingattsbuf, _(", \"%s\""), + remoterel->attnames[i]); + } + + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg_plural("logical replication target relation \"%s.%s\" is missing replicated column: %s", + "logical replication target relation \"%s.%s\" is missing replicated columns: %s", + missingattcnt, + remoterel->nspname, + remoterel->relname, + missingattsbuf.data))); + } +} + /* * Open the local relation associated with the remote one. * - * Optionally rebuilds the Relcache mapping if it was invalidated - * by local DDL. + * Rebuilds the Relcache mapping if it was invalidated by local DDL. */ LogicalRepRelMapEntry * logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) { LogicalRepRelMapEntry *entry; bool found; - Oid relid = InvalidOid; LogicalRepRelation *remoterel; if (LogicalRepRelMap == NULL) @@ -254,14 +288,45 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) remoterel = &entry->remoterel; + /* Ensure we don't leak a relcache refcount. */ + if (entry->localrel) + elog(ERROR, "remote relation ID %u is already open", remoteid); + /* * When opening and locking a relation, pending invalidation messages are - * processed which can invalidate the relation. We need to update the - * local cache both when we are first time accessing the relation and when - * the relation is invalidated (aka entry->localreloid is set InvalidOid). + * processed which can invalidate the relation. Hence, if the entry is + * currently considered valid, try to open the local relation by OID and + * see if invalidation ensues. + */ + if (entry->localrelvalid) + { + entry->localrel = try_table_open(entry->localreloid, lockmode, false); + if (!entry->localrel) + { + /* Table was renamed or dropped. */ + entry->localrelvalid = false; + } + else if (!entry->localrelvalid) + { + /* Note we release the no-longer-useful lock here. */ + table_close(entry->localrel, lockmode); + entry->localrel = NULL; + } + } + + /* + * If the entry has been marked invalid since we last had lock on it, + * re-open the local relation by name and rebuild all derived data. */ - if (!OidIsValid(entry->localreloid)) + if (!entry->localrelvalid) { + Oid relid; + Bitmapset *idkey; + TupleDesc desc; + MemoryContext oldctx; + int i; + Bitmapset *missingatts; + /* Try to find and lock the relation by name. */ relid = RangeVarGetRelid(makeRangeVar(remoterel->nspname, remoterel->relname, -1), @@ -272,21 +337,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) errmsg("logical replication target relation \"%s.%s\" does not exist", remoterel->nspname, remoterel->relname))); entry->localrel = table_open(relid, NoLock); - - } - else - { - relid = entry->localreloid; - entry->localrel = table_open(entry->localreloid, lockmode); - } - - if (!OidIsValid(entry->localreloid)) - { - int found; - Bitmapset *idkey; - TupleDesc desc; - MemoryContext oldctx; - int i; + entry->localreloid = relid; /* Check for supported relkind. */ CheckSubscriptionRelkind(entry->localrel->rd_rel->relkind, @@ -302,7 +353,8 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) entry->attrmap = make_attrmap(desc->natts); MemoryContextSwitchTo(oldctx); - found = 0; + /* check and report missing attrs, if any */ + missingatts = bms_add_range(NULL, 0, remoterel->natts - 1); for (i = 0; i < desc->natts; i++) { int attnum; @@ -319,16 +371,13 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) entry->attrmap->attnums[i] = attnum; if (attnum >= 0) - found++; + missingatts = bms_del_member(missingatts, attnum); } - /* TODO, detail message with names of missing columns */ - if (found < remoterel->natts) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("logical replication target relation \"%s.%s\" is missing " - "some replicated columns", - remoterel->nspname, remoterel->relname))); + logicalrep_report_missing_attrs(remoterel, missingatts); + + /* be tidy */ + bms_free(missingatts); /* * Check that replica identity matches. We allow for stricter replica @@ -380,14 +429,13 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) } } - entry->localreloid = relid; + entry->localrelvalid = true; } if (entry->state != SUBREL_STATE_READY) entry->state = GetSubscriptionRelState(MySubscription->oid, entry->localreloid, - &entry->statelsn, - true); + &entry->statelsn); return entry; } @@ -523,7 +571,7 @@ logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid) { if (entry->localreloid == reloid) { - entry->localreloid = InvalidOid; + entry->localrelvalid = false; hash_seq_term(&status); break; } @@ -537,7 +585,7 @@ logicalrep_partmap_invalidate_cb(Datum arg, Oid reloid) hash_seq_init(&status, LogicalRepPartMap); while ((entry = (LogicalRepRelMapEntry *) hash_seq_search(&status)) != NULL) - entry->localreloid = InvalidOid; + entry->localrelvalid = false; } } @@ -556,7 +604,6 @@ logicalrep_partmap_init(void) ALLOCSET_DEFAULT_SIZES); /* Initialize the relation hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); /* partition OID */ ctl.entrysize = sizeof(LogicalRepPartMapEntry); ctl.hcxt = LogicalRepPartMapContext; @@ -573,7 +620,9 @@ logicalrep_partmap_init(void) * logicalrep_partition_open * * Returned entry reuses most of the values of the root table's entry, save - * the attribute map, which can be different for the partition. + * the attribute map, which can be different for the partition. However, + * we must physically copy all the data, in case the root table's entry + * gets freed/rebuilt. * * Note there's no logicalrep_partition_close, because the caller closes the * component relation. @@ -609,7 +658,7 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root, part_entry->partoid = partOid; - /* Remote relation is used as-is from the root entry. */ + /* Remote relation is copied as-is from the root entry. */ entry = &part_entry->relmapentry; entry->remoterel.remoteid = remoterel->remoteid; entry->remoterel.nspname = pstrdup(remoterel->nspname); @@ -631,8 +680,8 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root, /* * If the partition's attributes don't match the root relation's, we'll * need to make a new attrmap which maps partition attribute numbers to - * remoterel's, instead the original which maps root relation's attribute - * numbers to remoterel's. + * remoterel's, instead of the original which maps root relation's + * attribute numbers to remoterel's. * * Note that 'map' which comes from the tuple routing data structure * contains 1-based attribute numbers (of the parent relation). However, @@ -652,10 +701,17 @@ logicalrep_partition_open(LogicalRepRelMapEntry *root, } } else - entry->attrmap = attrmap; + { + /* Lacking copy_attmap, do this the hard way. */ + entry->attrmap = make_attrmap(attrmap->maplen); + memcpy(entry->attrmap->attnums, attrmap->attnums, + attrmap->maplen * sizeof(AttrNumber)); + } entry->updatable = root->updatable; + entry->localrelvalid = true; + /* state and statelsn are left set to 0. */ MemoryContextSwitchTo(oldctx); diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 1975d629a6e2..ad1c2bad0136 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -4,7 +4,7 @@ * PostgreSQL logical replay/reorder buffer management * * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -235,7 +235,7 @@ static void ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn, static ReorderBufferChange *ReorderBufferIterTXNNext(ReorderBuffer *rb, ReorderBufferIterTXNState *state); static void ReorderBufferIterTXNFinish(ReorderBuffer *rb, ReorderBufferIterTXNState *state); -static void ReorderBufferExecuteInvalidations(ReorderBuffer *rb, ReorderBufferTXN *txn); +static void ReorderBufferExecuteInvalidations(uint32 nmsgs, SharedInvalidationMessage *msgs); /* * --------------------------------------- @@ -251,7 +251,8 @@ static Size ReorderBufferRestoreChanges(ReorderBuffer *rb, ReorderBufferTXN *txn static void ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, char *change); static void ReorderBufferRestoreCleanup(ReorderBuffer *rb, ReorderBufferTXN *txn); -static void ReorderBufferTruncateTXN(ReorderBuffer *rb, ReorderBufferTXN *txn); +static void ReorderBufferTruncateTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, + bool txn_prepared); static void ReorderBufferCleanupSerializedTXNs(const char *slotname); static void ReorderBufferSerializedPath(char *path, ReplicationSlot *slot, TransactionId xid, XLogSegNo segno); @@ -343,6 +344,15 @@ ReorderBufferAllocate(void) buffer->outbufsize = 0; buffer->size = 0; + buffer->spillTxns = 0; + buffer->spillCount = 0; + buffer->spillBytes = 0; + buffer->streamTxns = 0; + buffer->streamCount = 0; + buffer->streamBytes = 0; + buffer->totalTxns = 0; + buffer->totalBytes = 0; + buffer->current_restart_decoding_lsn = InvalidXLogRecPtr; dlist_init(&buffer->toplevel_by_lsn); @@ -395,6 +405,7 @@ ReorderBufferGetTXN(ReorderBuffer *rb) /* InvalidCommandId is not zero, so set it explicitly */ txn->command_id = InvalidCommandId; + txn->output_plugin_private = NULL; return txn; } @@ -414,6 +425,12 @@ ReorderBufferReturnTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) /* free data that's contained */ + if (txn->gid != NULL) + { + pfree(txn->gid); + txn->gid = NULL; + } + if (txn->tuplecid_hash != NULL) { hash_destroy(txn->tuplecid_hash); @@ -426,6 +443,9 @@ ReorderBufferReturnTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) txn->invalidations = NULL; } + /* Reset the toast hash */ + ReorderBufferToastReset(rb, txn); + pfree(txn); } @@ -482,6 +502,11 @@ ReorderBufferReturnChange(ReorderBuffer *rb, ReorderBufferChange *change, pfree(change->data.msg.message); change->data.msg.message = NULL; break; + case REORDER_BUFFER_CHANGE_INVALIDATION: + if (change->data.inval.invalidations) + pfree(change->data.inval.invalidations); + change->data.inval.invalidations = NULL; + break; case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT: if (change->data.snapshot) { @@ -498,6 +523,7 @@ ReorderBufferReturnChange(ReorderBuffer *rb, ReorderBufferChange *change, } break; case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: + case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: break; @@ -683,31 +709,35 @@ ReorderBufferProcessPartialChange(ReorderBuffer *rb, ReorderBufferTXN *txn, toptxn = txn; /* - * Set the toast insert bit whenever we get toast insert to indicate a - * partial change and clear it when we get the insert or update on main - * table (Both update and insert will do the insert in the toast table). + * Indicate a partial change for toast inserts. The change will be + * considered as complete once we get the insert or update on the main + * table and we are sure that the pending toast chunks are not required + * anymore. + * + * If we allow streaming when there are pending toast chunks then such + * chunks won't be released till the insert (multi_insert) is complete and + * we expect the txn to have streamed all changes after streaming. This + * restriction is mainly to ensure the correctness of streamed + * transactions and it doesn't seem worth uplifting such a restriction + * just to allow this case because anyway we will stream the transaction + * once such an insert is complete. */ if (toast_insert) - toptxn->txn_flags |= RBTXN_HAS_TOAST_INSERT; - else if (rbtxn_has_toast_insert(toptxn) && - IsInsertOrUpdate(change->action)) - toptxn->txn_flags &= ~RBTXN_HAS_TOAST_INSERT; + toptxn->txn_flags |= RBTXN_HAS_PARTIAL_CHANGE; + else if (rbtxn_has_partial_change(toptxn) && + IsInsertOrUpdate(change->action) && + change->data.tp.clear_toast_afterwards) + toptxn->txn_flags &= ~RBTXN_HAS_PARTIAL_CHANGE; /* - * Set the spec insert bit whenever we get the speculative insert to - * indicate the partial change and clear the same on speculative confirm. + * Indicate a partial change for speculative inserts. The change will be + * considered as complete once we get the speculative confirm token. */ if (IsSpecInsert(change->action)) - toptxn->txn_flags |= RBTXN_HAS_SPEC_INSERT; - else if (IsSpecConfirm(change->action)) - { - /* - * Speculative confirm change must be preceded by speculative - * insertion. - */ - Assert(rbtxn_has_spec_insert(toptxn)); - toptxn->txn_flags &= ~RBTXN_HAS_SPEC_INSERT; - } + toptxn->txn_flags |= RBTXN_HAS_PARTIAL_CHANGE; + else if (rbtxn_has_partial_change(toptxn) && + IsSpecConfirm(change->action)) + toptxn->txn_flags &= ~RBTXN_HAS_PARTIAL_CHANGE; /* * Stream the transaction if it is serialized before and the changes are @@ -719,7 +749,7 @@ ReorderBufferProcessPartialChange(ReorderBuffer *rb, ReorderBufferTXN *txn, * changes. Delaying such transactions would increase apply lag for them. */ if (ReorderBufferCanStartStreaming(rb) && - !(rbtxn_has_incomplete_tuple(toptxn)) && + !(rbtxn_has_partial_change(toptxn)) && rbtxn_is_serialized(txn)) ReorderBufferStreamTXN(rb, toptxn); } @@ -770,7 +800,8 @@ ReorderBufferQueueChange(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn, } /* - * Queue message into a transaction so it can be processed upon commit. + * A transactional message is queued to be processed upon commit and a + * non-transactional message gets processed immediately. */ void ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid, @@ -1342,6 +1373,12 @@ ReorderBufferIterTXNNext(ReorderBuffer *rb, ReorderBufferIterTXNState *state) dlist_delete(&change->node); dlist_push_tail(&state->old_change, &change->node); + /* + * Update the total bytes processed by the txn for which we are + * releasing the current set of changes and restoring the new set of + * changes. + */ + rb->totalBytes += entry->txn->size; if (ReorderBufferRestoreChanges(rb, entry->txn, &entry->file, &state->entries[off].segno)) { @@ -1428,7 +1465,7 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) ReorderBufferCleanupTXN(rb, subtxn); } - /* cleanup changes in the toplevel txn */ + /* cleanup changes in the txn */ dlist_foreach_modify(iter, &txn->changes) { ReorderBufferChange *change; @@ -1502,12 +1539,18 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) } /* - * Discard changes from a transaction (and subtransactions), after streaming - * them. Keep the remaining info - transactions, tuplecids, invalidations and - * snapshots. + * Discard changes from a transaction (and subtransactions), either after + * streaming or decoding them at PREPARE. Keep the remaining info - + * transactions, tuplecids, invalidations and snapshots. + * + * We additionaly remove tuplecids after decoding the transaction at prepare + * time as we only need to perform invalidation at rollback or commit prepared. + * + * 'txn_prepared' indicates that we have decoded the transaction at prepare + * time. */ static void -ReorderBufferTruncateTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) +ReorderBufferTruncateTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, bool txn_prepared) { dlist_mutable_iter iter; @@ -1526,10 +1569,10 @@ ReorderBufferTruncateTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) Assert(rbtxn_is_known_subxact(subtxn)); Assert(subtxn->nsubtxns == 0); - ReorderBufferTruncateTXN(rb, subtxn); + ReorderBufferTruncateTXN(rb, subtxn, txn_prepared); } - /* cleanup changes in the toplevel txn */ + /* cleanup changes in the txn */ dlist_foreach_modify(iter, &txn->changes) { ReorderBufferChange *change; @@ -1560,9 +1603,33 @@ ReorderBufferTruncateTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) * about the toplevel xact (we send the XID in all messages), but we never * stream XIDs of empty subxacts. */ - if ((!txn->toptxn) || (txn->nentries_mem != 0)) + if ((!txn_prepared) && ((!txn->toptxn) || (txn->nentries_mem != 0))) txn->txn_flags |= RBTXN_IS_STREAMED; + if (txn_prepared) + { + /* + * If this is a prepared txn, cleanup the tuplecids we stored for + * decoding catalog snapshot access. They are always stored in the + * toplevel transaction. + */ + dlist_foreach_modify(iter, &txn->tuplecids) + { + ReorderBufferChange *change; + + change = dlist_container(ReorderBufferChange, node, iter.cur); + + /* Check we're not mixing changes from different transactions. */ + Assert(change->txn == txn); + Assert(change->action == REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID); + + /* Remove the change from its containing list. */ + dlist_delete(&change->node); + + ReorderBufferReturnChange(rb, change, true); + } + } + /* * Destroy the (relfilenode, ctid) hashtable, so that we don't leak any * memory. We could also keep the hash table and update it with new ctid @@ -1579,6 +1646,13 @@ ReorderBufferTruncateTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) { ReorderBufferRestoreCleanup(rb, txn); txn->txn_flags &= ~RBTXN_IS_SERIALIZED; + + /* + * We set this flag to indicate if the transaction is ever serialized. + * We need this to accurately update the stats as otherwise the same + * transaction can be counted as serialized multiple times. + */ + txn->txn_flags |= RBTXN_IS_SERIALIZED_CLEAR; } /* also reset the number of entries in the transaction */ @@ -1599,8 +1673,6 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn) if (!rbtxn_has_catalog_changes(txn) || dlist_is_empty(&txn->tuplecids)) return; - memset(&hash_ctl, 0, sizeof(hash_ctl)); - hash_ctl.keysize = sizeof(ReorderBufferTupleCidKey); hash_ctl.entrysize = sizeof(ReorderBufferTupleCidEnt); hash_ctl.hcxt = rb->context; @@ -1635,7 +1707,7 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn) ent = (ReorderBufferTupleCidEnt *) hash_search(txn->tuplecid_hash, (void *) &key, - HASH_ENTER | HASH_FIND, + HASH_ENTER, &found); if (!found) { @@ -1737,9 +1809,10 @@ ReorderBufferFreeSnap(ReorderBuffer *rb, Snapshot snap) } /* - * If the transaction was (partially) streamed, we need to commit it in a - * 'streamed' way. That is, we first stream the remaining part of the - * transaction, and then invoke stream_commit message. + * If the transaction was (partially) streamed, we need to prepare or commit + * it in a 'streamed' way. That is, we first stream the remaining part of the + * transaction, and then invoke stream_prepare or stream_commit message as per + * the case. */ static void ReorderBufferStreamCommit(ReorderBuffer *rb, ReorderBufferTXN *txn) @@ -1749,29 +1822,49 @@ ReorderBufferStreamCommit(ReorderBuffer *rb, ReorderBufferTXN *txn) ReorderBufferStreamTXN(rb, txn); - rb->stream_commit(rb, txn, txn->final_lsn); + if (rbtxn_prepared(txn)) + { + /* + * Note, we send stream prepare even if a concurrent abort is + * detected. See DecodePrepare for more information. + */ + rb->stream_prepare(rb, txn, txn->final_lsn); - ReorderBufferCleanupTXN(rb, txn); + /* + * This is a PREPARED transaction, part of a two-phase commit. The + * full cleanup will happen as part of the COMMIT PREPAREDs, so now + * just truncate txn by removing changes and tuple_cids. + */ + ReorderBufferTruncateTXN(rb, txn, true); + /* Reset the CheckXidAlive */ + CheckXidAlive = InvalidTransactionId; + } + else + { + rb->stream_commit(rb, txn, txn->final_lsn); + ReorderBufferCleanupTXN(rb, txn); + } } /* * Set xid to detect concurrent aborts. * - * While streaming an in-progress transaction there is a possibility that the - * (sub)transaction might get aborted concurrently. In such case if the - * (sub)transaction has catalog update then we might decode the tuple using - * wrong catalog version. For example, suppose there is one catalog tuple with - * (xmin: 500, xmax: 0). Now, the transaction 501 updates the catalog tuple - * and after that we will have two tuples (xmin: 500, xmax: 501) and - * (xmin: 501, xmax: 0). Now, if 501 is aborted and some other transaction - * say 502 updates the same catalog tuple then the first tuple will be changed - * to (xmin: 500, xmax: 502). So, the problem is that when we try to decode - * the tuple inserted/updated in 501 after the catalog update, we will see the - * catalog tuple with (xmin: 500, xmax: 502) as visible because it will - * consider that the tuple is deleted by xid 502 which is not visible to our - * snapshot. And when we will try to decode with that catalog tuple, it can - * lead to a wrong result or a crash. So, it is necessary to detect - * concurrent aborts to allow streaming of in-progress transactions. + * While streaming an in-progress transaction or decoding a prepared + * transaction there is a possibility that the (sub)transaction might get + * aborted concurrently. In such case if the (sub)transaction has catalog + * update then we might decode the tuple using wrong catalog version. For + * example, suppose there is one catalog tuple with (xmin: 500, xmax: 0). Now, + * the transaction 501 updates the catalog tuple and after that we will have + * two tuples (xmin: 500, xmax: 501) and (xmin: 501, xmax: 0). Now, if 501 is + * aborted and some other transaction say 502 updates the same catalog tuple + * then the first tuple will be changed to (xmin: 500, xmax: 502). So, the + * problem is that when we try to decode the tuple inserted/updated in 501 + * after the catalog update, we will see the catalog tuple with (xmin: 500, + * xmax: 502) as visible because it will consider that the tuple is deleted by + * xid 502 which is not visible to our snapshot. And when we will try to + * decode with that catalog tuple, it can lead to a wrong result or a crash. + * So, it is necessary to detect concurrent aborts to allow streaming of + * in-progress transactions or decoding of prepared transactions. * * For detecting the concurrent abort we set CheckXidAlive to the current * (sub)transaction's xid for which this change belongs to. And, during @@ -1780,7 +1873,10 @@ ReorderBufferStreamCommit(ReorderBuffer *rb, ReorderBufferTXN *txn) * and discard the already streamed changes on such an error. We might have * already streamed some of the changes for the aborted (sub)transaction, but * that is fine because when we decode the abort we will stream abort message - * to truncate the changes in the subscriber. + * to truncate the changes in the subscriber. Similarly, for prepared + * transactions, we stop decoding if concurrent abort is detected and then + * rollback the changes when rollback prepared is encountered. See + * DecodePrepare. */ static inline void SetupCheckXidLive(TransactionId xid) @@ -1871,6 +1967,8 @@ ReorderBufferSaveTXNSnapshot(ReorderBuffer *rb, ReorderBufferTXN *txn, * Helper function for ReorderBufferProcessTXN to handle the concurrent * abort of the streaming transaction. This resets the TXN such that it * can be used to stream the remaining data of transaction being processed. + * This can happen when the subtransaction is aborted and we still want to + * continue processing the main or other subtransactions data. */ static void ReorderBufferResetTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, @@ -1880,7 +1978,7 @@ ReorderBufferResetTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, ReorderBufferChange *specinsert) { /* Discard the changes that we just streamed */ - ReorderBufferTruncateTXN(rb, txn); + ReorderBufferTruncateTXN(rb, txn, rbtxn_prepared(txn)); /* Free all resources allocated for toast reconstruction */ ReorderBufferToastReset(rb, txn); @@ -1892,15 +1990,19 @@ ReorderBufferResetTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, specinsert = NULL; } - /* Stop the stream. */ - rb->stream_stop(rb, txn, last_lsn); - - /* Remember the command ID and snapshot for the streaming run */ - ReorderBufferSaveTXNSnapshot(rb, txn, snapshot_now, command_id); + /* + * For the streaming case, stop the stream and remember the command ID and + * snapshot for the streaming run. + */ + if (rbtxn_is_streamed(txn)) + { + rb->stream_stop(rb, txn, last_lsn); + ReorderBufferSaveTXNSnapshot(rb, txn, snapshot_now, command_id); + } } /* - * Helper function for ReorderBufferCommit and ReorderBufferStreamTXN. + * Helper function for ReorderBufferReplay and ReorderBufferStreamTXN. * * Send data of a transaction (and its subtransactions) to the * output plugin. We iterate over the top and subtransactions (using a k-way @@ -1953,9 +2055,17 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, else StartTransactionCommand(); - /* We only need to send begin/commit for non-streamed transactions. */ + /* + * We only need to send begin/begin-prepare for non-streamed + * transactions. + */ if (!streaming) - rb->begin(rb, txn); + { + if (rbtxn_prepared(txn)) + rb->begin_prepare(rb, txn); + else + rb->begin(rb, txn); + } ReorderBufferIterTXNInit(rb, txn, &iterstate); while ((change = ReorderBufferIterTXNNext(rb, iterstate)) != NULL) @@ -1986,8 +2096,12 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, prev_lsn = change->lsn; - /* Set the current xid to detect concurrent aborts. */ - if (streaming) + /* + * Set the current xid to detect concurrent aborts. This is + * required for the cases when we decode the changes before the + * COMMIT record is processed. + */ + if (streaming || rbtxn_prepared(change->txn)) { curtxn = change->txn; SetupCheckXidLive(curtxn->xid); @@ -2021,13 +2135,13 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, * Mapped catalog tuple without data, emitted while * catalog table was in the process of being rewritten. We * can fail to look up the relfilenode, because the - * relmapper has no "historic" view, in contrast to normal - * the normal catalog during decoding. Thus repeated - * rewrites can cause a lookup failure. That's OK because - * we do not decode catalog changes anyway. Normally such - * tuples would be skipped over below, but we can't - * identify whether the table should be logically logged - * without mapping the relfilenode to the oid. + * relmapper has no "historic" view, in contrast to the + * normal catalog during decoding. Thus repeated rewrites + * can cause a lookup failure. That's OK because we do not + * decode catalog changes anyway. Normally such tuples + * would be skipped over below, but we can't identify + * whether the table should be logically logged without + * mapping the relfilenode to the oid. */ if (reloid == InvalidOid && change->data.tp.newtuple == NULL && @@ -2101,8 +2215,8 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, change_done: /* - * Either speculative insertion was confirmed, or it was - * unsuccessful and the record isn't needed anymore. + * If speculative insertion was confirmed, the record + * isn't needed anymore. */ if (specinsert != NULL) { @@ -2144,6 +2258,32 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, specinsert = change; break; + case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: + + /* + * Abort for speculative insertion arrived. So cleanup the + * specinsert tuple and toast hash. + * + * Note that we get the spec abort change for each toast + * entry but we need to perform the cleanup only the first + * time we get it for the main table. + */ + if (specinsert != NULL) + { + /* + * We must clean the toast hash before processing a + * completely new tuple to avoid confusion about the + * previous tuple's toast chunks. + */ + Assert(change->data.tp.clear_toast_afterwards); + ReorderBufferToastReset(rb, txn); + + /* We don't need this record anymore. */ + ReorderBufferReturnChange(rb, specinsert, true); + specinsert = NULL; + } + break; + case REORDER_BUFFER_CHANGE_TRUNCATE: { int i; @@ -2183,6 +2323,13 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, ReorderBufferApplyMessage(rb, txn, change, streaming); break; + case REORDER_BUFFER_CHANGE_INVALIDATION: + /* Execute the invalidation messages locally */ + ReorderBufferExecuteInvalidations( + change->data.inval.ninvalidations, + change->data.inval.invalidations); + break; + case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT: /* get rid of the old */ TeardownHistoricSnapshot(false); @@ -2233,13 +2380,6 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, TeardownHistoricSnapshot(false); SetupHistoricSnapshot(snapshot_now, txn->tuplecid_hash); - - /* - * Every time the CommandId is incremented, we could - * see new catalog contents, so execute all - * invalidations. - */ - ReorderBufferExecuteInvalidations(rb, txn); } break; @@ -2250,21 +2390,27 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, } } - /* - * There's a speculative insertion remaining, just clean in up, it - * can't have been successful, otherwise we'd gotten a confirmation - * record. - */ - if (specinsert) - { - ReorderBufferReturnChange(rb, specinsert, true); - specinsert = NULL; - } + /* speculative insertion record must be freed by now */ + Assert(!specinsert); /* clean up the iterator */ ReorderBufferIterTXNFinish(rb, iterstate); iterstate = NULL; + /* + * Update total transaction count and total bytes processed by the + * transaction and its subtransactions. Ensure to not count the + * streamed transaction multiple times. + * + * Note that the statistics computation has to be done after + * ReorderBufferIterTXNFinish as it releases the serialized change + * which we have already accounted in ReorderBufferIterTXNNext. + */ + if (!rbtxn_is_streamed(txn)) + rb->totalTxns++; + + rb->totalBytes += txn->total_size; + /* * Done with current changes, send the last message for this set of * changes depending upon streaming mode. @@ -2278,7 +2424,16 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, } } else - rb->commit(rb, txn, commit_lsn); + { + /* + * Call either PREPARE (for two-phase transactions) or COMMIT (for + * regular ones). + */ + if (rbtxn_prepared(txn)) + rb->prepare(rb, txn, commit_lsn); + else + rb->commit(rb, txn, commit_lsn); + } /* this is just a sanity check against bad output plugin behaviour */ if (GetCurrentTransactionIdIfAny() != InvalidTransactionId) @@ -2306,21 +2461,28 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, AbortCurrentTransaction(); /* make sure there's no cache pollution */ - ReorderBufferExecuteInvalidations(rb, txn); + ReorderBufferExecuteInvalidations(txn->ninvalidations, txn->invalidations); if (using_subtxn) RollbackAndReleaseCurrentSubTransaction(); /* - * If we are streaming the in-progress transaction then discard the - * changes that we just streamed, and mark the transactions as - * streamed (if they contained changes). Otherwise, remove all the - * changes and deallocate the ReorderBufferTXN. + * We are here due to one of the four reasons: 1. Decoding an + * in-progress txn. 2. Decoding a prepared txn. 3. Decoding of a + * prepared txn that was (partially) streamed. 4. Decoding a committed + * txn. + * + * For 1, we allow truncation of txn data by removing the changes + * already streamed but still keeping other things like invalidations, + * snapshot, and tuplecids. For 2 and 3, we indicate + * ReorderBufferTruncateTXN to do more elaborate truncation of txn + * data as the entire transaction has been decoded except for commit. + * For 4, as the entire txn has been decoded, we can fully clean up + * the TXN reorder buffer. */ - if (streaming) + if (streaming || rbtxn_prepared(txn)) { - ReorderBufferTruncateTXN(rb, txn); - + ReorderBufferTruncateTXN(rb, txn, rbtxn_prepared(txn)); /* Reset the CheckXidAlive */ CheckXidAlive = InvalidTransactionId; } @@ -2345,24 +2507,29 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, AbortCurrentTransaction(); /* make sure there's no cache pollution */ - ReorderBufferExecuteInvalidations(rb, txn); + ReorderBufferExecuteInvalidations(txn->ninvalidations, + txn->invalidations); if (using_subtxn) RollbackAndReleaseCurrentSubTransaction(); /* * The error code ERRCODE_TRANSACTION_ROLLBACK indicates a concurrent - * abort of the (sub)transaction we are streaming. We need to do the - * cleanup and return gracefully on this error, see SetupCheckXidLive. + * abort of the (sub)transaction we are streaming or preparing. We + * need to do the cleanup and return gracefully on this error, see + * SetupCheckXidLive. + * + * This error code can be thrown by one of the callbacks we call + * during decoding so we need to ensure that we return gracefully only + * when we are sending the data in streaming mode and the streaming is + * not finished yet or when we are sending the data out on a PREPARE + * during a two-phase commit. */ - if (errdata->sqlerrcode == ERRCODE_TRANSACTION_ROLLBACK) + if (errdata->sqlerrcode == ERRCODE_TRANSACTION_ROLLBACK && + (stream_started || rbtxn_prepared(txn))) { - /* - * This error can only occur when we are sending the data in - * streaming mode and the streaming is not finished yet. - */ - Assert(streaming); - Assert(stream_started); + /* curtxn must be set for streaming or prepared transactions */ + Assert(curtxn); /* Cleanup the temporary error state. */ FlushErrorState(); @@ -2392,26 +2559,19 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn, * ReorderBufferCommitChild(), even if previously assigned to the toplevel * transaction with ReorderBufferAssignChild. * - * This interface is called once a toplevel commit is read for both streamed - * as well as non-streamed transactions. + * This interface is called once a prepare or toplevel commit is read for both + * streamed as well as non-streamed transactions. */ -void -ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, +static void +ReorderBufferReplay(ReorderBufferTXN *txn, + ReorderBuffer *rb, TransactionId xid, XLogRecPtr commit_lsn, XLogRecPtr end_lsn, TimestampTz commit_time, RepOriginId origin_id, XLogRecPtr origin_lsn) { - ReorderBufferTXN *txn; Snapshot snapshot_now; CommandId command_id = FirstCommandId; - txn = ReorderBufferTXNByXid(rb, xid, false, NULL, InvalidXLogRecPtr, - false); - - /* unknown transaction, nothing to replay */ - if (txn == NULL) - return; - txn->final_lsn = commit_lsn; txn->end_lsn = end_lsn; txn->commit_time = commit_time; @@ -2441,7 +2601,13 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, if (txn->base_snapshot == NULL) { Assert(txn->ninvalidations == 0); - ReorderBufferCleanupTXN(rb, txn); + + /* + * Removing this txn before a commit might result in the computation + * of an incorrect restart_lsn. See SnapBuildProcessRunningXacts. + */ + if (!rbtxn_prepared(txn)) + ReorderBufferCleanupTXN(rb, txn); return; } @@ -2452,6 +2618,189 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, command_id, false); } +/* + * Commit a transaction. + * + * See comments for ReorderBufferReplay(). + */ +void +ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn, + TimestampTz commit_time, + RepOriginId origin_id, XLogRecPtr origin_lsn) +{ + ReorderBufferTXN *txn; + + txn = ReorderBufferTXNByXid(rb, xid, false, NULL, InvalidXLogRecPtr, + false); + + /* unknown transaction, nothing to replay */ + if (txn == NULL) + return; + + ReorderBufferReplay(txn, rb, xid, commit_lsn, end_lsn, commit_time, + origin_id, origin_lsn); +} + +/* + * Record the prepare information for a transaction. + */ +bool +ReorderBufferRememberPrepareInfo(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr prepare_lsn, XLogRecPtr end_lsn, + TimestampTz prepare_time, + RepOriginId origin_id, XLogRecPtr origin_lsn) +{ + ReorderBufferTXN *txn; + + txn = ReorderBufferTXNByXid(rb, xid, false, NULL, InvalidXLogRecPtr, false); + + /* unknown transaction, nothing to do */ + if (txn == NULL) + return false; + + /* + * Remember the prepare information to be later used by commit prepared in + * case we skip doing prepare. + */ + txn->final_lsn = prepare_lsn; + txn->end_lsn = end_lsn; + txn->commit_time = prepare_time; + txn->origin_id = origin_id; + txn->origin_lsn = origin_lsn; + + return true; +} + +/* Remember that we have skipped prepare */ +void +ReorderBufferSkipPrepare(ReorderBuffer *rb, TransactionId xid) +{ + ReorderBufferTXN *txn; + + txn = ReorderBufferTXNByXid(rb, xid, false, NULL, InvalidXLogRecPtr, false); + + /* unknown transaction, nothing to do */ + if (txn == NULL) + return; + + txn->txn_flags |= RBTXN_SKIPPED_PREPARE; +} + +/* + * Prepare a two-phase transaction. + * + * See comments for ReorderBufferReplay(). + */ +void +ReorderBufferPrepare(ReorderBuffer *rb, TransactionId xid, + char *gid) +{ + ReorderBufferTXN *txn; + + txn = ReorderBufferTXNByXid(rb, xid, false, NULL, InvalidXLogRecPtr, + false); + + /* unknown transaction, nothing to replay */ + if (txn == NULL) + return; + + txn->txn_flags |= RBTXN_PREPARE; + txn->gid = pstrdup(gid); + + /* The prepare info must have been updated in txn by now. */ + Assert(txn->final_lsn != InvalidXLogRecPtr); + + ReorderBufferReplay(txn, rb, xid, txn->final_lsn, txn->end_lsn, + txn->commit_time, txn->origin_id, txn->origin_lsn); + + /* + * We send the prepare for the concurrently aborted xacts so that later + * when rollback prepared is decoded and sent, the downstream should be + * able to rollback such a xact. See comments atop DecodePrepare. + * + * Note, for the concurrent_abort + streaming case a stream_prepare was + * already sent within the ReorderBufferReplay call above. + */ + if (txn->concurrent_abort && !rbtxn_is_streamed(txn)) + rb->prepare(rb, txn, txn->final_lsn); +} + +/* + * This is used to handle COMMIT/ROLLBACK PREPARED. + */ +void +ReorderBufferFinishPrepared(ReorderBuffer *rb, TransactionId xid, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn, + XLogRecPtr initial_consistent_point, + TimestampTz commit_time, RepOriginId origin_id, + XLogRecPtr origin_lsn, char *gid, bool is_commit) +{ + ReorderBufferTXN *txn; + XLogRecPtr prepare_end_lsn; + TimestampTz prepare_time; + + txn = ReorderBufferTXNByXid(rb, xid, false, NULL, commit_lsn, false); + + /* unknown transaction, nothing to do */ + if (txn == NULL) + return; + + /* + * By this time the txn has the prepare record information, remember it to + * be later used for rollback. + */ + prepare_end_lsn = txn->end_lsn; + prepare_time = txn->commit_time; + + /* add the gid in the txn */ + txn->gid = pstrdup(gid); + + /* + * It is possible that this transaction is not decoded at prepare time + * either because by that time we didn't have a consistent snapshot or it + * was decoded earlier but we have restarted. We only need to send the + * prepare if it was not decoded earlier. We don't need to decode the xact + * for aborts if it is not done already. + */ + if ((txn->final_lsn < initial_consistent_point) && is_commit) + { + txn->txn_flags |= RBTXN_PREPARE; + + /* + * The prepare info must have been updated in txn even if we skip + * prepare. + */ + Assert(txn->final_lsn != InvalidXLogRecPtr); + + /* + * By this time the txn has the prepare record information and it is + * important to use that so that downstream gets the accurate + * information. If instead, we have passed commit information here + * then downstream can behave as it has already replayed commit + * prepared after the restart. + */ + ReorderBufferReplay(txn, rb, xid, txn->final_lsn, txn->end_lsn, + txn->commit_time, txn->origin_id, txn->origin_lsn); + } + + txn->final_lsn = commit_lsn; + txn->end_lsn = end_lsn; + txn->commit_time = commit_time; + txn->origin_id = origin_id; + txn->origin_lsn = origin_lsn; + + if (is_commit) + rb->commit_prepared(rb, txn, commit_lsn); + else + rb->rollback_prepared(rb, txn, prepare_end_lsn, prepare_time); + + /* cleanup: make sure there's no cache pollution */ + ReorderBufferExecuteInvalidations(txn->ninvalidations, + txn->invalidations); + ReorderBufferCleanupTXN(rb, txn); +} + /* * Abort a transaction that possibly has previous changes. Needs to be first * called for subtransactions and then for the toplevel xid. @@ -2583,6 +2932,39 @@ ReorderBufferForget(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn) ReorderBufferCleanupTXN(rb, txn); } +/* + * Invalidate cache for those transactions that need to be skipped just in case + * catalogs were manipulated as part of the transaction. + * + * Note that this is a special-purpose function for prepared transactions where + * we don't want to clean up the TXN even when we decide to skip it. See + * DecodePrepare. + */ +void +ReorderBufferInvalidate(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn) +{ + ReorderBufferTXN *txn; + + txn = ReorderBufferTXNByXid(rb, xid, false, NULL, InvalidXLogRecPtr, + false); + + /* unknown, nothing to do */ + if (txn == NULL) + return; + + /* + * Process cache invalidation messages if there are any. Even if we're not + * interested in the transaction's contents, it could have manipulated the + * catalog and we need to update the caches according to that. + */ + if (txn->base_snapshot != NULL && txn->ninvalidations > 0) + ReorderBufferImmediateInvalidation(rb, txn->ninvalidations, + txn->invalidations); + else + Assert(txn->ninvalidations == 0); +} + + /* * Execute invalidations happening outside the context of a decoded * transaction. That currently happens either for xid-less commits @@ -2719,7 +3101,7 @@ ReorderBufferChangeMemoryUpdate(ReorderBuffer *rb, { Size sz; ReorderBufferTXN *txn; - ReorderBufferTXN *toptxn = NULL; + ReorderBufferTXN *toptxn; Assert(change->txn); @@ -2733,14 +3115,14 @@ ReorderBufferChangeMemoryUpdate(ReorderBuffer *rb, txn = change->txn; - /* If streaming supported, update the total size in top level as well. */ - if (ReorderBufferCanStream(rb)) - { - if (txn->toptxn != NULL) - toptxn = txn->toptxn; - else - toptxn = txn; - } + /* + * Update the total size in top level as well. This is later used to + * compute the decoding stats. + */ + if (txn->toptxn != NULL) + toptxn = txn->toptxn; + else + toptxn = txn; sz = ReorderBufferChangeSize(change); @@ -2750,8 +3132,7 @@ ReorderBufferChangeMemoryUpdate(ReorderBuffer *rb, rb->size += sz; /* Update the total size in the top transaction. */ - if (toptxn) - toptxn->total_size += sz; + toptxn->total_size += sz; } else { @@ -2760,8 +3141,7 @@ ReorderBufferChangeMemoryUpdate(ReorderBuffer *rb, rb->size -= sz; /* Update the total size in the top transaction. */ - if (toptxn) - toptxn->total_size -= sz; + toptxn->total_size -= sz; } Assert(txn->size <= rb->size); @@ -2802,10 +3182,13 @@ ReorderBufferAddNewTupleCids(ReorderBuffer *rb, TransactionId xid, * Setup the invalidation of the toplevel transaction. * * This needs to be called for each XLOG_XACT_INVALIDATIONS message and - * accumulates all the invalidation messages in the toplevel transaction. - * This is required because in some cases where we skip processing the - * transaction (see ReorderBufferForget), we need to execute all the - * invalidations together. + * accumulates all the invalidation messages in the toplevel transaction as + * well as in the form of change in reorder buffer. We require to record it in + * form of the change so that we can execute only the required invalidations + * instead of executing all the invalidations on each CommandId increment. We + * also need to accumulate these in the toplevel transaction because in some + * cases we skip processing the transaction (see ReorderBufferForget), we need + * to execute all the invalidations together. */ void ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid, @@ -2813,12 +3196,16 @@ ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid, SharedInvalidationMessage *msgs) { ReorderBufferTXN *txn; + MemoryContext oldcontext; + ReorderBufferChange *change; txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true); + oldcontext = MemoryContextSwitchTo(rb->context); + /* - * We collect all the invalidations under the top transaction so that we - * can execute them all together. + * Collect all the invalidations under the top transaction so that we can + * execute them all together. See comment atop this function */ if (txn->toptxn) txn = txn->toptxn; @@ -2830,8 +3217,7 @@ ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid, { txn->ninvalidations = nmsgs; txn->invalidations = (SharedInvalidationMessage *) - MemoryContextAlloc(rb->context, - sizeof(SharedInvalidationMessage) * nmsgs); + palloc(sizeof(SharedInvalidationMessage) * nmsgs); memcpy(txn->invalidations, msgs, sizeof(SharedInvalidationMessage) * nmsgs); } @@ -2845,6 +3231,18 @@ ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid, nmsgs * sizeof(SharedInvalidationMessage)); txn->ninvalidations += nmsgs; } + + change = ReorderBufferGetChange(rb); + change->action = REORDER_BUFFER_CHANGE_INVALIDATION; + change->data.inval.ninvalidations = nmsgs; + change->data.inval.invalidations = (SharedInvalidationMessage *) + palloc(sizeof(SharedInvalidationMessage) * nmsgs); + memcpy(change->data.inval.invalidations, msgs, + sizeof(SharedInvalidationMessage) * nmsgs); + + ReorderBufferQueueChange(rb, xid, lsn, change, false); + + MemoryContextSwitchTo(oldcontext); } /* @@ -2852,12 +3250,12 @@ ReorderBufferAddInvalidations(ReorderBuffer *rb, TransactionId xid, * in the changestream but we don't know which those are. */ static void -ReorderBufferExecuteInvalidations(ReorderBuffer *rb, ReorderBufferTXN *txn) +ReorderBufferExecuteInvalidations(uint32 nmsgs, SharedInvalidationMessage *msgs) { int i; - for (i = 0; i < txn->ninvalidations; i++) - LocalExecuteInvalidationMessage(&txn->invalidations[i]); + for (i = 0; i < nmsgs; i++) + LocalExecuteInvalidationMessage(&msgs[i]); } /* @@ -2990,19 +3388,22 @@ ReorderBufferLargestTXN(ReorderBuffer *rb) * This can be seen as an optimized version of ReorderBufferLargestTXN, which * should give us the same transaction (because we don't update memory account * for subtransaction with streaming, so it's always 0). But we can simply - * iterate over the limited number of toplevel transactions. + * iterate over the limited number of toplevel transactions that have a base + * snapshot. There is no use of selecting a transaction that doesn't have base + * snapshot because we don't decode such transactions. * * Note that, we skip transactions that contains incomplete changes. There - * is a scope of optimization here such that we can select the largest transaction - * which has complete changes. But that will make the code and design quite complex - * and that might not be worth the benefit. If we plan to stream the transactions - * that contains incomplete changes then we need to find a way to partially - * stream/truncate the transaction changes in-memory and build a mechanism to - * partially truncate the spilled files. Additionally, whenever we partially - * stream the transaction we need to maintain the last streamed lsn and next time - * we need to restore from that segment and the offset in WAL. As we stream the - * changes from the top transaction and restore them subtransaction wise, we need - * to even remember the subxact from where we streamed the last change. + * is a scope of optimization here such that we can select the largest + * transaction which has incomplete changes. But that will make the code and + * design quite complex and that might not be worth the benefit. If we plan to + * stream the transactions that contains incomplete changes then we need to + * find a way to partially stream/truncate the transaction changes in-memory + * and build a mechanism to partially truncate the spilled files. + * Additionally, whenever we partially stream the transaction we need to + * maintain the last streamed lsn and next time we need to restore from that + * segment and the offset in WAL. As we stream the changes from the top + * transaction and restore them subtransaction wise, we need to even remember + * the subxact from where we streamed the last change. */ static ReorderBufferTXN * ReorderBufferLargestTopTXN(ReorderBuffer *rb) @@ -3011,15 +3412,20 @@ ReorderBufferLargestTopTXN(ReorderBuffer *rb) Size largest_size = 0; ReorderBufferTXN *largest = NULL; - /* Find the largest top-level transaction. */ - dlist_foreach(iter, &rb->toplevel_by_lsn) + /* Find the largest top-level transaction having a base snapshot. */ + dlist_foreach(iter, &rb->txns_by_base_snapshot_lsn) { ReorderBufferTXN *txn; - txn = dlist_container(ReorderBufferTXN, node, iter.cur); + txn = dlist_container(ReorderBufferTXN, base_snapshot_node, iter.cur); + + /* must not be a subtxn */ + Assert(!rbtxn_is_known_subxact(txn)); + /* base_snapshot must be set */ + Assert(txn->base_snapshot != NULL); - if ((largest != NULL || txn->total_size > largest_size) && - (txn->total_size > 0) && !(rbtxn_has_incomplete_tuple(txn))) + if ((largest == NULL || txn->total_size > largest_size) && + (txn->total_size > 0) && !(rbtxn_has_partial_change(txn))) { largest = txn; largest_size = txn->total_size; @@ -3112,6 +3518,7 @@ ReorderBufferSerializeTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) int fd = -1; XLogSegNo curOpenSegNo = 0; Size spilled = 0; + Size size = txn->size; elog(DEBUG2, "spill %u changes in XID %u to disk", (uint32) txn->nentries_mem, txn->xid); @@ -3170,6 +3577,19 @@ ReorderBufferSerializeTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) spilled++; } + /* update the statistics iff we have spilled anything */ + if (spilled) + { + rb->spillCount += 1; + rb->spillBytes += size; + + /* don't consider already serialized transactions */ + rb->spillTxns += (rbtxn_is_serialized(txn) || rbtxn_is_serialized_clear(txn)) ? 0 : 1; + + /* update the decoding stats */ + UpdateDecodingStats((LogicalDecodingContext *) rb->private_data); + } + Assert(spilled == txn->nentries_mem); Assert(dlist_is_empty(&txn->changes)); txn->nentries_mem = 0; @@ -3279,6 +3699,24 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn, change->data.msg.message_size); data += change->data.msg.message_size; + break; + } + case REORDER_BUFFER_CHANGE_INVALIDATION: + { + char *data; + Size inval_size = sizeof(SharedInvalidationMessage) * + change->data.inval.ninvalidations; + + sz += inval_size; + + ReorderBufferSerializeReserve(rb, sz); + data = ((char *) rb->outbuf) + sizeof(ReorderBufferDiskChange); + + /* might have been reallocated above */ + ondisk = (ReorderBufferDiskChange *) rb->outbuf; + memcpy(data, change->data.inval.invalidations, inval_size); + data += inval_size; + break; } case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT: @@ -3338,6 +3776,7 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn, break; } case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: + case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: /* ReorderBufferChange contains everything important */ @@ -3393,6 +3832,10 @@ ReorderBufferCanStartStreaming(ReorderBuffer *rb) LogicalDecodingContext *ctx = rb->private_data; SnapBuild *builder = ctx->snapshot_builder; + /* We can't start streaming unless a consistent state is reached. */ + if (SnapBuildCurrentState(builder) < SNAPBUILD_CONSISTENT) + return false; + /* * We can't start streaming immediately even if the streaming is enabled * because we previously decoded this transaction and now just are @@ -3400,11 +3843,7 @@ ReorderBufferCanStartStreaming(ReorderBuffer *rb) */ if (ReorderBufferCanStream(rb) && !SnapBuildXactNeedsSkip(builder, ctx->reader->EndRecPtr)) - { - /* We must have a consistent snapshot by this time */ - Assert(SnapBuildCurrentState(builder) == SNAPBUILD_CONSISTENT); return true; - } return false; } @@ -3418,6 +3857,8 @@ ReorderBufferStreamTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) { Snapshot snapshot_now; CommandId command_id; + Size stream_bytes; + bool txn_is_streamed; /* We can never reach here for a subtransaction. */ Assert(txn->toptxn == NULL); @@ -3498,10 +3939,28 @@ ReorderBufferStreamTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) txn->snapshot_now = NULL; } + /* + * Remember this information to be used later to update stats. We can't + * update the stats here as an error while processing the changes would + * lead to the accumulation of stats even though we haven't streamed all + * the changes. + */ + txn_is_streamed = rbtxn_is_streamed(txn); + stream_bytes = txn->total_size; + /* Process and send the changes to output plugin. */ ReorderBufferProcessTXN(rb, txn, InvalidXLogRecPtr, snapshot_now, command_id, true); + rb->streamCount += 1; + rb->streamBytes += stream_bytes; + + /* Don't consider already streamed transaction. */ + rb->streamTxns += (txn_is_streamed) ? 0 : 1; + + /* update the decoding stats */ + UpdateDecodingStats((LogicalDecodingContext *) rb->private_data); + Assert(dlist_is_empty(&txn->changes)); Assert(txn->nentries == 0); Assert(txn->nentries_mem == 0); @@ -3556,6 +4015,12 @@ ReorderBufferChangeSize(ReorderBufferChange *change) break; } + case REORDER_BUFFER_CHANGE_INVALIDATION: + { + sz += sizeof(SharedInvalidationMessage) * + change->data.inval.ninvalidations; + break; + } case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT: { Snapshot snap; @@ -3575,6 +4040,7 @@ ReorderBufferChangeSize(ReorderBufferChange *change) break; } case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: + case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: /* ReorderBufferChange contains everything important */ @@ -3822,6 +4288,19 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, change->data.msg.message_size); data += change->data.msg.message_size; + break; + } + case REORDER_BUFFER_CHANGE_INVALIDATION: + { + Size inval_size = sizeof(SharedInvalidationMessage) * + change->data.inval.ninvalidations; + + change->data.inval.invalidations = + MemoryContextAlloc(rb->context, inval_size); + + /* read the message */ + memcpy(change->data.inval.invalidations, data, inval_size); + break; } case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT: @@ -3860,6 +4339,7 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, break; } case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: + case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_ABORT: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: break; @@ -3961,8 +4441,7 @@ ReorderBufferSerializedPath(char *path, ReplicationSlot *slot, TransactionId xid snprintf(path, MAXPGPATH, "pg_replslot/%s/xid-%u-lsn-%X-%X.spill", NameStr(MyReplicationSlot->data.name), - xid, - (uint32) (recptr >> 32), (uint32) recptr); + xid, LSN_FORMAT_ARGS(recptr)); } /* @@ -4010,7 +4489,6 @@ ReorderBufferToastInitHash(ReorderBuffer *rb, ReorderBufferTXN *txn) Assert(txn->toast_hash == NULL); - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(ReorderBufferToastEnt); hash_ctl.hcxt = rb->context; @@ -4238,7 +4716,7 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn, VARSIZE(chunk) - VARHDRSZ); data_done += VARSIZE(chunk) - VARHDRSZ; } - Assert(data_done == toast_pointer.va_extsize); + Assert(data_done == VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer)); /* make sure its marked as compressed or not */ if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) @@ -4333,19 +4811,19 @@ ReorderBufferToastReset(ReorderBuffer *rb, ReorderBufferTXN *txn) * always rely on stored cmin/cmax values because of two scenarios: * * * A tuple got changed multiple times during a single transaction and thus - * has got a combocid. Combocid's are only valid for the duration of a + * has got a combo CID. Combo CIDs are only valid for the duration of a * single transaction. - * * A tuple with a cmin but no cmax (and thus no combocid) got + * * A tuple with a cmin but no cmax (and thus no combo CID) got * deleted/updated in another transaction than the one which created it - * which we are looking at right now. As only one of cmin, cmax or combocid + * which we are looking at right now. As only one of cmin, cmax or combo CID * is actually stored in the heap we don't have access to the value we * need anymore. * * To resolve those problems we have a per-transaction hash of (cmin, * cmax) tuples keyed by (relfilenode, ctid) which contains the actual - * (cmin, cmax) values. That also takes care of combocids by simply + * (cmin, cmax) values. That also takes care of combo CIDs by simply * not caring about them at all. As we have the real cmin/cmax values - * combocids aren't interesting. + * combo CIDs aren't interesting. * * As we only care about catalog tuples here the overhead of this * hashtable should be acceptable. @@ -4592,7 +5070,7 @@ UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, Snapshot snapshot) /* * Lookup cmin/cmax of a tuple, during logical decoding where we can't rely on - * combocids. + * combo CIDs. */ bool ResolveCminCmaxDuringDecoding(HTAB *tuplecid_data, diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index 172247060477..c0e986579725 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -42,7 +42,7 @@ * catalog in a transaction. During normal operation this is achieved by using * CommandIds/cmin/cmax. The problem with that however is that for space * efficiency reasons only one value of that is stored - * (cf. combocid.c). Since ComboCids are only available in memory we log + * (cf. combocid.c). Since combo CIDs are only available in memory we log * additional information which allows us to get the original (cmin, cmax) * pair during visibility checks. Check the reorderbuffer.c's comment above * ResolveCminCmaxDuringDecoding() for details. @@ -107,7 +107,7 @@ * is a convenient point to initialize replication from, which is why we * export a snapshot at that point, which *can* be used to read normal data. * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/snapbuild.c @@ -164,6 +164,17 @@ struct SnapBuild */ XLogRecPtr start_decoding_at; + /* + * LSN at which we found a consistent point at the time of slot creation. + * This is also the point where we have exported a snapshot for the + * initial copy. + * + * The prepared transactions that are not covered by initial snapshot + * needs to be sent later along with commit prepared and they must be + * before this point. + */ + XLogRecPtr initial_consistent_point; + /* * Don't start decoding WAL until the "xl_running_xacts" information * indicates there are no running xids with an xid smaller than this. @@ -189,24 +200,11 @@ struct SnapBuild ReorderBuffer *reorder; /* - * Outdated: This struct isn't used for its original purpose anymore, but - * can't be removed / changed in a minor version, because it's stored - * on-disk. + * TransactionId at which the next phase of initial snapshot building will + * happen. InvalidTransactionId if not known (i.e. SNAPBUILD_START), or + * when no next phase necessary (SNAPBUILD_CONSISTENT). */ - struct - { - /* - * NB: This field is misused, until a major version can break on-disk - * compatibility. See SnapBuildNextPhaseAt() / - * SnapBuildStartNextPhaseAt(). - */ - TransactionId was_xmin; - TransactionId was_xmax; - - size_t was_xcnt; /* number of used xip entries */ - size_t was_xcnt_space; /* allocated size of xip */ - TransactionId *was_xip; /* running xacts array, xidComparator-sorted */ - } was_running; + TransactionId next_phase_at; /* * Array of transactions which could have catalog changes that committed @@ -272,34 +270,6 @@ static void SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutof static void SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn); static bool SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn); -/* - * Return TransactionId after which the next phase of initial snapshot - * building will happen. - */ -static inline TransactionId -SnapBuildNextPhaseAt(SnapBuild *builder) -{ - /* - * For backward compatibility reasons this has to be stored in the wrongly - * named field. Will be fixed in next major version. - */ - return builder->was_running.was_xmax; -} - -/* - * Set TransactionId after which the next phase of initial snapshot building - * will happen. - */ -static inline void -SnapBuildStartNextPhaseAt(SnapBuild *builder, TransactionId at) -{ - /* - * For backward compatibility reasons this has to be stored in the wrongly - * named field. Will be fixed in next major version. - */ - builder->was_running.was_xmax = at; -} - /* * Allocate a new snapshot builder. * @@ -310,7 +280,8 @@ SnapBuild * AllocateSnapshotBuilder(ReorderBuffer *reorder, TransactionId xmin_horizon, XLogRecPtr start_lsn, - bool need_full_snapshot) + bool need_full_snapshot, + XLogRecPtr initial_consistent_point) { MemoryContext context; MemoryContext oldcontext; @@ -338,6 +309,7 @@ AllocateSnapshotBuilder(ReorderBuffer *reorder, builder->initial_xmin_horizon = xmin_horizon; builder->start_decoding_at = start_lsn; builder->building_full_snapshot = need_full_snapshot; + builder->initial_consistent_point = initial_consistent_point; MemoryContextSwitchTo(oldcontext); @@ -397,6 +369,15 @@ SnapBuildCurrentState(SnapBuild *builder) return builder->state; } +/* + * Return the LSN at which the snapshot was exported + */ +XLogRecPtr +SnapBuildInitialConsistentPoint(SnapBuild *builder) +{ + return builder->initial_consistent_point; +} + /* * Should the contents of transaction ending at 'ptr' be decoded? */ @@ -728,7 +709,7 @@ SnapBuildProcessChange(SnapBuild *builder, TransactionId xid, XLogRecPtr lsn) * we got into the SNAPBUILD_FULL_SNAPSHOT state. */ if (builder->state < SNAPBUILD_CONSISTENT && - TransactionIdPrecedes(xid, SnapBuildNextPhaseAt(builder))) + TransactionIdPrecedes(xid, builder->next_phase_at)) return false; /* @@ -758,7 +739,7 @@ SnapBuildProcessChange(SnapBuild *builder, TransactionId xid, XLogRecPtr lsn) } /* - * Do CommandId/ComboCid handling after reading an xl_heap_new_cid record. + * Do CommandId/combo CID handling after reading an xl_heap_new_cid record. * This implies that a transaction has done some form of write to system * catalogs. */ @@ -834,8 +815,15 @@ SnapBuildDistributeNewCatalogSnapshot(SnapBuild *builder, XLogRecPtr lsn) if (!ReorderBufferXidHasBaseSnapshot(builder->reorder, txn->xid)) continue; + /* + * We don't need to add snapshot to prepared transactions as they + * should not see the new catalog contents. + */ + if (rbtxn_prepared(txn) || rbtxn_skip_prepared(txn)) + continue; + elog(DEBUG2, "adding a new snapshot to %u at %X/%X", - txn->xid, (uint32) (lsn >> 32), (uint32) lsn); + txn->xid, LSN_FORMAT_ARGS(lsn)); /* * increase the snapshot's refcount for the transaction we are handing @@ -938,7 +926,7 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid, */ if (builder->state == SNAPBUILD_START || (builder->state == SNAPBUILD_BUILDING_SNAPSHOT && - TransactionIdPrecedes(xid, SnapBuildNextPhaseAt(builder)))) + TransactionIdPrecedes(xid, builder->next_phase_at))) { /* ensure that only commits after this are getting replayed */ if (builder->start_decoding_at <= lsn) @@ -1225,7 +1213,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn { ereport(DEBUG1, (errmsg_internal("skipping snapshot at %X/%X while building logical decoding snapshot, xmin horizon too low", - (uint32) (lsn >> 32), (uint32) lsn), + LSN_FORMAT_ARGS(lsn)), errdetail_internal("initial xmin horizon of %u vs the snapshot's %u", builder->initial_xmin_horizon, running->oldestRunningXid))); @@ -1260,11 +1248,11 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn Assert(TransactionIdIsNormal(builder->xmax)); builder->state = SNAPBUILD_CONSISTENT; - SnapBuildStartNextPhaseAt(builder, InvalidTransactionId); + builder->next_phase_at = InvalidTransactionId; ereport(LOG, (errmsg("logical decoding found consistent point at %X/%X", - (uint32) (lsn >> 32), (uint32) lsn), + LSN_FORMAT_ARGS(lsn)), errdetail("There are no running transactions."))); return false; @@ -1291,7 +1279,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn else if (builder->state == SNAPBUILD_START) { builder->state = SNAPBUILD_BUILDING_SNAPSHOT; - SnapBuildStartNextPhaseAt(builder, running->nextXid); + builder->next_phase_at = running->nextXid; /* * Start with an xmin/xmax that's correct for future, when all the @@ -1307,7 +1295,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn ereport(LOG, (errmsg("logical decoding found initial starting point at %X/%X", - (uint32) (lsn >> 32), (uint32) lsn), + LSN_FORMAT_ARGS(lsn)), errdetail("Waiting for transactions (approximately %d) older than %u to end.", running->xcnt, running->nextXid))); @@ -1323,15 +1311,15 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn * be decoded. Switch to FULL_SNAPSHOT. */ else if (builder->state == SNAPBUILD_BUILDING_SNAPSHOT && - TransactionIdPrecedesOrEquals(SnapBuildNextPhaseAt(builder), + TransactionIdPrecedesOrEquals(builder->next_phase_at, running->oldestRunningXid)) { builder->state = SNAPBUILD_FULL_SNAPSHOT; - SnapBuildStartNextPhaseAt(builder, running->nextXid); + builder->next_phase_at = running->nextXid; ereport(LOG, (errmsg("logical decoding found initial consistent point at %X/%X", - (uint32) (lsn >> 32), (uint32) lsn), + LSN_FORMAT_ARGS(lsn)), errdetail("Waiting for transactions (approximately %d) older than %u to end.", running->xcnt, running->nextXid))); @@ -1348,15 +1336,15 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn * collected. Switch to CONSISTENT. */ else if (builder->state == SNAPBUILD_FULL_SNAPSHOT && - TransactionIdPrecedesOrEquals(SnapBuildNextPhaseAt(builder), + TransactionIdPrecedesOrEquals(builder->next_phase_at, running->oldestRunningXid)) { builder->state = SNAPBUILD_CONSISTENT; - SnapBuildStartNextPhaseAt(builder, InvalidTransactionId); + builder->next_phase_at = InvalidTransactionId; ereport(LOG, (errmsg("logical decoding found consistent point at %X/%X", - (uint32) (lsn >> 32), (uint32) lsn), + LSN_FORMAT_ARGS(lsn)), errdetail("There are no old transactions anymore."))); } @@ -1377,7 +1365,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn * a) allow isolationtester to notice that we're currently waiting for * something. * b) log a new xl_running_xacts record where it'd be helpful, without having - * to write for bgwriter or checkpointer. + * to wait for bgwriter or checkpointer. * --- */ static void @@ -1406,8 +1394,8 @@ SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutoff) /* * All transactions we needed to finish finished - try to ensure there is * another xl_running_xacts record in a timely manner, without having to - * write for bgwriter or checkpointer to log one. During recovery we - * can't enforce that, so we'll have to wait. + * wait for bgwriter or checkpointer to log one. During recovery we can't + * enforce that, so we'll have to wait. */ if (!RecoveryInProgress()) { @@ -1455,7 +1443,7 @@ typedef struct SnapBuildOnDisk offsetof(SnapBuildOnDisk, version) #define SNAPBUILD_MAGIC 0x51A1E001 -#define SNAPBUILD_VERSION 2 +#define SNAPBUILD_VERSION 4 /* * Store/Load a snapshot from disk, depending on the snapshot builder's state. @@ -1480,7 +1468,7 @@ static void SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) { Size needed_length; - SnapBuildOnDisk *ondisk; + SnapBuildOnDisk *ondisk = NULL; char *ondisk_c; int fd; char tmppath[MAXPGPATH]; @@ -1500,6 +1488,9 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) if (builder->state < SNAPBUILD_CONSISTENT) return; + /* consistent snapshots have no next phase */ + Assert(builder->next_phase_at == InvalidTransactionId); + /* * We identify snapshots by the LSN they are valid for. We don't need to * include timelines in the name as each LSN maps to exactly one timeline @@ -1507,7 +1498,7 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) * no hope continuing to decode anyway. */ sprintf(path, "pg_logical/snapshots/%X-%X.snap", - (uint32) (lsn >> 32), (uint32) lsn); + LSN_FORMAT_ARGS(lsn)); /* * first check whether some other backend already has written the snapshot @@ -1549,8 +1540,8 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) elog(DEBUG1, "serializing snapshot to %s", path); /* to make sure only we will write to this tempfile, include pid */ - sprintf(tmppath, "pg_logical/snapshots/%X-%X.snap.%u.tmp", - (uint32) (lsn >> 32), (uint32) lsn, MyProcPid); + sprintf(tmppath, "pg_logical/snapshots/%X-%X.snap.%d.tmp", + LSN_FORMAT_ARGS(lsn), MyProcPid); /* * Unlink temporary file if it already exists, needs to have been before a @@ -1588,9 +1579,6 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) &ondisk->builder, sizeof(SnapBuild)); - /* there shouldn't be any running xacts */ - Assert(builder->was_running.was_xcnt == 0); - /* copy committed xacts */ sz = sizeof(TransactionId) * builder->committed.xcnt; memcpy(ondisk_c, builder->committed.xip, sz); @@ -1679,6 +1667,9 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) out: ReorderBufferSetRestartPoint(builder->reorder, builder->last_serialized_snapshot); + /* be tidy */ + if (ondisk) + pfree(ondisk); } /* @@ -1700,7 +1691,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) return false; sprintf(path, "pg_logical/snapshots/%X-%X.snap", - (uint32) (lsn >> 32), (uint32) lsn); + LSN_FORMAT_ARGS(lsn)); fd = OpenTransientFile(path, O_RDONLY | PG_BINARY); @@ -1790,34 +1781,6 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) } COMP_CRC32C(checksum, &ondisk.builder, sizeof(SnapBuild)); - /* restore running xacts (dead, but kept for backward compat) */ - sz = sizeof(TransactionId) * ondisk.builder.was_running.was_xcnt_space; - ondisk.builder.was_running.was_xip = - MemoryContextAllocZero(builder->context, sz); - pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_READ); - readBytes = read(fd, ondisk.builder.was_running.was_xip, sz); - pgstat_report_wait_end(); - if (readBytes != sz) - { - int save_errno = errno; - - CloseTransientFile(fd); - - if (readBytes < 0) - { - errno = save_errno; - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\": %m", path))); - } - else - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("could not read file \"%s\": read %d of %zu", - path, readBytes, sz))); - } - COMP_CRC32C(checksum, ondisk.builder.was_running.was_xip, sz); - /* restore committed xacts information */ sz = sizeof(TransactionId) * ondisk.builder.committed.xcnt; ondisk.builder.committed.xip = MemoryContextAllocZero(builder->context, sz); @@ -1879,6 +1842,8 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) if (TransactionIdPrecedes(ondisk.builder.xmin, builder->initial_xmin_horizon)) goto snapshot_not_interesting; + /* consistent snapshots have no next phase */ + Assert(ondisk.builder.next_phase_at == InvalidTransactionId); /* ok, we think the snapshot is sensible, copy over everything important */ builder->xmin = ondisk.builder.xmin; @@ -1910,7 +1875,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) ereport(LOG, (errmsg("logical decoding found consistent point at %X/%X", - (uint32) (lsn >> 32), (uint32) lsn), + LSN_FORMAT_ARGS(lsn)), errdetail("Logical decoding will begin using saved snapshot."))); return true; diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c index 374ed42ae3d1..2424db636103 100644 --- a/src/backend/replication/logical/tablesync.c +++ b/src/backend/replication/logical/tablesync.c @@ -1,8 +1,8 @@ /*------------------------------------------------------------------------- * tablesync.c - * PostgreSQL logical replication + * PostgreSQL logical replication: initial table data synchronization * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/tablesync.c @@ -26,35 +26,42 @@ * - It allows us to synchronize any tables added after the initial * synchronization has finished. * - * The stream position synchronization works in multiple steps. - * - Sync finishes copy and sets worker state as SYNCWAIT and waits for - * state to change in a loop. - * - Apply periodically checks tables that are synchronizing for SYNCWAIT. - * When the desired state appears, it will set the worker state to - * CATCHUP and starts loop-waiting until either the table state is set - * to SYNCDONE or the sync worker exits. + * The stream position synchronization works in multiple steps: + * - Apply worker requests a tablesync worker to start, setting the new + * table state to INIT. + * - Tablesync worker starts; changes table state from INIT to DATASYNC while + * copying. + * - Tablesync worker does initial table copy; there is a FINISHEDCOPY (sync + * worker specific) state to indicate when the copy phase has completed, so + * if the worker crashes with this (non-memory) state then the copy will not + * be re-attempted. + * - Tablesync worker then sets table state to SYNCWAIT; waits for state change. + * - Apply worker periodically checks for tables in SYNCWAIT state. When + * any appear, it sets the table state to CATCHUP and starts loop-waiting + * until either the table state is set to SYNCDONE or the sync worker + * exits. * - After the sync worker has seen the state change to CATCHUP, it will * read the stream and apply changes (acting like an apply worker) until * it catches up to the specified stream position. Then it sets the * state to SYNCDONE. There might be zero changes applied between * CATCHUP and SYNCDONE, because the sync worker might be ahead of the * apply worker. - * - Once the state was set to SYNCDONE, the apply will continue tracking + * - Once the state is set to SYNCDONE, the apply will continue tracking * the table until it reaches the SYNCDONE stream position, at which * point it sets state to READY and stops tracking. Again, there might * be zero changes in between. * - * So the state progression is always: INIT -> DATASYNC -> SYNCWAIT -> CATCHUP -> - * SYNCDONE -> READY. + * So the state progression is always: INIT -> DATASYNC -> FINISHEDCOPY + * -> SYNCWAIT -> CATCHUP -> SYNCDONE -> READY. * * The catalog pg_subscription_rel is used to keep information about - * subscribed tables and their state. Some transient state during data - * synchronization is kept in shared memory. The states SYNCWAIT and - * CATCHUP only appear in memory. + * subscribed tables and their state. The catalog holds all states + * except SYNCWAIT and CATCHUP which are only in shared memory. * * Example flows look like this: * - Apply is in front: * sync:8 + * -> set in catalog FINISHEDCOPY * -> set in memory SYNCWAIT * apply:10 * -> set in memory CATCHUP @@ -67,8 +74,10 @@ * -> continue rep * apply:11 * -> set in catalog READY - * - Sync in front: + * + * - Sync is in front: * sync:10 + * -> set in catalog FINISHEDCOPY * -> set in memory SYNCWAIT * apply:8 * -> set in memory CATCHUP @@ -97,7 +106,10 @@ #include "replication/logicalrelation.h" #include "replication/walreceiver.h" #include "replication/worker_internal.h" +#include "replication/slot.h" +#include "replication/origin.h" #include "storage/ipc.h" +#include "storage/lmgr.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -142,13 +154,14 @@ finish_sync_worker(void) } /* - * Wait until the relation synchronization state is set in the catalog to the - * expected one. + * Wait until the relation sync state is set in the catalog to the expected + * one; return true when it happens. * - * Used when transitioning from CATCHUP state to SYNCDONE. + * Returns false if the table sync worker or the table itself have + * disappeared, or the table state has been reset. * - * Returns false if the synchronization worker has disappeared or the table state - * has been reset. + * Currently, this is used in the apply worker when transitioning from + * CATCHUP state to SYNCDONE. */ static bool wait_for_relation_state_change(Oid relid, char expected_state) @@ -162,28 +175,23 @@ wait_for_relation_state_change(Oid relid, char expected_state) CHECK_FOR_INTERRUPTS(); - /* XXX use cache invalidation here to improve performance? */ - PushActiveSnapshot(GetLatestSnapshot()); + InvalidateCatalogSnapshot(); state = GetSubscriptionRelState(MyLogicalRepWorker->subid, - relid, &statelsn, true); - PopActiveSnapshot(); + relid, &statelsn); if (state == SUBREL_STATE_UNKNOWN) - return false; + break; if (state == expected_state) return true; /* Check if the sync worker is still running and bail if not. */ LWLockAcquire(LogicalRepWorkerLock, LW_SHARED); - - /* Check if the opposite worker is still running and bail if not. */ - worker = logicalrep_worker_find(MyLogicalRepWorker->subid, - am_tablesync_worker() ? InvalidOid : relid, + worker = logicalrep_worker_find(MyLogicalRepWorker->subid, relid, false); LWLockRelease(LogicalRepWorkerLock); if (!worker) - return false; + break; (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, @@ -269,26 +277,56 @@ invalidate_syncing_table_states(Datum arg, int cacheid, uint32 hashvalue) static void process_syncing_tables_for_sync(XLogRecPtr current_lsn) { - Assert(IsTransactionState()); - SpinLockAcquire(&MyLogicalRepWorker->relmutex); if (MyLogicalRepWorker->relstate == SUBREL_STATE_CATCHUP && current_lsn >= MyLogicalRepWorker->relstate_lsn) { TimeLineID tli; + char syncslotname[NAMEDATALEN] = {0}; MyLogicalRepWorker->relstate = SUBREL_STATE_SYNCDONE; MyLogicalRepWorker->relstate_lsn = current_lsn; SpinLockRelease(&MyLogicalRepWorker->relmutex); + /* + * UpdateSubscriptionRelState must be called within a transaction. + * That transaction will be ended within the finish_sync_worker(). + */ + if (!IsTransactionState()) + StartTransactionCommand(); + UpdateSubscriptionRelState(MyLogicalRepWorker->subid, MyLogicalRepWorker->relid, MyLogicalRepWorker->relstate, MyLogicalRepWorker->relstate_lsn); - walrcv_endstreaming(wrconn, &tli); + /* + * End streaming so that LogRepWorkerWalRcvConn can be used to drop + * the slot. + */ + walrcv_endstreaming(LogRepWorkerWalRcvConn, &tli); + + /* + * Cleanup the tablesync slot. + * + * This has to be done after updating the state because otherwise if + * there is an error while doing the database operations we won't be + * able to rollback dropped slot. + */ + ReplicationSlotNameForTablesync(MyLogicalRepWorker->subid, + MyLogicalRepWorker->relid, + syncslotname, + sizeof(syncslotname)); + + /* + * It is important to give an error if we are unable to drop the slot, + * otherwise, it won't be dropped till the corresponding subscription + * is dropped. So passing missing_ok = false. + */ + ReplicationSlotDropAtPubNode(LogRepWorkerWalRcvConn, syncslotname, false); + finish_sync_worker(); } else @@ -371,7 +409,6 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn) { HASHCTL ctl; - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(struct tablesync_start_time_mapping); last_start_times = hash_create("Logical replication table sync worker start times", @@ -404,6 +441,8 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn) */ if (current_lsn >= rstate->lsn) { + char originname[NAMEDATALEN]; + rstate->state = SUBREL_STATE_READY; rstate->lsn = current_lsn; if (!started_tx) @@ -412,6 +451,28 @@ process_syncing_tables_for_apply(XLogRecPtr current_lsn) started_tx = true; } + /* + * Remove the tablesync origin tracking if exists. + * + * The normal case origin drop is done here instead of in the + * process_syncing_tables_for_sync function because we don't + * allow to drop the origin till the process owning the origin + * is alive. + * + * There is a chance that the user is concurrently performing + * refresh for the subscription where we remove the table + * state and its origin and by this time the origin might be + * already removed. So passing missing_ok = true. + */ + ReplicationOriginNameForTablesync(MyLogicalRepWorker->subid, + rstate->relid, + originname, + sizeof(originname)); + replorigin_drop_by_name(originname, true, false); + + /* + * Update the state to READY only after the origin cleanup. + */ UpdateSubscriptionRelState(MyLogicalRepWorker->subid, rstate->relid, rstate->state, rstate->lsn); @@ -584,7 +645,7 @@ copy_read_data(void *outbuf, int minread, int maxread, void *extra) for (;;) { /* Try read the data. */ - len = walrcv_receive(wrconn, &buf, &fd); + len = walrcv_receive(LogRepWorkerWalRcvConn, &buf, &fd); CHECK_FOR_INTERRUPTS(); @@ -640,7 +701,7 @@ fetch_remote_table_info(char *nspname, char *relname, StringInfoData cmd; TupleTableSlot *slot; Oid tableRow[] = {OIDOID, CHAROID, CHAROID}; - Oid attrRow[] = {TEXTOID, OIDOID, INT4OID, BOOLOID}; + Oid attrRow[] = {TEXTOID, OIDOID, BOOLOID}; bool isnull; int natt; @@ -657,17 +718,20 @@ fetch_remote_table_info(char *nspname, char *relname, " AND c.relname = %s", quote_literal_cstr(nspname), quote_literal_cstr(relname)); - res = walrcv_exec(wrconn, cmd.data, lengthof(tableRow), tableRow); + res = walrcv_exec(LogRepWorkerWalRcvConn, cmd.data, + lengthof(tableRow), tableRow); if (res->status != WALRCV_OK_TUPLES) ereport(ERROR, - (errmsg("could not fetch table info for table \"%s.%s\" from publisher: %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not fetch table info for table \"%s.%s\" from publisher: %s", nspname, relname, res->err))); slot = MakeSingleTupleTableSlot(res->tupledesc, &TTSOpsMinimalTuple); if (!tuplestore_gettupleslot(res->tuplestore, true, false, slot)) ereport(ERROR, - (errmsg("table \"%s.%s\" not found on publisher", + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("table \"%s.%s\" not found on publisher", nspname, relname))); lrel->remoteid = DatumGetObjectId(slot_getattr(slot, 1, &isnull)); @@ -685,7 +749,6 @@ fetch_remote_table_info(char *nspname, char *relname, appendStringInfo(&cmd, "SELECT a.attname," " a.atttypid," - " a.atttypmod," " a.attnum = ANY(i.indkey)" " FROM pg_catalog.pg_attribute a" " LEFT JOIN pg_catalog.pg_index i" @@ -695,13 +758,16 @@ fetch_remote_table_info(char *nspname, char *relname, " AND a.attrelid = %u" " ORDER BY a.attnum", lrel->remoteid, - (walrcv_server_version(wrconn) >= 120000 ? "AND a.attgenerated = ''" : ""), + (walrcv_server_version(LogRepWorkerWalRcvConn) >= 120000 ? + "AND a.attgenerated = ''" : ""), lrel->remoteid); - res = walrcv_exec(wrconn, cmd.data, lengthof(attrRow), attrRow); + res = walrcv_exec(LogRepWorkerWalRcvConn, cmd.data, + lengthof(attrRow), attrRow); if (res->status != WALRCV_OK_TUPLES) ereport(ERROR, - (errmsg("could not fetch table info for table \"%s.%s\": %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not fetch table info for table \"%s.%s\" from publisher: %s", nspname, relname, res->err))); /* We don't know the number of rows coming, so allocate enough space. */ @@ -718,7 +784,7 @@ fetch_remote_table_info(char *nspname, char *relname, Assert(!isnull); lrel->atttyps[natt] = DatumGetObjectId(slot_getattr(slot, 2, &isnull)); Assert(!isnull); - if (DatumGetBool(slot_getattr(slot, 4, &isnull))) + if (DatumGetBool(slot_getattr(slot, 3, &isnull))) lrel->attkeys = bms_add_member(lrel->attkeys, natt); /* Should never happen. */ @@ -748,7 +814,7 @@ copy_table(Relation rel) LogicalRepRelation lrel; WalRcvExecResult *res; StringInfoData cmd; - CopyState cstate; + CopyFromState cstate; List *attnamelist; ParseState *pstate; @@ -774,7 +840,7 @@ copy_table(Relation rel) * For non-tables, we need to do COPY (SELECT ...), but we can't just * do SELECT * because we need to not copy generated columns. */ - appendStringInfo(&cmd, "COPY (SELECT "); + appendStringInfoString(&cmd, "COPY (SELECT "); for (int i = 0; i < lrel.natts; i++) { appendStringInfoString(&cmd, quote_identifier(lrel.attnames[i])); @@ -784,11 +850,12 @@ copy_table(Relation rel) appendStringInfo(&cmd, " FROM %s) TO STDOUT", quote_qualified_identifier(lrel.nspname, lrel.relname)); } - res = walrcv_exec(wrconn, cmd.data, 0, NULL); + res = walrcv_exec(LogRepWorkerWalRcvConn, cmd.data, 0, NULL); pfree(cmd.data); if (res->status != WALRCV_OK_COPY_OUT) ereport(ERROR, - (errmsg("could not start initial contents copy for table \"%s.%s\": %s", + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not start initial contents copy for table \"%s.%s\": %s", lrel.nspname, lrel.relname, res->err))); walrcv_clear_result(res); @@ -799,9 +866,7 @@ copy_table(Relation rel) NULL, false, false); attnamelist = make_copy_attnamelist(relmapentry); - cstate = BeginCopyFrom(pstate, rel, NULL, false, copy_read_data, - NULL /* callback extra data */, - attnamelist, NIL); + cstate = BeginCopyFrom(pstate, rel, NULL, NULL, false, copy_read_data, attnamelist, NIL); /* Do the copy */ (void) CopyFrom(cstate); @@ -809,9 +874,49 @@ copy_table(Relation rel) logicalrep_rel_close(relmapentry, NoLock); } +/* + * Determine the tablesync slot name. + * + * The name must not exceed NAMEDATALEN - 1 because of remote node constraints + * on slot name length. We append system_identifier to avoid slot_name + * collision with subscriptions in other clusters. With the current scheme + * pg_%u_sync_%u_UINT64_FORMAT (3 + 10 + 6 + 10 + 20 + '\0'), the maximum + * length of slot_name will be 50. + * + * The returned slot name is stored in the supplied buffer (syncslotname) with + * the given size. + * + * Note: We don't use the subscription slot name as part of tablesync slot name + * because we are responsible for cleaning up these slots and it could become + * impossible to recalculate what name to cleanup if the subscription slot name + * had changed. + */ +void +ReplicationSlotNameForTablesync(Oid suboid, Oid relid, + char *syncslotname, int szslot) +{ + snprintf(syncslotname, szslot, "pg_%u_sync_%u_" UINT64_FORMAT, suboid, + relid, GetSystemIdentifier()); +} + +/* + * Form the origin name for tablesync. + * + * Return the name in the supplied buffer. + */ +void +ReplicationOriginNameForTablesync(Oid suboid, Oid relid, + char *originname, int szorgname) +{ + snprintf(originname, szorgname, "pg_%u_%u", suboid, relid); +} + /* * Start syncing the table in the sync worker. * + * If nothing needs to be done to sync the table, we exit the worker without + * any further action. + * * The returned slot name is palloc'ed in current memory context. */ char * @@ -821,12 +926,16 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos) char *err; char relstate; XLogRecPtr relstate_lsn; + Relation rel; + WalRcvExecResult *res; + char originname[NAMEDATALEN]; + RepOriginId originid; /* Check the state of the table synchronization. */ StartTransactionCommand(); relstate = GetSubscriptionRelState(MyLogicalRepWorker->subid, MyLogicalRepWorker->relid, - &relstate_lsn, true); + &relstate_lsn); CommitTransactionCommand(); SpinLockAcquire(&MyLogicalRepWorker->relmutex); @@ -835,157 +944,217 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos) SpinLockRelease(&MyLogicalRepWorker->relmutex); /* - * To build a slot name for the sync work, we are limited to NAMEDATALEN - - * 1 characters. We cut the original slot name to NAMEDATALEN - 28 chars - * and append _%u_sync_%u (1 + 10 + 6 + 10 + '\0'). (It's actually the - * NAMEDATALEN on the remote that matters, but this scheme will also work - * reasonably if that is different.) + * If synchronization is already done or no longer necessary, exit now + * that we've updated shared memory state. */ - StaticAssertStmt(NAMEDATALEN >= 32, "NAMEDATALEN too small"); /* for sanity */ - slotname = psprintf("%.*s_%u_sync_%u", - NAMEDATALEN - 28, - MySubscription->slotname, - MySubscription->oid, - MyLogicalRepWorker->relid); + switch (relstate) + { + case SUBREL_STATE_SYNCDONE: + case SUBREL_STATE_READY: + case SUBREL_STATE_UNKNOWN: + finish_sync_worker(); /* doesn't return */ + } + + /* Calculate the name of the tablesync slot. */ + slotname = (char *) palloc(NAMEDATALEN); + ReplicationSlotNameForTablesync(MySubscription->oid, + MyLogicalRepWorker->relid, + slotname, + NAMEDATALEN); /* * Here we use the slot name instead of the subscription name as the * application_name, so that it is different from the main apply worker, * so that synchronous replication can distinguish them. */ - wrconn = walrcv_connect(MySubscription->conninfo, true, slotname, &err); - if (wrconn == NULL) + LogRepWorkerWalRcvConn = + walrcv_connect(MySubscription->conninfo, true, slotname, &err); + if (LogRepWorkerWalRcvConn == NULL) ereport(ERROR, - (errmsg("could not connect to the publisher: %s", err))); + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not connect to the publisher: %s", err))); - switch (MyLogicalRepWorker->relstate) + Assert(MyLogicalRepWorker->relstate == SUBREL_STATE_INIT || + MyLogicalRepWorker->relstate == SUBREL_STATE_DATASYNC || + MyLogicalRepWorker->relstate == SUBREL_STATE_FINISHEDCOPY); + + /* Assign the origin tracking record name. */ + ReplicationOriginNameForTablesync(MySubscription->oid, + MyLogicalRepWorker->relid, + originname, + sizeof(originname)); + + if (MyLogicalRepWorker->relstate == SUBREL_STATE_DATASYNC) { - case SUBREL_STATE_INIT: - case SUBREL_STATE_DATASYNC: - { - Relation rel; - WalRcvExecResult *res; + /* + * We have previously errored out before finishing the copy so the + * replication slot might exist. We want to remove the slot if it + * already exists and proceed. + * + * XXX We could also instead try to drop the slot, last time we failed + * but for that, we might need to clean up the copy state as it might + * be in the middle of fetching the rows. Also, if there is a network + * breakdown then it wouldn't have succeeded so trying it next time + * seems like a better bet. + */ + ReplicationSlotDropAtPubNode(LogRepWorkerWalRcvConn, slotname, true); + } + else if (MyLogicalRepWorker->relstate == SUBREL_STATE_FINISHEDCOPY) + { + /* + * The COPY phase was previously done, but tablesync then crashed + * before it was able to finish normally. + */ + StartTransactionCommand(); - SpinLockAcquire(&MyLogicalRepWorker->relmutex); - MyLogicalRepWorker->relstate = SUBREL_STATE_DATASYNC; - MyLogicalRepWorker->relstate_lsn = InvalidXLogRecPtr; - SpinLockRelease(&MyLogicalRepWorker->relmutex); + /* + * The origin tracking name must already exist. It was created first + * time this tablesync was launched. + */ + originid = replorigin_by_name(originname, false); + replorigin_session_setup(originid); + replorigin_session_origin = originid; + *origin_startpos = replorigin_session_get_progress(false); - /* Update the state and make it visible to others. */ - StartTransactionCommand(); - UpdateSubscriptionRelState(MyLogicalRepWorker->subid, - MyLogicalRepWorker->relid, - MyLogicalRepWorker->relstate, - MyLogicalRepWorker->relstate_lsn); - CommitTransactionCommand(); - pgstat_report_stat(false); + CommitTransactionCommand(); - /* - * We want to do the table data sync in a single transaction. - */ - StartTransactionCommand(); + goto copy_table_done; + } - /* - * Use a standard write lock here. It might be better to - * disallow access to the table while it's being synchronized. - * But we don't want to block the main apply process from - * working and it has to open the relation in RowExclusiveLock - * when remapping remote relation id to local one. - */ - rel = table_open(MyLogicalRepWorker->relid, RowExclusiveLock); + SpinLockAcquire(&MyLogicalRepWorker->relmutex); + MyLogicalRepWorker->relstate = SUBREL_STATE_DATASYNC; + MyLogicalRepWorker->relstate_lsn = InvalidXLogRecPtr; + SpinLockRelease(&MyLogicalRepWorker->relmutex); - /* - * Create a temporary slot for the sync process. We do this - * inside the transaction so that we can use the snapshot made - * by the slot to get existing data. - */ - res = walrcv_exec(wrconn, - "BEGIN READ ONLY ISOLATION LEVEL " - "REPEATABLE READ", 0, NULL); - if (res->status != WALRCV_OK_COMMAND) - ereport(ERROR, - (errmsg("table copy could not start transaction on publisher"), - errdetail("The error was: %s", res->err))); - walrcv_clear_result(res); + /* Update the state and make it visible to others. */ + StartTransactionCommand(); + UpdateSubscriptionRelState(MyLogicalRepWorker->subid, + MyLogicalRepWorker->relid, + MyLogicalRepWorker->relstate, + MyLogicalRepWorker->relstate_lsn); + CommitTransactionCommand(); + pgstat_report_stat(false); - /* - * Create new temporary logical decoding slot. - * - * We'll use slot for data copy so make sure the snapshot is - * used for the transaction; that way the COPY will get data - * that is consistent with the lsn used by the slot to start - * decoding. - */ - walrcv_create_slot(wrconn, slotname, true, - CRS_USE_SNAPSHOT, origin_startpos); + StartTransactionCommand(); - PushActiveSnapshot(GetTransactionSnapshot()); - copy_table(rel); - PopActiveSnapshot(); + /* + * Use a standard write lock here. It might be better to disallow access + * to the table while it's being synchronized. But we don't want to block + * the main apply process from working and it has to open the relation in + * RowExclusiveLock when remapping remote relation id to local one. + */ + rel = table_open(MyLogicalRepWorker->relid, RowExclusiveLock); - res = walrcv_exec(wrconn, "COMMIT", 0, NULL); - if (res->status != WALRCV_OK_COMMAND) - ereport(ERROR, - (errmsg("table copy could not finish transaction on publisher"), - errdetail("The error was: %s", res->err))); - walrcv_clear_result(res); + /* + * Start a transaction in the remote node in REPEATABLE READ mode. This + * ensures that both the replication slot we create (see below) and the + * COPY are consistent with each other. + */ + res = walrcv_exec(LogRepWorkerWalRcvConn, + "BEGIN READ ONLY ISOLATION LEVEL REPEATABLE READ", + 0, NULL); + if (res->status != WALRCV_OK_COMMAND) + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("table copy could not start transaction on publisher: %s", + res->err))); + walrcv_clear_result(res); - table_close(rel, NoLock); + /* + * Create a new permanent logical decoding slot. This slot will be used + * for the catchup phase after COPY is done, so tell it to use the + * snapshot to make the final data consistent. + * + * Prevent cancel/die interrupts while creating slot here because it is + * possible that before the server finishes this command, a concurrent + * drop subscription happens which would complete without removing this + * slot leading to a dangling slot on the server. + */ + HOLD_INTERRUPTS(); + walrcv_create_slot(LogRepWorkerWalRcvConn, slotname, false /* permanent */ , + CRS_USE_SNAPSHOT, origin_startpos); + RESUME_INTERRUPTS(); - /* Make the copy visible. */ - CommandCounterIncrement(); + /* + * Setup replication origin tracking. The purpose of doing this before the + * copy is to avoid doing the copy again due to any error in setting up + * origin tracking. + */ + originid = replorigin_by_name(originname, true); + if (!OidIsValid(originid)) + { + /* + * Origin tracking does not exist, so create it now. + * + * Then advance to the LSN got from walrcv_create_slot. This is WAL + * logged for the purpose of recovery. Locks are to prevent the + * replication origin from vanishing while advancing. + */ + originid = replorigin_create(originname); - /* - * We are done with the initial data synchronization, update - * the state. - */ - SpinLockAcquire(&MyLogicalRepWorker->relmutex); - MyLogicalRepWorker->relstate = SUBREL_STATE_SYNCWAIT; - MyLogicalRepWorker->relstate_lsn = *origin_startpos; - SpinLockRelease(&MyLogicalRepWorker->relmutex); - - /* Wait for main apply worker to tell us to catchup. */ - wait_for_worker_state_change(SUBREL_STATE_CATCHUP); - - /*---------- - * There are now two possible states here: - * a) Sync is behind the apply. If that's the case we need to - * catch up with it by consuming the logical replication - * stream up to the relstate_lsn. For that, we exit this - * function and continue in ApplyWorkerMain(). - * b) Sync is caught up with the apply. So it can just set - * the state to SYNCDONE and finish. - *---------- - */ - if (*origin_startpos >= MyLogicalRepWorker->relstate_lsn) - { - /* - * Update the new state in catalog. No need to bother - * with the shmem state as we are exiting for good. - */ - UpdateSubscriptionRelState(MyLogicalRepWorker->subid, - MyLogicalRepWorker->relid, - SUBREL_STATE_SYNCDONE, - *origin_startpos); - finish_sync_worker(); - } - break; - } - case SUBREL_STATE_SYNCDONE: - case SUBREL_STATE_READY: - case SUBREL_STATE_UNKNOWN: + LockRelationOid(ReplicationOriginRelationId, RowExclusiveLock); + replorigin_advance(originid, *origin_startpos, InvalidXLogRecPtr, + true /* go backward */ , true /* WAL log */ ); + UnlockRelationOid(ReplicationOriginRelationId, RowExclusiveLock); - /* - * Nothing to do here but finish. (UNKNOWN means the relation was - * removed from pg_subscription_rel before the sync worker could - * start.) - */ - finish_sync_worker(); - break; - default: - elog(ERROR, "unknown relation state \"%c\"", - MyLogicalRepWorker->relstate); + replorigin_session_setup(originid); + replorigin_session_origin = originid; } + else + { + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("replication origin \"%s\" already exists", + originname))); + } + + /* Now do the initial data copy */ + PushActiveSnapshot(GetTransactionSnapshot()); + copy_table(rel); + PopActiveSnapshot(); + + res = walrcv_exec(LogRepWorkerWalRcvConn, "COMMIT", 0, NULL); + if (res->status != WALRCV_OK_COMMAND) + ereport(ERROR, + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("table copy could not finish transaction on publisher: %s", + res->err))); + walrcv_clear_result(res); + table_close(rel, NoLock); + + /* Make the copy visible. */ + CommandCounterIncrement(); + + /* + * Update the persisted state to indicate the COPY phase is done; make it + * visible to others. + */ + UpdateSubscriptionRelState(MyLogicalRepWorker->subid, + MyLogicalRepWorker->relid, + SUBREL_STATE_FINISHEDCOPY, + MyLogicalRepWorker->relstate_lsn); + + CommitTransactionCommand(); + +copy_table_done: + + elog(DEBUG1, + "LogicalRepSyncTableStart: '%s' origin_startpos lsn %X/%X", + originname, LSN_FORMAT_ARGS(*origin_startpos)); + + /* + * We are done with the initial data synchronization, update the state. + */ + SpinLockAcquire(&MyLogicalRepWorker->relmutex); + MyLogicalRepWorker->relstate = SUBREL_STATE_SYNCWAIT; + MyLogicalRepWorker->relstate_lsn = *origin_startpos; + SpinLockRelease(&MyLogicalRepWorker->relmutex); + + /* + * Finally, wait until the main apply worker tells us to catch up and then + * return to let LogicalRepApplyLoop do it. + */ + wait_for_worker_state_change(SUBREL_STATE_CATCHUP); return slotname; } diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index b95025d3ae9d..7c8c4222775b 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -2,7 +2,7 @@ * worker.c * PostgreSQL logical replication worker (apply) * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/worker.c @@ -18,11 +18,45 @@ * This module includes server facing code and shares libpqwalreceiver * module with walreceiver for providing the libpq specific functionality. * + * + * STREAMED TRANSACTIONS + * --------------------- + * Streamed transactions (large transactions exceeding a memory limit on the + * upstream) are not applied immediately, but instead, the data is written + * to temporary files and then applied at once when the final commit arrives. + * + * Unlike the regular (non-streamed) case, handling streamed transactions has + * to handle aborts of both the toplevel transaction and subtransactions. This + * is achieved by tracking offsets for subtransactions, which is then used + * to truncate the file with serialized changes. + * + * The files are placed in tmp file directory by default, and the filenames + * include both the XID of the toplevel transaction and OID of the + * subscription. This is necessary so that different workers processing a + * remote transaction with the same XID doesn't interfere. + * + * We use BufFiles instead of using normal temporary files because (a) the + * BufFile infrastructure supports temporary files that exceed the OS file size + * limit, (b) provides a way for automatic clean up on the error and (c) provides + * a way to survive these files across local transactions and allow to open and + * close at stream start and close. We decided to use SharedFileSet + * infrastructure as without that it deletes the files on the closure of the + * file and if we decide to keep stream files open across the start/stop stream + * then it will consume a lot of memory (more than 8K for each BufFile and + * there could be multiple such BufFiles as the subscriber could receive + * multiple start/stop streams for different transactions before getting the + * commit). Moreover, if we don't use SharedFileSet then we also need to invent + * a new way to pass filenames to BufFile APIs so that we are allowed to open + * the file we desired across multiple stream-open calls for the same + * transaction. *------------------------------------------------------------------------- */ #include "postgres.h" +#include +#include + #include "access/table.h" #include "access/tableam.h" #include "access/xact.h" @@ -33,7 +67,9 @@ #include "catalog/pg_inherits.h" #include "catalog/pg_subscription.h" #include "catalog/pg_subscription_rel.h" +#include "catalog/pg_tablespace.h" #include "commands/tablecmds.h" +#include "commands/tablespace.h" #include "commands/trigger.h" #include "executor/executor.h" #include "executor/execPartition.h" @@ -45,8 +81,6 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "optimizer/optimizer.h" -#include "parser/analyze.h" -#include "parser/parse_relation.h" #include "pgstat.h" #include "postmaster/bgworker.h" #include "postmaster/interrupt.h" @@ -63,7 +97,9 @@ #include "replication/walreceiver.h" #include "replication/worker_internal.h" #include "rewrite/rewriteHandler.h" +#include "storage/buffile.h" #include "storage/bufmgr.h" +#include "storage/fd.h" #include "storage/ipc.h" #include "storage/lmgr.h" #include "storage/proc.h" @@ -71,6 +107,7 @@ #include "tcop/tcopprot.h" #include "utils/builtins.h" #include "utils/catcache.h" +#include "utils/dynahash.h" #include "utils/datum.h" #include "utils/fmgroids.h" #include "utils/guc.h" @@ -99,10 +136,39 @@ typedef struct SlotErrCallbackArg int remote_attnum; } SlotErrCallbackArg; +typedef struct ApplyExecutionData +{ + EState *estate; /* executor state, used to track resources */ + + LogicalRepRelMapEntry *targetRel; /* replication target rel */ + ResultRelInfo *targetRelInfo; /* ResultRelInfo for same */ + + /* These fields are used when the target relation is partitioned: */ + ModifyTableState *mtstate; /* dummy ModifyTable state */ + PartitionTupleRouting *proute; /* partition routing info */ +} ApplyExecutionData; + +/* + * Stream xid hash entry. Whenever we see a new xid we create this entry in the + * xidhash and along with it create the streaming file and store the fileset handle. + * The subxact file is created iff there is any subxact info under this xid. This + * entry is used on the subsequent streams for the xid to get the corresponding + * fileset handles, so storing them in hash makes the search faster. + */ +typedef struct StreamXidHash +{ + TransactionId xid; /* xid is the hash key and must be first */ + SharedFileSet *stream_fileset; /* shared file set for stream data */ + SharedFileSet *subxact_fileset; /* shared file set for subxact info */ +} StreamXidHash; + static MemoryContext ApplyMessageContext = NULL; MemoryContext ApplyContext = NULL; -WalReceiverConn *wrconn = NULL; +/* per stream context for streaming transactions */ +static MemoryContext LogicalStreamingContext = NULL; + +WalReceiverConn *LogRepWorkerWalRcvConn = NULL; Subscription *MySubscription = NULL; bool MySubscriptionValid = false; @@ -110,30 +176,85 @@ bool MySubscriptionValid = false; bool in_remote_transaction = false; static XLogRecPtr remote_final_lsn = InvalidXLogRecPtr; +/* fields valid only when processing streamed transaction */ +static bool in_streamed_transaction = false; + +static TransactionId stream_xid = InvalidTransactionId; + +/* + * Hash table for storing the streaming xid information along with shared file + * set for streaming and subxact files. + */ +static HTAB *xidhash = NULL; + +/* BufFile handle of the current streaming file */ +static BufFile *stream_fd = NULL; + +typedef struct SubXactInfo +{ + TransactionId xid; /* XID of the subxact */ + int fileno; /* file number in the buffile */ + off_t offset; /* offset in the file */ +} SubXactInfo; + +/* Sub-transaction data for the current streaming transaction */ +typedef struct ApplySubXactData +{ + uint32 nsubxacts; /* number of sub-transactions */ + uint32 nsubxacts_max; /* current capacity of subxacts */ + TransactionId subxact_last; /* xid of the last sub-transaction */ + SubXactInfo *subxacts; /* sub-xact offset in changes file */ +} ApplySubXactData; + +static ApplySubXactData subxact_data = {0, 0, InvalidTransactionId, NULL}; + +static inline void subxact_filename(char *path, Oid subid, TransactionId xid); +static inline void changes_filename(char *path, Oid subid, TransactionId xid); + +/* + * Information about subtransactions of a given toplevel transaction. + */ +static void subxact_info_write(Oid subid, TransactionId xid); +static void subxact_info_read(Oid subid, TransactionId xid); +static void subxact_info_add(TransactionId xid); +static inline void cleanup_subxact_info(void); + +/* + * Serialize and deserialize changes for a toplevel transaction. + */ +static void stream_cleanup_files(Oid subid, TransactionId xid); +static void stream_open_file(Oid subid, TransactionId xid, bool first); +static void stream_write_change(char action, StringInfo s); +static void stream_close_file(void); + static void send_feedback(XLogRecPtr recvpos, bool force, bool requestReply); static void store_flush_position(XLogRecPtr remote_lsn); static void maybe_reread_subscription(void); -static void apply_handle_insert_internal(ResultRelInfo *relinfo, - EState *estate, TupleTableSlot *remoteslot); -static void apply_handle_update_internal(ResultRelInfo *relinfo, - EState *estate, TupleTableSlot *remoteslot, - LogicalRepTupleData *newtup, - LogicalRepRelMapEntry *relmapentry); -static void apply_handle_delete_internal(ResultRelInfo *relinfo, EState *estate, +/* prototype needed because of stream_commit */ +static void apply_dispatch(StringInfo s); + +static void apply_handle_commit_internal(StringInfo s, + LogicalRepCommitData *commit_data); +static void apply_handle_insert_internal(ApplyExecutionData *edata, + ResultRelInfo *relinfo, + TupleTableSlot *remoteslot); +static void apply_handle_update_internal(ApplyExecutionData *edata, + ResultRelInfo *relinfo, TupleTableSlot *remoteslot, - LogicalRepRelation *remoterel); + LogicalRepTupleData *newtup); +static void apply_handle_delete_internal(ApplyExecutionData *edata, + ResultRelInfo *relinfo, + TupleTableSlot *remoteslot); static bool FindReplTupleInLocalRel(EState *estate, Relation localrel, LogicalRepRelation *remoterel, TupleTableSlot *remoteslot, TupleTableSlot **localslot); -static void apply_handle_tuple_routing(ResultRelInfo *relinfo, - EState *estate, +static void apply_handle_tuple_routing(ApplyExecutionData *edata, TupleTableSlot *remoteslot, LogicalRepTupleData *newtup, - LogicalRepRelMapEntry *relmapentry, CmdType operation); /* @@ -161,47 +282,101 @@ should_apply_changes_for_rel(LogicalRepRelMapEntry *rel) } /* - * Make sure that we started local transaction. + * Begin one step (one INSERT, UPDATE, etc) of a replication transaction. * - * Also switches to ApplyMessageContext as necessary. + * Start a transaction, if this is the first step (else we keep using the + * existing transaction). + * Also provide a global snapshot and ensure we run in ApplyMessageContext. */ -static bool -ensure_transaction(void) +static void +begin_replication_step(void) { - if (IsTransactionState()) + SetCurrentStatementStartTimestamp(); + + if (!IsTransactionState()) { - SetCurrentStatementStartTimestamp(); + StartTransactionCommand(); + maybe_reread_subscription(); + } + + PushActiveSnapshot(GetTransactionSnapshot()); - if (CurrentMemoryContext != ApplyMessageContext) - MemoryContextSwitchTo(ApplyMessageContext); + MemoryContextSwitchTo(ApplyMessageContext); +} + +/* + * Finish up one step of a replication transaction. + * Callers of begin_replication_step() must also call this. + * + * We don't close out the transaction here, but we should increment + * the command counter to make the effects of this step visible. + */ +static void +end_replication_step(void) +{ + PopActiveSnapshot(); + + CommandCounterIncrement(); +} +/* + * Handle streamed transactions. + * + * If in streaming mode (receiving a block of streamed transaction), we + * simply redirect it to a file for the proper toplevel transaction. + * + * Returns true for streamed transactions, false otherwise (regular mode). + */ +static bool +handle_streamed_transaction(LogicalRepMsgType action, StringInfo s) +{ + TransactionId xid; + + /* not in streaming mode */ + if (!in_streamed_transaction) return false; - } - SetCurrentStatementStartTimestamp(); - StartTransactionCommand(); + Assert(stream_fd != NULL); + Assert(TransactionIdIsValid(stream_xid)); - maybe_reread_subscription(); + /* + * We should have received XID of the subxact as the first part of the + * message, so extract it. + */ + xid = pq_getmsgint(s, 4); + + if (!TransactionIdIsValid(xid)) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("invalid transaction ID in streamed replication transaction"))); + + /* Add the new subxact to the array (unless already there). */ + subxact_info_add(xid); + + /* write the change to the current file */ + stream_write_change(action, s); - MemoryContextSwitchTo(ApplyMessageContext); return true; } - /* * Executor state preparation for evaluation of constraint expressions, - * indexes and triggers. + * indexes and triggers for the specified relation. * - * This is based on similar code in copy.c + * Note that the caller must open and close any indexes to be updated. */ -static EState * -create_estate_for_relation(LogicalRepRelMapEntry *rel) +static ApplyExecutionData * +create_edata_for_relation(LogicalRepRelMapEntry *rel) { + ApplyExecutionData *edata; EState *estate; - ResultRelInfo *resultRelInfo; RangeTblEntry *rte; + ResultRelInfo *resultRelInfo; - estate = CreateExecutorState(); + edata = (ApplyExecutionData *) palloc0(sizeof(ApplyExecutionData)); + edata->targetRel = rel; + + edata->estate = estate = CreateExecutorState(); rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; @@ -210,19 +385,61 @@ create_estate_for_relation(LogicalRepRelMapEntry *rel) rte->rellockmode = AccessShareLock; ExecInitRangeTable(estate, list_make1(rte)); - resultRelInfo = makeNode(ResultRelInfo); + edata->targetRelInfo = resultRelInfo = makeNode(ResultRelInfo); + + /* + * Use Relation opened by logicalrep_rel_open() instead of opening it + * again. + */ InitResultRelInfo(resultRelInfo, rel->localrel, 1, NULL, 0); - estate->es_result_relations = resultRelInfo; - estate->es_num_result_relations = 1; - estate->es_result_relation_info = resultRelInfo; + /* + * We put the ResultRelInfo in the es_opened_result_relations list, even + * though we don't populate the es_result_relations array. That's a bit + * bogus, but it's enough to make ExecGetTriggerResultRel() find them. + * + * ExecOpenIndices() is not called here either, each execution path doing + * an apply operation being responsible for that. + */ + estate->es_opened_result_relations = + lappend(estate->es_opened_result_relations, resultRelInfo); estate->es_output_cid = GetCurrentCommandId(true); /* Prepare to catch AFTER triggers. */ AfterTriggerBeginQuery(); - return estate; + /* other fields of edata remain NULL for now */ + + return edata; +} + +/* + * Finish any operations related to the executor state created by + * create_edata_for_relation(). + */ +static void +finish_edata(ApplyExecutionData *edata) +{ + EState *estate = edata->estate; + + /* Handle any queued AFTER triggers. */ + AfterTriggerEndQuery(estate); + + /* Shut down tuple routing, if any was done. */ + if (edata->proute) + ExecCleanupTupleRouting(edata->mtstate, edata->proute); + + /* + * Cleanup. It might seem that we should call ExecCloseResultRelations() + * here, but we intentionally don't. It would close the rel we added to + * es_opened_result_relations above, which is wrong because we took no + * corresponding refcount. We rely on ExecCleanupTupleRouting() to close + * any other relations opened during execution. + */ + ExecResetTupleTable(estate->es_tupleTable, false); + FreeExecutorState(estate); + pfree(edata); } /* @@ -571,31 +788,375 @@ apply_handle_commit(StringInfo s) logicalrep_read_commit(s, &commit_data); - Assert(commit_data.commit_lsn == remote_final_lsn); + if (commit_data.commit_lsn != remote_final_lsn) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("incorrect commit LSN %X/%X in commit message (expected %X/%X)", + LSN_FORMAT_ARGS(commit_data.commit_lsn), + LSN_FORMAT_ARGS(remote_final_lsn)))); + + apply_handle_commit_internal(s, &commit_data); + + /* Process any tables that are being synchronized in parallel. */ + process_syncing_tables(commit_data.end_lsn); + + pgstat_report_activity(STATE_IDLE, NULL); +} + +/* + * Handle ORIGIN message. + * + * TODO, support tracking of multiple origins + */ +static void +apply_handle_origin(StringInfo s) +{ + /* + * ORIGIN message can only come inside streaming transaction or inside + * remote transaction and before any actual writes. + */ + if (!in_streamed_transaction && + (!in_remote_transaction || + (IsTransactionState() && !am_tablesync_worker()))) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("ORIGIN message sent out of order"))); +} + +/* + * Handle STREAM START message. + */ +static void +apply_handle_stream_start(StringInfo s) +{ + bool first_segment; + HASHCTL hash_ctl; + + if (in_streamed_transaction) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("duplicate STREAM START message"))); + + /* + * Start a transaction on stream start, this transaction will be committed + * on the stream stop unless it is a tablesync worker in which case it + * will be committed after processing all the messages. We need the + * transaction for handling the buffile, used for serializing the + * streaming data and subxact info. + */ + begin_replication_step(); + + /* notify handle methods we're processing a remote transaction */ + in_streamed_transaction = true; + + /* extract XID of the top-level transaction */ + stream_xid = logicalrep_read_stream_start(s, &first_segment); + + if (!TransactionIdIsValid(stream_xid)) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("invalid transaction ID in streamed replication transaction"))); - /* The synchronization worker runs in single transaction. */ - if (IsTransactionState() && !am_tablesync_worker()) + /* + * Initialize the xidhash table if we haven't yet. This will be used for + * the entire duration of the apply worker so create it in permanent + * context. + */ + if (xidhash == NULL) + { + hash_ctl.keysize = sizeof(TransactionId); + hash_ctl.entrysize = sizeof(StreamXidHash); + hash_ctl.hcxt = ApplyContext; + xidhash = hash_create("StreamXidHash", 1024, &hash_ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + } + + /* open the spool file for this transaction */ + stream_open_file(MyLogicalRepWorker->subid, stream_xid, first_segment); + + /* if this is not the first segment, open existing subxact file */ + if (!first_segment) + subxact_info_read(MyLogicalRepWorker->subid, stream_xid); + + pgstat_report_activity(STATE_RUNNING, NULL); + + end_replication_step(); +} + +/* + * Handle STREAM STOP message. + */ +static void +apply_handle_stream_stop(StringInfo s) +{ + if (!in_streamed_transaction) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("STREAM STOP message without STREAM START"))); + + /* + * Close the file with serialized changes, and serialize information about + * subxacts for the toplevel transaction. + */ + subxact_info_write(MyLogicalRepWorker->subid, stream_xid); + stream_close_file(); + + /* We must be in a valid transaction state */ + Assert(IsTransactionState()); + + /* Commit the per-stream transaction */ + CommitTransactionCommand(); + + in_streamed_transaction = false; + + /* Reset per-stream context */ + MemoryContextReset(LogicalStreamingContext); + + pgstat_report_activity(STATE_IDLE, NULL); +} + +/* + * Handle STREAM abort message. + */ +static void +apply_handle_stream_abort(StringInfo s) +{ + TransactionId xid; + TransactionId subxid; + + if (in_streamed_transaction) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("STREAM ABORT message without STREAM STOP"))); + + logicalrep_read_stream_abort(s, &xid, &subxid); + + /* + * If the two XIDs are the same, it's in fact abort of toplevel xact, so + * just delete the files with serialized info. + */ + if (xid == subxid) + stream_cleanup_files(MyLogicalRepWorker->subid, xid); + else { /* - * Update origin state so we can restart streaming from correct - * position in case of crash. + * OK, so it's a subxact. We need to read the subxact file for the + * toplevel transaction, determine the offset tracked for the subxact, + * and truncate the file with changes. We also remove the subxacts + * with higher offsets (or rather higher XIDs). + * + * We intentionally scan the array from the tail, because we're likely + * aborting a change for the most recent subtransactions. + * + * We can't use the binary search here as subxact XIDs won't + * necessarily arrive in sorted order, consider the case where we have + * released the savepoint for multiple subtransactions and then + * performed rollback to savepoint for one of the earlier + * sub-transaction. + */ + int64 i; + int64 subidx; + BufFile *fd; + bool found = false; + char path[MAXPGPATH]; + StreamXidHash *ent; + + subidx = -1; + begin_replication_step(); + subxact_info_read(MyLogicalRepWorker->subid, xid); + + for (i = subxact_data.nsubxacts; i > 0; i--) + { + if (subxact_data.subxacts[i - 1].xid == subxid) + { + subidx = (i - 1); + found = true; + break; + } + } + + /* + * If it's an empty sub-transaction then we will not find the subxid + * here so just cleanup the subxact info and return. */ - replorigin_session_origin_lsn = commit_data.end_lsn; - replorigin_session_origin_timestamp = commit_data.committime; + if (!found) + { + /* Cleanup the subxact info */ + cleanup_subxact_info(); + end_replication_step(); + CommitTransactionCommand(); + return; + } - CommitTransactionCommand(); - pgstat_report_stat(false); + ent = (StreamXidHash *) hash_search(xidhash, + (void *) &xid, + HASH_FIND, + NULL); + if (!ent) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("transaction %u not found in stream XID hash table", + xid))); + + /* open the changes file */ + changes_filename(path, MyLogicalRepWorker->subid, xid); + fd = BufFileOpenShared(ent->stream_fileset, path, O_RDWR); - store_flush_position(commit_data.end_lsn); + /* OK, truncate the file at the right offset */ + BufFileTruncateShared(fd, subxact_data.subxacts[subidx].fileno, + subxact_data.subxacts[subidx].offset); + BufFileClose(fd); + + /* discard the subxacts added later */ + subxact_data.nsubxacts = subidx; + + /* write the updated subxact list */ + subxact_info_write(MyLogicalRepWorker->subid, xid); + + end_replication_step(); + CommitTransactionCommand(); } - else +} + +/* + * Handle STREAM COMMIT message. + */ +static void +apply_handle_stream_commit(StringInfo s) +{ + TransactionId xid; + StringInfoData s2; + int nchanges; + char path[MAXPGPATH]; + char *buffer = NULL; + LogicalRepCommitData commit_data; + StreamXidHash *ent; + MemoryContext oldcxt; + BufFile *fd; + + if (in_streamed_transaction) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("STREAM COMMIT message without STREAM STOP"))); + + xid = logicalrep_read_stream_commit(s, &commit_data); + + elog(DEBUG1, "received commit for streamed transaction %u", xid); + + /* Make sure we have an open transaction */ + begin_replication_step(); + + /* + * Allocate file handle and memory required to process all the messages in + * TopTransactionContext to avoid them getting reset after each message is + * processed. + */ + oldcxt = MemoryContextSwitchTo(TopTransactionContext); + + /* open the spool file for the committed transaction */ + changes_filename(path, MyLogicalRepWorker->subid, xid); + elog(DEBUG1, "replaying changes from file \"%s\"", path); + + ent = (StreamXidHash *) hash_search(xidhash, + (void *) &xid, + HASH_FIND, + NULL); + if (!ent) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("transaction %u not found in stream XID hash table", + xid))); + + fd = BufFileOpenShared(ent->stream_fileset, path, O_RDONLY); + + buffer = palloc(BLCKSZ); + initStringInfo(&s2); + + MemoryContextSwitchTo(oldcxt); + + remote_final_lsn = commit_data.commit_lsn; + + /* + * Make sure the handle apply_dispatch methods are aware we're in a remote + * transaction. + */ + in_remote_transaction = true; + pgstat_report_activity(STATE_RUNNING, NULL); + + end_replication_step(); + + /* + * Read the entries one by one and pass them through the same logic as in + * apply_dispatch. + */ + nchanges = 0; + while (true) { - /* Process any invalidation messages that might have accumulated. */ - AcceptInvalidationMessages(); - maybe_reread_subscription(); + int nbytes; + int len; + + CHECK_FOR_INTERRUPTS(); + + /* read length of the on-disk record */ + nbytes = BufFileRead(fd, &len, sizeof(len)); + + /* have we reached end of the file? */ + if (nbytes == 0) + break; + + /* do we have a correct length? */ + if (nbytes != sizeof(len)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read from streaming transaction's changes file \"%s\": %m", + path))); + + if (len <= 0) + elog(ERROR, "incorrect length %d in streaming transaction's changes file \"%s\"", + len, path); + + /* make sure we have sufficiently large buffer */ + buffer = repalloc(buffer, len); + + /* and finally read the data into the buffer */ + if (BufFileRead(fd, buffer, len) != len) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read from streaming transaction's changes file \"%s\": %m", + path))); + + /* copy the buffer to the stringinfo and call apply_dispatch */ + resetStringInfo(&s2); + appendBinaryStringInfo(&s2, buffer, len); + + /* Ensure we are reading the data into our memory context. */ + oldcxt = MemoryContextSwitchTo(ApplyMessageContext); + + apply_dispatch(&s2); + + MemoryContextReset(ApplyMessageContext); + + MemoryContextSwitchTo(oldcxt); + + nchanges++; + + if (nchanges % 1000 == 0) + elog(DEBUG1, "replayed %d changes from file \"%s\"", + nchanges, path); } - in_remote_transaction = false; + BufFileClose(fd); + + pfree(buffer); + pfree(s2.data); + + elog(DEBUG1, "replayed %d (all) changes from file \"%s\"", + nchanges, path); + + apply_handle_commit_internal(s, &commit_data); + + /* unlink the files with serialized changes and subxact info */ + stream_cleanup_files(MyLogicalRepWorker->subid, xid); /* Process any tables that are being synchronized in parallel. */ process_syncing_tables(commit_data.end_lsn); @@ -604,22 +1165,33 @@ apply_handle_commit(StringInfo s) } /* - * Handle ORIGIN message. - * - * TODO, support tracking of multiple origins + * Helper function for apply_handle_commit and apply_handle_stream_commit. */ static void -apply_handle_origin(StringInfo s) +apply_handle_commit_internal(StringInfo s, LogicalRepCommitData *commit_data) { - /* - * ORIGIN message can only come inside remote transaction and before any - * actual writes. - */ - if (!in_remote_transaction || - (IsTransactionState() && !am_tablesync_worker())) - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("ORIGIN message sent out of order"))); + if (IsTransactionState()) + { + /* + * Update origin state so we can restart streaming from correct + * position in case of crash. + */ + replorigin_session_origin_lsn = commit_data->end_lsn; + replorigin_session_origin_timestamp = commit_data->committime; + + CommitTransactionCommand(); + pgstat_report_stat(false); + + store_flush_position(commit_data->end_lsn); + } + else + { + /* Process any invalidation messages that might have accumulated. */ + AcceptInvalidationMessages(); + maybe_reread_subscription(); + } + + in_remote_transaction = false; } /* @@ -635,6 +1207,9 @@ apply_handle_relation(StringInfo s) { LogicalRepRelation *rel; + if (handle_streamed_transaction(LOGICAL_REP_MSG_RELATION, s)) + return; + rel = logicalrep_read_rel(s); logicalrep_relmap_update(rel); } @@ -650,6 +1225,9 @@ apply_handle_type(StringInfo s) { LogicalRepTyp typ; + if (handle_streamed_transaction(LOGICAL_REP_MSG_TYPE, s)) + return; + logicalrep_read_typ(s, &typ); logicalrep_typmap_update(&typ); } @@ -682,11 +1260,15 @@ apply_handle_insert(StringInfo s) LogicalRepRelMapEntry *rel; LogicalRepTupleData newtup; LogicalRepRelId relid; + ApplyExecutionData *edata; EState *estate; TupleTableSlot *remoteslot; MemoryContext oldctx; - ensure_transaction(); + if (handle_streamed_transaction(LOGICAL_REP_MSG_INSERT, s)) + return; + + begin_replication_step(); relid = logicalrep_read_insert(s, &newtup); rel = logicalrep_rel_open(relid, RowExclusiveLock); @@ -697,18 +1279,17 @@ apply_handle_insert(StringInfo s) * transaction so it's safe to unlock it. */ logicalrep_rel_close(rel, RowExclusiveLock); + end_replication_step(); return; } /* Initialize the executor state. */ - estate = create_estate_for_relation(rel); + edata = create_edata_for_relation(rel); + estate = edata->estate; remoteslot = ExecInitExtraTupleSlot(estate, RelationGetDescr(rel->localrel), &TTSOpsVirtual); - /* Input functions may need an active snapshot, so get one */ - PushActiveSnapshot(GetTransactionSnapshot()); - /* Process and store remote tuple in the slot */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); slot_store_data(remoteslot, rel, &newtup); @@ -717,34 +1298,36 @@ apply_handle_insert(StringInfo s) /* For a partitioned table, insert the tuple into a partition. */ if (rel->localrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - apply_handle_tuple_routing(estate->es_result_relation_info, estate, - remoteslot, NULL, rel, CMD_INSERT); + apply_handle_tuple_routing(edata, + remoteslot, NULL, CMD_INSERT); else - apply_handle_insert_internal(estate->es_result_relation_info, estate, + apply_handle_insert_internal(edata, edata->targetRelInfo, remoteslot); - PopActiveSnapshot(); - - /* Handle queued AFTER triggers. */ - AfterTriggerEndQuery(estate); - - ExecResetTupleTable(estate->es_tupleTable, false); - FreeExecutorState(estate); + finish_edata(edata); logicalrep_rel_close(rel, NoLock); - CommandCounterIncrement(); + end_replication_step(); } -/* Workhorse for apply_handle_insert() */ +/* + * Workhorse for apply_handle_insert() + * relinfo is for the relation we're actually inserting into + * (could be a child partition of edata->targetRelInfo) + */ static void -apply_handle_insert_internal(ResultRelInfo *relinfo, - EState *estate, TupleTableSlot *remoteslot) +apply_handle_insert_internal(ApplyExecutionData *edata, + ResultRelInfo *relinfo, + TupleTableSlot *remoteslot) { + EState *estate = edata->estate; + + /* We must open indexes here. */ ExecOpenIndices(relinfo, false); /* Do the insert. */ - ExecSimpleRelationInsert(estate, remoteslot); + ExecSimpleRelationInsert(relinfo, estate, remoteslot); /* Cleanup. */ ExecCloseIndices(relinfo); @@ -793,6 +1376,7 @@ apply_handle_update(StringInfo s) { LogicalRepRelMapEntry *rel; LogicalRepRelId relid; + ApplyExecutionData *edata; EState *estate; LogicalRepTupleData oldtup; LogicalRepTupleData newtup; @@ -801,7 +1385,10 @@ apply_handle_update(StringInfo s) RangeTblEntry *target_rte; MemoryContext oldctx; - ensure_transaction(); + if (handle_streamed_transaction(LOGICAL_REP_MSG_UPDATE, s)) + return; + + begin_replication_step(); relid = logicalrep_read_update(s, &has_oldtup, &oldtup, &newtup); @@ -813,6 +1400,7 @@ apply_handle_update(StringInfo s) * transaction so it's safe to unlock it. */ logicalrep_rel_close(rel, RowExclusiveLock); + end_replication_step(); return; } @@ -820,13 +1408,15 @@ apply_handle_update(StringInfo s) check_relation_updatable(rel); /* Initialize the executor state. */ - estate = create_estate_for_relation(rel); + edata = create_edata_for_relation(rel); + estate = edata->estate; remoteslot = ExecInitExtraTupleSlot(estate, RelationGetDescr(rel->localrel), &TTSOpsVirtual); /* - * Populate updatedCols so that per-column triggers can fire. This could + * Populate updatedCols so that per-column triggers can fire, and so + * executor can correctly pass down indexUnchanged hint. This could * include more columns than were actually changed on the publisher * because the logical replication protocol doesn't contain that * information. But it would for example exclude columns that only exist @@ -848,9 +1438,8 @@ apply_handle_update(StringInfo s) } } - fill_extraUpdatedCols(target_rte, RelationGetDescr(rel->localrel)); - - PushActiveSnapshot(GetTransactionSnapshot()); + /* Also populate extraUpdatedCols, in case we have generated columns */ + fill_extraUpdatedCols(target_rte, rel->localrel); /* Build the search tuple. */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); @@ -860,32 +1449,32 @@ apply_handle_update(StringInfo s) /* For a partitioned table, apply update to correct partition. */ if (rel->localrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - apply_handle_tuple_routing(estate->es_result_relation_info, estate, - remoteslot, &newtup, rel, CMD_UPDATE); + apply_handle_tuple_routing(edata, + remoteslot, &newtup, CMD_UPDATE); else - apply_handle_update_internal(estate->es_result_relation_info, estate, - remoteslot, &newtup, rel); + apply_handle_update_internal(edata, edata->targetRelInfo, + remoteslot, &newtup); - PopActiveSnapshot(); - - /* Handle queued AFTER triggers. */ - AfterTriggerEndQuery(estate); - - ExecResetTupleTable(estate->es_tupleTable, false); - FreeExecutorState(estate); + finish_edata(edata); logicalrep_rel_close(rel, NoLock); - CommandCounterIncrement(); + end_replication_step(); } -/* Workhorse for apply_handle_update() */ +/* + * Workhorse for apply_handle_update() + * relinfo is for the relation we're actually updating in + * (could be a child partition of edata->targetRelInfo) + */ static void -apply_handle_update_internal(ResultRelInfo *relinfo, - EState *estate, TupleTableSlot *remoteslot, - LogicalRepTupleData *newtup, - LogicalRepRelMapEntry *relmapentry) +apply_handle_update_internal(ApplyExecutionData *edata, + ResultRelInfo *relinfo, + TupleTableSlot *remoteslot, + LogicalRepTupleData *newtup) { + EState *estate = edata->estate; + LogicalRepRelMapEntry *relmapentry = edata->targetRel; Relation localrel = relinfo->ri_RelationDesc; EPQState epqstate; TupleTableSlot *localslot; @@ -915,17 +1504,19 @@ apply_handle_update_internal(ResultRelInfo *relinfo, EvalPlanQualSetSlot(&epqstate, remoteslot); /* Do the actual update. */ - ExecSimpleRelationUpdate(estate, &epqstate, localslot, remoteslot); + ExecSimpleRelationUpdate(relinfo, estate, &epqstate, localslot, + remoteslot); } else { /* - * The tuple to be updated could not be found. + * The tuple to be updated could not be found. Do nothing except for + * emitting a log message. * - * TODO what to do here, change the log level to LOG perhaps? + * XXX should this be promoted to ereport(LOG) perhaps? */ elog(DEBUG1, - "logical replication did not find row for update " + "logical replication did not find row to be updated " "in replication target relation \"%s\"", RelationGetRelationName(localrel)); } @@ -946,11 +1537,15 @@ apply_handle_delete(StringInfo s) LogicalRepRelMapEntry *rel; LogicalRepTupleData oldtup; LogicalRepRelId relid; + ApplyExecutionData *edata; EState *estate; TupleTableSlot *remoteslot; MemoryContext oldctx; - ensure_transaction(); + if (handle_streamed_transaction(LOGICAL_REP_MSG_DELETE, s)) + return; + + begin_replication_step(); relid = logicalrep_read_delete(s, &oldtup); rel = logicalrep_rel_open(relid, RowExclusiveLock); @@ -961,6 +1556,7 @@ apply_handle_delete(StringInfo s) * transaction so it's safe to unlock it. */ logicalrep_rel_close(rel, RowExclusiveLock); + end_replication_step(); return; } @@ -968,13 +1564,12 @@ apply_handle_delete(StringInfo s) check_relation_updatable(rel); /* Initialize the executor state. */ - estate = create_estate_for_relation(rel); + edata = create_edata_for_relation(rel); + estate = edata->estate; remoteslot = ExecInitExtraTupleSlot(estate, RelationGetDescr(rel->localrel), &TTSOpsVirtual); - PushActiveSnapshot(GetTransactionSnapshot()); - /* Build the search tuple. */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); slot_store_data(remoteslot, rel, &oldtup); @@ -982,32 +1577,32 @@ apply_handle_delete(StringInfo s) /* For a partitioned table, apply delete to correct partition. */ if (rel->localrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - apply_handle_tuple_routing(estate->es_result_relation_info, estate, - remoteslot, NULL, rel, CMD_DELETE); + apply_handle_tuple_routing(edata, + remoteslot, NULL, CMD_DELETE); else - apply_handle_delete_internal(estate->es_result_relation_info, estate, - remoteslot, &rel->remoterel); - - PopActiveSnapshot(); - - /* Handle queued AFTER triggers. */ - AfterTriggerEndQuery(estate); + apply_handle_delete_internal(edata, edata->targetRelInfo, + remoteslot); - ExecResetTupleTable(estate->es_tupleTable, false); - FreeExecutorState(estate); + finish_edata(edata); logicalrep_rel_close(rel, NoLock); - CommandCounterIncrement(); + end_replication_step(); } -/* Workhorse for apply_handle_delete() */ +/* + * Workhorse for apply_handle_delete() + * relinfo is for the relation we're actually deleting from + * (could be a child partition of edata->targetRelInfo) + */ static void -apply_handle_delete_internal(ResultRelInfo *relinfo, EState *estate, - TupleTableSlot *remoteslot, - LogicalRepRelation *remoterel) +apply_handle_delete_internal(ApplyExecutionData *edata, + ResultRelInfo *relinfo, + TupleTableSlot *remoteslot) { + EState *estate = edata->estate; Relation localrel = relinfo->ri_RelationDesc; + LogicalRepRelation *remoterel = &edata->targetRel->remoterel; EPQState epqstate; TupleTableSlot *localslot; bool found; @@ -1024,13 +1619,18 @@ apply_handle_delete_internal(ResultRelInfo *relinfo, EState *estate, EvalPlanQualSetSlot(&epqstate, localslot); /* Do the actual delete. */ - ExecSimpleRelationDelete(estate, &epqstate, localslot); + ExecSimpleRelationDelete(relinfo, estate, &epqstate, localslot); } else { - /* The tuple to be deleted could not be found. */ + /* + * The tuple to be deleted could not be found. Do nothing except for + * emitting a log message. + * + * XXX should this be promoted to ereport(LOG) perhaps? + */ elog(DEBUG1, - "logical replication could not find row for delete " + "logical replication did not find row to be deleted " "in replication target relation \"%s\"", RelationGetRelationName(localrel)); } @@ -1077,30 +1677,32 @@ FindReplTupleInLocalRel(EState *estate, Relation localrel, * This handles insert, update, delete on a partitioned table. */ static void -apply_handle_tuple_routing(ResultRelInfo *relinfo, - EState *estate, +apply_handle_tuple_routing(ApplyExecutionData *edata, TupleTableSlot *remoteslot, LogicalRepTupleData *newtup, - LogicalRepRelMapEntry *relmapentry, CmdType operation) { + EState *estate = edata->estate; + LogicalRepRelMapEntry *relmapentry = edata->targetRel; + ResultRelInfo *relinfo = edata->targetRelInfo; Relation parentrel = relinfo->ri_RelationDesc; - ModifyTableState *mtstate = NULL; - PartitionTupleRouting *proute = NULL; + ModifyTableState *mtstate; + PartitionTupleRouting *proute; ResultRelInfo *partrelinfo; Relation partrel; TupleTableSlot *remoteslot_part; - PartitionRoutingInfo *partinfo; TupleConversionMap *map; MemoryContext oldctx; /* ModifyTableState is needed for ExecFindPartition(). */ - mtstate = makeNode(ModifyTableState); + edata->mtstate = mtstate = makeNode(ModifyTableState); mtstate->ps.plan = NULL; mtstate->ps.state = estate; mtstate->operation = operation; mtstate->resultRelInfo = relinfo; - proute = ExecSetupPartitionTupleRouting(estate, mtstate, parentrel); + + /* ... as is PartitionTupleRouting. */ + edata->proute = proute = ExecSetupPartitionTupleRouting(estate, parentrel); /* * Find the partition to which the "search tuple" belongs. @@ -1117,11 +1719,10 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, * partition's rowtype. Convert if needed or just copy, using a dedicated * slot to store the tuple in any case. */ - partinfo = partrelinfo->ri_PartitionInfo; - remoteslot_part = partinfo->pi_PartitionTupleSlot; + remoteslot_part = partrelinfo->ri_PartitionTupleSlot; if (remoteslot_part == NULL) remoteslot_part = table_slot_create(partrel, &estate->es_tupleTable); - map = partinfo->pi_RootToPartitionMap; + map = partrelinfo->ri_RootToPartitionMap; if (map != NULL) remoteslot_part = execute_attr_map_slot(map->attrMap, remoteslot, remoteslot_part); @@ -1132,18 +1733,16 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, } MemoryContextSwitchTo(oldctx); - estate->es_result_relation_info = partrelinfo; switch (operation) { case CMD_INSERT: - apply_handle_insert_internal(partrelinfo, estate, + apply_handle_insert_internal(edata, partrelinfo, remoteslot_part); break; case CMD_DELETE: - apply_handle_delete_internal(partrelinfo, estate, - remoteslot_part, - &relmapentry->remoterel); + apply_handle_delete_internal(edata, partrelinfo, + remoteslot_part); break; case CMD_UPDATE: @@ -1165,38 +1764,38 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, attrmap); /* Get the matching local tuple from the partition. */ - found = FindReplTupleInLocalRel(estate, partrel, - &part_entry->remoterel, - remoteslot_part, &localslot); - - oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - if (found) - { - /* Apply the update. */ - slot_modify_data(remoteslot_part, localslot, - part_entry, - newtup); - MemoryContextSwitchTo(oldctx); - } - else + found = FindReplTupleInLocalRel(estate, partrel, + &part_entry->remoterel, + remoteslot_part, &localslot); + if (!found) { /* - * The tuple to be updated could not be found. + * The tuple to be updated could not be found. Do nothing + * except for emitting a log message. * - * TODO what to do here, change the log level to LOG - * perhaps? + * XXX should this be promoted to ereport(LOG) perhaps? */ elog(DEBUG1, - "logical replication did not find row for update " - "in replication target relation \"%s\"", + "logical replication did not find row to be updated " + "in replication target relation's partition \"%s\"", RelationGetRelationName(partrel)); + return; } + /* + * Apply the update to the local tuple, putting the result in + * remoteslot_part. + */ + oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); + slot_modify_data(remoteslot_part, localslot, part_entry, + newtup); + MemoryContextSwitchTo(oldctx); + /* * Does the updated tuple still satisfy the current * partition's constraint? */ - if (partrelinfo->ri_PartitionCheck == NULL || + if (!partrel->rd_rel->relispartition || ExecPartitionCheck(partrelinfo, remoteslot_part, estate, false)) { @@ -1213,8 +1812,8 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, ExecOpenIndices(partrelinfo, false); EvalPlanQualSetSlot(&epqstate, remoteslot_part); - ExecSimpleRelationUpdate(estate, &epqstate, localslot, - remoteslot_part); + ExecSimpleRelationUpdate(partrelinfo, estate, &epqstate, + localslot, remoteslot_part); ExecCloseIndices(partrelinfo); EvalPlanQualEnd(&epqstate); } @@ -1255,10 +1854,8 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, Assert(partrelinfo_new != partrelinfo); /* DELETE old tuple found in the old partition. */ - estate->es_result_relation_info = partrelinfo; - apply_handle_delete_internal(partrelinfo, estate, - localslot, - &relmapentry->remoterel); + apply_handle_delete_internal(edata, partrelinfo, + localslot); /* INSERT new tuple into the new partition. */ @@ -1268,12 +1865,11 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); partrel = partrelinfo_new->ri_RelationDesc; - partinfo = partrelinfo_new->ri_PartitionInfo; - remoteslot_part = partinfo->pi_PartitionTupleSlot; + remoteslot_part = partrelinfo_new->ri_PartitionTupleSlot; if (remoteslot_part == NULL) remoteslot_part = table_slot_create(partrel, &estate->es_tupleTable); - map = partinfo->pi_RootToPartitionMap; + map = partrelinfo_new->ri_RootToPartitionMap; if (map != NULL) { remoteslot_part = execute_attr_map_slot(map->attrMap, @@ -1287,8 +1883,7 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, slot_getallattrs(remoteslot); } MemoryContextSwitchTo(oldctx); - estate->es_result_relation_info = partrelinfo_new; - apply_handle_insert_internal(partrelinfo_new, estate, + apply_handle_insert_internal(edata, partrelinfo_new, remoteslot_part); } } @@ -1298,8 +1893,6 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo, elog(ERROR, "unrecognized CmdType: %d", (int) operation); break; } - - ExecCleanupTupleRouting(mtstate, proute); } /* @@ -1319,8 +1912,12 @@ apply_handle_truncate(StringInfo s) List *relids = NIL; List *relids_logged = NIL; ListCell *lc; + LOCKMODE lockmode = AccessExclusiveLock; - ensure_transaction(); + if (handle_streamed_transaction(LOGICAL_REP_MSG_TRUNCATE, s)) + return; + + begin_replication_step(); remote_relids = logicalrep_read_truncate(s, &cascade, &restart_seqs); @@ -1329,14 +1926,14 @@ apply_handle_truncate(StringInfo s) LogicalRepRelId relid = lfirst_oid(lc); LogicalRepRelMapEntry *rel; - rel = logicalrep_rel_open(relid, RowExclusiveLock); + rel = logicalrep_rel_open(relid, lockmode); if (!should_apply_changes_for_rel(rel)) { /* * The relation can't become interesting in the middle of the * transaction so it's safe to unlock it. */ - logicalrep_rel_close(rel, RowExclusiveLock); + logicalrep_rel_close(rel, lockmode); continue; } @@ -1354,7 +1951,7 @@ apply_handle_truncate(StringInfo s) { ListCell *child; List *children = find_all_inheritors(rel->localreloid, - RowExclusiveLock, + lockmode, NULL); foreach(child, children) @@ -1374,7 +1971,7 @@ apply_handle_truncate(StringInfo s) */ if (RELATION_IS_OTHER_TEMP(childrel)) { - table_close(childrel, RowExclusiveLock); + table_close(childrel, lockmode); continue; } @@ -1393,9 +1990,12 @@ apply_handle_truncate(StringInfo s) * to replaying changes without further cascading. This might be later * changeable with a user specified option. */ - ExecuteTruncateGuts(rels, relids, relids_logged, DROP_RESTRICT, restart_seqs, + ExecuteTruncateGuts(rels, + relids, + relids_logged, + DROP_RESTRICT, + restart_seqs, NULL); - foreach(lc, remote_rels) { LogicalRepRelMapEntry *rel = lfirst(lc); @@ -1409,7 +2009,7 @@ apply_handle_truncate(StringInfo s) table_close(rel, NoLock); } - CommandCounterIncrement(); + end_replication_step(); } @@ -1419,51 +2019,76 @@ apply_handle_truncate(StringInfo s) static void apply_dispatch(StringInfo s) { - char action = pq_getmsgbyte(s); + LogicalRepMsgType action = pq_getmsgbyte(s); switch (action) { - /* BEGIN */ - case 'B': + case LOGICAL_REP_MSG_BEGIN: apply_handle_begin(s); - break; - /* COMMIT */ - case 'C': + return; + + case LOGICAL_REP_MSG_COMMIT: apply_handle_commit(s); - break; - /* INSERT */ - case 'I': + return; + + case LOGICAL_REP_MSG_INSERT: apply_handle_insert(s); - break; - /* UPDATE */ - case 'U': + return; + + case LOGICAL_REP_MSG_UPDATE: apply_handle_update(s); - break; - /* DELETE */ - case 'D': + return; + + case LOGICAL_REP_MSG_DELETE: apply_handle_delete(s); - break; - /* TRUNCATE */ - case 'T': + return; + + case LOGICAL_REP_MSG_TRUNCATE: apply_handle_truncate(s); - break; - /* RELATION */ - case 'R': + return; + + case LOGICAL_REP_MSG_RELATION: apply_handle_relation(s); - break; - /* TYPE */ - case 'Y': + return; + + case LOGICAL_REP_MSG_TYPE: apply_handle_type(s); - break; - /* ORIGIN */ - case 'O': + return; + + case LOGICAL_REP_MSG_ORIGIN: apply_handle_origin(s); - break; - default: - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid logical replication message type \"%c\"", action))); + return; + + case LOGICAL_REP_MSG_MESSAGE: + + /* + * Logical replication does not use generic logical messages yet. + * Although, it could be used by other applications that use this + * output plugin. + */ + return; + + case LOGICAL_REP_MSG_STREAM_START: + apply_handle_stream_start(s); + return; + + case LOGICAL_REP_MSG_STREAM_END: + apply_handle_stream_stop(s); + return; + + case LOGICAL_REP_MSG_STREAM_ABORT: + apply_handle_stream_abort(s); + return; + + case LOGICAL_REP_MSG_STREAM_COMMIT: + apply_handle_stream_commit(s); + return; } + + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("invalid logical replication message type \"%c\"", + action))); } /* @@ -1562,6 +2187,8 @@ static void LogicalRepApplyLoop(XLogRecPtr last_received) { TimestampTz last_recv_timestamp = GetCurrentTimestamp(); + bool ping_sent = false; + TimeLineID tli; /* * Init the ApplyMessageContext which we clean up after each replication @@ -1571,9 +2198,18 @@ LogicalRepApplyLoop(XLogRecPtr last_received) "ApplyMessageContext", ALLOCSET_DEFAULT_SIZES); + /* + * This memory context is used for per-stream data when the streaming mode + * is enabled. This context is reset on each stream stop. + */ + LogicalStreamingContext = AllocSetContextCreate(ApplyContext, + "LogicalStreamingContext", + ALLOCSET_DEFAULT_SIZES); + /* mark as idle, before starting to loop */ pgstat_report_activity(STATE_IDLE, NULL); + /* This outer loop iterates once per wait. */ for (;;) { pgsocket fd = PGINVALID_SOCKET; @@ -1581,18 +2217,17 @@ LogicalRepApplyLoop(XLogRecPtr last_received) int len; char *buf = NULL; bool endofstream = false; - bool ping_sent = false; long wait_time; CHECK_FOR_INTERRUPTS(); MemoryContextSwitchTo(ApplyMessageContext); - len = walrcv_receive(wrconn, &buf, &fd); + len = walrcv_receive(LogRepWorkerWalRcvConn, &buf, &fd); if (len != 0) { - /* Process the data */ + /* Loop to process all available data (without blocking). */ for (;;) { CHECK_FOR_INTERRUPTS(); @@ -1668,14 +2303,14 @@ LogicalRepApplyLoop(XLogRecPtr last_received) MemoryContextReset(ApplyMessageContext); } - len = walrcv_receive(wrconn, &buf, &fd); + len = walrcv_receive(LogRepWorkerWalRcvConn, &buf, &fd); } } /* confirm all writes so far */ send_feedback(last_received, false, false); - if (!in_remote_transaction) + if (!in_remote_transaction && !in_streamed_transaction) { /* * If we didn't get any transactions for a while there might be @@ -1695,12 +2330,7 @@ LogicalRepApplyLoop(XLogRecPtr last_received) /* Check if we need to exit the streaming loop. */ if (endofstream) - { - TimeLineID tli; - - walrcv_endstreaming(wrconn, &tli); break; - } /* * Wait for more data or latch. If we have unflushed transactions, @@ -1745,7 +2375,7 @@ LogicalRepApplyLoop(XLogRecPtr last_received) bool requestReply = false; /* - * Check if time since last receive from standby has reached the + * Check if time since last receive from primary has reached the * configured limit. */ if (wal_receiver_timeout > 0) @@ -1759,12 +2389,10 @@ LogicalRepApplyLoop(XLogRecPtr last_received) if (now >= timeout) ereport(ERROR, - (errmsg("terminating logical replication worker due to timeout"))); + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("terminating logical replication worker due to timeout"))); - /* - * We didn't receive anything new, for half of receiver - * replication timeout. Ping the server. - */ + /* Check to see if it's time for a ping. */ if (!ping_sent) { timeout = TimestampTzPlusMilliseconds(last_recv_timestamp, @@ -1780,6 +2408,9 @@ LogicalRepApplyLoop(XLogRecPtr last_received) send_feedback(last_received, requestReply, requestReply); } } + + /* All done */ + walrcv_endstreaming(LogRepWorkerWalRcvConn, &tli); } /* @@ -1859,12 +2490,12 @@ send_feedback(XLogRecPtr recvpos, bool force, bool requestReply) elog(DEBUG2, "sending feedback (force %d) to recv %X/%X, write %X/%X, flush %X/%X", force, - (uint32) (recvpos >> 32), (uint32) recvpos, - (uint32) (writepos >> 32), (uint32) writepos, - (uint32) (flushpos >> 32), (uint32) flushpos - ); + LSN_FORMAT_ARGS(recvpos), + LSN_FORMAT_ARGS(writepos), + LSN_FORMAT_ARGS(flushpos)); - walrcv_send(wrconn, reply_message->data, reply_message->len); + walrcv_send(LogRepWorkerWalRcvConn, + reply_message->data, reply_message->len); if (recvpos > last_recvpos) last_recvpos = recvpos; @@ -1939,6 +2570,7 @@ maybe_reread_subscription(void) strcmp(newsub->name, MySubscription->name) != 0 || strcmp(newsub->slotname, MySubscription->slotname) != 0 || newsub->binary != MySubscription->binary || + newsub->stream != MySubscription->stream || !equal(newsub->publications, MySubscription->publications)) { ereport(LOG, @@ -1980,6 +2612,457 @@ subscription_change_cb(Datum arg, int cacheid, uint32 hashvalue) MySubscriptionValid = false; } +/* + * subxact_info_write + * Store information about subxacts for a toplevel transaction. + * + * For each subxact we store offset of it's first change in the main file. + * The file is always over-written as a whole. + * + * XXX We should only store subxacts that were not aborted yet. + */ +static void +subxact_info_write(Oid subid, TransactionId xid) +{ + char path[MAXPGPATH]; + Size len; + StreamXidHash *ent; + BufFile *fd; + + Assert(TransactionIdIsValid(xid)); + + /* Find the xid entry in the xidhash */ + ent = (StreamXidHash *) hash_search(xidhash, + (void *) &xid, + HASH_FIND, + NULL); + /* By this time we must have created the transaction entry */ + Assert(ent); + + /* + * If there is no subtransaction then nothing to do, but if already have + * subxact file then delete that. + */ + if (subxact_data.nsubxacts == 0) + { + if (ent->subxact_fileset) + { + cleanup_subxact_info(); + SharedFileSetDeleteAll(ent->subxact_fileset); + pfree(ent->subxact_fileset); + ent->subxact_fileset = NULL; + } + return; + } + + subxact_filename(path, subid, xid); + + /* + * Create the subxact file if it not already created, otherwise open the + * existing file. + */ + if (ent->subxact_fileset == NULL) + { + MemoryContext oldctx; + + /* + * We need to maintain shared fileset across multiple stream + * start/stop calls. So, need to allocate it in a persistent context. + */ + oldctx = MemoryContextSwitchTo(ApplyContext); + ent->subxact_fileset = palloc(sizeof(SharedFileSet)); + SharedFileSetInit(ent->subxact_fileset, NULL); + MemoryContextSwitchTo(oldctx); + + fd = BufFileCreateShared(ent->subxact_fileset, path, NULL); + } + else + fd = BufFileOpenShared(ent->subxact_fileset, path, O_RDWR); + + len = sizeof(SubXactInfo) * subxact_data.nsubxacts; + + /* Write the subxact count and subxact info */ + BufFileWrite(fd, &subxact_data.nsubxacts, sizeof(subxact_data.nsubxacts)); + BufFileWrite(fd, subxact_data.subxacts, len); + + BufFileClose(fd); + + /* free the memory allocated for subxact info */ + cleanup_subxact_info(); +} + +/* + * subxact_info_read + * Restore information about subxacts of a streamed transaction. + * + * Read information about subxacts into the structure subxact_data that can be + * used later. + */ +static void +subxact_info_read(Oid subid, TransactionId xid) +{ + char path[MAXPGPATH]; + Size len; + BufFile *fd; + StreamXidHash *ent; + MemoryContext oldctx; + + Assert(!subxact_data.subxacts); + Assert(subxact_data.nsubxacts == 0); + Assert(subxact_data.nsubxacts_max == 0); + + /* Find the stream xid entry in the xidhash */ + ent = (StreamXidHash *) hash_search(xidhash, + (void *) &xid, + HASH_FIND, + NULL); + if (!ent) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("transaction %u not found in stream XID hash table", + xid))); + + /* + * If subxact_fileset is not valid that mean we don't have any subxact + * info + */ + if (ent->subxact_fileset == NULL) + return; + + subxact_filename(path, subid, xid); + + fd = BufFileOpenShared(ent->subxact_fileset, path, O_RDONLY); + + /* read number of subxact items */ + if (BufFileRead(fd, &subxact_data.nsubxacts, + sizeof(subxact_data.nsubxacts)) != + sizeof(subxact_data.nsubxacts)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read from streaming transaction's subxact file \"%s\": %m", + path))); + + len = sizeof(SubXactInfo) * subxact_data.nsubxacts; + + /* we keep the maximum as a power of 2 */ + subxact_data.nsubxacts_max = 1 << my_log2(subxact_data.nsubxacts); + + /* + * Allocate subxact information in the logical streaming context. We need + * this information during the complete stream so that we can add the sub + * transaction info to this. On stream stop we will flush this information + * to the subxact file and reset the logical streaming context. + */ + oldctx = MemoryContextSwitchTo(LogicalStreamingContext); + subxact_data.subxacts = palloc(subxact_data.nsubxacts_max * + sizeof(SubXactInfo)); + MemoryContextSwitchTo(oldctx); + + if ((len > 0) && ((BufFileRead(fd, subxact_data.subxacts, len)) != len)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read from streaming transaction's subxact file \"%s\": %m", + path))); + + BufFileClose(fd); +} + +/* + * subxact_info_add + * Add information about a subxact (offset in the main file). + */ +static void +subxact_info_add(TransactionId xid) +{ + SubXactInfo *subxacts = subxact_data.subxacts; + int64 i; + + /* We must have a valid top level stream xid and a stream fd. */ + Assert(TransactionIdIsValid(stream_xid)); + Assert(stream_fd != NULL); + + /* + * If the XID matches the toplevel transaction, we don't want to add it. + */ + if (stream_xid == xid) + return; + + /* + * In most cases we're checking the same subxact as we've already seen in + * the last call, so make sure to ignore it (this change comes later). + */ + if (subxact_data.subxact_last == xid) + return; + + /* OK, remember we're processing this XID. */ + subxact_data.subxact_last = xid; + + /* + * Check if the transaction is already present in the array of subxact. We + * intentionally scan the array from the tail, because we're likely adding + * a change for the most recent subtransactions. + * + * XXX Can we rely on the subxact XIDs arriving in sorted order? That + * would allow us to use binary search here. + */ + for (i = subxact_data.nsubxacts; i > 0; i--) + { + /* found, so we're done */ + if (subxacts[i - 1].xid == xid) + return; + } + + /* This is a new subxact, so we need to add it to the array. */ + if (subxact_data.nsubxacts == 0) + { + MemoryContext oldctx; + + subxact_data.nsubxacts_max = 128; + + /* + * Allocate this memory for subxacts in per-stream context, see + * subxact_info_read. + */ + oldctx = MemoryContextSwitchTo(LogicalStreamingContext); + subxacts = palloc(subxact_data.nsubxacts_max * sizeof(SubXactInfo)); + MemoryContextSwitchTo(oldctx); + } + else if (subxact_data.nsubxacts == subxact_data.nsubxacts_max) + { + subxact_data.nsubxacts_max *= 2; + subxacts = repalloc(subxacts, + subxact_data.nsubxacts_max * sizeof(SubXactInfo)); + } + + subxacts[subxact_data.nsubxacts].xid = xid; + + /* + * Get the current offset of the stream file and store it as offset of + * this subxact. + */ + BufFileTell(stream_fd, + &subxacts[subxact_data.nsubxacts].fileno, + &subxacts[subxact_data.nsubxacts].offset); + + subxact_data.nsubxacts++; + subxact_data.subxacts = subxacts; +} + +/* format filename for file containing the info about subxacts */ +static inline void +subxact_filename(char *path, Oid subid, TransactionId xid) +{ + snprintf(path, MAXPGPATH, "%u-%u.subxacts", subid, xid); +} + +/* format filename for file containing serialized changes */ +static inline void +changes_filename(char *path, Oid subid, TransactionId xid) +{ + snprintf(path, MAXPGPATH, "%u-%u.changes", subid, xid); +} + +/* + * stream_cleanup_files + * Cleanup files for a subscription / toplevel transaction. + * + * Remove files with serialized changes and subxact info for a particular + * toplevel transaction. Each subscription has a separate set of files. + */ +static void +stream_cleanup_files(Oid subid, TransactionId xid) +{ + char path[MAXPGPATH]; + StreamXidHash *ent; + + /* Find the xid entry in the xidhash */ + ent = (StreamXidHash *) hash_search(xidhash, + (void *) &xid, + HASH_FIND, + NULL); + if (!ent) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("transaction %u not found in stream XID hash table", + xid))); + + /* Delete the change file and release the stream fileset memory */ + changes_filename(path, subid, xid); + SharedFileSetDeleteAll(ent->stream_fileset); + pfree(ent->stream_fileset); + ent->stream_fileset = NULL; + + /* Delete the subxact file and release the memory, if it exist */ + if (ent->subxact_fileset) + { + subxact_filename(path, subid, xid); + SharedFileSetDeleteAll(ent->subxact_fileset); + pfree(ent->subxact_fileset); + ent->subxact_fileset = NULL; + } + + /* Remove the xid entry from the stream xid hash */ + hash_search(xidhash, (void *) &xid, HASH_REMOVE, NULL); +} + +/* + * stream_open_file + * Open a file that we'll use to serialize changes for a toplevel + * transaction. + * + * Open a file for streamed changes from a toplevel transaction identified + * by stream_xid (global variable). If it's the first chunk of streamed + * changes for this transaction, initialize the shared fileset and create the + * buffile, otherwise open the previously created file. + * + * This can only be called at the beginning of a "streaming" block, i.e. + * between stream_start/stream_stop messages from the upstream. + */ +static void +stream_open_file(Oid subid, TransactionId xid, bool first_segment) +{ + char path[MAXPGPATH]; + bool found; + MemoryContext oldcxt; + StreamXidHash *ent; + + Assert(in_streamed_transaction); + Assert(OidIsValid(subid)); + Assert(TransactionIdIsValid(xid)); + Assert(stream_fd == NULL); + + /* create or find the xid entry in the xidhash */ + ent = (StreamXidHash *) hash_search(xidhash, + (void *) &xid, + HASH_ENTER, + &found); + + changes_filename(path, subid, xid); + elog(DEBUG1, "opening file \"%s\" for streamed changes", path); + + /* + * Create/open the buffiles under the logical streaming context so that we + * have those files until stream stop. + */ + oldcxt = MemoryContextSwitchTo(LogicalStreamingContext); + + /* + * If this is the first streamed segment, the file must not exist, so make + * sure we're the ones creating it. Otherwise just open the file for + * writing, in append mode. + */ + if (first_segment) + { + MemoryContext savectx; + SharedFileSet *fileset; + + if (found) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("incorrect first-segment flag for streamed replication transaction"))); + + /* + * We need to maintain shared fileset across multiple stream + * start/stop calls. So, need to allocate it in a persistent context. + */ + savectx = MemoryContextSwitchTo(ApplyContext); + fileset = palloc(sizeof(SharedFileSet)); + + SharedFileSetInit(fileset, NULL); + MemoryContextSwitchTo(savectx); + + stream_fd = BufFileCreateShared(fileset, path, NULL); + + /* Remember the fileset for the next stream of the same transaction */ + ent->xid = xid; + ent->stream_fileset = fileset; + ent->subxact_fileset = NULL; + } + else + { + if (!found) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg_internal("incorrect first-segment flag for streamed replication transaction"))); + + /* + * Open the file and seek to the end of the file because we always + * append the changes file. + */ + stream_fd = BufFileOpenShared(ent->stream_fileset, path, O_RDWR); + BufFileSeek(stream_fd, 0, 0, SEEK_END); + } + + MemoryContextSwitchTo(oldcxt); +} + +/* + * stream_close_file + * Close the currently open file with streamed changes. + * + * This can only be called at the end of a streaming block, i.e. at stream_stop + * message from the upstream. + */ +static void +stream_close_file(void) +{ + Assert(in_streamed_transaction); + Assert(TransactionIdIsValid(stream_xid)); + Assert(stream_fd != NULL); + + BufFileClose(stream_fd); + + stream_xid = InvalidTransactionId; + stream_fd = NULL; +} + +/* + * stream_write_change + * Serialize a change to a file for the current toplevel transaction. + * + * The change is serialized in a simple format, with length (not including + * the length), action code (identifying the message type) and message + * contents (without the subxact TransactionId value). + */ +static void +stream_write_change(char action, StringInfo s) +{ + int len; + + Assert(in_streamed_transaction); + Assert(TransactionIdIsValid(stream_xid)); + Assert(stream_fd != NULL); + + /* total on-disk size, including the action type character */ + len = (s->len - s->cursor) + sizeof(char); + + /* first write the size */ + BufFileWrite(stream_fd, &len, sizeof(len)); + + /* then the action */ + BufFileWrite(stream_fd, &action, sizeof(action)); + + /* and finally the remaining part of the buffer (after the XID) */ + len = (s->len - s->cursor); + + BufFileWrite(stream_fd, &s->data[s->cursor], len); +} + +/* + * Cleanup the memory for subxacts and reset the related variables. + */ +static inline void +cleanup_subxact_info() +{ + if (subxact_data.subxacts) + pfree(subxact_data.subxacts); + + subxact_data.subxacts = NULL; + subxact_data.subxact_last = InvalidTransactionId; + subxact_data.nsubxacts = 0; + subxact_data.nsubxacts_max = 0; +} + /* Logical Replication Apply worker entry point */ void ApplyWorkerMain(Datum main_arg) @@ -2093,10 +3176,8 @@ ApplyWorkerMain(Datum main_arg) /* This is table synchronization worker, call initial sync. */ syncslotname = LogicalRepSyncTableStart(&origin_startpos); - /* The slot name needs to be allocated in permanent memory context. */ - oldctx = MemoryContextSwitchTo(ApplyContext); - myslotname = pstrdup(syncslotname); - MemoryContextSwitchTo(oldctx); + /* allocate slot name in long-lived context */ + myslotname = MemoryContextStrdup(ApplyContext, syncslotname); pfree(syncslotname); } @@ -2116,7 +3197,8 @@ ApplyWorkerMain(Datum main_arg) */ if (!myslotname) ereport(ERROR, - (errmsg("subscription has no replication slot set"))); + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("subscription has no replication slot set"))); /* Setup replication origin tracking. */ StartTransactionCommand(); @@ -2129,18 +3211,18 @@ ApplyWorkerMain(Datum main_arg) origin_startpos = replorigin_session_get_progress(false); CommitTransactionCommand(); - wrconn = walrcv_connect(MySubscription->conninfo, true, MySubscription->name, - &err); - if (wrconn == NULL) + LogRepWorkerWalRcvConn = walrcv_connect(MySubscription->conninfo, true, + MySubscription->name, &err); + if (LogRepWorkerWalRcvConn == NULL) ereport(ERROR, - (errmsg("could not connect to the publisher: %s", err))); + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not connect to the publisher: %s", err))); /* * We don't really use the output identify_system for anything but it * does some initializations on the upstream so let's still call it. */ - (void) walrcv_identify_system(wrconn, &startpointTLI); - + (void) walrcv_identify_system(LogRepWorkerWalRcvConn, &startpointTLI); } /* @@ -2155,12 +3237,15 @@ ApplyWorkerMain(Datum main_arg) options.logical = true; options.startpoint = origin_startpos; options.slotname = myslotname; - options.proto.logical.proto_version = LOGICALREP_PROTO_VERSION_NUM; + options.proto.logical.proto_version = + walrcv_server_version(LogRepWorkerWalRcvConn) >= 140000 ? + LOGICALREP_PROTO_STREAM_VERSION_NUM : LOGICALREP_PROTO_VERSION_NUM; options.proto.logical.publication_names = MySubscription->publications; options.proto.logical.binary = MySubscription->binary; + options.proto.logical.streaming = MySubscription->stream; /* Start normal logical streaming replication. */ - walrcv_startstreaming(wrconn, &options); + walrcv_startstreaming(LogRepWorkerWalRcvConn, &options); /* Run the main loop. */ LogicalRepApplyLoop(origin_startpos); diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 81ef7dc4c1a3..abd5217ab1b5 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -3,7 +3,7 @@ * pgoutput.c * Logical Replication output plugin * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/pgoutput/pgoutput.c @@ -45,19 +45,47 @@ static void pgoutput_change(LogicalDecodingContext *ctx, static void pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, int nrelations, Relation relations[], ReorderBufferChange *change); +static void pgoutput_message(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, XLogRecPtr message_lsn, + bool transactional, const char *prefix, + Size sz, const char *message); static bool pgoutput_origin_filter(LogicalDecodingContext *ctx, RepOriginId origin_id); +static void pgoutput_stream_start(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +static void pgoutput_stream_stop(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn); +static void pgoutput_stream_abort(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr abort_lsn); +static void pgoutput_stream_commit(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn); static bool publications_valid; +static bool in_streaming; static List *LoadPublications(List *pubnames); static void publication_invalidation_cb(Datum arg, int cacheid, uint32 hashvalue); -static void send_relation_and_attrs(Relation relation, LogicalDecodingContext *ctx); +static void send_relation_and_attrs(Relation relation, TransactionId xid, + LogicalDecodingContext *ctx); /* * Entry in the map used to remember which relation schemas we sent. * + * The schema_sent flag determines if the current schema record for the + * relation (and for its ancestor if publish_as_relid is set) was already + * sent to the subscriber (in which case we don't need to send it again). + * + * The schema cache on downstream is however updated only at commit time, + * and with streamed transactions the commit order may be different from + * the order the transactions are sent in. Also, the (sub) transactions + * might get aborted so we need to send the schema for each (sub) transaction + * so that we don't lose the schema information on abort. For handling this, + * we maintain the list of xids (streamed_txns) for those we have already sent + * the schema. + * * For partitions, 'pubactions' considers not only the table's own * publications, but also those of all of its ancestors. */ @@ -65,11 +93,9 @@ typedef struct RelationSyncEntry { Oid relid; /* relation oid */ - /* - * Did we send the schema? If ancestor relid is set, its schema must also - * have been sent for this to be true. - */ bool schema_sent; + List *streamed_txns; /* streamed toplevel transactions with this + * schema */ bool replicate_valid; PublicationActions pubactions; @@ -95,10 +121,15 @@ typedef struct RelationSyncEntry static HTAB *RelationSyncCache = NULL; static void init_rel_sync_cache(MemoryContext decoding_context); +static void cleanup_rel_sync_cache(TransactionId xid, bool is_commit); static RelationSyncEntry *get_rel_sync_entry(PGOutputData *data, Oid relid); static void rel_sync_cache_relation_cb(Datum arg, Oid relid); static void rel_sync_cache_publication_cb(Datum arg, int cacheid, uint32 hashvalue); +static void set_schema_sent_in_streamed_txn(RelationSyncEntry *entry, + TransactionId xid); +static bool get_schema_sent_in_streamed_txn(RelationSyncEntry *entry, + TransactionId xid); /* * Specify output plugin callbacks @@ -112,21 +143,34 @@ _PG_output_plugin_init(OutputPluginCallbacks *cb) cb->begin_cb = pgoutput_begin_txn; cb->change_cb = pgoutput_change; cb->truncate_cb = pgoutput_truncate; + cb->message_cb = pgoutput_message; cb->commit_cb = pgoutput_commit_txn; cb->filter_by_origin_cb = pgoutput_origin_filter; cb->shutdown_cb = pgoutput_shutdown; + + /* transaction streaming */ + cb->stream_start_cb = pgoutput_stream_start; + cb->stream_stop_cb = pgoutput_stream_stop; + cb->stream_abort_cb = pgoutput_stream_abort; + cb->stream_commit_cb = pgoutput_stream_commit; + cb->stream_change_cb = pgoutput_change; + cb->stream_message_cb = pgoutput_message; + cb->stream_truncate_cb = pgoutput_truncate; } static void -parse_output_parameters(List *options, uint32 *protocol_version, - List **publication_names, bool *binary) +parse_output_parameters(List *options, PGOutputData *data) { ListCell *lc; bool protocol_version_given = false; bool publication_names_given = false; bool binary_option_given = false; + bool messages_option_given = false; + bool streaming_given = false; - *binary = false; + data->binary = false; + data->streaming = false; + data->messages = false; foreach(lc, options) { @@ -156,7 +200,7 @@ parse_output_parameters(List *options, uint32 *protocol_version, errmsg("proto_version \"%s\" out of range", strVal(defel->arg)))); - *protocol_version = (uint32) parsed; + data->protocol_version = (uint32) parsed; } else if (strcmp(defel->defname, "publication_names") == 0) { @@ -167,7 +211,7 @@ parse_output_parameters(List *options, uint32 *protocol_version, publication_names_given = true; if (!SplitIdentifierString(strVal(defel->arg), ',', - publication_names)) + &data->publication_names)) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("invalid publication_names syntax"))); @@ -180,7 +224,27 @@ parse_output_parameters(List *options, uint32 *protocol_version, errmsg("conflicting or redundant options"))); binary_option_given = true; - *binary = defGetBoolean(defel); + data->binary = defGetBoolean(defel); + } + else if (strcmp(defel->defname, "messages") == 0) + { + if (messages_option_given) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + messages_option_given = true; + + data->messages = defGetBoolean(defel); + } + else if (strcmp(defel->defname, "streaming") == 0) + { + if (streaming_given) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"))); + streaming_given = true; + + data->streaming = defGetBoolean(defel); } else elog(ERROR, "unrecognized pgoutput option: %s", defel->defname); @@ -214,17 +278,14 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, if (!is_init) { /* Parse the params and ERROR if we see any we don't recognize */ - parse_output_parameters(ctx->output_plugin_options, - &data->protocol_version, - &data->publication_names, - &data->binary); + parse_output_parameters(ctx->output_plugin_options, data); /* Check if we support requested protocol */ - if (data->protocol_version > LOGICALREP_PROTO_VERSION_NUM) + if (data->protocol_version > LOGICALREP_PROTO_MAX_VERSION_NUM) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("client sent proto_version=%d but we only support protocol %d or lower", - data->protocol_version, LOGICALREP_PROTO_VERSION_NUM))); + data->protocol_version, LOGICALREP_PROTO_MAX_VERSION_NUM))); if (data->protocol_version < LOGICALREP_PROTO_MIN_VERSION_NUM) ereport(ERROR, @@ -237,6 +298,27 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("publication_names parameter missing"))); + /* + * Decide whether to enable streaming. It is disabled by default, in + * which case we just update the flag in decoding context. Otherwise + * we only allow it with sufficient version of the protocol, and when + * the output plugin supports it. + */ + if (!data->streaming) + ctx->streaming = false; + else if (data->protocol_version < LOGICALREP_PROTO_STREAM_VERSION_NUM) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("requested proto_version=%d does not support streaming, need %d or higher", + data->protocol_version, LOGICALREP_PROTO_STREAM_VERSION_NUM))); + else if (!ctx->streaming) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("streaming requested, but not supported by output plugin"))); + + /* Also remember we're currently not streaming any transaction. */ + in_streaming = false; + /* Init publication state. */ data->publications = NIL; publications_valid = false; @@ -247,6 +329,11 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, /* Initialize relation schema cache. */ init_rel_sync_cache(CacheMemoryContext); } + else + { + /* Disable the streaming during the slot initialization mode. */ + ctx->streaming = false; + } } /* @@ -264,10 +351,6 @@ pgoutput_begin_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) { char *origin; - /* Message boundary */ - OutputPluginWrite(ctx, false); - OutputPluginPrepareWrite(ctx, true); - /*---------- * XXX: which behaviour do we want here? * @@ -279,7 +362,13 @@ pgoutput_begin_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) *---------- */ if (replorigin_by_oid(txn->origin_id, true, &origin)) + { + /* Message boundary */ + OutputPluginWrite(ctx, false); + OutputPluginPrepareWrite(ctx, true); logicalrep_write_origin(ctx->out, origin, txn->origin_lsn); + } + } OutputPluginWrite(ctx, true); @@ -305,12 +394,57 @@ pgoutput_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, */ static void maybe_send_schema(LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, ReorderBufferChange *change, Relation relation, RelationSyncEntry *relentry) { - if (relentry->schema_sent) + bool schema_sent; + TransactionId xid = InvalidTransactionId; + TransactionId topxid = InvalidTransactionId; + + /* + * Remember XID of the (sub)transaction for the change. We don't care if + * it's top-level transaction or not (we have already sent that XID in + * start of the current streaming block). + * + * If we're not in a streaming block, just use InvalidTransactionId and + * the write methods will not include it. + */ + if (in_streaming) + xid = change->txn->xid; + + if (change->txn->toptxn) + topxid = change->txn->toptxn->xid; + else + topxid = xid; + + /* + * Do we need to send the schema? We do track streamed transactions + * separately, because those may be applied later (and the regular + * transactions won't see their effects until then) and in an order that + * we don't know at this point. + * + * XXX There is a scope of optimization here. Currently, we always send + * the schema first time in a streaming transaction but we can probably + * avoid that by checking 'relentry->schema_sent' flag. However, before + * doing that we need to study its impact on the case where we have a mix + * of streaming and non-streaming transactions. + */ + if (in_streaming) + schema_sent = get_schema_sent_in_streamed_txn(relentry, topxid); + else + schema_sent = relentry->schema_sent; + + /* Nothing to do if we already sent the schema. */ + if (schema_sent) return; - /* If needed, send the ancestor's schema first. */ + /* + * Nope, so send the schema. If the changes will be published using an + * ancestor's schema, not the relation's own, send that ancestor's schema + * before sending relation's own (XXX - maybe sending only the former + * suffices?). This is also a good place to set the map that will be used + * to convert the relation's tuples into the ancestor's format, if needed. + */ if (relentry->publish_as_relid != RelationGetRelid(relation)) { Relation ancestor = RelationIdGetRelation(relentry->publish_as_relid); @@ -320,22 +454,40 @@ maybe_send_schema(LogicalDecodingContext *ctx, /* Map must live as long as the session does. */ oldctx = MemoryContextSwitchTo(CacheMemoryContext); - relentry->map = convert_tuples_by_name(CreateTupleDescCopy(indesc), - CreateTupleDescCopy(outdesc)); + + /* + * Make copies of the TupleDescs that will live as long as the map + * does before putting into the map. + */ + indesc = CreateTupleDescCopy(indesc); + outdesc = CreateTupleDescCopy(outdesc); + relentry->map = convert_tuples_by_name(indesc, outdesc); + if (relentry->map == NULL) + { + /* Map not necessary, so free the TupleDescs too. */ + FreeTupleDesc(indesc); + FreeTupleDesc(outdesc); + } + MemoryContextSwitchTo(oldctx); - send_relation_and_attrs(ancestor, ctx); + send_relation_and_attrs(ancestor, xid, ctx); RelationClose(ancestor); } - send_relation_and_attrs(relation, ctx); - relentry->schema_sent = true; + send_relation_and_attrs(relation, xid, ctx); + + if (in_streaming) + set_schema_sent_in_streamed_txn(relentry, topxid); + else + relentry->schema_sent = true; } /* * Sends a relation */ static void -send_relation_and_attrs(Relation relation, LogicalDecodingContext *ctx) +send_relation_and_attrs(Relation relation, TransactionId xid, + LogicalDecodingContext *ctx) { TupleDesc desc = RelationGetDescr(relation); int i; @@ -359,17 +511,19 @@ send_relation_and_attrs(Relation relation, LogicalDecodingContext *ctx) continue; OutputPluginPrepareWrite(ctx, false); - logicalrep_write_typ(ctx->out, att->atttypid); + logicalrep_write_typ(ctx->out, xid, att->atttypid); OutputPluginWrite(ctx, false); } OutputPluginPrepareWrite(ctx, false); - logicalrep_write_rel(ctx->out, relation); + logicalrep_write_rel(ctx->out, xid, relation); OutputPluginWrite(ctx, false); } /* * Sends the decoded DML over wire. + * + * This is called both in streaming and non-streaming modes. */ static void pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, @@ -378,10 +532,21 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, PGOutputData *data = (PGOutputData *) ctx->output_plugin_private; MemoryContext old; RelationSyncEntry *relentry; + TransactionId xid = InvalidTransactionId; + Relation ancestor = NULL; if (!is_publishable_relation(relation)) return; + /* + * Remember the xid for the change in streaming mode. We need to send xid + * with each change in the streaming mode so that subscriber can make + * their association and on aborts, it can discard the corresponding + * changes. + */ + if (in_streaming) + xid = change->txn->xid; + relentry = get_rel_sync_entry(data, RelationGetRelid(relation)); /* First check the table filter */ @@ -406,7 +571,7 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, /* Avoid leaking memory by using and resetting our own context */ old = MemoryContextSwitchTo(data->context); - maybe_send_schema(ctx, relation, relentry); + maybe_send_schema(ctx, txn, change, relation, relentry); /* Send the data */ switch (change->action) @@ -419,14 +584,15 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, if (relentry->publish_as_relid != RelationGetRelid(relation)) { Assert(relation->rd_rel->relispartition); - relation = RelationIdGetRelation(relentry->publish_as_relid); + ancestor = RelationIdGetRelation(relentry->publish_as_relid); + relation = ancestor; /* Convert tuple if needed. */ if (relentry->map) tuple = execute_attr_map_tuple(tuple, relentry->map); } OutputPluginPrepareWrite(ctx, true); - logicalrep_write_insert(ctx->out, relation, tuple, + logicalrep_write_insert(ctx->out, xid, relation, tuple, data->binary); OutputPluginWrite(ctx, true); break; @@ -441,18 +607,22 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, if (relentry->publish_as_relid != RelationGetRelid(relation)) { Assert(relation->rd_rel->relispartition); - relation = RelationIdGetRelation(relentry->publish_as_relid); + ancestor = RelationIdGetRelation(relentry->publish_as_relid); + relation = ancestor; /* Convert tuples if needed. */ if (relentry->map) { - oldtuple = execute_attr_map_tuple(oldtuple, relentry->map); - newtuple = execute_attr_map_tuple(newtuple, relentry->map); + if (oldtuple) + oldtuple = execute_attr_map_tuple(oldtuple, + relentry->map); + newtuple = execute_attr_map_tuple(newtuple, + relentry->map); } } OutputPluginPrepareWrite(ctx, true); - logicalrep_write_update(ctx->out, relation, oldtuple, newtuple, - data->binary); + logicalrep_write_update(ctx->out, xid, relation, oldtuple, + newtuple, data->binary); OutputPluginWrite(ctx, true); break; } @@ -465,14 +635,15 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, if (relentry->publish_as_relid != RelationGetRelid(relation)) { Assert(relation->rd_rel->relispartition); - relation = RelationIdGetRelation(relentry->publish_as_relid); + ancestor = RelationIdGetRelation(relentry->publish_as_relid); + relation = ancestor; /* Convert tuple if needed. */ if (relentry->map) oldtuple = execute_attr_map_tuple(oldtuple, relentry->map); } OutputPluginPrepareWrite(ctx, true); - logicalrep_write_delete(ctx->out, relation, oldtuple, + logicalrep_write_delete(ctx->out, xid, relation, oldtuple, data->binary); OutputPluginWrite(ctx, true); } @@ -483,6 +654,12 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, Assert(false); } + if (RelationIsValid(ancestor)) + { + RelationClose(ancestor); + ancestor = NULL; + } + /* Cleanup */ MemoryContextSwitchTo(old); MemoryContextReset(data->context); @@ -498,6 +675,11 @@ pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, int i; int nrelids; Oid *relids; + TransactionId xid = InvalidTransactionId; + + /* Remember the xid for the change in streaming mode. See pgoutput_change. */ + if (in_streaming) + xid = change->txn->xid; old = MemoryContextSwitchTo(data->context); @@ -526,13 +708,14 @@ pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, continue; relids[nrelids++] = relid; - maybe_send_schema(ctx, relation, relentry); + maybe_send_schema(ctx, txn, change, relation, relentry); } if (nrelids > 0) { OutputPluginPrepareWrite(ctx, true); logicalrep_write_truncate(ctx->out, + xid, nrelids, relids, change->data.truncate.cascade, @@ -544,6 +727,35 @@ pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, MemoryContextReset(data->context); } +static void +pgoutput_message(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, + XLogRecPtr message_lsn, bool transactional, const char *prefix, Size sz, + const char *message) +{ + PGOutputData *data = (PGOutputData *) ctx->output_plugin_private; + TransactionId xid = InvalidTransactionId; + + if (!data->messages) + return; + + /* + * Remember the xid for the message in streaming mode. See + * pgoutput_change. + */ + if (in_streaming) + xid = txn->xid; + + OutputPluginPrepareWrite(ctx, true); + logicalrep_write_message(ctx->out, + xid, + message_lsn, + transactional, + prefix, + sz, + message); + OutputPluginWrite(ctx, true); +} + /* * Currently we always forward. */ @@ -605,6 +817,119 @@ publication_invalidation_cb(Datum arg, int cacheid, uint32 hashvalue) rel_sync_cache_publication_cb(arg, cacheid, hashvalue); } +/* + * START STREAM callback + */ +static void +pgoutput_stream_start(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn) +{ + bool send_replication_origin = txn->origin_id != InvalidRepOriginId; + + /* we can't nest streaming of transactions */ + Assert(!in_streaming); + + /* + * If we already sent the first stream for this transaction then don't + * send the origin id in the subsequent streams. + */ + if (rbtxn_is_streamed(txn)) + send_replication_origin = false; + + OutputPluginPrepareWrite(ctx, !send_replication_origin); + logicalrep_write_stream_start(ctx->out, txn->xid, !rbtxn_is_streamed(txn)); + + if (send_replication_origin) + { + char *origin; + + if (replorigin_by_oid(txn->origin_id, true, &origin)) + { + /* Message boundary */ + OutputPluginWrite(ctx, false); + OutputPluginPrepareWrite(ctx, true); + logicalrep_write_origin(ctx->out, origin, InvalidXLogRecPtr); + } + } + + OutputPluginWrite(ctx, true); + + /* we're streaming a chunk of transaction now */ + in_streaming = true; +} + +/* + * STOP STREAM callback + */ +static void +pgoutput_stream_stop(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn) +{ + /* we should be streaming a trasanction */ + Assert(in_streaming); + + OutputPluginPrepareWrite(ctx, true); + logicalrep_write_stream_stop(ctx->out); + OutputPluginWrite(ctx, true); + + /* we've stopped streaming a transaction */ + in_streaming = false; +} + +/* + * Notify downstream to discard the streamed transaction (along with all + * it's subtransactions, if it's a toplevel transaction). + */ +static void +pgoutput_stream_abort(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr abort_lsn) +{ + ReorderBufferTXN *toptxn; + + /* + * The abort should happen outside streaming block, even for streamed + * transactions. The transaction has to be marked as streamed, though. + */ + Assert(!in_streaming); + + /* determine the toplevel transaction */ + toptxn = (txn->toptxn) ? txn->toptxn : txn; + + Assert(rbtxn_is_streamed(toptxn)); + + OutputPluginPrepareWrite(ctx, true); + logicalrep_write_stream_abort(ctx->out, toptxn->xid, txn->xid); + OutputPluginWrite(ctx, true); + + cleanup_rel_sync_cache(toptxn->xid, false); +} + +/* + * Notify downstream to apply the streamed transaction (along with all + * it's subtransactions). + */ +static void +pgoutput_stream_commit(struct LogicalDecodingContext *ctx, + ReorderBufferTXN *txn, + XLogRecPtr commit_lsn) +{ + /* + * The commit should happen outside streaming block, even for streamed + * transactions. The transaction has to be marked as streamed, though. + */ + Assert(!in_streaming); + Assert(rbtxn_is_streamed(txn)); + + OutputPluginUpdateProgress(ctx); + + OutputPluginPrepareWrite(ctx, true); + logicalrep_write_stream_commit(ctx->out, txn, commit_lsn); + OutputPluginWrite(ctx, true); + + cleanup_rel_sync_cache(txn->xid, true); +} + /* * Initialize the relation schema sync cache for a decoding session. * @@ -616,22 +941,18 @@ static void init_rel_sync_cache(MemoryContext cachectx) { HASHCTL ctl; - MemoryContext old_ctxt; if (RelationSyncCache != NULL) return; /* Make a new hash table for the cache */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RelationSyncEntry); ctl.hcxt = cachectx; - old_ctxt = MemoryContextSwitchTo(cachectx); RelationSyncCache = hash_create("logical replication output relation cache", 128, &ctl, HASH_ELEM | HASH_CONTEXT | HASH_BLOBS); - (void) MemoryContextSwitchTo(old_ctxt); Assert(RelationSyncCache != NULL); @@ -641,6 +962,39 @@ init_rel_sync_cache(MemoryContext cachectx) (Datum) 0); } +/* + * We expect relatively small number of streamed transactions. + */ +static bool +get_schema_sent_in_streamed_txn(RelationSyncEntry *entry, TransactionId xid) +{ + ListCell *lc; + + foreach(lc, entry->streamed_txns) + { + if (xid == (uint32) lfirst_int(lc)) + return true; + } + + return false; +} + +/* + * Add the xid in the rel sync entry for which we have already sent the schema + * of the relation. + */ +static void +set_schema_sent_in_streamed_txn(RelationSyncEntry *entry, TransactionId xid) +{ + MemoryContext oldctx; + + oldctx = MemoryContextSwitchTo(CacheMemoryContext); + + entry->streamed_txns = lappend_int(entry->streamed_txns, xid); + + MemoryContextSwitchTo(oldctx); +} + /* * Find or create entry in the relation schema cache. * @@ -661,16 +1015,28 @@ get_rel_sync_entry(PGOutputData *data, Oid relid) Assert(RelationSyncCache != NULL); - /* Find cached function info, creating if not found */ - oldctx = MemoryContextSwitchTo(CacheMemoryContext); + /* Find cached relation info, creating if not found */ entry = (RelationSyncEntry *) hash_search(RelationSyncCache, (void *) &relid, HASH_ENTER, &found); - MemoryContextSwitchTo(oldctx); Assert(entry != NULL); /* Not found means schema wasn't sent */ - if (!found || !entry->replicate_valid) + if (!found) + { + /* immediately make a new entry valid enough to satisfy callbacks */ + entry->schema_sent = false; + entry->streamed_txns = NIL; + entry->replicate_valid = false; + entry->pubactions.pubinsert = entry->pubactions.pubupdate = + entry->pubactions.pubdelete = entry->pubactions.pubtruncate = false; + entry->publish_as_relid = InvalidOid; + entry->map = NULL; /* will be set by maybe_send_schema() if + * needed */ + } + + /* Validate the entry */ + if (!entry->replicate_valid) { List *pubids = GetRelationPublications(relid); ListCell *lc; @@ -693,9 +1059,6 @@ get_rel_sync_entry(PGOutputData *data, Oid relid) * relcache considers all publications given relation is in, but here * we only need to consider ones that the subscriber requested. */ - entry->pubactions.pubinsert = entry->pubactions.pubupdate = - entry->pubactions.pubdelete = entry->pubactions.pubtruncate = false; - foreach(lc, data->publications) { Publication *pub = lfirst(lc); @@ -770,12 +1133,53 @@ get_rel_sync_entry(PGOutputData *data, Oid relid) entry->replicate_valid = true; } - if (!found) - entry->schema_sent = false; - return entry; } +/* + * Cleanup list of streamed transactions and update the schema_sent flag. + * + * When a streamed transaction commits or aborts, we need to remove the + * toplevel XID from the schema cache. If the transaction aborted, the + * subscriber will simply throw away the schema records we streamed, so + * we don't need to do anything else. + * + * If the transaction is committed, the subscriber will update the relation + * cache - so tweak the schema_sent flag accordingly. + */ +static void +cleanup_rel_sync_cache(TransactionId xid, bool is_commit) +{ + HASH_SEQ_STATUS hash_seq; + RelationSyncEntry *entry; + ListCell *lc; + + Assert(RelationSyncCache != NULL); + + hash_seq_init(&hash_seq, RelationSyncCache); + while ((entry = hash_seq_search(&hash_seq)) != NULL) + { + /* + * We can set the schema_sent flag for an entry that has committed xid + * in the list as that ensures that the subscriber would have the + * corresponding schema and we don't need to send it unless there is + * any invalidation for that relation. + */ + foreach(lc, entry->streamed_txns) + { + if (xid == (uint32) lfirst_int(lc)) + { + if (is_commit) + entry->schema_sent = true; + + entry->streamed_txns = + foreach_delete_current(entry->streamed_txns, lc); + break; + } + } + } +} + /* * Relcache invalidation callback */ @@ -809,9 +1213,25 @@ rel_sync_cache_relation_cb(Datum arg, Oid relid) /* * Reset schema sent status as the relation definition may have changed. + * Also free any objects that depended on the earlier definition. */ if (entry != NULL) + { entry->schema_sent = false; + list_free(entry->streamed_txns); + entry->streamed_txns = NIL; + if (entry->map) + { + /* + * Must free the TupleDescs contained in the map explicitly, + * because free_conversion_map() doesn't. + */ + FreeTupleDesc(entry->map->indesc); + FreeTupleDesc(entry->map->outdesc); + free_conversion_map(entry->map); + } + entry->map = NULL; + } } /* @@ -837,5 +1257,16 @@ rel_sync_cache_publication_cb(Datum arg, int cacheid, uint32 hashvalue) */ hash_seq_init(&status, RelationSyncCache); while ((entry = (RelationSyncEntry *) hash_seq_search(&status)) != NULL) + { entry->replicate_valid = false; + + /* + * There might be some relations dropped from the publication so we + * don't need to publish the changes for them. + */ + entry->pubactions.pubinsert = false; + entry->pubactions.pubupdate = false; + entry->pubactions.pubdelete = false; + entry->pubactions.pubtruncate = false; + } } diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index 4cc1a2dc2f16..c145fe68791e 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -3,7 +3,7 @@ * * repl_gram.y - Parser for the replication commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index d0025634dae5..322bc58b5149 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -4,7 +4,7 @@ * repl_scanner.l * a lexical scanner for the replication commands * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index f7e34a6ff874..153184051047 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -4,7 +4,7 @@ * Replication slot management. * * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -99,9 +99,6 @@ ReplicationSlot *MyReplicationSlot = NULL; int max_replication_slots = 0; /* the maximum number of replication * slots */ -static ReplicationSlot *SearchNamedReplicationSlot(const char *name); -static int ReplicationSlotAcquireInternal(ReplicationSlot *slot, - const char *name, SlotAcquireBehavior behavior); static void ReplicationSlotDropAcquired(void); static void ReplicationSlotDropPtr(ReplicationSlot *slot); @@ -217,10 +214,17 @@ ReplicationSlotValidateName(const char *name, int elevel) * name: Name of the slot * db_specific: logical decoding is db specific; if the slot is going to * be used for that pass true, otherwise false. + * two_phase: Allows decoding of prepared transactions. We allow this option + * to be enabled only at the slot creation time. If we allow this option + * to be changed during decoding then it is quite possible that we skip + * prepare first time because this option was not enabled. Now next time + * during getting changes, if the two_phase option is enabled it can skip + * prepare because by that time start decoding point has been moved. So the + * user will only get commit prepared. */ void ReplicationSlotCreate(const char *name, bool db_specific, - ReplicationSlotPersistency persistency) + ReplicationSlotPersistency persistency, bool two_phase) { ReplicationSlot *slot = NULL; int i; @@ -278,6 +282,7 @@ ReplicationSlotCreate(const char *name, bool db_specific, namestrcpy(&slot->data.name, name); slot->data.database = db_specific ? MyDatabaseId : InvalidOid; slot->data.persistency = persistency; + slot->data.two_phase = two_phase; /* and then data only present in shared memory */ slot->just_dirtied = false; @@ -314,6 +319,15 @@ ReplicationSlotCreate(const char *name, bool db_specific, LWLockRelease(ReplicationSlotControlLock); + /* + * Create statistics entry for the new logical slot. We don't collect any + * stats for physical slots, so no need to create an entry for the same. + * See ReplicationSlotDropPtr for why we need to do this before releasing + * ReplicationSlotAllocationLock. + */ + if (SlotIsLogical(slot)) + pgstat_report_replslot_create(NameStr(slot->data.name)); + /* * Now that the slot has been marked as in_use and active, it's safe to * let somebody else try to allocate a slot. @@ -328,17 +342,15 @@ ReplicationSlotCreate(const char *name, bool db_specific, * Search for the named replication slot. * * Return the replication slot if found, otherwise NULL. - * - * The caller must hold ReplicationSlotControlLock in shared mode. */ -static ReplicationSlot * -SearchNamedReplicationSlot(const char *name) +ReplicationSlot * +SearchNamedReplicationSlot(const char *name, bool need_lock) { int i; - ReplicationSlot *slot = NULL; + ReplicationSlot *slot = NULL; - Assert(LWLockHeldByMeInMode(ReplicationSlotControlLock, - LW_SHARED)); + if (need_lock) + LWLockAcquire(ReplicationSlotControlLock, LW_SHARED); for (i = 0; i < max_replication_slots; i++) { @@ -351,40 +363,25 @@ SearchNamedReplicationSlot(const char *name) } } + if (need_lock) + LWLockRelease(ReplicationSlotControlLock); + return slot; } /* * Find a previously created slot and mark it as used by this process. * - * The return value is only useful if behavior is SAB_Inquire, in which - * it's zero if we successfully acquired the slot, -1 if the slot no longer - * exists, or the PID of the owning process otherwise. If behavior is - * SAB_Error, then trying to acquire an owned slot is an error. - * If SAB_Block, we sleep until the slot is released by the owning process. - */ -int -ReplicationSlotAcquire(const char *name, SlotAcquireBehavior behavior) -{ - return ReplicationSlotAcquireInternal(NULL, name, behavior); -} - -/* - * Mark the specified slot as used by this process. - * - * Only one of slot and name can be specified. - * If slot == NULL, search for the slot with the given name. - * - * See comments about the return value in ReplicationSlotAcquire(). + * An error is raised if nowait is true and the slot is currently in use. If + * nowait is false, we sleep until the slot is released by the owning process. */ -static int -ReplicationSlotAcquireInternal(ReplicationSlot *slot, const char *name, - SlotAcquireBehavior behavior) +void +ReplicationSlotAcquire(const char *name, bool nowait) { ReplicationSlot *s; int active_pid; - AssertArg((slot == NULL) ^ (name == NULL)); + AssertArg(name != NULL); retry: Assert(MyReplicationSlot == NULL); @@ -395,17 +392,15 @@ ReplicationSlotAcquireInternal(ReplicationSlot *slot, const char *name, * Search for the slot with the specified name if the slot to acquire is * not given. If the slot is not found, we either return -1 or error out. */ - s = slot ? slot : SearchNamedReplicationSlot(name); + s = SearchNamedReplicationSlot(name, false); if (s == NULL || !s->in_use) { LWLockRelease(ReplicationSlotControlLock); - if (behavior == SAB_Inquire) - return -1; ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("replication slot \"%s\" does not exist", - name ? name : NameStr(slot->data.name)))); + name))); } /* @@ -415,11 +410,11 @@ ReplicationSlotAcquireInternal(ReplicationSlot *slot, const char *name, if (IsUnderPostmaster) { /* - * Get ready to sleep on the slot in case it is active if SAB_Block. - * (We may end up not sleeping, but we don't want to do this while - * holding the spinlock.) + * Get ready to sleep on the slot in case it is active. (We may end + * up not sleeping, but we don't want to do this while holding the + * spinlock.) */ - if (behavior == SAB_Block) + if (!nowait) ConditionVariablePrepareToSleep(&s->active_cv); SpinLockAcquire(&s->mutex); @@ -434,36 +429,33 @@ ReplicationSlotAcquireInternal(ReplicationSlot *slot, const char *name, /* * If we found the slot but it's already active in another process, we - * either error out, return the PID of the owning process, or retry - * after a short wait, as caller specified. + * wait until the owning process signals us that it's been released, or + * error out. */ if (active_pid != MyProcPid) { - if (behavior == SAB_Error) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("replication slot \"%s\" is active for PID %d", - NameStr(s->data.name), active_pid))); - else if (behavior == SAB_Inquire) - return active_pid; - - /* Wait here until we get signaled, and then restart */ - ConditionVariableSleep(&s->active_cv, - WAIT_EVENT_REPLICATION_SLOT_DROP); - ConditionVariableCancelSleep(); - goto retry; + if (!nowait) + { + /* Wait here until we get signaled, and then restart */ + ConditionVariableSleep(&s->active_cv, + WAIT_EVENT_REPLICATION_SLOT_DROP); + ConditionVariableCancelSleep(); + goto retry; + } + + ereport(ERROR, + (errcode(ERRCODE_OBJECT_IN_USE), + errmsg("replication slot \"%s\" is active for PID %d", + NameStr(s->data.name), active_pid))); } - else if (behavior == SAB_Block) - ConditionVariableCancelSleep(); /* no sleep needed after all */ + else if (!nowait) + ConditionVariableCancelSleep(); /* no sleep needed after all */ /* Let everybody know we've modified this slot */ ConditionVariableBroadcast(&s->active_cv); /* We made this slot active, so it's ours now. */ MyReplicationSlot = s; - - /* success */ - return 0; } /* @@ -535,9 +527,9 @@ ReplicationSlotRelease(void) MyReplicationSlot = NULL; /* might not have been set when we've been a plain slot */ - LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); - MyProc->vacuumFlags &= ~PROC_IN_LOGICAL_DECODING; - ProcGlobal->vacuumFlags[MyProc->pgxactoff] = MyProc->vacuumFlags; + LWLockAcquire(ProcArrayLock, LW_SHARED); + MyProc->statusFlags &= ~PROC_IN_LOGICAL_DECODING; + ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; LWLockRelease(ProcArrayLock); } @@ -587,7 +579,7 @@ ReplicationSlotDrop(const char *name, bool nowait) { Assert(MyReplicationSlot == NULL); - (void) ReplicationSlotAcquire(name, nowait ? SAB_Error : SAB_Block); + ReplicationSlotAcquire(name, nowait); ReplicationSlotDropAcquired(); } @@ -699,6 +691,25 @@ ReplicationSlotDropPtr(ReplicationSlot *slot) ereport(WARNING, (errmsg("could not remove directory \"%s\"", tmppath))); + /* + * Send a message to drop the replication slot to the stats collector. + * Since there is no guarantee of the order of message transfer on a UDP + * connection, it's possible that a message for creating a new slot + * reaches before a message for removing the old slot. We send the drop + * and create messages while holding ReplicationSlotAllocationLock to + * reduce that possibility. If the messages reached in reverse, we would + * lose one statistics update message. But the next update message will + * create the statistics for the replication slot. + * + * XXX In case, the messages for creation and drop slot of the same name + * get lost and create happens before (auto)vacuum cleans up the dead + * slot, the stats will be accumulated into the old slot. One can imagine + * having OIDs for each slot to avoid the accumulation of stats but that + * doesn't seem worth doing as in practice this won't happen frequently. + */ + if (SlotIsLogical(slot)) + pgstat_report_replslot_drop(NameStr(slot->data.name)); + /* * We release this at the very end, so that nobody starts trying to create * a slot while we're still cleaning up the detritus of the old one. @@ -1141,117 +1152,183 @@ ReplicationSlotReserveWal(void) } /* - * Mark any slot that points to an LSN older than the given segment - * as invalid; it requires WAL that's about to be removed. + * Helper for InvalidateObsoleteReplicationSlots -- acquires the given slot + * and mark it invalid, if necessary and possible. * - * NB - this runs as part of checkpoint, so avoid raising errors if possible. + * Returns whether ReplicationSlotControlLock was released in the interim (and + * in that case we're not holding the lock at return, otherwise we are). + * + * This is inherently racy, because we release the LWLock + * for syscalls, so caller must restart if we return true. */ -void -InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno) +static bool +InvalidatePossiblyObsoleteSlot(ReplicationSlot *s, XLogRecPtr oldestLSN) { - XLogRecPtr oldestLSN; + int last_signaled_pid = 0; + bool released_lock = false; - XLogSegNoOffsetToRecPtr(oldestSegno, 0, wal_segment_size, oldestLSN); - -restart: - LWLockAcquire(ReplicationSlotControlLock, LW_SHARED); - for (int i = 0; i < max_replication_slots; i++) + for (;;) { - ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i]; - XLogRecPtr restart_lsn = InvalidXLogRecPtr; + XLogRecPtr restart_lsn; NameData slotname; - int wspid; - int last_signaled_pid = 0; + int active_pid = 0; + + Assert(LWLockHeldByMeInMode(ReplicationSlotControlLock, LW_SHARED)); if (!s->in_use) - continue; + { + if (released_lock) + LWLockRelease(ReplicationSlotControlLock); + break; + } + /* + * Check if the slot needs to be invalidated. If it needs to be + * invalidated, and is not currently acquired, acquire it and mark it + * as having been invalidated. We do this with the spinlock held to + * avoid race conditions -- for example the restart_lsn could move + * forward, or the slot could be dropped. + */ SpinLockAcquire(&s->mutex); - slotname = s->data.name; + restart_lsn = s->data.restart_lsn; - SpinLockRelease(&s->mutex); + /* + * If the slot is already invalid or is fresh enough, we don't need to + * do anything. + */ if (XLogRecPtrIsInvalid(restart_lsn) || restart_lsn >= oldestLSN) - continue; - LWLockRelease(ReplicationSlotControlLock); - CHECK_FOR_INTERRUPTS(); + { + SpinLockRelease(&s->mutex); + if (released_lock) + LWLockRelease(ReplicationSlotControlLock); + break; + } - /* Get ready to sleep on the slot in case it is active */ - ConditionVariablePrepareToSleep(&s->active_cv); + slotname = s->data.name; + active_pid = s->active_pid; - for (;;) + /* + * If the slot can be acquired, do so and mark it invalidated + * immediately. Otherwise we'll signal the owning process, below, and + * retry. + */ + if (active_pid == 0) { - /* - * Try to mark this slot as used by this process. - * - * Note that ReplicationSlotAcquireInternal(SAB_Inquire) - * should not cancel the prepared condition variable - * if this slot is active in other process. Because in this case - * we have to wait on that CV for the process owning - * the slot to be terminated, later. - */ - wspid = ReplicationSlotAcquireInternal(s, NULL, SAB_Inquire); + MyReplicationSlot = s; + s->active_pid = MyProcPid; + s->data.invalidated_at = restart_lsn; + s->data.restart_lsn = InvalidXLogRecPtr; + } + + SpinLockRelease(&s->mutex); + if (active_pid != 0) + { /* - * Exit the loop if we successfully acquired the slot or - * the slot was dropped during waiting for the owning process - * to be terminated. For example, the latter case is likely to - * happen when the slot is temporary because it's automatically - * dropped by the termination of the owning process. + * Prepare the sleep on the slot's condition variable before + * releasing the lock, to close a possible race condition if the + * slot is released before the sleep below. */ - if (wspid <= 0) - break; + ConditionVariablePrepareToSleep(&s->active_cv); + + LWLockRelease(ReplicationSlotControlLock); + released_lock = true; /* - * Signal to terminate the process that owns the slot. + * Signal to terminate the process that owns the slot, if we + * haven't already signalled it. (Avoidance of repeated + * signalling is the only reason for there to be a loop in this + * routine; otherwise we could rely on caller's restart loop.) * - * There is the race condition where other process may own - * the slot after the process using it was terminated and before - * this process owns it. To handle this case, we signal again - * if the PID of the owning process is changed than the last. - * - * XXX This logic assumes that the same PID is not reused - * very quickly. + * There is the race condition that other process may own the slot + * after its current owner process is terminated and before this + * process owns it. To handle that, we signal only if the PID of + * the owning process has changed from the previous time. (This + * logic assumes that the same PID is not reused very quickly.) */ - if (last_signaled_pid != wspid) + if (last_signaled_pid != active_pid) { ereport(LOG, - (errmsg("terminating process %d because replication slot \"%s\" is too far behind", - wspid, NameStr(slotname)))); - (void) kill(wspid, SIGTERM); - last_signaled_pid = wspid; + (errmsg("terminating process %d to release replication slot \"%s\"", + active_pid, NameStr(slotname)))); + + (void) kill(active_pid, SIGTERM); + last_signaled_pid = active_pid; } - ConditionVariableTimedSleep(&s->active_cv, 10, - WAIT_EVENT_REPLICATION_SLOT_DROP); + /* Wait until the slot is released. */ + ConditionVariableSleep(&s->active_cv, + WAIT_EVENT_REPLICATION_SLOT_DROP); + + /* + * Re-acquire lock and start over; we expect to invalidate the + * slot next time (unless another process acquires the slot in the + * meantime). + */ + LWLockAcquire(ReplicationSlotControlLock, LW_SHARED); + continue; } - ConditionVariableCancelSleep(); + else + { + /* + * We hold the slot now and have already invalidated it; flush it + * to ensure that state persists. + * + * Don't want to hold ReplicationSlotControlLock across file + * system operations, so release it now but be sure to tell caller + * to restart from scratch. + */ + LWLockRelease(ReplicationSlotControlLock); + released_lock = true; - /* - * Do nothing here and start from scratch if the slot has - * already been dropped. - */ - if (wspid == -1) - goto restart; + /* Make sure the invalidated state persists across server restart */ + ReplicationSlotMarkDirty(); + ReplicationSlotSave(); + ReplicationSlotRelease(); - ereport(LOG, - (errmsg("invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size", - NameStr(slotname), - (uint32) (restart_lsn >> 32), - (uint32) restart_lsn))); + ereport(LOG, + (errmsg("invalidating slot \"%s\" because its restart_lsn %X/%X exceeds max_slot_wal_keep_size", + NameStr(slotname), + LSN_FORMAT_ARGS(restart_lsn)))); - SpinLockAcquire(&s->mutex); - s->data.invalidated_at = s->data.restart_lsn; - s->data.restart_lsn = InvalidXLogRecPtr; - SpinLockRelease(&s->mutex); + /* done with this slot for now */ + break; + } + } - /* Make sure the invalidated state persists across server restart */ - ReplicationSlotMarkDirty(); - ReplicationSlotSave(); - ReplicationSlotRelease(); + Assert(released_lock == !LWLockHeldByMe(ReplicationSlotControlLock)); - /* if we did anything, start from scratch */ - goto restart; + return released_lock; +} + +/* + * Mark any slot that points to an LSN older than the given segment + * as invalid; it requires WAL that's about to be removed. + * + * NB - this runs as part of checkpoint, so avoid raising errors if possible. + */ +void +InvalidateObsoleteReplicationSlots(XLogSegNo oldestSegno) +{ + XLogRecPtr oldestLSN; + + XLogSegNoOffsetToRecPtr(oldestSegno, 0, wal_segment_size, oldestLSN); + +restart: + LWLockAcquire(ReplicationSlotControlLock, LW_SHARED); + for (int i = 0; i < max_replication_slots; i++) + { + ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i]; + + if (!s->in_use) + continue; + + if (InvalidatePossiblyObsoleteSlot(s, oldestLSN)) + { + /* if the lock was released, start from scratch */ + goto restart; + } } LWLockRelease(ReplicationSlotControlLock); } diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index db32fa9f3be3..afedf6c40afb 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -3,7 +3,7 @@ * slotfuncs.c * Support functions for replication slots * - * Copyright (c) 2012-2020, PostgreSQL Global Development Group + * Copyright (c) 2012-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/slotfuncs.c @@ -57,7 +57,7 @@ create_physical_replication_slot(char *name, bool immediately_reserve, /* acquire replication slot, this will check for conflicting names */ ReplicationSlotCreate(name, false, - temporary ? RS_TEMPORARY : RS_PERSISTENT); + temporary ? RS_TEMPORARY : RS_PERSISTENT, false); if (immediately_reserve) { @@ -133,7 +133,8 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS) */ static void create_logical_replication_slot(char *name, char *plugin, - bool temporary, XLogRecPtr restart_lsn, + bool temporary, bool two_phase, + XLogRecPtr restart_lsn, bool find_startpoint) { LogicalDecodingContext *ctx = NULL; @@ -149,7 +150,7 @@ create_logical_replication_slot(char *name, char *plugin, * error as well. */ ReplicationSlotCreate(name, true, - temporary ? RS_TEMPORARY : RS_EPHEMERAL); + temporary ? RS_TEMPORARY : RS_EPHEMERAL, two_phase); /* * Create logical decoding context to find start point or, if we don't @@ -186,6 +187,7 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS) Name name = PG_GETARG_NAME(0); Name plugin = PG_GETARG_NAME(1); bool temporary = PG_GETARG_BOOL(2); + bool two_phase = PG_GETARG_BOOL(3); Datum result; TupleDesc tupdesc; HeapTuple tuple; @@ -202,6 +204,7 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS) create_logical_replication_slot(NameStr(*name), NameStr(*plugin), temporary, + two_phase, InvalidXLogRecPtr, true); @@ -245,7 +248,7 @@ pg_drop_replication_slot(PG_FUNCTION_ARGS) Datum pg_get_replication_slots(PG_FUNCTION_ARGS) { -#define PG_GET_REPLICATION_SLOTS_COLS 13 +#define PG_GET_REPLICATION_SLOTS_COLS 14 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; TupleDesc tupdesc; Tuplestorestate *tupstore; @@ -421,11 +424,11 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) nulls[i++] = true; else { - XLogSegNo targetSeg; - uint64 slotKeepSegs; - uint64 keepSegs; - XLogSegNo failSeg; - XLogRecPtr failLSN; + XLogSegNo targetSeg; + uint64 slotKeepSegs; + uint64 keepSegs; + XLogSegNo failSeg; + XLogRecPtr failLSN; XLByteToSeg(slot_contents.data.restart_lsn, targetSeg, wal_segment_size); @@ -441,6 +444,8 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) values[i++] = Int64GetDatum(failLSN - currlsn); } + values[i++] = BoolGetDatum(slot_contents.data.two_phase); + Assert(i == PG_GET_REPLICATION_SLOTS_COLS); tuplestore_putvalues(tupstore, tupdesc, values, nulls); @@ -527,9 +532,6 @@ pg_logical_replication_slot_advance(XLogRecPtr moveto) */ XLogBeginRead(ctx->reader, MyReplicationSlot->data.restart_lsn); - /* Initialize our return value in case we don't do anything */ - retlsn = MyReplicationSlot->data.confirmed_flush; - /* invalidate non-timetravel entries */ InvalidateSystemCaches(); @@ -646,7 +648,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) moveto = Min(moveto, GetXLogReplayRecPtr(&ThisTimeLineID)); /* Acquire the slot so we "own" it */ - (void) ReplicationSlotAcquire(NameStr(*slotname), SAB_Error); + ReplicationSlotAcquire(NameStr(*slotname), true); /* A slot whose restart_lsn has never been reserved cannot be advanced */ if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn)) @@ -654,7 +656,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("replication slot \"%s\" cannot be advanced", NameStr(*slotname)), - errdetail("This slot has never previously reserved WAL, or has been invalidated."))); + errdetail("This slot has never previously reserved WAL, or it has been invalidated."))); /* * Check if the slot is not moving backwards. Physical slots rely simply @@ -671,8 +673,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("cannot advance replication slot to %X/%X, minimum is %X/%X", - (uint32) (moveto >> 32), (uint32) moveto, - (uint32) (minlsn >> 32), (uint32) minlsn))); + LSN_FORMAT_ARGS(moveto), LSN_FORMAT_ARGS(minlsn)))); /* Do the actual slot update, depending on the slot type */ if (OidIsValid(MyReplicationSlot->data.database)) @@ -809,6 +810,7 @@ copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot) create_logical_replication_slot(NameStr(*dst_name), plugin, temporary, + false, src_restart_lsn, false); } diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index d05851fa8789..2132237e3b19 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -63,7 +63,7 @@ * the standbys which are considered as synchronous at that moment * will release waiters from the queue. * - * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/syncrep.c @@ -160,6 +160,39 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit) const char *old_status; int mode; + /* + * This should be called while holding interrupts during a transaction + * commit to prevent the follow-up shared memory queue cleanups to be + * influenced by external interruptions. + */ + Assert(InterruptHoldoffCount > 0); + + /* + * Fast exit if user has not requested sync replication, or there are no + * sync replication standby names defined. + * + * Since this routine gets called every commit time, it's important to + * exit quickly if sync replication is not requested. So we check + * WalSndCtl->sync_standbys_defined flag without the lock and exit + * immediately if it's false. If it's true, we need to check it again + * later while holding the lock, to check the flag and operate the sync + * rep queue atomically. This is necessary to avoid the race condition + * described in SyncRepUpdateSyncStandbysDefined(). On the other hand, if + * it's false, the lock is not necessary because we don't touch the queue. + * + * GPDB: the coordinator's synchronous standby is not configured through + * synchronous_standby_names (so sync_standbys_defined is false for it); + * instead the QD decides synchronously below by looking for an active + * gp_walreceiver (see the IS_QUERY_DISPATCHER block). Therefore the QD + * must not take this sync_standbys_defined fast path -- doing so made + * coordinator commits never block on the standby. Segments keep the + * upstream behavior. (Mirrors the IS_QUERY_DISPATCHER guard further down.) + */ + if (!SyncRepRequested() || + (!IS_QUERY_DISPATCHER() && + !((volatile WalSndCtlData *) WalSndCtl)->sync_standbys_defined)) + return; + /* Cap the level for anything other than commit to remote flush only. */ if (commit) mode = SyncRepWaitMode; @@ -273,8 +306,8 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit) */ new_status = (char *) palloc(len + 32 + 12 + 1); memcpy(new_status, old_status, len); - sprintf(new_status + len, " waiting for %X/%X replication", - (uint32) (lsn >> 32), (uint32) lsn); + sprintf(new_status + len, " waiting for %X/%X", + LSN_FORMAT_ARGS(lsn)); set_ps_display(new_status); new_status[len] = '\0'; /* truncate off " waiting ..." */ } @@ -514,8 +547,8 @@ SyncRepInitConfig(void) SpinLockRelease(&MyWalSnd->mutex); ereport(DEBUG1, - (errmsg("standby \"%s\" now has synchronous standby priority %u", - application_name, priority))); + (errmsg_internal("standby \"%s\" now has synchronous standby priority %u", + application_name, priority))); } } @@ -622,11 +655,10 @@ SyncRepReleaseWaiters(void) LWLockRelease(SyncRepLock); - elogif(debug_walrepl_syncrep, LOG, - "released %d procs up to write %X/%X, %d procs up to flush %X/%X, %d procs up to apply %X/%X", - numwrite, (uint32) (writePtr >> 32), (uint32) writePtr, - numflush, (uint32) (flushPtr >> 32), (uint32) flushPtr, - numapply, (uint32) (applyPtr >> 32), (uint32) applyPtr); + elog(DEBUG3, "released %d procs up to write %X/%X, %d procs up to flush %X/%X, %d procs up to apply %X/%X", + numwrite, LSN_FORMAT_ARGS(writePtr), + numflush, LSN_FORMAT_ARGS(flushPtr), + numapply, LSN_FORMAT_ARGS(applyPtr)); } /* diff --git a/src/backend/replication/syncrep_gram.y b/src/backend/replication/syncrep_gram.y index 350195eff645..88d95f222862 100644 --- a/src/backend/replication/syncrep_gram.y +++ b/src/backend/replication/syncrep_gram.y @@ -3,7 +3,7 @@ * * syncrep_gram.y - Parser for synchronous_standby_names * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/syncrep_scanner.l b/src/backend/replication/syncrep_scanner.l index 6883f60e18ce..0491590d060b 100644 --- a/src/backend/replication/syncrep_scanner.l +++ b/src/backend/replication/syncrep_scanner.l @@ -4,7 +4,7 @@ * syncrep_scanner.l * a lexical scanner for synchronous_standby_names * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/test/gp_replication_test.c b/src/backend/replication/test/gp_replication_test.c index 1a7ae47ffe39..23d089d75881 100644 --- a/src/backend/replication/test/gp_replication_test.c +++ b/src/backend/replication/test/gp_replication_test.c @@ -40,10 +40,17 @@ expect_ereport() { expect_any(errstart, elevel); expect_any(errstart, domain); - will_be_called(errstart); } +static void +expect_ereport_cold() +{ + expect_any(errstart_cold, elevel); + expect_any(errstart_cold, domain); + will_be_called(errstart_cold); +} + static FTSReplicationStatusCtlData * test_setup(int pid, WalSndState state, int count) { diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index e1b4494b1e28..87fbdc3e5d66 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -39,7 +39,7 @@ * specific parts are in the libpqwalreceiver module. It's loaded * dynamically to avoid linking the server with libpq. * - * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -69,6 +69,7 @@ #include "replication/walsender.h" #include "storage/ipc.h" #include "storage/pmsignal.h" +#include "storage/proc.h" #include "storage/procarray.h" #include "storage/procsignal.h" #include "utils/acl.h" @@ -106,13 +107,6 @@ static int recvFile = -1; static TimeLineID recvFileTLI = 0; static XLogSegNo recvSegNo = 0; -/* - * Flags set by interrupt handlers of walreceiver for later service in the - * main loop. - */ -static volatile sig_atomic_t got_SIGHUP = false; -static volatile sig_atomic_t got_SIGTERM = false; - /* * LogstreamResult indicates the byte positions that we have already * written/fsynced. @@ -137,11 +131,6 @@ static void XLogWalRcvSendReply(bool force, bool requestReply); static void XLogWalRcvSendHSFeedback(bool immed); static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime); -/* Signal handlers */ -static void WalRcvSigHupHandler(SIGNAL_ARGS); -static void WalRcvShutdownHandler(SIGNAL_ARGS); - - /* * Process any interrupts the walreceiver process may have received. * This should be called any time the process's latch has become set. @@ -166,7 +155,7 @@ ProcessWalRcvInterrupts(void) */ CHECK_FOR_INTERRUPTS(); - if (got_SIGTERM) + if (ShutdownRequestPending) { ereport(FATAL, (errcode(ERRCODE_ADMIN_SHUTDOWN), @@ -221,6 +210,7 @@ WalReceiverMain(void) case WALRCV_STOPPED: SpinLockRelease(&walrcv->mutex); + ConditionVariableBroadcast(&walrcv->walRcvStoppedCV); proc_exit(1); break; @@ -267,16 +257,17 @@ WalReceiverMain(void) SpinLockRelease(&walrcv->mutex); - pg_atomic_init_u64(&WalRcv->writtenUpto, 0); + pg_atomic_write_u64(&WalRcv->writtenUpto, 0); /* Arrange to clean up at walreceiver exit */ on_shmem_exit(WalRcvDie, 0); /* Properly accept or ignore signals the postmaster might send us */ - pqsignal(SIGHUP, WalRcvSigHupHandler); /* set flag to read config file */ + pqsignal(SIGHUP, SignalHandlerForConfigReload); /* set flag to read config + * file */ pqsignal(SIGINT, SIG_IGN); - pqsignal(SIGTERM, WalRcvShutdownHandler); /* request shutdown */ - pqsignal(SIGQUIT, SignalHandlerForCrashExit); + pqsignal(SIGTERM, SignalHandlerForShutdownRequest); /* request shutdown */ + /* SIGQUIT handler was already set up by InitPostmasterChild */ pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); @@ -285,9 +276,6 @@ WalReceiverMain(void) /* Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - /* We allow SIGQUIT (quickdie) at all times */ - sigdelset(&BlockSig, SIGQUIT); - /* Load the libpq-specific functions */ libpqwalreceiver_PG_init(); if (WalReceiverFunctions == NULL) @@ -297,10 +285,13 @@ WalReceiverMain(void) PG_SETMASK(&UnBlockSig); /* Establish the connection to the primary for XLOG streaming */ - wrconn = walrcv_connect(conninfo, false, cluster_name[0] ? cluster_name : "walreceiver", &err); + wrconn = walrcv_connect(conninfo, false, + cluster_name[0] ? cluster_name : "walreceiver", + &err); if (!wrconn) ereport(ERROR, - (errmsg("could not connect to the primary server: %s", err))); + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("could not connect to the primary server: %s", err))); /* * Save user-visible connection string. This clobbers the original @@ -346,7 +337,8 @@ WalReceiverMain(void) if (strcmp(primary_sysid, standby_sysid) != 0) { ereport(ERROR, - (errmsg("database system identifier differs between the primary and standby"), + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("database system identifier differs between the primary and standby"), errdetail("The primary's identifier is %s, the standby's identifier is %s.", primary_sysid, standby_sysid))); } @@ -357,7 +349,8 @@ WalReceiverMain(void) */ if (primaryTLI < startpointTLI) ereport(ERROR, - (errmsg("highest timeline %u of the primary is behind recovery timeline %u", + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("highest timeline %u of the primary is behind recovery timeline %u", primaryTLI, startpointTLI))); /* @@ -412,13 +405,11 @@ WalReceiverMain(void) if (first_stream) ereport(LOG, (errmsg("started streaming WAL from primary at %X/%X on timeline %u", - (uint32) (startpoint >> 32), (uint32) startpoint, - startpointTLI))); + LSN_FORMAT_ARGS(startpoint), startpointTLI))); else ereport(LOG, (errmsg("restarted WAL streaming at %X/%X on timeline %u", - (uint32) (startpoint >> 32), (uint32) startpoint, - startpointTLI))); + LSN_FORMAT_ARGS(startpoint), startpointTLI))); first_stream = false; /* Initialize LogstreamResult and buffers for processing messages */ @@ -445,14 +436,15 @@ WalReceiverMain(void) */ if (!RecoveryInProgress()) ereport(FATAL, - (errmsg("cannot continue WAL streaming, recovery has already ended"))); + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot continue WAL streaming, recovery has already ended"))); /* Process any requests or signals received recently */ ProcessWalRcvInterrupts(); - if (got_SIGHUP) + if (ConfigReloadPending) { - got_SIGHUP = false; + ConfigReloadPending = false; ProcessConfigFile(PGC_SIGHUP); XLogWalRcvSendHSFeedback(true); } @@ -485,7 +477,7 @@ WalReceiverMain(void) (errmsg("replication terminated by primary server"), errdetail("End of WAL reached on timeline %u at %X/%X.", startpointTLI, - (uint32) (LogstreamResult.Write >> 32), (uint32) LogstreamResult.Write))); + LSN_FORMAT_ARGS(LogstreamResult.Write)))); endofwal = true; break; } @@ -519,7 +511,7 @@ WalReceiverMain(void) * avoiding some system calls. */ Assert(wait_fd != PGINVALID_SOCKET); - rc = WaitLatchOrSocket(walrcv->latch, + rc = WaitLatchOrSocket(MyLatch, WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE | WL_TIMEOUT | WL_LATCH_SET, wait_fd, @@ -527,7 +519,7 @@ WalReceiverMain(void) WAIT_EVENT_WAL_RECEIVER_MAIN); if (rc & WL_LATCH_SET) { - ResetLatch(walrcv->latch); + ResetLatch(MyLatch); ProcessWalRcvInterrupts(); if (walrcv->force_reply) @@ -557,7 +549,7 @@ WalReceiverMain(void) bool requestReply = false; /* - * Check if time since last receive from standby has + * Check if time since last receive from primary has * reached the configured limit. */ if (wal_receiver_timeout > 0) @@ -571,7 +563,8 @@ WalReceiverMain(void) if (now >= timeout) ereport(ERROR, - (errmsg("terminating walreceiver due to timeout"))); + (errcode(ERRCODE_CONNECTION_FAILURE), + errmsg("terminating walreceiver due to timeout"))); /* * We didn't receive anything new, for half of @@ -678,7 +671,7 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI) WakeupRecovery(); for (;;) { - ResetLatch(walrcv->latch); + ResetLatch(MyLatch); ProcessWalRcvInterrupts(); @@ -710,7 +703,7 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI) } SpinLockRelease(&walrcv->mutex); - (void) WaitLatch(walrcv->latch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, WAIT_EVENT_WAL_RECEIVER_WAIT_START); } @@ -719,8 +712,7 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI) char activitymsg[50]; snprintf(activitymsg, sizeof(activitymsg), "restarting at %X/%X", - (uint32) (*startpoint >> 32), - (uint32) *startpoint); + LSN_FORMAT_ARGS(*startpoint)); set_ps_display(activitymsg); } } @@ -767,6 +759,15 @@ WalRcvFetchTimeLineHistoryFiles(TimeLineID first, TimeLineID last) */ writeTimeLineHistoryFile(tli, content, len); + /* + * Mark the streamed history file as ready for archiving if + * archive_mode is always. + */ + if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS) + XLogArchiveForceDone(fname); + else + XLogArchiveNotify(fname); + pfree(fname); pfree(content); } @@ -798,6 +799,8 @@ WalRcvDie(int code, Datum arg) walrcv->latch = NULL; SpinLockRelease(&walrcv->mutex); + ConditionVariableBroadcast(&walrcv->walRcvStoppedCV); + /* Terminate the connection gracefully. */ if (wrconn != NULL) walrcv_disconnect(wrconn); @@ -806,28 +809,6 @@ WalRcvDie(int code, Datum arg) WakeupRecovery(); } -/* SIGHUP: set flag to re-read config file at next convenient time */ -static void -WalRcvSigHupHandler(SIGNAL_ARGS) -{ - got_SIGHUP = true; -} - - -/* SIGTERM: set flag for ProcessWalRcvInterrupts */ -static void -WalRcvShutdownHandler(SIGNAL_ARGS) -{ - int save_errno = errno; - - got_SIGTERM = true; - - if (WalRcv->latch) - SetLatch(WalRcv->latch); - - errno = save_errno; -} - /* * Accept the message from XLOG stream, and process it. */ @@ -1059,8 +1040,7 @@ XLogWalRcvFlush(bool dying) char activitymsg[50]; snprintf(activitymsg, sizeof(activitymsg), "streaming %X/%X", - (uint32) (LogstreamResult.Write >> 32), - (uint32) LogstreamResult.Write); + LSN_FORMAT_ARGS(LogstreamResult.Write)); set_ps_display(activitymsg); } @@ -1137,9 +1117,9 @@ XLogWalRcvSendReply(bool force, bool requestReply) /* Send it */ elog(DEBUG2, "sending write %X/%X flush %X/%X apply %X/%X%s", - (uint32) (writePtr >> 32), (uint32) writePtr, - (uint32) (flushPtr >> 32), (uint32) flushPtr, - (uint32) (applyPtr >> 32), (uint32) applyPtr, + LSN_FORMAT_ARGS(writePtr), + LSN_FORMAT_ARGS(flushPtr), + LSN_FORMAT_ARGS(applyPtr), requestReply ? " (reply requested)" : ""); walrcv_send(wrconn, reply_message.data, reply_message.len); @@ -1272,7 +1252,7 @@ ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime) walrcv->lastMsgReceiptTime = lastMsgReceiptTime; SpinLockRelease(&walrcv->mutex); - if (log_min_messages <= DEBUG2) + if (message_level_is_interesting(DEBUG2)) { char *sendtime; char *receipttime; @@ -1382,7 +1362,6 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) state = WalRcv->walRcvState; receive_start_lsn = WalRcv->receiveStart; receive_start_tli = WalRcv->receiveStartTLI; - written_lsn = pg_atomic_read_u64(&WalRcv->writtenUpto); flushed_lsn = WalRcv->flushedUpto; received_tli = WalRcv->receivedTLI; last_send_time = WalRcv->lastMsgSendTime; @@ -1402,6 +1381,14 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) if (pid == 0 || !ready_to_display) PG_RETURN_NULL(); + /* + * Read "writtenUpto" without holding a spinlock. Note that it may not be + * consistent with the other shared variables of the WAL receiver + * protected by a spinlock, but this should not be used for data integrity + * checks. + */ + written_lsn = pg_atomic_read_u64(&WalRcv->writtenUpto); + /* determine result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); @@ -1412,7 +1399,7 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) /* Fetch values */ values[0] = Int32GetDatum(pid); - if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS)) + if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS)) { /* * Only superusers and members of pg_read_all_stats can see details. diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c index d2512c5e56d9..dd71d5cd2f80 100644 --- a/src/backend/replication/walreceiverfuncs.c +++ b/src/backend/replication/walreceiverfuncs.c @@ -6,7 +6,7 @@ * with the walreceiver process. Functions implementing walreceiver itself * are in walreceiver.c. * - * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -23,6 +23,7 @@ #include #include "access/xlog_internal.h" +#include "pgstat.h" #include "postmaster/startup.h" #include "replication/walreceiver.h" #include "storage/pmsignal.h" @@ -67,7 +68,9 @@ WalRcvShmemInit(void) /* First time through, so initialize */ MemSet(WalRcv, 0, WalRcvShmemSize()); WalRcv->walRcvState = WALRCV_STOPPED; + ConditionVariableInit(&WalRcv->walRcvStoppedCV); SpinLockInit(&WalRcv->mutex); + pg_atomic_init_u64(&WalRcv->writtenUpto, 0); WalRcv->latch = NULL; *pm_launch_walreceiver = false; @@ -101,19 +104,23 @@ WalRcvRunning(void) if ((now - startTime) > WALRCV_STARTUP_TIMEOUT) { - SpinLockAcquire(&walrcv->mutex); + bool stopped = false; + SpinLockAcquire(&walrcv->mutex); if (walrcv->walRcvState == WALRCV_STARTING) { state = walrcv->walRcvState = WALRCV_STOPPED; + stopped = true; elogif(debug_xlog_record_read, LOG, "Set walreceiver state to %s as it has taken too" "long to start up", WalRcvGetStateString(walrcv->walRcvState)); } - SpinLockRelease(&walrcv->mutex); + + if (stopped) + ConditionVariableBroadcast(&walrcv->walRcvStoppedCV); } } @@ -153,12 +160,18 @@ WalRcvStreaming(void) if ((now - startTime) > WALRCV_STARTUP_TIMEOUT) { - SpinLockAcquire(&walrcv->mutex); + bool stopped = false; + SpinLockAcquire(&walrcv->mutex); if (walrcv->walRcvState == WALRCV_STARTING) + { state = walrcv->walRcvState = WALRCV_STOPPED; - + stopped = true; + } SpinLockRelease(&walrcv->mutex); + + if (stopped) + ConditionVariableBroadcast(&walrcv->walRcvStoppedCV); } } @@ -178,6 +191,7 @@ ShutdownWalRcv(void) { WalRcvData *walrcv = WalRcv; pid_t walrcvpid = 0; + bool stopped = false; elogif(debug_xlog_record_read, LOG, "walrcv shutdown -- Shutdown request with current walrcv state %s", @@ -195,6 +209,7 @@ ShutdownWalRcv(void) break; case WALRCV_STARTING: walrcv->walRcvState = WALRCV_STOPPED; + stopped = true; break; case WALRCV_STREAMING: @@ -208,6 +223,10 @@ ShutdownWalRcv(void) } SpinLockRelease(&walrcv->mutex); + /* Unnecessary but consistent. */ + if (stopped) + ConditionVariableBroadcast(&walrcv->walRcvStoppedCV); + /* * Signal walreceiver process if it was still running. */ @@ -218,20 +237,11 @@ ShutdownWalRcv(void) * Wait for walreceiver to acknowledge its death by setting state to * WALRCV_STOPPED. */ + ConditionVariablePrepareToSleep(&walrcv->walRcvStoppedCV); while (WalRcvRunning()) - { - /* - * This possibly-long loop needs to handle interrupts of startup - * process. - */ - HandleStartupProcInterrupts(); - - pg_usleep(100000); /* 100ms */ - } - - elogif(debug_xlog_record_read, LOG, - "walrcv shutdown -- Shutdown performed with current walrcv state %s", - WalRcvGetStateString(walrcv->walRcvState)); + ConditionVariableSleep(&walrcv->walRcvStoppedCV, + WAIT_EVENT_WAL_RECEIVER_EXIT); + ConditionVariableCancelSleep(); } /* @@ -372,10 +382,6 @@ GetReplicationApplyDelay(void) WalRcvData *walrcv = WalRcv; XLogRecPtr receivePtr; XLogRecPtr replayPtr; - - long secs; - int usecs; - TimestampTz chunkReplayStartTime; SpinLockAcquire(&walrcv->mutex); @@ -392,11 +398,8 @@ GetReplicationApplyDelay(void) if (chunkReplayStartTime == 0) return -1; - TimestampDifference(chunkReplayStartTime, - GetCurrentTimestamp(), - &secs, &usecs); - - return (((int) secs * 1000) + (usecs / 1000)); + return TimestampDifferenceMilliseconds(chunkReplayStartTime, + GetCurrentTimestamp()); } /* @@ -407,24 +410,14 @@ int GetReplicationTransferLatency(void) { WalRcvData *walrcv = WalRcv; - TimestampTz lastMsgSendTime; TimestampTz lastMsgReceiptTime; - long secs = 0; - int usecs = 0; - int ms; - SpinLockAcquire(&walrcv->mutex); lastMsgSendTime = walrcv->lastMsgSendTime; lastMsgReceiptTime = walrcv->lastMsgReceiptTime; SpinLockRelease(&walrcv->mutex); - TimestampDifference(lastMsgSendTime, - lastMsgReceiptTime, - &secs, &usecs); - - ms = ((int) secs * 1000) + (usecs / 1000); - - return ms; + return TimestampDifferenceMilliseconds(lastMsgSendTime, + lastMsgReceiptTime); } diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 0821c8575761..a9d1bac94641 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -40,7 +40,7 @@ * * Note - Currently only 1 walsender is supported for GPDB * - * Portions Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/walsender.c @@ -255,6 +255,7 @@ static void WalSndKeepalive(bool requestReply); static void WalSndKeepaliveIfNecessary(void); static void WalSndCheckTimeOut(void); static long WalSndComputeSleeptime(TimestampTz now); +static void WalSndWait(uint32 socket_events, long timeout, uint32 wait_event); static void WalSndPrepareWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write); static void WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write); static void WalSndUpdateProgress(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid); @@ -418,7 +419,7 @@ IdentifySystem(void) else logptr = GetFlushRecPtr(); - snprintf(xloc, sizeof(xloc), "%X/%X", (uint32) (logptr >> 32), (uint32) logptr); + snprintf(xloc, sizeof(xloc), "%X/%X", LSN_FORMAT_ARGS(logptr)); elogif(debug_walrepl_snd, LOG, "walsnd identifysystem -- " @@ -519,7 +520,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd) pq_sendstring(&buf, "content"); /* col name */ pq_sendint32(&buf, 0); /* table oid */ pq_sendint16(&buf, 0); /* attnum */ - pq_sendint32(&buf, BYTEAOID); /* type oid */ + pq_sendint32(&buf, TEXTOID); /* type oid */ pq_sendint16(&buf, -1); /* typlen */ pq_sendint32(&buf, 0); /* typmod */ pq_sendint16(&buf, 0); /* format code */ @@ -630,7 +631,7 @@ StartReplication(StartReplicationCmd *cmd) if (cmd->slotname) { - (void) ReplicationSlotAcquire(cmd->slotname, SAB_Error); + ReplicationSlotAcquire(cmd->slotname, true); if (SlotIsLogical(MyReplicationSlot)) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -704,13 +705,11 @@ StartReplication(StartReplicationCmd *cmd) { ereport(ERROR, (errmsg("requested starting point %X/%X on timeline %u is not in this server's history", - (uint32) (cmd->startpoint >> 32), - (uint32) (cmd->startpoint), + LSN_FORMAT_ARGS(cmd->startpoint), cmd->timeline), errdetail("This server's history forked from timeline %u at %X/%X.", cmd->timeline, - (uint32) (switchpoint >> 32), - (uint32) (switchpoint)))); + LSN_FORMAT_ARGS(switchpoint)))); } sendTimeLineValidUpto = switchpoint; } @@ -753,10 +752,8 @@ StartReplication(StartReplicationCmd *cmd) { ereport(ERROR, (errmsg("requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X", - (uint32) (cmd->startpoint >> 32), - (uint32) (cmd->startpoint), - (uint32) (FlushPtr >> 32), - (uint32) (FlushPtr)))); + LSN_FORMAT_ARGS(cmd->startpoint), + LSN_FORMAT_ARGS(FlushPtr)))); } /* Start streaming from the requested point */ @@ -799,8 +796,7 @@ StartReplication(StartReplicationCmd *cmd) bool nulls[2]; snprintf(startpos_str, sizeof(startpos_str), "%X/%X", - (uint32) (sendTimeLineValidUpto >> 32), - (uint32) sendTimeLineValidUpto); + LSN_FORMAT_ARGS(sendTimeLineValidUpto)); dest = CreateDestReceiver(DestRemoteSimple); MemSet(nulls, false, sizeof(nulls)); @@ -829,7 +825,7 @@ StartReplication(StartReplicationCmd *cmd) } /* Send CommandComplete message */ - pq_puttextmessage('C', "START_STREAMING"); + EndReplicationCommand("START_STREAMING"); } /* @@ -980,7 +976,8 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) if (cmd->kind == REPLICATION_KIND_PHYSICAL) { ReplicationSlotCreate(cmd->slotname, false, - cmd->temporary ? RS_TEMPORARY : RS_PERSISTENT); + cmd->temporary ? RS_TEMPORARY : RS_PERSISTENT, + false); } else { @@ -994,7 +991,8 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) * they get dropped on error as well. */ ReplicationSlotCreate(cmd->slotname, true, - cmd->temporary ? RS_TEMPORARY : RS_EPHEMERAL); + cmd->temporary ? RS_TEMPORARY : RS_EPHEMERAL, + false); } if (cmd->kind == REPLICATION_KIND_LOGICAL) @@ -1101,8 +1099,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) } snprintf(xloc, sizeof(xloc), "%X/%X", - (uint32) (MyReplicationSlot->data.confirmed_flush >> 32), - (uint32) MyReplicationSlot->data.confirmed_flush); + LSN_FORMAT_ARGS(MyReplicationSlot->data.confirmed_flush)); dest = CreateDestReceiver(DestRemoteSimple); MemSet(nulls, false, sizeof(nulls)); @@ -1160,11 +1157,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) static void DropReplicationSlot(DropReplicationSlotCmd *cmd) { - QueryCompletion qc; - ReplicationSlotDrop(cmd->slotname, !cmd->wait); - SetQueryCompletion(&qc, CMDTAG_DROP_REPLICATION_SLOT, 0); - EndCommand(&qc, DestRemote, false); } /* @@ -1182,7 +1175,7 @@ StartLogicalReplication(StartReplicationCmd *cmd) Assert(!MyReplicationSlot); - (void) ReplicationSlotAcquire(cmd->slotname, SAB_Error); + ReplicationSlotAcquire(cmd->slotname, true); if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn)) ereport(ERROR, @@ -1335,7 +1328,6 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, /* If we have pending write here, go to slow path */ for (;;) { - int wakeEvents; long sleeptime; /* Check for input from the client */ @@ -1352,13 +1344,9 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp()); - wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | - WL_SOCKET_WRITEABLE | WL_SOCKET_READABLE | WL_TIMEOUT; - /* Sleep until something happens or we time out */ - (void) WaitLatchOrSocket(MyLatch, wakeEvents, - MyProcPort->sock, sleeptime, - WAIT_EVENT_WAL_SENDER_WRITE_DATA); + WalSndWait(WL_SOCKET_WRITEABLE | WL_SOCKET_READABLE, sleeptime, + WAIT_EVENT_WAL_SENDER_WRITE_DATA); /* Clear any already-pending wakeups */ ResetLatch(MyLatch); @@ -1528,15 +1516,12 @@ WalSndWaitForWal(XLogRecPtr loc) */ sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp()); - wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | - WL_SOCKET_READABLE | WL_TIMEOUT; + wakeEvents = WL_SOCKET_READABLE; if (pq_is_send_pending()) wakeEvents |= WL_SOCKET_WRITEABLE; - (void) WaitLatchOrSocket(MyLatch, wakeEvents, - MyProcPort->sock, sleeptime, - WAIT_EVENT_WAL_SENDER_WAIT_WAL); + WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_WAIT_WAL); } /* reactivate latch so WalSndLoop knows to continue */ @@ -1555,9 +1540,9 @@ exec_replication_command(const char *cmd_string) { int parse_rc; Node *cmd_node; + const char *cmdtag; MemoryContext cmd_context; MemoryContext old_context; - QueryCompletion qc; /* * If WAL sender has been told that shutdown is getting close, switch its @@ -1583,6 +1568,9 @@ exec_replication_command(const char *cmd_string) CHECK_FOR_INTERRUPTS(); + /* + * Parse the command. + */ cmd_context = AllocSetContextCreate(CurrentMemoryContext, "Replication command context", ALLOCSET_DEFAULT_SIZES); @@ -1595,31 +1583,47 @@ exec_replication_command(const char *cmd_string) (errcode(ERRCODE_SYNTAX_ERROR), errmsg_internal("replication command parser returned %d", parse_rc))); + replication_scanner_finish(); cmd_node = replication_parse_result; /* - * Log replication command if log_replication_commands is enabled. Even - * when it's disabled, log the command with DEBUG1 level for backward - * compatibility. Note that SQL commands are not logged here, and will be - * logged later if log_statement is enabled. + * If it's a SQL command, just clean up our mess and return false; the + * caller will take care of executing it. + */ + if (IsA(cmd_node, SQLCmd)) + { + if (MyDatabaseId == InvalidOid) + ereport(ERROR, + (errmsg("cannot execute SQL commands in WAL sender for physical replication"))); + + MemoryContextSwitchTo(old_context); + MemoryContextDelete(cmd_context); + + /* Tell the caller that this wasn't a WalSender command. */ + return false; + } + + /* + * Report query to various monitoring facilities. For this purpose, we + * report replication commands just like SQL commands. */ - if (cmd_node->type != T_SQLCmd) - ereport(log_replication_commands ? LOG : DEBUG1, - (errmsg("received replication command: %s", cmd_string))); + debug_query_string = cmd_string; + + pgstat_report_activity(STATE_RUNNING, cmd_string); /* - * CREATE_REPLICATION_SLOT ... LOGICAL exports a snapshot. If it was - * called outside of transaction the snapshot should be cleared here. + * Log replication command if log_replication_commands is enabled. Even + * when it's disabled, log the command with DEBUG1 level for backward + * compatibility. */ - if (!IsTransactionBlock()) - SnapBuildClearExportedSnapshot(); + ereport(log_replication_commands ? LOG : DEBUG1, + (errmsg("received replication command: %s", cmd_string))); /* - * For aborted transactions, don't allow anything except pure SQL, the - * exec_simple_query() will handle it correctly. + * Disallow replication commands in aborted transaction blocks. */ - if (IsAbortedTransactionBlockState() && !IsA(cmd_node, SQLCmd)) + if (IsAbortedTransactionBlockState()) ereport(ERROR, (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION), errmsg("current transaction is aborted, " @@ -1635,46 +1639,63 @@ exec_replication_command(const char *cmd_string) initStringInfo(&reply_message); initStringInfo(&tmpbuf); - /* Report to pgstat that this process is running */ - pgstat_report_activity(STATE_RUNNING, NULL); - switch (cmd_node->type) { case T_IdentifySystemCmd: + cmdtag = "IDENTIFY_SYSTEM"; + set_ps_display(cmdtag); IdentifySystem(); + EndReplicationCommand(cmdtag); break; case T_BaseBackupCmd: - PreventInTransactionBlock(true, "BASE_BACKUP"); + cmdtag = "BASE_BACKUP"; + set_ps_display(cmdtag); + PreventInTransactionBlock(true, cmdtag); SendBaseBackup((BaseBackupCmd *) cmd_node); + EndReplicationCommand(cmdtag); break; case T_CreateReplicationSlotCmd: + cmdtag = "CREATE_REPLICATION_SLOT"; + set_ps_display(cmdtag); CreateReplicationSlot((CreateReplicationSlotCmd *) cmd_node); + EndReplicationCommand(cmdtag); break; case T_DropReplicationSlotCmd: + cmdtag = "DROP_REPLICATION_SLOT"; + set_ps_display(cmdtag); DropReplicationSlot((DropReplicationSlotCmd *) cmd_node); + EndReplicationCommand(cmdtag); break; case T_StartReplicationCmd: { StartReplicationCmd *cmd = (StartReplicationCmd *) cmd_node; - PreventInTransactionBlock(true, "START_REPLICATION"); + cmdtag = "START_REPLICATION"; + set_ps_display(cmdtag); + PreventInTransactionBlock(true, cmdtag); if (cmd->kind == REPLICATION_KIND_PHYSICAL) StartReplication(cmd); else StartLogicalReplication(cmd); + /* dupe, but necessary per libpqrcv_endstreaming */ + EndReplicationCommand(cmdtag); + Assert(xlogreader != NULL); break; } case T_TimeLineHistoryCmd: - PreventInTransactionBlock(true, "TIMELINE_HISTORY"); + cmdtag = "TIMELINE_HISTORY"; + set_ps_display(cmdtag); + PreventInTransactionBlock(true, cmdtag); SendTimeLineHistory((TimeLineHistoryCmd *) cmd_node); + EndReplicationCommand(cmdtag); break; case T_VariableShowStmt: @@ -1682,24 +1703,17 @@ exec_replication_command(const char *cmd_string) DestReceiver *dest = CreateDestReceiver(DestRemoteSimple); VariableShowStmt *n = (VariableShowStmt *) cmd_node; + cmdtag = "SHOW"; + set_ps_display(cmdtag); + /* syscache access needs a transaction environment */ StartTransactionCommand(); GetPGVariable(n->name, dest); CommitTransactionCommand(); + EndReplicationCommand(cmdtag); } break; - case T_SQLCmd: - if (MyDatabaseId == InvalidOid) - ereport(ERROR, - (errmsg("cannot execute SQL commands in WAL sender for physical replication"))); - - /* Report to pgstat that this process is now idle */ - pgstat_report_activity(STATE_IDLE, NULL); - - /* Tell the caller that this wasn't a WalSender command. */ - return false; - default: elog(ERROR, "unrecognized replication command node tag: %u", cmd_node->type); @@ -1709,12 +1723,12 @@ exec_replication_command(const char *cmd_string) MemoryContextSwitchTo(old_context); MemoryContextDelete(cmd_context); - /* Send CommandComplete message */ - SetQueryCompletion(&qc, CMDTAG_SELECT, 0); - EndCommand(&qc, DestRemote, true); - - /* Report to pgstat that this process is now idle */ - pgstat_report_activity(STATE_IDLE, NULL); + /* + * We need not update ps display or pg_stat_activity, because PostgresMain + * will reset those to "idle". But we must reset debug_query_string to + * ensure it doesn't become a dangling pointer. + */ + debug_query_string = NULL; return true; } @@ -1727,12 +1741,18 @@ static void ProcessRepliesIfAny(void) { unsigned char firstchar; + int maxmsglen; int r; bool received = false; last_processing = GetCurrentTimestamp(); - for (;;) + /* + * If we already received a CopyDone from the frontend, any subsequent + * message is the beginning of a new command, and should be processed in + * the main processing loop. + */ + while (!streamingDoneReceiving) { pq_startmsgread(); r = pq_getbyte_if_available(&firstchar); @@ -1751,9 +1771,28 @@ ProcessRepliesIfAny(void) break; } + /* Validate message type and set packet size limit */ + switch (firstchar) + { + case 'd': + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; + break; + case 'c': + case 'X': + maxmsglen = PQ_SMALL_MESSAGE_LIMIT; + break; + default: + ereport(FATAL, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("invalid standby message type \"%c\"", + firstchar))); + maxmsglen = 0; /* keep compiler quiet */ + break; + } + /* Read the message contents */ resetStringInfo(&reply_message); - if (pq_getmessage(&reply_message, 0)) + if (pq_getmessage(&reply_message, maxmsglen)) { ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), @@ -1761,20 +1800,7 @@ ProcessRepliesIfAny(void) proc_exit(0); } - /* - * If we already received a CopyDone from the frontend, the frontend - * should not send us anything until we've closed our end of the COPY. - * XXX: In theory, the frontend could already send the next command - * before receiving the CopyDone, but libpq doesn't currently allow - * that. - */ - if (streamingDoneReceiving && firstchar != 'X') - ereport(FATAL, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("unexpected standby message type \"%c\", after receiving CopyDone", - firstchar))); - - /* Handle the very limited subset of commands expected in this phase */ + /* ... and process it */ switch (firstchar) { /* @@ -1811,10 +1837,7 @@ ProcessRepliesIfAny(void) proc_exit(0); default: - ereport(FATAL, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid standby message type \"%c\"", - firstchar))); + Assert(false); /* NOT REACHED */ } } @@ -1917,7 +1940,7 @@ ProcessStandbyReplyMessage(void) replyTime = pq_getmsgint64(&reply_message); replyRequested = pq_getmsgbyte(&reply_message); - if (log_min_messages <= DEBUG2) + if (message_level_is_interesting(DEBUG2)) { char *replyTimeStr; @@ -1925,9 +1948,9 @@ ProcessStandbyReplyMessage(void) replyTimeStr = pstrdup(timestamptz_to_str(replyTime)); elog(DEBUG2, "write %X/%X flush %X/%X apply %X/%X%s reply_time %s", - (uint32) (writePtr >> 32), (uint32) writePtr, - (uint32) (flushPtr >> 32), (uint32) flushPtr, - (uint32) (applyPtr >> 32), (uint32) applyPtr, + LSN_FORMAT_ARGS(writePtr), + LSN_FORMAT_ARGS(flushPtr), + LSN_FORMAT_ARGS(applyPtr), replyRequested ? " (reply requested)" : "", replyTimeStr); @@ -2106,7 +2129,7 @@ ProcessStandbyHSFeedbackMessage(void) feedbackCatalogXmin = pq_getmsgint(&reply_message, 4); feedbackCatalogEpoch = pq_getmsgint(&reply_message, 4); - if (log_min_messages <= DEBUG2) + if (message_level_is_interesting(DEBUG2)) { char *replyTimeStr; @@ -2218,8 +2241,6 @@ WalSndComputeSleeptime(TimestampTz now) if (wal_sender_timeout > 0 && last_reply_timestamp > 0) { TimestampTz wakeup_time; - long sec_to_timeout; - int microsec_to_timeout; /* * At the latest stop sleeping once wal_sender_timeout has been @@ -2238,11 +2259,7 @@ WalSndComputeSleeptime(TimestampTz now) wal_sender_timeout / 2); /* Compute relative time until wakeup. */ - TimestampDifference(now, wakeup_time, - &sec_to_timeout, µsec_to_timeout); - - sleeptime = sec_to_timeout * 1000 + - microsec_to_timeout / 1000; + sleeptime = TimestampDifferenceMilliseconds(now, wakeup_time); } return sleeptime; @@ -2371,8 +2388,8 @@ WalSndLoop(WalSndSendDataCallback send_data) if (MyWalSnd->state == WALSNDSTATE_CATCHUP) { ereport(DEBUG1, - (errmsg("\"%s\" has now caught up with upstream server", - application_name))); + (errmsg_internal("\"%s\" has now caught up with upstream server", + application_name))); WalSndSetState(WALSNDSTATE_STREAMING); } @@ -2406,8 +2423,10 @@ WalSndLoop(WalSndSendDataCallback send_data) long sleeptime; int wakeEvents; - wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | WL_TIMEOUT | - WL_SOCKET_READABLE; + if (!streamingDoneReceiving) + wakeEvents = WL_SOCKET_READABLE; + else + wakeEvents = 0; /* * Use fresh timestamp, not last_processing, to reduce the chance @@ -2419,9 +2438,7 @@ WalSndLoop(WalSndSendDataCallback send_data) wakeEvents |= WL_SOCKET_WRITEABLE; /* Sleep until something happens or we time out */ - (void) WaitLatchOrSocket(MyLatch, wakeEvents, - MyProcPort->sock, sleeptime, - WAIT_EVENT_WAL_SENDER_MAIN); + WalSndWait(wakeEvents, sleeptime, WAIT_EVENT_WAL_SENDER_MAIN); } } } @@ -2582,7 +2599,7 @@ WalSndSegmentOpen(XLogReaderState *state, XLogSegNo nextSegNo, XLogSegNo endSegNo; XLByteToSeg(sendTimeLineValidUpto, endSegNo, state->segcxt.ws_segsize); - if (state->seg.ws_segno == endSegNo) + if (nextSegNo == endSegNo) *tli_p = sendTimeLineNextTLI; } @@ -2790,8 +2807,8 @@ XLogSendPhysical(void) WalSndCaughtUp = true; elog(DEBUG1, "walsender reached end of timeline at %X/%X (sent up to %X/%X)", - (uint32) (sendTimeLineValidUpto >> 32), (uint32) sendTimeLineValidUpto, - (uint32) (sentPtr >> 32), (uint32) sentPtr); + LSN_FORMAT_ARGS(sendTimeLineValidUpto), + LSN_FORMAT_ARGS(sentPtr)); return; } @@ -2941,7 +2958,7 @@ XLogSendPhysical(void) char activitymsg[50]; snprintf(activitymsg, sizeof(activitymsg), "streaming %X/%X", - (uint32) (sentPtr >> 32), (uint32) sentPtr); + LSN_FORMAT_ARGS(sentPtr)); set_ps_display(activitymsg); } @@ -3187,7 +3204,7 @@ WalSndSignals(void) pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, StatementCancelHandler); /* query cancel */ pqsignal(SIGTERM, die); /* request shutdown */ - pqsignal(SIGQUIT, quickdie); /* hard crash time */ + /* SIGQUIT handler was already set up by InitPostmasterChild */ InitializeTimeouts(); /* establishes SIGALRM handler */ pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); @@ -3277,6 +3294,22 @@ WalSndWakeup(void) } } +/* + * Wait for readiness on the FeBe socket, or a timeout. The mask should be + * composed of optional WL_SOCKET_WRITEABLE and WL_SOCKET_READABLE flags. Exit + * on postmaster death. + */ +static void +WalSndWait(uint32 socket_events, long timeout, uint32 wait_event) +{ + WaitEvent event; + + ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, socket_events, NULL); + if (WaitEventSetWait(FeBeWaitSet, timeout, &event, 1, wait_event) == 1 && + (event.events & WL_POSTMASTER_DEATH)) + proc_exit(1); +} + /* * Signal all walsenders to move to stopping state. * @@ -3663,7 +3696,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) memset(nulls, 0, sizeof(nulls)); values[0] = Int32GetDatum(pid); - if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS)) + if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS)) { /* * Only superusers and members of pg_read_all_stats can see diff --git a/src/backend/rewrite/Makefile b/src/backend/rewrite/Makefile index b435b3e985c0..4680752e6a7f 100644 --- a/src/backend/rewrite/Makefile +++ b/src/backend/rewrite/Makefile @@ -17,6 +17,7 @@ OBJS = \ rewriteHandler.o \ rewriteManip.o \ rewriteRemove.o \ + rewriteSearchCycle.o \ rewriteSupport.o \ rowsecurity.o diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index fbea979d4320..5462848256f6 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,9 +25,9 @@ #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/heap.h" -#include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/objectaccess.h" +#include "catalog/pg_inherits.h" #include "catalog/pg_rewrite.h" #include "catalog/storage.h" #include "commands/policy.h" @@ -445,13 +445,14 @@ DefineQueryRewrite(const char *rulename, * Are we converting a relation to a view? * * If so, check that the relation is empty because the storage for the - * relation is going to be deleted. Also insist that the rel not have - * any triggers, indexes, child tables, policies, or RLS enabled. - * (Note: these tests are too strict, because they will reject - * relations that once had such but don't anymore. But we don't - * really care, because this whole business of converting relations to - * views is just a kluge to allow dump/reload of views that - * participate in circular dependencies.) + * relation is going to be deleted. Also insist that the rel not be + * involved in partitioning, nor have any triggers, indexes, child or + * parent tables, RLS policies, or RLS enabled. (Note: some of these + * tests are too strict, because they will reject relations that once + * had such but don't anymore. But we don't really care, because this + * whole business of converting relations to views is just an obsolete + * kluge to allow dump/reload of views that participate in circular + * dependencies.) */ if (event_relation->rd_rel->relkind != RELKIND_VIEW && event_relation->rd_rel->relkind != RELKIND_MATVIEW) @@ -466,6 +467,9 @@ DefineQueryRewrite(const char *rulename, errmsg("cannot convert partitioned table \"%s\" to a view", RelationGetRelationName(event_relation)))); + /* only case left: */ + Assert(event_relation->rd_rel->relkind == RELKIND_RELATION); + if (event_relation->rd_rel->relispartition) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -516,6 +520,12 @@ DefineQueryRewrite(const char *rulename, errmsg("could not convert table \"%s\" to a view because it has child tables", RelationGetRelationName(event_relation)))); + if (has_superclass(RelationGetRelid(event_relation))) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("could not convert table \"%s\" to a view because it has parent tables", + RelationGetRelationName(event_relation)))); + if (event_relation->rd_rel->relrowsecurity) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -668,7 +678,7 @@ DefineQueryRewrite(const char *rulename, classForm->relam = InvalidOid; classForm->reltablespace = InvalidOid; classForm->relpages = 0; - classForm->reltuples = 0; + classForm->reltuples = -1; classForm->relallvisible = 0; classForm->reltoastrelid = InvalidOid; classForm->relhasindex = false; diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index e0f73f8d67c0..037725066439 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,6 +32,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "optimizer/optimizer.h" #include "parser/analyze.h" #include "parser/parse_coerce.h" #include "parser/parse_relation.h" @@ -39,6 +40,7 @@ #include "rewrite/rewriteDefine.h" #include "rewrite/rewriteHandler.h" #include "rewrite/rewriteManip.h" +#include "rewrite/rewriteSearchCycle.h" #include "rewrite/rowsecurity.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -72,13 +74,17 @@ static List *rewriteTargetListIU(List *targetList, CmdType commandType, OverridingKind override, Relation target_relation, - int result_rti); + RangeTblEntry *values_rte, + int values_rte_index, + Bitmapset **unused_values_attrnos); static TargetEntry *process_matched_tle(TargetEntry *src_tle, TargetEntry *prior_tle, const char *attrName); static Node *get_assignment_input(Node *node); +static Bitmapset *findDefaultOnlyColumns(RangeTblEntry *rte); static bool rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, - Relation target_relation, bool force_nulls); + Relation target_relation, bool force_nulls, + Bitmapset *unused_cols); static void markQueryForLocking(Query *qry, Node *jtnode, LockClauseStrength strength, LockWaitPolicy waitPolicy, bool pushedDown); @@ -706,11 +712,7 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index) if (IsA(rtr, RangeTblRef) && rtr->rtindex == rt_index) { - newjointree = list_delete_ptr(newjointree, rtr); - - /* - * foreach is safe because we exit loop after list_delete... - */ + newjointree = foreach_delete_current(newjointree, l); break; } } @@ -732,20 +734,7 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index) * and UPDATE, replace explicit DEFAULT specifications with column default * expressions. * - * 2. For an UPDATE on a trigger-updatable view, add tlist entries for any - * unassigned-to attributes, assigning them their old values. These will - * later get expanded to the output values of the view. (This is equivalent - * to what the planner's expand_targetlist() will do for UPDATE on a regular - * table, but it's more convenient to do it here while we still have easy - * access to the view's original RT index.) This is only necessary for - * trigger-updatable views, for which the view remains the result relation of - * the query. For auto-updatable views we must not do this, since it might - * add assignments to non-updatable view columns. For rule-updatable views it - * is unnecessary extra work, since the query will be rewritten with a - * different result relation which will be processed when we recurse via - * RewriteQuery. - * - * 3. Merge multiple entries for the same target attribute, or declare error + * 2. Merge multiple entries for the same target attribute, or declare error * if we can't. Multiple entries are only allowed for INSERT/UPDATE of * portions of an array or record field, for example * UPDATE table SET foo[2] = 42, foo[4] = 43; @@ -753,27 +742,31 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index) * the expression we want to produce in this case is like * foo = array_set_element(array_set_element(foo, 2, 42), 4, 43) * - * 4. Sort the tlist into standard order: non-junk fields in order by resno, + * 3. Sort the tlist into standard order: non-junk fields in order by resno, * then junk fields (these in no particular order). * - * We must do items 1,2,3 before firing rewrite rules, else rewritten - * references to NEW.foo will produce wrong or incomplete results. Item 4 - * is not needed for rewriting, but will be needed by the planner, and we + * We must do items 1 and 2 before firing rewrite rules, else rewritten + * references to NEW.foo will produce wrong or incomplete results. Item 3 + * is not needed for rewriting, but it is helpful for the planner, and we * can do it essentially for free while handling the other items. * - * Note that for an inheritable UPDATE, this processing is only done once, - * using the parent relation as reference. It must not do anything that - * will not be correct when transposed to the child relation(s). (Step 4 - * is incorrect by this light, since child relations might have different - * column ordering, but the planner will fix things by re-sorting the tlist - * for each child.) + * If values_rte is non-NULL (i.e., we are doing a multi-row INSERT using + * values from a VALUES RTE), we populate *unused_values_attrnos with the + * attribute numbers of any unused columns from the VALUES RTE. This can + * happen for identity and generated columns whose targetlist entries are + * replaced with generated expressions (if INSERT ... OVERRIDING USER VALUE is + * used, or all the values to be inserted are DEFAULT). This information is + * required by rewriteValuesRTE() to handle any DEFAULT items in the unused + * columns. The caller must have initialized *unused_values_attrnos to NULL. */ static List * rewriteTargetListIU(List *targetList, CmdType commandType, OverridingKind override, Relation target_relation, - int result_rti) + RangeTblEntry *values_rte, + int values_rte_index, + Bitmapset **unused_values_attrnos) { TargetEntry **new_tles; List *new_tlist = NIL; @@ -783,6 +776,7 @@ rewriteTargetListIU(List *targetList, next_junk_attrno, numattrs; ListCell *temp; + Bitmapset *default_only_cols = NULL; /* * We process the normal (non-junk) attributes by scanning the input tlist @@ -862,43 +856,122 @@ rewriteTargetListIU(List *targetList, if (commandType == CMD_INSERT) { + int values_attrno = 0; + + /* Source attribute number for values that come from a VALUES RTE */ + if (values_rte && new_tle && IsA(new_tle->expr, Var)) + { + Var *var = (Var *) new_tle->expr; + + if (var->varno == values_rte_index) + values_attrno = var->varattno; + } + + /* + * Can only insert DEFAULT into GENERATED ALWAYS identity columns, + * unless either OVERRIDING USER VALUE or OVERRIDING SYSTEM VALUE + * is specified. + */ if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS && !apply_default) { if (override == OVERRIDING_USER_VALUE) apply_default = true; else if (override != OVERRIDING_SYSTEM_VALUE) - ereport(ERROR, - (errcode(ERRCODE_GENERATED_ALWAYS), - errmsg("cannot insert into column \"%s\"", NameStr(att_tup->attname)), - errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.", - NameStr(att_tup->attname)), - errhint("Use OVERRIDING SYSTEM VALUE to override."))); + { + /* + * If this column's values come from a VALUES RTE, test + * whether it contains only SetToDefault items. Since the + * VALUES list might be quite large, we arrange to only + * scan it once. + */ + if (values_attrno != 0) + { + if (default_only_cols == NULL) + default_only_cols = findDefaultOnlyColumns(values_rte); + + if (bms_is_member(values_attrno, default_only_cols)) + apply_default = true; + } + + if (!apply_default) + ereport(ERROR, + (errcode(ERRCODE_GENERATED_ALWAYS), + errmsg("cannot insert a non-DEFAULT value into column \"%s\"", + NameStr(att_tup->attname)), + errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.", + NameStr(att_tup->attname)), + errhint("Use OVERRIDING SYSTEM VALUE to override."))); + } } - if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT && override == OVERRIDING_USER_VALUE) + /* + * Although inserting into a GENERATED BY DEFAULT identity column + * is allowed, apply the default if OVERRIDING USER VALUE is + * specified. + */ + if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT && + override == OVERRIDING_USER_VALUE) apply_default = true; + /* + * Can only insert DEFAULT into generated columns, regardless of + * any OVERRIDING clauses. + */ if (att_tup->attgenerated && !apply_default) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("cannot insert into column \"%s\"", NameStr(att_tup->attname)), - errdetail("Column \"%s\" is a generated column.", - NameStr(att_tup->attname)))); + { + /* + * If this column's values come from a VALUES RTE, test + * whether it contains only SetToDefault items, as above. + */ + if (values_attrno != 0) + { + if (default_only_cols == NULL) + default_only_cols = findDefaultOnlyColumns(values_rte); + + if (bms_is_member(values_attrno, default_only_cols)) + apply_default = true; + } + + if (!apply_default) + ereport(ERROR, + (errcode(ERRCODE_GENERATED_ALWAYS), + errmsg("cannot insert a non-DEFAULT value into column \"%s\"", + NameStr(att_tup->attname)), + errdetail("Column \"%s\" is a generated column.", + NameStr(att_tup->attname)))); + } + + /* + * For an INSERT from a VALUES RTE, return the attribute numbers + * of any VALUES columns that will no longer be used (due to the + * targetlist entry being replaced by a default expression). + */ + if (values_attrno != 0 && apply_default && unused_values_attrnos) + *unused_values_attrnos = bms_add_member(*unused_values_attrnos, + values_attrno); } + /* + * Updates to identity and generated columns follow the same rules as + * above, except that UPDATE doesn't admit OVERRIDING clauses. Also, + * the source can't be a VALUES RTE, so we needn't consider that. + */ if (commandType == CMD_UPDATE) { - if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS && new_tle && !apply_default) + if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS && + new_tle && !apply_default) ereport(ERROR, (errcode(ERRCODE_GENERATED_ALWAYS), - errmsg("column \"%s\" can only be updated to DEFAULT", NameStr(att_tup->attname)), + errmsg("column \"%s\" can only be updated to DEFAULT", + NameStr(att_tup->attname)), errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.", NameStr(att_tup->attname)))); if (att_tup->attgenerated && new_tle && !apply_default) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("column \"%s\" can only be updated to DEFAULT", NameStr(att_tup->attname)), + (errcode(ERRCODE_GENERATED_ALWAYS), + errmsg("column \"%s\" can only be updated to DEFAULT", + NameStr(att_tup->attname)), errdetail("Column \"%s\" is a generated column.", NameStr(att_tup->attname)))); } @@ -954,29 +1027,6 @@ rewriteTargetListIU(List *targetList, false); } - /* - * For an UPDATE on a trigger-updatable view, provide a dummy entry - * whenever there is no explicit assignment. - */ - if (new_tle == NULL && commandType == CMD_UPDATE && - target_relation->rd_rel->relkind == RELKIND_VIEW && - view_has_instead_trigger(target_relation, CMD_UPDATE)) - { - Node *new_expr; - - new_expr = (Node *) makeVar(result_rti, - attrno, - att_tup->atttypid, - att_tup->atttypmod, - att_tup->attcollation, - 0); - - new_tle = makeTargetEntry((Expr *) new_expr, - attrno, - pstrdup(NameStr(att_tup->attname)), - false); - } - if (new_tle) new_tlist = lappend(new_tlist, new_tle); } @@ -1196,25 +1246,28 @@ build_column_default(Relation rel, int attrno) } /* - * Scan to see if relation has a default for this column. + * If relation has a default for this column, fetch that expression. */ - if (att_tup->atthasdef && rd_att->constr && - rd_att->constr->num_defval > 0) + if (att_tup->atthasdef) { - AttrDefault *defval = rd_att->constr->defval; - int ndef = rd_att->constr->num_defval; - - while (--ndef >= 0) + if (rd_att->constr && rd_att->constr->num_defval > 0) { - if (attrno == defval[ndef].adnum) + AttrDefault *defval = rd_att->constr->defval; + int ndef = rd_att->constr->num_defval; + + while (--ndef >= 0) { - /* - * Found it, convert string representation to node tree. - */ - expr = stringToNode(defval[ndef].adbin); - break; + if (attrno == defval[ndef].adnum) + { + /* Found it, convert string representation to node tree. */ + expr = stringToNode(defval[ndef].adbin); + break; + } } } + if (expr == NULL) + elog(ERROR, "default expression not found for attribute %d of relation \"%s\"", + attrno, RelationGetRelationName(rel)); } /* @@ -1278,6 +1331,62 @@ searchForDefault(RangeTblEntry *rte) return false; } + +/* + * Search a VALUES RTE for columns that contain only SetToDefault items, + * returning a Bitmapset containing the attribute numbers of any such columns. + */ +static Bitmapset * +findDefaultOnlyColumns(RangeTblEntry *rte) +{ + Bitmapset *default_only_cols = NULL; + ListCell *lc; + + foreach(lc, rte->values_lists) + { + List *sublist = (List *) lfirst(lc); + ListCell *lc2; + int i; + + if (default_only_cols == NULL) + { + /* Populate the initial result bitmap from the first row */ + i = 0; + foreach(lc2, sublist) + { + Node *col = (Node *) lfirst(lc2); + + i++; + if (IsA(col, SetToDefault)) + default_only_cols = bms_add_member(default_only_cols, i); + } + } + else + { + /* Update the result bitmap from this next row */ + i = 0; + foreach(lc2, sublist) + { + Node *col = (Node *) lfirst(lc2); + + i++; + if (!IsA(col, SetToDefault)) + default_only_cols = bms_del_member(default_only_cols, i); + } + } + + /* + * If no column in the rows read so far contains only DEFAULT items, + * we are done. + */ + if (bms_is_empty(default_only_cols)) + break; + } + + return default_only_cols; +} + + /* * When processing INSERT ... VALUES with a VALUES RTE (ie, multiple VALUES * lists), we have to replace any DEFAULT items in the VALUES lists with @@ -1305,19 +1414,31 @@ searchForDefault(RangeTblEntry *rte) * an insert into an auto-updatable view, and the product queries are inserts * into a rule-updatable view. * + * Finally, if a DEFAULT item is found in a column mentioned in unused_cols, + * it is explicitly set to NULL. This happens for columns in the VALUES RTE + * whose corresponding targetlist entries have already been replaced with the + * relation's default expressions, so that any values in those columns of the + * VALUES RTE are no longer used. This can happen for identity and generated + * columns (if INSERT ... OVERRIDING USER VALUE is used, or all the values to + * be inserted are DEFAULT). In principle we could replace all entries in + * such a column with NULL, whether DEFAULT or not; but it doesn't seem worth + * the trouble. + * * Note that we may have subscripted or field assignment targetlist entries, * as well as more complex expressions from already-replaced DEFAULT items if * we have recursed to here for an auto-updatable view. However, it ought to - * be impossible for such entries to have DEFAULTs assigned to them --- we - * should only have to replace DEFAULT items for targetlist entries that - * contain simple Vars referencing the VALUES RTE. + * be impossible for such entries to have DEFAULTs assigned to them, except + * for unused columns, as described above --- we should only have to replace + * DEFAULT items for targetlist entries that contain simple Vars referencing + * the VALUES RTE, or which are no longer referred to by the targetlist. * * Returns true if all DEFAULT items were replaced, and false if some were * left untouched. */ static bool rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, - Relation target_relation, bool force_nulls) + Relation target_relation, bool force_nulls, + Bitmapset *unused_cols) { List *newValues; ListCell *lc; @@ -1341,8 +1462,8 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, * Scan the targetlist for entries referring to the VALUES RTE, and note * the target attributes. As noted above, we should only need to do this * for targetlist entries containing simple Vars --- nothing else in the - * VALUES RTE should contain DEFAULT items, and we complain if such a - * thing does occur. + * VALUES RTE should contain DEFAULT items (except possibly for unused + * columns), and we complain if such a thing does occur. */ numattrs = list_length(linitial(rte->values_lists)); attrnos = (int *) palloc0(numattrs * sizeof(int)); @@ -1429,6 +1550,22 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, Form_pg_attribute att_tup; Node *new_expr; + /* + * If this column isn't used, just replace the DEFAULT with + * NULL (attrno will be 0 in this case because the targetlist + * entry will have been replaced by the default expression). + */ + if (bms_is_member(i, unused_cols)) + { + SetToDefault *def = (SetToDefault *) col; + + newList = lappend(newList, + makeNullConst(def->typeId, + def->typeMod, + def->collation)); + continue; + } + if (attrno == 0) elog(ERROR, "cannot set value in column %d to DEFAULT", i); att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1); @@ -1485,138 +1622,38 @@ rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, /* - * rewriteTargetListUD - rewrite UPDATE/DELETE targetlist as needed - * - * This function adds a "junk" TLE that is needed to allow the executor to - * find the original row for the update or delete. When the target relation - * is a regular table, the junk TLE emits the ctid attribute of the original - * row. When the target relation is a foreign table, we let the FDW decide - * what to add. - * - * We used to do this during RewriteQuery(), but now that inheritance trees - * can contain a mix of regular and foreign tables, we must postpone it till - * planning, after the inheritance tree has been expanded. In that way we - * can do the right thing for each child table. + * Record in target_rte->extraUpdatedCols the indexes of any generated columns + * that depend on any columns mentioned in target_rte->updatedCols. */ void -rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte, - Relation target_relation) +fill_extraUpdatedCols(RangeTblEntry *target_rte, Relation target_relation) { - Var *var = NULL; - const char *attrname; - TargetEntry *tle; - Var *varSegid = NULL; - - if (target_relation->rd_rel->relkind == RELKIND_RELATION || - target_relation->rd_rel->relkind == RELKIND_MATVIEW || - target_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE || - IsAppendonlyMetadataRelkind(target_relation->rd_rel->relkind)) - { - /* - * Emit CTID so that executor can find the row to update or delete. - */ - var = makeVar(parsetree->resultRelation, - SelfItemPointerAttributeNumber, - TIDOID, - -1, - InvalidOid, - 0); + TupleDesc tupdesc = RelationGetDescr(target_relation); + TupleConstr *constr = tupdesc->constr; - attrname = "ctid"; + target_rte->extraUpdatedCols = NULL; - /* - * GPDB also needs gp_segment_id. ctid is only unique in the same - * segment. - */ - { - Oid reloid; - Oid vartypeid; - int32 type_mod; - Oid type_coll; - - reloid = RelationGetRelid(target_relation); - get_atttypetypmodcoll(reloid, GpSegmentIdAttributeNumber, &vartypeid, &type_mod, &type_coll); - varSegid = makeVar(parsetree->resultRelation, - GpSegmentIdAttributeNumber, - vartypeid, - type_mod, - type_coll, - 0); - } - } - else if (target_relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + if (constr && constr->has_generated_stored) { - /* - * Let the foreign table's FDW add whatever junk TLEs it wants. - */ - FdwRoutine *fdwroutine; - - fdwroutine = GetFdwRoutineForRelation(target_relation, false); - - if (fdwroutine->AddForeignUpdateTargets != NULL) - fdwroutine->AddForeignUpdateTargets(parsetree, target_rte, - target_relation); - - /* - * If we have a row-level trigger corresponding to the operation, emit - * a whole-row Var so that executor will have the "old" row to pass to - * the trigger. Alas, this misses system columns. - */ - if (target_relation->trigdesc && - ((parsetree->commandType == CMD_UPDATE && - (target_relation->trigdesc->trig_update_after_row || - target_relation->trigdesc->trig_update_before_row)) || - (parsetree->commandType == CMD_DELETE && - (target_relation->trigdesc->trig_delete_after_row || - target_relation->trigdesc->trig_delete_before_row)))) + for (int i = 0; i < constr->num_defval; i++) { - var = makeWholeRowVar(target_rte, - parsetree->resultRelation, - 0, - false); - - attrname = "wholerow"; - - /* - * GPDB also needs gp_segment_id. ctid is only unique in the same - * segment. - */ - { - Oid reloid; - Oid vartypeid; - int32 type_mod; - Oid type_coll; - - reloid = RelationGetRelid(target_relation); - get_atttypetypmodcoll(reloid, GpSegmentIdAttributeNumber, &vartypeid, &type_mod, &type_coll); - varSegid = makeVar(parsetree->resultRelation, - GpSegmentIdAttributeNumber, - vartypeid, - type_mod, - type_coll, - 0); - } - } - } + AttrDefault *defval = &constr->defval[i]; + Node *expr; + Bitmapset *attrs_used = NULL; - if (var != NULL) - { - tle = makeTargetEntry((Expr *) var, - list_length(parsetree->targetList) + 1, - pstrdup(attrname), - true); - - parsetree->targetList = lappend(parsetree->targetList, tle); - } + /* skip if not generated column */ + if (!TupleDescAttr(tupdesc, defval->adnum - 1)->attgenerated) + continue; - if (varSegid) - { - tle = makeTargetEntry((Expr *) varSegid, - list_length(parsetree->targetList) + 1, /* resno */ - pstrdup("gp_segment_id"), /* resname */ - true); /* resjunk */ + /* identify columns this generated column depends on */ + expr = stringToNode(defval->adbin); + pull_varattnos(expr, 1, &attrs_used); - parsetree->targetList = lappend(parsetree->targetList, tle); + if (bms_overlap(target_rte->updatedCols, attrs_used)) + target_rte->extraUpdatedCols = + bms_add_member(target_rte->extraUpdatedCols, + defval->adnum - FirstLowInvalidHeapAttributeNumber); + } } } @@ -1751,6 +1788,7 @@ ApplyRetrieveRule(Query *parsetree, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * For the most part, Vars referencing the view should remain as @@ -1972,6 +2010,23 @@ fireRIRrules(Query *parsetree, List *activeRIRs) int rt_index; ListCell *lc; + /* + * Expand SEARCH and CYCLE clauses in CTEs. + * + * This is just a convenient place to do this, since we are already + * looking at each Query. + */ + foreach(lc, parsetree->cteList) + { + CommonTableExpr *cte = lfirst_node(CommonTableExpr, lc); + + if (cte->search_clause || cte->cycle_clause) + { + cte = rewriteSearchAndCycle(cte); + lfirst(lc) = cte; + } + } + /* * don't try to convert this into a foreach loop, because rtable list can * get changed each time through... @@ -2126,7 +2181,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs) QTW_IGNORE_RC_SUBQUERIES); /* - * Apply any row level security policies. We do this last because it + * Apply any row-level security policies. We do this last because it * requires special recursion detection if the new quals have sublink * subqueries, and if we did it in the loop above query_tree_walker would * then recurse into those quals a second time. @@ -2216,7 +2271,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs) } /* - * Make sure the query is marked correctly if row level security + * Make sure the query is marked correctly if row-level security * applies, or if the new quals had sublinks. */ if (hasRowSecurity) @@ -3693,15 +3748,20 @@ RewriteQuery(Query *parsetree, List *rewrite_events) if (values_rte) { + Bitmapset *unused_values_attrnos = NULL; + /* Process the main targetlist ... */ parsetree->targetList = rewriteTargetListIU(parsetree->targetList, parsetree->commandType, parsetree->override, rt_entry_relation, - parsetree->resultRelation); + values_rte, + values_rte_index, + &unused_values_attrnos); /* ... and the VALUES expression lists */ if (!rewriteValuesRTE(parsetree, values_rte, values_rte_index, - rt_entry_relation, false)) + rt_entry_relation, false, + unused_values_attrnos)) defaults_remaining = true; } else @@ -3712,7 +3772,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events) parsetree->commandType, parsetree->override, rt_entry_relation, - parsetree->resultRelation); + NULL, 0, NULL); } if (parsetree->onConflict && @@ -3723,7 +3783,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events) CMD_UPDATE, parsetree->override, rt_entry_relation, - parsetree->resultRelation); + NULL, 0, NULL); } } else if (event == CMD_UPDATE) @@ -3733,7 +3793,10 @@ RewriteQuery(Query *parsetree, List *rewrite_events) parsetree->commandType, parsetree->override, rt_entry_relation, - parsetree->resultRelation); + NULL, 0, NULL); + + /* Also populate extraUpdatedCols (for generated columns) */ + fill_extraUpdatedCols(rt_entry, rt_entry_relation); } else if (event == CMD_DELETE) { @@ -3780,7 +3843,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events) rewriteValuesRTE(pt, values_rte, values_rte_index, rt_entry_relation, - true); /* Force remaining defaults to NULL */ + true, /* Force remaining defaults to NULL */ + NULL); } } diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index c73ff2295f8e..50a641945d60 100644 --- a/src/backend/rewrite/rewriteManip.c +++ b/src/backend/rewrite/rewriteManip.c @@ -4,7 +4,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c index a24303fd00c6..a48b15e249da 100644 --- a/src/backend/rewrite/rewriteRemove.c +++ b/src/backend/rewrite/rewriteRemove.c @@ -3,7 +3,7 @@ * rewriteRemove.c * routines for removing rewrite rules * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/rewrite/rewriteSearchCycle.c b/src/backend/rewrite/rewriteSearchCycle.c new file mode 100644 index 000000000000..599fe8e73529 --- /dev/null +++ b/src/backend/rewrite/rewriteSearchCycle.c @@ -0,0 +1,668 @@ +/*------------------------------------------------------------------------- + * + * rewriteSearchCycle.c + * Support for rewriting SEARCH and CYCLE clauses. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/rewrite/rewriteSearchCycle.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "catalog/pg_operator_d.h" +#include "catalog/pg_type_d.h" +#include "nodes/makefuncs.h" +#include "nodes/pg_list.h" +#include "nodes/parsenodes.h" +#include "nodes/primnodes.h" +#include "parser/analyze.h" +#include "parser/parsetree.h" +#include "rewrite/rewriteManip.h" +#include "rewrite/rewriteSearchCycle.h" +#include "utils/fmgroids.h" + + +/*---------- + * Rewrite a CTE with SEARCH or CYCLE clause + * + * Consider a CTE like + * + * WITH RECURSIVE ctename (col1, col2, col3) AS ( + * query1 + * UNION [ALL] + * SELECT trosl FROM ctename + * ) + * + * With a search clause + * + * SEARCH BREADTH FIRST BY col1, col2 SET sqc + * + * the CTE is rewritten to + * + * WITH RECURSIVE ctename (col1, col2, col3, sqc) AS ( + * SELECT col1, col2, col3, -- original WITH column list + * ROW(0, col1, col2) -- initial row of search columns + * FROM (query1) "*TLOCRN*" (col1, col2, col3) + * UNION [ALL] + * SELECT col1, col2, col3, -- same as above + * ROW(sqc.depth + 1, col1, col2) -- count depth + * FROM (SELECT trosl, ctename.sqc FROM ctename) "*TROCRN*" (col1, col2, col3, sqc) + * ) + * + * (This isn't quite legal SQL: sqc.depth is meant to refer to the first + * column of sqc, which has a row type, but the field names are not defined + * here. Representing this properly in SQL would be more complicated (and the + * SQL standard actually does it in that more complicated way), but the + * internal representation allows us to construct it this way.) + * + * With a search clause + * + * SEARCH DEPTH FIRST BY col1, col2 SET sqc + * + * the CTE is rewritten to + * + * WITH RECURSIVE ctename (col1, col2, col3, sqc) AS ( + * SELECT col1, col2, col3, -- original WITH column list + * ARRAY[ROW(col1, col2)] -- initial row of search columns + * FROM (query1) "*TLOCRN*" (col1, col2, col3) + * UNION [ALL] + * SELECT col1, col2, col3, -- same as above + * sqc || ARRAY[ROW(col1, col2)] -- record rows seen + * FROM (SELECT trosl, ctename.sqc FROM ctename) "*TROCRN*" (col1, col2, col3, sqc) + * ) + * + * With a cycle clause + * + * CYCLE col1, col2 SET cmc TO 'Y' DEFAULT 'N' USING cpa + * + * (cmc = cycle mark column, cpa = cycle path) the CTE is rewritten to + * + * WITH RECURSIVE ctename (col1, col2, col3, cmc, cpa) AS ( + * SELECT col1, col2, col3, -- original WITH column list + * 'N', -- cycle mark default + * ARRAY[ROW(col1, col2)] -- initial row of cycle columns + * FROM (query1) "*TLOCRN*" (col1, col2, col3) + * UNION [ALL] + * SELECT col1, col2, col3, -- same as above + * CASE WHEN ROW(col1, col2) = ANY (ARRAY[cpa]) THEN 'Y' ELSE 'N' END, -- compute cycle mark column + * cpa || ARRAY[ROW(col1, col2)] -- record rows seen + * FROM (SELECT trosl, ctename.cmc, ctename.cpa FROM ctename) "*TROCRN*" (col1, col2, col3, cmc, cpa) + * WHERE cmc <> 'Y' + * ) + * + * The expression to compute the cycle mark column in the right-hand query is + * written as + * + * CASE WHEN ROW(col1, col2) IN (SELECT p.* FROM TABLE(cpa) p) THEN cmv ELSE cmd END + * + * in the SQL standard, but in PostgreSQL we can use the scalar-array operator + * expression shown above. + * + * Also, in some of the cases where operators are shown above we actually + * directly produce the underlying function call. + * + * If both a search clause and a cycle clause is specified, then the search + * clause column is added before the cycle clause columns. + */ + +/* + * Make a RowExpr from the specified column names, which have to be among the + * output columns of the CTE. + */ +static RowExpr * +make_path_rowexpr(const CommonTableExpr *cte, const List *col_list) +{ + RowExpr *rowexpr; + ListCell *lc; + + rowexpr = makeNode(RowExpr); + rowexpr->row_typeid = RECORDOID; + rowexpr->row_format = COERCE_IMPLICIT_CAST; + rowexpr->location = -1; + + foreach(lc, col_list) + { + char *colname = strVal(lfirst(lc)); + + for (int i = 0; i < list_length(cte->ctecolnames); i++) + { + char *colname2 = strVal(list_nth(cte->ctecolnames, i)); + + if (strcmp(colname, colname2) == 0) + { + Var *var; + + var = makeVar(1, i + 1, + list_nth_oid(cte->ctecoltypes, i), + list_nth_int(cte->ctecoltypmods, i), + list_nth_oid(cte->ctecolcollations, i), + 0); + rowexpr->args = lappend(rowexpr->args, var); + rowexpr->colnames = lappend(rowexpr->colnames, makeString(colname)); + break; + } + } + } + + return rowexpr; +} + +/* + * Wrap a RowExpr in an ArrayExpr, for the initial search depth first or cycle + * row. + */ +static Expr * +make_path_initial_array(RowExpr *rowexpr) +{ + ArrayExpr *arr; + + arr = makeNode(ArrayExpr); + arr->array_typeid = RECORDARRAYOID; + arr->element_typeid = RECORDOID; + arr->location = -1; + arr->elements = list_make1(rowexpr); + + return (Expr *) arr; +} + +/* + * Make an array catenation expression like + * + * cpa || ARRAY[ROW(cols)] + * + * where the varattno of cpa is provided as path_varattno. + */ +static Expr * +make_path_cat_expr(RowExpr *rowexpr, AttrNumber path_varattno) +{ + ArrayExpr *arr; + FuncExpr *fexpr; + + arr = makeNode(ArrayExpr); + arr->array_typeid = RECORDARRAYOID; + arr->element_typeid = RECORDOID; + arr->location = -1; + arr->elements = list_make1(rowexpr); + + fexpr = makeFuncExpr(F_ARRAY_CAT, RECORDARRAYOID, + list_make2(makeVar(1, path_varattno, RECORDARRAYOID, -1, 0, 0), + arr), + InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL); + + return (Expr *) fexpr; +} + +/* + * The real work happens here. + */ +CommonTableExpr * +rewriteSearchAndCycle(CommonTableExpr *cte) +{ + Query *ctequery; + SetOperationStmt *sos; + int rti1, + rti2; + RangeTblEntry *rte1, + *rte2, + *newrte; + Query *newq1, + *newq2; + Query *newsubquery; + RangeTblRef *rtr; + Oid search_seq_type = InvalidOid; + AttrNumber sqc_attno = InvalidAttrNumber; + AttrNumber cmc_attno = InvalidAttrNumber; + AttrNumber cpa_attno = InvalidAttrNumber; + TargetEntry *tle; + RowExpr *cycle_col_rowexpr = NULL; + RowExpr *search_col_rowexpr = NULL; + List *ewcl; + int cte_rtindex = -1; + + Assert(cte->search_clause || cte->cycle_clause); + + cte = copyObject(cte); + + ctequery = castNode(Query, cte->ctequery); + + /* + * The top level of the CTE's query should be a UNION. Find the two + * subqueries. + */ + Assert(ctequery->setOperations); + sos = castNode(SetOperationStmt, ctequery->setOperations); + Assert(sos->op == SETOP_UNION); + + rti1 = castNode(RangeTblRef, sos->larg)->rtindex; + rti2 = castNode(RangeTblRef, sos->rarg)->rtindex; + + rte1 = rt_fetch(rti1, ctequery->rtable); + rte2 = rt_fetch(rti2, ctequery->rtable); + + Assert(rte1->rtekind == RTE_SUBQUERY); + Assert(rte2->rtekind == RTE_SUBQUERY); + + /* + * We'll need this a few times later. + */ + if (cte->search_clause) + { + if (cte->search_clause->search_breadth_first) + search_seq_type = RECORDOID; + else + search_seq_type = RECORDARRAYOID; + } + + /* + * Attribute numbers of the added columns in the CTE's column list + */ + if (cte->search_clause) + sqc_attno = list_length(cte->ctecolnames) + 1; + if (cte->cycle_clause) + { + cmc_attno = list_length(cte->ctecolnames) + 1; + cpa_attno = list_length(cte->ctecolnames) + 2; + if (cte->search_clause) + { + cmc_attno++; + cpa_attno++; + } + } + + /* + * Make new left subquery + */ + newq1 = makeNode(Query); + newq1->commandType = CMD_SELECT; + newq1->canSetTag = true; + + newrte = makeNode(RangeTblEntry); + newrte->rtekind = RTE_SUBQUERY; + newrte->alias = makeAlias("*TLOCRN*", cte->ctecolnames); + newrte->eref = newrte->alias; + newsubquery = copyObject(rte1->subquery); + IncrementVarSublevelsUp((Node *) newsubquery, 1, 1); + newrte->subquery = newsubquery; + newrte->inFromCl = true; + newq1->rtable = list_make1(newrte); + + rtr = makeNode(RangeTblRef); + rtr->rtindex = 1; + newq1->jointree = makeFromExpr(list_make1(rtr), NULL); + + /* + * Make target list + */ + for (int i = 0; i < list_length(cte->ctecolnames); i++) + { + Var *var; + + var = makeVar(1, i + 1, + list_nth_oid(cte->ctecoltypes, i), + list_nth_int(cte->ctecoltypmods, i), + list_nth_oid(cte->ctecolcollations, i), + 0); + tle = makeTargetEntry((Expr *) var, i + 1, strVal(list_nth(cte->ctecolnames, i)), false); + tle->resorigtbl = castNode(TargetEntry, list_nth(rte1->subquery->targetList, i))->resorigtbl; + tle->resorigcol = castNode(TargetEntry, list_nth(rte1->subquery->targetList, i))->resorigcol; + newq1->targetList = lappend(newq1->targetList, tle); + } + + if (cte->search_clause) + { + Expr *texpr; + + search_col_rowexpr = make_path_rowexpr(cte, cte->search_clause->search_col_list); + if (cte->search_clause->search_breadth_first) + { + search_col_rowexpr->args = lcons(makeConst(INT8OID, -1, InvalidOid, sizeof(int64), + Int64GetDatum(0), false, FLOAT8PASSBYVAL), + search_col_rowexpr->args); + search_col_rowexpr->colnames = lcons(makeString("*DEPTH*"), search_col_rowexpr->colnames); + texpr = (Expr *) search_col_rowexpr; + } + else + texpr = make_path_initial_array(search_col_rowexpr); + tle = makeTargetEntry(texpr, + list_length(newq1->targetList) + 1, + cte->search_clause->search_seq_column, + false); + newq1->targetList = lappend(newq1->targetList, tle); + } + if (cte->cycle_clause) + { + tle = makeTargetEntry((Expr *) cte->cycle_clause->cycle_mark_default, + list_length(newq1->targetList) + 1, + cte->cycle_clause->cycle_mark_column, + false); + newq1->targetList = lappend(newq1->targetList, tle); + cycle_col_rowexpr = make_path_rowexpr(cte, cte->cycle_clause->cycle_col_list); + tle = makeTargetEntry(make_path_initial_array(cycle_col_rowexpr), + list_length(newq1->targetList) + 1, + cte->cycle_clause->cycle_path_column, + false); + newq1->targetList = lappend(newq1->targetList, tle); + } + + rte1->subquery = newq1; + + if (cte->search_clause) + { + rte1->eref->colnames = lappend(rte1->eref->colnames, makeString(cte->search_clause->search_seq_column)); + } + if (cte->cycle_clause) + { + rte1->eref->colnames = lappend(rte1->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column)); + rte1->eref->colnames = lappend(rte1->eref->colnames, makeString(cte->cycle_clause->cycle_path_column)); + } + + /* + * Make new right subquery + */ + newq2 = makeNode(Query); + newq2->commandType = CMD_SELECT; + newq2->canSetTag = true; + + newrte = makeNode(RangeTblEntry); + newrte->rtekind = RTE_SUBQUERY; + ewcl = copyObject(cte->ctecolnames); + if (cte->search_clause) + { + ewcl = lappend(ewcl, makeString(cte->search_clause->search_seq_column)); + } + if (cte->cycle_clause) + { + ewcl = lappend(ewcl, makeString(cte->cycle_clause->cycle_mark_column)); + ewcl = lappend(ewcl, makeString(cte->cycle_clause->cycle_path_column)); + } + newrte->alias = makeAlias("*TROCRN*", ewcl); + newrte->eref = newrte->alias; + + /* + * Find the reference to our CTE in the range table + */ + for (int rti = 1; rti <= list_length(rte2->subquery->rtable); rti++) + { + RangeTblEntry *e = rt_fetch(rti, rte2->subquery->rtable); + + if (e->rtekind == RTE_CTE && strcmp(cte->ctename, e->ctename) == 0) + { + cte_rtindex = rti; + break; + } + } + Assert(cte_rtindex > 0); + + newsubquery = copyObject(rte2->subquery); + IncrementVarSublevelsUp((Node *) newsubquery, 1, 1); + + /* + * Add extra columns to target list of subquery of right subquery + */ + if (cte->search_clause) + { + Var *var; + + /* ctename.sqc */ + var = makeVar(cte_rtindex, sqc_attno, + search_seq_type, -1, InvalidOid, 0); + tle = makeTargetEntry((Expr *) var, + list_length(newsubquery->targetList) + 1, + cte->search_clause->search_seq_column, + false); + newsubquery->targetList = lappend(newsubquery->targetList, tle); + } + if (cte->cycle_clause) + { + Var *var; + + /* ctename.cmc */ + var = makeVar(cte_rtindex, cmc_attno, + cte->cycle_clause->cycle_mark_type, + cte->cycle_clause->cycle_mark_typmod, + cte->cycle_clause->cycle_mark_collation, 0); + tle = makeTargetEntry((Expr *) var, + list_length(newsubquery->targetList) + 1, + cte->cycle_clause->cycle_mark_column, + false); + newsubquery->targetList = lappend(newsubquery->targetList, tle); + + /* ctename.cpa */ + var = makeVar(cte_rtindex, cpa_attno, + RECORDARRAYOID, -1, InvalidOid, 0); + tle = makeTargetEntry((Expr *) var, + list_length(newsubquery->targetList) + 1, + cte->cycle_clause->cycle_path_column, + false); + newsubquery->targetList = lappend(newsubquery->targetList, tle); + } + + newrte->subquery = newsubquery; + newrte->inFromCl = true; + newq2->rtable = list_make1(newrte); + + rtr = makeNode(RangeTblRef); + rtr->rtindex = 1; + + if (cte->cycle_clause) + { + Expr *expr; + + /* + * Add cmc <> cmv condition + */ + expr = make_opclause(cte->cycle_clause->cycle_mark_neop, BOOLOID, false, + (Expr *) makeVar(1, cmc_attno, + cte->cycle_clause->cycle_mark_type, + cte->cycle_clause->cycle_mark_typmod, + cte->cycle_clause->cycle_mark_collation, 0), + (Expr *) cte->cycle_clause->cycle_mark_value, + InvalidOid, + cte->cycle_clause->cycle_mark_collation); + + newq2->jointree = makeFromExpr(list_make1(rtr), (Node *) expr); + } + else + newq2->jointree = makeFromExpr(list_make1(rtr), NULL); + + /* + * Make target list + */ + for (int i = 0; i < list_length(cte->ctecolnames); i++) + { + Var *var; + + var = makeVar(1, i + 1, + list_nth_oid(cte->ctecoltypes, i), + list_nth_int(cte->ctecoltypmods, i), + list_nth_oid(cte->ctecolcollations, i), + 0); + tle = makeTargetEntry((Expr *) var, i + 1, strVal(list_nth(cte->ctecolnames, i)), false); + tle->resorigtbl = castNode(TargetEntry, list_nth(rte2->subquery->targetList, i))->resorigtbl; + tle->resorigcol = castNode(TargetEntry, list_nth(rte2->subquery->targetList, i))->resorigcol; + newq2->targetList = lappend(newq2->targetList, tle); + } + + if (cte->search_clause) + { + Expr *texpr; + + if (cte->search_clause->search_breadth_first) + { + FieldSelect *fs; + FuncExpr *fexpr; + + /* + * ROW(sqc.depth + 1, cols) + */ + + search_col_rowexpr = copyObject(search_col_rowexpr); + + fs = makeNode(FieldSelect); + fs->arg = (Expr *) makeVar(1, sqc_attno, RECORDOID, -1, 0, 0); + fs->fieldnum = 1; + fs->resulttype = INT8OID; + fs->resulttypmod = -1; + + fexpr = makeFuncExpr(F_INT8INC, INT8OID, list_make1(fs), InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL); + + lfirst(list_head(search_col_rowexpr->args)) = fexpr; + + texpr = (Expr *) search_col_rowexpr; + } + else + { + /* + * sqc || ARRAY[ROW(cols)] + */ + texpr = make_path_cat_expr(search_col_rowexpr, sqc_attno); + } + tle = makeTargetEntry(texpr, + list_length(newq2->targetList) + 1, + cte->search_clause->search_seq_column, + false); + newq2->targetList = lappend(newq2->targetList, tle); + } + + if (cte->cycle_clause) + { + ScalarArrayOpExpr *saoe; + CaseExpr *caseexpr; + CaseWhen *casewhen; + + /* + * CASE WHEN ROW(cols) = ANY (ARRAY[cpa]) THEN cmv ELSE cmd END + */ + + saoe = makeNode(ScalarArrayOpExpr); + saoe->location = -1; + saoe->opno = RECORD_EQ_OP; + saoe->useOr = true; + saoe->args = list_make2(cycle_col_rowexpr, + makeVar(1, cpa_attno, RECORDARRAYOID, -1, 0, 0)); + + caseexpr = makeNode(CaseExpr); + caseexpr->location = -1; + caseexpr->casetype = cte->cycle_clause->cycle_mark_type; + caseexpr->casecollid = cte->cycle_clause->cycle_mark_collation; + casewhen = makeNode(CaseWhen); + casewhen->location = -1; + casewhen->expr = (Expr *) saoe; + casewhen->result = (Expr *) cte->cycle_clause->cycle_mark_value; + caseexpr->args = list_make1(casewhen); + caseexpr->defresult = (Expr *) cte->cycle_clause->cycle_mark_default; + + tle = makeTargetEntry((Expr *) caseexpr, + list_length(newq2->targetList) + 1, + cte->cycle_clause->cycle_mark_column, + false); + newq2->targetList = lappend(newq2->targetList, tle); + + /* + * cpa || ARRAY[ROW(cols)] + */ + tle = makeTargetEntry(make_path_cat_expr(cycle_col_rowexpr, cpa_attno), + list_length(newq2->targetList) + 1, + cte->cycle_clause->cycle_path_column, + false); + newq2->targetList = lappend(newq2->targetList, tle); + } + + rte2->subquery = newq2; + + if (cte->search_clause) + { + rte2->eref->colnames = lappend(rte2->eref->colnames, makeString(cte->search_clause->search_seq_column)); + } + if (cte->cycle_clause) + { + rte2->eref->colnames = lappend(rte2->eref->colnames, makeString(cte->cycle_clause->cycle_mark_column)); + rte2->eref->colnames = lappend(rte2->eref->colnames, makeString(cte->cycle_clause->cycle_path_column)); + } + + /* + * Add the additional columns to the SetOperationStmt + */ + if (cte->search_clause) + { + sos->colTypes = lappend_oid(sos->colTypes, search_seq_type); + sos->colTypmods = lappend_int(sos->colTypmods, -1); + sos->colCollations = lappend_oid(sos->colCollations, InvalidOid); + if (!sos->all) + sos->groupClauses = lappend(sos->groupClauses, + makeSortGroupClauseForSetOp(search_seq_type)); + } + if (cte->cycle_clause) + { + sos->colTypes = lappend_oid(sos->colTypes, cte->cycle_clause->cycle_mark_type); + sos->colTypmods = lappend_int(sos->colTypmods, cte->cycle_clause->cycle_mark_typmod); + sos->colCollations = lappend_oid(sos->colCollations, cte->cycle_clause->cycle_mark_collation); + if (!sos->all) + sos->groupClauses = lappend(sos->groupClauses, + makeSortGroupClauseForSetOp(cte->cycle_clause->cycle_mark_type)); + + sos->colTypes = lappend_oid(sos->colTypes, RECORDARRAYOID); + sos->colTypmods = lappend_int(sos->colTypmods, -1); + sos->colCollations = lappend_oid(sos->colCollations, InvalidOid); + if (!sos->all) + sos->groupClauses = lappend(sos->groupClauses, + makeSortGroupClauseForSetOp(RECORDARRAYOID)); + } + + /* + * Add the additional columns to the CTE query's target list + */ + if (cte->search_clause) + { + ctequery->targetList = lappend(ctequery->targetList, + makeTargetEntry((Expr *) makeVar(1, sqc_attno, + search_seq_type, -1, InvalidOid, 0), + list_length(ctequery->targetList) + 1, + cte->search_clause->search_seq_column, + false)); + } + if (cte->cycle_clause) + { + ctequery->targetList = lappend(ctequery->targetList, + makeTargetEntry((Expr *) makeVar(1, cmc_attno, + cte->cycle_clause->cycle_mark_type, + cte->cycle_clause->cycle_mark_typmod, + cte->cycle_clause->cycle_mark_collation, 0), + list_length(ctequery->targetList) + 1, + cte->cycle_clause->cycle_mark_column, + false)); + ctequery->targetList = lappend(ctequery->targetList, + makeTargetEntry((Expr *) makeVar(1, cpa_attno, + RECORDARRAYOID, -1, InvalidOid, 0), + list_length(ctequery->targetList) + 1, + cte->cycle_clause->cycle_path_column, + false)); + } + + /* + * Add the additional columns to the CTE's output columns + */ + cte->ctecolnames = ewcl; + if (cte->search_clause) + { + cte->ctecoltypes = lappend_oid(cte->ctecoltypes, search_seq_type); + cte->ctecoltypmods = lappend_int(cte->ctecoltypmods, -1); + cte->ctecolcollations = lappend_oid(cte->ctecolcollations, InvalidOid); + } + if (cte->cycle_clause) + { + cte->ctecoltypes = lappend_oid(cte->ctecoltypes, cte->cycle_clause->cycle_mark_type); + cte->ctecoltypmods = lappend_int(cte->ctecoltypmods, cte->cycle_clause->cycle_mark_typmod); + cte->ctecolcollations = lappend_oid(cte->ctecolcollations, cte->cycle_clause->cycle_mark_collation); + + cte->ctecoltypes = lappend_oid(cte->ctecoltypes, RECORDARRAYOID); + cte->ctecoltypmods = lappend_int(cte->ctecoltypmods, -1); + cte->ctecolcollations = lappend_oid(cte->ctecolcollations, InvalidOid); + } + + return cte; +} diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c index fc9a3b1ebf66..85f1ac953ad1 100644 --- a/src/backend/rewrite/rewriteSupport.c +++ b/src/backend/rewrite/rewriteSupport.c @@ -3,7 +3,7 @@ * rewriteSupport.c * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c index 0fe2f9ca8388..e10f94904e1a 100644 --- a/src/backend/rewrite/rowsecurity.c +++ b/src/backend/rewrite/rowsecurity.c @@ -1,6 +1,6 @@ /* * rewrite/rowsecurity.c - * Routines to support policies for row level security (aka RLS). + * Routines to support policies for row-level security (aka RLS). * * Policies in PostgreSQL provide a mechanism to limit what records are * returned to a user and what records a user is permitted to add to a table. @@ -29,7 +29,7 @@ * in the current environment, but that may change if the row_security GUC or * the current role changes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California */ #include "postgres.h" @@ -100,7 +100,7 @@ row_security_policy_hook_type row_security_policy_hook_restrictive = NULL; * Get any row security quals and WithCheckOption checks that should be * applied to the specified RTE. * - * In addition, hasRowSecurity is set to true if row level security is enabled + * In addition, hasRowSecurity is set to true if row-level security is enabled * (even if this RTE doesn't have any row security quals), and hasSubLinks is * set to true if any of the quals returned contain sublinks. */ diff --git a/src/backend/snowball/Makefile b/src/backend/snowball/Makefile index ad8482cdd1a7..50b9199910c5 100644 --- a/src/backend/snowball/Makefile +++ b/src/backend/snowball/Makefile @@ -43,6 +43,7 @@ OBJS += \ stem_ISO_8859_2_romanian.o \ stem_KOI8_R_russian.o \ stem_UTF_8_arabic.o \ + stem_UTF_8_armenian.o \ stem_UTF_8_basque.o \ stem_UTF_8_catalan.o \ stem_UTF_8_danish.o \ @@ -64,10 +65,12 @@ OBJS += \ stem_UTF_8_portuguese.o \ stem_UTF_8_romanian.o \ stem_UTF_8_russian.o \ + stem_UTF_8_serbian.o \ stem_UTF_8_spanish.o \ stem_UTF_8_swedish.o \ stem_UTF_8_tamil.o \ - stem_UTF_8_turkish.o + stem_UTF_8_turkish.o \ + stem_UTF_8_yiddish.o # first column is language name and also name of dictionary for not-all-ASCII # words, second is name of dictionary for all-ASCII words @@ -75,6 +78,7 @@ OBJS += \ # must come after creation of that language LANGUAGES= \ arabic arabic \ + armenian armenian \ basque basque \ catalan catalan \ danish danish \ @@ -95,10 +99,12 @@ LANGUAGES= \ portuguese portuguese \ romanian romanian \ russian english \ + serbian serbian \ spanish spanish \ swedish swedish \ tamil tamil \ - turkish turkish + turkish turkish \ + yiddish yiddish SQLSCRIPT= snowball_create.sql diff --git a/src/backend/snowball/README b/src/backend/snowball/README index 6948c28b69f3..d83321bad439 100644 --- a/src/backend/snowball/README +++ b/src/backend/snowball/README @@ -29,8 +29,8 @@ We choose to include the derived files in the PostgreSQL distribution because most installations will not have the Snowball compiler available. We are currently synced with the Snowball git commit -c70ed64f9d41c1032fba4e962b054f8e9d489a74 (tag v2.0.0) -of 2019-10-02. +4764395431c8f2a0b4fe18b816ab1fc966a45837 (tag v2.1.0) +of 2021-01-21. To update the PostgreSQL sources from a new Snowball version: @@ -59,7 +59,8 @@ do not require any changes. 4. Check whether any stemmer modules have been added or removed. If so, edit the OBJS list in Makefile, the list of #include's in dict_snowball.c, and the -stemmer_modules[] table in dict_snowball.c. You might also need to change +stemmer_modules[] table in dict_snowball.c, as well as the list in the +documentation in textsearch.sgml. You might also need to change the LANGUAGES list in Makefile and tsearch_config_languages in initdb.c. 5. The various stopword files in stopwords/ must be downloaded diff --git a/src/backend/snowball/dict_snowball.c b/src/backend/snowball/dict_snowball.c index 4e1aceee0257..8c25f3ebbf2f 100644 --- a/src/backend/snowball/dict_snowball.c +++ b/src/backend/snowball/dict_snowball.c @@ -3,7 +3,7 @@ * dict_snowball.c * Snowball dictionary * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/snowball/dict_snowball.c @@ -46,6 +46,7 @@ #include "snowball/libstemmer/stem_ISO_8859_2_romanian.h" #include "snowball/libstemmer/stem_KOI8_R_russian.h" #include "snowball/libstemmer/stem_UTF_8_arabic.h" +#include "snowball/libstemmer/stem_UTF_8_armenian.h" #include "snowball/libstemmer/stem_UTF_8_basque.h" #include "snowball/libstemmer/stem_UTF_8_catalan.h" #include "snowball/libstemmer/stem_UTF_8_danish.h" @@ -67,10 +68,12 @@ #include "snowball/libstemmer/stem_UTF_8_portuguese.h" #include "snowball/libstemmer/stem_UTF_8_romanian.h" #include "snowball/libstemmer/stem_UTF_8_russian.h" +#include "snowball/libstemmer/stem_UTF_8_serbian.h" #include "snowball/libstemmer/stem_UTF_8_spanish.h" #include "snowball/libstemmer/stem_UTF_8_swedish.h" #include "snowball/libstemmer/stem_UTF_8_tamil.h" #include "snowball/libstemmer/stem_UTF_8_turkish.h" +#include "snowball/libstemmer/stem_UTF_8_yiddish.h" PG_MODULE_MAGIC; @@ -117,6 +120,7 @@ static const stemmer_module stemmer_modules[] = STEMMER_MODULE(romanian, PG_LATIN2, ISO_8859_2), STEMMER_MODULE(russian, PG_KOI8R, KOI8_R), STEMMER_MODULE(arabic, PG_UTF8, UTF_8), + STEMMER_MODULE(armenian, PG_UTF8, UTF_8), STEMMER_MODULE(basque, PG_UTF8, UTF_8), STEMMER_MODULE(catalan, PG_UTF8, UTF_8), STEMMER_MODULE(danish, PG_UTF8, UTF_8), @@ -138,10 +142,12 @@ static const stemmer_module stemmer_modules[] = STEMMER_MODULE(portuguese, PG_UTF8, UTF_8), STEMMER_MODULE(romanian, PG_UTF8, UTF_8), STEMMER_MODULE(russian, PG_UTF8, UTF_8), + STEMMER_MODULE(serbian, PG_UTF8, UTF_8), STEMMER_MODULE(spanish, PG_UTF8, UTF_8), STEMMER_MODULE(swedish, PG_UTF8, UTF_8), STEMMER_MODULE(tamil, PG_UTF8, UTF_8), STEMMER_MODULE(turkish, PG_UTF8, UTF_8), + STEMMER_MODULE(yiddish, PG_UTF8, UTF_8), /* * Stemmer with PG_SQL_ASCII encoding should be valid for any server diff --git a/src/backend/snowball/libstemmer/api.c b/src/backend/snowball/libstemmer/api.c index 8dd32df3d429..375938e6d13f 100644 --- a/src/backend/snowball/libstemmer/api.c +++ b/src/backend/snowball/libstemmer/api.c @@ -1,6 +1,6 @@ #include "header.h" -extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size) +extern struct SN_env * SN_create_env(int S_size, int I_size) { struct SN_env * z = (struct SN_env *) calloc(1, sizeof(struct SN_env)); if (z == NULL) return NULL; @@ -25,12 +25,6 @@ extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size) if (z->I == NULL) goto error; } - if (B_size) - { - z->B = (unsigned char *) calloc(B_size, sizeof(unsigned char)); - if (z->B == NULL) goto error; - } - return z; error: SN_close_env(z, S_size); @@ -50,7 +44,6 @@ extern void SN_close_env(struct SN_env * z, int S_size) free(z->S); } free(z->I); - free(z->B); if (z->p) lose_s(z->p); free(z); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_basque.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_basque.c index 7f080d8e84ce..994ac234bb23 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_basque.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_basque.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -140,115 +140,115 @@ static const symbol s_0_108[5] = { 'k', 'a', 'i', 't', 'z' }; static const struct among a_0[109] = { -/* 0 */ { 4, s_0_0, -1, 1, 0}, -/* 1 */ { 5, s_0_1, 0, 1, 0}, -/* 2 */ { 5, s_0_2, 0, 1, 0}, -/* 3 */ { 5, s_0_3, 0, 1, 0}, -/* 4 */ { 6, s_0_4, -1, 1, 0}, -/* 5 */ { 5, s_0_5, -1, 1, 0}, -/* 6 */ { 6, s_0_6, -1, 1, 0}, -/* 7 */ { 7, s_0_7, -1, 1, 0}, -/* 8 */ { 5, s_0_8, -1, 1, 0}, -/* 9 */ { 5, s_0_9, -1, 1, 0}, -/* 10 */ { 5, s_0_10, -1, 1, 0}, -/* 11 */ { 4, s_0_11, -1, 1, 0}, -/* 12 */ { 5, s_0_12, -1, 1, 0}, -/* 13 */ { 6, s_0_13, 12, 1, 0}, -/* 14 */ { 5, s_0_14, -1, 1, 0}, -/* 15 */ { 6, s_0_15, -1, 2, 0}, -/* 16 */ { 6, s_0_16, -1, 1, 0}, -/* 17 */ { 2, s_0_17, -1, 1, 0}, -/* 18 */ { 5, s_0_18, 17, 1, 0}, -/* 19 */ { 2, s_0_19, -1, 1, 0}, -/* 20 */ { 4, s_0_20, -1, 1, 0}, -/* 21 */ { 4, s_0_21, -1, 1, 0}, -/* 22 */ { 4, s_0_22, -1, 1, 0}, -/* 23 */ { 5, s_0_23, -1, 1, 0}, -/* 24 */ { 6, s_0_24, 23, 1, 0}, -/* 25 */ { 4, s_0_25, -1, 1, 0}, -/* 26 */ { 4, s_0_26, -1, 1, 0}, -/* 27 */ { 6, s_0_27, -1, 1, 0}, -/* 28 */ { 3, s_0_28, -1, 1, 0}, -/* 29 */ { 4, s_0_29, 28, 1, 0}, -/* 30 */ { 7, s_0_30, 29, 4, 0}, -/* 31 */ { 4, s_0_31, 28, 1, 0}, -/* 32 */ { 4, s_0_32, 28, 1, 0}, -/* 33 */ { 4, s_0_33, -1, 1, 0}, -/* 34 */ { 5, s_0_34, 33, 1, 0}, -/* 35 */ { 4, s_0_35, -1, 1, 0}, -/* 36 */ { 4, s_0_36, -1, 1, 0}, -/* 37 */ { 4, s_0_37, -1, 1, 0}, -/* 38 */ { 4, s_0_38, -1, 1, 0}, -/* 39 */ { 3, s_0_39, -1, 1, 0}, -/* 40 */ { 4, s_0_40, 39, 1, 0}, -/* 41 */ { 6, s_0_41, -1, 1, 0}, -/* 42 */ { 3, s_0_42, -1, 1, 0}, -/* 43 */ { 6, s_0_43, 42, 1, 0}, -/* 44 */ { 3, s_0_44, -1, 2, 0}, -/* 45 */ { 6, s_0_45, 44, 1, 0}, -/* 46 */ { 6, s_0_46, 44, 1, 0}, -/* 47 */ { 6, s_0_47, 44, 1, 0}, -/* 48 */ { 3, s_0_48, -1, 1, 0}, -/* 49 */ { 4, s_0_49, 48, 1, 0}, -/* 50 */ { 4, s_0_50, 48, 1, 0}, -/* 51 */ { 4, s_0_51, 48, 1, 0}, -/* 52 */ { 5, s_0_52, -1, 1, 0}, -/* 53 */ { 5, s_0_53, -1, 1, 0}, -/* 54 */ { 5, s_0_54, -1, 1, 0}, -/* 55 */ { 2, s_0_55, -1, 1, 0}, -/* 56 */ { 4, s_0_56, 55, 1, 0}, -/* 57 */ { 5, s_0_57, 55, 1, 0}, -/* 58 */ { 6, s_0_58, 55, 1, 0}, -/* 59 */ { 4, s_0_59, -1, 1, 0}, -/* 60 */ { 4, s_0_60, -1, 1, 0}, -/* 61 */ { 3, s_0_61, -1, 1, 0}, -/* 62 */ { 4, s_0_62, 61, 1, 0}, -/* 63 */ { 3, s_0_63, -1, 1, 0}, -/* 64 */ { 4, s_0_64, -1, 1, 0}, -/* 65 */ { 5, s_0_65, 64, 1, 0}, -/* 66 */ { 2, s_0_66, -1, 1, 0}, -/* 67 */ { 3, s_0_67, -1, 1, 0}, -/* 68 */ { 4, s_0_68, 67, 1, 0}, -/* 69 */ { 4, s_0_69, 67, 1, 0}, -/* 70 */ { 4, s_0_70, 67, 1, 0}, -/* 71 */ { 5, s_0_71, 70, 1, 0}, -/* 72 */ { 5, s_0_72, -1, 2, 0}, -/* 73 */ { 5, s_0_73, -1, 1, 0}, -/* 74 */ { 5, s_0_74, -1, 1, 0}, -/* 75 */ { 6, s_0_75, 74, 1, 0}, -/* 76 */ { 2, s_0_76, -1, 1, 0}, -/* 77 */ { 3, s_0_77, 76, 1, 0}, -/* 78 */ { 4, s_0_78, 77, 1, 0}, -/* 79 */ { 3, s_0_79, 76, 1, 0}, -/* 80 */ { 4, s_0_80, 76, 1, 0}, -/* 81 */ { 7, s_0_81, -1, 3, 0}, -/* 82 */ { 3, s_0_82, -1, 1, 0}, -/* 83 */ { 3, s_0_83, -1, 1, 0}, -/* 84 */ { 3, s_0_84, -1, 1, 0}, -/* 85 */ { 5, s_0_85, 84, 1, 0}, -/* 86 */ { 4, s_0_86, -1, 1, 0}, -/* 87 */ { 5, s_0_87, 86, 1, 0}, -/* 88 */ { 3, s_0_88, -1, 1, 0}, -/* 89 */ { 5, s_0_89, -1, 1, 0}, -/* 90 */ { 2, s_0_90, -1, 1, 0}, -/* 91 */ { 3, s_0_91, 90, 1, 0}, -/* 92 */ { 3, s_0_92, -1, 1, 0}, -/* 93 */ { 4, s_0_93, -1, 1, 0}, -/* 94 */ { 2, s_0_94, -1, 1, 0}, -/* 95 */ { 3, s_0_95, 94, 1, 0}, -/* 96 */ { 4, s_0_96, -1, 1, 0}, -/* 97 */ { 2, s_0_97, -1, 1, 0}, -/* 98 */ { 5, s_0_98, -1, 1, 0}, -/* 99 */ { 2, s_0_99, -1, 1, 0}, -/*100 */ { 3, s_0_100, 99, 1, 0}, -/*101 */ { 6, s_0_101, 100, 1, 0}, -/*102 */ { 4, s_0_102, 100, 1, 0}, -/*103 */ { 6, s_0_103, 99, 5, 0}, -/*104 */ { 2, s_0_104, -1, 1, 0}, -/*105 */ { 5, s_0_105, 104, 1, 0}, -/*106 */ { 4, s_0_106, 104, 1, 0}, -/*107 */ { 5, s_0_107, -1, 1, 0}, -/*108 */ { 5, s_0_108, -1, 1, 0} +{ 4, s_0_0, -1, 1, 0}, +{ 5, s_0_1, 0, 1, 0}, +{ 5, s_0_2, 0, 1, 0}, +{ 5, s_0_3, 0, 1, 0}, +{ 6, s_0_4, -1, 1, 0}, +{ 5, s_0_5, -1, 1, 0}, +{ 6, s_0_6, -1, 1, 0}, +{ 7, s_0_7, -1, 1, 0}, +{ 5, s_0_8, -1, 1, 0}, +{ 5, s_0_9, -1, 1, 0}, +{ 5, s_0_10, -1, 1, 0}, +{ 4, s_0_11, -1, 1, 0}, +{ 5, s_0_12, -1, 1, 0}, +{ 6, s_0_13, 12, 1, 0}, +{ 5, s_0_14, -1, 1, 0}, +{ 6, s_0_15, -1, 2, 0}, +{ 6, s_0_16, -1, 1, 0}, +{ 2, s_0_17, -1, 1, 0}, +{ 5, s_0_18, 17, 1, 0}, +{ 2, s_0_19, -1, 1, 0}, +{ 4, s_0_20, -1, 1, 0}, +{ 4, s_0_21, -1, 1, 0}, +{ 4, s_0_22, -1, 1, 0}, +{ 5, s_0_23, -1, 1, 0}, +{ 6, s_0_24, 23, 1, 0}, +{ 4, s_0_25, -1, 1, 0}, +{ 4, s_0_26, -1, 1, 0}, +{ 6, s_0_27, -1, 1, 0}, +{ 3, s_0_28, -1, 1, 0}, +{ 4, s_0_29, 28, 1, 0}, +{ 7, s_0_30, 29, 4, 0}, +{ 4, s_0_31, 28, 1, 0}, +{ 4, s_0_32, 28, 1, 0}, +{ 4, s_0_33, -1, 1, 0}, +{ 5, s_0_34, 33, 1, 0}, +{ 4, s_0_35, -1, 1, 0}, +{ 4, s_0_36, -1, 1, 0}, +{ 4, s_0_37, -1, 1, 0}, +{ 4, s_0_38, -1, 1, 0}, +{ 3, s_0_39, -1, 1, 0}, +{ 4, s_0_40, 39, 1, 0}, +{ 6, s_0_41, -1, 1, 0}, +{ 3, s_0_42, -1, 1, 0}, +{ 6, s_0_43, 42, 1, 0}, +{ 3, s_0_44, -1, 2, 0}, +{ 6, s_0_45, 44, 1, 0}, +{ 6, s_0_46, 44, 1, 0}, +{ 6, s_0_47, 44, 1, 0}, +{ 3, s_0_48, -1, 1, 0}, +{ 4, s_0_49, 48, 1, 0}, +{ 4, s_0_50, 48, 1, 0}, +{ 4, s_0_51, 48, 1, 0}, +{ 5, s_0_52, -1, 1, 0}, +{ 5, s_0_53, -1, 1, 0}, +{ 5, s_0_54, -1, 1, 0}, +{ 2, s_0_55, -1, 1, 0}, +{ 4, s_0_56, 55, 1, 0}, +{ 5, s_0_57, 55, 1, 0}, +{ 6, s_0_58, 55, 1, 0}, +{ 4, s_0_59, -1, 1, 0}, +{ 4, s_0_60, -1, 1, 0}, +{ 3, s_0_61, -1, 1, 0}, +{ 4, s_0_62, 61, 1, 0}, +{ 3, s_0_63, -1, 1, 0}, +{ 4, s_0_64, -1, 1, 0}, +{ 5, s_0_65, 64, 1, 0}, +{ 2, s_0_66, -1, 1, 0}, +{ 3, s_0_67, -1, 1, 0}, +{ 4, s_0_68, 67, 1, 0}, +{ 4, s_0_69, 67, 1, 0}, +{ 4, s_0_70, 67, 1, 0}, +{ 5, s_0_71, 70, 1, 0}, +{ 5, s_0_72, -1, 2, 0}, +{ 5, s_0_73, -1, 1, 0}, +{ 5, s_0_74, -1, 1, 0}, +{ 6, s_0_75, 74, 1, 0}, +{ 2, s_0_76, -1, 1, 0}, +{ 3, s_0_77, 76, 1, 0}, +{ 4, s_0_78, 77, 1, 0}, +{ 3, s_0_79, 76, 1, 0}, +{ 4, s_0_80, 76, 1, 0}, +{ 7, s_0_81, -1, 3, 0}, +{ 3, s_0_82, -1, 1, 0}, +{ 3, s_0_83, -1, 1, 0}, +{ 3, s_0_84, -1, 1, 0}, +{ 5, s_0_85, 84, 1, 0}, +{ 4, s_0_86, -1, 1, 0}, +{ 5, s_0_87, 86, 1, 0}, +{ 3, s_0_88, -1, 1, 0}, +{ 5, s_0_89, -1, 1, 0}, +{ 2, s_0_90, -1, 1, 0}, +{ 3, s_0_91, 90, 1, 0}, +{ 3, s_0_92, -1, 1, 0}, +{ 4, s_0_93, -1, 1, 0}, +{ 2, s_0_94, -1, 1, 0}, +{ 3, s_0_95, 94, 1, 0}, +{ 4, s_0_96, -1, 1, 0}, +{ 2, s_0_97, -1, 1, 0}, +{ 5, s_0_98, -1, 1, 0}, +{ 2, s_0_99, -1, 1, 0}, +{ 3, s_0_100, 99, 1, 0}, +{ 6, s_0_101, 100, 1, 0}, +{ 4, s_0_102, 100, 1, 0}, +{ 6, s_0_103, 99, 5, 0}, +{ 2, s_0_104, -1, 1, 0}, +{ 5, s_0_105, 104, 1, 0}, +{ 4, s_0_106, 104, 1, 0}, +{ 5, s_0_107, -1, 1, 0}, +{ 5, s_0_108, -1, 1, 0} }; static const symbol s_1_0[3] = { 'a', 'd', 'a' }; @@ -549,301 +549,301 @@ static const symbol s_1_294[5] = { 'k', 'o', 'i', 't', 'z' }; static const struct among a_1[295] = { -/* 0 */ { 3, s_1_0, -1, 1, 0}, -/* 1 */ { 4, s_1_1, 0, 1, 0}, -/* 2 */ { 4, s_1_2, -1, 1, 0}, -/* 3 */ { 5, s_1_3, -1, 1, 0}, -/* 4 */ { 5, s_1_4, -1, 1, 0}, -/* 5 */ { 5, s_1_5, -1, 1, 0}, -/* 6 */ { 5, s_1_6, -1, 1, 0}, -/* 7 */ { 6, s_1_7, 6, 1, 0}, -/* 8 */ { 6, s_1_8, 6, 1, 0}, -/* 9 */ { 5, s_1_9, -1, 1, 0}, -/* 10 */ { 5, s_1_10, -1, 1, 0}, -/* 11 */ { 6, s_1_11, 10, 1, 0}, -/* 12 */ { 5, s_1_12, -1, 1, 0}, -/* 13 */ { 4, s_1_13, -1, 1, 0}, -/* 14 */ { 5, s_1_14, -1, 1, 0}, -/* 15 */ { 3, s_1_15, -1, 1, 0}, -/* 16 */ { 4, s_1_16, 15, 1, 0}, -/* 17 */ { 6, s_1_17, 15, 1, 0}, -/* 18 */ { 4, s_1_18, 15, 1, 0}, -/* 19 */ { 5, s_1_19, 18, 1, 0}, -/* 20 */ { 3, s_1_20, -1, 1, 0}, -/* 21 */ { 6, s_1_21, -1, 1, 0}, -/* 22 */ { 3, s_1_22, -1, 1, 0}, -/* 23 */ { 5, s_1_23, 22, 1, 0}, -/* 24 */ { 5, s_1_24, 22, 1, 0}, -/* 25 */ { 5, s_1_25, 22, 1, 0}, -/* 26 */ { 5, s_1_26, -1, 1, 0}, -/* 27 */ { 2, s_1_27, -1, 1, 0}, -/* 28 */ { 4, s_1_28, 27, 1, 0}, -/* 29 */ { 4, s_1_29, -1, 1, 0}, -/* 30 */ { 5, s_1_30, -1, 1, 0}, -/* 31 */ { 6, s_1_31, 30, 1, 0}, -/* 32 */ { 6, s_1_32, -1, 1, 0}, -/* 33 */ { 6, s_1_33, -1, 1, 0}, -/* 34 */ { 4, s_1_34, -1, 1, 0}, -/* 35 */ { 4, s_1_35, -1, 1, 0}, -/* 36 */ { 5, s_1_36, 35, 1, 0}, -/* 37 */ { 5, s_1_37, 35, 1, 0}, -/* 38 */ { 5, s_1_38, -1, 1, 0}, -/* 39 */ { 4, s_1_39, -1, 1, 0}, -/* 40 */ { 3, s_1_40, -1, 1, 0}, -/* 41 */ { 5, s_1_41, 40, 1, 0}, -/* 42 */ { 3, s_1_42, -1, 1, 0}, -/* 43 */ { 4, s_1_43, 42, 1, 0}, -/* 44 */ { 4, s_1_44, -1, 1, 0}, -/* 45 */ { 5, s_1_45, 44, 1, 0}, -/* 46 */ { 5, s_1_46, 44, 1, 0}, -/* 47 */ { 5, s_1_47, 44, 1, 0}, -/* 48 */ { 4, s_1_48, -1, 1, 0}, -/* 49 */ { 5, s_1_49, 48, 1, 0}, -/* 50 */ { 5, s_1_50, 48, 1, 0}, -/* 51 */ { 6, s_1_51, -1, 2, 0}, -/* 52 */ { 6, s_1_52, -1, 1, 0}, -/* 53 */ { 6, s_1_53, -1, 1, 0}, -/* 54 */ { 5, s_1_54, -1, 1, 0}, -/* 55 */ { 4, s_1_55, -1, 1, 0}, -/* 56 */ { 3, s_1_56, -1, 1, 0}, -/* 57 */ { 4, s_1_57, -1, 1, 0}, -/* 58 */ { 5, s_1_58, -1, 1, 0}, -/* 59 */ { 6, s_1_59, -1, 1, 0}, -/* 60 */ { 2, s_1_60, -1, 1, 0}, -/* 61 */ { 4, s_1_61, 60, 3, 0}, -/* 62 */ { 5, s_1_62, 60, 10, 0}, -/* 63 */ { 3, s_1_63, 60, 1, 0}, -/* 64 */ { 3, s_1_64, 60, 1, 0}, -/* 65 */ { 3, s_1_65, 60, 1, 0}, -/* 66 */ { 6, s_1_66, -1, 1, 0}, -/* 67 */ { 4, s_1_67, -1, 1, 0}, -/* 68 */ { 5, s_1_68, -1, 1, 0}, -/* 69 */ { 5, s_1_69, -1, 1, 0}, -/* 70 */ { 4, s_1_70, -1, 1, 0}, -/* 71 */ { 3, s_1_71, -1, 1, 0}, -/* 72 */ { 2, s_1_72, -1, 1, 0}, -/* 73 */ { 4, s_1_73, 72, 1, 0}, -/* 74 */ { 3, s_1_74, 72, 1, 0}, -/* 75 */ { 7, s_1_75, 74, 1, 0}, -/* 76 */ { 7, s_1_76, 74, 1, 0}, -/* 77 */ { 6, s_1_77, 74, 1, 0}, -/* 78 */ { 5, s_1_78, 72, 1, 0}, -/* 79 */ { 6, s_1_79, 78, 1, 0}, -/* 80 */ { 4, s_1_80, 72, 1, 0}, -/* 81 */ { 4, s_1_81, 72, 1, 0}, -/* 82 */ { 5, s_1_82, 72, 1, 0}, -/* 83 */ { 3, s_1_83, 72, 1, 0}, -/* 84 */ { 4, s_1_84, 83, 1, 0}, -/* 85 */ { 5, s_1_85, 83, 1, 0}, -/* 86 */ { 6, s_1_86, 85, 1, 0}, -/* 87 */ { 5, s_1_87, -1, 1, 0}, -/* 88 */ { 6, s_1_88, 87, 1, 0}, -/* 89 */ { 4, s_1_89, -1, 1, 0}, -/* 90 */ { 4, s_1_90, -1, 1, 0}, -/* 91 */ { 3, s_1_91, -1, 1, 0}, -/* 92 */ { 5, s_1_92, 91, 1, 0}, -/* 93 */ { 4, s_1_93, 91, 1, 0}, -/* 94 */ { 3, s_1_94, -1, 1, 0}, -/* 95 */ { 5, s_1_95, 94, 1, 0}, -/* 96 */ { 4, s_1_96, -1, 1, 0}, -/* 97 */ { 5, s_1_97, 96, 1, 0}, -/* 98 */ { 5, s_1_98, 96, 1, 0}, -/* 99 */ { 4, s_1_99, -1, 1, 0}, -/*100 */ { 4, s_1_100, -1, 1, 0}, -/*101 */ { 4, s_1_101, -1, 1, 0}, -/*102 */ { 3, s_1_102, -1, 1, 0}, -/*103 */ { 4, s_1_103, 102, 1, 0}, -/*104 */ { 4, s_1_104, 102, 1, 0}, -/*105 */ { 4, s_1_105, -1, 1, 0}, -/*106 */ { 4, s_1_106, -1, 1, 0}, -/*107 */ { 3, s_1_107, -1, 1, 0}, -/*108 */ { 2, s_1_108, -1, 1, 0}, -/*109 */ { 3, s_1_109, 108, 1, 0}, -/*110 */ { 4, s_1_110, 109, 1, 0}, -/*111 */ { 5, s_1_111, 109, 1, 0}, -/*112 */ { 5, s_1_112, 109, 1, 0}, -/*113 */ { 4, s_1_113, 109, 1, 0}, -/*114 */ { 5, s_1_114, 113, 1, 0}, -/*115 */ { 5, s_1_115, 109, 1, 0}, -/*116 */ { 4, s_1_116, 108, 1, 0}, -/*117 */ { 4, s_1_117, 108, 1, 0}, -/*118 */ { 4, s_1_118, 108, 1, 0}, -/*119 */ { 3, s_1_119, 108, 2, 0}, -/*120 */ { 6, s_1_120, 108, 1, 0}, -/*121 */ { 5, s_1_121, 108, 1, 0}, -/*122 */ { 3, s_1_122, 108, 1, 0}, -/*123 */ { 2, s_1_123, -1, 1, 0}, -/*124 */ { 3, s_1_124, 123, 1, 0}, -/*125 */ { 2, s_1_125, -1, 1, 0}, -/*126 */ { 3, s_1_126, 125, 1, 0}, -/*127 */ { 4, s_1_127, 126, 1, 0}, -/*128 */ { 3, s_1_128, 125, 1, 0}, -/*129 */ { 3, s_1_129, -1, 1, 0}, -/*130 */ { 6, s_1_130, 129, 1, 0}, -/*131 */ { 5, s_1_131, 129, 1, 0}, -/*132 */ { 5, s_1_132, -1, 1, 0}, -/*133 */ { 5, s_1_133, -1, 1, 0}, -/*134 */ { 5, s_1_134, -1, 1, 0}, -/*135 */ { 4, s_1_135, -1, 1, 0}, -/*136 */ { 3, s_1_136, -1, 1, 0}, -/*137 */ { 6, s_1_137, 136, 1, 0}, -/*138 */ { 5, s_1_138, 136, 1, 0}, -/*139 */ { 4, s_1_139, -1, 1, 0}, -/*140 */ { 3, s_1_140, -1, 1, 0}, -/*141 */ { 4, s_1_141, 140, 1, 0}, -/*142 */ { 2, s_1_142, -1, 1, 0}, -/*143 */ { 3, s_1_143, 142, 1, 0}, -/*144 */ { 5, s_1_144, 142, 1, 0}, -/*145 */ { 3, s_1_145, 142, 2, 0}, -/*146 */ { 6, s_1_146, 145, 1, 0}, -/*147 */ { 5, s_1_147, 145, 1, 0}, -/*148 */ { 6, s_1_148, 145, 1, 0}, -/*149 */ { 6, s_1_149, 145, 1, 0}, -/*150 */ { 6, s_1_150, 145, 1, 0}, -/*151 */ { 4, s_1_151, -1, 1, 0}, -/*152 */ { 4, s_1_152, -1, 1, 0}, -/*153 */ { 4, s_1_153, -1, 1, 0}, -/*154 */ { 4, s_1_154, -1, 1, 0}, -/*155 */ { 5, s_1_155, 154, 1, 0}, -/*156 */ { 5, s_1_156, 154, 1, 0}, -/*157 */ { 4, s_1_157, -1, 1, 0}, -/*158 */ { 2, s_1_158, -1, 1, 0}, -/*159 */ { 4, s_1_159, -1, 1, 0}, -/*160 */ { 5, s_1_160, 159, 1, 0}, -/*161 */ { 4, s_1_161, -1, 1, 0}, -/*162 */ { 3, s_1_162, -1, 1, 0}, -/*163 */ { 4, s_1_163, -1, 1, 0}, -/*164 */ { 2, s_1_164, -1, 1, 0}, -/*165 */ { 5, s_1_165, 164, 1, 0}, -/*166 */ { 3, s_1_166, 164, 1, 0}, -/*167 */ { 4, s_1_167, 166, 1, 0}, -/*168 */ { 2, s_1_168, -1, 1, 0}, -/*169 */ { 5, s_1_169, -1, 1, 0}, -/*170 */ { 2, s_1_170, -1, 1, 0}, -/*171 */ { 4, s_1_171, 170, 1, 0}, -/*172 */ { 4, s_1_172, 170, 1, 0}, -/*173 */ { 4, s_1_173, 170, 1, 0}, -/*174 */ { 4, s_1_174, -1, 1, 0}, -/*175 */ { 3, s_1_175, -1, 1, 0}, -/*176 */ { 2, s_1_176, -1, 1, 0}, -/*177 */ { 4, s_1_177, 176, 1, 0}, -/*178 */ { 5, s_1_178, 177, 1, 0}, -/*179 */ { 5, s_1_179, 176, 8, 0}, -/*180 */ { 5, s_1_180, 176, 1, 0}, -/*181 */ { 5, s_1_181, 176, 1, 0}, -/*182 */ { 3, s_1_182, -1, 1, 0}, -/*183 */ { 3, s_1_183, -1, 1, 0}, -/*184 */ { 4, s_1_184, 183, 1, 0}, -/*185 */ { 4, s_1_185, 183, 1, 0}, -/*186 */ { 4, s_1_186, -1, 1, 0}, -/*187 */ { 3, s_1_187, -1, 1, 0}, -/*188 */ { 2, s_1_188, -1, 1, 0}, -/*189 */ { 4, s_1_189, 188, 1, 0}, -/*190 */ { 2, s_1_190, -1, 1, 0}, -/*191 */ { 3, s_1_191, 190, 1, 0}, -/*192 */ { 3, s_1_192, 190, 1, 0}, -/*193 */ { 3, s_1_193, -1, 1, 0}, -/*194 */ { 4, s_1_194, 193, 1, 0}, -/*195 */ { 4, s_1_195, 193, 1, 0}, -/*196 */ { 4, s_1_196, 193, 1, 0}, -/*197 */ { 5, s_1_197, -1, 2, 0}, -/*198 */ { 5, s_1_198, -1, 1, 0}, -/*199 */ { 5, s_1_199, -1, 1, 0}, -/*200 */ { 4, s_1_200, -1, 1, 0}, -/*201 */ { 3, s_1_201, -1, 1, 0}, -/*202 */ { 2, s_1_202, -1, 1, 0}, -/*203 */ { 5, s_1_203, -1, 1, 0}, -/*204 */ { 2, s_1_204, -1, 1, 0}, -/*205 */ { 2, s_1_205, -1, 1, 0}, -/*206 */ { 2, s_1_206, -1, 1, 0}, -/*207 */ { 5, s_1_207, -1, 1, 0}, -/*208 */ { 5, s_1_208, -1, 1, 0}, -/*209 */ { 3, s_1_209, -1, 1, 0}, -/*210 */ { 4, s_1_210, 209, 1, 0}, -/*211 */ { 3, s_1_211, -1, 1, 0}, -/*212 */ { 3, s_1_212, -1, 1, 0}, -/*213 */ { 4, s_1_213, 212, 1, 0}, -/*214 */ { 2, s_1_214, -1, 4, 0}, -/*215 */ { 3, s_1_215, 214, 2, 0}, -/*216 */ { 6, s_1_216, 215, 1, 0}, -/*217 */ { 6, s_1_217, 215, 1, 0}, -/*218 */ { 5, s_1_218, 215, 1, 0}, -/*219 */ { 3, s_1_219, 214, 4, 0}, -/*220 */ { 4, s_1_220, 214, 4, 0}, -/*221 */ { 4, s_1_221, -1, 1, 0}, -/*222 */ { 5, s_1_222, 221, 1, 0}, -/*223 */ { 3, s_1_223, -1, 1, 0}, -/*224 */ { 3, s_1_224, -1, 1, 0}, -/*225 */ { 3, s_1_225, -1, 1, 0}, -/*226 */ { 4, s_1_226, -1, 1, 0}, -/*227 */ { 5, s_1_227, 226, 1, 0}, -/*228 */ { 5, s_1_228, -1, 1, 0}, -/*229 */ { 4, s_1_229, -1, 1, 0}, -/*230 */ { 5, s_1_230, 229, 1, 0}, -/*231 */ { 2, s_1_231, -1, 1, 0}, -/*232 */ { 3, s_1_232, 231, 1, 0}, -/*233 */ { 3, s_1_233, -1, 1, 0}, -/*234 */ { 2, s_1_234, -1, 1, 0}, -/*235 */ { 5, s_1_235, 234, 5, 0}, -/*236 */ { 4, s_1_236, 234, 1, 0}, -/*237 */ { 5, s_1_237, 236, 1, 0}, -/*238 */ { 3, s_1_238, 234, 1, 0}, -/*239 */ { 6, s_1_239, 234, 1, 0}, -/*240 */ { 3, s_1_240, 234, 1, 0}, -/*241 */ { 4, s_1_241, 234, 1, 0}, -/*242 */ { 8, s_1_242, 241, 6, 0}, -/*243 */ { 3, s_1_243, 234, 1, 0}, -/*244 */ { 2, s_1_244, -1, 1, 0}, -/*245 */ { 4, s_1_245, 244, 1, 0}, -/*246 */ { 2, s_1_246, -1, 1, 0}, -/*247 */ { 3, s_1_247, 246, 1, 0}, -/*248 */ { 5, s_1_248, 247, 9, 0}, -/*249 */ { 4, s_1_249, 247, 1, 0}, -/*250 */ { 4, s_1_250, 247, 1, 0}, -/*251 */ { 3, s_1_251, 246, 1, 0}, -/*252 */ { 4, s_1_252, 246, 1, 0}, -/*253 */ { 3, s_1_253, 246, 1, 0}, -/*254 */ { 3, s_1_254, -1, 1, 0}, -/*255 */ { 2, s_1_255, -1, 1, 0}, -/*256 */ { 3, s_1_256, 255, 1, 0}, -/*257 */ { 3, s_1_257, 255, 1, 0}, -/*258 */ { 3, s_1_258, -1, 1, 0}, -/*259 */ { 3, s_1_259, -1, 1, 0}, -/*260 */ { 6, s_1_260, 259, 1, 0}, -/*261 */ { 2, s_1_261, -1, 1, 0}, -/*262 */ { 2, s_1_262, -1, 1, 0}, -/*263 */ { 2, s_1_263, -1, 1, 0}, -/*264 */ { 3, s_1_264, 263, 1, 0}, -/*265 */ { 5, s_1_265, 263, 1, 0}, -/*266 */ { 5, s_1_266, 263, 7, 0}, -/*267 */ { 4, s_1_267, 263, 1, 0}, -/*268 */ { 4, s_1_268, 263, 1, 0}, -/*269 */ { 3, s_1_269, 263, 1, 0}, -/*270 */ { 4, s_1_270, 263, 1, 0}, -/*271 */ { 2, s_1_271, -1, 2, 0}, -/*272 */ { 3, s_1_272, 271, 1, 0}, -/*273 */ { 2, s_1_273, -1, 1, 0}, -/*274 */ { 3, s_1_274, -1, 1, 0}, -/*275 */ { 2, s_1_275, -1, 1, 0}, -/*276 */ { 5, s_1_276, 275, 1, 0}, -/*277 */ { 4, s_1_277, 275, 1, 0}, -/*278 */ { 4, s_1_278, -1, 1, 0}, -/*279 */ { 4, s_1_279, -1, 2, 0}, -/*280 */ { 4, s_1_280, -1, 1, 0}, -/*281 */ { 3, s_1_281, -1, 1, 0}, -/*282 */ { 2, s_1_282, -1, 1, 0}, -/*283 */ { 4, s_1_283, 282, 4, 0}, -/*284 */ { 5, s_1_284, 282, 1, 0}, -/*285 */ { 4, s_1_285, 282, 1, 0}, -/*286 */ { 3, s_1_286, -1, 1, 0}, -/*287 */ { 2, s_1_287, -1, 1, 0}, -/*288 */ { 3, s_1_288, 287, 1, 0}, -/*289 */ { 6, s_1_289, 288, 1, 0}, -/*290 */ { 1, s_1_290, -1, 1, 0}, -/*291 */ { 2, s_1_291, 290, 1, 0}, -/*292 */ { 4, s_1_292, 290, 1, 0}, -/*293 */ { 2, s_1_293, 290, 1, 0}, -/*294 */ { 5, s_1_294, 293, 1, 0} +{ 3, s_1_0, -1, 1, 0}, +{ 4, s_1_1, 0, 1, 0}, +{ 4, s_1_2, -1, 1, 0}, +{ 5, s_1_3, -1, 1, 0}, +{ 5, s_1_4, -1, 1, 0}, +{ 5, s_1_5, -1, 1, 0}, +{ 5, s_1_6, -1, 1, 0}, +{ 6, s_1_7, 6, 1, 0}, +{ 6, s_1_8, 6, 1, 0}, +{ 5, s_1_9, -1, 1, 0}, +{ 5, s_1_10, -1, 1, 0}, +{ 6, s_1_11, 10, 1, 0}, +{ 5, s_1_12, -1, 1, 0}, +{ 4, s_1_13, -1, 1, 0}, +{ 5, s_1_14, -1, 1, 0}, +{ 3, s_1_15, -1, 1, 0}, +{ 4, s_1_16, 15, 1, 0}, +{ 6, s_1_17, 15, 1, 0}, +{ 4, s_1_18, 15, 1, 0}, +{ 5, s_1_19, 18, 1, 0}, +{ 3, s_1_20, -1, 1, 0}, +{ 6, s_1_21, -1, 1, 0}, +{ 3, s_1_22, -1, 1, 0}, +{ 5, s_1_23, 22, 1, 0}, +{ 5, s_1_24, 22, 1, 0}, +{ 5, s_1_25, 22, 1, 0}, +{ 5, s_1_26, -1, 1, 0}, +{ 2, s_1_27, -1, 1, 0}, +{ 4, s_1_28, 27, 1, 0}, +{ 4, s_1_29, -1, 1, 0}, +{ 5, s_1_30, -1, 1, 0}, +{ 6, s_1_31, 30, 1, 0}, +{ 6, s_1_32, -1, 1, 0}, +{ 6, s_1_33, -1, 1, 0}, +{ 4, s_1_34, -1, 1, 0}, +{ 4, s_1_35, -1, 1, 0}, +{ 5, s_1_36, 35, 1, 0}, +{ 5, s_1_37, 35, 1, 0}, +{ 5, s_1_38, -1, 1, 0}, +{ 4, s_1_39, -1, 1, 0}, +{ 3, s_1_40, -1, 1, 0}, +{ 5, s_1_41, 40, 1, 0}, +{ 3, s_1_42, -1, 1, 0}, +{ 4, s_1_43, 42, 1, 0}, +{ 4, s_1_44, -1, 1, 0}, +{ 5, s_1_45, 44, 1, 0}, +{ 5, s_1_46, 44, 1, 0}, +{ 5, s_1_47, 44, 1, 0}, +{ 4, s_1_48, -1, 1, 0}, +{ 5, s_1_49, 48, 1, 0}, +{ 5, s_1_50, 48, 1, 0}, +{ 6, s_1_51, -1, 2, 0}, +{ 6, s_1_52, -1, 1, 0}, +{ 6, s_1_53, -1, 1, 0}, +{ 5, s_1_54, -1, 1, 0}, +{ 4, s_1_55, -1, 1, 0}, +{ 3, s_1_56, -1, 1, 0}, +{ 4, s_1_57, -1, 1, 0}, +{ 5, s_1_58, -1, 1, 0}, +{ 6, s_1_59, -1, 1, 0}, +{ 2, s_1_60, -1, 1, 0}, +{ 4, s_1_61, 60, 3, 0}, +{ 5, s_1_62, 60, 10, 0}, +{ 3, s_1_63, 60, 1, 0}, +{ 3, s_1_64, 60, 1, 0}, +{ 3, s_1_65, 60, 1, 0}, +{ 6, s_1_66, -1, 1, 0}, +{ 4, s_1_67, -1, 1, 0}, +{ 5, s_1_68, -1, 1, 0}, +{ 5, s_1_69, -1, 1, 0}, +{ 4, s_1_70, -1, 1, 0}, +{ 3, s_1_71, -1, 1, 0}, +{ 2, s_1_72, -1, 1, 0}, +{ 4, s_1_73, 72, 1, 0}, +{ 3, s_1_74, 72, 1, 0}, +{ 7, s_1_75, 74, 1, 0}, +{ 7, s_1_76, 74, 1, 0}, +{ 6, s_1_77, 74, 1, 0}, +{ 5, s_1_78, 72, 1, 0}, +{ 6, s_1_79, 78, 1, 0}, +{ 4, s_1_80, 72, 1, 0}, +{ 4, s_1_81, 72, 1, 0}, +{ 5, s_1_82, 72, 1, 0}, +{ 3, s_1_83, 72, 1, 0}, +{ 4, s_1_84, 83, 1, 0}, +{ 5, s_1_85, 83, 1, 0}, +{ 6, s_1_86, 85, 1, 0}, +{ 5, s_1_87, -1, 1, 0}, +{ 6, s_1_88, 87, 1, 0}, +{ 4, s_1_89, -1, 1, 0}, +{ 4, s_1_90, -1, 1, 0}, +{ 3, s_1_91, -1, 1, 0}, +{ 5, s_1_92, 91, 1, 0}, +{ 4, s_1_93, 91, 1, 0}, +{ 3, s_1_94, -1, 1, 0}, +{ 5, s_1_95, 94, 1, 0}, +{ 4, s_1_96, -1, 1, 0}, +{ 5, s_1_97, 96, 1, 0}, +{ 5, s_1_98, 96, 1, 0}, +{ 4, s_1_99, -1, 1, 0}, +{ 4, s_1_100, -1, 1, 0}, +{ 4, s_1_101, -1, 1, 0}, +{ 3, s_1_102, -1, 1, 0}, +{ 4, s_1_103, 102, 1, 0}, +{ 4, s_1_104, 102, 1, 0}, +{ 4, s_1_105, -1, 1, 0}, +{ 4, s_1_106, -1, 1, 0}, +{ 3, s_1_107, -1, 1, 0}, +{ 2, s_1_108, -1, 1, 0}, +{ 3, s_1_109, 108, 1, 0}, +{ 4, s_1_110, 109, 1, 0}, +{ 5, s_1_111, 109, 1, 0}, +{ 5, s_1_112, 109, 1, 0}, +{ 4, s_1_113, 109, 1, 0}, +{ 5, s_1_114, 113, 1, 0}, +{ 5, s_1_115, 109, 1, 0}, +{ 4, s_1_116, 108, 1, 0}, +{ 4, s_1_117, 108, 1, 0}, +{ 4, s_1_118, 108, 1, 0}, +{ 3, s_1_119, 108, 2, 0}, +{ 6, s_1_120, 108, 1, 0}, +{ 5, s_1_121, 108, 1, 0}, +{ 3, s_1_122, 108, 1, 0}, +{ 2, s_1_123, -1, 1, 0}, +{ 3, s_1_124, 123, 1, 0}, +{ 2, s_1_125, -1, 1, 0}, +{ 3, s_1_126, 125, 1, 0}, +{ 4, s_1_127, 126, 1, 0}, +{ 3, s_1_128, 125, 1, 0}, +{ 3, s_1_129, -1, 1, 0}, +{ 6, s_1_130, 129, 1, 0}, +{ 5, s_1_131, 129, 1, 0}, +{ 5, s_1_132, -1, 1, 0}, +{ 5, s_1_133, -1, 1, 0}, +{ 5, s_1_134, -1, 1, 0}, +{ 4, s_1_135, -1, 1, 0}, +{ 3, s_1_136, -1, 1, 0}, +{ 6, s_1_137, 136, 1, 0}, +{ 5, s_1_138, 136, 1, 0}, +{ 4, s_1_139, -1, 1, 0}, +{ 3, s_1_140, -1, 1, 0}, +{ 4, s_1_141, 140, 1, 0}, +{ 2, s_1_142, -1, 1, 0}, +{ 3, s_1_143, 142, 1, 0}, +{ 5, s_1_144, 142, 1, 0}, +{ 3, s_1_145, 142, 2, 0}, +{ 6, s_1_146, 145, 1, 0}, +{ 5, s_1_147, 145, 1, 0}, +{ 6, s_1_148, 145, 1, 0}, +{ 6, s_1_149, 145, 1, 0}, +{ 6, s_1_150, 145, 1, 0}, +{ 4, s_1_151, -1, 1, 0}, +{ 4, s_1_152, -1, 1, 0}, +{ 4, s_1_153, -1, 1, 0}, +{ 4, s_1_154, -1, 1, 0}, +{ 5, s_1_155, 154, 1, 0}, +{ 5, s_1_156, 154, 1, 0}, +{ 4, s_1_157, -1, 1, 0}, +{ 2, s_1_158, -1, 1, 0}, +{ 4, s_1_159, -1, 1, 0}, +{ 5, s_1_160, 159, 1, 0}, +{ 4, s_1_161, -1, 1, 0}, +{ 3, s_1_162, -1, 1, 0}, +{ 4, s_1_163, -1, 1, 0}, +{ 2, s_1_164, -1, 1, 0}, +{ 5, s_1_165, 164, 1, 0}, +{ 3, s_1_166, 164, 1, 0}, +{ 4, s_1_167, 166, 1, 0}, +{ 2, s_1_168, -1, 1, 0}, +{ 5, s_1_169, -1, 1, 0}, +{ 2, s_1_170, -1, 1, 0}, +{ 4, s_1_171, 170, 1, 0}, +{ 4, s_1_172, 170, 1, 0}, +{ 4, s_1_173, 170, 1, 0}, +{ 4, s_1_174, -1, 1, 0}, +{ 3, s_1_175, -1, 1, 0}, +{ 2, s_1_176, -1, 1, 0}, +{ 4, s_1_177, 176, 1, 0}, +{ 5, s_1_178, 177, 1, 0}, +{ 5, s_1_179, 176, 8, 0}, +{ 5, s_1_180, 176, 1, 0}, +{ 5, s_1_181, 176, 1, 0}, +{ 3, s_1_182, -1, 1, 0}, +{ 3, s_1_183, -1, 1, 0}, +{ 4, s_1_184, 183, 1, 0}, +{ 4, s_1_185, 183, 1, 0}, +{ 4, s_1_186, -1, 1, 0}, +{ 3, s_1_187, -1, 1, 0}, +{ 2, s_1_188, -1, 1, 0}, +{ 4, s_1_189, 188, 1, 0}, +{ 2, s_1_190, -1, 1, 0}, +{ 3, s_1_191, 190, 1, 0}, +{ 3, s_1_192, 190, 1, 0}, +{ 3, s_1_193, -1, 1, 0}, +{ 4, s_1_194, 193, 1, 0}, +{ 4, s_1_195, 193, 1, 0}, +{ 4, s_1_196, 193, 1, 0}, +{ 5, s_1_197, -1, 2, 0}, +{ 5, s_1_198, -1, 1, 0}, +{ 5, s_1_199, -1, 1, 0}, +{ 4, s_1_200, -1, 1, 0}, +{ 3, s_1_201, -1, 1, 0}, +{ 2, s_1_202, -1, 1, 0}, +{ 5, s_1_203, -1, 1, 0}, +{ 2, s_1_204, -1, 1, 0}, +{ 2, s_1_205, -1, 1, 0}, +{ 2, s_1_206, -1, 1, 0}, +{ 5, s_1_207, -1, 1, 0}, +{ 5, s_1_208, -1, 1, 0}, +{ 3, s_1_209, -1, 1, 0}, +{ 4, s_1_210, 209, 1, 0}, +{ 3, s_1_211, -1, 1, 0}, +{ 3, s_1_212, -1, 1, 0}, +{ 4, s_1_213, 212, 1, 0}, +{ 2, s_1_214, -1, 4, 0}, +{ 3, s_1_215, 214, 2, 0}, +{ 6, s_1_216, 215, 1, 0}, +{ 6, s_1_217, 215, 1, 0}, +{ 5, s_1_218, 215, 1, 0}, +{ 3, s_1_219, 214, 4, 0}, +{ 4, s_1_220, 214, 4, 0}, +{ 4, s_1_221, -1, 1, 0}, +{ 5, s_1_222, 221, 1, 0}, +{ 3, s_1_223, -1, 1, 0}, +{ 3, s_1_224, -1, 1, 0}, +{ 3, s_1_225, -1, 1, 0}, +{ 4, s_1_226, -1, 1, 0}, +{ 5, s_1_227, 226, 1, 0}, +{ 5, s_1_228, -1, 1, 0}, +{ 4, s_1_229, -1, 1, 0}, +{ 5, s_1_230, 229, 1, 0}, +{ 2, s_1_231, -1, 1, 0}, +{ 3, s_1_232, 231, 1, 0}, +{ 3, s_1_233, -1, 1, 0}, +{ 2, s_1_234, -1, 1, 0}, +{ 5, s_1_235, 234, 5, 0}, +{ 4, s_1_236, 234, 1, 0}, +{ 5, s_1_237, 236, 1, 0}, +{ 3, s_1_238, 234, 1, 0}, +{ 6, s_1_239, 234, 1, 0}, +{ 3, s_1_240, 234, 1, 0}, +{ 4, s_1_241, 234, 1, 0}, +{ 8, s_1_242, 241, 6, 0}, +{ 3, s_1_243, 234, 1, 0}, +{ 2, s_1_244, -1, 1, 0}, +{ 4, s_1_245, 244, 1, 0}, +{ 2, s_1_246, -1, 1, 0}, +{ 3, s_1_247, 246, 1, 0}, +{ 5, s_1_248, 247, 9, 0}, +{ 4, s_1_249, 247, 1, 0}, +{ 4, s_1_250, 247, 1, 0}, +{ 3, s_1_251, 246, 1, 0}, +{ 4, s_1_252, 246, 1, 0}, +{ 3, s_1_253, 246, 1, 0}, +{ 3, s_1_254, -1, 1, 0}, +{ 2, s_1_255, -1, 1, 0}, +{ 3, s_1_256, 255, 1, 0}, +{ 3, s_1_257, 255, 1, 0}, +{ 3, s_1_258, -1, 1, 0}, +{ 3, s_1_259, -1, 1, 0}, +{ 6, s_1_260, 259, 1, 0}, +{ 2, s_1_261, -1, 1, 0}, +{ 2, s_1_262, -1, 1, 0}, +{ 2, s_1_263, -1, 1, 0}, +{ 3, s_1_264, 263, 1, 0}, +{ 5, s_1_265, 263, 1, 0}, +{ 5, s_1_266, 263, 7, 0}, +{ 4, s_1_267, 263, 1, 0}, +{ 4, s_1_268, 263, 1, 0}, +{ 3, s_1_269, 263, 1, 0}, +{ 4, s_1_270, 263, 1, 0}, +{ 2, s_1_271, -1, 2, 0}, +{ 3, s_1_272, 271, 1, 0}, +{ 2, s_1_273, -1, 1, 0}, +{ 3, s_1_274, -1, 1, 0}, +{ 2, s_1_275, -1, 1, 0}, +{ 5, s_1_276, 275, 1, 0}, +{ 4, s_1_277, 275, 1, 0}, +{ 4, s_1_278, -1, 1, 0}, +{ 4, s_1_279, -1, 2, 0}, +{ 4, s_1_280, -1, 1, 0}, +{ 3, s_1_281, -1, 1, 0}, +{ 2, s_1_282, -1, 1, 0}, +{ 4, s_1_283, 282, 4, 0}, +{ 5, s_1_284, 282, 1, 0}, +{ 4, s_1_285, 282, 1, 0}, +{ 3, s_1_286, -1, 1, 0}, +{ 2, s_1_287, -1, 1, 0}, +{ 3, s_1_288, 287, 1, 0}, +{ 6, s_1_289, 288, 1, 0}, +{ 1, s_1_290, -1, 1, 0}, +{ 2, s_1_291, 290, 1, 0}, +{ 4, s_1_292, 290, 1, 0}, +{ 2, s_1_293, 290, 1, 0}, +{ 5, s_1_294, 293, 1, 0} }; static const symbol s_2_0[4] = { 'z', 'l', 'e', 'a' }; @@ -868,25 +868,25 @@ static const symbol s_2_18[2] = { 't', 'o' }; static const struct among a_2[19] = { -/* 0 */ { 4, s_2_0, -1, 2, 0}, -/* 1 */ { 5, s_2_1, -1, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 1, 0}, -/* 3 */ { 3, s_2_3, -1, 1, 0}, -/* 4 */ { 4, s_2_4, -1, 1, 0}, -/* 5 */ { 4, s_2_5, -1, 1, 0}, -/* 6 */ { 4, s_2_6, -1, 1, 0}, -/* 7 */ { 4, s_2_7, -1, 1, 0}, -/* 8 */ { 2, s_2_8, -1, 1, 0}, -/* 9 */ { 2, s_2_9, -1, 1, 0}, -/* 10 */ { 2, s_2_10, -1, 1, 0}, -/* 11 */ { 5, s_2_11, 10, 1, 0}, -/* 12 */ { 3, s_2_12, 10, 1, 0}, -/* 13 */ { 5, s_2_13, 12, 1, 0}, -/* 14 */ { 4, s_2_14, 10, 1, 0}, -/* 15 */ { 2, s_2_15, -1, 1, 0}, -/* 16 */ { 2, s_2_16, -1, 1, 0}, -/* 17 */ { 3, s_2_17, 16, 1, 0}, -/* 18 */ { 2, s_2_18, -1, 1, 0} +{ 4, s_2_0, -1, 2, 0}, +{ 5, s_2_1, -1, 1, 0}, +{ 2, s_2_2, -1, 1, 0}, +{ 3, s_2_3, -1, 1, 0}, +{ 4, s_2_4, -1, 1, 0}, +{ 4, s_2_5, -1, 1, 0}, +{ 4, s_2_6, -1, 1, 0}, +{ 4, s_2_7, -1, 1, 0}, +{ 2, s_2_8, -1, 1, 0}, +{ 2, s_2_9, -1, 1, 0}, +{ 2, s_2_10, -1, 1, 0}, +{ 5, s_2_11, 10, 1, 0}, +{ 3, s_2_12, 10, 1, 0}, +{ 5, s_2_13, 12, 1, 0}, +{ 4, s_2_14, 10, 1, 0}, +{ 2, s_2_15, -1, 1, 0}, +{ 2, s_2_16, -1, 1, 0}, +{ 3, s_2_17, 16, 1, 0}, +{ 2, s_2_18, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16 }; @@ -903,16 +903,16 @@ static const symbol s_8[] = { 'i', 'g', 'a', 'r', 'o' }; static const symbol s_9[] = { 'a', 'u', 'r', 'k', 'a' }; static const symbol s_10[] = { 'z' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 25 */ - z->I[1] = z->l; /* $p1 = , line 26 */ - z->I[2] = z->l; /* $p2 = , line 27 */ - { int c1 = z->c; /* do, line 29 */ - { int c2 = z->c; /* or, line 31 */ - if (in_grouping(z, g_v, 97, 117, 0)) goto lab2; /* grouping v, line 30 */ - { int c3 = z->c; /* or, line 30 */ - if (out_grouping(z, g_v, 97, 117, 0)) goto lab4; /* non v, line 30 */ - { /* gopast */ /* grouping v, line 30 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping(z, g_v, 97, 117, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping(z, g_v, 97, 117, 0)) goto lab4; + { int ret = out_grouping(z, g_v, 97, 117, 1); if (ret < 0) goto lab4; z->c += ret; @@ -920,8 +920,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 117, 0)) goto lab2; /* grouping v, line 30 */ - { /* gopast */ /* non v, line 30 */ + if (in_grouping(z, g_v, 97, 117, 0)) goto lab2; + { int ret = in_grouping(z, g_v, 97, 117, 1); if (ret < 0) goto lab2; z->c += ret; @@ -931,10 +931,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 117, 0)) goto lab0; /* non v, line 32 */ - { int c4 = z->c; /* or, line 32 */ - if (out_grouping(z, g_v, 97, 117, 0)) goto lab6; /* non v, line 32 */ - { /* gopast */ /* grouping v, line 32 */ + if (out_grouping(z, g_v, 97, 117, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping(z, g_v, 97, 117, 0)) goto lab6; + { int ret = out_grouping(z, g_v, 97, 117, 1); if (ret < 0) goto lab6; z->c += ret; @@ -942,98 +942,98 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 117, 0)) goto lab0; /* grouping v, line 32 */ + if (in_grouping(z, g_v, 97, 117, 0)) goto lab0; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 32 */ + z->c++; } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 33 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 35 */ - { /* gopast */ /* grouping v, line 36 */ + { int c5 = z->c; + { int ret = out_grouping(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 36 */ + { int ret = in_grouping(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 36 */ - { /* gopast */ /* grouping v, line 37 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 37 */ + { int ret = in_grouping(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 37 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 43 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 44 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 45 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_aditzak(struct SN_env * z) { /* backwardmode */ +static int r_aditzak(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 48 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((70566434 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 48 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((70566434 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_0, 109); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 48 */ - switch (among_var) { /* among, line 48 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 59 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 59 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 61 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 61 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 7, s_0); /* <-, line 63 */ + { int ret = slice_from_s(z, 7, s_0); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 7, s_1); /* <-, line 65 */ + { int ret = slice_from_s(z, 7, s_1); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 6, s_2); /* <-, line 67 */ + { int ret = slice_from_s(z, 6, s_2); if (ret < 0) return ret; } break; @@ -1041,70 +1041,70 @@ static int r_aditzak(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_izenak(struct SN_env * z) { /* backwardmode */ +static int r_izenak(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 73 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((71162402 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 73 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((71162402 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_1, 295); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 73 */ - switch (among_var) { /* among, line 73 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 103 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 103 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 105 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 105 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_3); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_3); if (ret < 0) return ret; } break; case 4: - { int ret = r_R1(z); /* call R1, line 109 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 109 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_4); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 6, s_5); /* <-, line 113 */ + { int ret = slice_from_s(z, 6, s_5); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 5, s_6); /* <-, line 115 */ + { int ret = slice_from_s(z, 5, s_6); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 5, s_7); /* <-, line 117 */ + { int ret = slice_from_s(z, 5, s_7); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 5, s_8); /* <-, line 119 */ + { int ret = slice_from_s(z, 5, s_8); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 5, s_9); /* <-, line 121 */ + { int ret = slice_from_s(z, 5, s_9); if (ret < 0) return ret; } break; @@ -1112,24 +1112,24 @@ static int r_izenak(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_adjetiboak(struct SN_env * z) { /* backwardmode */ +static int r_adjetiboak(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 126 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((35362 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 126 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((35362 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_2, 19); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 126 */ - switch (among_var) { /* among, line 126 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 129 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 129 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 131 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; @@ -1137,17 +1137,16 @@ static int r_adjetiboak(struct SN_env * z) { /* backwardmode */ return 1; } -extern int basque_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - /* do, line 138 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 138 */ +extern int basque_ISO_8859_1_stem(struct SN_env * z) { + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 139 */ + z->lb = z->c; z->c = z->l; -/* repeat, line 140 */ - - while(1) { int m1 = z->l - z->c; (void)m1; - { int ret = r_aditzak(z); /* call aditzak, line 140 */ + while(1) { + int m1 = z->l - z->c; (void)m1; + { int ret = r_aditzak(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1156,10 +1155,9 @@ extern int basque_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ z->c = z->l - m1; break; } -/* repeat, line 141 */ - - while(1) { int m2 = z->l - z->c; (void)m2; - { int ret = r_izenak(z); /* call izenak, line 141 */ + while(1) { + int m2 = z->l - z->c; (void)m2; + { int ret = r_izenak(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } @@ -1168,8 +1166,8 @@ extern int basque_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ z->c = z->l - m2; break; } - { int m3 = z->l - z->c; (void)m3; /* do, line 142 */ - { int ret = r_adjetiboak(z); /* call adjetiboak, line 142 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_adjetiboak(z); if (ret < 0) return ret; } z->c = z->l - m3; @@ -1178,7 +1176,7 @@ extern int basque_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * basque_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * basque_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void basque_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_catalan.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_catalan.c index 87c0cada3df9..283d2c648211 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_catalan.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_catalan.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -44,19 +44,19 @@ static const symbol s_0_12[1] = { 0xFC }; static const struct among a_0[13] = { -/* 0 */ { 0, 0, -1, 7, 0}, -/* 1 */ { 1, s_0_1, 0, 6, 0}, -/* 2 */ { 1, s_0_2, 0, 1, 0}, -/* 3 */ { 1, s_0_3, 0, 1, 0}, -/* 4 */ { 1, s_0_4, 0, 2, 0}, -/* 5 */ { 1, s_0_5, 0, 2, 0}, -/* 6 */ { 1, s_0_6, 0, 3, 0}, -/* 7 */ { 1, s_0_7, 0, 3, 0}, -/* 8 */ { 1, s_0_8, 0, 3, 0}, -/* 9 */ { 1, s_0_9, 0, 4, 0}, -/* 10 */ { 1, s_0_10, 0, 4, 0}, -/* 11 */ { 1, s_0_11, 0, 5, 0}, -/* 12 */ { 1, s_0_12, 0, 5, 0} +{ 0, 0, -1, 7, 0}, +{ 1, s_0_1, 0, 6, 0}, +{ 1, s_0_2, 0, 1, 0}, +{ 1, s_0_3, 0, 1, 0}, +{ 1, s_0_4, 0, 2, 0}, +{ 1, s_0_5, 0, 2, 0}, +{ 1, s_0_6, 0, 3, 0}, +{ 1, s_0_7, 0, 3, 0}, +{ 1, s_0_8, 0, 3, 0}, +{ 1, s_0_9, 0, 4, 0}, +{ 1, s_0_10, 0, 4, 0}, +{ 1, s_0_11, 0, 5, 0}, +{ 1, s_0_12, 0, 5, 0} }; static const symbol s_1_0[2] = { 'l', 'a' }; @@ -101,45 +101,45 @@ static const symbol s_1_38[2] = { '\'', 't' }; static const struct among a_1[39] = { -/* 0 */ { 2, s_1_0, -1, 1, 0}, -/* 1 */ { 3, s_1_1, 0, 1, 0}, -/* 2 */ { 4, s_1_2, 0, 1, 0}, -/* 3 */ { 2, s_1_3, -1, 1, 0}, -/* 4 */ { 2, s_1_4, -1, 1, 0}, -/* 5 */ { 3, s_1_5, 4, 1, 0}, -/* 6 */ { 2, s_1_6, -1, 1, 0}, -/* 7 */ { 3, s_1_7, -1, 1, 0}, -/* 8 */ { 2, s_1_8, -1, 1, 0}, -/* 9 */ { 3, s_1_9, 8, 1, 0}, -/* 10 */ { 2, s_1_10, -1, 1, 0}, -/* 11 */ { 3, s_1_11, 10, 1, 0}, -/* 12 */ { 2, s_1_12, -1, 1, 0}, -/* 13 */ { 2, s_1_13, -1, 1, 0}, -/* 14 */ { 2, s_1_14, -1, 1, 0}, -/* 15 */ { 2, s_1_15, -1, 1, 0}, -/* 16 */ { 2, s_1_16, -1, 1, 0}, -/* 17 */ { 2, s_1_17, -1, 1, 0}, -/* 18 */ { 3, s_1_18, 17, 1, 0}, -/* 19 */ { 2, s_1_19, -1, 1, 0}, -/* 20 */ { 4, s_1_20, 19, 1, 0}, -/* 21 */ { 2, s_1_21, -1, 1, 0}, -/* 22 */ { 3, s_1_22, -1, 1, 0}, -/* 23 */ { 5, s_1_23, 22, 1, 0}, -/* 24 */ { 3, s_1_24, -1, 1, 0}, -/* 25 */ { 4, s_1_25, 24, 1, 0}, -/* 26 */ { 3, s_1_26, -1, 1, 0}, -/* 27 */ { 3, s_1_27, -1, 1, 0}, -/* 28 */ { 3, s_1_28, -1, 1, 0}, -/* 29 */ { 3, s_1_29, -1, 1, 0}, -/* 30 */ { 3, s_1_30, -1, 1, 0}, -/* 31 */ { 3, s_1_31, -1, 1, 0}, -/* 32 */ { 5, s_1_32, 31, 1, 0}, -/* 33 */ { 3, s_1_33, -1, 1, 0}, -/* 34 */ { 4, s_1_34, 33, 1, 0}, -/* 35 */ { 3, s_1_35, -1, 1, 0}, -/* 36 */ { 2, s_1_36, -1, 1, 0}, -/* 37 */ { 3, s_1_37, 36, 1, 0}, -/* 38 */ { 2, s_1_38, -1, 1, 0} +{ 2, s_1_0, -1, 1, 0}, +{ 3, s_1_1, 0, 1, 0}, +{ 4, s_1_2, 0, 1, 0}, +{ 2, s_1_3, -1, 1, 0}, +{ 2, s_1_4, -1, 1, 0}, +{ 3, s_1_5, 4, 1, 0}, +{ 2, s_1_6, -1, 1, 0}, +{ 3, s_1_7, -1, 1, 0}, +{ 2, s_1_8, -1, 1, 0}, +{ 3, s_1_9, 8, 1, 0}, +{ 2, s_1_10, -1, 1, 0}, +{ 3, s_1_11, 10, 1, 0}, +{ 2, s_1_12, -1, 1, 0}, +{ 2, s_1_13, -1, 1, 0}, +{ 2, s_1_14, -1, 1, 0}, +{ 2, s_1_15, -1, 1, 0}, +{ 2, s_1_16, -1, 1, 0}, +{ 2, s_1_17, -1, 1, 0}, +{ 3, s_1_18, 17, 1, 0}, +{ 2, s_1_19, -1, 1, 0}, +{ 4, s_1_20, 19, 1, 0}, +{ 2, s_1_21, -1, 1, 0}, +{ 3, s_1_22, -1, 1, 0}, +{ 5, s_1_23, 22, 1, 0}, +{ 3, s_1_24, -1, 1, 0}, +{ 4, s_1_25, 24, 1, 0}, +{ 3, s_1_26, -1, 1, 0}, +{ 3, s_1_27, -1, 1, 0}, +{ 3, s_1_28, -1, 1, 0}, +{ 3, s_1_29, -1, 1, 0}, +{ 3, s_1_30, -1, 1, 0}, +{ 3, s_1_31, -1, 1, 0}, +{ 5, s_1_32, 31, 1, 0}, +{ 3, s_1_33, -1, 1, 0}, +{ 4, s_1_34, 33, 1, 0}, +{ 3, s_1_35, -1, 1, 0}, +{ 2, s_1_36, -1, 1, 0}, +{ 3, s_1_37, 36, 1, 0}, +{ 2, s_1_38, -1, 1, 0} }; static const symbol s_2_0[3] = { 'i', 'c', 'a' }; @@ -345,206 +345,206 @@ static const symbol s_2_199[4] = { 'a', 'c', 'i', 0xF3 }; static const struct among a_2[200] = { -/* 0 */ { 3, s_2_0, -1, 4, 0}, -/* 1 */ { 6, s_2_1, 0, 3, 0}, -/* 2 */ { 4, s_2_2, -1, 1, 0}, -/* 3 */ { 3, s_2_3, -1, 2, 0}, -/* 4 */ { 5, s_2_4, -1, 1, 0}, -/* 5 */ { 5, s_2_5, -1, 1, 0}, -/* 6 */ { 5, s_2_6, -1, 1, 0}, -/* 7 */ { 4, s_2_7, -1, 1, 0}, -/* 8 */ { 5, s_2_8, -1, 3, 0}, -/* 9 */ { 4, s_2_9, -1, 1, 0}, -/* 10 */ { 5, s_2_10, 9, 1, 0}, -/* 11 */ { 4, s_2_11, -1, 1, 0}, -/* 12 */ { 4, s_2_12, -1, 1, 0}, -/* 13 */ { 6, s_2_13, -1, 1, 0}, -/* 14 */ { 4, s_2_14, -1, 1, 0}, -/* 15 */ { 4, s_2_15, -1, 1, 0}, -/* 16 */ { 5, s_2_16, -1, 1, 0}, -/* 17 */ { 3, s_2_17, -1, 1, 0}, -/* 18 */ { 6, s_2_18, 17, 1, 0}, -/* 19 */ { 8, s_2_19, 18, 5, 0}, -/* 20 */ { 3, s_2_20, -1, 1, 0}, -/* 21 */ { 3, s_2_21, -1, 1, 0}, -/* 22 */ { 3, s_2_22, -1, 1, 0}, -/* 23 */ { 5, s_2_23, 22, 1, 0}, -/* 24 */ { 3, s_2_24, -1, 1, 0}, -/* 25 */ { 4, s_2_25, 24, 1, 0}, -/* 26 */ { 5, s_2_26, 25, 1, 0}, -/* 27 */ { 5, s_2_27, -1, 1, 0}, -/* 28 */ { 3, s_2_28, -1, 1, 0}, -/* 29 */ { 3, s_2_29, -1, 1, 0}, -/* 30 */ { 4, s_2_30, -1, 1, 0}, -/* 31 */ { 4, s_2_31, -1, 1, 0}, -/* 32 */ { 4, s_2_32, -1, 1, 0}, -/* 33 */ { 3, s_2_33, -1, 1, 0}, -/* 34 */ { 3, s_2_34, -1, 1, 0}, -/* 35 */ { 3, s_2_35, -1, 1, 0}, -/* 36 */ { 4, s_2_36, -1, 1, 0}, -/* 37 */ { 7, s_2_37, 36, 1, 0}, -/* 38 */ { 7, s_2_38, 36, 1, 0}, -/* 39 */ { 3, s_2_39, -1, 1, 0}, -/* 40 */ { 5, s_2_40, 39, 1, 0}, -/* 41 */ { 3, s_2_41, -1, 1, 0}, -/* 42 */ { 5, s_2_42, -1, 3, 0}, -/* 43 */ { 2, s_2_43, -1, 4, 0}, -/* 44 */ { 5, s_2_44, 43, 1, 0}, -/* 45 */ { 3, s_2_45, -1, 1, 0}, -/* 46 */ { 3, s_2_46, -1, 1, 0}, -/* 47 */ { 2, s_2_47, -1, 1, 0}, -/* 48 */ { 4, s_2_48, -1, 1, 0}, -/* 49 */ { 3, s_2_49, -1, 1, 0}, -/* 50 */ { 4, s_2_50, 49, 1, 0}, -/* 51 */ { 4, s_2_51, 49, 1, 0}, -/* 52 */ { 4, s_2_52, -1, 1, 0}, -/* 53 */ { 7, s_2_53, 52, 1, 0}, -/* 54 */ { 7, s_2_54, 52, 1, 0}, -/* 55 */ { 6, s_2_55, 52, 1, 0}, -/* 56 */ { 4, s_2_56, -1, 1, 0}, -/* 57 */ { 4, s_2_57, -1, 1, 0}, -/* 58 */ { 4, s_2_58, -1, 1, 0}, -/* 59 */ { 3, s_2_59, -1, 1, 0}, -/* 60 */ { 3, s_2_60, -1, 1, 0}, -/* 61 */ { 4, s_2_61, -1, 3, 0}, -/* 62 */ { 3, s_2_62, -1, 1, 0}, -/* 63 */ { 4, s_2_63, -1, 1, 0}, -/* 64 */ { 2, s_2_64, -1, 1, 0}, -/* 65 */ { 2, s_2_65, -1, 1, 0}, -/* 66 */ { 3, s_2_66, -1, 1, 0}, -/* 67 */ { 3, s_2_67, -1, 1, 0}, -/* 68 */ { 4, s_2_68, -1, 1, 0}, -/* 69 */ { 4, s_2_69, -1, 1, 0}, -/* 70 */ { 5, s_2_70, -1, 1, 0}, -/* 71 */ { 5, s_2_71, -1, 1, 0}, -/* 72 */ { 5, s_2_72, -1, 1, 0}, -/* 73 */ { 5, s_2_73, -1, 1, 0}, -/* 74 */ { 7, s_2_74, 73, 5, 0}, -/* 75 */ { 4, s_2_75, -1, 1, 0}, -/* 76 */ { 5, s_2_76, -1, 1, 0}, -/* 77 */ { 2, s_2_77, -1, 1, 0}, -/* 78 */ { 6, s_2_78, 77, 1, 0}, -/* 79 */ { 4, s_2_79, 77, 1, 0}, -/* 80 */ { 4, s_2_80, 77, 1, 0}, -/* 81 */ { 4, s_2_81, 77, 1, 0}, -/* 82 */ { 5, s_2_82, 77, 1, 0}, -/* 83 */ { 3, s_2_83, -1, 1, 0}, -/* 84 */ { 2, s_2_84, -1, 1, 0}, -/* 85 */ { 3, s_2_85, 84, 1, 0}, -/* 86 */ { 3, s_2_86, -1, 1, 0}, -/* 87 */ { 5, s_2_87, -1, 1, 0}, -/* 88 */ { 3, s_2_88, -1, 4, 0}, -/* 89 */ { 6, s_2_89, 88, 3, 0}, -/* 90 */ { 3, s_2_90, -1, 1, 0}, -/* 91 */ { 4, s_2_91, -1, 1, 0}, -/* 92 */ { 4, s_2_92, -1, 2, 0}, -/* 93 */ { 6, s_2_93, -1, 1, 0}, -/* 94 */ { 6, s_2_94, -1, 1, 0}, -/* 95 */ { 6, s_2_95, -1, 1, 0}, -/* 96 */ { 5, s_2_96, -1, 1, 0}, -/* 97 */ { 6, s_2_97, -1, 3, 0}, -/* 98 */ { 5, s_2_98, -1, 1, 0}, -/* 99 */ { 5, s_2_99, -1, 1, 0}, -/*100 */ { 5, s_2_100, -1, 1, 0}, -/*101 */ { 5, s_2_101, -1, 1, 0}, -/*102 */ { 7, s_2_102, -1, 1, 0}, -/*103 */ { 4, s_2_103, -1, 1, 0}, -/*104 */ { 5, s_2_104, 103, 1, 0}, -/*105 */ { 5, s_2_105, 103, 1, 0}, -/*106 */ { 4, s_2_106, -1, 1, 0}, -/*107 */ { 7, s_2_107, 106, 1, 0}, -/*108 */ { 9, s_2_108, 107, 5, 0}, -/*109 */ { 6, s_2_109, -1, 1, 0}, -/*110 */ { 5, s_2_110, -1, 1, 0}, -/*111 */ { 8, s_2_111, 110, 1, 0}, -/*112 */ { 4, s_2_112, -1, 1, 0}, -/*113 */ { 4, s_2_113, -1, 1, 0}, -/*114 */ { 4, s_2_114, -1, 1, 0}, -/*115 */ { 5, s_2_115, 114, 1, 0}, -/*116 */ { 6, s_2_116, 115, 1, 0}, -/*117 */ { 5, s_2_117, -1, 1, 0}, -/*118 */ { 4, s_2_118, -1, 1, 0}, -/*119 */ { 4, s_2_119, -1, 1, 0}, -/*120 */ { 5, s_2_120, -1, 1, 0}, -/*121 */ { 5, s_2_121, -1, 1, 0}, -/*122 */ { 4, s_2_122, -1, 1, 0}, -/*123 */ { 4, s_2_123, -1, 1, 0}, -/*124 */ { 5, s_2_124, -1, 1, 0}, -/*125 */ { 8, s_2_125, 124, 1, 0}, -/*126 */ { 8, s_2_126, 124, 1, 0}, -/*127 */ { 5, s_2_127, -1, 4, 0}, -/*128 */ { 8, s_2_128, 127, 3, 0}, -/*129 */ { 4, s_2_129, -1, 1, 0}, -/*130 */ { 6, s_2_130, 129, 1, 0}, -/*131 */ { 6, s_2_131, -1, 3, 0}, -/*132 */ { 9, s_2_132, -1, 1, 0}, -/*133 */ { 4, s_2_133, -1, 1, 0}, -/*134 */ { 4, s_2_134, -1, 1, 0}, -/*135 */ { 5, s_2_135, -1, 3, 0}, -/*136 */ { 4, s_2_136, -1, 1, 0}, -/*137 */ { 5, s_2_137, -1, 1, 0}, -/*138 */ { 2, s_2_138, -1, 1, 0}, -/*139 */ { 3, s_2_139, 138, 1, 0}, -/*140 */ { 4, s_2_140, 138, 1, 0}, -/*141 */ { 3, s_2_141, -1, 1, 0}, -/*142 */ { 6, s_2_142, 141, 1, 0}, -/*143 */ { 8, s_2_143, 142, 5, 0}, -/*144 */ { 4, s_2_144, -1, 1, 0}, -/*145 */ { 5, s_2_145, 144, 1, 0}, -/*146 */ { 6, s_2_146, 145, 2, 0}, -/*147 */ { 4, s_2_147, -1, 1, 0}, -/*148 */ { 4, s_2_148, -1, 1, 0}, -/*149 */ { 5, s_2_149, -1, 1, 0}, -/*150 */ { 5, s_2_150, -1, 1, 0}, -/*151 */ { 3, s_2_151, -1, 1, 0}, -/*152 */ { 3, s_2_152, -1, 1, 0}, -/*153 */ { 4, s_2_153, 152, 1, 0}, -/*154 */ { 5, s_2_154, 153, 1, 0}, -/*155 */ { 5, s_2_155, 153, 1, 0}, -/*156 */ { 3, s_2_156, -1, 1, 0}, -/*157 */ { 5, s_2_157, 156, 1, 0}, -/*158 */ { 8, s_2_158, 157, 1, 0}, -/*159 */ { 7, s_2_159, 157, 1, 0}, -/*160 */ { 9, s_2_160, 159, 1, 0}, -/*161 */ { 5, s_2_161, 156, 1, 0}, -/*162 */ { 3, s_2_162, -1, 1, 0}, -/*163 */ { 4, s_2_163, -1, 1, 0}, -/*164 */ { 4, s_2_164, -1, 1, 0}, -/*165 */ { 5, s_2_165, 164, 1, 0}, -/*166 */ { 6, s_2_166, 165, 1, 0}, -/*167 */ { 3, s_2_167, -1, 1, 0}, -/*168 */ { 3, s_2_168, -1, 1, 0}, -/*169 */ { 3, s_2_169, -1, 1, 0}, -/*170 */ { 5, s_2_170, 169, 1, 0}, -/*171 */ { 5, s_2_171, 169, 1, 0}, -/*172 */ { 2, s_2_172, -1, 1, 0}, -/*173 */ { 2, s_2_173, -1, 1, 0}, -/*174 */ { 2, s_2_174, -1, 1, 0}, -/*175 */ { 3, s_2_175, 174, 1, 0}, -/*176 */ { 2, s_2_176, -1, 1, 0}, -/*177 */ { 4, s_2_177, -1, 1, 0}, -/*178 */ { 7, s_2_178, 177, 1, 0}, -/*179 */ { 6, s_2_179, 177, 1, 0}, -/*180 */ { 8, s_2_180, 179, 1, 0}, -/*181 */ { 4, s_2_181, -1, 1, 0}, -/*182 */ { 2, s_2_182, -1, 1, 0}, -/*183 */ { 3, s_2_183, -1, 1, 0}, -/*184 */ { 3, s_2_184, -1, 1, 0}, -/*185 */ { 4, s_2_185, 184, 1, 0}, -/*186 */ { 4, s_2_186, 184, 1, 0}, -/*187 */ { 5, s_2_187, 186, 1, 0}, -/*188 */ { 7, s_2_188, 187, 1, 0}, -/*189 */ { 2, s_2_189, -1, 1, 0}, -/*190 */ { 5, s_2_190, -1, 1, 0}, -/*191 */ { 5, s_2_191, -1, 1, 0}, -/*192 */ { 5, s_2_192, -1, 1, 0}, -/*193 */ { 4, s_2_193, -1, 1, 0}, -/*194 */ { 5, s_2_194, -1, 1, 0}, -/*195 */ { 4, s_2_195, -1, 1, 0}, -/*196 */ { 1, s_2_196, -1, 1, 0}, -/*197 */ { 2, s_2_197, 196, 1, 0}, -/*198 */ { 3, s_2_198, 197, 1, 0}, -/*199 */ { 4, s_2_199, 198, 1, 0} +{ 3, s_2_0, -1, 4, 0}, +{ 6, s_2_1, 0, 3, 0}, +{ 4, s_2_2, -1, 1, 0}, +{ 3, s_2_3, -1, 2, 0}, +{ 5, s_2_4, -1, 1, 0}, +{ 5, s_2_5, -1, 1, 0}, +{ 5, s_2_6, -1, 1, 0}, +{ 4, s_2_7, -1, 1, 0}, +{ 5, s_2_8, -1, 3, 0}, +{ 4, s_2_9, -1, 1, 0}, +{ 5, s_2_10, 9, 1, 0}, +{ 4, s_2_11, -1, 1, 0}, +{ 4, s_2_12, -1, 1, 0}, +{ 6, s_2_13, -1, 1, 0}, +{ 4, s_2_14, -1, 1, 0}, +{ 4, s_2_15, -1, 1, 0}, +{ 5, s_2_16, -1, 1, 0}, +{ 3, s_2_17, -1, 1, 0}, +{ 6, s_2_18, 17, 1, 0}, +{ 8, s_2_19, 18, 5, 0}, +{ 3, s_2_20, -1, 1, 0}, +{ 3, s_2_21, -1, 1, 0}, +{ 3, s_2_22, -1, 1, 0}, +{ 5, s_2_23, 22, 1, 0}, +{ 3, s_2_24, -1, 1, 0}, +{ 4, s_2_25, 24, 1, 0}, +{ 5, s_2_26, 25, 1, 0}, +{ 5, s_2_27, -1, 1, 0}, +{ 3, s_2_28, -1, 1, 0}, +{ 3, s_2_29, -1, 1, 0}, +{ 4, s_2_30, -1, 1, 0}, +{ 4, s_2_31, -1, 1, 0}, +{ 4, s_2_32, -1, 1, 0}, +{ 3, s_2_33, -1, 1, 0}, +{ 3, s_2_34, -1, 1, 0}, +{ 3, s_2_35, -1, 1, 0}, +{ 4, s_2_36, -1, 1, 0}, +{ 7, s_2_37, 36, 1, 0}, +{ 7, s_2_38, 36, 1, 0}, +{ 3, s_2_39, -1, 1, 0}, +{ 5, s_2_40, 39, 1, 0}, +{ 3, s_2_41, -1, 1, 0}, +{ 5, s_2_42, -1, 3, 0}, +{ 2, s_2_43, -1, 4, 0}, +{ 5, s_2_44, 43, 1, 0}, +{ 3, s_2_45, -1, 1, 0}, +{ 3, s_2_46, -1, 1, 0}, +{ 2, s_2_47, -1, 1, 0}, +{ 4, s_2_48, -1, 1, 0}, +{ 3, s_2_49, -1, 1, 0}, +{ 4, s_2_50, 49, 1, 0}, +{ 4, s_2_51, 49, 1, 0}, +{ 4, s_2_52, -1, 1, 0}, +{ 7, s_2_53, 52, 1, 0}, +{ 7, s_2_54, 52, 1, 0}, +{ 6, s_2_55, 52, 1, 0}, +{ 4, s_2_56, -1, 1, 0}, +{ 4, s_2_57, -1, 1, 0}, +{ 4, s_2_58, -1, 1, 0}, +{ 3, s_2_59, -1, 1, 0}, +{ 3, s_2_60, -1, 1, 0}, +{ 4, s_2_61, -1, 3, 0}, +{ 3, s_2_62, -1, 1, 0}, +{ 4, s_2_63, -1, 1, 0}, +{ 2, s_2_64, -1, 1, 0}, +{ 2, s_2_65, -1, 1, 0}, +{ 3, s_2_66, -1, 1, 0}, +{ 3, s_2_67, -1, 1, 0}, +{ 4, s_2_68, -1, 1, 0}, +{ 4, s_2_69, -1, 1, 0}, +{ 5, s_2_70, -1, 1, 0}, +{ 5, s_2_71, -1, 1, 0}, +{ 5, s_2_72, -1, 1, 0}, +{ 5, s_2_73, -1, 1, 0}, +{ 7, s_2_74, 73, 5, 0}, +{ 4, s_2_75, -1, 1, 0}, +{ 5, s_2_76, -1, 1, 0}, +{ 2, s_2_77, -1, 1, 0}, +{ 6, s_2_78, 77, 1, 0}, +{ 4, s_2_79, 77, 1, 0}, +{ 4, s_2_80, 77, 1, 0}, +{ 4, s_2_81, 77, 1, 0}, +{ 5, s_2_82, 77, 1, 0}, +{ 3, s_2_83, -1, 1, 0}, +{ 2, s_2_84, -1, 1, 0}, +{ 3, s_2_85, 84, 1, 0}, +{ 3, s_2_86, -1, 1, 0}, +{ 5, s_2_87, -1, 1, 0}, +{ 3, s_2_88, -1, 4, 0}, +{ 6, s_2_89, 88, 3, 0}, +{ 3, s_2_90, -1, 1, 0}, +{ 4, s_2_91, -1, 1, 0}, +{ 4, s_2_92, -1, 2, 0}, +{ 6, s_2_93, -1, 1, 0}, +{ 6, s_2_94, -1, 1, 0}, +{ 6, s_2_95, -1, 1, 0}, +{ 5, s_2_96, -1, 1, 0}, +{ 6, s_2_97, -1, 3, 0}, +{ 5, s_2_98, -1, 1, 0}, +{ 5, s_2_99, -1, 1, 0}, +{ 5, s_2_100, -1, 1, 0}, +{ 5, s_2_101, -1, 1, 0}, +{ 7, s_2_102, -1, 1, 0}, +{ 4, s_2_103, -1, 1, 0}, +{ 5, s_2_104, 103, 1, 0}, +{ 5, s_2_105, 103, 1, 0}, +{ 4, s_2_106, -1, 1, 0}, +{ 7, s_2_107, 106, 1, 0}, +{ 9, s_2_108, 107, 5, 0}, +{ 6, s_2_109, -1, 1, 0}, +{ 5, s_2_110, -1, 1, 0}, +{ 8, s_2_111, 110, 1, 0}, +{ 4, s_2_112, -1, 1, 0}, +{ 4, s_2_113, -1, 1, 0}, +{ 4, s_2_114, -1, 1, 0}, +{ 5, s_2_115, 114, 1, 0}, +{ 6, s_2_116, 115, 1, 0}, +{ 5, s_2_117, -1, 1, 0}, +{ 4, s_2_118, -1, 1, 0}, +{ 4, s_2_119, -1, 1, 0}, +{ 5, s_2_120, -1, 1, 0}, +{ 5, s_2_121, -1, 1, 0}, +{ 4, s_2_122, -1, 1, 0}, +{ 4, s_2_123, -1, 1, 0}, +{ 5, s_2_124, -1, 1, 0}, +{ 8, s_2_125, 124, 1, 0}, +{ 8, s_2_126, 124, 1, 0}, +{ 5, s_2_127, -1, 4, 0}, +{ 8, s_2_128, 127, 3, 0}, +{ 4, s_2_129, -1, 1, 0}, +{ 6, s_2_130, 129, 1, 0}, +{ 6, s_2_131, -1, 3, 0}, +{ 9, s_2_132, -1, 1, 0}, +{ 4, s_2_133, -1, 1, 0}, +{ 4, s_2_134, -1, 1, 0}, +{ 5, s_2_135, -1, 3, 0}, +{ 4, s_2_136, -1, 1, 0}, +{ 5, s_2_137, -1, 1, 0}, +{ 2, s_2_138, -1, 1, 0}, +{ 3, s_2_139, 138, 1, 0}, +{ 4, s_2_140, 138, 1, 0}, +{ 3, s_2_141, -1, 1, 0}, +{ 6, s_2_142, 141, 1, 0}, +{ 8, s_2_143, 142, 5, 0}, +{ 4, s_2_144, -1, 1, 0}, +{ 5, s_2_145, 144, 1, 0}, +{ 6, s_2_146, 145, 2, 0}, +{ 4, s_2_147, -1, 1, 0}, +{ 4, s_2_148, -1, 1, 0}, +{ 5, s_2_149, -1, 1, 0}, +{ 5, s_2_150, -1, 1, 0}, +{ 3, s_2_151, -1, 1, 0}, +{ 3, s_2_152, -1, 1, 0}, +{ 4, s_2_153, 152, 1, 0}, +{ 5, s_2_154, 153, 1, 0}, +{ 5, s_2_155, 153, 1, 0}, +{ 3, s_2_156, -1, 1, 0}, +{ 5, s_2_157, 156, 1, 0}, +{ 8, s_2_158, 157, 1, 0}, +{ 7, s_2_159, 157, 1, 0}, +{ 9, s_2_160, 159, 1, 0}, +{ 5, s_2_161, 156, 1, 0}, +{ 3, s_2_162, -1, 1, 0}, +{ 4, s_2_163, -1, 1, 0}, +{ 4, s_2_164, -1, 1, 0}, +{ 5, s_2_165, 164, 1, 0}, +{ 6, s_2_166, 165, 1, 0}, +{ 3, s_2_167, -1, 1, 0}, +{ 3, s_2_168, -1, 1, 0}, +{ 3, s_2_169, -1, 1, 0}, +{ 5, s_2_170, 169, 1, 0}, +{ 5, s_2_171, 169, 1, 0}, +{ 2, s_2_172, -1, 1, 0}, +{ 2, s_2_173, -1, 1, 0}, +{ 2, s_2_174, -1, 1, 0}, +{ 3, s_2_175, 174, 1, 0}, +{ 2, s_2_176, -1, 1, 0}, +{ 4, s_2_177, -1, 1, 0}, +{ 7, s_2_178, 177, 1, 0}, +{ 6, s_2_179, 177, 1, 0}, +{ 8, s_2_180, 179, 1, 0}, +{ 4, s_2_181, -1, 1, 0}, +{ 2, s_2_182, -1, 1, 0}, +{ 3, s_2_183, -1, 1, 0}, +{ 3, s_2_184, -1, 1, 0}, +{ 4, s_2_185, 184, 1, 0}, +{ 4, s_2_186, 184, 1, 0}, +{ 5, s_2_187, 186, 1, 0}, +{ 7, s_2_188, 187, 1, 0}, +{ 2, s_2_189, -1, 1, 0}, +{ 5, s_2_190, -1, 1, 0}, +{ 5, s_2_191, -1, 1, 0}, +{ 5, s_2_192, -1, 1, 0}, +{ 4, s_2_193, -1, 1, 0}, +{ 5, s_2_194, -1, 1, 0}, +{ 4, s_2_195, -1, 1, 0}, +{ 1, s_2_196, -1, 1, 0}, +{ 2, s_2_197, 196, 1, 0}, +{ 3, s_2_198, 197, 1, 0}, +{ 4, s_2_199, 198, 1, 0} }; static const symbol s_3_0[3] = { 'a', 'b', 'a' }; @@ -833,289 +833,289 @@ static const symbol s_3_282[2] = { 'i', 0xF3 }; static const struct among a_3[283] = { -/* 0 */ { 3, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 4, s_3_2, -1, 1, 0}, -/* 3 */ { 4, s_3_3, -1, 1, 0}, -/* 4 */ { 3, s_3_4, -1, 1, 0}, -/* 5 */ { 3, s_3_5, -1, 1, 0}, -/* 6 */ { 3, s_3_6, -1, 1, 0}, -/* 7 */ { 3, s_3_7, -1, 1, 0}, -/* 8 */ { 2, s_3_8, -1, 1, 0}, -/* 9 */ { 4, s_3_9, 8, 1, 0}, -/* 10 */ { 4, s_3_10, 8, 1, 0}, -/* 11 */ { 3, s_3_11, -1, 1, 0}, -/* 12 */ { 4, s_3_12, -1, 1, 0}, -/* 13 */ { 3, s_3_13, -1, 1, 0}, -/* 14 */ { 5, s_3_14, -1, 1, 0}, -/* 15 */ { 3, s_3_15, -1, 1, 0}, -/* 16 */ { 3, s_3_16, -1, 1, 0}, -/* 17 */ { 3, s_3_17, -1, 1, 0}, -/* 18 */ { 4, s_3_18, -1, 1, 0}, -/* 19 */ { 2, s_3_19, -1, 1, 0}, -/* 20 */ { 4, s_3_20, 19, 1, 0}, -/* 21 */ { 4, s_3_21, 19, 1, 0}, -/* 22 */ { 4, s_3_22, 19, 1, 0}, -/* 23 */ { 2, s_3_23, -1, 1, 0}, -/* 24 */ { 3, s_3_24, -1, 1, 0}, -/* 25 */ { 3, s_3_25, -1, 1, 0}, -/* 26 */ { 2, s_3_26, -1, 1, 0}, -/* 27 */ { 2, s_3_27, -1, 1, 0}, -/* 28 */ { 2, s_3_28, -1, 1, 0}, -/* 29 */ { 2, s_3_29, -1, 1, 0}, -/* 30 */ { 2, s_3_30, -1, 1, 0}, -/* 31 */ { 3, s_3_31, 30, 1, 0}, -/* 32 */ { 3, s_3_32, -1, 1, 0}, -/* 33 */ { 4, s_3_33, -1, 1, 0}, -/* 34 */ { 4, s_3_34, -1, 1, 0}, -/* 35 */ { 4, s_3_35, -1, 1, 0}, -/* 36 */ { 2, s_3_36, -1, 1, 0}, -/* 37 */ { 3, s_3_37, -1, 1, 0}, -/* 38 */ { 5, s_3_38, -1, 1, 0}, -/* 39 */ { 4, s_3_39, -1, 1, 0}, -/* 40 */ { 4, s_3_40, -1, 1, 0}, -/* 41 */ { 2, s_3_41, -1, 1, 0}, -/* 42 */ { 2, s_3_42, -1, 1, 0}, -/* 43 */ { 4, s_3_43, 42, 1, 0}, -/* 44 */ { 4, s_3_44, 42, 1, 0}, -/* 45 */ { 4, s_3_45, 42, 1, 0}, -/* 46 */ { 4, s_3_46, 42, 1, 0}, -/* 47 */ { 5, s_3_47, 42, 1, 0}, -/* 48 */ { 5, s_3_48, 42, 1, 0}, -/* 49 */ { 5, s_3_49, 42, 1, 0}, -/* 50 */ { 5, s_3_50, 42, 1, 0}, -/* 51 */ { 4, s_3_51, 42, 1, 0}, -/* 52 */ { 4, s_3_52, 42, 1, 0}, -/* 53 */ { 4, s_3_53, 42, 1, 0}, -/* 54 */ { 5, s_3_54, 42, 1, 0}, -/* 55 */ { 3, s_3_55, 42, 1, 0}, -/* 56 */ { 5, s_3_56, 55, 1, 0}, -/* 57 */ { 5, s_3_57, 55, 1, 0}, -/* 58 */ { 5, s_3_58, -1, 1, 0}, -/* 59 */ { 5, s_3_59, -1, 1, 0}, -/* 60 */ { 5, s_3_60, -1, 1, 0}, -/* 61 */ { 5, s_3_61, -1, 1, 0}, -/* 62 */ { 5, s_3_62, -1, 1, 0}, -/* 63 */ { 5, s_3_63, -1, 1, 0}, -/* 64 */ { 5, s_3_64, -1, 1, 0}, -/* 65 */ { 2, s_3_65, -1, 1, 0}, -/* 66 */ { 2, s_3_66, -1, 1, 0}, -/* 67 */ { 4, s_3_67, 66, 1, 0}, -/* 68 */ { 5, s_3_68, 66, 1, 0}, -/* 69 */ { 4, s_3_69, 66, 1, 0}, -/* 70 */ { 5, s_3_70, 66, 1, 0}, -/* 71 */ { 4, s_3_71, 66, 1, 0}, -/* 72 */ { 3, s_3_72, 66, 1, 0}, -/* 73 */ { 5, s_3_73, 72, 1, 0}, -/* 74 */ { 5, s_3_74, 72, 1, 0}, -/* 75 */ { 5, s_3_75, 72, 1, 0}, -/* 76 */ { 2, s_3_76, -1, 1, 0}, -/* 77 */ { 3, s_3_77, 76, 1, 0}, -/* 78 */ { 5, s_3_78, 77, 1, 0}, -/* 79 */ { 5, s_3_79, 77, 1, 0}, -/* 80 */ { 4, s_3_80, 76, 1, 0}, -/* 81 */ { 4, s_3_81, 76, 1, 0}, -/* 82 */ { 4, s_3_82, 76, 1, 0}, -/* 83 */ { 4, s_3_83, 76, 1, 0}, -/* 84 */ { 4, s_3_84, 76, 1, 0}, -/* 85 */ { 4, s_3_85, 76, 1, 0}, -/* 86 */ { 5, s_3_86, 76, 1, 0}, -/* 87 */ { 5, s_3_87, 76, 1, 0}, -/* 88 */ { 5, s_3_88, 76, 1, 0}, -/* 89 */ { 5, s_3_89, 76, 1, 0}, -/* 90 */ { 5, s_3_90, 76, 1, 0}, -/* 91 */ { 5, s_3_91, 76, 1, 0}, -/* 92 */ { 6, s_3_92, 76, 1, 0}, -/* 93 */ { 6, s_3_93, 76, 1, 0}, -/* 94 */ { 6, s_3_94, 76, 1, 0}, -/* 95 */ { 4, s_3_95, 76, 1, 0}, -/* 96 */ { 4, s_3_96, 76, 1, 0}, -/* 97 */ { 5, s_3_97, 96, 1, 0}, -/* 98 */ { 4, s_3_98, 76, 1, 0}, -/* 99 */ { 3, s_3_99, 76, 1, 0}, -/*100 */ { 2, s_3_100, -1, 1, 0}, -/*101 */ { 4, s_3_101, 100, 1, 0}, -/*102 */ { 3, s_3_102, 100, 1, 0}, -/*103 */ { 4, s_3_103, 102, 1, 0}, -/*104 */ { 5, s_3_104, 102, 1, 0}, -/*105 */ { 5, s_3_105, 102, 1, 0}, -/*106 */ { 5, s_3_106, 102, 1, 0}, -/*107 */ { 5, s_3_107, 102, 1, 0}, -/*108 */ { 6, s_3_108, 100, 1, 0}, -/*109 */ { 5, s_3_109, 100, 1, 0}, -/*110 */ { 4, s_3_110, -1, 1, 0}, -/*111 */ { 5, s_3_111, -1, 1, 0}, -/*112 */ { 4, s_3_112, -1, 1, 0}, -/*113 */ { 4, s_3_113, -1, 1, 0}, -/*114 */ { 4, s_3_114, -1, 1, 0}, -/*115 */ { 3, s_3_115, -1, 1, 0}, -/*116 */ { 3, s_3_116, -1, 1, 0}, -/*117 */ { 3, s_3_117, -1, 1, 0}, -/*118 */ { 4, s_3_118, -1, 2, 0}, -/*119 */ { 5, s_3_119, -1, 1, 0}, -/*120 */ { 2, s_3_120, -1, 1, 0}, -/*121 */ { 3, s_3_121, -1, 1, 0}, -/*122 */ { 4, s_3_122, 121, 1, 0}, -/*123 */ { 3, s_3_123, -1, 1, 0}, -/*124 */ { 4, s_3_124, -1, 1, 0}, -/*125 */ { 2, s_3_125, -1, 1, 0}, -/*126 */ { 4, s_3_126, 125, 1, 0}, -/*127 */ { 2, s_3_127, -1, 1, 0}, -/*128 */ { 5, s_3_128, 127, 1, 0}, -/*129 */ { 2, s_3_129, -1, 1, 0}, -/*130 */ { 4, s_3_130, -1, 1, 0}, -/*131 */ { 2, s_3_131, -1, 1, 0}, -/*132 */ { 4, s_3_132, 131, 1, 0}, -/*133 */ { 4, s_3_133, 131, 1, 0}, -/*134 */ { 4, s_3_134, 131, 1, 0}, -/*135 */ { 4, s_3_135, 131, 1, 0}, -/*136 */ { 5, s_3_136, 131, 1, 0}, -/*137 */ { 3, s_3_137, 131, 1, 0}, -/*138 */ { 5, s_3_138, 137, 1, 0}, -/*139 */ { 5, s_3_139, 137, 1, 0}, -/*140 */ { 5, s_3_140, 137, 1, 0}, -/*141 */ { 3, s_3_141, -1, 1, 0}, -/*142 */ { 2, s_3_142, -1, 1, 0}, -/*143 */ { 4, s_3_143, 142, 1, 0}, -/*144 */ { 4, s_3_144, 142, 1, 0}, -/*145 */ { 4, s_3_145, 142, 1, 0}, -/*146 */ { 4, s_3_146, 142, 1, 0}, -/*147 */ { 5, s_3_147, 142, 1, 0}, -/*148 */ { 3, s_3_148, 142, 1, 0}, -/*149 */ { 5, s_3_149, 148, 1, 0}, -/*150 */ { 5, s_3_150, 148, 1, 0}, -/*151 */ { 4, s_3_151, 142, 1, 0}, -/*152 */ { 4, s_3_152, 142, 1, 0}, -/*153 */ { 6, s_3_153, 142, 1, 0}, -/*154 */ { 4, s_3_154, 142, 1, 0}, -/*155 */ { 4, s_3_155, 142, 1, 0}, -/*156 */ { 5, s_3_156, 142, 1, 0}, -/*157 */ { 5, s_3_157, 142, 1, 0}, -/*158 */ { 5, s_3_158, 142, 1, 0}, -/*159 */ { 5, s_3_159, 142, 1, 0}, -/*160 */ { 5, s_3_160, 142, 1, 0}, -/*161 */ { 4, s_3_161, 142, 1, 0}, -/*162 */ { 6, s_3_162, 161, 1, 0}, -/*163 */ { 6, s_3_163, 161, 1, 0}, -/*164 */ { 4, s_3_164, 142, 1, 0}, -/*165 */ { 4, s_3_165, 142, 1, 0}, -/*166 */ { 5, s_3_166, 165, 1, 0}, -/*167 */ { 4, s_3_167, 142, 1, 0}, -/*168 */ { 3, s_3_168, 142, 1, 0}, -/*169 */ { 5, s_3_169, -1, 1, 0}, -/*170 */ { 5, s_3_170, -1, 1, 0}, -/*171 */ { 6, s_3_171, -1, 1, 0}, -/*172 */ { 4, s_3_172, -1, 1, 0}, -/*173 */ { 6, s_3_173, 172, 1, 0}, -/*174 */ { 6, s_3_174, 172, 1, 0}, -/*175 */ { 6, s_3_175, 172, 1, 0}, -/*176 */ { 5, s_3_176, -1, 1, 0}, -/*177 */ { 6, s_3_177, -1, 1, 0}, -/*178 */ { 6, s_3_178, -1, 1, 0}, -/*179 */ { 6, s_3_179, -1, 1, 0}, -/*180 */ { 4, s_3_180, -1, 1, 0}, -/*181 */ { 3, s_3_181, -1, 1, 0}, -/*182 */ { 4, s_3_182, 181, 1, 0}, -/*183 */ { 5, s_3_183, 181, 1, 0}, -/*184 */ { 5, s_3_184, 181, 1, 0}, -/*185 */ { 5, s_3_185, 181, 1, 0}, -/*186 */ { 5, s_3_186, 181, 1, 0}, -/*187 */ { 6, s_3_187, -1, 1, 0}, -/*188 */ { 5, s_3_188, -1, 1, 0}, -/*189 */ { 5, s_3_189, -1, 1, 0}, -/*190 */ { 3, s_3_190, -1, 1, 0}, -/*191 */ { 5, s_3_191, -1, 1, 0}, -/*192 */ { 5, s_3_192, -1, 1, 0}, -/*193 */ { 5, s_3_193, -1, 1, 0}, -/*194 */ { 3, s_3_194, -1, 1, 0}, -/*195 */ { 4, s_3_195, -1, 1, 0}, -/*196 */ { 4, s_3_196, -1, 1, 0}, -/*197 */ { 4, s_3_197, -1, 1, 0}, -/*198 */ { 6, s_3_198, 197, 1, 0}, -/*199 */ { 6, s_3_199, 197, 1, 0}, -/*200 */ { 7, s_3_200, 197, 1, 0}, -/*201 */ { 5, s_3_201, 197, 1, 0}, -/*202 */ { 7, s_3_202, 201, 1, 0}, -/*203 */ { 7, s_3_203, 201, 1, 0}, -/*204 */ { 7, s_3_204, 201, 1, 0}, -/*205 */ { 6, s_3_205, -1, 1, 0}, -/*206 */ { 6, s_3_206, -1, 1, 0}, -/*207 */ { 6, s_3_207, -1, 1, 0}, -/*208 */ { 6, s_3_208, -1, 1, 0}, -/*209 */ { 7, s_3_209, -1, 1, 0}, -/*210 */ { 4, s_3_210, -1, 1, 0}, -/*211 */ { 5, s_3_211, -1, 1, 0}, -/*212 */ { 3, s_3_212, -1, 1, 0}, -/*213 */ { 5, s_3_213, 212, 1, 0}, -/*214 */ { 3, s_3_214, -1, 1, 0}, -/*215 */ { 3, s_3_215, -1, 1, 0}, -/*216 */ { 3, s_3_216, -1, 1, 0}, -/*217 */ { 4, s_3_217, -1, 1, 0}, -/*218 */ { 2, s_3_218, -1, 1, 0}, -/*219 */ { 4, s_3_219, 218, 1, 0}, -/*220 */ { 4, s_3_220, 218, 1, 0}, -/*221 */ { 4, s_3_221, -1, 1, 0}, -/*222 */ { 4, s_3_222, -1, 1, 0}, -/*223 */ { 4, s_3_223, -1, 1, 0}, -/*224 */ { 2, s_3_224, -1, 1, 0}, -/*225 */ { 4, s_3_225, 224, 1, 0}, -/*226 */ { 2, s_3_226, -1, 1, 0}, -/*227 */ { 3, s_3_227, -1, 1, 0}, -/*228 */ { 2, s_3_228, -1, 1, 0}, -/*229 */ { 2, s_3_229, -1, 1, 0}, -/*230 */ { 3, s_3_230, -1, 1, 0}, -/*231 */ { 3, s_3_231, -1, 1, 0}, -/*232 */ { 3, s_3_232, -1, 1, 0}, -/*233 */ { 2, s_3_233, -1, 1, 0}, -/*234 */ { 2, s_3_234, -1, 1, 0}, -/*235 */ { 2, s_3_235, -1, 1, 0}, -/*236 */ { 4, s_3_236, 235, 1, 0}, -/*237 */ { 3, s_3_237, -1, 1, 0}, -/*238 */ { 4, s_3_238, -1, 1, 0}, -/*239 */ { 4, s_3_239, -1, 1, 0}, -/*240 */ { 4, s_3_240, -1, 1, 0}, -/*241 */ { 4, s_3_241, -1, 1, 0}, -/*242 */ { 4, s_3_242, -1, 1, 0}, -/*243 */ { 5, s_3_243, -1, 1, 0}, -/*244 */ { 5, s_3_244, -1, 1, 0}, -/*245 */ { 7, s_3_245, 244, 1, 0}, -/*246 */ { 5, s_3_246, -1, 1, 0}, -/*247 */ { 5, s_3_247, -1, 1, 0}, -/*248 */ { 5, s_3_248, -1, 1, 0}, -/*249 */ { 5, s_3_249, -1, 1, 0}, -/*250 */ { 4, s_3_250, -1, 1, 0}, -/*251 */ { 4, s_3_251, -1, 1, 0}, -/*252 */ { 5, s_3_252, -1, 1, 0}, -/*253 */ { 3, s_3_253, -1, 1, 0}, -/*254 */ { 5, s_3_254, 253, 1, 0}, -/*255 */ { 3, s_3_255, -1, 1, 0}, -/*256 */ { 5, s_3_256, 255, 1, 0}, -/*257 */ { 5, s_3_257, 255, 1, 0}, -/*258 */ { 5, s_3_258, -1, 1, 0}, -/*259 */ { 5, s_3_259, -1, 1, 0}, -/*260 */ { 5, s_3_260, -1, 1, 0}, -/*261 */ { 5, s_3_261, -1, 1, 0}, -/*262 */ { 5, s_3_262, -1, 1, 0}, -/*263 */ { 5, s_3_263, -1, 1, 0}, -/*264 */ { 2, s_3_264, -1, 1, 0}, -/*265 */ { 2, s_3_265, -1, 1, 0}, -/*266 */ { 3, s_3_266, 265, 1, 0}, -/*267 */ { 2, s_3_267, -1, 1, 0}, -/*268 */ { 3, s_3_268, -1, 1, 0}, -/*269 */ { 2, s_3_269, -1, 1, 0}, -/*270 */ { 3, s_3_270, -1, 1, 0}, -/*271 */ { 3, s_3_271, -1, 1, 0}, -/*272 */ { 4, s_3_272, -1, 1, 0}, -/*273 */ { 3, s_3_273, -1, 1, 0}, -/*274 */ { 3, s_3_274, -1, 1, 0}, -/*275 */ { 3, s_3_275, -1, 1, 0}, -/*276 */ { 3, s_3_276, -1, 1, 0}, -/*277 */ { 3, s_3_277, -1, 1, 0}, -/*278 */ { 3, s_3_278, -1, 1, 0}, -/*279 */ { 3, s_3_279, -1, 1, 0}, -/*280 */ { 1, s_3_280, -1, 1, 0}, -/*281 */ { 2, s_3_281, -1, 1, 0}, -/*282 */ { 2, s_3_282, -1, 1, 0} +{ 3, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 4, s_3_2, -1, 1, 0}, +{ 4, s_3_3, -1, 1, 0}, +{ 3, s_3_4, -1, 1, 0}, +{ 3, s_3_5, -1, 1, 0}, +{ 3, s_3_6, -1, 1, 0}, +{ 3, s_3_7, -1, 1, 0}, +{ 2, s_3_8, -1, 1, 0}, +{ 4, s_3_9, 8, 1, 0}, +{ 4, s_3_10, 8, 1, 0}, +{ 3, s_3_11, -1, 1, 0}, +{ 4, s_3_12, -1, 1, 0}, +{ 3, s_3_13, -1, 1, 0}, +{ 5, s_3_14, -1, 1, 0}, +{ 3, s_3_15, -1, 1, 0}, +{ 3, s_3_16, -1, 1, 0}, +{ 3, s_3_17, -1, 1, 0}, +{ 4, s_3_18, -1, 1, 0}, +{ 2, s_3_19, -1, 1, 0}, +{ 4, s_3_20, 19, 1, 0}, +{ 4, s_3_21, 19, 1, 0}, +{ 4, s_3_22, 19, 1, 0}, +{ 2, s_3_23, -1, 1, 0}, +{ 3, s_3_24, -1, 1, 0}, +{ 3, s_3_25, -1, 1, 0}, +{ 2, s_3_26, -1, 1, 0}, +{ 2, s_3_27, -1, 1, 0}, +{ 2, s_3_28, -1, 1, 0}, +{ 2, s_3_29, -1, 1, 0}, +{ 2, s_3_30, -1, 1, 0}, +{ 3, s_3_31, 30, 1, 0}, +{ 3, s_3_32, -1, 1, 0}, +{ 4, s_3_33, -1, 1, 0}, +{ 4, s_3_34, -1, 1, 0}, +{ 4, s_3_35, -1, 1, 0}, +{ 2, s_3_36, -1, 1, 0}, +{ 3, s_3_37, -1, 1, 0}, +{ 5, s_3_38, -1, 1, 0}, +{ 4, s_3_39, -1, 1, 0}, +{ 4, s_3_40, -1, 1, 0}, +{ 2, s_3_41, -1, 1, 0}, +{ 2, s_3_42, -1, 1, 0}, +{ 4, s_3_43, 42, 1, 0}, +{ 4, s_3_44, 42, 1, 0}, +{ 4, s_3_45, 42, 1, 0}, +{ 4, s_3_46, 42, 1, 0}, +{ 5, s_3_47, 42, 1, 0}, +{ 5, s_3_48, 42, 1, 0}, +{ 5, s_3_49, 42, 1, 0}, +{ 5, s_3_50, 42, 1, 0}, +{ 4, s_3_51, 42, 1, 0}, +{ 4, s_3_52, 42, 1, 0}, +{ 4, s_3_53, 42, 1, 0}, +{ 5, s_3_54, 42, 1, 0}, +{ 3, s_3_55, 42, 1, 0}, +{ 5, s_3_56, 55, 1, 0}, +{ 5, s_3_57, 55, 1, 0}, +{ 5, s_3_58, -1, 1, 0}, +{ 5, s_3_59, -1, 1, 0}, +{ 5, s_3_60, -1, 1, 0}, +{ 5, s_3_61, -1, 1, 0}, +{ 5, s_3_62, -1, 1, 0}, +{ 5, s_3_63, -1, 1, 0}, +{ 5, s_3_64, -1, 1, 0}, +{ 2, s_3_65, -1, 1, 0}, +{ 2, s_3_66, -1, 1, 0}, +{ 4, s_3_67, 66, 1, 0}, +{ 5, s_3_68, 66, 1, 0}, +{ 4, s_3_69, 66, 1, 0}, +{ 5, s_3_70, 66, 1, 0}, +{ 4, s_3_71, 66, 1, 0}, +{ 3, s_3_72, 66, 1, 0}, +{ 5, s_3_73, 72, 1, 0}, +{ 5, s_3_74, 72, 1, 0}, +{ 5, s_3_75, 72, 1, 0}, +{ 2, s_3_76, -1, 1, 0}, +{ 3, s_3_77, 76, 1, 0}, +{ 5, s_3_78, 77, 1, 0}, +{ 5, s_3_79, 77, 1, 0}, +{ 4, s_3_80, 76, 1, 0}, +{ 4, s_3_81, 76, 1, 0}, +{ 4, s_3_82, 76, 1, 0}, +{ 4, s_3_83, 76, 1, 0}, +{ 4, s_3_84, 76, 1, 0}, +{ 4, s_3_85, 76, 1, 0}, +{ 5, s_3_86, 76, 1, 0}, +{ 5, s_3_87, 76, 1, 0}, +{ 5, s_3_88, 76, 1, 0}, +{ 5, s_3_89, 76, 1, 0}, +{ 5, s_3_90, 76, 1, 0}, +{ 5, s_3_91, 76, 1, 0}, +{ 6, s_3_92, 76, 1, 0}, +{ 6, s_3_93, 76, 1, 0}, +{ 6, s_3_94, 76, 1, 0}, +{ 4, s_3_95, 76, 1, 0}, +{ 4, s_3_96, 76, 1, 0}, +{ 5, s_3_97, 96, 1, 0}, +{ 4, s_3_98, 76, 1, 0}, +{ 3, s_3_99, 76, 1, 0}, +{ 2, s_3_100, -1, 1, 0}, +{ 4, s_3_101, 100, 1, 0}, +{ 3, s_3_102, 100, 1, 0}, +{ 4, s_3_103, 102, 1, 0}, +{ 5, s_3_104, 102, 1, 0}, +{ 5, s_3_105, 102, 1, 0}, +{ 5, s_3_106, 102, 1, 0}, +{ 5, s_3_107, 102, 1, 0}, +{ 6, s_3_108, 100, 1, 0}, +{ 5, s_3_109, 100, 1, 0}, +{ 4, s_3_110, -1, 1, 0}, +{ 5, s_3_111, -1, 1, 0}, +{ 4, s_3_112, -1, 1, 0}, +{ 4, s_3_113, -1, 1, 0}, +{ 4, s_3_114, -1, 1, 0}, +{ 3, s_3_115, -1, 1, 0}, +{ 3, s_3_116, -1, 1, 0}, +{ 3, s_3_117, -1, 1, 0}, +{ 4, s_3_118, -1, 2, 0}, +{ 5, s_3_119, -1, 1, 0}, +{ 2, s_3_120, -1, 1, 0}, +{ 3, s_3_121, -1, 1, 0}, +{ 4, s_3_122, 121, 1, 0}, +{ 3, s_3_123, -1, 1, 0}, +{ 4, s_3_124, -1, 1, 0}, +{ 2, s_3_125, -1, 1, 0}, +{ 4, s_3_126, 125, 1, 0}, +{ 2, s_3_127, -1, 1, 0}, +{ 5, s_3_128, 127, 1, 0}, +{ 2, s_3_129, -1, 1, 0}, +{ 4, s_3_130, -1, 1, 0}, +{ 2, s_3_131, -1, 1, 0}, +{ 4, s_3_132, 131, 1, 0}, +{ 4, s_3_133, 131, 1, 0}, +{ 4, s_3_134, 131, 1, 0}, +{ 4, s_3_135, 131, 1, 0}, +{ 5, s_3_136, 131, 1, 0}, +{ 3, s_3_137, 131, 1, 0}, +{ 5, s_3_138, 137, 1, 0}, +{ 5, s_3_139, 137, 1, 0}, +{ 5, s_3_140, 137, 1, 0}, +{ 3, s_3_141, -1, 1, 0}, +{ 2, s_3_142, -1, 1, 0}, +{ 4, s_3_143, 142, 1, 0}, +{ 4, s_3_144, 142, 1, 0}, +{ 4, s_3_145, 142, 1, 0}, +{ 4, s_3_146, 142, 1, 0}, +{ 5, s_3_147, 142, 1, 0}, +{ 3, s_3_148, 142, 1, 0}, +{ 5, s_3_149, 148, 1, 0}, +{ 5, s_3_150, 148, 1, 0}, +{ 4, s_3_151, 142, 1, 0}, +{ 4, s_3_152, 142, 1, 0}, +{ 6, s_3_153, 142, 1, 0}, +{ 4, s_3_154, 142, 1, 0}, +{ 4, s_3_155, 142, 1, 0}, +{ 5, s_3_156, 142, 1, 0}, +{ 5, s_3_157, 142, 1, 0}, +{ 5, s_3_158, 142, 1, 0}, +{ 5, s_3_159, 142, 1, 0}, +{ 5, s_3_160, 142, 1, 0}, +{ 4, s_3_161, 142, 1, 0}, +{ 6, s_3_162, 161, 1, 0}, +{ 6, s_3_163, 161, 1, 0}, +{ 4, s_3_164, 142, 1, 0}, +{ 4, s_3_165, 142, 1, 0}, +{ 5, s_3_166, 165, 1, 0}, +{ 4, s_3_167, 142, 1, 0}, +{ 3, s_3_168, 142, 1, 0}, +{ 5, s_3_169, -1, 1, 0}, +{ 5, s_3_170, -1, 1, 0}, +{ 6, s_3_171, -1, 1, 0}, +{ 4, s_3_172, -1, 1, 0}, +{ 6, s_3_173, 172, 1, 0}, +{ 6, s_3_174, 172, 1, 0}, +{ 6, s_3_175, 172, 1, 0}, +{ 5, s_3_176, -1, 1, 0}, +{ 6, s_3_177, -1, 1, 0}, +{ 6, s_3_178, -1, 1, 0}, +{ 6, s_3_179, -1, 1, 0}, +{ 4, s_3_180, -1, 1, 0}, +{ 3, s_3_181, -1, 1, 0}, +{ 4, s_3_182, 181, 1, 0}, +{ 5, s_3_183, 181, 1, 0}, +{ 5, s_3_184, 181, 1, 0}, +{ 5, s_3_185, 181, 1, 0}, +{ 5, s_3_186, 181, 1, 0}, +{ 6, s_3_187, -1, 1, 0}, +{ 5, s_3_188, -1, 1, 0}, +{ 5, s_3_189, -1, 1, 0}, +{ 3, s_3_190, -1, 1, 0}, +{ 5, s_3_191, -1, 1, 0}, +{ 5, s_3_192, -1, 1, 0}, +{ 5, s_3_193, -1, 1, 0}, +{ 3, s_3_194, -1, 1, 0}, +{ 4, s_3_195, -1, 1, 0}, +{ 4, s_3_196, -1, 1, 0}, +{ 4, s_3_197, -1, 1, 0}, +{ 6, s_3_198, 197, 1, 0}, +{ 6, s_3_199, 197, 1, 0}, +{ 7, s_3_200, 197, 1, 0}, +{ 5, s_3_201, 197, 1, 0}, +{ 7, s_3_202, 201, 1, 0}, +{ 7, s_3_203, 201, 1, 0}, +{ 7, s_3_204, 201, 1, 0}, +{ 6, s_3_205, -1, 1, 0}, +{ 6, s_3_206, -1, 1, 0}, +{ 6, s_3_207, -1, 1, 0}, +{ 6, s_3_208, -1, 1, 0}, +{ 7, s_3_209, -1, 1, 0}, +{ 4, s_3_210, -1, 1, 0}, +{ 5, s_3_211, -1, 1, 0}, +{ 3, s_3_212, -1, 1, 0}, +{ 5, s_3_213, 212, 1, 0}, +{ 3, s_3_214, -1, 1, 0}, +{ 3, s_3_215, -1, 1, 0}, +{ 3, s_3_216, -1, 1, 0}, +{ 4, s_3_217, -1, 1, 0}, +{ 2, s_3_218, -1, 1, 0}, +{ 4, s_3_219, 218, 1, 0}, +{ 4, s_3_220, 218, 1, 0}, +{ 4, s_3_221, -1, 1, 0}, +{ 4, s_3_222, -1, 1, 0}, +{ 4, s_3_223, -1, 1, 0}, +{ 2, s_3_224, -1, 1, 0}, +{ 4, s_3_225, 224, 1, 0}, +{ 2, s_3_226, -1, 1, 0}, +{ 3, s_3_227, -1, 1, 0}, +{ 2, s_3_228, -1, 1, 0}, +{ 2, s_3_229, -1, 1, 0}, +{ 3, s_3_230, -1, 1, 0}, +{ 3, s_3_231, -1, 1, 0}, +{ 3, s_3_232, -1, 1, 0}, +{ 2, s_3_233, -1, 1, 0}, +{ 2, s_3_234, -1, 1, 0}, +{ 2, s_3_235, -1, 1, 0}, +{ 4, s_3_236, 235, 1, 0}, +{ 3, s_3_237, -1, 1, 0}, +{ 4, s_3_238, -1, 1, 0}, +{ 4, s_3_239, -1, 1, 0}, +{ 4, s_3_240, -1, 1, 0}, +{ 4, s_3_241, -1, 1, 0}, +{ 4, s_3_242, -1, 1, 0}, +{ 5, s_3_243, -1, 1, 0}, +{ 5, s_3_244, -1, 1, 0}, +{ 7, s_3_245, 244, 1, 0}, +{ 5, s_3_246, -1, 1, 0}, +{ 5, s_3_247, -1, 1, 0}, +{ 5, s_3_248, -1, 1, 0}, +{ 5, s_3_249, -1, 1, 0}, +{ 4, s_3_250, -1, 1, 0}, +{ 4, s_3_251, -1, 1, 0}, +{ 5, s_3_252, -1, 1, 0}, +{ 3, s_3_253, -1, 1, 0}, +{ 5, s_3_254, 253, 1, 0}, +{ 3, s_3_255, -1, 1, 0}, +{ 5, s_3_256, 255, 1, 0}, +{ 5, s_3_257, 255, 1, 0}, +{ 5, s_3_258, -1, 1, 0}, +{ 5, s_3_259, -1, 1, 0}, +{ 5, s_3_260, -1, 1, 0}, +{ 5, s_3_261, -1, 1, 0}, +{ 5, s_3_262, -1, 1, 0}, +{ 5, s_3_263, -1, 1, 0}, +{ 2, s_3_264, -1, 1, 0}, +{ 2, s_3_265, -1, 1, 0}, +{ 3, s_3_266, 265, 1, 0}, +{ 2, s_3_267, -1, 1, 0}, +{ 3, s_3_268, -1, 1, 0}, +{ 2, s_3_269, -1, 1, 0}, +{ 3, s_3_270, -1, 1, 0}, +{ 3, s_3_271, -1, 1, 0}, +{ 4, s_3_272, -1, 1, 0}, +{ 3, s_3_273, -1, 1, 0}, +{ 3, s_3_274, -1, 1, 0}, +{ 3, s_3_275, -1, 1, 0}, +{ 3, s_3_276, -1, 1, 0}, +{ 3, s_3_277, -1, 1, 0}, +{ 3, s_3_278, -1, 1, 0}, +{ 3, s_3_279, -1, 1, 0}, +{ 1, s_3_280, -1, 1, 0}, +{ 2, s_3_281, -1, 1, 0}, +{ 2, s_3_282, -1, 1, 0} }; static const symbol s_4_0[1] = { 'a' }; @@ -1143,28 +1143,28 @@ static const symbol s_4_21[1] = { 0xF3 }; static const struct among a_4[22] = { -/* 0 */ { 1, s_4_0, -1, 1, 0}, -/* 1 */ { 1, s_4_1, -1, 1, 0}, -/* 2 */ { 1, s_4_2, -1, 1, 0}, -/* 3 */ { 2, s_4_3, -1, 1, 0}, -/* 4 */ { 1, s_4_4, -1, 1, 0}, -/* 5 */ { 2, s_4_5, -1, 1, 0}, -/* 6 */ { 1, s_4_6, -1, 1, 0}, -/* 7 */ { 2, s_4_7, 6, 1, 0}, -/* 8 */ { 2, s_4_8, 6, 1, 0}, -/* 9 */ { 2, s_4_9, 6, 1, 0}, -/* 10 */ { 2, s_4_10, -1, 1, 0}, -/* 11 */ { 2, s_4_11, -1, 1, 0}, -/* 12 */ { 2, s_4_12, -1, 1, 0}, -/* 13 */ { 3, s_4_13, -1, 2, 0}, -/* 14 */ { 3, s_4_14, -1, 1, 0}, -/* 15 */ { 1, s_4_15, -1, 1, 0}, -/* 16 */ { 1, s_4_16, -1, 1, 0}, -/* 17 */ { 1, s_4_17, -1, 1, 0}, -/* 18 */ { 1, s_4_18, -1, 1, 0}, -/* 19 */ { 1, s_4_19, -1, 1, 0}, -/* 20 */ { 1, s_4_20, -1, 1, 0}, -/* 21 */ { 1, s_4_21, -1, 1, 0} +{ 1, s_4_0, -1, 1, 0}, +{ 1, s_4_1, -1, 1, 0}, +{ 1, s_4_2, -1, 1, 0}, +{ 2, s_4_3, -1, 1, 0}, +{ 1, s_4_4, -1, 1, 0}, +{ 2, s_4_5, -1, 1, 0}, +{ 1, s_4_6, -1, 1, 0}, +{ 2, s_4_7, 6, 1, 0}, +{ 2, s_4_8, 6, 1, 0}, +{ 2, s_4_9, 6, 1, 0}, +{ 2, s_4_10, -1, 1, 0}, +{ 2, s_4_11, -1, 1, 0}, +{ 2, s_4_12, -1, 1, 0}, +{ 3, s_4_13, -1, 2, 0}, +{ 3, s_4_14, -1, 1, 0}, +{ 1, s_4_15, -1, 1, 0}, +{ 1, s_4_16, -1, 1, 0}, +{ 1, s_4_17, -1, 1, 0}, +{ 1, s_4_18, -1, 1, 0}, +{ 1, s_4_19, -1, 1, 0}, +{ 1, s_4_20, -1, 1, 0}, +{ 1, s_4_21, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 129, 81, 6, 10 }; @@ -1180,81 +1180,80 @@ static const symbol s_7[] = { 'i', 'c' }; static const symbol s_8[] = { 'c' }; static const symbol s_9[] = { 'i', 'c' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 38 */ - z->I[1] = z->l; /* $p2 = , line 39 */ - { int c1 = z->c; /* do, line 41 */ - { /* gopast */ /* grouping v, line 42 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 42 */ + { int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 42 */ - { /* gopast */ /* grouping v, line 43 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 43 */ + { int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 43 */ + z->I[0] = z->c; lab0: z->c = c1; } return 1; } -static int r_cleaning(struct SN_env * z) { /* forwardmode */ +static int r_cleaning(struct SN_env * z) { int among_var; -/* repeat, line 47 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 48 */ - among_var = find_among(z, a_0, 13); /* substring, line 48 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + among_var = find_among(z, a_0, 13); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 48 */ - switch (among_var) { /* among, line 48 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 49 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 51 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 53 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 55 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 57 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 7: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 61 */ + z->c++; break; } continue; @@ -1265,74 +1264,74 @@ static int r_cleaning(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 67 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 68 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 71 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1634850 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 71 */ +static int r_attached_pronoun(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1634850 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_1, 39))) return 0; - z->bra = z->c; /* ], line 71 */ - { int ret = r_R1(z); /* call R1, line 81 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 81 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 86 */ - among_var = find_among_b(z, a_2, 200); /* substring, line 86 */ + z->ket = z->c; + among_var = find_among_b(z, a_2, 200); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 86 */ - switch (among_var) { /* among, line 86 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 110 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 112 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 112 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); /* call R2, line 114 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_6); /* <-, line 114 */ + { int ret = slice_from_s(z, 3, s_6); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 116 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_7); /* <-, line 116 */ + { int ret = slice_from_s(z, 2, s_7); if (ret < 0) return ret; } break; case 5: - { int ret = r_R1(z); /* call R1, line 118 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_8); /* <-, line 118 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; @@ -1340,26 +1339,26 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 123 */ - among_var = find_among_b(z, a_3, 283); /* substring, line 123 */ + z->ket = z->c; + among_var = find_among_b(z, a_3, 283); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 123 */ - switch (among_var) { /* among, line 123 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 168 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 168 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 170 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 170 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1367,26 +1366,26 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ +static int r_residual_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 175 */ - among_var = find_among_b(z, a_4, 22); /* substring, line 175 */ + z->ket = z->c; + among_var = find_among_b(z, a_4, 22); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 175 */ - switch (among_var) { /* among, line 175 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 178 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 178 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R1(z); /* call R1, line 180 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_9); /* <-, line 180 */ + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; @@ -1394,29 +1393,29 @@ static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int catalan_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - /* do, line 186 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 186 */ +extern int catalan_ISO_8859_1_stem(struct SN_env * z) { + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 187 */ + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 188 */ - { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 188 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_attached_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 189 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 189 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 189 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m3; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 190 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1425,15 +1424,15 @@ extern int catalan_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 192 */ - { int ret = r_residual_suffix(z); /* call residual_suffix, line 192 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_residual_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; } z->c = z->lb; - { int c5 = z->c; /* do, line 194 */ - { int ret = r_cleaning(z); /* call cleaning, line 194 */ + { int c5 = z->c; + { int ret = r_cleaning(z); if (ret < 0) return ret; } z->c = c5; @@ -1441,7 +1440,7 @@ extern int catalan_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * catalan_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * catalan_ISO_8859_1_create_env(void) { return SN_create_env(0, 2); } extern void catalan_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c index dff225884b8a..88ce5717c706 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -61,38 +61,38 @@ static const symbol s_0_31[4] = { 'e', 'r', 'e', 't' }; static const struct among a_0[32] = { -/* 0 */ { 3, s_0_0, -1, 1, 0}, -/* 1 */ { 5, s_0_1, 0, 1, 0}, -/* 2 */ { 4, s_0_2, -1, 1, 0}, -/* 3 */ { 1, s_0_3, -1, 1, 0}, -/* 4 */ { 5, s_0_4, 3, 1, 0}, -/* 5 */ { 4, s_0_5, 3, 1, 0}, -/* 6 */ { 6, s_0_6, 5, 1, 0}, -/* 7 */ { 3, s_0_7, 3, 1, 0}, -/* 8 */ { 4, s_0_8, 3, 1, 0}, -/* 9 */ { 3, s_0_9, 3, 1, 0}, -/* 10 */ { 2, s_0_10, -1, 1, 0}, -/* 11 */ { 5, s_0_11, 10, 1, 0}, -/* 12 */ { 4, s_0_12, 10, 1, 0}, -/* 13 */ { 2, s_0_13, -1, 1, 0}, -/* 14 */ { 5, s_0_14, 13, 1, 0}, -/* 15 */ { 4, s_0_15, 13, 1, 0}, -/* 16 */ { 1, s_0_16, -1, 2, 0}, -/* 17 */ { 4, s_0_17, 16, 1, 0}, -/* 18 */ { 2, s_0_18, 16, 1, 0}, -/* 19 */ { 5, s_0_19, 18, 1, 0}, -/* 20 */ { 7, s_0_20, 19, 1, 0}, -/* 21 */ { 4, s_0_21, 18, 1, 0}, -/* 22 */ { 5, s_0_22, 18, 1, 0}, -/* 23 */ { 4, s_0_23, 18, 1, 0}, -/* 24 */ { 3, s_0_24, 16, 1, 0}, -/* 25 */ { 6, s_0_25, 24, 1, 0}, -/* 26 */ { 5, s_0_26, 24, 1, 0}, -/* 27 */ { 3, s_0_27, 16, 1, 0}, -/* 28 */ { 3, s_0_28, 16, 1, 0}, -/* 29 */ { 5, s_0_29, 28, 1, 0}, -/* 30 */ { 2, s_0_30, -1, 1, 0}, -/* 31 */ { 4, s_0_31, 30, 1, 0} +{ 3, s_0_0, -1, 1, 0}, +{ 5, s_0_1, 0, 1, 0}, +{ 4, s_0_2, -1, 1, 0}, +{ 1, s_0_3, -1, 1, 0}, +{ 5, s_0_4, 3, 1, 0}, +{ 4, s_0_5, 3, 1, 0}, +{ 6, s_0_6, 5, 1, 0}, +{ 3, s_0_7, 3, 1, 0}, +{ 4, s_0_8, 3, 1, 0}, +{ 3, s_0_9, 3, 1, 0}, +{ 2, s_0_10, -1, 1, 0}, +{ 5, s_0_11, 10, 1, 0}, +{ 4, s_0_12, 10, 1, 0}, +{ 2, s_0_13, -1, 1, 0}, +{ 5, s_0_14, 13, 1, 0}, +{ 4, s_0_15, 13, 1, 0}, +{ 1, s_0_16, -1, 2, 0}, +{ 4, s_0_17, 16, 1, 0}, +{ 2, s_0_18, 16, 1, 0}, +{ 5, s_0_19, 18, 1, 0}, +{ 7, s_0_20, 19, 1, 0}, +{ 4, s_0_21, 18, 1, 0}, +{ 5, s_0_22, 18, 1, 0}, +{ 4, s_0_23, 18, 1, 0}, +{ 3, s_0_24, 16, 1, 0}, +{ 6, s_0_25, 24, 1, 0}, +{ 5, s_0_26, 24, 1, 0}, +{ 3, s_0_27, 16, 1, 0}, +{ 3, s_0_28, 16, 1, 0}, +{ 5, s_0_29, 28, 1, 0}, +{ 2, s_0_30, -1, 1, 0}, +{ 4, s_0_31, 30, 1, 0} }; static const symbol s_1_0[2] = { 'g', 'd' }; @@ -102,10 +102,10 @@ static const symbol s_1_3[2] = { 'k', 't' }; static const struct among a_1[4] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0}, -/* 2 */ { 2, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0}, +{ 2, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0} }; static const symbol s_2_0[2] = { 'i', 'g' }; @@ -116,11 +116,11 @@ static const symbol s_2_4[4] = { 'l', 0xF8, 's', 't' }; static const struct among a_2[5] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 3, s_2_1, 0, 1, 0}, -/* 2 */ { 4, s_2_2, 1, 1, 0}, -/* 3 */ { 3, s_2_3, -1, 1, 0}, -/* 4 */ { 4, s_2_4, -1, 2, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 3, s_2_1, 0, 1, 0}, +{ 4, s_2_2, 1, 1, 0}, +{ 3, s_2_3, -1, 1, 0}, +{ 4, s_2_4, -1, 2, 0} }; static const unsigned char g_c[] = { 119, 223, 119, 1 }; @@ -133,52 +133,50 @@ static const symbol s_0[] = { 's', 't' }; static const symbol s_1[] = { 'i', 'g' }; static const symbol s_2[] = { 'l', 0xF8, 's' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 33 */ - { int c_test1 = z->c; /* test, line 35 */ - { int ret = z->c + 3; /* hop, line 35 */ - if (0 > ret || ret > z->l) return 0; - z->c = ret; - } - z->I[1] = z->c; /* setmark x, line 35 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + { int c_test1 = z->c; +z->c = z->c + 3; + if (z->c > z->l) return 0; + z->I[0] = z->c; z->c = c_test1; } - if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 36 */ - { /* gopast */ /* non v, line 36 */ + if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; + { int ret = in_grouping(z, g_v, 97, 248, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 36 */ - /* try, line 37 */ - if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 37 */ - z->I[0] = z->I[1]; /* $p1 = , line 37 */ + z->I[1] = z->c; + + if (!(z->I[1] < z->I[0])) goto lab0; + z->I[1] = z->I[0]; lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { /* backwardmode */ +static int r_main_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 43 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 43 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 43 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_0, 32); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 43 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 44 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 50 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (in_grouping_b(z, g_s_ending, 97, 229, 0)) return 0; /* grouping s_ending, line 52 */ - { int ret = slice_del(z); /* delete, line 52 */ + if (in_grouping_b(z, g_s_ending, 97, 229, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -186,67 +184,67 @@ static int r_main_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 57 */ +static int r_consonant_pair(struct SN_env * z) { + { int m_test1 = z->l - z->c; - { int mlimit2; /* setlimit, line 58 */ - if (z->c < z->I[0]) return 0; - mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 58 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit2; return 0; } /* substring, line 58 */ + { int mlimit2; + if (z->c < z->I[1]) return 0; + mlimit2 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit2; return 0; } if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit2; return 0; } - z->bra = z->c; /* ], line 58 */ + z->bra = z->c; z->lb = mlimit2; } z->c = z->l - m_test1; } if (z->c <= z->lb) return 0; - z->c--; /* next, line 64 */ - z->bra = z->c; /* ], line 64 */ - { int ret = slice_del(z); /* delete, line 64 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_other_suffix(struct SN_env * z) { /* backwardmode */ +static int r_other_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 68 */ - z->ket = z->c; /* [, line 68 */ - if (!(eq_s_b(z, 2, s_0))) goto lab0; /* literal, line 68 */ - z->bra = z->c; /* ], line 68 */ - if (!(eq_s_b(z, 2, s_1))) goto lab0; /* literal, line 68 */ - { int ret = slice_del(z); /* delete, line 68 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_0))) goto lab0; + z->bra = z->c; + if (!(eq_s_b(z, 2, s_1))) goto lab0; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - { int mlimit2; /* setlimit, line 69 */ - if (z->c < z->I[0]) return 0; - mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 69 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit2; return 0; } /* substring, line 69 */ + { int mlimit2; + if (z->c < z->I[1]) return 0; + mlimit2 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit2; return 0; } among_var = find_among_b(z, a_2, 5); if (!(among_var)) { z->lb = mlimit2; return 0; } - z->bra = z->c; /* ], line 69 */ + z->bra = z->c; z->lb = mlimit2; } - switch (among_var) { /* among, line 70 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 72 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* do, line 72 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 72 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } break; case 2: - { int ret = slice_from_s(z, 3, s_2); /* <-, line 74 */ + { int ret = slice_from_s(z, 3, s_2); if (ret < 0) return ret; } break; @@ -254,54 +252,54 @@ static int r_other_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_undouble(struct SN_env * z) { /* backwardmode */ +static int r_undouble(struct SN_env * z) { - { int mlimit1; /* setlimit, line 78 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 78 */ - if (in_grouping_b(z, g_c, 98, 122, 0)) { z->lb = mlimit1; return 0; } /* grouping c, line 78 */ - z->bra = z->c; /* ], line 78 */ - z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 78 */ - if (z->S[0] == 0) return -1; /* -> ch, line 78 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (in_grouping_b(z, g_c, 98, 122, 0)) { z->lb = mlimit1; return 0; } + z->bra = z->c; + z->S[0] = slice_to(z, z->S[0]); + if (z->S[0] == 0) return -1; z->lb = mlimit1; } - if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 79 */ - { int ret = slice_del(z); /* delete, line 80 */ + if (!(eq_v_b(z, z->S[0]))) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int danish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 86 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 86 */ +extern int danish_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 87 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 88 */ - { int ret = r_main_suffix(z); /* call main_suffix, line 88 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_main_suffix(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 89 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 89 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 90 */ - { int ret = r_other_suffix(z); /* call other_suffix, line 90 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_other_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 91 */ - { int ret = r_undouble(z); /* call undouble, line 91 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_undouble(z); if (ret < 0) return ret; } z->c = z->l - m5; @@ -310,7 +308,7 @@ extern int danish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * danish_ISO_8859_1_create_env(void) { return SN_create_env(1, 2, 0); } +extern struct SN_env * danish_ISO_8859_1_create_env(void) { return SN_create_env(1, 2); } extern void danish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 1); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c index aa33b42df396..08de47a0959c 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -43,17 +43,17 @@ static const symbol s_0_10[1] = { 0xFC }; static const struct among a_0[11] = { -/* 0 */ { 0, 0, -1, 6, 0}, -/* 1 */ { 1, s_0_1, 0, 1, 0}, -/* 2 */ { 1, s_0_2, 0, 1, 0}, -/* 3 */ { 1, s_0_3, 0, 2, 0}, -/* 4 */ { 1, s_0_4, 0, 2, 0}, -/* 5 */ { 1, s_0_5, 0, 3, 0}, -/* 6 */ { 1, s_0_6, 0, 3, 0}, -/* 7 */ { 1, s_0_7, 0, 4, 0}, -/* 8 */ { 1, s_0_8, 0, 4, 0}, -/* 9 */ { 1, s_0_9, 0, 5, 0}, -/* 10 */ { 1, s_0_10, 0, 5, 0} +{ 0, 0, -1, 6, 0}, +{ 1, s_0_1, 0, 1, 0}, +{ 1, s_0_2, 0, 1, 0}, +{ 1, s_0_3, 0, 2, 0}, +{ 1, s_0_4, 0, 2, 0}, +{ 1, s_0_5, 0, 3, 0}, +{ 1, s_0_6, 0, 3, 0}, +{ 1, s_0_7, 0, 4, 0}, +{ 1, s_0_8, 0, 4, 0}, +{ 1, s_0_9, 0, 5, 0}, +{ 1, s_0_10, 0, 5, 0} }; static const symbol s_1_1[1] = { 'I' }; @@ -61,9 +61,9 @@ static const symbol s_1_2[1] = { 'Y' }; static const struct among a_1[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 1, s_1_1, 0, 2, 0}, -/* 2 */ { 1, s_1_2, 0, 1, 0} +{ 0, 0, -1, 3, 0}, +{ 1, s_1_1, 0, 2, 0}, +{ 1, s_1_2, 0, 1, 0} }; static const symbol s_2_0[2] = { 'd', 'd' }; @@ -72,9 +72,9 @@ static const symbol s_2_2[2] = { 't', 't' }; static const struct among a_2[3] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 2, s_2_2, -1, -1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 2, s_2_2, -1, -1, 0} }; static const symbol s_3_0[3] = { 'e', 'n', 'e' }; @@ -85,11 +85,11 @@ static const symbol s_3_4[1] = { 's' }; static const struct among a_3[5] = { -/* 0 */ { 3, s_3_0, -1, 2, 0}, -/* 1 */ { 2, s_3_1, -1, 3, 0}, -/* 2 */ { 2, s_3_2, -1, 2, 0}, -/* 3 */ { 5, s_3_3, 2, 1, 0}, -/* 4 */ { 1, s_3_4, -1, 3, 0} +{ 3, s_3_0, -1, 2, 0}, +{ 2, s_3_1, -1, 3, 0}, +{ 2, s_3_2, -1, 2, 0}, +{ 5, s_3_3, 2, 1, 0}, +{ 1, s_3_4, -1, 3, 0} }; static const symbol s_4_0[3] = { 'e', 'n', 'd' }; @@ -101,12 +101,12 @@ static const symbol s_4_5[3] = { 'b', 'a', 'r' }; static const struct among a_4[6] = { -/* 0 */ { 3, s_4_0, -1, 1, 0}, -/* 1 */ { 2, s_4_1, -1, 2, 0}, -/* 2 */ { 3, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 3, 0}, -/* 4 */ { 4, s_4_4, -1, 4, 0}, -/* 5 */ { 3, s_4_5, -1, 5, 0} +{ 3, s_4_0, -1, 1, 0}, +{ 2, s_4_1, -1, 2, 0}, +{ 3, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 3, 0}, +{ 4, s_4_4, -1, 4, 0}, +{ 3, s_4_5, -1, 5, 0} }; static const symbol s_5_0[2] = { 'a', 'a' }; @@ -116,10 +116,10 @@ static const symbol s_5_3[2] = { 'u', 'u' }; static const struct among a_5[4] = { -/* 0 */ { 2, s_5_0, -1, -1, 0}, -/* 1 */ { 2, s_5_1, -1, -1, 0}, -/* 2 */ { 2, s_5_2, -1, -1, 0}, -/* 3 */ { 2, s_5_3, -1, -1, 0} +{ 2, s_5_0, -1, -1, 0}, +{ 2, s_5_1, -1, -1, 0}, +{ 2, s_5_2, -1, -1, 0}, +{ 2, s_5_3, -1, -1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; @@ -144,46 +144,45 @@ static const symbol s_12[] = { 'h', 'e', 'i', 'd' }; static const symbol s_13[] = { 'e', 'n' }; static const symbol s_14[] = { 'i', 'g' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ +static int r_prelude(struct SN_env * z) { int among_var; - { int c_test1 = z->c; /* test, line 42 */ -/* repeat, line 42 */ - - while(1) { int c2 = z->c; - z->bra = z->c; /* [, line 43 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((340306450 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else /* substring, line 43 */ + { int c_test1 = z->c; + while(1) { + int c2 = z->c; + z->bra = z->c; + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((340306450 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else among_var = find_among(z, a_0, 11); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 43 */ - switch (among_var) { /* among, line 43 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 45 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 47 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 49 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 51 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 53 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 6: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 54 */ + z->c++; break; } continue; @@ -193,39 +192,38 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ } z->c = c_test1; } - { int c3 = z->c; /* try, line 57 */ - z->bra = z->c; /* [, line 57 */ - if (z->c == z->l || z->p[z->c] != 'y') { z->c = c3; goto lab1; } /* literal, line 57 */ + { int c3 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') { z->c = c3; goto lab1; } z->c++; - z->ket = z->c; /* ], line 57 */ - { int ret = slice_from_s(z, 1, s_5); /* <-, line 57 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } lab1: ; } -/* repeat, line 58 */ - - while(1) { int c4 = z->c; - while(1) { /* goto, line 58 */ + while(1) { + int c4 = z->c; + while(1) { int c5 = z->c; - if (in_grouping(z, g_v, 97, 232, 0)) goto lab3; /* grouping v, line 59 */ - z->bra = z->c; /* [, line 59 */ - { int c6 = z->c; /* or, line 59 */ - if (z->c == z->l || z->p[z->c] != 'i') goto lab5; /* literal, line 59 */ + if (in_grouping(z, g_v, 97, 232, 0)) goto lab3; + z->bra = z->c; + { int c6 = z->c; + if (z->c == z->l || z->p[z->c] != 'i') goto lab5; z->c++; - z->ket = z->c; /* ], line 59 */ - if (in_grouping(z, g_v, 97, 232, 0)) goto lab5; /* grouping v, line 59 */ - { int ret = slice_from_s(z, 1, s_6); /* <-, line 59 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 232, 0)) goto lab5; + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } goto lab4; lab5: z->c = c6; - if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 60 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; z->c++; - z->ket = z->c; /* ], line 60 */ - { int ret = slice_from_s(z, 1, s_7); /* <-, line 60 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } } @@ -235,7 +233,7 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ lab3: z->c = c5; if (z->c >= z->l) goto lab2; - z->c++; /* goto, line 58 */ + z->c++; } continue; lab2: @@ -245,62 +243,61 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 66 */ - z->I[1] = z->l; /* $p2 = , line 67 */ - { /* gopast */ /* grouping v, line 69 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int ret = out_grouping(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 69 */ + { int ret = in_grouping(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 69 */ - /* try, line 70 */ - if (!(z->I[0] < 3)) goto lab0; /* $( < ), line 70 */ - z->I[0] = 3; /* $p1 = , line 70 */ + z->I[1] = z->c; + + if (!(z->I[1] < 3)) goto lab0; + z->I[1] = 3; lab0: - { /* gopast */ /* grouping v, line 71 */ + { int ret = out_grouping(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 71 */ + { int ret = in_grouping(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 71 */ + z->I[0] = z->c; return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 75 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 77 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else /* substring, line 77 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 77 */ - switch (among_var) { /* among, line 77 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 78 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; case 3: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 80 */ + z->c++; break; } continue; @@ -311,109 +308,109 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 87 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 88 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_undouble(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 91 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 91 */ +static int r_undouble(struct SN_env * z) { + { int m_test1 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_2, 3))) return 0; z->c = z->l - m_test1; } - z->ket = z->c; /* [, line 91 */ + z->ket = z->c; if (z->c <= z->lb) return 0; - z->c--; /* next, line 91 */ - z->bra = z->c; /* ], line 91 */ - { int ret = slice_del(z); /* delete, line 91 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_e_ending(struct SN_env * z) { /* backwardmode */ - z->B[0] = 0; /* unset e_found, line 95 */ - z->ket = z->c; /* [, line 96 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 96 */ +static int r_e_ending(struct SN_env * z) { + z->I[2] = 0; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; - z->bra = z->c; /* ], line 96 */ - { int ret = r_R1(z); /* call R1, line 96 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m_test1 = z->l - z->c; /* test, line 96 */ - if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; /* non v, line 96 */ + { int m_test1 = z->l - z->c; + if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; z->c = z->l - m_test1; } - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set e_found, line 97 */ - { int ret = r_undouble(z); /* call undouble, line 98 */ + z->I[2] = 1; + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_en_ending(struct SN_env * z) { /* backwardmode */ - { int ret = r_R1(z); /* call R1, line 102 */ +static int r_en_ending(struct SN_env * z) { + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* and, line 102 */ - if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; /* non v, line 102 */ + { int m1 = z->l - z->c; (void)m1; + if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - if (!(eq_s_b(z, 3, s_10))) goto lab0; /* literal, line 102 */ + { int m2 = z->l - z->c; (void)m2; + if (!(eq_s_b(z, 3, s_10))) goto lab0; return 0; lab0: z->c = z->l - m2; } } - { int ret = slice_del(z); /* delete, line 102 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_undouble(z); /* call undouble, line 103 */ + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 107 */ - z->ket = z->c; /* [, line 108 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 108 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; among_var = find_among_b(z, a_3, 5); if (!(among_var)) goto lab0; - z->bra = z->c; /* ], line 108 */ - switch (among_var) { /* among, line 108 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 110 */ + { int ret = r_R1(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } - { int ret = slice_from_s(z, 4, s_11); /* <-, line 110 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 2: - { int ret = r_en_ending(z); /* call en_ending, line 113 */ + { int ret = r_en_ending(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } break; case 3: - { int ret = r_R1(z); /* call R1, line 116 */ + { int ret = r_R1(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } - if (out_grouping_b(z, g_v_j, 97, 232, 0)) goto lab0; /* non v_j, line 116 */ - { int ret = slice_del(z); /* delete, line 116 */ + if (out_grouping_b(z, g_v_j, 97, 232, 0)) goto lab0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -421,77 +418,77 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab0: z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 120 */ - { int ret = r_e_ending(z); /* call e_ending, line 120 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_e_ending(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 122 */ - z->ket = z->c; /* [, line 122 */ - if (!(eq_s_b(z, 4, s_12))) goto lab1; /* literal, line 122 */ - z->bra = z->c; /* ], line 122 */ - { int ret = r_R2(z); /* call R2, line 122 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (!(eq_s_b(z, 4, s_12))) goto lab1; + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* not, line 122 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab2; /* literal, line 122 */ + { int m4 = z->l - z->c; (void)m4; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab2; z->c--; goto lab1; lab2: z->c = z->l - m4; } - { int ret = slice_del(z); /* delete, line 122 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 123 */ - if (!(eq_s_b(z, 2, s_13))) goto lab1; /* literal, line 123 */ - z->bra = z->c; /* ], line 123 */ - { int ret = r_en_ending(z); /* call en_ending, line 123 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_13))) goto lab1; + z->bra = z->c; + { int ret = r_en_ending(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m3; } - { int m5 = z->l - z->c; (void)m5; /* do, line 126 */ - z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; /* substring, line 127 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; among_var = find_among_b(z, a_4, 6); if (!(among_var)) goto lab3; - z->bra = z->c; /* ], line 127 */ - switch (among_var) { /* among, line 127 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 129 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 129 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m6 = z->l - z->c; (void)m6; /* or, line 130 */ - z->ket = z->c; /* [, line 130 */ - if (!(eq_s_b(z, 2, s_14))) goto lab5; /* literal, line 130 */ - z->bra = z->c; /* ], line 130 */ - { int ret = r_R2(z); /* call R2, line 130 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_14))) goto lab5; + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int m7 = z->l - z->c; (void)m7; /* not, line 130 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; /* literal, line 130 */ + { int m7 = z->l - z->c; (void)m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; z->c--; goto lab5; lab6: z->c = z->l - m7; } - { int ret = slice_del(z); /* delete, line 130 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m6; - { int ret = r_undouble(z); /* call undouble, line 130 */ + { int ret = r_undouble(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } @@ -499,50 +496,50 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab4: break; case 2: - { int ret = r_R2(z); /* call R2, line 133 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int m8 = z->l - z->c; (void)m8; /* not, line 133 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab7; /* literal, line 133 */ + { int m8 = z->l - z->c; (void)m8; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab7; z->c--; goto lab3; lab7: z->c = z->l - m8; } - { int ret = slice_del(z); /* delete, line 133 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); /* call R2, line 136 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 136 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_e_ending(z); /* call e_ending, line 136 */ + { int ret = r_e_ending(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 139 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 142 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - if (!(z->B[0])) goto lab3; /* Boolean test e_found, line 142 */ - { int ret = slice_del(z); /* delete, line 142 */ + if (!(z->I[2])) goto lab3; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -550,19 +547,19 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab3: z->c = z->l - m5; } - { int m9 = z->l - z->c; (void)m9; /* do, line 146 */ - if (out_grouping_b(z, g_v_I, 73, 232, 0)) goto lab8; /* non v_I, line 147 */ - { int m_test10 = z->l - z->c; /* test, line 148 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab8; /* among, line 149 */ + { int m9 = z->l - z->c; (void)m9; + if (out_grouping_b(z, g_v_I, 73, 232, 0)) goto lab8; + { int m_test10 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab8; if (!(find_among_b(z, a_5, 4))) goto lab8; - if (out_grouping_b(z, g_v, 97, 232, 0)) goto lab8; /* non v, line 150 */ + if (out_grouping_b(z, g_v, 97, 232, 0)) goto lab8; z->c = z->l - m_test10; } - z->ket = z->c; /* [, line 152 */ + z->ket = z->c; if (z->c <= z->lb) goto lab8; - z->c--; /* next, line 152 */ - z->bra = z->c; /* ], line 152 */ - { int ret = slice_del(z); /* delete, line 152 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab8: @@ -571,28 +568,28 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int dutch_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 159 */ - { int ret = r_prelude(z); /* call prelude, line 159 */ +extern int dutch_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - { int c2 = z->c; /* do, line 160 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 160 */ + { int c2 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c2; } - z->lb = z->c; z->c = z->l; /* backwards, line 161 */ + z->lb = z->c; z->c = z->l; - /* do, line 162 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 162 */ + + { int ret = r_standard_suffix(z); if (ret < 0) return ret; } z->c = z->lb; - { int c3 = z->c; /* do, line 163 */ - { int ret = r_postlude(z); /* call postlude, line 163 */ + { int c3 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c3; @@ -600,7 +597,7 @@ extern int dutch_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * dutch_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); } +extern struct SN_env * dutch_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void dutch_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c index d1f80c6c3b3c..db67d68aed40 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -42,9 +42,9 @@ static const symbol s_0_2[5] = { 'g', 'e', 'n', 'e', 'r' }; static const struct among a_0[3] = { -/* 0 */ { 5, s_0_0, -1, -1, 0}, -/* 1 */ { 6, s_0_1, -1, -1, 0}, -/* 2 */ { 5, s_0_2, -1, -1, 0} +{ 5, s_0_0, -1, -1, 0}, +{ 6, s_0_1, -1, -1, 0}, +{ 5, s_0_2, -1, -1, 0} }; static const symbol s_1_0[1] = { '\'' }; @@ -53,9 +53,9 @@ static const symbol s_1_2[2] = { '\'', 's' }; static const struct among a_1[3] = { -/* 0 */ { 1, s_1_0, -1, 1, 0}, -/* 1 */ { 3, s_1_1, 0, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0} +{ 1, s_1_0, -1, 1, 0}, +{ 3, s_1_1, 0, 1, 0}, +{ 2, s_1_2, -1, 1, 0} }; static const symbol s_2_0[3] = { 'i', 'e', 'd' }; @@ -67,12 +67,12 @@ static const symbol s_2_5[2] = { 'u', 's' }; static const struct among a_2[6] = { -/* 0 */ { 3, s_2_0, -1, 2, 0}, -/* 1 */ { 1, s_2_1, -1, 3, 0}, -/* 2 */ { 3, s_2_2, 1, 2, 0}, -/* 3 */ { 4, s_2_3, 1, 1, 0}, -/* 4 */ { 2, s_2_4, 1, -1, 0}, -/* 5 */ { 2, s_2_5, 1, -1, 0} +{ 3, s_2_0, -1, 2, 0}, +{ 1, s_2_1, -1, 3, 0}, +{ 3, s_2_2, 1, 2, 0}, +{ 4, s_2_3, 1, 1, 0}, +{ 2, s_2_4, 1, -1, 0}, +{ 2, s_2_5, 1, -1, 0} }; static const symbol s_3_1[2] = { 'b', 'b' }; @@ -90,19 +90,19 @@ static const symbol s_3_12[2] = { 'i', 'z' }; static const struct among a_3[13] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 2, s_3_1, 0, 2, 0}, -/* 2 */ { 2, s_3_2, 0, 2, 0}, -/* 3 */ { 2, s_3_3, 0, 2, 0}, -/* 4 */ { 2, s_3_4, 0, 2, 0}, -/* 5 */ { 2, s_3_5, 0, 1, 0}, -/* 6 */ { 2, s_3_6, 0, 2, 0}, -/* 7 */ { 2, s_3_7, 0, 2, 0}, -/* 8 */ { 2, s_3_8, 0, 2, 0}, -/* 9 */ { 2, s_3_9, 0, 2, 0}, -/* 10 */ { 2, s_3_10, 0, 1, 0}, -/* 11 */ { 2, s_3_11, 0, 2, 0}, -/* 12 */ { 2, s_3_12, 0, 1, 0} +{ 0, 0, -1, 3, 0}, +{ 2, s_3_1, 0, 2, 0}, +{ 2, s_3_2, 0, 2, 0}, +{ 2, s_3_3, 0, 2, 0}, +{ 2, s_3_4, 0, 2, 0}, +{ 2, s_3_5, 0, 1, 0}, +{ 2, s_3_6, 0, 2, 0}, +{ 2, s_3_7, 0, 2, 0}, +{ 2, s_3_8, 0, 2, 0}, +{ 2, s_3_9, 0, 2, 0}, +{ 2, s_3_10, 0, 1, 0}, +{ 2, s_3_11, 0, 2, 0}, +{ 2, s_3_12, 0, 1, 0} }; static const symbol s_4_0[2] = { 'e', 'd' }; @@ -114,12 +114,12 @@ static const symbol s_4_5[5] = { 'i', 'n', 'g', 'l', 'y' }; static const struct among a_4[6] = { -/* 0 */ { 2, s_4_0, -1, 2, 0}, -/* 1 */ { 3, s_4_1, 0, 1, 0}, -/* 2 */ { 3, s_4_2, -1, 2, 0}, -/* 3 */ { 4, s_4_3, -1, 2, 0}, -/* 4 */ { 5, s_4_4, 3, 1, 0}, -/* 5 */ { 5, s_4_5, -1, 2, 0} +{ 2, s_4_0, -1, 2, 0}, +{ 3, s_4_1, 0, 1, 0}, +{ 3, s_4_2, -1, 2, 0}, +{ 4, s_4_3, -1, 2, 0}, +{ 5, s_4_4, 3, 1, 0}, +{ 5, s_4_5, -1, 2, 0} }; static const symbol s_5_0[4] = { 'a', 'n', 'c', 'i' }; @@ -149,30 +149,30 @@ static const symbol s_5_23[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; static const struct among a_5[24] = { -/* 0 */ { 4, s_5_0, -1, 3, 0}, -/* 1 */ { 4, s_5_1, -1, 2, 0}, -/* 2 */ { 3, s_5_2, -1, 13, 0}, -/* 3 */ { 2, s_5_3, -1, 15, 0}, -/* 4 */ { 3, s_5_4, 3, 12, 0}, -/* 5 */ { 4, s_5_5, 4, 4, 0}, -/* 6 */ { 4, s_5_6, 3, 8, 0}, -/* 7 */ { 5, s_5_7, 3, 9, 0}, -/* 8 */ { 6, s_5_8, 3, 14, 0}, -/* 9 */ { 5, s_5_9, 3, 10, 0}, -/* 10 */ { 5, s_5_10, 3, 5, 0}, -/* 11 */ { 5, s_5_11, -1, 8, 0}, -/* 12 */ { 6, s_5_12, -1, 12, 0}, -/* 13 */ { 5, s_5_13, -1, 11, 0}, -/* 14 */ { 6, s_5_14, -1, 1, 0}, -/* 15 */ { 7, s_5_15, 14, 7, 0}, -/* 16 */ { 5, s_5_16, -1, 8, 0}, -/* 17 */ { 5, s_5_17, -1, 7, 0}, -/* 18 */ { 7, s_5_18, 17, 6, 0}, -/* 19 */ { 4, s_5_19, -1, 6, 0}, -/* 20 */ { 4, s_5_20, -1, 7, 0}, -/* 21 */ { 7, s_5_21, -1, 11, 0}, -/* 22 */ { 7, s_5_22, -1, 9, 0}, -/* 23 */ { 7, s_5_23, -1, 10, 0} +{ 4, s_5_0, -1, 3, 0}, +{ 4, s_5_1, -1, 2, 0}, +{ 3, s_5_2, -1, 13, 0}, +{ 2, s_5_3, -1, 15, 0}, +{ 3, s_5_4, 3, 12, 0}, +{ 4, s_5_5, 4, 4, 0}, +{ 4, s_5_6, 3, 8, 0}, +{ 5, s_5_7, 3, 9, 0}, +{ 6, s_5_8, 3, 14, 0}, +{ 5, s_5_9, 3, 10, 0}, +{ 5, s_5_10, 3, 5, 0}, +{ 5, s_5_11, -1, 8, 0}, +{ 6, s_5_12, -1, 12, 0}, +{ 5, s_5_13, -1, 11, 0}, +{ 6, s_5_14, -1, 1, 0}, +{ 7, s_5_15, 14, 7, 0}, +{ 5, s_5_16, -1, 8, 0}, +{ 5, s_5_17, -1, 7, 0}, +{ 7, s_5_18, 17, 6, 0}, +{ 4, s_5_19, -1, 6, 0}, +{ 4, s_5_20, -1, 7, 0}, +{ 7, s_5_21, -1, 11, 0}, +{ 7, s_5_22, -1, 9, 0}, +{ 7, s_5_23, -1, 10, 0} }; static const symbol s_6_0[5] = { 'i', 'c', 'a', 't', 'e' }; @@ -187,15 +187,15 @@ static const symbol s_6_8[4] = { 'n', 'e', 's', 's' }; static const struct among a_6[9] = { -/* 0 */ { 5, s_6_0, -1, 4, 0}, -/* 1 */ { 5, s_6_1, -1, 6, 0}, -/* 2 */ { 5, s_6_2, -1, 3, 0}, -/* 3 */ { 5, s_6_3, -1, 4, 0}, -/* 4 */ { 4, s_6_4, -1, 4, 0}, -/* 5 */ { 6, s_6_5, -1, 1, 0}, -/* 6 */ { 7, s_6_6, 5, 2, 0}, -/* 7 */ { 3, s_6_7, -1, 5, 0}, -/* 8 */ { 4, s_6_8, -1, 5, 0} +{ 5, s_6_0, -1, 4, 0}, +{ 5, s_6_1, -1, 6, 0}, +{ 5, s_6_2, -1, 3, 0}, +{ 5, s_6_3, -1, 4, 0}, +{ 4, s_6_4, -1, 4, 0}, +{ 6, s_6_5, -1, 1, 0}, +{ 7, s_6_6, 5, 2, 0}, +{ 3, s_6_7, -1, 5, 0}, +{ 4, s_6_8, -1, 5, 0} }; static const symbol s_7_0[2] = { 'i', 'c' }; @@ -219,24 +219,24 @@ static const symbol s_7_17[5] = { 'e', 'm', 'e', 'n', 't' }; static const struct among a_7[18] = { -/* 0 */ { 2, s_7_0, -1, 1, 0}, -/* 1 */ { 4, s_7_1, -1, 1, 0}, -/* 2 */ { 4, s_7_2, -1, 1, 0}, -/* 3 */ { 4, s_7_3, -1, 1, 0}, -/* 4 */ { 4, s_7_4, -1, 1, 0}, -/* 5 */ { 3, s_7_5, -1, 1, 0}, -/* 6 */ { 3, s_7_6, -1, 1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 3, s_7_8, -1, 1, 0}, -/* 9 */ { 2, s_7_9, -1, 1, 0}, -/* 10 */ { 3, s_7_10, -1, 1, 0}, -/* 11 */ { 3, s_7_11, -1, 2, 0}, -/* 12 */ { 2, s_7_12, -1, 1, 0}, -/* 13 */ { 3, s_7_13, -1, 1, 0}, -/* 14 */ { 3, s_7_14, -1, 1, 0}, -/* 15 */ { 3, s_7_15, -1, 1, 0}, -/* 16 */ { 4, s_7_16, 15, 1, 0}, -/* 17 */ { 5, s_7_17, 16, 1, 0} +{ 2, s_7_0, -1, 1, 0}, +{ 4, s_7_1, -1, 1, 0}, +{ 4, s_7_2, -1, 1, 0}, +{ 4, s_7_3, -1, 1, 0}, +{ 4, s_7_4, -1, 1, 0}, +{ 3, s_7_5, -1, 1, 0}, +{ 3, s_7_6, -1, 1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 3, s_7_8, -1, 1, 0}, +{ 2, s_7_9, -1, 1, 0}, +{ 3, s_7_10, -1, 1, 0}, +{ 3, s_7_11, -1, 2, 0}, +{ 2, s_7_12, -1, 1, 0}, +{ 3, s_7_13, -1, 1, 0}, +{ 3, s_7_14, -1, 1, 0}, +{ 3, s_7_15, -1, 1, 0}, +{ 4, s_7_16, 15, 1, 0}, +{ 5, s_7_17, 16, 1, 0} }; static const symbol s_8_0[1] = { 'e' }; @@ -244,8 +244,8 @@ static const symbol s_8_1[1] = { 'l' }; static const struct among a_8[2] = { -/* 0 */ { 1, s_8_0, -1, 1, 0}, -/* 1 */ { 1, s_8_1, -1, 2, 0} +{ 1, s_8_0, -1, 1, 0}, +{ 1, s_8_1, -1, 2, 0} }; static const symbol s_9_0[7] = { 's', 'u', 'c', 'c', 'e', 'e', 'd' }; @@ -259,14 +259,14 @@ static const symbol s_9_7[6] = { 'o', 'u', 't', 'i', 'n', 'g' }; static const struct among a_9[8] = { -/* 0 */ { 7, s_9_0, -1, -1, 0}, -/* 1 */ { 7, s_9_1, -1, -1, 0}, -/* 2 */ { 6, s_9_2, -1, -1, 0}, -/* 3 */ { 7, s_9_3, -1, -1, 0}, -/* 4 */ { 6, s_9_4, -1, -1, 0}, -/* 5 */ { 7, s_9_5, -1, -1, 0}, -/* 6 */ { 7, s_9_6, -1, -1, 0}, -/* 7 */ { 6, s_9_7, -1, -1, 0} +{ 7, s_9_0, -1, -1, 0}, +{ 7, s_9_1, -1, -1, 0}, +{ 6, s_9_2, -1, -1, 0}, +{ 7, s_9_3, -1, -1, 0}, +{ 6, s_9_4, -1, -1, 0}, +{ 7, s_9_5, -1, -1, 0}, +{ 7, s_9_6, -1, -1, 0}, +{ 6, s_9_7, -1, -1, 0} }; static const symbol s_10_0[5] = { 'a', 'n', 'd', 'e', 's' }; @@ -290,24 +290,24 @@ static const symbol s_10_17[4] = { 'u', 'g', 'l', 'y' }; static const struct among a_10[18] = { -/* 0 */ { 5, s_10_0, -1, -1, 0}, -/* 1 */ { 5, s_10_1, -1, -1, 0}, -/* 2 */ { 4, s_10_2, -1, -1, 0}, -/* 3 */ { 6, s_10_3, -1, -1, 0}, -/* 4 */ { 5, s_10_4, -1, 3, 0}, -/* 5 */ { 5, s_10_5, -1, 9, 0}, -/* 6 */ { 6, s_10_6, -1, 7, 0}, -/* 7 */ { 4, s_10_7, -1, -1, 0}, -/* 8 */ { 4, s_10_8, -1, 6, 0}, -/* 9 */ { 5, s_10_9, -1, 4, 0}, -/* 10 */ { 4, s_10_10, -1, -1, 0}, -/* 11 */ { 4, s_10_11, -1, 10, 0}, -/* 12 */ { 6, s_10_12, -1, 11, 0}, -/* 13 */ { 5, s_10_13, -1, 2, 0}, -/* 14 */ { 4, s_10_14, -1, 1, 0}, -/* 15 */ { 3, s_10_15, -1, -1, 0}, -/* 16 */ { 5, s_10_16, -1, 5, 0}, -/* 17 */ { 4, s_10_17, -1, 8, 0} +{ 5, s_10_0, -1, -1, 0}, +{ 5, s_10_1, -1, -1, 0}, +{ 4, s_10_2, -1, -1, 0}, +{ 6, s_10_3, -1, -1, 0}, +{ 5, s_10_4, -1, 3, 0}, +{ 5, s_10_5, -1, 9, 0}, +{ 6, s_10_6, -1, 7, 0}, +{ 4, s_10_7, -1, -1, 0}, +{ 4, s_10_8, -1, 6, 0}, +{ 5, s_10_9, -1, 4, 0}, +{ 4, s_10_10, -1, -1, 0}, +{ 4, s_10_11, -1, 10, 0}, +{ 6, s_10_12, -1, 11, 0}, +{ 5, s_10_13, -1, 2, 0}, +{ 4, s_10_14, -1, 1, 0}, +{ 3, s_10_15, -1, -1, 0}, +{ 5, s_10_16, -1, 5, 0}, +{ 4, s_10_17, -1, 8, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1 }; @@ -356,53 +356,52 @@ static const symbol s_36[] = { 'o', 'n', 'l', 'i' }; static const symbol s_37[] = { 's', 'i', 'n', 'g', 'l' }; static const symbol s_38[] = { 'y' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset Y_found, line 26 */ - { int c1 = z->c; /* do, line 27 */ - z->bra = z->c; /* [, line 27 */ - if (z->c == z->l || z->p[z->c] != '\'') goto lab0; /* literal, line 27 */ +static int r_prelude(struct SN_env * z) { + z->I[2] = 0; + { int c1 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != '\'') goto lab0; z->c++; - z->ket = z->c; /* ], line 27 */ - { int ret = slice_del(z); /* delete, line 27 */ + z->ket = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 28 */ - z->bra = z->c; /* [, line 28 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab1; /* literal, line 28 */ + { int c2 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab1; z->c++; - z->ket = z->c; /* ], line 28 */ - { int ret = slice_from_s(z, 1, s_0); /* <-, line 28 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 28 */ + z->I[2] = 1; lab1: z->c = c2; } - { int c3 = z->c; /* do, line 29 */ -/* repeat, line 29 */ - - while(1) { int c4 = z->c; - while(1) { /* goto, line 29 */ + { int c3 = z->c; + while(1) { + int c4 = z->c; + while(1) { int c5 = z->c; - if (in_grouping(z, g_v, 97, 121, 0)) goto lab4; /* grouping v, line 29 */ - z->bra = z->c; /* [, line 29 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 29 */ + if (in_grouping(z, g_v, 97, 121, 0)) goto lab4; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; z->c++; - z->ket = z->c; /* ], line 29 */ + z->ket = z->c; z->c = c5; break; lab4: z->c = c5; if (z->c >= z->l) goto lab3; - z->c++; /* goto, line 29 */ + z->c++; } - { int ret = slice_from_s(z, 1, s_1); /* <-, line 29 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 29 */ + z->I[2] = 1; continue; lab3: z->c = c4; @@ -413,109 +412,107 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 33 */ - z->I[1] = z->l; /* $p2 = , line 34 */ - { int c1 = z->c; /* do, line 35 */ - { int c2 = z->c; /* or, line 41 */ - if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; /* among, line 36 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; if (!(find_among(z, a_0, 3))) goto lab2; goto lab1; lab2: z->c = c2; - { /* gopast */ /* grouping v, line 41 */ + { int ret = out_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 41 */ + { int ret = in_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } } lab1: - z->I[0] = z->c; /* setmark p1, line 42 */ - { /* gopast */ /* grouping v, line 43 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 43 */ + { int ret = in_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 43 */ + z->I[0] = z->c; lab0: z->c = c1; } return 1; } -static int r_shortv(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* or, line 51 */ - if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) goto lab1; /* non v_WXY, line 50 */ - if (in_grouping_b(z, g_v, 97, 121, 0)) goto lab1; /* grouping v, line 50 */ - if (out_grouping_b(z, g_v, 97, 121, 0)) goto lab1; /* non v, line 50 */ +static int r_shortv(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) goto lab1; + if (in_grouping_b(z, g_v, 97, 121, 0)) goto lab1; + if (out_grouping_b(z, g_v, 97, 121, 0)) goto lab1; goto lab0; lab1: z->c = z->l - m1; - if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; /* non v, line 52 */ - if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 52 */ - if (z->c > z->lb) return 0; /* atlimit, line 52 */ + if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; + if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; + if (z->c > z->lb) return 0; } lab0: return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 55 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 56 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_Step_1a(struct SN_env * z) { /* backwardmode */ +static int r_Step_1a(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* try, line 59 */ - z->ket = z->c; /* [, line 60 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m1; goto lab0; } /* substring, line 60 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m1; goto lab0; } if (!(find_among_b(z, a_1, 3))) { z->c = z->l - m1; goto lab0; } - z->bra = z->c; /* ], line 60 */ - { int ret = slice_del(z); /* delete, line 62 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: ; } - z->ket = z->c; /* [, line 65 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; /* substring, line 65 */ + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; among_var = find_among_b(z, a_2, 6); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 65 */ - switch (among_var) { /* among, line 65 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_2); /* <-, line 66 */ + { int ret = slice_from_s(z, 2, s_2); if (ret < 0) return ret; } break; case 2: - { int m2 = z->l - z->c; (void)m2; /* or, line 68 */ - { int ret = z->c - 2; /* hop, line 68 */ - if (z->lb > ret || ret > z->l) goto lab2; - z->c = ret; - } - { int ret = slice_from_s(z, 1, s_3); /* <-, line 68 */ + { int m2 = z->l - z->c; (void)m2; +z->c = z->c - 2; + if (z->c < z->lb) goto lab2; + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m2; - { int ret = slice_from_s(z, 2, s_4); /* <-, line 68 */ + { int ret = slice_from_s(z, 2, s_4); if (ret < 0) return ret; } } @@ -523,13 +520,13 @@ static int r_Step_1a(struct SN_env * z) { /* backwardmode */ break; case 3: if (z->c <= z->lb) return 0; - z->c--; /* next, line 69 */ - { /* gopast */ /* grouping v, line 69 */ + z->c--; + { int ret = out_grouping_b(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - { int ret = slice_del(z); /* delete, line 69 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -537,70 +534,70 @@ static int r_Step_1a(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1b(struct SN_env * z) { /* backwardmode */ +static int r_Step_1b(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 75 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 75 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_4, 6); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 75 */ - switch (among_var) { /* among, line 75 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 77 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_5); /* <-, line 77 */ + { int ret = slice_from_s(z, 2, s_5); if (ret < 0) return ret; } break; case 2: - { int m_test1 = z->l - z->c; /* test, line 80 */ - { /* gopast */ /* grouping v, line 80 */ + { int m_test1 = z->l - z->c; + { int ret = out_grouping_b(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } z->c = z->l - m_test1; } - { int ret = slice_del(z); /* delete, line 80 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m_test2 = z->l - z->c; /* test, line 81 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 81 */ + { int m_test2 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else among_var = find_among_b(z, a_3, 13); if (!(among_var)) return 0; z->c = z->l - m_test2; } - switch (among_var) { /* among, line 81 */ + switch (among_var) { case 1: { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_6); /* <+, line 83 */ + ret = insert_s(z, z->c, z->c, 1, s_6); z->c = saved_c; } if (ret < 0) return ret; } break; case 2: - z->ket = z->c; /* [, line 86 */ + z->ket = z->c; if (z->c <= z->lb) return 0; - z->c--; /* next, line 86 */ - z->bra = z->c; /* ], line 86 */ - { int ret = slice_del(z); /* delete, line 86 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - if (z->c != z->I[0]) return 0; /* atmark, line 87 */ - { int m_test3 = z->l - z->c; /* test, line 87 */ - { int ret = r_shortv(z); /* call shortv, line 87 */ + if (z->c != z->I[1]) return 0; + { int m_test3 = z->l - z->c; + { int ret = r_shortv(z); if (ret <= 0) return ret; } z->c = z->l - m_test3; } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_7); /* <+, line 87 */ + ret = insert_s(z, z->c, z->c, 1, s_7); z->c = saved_c; } if (ret < 0) return ret; @@ -612,116 +609,116 @@ static int r_Step_1b(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1c(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 94 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 94 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 94 */ +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 94 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; z->c--; } lab0: - z->bra = z->c; /* ], line 94 */ - if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; /* non v, line 95 */ - /* not, line 95 */ - if (z->c > z->lb) goto lab2; /* atlimit, line 95 */ + z->bra = z->c; + if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; + + if (z->c > z->lb) goto lab2; return 0; lab2: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 96 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { /* backwardmode */ +static int r_Step_2(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 100 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 100 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_5, 24); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 100 */ - { int ret = r_R1(z); /* call R1, line 100 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 100 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_9); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_9); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_10); /* <-, line 102 */ + { int ret = slice_from_s(z, 4, s_10); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 103 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_13); /* <-, line 105 */ + { int ret = slice_from_s(z, 3, s_13); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_14); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_14); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_15); /* <-, line 109 */ + { int ret = slice_from_s(z, 3, s_15); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 111 */ + { int ret = slice_from_s(z, 2, s_16); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 3, s_17); /* <-, line 112 */ + { int ret = slice_from_s(z, 3, s_17); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 114 */ + { int ret = slice_from_s(z, 3, s_18); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_19); /* <-, line 116 */ + { int ret = slice_from_s(z, 3, s_19); if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_20); if (ret < 0) return ret; } break; case 13: - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 119 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - { int ret = slice_from_s(z, 2, s_21); /* <-, line 119 */ + { int ret = slice_from_s(z, 2, s_21); if (ret < 0) return ret; } break; case 14: - { int ret = slice_from_s(z, 4, s_22); /* <-, line 121 */ + { int ret = slice_from_s(z, 4, s_22); if (ret < 0) return ret; } break; case 15: - if (in_grouping_b(z, g_valid_LI, 99, 116, 0)) return 0; /* grouping valid_LI, line 122 */ - { int ret = slice_del(z); /* delete, line 122 */ + if (in_grouping_b(z, g_valid_LI, 99, 116, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -729,47 +726,47 @@ static int r_Step_2(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_3(struct SN_env * z) { /* backwardmode */ +static int r_Step_3(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 127 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 127 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_6, 9); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 127 */ - { int ret = r_R1(z); /* call R1, line 127 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 127 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_23); /* <-, line 128 */ + { int ret = slice_from_s(z, 4, s_23); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_24); /* <-, line 129 */ + { int ret = slice_from_s(z, 3, s_24); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_25); /* <-, line 130 */ + { int ret = slice_from_s(z, 2, s_25); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_26); /* <-, line 132 */ + { int ret = slice_from_s(z, 2, s_26); if (ret < 0) return ret; } break; case 5: - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 6: - { int ret = r_R2(z); /* call R2, line 136 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 136 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -777,34 +774,34 @@ static int r_Step_3(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_4(struct SN_env * z) { /* backwardmode */ +static int r_Step_4(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 141 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 141 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_7, 18); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 141 */ - { int ret = r_R2(z); /* call R2, line 141 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 141 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 144 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 145 */ + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 145 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 145 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -812,28 +809,28 @@ static int r_Step_4(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_5(struct SN_env * z) { /* backwardmode */ +static int r_Step_5(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 150 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; /* substring, line 150 */ + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; among_var = find_among_b(z, a_8, 2); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 150 */ - switch (among_var) { /* among, line 150 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 151 */ - { int ret = r_R2(z); /* call R2, line 151 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_R2(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); /* call R1, line 151 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* not, line 151 */ - { int ret = r_shortv(z); /* call shortv, line 151 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_shortv(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } @@ -843,17 +840,17 @@ static int r_Step_5(struct SN_env * z) { /* backwardmode */ } } lab0: - { int ret = slice_del(z); /* delete, line 151 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 152 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 152 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -861,76 +858,76 @@ static int r_Step_5(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_exception2(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 158 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 158 */ +static int r_exception2(struct SN_env * z) { + z->ket = z->c; + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; if (!(find_among_b(z, a_9, 8))) return 0; - z->bra = z->c; /* ], line 158 */ - if (z->c > z->lb) return 0; /* atlimit, line 158 */ + z->bra = z->c; + if (z->c > z->lb) return 0; return 1; } -static int r_exception1(struct SN_env * z) { /* forwardmode */ +static int r_exception1(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 170 */ - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; /* substring, line 170 */ + z->bra = z->c; + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; among_var = find_among(z, a_10, 18); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 170 */ - if (z->c < z->l) return 0; /* atlimit, line 170 */ - switch (among_var) { /* among, line 170 */ + z->ket = z->c; + if (z->c < z->l) return 0; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 3, s_27); /* <-, line 174 */ + { int ret = slice_from_s(z, 3, s_27); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_28); /* <-, line 175 */ + { int ret = slice_from_s(z, 3, s_28); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_29); /* <-, line 176 */ + { int ret = slice_from_s(z, 3, s_29); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 3, s_30); /* <-, line 177 */ + { int ret = slice_from_s(z, 3, s_30); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_31); /* <-, line 178 */ + { int ret = slice_from_s(z, 3, s_31); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_32); /* <-, line 182 */ + { int ret = slice_from_s(z, 3, s_32); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 5, s_33); /* <-, line 183 */ + { int ret = slice_from_s(z, 5, s_33); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 4, s_34); /* <-, line 184 */ + { int ret = slice_from_s(z, 4, s_34); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 5, s_35); /* <-, line 185 */ + { int ret = slice_from_s(z, 5, s_35); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 4, s_36); /* <-, line 186 */ + { int ret = slice_from_s(z, 4, s_36); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 5, s_37); /* <-, line 187 */ + { int ret = slice_from_s(z, 5, s_37); if (ret < 0) return ret; } break; @@ -938,25 +935,24 @@ static int r_exception1(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ - if (!(z->B[0])) return 0; /* Boolean test Y_found, line 203 */ -/* repeat, line 203 */ - - while(1) { int c1 = z->c; - while(1) { /* goto, line 203 */ +static int r_postlude(struct SN_env * z) { + if (!(z->I[2])) return 0; + while(1) { + int c1 = z->c; + while(1) { int c2 = z->c; - z->bra = z->c; /* [, line 203 */ - if (z->c == z->l || z->p[z->c] != 'Y') goto lab1; /* literal, line 203 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab1; z->c++; - z->ket = z->c; /* ], line 203 */ + z->ket = z->c; z->c = c2; break; lab1: z->c = c2; if (z->c >= z->l) goto lab0; - z->c++; /* goto, line 203 */ + z->c++; } - { int ret = slice_from_s(z, 1, s_38); /* <-, line 203 */ + { int ret = slice_from_s(z, 1, s_38); if (ret < 0) return ret; } continue; @@ -967,20 +963,18 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -extern int english_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* or, line 207 */ - { int ret = r_exception1(z); /* call exception1, line 207 */ +extern int english_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_exception1(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = c1; - { int c2 = z->c; /* not, line 208 */ - { int ret = z->c + 3; /* hop, line 208 */ - if (0 > ret || ret > z->l) goto lab3; - z->c = ret; - } + { int c2 = z->c; +z->c = z->c + 3; + if (z->c > z->l) goto lab3; goto lab2; lab3: z->c = c2; @@ -988,62 +982,62 @@ extern int english_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ goto lab0; lab2: z->c = c1; - /* do, line 209 */ - { int ret = r_prelude(z); /* call prelude, line 209 */ + + { int ret = r_prelude(z); if (ret < 0) return ret; } - /* do, line 210 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 210 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 211 */ + z->lb = z->c; z->c = z->l; - { int m3 = z->l - z->c; (void)m3; /* do, line 213 */ - { int ret = r_Step_1a(z); /* call Step_1a, line 213 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_Step_1a(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* or, line 215 */ - { int ret = r_exception2(z); /* call exception2, line 215 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_exception2(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m4; - { int m5 = z->l - z->c; (void)m5; /* do, line 217 */ - { int ret = r_Step_1b(z); /* call Step_1b, line 217 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_Step_1b(z); if (ret < 0) return ret; } z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* do, line 218 */ - { int ret = r_Step_1c(z); /* call Step_1c, line 218 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_Step_1c(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 220 */ - { int ret = r_Step_2(z); /* call Step_2, line 220 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_Step_2(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 221 */ - { int ret = r_Step_3(z); /* call Step_3, line 221 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_Step_3(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 222 */ - { int ret = r_Step_4(z); /* call Step_4, line 222 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_Step_4(z); if (ret < 0) return ret; } z->c = z->l - m9; } - { int m10 = z->l - z->c; (void)m10; /* do, line 224 */ - { int ret = r_Step_5(z); /* call Step_5, line 224 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_Step_5(z); if (ret < 0) return ret; } z->c = z->l - m10; @@ -1051,8 +1045,8 @@ extern int english_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ } lab4: z->c = z->lb; - { int c11 = z->c; /* do, line 227 */ - { int ret = r_postlude(z); /* call postlude, line 227 */ + { int c11 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c11; @@ -1062,7 +1056,7 @@ extern int english_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * english_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); } +extern struct SN_env * english_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void english_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c index 3bb6615a68c4..70eae3a3fa38 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -45,16 +45,16 @@ static const symbol s_0_9[2] = { 'k', 0xF6 }; static const struct among a_0[10] = { -/* 0 */ { 2, s_0_0, -1, 1, 0}, -/* 1 */ { 3, s_0_1, -1, 2, 0}, -/* 2 */ { 4, s_0_2, -1, 1, 0}, -/* 3 */ { 3, s_0_3, -1, 1, 0}, -/* 4 */ { 3, s_0_4, -1, 1, 0}, -/* 5 */ { 3, s_0_5, -1, 1, 0}, -/* 6 */ { 4, s_0_6, -1, 1, 0}, -/* 7 */ { 2, s_0_7, -1, 1, 0}, -/* 8 */ { 2, s_0_8, -1, 1, 0}, -/* 9 */ { 2, s_0_9, -1, 1, 0} +{ 2, s_0_0, -1, 1, 0}, +{ 3, s_0_1, -1, 2, 0}, +{ 4, s_0_2, -1, 1, 0}, +{ 3, s_0_3, -1, 1, 0}, +{ 3, s_0_4, -1, 1, 0}, +{ 3, s_0_5, -1, 1, 0}, +{ 4, s_0_6, -1, 1, 0}, +{ 2, s_0_7, -1, 1, 0}, +{ 2, s_0_8, -1, 1, 0}, +{ 2, s_0_9, -1, 1, 0} }; static const symbol s_1_0[3] = { 'l', 'l', 'a' }; @@ -66,12 +66,12 @@ static const symbol s_1_5[3] = { 's', 't', 'a' }; static const struct among a_1[6] = { -/* 0 */ { 3, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0}, -/* 2 */ { 3, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0}, -/* 4 */ { 3, s_1_4, 3, -1, 0}, -/* 5 */ { 3, s_1_5, 3, -1, 0} +{ 3, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0}, +{ 3, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0}, +{ 3, s_1_4, 3, -1, 0}, +{ 3, s_1_5, 3, -1, 0} }; static const symbol s_2_0[3] = { 'l', 'l', 0xE4 }; @@ -83,12 +83,12 @@ static const symbol s_2_5[3] = { 's', 't', 0xE4 }; static const struct among a_2[6] = { -/* 0 */ { 3, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 3, s_2_2, -1, -1, 0}, -/* 3 */ { 2, s_2_3, -1, -1, 0}, -/* 4 */ { 3, s_2_4, 3, -1, 0}, -/* 5 */ { 3, s_2_5, 3, -1, 0} +{ 3, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 3, s_2_2, -1, -1, 0}, +{ 2, s_2_3, -1, -1, 0}, +{ 3, s_2_4, 3, -1, 0}, +{ 3, s_2_5, 3, -1, 0} }; static const symbol s_3_0[3] = { 'l', 'l', 'e' }; @@ -96,8 +96,8 @@ static const symbol s_3_1[3] = { 'i', 'n', 'e' }; static const struct among a_3[2] = { -/* 0 */ { 3, s_3_0, -1, -1, 0}, -/* 1 */ { 3, s_3_1, -1, -1, 0} +{ 3, s_3_0, -1, -1, 0}, +{ 3, s_3_1, -1, -1, 0} }; static const symbol s_4_0[3] = { 'n', 's', 'a' }; @@ -112,15 +112,15 @@ static const symbol s_4_8[3] = { 'n', 's', 0xE4 }; static const struct among a_4[9] = { -/* 0 */ { 3, s_4_0, -1, 3, 0}, -/* 1 */ { 3, s_4_1, -1, 3, 0}, -/* 2 */ { 3, s_4_2, -1, 3, 0}, -/* 3 */ { 2, s_4_3, -1, 2, 0}, -/* 4 */ { 2, s_4_4, -1, 1, 0}, -/* 5 */ { 2, s_4_5, -1, 4, 0}, -/* 6 */ { 2, s_4_6, -1, 6, 0}, -/* 7 */ { 2, s_4_7, -1, 5, 0}, -/* 8 */ { 3, s_4_8, -1, 3, 0} +{ 3, s_4_0, -1, 3, 0}, +{ 3, s_4_1, -1, 3, 0}, +{ 3, s_4_2, -1, 3, 0}, +{ 2, s_4_3, -1, 2, 0}, +{ 2, s_4_4, -1, 1, 0}, +{ 2, s_4_5, -1, 4, 0}, +{ 2, s_4_6, -1, 6, 0}, +{ 2, s_4_7, -1, 5, 0}, +{ 3, s_4_8, -1, 3, 0} }; static const symbol s_5_0[2] = { 'a', 'a' }; @@ -133,13 +133,13 @@ static const symbol s_5_6[2] = { 0xF6, 0xF6 }; static const struct among a_5[7] = { -/* 0 */ { 2, s_5_0, -1, -1, 0}, -/* 1 */ { 2, s_5_1, -1, -1, 0}, -/* 2 */ { 2, s_5_2, -1, -1, 0}, -/* 3 */ { 2, s_5_3, -1, -1, 0}, -/* 4 */ { 2, s_5_4, -1, -1, 0}, -/* 5 */ { 2, s_5_5, -1, -1, 0}, -/* 6 */ { 2, s_5_6, -1, -1, 0} +{ 2, s_5_0, -1, -1, 0}, +{ 2, s_5_1, -1, -1, 0}, +{ 2, s_5_2, -1, -1, 0}, +{ 2, s_5_3, -1, -1, 0}, +{ 2, s_5_4, -1, -1, 0}, +{ 2, s_5_5, -1, -1, 0}, +{ 2, s_5_6, -1, -1, 0} }; static const symbol s_6_0[1] = { 'a' }; @@ -175,36 +175,36 @@ static const symbol s_6_29[3] = { 't', 't', 0xE4 }; static const struct among a_6[30] = { -/* 0 */ { 1, s_6_0, -1, 8, 0}, -/* 1 */ { 3, s_6_1, 0, -1, 0}, -/* 2 */ { 2, s_6_2, 0, -1, 0}, -/* 3 */ { 3, s_6_3, 0, -1, 0}, -/* 4 */ { 2, s_6_4, 0, -1, 0}, -/* 5 */ { 3, s_6_5, 4, -1, 0}, -/* 6 */ { 3, s_6_6, 4, -1, 0}, -/* 7 */ { 3, s_6_7, 4, 2, 0}, -/* 8 */ { 3, s_6_8, -1, -1, 0}, -/* 9 */ { 3, s_6_9, -1, -1, 0}, -/* 10 */ { 3, s_6_10, -1, -1, 0}, -/* 11 */ { 1, s_6_11, -1, 7, 0}, -/* 12 */ { 3, s_6_12, 11, 1, 0}, -/* 13 */ { 3, s_6_13, 11, -1, r_VI}, -/* 14 */ { 4, s_6_14, 11, -1, r_LONG}, -/* 15 */ { 3, s_6_15, 11, 2, 0}, -/* 16 */ { 4, s_6_16, 11, -1, r_VI}, -/* 17 */ { 3, s_6_17, 11, 3, 0}, -/* 18 */ { 4, s_6_18, 11, -1, r_VI}, -/* 19 */ { 3, s_6_19, 11, 4, 0}, -/* 20 */ { 3, s_6_20, 11, 5, 0}, -/* 21 */ { 3, s_6_21, 11, 6, 0}, -/* 22 */ { 1, s_6_22, -1, 8, 0}, -/* 23 */ { 3, s_6_23, 22, -1, 0}, -/* 24 */ { 2, s_6_24, 22, -1, 0}, -/* 25 */ { 3, s_6_25, 22, -1, 0}, -/* 26 */ { 2, s_6_26, 22, -1, 0}, -/* 27 */ { 3, s_6_27, 26, -1, 0}, -/* 28 */ { 3, s_6_28, 26, -1, 0}, -/* 29 */ { 3, s_6_29, 26, 2, 0} +{ 1, s_6_0, -1, 8, 0}, +{ 3, s_6_1, 0, -1, 0}, +{ 2, s_6_2, 0, -1, 0}, +{ 3, s_6_3, 0, -1, 0}, +{ 2, s_6_4, 0, -1, 0}, +{ 3, s_6_5, 4, -1, 0}, +{ 3, s_6_6, 4, -1, 0}, +{ 3, s_6_7, 4, 2, 0}, +{ 3, s_6_8, -1, -1, 0}, +{ 3, s_6_9, -1, -1, 0}, +{ 3, s_6_10, -1, -1, 0}, +{ 1, s_6_11, -1, 7, 0}, +{ 3, s_6_12, 11, 1, 0}, +{ 3, s_6_13, 11, -1, r_VI}, +{ 4, s_6_14, 11, -1, r_LONG}, +{ 3, s_6_15, 11, 2, 0}, +{ 4, s_6_16, 11, -1, r_VI}, +{ 3, s_6_17, 11, 3, 0}, +{ 4, s_6_18, 11, -1, r_VI}, +{ 3, s_6_19, 11, 4, 0}, +{ 3, s_6_20, 11, 5, 0}, +{ 3, s_6_21, 11, 6, 0}, +{ 1, s_6_22, -1, 8, 0}, +{ 3, s_6_23, 22, -1, 0}, +{ 2, s_6_24, 22, -1, 0}, +{ 3, s_6_25, 22, -1, 0}, +{ 2, s_6_26, 22, -1, 0}, +{ 3, s_6_27, 26, -1, 0}, +{ 3, s_6_28, 26, -1, 0}, +{ 3, s_6_29, 26, 2, 0} }; static const symbol s_7_0[3] = { 'e', 'j', 'a' }; @@ -224,20 +224,20 @@ static const symbol s_7_13[4] = { 'i', 'm', 'p', 0xE4 }; static const struct among a_7[14] = { -/* 0 */ { 3, s_7_0, -1, -1, 0}, -/* 1 */ { 3, s_7_1, -1, 1, 0}, -/* 2 */ { 4, s_7_2, 1, -1, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 4, s_7_4, 3, -1, 0}, -/* 5 */ { 3, s_7_5, -1, 1, 0}, -/* 6 */ { 4, s_7_6, 5, -1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 4, s_7_8, 7, -1, 0}, -/* 9 */ { 3, s_7_9, -1, -1, 0}, -/* 10 */ { 3, s_7_10, -1, 1, 0}, -/* 11 */ { 4, s_7_11, 10, -1, 0}, -/* 12 */ { 3, s_7_12, -1, 1, 0}, -/* 13 */ { 4, s_7_13, 12, -1, 0} +{ 3, s_7_0, -1, -1, 0}, +{ 3, s_7_1, -1, 1, 0}, +{ 4, s_7_2, 1, -1, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 4, s_7_4, 3, -1, 0}, +{ 3, s_7_5, -1, 1, 0}, +{ 4, s_7_6, 5, -1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 4, s_7_8, 7, -1, 0}, +{ 3, s_7_9, -1, -1, 0}, +{ 3, s_7_10, -1, 1, 0}, +{ 4, s_7_11, 10, -1, 0}, +{ 3, s_7_12, -1, 1, 0}, +{ 4, s_7_13, 12, -1, 0} }; static const symbol s_8_0[1] = { 'i' }; @@ -245,8 +245,8 @@ static const symbol s_8_1[1] = { 'j' }; static const struct among a_8[2] = { -/* 0 */ { 1, s_8_0, -1, -1, 0}, -/* 1 */ { 1, s_8_1, -1, -1, 0} +{ 1, s_8_0, -1, -1, 0}, +{ 1, s_8_1, -1, -1, 0} }; static const symbol s_9_0[3] = { 'm', 'm', 'a' }; @@ -254,8 +254,8 @@ static const symbol s_9_1[4] = { 'i', 'm', 'm', 'a' }; static const struct among a_9[2] = { -/* 0 */ { 3, s_9_0, -1, 1, 0}, -/* 1 */ { 4, s_9_1, 0, -1, 0} +{ 3, s_9_0, -1, 1, 0}, +{ 4, s_9_1, 0, -1, 0} }; static const unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; @@ -274,118 +274,118 @@ static const symbol s_2[] = { 'i', 'e' }; static const symbol s_3[] = { 'p', 'o' }; static const symbol s_4[] = { 'p', 'o' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 44 */ - z->I[1] = z->l; /* $p2 = , line 45 */ - if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */ - { /* gopast */ /* non V1, line 47 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; + { int ret = in_grouping(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 47 */ - if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 48 */ - { /* gopast */ /* non V1, line 48 */ + z->I[1] = z->c; + if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; + { int ret = in_grouping(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 48 */ + z->I[0] = z->c; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 53 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_particle_etc(struct SN_env * z) { /* backwardmode */ +static int r_particle_etc(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 56 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 56 */ - among_var = find_among_b(z, a_0, 10); /* substring, line 56 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + among_var = find_among_b(z, a_0, 10); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 56 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 57 */ + switch (among_var) { case 1: - if (in_grouping_b(z, g_particle_end, 97, 246, 0)) return 0; /* grouping particle_end, line 63 */ + if (in_grouping_b(z, g_particle_end, 97, 246, 0)) return 0; break; case 2: - { int ret = r_R2(z); /* call R2, line 65 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } break; } - { int ret = slice_del(z); /* delete, line 67 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_possessive(struct SN_env * z) { /* backwardmode */ +static int r_possessive(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 70 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 70 */ - among_var = find_among_b(z, a_4, 9); /* substring, line 70 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + among_var = find_among_b(z, a_4, 9); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 70 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 71 */ + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 73 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'k') goto lab0; /* literal, line 73 */ + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'k') goto lab0; z->c--; return 0; lab0: z->c = z->l - m2; } - { int ret = slice_del(z); /* delete, line 73 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 75 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 75 */ - if (!(eq_s_b(z, 3, s_0))) return 0; /* literal, line 75 */ - z->bra = z->c; /* ], line 75 */ - { int ret = slice_from_s(z, 3, s_1); /* <-, line 75 */ + z->ket = z->c; + if (!(eq_s_b(z, 3, s_0))) return 0; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 79 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 4: - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; /* among, line 82 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; if (!(find_among_b(z, a_1, 6))) return 0; - { int ret = slice_del(z); /* delete, line 82 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 5: - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 228) return 0; /* among, line 84 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 228) return 0; if (!(find_among_b(z, a_2, 6))) return 0; - { int ret = slice_del(z); /* delete, line 85 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 6: - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; /* among, line 87 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; if (!(find_among_b(z, a_3, 2))) return 0; - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -393,244 +393,244 @@ static int r_possessive(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_LONG(struct SN_env * z) { /* backwardmode */ - if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 92 */ +static int r_LONG(struct SN_env * z) { + if (!(find_among_b(z, a_5, 7))) return 0; return 1; } -static int r_VI(struct SN_env * z) { /* backwardmode */ - if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 94 */ +static int r_VI(struct SN_env * z) { + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; z->c--; - if (in_grouping_b(z, g_V2, 97, 246, 0)) return 0; /* grouping V2, line 94 */ + if (in_grouping_b(z, g_V2, 97, 246, 0)) return 0; return 1; } -static int r_case_ending(struct SN_env * z) { /* backwardmode */ +static int r_case_ending(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 97 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 97 */ - among_var = find_among_b(z, a_6, 30); /* substring, line 97 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + among_var = find_among_b(z, a_6, 30); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 97 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 98 */ + switch (among_var) { case 1: - if (z->c <= z->lb || z->p[z->c - 1] != 'a') return 0; /* literal, line 99 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'a') return 0; z->c--; break; case 2: - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 100 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; break; case 3: - if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 101 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; z->c--; break; case 4: - if (z->c <= z->lb || z->p[z->c - 1] != 'o') return 0; /* literal, line 102 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') return 0; z->c--; break; case 5: - if (z->c <= z->lb || z->p[z->c - 1] != 0xE4) return 0; /* literal, line 103 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xE4) return 0; z->c--; break; case 6: - if (z->c <= z->lb || z->p[z->c - 1] != 0xF6) return 0; /* literal, line 104 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xF6) return 0; z->c--; break; case 7: - { int m2 = z->l - z->c; (void)m2; /* try, line 112 */ - { int m3 = z->l - z->c; (void)m3; /* and, line 114 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 113 */ - { int ret = r_LONG(z); /* call LONG, line 112 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int ret = r_LONG(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m4; - if (!(eq_s_b(z, 2, s_2))) { z->c = z->l - m2; goto lab0; } /* literal, line 113 */ + if (!(eq_s_b(z, 2, s_2))) { z->c = z->l - m2; goto lab0; } } lab1: z->c = z->l - m3; if (z->c <= z->lb) { z->c = z->l - m2; goto lab0; } - z->c--; /* next, line 114 */ + z->c--; } - z->bra = z->c; /* ], line 114 */ + z->bra = z->c; lab0: ; } break; case 8: - if (in_grouping_b(z, g_V1, 97, 246, 0)) return 0; /* grouping V1, line 120 */ - if (in_grouping_b(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 120 */ + if (in_grouping_b(z, g_V1, 97, 246, 0)) return 0; + if (in_grouping_b(z, g_C, 98, 122, 0)) return 0; break; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set ending_removed, line 140 */ + z->I[2] = 1; return 1; } -static int r_other_endings(struct SN_env * z) { /* backwardmode */ +static int r_other_endings(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 143 */ - if (z->c < z->I[1]) return 0; - mlimit1 = z->lb; z->lb = z->I[1]; - z->ket = z->c; /* [, line 143 */ - among_var = find_among_b(z, a_7, 14); /* substring, line 143 */ + { int mlimit1; + if (z->c < z->I[0]) return 0; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; + among_var = find_among_b(z, a_7, 14); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 143 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 144 */ + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 147 */ - if (!(eq_s_b(z, 2, s_3))) goto lab0; /* literal, line 147 */ + { int m2 = z->l - z->c; (void)m2; + if (!(eq_s_b(z, 2, s_3))) goto lab0; return 0; lab0: z->c = z->l - m2; } break; } - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_i_plural(struct SN_env * z) { /* backwardmode */ +static int r_i_plural(struct SN_env * z) { - { int mlimit1; /* setlimit, line 155 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 155 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit1; return 0; } /* substring, line 155 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 155 */ + z->bra = z->c; z->lb = mlimit1; } - { int ret = slice_del(z); /* delete, line 159 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_t_plural(struct SN_env * z) { /* backwardmode */ +static int r_t_plural(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 162 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 163 */ - if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit1; return 0; } /* literal, line 163 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit1; return 0; } z->c--; - z->bra = z->c; /* ], line 163 */ - { int m_test2 = z->l - z->c; /* test, line 163 */ - if (in_grouping_b(z, g_V1, 97, 246, 0)) { z->lb = mlimit1; return 0; } /* grouping V1, line 163 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + if (in_grouping_b(z, g_V1, 97, 246, 0)) { z->lb = mlimit1; return 0; } z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 164 */ + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; } - { int mlimit3; /* setlimit, line 166 */ - if (z->c < z->I[1]) return 0; - mlimit3 = z->lb; z->lb = z->I[1]; - z->ket = z->c; /* [, line 166 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit3; return 0; } /* substring, line 166 */ + { int mlimit3; + if (z->c < z->I[0]) return 0; + mlimit3 = z->lb; z->lb = z->I[0]; + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit3; return 0; } among_var = find_among_b(z, a_9, 2); if (!(among_var)) { z->lb = mlimit3; return 0; } - z->bra = z->c; /* ], line 166 */ + z->bra = z->c; z->lb = mlimit3; } - switch (among_var) { /* among, line 167 */ + switch (among_var) { case 1: - { int m4 = z->l - z->c; (void)m4; /* not, line 168 */ - if (!(eq_s_b(z, 2, s_4))) goto lab0; /* literal, line 168 */ + { int m4 = z->l - z->c; (void)m4; + if (!(eq_s_b(z, 2, s_4))) goto lab0; return 0; lab0: z->c = z->l - m4; } break; } - { int ret = slice_del(z); /* delete, line 171 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_tidy(struct SN_env * z) { /* backwardmode */ +static int r_tidy(struct SN_env * z) { - { int mlimit1; /* setlimit, line 174 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - { int m2 = z->l - z->c; (void)m2; /* do, line 175 */ - { int m3 = z->l - z->c; (void)m3; /* and, line 175 */ - { int ret = r_LONG(z); /* call LONG, line 175 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_LONG(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } z->c = z->l - m3; - z->ket = z->c; /* [, line 175 */ + z->ket = z->c; if (z->c <= z->lb) goto lab0; - z->c--; /* next, line 175 */ - z->bra = z->c; /* ], line 175 */ - { int ret = slice_del(z); /* delete, line 175 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } } lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 176 */ - z->ket = z->c; /* [, line 176 */ - if (in_grouping_b(z, g_AEI, 97, 228, 0)) goto lab1; /* grouping AEI, line 176 */ - z->bra = z->c; /* ], line 176 */ - if (in_grouping_b(z, g_C, 98, 122, 0)) goto lab1; /* grouping C, line 176 */ - { int ret = slice_del(z); /* delete, line 176 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (in_grouping_b(z, g_AEI, 97, 228, 0)) goto lab1; + z->bra = z->c; + if (in_grouping_b(z, g_C, 98, 122, 0)) goto lab1; + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 177 */ - z->ket = z->c; /* [, line 177 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab2; /* literal, line 177 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab2; z->c--; - z->bra = z->c; /* ], line 177 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 177 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab4; /* literal, line 177 */ + z->bra = z->c; + { int m6 = z->l - z->c; (void)m6; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab4; z->c--; goto lab3; lab4: z->c = z->l - m6; - if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab2; /* literal, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab2; z->c--; } lab3: - { int ret = slice_del(z); /* delete, line 177 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: z->c = z->l - m5; } - { int m7 = z->l - z->c; (void)m7; /* do, line 178 */ - z->ket = z->c; /* [, line 178 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; /* literal, line 178 */ + { int m7 = z->l - z->c; (void)m7; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; z->c--; - z->bra = z->c; /* ], line 178 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab5; /* literal, line 178 */ + z->bra = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab5; z->c--; - { int ret = slice_del(z); /* delete, line 178 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab5: @@ -638,72 +638,72 @@ static int r_tidy(struct SN_env * z) { /* backwardmode */ } z->lb = mlimit1; } - if (in_grouping_b(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 180 */ - z->ket = z->c; /* [, line 180 */ - if (in_grouping_b(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 180 */ - z->bra = z->c; /* ], line 180 */ - z->S[0] = slice_to(z, z->S[0]); /* -> x, line 180 */ - if (z->S[0] == 0) return -1; /* -> x, line 180 */ - if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 180 */ - { int ret = slice_del(z); /* delete, line 180 */ + if (in_grouping_b(z, g_V1, 97, 246, 1) < 0) return 0; + z->ket = z->c; + if (in_grouping_b(z, g_C, 98, 122, 0)) return 0; + z->bra = z->c; + z->S[0] = slice_to(z, z->S[0]); + if (z->S[0] == 0) return -1; + if (!(eq_v_b(z, z->S[0]))) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int finnish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 186 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 186 */ +extern int finnish_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->B[0] = 0; /* unset ending_removed, line 187 */ - z->lb = z->c; z->c = z->l; /* backwards, line 188 */ + z->I[2] = 0; + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 189 */ - { int ret = r_particle_etc(z); /* call particle_etc, line 189 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_particle_etc(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 190 */ - { int ret = r_possessive(z); /* call possessive, line 190 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_possessive(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 191 */ - { int ret = r_case_ending(z); /* call case_ending, line 191 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_case_ending(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 192 */ - { int ret = r_other_endings(z); /* call other_endings, line 192 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_other_endings(z); if (ret < 0) return ret; } z->c = z->l - m5; } - /* or, line 193 */ - if (!(z->B[0])) goto lab1; /* Boolean test ending_removed, line 193 */ - { int m6 = z->l - z->c; (void)m6; /* do, line 193 */ - { int ret = r_i_plural(z); /* call i_plural, line 193 */ + + if (!(z->I[2])) goto lab1; + { int m6 = z->l - z->c; (void)m6; + { int ret = r_i_plural(z); if (ret < 0) return ret; } z->c = z->l - m6; } goto lab0; lab1: - { int m7 = z->l - z->c; (void)m7; /* do, line 193 */ - { int ret = r_t_plural(z); /* call t_plural, line 193 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_t_plural(z); if (ret < 0) return ret; } z->c = z->l - m7; } lab0: - { int m8 = z->l - z->c; (void)m8; /* do, line 194 */ - { int ret = r_tidy(z); /* call tidy, line 194 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_tidy(z); if (ret < 0) return ret; } z->c = z->l - m8; @@ -712,7 +712,7 @@ extern int finnish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * finnish_ISO_8859_1_create_env(void) { return SN_create_env(1, 2, 1); } +extern struct SN_env * finnish_ISO_8859_1_create_env(void) { return SN_create_env(1, 3); } extern void finnish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 1); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c index bbf6985ba584..05fd6b61a246 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -39,9 +39,9 @@ static const symbol s_0_2[3] = { 't', 'a', 'p' }; static const struct among a_0[3] = { -/* 0 */ { 3, s_0_0, -1, -1, 0}, -/* 1 */ { 3, s_0_1, -1, -1, 0}, -/* 2 */ { 3, s_0_2, -1, -1, 0} +{ 3, s_0_0, -1, -1, 0}, +{ 3, s_0_1, -1, -1, 0}, +{ 3, s_0_2, -1, -1, 0} }; static const symbol s_1_1[1] = { 'H' }; @@ -53,13 +53,13 @@ static const symbol s_1_6[1] = { 'Y' }; static const struct among a_1[7] = { -/* 0 */ { 0, 0, -1, 7, 0}, -/* 1 */ { 1, s_1_1, 0, 6, 0}, -/* 2 */ { 2, s_1_2, 1, 4, 0}, -/* 3 */ { 2, s_1_3, 1, 5, 0}, -/* 4 */ { 1, s_1_4, 0, 1, 0}, -/* 5 */ { 1, s_1_5, 0, 2, 0}, -/* 6 */ { 1, s_1_6, 0, 3, 0} +{ 0, 0, -1, 7, 0}, +{ 1, s_1_1, 0, 6, 0}, +{ 2, s_1_2, 1, 4, 0}, +{ 2, s_1_3, 1, 5, 0}, +{ 1, s_1_4, 0, 1, 0}, +{ 1, s_1_5, 0, 2, 0}, +{ 1, s_1_6, 0, 3, 0} }; static const symbol s_2_0[3] = { 'i', 'q', 'U' }; @@ -71,12 +71,12 @@ static const symbol s_2_5[2] = { 'i', 'v' }; static const struct among a_2[6] = { -/* 0 */ { 3, s_2_0, -1, 3, 0}, -/* 1 */ { 3, s_2_1, -1, 3, 0}, -/* 2 */ { 3, s_2_2, -1, 4, 0}, -/* 3 */ { 3, s_2_3, -1, 4, 0}, -/* 4 */ { 3, s_2_4, -1, 2, 0}, -/* 5 */ { 2, s_2_5, -1, 1, 0} +{ 3, s_2_0, -1, 3, 0}, +{ 3, s_2_1, -1, 3, 0}, +{ 3, s_2_2, -1, 4, 0}, +{ 3, s_2_3, -1, 4, 0}, +{ 3, s_2_4, -1, 2, 0}, +{ 2, s_2_5, -1, 1, 0} }; static const symbol s_3_0[2] = { 'i', 'c' }; @@ -85,9 +85,9 @@ static const symbol s_3_2[2] = { 'i', 'v' }; static const struct among a_3[3] = { -/* 0 */ { 2, s_3_0, -1, 2, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 2, s_3_2, -1, 3, 0} +{ 2, s_3_0, -1, 2, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 2, s_3_2, -1, 3, 0} }; static const symbol s_4_0[4] = { 'i', 'q', 'U', 'e' }; @@ -136,49 +136,49 @@ static const symbol s_4_42[3] = { 'i', 't', 0xE9 }; static const struct among a_4[43] = { -/* 0 */ { 4, s_4_0, -1, 1, 0}, -/* 1 */ { 6, s_4_1, -1, 2, 0}, -/* 2 */ { 4, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 5, 0}, -/* 4 */ { 5, s_4_4, -1, 3, 0}, -/* 5 */ { 4, s_4_5, -1, 1, 0}, -/* 6 */ { 4, s_4_6, -1, 1, 0}, -/* 7 */ { 4, s_4_7, -1, 11, 0}, -/* 8 */ { 4, s_4_8, -1, 1, 0}, -/* 9 */ { 3, s_4_9, -1, 8, 0}, -/* 10 */ { 2, s_4_10, -1, 8, 0}, -/* 11 */ { 5, s_4_11, -1, 4, 0}, -/* 12 */ { 5, s_4_12, -1, 2, 0}, -/* 13 */ { 5, s_4_13, -1, 4, 0}, -/* 14 */ { 5, s_4_14, -1, 2, 0}, -/* 15 */ { 5, s_4_15, -1, 1, 0}, -/* 16 */ { 7, s_4_16, -1, 2, 0}, -/* 17 */ { 5, s_4_17, -1, 1, 0}, -/* 18 */ { 5, s_4_18, -1, 5, 0}, -/* 19 */ { 6, s_4_19, -1, 3, 0}, -/* 20 */ { 5, s_4_20, -1, 1, 0}, -/* 21 */ { 5, s_4_21, -1, 1, 0}, -/* 22 */ { 5, s_4_22, -1, 11, 0}, -/* 23 */ { 5, s_4_23, -1, 1, 0}, -/* 24 */ { 4, s_4_24, -1, 8, 0}, -/* 25 */ { 3, s_4_25, -1, 8, 0}, -/* 26 */ { 6, s_4_26, -1, 4, 0}, -/* 27 */ { 6, s_4_27, -1, 2, 0}, -/* 28 */ { 6, s_4_28, -1, 4, 0}, -/* 29 */ { 6, s_4_29, -1, 2, 0}, -/* 30 */ { 5, s_4_30, -1, 15, 0}, -/* 31 */ { 6, s_4_31, 30, 6, 0}, -/* 32 */ { 9, s_4_32, 31, 12, 0}, -/* 33 */ { 4, s_4_33, -1, 7, 0}, -/* 34 */ { 4, s_4_34, -1, 15, 0}, -/* 35 */ { 5, s_4_35, 34, 6, 0}, -/* 36 */ { 8, s_4_36, 35, 12, 0}, -/* 37 */ { 6, s_4_37, 34, 13, 0}, -/* 38 */ { 6, s_4_38, 34, 14, 0}, -/* 39 */ { 3, s_4_39, -1, 10, 0}, -/* 40 */ { 4, s_4_40, 39, 9, 0}, -/* 41 */ { 3, s_4_41, -1, 1, 0}, -/* 42 */ { 3, s_4_42, -1, 7, 0} +{ 4, s_4_0, -1, 1, 0}, +{ 6, s_4_1, -1, 2, 0}, +{ 4, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 5, 0}, +{ 5, s_4_4, -1, 3, 0}, +{ 4, s_4_5, -1, 1, 0}, +{ 4, s_4_6, -1, 1, 0}, +{ 4, s_4_7, -1, 11, 0}, +{ 4, s_4_8, -1, 1, 0}, +{ 3, s_4_9, -1, 8, 0}, +{ 2, s_4_10, -1, 8, 0}, +{ 5, s_4_11, -1, 4, 0}, +{ 5, s_4_12, -1, 2, 0}, +{ 5, s_4_13, -1, 4, 0}, +{ 5, s_4_14, -1, 2, 0}, +{ 5, s_4_15, -1, 1, 0}, +{ 7, s_4_16, -1, 2, 0}, +{ 5, s_4_17, -1, 1, 0}, +{ 5, s_4_18, -1, 5, 0}, +{ 6, s_4_19, -1, 3, 0}, +{ 5, s_4_20, -1, 1, 0}, +{ 5, s_4_21, -1, 1, 0}, +{ 5, s_4_22, -1, 11, 0}, +{ 5, s_4_23, -1, 1, 0}, +{ 4, s_4_24, -1, 8, 0}, +{ 3, s_4_25, -1, 8, 0}, +{ 6, s_4_26, -1, 4, 0}, +{ 6, s_4_27, -1, 2, 0}, +{ 6, s_4_28, -1, 4, 0}, +{ 6, s_4_29, -1, 2, 0}, +{ 5, s_4_30, -1, 15, 0}, +{ 6, s_4_31, 30, 6, 0}, +{ 9, s_4_32, 31, 12, 0}, +{ 4, s_4_33, -1, 7, 0}, +{ 4, s_4_34, -1, 15, 0}, +{ 5, s_4_35, 34, 6, 0}, +{ 8, s_4_36, 35, 12, 0}, +{ 6, s_4_37, 34, 13, 0}, +{ 6, s_4_38, 34, 14, 0}, +{ 3, s_4_39, -1, 10, 0}, +{ 4, s_4_40, 39, 9, 0}, +{ 3, s_4_41, -1, 1, 0}, +{ 3, s_4_42, -1, 7, 0} }; static const symbol s_5_0[3] = { 'i', 'r', 'a' }; @@ -219,41 +219,41 @@ static const symbol s_5_34[5] = { 'i', 's', 's', 'e', 'z' }; static const struct among a_5[35] = { -/* 0 */ { 3, s_5_0, -1, 1, 0}, -/* 1 */ { 2, s_5_1, -1, 1, 0}, -/* 2 */ { 4, s_5_2, -1, 1, 0}, -/* 3 */ { 7, s_5_3, -1, 1, 0}, -/* 4 */ { 1, s_5_4, -1, 1, 0}, -/* 5 */ { 4, s_5_5, 4, 1, 0}, -/* 6 */ { 2, s_5_6, -1, 1, 0}, -/* 7 */ { 4, s_5_7, -1, 1, 0}, -/* 8 */ { 3, s_5_8, -1, 1, 0}, -/* 9 */ { 4, s_5_9, -1, 1, 0}, -/* 10 */ { 5, s_5_10, -1, 1, 0}, -/* 11 */ { 8, s_5_11, -1, 1, 0}, -/* 12 */ { 4, s_5_12, -1, 1, 0}, -/* 13 */ { 2, s_5_13, -1, 1, 0}, -/* 14 */ { 5, s_5_14, 13, 1, 0}, -/* 15 */ { 6, s_5_15, 13, 1, 0}, -/* 16 */ { 6, s_5_16, -1, 1, 0}, -/* 17 */ { 7, s_5_17, -1, 1, 0}, -/* 18 */ { 5, s_5_18, -1, 1, 0}, -/* 19 */ { 6, s_5_19, -1, 1, 0}, -/* 20 */ { 7, s_5_20, -1, 1, 0}, -/* 21 */ { 2, s_5_21, -1, 1, 0}, -/* 22 */ { 5, s_5_22, 21, 1, 0}, -/* 23 */ { 6, s_5_23, 21, 1, 0}, -/* 24 */ { 6, s_5_24, -1, 1, 0}, -/* 25 */ { 7, s_5_25, -1, 1, 0}, -/* 26 */ { 8, s_5_26, -1, 1, 0}, -/* 27 */ { 5, s_5_27, -1, 1, 0}, -/* 28 */ { 6, s_5_28, -1, 1, 0}, -/* 29 */ { 5, s_5_29, -1, 1, 0}, -/* 30 */ { 2, s_5_30, -1, 1, 0}, -/* 31 */ { 5, s_5_31, -1, 1, 0}, -/* 32 */ { 6, s_5_32, -1, 1, 0}, -/* 33 */ { 4, s_5_33, -1, 1, 0}, -/* 34 */ { 5, s_5_34, -1, 1, 0} +{ 3, s_5_0, -1, 1, 0}, +{ 2, s_5_1, -1, 1, 0}, +{ 4, s_5_2, -1, 1, 0}, +{ 7, s_5_3, -1, 1, 0}, +{ 1, s_5_4, -1, 1, 0}, +{ 4, s_5_5, 4, 1, 0}, +{ 2, s_5_6, -1, 1, 0}, +{ 4, s_5_7, -1, 1, 0}, +{ 3, s_5_8, -1, 1, 0}, +{ 4, s_5_9, -1, 1, 0}, +{ 5, s_5_10, -1, 1, 0}, +{ 8, s_5_11, -1, 1, 0}, +{ 4, s_5_12, -1, 1, 0}, +{ 2, s_5_13, -1, 1, 0}, +{ 5, s_5_14, 13, 1, 0}, +{ 6, s_5_15, 13, 1, 0}, +{ 6, s_5_16, -1, 1, 0}, +{ 7, s_5_17, -1, 1, 0}, +{ 5, s_5_18, -1, 1, 0}, +{ 6, s_5_19, -1, 1, 0}, +{ 7, s_5_20, -1, 1, 0}, +{ 2, s_5_21, -1, 1, 0}, +{ 5, s_5_22, 21, 1, 0}, +{ 6, s_5_23, 21, 1, 0}, +{ 6, s_5_24, -1, 1, 0}, +{ 7, s_5_25, -1, 1, 0}, +{ 8, s_5_26, -1, 1, 0}, +{ 5, s_5_27, -1, 1, 0}, +{ 6, s_5_28, -1, 1, 0}, +{ 5, s_5_29, -1, 1, 0}, +{ 2, s_5_30, -1, 1, 0}, +{ 5, s_5_31, -1, 1, 0}, +{ 6, s_5_32, -1, 1, 0}, +{ 4, s_5_33, -1, 1, 0}, +{ 5, s_5_34, -1, 1, 0} }; static const symbol s_6_0[1] = { 'a' }; @@ -297,44 +297,44 @@ static const symbol s_6_37[1] = { 0xE9 }; static const struct among a_6[38] = { -/* 0 */ { 1, s_6_0, -1, 3, 0}, -/* 1 */ { 3, s_6_1, 0, 2, 0}, -/* 2 */ { 4, s_6_2, -1, 3, 0}, -/* 3 */ { 4, s_6_3, -1, 3, 0}, -/* 4 */ { 2, s_6_4, -1, 2, 0}, -/* 5 */ { 2, s_6_5, -1, 3, 0}, -/* 6 */ { 4, s_6_6, 5, 2, 0}, -/* 7 */ { 2, s_6_7, -1, 2, 0}, -/* 8 */ { 2, s_6_8, -1, 3, 0}, -/* 9 */ { 4, s_6_9, 8, 2, 0}, -/* 10 */ { 4, s_6_10, -1, 3, 0}, -/* 11 */ { 5, s_6_11, -1, 3, 0}, -/* 12 */ { 5, s_6_12, -1, 3, 0}, -/* 13 */ { 4, s_6_13, -1, 3, 0}, -/* 14 */ { 3, s_6_14, -1, 2, 0}, -/* 15 */ { 3, s_6_15, -1, 3, 0}, -/* 16 */ { 5, s_6_16, 15, 2, 0}, -/* 17 */ { 4, s_6_17, -1, 1, 0}, -/* 18 */ { 6, s_6_18, 17, 2, 0}, -/* 19 */ { 7, s_6_19, 17, 3, 0}, -/* 20 */ { 5, s_6_20, -1, 2, 0}, -/* 21 */ { 4, s_6_21, -1, 3, 0}, -/* 22 */ { 2, s_6_22, -1, 2, 0}, -/* 23 */ { 3, s_6_23, -1, 3, 0}, -/* 24 */ { 5, s_6_24, 23, 2, 0}, -/* 25 */ { 3, s_6_25, -1, 3, 0}, -/* 26 */ { 5, s_6_26, -1, 3, 0}, -/* 27 */ { 7, s_6_27, 26, 2, 0}, -/* 28 */ { 5, s_6_28, -1, 2, 0}, -/* 29 */ { 6, s_6_29, -1, 3, 0}, -/* 30 */ { 5, s_6_30, -1, 2, 0}, -/* 31 */ { 2, s_6_31, -1, 3, 0}, -/* 32 */ { 2, s_6_32, -1, 2, 0}, -/* 33 */ { 3, s_6_33, 32, 2, 0}, -/* 34 */ { 5, s_6_34, 33, 2, 0}, -/* 35 */ { 6, s_6_35, 33, 3, 0}, -/* 36 */ { 4, s_6_36, 32, 2, 0}, -/* 37 */ { 1, s_6_37, -1, 2, 0} +{ 1, s_6_0, -1, 3, 0}, +{ 3, s_6_1, 0, 2, 0}, +{ 4, s_6_2, -1, 3, 0}, +{ 4, s_6_3, -1, 3, 0}, +{ 2, s_6_4, -1, 2, 0}, +{ 2, s_6_5, -1, 3, 0}, +{ 4, s_6_6, 5, 2, 0}, +{ 2, s_6_7, -1, 2, 0}, +{ 2, s_6_8, -1, 3, 0}, +{ 4, s_6_9, 8, 2, 0}, +{ 4, s_6_10, -1, 3, 0}, +{ 5, s_6_11, -1, 3, 0}, +{ 5, s_6_12, -1, 3, 0}, +{ 4, s_6_13, -1, 3, 0}, +{ 3, s_6_14, -1, 2, 0}, +{ 3, s_6_15, -1, 3, 0}, +{ 5, s_6_16, 15, 2, 0}, +{ 4, s_6_17, -1, 1, 0}, +{ 6, s_6_18, 17, 2, 0}, +{ 7, s_6_19, 17, 3, 0}, +{ 5, s_6_20, -1, 2, 0}, +{ 4, s_6_21, -1, 3, 0}, +{ 2, s_6_22, -1, 2, 0}, +{ 3, s_6_23, -1, 3, 0}, +{ 5, s_6_24, 23, 2, 0}, +{ 3, s_6_25, -1, 3, 0}, +{ 5, s_6_26, -1, 3, 0}, +{ 7, s_6_27, 26, 2, 0}, +{ 5, s_6_28, -1, 2, 0}, +{ 6, s_6_29, -1, 3, 0}, +{ 5, s_6_30, -1, 2, 0}, +{ 2, s_6_31, -1, 3, 0}, +{ 2, s_6_32, -1, 2, 0}, +{ 3, s_6_33, 32, 2, 0}, +{ 5, s_6_34, 33, 2, 0}, +{ 6, s_6_35, 33, 3, 0}, +{ 4, s_6_36, 32, 2, 0}, +{ 1, s_6_37, -1, 2, 0} }; static const symbol s_7_0[1] = { 'e' }; @@ -346,12 +346,12 @@ static const symbol s_7_5[3] = { 'i', 'e', 'r' }; static const struct among a_7[6] = { -/* 0 */ { 1, s_7_0, -1, 3, 0}, -/* 1 */ { 4, s_7_1, 0, 2, 0}, -/* 2 */ { 4, s_7_2, 0, 2, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 3, s_7_4, -1, 2, 0}, -/* 5 */ { 3, s_7_5, -1, 2, 0} +{ 1, s_7_0, -1, 3, 0}, +{ 4, s_7_1, 0, 2, 0}, +{ 4, s_7_2, 0, 2, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 3, s_7_4, -1, 2, 0}, +{ 3, s_7_5, -1, 2, 0} }; static const symbol s_8_0[3] = { 'e', 'l', 'l' }; @@ -362,11 +362,11 @@ static const symbol s_8_4[3] = { 'e', 't', 't' }; static const struct among a_8[5] = { -/* 0 */ { 3, s_8_0, -1, -1, 0}, -/* 1 */ { 4, s_8_1, -1, -1, 0}, -/* 2 */ { 3, s_8_2, -1, -1, 0}, -/* 3 */ { 3, s_8_3, -1, -1, 0}, -/* 4 */ { 3, s_8_4, -1, -1, 0} +{ 3, s_8_0, -1, -1, 0}, +{ 4, s_8_1, -1, -1, 0}, +{ 3, s_8_2, -1, -1, 0}, +{ 3, s_8_3, -1, -1, 0}, +{ 3, s_8_4, -1, -1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 }; @@ -409,40 +409,39 @@ static const symbol s_32[] = { 'e' }; static const symbol s_33[] = { 'i' }; static const symbol s_34[] = { 'c' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ -/* repeat, line 38 */ - - while(1) { int c1 = z->c; - while(1) { /* goto, line 38 */ +static int r_prelude(struct SN_env * z) { + while(1) { + int c1 = z->c; + while(1) { int c2 = z->c; - { int c3 = z->c; /* or, line 44 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab3; /* grouping v, line 40 */ - z->bra = z->c; /* [, line 40 */ - { int c4 = z->c; /* or, line 40 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab5; /* literal, line 40 */ + { int c3 = z->c; + if (in_grouping(z, g_v, 97, 251, 0)) goto lab3; + z->bra = z->c; + { int c4 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab5; z->c++; - z->ket = z->c; /* ], line 40 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab5; /* grouping v, line 40 */ - { int ret = slice_from_s(z, 1, s_0); /* <-, line 40 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 251, 0)) goto lab5; + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } goto lab4; lab5: z->c = c4; - if (z->c == z->l || z->p[z->c] != 'i') goto lab6; /* literal, line 41 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab6; z->c++; - z->ket = z->c; /* ], line 41 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab6; /* grouping v, line 41 */ - { int ret = slice_from_s(z, 1, s_1); /* <-, line 41 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 251, 0)) goto lab6; + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } goto lab4; lab6: z->c = c4; - if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 42 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; z->c++; - z->ket = z->c; /* ], line 42 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 42 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } } @@ -450,44 +449,44 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ goto lab2; lab3: z->c = c3; - z->bra = z->c; /* [, line 45 */ - if (z->c == z->l || z->p[z->c] != 0xEB) goto lab7; /* literal, line 45 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 0xEB) goto lab7; z->c++; - z->ket = z->c; /* ], line 45 */ - { int ret = slice_from_s(z, 2, s_3); /* <-, line 45 */ + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_3); if (ret < 0) return ret; } goto lab2; lab7: z->c = c3; - z->bra = z->c; /* [, line 47 */ - if (z->c == z->l || z->p[z->c] != 0xEF) goto lab8; /* literal, line 47 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 0xEF) goto lab8; z->c++; - z->ket = z->c; /* ], line 47 */ - { int ret = slice_from_s(z, 2, s_4); /* <-, line 47 */ + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_4); if (ret < 0) return ret; } goto lab2; lab8: z->c = c3; - z->bra = z->c; /* [, line 49 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab9; /* literal, line 49 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab9; z->c++; - z->ket = z->c; /* ], line 49 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab9; /* grouping v, line 49 */ - { int ret = slice_from_s(z, 1, s_5); /* <-, line 49 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 251, 0)) goto lab9; + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } goto lab2; lab9: z->c = c3; - if (z->c == z->l || z->p[z->c] != 'q') goto lab1; /* literal, line 51 */ + if (z->c == z->l || z->p[z->c] != 'q') goto lab1; z->c++; - z->bra = z->c; /* [, line 51 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab1; /* literal, line 51 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab1; z->c++; - z->ket = z->c; /* ], line 51 */ - { int ret = slice_from_s(z, 1, s_6); /* <-, line 51 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } } @@ -497,7 +496,7 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ lab1: z->c = c2; if (z->c >= z->l) goto lab0; - z->c++; /* goto, line 38 */ + z->c++; } continue; lab0: @@ -507,110 +506,109 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 56 */ - z->I[1] = z->l; /* $p1 = , line 57 */ - z->I[2] = z->l; /* $p2 = , line 58 */ - { int c1 = z->c; /* do, line 60 */ - { int c2 = z->c; /* or, line 62 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; if (z->c >= z->l) goto lab2; - z->c++; /* next, line 61 */ + z->c++; goto lab1; lab2: z->c = c2; - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; /* among, line 63 */ + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; if (!(find_among(z, a_0, 3))) goto lab3; goto lab1; lab3: z->c = c2; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 70 */ - { /* gopast */ /* grouping v, line 70 */ + z->c++; + { int ret = out_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab0; z->c += ret; } } lab1: - z->I[0] = z->c; /* setmark pV, line 71 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c3 = z->c; /* do, line 73 */ - { /* gopast */ /* grouping v, line 74 */ + { int c3 = z->c; + { int ret = out_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 74 */ + { int ret = in_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 74 */ - { /* gopast */ /* grouping v, line 75 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 75 */ + { int ret = in_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 75 */ + z->I[0] = z->c; lab4: z->c = c3; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 79 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 81 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652352 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 7; else /* substring, line 81 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652352 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 7; else among_var = find_among(z, a_1, 7); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 81 */ - switch (among_var) { /* among, line 81 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 82 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 83 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 84 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 85 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 86 */ + { int ret = slice_from_s(z, 1, s_11); if (ret < 0) return ret; } break; case 6: - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 7: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 88 */ + z->c++; break; } continue; @@ -621,59 +619,59 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 94 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 95 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 96 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 99 */ - among_var = find_among_b(z, a_4, 43); /* substring, line 99 */ + z->ket = z->c; + among_var = find_among_b(z, a_4, 43); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 99 */ - switch (among_var) { /* among, line 99 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 103 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 103 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 106 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 107 */ - z->ket = z->c; /* [, line 107 */ - if (!(eq_s_b(z, 2, s_12))) { z->c = z->l - m1; goto lab0; } /* literal, line 107 */ - z->bra = z->c; /* ], line 107 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 107 */ - { int ret = r_R2(z); /* call R2, line 107 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_12))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int m2 = z->l - z->c; (void)m2; + { int ret = r_R2(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 107 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m2; - { int ret = slice_from_s(z, 3, s_13); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_13); if (ret < 0) return ret; } } @@ -683,98 +681,98 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - { int ret = r_R2(z); /* call R2, line 111 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_14); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_14); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 114 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_15); /* <-, line 114 */ + { int ret = slice_from_s(z, 1, s_15); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 117 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_16); /* <-, line 117 */ + { int ret = slice_from_s(z, 3, s_16); if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); /* call RV, line 121 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 121 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 122 */ - z->ket = z->c; /* [, line 123 */ - among_var = find_among_b(z, a_2, 6); /* substring, line 123 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + among_var = find_among_b(z, a_2, 6); if (!(among_var)) { z->c = z->l - m3; goto lab3; } - z->bra = z->c; /* ], line 123 */ - switch (among_var) { /* among, line 123 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 124 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 124 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 124 */ - if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m3; goto lab3; } /* literal, line 124 */ - z->bra = z->c; /* ], line 124 */ - { int ret = r_R2(z); /* call R2, line 124 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m3; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 124 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m4 = z->l - z->c; (void)m4; /* or, line 125 */ - { int ret = r_R2(z); /* call R2, line 125 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_R2(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m4; - { int ret = r_R1(z); /* call R1, line 125 */ + { int ret = r_R1(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 3, s_18); /* <-, line 125 */ + { int ret = slice_from_s(z, 3, s_18); if (ret < 0) return ret; } } lab4: break; case 3: - { int ret = r_R2(z); /* call R2, line 127 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 127 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 4: - { int ret = r_RV(z); /* call RV, line 129 */ + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 1, s_19); /* <-, line 129 */ + { int ret = slice_from_s(z, 1, s_19); if (ret < 0) return ret; } break; @@ -784,61 +782,61 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 7: - { int ret = r_R2(z); /* call R2, line 136 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 136 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* try, line 137 */ - z->ket = z->c; /* [, line 138 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m5; goto lab6; } /* substring, line 138 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m5; goto lab6; } among_var = find_among_b(z, a_3, 3); if (!(among_var)) { z->c = z->l - m5; goto lab6; } - z->bra = z->c; /* ], line 138 */ - switch (among_var) { /* among, line 138 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m6 = z->l - z->c; (void)m6; /* or, line 139 */ - { int ret = r_R2(z); /* call R2, line 139 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_R2(z); if (ret == 0) goto lab8; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m6; - { int ret = slice_from_s(z, 3, s_20); /* <-, line 139 */ + { int ret = slice_from_s(z, 3, s_20); if (ret < 0) return ret; } } lab7: break; case 2: - { int m7 = z->l - z->c; (void)m7; /* or, line 140 */ - { int ret = r_R2(z); /* call R2, line 140 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_R2(z); if (ret == 0) goto lab10; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 140 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab9; lab10: z->c = z->l - m7; - { int ret = slice_from_s(z, 3, s_21); /* <-, line 140 */ + { int ret = slice_from_s(z, 3, s_21); if (ret < 0) return ret; } } lab9: break; case 3: - { int ret = r_R2(z); /* call R2, line 141 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 141 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -848,38 +846,38 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 148 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 148 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m8 = z->l - z->c; (void)m8; /* try, line 149 */ - z->ket = z->c; /* [, line 149 */ - if (!(eq_s_b(z, 2, s_22))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ - z->bra = z->c; /* ], line 149 */ - { int ret = r_R2(z); /* call R2, line 149 */ + { int m8 = z->l - z->c; (void)m8; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_22))) { z->c = z->l - m8; goto lab11; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m8; goto lab11; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 149 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 149 */ - if (!(eq_s_b(z, 2, s_23))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ - z->bra = z->c; /* ], line 149 */ - { int m9 = z->l - z->c; (void)m9; /* or, line 149 */ - { int ret = r_R2(z); /* call R2, line 149 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_23))) { z->c = z->l - m8; goto lab11; } + z->bra = z->c; + { int m9 = z->l - z->c; (void)m9; + { int ret = r_R2(z); if (ret == 0) goto lab13; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 149 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab12; lab13: z->c = z->l - m9; - { int ret = slice_from_s(z, 3, s_24); /* <-, line 149 */ + { int ret = slice_from_s(z, 3, s_24); if (ret < 0) return ret; } } @@ -889,101 +887,101 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = slice_from_s(z, 3, s_25); /* <-, line 151 */ + { int ret = slice_from_s(z, 3, s_25); if (ret < 0) return ret; } break; case 10: - { int ret = r_R1(z); /* call R1, line 152 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_26); /* <-, line 152 */ + { int ret = slice_from_s(z, 2, s_26); if (ret < 0) return ret; } break; case 11: - { int m10 = z->l - z->c; (void)m10; /* or, line 154 */ - { int ret = r_R2(z); /* call R2, line 154 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_R2(z); if (ret == 0) goto lab15; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 154 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab14; lab15: z->c = z->l - m10; - { int ret = r_R1(z); /* call R1, line 154 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_27); /* <-, line 154 */ + { int ret = slice_from_s(z, 3, s_27); if (ret < 0) return ret; } } lab14: break; case 12: - { int ret = r_R1(z); /* call R1, line 157 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - if (out_grouping_b(z, g_v, 97, 251, 0)) return 0; /* non v, line 157 */ - { int ret = slice_del(z); /* delete, line 157 */ + if (out_grouping_b(z, g_v, 97, 251, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 13: - { int ret = r_RV(z); /* call RV, line 162 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_28); /* <-, line 162 */ + { int ret = slice_from_s(z, 3, s_28); if (ret < 0) return ret; } - return 0; /* fail, line 162 */ + return 0; break; case 14: - { int ret = r_RV(z); /* call RV, line 163 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_29); /* <-, line 163 */ + { int ret = slice_from_s(z, 3, s_29); if (ret < 0) return ret; } - return 0; /* fail, line 163 */ + return 0; break; case 15: - { int m_test11 = z->l - z->c; /* test, line 165 */ - if (in_grouping_b(z, g_v, 97, 251, 0)) return 0; /* grouping v, line 165 */ - { int ret = r_RV(z); /* call RV, line 165 */ + { int m_test11 = z->l - z->c; + if (in_grouping_b(z, g_v, 97, 251, 0)) return 0; + { int ret = r_RV(z); if (ret <= 0) return ret; } z->c = z->l - m_test11; } - { int ret = slice_del(z); /* delete, line 165 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - return 0; /* fail, line 165 */ + return 0; break; } return 1; } -static int r_i_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_i_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 170 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 171 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 171 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_5, 35))) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 171 */ - { int m2 = z->l - z->c; (void)m2; /* not, line 177 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'H') goto lab0; /* literal, line 177 */ + z->bra = z->c; + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'H') goto lab0; z->c--; { z->lb = mlimit1; return 0; } lab0: z->c = z->l - m2; } - if (out_grouping_b(z, g_v, 97, 251, 0)) { z->lb = mlimit1; return 0; } /* non v, line 177 */ - { int ret = slice_del(z); /* delete, line 177 */ + if (out_grouping_b(z, g_v, 97, 251, 0)) { z->lb = mlimit1; return 0; } + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; @@ -991,41 +989,41 @@ static int r_i_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 181 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 182 */ - among_var = find_among_b(z, a_6, 38); /* substring, line 182 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + among_var = find_among_b(z, a_6, 38); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 182 */ - switch (among_var) { /* among, line 182 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 184 */ + { int ret = r_R2(z); if (ret == 0) { z->lb = mlimit1; return 0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 184 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 192 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 197 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 198 */ - z->ket = z->c; /* [, line 198 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') { z->c = z->l - m2; goto lab0; } /* literal, line 198 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') { z->c = z->l - m2; goto lab0; } z->c--; - z->bra = z->c; /* ], line 198 */ - { int ret = slice_del(z); /* delete, line 198 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -1038,66 +1036,66 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ +static int r_residual_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* try, line 206 */ - z->ket = z->c; /* [, line 206 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m1; goto lab0; } /* literal, line 206 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m1; goto lab0; } z->c--; - z->bra = z->c; /* ], line 206 */ - { int m_test2 = z->l - z->c; /* test, line 206 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 206 */ - if (!(eq_s_b(z, 2, s_30))) goto lab2; /* literal, line 206 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + { int m3 = z->l - z->c; (void)m3; + if (!(eq_s_b(z, 2, s_30))) goto lab2; goto lab1; lab2: z->c = z->l - m3; - if (out_grouping_b(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m1; goto lab0; } /* non keep_with_s, line 206 */ + if (out_grouping_b(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m1; goto lab0; } } lab1: z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 206 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: ; } - { int mlimit4; /* setlimit, line 207 */ - if (z->c < z->I[0]) return 0; - mlimit4 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 208 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((278560 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit4; return 0; } /* substring, line 208 */ + { int mlimit4; + if (z->c < z->I[2]) return 0; + mlimit4 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((278560 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit4; return 0; } among_var = find_among_b(z, a_7, 6); if (!(among_var)) { z->lb = mlimit4; return 0; } - z->bra = z->c; /* ], line 208 */ - switch (among_var) { /* among, line 208 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 209 */ + { int ret = r_R2(z); if (ret == 0) { z->lb = mlimit4; return 0; } if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* or, line 209 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab4; /* literal, line 209 */ + { int m5 = z->l - z->c; (void)m5; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab4; z->c--; goto lab3; lab4: z->c = z->l - m5; - if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit4; return 0; } /* literal, line 209 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit4; return 0; } z->c--; } lab3: - { int ret = slice_del(z); /* delete, line 209 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_31); /* <-, line 211 */ + { int ret = slice_from_s(z, 1, s_31); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 212 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1107,25 +1105,26 @@ static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_un_double(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 218 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 218 */ +static int r_un_double(struct SN_env * z) { + { int m_test1 = z->l - z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_8, 5))) return 0; z->c = z->l - m_test1; } - z->ket = z->c; /* [, line 218 */ + z->ket = z->c; if (z->c <= z->lb) return 0; - z->c--; /* next, line 218 */ - z->bra = z->c; /* ], line 218 */ - { int ret = slice_del(z); /* delete, line 218 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_un_accent(struct SN_env * z) { /* backwardmode */ +static int r_un_accent(struct SN_env * z) { { int i = 1; - while(1) { if (out_grouping_b(z, g_v, 97, 251, 0)) goto lab0; /* non v, line 222 */ + while(1) { + if (out_grouping_b(z, g_v, 97, 251, 0)) goto lab0; i--; continue; lab0: @@ -1133,78 +1132,78 @@ static int r_un_accent(struct SN_env * z) { /* backwardmode */ } if (i > 0) return 0; } - z->ket = z->c; /* [, line 223 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 223 */ - if (z->c <= z->lb || z->p[z->c - 1] != 0xE9) goto lab2; /* literal, line 223 */ + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 0xE9) goto lab2; z->c--; goto lab1; lab2: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 0xE8) return 0; /* literal, line 223 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xE8) return 0; z->c--; } lab1: - z->bra = z->c; /* ], line 223 */ - { int ret = slice_from_s(z, 1, s_32); /* <-, line 223 */ + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_32); if (ret < 0) return ret; } return 1; } -extern int french_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 229 */ - { int ret = r_prelude(z); /* call prelude, line 229 */ +extern int french_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 230 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 230 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 231 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 233 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 243 */ - { int m4 = z->l - z->c; (void)m4; /* and, line 239 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 235 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 235 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab3; lab4: z->c = z->l - m5; - { int ret = r_i_verb_suffix(z); /* call i_verb_suffix, line 236 */ + { int ret = r_i_verb_suffix(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab3; lab5: z->c = z->l - m5; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 237 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: z->c = z->l - m4; - { int m6 = z->l - z->c; (void)m6; /* try, line 240 */ - z->ket = z->c; /* [, line 240 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 240 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'Y') goto lab8; /* literal, line 240 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + { int m7 = z->l - z->c; (void)m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') goto lab8; z->c--; - z->bra = z->c; /* ], line 240 */ - { int ret = slice_from_s(z, 1, s_33); /* <-, line 240 */ + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_33); if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m7; - if (z->c <= z->lb || z->p[z->c - 1] != 0xE7) { z->c = z->l - m6; goto lab6; } /* literal, line 241 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xE7) { z->c = z->l - m6; goto lab6; } z->c--; - z->bra = z->c; /* ], line 241 */ - { int ret = slice_from_s(z, 1, s_34); /* <-, line 241 */ + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_34); if (ret < 0) return ret; } } @@ -1216,7 +1215,7 @@ extern int french_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = z->l - m3; - { int ret = r_residual_suffix(z); /* call residual_suffix, line 244 */ + { int ret = r_residual_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1225,21 +1224,21 @@ extern int french_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m8 = z->l - z->c; (void)m8; /* do, line 249 */ - { int ret = r_un_double(z); /* call un_double, line 249 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_un_double(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 250 */ - { int ret = r_un_accent(z); /* call un_accent, line 250 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_un_accent(z); if (ret < 0) return ret; } z->c = z->l - m9; } z->c = z->lb; - { int c10 = z->c; /* do, line 252 */ - { int ret = r_postlude(z); /* call postlude, line 252 */ + { int c10 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c10; @@ -1247,7 +1246,7 @@ extern int french_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * french_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * french_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void french_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c index 48d6fbc294a1..5c5cfb6e80a0 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -35,12 +35,12 @@ static const symbol s_0_5[1] = { 0xFC }; static const struct among a_0[6] = { -/* 0 */ { 0, 0, -1, 5, 0}, -/* 1 */ { 1, s_0_1, 0, 2, 0}, -/* 2 */ { 1, s_0_2, 0, 1, 0}, -/* 3 */ { 1, s_0_3, 0, 3, 0}, -/* 4 */ { 1, s_0_4, 0, 4, 0}, -/* 5 */ { 1, s_0_5, 0, 2, 0} +{ 0, 0, -1, 5, 0}, +{ 1, s_0_1, 0, 2, 0}, +{ 1, s_0_2, 0, 1, 0}, +{ 1, s_0_3, 0, 3, 0}, +{ 1, s_0_4, 0, 4, 0}, +{ 1, s_0_5, 0, 2, 0} }; static const symbol s_1_0[1] = { 'e' }; @@ -53,13 +53,13 @@ static const symbol s_1_6[2] = { 'e', 's' }; static const struct among a_1[7] = { -/* 0 */ { 1, s_1_0, -1, 2, 0}, -/* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 2, 0}, -/* 3 */ { 3, s_1_3, -1, 1, 0}, -/* 4 */ { 2, s_1_4, -1, 1, 0}, -/* 5 */ { 1, s_1_5, -1, 3, 0}, -/* 6 */ { 2, s_1_6, 5, 2, 0} +{ 1, s_1_0, -1, 2, 0}, +{ 2, s_1_1, -1, 1, 0}, +{ 2, s_1_2, -1, 2, 0}, +{ 3, s_1_3, -1, 1, 0}, +{ 2, s_1_4, -1, 1, 0}, +{ 1, s_1_5, -1, 3, 0}, +{ 2, s_1_6, 5, 2, 0} }; static const symbol s_2_0[2] = { 'e', 'n' }; @@ -69,10 +69,10 @@ static const symbol s_2_3[3] = { 'e', 's', 't' }; static const struct among a_2[4] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 2, s_2_1, -1, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 2, 0}, -/* 3 */ { 3, s_2_3, 2, 1, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 2, s_2_1, -1, 1, 0}, +{ 2, s_2_2, -1, 2, 0}, +{ 3, s_2_3, 2, 1, 0} }; static const symbol s_3_0[2] = { 'i', 'g' }; @@ -80,8 +80,8 @@ static const symbol s_3_1[4] = { 'l', 'i', 'c', 'h' }; static const struct among a_3[2] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0} }; static const symbol s_4_0[3] = { 'e', 'n', 'd' }; @@ -95,14 +95,14 @@ static const symbol s_4_7[4] = { 'k', 'e', 'i', 't' }; static const struct among a_4[8] = { -/* 0 */ { 3, s_4_0, -1, 1, 0}, -/* 1 */ { 2, s_4_1, -1, 2, 0}, -/* 2 */ { 3, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 3, 0}, -/* 4 */ { 4, s_4_4, -1, 2, 0}, -/* 5 */ { 2, s_4_5, -1, 2, 0}, -/* 6 */ { 4, s_4_6, -1, 3, 0}, -/* 7 */ { 4, s_4_7, -1, 4, 0} +{ 3, s_4_0, -1, 1, 0}, +{ 2, s_4_1, -1, 2, 0}, +{ 3, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 3, 0}, +{ 4, s_4_4, -1, 2, 0}, +{ 2, s_4_5, -1, 2, 0}, +{ 4, s_4_6, -1, 3, 0}, +{ 4, s_4_7, -1, 4, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8 }; @@ -123,24 +123,23 @@ static const symbol s_8[] = { 'i', 'g' }; static const symbol s_9[] = { 'e', 'r' }; static const symbol s_10[] = { 'e', 'n' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ - { int c_test1 = z->c; /* test, line 35 */ -/* repeat, line 35 */ - - while(1) { int c2 = z->c; - { int c3 = z->c; /* or, line 38 */ - z->bra = z->c; /* [, line 37 */ - if (z->c == z->l || z->p[z->c] != 0xDF) goto lab2; /* literal, line 37 */ +static int r_prelude(struct SN_env * z) { + { int c_test1 = z->c; + while(1) { + int c2 = z->c; + { int c3 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 0xDF) goto lab2; z->c++; - z->ket = z->c; /* ], line 37 */ - { int ret = slice_from_s(z, 2, s_0); /* <-, line 37 */ + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } goto lab1; lab2: z->c = c3; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 38 */ + z->c++; } lab1: continue; @@ -150,29 +149,28 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ } z->c = c_test1; } -/* repeat, line 41 */ - - while(1) { int c4 = z->c; - while(1) { /* goto, line 41 */ + while(1) { + int c4 = z->c; + while(1) { int c5 = z->c; - if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 42 */ - z->bra = z->c; /* [, line 42 */ - { int c6 = z->c; /* or, line 42 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab6; /* literal, line 42 */ + if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; + z->bra = z->c; + { int c6 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab6; z->c++; - z->ket = z->c; /* ], line 42 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab6; /* grouping v, line 42 */ - { int ret = slice_from_s(z, 1, s_1); /* <-, line 42 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab6; + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } goto lab5; lab6: z->c = c6; - if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 43 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; z->c++; - z->ket = z->c; /* ], line 43 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 43 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 43 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } } @@ -182,7 +180,7 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ lab4: z->c = c5; if (z->c >= z->l) goto lab3; - z->c++; /* goto, line 41 */ + z->c++; } continue; lab3: @@ -192,79 +190,76 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 49 */ - z->I[1] = z->l; /* $p2 = , line 50 */ - { int c_test1 = z->c; /* test, line 52 */ - { int ret = z->c + 3; /* hop, line 52 */ - if (0 > ret || ret > z->l) return 0; - z->c = ret; - } - z->I[2] = z->c; /* setmark x, line 52 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + { int c_test1 = z->c; +z->c = z->c + 3; + if (z->c > z->l) return 0; + z->I[0] = z->c; z->c = c_test1; } - { /* gopast */ /* grouping v, line 54 */ + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 54 */ + { int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 54 */ - /* try, line 55 */ - if (!(z->I[0] < z->I[2])) goto lab0; /* $( < ), line 55 */ - z->I[0] = z->I[2]; /* $p1 = , line 55 */ + z->I[2] = z->c; + + if (!(z->I[2] < z->I[0])) goto lab0; + z->I[2] = z->I[0]; lab0: - { /* gopast */ /* grouping v, line 56 */ + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 56 */ + { int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 56 */ + z->I[1] = z->c; return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 60 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 62 */ - among_var = find_among(z, a_0, 6); /* substring, line 62 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + among_var = find_among(z, a_0, 6); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 62 */ - switch (among_var) { /* among, line 62 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 63 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 64 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 65 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 66 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 5: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 68 */ + z->c++; break; } continue; @@ -275,45 +270,45 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 75 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 76 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 79 */ - z->ket = z->c; /* [, line 80 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 80 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; among_var = find_among_b(z, a_1, 7); if (!(among_var)) goto lab0; - z->bra = z->c; /* ], line 80 */ - { int ret = r_R1(z); /* call R1, line 80 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } - switch (among_var) { /* among, line 80 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 82 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 85 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 86 */ - z->ket = z->c; /* [, line 86 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m2; goto lab1; } z->c--; - z->bra = z->c; /* ], line 86 */ - if (!(eq_s_b(z, 3, s_7))) { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ - { int ret = slice_del(z); /* delete, line 86 */ + z->bra = z->c; + if (!(eq_s_b(z, 3, s_7))) { z->c = z->l - m2; goto lab1; } + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: @@ -321,8 +316,8 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - if (in_grouping_b(z, g_s_ending, 98, 116, 0)) goto lab0; /* grouping s_ending, line 89 */ - { int ret = slice_del(z); /* delete, line 89 */ + if (in_grouping_b(z, g_s_ending, 98, 116, 0)) goto lab0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -330,29 +325,27 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab0: z->c = z->l - m1; } - { int m3 = z->l - z->c; (void)m3; /* do, line 93 */ - z->ket = z->c; /* [, line 94 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; /* substring, line 94 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; among_var = find_among_b(z, a_2, 4); if (!(among_var)) goto lab2; - z->bra = z->c; /* ], line 94 */ - { int ret = r_R1(z); /* call R1, line 94 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } - switch (among_var) { /* among, line 94 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (in_grouping_b(z, g_st_ending, 98, 116, 0)) goto lab2; /* grouping st_ending, line 99 */ - { int ret = z->c - 3; /* hop, line 99 */ - if (z->lb > ret || ret > z->l) goto lab2; - z->c = ret; - } - { int ret = slice_del(z); /* delete, line 99 */ + if (in_grouping_b(z, g_st_ending, 98, 116, 0)) goto lab2; +z->c = z->c - 3; + if (z->c < z->lb) goto lab2; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -360,37 +353,37 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab2: z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 103 */ - z->ket = z->c; /* [, line 104 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; /* substring, line 104 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; among_var = find_among_b(z, a_4, 8); if (!(among_var)) goto lab3; - z->bra = z->c; /* ], line 104 */ - { int ret = r_R2(z); /* call R2, line 104 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - switch (among_var) { /* among, line 104 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* try, line 107 */ - z->ket = z->c; /* [, line 107 */ - if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m5; goto lab4; } /* literal, line 107 */ - z->bra = z->c; /* ], line 107 */ - { int m6 = z->l - z->c; (void)m6; /* not, line 107 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab5; /* literal, line 107 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m5; goto lab4; } + z->bra = z->c; + { int m6 = z->l - z->c; (void)m6; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab5; z->c--; { z->c = z->l - m5; goto lab4; } lab5: z->c = z->l - m6; } - { int ret = r_R2(z); /* call R2, line 107 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 107 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab4: @@ -398,37 +391,37 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 2: - { int m7 = z->l - z->c; (void)m7; /* not, line 110 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; /* literal, line 110 */ + { int m7 = z->l - z->c; (void)m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; z->c--; goto lab3; lab6: z->c = z->l - m7; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 113 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m8 = z->l - z->c; (void)m8; /* try, line 114 */ - z->ket = z->c; /* [, line 115 */ - { int m9 = z->l - z->c; (void)m9; /* or, line 115 */ - if (!(eq_s_b(z, 2, s_9))) goto lab9; /* literal, line 115 */ + { int m8 = z->l - z->c; (void)m8; + z->ket = z->c; + { int m9 = z->l - z->c; (void)m9; + if (!(eq_s_b(z, 2, s_9))) goto lab9; goto lab8; lab9: z->c = z->l - m9; - if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m8; goto lab7; } /* literal, line 115 */ + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m8; goto lab7; } } lab8: - z->bra = z->c; /* ], line 115 */ - { int ret = r_R1(z); /* call R1, line 115 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret == 0) { z->c = z->l - m8; goto lab7; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 115 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab7: @@ -436,19 +429,19 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 4: - { int ret = slice_del(z); /* delete, line 119 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m10 = z->l - z->c; (void)m10; /* try, line 120 */ - z->ket = z->c; /* [, line 121 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m10; goto lab10; } /* substring, line 121 */ + { int m10 = z->l - z->c; (void)m10; + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m10; goto lab10; } if (!(find_among_b(z, a_3, 2))) { z->c = z->l - m10; goto lab10; } - z->bra = z->c; /* ], line 121 */ - { int ret = r_R2(z); /* call R2, line 121 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m10; goto lab10; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 123 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab10: @@ -462,28 +455,28 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int german_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 134 */ - { int ret = r_prelude(z); /* call prelude, line 134 */ +extern int german_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - { int c2 = z->c; /* do, line 135 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 135 */ + { int c2 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c2; } - z->lb = z->c; z->c = z->l; /* backwards, line 136 */ + z->lb = z->c; z->c = z->l; - /* do, line 137 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 137 */ + + { int ret = r_standard_suffix(z); if (ret < 0) return ret; } z->c = z->lb; - { int c3 = z->c; /* do, line 138 */ - { int ret = r_postlude(z); /* call postlude, line 138 */ + { int c3 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c3; @@ -491,7 +484,7 @@ extern int german_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * german_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * german_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void german_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_indonesian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_indonesian.c index 6e0c911d690f..5fda5450cf87 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_indonesian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_indonesian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -37,9 +37,9 @@ static const symbol s_0_2[3] = { 'p', 'u', 'n' }; static const struct among a_0[3] = { -/* 0 */ { 3, s_0_0, -1, 1, 0}, -/* 1 */ { 3, s_0_1, -1, 1, 0}, -/* 2 */ { 3, s_0_2, -1, 1, 0} +{ 3, s_0_0, -1, 1, 0}, +{ 3, s_0_1, -1, 1, 0}, +{ 3, s_0_2, -1, 1, 0} }; static const symbol s_1_0[3] = { 'n', 'y', 'a' }; @@ -48,9 +48,9 @@ static const symbol s_1_2[2] = { 'm', 'u' }; static const struct among a_1[3] = { -/* 0 */ { 3, s_1_0, -1, 1, 0}, -/* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0} +{ 3, s_1_0, -1, 1, 0}, +{ 2, s_1_1, -1, 1, 0}, +{ 2, s_1_2, -1, 1, 0} }; static const symbol s_2_0[1] = { 'i' }; @@ -59,9 +59,9 @@ static const symbol s_2_2[3] = { 'k', 'a', 'n' }; static const struct among a_2[3] = { -/* 0 */ { 1, s_2_0, -1, 1, r_SUFFIX_I_OK}, -/* 1 */ { 2, s_2_1, -1, 1, r_SUFFIX_AN_OK}, -/* 2 */ { 3, s_2_2, 1, 1, r_SUFFIX_KAN_OK} +{ 1, s_2_0, -1, 1, r_SUFFIX_I_OK}, +{ 2, s_2_1, -1, 1, r_SUFFIX_AN_OK}, +{ 3, s_2_2, 1, 1, r_SUFFIX_KAN_OK} }; static const symbol s_3_0[2] = { 'd', 'i' }; @@ -79,18 +79,18 @@ static const symbol s_3_11[3] = { 't', 'e', 'r' }; static const struct among a_3[12] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 2, s_3_1, -1, 2, 0}, -/* 2 */ { 2, s_3_2, -1, 1, 0}, -/* 3 */ { 3, s_3_3, 2, 5, 0}, -/* 4 */ { 3, s_3_4, 2, 1, 0}, -/* 5 */ { 4, s_3_5, 4, 1, 0}, -/* 6 */ { 4, s_3_6, 4, 3, r_VOWEL}, -/* 7 */ { 3, s_3_7, -1, 6, 0}, -/* 8 */ { 3, s_3_8, -1, 2, 0}, -/* 9 */ { 4, s_3_9, 8, 2, 0}, -/* 10 */ { 4, s_3_10, 8, 4, r_VOWEL}, -/* 11 */ { 3, s_3_11, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 2, s_3_1, -1, 2, 0}, +{ 2, s_3_2, -1, 1, 0}, +{ 3, s_3_3, 2, 5, 0}, +{ 3, s_3_4, 2, 1, 0}, +{ 4, s_3_5, 4, 1, 0}, +{ 4, s_3_6, 4, 3, r_VOWEL}, +{ 3, s_3_7, -1, 6, 0}, +{ 3, s_3_8, -1, 2, 0}, +{ 4, s_3_9, 8, 2, 0}, +{ 4, s_3_10, 8, 4, r_VOWEL}, +{ 3, s_3_11, -1, 1, 0} }; static const symbol s_4_0[2] = { 'b', 'e' }; @@ -102,12 +102,12 @@ static const symbol s_4_5[3] = { 'p', 'e', 'r' }; static const struct among a_4[6] = { -/* 0 */ { 2, s_4_0, -1, 3, r_KER}, -/* 1 */ { 7, s_4_1, 0, 4, 0}, -/* 2 */ { 3, s_4_2, 0, 3, 0}, -/* 3 */ { 2, s_4_3, -1, 1, 0}, -/* 4 */ { 7, s_4_4, 3, 2, 0}, -/* 5 */ { 3, s_4_5, 3, 1, 0} +{ 2, s_4_0, -1, 3, r_KER}, +{ 7, s_4_1, 0, 4, 0}, +{ 3, s_4_2, 0, 3, 0}, +{ 2, s_4_3, -1, 1, 0}, +{ 7, s_4_4, 3, 2, 0}, +{ 3, s_4_5, 3, 1, 0} }; static const unsigned char g_vowel[] = { 17, 65, 16 }; @@ -120,46 +120,46 @@ static const symbol s_4[] = { 'p' }; static const symbol s_5[] = { 'a', 'j', 'a', 'r' }; static const symbol s_6[] = { 'a', 'j', 'a', 'r' }; -static int r_remove_particle(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 51 */ - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 104 && z->p[z->c - 1] != 110)) return 0; /* substring, line 51 */ +static int r_remove_particle(struct SN_env * z) { + z->ket = z->c; + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 104 && z->p[z->c - 1] != 110)) return 0; if (!(find_among_b(z, a_0, 3))) return 0; - z->bra = z->c; /* ], line 51 */ - { int ret = slice_del(z); /* delete, line 52 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 52 */ + z->I[1] -= 1; return 1; } -static int r_remove_possessive_pronoun(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 57 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 117)) return 0; /* substring, line 57 */ +static int r_remove_possessive_pronoun(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 117)) return 0; if (!(find_among_b(z, a_1, 3))) return 0; - z->bra = z->c; /* ], line 57 */ - { int ret = slice_del(z); /* delete, line 58 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 58 */ + z->I[1] -= 1; return 1; } -static int r_SUFFIX_KAN_OK(struct SN_env * z) { /* backwardmode */ - /* and, line 85 */ - if (!(z->I[1] != 3)) return 0; /* $( != ), line 85 */ - if (!(z->I[1] != 2)) return 0; /* $( != ), line 85 */ +static int r_SUFFIX_KAN_OK(struct SN_env * z) { + + if (!(z->I[0] != 3)) return 0; + if (!(z->I[0] != 2)) return 0; return 1; } -static int r_SUFFIX_AN_OK(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] != 1)) return 0; /* $( != ), line 89 */ +static int r_SUFFIX_AN_OK(struct SN_env * z) { + if (!(z->I[0] != 1)) return 0; return 1; } -static int r_SUFFIX_I_OK(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= 2)) return 0; /* $( <= ), line 93 */ - { int m1 = z->l - z->c; (void)m1; /* not, line 128 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab0; /* literal, line 128 */ +static int r_SUFFIX_I_OK(struct SN_env * z) { + if (!(z->I[0] <= 2)) return 0; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab0; z->c--; return 0; lab0: @@ -168,100 +168,100 @@ static int r_SUFFIX_I_OK(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_remove_suffix(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 132 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 110)) return 0; /* substring, line 132 */ +static int r_remove_suffix(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 110)) return 0; if (!(find_among_b(z, a_2, 3))) return 0; - z->bra = z->c; /* ], line 132 */ - { int ret = slice_del(z); /* delete, line 134 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 134 */ + z->I[1] -= 1; return 1; } -static int r_VOWEL(struct SN_env * z) { /* forwardmode */ - if (in_grouping(z, g_vowel, 97, 117, 0)) return 0; /* grouping vowel, line 141 */ +static int r_VOWEL(struct SN_env * z) { + if (in_grouping(z, g_vowel, 97, 117, 0)) return 0; return 1; } -static int r_KER(struct SN_env * z) { /* forwardmode */ - if (out_grouping(z, g_vowel, 97, 117, 0)) return 0; /* non vowel, line 143 */ - if (!(eq_s(z, 2, s_0))) return 0; /* literal, line 143 */ +static int r_KER(struct SN_env * z) { + if (out_grouping(z, g_vowel, 97, 117, 0)) return 0; + if (!(eq_s(z, 2, s_0))) return 0; return 1; } -static int r_remove_first_order_prefix(struct SN_env * z) { /* forwardmode */ +static int r_remove_first_order_prefix(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 146 */ - if (z->c + 1 >= z->l || (z->p[z->c + 1] != 105 && z->p[z->c + 1] != 101)) return 0; /* substring, line 146 */ + z->bra = z->c; + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 105 && z->p[z->c + 1] != 101)) return 0; among_var = find_among(z, a_3, 12); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 146 */ - switch (among_var) { /* among, line 146 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 147 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 1; /* $prefix = , line 147 */ - z->I[0] -= 1; /* $measure -= , line 147 */ + z->I[0] = 1; + z->I[1] -= 1; break; case 2: - { int ret = slice_del(z); /* delete, line 148 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 3; /* $prefix = , line 148 */ - z->I[0] -= 1; /* $measure -= , line 148 */ + z->I[0] = 3; + z->I[1] -= 1; break; case 3: - z->I[1] = 1; /* $prefix = , line 149 */ - { int ret = slice_from_s(z, 1, s_1); /* <-, line 149 */ + z->I[0] = 1; + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 149 */ + z->I[1] -= 1; break; case 4: - z->I[1] = 3; /* $prefix = , line 150 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 150 */ + z->I[0] = 3; + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 150 */ + z->I[1] -= 1; break; case 5: - z->I[1] = 1; /* $prefix = , line 151 */ - z->I[0] -= 1; /* $measure -= , line 151 */ - { int c1 = z->c; /* or, line 151 */ - { int c2 = z->c; /* and, line 151 */ - if (in_grouping(z, g_vowel, 97, 117, 0)) goto lab1; /* grouping vowel, line 151 */ + z->I[0] = 1; + z->I[1] -= 1; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping(z, g_vowel, 97, 117, 0)) goto lab1; z->c = c2; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 151 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } } goto lab0; lab1: z->c = c1; - { int ret = slice_del(z); /* delete, line 151 */ + { int ret = slice_del(z); if (ret < 0) return ret; } } lab0: break; case 6: - z->I[1] = 3; /* $prefix = , line 152 */ - z->I[0] -= 1; /* $measure -= , line 152 */ - { int c3 = z->c; /* or, line 152 */ - { int c4 = z->c; /* and, line 152 */ - if (in_grouping(z, g_vowel, 97, 117, 0)) goto lab3; /* grouping vowel, line 152 */ + z->I[0] = 3; + z->I[1] -= 1; + { int c3 = z->c; + { int c4 = z->c; + if (in_grouping(z, g_vowel, 97, 117, 0)) goto lab3; z->c = c4; - { int ret = slice_from_s(z, 1, s_4); /* <-, line 152 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } } goto lab2; lab3: z->c = c3; - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } } @@ -271,57 +271,56 @@ static int r_remove_first_order_prefix(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_remove_second_order_prefix(struct SN_env * z) { /* forwardmode */ +static int r_remove_second_order_prefix(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 162 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] != 101) return 0; /* substring, line 162 */ + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] != 101) return 0; among_var = find_among(z, a_4, 6); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 162 */ - switch (among_var) { /* among, line 162 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 163 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 2; /* $prefix = , line 163 */ - z->I[0] -= 1; /* $measure -= , line 163 */ + z->I[0] = 2; + z->I[1] -= 1; break; case 2: - { int ret = slice_from_s(z, 4, s_5); /* <-, line 164 */ + { int ret = slice_from_s(z, 4, s_5); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 164 */ + z->I[1] -= 1; break; case 3: - { int ret = slice_del(z); /* delete, line 165 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 4; /* $prefix = , line 165 */ - z->I[0] -= 1; /* $measure -= , line 165 */ + z->I[0] = 4; + z->I[1] -= 1; break; case 4: - { int ret = slice_from_s(z, 4, s_6); /* <-, line 166 */ + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } - z->I[1] = 4; /* $prefix = , line 166 */ - z->I[0] -= 1; /* $measure -= , line 166 */ + z->I[0] = 4; + z->I[1] -= 1; break; } return 1; } -extern int indonesian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - z->I[0] = 0; /* $measure = , line 172 */ - { int c1 = z->c; /* do, line 173 */ -/* repeat, line 173 */ - - while(1) { int c2 = z->c; - { /* gopast */ /* grouping vowel, line 173 */ +extern int indonesian_ISO_8859_1_stem(struct SN_env * z) { + z->I[1] = 0; + { int c1 = z->c; + while(1) { + int c2 = z->c; + { int ret = out_grouping(z, g_vowel, 97, 117, 1); if (ret < 0) goto lab1; z->c += ret; } - z->I[0] += 1; /* $measure += , line 173 */ + z->I[1] += 1; continue; lab1: z->c = c2; @@ -329,45 +328,45 @@ extern int indonesian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ } z->c = c1; } - if (!(z->I[0] > 2)) return 0; /* $( > ), line 174 */ - z->I[1] = 0; /* $prefix = , line 175 */ - z->lb = z->c; z->c = z->l; /* backwards, line 176 */ + if (!(z->I[1] > 2)) return 0; + z->I[0] = 0; + z->lb = z->c; z->c = z->l; - { int m3 = z->l - z->c; (void)m3; /* do, line 177 */ - { int ret = r_remove_particle(z); /* call remove_particle, line 177 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_remove_particle(z); if (ret < 0) return ret; } z->c = z->l - m3; } - if (!(z->I[0] > 2)) return 0; /* $( > ), line 178 */ - { int m4 = z->l - z->c; (void)m4; /* do, line 179 */ - { int ret = r_remove_possessive_pronoun(z); /* call remove_possessive_pronoun, line 179 */ + if (!(z->I[1] > 2)) return 0; + { int m4 = z->l - z->c; (void)m4; + { int ret = r_remove_possessive_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m4; } z->c = z->lb; - if (!(z->I[0] > 2)) return 0; /* $( > ), line 181 */ - { int c5 = z->c; /* or, line 188 */ - { int c_test6 = z->c; /* test, line 182 */ - { int ret = r_remove_first_order_prefix(z); /* call remove_first_order_prefix, line 183 */ + if (!(z->I[1] > 2)) return 0; + { int c5 = z->c; + { int c_test6 = z->c; + { int ret = r_remove_first_order_prefix(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int c7 = z->c; /* do, line 184 */ - { int c_test8 = z->c; /* test, line 185 */ - if (!(z->I[0] > 2)) goto lab4; /* $( > ), line 185 */ - z->lb = z->c; z->c = z->l; /* backwards, line 185 */ + { int c7 = z->c; + { int c_test8 = z->c; + if (!(z->I[1] > 2)) goto lab4; + z->lb = z->c; z->c = z->l; - { int ret = r_remove_suffix(z); /* call remove_suffix, line 185 */ + { int ret = r_remove_suffix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } z->c = z->lb; z->c = c_test8; } - if (!(z->I[0] > 2)) goto lab4; /* $( > ), line 186 */ - { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 186 */ + if (!(z->I[1] > 2)) goto lab4; + { int ret = r_remove_second_order_prefix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } @@ -379,17 +378,17 @@ extern int indonesian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ goto lab2; lab3: z->c = c5; - { int c9 = z->c; /* do, line 189 */ - { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 189 */ + { int c9 = z->c; + { int ret = r_remove_second_order_prefix(z); if (ret < 0) return ret; } z->c = c9; } - { int c10 = z->c; /* do, line 190 */ - if (!(z->I[0] > 2)) goto lab5; /* $( > ), line 190 */ - z->lb = z->c; z->c = z->l; /* backwards, line 190 */ + { int c10 = z->c; + if (!(z->I[1] > 2)) goto lab5; + z->lb = z->c; z->c = z->l; - { int ret = r_remove_suffix(z); /* call remove_suffix, line 190 */ + { int ret = r_remove_suffix(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } @@ -402,7 +401,7 @@ extern int indonesian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * indonesian_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * indonesian_ISO_8859_1_create_env(void) { return SN_create_env(0, 2); } extern void indonesian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_irish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_irish.c index 87df430aea64..fbe75f89a0c1 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_irish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_irish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -56,30 +56,30 @@ static const symbol s_0_23[2] = { 't', 's' }; static const struct among a_0[24] = { -/* 0 */ { 2, s_0_0, -1, 1, 0}, -/* 1 */ { 2, s_0_1, -1, 4, 0}, -/* 2 */ { 3, s_0_2, 1, 2, 0}, -/* 3 */ { 2, s_0_3, -1, 8, 0}, -/* 4 */ { 2, s_0_4, -1, 5, 0}, -/* 5 */ { 2, s_0_5, -1, 1, 0}, -/* 6 */ { 4, s_0_6, 5, 2, 0}, -/* 7 */ { 2, s_0_7, -1, 6, 0}, -/* 8 */ { 2, s_0_8, -1, 9, 0}, -/* 9 */ { 2, s_0_9, -1, 2, 0}, -/* 10 */ { 2, s_0_10, -1, 5, 0}, -/* 11 */ { 2, s_0_11, -1, 7, 0}, -/* 12 */ { 2, s_0_12, -1, 1, 0}, -/* 13 */ { 2, s_0_13, -1, 1, 0}, -/* 14 */ { 2, s_0_14, -1, 4, 0}, -/* 15 */ { 2, s_0_15, -1, 10, 0}, -/* 16 */ { 2, s_0_16, -1, 1, 0}, -/* 17 */ { 2, s_0_17, -1, 6, 0}, -/* 18 */ { 2, s_0_18, -1, 7, 0}, -/* 19 */ { 2, s_0_19, -1, 8, 0}, -/* 20 */ { 2, s_0_20, -1, 3, 0}, -/* 21 */ { 2, s_0_21, -1, 1, 0}, -/* 22 */ { 2, s_0_22, -1, 9, 0}, -/* 23 */ { 2, s_0_23, -1, 3, 0} +{ 2, s_0_0, -1, 1, 0}, +{ 2, s_0_1, -1, 4, 0}, +{ 3, s_0_2, 1, 2, 0}, +{ 2, s_0_3, -1, 8, 0}, +{ 2, s_0_4, -1, 5, 0}, +{ 2, s_0_5, -1, 1, 0}, +{ 4, s_0_6, 5, 2, 0}, +{ 2, s_0_7, -1, 6, 0}, +{ 2, s_0_8, -1, 9, 0}, +{ 2, s_0_9, -1, 2, 0}, +{ 2, s_0_10, -1, 5, 0}, +{ 2, s_0_11, -1, 7, 0}, +{ 2, s_0_12, -1, 1, 0}, +{ 2, s_0_13, -1, 1, 0}, +{ 2, s_0_14, -1, 4, 0}, +{ 2, s_0_15, -1, 10, 0}, +{ 2, s_0_16, -1, 1, 0}, +{ 2, s_0_17, -1, 6, 0}, +{ 2, s_0_18, -1, 7, 0}, +{ 2, s_0_19, -1, 8, 0}, +{ 2, s_0_20, -1, 3, 0}, +{ 2, s_0_21, -1, 1, 0}, +{ 2, s_0_22, -1, 9, 0}, +{ 2, s_0_23, -1, 3, 0} }; static const symbol s_1_0[6] = { 0xED, 'o', 'c', 'h', 't', 'a' }; @@ -101,22 +101,22 @@ static const symbol s_1_15[4] = { 'a', 'i', 'r', 0xED }; static const struct among a_1[16] = { -/* 0 */ { 6, s_1_0, -1, 1, 0}, -/* 1 */ { 7, s_1_1, 0, 1, 0}, -/* 2 */ { 3, s_1_2, -1, 2, 0}, -/* 3 */ { 4, s_1_3, 2, 2, 0}, -/* 4 */ { 3, s_1_4, -1, 1, 0}, -/* 5 */ { 4, s_1_5, 4, 1, 0}, -/* 6 */ { 3, s_1_6, -1, 1, 0}, -/* 7 */ { 4, s_1_7, 6, 1, 0}, -/* 8 */ { 3, s_1_8, -1, 1, 0}, -/* 9 */ { 4, s_1_9, 8, 1, 0}, -/* 10 */ { 3, s_1_10, -1, 1, 0}, -/* 11 */ { 4, s_1_11, 10, 1, 0}, -/* 12 */ { 5, s_1_12, -1, 1, 0}, -/* 13 */ { 6, s_1_13, 12, 1, 0}, -/* 14 */ { 3, s_1_14, -1, 2, 0}, -/* 15 */ { 4, s_1_15, 14, 2, 0} +{ 6, s_1_0, -1, 1, 0}, +{ 7, s_1_1, 0, 1, 0}, +{ 3, s_1_2, -1, 2, 0}, +{ 4, s_1_3, 2, 2, 0}, +{ 3, s_1_4, -1, 1, 0}, +{ 4, s_1_5, 4, 1, 0}, +{ 3, s_1_6, -1, 1, 0}, +{ 4, s_1_7, 6, 1, 0}, +{ 3, s_1_8, -1, 1, 0}, +{ 4, s_1_9, 8, 1, 0}, +{ 3, s_1_10, -1, 1, 0}, +{ 4, s_1_11, 10, 1, 0}, +{ 5, s_1_12, -1, 1, 0}, +{ 6, s_1_13, 12, 1, 0}, +{ 3, s_1_14, -1, 2, 0}, +{ 4, s_1_15, 14, 2, 0} }; static const symbol s_2_0[8] = { 0xF3, 'i', 'd', 'e', 'a', 'c', 'h', 'a' }; @@ -147,31 +147,31 @@ static const symbol s_2_24[12] = { 'g', 'r', 'a', 'f', 'a', 0xED, 'o', 'c', 'h', static const struct among a_2[25] = { -/* 0 */ { 8, s_2_0, -1, 6, 0}, -/* 1 */ { 7, s_2_1, -1, 5, 0}, -/* 2 */ { 5, s_2_2, -1, 1, 0}, -/* 3 */ { 8, s_2_3, 2, 2, 0}, -/* 4 */ { 6, s_2_4, 2, 1, 0}, -/* 5 */ { 11, s_2_5, -1, 4, 0}, -/* 6 */ { 5, s_2_6, -1, 5, 0}, -/* 7 */ { 3, s_2_7, -1, 1, 0}, -/* 8 */ { 4, s_2_8, 7, 1, 0}, -/* 9 */ { 7, s_2_9, 8, 6, 0}, -/* 10 */ { 7, s_2_10, 8, 3, 0}, -/* 11 */ { 6, s_2_11, 7, 5, 0}, -/* 12 */ { 9, s_2_12, -1, 4, 0}, -/* 13 */ { 7, s_2_13, -1, 5, 0}, -/* 14 */ { 6, s_2_14, -1, 6, 0}, -/* 15 */ { 7, s_2_15, -1, 1, 0}, -/* 16 */ { 8, s_2_16, 15, 1, 0}, -/* 17 */ { 6, s_2_17, -1, 3, 0}, -/* 18 */ { 5, s_2_18, -1, 3, 0}, -/* 19 */ { 4, s_2_19, -1, 1, 0}, -/* 20 */ { 7, s_2_20, 19, 2, 0}, -/* 21 */ { 5, s_2_21, 19, 1, 0}, -/* 22 */ { 10, s_2_22, -1, 4, 0}, -/* 23 */ { 9, s_2_23, -1, 2, 0}, -/* 24 */ { 12, s_2_24, -1, 4, 0} +{ 8, s_2_0, -1, 6, 0}, +{ 7, s_2_1, -1, 5, 0}, +{ 5, s_2_2, -1, 1, 0}, +{ 8, s_2_3, 2, 2, 0}, +{ 6, s_2_4, 2, 1, 0}, +{ 11, s_2_5, -1, 4, 0}, +{ 5, s_2_6, -1, 5, 0}, +{ 3, s_2_7, -1, 1, 0}, +{ 4, s_2_8, 7, 1, 0}, +{ 7, s_2_9, 8, 6, 0}, +{ 7, s_2_10, 8, 3, 0}, +{ 6, s_2_11, 7, 5, 0}, +{ 9, s_2_12, -1, 4, 0}, +{ 7, s_2_13, -1, 5, 0}, +{ 6, s_2_14, -1, 6, 0}, +{ 7, s_2_15, -1, 1, 0}, +{ 8, s_2_16, 15, 1, 0}, +{ 6, s_2_17, -1, 3, 0}, +{ 5, s_2_18, -1, 3, 0}, +{ 4, s_2_19, -1, 1, 0}, +{ 7, s_2_20, 19, 2, 0}, +{ 5, s_2_21, 19, 1, 0}, +{ 10, s_2_22, -1, 4, 0}, +{ 9, s_2_23, -1, 2, 0}, +{ 12, s_2_24, -1, 4, 0} }; static const symbol s_3_0[4] = { 'i', 'm', 'i', 'd' }; @@ -189,18 +189,18 @@ static const symbol s_3_11[3] = { 't', 'a', 'r' }; static const struct among a_3[12] = { -/* 0 */ { 4, s_3_0, -1, 1, 0}, -/* 1 */ { 5, s_3_1, 0, 1, 0}, -/* 2 */ { 4, s_3_2, -1, 1, 0}, -/* 3 */ { 5, s_3_3, 2, 1, 0}, -/* 4 */ { 3, s_3_4, -1, 2, 0}, -/* 5 */ { 4, s_3_5, 4, 2, 0}, -/* 6 */ { 5, s_3_6, -1, 1, 0}, -/* 7 */ { 4, s_3_7, -1, 1, 0}, -/* 8 */ { 3, s_3_8, -1, 2, 0}, -/* 9 */ { 3, s_3_9, -1, 2, 0}, -/* 10 */ { 4, s_3_10, -1, 2, 0}, -/* 11 */ { 3, s_3_11, -1, 2, 0} +{ 4, s_3_0, -1, 1, 0}, +{ 5, s_3_1, 0, 1, 0}, +{ 4, s_3_2, -1, 1, 0}, +{ 5, s_3_3, 2, 1, 0}, +{ 3, s_3_4, -1, 2, 0}, +{ 4, s_3_5, 4, 2, 0}, +{ 5, s_3_6, -1, 1, 0}, +{ 4, s_3_7, -1, 1, 0}, +{ 3, s_3_8, -1, 2, 0}, +{ 3, s_3_9, -1, 2, 0}, +{ 4, s_3_10, -1, 2, 0}, +{ 3, s_3_11, -1, 2, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 2 }; @@ -220,103 +220,103 @@ static const symbol s_11[] = { 'g', 'r', 'a', 'f' }; static const symbol s_12[] = { 'p', 'a', 'i', 't', 'e' }; static const symbol s_13[] = { 0xF3, 'i', 'd' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 30 */ - z->I[1] = z->l; /* $p1 = , line 31 */ - z->I[2] = z->l; /* $p2 = , line 32 */ - { int c1 = z->c; /* do, line 34 */ - { /* gopast */ /* grouping v, line 35 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark pV, line 35 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c2 = z->c; /* do, line 37 */ - { /* gopast */ /* grouping v, line 38 */ + { int c2 = z->c; + { int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - { /* gopast */ /* non v, line 38 */ + { int ret = in_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 38 */ - { /* gopast */ /* grouping v, line 39 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - { /* gopast */ /* non v, line 39 */ + { int ret = in_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 39 */ + z->I[0] = z->c; lab1: z->c = c2; } return 1; } -static int r_initial_morph(struct SN_env * z) { /* forwardmode */ +static int r_initial_morph(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 44 */ - among_var = find_among(z, a_0, 24); /* substring, line 44 */ + z->bra = z->c; + among_var = find_among(z, a_0, 24); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 44 */ - switch (among_var) { /* among, line 44 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 46 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 52 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 58 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 61 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 63 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 65 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 69 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 71 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 75 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 89 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; @@ -324,41 +324,41 @@ static int r_initial_morph(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 99 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 100 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 101 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_noun_sfx(struct SN_env * z) { /* backwardmode */ +static int r_noun_sfx(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 104 */ - among_var = find_among_b(z, a_1, 16); /* substring, line 104 */ + z->ket = z->c; + among_var = find_among_b(z, a_1, 16); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 104 */ - switch (among_var) { /* among, line 104 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 108 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 108 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 110 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -366,43 +366,43 @@ static int r_noun_sfx(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_deriv(struct SN_env * z) { /* backwardmode */ +static int r_deriv(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 114 */ - among_var = find_among_b(z, a_2, 25); /* substring, line 114 */ + z->ket = z->c; + among_var = find_among_b(z, a_2, 25); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 114 */ - switch (among_var) { /* among, line 114 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 116 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 116 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_9); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_9); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_10); /* <-, line 120 */ + { int ret = slice_from_s(z, 3, s_10); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 122 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 5, s_12); /* <-, line 124 */ + { int ret = slice_from_s(z, 5, s_12); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_13); /* <-, line 126 */ + { int ret = slice_from_s(z, 3, s_13); if (ret < 0) return ret; } break; @@ -410,27 +410,27 @@ static int r_deriv(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_sfx(struct SN_env * z) { /* backwardmode */ +static int r_verb_sfx(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 130 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((282896 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 130 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((282896 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_3, 12); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 130 */ - switch (among_var) { /* among, line 130 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 133 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 133 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R1(z); /* call R1, line 138 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 138 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -438,33 +438,33 @@ static int r_verb_sfx(struct SN_env * z) { /* backwardmode */ return 1; } -extern int irish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 144 */ - { int ret = r_initial_morph(z); /* call initial_morph, line 144 */ +extern int irish_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_initial_morph(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 145 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 145 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 146 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 147 */ - { int ret = r_noun_sfx(z); /* call noun_sfx, line 147 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_noun_sfx(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 148 */ - { int ret = r_deriv(z); /* call deriv, line 148 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_deriv(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 149 */ - { int ret = r_verb_sfx(z); /* call verb_sfx, line 149 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_verb_sfx(z); if (ret < 0) return ret; } z->c = z->l - m4; @@ -473,7 +473,7 @@ extern int irish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * irish_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * irish_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void irish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c index a06e8902d93d..e71178e404db 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -40,13 +40,13 @@ static const symbol s_0_6[1] = { 0xFA }; static const struct among a_0[7] = { -/* 0 */ { 0, 0, -1, 7, 0}, -/* 1 */ { 2, s_0_1, 0, 6, 0}, -/* 2 */ { 1, s_0_2, 0, 1, 0}, -/* 3 */ { 1, s_0_3, 0, 2, 0}, -/* 4 */ { 1, s_0_4, 0, 3, 0}, -/* 5 */ { 1, s_0_5, 0, 4, 0}, -/* 6 */ { 1, s_0_6, 0, 5, 0} +{ 0, 0, -1, 7, 0}, +{ 2, s_0_1, 0, 6, 0}, +{ 1, s_0_2, 0, 1, 0}, +{ 1, s_0_3, 0, 2, 0}, +{ 1, s_0_4, 0, 3, 0}, +{ 1, s_0_5, 0, 4, 0}, +{ 1, s_0_6, 0, 5, 0} }; static const symbol s_1_1[1] = { 'I' }; @@ -54,9 +54,9 @@ static const symbol s_1_2[1] = { 'U' }; static const struct among a_1[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 1, s_1_1, 0, 1, 0}, -/* 2 */ { 1, s_1_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 1, s_1_1, 0, 1, 0}, +{ 1, s_1_2, 0, 2, 0} }; static const symbol s_2_0[2] = { 'l', 'a' }; @@ -99,43 +99,43 @@ static const symbol s_2_36[4] = { 'v', 'e', 'l', 'o' }; static const struct among a_2[37] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 4, s_2_1, 0, -1, 0}, -/* 2 */ { 6, s_2_2, 0, -1, 0}, -/* 3 */ { 4, s_2_3, 0, -1, 0}, -/* 4 */ { 4, s_2_4, 0, -1, 0}, -/* 5 */ { 4, s_2_5, 0, -1, 0}, -/* 6 */ { 2, s_2_6, -1, -1, 0}, -/* 7 */ { 4, s_2_7, 6, -1, 0}, -/* 8 */ { 6, s_2_8, 6, -1, 0}, -/* 9 */ { 4, s_2_9, 6, -1, 0}, -/* 10 */ { 4, s_2_10, 6, -1, 0}, -/* 11 */ { 4, s_2_11, 6, -1, 0}, -/* 12 */ { 2, s_2_12, -1, -1, 0}, -/* 13 */ { 4, s_2_13, 12, -1, 0}, -/* 14 */ { 6, s_2_14, 12, -1, 0}, -/* 15 */ { 4, s_2_15, 12, -1, 0}, -/* 16 */ { 4, s_2_16, 12, -1, 0}, -/* 17 */ { 4, s_2_17, 12, -1, 0}, -/* 18 */ { 4, s_2_18, 12, -1, 0}, -/* 19 */ { 2, s_2_19, -1, -1, 0}, -/* 20 */ { 2, s_2_20, -1, -1, 0}, -/* 21 */ { 4, s_2_21, 20, -1, 0}, -/* 22 */ { 6, s_2_22, 20, -1, 0}, -/* 23 */ { 4, s_2_23, 20, -1, 0}, -/* 24 */ { 4, s_2_24, 20, -1, 0}, -/* 25 */ { 4, s_2_25, 20, -1, 0}, -/* 26 */ { 3, s_2_26, 20, -1, 0}, -/* 27 */ { 2, s_2_27, -1, -1, 0}, -/* 28 */ { 2, s_2_28, -1, -1, 0}, -/* 29 */ { 2, s_2_29, -1, -1, 0}, -/* 30 */ { 2, s_2_30, -1, -1, 0}, -/* 31 */ { 2, s_2_31, -1, -1, 0}, -/* 32 */ { 4, s_2_32, 31, -1, 0}, -/* 33 */ { 6, s_2_33, 31, -1, 0}, -/* 34 */ { 4, s_2_34, 31, -1, 0}, -/* 35 */ { 4, s_2_35, 31, -1, 0}, -/* 36 */ { 4, s_2_36, 31, -1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 4, s_2_1, 0, -1, 0}, +{ 6, s_2_2, 0, -1, 0}, +{ 4, s_2_3, 0, -1, 0}, +{ 4, s_2_4, 0, -1, 0}, +{ 4, s_2_5, 0, -1, 0}, +{ 2, s_2_6, -1, -1, 0}, +{ 4, s_2_7, 6, -1, 0}, +{ 6, s_2_8, 6, -1, 0}, +{ 4, s_2_9, 6, -1, 0}, +{ 4, s_2_10, 6, -1, 0}, +{ 4, s_2_11, 6, -1, 0}, +{ 2, s_2_12, -1, -1, 0}, +{ 4, s_2_13, 12, -1, 0}, +{ 6, s_2_14, 12, -1, 0}, +{ 4, s_2_15, 12, -1, 0}, +{ 4, s_2_16, 12, -1, 0}, +{ 4, s_2_17, 12, -1, 0}, +{ 4, s_2_18, 12, -1, 0}, +{ 2, s_2_19, -1, -1, 0}, +{ 2, s_2_20, -1, -1, 0}, +{ 4, s_2_21, 20, -1, 0}, +{ 6, s_2_22, 20, -1, 0}, +{ 4, s_2_23, 20, -1, 0}, +{ 4, s_2_24, 20, -1, 0}, +{ 4, s_2_25, 20, -1, 0}, +{ 3, s_2_26, 20, -1, 0}, +{ 2, s_2_27, -1, -1, 0}, +{ 2, s_2_28, -1, -1, 0}, +{ 2, s_2_29, -1, -1, 0}, +{ 2, s_2_30, -1, -1, 0}, +{ 2, s_2_31, -1, -1, 0}, +{ 4, s_2_32, 31, -1, 0}, +{ 6, s_2_33, 31, -1, 0}, +{ 4, s_2_34, 31, -1, 0}, +{ 4, s_2_35, 31, -1, 0}, +{ 4, s_2_36, 31, -1, 0} }; static const symbol s_3_0[4] = { 'a', 'n', 'd', 'o' }; @@ -146,11 +146,11 @@ static const symbol s_3_4[2] = { 'i', 'r' }; static const struct among a_3[5] = { -/* 0 */ { 4, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 2, s_3_2, -1, 2, 0}, -/* 3 */ { 2, s_3_3, -1, 2, 0}, -/* 4 */ { 2, s_3_4, -1, 2, 0} +{ 4, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 2, s_3_2, -1, 2, 0}, +{ 2, s_3_3, -1, 2, 0}, +{ 2, s_3_4, -1, 2, 0} }; static const symbol s_4_0[2] = { 'i', 'c' }; @@ -160,10 +160,10 @@ static const symbol s_4_3[2] = { 'i', 'v' }; static const struct among a_4[4] = { -/* 0 */ { 2, s_4_0, -1, -1, 0}, -/* 1 */ { 4, s_4_1, -1, -1, 0}, -/* 2 */ { 2, s_4_2, -1, -1, 0}, -/* 3 */ { 2, s_4_3, -1, 1, 0} +{ 2, s_4_0, -1, -1, 0}, +{ 4, s_4_1, -1, -1, 0}, +{ 2, s_4_2, -1, -1, 0}, +{ 2, s_4_3, -1, 1, 0} }; static const symbol s_5_0[2] = { 'i', 'c' }; @@ -172,9 +172,9 @@ static const symbol s_5_2[2] = { 'i', 'v' }; static const struct among a_5[3] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 4, s_5_1, -1, 1, 0}, -/* 2 */ { 2, s_5_2, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 4, s_5_1, -1, 1, 0}, +{ 2, s_5_2, -1, 1, 0} }; static const symbol s_6_0[3] = { 'i', 'c', 'a' }; @@ -231,57 +231,57 @@ static const symbol s_6_50[4] = { 'i', 's', 't', 0xEC }; static const struct among a_6[51] = { -/* 0 */ { 3, s_6_0, -1, 1, 0}, -/* 1 */ { 5, s_6_1, -1, 3, 0}, -/* 2 */ { 3, s_6_2, -1, 1, 0}, -/* 3 */ { 4, s_6_3, -1, 1, 0}, -/* 4 */ { 3, s_6_4, -1, 9, 0}, -/* 5 */ { 4, s_6_5, -1, 1, 0}, -/* 6 */ { 4, s_6_6, -1, 5, 0}, -/* 7 */ { 3, s_6_7, -1, 1, 0}, -/* 8 */ { 6, s_6_8, 7, 1, 0}, -/* 9 */ { 4, s_6_9, -1, 1, 0}, -/* 10 */ { 5, s_6_10, -1, 3, 0}, -/* 11 */ { 5, s_6_11, -1, 1, 0}, -/* 12 */ { 5, s_6_12, -1, 1, 0}, -/* 13 */ { 6, s_6_13, -1, 4, 0}, -/* 14 */ { 6, s_6_14, -1, 2, 0}, -/* 15 */ { 6, s_6_15, -1, 4, 0}, -/* 16 */ { 5, s_6_16, -1, 2, 0}, -/* 17 */ { 3, s_6_17, -1, 1, 0}, -/* 18 */ { 4, s_6_18, -1, 1, 0}, -/* 19 */ { 5, s_6_19, -1, 1, 0}, -/* 20 */ { 6, s_6_20, 19, 7, 0}, -/* 21 */ { 4, s_6_21, -1, 1, 0}, -/* 22 */ { 3, s_6_22, -1, 9, 0}, -/* 23 */ { 4, s_6_23, -1, 1, 0}, -/* 24 */ { 4, s_6_24, -1, 5, 0}, -/* 25 */ { 3, s_6_25, -1, 1, 0}, -/* 26 */ { 6, s_6_26, 25, 1, 0}, -/* 27 */ { 4, s_6_27, -1, 1, 0}, -/* 28 */ { 5, s_6_28, -1, 1, 0}, -/* 29 */ { 5, s_6_29, -1, 1, 0}, -/* 30 */ { 4, s_6_30, -1, 1, 0}, -/* 31 */ { 6, s_6_31, -1, 4, 0}, -/* 32 */ { 6, s_6_32, -1, 2, 0}, -/* 33 */ { 6, s_6_33, -1, 4, 0}, -/* 34 */ { 5, s_6_34, -1, 2, 0}, -/* 35 */ { 3, s_6_35, -1, 1, 0}, -/* 36 */ { 4, s_6_36, -1, 1, 0}, -/* 37 */ { 6, s_6_37, -1, 6, 0}, -/* 38 */ { 6, s_6_38, -1, 6, 0}, -/* 39 */ { 4, s_6_39, -1, 1, 0}, -/* 40 */ { 3, s_6_40, -1, 9, 0}, -/* 41 */ { 3, s_6_41, -1, 1, 0}, -/* 42 */ { 4, s_6_42, -1, 1, 0}, -/* 43 */ { 3, s_6_43, -1, 1, 0}, -/* 44 */ { 6, s_6_44, -1, 6, 0}, -/* 45 */ { 6, s_6_45, -1, 6, 0}, -/* 46 */ { 3, s_6_46, -1, 9, 0}, -/* 47 */ { 3, s_6_47, -1, 8, 0}, -/* 48 */ { 4, s_6_48, -1, 1, 0}, -/* 49 */ { 4, s_6_49, -1, 1, 0}, -/* 50 */ { 4, s_6_50, -1, 1, 0} +{ 3, s_6_0, -1, 1, 0}, +{ 5, s_6_1, -1, 3, 0}, +{ 3, s_6_2, -1, 1, 0}, +{ 4, s_6_3, -1, 1, 0}, +{ 3, s_6_4, -1, 9, 0}, +{ 4, s_6_5, -1, 1, 0}, +{ 4, s_6_6, -1, 5, 0}, +{ 3, s_6_7, -1, 1, 0}, +{ 6, s_6_8, 7, 1, 0}, +{ 4, s_6_9, -1, 1, 0}, +{ 5, s_6_10, -1, 3, 0}, +{ 5, s_6_11, -1, 1, 0}, +{ 5, s_6_12, -1, 1, 0}, +{ 6, s_6_13, -1, 4, 0}, +{ 6, s_6_14, -1, 2, 0}, +{ 6, s_6_15, -1, 4, 0}, +{ 5, s_6_16, -1, 2, 0}, +{ 3, s_6_17, -1, 1, 0}, +{ 4, s_6_18, -1, 1, 0}, +{ 5, s_6_19, -1, 1, 0}, +{ 6, s_6_20, 19, 7, 0}, +{ 4, s_6_21, -1, 1, 0}, +{ 3, s_6_22, -1, 9, 0}, +{ 4, s_6_23, -1, 1, 0}, +{ 4, s_6_24, -1, 5, 0}, +{ 3, s_6_25, -1, 1, 0}, +{ 6, s_6_26, 25, 1, 0}, +{ 4, s_6_27, -1, 1, 0}, +{ 5, s_6_28, -1, 1, 0}, +{ 5, s_6_29, -1, 1, 0}, +{ 4, s_6_30, -1, 1, 0}, +{ 6, s_6_31, -1, 4, 0}, +{ 6, s_6_32, -1, 2, 0}, +{ 6, s_6_33, -1, 4, 0}, +{ 5, s_6_34, -1, 2, 0}, +{ 3, s_6_35, -1, 1, 0}, +{ 4, s_6_36, -1, 1, 0}, +{ 6, s_6_37, -1, 6, 0}, +{ 6, s_6_38, -1, 6, 0}, +{ 4, s_6_39, -1, 1, 0}, +{ 3, s_6_40, -1, 9, 0}, +{ 3, s_6_41, -1, 1, 0}, +{ 4, s_6_42, -1, 1, 0}, +{ 3, s_6_43, -1, 1, 0}, +{ 6, s_6_44, -1, 6, 0}, +{ 6, s_6_45, -1, 6, 0}, +{ 3, s_6_46, -1, 9, 0}, +{ 3, s_6_47, -1, 8, 0}, +{ 4, s_6_48, -1, 1, 0}, +{ 4, s_6_49, -1, 1, 0}, +{ 4, s_6_50, -1, 1, 0} }; static const symbol s_7_0[4] = { 'i', 's', 'c', 'a' }; @@ -374,93 +374,93 @@ static const symbol s_7_86[3] = { 'i', 'r', 0xF2 }; static const struct among a_7[87] = { -/* 0 */ { 4, s_7_0, -1, 1, 0}, -/* 1 */ { 4, s_7_1, -1, 1, 0}, -/* 2 */ { 3, s_7_2, -1, 1, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 3, s_7_4, -1, 1, 0}, -/* 5 */ { 3, s_7_5, -1, 1, 0}, -/* 6 */ { 3, s_7_6, -1, 1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 6, s_7_8, -1, 1, 0}, -/* 9 */ { 6, s_7_9, -1, 1, 0}, -/* 10 */ { 4, s_7_10, -1, 1, 0}, -/* 11 */ { 4, s_7_11, -1, 1, 0}, -/* 12 */ { 3, s_7_12, -1, 1, 0}, -/* 13 */ { 3, s_7_13, -1, 1, 0}, -/* 14 */ { 3, s_7_14, -1, 1, 0}, -/* 15 */ { 4, s_7_15, -1, 1, 0}, -/* 16 */ { 3, s_7_16, -1, 1, 0}, -/* 17 */ { 5, s_7_17, 16, 1, 0}, -/* 18 */ { 5, s_7_18, 16, 1, 0}, -/* 19 */ { 5, s_7_19, 16, 1, 0}, -/* 20 */ { 3, s_7_20, -1, 1, 0}, -/* 21 */ { 5, s_7_21, 20, 1, 0}, -/* 22 */ { 5, s_7_22, 20, 1, 0}, -/* 23 */ { 3, s_7_23, -1, 1, 0}, -/* 24 */ { 6, s_7_24, -1, 1, 0}, -/* 25 */ { 6, s_7_25, -1, 1, 0}, -/* 26 */ { 3, s_7_26, -1, 1, 0}, -/* 27 */ { 4, s_7_27, -1, 1, 0}, -/* 28 */ { 4, s_7_28, -1, 1, 0}, -/* 29 */ { 4, s_7_29, -1, 1, 0}, -/* 30 */ { 4, s_7_30, -1, 1, 0}, -/* 31 */ { 4, s_7_31, -1, 1, 0}, -/* 32 */ { 4, s_7_32, -1, 1, 0}, -/* 33 */ { 4, s_7_33, -1, 1, 0}, -/* 34 */ { 3, s_7_34, -1, 1, 0}, -/* 35 */ { 3, s_7_35, -1, 1, 0}, -/* 36 */ { 6, s_7_36, -1, 1, 0}, -/* 37 */ { 6, s_7_37, -1, 1, 0}, -/* 38 */ { 3, s_7_38, -1, 1, 0}, -/* 39 */ { 3, s_7_39, -1, 1, 0}, -/* 40 */ { 3, s_7_40, -1, 1, 0}, -/* 41 */ { 3, s_7_41, -1, 1, 0}, -/* 42 */ { 4, s_7_42, -1, 1, 0}, -/* 43 */ { 4, s_7_43, -1, 1, 0}, -/* 44 */ { 4, s_7_44, -1, 1, 0}, -/* 45 */ { 4, s_7_45, -1, 1, 0}, -/* 46 */ { 4, s_7_46, -1, 1, 0}, -/* 47 */ { 5, s_7_47, -1, 1, 0}, -/* 48 */ { 5, s_7_48, -1, 1, 0}, -/* 49 */ { 5, s_7_49, -1, 1, 0}, -/* 50 */ { 5, s_7_50, -1, 1, 0}, -/* 51 */ { 5, s_7_51, -1, 1, 0}, -/* 52 */ { 6, s_7_52, -1, 1, 0}, -/* 53 */ { 4, s_7_53, -1, 1, 0}, -/* 54 */ { 4, s_7_54, -1, 1, 0}, -/* 55 */ { 6, s_7_55, 54, 1, 0}, -/* 56 */ { 6, s_7_56, 54, 1, 0}, -/* 57 */ { 4, s_7_57, -1, 1, 0}, -/* 58 */ { 3, s_7_58, -1, 1, 0}, -/* 59 */ { 6, s_7_59, 58, 1, 0}, -/* 60 */ { 5, s_7_60, 58, 1, 0}, -/* 61 */ { 5, s_7_61, 58, 1, 0}, -/* 62 */ { 5, s_7_62, 58, 1, 0}, -/* 63 */ { 6, s_7_63, -1, 1, 0}, -/* 64 */ { 6, s_7_64, -1, 1, 0}, -/* 65 */ { 3, s_7_65, -1, 1, 0}, -/* 66 */ { 6, s_7_66, 65, 1, 0}, -/* 67 */ { 5, s_7_67, 65, 1, 0}, -/* 68 */ { 5, s_7_68, 65, 1, 0}, -/* 69 */ { 5, s_7_69, 65, 1, 0}, -/* 70 */ { 8, s_7_70, -1, 1, 0}, -/* 71 */ { 8, s_7_71, -1, 1, 0}, -/* 72 */ { 6, s_7_72, -1, 1, 0}, -/* 73 */ { 6, s_7_73, -1, 1, 0}, -/* 74 */ { 6, s_7_74, -1, 1, 0}, -/* 75 */ { 3, s_7_75, -1, 1, 0}, -/* 76 */ { 3, s_7_76, -1, 1, 0}, -/* 77 */ { 3, s_7_77, -1, 1, 0}, -/* 78 */ { 3, s_7_78, -1, 1, 0}, -/* 79 */ { 3, s_7_79, -1, 1, 0}, -/* 80 */ { 3, s_7_80, -1, 1, 0}, -/* 81 */ { 2, s_7_81, -1, 1, 0}, -/* 82 */ { 2, s_7_82, -1, 1, 0}, -/* 83 */ { 3, s_7_83, -1, 1, 0}, -/* 84 */ { 3, s_7_84, -1, 1, 0}, -/* 85 */ { 3, s_7_85, -1, 1, 0}, -/* 86 */ { 3, s_7_86, -1, 1, 0} +{ 4, s_7_0, -1, 1, 0}, +{ 4, s_7_1, -1, 1, 0}, +{ 3, s_7_2, -1, 1, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 3, s_7_4, -1, 1, 0}, +{ 3, s_7_5, -1, 1, 0}, +{ 3, s_7_6, -1, 1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 6, s_7_8, -1, 1, 0}, +{ 6, s_7_9, -1, 1, 0}, +{ 4, s_7_10, -1, 1, 0}, +{ 4, s_7_11, -1, 1, 0}, +{ 3, s_7_12, -1, 1, 0}, +{ 3, s_7_13, -1, 1, 0}, +{ 3, s_7_14, -1, 1, 0}, +{ 4, s_7_15, -1, 1, 0}, +{ 3, s_7_16, -1, 1, 0}, +{ 5, s_7_17, 16, 1, 0}, +{ 5, s_7_18, 16, 1, 0}, +{ 5, s_7_19, 16, 1, 0}, +{ 3, s_7_20, -1, 1, 0}, +{ 5, s_7_21, 20, 1, 0}, +{ 5, s_7_22, 20, 1, 0}, +{ 3, s_7_23, -1, 1, 0}, +{ 6, s_7_24, -1, 1, 0}, +{ 6, s_7_25, -1, 1, 0}, +{ 3, s_7_26, -1, 1, 0}, +{ 4, s_7_27, -1, 1, 0}, +{ 4, s_7_28, -1, 1, 0}, +{ 4, s_7_29, -1, 1, 0}, +{ 4, s_7_30, -1, 1, 0}, +{ 4, s_7_31, -1, 1, 0}, +{ 4, s_7_32, -1, 1, 0}, +{ 4, s_7_33, -1, 1, 0}, +{ 3, s_7_34, -1, 1, 0}, +{ 3, s_7_35, -1, 1, 0}, +{ 6, s_7_36, -1, 1, 0}, +{ 6, s_7_37, -1, 1, 0}, +{ 3, s_7_38, -1, 1, 0}, +{ 3, s_7_39, -1, 1, 0}, +{ 3, s_7_40, -1, 1, 0}, +{ 3, s_7_41, -1, 1, 0}, +{ 4, s_7_42, -1, 1, 0}, +{ 4, s_7_43, -1, 1, 0}, +{ 4, s_7_44, -1, 1, 0}, +{ 4, s_7_45, -1, 1, 0}, +{ 4, s_7_46, -1, 1, 0}, +{ 5, s_7_47, -1, 1, 0}, +{ 5, s_7_48, -1, 1, 0}, +{ 5, s_7_49, -1, 1, 0}, +{ 5, s_7_50, -1, 1, 0}, +{ 5, s_7_51, -1, 1, 0}, +{ 6, s_7_52, -1, 1, 0}, +{ 4, s_7_53, -1, 1, 0}, +{ 4, s_7_54, -1, 1, 0}, +{ 6, s_7_55, 54, 1, 0}, +{ 6, s_7_56, 54, 1, 0}, +{ 4, s_7_57, -1, 1, 0}, +{ 3, s_7_58, -1, 1, 0}, +{ 6, s_7_59, 58, 1, 0}, +{ 5, s_7_60, 58, 1, 0}, +{ 5, s_7_61, 58, 1, 0}, +{ 5, s_7_62, 58, 1, 0}, +{ 6, s_7_63, -1, 1, 0}, +{ 6, s_7_64, -1, 1, 0}, +{ 3, s_7_65, -1, 1, 0}, +{ 6, s_7_66, 65, 1, 0}, +{ 5, s_7_67, 65, 1, 0}, +{ 5, s_7_68, 65, 1, 0}, +{ 5, s_7_69, 65, 1, 0}, +{ 8, s_7_70, -1, 1, 0}, +{ 8, s_7_71, -1, 1, 0}, +{ 6, s_7_72, -1, 1, 0}, +{ 6, s_7_73, -1, 1, 0}, +{ 6, s_7_74, -1, 1, 0}, +{ 3, s_7_75, -1, 1, 0}, +{ 3, s_7_76, -1, 1, 0}, +{ 3, s_7_77, -1, 1, 0}, +{ 3, s_7_78, -1, 1, 0}, +{ 3, s_7_79, -1, 1, 0}, +{ 3, s_7_80, -1, 1, 0}, +{ 2, s_7_81, -1, 1, 0}, +{ 2, s_7_82, -1, 1, 0}, +{ 3, s_7_83, -1, 1, 0}, +{ 3, s_7_84, -1, 1, 0}, +{ 3, s_7_85, -1, 1, 0}, +{ 3, s_7_86, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1 }; @@ -488,50 +488,49 @@ static const symbol s_15[] = { 'a', 't' }; static const symbol s_16[] = { 'a', 't' }; static const symbol s_17[] = { 'i', 'c' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ +static int r_prelude(struct SN_env * z) { int among_var; - { int c_test1 = z->c; /* test, line 35 */ -/* repeat, line 35 */ - - while(1) { int c2 = z->c; - z->bra = z->c; /* [, line 36 */ - among_var = find_among(z, a_0, 7); /* substring, line 36 */ + { int c_test1 = z->c; + while(1) { + int c2 = z->c; + z->bra = z->c; + among_var = find_among(z, a_0, 7); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 36 */ - switch (among_var) { /* among, line 36 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 37 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 38 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 39 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 40 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 41 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_5); /* <-, line 42 */ + { int ret = slice_from_s(z, 2, s_5); if (ret < 0) return ret; } break; case 7: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 43 */ + z->c++; break; } continue; @@ -541,29 +540,28 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ } z->c = c_test1; } -/* repeat, line 46 */ - - while(1) { int c3 = z->c; - while(1) { /* goto, line 46 */ + while(1) { + int c3 = z->c; + while(1) { int c4 = z->c; - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 47 */ - z->bra = z->c; /* [, line 47 */ - { int c5 = z->c; /* or, line 47 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab4; /* literal, line 47 */ + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; + z->bra = z->c; + { int c5 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab4; z->c++; - z->ket = z->c; /* ], line 47 */ - if (in_grouping(z, g_v, 97, 249, 0)) goto lab4; /* grouping v, line 47 */ - { int ret = slice_from_s(z, 1, s_6); /* <-, line 47 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 249, 0)) goto lab4; + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } goto lab3; lab4: z->c = c5; - if (z->c == z->l || z->p[z->c] != 'i') goto lab2; /* literal, line 48 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab2; z->c++; - z->ket = z->c; /* ], line 48 */ - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 48 */ - { int ret = slice_from_s(z, 1, s_7); /* <-, line 48 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } } @@ -573,7 +571,7 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ lab2: z->c = c4; if (z->c >= z->l) goto lab1; - z->c++; /* goto, line 46 */ + z->c++; } continue; lab1: @@ -583,16 +581,16 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 54 */ - z->I[1] = z->l; /* $p1 = , line 55 */ - z->I[2] = z->l; /* $p2 = , line 56 */ - { int c1 = z->c; /* do, line 58 */ - { int c2 = z->c; /* or, line 60 */ - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ - { int c3 = z->c; /* or, line 59 */ - if (out_grouping(z, g_v, 97, 249, 0)) goto lab4; /* non v, line 59 */ - { /* gopast */ /* grouping v, line 59 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping(z, g_v, 97, 249, 0)) goto lab4; + { int ret = out_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab4; z->c += ret; @@ -600,8 +598,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ - { /* gopast */ /* non v, line 59 */ + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; + { int ret = in_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab2; z->c += ret; @@ -611,10 +609,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 249, 0)) goto lab0; /* non v, line 61 */ - { int c4 = z->c; /* or, line 61 */ - if (out_grouping(z, g_v, 97, 249, 0)) goto lab6; /* non v, line 61 */ - { /* gopast */ /* grouping v, line 61 */ + if (out_grouping(z, g_v, 97, 249, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping(z, g_v, 97, 249, 0)) goto lab6; + { int ret = out_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab6; z->c += ret; @@ -622,71 +620,70 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 249, 0)) goto lab0; /* grouping v, line 61 */ + if (in_grouping(z, g_v, 97, 249, 0)) goto lab0; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 61 */ + z->c++; } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 62 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 64 */ - { /* gopast */ /* grouping v, line 65 */ + { int c5 = z->c; + { int ret = out_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 65 */ + { int ret = in_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 65 */ - { /* gopast */ /* grouping v, line 66 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 66 */ + { int ret = in_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 66 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 70 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 72 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 72 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 72 */ - switch (among_var) { /* among, line 72 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 73 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 74 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; case 3: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 75 */ + z->c++; break; } continue; @@ -697,41 +694,41 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 82 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 83 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 84 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ +static int r_attached_pronoun(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 87 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_2, 37))) return 0; - z->bra = z->c; /* ], line 87 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* among, line 97 */ + z->bra = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; among_var = find_among_b(z, a_3, 5); if (!(among_var)) return 0; - { int ret = r_RV(z); /* call RV, line 97 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 97 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 98 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 99 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; @@ -739,37 +736,37 @@ static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 104 */ - among_var = find_among_b(z, a_6, 51); /* substring, line 104 */ + z->ket = z->c; + among_var = find_among_b(z, a_6, 51); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 104 */ - switch (among_var) { /* among, line 104 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 111 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 111 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 113 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 113 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 114 */ - z->ket = z->c; /* [, line 114 */ - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m1; goto lab0; } /* literal, line 114 */ - z->bra = z->c; /* ], line 114 */ - { int ret = r_R2(z); /* call R2, line 114 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 114 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -777,67 +774,67 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - { int ret = r_R2(z); /* call R2, line 117 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_12); /* <-, line 117 */ + { int ret = slice_from_s(z, 3, s_12); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 119 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_13); /* <-, line 119 */ + { int ret = slice_from_s(z, 1, s_13); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 121 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_14); /* <-, line 121 */ + { int ret = slice_from_s(z, 4, s_14); if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); /* call RV, line 123 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 123 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 7: - { int ret = r_R1(z); /* call R1, line 125 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 126 */ - z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 127 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } among_var = find_among_b(z, a_4, 4); if (!(among_var)) { z->c = z->l - m2; goto lab1; } - z->bra = z->c; /* ], line 127 */ - { int ret = r_R2(z); /* call R2, line 127 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 127 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - switch (among_var) { /* among, line 127 */ + switch (among_var) { case 1: - z->ket = z->c; /* [, line 128 */ - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m2; goto lab1; } /* literal, line 128 */ - z->bra = z->c; /* ], line 128 */ - { int ret = r_R2(z); /* call R2, line 128 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m2; goto lab1; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 128 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -847,22 +844,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 134 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ - z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m3; goto lab2; } - z->bra = z->c; /* ], line 136 */ - { int ret = r_R2(z); /* call R2, line 137 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab2; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 137 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: @@ -870,31 +867,31 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = r_R2(z); /* call R2, line 142 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 142 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 143 */ - z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ - z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); /* call R2, line 143 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m4; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 143 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ - z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); /* call R2, line 143 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m4; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 143 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab3: @@ -905,15 +902,15 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 148 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 149 */ - if (!(find_among_b(z, a_7, 87))) { z->lb = mlimit1; return 0; } /* substring, line 149 */ - z->bra = z->c; /* ], line 149 */ - { int ret = slice_del(z); /* delete, line 163 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (!(find_among_b(z, a_7, 87))) { z->lb = mlimit1; return 0; } + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; @@ -921,43 +918,43 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* try, line 171 */ - z->ket = z->c; /* [, line 172 */ - if (in_grouping_b(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m1; goto lab0; } /* grouping AEIO, line 172 */ - z->bra = z->c; /* ], line 172 */ - { int ret = r_RV(z); /* call RV, line 172 */ +static int r_vowel_suffix(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (in_grouping_b(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 172 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 173 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'i') { z->c = z->l - m1; goto lab0; } /* literal, line 173 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') { z->c = z->l - m1; goto lab0; } z->c--; - z->bra = z->c; /* ], line 173 */ - { int ret = r_RV(z); /* call RV, line 173 */ + z->bra = z->c; + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 173 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: ; } - { int m2 = z->l - z->c; (void)m2; /* try, line 175 */ - z->ket = z->c; /* [, line 176 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'h') { z->c = z->l - m2; goto lab1; } /* literal, line 176 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'h') { z->c = z->l - m2; goto lab1; } z->c--; - z->bra = z->c; /* ], line 176 */ - if (in_grouping_b(z, g_CG, 99, 103, 0)) { z->c = z->l - m2; goto lab1; } /* grouping CG, line 176 */ - { int ret = r_RV(z); /* call RV, line 176 */ + z->bra = z->c; + if (in_grouping_b(z, g_CG, 99, 103, 0)) { z->c = z->l - m2; goto lab1; } + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 176 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: @@ -966,35 +963,35 @@ static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int italian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 182 */ - { int ret = r_prelude(z); /* call prelude, line 182 */ +extern int italian_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 183 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 183 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 184 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 185 */ - { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 185 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_attached_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 186 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 186 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 186 */ + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m4; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 186 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1003,15 +1000,15 @@ extern int italian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m3; } - { int m5 = z->l - z->c; (void)m5; /* do, line 187 */ - { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 187 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_vowel_suffix(z); if (ret < 0) return ret; } z->c = z->l - m5; } z->c = z->lb; - { int c6 = z->c; /* do, line 189 */ - { int ret = r_postlude(z); /* call postlude, line 189 */ + { int c6 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c6; @@ -1019,7 +1016,7 @@ extern int italian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * italian_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * italian_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void italian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c index a70f6f5aa200..59f7579f1d70 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -57,35 +57,35 @@ static const symbol s_0_28[3] = { 'a', 's', 't' }; static const struct among a_0[29] = { -/* 0 */ { 1, s_0_0, -1, 1, 0}, -/* 1 */ { 1, s_0_1, -1, 1, 0}, -/* 2 */ { 3, s_0_2, 1, 1, 0}, -/* 3 */ { 4, s_0_3, 1, 1, 0}, -/* 4 */ { 4, s_0_4, 1, 1, 0}, -/* 5 */ { 3, s_0_5, 1, 1, 0}, -/* 6 */ { 3, s_0_6, 1, 1, 0}, -/* 7 */ { 6, s_0_7, 6, 1, 0}, -/* 8 */ { 4, s_0_8, 1, 3, 0}, -/* 9 */ { 2, s_0_9, -1, 1, 0}, -/* 10 */ { 5, s_0_10, 9, 1, 0}, -/* 11 */ { 2, s_0_11, -1, 1, 0}, -/* 12 */ { 2, s_0_12, -1, 1, 0}, -/* 13 */ { 5, s_0_13, 12, 1, 0}, -/* 14 */ { 1, s_0_14, -1, 2, 0}, -/* 15 */ { 2, s_0_15, 14, 1, 0}, -/* 16 */ { 2, s_0_16, 14, 1, 0}, -/* 17 */ { 4, s_0_17, 16, 1, 0}, -/* 18 */ { 5, s_0_18, 16, 1, 0}, -/* 19 */ { 4, s_0_19, 16, 1, 0}, -/* 20 */ { 7, s_0_20, 19, 1, 0}, -/* 21 */ { 3, s_0_21, 14, 1, 0}, -/* 22 */ { 6, s_0_22, 21, 1, 0}, -/* 23 */ { 3, s_0_23, 14, 1, 0}, -/* 24 */ { 3, s_0_24, 14, 1, 0}, -/* 25 */ { 2, s_0_25, -1, 1, 0}, -/* 26 */ { 3, s_0_26, 25, 1, 0}, -/* 27 */ { 3, s_0_27, -1, 3, 0}, -/* 28 */ { 3, s_0_28, -1, 1, 0} +{ 1, s_0_0, -1, 1, 0}, +{ 1, s_0_1, -1, 1, 0}, +{ 3, s_0_2, 1, 1, 0}, +{ 4, s_0_3, 1, 1, 0}, +{ 4, s_0_4, 1, 1, 0}, +{ 3, s_0_5, 1, 1, 0}, +{ 3, s_0_6, 1, 1, 0}, +{ 6, s_0_7, 6, 1, 0}, +{ 4, s_0_8, 1, 3, 0}, +{ 2, s_0_9, -1, 1, 0}, +{ 5, s_0_10, 9, 1, 0}, +{ 2, s_0_11, -1, 1, 0}, +{ 2, s_0_12, -1, 1, 0}, +{ 5, s_0_13, 12, 1, 0}, +{ 1, s_0_14, -1, 2, 0}, +{ 2, s_0_15, 14, 1, 0}, +{ 2, s_0_16, 14, 1, 0}, +{ 4, s_0_17, 16, 1, 0}, +{ 5, s_0_18, 16, 1, 0}, +{ 4, s_0_19, 16, 1, 0}, +{ 7, s_0_20, 19, 1, 0}, +{ 3, s_0_21, 14, 1, 0}, +{ 6, s_0_22, 21, 1, 0}, +{ 3, s_0_23, 14, 1, 0}, +{ 3, s_0_24, 14, 1, 0}, +{ 2, s_0_25, -1, 1, 0}, +{ 3, s_0_26, 25, 1, 0}, +{ 3, s_0_27, -1, 3, 0}, +{ 3, s_0_28, -1, 1, 0} }; static const symbol s_1_0[2] = { 'd', 't' }; @@ -93,8 +93,8 @@ static const symbol s_1_1[2] = { 'v', 't' }; static const struct among a_1[2] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0} }; static const symbol s_2_0[3] = { 'l', 'e', 'g' }; @@ -111,17 +111,17 @@ static const symbol s_2_10[7] = { 'h', 'e', 't', 's', 'l', 'o', 'v' }; static const struct among a_2[11] = { -/* 0 */ { 3, s_2_0, -1, 1, 0}, -/* 1 */ { 4, s_2_1, 0, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 1, 0}, -/* 3 */ { 3, s_2_3, 2, 1, 0}, -/* 4 */ { 3, s_2_4, 2, 1, 0}, -/* 5 */ { 4, s_2_5, 4, 1, 0}, -/* 6 */ { 3, s_2_6, -1, 1, 0}, -/* 7 */ { 3, s_2_7, -1, 1, 0}, -/* 8 */ { 4, s_2_8, 7, 1, 0}, -/* 9 */ { 4, s_2_9, 7, 1, 0}, -/* 10 */ { 7, s_2_10, 9, 1, 0} +{ 3, s_2_0, -1, 1, 0}, +{ 4, s_2_1, 0, 1, 0}, +{ 2, s_2_2, -1, 1, 0}, +{ 3, s_2_3, 2, 1, 0}, +{ 3, s_2_4, 2, 1, 0}, +{ 4, s_2_5, 4, 1, 0}, +{ 3, s_2_6, -1, 1, 0}, +{ 3, s_2_7, -1, 1, 0}, +{ 4, s_2_8, 7, 1, 0}, +{ 4, s_2_9, 7, 1, 0}, +{ 7, s_2_10, 9, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; @@ -130,66 +130,64 @@ static const unsigned char g_s_ending[] = { 119, 125, 149, 1 }; static const symbol s_0[] = { 'e', 'r' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 28 */ - { int c_test1 = z->c; /* test, line 30 */ - { int ret = z->c + 3; /* hop, line 30 */ - if (0 > ret || ret > z->l) return 0; - z->c = ret; - } - z->I[1] = z->c; /* setmark x, line 30 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + { int c_test1 = z->c; +z->c = z->c + 3; + if (z->c > z->l) return 0; + z->I[0] = z->c; z->c = c_test1; } - if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 31 */ - { /* gopast */ /* non v, line 31 */ + if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; + { int ret = in_grouping(z, g_v, 97, 248, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 31 */ - /* try, line 32 */ - if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 32 */ - z->I[0] = z->I[1]; /* $p1 = , line 32 */ + z->I[1] = z->c; + + if (!(z->I[1] < z->I[0])) goto lab0; + z->I[1] = z->I[0]; lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { /* backwardmode */ +static int r_main_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 38 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 38 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 38 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_0, 29); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 38 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 39 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 44 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m2 = z->l - z->c; (void)m2; /* or, line 46 */ - if (in_grouping_b(z, g_s_ending, 98, 122, 0)) goto lab1; /* grouping s_ending, line 46 */ + { int m2 = z->l - z->c; (void)m2; + if (in_grouping_b(z, g_s_ending, 98, 122, 0)) goto lab1; goto lab0; lab1: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'k') return 0; /* literal, line 46 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'k') return 0; z->c--; - if (out_grouping_b(z, g_v, 97, 248, 0)) return 0; /* non v, line 46 */ + if (out_grouping_b(z, g_v, 97, 248, 0)) return 0; } lab0: - { int ret = slice_del(z); /* delete, line 46 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 48 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; @@ -197,69 +195,69 @@ static int r_main_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 53 */ +static int r_consonant_pair(struct SN_env * z) { + { int m_test1 = z->l - z->c; - { int mlimit2; /* setlimit, line 54 */ - if (z->c < z->I[0]) return 0; - mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 54 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit2; return 0; } /* substring, line 54 */ + { int mlimit2; + if (z->c < z->I[1]) return 0; + mlimit2 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit2; return 0; } if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit2; return 0; } - z->bra = z->c; /* ], line 54 */ + z->bra = z->c; z->lb = mlimit2; } z->c = z->l - m_test1; } if (z->c <= z->lb) return 0; - z->c--; /* next, line 59 */ - z->bra = z->c; /* ], line 59 */ - { int ret = slice_del(z); /* delete, line 59 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_other_suffix(struct SN_env * z) { /* backwardmode */ +static int r_other_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 63 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 63 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 63 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_2, 11))) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 63 */ + z->bra = z->c; z->lb = mlimit1; } - { int ret = slice_del(z); /* delete, line 67 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int norwegian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 74 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 74 */ +extern int norwegian_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 75 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 76 */ - { int ret = r_main_suffix(z); /* call main_suffix, line 76 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_main_suffix(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 77 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 77 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 78 */ - { int ret = r_other_suffix(z); /* call other_suffix, line 78 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_other_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; @@ -268,7 +266,7 @@ extern int norwegian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * norwegian_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * norwegian_ISO_8859_1_create_env(void) { return SN_create_env(0, 2); } extern void norwegian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c index 4666afb725f2..c698662d42ce 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -39,10 +39,10 @@ static const symbol s_0_3[2] = { 's', 's' }; static const struct among a_0[4] = { -/* 0 */ { 1, s_0_0, -1, 3, 0}, -/* 1 */ { 3, s_0_1, 0, 2, 0}, -/* 2 */ { 4, s_0_2, 0, 1, 0}, -/* 3 */ { 2, s_0_3, 0, -1, 0} +{ 1, s_0_0, -1, 3, 0}, +{ 3, s_0_1, 0, 2, 0}, +{ 4, s_0_2, 0, 1, 0}, +{ 2, s_0_3, 0, -1, 0} }; static const symbol s_1_1[2] = { 'b', 'b' }; @@ -60,19 +60,19 @@ static const symbol s_1_12[2] = { 'i', 'z' }; static const struct among a_1[13] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 2, s_1_1, 0, 2, 0}, -/* 2 */ { 2, s_1_2, 0, 2, 0}, -/* 3 */ { 2, s_1_3, 0, 2, 0}, -/* 4 */ { 2, s_1_4, 0, 2, 0}, -/* 5 */ { 2, s_1_5, 0, 1, 0}, -/* 6 */ { 2, s_1_6, 0, 2, 0}, -/* 7 */ { 2, s_1_7, 0, 2, 0}, -/* 8 */ { 2, s_1_8, 0, 2, 0}, -/* 9 */ { 2, s_1_9, 0, 2, 0}, -/* 10 */ { 2, s_1_10, 0, 1, 0}, -/* 11 */ { 2, s_1_11, 0, 2, 0}, -/* 12 */ { 2, s_1_12, 0, 1, 0} +{ 0, 0, -1, 3, 0}, +{ 2, s_1_1, 0, 2, 0}, +{ 2, s_1_2, 0, 2, 0}, +{ 2, s_1_3, 0, 2, 0}, +{ 2, s_1_4, 0, 2, 0}, +{ 2, s_1_5, 0, 1, 0}, +{ 2, s_1_6, 0, 2, 0}, +{ 2, s_1_7, 0, 2, 0}, +{ 2, s_1_8, 0, 2, 0}, +{ 2, s_1_9, 0, 2, 0}, +{ 2, s_1_10, 0, 1, 0}, +{ 2, s_1_11, 0, 2, 0}, +{ 2, s_1_12, 0, 1, 0} }; static const symbol s_2_0[2] = { 'e', 'd' }; @@ -81,9 +81,9 @@ static const symbol s_2_2[3] = { 'i', 'n', 'g' }; static const struct among a_2[3] = { -/* 0 */ { 2, s_2_0, -1, 2, 0}, -/* 1 */ { 3, s_2_1, 0, 1, 0}, -/* 2 */ { 3, s_2_2, -1, 2, 0} +{ 2, s_2_0, -1, 2, 0}, +{ 3, s_2_1, 0, 1, 0}, +{ 3, s_2_2, -1, 2, 0} }; static const symbol s_3_0[4] = { 'a', 'n', 'c', 'i' }; @@ -109,26 +109,26 @@ static const symbol s_3_19[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; static const struct among a_3[20] = { -/* 0 */ { 4, s_3_0, -1, 3, 0}, -/* 1 */ { 4, s_3_1, -1, 2, 0}, -/* 2 */ { 4, s_3_2, -1, 4, 0}, -/* 3 */ { 3, s_3_3, -1, 6, 0}, -/* 4 */ { 4, s_3_4, -1, 9, 0}, -/* 5 */ { 5, s_3_5, -1, 11, 0}, -/* 6 */ { 5, s_3_6, -1, 5, 0}, -/* 7 */ { 5, s_3_7, -1, 9, 0}, -/* 8 */ { 6, s_3_8, -1, 13, 0}, -/* 9 */ { 5, s_3_9, -1, 12, 0}, -/* 10 */ { 6, s_3_10, -1, 1, 0}, -/* 11 */ { 7, s_3_11, 10, 8, 0}, -/* 12 */ { 5, s_3_12, -1, 9, 0}, -/* 13 */ { 5, s_3_13, -1, 8, 0}, -/* 14 */ { 7, s_3_14, 13, 7, 0}, -/* 15 */ { 4, s_3_15, -1, 7, 0}, -/* 16 */ { 4, s_3_16, -1, 8, 0}, -/* 17 */ { 7, s_3_17, -1, 12, 0}, -/* 18 */ { 7, s_3_18, -1, 10, 0}, -/* 19 */ { 7, s_3_19, -1, 11, 0} +{ 4, s_3_0, -1, 3, 0}, +{ 4, s_3_1, -1, 2, 0}, +{ 4, s_3_2, -1, 4, 0}, +{ 3, s_3_3, -1, 6, 0}, +{ 4, s_3_4, -1, 9, 0}, +{ 5, s_3_5, -1, 11, 0}, +{ 5, s_3_6, -1, 5, 0}, +{ 5, s_3_7, -1, 9, 0}, +{ 6, s_3_8, -1, 13, 0}, +{ 5, s_3_9, -1, 12, 0}, +{ 6, s_3_10, -1, 1, 0}, +{ 7, s_3_11, 10, 8, 0}, +{ 5, s_3_12, -1, 9, 0}, +{ 5, s_3_13, -1, 8, 0}, +{ 7, s_3_14, 13, 7, 0}, +{ 4, s_3_15, -1, 7, 0}, +{ 4, s_3_16, -1, 8, 0}, +{ 7, s_3_17, -1, 12, 0}, +{ 7, s_3_18, -1, 10, 0}, +{ 7, s_3_19, -1, 11, 0} }; static const symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' }; @@ -141,13 +141,13 @@ static const symbol s_4_6[4] = { 'n', 'e', 's', 's' }; static const struct among a_4[7] = { -/* 0 */ { 5, s_4_0, -1, 2, 0}, -/* 1 */ { 5, s_4_1, -1, 3, 0}, -/* 2 */ { 5, s_4_2, -1, 1, 0}, -/* 3 */ { 5, s_4_3, -1, 2, 0}, -/* 4 */ { 4, s_4_4, -1, 2, 0}, -/* 5 */ { 3, s_4_5, -1, 3, 0}, -/* 6 */ { 4, s_4_6, -1, 3, 0} +{ 5, s_4_0, -1, 2, 0}, +{ 5, s_4_1, -1, 3, 0}, +{ 5, s_4_2, -1, 1, 0}, +{ 5, s_4_3, -1, 2, 0}, +{ 4, s_4_4, -1, 2, 0}, +{ 3, s_4_5, -1, 3, 0}, +{ 4, s_4_6, -1, 3, 0} }; static const symbol s_5_0[2] = { 'i', 'c' }; @@ -172,25 +172,25 @@ static const symbol s_5_18[2] = { 'o', 'u' }; static const struct among a_5[19] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 4, s_5_1, -1, 1, 0}, -/* 2 */ { 4, s_5_2, -1, 1, 0}, -/* 3 */ { 4, s_5_3, -1, 1, 0}, -/* 4 */ { 4, s_5_4, -1, 1, 0}, -/* 5 */ { 3, s_5_5, -1, 1, 0}, -/* 6 */ { 3, s_5_6, -1, 1, 0}, -/* 7 */ { 3, s_5_7, -1, 1, 0}, -/* 8 */ { 3, s_5_8, -1, 1, 0}, -/* 9 */ { 2, s_5_9, -1, 1, 0}, -/* 10 */ { 3, s_5_10, -1, 1, 0}, -/* 11 */ { 3, s_5_11, -1, 2, 0}, -/* 12 */ { 2, s_5_12, -1, 1, 0}, -/* 13 */ { 3, s_5_13, -1, 1, 0}, -/* 14 */ { 3, s_5_14, -1, 1, 0}, -/* 15 */ { 3, s_5_15, -1, 1, 0}, -/* 16 */ { 4, s_5_16, 15, 1, 0}, -/* 17 */ { 5, s_5_17, 16, 1, 0}, -/* 18 */ { 2, s_5_18, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 4, s_5_1, -1, 1, 0}, +{ 4, s_5_2, -1, 1, 0}, +{ 4, s_5_3, -1, 1, 0}, +{ 4, s_5_4, -1, 1, 0}, +{ 3, s_5_5, -1, 1, 0}, +{ 3, s_5_6, -1, 1, 0}, +{ 3, s_5_7, -1, 1, 0}, +{ 3, s_5_8, -1, 1, 0}, +{ 2, s_5_9, -1, 1, 0}, +{ 3, s_5_10, -1, 1, 0}, +{ 3, s_5_11, -1, 2, 0}, +{ 2, s_5_12, -1, 1, 0}, +{ 3, s_5_13, -1, 1, 0}, +{ 3, s_5_14, -1, 1, 0}, +{ 3, s_5_15, -1, 1, 0}, +{ 4, s_5_16, 15, 1, 0}, +{ 5, s_5_17, 16, 1, 0}, +{ 2, s_5_18, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1 }; @@ -222,43 +222,43 @@ static const symbol s_21[] = { 'Y' }; static const symbol s_22[] = { 'Y' }; static const symbol s_23[] = { 'y' }; -static int r_shortv(struct SN_env * z) { /* backwardmode */ - if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) return 0; /* non v_WXY, line 19 */ - if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 19 */ - if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; /* non v, line 19 */ +static int r_shortv(struct SN_env * z) { + if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) return 0; + if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; + if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 21 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 22 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_Step_1a(struct SN_env * z) { /* backwardmode */ +static int r_Step_1a(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 25 */ - if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; /* substring, line 25 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; among_var = find_among_b(z, a_0, 4); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 25 */ - switch (among_var) { /* among, line 25 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 26 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 27 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 29 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -266,70 +266,70 @@ static int r_Step_1a(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1b(struct SN_env * z) { /* backwardmode */ +static int r_Step_1b(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 34 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 34 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; among_var = find_among_b(z, a_2, 3); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 34 */ - switch (among_var) { /* among, line 34 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 35 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_2); /* <-, line 35 */ + { int ret = slice_from_s(z, 2, s_2); if (ret < 0) return ret; } break; case 2: - { int m_test1 = z->l - z->c; /* test, line 38 */ - { /* gopast */ /* grouping v, line 38 */ + { int m_test1 = z->l - z->c; + { int ret = out_grouping_b(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } z->c = z->l - m_test1; } - { int ret = slice_del(z); /* delete, line 38 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m_test2 = z->l - z->c; /* test, line 39 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 39 */ + { int m_test2 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else among_var = find_among_b(z, a_1, 13); if (!(among_var)) return 0; z->c = z->l - m_test2; } - switch (among_var) { /* among, line 39 */ + switch (among_var) { case 1: { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ + ret = insert_s(z, z->c, z->c, 1, s_3); z->c = saved_c; } if (ret < 0) return ret; } break; case 2: - z->ket = z->c; /* [, line 44 */ + z->ket = z->c; if (z->c <= z->lb) return 0; - z->c--; /* next, line 44 */ - z->bra = z->c; /* ], line 44 */ - { int ret = slice_del(z); /* delete, line 44 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - if (z->c != z->I[0]) return 0; /* atmark, line 45 */ - { int m_test3 = z->l - z->c; /* test, line 45 */ - { int ret = r_shortv(z); /* call shortv, line 45 */ + if (z->c != z->I[1]) return 0; + { int m_test3 = z->l - z->c; + { int ret = r_shortv(z); if (ret <= 0) return ret; } z->c = z->l - m_test3; } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ + ret = insert_s(z, z->c, z->c, 1, s_4); z->c = saved_c; } if (ret < 0) return ret; @@ -341,103 +341,103 @@ static int r_Step_1b(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1c(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 52 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 52 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 52 */ +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 52 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; z->c--; } lab0: - z->bra = z->c; /* ], line 52 */ - { /* gopast */ /* grouping v, line 53 */ + z->bra = z->c; + { int ret = out_grouping_b(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - { int ret = slice_from_s(z, 1, s_5); /* <-, line 54 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { /* backwardmode */ +static int r_Step_2(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 58 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 58 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_3, 20); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 58 */ - { int ret = r_R1(z); /* call R1, line 58 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 58 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_6); /* <-, line 59 */ + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_7); /* <-, line 60 */ + { int ret = slice_from_s(z, 4, s_7); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_8); /* <-, line 61 */ + { int ret = slice_from_s(z, 4, s_8); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_9); /* <-, line 62 */ + { int ret = slice_from_s(z, 4, s_9); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_10); /* <-, line 63 */ + { int ret = slice_from_s(z, 3, s_10); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 64 */ + { int ret = slice_from_s(z, 1, s_11); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_12); /* <-, line 66 */ + { int ret = slice_from_s(z, 3, s_12); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 3, s_13); /* <-, line 68 */ + { int ret = slice_from_s(z, 3, s_13); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 2, s_14); /* <-, line 69 */ + { int ret = slice_from_s(z, 2, s_14); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 3, s_15); /* <-, line 72 */ + { int ret = slice_from_s(z, 3, s_15); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_16); /* <-, line 74 */ + { int ret = slice_from_s(z, 3, s_16); if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_17); /* <-, line 76 */ + { int ret = slice_from_s(z, 3, s_17); if (ret < 0) return ret; } break; case 13: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 77 */ + { int ret = slice_from_s(z, 3, s_18); if (ret < 0) return ret; } break; @@ -445,29 +445,29 @@ static int r_Step_2(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_3(struct SN_env * z) { /* backwardmode */ +static int r_Step_3(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 82 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 82 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_4, 7); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 82 */ - { int ret = r_R1(z); /* call R1, line 82 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 82 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_19); /* <-, line 83 */ + { int ret = slice_from_s(z, 2, s_19); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_20); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_20); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -475,34 +475,34 @@ static int r_Step_3(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_4(struct SN_env * z) { /* backwardmode */ +static int r_Step_4(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 92 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 92 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_5, 19); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 92 */ - { int ret = r_R2(z); /* call R2, line 92 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 92 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 95 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m1 = z->l - z->c; (void)m1; /* or, line 96 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 96 */ + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 96 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -510,24 +510,24 @@ static int r_Step_4(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_5a(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 101 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 101 */ +static int r_Step_5a(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; - z->bra = z->c; /* ], line 101 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 102 */ - { int ret = r_R2(z); /* call R2, line 102 */ + z->bra = z->c; + { int m1 = z->l - z->c; (void)m1; + { int ret = r_R2(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); /* call R1, line 102 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - { int ret = r_shortv(z); /* call shortv, line 102 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_shortv(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } @@ -537,64 +537,63 @@ static int r_Step_5a(struct SN_env * z) { /* backwardmode */ } } lab0: - { int ret = slice_del(z); /* delete, line 103 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Step_5b(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 107 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 107 */ +static int r_Step_5b(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - z->bra = z->c; /* ], line 107 */ - { int ret = r_R2(z); /* call R2, line 108 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 108 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 109 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int porter_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset Y_found, line 115 */ - { int c1 = z->c; /* do, line 116 */ - z->bra = z->c; /* [, line 116 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab0; /* literal, line 116 */ +extern int porter_ISO_8859_1_stem(struct SN_env * z) { + z->I[2] = 0; + { int c1 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab0; z->c++; - z->ket = z->c; /* ], line 116 */ - { int ret = slice_from_s(z, 1, s_21); /* <-, line 116 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_21); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 116 */ + z->I[2] = 1; lab0: z->c = c1; } - { int c2 = z->c; /* do, line 117 */ -/* repeat, line 117 */ - - while(1) { int c3 = z->c; - while(1) { /* goto, line 117 */ + { int c2 = z->c; + while(1) { + int c3 = z->c; + while(1) { int c4 = z->c; - if (in_grouping(z, g_v, 97, 121, 0)) goto lab3; /* grouping v, line 117 */ - z->bra = z->c; /* [, line 117 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 117 */ + if (in_grouping(z, g_v, 97, 121, 0)) goto lab3; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; z->c++; - z->ket = z->c; /* ], line 117 */ + z->ket = z->c; z->c = c4; break; lab3: z->c = c4; if (z->c >= z->l) goto lab2; - z->c++; /* goto, line 117 */ + z->c++; } - { int ret = slice_from_s(z, 1, s_22); /* <-, line 117 */ + { int ret = slice_from_s(z, 1, s_22); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 117 */ + z->I[2] = 1; continue; lab2: z->c = c3; @@ -602,104 +601,103 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ } z->c = c2; } - z->I[0] = z->l; /* $p1 = , line 119 */ - z->I[1] = z->l; /* $p2 = , line 120 */ - { int c5 = z->c; /* do, line 121 */ - { /* gopast */ /* grouping v, line 122 */ + z->I[1] = z->l; + z->I[0] = z->l; + { int c5 = z->c; + { int ret = out_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 122 */ + { int ret = in_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 122 */ - { /* gopast */ /* grouping v, line 123 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 123 */ + { int ret = in_grouping(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 123 */ + z->I[0] = z->c; lab4: z->c = c5; } - z->lb = z->c; z->c = z->l; /* backwards, line 126 */ + z->lb = z->c; z->c = z->l; - { int m6 = z->l - z->c; (void)m6; /* do, line 127 */ - { int ret = r_Step_1a(z); /* call Step_1a, line 127 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_Step_1a(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 128 */ - { int ret = r_Step_1b(z); /* call Step_1b, line 128 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_Step_1b(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 129 */ - { int ret = r_Step_1c(z); /* call Step_1c, line 129 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_Step_1c(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 130 */ - { int ret = r_Step_2(z); /* call Step_2, line 130 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_Step_2(z); if (ret < 0) return ret; } z->c = z->l - m9; } - { int m10 = z->l - z->c; (void)m10; /* do, line 131 */ - { int ret = r_Step_3(z); /* call Step_3, line 131 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_Step_3(z); if (ret < 0) return ret; } z->c = z->l - m10; } - { int m11 = z->l - z->c; (void)m11; /* do, line 132 */ - { int ret = r_Step_4(z); /* call Step_4, line 132 */ + { int m11 = z->l - z->c; (void)m11; + { int ret = r_Step_4(z); if (ret < 0) return ret; } z->c = z->l - m11; } - { int m12 = z->l - z->c; (void)m12; /* do, line 133 */ - { int ret = r_Step_5a(z); /* call Step_5a, line 133 */ + { int m12 = z->l - z->c; (void)m12; + { int ret = r_Step_5a(z); if (ret < 0) return ret; } z->c = z->l - m12; } - { int m13 = z->l - z->c; (void)m13; /* do, line 134 */ - { int ret = r_Step_5b(z); /* call Step_5b, line 134 */ + { int m13 = z->l - z->c; (void)m13; + { int ret = r_Step_5b(z); if (ret < 0) return ret; } z->c = z->l - m13; } z->c = z->lb; - { int c14 = z->c; /* do, line 137 */ - if (!(z->B[0])) goto lab5; /* Boolean test Y_found, line 137 */ -/* repeat, line 137 */ - - while(1) { int c15 = z->c; - while(1) { /* goto, line 137 */ + { int c14 = z->c; + if (!(z->I[2])) goto lab5; + while(1) { + int c15 = z->c; + while(1) { int c16 = z->c; - z->bra = z->c; /* [, line 137 */ - if (z->c == z->l || z->p[z->c] != 'Y') goto lab7; /* literal, line 137 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab7; z->c++; - z->ket = z->c; /* ], line 137 */ + z->ket = z->c; z->c = c16; break; lab7: z->c = c16; if (z->c >= z->l) goto lab6; - z->c++; /* goto, line 137 */ + z->c++; } - { int ret = slice_from_s(z, 1, s_23); /* <-, line 137 */ + { int ret = slice_from_s(z, 1, s_23); if (ret < 0) return ret; } continue; @@ -713,7 +711,7 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * porter_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 1); } +extern struct SN_env * porter_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void porter_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c index 1e440a66e143..23d883a7a13c 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -36,9 +36,9 @@ static const symbol s_0_2[1] = { 0xF5 }; static const struct among a_0[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 1, s_0_1, 0, 1, 0}, -/* 2 */ { 1, s_0_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 1, s_0_1, 0, 1, 0}, +{ 1, s_0_2, 0, 2, 0} }; static const symbol s_1_1[2] = { 'a', '~' }; @@ -46,9 +46,9 @@ static const symbol s_1_2[2] = { 'o', '~' }; static const struct among a_1[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 2, s_1_1, 0, 1, 0}, -/* 2 */ { 2, s_1_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 2, s_1_1, 0, 1, 0}, +{ 2, s_1_2, 0, 2, 0} }; static const symbol s_2_0[2] = { 'i', 'c' }; @@ -58,10 +58,10 @@ static const symbol s_2_3[2] = { 'i', 'v' }; static const struct among a_2[4] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 2, s_2_2, -1, -1, 0}, -/* 3 */ { 2, s_2_3, -1, 1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 2, s_2_2, -1, -1, 0}, +{ 2, s_2_3, -1, 1, 0} }; static const symbol s_3_0[4] = { 'a', 'n', 't', 'e' }; @@ -70,9 +70,9 @@ static const symbol s_3_2[4] = { 0xED, 'v', 'e', 'l' }; static const struct among a_3[3] = { -/* 0 */ { 4, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 4, s_3_2, -1, 1, 0} +{ 4, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 4, s_3_2, -1, 1, 0} }; static const symbol s_4_0[2] = { 'i', 'c' }; @@ -81,9 +81,9 @@ static const symbol s_4_2[2] = { 'i', 'v' }; static const struct among a_4[3] = { -/* 0 */ { 2, s_4_0, -1, 1, 0}, -/* 1 */ { 4, s_4_1, -1, 1, 0}, -/* 2 */ { 2, s_4_2, -1, 1, 0} +{ 2, s_4_0, -1, 1, 0}, +{ 4, s_4_1, -1, 1, 0}, +{ 2, s_4_2, -1, 1, 0} }; static const symbol s_5_0[3] = { 'i', 'c', 'a' }; @@ -134,51 +134,51 @@ static const symbol s_5_44[4] = { 'i', 'v', 'o', 's' }; static const struct among a_5[45] = { -/* 0 */ { 3, s_5_0, -1, 1, 0}, -/* 1 */ { 5, s_5_1, -1, 1, 0}, -/* 2 */ { 5, s_5_2, -1, 4, 0}, -/* 3 */ { 5, s_5_3, -1, 2, 0}, -/* 4 */ { 3, s_5_4, -1, 9, 0}, -/* 5 */ { 5, s_5_5, -1, 1, 0}, -/* 6 */ { 3, s_5_6, -1, 1, 0}, -/* 7 */ { 4, s_5_7, -1, 1, 0}, -/* 8 */ { 3, s_5_8, -1, 8, 0}, -/* 9 */ { 3, s_5_9, -1, 1, 0}, -/* 10 */ { 5, s_5_10, -1, 7, 0}, -/* 11 */ { 4, s_5_11, -1, 1, 0}, -/* 12 */ { 5, s_5_12, -1, 6, 0}, -/* 13 */ { 6, s_5_13, 12, 5, 0}, -/* 14 */ { 4, s_5_14, -1, 1, 0}, -/* 15 */ { 4, s_5_15, -1, 1, 0}, -/* 16 */ { 3, s_5_16, -1, 1, 0}, -/* 17 */ { 4, s_5_17, -1, 1, 0}, -/* 18 */ { 3, s_5_18, -1, 1, 0}, -/* 19 */ { 6, s_5_19, -1, 1, 0}, -/* 20 */ { 6, s_5_20, -1, 1, 0}, -/* 21 */ { 3, s_5_21, -1, 8, 0}, -/* 22 */ { 5, s_5_22, -1, 1, 0}, -/* 23 */ { 5, s_5_23, -1, 3, 0}, -/* 24 */ { 4, s_5_24, -1, 1, 0}, -/* 25 */ { 4, s_5_25, -1, 1, 0}, -/* 26 */ { 6, s_5_26, -1, 4, 0}, -/* 27 */ { 6, s_5_27, -1, 2, 0}, -/* 28 */ { 4, s_5_28, -1, 9, 0}, -/* 29 */ { 6, s_5_29, -1, 1, 0}, -/* 30 */ { 4, s_5_30, -1, 1, 0}, -/* 31 */ { 5, s_5_31, -1, 1, 0}, -/* 32 */ { 4, s_5_32, -1, 8, 0}, -/* 33 */ { 4, s_5_33, -1, 1, 0}, -/* 34 */ { 6, s_5_34, -1, 7, 0}, -/* 35 */ { 6, s_5_35, -1, 1, 0}, -/* 36 */ { 5, s_5_36, -1, 1, 0}, -/* 37 */ { 6, s_5_37, -1, 1, 0}, -/* 38 */ { 6, s_5_38, -1, 3, 0}, -/* 39 */ { 4, s_5_39, -1, 1, 0}, -/* 40 */ { 5, s_5_40, -1, 1, 0}, -/* 41 */ { 4, s_5_41, -1, 1, 0}, -/* 42 */ { 7, s_5_42, -1, 1, 0}, -/* 43 */ { 7, s_5_43, -1, 1, 0}, -/* 44 */ { 4, s_5_44, -1, 8, 0} +{ 3, s_5_0, -1, 1, 0}, +{ 5, s_5_1, -1, 1, 0}, +{ 5, s_5_2, -1, 4, 0}, +{ 5, s_5_3, -1, 2, 0}, +{ 3, s_5_4, -1, 9, 0}, +{ 5, s_5_5, -1, 1, 0}, +{ 3, s_5_6, -1, 1, 0}, +{ 4, s_5_7, -1, 1, 0}, +{ 3, s_5_8, -1, 8, 0}, +{ 3, s_5_9, -1, 1, 0}, +{ 5, s_5_10, -1, 7, 0}, +{ 4, s_5_11, -1, 1, 0}, +{ 5, s_5_12, -1, 6, 0}, +{ 6, s_5_13, 12, 5, 0}, +{ 4, s_5_14, -1, 1, 0}, +{ 4, s_5_15, -1, 1, 0}, +{ 3, s_5_16, -1, 1, 0}, +{ 4, s_5_17, -1, 1, 0}, +{ 3, s_5_18, -1, 1, 0}, +{ 6, s_5_19, -1, 1, 0}, +{ 6, s_5_20, -1, 1, 0}, +{ 3, s_5_21, -1, 8, 0}, +{ 5, s_5_22, -1, 1, 0}, +{ 5, s_5_23, -1, 3, 0}, +{ 4, s_5_24, -1, 1, 0}, +{ 4, s_5_25, -1, 1, 0}, +{ 6, s_5_26, -1, 4, 0}, +{ 6, s_5_27, -1, 2, 0}, +{ 4, s_5_28, -1, 9, 0}, +{ 6, s_5_29, -1, 1, 0}, +{ 4, s_5_30, -1, 1, 0}, +{ 5, s_5_31, -1, 1, 0}, +{ 4, s_5_32, -1, 8, 0}, +{ 4, s_5_33, -1, 1, 0}, +{ 6, s_5_34, -1, 7, 0}, +{ 6, s_5_35, -1, 1, 0}, +{ 5, s_5_36, -1, 1, 0}, +{ 6, s_5_37, -1, 1, 0}, +{ 6, s_5_38, -1, 3, 0}, +{ 4, s_5_39, -1, 1, 0}, +{ 5, s_5_40, -1, 1, 0}, +{ 4, s_5_41, -1, 1, 0}, +{ 7, s_5_42, -1, 1, 0}, +{ 7, s_5_43, -1, 1, 0}, +{ 4, s_5_44, -1, 8, 0} }; static const symbol s_6_0[3] = { 'a', 'd', 'a' }; @@ -304,126 +304,126 @@ static const symbol s_6_119[3] = { 'i', 'r', 0xE1 }; static const struct among a_6[120] = { -/* 0 */ { 3, s_6_0, -1, 1, 0}, -/* 1 */ { 3, s_6_1, -1, 1, 0}, -/* 2 */ { 2, s_6_2, -1, 1, 0}, -/* 3 */ { 4, s_6_3, 2, 1, 0}, -/* 4 */ { 4, s_6_4, 2, 1, 0}, -/* 5 */ { 4, s_6_5, 2, 1, 0}, -/* 6 */ { 3, s_6_6, -1, 1, 0}, -/* 7 */ { 3, s_6_7, -1, 1, 0}, -/* 8 */ { 3, s_6_8, -1, 1, 0}, -/* 9 */ { 3, s_6_9, -1, 1, 0}, -/* 10 */ { 4, s_6_10, -1, 1, 0}, -/* 11 */ { 4, s_6_11, -1, 1, 0}, -/* 12 */ { 4, s_6_12, -1, 1, 0}, -/* 13 */ { 4, s_6_13, -1, 1, 0}, -/* 14 */ { 4, s_6_14, -1, 1, 0}, -/* 15 */ { 4, s_6_15, -1, 1, 0}, -/* 16 */ { 2, s_6_16, -1, 1, 0}, -/* 17 */ { 4, s_6_17, 16, 1, 0}, -/* 18 */ { 4, s_6_18, 16, 1, 0}, -/* 19 */ { 4, s_6_19, 16, 1, 0}, -/* 20 */ { 2, s_6_20, -1, 1, 0}, -/* 21 */ { 3, s_6_21, 20, 1, 0}, -/* 22 */ { 5, s_6_22, 21, 1, 0}, -/* 23 */ { 5, s_6_23, 21, 1, 0}, -/* 24 */ { 5, s_6_24, 21, 1, 0}, -/* 25 */ { 4, s_6_25, 20, 1, 0}, -/* 26 */ { 4, s_6_26, 20, 1, 0}, -/* 27 */ { 4, s_6_27, 20, 1, 0}, -/* 28 */ { 4, s_6_28, 20, 1, 0}, -/* 29 */ { 2, s_6_29, -1, 1, 0}, -/* 30 */ { 4, s_6_30, 29, 1, 0}, -/* 31 */ { 4, s_6_31, 29, 1, 0}, -/* 32 */ { 4, s_6_32, 29, 1, 0}, -/* 33 */ { 5, s_6_33, 29, 1, 0}, -/* 34 */ { 5, s_6_34, 29, 1, 0}, -/* 35 */ { 5, s_6_35, 29, 1, 0}, -/* 36 */ { 3, s_6_36, -1, 1, 0}, -/* 37 */ { 3, s_6_37, -1, 1, 0}, -/* 38 */ { 4, s_6_38, -1, 1, 0}, -/* 39 */ { 4, s_6_39, -1, 1, 0}, -/* 40 */ { 4, s_6_40, -1, 1, 0}, -/* 41 */ { 5, s_6_41, -1, 1, 0}, -/* 42 */ { 5, s_6_42, -1, 1, 0}, -/* 43 */ { 5, s_6_43, -1, 1, 0}, -/* 44 */ { 2, s_6_44, -1, 1, 0}, -/* 45 */ { 2, s_6_45, -1, 1, 0}, -/* 46 */ { 2, s_6_46, -1, 1, 0}, -/* 47 */ { 2, s_6_47, -1, 1, 0}, -/* 48 */ { 4, s_6_48, 47, 1, 0}, -/* 49 */ { 4, s_6_49, 47, 1, 0}, -/* 50 */ { 3, s_6_50, 47, 1, 0}, -/* 51 */ { 5, s_6_51, 50, 1, 0}, -/* 52 */ { 5, s_6_52, 50, 1, 0}, -/* 53 */ { 5, s_6_53, 50, 1, 0}, -/* 54 */ { 4, s_6_54, 47, 1, 0}, -/* 55 */ { 4, s_6_55, 47, 1, 0}, -/* 56 */ { 4, s_6_56, 47, 1, 0}, -/* 57 */ { 4, s_6_57, 47, 1, 0}, -/* 58 */ { 2, s_6_58, -1, 1, 0}, -/* 59 */ { 5, s_6_59, 58, 1, 0}, -/* 60 */ { 5, s_6_60, 58, 1, 0}, -/* 61 */ { 5, s_6_61, 58, 1, 0}, -/* 62 */ { 4, s_6_62, 58, 1, 0}, -/* 63 */ { 4, s_6_63, 58, 1, 0}, -/* 64 */ { 4, s_6_64, 58, 1, 0}, -/* 65 */ { 5, s_6_65, 58, 1, 0}, -/* 66 */ { 5, s_6_66, 58, 1, 0}, -/* 67 */ { 5, s_6_67, 58, 1, 0}, -/* 68 */ { 5, s_6_68, 58, 1, 0}, -/* 69 */ { 5, s_6_69, 58, 1, 0}, -/* 70 */ { 5, s_6_70, 58, 1, 0}, -/* 71 */ { 2, s_6_71, -1, 1, 0}, -/* 72 */ { 3, s_6_72, 71, 1, 0}, -/* 73 */ { 3, s_6_73, 71, 1, 0}, -/* 74 */ { 5, s_6_74, 73, 1, 0}, -/* 75 */ { 5, s_6_75, 73, 1, 0}, -/* 76 */ { 5, s_6_76, 73, 1, 0}, -/* 77 */ { 5, s_6_77, 73, 1, 0}, -/* 78 */ { 5, s_6_78, 73, 1, 0}, -/* 79 */ { 5, s_6_79, 73, 1, 0}, -/* 80 */ { 6, s_6_80, 73, 1, 0}, -/* 81 */ { 6, s_6_81, 73, 1, 0}, -/* 82 */ { 6, s_6_82, 73, 1, 0}, -/* 83 */ { 5, s_6_83, 73, 1, 0}, -/* 84 */ { 4, s_6_84, 73, 1, 0}, -/* 85 */ { 6, s_6_85, 84, 1, 0}, -/* 86 */ { 6, s_6_86, 84, 1, 0}, -/* 87 */ { 6, s_6_87, 84, 1, 0}, -/* 88 */ { 4, s_6_88, -1, 1, 0}, -/* 89 */ { 4, s_6_89, -1, 1, 0}, -/* 90 */ { 4, s_6_90, -1, 1, 0}, -/* 91 */ { 6, s_6_91, 90, 1, 0}, -/* 92 */ { 6, s_6_92, 90, 1, 0}, -/* 93 */ { 6, s_6_93, 90, 1, 0}, -/* 94 */ { 6, s_6_94, 90, 1, 0}, -/* 95 */ { 5, s_6_95, 90, 1, 0}, -/* 96 */ { 7, s_6_96, 95, 1, 0}, -/* 97 */ { 7, s_6_97, 95, 1, 0}, -/* 98 */ { 7, s_6_98, 95, 1, 0}, -/* 99 */ { 4, s_6_99, -1, 1, 0}, -/*100 */ { 6, s_6_100, 99, 1, 0}, -/*101 */ { 6, s_6_101, 99, 1, 0}, -/*102 */ { 6, s_6_102, 99, 1, 0}, -/*103 */ { 7, s_6_103, 99, 1, 0}, -/*104 */ { 7, s_6_104, 99, 1, 0}, -/*105 */ { 7, s_6_105, 99, 1, 0}, -/*106 */ { 4, s_6_106, -1, 1, 0}, -/*107 */ { 5, s_6_107, -1, 1, 0}, -/*108 */ { 5, s_6_108, -1, 1, 0}, -/*109 */ { 5, s_6_109, -1, 1, 0}, -/*110 */ { 4, s_6_110, -1, 1, 0}, -/*111 */ { 4, s_6_111, -1, 1, 0}, -/*112 */ { 4, s_6_112, -1, 1, 0}, -/*113 */ { 4, s_6_113, -1, 1, 0}, -/*114 */ { 2, s_6_114, -1, 1, 0}, -/*115 */ { 2, s_6_115, -1, 1, 0}, -/*116 */ { 2, s_6_116, -1, 1, 0}, -/*117 */ { 3, s_6_117, -1, 1, 0}, -/*118 */ { 3, s_6_118, -1, 1, 0}, -/*119 */ { 3, s_6_119, -1, 1, 0} +{ 3, s_6_0, -1, 1, 0}, +{ 3, s_6_1, -1, 1, 0}, +{ 2, s_6_2, -1, 1, 0}, +{ 4, s_6_3, 2, 1, 0}, +{ 4, s_6_4, 2, 1, 0}, +{ 4, s_6_5, 2, 1, 0}, +{ 3, s_6_6, -1, 1, 0}, +{ 3, s_6_7, -1, 1, 0}, +{ 3, s_6_8, -1, 1, 0}, +{ 3, s_6_9, -1, 1, 0}, +{ 4, s_6_10, -1, 1, 0}, +{ 4, s_6_11, -1, 1, 0}, +{ 4, s_6_12, -1, 1, 0}, +{ 4, s_6_13, -1, 1, 0}, +{ 4, s_6_14, -1, 1, 0}, +{ 4, s_6_15, -1, 1, 0}, +{ 2, s_6_16, -1, 1, 0}, +{ 4, s_6_17, 16, 1, 0}, +{ 4, s_6_18, 16, 1, 0}, +{ 4, s_6_19, 16, 1, 0}, +{ 2, s_6_20, -1, 1, 0}, +{ 3, s_6_21, 20, 1, 0}, +{ 5, s_6_22, 21, 1, 0}, +{ 5, s_6_23, 21, 1, 0}, +{ 5, s_6_24, 21, 1, 0}, +{ 4, s_6_25, 20, 1, 0}, +{ 4, s_6_26, 20, 1, 0}, +{ 4, s_6_27, 20, 1, 0}, +{ 4, s_6_28, 20, 1, 0}, +{ 2, s_6_29, -1, 1, 0}, +{ 4, s_6_30, 29, 1, 0}, +{ 4, s_6_31, 29, 1, 0}, +{ 4, s_6_32, 29, 1, 0}, +{ 5, s_6_33, 29, 1, 0}, +{ 5, s_6_34, 29, 1, 0}, +{ 5, s_6_35, 29, 1, 0}, +{ 3, s_6_36, -1, 1, 0}, +{ 3, s_6_37, -1, 1, 0}, +{ 4, s_6_38, -1, 1, 0}, +{ 4, s_6_39, -1, 1, 0}, +{ 4, s_6_40, -1, 1, 0}, +{ 5, s_6_41, -1, 1, 0}, +{ 5, s_6_42, -1, 1, 0}, +{ 5, s_6_43, -1, 1, 0}, +{ 2, s_6_44, -1, 1, 0}, +{ 2, s_6_45, -1, 1, 0}, +{ 2, s_6_46, -1, 1, 0}, +{ 2, s_6_47, -1, 1, 0}, +{ 4, s_6_48, 47, 1, 0}, +{ 4, s_6_49, 47, 1, 0}, +{ 3, s_6_50, 47, 1, 0}, +{ 5, s_6_51, 50, 1, 0}, +{ 5, s_6_52, 50, 1, 0}, +{ 5, s_6_53, 50, 1, 0}, +{ 4, s_6_54, 47, 1, 0}, +{ 4, s_6_55, 47, 1, 0}, +{ 4, s_6_56, 47, 1, 0}, +{ 4, s_6_57, 47, 1, 0}, +{ 2, s_6_58, -1, 1, 0}, +{ 5, s_6_59, 58, 1, 0}, +{ 5, s_6_60, 58, 1, 0}, +{ 5, s_6_61, 58, 1, 0}, +{ 4, s_6_62, 58, 1, 0}, +{ 4, s_6_63, 58, 1, 0}, +{ 4, s_6_64, 58, 1, 0}, +{ 5, s_6_65, 58, 1, 0}, +{ 5, s_6_66, 58, 1, 0}, +{ 5, s_6_67, 58, 1, 0}, +{ 5, s_6_68, 58, 1, 0}, +{ 5, s_6_69, 58, 1, 0}, +{ 5, s_6_70, 58, 1, 0}, +{ 2, s_6_71, -1, 1, 0}, +{ 3, s_6_72, 71, 1, 0}, +{ 3, s_6_73, 71, 1, 0}, +{ 5, s_6_74, 73, 1, 0}, +{ 5, s_6_75, 73, 1, 0}, +{ 5, s_6_76, 73, 1, 0}, +{ 5, s_6_77, 73, 1, 0}, +{ 5, s_6_78, 73, 1, 0}, +{ 5, s_6_79, 73, 1, 0}, +{ 6, s_6_80, 73, 1, 0}, +{ 6, s_6_81, 73, 1, 0}, +{ 6, s_6_82, 73, 1, 0}, +{ 5, s_6_83, 73, 1, 0}, +{ 4, s_6_84, 73, 1, 0}, +{ 6, s_6_85, 84, 1, 0}, +{ 6, s_6_86, 84, 1, 0}, +{ 6, s_6_87, 84, 1, 0}, +{ 4, s_6_88, -1, 1, 0}, +{ 4, s_6_89, -1, 1, 0}, +{ 4, s_6_90, -1, 1, 0}, +{ 6, s_6_91, 90, 1, 0}, +{ 6, s_6_92, 90, 1, 0}, +{ 6, s_6_93, 90, 1, 0}, +{ 6, s_6_94, 90, 1, 0}, +{ 5, s_6_95, 90, 1, 0}, +{ 7, s_6_96, 95, 1, 0}, +{ 7, s_6_97, 95, 1, 0}, +{ 7, s_6_98, 95, 1, 0}, +{ 4, s_6_99, -1, 1, 0}, +{ 6, s_6_100, 99, 1, 0}, +{ 6, s_6_101, 99, 1, 0}, +{ 6, s_6_102, 99, 1, 0}, +{ 7, s_6_103, 99, 1, 0}, +{ 7, s_6_104, 99, 1, 0}, +{ 7, s_6_105, 99, 1, 0}, +{ 4, s_6_106, -1, 1, 0}, +{ 5, s_6_107, -1, 1, 0}, +{ 5, s_6_108, -1, 1, 0}, +{ 5, s_6_109, -1, 1, 0}, +{ 4, s_6_110, -1, 1, 0}, +{ 4, s_6_111, -1, 1, 0}, +{ 4, s_6_112, -1, 1, 0}, +{ 4, s_6_113, -1, 1, 0}, +{ 2, s_6_114, -1, 1, 0}, +{ 2, s_6_115, -1, 1, 0}, +{ 2, s_6_116, -1, 1, 0}, +{ 3, s_6_117, -1, 1, 0}, +{ 3, s_6_118, -1, 1, 0}, +{ 3, s_6_119, -1, 1, 0} }; static const symbol s_7_0[1] = { 'a' }; @@ -436,13 +436,13 @@ static const symbol s_7_6[1] = { 0xF3 }; static const struct among a_7[7] = { -/* 0 */ { 1, s_7_0, -1, 1, 0}, -/* 1 */ { 1, s_7_1, -1, 1, 0}, -/* 2 */ { 1, s_7_2, -1, 1, 0}, -/* 3 */ { 2, s_7_3, -1, 1, 0}, -/* 4 */ { 1, s_7_4, -1, 1, 0}, -/* 5 */ { 1, s_7_5, -1, 1, 0}, -/* 6 */ { 1, s_7_6, -1, 1, 0} +{ 1, s_7_0, -1, 1, 0}, +{ 1, s_7_1, -1, 1, 0}, +{ 1, s_7_2, -1, 1, 0}, +{ 2, s_7_3, -1, 1, 0}, +{ 1, s_7_4, -1, 1, 0}, +{ 1, s_7_5, -1, 1, 0}, +{ 1, s_7_6, -1, 1, 0} }; static const symbol s_8_0[1] = { 'e' }; @@ -452,10 +452,10 @@ static const symbol s_8_3[1] = { 0xEA }; static const struct among a_8[4] = { -/* 0 */ { 1, s_8_0, -1, 1, 0}, -/* 1 */ { 1, s_8_1, -1, 2, 0}, -/* 2 */ { 1, s_8_2, -1, 1, 0}, -/* 3 */ { 1, s_8_3, -1, 1, 0} +{ 1, s_8_0, -1, 1, 0}, +{ 1, s_8_1, -1, 2, 0}, +{ 1, s_8_2, -1, 1, 0}, +{ 1, s_8_3, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2 }; @@ -472,30 +472,29 @@ static const symbol s_8[] = { 'a', 't' }; static const symbol s_9[] = { 'i', 'r' }; static const symbol s_10[] = { 'c' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ +static int r_prelude(struct SN_env * z) { int among_var; -/* repeat, line 36 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 37 */ - if (z->c >= z->l || (z->p[z->c + 0] != 227 && z->p[z->c + 0] != 245)) among_var = 3; else /* substring, line 37 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || (z->p[z->c + 0] != 227 && z->p[z->c + 0] != 245)) among_var = 3; else among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 37 */ - switch (among_var) { /* among, line 37 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 38 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_1); /* <-, line 39 */ + { int ret = slice_from_s(z, 2, s_1); if (ret < 0) return ret; } break; case 3: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 40 */ + z->c++; break; } continue; @@ -506,16 +505,16 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 46 */ - z->I[1] = z->l; /* $p1 = , line 47 */ - z->I[2] = z->l; /* $p2 = , line 48 */ - { int c1 = z->c; /* do, line 50 */ - { int c2 = z->c; /* or, line 52 */ - if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ - { int c3 = z->c; /* or, line 51 */ - if (out_grouping(z, g_v, 97, 250, 0)) goto lab4; /* non v, line 51 */ - { /* gopast */ /* grouping v, line 51 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping(z, g_v, 97, 250, 0)) goto lab4; + { int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab4; z->c += ret; @@ -523,8 +522,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ - { /* gopast */ /* non v, line 51 */ + if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; + { int ret = in_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab2; z->c += ret; @@ -534,10 +533,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 250, 0)) goto lab0; /* non v, line 53 */ - { int c4 = z->c; /* or, line 53 */ - if (out_grouping(z, g_v, 97, 250, 0)) goto lab6; /* non v, line 53 */ - { /* gopast */ /* grouping v, line 53 */ + if (out_grouping(z, g_v, 97, 250, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping(z, g_v, 97, 250, 0)) goto lab6; + { int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab6; z->c += ret; @@ -545,71 +544,70 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 250, 0)) goto lab0; /* grouping v, line 53 */ + if (in_grouping(z, g_v, 97, 250, 0)) goto lab0; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 53 */ + z->c++; } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 54 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 56 */ - { /* gopast */ /* grouping v, line 57 */ + { int c5 = z->c; + { int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 57 */ + { int ret = in_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 57 */ - { /* gopast */ /* grouping v, line 58 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 58 */ + { int ret = in_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 58 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 62 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 63 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else /* substring, line 63 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 63 */ - switch (among_var) { /* among, line 63 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 64 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 65 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 3: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 66 */ + z->c++; break; } continue; @@ -620,91 +618,91 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 72 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 73 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 74 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 77 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((823330 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 77 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((823330 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_5, 45); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 77 */ - switch (among_var) { /* among, line 77 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 93 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 93 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 98 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_4); /* <-, line 98 */ + { int ret = slice_from_s(z, 3, s_4); if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); /* call R2, line 102 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_5); /* <-, line 102 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 106 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_6); /* <-, line 106 */ + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } break; case 5: - { int ret = r_R1(z); /* call R1, line 110 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ - z->ket = z->c; /* [, line 112 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } /* substring, line 112 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } among_var = find_among_b(z, a_2, 4); if (!(among_var)) { z->c = z->l - m1; goto lab0; } - z->bra = z->c; /* ], line 112 */ - { int ret = r_R2(z); /* call R2, line 112 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 112 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - switch (among_var) { /* among, line 112 */ + switch (among_var) { case 1: - z->ket = z->c; /* [, line 113 */ - if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m1; goto lab0; } /* literal, line 113 */ - z->bra = z->c; /* ], line 113 */ - { int ret = r_R2(z); /* call R2, line 113 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 113 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -714,22 +712,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 6: - { int ret = r_R2(z); /* call R2, line 122 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 122 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 123 */ - z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m2; goto lab1; } /* substring, line 124 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m2; goto lab1; } if (!(find_among_b(z, a_3, 3))) { z->c = z->l - m2; goto lab1; } - z->bra = z->c; /* ], line 124 */ - { int ret = r_R2(z); /* call R2, line 127 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 127 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: @@ -737,22 +735,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 7: - { int ret = r_R2(z); /* call R2, line 134 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ - z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } - z->bra = z->c; /* ], line 136 */ - { int ret = r_R2(z); /* call R2, line 139 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab2; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: @@ -760,21 +758,21 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 146 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 146 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 147 */ - z->ket = z->c; /* [, line 148 */ - if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m4; goto lab3; } /* literal, line 148 */ - z->bra = z->c; /* ], line 148 */ - { int ret = r_R2(z); /* call R2, line 148 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m4; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 148 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab3: @@ -782,12 +780,12 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = r_RV(z); /* call RV, line 153 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 153 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; - { int ret = slice_from_s(z, 2, s_9); /* <-, line 154 */ + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; @@ -795,15 +793,15 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 159 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 160 */ - if (!(find_among_b(z, a_6, 120))) { z->lb = mlimit1; return 0; } /* substring, line 160 */ - z->bra = z->c; /* ], line 160 */ - { int ret = slice_del(z); /* delete, line 179 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (!(find_among_b(z, a_6, 120))) { z->lb = mlimit1; return 0; } + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; @@ -811,65 +809,65 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 184 */ - if (!(find_among_b(z, a_7, 7))) return 0; /* substring, line 184 */ - z->bra = z->c; /* ], line 184 */ - { int ret = r_RV(z); /* call RV, line 187 */ +static int r_residual_suffix(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_7, 7))) return 0; + z->bra = z->c; + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 187 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_residual_form(struct SN_env * z) { /* backwardmode */ +static int r_residual_form(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 192 */ - among_var = find_among_b(z, a_8, 4); /* substring, line 192 */ + z->ket = z->c; + among_var = find_among_b(z, a_8, 4); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 192 */ - switch (among_var) { /* among, line 192 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 194 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 194 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 194 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 194 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab1; /* literal, line 194 */ + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab1; z->c--; - z->bra = z->c; /* ], line 194 */ - { int m_test2 = z->l - z->c; /* test, line 194 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'g') goto lab1; /* literal, line 194 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'g') goto lab1; z->c--; z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 195 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; z->c--; - z->bra = z->c; /* ], line 195 */ - { int m_test3 = z->l - z->c; /* test, line 195 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'c') return 0; /* literal, line 195 */ + z->bra = z->c; + { int m_test3 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') return 0; z->c--; z->c = z->l - m_test3; } } lab0: - { int ret = r_RV(z); /* call RV, line 195 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 195 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 196 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; @@ -877,52 +875,52 @@ static int r_residual_form(struct SN_env * z) { /* backwardmode */ return 1; } -extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 202 */ - { int ret = r_prelude(z); /* call prelude, line 202 */ +extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 203 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 203 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 204 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 205 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 209 */ - { int m4 = z->l - z->c; (void)m4; /* and, line 207 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 206 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 206 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab3; lab4: z->c = z->l - m5; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 206 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: z->c = z->l - m4; - { int m6 = z->l - z->c; (void)m6; /* do, line 207 */ - z->ket = z->c; /* [, line 207 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab5; /* literal, line 207 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab5; z->c--; - z->bra = z->c; /* ], line 207 */ - { int m_test7 = z->l - z->c; /* test, line 207 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab5; /* literal, line 207 */ + z->bra = z->c; + { int m_test7 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab5; z->c--; z->c = z->l - m_test7; } - { int ret = r_RV(z); /* call RV, line 207 */ + { int ret = r_RV(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 207 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab5: @@ -932,7 +930,7 @@ extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = z->l - m3; - { int ret = r_residual_suffix(z); /* call residual_suffix, line 209 */ + { int ret = r_residual_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -941,15 +939,15 @@ extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m8 = z->l - z->c; (void)m8; /* do, line 211 */ - { int ret = r_residual_form(z); /* call residual_form, line 211 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_residual_form(z); if (ret < 0) return ret; } z->c = z->l - m8; } z->c = z->lb; - { int c9 = z->c; /* do, line 213 */ - { int ret = r_postlude(z); /* call postlude, line 213 */ + { int c9 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c9; @@ -957,7 +955,7 @@ extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * portuguese_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * portuguese_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void portuguese_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c index e77aadda6a39..825e68f21edf 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -39,12 +39,12 @@ static const symbol s_0_5[1] = { 0xFA }; static const struct among a_0[6] = { -/* 0 */ { 0, 0, -1, 6, 0}, -/* 1 */ { 1, s_0_1, 0, 1, 0}, -/* 2 */ { 1, s_0_2, 0, 2, 0}, -/* 3 */ { 1, s_0_3, 0, 3, 0}, -/* 4 */ { 1, s_0_4, 0, 4, 0}, -/* 5 */ { 1, s_0_5, 0, 5, 0} +{ 0, 0, -1, 6, 0}, +{ 1, s_0_1, 0, 1, 0}, +{ 1, s_0_2, 0, 2, 0}, +{ 1, s_0_3, 0, 3, 0}, +{ 1, s_0_4, 0, 4, 0}, +{ 1, s_0_5, 0, 5, 0} }; static const symbol s_1_0[2] = { 'l', 'a' }; @@ -63,19 +63,19 @@ static const symbol s_1_12[3] = { 'n', 'o', 's' }; static const struct among a_1[13] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 4, s_1_1, 0, -1, 0}, -/* 2 */ { 2, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0}, -/* 4 */ { 2, s_1_4, -1, -1, 0}, -/* 5 */ { 2, s_1_5, -1, -1, 0}, -/* 6 */ { 4, s_1_6, 5, -1, 0}, -/* 7 */ { 3, s_1_7, -1, -1, 0}, -/* 8 */ { 5, s_1_8, 7, -1, 0}, -/* 9 */ { 3, s_1_9, -1, -1, 0}, -/* 10 */ { 3, s_1_10, -1, -1, 0}, -/* 11 */ { 5, s_1_11, 10, -1, 0}, -/* 12 */ { 3, s_1_12, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 4, s_1_1, 0, -1, 0}, +{ 2, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0}, +{ 2, s_1_4, -1, -1, 0}, +{ 2, s_1_5, -1, -1, 0}, +{ 4, s_1_6, 5, -1, 0}, +{ 3, s_1_7, -1, -1, 0}, +{ 5, s_1_8, 7, -1, 0}, +{ 3, s_1_9, -1, -1, 0}, +{ 3, s_1_10, -1, -1, 0}, +{ 5, s_1_11, 10, -1, 0}, +{ 3, s_1_12, -1, -1, 0} }; static const symbol s_2_0[4] = { 'a', 'n', 'd', 'o' }; @@ -92,17 +92,17 @@ static const symbol s_2_10[2] = { 0xED, 'r' }; static const struct among a_2[11] = { -/* 0 */ { 4, s_2_0, -1, 6, 0}, -/* 1 */ { 5, s_2_1, -1, 6, 0}, -/* 2 */ { 5, s_2_2, -1, 7, 0}, -/* 3 */ { 4, s_2_3, -1, 2, 0}, -/* 4 */ { 5, s_2_4, -1, 1, 0}, -/* 5 */ { 2, s_2_5, -1, 6, 0}, -/* 6 */ { 2, s_2_6, -1, 6, 0}, -/* 7 */ { 2, s_2_7, -1, 6, 0}, -/* 8 */ { 2, s_2_8, -1, 3, 0}, -/* 9 */ { 2, s_2_9, -1, 4, 0}, -/* 10 */ { 2, s_2_10, -1, 5, 0} +{ 4, s_2_0, -1, 6, 0}, +{ 5, s_2_1, -1, 6, 0}, +{ 5, s_2_2, -1, 7, 0}, +{ 4, s_2_3, -1, 2, 0}, +{ 5, s_2_4, -1, 1, 0}, +{ 2, s_2_5, -1, 6, 0}, +{ 2, s_2_6, -1, 6, 0}, +{ 2, s_2_7, -1, 6, 0}, +{ 2, s_2_8, -1, 3, 0}, +{ 2, s_2_9, -1, 4, 0}, +{ 2, s_2_10, -1, 5, 0} }; static const symbol s_3_0[2] = { 'i', 'c' }; @@ -112,10 +112,10 @@ static const symbol s_3_3[2] = { 'i', 'v' }; static const struct among a_3[4] = { -/* 0 */ { 2, s_3_0, -1, -1, 0}, -/* 1 */ { 2, s_3_1, -1, -1, 0}, -/* 2 */ { 2, s_3_2, -1, -1, 0}, -/* 3 */ { 2, s_3_3, -1, 1, 0} +{ 2, s_3_0, -1, -1, 0}, +{ 2, s_3_1, -1, -1, 0}, +{ 2, s_3_2, -1, -1, 0}, +{ 2, s_3_3, -1, 1, 0} }; static const symbol s_4_0[4] = { 'a', 'b', 'l', 'e' }; @@ -124,9 +124,9 @@ static const symbol s_4_2[4] = { 'a', 'n', 't', 'e' }; static const struct among a_4[3] = { -/* 0 */ { 4, s_4_0, -1, 1, 0}, -/* 1 */ { 4, s_4_1, -1, 1, 0}, -/* 2 */ { 4, s_4_2, -1, 1, 0} +{ 4, s_4_0, -1, 1, 0}, +{ 4, s_4_1, -1, 1, 0}, +{ 4, s_4_2, -1, 1, 0} }; static const symbol s_5_0[2] = { 'i', 'c' }; @@ -135,9 +135,9 @@ static const symbol s_5_2[2] = { 'i', 'v' }; static const struct among a_5[3] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 4, s_5_1, -1, 1, 0}, -/* 2 */ { 2, s_5_2, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 4, s_5_1, -1, 1, 0}, +{ 2, s_5_2, -1, 1, 0} }; static const symbol s_6_0[3] = { 'i', 'c', 'a' }; @@ -189,52 +189,52 @@ static const symbol s_6_45[4] = { 'i', 'v', 'o', 's' }; static const struct among a_6[46] = { -/* 0 */ { 3, s_6_0, -1, 1, 0}, -/* 1 */ { 5, s_6_1, -1, 2, 0}, -/* 2 */ { 5, s_6_2, -1, 5, 0}, -/* 3 */ { 5, s_6_3, -1, 2, 0}, -/* 4 */ { 3, s_6_4, -1, 1, 0}, -/* 5 */ { 4, s_6_5, -1, 1, 0}, -/* 6 */ { 3, s_6_6, -1, 9, 0}, -/* 7 */ { 4, s_6_7, -1, 1, 0}, -/* 8 */ { 5, s_6_8, -1, 3, 0}, -/* 9 */ { 4, s_6_9, -1, 8, 0}, -/* 10 */ { 4, s_6_10, -1, 1, 0}, -/* 11 */ { 4, s_6_11, -1, 1, 0}, -/* 12 */ { 4, s_6_12, -1, 2, 0}, -/* 13 */ { 5, s_6_13, -1, 7, 0}, -/* 14 */ { 6, s_6_14, 13, 6, 0}, -/* 15 */ { 5, s_6_15, -1, 2, 0}, -/* 16 */ { 5, s_6_16, -1, 4, 0}, -/* 17 */ { 3, s_6_17, -1, 1, 0}, -/* 18 */ { 4, s_6_18, -1, 1, 0}, -/* 19 */ { 3, s_6_19, -1, 1, 0}, -/* 20 */ { 7, s_6_20, -1, 1, 0}, -/* 21 */ { 7, s_6_21, -1, 1, 0}, -/* 22 */ { 3, s_6_22, -1, 9, 0}, -/* 23 */ { 4, s_6_23, -1, 2, 0}, -/* 24 */ { 4, s_6_24, -1, 1, 0}, -/* 25 */ { 6, s_6_25, -1, 2, 0}, -/* 26 */ { 6, s_6_26, -1, 5, 0}, -/* 27 */ { 6, s_6_27, -1, 2, 0}, -/* 28 */ { 4, s_6_28, -1, 1, 0}, -/* 29 */ { 5, s_6_29, -1, 1, 0}, -/* 30 */ { 4, s_6_30, -1, 9, 0}, -/* 31 */ { 5, s_6_31, -1, 1, 0}, -/* 32 */ { 6, s_6_32, -1, 3, 0}, -/* 33 */ { 6, s_6_33, -1, 8, 0}, -/* 34 */ { 5, s_6_34, -1, 1, 0}, -/* 35 */ { 5, s_6_35, -1, 1, 0}, -/* 36 */ { 7, s_6_36, -1, 2, 0}, -/* 37 */ { 7, s_6_37, -1, 4, 0}, -/* 38 */ { 6, s_6_38, -1, 2, 0}, -/* 39 */ { 5, s_6_39, -1, 2, 0}, -/* 40 */ { 4, s_6_40, -1, 1, 0}, -/* 41 */ { 5, s_6_41, -1, 1, 0}, -/* 42 */ { 4, s_6_42, -1, 1, 0}, -/* 43 */ { 8, s_6_43, -1, 1, 0}, -/* 44 */ { 8, s_6_44, -1, 1, 0}, -/* 45 */ { 4, s_6_45, -1, 9, 0} +{ 3, s_6_0, -1, 1, 0}, +{ 5, s_6_1, -1, 2, 0}, +{ 5, s_6_2, -1, 5, 0}, +{ 5, s_6_3, -1, 2, 0}, +{ 3, s_6_4, -1, 1, 0}, +{ 4, s_6_5, -1, 1, 0}, +{ 3, s_6_6, -1, 9, 0}, +{ 4, s_6_7, -1, 1, 0}, +{ 5, s_6_8, -1, 3, 0}, +{ 4, s_6_9, -1, 8, 0}, +{ 4, s_6_10, -1, 1, 0}, +{ 4, s_6_11, -1, 1, 0}, +{ 4, s_6_12, -1, 2, 0}, +{ 5, s_6_13, -1, 7, 0}, +{ 6, s_6_14, 13, 6, 0}, +{ 5, s_6_15, -1, 2, 0}, +{ 5, s_6_16, -1, 4, 0}, +{ 3, s_6_17, -1, 1, 0}, +{ 4, s_6_18, -1, 1, 0}, +{ 3, s_6_19, -1, 1, 0}, +{ 7, s_6_20, -1, 1, 0}, +{ 7, s_6_21, -1, 1, 0}, +{ 3, s_6_22, -1, 9, 0}, +{ 4, s_6_23, -1, 2, 0}, +{ 4, s_6_24, -1, 1, 0}, +{ 6, s_6_25, -1, 2, 0}, +{ 6, s_6_26, -1, 5, 0}, +{ 6, s_6_27, -1, 2, 0}, +{ 4, s_6_28, -1, 1, 0}, +{ 5, s_6_29, -1, 1, 0}, +{ 4, s_6_30, -1, 9, 0}, +{ 5, s_6_31, -1, 1, 0}, +{ 6, s_6_32, -1, 3, 0}, +{ 6, s_6_33, -1, 8, 0}, +{ 5, s_6_34, -1, 1, 0}, +{ 5, s_6_35, -1, 1, 0}, +{ 7, s_6_36, -1, 2, 0}, +{ 7, s_6_37, -1, 4, 0}, +{ 6, s_6_38, -1, 2, 0}, +{ 5, s_6_39, -1, 2, 0}, +{ 4, s_6_40, -1, 1, 0}, +{ 5, s_6_41, -1, 1, 0}, +{ 4, s_6_42, -1, 1, 0}, +{ 8, s_6_43, -1, 1, 0}, +{ 8, s_6_44, -1, 1, 0}, +{ 4, s_6_45, -1, 9, 0} }; static const symbol s_7_0[2] = { 'y', 'a' }; @@ -252,18 +252,18 @@ static const symbol s_7_11[2] = { 'y', 0xF3 }; static const struct among a_7[12] = { -/* 0 */ { 2, s_7_0, -1, 1, 0}, -/* 1 */ { 2, s_7_1, -1, 1, 0}, -/* 2 */ { 3, s_7_2, -1, 1, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 5, s_7_4, -1, 1, 0}, -/* 5 */ { 5, s_7_5, -1, 1, 0}, -/* 6 */ { 2, s_7_6, -1, 1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 3, s_7_8, -1, 1, 0}, -/* 9 */ { 4, s_7_9, -1, 1, 0}, -/* 10 */ { 5, s_7_10, -1, 1, 0}, -/* 11 */ { 2, s_7_11, -1, 1, 0} +{ 2, s_7_0, -1, 1, 0}, +{ 2, s_7_1, -1, 1, 0}, +{ 3, s_7_2, -1, 1, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 5, s_7_4, -1, 1, 0}, +{ 5, s_7_5, -1, 1, 0}, +{ 2, s_7_6, -1, 1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 3, s_7_8, -1, 1, 0}, +{ 4, s_7_9, -1, 1, 0}, +{ 5, s_7_10, -1, 1, 0}, +{ 2, s_7_11, -1, 1, 0} }; static const symbol s_8_0[3] = { 'a', 'b', 'a' }; @@ -365,102 +365,102 @@ static const symbol s_8_95[2] = { 'i', 0xF3 }; static const struct among a_8[96] = { -/* 0 */ { 3, s_8_0, -1, 2, 0}, -/* 1 */ { 3, s_8_1, -1, 2, 0}, -/* 2 */ { 3, s_8_2, -1, 2, 0}, -/* 3 */ { 3, s_8_3, -1, 2, 0}, -/* 4 */ { 4, s_8_4, -1, 2, 0}, -/* 5 */ { 2, s_8_5, -1, 2, 0}, -/* 6 */ { 4, s_8_6, 5, 2, 0}, -/* 7 */ { 4, s_8_7, 5, 2, 0}, -/* 8 */ { 4, s_8_8, 5, 2, 0}, -/* 9 */ { 2, s_8_9, -1, 2, 0}, -/* 10 */ { 2, s_8_10, -1, 2, 0}, -/* 11 */ { 2, s_8_11, -1, 2, 0}, -/* 12 */ { 3, s_8_12, -1, 2, 0}, -/* 13 */ { 4, s_8_13, -1, 2, 0}, -/* 14 */ { 4, s_8_14, -1, 2, 0}, -/* 15 */ { 4, s_8_15, -1, 2, 0}, -/* 16 */ { 2, s_8_16, -1, 2, 0}, -/* 17 */ { 4, s_8_17, 16, 2, 0}, -/* 18 */ { 4, s_8_18, 16, 2, 0}, -/* 19 */ { 5, s_8_19, 16, 2, 0}, -/* 20 */ { 3, s_8_20, 16, 2, 0}, -/* 21 */ { 5, s_8_21, 20, 2, 0}, -/* 22 */ { 5, s_8_22, 20, 2, 0}, -/* 23 */ { 5, s_8_23, 20, 2, 0}, -/* 24 */ { 2, s_8_24, -1, 1, 0}, -/* 25 */ { 4, s_8_25, 24, 2, 0}, -/* 26 */ { 5, s_8_26, 24, 2, 0}, -/* 27 */ { 4, s_8_27, -1, 2, 0}, -/* 28 */ { 5, s_8_28, -1, 2, 0}, -/* 29 */ { 4, s_8_29, -1, 2, 0}, -/* 30 */ { 4, s_8_30, -1, 2, 0}, -/* 31 */ { 4, s_8_31, -1, 2, 0}, -/* 32 */ { 3, s_8_32, -1, 2, 0}, -/* 33 */ { 3, s_8_33, -1, 2, 0}, -/* 34 */ { 4, s_8_34, -1, 2, 0}, -/* 35 */ { 5, s_8_35, -1, 2, 0}, -/* 36 */ { 2, s_8_36, -1, 2, 0}, -/* 37 */ { 2, s_8_37, -1, 2, 0}, -/* 38 */ { 2, s_8_38, -1, 2, 0}, -/* 39 */ { 2, s_8_39, -1, 2, 0}, -/* 40 */ { 4, s_8_40, 39, 2, 0}, -/* 41 */ { 4, s_8_41, 39, 2, 0}, -/* 42 */ { 4, s_8_42, 39, 2, 0}, -/* 43 */ { 4, s_8_43, 39, 2, 0}, -/* 44 */ { 5, s_8_44, 39, 2, 0}, -/* 45 */ { 3, s_8_45, 39, 2, 0}, -/* 46 */ { 5, s_8_46, 45, 2, 0}, -/* 47 */ { 5, s_8_47, 45, 2, 0}, -/* 48 */ { 5, s_8_48, 45, 2, 0}, -/* 49 */ { 2, s_8_49, -1, 1, 0}, -/* 50 */ { 4, s_8_50, 49, 2, 0}, -/* 51 */ { 5, s_8_51, 49, 2, 0}, -/* 52 */ { 5, s_8_52, -1, 2, 0}, -/* 53 */ { 5, s_8_53, -1, 2, 0}, -/* 54 */ { 6, s_8_54, -1, 2, 0}, -/* 55 */ { 4, s_8_55, -1, 2, 0}, -/* 56 */ { 6, s_8_56, 55, 2, 0}, -/* 57 */ { 6, s_8_57, 55, 2, 0}, -/* 58 */ { 6, s_8_58, 55, 2, 0}, -/* 59 */ { 5, s_8_59, -1, 2, 0}, -/* 60 */ { 6, s_8_60, -1, 2, 0}, -/* 61 */ { 6, s_8_61, -1, 2, 0}, -/* 62 */ { 6, s_8_62, -1, 2, 0}, -/* 63 */ { 3, s_8_63, -1, 2, 0}, -/* 64 */ { 3, s_8_64, -1, 1, 0}, -/* 65 */ { 5, s_8_65, 64, 2, 0}, -/* 66 */ { 5, s_8_66, 64, 2, 0}, -/* 67 */ { 5, s_8_67, 64, 2, 0}, -/* 68 */ { 4, s_8_68, -1, 2, 0}, -/* 69 */ { 4, s_8_69, -1, 2, 0}, -/* 70 */ { 4, s_8_70, -1, 2, 0}, -/* 71 */ { 6, s_8_71, 70, 2, 0}, -/* 72 */ { 6, s_8_72, 70, 2, 0}, -/* 73 */ { 7, s_8_73, 70, 2, 0}, -/* 74 */ { 5, s_8_74, 70, 2, 0}, -/* 75 */ { 7, s_8_75, 74, 2, 0}, -/* 76 */ { 7, s_8_76, 74, 2, 0}, -/* 77 */ { 7, s_8_77, 74, 2, 0}, -/* 78 */ { 4, s_8_78, -1, 1, 0}, -/* 79 */ { 6, s_8_79, 78, 2, 0}, -/* 80 */ { 6, s_8_80, 78, 2, 0}, -/* 81 */ { 6, s_8_81, 78, 2, 0}, -/* 82 */ { 6, s_8_82, 78, 2, 0}, -/* 83 */ { 7, s_8_83, 78, 2, 0}, -/* 84 */ { 4, s_8_84, -1, 2, 0}, -/* 85 */ { 4, s_8_85, -1, 2, 0}, -/* 86 */ { 4, s_8_86, -1, 2, 0}, -/* 87 */ { 4, s_8_87, -1, 2, 0}, -/* 88 */ { 2, s_8_88, -1, 2, 0}, -/* 89 */ { 3, s_8_89, -1, 2, 0}, -/* 90 */ { 3, s_8_90, -1, 2, 0}, -/* 91 */ { 3, s_8_91, -1, 2, 0}, -/* 92 */ { 3, s_8_92, -1, 2, 0}, -/* 93 */ { 3, s_8_93, -1, 2, 0}, -/* 94 */ { 3, s_8_94, -1, 2, 0}, -/* 95 */ { 2, s_8_95, -1, 2, 0} +{ 3, s_8_0, -1, 2, 0}, +{ 3, s_8_1, -1, 2, 0}, +{ 3, s_8_2, -1, 2, 0}, +{ 3, s_8_3, -1, 2, 0}, +{ 4, s_8_4, -1, 2, 0}, +{ 2, s_8_5, -1, 2, 0}, +{ 4, s_8_6, 5, 2, 0}, +{ 4, s_8_7, 5, 2, 0}, +{ 4, s_8_8, 5, 2, 0}, +{ 2, s_8_9, -1, 2, 0}, +{ 2, s_8_10, -1, 2, 0}, +{ 2, s_8_11, -1, 2, 0}, +{ 3, s_8_12, -1, 2, 0}, +{ 4, s_8_13, -1, 2, 0}, +{ 4, s_8_14, -1, 2, 0}, +{ 4, s_8_15, -1, 2, 0}, +{ 2, s_8_16, -1, 2, 0}, +{ 4, s_8_17, 16, 2, 0}, +{ 4, s_8_18, 16, 2, 0}, +{ 5, s_8_19, 16, 2, 0}, +{ 3, s_8_20, 16, 2, 0}, +{ 5, s_8_21, 20, 2, 0}, +{ 5, s_8_22, 20, 2, 0}, +{ 5, s_8_23, 20, 2, 0}, +{ 2, s_8_24, -1, 1, 0}, +{ 4, s_8_25, 24, 2, 0}, +{ 5, s_8_26, 24, 2, 0}, +{ 4, s_8_27, -1, 2, 0}, +{ 5, s_8_28, -1, 2, 0}, +{ 4, s_8_29, -1, 2, 0}, +{ 4, s_8_30, -1, 2, 0}, +{ 4, s_8_31, -1, 2, 0}, +{ 3, s_8_32, -1, 2, 0}, +{ 3, s_8_33, -1, 2, 0}, +{ 4, s_8_34, -1, 2, 0}, +{ 5, s_8_35, -1, 2, 0}, +{ 2, s_8_36, -1, 2, 0}, +{ 2, s_8_37, -1, 2, 0}, +{ 2, s_8_38, -1, 2, 0}, +{ 2, s_8_39, -1, 2, 0}, +{ 4, s_8_40, 39, 2, 0}, +{ 4, s_8_41, 39, 2, 0}, +{ 4, s_8_42, 39, 2, 0}, +{ 4, s_8_43, 39, 2, 0}, +{ 5, s_8_44, 39, 2, 0}, +{ 3, s_8_45, 39, 2, 0}, +{ 5, s_8_46, 45, 2, 0}, +{ 5, s_8_47, 45, 2, 0}, +{ 5, s_8_48, 45, 2, 0}, +{ 2, s_8_49, -1, 1, 0}, +{ 4, s_8_50, 49, 2, 0}, +{ 5, s_8_51, 49, 2, 0}, +{ 5, s_8_52, -1, 2, 0}, +{ 5, s_8_53, -1, 2, 0}, +{ 6, s_8_54, -1, 2, 0}, +{ 4, s_8_55, -1, 2, 0}, +{ 6, s_8_56, 55, 2, 0}, +{ 6, s_8_57, 55, 2, 0}, +{ 6, s_8_58, 55, 2, 0}, +{ 5, s_8_59, -1, 2, 0}, +{ 6, s_8_60, -1, 2, 0}, +{ 6, s_8_61, -1, 2, 0}, +{ 6, s_8_62, -1, 2, 0}, +{ 3, s_8_63, -1, 2, 0}, +{ 3, s_8_64, -1, 1, 0}, +{ 5, s_8_65, 64, 2, 0}, +{ 5, s_8_66, 64, 2, 0}, +{ 5, s_8_67, 64, 2, 0}, +{ 4, s_8_68, -1, 2, 0}, +{ 4, s_8_69, -1, 2, 0}, +{ 4, s_8_70, -1, 2, 0}, +{ 6, s_8_71, 70, 2, 0}, +{ 6, s_8_72, 70, 2, 0}, +{ 7, s_8_73, 70, 2, 0}, +{ 5, s_8_74, 70, 2, 0}, +{ 7, s_8_75, 74, 2, 0}, +{ 7, s_8_76, 74, 2, 0}, +{ 7, s_8_77, 74, 2, 0}, +{ 4, s_8_78, -1, 1, 0}, +{ 6, s_8_79, 78, 2, 0}, +{ 6, s_8_80, 78, 2, 0}, +{ 6, s_8_81, 78, 2, 0}, +{ 6, s_8_82, 78, 2, 0}, +{ 7, s_8_83, 78, 2, 0}, +{ 4, s_8_84, -1, 2, 0}, +{ 4, s_8_85, -1, 2, 0}, +{ 4, s_8_86, -1, 2, 0}, +{ 4, s_8_87, -1, 2, 0}, +{ 2, s_8_88, -1, 2, 0}, +{ 3, s_8_89, -1, 2, 0}, +{ 3, s_8_90, -1, 2, 0}, +{ 3, s_8_91, -1, 2, 0}, +{ 3, s_8_92, -1, 2, 0}, +{ 3, s_8_93, -1, 2, 0}, +{ 3, s_8_94, -1, 2, 0}, +{ 2, s_8_95, -1, 2, 0} }; static const symbol s_9_0[1] = { 'a' }; @@ -474,14 +474,14 @@ static const symbol s_9_7[1] = { 0xF3 }; static const struct among a_9[8] = { -/* 0 */ { 1, s_9_0, -1, 1, 0}, -/* 1 */ { 1, s_9_1, -1, 2, 0}, -/* 2 */ { 1, s_9_2, -1, 1, 0}, -/* 3 */ { 2, s_9_3, -1, 1, 0}, -/* 4 */ { 1, s_9_4, -1, 1, 0}, -/* 5 */ { 1, s_9_5, -1, 2, 0}, -/* 6 */ { 1, s_9_6, -1, 1, 0}, -/* 7 */ { 1, s_9_7, -1, 1, 0} +{ 1, s_9_0, -1, 1, 0}, +{ 1, s_9_1, -1, 2, 0}, +{ 1, s_9_2, -1, 1, 0}, +{ 2, s_9_3, -1, 1, 0}, +{ 1, s_9_4, -1, 1, 0}, +{ 1, s_9_5, -1, 2, 0}, +{ 1, s_9_6, -1, 1, 0}, +{ 1, s_9_7, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 }; @@ -503,16 +503,16 @@ static const symbol s_13[] = { 'e', 'n', 't', 'e' }; static const symbol s_14[] = { 'a', 't' }; static const symbol s_15[] = { 'a', 't' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 33 */ - z->I[1] = z->l; /* $p1 = , line 34 */ - z->I[2] = z->l; /* $p2 = , line 35 */ - { int c1 = z->c; /* do, line 37 */ - { int c2 = z->c; /* or, line 39 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ - { int c3 = z->c; /* or, line 38 */ - if (out_grouping(z, g_v, 97, 252, 0)) goto lab4; /* non v, line 38 */ - { /* gopast */ /* grouping v, line 38 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping(z, g_v, 97, 252, 0)) goto lab4; + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab4; z->c += ret; @@ -520,8 +520,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ - { /* gopast */ /* non v, line 38 */ + if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; + { int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab2; z->c += ret; @@ -531,10 +531,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 252, 0)) goto lab0; /* non v, line 40 */ - { int c4 = z->c; /* or, line 40 */ - if (out_grouping(z, g_v, 97, 252, 0)) goto lab6; /* non v, line 40 */ - { /* gopast */ /* grouping v, line 40 */ + if (out_grouping(z, g_v, 97, 252, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping(z, g_v, 97, 252, 0)) goto lab6; + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab6; z->c += ret; @@ -542,86 +542,85 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 252, 0)) goto lab0; /* grouping v, line 40 */ + if (in_grouping(z, g_v, 97, 252, 0)) goto lab0; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 40 */ + z->c++; } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 41 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 43 */ - { /* gopast */ /* grouping v, line 44 */ + { int c5 = z->c; + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 44 */ + { int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 44 */ - { /* gopast */ /* grouping v, line 45 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 45 */ + { int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 45 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 49 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 50 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((67641858 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else /* substring, line 50 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((67641858 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else among_var = find_among(z, a_0, 6); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 50 */ - switch (among_var) { /* among, line 50 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 51 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 52 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 53 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 54 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 55 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 6: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 57 */ + z->c++; break; } continue; @@ -632,73 +631,73 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 63 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 64 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 65 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ +static int r_attached_pronoun(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 68 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_1, 13))) return 0; - z->bra = z->c; /* ], line 68 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* substring, line 72 */ + z->bra = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; among_var = find_among_b(z, a_2, 11); if (!(among_var)) return 0; - { int ret = r_RV(z); /* call RV, line 72 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 72 */ + switch (among_var) { case 1: - z->bra = z->c; /* ], line 73 */ - { int ret = slice_from_s(z, 5, s_5); /* <-, line 73 */ + z->bra = z->c; + { int ret = slice_from_s(z, 5, s_5); if (ret < 0) return ret; } break; case 2: - z->bra = z->c; /* ], line 74 */ - { int ret = slice_from_s(z, 4, s_6); /* <-, line 74 */ + z->bra = z->c; + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } break; case 3: - z->bra = z->c; /* ], line 75 */ - { int ret = slice_from_s(z, 2, s_7); /* <-, line 75 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_7); if (ret < 0) return ret; } break; case 4: - z->bra = z->c; /* ], line 76 */ - { int ret = slice_from_s(z, 2, s_8); /* <-, line 76 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_8); if (ret < 0) return ret; } break; case 5: - z->bra = z->c; /* ], line 77 */ - { int ret = slice_from_s(z, 2, s_9); /* <-, line 77 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; case 6: - { int ret = slice_del(z); /* delete, line 81 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 7: - if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 82 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 82 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -706,38 +705,38 @@ static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 87 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_6, 46); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 87 */ - switch (among_var) { /* among, line 87 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 99 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 99 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 105 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 105 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 106 */ - z->ket = z->c; /* [, line 106 */ - if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m1; goto lab0; } /* literal, line 106 */ - z->bra = z->c; /* ], line 106 */ - { int ret = r_R2(z); /* call R2, line 106 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -745,59 +744,59 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - { int ret = r_R2(z); /* call R2, line 111 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_11); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_11); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 115 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_12); /* <-, line 115 */ + { int ret = slice_from_s(z, 1, s_12); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 119 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_13); /* <-, line 119 */ + { int ret = slice_from_s(z, 4, s_13); if (ret < 0) return ret; } break; case 6: - { int ret = r_R1(z); /* call R1, line 123 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 123 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 124 */ - z->ket = z->c; /* [, line 125 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 125 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } among_var = find_among_b(z, a_3, 4); if (!(among_var)) { z->c = z->l - m2; goto lab1; } - z->bra = z->c; /* ], line 125 */ - { int ret = r_R2(z); /* call R2, line 125 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - switch (among_var) { /* among, line 125 */ + switch (among_var) { case 1: - z->ket = z->c; /* [, line 126 */ - if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m2; goto lab1; } /* literal, line 126 */ - z->bra = z->c; /* ], line 126 */ - { int ret = r_R2(z); /* call R2, line 126 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m2; goto lab1; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 126 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -807,22 +806,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 7: - { int ret = r_R2(z); /* call R2, line 135 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 135 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 136 */ - z->ket = z->c; /* [, line 137 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m3; goto lab2; } /* substring, line 137 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m3; goto lab2; } if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } - z->bra = z->c; /* ], line 137 */ - { int ret = r_R2(z); /* call R2, line 140 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab2; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 140 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: @@ -830,22 +829,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 147 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 147 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 148 */ - z->ket = z->c; /* [, line 149 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m4; goto lab3; } /* substring, line 149 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m4; goto lab3; } if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m4; goto lab3; } - z->bra = z->c; /* ], line 149 */ - { int ret = r_R2(z); /* call R2, line 152 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab3: @@ -853,21 +852,21 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = r_R2(z); /* call R2, line 159 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 159 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* try, line 160 */ - z->ket = z->c; /* [, line 161 */ - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m5; goto lab4; } /* literal, line 161 */ - z->bra = z->c; /* ], line 161 */ - { int ret = r_R2(z); /* call R2, line 161 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m5; goto lab4; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 161 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab4: @@ -878,56 +877,56 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_y_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_y_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 168 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 168 */ - if (!(find_among_b(z, a_7, 12))) { z->lb = mlimit1; return 0; } /* substring, line 168 */ - z->bra = z->c; /* ], line 168 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (!(find_among_b(z, a_7, 12))) { z->lb = mlimit1; return 0; } + z->bra = z->c; z->lb = mlimit1; } - if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 171 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 171 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 176 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 176 */ - among_var = find_among_b(z, a_8, 96); /* substring, line 176 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + among_var = find_among_b(z, a_8, 96); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 176 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 176 */ + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* try, line 179 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m2; goto lab0; } z->c--; - { int m_test3 = z->l - z->c; /* test, line 179 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + { int m_test3 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m2; goto lab0; } z->c--; z->c = z->l - m_test3; } lab0: ; } - z->bra = z->c; /* ], line 179 */ - { int ret = slice_del(z); /* delete, line 179 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 200 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -935,43 +934,43 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ +static int r_residual_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 205 */ - among_var = find_among_b(z, a_9, 8); /* substring, line 205 */ + z->ket = z->c; + among_var = find_among_b(z, a_9, 8); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 205 */ - switch (among_var) { /* among, line 205 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 208 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 208 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_RV(z); /* call RV, line 210 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 210 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 210 */ - z->ket = z->c; /* [, line 210 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m1; goto lab0; } z->c--; - z->bra = z->c; /* ], line 210 */ - { int m_test2 = z->l - z->c; /* test, line 210 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m1; goto lab0; } z->c--; z->c = z->l - m_test2; } - { int ret = r_RV(z); /* call RV, line 210 */ + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 210 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -982,36 +981,36 @@ static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int spanish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - /* do, line 216 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 216 */ +extern int spanish_ISO_8859_1_stem(struct SN_env * z) { + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 217 */ + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 218 */ - { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 218 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_attached_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 219 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 219 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 219 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m3; - { int ret = r_y_verb_suffix(z); /* call y_verb_suffix, line 220 */ + { int ret = r_y_verb_suffix(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } goto lab1; lab3: z->c = z->l - m3; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 221 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1020,15 +1019,15 @@ extern int spanish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 223 */ - { int ret = r_residual_suffix(z); /* call residual_suffix, line 223 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_residual_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; } z->c = z->lb; - { int c5 = z->c; /* do, line 225 */ - { int ret = r_postlude(z); /* call postlude, line 225 */ + { int c5 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c5; @@ -1036,7 +1035,7 @@ extern int spanish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * spanish_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * spanish_ISO_8859_1_create_env(void) { return SN_create_env(0, 3); } extern void spanish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c index e53777eb735a..215298c03465 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -65,43 +65,43 @@ static const symbol s_0_36[3] = { 'a', 's', 't' }; static const struct among a_0[37] = { -/* 0 */ { 1, s_0_0, -1, 1, 0}, -/* 1 */ { 4, s_0_1, 0, 1, 0}, -/* 2 */ { 4, s_0_2, 0, 1, 0}, -/* 3 */ { 7, s_0_3, 2, 1, 0}, -/* 4 */ { 4, s_0_4, 0, 1, 0}, -/* 5 */ { 2, s_0_5, -1, 1, 0}, -/* 6 */ { 1, s_0_6, -1, 1, 0}, -/* 7 */ { 3, s_0_7, 6, 1, 0}, -/* 8 */ { 4, s_0_8, 6, 1, 0}, -/* 9 */ { 4, s_0_9, 6, 1, 0}, -/* 10 */ { 3, s_0_10, 6, 1, 0}, -/* 11 */ { 4, s_0_11, 6, 1, 0}, -/* 12 */ { 2, s_0_12, -1, 1, 0}, -/* 13 */ { 5, s_0_13, 12, 1, 0}, -/* 14 */ { 4, s_0_14, 12, 1, 0}, -/* 15 */ { 5, s_0_15, 12, 1, 0}, -/* 16 */ { 3, s_0_16, -1, 1, 0}, -/* 17 */ { 2, s_0_17, -1, 1, 0}, -/* 18 */ { 2, s_0_18, -1, 1, 0}, -/* 19 */ { 5, s_0_19, 18, 1, 0}, -/* 20 */ { 2, s_0_20, -1, 1, 0}, -/* 21 */ { 1, s_0_21, -1, 2, 0}, -/* 22 */ { 2, s_0_22, 21, 1, 0}, -/* 23 */ { 5, s_0_23, 22, 1, 0}, -/* 24 */ { 5, s_0_24, 22, 1, 0}, -/* 25 */ { 5, s_0_25, 22, 1, 0}, -/* 26 */ { 2, s_0_26, 21, 1, 0}, -/* 27 */ { 4, s_0_27, 26, 1, 0}, -/* 28 */ { 5, s_0_28, 26, 1, 0}, -/* 29 */ { 3, s_0_29, 21, 1, 0}, -/* 30 */ { 5, s_0_30, 29, 1, 0}, -/* 31 */ { 6, s_0_31, 29, 1, 0}, -/* 32 */ { 4, s_0_32, 21, 1, 0}, -/* 33 */ { 2, s_0_33, -1, 1, 0}, -/* 34 */ { 5, s_0_34, -1, 1, 0}, -/* 35 */ { 3, s_0_35, -1, 1, 0}, -/* 36 */ { 3, s_0_36, -1, 1, 0} +{ 1, s_0_0, -1, 1, 0}, +{ 4, s_0_1, 0, 1, 0}, +{ 4, s_0_2, 0, 1, 0}, +{ 7, s_0_3, 2, 1, 0}, +{ 4, s_0_4, 0, 1, 0}, +{ 2, s_0_5, -1, 1, 0}, +{ 1, s_0_6, -1, 1, 0}, +{ 3, s_0_7, 6, 1, 0}, +{ 4, s_0_8, 6, 1, 0}, +{ 4, s_0_9, 6, 1, 0}, +{ 3, s_0_10, 6, 1, 0}, +{ 4, s_0_11, 6, 1, 0}, +{ 2, s_0_12, -1, 1, 0}, +{ 5, s_0_13, 12, 1, 0}, +{ 4, s_0_14, 12, 1, 0}, +{ 5, s_0_15, 12, 1, 0}, +{ 3, s_0_16, -1, 1, 0}, +{ 2, s_0_17, -1, 1, 0}, +{ 2, s_0_18, -1, 1, 0}, +{ 5, s_0_19, 18, 1, 0}, +{ 2, s_0_20, -1, 1, 0}, +{ 1, s_0_21, -1, 2, 0}, +{ 2, s_0_22, 21, 1, 0}, +{ 5, s_0_23, 22, 1, 0}, +{ 5, s_0_24, 22, 1, 0}, +{ 5, s_0_25, 22, 1, 0}, +{ 2, s_0_26, 21, 1, 0}, +{ 4, s_0_27, 26, 1, 0}, +{ 5, s_0_28, 26, 1, 0}, +{ 3, s_0_29, 21, 1, 0}, +{ 5, s_0_30, 29, 1, 0}, +{ 6, s_0_31, 29, 1, 0}, +{ 4, s_0_32, 21, 1, 0}, +{ 2, s_0_33, -1, 1, 0}, +{ 5, s_0_34, -1, 1, 0}, +{ 3, s_0_35, -1, 1, 0}, +{ 3, s_0_36, -1, 1, 0} }; static const symbol s_1_0[2] = { 'd', 'd' }; @@ -114,13 +114,13 @@ static const symbol s_1_6[2] = { 't', 't' }; static const struct among a_1[7] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0}, -/* 2 */ { 2, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0}, -/* 4 */ { 2, s_1_4, -1, -1, 0}, -/* 5 */ { 2, s_1_5, -1, -1, 0}, -/* 6 */ { 2, s_1_6, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0}, +{ 2, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0}, +{ 2, s_1_4, -1, -1, 0}, +{ 2, s_1_5, -1, -1, 0}, +{ 2, s_1_6, -1, -1, 0} }; static const symbol s_2_0[2] = { 'i', 'g' }; @@ -131,11 +131,11 @@ static const symbol s_2_4[4] = { 'l', 0xF6, 's', 't' }; static const struct among a_2[5] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 3, s_2_1, 0, 1, 0}, -/* 2 */ { 3, s_2_2, -1, 1, 0}, -/* 3 */ { 5, s_2_3, -1, 3, 0}, -/* 4 */ { 4, s_2_4, -1, 2, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 3, s_2_1, 0, 1, 0}, +{ 3, s_2_2, -1, 1, 0}, +{ 5, s_2_3, -1, 3, 0}, +{ 4, s_2_4, -1, 2, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32 }; @@ -145,52 +145,50 @@ static const unsigned char g_s_ending[] = { 119, 127, 149 }; static const symbol s_0[] = { 'l', 0xF6, 's' }; static const symbol s_1[] = { 'f', 'u', 'l', 'l' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 28 */ - { int c_test1 = z->c; /* test, line 29 */ - { int ret = z->c + 3; /* hop, line 29 */ - if (0 > ret || ret > z->l) return 0; - z->c = ret; - } - z->I[1] = z->c; /* setmark x, line 29 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + { int c_test1 = z->c; +z->c = z->c + 3; + if (z->c > z->l) return 0; + z->I[0] = z->c; z->c = c_test1; } - if (out_grouping(z, g_v, 97, 246, 1) < 0) return 0; /* goto */ /* grouping v, line 30 */ - { /* gopast */ /* non v, line 30 */ + if (out_grouping(z, g_v, 97, 246, 1) < 0) return 0; + { int ret = in_grouping(z, g_v, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 30 */ - /* try, line 31 */ - if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 31 */ - z->I[0] = z->I[1]; /* $p1 = , line 31 */ + z->I[1] = z->c; + + if (!(z->I[1] < z->I[0])) goto lab0; + z->I[1] = z->I[0]; lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { /* backwardmode */ +static int r_main_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 37 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 37 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 37 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_0, 37); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 37 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 38 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 44 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (in_grouping_b(z, g_s_ending, 98, 121, 0)) return 0; /* grouping s_ending, line 46 */ - { int ret = slice_del(z); /* delete, line 46 */ + if (in_grouping_b(z, g_s_ending, 98, 121, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -198,20 +196,20 @@ static int r_main_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ +static int r_consonant_pair(struct SN_env * z) { - { int mlimit1; /* setlimit, line 50 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - { int m2 = z->l - z->c; (void)m2; /* and, line 52 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* among, line 51 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + { int m2 = z->l - z->c; (void)m2; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit1; return 0; } z->c = z->l - m2; - z->ket = z->c; /* [, line 52 */ + z->ket = z->c; if (z->c <= z->lb) { z->lb = mlimit1; return 0; } - z->c--; /* next, line 52 */ - z->bra = z->c; /* ], line 52 */ - { int ret = slice_del(z); /* delete, line 52 */ + z->c--; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } } @@ -220,30 +218,30 @@ static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_other_suffix(struct SN_env * z) { /* backwardmode */ +static int r_other_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 55 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 56 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 56 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_2, 5); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 56 */ - switch (among_var) { /* among, line 56 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 57 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_0); /* <-, line 58 */ + { int ret = slice_from_s(z, 3, s_0); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_1); /* <-, line 59 */ + { int ret = slice_from_s(z, 4, s_1); if (ret < 0) return ret; } break; @@ -253,29 +251,29 @@ static int r_other_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int swedish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 66 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 66 */ +extern int swedish_ISO_8859_1_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 67 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 68 */ - { int ret = r_main_suffix(z); /* call main_suffix, line 68 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_main_suffix(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 69 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 69 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 70 */ - { int ret = r_other_suffix(z); /* call other_suffix, line 70 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_other_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; @@ -284,7 +282,7 @@ extern int swedish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * swedish_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * swedish_ISO_8859_1_create_env(void) { return SN_create_env(0, 2); } extern void swedish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_2_hungarian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_2_hungarian.c index 44ef3d9253d8..ce499386facc 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_2_hungarian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_2_hungarian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -46,14 +46,14 @@ static const symbol s_0_7[2] = { 'z', 's' }; static const struct among a_0[8] = { -/* 0 */ { 2, s_0_0, -1, -1, 0}, -/* 1 */ { 3, s_0_1, -1, -1, 0}, -/* 2 */ { 2, s_0_2, -1, -1, 0}, -/* 3 */ { 2, s_0_3, -1, -1, 0}, -/* 4 */ { 2, s_0_4, -1, -1, 0}, -/* 5 */ { 2, s_0_5, -1, -1, 0}, -/* 6 */ { 2, s_0_6, -1, -1, 0}, -/* 7 */ { 2, s_0_7, -1, -1, 0} +{ 2, s_0_0, -1, -1, 0}, +{ 3, s_0_1, -1, -1, 0}, +{ 2, s_0_2, -1, -1, 0}, +{ 2, s_0_3, -1, -1, 0}, +{ 2, s_0_4, -1, -1, 0}, +{ 2, s_0_5, -1, -1, 0}, +{ 2, s_0_6, -1, -1, 0}, +{ 2, s_0_7, -1, -1, 0} }; static const symbol s_1_0[1] = { 0xE1 }; @@ -61,8 +61,8 @@ static const symbol s_1_1[1] = { 0xE9 }; static const struct among a_1[2] = { -/* 0 */ { 1, s_1_0, -1, 1, 0}, -/* 1 */ { 1, s_1_1, -1, 2, 0} +{ 1, s_1_0, -1, 1, 0}, +{ 1, s_1_1, -1, 2, 0} }; static const symbol s_2_0[2] = { 'b', 'b' }; @@ -91,29 +91,29 @@ static const symbol s_2_22[2] = { 'z', 'z' }; static const struct among a_2[23] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 2, s_2_2, -1, -1, 0}, -/* 3 */ { 2, s_2_3, -1, -1, 0}, -/* 4 */ { 2, s_2_4, -1, -1, 0}, -/* 5 */ { 2, s_2_5, -1, -1, 0}, -/* 6 */ { 2, s_2_6, -1, -1, 0}, -/* 7 */ { 2, s_2_7, -1, -1, 0}, -/* 8 */ { 2, s_2_8, -1, -1, 0}, -/* 9 */ { 2, s_2_9, -1, -1, 0}, -/* 10 */ { 2, s_2_10, -1, -1, 0}, -/* 11 */ { 2, s_2_11, -1, -1, 0}, -/* 12 */ { 3, s_2_12, -1, -1, 0}, -/* 13 */ { 2, s_2_13, -1, -1, 0}, -/* 14 */ { 3, s_2_14, -1, -1, 0}, -/* 15 */ { 2, s_2_15, -1, -1, 0}, -/* 16 */ { 2, s_2_16, -1, -1, 0}, -/* 17 */ { 3, s_2_17, -1, -1, 0}, -/* 18 */ { 3, s_2_18, -1, -1, 0}, -/* 19 */ { 3, s_2_19, -1, -1, 0}, -/* 20 */ { 3, s_2_20, -1, -1, 0}, -/* 21 */ { 3, s_2_21, -1, -1, 0}, -/* 22 */ { 2, s_2_22, -1, -1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 2, s_2_2, -1, -1, 0}, +{ 2, s_2_3, -1, -1, 0}, +{ 2, s_2_4, -1, -1, 0}, +{ 2, s_2_5, -1, -1, 0}, +{ 2, s_2_6, -1, -1, 0}, +{ 2, s_2_7, -1, -1, 0}, +{ 2, s_2_8, -1, -1, 0}, +{ 2, s_2_9, -1, -1, 0}, +{ 2, s_2_10, -1, -1, 0}, +{ 2, s_2_11, -1, -1, 0}, +{ 3, s_2_12, -1, -1, 0}, +{ 2, s_2_13, -1, -1, 0}, +{ 3, s_2_14, -1, -1, 0}, +{ 2, s_2_15, -1, -1, 0}, +{ 2, s_2_16, -1, -1, 0}, +{ 3, s_2_17, -1, -1, 0}, +{ 3, s_2_18, -1, -1, 0}, +{ 3, s_2_19, -1, -1, 0}, +{ 3, s_2_20, -1, -1, 0}, +{ 3, s_2_21, -1, -1, 0}, +{ 2, s_2_22, -1, -1, 0} }; static const symbol s_3_0[2] = { 'a', 'l' }; @@ -121,8 +121,8 @@ static const symbol s_3_1[2] = { 'e', 'l' }; static const struct among a_3[2] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 2, s_3_1, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 2, s_3_1, -1, 1, 0} }; static const symbol s_4_0[2] = { 'b', 'a' }; @@ -172,50 +172,50 @@ static const symbol s_4_43[2] = { 'v', 0xE9 }; static const struct among a_4[44] = { -/* 0 */ { 2, s_4_0, -1, -1, 0}, -/* 1 */ { 2, s_4_1, -1, -1, 0}, -/* 2 */ { 2, s_4_2, -1, -1, 0}, -/* 3 */ { 2, s_4_3, -1, -1, 0}, -/* 4 */ { 2, s_4_4, -1, -1, 0}, -/* 5 */ { 3, s_4_5, -1, -1, 0}, -/* 6 */ { 3, s_4_6, -1, -1, 0}, -/* 7 */ { 3, s_4_7, -1, -1, 0}, -/* 8 */ { 3, s_4_8, -1, -1, 0}, -/* 9 */ { 2, s_4_9, -1, -1, 0}, -/* 10 */ { 3, s_4_10, -1, -1, 0}, -/* 11 */ { 3, s_4_11, -1, -1, 0}, -/* 12 */ { 3, s_4_12, -1, -1, 0}, -/* 13 */ { 3, s_4_13, -1, -1, 0}, -/* 14 */ { 3, s_4_14, -1, -1, 0}, -/* 15 */ { 3, s_4_15, -1, -1, 0}, -/* 16 */ { 3, s_4_16, -1, -1, 0}, -/* 17 */ { 3, s_4_17, -1, -1, 0}, -/* 18 */ { 2, s_4_18, -1, -1, 0}, -/* 19 */ { 1, s_4_19, -1, -1, 0}, -/* 20 */ { 2, s_4_20, 19, -1, 0}, -/* 21 */ { 3, s_4_21, 20, -1, 0}, -/* 22 */ { 2, s_4_22, 19, -1, 0}, -/* 23 */ { 3, s_4_23, 22, -1, 0}, -/* 24 */ { 6, s_4_24, 22, -1, 0}, -/* 25 */ { 2, s_4_25, 19, -1, 0}, -/* 26 */ { 2, s_4_26, 19, -1, 0}, -/* 27 */ { 4, s_4_27, -1, -1, 0}, -/* 28 */ { 3, s_4_28, -1, -1, 0}, -/* 29 */ { 1, s_4_29, -1, -1, 0}, -/* 30 */ { 2, s_4_30, 29, -1, 0}, -/* 31 */ { 2, s_4_31, 29, -1, 0}, -/* 32 */ { 4, s_4_32, 29, -1, 0}, -/* 33 */ { 6, s_4_33, 32, -1, 0}, -/* 34 */ { 6, s_4_34, 32, -1, 0}, -/* 35 */ { 6, s_4_35, 32, -1, 0}, -/* 36 */ { 2, s_4_36, 29, -1, 0}, -/* 37 */ { 3, s_4_37, 29, -1, 0}, -/* 38 */ { 2, s_4_38, 29, -1, 0}, -/* 39 */ { 3, s_4_39, -1, -1, 0}, -/* 40 */ { 3, s_4_40, -1, -1, 0}, -/* 41 */ { 3, s_4_41, -1, -1, 0}, -/* 42 */ { 2, s_4_42, -1, -1, 0}, -/* 43 */ { 2, s_4_43, -1, -1, 0} +{ 2, s_4_0, -1, -1, 0}, +{ 2, s_4_1, -1, -1, 0}, +{ 2, s_4_2, -1, -1, 0}, +{ 2, s_4_3, -1, -1, 0}, +{ 2, s_4_4, -1, -1, 0}, +{ 3, s_4_5, -1, -1, 0}, +{ 3, s_4_6, -1, -1, 0}, +{ 3, s_4_7, -1, -1, 0}, +{ 3, s_4_8, -1, -1, 0}, +{ 2, s_4_9, -1, -1, 0}, +{ 3, s_4_10, -1, -1, 0}, +{ 3, s_4_11, -1, -1, 0}, +{ 3, s_4_12, -1, -1, 0}, +{ 3, s_4_13, -1, -1, 0}, +{ 3, s_4_14, -1, -1, 0}, +{ 3, s_4_15, -1, -1, 0}, +{ 3, s_4_16, -1, -1, 0}, +{ 3, s_4_17, -1, -1, 0}, +{ 2, s_4_18, -1, -1, 0}, +{ 1, s_4_19, -1, -1, 0}, +{ 2, s_4_20, 19, -1, 0}, +{ 3, s_4_21, 20, -1, 0}, +{ 2, s_4_22, 19, -1, 0}, +{ 3, s_4_23, 22, -1, 0}, +{ 6, s_4_24, 22, -1, 0}, +{ 2, s_4_25, 19, -1, 0}, +{ 2, s_4_26, 19, -1, 0}, +{ 4, s_4_27, -1, -1, 0}, +{ 3, s_4_28, -1, -1, 0}, +{ 1, s_4_29, -1, -1, 0}, +{ 2, s_4_30, 29, -1, 0}, +{ 2, s_4_31, 29, -1, 0}, +{ 4, s_4_32, 29, -1, 0}, +{ 6, s_4_33, 32, -1, 0}, +{ 6, s_4_34, 32, -1, 0}, +{ 6, s_4_35, 32, -1, 0}, +{ 2, s_4_36, 29, -1, 0}, +{ 3, s_4_37, 29, -1, 0}, +{ 2, s_4_38, 29, -1, 0}, +{ 3, s_4_39, -1, -1, 0}, +{ 3, s_4_40, -1, -1, 0}, +{ 3, s_4_41, -1, -1, 0}, +{ 2, s_4_42, -1, -1, 0}, +{ 2, s_4_43, -1, -1, 0} }; static const symbol s_5_0[2] = { 0xE1, 'n' }; @@ -224,9 +224,9 @@ static const symbol s_5_2[6] = { 0xE1, 'n', 'k', 0xE9, 'n', 't' }; static const struct among a_5[3] = { -/* 0 */ { 2, s_5_0, -1, 2, 0}, -/* 1 */ { 2, s_5_1, -1, 1, 0}, -/* 2 */ { 6, s_5_2, -1, 2, 0} +{ 2, s_5_0, -1, 2, 0}, +{ 2, s_5_1, -1, 1, 0}, +{ 6, s_5_2, -1, 2, 0} }; static const symbol s_6_0[4] = { 's', 't', 'u', 'l' }; @@ -238,12 +238,12 @@ static const symbol s_6_5[5] = { 0xE9, 's', 't', 0xFC, 'l' }; static const struct among a_6[6] = { -/* 0 */ { 4, s_6_0, -1, 1, 0}, -/* 1 */ { 5, s_6_1, 0, 1, 0}, -/* 2 */ { 5, s_6_2, 0, 2, 0}, -/* 3 */ { 4, s_6_3, -1, 1, 0}, -/* 4 */ { 5, s_6_4, 3, 1, 0}, -/* 5 */ { 5, s_6_5, 3, 3, 0} +{ 4, s_6_0, -1, 1, 0}, +{ 5, s_6_1, 0, 1, 0}, +{ 5, s_6_2, 0, 2, 0}, +{ 4, s_6_3, -1, 1, 0}, +{ 5, s_6_4, 3, 1, 0}, +{ 5, s_6_5, 3, 3, 0} }; static const symbol s_7_0[1] = { 0xE1 }; @@ -251,8 +251,8 @@ static const symbol s_7_1[1] = { 0xE9 }; static const struct among a_7[2] = { -/* 0 */ { 1, s_7_0, -1, 1, 0}, -/* 1 */ { 1, s_7_1, -1, 1, 0} +{ 1, s_7_0, -1, 1, 0}, +{ 1, s_7_1, -1, 1, 0} }; static const symbol s_8_0[1] = { 'k' }; @@ -265,13 +265,13 @@ static const symbol s_8_6[2] = { 0xF6, 'k' }; static const struct among a_8[7] = { -/* 0 */ { 1, s_8_0, -1, 3, 0}, -/* 1 */ { 2, s_8_1, 0, 3, 0}, -/* 2 */ { 2, s_8_2, 0, 3, 0}, -/* 3 */ { 2, s_8_3, 0, 3, 0}, -/* 4 */ { 2, s_8_4, 0, 1, 0}, -/* 5 */ { 2, s_8_5, 0, 2, 0}, -/* 6 */ { 2, s_8_6, 0, 3, 0} +{ 1, s_8_0, -1, 3, 0}, +{ 2, s_8_1, 0, 3, 0}, +{ 2, s_8_2, 0, 3, 0}, +{ 2, s_8_3, 0, 3, 0}, +{ 2, s_8_4, 0, 1, 0}, +{ 2, s_8_5, 0, 2, 0}, +{ 2, s_8_6, 0, 3, 0} }; static const symbol s_9_0[2] = { 0xE9, 'i' }; @@ -289,18 +289,18 @@ static const symbol s_9_11[2] = { 0xE9, 0xE9 }; static const struct among a_9[12] = { -/* 0 */ { 2, s_9_0, -1, 1, 0}, -/* 1 */ { 3, s_9_1, 0, 3, 0}, -/* 2 */ { 3, s_9_2, 0, 2, 0}, -/* 3 */ { 1, s_9_3, -1, 1, 0}, -/* 4 */ { 2, s_9_4, 3, 1, 0}, -/* 5 */ { 3, s_9_5, 4, 1, 0}, -/* 6 */ { 3, s_9_6, 4, 1, 0}, -/* 7 */ { 3, s_9_7, 4, 1, 0}, -/* 8 */ { 3, s_9_8, 4, 3, 0}, -/* 9 */ { 3, s_9_9, 4, 2, 0}, -/* 10 */ { 3, s_9_10, 4, 1, 0}, -/* 11 */ { 2, s_9_11, 3, 2, 0} +{ 2, s_9_0, -1, 1, 0}, +{ 3, s_9_1, 0, 3, 0}, +{ 3, s_9_2, 0, 2, 0}, +{ 1, s_9_3, -1, 1, 0}, +{ 2, s_9_4, 3, 1, 0}, +{ 3, s_9_5, 4, 1, 0}, +{ 3, s_9_6, 4, 1, 0}, +{ 3, s_9_7, 4, 1, 0}, +{ 3, s_9_8, 4, 3, 0}, +{ 3, s_9_9, 4, 2, 0}, +{ 3, s_9_10, 4, 1, 0}, +{ 2, s_9_11, 3, 2, 0} }; static const symbol s_10_0[1] = { 'a' }; @@ -337,37 +337,37 @@ static const symbol s_10_30[1] = { 0xE9 }; static const struct among a_10[31] = { -/* 0 */ { 1, s_10_0, -1, 1, 0}, -/* 1 */ { 2, s_10_1, 0, 1, 0}, -/* 2 */ { 1, s_10_2, -1, 1, 0}, -/* 3 */ { 2, s_10_3, 2, 1, 0}, -/* 4 */ { 2, s_10_4, 2, 1, 0}, -/* 5 */ { 2, s_10_5, 2, 1, 0}, -/* 6 */ { 2, s_10_6, 2, 2, 0}, -/* 7 */ { 2, s_10_7, 2, 3, 0}, -/* 8 */ { 2, s_10_8, 2, 1, 0}, -/* 9 */ { 1, s_10_9, -1, 1, 0}, -/* 10 */ { 2, s_10_10, 9, 1, 0}, -/* 11 */ { 2, s_10_11, -1, 1, 0}, -/* 12 */ { 3, s_10_12, 11, 1, 0}, -/* 13 */ { 3, s_10_13, 11, 2, 0}, -/* 14 */ { 3, s_10_14, 11, 3, 0}, -/* 15 */ { 3, s_10_15, 11, 1, 0}, -/* 16 */ { 2, s_10_16, -1, 1, 0}, -/* 17 */ { 3, s_10_17, 16, 1, 0}, -/* 18 */ { 4, s_10_18, 17, 2, 0}, -/* 19 */ { 2, s_10_19, -1, 1, 0}, -/* 20 */ { 3, s_10_20, 19, 1, 0}, -/* 21 */ { 4, s_10_21, 20, 3, 0}, -/* 22 */ { 1, s_10_22, -1, 1, 0}, -/* 23 */ { 2, s_10_23, 22, 1, 0}, -/* 24 */ { 2, s_10_24, 22, 1, 0}, -/* 25 */ { 2, s_10_25, 22, 1, 0}, -/* 26 */ { 2, s_10_26, 22, 2, 0}, -/* 27 */ { 2, s_10_27, 22, 3, 0}, -/* 28 */ { 1, s_10_28, -1, 1, 0}, -/* 29 */ { 1, s_10_29, -1, 2, 0}, -/* 30 */ { 1, s_10_30, -1, 3, 0} +{ 1, s_10_0, -1, 1, 0}, +{ 2, s_10_1, 0, 1, 0}, +{ 1, s_10_2, -1, 1, 0}, +{ 2, s_10_3, 2, 1, 0}, +{ 2, s_10_4, 2, 1, 0}, +{ 2, s_10_5, 2, 1, 0}, +{ 2, s_10_6, 2, 2, 0}, +{ 2, s_10_7, 2, 3, 0}, +{ 2, s_10_8, 2, 1, 0}, +{ 1, s_10_9, -1, 1, 0}, +{ 2, s_10_10, 9, 1, 0}, +{ 2, s_10_11, -1, 1, 0}, +{ 3, s_10_12, 11, 1, 0}, +{ 3, s_10_13, 11, 2, 0}, +{ 3, s_10_14, 11, 3, 0}, +{ 3, s_10_15, 11, 1, 0}, +{ 2, s_10_16, -1, 1, 0}, +{ 3, s_10_17, 16, 1, 0}, +{ 4, s_10_18, 17, 2, 0}, +{ 2, s_10_19, -1, 1, 0}, +{ 3, s_10_20, 19, 1, 0}, +{ 4, s_10_21, 20, 3, 0}, +{ 1, s_10_22, -1, 1, 0}, +{ 2, s_10_23, 22, 1, 0}, +{ 2, s_10_24, 22, 1, 0}, +{ 2, s_10_25, 22, 1, 0}, +{ 2, s_10_26, 22, 2, 0}, +{ 2, s_10_27, 22, 3, 0}, +{ 1, s_10_28, -1, 1, 0}, +{ 1, s_10_29, -1, 2, 0}, +{ 1, s_10_30, -1, 3, 0} }; static const symbol s_11_0[2] = { 'i', 'd' }; @@ -415,48 +415,48 @@ static const symbol s_11_41[3] = { 0xE9, 'i', 'm' }; static const struct among a_11[42] = { -/* 0 */ { 2, s_11_0, -1, 1, 0}, -/* 1 */ { 3, s_11_1, 0, 1, 0}, -/* 2 */ { 4, s_11_2, 1, 1, 0}, -/* 3 */ { 3, s_11_3, 0, 1, 0}, -/* 4 */ { 4, s_11_4, 3, 1, 0}, -/* 5 */ { 3, s_11_5, 0, 2, 0}, -/* 6 */ { 3, s_11_6, 0, 3, 0}, -/* 7 */ { 1, s_11_7, -1, 1, 0}, -/* 8 */ { 2, s_11_8, 7, 1, 0}, -/* 9 */ { 3, s_11_9, 8, 1, 0}, -/* 10 */ { 2, s_11_10, 7, 1, 0}, -/* 11 */ { 3, s_11_11, 10, 1, 0}, -/* 12 */ { 2, s_11_12, 7, 2, 0}, -/* 13 */ { 2, s_11_13, 7, 3, 0}, -/* 14 */ { 4, s_11_14, -1, 1, 0}, -/* 15 */ { 5, s_11_15, 14, 1, 0}, -/* 16 */ { 6, s_11_16, 15, 1, 0}, -/* 17 */ { 5, s_11_17, 14, 3, 0}, -/* 18 */ { 2, s_11_18, -1, 1, 0}, -/* 19 */ { 3, s_11_19, 18, 1, 0}, -/* 20 */ { 4, s_11_20, 19, 1, 0}, -/* 21 */ { 3, s_11_21, 18, 1, 0}, -/* 22 */ { 4, s_11_22, 21, 1, 0}, -/* 23 */ { 3, s_11_23, 18, 2, 0}, -/* 24 */ { 3, s_11_24, 18, 3, 0}, -/* 25 */ { 3, s_11_25, -1, 1, 0}, -/* 26 */ { 4, s_11_26, 25, 1, 0}, -/* 27 */ { 5, s_11_27, 26, 1, 0}, -/* 28 */ { 4, s_11_28, 25, 1, 0}, -/* 29 */ { 5, s_11_29, 28, 1, 0}, -/* 30 */ { 4, s_11_30, 25, 2, 0}, -/* 31 */ { 4, s_11_31, 25, 3, 0}, -/* 32 */ { 5, s_11_32, -1, 1, 0}, -/* 33 */ { 6, s_11_33, 32, 1, 0}, -/* 34 */ { 5, s_11_34, -1, 2, 0}, -/* 35 */ { 2, s_11_35, -1, 1, 0}, -/* 36 */ { 3, s_11_36, 35, 1, 0}, -/* 37 */ { 4, s_11_37, 36, 1, 0}, -/* 38 */ { 3, s_11_38, 35, 1, 0}, -/* 39 */ { 4, s_11_39, 38, 1, 0}, -/* 40 */ { 3, s_11_40, 35, 2, 0}, -/* 41 */ { 3, s_11_41, 35, 3, 0} +{ 2, s_11_0, -1, 1, 0}, +{ 3, s_11_1, 0, 1, 0}, +{ 4, s_11_2, 1, 1, 0}, +{ 3, s_11_3, 0, 1, 0}, +{ 4, s_11_4, 3, 1, 0}, +{ 3, s_11_5, 0, 2, 0}, +{ 3, s_11_6, 0, 3, 0}, +{ 1, s_11_7, -1, 1, 0}, +{ 2, s_11_8, 7, 1, 0}, +{ 3, s_11_9, 8, 1, 0}, +{ 2, s_11_10, 7, 1, 0}, +{ 3, s_11_11, 10, 1, 0}, +{ 2, s_11_12, 7, 2, 0}, +{ 2, s_11_13, 7, 3, 0}, +{ 4, s_11_14, -1, 1, 0}, +{ 5, s_11_15, 14, 1, 0}, +{ 6, s_11_16, 15, 1, 0}, +{ 5, s_11_17, 14, 3, 0}, +{ 2, s_11_18, -1, 1, 0}, +{ 3, s_11_19, 18, 1, 0}, +{ 4, s_11_20, 19, 1, 0}, +{ 3, s_11_21, 18, 1, 0}, +{ 4, s_11_22, 21, 1, 0}, +{ 3, s_11_23, 18, 2, 0}, +{ 3, s_11_24, 18, 3, 0}, +{ 3, s_11_25, -1, 1, 0}, +{ 4, s_11_26, 25, 1, 0}, +{ 5, s_11_27, 26, 1, 0}, +{ 4, s_11_28, 25, 1, 0}, +{ 5, s_11_29, 28, 1, 0}, +{ 4, s_11_30, 25, 2, 0}, +{ 4, s_11_31, 25, 3, 0}, +{ 5, s_11_32, -1, 1, 0}, +{ 6, s_11_33, 32, 1, 0}, +{ 5, s_11_34, -1, 2, 0}, +{ 2, s_11_35, -1, 1, 0}, +{ 3, s_11_36, 35, 1, 0}, +{ 4, s_11_37, 36, 1, 0}, +{ 3, s_11_38, 35, 1, 0}, +{ 4, s_11_39, 38, 1, 0}, +{ 3, s_11_40, 35, 2, 0}, +{ 3, s_11_41, 35, 3, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 52, 14 }; @@ -476,60 +476,60 @@ static const symbol s_11[] = { 'e' }; static const symbol s_12[] = { 'a' }; static const symbol s_13[] = { 'e' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 46 */ - { int c1 = z->c; /* or, line 51 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab1; /* grouping v, line 48 */ - if (in_grouping(z, g_v, 97, 252, 1) < 0) goto lab1; /* goto */ /* non v, line 48 */ - { int c2 = z->c; /* or, line 49 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; /* among, line 49 */ +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c1 = z->c; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab1; + if (in_grouping(z, g_v, 97, 252, 1) < 0) goto lab1; + { int c2 = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; if (!(find_among(z, a_0, 8))) goto lab3; goto lab2; lab3: z->c = c2; if (z->c >= z->l) goto lab1; - z->c++; /* next, line 49 */ + z->c++; } lab2: - z->I[0] = z->c; /* setmark p1, line 50 */ + z->I[0] = z->c; goto lab0; lab1: z->c = c1; - if (out_grouping(z, g_v, 97, 252, 0)) return 0; /* non v, line 53 */ - { /* gopast */ /* grouping v, line 53 */ + if (out_grouping(z, g_v, 97, 252, 0)) return 0; + { int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 53 */ + z->I[0] = z->c; } lab0: return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 58 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_v_ending(struct SN_env * z) { /* backwardmode */ +static int r_v_ending(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 61 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; /* substring, line 61 */ + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; among_var = find_among_b(z, a_1, 2); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 61 */ - { int ret = r_R1(z); /* call R1, line 61 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 61 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 62 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 63 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; @@ -537,84 +537,82 @@ static int r_v_ending(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_double(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 68 */ +static int r_double(struct SN_env * z) { + { int m_test1 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_2, 23))) return 0; z->c = z->l - m_test1; } return 1; } -static int r_undouble(struct SN_env * z) { /* backwardmode */ +static int r_undouble(struct SN_env * z) { if (z->c <= z->lb) return 0; - z->c--; /* next, line 73 */ - z->ket = z->c; /* [, line 73 */ - { int ret = z->c - 1; /* hop, line 73 */ - if (z->lb > ret || ret > z->l) return 0; - z->c = ret; - } - z->bra = z->c; /* ], line 73 */ - { int ret = slice_del(z); /* delete, line 73 */ + z->c--; + z->ket = z->c; +z->c = z->c - 1; + if (z->c < z->lb) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_instrum(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 77 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 77 */ +static int r_instrum(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; if (!(find_among_b(z, a_3, 2))) return 0; - z->bra = z->c; /* ], line 77 */ - { int ret = r_R1(z); /* call R1, line 77 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = r_double(z); /* call double, line 78 */ + { int ret = r_double(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 81 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_undouble(z); /* call undouble, line 82 */ + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_case(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 87 */ - if (!(find_among_b(z, a_4, 44))) return 0; /* substring, line 87 */ - z->bra = z->c; /* ], line 87 */ - { int ret = r_R1(z); /* call R1, line 87 */ +static int r_case(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_4, 44))) return 0; + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 111 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_v_ending(z); /* call v_ending, line 112 */ + { int ret = r_v_ending(z); if (ret <= 0) return ret; } return 1; } -static int r_case_special(struct SN_env * z) { /* backwardmode */ +static int r_case_special(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 116 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; /* substring, line 116 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; among_var = find_among_b(z, a_5, 3); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 116 */ - { int ret = r_R1(z); /* call R1, line 116 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 116 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 117 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 118 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; @@ -622,29 +620,29 @@ static int r_case_special(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_case_other(struct SN_env * z) { /* backwardmode */ +static int r_case_other(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 124 */ + z->ket = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; among_var = find_among_b(z, a_6, 6); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 124 */ - { int ret = r_R1(z); /* call R1, line 124 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 124 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 127 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 128 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; @@ -652,49 +650,49 @@ static int r_case_other(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_factive(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 133 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; /* substring, line 133 */ +static int r_factive(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; if (!(find_among_b(z, a_7, 2))) return 0; - z->bra = z->c; /* ], line 133 */ - { int ret = r_R1(z); /* call R1, line 133 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = r_double(z); /* call double, line 134 */ + { int ret = r_double(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 137 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_undouble(z); /* call undouble, line 138 */ + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_plural(struct SN_env * z) { /* backwardmode */ +static int r_plural(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 142 */ - if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; /* substring, line 142 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; among_var = find_among_b(z, a_8, 7); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 142 */ - { int ret = r_R1(z); /* call R1, line 142 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 142 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 143 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 144 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 145 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -702,29 +700,29 @@ static int r_plural(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_owned(struct SN_env * z) { /* backwardmode */ +static int r_owned(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 154 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 233)) return 0; /* substring, line 154 */ + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 233)) return 0; among_var = find_among_b(z, a_9, 12); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 154 */ - { int ret = r_R1(z); /* call R1, line 154 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 154 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 155 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 156 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 157 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; @@ -732,28 +730,28 @@ static int r_owned(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_sing_owner(struct SN_env * z) { /* backwardmode */ +static int r_sing_owner(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 168 */ - among_var = find_among_b(z, a_10, 31); /* substring, line 168 */ + z->ket = z->c; + among_var = find_among_b(z, a_10, 31); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 168 */ - { int ret = r_R1(z); /* call R1, line 168 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 168 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 169 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 170 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 171 */ + { int ret = slice_from_s(z, 1, s_11); if (ret < 0) return ret; } break; @@ -761,29 +759,29 @@ static int r_sing_owner(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_plur_owner(struct SN_env * z) { /* backwardmode */ +static int r_plur_owner(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 193 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 193 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_11, 42); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 193 */ - { int ret = r_R1(z); /* call R1, line 193 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 193 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 194 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 195 */ + { int ret = slice_from_s(z, 1, s_12); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 196 */ + { int ret = slice_from_s(z, 1, s_13); if (ret < 0) return ret; } break; @@ -791,65 +789,65 @@ static int r_plur_owner(struct SN_env * z) { /* backwardmode */ return 1; } -extern int hungarian_ISO_8859_2_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 229 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 229 */ +extern int hungarian_ISO_8859_2_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 230 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 231 */ - { int ret = r_instrum(z); /* call instrum, line 231 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_instrum(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 232 */ - { int ret = r_case(z); /* call case, line 232 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_case(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 233 */ - { int ret = r_case_special(z); /* call case_special, line 233 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_case_special(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 234 */ - { int ret = r_case_other(z); /* call case_other, line 234 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_case_other(z); if (ret < 0) return ret; } z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* do, line 235 */ - { int ret = r_factive(z); /* call factive, line 235 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_factive(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 236 */ - { int ret = r_owned(z); /* call owned, line 236 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_owned(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 237 */ - { int ret = r_sing_owner(z); /* call sing_owner, line 237 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_sing_owner(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 238 */ - { int ret = r_plur_owner(z); /* call plur_owner, line 238 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_plur_owner(z); if (ret < 0) return ret; } z->c = z->l - m9; } - { int m10 = z->l - z->c; (void)m10; /* do, line 239 */ - { int ret = r_plural(z); /* call plural, line 239 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_plural(z); if (ret < 0) return ret; } z->c = z->l - m10; @@ -858,7 +856,7 @@ extern int hungarian_ISO_8859_2_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * hungarian_ISO_8859_2_create_env(void) { return SN_create_env(0, 1, 0); } +extern struct SN_env * hungarian_ISO_8859_2_create_env(void) { return SN_create_env(0, 1); } extern void hungarian_ISO_8859_2_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c index 14c6fb3c1463..c1dd11909ae1 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -37,9 +37,9 @@ static const symbol s_0_2[1] = { 'U' }; static const struct among a_0[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 1, s_0_1, 0, 1, 0}, -/* 2 */ { 1, s_0_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 1, s_0_1, 0, 1, 0}, +{ 1, s_0_2, 0, 2, 0} }; static const symbol s_1_0[2] = { 'e', 'a' }; @@ -61,22 +61,22 @@ static const symbol s_1_15[5] = { 'i', 'i', 'l', 'o', 'r' }; static const struct among a_1[16] = { -/* 0 */ { 2, s_1_0, -1, 3, 0}, -/* 1 */ { 4, s_1_1, -1, 7, 0}, -/* 2 */ { 3, s_1_2, -1, 2, 0}, -/* 3 */ { 3, s_1_3, -1, 4, 0}, -/* 4 */ { 4, s_1_4, -1, 7, 0}, -/* 5 */ { 3, s_1_5, -1, 3, 0}, -/* 6 */ { 3, s_1_6, -1, 5, 0}, -/* 7 */ { 4, s_1_7, 6, 4, 0}, -/* 8 */ { 3, s_1_8, -1, 4, 0}, -/* 9 */ { 4, s_1_9, -1, 6, 0}, -/* 10 */ { 2, s_1_10, -1, 4, 0}, -/* 11 */ { 4, s_1_11, -1, 1, 0}, -/* 12 */ { 2, s_1_12, -1, 1, 0}, -/* 13 */ { 4, s_1_13, -1, 3, 0}, -/* 14 */ { 4, s_1_14, -1, 4, 0}, -/* 15 */ { 5, s_1_15, 14, 4, 0} +{ 2, s_1_0, -1, 3, 0}, +{ 4, s_1_1, -1, 7, 0}, +{ 3, s_1_2, -1, 2, 0}, +{ 3, s_1_3, -1, 4, 0}, +{ 4, s_1_4, -1, 7, 0}, +{ 3, s_1_5, -1, 3, 0}, +{ 3, s_1_6, -1, 5, 0}, +{ 4, s_1_7, 6, 4, 0}, +{ 3, s_1_8, -1, 4, 0}, +{ 4, s_1_9, -1, 6, 0}, +{ 2, s_1_10, -1, 4, 0}, +{ 4, s_1_11, -1, 1, 0}, +{ 2, s_1_12, -1, 1, 0}, +{ 4, s_1_13, -1, 3, 0}, +{ 4, s_1_14, -1, 4, 0}, +{ 5, s_1_15, 14, 4, 0} }; static const symbol s_2_0[5] = { 'i', 'c', 'a', 'l', 'a' }; @@ -128,52 +128,52 @@ static const symbol s_2_45[5] = { 'i', 't', 'i', 'v', 0xE3 }; static const struct among a_2[46] = { -/* 0 */ { 5, s_2_0, -1, 4, 0}, -/* 1 */ { 5, s_2_1, -1, 4, 0}, -/* 2 */ { 5, s_2_2, -1, 5, 0}, -/* 3 */ { 5, s_2_3, -1, 6, 0}, -/* 4 */ { 5, s_2_4, -1, 4, 0}, -/* 5 */ { 6, s_2_5, -1, 5, 0}, -/* 6 */ { 6, s_2_6, -1, 6, 0}, -/* 7 */ { 6, s_2_7, -1, 5, 0}, -/* 8 */ { 6, s_2_8, -1, 6, 0}, -/* 9 */ { 6, s_2_9, -1, 5, 0}, -/* 10 */ { 7, s_2_10, -1, 4, 0}, -/* 11 */ { 9, s_2_11, -1, 1, 0}, -/* 12 */ { 9, s_2_12, -1, 2, 0}, -/* 13 */ { 7, s_2_13, -1, 3, 0}, -/* 14 */ { 5, s_2_14, -1, 4, 0}, -/* 15 */ { 5, s_2_15, -1, 5, 0}, -/* 16 */ { 5, s_2_16, -1, 6, 0}, -/* 17 */ { 5, s_2_17, -1, 4, 0}, -/* 18 */ { 5, s_2_18, -1, 5, 0}, -/* 19 */ { 7, s_2_19, 18, 4, 0}, -/* 20 */ { 5, s_2_20, -1, 6, 0}, -/* 21 */ { 5, s_2_21, -1, 5, 0}, -/* 22 */ { 7, s_2_22, -1, 4, 0}, -/* 23 */ { 9, s_2_23, -1, 1, 0}, -/* 24 */ { 7, s_2_24, -1, 3, 0}, -/* 25 */ { 5, s_2_25, -1, 4, 0}, -/* 26 */ { 5, s_2_26, -1, 5, 0}, -/* 27 */ { 5, s_2_27, -1, 6, 0}, -/* 28 */ { 6, s_2_28, -1, 4, 0}, -/* 29 */ { 8, s_2_29, -1, 1, 0}, -/* 30 */ { 6, s_2_30, -1, 3, 0}, -/* 31 */ { 7, s_2_31, -1, 4, 0}, -/* 32 */ { 9, s_2_32, -1, 1, 0}, -/* 33 */ { 7, s_2_33, -1, 3, 0}, -/* 34 */ { 4, s_2_34, -1, 4, 0}, -/* 35 */ { 4, s_2_35, -1, 5, 0}, -/* 36 */ { 6, s_2_36, 35, 4, 0}, -/* 37 */ { 4, s_2_37, -1, 6, 0}, -/* 38 */ { 4, s_2_38, -1, 5, 0}, -/* 39 */ { 4, s_2_39, -1, 4, 0}, -/* 40 */ { 4, s_2_40, -1, 5, 0}, -/* 41 */ { 4, s_2_41, -1, 6, 0}, -/* 42 */ { 5, s_2_42, -1, 4, 0}, -/* 43 */ { 5, s_2_43, -1, 4, 0}, -/* 44 */ { 5, s_2_44, -1, 5, 0}, -/* 45 */ { 5, s_2_45, -1, 6, 0} +{ 5, s_2_0, -1, 4, 0}, +{ 5, s_2_1, -1, 4, 0}, +{ 5, s_2_2, -1, 5, 0}, +{ 5, s_2_3, -1, 6, 0}, +{ 5, s_2_4, -1, 4, 0}, +{ 6, s_2_5, -1, 5, 0}, +{ 6, s_2_6, -1, 6, 0}, +{ 6, s_2_7, -1, 5, 0}, +{ 6, s_2_8, -1, 6, 0}, +{ 6, s_2_9, -1, 5, 0}, +{ 7, s_2_10, -1, 4, 0}, +{ 9, s_2_11, -1, 1, 0}, +{ 9, s_2_12, -1, 2, 0}, +{ 7, s_2_13, -1, 3, 0}, +{ 5, s_2_14, -1, 4, 0}, +{ 5, s_2_15, -1, 5, 0}, +{ 5, s_2_16, -1, 6, 0}, +{ 5, s_2_17, -1, 4, 0}, +{ 5, s_2_18, -1, 5, 0}, +{ 7, s_2_19, 18, 4, 0}, +{ 5, s_2_20, -1, 6, 0}, +{ 5, s_2_21, -1, 5, 0}, +{ 7, s_2_22, -1, 4, 0}, +{ 9, s_2_23, -1, 1, 0}, +{ 7, s_2_24, -1, 3, 0}, +{ 5, s_2_25, -1, 4, 0}, +{ 5, s_2_26, -1, 5, 0}, +{ 5, s_2_27, -1, 6, 0}, +{ 6, s_2_28, -1, 4, 0}, +{ 8, s_2_29, -1, 1, 0}, +{ 6, s_2_30, -1, 3, 0}, +{ 7, s_2_31, -1, 4, 0}, +{ 9, s_2_32, -1, 1, 0}, +{ 7, s_2_33, -1, 3, 0}, +{ 4, s_2_34, -1, 4, 0}, +{ 4, s_2_35, -1, 5, 0}, +{ 6, s_2_36, 35, 4, 0}, +{ 4, s_2_37, -1, 6, 0}, +{ 4, s_2_38, -1, 5, 0}, +{ 4, s_2_39, -1, 4, 0}, +{ 4, s_2_40, -1, 5, 0}, +{ 4, s_2_41, -1, 6, 0}, +{ 5, s_2_42, -1, 4, 0}, +{ 5, s_2_43, -1, 4, 0}, +{ 5, s_2_44, -1, 5, 0}, +{ 5, s_2_45, -1, 6, 0} }; static const symbol s_3_0[3] = { 'i', 'c', 'a' }; @@ -241,68 +241,68 @@ static const symbol s_3_61[3] = { 'i', 'v', 0xE3 }; static const struct among a_3[62] = { -/* 0 */ { 3, s_3_0, -1, 1, 0}, -/* 1 */ { 5, s_3_1, -1, 1, 0}, -/* 2 */ { 5, s_3_2, -1, 1, 0}, -/* 3 */ { 4, s_3_3, -1, 1, 0}, -/* 4 */ { 3, s_3_4, -1, 1, 0}, -/* 5 */ { 3, s_3_5, -1, 1, 0}, -/* 6 */ { 4, s_3_6, -1, 1, 0}, -/* 7 */ { 4, s_3_7, -1, 3, 0}, -/* 8 */ { 3, s_3_8, -1, 1, 0}, -/* 9 */ { 3, s_3_9, -1, 1, 0}, -/* 10 */ { 2, s_3_10, -1, 1, 0}, -/* 11 */ { 3, s_3_11, -1, 1, 0}, -/* 12 */ { 5, s_3_12, -1, 1, 0}, -/* 13 */ { 5, s_3_13, -1, 1, 0}, -/* 14 */ { 4, s_3_14, -1, 3, 0}, -/* 15 */ { 4, s_3_15, -1, 2, 0}, -/* 16 */ { 4, s_3_16, -1, 1, 0}, -/* 17 */ { 3, s_3_17, -1, 1, 0}, -/* 18 */ { 5, s_3_18, 17, 1, 0}, -/* 19 */ { 3, s_3_19, -1, 1, 0}, -/* 20 */ { 4, s_3_20, -1, 1, 0}, -/* 21 */ { 4, s_3_21, -1, 3, 0}, -/* 22 */ { 3, s_3_22, -1, 1, 0}, -/* 23 */ { 3, s_3_23, -1, 1, 0}, -/* 24 */ { 3, s_3_24, -1, 1, 0}, -/* 25 */ { 5, s_3_25, -1, 1, 0}, -/* 26 */ { 5, s_3_26, -1, 1, 0}, -/* 27 */ { 4, s_3_27, -1, 2, 0}, -/* 28 */ { 5, s_3_28, -1, 1, 0}, -/* 29 */ { 3, s_3_29, -1, 1, 0}, -/* 30 */ { 3, s_3_30, -1, 1, 0}, -/* 31 */ { 5, s_3_31, 30, 1, 0}, -/* 32 */ { 3, s_3_32, -1, 1, 0}, -/* 33 */ { 4, s_3_33, -1, 1, 0}, -/* 34 */ { 4, s_3_34, -1, 3, 0}, -/* 35 */ { 3, s_3_35, -1, 1, 0}, -/* 36 */ { 4, s_3_36, -1, 3, 0}, -/* 37 */ { 3, s_3_37, -1, 1, 0}, -/* 38 */ { 3, s_3_38, -1, 1, 0}, -/* 39 */ { 4, s_3_39, -1, 1, 0}, -/* 40 */ { 5, s_3_40, -1, 1, 0}, -/* 41 */ { 4, s_3_41, -1, 1, 0}, -/* 42 */ { 4, s_3_42, -1, 1, 0}, -/* 43 */ { 3, s_3_43, -1, 3, 0}, -/* 44 */ { 4, s_3_44, -1, 1, 0}, -/* 45 */ { 2, s_3_45, -1, 1, 0}, -/* 46 */ { 2, s_3_46, -1, 1, 0}, -/* 47 */ { 2, s_3_47, -1, 1, 0}, -/* 48 */ { 3, s_3_48, -1, 1, 0}, -/* 49 */ { 3, s_3_49, -1, 3, 0}, -/* 50 */ { 2, s_3_50, -1, 1, 0}, -/* 51 */ { 2, s_3_51, -1, 1, 0}, -/* 52 */ { 3, s_3_52, -1, 1, 0}, -/* 53 */ { 5, s_3_53, -1, 1, 0}, -/* 54 */ { 5, s_3_54, -1, 1, 0}, -/* 55 */ { 4, s_3_55, -1, 1, 0}, -/* 56 */ { 3, s_3_56, -1, 1, 0}, -/* 57 */ { 3, s_3_57, -1, 1, 0}, -/* 58 */ { 4, s_3_58, -1, 1, 0}, -/* 59 */ { 4, s_3_59, -1, 3, 0}, -/* 60 */ { 3, s_3_60, -1, 1, 0}, -/* 61 */ { 3, s_3_61, -1, 1, 0} +{ 3, s_3_0, -1, 1, 0}, +{ 5, s_3_1, -1, 1, 0}, +{ 5, s_3_2, -1, 1, 0}, +{ 4, s_3_3, -1, 1, 0}, +{ 3, s_3_4, -1, 1, 0}, +{ 3, s_3_5, -1, 1, 0}, +{ 4, s_3_6, -1, 1, 0}, +{ 4, s_3_7, -1, 3, 0}, +{ 3, s_3_8, -1, 1, 0}, +{ 3, s_3_9, -1, 1, 0}, +{ 2, s_3_10, -1, 1, 0}, +{ 3, s_3_11, -1, 1, 0}, +{ 5, s_3_12, -1, 1, 0}, +{ 5, s_3_13, -1, 1, 0}, +{ 4, s_3_14, -1, 3, 0}, +{ 4, s_3_15, -1, 2, 0}, +{ 4, s_3_16, -1, 1, 0}, +{ 3, s_3_17, -1, 1, 0}, +{ 5, s_3_18, 17, 1, 0}, +{ 3, s_3_19, -1, 1, 0}, +{ 4, s_3_20, -1, 1, 0}, +{ 4, s_3_21, -1, 3, 0}, +{ 3, s_3_22, -1, 1, 0}, +{ 3, s_3_23, -1, 1, 0}, +{ 3, s_3_24, -1, 1, 0}, +{ 5, s_3_25, -1, 1, 0}, +{ 5, s_3_26, -1, 1, 0}, +{ 4, s_3_27, -1, 2, 0}, +{ 5, s_3_28, -1, 1, 0}, +{ 3, s_3_29, -1, 1, 0}, +{ 3, s_3_30, -1, 1, 0}, +{ 5, s_3_31, 30, 1, 0}, +{ 3, s_3_32, -1, 1, 0}, +{ 4, s_3_33, -1, 1, 0}, +{ 4, s_3_34, -1, 3, 0}, +{ 3, s_3_35, -1, 1, 0}, +{ 4, s_3_36, -1, 3, 0}, +{ 3, s_3_37, -1, 1, 0}, +{ 3, s_3_38, -1, 1, 0}, +{ 4, s_3_39, -1, 1, 0}, +{ 5, s_3_40, -1, 1, 0}, +{ 4, s_3_41, -1, 1, 0}, +{ 4, s_3_42, -1, 1, 0}, +{ 3, s_3_43, -1, 3, 0}, +{ 4, s_3_44, -1, 1, 0}, +{ 2, s_3_45, -1, 1, 0}, +{ 2, s_3_46, -1, 1, 0}, +{ 2, s_3_47, -1, 1, 0}, +{ 3, s_3_48, -1, 1, 0}, +{ 3, s_3_49, -1, 3, 0}, +{ 2, s_3_50, -1, 1, 0}, +{ 2, s_3_51, -1, 1, 0}, +{ 3, s_3_52, -1, 1, 0}, +{ 5, s_3_53, -1, 1, 0}, +{ 5, s_3_54, -1, 1, 0}, +{ 4, s_3_55, -1, 1, 0}, +{ 3, s_3_56, -1, 1, 0}, +{ 3, s_3_57, -1, 1, 0}, +{ 4, s_3_58, -1, 1, 0}, +{ 4, s_3_59, -1, 3, 0}, +{ 3, s_3_60, -1, 1, 0}, +{ 3, s_3_61, -1, 1, 0} }; static const symbol s_4_0[2] = { 'e', 'a' }; @@ -402,100 +402,100 @@ static const symbol s_4_93[4] = { 'e', 'a', 'z', 0xE3 }; static const struct among a_4[94] = { -/* 0 */ { 2, s_4_0, -1, 1, 0}, -/* 1 */ { 2, s_4_1, -1, 1, 0}, -/* 2 */ { 3, s_4_2, -1, 1, 0}, -/* 3 */ { 3, s_4_3, -1, 1, 0}, -/* 4 */ { 3, s_4_4, -1, 1, 0}, -/* 5 */ { 3, s_4_5, -1, 1, 0}, -/* 6 */ { 3, s_4_6, -1, 1, 0}, -/* 7 */ { 3, s_4_7, -1, 1, 0}, -/* 8 */ { 3, s_4_8, -1, 1, 0}, -/* 9 */ { 3, s_4_9, -1, 1, 0}, -/* 10 */ { 2, s_4_10, -1, 2, 0}, -/* 11 */ { 3, s_4_11, 10, 1, 0}, -/* 12 */ { 4, s_4_12, 10, 2, 0}, -/* 13 */ { 3, s_4_13, 10, 1, 0}, -/* 14 */ { 3, s_4_14, 10, 1, 0}, -/* 15 */ { 3, s_4_15, 10, 1, 0}, -/* 16 */ { 4, s_4_16, -1, 1, 0}, -/* 17 */ { 4, s_4_17, -1, 1, 0}, -/* 18 */ { 3, s_4_18, -1, 1, 0}, -/* 19 */ { 2, s_4_19, -1, 1, 0}, -/* 20 */ { 3, s_4_20, 19, 1, 0}, -/* 21 */ { 3, s_4_21, 19, 1, 0}, -/* 22 */ { 3, s_4_22, -1, 2, 0}, -/* 23 */ { 4, s_4_23, -1, 1, 0}, -/* 24 */ { 4, s_4_24, -1, 1, 0}, -/* 25 */ { 2, s_4_25, -1, 1, 0}, -/* 26 */ { 3, s_4_26, -1, 1, 0}, -/* 27 */ { 3, s_4_27, -1, 1, 0}, -/* 28 */ { 4, s_4_28, -1, 2, 0}, -/* 29 */ { 5, s_4_29, 28, 1, 0}, -/* 30 */ { 6, s_4_30, 28, 2, 0}, -/* 31 */ { 5, s_4_31, 28, 1, 0}, -/* 32 */ { 5, s_4_32, 28, 1, 0}, -/* 33 */ { 5, s_4_33, 28, 1, 0}, -/* 34 */ { 3, s_4_34, -1, 1, 0}, -/* 35 */ { 3, s_4_35, -1, 1, 0}, -/* 36 */ { 3, s_4_36, -1, 1, 0}, -/* 37 */ { 2, s_4_37, -1, 1, 0}, -/* 38 */ { 3, s_4_38, -1, 2, 0}, -/* 39 */ { 4, s_4_39, 38, 1, 0}, -/* 40 */ { 4, s_4_40, 38, 1, 0}, -/* 41 */ { 3, s_4_41, -1, 2, 0}, -/* 42 */ { 3, s_4_42, -1, 2, 0}, -/* 43 */ { 3, s_4_43, -1, 2, 0}, -/* 44 */ { 5, s_4_44, -1, 1, 0}, -/* 45 */ { 6, s_4_45, -1, 2, 0}, -/* 46 */ { 7, s_4_46, 45, 1, 0}, -/* 47 */ { 8, s_4_47, 45, 2, 0}, -/* 48 */ { 7, s_4_48, 45, 1, 0}, -/* 49 */ { 7, s_4_49, 45, 1, 0}, -/* 50 */ { 7, s_4_50, 45, 1, 0}, -/* 51 */ { 5, s_4_51, -1, 1, 0}, -/* 52 */ { 5, s_4_52, -1, 1, 0}, -/* 53 */ { 5, s_4_53, -1, 1, 0}, -/* 54 */ { 2, s_4_54, -1, 1, 0}, -/* 55 */ { 3, s_4_55, 54, 1, 0}, -/* 56 */ { 3, s_4_56, 54, 1, 0}, -/* 57 */ { 2, s_4_57, -1, 2, 0}, -/* 58 */ { 4, s_4_58, 57, 1, 0}, -/* 59 */ { 5, s_4_59, 57, 2, 0}, -/* 60 */ { 4, s_4_60, 57, 1, 0}, -/* 61 */ { 4, s_4_61, 57, 1, 0}, -/* 62 */ { 4, s_4_62, 57, 1, 0}, -/* 63 */ { 2, s_4_63, -1, 2, 0}, -/* 64 */ { 2, s_4_64, -1, 2, 0}, -/* 65 */ { 2, s_4_65, -1, 2, 0}, -/* 66 */ { 4, s_4_66, 65, 1, 0}, -/* 67 */ { 5, s_4_67, 65, 2, 0}, -/* 68 */ { 6, s_4_68, 67, 1, 0}, -/* 69 */ { 7, s_4_69, 67, 2, 0}, -/* 70 */ { 6, s_4_70, 67, 1, 0}, -/* 71 */ { 6, s_4_71, 67, 1, 0}, -/* 72 */ { 6, s_4_72, 67, 1, 0}, -/* 73 */ { 4, s_4_73, 65, 1, 0}, -/* 74 */ { 4, s_4_74, 65, 1, 0}, -/* 75 */ { 4, s_4_75, 65, 1, 0}, -/* 76 */ { 2, s_4_76, -1, 1, 0}, -/* 77 */ { 3, s_4_77, 76, 1, 0}, -/* 78 */ { 3, s_4_78, 76, 1, 0}, -/* 79 */ { 4, s_4_79, -1, 1, 0}, -/* 80 */ { 4, s_4_80, -1, 1, 0}, -/* 81 */ { 2, s_4_81, -1, 1, 0}, -/* 82 */ { 5, s_4_82, -1, 1, 0}, -/* 83 */ { 3, s_4_83, -1, 1, 0}, -/* 84 */ { 4, s_4_84, -1, 2, 0}, -/* 85 */ { 5, s_4_85, 84, 1, 0}, -/* 86 */ { 6, s_4_86, 84, 2, 0}, -/* 87 */ { 5, s_4_87, 84, 1, 0}, -/* 88 */ { 5, s_4_88, 84, 1, 0}, -/* 89 */ { 5, s_4_89, 84, 1, 0}, -/* 90 */ { 3, s_4_90, -1, 1, 0}, -/* 91 */ { 3, s_4_91, -1, 1, 0}, -/* 92 */ { 3, s_4_92, -1, 1, 0}, -/* 93 */ { 4, s_4_93, -1, 1, 0} +{ 2, s_4_0, -1, 1, 0}, +{ 2, s_4_1, -1, 1, 0}, +{ 3, s_4_2, -1, 1, 0}, +{ 3, s_4_3, -1, 1, 0}, +{ 3, s_4_4, -1, 1, 0}, +{ 3, s_4_5, -1, 1, 0}, +{ 3, s_4_6, -1, 1, 0}, +{ 3, s_4_7, -1, 1, 0}, +{ 3, s_4_8, -1, 1, 0}, +{ 3, s_4_9, -1, 1, 0}, +{ 2, s_4_10, -1, 2, 0}, +{ 3, s_4_11, 10, 1, 0}, +{ 4, s_4_12, 10, 2, 0}, +{ 3, s_4_13, 10, 1, 0}, +{ 3, s_4_14, 10, 1, 0}, +{ 3, s_4_15, 10, 1, 0}, +{ 4, s_4_16, -1, 1, 0}, +{ 4, s_4_17, -1, 1, 0}, +{ 3, s_4_18, -1, 1, 0}, +{ 2, s_4_19, -1, 1, 0}, +{ 3, s_4_20, 19, 1, 0}, +{ 3, s_4_21, 19, 1, 0}, +{ 3, s_4_22, -1, 2, 0}, +{ 4, s_4_23, -1, 1, 0}, +{ 4, s_4_24, -1, 1, 0}, +{ 2, s_4_25, -1, 1, 0}, +{ 3, s_4_26, -1, 1, 0}, +{ 3, s_4_27, -1, 1, 0}, +{ 4, s_4_28, -1, 2, 0}, +{ 5, s_4_29, 28, 1, 0}, +{ 6, s_4_30, 28, 2, 0}, +{ 5, s_4_31, 28, 1, 0}, +{ 5, s_4_32, 28, 1, 0}, +{ 5, s_4_33, 28, 1, 0}, +{ 3, s_4_34, -1, 1, 0}, +{ 3, s_4_35, -1, 1, 0}, +{ 3, s_4_36, -1, 1, 0}, +{ 2, s_4_37, -1, 1, 0}, +{ 3, s_4_38, -1, 2, 0}, +{ 4, s_4_39, 38, 1, 0}, +{ 4, s_4_40, 38, 1, 0}, +{ 3, s_4_41, -1, 2, 0}, +{ 3, s_4_42, -1, 2, 0}, +{ 3, s_4_43, -1, 2, 0}, +{ 5, s_4_44, -1, 1, 0}, +{ 6, s_4_45, -1, 2, 0}, +{ 7, s_4_46, 45, 1, 0}, +{ 8, s_4_47, 45, 2, 0}, +{ 7, s_4_48, 45, 1, 0}, +{ 7, s_4_49, 45, 1, 0}, +{ 7, s_4_50, 45, 1, 0}, +{ 5, s_4_51, -1, 1, 0}, +{ 5, s_4_52, -1, 1, 0}, +{ 5, s_4_53, -1, 1, 0}, +{ 2, s_4_54, -1, 1, 0}, +{ 3, s_4_55, 54, 1, 0}, +{ 3, s_4_56, 54, 1, 0}, +{ 2, s_4_57, -1, 2, 0}, +{ 4, s_4_58, 57, 1, 0}, +{ 5, s_4_59, 57, 2, 0}, +{ 4, s_4_60, 57, 1, 0}, +{ 4, s_4_61, 57, 1, 0}, +{ 4, s_4_62, 57, 1, 0}, +{ 2, s_4_63, -1, 2, 0}, +{ 2, s_4_64, -1, 2, 0}, +{ 2, s_4_65, -1, 2, 0}, +{ 4, s_4_66, 65, 1, 0}, +{ 5, s_4_67, 65, 2, 0}, +{ 6, s_4_68, 67, 1, 0}, +{ 7, s_4_69, 67, 2, 0}, +{ 6, s_4_70, 67, 1, 0}, +{ 6, s_4_71, 67, 1, 0}, +{ 6, s_4_72, 67, 1, 0}, +{ 4, s_4_73, 65, 1, 0}, +{ 4, s_4_74, 65, 1, 0}, +{ 4, s_4_75, 65, 1, 0}, +{ 2, s_4_76, -1, 1, 0}, +{ 3, s_4_77, 76, 1, 0}, +{ 3, s_4_78, 76, 1, 0}, +{ 4, s_4_79, -1, 1, 0}, +{ 4, s_4_80, -1, 1, 0}, +{ 2, s_4_81, -1, 1, 0}, +{ 5, s_4_82, -1, 1, 0}, +{ 3, s_4_83, -1, 1, 0}, +{ 4, s_4_84, -1, 2, 0}, +{ 5, s_4_85, 84, 1, 0}, +{ 6, s_4_86, 84, 2, 0}, +{ 5, s_4_87, 84, 1, 0}, +{ 5, s_4_88, 84, 1, 0}, +{ 5, s_4_89, 84, 1, 0}, +{ 3, s_4_90, -1, 1, 0}, +{ 3, s_4_91, -1, 1, 0}, +{ 3, s_4_92, -1, 1, 0}, +{ 4, s_4_93, -1, 1, 0} }; static const symbol s_5_0[1] = { 'a' }; @@ -506,11 +506,11 @@ static const symbol s_5_4[1] = { 0xE3 }; static const struct among a_5[5] = { -/* 0 */ { 1, s_5_0, -1, 1, 0}, -/* 1 */ { 1, s_5_1, -1, 1, 0}, -/* 2 */ { 2, s_5_2, 1, 1, 0}, -/* 3 */ { 1, s_5_3, -1, 1, 0}, -/* 4 */ { 1, s_5_4, -1, 1, 0} +{ 1, s_5_0, -1, 1, 0}, +{ 1, s_5_1, -1, 1, 0}, +{ 2, s_5_2, 1, 1, 0}, +{ 1, s_5_3, -1, 1, 0}, +{ 1, s_5_4, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 32 }; @@ -535,30 +535,29 @@ static const symbol s_16[] = { 'i', 't' }; static const symbol s_17[] = { 't' }; static const symbol s_18[] = { 'i', 's', 't' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ -/* repeat, line 32 */ - - while(1) { int c1 = z->c; - while(1) { /* goto, line 32 */ +static int r_prelude(struct SN_env * z) { + while(1) { + int c1 = z->c; + while(1) { int c2 = z->c; - if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; /* grouping v, line 33 */ - z->bra = z->c; /* [, line 33 */ - { int c3 = z->c; /* or, line 33 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab3; /* literal, line 33 */ + if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; + z->bra = z->c; + { int c3 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab3; z->c++; - z->ket = z->c; /* ], line 33 */ - if (in_grouping(z, g_v, 97, 238, 0)) goto lab3; /* grouping v, line 33 */ - { int ret = slice_from_s(z, 1, s_0); /* <-, line 33 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 238, 0)) goto lab3; + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } goto lab2; lab3: z->c = c3; - if (z->c == z->l || z->p[z->c] != 'i') goto lab1; /* literal, line 34 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab1; z->c++; - z->ket = z->c; /* ], line 34 */ - if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; /* grouping v, line 34 */ - { int ret = slice_from_s(z, 1, s_1); /* <-, line 34 */ + z->ket = z->c; + if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } } @@ -568,7 +567,7 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ lab1: z->c = c2; if (z->c >= z->l) goto lab0; - z->c++; /* goto, line 32 */ + z->c++; } continue; lab0: @@ -578,16 +577,16 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 40 */ - z->I[1] = z->l; /* $p1 = , line 41 */ - z->I[2] = z->l; /* $p2 = , line 42 */ - { int c1 = z->c; /* do, line 44 */ - { int c2 = z->c; /* or, line 46 */ - if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; /* grouping v, line 45 */ - { int c3 = z->c; /* or, line 45 */ - if (out_grouping(z, g_v, 97, 238, 0)) goto lab4; /* non v, line 45 */ - { /* gopast */ /* grouping v, line 45 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping(z, g_v, 97, 238, 0)) goto lab4; + { int ret = out_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab4; z->c += ret; @@ -595,8 +594,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; /* grouping v, line 45 */ - { /* gopast */ /* non v, line 45 */ + if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; + { int ret = in_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab2; z->c += ret; @@ -606,10 +605,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 238, 0)) goto lab0; /* non v, line 47 */ - { int c4 = z->c; /* or, line 47 */ - if (out_grouping(z, g_v, 97, 238, 0)) goto lab6; /* non v, line 47 */ - { /* gopast */ /* grouping v, line 47 */ + if (out_grouping(z, g_v, 97, 238, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping(z, g_v, 97, 238, 0)) goto lab6; + { int ret = out_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab6; z->c += ret; @@ -617,71 +616,70 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 238, 0)) goto lab0; /* grouping v, line 47 */ + if (in_grouping(z, g_v, 97, 238, 0)) goto lab0; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 47 */ + z->c++; } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 48 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 50 */ - { /* gopast */ /* grouping v, line 51 */ + { int c5 = z->c; + { int ret = out_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 51 */ + { int ret = in_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 51 */ - { /* gopast */ /* grouping v, line 52 */ + z->I[1] = z->c; + { int ret = out_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 52 */ + { int ret = in_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 52 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 56 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 58 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 58 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 58 */ - switch (among_var) { /* among, line 58 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 59 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 3: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 61 */ + z->c++; break; } continue; @@ -692,70 +690,70 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 68 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 69 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 70 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_step_0(struct SN_env * z) { /* backwardmode */ +static int r_step_0(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 73 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 73 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_1, 16); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 73 */ - { int ret = r_R1(z); /* call R1, line 73 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 73 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 75 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 77 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 81 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 5: - { int m1 = z->l - z->c; (void)m1; /* not, line 83 */ - if (!(eq_s_b(z, 2, s_7))) goto lab0; /* literal, line 83 */ + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 2, s_7))) goto lab0; return 0; lab0: z->c = z->l - m1; } - { int ret = slice_from_s(z, 1, s_8); /* <-, line 83 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_9); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_10); /* <-, line 87 */ + { int ret = slice_from_s(z, 3, s_10); if (ret < 0) return ret; } break; @@ -763,61 +761,60 @@ static int r_step_0(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_combo_suffix(struct SN_env * z) { /* backwardmode */ +static int r_combo_suffix(struct SN_env * z) { int among_var; - { int m_test1 = z->l - z->c; /* test, line 91 */ - z->ket = z->c; /* [, line 92 */ - among_var = find_among_b(z, a_2, 46); /* substring, line 92 */ + { int m_test1 = z->l - z->c; + z->ket = z->c; + among_var = find_among_b(z, a_2, 46); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 92 */ - { int ret = r_R1(z); /* call R1, line 92 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 93 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_13); /* <-, line 107 */ + { int ret = slice_from_s(z, 2, s_13); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_14); /* <-, line 113 */ + { int ret = slice_from_s(z, 2, s_14); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 2, s_15); /* <-, line 118 */ + { int ret = slice_from_s(z, 2, s_15); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 122 */ + { int ret = slice_from_s(z, 2, s_16); if (ret < 0) return ret; } break; } - z->B[0] = 1; /* set standard_suffix_removed, line 125 */ + z->I[3] = 1; z->c = z->l - m_test1; } return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->B[0] = 0; /* unset standard_suffix_removed, line 130 */ -/* repeat, line 131 */ - - while(1) { int m1 = z->l - z->c; (void)m1; - { int ret = r_combo_suffix(z); /* call combo_suffix, line 131 */ + z->I[3] = 0; + while(1) { + int m1 = z->l - z->c; (void)m1; + { int ret = r_combo_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -826,64 +823,64 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ z->c = z->l - m1; break; } - z->ket = z->c; /* [, line 132 */ - among_var = find_among_b(z, a_3, 62); /* substring, line 132 */ + z->ket = z->c; + among_var = find_among_b(z, a_3, 62); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 132 */ - { int ret = r_R2(z); /* call R2, line 132 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 133 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 149 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (z->c <= z->lb || z->p[z->c - 1] != 0xFE) return 0; /* literal, line 152 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xFE) return 0; z->c--; - z->bra = z->c; /* ], line 152 */ - { int ret = slice_from_s(z, 1, s_17); /* <-, line 152 */ + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_17); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 156 */ + { int ret = slice_from_s(z, 3, s_18); if (ret < 0) return ret; } break; } - z->B[0] = 1; /* set standard_suffix_removed, line 160 */ + z->I[3] = 1; return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 164 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 165 */ - among_var = find_among_b(z, a_4, 94); /* substring, line 165 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + among_var = find_among_b(z, a_4, 94); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 165 */ - switch (among_var) { /* among, line 165 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* or, line 200 */ - if (out_grouping_b(z, g_v, 97, 238, 0)) goto lab1; /* non v, line 200 */ + { int m2 = z->l - z->c; (void)m2; + if (out_grouping_b(z, g_v, 97, 238, 0)) goto lab1; goto lab0; lab1: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->lb = mlimit1; return 0; } /* literal, line 200 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->lb = mlimit1; return 0; } z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 200 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 214 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -893,51 +890,51 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 219 */ - if (!(find_among_b(z, a_5, 5))) return 0; /* substring, line 219 */ - z->bra = z->c; /* ], line 219 */ - { int ret = r_RV(z); /* call RV, line 219 */ +static int r_vowel_suffix(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_5, 5))) return 0; + z->bra = z->c; + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 220 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int romanian_ISO_8859_2_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 226 */ - { int ret = r_prelude(z); /* call prelude, line 226 */ +extern int romanian_ISO_8859_2_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 227 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 227 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 228 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 229 */ - { int ret = r_step_0(z); /* call step_0, line 229 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_step_0(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 230 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 230 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_standard_suffix(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 231 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 231 */ - if (!(z->B[0])) goto lab2; /* Boolean test standard_suffix_removed, line 231 */ + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + if (!(z->I[3])) goto lab2; goto lab1; lab2: z->c = z->l - m5; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 231 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -946,15 +943,15 @@ extern int romanian_ISO_8859_2_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m4; } - { int m6 = z->l - z->c; (void)m6; /* do, line 232 */ - { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 232 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_vowel_suffix(z); if (ret < 0) return ret; } z->c = z->l - m6; } z->c = z->lb; - { int c7 = z->c; /* do, line 234 */ - { int ret = r_postlude(z); /* call postlude, line 234 */ + { int c7 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c7; @@ -962,7 +959,7 @@ extern int romanian_ISO_8859_2_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * romanian_ISO_8859_2_create_env(void) { return SN_create_env(0, 3, 1); } +extern struct SN_env * romanian_ISO_8859_2_create_env(void) { return SN_create_env(0, 4); } extern void romanian_ISO_8859_2_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c b/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c index eef4b208e8f4..03c13b83f353 100644 --- a/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c +++ b/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -43,15 +43,15 @@ static const symbol s_0_8[6] = { 0xD9, 0xD7, 0xDB, 0xC9, 0xD3, 0xD8 }; static const struct among a_0[9] = { -/* 0 */ { 3, s_0_0, -1, 1, 0}, -/* 1 */ { 4, s_0_1, 0, 2, 0}, -/* 2 */ { 4, s_0_2, 0, 2, 0}, -/* 3 */ { 1, s_0_3, -1, 1, 0}, -/* 4 */ { 2, s_0_4, 3, 2, 0}, -/* 5 */ { 2, s_0_5, 3, 2, 0}, -/* 6 */ { 5, s_0_6, -1, 1, 0}, -/* 7 */ { 6, s_0_7, 6, 2, 0}, -/* 8 */ { 6, s_0_8, 6, 2, 0} +{ 3, s_0_0, -1, 1, 0}, +{ 4, s_0_1, 0, 2, 0}, +{ 4, s_0_2, 0, 2, 0}, +{ 1, s_0_3, -1, 1, 0}, +{ 2, s_0_4, 3, 2, 0}, +{ 2, s_0_5, 3, 2, 0}, +{ 5, s_0_6, -1, 1, 0}, +{ 6, s_0_7, 6, 2, 0}, +{ 6, s_0_8, 6, 2, 0} }; static const symbol s_1_0[2] = { 0xC0, 0xC0 }; @@ -83,32 +83,32 @@ static const symbol s_1_25[3] = { 0xCF, 0xCD, 0xD5 }; static const struct among a_1[26] = { -/* 0 */ { 2, s_1_0, -1, 1, 0}, -/* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0}, -/* 3 */ { 2, s_1_3, -1, 1, 0}, -/* 4 */ { 2, s_1_4, -1, 1, 0}, -/* 5 */ { 2, s_1_5, -1, 1, 0}, -/* 6 */ { 2, s_1_6, -1, 1, 0}, -/* 7 */ { 2, s_1_7, -1, 1, 0}, -/* 8 */ { 2, s_1_8, -1, 1, 0}, -/* 9 */ { 2, s_1_9, -1, 1, 0}, -/* 10 */ { 3, s_1_10, -1, 1, 0}, -/* 11 */ { 3, s_1_11, -1, 1, 0}, -/* 12 */ { 2, s_1_12, -1, 1, 0}, -/* 13 */ { 2, s_1_13, -1, 1, 0}, -/* 14 */ { 2, s_1_14, -1, 1, 0}, -/* 15 */ { 2, s_1_15, -1, 1, 0}, -/* 16 */ { 2, s_1_16, -1, 1, 0}, -/* 17 */ { 2, s_1_17, -1, 1, 0}, -/* 18 */ { 2, s_1_18, -1, 1, 0}, -/* 19 */ { 2, s_1_19, -1, 1, 0}, -/* 20 */ { 3, s_1_20, -1, 1, 0}, -/* 21 */ { 3, s_1_21, -1, 1, 0}, -/* 22 */ { 2, s_1_22, -1, 1, 0}, -/* 23 */ { 2, s_1_23, -1, 1, 0}, -/* 24 */ { 3, s_1_24, -1, 1, 0}, -/* 25 */ { 3, s_1_25, -1, 1, 0} +{ 2, s_1_0, -1, 1, 0}, +{ 2, s_1_1, -1, 1, 0}, +{ 2, s_1_2, -1, 1, 0}, +{ 2, s_1_3, -1, 1, 0}, +{ 2, s_1_4, -1, 1, 0}, +{ 2, s_1_5, -1, 1, 0}, +{ 2, s_1_6, -1, 1, 0}, +{ 2, s_1_7, -1, 1, 0}, +{ 2, s_1_8, -1, 1, 0}, +{ 2, s_1_9, -1, 1, 0}, +{ 3, s_1_10, -1, 1, 0}, +{ 3, s_1_11, -1, 1, 0}, +{ 2, s_1_12, -1, 1, 0}, +{ 2, s_1_13, -1, 1, 0}, +{ 2, s_1_14, -1, 1, 0}, +{ 2, s_1_15, -1, 1, 0}, +{ 2, s_1_16, -1, 1, 0}, +{ 2, s_1_17, -1, 1, 0}, +{ 2, s_1_18, -1, 1, 0}, +{ 2, s_1_19, -1, 1, 0}, +{ 3, s_1_20, -1, 1, 0}, +{ 3, s_1_21, -1, 1, 0}, +{ 2, s_1_22, -1, 1, 0}, +{ 2, s_1_23, -1, 1, 0}, +{ 3, s_1_24, -1, 1, 0}, +{ 3, s_1_25, -1, 1, 0} }; static const symbol s_2_0[2] = { 0xC5, 0xCD }; @@ -122,14 +122,14 @@ static const symbol s_2_7[3] = { 0xD5, 0xC0, 0xDD }; static const struct among a_2[8] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 2, s_2_1, -1, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 1, 0}, -/* 3 */ { 3, s_2_3, 2, 2, 0}, -/* 4 */ { 3, s_2_4, 2, 2, 0}, -/* 5 */ { 1, s_2_5, -1, 1, 0}, -/* 6 */ { 2, s_2_6, 5, 1, 0}, -/* 7 */ { 3, s_2_7, 6, 2, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 2, s_2_1, -1, 1, 0}, +{ 2, s_2_2, -1, 1, 0}, +{ 3, s_2_3, 2, 2, 0}, +{ 3, s_2_4, 2, 2, 0}, +{ 1, s_2_5, -1, 1, 0}, +{ 2, s_2_6, 5, 1, 0}, +{ 3, s_2_7, 6, 2, 0} }; static const symbol s_3_0[2] = { 0xD3, 0xD1 }; @@ -137,8 +137,8 @@ static const symbol s_3_1[2] = { 0xD3, 0xD8 }; static const struct among a_3[2] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 2, s_3_1, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 2, s_3_1, -1, 1, 0} }; static const symbol s_4_0[1] = { 0xC0 }; @@ -190,52 +190,52 @@ static const symbol s_4_45[3] = { 0xC5, 0xCE, 0xD9 }; static const struct among a_4[46] = { -/* 0 */ { 1, s_4_0, -1, 2, 0}, -/* 1 */ { 2, s_4_1, 0, 2, 0}, -/* 2 */ { 2, s_4_2, -1, 1, 0}, -/* 3 */ { 3, s_4_3, 2, 2, 0}, -/* 4 */ { 3, s_4_4, 2, 2, 0}, -/* 5 */ { 2, s_4_5, -1, 1, 0}, -/* 6 */ { 3, s_4_6, 5, 2, 0}, -/* 7 */ { 3, s_4_7, -1, 1, 0}, -/* 8 */ { 3, s_4_8, -1, 2, 0}, -/* 9 */ { 3, s_4_9, -1, 1, 0}, -/* 10 */ { 4, s_4_10, 9, 2, 0}, -/* 11 */ { 4, s_4_11, 9, 2, 0}, -/* 12 */ { 2, s_4_12, -1, 1, 0}, -/* 13 */ { 3, s_4_13, 12, 2, 0}, -/* 14 */ { 3, s_4_14, 12, 2, 0}, -/* 15 */ { 1, s_4_15, -1, 1, 0}, -/* 16 */ { 2, s_4_16, 15, 2, 0}, -/* 17 */ { 2, s_4_17, 15, 2, 0}, -/* 18 */ { 1, s_4_18, -1, 1, 0}, -/* 19 */ { 2, s_4_19, 18, 2, 0}, -/* 20 */ { 2, s_4_20, 18, 2, 0}, -/* 21 */ { 2, s_4_21, -1, 1, 0}, -/* 22 */ { 2, s_4_22, -1, 2, 0}, -/* 23 */ { 2, s_4_23, -1, 2, 0}, -/* 24 */ { 1, s_4_24, -1, 1, 0}, -/* 25 */ { 2, s_4_25, 24, 2, 0}, -/* 26 */ { 2, s_4_26, -1, 1, 0}, -/* 27 */ { 3, s_4_27, 26, 2, 0}, -/* 28 */ { 3, s_4_28, 26, 2, 0}, -/* 29 */ { 2, s_4_29, -1, 1, 0}, -/* 30 */ { 3, s_4_30, 29, 2, 0}, -/* 31 */ { 3, s_4_31, 29, 1, 0}, -/* 32 */ { 2, s_4_32, -1, 1, 0}, -/* 33 */ { 3, s_4_33, 32, 2, 0}, -/* 34 */ { 2, s_4_34, -1, 1, 0}, -/* 35 */ { 3, s_4_35, 34, 2, 0}, -/* 36 */ { 2, s_4_36, -1, 2, 0}, -/* 37 */ { 2, s_4_37, -1, 2, 0}, -/* 38 */ { 2, s_4_38, -1, 2, 0}, -/* 39 */ { 2, s_4_39, -1, 1, 0}, -/* 40 */ { 3, s_4_40, 39, 2, 0}, -/* 41 */ { 3, s_4_41, 39, 2, 0}, -/* 42 */ { 3, s_4_42, -1, 1, 0}, -/* 43 */ { 3, s_4_43, -1, 2, 0}, -/* 44 */ { 2, s_4_44, -1, 1, 0}, -/* 45 */ { 3, s_4_45, 44, 2, 0} +{ 1, s_4_0, -1, 2, 0}, +{ 2, s_4_1, 0, 2, 0}, +{ 2, s_4_2, -1, 1, 0}, +{ 3, s_4_3, 2, 2, 0}, +{ 3, s_4_4, 2, 2, 0}, +{ 2, s_4_5, -1, 1, 0}, +{ 3, s_4_6, 5, 2, 0}, +{ 3, s_4_7, -1, 1, 0}, +{ 3, s_4_8, -1, 2, 0}, +{ 3, s_4_9, -1, 1, 0}, +{ 4, s_4_10, 9, 2, 0}, +{ 4, s_4_11, 9, 2, 0}, +{ 2, s_4_12, -1, 1, 0}, +{ 3, s_4_13, 12, 2, 0}, +{ 3, s_4_14, 12, 2, 0}, +{ 1, s_4_15, -1, 1, 0}, +{ 2, s_4_16, 15, 2, 0}, +{ 2, s_4_17, 15, 2, 0}, +{ 1, s_4_18, -1, 1, 0}, +{ 2, s_4_19, 18, 2, 0}, +{ 2, s_4_20, 18, 2, 0}, +{ 2, s_4_21, -1, 1, 0}, +{ 2, s_4_22, -1, 2, 0}, +{ 2, s_4_23, -1, 2, 0}, +{ 1, s_4_24, -1, 1, 0}, +{ 2, s_4_25, 24, 2, 0}, +{ 2, s_4_26, -1, 1, 0}, +{ 3, s_4_27, 26, 2, 0}, +{ 3, s_4_28, 26, 2, 0}, +{ 2, s_4_29, -1, 1, 0}, +{ 3, s_4_30, 29, 2, 0}, +{ 3, s_4_31, 29, 1, 0}, +{ 2, s_4_32, -1, 1, 0}, +{ 3, s_4_33, 32, 2, 0}, +{ 2, s_4_34, -1, 1, 0}, +{ 3, s_4_35, 34, 2, 0}, +{ 2, s_4_36, -1, 2, 0}, +{ 2, s_4_37, -1, 2, 0}, +{ 2, s_4_38, -1, 2, 0}, +{ 2, s_4_39, -1, 1, 0}, +{ 3, s_4_40, 39, 2, 0}, +{ 3, s_4_41, 39, 2, 0}, +{ 3, s_4_42, -1, 1, 0}, +{ 3, s_4_43, -1, 2, 0}, +{ 2, s_4_44, -1, 1, 0}, +{ 3, s_4_45, 44, 2, 0} }; static const symbol s_5_0[1] = { 0xC0 }; @@ -277,42 +277,42 @@ static const symbol s_5_35[1] = { 0xD9 }; static const struct among a_5[36] = { -/* 0 */ { 1, s_5_0, -1, 1, 0}, -/* 1 */ { 2, s_5_1, 0, 1, 0}, -/* 2 */ { 2, s_5_2, 0, 1, 0}, -/* 3 */ { 1, s_5_3, -1, 1, 0}, -/* 4 */ { 1, s_5_4, -1, 1, 0}, -/* 5 */ { 2, s_5_5, 4, 1, 0}, -/* 6 */ { 2, s_5_6, 4, 1, 0}, -/* 7 */ { 2, s_5_7, -1, 1, 0}, -/* 8 */ { 2, s_5_8, -1, 1, 0}, -/* 9 */ { 3, s_5_9, 8, 1, 0}, -/* 10 */ { 1, s_5_10, -1, 1, 0}, -/* 11 */ { 2, s_5_11, 10, 1, 0}, -/* 12 */ { 2, s_5_12, 10, 1, 0}, -/* 13 */ { 3, s_5_13, 10, 1, 0}, -/* 14 */ { 3, s_5_14, 10, 1, 0}, -/* 15 */ { 4, s_5_15, 14, 1, 0}, -/* 16 */ { 1, s_5_16, -1, 1, 0}, -/* 17 */ { 2, s_5_17, 16, 1, 0}, -/* 18 */ { 3, s_5_18, 17, 1, 0}, -/* 19 */ { 2, s_5_19, 16, 1, 0}, -/* 20 */ { 2, s_5_20, 16, 1, 0}, -/* 21 */ { 2, s_5_21, -1, 1, 0}, -/* 22 */ { 2, s_5_22, -1, 1, 0}, -/* 23 */ { 3, s_5_23, 22, 1, 0}, -/* 24 */ { 2, s_5_24, -1, 1, 0}, -/* 25 */ { 2, s_5_25, -1, 1, 0}, -/* 26 */ { 3, s_5_26, 25, 1, 0}, -/* 27 */ { 1, s_5_27, -1, 1, 0}, -/* 28 */ { 1, s_5_28, -1, 1, 0}, -/* 29 */ { 2, s_5_29, 28, 1, 0}, -/* 30 */ { 2, s_5_30, 28, 1, 0}, -/* 31 */ { 1, s_5_31, -1, 1, 0}, -/* 32 */ { 2, s_5_32, -1, 1, 0}, -/* 33 */ { 2, s_5_33, -1, 1, 0}, -/* 34 */ { 1, s_5_34, -1, 1, 0}, -/* 35 */ { 1, s_5_35, -1, 1, 0} +{ 1, s_5_0, -1, 1, 0}, +{ 2, s_5_1, 0, 1, 0}, +{ 2, s_5_2, 0, 1, 0}, +{ 1, s_5_3, -1, 1, 0}, +{ 1, s_5_4, -1, 1, 0}, +{ 2, s_5_5, 4, 1, 0}, +{ 2, s_5_6, 4, 1, 0}, +{ 2, s_5_7, -1, 1, 0}, +{ 2, s_5_8, -1, 1, 0}, +{ 3, s_5_9, 8, 1, 0}, +{ 1, s_5_10, -1, 1, 0}, +{ 2, s_5_11, 10, 1, 0}, +{ 2, s_5_12, 10, 1, 0}, +{ 3, s_5_13, 10, 1, 0}, +{ 3, s_5_14, 10, 1, 0}, +{ 4, s_5_15, 14, 1, 0}, +{ 1, s_5_16, -1, 1, 0}, +{ 2, s_5_17, 16, 1, 0}, +{ 3, s_5_18, 17, 1, 0}, +{ 2, s_5_19, 16, 1, 0}, +{ 2, s_5_20, 16, 1, 0}, +{ 2, s_5_21, -1, 1, 0}, +{ 2, s_5_22, -1, 1, 0}, +{ 3, s_5_23, 22, 1, 0}, +{ 2, s_5_24, -1, 1, 0}, +{ 2, s_5_25, -1, 1, 0}, +{ 3, s_5_26, 25, 1, 0}, +{ 1, s_5_27, -1, 1, 0}, +{ 1, s_5_28, -1, 1, 0}, +{ 2, s_5_29, 28, 1, 0}, +{ 2, s_5_30, 28, 1, 0}, +{ 1, s_5_31, -1, 1, 0}, +{ 2, s_5_32, -1, 1, 0}, +{ 2, s_5_33, -1, 1, 0}, +{ 1, s_5_34, -1, 1, 0}, +{ 1, s_5_35, -1, 1, 0} }; static const symbol s_6_0[3] = { 0xCF, 0xD3, 0xD4 }; @@ -320,8 +320,8 @@ static const symbol s_6_1[4] = { 0xCF, 0xD3, 0xD4, 0xD8 }; static const struct among a_6[2] = { -/* 0 */ { 3, s_6_0, -1, 1, 0}, -/* 1 */ { 4, s_6_1, -1, 1, 0} +{ 3, s_6_0, -1, 1, 0}, +{ 4, s_6_1, -1, 1, 0} }; static const symbol s_7_0[4] = { 0xC5, 0xCA, 0xDB, 0xC5 }; @@ -331,78 +331,78 @@ static const symbol s_7_3[3] = { 0xC5, 0xCA, 0xDB }; static const struct among a_7[4] = { -/* 0 */ { 4, s_7_0, -1, 1, 0}, -/* 1 */ { 1, s_7_1, -1, 2, 0}, -/* 2 */ { 1, s_7_2, -1, 3, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0} +{ 4, s_7_0, -1, 1, 0}, +{ 1, s_7_1, -1, 2, 0}, +{ 1, s_7_2, -1, 3, 0}, +{ 3, s_7_3, -1, 1, 0} }; static const unsigned char g_v[] = { 35, 130, 34, 18 }; static const symbol s_0[] = { 0xC5 }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 61 */ - z->I[1] = z->l; /* $p2 = , line 62 */ - { int c1 = z->c; /* do, line 63 */ - { /* gopast */ /* grouping v, line 64 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int ret = out_grouping(z, g_v, 192, 220, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark pV, line 64 */ - { /* gopast */ /* non v, line 64 */ + z->I[1] = z->c; + { int ret = in_grouping(z, g_v, 192, 220, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* grouping v, line 65 */ + { int ret = out_grouping(z, g_v, 192, 220, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 65 */ + { int ret = in_grouping(z, g_v, 192, 220, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 65 */ + z->I[0] = z->c; lab0: z->c = c1; } return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 71 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_perfective_gerund(struct SN_env * z) { /* backwardmode */ +static int r_perfective_gerund(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 74 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((25166336 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 74 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((25166336 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_0, 9); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 74 */ - switch (among_var) { /* among, line 74 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 78 */ - if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab1; /* literal, line 78 */ + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) return 0; /* literal, line 78 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) return 0; z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 78 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 85 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -410,46 +410,46 @@ static int r_perfective_gerund(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_adjective(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 90 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((2271009 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 90 */ +static int r_adjective(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((2271009 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_1, 26))) return 0; - z->bra = z->c; /* ], line 90 */ - { int ret = slice_del(z); /* delete, line 99 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_adjectival(struct SN_env * z) { /* backwardmode */ +static int r_adjectival(struct SN_env * z) { int among_var; - { int ret = r_adjective(z); /* call adjective, line 104 */ + { int ret = r_adjective(z); if (ret <= 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ - z->ket = z->c; /* [, line 112 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((671113216 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } /* substring, line 112 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((671113216 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } among_var = find_among_b(z, a_2, 8); if (!(among_var)) { z->c = z->l - m1; goto lab0; } - z->bra = z->c; /* ], line 112 */ - switch (among_var) { /* among, line 112 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* or, line 117 */ - if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab2; /* literal, line 117 */ + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab2; z->c--; goto lab1; lab2: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) { z->c = z->l - m1; goto lab0; } /* literal, line 117 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) { z->c = z->l - m1; goto lab0; } z->c--; } lab1: - { int ret = slice_del(z); /* delete, line 117 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 124 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -460,42 +460,42 @@ static int r_adjectival(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_reflexive(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 131 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 209 && z->p[z->c - 1] != 216)) return 0; /* substring, line 131 */ +static int r_reflexive(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 209 && z->p[z->c - 1] != 216)) return 0; if (!(find_among_b(z, a_3, 2))) return 0; - z->bra = z->c; /* ], line 131 */ - { int ret = slice_del(z); /* delete, line 134 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_verb(struct SN_env * z) { /* backwardmode */ +static int r_verb(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 139 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((51443235 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 139 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((51443235 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_4, 46); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 139 */ - switch (among_var) { /* among, line 139 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab1; /* literal, line 145 */ + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) return 0; /* literal, line 145 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) return 0; z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 145 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 153 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -503,62 +503,62 @@ static int r_verb(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_noun(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 162 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((60991267 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 162 */ +static int r_noun(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((60991267 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_5, 36))) return 0; - z->bra = z->c; /* ], line 162 */ - { int ret = slice_del(z); /* delete, line 169 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_derivational(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 178 */ - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 212 && z->p[z->c - 1] != 216)) return 0; /* substring, line 178 */ +static int r_derivational(struct SN_env * z) { + z->ket = z->c; + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 212 && z->p[z->c - 1] != 216)) return 0; if (!(find_among_b(z, a_6, 2))) return 0; - z->bra = z->c; /* ], line 178 */ - { int ret = r_R2(z); /* call R2, line 178 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 181 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_tidy_up(struct SN_env * z) { /* backwardmode */ +static int r_tidy_up(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 186 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((151011360 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 186 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((151011360 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_7, 4); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 186 */ - switch (among_var) { /* among, line 186 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 190 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 191 */ - if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; /* literal, line 191 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; z->c--; - z->bra = z->c; /* ], line 191 */ - if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; /* literal, line 191 */ + z->bra = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; z->c--; - { int ret = slice_del(z); /* delete, line 191 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; /* literal, line 194 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; z->c--; - { int ret = slice_del(z); /* delete, line 194 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 196 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -566,25 +566,24 @@ static int r_tidy_up(struct SN_env * z) { /* backwardmode */ return 1; } -extern int russian_KOI8_R_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 205 */ -/* repeat, line 205 */ - - while(1) { int c2 = z->c; - while(1) { /* goto, line 205 */ +extern int russian_KOI8_R_stem(struct SN_env * z) { + { int c1 = z->c; + while(1) { + int c2 = z->c; + while(1) { int c3 = z->c; - z->bra = z->c; /* [, line 205 */ - if (z->c == z->l || z->p[z->c] != 0xA3) goto lab2; /* literal, line 205 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 0xA3) goto lab2; z->c++; - z->ket = z->c; /* ], line 205 */ + z->ket = z->c; z->c = c3; break; lab2: z->c = c3; if (z->c >= z->l) goto lab1; - z->c++; /* goto, line 205 */ + z->c++; } - { int ret = slice_from_s(z, 1, s_0); /* <-, line 205 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } continue; @@ -594,49 +593,49 @@ extern int russian_KOI8_R_stem(struct SN_env * z) { /* forwardmode */ } z->c = c1; } - /* do, line 207 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 207 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 208 */ + z->lb = z->c; z->c = z->l; - { int mlimit4; /* setlimit, line 208 */ - if (z->c < z->I[0]) return 0; - mlimit4 = z->lb; z->lb = z->I[0]; - { int m5 = z->l - z->c; (void)m5; /* do, line 209 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 210 */ - { int ret = r_perfective_gerund(z); /* call perfective_gerund, line 210 */ + { int mlimit4; + if (z->c < z->I[1]) return 0; + mlimit4 = z->lb; z->lb = z->I[1]; + { int m5 = z->l - z->c; (void)m5; + { int m6 = z->l - z->c; (void)m6; + { int ret = r_perfective_gerund(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m6; - { int m7 = z->l - z->c; (void)m7; /* try, line 211 */ - { int ret = r_reflexive(z); /* call reflexive, line 211 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_reflexive(z); if (ret == 0) { z->c = z->l - m7; goto lab6; } if (ret < 0) return ret; } lab6: ; } - { int m8 = z->l - z->c; (void)m8; /* or, line 212 */ - { int ret = r_adjectival(z); /* call adjectival, line 212 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_adjectival(z); if (ret == 0) goto lab8; if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m8; - { int ret = r_verb(z); /* call verb, line 212 */ + { int ret = r_verb(z); if (ret == 0) goto lab9; if (ret < 0) return ret; } goto lab7; lab9: z->c = z->l - m8; - { int ret = r_noun(z); /* call noun, line 212 */ + { int ret = r_noun(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } @@ -648,25 +647,25 @@ extern int russian_KOI8_R_stem(struct SN_env * z) { /* forwardmode */ lab3: z->c = z->l - m5; } - { int m9 = z->l - z->c; (void)m9; /* try, line 215 */ - z->ket = z->c; /* [, line 215 */ - if (z->c <= z->lb || z->p[z->c - 1] != 0xC9) { z->c = z->l - m9; goto lab10; } /* literal, line 215 */ + { int m9 = z->l - z->c; (void)m9; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 0xC9) { z->c = z->l - m9; goto lab10; } z->c--; - z->bra = z->c; /* ], line 215 */ - { int ret = slice_del(z); /* delete, line 215 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab10: ; } - { int m10 = z->l - z->c; (void)m10; /* do, line 218 */ - { int ret = r_derivational(z); /* call derivational, line 218 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_derivational(z); if (ret < 0) return ret; } z->c = z->l - m10; } - { int m11 = z->l - z->c; (void)m11; /* do, line 219 */ - { int ret = r_tidy_up(z); /* call tidy_up, line 219 */ + { int m11 = z->l - z->c; (void)m11; + { int ret = r_tidy_up(z); if (ret < 0) return ret; } z->c = z->l - m11; @@ -677,7 +676,7 @@ extern int russian_KOI8_R_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * russian_KOI8_R_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * russian_KOI8_R_create_env(void) { return SN_create_env(0, 2); } extern void russian_KOI8_R_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_arabic.c b/src/backend/snowball/libstemmer/stem_UTF_8_arabic.c index 701ae2e810e4..52045628714c 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_arabic.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_arabic.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -189,150 +189,150 @@ static const symbol s_0_143[3] = { 0xEF, 0xBB, 0xBC }; static const struct among a_0[144] = { -/* 0 */ { 2, s_0_0, -1, 1, 0}, -/* 1 */ { 2, s_0_1, -1, 1, 0}, -/* 2 */ { 2, s_0_2, -1, 1, 0}, -/* 3 */ { 2, s_0_3, -1, 1, 0}, -/* 4 */ { 2, s_0_4, -1, 1, 0}, -/* 5 */ { 2, s_0_5, -1, 1, 0}, -/* 6 */ { 2, s_0_6, -1, 1, 0}, -/* 7 */ { 2, s_0_7, -1, 1, 0}, -/* 8 */ { 2, s_0_8, -1, 1, 0}, -/* 9 */ { 2, s_0_9, -1, 2, 0}, -/* 10 */ { 2, s_0_10, -1, 3, 0}, -/* 11 */ { 2, s_0_11, -1, 4, 0}, -/* 12 */ { 2, s_0_12, -1, 5, 0}, -/* 13 */ { 2, s_0_13, -1, 6, 0}, -/* 14 */ { 2, s_0_14, -1, 7, 0}, -/* 15 */ { 2, s_0_15, -1, 8, 0}, -/* 16 */ { 2, s_0_16, -1, 9, 0}, -/* 17 */ { 2, s_0_17, -1, 10, 0}, -/* 18 */ { 2, s_0_18, -1, 11, 0}, -/* 19 */ { 3, s_0_19, -1, 12, 0}, -/* 20 */ { 3, s_0_20, -1, 16, 0}, -/* 21 */ { 3, s_0_21, -1, 16, 0}, -/* 22 */ { 3, s_0_22, -1, 13, 0}, -/* 23 */ { 3, s_0_23, -1, 13, 0}, -/* 24 */ { 3, s_0_24, -1, 17, 0}, -/* 25 */ { 3, s_0_25, -1, 17, 0}, -/* 26 */ { 3, s_0_26, -1, 14, 0}, -/* 27 */ { 3, s_0_27, -1, 14, 0}, -/* 28 */ { 3, s_0_28, -1, 15, 0}, -/* 29 */ { 3, s_0_29, -1, 15, 0}, -/* 30 */ { 3, s_0_30, -1, 15, 0}, -/* 31 */ { 3, s_0_31, -1, 15, 0}, -/* 32 */ { 3, s_0_32, -1, 18, 0}, -/* 33 */ { 3, s_0_33, -1, 18, 0}, -/* 34 */ { 3, s_0_34, -1, 19, 0}, -/* 35 */ { 3, s_0_35, -1, 19, 0}, -/* 36 */ { 3, s_0_36, -1, 19, 0}, -/* 37 */ { 3, s_0_37, -1, 19, 0}, -/* 38 */ { 3, s_0_38, -1, 20, 0}, -/* 39 */ { 3, s_0_39, -1, 20, 0}, -/* 40 */ { 3, s_0_40, -1, 21, 0}, -/* 41 */ { 3, s_0_41, -1, 21, 0}, -/* 42 */ { 3, s_0_42, -1, 21, 0}, -/* 43 */ { 3, s_0_43, -1, 21, 0}, -/* 44 */ { 3, s_0_44, -1, 22, 0}, -/* 45 */ { 3, s_0_45, -1, 22, 0}, -/* 46 */ { 3, s_0_46, -1, 22, 0}, -/* 47 */ { 3, s_0_47, -1, 22, 0}, -/* 48 */ { 3, s_0_48, -1, 23, 0}, -/* 49 */ { 3, s_0_49, -1, 23, 0}, -/* 50 */ { 3, s_0_50, -1, 23, 0}, -/* 51 */ { 3, s_0_51, -1, 23, 0}, -/* 52 */ { 3, s_0_52, -1, 24, 0}, -/* 53 */ { 3, s_0_53, -1, 24, 0}, -/* 54 */ { 3, s_0_54, -1, 24, 0}, -/* 55 */ { 3, s_0_55, -1, 24, 0}, -/* 56 */ { 3, s_0_56, -1, 25, 0}, -/* 57 */ { 3, s_0_57, -1, 25, 0}, -/* 58 */ { 3, s_0_58, -1, 25, 0}, -/* 59 */ { 3, s_0_59, -1, 25, 0}, -/* 60 */ { 3, s_0_60, -1, 26, 0}, -/* 61 */ { 3, s_0_61, -1, 26, 0}, -/* 62 */ { 3, s_0_62, -1, 27, 0}, -/* 63 */ { 3, s_0_63, -1, 27, 0}, -/* 64 */ { 3, s_0_64, -1, 28, 0}, -/* 65 */ { 3, s_0_65, -1, 28, 0}, -/* 66 */ { 3, s_0_66, -1, 29, 0}, -/* 67 */ { 3, s_0_67, -1, 29, 0}, -/* 68 */ { 3, s_0_68, -1, 30, 0}, -/* 69 */ { 3, s_0_69, -1, 30, 0}, -/* 70 */ { 3, s_0_70, -1, 30, 0}, -/* 71 */ { 3, s_0_71, -1, 30, 0}, -/* 72 */ { 3, s_0_72, -1, 31, 0}, -/* 73 */ { 3, s_0_73, -1, 31, 0}, -/* 74 */ { 3, s_0_74, -1, 31, 0}, -/* 75 */ { 3, s_0_75, -1, 31, 0}, -/* 76 */ { 3, s_0_76, -1, 32, 0}, -/* 77 */ { 3, s_0_77, -1, 32, 0}, -/* 78 */ { 3, s_0_78, -1, 32, 0}, -/* 79 */ { 3, s_0_79, -1, 32, 0}, -/* 80 */ { 3, s_0_80, -1, 33, 0}, -/* 81 */ { 3, s_0_81, -1, 33, 0}, -/* 82 */ { 3, s_0_82, -1, 33, 0}, -/* 83 */ { 3, s_0_83, -1, 33, 0}, -/* 84 */ { 3, s_0_84, -1, 34, 0}, -/* 85 */ { 3, s_0_85, -1, 34, 0}, -/* 86 */ { 3, s_0_86, -1, 34, 0}, -/* 87 */ { 3, s_0_87, -1, 34, 0}, -/* 88 */ { 3, s_0_88, -1, 35, 0}, -/* 89 */ { 3, s_0_89, -1, 35, 0}, -/* 90 */ { 3, s_0_90, -1, 35, 0}, -/* 91 */ { 3, s_0_91, -1, 35, 0}, -/* 92 */ { 3, s_0_92, -1, 36, 0}, -/* 93 */ { 3, s_0_93, -1, 36, 0}, -/* 94 */ { 3, s_0_94, -1, 36, 0}, -/* 95 */ { 3, s_0_95, -1, 36, 0}, -/* 96 */ { 3, s_0_96, -1, 37, 0}, -/* 97 */ { 3, s_0_97, -1, 37, 0}, -/* 98 */ { 3, s_0_98, -1, 37, 0}, -/* 99 */ { 3, s_0_99, -1, 37, 0}, -/*100 */ { 3, s_0_100, -1, 38, 0}, -/*101 */ { 3, s_0_101, -1, 38, 0}, -/*102 */ { 3, s_0_102, -1, 38, 0}, -/*103 */ { 3, s_0_103, -1, 38, 0}, -/*104 */ { 3, s_0_104, -1, 39, 0}, -/*105 */ { 3, s_0_105, -1, 39, 0}, -/*106 */ { 3, s_0_106, -1, 39, 0}, -/*107 */ { 3, s_0_107, -1, 39, 0}, -/*108 */ { 3, s_0_108, -1, 40, 0}, -/*109 */ { 3, s_0_109, -1, 40, 0}, -/*110 */ { 3, s_0_110, -1, 40, 0}, -/*111 */ { 3, s_0_111, -1, 40, 0}, -/*112 */ { 3, s_0_112, -1, 41, 0}, -/*113 */ { 3, s_0_113, -1, 41, 0}, -/*114 */ { 3, s_0_114, -1, 41, 0}, -/*115 */ { 3, s_0_115, -1, 41, 0}, -/*116 */ { 3, s_0_116, -1, 42, 0}, -/*117 */ { 3, s_0_117, -1, 42, 0}, -/*118 */ { 3, s_0_118, -1, 42, 0}, -/*119 */ { 3, s_0_119, -1, 42, 0}, -/*120 */ { 3, s_0_120, -1, 43, 0}, -/*121 */ { 3, s_0_121, -1, 43, 0}, -/*122 */ { 3, s_0_122, -1, 43, 0}, -/*123 */ { 3, s_0_123, -1, 43, 0}, -/*124 */ { 3, s_0_124, -1, 44, 0}, -/*125 */ { 3, s_0_125, -1, 44, 0}, -/*126 */ { 3, s_0_126, -1, 44, 0}, -/*127 */ { 3, s_0_127, -1, 44, 0}, -/*128 */ { 3, s_0_128, -1, 45, 0}, -/*129 */ { 3, s_0_129, -1, 45, 0}, -/*130 */ { 3, s_0_130, -1, 46, 0}, -/*131 */ { 3, s_0_131, -1, 46, 0}, -/*132 */ { 3, s_0_132, -1, 47, 0}, -/*133 */ { 3, s_0_133, -1, 47, 0}, -/*134 */ { 3, s_0_134, -1, 47, 0}, -/*135 */ { 3, s_0_135, -1, 47, 0}, -/*136 */ { 3, s_0_136, -1, 51, 0}, -/*137 */ { 3, s_0_137, -1, 51, 0}, -/*138 */ { 3, s_0_138, -1, 49, 0}, -/*139 */ { 3, s_0_139, -1, 49, 0}, -/*140 */ { 3, s_0_140, -1, 50, 0}, -/*141 */ { 3, s_0_141, -1, 50, 0}, -/*142 */ { 3, s_0_142, -1, 48, 0}, -/*143 */ { 3, s_0_143, -1, 48, 0} +{ 2, s_0_0, -1, 1, 0}, +{ 2, s_0_1, -1, 1, 0}, +{ 2, s_0_2, -1, 1, 0}, +{ 2, s_0_3, -1, 1, 0}, +{ 2, s_0_4, -1, 1, 0}, +{ 2, s_0_5, -1, 1, 0}, +{ 2, s_0_6, -1, 1, 0}, +{ 2, s_0_7, -1, 1, 0}, +{ 2, s_0_8, -1, 1, 0}, +{ 2, s_0_9, -1, 2, 0}, +{ 2, s_0_10, -1, 3, 0}, +{ 2, s_0_11, -1, 4, 0}, +{ 2, s_0_12, -1, 5, 0}, +{ 2, s_0_13, -1, 6, 0}, +{ 2, s_0_14, -1, 7, 0}, +{ 2, s_0_15, -1, 8, 0}, +{ 2, s_0_16, -1, 9, 0}, +{ 2, s_0_17, -1, 10, 0}, +{ 2, s_0_18, -1, 11, 0}, +{ 3, s_0_19, -1, 12, 0}, +{ 3, s_0_20, -1, 16, 0}, +{ 3, s_0_21, -1, 16, 0}, +{ 3, s_0_22, -1, 13, 0}, +{ 3, s_0_23, -1, 13, 0}, +{ 3, s_0_24, -1, 17, 0}, +{ 3, s_0_25, -1, 17, 0}, +{ 3, s_0_26, -1, 14, 0}, +{ 3, s_0_27, -1, 14, 0}, +{ 3, s_0_28, -1, 15, 0}, +{ 3, s_0_29, -1, 15, 0}, +{ 3, s_0_30, -1, 15, 0}, +{ 3, s_0_31, -1, 15, 0}, +{ 3, s_0_32, -1, 18, 0}, +{ 3, s_0_33, -1, 18, 0}, +{ 3, s_0_34, -1, 19, 0}, +{ 3, s_0_35, -1, 19, 0}, +{ 3, s_0_36, -1, 19, 0}, +{ 3, s_0_37, -1, 19, 0}, +{ 3, s_0_38, -1, 20, 0}, +{ 3, s_0_39, -1, 20, 0}, +{ 3, s_0_40, -1, 21, 0}, +{ 3, s_0_41, -1, 21, 0}, +{ 3, s_0_42, -1, 21, 0}, +{ 3, s_0_43, -1, 21, 0}, +{ 3, s_0_44, -1, 22, 0}, +{ 3, s_0_45, -1, 22, 0}, +{ 3, s_0_46, -1, 22, 0}, +{ 3, s_0_47, -1, 22, 0}, +{ 3, s_0_48, -1, 23, 0}, +{ 3, s_0_49, -1, 23, 0}, +{ 3, s_0_50, -1, 23, 0}, +{ 3, s_0_51, -1, 23, 0}, +{ 3, s_0_52, -1, 24, 0}, +{ 3, s_0_53, -1, 24, 0}, +{ 3, s_0_54, -1, 24, 0}, +{ 3, s_0_55, -1, 24, 0}, +{ 3, s_0_56, -1, 25, 0}, +{ 3, s_0_57, -1, 25, 0}, +{ 3, s_0_58, -1, 25, 0}, +{ 3, s_0_59, -1, 25, 0}, +{ 3, s_0_60, -1, 26, 0}, +{ 3, s_0_61, -1, 26, 0}, +{ 3, s_0_62, -1, 27, 0}, +{ 3, s_0_63, -1, 27, 0}, +{ 3, s_0_64, -1, 28, 0}, +{ 3, s_0_65, -1, 28, 0}, +{ 3, s_0_66, -1, 29, 0}, +{ 3, s_0_67, -1, 29, 0}, +{ 3, s_0_68, -1, 30, 0}, +{ 3, s_0_69, -1, 30, 0}, +{ 3, s_0_70, -1, 30, 0}, +{ 3, s_0_71, -1, 30, 0}, +{ 3, s_0_72, -1, 31, 0}, +{ 3, s_0_73, -1, 31, 0}, +{ 3, s_0_74, -1, 31, 0}, +{ 3, s_0_75, -1, 31, 0}, +{ 3, s_0_76, -1, 32, 0}, +{ 3, s_0_77, -1, 32, 0}, +{ 3, s_0_78, -1, 32, 0}, +{ 3, s_0_79, -1, 32, 0}, +{ 3, s_0_80, -1, 33, 0}, +{ 3, s_0_81, -1, 33, 0}, +{ 3, s_0_82, -1, 33, 0}, +{ 3, s_0_83, -1, 33, 0}, +{ 3, s_0_84, -1, 34, 0}, +{ 3, s_0_85, -1, 34, 0}, +{ 3, s_0_86, -1, 34, 0}, +{ 3, s_0_87, -1, 34, 0}, +{ 3, s_0_88, -1, 35, 0}, +{ 3, s_0_89, -1, 35, 0}, +{ 3, s_0_90, -1, 35, 0}, +{ 3, s_0_91, -1, 35, 0}, +{ 3, s_0_92, -1, 36, 0}, +{ 3, s_0_93, -1, 36, 0}, +{ 3, s_0_94, -1, 36, 0}, +{ 3, s_0_95, -1, 36, 0}, +{ 3, s_0_96, -1, 37, 0}, +{ 3, s_0_97, -1, 37, 0}, +{ 3, s_0_98, -1, 37, 0}, +{ 3, s_0_99, -1, 37, 0}, +{ 3, s_0_100, -1, 38, 0}, +{ 3, s_0_101, -1, 38, 0}, +{ 3, s_0_102, -1, 38, 0}, +{ 3, s_0_103, -1, 38, 0}, +{ 3, s_0_104, -1, 39, 0}, +{ 3, s_0_105, -1, 39, 0}, +{ 3, s_0_106, -1, 39, 0}, +{ 3, s_0_107, -1, 39, 0}, +{ 3, s_0_108, -1, 40, 0}, +{ 3, s_0_109, -1, 40, 0}, +{ 3, s_0_110, -1, 40, 0}, +{ 3, s_0_111, -1, 40, 0}, +{ 3, s_0_112, -1, 41, 0}, +{ 3, s_0_113, -1, 41, 0}, +{ 3, s_0_114, -1, 41, 0}, +{ 3, s_0_115, -1, 41, 0}, +{ 3, s_0_116, -1, 42, 0}, +{ 3, s_0_117, -1, 42, 0}, +{ 3, s_0_118, -1, 42, 0}, +{ 3, s_0_119, -1, 42, 0}, +{ 3, s_0_120, -1, 43, 0}, +{ 3, s_0_121, -1, 43, 0}, +{ 3, s_0_122, -1, 43, 0}, +{ 3, s_0_123, -1, 43, 0}, +{ 3, s_0_124, -1, 44, 0}, +{ 3, s_0_125, -1, 44, 0}, +{ 3, s_0_126, -1, 44, 0}, +{ 3, s_0_127, -1, 44, 0}, +{ 3, s_0_128, -1, 45, 0}, +{ 3, s_0_129, -1, 45, 0}, +{ 3, s_0_130, -1, 46, 0}, +{ 3, s_0_131, -1, 46, 0}, +{ 3, s_0_132, -1, 47, 0}, +{ 3, s_0_133, -1, 47, 0}, +{ 3, s_0_134, -1, 47, 0}, +{ 3, s_0_135, -1, 47, 0}, +{ 3, s_0_136, -1, 51, 0}, +{ 3, s_0_137, -1, 51, 0}, +{ 3, s_0_138, -1, 49, 0}, +{ 3, s_0_139, -1, 49, 0}, +{ 3, s_0_140, -1, 50, 0}, +{ 3, s_0_141, -1, 50, 0}, +{ 3, s_0_142, -1, 48, 0}, +{ 3, s_0_143, -1, 48, 0} }; static const symbol s_1_0[2] = { 0xD8, 0xA2 }; @@ -343,11 +343,11 @@ static const symbol s_1_4[2] = { 0xD8, 0xA6 }; static const struct among a_1[5] = { -/* 0 */ { 2, s_1_0, -1, 1, 0}, -/* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0}, -/* 3 */ { 2, s_1_3, -1, 1, 0}, -/* 4 */ { 2, s_1_4, -1, 1, 0} +{ 2, s_1_0, -1, 1, 0}, +{ 2, s_1_1, -1, 1, 0}, +{ 2, s_1_2, -1, 1, 0}, +{ 2, s_1_3, -1, 1, 0}, +{ 2, s_1_4, -1, 1, 0} }; static const symbol s_2_0[2] = { 0xD8, 0xA2 }; @@ -358,11 +358,11 @@ static const symbol s_2_4[2] = { 0xD8, 0xA6 }; static const struct among a_2[5] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 2, s_2_1, -1, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 2, 0}, -/* 3 */ { 2, s_2_3, -1, 1, 0}, -/* 4 */ { 2, s_2_4, -1, 3, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 2, s_2_1, -1, 1, 0}, +{ 2, s_2_2, -1, 2, 0}, +{ 2, s_2_3, -1, 1, 0}, +{ 2, s_2_4, -1, 3, 0} }; static const symbol s_3_0[4] = { 0xD8, 0xA7, 0xD9, 0x84 }; @@ -372,10 +372,10 @@ static const symbol s_3_3[4] = { 0xD9, 0x84, 0xD9, 0x84 }; static const struct among a_3[4] = { -/* 0 */ { 4, s_3_0, -1, 2, 0}, -/* 1 */ { 6, s_3_1, -1, 1, 0}, -/* 2 */ { 6, s_3_2, -1, 1, 0}, -/* 3 */ { 4, s_3_3, -1, 2, 0} +{ 4, s_3_0, -1, 2, 0}, +{ 6, s_3_1, -1, 1, 0}, +{ 6, s_3_2, -1, 1, 0}, +{ 4, s_3_3, -1, 2, 0} }; static const symbol s_4_0[4] = { 0xD8, 0xA3, 0xD8, 0xA2 }; @@ -386,11 +386,11 @@ static const symbol s_4_4[4] = { 0xD8, 0xA3, 0xD8, 0xA7 }; static const struct among a_4[5] = { -/* 0 */ { 4, s_4_0, -1, 2, 0}, -/* 1 */ { 4, s_4_1, -1, 1, 0}, -/* 2 */ { 4, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 4, 0}, -/* 4 */ { 4, s_4_4, -1, 3, 0} +{ 4, s_4_0, -1, 2, 0}, +{ 4, s_4_1, -1, 1, 0}, +{ 4, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 4, 0}, +{ 4, s_4_4, -1, 3, 0} }; static const symbol s_5_0[2] = { 0xD9, 0x81 }; @@ -398,8 +398,8 @@ static const symbol s_5_1[2] = { 0xD9, 0x88 }; static const struct among a_5[2] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 2, s_5_1, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 2, s_5_1, -1, 1, 0} }; static const symbol s_6_0[4] = { 0xD8, 0xA7, 0xD9, 0x84 }; @@ -409,10 +409,10 @@ static const symbol s_6_3[4] = { 0xD9, 0x84, 0xD9, 0x84 }; static const struct among a_6[4] = { -/* 0 */ { 4, s_6_0, -1, 2, 0}, -/* 1 */ { 6, s_6_1, -1, 1, 0}, -/* 2 */ { 6, s_6_2, -1, 1, 0}, -/* 3 */ { 4, s_6_3, -1, 2, 0} +{ 4, s_6_0, -1, 2, 0}, +{ 6, s_6_1, -1, 1, 0}, +{ 6, s_6_2, -1, 1, 0}, +{ 4, s_6_3, -1, 2, 0} }; static const symbol s_7_0[2] = { 0xD8, 0xA8 }; @@ -421,9 +421,9 @@ static const symbol s_7_2[4] = { 0xD9, 0x83, 0xD9, 0x83 }; static const struct among a_7[3] = { -/* 0 */ { 2, s_7_0, -1, 1, 0}, -/* 1 */ { 4, s_7_1, 0, 2, 0}, -/* 2 */ { 4, s_7_2, -1, 3, 0} +{ 2, s_7_0, -1, 1, 0}, +{ 4, s_7_1, 0, 2, 0}, +{ 4, s_7_2, -1, 3, 0} }; static const symbol s_8_0[4] = { 0xD8, 0xB3, 0xD8, 0xA3 }; @@ -433,10 +433,10 @@ static const symbol s_8_3[4] = { 0xD8, 0xB3, 0xD9, 0x8A }; static const struct among a_8[4] = { -/* 0 */ { 4, s_8_0, -1, 4, 0}, -/* 1 */ { 4, s_8_1, -1, 2, 0}, -/* 2 */ { 4, s_8_2, -1, 3, 0}, -/* 3 */ { 4, s_8_3, -1, 1, 0} +{ 4, s_8_0, -1, 4, 0}, +{ 4, s_8_1, -1, 2, 0}, +{ 4, s_8_2, -1, 3, 0}, +{ 4, s_8_3, -1, 1, 0} }; static const symbol s_9_0[6] = { 0xD8, 0xAA, 0xD8, 0xB3, 0xD8, 0xAA }; @@ -445,9 +445,9 @@ static const symbol s_9_2[6] = { 0xD9, 0x8A, 0xD8, 0xB3, 0xD8, 0xAA }; static const struct among a_9[3] = { -/* 0 */ { 6, s_9_0, -1, 1, 0}, -/* 1 */ { 6, s_9_1, -1, 1, 0}, -/* 2 */ { 6, s_9_2, -1, 1, 0} +{ 6, s_9_0, -1, 1, 0}, +{ 6, s_9_1, -1, 1, 0}, +{ 6, s_9_2, -1, 1, 0} }; static const symbol s_10_0[2] = { 0xD9, 0x83 }; @@ -463,23 +463,23 @@ static const symbol s_10_9[4] = { 0xD9, 0x87, 0xD8, 0xA7 }; static const struct among a_10[10] = { -/* 0 */ { 2, s_10_0, -1, 1, 0}, -/* 1 */ { 4, s_10_1, -1, 2, 0}, -/* 2 */ { 4, s_10_2, -1, 2, 0}, -/* 3 */ { 4, s_10_3, -1, 2, 0}, -/* 4 */ { 2, s_10_4, -1, 1, 0}, -/* 5 */ { 2, s_10_5, -1, 1, 0}, -/* 6 */ { 6, s_10_6, -1, 3, 0}, -/* 7 */ { 6, s_10_7, -1, 3, 0}, -/* 8 */ { 4, s_10_8, -1, 2, 0}, -/* 9 */ { 4, s_10_9, -1, 2, 0} +{ 2, s_10_0, -1, 1, 0}, +{ 4, s_10_1, -1, 2, 0}, +{ 4, s_10_2, -1, 2, 0}, +{ 4, s_10_3, -1, 2, 0}, +{ 2, s_10_4, -1, 1, 0}, +{ 2, s_10_5, -1, 1, 0}, +{ 6, s_10_6, -1, 3, 0}, +{ 6, s_10_7, -1, 3, 0}, +{ 4, s_10_8, -1, 2, 0}, +{ 4, s_10_9, -1, 2, 0} }; static const symbol s_11_0[2] = { 0xD9, 0x86 }; static const struct among a_11[1] = { -/* 0 */ { 2, s_11_0, -1, 1, 0} +{ 2, s_11_0, -1, 1, 0} }; static const symbol s_12_0[2] = { 0xD9, 0x88 }; @@ -488,37 +488,37 @@ static const symbol s_12_2[2] = { 0xD8, 0xA7 }; static const struct among a_12[3] = { -/* 0 */ { 2, s_12_0, -1, 1, 0}, -/* 1 */ { 2, s_12_1, -1, 1, 0}, -/* 2 */ { 2, s_12_2, -1, 1, 0} +{ 2, s_12_0, -1, 1, 0}, +{ 2, s_12_1, -1, 1, 0}, +{ 2, s_12_2, -1, 1, 0} }; static const symbol s_13_0[4] = { 0xD8, 0xA7, 0xD8, 0xAA }; static const struct among a_13[1] = { -/* 0 */ { 4, s_13_0, -1, 1, 0} +{ 4, s_13_0, -1, 1, 0} }; static const symbol s_14_0[2] = { 0xD8, 0xAA }; static const struct among a_14[1] = { -/* 0 */ { 2, s_14_0, -1, 1, 0} +{ 2, s_14_0, -1, 1, 0} }; static const symbol s_15_0[2] = { 0xD8, 0xA9 }; static const struct among a_15[1] = { -/* 0 */ { 2, s_15_0, -1, 1, 0} +{ 2, s_15_0, -1, 1, 0} }; static const symbol s_16_0[2] = { 0xD9, 0x8A }; static const struct among a_16[1] = { -/* 0 */ { 2, s_16_0, -1, 1, 0} +{ 2, s_16_0, -1, 1, 0} }; static const symbol s_17_0[2] = { 0xD9, 0x83 }; @@ -536,18 +536,18 @@ static const symbol s_17_11[4] = { 0xD9, 0x87, 0xD8, 0xA7 }; static const struct among a_17[12] = { -/* 0 */ { 2, s_17_0, -1, 1, 0}, -/* 1 */ { 4, s_17_1, -1, 2, 0}, -/* 2 */ { 4, s_17_2, -1, 2, 0}, -/* 3 */ { 4, s_17_3, -1, 2, 0}, -/* 4 */ { 4, s_17_4, -1, 2, 0}, -/* 5 */ { 2, s_17_5, -1, 1, 0}, -/* 6 */ { 6, s_17_6, -1, 3, 0}, -/* 7 */ { 4, s_17_7, -1, 2, 0}, -/* 8 */ { 6, s_17_8, -1, 3, 0}, -/* 9 */ { 6, s_17_9, -1, 3, 0}, -/* 10 */ { 4, s_17_10, -1, 2, 0}, -/* 11 */ { 4, s_17_11, -1, 2, 0} +{ 2, s_17_0, -1, 1, 0}, +{ 4, s_17_1, -1, 2, 0}, +{ 4, s_17_2, -1, 2, 0}, +{ 4, s_17_3, -1, 2, 0}, +{ 4, s_17_4, -1, 2, 0}, +{ 2, s_17_5, -1, 1, 0}, +{ 6, s_17_6, -1, 3, 0}, +{ 4, s_17_7, -1, 2, 0}, +{ 6, s_17_8, -1, 3, 0}, +{ 6, s_17_9, -1, 3, 0}, +{ 4, s_17_10, -1, 2, 0}, +{ 4, s_17_11, -1, 2, 0} }; static const symbol s_18_0[2] = { 0xD9, 0x86 }; @@ -564,17 +564,17 @@ static const symbol s_18_10[2] = { 0xD8, 0xAA }; static const struct among a_18[11] = { -/* 0 */ { 2, s_18_0, -1, 1, 0}, -/* 1 */ { 4, s_18_1, 0, 3, 0}, -/* 2 */ { 4, s_18_2, 0, 3, 0}, -/* 3 */ { 4, s_18_3, 0, 3, 0}, -/* 4 */ { 4, s_18_4, 0, 2, 0}, -/* 5 */ { 2, s_18_5, -1, 1, 0}, -/* 6 */ { 2, s_18_6, -1, 1, 0}, -/* 7 */ { 6, s_18_7, 6, 4, 0}, -/* 8 */ { 4, s_18_8, 6, 2, 0}, -/* 9 */ { 4, s_18_9, 6, 2, 0}, -/* 10 */ { 2, s_18_10, -1, 1, 0} +{ 2, s_18_0, -1, 1, 0}, +{ 4, s_18_1, 0, 3, 0}, +{ 4, s_18_2, 0, 3, 0}, +{ 4, s_18_3, 0, 3, 0}, +{ 4, s_18_4, 0, 2, 0}, +{ 2, s_18_5, -1, 1, 0}, +{ 2, s_18_6, -1, 1, 0}, +{ 6, s_18_7, 6, 4, 0}, +{ 4, s_18_8, 6, 2, 0}, +{ 4, s_18_9, 6, 2, 0}, +{ 2, s_18_10, -1, 1, 0} }; static const symbol s_19_0[4] = { 0xD8, 0xAA, 0xD9, 0x85 }; @@ -582,8 +582,8 @@ static const symbol s_19_1[4] = { 0xD9, 0x88, 0xD8, 0xA7 }; static const struct among a_19[2] = { -/* 0 */ { 4, s_19_0, -1, 1, 0}, -/* 1 */ { 4, s_19_1, -1, 1, 0} +{ 4, s_19_0, -1, 1, 0}, +{ 4, s_19_1, -1, 1, 0} }; static const symbol s_20_0[2] = { 0xD9, 0x88 }; @@ -591,15 +591,15 @@ static const symbol s_20_1[6] = { 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x88 }; static const struct among a_20[2] = { -/* 0 */ { 2, s_20_0, -1, 1, 0}, -/* 1 */ { 6, s_20_1, 0, 2, 0} +{ 2, s_20_0, -1, 1, 0}, +{ 6, s_20_1, 0, 2, 0} }; static const symbol s_21_0[2] = { 0xD9, 0x89 }; static const struct among a_21[1] = { -/* 0 */ { 2, s_21_0, -1, 1, 0} +{ 2, s_21_0, -1, 1, 0} }; static const symbol s_0[] = { '0' }; @@ -672,270 +672,269 @@ static const symbol s_66[] = { 0xD8, 0xA3 }; static const symbol s_67[] = { 0xD8, 0xA7, 0xD8, 0xB3, 0xD8, 0xAA }; static const symbol s_68[] = { 0xD9, 0x8A }; -static int r_Normalize_pre(struct SN_env * z) { /* forwardmode */ +static int r_Normalize_pre(struct SN_env * z) { int among_var; - { int c1 = z->c; /* do, line 247 */ -/* repeat, line 247 */ - - while(1) { int c2 = z->c; - { int c3 = z->c; /* or, line 311 */ - z->bra = z->c; /* [, line 249 */ - among_var = find_among(z, a_0, 144); /* substring, line 249 */ + { int c1 = z->c; + while(1) { + int c2 = z->c; + { int c3 = z->c; + z->bra = z->c; + among_var = find_among(z, a_0, 144); if (!(among_var)) goto lab3; - z->ket = z->c; /* ], line 249 */ - switch (among_var) { /* among, line 249 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 250 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 254 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 255 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 256 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 257 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 258 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 259 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 260 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 261 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 262 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 263 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 2, s_10); /* <-, line 266 */ + { int ret = slice_from_s(z, 2, s_10); if (ret < 0) return ret; } break; case 13: - { int ret = slice_from_s(z, 2, s_11); /* <-, line 267 */ + { int ret = slice_from_s(z, 2, s_11); if (ret < 0) return ret; } break; case 14: - { int ret = slice_from_s(z, 2, s_12); /* <-, line 268 */ + { int ret = slice_from_s(z, 2, s_12); if (ret < 0) return ret; } break; case 15: - { int ret = slice_from_s(z, 2, s_13); /* <-, line 269 */ + { int ret = slice_from_s(z, 2, s_13); if (ret < 0) return ret; } break; case 16: - { int ret = slice_from_s(z, 2, s_14); /* <-, line 270 */ + { int ret = slice_from_s(z, 2, s_14); if (ret < 0) return ret; } break; case 17: - { int ret = slice_from_s(z, 2, s_15); /* <-, line 271 */ + { int ret = slice_from_s(z, 2, s_15); if (ret < 0) return ret; } break; case 18: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 272 */ + { int ret = slice_from_s(z, 2, s_16); if (ret < 0) return ret; } break; case 19: - { int ret = slice_from_s(z, 2, s_17); /* <-, line 273 */ + { int ret = slice_from_s(z, 2, s_17); if (ret < 0) return ret; } break; case 20: - { int ret = slice_from_s(z, 2, s_18); /* <-, line 274 */ + { int ret = slice_from_s(z, 2, s_18); if (ret < 0) return ret; } break; case 21: - { int ret = slice_from_s(z, 2, s_19); /* <-, line 275 */ + { int ret = slice_from_s(z, 2, s_19); if (ret < 0) return ret; } break; case 22: - { int ret = slice_from_s(z, 2, s_20); /* <-, line 276 */ + { int ret = slice_from_s(z, 2, s_20); if (ret < 0) return ret; } break; case 23: - { int ret = slice_from_s(z, 2, s_21); /* <-, line 277 */ + { int ret = slice_from_s(z, 2, s_21); if (ret < 0) return ret; } break; case 24: - { int ret = slice_from_s(z, 2, s_22); /* <-, line 278 */ + { int ret = slice_from_s(z, 2, s_22); if (ret < 0) return ret; } break; case 25: - { int ret = slice_from_s(z, 2, s_23); /* <-, line 279 */ + { int ret = slice_from_s(z, 2, s_23); if (ret < 0) return ret; } break; case 26: - { int ret = slice_from_s(z, 2, s_24); /* <-, line 280 */ + { int ret = slice_from_s(z, 2, s_24); if (ret < 0) return ret; } break; case 27: - { int ret = slice_from_s(z, 2, s_25); /* <-, line 281 */ + { int ret = slice_from_s(z, 2, s_25); if (ret < 0) return ret; } break; case 28: - { int ret = slice_from_s(z, 2, s_26); /* <-, line 282 */ + { int ret = slice_from_s(z, 2, s_26); if (ret < 0) return ret; } break; case 29: - { int ret = slice_from_s(z, 2, s_27); /* <-, line 283 */ + { int ret = slice_from_s(z, 2, s_27); if (ret < 0) return ret; } break; case 30: - { int ret = slice_from_s(z, 2, s_28); /* <-, line 284 */ + { int ret = slice_from_s(z, 2, s_28); if (ret < 0) return ret; } break; case 31: - { int ret = slice_from_s(z, 2, s_29); /* <-, line 285 */ + { int ret = slice_from_s(z, 2, s_29); if (ret < 0) return ret; } break; case 32: - { int ret = slice_from_s(z, 2, s_30); /* <-, line 286 */ + { int ret = slice_from_s(z, 2, s_30); if (ret < 0) return ret; } break; case 33: - { int ret = slice_from_s(z, 2, s_31); /* <-, line 287 */ + { int ret = slice_from_s(z, 2, s_31); if (ret < 0) return ret; } break; case 34: - { int ret = slice_from_s(z, 2, s_32); /* <-, line 288 */ + { int ret = slice_from_s(z, 2, s_32); if (ret < 0) return ret; } break; case 35: - { int ret = slice_from_s(z, 2, s_33); /* <-, line 289 */ + { int ret = slice_from_s(z, 2, s_33); if (ret < 0) return ret; } break; case 36: - { int ret = slice_from_s(z, 2, s_34); /* <-, line 290 */ + { int ret = slice_from_s(z, 2, s_34); if (ret < 0) return ret; } break; case 37: - { int ret = slice_from_s(z, 2, s_35); /* <-, line 291 */ + { int ret = slice_from_s(z, 2, s_35); if (ret < 0) return ret; } break; case 38: - { int ret = slice_from_s(z, 2, s_36); /* <-, line 292 */ + { int ret = slice_from_s(z, 2, s_36); if (ret < 0) return ret; } break; case 39: - { int ret = slice_from_s(z, 2, s_37); /* <-, line 293 */ + { int ret = slice_from_s(z, 2, s_37); if (ret < 0) return ret; } break; case 40: - { int ret = slice_from_s(z, 2, s_38); /* <-, line 294 */ + { int ret = slice_from_s(z, 2, s_38); if (ret < 0) return ret; } break; case 41: - { int ret = slice_from_s(z, 2, s_39); /* <-, line 295 */ + { int ret = slice_from_s(z, 2, s_39); if (ret < 0) return ret; } break; case 42: - { int ret = slice_from_s(z, 2, s_40); /* <-, line 296 */ + { int ret = slice_from_s(z, 2, s_40); if (ret < 0) return ret; } break; case 43: - { int ret = slice_from_s(z, 2, s_41); /* <-, line 297 */ + { int ret = slice_from_s(z, 2, s_41); if (ret < 0) return ret; } break; case 44: - { int ret = slice_from_s(z, 2, s_42); /* <-, line 298 */ + { int ret = slice_from_s(z, 2, s_42); if (ret < 0) return ret; } break; case 45: - { int ret = slice_from_s(z, 2, s_43); /* <-, line 299 */ + { int ret = slice_from_s(z, 2, s_43); if (ret < 0) return ret; } break; case 46: - { int ret = slice_from_s(z, 2, s_44); /* <-, line 300 */ + { int ret = slice_from_s(z, 2, s_44); if (ret < 0) return ret; } break; case 47: - { int ret = slice_from_s(z, 2, s_45); /* <-, line 301 */ + { int ret = slice_from_s(z, 2, s_45); if (ret < 0) return ret; } break; case 48: - { int ret = slice_from_s(z, 4, s_46); /* <-, line 304 */ + { int ret = slice_from_s(z, 4, s_46); if (ret < 0) return ret; } break; case 49: - { int ret = slice_from_s(z, 4, s_47); /* <-, line 305 */ + { int ret = slice_from_s(z, 4, s_47); if (ret < 0) return ret; } break; case 50: - { int ret = slice_from_s(z, 4, s_48); /* <-, line 306 */ + { int ret = slice_from_s(z, 4, s_48); if (ret < 0) return ret; } break; case 51: - { int ret = slice_from_s(z, 4, s_49); /* <-, line 307 */ + { int ret = slice_from_s(z, 4, s_49); if (ret < 0) return ret; } break; @@ -943,9 +942,9 @@ static int r_Normalize_pre(struct SN_env * z) { /* forwardmode */ goto lab2; lab3: z->c = c3; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab1; - z->c = ret; /* next, line 312 */ + z->c = ret; } } lab2: @@ -959,45 +958,44 @@ static int r_Normalize_pre(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_Normalize_post(struct SN_env * z) { /* forwardmode */ +static int r_Normalize_post(struct SN_env * z) { int among_var; - { int c1 = z->c; /* do, line 318 */ - z->lb = z->c; z->c = z->l; /* backwards, line 320 */ + { int c1 = z->c; + z->lb = z->c; z->c = z->l; - z->ket = z->c; /* [, line 321 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((124 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 321 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((124 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; if (!(find_among_b(z, a_1, 5))) goto lab0; - z->bra = z->c; /* ], line 321 */ - { int ret = slice_from_s(z, 2, s_50); /* <-, line 322 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_50); if (ret < 0) return ret; } z->c = z->lb; lab0: z->c = c1; } - { int c2 = z->c; /* do, line 329 */ -/* repeat, line 329 */ - - while(1) { int c3 = z->c; - { int c4 = z->c; /* or, line 338 */ - z->bra = z->c; /* [, line 332 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((124 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab4; /* substring, line 332 */ + { int c2 = z->c; + while(1) { + int c3 = z->c; + { int c4 = z->c; + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((124 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab4; among_var = find_among(z, a_2, 5); if (!(among_var)) goto lab4; - z->ket = z->c; /* ], line 332 */ - switch (among_var) { /* among, line 332 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_51); /* <-, line 333 */ + { int ret = slice_from_s(z, 2, s_51); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_52); /* <-, line 334 */ + { int ret = slice_from_s(z, 2, s_52); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_53); /* <-, line 335 */ + { int ret = slice_from_s(z, 2, s_53); if (ret < 0) return ret; } break; @@ -1005,9 +1003,9 @@ static int r_Normalize_post(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c4; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab2; - z->c = ret; /* next, line 339 */ + z->c = ret; } } lab3: @@ -1021,59 +1019,59 @@ static int r_Normalize_post(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_Checks1(struct SN_env * z) { /* forwardmode */ +static int r_Checks1(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 345 */ - if (z->c + 3 >= z->l || (z->p[z->c + 3] != 132 && z->p[z->c + 3] != 167)) return 0; /* substring, line 345 */ + z->bra = z->c; + if (z->c + 3 >= z->l || (z->p[z->c + 3] != 132 && z->p[z->c + 3] != 167)) return 0; among_var = find_among(z, a_3, 4); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 345 */ - switch (among_var) { /* among, line 345 */ + z->ket = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 346 */ - z->B[0] = 1; /* set is_noun, line 346 */ - z->B[1] = 0; /* unset is_verb, line 346 */ - z->B[2] = 1; /* set is_defined, line 346 */ + if (!(len_utf8(z->p) > 4)) return 0; + z->I[2] = 1; + z->I[1] = 0; + z->I[0] = 1; break; case 2: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 347 */ - z->B[0] = 1; /* set is_noun, line 347 */ - z->B[1] = 0; /* unset is_verb, line 347 */ - z->B[2] = 1; /* set is_defined, line 347 */ + if (!(len_utf8(z->p) > 3)) return 0; + z->I[2] = 1; + z->I[1] = 0; + z->I[0] = 1; break; } return 1; } -static int r_Prefix_Step1(struct SN_env * z) { /* forwardmode */ +static int r_Prefix_Step1(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 354 */ - if (z->c + 3 >= z->l || z->p[z->c + 3] >> 5 != 5 || !((188 >> (z->p[z->c + 3] & 0x1f)) & 1)) return 0; /* substring, line 354 */ + z->bra = z->c; + if (z->c + 3 >= z->l || z->p[z->c + 3] >> 5 != 5 || !((188 >> (z->p[z->c + 3] & 0x1f)) & 1)) return 0; among_var = find_among(z, a_4, 5); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 354 */ - switch (among_var) { /* among, line 354 */ + z->ket = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 355 */ - { int ret = slice_from_s(z, 2, s_54); /* <-, line 355 */ + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_from_s(z, 2, s_54); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 356 */ - { int ret = slice_from_s(z, 2, s_55); /* <-, line 356 */ + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_from_s(z, 2, s_55); if (ret < 0) return ret; } break; case 3: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 358 */ - { int ret = slice_from_s(z, 2, s_56); /* <-, line 358 */ + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_from_s(z, 2, s_56); if (ret < 0) return ret; } break; case 4: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 359 */ - { int ret = slice_from_s(z, 2, s_57); /* <-, line 359 */ + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_from_s(z, 2, s_57); if (ret < 0) return ret; } break; @@ -1081,47 +1079,47 @@ static int r_Prefix_Step1(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_Prefix_Step2(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* not, line 365 */ - if (!(eq_s(z, 4, s_58))) goto lab0; /* literal, line 365 */ +static int r_Prefix_Step2(struct SN_env * z) { + { int c1 = z->c; + if (!(eq_s(z, 4, s_58))) goto lab0; return 0; lab0: z->c = c1; } - { int c2 = z->c; /* not, line 366 */ - if (!(eq_s(z, 4, s_59))) goto lab1; /* literal, line 366 */ + { int c2 = z->c; + if (!(eq_s(z, 4, s_59))) goto lab1; return 0; lab1: z->c = c2; } - z->bra = z->c; /* [, line 367 */ - if (z->c + 1 >= z->l || (z->p[z->c + 1] != 129 && z->p[z->c + 1] != 136)) return 0; /* substring, line 367 */ + z->bra = z->c; + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 129 && z->p[z->c + 1] != 136)) return 0; if (!(find_among(z, a_5, 2))) return 0; - z->ket = z->c; /* ], line 367 */ - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 368 */ - { int ret = slice_del(z); /* delete, line 368 */ + z->ket = z->c; + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Prefix_Step3a_Noun(struct SN_env * z) { /* forwardmode */ +static int r_Prefix_Step3a_Noun(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 374 */ - if (z->c + 3 >= z->l || (z->p[z->c + 3] != 132 && z->p[z->c + 3] != 167)) return 0; /* substring, line 374 */ + z->bra = z->c; + if (z->c + 3 >= z->l || (z->p[z->c + 3] != 132 && z->p[z->c + 3] != 167)) return 0; among_var = find_among(z, a_6, 4); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 374 */ - switch (among_var) { /* among, line 374 */ + z->ket = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) > 5)) return 0; /* $( > ), line 375 */ - { int ret = slice_del(z); /* delete, line 375 */ + if (!(len_utf8(z->p) > 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 376 */ - { int ret = slice_del(z); /* delete, line 376 */ + if (!(len_utf8(z->p) > 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1129,35 +1127,35 @@ static int r_Prefix_Step3a_Noun(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_Prefix_Step3b_Noun(struct SN_env * z) { /* forwardmode */ +static int r_Prefix_Step3b_Noun(struct SN_env * z) { int among_var; - { int c1 = z->c; /* not, line 381 */ - if (!(eq_s(z, 4, s_60))) goto lab0; /* literal, line 381 */ + { int c1 = z->c; + if (!(eq_s(z, 4, s_60))) goto lab0; return 0; lab0: z->c = c1; } - z->bra = z->c; /* [, line 382 */ - if (z->c + 1 >= z->l || (z->p[z->c + 1] != 168 && z->p[z->c + 1] != 131)) return 0; /* substring, line 382 */ + z->bra = z->c; + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 168 && z->p[z->c + 1] != 131)) return 0; among_var = find_among(z, a_7, 3); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 382 */ - switch (among_var) { /* among, line 382 */ + z->ket = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 383 */ - { int ret = slice_del(z); /* delete, line 383 */ + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 385 */ - { int ret = slice_from_s(z, 2, s_61); /* <-, line 385 */ + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_from_s(z, 2, s_61); if (ret < 0) return ret; } break; case 3: - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 386 */ - { int ret = slice_from_s(z, 2, s_62); /* <-, line 386 */ + if (!(len_utf8(z->p) > 3)) return 0; + { int ret = slice_from_s(z, 2, s_62); if (ret < 0) return ret; } break; @@ -1165,34 +1163,34 @@ static int r_Prefix_Step3b_Noun(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_Prefix_Step3_Verb(struct SN_env * z) { /* forwardmode */ +static int r_Prefix_Step3_Verb(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 392 */ - among_var = find_among(z, a_8, 4); /* substring, line 392 */ + z->bra = z->c; + among_var = find_among(z, a_8, 4); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 392 */ - switch (among_var) { /* among, line 392 */ + z->ket = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 394 */ - { int ret = slice_from_s(z, 2, s_63); /* <-, line 394 */ + if (!(len_utf8(z->p) > 4)) return 0; + { int ret = slice_from_s(z, 2, s_63); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 395 */ - { int ret = slice_from_s(z, 2, s_64); /* <-, line 395 */ + if (!(len_utf8(z->p) > 4)) return 0; + { int ret = slice_from_s(z, 2, s_64); if (ret < 0) return ret; } break; case 3: - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 396 */ - { int ret = slice_from_s(z, 2, s_65); /* <-, line 396 */ + if (!(len_utf8(z->p) > 4)) return 0; + { int ret = slice_from_s(z, 2, s_65); if (ret < 0) return ret; } break; case 4: - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 397 */ - { int ret = slice_from_s(z, 2, s_66); /* <-, line 397 */ + if (!(len_utf8(z->p) > 4)) return 0; + { int ret = slice_from_s(z, 2, s_66); if (ret < 0) return ret; } break; @@ -1200,42 +1198,42 @@ static int r_Prefix_Step3_Verb(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_Prefix_Step4_Verb(struct SN_env * z) { /* forwardmode */ - z->bra = z->c; /* [, line 402 */ - if (z->c + 5 >= z->l || z->p[z->c + 5] != 170) return 0; /* substring, line 402 */ +static int r_Prefix_Step4_Verb(struct SN_env * z) { + z->bra = z->c; + if (z->c + 5 >= z->l || z->p[z->c + 5] != 170) return 0; if (!(find_among(z, a_9, 3))) return 0; - z->ket = z->c; /* ], line 402 */ - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 403 */ - z->B[1] = 1; /* set is_verb, line 403 */ - z->B[0] = 0; /* unset is_noun, line 403 */ - { int ret = slice_from_s(z, 6, s_67); /* <-, line 403 */ + z->ket = z->c; + if (!(len_utf8(z->p) > 4)) return 0; + z->I[1] = 1; + z->I[2] = 0; + { int ret = slice_from_s(z, 6, s_67); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Noun_Step1a(struct SN_env * z) { /* backwardmode */ +static int r_Suffix_Noun_Step1a(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 411 */ - among_var = find_among_b(z, a_10, 10); /* substring, line 411 */ + z->ket = z->c; + among_var = find_among_b(z, a_10, 10); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 411 */ - switch (among_var) { /* among, line 411 */ + z->bra = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 412 */ - { int ret = slice_del(z); /* delete, line 412 */ + if (!(len_utf8(z->p) >= 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 413 */ - { int ret = slice_del(z); /* delete, line 413 */ + if (!(len_utf8(z->p) >= 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 414 */ - { int ret = slice_del(z); /* delete, line 414 */ + if (!(len_utf8(z->p) >= 6)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1243,99 +1241,99 @@ static int r_Suffix_Noun_Step1a(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Suffix_Noun_Step1b(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 418 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 134) return 0; /* substring, line 418 */ +static int r_Suffix_Noun_Step1b(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 134) return 0; if (!(find_among_b(z, a_11, 1))) return 0; - z->bra = z->c; /* ], line 418 */ - if (!(len_utf8(z->p) > 5)) return 0; /* $( > ), line 419 */ - { int ret = slice_del(z); /* delete, line 419 */ + z->bra = z->c; + if (!(len_utf8(z->p) > 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Noun_Step2a(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 424 */ - if (!(find_among_b(z, a_12, 3))) return 0; /* substring, line 424 */ - z->bra = z->c; /* ], line 424 */ - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 425 */ - { int ret = slice_del(z); /* delete, line 425 */ +static int r_Suffix_Noun_Step2a(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_12, 3))) return 0; + z->bra = z->c; + if (!(len_utf8(z->p) > 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Noun_Step2b(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 430 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 170) return 0; /* substring, line 430 */ +static int r_Suffix_Noun_Step2b(struct SN_env * z) { + z->ket = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 170) return 0; if (!(find_among_b(z, a_13, 1))) return 0; - z->bra = z->c; /* ], line 430 */ - if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 431 */ - { int ret = slice_del(z); /* delete, line 431 */ + z->bra = z->c; + if (!(len_utf8(z->p) >= 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Noun_Step2c1(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 436 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 170) return 0; /* substring, line 436 */ +static int r_Suffix_Noun_Step2c1(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 170) return 0; if (!(find_among_b(z, a_14, 1))) return 0; - z->bra = z->c; /* ], line 436 */ - if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 437 */ - { int ret = slice_del(z); /* delete, line 437 */ + z->bra = z->c; + if (!(len_utf8(z->p) >= 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Noun_Step2c2(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 441 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 169) return 0; /* substring, line 441 */ +static int r_Suffix_Noun_Step2c2(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 169) return 0; if (!(find_among_b(z, a_15, 1))) return 0; - z->bra = z->c; /* ], line 441 */ - if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 442 */ - { int ret = slice_del(z); /* delete, line 442 */ + z->bra = z->c; + if (!(len_utf8(z->p) >= 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Noun_Step3(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 446 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 138) return 0; /* substring, line 446 */ +static int r_Suffix_Noun_Step3(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 138) return 0; if (!(find_among_b(z, a_16, 1))) return 0; - z->bra = z->c; /* ], line 446 */ - if (!(len_utf8(z->p) >= 3)) return 0; /* $( >= ), line 447 */ - { int ret = slice_del(z); /* delete, line 447 */ + z->bra = z->c; + if (!(len_utf8(z->p) >= 3)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Verb_Step1(struct SN_env * z) { /* backwardmode */ +static int r_Suffix_Verb_Step1(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 452 */ - among_var = find_among_b(z, a_17, 12); /* substring, line 452 */ + z->ket = z->c; + among_var = find_among_b(z, a_17, 12); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 452 */ - switch (among_var) { /* among, line 452 */ + z->bra = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 453 */ - { int ret = slice_del(z); /* delete, line 453 */ + if (!(len_utf8(z->p) >= 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 454 */ - { int ret = slice_del(z); /* delete, line 454 */ + if (!(len_utf8(z->p) >= 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 455 */ - { int ret = slice_del(z); /* delete, line 455 */ + if (!(len_utf8(z->p) >= 6)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1343,34 +1341,34 @@ static int r_Suffix_Verb_Step1(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Suffix_Verb_Step2a(struct SN_env * z) { /* backwardmode */ +static int r_Suffix_Verb_Step2a(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 459 */ - among_var = find_among_b(z, a_18, 11); /* substring, line 459 */ + z->ket = z->c; + among_var = find_among_b(z, a_18, 11); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 459 */ - switch (among_var) { /* among, line 459 */ + z->bra = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 460 */ - { int ret = slice_del(z); /* delete, line 460 */ + if (!(len_utf8(z->p) >= 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 462 */ - { int ret = slice_del(z); /* delete, line 462 */ + if (!(len_utf8(z->p) >= 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - if (!(len_utf8(z->p) > 5)) return 0; /* $( > ), line 463 */ - { int ret = slice_del(z); /* delete, line 463 */ + if (!(len_utf8(z->p) > 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 4: - if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 464 */ - { int ret = slice_del(z); /* delete, line 464 */ + if (!(len_utf8(z->p) >= 6)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1378,35 +1376,35 @@ static int r_Suffix_Verb_Step2a(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Suffix_Verb_Step2b(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 469 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 133 && z->p[z->c - 1] != 167)) return 0; /* substring, line 469 */ +static int r_Suffix_Verb_Step2b(struct SN_env * z) { + z->ket = z->c; + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 133 && z->p[z->c - 1] != 167)) return 0; if (!(find_among_b(z, a_19, 2))) return 0; - z->bra = z->c; /* ], line 469 */ - if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 470 */ - { int ret = slice_del(z); /* delete, line 470 */ + z->bra = z->c; + if (!(len_utf8(z->p) >= 5)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Suffix_Verb_Step2c(struct SN_env * z) { /* backwardmode */ +static int r_Suffix_Verb_Step2c(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 476 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 136) return 0; /* substring, line 476 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 136) return 0; among_var = find_among_b(z, a_20, 2); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 476 */ - switch (among_var) { /* among, line 476 */ + z->bra = z->c; + switch (among_var) { case 1: - if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 477 */ - { int ret = slice_del(z); /* delete, line 477 */ + if (!(len_utf8(z->p) >= 4)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 478 */ - { int ret = slice_del(z); /* delete, line 478 */ + if (!(len_utf8(z->p) >= 6)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1414,40 +1412,41 @@ static int r_Suffix_Verb_Step2c(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Suffix_All_alef_maqsura(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 483 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 137) return 0; /* substring, line 483 */ +static int r_Suffix_All_alef_maqsura(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 137) return 0; if (!(find_among_b(z, a_21, 1))) return 0; - z->bra = z->c; /* ], line 483 */ - { int ret = slice_from_s(z, 2, s_68); /* <-, line 484 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_68); if (ret < 0) return ret; } return 1; } -extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - z->B[0] = 1; /* set is_noun, line 493 */ - z->B[1] = 1; /* set is_verb, line 494 */ - z->B[2] = 0; /* unset is_defined, line 495 */ - { int c1 = z->c; /* do, line 498 */ - { int ret = r_Checks1(z); /* call Checks1, line 498 */ +extern int arabic_UTF_8_stem(struct SN_env * z) { + z->I[2] = 1; + z->I[1] = 1; + z->I[0] = 0; + { int c1 = z->c; + { int ret = r_Checks1(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 501 */ - { int ret = r_Normalize_pre(z); /* call Normalize_pre, line 501 */ + + { int ret = r_Normalize_pre(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 504 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 506 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 520 */ - if (!(z->B[1])) goto lab2; /* Boolean test is_verb, line 509 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 515 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + if (!(z->I[1])) goto lab2; + { int m4 = z->l - z->c; (void)m4; { int i = 1; - while(1) { int m5 = z->l - z->c; (void)m5; - { int ret = r_Suffix_Verb_Step1(z); /* call Suffix_Verb_Step1, line 512 */ + while(1) { + int m5 = z->l - z->c; (void)m5; + { int ret = r_Suffix_Verb_Step1(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } @@ -1459,38 +1458,38 @@ extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ } if (i > 0) goto lab4; } - { int m6 = z->l - z->c; (void)m6; /* or, line 513 */ - { int ret = r_Suffix_Verb_Step2a(z); /* call Suffix_Verb_Step2a, line 513 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_Suffix_Verb_Step2a(z); if (ret == 0) goto lab7; if (ret < 0) return ret; } goto lab6; lab7: z->c = z->l - m6; - { int ret = r_Suffix_Verb_Step2c(z); /* call Suffix_Verb_Step2c, line 513 */ + { int ret = r_Suffix_Verb_Step2c(z); if (ret == 0) goto lab8; if (ret < 0) return ret; } goto lab6; lab8: z->c = z->l - m6; - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) goto lab4; - z->c = ret; /* next, line 513 */ + z->c = ret; } } lab6: goto lab3; lab4: z->c = z->l - m4; - { int ret = r_Suffix_Verb_Step2b(z); /* call Suffix_Verb_Step2b, line 515 */ + { int ret = r_Suffix_Verb_Step2b(z); if (ret == 0) goto lab9; if (ret < 0) return ret; } goto lab3; lab9: z->c = z->l - m4; - { int ret = r_Suffix_Verb_Step2a(z); /* call Suffix_Verb_Step2a, line 516 */ + { int ret = r_Suffix_Verb_Step2a(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } @@ -1499,75 +1498,75 @@ extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = z->l - m3; - if (!(z->B[0])) goto lab10; /* Boolean test is_noun, line 521 */ - { int m7 = z->l - z->c; (void)m7; /* try, line 524 */ - { int m8 = z->l - z->c; (void)m8; /* or, line 526 */ - { int ret = r_Suffix_Noun_Step2c2(z); /* call Suffix_Noun_Step2c2, line 525 */ + if (!(z->I[2])) goto lab10; + { int m7 = z->l - z->c; (void)m7; + { int m8 = z->l - z->c; (void)m8; + { int ret = r_Suffix_Noun_Step2c2(z); if (ret == 0) goto lab13; if (ret < 0) return ret; } goto lab12; lab13: z->c = z->l - m8; - /* not, line 526 */ - if (!(z->B[2])) goto lab15; /* Boolean test is_defined, line 526 */ + + if (!(z->I[0])) goto lab15; goto lab14; lab15: - { int ret = r_Suffix_Noun_Step1a(z); /* call Suffix_Noun_Step1a, line 526 */ + { int ret = r_Suffix_Noun_Step1a(z); if (ret == 0) goto lab14; if (ret < 0) return ret; } - { int m9 = z->l - z->c; (void)m9; /* or, line 528 */ - { int ret = r_Suffix_Noun_Step2a(z); /* call Suffix_Noun_Step2a, line 527 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_Suffix_Noun_Step2a(z); if (ret == 0) goto lab17; if (ret < 0) return ret; } goto lab16; lab17: z->c = z->l - m9; - { int ret = r_Suffix_Noun_Step2b(z); /* call Suffix_Noun_Step2b, line 528 */ + { int ret = r_Suffix_Noun_Step2b(z); if (ret == 0) goto lab18; if (ret < 0) return ret; } goto lab16; lab18: z->c = z->l - m9; - { int ret = r_Suffix_Noun_Step2c1(z); /* call Suffix_Noun_Step2c1, line 529 */ + { int ret = r_Suffix_Noun_Step2c1(z); if (ret == 0) goto lab19; if (ret < 0) return ret; } goto lab16; lab19: z->c = z->l - m9; - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) goto lab14; - z->c = ret; /* next, line 530 */ + z->c = ret; } } lab16: goto lab12; lab14: z->c = z->l - m8; - { int ret = r_Suffix_Noun_Step1b(z); /* call Suffix_Noun_Step1b, line 531 */ + { int ret = r_Suffix_Noun_Step1b(z); if (ret == 0) goto lab20; if (ret < 0) return ret; } - { int m10 = z->l - z->c; (void)m10; /* or, line 533 */ - { int ret = r_Suffix_Noun_Step2a(z); /* call Suffix_Noun_Step2a, line 532 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_Suffix_Noun_Step2a(z); if (ret == 0) goto lab22; if (ret < 0) return ret; } goto lab21; lab22: z->c = z->l - m10; - { int ret = r_Suffix_Noun_Step2b(z); /* call Suffix_Noun_Step2b, line 533 */ + { int ret = r_Suffix_Noun_Step2b(z); if (ret == 0) goto lab23; if (ret < 0) return ret; } goto lab21; lab23: z->c = z->l - m10; - { int ret = r_Suffix_Noun_Step2c1(z); /* call Suffix_Noun_Step2c1, line 534 */ + { int ret = r_Suffix_Noun_Step2c1(z); if (ret == 0) goto lab20; if (ret < 0) return ret; } @@ -1576,18 +1575,18 @@ extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ goto lab12; lab20: z->c = z->l - m8; - /* not, line 535 */ - if (!(z->B[2])) goto lab25; /* Boolean test is_defined, line 535 */ + + if (!(z->I[0])) goto lab25; goto lab24; lab25: - { int ret = r_Suffix_Noun_Step2a(z); /* call Suffix_Noun_Step2a, line 535 */ + { int ret = r_Suffix_Noun_Step2a(z); if (ret == 0) goto lab24; if (ret < 0) return ret; } goto lab12; lab24: z->c = z->l - m8; - { int ret = r_Suffix_Noun_Step2b(z); /* call Suffix_Noun_Step2b, line 536 */ + { int ret = r_Suffix_Noun_Step2b(z); if (ret == 0) { z->c = z->l - m7; goto lab11; } if (ret < 0) return ret; } @@ -1596,14 +1595,14 @@ extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab11: ; } - { int ret = r_Suffix_Noun_Step3(z); /* call Suffix_Noun_Step3, line 538 */ + { int ret = r_Suffix_Noun_Step3(z); if (ret == 0) goto lab10; if (ret < 0) return ret; } goto lab1; lab10: z->c = z->l - m3; - { int ret = r_Suffix_All_alef_maqsura(z); /* call Suffix_All_alef_maqsura, line 544 */ + { int ret = r_Suffix_All_alef_maqsura(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1613,49 +1612,49 @@ extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ z->c = z->l - m2; } z->c = z->lb; - { int c11 = z->c; /* do, line 549 */ - { int c12 = z->c; /* try, line 550 */ - { int ret = r_Prefix_Step1(z); /* call Prefix_Step1, line 550 */ + { int c11 = z->c; + { int c12 = z->c; + { int ret = r_Prefix_Step1(z); if (ret == 0) { z->c = c12; goto lab27; } if (ret < 0) return ret; } lab27: ; } - { int c13 = z->c; /* try, line 551 */ - { int ret = r_Prefix_Step2(z); /* call Prefix_Step2, line 551 */ + { int c13 = z->c; + { int ret = r_Prefix_Step2(z); if (ret == 0) { z->c = c13; goto lab28; } if (ret < 0) return ret; } lab28: ; } - { int c14 = z->c; /* or, line 553 */ - { int ret = r_Prefix_Step3a_Noun(z); /* call Prefix_Step3a_Noun, line 552 */ + { int c14 = z->c; + { int ret = r_Prefix_Step3a_Noun(z); if (ret == 0) goto lab30; if (ret < 0) return ret; } goto lab29; lab30: z->c = c14; - if (!(z->B[0])) goto lab31; /* Boolean test is_noun, line 553 */ - { int ret = r_Prefix_Step3b_Noun(z); /* call Prefix_Step3b_Noun, line 553 */ + if (!(z->I[2])) goto lab31; + { int ret = r_Prefix_Step3b_Noun(z); if (ret == 0) goto lab31; if (ret < 0) return ret; } goto lab29; lab31: z->c = c14; - if (!(z->B[1])) goto lab26; /* Boolean test is_verb, line 554 */ - { int c15 = z->c; /* try, line 554 */ - { int ret = r_Prefix_Step3_Verb(z); /* call Prefix_Step3_Verb, line 554 */ + if (!(z->I[1])) goto lab26; + { int c15 = z->c; + { int ret = r_Prefix_Step3_Verb(z); if (ret == 0) { z->c = c15; goto lab32; } if (ret < 0) return ret; } lab32: ; } - { int ret = r_Prefix_Step4_Verb(z); /* call Prefix_Step4_Verb, line 554 */ + { int ret = r_Prefix_Step4_Verb(z); if (ret == 0) goto lab26; if (ret < 0) return ret; } @@ -1664,14 +1663,14 @@ extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab26: z->c = c11; } - /* do, line 559 */ - { int ret = r_Normalize_post(z); /* call Normalize_post, line 559 */ + + { int ret = r_Normalize_post(z); if (ret < 0) return ret; } return 1; } -extern struct SN_env * arabic_UTF_8_create_env(void) { return SN_create_env(0, 0, 3); } +extern struct SN_env * arabic_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void arabic_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_armenian.c b/src/backend/snowball/libstemmer/stem_UTF_8_armenian.c new file mode 100644 index 000000000000..009ddb51d1d1 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_armenian.c @@ -0,0 +1,559 @@ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int armenian_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_ending(struct SN_env * z); +static int r_noun(struct SN_env * z); +static int r_verb(struct SN_env * z); +static int r_adjective(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * armenian_UTF_8_create_env(void); +extern void armenian_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[6] = { 0xD5, 0xA2, 0xD5, 0xA1, 0xD6, 0x80 }; +static const symbol s_0_1[8] = { 0xD6, 0x80, 0xD5, 0xB8, 0xD6, 0x80, 0xD5, 0xA4 }; +static const symbol s_0_2[10] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xB8, 0xD6, 0x80, 0xD5, 0xA4 }; +static const symbol s_0_3[6] = { 0xD5, 0xA1, 0xD5, 0xAC, 0xD5, 0xAB }; +static const symbol s_0_4[6] = { 0xD5, 0xA1, 0xD5, 0xAF, 0xD5, 0xAB }; +static const symbol s_0_5[8] = { 0xD5, 0xB8, 0xD6, 0x80, 0xD5, 0xA1, 0xD5, 0xAF }; +static const symbol s_0_6[4] = { 0xD5, 0xA5, 0xD5, 0xB2 }; +static const symbol s_0_7[8] = { 0xD5, 0xBE, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB6 }; +static const symbol s_0_8[8] = { 0xD5, 0xA1, 0xD6, 0x80, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_0_9[8] = { 0xD5, 0xA1, 0xD5, 0xAF, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_0_10[4] = { 0xD5, 0xA5, 0xD5, 0xB6 }; +static const symbol s_0_11[8] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xA5, 0xD5, 0xB6 }; +static const symbol s_0_12[8] = { 0xD5, 0xA5, 0xD5, 0xAF, 0xD5, 0xA5, 0xD5, 0xB6 }; +static const symbol s_0_13[8] = { 0xD5, 0xB8, 0xD6, 0x80, 0xD5, 0xA7, 0xD5, 0xB6 }; +static const symbol s_0_14[4] = { 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_0_15[6] = { 0xD5, 0xA3, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_0_16[8] = { 0xD5, 0xB8, 0xD5, 0xBE, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_0_17[8] = { 0xD5, 0xAC, 0xD5, 0xA1, 0xD5, 0xB5, 0xD5, 0xB6 }; +static const symbol s_0_18[6] = { 0xD5, 0xBA, 0xD5, 0xA5, 0xD5, 0xBD }; +static const symbol s_0_19[4] = { 0xD5, 0xAB, 0xD5, 0xBE }; +static const symbol s_0_20[4] = { 0xD5, 0xA1, 0xD5, 0xBF }; +static const symbol s_0_21[8] = { 0xD5, 0xA1, 0xD5, 0xBE, 0xD5, 0xA5, 0xD5, 0xBF }; +static const symbol s_0_22[6] = { 0xD5, 0xAF, 0xD5, 0xB8, 0xD5, 0xBF }; + +static const struct among a_0[23] = +{ +{ 6, s_0_0, -1, 1, 0}, +{ 8, s_0_1, -1, 1, 0}, +{ 10, s_0_2, 1, 1, 0}, +{ 6, s_0_3, -1, 1, 0}, +{ 6, s_0_4, -1, 1, 0}, +{ 8, s_0_5, -1, 1, 0}, +{ 4, s_0_6, -1, 1, 0}, +{ 8, s_0_7, -1, 1, 0}, +{ 8, s_0_8, -1, 1, 0}, +{ 8, s_0_9, -1, 1, 0}, +{ 4, s_0_10, -1, 1, 0}, +{ 8, s_0_11, 10, 1, 0}, +{ 8, s_0_12, 10, 1, 0}, +{ 8, s_0_13, -1, 1, 0}, +{ 4, s_0_14, -1, 1, 0}, +{ 6, s_0_15, 14, 1, 0}, +{ 8, s_0_16, 14, 1, 0}, +{ 8, s_0_17, -1, 1, 0}, +{ 6, s_0_18, -1, 1, 0}, +{ 4, s_0_19, -1, 1, 0}, +{ 4, s_0_20, -1, 1, 0}, +{ 8, s_0_21, -1, 1, 0}, +{ 6, s_0_22, -1, 1, 0} +}; + +static const symbol s_1_0[4] = { 0xD5, 0xA1, 0xD6, 0x80 }; +static const symbol s_1_1[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xA1, 0xD6, 0x80 }; +static const symbol s_1_2[8] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xA1, 0xD6, 0x80 }; +static const symbol s_1_3[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD6, 0x80, 0xD5, 0xAB, 0xD6, 0x80 }; +static const symbol s_1_4[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xAB, 0xD6, 0x80 }; +static const symbol s_1_5[8] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD6, 0x80 }; +static const symbol s_1_6[10] = { 0xD5, 0xBE, 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD6, 0x80 }; +static const symbol s_1_7[10] = { 0xD5, 0xA1, 0xD5, 0xAC, 0xD5, 0xB8, 0xD6, 0x82, 0xD6, 0x81 }; +static const symbol s_1_8[10] = { 0xD5, 0xA5, 0xD5, 0xAC, 0xD5, 0xB8, 0xD6, 0x82, 0xD6, 0x81 }; +static const symbol s_1_9[4] = { 0xD5, 0xA1, 0xD6, 0x81 }; +static const symbol s_1_10[4] = { 0xD5, 0xA5, 0xD6, 0x81 }; +static const symbol s_1_11[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD6, 0x80, 0xD5, 0xA5, 0xD6, 0x81 }; +static const symbol s_1_12[8] = { 0xD5, 0xA1, 0xD5, 0xAC, 0xD5, 0xB8, 0xD6, 0x82 }; +static const symbol s_1_13[8] = { 0xD5, 0xA5, 0xD5, 0xAC, 0xD5, 0xB8, 0xD6, 0x82 }; +static const symbol s_1_14[4] = { 0xD5, 0xA1, 0xD6, 0x84 }; +static const symbol s_1_15[6] = { 0xD6, 0x81, 0xD5, 0xA1, 0xD6, 0x84 }; +static const symbol s_1_16[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xA1, 0xD6, 0x84 }; +static const symbol s_1_17[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD6, 0x80, 0xD5, 0xAB, 0xD6, 0x84 }; +static const symbol s_1_18[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xAB, 0xD6, 0x84 }; +static const symbol s_1_19[8] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD6, 0x84 }; +static const symbol s_1_20[10] = { 0xD5, 0xBE, 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD6, 0x84 }; +static const symbol s_1_21[6] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_1_22[8] = { 0xD6, 0x81, 0xD5, 0xA1, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_1_23[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xA1, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_1_24[12] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD6, 0x80, 0xD5, 0xAB, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_1_25[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xAB, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_1_26[10] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_1_27[12] = { 0xD5, 0xBE, 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_1_28[2] = { 0xD5, 0xA1 }; +static const symbol s_1_29[6] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xA1 }; +static const symbol s_1_30[6] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xA1 }; +static const symbol s_1_31[4] = { 0xD5, 0xBE, 0xD5, 0xA5 }; +static const symbol s_1_32[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD6, 0x80, 0xD5, 0xAB }; +static const symbol s_1_33[6] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xAB }; +static const symbol s_1_34[6] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB }; +static const symbol s_1_35[8] = { 0xD5, 0xBE, 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB }; +static const symbol s_1_36[4] = { 0xD5, 0xA1, 0xD5, 0xAC }; +static const symbol s_1_37[6] = { 0xD5, 0xA8, 0xD5, 0xA1, 0xD5, 0xAC }; +static const symbol s_1_38[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xB6, 0xD5, 0xA1, 0xD5, 0xAC }; +static const symbol s_1_39[8] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA1, 0xD5, 0xAC }; +static const symbol s_1_40[8] = { 0xD5, 0xA5, 0xD5, 0xB6, 0xD5, 0xA1, 0xD5, 0xAC }; +static const symbol s_1_41[4] = { 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_42[6] = { 0xD5, 0xA8, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_43[6] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_44[8] = { 0xD6, 0x81, 0xD5, 0xB6, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_45[10] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xB6, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_46[6] = { 0xD5, 0xB9, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_47[6] = { 0xD5, 0xBE, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_48[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xBE, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_49[10] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xBE, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_50[6] = { 0xD5, 0xBF, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_51[8] = { 0xD5, 0xA1, 0xD5, 0xBF, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_52[8] = { 0xD5, 0xB8, 0xD5, 0xBF, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_53[10] = { 0xD5, 0xAF, 0xD5, 0xB8, 0xD5, 0xBF, 0xD5, 0xA5, 0xD5, 0xAC }; +static const symbol s_1_54[6] = { 0xD5, 0xBE, 0xD5, 0xA1, 0xD5, 0xAE }; +static const symbol s_1_55[6] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB4 }; +static const symbol s_1_56[8] = { 0xD5, 0xBE, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB4 }; +static const symbol s_1_57[4] = { 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_1_58[6] = { 0xD6, 0x81, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_1_59[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_1_60[10] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD6, 0x80, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_1_61[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_1_62[8] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_1_63[10] = { 0xD5, 0xBE, 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_1_64[8] = { 0xD5, 0xA1, 0xD5, 0xAC, 0xD5, 0xAB, 0xD5, 0xBD }; +static const symbol s_1_65[8] = { 0xD5, 0xA5, 0xD5, 0xAC, 0xD5, 0xAB, 0xD5, 0xBD }; +static const symbol s_1_66[4] = { 0xD5, 0xA1, 0xD5, 0xBE }; +static const symbol s_1_67[8] = { 0xD5, 0xA1, 0xD6, 0x81, 0xD5, 0xA1, 0xD5, 0xBE }; +static const symbol s_1_68[8] = { 0xD5, 0xA5, 0xD6, 0x81, 0xD5, 0xA1, 0xD5, 0xBE }; +static const symbol s_1_69[8] = { 0xD5, 0xA1, 0xD5, 0xAC, 0xD5, 0xB8, 0xD5, 0xBE }; +static const symbol s_1_70[8] = { 0xD5, 0xA5, 0xD5, 0xAC, 0xD5, 0xB8, 0xD5, 0xBE }; + +static const struct among a_1[71] = +{ +{ 4, s_1_0, -1, 1, 0}, +{ 8, s_1_1, 0, 1, 0}, +{ 8, s_1_2, 0, 1, 0}, +{ 10, s_1_3, -1, 1, 0}, +{ 8, s_1_4, -1, 1, 0}, +{ 8, s_1_5, -1, 1, 0}, +{ 10, s_1_6, 5, 1, 0}, +{ 10, s_1_7, -1, 1, 0}, +{ 10, s_1_8, -1, 1, 0}, +{ 4, s_1_9, -1, 1, 0}, +{ 4, s_1_10, -1, 1, 0}, +{ 10, s_1_11, 10, 1, 0}, +{ 8, s_1_12, -1, 1, 0}, +{ 8, s_1_13, -1, 1, 0}, +{ 4, s_1_14, -1, 1, 0}, +{ 6, s_1_15, 14, 1, 0}, +{ 8, s_1_16, 15, 1, 0}, +{ 10, s_1_17, -1, 1, 0}, +{ 8, s_1_18, -1, 1, 0}, +{ 8, s_1_19, -1, 1, 0}, +{ 10, s_1_20, 19, 1, 0}, +{ 6, s_1_21, -1, 1, 0}, +{ 8, s_1_22, 21, 1, 0}, +{ 10, s_1_23, 22, 1, 0}, +{ 12, s_1_24, -1, 1, 0}, +{ 10, s_1_25, -1, 1, 0}, +{ 10, s_1_26, -1, 1, 0}, +{ 12, s_1_27, 26, 1, 0}, +{ 2, s_1_28, -1, 1, 0}, +{ 6, s_1_29, 28, 1, 0}, +{ 6, s_1_30, 28, 1, 0}, +{ 4, s_1_31, -1, 1, 0}, +{ 8, s_1_32, -1, 1, 0}, +{ 6, s_1_33, -1, 1, 0}, +{ 6, s_1_34, -1, 1, 0}, +{ 8, s_1_35, 34, 1, 0}, +{ 4, s_1_36, -1, 1, 0}, +{ 6, s_1_37, 36, 1, 0}, +{ 10, s_1_38, 36, 1, 0}, +{ 8, s_1_39, 36, 1, 0}, +{ 8, s_1_40, 36, 1, 0}, +{ 4, s_1_41, -1, 1, 0}, +{ 6, s_1_42, 41, 1, 0}, +{ 6, s_1_43, 41, 1, 0}, +{ 8, s_1_44, 43, 1, 0}, +{ 10, s_1_45, 44, 1, 0}, +{ 6, s_1_46, 41, 1, 0}, +{ 6, s_1_47, 41, 1, 0}, +{ 10, s_1_48, 47, 1, 0}, +{ 10, s_1_49, 47, 1, 0}, +{ 6, s_1_50, 41, 1, 0}, +{ 8, s_1_51, 50, 1, 0}, +{ 8, s_1_52, 50, 1, 0}, +{ 10, s_1_53, 52, 1, 0}, +{ 6, s_1_54, -1, 1, 0}, +{ 6, s_1_55, -1, 1, 0}, +{ 8, s_1_56, 55, 1, 0}, +{ 4, s_1_57, -1, 1, 0}, +{ 6, s_1_58, 57, 1, 0}, +{ 8, s_1_59, 58, 1, 0}, +{ 10, s_1_60, -1, 1, 0}, +{ 8, s_1_61, -1, 1, 0}, +{ 8, s_1_62, -1, 1, 0}, +{ 10, s_1_63, 62, 1, 0}, +{ 8, s_1_64, -1, 1, 0}, +{ 8, s_1_65, -1, 1, 0}, +{ 4, s_1_66, -1, 1, 0}, +{ 8, s_1_67, 66, 1, 0}, +{ 8, s_1_68, 66, 1, 0}, +{ 8, s_1_69, -1, 1, 0}, +{ 8, s_1_70, -1, 1, 0} +}; + +static const symbol s_2_0[6] = { 0xD5, 0xA3, 0xD5, 0xA1, 0xD6, 0x80 }; +static const symbol s_2_1[6] = { 0xD5, 0xBE, 0xD5, 0xB8, 0xD6, 0x80 }; +static const symbol s_2_2[8] = { 0xD5, 0xA1, 0xD5, 0xBE, 0xD5, 0xB8, 0xD6, 0x80 }; +static const symbol s_2_3[8] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD6, 0x85, 0xD6, 0x81 }; +static const symbol s_2_4[4] = { 0xD5, 0xB8, 0xD6, 0x81 }; +static const symbol s_2_5[4] = { 0xD5, 0xB8, 0xD6, 0x82 }; +static const symbol s_2_6[2] = { 0xD6, 0x84 }; +static const symbol s_2_7[6] = { 0xD5, 0xA1, 0xD6, 0x80, 0xD6, 0x84 }; +static const symbol s_2_8[6] = { 0xD5, 0xB9, 0xD5, 0xA5, 0xD6, 0x84 }; +static const symbol s_2_9[4] = { 0xD5, 0xAB, 0xD6, 0x84 }; +static const symbol s_2_10[8] = { 0xD5, 0xA1, 0xD5, 0xAC, 0xD5, 0xAB, 0xD6, 0x84 }; +static const symbol s_2_11[8] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xAB, 0xD6, 0x84 }; +static const symbol s_2_12[8] = { 0xD5, 0xBE, 0xD5, 0xA1, 0xD5, 0xAE, 0xD6, 0x84 }; +static const symbol s_2_13[8] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB5, 0xD6, 0x84 }; +static const symbol s_2_14[8] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_2_15[10] = { 0xD5, 0xB4, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_2_16[6] = { 0xD5, 0xA5, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_2_17[6] = { 0xD5, 0xB8, 0xD5, 0xB6, 0xD6, 0x84 }; +static const symbol s_2_18[6] = { 0xD5, 0xAB, 0xD5, 0xB9, 0xD6, 0x84 }; +static const symbol s_2_19[6] = { 0xD5, 0xB8, 0xD6, 0x80, 0xD5, 0xA4 }; +static const symbol s_2_20[8] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB5, 0xD5, 0xA9 }; +static const symbol s_2_21[4] = { 0xD6, 0x81, 0xD5, 0xAB }; +static const symbol s_2_22[8] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB0, 0xD5, 0xAB }; +static const symbol s_2_23[4] = { 0xD5, 0xAB, 0xD5, 0xAC }; +static const symbol s_2_24[6] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xAF }; +static const symbol s_2_25[4] = { 0xD5, 0xA1, 0xD5, 0xAF }; +static const symbol s_2_26[6] = { 0xD5, 0xB5, 0xD5, 0xA1, 0xD5, 0xAF }; +static const symbol s_2_27[8] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA1, 0xD5, 0xAF }; +static const symbol s_2_28[4] = { 0xD5, 0xAB, 0xD5, 0xAF }; +static const symbol s_2_29[8] = { 0xD5, 0xB5, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB6 }; +static const symbol s_2_30[14] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xA9, 0xD5, 0xB5, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB6 }; +static const symbol s_2_31[4] = { 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_2_32[8] = { 0xD5, 0xA1, 0xD6, 0x80, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_2_33[6] = { 0xD5, 0xBA, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_2_34[8] = { 0xD5, 0xBD, 0xD5, 0xBF, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_2_35[8] = { 0xD5, 0xA5, 0xD5, 0xB2, 0xD5, 0xA7, 0xD5, 0xB6 }; +static const symbol s_2_36[6] = { 0xD5, 0xA1, 0xD5, 0xAE, 0xD5, 0xB8 }; +static const symbol s_2_37[4] = { 0xD5, 0xAB, 0xD5, 0xB9 }; +static const symbol s_2_38[6] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xBD }; +static const symbol s_2_39[8] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xBD, 0xD5, 0xBF }; + +static const struct among a_2[40] = +{ +{ 6, s_2_0, -1, 1, 0}, +{ 6, s_2_1, -1, 1, 0}, +{ 8, s_2_2, 1, 1, 0}, +{ 8, s_2_3, -1, 1, 0}, +{ 4, s_2_4, -1, 1, 0}, +{ 4, s_2_5, -1, 1, 0}, +{ 2, s_2_6, -1, 1, 0}, +{ 6, s_2_7, 6, 1, 0}, +{ 6, s_2_8, 6, 1, 0}, +{ 4, s_2_9, 6, 1, 0}, +{ 8, s_2_10, 9, 1, 0}, +{ 8, s_2_11, 9, 1, 0}, +{ 8, s_2_12, 6, 1, 0}, +{ 8, s_2_13, 6, 1, 0}, +{ 8, s_2_14, 6, 1, 0}, +{ 10, s_2_15, 14, 1, 0}, +{ 6, s_2_16, 6, 1, 0}, +{ 6, s_2_17, 6, 1, 0}, +{ 6, s_2_18, 6, 1, 0}, +{ 6, s_2_19, -1, 1, 0}, +{ 8, s_2_20, -1, 1, 0}, +{ 4, s_2_21, -1, 1, 0}, +{ 8, s_2_22, -1, 1, 0}, +{ 4, s_2_23, -1, 1, 0}, +{ 6, s_2_24, -1, 1, 0}, +{ 4, s_2_25, -1, 1, 0}, +{ 6, s_2_26, 25, 1, 0}, +{ 8, s_2_27, 25, 1, 0}, +{ 4, s_2_28, -1, 1, 0}, +{ 8, s_2_29, -1, 1, 0}, +{ 14, s_2_30, 29, 1, 0}, +{ 4, s_2_31, -1, 1, 0}, +{ 8, s_2_32, 31, 1, 0}, +{ 6, s_2_33, 31, 1, 0}, +{ 8, s_2_34, 31, 1, 0}, +{ 8, s_2_35, -1, 1, 0}, +{ 6, s_2_36, -1, 1, 0}, +{ 4, s_2_37, -1, 1, 0}, +{ 6, s_2_38, -1, 1, 0}, +{ 8, s_2_39, -1, 1, 0} +}; + +static const symbol s_3_0[4] = { 0xD5, 0xA5, 0xD6, 0x80 }; +static const symbol s_3_1[6] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80 }; +static const symbol s_3_2[2] = { 0xD6, 0x81 }; +static const symbol s_3_3[6] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD6, 0x81 }; +static const symbol s_3_4[4] = { 0xD5, 0xAB, 0xD6, 0x81 }; +static const symbol s_3_5[8] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xAB, 0xD6, 0x81 }; +static const symbol s_3_6[10] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xAB, 0xD6, 0x81 }; +static const symbol s_3_7[6] = { 0xD6, 0x81, 0xD5, 0xAB, 0xD6, 0x81 }; +static const symbol s_3_8[10] = { 0xD5, 0xBE, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xAB, 0xD6, 0x81 }; +static const symbol s_3_9[8] = { 0xD5, 0xB8, 0xD5, 0xBB, 0xD5, 0xAB, 0xD6, 0x81 }; +static const symbol s_3_10[6] = { 0xD5, 0xBE, 0xD5, 0xAB, 0xD6, 0x81 }; +static const symbol s_3_11[4] = { 0xD5, 0xB8, 0xD6, 0x81 }; +static const symbol s_3_12[4] = { 0xD5, 0xBD, 0xD5, 0xA1 }; +static const symbol s_3_13[4] = { 0xD5, 0xBE, 0xD5, 0xA1 }; +static const symbol s_3_14[6] = { 0xD5, 0xA1, 0xD5, 0xB4, 0xD5, 0xA2 }; +static const symbol s_3_15[2] = { 0xD5, 0xA4 }; +static const symbol s_3_16[6] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xA4 }; +static const symbol s_3_17[8] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xA4 }; +static const symbol s_3_18[6] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xA4 }; +static const symbol s_3_19[6] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA4 }; +static const symbol s_3_20[14] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xA9, 0xD5, 0xB5, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA4 }; +static const symbol s_3_21[8] = { 0xD5, 0xBE, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA4 }; +static const symbol s_3_22[6] = { 0xD5, 0xB8, 0xD5, 0xBB, 0xD5, 0xA4 }; +static const symbol s_3_23[2] = { 0xD5, 0xA8 }; +static const symbol s_3_24[6] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xA8 }; +static const symbol s_3_25[8] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xA8 }; +static const symbol s_3_26[6] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA8 }; +static const symbol s_3_27[14] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xA9, 0xD5, 0xB5, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA8 }; +static const symbol s_3_28[8] = { 0xD5, 0xBE, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xA8 }; +static const symbol s_3_29[6] = { 0xD5, 0xB8, 0xD5, 0xBB, 0xD5, 0xA8 }; +static const symbol s_3_30[2] = { 0xD5, 0xAB }; +static const symbol s_3_31[6] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xAB }; +static const symbol s_3_32[8] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xAB }; +static const symbol s_3_33[4] = { 0xD5, 0xBE, 0xD5, 0xAB }; +static const symbol s_3_34[10] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB4 }; +static const symbol s_3_35[12] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB4 }; +static const symbol s_3_36[10] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB4 }; +static const symbol s_3_37[2] = { 0xD5, 0xB6 }; +static const symbol s_3_38[6] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xB6 }; +static const symbol s_3_39[8] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xB6 }; +static const symbol s_3_40[6] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xB6 }; +static const symbol s_3_41[4] = { 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_3_42[12] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xA9, 0xD5, 0xB5, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_3_43[6] = { 0xD5, 0xBE, 0xD5, 0xA1, 0xD5, 0xB6 }; +static const symbol s_3_44[4] = { 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_3_45[8] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_3_46[10] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xAB, 0xD5, 0xB6 }; +static const symbol s_3_47[14] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xA9, 0xD5, 0xB5, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xB6 }; +static const symbol s_3_48[4] = { 0xD5, 0xB8, 0xD5, 0xBB }; +static const symbol s_3_49[14] = { 0xD5, 0xB8, 0xD6, 0x82, 0xD5, 0xA9, 0xD5, 0xB5, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xBD }; +static const symbol s_3_50[8] = { 0xD5, 0xBE, 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xBD }; +static const symbol s_3_51[6] = { 0xD5, 0xB8, 0xD5, 0xBB, 0xD5, 0xBD }; +static const symbol s_3_52[4] = { 0xD5, 0xB8, 0xD5, 0xBE }; +static const symbol s_3_53[8] = { 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xB8, 0xD5, 0xBE }; +static const symbol s_3_54[10] = { 0xD5, 0xB6, 0xD5, 0xA5, 0xD6, 0x80, 0xD5, 0xB8, 0xD5, 0xBE }; +static const symbol s_3_55[8] = { 0xD5, 0xA1, 0xD5, 0xB6, 0xD5, 0xB8, 0xD5, 0xBE }; +static const symbol s_3_56[6] = { 0xD5, 0xBE, 0xD5, 0xB8, 0xD5, 0xBE }; + +static const struct among a_3[57] = +{ +{ 4, s_3_0, -1, 1, 0}, +{ 6, s_3_1, 0, 1, 0}, +{ 2, s_3_2, -1, 1, 0}, +{ 6, s_3_3, 2, 1, 0}, +{ 4, s_3_4, 2, 1, 0}, +{ 8, s_3_5, 4, 1, 0}, +{ 10, s_3_6, 5, 1, 0}, +{ 6, s_3_7, 4, 1, 0}, +{ 10, s_3_8, 4, 1, 0}, +{ 8, s_3_9, 4, 1, 0}, +{ 6, s_3_10, 4, 1, 0}, +{ 4, s_3_11, 2, 1, 0}, +{ 4, s_3_12, -1, 1, 0}, +{ 4, s_3_13, -1, 1, 0}, +{ 6, s_3_14, -1, 1, 0}, +{ 2, s_3_15, -1, 1, 0}, +{ 6, s_3_16, 15, 1, 0}, +{ 8, s_3_17, 16, 1, 0}, +{ 6, s_3_18, 15, 1, 0}, +{ 6, s_3_19, 15, 1, 0}, +{ 14, s_3_20, 19, 1, 0}, +{ 8, s_3_21, 19, 1, 0}, +{ 6, s_3_22, 15, 1, 0}, +{ 2, s_3_23, -1, 1, 0}, +{ 6, s_3_24, 23, 1, 0}, +{ 8, s_3_25, 24, 1, 0}, +{ 6, s_3_26, 23, 1, 0}, +{ 14, s_3_27, 26, 1, 0}, +{ 8, s_3_28, 26, 1, 0}, +{ 6, s_3_29, 23, 1, 0}, +{ 2, s_3_30, -1, 1, 0}, +{ 6, s_3_31, 30, 1, 0}, +{ 8, s_3_32, 31, 1, 0}, +{ 4, s_3_33, 30, 1, 0}, +{ 10, s_3_34, -1, 1, 0}, +{ 12, s_3_35, 34, 1, 0}, +{ 10, s_3_36, -1, 1, 0}, +{ 2, s_3_37, -1, 1, 0}, +{ 6, s_3_38, 37, 1, 0}, +{ 8, s_3_39, 38, 1, 0}, +{ 6, s_3_40, 37, 1, 0}, +{ 4, s_3_41, 37, 1, 0}, +{ 12, s_3_42, 41, 1, 0}, +{ 6, s_3_43, 41, 1, 0}, +{ 4, s_3_44, 37, 1, 0}, +{ 8, s_3_45, 44, 1, 0}, +{ 10, s_3_46, 45, 1, 0}, +{ 14, s_3_47, 37, 1, 0}, +{ 4, s_3_48, -1, 1, 0}, +{ 14, s_3_49, -1, 1, 0}, +{ 8, s_3_50, -1, 1, 0}, +{ 6, s_3_51, -1, 1, 0}, +{ 4, s_3_52, -1, 1, 0}, +{ 8, s_3_53, 52, 1, 0}, +{ 10, s_3_54, 53, 1, 0}, +{ 8, s_3_55, 52, 1, 0}, +{ 6, s_3_56, 52, 1, 0} +}; + +static const unsigned char g_v[] = { 209, 4, 128, 0, 18 }; + + +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { + int ret = out_grouping_U(z, g_v, 1377, 1413, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + z->I[1] = z->c; + { + int ret = in_grouping_U(z, g_v, 1377, 1413, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + { + int ret = out_grouping_U(z, g_v, 1377, 1413, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + { + int ret = in_grouping_U(z, g_v, 1377, 1413, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + z->I[0] = z->c; + lab0: + z->c = c1; + } + return 1; +} + +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_adjective(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_0, 23))) return 0; + z->bra = z->c; + { int ret = slice_del(z); + if (ret < 0) return ret; + } + return 1; +} + +static int r_verb(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_1, 71))) return 0; + z->bra = z->c; + { int ret = slice_del(z); + if (ret < 0) return ret; + } + return 1; +} + +static int r_noun(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_2, 40))) return 0; + z->bra = z->c; + { int ret = slice_del(z); + if (ret < 0) return ret; + } + return 1; +} + +static int r_ending(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_3, 57))) return 0; + z->bra = z->c; + { int ret = r_R2(z); + if (ret <= 0) return ret; + } + { int ret = slice_del(z); + if (ret < 0) return ret; + } + return 1; +} + +extern int armenian_UTF_8_stem(struct SN_env * z) { + + { int ret = r_mark_regions(z); + if (ret < 0) return ret; + } + z->lb = z->c; z->c = z->l; + + + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + { int m2 = z->l - z->c; (void)m2; + { int ret = r_ending(z); + if (ret < 0) return ret; + } + z->c = z->l - m2; + } + { int m3 = z->l - z->c; (void)m3; + { int ret = r_verb(z); + if (ret < 0) return ret; + } + z->c = z->l - m3; + } + { int m4 = z->l - z->c; (void)m4; + { int ret = r_adjective(z); + if (ret < 0) return ret; + } + z->c = z->l - m4; + } + { int m5 = z->l - z->c; (void)m5; + { int ret = r_noun(z); + if (ret < 0) return ret; + } + z->c = z->l - m5; + } + z->lb = mlimit1; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * armenian_UTF_8_create_env(void) { return SN_create_env(0, 2); } + +extern void armenian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_basque.c b/src/backend/snowball/libstemmer/stem_UTF_8_basque.c index f21f53165b8a..d6beab6df92d 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_basque.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_basque.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -140,115 +140,115 @@ static const symbol s_0_108[5] = { 'k', 'a', 'i', 't', 'z' }; static const struct among a_0[109] = { -/* 0 */ { 4, s_0_0, -1, 1, 0}, -/* 1 */ { 5, s_0_1, 0, 1, 0}, -/* 2 */ { 5, s_0_2, 0, 1, 0}, -/* 3 */ { 5, s_0_3, 0, 1, 0}, -/* 4 */ { 6, s_0_4, -1, 1, 0}, -/* 5 */ { 5, s_0_5, -1, 1, 0}, -/* 6 */ { 6, s_0_6, -1, 1, 0}, -/* 7 */ { 7, s_0_7, -1, 1, 0}, -/* 8 */ { 5, s_0_8, -1, 1, 0}, -/* 9 */ { 5, s_0_9, -1, 1, 0}, -/* 10 */ { 5, s_0_10, -1, 1, 0}, -/* 11 */ { 4, s_0_11, -1, 1, 0}, -/* 12 */ { 5, s_0_12, -1, 1, 0}, -/* 13 */ { 6, s_0_13, 12, 1, 0}, -/* 14 */ { 5, s_0_14, -1, 1, 0}, -/* 15 */ { 6, s_0_15, -1, 2, 0}, -/* 16 */ { 6, s_0_16, -1, 1, 0}, -/* 17 */ { 2, s_0_17, -1, 1, 0}, -/* 18 */ { 5, s_0_18, 17, 1, 0}, -/* 19 */ { 2, s_0_19, -1, 1, 0}, -/* 20 */ { 4, s_0_20, -1, 1, 0}, -/* 21 */ { 4, s_0_21, -1, 1, 0}, -/* 22 */ { 4, s_0_22, -1, 1, 0}, -/* 23 */ { 5, s_0_23, -1, 1, 0}, -/* 24 */ { 6, s_0_24, 23, 1, 0}, -/* 25 */ { 4, s_0_25, -1, 1, 0}, -/* 26 */ { 4, s_0_26, -1, 1, 0}, -/* 27 */ { 6, s_0_27, -1, 1, 0}, -/* 28 */ { 3, s_0_28, -1, 1, 0}, -/* 29 */ { 4, s_0_29, 28, 1, 0}, -/* 30 */ { 7, s_0_30, 29, 4, 0}, -/* 31 */ { 4, s_0_31, 28, 1, 0}, -/* 32 */ { 4, s_0_32, 28, 1, 0}, -/* 33 */ { 4, s_0_33, -1, 1, 0}, -/* 34 */ { 5, s_0_34, 33, 1, 0}, -/* 35 */ { 4, s_0_35, -1, 1, 0}, -/* 36 */ { 4, s_0_36, -1, 1, 0}, -/* 37 */ { 4, s_0_37, -1, 1, 0}, -/* 38 */ { 4, s_0_38, -1, 1, 0}, -/* 39 */ { 3, s_0_39, -1, 1, 0}, -/* 40 */ { 4, s_0_40, 39, 1, 0}, -/* 41 */ { 6, s_0_41, -1, 1, 0}, -/* 42 */ { 3, s_0_42, -1, 1, 0}, -/* 43 */ { 6, s_0_43, 42, 1, 0}, -/* 44 */ { 3, s_0_44, -1, 2, 0}, -/* 45 */ { 6, s_0_45, 44, 1, 0}, -/* 46 */ { 6, s_0_46, 44, 1, 0}, -/* 47 */ { 6, s_0_47, 44, 1, 0}, -/* 48 */ { 3, s_0_48, -1, 1, 0}, -/* 49 */ { 4, s_0_49, 48, 1, 0}, -/* 50 */ { 4, s_0_50, 48, 1, 0}, -/* 51 */ { 4, s_0_51, 48, 1, 0}, -/* 52 */ { 5, s_0_52, -1, 1, 0}, -/* 53 */ { 5, s_0_53, -1, 1, 0}, -/* 54 */ { 5, s_0_54, -1, 1, 0}, -/* 55 */ { 2, s_0_55, -1, 1, 0}, -/* 56 */ { 4, s_0_56, 55, 1, 0}, -/* 57 */ { 5, s_0_57, 55, 1, 0}, -/* 58 */ { 6, s_0_58, 55, 1, 0}, -/* 59 */ { 4, s_0_59, -1, 1, 0}, -/* 60 */ { 4, s_0_60, -1, 1, 0}, -/* 61 */ { 3, s_0_61, -1, 1, 0}, -/* 62 */ { 4, s_0_62, 61, 1, 0}, -/* 63 */ { 3, s_0_63, -1, 1, 0}, -/* 64 */ { 4, s_0_64, -1, 1, 0}, -/* 65 */ { 5, s_0_65, 64, 1, 0}, -/* 66 */ { 2, s_0_66, -1, 1, 0}, -/* 67 */ { 3, s_0_67, -1, 1, 0}, -/* 68 */ { 4, s_0_68, 67, 1, 0}, -/* 69 */ { 4, s_0_69, 67, 1, 0}, -/* 70 */ { 4, s_0_70, 67, 1, 0}, -/* 71 */ { 5, s_0_71, 70, 1, 0}, -/* 72 */ { 5, s_0_72, -1, 2, 0}, -/* 73 */ { 5, s_0_73, -1, 1, 0}, -/* 74 */ { 5, s_0_74, -1, 1, 0}, -/* 75 */ { 6, s_0_75, 74, 1, 0}, -/* 76 */ { 2, s_0_76, -1, 1, 0}, -/* 77 */ { 3, s_0_77, 76, 1, 0}, -/* 78 */ { 4, s_0_78, 77, 1, 0}, -/* 79 */ { 3, s_0_79, 76, 1, 0}, -/* 80 */ { 4, s_0_80, 76, 1, 0}, -/* 81 */ { 7, s_0_81, -1, 3, 0}, -/* 82 */ { 3, s_0_82, -1, 1, 0}, -/* 83 */ { 3, s_0_83, -1, 1, 0}, -/* 84 */ { 3, s_0_84, -1, 1, 0}, -/* 85 */ { 5, s_0_85, 84, 1, 0}, -/* 86 */ { 4, s_0_86, -1, 1, 0}, -/* 87 */ { 5, s_0_87, 86, 1, 0}, -/* 88 */ { 3, s_0_88, -1, 1, 0}, -/* 89 */ { 5, s_0_89, -1, 1, 0}, -/* 90 */ { 2, s_0_90, -1, 1, 0}, -/* 91 */ { 3, s_0_91, 90, 1, 0}, -/* 92 */ { 3, s_0_92, -1, 1, 0}, -/* 93 */ { 4, s_0_93, -1, 1, 0}, -/* 94 */ { 2, s_0_94, -1, 1, 0}, -/* 95 */ { 3, s_0_95, 94, 1, 0}, -/* 96 */ { 4, s_0_96, -1, 1, 0}, -/* 97 */ { 2, s_0_97, -1, 1, 0}, -/* 98 */ { 5, s_0_98, -1, 1, 0}, -/* 99 */ { 2, s_0_99, -1, 1, 0}, -/*100 */ { 3, s_0_100, 99, 1, 0}, -/*101 */ { 6, s_0_101, 100, 1, 0}, -/*102 */ { 4, s_0_102, 100, 1, 0}, -/*103 */ { 6, s_0_103, 99, 5, 0}, -/*104 */ { 2, s_0_104, -1, 1, 0}, -/*105 */ { 5, s_0_105, 104, 1, 0}, -/*106 */ { 4, s_0_106, 104, 1, 0}, -/*107 */ { 5, s_0_107, -1, 1, 0}, -/*108 */ { 5, s_0_108, -1, 1, 0} +{ 4, s_0_0, -1, 1, 0}, +{ 5, s_0_1, 0, 1, 0}, +{ 5, s_0_2, 0, 1, 0}, +{ 5, s_0_3, 0, 1, 0}, +{ 6, s_0_4, -1, 1, 0}, +{ 5, s_0_5, -1, 1, 0}, +{ 6, s_0_6, -1, 1, 0}, +{ 7, s_0_7, -1, 1, 0}, +{ 5, s_0_8, -1, 1, 0}, +{ 5, s_0_9, -1, 1, 0}, +{ 5, s_0_10, -1, 1, 0}, +{ 4, s_0_11, -1, 1, 0}, +{ 5, s_0_12, -1, 1, 0}, +{ 6, s_0_13, 12, 1, 0}, +{ 5, s_0_14, -1, 1, 0}, +{ 6, s_0_15, -1, 2, 0}, +{ 6, s_0_16, -1, 1, 0}, +{ 2, s_0_17, -1, 1, 0}, +{ 5, s_0_18, 17, 1, 0}, +{ 2, s_0_19, -1, 1, 0}, +{ 4, s_0_20, -1, 1, 0}, +{ 4, s_0_21, -1, 1, 0}, +{ 4, s_0_22, -1, 1, 0}, +{ 5, s_0_23, -1, 1, 0}, +{ 6, s_0_24, 23, 1, 0}, +{ 4, s_0_25, -1, 1, 0}, +{ 4, s_0_26, -1, 1, 0}, +{ 6, s_0_27, -1, 1, 0}, +{ 3, s_0_28, -1, 1, 0}, +{ 4, s_0_29, 28, 1, 0}, +{ 7, s_0_30, 29, 4, 0}, +{ 4, s_0_31, 28, 1, 0}, +{ 4, s_0_32, 28, 1, 0}, +{ 4, s_0_33, -1, 1, 0}, +{ 5, s_0_34, 33, 1, 0}, +{ 4, s_0_35, -1, 1, 0}, +{ 4, s_0_36, -1, 1, 0}, +{ 4, s_0_37, -1, 1, 0}, +{ 4, s_0_38, -1, 1, 0}, +{ 3, s_0_39, -1, 1, 0}, +{ 4, s_0_40, 39, 1, 0}, +{ 6, s_0_41, -1, 1, 0}, +{ 3, s_0_42, -1, 1, 0}, +{ 6, s_0_43, 42, 1, 0}, +{ 3, s_0_44, -1, 2, 0}, +{ 6, s_0_45, 44, 1, 0}, +{ 6, s_0_46, 44, 1, 0}, +{ 6, s_0_47, 44, 1, 0}, +{ 3, s_0_48, -1, 1, 0}, +{ 4, s_0_49, 48, 1, 0}, +{ 4, s_0_50, 48, 1, 0}, +{ 4, s_0_51, 48, 1, 0}, +{ 5, s_0_52, -1, 1, 0}, +{ 5, s_0_53, -1, 1, 0}, +{ 5, s_0_54, -1, 1, 0}, +{ 2, s_0_55, -1, 1, 0}, +{ 4, s_0_56, 55, 1, 0}, +{ 5, s_0_57, 55, 1, 0}, +{ 6, s_0_58, 55, 1, 0}, +{ 4, s_0_59, -1, 1, 0}, +{ 4, s_0_60, -1, 1, 0}, +{ 3, s_0_61, -1, 1, 0}, +{ 4, s_0_62, 61, 1, 0}, +{ 3, s_0_63, -1, 1, 0}, +{ 4, s_0_64, -1, 1, 0}, +{ 5, s_0_65, 64, 1, 0}, +{ 2, s_0_66, -1, 1, 0}, +{ 3, s_0_67, -1, 1, 0}, +{ 4, s_0_68, 67, 1, 0}, +{ 4, s_0_69, 67, 1, 0}, +{ 4, s_0_70, 67, 1, 0}, +{ 5, s_0_71, 70, 1, 0}, +{ 5, s_0_72, -1, 2, 0}, +{ 5, s_0_73, -1, 1, 0}, +{ 5, s_0_74, -1, 1, 0}, +{ 6, s_0_75, 74, 1, 0}, +{ 2, s_0_76, -1, 1, 0}, +{ 3, s_0_77, 76, 1, 0}, +{ 4, s_0_78, 77, 1, 0}, +{ 3, s_0_79, 76, 1, 0}, +{ 4, s_0_80, 76, 1, 0}, +{ 7, s_0_81, -1, 3, 0}, +{ 3, s_0_82, -1, 1, 0}, +{ 3, s_0_83, -1, 1, 0}, +{ 3, s_0_84, -1, 1, 0}, +{ 5, s_0_85, 84, 1, 0}, +{ 4, s_0_86, -1, 1, 0}, +{ 5, s_0_87, 86, 1, 0}, +{ 3, s_0_88, -1, 1, 0}, +{ 5, s_0_89, -1, 1, 0}, +{ 2, s_0_90, -1, 1, 0}, +{ 3, s_0_91, 90, 1, 0}, +{ 3, s_0_92, -1, 1, 0}, +{ 4, s_0_93, -1, 1, 0}, +{ 2, s_0_94, -1, 1, 0}, +{ 3, s_0_95, 94, 1, 0}, +{ 4, s_0_96, -1, 1, 0}, +{ 2, s_0_97, -1, 1, 0}, +{ 5, s_0_98, -1, 1, 0}, +{ 2, s_0_99, -1, 1, 0}, +{ 3, s_0_100, 99, 1, 0}, +{ 6, s_0_101, 100, 1, 0}, +{ 4, s_0_102, 100, 1, 0}, +{ 6, s_0_103, 99, 5, 0}, +{ 2, s_0_104, -1, 1, 0}, +{ 5, s_0_105, 104, 1, 0}, +{ 4, s_0_106, 104, 1, 0}, +{ 5, s_0_107, -1, 1, 0}, +{ 5, s_0_108, -1, 1, 0} }; static const symbol s_1_0[3] = { 'a', 'd', 'a' }; @@ -549,301 +549,301 @@ static const symbol s_1_294[5] = { 'k', 'o', 'i', 't', 'z' }; static const struct among a_1[295] = { -/* 0 */ { 3, s_1_0, -1, 1, 0}, -/* 1 */ { 4, s_1_1, 0, 1, 0}, -/* 2 */ { 4, s_1_2, -1, 1, 0}, -/* 3 */ { 5, s_1_3, -1, 1, 0}, -/* 4 */ { 5, s_1_4, -1, 1, 0}, -/* 5 */ { 5, s_1_5, -1, 1, 0}, -/* 6 */ { 5, s_1_6, -1, 1, 0}, -/* 7 */ { 6, s_1_7, 6, 1, 0}, -/* 8 */ { 6, s_1_8, 6, 1, 0}, -/* 9 */ { 5, s_1_9, -1, 1, 0}, -/* 10 */ { 5, s_1_10, -1, 1, 0}, -/* 11 */ { 6, s_1_11, 10, 1, 0}, -/* 12 */ { 5, s_1_12, -1, 1, 0}, -/* 13 */ { 4, s_1_13, -1, 1, 0}, -/* 14 */ { 5, s_1_14, -1, 1, 0}, -/* 15 */ { 3, s_1_15, -1, 1, 0}, -/* 16 */ { 4, s_1_16, 15, 1, 0}, -/* 17 */ { 6, s_1_17, 15, 1, 0}, -/* 18 */ { 4, s_1_18, 15, 1, 0}, -/* 19 */ { 5, s_1_19, 18, 1, 0}, -/* 20 */ { 3, s_1_20, -1, 1, 0}, -/* 21 */ { 6, s_1_21, -1, 1, 0}, -/* 22 */ { 3, s_1_22, -1, 1, 0}, -/* 23 */ { 5, s_1_23, 22, 1, 0}, -/* 24 */ { 5, s_1_24, 22, 1, 0}, -/* 25 */ { 5, s_1_25, 22, 1, 0}, -/* 26 */ { 5, s_1_26, -1, 1, 0}, -/* 27 */ { 2, s_1_27, -1, 1, 0}, -/* 28 */ { 4, s_1_28, 27, 1, 0}, -/* 29 */ { 4, s_1_29, -1, 1, 0}, -/* 30 */ { 5, s_1_30, -1, 1, 0}, -/* 31 */ { 6, s_1_31, 30, 1, 0}, -/* 32 */ { 6, s_1_32, -1, 1, 0}, -/* 33 */ { 6, s_1_33, -1, 1, 0}, -/* 34 */ { 4, s_1_34, -1, 1, 0}, -/* 35 */ { 4, s_1_35, -1, 1, 0}, -/* 36 */ { 5, s_1_36, 35, 1, 0}, -/* 37 */ { 5, s_1_37, 35, 1, 0}, -/* 38 */ { 5, s_1_38, -1, 1, 0}, -/* 39 */ { 4, s_1_39, -1, 1, 0}, -/* 40 */ { 3, s_1_40, -1, 1, 0}, -/* 41 */ { 5, s_1_41, 40, 1, 0}, -/* 42 */ { 3, s_1_42, -1, 1, 0}, -/* 43 */ { 4, s_1_43, 42, 1, 0}, -/* 44 */ { 4, s_1_44, -1, 1, 0}, -/* 45 */ { 5, s_1_45, 44, 1, 0}, -/* 46 */ { 5, s_1_46, 44, 1, 0}, -/* 47 */ { 5, s_1_47, 44, 1, 0}, -/* 48 */ { 4, s_1_48, -1, 1, 0}, -/* 49 */ { 5, s_1_49, 48, 1, 0}, -/* 50 */ { 5, s_1_50, 48, 1, 0}, -/* 51 */ { 6, s_1_51, -1, 2, 0}, -/* 52 */ { 6, s_1_52, -1, 1, 0}, -/* 53 */ { 6, s_1_53, -1, 1, 0}, -/* 54 */ { 5, s_1_54, -1, 1, 0}, -/* 55 */ { 4, s_1_55, -1, 1, 0}, -/* 56 */ { 3, s_1_56, -1, 1, 0}, -/* 57 */ { 4, s_1_57, -1, 1, 0}, -/* 58 */ { 5, s_1_58, -1, 1, 0}, -/* 59 */ { 6, s_1_59, -1, 1, 0}, -/* 60 */ { 2, s_1_60, -1, 1, 0}, -/* 61 */ { 4, s_1_61, 60, 3, 0}, -/* 62 */ { 5, s_1_62, 60, 10, 0}, -/* 63 */ { 3, s_1_63, 60, 1, 0}, -/* 64 */ { 3, s_1_64, 60, 1, 0}, -/* 65 */ { 3, s_1_65, 60, 1, 0}, -/* 66 */ { 6, s_1_66, -1, 1, 0}, -/* 67 */ { 4, s_1_67, -1, 1, 0}, -/* 68 */ { 5, s_1_68, -1, 1, 0}, -/* 69 */ { 5, s_1_69, -1, 1, 0}, -/* 70 */ { 4, s_1_70, -1, 1, 0}, -/* 71 */ { 3, s_1_71, -1, 1, 0}, -/* 72 */ { 2, s_1_72, -1, 1, 0}, -/* 73 */ { 4, s_1_73, 72, 1, 0}, -/* 74 */ { 3, s_1_74, 72, 1, 0}, -/* 75 */ { 7, s_1_75, 74, 1, 0}, -/* 76 */ { 7, s_1_76, 74, 1, 0}, -/* 77 */ { 6, s_1_77, 74, 1, 0}, -/* 78 */ { 5, s_1_78, 72, 1, 0}, -/* 79 */ { 6, s_1_79, 78, 1, 0}, -/* 80 */ { 4, s_1_80, 72, 1, 0}, -/* 81 */ { 4, s_1_81, 72, 1, 0}, -/* 82 */ { 5, s_1_82, 72, 1, 0}, -/* 83 */ { 3, s_1_83, 72, 1, 0}, -/* 84 */ { 4, s_1_84, 83, 1, 0}, -/* 85 */ { 5, s_1_85, 83, 1, 0}, -/* 86 */ { 6, s_1_86, 85, 1, 0}, -/* 87 */ { 5, s_1_87, -1, 1, 0}, -/* 88 */ { 6, s_1_88, 87, 1, 0}, -/* 89 */ { 4, s_1_89, -1, 1, 0}, -/* 90 */ { 4, s_1_90, -1, 1, 0}, -/* 91 */ { 3, s_1_91, -1, 1, 0}, -/* 92 */ { 5, s_1_92, 91, 1, 0}, -/* 93 */ { 4, s_1_93, 91, 1, 0}, -/* 94 */ { 3, s_1_94, -1, 1, 0}, -/* 95 */ { 5, s_1_95, 94, 1, 0}, -/* 96 */ { 4, s_1_96, -1, 1, 0}, -/* 97 */ { 5, s_1_97, 96, 1, 0}, -/* 98 */ { 5, s_1_98, 96, 1, 0}, -/* 99 */ { 4, s_1_99, -1, 1, 0}, -/*100 */ { 4, s_1_100, -1, 1, 0}, -/*101 */ { 4, s_1_101, -1, 1, 0}, -/*102 */ { 3, s_1_102, -1, 1, 0}, -/*103 */ { 4, s_1_103, 102, 1, 0}, -/*104 */ { 4, s_1_104, 102, 1, 0}, -/*105 */ { 4, s_1_105, -1, 1, 0}, -/*106 */ { 4, s_1_106, -1, 1, 0}, -/*107 */ { 4, s_1_107, -1, 1, 0}, -/*108 */ { 2, s_1_108, -1, 1, 0}, -/*109 */ { 3, s_1_109, 108, 1, 0}, -/*110 */ { 4, s_1_110, 109, 1, 0}, -/*111 */ { 5, s_1_111, 109, 1, 0}, -/*112 */ { 5, s_1_112, 109, 1, 0}, -/*113 */ { 4, s_1_113, 109, 1, 0}, -/*114 */ { 5, s_1_114, 113, 1, 0}, -/*115 */ { 5, s_1_115, 109, 1, 0}, -/*116 */ { 4, s_1_116, 108, 1, 0}, -/*117 */ { 4, s_1_117, 108, 1, 0}, -/*118 */ { 4, s_1_118, 108, 1, 0}, -/*119 */ { 3, s_1_119, 108, 2, 0}, -/*120 */ { 6, s_1_120, 108, 1, 0}, -/*121 */ { 5, s_1_121, 108, 1, 0}, -/*122 */ { 3, s_1_122, 108, 1, 0}, -/*123 */ { 2, s_1_123, -1, 1, 0}, -/*124 */ { 3, s_1_124, 123, 1, 0}, -/*125 */ { 2, s_1_125, -1, 1, 0}, -/*126 */ { 3, s_1_126, 125, 1, 0}, -/*127 */ { 4, s_1_127, 126, 1, 0}, -/*128 */ { 3, s_1_128, 125, 1, 0}, -/*129 */ { 3, s_1_129, -1, 1, 0}, -/*130 */ { 6, s_1_130, 129, 1, 0}, -/*131 */ { 5, s_1_131, 129, 1, 0}, -/*132 */ { 5, s_1_132, -1, 1, 0}, -/*133 */ { 5, s_1_133, -1, 1, 0}, -/*134 */ { 5, s_1_134, -1, 1, 0}, -/*135 */ { 4, s_1_135, -1, 1, 0}, -/*136 */ { 3, s_1_136, -1, 1, 0}, -/*137 */ { 6, s_1_137, 136, 1, 0}, -/*138 */ { 5, s_1_138, 136, 1, 0}, -/*139 */ { 4, s_1_139, -1, 1, 0}, -/*140 */ { 3, s_1_140, -1, 1, 0}, -/*141 */ { 4, s_1_141, 140, 1, 0}, -/*142 */ { 2, s_1_142, -1, 1, 0}, -/*143 */ { 3, s_1_143, 142, 1, 0}, -/*144 */ { 5, s_1_144, 142, 1, 0}, -/*145 */ { 3, s_1_145, 142, 2, 0}, -/*146 */ { 6, s_1_146, 145, 1, 0}, -/*147 */ { 5, s_1_147, 145, 1, 0}, -/*148 */ { 6, s_1_148, 145, 1, 0}, -/*149 */ { 6, s_1_149, 145, 1, 0}, -/*150 */ { 6, s_1_150, 145, 1, 0}, -/*151 */ { 4, s_1_151, -1, 1, 0}, -/*152 */ { 4, s_1_152, -1, 1, 0}, -/*153 */ { 4, s_1_153, -1, 1, 0}, -/*154 */ { 4, s_1_154, -1, 1, 0}, -/*155 */ { 5, s_1_155, 154, 1, 0}, -/*156 */ { 5, s_1_156, 154, 1, 0}, -/*157 */ { 4, s_1_157, -1, 1, 0}, -/*158 */ { 2, s_1_158, -1, 1, 0}, -/*159 */ { 4, s_1_159, -1, 1, 0}, -/*160 */ { 5, s_1_160, 159, 1, 0}, -/*161 */ { 4, s_1_161, -1, 1, 0}, -/*162 */ { 3, s_1_162, -1, 1, 0}, -/*163 */ { 4, s_1_163, -1, 1, 0}, -/*164 */ { 2, s_1_164, -1, 1, 0}, -/*165 */ { 5, s_1_165, 164, 1, 0}, -/*166 */ { 3, s_1_166, 164, 1, 0}, -/*167 */ { 4, s_1_167, 166, 1, 0}, -/*168 */ { 2, s_1_168, -1, 1, 0}, -/*169 */ { 5, s_1_169, -1, 1, 0}, -/*170 */ { 2, s_1_170, -1, 1, 0}, -/*171 */ { 4, s_1_171, 170, 1, 0}, -/*172 */ { 4, s_1_172, 170, 1, 0}, -/*173 */ { 4, s_1_173, 170, 1, 0}, -/*174 */ { 4, s_1_174, -1, 1, 0}, -/*175 */ { 3, s_1_175, -1, 1, 0}, -/*176 */ { 2, s_1_176, -1, 1, 0}, -/*177 */ { 4, s_1_177, 176, 1, 0}, -/*178 */ { 5, s_1_178, 177, 1, 0}, -/*179 */ { 5, s_1_179, 176, 8, 0}, -/*180 */ { 5, s_1_180, 176, 1, 0}, -/*181 */ { 5, s_1_181, 176, 1, 0}, -/*182 */ { 3, s_1_182, -1, 1, 0}, -/*183 */ { 3, s_1_183, -1, 1, 0}, -/*184 */ { 4, s_1_184, 183, 1, 0}, -/*185 */ { 4, s_1_185, 183, 1, 0}, -/*186 */ { 4, s_1_186, -1, 1, 0}, -/*187 */ { 3, s_1_187, -1, 1, 0}, -/*188 */ { 2, s_1_188, -1, 1, 0}, -/*189 */ { 4, s_1_189, 188, 1, 0}, -/*190 */ { 2, s_1_190, -1, 1, 0}, -/*191 */ { 3, s_1_191, 190, 1, 0}, -/*192 */ { 3, s_1_192, 190, 1, 0}, -/*193 */ { 3, s_1_193, -1, 1, 0}, -/*194 */ { 4, s_1_194, 193, 1, 0}, -/*195 */ { 4, s_1_195, 193, 1, 0}, -/*196 */ { 4, s_1_196, 193, 1, 0}, -/*197 */ { 5, s_1_197, -1, 2, 0}, -/*198 */ { 5, s_1_198, -1, 1, 0}, -/*199 */ { 5, s_1_199, -1, 1, 0}, -/*200 */ { 4, s_1_200, -1, 1, 0}, -/*201 */ { 3, s_1_201, -1, 1, 0}, -/*202 */ { 2, s_1_202, -1, 1, 0}, -/*203 */ { 5, s_1_203, -1, 1, 0}, -/*204 */ { 3, s_1_204, -1, 1, 0}, -/*205 */ { 2, s_1_205, -1, 1, 0}, -/*206 */ { 2, s_1_206, -1, 1, 0}, -/*207 */ { 5, s_1_207, -1, 1, 0}, -/*208 */ { 5, s_1_208, -1, 1, 0}, -/*209 */ { 3, s_1_209, -1, 1, 0}, -/*210 */ { 4, s_1_210, 209, 1, 0}, -/*211 */ { 3, s_1_211, -1, 1, 0}, -/*212 */ { 3, s_1_212, -1, 1, 0}, -/*213 */ { 4, s_1_213, 212, 1, 0}, -/*214 */ { 2, s_1_214, -1, 4, 0}, -/*215 */ { 3, s_1_215, 214, 2, 0}, -/*216 */ { 6, s_1_216, 215, 1, 0}, -/*217 */ { 6, s_1_217, 215, 1, 0}, -/*218 */ { 5, s_1_218, 215, 1, 0}, -/*219 */ { 3, s_1_219, 214, 4, 0}, -/*220 */ { 4, s_1_220, 214, 4, 0}, -/*221 */ { 4, s_1_221, -1, 1, 0}, -/*222 */ { 5, s_1_222, 221, 1, 0}, -/*223 */ { 3, s_1_223, -1, 1, 0}, -/*224 */ { 3, s_1_224, -1, 1, 0}, -/*225 */ { 3, s_1_225, -1, 1, 0}, -/*226 */ { 4, s_1_226, -1, 1, 0}, -/*227 */ { 5, s_1_227, 226, 1, 0}, -/*228 */ { 5, s_1_228, -1, 1, 0}, -/*229 */ { 4, s_1_229, -1, 1, 0}, -/*230 */ { 5, s_1_230, 229, 1, 0}, -/*231 */ { 2, s_1_231, -1, 1, 0}, -/*232 */ { 3, s_1_232, 231, 1, 0}, -/*233 */ { 3, s_1_233, -1, 1, 0}, -/*234 */ { 2, s_1_234, -1, 1, 0}, -/*235 */ { 5, s_1_235, 234, 5, 0}, -/*236 */ { 4, s_1_236, 234, 1, 0}, -/*237 */ { 5, s_1_237, 236, 1, 0}, -/*238 */ { 3, s_1_238, 234, 1, 0}, -/*239 */ { 6, s_1_239, 234, 1, 0}, -/*240 */ { 3, s_1_240, 234, 1, 0}, -/*241 */ { 4, s_1_241, 234, 1, 0}, -/*242 */ { 8, s_1_242, 241, 6, 0}, -/*243 */ { 3, s_1_243, 234, 1, 0}, -/*244 */ { 2, s_1_244, -1, 1, 0}, -/*245 */ { 4, s_1_245, 244, 1, 0}, -/*246 */ { 2, s_1_246, -1, 1, 0}, -/*247 */ { 3, s_1_247, 246, 1, 0}, -/*248 */ { 5, s_1_248, 247, 9, 0}, -/*249 */ { 4, s_1_249, 247, 1, 0}, -/*250 */ { 4, s_1_250, 247, 1, 0}, -/*251 */ { 3, s_1_251, 246, 1, 0}, -/*252 */ { 4, s_1_252, 246, 1, 0}, -/*253 */ { 3, s_1_253, 246, 1, 0}, -/*254 */ { 3, s_1_254, -1, 1, 0}, -/*255 */ { 2, s_1_255, -1, 1, 0}, -/*256 */ { 3, s_1_256, 255, 1, 0}, -/*257 */ { 3, s_1_257, 255, 1, 0}, -/*258 */ { 3, s_1_258, -1, 1, 0}, -/*259 */ { 3, s_1_259, -1, 1, 0}, -/*260 */ { 6, s_1_260, 259, 1, 0}, -/*261 */ { 3, s_1_261, -1, 1, 0}, -/*262 */ { 2, s_1_262, -1, 1, 0}, -/*263 */ { 2, s_1_263, -1, 1, 0}, -/*264 */ { 3, s_1_264, 263, 1, 0}, -/*265 */ { 5, s_1_265, 263, 1, 0}, -/*266 */ { 5, s_1_266, 263, 7, 0}, -/*267 */ { 4, s_1_267, 263, 1, 0}, -/*268 */ { 4, s_1_268, 263, 1, 0}, -/*269 */ { 3, s_1_269, 263, 1, 0}, -/*270 */ { 4, s_1_270, 263, 1, 0}, -/*271 */ { 2, s_1_271, -1, 2, 0}, -/*272 */ { 3, s_1_272, 271, 1, 0}, -/*273 */ { 2, s_1_273, -1, 1, 0}, -/*274 */ { 3, s_1_274, -1, 1, 0}, -/*275 */ { 2, s_1_275, -1, 1, 0}, -/*276 */ { 5, s_1_276, 275, 1, 0}, -/*277 */ { 4, s_1_277, 275, 1, 0}, -/*278 */ { 4, s_1_278, -1, 1, 0}, -/*279 */ { 4, s_1_279, -1, 2, 0}, -/*280 */ { 4, s_1_280, -1, 1, 0}, -/*281 */ { 3, s_1_281, -1, 1, 0}, -/*282 */ { 2, s_1_282, -1, 1, 0}, -/*283 */ { 4, s_1_283, 282, 4, 0}, -/*284 */ { 5, s_1_284, 282, 1, 0}, -/*285 */ { 4, s_1_285, 282, 1, 0}, -/*286 */ { 3, s_1_286, -1, 1, 0}, -/*287 */ { 2, s_1_287, -1, 1, 0}, -/*288 */ { 3, s_1_288, 287, 1, 0}, -/*289 */ { 6, s_1_289, 288, 1, 0}, -/*290 */ { 1, s_1_290, -1, 1, 0}, -/*291 */ { 2, s_1_291, 290, 1, 0}, -/*292 */ { 4, s_1_292, 290, 1, 0}, -/*293 */ { 2, s_1_293, 290, 1, 0}, -/*294 */ { 5, s_1_294, 293, 1, 0} +{ 3, s_1_0, -1, 1, 0}, +{ 4, s_1_1, 0, 1, 0}, +{ 4, s_1_2, -1, 1, 0}, +{ 5, s_1_3, -1, 1, 0}, +{ 5, s_1_4, -1, 1, 0}, +{ 5, s_1_5, -1, 1, 0}, +{ 5, s_1_6, -1, 1, 0}, +{ 6, s_1_7, 6, 1, 0}, +{ 6, s_1_8, 6, 1, 0}, +{ 5, s_1_9, -1, 1, 0}, +{ 5, s_1_10, -1, 1, 0}, +{ 6, s_1_11, 10, 1, 0}, +{ 5, s_1_12, -1, 1, 0}, +{ 4, s_1_13, -1, 1, 0}, +{ 5, s_1_14, -1, 1, 0}, +{ 3, s_1_15, -1, 1, 0}, +{ 4, s_1_16, 15, 1, 0}, +{ 6, s_1_17, 15, 1, 0}, +{ 4, s_1_18, 15, 1, 0}, +{ 5, s_1_19, 18, 1, 0}, +{ 3, s_1_20, -1, 1, 0}, +{ 6, s_1_21, -1, 1, 0}, +{ 3, s_1_22, -1, 1, 0}, +{ 5, s_1_23, 22, 1, 0}, +{ 5, s_1_24, 22, 1, 0}, +{ 5, s_1_25, 22, 1, 0}, +{ 5, s_1_26, -1, 1, 0}, +{ 2, s_1_27, -1, 1, 0}, +{ 4, s_1_28, 27, 1, 0}, +{ 4, s_1_29, -1, 1, 0}, +{ 5, s_1_30, -1, 1, 0}, +{ 6, s_1_31, 30, 1, 0}, +{ 6, s_1_32, -1, 1, 0}, +{ 6, s_1_33, -1, 1, 0}, +{ 4, s_1_34, -1, 1, 0}, +{ 4, s_1_35, -1, 1, 0}, +{ 5, s_1_36, 35, 1, 0}, +{ 5, s_1_37, 35, 1, 0}, +{ 5, s_1_38, -1, 1, 0}, +{ 4, s_1_39, -1, 1, 0}, +{ 3, s_1_40, -1, 1, 0}, +{ 5, s_1_41, 40, 1, 0}, +{ 3, s_1_42, -1, 1, 0}, +{ 4, s_1_43, 42, 1, 0}, +{ 4, s_1_44, -1, 1, 0}, +{ 5, s_1_45, 44, 1, 0}, +{ 5, s_1_46, 44, 1, 0}, +{ 5, s_1_47, 44, 1, 0}, +{ 4, s_1_48, -1, 1, 0}, +{ 5, s_1_49, 48, 1, 0}, +{ 5, s_1_50, 48, 1, 0}, +{ 6, s_1_51, -1, 2, 0}, +{ 6, s_1_52, -1, 1, 0}, +{ 6, s_1_53, -1, 1, 0}, +{ 5, s_1_54, -1, 1, 0}, +{ 4, s_1_55, -1, 1, 0}, +{ 3, s_1_56, -1, 1, 0}, +{ 4, s_1_57, -1, 1, 0}, +{ 5, s_1_58, -1, 1, 0}, +{ 6, s_1_59, -1, 1, 0}, +{ 2, s_1_60, -1, 1, 0}, +{ 4, s_1_61, 60, 3, 0}, +{ 5, s_1_62, 60, 10, 0}, +{ 3, s_1_63, 60, 1, 0}, +{ 3, s_1_64, 60, 1, 0}, +{ 3, s_1_65, 60, 1, 0}, +{ 6, s_1_66, -1, 1, 0}, +{ 4, s_1_67, -1, 1, 0}, +{ 5, s_1_68, -1, 1, 0}, +{ 5, s_1_69, -1, 1, 0}, +{ 4, s_1_70, -1, 1, 0}, +{ 3, s_1_71, -1, 1, 0}, +{ 2, s_1_72, -1, 1, 0}, +{ 4, s_1_73, 72, 1, 0}, +{ 3, s_1_74, 72, 1, 0}, +{ 7, s_1_75, 74, 1, 0}, +{ 7, s_1_76, 74, 1, 0}, +{ 6, s_1_77, 74, 1, 0}, +{ 5, s_1_78, 72, 1, 0}, +{ 6, s_1_79, 78, 1, 0}, +{ 4, s_1_80, 72, 1, 0}, +{ 4, s_1_81, 72, 1, 0}, +{ 5, s_1_82, 72, 1, 0}, +{ 3, s_1_83, 72, 1, 0}, +{ 4, s_1_84, 83, 1, 0}, +{ 5, s_1_85, 83, 1, 0}, +{ 6, s_1_86, 85, 1, 0}, +{ 5, s_1_87, -1, 1, 0}, +{ 6, s_1_88, 87, 1, 0}, +{ 4, s_1_89, -1, 1, 0}, +{ 4, s_1_90, -1, 1, 0}, +{ 3, s_1_91, -1, 1, 0}, +{ 5, s_1_92, 91, 1, 0}, +{ 4, s_1_93, 91, 1, 0}, +{ 3, s_1_94, -1, 1, 0}, +{ 5, s_1_95, 94, 1, 0}, +{ 4, s_1_96, -1, 1, 0}, +{ 5, s_1_97, 96, 1, 0}, +{ 5, s_1_98, 96, 1, 0}, +{ 4, s_1_99, -1, 1, 0}, +{ 4, s_1_100, -1, 1, 0}, +{ 4, s_1_101, -1, 1, 0}, +{ 3, s_1_102, -1, 1, 0}, +{ 4, s_1_103, 102, 1, 0}, +{ 4, s_1_104, 102, 1, 0}, +{ 4, s_1_105, -1, 1, 0}, +{ 4, s_1_106, -1, 1, 0}, +{ 4, s_1_107, -1, 1, 0}, +{ 2, s_1_108, -1, 1, 0}, +{ 3, s_1_109, 108, 1, 0}, +{ 4, s_1_110, 109, 1, 0}, +{ 5, s_1_111, 109, 1, 0}, +{ 5, s_1_112, 109, 1, 0}, +{ 4, s_1_113, 109, 1, 0}, +{ 5, s_1_114, 113, 1, 0}, +{ 5, s_1_115, 109, 1, 0}, +{ 4, s_1_116, 108, 1, 0}, +{ 4, s_1_117, 108, 1, 0}, +{ 4, s_1_118, 108, 1, 0}, +{ 3, s_1_119, 108, 2, 0}, +{ 6, s_1_120, 108, 1, 0}, +{ 5, s_1_121, 108, 1, 0}, +{ 3, s_1_122, 108, 1, 0}, +{ 2, s_1_123, -1, 1, 0}, +{ 3, s_1_124, 123, 1, 0}, +{ 2, s_1_125, -1, 1, 0}, +{ 3, s_1_126, 125, 1, 0}, +{ 4, s_1_127, 126, 1, 0}, +{ 3, s_1_128, 125, 1, 0}, +{ 3, s_1_129, -1, 1, 0}, +{ 6, s_1_130, 129, 1, 0}, +{ 5, s_1_131, 129, 1, 0}, +{ 5, s_1_132, -1, 1, 0}, +{ 5, s_1_133, -1, 1, 0}, +{ 5, s_1_134, -1, 1, 0}, +{ 4, s_1_135, -1, 1, 0}, +{ 3, s_1_136, -1, 1, 0}, +{ 6, s_1_137, 136, 1, 0}, +{ 5, s_1_138, 136, 1, 0}, +{ 4, s_1_139, -1, 1, 0}, +{ 3, s_1_140, -1, 1, 0}, +{ 4, s_1_141, 140, 1, 0}, +{ 2, s_1_142, -1, 1, 0}, +{ 3, s_1_143, 142, 1, 0}, +{ 5, s_1_144, 142, 1, 0}, +{ 3, s_1_145, 142, 2, 0}, +{ 6, s_1_146, 145, 1, 0}, +{ 5, s_1_147, 145, 1, 0}, +{ 6, s_1_148, 145, 1, 0}, +{ 6, s_1_149, 145, 1, 0}, +{ 6, s_1_150, 145, 1, 0}, +{ 4, s_1_151, -1, 1, 0}, +{ 4, s_1_152, -1, 1, 0}, +{ 4, s_1_153, -1, 1, 0}, +{ 4, s_1_154, -1, 1, 0}, +{ 5, s_1_155, 154, 1, 0}, +{ 5, s_1_156, 154, 1, 0}, +{ 4, s_1_157, -1, 1, 0}, +{ 2, s_1_158, -1, 1, 0}, +{ 4, s_1_159, -1, 1, 0}, +{ 5, s_1_160, 159, 1, 0}, +{ 4, s_1_161, -1, 1, 0}, +{ 3, s_1_162, -1, 1, 0}, +{ 4, s_1_163, -1, 1, 0}, +{ 2, s_1_164, -1, 1, 0}, +{ 5, s_1_165, 164, 1, 0}, +{ 3, s_1_166, 164, 1, 0}, +{ 4, s_1_167, 166, 1, 0}, +{ 2, s_1_168, -1, 1, 0}, +{ 5, s_1_169, -1, 1, 0}, +{ 2, s_1_170, -1, 1, 0}, +{ 4, s_1_171, 170, 1, 0}, +{ 4, s_1_172, 170, 1, 0}, +{ 4, s_1_173, 170, 1, 0}, +{ 4, s_1_174, -1, 1, 0}, +{ 3, s_1_175, -1, 1, 0}, +{ 2, s_1_176, -1, 1, 0}, +{ 4, s_1_177, 176, 1, 0}, +{ 5, s_1_178, 177, 1, 0}, +{ 5, s_1_179, 176, 8, 0}, +{ 5, s_1_180, 176, 1, 0}, +{ 5, s_1_181, 176, 1, 0}, +{ 3, s_1_182, -1, 1, 0}, +{ 3, s_1_183, -1, 1, 0}, +{ 4, s_1_184, 183, 1, 0}, +{ 4, s_1_185, 183, 1, 0}, +{ 4, s_1_186, -1, 1, 0}, +{ 3, s_1_187, -1, 1, 0}, +{ 2, s_1_188, -1, 1, 0}, +{ 4, s_1_189, 188, 1, 0}, +{ 2, s_1_190, -1, 1, 0}, +{ 3, s_1_191, 190, 1, 0}, +{ 3, s_1_192, 190, 1, 0}, +{ 3, s_1_193, -1, 1, 0}, +{ 4, s_1_194, 193, 1, 0}, +{ 4, s_1_195, 193, 1, 0}, +{ 4, s_1_196, 193, 1, 0}, +{ 5, s_1_197, -1, 2, 0}, +{ 5, s_1_198, -1, 1, 0}, +{ 5, s_1_199, -1, 1, 0}, +{ 4, s_1_200, -1, 1, 0}, +{ 3, s_1_201, -1, 1, 0}, +{ 2, s_1_202, -1, 1, 0}, +{ 5, s_1_203, -1, 1, 0}, +{ 3, s_1_204, -1, 1, 0}, +{ 2, s_1_205, -1, 1, 0}, +{ 2, s_1_206, -1, 1, 0}, +{ 5, s_1_207, -1, 1, 0}, +{ 5, s_1_208, -1, 1, 0}, +{ 3, s_1_209, -1, 1, 0}, +{ 4, s_1_210, 209, 1, 0}, +{ 3, s_1_211, -1, 1, 0}, +{ 3, s_1_212, -1, 1, 0}, +{ 4, s_1_213, 212, 1, 0}, +{ 2, s_1_214, -1, 4, 0}, +{ 3, s_1_215, 214, 2, 0}, +{ 6, s_1_216, 215, 1, 0}, +{ 6, s_1_217, 215, 1, 0}, +{ 5, s_1_218, 215, 1, 0}, +{ 3, s_1_219, 214, 4, 0}, +{ 4, s_1_220, 214, 4, 0}, +{ 4, s_1_221, -1, 1, 0}, +{ 5, s_1_222, 221, 1, 0}, +{ 3, s_1_223, -1, 1, 0}, +{ 3, s_1_224, -1, 1, 0}, +{ 3, s_1_225, -1, 1, 0}, +{ 4, s_1_226, -1, 1, 0}, +{ 5, s_1_227, 226, 1, 0}, +{ 5, s_1_228, -1, 1, 0}, +{ 4, s_1_229, -1, 1, 0}, +{ 5, s_1_230, 229, 1, 0}, +{ 2, s_1_231, -1, 1, 0}, +{ 3, s_1_232, 231, 1, 0}, +{ 3, s_1_233, -1, 1, 0}, +{ 2, s_1_234, -1, 1, 0}, +{ 5, s_1_235, 234, 5, 0}, +{ 4, s_1_236, 234, 1, 0}, +{ 5, s_1_237, 236, 1, 0}, +{ 3, s_1_238, 234, 1, 0}, +{ 6, s_1_239, 234, 1, 0}, +{ 3, s_1_240, 234, 1, 0}, +{ 4, s_1_241, 234, 1, 0}, +{ 8, s_1_242, 241, 6, 0}, +{ 3, s_1_243, 234, 1, 0}, +{ 2, s_1_244, -1, 1, 0}, +{ 4, s_1_245, 244, 1, 0}, +{ 2, s_1_246, -1, 1, 0}, +{ 3, s_1_247, 246, 1, 0}, +{ 5, s_1_248, 247, 9, 0}, +{ 4, s_1_249, 247, 1, 0}, +{ 4, s_1_250, 247, 1, 0}, +{ 3, s_1_251, 246, 1, 0}, +{ 4, s_1_252, 246, 1, 0}, +{ 3, s_1_253, 246, 1, 0}, +{ 3, s_1_254, -1, 1, 0}, +{ 2, s_1_255, -1, 1, 0}, +{ 3, s_1_256, 255, 1, 0}, +{ 3, s_1_257, 255, 1, 0}, +{ 3, s_1_258, -1, 1, 0}, +{ 3, s_1_259, -1, 1, 0}, +{ 6, s_1_260, 259, 1, 0}, +{ 3, s_1_261, -1, 1, 0}, +{ 2, s_1_262, -1, 1, 0}, +{ 2, s_1_263, -1, 1, 0}, +{ 3, s_1_264, 263, 1, 0}, +{ 5, s_1_265, 263, 1, 0}, +{ 5, s_1_266, 263, 7, 0}, +{ 4, s_1_267, 263, 1, 0}, +{ 4, s_1_268, 263, 1, 0}, +{ 3, s_1_269, 263, 1, 0}, +{ 4, s_1_270, 263, 1, 0}, +{ 2, s_1_271, -1, 2, 0}, +{ 3, s_1_272, 271, 1, 0}, +{ 2, s_1_273, -1, 1, 0}, +{ 3, s_1_274, -1, 1, 0}, +{ 2, s_1_275, -1, 1, 0}, +{ 5, s_1_276, 275, 1, 0}, +{ 4, s_1_277, 275, 1, 0}, +{ 4, s_1_278, -1, 1, 0}, +{ 4, s_1_279, -1, 2, 0}, +{ 4, s_1_280, -1, 1, 0}, +{ 3, s_1_281, -1, 1, 0}, +{ 2, s_1_282, -1, 1, 0}, +{ 4, s_1_283, 282, 4, 0}, +{ 5, s_1_284, 282, 1, 0}, +{ 4, s_1_285, 282, 1, 0}, +{ 3, s_1_286, -1, 1, 0}, +{ 2, s_1_287, -1, 1, 0}, +{ 3, s_1_288, 287, 1, 0}, +{ 6, s_1_289, 288, 1, 0}, +{ 1, s_1_290, -1, 1, 0}, +{ 2, s_1_291, 290, 1, 0}, +{ 4, s_1_292, 290, 1, 0}, +{ 2, s_1_293, 290, 1, 0}, +{ 5, s_1_294, 293, 1, 0} }; static const symbol s_2_0[4] = { 'z', 'l', 'e', 'a' }; @@ -868,25 +868,25 @@ static const symbol s_2_18[2] = { 't', 'o' }; static const struct among a_2[19] = { -/* 0 */ { 4, s_2_0, -1, 2, 0}, -/* 1 */ { 5, s_2_1, -1, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 1, 0}, -/* 3 */ { 3, s_2_3, -1, 1, 0}, -/* 4 */ { 4, s_2_4, -1, 1, 0}, -/* 5 */ { 4, s_2_5, -1, 1, 0}, -/* 6 */ { 4, s_2_6, -1, 1, 0}, -/* 7 */ { 4, s_2_7, -1, 1, 0}, -/* 8 */ { 2, s_2_8, -1, 1, 0}, -/* 9 */ { 2, s_2_9, -1, 1, 0}, -/* 10 */ { 2, s_2_10, -1, 1, 0}, -/* 11 */ { 5, s_2_11, 10, 1, 0}, -/* 12 */ { 3, s_2_12, 10, 1, 0}, -/* 13 */ { 5, s_2_13, 12, 1, 0}, -/* 14 */ { 4, s_2_14, 10, 1, 0}, -/* 15 */ { 2, s_2_15, -1, 1, 0}, -/* 16 */ { 2, s_2_16, -1, 1, 0}, -/* 17 */ { 3, s_2_17, 16, 1, 0}, -/* 18 */ { 2, s_2_18, -1, 1, 0} +{ 4, s_2_0, -1, 2, 0}, +{ 5, s_2_1, -1, 1, 0}, +{ 2, s_2_2, -1, 1, 0}, +{ 3, s_2_3, -1, 1, 0}, +{ 4, s_2_4, -1, 1, 0}, +{ 4, s_2_5, -1, 1, 0}, +{ 4, s_2_6, -1, 1, 0}, +{ 4, s_2_7, -1, 1, 0}, +{ 2, s_2_8, -1, 1, 0}, +{ 2, s_2_9, -1, 1, 0}, +{ 2, s_2_10, -1, 1, 0}, +{ 5, s_2_11, 10, 1, 0}, +{ 3, s_2_12, 10, 1, 0}, +{ 5, s_2_13, 12, 1, 0}, +{ 4, s_2_14, 10, 1, 0}, +{ 2, s_2_15, -1, 1, 0}, +{ 2, s_2_16, -1, 1, 0}, +{ 3, s_2_17, 16, 1, 0}, +{ 2, s_2_18, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16 }; @@ -903,16 +903,16 @@ static const symbol s_8[] = { 'i', 'g', 'a', 'r', 'o' }; static const symbol s_9[] = { 'a', 'u', 'r', 'k', 'a' }; static const symbol s_10[] = { 'z' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 25 */ - z->I[1] = z->l; /* $p1 = , line 26 */ - z->I[2] = z->l; /* $p2 = , line 27 */ - { int c1 = z->c; /* do, line 29 */ - { int c2 = z->c; /* or, line 31 */ - if (in_grouping_U(z, g_v, 97, 117, 0)) goto lab2; /* grouping v, line 30 */ - { int c3 = z->c; /* or, line 30 */ - if (out_grouping_U(z, g_v, 97, 117, 0)) goto lab4; /* non v, line 30 */ - { /* gopast */ /* grouping v, line 30 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping_U(z, g_v, 97, 117, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping_U(z, g_v, 97, 117, 0)) goto lab4; + { int ret = out_grouping_U(z, g_v, 97, 117, 1); if (ret < 0) goto lab4; z->c += ret; @@ -920,8 +920,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 117, 0)) goto lab2; /* grouping v, line 30 */ - { /* gopast */ /* non v, line 30 */ + if (in_grouping_U(z, g_v, 97, 117, 0)) goto lab2; + { int ret = in_grouping_U(z, g_v, 97, 117, 1); if (ret < 0) goto lab2; z->c += ret; @@ -931,10 +931,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 117, 0)) goto lab0; /* non v, line 32 */ - { int c4 = z->c; /* or, line 32 */ - if (out_grouping_U(z, g_v, 97, 117, 0)) goto lab6; /* non v, line 32 */ - { /* gopast */ /* grouping v, line 32 */ + if (out_grouping_U(z, g_v, 97, 117, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping_U(z, g_v, 97, 117, 0)) goto lab6; + { int ret = out_grouping_U(z, g_v, 97, 117, 1); if (ret < 0) goto lab6; z->c += ret; @@ -942,100 +942,100 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 117, 0)) goto lab0; /* grouping v, line 32 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (in_grouping_U(z, g_v, 97, 117, 0)) goto lab0; + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 32 */ + z->c = ret; } } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 33 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 35 */ - { /* gopast */ /* grouping v, line 36 */ + { int c5 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 36 */ + { int ret = in_grouping_U(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 36 */ - { /* gopast */ /* grouping v, line 37 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 37 */ + { int ret = in_grouping_U(z, g_v, 97, 117, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 37 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 43 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 44 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 45 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_aditzak(struct SN_env * z) { /* backwardmode */ +static int r_aditzak(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 48 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((70566434 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 48 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((70566434 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_0, 109); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 48 */ - switch (among_var) { /* among, line 48 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 59 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 59 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 61 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 61 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 7, s_0); /* <-, line 63 */ + { int ret = slice_from_s(z, 7, s_0); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 7, s_1); /* <-, line 65 */ + { int ret = slice_from_s(z, 7, s_1); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 6, s_2); /* <-, line 67 */ + { int ret = slice_from_s(z, 6, s_2); if (ret < 0) return ret; } break; @@ -1043,70 +1043,70 @@ static int r_aditzak(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_izenak(struct SN_env * z) { /* backwardmode */ +static int r_izenak(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 73 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((71162402 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 73 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((71162402 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_1, 295); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 73 */ - switch (among_var) { /* among, line 73 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 103 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 103 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 105 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 105 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_3); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_3); if (ret < 0) return ret; } break; case 4: - { int ret = r_R1(z); /* call R1, line 109 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 109 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_4); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 6, s_5); /* <-, line 113 */ + { int ret = slice_from_s(z, 6, s_5); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 5, s_6); /* <-, line 115 */ + { int ret = slice_from_s(z, 5, s_6); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 5, s_7); /* <-, line 117 */ + { int ret = slice_from_s(z, 5, s_7); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 5, s_8); /* <-, line 119 */ + { int ret = slice_from_s(z, 5, s_8); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 5, s_9); /* <-, line 121 */ + { int ret = slice_from_s(z, 5, s_9); if (ret < 0) return ret; } break; @@ -1114,24 +1114,24 @@ static int r_izenak(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_adjetiboak(struct SN_env * z) { /* backwardmode */ +static int r_adjetiboak(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 126 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((35362 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 126 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((35362 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_2, 19); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 126 */ - switch (among_var) { /* among, line 126 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 129 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 129 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 131 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; @@ -1139,17 +1139,16 @@ static int r_adjetiboak(struct SN_env * z) { /* backwardmode */ return 1; } -extern int basque_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - /* do, line 138 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 138 */ +extern int basque_UTF_8_stem(struct SN_env * z) { + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 139 */ + z->lb = z->c; z->c = z->l; -/* repeat, line 140 */ - - while(1) { int m1 = z->l - z->c; (void)m1; - { int ret = r_aditzak(z); /* call aditzak, line 140 */ + while(1) { + int m1 = z->l - z->c; (void)m1; + { int ret = r_aditzak(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1158,10 +1157,9 @@ extern int basque_UTF_8_stem(struct SN_env * z) { /* forwardmode */ z->c = z->l - m1; break; } -/* repeat, line 141 */ - - while(1) { int m2 = z->l - z->c; (void)m2; - { int ret = r_izenak(z); /* call izenak, line 141 */ + while(1) { + int m2 = z->l - z->c; (void)m2; + { int ret = r_izenak(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } @@ -1170,8 +1168,8 @@ extern int basque_UTF_8_stem(struct SN_env * z) { /* forwardmode */ z->c = z->l - m2; break; } - { int m3 = z->l - z->c; (void)m3; /* do, line 142 */ - { int ret = r_adjetiboak(z); /* call adjetiboak, line 142 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_adjetiboak(z); if (ret < 0) return ret; } z->c = z->l - m3; @@ -1180,7 +1178,7 @@ extern int basque_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * basque_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * basque_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void basque_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_catalan.c b/src/backend/snowball/libstemmer/stem_UTF_8_catalan.c index 23cf4e534bd1..f92579f37b9a 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_catalan.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_catalan.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -44,19 +44,19 @@ static const symbol s_0_12[2] = { 0xC3, 0xBC }; static const struct among a_0[13] = { -/* 0 */ { 0, 0, -1, 7, 0}, -/* 1 */ { 2, s_0_1, 0, 6, 0}, -/* 2 */ { 2, s_0_2, 0, 1, 0}, -/* 3 */ { 2, s_0_3, 0, 1, 0}, -/* 4 */ { 2, s_0_4, 0, 2, 0}, -/* 5 */ { 2, s_0_5, 0, 2, 0}, -/* 6 */ { 2, s_0_6, 0, 3, 0}, -/* 7 */ { 2, s_0_7, 0, 3, 0}, -/* 8 */ { 2, s_0_8, 0, 3, 0}, -/* 9 */ { 2, s_0_9, 0, 4, 0}, -/* 10 */ { 2, s_0_10, 0, 4, 0}, -/* 11 */ { 2, s_0_11, 0, 5, 0}, -/* 12 */ { 2, s_0_12, 0, 5, 0} +{ 0, 0, -1, 7, 0}, +{ 2, s_0_1, 0, 6, 0}, +{ 2, s_0_2, 0, 1, 0}, +{ 2, s_0_3, 0, 1, 0}, +{ 2, s_0_4, 0, 2, 0}, +{ 2, s_0_5, 0, 2, 0}, +{ 2, s_0_6, 0, 3, 0}, +{ 2, s_0_7, 0, 3, 0}, +{ 2, s_0_8, 0, 3, 0}, +{ 2, s_0_9, 0, 4, 0}, +{ 2, s_0_10, 0, 4, 0}, +{ 2, s_0_11, 0, 5, 0}, +{ 2, s_0_12, 0, 5, 0} }; static const symbol s_1_0[2] = { 'l', 'a' }; @@ -101,45 +101,45 @@ static const symbol s_1_38[2] = { '\'', 't' }; static const struct among a_1[39] = { -/* 0 */ { 2, s_1_0, -1, 1, 0}, -/* 1 */ { 3, s_1_1, 0, 1, 0}, -/* 2 */ { 4, s_1_2, 0, 1, 0}, -/* 3 */ { 2, s_1_3, -1, 1, 0}, -/* 4 */ { 2, s_1_4, -1, 1, 0}, -/* 5 */ { 3, s_1_5, 4, 1, 0}, -/* 6 */ { 2, s_1_6, -1, 1, 0}, -/* 7 */ { 3, s_1_7, -1, 1, 0}, -/* 8 */ { 2, s_1_8, -1, 1, 0}, -/* 9 */ { 3, s_1_9, 8, 1, 0}, -/* 10 */ { 2, s_1_10, -1, 1, 0}, -/* 11 */ { 3, s_1_11, 10, 1, 0}, -/* 12 */ { 2, s_1_12, -1, 1, 0}, -/* 13 */ { 2, s_1_13, -1, 1, 0}, -/* 14 */ { 2, s_1_14, -1, 1, 0}, -/* 15 */ { 2, s_1_15, -1, 1, 0}, -/* 16 */ { 2, s_1_16, -1, 1, 0}, -/* 17 */ { 2, s_1_17, -1, 1, 0}, -/* 18 */ { 3, s_1_18, 17, 1, 0}, -/* 19 */ { 2, s_1_19, -1, 1, 0}, -/* 20 */ { 4, s_1_20, 19, 1, 0}, -/* 21 */ { 2, s_1_21, -1, 1, 0}, -/* 22 */ { 3, s_1_22, -1, 1, 0}, -/* 23 */ { 5, s_1_23, 22, 1, 0}, -/* 24 */ { 3, s_1_24, -1, 1, 0}, -/* 25 */ { 4, s_1_25, 24, 1, 0}, -/* 26 */ { 3, s_1_26, -1, 1, 0}, -/* 27 */ { 3, s_1_27, -1, 1, 0}, -/* 28 */ { 3, s_1_28, -1, 1, 0}, -/* 29 */ { 3, s_1_29, -1, 1, 0}, -/* 30 */ { 3, s_1_30, -1, 1, 0}, -/* 31 */ { 3, s_1_31, -1, 1, 0}, -/* 32 */ { 5, s_1_32, 31, 1, 0}, -/* 33 */ { 3, s_1_33, -1, 1, 0}, -/* 34 */ { 4, s_1_34, 33, 1, 0}, -/* 35 */ { 3, s_1_35, -1, 1, 0}, -/* 36 */ { 2, s_1_36, -1, 1, 0}, -/* 37 */ { 3, s_1_37, 36, 1, 0}, -/* 38 */ { 2, s_1_38, -1, 1, 0} +{ 2, s_1_0, -1, 1, 0}, +{ 3, s_1_1, 0, 1, 0}, +{ 4, s_1_2, 0, 1, 0}, +{ 2, s_1_3, -1, 1, 0}, +{ 2, s_1_4, -1, 1, 0}, +{ 3, s_1_5, 4, 1, 0}, +{ 2, s_1_6, -1, 1, 0}, +{ 3, s_1_7, -1, 1, 0}, +{ 2, s_1_8, -1, 1, 0}, +{ 3, s_1_9, 8, 1, 0}, +{ 2, s_1_10, -1, 1, 0}, +{ 3, s_1_11, 10, 1, 0}, +{ 2, s_1_12, -1, 1, 0}, +{ 2, s_1_13, -1, 1, 0}, +{ 2, s_1_14, -1, 1, 0}, +{ 2, s_1_15, -1, 1, 0}, +{ 2, s_1_16, -1, 1, 0}, +{ 2, s_1_17, -1, 1, 0}, +{ 3, s_1_18, 17, 1, 0}, +{ 2, s_1_19, -1, 1, 0}, +{ 4, s_1_20, 19, 1, 0}, +{ 2, s_1_21, -1, 1, 0}, +{ 3, s_1_22, -1, 1, 0}, +{ 5, s_1_23, 22, 1, 0}, +{ 3, s_1_24, -1, 1, 0}, +{ 4, s_1_25, 24, 1, 0}, +{ 3, s_1_26, -1, 1, 0}, +{ 3, s_1_27, -1, 1, 0}, +{ 3, s_1_28, -1, 1, 0}, +{ 3, s_1_29, -1, 1, 0}, +{ 3, s_1_30, -1, 1, 0}, +{ 3, s_1_31, -1, 1, 0}, +{ 5, s_1_32, 31, 1, 0}, +{ 3, s_1_33, -1, 1, 0}, +{ 4, s_1_34, 33, 1, 0}, +{ 3, s_1_35, -1, 1, 0}, +{ 2, s_1_36, -1, 1, 0}, +{ 3, s_1_37, 36, 1, 0}, +{ 2, s_1_38, -1, 1, 0} }; static const symbol s_2_0[3] = { 'i', 'c', 'a' }; @@ -345,206 +345,206 @@ static const symbol s_2_199[5] = { 'a', 'c', 'i', 0xC3, 0xB3 }; static const struct among a_2[200] = { -/* 0 */ { 3, s_2_0, -1, 4, 0}, -/* 1 */ { 7, s_2_1, 0, 3, 0}, -/* 2 */ { 4, s_2_2, -1, 1, 0}, -/* 3 */ { 3, s_2_3, -1, 2, 0}, -/* 4 */ { 5, s_2_4, -1, 1, 0}, -/* 5 */ { 5, s_2_5, -1, 1, 0}, -/* 6 */ { 6, s_2_6, -1, 1, 0}, -/* 7 */ { 5, s_2_7, -1, 1, 0}, -/* 8 */ { 5, s_2_8, -1, 3, 0}, -/* 9 */ { 4, s_2_9, -1, 1, 0}, -/* 10 */ { 6, s_2_10, 9, 1, 0}, -/* 11 */ { 4, s_2_11, -1, 1, 0}, -/* 12 */ { 5, s_2_12, -1, 1, 0}, -/* 13 */ { 7, s_2_13, -1, 1, 0}, -/* 14 */ { 4, s_2_14, -1, 1, 0}, -/* 15 */ { 4, s_2_15, -1, 1, 0}, -/* 16 */ { 6, s_2_16, -1, 1, 0}, -/* 17 */ { 3, s_2_17, -1, 1, 0}, -/* 18 */ { 7, s_2_18, 17, 1, 0}, -/* 19 */ { 9, s_2_19, 18, 5, 0}, -/* 20 */ { 3, s_2_20, -1, 1, 0}, -/* 21 */ { 3, s_2_21, -1, 1, 0}, -/* 22 */ { 3, s_2_22, -1, 1, 0}, -/* 23 */ { 5, s_2_23, 22, 1, 0}, -/* 24 */ { 3, s_2_24, -1, 1, 0}, -/* 25 */ { 4, s_2_25, 24, 1, 0}, -/* 26 */ { 5, s_2_26, 25, 1, 0}, -/* 27 */ { 5, s_2_27, -1, 1, 0}, -/* 28 */ { 3, s_2_28, -1, 1, 0}, -/* 29 */ { 3, s_2_29, -1, 1, 0}, -/* 30 */ { 4, s_2_30, -1, 1, 0}, -/* 31 */ { 4, s_2_31, -1, 1, 0}, -/* 32 */ { 4, s_2_32, -1, 1, 0}, -/* 33 */ { 3, s_2_33, -1, 1, 0}, -/* 34 */ { 3, s_2_34, -1, 1, 0}, -/* 35 */ { 3, s_2_35, -1, 1, 0}, -/* 36 */ { 4, s_2_36, -1, 1, 0}, -/* 37 */ { 7, s_2_37, 36, 1, 0}, -/* 38 */ { 7, s_2_38, 36, 1, 0}, -/* 39 */ { 3, s_2_39, -1, 1, 0}, -/* 40 */ { 5, s_2_40, 39, 1, 0}, -/* 41 */ { 4, s_2_41, -1, 1, 0}, -/* 42 */ { 6, s_2_42, -1, 3, 0}, -/* 43 */ { 2, s_2_43, -1, 4, 0}, -/* 44 */ { 6, s_2_44, 43, 1, 0}, -/* 45 */ { 3, s_2_45, -1, 1, 0}, -/* 46 */ { 3, s_2_46, -1, 1, 0}, -/* 47 */ { 2, s_2_47, -1, 1, 0}, -/* 48 */ { 4, s_2_48, -1, 1, 0}, -/* 49 */ { 3, s_2_49, -1, 1, 0}, -/* 50 */ { 4, s_2_50, 49, 1, 0}, -/* 51 */ { 4, s_2_51, 49, 1, 0}, -/* 52 */ { 4, s_2_52, -1, 1, 0}, -/* 53 */ { 7, s_2_53, 52, 1, 0}, -/* 54 */ { 7, s_2_54, 52, 1, 0}, -/* 55 */ { 6, s_2_55, 52, 1, 0}, -/* 56 */ { 4, s_2_56, -1, 1, 0}, -/* 57 */ { 4, s_2_57, -1, 1, 0}, -/* 58 */ { 4, s_2_58, -1, 1, 0}, -/* 59 */ { 3, s_2_59, -1, 1, 0}, -/* 60 */ { 4, s_2_60, -1, 1, 0}, -/* 61 */ { 4, s_2_61, -1, 3, 0}, -/* 62 */ { 3, s_2_62, -1, 1, 0}, -/* 63 */ { 4, s_2_63, -1, 1, 0}, -/* 64 */ { 2, s_2_64, -1, 1, 0}, -/* 65 */ { 2, s_2_65, -1, 1, 0}, -/* 66 */ { 3, s_2_66, -1, 1, 0}, -/* 67 */ { 3, s_2_67, -1, 1, 0}, -/* 68 */ { 5, s_2_68, -1, 1, 0}, -/* 69 */ { 4, s_2_69, -1, 1, 0}, -/* 70 */ { 5, s_2_70, -1, 1, 0}, -/* 71 */ { 6, s_2_71, -1, 1, 0}, -/* 72 */ { 6, s_2_72, -1, 1, 0}, -/* 73 */ { 6, s_2_73, -1, 1, 0}, -/* 74 */ { 8, s_2_74, 73, 5, 0}, -/* 75 */ { 4, s_2_75, -1, 1, 0}, -/* 76 */ { 6, s_2_76, -1, 1, 0}, -/* 77 */ { 2, s_2_77, -1, 1, 0}, -/* 78 */ { 6, s_2_78, 77, 1, 0}, -/* 79 */ { 4, s_2_79, 77, 1, 0}, -/* 80 */ { 4, s_2_80, 77, 1, 0}, -/* 81 */ { 4, s_2_81, 77, 1, 0}, -/* 82 */ { 5, s_2_82, 77, 1, 0}, -/* 83 */ { 3, s_2_83, -1, 1, 0}, -/* 84 */ { 2, s_2_84, -1, 1, 0}, -/* 85 */ { 3, s_2_85, 84, 1, 0}, -/* 86 */ { 3, s_2_86, -1, 1, 0}, -/* 87 */ { 5, s_2_87, -1, 1, 0}, -/* 88 */ { 3, s_2_88, -1, 4, 0}, -/* 89 */ { 7, s_2_89, 88, 3, 0}, -/* 90 */ { 3, s_2_90, -1, 1, 0}, -/* 91 */ { 4, s_2_91, -1, 1, 0}, -/* 92 */ { 4, s_2_92, -1, 2, 0}, -/* 93 */ { 6, s_2_93, -1, 1, 0}, -/* 94 */ { 6, s_2_94, -1, 1, 0}, -/* 95 */ { 7, s_2_95, -1, 1, 0}, -/* 96 */ { 6, s_2_96, -1, 1, 0}, -/* 97 */ { 6, s_2_97, -1, 3, 0}, -/* 98 */ { 5, s_2_98, -1, 1, 0}, -/* 99 */ { 6, s_2_99, -1, 1, 0}, -/*100 */ { 5, s_2_100, -1, 1, 0}, -/*101 */ { 6, s_2_101, -1, 1, 0}, -/*102 */ { 8, s_2_102, -1, 1, 0}, -/*103 */ { 4, s_2_103, -1, 1, 0}, -/*104 */ { 5, s_2_104, 103, 1, 0}, -/*105 */ { 5, s_2_105, 103, 1, 0}, -/*106 */ { 4, s_2_106, -1, 1, 0}, -/*107 */ { 8, s_2_107, 106, 1, 0}, -/*108 */ { 10, s_2_108, 107, 5, 0}, -/*109 */ { 6, s_2_109, -1, 1, 0}, -/*110 */ { 5, s_2_110, -1, 1, 0}, -/*111 */ { 8, s_2_111, 110, 1, 0}, -/*112 */ { 4, s_2_112, -1, 1, 0}, -/*113 */ { 4, s_2_113, -1, 1, 0}, -/*114 */ { 4, s_2_114, -1, 1, 0}, -/*115 */ { 5, s_2_115, 114, 1, 0}, -/*116 */ { 6, s_2_116, 115, 1, 0}, -/*117 */ { 5, s_2_117, -1, 1, 0}, -/*118 */ { 4, s_2_118, -1, 1, 0}, -/*119 */ { 4, s_2_119, -1, 1, 0}, -/*120 */ { 5, s_2_120, -1, 1, 0}, -/*121 */ { 5, s_2_121, -1, 1, 0}, -/*122 */ { 4, s_2_122, -1, 1, 0}, -/*123 */ { 4, s_2_123, -1, 1, 0}, -/*124 */ { 5, s_2_124, -1, 1, 0}, -/*125 */ { 8, s_2_125, 124, 1, 0}, -/*126 */ { 8, s_2_126, 124, 1, 0}, -/*127 */ { 5, s_2_127, -1, 4, 0}, -/*128 */ { 9, s_2_128, 127, 3, 0}, -/*129 */ { 4, s_2_129, -1, 1, 0}, -/*130 */ { 6, s_2_130, 129, 1, 0}, -/*131 */ { 7, s_2_131, -1, 3, 0}, -/*132 */ { 10, s_2_132, -1, 1, 0}, -/*133 */ { 4, s_2_133, -1, 1, 0}, -/*134 */ { 5, s_2_134, -1, 1, 0}, -/*135 */ { 5, s_2_135, -1, 3, 0}, -/*136 */ { 4, s_2_136, -1, 1, 0}, -/*137 */ { 5, s_2_137, -1, 1, 0}, -/*138 */ { 2, s_2_138, -1, 1, 0}, -/*139 */ { 3, s_2_139, 138, 1, 0}, -/*140 */ { 4, s_2_140, 138, 1, 0}, -/*141 */ { 3, s_2_141, -1, 1, 0}, -/*142 */ { 7, s_2_142, 141, 1, 0}, -/*143 */ { 9, s_2_143, 142, 5, 0}, -/*144 */ { 4, s_2_144, -1, 1, 0}, -/*145 */ { 5, s_2_145, 144, 1, 0}, -/*146 */ { 6, s_2_146, 145, 2, 0}, -/*147 */ { 4, s_2_147, -1, 1, 0}, -/*148 */ { 4, s_2_148, -1, 1, 0}, -/*149 */ { 5, s_2_149, -1, 1, 0}, -/*150 */ { 5, s_2_150, -1, 1, 0}, -/*151 */ { 3, s_2_151, -1, 1, 0}, -/*152 */ { 3, s_2_152, -1, 1, 0}, -/*153 */ { 4, s_2_153, 152, 1, 0}, -/*154 */ { 5, s_2_154, 153, 1, 0}, -/*155 */ { 5, s_2_155, 153, 1, 0}, -/*156 */ { 3, s_2_156, -1, 1, 0}, -/*157 */ { 5, s_2_157, 156, 1, 0}, -/*158 */ { 8, s_2_158, 157, 1, 0}, -/*159 */ { 7, s_2_159, 157, 1, 0}, -/*160 */ { 9, s_2_160, 159, 1, 0}, -/*161 */ { 6, s_2_161, 156, 1, 0}, -/*162 */ { 3, s_2_162, -1, 1, 0}, -/*163 */ { 4, s_2_163, -1, 1, 0}, -/*164 */ { 4, s_2_164, -1, 1, 0}, -/*165 */ { 5, s_2_165, 164, 1, 0}, -/*166 */ { 6, s_2_166, 165, 1, 0}, -/*167 */ { 3, s_2_167, -1, 1, 0}, -/*168 */ { 3, s_2_168, -1, 1, 0}, -/*169 */ { 3, s_2_169, -1, 1, 0}, -/*170 */ { 5, s_2_170, 169, 1, 0}, -/*171 */ { 5, s_2_171, 169, 1, 0}, -/*172 */ { 3, s_2_172, -1, 1, 0}, -/*173 */ { 3, s_2_173, -1, 1, 0}, -/*174 */ { 3, s_2_174, -1, 1, 0}, -/*175 */ { 4, s_2_175, 174, 1, 0}, -/*176 */ { 3, s_2_176, -1, 1, 0}, -/*177 */ { 4, s_2_177, -1, 1, 0}, -/*178 */ { 7, s_2_178, 177, 1, 0}, -/*179 */ { 6, s_2_179, 177, 1, 0}, -/*180 */ { 8, s_2_180, 179, 1, 0}, -/*181 */ { 5, s_2_181, -1, 1, 0}, -/*182 */ { 2, s_2_182, -1, 1, 0}, -/*183 */ { 3, s_2_183, -1, 1, 0}, -/*184 */ { 3, s_2_184, -1, 1, 0}, -/*185 */ { 4, s_2_185, 184, 1, 0}, -/*186 */ { 4, s_2_186, 184, 1, 0}, -/*187 */ { 5, s_2_187, 186, 1, 0}, -/*188 */ { 7, s_2_188, 187, 1, 0}, -/*189 */ { 2, s_2_189, -1, 1, 0}, -/*190 */ { 5, s_2_190, -1, 1, 0}, -/*191 */ { 6, s_2_191, -1, 1, 0}, -/*192 */ { 6, s_2_192, -1, 1, 0}, -/*193 */ { 4, s_2_193, -1, 1, 0}, -/*194 */ { 6, s_2_194, -1, 1, 0}, -/*195 */ { 4, s_2_195, -1, 1, 0}, -/*196 */ { 2, s_2_196, -1, 1, 0}, -/*197 */ { 3, s_2_197, 196, 1, 0}, -/*198 */ { 4, s_2_198, 197, 1, 0}, -/*199 */ { 5, s_2_199, 198, 1, 0} +{ 3, s_2_0, -1, 4, 0}, +{ 7, s_2_1, 0, 3, 0}, +{ 4, s_2_2, -1, 1, 0}, +{ 3, s_2_3, -1, 2, 0}, +{ 5, s_2_4, -1, 1, 0}, +{ 5, s_2_5, -1, 1, 0}, +{ 6, s_2_6, -1, 1, 0}, +{ 5, s_2_7, -1, 1, 0}, +{ 5, s_2_8, -1, 3, 0}, +{ 4, s_2_9, -1, 1, 0}, +{ 6, s_2_10, 9, 1, 0}, +{ 4, s_2_11, -1, 1, 0}, +{ 5, s_2_12, -1, 1, 0}, +{ 7, s_2_13, -1, 1, 0}, +{ 4, s_2_14, -1, 1, 0}, +{ 4, s_2_15, -1, 1, 0}, +{ 6, s_2_16, -1, 1, 0}, +{ 3, s_2_17, -1, 1, 0}, +{ 7, s_2_18, 17, 1, 0}, +{ 9, s_2_19, 18, 5, 0}, +{ 3, s_2_20, -1, 1, 0}, +{ 3, s_2_21, -1, 1, 0}, +{ 3, s_2_22, -1, 1, 0}, +{ 5, s_2_23, 22, 1, 0}, +{ 3, s_2_24, -1, 1, 0}, +{ 4, s_2_25, 24, 1, 0}, +{ 5, s_2_26, 25, 1, 0}, +{ 5, s_2_27, -1, 1, 0}, +{ 3, s_2_28, -1, 1, 0}, +{ 3, s_2_29, -1, 1, 0}, +{ 4, s_2_30, -1, 1, 0}, +{ 4, s_2_31, -1, 1, 0}, +{ 4, s_2_32, -1, 1, 0}, +{ 3, s_2_33, -1, 1, 0}, +{ 3, s_2_34, -1, 1, 0}, +{ 3, s_2_35, -1, 1, 0}, +{ 4, s_2_36, -1, 1, 0}, +{ 7, s_2_37, 36, 1, 0}, +{ 7, s_2_38, 36, 1, 0}, +{ 3, s_2_39, -1, 1, 0}, +{ 5, s_2_40, 39, 1, 0}, +{ 4, s_2_41, -1, 1, 0}, +{ 6, s_2_42, -1, 3, 0}, +{ 2, s_2_43, -1, 4, 0}, +{ 6, s_2_44, 43, 1, 0}, +{ 3, s_2_45, -1, 1, 0}, +{ 3, s_2_46, -1, 1, 0}, +{ 2, s_2_47, -1, 1, 0}, +{ 4, s_2_48, -1, 1, 0}, +{ 3, s_2_49, -1, 1, 0}, +{ 4, s_2_50, 49, 1, 0}, +{ 4, s_2_51, 49, 1, 0}, +{ 4, s_2_52, -1, 1, 0}, +{ 7, s_2_53, 52, 1, 0}, +{ 7, s_2_54, 52, 1, 0}, +{ 6, s_2_55, 52, 1, 0}, +{ 4, s_2_56, -1, 1, 0}, +{ 4, s_2_57, -1, 1, 0}, +{ 4, s_2_58, -1, 1, 0}, +{ 3, s_2_59, -1, 1, 0}, +{ 4, s_2_60, -1, 1, 0}, +{ 4, s_2_61, -1, 3, 0}, +{ 3, s_2_62, -1, 1, 0}, +{ 4, s_2_63, -1, 1, 0}, +{ 2, s_2_64, -1, 1, 0}, +{ 2, s_2_65, -1, 1, 0}, +{ 3, s_2_66, -1, 1, 0}, +{ 3, s_2_67, -1, 1, 0}, +{ 5, s_2_68, -1, 1, 0}, +{ 4, s_2_69, -1, 1, 0}, +{ 5, s_2_70, -1, 1, 0}, +{ 6, s_2_71, -1, 1, 0}, +{ 6, s_2_72, -1, 1, 0}, +{ 6, s_2_73, -1, 1, 0}, +{ 8, s_2_74, 73, 5, 0}, +{ 4, s_2_75, -1, 1, 0}, +{ 6, s_2_76, -1, 1, 0}, +{ 2, s_2_77, -1, 1, 0}, +{ 6, s_2_78, 77, 1, 0}, +{ 4, s_2_79, 77, 1, 0}, +{ 4, s_2_80, 77, 1, 0}, +{ 4, s_2_81, 77, 1, 0}, +{ 5, s_2_82, 77, 1, 0}, +{ 3, s_2_83, -1, 1, 0}, +{ 2, s_2_84, -1, 1, 0}, +{ 3, s_2_85, 84, 1, 0}, +{ 3, s_2_86, -1, 1, 0}, +{ 5, s_2_87, -1, 1, 0}, +{ 3, s_2_88, -1, 4, 0}, +{ 7, s_2_89, 88, 3, 0}, +{ 3, s_2_90, -1, 1, 0}, +{ 4, s_2_91, -1, 1, 0}, +{ 4, s_2_92, -1, 2, 0}, +{ 6, s_2_93, -1, 1, 0}, +{ 6, s_2_94, -1, 1, 0}, +{ 7, s_2_95, -1, 1, 0}, +{ 6, s_2_96, -1, 1, 0}, +{ 6, s_2_97, -1, 3, 0}, +{ 5, s_2_98, -1, 1, 0}, +{ 6, s_2_99, -1, 1, 0}, +{ 5, s_2_100, -1, 1, 0}, +{ 6, s_2_101, -1, 1, 0}, +{ 8, s_2_102, -1, 1, 0}, +{ 4, s_2_103, -1, 1, 0}, +{ 5, s_2_104, 103, 1, 0}, +{ 5, s_2_105, 103, 1, 0}, +{ 4, s_2_106, -1, 1, 0}, +{ 8, s_2_107, 106, 1, 0}, +{ 10, s_2_108, 107, 5, 0}, +{ 6, s_2_109, -1, 1, 0}, +{ 5, s_2_110, -1, 1, 0}, +{ 8, s_2_111, 110, 1, 0}, +{ 4, s_2_112, -1, 1, 0}, +{ 4, s_2_113, -1, 1, 0}, +{ 4, s_2_114, -1, 1, 0}, +{ 5, s_2_115, 114, 1, 0}, +{ 6, s_2_116, 115, 1, 0}, +{ 5, s_2_117, -1, 1, 0}, +{ 4, s_2_118, -1, 1, 0}, +{ 4, s_2_119, -1, 1, 0}, +{ 5, s_2_120, -1, 1, 0}, +{ 5, s_2_121, -1, 1, 0}, +{ 4, s_2_122, -1, 1, 0}, +{ 4, s_2_123, -1, 1, 0}, +{ 5, s_2_124, -1, 1, 0}, +{ 8, s_2_125, 124, 1, 0}, +{ 8, s_2_126, 124, 1, 0}, +{ 5, s_2_127, -1, 4, 0}, +{ 9, s_2_128, 127, 3, 0}, +{ 4, s_2_129, -1, 1, 0}, +{ 6, s_2_130, 129, 1, 0}, +{ 7, s_2_131, -1, 3, 0}, +{ 10, s_2_132, -1, 1, 0}, +{ 4, s_2_133, -1, 1, 0}, +{ 5, s_2_134, -1, 1, 0}, +{ 5, s_2_135, -1, 3, 0}, +{ 4, s_2_136, -1, 1, 0}, +{ 5, s_2_137, -1, 1, 0}, +{ 2, s_2_138, -1, 1, 0}, +{ 3, s_2_139, 138, 1, 0}, +{ 4, s_2_140, 138, 1, 0}, +{ 3, s_2_141, -1, 1, 0}, +{ 7, s_2_142, 141, 1, 0}, +{ 9, s_2_143, 142, 5, 0}, +{ 4, s_2_144, -1, 1, 0}, +{ 5, s_2_145, 144, 1, 0}, +{ 6, s_2_146, 145, 2, 0}, +{ 4, s_2_147, -1, 1, 0}, +{ 4, s_2_148, -1, 1, 0}, +{ 5, s_2_149, -1, 1, 0}, +{ 5, s_2_150, -1, 1, 0}, +{ 3, s_2_151, -1, 1, 0}, +{ 3, s_2_152, -1, 1, 0}, +{ 4, s_2_153, 152, 1, 0}, +{ 5, s_2_154, 153, 1, 0}, +{ 5, s_2_155, 153, 1, 0}, +{ 3, s_2_156, -1, 1, 0}, +{ 5, s_2_157, 156, 1, 0}, +{ 8, s_2_158, 157, 1, 0}, +{ 7, s_2_159, 157, 1, 0}, +{ 9, s_2_160, 159, 1, 0}, +{ 6, s_2_161, 156, 1, 0}, +{ 3, s_2_162, -1, 1, 0}, +{ 4, s_2_163, -1, 1, 0}, +{ 4, s_2_164, -1, 1, 0}, +{ 5, s_2_165, 164, 1, 0}, +{ 6, s_2_166, 165, 1, 0}, +{ 3, s_2_167, -1, 1, 0}, +{ 3, s_2_168, -1, 1, 0}, +{ 3, s_2_169, -1, 1, 0}, +{ 5, s_2_170, 169, 1, 0}, +{ 5, s_2_171, 169, 1, 0}, +{ 3, s_2_172, -1, 1, 0}, +{ 3, s_2_173, -1, 1, 0}, +{ 3, s_2_174, -1, 1, 0}, +{ 4, s_2_175, 174, 1, 0}, +{ 3, s_2_176, -1, 1, 0}, +{ 4, s_2_177, -1, 1, 0}, +{ 7, s_2_178, 177, 1, 0}, +{ 6, s_2_179, 177, 1, 0}, +{ 8, s_2_180, 179, 1, 0}, +{ 5, s_2_181, -1, 1, 0}, +{ 2, s_2_182, -1, 1, 0}, +{ 3, s_2_183, -1, 1, 0}, +{ 3, s_2_184, -1, 1, 0}, +{ 4, s_2_185, 184, 1, 0}, +{ 4, s_2_186, 184, 1, 0}, +{ 5, s_2_187, 186, 1, 0}, +{ 7, s_2_188, 187, 1, 0}, +{ 2, s_2_189, -1, 1, 0}, +{ 5, s_2_190, -1, 1, 0}, +{ 6, s_2_191, -1, 1, 0}, +{ 6, s_2_192, -1, 1, 0}, +{ 4, s_2_193, -1, 1, 0}, +{ 6, s_2_194, -1, 1, 0}, +{ 4, s_2_195, -1, 1, 0}, +{ 2, s_2_196, -1, 1, 0}, +{ 3, s_2_197, 196, 1, 0}, +{ 4, s_2_198, 197, 1, 0}, +{ 5, s_2_199, 198, 1, 0} }; static const symbol s_3_0[3] = { 'a', 'b', 'a' }; @@ -833,289 +833,289 @@ static const symbol s_3_282[3] = { 'i', 0xC3, 0xB3 }; static const struct among a_3[283] = { -/* 0 */ { 3, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 4, s_3_2, -1, 1, 0}, -/* 3 */ { 5, s_3_3, -1, 1, 0}, -/* 4 */ { 3, s_3_4, -1, 1, 0}, -/* 5 */ { 3, s_3_5, -1, 1, 0}, -/* 6 */ { 3, s_3_6, -1, 1, 0}, -/* 7 */ { 4, s_3_7, -1, 1, 0}, -/* 8 */ { 2, s_3_8, -1, 1, 0}, -/* 9 */ { 4, s_3_9, 8, 1, 0}, -/* 10 */ { 4, s_3_10, 8, 1, 0}, -/* 11 */ { 3, s_3_11, -1, 1, 0}, -/* 12 */ { 4, s_3_12, -1, 1, 0}, -/* 13 */ { 3, s_3_13, -1, 1, 0}, -/* 14 */ { 5, s_3_14, -1, 1, 0}, -/* 15 */ { 4, s_3_15, -1, 1, 0}, -/* 16 */ { 3, s_3_16, -1, 1, 0}, -/* 17 */ { 3, s_3_17, -1, 1, 0}, -/* 18 */ { 4, s_3_18, -1, 1, 0}, -/* 19 */ { 3, s_3_19, -1, 1, 0}, -/* 20 */ { 5, s_3_20, 19, 1, 0}, -/* 21 */ { 5, s_3_21, 19, 1, 0}, -/* 22 */ { 5, s_3_22, 19, 1, 0}, -/* 23 */ { 3, s_3_23, -1, 1, 0}, -/* 24 */ { 3, s_3_24, -1, 1, 0}, -/* 25 */ { 4, s_3_25, -1, 1, 0}, -/* 26 */ { 2, s_3_26, -1, 1, 0}, -/* 27 */ { 2, s_3_27, -1, 1, 0}, -/* 28 */ { 2, s_3_28, -1, 1, 0}, -/* 29 */ { 2, s_3_29, -1, 1, 0}, -/* 30 */ { 2, s_3_30, -1, 1, 0}, -/* 31 */ { 3, s_3_31, 30, 1, 0}, -/* 32 */ { 3, s_3_32, -1, 1, 0}, -/* 33 */ { 4, s_3_33, -1, 1, 0}, -/* 34 */ { 4, s_3_34, -1, 1, 0}, -/* 35 */ { 4, s_3_35, -1, 1, 0}, -/* 36 */ { 2, s_3_36, -1, 1, 0}, -/* 37 */ { 3, s_3_37, -1, 1, 0}, -/* 38 */ { 5, s_3_38, -1, 1, 0}, -/* 39 */ { 4, s_3_39, -1, 1, 0}, -/* 40 */ { 4, s_3_40, -1, 1, 0}, -/* 41 */ { 2, s_3_41, -1, 1, 0}, -/* 42 */ { 2, s_3_42, -1, 1, 0}, -/* 43 */ { 4, s_3_43, 42, 1, 0}, -/* 44 */ { 4, s_3_44, 42, 1, 0}, -/* 45 */ { 5, s_3_45, 42, 1, 0}, -/* 46 */ { 5, s_3_46, 42, 1, 0}, -/* 47 */ { 6, s_3_47, 42, 1, 0}, -/* 48 */ { 6, s_3_48, 42, 1, 0}, -/* 49 */ { 5, s_3_49, 42, 1, 0}, -/* 50 */ { 6, s_3_50, 42, 1, 0}, -/* 51 */ { 4, s_3_51, 42, 1, 0}, -/* 52 */ { 5, s_3_52, 42, 1, 0}, -/* 53 */ { 5, s_3_53, 42, 1, 0}, -/* 54 */ { 6, s_3_54, 42, 1, 0}, -/* 55 */ { 4, s_3_55, 42, 1, 0}, -/* 56 */ { 6, s_3_56, 55, 1, 0}, -/* 57 */ { 6, s_3_57, 55, 1, 0}, -/* 58 */ { 5, s_3_58, -1, 1, 0}, -/* 59 */ { 5, s_3_59, -1, 1, 0}, -/* 60 */ { 5, s_3_60, -1, 1, 0}, -/* 61 */ { 6, s_3_61, -1, 1, 0}, -/* 62 */ { 6, s_3_62, -1, 1, 0}, -/* 63 */ { 6, s_3_63, -1, 1, 0}, -/* 64 */ { 6, s_3_64, -1, 1, 0}, -/* 65 */ { 3, s_3_65, -1, 1, 0}, -/* 66 */ { 2, s_3_66, -1, 1, 0}, -/* 67 */ { 4, s_3_67, 66, 1, 0}, -/* 68 */ { 5, s_3_68, 66, 1, 0}, -/* 69 */ { 4, s_3_69, 66, 1, 0}, -/* 70 */ { 5, s_3_70, 66, 1, 0}, -/* 71 */ { 4, s_3_71, 66, 1, 0}, -/* 72 */ { 4, s_3_72, 66, 1, 0}, -/* 73 */ { 6, s_3_73, 72, 1, 0}, -/* 74 */ { 6, s_3_74, 72, 1, 0}, -/* 75 */ { 6, s_3_75, 72, 1, 0}, -/* 76 */ { 2, s_3_76, -1, 1, 0}, -/* 77 */ { 3, s_3_77, 76, 1, 0}, -/* 78 */ { 5, s_3_78, 77, 1, 0}, -/* 79 */ { 5, s_3_79, 77, 1, 0}, -/* 80 */ { 4, s_3_80, 76, 1, 0}, -/* 81 */ { 4, s_3_81, 76, 1, 0}, -/* 82 */ { 4, s_3_82, 76, 1, 0}, -/* 83 */ { 5, s_3_83, 76, 1, 0}, -/* 84 */ { 5, s_3_84, 76, 1, 0}, -/* 85 */ { 4, s_3_85, 76, 1, 0}, -/* 86 */ { 5, s_3_86, 76, 1, 0}, -/* 87 */ { 5, s_3_87, 76, 1, 0}, -/* 88 */ { 5, s_3_88, 76, 1, 0}, -/* 89 */ { 5, s_3_89, 76, 1, 0}, -/* 90 */ { 6, s_3_90, 76, 1, 0}, -/* 91 */ { 6, s_3_91, 76, 1, 0}, -/* 92 */ { 6, s_3_92, 76, 1, 0}, -/* 93 */ { 6, s_3_93, 76, 1, 0}, -/* 94 */ { 7, s_3_94, 76, 1, 0}, -/* 95 */ { 4, s_3_95, 76, 1, 0}, -/* 96 */ { 4, s_3_96, 76, 1, 0}, -/* 97 */ { 5, s_3_97, 96, 1, 0}, -/* 98 */ { 5, s_3_98, 76, 1, 0}, -/* 99 */ { 4, s_3_99, 76, 1, 0}, -/*100 */ { 2, s_3_100, -1, 1, 0}, -/*101 */ { 4, s_3_101, 100, 1, 0}, -/*102 */ { 3, s_3_102, 100, 1, 0}, -/*103 */ { 4, s_3_103, 102, 1, 0}, -/*104 */ { 5, s_3_104, 102, 1, 0}, -/*105 */ { 5, s_3_105, 102, 1, 0}, -/*106 */ { 5, s_3_106, 102, 1, 0}, -/*107 */ { 6, s_3_107, 102, 1, 0}, -/*108 */ { 6, s_3_108, 100, 1, 0}, -/*109 */ { 5, s_3_109, 100, 1, 0}, -/*110 */ { 4, s_3_110, -1, 1, 0}, -/*111 */ { 5, s_3_111, -1, 1, 0}, -/*112 */ { 5, s_3_112, -1, 1, 0}, -/*113 */ { 5, s_3_113, -1, 1, 0}, -/*114 */ { 5, s_3_114, -1, 1, 0}, -/*115 */ { 4, s_3_115, -1, 1, 0}, -/*116 */ { 3, s_3_116, -1, 1, 0}, -/*117 */ { 3, s_3_117, -1, 1, 0}, -/*118 */ { 4, s_3_118, -1, 2, 0}, -/*119 */ { 5, s_3_119, -1, 1, 0}, -/*120 */ { 2, s_3_120, -1, 1, 0}, -/*121 */ { 3, s_3_121, -1, 1, 0}, -/*122 */ { 4, s_3_122, 121, 1, 0}, -/*123 */ { 4, s_3_123, -1, 1, 0}, -/*124 */ { 4, s_3_124, -1, 1, 0}, -/*125 */ { 2, s_3_125, -1, 1, 0}, -/*126 */ { 4, s_3_126, 125, 1, 0}, -/*127 */ { 2, s_3_127, -1, 1, 0}, -/*128 */ { 5, s_3_128, 127, 1, 0}, -/*129 */ { 2, s_3_129, -1, 1, 0}, -/*130 */ { 4, s_3_130, -1, 1, 0}, -/*131 */ { 2, s_3_131, -1, 1, 0}, -/*132 */ { 4, s_3_132, 131, 1, 0}, -/*133 */ { 4, s_3_133, 131, 1, 0}, -/*134 */ { 4, s_3_134, 131, 1, 0}, -/*135 */ { 4, s_3_135, 131, 1, 0}, -/*136 */ { 5, s_3_136, 131, 1, 0}, -/*137 */ { 4, s_3_137, 131, 1, 0}, -/*138 */ { 6, s_3_138, 137, 1, 0}, -/*139 */ { 6, s_3_139, 137, 1, 0}, -/*140 */ { 6, s_3_140, 137, 1, 0}, -/*141 */ { 3, s_3_141, -1, 1, 0}, -/*142 */ { 2, s_3_142, -1, 1, 0}, -/*143 */ { 4, s_3_143, 142, 1, 0}, -/*144 */ { 4, s_3_144, 142, 1, 0}, -/*145 */ { 4, s_3_145, 142, 1, 0}, -/*146 */ { 5, s_3_146, 142, 1, 0}, -/*147 */ { 5, s_3_147, 142, 1, 0}, -/*148 */ { 3, s_3_148, 142, 1, 0}, -/*149 */ { 5, s_3_149, 148, 1, 0}, -/*150 */ { 5, s_3_150, 148, 1, 0}, -/*151 */ { 4, s_3_151, 142, 1, 0}, -/*152 */ { 4, s_3_152, 142, 1, 0}, -/*153 */ { 6, s_3_153, 142, 1, 0}, -/*154 */ { 5, s_3_154, 142, 1, 0}, -/*155 */ { 4, s_3_155, 142, 1, 0}, -/*156 */ { 5, s_3_156, 142, 1, 0}, -/*157 */ { 5, s_3_157, 142, 1, 0}, -/*158 */ { 5, s_3_158, 142, 1, 0}, -/*159 */ { 5, s_3_159, 142, 1, 0}, -/*160 */ { 6, s_3_160, 142, 1, 0}, -/*161 */ { 4, s_3_161, 142, 1, 0}, -/*162 */ { 6, s_3_162, 161, 1, 0}, -/*163 */ { 7, s_3_163, 161, 1, 0}, -/*164 */ { 4, s_3_164, 142, 1, 0}, -/*165 */ { 4, s_3_165, 142, 1, 0}, -/*166 */ { 5, s_3_166, 165, 1, 0}, -/*167 */ { 5, s_3_167, 142, 1, 0}, -/*168 */ { 4, s_3_168, 142, 1, 0}, -/*169 */ { 5, s_3_169, -1, 1, 0}, -/*170 */ { 5, s_3_170, -1, 1, 0}, -/*171 */ { 6, s_3_171, -1, 1, 0}, -/*172 */ { 5, s_3_172, -1, 1, 0}, -/*173 */ { 7, s_3_173, 172, 1, 0}, -/*174 */ { 7, s_3_174, 172, 1, 0}, -/*175 */ { 7, s_3_175, 172, 1, 0}, -/*176 */ { 5, s_3_176, -1, 1, 0}, -/*177 */ { 6, s_3_177, -1, 1, 0}, -/*178 */ { 6, s_3_178, -1, 1, 0}, -/*179 */ { 6, s_3_179, -1, 1, 0}, -/*180 */ { 4, s_3_180, -1, 1, 0}, -/*181 */ { 3, s_3_181, -1, 1, 0}, -/*182 */ { 4, s_3_182, 181, 1, 0}, -/*183 */ { 5, s_3_183, 181, 1, 0}, -/*184 */ { 5, s_3_184, 181, 1, 0}, -/*185 */ { 5, s_3_185, 181, 1, 0}, -/*186 */ { 6, s_3_186, 181, 1, 0}, -/*187 */ { 6, s_3_187, -1, 1, 0}, -/*188 */ { 5, s_3_188, -1, 1, 0}, -/*189 */ { 5, s_3_189, -1, 1, 0}, -/*190 */ { 4, s_3_190, -1, 1, 0}, -/*191 */ { 6, s_3_191, -1, 1, 0}, -/*192 */ { 6, s_3_192, -1, 1, 0}, -/*193 */ { 6, s_3_193, -1, 1, 0}, -/*194 */ { 3, s_3_194, -1, 1, 0}, -/*195 */ { 4, s_3_195, -1, 1, 0}, -/*196 */ { 4, s_3_196, -1, 1, 0}, -/*197 */ { 4, s_3_197, -1, 1, 0}, -/*198 */ { 7, s_3_198, 197, 1, 0}, -/*199 */ { 7, s_3_199, 197, 1, 0}, -/*200 */ { 8, s_3_200, 197, 1, 0}, -/*201 */ { 6, s_3_201, 197, 1, 0}, -/*202 */ { 8, s_3_202, 201, 1, 0}, -/*203 */ { 8, s_3_203, 201, 1, 0}, -/*204 */ { 8, s_3_204, 201, 1, 0}, -/*205 */ { 6, s_3_205, -1, 1, 0}, -/*206 */ { 6, s_3_206, -1, 1, 0}, -/*207 */ { 6, s_3_207, -1, 1, 0}, -/*208 */ { 7, s_3_208, -1, 1, 0}, -/*209 */ { 8, s_3_209, -1, 1, 0}, -/*210 */ { 4, s_3_210, -1, 1, 0}, -/*211 */ { 5, s_3_211, -1, 1, 0}, -/*212 */ { 3, s_3_212, -1, 1, 0}, -/*213 */ { 5, s_3_213, 212, 1, 0}, -/*214 */ { 3, s_3_214, -1, 1, 0}, -/*215 */ { 3, s_3_215, -1, 1, 0}, -/*216 */ { 3, s_3_216, -1, 1, 0}, -/*217 */ { 4, s_3_217, -1, 1, 0}, -/*218 */ { 3, s_3_218, -1, 1, 0}, -/*219 */ { 5, s_3_219, 218, 1, 0}, -/*220 */ { 5, s_3_220, 218, 1, 0}, -/*221 */ { 5, s_3_221, -1, 1, 0}, -/*222 */ { 5, s_3_222, -1, 1, 0}, -/*223 */ { 5, s_3_223, -1, 1, 0}, -/*224 */ { 3, s_3_224, -1, 1, 0}, -/*225 */ { 5, s_3_225, 224, 1, 0}, -/*226 */ { 3, s_3_226, -1, 1, 0}, -/*227 */ { 4, s_3_227, -1, 1, 0}, -/*228 */ { 2, s_3_228, -1, 1, 0}, -/*229 */ { 2, s_3_229, -1, 1, 0}, -/*230 */ { 3, s_3_230, -1, 1, 0}, -/*231 */ { 3, s_3_231, -1, 1, 0}, -/*232 */ { 3, s_3_232, -1, 1, 0}, -/*233 */ { 2, s_3_233, -1, 1, 0}, -/*234 */ { 3, s_3_234, -1, 1, 0}, -/*235 */ { 2, s_3_235, -1, 1, 0}, -/*236 */ { 4, s_3_236, 235, 1, 0}, -/*237 */ { 3, s_3_237, -1, 1, 0}, -/*238 */ { 4, s_3_238, -1, 1, 0}, -/*239 */ { 4, s_3_239, -1, 1, 0}, -/*240 */ { 4, s_3_240, -1, 1, 0}, -/*241 */ { 5, s_3_241, -1, 1, 0}, -/*242 */ { 5, s_3_242, -1, 1, 0}, -/*243 */ { 5, s_3_243, -1, 1, 0}, -/*244 */ { 5, s_3_244, -1, 1, 0}, -/*245 */ { 7, s_3_245, 244, 1, 0}, -/*246 */ { 6, s_3_246, -1, 1, 0}, -/*247 */ { 6, s_3_247, -1, 1, 0}, -/*248 */ { 5, s_3_248, -1, 1, 0}, -/*249 */ { 6, s_3_249, -1, 1, 0}, -/*250 */ { 5, s_3_250, -1, 1, 0}, -/*251 */ { 5, s_3_251, -1, 1, 0}, -/*252 */ { 5, s_3_252, -1, 1, 0}, -/*253 */ { 4, s_3_253, -1, 1, 0}, -/*254 */ { 6, s_3_254, 253, 1, 0}, -/*255 */ { 4, s_3_255, -1, 1, 0}, -/*256 */ { 6, s_3_256, 255, 1, 0}, -/*257 */ { 6, s_3_257, 255, 1, 0}, -/*258 */ { 5, s_3_258, -1, 1, 0}, -/*259 */ { 5, s_3_259, -1, 1, 0}, -/*260 */ { 6, s_3_260, -1, 1, 0}, -/*261 */ { 6, s_3_261, -1, 1, 0}, -/*262 */ { 6, s_3_262, -1, 1, 0}, -/*263 */ { 6, s_3_263, -1, 1, 0}, -/*264 */ { 3, s_3_264, -1, 1, 0}, -/*265 */ { 2, s_3_265, -1, 1, 0}, -/*266 */ { 3, s_3_266, 265, 1, 0}, -/*267 */ { 3, s_3_267, -1, 1, 0}, -/*268 */ { 3, s_3_268, -1, 1, 0}, -/*269 */ { 3, s_3_269, -1, 1, 0}, -/*270 */ { 4, s_3_270, -1, 1, 0}, -/*271 */ { 4, s_3_271, -1, 1, 0}, -/*272 */ { 5, s_3_272, -1, 1, 0}, -/*273 */ { 4, s_3_273, -1, 1, 0}, -/*274 */ { 4, s_3_274, -1, 1, 0}, -/*275 */ { 4, s_3_275, -1, 1, 0}, -/*276 */ { 4, s_3_276, -1, 1, 0}, -/*277 */ { 4, s_3_277, -1, 1, 0}, -/*278 */ { 4, s_3_278, -1, 1, 0}, -/*279 */ { 4, s_3_279, -1, 1, 0}, -/*280 */ { 2, s_3_280, -1, 1, 0}, -/*281 */ { 3, s_3_281, -1, 1, 0}, -/*282 */ { 3, s_3_282, -1, 1, 0} +{ 3, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 4, s_3_2, -1, 1, 0}, +{ 5, s_3_3, -1, 1, 0}, +{ 3, s_3_4, -1, 1, 0}, +{ 3, s_3_5, -1, 1, 0}, +{ 3, s_3_6, -1, 1, 0}, +{ 4, s_3_7, -1, 1, 0}, +{ 2, s_3_8, -1, 1, 0}, +{ 4, s_3_9, 8, 1, 0}, +{ 4, s_3_10, 8, 1, 0}, +{ 3, s_3_11, -1, 1, 0}, +{ 4, s_3_12, -1, 1, 0}, +{ 3, s_3_13, -1, 1, 0}, +{ 5, s_3_14, -1, 1, 0}, +{ 4, s_3_15, -1, 1, 0}, +{ 3, s_3_16, -1, 1, 0}, +{ 3, s_3_17, -1, 1, 0}, +{ 4, s_3_18, -1, 1, 0}, +{ 3, s_3_19, -1, 1, 0}, +{ 5, s_3_20, 19, 1, 0}, +{ 5, s_3_21, 19, 1, 0}, +{ 5, s_3_22, 19, 1, 0}, +{ 3, s_3_23, -1, 1, 0}, +{ 3, s_3_24, -1, 1, 0}, +{ 4, s_3_25, -1, 1, 0}, +{ 2, s_3_26, -1, 1, 0}, +{ 2, s_3_27, -1, 1, 0}, +{ 2, s_3_28, -1, 1, 0}, +{ 2, s_3_29, -1, 1, 0}, +{ 2, s_3_30, -1, 1, 0}, +{ 3, s_3_31, 30, 1, 0}, +{ 3, s_3_32, -1, 1, 0}, +{ 4, s_3_33, -1, 1, 0}, +{ 4, s_3_34, -1, 1, 0}, +{ 4, s_3_35, -1, 1, 0}, +{ 2, s_3_36, -1, 1, 0}, +{ 3, s_3_37, -1, 1, 0}, +{ 5, s_3_38, -1, 1, 0}, +{ 4, s_3_39, -1, 1, 0}, +{ 4, s_3_40, -1, 1, 0}, +{ 2, s_3_41, -1, 1, 0}, +{ 2, s_3_42, -1, 1, 0}, +{ 4, s_3_43, 42, 1, 0}, +{ 4, s_3_44, 42, 1, 0}, +{ 5, s_3_45, 42, 1, 0}, +{ 5, s_3_46, 42, 1, 0}, +{ 6, s_3_47, 42, 1, 0}, +{ 6, s_3_48, 42, 1, 0}, +{ 5, s_3_49, 42, 1, 0}, +{ 6, s_3_50, 42, 1, 0}, +{ 4, s_3_51, 42, 1, 0}, +{ 5, s_3_52, 42, 1, 0}, +{ 5, s_3_53, 42, 1, 0}, +{ 6, s_3_54, 42, 1, 0}, +{ 4, s_3_55, 42, 1, 0}, +{ 6, s_3_56, 55, 1, 0}, +{ 6, s_3_57, 55, 1, 0}, +{ 5, s_3_58, -1, 1, 0}, +{ 5, s_3_59, -1, 1, 0}, +{ 5, s_3_60, -1, 1, 0}, +{ 6, s_3_61, -1, 1, 0}, +{ 6, s_3_62, -1, 1, 0}, +{ 6, s_3_63, -1, 1, 0}, +{ 6, s_3_64, -1, 1, 0}, +{ 3, s_3_65, -1, 1, 0}, +{ 2, s_3_66, -1, 1, 0}, +{ 4, s_3_67, 66, 1, 0}, +{ 5, s_3_68, 66, 1, 0}, +{ 4, s_3_69, 66, 1, 0}, +{ 5, s_3_70, 66, 1, 0}, +{ 4, s_3_71, 66, 1, 0}, +{ 4, s_3_72, 66, 1, 0}, +{ 6, s_3_73, 72, 1, 0}, +{ 6, s_3_74, 72, 1, 0}, +{ 6, s_3_75, 72, 1, 0}, +{ 2, s_3_76, -1, 1, 0}, +{ 3, s_3_77, 76, 1, 0}, +{ 5, s_3_78, 77, 1, 0}, +{ 5, s_3_79, 77, 1, 0}, +{ 4, s_3_80, 76, 1, 0}, +{ 4, s_3_81, 76, 1, 0}, +{ 4, s_3_82, 76, 1, 0}, +{ 5, s_3_83, 76, 1, 0}, +{ 5, s_3_84, 76, 1, 0}, +{ 4, s_3_85, 76, 1, 0}, +{ 5, s_3_86, 76, 1, 0}, +{ 5, s_3_87, 76, 1, 0}, +{ 5, s_3_88, 76, 1, 0}, +{ 5, s_3_89, 76, 1, 0}, +{ 6, s_3_90, 76, 1, 0}, +{ 6, s_3_91, 76, 1, 0}, +{ 6, s_3_92, 76, 1, 0}, +{ 6, s_3_93, 76, 1, 0}, +{ 7, s_3_94, 76, 1, 0}, +{ 4, s_3_95, 76, 1, 0}, +{ 4, s_3_96, 76, 1, 0}, +{ 5, s_3_97, 96, 1, 0}, +{ 5, s_3_98, 76, 1, 0}, +{ 4, s_3_99, 76, 1, 0}, +{ 2, s_3_100, -1, 1, 0}, +{ 4, s_3_101, 100, 1, 0}, +{ 3, s_3_102, 100, 1, 0}, +{ 4, s_3_103, 102, 1, 0}, +{ 5, s_3_104, 102, 1, 0}, +{ 5, s_3_105, 102, 1, 0}, +{ 5, s_3_106, 102, 1, 0}, +{ 6, s_3_107, 102, 1, 0}, +{ 6, s_3_108, 100, 1, 0}, +{ 5, s_3_109, 100, 1, 0}, +{ 4, s_3_110, -1, 1, 0}, +{ 5, s_3_111, -1, 1, 0}, +{ 5, s_3_112, -1, 1, 0}, +{ 5, s_3_113, -1, 1, 0}, +{ 5, s_3_114, -1, 1, 0}, +{ 4, s_3_115, -1, 1, 0}, +{ 3, s_3_116, -1, 1, 0}, +{ 3, s_3_117, -1, 1, 0}, +{ 4, s_3_118, -1, 2, 0}, +{ 5, s_3_119, -1, 1, 0}, +{ 2, s_3_120, -1, 1, 0}, +{ 3, s_3_121, -1, 1, 0}, +{ 4, s_3_122, 121, 1, 0}, +{ 4, s_3_123, -1, 1, 0}, +{ 4, s_3_124, -1, 1, 0}, +{ 2, s_3_125, -1, 1, 0}, +{ 4, s_3_126, 125, 1, 0}, +{ 2, s_3_127, -1, 1, 0}, +{ 5, s_3_128, 127, 1, 0}, +{ 2, s_3_129, -1, 1, 0}, +{ 4, s_3_130, -1, 1, 0}, +{ 2, s_3_131, -1, 1, 0}, +{ 4, s_3_132, 131, 1, 0}, +{ 4, s_3_133, 131, 1, 0}, +{ 4, s_3_134, 131, 1, 0}, +{ 4, s_3_135, 131, 1, 0}, +{ 5, s_3_136, 131, 1, 0}, +{ 4, s_3_137, 131, 1, 0}, +{ 6, s_3_138, 137, 1, 0}, +{ 6, s_3_139, 137, 1, 0}, +{ 6, s_3_140, 137, 1, 0}, +{ 3, s_3_141, -1, 1, 0}, +{ 2, s_3_142, -1, 1, 0}, +{ 4, s_3_143, 142, 1, 0}, +{ 4, s_3_144, 142, 1, 0}, +{ 4, s_3_145, 142, 1, 0}, +{ 5, s_3_146, 142, 1, 0}, +{ 5, s_3_147, 142, 1, 0}, +{ 3, s_3_148, 142, 1, 0}, +{ 5, s_3_149, 148, 1, 0}, +{ 5, s_3_150, 148, 1, 0}, +{ 4, s_3_151, 142, 1, 0}, +{ 4, s_3_152, 142, 1, 0}, +{ 6, s_3_153, 142, 1, 0}, +{ 5, s_3_154, 142, 1, 0}, +{ 4, s_3_155, 142, 1, 0}, +{ 5, s_3_156, 142, 1, 0}, +{ 5, s_3_157, 142, 1, 0}, +{ 5, s_3_158, 142, 1, 0}, +{ 5, s_3_159, 142, 1, 0}, +{ 6, s_3_160, 142, 1, 0}, +{ 4, s_3_161, 142, 1, 0}, +{ 6, s_3_162, 161, 1, 0}, +{ 7, s_3_163, 161, 1, 0}, +{ 4, s_3_164, 142, 1, 0}, +{ 4, s_3_165, 142, 1, 0}, +{ 5, s_3_166, 165, 1, 0}, +{ 5, s_3_167, 142, 1, 0}, +{ 4, s_3_168, 142, 1, 0}, +{ 5, s_3_169, -1, 1, 0}, +{ 5, s_3_170, -1, 1, 0}, +{ 6, s_3_171, -1, 1, 0}, +{ 5, s_3_172, -1, 1, 0}, +{ 7, s_3_173, 172, 1, 0}, +{ 7, s_3_174, 172, 1, 0}, +{ 7, s_3_175, 172, 1, 0}, +{ 5, s_3_176, -1, 1, 0}, +{ 6, s_3_177, -1, 1, 0}, +{ 6, s_3_178, -1, 1, 0}, +{ 6, s_3_179, -1, 1, 0}, +{ 4, s_3_180, -1, 1, 0}, +{ 3, s_3_181, -1, 1, 0}, +{ 4, s_3_182, 181, 1, 0}, +{ 5, s_3_183, 181, 1, 0}, +{ 5, s_3_184, 181, 1, 0}, +{ 5, s_3_185, 181, 1, 0}, +{ 6, s_3_186, 181, 1, 0}, +{ 6, s_3_187, -1, 1, 0}, +{ 5, s_3_188, -1, 1, 0}, +{ 5, s_3_189, -1, 1, 0}, +{ 4, s_3_190, -1, 1, 0}, +{ 6, s_3_191, -1, 1, 0}, +{ 6, s_3_192, -1, 1, 0}, +{ 6, s_3_193, -1, 1, 0}, +{ 3, s_3_194, -1, 1, 0}, +{ 4, s_3_195, -1, 1, 0}, +{ 4, s_3_196, -1, 1, 0}, +{ 4, s_3_197, -1, 1, 0}, +{ 7, s_3_198, 197, 1, 0}, +{ 7, s_3_199, 197, 1, 0}, +{ 8, s_3_200, 197, 1, 0}, +{ 6, s_3_201, 197, 1, 0}, +{ 8, s_3_202, 201, 1, 0}, +{ 8, s_3_203, 201, 1, 0}, +{ 8, s_3_204, 201, 1, 0}, +{ 6, s_3_205, -1, 1, 0}, +{ 6, s_3_206, -1, 1, 0}, +{ 6, s_3_207, -1, 1, 0}, +{ 7, s_3_208, -1, 1, 0}, +{ 8, s_3_209, -1, 1, 0}, +{ 4, s_3_210, -1, 1, 0}, +{ 5, s_3_211, -1, 1, 0}, +{ 3, s_3_212, -1, 1, 0}, +{ 5, s_3_213, 212, 1, 0}, +{ 3, s_3_214, -1, 1, 0}, +{ 3, s_3_215, -1, 1, 0}, +{ 3, s_3_216, -1, 1, 0}, +{ 4, s_3_217, -1, 1, 0}, +{ 3, s_3_218, -1, 1, 0}, +{ 5, s_3_219, 218, 1, 0}, +{ 5, s_3_220, 218, 1, 0}, +{ 5, s_3_221, -1, 1, 0}, +{ 5, s_3_222, -1, 1, 0}, +{ 5, s_3_223, -1, 1, 0}, +{ 3, s_3_224, -1, 1, 0}, +{ 5, s_3_225, 224, 1, 0}, +{ 3, s_3_226, -1, 1, 0}, +{ 4, s_3_227, -1, 1, 0}, +{ 2, s_3_228, -1, 1, 0}, +{ 2, s_3_229, -1, 1, 0}, +{ 3, s_3_230, -1, 1, 0}, +{ 3, s_3_231, -1, 1, 0}, +{ 3, s_3_232, -1, 1, 0}, +{ 2, s_3_233, -1, 1, 0}, +{ 3, s_3_234, -1, 1, 0}, +{ 2, s_3_235, -1, 1, 0}, +{ 4, s_3_236, 235, 1, 0}, +{ 3, s_3_237, -1, 1, 0}, +{ 4, s_3_238, -1, 1, 0}, +{ 4, s_3_239, -1, 1, 0}, +{ 4, s_3_240, -1, 1, 0}, +{ 5, s_3_241, -1, 1, 0}, +{ 5, s_3_242, -1, 1, 0}, +{ 5, s_3_243, -1, 1, 0}, +{ 5, s_3_244, -1, 1, 0}, +{ 7, s_3_245, 244, 1, 0}, +{ 6, s_3_246, -1, 1, 0}, +{ 6, s_3_247, -1, 1, 0}, +{ 5, s_3_248, -1, 1, 0}, +{ 6, s_3_249, -1, 1, 0}, +{ 5, s_3_250, -1, 1, 0}, +{ 5, s_3_251, -1, 1, 0}, +{ 5, s_3_252, -1, 1, 0}, +{ 4, s_3_253, -1, 1, 0}, +{ 6, s_3_254, 253, 1, 0}, +{ 4, s_3_255, -1, 1, 0}, +{ 6, s_3_256, 255, 1, 0}, +{ 6, s_3_257, 255, 1, 0}, +{ 5, s_3_258, -1, 1, 0}, +{ 5, s_3_259, -1, 1, 0}, +{ 6, s_3_260, -1, 1, 0}, +{ 6, s_3_261, -1, 1, 0}, +{ 6, s_3_262, -1, 1, 0}, +{ 6, s_3_263, -1, 1, 0}, +{ 3, s_3_264, -1, 1, 0}, +{ 2, s_3_265, -1, 1, 0}, +{ 3, s_3_266, 265, 1, 0}, +{ 3, s_3_267, -1, 1, 0}, +{ 3, s_3_268, -1, 1, 0}, +{ 3, s_3_269, -1, 1, 0}, +{ 4, s_3_270, -1, 1, 0}, +{ 4, s_3_271, -1, 1, 0}, +{ 5, s_3_272, -1, 1, 0}, +{ 4, s_3_273, -1, 1, 0}, +{ 4, s_3_274, -1, 1, 0}, +{ 4, s_3_275, -1, 1, 0}, +{ 4, s_3_276, -1, 1, 0}, +{ 4, s_3_277, -1, 1, 0}, +{ 4, s_3_278, -1, 1, 0}, +{ 4, s_3_279, -1, 1, 0}, +{ 2, s_3_280, -1, 1, 0}, +{ 3, s_3_281, -1, 1, 0}, +{ 3, s_3_282, -1, 1, 0} }; static const symbol s_4_0[1] = { 'a' }; @@ -1143,28 +1143,28 @@ static const symbol s_4_21[2] = { 0xC3, 0xB3 }; static const struct among a_4[22] = { -/* 0 */ { 1, s_4_0, -1, 1, 0}, -/* 1 */ { 1, s_4_1, -1, 1, 0}, -/* 2 */ { 1, s_4_2, -1, 1, 0}, -/* 3 */ { 3, s_4_3, -1, 1, 0}, -/* 4 */ { 1, s_4_4, -1, 1, 0}, -/* 5 */ { 2, s_4_5, -1, 1, 0}, -/* 6 */ { 1, s_4_6, -1, 1, 0}, -/* 7 */ { 2, s_4_7, 6, 1, 0}, -/* 8 */ { 2, s_4_8, 6, 1, 0}, -/* 9 */ { 3, s_4_9, 6, 1, 0}, -/* 10 */ { 2, s_4_10, -1, 1, 0}, -/* 11 */ { 2, s_4_11, -1, 1, 0}, -/* 12 */ { 2, s_4_12, -1, 1, 0}, -/* 13 */ { 3, s_4_13, -1, 2, 0}, -/* 14 */ { 3, s_4_14, -1, 1, 0}, -/* 15 */ { 2, s_4_15, -1, 1, 0}, -/* 16 */ { 2, s_4_16, -1, 1, 0}, -/* 17 */ { 2, s_4_17, -1, 1, 0}, -/* 18 */ { 2, s_4_18, -1, 1, 0}, -/* 19 */ { 2, s_4_19, -1, 1, 0}, -/* 20 */ { 2, s_4_20, -1, 1, 0}, -/* 21 */ { 2, s_4_21, -1, 1, 0} +{ 1, s_4_0, -1, 1, 0}, +{ 1, s_4_1, -1, 1, 0}, +{ 1, s_4_2, -1, 1, 0}, +{ 3, s_4_3, -1, 1, 0}, +{ 1, s_4_4, -1, 1, 0}, +{ 2, s_4_5, -1, 1, 0}, +{ 1, s_4_6, -1, 1, 0}, +{ 2, s_4_7, 6, 1, 0}, +{ 2, s_4_8, 6, 1, 0}, +{ 3, s_4_9, 6, 1, 0}, +{ 2, s_4_10, -1, 1, 0}, +{ 2, s_4_11, -1, 1, 0}, +{ 2, s_4_12, -1, 1, 0}, +{ 3, s_4_13, -1, 2, 0}, +{ 3, s_4_14, -1, 1, 0}, +{ 2, s_4_15, -1, 1, 0}, +{ 2, s_4_16, -1, 1, 0}, +{ 2, s_4_17, -1, 1, 0}, +{ 2, s_4_18, -1, 1, 0}, +{ 2, s_4_19, -1, 1, 0}, +{ 2, s_4_20, -1, 1, 0}, +{ 2, s_4_21, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 129, 81, 6, 10 }; @@ -1180,83 +1180,82 @@ static const symbol s_7[] = { 'i', 'c' }; static const symbol s_8[] = { 'c' }; static const symbol s_9[] = { 'i', 'c' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 38 */ - z->I[1] = z->l; /* $p2 = , line 39 */ - { int c1 = z->c; /* do, line 41 */ - { /* gopast */ /* grouping v, line 42 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 42 */ + { int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 42 */ - { /* gopast */ /* grouping v, line 43 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 43 */ + { int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 43 */ + z->I[0] = z->c; lab0: z->c = c1; } return 1; } -static int r_cleaning(struct SN_env * z) { /* forwardmode */ +static int r_cleaning(struct SN_env * z) { int among_var; -/* repeat, line 47 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 48 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((344765187 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 7; else /* substring, line 48 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((344765187 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 7; else among_var = find_among(z, a_0, 13); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 48 */ - switch (among_var) { /* among, line 48 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 49 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 51 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 53 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 55 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 57 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 7: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 61 */ + z->c = ret; } break; } @@ -1268,74 +1267,74 @@ static int r_cleaning(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 67 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 68 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 71 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1634850 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 71 */ +static int r_attached_pronoun(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1634850 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_1, 39))) return 0; - z->bra = z->c; /* ], line 71 */ - { int ret = r_R1(z); /* call R1, line 81 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 81 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 86 */ - among_var = find_among_b(z, a_2, 200); /* substring, line 86 */ + z->ket = z->c; + among_var = find_among_b(z, a_2, 200); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 86 */ - switch (among_var) { /* among, line 86 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 110 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 112 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 112 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); /* call R2, line 114 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_6); /* <-, line 114 */ + { int ret = slice_from_s(z, 3, s_6); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 116 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_7); /* <-, line 116 */ + { int ret = slice_from_s(z, 2, s_7); if (ret < 0) return ret; } break; case 5: - { int ret = r_R1(z); /* call R1, line 118 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_8); /* <-, line 118 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; @@ -1343,26 +1342,26 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 123 */ - among_var = find_among_b(z, a_3, 283); /* substring, line 123 */ + z->ket = z->c; + among_var = find_among_b(z, a_3, 283); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 123 */ - switch (among_var) { /* among, line 123 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 168 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 168 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 170 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 170 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1370,26 +1369,26 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ +static int r_residual_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 175 */ - among_var = find_among_b(z, a_4, 22); /* substring, line 175 */ + z->ket = z->c; + among_var = find_among_b(z, a_4, 22); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 175 */ - switch (among_var) { /* among, line 175 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 178 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 178 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R1(z); /* call R1, line 180 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_9); /* <-, line 180 */ + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; @@ -1397,29 +1396,29 @@ static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int catalan_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - /* do, line 186 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 186 */ +extern int catalan_UTF_8_stem(struct SN_env * z) { + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 187 */ + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 188 */ - { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 188 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_attached_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 189 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 189 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 189 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m3; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 190 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1428,15 +1427,15 @@ extern int catalan_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 192 */ - { int ret = r_residual_suffix(z); /* call residual_suffix, line 192 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_residual_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; } z->c = z->lb; - { int c5 = z->c; /* do, line 194 */ - { int ret = r_cleaning(z); /* call cleaning, line 194 */ + { int c5 = z->c; + { int ret = r_cleaning(z); if (ret < 0) return ret; } z->c = c5; @@ -1444,7 +1443,7 @@ extern int catalan_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * catalan_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * catalan_UTF_8_create_env(void) { return SN_create_env(0, 2); } extern void catalan_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_danish.c b/src/backend/snowball/libstemmer/stem_UTF_8_danish.c index 9bc7e060b1d0..ded772b8f2d2 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_danish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_danish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -61,38 +61,38 @@ static const symbol s_0_31[4] = { 'e', 'r', 'e', 't' }; static const struct among a_0[32] = { -/* 0 */ { 3, s_0_0, -1, 1, 0}, -/* 1 */ { 5, s_0_1, 0, 1, 0}, -/* 2 */ { 4, s_0_2, -1, 1, 0}, -/* 3 */ { 1, s_0_3, -1, 1, 0}, -/* 4 */ { 5, s_0_4, 3, 1, 0}, -/* 5 */ { 4, s_0_5, 3, 1, 0}, -/* 6 */ { 6, s_0_6, 5, 1, 0}, -/* 7 */ { 3, s_0_7, 3, 1, 0}, -/* 8 */ { 4, s_0_8, 3, 1, 0}, -/* 9 */ { 3, s_0_9, 3, 1, 0}, -/* 10 */ { 2, s_0_10, -1, 1, 0}, -/* 11 */ { 5, s_0_11, 10, 1, 0}, -/* 12 */ { 4, s_0_12, 10, 1, 0}, -/* 13 */ { 2, s_0_13, -1, 1, 0}, -/* 14 */ { 5, s_0_14, 13, 1, 0}, -/* 15 */ { 4, s_0_15, 13, 1, 0}, -/* 16 */ { 1, s_0_16, -1, 2, 0}, -/* 17 */ { 4, s_0_17, 16, 1, 0}, -/* 18 */ { 2, s_0_18, 16, 1, 0}, -/* 19 */ { 5, s_0_19, 18, 1, 0}, -/* 20 */ { 7, s_0_20, 19, 1, 0}, -/* 21 */ { 4, s_0_21, 18, 1, 0}, -/* 22 */ { 5, s_0_22, 18, 1, 0}, -/* 23 */ { 4, s_0_23, 18, 1, 0}, -/* 24 */ { 3, s_0_24, 16, 1, 0}, -/* 25 */ { 6, s_0_25, 24, 1, 0}, -/* 26 */ { 5, s_0_26, 24, 1, 0}, -/* 27 */ { 3, s_0_27, 16, 1, 0}, -/* 28 */ { 3, s_0_28, 16, 1, 0}, -/* 29 */ { 5, s_0_29, 28, 1, 0}, -/* 30 */ { 2, s_0_30, -1, 1, 0}, -/* 31 */ { 4, s_0_31, 30, 1, 0} +{ 3, s_0_0, -1, 1, 0}, +{ 5, s_0_1, 0, 1, 0}, +{ 4, s_0_2, -1, 1, 0}, +{ 1, s_0_3, -1, 1, 0}, +{ 5, s_0_4, 3, 1, 0}, +{ 4, s_0_5, 3, 1, 0}, +{ 6, s_0_6, 5, 1, 0}, +{ 3, s_0_7, 3, 1, 0}, +{ 4, s_0_8, 3, 1, 0}, +{ 3, s_0_9, 3, 1, 0}, +{ 2, s_0_10, -1, 1, 0}, +{ 5, s_0_11, 10, 1, 0}, +{ 4, s_0_12, 10, 1, 0}, +{ 2, s_0_13, -1, 1, 0}, +{ 5, s_0_14, 13, 1, 0}, +{ 4, s_0_15, 13, 1, 0}, +{ 1, s_0_16, -1, 2, 0}, +{ 4, s_0_17, 16, 1, 0}, +{ 2, s_0_18, 16, 1, 0}, +{ 5, s_0_19, 18, 1, 0}, +{ 7, s_0_20, 19, 1, 0}, +{ 4, s_0_21, 18, 1, 0}, +{ 5, s_0_22, 18, 1, 0}, +{ 4, s_0_23, 18, 1, 0}, +{ 3, s_0_24, 16, 1, 0}, +{ 6, s_0_25, 24, 1, 0}, +{ 5, s_0_26, 24, 1, 0}, +{ 3, s_0_27, 16, 1, 0}, +{ 3, s_0_28, 16, 1, 0}, +{ 5, s_0_29, 28, 1, 0}, +{ 2, s_0_30, -1, 1, 0}, +{ 4, s_0_31, 30, 1, 0} }; static const symbol s_1_0[2] = { 'g', 'd' }; @@ -102,10 +102,10 @@ static const symbol s_1_3[2] = { 'k', 't' }; static const struct among a_1[4] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0}, -/* 2 */ { 2, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0}, +{ 2, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0} }; static const symbol s_2_0[2] = { 'i', 'g' }; @@ -116,11 +116,11 @@ static const symbol s_2_4[5] = { 'l', 0xC3, 0xB8, 's', 't' }; static const struct among a_2[5] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 3, s_2_1, 0, 1, 0}, -/* 2 */ { 4, s_2_2, 1, 1, 0}, -/* 3 */ { 3, s_2_3, -1, 1, 0}, -/* 4 */ { 5, s_2_4, -1, 2, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 3, s_2_1, 0, 1, 0}, +{ 4, s_2_2, 1, 1, 0}, +{ 3, s_2_3, -1, 1, 0}, +{ 5, s_2_4, -1, 2, 0} }; static const unsigned char g_c[] = { 119, 223, 119, 1 }; @@ -133,52 +133,52 @@ static const symbol s_0[] = { 's', 't' }; static const symbol s_1[] = { 'i', 'g' }; static const symbol s_2[] = { 'l', 0xC3, 0xB8, 's' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 33 */ - { int c_test1 = z->c; /* test, line 35 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 35 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + { int c_test1 = z->c; + { int ret = skip_utf8(z->p, z->c, z->l, 3); if (ret < 0) return 0; z->c = ret; } - z->I[1] = z->c; /* setmark x, line 35 */ + z->I[0] = z->c; z->c = c_test1; } - if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 36 */ - { /* gopast */ /* non v, line 36 */ + if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; + { int ret = in_grouping_U(z, g_v, 97, 248, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 36 */ - /* try, line 37 */ - if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 37 */ - z->I[0] = z->I[1]; /* $p1 = , line 37 */ + z->I[1] = z->c; + + if (!(z->I[1] < z->I[0])) goto lab0; + z->I[1] = z->I[0]; lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { /* backwardmode */ +static int r_main_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 43 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 43 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 43 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_0, 32); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 43 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 44 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 50 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (in_grouping_b_U(z, g_s_ending, 97, 229, 0)) return 0; /* grouping s_ending, line 52 */ - { int ret = slice_del(z); /* delete, line 52 */ + if (in_grouping_b_U(z, g_s_ending, 97, 229, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -186,69 +186,69 @@ static int r_main_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 57 */ +static int r_consonant_pair(struct SN_env * z) { + { int m_test1 = z->l - z->c; - { int mlimit2; /* setlimit, line 58 */ - if (z->c < z->I[0]) return 0; - mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 58 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit2; return 0; } /* substring, line 58 */ + { int mlimit2; + if (z->c < z->I[1]) return 0; + mlimit2 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit2; return 0; } if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit2; return 0; } - z->bra = z->c; /* ], line 58 */ + z->bra = z->c; z->lb = mlimit2; } z->c = z->l - m_test1; } - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 64 */ + z->c = ret; } - z->bra = z->c; /* ], line 64 */ - { int ret = slice_del(z); /* delete, line 64 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_other_suffix(struct SN_env * z) { /* backwardmode */ +static int r_other_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 68 */ - z->ket = z->c; /* [, line 68 */ - if (!(eq_s_b(z, 2, s_0))) goto lab0; /* literal, line 68 */ - z->bra = z->c; /* ], line 68 */ - if (!(eq_s_b(z, 2, s_1))) goto lab0; /* literal, line 68 */ - { int ret = slice_del(z); /* delete, line 68 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_0))) goto lab0; + z->bra = z->c; + if (!(eq_s_b(z, 2, s_1))) goto lab0; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - { int mlimit2; /* setlimit, line 69 */ - if (z->c < z->I[0]) return 0; - mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 69 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit2; return 0; } /* substring, line 69 */ + { int mlimit2; + if (z->c < z->I[1]) return 0; + mlimit2 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit2; return 0; } among_var = find_among_b(z, a_2, 5); if (!(among_var)) { z->lb = mlimit2; return 0; } - z->bra = z->c; /* ], line 69 */ + z->bra = z->c; z->lb = mlimit2; } - switch (among_var) { /* among, line 70 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 72 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* do, line 72 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 72 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } break; case 2: - { int ret = slice_from_s(z, 4, s_2); /* <-, line 74 */ + { int ret = slice_from_s(z, 4, s_2); if (ret < 0) return ret; } break; @@ -256,54 +256,54 @@ static int r_other_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_undouble(struct SN_env * z) { /* backwardmode */ +static int r_undouble(struct SN_env * z) { - { int mlimit1; /* setlimit, line 78 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 78 */ - if (in_grouping_b_U(z, g_c, 98, 122, 0)) { z->lb = mlimit1; return 0; } /* grouping c, line 78 */ - z->bra = z->c; /* ], line 78 */ - z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 78 */ - if (z->S[0] == 0) return -1; /* -> ch, line 78 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (in_grouping_b_U(z, g_c, 98, 122, 0)) { z->lb = mlimit1; return 0; } + z->bra = z->c; + z->S[0] = slice_to(z, z->S[0]); + if (z->S[0] == 0) return -1; z->lb = mlimit1; } - if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 79 */ - { int ret = slice_del(z); /* delete, line 80 */ + if (!(eq_v_b(z, z->S[0]))) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int danish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 86 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 86 */ +extern int danish_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 87 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 88 */ - { int ret = r_main_suffix(z); /* call main_suffix, line 88 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_main_suffix(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 89 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 89 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 90 */ - { int ret = r_other_suffix(z); /* call other_suffix, line 90 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_other_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 91 */ - { int ret = r_undouble(z); /* call undouble, line 91 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_undouble(z); if (ret < 0) return ret; } z->c = z->l - m5; @@ -312,7 +312,7 @@ extern int danish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * danish_UTF_8_create_env(void) { return SN_create_env(1, 2, 0); } +extern struct SN_env * danish_UTF_8_create_env(void) { return SN_create_env(1, 2); } extern void danish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 1); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c b/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c index 56028832f1f4..bb82be87f7b9 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -43,17 +43,17 @@ static const symbol s_0_10[2] = { 0xC3, 0xBC }; static const struct among a_0[11] = { -/* 0 */ { 0, 0, -1, 6, 0}, -/* 1 */ { 2, s_0_1, 0, 1, 0}, -/* 2 */ { 2, s_0_2, 0, 1, 0}, -/* 3 */ { 2, s_0_3, 0, 2, 0}, -/* 4 */ { 2, s_0_4, 0, 2, 0}, -/* 5 */ { 2, s_0_5, 0, 3, 0}, -/* 6 */ { 2, s_0_6, 0, 3, 0}, -/* 7 */ { 2, s_0_7, 0, 4, 0}, -/* 8 */ { 2, s_0_8, 0, 4, 0}, -/* 9 */ { 2, s_0_9, 0, 5, 0}, -/* 10 */ { 2, s_0_10, 0, 5, 0} +{ 0, 0, -1, 6, 0}, +{ 2, s_0_1, 0, 1, 0}, +{ 2, s_0_2, 0, 1, 0}, +{ 2, s_0_3, 0, 2, 0}, +{ 2, s_0_4, 0, 2, 0}, +{ 2, s_0_5, 0, 3, 0}, +{ 2, s_0_6, 0, 3, 0}, +{ 2, s_0_7, 0, 4, 0}, +{ 2, s_0_8, 0, 4, 0}, +{ 2, s_0_9, 0, 5, 0}, +{ 2, s_0_10, 0, 5, 0} }; static const symbol s_1_1[1] = { 'I' }; @@ -61,9 +61,9 @@ static const symbol s_1_2[1] = { 'Y' }; static const struct among a_1[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 1, s_1_1, 0, 2, 0}, -/* 2 */ { 1, s_1_2, 0, 1, 0} +{ 0, 0, -1, 3, 0}, +{ 1, s_1_1, 0, 2, 0}, +{ 1, s_1_2, 0, 1, 0} }; static const symbol s_2_0[2] = { 'd', 'd' }; @@ -72,9 +72,9 @@ static const symbol s_2_2[2] = { 't', 't' }; static const struct among a_2[3] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 2, s_2_2, -1, -1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 2, s_2_2, -1, -1, 0} }; static const symbol s_3_0[3] = { 'e', 'n', 'e' }; @@ -85,11 +85,11 @@ static const symbol s_3_4[1] = { 's' }; static const struct among a_3[5] = { -/* 0 */ { 3, s_3_0, -1, 2, 0}, -/* 1 */ { 2, s_3_1, -1, 3, 0}, -/* 2 */ { 2, s_3_2, -1, 2, 0}, -/* 3 */ { 5, s_3_3, 2, 1, 0}, -/* 4 */ { 1, s_3_4, -1, 3, 0} +{ 3, s_3_0, -1, 2, 0}, +{ 2, s_3_1, -1, 3, 0}, +{ 2, s_3_2, -1, 2, 0}, +{ 5, s_3_3, 2, 1, 0}, +{ 1, s_3_4, -1, 3, 0} }; static const symbol s_4_0[3] = { 'e', 'n', 'd' }; @@ -101,12 +101,12 @@ static const symbol s_4_5[3] = { 'b', 'a', 'r' }; static const struct among a_4[6] = { -/* 0 */ { 3, s_4_0, -1, 1, 0}, -/* 1 */ { 2, s_4_1, -1, 2, 0}, -/* 2 */ { 3, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 3, 0}, -/* 4 */ { 4, s_4_4, -1, 4, 0}, -/* 5 */ { 3, s_4_5, -1, 5, 0} +{ 3, s_4_0, -1, 1, 0}, +{ 2, s_4_1, -1, 2, 0}, +{ 3, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 3, 0}, +{ 4, s_4_4, -1, 4, 0}, +{ 3, s_4_5, -1, 5, 0} }; static const symbol s_5_0[2] = { 'a', 'a' }; @@ -116,10 +116,10 @@ static const symbol s_5_3[2] = { 'u', 'u' }; static const struct among a_5[4] = { -/* 0 */ { 2, s_5_0, -1, -1, 0}, -/* 1 */ { 2, s_5_1, -1, -1, 0}, -/* 2 */ { 2, s_5_2, -1, -1, 0}, -/* 3 */ { 2, s_5_3, -1, -1, 0} +{ 2, s_5_0, -1, -1, 0}, +{ 2, s_5_1, -1, -1, 0}, +{ 2, s_5_2, -1, -1, 0}, +{ 2, s_5_3, -1, -1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; @@ -144,47 +144,46 @@ static const symbol s_12[] = { 'h', 'e', 'i', 'd' }; static const symbol s_13[] = { 'e', 'n' }; static const symbol s_14[] = { 'i', 'g' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ +static int r_prelude(struct SN_env * z) { int among_var; - { int c_test1 = z->c; /* test, line 42 */ -/* repeat, line 42 */ - - while(1) { int c2 = z->c; - z->bra = z->c; /* [, line 43 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((340306450 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else /* substring, line 43 */ + { int c_test1 = z->c; + while(1) { + int c2 = z->c; + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((340306450 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else among_var = find_among(z, a_0, 11); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 43 */ - switch (among_var) { /* among, line 43 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 45 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 47 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 49 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 51 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 53 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 54 */ + z->c = ret; } break; } @@ -195,39 +194,38 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ } z->c = c_test1; } - { int c3 = z->c; /* try, line 57 */ - z->bra = z->c; /* [, line 57 */ - if (z->c == z->l || z->p[z->c] != 'y') { z->c = c3; goto lab1; } /* literal, line 57 */ + { int c3 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') { z->c = c3; goto lab1; } z->c++; - z->ket = z->c; /* ], line 57 */ - { int ret = slice_from_s(z, 1, s_5); /* <-, line 57 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } lab1: ; } -/* repeat, line 58 */ - - while(1) { int c4 = z->c; - while(1) { /* goto, line 58 */ + while(1) { + int c4 = z->c; + while(1) { int c5 = z->c; - if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab3; /* grouping v, line 59 */ - z->bra = z->c; /* [, line 59 */ - { int c6 = z->c; /* or, line 59 */ - if (z->c == z->l || z->p[z->c] != 'i') goto lab5; /* literal, line 59 */ + if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab3; + z->bra = z->c; + { int c6 = z->c; + if (z->c == z->l || z->p[z->c] != 'i') goto lab5; z->c++; - z->ket = z->c; /* ], line 59 */ - if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab5; /* grouping v, line 59 */ - { int ret = slice_from_s(z, 1, s_6); /* <-, line 59 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab5; + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } goto lab4; lab5: z->c = c6; - if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 60 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; z->c++; - z->ket = z->c; /* ], line 60 */ - { int ret = slice_from_s(z, 1, s_7); /* <-, line 60 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } } @@ -236,9 +234,9 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ break; lab3: z->c = c5; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab2; - z->c = ret; /* goto, line 58 */ + z->c = ret; } } continue; @@ -249,63 +247,62 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 66 */ - z->I[1] = z->l; /* $p2 = , line 67 */ - { /* gopast */ /* grouping v, line 69 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int ret = out_grouping_U(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 69 */ + { int ret = in_grouping_U(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 69 */ - /* try, line 70 */ - if (!(z->I[0] < 3)) goto lab0; /* $( < ), line 70 */ - z->I[0] = 3; /* $p1 = , line 70 */ + z->I[1] = z->c; + + if (!(z->I[1] < 3)) goto lab0; + z->I[1] = 3; lab0: - { /* gopast */ /* grouping v, line 71 */ + { int ret = out_grouping_U(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 71 */ + { int ret = in_grouping_U(z, g_v, 97, 232, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 71 */ + z->I[0] = z->c; return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 75 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 77 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else /* substring, line 77 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 77 */ - switch (among_var) { /* among, line 77 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 78 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; case 3: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 80 */ + z->c = ret; } break; } @@ -317,111 +314,111 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 87 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 88 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_undouble(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 91 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 91 */ +static int r_undouble(struct SN_env * z) { + { int m_test1 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_2, 3))) return 0; z->c = z->l - m_test1; } - z->ket = z->c; /* [, line 91 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 91 */ + z->c = ret; } - z->bra = z->c; /* ], line 91 */ - { int ret = slice_del(z); /* delete, line 91 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_e_ending(struct SN_env * z) { /* backwardmode */ - z->B[0] = 0; /* unset e_found, line 95 */ - z->ket = z->c; /* [, line 96 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 96 */ +static int r_e_ending(struct SN_env * z) { + z->I[2] = 0; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; - z->bra = z->c; /* ], line 96 */ - { int ret = r_R1(z); /* call R1, line 96 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m_test1 = z->l - z->c; /* test, line 96 */ - if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; /* non v, line 96 */ + { int m_test1 = z->l - z->c; + if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; z->c = z->l - m_test1; } - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set e_found, line 97 */ - { int ret = r_undouble(z); /* call undouble, line 98 */ + z->I[2] = 1; + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_en_ending(struct SN_env * z) { /* backwardmode */ - { int ret = r_R1(z); /* call R1, line 102 */ +static int r_en_ending(struct SN_env * z) { + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* and, line 102 */ - if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; /* non v, line 102 */ + { int m1 = z->l - z->c; (void)m1; + if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - if (!(eq_s_b(z, 3, s_10))) goto lab0; /* literal, line 102 */ + { int m2 = z->l - z->c; (void)m2; + if (!(eq_s_b(z, 3, s_10))) goto lab0; return 0; lab0: z->c = z->l - m2; } } - { int ret = slice_del(z); /* delete, line 102 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_undouble(z); /* call undouble, line 103 */ + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 107 */ - z->ket = z->c; /* [, line 108 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 108 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; among_var = find_among_b(z, a_3, 5); if (!(among_var)) goto lab0; - z->bra = z->c; /* ], line 108 */ - switch (among_var) { /* among, line 108 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 110 */ + { int ret = r_R1(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } - { int ret = slice_from_s(z, 4, s_11); /* <-, line 110 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 2: - { int ret = r_en_ending(z); /* call en_ending, line 113 */ + { int ret = r_en_ending(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } break; case 3: - { int ret = r_R1(z); /* call R1, line 116 */ + { int ret = r_R1(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } - if (out_grouping_b_U(z, g_v_j, 97, 232, 0)) goto lab0; /* non v_j, line 116 */ - { int ret = slice_del(z); /* delete, line 116 */ + if (out_grouping_b_U(z, g_v_j, 97, 232, 0)) goto lab0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -429,77 +426,77 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab0: z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 120 */ - { int ret = r_e_ending(z); /* call e_ending, line 120 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_e_ending(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 122 */ - z->ket = z->c; /* [, line 122 */ - if (!(eq_s_b(z, 4, s_12))) goto lab1; /* literal, line 122 */ - z->bra = z->c; /* ], line 122 */ - { int ret = r_R2(z); /* call R2, line 122 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (!(eq_s_b(z, 4, s_12))) goto lab1; + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* not, line 122 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab2; /* literal, line 122 */ + { int m4 = z->l - z->c; (void)m4; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab2; z->c--; goto lab1; lab2: z->c = z->l - m4; } - { int ret = slice_del(z); /* delete, line 122 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 123 */ - if (!(eq_s_b(z, 2, s_13))) goto lab1; /* literal, line 123 */ - z->bra = z->c; /* ], line 123 */ - { int ret = r_en_ending(z); /* call en_ending, line 123 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_13))) goto lab1; + z->bra = z->c; + { int ret = r_en_ending(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m3; } - { int m5 = z->l - z->c; (void)m5; /* do, line 126 */ - z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; /* substring, line 127 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; among_var = find_among_b(z, a_4, 6); if (!(among_var)) goto lab3; - z->bra = z->c; /* ], line 127 */ - switch (among_var) { /* among, line 127 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 129 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 129 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m6 = z->l - z->c; (void)m6; /* or, line 130 */ - z->ket = z->c; /* [, line 130 */ - if (!(eq_s_b(z, 2, s_14))) goto lab5; /* literal, line 130 */ - z->bra = z->c; /* ], line 130 */ - { int ret = r_R2(z); /* call R2, line 130 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_14))) goto lab5; + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int m7 = z->l - z->c; (void)m7; /* not, line 130 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; /* literal, line 130 */ + { int m7 = z->l - z->c; (void)m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; z->c--; goto lab5; lab6: z->c = z->l - m7; } - { int ret = slice_del(z); /* delete, line 130 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m6; - { int ret = r_undouble(z); /* call undouble, line 130 */ + { int ret = r_undouble(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } @@ -507,50 +504,50 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab4: break; case 2: - { int ret = r_R2(z); /* call R2, line 133 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int m8 = z->l - z->c; (void)m8; /* not, line 133 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab7; /* literal, line 133 */ + { int m8 = z->l - z->c; (void)m8; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab7; z->c--; goto lab3; lab7: z->c = z->l - m8; } - { int ret = slice_del(z); /* delete, line 133 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); /* call R2, line 136 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 136 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_e_ending(z); /* call e_ending, line 136 */ + { int ret = r_e_ending(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 139 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 142 */ + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - if (!(z->B[0])) goto lab3; /* Boolean test e_found, line 142 */ - { int ret = slice_del(z); /* delete, line 142 */ + if (!(z->I[2])) goto lab3; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -558,21 +555,21 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab3: z->c = z->l - m5; } - { int m9 = z->l - z->c; (void)m9; /* do, line 146 */ - if (out_grouping_b_U(z, g_v_I, 73, 232, 0)) goto lab8; /* non v_I, line 147 */ - { int m_test10 = z->l - z->c; /* test, line 148 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab8; /* among, line 149 */ + { int m9 = z->l - z->c; (void)m9; + if (out_grouping_b_U(z, g_v_I, 73, 232, 0)) goto lab8; + { int m_test10 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab8; if (!(find_among_b(z, a_5, 4))) goto lab8; - if (out_grouping_b_U(z, g_v, 97, 232, 0)) goto lab8; /* non v, line 150 */ + if (out_grouping_b_U(z, g_v, 97, 232, 0)) goto lab8; z->c = z->l - m_test10; } - z->ket = z->c; /* [, line 152 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) goto lab8; - z->c = ret; /* next, line 152 */ + z->c = ret; } - z->bra = z->c; /* ], line 152 */ - { int ret = slice_del(z); /* delete, line 152 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab8: @@ -581,28 +578,28 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int dutch_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 159 */ - { int ret = r_prelude(z); /* call prelude, line 159 */ +extern int dutch_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - { int c2 = z->c; /* do, line 160 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 160 */ + { int c2 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c2; } - z->lb = z->c; z->c = z->l; /* backwards, line 161 */ + z->lb = z->c; z->c = z->l; - /* do, line 162 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 162 */ + + { int ret = r_standard_suffix(z); if (ret < 0) return ret; } z->c = z->lb; - { int c3 = z->c; /* do, line 163 */ - { int ret = r_postlude(z); /* call postlude, line 163 */ + { int c3 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c3; @@ -610,7 +607,7 @@ extern int dutch_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * dutch_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); } +extern struct SN_env * dutch_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void dutch_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_english.c b/src/backend/snowball/libstemmer/stem_UTF_8_english.c index e03c37c98a3b..f94d08f9f727 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_english.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_english.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -42,9 +42,9 @@ static const symbol s_0_2[5] = { 'g', 'e', 'n', 'e', 'r' }; static const struct among a_0[3] = { -/* 0 */ { 5, s_0_0, -1, -1, 0}, -/* 1 */ { 6, s_0_1, -1, -1, 0}, -/* 2 */ { 5, s_0_2, -1, -1, 0} +{ 5, s_0_0, -1, -1, 0}, +{ 6, s_0_1, -1, -1, 0}, +{ 5, s_0_2, -1, -1, 0} }; static const symbol s_1_0[1] = { '\'' }; @@ -53,9 +53,9 @@ static const symbol s_1_2[2] = { '\'', 's' }; static const struct among a_1[3] = { -/* 0 */ { 1, s_1_0, -1, 1, 0}, -/* 1 */ { 3, s_1_1, 0, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0} +{ 1, s_1_0, -1, 1, 0}, +{ 3, s_1_1, 0, 1, 0}, +{ 2, s_1_2, -1, 1, 0} }; static const symbol s_2_0[3] = { 'i', 'e', 'd' }; @@ -67,12 +67,12 @@ static const symbol s_2_5[2] = { 'u', 's' }; static const struct among a_2[6] = { -/* 0 */ { 3, s_2_0, -1, 2, 0}, -/* 1 */ { 1, s_2_1, -1, 3, 0}, -/* 2 */ { 3, s_2_2, 1, 2, 0}, -/* 3 */ { 4, s_2_3, 1, 1, 0}, -/* 4 */ { 2, s_2_4, 1, -1, 0}, -/* 5 */ { 2, s_2_5, 1, -1, 0} +{ 3, s_2_0, -1, 2, 0}, +{ 1, s_2_1, -1, 3, 0}, +{ 3, s_2_2, 1, 2, 0}, +{ 4, s_2_3, 1, 1, 0}, +{ 2, s_2_4, 1, -1, 0}, +{ 2, s_2_5, 1, -1, 0} }; static const symbol s_3_1[2] = { 'b', 'b' }; @@ -90,19 +90,19 @@ static const symbol s_3_12[2] = { 'i', 'z' }; static const struct among a_3[13] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 2, s_3_1, 0, 2, 0}, -/* 2 */ { 2, s_3_2, 0, 2, 0}, -/* 3 */ { 2, s_3_3, 0, 2, 0}, -/* 4 */ { 2, s_3_4, 0, 2, 0}, -/* 5 */ { 2, s_3_5, 0, 1, 0}, -/* 6 */ { 2, s_3_6, 0, 2, 0}, -/* 7 */ { 2, s_3_7, 0, 2, 0}, -/* 8 */ { 2, s_3_8, 0, 2, 0}, -/* 9 */ { 2, s_3_9, 0, 2, 0}, -/* 10 */ { 2, s_3_10, 0, 1, 0}, -/* 11 */ { 2, s_3_11, 0, 2, 0}, -/* 12 */ { 2, s_3_12, 0, 1, 0} +{ 0, 0, -1, 3, 0}, +{ 2, s_3_1, 0, 2, 0}, +{ 2, s_3_2, 0, 2, 0}, +{ 2, s_3_3, 0, 2, 0}, +{ 2, s_3_4, 0, 2, 0}, +{ 2, s_3_5, 0, 1, 0}, +{ 2, s_3_6, 0, 2, 0}, +{ 2, s_3_7, 0, 2, 0}, +{ 2, s_3_8, 0, 2, 0}, +{ 2, s_3_9, 0, 2, 0}, +{ 2, s_3_10, 0, 1, 0}, +{ 2, s_3_11, 0, 2, 0}, +{ 2, s_3_12, 0, 1, 0} }; static const symbol s_4_0[2] = { 'e', 'd' }; @@ -114,12 +114,12 @@ static const symbol s_4_5[5] = { 'i', 'n', 'g', 'l', 'y' }; static const struct among a_4[6] = { -/* 0 */ { 2, s_4_0, -1, 2, 0}, -/* 1 */ { 3, s_4_1, 0, 1, 0}, -/* 2 */ { 3, s_4_2, -1, 2, 0}, -/* 3 */ { 4, s_4_3, -1, 2, 0}, -/* 4 */ { 5, s_4_4, 3, 1, 0}, -/* 5 */ { 5, s_4_5, -1, 2, 0} +{ 2, s_4_0, -1, 2, 0}, +{ 3, s_4_1, 0, 1, 0}, +{ 3, s_4_2, -1, 2, 0}, +{ 4, s_4_3, -1, 2, 0}, +{ 5, s_4_4, 3, 1, 0}, +{ 5, s_4_5, -1, 2, 0} }; static const symbol s_5_0[4] = { 'a', 'n', 'c', 'i' }; @@ -149,30 +149,30 @@ static const symbol s_5_23[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; static const struct among a_5[24] = { -/* 0 */ { 4, s_5_0, -1, 3, 0}, -/* 1 */ { 4, s_5_1, -1, 2, 0}, -/* 2 */ { 3, s_5_2, -1, 13, 0}, -/* 3 */ { 2, s_5_3, -1, 15, 0}, -/* 4 */ { 3, s_5_4, 3, 12, 0}, -/* 5 */ { 4, s_5_5, 4, 4, 0}, -/* 6 */ { 4, s_5_6, 3, 8, 0}, -/* 7 */ { 5, s_5_7, 3, 9, 0}, -/* 8 */ { 6, s_5_8, 3, 14, 0}, -/* 9 */ { 5, s_5_9, 3, 10, 0}, -/* 10 */ { 5, s_5_10, 3, 5, 0}, -/* 11 */ { 5, s_5_11, -1, 8, 0}, -/* 12 */ { 6, s_5_12, -1, 12, 0}, -/* 13 */ { 5, s_5_13, -1, 11, 0}, -/* 14 */ { 6, s_5_14, -1, 1, 0}, -/* 15 */ { 7, s_5_15, 14, 7, 0}, -/* 16 */ { 5, s_5_16, -1, 8, 0}, -/* 17 */ { 5, s_5_17, -1, 7, 0}, -/* 18 */ { 7, s_5_18, 17, 6, 0}, -/* 19 */ { 4, s_5_19, -1, 6, 0}, -/* 20 */ { 4, s_5_20, -1, 7, 0}, -/* 21 */ { 7, s_5_21, -1, 11, 0}, -/* 22 */ { 7, s_5_22, -1, 9, 0}, -/* 23 */ { 7, s_5_23, -1, 10, 0} +{ 4, s_5_0, -1, 3, 0}, +{ 4, s_5_1, -1, 2, 0}, +{ 3, s_5_2, -1, 13, 0}, +{ 2, s_5_3, -1, 15, 0}, +{ 3, s_5_4, 3, 12, 0}, +{ 4, s_5_5, 4, 4, 0}, +{ 4, s_5_6, 3, 8, 0}, +{ 5, s_5_7, 3, 9, 0}, +{ 6, s_5_8, 3, 14, 0}, +{ 5, s_5_9, 3, 10, 0}, +{ 5, s_5_10, 3, 5, 0}, +{ 5, s_5_11, -1, 8, 0}, +{ 6, s_5_12, -1, 12, 0}, +{ 5, s_5_13, -1, 11, 0}, +{ 6, s_5_14, -1, 1, 0}, +{ 7, s_5_15, 14, 7, 0}, +{ 5, s_5_16, -1, 8, 0}, +{ 5, s_5_17, -1, 7, 0}, +{ 7, s_5_18, 17, 6, 0}, +{ 4, s_5_19, -1, 6, 0}, +{ 4, s_5_20, -1, 7, 0}, +{ 7, s_5_21, -1, 11, 0}, +{ 7, s_5_22, -1, 9, 0}, +{ 7, s_5_23, -1, 10, 0} }; static const symbol s_6_0[5] = { 'i', 'c', 'a', 't', 'e' }; @@ -187,15 +187,15 @@ static const symbol s_6_8[4] = { 'n', 'e', 's', 's' }; static const struct among a_6[9] = { -/* 0 */ { 5, s_6_0, -1, 4, 0}, -/* 1 */ { 5, s_6_1, -1, 6, 0}, -/* 2 */ { 5, s_6_2, -1, 3, 0}, -/* 3 */ { 5, s_6_3, -1, 4, 0}, -/* 4 */ { 4, s_6_4, -1, 4, 0}, -/* 5 */ { 6, s_6_5, -1, 1, 0}, -/* 6 */ { 7, s_6_6, 5, 2, 0}, -/* 7 */ { 3, s_6_7, -1, 5, 0}, -/* 8 */ { 4, s_6_8, -1, 5, 0} +{ 5, s_6_0, -1, 4, 0}, +{ 5, s_6_1, -1, 6, 0}, +{ 5, s_6_2, -1, 3, 0}, +{ 5, s_6_3, -1, 4, 0}, +{ 4, s_6_4, -1, 4, 0}, +{ 6, s_6_5, -1, 1, 0}, +{ 7, s_6_6, 5, 2, 0}, +{ 3, s_6_7, -1, 5, 0}, +{ 4, s_6_8, -1, 5, 0} }; static const symbol s_7_0[2] = { 'i', 'c' }; @@ -219,24 +219,24 @@ static const symbol s_7_17[5] = { 'e', 'm', 'e', 'n', 't' }; static const struct among a_7[18] = { -/* 0 */ { 2, s_7_0, -1, 1, 0}, -/* 1 */ { 4, s_7_1, -1, 1, 0}, -/* 2 */ { 4, s_7_2, -1, 1, 0}, -/* 3 */ { 4, s_7_3, -1, 1, 0}, -/* 4 */ { 4, s_7_4, -1, 1, 0}, -/* 5 */ { 3, s_7_5, -1, 1, 0}, -/* 6 */ { 3, s_7_6, -1, 1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 3, s_7_8, -1, 1, 0}, -/* 9 */ { 2, s_7_9, -1, 1, 0}, -/* 10 */ { 3, s_7_10, -1, 1, 0}, -/* 11 */ { 3, s_7_11, -1, 2, 0}, -/* 12 */ { 2, s_7_12, -1, 1, 0}, -/* 13 */ { 3, s_7_13, -1, 1, 0}, -/* 14 */ { 3, s_7_14, -1, 1, 0}, -/* 15 */ { 3, s_7_15, -1, 1, 0}, -/* 16 */ { 4, s_7_16, 15, 1, 0}, -/* 17 */ { 5, s_7_17, 16, 1, 0} +{ 2, s_7_0, -1, 1, 0}, +{ 4, s_7_1, -1, 1, 0}, +{ 4, s_7_2, -1, 1, 0}, +{ 4, s_7_3, -1, 1, 0}, +{ 4, s_7_4, -1, 1, 0}, +{ 3, s_7_5, -1, 1, 0}, +{ 3, s_7_6, -1, 1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 3, s_7_8, -1, 1, 0}, +{ 2, s_7_9, -1, 1, 0}, +{ 3, s_7_10, -1, 1, 0}, +{ 3, s_7_11, -1, 2, 0}, +{ 2, s_7_12, -1, 1, 0}, +{ 3, s_7_13, -1, 1, 0}, +{ 3, s_7_14, -1, 1, 0}, +{ 3, s_7_15, -1, 1, 0}, +{ 4, s_7_16, 15, 1, 0}, +{ 5, s_7_17, 16, 1, 0} }; static const symbol s_8_0[1] = { 'e' }; @@ -244,8 +244,8 @@ static const symbol s_8_1[1] = { 'l' }; static const struct among a_8[2] = { -/* 0 */ { 1, s_8_0, -1, 1, 0}, -/* 1 */ { 1, s_8_1, -1, 2, 0} +{ 1, s_8_0, -1, 1, 0}, +{ 1, s_8_1, -1, 2, 0} }; static const symbol s_9_0[7] = { 's', 'u', 'c', 'c', 'e', 'e', 'd' }; @@ -259,14 +259,14 @@ static const symbol s_9_7[6] = { 'o', 'u', 't', 'i', 'n', 'g' }; static const struct among a_9[8] = { -/* 0 */ { 7, s_9_0, -1, -1, 0}, -/* 1 */ { 7, s_9_1, -1, -1, 0}, -/* 2 */ { 6, s_9_2, -1, -1, 0}, -/* 3 */ { 7, s_9_3, -1, -1, 0}, -/* 4 */ { 6, s_9_4, -1, -1, 0}, -/* 5 */ { 7, s_9_5, -1, -1, 0}, -/* 6 */ { 7, s_9_6, -1, -1, 0}, -/* 7 */ { 6, s_9_7, -1, -1, 0} +{ 7, s_9_0, -1, -1, 0}, +{ 7, s_9_1, -1, -1, 0}, +{ 6, s_9_2, -1, -1, 0}, +{ 7, s_9_3, -1, -1, 0}, +{ 6, s_9_4, -1, -1, 0}, +{ 7, s_9_5, -1, -1, 0}, +{ 7, s_9_6, -1, -1, 0}, +{ 6, s_9_7, -1, -1, 0} }; static const symbol s_10_0[5] = { 'a', 'n', 'd', 'e', 's' }; @@ -290,24 +290,24 @@ static const symbol s_10_17[4] = { 'u', 'g', 'l', 'y' }; static const struct among a_10[18] = { -/* 0 */ { 5, s_10_0, -1, -1, 0}, -/* 1 */ { 5, s_10_1, -1, -1, 0}, -/* 2 */ { 4, s_10_2, -1, -1, 0}, -/* 3 */ { 6, s_10_3, -1, -1, 0}, -/* 4 */ { 5, s_10_4, -1, 3, 0}, -/* 5 */ { 5, s_10_5, -1, 9, 0}, -/* 6 */ { 6, s_10_6, -1, 7, 0}, -/* 7 */ { 4, s_10_7, -1, -1, 0}, -/* 8 */ { 4, s_10_8, -1, 6, 0}, -/* 9 */ { 5, s_10_9, -1, 4, 0}, -/* 10 */ { 4, s_10_10, -1, -1, 0}, -/* 11 */ { 4, s_10_11, -1, 10, 0}, -/* 12 */ { 6, s_10_12, -1, 11, 0}, -/* 13 */ { 5, s_10_13, -1, 2, 0}, -/* 14 */ { 4, s_10_14, -1, 1, 0}, -/* 15 */ { 3, s_10_15, -1, -1, 0}, -/* 16 */ { 5, s_10_16, -1, 5, 0}, -/* 17 */ { 4, s_10_17, -1, 8, 0} +{ 5, s_10_0, -1, -1, 0}, +{ 5, s_10_1, -1, -1, 0}, +{ 4, s_10_2, -1, -1, 0}, +{ 6, s_10_3, -1, -1, 0}, +{ 5, s_10_4, -1, 3, 0}, +{ 5, s_10_5, -1, 9, 0}, +{ 6, s_10_6, -1, 7, 0}, +{ 4, s_10_7, -1, -1, 0}, +{ 4, s_10_8, -1, 6, 0}, +{ 5, s_10_9, -1, 4, 0}, +{ 4, s_10_10, -1, -1, 0}, +{ 4, s_10_11, -1, 10, 0}, +{ 6, s_10_12, -1, 11, 0}, +{ 5, s_10_13, -1, 2, 0}, +{ 4, s_10_14, -1, 1, 0}, +{ 3, s_10_15, -1, -1, 0}, +{ 5, s_10_16, -1, 5, 0}, +{ 4, s_10_17, -1, 8, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1 }; @@ -356,55 +356,54 @@ static const symbol s_36[] = { 'o', 'n', 'l', 'i' }; static const symbol s_37[] = { 's', 'i', 'n', 'g', 'l' }; static const symbol s_38[] = { 'y' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset Y_found, line 26 */ - { int c1 = z->c; /* do, line 27 */ - z->bra = z->c; /* [, line 27 */ - if (z->c == z->l || z->p[z->c] != '\'') goto lab0; /* literal, line 27 */ +static int r_prelude(struct SN_env * z) { + z->I[2] = 0; + { int c1 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != '\'') goto lab0; z->c++; - z->ket = z->c; /* ], line 27 */ - { int ret = slice_del(z); /* delete, line 27 */ + z->ket = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 28 */ - z->bra = z->c; /* [, line 28 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab1; /* literal, line 28 */ + { int c2 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab1; z->c++; - z->ket = z->c; /* ], line 28 */ - { int ret = slice_from_s(z, 1, s_0); /* <-, line 28 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 28 */ + z->I[2] = 1; lab1: z->c = c2; } - { int c3 = z->c; /* do, line 29 */ -/* repeat, line 29 */ - - while(1) { int c4 = z->c; - while(1) { /* goto, line 29 */ + { int c3 = z->c; + while(1) { + int c4 = z->c; + while(1) { int c5 = z->c; - if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab4; /* grouping v, line 29 */ - z->bra = z->c; /* [, line 29 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 29 */ + if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab4; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; z->c++; - z->ket = z->c; /* ], line 29 */ + z->ket = z->c; z->c = c5; break; lab4: z->c = c5; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab3; - z->c = ret; /* goto, line 29 */ + z->c = ret; } } - { int ret = slice_from_s(z, 1, s_1); /* <-, line 29 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 29 */ + z->I[2] = 1; continue; lab3: z->c = c4; @@ -415,125 +414,125 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 33 */ - z->I[1] = z->l; /* $p2 = , line 34 */ - { int c1 = z->c; /* do, line 35 */ - { int c2 = z->c; /* or, line 41 */ - if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; /* among, line 36 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; if (!(find_among(z, a_0, 3))) goto lab2; goto lab1; lab2: z->c = c2; - { /* gopast */ /* grouping v, line 41 */ + { int ret = out_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 41 */ + { int ret = in_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } } lab1: - z->I[0] = z->c; /* setmark p1, line 42 */ - { /* gopast */ /* grouping v, line 43 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 43 */ + { int ret = in_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 43 */ + z->I[0] = z->c; lab0: z->c = c1; } return 1; } -static int r_shortv(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* or, line 51 */ - if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) goto lab1; /* non v_WXY, line 50 */ - if (in_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; /* grouping v, line 50 */ - if (out_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; /* non v, line 50 */ +static int r_shortv(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) goto lab1; + if (in_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; + if (out_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; goto lab0; lab1: z->c = z->l - m1; - if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* non v, line 52 */ - if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 52 */ - if (z->c > z->lb) return 0; /* atlimit, line 52 */ + if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; + if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; + if (z->c > z->lb) return 0; } lab0: return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 55 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 56 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_Step_1a(struct SN_env * z) { /* backwardmode */ +static int r_Step_1a(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* try, line 59 */ - z->ket = z->c; /* [, line 60 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m1; goto lab0; } /* substring, line 60 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m1; goto lab0; } if (!(find_among_b(z, a_1, 3))) { z->c = z->l - m1; goto lab0; } - z->bra = z->c; /* ], line 60 */ - { int ret = slice_del(z); /* delete, line 62 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: ; } - z->ket = z->c; /* [, line 65 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; /* substring, line 65 */ + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; among_var = find_among_b(z, a_2, 6); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 65 */ - switch (among_var) { /* among, line 65 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_2); /* <-, line 66 */ + { int ret = slice_from_s(z, 2, s_2); if (ret < 0) return ret; } break; case 2: - { int m2 = z->l - z->c; (void)m2; /* or, line 68 */ - { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 2); /* hop, line 68 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 2); if (ret < 0) goto lab2; z->c = ret; } - { int ret = slice_from_s(z, 1, s_3); /* <-, line 68 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m2; - { int ret = slice_from_s(z, 2, s_4); /* <-, line 68 */ + { int ret = slice_from_s(z, 2, s_4); if (ret < 0) return ret; } } lab1: break; case 3: - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 69 */ + z->c = ret; } - { /* gopast */ /* grouping v, line 69 */ + { int ret = out_grouping_b_U(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - { int ret = slice_del(z); /* delete, line 69 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -541,72 +540,72 @@ static int r_Step_1a(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1b(struct SN_env * z) { /* backwardmode */ +static int r_Step_1b(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 75 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 75 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_4, 6); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 75 */ - switch (among_var) { /* among, line 75 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 77 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_5); /* <-, line 77 */ + { int ret = slice_from_s(z, 2, s_5); if (ret < 0) return ret; } break; case 2: - { int m_test1 = z->l - z->c; /* test, line 80 */ - { /* gopast */ /* grouping v, line 80 */ + { int m_test1 = z->l - z->c; + { int ret = out_grouping_b_U(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } z->c = z->l - m_test1; } - { int ret = slice_del(z); /* delete, line 80 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m_test2 = z->l - z->c; /* test, line 81 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 81 */ + { int m_test2 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else among_var = find_among_b(z, a_3, 13); if (!(among_var)) return 0; z->c = z->l - m_test2; } - switch (among_var) { /* among, line 81 */ + switch (among_var) { case 1: { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_6); /* <+, line 83 */ + ret = insert_s(z, z->c, z->c, 1, s_6); z->c = saved_c; } if (ret < 0) return ret; } break; case 2: - z->ket = z->c; /* [, line 86 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 86 */ + z->c = ret; } - z->bra = z->c; /* ], line 86 */ - { int ret = slice_del(z); /* delete, line 86 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - if (z->c != z->I[0]) return 0; /* atmark, line 87 */ - { int m_test3 = z->l - z->c; /* test, line 87 */ - { int ret = r_shortv(z); /* call shortv, line 87 */ + if (z->c != z->I[1]) return 0; + { int m_test3 = z->l - z->c; + { int ret = r_shortv(z); if (ret <= 0) return ret; } z->c = z->l - m_test3; } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_7); /* <+, line 87 */ + ret = insert_s(z, z->c, z->c, 1, s_7); z->c = saved_c; } if (ret < 0) return ret; @@ -618,116 +617,116 @@ static int r_Step_1b(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1c(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 94 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 94 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 94 */ +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 94 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; z->c--; } lab0: - z->bra = z->c; /* ], line 94 */ - if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* non v, line 95 */ - /* not, line 95 */ - if (z->c > z->lb) goto lab2; /* atlimit, line 95 */ + z->bra = z->c; + if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; + + if (z->c > z->lb) goto lab2; return 0; lab2: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 96 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { /* backwardmode */ +static int r_Step_2(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 100 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 100 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_5, 24); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 100 */ - { int ret = r_R1(z); /* call R1, line 100 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 100 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_9); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_9); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_10); /* <-, line 102 */ + { int ret = slice_from_s(z, 4, s_10); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 103 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_13); /* <-, line 105 */ + { int ret = slice_from_s(z, 3, s_13); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_14); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_14); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_15); /* <-, line 109 */ + { int ret = slice_from_s(z, 3, s_15); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 111 */ + { int ret = slice_from_s(z, 2, s_16); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 3, s_17); /* <-, line 112 */ + { int ret = slice_from_s(z, 3, s_17); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 114 */ + { int ret = slice_from_s(z, 3, s_18); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_19); /* <-, line 116 */ + { int ret = slice_from_s(z, 3, s_19); if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_20); if (ret < 0) return ret; } break; case 13: - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 119 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - { int ret = slice_from_s(z, 2, s_21); /* <-, line 119 */ + { int ret = slice_from_s(z, 2, s_21); if (ret < 0) return ret; } break; case 14: - { int ret = slice_from_s(z, 4, s_22); /* <-, line 121 */ + { int ret = slice_from_s(z, 4, s_22); if (ret < 0) return ret; } break; case 15: - if (in_grouping_b_U(z, g_valid_LI, 99, 116, 0)) return 0; /* grouping valid_LI, line 122 */ - { int ret = slice_del(z); /* delete, line 122 */ + if (in_grouping_b_U(z, g_valid_LI, 99, 116, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -735,47 +734,47 @@ static int r_Step_2(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_3(struct SN_env * z) { /* backwardmode */ +static int r_Step_3(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 127 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 127 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_6, 9); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 127 */ - { int ret = r_R1(z); /* call R1, line 127 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 127 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_23); /* <-, line 128 */ + { int ret = slice_from_s(z, 4, s_23); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_24); /* <-, line 129 */ + { int ret = slice_from_s(z, 3, s_24); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_25); /* <-, line 130 */ + { int ret = slice_from_s(z, 2, s_25); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_26); /* <-, line 132 */ + { int ret = slice_from_s(z, 2, s_26); if (ret < 0) return ret; } break; case 5: - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 6: - { int ret = r_R2(z); /* call R2, line 136 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 136 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -783,34 +782,34 @@ static int r_Step_3(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_4(struct SN_env * z) { /* backwardmode */ +static int r_Step_4(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 141 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 141 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_7, 18); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 141 */ - { int ret = r_R2(z); /* call R2, line 141 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 141 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 144 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 145 */ + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 145 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 145 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -818,28 +817,28 @@ static int r_Step_4(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_5(struct SN_env * z) { /* backwardmode */ +static int r_Step_5(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 150 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; /* substring, line 150 */ + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; among_var = find_among_b(z, a_8, 2); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 150 */ - switch (among_var) { /* among, line 150 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 151 */ - { int ret = r_R2(z); /* call R2, line 151 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_R2(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); /* call R1, line 151 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* not, line 151 */ - { int ret = r_shortv(z); /* call shortv, line 151 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_shortv(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } @@ -849,17 +848,17 @@ static int r_Step_5(struct SN_env * z) { /* backwardmode */ } } lab0: - { int ret = slice_del(z); /* delete, line 151 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 152 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 152 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -867,76 +866,76 @@ static int r_Step_5(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_exception2(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 158 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 158 */ +static int r_exception2(struct SN_env * z) { + z->ket = z->c; + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; if (!(find_among_b(z, a_9, 8))) return 0; - z->bra = z->c; /* ], line 158 */ - if (z->c > z->lb) return 0; /* atlimit, line 158 */ + z->bra = z->c; + if (z->c > z->lb) return 0; return 1; } -static int r_exception1(struct SN_env * z) { /* forwardmode */ +static int r_exception1(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 170 */ - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; /* substring, line 170 */ + z->bra = z->c; + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; among_var = find_among(z, a_10, 18); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 170 */ - if (z->c < z->l) return 0; /* atlimit, line 170 */ - switch (among_var) { /* among, line 170 */ + z->ket = z->c; + if (z->c < z->l) return 0; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 3, s_27); /* <-, line 174 */ + { int ret = slice_from_s(z, 3, s_27); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_28); /* <-, line 175 */ + { int ret = slice_from_s(z, 3, s_28); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_29); /* <-, line 176 */ + { int ret = slice_from_s(z, 3, s_29); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 3, s_30); /* <-, line 177 */ + { int ret = slice_from_s(z, 3, s_30); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_31); /* <-, line 178 */ + { int ret = slice_from_s(z, 3, s_31); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_32); /* <-, line 182 */ + { int ret = slice_from_s(z, 3, s_32); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 5, s_33); /* <-, line 183 */ + { int ret = slice_from_s(z, 5, s_33); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 4, s_34); /* <-, line 184 */ + { int ret = slice_from_s(z, 4, s_34); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 5, s_35); /* <-, line 185 */ + { int ret = slice_from_s(z, 5, s_35); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 4, s_36); /* <-, line 186 */ + { int ret = slice_from_s(z, 4, s_36); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 5, s_37); /* <-, line 187 */ + { int ret = slice_from_s(z, 5, s_37); if (ret < 0) return ret; } break; @@ -944,27 +943,26 @@ static int r_exception1(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ - if (!(z->B[0])) return 0; /* Boolean test Y_found, line 203 */ -/* repeat, line 203 */ - - while(1) { int c1 = z->c; - while(1) { /* goto, line 203 */ +static int r_postlude(struct SN_env * z) { + if (!(z->I[2])) return 0; + while(1) { + int c1 = z->c; + while(1) { int c2 = z->c; - z->bra = z->c; /* [, line 203 */ - if (z->c == z->l || z->p[z->c] != 'Y') goto lab1; /* literal, line 203 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab1; z->c++; - z->ket = z->c; /* ], line 203 */ + z->ket = z->c; z->c = c2; break; lab1: z->c = c2; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* goto, line 203 */ + z->c = ret; } } - { int ret = slice_from_s(z, 1, s_38); /* <-, line 203 */ + { int ret = slice_from_s(z, 1, s_38); if (ret < 0) return ret; } continue; @@ -975,17 +973,17 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -extern int english_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* or, line 207 */ - { int ret = r_exception1(z); /* call exception1, line 207 */ +extern int english_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_exception1(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = c1; - { int c2 = z->c; /* not, line 208 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 208 */ + { int c2 = z->c; + { int ret = skip_utf8(z->p, z->c, z->l, 3); if (ret < 0) goto lab3; z->c = ret; } @@ -996,62 +994,62 @@ extern int english_UTF_8_stem(struct SN_env * z) { /* forwardmode */ goto lab0; lab2: z->c = c1; - /* do, line 209 */ - { int ret = r_prelude(z); /* call prelude, line 209 */ + + { int ret = r_prelude(z); if (ret < 0) return ret; } - /* do, line 210 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 210 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 211 */ + z->lb = z->c; z->c = z->l; - { int m3 = z->l - z->c; (void)m3; /* do, line 213 */ - { int ret = r_Step_1a(z); /* call Step_1a, line 213 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_Step_1a(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* or, line 215 */ - { int ret = r_exception2(z); /* call exception2, line 215 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_exception2(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m4; - { int m5 = z->l - z->c; (void)m5; /* do, line 217 */ - { int ret = r_Step_1b(z); /* call Step_1b, line 217 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_Step_1b(z); if (ret < 0) return ret; } z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* do, line 218 */ - { int ret = r_Step_1c(z); /* call Step_1c, line 218 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_Step_1c(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 220 */ - { int ret = r_Step_2(z); /* call Step_2, line 220 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_Step_2(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 221 */ - { int ret = r_Step_3(z); /* call Step_3, line 221 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_Step_3(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 222 */ - { int ret = r_Step_4(z); /* call Step_4, line 222 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_Step_4(z); if (ret < 0) return ret; } z->c = z->l - m9; } - { int m10 = z->l - z->c; (void)m10; /* do, line 224 */ - { int ret = r_Step_5(z); /* call Step_5, line 224 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_Step_5(z); if (ret < 0) return ret; } z->c = z->l - m10; @@ -1059,8 +1057,8 @@ extern int english_UTF_8_stem(struct SN_env * z) { /* forwardmode */ } lab4: z->c = z->lb; - { int c11 = z->c; /* do, line 227 */ - { int ret = r_postlude(z); /* call postlude, line 227 */ + { int c11 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c11; @@ -1070,7 +1068,7 @@ extern int english_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * english_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); } +extern struct SN_env * english_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void english_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c b/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c index d99456f32392..77995bec0158 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -45,16 +45,16 @@ static const symbol s_0_9[3] = { 'k', 0xC3, 0xB6 }; static const struct among a_0[10] = { -/* 0 */ { 2, s_0_0, -1, 1, 0}, -/* 1 */ { 3, s_0_1, -1, 2, 0}, -/* 2 */ { 4, s_0_2, -1, 1, 0}, -/* 3 */ { 3, s_0_3, -1, 1, 0}, -/* 4 */ { 3, s_0_4, -1, 1, 0}, -/* 5 */ { 4, s_0_5, -1, 1, 0}, -/* 6 */ { 6, s_0_6, -1, 1, 0}, -/* 7 */ { 2, s_0_7, -1, 1, 0}, -/* 8 */ { 3, s_0_8, -1, 1, 0}, -/* 9 */ { 3, s_0_9, -1, 1, 0} +{ 2, s_0_0, -1, 1, 0}, +{ 3, s_0_1, -1, 2, 0}, +{ 4, s_0_2, -1, 1, 0}, +{ 3, s_0_3, -1, 1, 0}, +{ 3, s_0_4, -1, 1, 0}, +{ 4, s_0_5, -1, 1, 0}, +{ 6, s_0_6, -1, 1, 0}, +{ 2, s_0_7, -1, 1, 0}, +{ 3, s_0_8, -1, 1, 0}, +{ 3, s_0_9, -1, 1, 0} }; static const symbol s_1_0[3] = { 'l', 'l', 'a' }; @@ -66,12 +66,12 @@ static const symbol s_1_5[3] = { 's', 't', 'a' }; static const struct among a_1[6] = { -/* 0 */ { 3, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0}, -/* 2 */ { 3, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0}, -/* 4 */ { 3, s_1_4, 3, -1, 0}, -/* 5 */ { 3, s_1_5, 3, -1, 0} +{ 3, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0}, +{ 3, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0}, +{ 3, s_1_4, 3, -1, 0}, +{ 3, s_1_5, 3, -1, 0} }; static const symbol s_2_0[4] = { 'l', 'l', 0xC3, 0xA4 }; @@ -83,12 +83,12 @@ static const symbol s_2_5[4] = { 's', 't', 0xC3, 0xA4 }; static const struct among a_2[6] = { -/* 0 */ { 4, s_2_0, -1, -1, 0}, -/* 1 */ { 3, s_2_1, -1, -1, 0}, -/* 2 */ { 4, s_2_2, -1, -1, 0}, -/* 3 */ { 3, s_2_3, -1, -1, 0}, -/* 4 */ { 4, s_2_4, 3, -1, 0}, -/* 5 */ { 4, s_2_5, 3, -1, 0} +{ 4, s_2_0, -1, -1, 0}, +{ 3, s_2_1, -1, -1, 0}, +{ 4, s_2_2, -1, -1, 0}, +{ 3, s_2_3, -1, -1, 0}, +{ 4, s_2_4, 3, -1, 0}, +{ 4, s_2_5, 3, -1, 0} }; static const symbol s_3_0[3] = { 'l', 'l', 'e' }; @@ -96,8 +96,8 @@ static const symbol s_3_1[3] = { 'i', 'n', 'e' }; static const struct among a_3[2] = { -/* 0 */ { 3, s_3_0, -1, -1, 0}, -/* 1 */ { 3, s_3_1, -1, -1, 0} +{ 3, s_3_0, -1, -1, 0}, +{ 3, s_3_1, -1, -1, 0} }; static const symbol s_4_0[3] = { 'n', 's', 'a' }; @@ -112,15 +112,15 @@ static const symbol s_4_8[4] = { 'n', 's', 0xC3, 0xA4 }; static const struct among a_4[9] = { -/* 0 */ { 3, s_4_0, -1, 3, 0}, -/* 1 */ { 3, s_4_1, -1, 3, 0}, -/* 2 */ { 3, s_4_2, -1, 3, 0}, -/* 3 */ { 2, s_4_3, -1, 2, 0}, -/* 4 */ { 2, s_4_4, -1, 1, 0}, -/* 5 */ { 2, s_4_5, -1, 4, 0}, -/* 6 */ { 2, s_4_6, -1, 6, 0}, -/* 7 */ { 3, s_4_7, -1, 5, 0}, -/* 8 */ { 4, s_4_8, -1, 3, 0} +{ 3, s_4_0, -1, 3, 0}, +{ 3, s_4_1, -1, 3, 0}, +{ 3, s_4_2, -1, 3, 0}, +{ 2, s_4_3, -1, 2, 0}, +{ 2, s_4_4, -1, 1, 0}, +{ 2, s_4_5, -1, 4, 0}, +{ 2, s_4_6, -1, 6, 0}, +{ 3, s_4_7, -1, 5, 0}, +{ 4, s_4_8, -1, 3, 0} }; static const symbol s_5_0[2] = { 'a', 'a' }; @@ -133,13 +133,13 @@ static const symbol s_5_6[4] = { 0xC3, 0xB6, 0xC3, 0xB6 }; static const struct among a_5[7] = { -/* 0 */ { 2, s_5_0, -1, -1, 0}, -/* 1 */ { 2, s_5_1, -1, -1, 0}, -/* 2 */ { 2, s_5_2, -1, -1, 0}, -/* 3 */ { 2, s_5_3, -1, -1, 0}, -/* 4 */ { 2, s_5_4, -1, -1, 0}, -/* 5 */ { 4, s_5_5, -1, -1, 0}, -/* 6 */ { 4, s_5_6, -1, -1, 0} +{ 2, s_5_0, -1, -1, 0}, +{ 2, s_5_1, -1, -1, 0}, +{ 2, s_5_2, -1, -1, 0}, +{ 2, s_5_3, -1, -1, 0}, +{ 2, s_5_4, -1, -1, 0}, +{ 4, s_5_5, -1, -1, 0}, +{ 4, s_5_6, -1, -1, 0} }; static const symbol s_6_0[1] = { 'a' }; @@ -175,36 +175,36 @@ static const symbol s_6_29[4] = { 't', 't', 0xC3, 0xA4 }; static const struct among a_6[30] = { -/* 0 */ { 1, s_6_0, -1, 8, 0}, -/* 1 */ { 3, s_6_1, 0, -1, 0}, -/* 2 */ { 2, s_6_2, 0, -1, 0}, -/* 3 */ { 3, s_6_3, 0, -1, 0}, -/* 4 */ { 2, s_6_4, 0, -1, 0}, -/* 5 */ { 3, s_6_5, 4, -1, 0}, -/* 6 */ { 3, s_6_6, 4, -1, 0}, -/* 7 */ { 3, s_6_7, 4, 2, 0}, -/* 8 */ { 3, s_6_8, -1, -1, 0}, -/* 9 */ { 3, s_6_9, -1, -1, 0}, -/* 10 */ { 3, s_6_10, -1, -1, 0}, -/* 11 */ { 1, s_6_11, -1, 7, 0}, -/* 12 */ { 3, s_6_12, 11, 1, 0}, -/* 13 */ { 3, s_6_13, 11, -1, r_VI}, -/* 14 */ { 4, s_6_14, 11, -1, r_LONG}, -/* 15 */ { 3, s_6_15, 11, 2, 0}, -/* 16 */ { 4, s_6_16, 11, -1, r_VI}, -/* 17 */ { 3, s_6_17, 11, 3, 0}, -/* 18 */ { 4, s_6_18, 11, -1, r_VI}, -/* 19 */ { 3, s_6_19, 11, 4, 0}, -/* 20 */ { 4, s_6_20, 11, 5, 0}, -/* 21 */ { 4, s_6_21, 11, 6, 0}, -/* 22 */ { 2, s_6_22, -1, 8, 0}, -/* 23 */ { 4, s_6_23, 22, -1, 0}, -/* 24 */ { 3, s_6_24, 22, -1, 0}, -/* 25 */ { 4, s_6_25, 22, -1, 0}, -/* 26 */ { 3, s_6_26, 22, -1, 0}, -/* 27 */ { 4, s_6_27, 26, -1, 0}, -/* 28 */ { 4, s_6_28, 26, -1, 0}, -/* 29 */ { 4, s_6_29, 26, 2, 0} +{ 1, s_6_0, -1, 8, 0}, +{ 3, s_6_1, 0, -1, 0}, +{ 2, s_6_2, 0, -1, 0}, +{ 3, s_6_3, 0, -1, 0}, +{ 2, s_6_4, 0, -1, 0}, +{ 3, s_6_5, 4, -1, 0}, +{ 3, s_6_6, 4, -1, 0}, +{ 3, s_6_7, 4, 2, 0}, +{ 3, s_6_8, -1, -1, 0}, +{ 3, s_6_9, -1, -1, 0}, +{ 3, s_6_10, -1, -1, 0}, +{ 1, s_6_11, -1, 7, 0}, +{ 3, s_6_12, 11, 1, 0}, +{ 3, s_6_13, 11, -1, r_VI}, +{ 4, s_6_14, 11, -1, r_LONG}, +{ 3, s_6_15, 11, 2, 0}, +{ 4, s_6_16, 11, -1, r_VI}, +{ 3, s_6_17, 11, 3, 0}, +{ 4, s_6_18, 11, -1, r_VI}, +{ 3, s_6_19, 11, 4, 0}, +{ 4, s_6_20, 11, 5, 0}, +{ 4, s_6_21, 11, 6, 0}, +{ 2, s_6_22, -1, 8, 0}, +{ 4, s_6_23, 22, -1, 0}, +{ 3, s_6_24, 22, -1, 0}, +{ 4, s_6_25, 22, -1, 0}, +{ 3, s_6_26, 22, -1, 0}, +{ 4, s_6_27, 26, -1, 0}, +{ 4, s_6_28, 26, -1, 0}, +{ 4, s_6_29, 26, 2, 0} }; static const symbol s_7_0[3] = { 'e', 'j', 'a' }; @@ -224,20 +224,20 @@ static const symbol s_7_13[5] = { 'i', 'm', 'p', 0xC3, 0xA4 }; static const struct among a_7[14] = { -/* 0 */ { 3, s_7_0, -1, -1, 0}, -/* 1 */ { 3, s_7_1, -1, 1, 0}, -/* 2 */ { 4, s_7_2, 1, -1, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 4, s_7_4, 3, -1, 0}, -/* 5 */ { 3, s_7_5, -1, 1, 0}, -/* 6 */ { 4, s_7_6, 5, -1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 4, s_7_8, 7, -1, 0}, -/* 9 */ { 4, s_7_9, -1, -1, 0}, -/* 10 */ { 4, s_7_10, -1, 1, 0}, -/* 11 */ { 5, s_7_11, 10, -1, 0}, -/* 12 */ { 4, s_7_12, -1, 1, 0}, -/* 13 */ { 5, s_7_13, 12, -1, 0} +{ 3, s_7_0, -1, -1, 0}, +{ 3, s_7_1, -1, 1, 0}, +{ 4, s_7_2, 1, -1, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 4, s_7_4, 3, -1, 0}, +{ 3, s_7_5, -1, 1, 0}, +{ 4, s_7_6, 5, -1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 4, s_7_8, 7, -1, 0}, +{ 4, s_7_9, -1, -1, 0}, +{ 4, s_7_10, -1, 1, 0}, +{ 5, s_7_11, 10, -1, 0}, +{ 4, s_7_12, -1, 1, 0}, +{ 5, s_7_13, 12, -1, 0} }; static const symbol s_8_0[1] = { 'i' }; @@ -245,8 +245,8 @@ static const symbol s_8_1[1] = { 'j' }; static const struct among a_8[2] = { -/* 0 */ { 1, s_8_0, -1, -1, 0}, -/* 1 */ { 1, s_8_1, -1, -1, 0} +{ 1, s_8_0, -1, -1, 0}, +{ 1, s_8_1, -1, -1, 0} }; static const symbol s_9_0[3] = { 'm', 'm', 'a' }; @@ -254,8 +254,8 @@ static const symbol s_9_1[4] = { 'i', 'm', 'm', 'a' }; static const struct among a_9[2] = { -/* 0 */ { 3, s_9_0, -1, 1, 0}, -/* 1 */ { 4, s_9_1, 0, -1, 0} +{ 3, s_9_0, -1, 1, 0}, +{ 4, s_9_1, 0, -1, 0} }; static const unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; @@ -276,118 +276,118 @@ static const symbol s_4[] = { 'i', 'e' }; static const symbol s_5[] = { 'p', 'o' }; static const symbol s_6[] = { 'p', 'o' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 44 */ - z->I[1] = z->l; /* $p2 = , line 45 */ - if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */ - { /* gopast */ /* non V1, line 47 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; + { int ret = in_grouping_U(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 47 */ - if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 48 */ - { /* gopast */ /* non V1, line 48 */ + z->I[1] = z->c; + if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; + { int ret = in_grouping_U(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 48 */ + z->I[0] = z->c; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 53 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_particle_etc(struct SN_env * z) { /* backwardmode */ +static int r_particle_etc(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 56 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 56 */ - among_var = find_among_b(z, a_0, 10); /* substring, line 56 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + among_var = find_among_b(z, a_0, 10); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 56 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 57 */ + switch (among_var) { case 1: - if (in_grouping_b_U(z, g_particle_end, 97, 246, 0)) return 0; /* grouping particle_end, line 63 */ + if (in_grouping_b_U(z, g_particle_end, 97, 246, 0)) return 0; break; case 2: - { int ret = r_R2(z); /* call R2, line 65 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } break; } - { int ret = slice_del(z); /* delete, line 67 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_possessive(struct SN_env * z) { /* backwardmode */ +static int r_possessive(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 70 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 70 */ - among_var = find_among_b(z, a_4, 9); /* substring, line 70 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + among_var = find_among_b(z, a_4, 9); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 70 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 71 */ + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 73 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'k') goto lab0; /* literal, line 73 */ + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'k') goto lab0; z->c--; return 0; lab0: z->c = z->l - m2; } - { int ret = slice_del(z); /* delete, line 73 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 75 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 75 */ - if (!(eq_s_b(z, 3, s_0))) return 0; /* literal, line 75 */ - z->bra = z->c; /* ], line 75 */ - { int ret = slice_from_s(z, 3, s_1); /* <-, line 75 */ + z->ket = z->c; + if (!(eq_s_b(z, 3, s_0))) return 0; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 79 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 4: - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; /* among, line 82 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; if (!(find_among_b(z, a_1, 6))) return 0; - { int ret = slice_del(z); /* delete, line 82 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 5: - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 164) return 0; /* among, line 84 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 164) return 0; if (!(find_among_b(z, a_2, 6))) return 0; - { int ret = slice_del(z); /* delete, line 85 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 6: - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; /* among, line 87 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; if (!(find_among_b(z, a_3, 2))) return 0; - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -395,246 +395,246 @@ static int r_possessive(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_LONG(struct SN_env * z) { /* backwardmode */ - if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 92 */ +static int r_LONG(struct SN_env * z) { + if (!(find_among_b(z, a_5, 7))) return 0; return 1; } -static int r_VI(struct SN_env * z) { /* backwardmode */ - if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 94 */ +static int r_VI(struct SN_env * z) { + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; z->c--; - if (in_grouping_b_U(z, g_V2, 97, 246, 0)) return 0; /* grouping V2, line 94 */ + if (in_grouping_b_U(z, g_V2, 97, 246, 0)) return 0; return 1; } -static int r_case_ending(struct SN_env * z) { /* backwardmode */ +static int r_case_ending(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 97 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 97 */ - among_var = find_among_b(z, a_6, 30); /* substring, line 97 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + among_var = find_among_b(z, a_6, 30); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 97 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 98 */ + switch (among_var) { case 1: - if (z->c <= z->lb || z->p[z->c - 1] != 'a') return 0; /* literal, line 99 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'a') return 0; z->c--; break; case 2: - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 100 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; break; case 3: - if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 101 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; z->c--; break; case 4: - if (z->c <= z->lb || z->p[z->c - 1] != 'o') return 0; /* literal, line 102 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') return 0; z->c--; break; case 5: - if (!(eq_s_b(z, 2, s_2))) return 0; /* literal, line 103 */ + if (!(eq_s_b(z, 2, s_2))) return 0; break; case 6: - if (!(eq_s_b(z, 2, s_3))) return 0; /* literal, line 104 */ + if (!(eq_s_b(z, 2, s_3))) return 0; break; case 7: - { int m2 = z->l - z->c; (void)m2; /* try, line 112 */ - { int m3 = z->l - z->c; (void)m3; /* and, line 114 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 113 */ - { int ret = r_LONG(z); /* call LONG, line 112 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int ret = r_LONG(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m4; - if (!(eq_s_b(z, 2, s_4))) { z->c = z->l - m2; goto lab0; } /* literal, line 113 */ + if (!(eq_s_b(z, 2, s_4))) { z->c = z->l - m2; goto lab0; } } lab1: z->c = z->l - m3; - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) { z->c = z->l - m2; goto lab0; } - z->c = ret; /* next, line 114 */ + z->c = ret; } } - z->bra = z->c; /* ], line 114 */ + z->bra = z->c; lab0: ; } break; case 8: - if (in_grouping_b_U(z, g_V1, 97, 246, 0)) return 0; /* grouping V1, line 120 */ - if (in_grouping_b_U(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 120 */ + if (in_grouping_b_U(z, g_V1, 97, 246, 0)) return 0; + if (in_grouping_b_U(z, g_C, 98, 122, 0)) return 0; break; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set ending_removed, line 140 */ + z->I[2] = 1; return 1; } -static int r_other_endings(struct SN_env * z) { /* backwardmode */ +static int r_other_endings(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 143 */ - if (z->c < z->I[1]) return 0; - mlimit1 = z->lb; z->lb = z->I[1]; - z->ket = z->c; /* [, line 143 */ - among_var = find_among_b(z, a_7, 14); /* substring, line 143 */ + { int mlimit1; + if (z->c < z->I[0]) return 0; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; + among_var = find_among_b(z, a_7, 14); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 143 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 144 */ + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 147 */ - if (!(eq_s_b(z, 2, s_5))) goto lab0; /* literal, line 147 */ + { int m2 = z->l - z->c; (void)m2; + if (!(eq_s_b(z, 2, s_5))) goto lab0; return 0; lab0: z->c = z->l - m2; } break; } - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_i_plural(struct SN_env * z) { /* backwardmode */ +static int r_i_plural(struct SN_env * z) { - { int mlimit1; /* setlimit, line 155 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 155 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit1; return 0; } /* substring, line 155 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 155 */ + z->bra = z->c; z->lb = mlimit1; } - { int ret = slice_del(z); /* delete, line 159 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_t_plural(struct SN_env * z) { /* backwardmode */ +static int r_t_plural(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 162 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 163 */ - if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit1; return 0; } /* literal, line 163 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit1; return 0; } z->c--; - z->bra = z->c; /* ], line 163 */ - { int m_test2 = z->l - z->c; /* test, line 163 */ - if (in_grouping_b_U(z, g_V1, 97, 246, 0)) { z->lb = mlimit1; return 0; } /* grouping V1, line 163 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + if (in_grouping_b_U(z, g_V1, 97, 246, 0)) { z->lb = mlimit1; return 0; } z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 164 */ + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; } - { int mlimit3; /* setlimit, line 166 */ - if (z->c < z->I[1]) return 0; - mlimit3 = z->lb; z->lb = z->I[1]; - z->ket = z->c; /* [, line 166 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit3; return 0; } /* substring, line 166 */ + { int mlimit3; + if (z->c < z->I[0]) return 0; + mlimit3 = z->lb; z->lb = z->I[0]; + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit3; return 0; } among_var = find_among_b(z, a_9, 2); if (!(among_var)) { z->lb = mlimit3; return 0; } - z->bra = z->c; /* ], line 166 */ + z->bra = z->c; z->lb = mlimit3; } - switch (among_var) { /* among, line 167 */ + switch (among_var) { case 1: - { int m4 = z->l - z->c; (void)m4; /* not, line 168 */ - if (!(eq_s_b(z, 2, s_6))) goto lab0; /* literal, line 168 */ + { int m4 = z->l - z->c; (void)m4; + if (!(eq_s_b(z, 2, s_6))) goto lab0; return 0; lab0: z->c = z->l - m4; } break; } - { int ret = slice_del(z); /* delete, line 171 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_tidy(struct SN_env * z) { /* backwardmode */ +static int r_tidy(struct SN_env * z) { - { int mlimit1; /* setlimit, line 174 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - { int m2 = z->l - z->c; (void)m2; /* do, line 175 */ - { int m3 = z->l - z->c; (void)m3; /* and, line 175 */ - { int ret = r_LONG(z); /* call LONG, line 175 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_LONG(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } z->c = z->l - m3; - z->ket = z->c; /* [, line 175 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 175 */ + z->c = ret; } - z->bra = z->c; /* ], line 175 */ - { int ret = slice_del(z); /* delete, line 175 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } } lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 176 */ - z->ket = z->c; /* [, line 176 */ - if (in_grouping_b_U(z, g_AEI, 97, 228, 0)) goto lab1; /* grouping AEI, line 176 */ - z->bra = z->c; /* ], line 176 */ - if (in_grouping_b_U(z, g_C, 98, 122, 0)) goto lab1; /* grouping C, line 176 */ - { int ret = slice_del(z); /* delete, line 176 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (in_grouping_b_U(z, g_AEI, 97, 228, 0)) goto lab1; + z->bra = z->c; + if (in_grouping_b_U(z, g_C, 98, 122, 0)) goto lab1; + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 177 */ - z->ket = z->c; /* [, line 177 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab2; /* literal, line 177 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab2; z->c--; - z->bra = z->c; /* ], line 177 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 177 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab4; /* literal, line 177 */ + z->bra = z->c; + { int m6 = z->l - z->c; (void)m6; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab4; z->c--; goto lab3; lab4: z->c = z->l - m6; - if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab2; /* literal, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab2; z->c--; } lab3: - { int ret = slice_del(z); /* delete, line 177 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: z->c = z->l - m5; } - { int m7 = z->l - z->c; (void)m7; /* do, line 178 */ - z->ket = z->c; /* [, line 178 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; /* literal, line 178 */ + { int m7 = z->l - z->c; (void)m7; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; z->c--; - z->bra = z->c; /* ], line 178 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab5; /* literal, line 178 */ + z->bra = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab5; z->c--; - { int ret = slice_del(z); /* delete, line 178 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab5: @@ -642,72 +642,72 @@ static int r_tidy(struct SN_env * z) { /* backwardmode */ } z->lb = mlimit1; } - if (in_grouping_b_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 180 */ - z->ket = z->c; /* [, line 180 */ - if (in_grouping_b_U(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 180 */ - z->bra = z->c; /* ], line 180 */ - z->S[0] = slice_to(z, z->S[0]); /* -> x, line 180 */ - if (z->S[0] == 0) return -1; /* -> x, line 180 */ - if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 180 */ - { int ret = slice_del(z); /* delete, line 180 */ + if (in_grouping_b_U(z, g_V1, 97, 246, 1) < 0) return 0; + z->ket = z->c; + if (in_grouping_b_U(z, g_C, 98, 122, 0)) return 0; + z->bra = z->c; + z->S[0] = slice_to(z, z->S[0]); + if (z->S[0] == 0) return -1; + if (!(eq_v_b(z, z->S[0]))) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int finnish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 186 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 186 */ +extern int finnish_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->B[0] = 0; /* unset ending_removed, line 187 */ - z->lb = z->c; z->c = z->l; /* backwards, line 188 */ + z->I[2] = 0; + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 189 */ - { int ret = r_particle_etc(z); /* call particle_etc, line 189 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_particle_etc(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 190 */ - { int ret = r_possessive(z); /* call possessive, line 190 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_possessive(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 191 */ - { int ret = r_case_ending(z); /* call case_ending, line 191 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_case_ending(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 192 */ - { int ret = r_other_endings(z); /* call other_endings, line 192 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_other_endings(z); if (ret < 0) return ret; } z->c = z->l - m5; } - /* or, line 193 */ - if (!(z->B[0])) goto lab1; /* Boolean test ending_removed, line 193 */ - { int m6 = z->l - z->c; (void)m6; /* do, line 193 */ - { int ret = r_i_plural(z); /* call i_plural, line 193 */ + + if (!(z->I[2])) goto lab1; + { int m6 = z->l - z->c; (void)m6; + { int ret = r_i_plural(z); if (ret < 0) return ret; } z->c = z->l - m6; } goto lab0; lab1: - { int m7 = z->l - z->c; (void)m7; /* do, line 193 */ - { int ret = r_t_plural(z); /* call t_plural, line 193 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_t_plural(z); if (ret < 0) return ret; } z->c = z->l - m7; } lab0: - { int m8 = z->l - z->c; (void)m8; /* do, line 194 */ - { int ret = r_tidy(z); /* call tidy, line 194 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_tidy(z); if (ret < 0) return ret; } z->c = z->l - m8; @@ -716,7 +716,7 @@ extern int finnish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * finnish_UTF_8_create_env(void) { return SN_create_env(1, 2, 1); } +extern struct SN_env * finnish_UTF_8_create_env(void) { return SN_create_env(1, 3); } extern void finnish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 1); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_french.c b/src/backend/snowball/libstemmer/stem_UTF_8_french.c index fa4a1c8f3057..6d12e99a8cb5 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_french.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_french.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -39,9 +39,9 @@ static const symbol s_0_2[3] = { 't', 'a', 'p' }; static const struct among a_0[3] = { -/* 0 */ { 3, s_0_0, -1, -1, 0}, -/* 1 */ { 3, s_0_1, -1, -1, 0}, -/* 2 */ { 3, s_0_2, -1, -1, 0} +{ 3, s_0_0, -1, -1, 0}, +{ 3, s_0_1, -1, -1, 0}, +{ 3, s_0_2, -1, -1, 0} }; static const symbol s_1_1[1] = { 'H' }; @@ -53,13 +53,13 @@ static const symbol s_1_6[1] = { 'Y' }; static const struct among a_1[7] = { -/* 0 */ { 0, 0, -1, 7, 0}, -/* 1 */ { 1, s_1_1, 0, 6, 0}, -/* 2 */ { 2, s_1_2, 1, 4, 0}, -/* 3 */ { 2, s_1_3, 1, 5, 0}, -/* 4 */ { 1, s_1_4, 0, 1, 0}, -/* 5 */ { 1, s_1_5, 0, 2, 0}, -/* 6 */ { 1, s_1_6, 0, 3, 0} +{ 0, 0, -1, 7, 0}, +{ 1, s_1_1, 0, 6, 0}, +{ 2, s_1_2, 1, 4, 0}, +{ 2, s_1_3, 1, 5, 0}, +{ 1, s_1_4, 0, 1, 0}, +{ 1, s_1_5, 0, 2, 0}, +{ 1, s_1_6, 0, 3, 0} }; static const symbol s_2_0[3] = { 'i', 'q', 'U' }; @@ -71,12 +71,12 @@ static const symbol s_2_5[2] = { 'i', 'v' }; static const struct among a_2[6] = { -/* 0 */ { 3, s_2_0, -1, 3, 0}, -/* 1 */ { 3, s_2_1, -1, 3, 0}, -/* 2 */ { 4, s_2_2, -1, 4, 0}, -/* 3 */ { 4, s_2_3, -1, 4, 0}, -/* 4 */ { 3, s_2_4, -1, 2, 0}, -/* 5 */ { 2, s_2_5, -1, 1, 0} +{ 3, s_2_0, -1, 3, 0}, +{ 3, s_2_1, -1, 3, 0}, +{ 4, s_2_2, -1, 4, 0}, +{ 4, s_2_3, -1, 4, 0}, +{ 3, s_2_4, -1, 2, 0}, +{ 2, s_2_5, -1, 1, 0} }; static const symbol s_3_0[2] = { 'i', 'c' }; @@ -85,9 +85,9 @@ static const symbol s_3_2[2] = { 'i', 'v' }; static const struct among a_3[3] = { -/* 0 */ { 2, s_3_0, -1, 2, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 2, s_3_2, -1, 3, 0} +{ 2, s_3_0, -1, 2, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 2, s_3_2, -1, 3, 0} }; static const symbol s_4_0[4] = { 'i', 'q', 'U', 'e' }; @@ -136,49 +136,49 @@ static const symbol s_4_42[4] = { 'i', 't', 0xC3, 0xA9 }; static const struct among a_4[43] = { -/* 0 */ { 4, s_4_0, -1, 1, 0}, -/* 1 */ { 6, s_4_1, -1, 2, 0}, -/* 2 */ { 4, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 5, 0}, -/* 4 */ { 5, s_4_4, -1, 3, 0}, -/* 5 */ { 4, s_4_5, -1, 1, 0}, -/* 6 */ { 4, s_4_6, -1, 1, 0}, -/* 7 */ { 4, s_4_7, -1, 11, 0}, -/* 8 */ { 4, s_4_8, -1, 1, 0}, -/* 9 */ { 3, s_4_9, -1, 8, 0}, -/* 10 */ { 2, s_4_10, -1, 8, 0}, -/* 11 */ { 5, s_4_11, -1, 4, 0}, -/* 12 */ { 5, s_4_12, -1, 2, 0}, -/* 13 */ { 5, s_4_13, -1, 4, 0}, -/* 14 */ { 5, s_4_14, -1, 2, 0}, -/* 15 */ { 5, s_4_15, -1, 1, 0}, -/* 16 */ { 7, s_4_16, -1, 2, 0}, -/* 17 */ { 5, s_4_17, -1, 1, 0}, -/* 18 */ { 5, s_4_18, -1, 5, 0}, -/* 19 */ { 6, s_4_19, -1, 3, 0}, -/* 20 */ { 5, s_4_20, -1, 1, 0}, -/* 21 */ { 5, s_4_21, -1, 1, 0}, -/* 22 */ { 5, s_4_22, -1, 11, 0}, -/* 23 */ { 5, s_4_23, -1, 1, 0}, -/* 24 */ { 4, s_4_24, -1, 8, 0}, -/* 25 */ { 3, s_4_25, -1, 8, 0}, -/* 26 */ { 6, s_4_26, -1, 4, 0}, -/* 27 */ { 6, s_4_27, -1, 2, 0}, -/* 28 */ { 6, s_4_28, -1, 4, 0}, -/* 29 */ { 6, s_4_29, -1, 2, 0}, -/* 30 */ { 5, s_4_30, -1, 15, 0}, -/* 31 */ { 6, s_4_31, 30, 6, 0}, -/* 32 */ { 9, s_4_32, 31, 12, 0}, -/* 33 */ { 5, s_4_33, -1, 7, 0}, -/* 34 */ { 4, s_4_34, -1, 15, 0}, -/* 35 */ { 5, s_4_35, 34, 6, 0}, -/* 36 */ { 8, s_4_36, 35, 12, 0}, -/* 37 */ { 6, s_4_37, 34, 13, 0}, -/* 38 */ { 6, s_4_38, 34, 14, 0}, -/* 39 */ { 3, s_4_39, -1, 10, 0}, -/* 40 */ { 4, s_4_40, 39, 9, 0}, -/* 41 */ { 3, s_4_41, -1, 1, 0}, -/* 42 */ { 4, s_4_42, -1, 7, 0} +{ 4, s_4_0, -1, 1, 0}, +{ 6, s_4_1, -1, 2, 0}, +{ 4, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 5, 0}, +{ 5, s_4_4, -1, 3, 0}, +{ 4, s_4_5, -1, 1, 0}, +{ 4, s_4_6, -1, 1, 0}, +{ 4, s_4_7, -1, 11, 0}, +{ 4, s_4_8, -1, 1, 0}, +{ 3, s_4_9, -1, 8, 0}, +{ 2, s_4_10, -1, 8, 0}, +{ 5, s_4_11, -1, 4, 0}, +{ 5, s_4_12, -1, 2, 0}, +{ 5, s_4_13, -1, 4, 0}, +{ 5, s_4_14, -1, 2, 0}, +{ 5, s_4_15, -1, 1, 0}, +{ 7, s_4_16, -1, 2, 0}, +{ 5, s_4_17, -1, 1, 0}, +{ 5, s_4_18, -1, 5, 0}, +{ 6, s_4_19, -1, 3, 0}, +{ 5, s_4_20, -1, 1, 0}, +{ 5, s_4_21, -1, 1, 0}, +{ 5, s_4_22, -1, 11, 0}, +{ 5, s_4_23, -1, 1, 0}, +{ 4, s_4_24, -1, 8, 0}, +{ 3, s_4_25, -1, 8, 0}, +{ 6, s_4_26, -1, 4, 0}, +{ 6, s_4_27, -1, 2, 0}, +{ 6, s_4_28, -1, 4, 0}, +{ 6, s_4_29, -1, 2, 0}, +{ 5, s_4_30, -1, 15, 0}, +{ 6, s_4_31, 30, 6, 0}, +{ 9, s_4_32, 31, 12, 0}, +{ 5, s_4_33, -1, 7, 0}, +{ 4, s_4_34, -1, 15, 0}, +{ 5, s_4_35, 34, 6, 0}, +{ 8, s_4_36, 35, 12, 0}, +{ 6, s_4_37, 34, 13, 0}, +{ 6, s_4_38, 34, 14, 0}, +{ 3, s_4_39, -1, 10, 0}, +{ 4, s_4_40, 39, 9, 0}, +{ 3, s_4_41, -1, 1, 0}, +{ 4, s_4_42, -1, 7, 0} }; static const symbol s_5_0[3] = { 'i', 'r', 'a' }; @@ -219,41 +219,41 @@ static const symbol s_5_34[5] = { 'i', 's', 's', 'e', 'z' }; static const struct among a_5[35] = { -/* 0 */ { 3, s_5_0, -1, 1, 0}, -/* 1 */ { 2, s_5_1, -1, 1, 0}, -/* 2 */ { 4, s_5_2, -1, 1, 0}, -/* 3 */ { 7, s_5_3, -1, 1, 0}, -/* 4 */ { 1, s_5_4, -1, 1, 0}, -/* 5 */ { 4, s_5_5, 4, 1, 0}, -/* 6 */ { 2, s_5_6, -1, 1, 0}, -/* 7 */ { 4, s_5_7, -1, 1, 0}, -/* 8 */ { 3, s_5_8, -1, 1, 0}, -/* 9 */ { 5, s_5_9, -1, 1, 0}, -/* 10 */ { 5, s_5_10, -1, 1, 0}, -/* 11 */ { 8, s_5_11, -1, 1, 0}, -/* 12 */ { 5, s_5_12, -1, 1, 0}, -/* 13 */ { 2, s_5_13, -1, 1, 0}, -/* 14 */ { 5, s_5_14, 13, 1, 0}, -/* 15 */ { 6, s_5_15, 13, 1, 0}, -/* 16 */ { 6, s_5_16, -1, 1, 0}, -/* 17 */ { 7, s_5_17, -1, 1, 0}, -/* 18 */ { 5, s_5_18, -1, 1, 0}, -/* 19 */ { 6, s_5_19, -1, 1, 0}, -/* 20 */ { 7, s_5_20, -1, 1, 0}, -/* 21 */ { 2, s_5_21, -1, 1, 0}, -/* 22 */ { 5, s_5_22, 21, 1, 0}, -/* 23 */ { 6, s_5_23, 21, 1, 0}, -/* 24 */ { 6, s_5_24, -1, 1, 0}, -/* 25 */ { 7, s_5_25, -1, 1, 0}, -/* 26 */ { 8, s_5_26, -1, 1, 0}, -/* 27 */ { 5, s_5_27, -1, 1, 0}, -/* 28 */ { 6, s_5_28, -1, 1, 0}, -/* 29 */ { 5, s_5_29, -1, 1, 0}, -/* 30 */ { 3, s_5_30, -1, 1, 0}, -/* 31 */ { 5, s_5_31, -1, 1, 0}, -/* 32 */ { 6, s_5_32, -1, 1, 0}, -/* 33 */ { 4, s_5_33, -1, 1, 0}, -/* 34 */ { 5, s_5_34, -1, 1, 0} +{ 3, s_5_0, -1, 1, 0}, +{ 2, s_5_1, -1, 1, 0}, +{ 4, s_5_2, -1, 1, 0}, +{ 7, s_5_3, -1, 1, 0}, +{ 1, s_5_4, -1, 1, 0}, +{ 4, s_5_5, 4, 1, 0}, +{ 2, s_5_6, -1, 1, 0}, +{ 4, s_5_7, -1, 1, 0}, +{ 3, s_5_8, -1, 1, 0}, +{ 5, s_5_9, -1, 1, 0}, +{ 5, s_5_10, -1, 1, 0}, +{ 8, s_5_11, -1, 1, 0}, +{ 5, s_5_12, -1, 1, 0}, +{ 2, s_5_13, -1, 1, 0}, +{ 5, s_5_14, 13, 1, 0}, +{ 6, s_5_15, 13, 1, 0}, +{ 6, s_5_16, -1, 1, 0}, +{ 7, s_5_17, -1, 1, 0}, +{ 5, s_5_18, -1, 1, 0}, +{ 6, s_5_19, -1, 1, 0}, +{ 7, s_5_20, -1, 1, 0}, +{ 2, s_5_21, -1, 1, 0}, +{ 5, s_5_22, 21, 1, 0}, +{ 6, s_5_23, 21, 1, 0}, +{ 6, s_5_24, -1, 1, 0}, +{ 7, s_5_25, -1, 1, 0}, +{ 8, s_5_26, -1, 1, 0}, +{ 5, s_5_27, -1, 1, 0}, +{ 6, s_5_28, -1, 1, 0}, +{ 5, s_5_29, -1, 1, 0}, +{ 3, s_5_30, -1, 1, 0}, +{ 5, s_5_31, -1, 1, 0}, +{ 6, s_5_32, -1, 1, 0}, +{ 4, s_5_33, -1, 1, 0}, +{ 5, s_5_34, -1, 1, 0} }; static const symbol s_6_0[1] = { 'a' }; @@ -297,44 +297,44 @@ static const symbol s_6_37[2] = { 0xC3, 0xA9 }; static const struct among a_6[38] = { -/* 0 */ { 1, s_6_0, -1, 3, 0}, -/* 1 */ { 3, s_6_1, 0, 2, 0}, -/* 2 */ { 4, s_6_2, -1, 3, 0}, -/* 3 */ { 4, s_6_3, -1, 3, 0}, -/* 4 */ { 3, s_6_4, -1, 2, 0}, -/* 5 */ { 2, s_6_5, -1, 3, 0}, -/* 6 */ { 4, s_6_6, 5, 2, 0}, -/* 7 */ { 2, s_6_7, -1, 2, 0}, -/* 8 */ { 2, s_6_8, -1, 3, 0}, -/* 9 */ { 4, s_6_9, 8, 2, 0}, -/* 10 */ { 5, s_6_10, -1, 3, 0}, -/* 11 */ { 5, s_6_11, -1, 3, 0}, -/* 12 */ { 5, s_6_12, -1, 3, 0}, -/* 13 */ { 5, s_6_13, -1, 3, 0}, -/* 14 */ { 4, s_6_14, -1, 2, 0}, -/* 15 */ { 3, s_6_15, -1, 3, 0}, -/* 16 */ { 5, s_6_16, 15, 2, 0}, -/* 17 */ { 4, s_6_17, -1, 1, 0}, -/* 18 */ { 6, s_6_18, 17, 2, 0}, -/* 19 */ { 7, s_6_19, 17, 3, 0}, -/* 20 */ { 5, s_6_20, -1, 2, 0}, -/* 21 */ { 4, s_6_21, -1, 3, 0}, -/* 22 */ { 3, s_6_22, -1, 2, 0}, -/* 23 */ { 3, s_6_23, -1, 3, 0}, -/* 24 */ { 5, s_6_24, 23, 2, 0}, -/* 25 */ { 3, s_6_25, -1, 3, 0}, -/* 26 */ { 5, s_6_26, -1, 3, 0}, -/* 27 */ { 7, s_6_27, 26, 2, 0}, -/* 28 */ { 6, s_6_28, -1, 2, 0}, -/* 29 */ { 6, s_6_29, -1, 3, 0}, -/* 30 */ { 5, s_6_30, -1, 2, 0}, -/* 31 */ { 3, s_6_31, -1, 3, 0}, -/* 32 */ { 2, s_6_32, -1, 2, 0}, -/* 33 */ { 3, s_6_33, 32, 2, 0}, -/* 34 */ { 5, s_6_34, 33, 2, 0}, -/* 35 */ { 6, s_6_35, 33, 3, 0}, -/* 36 */ { 4, s_6_36, 32, 2, 0}, -/* 37 */ { 2, s_6_37, -1, 2, 0} +{ 1, s_6_0, -1, 3, 0}, +{ 3, s_6_1, 0, 2, 0}, +{ 4, s_6_2, -1, 3, 0}, +{ 4, s_6_3, -1, 3, 0}, +{ 3, s_6_4, -1, 2, 0}, +{ 2, s_6_5, -1, 3, 0}, +{ 4, s_6_6, 5, 2, 0}, +{ 2, s_6_7, -1, 2, 0}, +{ 2, s_6_8, -1, 3, 0}, +{ 4, s_6_9, 8, 2, 0}, +{ 5, s_6_10, -1, 3, 0}, +{ 5, s_6_11, -1, 3, 0}, +{ 5, s_6_12, -1, 3, 0}, +{ 5, s_6_13, -1, 3, 0}, +{ 4, s_6_14, -1, 2, 0}, +{ 3, s_6_15, -1, 3, 0}, +{ 5, s_6_16, 15, 2, 0}, +{ 4, s_6_17, -1, 1, 0}, +{ 6, s_6_18, 17, 2, 0}, +{ 7, s_6_19, 17, 3, 0}, +{ 5, s_6_20, -1, 2, 0}, +{ 4, s_6_21, -1, 3, 0}, +{ 3, s_6_22, -1, 2, 0}, +{ 3, s_6_23, -1, 3, 0}, +{ 5, s_6_24, 23, 2, 0}, +{ 3, s_6_25, -1, 3, 0}, +{ 5, s_6_26, -1, 3, 0}, +{ 7, s_6_27, 26, 2, 0}, +{ 6, s_6_28, -1, 2, 0}, +{ 6, s_6_29, -1, 3, 0}, +{ 5, s_6_30, -1, 2, 0}, +{ 3, s_6_31, -1, 3, 0}, +{ 2, s_6_32, -1, 2, 0}, +{ 3, s_6_33, 32, 2, 0}, +{ 5, s_6_34, 33, 2, 0}, +{ 6, s_6_35, 33, 3, 0}, +{ 4, s_6_36, 32, 2, 0}, +{ 2, s_6_37, -1, 2, 0} }; static const symbol s_7_0[1] = { 'e' }; @@ -346,12 +346,12 @@ static const symbol s_7_5[3] = { 'i', 'e', 'r' }; static const struct among a_7[6] = { -/* 0 */ { 1, s_7_0, -1, 3, 0}, -/* 1 */ { 5, s_7_1, 0, 2, 0}, -/* 2 */ { 5, s_7_2, 0, 2, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 3, s_7_4, -1, 2, 0}, -/* 5 */ { 3, s_7_5, -1, 2, 0} +{ 1, s_7_0, -1, 3, 0}, +{ 5, s_7_1, 0, 2, 0}, +{ 5, s_7_2, 0, 2, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 3, s_7_4, -1, 2, 0}, +{ 3, s_7_5, -1, 2, 0} }; static const symbol s_8_0[3] = { 'e', 'l', 'l' }; @@ -362,11 +362,11 @@ static const symbol s_8_4[3] = { 'e', 't', 't' }; static const struct among a_8[5] = { -/* 0 */ { 3, s_8_0, -1, -1, 0}, -/* 1 */ { 4, s_8_1, -1, -1, 0}, -/* 2 */ { 3, s_8_2, -1, -1, 0}, -/* 3 */ { 3, s_8_3, -1, -1, 0}, -/* 4 */ { 3, s_8_4, -1, -1, 0} +{ 3, s_8_0, -1, -1, 0}, +{ 4, s_8_1, -1, -1, 0}, +{ 3, s_8_2, -1, -1, 0}, +{ 3, s_8_3, -1, -1, 0}, +{ 3, s_8_4, -1, -1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 130, 103, 8, 5 }; @@ -414,40 +414,39 @@ static const symbol s_37[] = { 'i' }; static const symbol s_38[] = { 0xC3, 0xA7 }; static const symbol s_39[] = { 'c' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ -/* repeat, line 38 */ - - while(1) { int c1 = z->c; - while(1) { /* goto, line 38 */ +static int r_prelude(struct SN_env * z) { + while(1) { + int c1 = z->c; + while(1) { int c2 = z->c; - { int c3 = z->c; /* or, line 44 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab3; /* grouping v, line 40 */ - z->bra = z->c; /* [, line 40 */ - { int c4 = z->c; /* or, line 40 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab5; /* literal, line 40 */ + { int c3 = z->c; + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab3; + z->bra = z->c; + { int c4 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab5; z->c++; - z->ket = z->c; /* ], line 40 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab5; /* grouping v, line 40 */ - { int ret = slice_from_s(z, 1, s_0); /* <-, line 40 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab5; + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } goto lab4; lab5: z->c = c4; - if (z->c == z->l || z->p[z->c] != 'i') goto lab6; /* literal, line 41 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab6; z->c++; - z->ket = z->c; /* ], line 41 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab6; /* grouping v, line 41 */ - { int ret = slice_from_s(z, 1, s_1); /* <-, line 41 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab6; + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } goto lab4; lab6: z->c = c4; - if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 42 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; z->c++; - z->ket = z->c; /* ], line 42 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 42 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } } @@ -455,42 +454,42 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ goto lab2; lab3: z->c = c3; - z->bra = z->c; /* [, line 45 */ - if (!(eq_s(z, 2, s_3))) goto lab7; /* literal, line 45 */ - z->ket = z->c; /* ], line 45 */ - { int ret = slice_from_s(z, 2, s_4); /* <-, line 45 */ + z->bra = z->c; + if (!(eq_s(z, 2, s_3))) goto lab7; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_4); if (ret < 0) return ret; } goto lab2; lab7: z->c = c3; - z->bra = z->c; /* [, line 47 */ - if (!(eq_s(z, 2, s_5))) goto lab8; /* literal, line 47 */ - z->ket = z->c; /* ], line 47 */ - { int ret = slice_from_s(z, 2, s_6); /* <-, line 47 */ + z->bra = z->c; + if (!(eq_s(z, 2, s_5))) goto lab8; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_6); if (ret < 0) return ret; } goto lab2; lab8: z->c = c3; - z->bra = z->c; /* [, line 49 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab9; /* literal, line 49 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab9; z->c++; - z->ket = z->c; /* ], line 49 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab9; /* grouping v, line 49 */ - { int ret = slice_from_s(z, 1, s_7); /* <-, line 49 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab9; + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } goto lab2; lab9: z->c = c3; - if (z->c == z->l || z->p[z->c] != 'q') goto lab1; /* literal, line 51 */ + if (z->c == z->l || z->p[z->c] != 'q') goto lab1; z->c++; - z->bra = z->c; /* [, line 51 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab1; /* literal, line 51 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab1; z->c++; - z->ket = z->c; /* ], line 51 */ - { int ret = slice_from_s(z, 1, s_8); /* <-, line 51 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } } @@ -499,9 +498,9 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ break; lab1: z->c = c2; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* goto, line 38 */ + z->c = ret; } } continue; @@ -512,115 +511,114 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 56 */ - z->I[1] = z->l; /* $p1 = , line 57 */ - z->I[2] = z->l; /* $p2 = , line 58 */ - { int c1 = z->c; /* do, line 60 */ - { int c2 = z->c; /* or, line 62 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab2; - z->c = ret; /* next, line 61 */ + z->c = ret; } goto lab1; lab2: z->c = c2; - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; /* among, line 63 */ + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; if (!(find_among(z, a_0, 3))) goto lab3; goto lab1; lab3: z->c = c2; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 70 */ + z->c = ret; } - { /* gopast */ /* grouping v, line 70 */ + { int ret = out_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab0; z->c += ret; } } lab1: - z->I[0] = z->c; /* setmark pV, line 71 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c3 = z->c; /* do, line 73 */ - { /* gopast */ /* grouping v, line 74 */ + { int c3 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 74 */ + { int ret = in_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 74 */ - { /* gopast */ /* grouping v, line 75 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 75 */ + { int ret = in_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 75 */ + z->I[0] = z->c; lab4: z->c = c3; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 79 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 81 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652352 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 7; else /* substring, line 81 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652352 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 7; else among_var = find_among(z, a_1, 7); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 81 */ - switch (among_var) { /* among, line 81 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 82 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 83 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 84 */ + { int ret = slice_from_s(z, 1, s_11); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_12); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_12); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 2, s_13); /* <-, line 86 */ + { int ret = slice_from_s(z, 2, s_13); if (ret < 0) return ret; } break; case 6: - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 7: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 88 */ + z->c = ret; } break; } @@ -632,59 +630,59 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 94 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 95 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 96 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 99 */ - among_var = find_among_b(z, a_4, 43); /* substring, line 99 */ + z->ket = z->c; + among_var = find_among_b(z, a_4, 43); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 99 */ - switch (among_var) { /* among, line 99 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 103 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 103 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 106 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 107 */ - z->ket = z->c; /* [, line 107 */ - if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m1; goto lab0; } /* literal, line 107 */ - z->bra = z->c; /* ], line 107 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 107 */ - { int ret = r_R2(z); /* call R2, line 107 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int m2 = z->l - z->c; (void)m2; + { int ret = r_R2(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 107 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m2; - { int ret = slice_from_s(z, 3, s_15); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_15); if (ret < 0) return ret; } } @@ -694,98 +692,98 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - { int ret = r_R2(z); /* call R2, line 111 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_16); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_16); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 114 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_17); /* <-, line 114 */ + { int ret = slice_from_s(z, 1, s_17); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 117 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_18); /* <-, line 117 */ + { int ret = slice_from_s(z, 3, s_18); if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); /* call RV, line 121 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 121 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 122 */ - z->ket = z->c; /* [, line 123 */ - among_var = find_among_b(z, a_2, 6); /* substring, line 123 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + among_var = find_among_b(z, a_2, 6); if (!(among_var)) { z->c = z->l - m3; goto lab3; } - z->bra = z->c; /* ], line 123 */ - switch (among_var) { /* among, line 123 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 124 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 124 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 124 */ - if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m3; goto lab3; } /* literal, line 124 */ - z->bra = z->c; /* ], line 124 */ - { int ret = r_R2(z); /* call R2, line 124 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m3; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 124 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m4 = z->l - z->c; (void)m4; /* or, line 125 */ - { int ret = r_R2(z); /* call R2, line 125 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_R2(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m4; - { int ret = r_R1(z); /* call R1, line 125 */ + { int ret = r_R1(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 3, s_20); /* <-, line 125 */ + { int ret = slice_from_s(z, 3, s_20); if (ret < 0) return ret; } } lab4: break; case 3: - { int ret = r_R2(z); /* call R2, line 127 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 127 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 4: - { int ret = r_RV(z); /* call RV, line 129 */ + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 1, s_21); /* <-, line 129 */ + { int ret = slice_from_s(z, 1, s_21); if (ret < 0) return ret; } break; @@ -795,61 +793,61 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 7: - { int ret = r_R2(z); /* call R2, line 136 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 136 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* try, line 137 */ - z->ket = z->c; /* [, line 138 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m5; goto lab6; } /* substring, line 138 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m5; goto lab6; } among_var = find_among_b(z, a_3, 3); if (!(among_var)) { z->c = z->l - m5; goto lab6; } - z->bra = z->c; /* ], line 138 */ - switch (among_var) { /* among, line 138 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m6 = z->l - z->c; (void)m6; /* or, line 139 */ - { int ret = r_R2(z); /* call R2, line 139 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_R2(z); if (ret == 0) goto lab8; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m6; - { int ret = slice_from_s(z, 3, s_22); /* <-, line 139 */ + { int ret = slice_from_s(z, 3, s_22); if (ret < 0) return ret; } } lab7: break; case 2: - { int m7 = z->l - z->c; (void)m7; /* or, line 140 */ - { int ret = r_R2(z); /* call R2, line 140 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_R2(z); if (ret == 0) goto lab10; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 140 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab9; lab10: z->c = z->l - m7; - { int ret = slice_from_s(z, 3, s_23); /* <-, line 140 */ + { int ret = slice_from_s(z, 3, s_23); if (ret < 0) return ret; } } lab9: break; case 3: - { int ret = r_R2(z); /* call R2, line 141 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 141 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -859,38 +857,38 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 148 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 148 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m8 = z->l - z->c; (void)m8; /* try, line 149 */ - z->ket = z->c; /* [, line 149 */ - if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ - z->bra = z->c; /* ], line 149 */ - { int ret = r_R2(z); /* call R2, line 149 */ + { int m8 = z->l - z->c; (void)m8; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m8; goto lab11; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m8; goto lab11; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 149 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 149 */ - if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ - z->bra = z->c; /* ], line 149 */ - { int m9 = z->l - z->c; (void)m9; /* or, line 149 */ - { int ret = r_R2(z); /* call R2, line 149 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m8; goto lab11; } + z->bra = z->c; + { int m9 = z->l - z->c; (void)m9; + { int ret = r_R2(z); if (ret == 0) goto lab13; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 149 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab12; lab13: z->c = z->l - m9; - { int ret = slice_from_s(z, 3, s_26); /* <-, line 149 */ + { int ret = slice_from_s(z, 3, s_26); if (ret < 0) return ret; } } @@ -900,101 +898,101 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = slice_from_s(z, 3, s_27); /* <-, line 151 */ + { int ret = slice_from_s(z, 3, s_27); if (ret < 0) return ret; } break; case 10: - { int ret = r_R1(z); /* call R1, line 152 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_28); /* <-, line 152 */ + { int ret = slice_from_s(z, 2, s_28); if (ret < 0) return ret; } break; case 11: - { int m10 = z->l - z->c; (void)m10; /* or, line 154 */ - { int ret = r_R2(z); /* call R2, line 154 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_R2(z); if (ret == 0) goto lab15; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 154 */ + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab14; lab15: z->c = z->l - m10; - { int ret = r_R1(z); /* call R1, line 154 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_29); /* <-, line 154 */ + { int ret = slice_from_s(z, 3, s_29); if (ret < 0) return ret; } } lab14: break; case 12: - { int ret = r_R1(z); /* call R1, line 157 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - if (out_grouping_b_U(z, g_v, 97, 251, 0)) return 0; /* non v, line 157 */ - { int ret = slice_del(z); /* delete, line 157 */ + if (out_grouping_b_U(z, g_v, 97, 251, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 13: - { int ret = r_RV(z); /* call RV, line 162 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_30); /* <-, line 162 */ + { int ret = slice_from_s(z, 3, s_30); if (ret < 0) return ret; } - return 0; /* fail, line 162 */ + return 0; break; case 14: - { int ret = r_RV(z); /* call RV, line 163 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_31); /* <-, line 163 */ + { int ret = slice_from_s(z, 3, s_31); if (ret < 0) return ret; } - return 0; /* fail, line 163 */ + return 0; break; case 15: - { int m_test11 = z->l - z->c; /* test, line 165 */ - if (in_grouping_b_U(z, g_v, 97, 251, 0)) return 0; /* grouping v, line 165 */ - { int ret = r_RV(z); /* call RV, line 165 */ + { int m_test11 = z->l - z->c; + if (in_grouping_b_U(z, g_v, 97, 251, 0)) return 0; + { int ret = r_RV(z); if (ret <= 0) return ret; } z->c = z->l - m_test11; } - { int ret = slice_del(z); /* delete, line 165 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - return 0; /* fail, line 165 */ + return 0; break; } return 1; } -static int r_i_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_i_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 170 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 171 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 171 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_5, 35))) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 171 */ - { int m2 = z->l - z->c; (void)m2; /* not, line 177 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'H') goto lab0; /* literal, line 177 */ + z->bra = z->c; + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'H') goto lab0; z->c--; { z->lb = mlimit1; return 0; } lab0: z->c = z->l - m2; } - if (out_grouping_b_U(z, g_v, 97, 251, 0)) { z->lb = mlimit1; return 0; } /* non v, line 177 */ - { int ret = slice_del(z); /* delete, line 177 */ + if (out_grouping_b_U(z, g_v, 97, 251, 0)) { z->lb = mlimit1; return 0; } + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; @@ -1002,41 +1000,41 @@ static int r_i_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 181 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 182 */ - among_var = find_among_b(z, a_6, 38); /* substring, line 182 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + among_var = find_among_b(z, a_6, 38); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 182 */ - switch (among_var) { /* among, line 182 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 184 */ + { int ret = r_R2(z); if (ret == 0) { z->lb = mlimit1; return 0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 184 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 192 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 197 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 198 */ - z->ket = z->c; /* [, line 198 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') { z->c = z->l - m2; goto lab0; } /* literal, line 198 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') { z->c = z->l - m2; goto lab0; } z->c--; - z->bra = z->c; /* ], line 198 */ - { int ret = slice_del(z); /* delete, line 198 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -1049,66 +1047,66 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ +static int r_residual_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* try, line 206 */ - z->ket = z->c; /* [, line 206 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m1; goto lab0; } /* literal, line 206 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m1; goto lab0; } z->c--; - z->bra = z->c; /* ], line 206 */ - { int m_test2 = z->l - z->c; /* test, line 206 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 206 */ - if (!(eq_s_b(z, 2, s_32))) goto lab2; /* literal, line 206 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + { int m3 = z->l - z->c; (void)m3; + if (!(eq_s_b(z, 2, s_32))) goto lab2; goto lab1; lab2: z->c = z->l - m3; - if (out_grouping_b_U(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m1; goto lab0; } /* non keep_with_s, line 206 */ + if (out_grouping_b_U(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m1; goto lab0; } } lab1: z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 206 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: ; } - { int mlimit4; /* setlimit, line 207 */ - if (z->c < z->I[0]) return 0; - mlimit4 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 208 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((278560 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit4; return 0; } /* substring, line 208 */ + { int mlimit4; + if (z->c < z->I[2]) return 0; + mlimit4 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((278560 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit4; return 0; } among_var = find_among_b(z, a_7, 6); if (!(among_var)) { z->lb = mlimit4; return 0; } - z->bra = z->c; /* ], line 208 */ - switch (among_var) { /* among, line 208 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 209 */ + { int ret = r_R2(z); if (ret == 0) { z->lb = mlimit4; return 0; } if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* or, line 209 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab4; /* literal, line 209 */ + { int m5 = z->l - z->c; (void)m5; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab4; z->c--; goto lab3; lab4: z->c = z->l - m5; - if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit4; return 0; } /* literal, line 209 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit4; return 0; } z->c--; } lab3: - { int ret = slice_del(z); /* delete, line 209 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_33); /* <-, line 211 */ + { int ret = slice_from_s(z, 1, s_33); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 212 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -1118,27 +1116,28 @@ static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_un_double(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 218 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 218 */ +static int r_un_double(struct SN_env * z) { + { int m_test1 = z->l - z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_8, 5))) return 0; z->c = z->l - m_test1; } - z->ket = z->c; /* [, line 218 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 218 */ + z->c = ret; } - z->bra = z->c; /* ], line 218 */ - { int ret = slice_del(z); /* delete, line 218 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_un_accent(struct SN_env * z) { /* backwardmode */ +static int r_un_accent(struct SN_env * z) { { int i = 1; - while(1) { if (out_grouping_b_U(z, g_v, 97, 251, 0)) goto lab0; /* non v, line 222 */ + while(1) { + if (out_grouping_b_U(z, g_v, 97, 251, 0)) goto lab0; i--; continue; lab0: @@ -1146,75 +1145,75 @@ static int r_un_accent(struct SN_env * z) { /* backwardmode */ } if (i > 0) return 0; } - z->ket = z->c; /* [, line 223 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 223 */ - if (!(eq_s_b(z, 2, s_34))) goto lab2; /* literal, line 223 */ + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 2, s_34))) goto lab2; goto lab1; lab2: z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_35))) return 0; /* literal, line 223 */ + if (!(eq_s_b(z, 2, s_35))) return 0; } lab1: - z->bra = z->c; /* ], line 223 */ - { int ret = slice_from_s(z, 1, s_36); /* <-, line 223 */ + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_36); if (ret < 0) return ret; } return 1; } -extern int french_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 229 */ - { int ret = r_prelude(z); /* call prelude, line 229 */ +extern int french_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 230 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 230 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 231 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 233 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 243 */ - { int m4 = z->l - z->c; (void)m4; /* and, line 239 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 235 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 235 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab3; lab4: z->c = z->l - m5; - { int ret = r_i_verb_suffix(z); /* call i_verb_suffix, line 236 */ + { int ret = r_i_verb_suffix(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab3; lab5: z->c = z->l - m5; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 237 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: z->c = z->l - m4; - { int m6 = z->l - z->c; (void)m6; /* try, line 240 */ - z->ket = z->c; /* [, line 240 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 240 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'Y') goto lab8; /* literal, line 240 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + { int m7 = z->l - z->c; (void)m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') goto lab8; z->c--; - z->bra = z->c; /* ], line 240 */ - { int ret = slice_from_s(z, 1, s_37); /* <-, line 240 */ + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_37); if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m7; - if (!(eq_s_b(z, 2, s_38))) { z->c = z->l - m6; goto lab6; } /* literal, line 241 */ - z->bra = z->c; /* ], line 241 */ - { int ret = slice_from_s(z, 1, s_39); /* <-, line 241 */ + if (!(eq_s_b(z, 2, s_38))) { z->c = z->l - m6; goto lab6; } + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_39); if (ret < 0) return ret; } } @@ -1226,7 +1225,7 @@ extern int french_UTF_8_stem(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = z->l - m3; - { int ret = r_residual_suffix(z); /* call residual_suffix, line 244 */ + { int ret = r_residual_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1235,21 +1234,21 @@ extern int french_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m8 = z->l - z->c; (void)m8; /* do, line 249 */ - { int ret = r_un_double(z); /* call un_double, line 249 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_un_double(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 250 */ - { int ret = r_un_accent(z); /* call un_accent, line 250 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_un_accent(z); if (ret < 0) return ret; } z->c = z->l - m9; } z->c = z->lb; - { int c10 = z->c; /* do, line 252 */ - { int ret = r_postlude(z); /* call postlude, line 252 */ + { int c10 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c10; @@ -1257,7 +1256,7 @@ extern int french_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * french_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * french_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void french_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_german.c b/src/backend/snowball/libstemmer/stem_UTF_8_german.c index 41a3b4eec347..5b65f2d039cf 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_german.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_german.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -35,12 +35,12 @@ static const symbol s_0_5[2] = { 0xC3, 0xBC }; static const struct among a_0[6] = { -/* 0 */ { 0, 0, -1, 5, 0}, -/* 1 */ { 1, s_0_1, 0, 2, 0}, -/* 2 */ { 1, s_0_2, 0, 1, 0}, -/* 3 */ { 2, s_0_3, 0, 3, 0}, -/* 4 */ { 2, s_0_4, 0, 4, 0}, -/* 5 */ { 2, s_0_5, 0, 2, 0} +{ 0, 0, -1, 5, 0}, +{ 1, s_0_1, 0, 2, 0}, +{ 1, s_0_2, 0, 1, 0}, +{ 2, s_0_3, 0, 3, 0}, +{ 2, s_0_4, 0, 4, 0}, +{ 2, s_0_5, 0, 2, 0} }; static const symbol s_1_0[1] = { 'e' }; @@ -53,13 +53,13 @@ static const symbol s_1_6[2] = { 'e', 's' }; static const struct among a_1[7] = { -/* 0 */ { 1, s_1_0, -1, 2, 0}, -/* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 2, 0}, -/* 3 */ { 3, s_1_3, -1, 1, 0}, -/* 4 */ { 2, s_1_4, -1, 1, 0}, -/* 5 */ { 1, s_1_5, -1, 3, 0}, -/* 6 */ { 2, s_1_6, 5, 2, 0} +{ 1, s_1_0, -1, 2, 0}, +{ 2, s_1_1, -1, 1, 0}, +{ 2, s_1_2, -1, 2, 0}, +{ 3, s_1_3, -1, 1, 0}, +{ 2, s_1_4, -1, 1, 0}, +{ 1, s_1_5, -1, 3, 0}, +{ 2, s_1_6, 5, 2, 0} }; static const symbol s_2_0[2] = { 'e', 'n' }; @@ -69,10 +69,10 @@ static const symbol s_2_3[3] = { 'e', 's', 't' }; static const struct among a_2[4] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 2, s_2_1, -1, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 2, 0}, -/* 3 */ { 3, s_2_3, 2, 1, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 2, s_2_1, -1, 1, 0}, +{ 2, s_2_2, -1, 2, 0}, +{ 3, s_2_3, 2, 1, 0} }; static const symbol s_3_0[2] = { 'i', 'g' }; @@ -80,8 +80,8 @@ static const symbol s_3_1[4] = { 'l', 'i', 'c', 'h' }; static const struct among a_3[2] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0} }; static const symbol s_4_0[3] = { 'e', 'n', 'd' }; @@ -95,14 +95,14 @@ static const symbol s_4_7[4] = { 'k', 'e', 'i', 't' }; static const struct among a_4[8] = { -/* 0 */ { 3, s_4_0, -1, 1, 0}, -/* 1 */ { 2, s_4_1, -1, 2, 0}, -/* 2 */ { 3, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 3, 0}, -/* 4 */ { 4, s_4_4, -1, 2, 0}, -/* 5 */ { 2, s_4_5, -1, 2, 0}, -/* 6 */ { 4, s_4_6, -1, 3, 0}, -/* 7 */ { 4, s_4_7, -1, 4, 0} +{ 3, s_4_0, -1, 1, 0}, +{ 2, s_4_1, -1, 2, 0}, +{ 3, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 3, 0}, +{ 4, s_4_4, -1, 2, 0}, +{ 2, s_4_5, -1, 2, 0}, +{ 4, s_4_6, -1, 3, 0}, +{ 4, s_4_7, -1, 4, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32, 8 }; @@ -124,24 +124,23 @@ static const symbol s_9[] = { 'i', 'g' }; static const symbol s_10[] = { 'e', 'r' }; static const symbol s_11[] = { 'e', 'n' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ - { int c_test1 = z->c; /* test, line 35 */ -/* repeat, line 35 */ - - while(1) { int c2 = z->c; - { int c3 = z->c; /* or, line 38 */ - z->bra = z->c; /* [, line 37 */ - if (!(eq_s(z, 2, s_0))) goto lab2; /* literal, line 37 */ - z->ket = z->c; /* ], line 37 */ - { int ret = slice_from_s(z, 2, s_1); /* <-, line 37 */ +static int r_prelude(struct SN_env * z) { + { int c_test1 = z->c; + while(1) { + int c2 = z->c; + { int c3 = z->c; + z->bra = z->c; + if (!(eq_s(z, 2, s_0))) goto lab2; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_1); if (ret < 0) return ret; } goto lab1; lab2: z->c = c3; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 38 */ + z->c = ret; } } lab1: @@ -152,29 +151,28 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ } z->c = c_test1; } -/* repeat, line 41 */ - - while(1) { int c4 = z->c; - while(1) { /* goto, line 41 */ + while(1) { + int c4 = z->c; + while(1) { int c5 = z->c; - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 42 */ - z->bra = z->c; /* [, line 42 */ - { int c6 = z->c; /* or, line 42 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab6; /* literal, line 42 */ + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; + z->bra = z->c; + { int c6 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab6; z->c++; - z->ket = z->c; /* ], line 42 */ - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab6; /* grouping v, line 42 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 42 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab6; + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } goto lab5; lab6: z->c = c6; - if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 43 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; z->c++; - z->ket = z->c; /* ], line 43 */ - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 43 */ - { int ret = slice_from_s(z, 1, s_3); /* <-, line 43 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } } @@ -183,9 +181,9 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ break; lab4: z->c = c5; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab3; - z->c = ret; /* goto, line 41 */ + z->c = ret; } } continue; @@ -196,80 +194,79 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 49 */ - z->I[1] = z->l; /* $p2 = , line 50 */ - { int c_test1 = z->c; /* test, line 52 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 52 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + { int c_test1 = z->c; + { int ret = skip_utf8(z->p, z->c, z->l, 3); if (ret < 0) return 0; z->c = ret; } - z->I[2] = z->c; /* setmark x, line 52 */ + z->I[0] = z->c; z->c = c_test1; } - { /* gopast */ /* grouping v, line 54 */ + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 54 */ + { int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 54 */ - /* try, line 55 */ - if (!(z->I[0] < z->I[2])) goto lab0; /* $( < ), line 55 */ - z->I[0] = z->I[2]; /* $p1 = , line 55 */ + z->I[2] = z->c; + + if (!(z->I[2] < z->I[0])) goto lab0; + z->I[2] = z->I[0]; lab0: - { /* gopast */ /* grouping v, line 56 */ + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 56 */ + { int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 56 */ + z->I[1] = z->c; return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 60 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 62 */ - among_var = find_among(z, a_0, 6); /* substring, line 62 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + among_var = find_among(z, a_0, 6); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 62 */ - switch (among_var) { /* among, line 62 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 63 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 64 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 65 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 66 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 5: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 68 */ + z->c = ret; } break; } @@ -281,45 +278,45 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 75 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 76 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 79 */ - z->ket = z->c; /* [, line 80 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 80 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; among_var = find_among_b(z, a_1, 7); if (!(among_var)) goto lab0; - z->bra = z->c; /* ], line 80 */ - { int ret = r_R1(z); /* call R1, line 80 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } - switch (among_var) { /* among, line 80 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 82 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 85 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 86 */ - z->ket = z->c; /* [, line 86 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m2; goto lab1; } z->c--; - z->bra = z->c; /* ], line 86 */ - if (!(eq_s_b(z, 3, s_8))) { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ - { int ret = slice_del(z); /* delete, line 86 */ + z->bra = z->c; + if (!(eq_s_b(z, 3, s_8))) { z->c = z->l - m2; goto lab1; } + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: @@ -327,8 +324,8 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - if (in_grouping_b_U(z, g_s_ending, 98, 116, 0)) goto lab0; /* grouping s_ending, line 89 */ - { int ret = slice_del(z); /* delete, line 89 */ + if (in_grouping_b_U(z, g_s_ending, 98, 116, 0)) goto lab0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -336,29 +333,29 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab0: z->c = z->l - m1; } - { int m3 = z->l - z->c; (void)m3; /* do, line 93 */ - z->ket = z->c; /* [, line 94 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; /* substring, line 94 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; among_var = find_among_b(z, a_2, 4); if (!(among_var)) goto lab2; - z->bra = z->c; /* ], line 94 */ - { int ret = r_R1(z); /* call R1, line 94 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } - switch (among_var) { /* among, line 94 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (in_grouping_b_U(z, g_st_ending, 98, 116, 0)) goto lab2; /* grouping st_ending, line 99 */ - { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 3); /* hop, line 99 */ + if (in_grouping_b_U(z, g_st_ending, 98, 116, 0)) goto lab2; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 3); if (ret < 0) goto lab2; z->c = ret; } - { int ret = slice_del(z); /* delete, line 99 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -366,37 +363,37 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ lab2: z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 103 */ - z->ket = z->c; /* [, line 104 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; /* substring, line 104 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; among_var = find_among_b(z, a_4, 8); if (!(among_var)) goto lab3; - z->bra = z->c; /* ], line 104 */ - { int ret = r_R2(z); /* call R2, line 104 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - switch (among_var) { /* among, line 104 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* try, line 107 */ - z->ket = z->c; /* [, line 107 */ - if (!(eq_s_b(z, 2, s_9))) { z->c = z->l - m5; goto lab4; } /* literal, line 107 */ - z->bra = z->c; /* ], line 107 */ - { int m6 = z->l - z->c; (void)m6; /* not, line 107 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab5; /* literal, line 107 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_9))) { z->c = z->l - m5; goto lab4; } + z->bra = z->c; + { int m6 = z->l - z->c; (void)m6; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab5; z->c--; { z->c = z->l - m5; goto lab4; } lab5: z->c = z->l - m6; } - { int ret = r_R2(z); /* call R2, line 107 */ + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 107 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab4: @@ -404,37 +401,37 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 2: - { int m7 = z->l - z->c; (void)m7; /* not, line 110 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; /* literal, line 110 */ + { int m7 = z->l - z->c; (void)m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; z->c--; goto lab3; lab6: z->c = z->l - m7; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 113 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m8 = z->l - z->c; (void)m8; /* try, line 114 */ - z->ket = z->c; /* [, line 115 */ - { int m9 = z->l - z->c; (void)m9; /* or, line 115 */ - if (!(eq_s_b(z, 2, s_10))) goto lab9; /* literal, line 115 */ + { int m8 = z->l - z->c; (void)m8; + z->ket = z->c; + { int m9 = z->l - z->c; (void)m9; + if (!(eq_s_b(z, 2, s_10))) goto lab9; goto lab8; lab9: z->c = z->l - m9; - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m8; goto lab7; } /* literal, line 115 */ + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m8; goto lab7; } } lab8: - z->bra = z->c; /* ], line 115 */ - { int ret = r_R1(z); /* call R1, line 115 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret == 0) { z->c = z->l - m8; goto lab7; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 115 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab7: @@ -442,19 +439,19 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 4: - { int ret = slice_del(z); /* delete, line 119 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m10 = z->l - z->c; (void)m10; /* try, line 120 */ - z->ket = z->c; /* [, line 121 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m10; goto lab10; } /* substring, line 121 */ + { int m10 = z->l - z->c; (void)m10; + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m10; goto lab10; } if (!(find_among_b(z, a_3, 2))) { z->c = z->l - m10; goto lab10; } - z->bra = z->c; /* ], line 121 */ - { int ret = r_R2(z); /* call R2, line 121 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m10; goto lab10; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 123 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab10: @@ -468,28 +465,28 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int german_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 134 */ - { int ret = r_prelude(z); /* call prelude, line 134 */ +extern int german_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - { int c2 = z->c; /* do, line 135 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 135 */ + { int c2 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c2; } - z->lb = z->c; z->c = z->l; /* backwards, line 136 */ + z->lb = z->c; z->c = z->l; - /* do, line 137 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 137 */ + + { int ret = r_standard_suffix(z); if (ret < 0) return ret; } z->c = z->lb; - { int c3 = z->c; /* do, line 138 */ - { int ret = r_postlude(z); /* call postlude, line 138 */ + { int c3 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c3; @@ -497,7 +494,7 @@ extern int german_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * german_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * german_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void german_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_greek.c b/src/backend/snowball/libstemmer/stem_UTF_8_greek.c index 8810357358f8..bb2d4259e6ae 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_greek.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_greek.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -103,52 +103,52 @@ static const symbol s_0_45[2] = { 0xCE, 0xB0 }; static const struct among a_0[46] = { -/* 0 */ { 0, 0, -1, 25, 0}, -/* 1 */ { 2, s_0_1, 0, 18, 0}, -/* 2 */ { 2, s_0_2, 0, 1, 0}, -/* 3 */ { 2, s_0_3, 0, 5, 0}, -/* 4 */ { 2, s_0_4, 0, 7, 0}, -/* 5 */ { 2, s_0_5, 0, 9, 0}, -/* 6 */ { 2, s_0_6, 0, 7, 0}, -/* 7 */ { 2, s_0_7, 0, 20, 0}, -/* 8 */ { 2, s_0_8, 0, 15, 0}, -/* 9 */ { 2, s_0_9, 0, 15, 0}, -/* 10 */ { 2, s_0_10, 0, 20, 0}, -/* 11 */ { 2, s_0_11, 0, 20, 0}, -/* 12 */ { 2, s_0_12, 0, 24, 0}, -/* 13 */ { 2, s_0_13, 0, 24, 0}, -/* 14 */ { 2, s_0_14, 0, 7, 0}, -/* 15 */ { 2, s_0_15, 0, 1, 0}, -/* 16 */ { 2, s_0_16, 0, 2, 0}, -/* 17 */ { 2, s_0_17, 0, 3, 0}, -/* 18 */ { 2, s_0_18, 0, 4, 0}, -/* 19 */ { 2, s_0_19, 0, 5, 0}, -/* 20 */ { 2, s_0_20, 0, 6, 0}, -/* 21 */ { 2, s_0_21, 0, 7, 0}, -/* 22 */ { 2, s_0_22, 0, 8, 0}, -/* 23 */ { 2, s_0_23, 0, 9, 0}, -/* 24 */ { 2, s_0_24, 0, 10, 0}, -/* 25 */ { 2, s_0_25, 0, 11, 0}, -/* 26 */ { 2, s_0_26, 0, 12, 0}, -/* 27 */ { 2, s_0_27, 0, 13, 0}, -/* 28 */ { 2, s_0_28, 0, 14, 0}, -/* 29 */ { 2, s_0_29, 0, 15, 0}, -/* 30 */ { 2, s_0_30, 0, 16, 0}, -/* 31 */ { 2, s_0_31, 0, 17, 0}, -/* 32 */ { 2, s_0_32, 0, 18, 0}, -/* 33 */ { 2, s_0_33, 0, 19, 0}, -/* 34 */ { 2, s_0_34, 0, 20, 0}, -/* 35 */ { 2, s_0_35, 0, 21, 0}, -/* 36 */ { 2, s_0_36, 0, 22, 0}, -/* 37 */ { 2, s_0_37, 0, 23, 0}, -/* 38 */ { 2, s_0_38, 0, 24, 0}, -/* 39 */ { 2, s_0_39, 0, 9, 0}, -/* 40 */ { 2, s_0_40, 0, 20, 0}, -/* 41 */ { 2, s_0_41, 0, 1, 0}, -/* 42 */ { 2, s_0_42, 0, 5, 0}, -/* 43 */ { 2, s_0_43, 0, 7, 0}, -/* 44 */ { 2, s_0_44, 0, 9, 0}, -/* 45 */ { 2, s_0_45, 0, 20, 0} +{ 0, 0, -1, 25, 0}, +{ 2, s_0_1, 0, 18, 0}, +{ 2, s_0_2, 0, 1, 0}, +{ 2, s_0_3, 0, 5, 0}, +{ 2, s_0_4, 0, 7, 0}, +{ 2, s_0_5, 0, 9, 0}, +{ 2, s_0_6, 0, 7, 0}, +{ 2, s_0_7, 0, 20, 0}, +{ 2, s_0_8, 0, 15, 0}, +{ 2, s_0_9, 0, 15, 0}, +{ 2, s_0_10, 0, 20, 0}, +{ 2, s_0_11, 0, 20, 0}, +{ 2, s_0_12, 0, 24, 0}, +{ 2, s_0_13, 0, 24, 0}, +{ 2, s_0_14, 0, 7, 0}, +{ 2, s_0_15, 0, 1, 0}, +{ 2, s_0_16, 0, 2, 0}, +{ 2, s_0_17, 0, 3, 0}, +{ 2, s_0_18, 0, 4, 0}, +{ 2, s_0_19, 0, 5, 0}, +{ 2, s_0_20, 0, 6, 0}, +{ 2, s_0_21, 0, 7, 0}, +{ 2, s_0_22, 0, 8, 0}, +{ 2, s_0_23, 0, 9, 0}, +{ 2, s_0_24, 0, 10, 0}, +{ 2, s_0_25, 0, 11, 0}, +{ 2, s_0_26, 0, 12, 0}, +{ 2, s_0_27, 0, 13, 0}, +{ 2, s_0_28, 0, 14, 0}, +{ 2, s_0_29, 0, 15, 0}, +{ 2, s_0_30, 0, 16, 0}, +{ 2, s_0_31, 0, 17, 0}, +{ 2, s_0_32, 0, 18, 0}, +{ 2, s_0_33, 0, 19, 0}, +{ 2, s_0_34, 0, 20, 0}, +{ 2, s_0_35, 0, 21, 0}, +{ 2, s_0_36, 0, 22, 0}, +{ 2, s_0_37, 0, 23, 0}, +{ 2, s_0_38, 0, 24, 0}, +{ 2, s_0_39, 0, 9, 0}, +{ 2, s_0_40, 0, 20, 0}, +{ 2, s_0_41, 0, 1, 0}, +{ 2, s_0_42, 0, 5, 0}, +{ 2, s_0_43, 0, 7, 0}, +{ 2, s_0_44, 0, 9, 0}, +{ 2, s_0_45, 0, 20, 0} }; static const symbol s_1_0[16] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x89, 0xCF, 0x83 }; @@ -194,46 +194,46 @@ static const symbol s_1_39[14] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB static const struct among a_1[40] = { -/* 0 */ { 16, s_1_0, -1, 10, 0}, -/* 1 */ { 6, s_1_1, -1, 9, 0}, -/* 2 */ { 10, s_1_2, -1, 7, 0}, -/* 3 */ { 10, s_1_3, -1, 8, 0}, -/* 4 */ { 10, s_1_4, -1, 6, 0}, -/* 5 */ { 20, s_1_5, -1, 10, 0}, -/* 6 */ { 10, s_1_6, -1, 9, 0}, -/* 7 */ { 14, s_1_7, -1, 7, 0}, -/* 8 */ { 14, s_1_8, -1, 8, 0}, -/* 9 */ { 14, s_1_9, -1, 6, 0}, -/* 10 */ { 18, s_1_10, -1, 11, 0}, -/* 11 */ { 14, s_1_11, -1, 11, 0}, -/* 12 */ { 12, s_1_12, -1, 1, 0}, -/* 13 */ { 14, s_1_13, -1, 2, 0}, -/* 14 */ { 12, s_1_14, -1, 4, 0}, -/* 15 */ { 16, s_1_15, -1, 5, 0}, -/* 16 */ { 14, s_1_16, -1, 3, 0}, -/* 17 */ { 18, s_1_17, -1, 10, 0}, -/* 18 */ { 8, s_1_18, -1, 9, 0}, -/* 19 */ { 12, s_1_19, -1, 7, 0}, -/* 20 */ { 12, s_1_20, -1, 8, 0}, -/* 21 */ { 12, s_1_21, -1, 6, 0}, -/* 22 */ { 16, s_1_22, -1, 11, 0}, -/* 23 */ { 10, s_1_23, -1, 1, 0}, -/* 24 */ { 12, s_1_24, -1, 2, 0}, -/* 25 */ { 10, s_1_25, -1, 4, 0}, -/* 26 */ { 14, s_1_26, -1, 5, 0}, -/* 27 */ { 12, s_1_27, -1, 3, 0}, -/* 28 */ { 12, s_1_28, -1, 7, 0}, -/* 29 */ { 20, s_1_29, -1, 10, 0}, -/* 30 */ { 10, s_1_30, -1, 9, 0}, -/* 31 */ { 14, s_1_31, -1, 7, 0}, -/* 32 */ { 14, s_1_32, -1, 8, 0}, -/* 33 */ { 14, s_1_33, -1, 6, 0}, -/* 34 */ { 18, s_1_34, -1, 11, 0}, -/* 35 */ { 12, s_1_35, -1, 1, 0}, -/* 36 */ { 14, s_1_36, -1, 2, 0}, -/* 37 */ { 12, s_1_37, -1, 4, 0}, -/* 38 */ { 16, s_1_38, -1, 5, 0}, -/* 39 */ { 14, s_1_39, -1, 3, 0} +{ 16, s_1_0, -1, 10, 0}, +{ 6, s_1_1, -1, 9, 0}, +{ 10, s_1_2, -1, 7, 0}, +{ 10, s_1_3, -1, 8, 0}, +{ 10, s_1_4, -1, 6, 0}, +{ 20, s_1_5, -1, 10, 0}, +{ 10, s_1_6, -1, 9, 0}, +{ 14, s_1_7, -1, 7, 0}, +{ 14, s_1_8, -1, 8, 0}, +{ 14, s_1_9, -1, 6, 0}, +{ 18, s_1_10, -1, 11, 0}, +{ 14, s_1_11, -1, 11, 0}, +{ 12, s_1_12, -1, 1, 0}, +{ 14, s_1_13, -1, 2, 0}, +{ 12, s_1_14, -1, 4, 0}, +{ 16, s_1_15, -1, 5, 0}, +{ 14, s_1_16, -1, 3, 0}, +{ 18, s_1_17, -1, 10, 0}, +{ 8, s_1_18, -1, 9, 0}, +{ 12, s_1_19, -1, 7, 0}, +{ 12, s_1_20, -1, 8, 0}, +{ 12, s_1_21, -1, 6, 0}, +{ 16, s_1_22, -1, 11, 0}, +{ 10, s_1_23, -1, 1, 0}, +{ 12, s_1_24, -1, 2, 0}, +{ 10, s_1_25, -1, 4, 0}, +{ 14, s_1_26, -1, 5, 0}, +{ 12, s_1_27, -1, 3, 0}, +{ 12, s_1_28, -1, 7, 0}, +{ 20, s_1_29, -1, 10, 0}, +{ 10, s_1_30, -1, 9, 0}, +{ 14, s_1_31, -1, 7, 0}, +{ 14, s_1_32, -1, 8, 0}, +{ 14, s_1_33, -1, 6, 0}, +{ 18, s_1_34, -1, 11, 0}, +{ 12, s_1_35, -1, 1, 0}, +{ 14, s_1_36, -1, 2, 0}, +{ 12, s_1_37, -1, 4, 0}, +{ 16, s_1_38, -1, 5, 0}, +{ 14, s_1_39, -1, 3, 0} }; static const symbol s_2_0[4] = { 0xCF, 0x80, 0xCE, 0xB1 }; @@ -248,15 +248,15 @@ static const symbol s_2_8[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1 static const struct among a_2[9] = { -/* 0 */ { 4, s_2_0, -1, 1, 0}, -/* 1 */ { 12, s_2_1, 0, 1, 0}, -/* 2 */ { 6, s_2_2, 0, 1, 0}, -/* 3 */ { 12, s_2_3, 0, 1, 0}, -/* 4 */ { 12, s_2_4, 0, 1, 0}, -/* 5 */ { 8, s_2_5, 0, 1, 0}, -/* 6 */ { 8, s_2_6, -1, 1, 0}, -/* 7 */ { 8, s_2_7, -1, 1, 0}, -/* 8 */ { 14, s_2_8, 7, 1, 0} +{ 4, s_2_0, -1, 1, 0}, +{ 12, s_2_1, 0, 1, 0}, +{ 6, s_2_2, 0, 1, 0}, +{ 12, s_2_3, 0, 1, 0}, +{ 12, s_2_4, 0, 1, 0}, +{ 8, s_2_5, 0, 1, 0}, +{ 8, s_2_6, -1, 1, 0}, +{ 8, s_2_7, -1, 1, 0}, +{ 14, s_2_8, 7, 1, 0} }; static const symbol s_3_0[2] = { 0xCF, 0x80 }; @@ -284,28 +284,28 @@ static const symbol s_3_21[8] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x81, 0xCE, 0xBD static const struct among a_3[22] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 6, s_3_1, 0, 1, 0}, -/* 2 */ { 2, s_3_2, -1, 1, 0}, -/* 3 */ { 4, s_3_3, 2, 1, 0}, -/* 4 */ { 6, s_3_4, 3, 1, 0}, -/* 5 */ { 6, s_3_5, 2, 1, 0}, -/* 6 */ { 12, s_3_6, 2, 1, 0}, -/* 7 */ { 10, s_3_7, 2, 1, 0}, -/* 8 */ { 10, s_3_8, 2, 1, 0}, -/* 9 */ { 6, s_3_9, 2, 1, 0}, -/* 10 */ { 6, s_3_10, 2, 1, 0}, -/* 11 */ { 14, s_3_11, 2, 1, 0}, -/* 12 */ { 12, s_3_12, 2, 1, 0}, -/* 13 */ { 12, s_3_13, 2, 1, 0}, -/* 14 */ { 6, s_3_14, -1, 1, 0}, -/* 15 */ { 2, s_3_15, -1, 1, 0}, -/* 16 */ { 12, s_3_16, -1, 1, 0}, -/* 17 */ { 8, s_3_17, -1, 1, 0}, -/* 18 */ { 8, s_3_18, -1, 1, 0}, -/* 19 */ { 2, s_3_19, -1, 1, 0}, -/* 20 */ { 2, s_3_20, -1, 1, 0}, -/* 21 */ { 8, s_3_21, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 6, s_3_1, 0, 1, 0}, +{ 2, s_3_2, -1, 1, 0}, +{ 4, s_3_3, 2, 1, 0}, +{ 6, s_3_4, 3, 1, 0}, +{ 6, s_3_5, 2, 1, 0}, +{ 12, s_3_6, 2, 1, 0}, +{ 10, s_3_7, 2, 1, 0}, +{ 10, s_3_8, 2, 1, 0}, +{ 6, s_3_9, 2, 1, 0}, +{ 6, s_3_10, 2, 1, 0}, +{ 14, s_3_11, 2, 1, 0}, +{ 12, s_3_12, 2, 1, 0}, +{ 12, s_3_13, 2, 1, 0}, +{ 6, s_3_14, -1, 1, 0}, +{ 2, s_3_15, -1, 1, 0}, +{ 12, s_3_16, -1, 1, 0}, +{ 8, s_3_17, -1, 1, 0}, +{ 8, s_3_18, -1, 1, 0}, +{ 2, s_3_19, -1, 1, 0}, +{ 2, s_3_20, -1, 1, 0}, +{ 8, s_3_21, -1, 1, 0} }; static const symbol s_4_0[8] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -325,20 +325,20 @@ static const symbol s_4_13[8] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB1, 0xCE, 0xBD static const struct among a_4[14] = { -/* 0 */ { 8, s_4_0, -1, 1, 0}, -/* 1 */ { 10, s_4_1, -1, 1, 0}, -/* 2 */ { 6, s_4_2, -1, 1, 0}, -/* 3 */ { 6, s_4_3, -1, 1, 0}, -/* 4 */ { 10, s_4_4, -1, 1, 0}, -/* 5 */ { 10, s_4_5, -1, 1, 0}, -/* 6 */ { 6, s_4_6, -1, 1, 0}, -/* 7 */ { 12, s_4_7, -1, 1, 0}, -/* 8 */ { 10, s_4_8, -1, 1, 0}, -/* 9 */ { 12, s_4_9, -1, 1, 0}, -/* 10 */ { 10, s_4_10, -1, 1, 0}, -/* 11 */ { 8, s_4_11, -1, 1, 0}, -/* 12 */ { 10, s_4_12, -1, 1, 0}, -/* 13 */ { 8, s_4_13, -1, 1, 0} +{ 8, s_4_0, -1, 1, 0}, +{ 10, s_4_1, -1, 1, 0}, +{ 6, s_4_2, -1, 1, 0}, +{ 6, s_4_3, -1, 1, 0}, +{ 10, s_4_4, -1, 1, 0}, +{ 10, s_4_5, -1, 1, 0}, +{ 6, s_4_6, -1, 1, 0}, +{ 12, s_4_7, -1, 1, 0}, +{ 10, s_4_8, -1, 1, 0}, +{ 12, s_4_9, -1, 1, 0}, +{ 10, s_4_10, -1, 1, 0}, +{ 8, s_4_11, -1, 1, 0}, +{ 10, s_4_12, -1, 1, 0}, +{ 8, s_4_13, -1, 1, 0} }; static const symbol s_5_0[2] = { 0xCF, 0x83 }; @@ -352,14 +352,14 @@ static const symbol s_5_7[4] = { 0xCE, 0xB5, 0xCE, 0xBD }; static const struct among a_5[8] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 2, s_5_1, -1, 1, 0}, -/* 2 */ { 4, s_5_2, -1, 1, 0}, -/* 3 */ { 4, s_5_3, -1, 1, 0}, -/* 4 */ { 4, s_5_4, -1, 1, 0}, -/* 5 */ { 4, s_5_5, -1, 1, 0}, -/* 6 */ { 4, s_5_6, -1, 1, 0}, -/* 7 */ { 4, s_5_7, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 2, s_5_1, -1, 1, 0}, +{ 4, s_5_2, -1, 1, 0}, +{ 4, s_5_3, -1, 1, 0}, +{ 4, s_5_4, -1, 1, 0}, +{ 4, s_5_5, -1, 1, 0}, +{ 4, s_5_6, -1, 1, 0}, +{ 4, s_5_7, -1, 1, 0} }; static const symbol s_6_0[12] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -372,13 +372,13 @@ static const symbol s_6_6[12] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA static const struct among a_6[7] = { -/* 0 */ { 12, s_6_0, -1, 1, 0}, -/* 1 */ { 10, s_6_1, -1, 1, 0}, -/* 2 */ { 14, s_6_2, -1, 1, 0}, -/* 3 */ { 10, s_6_3, -1, 1, 0}, -/* 4 */ { 14, s_6_4, -1, 1, 0}, -/* 5 */ { 14, s_6_5, -1, 1, 0}, -/* 6 */ { 12, s_6_6, -1, 1, 0} +{ 12, s_6_0, -1, 1, 0}, +{ 10, s_6_1, -1, 1, 0}, +{ 14, s_6_2, -1, 1, 0}, +{ 10, s_6_3, -1, 1, 0}, +{ 14, s_6_4, -1, 1, 0}, +{ 14, s_6_5, -1, 1, 0}, +{ 12, s_6_6, -1, 1, 0} }; static const symbol s_7_0[12] = { 0xCE, 0xBE, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB1 }; @@ -403,25 +403,25 @@ static const symbol s_7_18[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB static const struct among a_7[19] = { -/* 0 */ { 12, s_7_0, -1, 1, 0}, -/* 1 */ { 6, s_7_1, -1, 1, 0}, -/* 2 */ { 12, s_7_2, -1, 1, 0}, -/* 3 */ { 12, s_7_3, -1, 1, 0}, -/* 4 */ { 8, s_7_4, -1, 1, 0}, -/* 5 */ { 14, s_7_5, -1, 1, 0}, -/* 6 */ { 12, s_7_6, -1, 1, 0}, -/* 7 */ { 4, s_7_7, -1, 1, 0}, -/* 8 */ { 6, s_7_8, 7, 1, 0}, -/* 9 */ { 12, s_7_9, 8, 1, 0}, -/* 10 */ { 6, s_7_10, -1, 1, 0}, -/* 11 */ { 6, s_7_11, -1, 1, 0}, -/* 12 */ { 12, s_7_12, 11, 1, 0}, -/* 13 */ { 8, s_7_13, 11, 1, 0}, -/* 14 */ { 12, s_7_14, 13, 1, 0}, -/* 15 */ { 12, s_7_15, 11, 1, 0}, -/* 16 */ { 8, s_7_16, -1, 1, 0}, -/* 17 */ { 8, s_7_17, -1, 1, 0}, -/* 18 */ { 14, s_7_18, 17, 1, 0} +{ 12, s_7_0, -1, 1, 0}, +{ 6, s_7_1, -1, 1, 0}, +{ 12, s_7_2, -1, 1, 0}, +{ 12, s_7_3, -1, 1, 0}, +{ 8, s_7_4, -1, 1, 0}, +{ 14, s_7_5, -1, 1, 0}, +{ 12, s_7_6, -1, 1, 0}, +{ 4, s_7_7, -1, 1, 0}, +{ 6, s_7_8, 7, 1, 0}, +{ 12, s_7_9, 8, 1, 0}, +{ 6, s_7_10, -1, 1, 0}, +{ 6, s_7_11, -1, 1, 0}, +{ 12, s_7_12, 11, 1, 0}, +{ 8, s_7_13, 11, 1, 0}, +{ 12, s_7_14, 13, 1, 0}, +{ 12, s_7_15, 11, 1, 0}, +{ 8, s_7_16, -1, 1, 0}, +{ 8, s_7_17, -1, 1, 0}, +{ 14, s_7_18, 17, 1, 0} }; static const symbol s_8_0[2] = { 0xCF, 0x80 }; @@ -440,19 +440,19 @@ static const symbol s_8_12[6] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF }; static const struct among a_8[13] = { -/* 0 */ { 2, s_8_0, -1, 1, 0}, -/* 1 */ { 6, s_8_1, -1, 1, 0}, -/* 2 */ { 16, s_8_2, -1, 1, 0}, -/* 3 */ { 4, s_8_3, -1, 1, 0}, -/* 4 */ { 18, s_8_4, 3, 1, 0}, -/* 5 */ { 4, s_8_5, -1, 1, 0}, -/* 6 */ { 6, s_8_6, -1, 1, 0}, -/* 7 */ { 4, s_8_7, -1, 1, 0}, -/* 8 */ { 2, s_8_8, -1, 1, 0}, -/* 9 */ { 12, s_8_9, 8, 1, 0}, -/* 10 */ { 6, s_8_10, 8, 1, 0}, -/* 11 */ { 4, s_8_11, -1, 1, 0}, -/* 12 */ { 6, s_8_12, -1, 1, 0} +{ 2, s_8_0, -1, 1, 0}, +{ 6, s_8_1, -1, 1, 0}, +{ 16, s_8_2, -1, 1, 0}, +{ 4, s_8_3, -1, 1, 0}, +{ 18, s_8_4, 3, 1, 0}, +{ 4, s_8_5, -1, 1, 0}, +{ 6, s_8_6, -1, 1, 0}, +{ 4, s_8_7, -1, 1, 0}, +{ 2, s_8_8, -1, 1, 0}, +{ 12, s_8_9, 8, 1, 0}, +{ 6, s_8_10, 8, 1, 0}, +{ 4, s_8_11, -1, 1, 0}, +{ 6, s_8_12, -1, 1, 0} }; static const symbol s_9_0[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -465,13 +465,13 @@ static const symbol s_9_6[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD static const struct among a_9[7] = { -/* 0 */ { 8, s_9_0, -1, 1, 0}, -/* 1 */ { 6, s_9_1, -1, 1, 0}, -/* 2 */ { 6, s_9_2, -1, 1, 0}, -/* 3 */ { 10, s_9_3, -1, 1, 0}, -/* 4 */ { 10, s_9_4, -1, 1, 0}, -/* 5 */ { 10, s_9_5, -1, 1, 0}, -/* 6 */ { 8, s_9_6, -1, 1, 0} +{ 8, s_9_0, -1, 1, 0}, +{ 6, s_9_1, -1, 1, 0}, +{ 6, s_9_2, -1, 1, 0}, +{ 10, s_9_3, -1, 1, 0}, +{ 10, s_9_4, -1, 1, 0}, +{ 10, s_9_5, -1, 1, 0}, +{ 8, s_9_6, -1, 1, 0} }; static const symbol s_10_0[12] = { 0xCE, 0xBE, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB1 }; @@ -496,25 +496,25 @@ static const symbol s_10_18[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0x static const struct among a_10[19] = { -/* 0 */ { 12, s_10_0, -1, 1, 0}, -/* 1 */ { 6, s_10_1, -1, 1, 0}, -/* 2 */ { 12, s_10_2, -1, 1, 0}, -/* 3 */ { 12, s_10_3, -1, 1, 0}, -/* 4 */ { 8, s_10_4, -1, 1, 0}, -/* 5 */ { 14, s_10_5, -1, 1, 0}, -/* 6 */ { 12, s_10_6, -1, 1, 0}, -/* 7 */ { 4, s_10_7, -1, 1, 0}, -/* 8 */ { 6, s_10_8, 7, 1, 0}, -/* 9 */ { 12, s_10_9, 8, 1, 0}, -/* 10 */ { 6, s_10_10, -1, 1, 0}, -/* 11 */ { 6, s_10_11, -1, 1, 0}, -/* 12 */ { 12, s_10_12, 11, 1, 0}, -/* 13 */ { 8, s_10_13, 11, 1, 0}, -/* 14 */ { 12, s_10_14, 13, 1, 0}, -/* 15 */ { 12, s_10_15, 11, 1, 0}, -/* 16 */ { 8, s_10_16, -1, 1, 0}, -/* 17 */ { 8, s_10_17, -1, 1, 0}, -/* 18 */ { 14, s_10_18, 17, 1, 0} +{ 12, s_10_0, -1, 1, 0}, +{ 6, s_10_1, -1, 1, 0}, +{ 12, s_10_2, -1, 1, 0}, +{ 12, s_10_3, -1, 1, 0}, +{ 8, s_10_4, -1, 1, 0}, +{ 14, s_10_5, -1, 1, 0}, +{ 12, s_10_6, -1, 1, 0}, +{ 4, s_10_7, -1, 1, 0}, +{ 6, s_10_8, 7, 1, 0}, +{ 12, s_10_9, 8, 1, 0}, +{ 6, s_10_10, -1, 1, 0}, +{ 6, s_10_11, -1, 1, 0}, +{ 12, s_10_12, 11, 1, 0}, +{ 8, s_10_13, 11, 1, 0}, +{ 12, s_10_14, 13, 1, 0}, +{ 12, s_10_15, 11, 1, 0}, +{ 8, s_10_16, -1, 1, 0}, +{ 8, s_10_17, -1, 1, 0}, +{ 14, s_10_18, 17, 1, 0} }; static const symbol s_11_0[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x83 }; @@ -527,13 +527,13 @@ static const symbol s_11_6[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x8 static const struct among a_11[7] = { -/* 0 */ { 10, s_11_0, -1, 1, 0}, -/* 1 */ { 6, s_11_1, -1, 1, 0}, -/* 2 */ { 10, s_11_2, -1, 1, 0}, -/* 3 */ { 12, s_11_3, -1, 1, 0}, -/* 4 */ { 12, s_11_4, -1, 1, 0}, -/* 5 */ { 8, s_11_5, -1, 1, 0}, -/* 6 */ { 10, s_11_6, -1, 1, 0} +{ 10, s_11_0, -1, 1, 0}, +{ 6, s_11_1, -1, 1, 0}, +{ 10, s_11_2, -1, 1, 0}, +{ 12, s_11_3, -1, 1, 0}, +{ 12, s_11_4, -1, 1, 0}, +{ 8, s_11_5, -1, 1, 0}, +{ 10, s_11_6, -1, 1, 0} }; static const symbol s_12_0[4] = { 0xCF, 0x83, 0xCE, 0xB5 }; @@ -546,13 +546,13 @@ static const symbol s_12_6[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB static const struct among a_12[7] = { -/* 0 */ { 4, s_12_0, -1, 1, 0}, -/* 1 */ { 6, s_12_1, 0, 1, 0}, -/* 2 */ { 6, s_12_2, -1, 1, 0}, -/* 3 */ { 6, s_12_3, -1, 1, 0}, -/* 4 */ { 12, s_12_4, 3, 1, 0}, -/* 5 */ { 8, s_12_5, -1, 1, 0}, -/* 6 */ { 14, s_12_6, -1, 1, 0} +{ 4, s_12_0, -1, 1, 0}, +{ 6, s_12_1, 0, 1, 0}, +{ 6, s_12_2, -1, 1, 0}, +{ 6, s_12_3, -1, 1, 0}, +{ 12, s_12_4, 3, 1, 0}, +{ 8, s_12_5, -1, 1, 0}, +{ 14, s_12_6, -1, 1, 0} }; static const symbol s_13_0[2] = { 0xCF, 0x80 }; @@ -591,39 +591,39 @@ static const symbol s_13_32[6] = { 0xCE, 0xB1, 0xCF, 0x87, 0xCE, 0xBD }; static const struct among a_13[33] = { -/* 0 */ { 2, s_13_0, -1, 1, 0}, -/* 1 */ { 6, s_13_1, 0, 1, 0}, -/* 2 */ { 4, s_13_2, 0, 1, 0}, -/* 3 */ { 6, s_13_3, 0, 1, 0}, -/* 4 */ { 6, s_13_4, -1, 1, 0}, -/* 5 */ { 4, s_13_5, -1, 1, 0}, -/* 6 */ { 6, s_13_6, -1, 1, 0}, -/* 7 */ { 4, s_13_7, -1, 1, 0}, -/* 8 */ { 6, s_13_8, -1, 1, 0}, -/* 9 */ { 4, s_13_9, -1, 1, 0}, -/* 10 */ { 6, s_13_10, 9, 1, 0}, -/* 11 */ { 4, s_13_11, -1, 1, 0}, -/* 12 */ { 6, s_13_12, 11, 1, 0}, -/* 13 */ { 4, s_13_13, -1, 1, 0}, -/* 14 */ { 6, s_13_14, 13, 1, 0}, -/* 15 */ { 6, s_13_15, -1, 1, 0}, -/* 16 */ { 4, s_13_16, -1, 1, 0}, -/* 17 */ { 6, s_13_17, -1, 1, 0}, -/* 18 */ { 4, s_13_18, -1, 1, 0}, -/* 19 */ { 6, s_13_19, 18, 1, 0}, -/* 20 */ { 6, s_13_20, -1, 1, 0}, -/* 21 */ { 6, s_13_21, -1, 1, 0}, -/* 22 */ { 4, s_13_22, -1, 1, 0}, -/* 23 */ { 6, s_13_23, -1, 1, 0}, -/* 24 */ { 6, s_13_24, -1, 1, 0}, -/* 25 */ { 4, s_13_25, -1, 1, 0}, -/* 26 */ { 6, s_13_26, -1, 1, 0}, -/* 27 */ { 6, s_13_27, -1, 1, 0}, -/* 28 */ { 6, s_13_28, -1, 1, 0}, -/* 29 */ { 6, s_13_29, -1, 1, 0}, -/* 30 */ { 2, s_13_30, -1, 1, 0}, -/* 31 */ { 6, s_13_31, 30, 1, 0}, -/* 32 */ { 6, s_13_32, -1, 1, 0} +{ 2, s_13_0, -1, 1, 0}, +{ 6, s_13_1, 0, 1, 0}, +{ 4, s_13_2, 0, 1, 0}, +{ 6, s_13_3, 0, 1, 0}, +{ 6, s_13_4, -1, 1, 0}, +{ 4, s_13_5, -1, 1, 0}, +{ 6, s_13_6, -1, 1, 0}, +{ 4, s_13_7, -1, 1, 0}, +{ 6, s_13_8, -1, 1, 0}, +{ 4, s_13_9, -1, 1, 0}, +{ 6, s_13_10, 9, 1, 0}, +{ 4, s_13_11, -1, 1, 0}, +{ 6, s_13_12, 11, 1, 0}, +{ 4, s_13_13, -1, 1, 0}, +{ 6, s_13_14, 13, 1, 0}, +{ 6, s_13_15, -1, 1, 0}, +{ 4, s_13_16, -1, 1, 0}, +{ 6, s_13_17, -1, 1, 0}, +{ 4, s_13_18, -1, 1, 0}, +{ 6, s_13_19, 18, 1, 0}, +{ 6, s_13_20, -1, 1, 0}, +{ 6, s_13_21, -1, 1, 0}, +{ 4, s_13_22, -1, 1, 0}, +{ 6, s_13_23, -1, 1, 0}, +{ 6, s_13_24, -1, 1, 0}, +{ 4, s_13_25, -1, 1, 0}, +{ 6, s_13_26, -1, 1, 0}, +{ 6, s_13_27, -1, 1, 0}, +{ 6, s_13_28, -1, 1, 0}, +{ 6, s_13_29, -1, 1, 0}, +{ 2, s_13_30, -1, 1, 0}, +{ 6, s_13_31, 30, 1, 0}, +{ 6, s_13_32, -1, 1, 0} }; static const symbol s_14_0[12] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; @@ -640,17 +640,17 @@ static const symbol s_14_10[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB static const struct among a_14[11] = { -/* 0 */ { 12, s_14_0, -1, 1, 0}, -/* 1 */ { 10, s_14_1, -1, 1, 0}, -/* 2 */ { 10, s_14_2, -1, 1, 0}, -/* 3 */ { 10, s_14_3, -1, 1, 0}, -/* 4 */ { 10, s_14_4, -1, 1, 0}, -/* 5 */ { 8, s_14_5, -1, 1, 0}, -/* 6 */ { 8, s_14_6, -1, 1, 0}, -/* 7 */ { 8, s_14_7, -1, 1, 0}, -/* 8 */ { 10, s_14_8, -1, 1, 0}, -/* 9 */ { 10, s_14_9, -1, 1, 0}, -/* 10 */ { 8, s_14_10, -1, 1, 0} +{ 12, s_14_0, -1, 1, 0}, +{ 10, s_14_1, -1, 1, 0}, +{ 10, s_14_2, -1, 1, 0}, +{ 10, s_14_3, -1, 1, 0}, +{ 10, s_14_4, -1, 1, 0}, +{ 8, s_14_5, -1, 1, 0}, +{ 8, s_14_6, -1, 1, 0}, +{ 8, s_14_7, -1, 1, 0}, +{ 10, s_14_8, -1, 1, 0}, +{ 10, s_14_9, -1, 1, 0}, +{ 8, s_14_10, -1, 1, 0} }; static const symbol s_15_0[4] = { 0xCF, 0x83, 0xCE, 0xB5 }; @@ -661,11 +661,11 @@ static const symbol s_15_4[12] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xB static const struct among a_15[5] = { -/* 0 */ { 4, s_15_0, -1, 1, 0}, -/* 1 */ { 12, s_15_1, 0, 1, 0}, -/* 2 */ { 14, s_15_2, 0, 1, 0}, -/* 3 */ { 10, s_15_3, -1, 1, 0}, -/* 4 */ { 12, s_15_4, -1, 1, 0} +{ 4, s_15_0, -1, 1, 0}, +{ 12, s_15_1, 0, 1, 0}, +{ 14, s_15_2, 0, 1, 0}, +{ 10, s_15_3, -1, 1, 0}, +{ 12, s_15_4, -1, 1, 0} }; static const symbol s_16_0[8] = { 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; @@ -673,8 +673,8 @@ static const symbol s_16_1[16] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB static const struct among a_16[2] = { -/* 0 */ { 8, s_16_0, -1, 1, 0}, -/* 1 */ { 16, s_16_1, 0, 1, 0} +{ 8, s_16_0, -1, 1, 0}, +{ 16, s_16_1, 0, 1, 0} }; static const symbol s_17_0[10] = { 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xBA }; @@ -690,16 +690,16 @@ static const symbol s_17_9[16] = { 0xCE, 0xB2, 0xCF, 0x85, 0xCE, 0xB6, 0xCE, 0xB static const struct among a_17[10] = { -/* 0 */ { 10, s_17_0, -1, 7, 0}, -/* 1 */ { 14, s_17_1, -1, 6, 0}, -/* 2 */ { 14, s_17_2, -1, 3, 0}, -/* 3 */ { 16, s_17_3, 2, 1, 0}, -/* 4 */ { 16, s_17_4, -1, 5, 0}, -/* 5 */ { 12, s_17_5, -1, 2, 0}, -/* 6 */ { 10, s_17_6, -1, 4, 0}, -/* 7 */ { 14, s_17_7, -1, 10, 0}, -/* 8 */ { 20, s_17_8, -1, 8, 0}, -/* 9 */ { 16, s_17_9, -1, 9, 0} +{ 10, s_17_0, -1, 7, 0}, +{ 14, s_17_1, -1, 6, 0}, +{ 14, s_17_2, -1, 3, 0}, +{ 16, s_17_3, 2, 1, 0}, +{ 16, s_17_4, -1, 5, 0}, +{ 12, s_17_5, -1, 2, 0}, +{ 10, s_17_6, -1, 4, 0}, +{ 14, s_17_7, -1, 10, 0}, +{ 20, s_17_8, -1, 8, 0}, +{ 16, s_17_9, -1, 9, 0} }; static const symbol s_18_0[12] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; @@ -711,12 +711,12 @@ static const symbol s_18_5[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xBF static const struct among a_18[6] = { -/* 0 */ { 12, s_18_0, -1, 1, 0}, -/* 1 */ { 10, s_18_1, -1, 1, 0}, -/* 2 */ { 10, s_18_2, -1, 1, 0}, -/* 3 */ { 10, s_18_3, -1, 1, 0}, -/* 4 */ { 10, s_18_4, -1, 1, 0}, -/* 5 */ { 8, s_18_5, -1, 1, 0} +{ 12, s_18_0, -1, 1, 0}, +{ 10, s_18_1, -1, 1, 0}, +{ 10, s_18_2, -1, 1, 0}, +{ 10, s_18_3, -1, 1, 0}, +{ 10, s_18_4, -1, 1, 0}, +{ 8, s_18_5, -1, 1, 0} }; static const symbol s_19_0[2] = { 0xCF, 0x83 }; @@ -724,8 +724,8 @@ static const symbol s_19_1[2] = { 0xCF, 0x87 }; static const struct among a_19[2] = { -/* 0 */ { 2, s_19_0, -1, 1, 0}, -/* 1 */ { 2, s_19_1, -1, 1, 0} +{ 2, s_19_0, -1, 1, 0}, +{ 2, s_19_1, -1, 1, 0} }; static const symbol s_20_0[12] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9, 0xCE, 0xB1 }; @@ -735,10 +735,10 @@ static const symbol s_20_3[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4, 0xCE, 0xB static const struct among a_20[4] = { -/* 0 */ { 12, s_20_0, -1, 1, 0}, -/* 1 */ { 14, s_20_1, -1, 1, 0}, -/* 2 */ { 10, s_20_2, -1, 1, 0}, -/* 3 */ { 12, s_20_3, -1, 1, 0} +{ 12, s_20_0, -1, 1, 0}, +{ 14, s_20_1, -1, 1, 0}, +{ 10, s_20_2, -1, 1, 0}, +{ 12, s_20_3, -1, 1, 0} }; static const symbol s_21_0[12] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x80 }; @@ -777,39 +777,39 @@ static const symbol s_21_32[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xBD }; static const struct among a_21[33] = { -/* 0 */ { 12, s_21_0, -1, 1, 0}, -/* 1 */ { 2, s_21_1, -1, 1, 0}, -/* 2 */ { 4, s_21_2, 1, 1, 0}, -/* 3 */ { 8, s_21_3, 2, 1, 0}, -/* 4 */ { 8, s_21_4, 2, 1, 0}, -/* 5 */ { 6, s_21_5, 1, 1, 0}, -/* 6 */ { 8, s_21_6, 1, 1, 0}, -/* 7 */ { 6, s_21_7, 1, 1, 0}, -/* 8 */ { 2, s_21_8, -1, 1, 0}, -/* 9 */ { 12, s_21_9, 8, 1, 0}, -/* 10 */ { 10, s_21_10, -1, 1, 0}, -/* 11 */ { 4, s_21_11, -1, 1, 0}, -/* 12 */ { 2, s_21_12, -1, 1, 0}, -/* 13 */ { 4, s_21_13, 12, 1, 0}, -/* 14 */ { 10, s_21_14, 13, 1, 0}, -/* 15 */ { 2, s_21_15, -1, 1, 0}, -/* 16 */ { 8, s_21_16, -1, 1, 0}, -/* 17 */ { 8, s_21_17, -1, 1, 0}, -/* 18 */ { 18, s_21_18, 17, 1, 0}, -/* 19 */ { 4, s_21_19, -1, 1, 0}, -/* 20 */ { 2, s_21_20, -1, 1, 0}, -/* 21 */ { 4, s_21_21, 20, 1, 0}, -/* 22 */ { 10, s_21_22, 20, 1, 0}, -/* 23 */ { 6, s_21_23, 20, 1, 0}, -/* 24 */ { 4, s_21_24, -1, 1, 0}, -/* 25 */ { 6, s_21_25, -1, 1, 0}, -/* 26 */ { 8, s_21_26, -1, 1, 0}, -/* 27 */ { 6, s_21_27, -1, 1, 0}, -/* 28 */ { 8, s_21_28, -1, 1, 0}, -/* 29 */ { 8, s_21_29, -1, 1, 0}, -/* 30 */ { 8, s_21_30, -1, 1, 0}, -/* 31 */ { 8, s_21_31, -1, 1, 0}, -/* 32 */ { 6, s_21_32, -1, 1, 0} +{ 12, s_21_0, -1, 1, 0}, +{ 2, s_21_1, -1, 1, 0}, +{ 4, s_21_2, 1, 1, 0}, +{ 8, s_21_3, 2, 1, 0}, +{ 8, s_21_4, 2, 1, 0}, +{ 6, s_21_5, 1, 1, 0}, +{ 8, s_21_6, 1, 1, 0}, +{ 6, s_21_7, 1, 1, 0}, +{ 2, s_21_8, -1, 1, 0}, +{ 12, s_21_9, 8, 1, 0}, +{ 10, s_21_10, -1, 1, 0}, +{ 4, s_21_11, -1, 1, 0}, +{ 2, s_21_12, -1, 1, 0}, +{ 4, s_21_13, 12, 1, 0}, +{ 10, s_21_14, 13, 1, 0}, +{ 2, s_21_15, -1, 1, 0}, +{ 8, s_21_16, -1, 1, 0}, +{ 8, s_21_17, -1, 1, 0}, +{ 18, s_21_18, 17, 1, 0}, +{ 4, s_21_19, -1, 1, 0}, +{ 2, s_21_20, -1, 1, 0}, +{ 4, s_21_21, 20, 1, 0}, +{ 10, s_21_22, 20, 1, 0}, +{ 6, s_21_23, 20, 1, 0}, +{ 4, s_21_24, -1, 1, 0}, +{ 6, s_21_25, -1, 1, 0}, +{ 8, s_21_26, -1, 1, 0}, +{ 6, s_21_27, -1, 1, 0}, +{ 8, s_21_28, -1, 1, 0}, +{ 8, s_21_29, -1, 1, 0}, +{ 8, s_21_30, -1, 1, 0}, +{ 8, s_21_31, -1, 1, 0}, +{ 6, s_21_32, -1, 1, 0} }; static const symbol s_22_0[2] = { 0xCF, 0x80 }; @@ -830,21 +830,21 @@ static const symbol s_22_14[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xBD }; static const struct among a_22[15] = { -/* 0 */ { 2, s_22_0, -1, 1, 0}, -/* 1 */ { 10, s_22_1, -1, 1, 0}, -/* 2 */ { 6, s_22_2, -1, 1, 0}, -/* 3 */ { 6, s_22_3, -1, 1, 0}, -/* 4 */ { 2, s_22_4, -1, 1, 0}, -/* 5 */ { 8, s_22_5, -1, 1, 0}, -/* 6 */ { 2, s_22_6, -1, 1, 0}, -/* 7 */ { 4, s_22_7, -1, 1, 0}, -/* 8 */ { 6, s_22_8, -1, 1, 0}, -/* 9 */ { 4, s_22_9, -1, 1, 0}, -/* 10 */ { 12, s_22_10, -1, 1, 0}, -/* 11 */ { 12, s_22_11, -1, 1, 0}, -/* 12 */ { 8, s_22_12, -1, 1, 0}, -/* 13 */ { 14, s_22_13, -1, 1, 0}, -/* 14 */ { 6, s_22_14, -1, 1, 0} +{ 2, s_22_0, -1, 1, 0}, +{ 10, s_22_1, -1, 1, 0}, +{ 6, s_22_2, -1, 1, 0}, +{ 6, s_22_3, -1, 1, 0}, +{ 2, s_22_4, -1, 1, 0}, +{ 8, s_22_5, -1, 1, 0}, +{ 2, s_22_6, -1, 1, 0}, +{ 4, s_22_7, -1, 1, 0}, +{ 6, s_22_8, -1, 1, 0}, +{ 4, s_22_9, -1, 1, 0}, +{ 12, s_22_10, -1, 1, 0}, +{ 12, s_22_11, -1, 1, 0}, +{ 8, s_22_12, -1, 1, 0}, +{ 14, s_22_13, -1, 1, 0}, +{ 6, s_22_14, -1, 1, 0} }; static const symbol s_23_0[10] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x83 }; @@ -858,14 +858,14 @@ static const symbol s_23_7[10] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83, 0xCF, 0x8 static const struct among a_23[8] = { -/* 0 */ { 10, s_23_0, -1, 1, 0}, -/* 1 */ { 10, s_23_1, -1, 1, 0}, -/* 2 */ { 8, s_23_2, -1, 1, 0}, -/* 3 */ { 8, s_23_3, -1, 1, 0}, -/* 4 */ { 12, s_23_4, 3, 1, 0}, -/* 5 */ { 6, s_23_5, -1, 1, 0}, -/* 6 */ { 10, s_23_6, 5, 1, 0}, -/* 7 */ { 10, s_23_7, -1, 1, 0} +{ 10, s_23_0, -1, 1, 0}, +{ 10, s_23_1, -1, 1, 0}, +{ 8, s_23_2, -1, 1, 0}, +{ 8, s_23_3, -1, 1, 0}, +{ 12, s_23_4, 3, 1, 0}, +{ 6, s_23_5, -1, 1, 0}, +{ 10, s_23_6, 5, 1, 0}, +{ 10, s_23_7, -1, 1, 0} }; static const symbol s_24_0[4] = { 0xCE, 0xB9, 0xCF, 0x81 }; @@ -875,10 +875,10 @@ static const symbol s_24_3[6] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF }; static const struct among a_24[4] = { -/* 0 */ { 4, s_24_0, -1, 1, 0}, -/* 1 */ { 6, s_24_1, -1, 1, 0}, -/* 2 */ { 8, s_24_2, -1, 1, 0}, -/* 3 */ { 6, s_24_3, -1, 1, 0} +{ 4, s_24_0, -1, 1, 0}, +{ 6, s_24_1, -1, 1, 0}, +{ 8, s_24_2, -1, 1, 0}, +{ 6, s_24_3, -1, 1, 0} }; static const symbol s_25_0[2] = { 0xCE, 0xB5 }; @@ -886,8 +886,8 @@ static const symbol s_25_1[10] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xB9, 0xCF, 0x8 static const struct among a_25[2] = { -/* 0 */ { 2, s_25_0, -1, 1, 0}, -/* 1 */ { 10, s_25_1, -1, 1, 0} +{ 2, s_25_0, -1, 1, 0}, +{ 10, s_25_1, -1, 1, 0} }; static const symbol s_26_0[8] = { 0xCE, 0xB9, 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1 }; @@ -896,9 +896,9 @@ static const symbol s_26_2[8] = { 0xCE, 0xB9, 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xBF static const struct among a_26[3] = { -/* 0 */ { 8, s_26_0, -1, 1, 0}, -/* 1 */ { 10, s_26_1, -1, 1, 0}, -/* 2 */ { 8, s_26_2, -1, 1, 0} +{ 8, s_26_0, -1, 1, 0}, +{ 10, s_26_1, -1, 1, 0}, +{ 8, s_26_2, -1, 1, 0} }; static const symbol s_27_0[2] = { 0xCF, 0x81 }; @@ -911,13 +911,13 @@ static const symbol s_27_6[6] = { 0xCE, 0xBC, 0xCE, 0xB7, 0xCE, 0xBD }; static const struct among a_27[7] = { -/* 0 */ { 2, s_27_0, -1, 1, 0}, -/* 1 */ { 4, s_27_1, -1, 1, 0}, -/* 2 */ { 2, s_27_2, -1, 1, 0}, -/* 3 */ { 6, s_27_3, -1, 1, 0}, -/* 4 */ { 10, s_27_4, -1, 1, 0}, -/* 5 */ { 8, s_27_5, -1, 1, 0}, -/* 6 */ { 6, s_27_6, -1, 1, 0} +{ 2, s_27_0, -1, 1, 0}, +{ 4, s_27_1, -1, 1, 0}, +{ 2, s_27_2, -1, 1, 0}, +{ 6, s_27_3, -1, 1, 0}, +{ 10, s_27_4, -1, 1, 0}, +{ 8, s_27_5, -1, 1, 0}, +{ 6, s_27_6, -1, 1, 0} }; static const symbol s_28_0[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x83 }; @@ -927,10 +927,10 @@ static const symbol s_28_3[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xBF static const struct among a_28[4] = { -/* 0 */ { 10, s_28_0, -1, 1, 0}, -/* 1 */ { 10, s_28_1, -1, 1, 0}, -/* 2 */ { 8, s_28_2, -1, 1, 0}, -/* 3 */ { 8, s_28_3, -1, 1, 0} +{ 10, s_28_0, -1, 1, 0}, +{ 10, s_28_1, -1, 1, 0}, +{ 8, s_28_2, -1, 1, 0}, +{ 8, s_28_3, -1, 1, 0} }; static const symbol s_29_0[8] = { 0xCE, 0xB1, 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -938,8 +938,8 @@ static const symbol s_29_1[8] = { 0xCE, 0xB1, 0xCE, 0xB4, 0xCF, 0x89, 0xCE, 0xBD static const struct among a_29[2] = { -/* 0 */ { 8, s_29_0, -1, 1, 0}, -/* 1 */ { 8, s_29_1, -1, 1, 0} +{ 8, s_29_0, -1, 1, 0}, +{ 8, s_29_1, -1, 1, 0} }; static const symbol s_30_0[10] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x80 }; @@ -955,16 +955,16 @@ static const symbol s_30_9[6] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBD }; static const struct among a_30[10] = { -/* 0 */ { 10, s_30_0, -1, -1, 0}, -/* 1 */ { 6, s_30_1, -1, -1, 0}, -/* 2 */ { 10, s_30_2, -1, -1, 0}, -/* 3 */ { 10, s_30_3, -1, -1, 0}, -/* 4 */ { 10, s_30_4, -1, -1, 0}, -/* 5 */ { 10, s_30_5, -1, -1, 0}, -/* 6 */ { 6, s_30_6, -1, -1, 0}, -/* 7 */ { 4, s_30_7, -1, -1, 0}, -/* 8 */ { 6, s_30_8, -1, -1, 0}, -/* 9 */ { 6, s_30_9, -1, -1, 0} +{ 10, s_30_0, -1, -1, 0}, +{ 6, s_30_1, -1, -1, 0}, +{ 10, s_30_2, -1, -1, 0}, +{ 10, s_30_3, -1, -1, 0}, +{ 10, s_30_4, -1, -1, 0}, +{ 10, s_30_5, -1, -1, 0}, +{ 6, s_30_6, -1, -1, 0}, +{ 4, s_30_7, -1, -1, 0}, +{ 6, s_30_8, -1, -1, 0}, +{ 6, s_30_9, -1, -1, 0} }; static const symbol s_31_0[8] = { 0xCE, 0xB5, 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -972,8 +972,8 @@ static const symbol s_31_1[8] = { 0xCE, 0xB5, 0xCE, 0xB4, 0xCF, 0x89, 0xCE, 0xBD static const struct among a_31[2] = { -/* 0 */ { 8, s_31_0, -1, 1, 0}, -/* 1 */ { 8, s_31_1, -1, 1, 0} +{ 8, s_31_0, -1, 1, 0}, +{ 8, s_31_1, -1, 1, 0} }; static const symbol s_32_0[10] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x80 }; @@ -987,14 +987,14 @@ static const symbol s_32_7[6] = { 0xCE, 0xBC, 0xCE, 0xB9, 0xCE, 0xBB }; static const struct among a_32[8] = { -/* 0 */ { 10, s_32_0, -1, 1, 0}, -/* 1 */ { 4, s_32_1, -1, 1, 0}, -/* 2 */ { 6, s_32_2, -1, 1, 0}, -/* 3 */ { 6, s_32_3, -1, 1, 0}, -/* 4 */ { 4, s_32_4, -1, 1, 0}, -/* 5 */ { 6, s_32_5, -1, 1, 0}, -/* 6 */ { 4, s_32_6, -1, 1, 0}, -/* 7 */ { 6, s_32_7, -1, 1, 0} +{ 10, s_32_0, -1, 1, 0}, +{ 4, s_32_1, -1, 1, 0}, +{ 6, s_32_2, -1, 1, 0}, +{ 6, s_32_3, -1, 1, 0}, +{ 4, s_32_4, -1, 1, 0}, +{ 6, s_32_5, -1, 1, 0}, +{ 4, s_32_6, -1, 1, 0}, +{ 6, s_32_7, -1, 1, 0} }; static const symbol s_33_0[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -1002,8 +1002,8 @@ static const symbol s_33_1[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4, 0xCF, 0x8 static const struct among a_33[2] = { -/* 0 */ { 10, s_33_0, -1, 1, 0}, -/* 1 */ { 10, s_33_1, -1, 1, 0} +{ 10, s_33_0, -1, 1, 0}, +{ 10, s_33_1, -1, 1, 0} }; static const symbol s_34_0[4] = { 0xCF, 0x83, 0xCF, 0x80 }; @@ -1024,21 +1024,21 @@ static const symbol s_34_14[8] = { 0xCF, 0x80, 0xCE, 0xBB, 0xCE, 0xB5, 0xCE, 0xB static const struct among a_34[15] = { -/* 0 */ { 4, s_34_0, -1, 1, 0}, -/* 1 */ { 4, s_34_1, -1, 1, 0}, -/* 2 */ { 2, s_34_2, -1, 1, 0}, -/* 3 */ { 6, s_34_3, -1, 1, 0}, -/* 4 */ { 8, s_34_4, -1, 1, 0}, -/* 5 */ { 4, s_34_5, -1, 1, 0}, -/* 6 */ { 6, s_34_6, -1, 1, 0}, -/* 7 */ { 4, s_34_7, -1, 1, 0}, -/* 8 */ { 12, s_34_8, -1, 1, 0}, -/* 9 */ { 8, s_34_9, -1, 1, 0}, -/* 10 */ { 4, s_34_10, -1, 1, 0}, -/* 11 */ { 10, s_34_11, -1, 1, 0}, -/* 12 */ { 6, s_34_12, -1, 1, 0}, -/* 13 */ { 4, s_34_13, -1, 1, 0}, -/* 14 */ { 8, s_34_14, -1, 1, 0} +{ 4, s_34_0, -1, 1, 0}, +{ 4, s_34_1, -1, 1, 0}, +{ 2, s_34_2, -1, 1, 0}, +{ 6, s_34_3, -1, 1, 0}, +{ 8, s_34_4, -1, 1, 0}, +{ 4, s_34_5, -1, 1, 0}, +{ 6, s_34_6, -1, 1, 0}, +{ 4, s_34_7, -1, 1, 0}, +{ 12, s_34_8, -1, 1, 0}, +{ 8, s_34_9, -1, 1, 0}, +{ 4, s_34_10, -1, 1, 0}, +{ 10, s_34_11, -1, 1, 0}, +{ 6, s_34_12, -1, 1, 0}, +{ 4, s_34_13, -1, 1, 0}, +{ 8, s_34_14, -1, 1, 0} }; static const symbol s_35_0[6] = { 0xCE, 0xB5, 0xCF, 0x89, 0xCF, 0x83 }; @@ -1046,8 +1046,8 @@ static const symbol s_35_1[6] = { 0xCE, 0xB5, 0xCF, 0x89, 0xCE, 0xBD }; static const struct among a_35[2] = { -/* 0 */ { 6, s_35_0, -1, 1, 0}, -/* 1 */ { 6, s_35_1, -1, 1, 0} +{ 6, s_35_0, -1, 1, 0}, +{ 6, s_35_1, -1, 1, 0} }; static const symbol s_36_0[2] = { 0xCF, 0x80 }; @@ -1061,14 +1061,14 @@ static const symbol s_36_7[2] = { 0xCE, 0xBD }; static const struct among a_36[8] = { -/* 0 */ { 2, s_36_0, -1, 1, 0}, -/* 1 */ { 6, s_36_1, -1, 1, 0}, -/* 2 */ { 2, s_36_2, -1, 1, 0}, -/* 3 */ { 4, s_36_3, 2, 1, 0}, -/* 4 */ { 2, s_36_4, -1, 1, 0}, -/* 5 */ { 6, s_36_5, -1, 1, 0}, -/* 6 */ { 4, s_36_6, -1, 1, 0}, -/* 7 */ { 2, s_36_7, -1, 1, 0} +{ 2, s_36_0, -1, 1, 0}, +{ 6, s_36_1, -1, 1, 0}, +{ 2, s_36_2, -1, 1, 0}, +{ 4, s_36_3, 2, 1, 0}, +{ 2, s_36_4, -1, 1, 0}, +{ 6, s_36_5, -1, 1, 0}, +{ 4, s_36_6, -1, 1, 0}, +{ 2, s_36_7, -1, 1, 0} }; static const symbol s_37_0[6] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85 }; @@ -1077,9 +1077,9 @@ static const symbol s_37_2[6] = { 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; static const struct among a_37[3] = { -/* 0 */ { 6, s_37_0, -1, 1, 0}, -/* 1 */ { 4, s_37_1, -1, 1, 0}, -/* 2 */ { 6, s_37_2, -1, 1, 0} +{ 6, s_37_0, -1, 1, 0}, +{ 4, s_37_1, -1, 1, 0}, +{ 6, s_37_2, -1, 1, 0} }; static const symbol s_38_0[8] = { 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x85 }; @@ -1089,10 +1089,10 @@ static const symbol s_38_3[6] = { 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBF }; static const struct among a_38[4] = { -/* 0 */ { 8, s_38_0, -1, 1, 0}, -/* 1 */ { 6, s_38_1, -1, 1, 0}, -/* 2 */ { 8, s_38_2, -1, 1, 0}, -/* 3 */ { 6, s_38_3, -1, 1, 0} +{ 8, s_38_0, -1, 1, 0}, +{ 6, s_38_1, -1, 1, 0}, +{ 8, s_38_2, -1, 1, 0}, +{ 6, s_38_3, -1, 1, 0} }; static const symbol s_39_0[8] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB, 0xCF, 0x80 }; @@ -1134,42 +1134,42 @@ static const symbol s_39_35[10] = { 0xCF, 0x86, 0xCE, 0xB9, 0xCE, 0xBB, 0xCE, 0x static const struct among a_39[36] = { -/* 0 */ { 8, s_39_0, -1, 1, 0}, -/* 1 */ { 6, s_39_1, -1, 1, 0}, -/* 2 */ { 12, s_39_2, -1, 1, 0}, -/* 3 */ { 8, s_39_3, -1, 1, 0}, -/* 4 */ { 8, s_39_4, -1, 1, 0}, -/* 5 */ { 6, s_39_5, -1, 1, 0}, -/* 6 */ { 6, s_39_6, -1, 1, 0}, -/* 7 */ { 8, s_39_7, -1, 1, 0}, -/* 8 */ { 8, s_39_8, -1, 1, 0}, -/* 9 */ { 14, s_39_9, -1, 1, 0}, -/* 10 */ { 6, s_39_10, -1, 1, 0}, -/* 11 */ { 12, s_39_11, -1, 1, 0}, -/* 12 */ { 8, s_39_12, -1, 1, 0}, -/* 13 */ { 4, s_39_13, -1, 1, 0}, -/* 14 */ { 10, s_39_14, 13, 1, 0}, -/* 15 */ { 10, s_39_15, 13, 1, 0}, -/* 16 */ { 10, s_39_16, -1, 1, 0}, -/* 17 */ { 6, s_39_17, -1, 1, 0}, -/* 18 */ { 8, s_39_18, -1, 1, 0}, -/* 19 */ { 12, s_39_19, -1, 1, 0}, -/* 20 */ { 10, s_39_20, -1, 1, 0}, -/* 21 */ { 4, s_39_21, -1, 1, 0}, -/* 22 */ { 8, s_39_22, 21, 1, 0}, -/* 23 */ { 6, s_39_23, -1, 1, 0}, -/* 24 */ { 8, s_39_24, -1, 1, 0}, -/* 25 */ { 4, s_39_25, -1, 1, 0}, -/* 26 */ { 14, s_39_26, 25, 1, 0}, -/* 27 */ { 14, s_39_27, -1, 1, 0}, -/* 28 */ { 8, s_39_28, -1, 1, 0}, -/* 29 */ { 8, s_39_29, -1, 1, 0}, -/* 30 */ { 8, s_39_30, -1, 1, 0}, -/* 31 */ { 8, s_39_31, -1, 1, 0}, -/* 32 */ { 8, s_39_32, -1, 1, 0}, -/* 33 */ { 12, s_39_33, -1, 1, 0}, -/* 34 */ { 14, s_39_34, -1, 1, 0}, -/* 35 */ { 10, s_39_35, -1, 1, 0} +{ 8, s_39_0, -1, 1, 0}, +{ 6, s_39_1, -1, 1, 0}, +{ 12, s_39_2, -1, 1, 0}, +{ 8, s_39_3, -1, 1, 0}, +{ 8, s_39_4, -1, 1, 0}, +{ 6, s_39_5, -1, 1, 0}, +{ 6, s_39_6, -1, 1, 0}, +{ 8, s_39_7, -1, 1, 0}, +{ 8, s_39_8, -1, 1, 0}, +{ 14, s_39_9, -1, 1, 0}, +{ 6, s_39_10, -1, 1, 0}, +{ 12, s_39_11, -1, 1, 0}, +{ 8, s_39_12, -1, 1, 0}, +{ 4, s_39_13, -1, 1, 0}, +{ 10, s_39_14, 13, 1, 0}, +{ 10, s_39_15, 13, 1, 0}, +{ 10, s_39_16, -1, 1, 0}, +{ 6, s_39_17, -1, 1, 0}, +{ 8, s_39_18, -1, 1, 0}, +{ 12, s_39_19, -1, 1, 0}, +{ 10, s_39_20, -1, 1, 0}, +{ 4, s_39_21, -1, 1, 0}, +{ 8, s_39_22, 21, 1, 0}, +{ 6, s_39_23, -1, 1, 0}, +{ 8, s_39_24, -1, 1, 0}, +{ 4, s_39_25, -1, 1, 0}, +{ 14, s_39_26, 25, 1, 0}, +{ 14, s_39_27, -1, 1, 0}, +{ 8, s_39_28, -1, 1, 0}, +{ 8, s_39_29, -1, 1, 0}, +{ 8, s_39_30, -1, 1, 0}, +{ 8, s_39_31, -1, 1, 0}, +{ 8, s_39_32, -1, 1, 0}, +{ 12, s_39_33, -1, 1, 0}, +{ 14, s_39_34, -1, 1, 0}, +{ 10, s_39_35, -1, 1, 0} }; static const symbol s_40_0[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; @@ -1180,11 +1180,11 @@ static const symbol s_40_4[14] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xB static const struct among a_40[5] = { -/* 0 */ { 12, s_40_0, -1, 1, 0}, -/* 1 */ { 10, s_40_1, -1, 1, 0}, -/* 2 */ { 10, s_40_2, -1, 1, 0}, -/* 3 */ { 10, s_40_3, -1, 1, 0}, -/* 4 */ { 14, s_40_4, 3, 1, 0} +{ 12, s_40_0, -1, 1, 0}, +{ 10, s_40_1, -1, 1, 0}, +{ 10, s_40_2, -1, 1, 0}, +{ 10, s_40_3, -1, 1, 0}, +{ 14, s_40_4, 3, 1, 0} }; static const symbol s_41_0[8] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x80 }; @@ -1202,18 +1202,18 @@ static const symbol s_41_11[6] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB }; static const struct among a_41[12] = { -/* 0 */ { 8, s_41_0, -1, 1, 0}, -/* 1 */ { 8, s_41_1, -1, 1, 0}, -/* 2 */ { 10, s_41_2, -1, 1, 0}, -/* 3 */ { 6, s_41_3, -1, 1, 0}, -/* 4 */ { 2, s_41_4, -1, 1, 0}, -/* 5 */ { 6, s_41_5, 4, 1, 0}, -/* 6 */ { 8, s_41_6, -1, 1, 0}, -/* 7 */ { 6, s_41_7, -1, 1, 0}, -/* 8 */ { 6, s_41_8, -1, 1, 0}, -/* 9 */ { 8, s_41_9, -1, 1, 0}, -/* 10 */ { 8, s_41_10, -1, 1, 0}, -/* 11 */ { 6, s_41_11, -1, 1, 0} +{ 8, s_41_0, -1, 1, 0}, +{ 8, s_41_1, -1, 1, 0}, +{ 10, s_41_2, -1, 1, 0}, +{ 6, s_41_3, -1, 1, 0}, +{ 2, s_41_4, -1, 1, 0}, +{ 6, s_41_5, 4, 1, 0}, +{ 8, s_41_6, -1, 1, 0}, +{ 6, s_41_7, -1, 1, 0}, +{ 6, s_41_8, -1, 1, 0}, +{ 8, s_41_9, -1, 1, 0}, +{ 8, s_41_10, -1, 1, 0}, +{ 6, s_41_11, -1, 1, 0} }; static const symbol s_42_0[4] = { 0xCF, 0x84, 0xCF, 0x81 }; @@ -1221,8 +1221,8 @@ static const symbol s_42_1[4] = { 0xCF, 0x84, 0xCF, 0x83 }; static const struct among a_42[2] = { -/* 0 */ { 4, s_42_0, -1, 1, 0}, -/* 1 */ { 4, s_42_1, -1, 1, 0} +{ 4, s_42_0, -1, 1, 0}, +{ 4, s_42_1, -1, 1, 0} }; static const symbol s_43_0[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; @@ -1239,17 +1239,17 @@ static const symbol s_43_10[14] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0x static const struct among a_43[11] = { -/* 0 */ { 12, s_43_0, -1, 1, 0}, -/* 1 */ { 10, s_43_1, -1, 1, 0}, -/* 2 */ { 14, s_43_2, -1, 1, 0}, -/* 3 */ { 16, s_43_3, 2, 1, 0}, -/* 4 */ { 12, s_43_4, -1, 1, 0}, -/* 5 */ { 14, s_43_5, 4, 1, 0}, -/* 6 */ { 10, s_43_6, -1, 1, 0}, -/* 7 */ { 12, s_43_7, 6, 1, 0}, -/* 8 */ { 10, s_43_8, -1, 1, 0}, -/* 9 */ { 10, s_43_9, -1, 1, 0}, -/* 10 */ { 14, s_43_10, 9, 1, 0} +{ 12, s_43_0, -1, 1, 0}, +{ 10, s_43_1, -1, 1, 0}, +{ 14, s_43_2, -1, 1, 0}, +{ 16, s_43_3, 2, 1, 0}, +{ 12, s_43_4, -1, 1, 0}, +{ 14, s_43_5, 4, 1, 0}, +{ 10, s_43_6, -1, 1, 0}, +{ 12, s_43_7, 6, 1, 0}, +{ 10, s_43_8, -1, 1, 0}, +{ 10, s_43_9, -1, 1, 0}, +{ 14, s_43_10, 9, 1, 0} }; static const symbol s_44_0[2] = { 0xCF, 0x80 }; @@ -1350,108 +1350,108 @@ static const symbol s_44_94[16] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x static const struct among a_44[95] = { -/* 0 */ { 2, s_44_0, -1, 1, 0}, -/* 1 */ { 4, s_44_1, 0, 1, 0}, -/* 2 */ { 14, s_44_2, 0, 1, 0}, -/* 3 */ { 8, s_44_3, 0, 1, 0}, -/* 4 */ { 18, s_44_4, 0, 1, 0}, -/* 5 */ { 8, s_44_5, 0, 1, 0}, -/* 6 */ { 6, s_44_6, 0, 1, 0}, -/* 7 */ { 12, s_44_7, 6, 1, 0}, -/* 8 */ { 12, s_44_8, -1, 1, 0}, -/* 9 */ { 6, s_44_9, -1, 1, 0}, -/* 10 */ { 4, s_44_10, -1, 1, 0}, -/* 11 */ { 10, s_44_11, 10, 1, 0}, -/* 12 */ { 6, s_44_12, 10, 1, 0}, -/* 13 */ { 12, s_44_13, -1, 1, 0}, -/* 14 */ { 12, s_44_14, -1, 1, 0}, -/* 15 */ { 2, s_44_15, -1, 1, 0}, -/* 16 */ { 16, s_44_16, 15, 1, 0}, -/* 17 */ { 6, s_44_17, 15, 1, 0}, -/* 18 */ { 6, s_44_18, 15, 1, 0}, -/* 19 */ { 10, s_44_19, 15, 1, 0}, -/* 20 */ { 8, s_44_20, -1, 1, 0}, -/* 21 */ { 8, s_44_21, -1, 1, 0}, -/* 22 */ { 8, s_44_22, -1, 1, 0}, -/* 23 */ { 14, s_44_23, -1, 1, 0}, -/* 24 */ { 6, s_44_24, -1, 1, 0}, -/* 25 */ { 12, s_44_25, -1, 1, 0}, -/* 26 */ { 10, s_44_26, -1, 1, 0}, -/* 27 */ { 8, s_44_27, -1, 1, 0}, -/* 28 */ { 10, s_44_28, -1, 1, 0}, -/* 29 */ { 2, s_44_29, -1, 1, 0}, -/* 30 */ { 14, s_44_30, 29, 1, 0}, -/* 31 */ { 14, s_44_31, 29, 1, 0}, -/* 32 */ { 6, s_44_32, 29, 1, 0}, -/* 33 */ { 8, s_44_33, 29, 1, 0}, -/* 34 */ { 8, s_44_34, 29, 1, 0}, -/* 35 */ { 16, s_44_35, 34, 1, 0}, -/* 36 */ { 10, s_44_36, 29, 1, 0}, -/* 37 */ { 12, s_44_37, 36, 1, 0}, -/* 38 */ { 2, s_44_38, -1, 1, 0}, -/* 39 */ { 14, s_44_39, 38, 1, 0}, -/* 40 */ { 8, s_44_40, 38, 1, 0}, -/* 41 */ { 12, s_44_41, 38, 1, 0}, -/* 42 */ { 22, s_44_42, 41, 1, 0}, -/* 43 */ { 22, s_44_43, 41, 1, 0}, -/* 44 */ { 22, s_44_44, 41, 1, 0}, -/* 45 */ { 6, s_44_45, 38, 1, 0}, -/* 46 */ { 6, s_44_46, -1, 1, 0}, -/* 47 */ { 8, s_44_47, 46, 1, 0}, -/* 48 */ { 14, s_44_48, 46, 1, 0}, -/* 49 */ { 6, s_44_49, -1, 1, 0}, -/* 50 */ { 8, s_44_50, 49, 1, 0}, -/* 51 */ { 16, s_44_51, 50, 1, 0}, -/* 52 */ { 2, s_44_52, -1, 1, 0}, -/* 53 */ { 10, s_44_53, 52, 1, 0}, -/* 54 */ { 10, s_44_54, 52, 1, 0}, -/* 55 */ { 4, s_44_55, 52, 1, 0}, -/* 56 */ { 8, s_44_56, 55, 1, 0}, -/* 57 */ { 8, s_44_57, 55, 1, 0}, -/* 58 */ { 10, s_44_58, 52, 1, 0}, -/* 59 */ { 12, s_44_59, 58, 1, 0}, -/* 60 */ { 10, s_44_60, 52, 1, 0}, -/* 61 */ { 8, s_44_61, 52, 1, 0}, -/* 62 */ { 8, s_44_62, 52, 1, 0}, -/* 63 */ { 6, s_44_63, 52, 1, 0}, -/* 64 */ { 14, s_44_64, -1, 1, 0}, -/* 65 */ { 2, s_44_65, -1, 1, 0}, -/* 66 */ { 12, s_44_66, 65, 1, 0}, -/* 67 */ { 6, s_44_67, 65, 1, 0}, -/* 68 */ { 8, s_44_68, 67, 1, 0}, -/* 69 */ { 8, s_44_69, -1, 1, 0}, -/* 70 */ { 12, s_44_70, -1, 1, 0}, -/* 71 */ { 6, s_44_71, -1, 1, 0}, -/* 72 */ { 10, s_44_72, -1, 1, 0}, -/* 73 */ { 4, s_44_73, -1, 1, 0}, -/* 74 */ { 8, s_44_74, 73, 1, 0}, -/* 75 */ { 10, s_44_75, -1, 1, 0}, -/* 76 */ { 4, s_44_76, -1, 1, 0}, -/* 77 */ { 8, s_44_77, 76, 1, 0}, -/* 78 */ { 12, s_44_78, 76, 1, 0}, -/* 79 */ { 10, s_44_79, 76, 1, 0}, -/* 80 */ { 6, s_44_80, -1, 1, 0}, -/* 81 */ { 6, s_44_81, -1, 1, 0}, -/* 82 */ { 14, s_44_82, 81, 1, 0}, -/* 83 */ { 14, s_44_83, 81, 1, 0}, -/* 84 */ { 12, s_44_84, 81, 1, 0}, -/* 85 */ { 12, s_44_85, -1, 1, 0}, -/* 86 */ { 6, s_44_86, -1, 1, 0}, -/* 87 */ { 12, s_44_87, -1, 1, 0}, -/* 88 */ { 2, s_44_88, -1, 1, 0}, -/* 89 */ { 14, s_44_89, 88, 1, 0}, -/* 90 */ { 10, s_44_90, 88, 1, 0}, -/* 91 */ { 16, s_44_91, 88, 1, 0}, -/* 92 */ { 16, s_44_92, 88, 1, 0}, -/* 93 */ { 2, s_44_93, -1, 1, 0}, -/* 94 */ { 16, s_44_94, 93, 1, 0} +{ 2, s_44_0, -1, 1, 0}, +{ 4, s_44_1, 0, 1, 0}, +{ 14, s_44_2, 0, 1, 0}, +{ 8, s_44_3, 0, 1, 0}, +{ 18, s_44_4, 0, 1, 0}, +{ 8, s_44_5, 0, 1, 0}, +{ 6, s_44_6, 0, 1, 0}, +{ 12, s_44_7, 6, 1, 0}, +{ 12, s_44_8, -1, 1, 0}, +{ 6, s_44_9, -1, 1, 0}, +{ 4, s_44_10, -1, 1, 0}, +{ 10, s_44_11, 10, 1, 0}, +{ 6, s_44_12, 10, 1, 0}, +{ 12, s_44_13, -1, 1, 0}, +{ 12, s_44_14, -1, 1, 0}, +{ 2, s_44_15, -1, 1, 0}, +{ 16, s_44_16, 15, 1, 0}, +{ 6, s_44_17, 15, 1, 0}, +{ 6, s_44_18, 15, 1, 0}, +{ 10, s_44_19, 15, 1, 0}, +{ 8, s_44_20, -1, 1, 0}, +{ 8, s_44_21, -1, 1, 0}, +{ 8, s_44_22, -1, 1, 0}, +{ 14, s_44_23, -1, 1, 0}, +{ 6, s_44_24, -1, 1, 0}, +{ 12, s_44_25, -1, 1, 0}, +{ 10, s_44_26, -1, 1, 0}, +{ 8, s_44_27, -1, 1, 0}, +{ 10, s_44_28, -1, 1, 0}, +{ 2, s_44_29, -1, 1, 0}, +{ 14, s_44_30, 29, 1, 0}, +{ 14, s_44_31, 29, 1, 0}, +{ 6, s_44_32, 29, 1, 0}, +{ 8, s_44_33, 29, 1, 0}, +{ 8, s_44_34, 29, 1, 0}, +{ 16, s_44_35, 34, 1, 0}, +{ 10, s_44_36, 29, 1, 0}, +{ 12, s_44_37, 36, 1, 0}, +{ 2, s_44_38, -1, 1, 0}, +{ 14, s_44_39, 38, 1, 0}, +{ 8, s_44_40, 38, 1, 0}, +{ 12, s_44_41, 38, 1, 0}, +{ 22, s_44_42, 41, 1, 0}, +{ 22, s_44_43, 41, 1, 0}, +{ 22, s_44_44, 41, 1, 0}, +{ 6, s_44_45, 38, 1, 0}, +{ 6, s_44_46, -1, 1, 0}, +{ 8, s_44_47, 46, 1, 0}, +{ 14, s_44_48, 46, 1, 0}, +{ 6, s_44_49, -1, 1, 0}, +{ 8, s_44_50, 49, 1, 0}, +{ 16, s_44_51, 50, 1, 0}, +{ 2, s_44_52, -1, 1, 0}, +{ 10, s_44_53, 52, 1, 0}, +{ 10, s_44_54, 52, 1, 0}, +{ 4, s_44_55, 52, 1, 0}, +{ 8, s_44_56, 55, 1, 0}, +{ 8, s_44_57, 55, 1, 0}, +{ 10, s_44_58, 52, 1, 0}, +{ 12, s_44_59, 58, 1, 0}, +{ 10, s_44_60, 52, 1, 0}, +{ 8, s_44_61, 52, 1, 0}, +{ 8, s_44_62, 52, 1, 0}, +{ 6, s_44_63, 52, 1, 0}, +{ 14, s_44_64, -1, 1, 0}, +{ 2, s_44_65, -1, 1, 0}, +{ 12, s_44_66, 65, 1, 0}, +{ 6, s_44_67, 65, 1, 0}, +{ 8, s_44_68, 67, 1, 0}, +{ 8, s_44_69, -1, 1, 0}, +{ 12, s_44_70, -1, 1, 0}, +{ 6, s_44_71, -1, 1, 0}, +{ 10, s_44_72, -1, 1, 0}, +{ 4, s_44_73, -1, 1, 0}, +{ 8, s_44_74, 73, 1, 0}, +{ 10, s_44_75, -1, 1, 0}, +{ 4, s_44_76, -1, 1, 0}, +{ 8, s_44_77, 76, 1, 0}, +{ 12, s_44_78, 76, 1, 0}, +{ 10, s_44_79, 76, 1, 0}, +{ 6, s_44_80, -1, 1, 0}, +{ 6, s_44_81, -1, 1, 0}, +{ 14, s_44_82, 81, 1, 0}, +{ 14, s_44_83, 81, 1, 0}, +{ 12, s_44_84, 81, 1, 0}, +{ 12, s_44_85, -1, 1, 0}, +{ 6, s_44_86, -1, 1, 0}, +{ 12, s_44_87, -1, 1, 0}, +{ 2, s_44_88, -1, 1, 0}, +{ 14, s_44_89, 88, 1, 0}, +{ 10, s_44_90, 88, 1, 0}, +{ 16, s_44_91, 88, 1, 0}, +{ 16, s_44_92, 88, 1, 0}, +{ 2, s_44_93, -1, 1, 0}, +{ 16, s_44_94, 93, 1, 0} }; static const symbol s_45_0[10] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5 }; static const struct among a_45[1] = { -/* 0 */ { 10, s_45_0, -1, 1, 0} +{ 10, s_45_0, -1, 1, 0} }; static const symbol s_46_0[6] = { 0xCF, 0x80, 0xCF, 0x85, 0xCF, 0x81 }; @@ -1488,37 +1488,37 @@ static const symbol s_46_30[6] = { 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xBD }; static const struct among a_46[31] = { -/* 0 */ { 6, s_46_0, -1, 1, 0}, -/* 1 */ { 6, s_46_1, -1, 1, 0}, -/* 2 */ { 6, s_46_2, -1, 1, 0}, -/* 3 */ { 6, s_46_3, -1, 1, 0}, -/* 4 */ { 4, s_46_4, -1, 1, 0}, -/* 5 */ { 6, s_46_5, -1, 1, 0}, -/* 6 */ { 6, s_46_6, -1, 1, 0}, -/* 7 */ { 6, s_46_7, -1, 1, 0}, -/* 8 */ { 4, s_46_8, -1, 1, 0}, -/* 9 */ { 8, s_46_9, -1, 1, 0}, -/* 10 */ { 6, s_46_10, -1, 1, 0}, -/* 11 */ { 4, s_46_11, -1, 1, 0}, -/* 12 */ { 10, s_46_12, -1, 1, 0}, -/* 13 */ { 4, s_46_13, -1, 1, 0}, -/* 14 */ { 6, s_46_14, -1, 1, 0}, -/* 15 */ { 6, s_46_15, -1, 1, 0}, -/* 16 */ { 6, s_46_16, -1, 1, 0}, -/* 17 */ { 8, s_46_17, -1, 1, 0}, -/* 18 */ { 6, s_46_18, -1, 1, 0}, -/* 19 */ { 6, s_46_19, -1, 1, 0}, -/* 20 */ { 6, s_46_20, -1, 1, 0}, -/* 21 */ { 8, s_46_21, -1, 1, 0}, -/* 22 */ { 6, s_46_22, -1, 1, 0}, -/* 23 */ { 6, s_46_23, -1, 1, 0}, -/* 24 */ { 6, s_46_24, -1, 1, 0}, -/* 25 */ { 8, s_46_25, -1, 1, 0}, -/* 26 */ { 6, s_46_26, -1, 1, 0}, -/* 27 */ { 6, s_46_27, -1, 1, 0}, -/* 28 */ { 6, s_46_28, -1, 1, 0}, -/* 29 */ { 6, s_46_29, -1, 1, 0}, -/* 30 */ { 6, s_46_30, -1, 1, 0} +{ 6, s_46_0, -1, 1, 0}, +{ 6, s_46_1, -1, 1, 0}, +{ 6, s_46_2, -1, 1, 0}, +{ 6, s_46_3, -1, 1, 0}, +{ 4, s_46_4, -1, 1, 0}, +{ 6, s_46_5, -1, 1, 0}, +{ 6, s_46_6, -1, 1, 0}, +{ 6, s_46_7, -1, 1, 0}, +{ 4, s_46_8, -1, 1, 0}, +{ 8, s_46_9, -1, 1, 0}, +{ 6, s_46_10, -1, 1, 0}, +{ 4, s_46_11, -1, 1, 0}, +{ 10, s_46_12, -1, 1, 0}, +{ 4, s_46_13, -1, 1, 0}, +{ 6, s_46_14, -1, 1, 0}, +{ 6, s_46_15, -1, 1, 0}, +{ 6, s_46_16, -1, 1, 0}, +{ 8, s_46_17, -1, 1, 0}, +{ 6, s_46_18, -1, 1, 0}, +{ 6, s_46_19, -1, 1, 0}, +{ 6, s_46_20, -1, 1, 0}, +{ 8, s_46_21, -1, 1, 0}, +{ 6, s_46_22, -1, 1, 0}, +{ 6, s_46_23, -1, 1, 0}, +{ 6, s_46_24, -1, 1, 0}, +{ 8, s_46_25, -1, 1, 0}, +{ 6, s_46_26, -1, 1, 0}, +{ 6, s_46_27, -1, 1, 0}, +{ 6, s_46_28, -1, 1, 0}, +{ 6, s_46_29, -1, 1, 0}, +{ 6, s_46_30, -1, 1, 0} }; static const symbol s_47_0[8] = { 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x81, 0xCF, 0x80 }; @@ -1549,31 +1549,31 @@ static const symbol s_47_24[10] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0x static const struct among a_47[25] = { -/* 0 */ { 8, s_47_0, -1, 1, 0}, -/* 1 */ { 6, s_47_1, -1, 1, 0}, -/* 2 */ { 8, s_47_2, -1, 1, 0}, -/* 3 */ { 6, s_47_3, -1, 1, 0}, -/* 4 */ { 8, s_47_4, -1, 1, 0}, -/* 5 */ { 8, s_47_5, -1, 1, 0}, -/* 6 */ { 6, s_47_6, -1, 1, 0}, -/* 7 */ { 8, s_47_7, -1, 1, 0}, -/* 8 */ { 2, s_47_8, -1, 1, 0}, -/* 9 */ { 8, s_47_9, -1, 1, 0}, -/* 10 */ { 6, s_47_10, -1, 1, 0}, -/* 11 */ { 6, s_47_11, -1, 1, 0}, -/* 12 */ { 2, s_47_12, -1, 1, 0}, -/* 13 */ { 4, s_47_13, 12, 1, 0}, -/* 14 */ { 2, s_47_14, -1, 1, 0}, -/* 15 */ { 4, s_47_15, 14, 1, 0}, -/* 16 */ { 4, s_47_16, -1, 1, 0}, -/* 17 */ { 6, s_47_17, -1, 1, 0}, -/* 18 */ { 6, s_47_18, -1, 1, 0}, -/* 19 */ { 14, s_47_19, -1, 1, 0}, -/* 20 */ { 8, s_47_20, -1, 1, 0}, -/* 21 */ { 4, s_47_21, -1, 1, 0}, -/* 22 */ { 4, s_47_22, -1, 1, 0}, -/* 23 */ { 6, s_47_23, -1, 1, 0}, -/* 24 */ { 10, s_47_24, -1, 1, 0} +{ 8, s_47_0, -1, 1, 0}, +{ 6, s_47_1, -1, 1, 0}, +{ 8, s_47_2, -1, 1, 0}, +{ 6, s_47_3, -1, 1, 0}, +{ 8, s_47_4, -1, 1, 0}, +{ 8, s_47_5, -1, 1, 0}, +{ 6, s_47_6, -1, 1, 0}, +{ 8, s_47_7, -1, 1, 0}, +{ 2, s_47_8, -1, 1, 0}, +{ 8, s_47_9, -1, 1, 0}, +{ 6, s_47_10, -1, 1, 0}, +{ 6, s_47_11, -1, 1, 0}, +{ 2, s_47_12, -1, 1, 0}, +{ 4, s_47_13, 12, 1, 0}, +{ 2, s_47_14, -1, 1, 0}, +{ 4, s_47_15, 14, 1, 0}, +{ 4, s_47_16, -1, 1, 0}, +{ 6, s_47_17, -1, 1, 0}, +{ 6, s_47_18, -1, 1, 0}, +{ 14, s_47_19, -1, 1, 0}, +{ 8, s_47_20, -1, 1, 0}, +{ 4, s_47_21, -1, 1, 0}, +{ 4, s_47_22, -1, 1, 0}, +{ 6, s_47_23, -1, 1, 0}, +{ 10, s_47_24, -1, 1, 0} }; static const symbol s_48_0[10] = { 0xCF, 0x89, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x83 }; @@ -1581,8 +1581,8 @@ static const symbol s_48_1[10] = { 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB static const struct among a_48[2] = { -/* 0 */ { 10, s_48_0, -1, 1, 0}, -/* 1 */ { 10, s_48_1, -1, 1, 0} +{ 10, s_48_0, -1, 1, 0}, +{ 10, s_48_1, -1, 1, 0} }; static const symbol s_49_0[12] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; @@ -1590,8 +1590,8 @@ static const symbol s_49_1[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB static const struct among a_49[2] = { -/* 0 */ { 12, s_49_0, -1, 1, 0}, -/* 1 */ { 14, s_49_1, 0, 1, 0} +{ 12, s_49_0, -1, 1, 0}, +{ 14, s_49_1, 0, 1, 0} }; static const symbol s_50_0[2] = { 0xCF, 0x80 }; @@ -1603,12 +1603,12 @@ static const symbol s_50_5[14] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x8 static const struct among a_50[6] = { -/* 0 */ { 2, s_50_0, -1, 1, 0}, -/* 1 */ { 4, s_50_1, 0, 1, 0}, -/* 2 */ { 12, s_50_2, 1, 1, 0}, -/* 3 */ { 8, s_50_3, 0, 1, 0}, -/* 4 */ { 10, s_50_4, 3, 1, 0}, -/* 5 */ { 14, s_50_5, -1, 1, 0} +{ 2, s_50_0, -1, 1, 0}, +{ 4, s_50_1, 0, 1, 0}, +{ 12, s_50_2, 1, 1, 0}, +{ 8, s_50_3, 0, 1, 0}, +{ 10, s_50_4, 3, 1, 0}, +{ 14, s_50_5, -1, 1, 0} }; static const symbol s_51_0[4] = { 0xCE, 0xB1, 0xCF, 0x81 }; @@ -1623,15 +1623,15 @@ static const symbol s_51_8[6] = { 0xCF, 0x80, 0xCF, 0x81, 0xCE, 0xBF }; static const struct among a_51[9] = { -/* 0 */ { 4, s_51_0, -1, 1, 0}, -/* 1 */ { 6, s_51_1, -1, 1, 0}, -/* 2 */ { 2, s_51_2, -1, 1, 0}, -/* 3 */ { 4, s_51_3, -1, 1, 0}, -/* 4 */ { 14, s_51_4, 3, 1, 0}, -/* 5 */ { 10, s_51_5, -1, 1, 0}, -/* 6 */ { 2, s_51_6, -1, 1, 0}, -/* 7 */ { 2, s_51_7, -1, 1, 0}, -/* 8 */ { 6, s_51_8, -1, 1, 0} +{ 4, s_51_0, -1, 1, 0}, +{ 6, s_51_1, -1, 1, 0}, +{ 2, s_51_2, -1, 1, 0}, +{ 4, s_51_3, -1, 1, 0}, +{ 14, s_51_4, 3, 1, 0}, +{ 10, s_51_5, -1, 1, 0}, +{ 2, s_51_6, -1, 1, 0}, +{ 2, s_51_7, -1, 1, 0}, +{ 6, s_51_8, -1, 1, 0} }; static const symbol s_52_0[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -1640,9 +1640,9 @@ static const symbol s_52_2[10] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xB static const struct among a_52[3] = { -/* 0 */ { 12, s_52_0, -1, 1, 0}, -/* 1 */ { 10, s_52_1, -1, 1, 0}, -/* 2 */ { 10, s_52_2, -1, 1, 0} +{ 12, s_52_0, -1, 1, 0}, +{ 10, s_52_1, -1, 1, 0}, +{ 10, s_52_2, -1, 1, 0} }; static const symbol s_53_0[4] = { 0xCF, 0x83, 0xCF, 0x86 }; @@ -1654,12 +1654,12 @@ static const symbol s_53_5[8] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCF, 0x89, 0xCE, 0xBB static const struct among a_53[6] = { -/* 0 */ { 4, s_53_0, -1, 1, 0}, -/* 1 */ { 8, s_53_1, -1, 1, 0}, -/* 2 */ { 6, s_53_2, -1, 1, 0}, -/* 3 */ { 4, s_53_3, -1, 1, 0}, -/* 4 */ { 10, s_53_4, -1, 1, 0}, -/* 5 */ { 8, s_53_5, -1, 1, 0} +{ 4, s_53_0, -1, 1, 0}, +{ 8, s_53_1, -1, 1, 0}, +{ 6, s_53_2, -1, 1, 0}, +{ 4, s_53_3, -1, 1, 0}, +{ 10, s_53_4, -1, 1, 0}, +{ 8, s_53_5, -1, 1, 0} }; static const symbol s_54_0[2] = { 0xCE, 0xB8 }; @@ -1670,11 +1670,11 @@ static const symbol s_54_4[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB8 static const struct among a_54[5] = { -/* 0 */ { 2, s_54_0, -1, 1, 0}, -/* 1 */ { 10, s_54_1, 0, 1, 0}, -/* 2 */ { 18, s_54_2, 0, 1, 0}, -/* 3 */ { 8, s_54_3, 0, 1, 0}, -/* 4 */ { 8, s_54_4, 0, 1, 0} +{ 2, s_54_0, -1, 1, 0}, +{ 10, s_54_1, 0, 1, 0}, +{ 18, s_54_2, 0, 1, 0}, +{ 8, s_54_3, 0, 1, 0}, +{ 8, s_54_4, 0, 1, 0} }; static const symbol s_55_0[8] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -1683,9 +1683,9 @@ static const symbol s_55_2[6] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5 }; static const struct among a_55[3] = { -/* 0 */ { 8, s_55_0, -1, 1, 0}, -/* 1 */ { 6, s_55_1, -1, 1, 0}, -/* 2 */ { 6, s_55_2, -1, 1, 0} +{ 8, s_55_0, -1, 1, 0}, +{ 6, s_55_1, -1, 1, 0}, +{ 6, s_55_2, -1, 1, 0} }; static const symbol s_56_0[8] = { 0xCE, 0xB2, 0xCE, 0xBB, 0xCE, 0xB5, 0xCF, 0x80 }; @@ -1703,18 +1703,18 @@ static const symbol s_56_11[4] = { 0xCE, 0xBF, 0xCE, 0xBC }; static const struct among a_56[12] = { -/* 0 */ { 8, s_56_0, -1, 1, 0}, -/* 1 */ { 10, s_56_1, -1, 1, 0}, -/* 2 */ { 8, s_56_2, -1, 1, 0}, -/* 3 */ { 10, s_56_3, -1, 1, 0}, -/* 4 */ { 12, s_56_4, -1, 1, 0}, -/* 5 */ { 6, s_56_5, -1, 1, 0}, -/* 6 */ { 6, s_56_6, -1, 1, 0}, -/* 7 */ { 6, s_56_7, -1, 1, 0}, -/* 8 */ { 8, s_56_8, -1, 1, 0}, -/* 9 */ { 12, s_56_9, -1, 1, 0}, -/* 10 */ { 8, s_56_10, -1, 1, 0}, -/* 11 */ { 4, s_56_11, -1, 1, 0} +{ 8, s_56_0, -1, 1, 0}, +{ 10, s_56_1, -1, 1, 0}, +{ 8, s_56_2, -1, 1, 0}, +{ 10, s_56_3, -1, 1, 0}, +{ 12, s_56_4, -1, 1, 0}, +{ 6, s_56_5, -1, 1, 0}, +{ 6, s_56_6, -1, 1, 0}, +{ 6, s_56_7, -1, 1, 0}, +{ 8, s_56_8, -1, 1, 0}, +{ 12, s_56_9, -1, 1, 0}, +{ 8, s_56_10, -1, 1, 0}, +{ 4, s_56_11, -1, 1, 0} }; static const symbol s_57_0[10] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB9, 0xCF, 0x80 }; @@ -1745,31 +1745,31 @@ static const symbol s_57_24[14] = { 0xCF, 0x85, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x static const struct among a_57[25] = { -/* 0 */ { 10, s_57_0, -1, 1, 0}, -/* 1 */ { 2, s_57_1, -1, 1, 0}, -/* 2 */ { 10, s_57_2, 1, 1, 0}, -/* 3 */ { 16, s_57_3, 1, 1, 0}, -/* 4 */ { 6, s_57_4, -1, 1, 0}, -/* 5 */ { 14, s_57_5, -1, 1, 0}, -/* 6 */ { 16, s_57_6, -1, 1, 0}, -/* 7 */ { 6, s_57_7, -1, 1, 0}, -/* 8 */ { 6, s_57_8, -1, 1, 0}, -/* 9 */ { 6, s_57_9, -1, 1, 0}, -/* 10 */ { 6, s_57_10, -1, 1, 0}, -/* 11 */ { 12, s_57_11, -1, 1, 0}, -/* 12 */ { 4, s_57_12, -1, 1, 0}, -/* 13 */ { 6, s_57_13, -1, 1, 0}, -/* 14 */ { 10, s_57_14, -1, 1, 0}, -/* 15 */ { 12, s_57_15, -1, 1, 0}, -/* 16 */ { 6, s_57_16, -1, 1, 0}, -/* 17 */ { 12, s_57_17, -1, 1, 0}, -/* 18 */ { 6, s_57_18, -1, 1, 0}, -/* 19 */ { 8, s_57_19, -1, 1, 0}, -/* 20 */ { 2, s_57_20, -1, 1, 0}, -/* 21 */ { 2, s_57_21, -1, 1, 0}, -/* 22 */ { 4, s_57_22, 21, 1, 0}, -/* 23 */ { 8, s_57_23, 21, 1, 0}, -/* 24 */ { 14, s_57_24, -1, 1, 0} +{ 10, s_57_0, -1, 1, 0}, +{ 2, s_57_1, -1, 1, 0}, +{ 10, s_57_2, 1, 1, 0}, +{ 16, s_57_3, 1, 1, 0}, +{ 6, s_57_4, -1, 1, 0}, +{ 14, s_57_5, -1, 1, 0}, +{ 16, s_57_6, -1, 1, 0}, +{ 6, s_57_7, -1, 1, 0}, +{ 6, s_57_8, -1, 1, 0}, +{ 6, s_57_9, -1, 1, 0}, +{ 6, s_57_10, -1, 1, 0}, +{ 12, s_57_11, -1, 1, 0}, +{ 4, s_57_12, -1, 1, 0}, +{ 6, s_57_13, -1, 1, 0}, +{ 10, s_57_14, -1, 1, 0}, +{ 12, s_57_15, -1, 1, 0}, +{ 6, s_57_16, -1, 1, 0}, +{ 12, s_57_17, -1, 1, 0}, +{ 6, s_57_18, -1, 1, 0}, +{ 8, s_57_19, -1, 1, 0}, +{ 2, s_57_20, -1, 1, 0}, +{ 2, s_57_21, -1, 1, 0}, +{ 4, s_57_22, 21, 1, 0}, +{ 8, s_57_23, 21, 1, 0}, +{ 14, s_57_24, -1, 1, 0} }; static const symbol s_58_0[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -1778,9 +1778,9 @@ static const symbol s_58_2[8] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB5 static const struct among a_58[3] = { -/* 0 */ { 10, s_58_0, -1, 1, 0}, -/* 1 */ { 8, s_58_1, -1, 1, 0}, -/* 2 */ { 8, s_58_2, -1, 1, 0} +{ 10, s_58_0, -1, 1, 0}, +{ 8, s_58_1, -1, 1, 0}, +{ 8, s_58_2, -1, 1, 0} }; static const symbol s_59_0[6] = { 0xCF, 0x88, 0xCE, 0xBF, 0xCF, 0x86 }; @@ -1788,8 +1788,8 @@ static const symbol s_59_1[12] = { 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x85, 0xCE, 0xB static const struct among a_59[2] = { -/* 0 */ { 6, s_59_0, -1, -1, 0}, -/* 1 */ { 12, s_59_1, -1, -1, 0} +{ 6, s_59_0, -1, -1, 0}, +{ 12, s_59_1, -1, -1, 0} }; static const symbol s_60_0[4] = { 0xCF, 0x81, 0xCF, 0x80 }; @@ -1805,16 +1805,16 @@ static const symbol s_60_9[8] = { 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xB7, 0xCE, 0xBD static const struct among a_60[10] = { -/* 0 */ { 4, s_60_0, -1, 1, 0}, -/* 1 */ { 4, s_60_1, -1, 1, 0}, -/* 2 */ { 4, s_60_2, -1, 1, 0}, -/* 3 */ { 8, s_60_3, -1, 1, 0}, -/* 4 */ { 4, s_60_4, -1, 1, 0}, -/* 5 */ { 4, s_60_5, -1, 1, 0}, -/* 6 */ { 6, s_60_6, -1, 1, 0}, -/* 7 */ { 6, s_60_7, -1, 1, 0}, -/* 8 */ { 4, s_60_8, -1, 1, 0}, -/* 9 */ { 8, s_60_9, -1, 1, 0} +{ 4, s_60_0, -1, 1, 0}, +{ 4, s_60_1, -1, 1, 0}, +{ 4, s_60_2, -1, 1, 0}, +{ 8, s_60_3, -1, 1, 0}, +{ 4, s_60_4, -1, 1, 0}, +{ 4, s_60_5, -1, 1, 0}, +{ 6, s_60_6, -1, 1, 0}, +{ 6, s_60_7, -1, 1, 0}, +{ 4, s_60_8, -1, 1, 0}, +{ 8, s_60_9, -1, 1, 0} }; static const symbol s_61_0[2] = { 0xCF, 0x80 }; @@ -1864,50 +1864,50 @@ static const symbol s_61_43[12] = { 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0x static const struct among a_61[44] = { -/* 0 */ { 2, s_61_0, -1, 1, 0}, -/* 1 */ { 6, s_61_1, 0, 1, 0}, -/* 2 */ { 8, s_61_2, 0, 1, 0}, -/* 3 */ { 10, s_61_3, 0, 1, 0}, -/* 4 */ { 8, s_61_4, 0, 1, 0}, -/* 5 */ { 8, s_61_5, 0, 1, 0}, -/* 6 */ { 16, s_61_6, 0, 1, 0}, -/* 7 */ { 14, s_61_7, 0, 1, 0}, -/* 8 */ { 12, s_61_8, 0, 1, 0}, -/* 9 */ { 8, s_61_9, 0, 1, 0}, -/* 10 */ { 16, s_61_10, 0, 1, 0}, -/* 11 */ { 8, s_61_11, 0, 1, 0}, -/* 12 */ { 2, s_61_12, -1, 1, 0}, -/* 13 */ { 4, s_61_13, 12, 1, 0}, -/* 14 */ { 6, s_61_14, 12, 1, 0}, -/* 15 */ { 10, s_61_15, 12, 1, 0}, -/* 16 */ { 6, s_61_16, 12, 1, 0}, -/* 17 */ { 8, s_61_17, 16, 1, 0}, -/* 18 */ { 8, s_61_18, 12, 1, 0}, -/* 19 */ { 2, s_61_19, -1, 1, 0}, -/* 20 */ { 10, s_61_20, 19, 1, 0}, -/* 21 */ { 10, s_61_21, 19, 1, 0}, -/* 22 */ { 10, s_61_22, 19, 1, 0}, -/* 23 */ { 12, s_61_23, 19, 1, 0}, -/* 24 */ { 8, s_61_24, 19, 1, 0}, -/* 25 */ { 8, s_61_25, 19, 1, 0}, -/* 26 */ { 8, s_61_26, 19, 1, 0}, -/* 27 */ { 8, s_61_27, 19, 1, 0}, -/* 28 */ { 8, s_61_28, 19, 1, 0}, -/* 29 */ { 8, s_61_29, 19, 1, 0}, -/* 30 */ { 10, s_61_30, 29, 1, 0}, -/* 31 */ { 6, s_61_31, -1, 1, 0}, -/* 32 */ { 10, s_61_32, -1, 1, 0}, -/* 33 */ { 4, s_61_33, -1, 1, 0}, -/* 34 */ { 6, s_61_34, -1, 1, 0}, -/* 35 */ { 8, s_61_35, -1, 1, 0}, -/* 36 */ { 8, s_61_36, -1, 1, 0}, -/* 37 */ { 12, s_61_37, -1, 1, 0}, -/* 38 */ { 2, s_61_38, -1, 1, 0}, -/* 39 */ { 8, s_61_39, 38, 1, 0}, -/* 40 */ { 2, s_61_40, -1, 1, 0}, -/* 41 */ { 10, s_61_41, 40, 1, 0}, -/* 42 */ { 4, s_61_42, -1, 1, 0}, -/* 43 */ { 12, s_61_43, 42, 1, 0} +{ 2, s_61_0, -1, 1, 0}, +{ 6, s_61_1, 0, 1, 0}, +{ 8, s_61_2, 0, 1, 0}, +{ 10, s_61_3, 0, 1, 0}, +{ 8, s_61_4, 0, 1, 0}, +{ 8, s_61_5, 0, 1, 0}, +{ 16, s_61_6, 0, 1, 0}, +{ 14, s_61_7, 0, 1, 0}, +{ 12, s_61_8, 0, 1, 0}, +{ 8, s_61_9, 0, 1, 0}, +{ 16, s_61_10, 0, 1, 0}, +{ 8, s_61_11, 0, 1, 0}, +{ 2, s_61_12, -1, 1, 0}, +{ 4, s_61_13, 12, 1, 0}, +{ 6, s_61_14, 12, 1, 0}, +{ 10, s_61_15, 12, 1, 0}, +{ 6, s_61_16, 12, 1, 0}, +{ 8, s_61_17, 16, 1, 0}, +{ 8, s_61_18, 12, 1, 0}, +{ 2, s_61_19, -1, 1, 0}, +{ 10, s_61_20, 19, 1, 0}, +{ 10, s_61_21, 19, 1, 0}, +{ 10, s_61_22, 19, 1, 0}, +{ 12, s_61_23, 19, 1, 0}, +{ 8, s_61_24, 19, 1, 0}, +{ 8, s_61_25, 19, 1, 0}, +{ 8, s_61_26, 19, 1, 0}, +{ 8, s_61_27, 19, 1, 0}, +{ 8, s_61_28, 19, 1, 0}, +{ 8, s_61_29, 19, 1, 0}, +{ 10, s_61_30, 29, 1, 0}, +{ 6, s_61_31, -1, 1, 0}, +{ 10, s_61_32, -1, 1, 0}, +{ 4, s_61_33, -1, 1, 0}, +{ 6, s_61_34, -1, 1, 0}, +{ 8, s_61_35, -1, 1, 0}, +{ 8, s_61_36, -1, 1, 0}, +{ 12, s_61_37, -1, 1, 0}, +{ 2, s_61_38, -1, 1, 0}, +{ 8, s_61_39, 38, 1, 0}, +{ 2, s_61_40, -1, 1, 0}, +{ 10, s_61_41, 40, 1, 0}, +{ 4, s_61_42, -1, 1, 0}, +{ 12, s_61_43, 42, 1, 0} }; static const symbol s_62_0[8] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB5, 0xCF, 0x83 }; @@ -1916,9 +1916,9 @@ static const symbol s_62_2[6] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB5 }; static const struct among a_62[3] = { -/* 0 */ { 8, s_62_0, -1, 1, 0}, -/* 1 */ { 6, s_62_1, -1, 1, 0}, -/* 2 */ { 6, s_62_2, -1, 1, 0} +{ 8, s_62_0, -1, 1, 0}, +{ 6, s_62_1, -1, 1, 0}, +{ 6, s_62_2, -1, 1, 0} }; static const symbol s_63_0[8] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85 }; @@ -1927,9 +1927,9 @@ static const symbol s_63_2[6] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB5 }; static const struct among a_63[3] = { -/* 0 */ { 8, s_63_0, -1, 1, 0}, -/* 1 */ { 6, s_63_1, -1, 1, 0}, -/* 2 */ { 6, s_63_2, -1, 1, 0} +{ 8, s_63_0, -1, 1, 0}, +{ 6, s_63_1, -1, 1, 0}, +{ 6, s_63_2, -1, 1, 0} }; static const symbol s_64_0[2] = { 0xCE, 0xBD }; @@ -1941,19 +1941,19 @@ static const symbol s_64_5[12] = { 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB7, 0xCE, 0xB static const struct among a_64[6] = { -/* 0 */ { 2, s_64_0, -1, 1, 0}, -/* 1 */ { 10, s_64_1, 0, 1, 0}, -/* 2 */ { 14, s_64_2, 0, 1, 0}, -/* 3 */ { 12, s_64_3, 0, 1, 0}, -/* 4 */ { 14, s_64_4, 0, 1, 0}, -/* 5 */ { 12, s_64_5, 0, 1, 0} +{ 2, s_64_0, -1, 1, 0}, +{ 10, s_64_1, 0, 1, 0}, +{ 14, s_64_2, 0, 1, 0}, +{ 12, s_64_3, 0, 1, 0}, +{ 14, s_64_4, 0, 1, 0}, +{ 12, s_64_5, 0, 1, 0} }; static const symbol s_65_0[8] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; static const struct among a_65[1] = { -/* 0 */ { 8, s_65_0, -1, 1, 0} +{ 8, s_65_0, -1, 1, 0} }; static const symbol s_66_0[4] = { 0xCF, 0x87, 0xCF, 0x81 }; @@ -1969,16 +1969,16 @@ static const symbol s_66_9[10] = { 0xCE, 0xB1, 0xCE, 0xB5, 0xCE, 0xB9, 0xCE, 0xB static const struct among a_66[10] = { -/* 0 */ { 4, s_66_0, -1, 1, 0}, -/* 1 */ { 10, s_66_1, 0, 1, 0}, -/* 2 */ { 8, s_66_2, 0, 1, 0}, -/* 3 */ { 6, s_66_3, 0, 1, 0}, -/* 4 */ { 14, s_66_4, 0, 1, 0}, -/* 5 */ { 12, s_66_5, -1, 1, 0}, -/* 6 */ { 4, s_66_6, -1, 1, 0}, -/* 7 */ { 6, s_66_7, 6, 1, 0}, -/* 8 */ { 6, s_66_8, -1, 1, 0}, -/* 9 */ { 10, s_66_9, -1, 1, 0} +{ 4, s_66_0, -1, 1, 0}, +{ 10, s_66_1, 0, 1, 0}, +{ 8, s_66_2, 0, 1, 0}, +{ 6, s_66_3, 0, 1, 0}, +{ 14, s_66_4, 0, 1, 0}, +{ 12, s_66_5, -1, 1, 0}, +{ 4, s_66_6, -1, 1, 0}, +{ 6, s_66_7, 6, 1, 0}, +{ 6, s_66_8, -1, 1, 0}, +{ 10, s_66_9, -1, 1, 0} }; static const symbol s_67_0[8] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB5 }; @@ -1987,9 +1987,9 @@ static const symbol s_67_2[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xBF, 0xCF, 0x8 static const struct among a_67[3] = { -/* 0 */ { 8, s_67_0, -1, 1, 0}, -/* 1 */ { 12, s_67_1, 0, 1, 0}, -/* 2 */ { 12, s_67_2, 0, 1, 0} +{ 8, s_67_0, -1, 1, 0}, +{ 12, s_67_1, 0, 1, 0}, +{ 12, s_67_2, 0, 1, 0} }; static const symbol s_68_0[2] = { 0xCF, 0x81 }; @@ -2001,12 +2001,12 @@ static const symbol s_68_5[8] = { 0xCE, 0xB5, 0xCE, 0xBE, 0xCF, 0x89, 0xCE, 0xBD static const struct among a_68[6] = { -/* 0 */ { 2, s_68_0, -1, 1, 0}, -/* 1 */ { 22, s_68_1, -1, 1, 0}, -/* 2 */ { 18, s_68_2, -1, 1, 0}, -/* 3 */ { 6, s_68_3, -1, 1, 0}, -/* 4 */ { 2, s_68_4, -1, 1, 0}, -/* 5 */ { 8, s_68_5, 4, 1, 0} +{ 2, s_68_0, -1, 1, 0}, +{ 22, s_68_1, -1, 1, 0}, +{ 18, s_68_2, -1, 1, 0}, +{ 6, s_68_3, -1, 1, 0}, +{ 2, s_68_4, -1, 1, 0}, +{ 8, s_68_5, 4, 1, 0} }; static const symbol s_69_0[8] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB5 }; @@ -2015,9 +2015,9 @@ static const symbol s_69_2[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xBF, 0xCF, 0x8 static const struct among a_69[3] = { -/* 0 */ { 8, s_69_0, -1, 1, 0}, -/* 1 */ { 12, s_69_1, 0, 1, 0}, -/* 2 */ { 12, s_69_2, 0, 1, 0} +{ 8, s_69_0, -1, 1, 0}, +{ 12, s_69_1, 0, 1, 0}, +{ 12, s_69_2, 0, 1, 0} }; static const symbol s_70_0[10] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; @@ -2030,13 +2030,13 @@ static const symbol s_70_6[12] = { 0xCF, 0x89, 0xCF, 0x81, 0xCE, 0xB9, 0xCE, 0xB static const struct among a_70[7] = { -/* 0 */ { 10, s_70_0, -1, 1, 0}, -/* 1 */ { 16, s_70_1, 0, 1, 0}, -/* 2 */ { 16, s_70_2, -1, 1, 0}, -/* 3 */ { 2, s_70_3, -1, 1, 0}, -/* 4 */ { 2, s_70_4, -1, 1, 0}, -/* 5 */ { 4, s_70_5, -1, 1, 0}, -/* 6 */ { 12, s_70_6, -1, 1, 0} +{ 10, s_70_0, -1, 1, 0}, +{ 16, s_70_1, 0, 1, 0}, +{ 16, s_70_2, -1, 1, 0}, +{ 2, s_70_3, -1, 1, 0}, +{ 2, s_70_4, -1, 1, 0}, +{ 4, s_70_5, -1, 1, 0}, +{ 12, s_70_6, -1, 1, 0} }; static const symbol s_71_0[10] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; @@ -2045,9 +2045,9 @@ static const symbol s_71_2[10] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x8 static const struct among a_71[3] = { -/* 0 */ { 10, s_71_0, -1, 1, 0}, -/* 1 */ { 8, s_71_1, -1, 1, 0}, -/* 2 */ { 10, s_71_2, -1, 1, 0} +{ 10, s_71_0, -1, 1, 0}, +{ 8, s_71_1, -1, 1, 0}, +{ 10, s_71_2, -1, 1, 0} }; static const symbol s_72_0[4] = { 0xCF, 0x85, 0xCF, 0x83 }; @@ -2137,90 +2137,90 @@ static const symbol s_72_83[2] = { 0xCE, 0xBF }; static const struct among a_72[84] = { -/* 0 */ { 4, s_72_0, -1, 1, 0}, -/* 1 */ { 6, s_72_1, 0, 1, 0}, -/* 2 */ { 4, s_72_2, -1, 1, 0}, -/* 3 */ { 4, s_72_3, -1, 1, 0}, -/* 4 */ { 8, s_72_4, 3, 1, 0}, -/* 5 */ { 8, s_72_5, 3, 1, 0}, -/* 6 */ { 4, s_72_6, -1, 1, 0}, -/* 7 */ { 6, s_72_7, -1, 1, 0}, -/* 8 */ { 10, s_72_8, 7, 1, 0}, -/* 9 */ { 4, s_72_9, -1, 1, 0}, -/* 10 */ { 2, s_72_10, -1, 1, 0}, -/* 11 */ { 4, s_72_11, 10, 1, 0}, -/* 12 */ { 2, s_72_12, -1, 1, 0}, -/* 13 */ { 6, s_72_13, 12, 1, 0}, -/* 14 */ { 4, s_72_14, 12, 1, 0}, -/* 15 */ { 6, s_72_15, 12, 1, 0}, -/* 16 */ { 2, s_72_16, -1, 1, 0}, -/* 17 */ { 10, s_72_17, 16, 1, 0}, -/* 18 */ { 12, s_72_18, 16, 1, 0}, -/* 19 */ { 14, s_72_19, 18, 1, 0}, -/* 20 */ { 12, s_72_20, 16, 1, 0}, -/* 21 */ { 14, s_72_21, 20, 1, 0}, -/* 22 */ { 2, s_72_22, -1, 1, 0}, -/* 23 */ { 14, s_72_23, 22, 1, 0}, -/* 24 */ { 12, s_72_24, 22, 1, 0}, -/* 25 */ { 14, s_72_25, 24, 1, 0}, -/* 26 */ { 14, s_72_26, 22, 1, 0}, -/* 27 */ { 16, s_72_27, 26, 1, 0}, -/* 28 */ { 14, s_72_28, 22, 1, 0}, -/* 29 */ { 12, s_72_29, 22, 1, 0}, -/* 30 */ { 10, s_72_30, 22, 1, 0}, -/* 31 */ { 10, s_72_31, 22, 1, 0}, -/* 32 */ { 10, s_72_32, 22, 1, 0}, -/* 33 */ { 14, s_72_33, 32, 1, 0}, -/* 34 */ { 8, s_72_34, 22, 1, 0}, -/* 35 */ { 12, s_72_35, 34, 1, 0}, -/* 36 */ { 2, s_72_36, -1, 1, 0}, -/* 37 */ { 2, s_72_37, -1, 1, 0}, -/* 38 */ { 8, s_72_38, 37, 1, 0}, -/* 39 */ { 8, s_72_39, 37, 1, 0}, -/* 40 */ { 10, s_72_40, 39, 1, 0}, -/* 41 */ { 8, s_72_41, 37, 1, 0}, -/* 42 */ { 8, s_72_42, 37, 1, 0}, -/* 43 */ { 10, s_72_43, 42, 1, 0}, -/* 44 */ { 12, s_72_44, 37, 1, 0}, -/* 45 */ { 14, s_72_45, 44, 1, 0}, -/* 46 */ { 10, s_72_46, 37, 1, 0}, -/* 47 */ { 10, s_72_47, 37, 1, 0}, -/* 48 */ { 8, s_72_48, 37, 1, 0}, -/* 49 */ { 10, s_72_49, 37, 1, 0}, -/* 50 */ { 8, s_72_50, 37, 1, 0}, -/* 51 */ { 4, s_72_51, 37, 1, 0}, -/* 52 */ { 8, s_72_52, 51, 1, 0}, -/* 53 */ { 6, s_72_53, 51, 1, 0}, -/* 54 */ { 8, s_72_54, 51, 1, 0}, -/* 55 */ { 4, s_72_55, 37, 1, 0}, -/* 56 */ { 6, s_72_56, -1, 1, 0}, -/* 57 */ { 10, s_72_57, 56, 1, 0}, -/* 58 */ { 10, s_72_58, 56, 1, 0}, -/* 59 */ { 12, s_72_59, 58, 1, 0}, -/* 60 */ { 10, s_72_60, 56, 1, 0}, -/* 61 */ { 10, s_72_61, 56, 1, 0}, -/* 62 */ { 12, s_72_62, 61, 1, 0}, -/* 63 */ { 4, s_72_63, -1, 1, 0}, -/* 64 */ { 8, s_72_64, 63, 1, 0}, -/* 65 */ { 4, s_72_65, -1, 1, 0}, -/* 66 */ { 10, s_72_66, 65, 1, 0}, -/* 67 */ { 16, s_72_67, 66, 1, 0}, -/* 68 */ { 18, s_72_68, 67, 1, 0}, -/* 69 */ { 8, s_72_69, 65, 1, 0}, -/* 70 */ { 14, s_72_70, 65, 1, 0}, -/* 71 */ { 16, s_72_71, 70, 1, 0}, -/* 72 */ { 14, s_72_72, 65, 1, 0}, -/* 73 */ { 16, s_72_73, 72, 1, 0}, -/* 74 */ { 12, s_72_74, 65, 1, 0}, -/* 75 */ { 14, s_72_75, 74, 1, 0}, -/* 76 */ { 10, s_72_76, 65, 1, 0}, -/* 77 */ { 12, s_72_77, 76, 1, 0}, -/* 78 */ { 8, s_72_78, 65, 1, 0}, -/* 79 */ { 10, s_72_79, 78, 1, 0}, -/* 80 */ { 8, s_72_80, 65, 1, 0}, -/* 81 */ { 8, s_72_81, 65, 1, 0}, -/* 82 */ { 12, s_72_82, 81, 1, 0}, -/* 83 */ { 2, s_72_83, -1, 1, 0} +{ 4, s_72_0, -1, 1, 0}, +{ 6, s_72_1, 0, 1, 0}, +{ 4, s_72_2, -1, 1, 0}, +{ 4, s_72_3, -1, 1, 0}, +{ 8, s_72_4, 3, 1, 0}, +{ 8, s_72_5, 3, 1, 0}, +{ 4, s_72_6, -1, 1, 0}, +{ 6, s_72_7, -1, 1, 0}, +{ 10, s_72_8, 7, 1, 0}, +{ 4, s_72_9, -1, 1, 0}, +{ 2, s_72_10, -1, 1, 0}, +{ 4, s_72_11, 10, 1, 0}, +{ 2, s_72_12, -1, 1, 0}, +{ 6, s_72_13, 12, 1, 0}, +{ 4, s_72_14, 12, 1, 0}, +{ 6, s_72_15, 12, 1, 0}, +{ 2, s_72_16, -1, 1, 0}, +{ 10, s_72_17, 16, 1, 0}, +{ 12, s_72_18, 16, 1, 0}, +{ 14, s_72_19, 18, 1, 0}, +{ 12, s_72_20, 16, 1, 0}, +{ 14, s_72_21, 20, 1, 0}, +{ 2, s_72_22, -1, 1, 0}, +{ 14, s_72_23, 22, 1, 0}, +{ 12, s_72_24, 22, 1, 0}, +{ 14, s_72_25, 24, 1, 0}, +{ 14, s_72_26, 22, 1, 0}, +{ 16, s_72_27, 26, 1, 0}, +{ 14, s_72_28, 22, 1, 0}, +{ 12, s_72_29, 22, 1, 0}, +{ 10, s_72_30, 22, 1, 0}, +{ 10, s_72_31, 22, 1, 0}, +{ 10, s_72_32, 22, 1, 0}, +{ 14, s_72_33, 32, 1, 0}, +{ 8, s_72_34, 22, 1, 0}, +{ 12, s_72_35, 34, 1, 0}, +{ 2, s_72_36, -1, 1, 0}, +{ 2, s_72_37, -1, 1, 0}, +{ 8, s_72_38, 37, 1, 0}, +{ 8, s_72_39, 37, 1, 0}, +{ 10, s_72_40, 39, 1, 0}, +{ 8, s_72_41, 37, 1, 0}, +{ 8, s_72_42, 37, 1, 0}, +{ 10, s_72_43, 42, 1, 0}, +{ 12, s_72_44, 37, 1, 0}, +{ 14, s_72_45, 44, 1, 0}, +{ 10, s_72_46, 37, 1, 0}, +{ 10, s_72_47, 37, 1, 0}, +{ 8, s_72_48, 37, 1, 0}, +{ 10, s_72_49, 37, 1, 0}, +{ 8, s_72_50, 37, 1, 0}, +{ 4, s_72_51, 37, 1, 0}, +{ 8, s_72_52, 51, 1, 0}, +{ 6, s_72_53, 51, 1, 0}, +{ 8, s_72_54, 51, 1, 0}, +{ 4, s_72_55, 37, 1, 0}, +{ 6, s_72_56, -1, 1, 0}, +{ 10, s_72_57, 56, 1, 0}, +{ 10, s_72_58, 56, 1, 0}, +{ 12, s_72_59, 58, 1, 0}, +{ 10, s_72_60, 56, 1, 0}, +{ 10, s_72_61, 56, 1, 0}, +{ 12, s_72_62, 61, 1, 0}, +{ 4, s_72_63, -1, 1, 0}, +{ 8, s_72_64, 63, 1, 0}, +{ 4, s_72_65, -1, 1, 0}, +{ 10, s_72_66, 65, 1, 0}, +{ 16, s_72_67, 66, 1, 0}, +{ 18, s_72_68, 67, 1, 0}, +{ 8, s_72_69, 65, 1, 0}, +{ 14, s_72_70, 65, 1, 0}, +{ 16, s_72_71, 70, 1, 0}, +{ 14, s_72_72, 65, 1, 0}, +{ 16, s_72_73, 72, 1, 0}, +{ 12, s_72_74, 65, 1, 0}, +{ 14, s_72_75, 74, 1, 0}, +{ 10, s_72_76, 65, 1, 0}, +{ 12, s_72_77, 76, 1, 0}, +{ 8, s_72_78, 65, 1, 0}, +{ 10, s_72_79, 78, 1, 0}, +{ 8, s_72_80, 65, 1, 0}, +{ 8, s_72_81, 65, 1, 0}, +{ 12, s_72_82, 81, 1, 0}, +{ 2, s_72_83, -1, 1, 0} }; static const symbol s_73_0[10] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; @@ -2234,14 +2234,14 @@ static const symbol s_73_7[8] = { 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84 static const struct among a_73[8] = { -/* 0 */ { 10, s_73_0, -1, 1, 0}, -/* 1 */ { 8, s_73_1, -1, 1, 0}, -/* 2 */ { 8, s_73_2, -1, 1, 0}, -/* 3 */ { 8, s_73_3, -1, 1, 0}, -/* 4 */ { 10, s_73_4, -1, 1, 0}, -/* 5 */ { 8, s_73_5, -1, 1, 0}, -/* 6 */ { 8, s_73_6, -1, 1, 0}, -/* 7 */ { 8, s_73_7, -1, 1, 0} +{ 10, s_73_0, -1, 1, 0}, +{ 8, s_73_1, -1, 1, 0}, +{ 8, s_73_2, -1, 1, 0}, +{ 8, s_73_3, -1, 1, 0}, +{ 10, s_73_4, -1, 1, 0}, +{ 8, s_73_5, -1, 1, 0}, +{ 8, s_73_6, -1, 1, 0}, +{ 8, s_73_7, -1, 1, 0} }; static const unsigned char g_v[] = { 81, 65, 16, 1 }; @@ -2356,145 +2356,144 @@ static const symbol s_104[] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; static const symbol s_105[] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC }; static const symbol s_106[] = { 0xCE, 0xBC, 0xCE, 0xB1 }; -static int r_has_min_length(struct SN_env * z) { /* backwardmode */ - if (!(len_utf8(z->p) >= 3)) return 0; /* $( >= ), line 109 */ +static int r_has_min_length(struct SN_env * z) { + if (!(len_utf8(z->p) >= 3)) return 0; return 1; } -static int r_tolower(struct SN_env * z) { /* backwardmode */ +static int r_tolower(struct SN_env * z) { int among_var; -/* repeat, line 113 */ - - while(1) { int m1 = z->l - z->c; (void)m1; - z->ket = z->c; /* [, line 114 */ - among_var = find_among_b(z, a_0, 46); /* substring, line 114 */ + while(1) { + int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + among_var = find_among_b(z, a_0, 46); if (!(among_var)) goto lab0; - z->bra = z->c; /* ], line 114 */ - switch (among_var) { /* among, line 114 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 115 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_1); /* <-, line 116 */ + { int ret = slice_from_s(z, 2, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_2); /* <-, line 117 */ + { int ret = slice_from_s(z, 2, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_3); /* <-, line 118 */ + { int ret = slice_from_s(z, 2, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 2, s_4); /* <-, line 119 */ + { int ret = slice_from_s(z, 2, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_5); /* <-, line 120 */ + { int ret = slice_from_s(z, 2, s_5); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 2, s_6); /* <-, line 121 */ + { int ret = slice_from_s(z, 2, s_6); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 2, s_7); /* <-, line 122 */ + { int ret = slice_from_s(z, 2, s_7); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 2, s_8); /* <-, line 123 */ + { int ret = slice_from_s(z, 2, s_8); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 2, s_9); /* <-, line 124 */ + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 2, s_10); /* <-, line 125 */ + { int ret = slice_from_s(z, 2, s_10); if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 2, s_11); /* <-, line 126 */ + { int ret = slice_from_s(z, 2, s_11); if (ret < 0) return ret; } break; case 13: - { int ret = slice_from_s(z, 2, s_12); /* <-, line 127 */ + { int ret = slice_from_s(z, 2, s_12); if (ret < 0) return ret; } break; case 14: - { int ret = slice_from_s(z, 2, s_13); /* <-, line 128 */ + { int ret = slice_from_s(z, 2, s_13); if (ret < 0) return ret; } break; case 15: - { int ret = slice_from_s(z, 2, s_14); /* <-, line 129 */ + { int ret = slice_from_s(z, 2, s_14); if (ret < 0) return ret; } break; case 16: - { int ret = slice_from_s(z, 2, s_15); /* <-, line 130 */ + { int ret = slice_from_s(z, 2, s_15); if (ret < 0) return ret; } break; case 17: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 131 */ + { int ret = slice_from_s(z, 2, s_16); if (ret < 0) return ret; } break; case 18: - { int ret = slice_from_s(z, 2, s_17); /* <-, line 132 */ + { int ret = slice_from_s(z, 2, s_17); if (ret < 0) return ret; } break; case 19: - { int ret = slice_from_s(z, 2, s_18); /* <-, line 133 */ + { int ret = slice_from_s(z, 2, s_18); if (ret < 0) return ret; } break; case 20: - { int ret = slice_from_s(z, 2, s_19); /* <-, line 134 */ + { int ret = slice_from_s(z, 2, s_19); if (ret < 0) return ret; } break; case 21: - { int ret = slice_from_s(z, 2, s_20); /* <-, line 135 */ + { int ret = slice_from_s(z, 2, s_20); if (ret < 0) return ret; } break; case 22: - { int ret = slice_from_s(z, 2, s_21); /* <-, line 136 */ + { int ret = slice_from_s(z, 2, s_21); if (ret < 0) return ret; } break; case 23: - { int ret = slice_from_s(z, 2, s_22); /* <-, line 137 */ + { int ret = slice_from_s(z, 2, s_22); if (ret < 0) return ret; } break; case 24: - { int ret = slice_from_s(z, 2, s_23); /* <-, line 138 */ + { int ret = slice_from_s(z, 2, s_23); if (ret < 0) return ret; } break; case 25: - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 160 */ + z->c = ret; } break; } @@ -2506,98 +2505,98 @@ static int r_tolower(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_step1(struct SN_env * z) { /* backwardmode */ +static int r_step1(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 166 */ - among_var = find_among_b(z, a_1, 40); /* substring, line 166 */ + z->ket = z->c; + among_var = find_among_b(z, a_1, 40); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 166 */ - switch (among_var) { /* among, line 166 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_24); /* <-, line 167 */ + { int ret = slice_from_s(z, 4, s_24); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 6, s_25); /* <-, line 168 */ + { int ret = slice_from_s(z, 6, s_25); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 6, s_26); /* <-, line 169 */ + { int ret = slice_from_s(z, 6, s_26); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_27); /* <-, line 170 */ + { int ret = slice_from_s(z, 4, s_27); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 8, s_28); /* <-, line 171 */ + { int ret = slice_from_s(z, 8, s_28); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 6, s_29); /* <-, line 172 */ + { int ret = slice_from_s(z, 6, s_29); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 6, s_30); /* <-, line 173 */ + { int ret = slice_from_s(z, 6, s_30); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 6, s_31); /* <-, line 174 */ + { int ret = slice_from_s(z, 6, s_31); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 4, s_32); /* <-, line 175 */ + { int ret = slice_from_s(z, 4, s_32); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 12, s_33); /* <-, line 176 */ + { int ret = slice_from_s(z, 12, s_33); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 10, s_34); /* <-, line 177 */ + { int ret = slice_from_s(z, 10, s_34); if (ret < 0) return ret; } break; } - z->B[0] = 0; /* unset test1, line 179 */ + z->I[0] = 0; return 1; } -static int r_steps1(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 183 */ - if (!(find_among_b(z, a_4, 14))) return 0; /* substring, line 183 */ - z->bra = z->c; /* ], line 183 */ - { int ret = slice_del(z); /* delete, line 186 */ +static int r_steps1(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_4, 14))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 187 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 191 */ - z->ket = z->c; /* [, line 188 */ - z->bra = z->c; /* ], line 188 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab1; /* substring, line 188 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab1; if (!(find_among_b(z, a_2, 9))) goto lab1; - if (z->c > z->lb) goto lab1; /* atlimit, line 188 */ - { int ret = slice_from_s(z, 2, s_35); /* <-, line 190 */ + if (z->c > z->lb) goto lab1; + { int ret = slice_from_s(z, 2, s_35); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 192 */ - z->bra = z->c; /* ], line 192 */ - if (!(find_among_b(z, a_3, 22))) return 0; /* substring, line 192 */ - if (z->c > z->lb) return 0; /* atlimit, line 192 */ - { int ret = slice_from_s(z, 4, s_36); /* <-, line 196 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_3, 22))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_36); if (ret < 0) return ret; } } @@ -2605,57 +2604,57 @@ static int r_steps1(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_steps2(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 203 */ - if (!(find_among_b(z, a_6, 7))) return 0; /* substring, line 203 */ - z->bra = z->c; /* ], line 203 */ - { int ret = slice_del(z); /* delete, line 205 */ +static int r_steps2(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_6, 7))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 206 */ - z->ket = z->c; /* [, line 207 */ - z->bra = z->c; /* ], line 207 */ - if (!(find_among_b(z, a_5, 8))) return 0; /* substring, line 207 */ - if (z->c > z->lb) return 0; /* atlimit, line 207 */ - { int ret = slice_from_s(z, 4, s_37); /* <-, line 208 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_5, 8))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_37); if (ret < 0) return ret; } return 1; } -static int r_steps3(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 215 */ - if (!(find_among_b(z, a_9, 7))) return 0; /* substring, line 215 */ - z->bra = z->c; /* ], line 215 */ - { int ret = slice_del(z); /* delete, line 217 */ +static int r_steps3(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_9, 7))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 218 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 219 */ - if (!(eq_s_b(z, 6, s_38))) goto lab1; /* literal, line 219 */ - if (z->c > z->lb) goto lab1; /* atlimit, line 219 */ - { int ret = slice_from_s(z, 4, s_39); /* <-, line 219 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 6, s_38))) goto lab1; + if (z->c > z->lb) goto lab1; + { int ret = slice_from_s(z, 4, s_39); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 220 */ - z->bra = z->c; /* ], line 220 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; /* substring, line 220 */ + z->ket = z->c; + z->bra = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; if (!(find_among_b(z, a_7, 19))) goto lab2; - if (z->c > z->lb) goto lab2; /* atlimit, line 220 */ - { int ret = slice_from_s(z, 2, s_40); /* <-, line 224 */ + if (z->c > z->lb) goto lab2; + { int ret = slice_from_s(z, 2, s_40); if (ret < 0) return ret; } goto lab0; lab2: z->c = z->l - m1; - z->ket = z->c; /* [, line 226 */ - z->bra = z->c; /* ], line 226 */ - if (!(find_among_b(z, a_8, 13))) return 0; /* substring, line 226 */ - if (z->c > z->lb) return 0; /* atlimit, line 226 */ - { int ret = slice_from_s(z, 4, s_41); /* <-, line 229 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_8, 13))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_41); if (ret < 0) return ret; } } @@ -2663,50 +2662,50 @@ static int r_steps3(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_steps4(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 236 */ - if (!(find_among_b(z, a_11, 7))) return 0; /* substring, line 236 */ - z->bra = z->c; /* ], line 236 */ - { int ret = slice_del(z); /* delete, line 238 */ +static int r_steps4(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_11, 7))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 239 */ - z->ket = z->c; /* [, line 240 */ - z->bra = z->c; /* ], line 240 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 240 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_10, 19))) return 0; - if (z->c > z->lb) return 0; /* atlimit, line 240 */ - { int ret = slice_from_s(z, 2, s_42); /* <-, line 244 */ + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 2, s_42); if (ret < 0) return ret; } return 1; } -static int r_steps5(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 251 */ - if (!(find_among_b(z, a_14, 11))) return 0; /* substring, line 251 */ - z->bra = z->c; /* ], line 251 */ - { int ret = slice_del(z); /* delete, line 254 */ +static int r_steps5(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_14, 11))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 255 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 259 */ - z->ket = z->c; /* [, line 256 */ - z->bra = z->c; /* ], line 256 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 181 && z->p[z->c - 1] != 191)) goto lab1; /* substring, line 256 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 181 && z->p[z->c - 1] != 191)) goto lab1; if (!(find_among_b(z, a_12, 7))) goto lab1; - if (z->c > z->lb) goto lab1; /* atlimit, line 256 */ - { int ret = slice_from_s(z, 2, s_43); /* <-, line 258 */ + if (z->c > z->lb) goto lab1; + { int ret = slice_from_s(z, 2, s_43); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 260 */ - z->bra = z->c; /* ], line 260 */ - if (!(find_among_b(z, a_13, 33))) return 0; /* substring, line 260 */ - if (z->c > z->lb) return 0; /* atlimit, line 260 */ - { int ret = slice_from_s(z, 6, s_44); /* <-, line 264 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_13, 33))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 6, s_44); if (ret < 0) return ret; } } @@ -2714,91 +2713,91 @@ static int r_steps5(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_steps6(struct SN_env * z) { /* backwardmode */ +static int r_steps6(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 271 */ - if (!(find_among_b(z, a_18, 6))) return 0; /* substring, line 271 */ - z->bra = z->c; /* ], line 271 */ - { int ret = slice_del(z); /* delete, line 273 */ + z->ket = z->c; + if (!(find_among_b(z, a_18, 6))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 274 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 278 */ - z->ket = z->c; /* [, line 275 */ - z->bra = z->c; /* ], line 275 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 181) goto lab1; /* substring, line 275 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 181) goto lab1; if (!(find_among_b(z, a_15, 5))) goto lab1; - if (z->c > z->lb) goto lab1; /* atlimit, line 275 */ - { int ret = slice_from_s(z, 6, s_45); /* <-, line 277 */ + if (z->c > z->lb) goto lab1; + { int ret = slice_from_s(z, 6, s_45); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 279 */ - z->bra = z->c; /* ], line 279 */ - if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) goto lab2; /* substring, line 279 */ + z->ket = z->c; + z->bra = z->c; + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) goto lab2; if (!(find_among_b(z, a_16, 2))) goto lab2; - if (z->c > z->lb) goto lab2; /* atlimit, line 279 */ - { int ret = slice_from_s(z, 2, s_46); /* <-, line 281 */ + if (z->c > z->lb) goto lab2; + { int ret = slice_from_s(z, 2, s_46); if (ret < 0) return ret; } goto lab0; lab2: z->c = z->l - m1; - z->ket = z->c; /* [, line 283 */ - if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 186 && z->p[z->c - 1] != 189)) return 0; /* substring, line 283 */ + z->ket = z->c; + if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 186 && z->p[z->c - 1] != 189)) return 0; among_var = find_among_b(z, a_17, 10); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 283 */ - switch (among_var) { /* among, line 283 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 12, s_47); /* <-, line 284 */ + { int ret = slice_from_s(z, 12, s_47); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 8, s_48); /* <-, line 285 */ + { int ret = slice_from_s(z, 8, s_48); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 10, s_49); /* <-, line 286 */ + { int ret = slice_from_s(z, 10, s_49); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 6, s_50); /* <-, line 287 */ + { int ret = slice_from_s(z, 6, s_50); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 12, s_51); /* <-, line 288 */ + { int ret = slice_from_s(z, 12, s_51); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 10, s_52); /* <-, line 289 */ + { int ret = slice_from_s(z, 10, s_52); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 6, s_53); /* <-, line 290 */ + { int ret = slice_from_s(z, 6, s_53); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 16, s_54); /* <-, line 291 */ + { int ret = slice_from_s(z, 16, s_54); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 12, s_55); /* <-, line 292 */ + { int ret = slice_from_s(z, 12, s_55); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 10, s_56); /* <-, line 293 */ + { int ret = slice_from_s(z, 10, s_56); if (ret < 0) return ret; } break; @@ -2808,59 +2807,59 @@ static int r_steps6(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_steps7(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 300 */ - if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 177 && z->p[z->c - 1] != 185)) return 0; /* substring, line 300 */ +static int r_steps7(struct SN_env * z) { + z->ket = z->c; + if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 177 && z->p[z->c - 1] != 185)) return 0; if (!(find_among_b(z, a_20, 4))) return 0; - z->bra = z->c; /* ], line 300 */ - { int ret = slice_del(z); /* delete, line 302 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 303 */ - z->ket = z->c; /* [, line 304 */ - z->bra = z->c; /* ], line 304 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 135)) return 0; /* substring, line 304 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 135)) return 0; if (!(find_among_b(z, a_19, 2))) return 0; - if (z->c > z->lb) return 0; /* atlimit, line 304 */ - { int ret = slice_from_s(z, 8, s_57); /* <-, line 306 */ + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 8, s_57); if (ret < 0) return ret; } return 1; } -static int r_steps8(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 313 */ - if (!(find_among_b(z, a_23, 8))) return 0; /* substring, line 313 */ - z->bra = z->c; /* ], line 313 */ - { int ret = slice_del(z); /* delete, line 315 */ +static int r_steps8(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_23, 8))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 316 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 323 */ - z->ket = z->c; /* [, line 317 */ - z->bra = z->c; /* ], line 317 */ - if (!(find_among_b(z, a_21, 33))) goto lab1; /* substring, line 317 */ - if (z->c > z->lb) goto lab1; /* atlimit, line 317 */ - { int ret = slice_from_s(z, 4, s_58); /* <-, line 322 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_21, 33))) goto lab1; + if (z->c > z->lb) goto lab1; + { int ret = slice_from_s(z, 4, s_58); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 324 */ - z->bra = z->c; /* ], line 324 */ - if (!(find_among_b(z, a_22, 15))) goto lab2; /* substring, line 324 */ - if (z->c > z->lb) goto lab2; /* atlimit, line 324 */ - { int ret = slice_from_s(z, 6, s_59); /* <-, line 327 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_22, 15))) goto lab2; + if (z->c > z->lb) goto lab2; + { int ret = slice_from_s(z, 6, s_59); if (ret < 0) return ret; } goto lab0; lab2: z->c = z->l - m1; - z->ket = z->c; /* [, line 329 */ - z->bra = z->c; /* ], line 329 */ - if (!(eq_s_b(z, 6, s_60))) return 0; /* literal, line 329 */ - { int ret = slice_from_s(z, 6, s_61); /* <-, line 329 */ + z->ket = z->c; + z->bra = z->c; + if (!(eq_s_b(z, 6, s_60))) return 0; + { int ret = slice_from_s(z, 6, s_61); if (ret < 0) return ret; } } @@ -2868,31 +2867,31 @@ static int r_steps8(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_steps9(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 335 */ - if (z->c - 7 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-1610481664 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 335 */ +static int r_steps9(struct SN_env * z) { + z->ket = z->c; + if (z->c - 7 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-1610481664 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_26, 3))) return 0; - z->bra = z->c; /* ], line 335 */ - { int ret = slice_del(z); /* delete, line 337 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 338 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 341 */ - z->ket = z->c; /* [, line 339 */ - z->bra = z->c; /* ], line 339 */ - if (!(find_among_b(z, a_24, 4))) goto lab1; /* substring, line 339 */ - if (z->c > z->lb) goto lab1; /* atlimit, line 339 */ - { int ret = slice_from_s(z, 4, s_62); /* <-, line 340 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_24, 4))) goto lab1; + if (z->c > z->lb) goto lab1; + { int ret = slice_from_s(z, 4, s_62); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 342 */ - z->bra = z->c; /* ], line 342 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 181 && z->p[z->c - 1] != 189)) return 0; /* substring, line 342 */ + z->ket = z->c; + z->bra = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 181 && z->p[z->c - 1] != 189)) return 0; if (!(find_among_b(z, a_25, 2))) return 0; - { int ret = slice_from_s(z, 4, s_63); /* <-, line 343 */ + { int ret = slice_from_s(z, 4, s_63); if (ret < 0) return ret; } } @@ -2900,43 +2899,43 @@ static int r_steps9(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_steps10(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 350 */ - if (!(find_among_b(z, a_28, 4))) return 0; /* substring, line 350 */ - z->bra = z->c; /* ], line 350 */ - { int ret = slice_del(z); /* delete, line 352 */ +static int r_steps10(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_28, 4))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 353 */ - z->ket = z->c; /* [, line 354 */ - z->bra = z->c; /* ], line 354 */ - if (!(find_among_b(z, a_27, 7))) return 0; /* substring, line 354 */ - if (z->c > z->lb) return 0; /* atlimit, line 354 */ - { int ret = slice_from_s(z, 6, s_64); /* <-, line 356 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_27, 7))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 6, s_64); if (ret < 0) return ret; } return 1; } -static int r_step2a(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 363 */ - if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 363 */ +static int r_step2a(struct SN_env * z) { + z->ket = z->c; + if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; if (!(find_among_b(z, a_29, 2))) return 0; - z->bra = z->c; /* ], line 363 */ - { int ret = slice_del(z); /* delete, line 364 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* not, line 366 */ - z->ket = z->c; /* [, line 366 */ - if (!(find_among_b(z, a_30, 10))) goto lab0; /* substring, line 366 */ - z->bra = z->c; /* ], line 366 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(find_among_b(z, a_30, 10))) goto lab0; + z->bra = z->c; return 0; lab0: z->c = z->l - m1; } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 4, s_65); /* <+, line 369 */ + ret = insert_s(z, z->c, z->c, 4, s_65); z->c = saved_c; } if (ret < 0) return ret; @@ -2944,271 +2943,271 @@ static int r_step2a(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_step2b(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 373 */ - if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 373 */ +static int r_step2b(struct SN_env * z) { + z->ket = z->c; + if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; if (!(find_among_b(z, a_31, 2))) return 0; - z->bra = z->c; /* ], line 373 */ - { int ret = slice_del(z); /* delete, line 374 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 376 */ - z->bra = z->c; /* ], line 376 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 128 && z->p[z->c - 1] != 187)) return 0; /* substring, line 376 */ + z->ket = z->c; + z->bra = z->c; + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 128 && z->p[z->c - 1] != 187)) return 0; if (!(find_among_b(z, a_32, 8))) return 0; - { int ret = slice_from_s(z, 4, s_66); /* <-, line 377 */ + { int ret = slice_from_s(z, 4, s_66); if (ret < 0) return ret; } return 1; } -static int r_step2c(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 382 */ - if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 382 */ +static int r_step2c(struct SN_env * z) { + z->ket = z->c; + if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; if (!(find_among_b(z, a_33, 2))) return 0; - z->bra = z->c; /* ], line 382 */ - { int ret = slice_del(z); /* delete, line 383 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 385 */ - z->bra = z->c; /* ], line 385 */ - if (!(find_among_b(z, a_34, 15))) return 0; /* substring, line 385 */ - { int ret = slice_from_s(z, 6, s_67); /* <-, line 387 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_34, 15))) return 0; + { int ret = slice_from_s(z, 6, s_67); if (ret < 0) return ret; } return 1; } -static int r_step2d(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 392 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 392 */ +static int r_step2d(struct SN_env * z) { + z->ket = z->c; + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; if (!(find_among_b(z, a_35, 2))) return 0; - z->bra = z->c; /* ], line 392 */ - { int ret = slice_del(z); /* delete, line 393 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 393 */ - z->ket = z->c; /* [, line 395 */ - z->bra = z->c; /* ], line 395 */ - if (!(find_among_b(z, a_36, 8))) return 0; /* substring, line 395 */ - if (z->c > z->lb) return 0; /* atlimit, line 395 */ - { int ret = slice_from_s(z, 2, s_68); /* <-, line 396 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_36, 8))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 2, s_68); if (ret < 0) return ret; } return 1; } -static int r_step3(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 401 */ - if (!(find_among_b(z, a_37, 3))) return 0; /* substring, line 401 */ - z->bra = z->c; /* ], line 401 */ - { int ret = slice_del(z); /* delete, line 402 */ +static int r_step3(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_37, 3))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 402 */ - z->ket = z->c; /* [, line 404 */ - z->bra = z->c; /* ], line 404 */ - if (in_grouping_b_U(z, g_v, 945, 969, 0)) return 0; /* grouping v, line 404 */ - { int ret = slice_from_s(z, 2, s_69); /* <-, line 404 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (in_grouping_b_U(z, g_v, 945, 969, 0)) return 0; + { int ret = slice_from_s(z, 2, s_69); if (ret < 0) return ret; } return 1; } -static int r_step4(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 408 */ - if (!(find_among_b(z, a_38, 4))) return 0; /* substring, line 408 */ - z->bra = z->c; /* ], line 408 */ - { int ret = slice_del(z); /* delete, line 409 */ +static int r_step4(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_38, 4))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 409 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 411 */ - z->ket = z->c; /* [, line 411 */ - z->bra = z->c; /* ], line 411 */ - if (in_grouping_b_U(z, g_v, 945, 969, 0)) goto lab1; /* grouping v, line 411 */ - { int ret = slice_from_s(z, 4, s_70); /* <-, line 411 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (in_grouping_b_U(z, g_v, 945, 969, 0)) goto lab1; + { int ret = slice_from_s(z, 4, s_70); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 412 */ + z->ket = z->c; } lab0: - z->bra = z->c; /* ], line 412 */ - if (!(find_among_b(z, a_39, 36))) return 0; /* substring, line 412 */ - if (z->c > z->lb) return 0; /* atlimit, line 412 */ - { int ret = slice_from_s(z, 4, s_71); /* <-, line 417 */ + z->bra = z->c; + if (!(find_among_b(z, a_39, 36))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_71); if (ret < 0) return ret; } return 1; } -static int r_step5a(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* do, line 422 */ - if (!(eq_s_b(z, 10, s_72))) goto lab0; /* literal, line 422 */ - if (z->c > z->lb) goto lab0; /* atlimit, line 422 */ - { int ret = slice_from_s(z, 8, s_73); /* <-, line 422 */ +static int r_step5a(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 10, s_72))) goto lab0; + if (z->c > z->lb) goto lab0; + { int ret = slice_from_s(z, 8, s_73); if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 423 */ - z->ket = z->c; /* [, line 424 */ - if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab1; /* substring, line 424 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab1; if (!(find_among_b(z, a_40, 5))) goto lab1; - z->bra = z->c; /* ], line 424 */ - { int ret = slice_del(z); /* delete, line 425 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 425 */ + z->I[0] = 0; lab1: z->c = z->l - m2; } - z->ket = z->c; /* [, line 428 */ - if (!(eq_s_b(z, 6, s_74))) return 0; /* literal, line 428 */ - z->bra = z->c; /* ], line 428 */ - { int ret = slice_del(z); /* delete, line 429 */ + z->ket = z->c; + if (!(eq_s_b(z, 6, s_74))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 430 */ - z->ket = z->c; /* [, line 431 */ - z->bra = z->c; /* ], line 431 */ - if (!(find_among_b(z, a_41, 12))) return 0; /* substring, line 431 */ - if (z->c > z->lb) return 0; /* atlimit, line 431 */ - { int ret = slice_from_s(z, 4, s_75); /* <-, line 433 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_41, 12))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_75); if (ret < 0) return ret; } return 1; } -static int r_step5b(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* do, line 438 */ - z->ket = z->c; /* [, line 439 */ - if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab0; /* substring, line 439 */ +static int r_step5b(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab0; if (!(find_among_b(z, a_43, 11))) goto lab0; - z->bra = z->c; /* ], line 439 */ - { int ret = slice_del(z); /* delete, line 442 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 443 */ - z->ket = z->c; /* [, line 444 */ - z->bra = z->c; /* ], line 444 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 131)) goto lab0; /* substring, line 444 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 131)) goto lab0; if (!(find_among_b(z, a_42, 2))) goto lab0; - if (z->c > z->lb) goto lab0; /* atlimit, line 444 */ - { int ret = slice_from_s(z, 8, s_76); /* <-, line 445 */ + if (z->c > z->lb) goto lab0; + { int ret = slice_from_s(z, 8, s_76); if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - z->ket = z->c; /* [, line 450 */ - if (!(eq_s_b(z, 6, s_77))) return 0; /* literal, line 450 */ - z->bra = z->c; /* ], line 450 */ - { int ret = slice_del(z); /* delete, line 451 */ + z->ket = z->c; + if (!(eq_s_b(z, 6, s_77))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 452 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 453 */ - z->ket = z->c; /* [, line 453 */ - z->bra = z->c; /* ], line 453 */ - if (in_grouping_b_U(z, g_v2, 945, 969, 0)) goto lab2; /* grouping v2, line 453 */ - { int ret = slice_from_s(z, 4, s_78); /* <-, line 453 */ + z->I[0] = 0; + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + z->bra = z->c; + if (in_grouping_b_U(z, g_v2, 945, 969, 0)) goto lab2; + { int ret = slice_from_s(z, 4, s_78); if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m2; - z->ket = z->c; /* [, line 454 */ + z->ket = z->c; } lab1: - z->bra = z->c; /* ], line 454 */ - if (!(find_among_b(z, a_44, 95))) return 0; /* substring, line 454 */ - if (z->c > z->lb) return 0; /* atlimit, line 454 */ - { int ret = slice_from_s(z, 4, s_79); /* <-, line 471 */ + z->bra = z->c; + if (!(find_among_b(z, a_44, 95))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_79); if (ret < 0) return ret; } return 1; } -static int r_step5c(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* do, line 476 */ - z->ket = z->c; /* [, line 477 */ - if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab0; /* substring, line 477 */ +static int r_step5c(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab0; if (!(find_among_b(z, a_45, 1))) goto lab0; - z->bra = z->c; /* ], line 477 */ - { int ret = slice_del(z); /* delete, line 478 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 478 */ + z->I[0] = 0; lab0: z->c = z->l - m1; } - z->ket = z->c; /* [, line 481 */ - if (!(eq_s_b(z, 6, s_80))) return 0; /* literal, line 481 */ - z->bra = z->c; /* ], line 481 */ - { int ret = slice_del(z); /* delete, line 482 */ + z->ket = z->c; + if (!(eq_s_b(z, 6, s_80))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 483 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 484 */ - z->ket = z->c; /* [, line 484 */ - z->bra = z->c; /* ], line 484 */ - if (in_grouping_b_U(z, g_v2, 945, 969, 0)) goto lab2; /* grouping v2, line 484 */ - { int ret = slice_from_s(z, 4, s_81); /* <-, line 484 */ + z->I[0] = 0; + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + z->bra = z->c; + if (in_grouping_b_U(z, g_v2, 945, 969, 0)) goto lab2; + { int ret = slice_from_s(z, 4, s_81); if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m2; - z->ket = z->c; /* [, line 485 */ - z->bra = z->c; /* ], line 485 */ - if (!(find_among_b(z, a_46, 31))) goto lab3; /* substring, line 485 */ - { int ret = slice_from_s(z, 4, s_82); /* <-, line 489 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_46, 31))) goto lab3; + { int ret = slice_from_s(z, 4, s_82); if (ret < 0) return ret; } goto lab1; lab3: z->c = z->l - m2; - z->ket = z->c; /* [, line 491 */ + z->ket = z->c; } lab1: - z->bra = z->c; /* ], line 491 */ - if (!(find_among_b(z, a_47, 25))) return 0; /* substring, line 491 */ - if (z->c > z->lb) return 0; /* atlimit, line 491 */ - { int ret = slice_from_s(z, 4, s_83); /* <-, line 495 */ + z->bra = z->c; + if (!(find_among_b(z, a_47, 25))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_83); if (ret < 0) return ret; } return 1; } -static int r_step5d(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 500 */ - if (z->c - 9 <= z->lb || z->p[z->c - 1] != 131) return 0; /* substring, line 500 */ +static int r_step5d(struct SN_env * z) { + z->ket = z->c; + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 131) return 0; if (!(find_among_b(z, a_48, 2))) return 0; - z->bra = z->c; /* ], line 500 */ - { int ret = slice_del(z); /* delete, line 502 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 503 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 504 */ - z->ket = z->c; /* [, line 504 */ - z->bra = z->c; /* ], line 504 */ - if (!(eq_s_b(z, 6, s_84))) goto lab1; /* literal, line 504 */ - if (z->c > z->lb) goto lab1; /* atlimit, line 504 */ - { int ret = slice_from_s(z, 6, s_85); /* <-, line 504 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (!(eq_s_b(z, 6, s_84))) goto lab1; + if (z->c > z->lb) goto lab1; + { int ret = slice_from_s(z, 6, s_85); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 505 */ - z->bra = z->c; /* ], line 505 */ - if (!(eq_s_b(z, 6, s_86))) return 0; /* literal, line 505 */ - { int ret = slice_from_s(z, 6, s_87); /* <-, line 505 */ + z->ket = z->c; + z->bra = z->c; + if (!(eq_s_b(z, 6, s_86))) return 0; + { int ret = slice_from_s(z, 6, s_87); if (ret < 0) return ret; } } @@ -3216,97 +3215,97 @@ static int r_step5d(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_step5e(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 511 */ - if (z->c - 11 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 511 */ +static int r_step5e(struct SN_env * z) { + z->ket = z->c; + if (z->c - 11 <= z->lb || z->p[z->c - 1] != 181) return 0; if (!(find_among_b(z, a_49, 2))) return 0; - z->bra = z->c; /* ], line 511 */ - { int ret = slice_del(z); /* delete, line 513 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 514 */ - z->ket = z->c; /* [, line 515 */ - z->bra = z->c; /* ], line 515 */ - if (!(eq_s_b(z, 4, s_88))) return 0; /* literal, line 515 */ - if (z->c > z->lb) return 0; /* atlimit, line 515 */ - { int ret = slice_from_s(z, 10, s_89); /* <-, line 515 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(eq_s_b(z, 4, s_88))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 10, s_89); if (ret < 0) return ret; } return 1; } -static int r_step5f(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* do, line 521 */ - z->ket = z->c; /* [, line 522 */ - if (!(eq_s_b(z, 10, s_90))) goto lab0; /* literal, line 522 */ - z->bra = z->c; /* ], line 522 */ - { int ret = slice_del(z); /* delete, line 523 */ +static int r_step5f(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 10, s_90))) goto lab0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 524 */ - z->ket = z->c; /* [, line 525 */ - z->bra = z->c; /* ], line 525 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 128 && z->p[z->c - 1] != 134)) goto lab0; /* substring, line 525 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 128 && z->p[z->c - 1] != 134)) goto lab0; if (!(find_among_b(z, a_50, 6))) goto lab0; - if (z->c > z->lb) goto lab0; /* atlimit, line 525 */ - { int ret = slice_from_s(z, 8, s_91); /* <-, line 526 */ + if (z->c > z->lb) goto lab0; + { int ret = slice_from_s(z, 8, s_91); if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - z->ket = z->c; /* [, line 529 */ - if (!(eq_s_b(z, 8, s_92))) return 0; /* literal, line 529 */ - z->bra = z->c; /* ], line 529 */ - { int ret = slice_del(z); /* delete, line 530 */ + z->ket = z->c; + if (!(eq_s_b(z, 8, s_92))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 531 */ - z->ket = z->c; /* [, line 532 */ - z->bra = z->c; /* ], line 532 */ - if (!(find_among_b(z, a_51, 9))) return 0; /* substring, line 532 */ - if (z->c > z->lb) return 0; /* atlimit, line 532 */ - { int ret = slice_from_s(z, 8, s_93); /* <-, line 534 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_51, 9))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 8, s_93); if (ret < 0) return ret; } return 1; } -static int r_step5g(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* do, line 539 */ - z->ket = z->c; /* [, line 540 */ - if (!(find_among_b(z, a_52, 3))) goto lab0; /* substring, line 540 */ - z->bra = z->c; /* ], line 540 */ - { int ret = slice_del(z); /* delete, line 541 */ +static int r_step5g(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(find_among_b(z, a_52, 3))) goto lab0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 541 */ + z->I[0] = 0; lab0: z->c = z->l - m1; } - z->ket = z->c; /* [, line 544 */ - if (!(find_among_b(z, a_55, 3))) return 0; /* substring, line 544 */ - z->bra = z->c; /* ], line 544 */ - { int ret = slice_del(z); /* delete, line 546 */ + z->ket = z->c; + if (!(find_among_b(z, a_55, 3))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 547 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 550 */ - z->ket = z->c; /* [, line 548 */ - z->bra = z->c; /* ], line 548 */ - if (!(find_among_b(z, a_53, 6))) goto lab2; /* substring, line 548 */ - { int ret = slice_from_s(z, 4, s_94); /* <-, line 549 */ + z->I[0] = 0; + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_53, 6))) goto lab2; + { int ret = slice_from_s(z, 4, s_94); if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m2; - z->ket = z->c; /* [, line 551 */ - z->bra = z->c; /* ], line 551 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 184) return 0; /* substring, line 551 */ + z->ket = z->c; + z->bra = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 184) return 0; if (!(find_among_b(z, a_54, 5))) return 0; - if (z->c > z->lb) return 0; /* atlimit, line 551 */ - { int ret = slice_from_s(z, 4, s_95); /* <-, line 552 */ + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_95); if (ret < 0) return ret; } } @@ -3314,29 +3313,29 @@ static int r_step5g(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_step5h(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 559 */ - if (!(find_among_b(z, a_58, 3))) return 0; /* substring, line 559 */ - z->bra = z->c; /* ], line 559 */ - { int ret = slice_del(z); /* delete, line 561 */ +static int r_step5h(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_58, 3))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 562 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 567 */ - z->ket = z->c; /* [, line 563 */ - z->bra = z->c; /* ], line 563 */ - if (!(find_among_b(z, a_56, 12))) goto lab1; /* substring, line 563 */ - { int ret = slice_from_s(z, 6, s_96); /* <-, line 565 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_56, 12))) goto lab1; + { int ret = slice_from_s(z, 6, s_96); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 568 */ - z->bra = z->c; /* ], line 568 */ - if (!(find_among_b(z, a_57, 25))) return 0; /* substring, line 568 */ - if (z->c > z->lb) return 0; /* atlimit, line 568 */ - { int ret = slice_from_s(z, 6, s_97); /* <-, line 572 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_57, 25))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 6, s_97); if (ret < 0) return ret; } } @@ -3344,48 +3343,48 @@ static int r_step5h(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_step5i(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 579 */ - if (!(find_among_b(z, a_62, 3))) return 0; /* substring, line 579 */ - z->bra = z->c; /* ], line 579 */ - { int ret = slice_del(z); /* delete, line 581 */ +static int r_step5i(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_62, 3))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 582 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 583 */ - z->ket = z->c; /* [, line 583 */ - z->bra = z->c; /* ], line 583 */ - if (!(eq_s_b(z, 8, s_98))) goto lab1; /* literal, line 583 */ - { int ret = slice_from_s(z, 4, s_99); /* <-, line 583 */ + z->I[0] = 0; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + z->bra = z->c; + if (!(eq_s_b(z, 8, s_98))) goto lab1; + { int ret = slice_from_s(z, 4, s_99); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* not, line 584 */ - z->ket = z->c; /* [, line 584 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 134 && z->p[z->c - 1] != 135)) goto lab2; /* substring, line 584 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 134 && z->p[z->c - 1] != 135)) goto lab2; if (!(find_among_b(z, a_59, 2))) goto lab2; - z->bra = z->c; /* ], line 584 */ + z->bra = z->c; return 0; lab2: z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* or, line 588 */ - z->ket = z->c; /* [, line 585 */ - z->bra = z->c; /* ], line 585 */ - if (!(find_among_b(z, a_60, 10))) goto lab4; /* substring, line 585 */ - { int ret = slice_from_s(z, 4, s_100); /* <-, line 587 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_60, 10))) goto lab4; + { int ret = slice_from_s(z, 4, s_100); if (ret < 0) return ret; } goto lab3; lab4: z->c = z->l - m3; - z->ket = z->c; /* [, line 589 */ - z->bra = z->c; /* ], line 589 */ - if (!(find_among_b(z, a_61, 44))) return 0; /* substring, line 589 */ - if (z->c > z->lb) return 0; /* atlimit, line 589 */ - { int ret = slice_from_s(z, 4, s_101); /* <-, line 595 */ + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_61, 44))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_101); if (ret < 0) return ret; } } @@ -3396,315 +3395,315 @@ static int r_step5i(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_step5j(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 603 */ - if (!(find_among_b(z, a_63, 3))) return 0; /* substring, line 603 */ - z->bra = z->c; /* ], line 603 */ - { int ret = slice_del(z); /* delete, line 604 */ +static int r_step5j(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_63, 3))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 604 */ - z->ket = z->c; /* [, line 606 */ - z->bra = z->c; /* ], line 606 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 189) return 0; /* substring, line 606 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 189) return 0; if (!(find_among_b(z, a_64, 6))) return 0; - if (z->c > z->lb) return 0; /* atlimit, line 606 */ - { int ret = slice_from_s(z, 4, s_102); /* <-, line 607 */ + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 4, s_102); if (ret < 0) return ret; } return 1; } -static int r_step5k(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 612 */ - if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 612 */ +static int r_step5k(struct SN_env * z) { + z->ket = z->c; + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; if (!(find_among_b(z, a_65, 1))) return 0; - z->bra = z->c; /* ], line 612 */ - { int ret = slice_del(z); /* delete, line 613 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 613 */ - z->ket = z->c; /* [, line 615 */ - z->bra = z->c; /* ], line 615 */ - if (!(find_among_b(z, a_66, 10))) return 0; /* substring, line 615 */ - if (z->c > z->lb) return 0; /* atlimit, line 615 */ - { int ret = slice_from_s(z, 6, s_103); /* <-, line 617 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_66, 10))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 6, s_103); if (ret < 0) return ret; } return 1; } -static int r_step5l(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 622 */ - if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 622 */ +static int r_step5l(struct SN_env * z) { + z->ket = z->c; + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; if (!(find_among_b(z, a_67, 3))) return 0; - z->bra = z->c; /* ], line 622 */ - { int ret = slice_del(z); /* delete, line 623 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 623 */ - z->ket = z->c; /* [, line 625 */ - z->bra = z->c; /* ], line 625 */ - if (!(find_among_b(z, a_68, 6))) return 0; /* substring, line 625 */ - if (z->c > z->lb) return 0; /* atlimit, line 625 */ - { int ret = slice_from_s(z, 6, s_104); /* <-, line 626 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_68, 6))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 6, s_104); if (ret < 0) return ret; } return 1; } -static int r_step5m(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 631 */ - if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 631 */ +static int r_step5m(struct SN_env * z) { + z->ket = z->c; + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; if (!(find_among_b(z, a_69, 3))) return 0; - z->bra = z->c; /* ], line 631 */ - { int ret = slice_del(z); /* delete, line 632 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 0; /* unset test1, line 632 */ - z->ket = z->c; /* [, line 634 */ - z->bra = z->c; /* ], line 634 */ - if (!(find_among_b(z, a_70, 7))) return 0; /* substring, line 634 */ - if (z->c > z->lb) return 0; /* atlimit, line 634 */ - { int ret = slice_from_s(z, 6, s_105); /* <-, line 636 */ + z->I[0] = 0; + z->ket = z->c; + z->bra = z->c; + if (!(find_among_b(z, a_70, 7))) return 0; + if (z->c > z->lb) return 0; + { int ret = slice_from_s(z, 6, s_105); if (ret < 0) return ret; } return 1; } -static int r_step6(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* do, line 641 */ - z->ket = z->c; /* [, line 642 */ - if (!(find_among_b(z, a_71, 3))) goto lab0; /* substring, line 642 */ - z->bra = z->c; /* ], line 642 */ - { int ret = slice_from_s(z, 4, s_106); /* <-, line 643 */ +static int r_step6(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(find_among_b(z, a_71, 3))) goto lab0; + z->bra = z->c; + { int ret = slice_from_s(z, 4, s_106); if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - if (!(z->B[0])) return 0; /* Boolean test test1, line 646 */ - z->ket = z->c; /* [, line 647 */ - if (!(find_among_b(z, a_72, 84))) return 0; /* substring, line 647 */ - z->bra = z->c; /* ], line 647 */ - { int ret = slice_del(z); /* delete, line 657 */ + if (!(z->I[0])) return 0; + z->ket = z->c; + if (!(find_among_b(z, a_72, 84))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_step7(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 662 */ - if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 132)) return 0; /* substring, line 662 */ +static int r_step7(struct SN_env * z) { + z->ket = z->c; + if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 132)) return 0; if (!(find_among_b(z, a_73, 8))) return 0; - z->bra = z->c; /* ], line 662 */ - { int ret = slice_del(z); /* delete, line 663 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int greek_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - z->lb = z->c; z->c = z->l; /* backwards, line 669 */ +extern int greek_UTF_8_stem(struct SN_env * z) { + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 670 */ - { int ret = r_tolower(z); /* call tolower, line 670 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_tolower(z); if (ret < 0) return ret; } z->c = z->l - m1; } - { int ret = r_has_min_length(z); /* call has_min_length, line 671 */ + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - z->B[0] = 1; /* set test1, line 672 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 673 */ - { int ret = r_step1(z); /* call step1, line 673 */ + z->I[0] = 1; + { int m2 = z->l - z->c; (void)m2; + { int ret = r_step1(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 674 */ - { int ret = r_steps1(z); /* call steps1, line 674 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_steps1(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 675 */ - { int ret = r_steps2(z); /* call steps2, line 675 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_steps2(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 676 */ - { int ret = r_steps3(z); /* call steps3, line 676 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_steps3(z); if (ret < 0) return ret; } z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* do, line 677 */ - { int ret = r_steps4(z); /* call steps4, line 677 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_steps4(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 678 */ - { int ret = r_steps5(z); /* call steps5, line 678 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_steps5(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 679 */ - { int ret = r_steps6(z); /* call steps6, line 679 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_steps6(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 680 */ - { int ret = r_steps7(z); /* call steps7, line 680 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_steps7(z); if (ret < 0) return ret; } z->c = z->l - m9; } - { int m10 = z->l - z->c; (void)m10; /* do, line 681 */ - { int ret = r_steps8(z); /* call steps8, line 681 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_steps8(z); if (ret < 0) return ret; } z->c = z->l - m10; } - { int m11 = z->l - z->c; (void)m11; /* do, line 682 */ - { int ret = r_steps9(z); /* call steps9, line 682 */ + { int m11 = z->l - z->c; (void)m11; + { int ret = r_steps9(z); if (ret < 0) return ret; } z->c = z->l - m11; } - { int m12 = z->l - z->c; (void)m12; /* do, line 683 */ - { int ret = r_steps10(z); /* call steps10, line 683 */ + { int m12 = z->l - z->c; (void)m12; + { int ret = r_steps10(z); if (ret < 0) return ret; } z->c = z->l - m12; } - { int m13 = z->l - z->c; (void)m13; /* do, line 684 */ - { int ret = r_step2a(z); /* call step2a, line 684 */ + { int m13 = z->l - z->c; (void)m13; + { int ret = r_step2a(z); if (ret < 0) return ret; } z->c = z->l - m13; } - { int m14 = z->l - z->c; (void)m14; /* do, line 685 */ - { int ret = r_step2b(z); /* call step2b, line 685 */ + { int m14 = z->l - z->c; (void)m14; + { int ret = r_step2b(z); if (ret < 0) return ret; } z->c = z->l - m14; } - { int m15 = z->l - z->c; (void)m15; /* do, line 686 */ - { int ret = r_step2c(z); /* call step2c, line 686 */ + { int m15 = z->l - z->c; (void)m15; + { int ret = r_step2c(z); if (ret < 0) return ret; } z->c = z->l - m15; } - { int m16 = z->l - z->c; (void)m16; /* do, line 687 */ - { int ret = r_step2d(z); /* call step2d, line 687 */ + { int m16 = z->l - z->c; (void)m16; + { int ret = r_step2d(z); if (ret < 0) return ret; } z->c = z->l - m16; } - { int m17 = z->l - z->c; (void)m17; /* do, line 688 */ - { int ret = r_step3(z); /* call step3, line 688 */ + { int m17 = z->l - z->c; (void)m17; + { int ret = r_step3(z); if (ret < 0) return ret; } z->c = z->l - m17; } - { int m18 = z->l - z->c; (void)m18; /* do, line 689 */ - { int ret = r_step4(z); /* call step4, line 689 */ + { int m18 = z->l - z->c; (void)m18; + { int ret = r_step4(z); if (ret < 0) return ret; } z->c = z->l - m18; } - { int m19 = z->l - z->c; (void)m19; /* do, line 690 */ - { int ret = r_step5a(z); /* call step5a, line 690 */ + { int m19 = z->l - z->c; (void)m19; + { int ret = r_step5a(z); if (ret < 0) return ret; } z->c = z->l - m19; } - { int m20 = z->l - z->c; (void)m20; /* do, line 691 */ - { int ret = r_step5b(z); /* call step5b, line 691 */ + { int m20 = z->l - z->c; (void)m20; + { int ret = r_step5b(z); if (ret < 0) return ret; } z->c = z->l - m20; } - { int m21 = z->l - z->c; (void)m21; /* do, line 692 */ - { int ret = r_step5c(z); /* call step5c, line 692 */ + { int m21 = z->l - z->c; (void)m21; + { int ret = r_step5c(z); if (ret < 0) return ret; } z->c = z->l - m21; } - { int m22 = z->l - z->c; (void)m22; /* do, line 693 */ - { int ret = r_step5d(z); /* call step5d, line 693 */ + { int m22 = z->l - z->c; (void)m22; + { int ret = r_step5d(z); if (ret < 0) return ret; } z->c = z->l - m22; } - { int m23 = z->l - z->c; (void)m23; /* do, line 694 */ - { int ret = r_step5e(z); /* call step5e, line 694 */ + { int m23 = z->l - z->c; (void)m23; + { int ret = r_step5e(z); if (ret < 0) return ret; } z->c = z->l - m23; } - { int m24 = z->l - z->c; (void)m24; /* do, line 695 */ - { int ret = r_step5f(z); /* call step5f, line 695 */ + { int m24 = z->l - z->c; (void)m24; + { int ret = r_step5f(z); if (ret < 0) return ret; } z->c = z->l - m24; } - { int m25 = z->l - z->c; (void)m25; /* do, line 696 */ - { int ret = r_step5g(z); /* call step5g, line 696 */ + { int m25 = z->l - z->c; (void)m25; + { int ret = r_step5g(z); if (ret < 0) return ret; } z->c = z->l - m25; } - { int m26 = z->l - z->c; (void)m26; /* do, line 697 */ - { int ret = r_step5h(z); /* call step5h, line 697 */ + { int m26 = z->l - z->c; (void)m26; + { int ret = r_step5h(z); if (ret < 0) return ret; } z->c = z->l - m26; } - { int m27 = z->l - z->c; (void)m27; /* do, line 698 */ - { int ret = r_step5j(z); /* call step5j, line 698 */ + { int m27 = z->l - z->c; (void)m27; + { int ret = r_step5j(z); if (ret < 0) return ret; } z->c = z->l - m27; } - { int m28 = z->l - z->c; (void)m28; /* do, line 699 */ - { int ret = r_step5i(z); /* call step5i, line 699 */ + { int m28 = z->l - z->c; (void)m28; + { int ret = r_step5i(z); if (ret < 0) return ret; } z->c = z->l - m28; } - { int m29 = z->l - z->c; (void)m29; /* do, line 700 */ - { int ret = r_step5k(z); /* call step5k, line 700 */ + { int m29 = z->l - z->c; (void)m29; + { int ret = r_step5k(z); if (ret < 0) return ret; } z->c = z->l - m29; } - { int m30 = z->l - z->c; (void)m30; /* do, line 701 */ - { int ret = r_step5l(z); /* call step5l, line 701 */ + { int m30 = z->l - z->c; (void)m30; + { int ret = r_step5l(z); if (ret < 0) return ret; } z->c = z->l - m30; } - { int m31 = z->l - z->c; (void)m31; /* do, line 702 */ - { int ret = r_step5m(z); /* call step5m, line 702 */ + { int m31 = z->l - z->c; (void)m31; + { int ret = r_step5m(z); if (ret < 0) return ret; } z->c = z->l - m31; } - { int m32 = z->l - z->c; (void)m32; /* do, line 703 */ - { int ret = r_step6(z); /* call step6, line 703 */ + { int m32 = z->l - z->c; (void)m32; + { int ret = r_step6(z); if (ret < 0) return ret; } z->c = z->l - m32; } - { int m33 = z->l - z->c; (void)m33; /* do, line 704 */ - { int ret = r_step7(z); /* call step7, line 704 */ + { int m33 = z->l - z->c; (void)m33; + { int ret = r_step7(z); if (ret < 0) return ret; } z->c = z->l - m33; @@ -3713,7 +3712,7 @@ extern int greek_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * greek_UTF_8_create_env(void) { return SN_create_env(0, 0, 1); } +extern struct SN_env * greek_UTF_8_create_env(void) { return SN_create_env(0, 1); } extern void greek_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_hindi.c b/src/backend/snowball/libstemmer/stem_UTF_8_hindi.c index 06bc674eb90f..68f9c557af95 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_hindi.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_hindi.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -157,176 +157,176 @@ static const symbol s_0_131[3] = { 0xE0, 0xA4, 0xBF }; static const struct among a_0[132] = { -/* 0 */ { 3, s_0_0, -1, -1, 0}, -/* 1 */ { 12, s_0_1, 0, -1, 0}, -/* 2 */ { 12, s_0_2, 0, -1, 0}, -/* 3 */ { 12, s_0_3, 0, -1, 0}, -/* 4 */ { 15, s_0_4, 3, -1, 0}, -/* 5 */ { 15, s_0_5, 3, -1, 0}, -/* 6 */ { 12, s_0_6, 0, -1, 0}, -/* 7 */ { 15, s_0_7, 6, -1, 0}, -/* 8 */ { 15, s_0_8, 6, -1, 0}, -/* 9 */ { 9, s_0_9, 0, -1, 0}, -/* 10 */ { 9, s_0_10, 0, -1, 0}, -/* 11 */ { 9, s_0_11, 0, -1, 0}, -/* 12 */ { 12, s_0_12, 11, -1, 0}, -/* 13 */ { 12, s_0_13, 11, -1, 0}, -/* 14 */ { 9, s_0_14, 0, -1, 0}, -/* 15 */ { 12, s_0_15, 14, -1, 0}, -/* 16 */ { 12, s_0_16, 14, -1, 0}, -/* 17 */ { 6, s_0_17, 0, -1, r_CONSONANT}, -/* 18 */ { 9, s_0_18, 17, -1, 0}, -/* 19 */ { 9, s_0_19, 17, -1, 0}, -/* 20 */ { 9, s_0_20, 17, -1, 0}, -/* 21 */ { 6, s_0_21, 0, -1, r_CONSONANT}, -/* 22 */ { 9, s_0_22, 21, -1, 0}, -/* 23 */ { 6, s_0_23, -1, -1, 0}, -/* 24 */ { 6, s_0_24, -1, -1, 0}, -/* 25 */ { 12, s_0_25, 24, -1, 0}, -/* 26 */ { 15, s_0_26, 25, -1, 0}, -/* 27 */ { 15, s_0_27, 25, -1, 0}, -/* 28 */ { 12, s_0_28, 24, -1, 0}, -/* 29 */ { 3, s_0_29, -1, -1, 0}, -/* 30 */ { 6, s_0_30, -1, -1, 0}, -/* 31 */ { 9, s_0_31, 30, -1, r_CONSONANT}, -/* 32 */ { 12, s_0_32, 31, -1, 0}, -/* 33 */ { 12, s_0_33, 31, -1, 0}, -/* 34 */ { 12, s_0_34, 31, -1, 0}, -/* 35 */ { 6, s_0_35, -1, -1, 0}, -/* 36 */ { 9, s_0_36, 35, -1, 0}, -/* 37 */ { 9, s_0_37, 35, -1, 0}, -/* 38 */ { 6, s_0_38, -1, -1, 0}, -/* 39 */ { 6, s_0_39, -1, -1, 0}, -/* 40 */ { 9, s_0_40, 39, -1, 0}, -/* 41 */ { 9, s_0_41, 39, -1, 0}, -/* 42 */ { 6, s_0_42, -1, -1, 0}, -/* 43 */ { 12, s_0_43, 42, -1, 0}, -/* 44 */ { 15, s_0_44, 43, -1, 0}, -/* 45 */ { 15, s_0_45, 43, -1, 0}, -/* 46 */ { 12, s_0_46, 42, -1, 0}, -/* 47 */ { 6, s_0_47, -1, -1, 0}, -/* 48 */ { 9, s_0_48, 47, -1, 0}, -/* 49 */ { 9, s_0_49, 47, -1, 0}, -/* 50 */ { 9, s_0_50, 47, -1, 0}, -/* 51 */ { 9, s_0_51, 47, -1, 0}, -/* 52 */ { 12, s_0_52, 51, -1, r_CONSONANT}, -/* 53 */ { 15, s_0_53, 52, -1, 0}, -/* 54 */ { 12, s_0_54, 51, -1, r_CONSONANT}, -/* 55 */ { 15, s_0_55, 54, -1, 0}, -/* 56 */ { 6, s_0_56, -1, -1, 0}, -/* 57 */ { 9, s_0_57, 56, -1, 0}, -/* 58 */ { 9, s_0_58, 56, -1, 0}, -/* 59 */ { 9, s_0_59, 56, -1, 0}, -/* 60 */ { 9, s_0_60, 56, -1, 0}, -/* 61 */ { 12, s_0_61, 60, -1, r_CONSONANT}, -/* 62 */ { 15, s_0_62, 61, -1, 0}, -/* 63 */ { 12, s_0_63, 60, -1, r_CONSONANT}, -/* 64 */ { 15, s_0_64, 63, -1, 0}, -/* 65 */ { 6, s_0_65, -1, -1, 0}, -/* 66 */ { 12, s_0_66, 65, -1, 0}, -/* 67 */ { 15, s_0_67, 66, -1, 0}, -/* 68 */ { 15, s_0_68, 66, -1, 0}, -/* 69 */ { 12, s_0_69, 65, -1, 0}, -/* 70 */ { 3, s_0_70, -1, -1, 0}, -/* 71 */ { 3, s_0_71, -1, -1, 0}, -/* 72 */ { 3, s_0_72, -1, -1, 0}, -/* 73 */ { 3, s_0_73, -1, -1, 0}, -/* 74 */ { 3, s_0_74, -1, -1, 0}, -/* 75 */ { 12, s_0_75, 74, -1, 0}, -/* 76 */ { 12, s_0_76, 74, -1, 0}, -/* 77 */ { 15, s_0_77, 76, -1, 0}, -/* 78 */ { 15, s_0_78, 76, -1, 0}, -/* 79 */ { 9, s_0_79, 74, -1, 0}, -/* 80 */ { 9, s_0_80, 74, -1, 0}, -/* 81 */ { 12, s_0_81, 80, -1, 0}, -/* 82 */ { 12, s_0_82, 80, -1, 0}, -/* 83 */ { 6, s_0_83, 74, -1, r_CONSONANT}, -/* 84 */ { 9, s_0_84, 83, -1, 0}, -/* 85 */ { 9, s_0_85, 83, -1, 0}, -/* 86 */ { 9, s_0_86, 83, -1, 0}, -/* 87 */ { 6, s_0_87, 74, -1, r_CONSONANT}, -/* 88 */ { 9, s_0_88, 87, -1, 0}, -/* 89 */ { 9, s_0_89, 87, -1, 0}, -/* 90 */ { 9, s_0_90, 87, -1, 0}, -/* 91 */ { 3, s_0_91, -1, -1, 0}, -/* 92 */ { 6, s_0_92, 91, -1, 0}, -/* 93 */ { 6, s_0_93, 91, -1, 0}, -/* 94 */ { 3, s_0_94, -1, -1, 0}, -/* 95 */ { 3, s_0_95, -1, -1, 0}, -/* 96 */ { 3, s_0_96, -1, -1, 0}, -/* 97 */ { 3, s_0_97, -1, -1, 0}, -/* 98 */ { 3, s_0_98, -1, -1, 0}, -/* 99 */ { 6, s_0_99, 98, -1, 0}, -/*100 */ { 6, s_0_100, 98, -1, 0}, -/*101 */ { 9, s_0_101, 100, -1, 0}, -/*102 */ { 9, s_0_102, 100, -1, 0}, -/*103 */ { 6, s_0_103, 98, -1, 0}, -/*104 */ { 6, s_0_104, 98, -1, 0}, -/*105 */ { 3, s_0_105, -1, -1, 0}, -/*106 */ { 6, s_0_106, 105, -1, 0}, -/*107 */ { 6, s_0_107, 105, -1, 0}, -/*108 */ { 6, s_0_108, -1, -1, r_CONSONANT}, -/*109 */ { 9, s_0_109, 108, -1, 0}, -/*110 */ { 9, s_0_110, 108, -1, 0}, -/*111 */ { 9, s_0_111, 108, -1, 0}, -/*112 */ { 3, s_0_112, -1, -1, 0}, -/*113 */ { 12, s_0_113, 112, -1, 0}, -/*114 */ { 12, s_0_114, 112, -1, 0}, -/*115 */ { 15, s_0_115, 114, -1, 0}, -/*116 */ { 15, s_0_116, 114, -1, 0}, -/*117 */ { 9, s_0_117, 112, -1, 0}, -/*118 */ { 9, s_0_118, 112, -1, 0}, -/*119 */ { 12, s_0_119, 118, -1, 0}, -/*120 */ { 12, s_0_120, 118, -1, 0}, -/*121 */ { 6, s_0_121, 112, -1, r_CONSONANT}, -/*122 */ { 9, s_0_122, 121, -1, 0}, -/*123 */ { 9, s_0_123, 121, -1, 0}, -/*124 */ { 9, s_0_124, 121, -1, 0}, -/*125 */ { 6, s_0_125, 112, -1, r_CONSONANT}, -/*126 */ { 9, s_0_126, 125, -1, 0}, -/*127 */ { 9, s_0_127, 125, -1, 0}, -/*128 */ { 9, s_0_128, 125, -1, 0}, -/*129 */ { 9, s_0_129, 112, -1, 0}, -/*130 */ { 9, s_0_130, 112, -1, 0}, -/*131 */ { 3, s_0_131, -1, -1, 0} +{ 3, s_0_0, -1, -1, 0}, +{ 12, s_0_1, 0, -1, 0}, +{ 12, s_0_2, 0, -1, 0}, +{ 12, s_0_3, 0, -1, 0}, +{ 15, s_0_4, 3, -1, 0}, +{ 15, s_0_5, 3, -1, 0}, +{ 12, s_0_6, 0, -1, 0}, +{ 15, s_0_7, 6, -1, 0}, +{ 15, s_0_8, 6, -1, 0}, +{ 9, s_0_9, 0, -1, 0}, +{ 9, s_0_10, 0, -1, 0}, +{ 9, s_0_11, 0, -1, 0}, +{ 12, s_0_12, 11, -1, 0}, +{ 12, s_0_13, 11, -1, 0}, +{ 9, s_0_14, 0, -1, 0}, +{ 12, s_0_15, 14, -1, 0}, +{ 12, s_0_16, 14, -1, 0}, +{ 6, s_0_17, 0, -1, r_CONSONANT}, +{ 9, s_0_18, 17, -1, 0}, +{ 9, s_0_19, 17, -1, 0}, +{ 9, s_0_20, 17, -1, 0}, +{ 6, s_0_21, 0, -1, r_CONSONANT}, +{ 9, s_0_22, 21, -1, 0}, +{ 6, s_0_23, -1, -1, 0}, +{ 6, s_0_24, -1, -1, 0}, +{ 12, s_0_25, 24, -1, 0}, +{ 15, s_0_26, 25, -1, 0}, +{ 15, s_0_27, 25, -1, 0}, +{ 12, s_0_28, 24, -1, 0}, +{ 3, s_0_29, -1, -1, 0}, +{ 6, s_0_30, -1, -1, 0}, +{ 9, s_0_31, 30, -1, r_CONSONANT}, +{ 12, s_0_32, 31, -1, 0}, +{ 12, s_0_33, 31, -1, 0}, +{ 12, s_0_34, 31, -1, 0}, +{ 6, s_0_35, -1, -1, 0}, +{ 9, s_0_36, 35, -1, 0}, +{ 9, s_0_37, 35, -1, 0}, +{ 6, s_0_38, -1, -1, 0}, +{ 6, s_0_39, -1, -1, 0}, +{ 9, s_0_40, 39, -1, 0}, +{ 9, s_0_41, 39, -1, 0}, +{ 6, s_0_42, -1, -1, 0}, +{ 12, s_0_43, 42, -1, 0}, +{ 15, s_0_44, 43, -1, 0}, +{ 15, s_0_45, 43, -1, 0}, +{ 12, s_0_46, 42, -1, 0}, +{ 6, s_0_47, -1, -1, 0}, +{ 9, s_0_48, 47, -1, 0}, +{ 9, s_0_49, 47, -1, 0}, +{ 9, s_0_50, 47, -1, 0}, +{ 9, s_0_51, 47, -1, 0}, +{ 12, s_0_52, 51, -1, r_CONSONANT}, +{ 15, s_0_53, 52, -1, 0}, +{ 12, s_0_54, 51, -1, r_CONSONANT}, +{ 15, s_0_55, 54, -1, 0}, +{ 6, s_0_56, -1, -1, 0}, +{ 9, s_0_57, 56, -1, 0}, +{ 9, s_0_58, 56, -1, 0}, +{ 9, s_0_59, 56, -1, 0}, +{ 9, s_0_60, 56, -1, 0}, +{ 12, s_0_61, 60, -1, r_CONSONANT}, +{ 15, s_0_62, 61, -1, 0}, +{ 12, s_0_63, 60, -1, r_CONSONANT}, +{ 15, s_0_64, 63, -1, 0}, +{ 6, s_0_65, -1, -1, 0}, +{ 12, s_0_66, 65, -1, 0}, +{ 15, s_0_67, 66, -1, 0}, +{ 15, s_0_68, 66, -1, 0}, +{ 12, s_0_69, 65, -1, 0}, +{ 3, s_0_70, -1, -1, 0}, +{ 3, s_0_71, -1, -1, 0}, +{ 3, s_0_72, -1, -1, 0}, +{ 3, s_0_73, -1, -1, 0}, +{ 3, s_0_74, -1, -1, 0}, +{ 12, s_0_75, 74, -1, 0}, +{ 12, s_0_76, 74, -1, 0}, +{ 15, s_0_77, 76, -1, 0}, +{ 15, s_0_78, 76, -1, 0}, +{ 9, s_0_79, 74, -1, 0}, +{ 9, s_0_80, 74, -1, 0}, +{ 12, s_0_81, 80, -1, 0}, +{ 12, s_0_82, 80, -1, 0}, +{ 6, s_0_83, 74, -1, r_CONSONANT}, +{ 9, s_0_84, 83, -1, 0}, +{ 9, s_0_85, 83, -1, 0}, +{ 9, s_0_86, 83, -1, 0}, +{ 6, s_0_87, 74, -1, r_CONSONANT}, +{ 9, s_0_88, 87, -1, 0}, +{ 9, s_0_89, 87, -1, 0}, +{ 9, s_0_90, 87, -1, 0}, +{ 3, s_0_91, -1, -1, 0}, +{ 6, s_0_92, 91, -1, 0}, +{ 6, s_0_93, 91, -1, 0}, +{ 3, s_0_94, -1, -1, 0}, +{ 3, s_0_95, -1, -1, 0}, +{ 3, s_0_96, -1, -1, 0}, +{ 3, s_0_97, -1, -1, 0}, +{ 3, s_0_98, -1, -1, 0}, +{ 6, s_0_99, 98, -1, 0}, +{ 6, s_0_100, 98, -1, 0}, +{ 9, s_0_101, 100, -1, 0}, +{ 9, s_0_102, 100, -1, 0}, +{ 6, s_0_103, 98, -1, 0}, +{ 6, s_0_104, 98, -1, 0}, +{ 3, s_0_105, -1, -1, 0}, +{ 6, s_0_106, 105, -1, 0}, +{ 6, s_0_107, 105, -1, 0}, +{ 6, s_0_108, -1, -1, r_CONSONANT}, +{ 9, s_0_109, 108, -1, 0}, +{ 9, s_0_110, 108, -1, 0}, +{ 9, s_0_111, 108, -1, 0}, +{ 3, s_0_112, -1, -1, 0}, +{ 12, s_0_113, 112, -1, 0}, +{ 12, s_0_114, 112, -1, 0}, +{ 15, s_0_115, 114, -1, 0}, +{ 15, s_0_116, 114, -1, 0}, +{ 9, s_0_117, 112, -1, 0}, +{ 9, s_0_118, 112, -1, 0}, +{ 12, s_0_119, 118, -1, 0}, +{ 12, s_0_120, 118, -1, 0}, +{ 6, s_0_121, 112, -1, r_CONSONANT}, +{ 9, s_0_122, 121, -1, 0}, +{ 9, s_0_123, 121, -1, 0}, +{ 9, s_0_124, 121, -1, 0}, +{ 6, s_0_125, 112, -1, r_CONSONANT}, +{ 9, s_0_126, 125, -1, 0}, +{ 9, s_0_127, 125, -1, 0}, +{ 9, s_0_128, 125, -1, 0}, +{ 9, s_0_129, 112, -1, 0}, +{ 9, s_0_130, 112, -1, 0}, +{ 3, s_0_131, -1, -1, 0} }; static const unsigned char g_consonant[] = { 255, 255, 255, 255, 159, 0, 0, 0, 248, 7 }; -static int r_CONSONANT(struct SN_env * z) { /* backwardmode */ - if (in_grouping_b_U(z, g_consonant, 2325, 2399, 0)) return 0; /* grouping consonant, line 129 */ +static int r_CONSONANT(struct SN_env * z) { + if (in_grouping_b_U(z, g_consonant, 2325, 2399, 0)) return 0; return 1; } -extern int hindi_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c_test1 = z->c; /* test, line 132 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); +extern int hindi_UTF_8_stem(struct SN_env * z) { + { int c_test1 = z->c; + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 132 */ + z->c = ret; } - z->I[0] = z->c; /* setmark p, line 132 */ + z->I[0] = z->c; z->c = c_test1; } - z->lb = z->c; z->c = z->l; /* backwards, line 133 */ + z->lb = z->c; z->c = z->l; - { int mlimit2; /* setlimit, line 139 */ + { int mlimit2; if (z->c < z->I[0]) return 0; mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 139 */ - if (!(find_among_b(z, a_0, 132))) { z->lb = mlimit2; return 0; } /* substring, line 139 */ - z->bra = z->c; /* ], line 139 */ + z->ket = z->c; + if (!(find_among_b(z, a_0, 132))) { z->lb = mlimit2; return 0; } + z->bra = z->c; z->lb = mlimit2; } - { int ret = slice_del(z); /* delete, line 321 */ + { int ret = slice_del(z); if (ret < 0) return ret; } z->c = z->lb; return 1; } -extern struct SN_env * hindi_UTF_8_create_env(void) { return SN_create_env(0, 1, 0); } +extern struct SN_env * hindi_UTF_8_create_env(void) { return SN_create_env(0, 1); } extern void hindi_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c b/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c index 284b3230c242..160c926519f1 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -46,14 +46,14 @@ static const symbol s_0_7[2] = { 'z', 's' }; static const struct among a_0[8] = { -/* 0 */ { 2, s_0_0, -1, -1, 0}, -/* 1 */ { 3, s_0_1, -1, -1, 0}, -/* 2 */ { 2, s_0_2, -1, -1, 0}, -/* 3 */ { 2, s_0_3, -1, -1, 0}, -/* 4 */ { 2, s_0_4, -1, -1, 0}, -/* 5 */ { 2, s_0_5, -1, -1, 0}, -/* 6 */ { 2, s_0_6, -1, -1, 0}, -/* 7 */ { 2, s_0_7, -1, -1, 0} +{ 2, s_0_0, -1, -1, 0}, +{ 3, s_0_1, -1, -1, 0}, +{ 2, s_0_2, -1, -1, 0}, +{ 2, s_0_3, -1, -1, 0}, +{ 2, s_0_4, -1, -1, 0}, +{ 2, s_0_5, -1, -1, 0}, +{ 2, s_0_6, -1, -1, 0}, +{ 2, s_0_7, -1, -1, 0} }; static const symbol s_1_0[2] = { 0xC3, 0xA1 }; @@ -61,8 +61,8 @@ static const symbol s_1_1[2] = { 0xC3, 0xA9 }; static const struct among a_1[2] = { -/* 0 */ { 2, s_1_0, -1, 1, 0}, -/* 1 */ { 2, s_1_1, -1, 2, 0} +{ 2, s_1_0, -1, 1, 0}, +{ 2, s_1_1, -1, 2, 0} }; static const symbol s_2_0[2] = { 'b', 'b' }; @@ -91,29 +91,29 @@ static const symbol s_2_22[2] = { 'z', 'z' }; static const struct among a_2[23] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 2, s_2_2, -1, -1, 0}, -/* 3 */ { 2, s_2_3, -1, -1, 0}, -/* 4 */ { 2, s_2_4, -1, -1, 0}, -/* 5 */ { 2, s_2_5, -1, -1, 0}, -/* 6 */ { 2, s_2_6, -1, -1, 0}, -/* 7 */ { 2, s_2_7, -1, -1, 0}, -/* 8 */ { 2, s_2_8, -1, -1, 0}, -/* 9 */ { 2, s_2_9, -1, -1, 0}, -/* 10 */ { 2, s_2_10, -1, -1, 0}, -/* 11 */ { 2, s_2_11, -1, -1, 0}, -/* 12 */ { 3, s_2_12, -1, -1, 0}, -/* 13 */ { 2, s_2_13, -1, -1, 0}, -/* 14 */ { 3, s_2_14, -1, -1, 0}, -/* 15 */ { 2, s_2_15, -1, -1, 0}, -/* 16 */ { 2, s_2_16, -1, -1, 0}, -/* 17 */ { 3, s_2_17, -1, -1, 0}, -/* 18 */ { 3, s_2_18, -1, -1, 0}, -/* 19 */ { 3, s_2_19, -1, -1, 0}, -/* 20 */ { 3, s_2_20, -1, -1, 0}, -/* 21 */ { 3, s_2_21, -1, -1, 0}, -/* 22 */ { 2, s_2_22, -1, -1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 2, s_2_2, -1, -1, 0}, +{ 2, s_2_3, -1, -1, 0}, +{ 2, s_2_4, -1, -1, 0}, +{ 2, s_2_5, -1, -1, 0}, +{ 2, s_2_6, -1, -1, 0}, +{ 2, s_2_7, -1, -1, 0}, +{ 2, s_2_8, -1, -1, 0}, +{ 2, s_2_9, -1, -1, 0}, +{ 2, s_2_10, -1, -1, 0}, +{ 2, s_2_11, -1, -1, 0}, +{ 3, s_2_12, -1, -1, 0}, +{ 2, s_2_13, -1, -1, 0}, +{ 3, s_2_14, -1, -1, 0}, +{ 2, s_2_15, -1, -1, 0}, +{ 2, s_2_16, -1, -1, 0}, +{ 3, s_2_17, -1, -1, 0}, +{ 3, s_2_18, -1, -1, 0}, +{ 3, s_2_19, -1, -1, 0}, +{ 3, s_2_20, -1, -1, 0}, +{ 3, s_2_21, -1, -1, 0}, +{ 2, s_2_22, -1, -1, 0} }; static const symbol s_3_0[2] = { 'a', 'l' }; @@ -121,8 +121,8 @@ static const symbol s_3_1[2] = { 'e', 'l' }; static const struct among a_3[2] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 2, s_3_1, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 2, s_3_1, -1, 1, 0} }; static const symbol s_4_0[2] = { 'b', 'a' }; @@ -172,50 +172,50 @@ static const symbol s_4_43[3] = { 'v', 0xC3, 0xA9 }; static const struct among a_4[44] = { -/* 0 */ { 2, s_4_0, -1, -1, 0}, -/* 1 */ { 2, s_4_1, -1, -1, 0}, -/* 2 */ { 2, s_4_2, -1, -1, 0}, -/* 3 */ { 2, s_4_3, -1, -1, 0}, -/* 4 */ { 2, s_4_4, -1, -1, 0}, -/* 5 */ { 3, s_4_5, -1, -1, 0}, -/* 6 */ { 3, s_4_6, -1, -1, 0}, -/* 7 */ { 3, s_4_7, -1, -1, 0}, -/* 8 */ { 3, s_4_8, -1, -1, 0}, -/* 9 */ { 2, s_4_9, -1, -1, 0}, -/* 10 */ { 4, s_4_10, -1, -1, 0}, -/* 11 */ { 4, s_4_11, -1, -1, 0}, -/* 12 */ { 4, s_4_12, -1, -1, 0}, -/* 13 */ { 4, s_4_13, -1, -1, 0}, -/* 14 */ { 4, s_4_14, -1, -1, 0}, -/* 15 */ { 4, s_4_15, -1, -1, 0}, -/* 16 */ { 4, s_4_16, -1, -1, 0}, -/* 17 */ { 4, s_4_17, -1, -1, 0}, -/* 18 */ { 3, s_4_18, -1, -1, 0}, -/* 19 */ { 1, s_4_19, -1, -1, 0}, -/* 20 */ { 2, s_4_20, 19, -1, 0}, -/* 21 */ { 3, s_4_21, 20, -1, 0}, -/* 22 */ { 2, s_4_22, 19, -1, 0}, -/* 23 */ { 3, s_4_23, 22, -1, 0}, -/* 24 */ { 7, s_4_24, 22, -1, 0}, -/* 25 */ { 2, s_4_25, 19, -1, 0}, -/* 26 */ { 3, s_4_26, 19, -1, 0}, -/* 27 */ { 5, s_4_27, -1, -1, 0}, -/* 28 */ { 3, s_4_28, -1, -1, 0}, -/* 29 */ { 1, s_4_29, -1, -1, 0}, -/* 30 */ { 2, s_4_30, 29, -1, 0}, -/* 31 */ { 2, s_4_31, 29, -1, 0}, -/* 32 */ { 5, s_4_32, 29, -1, 0}, -/* 33 */ { 7, s_4_33, 32, -1, 0}, -/* 34 */ { 7, s_4_34, 32, -1, 0}, -/* 35 */ { 7, s_4_35, 32, -1, 0}, -/* 36 */ { 2, s_4_36, 29, -1, 0}, -/* 37 */ { 4, s_4_37, 29, -1, 0}, -/* 38 */ { 3, s_4_38, 29, -1, 0}, -/* 39 */ { 3, s_4_39, -1, -1, 0}, -/* 40 */ { 3, s_4_40, -1, -1, 0}, -/* 41 */ { 4, s_4_41, -1, -1, 0}, -/* 42 */ { 3, s_4_42, -1, -1, 0}, -/* 43 */ { 3, s_4_43, -1, -1, 0} +{ 2, s_4_0, -1, -1, 0}, +{ 2, s_4_1, -1, -1, 0}, +{ 2, s_4_2, -1, -1, 0}, +{ 2, s_4_3, -1, -1, 0}, +{ 2, s_4_4, -1, -1, 0}, +{ 3, s_4_5, -1, -1, 0}, +{ 3, s_4_6, -1, -1, 0}, +{ 3, s_4_7, -1, -1, 0}, +{ 3, s_4_8, -1, -1, 0}, +{ 2, s_4_9, -1, -1, 0}, +{ 4, s_4_10, -1, -1, 0}, +{ 4, s_4_11, -1, -1, 0}, +{ 4, s_4_12, -1, -1, 0}, +{ 4, s_4_13, -1, -1, 0}, +{ 4, s_4_14, -1, -1, 0}, +{ 4, s_4_15, -1, -1, 0}, +{ 4, s_4_16, -1, -1, 0}, +{ 4, s_4_17, -1, -1, 0}, +{ 3, s_4_18, -1, -1, 0}, +{ 1, s_4_19, -1, -1, 0}, +{ 2, s_4_20, 19, -1, 0}, +{ 3, s_4_21, 20, -1, 0}, +{ 2, s_4_22, 19, -1, 0}, +{ 3, s_4_23, 22, -1, 0}, +{ 7, s_4_24, 22, -1, 0}, +{ 2, s_4_25, 19, -1, 0}, +{ 3, s_4_26, 19, -1, 0}, +{ 5, s_4_27, -1, -1, 0}, +{ 3, s_4_28, -1, -1, 0}, +{ 1, s_4_29, -1, -1, 0}, +{ 2, s_4_30, 29, -1, 0}, +{ 2, s_4_31, 29, -1, 0}, +{ 5, s_4_32, 29, -1, 0}, +{ 7, s_4_33, 32, -1, 0}, +{ 7, s_4_34, 32, -1, 0}, +{ 7, s_4_35, 32, -1, 0}, +{ 2, s_4_36, 29, -1, 0}, +{ 4, s_4_37, 29, -1, 0}, +{ 3, s_4_38, 29, -1, 0}, +{ 3, s_4_39, -1, -1, 0}, +{ 3, s_4_40, -1, -1, 0}, +{ 4, s_4_41, -1, -1, 0}, +{ 3, s_4_42, -1, -1, 0}, +{ 3, s_4_43, -1, -1, 0} }; static const symbol s_5_0[3] = { 0xC3, 0xA1, 'n' }; @@ -224,9 +224,9 @@ static const symbol s_5_2[8] = { 0xC3, 0xA1, 'n', 'k', 0xC3, 0xA9, 'n', 't' }; static const struct among a_5[3] = { -/* 0 */ { 3, s_5_0, -1, 2, 0}, -/* 1 */ { 3, s_5_1, -1, 1, 0}, -/* 2 */ { 8, s_5_2, -1, 2, 0} +{ 3, s_5_0, -1, 2, 0}, +{ 3, s_5_1, -1, 1, 0}, +{ 8, s_5_2, -1, 2, 0} }; static const symbol s_6_0[4] = { 's', 't', 'u', 'l' }; @@ -238,12 +238,12 @@ static const symbol s_6_5[7] = { 0xC3, 0xA9, 's', 't', 0xC3, 0xBC, 'l' }; static const struct among a_6[6] = { -/* 0 */ { 4, s_6_0, -1, 1, 0}, -/* 1 */ { 5, s_6_1, 0, 1, 0}, -/* 2 */ { 6, s_6_2, 0, 2, 0}, -/* 3 */ { 5, s_6_3, -1, 1, 0}, -/* 4 */ { 6, s_6_4, 3, 1, 0}, -/* 5 */ { 7, s_6_5, 3, 3, 0} +{ 4, s_6_0, -1, 1, 0}, +{ 5, s_6_1, 0, 1, 0}, +{ 6, s_6_2, 0, 2, 0}, +{ 5, s_6_3, -1, 1, 0}, +{ 6, s_6_4, 3, 1, 0}, +{ 7, s_6_5, 3, 3, 0} }; static const symbol s_7_0[2] = { 0xC3, 0xA1 }; @@ -251,8 +251,8 @@ static const symbol s_7_1[2] = { 0xC3, 0xA9 }; static const struct among a_7[2] = { -/* 0 */ { 2, s_7_0, -1, 1, 0}, -/* 1 */ { 2, s_7_1, -1, 1, 0} +{ 2, s_7_0, -1, 1, 0}, +{ 2, s_7_1, -1, 1, 0} }; static const symbol s_8_0[1] = { 'k' }; @@ -265,13 +265,13 @@ static const symbol s_8_6[3] = { 0xC3, 0xB6, 'k' }; static const struct among a_8[7] = { -/* 0 */ { 1, s_8_0, -1, 3, 0}, -/* 1 */ { 2, s_8_1, 0, 3, 0}, -/* 2 */ { 2, s_8_2, 0, 3, 0}, -/* 3 */ { 2, s_8_3, 0, 3, 0}, -/* 4 */ { 3, s_8_4, 0, 1, 0}, -/* 5 */ { 3, s_8_5, 0, 2, 0}, -/* 6 */ { 3, s_8_6, 0, 3, 0} +{ 1, s_8_0, -1, 3, 0}, +{ 2, s_8_1, 0, 3, 0}, +{ 2, s_8_2, 0, 3, 0}, +{ 2, s_8_3, 0, 3, 0}, +{ 3, s_8_4, 0, 1, 0}, +{ 3, s_8_5, 0, 2, 0}, +{ 3, s_8_6, 0, 3, 0} }; static const symbol s_9_0[3] = { 0xC3, 0xA9, 'i' }; @@ -289,18 +289,18 @@ static const symbol s_9_11[4] = { 0xC3, 0xA9, 0xC3, 0xA9 }; static const struct among a_9[12] = { -/* 0 */ { 3, s_9_0, -1, 1, 0}, -/* 1 */ { 5, s_9_1, 0, 3, 0}, -/* 2 */ { 5, s_9_2, 0, 2, 0}, -/* 3 */ { 2, s_9_3, -1, 1, 0}, -/* 4 */ { 3, s_9_4, 3, 1, 0}, -/* 5 */ { 4, s_9_5, 4, 1, 0}, -/* 6 */ { 4, s_9_6, 4, 1, 0}, -/* 7 */ { 4, s_9_7, 4, 1, 0}, -/* 8 */ { 5, s_9_8, 4, 3, 0}, -/* 9 */ { 5, s_9_9, 4, 2, 0}, -/* 10 */ { 5, s_9_10, 4, 1, 0}, -/* 11 */ { 4, s_9_11, 3, 2, 0} +{ 3, s_9_0, -1, 1, 0}, +{ 5, s_9_1, 0, 3, 0}, +{ 5, s_9_2, 0, 2, 0}, +{ 2, s_9_3, -1, 1, 0}, +{ 3, s_9_4, 3, 1, 0}, +{ 4, s_9_5, 4, 1, 0}, +{ 4, s_9_6, 4, 1, 0}, +{ 4, s_9_7, 4, 1, 0}, +{ 5, s_9_8, 4, 3, 0}, +{ 5, s_9_9, 4, 2, 0}, +{ 5, s_9_10, 4, 1, 0}, +{ 4, s_9_11, 3, 2, 0} }; static const symbol s_10_0[1] = { 'a' }; @@ -337,37 +337,37 @@ static const symbol s_10_30[2] = { 0xC3, 0xA9 }; static const struct among a_10[31] = { -/* 0 */ { 1, s_10_0, -1, 1, 0}, -/* 1 */ { 2, s_10_1, 0, 1, 0}, -/* 2 */ { 1, s_10_2, -1, 1, 0}, -/* 3 */ { 2, s_10_3, 2, 1, 0}, -/* 4 */ { 2, s_10_4, 2, 1, 0}, -/* 5 */ { 2, s_10_5, 2, 1, 0}, -/* 6 */ { 3, s_10_6, 2, 2, 0}, -/* 7 */ { 3, s_10_7, 2, 3, 0}, -/* 8 */ { 3, s_10_8, 2, 1, 0}, -/* 9 */ { 1, s_10_9, -1, 1, 0}, -/* 10 */ { 2, s_10_10, 9, 1, 0}, -/* 11 */ { 2, s_10_11, -1, 1, 0}, -/* 12 */ { 3, s_10_12, 11, 1, 0}, -/* 13 */ { 4, s_10_13, 11, 2, 0}, -/* 14 */ { 4, s_10_14, 11, 3, 0}, -/* 15 */ { 4, s_10_15, 11, 1, 0}, -/* 16 */ { 2, s_10_16, -1, 1, 0}, -/* 17 */ { 3, s_10_17, 16, 1, 0}, -/* 18 */ { 5, s_10_18, 17, 2, 0}, -/* 19 */ { 3, s_10_19, -1, 1, 0}, -/* 20 */ { 4, s_10_20, 19, 1, 0}, -/* 21 */ { 6, s_10_21, 20, 3, 0}, -/* 22 */ { 1, s_10_22, -1, 1, 0}, -/* 23 */ { 2, s_10_23, 22, 1, 0}, -/* 24 */ { 2, s_10_24, 22, 1, 0}, -/* 25 */ { 2, s_10_25, 22, 1, 0}, -/* 26 */ { 3, s_10_26, 22, 2, 0}, -/* 27 */ { 3, s_10_27, 22, 3, 0}, -/* 28 */ { 1, s_10_28, -1, 1, 0}, -/* 29 */ { 2, s_10_29, -1, 2, 0}, -/* 30 */ { 2, s_10_30, -1, 3, 0} +{ 1, s_10_0, -1, 1, 0}, +{ 2, s_10_1, 0, 1, 0}, +{ 1, s_10_2, -1, 1, 0}, +{ 2, s_10_3, 2, 1, 0}, +{ 2, s_10_4, 2, 1, 0}, +{ 2, s_10_5, 2, 1, 0}, +{ 3, s_10_6, 2, 2, 0}, +{ 3, s_10_7, 2, 3, 0}, +{ 3, s_10_8, 2, 1, 0}, +{ 1, s_10_9, -1, 1, 0}, +{ 2, s_10_10, 9, 1, 0}, +{ 2, s_10_11, -1, 1, 0}, +{ 3, s_10_12, 11, 1, 0}, +{ 4, s_10_13, 11, 2, 0}, +{ 4, s_10_14, 11, 3, 0}, +{ 4, s_10_15, 11, 1, 0}, +{ 2, s_10_16, -1, 1, 0}, +{ 3, s_10_17, 16, 1, 0}, +{ 5, s_10_18, 17, 2, 0}, +{ 3, s_10_19, -1, 1, 0}, +{ 4, s_10_20, 19, 1, 0}, +{ 6, s_10_21, 20, 3, 0}, +{ 1, s_10_22, -1, 1, 0}, +{ 2, s_10_23, 22, 1, 0}, +{ 2, s_10_24, 22, 1, 0}, +{ 2, s_10_25, 22, 1, 0}, +{ 3, s_10_26, 22, 2, 0}, +{ 3, s_10_27, 22, 3, 0}, +{ 1, s_10_28, -1, 1, 0}, +{ 2, s_10_29, -1, 2, 0}, +{ 2, s_10_30, -1, 3, 0} }; static const symbol s_11_0[2] = { 'i', 'd' }; @@ -415,48 +415,48 @@ static const symbol s_11_41[4] = { 0xC3, 0xA9, 'i', 'm' }; static const struct among a_11[42] = { -/* 0 */ { 2, s_11_0, -1, 1, 0}, -/* 1 */ { 3, s_11_1, 0, 1, 0}, -/* 2 */ { 4, s_11_2, 1, 1, 0}, -/* 3 */ { 3, s_11_3, 0, 1, 0}, -/* 4 */ { 4, s_11_4, 3, 1, 0}, -/* 5 */ { 4, s_11_5, 0, 2, 0}, -/* 6 */ { 4, s_11_6, 0, 3, 0}, -/* 7 */ { 1, s_11_7, -1, 1, 0}, -/* 8 */ { 2, s_11_8, 7, 1, 0}, -/* 9 */ { 3, s_11_9, 8, 1, 0}, -/* 10 */ { 2, s_11_10, 7, 1, 0}, -/* 11 */ { 3, s_11_11, 10, 1, 0}, -/* 12 */ { 3, s_11_12, 7, 2, 0}, -/* 13 */ { 3, s_11_13, 7, 3, 0}, -/* 14 */ { 4, s_11_14, -1, 1, 0}, -/* 15 */ { 5, s_11_15, 14, 1, 0}, -/* 16 */ { 6, s_11_16, 15, 1, 0}, -/* 17 */ { 6, s_11_17, 14, 3, 0}, -/* 18 */ { 2, s_11_18, -1, 1, 0}, -/* 19 */ { 3, s_11_19, 18, 1, 0}, -/* 20 */ { 4, s_11_20, 19, 1, 0}, -/* 21 */ { 3, s_11_21, 18, 1, 0}, -/* 22 */ { 4, s_11_22, 21, 1, 0}, -/* 23 */ { 4, s_11_23, 18, 2, 0}, -/* 24 */ { 4, s_11_24, 18, 3, 0}, -/* 25 */ { 3, s_11_25, -1, 1, 0}, -/* 26 */ { 4, s_11_26, 25, 1, 0}, -/* 27 */ { 5, s_11_27, 26, 1, 0}, -/* 28 */ { 4, s_11_28, 25, 1, 0}, -/* 29 */ { 5, s_11_29, 28, 1, 0}, -/* 30 */ { 5, s_11_30, 25, 2, 0}, -/* 31 */ { 5, s_11_31, 25, 3, 0}, -/* 32 */ { 5, s_11_32, -1, 1, 0}, -/* 33 */ { 6, s_11_33, 32, 1, 0}, -/* 34 */ { 6, s_11_34, -1, 2, 0}, -/* 35 */ { 2, s_11_35, -1, 1, 0}, -/* 36 */ { 3, s_11_36, 35, 1, 0}, -/* 37 */ { 4, s_11_37, 36, 1, 0}, -/* 38 */ { 3, s_11_38, 35, 1, 0}, -/* 39 */ { 4, s_11_39, 38, 1, 0}, -/* 40 */ { 4, s_11_40, 35, 2, 0}, -/* 41 */ { 4, s_11_41, 35, 3, 0} +{ 2, s_11_0, -1, 1, 0}, +{ 3, s_11_1, 0, 1, 0}, +{ 4, s_11_2, 1, 1, 0}, +{ 3, s_11_3, 0, 1, 0}, +{ 4, s_11_4, 3, 1, 0}, +{ 4, s_11_5, 0, 2, 0}, +{ 4, s_11_6, 0, 3, 0}, +{ 1, s_11_7, -1, 1, 0}, +{ 2, s_11_8, 7, 1, 0}, +{ 3, s_11_9, 8, 1, 0}, +{ 2, s_11_10, 7, 1, 0}, +{ 3, s_11_11, 10, 1, 0}, +{ 3, s_11_12, 7, 2, 0}, +{ 3, s_11_13, 7, 3, 0}, +{ 4, s_11_14, -1, 1, 0}, +{ 5, s_11_15, 14, 1, 0}, +{ 6, s_11_16, 15, 1, 0}, +{ 6, s_11_17, 14, 3, 0}, +{ 2, s_11_18, -1, 1, 0}, +{ 3, s_11_19, 18, 1, 0}, +{ 4, s_11_20, 19, 1, 0}, +{ 3, s_11_21, 18, 1, 0}, +{ 4, s_11_22, 21, 1, 0}, +{ 4, s_11_23, 18, 2, 0}, +{ 4, s_11_24, 18, 3, 0}, +{ 3, s_11_25, -1, 1, 0}, +{ 4, s_11_26, 25, 1, 0}, +{ 5, s_11_27, 26, 1, 0}, +{ 4, s_11_28, 25, 1, 0}, +{ 5, s_11_29, 28, 1, 0}, +{ 5, s_11_30, 25, 2, 0}, +{ 5, s_11_31, 25, 3, 0}, +{ 5, s_11_32, -1, 1, 0}, +{ 6, s_11_33, 32, 1, 0}, +{ 6, s_11_34, -1, 2, 0}, +{ 2, s_11_35, -1, 1, 0}, +{ 3, s_11_36, 35, 1, 0}, +{ 4, s_11_37, 36, 1, 0}, +{ 3, s_11_38, 35, 1, 0}, +{ 4, s_11_39, 38, 1, 0}, +{ 4, s_11_40, 35, 2, 0}, +{ 4, s_11_41, 35, 3, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 36, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 }; @@ -476,62 +476,62 @@ static const symbol s_11[] = { 'e' }; static const symbol s_12[] = { 'a' }; static const symbol s_13[] = { 'e' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 46 */ - { int c1 = z->c; /* or, line 51 */ - if (in_grouping_U(z, g_v, 97, 369, 0)) goto lab1; /* grouping v, line 48 */ - if (in_grouping_U(z, g_v, 97, 369, 1) < 0) goto lab1; /* goto */ /* non v, line 48 */ - { int c2 = z->c; /* or, line 49 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; /* among, line 49 */ +static int r_mark_regions(struct SN_env * z) { + z->I[0] = z->l; + { int c1 = z->c; + if (in_grouping_U(z, g_v, 97, 369, 0)) goto lab1; + if (in_grouping_U(z, g_v, 97, 369, 1) < 0) goto lab1; + { int c2 = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; if (!(find_among(z, a_0, 8))) goto lab3; goto lab2; lab3: z->c = c2; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab1; - z->c = ret; /* next, line 49 */ + z->c = ret; } } lab2: - z->I[0] = z->c; /* setmark p1, line 50 */ + z->I[0] = z->c; goto lab0; lab1: z->c = c1; - if (out_grouping_U(z, g_v, 97, 369, 0)) return 0; /* non v, line 53 */ - { /* gopast */ /* grouping v, line 53 */ + if (out_grouping_U(z, g_v, 97, 369, 0)) return 0; + { int ret = out_grouping_U(z, g_v, 97, 369, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 53 */ + z->I[0] = z->c; } lab0: return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 58 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_v_ending(struct SN_env * z) { /* backwardmode */ +static int r_v_ending(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 61 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; /* substring, line 61 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; among_var = find_among_b(z, a_1, 2); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 61 */ - { int ret = r_R1(z); /* call R1, line 61 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 61 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 62 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 63 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; @@ -539,86 +539,86 @@ static int r_v_ending(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_double(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 68 */ +static int r_double(struct SN_env * z) { + { int m_test1 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_2, 23))) return 0; z->c = z->l - m_test1; } return 1; } -static int r_undouble(struct SN_env * z) { /* backwardmode */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); +static int r_undouble(struct SN_env * z) { + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 73 */ + z->c = ret; } - z->ket = z->c; /* [, line 73 */ - { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 1); /* hop, line 73 */ + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; z->c = ret; } - z->bra = z->c; /* ], line 73 */ - { int ret = slice_del(z); /* delete, line 73 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_instrum(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 77 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 77 */ +static int r_instrum(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; if (!(find_among_b(z, a_3, 2))) return 0; - z->bra = z->c; /* ], line 77 */ - { int ret = r_R1(z); /* call R1, line 77 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = r_double(z); /* call double, line 78 */ + { int ret = r_double(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 81 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_undouble(z); /* call undouble, line 82 */ + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_case(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 87 */ - if (!(find_among_b(z, a_4, 44))) return 0; /* substring, line 87 */ - z->bra = z->c; /* ], line 87 */ - { int ret = r_R1(z); /* call R1, line 87 */ +static int r_case(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_4, 44))) return 0; + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 111 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_v_ending(z); /* call v_ending, line 112 */ + { int ret = r_v_ending(z); if (ret <= 0) return ret; } return 1; } -static int r_case_special(struct SN_env * z) { /* backwardmode */ +static int r_case_special(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 116 */ - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; /* substring, line 116 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; among_var = find_among_b(z, a_5, 3); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 116 */ - { int ret = r_R1(z); /* call R1, line 116 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 116 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 117 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 118 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; @@ -626,29 +626,29 @@ static int r_case_special(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_case_other(struct SN_env * z) { /* backwardmode */ +static int r_case_other(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 124 */ + z->ket = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; among_var = find_among_b(z, a_6, 6); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 124 */ - { int ret = r_R1(z); /* call R1, line 124 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 124 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 127 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 128 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; @@ -656,49 +656,49 @@ static int r_case_other(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_factive(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 133 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; /* substring, line 133 */ +static int r_factive(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; if (!(find_among_b(z, a_7, 2))) return 0; - z->bra = z->c; /* ], line 133 */ - { int ret = r_R1(z); /* call R1, line 133 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = r_double(z); /* call double, line 134 */ + { int ret = r_double(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 137 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_undouble(z); /* call undouble, line 138 */ + { int ret = r_undouble(z); if (ret <= 0) return ret; } return 1; } -static int r_plural(struct SN_env * z) { /* backwardmode */ +static int r_plural(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 142 */ - if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; /* substring, line 142 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; among_var = find_among_b(z, a_8, 7); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 142 */ - { int ret = r_R1(z); /* call R1, line 142 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 142 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 143 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 144 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 145 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -706,29 +706,29 @@ static int r_plural(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_owned(struct SN_env * z) { /* backwardmode */ +static int r_owned(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 154 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 169)) return 0; /* substring, line 154 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 169)) return 0; among_var = find_among_b(z, a_9, 12); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 154 */ - { int ret = r_R1(z); /* call R1, line 154 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 154 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 155 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 156 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 157 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; @@ -736,28 +736,28 @@ static int r_owned(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_sing_owner(struct SN_env * z) { /* backwardmode */ +static int r_sing_owner(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 168 */ - among_var = find_among_b(z, a_10, 31); /* substring, line 168 */ + z->ket = z->c; + among_var = find_among_b(z, a_10, 31); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 168 */ - { int ret = r_R1(z); /* call R1, line 168 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 168 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 169 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 170 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 171 */ + { int ret = slice_from_s(z, 1, s_11); if (ret < 0) return ret; } break; @@ -765,29 +765,29 @@ static int r_sing_owner(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_plur_owner(struct SN_env * z) { /* backwardmode */ +static int r_plur_owner(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 193 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 193 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_11, 42); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 193 */ - { int ret = r_R1(z); /* call R1, line 193 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 193 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 194 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 195 */ + { int ret = slice_from_s(z, 1, s_12); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 196 */ + { int ret = slice_from_s(z, 1, s_13); if (ret < 0) return ret; } break; @@ -795,65 +795,65 @@ static int r_plur_owner(struct SN_env * z) { /* backwardmode */ return 1; } -extern int hungarian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 229 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 229 */ +extern int hungarian_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 230 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 231 */ - { int ret = r_instrum(z); /* call instrum, line 231 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_instrum(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 232 */ - { int ret = r_case(z); /* call case, line 232 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_case(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 233 */ - { int ret = r_case_special(z); /* call case_special, line 233 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_case_special(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 234 */ - { int ret = r_case_other(z); /* call case_other, line 234 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_case_other(z); if (ret < 0) return ret; } z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* do, line 235 */ - { int ret = r_factive(z); /* call factive, line 235 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_factive(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 236 */ - { int ret = r_owned(z); /* call owned, line 236 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_owned(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 237 */ - { int ret = r_sing_owner(z); /* call sing_owner, line 237 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_sing_owner(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 238 */ - { int ret = r_plur_owner(z); /* call plur_owner, line 238 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_plur_owner(z); if (ret < 0) return ret; } z->c = z->l - m9; } - { int m10 = z->l - z->c; (void)m10; /* do, line 239 */ - { int ret = r_plural(z); /* call plural, line 239 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_plural(z); if (ret < 0) return ret; } z->c = z->l - m10; @@ -862,7 +862,7 @@ extern int hungarian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * hungarian_UTF_8_create_env(void) { return SN_create_env(0, 1, 0); } +extern struct SN_env * hungarian_UTF_8_create_env(void) { return SN_create_env(0, 1); } extern void hungarian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_indonesian.c b/src/backend/snowball/libstemmer/stem_UTF_8_indonesian.c index 0a4d6392bff8..573178d8e7fd 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_indonesian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_indonesian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -37,9 +37,9 @@ static const symbol s_0_2[3] = { 'p', 'u', 'n' }; static const struct among a_0[3] = { -/* 0 */ { 3, s_0_0, -1, 1, 0}, -/* 1 */ { 3, s_0_1, -1, 1, 0}, -/* 2 */ { 3, s_0_2, -1, 1, 0} +{ 3, s_0_0, -1, 1, 0}, +{ 3, s_0_1, -1, 1, 0}, +{ 3, s_0_2, -1, 1, 0} }; static const symbol s_1_0[3] = { 'n', 'y', 'a' }; @@ -48,9 +48,9 @@ static const symbol s_1_2[2] = { 'm', 'u' }; static const struct among a_1[3] = { -/* 0 */ { 3, s_1_0, -1, 1, 0}, -/* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0} +{ 3, s_1_0, -1, 1, 0}, +{ 2, s_1_1, -1, 1, 0}, +{ 2, s_1_2, -1, 1, 0} }; static const symbol s_2_0[1] = { 'i' }; @@ -59,9 +59,9 @@ static const symbol s_2_2[3] = { 'k', 'a', 'n' }; static const struct among a_2[3] = { -/* 0 */ { 1, s_2_0, -1, 1, r_SUFFIX_I_OK}, -/* 1 */ { 2, s_2_1, -1, 1, r_SUFFIX_AN_OK}, -/* 2 */ { 3, s_2_2, 1, 1, r_SUFFIX_KAN_OK} +{ 1, s_2_0, -1, 1, r_SUFFIX_I_OK}, +{ 2, s_2_1, -1, 1, r_SUFFIX_AN_OK}, +{ 3, s_2_2, 1, 1, r_SUFFIX_KAN_OK} }; static const symbol s_3_0[2] = { 'd', 'i' }; @@ -79,18 +79,18 @@ static const symbol s_3_11[3] = { 't', 'e', 'r' }; static const struct among a_3[12] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 2, s_3_1, -1, 2, 0}, -/* 2 */ { 2, s_3_2, -1, 1, 0}, -/* 3 */ { 3, s_3_3, 2, 5, 0}, -/* 4 */ { 3, s_3_4, 2, 1, 0}, -/* 5 */ { 4, s_3_5, 4, 1, 0}, -/* 6 */ { 4, s_3_6, 4, 3, r_VOWEL}, -/* 7 */ { 3, s_3_7, -1, 6, 0}, -/* 8 */ { 3, s_3_8, -1, 2, 0}, -/* 9 */ { 4, s_3_9, 8, 2, 0}, -/* 10 */ { 4, s_3_10, 8, 4, r_VOWEL}, -/* 11 */ { 3, s_3_11, -1, 1, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 2, s_3_1, -1, 2, 0}, +{ 2, s_3_2, -1, 1, 0}, +{ 3, s_3_3, 2, 5, 0}, +{ 3, s_3_4, 2, 1, 0}, +{ 4, s_3_5, 4, 1, 0}, +{ 4, s_3_6, 4, 3, r_VOWEL}, +{ 3, s_3_7, -1, 6, 0}, +{ 3, s_3_8, -1, 2, 0}, +{ 4, s_3_9, 8, 2, 0}, +{ 4, s_3_10, 8, 4, r_VOWEL}, +{ 3, s_3_11, -1, 1, 0} }; static const symbol s_4_0[2] = { 'b', 'e' }; @@ -102,12 +102,12 @@ static const symbol s_4_5[3] = { 'p', 'e', 'r' }; static const struct among a_4[6] = { -/* 0 */ { 2, s_4_0, -1, 3, r_KER}, -/* 1 */ { 7, s_4_1, 0, 4, 0}, -/* 2 */ { 3, s_4_2, 0, 3, 0}, -/* 3 */ { 2, s_4_3, -1, 1, 0}, -/* 4 */ { 7, s_4_4, 3, 2, 0}, -/* 5 */ { 3, s_4_5, 3, 1, 0} +{ 2, s_4_0, -1, 3, r_KER}, +{ 7, s_4_1, 0, 4, 0}, +{ 3, s_4_2, 0, 3, 0}, +{ 2, s_4_3, -1, 1, 0}, +{ 7, s_4_4, 3, 2, 0}, +{ 3, s_4_5, 3, 1, 0} }; static const unsigned char g_vowel[] = { 17, 65, 16 }; @@ -120,46 +120,46 @@ static const symbol s_4[] = { 'p' }; static const symbol s_5[] = { 'a', 'j', 'a', 'r' }; static const symbol s_6[] = { 'a', 'j', 'a', 'r' }; -static int r_remove_particle(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 51 */ - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 104 && z->p[z->c - 1] != 110)) return 0; /* substring, line 51 */ +static int r_remove_particle(struct SN_env * z) { + z->ket = z->c; + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 104 && z->p[z->c - 1] != 110)) return 0; if (!(find_among_b(z, a_0, 3))) return 0; - z->bra = z->c; /* ], line 51 */ - { int ret = slice_del(z); /* delete, line 52 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 52 */ + z->I[1] -= 1; return 1; } -static int r_remove_possessive_pronoun(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 57 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 117)) return 0; /* substring, line 57 */ +static int r_remove_possessive_pronoun(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 117)) return 0; if (!(find_among_b(z, a_1, 3))) return 0; - z->bra = z->c; /* ], line 57 */ - { int ret = slice_del(z); /* delete, line 58 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 58 */ + z->I[1] -= 1; return 1; } -static int r_SUFFIX_KAN_OK(struct SN_env * z) { /* backwardmode */ - /* and, line 85 */ - if (!(z->I[1] != 3)) return 0; /* $( != ), line 85 */ - if (!(z->I[1] != 2)) return 0; /* $( != ), line 85 */ +static int r_SUFFIX_KAN_OK(struct SN_env * z) { + + if (!(z->I[0] != 3)) return 0; + if (!(z->I[0] != 2)) return 0; return 1; } -static int r_SUFFIX_AN_OK(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] != 1)) return 0; /* $( != ), line 89 */ +static int r_SUFFIX_AN_OK(struct SN_env * z) { + if (!(z->I[0] != 1)) return 0; return 1; } -static int r_SUFFIX_I_OK(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= 2)) return 0; /* $( <= ), line 93 */ - { int m1 = z->l - z->c; (void)m1; /* not, line 128 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab0; /* literal, line 128 */ +static int r_SUFFIX_I_OK(struct SN_env * z) { + if (!(z->I[0] <= 2)) return 0; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab0; z->c--; return 0; lab0: @@ -168,100 +168,100 @@ static int r_SUFFIX_I_OK(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_remove_suffix(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 132 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 110)) return 0; /* substring, line 132 */ +static int r_remove_suffix(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 110)) return 0; if (!(find_among_b(z, a_2, 3))) return 0; - z->bra = z->c; /* ], line 132 */ - { int ret = slice_del(z); /* delete, line 134 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 134 */ + z->I[1] -= 1; return 1; } -static int r_VOWEL(struct SN_env * z) { /* forwardmode */ - if (in_grouping_U(z, g_vowel, 97, 117, 0)) return 0; /* grouping vowel, line 141 */ +static int r_VOWEL(struct SN_env * z) { + if (in_grouping_U(z, g_vowel, 97, 117, 0)) return 0; return 1; } -static int r_KER(struct SN_env * z) { /* forwardmode */ - if (out_grouping_U(z, g_vowel, 97, 117, 0)) return 0; /* non vowel, line 143 */ - if (!(eq_s(z, 2, s_0))) return 0; /* literal, line 143 */ +static int r_KER(struct SN_env * z) { + if (out_grouping_U(z, g_vowel, 97, 117, 0)) return 0; + if (!(eq_s(z, 2, s_0))) return 0; return 1; } -static int r_remove_first_order_prefix(struct SN_env * z) { /* forwardmode */ +static int r_remove_first_order_prefix(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 146 */ - if (z->c + 1 >= z->l || (z->p[z->c + 1] != 105 && z->p[z->c + 1] != 101)) return 0; /* substring, line 146 */ + z->bra = z->c; + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 105 && z->p[z->c + 1] != 101)) return 0; among_var = find_among(z, a_3, 12); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 146 */ - switch (among_var) { /* among, line 146 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 147 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 1; /* $prefix = , line 147 */ - z->I[0] -= 1; /* $measure -= , line 147 */ + z->I[0] = 1; + z->I[1] -= 1; break; case 2: - { int ret = slice_del(z); /* delete, line 148 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 3; /* $prefix = , line 148 */ - z->I[0] -= 1; /* $measure -= , line 148 */ + z->I[0] = 3; + z->I[1] -= 1; break; case 3: - z->I[1] = 1; /* $prefix = , line 149 */ - { int ret = slice_from_s(z, 1, s_1); /* <-, line 149 */ + z->I[0] = 1; + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 149 */ + z->I[1] -= 1; break; case 4: - z->I[1] = 3; /* $prefix = , line 150 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 150 */ + z->I[0] = 3; + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 150 */ + z->I[1] -= 1; break; case 5: - z->I[1] = 1; /* $prefix = , line 151 */ - z->I[0] -= 1; /* $measure -= , line 151 */ - { int c1 = z->c; /* or, line 151 */ - { int c2 = z->c; /* and, line 151 */ - if (in_grouping_U(z, g_vowel, 97, 117, 0)) goto lab1; /* grouping vowel, line 151 */ + z->I[0] = 1; + z->I[1] -= 1; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping_U(z, g_vowel, 97, 117, 0)) goto lab1; z->c = c2; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 151 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } } goto lab0; lab1: z->c = c1; - { int ret = slice_del(z); /* delete, line 151 */ + { int ret = slice_del(z); if (ret < 0) return ret; } } lab0: break; case 6: - z->I[1] = 3; /* $prefix = , line 152 */ - z->I[0] -= 1; /* $measure -= , line 152 */ - { int c3 = z->c; /* or, line 152 */ - { int c4 = z->c; /* and, line 152 */ - if (in_grouping_U(z, g_vowel, 97, 117, 0)) goto lab3; /* grouping vowel, line 152 */ + z->I[0] = 3; + z->I[1] -= 1; + { int c3 = z->c; + { int c4 = z->c; + if (in_grouping_U(z, g_vowel, 97, 117, 0)) goto lab3; z->c = c4; - { int ret = slice_from_s(z, 1, s_4); /* <-, line 152 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } } goto lab2; lab3: z->c = c3; - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } } @@ -271,57 +271,56 @@ static int r_remove_first_order_prefix(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_remove_second_order_prefix(struct SN_env * z) { /* forwardmode */ +static int r_remove_second_order_prefix(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 162 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] != 101) return 0; /* substring, line 162 */ + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] != 101) return 0; among_var = find_among(z, a_4, 6); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 162 */ - switch (among_var) { /* among, line 162 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 163 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 2; /* $prefix = , line 163 */ - z->I[0] -= 1; /* $measure -= , line 163 */ + z->I[0] = 2; + z->I[1] -= 1; break; case 2: - { int ret = slice_from_s(z, 4, s_5); /* <-, line 164 */ + { int ret = slice_from_s(z, 4, s_5); if (ret < 0) return ret; } - z->I[0] -= 1; /* $measure -= , line 164 */ + z->I[1] -= 1; break; case 3: - { int ret = slice_del(z); /* delete, line 165 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->I[1] = 4; /* $prefix = , line 165 */ - z->I[0] -= 1; /* $measure -= , line 165 */ + z->I[0] = 4; + z->I[1] -= 1; break; case 4: - { int ret = slice_from_s(z, 4, s_6); /* <-, line 166 */ + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } - z->I[1] = 4; /* $prefix = , line 166 */ - z->I[0] -= 1; /* $measure -= , line 166 */ + z->I[0] = 4; + z->I[1] -= 1; break; } return 1; } -extern int indonesian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - z->I[0] = 0; /* $measure = , line 172 */ - { int c1 = z->c; /* do, line 173 */ -/* repeat, line 173 */ - - while(1) { int c2 = z->c; - { /* gopast */ /* grouping vowel, line 173 */ +extern int indonesian_UTF_8_stem(struct SN_env * z) { + z->I[1] = 0; + { int c1 = z->c; + while(1) { + int c2 = z->c; + { int ret = out_grouping_U(z, g_vowel, 97, 117, 1); if (ret < 0) goto lab1; z->c += ret; } - z->I[0] += 1; /* $measure += , line 173 */ + z->I[1] += 1; continue; lab1: z->c = c2; @@ -329,45 +328,45 @@ extern int indonesian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ } z->c = c1; } - if (!(z->I[0] > 2)) return 0; /* $( > ), line 174 */ - z->I[1] = 0; /* $prefix = , line 175 */ - z->lb = z->c; z->c = z->l; /* backwards, line 176 */ + if (!(z->I[1] > 2)) return 0; + z->I[0] = 0; + z->lb = z->c; z->c = z->l; - { int m3 = z->l - z->c; (void)m3; /* do, line 177 */ - { int ret = r_remove_particle(z); /* call remove_particle, line 177 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_remove_particle(z); if (ret < 0) return ret; } z->c = z->l - m3; } - if (!(z->I[0] > 2)) return 0; /* $( > ), line 178 */ - { int m4 = z->l - z->c; (void)m4; /* do, line 179 */ - { int ret = r_remove_possessive_pronoun(z); /* call remove_possessive_pronoun, line 179 */ + if (!(z->I[1] > 2)) return 0; + { int m4 = z->l - z->c; (void)m4; + { int ret = r_remove_possessive_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m4; } z->c = z->lb; - if (!(z->I[0] > 2)) return 0; /* $( > ), line 181 */ - { int c5 = z->c; /* or, line 188 */ - { int c_test6 = z->c; /* test, line 182 */ - { int ret = r_remove_first_order_prefix(z); /* call remove_first_order_prefix, line 183 */ + if (!(z->I[1] > 2)) return 0; + { int c5 = z->c; + { int c_test6 = z->c; + { int ret = r_remove_first_order_prefix(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - { int c7 = z->c; /* do, line 184 */ - { int c_test8 = z->c; /* test, line 185 */ - if (!(z->I[0] > 2)) goto lab4; /* $( > ), line 185 */ - z->lb = z->c; z->c = z->l; /* backwards, line 185 */ + { int c7 = z->c; + { int c_test8 = z->c; + if (!(z->I[1] > 2)) goto lab4; + z->lb = z->c; z->c = z->l; - { int ret = r_remove_suffix(z); /* call remove_suffix, line 185 */ + { int ret = r_remove_suffix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } z->c = z->lb; z->c = c_test8; } - if (!(z->I[0] > 2)) goto lab4; /* $( > ), line 186 */ - { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 186 */ + if (!(z->I[1] > 2)) goto lab4; + { int ret = r_remove_second_order_prefix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } @@ -379,17 +378,17 @@ extern int indonesian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ goto lab2; lab3: z->c = c5; - { int c9 = z->c; /* do, line 189 */ - { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 189 */ + { int c9 = z->c; + { int ret = r_remove_second_order_prefix(z); if (ret < 0) return ret; } z->c = c9; } - { int c10 = z->c; /* do, line 190 */ - if (!(z->I[0] > 2)) goto lab5; /* $( > ), line 190 */ - z->lb = z->c; z->c = z->l; /* backwards, line 190 */ + { int c10 = z->c; + if (!(z->I[1] > 2)) goto lab5; + z->lb = z->c; z->c = z->l; - { int ret = r_remove_suffix(z); /* call remove_suffix, line 190 */ + { int ret = r_remove_suffix(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } @@ -402,7 +401,7 @@ extern int indonesian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * indonesian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * indonesian_UTF_8_create_env(void) { return SN_create_env(0, 2); } extern void indonesian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_irish.c b/src/backend/snowball/libstemmer/stem_UTF_8_irish.c index 8d1f219db0b2..b719318ce498 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_irish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_irish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -56,30 +56,30 @@ static const symbol s_0_23[2] = { 't', 's' }; static const struct among a_0[24] = { -/* 0 */ { 2, s_0_0, -1, 1, 0}, -/* 1 */ { 2, s_0_1, -1, 4, 0}, -/* 2 */ { 3, s_0_2, 1, 2, 0}, -/* 3 */ { 2, s_0_3, -1, 8, 0}, -/* 4 */ { 2, s_0_4, -1, 5, 0}, -/* 5 */ { 2, s_0_5, -1, 1, 0}, -/* 6 */ { 4, s_0_6, 5, 2, 0}, -/* 7 */ { 2, s_0_7, -1, 6, 0}, -/* 8 */ { 2, s_0_8, -1, 9, 0}, -/* 9 */ { 2, s_0_9, -1, 2, 0}, -/* 10 */ { 2, s_0_10, -1, 5, 0}, -/* 11 */ { 2, s_0_11, -1, 7, 0}, -/* 12 */ { 2, s_0_12, -1, 1, 0}, -/* 13 */ { 2, s_0_13, -1, 1, 0}, -/* 14 */ { 2, s_0_14, -1, 4, 0}, -/* 15 */ { 2, s_0_15, -1, 10, 0}, -/* 16 */ { 2, s_0_16, -1, 1, 0}, -/* 17 */ { 2, s_0_17, -1, 6, 0}, -/* 18 */ { 2, s_0_18, -1, 7, 0}, -/* 19 */ { 2, s_0_19, -1, 8, 0}, -/* 20 */ { 2, s_0_20, -1, 3, 0}, -/* 21 */ { 2, s_0_21, -1, 1, 0}, -/* 22 */ { 2, s_0_22, -1, 9, 0}, -/* 23 */ { 2, s_0_23, -1, 3, 0} +{ 2, s_0_0, -1, 1, 0}, +{ 2, s_0_1, -1, 4, 0}, +{ 3, s_0_2, 1, 2, 0}, +{ 2, s_0_3, -1, 8, 0}, +{ 2, s_0_4, -1, 5, 0}, +{ 2, s_0_5, -1, 1, 0}, +{ 4, s_0_6, 5, 2, 0}, +{ 2, s_0_7, -1, 6, 0}, +{ 2, s_0_8, -1, 9, 0}, +{ 2, s_0_9, -1, 2, 0}, +{ 2, s_0_10, -1, 5, 0}, +{ 2, s_0_11, -1, 7, 0}, +{ 2, s_0_12, -1, 1, 0}, +{ 2, s_0_13, -1, 1, 0}, +{ 2, s_0_14, -1, 4, 0}, +{ 2, s_0_15, -1, 10, 0}, +{ 2, s_0_16, -1, 1, 0}, +{ 2, s_0_17, -1, 6, 0}, +{ 2, s_0_18, -1, 7, 0}, +{ 2, s_0_19, -1, 8, 0}, +{ 2, s_0_20, -1, 3, 0}, +{ 2, s_0_21, -1, 1, 0}, +{ 2, s_0_22, -1, 9, 0}, +{ 2, s_0_23, -1, 3, 0} }; static const symbol s_1_0[7] = { 0xC3, 0xAD, 'o', 'c', 'h', 't', 'a' }; @@ -101,22 +101,22 @@ static const symbol s_1_15[5] = { 'a', 'i', 'r', 0xC3, 0xAD }; static const struct among a_1[16] = { -/* 0 */ { 7, s_1_0, -1, 1, 0}, -/* 1 */ { 8, s_1_1, 0, 1, 0}, -/* 2 */ { 3, s_1_2, -1, 2, 0}, -/* 3 */ { 4, s_1_3, 2, 2, 0}, -/* 4 */ { 3, s_1_4, -1, 1, 0}, -/* 5 */ { 4, s_1_5, 4, 1, 0}, -/* 6 */ { 3, s_1_6, -1, 1, 0}, -/* 7 */ { 4, s_1_7, 6, 1, 0}, -/* 8 */ { 3, s_1_8, -1, 1, 0}, -/* 9 */ { 4, s_1_9, 8, 1, 0}, -/* 10 */ { 3, s_1_10, -1, 1, 0}, -/* 11 */ { 4, s_1_11, 10, 1, 0}, -/* 12 */ { 6, s_1_12, -1, 1, 0}, -/* 13 */ { 7, s_1_13, 12, 1, 0}, -/* 14 */ { 4, s_1_14, -1, 2, 0}, -/* 15 */ { 5, s_1_15, 14, 2, 0} +{ 7, s_1_0, -1, 1, 0}, +{ 8, s_1_1, 0, 1, 0}, +{ 3, s_1_2, -1, 2, 0}, +{ 4, s_1_3, 2, 2, 0}, +{ 3, s_1_4, -1, 1, 0}, +{ 4, s_1_5, 4, 1, 0}, +{ 3, s_1_6, -1, 1, 0}, +{ 4, s_1_7, 6, 1, 0}, +{ 3, s_1_8, -1, 1, 0}, +{ 4, s_1_9, 8, 1, 0}, +{ 3, s_1_10, -1, 1, 0}, +{ 4, s_1_11, 10, 1, 0}, +{ 6, s_1_12, -1, 1, 0}, +{ 7, s_1_13, 12, 1, 0}, +{ 4, s_1_14, -1, 2, 0}, +{ 5, s_1_15, 14, 2, 0} }; static const symbol s_2_0[9] = { 0xC3, 0xB3, 'i', 'd', 'e', 'a', 'c', 'h', 'a' }; @@ -147,31 +147,31 @@ static const symbol s_2_24[14] = { 'g', 'r', 'a', 'f', 'a', 0xC3, 0xAD, 'o', 'c' static const struct among a_2[25] = { -/* 0 */ { 9, s_2_0, -1, 6, 0}, -/* 1 */ { 7, s_2_1, -1, 5, 0}, -/* 2 */ { 5, s_2_2, -1, 1, 0}, -/* 3 */ { 8, s_2_3, 2, 2, 0}, -/* 4 */ { 6, s_2_4, 2, 1, 0}, -/* 5 */ { 12, s_2_5, -1, 4, 0}, -/* 6 */ { 5, s_2_6, -1, 5, 0}, -/* 7 */ { 3, s_2_7, -1, 1, 0}, -/* 8 */ { 4, s_2_8, 7, 1, 0}, -/* 9 */ { 8, s_2_9, 8, 6, 0}, -/* 10 */ { 7, s_2_10, 8, 3, 0}, -/* 11 */ { 6, s_2_11, 7, 5, 0}, -/* 12 */ { 10, s_2_12, -1, 4, 0}, -/* 13 */ { 7, s_2_13, -1, 5, 0}, -/* 14 */ { 7, s_2_14, -1, 6, 0}, -/* 15 */ { 8, s_2_15, -1, 1, 0}, -/* 16 */ { 9, s_2_16, 15, 1, 0}, -/* 17 */ { 6, s_2_17, -1, 3, 0}, -/* 18 */ { 5, s_2_18, -1, 3, 0}, -/* 19 */ { 4, s_2_19, -1, 1, 0}, -/* 20 */ { 7, s_2_20, 19, 2, 0}, -/* 21 */ { 5, s_2_21, 19, 1, 0}, -/* 22 */ { 11, s_2_22, -1, 4, 0}, -/* 23 */ { 10, s_2_23, -1, 2, 0}, -/* 24 */ { 14, s_2_24, -1, 4, 0} +{ 9, s_2_0, -1, 6, 0}, +{ 7, s_2_1, -1, 5, 0}, +{ 5, s_2_2, -1, 1, 0}, +{ 8, s_2_3, 2, 2, 0}, +{ 6, s_2_4, 2, 1, 0}, +{ 12, s_2_5, -1, 4, 0}, +{ 5, s_2_6, -1, 5, 0}, +{ 3, s_2_7, -1, 1, 0}, +{ 4, s_2_8, 7, 1, 0}, +{ 8, s_2_9, 8, 6, 0}, +{ 7, s_2_10, 8, 3, 0}, +{ 6, s_2_11, 7, 5, 0}, +{ 10, s_2_12, -1, 4, 0}, +{ 7, s_2_13, -1, 5, 0}, +{ 7, s_2_14, -1, 6, 0}, +{ 8, s_2_15, -1, 1, 0}, +{ 9, s_2_16, 15, 1, 0}, +{ 6, s_2_17, -1, 3, 0}, +{ 5, s_2_18, -1, 3, 0}, +{ 4, s_2_19, -1, 1, 0}, +{ 7, s_2_20, 19, 2, 0}, +{ 5, s_2_21, 19, 1, 0}, +{ 11, s_2_22, -1, 4, 0}, +{ 10, s_2_23, -1, 2, 0}, +{ 14, s_2_24, -1, 4, 0} }; static const symbol s_3_0[4] = { 'i', 'm', 'i', 'd' }; @@ -189,18 +189,18 @@ static const symbol s_3_11[3] = { 't', 'a', 'r' }; static const struct among a_3[12] = { -/* 0 */ { 4, s_3_0, -1, 1, 0}, -/* 1 */ { 5, s_3_1, 0, 1, 0}, -/* 2 */ { 5, s_3_2, -1, 1, 0}, -/* 3 */ { 6, s_3_3, 2, 1, 0}, -/* 4 */ { 3, s_3_4, -1, 2, 0}, -/* 5 */ { 4, s_3_5, 4, 2, 0}, -/* 6 */ { 5, s_3_6, -1, 1, 0}, -/* 7 */ { 4, s_3_7, -1, 1, 0}, -/* 8 */ { 4, s_3_8, -1, 2, 0}, -/* 9 */ { 3, s_3_9, -1, 2, 0}, -/* 10 */ { 4, s_3_10, -1, 2, 0}, -/* 11 */ { 3, s_3_11, -1, 2, 0} +{ 4, s_3_0, -1, 1, 0}, +{ 5, s_3_1, 0, 1, 0}, +{ 5, s_3_2, -1, 1, 0}, +{ 6, s_3_3, 2, 1, 0}, +{ 3, s_3_4, -1, 2, 0}, +{ 4, s_3_5, 4, 2, 0}, +{ 5, s_3_6, -1, 1, 0}, +{ 4, s_3_7, -1, 1, 0}, +{ 4, s_3_8, -1, 2, 0}, +{ 3, s_3_9, -1, 2, 0}, +{ 4, s_3_10, -1, 2, 0}, +{ 3, s_3_11, -1, 2, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 2 }; @@ -220,103 +220,103 @@ static const symbol s_11[] = { 'g', 'r', 'a', 'f' }; static const symbol s_12[] = { 'p', 'a', 'i', 't', 'e' }; static const symbol s_13[] = { 0xC3, 0xB3, 'i', 'd' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 30 */ - z->I[1] = z->l; /* $p1 = , line 31 */ - z->I[2] = z->l; /* $p2 = , line 32 */ - { int c1 = z->c; /* do, line 34 */ - { /* gopast */ /* grouping v, line 35 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark pV, line 35 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c2 = z->c; /* do, line 37 */ - { /* gopast */ /* grouping v, line 38 */ + { int c2 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - { /* gopast */ /* non v, line 38 */ + { int ret = in_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 38 */ - { /* gopast */ /* grouping v, line 39 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - { /* gopast */ /* non v, line 39 */ + { int ret = in_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab1; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 39 */ + z->I[0] = z->c; lab1: z->c = c2; } return 1; } -static int r_initial_morph(struct SN_env * z) { /* forwardmode */ +static int r_initial_morph(struct SN_env * z) { int among_var; - z->bra = z->c; /* [, line 44 */ - among_var = find_among(z, a_0, 24); /* substring, line 44 */ + z->bra = z->c; + among_var = find_among(z, a_0, 24); if (!(among_var)) return 0; - z->ket = z->c; /* ], line 44 */ - switch (among_var) { /* among, line 44 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 46 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 52 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 58 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 61 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 63 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 65 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 69 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 71 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 75 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 89 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; @@ -324,41 +324,41 @@ static int r_initial_morph(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 99 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 100 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 101 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_noun_sfx(struct SN_env * z) { /* backwardmode */ +static int r_noun_sfx(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 104 */ - among_var = find_among_b(z, a_1, 16); /* substring, line 104 */ + z->ket = z->c; + among_var = find_among_b(z, a_1, 16); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 104 */ - switch (among_var) { /* among, line 104 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 108 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 108 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 110 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -366,43 +366,43 @@ static int r_noun_sfx(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_deriv(struct SN_env * z) { /* backwardmode */ +static int r_deriv(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 114 */ - among_var = find_among_b(z, a_2, 25); /* substring, line 114 */ + z->ket = z->c; + among_var = find_among_b(z, a_2, 25); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 114 */ - switch (among_var) { /* among, line 114 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 116 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 116 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_9); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_9); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_10); /* <-, line 120 */ + { int ret = slice_from_s(z, 3, s_10); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 122 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 5, s_12); /* <-, line 124 */ + { int ret = slice_from_s(z, 5, s_12); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 4, s_13); /* <-, line 126 */ + { int ret = slice_from_s(z, 4, s_13); if (ret < 0) return ret; } break; @@ -410,27 +410,27 @@ static int r_deriv(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_sfx(struct SN_env * z) { /* backwardmode */ +static int r_verb_sfx(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 130 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((282896 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 130 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((282896 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_3, 12); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 130 */ - switch (among_var) { /* among, line 130 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 133 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 133 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R1(z); /* call R1, line 138 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 138 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -438,33 +438,33 @@ static int r_verb_sfx(struct SN_env * z) { /* backwardmode */ return 1; } -extern int irish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 144 */ - { int ret = r_initial_morph(z); /* call initial_morph, line 144 */ +extern int irish_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_initial_morph(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 145 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 145 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 146 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 147 */ - { int ret = r_noun_sfx(z); /* call noun_sfx, line 147 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_noun_sfx(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 148 */ - { int ret = r_deriv(z); /* call deriv, line 148 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_deriv(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 149 */ - { int ret = r_verb_sfx(z); /* call verb_sfx, line 149 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_verb_sfx(z); if (ret < 0) return ret; } z->c = z->l - m4; @@ -473,7 +473,7 @@ extern int irish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * irish_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * irish_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void irish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_italian.c b/src/backend/snowball/libstemmer/stem_UTF_8_italian.c index 51e47978c21a..bd68ad711c31 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_italian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_italian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -40,13 +40,13 @@ static const symbol s_0_6[2] = { 0xC3, 0xBA }; static const struct among a_0[7] = { -/* 0 */ { 0, 0, -1, 7, 0}, -/* 1 */ { 2, s_0_1, 0, 6, 0}, -/* 2 */ { 2, s_0_2, 0, 1, 0}, -/* 3 */ { 2, s_0_3, 0, 2, 0}, -/* 4 */ { 2, s_0_4, 0, 3, 0}, -/* 5 */ { 2, s_0_5, 0, 4, 0}, -/* 6 */ { 2, s_0_6, 0, 5, 0} +{ 0, 0, -1, 7, 0}, +{ 2, s_0_1, 0, 6, 0}, +{ 2, s_0_2, 0, 1, 0}, +{ 2, s_0_3, 0, 2, 0}, +{ 2, s_0_4, 0, 3, 0}, +{ 2, s_0_5, 0, 4, 0}, +{ 2, s_0_6, 0, 5, 0} }; static const symbol s_1_1[1] = { 'I' }; @@ -54,9 +54,9 @@ static const symbol s_1_2[1] = { 'U' }; static const struct among a_1[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 1, s_1_1, 0, 1, 0}, -/* 2 */ { 1, s_1_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 1, s_1_1, 0, 1, 0}, +{ 1, s_1_2, 0, 2, 0} }; static const symbol s_2_0[2] = { 'l', 'a' }; @@ -99,43 +99,43 @@ static const symbol s_2_36[4] = { 'v', 'e', 'l', 'o' }; static const struct among a_2[37] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 4, s_2_1, 0, -1, 0}, -/* 2 */ { 6, s_2_2, 0, -1, 0}, -/* 3 */ { 4, s_2_3, 0, -1, 0}, -/* 4 */ { 4, s_2_4, 0, -1, 0}, -/* 5 */ { 4, s_2_5, 0, -1, 0}, -/* 6 */ { 2, s_2_6, -1, -1, 0}, -/* 7 */ { 4, s_2_7, 6, -1, 0}, -/* 8 */ { 6, s_2_8, 6, -1, 0}, -/* 9 */ { 4, s_2_9, 6, -1, 0}, -/* 10 */ { 4, s_2_10, 6, -1, 0}, -/* 11 */ { 4, s_2_11, 6, -1, 0}, -/* 12 */ { 2, s_2_12, -1, -1, 0}, -/* 13 */ { 4, s_2_13, 12, -1, 0}, -/* 14 */ { 6, s_2_14, 12, -1, 0}, -/* 15 */ { 4, s_2_15, 12, -1, 0}, -/* 16 */ { 4, s_2_16, 12, -1, 0}, -/* 17 */ { 4, s_2_17, 12, -1, 0}, -/* 18 */ { 4, s_2_18, 12, -1, 0}, -/* 19 */ { 2, s_2_19, -1, -1, 0}, -/* 20 */ { 2, s_2_20, -1, -1, 0}, -/* 21 */ { 4, s_2_21, 20, -1, 0}, -/* 22 */ { 6, s_2_22, 20, -1, 0}, -/* 23 */ { 4, s_2_23, 20, -1, 0}, -/* 24 */ { 4, s_2_24, 20, -1, 0}, -/* 25 */ { 4, s_2_25, 20, -1, 0}, -/* 26 */ { 3, s_2_26, 20, -1, 0}, -/* 27 */ { 2, s_2_27, -1, -1, 0}, -/* 28 */ { 2, s_2_28, -1, -1, 0}, -/* 29 */ { 2, s_2_29, -1, -1, 0}, -/* 30 */ { 2, s_2_30, -1, -1, 0}, -/* 31 */ { 2, s_2_31, -1, -1, 0}, -/* 32 */ { 4, s_2_32, 31, -1, 0}, -/* 33 */ { 6, s_2_33, 31, -1, 0}, -/* 34 */ { 4, s_2_34, 31, -1, 0}, -/* 35 */ { 4, s_2_35, 31, -1, 0}, -/* 36 */ { 4, s_2_36, 31, -1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 4, s_2_1, 0, -1, 0}, +{ 6, s_2_2, 0, -1, 0}, +{ 4, s_2_3, 0, -1, 0}, +{ 4, s_2_4, 0, -1, 0}, +{ 4, s_2_5, 0, -1, 0}, +{ 2, s_2_6, -1, -1, 0}, +{ 4, s_2_7, 6, -1, 0}, +{ 6, s_2_8, 6, -1, 0}, +{ 4, s_2_9, 6, -1, 0}, +{ 4, s_2_10, 6, -1, 0}, +{ 4, s_2_11, 6, -1, 0}, +{ 2, s_2_12, -1, -1, 0}, +{ 4, s_2_13, 12, -1, 0}, +{ 6, s_2_14, 12, -1, 0}, +{ 4, s_2_15, 12, -1, 0}, +{ 4, s_2_16, 12, -1, 0}, +{ 4, s_2_17, 12, -1, 0}, +{ 4, s_2_18, 12, -1, 0}, +{ 2, s_2_19, -1, -1, 0}, +{ 2, s_2_20, -1, -1, 0}, +{ 4, s_2_21, 20, -1, 0}, +{ 6, s_2_22, 20, -1, 0}, +{ 4, s_2_23, 20, -1, 0}, +{ 4, s_2_24, 20, -1, 0}, +{ 4, s_2_25, 20, -1, 0}, +{ 3, s_2_26, 20, -1, 0}, +{ 2, s_2_27, -1, -1, 0}, +{ 2, s_2_28, -1, -1, 0}, +{ 2, s_2_29, -1, -1, 0}, +{ 2, s_2_30, -1, -1, 0}, +{ 2, s_2_31, -1, -1, 0}, +{ 4, s_2_32, 31, -1, 0}, +{ 6, s_2_33, 31, -1, 0}, +{ 4, s_2_34, 31, -1, 0}, +{ 4, s_2_35, 31, -1, 0}, +{ 4, s_2_36, 31, -1, 0} }; static const symbol s_3_0[4] = { 'a', 'n', 'd', 'o' }; @@ -146,11 +146,11 @@ static const symbol s_3_4[2] = { 'i', 'r' }; static const struct among a_3[5] = { -/* 0 */ { 4, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 2, s_3_2, -1, 2, 0}, -/* 3 */ { 2, s_3_3, -1, 2, 0}, -/* 4 */ { 2, s_3_4, -1, 2, 0} +{ 4, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 2, s_3_2, -1, 2, 0}, +{ 2, s_3_3, -1, 2, 0}, +{ 2, s_3_4, -1, 2, 0} }; static const symbol s_4_0[2] = { 'i', 'c' }; @@ -160,10 +160,10 @@ static const symbol s_4_3[2] = { 'i', 'v' }; static const struct among a_4[4] = { -/* 0 */ { 2, s_4_0, -1, -1, 0}, -/* 1 */ { 4, s_4_1, -1, -1, 0}, -/* 2 */ { 2, s_4_2, -1, -1, 0}, -/* 3 */ { 2, s_4_3, -1, 1, 0} +{ 2, s_4_0, -1, -1, 0}, +{ 4, s_4_1, -1, -1, 0}, +{ 2, s_4_2, -1, -1, 0}, +{ 2, s_4_3, -1, 1, 0} }; static const symbol s_5_0[2] = { 'i', 'c' }; @@ -172,9 +172,9 @@ static const symbol s_5_2[2] = { 'i', 'v' }; static const struct among a_5[3] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 4, s_5_1, -1, 1, 0}, -/* 2 */ { 2, s_5_2, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 4, s_5_1, -1, 1, 0}, +{ 2, s_5_2, -1, 1, 0} }; static const symbol s_6_0[3] = { 'i', 'c', 'a' }; @@ -231,57 +231,57 @@ static const symbol s_6_50[5] = { 'i', 's', 't', 0xC3, 0xAC }; static const struct among a_6[51] = { -/* 0 */ { 3, s_6_0, -1, 1, 0}, -/* 1 */ { 5, s_6_1, -1, 3, 0}, -/* 2 */ { 3, s_6_2, -1, 1, 0}, -/* 3 */ { 4, s_6_3, -1, 1, 0}, -/* 4 */ { 3, s_6_4, -1, 9, 0}, -/* 5 */ { 4, s_6_5, -1, 1, 0}, -/* 6 */ { 4, s_6_6, -1, 5, 0}, -/* 7 */ { 3, s_6_7, -1, 1, 0}, -/* 8 */ { 6, s_6_8, 7, 1, 0}, -/* 9 */ { 4, s_6_9, -1, 1, 0}, -/* 10 */ { 5, s_6_10, -1, 3, 0}, -/* 11 */ { 5, s_6_11, -1, 1, 0}, -/* 12 */ { 5, s_6_12, -1, 1, 0}, -/* 13 */ { 6, s_6_13, -1, 4, 0}, -/* 14 */ { 6, s_6_14, -1, 2, 0}, -/* 15 */ { 6, s_6_15, -1, 4, 0}, -/* 16 */ { 5, s_6_16, -1, 2, 0}, -/* 17 */ { 3, s_6_17, -1, 1, 0}, -/* 18 */ { 4, s_6_18, -1, 1, 0}, -/* 19 */ { 5, s_6_19, -1, 1, 0}, -/* 20 */ { 6, s_6_20, 19, 7, 0}, -/* 21 */ { 4, s_6_21, -1, 1, 0}, -/* 22 */ { 3, s_6_22, -1, 9, 0}, -/* 23 */ { 4, s_6_23, -1, 1, 0}, -/* 24 */ { 4, s_6_24, -1, 5, 0}, -/* 25 */ { 3, s_6_25, -1, 1, 0}, -/* 26 */ { 6, s_6_26, 25, 1, 0}, -/* 27 */ { 4, s_6_27, -1, 1, 0}, -/* 28 */ { 5, s_6_28, -1, 1, 0}, -/* 29 */ { 5, s_6_29, -1, 1, 0}, -/* 30 */ { 4, s_6_30, -1, 1, 0}, -/* 31 */ { 6, s_6_31, -1, 4, 0}, -/* 32 */ { 6, s_6_32, -1, 2, 0}, -/* 33 */ { 6, s_6_33, -1, 4, 0}, -/* 34 */ { 5, s_6_34, -1, 2, 0}, -/* 35 */ { 3, s_6_35, -1, 1, 0}, -/* 36 */ { 4, s_6_36, -1, 1, 0}, -/* 37 */ { 6, s_6_37, -1, 6, 0}, -/* 38 */ { 6, s_6_38, -1, 6, 0}, -/* 39 */ { 4, s_6_39, -1, 1, 0}, -/* 40 */ { 3, s_6_40, -1, 9, 0}, -/* 41 */ { 3, s_6_41, -1, 1, 0}, -/* 42 */ { 4, s_6_42, -1, 1, 0}, -/* 43 */ { 3, s_6_43, -1, 1, 0}, -/* 44 */ { 6, s_6_44, -1, 6, 0}, -/* 45 */ { 6, s_6_45, -1, 6, 0}, -/* 46 */ { 3, s_6_46, -1, 9, 0}, -/* 47 */ { 4, s_6_47, -1, 8, 0}, -/* 48 */ { 5, s_6_48, -1, 1, 0}, -/* 49 */ { 5, s_6_49, -1, 1, 0}, -/* 50 */ { 5, s_6_50, -1, 1, 0} +{ 3, s_6_0, -1, 1, 0}, +{ 5, s_6_1, -1, 3, 0}, +{ 3, s_6_2, -1, 1, 0}, +{ 4, s_6_3, -1, 1, 0}, +{ 3, s_6_4, -1, 9, 0}, +{ 4, s_6_5, -1, 1, 0}, +{ 4, s_6_6, -1, 5, 0}, +{ 3, s_6_7, -1, 1, 0}, +{ 6, s_6_8, 7, 1, 0}, +{ 4, s_6_9, -1, 1, 0}, +{ 5, s_6_10, -1, 3, 0}, +{ 5, s_6_11, -1, 1, 0}, +{ 5, s_6_12, -1, 1, 0}, +{ 6, s_6_13, -1, 4, 0}, +{ 6, s_6_14, -1, 2, 0}, +{ 6, s_6_15, -1, 4, 0}, +{ 5, s_6_16, -1, 2, 0}, +{ 3, s_6_17, -1, 1, 0}, +{ 4, s_6_18, -1, 1, 0}, +{ 5, s_6_19, -1, 1, 0}, +{ 6, s_6_20, 19, 7, 0}, +{ 4, s_6_21, -1, 1, 0}, +{ 3, s_6_22, -1, 9, 0}, +{ 4, s_6_23, -1, 1, 0}, +{ 4, s_6_24, -1, 5, 0}, +{ 3, s_6_25, -1, 1, 0}, +{ 6, s_6_26, 25, 1, 0}, +{ 4, s_6_27, -1, 1, 0}, +{ 5, s_6_28, -1, 1, 0}, +{ 5, s_6_29, -1, 1, 0}, +{ 4, s_6_30, -1, 1, 0}, +{ 6, s_6_31, -1, 4, 0}, +{ 6, s_6_32, -1, 2, 0}, +{ 6, s_6_33, -1, 4, 0}, +{ 5, s_6_34, -1, 2, 0}, +{ 3, s_6_35, -1, 1, 0}, +{ 4, s_6_36, -1, 1, 0}, +{ 6, s_6_37, -1, 6, 0}, +{ 6, s_6_38, -1, 6, 0}, +{ 4, s_6_39, -1, 1, 0}, +{ 3, s_6_40, -1, 9, 0}, +{ 3, s_6_41, -1, 1, 0}, +{ 4, s_6_42, -1, 1, 0}, +{ 3, s_6_43, -1, 1, 0}, +{ 6, s_6_44, -1, 6, 0}, +{ 6, s_6_45, -1, 6, 0}, +{ 3, s_6_46, -1, 9, 0}, +{ 4, s_6_47, -1, 8, 0}, +{ 5, s_6_48, -1, 1, 0}, +{ 5, s_6_49, -1, 1, 0}, +{ 5, s_6_50, -1, 1, 0} }; static const symbol s_7_0[4] = { 'i', 's', 'c', 'a' }; @@ -374,93 +374,93 @@ static const symbol s_7_86[4] = { 'i', 'r', 0xC3, 0xB2 }; static const struct among a_7[87] = { -/* 0 */ { 4, s_7_0, -1, 1, 0}, -/* 1 */ { 4, s_7_1, -1, 1, 0}, -/* 2 */ { 3, s_7_2, -1, 1, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 3, s_7_4, -1, 1, 0}, -/* 5 */ { 3, s_7_5, -1, 1, 0}, -/* 6 */ { 3, s_7_6, -1, 1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 6, s_7_8, -1, 1, 0}, -/* 9 */ { 6, s_7_9, -1, 1, 0}, -/* 10 */ { 4, s_7_10, -1, 1, 0}, -/* 11 */ { 4, s_7_11, -1, 1, 0}, -/* 12 */ { 3, s_7_12, -1, 1, 0}, -/* 13 */ { 3, s_7_13, -1, 1, 0}, -/* 14 */ { 3, s_7_14, -1, 1, 0}, -/* 15 */ { 4, s_7_15, -1, 1, 0}, -/* 16 */ { 3, s_7_16, -1, 1, 0}, -/* 17 */ { 5, s_7_17, 16, 1, 0}, -/* 18 */ { 5, s_7_18, 16, 1, 0}, -/* 19 */ { 5, s_7_19, 16, 1, 0}, -/* 20 */ { 3, s_7_20, -1, 1, 0}, -/* 21 */ { 5, s_7_21, 20, 1, 0}, -/* 22 */ { 5, s_7_22, 20, 1, 0}, -/* 23 */ { 3, s_7_23, -1, 1, 0}, -/* 24 */ { 6, s_7_24, -1, 1, 0}, -/* 25 */ { 6, s_7_25, -1, 1, 0}, -/* 26 */ { 3, s_7_26, -1, 1, 0}, -/* 27 */ { 4, s_7_27, -1, 1, 0}, -/* 28 */ { 4, s_7_28, -1, 1, 0}, -/* 29 */ { 4, s_7_29, -1, 1, 0}, -/* 30 */ { 4, s_7_30, -1, 1, 0}, -/* 31 */ { 4, s_7_31, -1, 1, 0}, -/* 32 */ { 4, s_7_32, -1, 1, 0}, -/* 33 */ { 4, s_7_33, -1, 1, 0}, -/* 34 */ { 3, s_7_34, -1, 1, 0}, -/* 35 */ { 3, s_7_35, -1, 1, 0}, -/* 36 */ { 6, s_7_36, -1, 1, 0}, -/* 37 */ { 6, s_7_37, -1, 1, 0}, -/* 38 */ { 3, s_7_38, -1, 1, 0}, -/* 39 */ { 3, s_7_39, -1, 1, 0}, -/* 40 */ { 3, s_7_40, -1, 1, 0}, -/* 41 */ { 3, s_7_41, -1, 1, 0}, -/* 42 */ { 4, s_7_42, -1, 1, 0}, -/* 43 */ { 4, s_7_43, -1, 1, 0}, -/* 44 */ { 4, s_7_44, -1, 1, 0}, -/* 45 */ { 4, s_7_45, -1, 1, 0}, -/* 46 */ { 4, s_7_46, -1, 1, 0}, -/* 47 */ { 5, s_7_47, -1, 1, 0}, -/* 48 */ { 5, s_7_48, -1, 1, 0}, -/* 49 */ { 5, s_7_49, -1, 1, 0}, -/* 50 */ { 5, s_7_50, -1, 1, 0}, -/* 51 */ { 5, s_7_51, -1, 1, 0}, -/* 52 */ { 6, s_7_52, -1, 1, 0}, -/* 53 */ { 4, s_7_53, -1, 1, 0}, -/* 54 */ { 4, s_7_54, -1, 1, 0}, -/* 55 */ { 6, s_7_55, 54, 1, 0}, -/* 56 */ { 6, s_7_56, 54, 1, 0}, -/* 57 */ { 4, s_7_57, -1, 1, 0}, -/* 58 */ { 3, s_7_58, -1, 1, 0}, -/* 59 */ { 6, s_7_59, 58, 1, 0}, -/* 60 */ { 5, s_7_60, 58, 1, 0}, -/* 61 */ { 5, s_7_61, 58, 1, 0}, -/* 62 */ { 5, s_7_62, 58, 1, 0}, -/* 63 */ { 6, s_7_63, -1, 1, 0}, -/* 64 */ { 6, s_7_64, -1, 1, 0}, -/* 65 */ { 3, s_7_65, -1, 1, 0}, -/* 66 */ { 6, s_7_66, 65, 1, 0}, -/* 67 */ { 5, s_7_67, 65, 1, 0}, -/* 68 */ { 5, s_7_68, 65, 1, 0}, -/* 69 */ { 5, s_7_69, 65, 1, 0}, -/* 70 */ { 8, s_7_70, -1, 1, 0}, -/* 71 */ { 8, s_7_71, -1, 1, 0}, -/* 72 */ { 6, s_7_72, -1, 1, 0}, -/* 73 */ { 6, s_7_73, -1, 1, 0}, -/* 74 */ { 6, s_7_74, -1, 1, 0}, -/* 75 */ { 3, s_7_75, -1, 1, 0}, -/* 76 */ { 3, s_7_76, -1, 1, 0}, -/* 77 */ { 3, s_7_77, -1, 1, 0}, -/* 78 */ { 3, s_7_78, -1, 1, 0}, -/* 79 */ { 3, s_7_79, -1, 1, 0}, -/* 80 */ { 3, s_7_80, -1, 1, 0}, -/* 81 */ { 2, s_7_81, -1, 1, 0}, -/* 82 */ { 2, s_7_82, -1, 1, 0}, -/* 83 */ { 4, s_7_83, -1, 1, 0}, -/* 84 */ { 4, s_7_84, -1, 1, 0}, -/* 85 */ { 4, s_7_85, -1, 1, 0}, -/* 86 */ { 4, s_7_86, -1, 1, 0} +{ 4, s_7_0, -1, 1, 0}, +{ 4, s_7_1, -1, 1, 0}, +{ 3, s_7_2, -1, 1, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 3, s_7_4, -1, 1, 0}, +{ 3, s_7_5, -1, 1, 0}, +{ 3, s_7_6, -1, 1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 6, s_7_8, -1, 1, 0}, +{ 6, s_7_9, -1, 1, 0}, +{ 4, s_7_10, -1, 1, 0}, +{ 4, s_7_11, -1, 1, 0}, +{ 3, s_7_12, -1, 1, 0}, +{ 3, s_7_13, -1, 1, 0}, +{ 3, s_7_14, -1, 1, 0}, +{ 4, s_7_15, -1, 1, 0}, +{ 3, s_7_16, -1, 1, 0}, +{ 5, s_7_17, 16, 1, 0}, +{ 5, s_7_18, 16, 1, 0}, +{ 5, s_7_19, 16, 1, 0}, +{ 3, s_7_20, -1, 1, 0}, +{ 5, s_7_21, 20, 1, 0}, +{ 5, s_7_22, 20, 1, 0}, +{ 3, s_7_23, -1, 1, 0}, +{ 6, s_7_24, -1, 1, 0}, +{ 6, s_7_25, -1, 1, 0}, +{ 3, s_7_26, -1, 1, 0}, +{ 4, s_7_27, -1, 1, 0}, +{ 4, s_7_28, -1, 1, 0}, +{ 4, s_7_29, -1, 1, 0}, +{ 4, s_7_30, -1, 1, 0}, +{ 4, s_7_31, -1, 1, 0}, +{ 4, s_7_32, -1, 1, 0}, +{ 4, s_7_33, -1, 1, 0}, +{ 3, s_7_34, -1, 1, 0}, +{ 3, s_7_35, -1, 1, 0}, +{ 6, s_7_36, -1, 1, 0}, +{ 6, s_7_37, -1, 1, 0}, +{ 3, s_7_38, -1, 1, 0}, +{ 3, s_7_39, -1, 1, 0}, +{ 3, s_7_40, -1, 1, 0}, +{ 3, s_7_41, -1, 1, 0}, +{ 4, s_7_42, -1, 1, 0}, +{ 4, s_7_43, -1, 1, 0}, +{ 4, s_7_44, -1, 1, 0}, +{ 4, s_7_45, -1, 1, 0}, +{ 4, s_7_46, -1, 1, 0}, +{ 5, s_7_47, -1, 1, 0}, +{ 5, s_7_48, -1, 1, 0}, +{ 5, s_7_49, -1, 1, 0}, +{ 5, s_7_50, -1, 1, 0}, +{ 5, s_7_51, -1, 1, 0}, +{ 6, s_7_52, -1, 1, 0}, +{ 4, s_7_53, -1, 1, 0}, +{ 4, s_7_54, -1, 1, 0}, +{ 6, s_7_55, 54, 1, 0}, +{ 6, s_7_56, 54, 1, 0}, +{ 4, s_7_57, -1, 1, 0}, +{ 3, s_7_58, -1, 1, 0}, +{ 6, s_7_59, 58, 1, 0}, +{ 5, s_7_60, 58, 1, 0}, +{ 5, s_7_61, 58, 1, 0}, +{ 5, s_7_62, 58, 1, 0}, +{ 6, s_7_63, -1, 1, 0}, +{ 6, s_7_64, -1, 1, 0}, +{ 3, s_7_65, -1, 1, 0}, +{ 6, s_7_66, 65, 1, 0}, +{ 5, s_7_67, 65, 1, 0}, +{ 5, s_7_68, 65, 1, 0}, +{ 5, s_7_69, 65, 1, 0}, +{ 8, s_7_70, -1, 1, 0}, +{ 8, s_7_71, -1, 1, 0}, +{ 6, s_7_72, -1, 1, 0}, +{ 6, s_7_73, -1, 1, 0}, +{ 6, s_7_74, -1, 1, 0}, +{ 3, s_7_75, -1, 1, 0}, +{ 3, s_7_76, -1, 1, 0}, +{ 3, s_7_77, -1, 1, 0}, +{ 3, s_7_78, -1, 1, 0}, +{ 3, s_7_79, -1, 1, 0}, +{ 3, s_7_80, -1, 1, 0}, +{ 2, s_7_81, -1, 1, 0}, +{ 2, s_7_82, -1, 1, 0}, +{ 4, s_7_83, -1, 1, 0}, +{ 4, s_7_84, -1, 1, 0}, +{ 4, s_7_85, -1, 1, 0}, +{ 4, s_7_86, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 8, 2, 1 }; @@ -488,51 +488,50 @@ static const symbol s_15[] = { 'a', 't' }; static const symbol s_16[] = { 'a', 't' }; static const symbol s_17[] = { 'i', 'c' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ +static int r_prelude(struct SN_env * z) { int among_var; - { int c_test1 = z->c; /* test, line 35 */ -/* repeat, line 35 */ - - while(1) { int c2 = z->c; - z->bra = z->c; /* [, line 36 */ - among_var = find_among(z, a_0, 7); /* substring, line 36 */ + { int c_test1 = z->c; + while(1) { + int c2 = z->c; + z->bra = z->c; + among_var = find_among(z, a_0, 7); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 36 */ - switch (among_var) { /* among, line 36 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 37 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_1); /* <-, line 38 */ + { int ret = slice_from_s(z, 2, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_2); /* <-, line 39 */ + { int ret = slice_from_s(z, 2, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_3); /* <-, line 40 */ + { int ret = slice_from_s(z, 2, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 2, s_4); /* <-, line 41 */ + { int ret = slice_from_s(z, 2, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_5); /* <-, line 42 */ + { int ret = slice_from_s(z, 2, s_5); if (ret < 0) return ret; } break; case 7: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 43 */ + z->c = ret; } break; } @@ -543,29 +542,28 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ } z->c = c_test1; } -/* repeat, line 46 */ - - while(1) { int c3 = z->c; - while(1) { /* goto, line 46 */ + while(1) { + int c3 = z->c; + while(1) { int c4 = z->c; - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 47 */ - z->bra = z->c; /* [, line 47 */ - { int c5 = z->c; /* or, line 47 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab4; /* literal, line 47 */ + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; + z->bra = z->c; + { int c5 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab4; z->c++; - z->ket = z->c; /* ], line 47 */ - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab4; /* grouping v, line 47 */ - { int ret = slice_from_s(z, 1, s_6); /* <-, line 47 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab4; + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } goto lab3; lab4: z->c = c5; - if (z->c == z->l || z->p[z->c] != 'i') goto lab2; /* literal, line 48 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab2; z->c++; - z->ket = z->c; /* ], line 48 */ - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 48 */ - { int ret = slice_from_s(z, 1, s_7); /* <-, line 48 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } } @@ -574,9 +572,9 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ break; lab2: z->c = c4; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab1; - z->c = ret; /* goto, line 46 */ + z->c = ret; } } continue; @@ -587,16 +585,16 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 54 */ - z->I[1] = z->l; /* $p1 = , line 55 */ - z->I[2] = z->l; /* $p2 = , line 56 */ - { int c1 = z->c; /* do, line 58 */ - { int c2 = z->c; /* or, line 60 */ - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ - { int c3 = z->c; /* or, line 59 */ - if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab4; /* non v, line 59 */ - { /* gopast */ /* grouping v, line 59 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab4; + { int ret = out_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab4; z->c += ret; @@ -604,8 +602,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ - { /* gopast */ /* non v, line 59 */ + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; + { int ret = in_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab2; z->c += ret; @@ -615,10 +613,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab0; /* non v, line 61 */ - { int c4 = z->c; /* or, line 61 */ - if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab6; /* non v, line 61 */ - { /* gopast */ /* grouping v, line 61 */ + if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab6; + { int ret = out_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab6; z->c += ret; @@ -626,74 +624,73 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab0; /* grouping v, line 61 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab0; + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 61 */ + z->c = ret; } } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 62 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 64 */ - { /* gopast */ /* grouping v, line 65 */ + { int c5 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 65 */ + { int ret = in_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 65 */ - { /* gopast */ /* grouping v, line 66 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 66 */ + { int ret = in_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 66 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 70 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 72 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 72 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 72 */ - switch (among_var) { /* among, line 72 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 73 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 74 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; case 3: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 75 */ + z->c = ret; } break; } @@ -705,41 +702,41 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 82 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 83 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 84 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ +static int r_attached_pronoun(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 87 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_2, 37))) return 0; - z->bra = z->c; /* ], line 87 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* among, line 97 */ + z->bra = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; among_var = find_among_b(z, a_3, 5); if (!(among_var)) return 0; - { int ret = r_RV(z); /* call RV, line 97 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 97 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 98 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 99 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; @@ -747,37 +744,37 @@ static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 104 */ - among_var = find_among_b(z, a_6, 51); /* substring, line 104 */ + z->ket = z->c; + among_var = find_among_b(z, a_6, 51); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 104 */ - switch (among_var) { /* among, line 104 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 111 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 111 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 113 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 113 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 114 */ - z->ket = z->c; /* [, line 114 */ - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m1; goto lab0; } /* literal, line 114 */ - z->bra = z->c; /* ], line 114 */ - { int ret = r_R2(z); /* call R2, line 114 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 114 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -785,67 +782,67 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - { int ret = r_R2(z); /* call R2, line 117 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_12); /* <-, line 117 */ + { int ret = slice_from_s(z, 3, s_12); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 119 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_13); /* <-, line 119 */ + { int ret = slice_from_s(z, 1, s_13); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 121 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_14); /* <-, line 121 */ + { int ret = slice_from_s(z, 4, s_14); if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); /* call RV, line 123 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 123 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 7: - { int ret = r_R1(z); /* call R1, line 125 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 126 */ - z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 127 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } among_var = find_among_b(z, a_4, 4); if (!(among_var)) { z->c = z->l - m2; goto lab1; } - z->bra = z->c; /* ], line 127 */ - { int ret = r_R2(z); /* call R2, line 127 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 127 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - switch (among_var) { /* among, line 127 */ + switch (among_var) { case 1: - z->ket = z->c; /* [, line 128 */ - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m2; goto lab1; } /* literal, line 128 */ - z->bra = z->c; /* ], line 128 */ - { int ret = r_R2(z); /* call R2, line 128 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m2; goto lab1; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 128 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -855,22 +852,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 134 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ - z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m3; goto lab2; } - z->bra = z->c; /* ], line 136 */ - { int ret = r_R2(z); /* call R2, line 137 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab2; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 137 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: @@ -878,31 +875,31 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = r_R2(z); /* call R2, line 142 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 142 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 143 */ - z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ - z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); /* call R2, line 143 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m4; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 143 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ - z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); /* call R2, line 143 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m4; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 143 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab3: @@ -913,15 +910,15 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 148 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 149 */ - if (!(find_among_b(z, a_7, 87))) { z->lb = mlimit1; return 0; } /* substring, line 149 */ - z->bra = z->c; /* ], line 149 */ - { int ret = slice_del(z); /* delete, line 163 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (!(find_among_b(z, a_7, 87))) { z->lb = mlimit1; return 0; } + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; @@ -929,43 +926,43 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* try, line 171 */ - z->ket = z->c; /* [, line 172 */ - if (in_grouping_b_U(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m1; goto lab0; } /* grouping AEIO, line 172 */ - z->bra = z->c; /* ], line 172 */ - { int ret = r_RV(z); /* call RV, line 172 */ +static int r_vowel_suffix(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (in_grouping_b_U(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 172 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 173 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'i') { z->c = z->l - m1; goto lab0; } /* literal, line 173 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') { z->c = z->l - m1; goto lab0; } z->c--; - z->bra = z->c; /* ], line 173 */ - { int ret = r_RV(z); /* call RV, line 173 */ + z->bra = z->c; + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 173 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: ; } - { int m2 = z->l - z->c; (void)m2; /* try, line 175 */ - z->ket = z->c; /* [, line 176 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'h') { z->c = z->l - m2; goto lab1; } /* literal, line 176 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'h') { z->c = z->l - m2; goto lab1; } z->c--; - z->bra = z->c; /* ], line 176 */ - if (in_grouping_b_U(z, g_CG, 99, 103, 0)) { z->c = z->l - m2; goto lab1; } /* grouping CG, line 176 */ - { int ret = r_RV(z); /* call RV, line 176 */ + z->bra = z->c; + if (in_grouping_b_U(z, g_CG, 99, 103, 0)) { z->c = z->l - m2; goto lab1; } + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 176 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: @@ -974,35 +971,35 @@ static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int italian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 182 */ - { int ret = r_prelude(z); /* call prelude, line 182 */ +extern int italian_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 183 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 183 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 184 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 185 */ - { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 185 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_attached_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 186 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 186 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 186 */ + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m4; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 186 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1011,15 +1008,15 @@ extern int italian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m3; } - { int m5 = z->l - z->c; (void)m5; /* do, line 187 */ - { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 187 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_vowel_suffix(z); if (ret < 0) return ret; } z->c = z->l - m5; } z->c = z->lb; - { int c6 = z->c; /* do, line 189 */ - { int ret = r_postlude(z); /* call postlude, line 189 */ + { int c6 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c6; @@ -1027,7 +1024,7 @@ extern int italian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * italian_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * italian_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void italian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_lithuanian.c b/src/backend/snowball/libstemmer/stem_UTF_8_lithuanian.c index f876e8fc236b..58f7d78f40f2 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_lithuanian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_lithuanian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -234,210 +234,210 @@ static const symbol s_0_203[4] = { 'e', 'r', 0xC5, 0xB3 }; static const struct among a_0[204] = { -/* 0 */ { 1, s_0_0, -1, -1, 0}, -/* 1 */ { 2, s_0_1, 0, -1, 0}, -/* 2 */ { 4, s_0_2, 1, -1, 0}, -/* 3 */ { 4, s_0_3, 0, -1, 0}, -/* 4 */ { 5, s_0_4, 3, -1, 0}, -/* 5 */ { 5, s_0_5, 3, -1, 0}, -/* 6 */ { 6, s_0_6, 5, -1, 0}, -/* 7 */ { 4, s_0_7, 0, -1, 0}, -/* 8 */ { 5, s_0_8, 0, -1, 0}, -/* 9 */ { 1, s_0_9, -1, -1, 0}, -/* 10 */ { 2, s_0_10, 9, -1, 0}, -/* 11 */ { 4, s_0_11, 10, -1, 0}, -/* 12 */ { 4, s_0_12, 10, -1, 0}, -/* 13 */ { 3, s_0_13, 9, -1, 0}, -/* 14 */ { 4, s_0_14, 13, -1, 0}, -/* 15 */ { 3, s_0_15, 9, -1, 0}, -/* 16 */ { 4, s_0_16, 15, -1, 0}, -/* 17 */ { 3, s_0_17, 9, -1, 0}, -/* 18 */ { 5, s_0_18, 17, -1, 0}, -/* 19 */ { 5, s_0_19, 17, -1, 0}, -/* 20 */ { 4, s_0_20, 9, -1, 0}, -/* 21 */ { 3, s_0_21, 9, -1, 0}, -/* 22 */ { 4, s_0_22, 21, -1, 0}, -/* 23 */ { 4, s_0_23, 9, -1, 0}, -/* 24 */ { 3, s_0_24, 9, -1, 0}, -/* 25 */ { 4, s_0_25, 9, -1, 0}, -/* 26 */ { 7, s_0_26, 25, -1, 0}, -/* 27 */ { 3, s_0_27, 9, -1, 0}, -/* 28 */ { 4, s_0_28, 27, -1, 0}, -/* 29 */ { 4, s_0_29, 27, -1, 0}, -/* 30 */ { 5, s_0_30, 29, -1, 0}, -/* 31 */ { 3, s_0_31, 9, -1, 0}, -/* 32 */ { 5, s_0_32, 31, -1, 0}, -/* 33 */ { 5, s_0_33, 31, -1, 0}, -/* 34 */ { 4, s_0_34, 9, -1, 0}, -/* 35 */ { 3, s_0_35, 9, -1, 0}, -/* 36 */ { 4, s_0_36, 35, -1, 0}, -/* 37 */ { 3, s_0_37, 9, -1, 0}, -/* 38 */ { 4, s_0_38, 37, -1, 0}, -/* 39 */ { 4, s_0_39, 37, -1, 0}, -/* 40 */ { 3, s_0_40, 9, -1, 0}, -/* 41 */ { 4, s_0_41, 9, -1, 0}, -/* 42 */ { 4, s_0_42, 9, -1, 0}, -/* 43 */ { 7, s_0_43, 42, -1, 0}, -/* 44 */ { 1, s_0_44, -1, -1, 0}, -/* 45 */ { 2, s_0_45, 44, -1, 0}, -/* 46 */ { 3, s_0_46, 45, -1, 0}, -/* 47 */ { 5, s_0_47, 46, -1, 0}, -/* 48 */ { 2, s_0_48, 44, -1, 0}, -/* 49 */ { 5, s_0_49, 48, -1, 0}, -/* 50 */ { 2, s_0_50, 44, -1, 0}, -/* 51 */ { 3, s_0_51, 44, -1, 0}, -/* 52 */ { 5, s_0_52, 51, -1, 0}, -/* 53 */ { 3, s_0_53, 44, -1, 0}, -/* 54 */ { 4, s_0_54, 53, -1, 0}, -/* 55 */ { 2, s_0_55, 44, -1, 0}, -/* 56 */ { 3, s_0_56, 55, -1, 0}, -/* 57 */ { 4, s_0_57, 56, -1, 0}, -/* 58 */ { 3, s_0_58, 55, -1, 0}, -/* 59 */ { 4, s_0_59, 58, -1, 0}, -/* 60 */ { 5, s_0_60, 59, -1, 0}, -/* 61 */ { 3, s_0_61, 55, -1, 0}, -/* 62 */ { 4, s_0_62, 61, -1, 0}, -/* 63 */ { 4, s_0_63, 61, -1, 0}, -/* 64 */ { 7, s_0_64, 63, -1, 0}, -/* 65 */ { 4, s_0_65, 61, -1, 0}, -/* 66 */ { 3, s_0_66, 55, -1, 0}, -/* 67 */ { 6, s_0_67, 66, -1, 0}, -/* 68 */ { 4, s_0_68, 66, -1, 0}, -/* 69 */ { 5, s_0_69, 68, -1, 0}, -/* 70 */ { 6, s_0_70, 69, -1, 0}, -/* 71 */ { 3, s_0_71, 55, -1, 0}, -/* 72 */ { 4, s_0_72, 71, -1, 0}, -/* 73 */ { 7, s_0_73, 72, -1, 0}, -/* 74 */ { 4, s_0_74, 55, -1, 0}, -/* 75 */ { 4, s_0_75, 55, -1, 0}, -/* 76 */ { 4, s_0_76, 55, -1, 0}, -/* 77 */ { 5, s_0_77, 76, -1, 0}, -/* 78 */ { 2, s_0_78, 44, -1, 0}, -/* 79 */ { 4, s_0_79, 78, -1, 0}, -/* 80 */ { 4, s_0_80, 78, -1, 0}, -/* 81 */ { 3, s_0_81, 78, -1, 0}, -/* 82 */ { 4, s_0_82, 81, -1, 0}, -/* 83 */ { 4, s_0_83, 81, -1, 0}, -/* 84 */ { 5, s_0_84, 83, -1, 0}, -/* 85 */ { 4, s_0_85, 78, -1, 0}, -/* 86 */ { 5, s_0_86, 85, -1, 0}, -/* 87 */ { 3, s_0_87, 78, -1, 0}, -/* 88 */ { 4, s_0_88, 78, -1, 0}, -/* 89 */ { 7, s_0_89, 88, -1, 0}, -/* 90 */ { 6, s_0_90, 88, -1, 0}, -/* 91 */ { 7, s_0_91, 88, -1, 0}, -/* 92 */ { 2, s_0_92, 44, -1, 0}, -/* 93 */ { 3, s_0_93, 92, -1, 0}, -/* 94 */ { 5, s_0_94, 93, -1, 0}, -/* 95 */ { 2, s_0_95, -1, -1, 0}, -/* 96 */ { 3, s_0_96, -1, -1, 0}, -/* 97 */ { 1, s_0_97, -1, -1, 0}, -/* 98 */ { 2, s_0_98, -1, -1, 0}, -/* 99 */ { 3, s_0_99, 98, -1, 0}, -/*100 */ { 3, s_0_100, -1, -1, 0}, -/*101 */ { 2, s_0_101, -1, -1, 0}, -/*102 */ { 3, s_0_102, 101, -1, 0}, -/*103 */ { 2, s_0_103, -1, -1, 0}, -/*104 */ { 3, s_0_104, -1, -1, 0}, -/*105 */ { 3, s_0_105, -1, -1, 0}, -/*106 */ { 6, s_0_106, 105, -1, 0}, -/*107 */ { 2, s_0_107, -1, -1, 0}, -/*108 */ { 2, s_0_108, -1, -1, 0}, -/*109 */ { 3, s_0_109, 108, -1, 0}, -/*110 */ { 2, s_0_110, -1, -1, 0}, -/*111 */ { 3, s_0_111, 110, -1, 0}, -/*112 */ { 3, s_0_112, -1, -1, 0}, -/*113 */ { 1, s_0_113, -1, -1, 0}, -/*114 */ { 2, s_0_114, 113, -1, 0}, -/*115 */ { 4, s_0_115, 114, -1, 0}, -/*116 */ { 4, s_0_116, 113, -1, 0}, -/*117 */ { 2, s_0_117, 113, -1, 0}, -/*118 */ { 1, s_0_118, -1, -1, 0}, -/*119 */ { 2, s_0_119, 118, -1, 0}, -/*120 */ { 3, s_0_120, 119, -1, 0}, -/*121 */ { 2, s_0_121, 118, -1, 0}, -/*122 */ { 3, s_0_122, 121, -1, 0}, -/*123 */ { 2, s_0_123, 118, -1, 0}, -/*124 */ { 3, s_0_124, 123, -1, 0}, -/*125 */ { 4, s_0_125, 124, -1, 0}, -/*126 */ { 6, s_0_126, 123, -1, 0}, -/*127 */ { 4, s_0_127, 123, -1, 0}, -/*128 */ { 6, s_0_128, 127, -1, 0}, -/*129 */ { 4, s_0_129, 123, -1, 0}, -/*130 */ { 5, s_0_130, 129, -1, 0}, -/*131 */ { 4, s_0_131, 123, -1, 0}, -/*132 */ { 5, s_0_132, 123, -1, 0}, -/*133 */ { 4, s_0_133, 123, -1, 0}, -/*134 */ { 4, s_0_134, 123, -1, 0}, -/*135 */ { 4, s_0_135, 123, -1, 0}, -/*136 */ { 3, s_0_136, 118, -1, 0}, -/*137 */ { 4, s_0_137, 136, -1, 0}, -/*138 */ { 4, s_0_138, 118, -1, 0}, -/*139 */ { 3, s_0_139, 118, -1, 0}, -/*140 */ { 5, s_0_140, 139, -1, 0}, -/*141 */ { 5, s_0_141, 139, -1, 0}, -/*142 */ { 3, s_0_142, 118, -1, 0}, -/*143 */ { 4, s_0_143, 142, -1, 0}, -/*144 */ { 3, s_0_144, 118, -1, 0}, -/*145 */ { 4, s_0_145, 118, -1, 0}, -/*146 */ { 3, s_0_146, 118, -1, 0}, -/*147 */ { 2, s_0_147, 118, -1, 0}, -/*148 */ { 3, s_0_148, 147, -1, 0}, -/*149 */ { 3, s_0_149, 147, -1, 0}, -/*150 */ { 4, s_0_150, 149, -1, 0}, -/*151 */ { 3, s_0_151, 118, -1, 0}, -/*152 */ { 2, s_0_152, 118, -1, 0}, -/*153 */ { 3, s_0_153, 152, -1, 0}, -/*154 */ { 4, s_0_154, 153, -1, 0}, -/*155 */ { 3, s_0_155, 152, -1, 0}, -/*156 */ { 2, s_0_156, 118, -1, 0}, -/*157 */ { 4, s_0_157, 156, -1, 0}, -/*158 */ { 4, s_0_158, 156, -1, 0}, -/*159 */ { 3, s_0_159, 118, -1, 0}, -/*160 */ { 4, s_0_160, 159, -1, 0}, -/*161 */ { 3, s_0_161, 118, -1, 0}, -/*162 */ { 5, s_0_162, 161, -1, 0}, -/*163 */ { 6, s_0_163, 162, -1, 0}, -/*164 */ { 5, s_0_164, 161, -1, 0}, -/*165 */ { 6, s_0_165, 164, -1, 0}, -/*166 */ { 6, s_0_166, 164, -1, 0}, -/*167 */ { 5, s_0_167, 161, -1, 0}, -/*168 */ { 6, s_0_168, 161, -1, 0}, -/*169 */ { 9, s_0_169, 168, -1, 0}, -/*170 */ { 5, s_0_170, 161, -1, 0}, -/*171 */ { 6, s_0_171, 170, -1, 0}, -/*172 */ { 6, s_0_172, 161, -1, 0}, -/*173 */ { 5, s_0_173, 161, -1, 0}, -/*174 */ { 6, s_0_174, 161, -1, 0}, -/*175 */ { 9, s_0_175, 174, -1, 0}, -/*176 */ { 3, s_0_176, 118, -1, 0}, -/*177 */ { 3, s_0_177, 118, -1, 0}, -/*178 */ { 4, s_0_178, 118, -1, 0}, -/*179 */ { 2, s_0_179, -1, -1, 0}, -/*180 */ { 3, s_0_180, 179, -1, 0}, -/*181 */ { 2, s_0_181, -1, -1, 0}, -/*182 */ { 3, s_0_182, 181, -1, 0}, -/*183 */ { 2, s_0_183, -1, -1, 0}, -/*184 */ { 3, s_0_184, -1, -1, 0}, -/*185 */ { 6, s_0_185, 184, -1, 0}, -/*186 */ { 1, s_0_186, -1, -1, 0}, -/*187 */ { 2, s_0_187, 186, -1, 0}, -/*188 */ { 3, s_0_188, 187, -1, 0}, -/*189 */ { 5, s_0_189, 188, -1, 0}, -/*190 */ { 2, s_0_190, 186, -1, 0}, -/*191 */ { 4, s_0_191, 190, -1, 0}, -/*192 */ { 3, s_0_192, 190, -1, 0}, -/*193 */ { 1, s_0_193, -1, -1, 0}, -/*194 */ { 2, s_0_194, -1, -1, 0}, -/*195 */ { 3, s_0_195, 194, -1, 0}, -/*196 */ { 2, s_0_196, -1, -1, 0}, -/*197 */ { 2, s_0_197, -1, -1, 0}, -/*198 */ { 2, s_0_198, -1, -1, 0}, -/*199 */ { 4, s_0_199, 198, -1, 0}, -/*200 */ { 4, s_0_200, 198, -1, 0}, -/*201 */ { 2, s_0_201, -1, -1, 0}, -/*202 */ { 3, s_0_202, 201, -1, 0}, -/*203 */ { 4, s_0_203, 201, -1, 0} +{ 1, s_0_0, -1, -1, 0}, +{ 2, s_0_1, 0, -1, 0}, +{ 4, s_0_2, 1, -1, 0}, +{ 4, s_0_3, 0, -1, 0}, +{ 5, s_0_4, 3, -1, 0}, +{ 5, s_0_5, 3, -1, 0}, +{ 6, s_0_6, 5, -1, 0}, +{ 4, s_0_7, 0, -1, 0}, +{ 5, s_0_8, 0, -1, 0}, +{ 1, s_0_9, -1, -1, 0}, +{ 2, s_0_10, 9, -1, 0}, +{ 4, s_0_11, 10, -1, 0}, +{ 4, s_0_12, 10, -1, 0}, +{ 3, s_0_13, 9, -1, 0}, +{ 4, s_0_14, 13, -1, 0}, +{ 3, s_0_15, 9, -1, 0}, +{ 4, s_0_16, 15, -1, 0}, +{ 3, s_0_17, 9, -1, 0}, +{ 5, s_0_18, 17, -1, 0}, +{ 5, s_0_19, 17, -1, 0}, +{ 4, s_0_20, 9, -1, 0}, +{ 3, s_0_21, 9, -1, 0}, +{ 4, s_0_22, 21, -1, 0}, +{ 4, s_0_23, 9, -1, 0}, +{ 3, s_0_24, 9, -1, 0}, +{ 4, s_0_25, 9, -1, 0}, +{ 7, s_0_26, 25, -1, 0}, +{ 3, s_0_27, 9, -1, 0}, +{ 4, s_0_28, 27, -1, 0}, +{ 4, s_0_29, 27, -1, 0}, +{ 5, s_0_30, 29, -1, 0}, +{ 3, s_0_31, 9, -1, 0}, +{ 5, s_0_32, 31, -1, 0}, +{ 5, s_0_33, 31, -1, 0}, +{ 4, s_0_34, 9, -1, 0}, +{ 3, s_0_35, 9, -1, 0}, +{ 4, s_0_36, 35, -1, 0}, +{ 3, s_0_37, 9, -1, 0}, +{ 4, s_0_38, 37, -1, 0}, +{ 4, s_0_39, 37, -1, 0}, +{ 3, s_0_40, 9, -1, 0}, +{ 4, s_0_41, 9, -1, 0}, +{ 4, s_0_42, 9, -1, 0}, +{ 7, s_0_43, 42, -1, 0}, +{ 1, s_0_44, -1, -1, 0}, +{ 2, s_0_45, 44, -1, 0}, +{ 3, s_0_46, 45, -1, 0}, +{ 5, s_0_47, 46, -1, 0}, +{ 2, s_0_48, 44, -1, 0}, +{ 5, s_0_49, 48, -1, 0}, +{ 2, s_0_50, 44, -1, 0}, +{ 3, s_0_51, 44, -1, 0}, +{ 5, s_0_52, 51, -1, 0}, +{ 3, s_0_53, 44, -1, 0}, +{ 4, s_0_54, 53, -1, 0}, +{ 2, s_0_55, 44, -1, 0}, +{ 3, s_0_56, 55, -1, 0}, +{ 4, s_0_57, 56, -1, 0}, +{ 3, s_0_58, 55, -1, 0}, +{ 4, s_0_59, 58, -1, 0}, +{ 5, s_0_60, 59, -1, 0}, +{ 3, s_0_61, 55, -1, 0}, +{ 4, s_0_62, 61, -1, 0}, +{ 4, s_0_63, 61, -1, 0}, +{ 7, s_0_64, 63, -1, 0}, +{ 4, s_0_65, 61, -1, 0}, +{ 3, s_0_66, 55, -1, 0}, +{ 6, s_0_67, 66, -1, 0}, +{ 4, s_0_68, 66, -1, 0}, +{ 5, s_0_69, 68, -1, 0}, +{ 6, s_0_70, 69, -1, 0}, +{ 3, s_0_71, 55, -1, 0}, +{ 4, s_0_72, 71, -1, 0}, +{ 7, s_0_73, 72, -1, 0}, +{ 4, s_0_74, 55, -1, 0}, +{ 4, s_0_75, 55, -1, 0}, +{ 4, s_0_76, 55, -1, 0}, +{ 5, s_0_77, 76, -1, 0}, +{ 2, s_0_78, 44, -1, 0}, +{ 4, s_0_79, 78, -1, 0}, +{ 4, s_0_80, 78, -1, 0}, +{ 3, s_0_81, 78, -1, 0}, +{ 4, s_0_82, 81, -1, 0}, +{ 4, s_0_83, 81, -1, 0}, +{ 5, s_0_84, 83, -1, 0}, +{ 4, s_0_85, 78, -1, 0}, +{ 5, s_0_86, 85, -1, 0}, +{ 3, s_0_87, 78, -1, 0}, +{ 4, s_0_88, 78, -1, 0}, +{ 7, s_0_89, 88, -1, 0}, +{ 6, s_0_90, 88, -1, 0}, +{ 7, s_0_91, 88, -1, 0}, +{ 2, s_0_92, 44, -1, 0}, +{ 3, s_0_93, 92, -1, 0}, +{ 5, s_0_94, 93, -1, 0}, +{ 2, s_0_95, -1, -1, 0}, +{ 3, s_0_96, -1, -1, 0}, +{ 1, s_0_97, -1, -1, 0}, +{ 2, s_0_98, -1, -1, 0}, +{ 3, s_0_99, 98, -1, 0}, +{ 3, s_0_100, -1, -1, 0}, +{ 2, s_0_101, -1, -1, 0}, +{ 3, s_0_102, 101, -1, 0}, +{ 2, s_0_103, -1, -1, 0}, +{ 3, s_0_104, -1, -1, 0}, +{ 3, s_0_105, -1, -1, 0}, +{ 6, s_0_106, 105, -1, 0}, +{ 2, s_0_107, -1, -1, 0}, +{ 2, s_0_108, -1, -1, 0}, +{ 3, s_0_109, 108, -1, 0}, +{ 2, s_0_110, -1, -1, 0}, +{ 3, s_0_111, 110, -1, 0}, +{ 3, s_0_112, -1, -1, 0}, +{ 1, s_0_113, -1, -1, 0}, +{ 2, s_0_114, 113, -1, 0}, +{ 4, s_0_115, 114, -1, 0}, +{ 4, s_0_116, 113, -1, 0}, +{ 2, s_0_117, 113, -1, 0}, +{ 1, s_0_118, -1, -1, 0}, +{ 2, s_0_119, 118, -1, 0}, +{ 3, s_0_120, 119, -1, 0}, +{ 2, s_0_121, 118, -1, 0}, +{ 3, s_0_122, 121, -1, 0}, +{ 2, s_0_123, 118, -1, 0}, +{ 3, s_0_124, 123, -1, 0}, +{ 4, s_0_125, 124, -1, 0}, +{ 6, s_0_126, 123, -1, 0}, +{ 4, s_0_127, 123, -1, 0}, +{ 6, s_0_128, 127, -1, 0}, +{ 4, s_0_129, 123, -1, 0}, +{ 5, s_0_130, 129, -1, 0}, +{ 4, s_0_131, 123, -1, 0}, +{ 5, s_0_132, 123, -1, 0}, +{ 4, s_0_133, 123, -1, 0}, +{ 4, s_0_134, 123, -1, 0}, +{ 4, s_0_135, 123, -1, 0}, +{ 3, s_0_136, 118, -1, 0}, +{ 4, s_0_137, 136, -1, 0}, +{ 4, s_0_138, 118, -1, 0}, +{ 3, s_0_139, 118, -1, 0}, +{ 5, s_0_140, 139, -1, 0}, +{ 5, s_0_141, 139, -1, 0}, +{ 3, s_0_142, 118, -1, 0}, +{ 4, s_0_143, 142, -1, 0}, +{ 3, s_0_144, 118, -1, 0}, +{ 4, s_0_145, 118, -1, 0}, +{ 3, s_0_146, 118, -1, 0}, +{ 2, s_0_147, 118, -1, 0}, +{ 3, s_0_148, 147, -1, 0}, +{ 3, s_0_149, 147, -1, 0}, +{ 4, s_0_150, 149, -1, 0}, +{ 3, s_0_151, 118, -1, 0}, +{ 2, s_0_152, 118, -1, 0}, +{ 3, s_0_153, 152, -1, 0}, +{ 4, s_0_154, 153, -1, 0}, +{ 3, s_0_155, 152, -1, 0}, +{ 2, s_0_156, 118, -1, 0}, +{ 4, s_0_157, 156, -1, 0}, +{ 4, s_0_158, 156, -1, 0}, +{ 3, s_0_159, 118, -1, 0}, +{ 4, s_0_160, 159, -1, 0}, +{ 3, s_0_161, 118, -1, 0}, +{ 5, s_0_162, 161, -1, 0}, +{ 6, s_0_163, 162, -1, 0}, +{ 5, s_0_164, 161, -1, 0}, +{ 6, s_0_165, 164, -1, 0}, +{ 6, s_0_166, 164, -1, 0}, +{ 5, s_0_167, 161, -1, 0}, +{ 6, s_0_168, 161, -1, 0}, +{ 9, s_0_169, 168, -1, 0}, +{ 5, s_0_170, 161, -1, 0}, +{ 6, s_0_171, 170, -1, 0}, +{ 6, s_0_172, 161, -1, 0}, +{ 5, s_0_173, 161, -1, 0}, +{ 6, s_0_174, 161, -1, 0}, +{ 9, s_0_175, 174, -1, 0}, +{ 3, s_0_176, 118, -1, 0}, +{ 3, s_0_177, 118, -1, 0}, +{ 4, s_0_178, 118, -1, 0}, +{ 2, s_0_179, -1, -1, 0}, +{ 3, s_0_180, 179, -1, 0}, +{ 2, s_0_181, -1, -1, 0}, +{ 3, s_0_182, 181, -1, 0}, +{ 2, s_0_183, -1, -1, 0}, +{ 3, s_0_184, -1, -1, 0}, +{ 6, s_0_185, 184, -1, 0}, +{ 1, s_0_186, -1, -1, 0}, +{ 2, s_0_187, 186, -1, 0}, +{ 3, s_0_188, 187, -1, 0}, +{ 5, s_0_189, 188, -1, 0}, +{ 2, s_0_190, 186, -1, 0}, +{ 4, s_0_191, 190, -1, 0}, +{ 3, s_0_192, 190, -1, 0}, +{ 1, s_0_193, -1, -1, 0}, +{ 2, s_0_194, -1, -1, 0}, +{ 3, s_0_195, 194, -1, 0}, +{ 2, s_0_196, -1, -1, 0}, +{ 2, s_0_197, -1, -1, 0}, +{ 2, s_0_198, -1, -1, 0}, +{ 4, s_0_199, 198, -1, 0}, +{ 4, s_0_200, 198, -1, 0}, +{ 2, s_0_201, -1, -1, 0}, +{ 3, s_0_202, 201, -1, 0}, +{ 4, s_0_203, 201, -1, 0} }; static const symbol s_1_0[3] = { 'i', 'n', 'g' }; @@ -505,68 +505,68 @@ static const symbol s_1_61[5] = { 0xC4, 0x97, 'j', 0xC4, 0x99 }; static const struct among a_1[62] = { -/* 0 */ { 3, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0}, -/* 2 */ { 3, s_1_2, 1, -1, 0}, -/* 3 */ { 3, s_1_3, -1, -1, 0}, -/* 4 */ { 2, s_1_4, -1, -1, 0}, -/* 5 */ { 3, s_1_5, 4, -1, 0}, -/* 6 */ { 3, s_1_6, 4, -1, 0}, -/* 7 */ { 4, s_1_7, 6, -1, 0}, -/* 8 */ { 3, s_1_8, -1, -1, 0}, -/* 9 */ { 3, s_1_9, -1, -1, 0}, -/* 10 */ { 4, s_1_10, 9, -1, 0}, -/* 11 */ { 3, s_1_11, -1, -1, 0}, -/* 12 */ { 3, s_1_12, -1, -1, 0}, -/* 13 */ { 4, s_1_13, 12, -1, 0}, -/* 14 */ { 2, s_1_14, -1, -1, 0}, -/* 15 */ { 3, s_1_15, 14, -1, 0}, -/* 16 */ { 3, s_1_16, -1, -1, 0}, -/* 17 */ { 5, s_1_17, 16, -1, 0}, -/* 18 */ { 6, s_1_18, 16, -1, 0}, -/* 19 */ { 4, s_1_19, -1, -1, 0}, -/* 20 */ { 3, s_1_20, -1, -1, 0}, -/* 21 */ { 2, s_1_21, -1, -1, 0}, -/* 22 */ { 3, s_1_22, -1, -1, 0}, -/* 23 */ { 2, s_1_23, -1, -1, 0}, -/* 24 */ { 3, s_1_24, 23, -1, 0}, -/* 25 */ { 3, s_1_25, 23, -1, 0}, -/* 26 */ { 4, s_1_26, -1, -1, 0}, -/* 27 */ { 3, s_1_27, -1, -1, 0}, -/* 28 */ { 3, s_1_28, -1, -1, 0}, -/* 29 */ { 2, s_1_29, -1, -1, 0}, -/* 30 */ { 3, s_1_30, 29, -1, 0}, -/* 31 */ { 3, s_1_31, -1, -1, 0}, -/* 32 */ { 3, s_1_32, -1, -1, 0}, -/* 33 */ { 3, s_1_33, -1, -1, 0}, -/* 34 */ { 4, s_1_34, 33, -1, 0}, -/* 35 */ { 2, s_1_35, -1, -1, 0}, -/* 36 */ { 3, s_1_36, 35, -1, 0}, -/* 37 */ { 3, s_1_37, 35, -1, 0}, -/* 38 */ { 4, s_1_38, 37, -1, 0}, -/* 39 */ { 3, s_1_39, -1, -1, 0}, -/* 40 */ { 4, s_1_40, 39, -1, 0}, -/* 41 */ { 3, s_1_41, -1, -1, 0}, -/* 42 */ { 4, s_1_42, 41, -1, 0}, -/* 43 */ { 3, s_1_43, -1, -1, 0}, -/* 44 */ { 7, s_1_44, -1, -1, 0}, -/* 45 */ { 3, s_1_45, -1, -1, 0}, -/* 46 */ { 4, s_1_46, 45, -1, 0}, -/* 47 */ { 5, s_1_47, 46, -1, 0}, -/* 48 */ { 3, s_1_48, -1, -1, 0}, -/* 49 */ { 2, s_1_49, -1, -1, 0}, -/* 50 */ { 3, s_1_50, 49, -1, 0}, -/* 51 */ { 4, s_1_51, 50, -1, 0}, -/* 52 */ { 2, s_1_52, -1, -1, 0}, -/* 53 */ { 3, s_1_53, -1, -1, 0}, -/* 54 */ { 5, s_1_54, -1, -1, 0}, -/* 55 */ { 3, s_1_55, -1, -1, 0}, -/* 56 */ { 3, s_1_56, -1, -1, 0}, -/* 57 */ { 2, s_1_57, -1, -1, 0}, -/* 58 */ { 3, s_1_58, -1, -1, 0}, -/* 59 */ { 6, s_1_59, -1, -1, 0}, -/* 60 */ { 2, s_1_60, -1, -1, 0}, -/* 61 */ { 5, s_1_61, 60, -1, 0} +{ 3, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0}, +{ 3, s_1_2, 1, -1, 0}, +{ 3, s_1_3, -1, -1, 0}, +{ 2, s_1_4, -1, -1, 0}, +{ 3, s_1_5, 4, -1, 0}, +{ 3, s_1_6, 4, -1, 0}, +{ 4, s_1_7, 6, -1, 0}, +{ 3, s_1_8, -1, -1, 0}, +{ 3, s_1_9, -1, -1, 0}, +{ 4, s_1_10, 9, -1, 0}, +{ 3, s_1_11, -1, -1, 0}, +{ 3, s_1_12, -1, -1, 0}, +{ 4, s_1_13, 12, -1, 0}, +{ 2, s_1_14, -1, -1, 0}, +{ 3, s_1_15, 14, -1, 0}, +{ 3, s_1_16, -1, -1, 0}, +{ 5, s_1_17, 16, -1, 0}, +{ 6, s_1_18, 16, -1, 0}, +{ 4, s_1_19, -1, -1, 0}, +{ 3, s_1_20, -1, -1, 0}, +{ 2, s_1_21, -1, -1, 0}, +{ 3, s_1_22, -1, -1, 0}, +{ 2, s_1_23, -1, -1, 0}, +{ 3, s_1_24, 23, -1, 0}, +{ 3, s_1_25, 23, -1, 0}, +{ 4, s_1_26, -1, -1, 0}, +{ 3, s_1_27, -1, -1, 0}, +{ 3, s_1_28, -1, -1, 0}, +{ 2, s_1_29, -1, -1, 0}, +{ 3, s_1_30, 29, -1, 0}, +{ 3, s_1_31, -1, -1, 0}, +{ 3, s_1_32, -1, -1, 0}, +{ 3, s_1_33, -1, -1, 0}, +{ 4, s_1_34, 33, -1, 0}, +{ 2, s_1_35, -1, -1, 0}, +{ 3, s_1_36, 35, -1, 0}, +{ 3, s_1_37, 35, -1, 0}, +{ 4, s_1_38, 37, -1, 0}, +{ 3, s_1_39, -1, -1, 0}, +{ 4, s_1_40, 39, -1, 0}, +{ 3, s_1_41, -1, -1, 0}, +{ 4, s_1_42, 41, -1, 0}, +{ 3, s_1_43, -1, -1, 0}, +{ 7, s_1_44, -1, -1, 0}, +{ 3, s_1_45, -1, -1, 0}, +{ 4, s_1_46, 45, -1, 0}, +{ 5, s_1_47, 46, -1, 0}, +{ 3, s_1_48, -1, -1, 0}, +{ 2, s_1_49, -1, -1, 0}, +{ 3, s_1_50, 49, -1, 0}, +{ 4, s_1_51, 50, -1, 0}, +{ 2, s_1_52, -1, -1, 0}, +{ 3, s_1_53, -1, -1, 0}, +{ 5, s_1_54, -1, -1, 0}, +{ 3, s_1_55, -1, -1, 0}, +{ 3, s_1_56, -1, -1, 0}, +{ 2, s_1_57, -1, -1, 0}, +{ 3, s_1_58, -1, -1, 0}, +{ 6, s_1_59, -1, -1, 0}, +{ 2, s_1_60, -1, -1, 0}, +{ 5, s_1_61, 60, -1, 0} }; static const symbol s_2_0[5] = { 'o', 'j', 'i', 'm', 'e' }; @@ -583,17 +583,17 @@ static const symbol s_2_10[4] = { 'e', 's', 'i', 'u' }; static const struct among a_2[11] = { -/* 0 */ { 5, s_2_0, -1, 7, 0}, -/* 1 */ { 6, s_2_1, -1, 3, 0}, -/* 2 */ { 5, s_2_2, -1, 6, 0}, -/* 3 */ { 5, s_2_3, -1, 8, 0}, -/* 4 */ { 4, s_2_4, -1, 1, 0}, -/* 5 */ { 4, s_2_5, -1, 2, 0}, -/* 6 */ { 5, s_2_6, -1, 5, 0}, -/* 7 */ { 7, s_2_7, -1, 8, 0}, -/* 8 */ { 6, s_2_8, -1, 1, 0}, -/* 9 */ { 6, s_2_9, -1, 2, 0}, -/* 10 */ { 4, s_2_10, -1, 4, 0} +{ 5, s_2_0, -1, 7, 0}, +{ 6, s_2_1, -1, 3, 0}, +{ 5, s_2_2, -1, 6, 0}, +{ 5, s_2_3, -1, 8, 0}, +{ 4, s_2_4, -1, 1, 0}, +{ 4, s_2_5, -1, 2, 0}, +{ 5, s_2_6, -1, 5, 0}, +{ 7, s_2_7, -1, 8, 0}, +{ 6, s_2_8, -1, 1, 0}, +{ 6, s_2_9, -1, 2, 0}, +{ 4, s_2_10, -1, 4, 0} }; static const symbol s_3_0[2] = { 0xC4, 0x8D }; @@ -601,15 +601,15 @@ static const symbol s_3_1[3] = { 'd', 0xC5, 0xBE }; static const struct among a_3[2] = { -/* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 3, s_3_1, -1, 2, 0} +{ 2, s_3_0, -1, 1, 0}, +{ 3, s_3_1, -1, 2, 0} }; static const symbol s_4_0[2] = { 'g', 'd' }; static const struct among a_4[1] = { -/* 0 */ { 2, s_4_0, -1, 1, 0} +{ 2, s_4_0, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 64, 1, 0, 64, 0, 0, 0, 0, 0, 0, 0, 4, 4 }; @@ -626,44 +626,43 @@ static const symbol s_8[] = { 't' }; static const symbol s_9[] = { 'd' }; static const symbol s_10[] = { 'g' }; -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 43 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_step1(struct SN_env * z) { /* backwardmode */ +static int r_step1(struct SN_env * z) { - { int mlimit1; /* setlimit, line 45 */ + { int mlimit1; if (z->c < z->I[0]) return 0; mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 45 */ - if (!(find_among_b(z, a_0, 204))) { z->lb = mlimit1; return 0; } /* substring, line 45 */ - z->bra = z->c; /* ], line 45 */ + z->ket = z->c; + if (!(find_among_b(z, a_0, 204))) { z->lb = mlimit1; return 0; } + z->bra = z->c; z->lb = mlimit1; } - { int ret = r_R1(z); /* call R1, line 45 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 229 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_step2(struct SN_env * z) { /* backwardmode */ -/* repeat, line 232 */ +static int r_step2(struct SN_env * z) { + while(1) { + int m1 = z->l - z->c; (void)m1; - while(1) { int m1 = z->l - z->c; (void)m1; - - { int mlimit2; /* setlimit, line 233 */ + { int mlimit2; if (z->c < z->I[0]) goto lab0; mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 233 */ - if (!(find_among_b(z, a_1, 62))) { z->lb = mlimit2; goto lab0; } /* substring, line 233 */ - z->bra = z->c; /* ], line 233 */ + z->ket = z->c; + if (!(find_among_b(z, a_1, 62))) { z->lb = mlimit2; goto lab0; } + z->bra = z->c; z->lb = mlimit2; } - { int ret = slice_del(z); /* delete, line 303 */ + { int ret = slice_del(z); if (ret < 0) return ret; } continue; @@ -674,51 +673,51 @@ static int r_step2(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_fix_conflicts(struct SN_env * z) { /* backwardmode */ +static int r_fix_conflicts(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 307 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2621472 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 307 */ + z->ket = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2621472 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_2, 11); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 307 */ - switch (among_var) { /* among, line 307 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 5, s_0); /* <-, line 309 */ + { int ret = slice_from_s(z, 5, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 5, s_1); /* <-, line 314 */ + { int ret = slice_from_s(z, 5, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 7, s_2); /* <-, line 319 */ + { int ret = slice_from_s(z, 7, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_3); /* <-, line 322 */ + { int ret = slice_from_s(z, 4, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 4, s_4); /* <-, line 324 */ + { int ret = slice_from_s(z, 4, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 6, s_5); /* <-, line 327 */ + { int ret = slice_from_s(z, 6, s_5); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 6, s_6); /* <-, line 328 */ + { int ret = slice_from_s(z, 6, s_6); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 6, s_7); /* <-, line 331 */ + { int ret = slice_from_s(z, 6, s_7); if (ret < 0) return ret; } break; @@ -726,21 +725,21 @@ static int r_fix_conflicts(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_fix_chdz(struct SN_env * z) { /* backwardmode */ +static int r_fix_chdz(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 338 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 190)) return 0; /* substring, line 338 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 190)) return 0; among_var = find_among_b(z, a_3, 2); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 338 */ - switch (among_var) { /* among, line 338 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 339 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 340 */ + { int ret = slice_from_s(z, 1, s_9); if (ret < 0) return ret; } break; @@ -748,82 +747,82 @@ static int r_fix_chdz(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_fix_gd(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 345 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 100) return 0; /* substring, line 345 */ +static int r_fix_gd(struct SN_env * z) { + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 100) return 0; if (!(find_among_b(z, a_4, 1))) return 0; - z->bra = z->c; /* ], line 345 */ - { int ret = slice_from_s(z, 1, s_10); /* <-, line 346 */ + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } return 1; } -extern int lithuanian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 355 */ - { int c1 = z->c; /* do, line 357 */ - { int c2 = z->c; /* try, line 359 */ - { int c_test3 = z->c; /* test, line 359 */ - if (z->c == z->l || z->p[z->c] != 'a') { z->c = c2; goto lab1; } /* literal, line 359 */ +extern int lithuanian_UTF_8_stem(struct SN_env * z) { + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + { int c_test3 = z->c; + if (z->c == z->l || z->p[z->c] != 'a') { z->c = c2; goto lab1; } z->c++; z->c = c_test3; } - if (!(len_utf8(z->p) > 6)) { z->c = c2; goto lab1; } /* $( > ), line 359 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 1); /* hop, line 359 */ + if (!(len_utf8(z->p) > 6)) { z->c = c2; goto lab1; } + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) { z->c = c2; goto lab1; } z->c = ret; } lab1: ; } - { /* gopast */ /* grouping v, line 361 */ + { int ret = out_grouping_U(z, g_v, 97, 371, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 361 */ + { int ret = in_grouping_U(z, g_v, 97, 371, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 361 */ + z->I[0] = z->c; lab0: z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 364 */ + z->lb = z->c; z->c = z->l; - { int m4 = z->l - z->c; (void)m4; /* do, line 365 */ - { int ret = r_fix_conflicts(z); /* call fix_conflicts, line 365 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_fix_conflicts(z); if (ret < 0) return ret; } z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 366 */ - { int ret = r_step1(z); /* call step1, line 366 */ + { int m5 = z->l - z->c; (void)m5; + { int ret = r_step1(z); if (ret < 0) return ret; } z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* do, line 367 */ - { int ret = r_fix_chdz(z); /* call fix_chdz, line 367 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_fix_chdz(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 368 */ - { int ret = r_step2(z); /* call step2, line 368 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_step2(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 369 */ - { int ret = r_fix_chdz(z); /* call fix_chdz, line 369 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_fix_chdz(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 370 */ - { int ret = r_fix_gd(z); /* call fix_gd, line 370 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_fix_gd(z); if (ret < 0) return ret; } z->c = z->l - m9; @@ -832,7 +831,7 @@ extern int lithuanian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * lithuanian_UTF_8_create_env(void) { return SN_create_env(0, 1, 0); } +extern struct SN_env * lithuanian_UTF_8_create_env(void) { return SN_create_env(0, 1); } extern void lithuanian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_nepali.c b/src/backend/snowball/libstemmer/stem_UTF_8_nepali.c index 7927e66803e5..0c9ff0830fbf 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_nepali.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_nepali.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -45,23 +45,23 @@ static const symbol s_0_16[9] = { 0xE0, 0xA4, 0xAA, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4 static const struct among a_0[17] = { -/* 0 */ { 6, s_0_0, -1, 2, 0}, -/* 1 */ { 9, s_0_1, -1, 1, 0}, -/* 2 */ { 6, s_0_2, -1, 1, 0}, -/* 3 */ { 9, s_0_3, -1, 1, 0}, -/* 4 */ { 6, s_0_4, -1, 2, 0}, -/* 5 */ { 12, s_0_5, -1, 1, 0}, -/* 6 */ { 6, s_0_6, -1, 1, 0}, -/* 7 */ { 6, s_0_7, -1, 2, 0}, -/* 8 */ { 9, s_0_8, -1, 1, 0}, -/* 9 */ { 9, s_0_9, -1, 1, 0}, -/* 10 */ { 18, s_0_10, -1, 1, 0}, -/* 11 */ { 6, s_0_11, -1, 1, 0}, -/* 12 */ { 6, s_0_12, -1, 2, 0}, -/* 13 */ { 6, s_0_13, -1, 1, 0}, -/* 14 */ { 18, s_0_14, -1, 1, 0}, -/* 15 */ { 6, s_0_15, -1, 2, 0}, -/* 16 */ { 9, s_0_16, -1, 1, 0} +{ 6, s_0_0, -1, 2, 0}, +{ 9, s_0_1, -1, 1, 0}, +{ 6, s_0_2, -1, 1, 0}, +{ 9, s_0_3, -1, 1, 0}, +{ 6, s_0_4, -1, 2, 0}, +{ 12, s_0_5, -1, 1, 0}, +{ 6, s_0_6, -1, 1, 0}, +{ 6, s_0_7, -1, 2, 0}, +{ 9, s_0_8, -1, 1, 0}, +{ 9, s_0_9, -1, 1, 0}, +{ 18, s_0_10, -1, 1, 0}, +{ 6, s_0_11, -1, 1, 0}, +{ 6, s_0_12, -1, 2, 0}, +{ 6, s_0_13, -1, 1, 0}, +{ 18, s_0_14, -1, 1, 0}, +{ 6, s_0_15, -1, 2, 0}, +{ 9, s_0_16, -1, 1, 0} }; static const symbol s_1_0[3] = { 0xE0, 0xA4, 0x81 }; @@ -70,9 +70,9 @@ static const symbol s_1_2[3] = { 0xE0, 0xA5, 0x88 }; static const struct among a_1[3] = { -/* 0 */ { 3, s_1_0, -1, -1, 0}, -/* 1 */ { 3, s_1_1, -1, -1, 0}, -/* 2 */ { 3, s_1_2, -1, -1, 0} +{ 3, s_1_0, -1, -1, 0}, +{ 3, s_1_1, -1, -1, 0}, +{ 3, s_1_2, -1, -1, 0} }; static const symbol s_2_0[3] = { 0xE0, 0xA4, 0x81 }; @@ -81,9 +81,9 @@ static const symbol s_2_2[3] = { 0xE0, 0xA5, 0x88 }; static const struct among a_2[3] = { -/* 0 */ { 3, s_2_0, -1, 1, 0}, -/* 1 */ { 3, s_2_1, -1, 1, 0}, -/* 2 */ { 3, s_2_2, -1, 2, 0} +{ 3, s_2_0, -1, 1, 0}, +{ 3, s_2_1, -1, 1, 0}, +{ 3, s_2_2, -1, 2, 0} }; static const symbol s_3_0[9] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x80 }; @@ -180,97 +180,97 @@ static const symbol s_3_90[12] = { 0xE0, 0xA4, 0xAE, 0xE0, 0xA4, 0xBE, 0xE0, 0xA static const struct among a_3[91] = { -/* 0 */ { 9, s_3_0, -1, 1, 0}, -/* 1 */ { 9, s_3_1, -1, 1, 0}, -/* 2 */ { 12, s_3_2, 1, 1, 0}, -/* 3 */ { 12, s_3_3, 1, 1, 0}, -/* 4 */ { 12, s_3_4, -1, 1, 0}, -/* 5 */ { 6, s_3_5, -1, 1, 0}, -/* 6 */ { 6, s_3_6, -1, 1, 0}, -/* 7 */ { 6, s_3_7, -1, 1, 0}, -/* 8 */ { 9, s_3_8, 7, 1, 0}, -/* 9 */ { 12, s_3_9, 8, 1, 0}, -/* 10 */ { 9, s_3_10, 7, 1, 0}, -/* 11 */ { 6, s_3_11, -1, 1, 0}, -/* 12 */ { 9, s_3_12, -1, 1, 0}, -/* 13 */ { 9, s_3_13, -1, 1, 0}, -/* 14 */ { 6, s_3_14, -1, 1, 0}, -/* 15 */ { 6, s_3_15, -1, 1, 0}, -/* 16 */ { 6, s_3_16, -1, 1, 0}, -/* 17 */ { 9, s_3_17, -1, 1, 0}, -/* 18 */ { 12, s_3_18, 17, 1, 0}, -/* 19 */ { 9, s_3_19, -1, 1, 0}, -/* 20 */ { 6, s_3_20, -1, 1, 0}, -/* 21 */ { 9, s_3_21, 20, 1, 0}, -/* 22 */ { 9, s_3_22, 20, 1, 0}, -/* 23 */ { 9, s_3_23, -1, 1, 0}, -/* 24 */ { 12, s_3_24, 23, 1, 0}, -/* 25 */ { 9, s_3_25, -1, 1, 0}, -/* 26 */ { 12, s_3_26, 25, 1, 0}, -/* 27 */ { 12, s_3_27, 25, 1, 0}, -/* 28 */ { 6, s_3_28, -1, 1, 0}, -/* 29 */ { 9, s_3_29, 28, 1, 0}, -/* 30 */ { 9, s_3_30, 28, 1, 0}, -/* 31 */ { 6, s_3_31, -1, 1, 0}, -/* 32 */ { 9, s_3_32, 31, 1, 0}, -/* 33 */ { 12, s_3_33, 31, 1, 0}, -/* 34 */ { 9, s_3_34, 31, 1, 0}, -/* 35 */ { 9, s_3_35, 31, 1, 0}, -/* 36 */ { 12, s_3_36, 35, 1, 0}, -/* 37 */ { 12, s_3_37, 35, 1, 0}, -/* 38 */ { 6, s_3_38, -1, 1, 0}, -/* 39 */ { 9, s_3_39, 38, 1, 0}, -/* 40 */ { 9, s_3_40, 38, 1, 0}, -/* 41 */ { 12, s_3_41, 40, 1, 0}, -/* 42 */ { 9, s_3_42, 38, 1, 0}, -/* 43 */ { 9, s_3_43, 38, 1, 0}, -/* 44 */ { 6, s_3_44, -1, 1, 0}, -/* 45 */ { 12, s_3_45, 44, 1, 0}, -/* 46 */ { 12, s_3_46, 44, 1, 0}, -/* 47 */ { 12, s_3_47, 44, 1, 0}, -/* 48 */ { 9, s_3_48, -1, 1, 0}, -/* 49 */ { 12, s_3_49, 48, 1, 0}, -/* 50 */ { 12, s_3_50, 48, 1, 0}, -/* 51 */ { 15, s_3_51, 50, 1, 0}, -/* 52 */ { 12, s_3_52, 48, 1, 0}, -/* 53 */ { 12, s_3_53, 48, 1, 0}, -/* 54 */ { 12, s_3_54, -1, 1, 0}, -/* 55 */ { 12, s_3_55, -1, 1, 0}, -/* 56 */ { 12, s_3_56, -1, 1, 0}, -/* 57 */ { 9, s_3_57, -1, 1, 0}, -/* 58 */ { 9, s_3_58, -1, 1, 0}, -/* 59 */ { 15, s_3_59, 58, 1, 0}, -/* 60 */ { 12, s_3_60, -1, 1, 0}, -/* 61 */ { 12, s_3_61, -1, 1, 0}, -/* 62 */ { 9, s_3_62, -1, 1, 0}, -/* 63 */ { 12, s_3_63, 62, 1, 0}, -/* 64 */ { 12, s_3_64, 62, 1, 0}, -/* 65 */ { 15, s_3_65, 64, 1, 0}, -/* 66 */ { 12, s_3_66, 62, 1, 0}, -/* 67 */ { 12, s_3_67, 62, 1, 0}, -/* 68 */ { 9, s_3_68, -1, 1, 0}, -/* 69 */ { 12, s_3_69, 68, 1, 0}, -/* 70 */ { 9, s_3_70, -1, 1, 0}, -/* 71 */ { 3, s_3_71, -1, 1, 0}, -/* 72 */ { 6, s_3_72, 71, 1, 0}, -/* 73 */ { 6, s_3_73, 71, 1, 0}, -/* 74 */ { 9, s_3_74, 73, 1, 0}, -/* 75 */ { 15, s_3_75, 74, 1, 0}, -/* 76 */ { 15, s_3_76, 71, 1, 0}, -/* 77 */ { 12, s_3_77, 71, 1, 0}, -/* 78 */ { 12, s_3_78, 71, 1, 0}, -/* 79 */ { 6, s_3_79, 71, 1, 0}, -/* 80 */ { 6, s_3_80, 71, 1, 0}, -/* 81 */ { 9, s_3_81, -1, 1, 0}, -/* 82 */ { 12, s_3_82, 81, 1, 0}, -/* 83 */ { 9, s_3_83, -1, 1, 0}, -/* 84 */ { 12, s_3_84, 83, 1, 0}, -/* 85 */ { 12, s_3_85, 83, 1, 0}, -/* 86 */ { 6, s_3_86, -1, 1, 0}, -/* 87 */ { 9, s_3_87, 86, 1, 0}, -/* 88 */ { 9, s_3_88, 86, 1, 0}, -/* 89 */ { 12, s_3_89, -1, 1, 0}, -/* 90 */ { 12, s_3_90, -1, 1, 0} +{ 9, s_3_0, -1, 1, 0}, +{ 9, s_3_1, -1, 1, 0}, +{ 12, s_3_2, 1, 1, 0}, +{ 12, s_3_3, 1, 1, 0}, +{ 12, s_3_4, -1, 1, 0}, +{ 6, s_3_5, -1, 1, 0}, +{ 6, s_3_6, -1, 1, 0}, +{ 6, s_3_7, -1, 1, 0}, +{ 9, s_3_8, 7, 1, 0}, +{ 12, s_3_9, 8, 1, 0}, +{ 9, s_3_10, 7, 1, 0}, +{ 6, s_3_11, -1, 1, 0}, +{ 9, s_3_12, -1, 1, 0}, +{ 9, s_3_13, -1, 1, 0}, +{ 6, s_3_14, -1, 1, 0}, +{ 6, s_3_15, -1, 1, 0}, +{ 6, s_3_16, -1, 1, 0}, +{ 9, s_3_17, -1, 1, 0}, +{ 12, s_3_18, 17, 1, 0}, +{ 9, s_3_19, -1, 1, 0}, +{ 6, s_3_20, -1, 1, 0}, +{ 9, s_3_21, 20, 1, 0}, +{ 9, s_3_22, 20, 1, 0}, +{ 9, s_3_23, -1, 1, 0}, +{ 12, s_3_24, 23, 1, 0}, +{ 9, s_3_25, -1, 1, 0}, +{ 12, s_3_26, 25, 1, 0}, +{ 12, s_3_27, 25, 1, 0}, +{ 6, s_3_28, -1, 1, 0}, +{ 9, s_3_29, 28, 1, 0}, +{ 9, s_3_30, 28, 1, 0}, +{ 6, s_3_31, -1, 1, 0}, +{ 9, s_3_32, 31, 1, 0}, +{ 12, s_3_33, 31, 1, 0}, +{ 9, s_3_34, 31, 1, 0}, +{ 9, s_3_35, 31, 1, 0}, +{ 12, s_3_36, 35, 1, 0}, +{ 12, s_3_37, 35, 1, 0}, +{ 6, s_3_38, -1, 1, 0}, +{ 9, s_3_39, 38, 1, 0}, +{ 9, s_3_40, 38, 1, 0}, +{ 12, s_3_41, 40, 1, 0}, +{ 9, s_3_42, 38, 1, 0}, +{ 9, s_3_43, 38, 1, 0}, +{ 6, s_3_44, -1, 1, 0}, +{ 12, s_3_45, 44, 1, 0}, +{ 12, s_3_46, 44, 1, 0}, +{ 12, s_3_47, 44, 1, 0}, +{ 9, s_3_48, -1, 1, 0}, +{ 12, s_3_49, 48, 1, 0}, +{ 12, s_3_50, 48, 1, 0}, +{ 15, s_3_51, 50, 1, 0}, +{ 12, s_3_52, 48, 1, 0}, +{ 12, s_3_53, 48, 1, 0}, +{ 12, s_3_54, -1, 1, 0}, +{ 12, s_3_55, -1, 1, 0}, +{ 12, s_3_56, -1, 1, 0}, +{ 9, s_3_57, -1, 1, 0}, +{ 9, s_3_58, -1, 1, 0}, +{ 15, s_3_59, 58, 1, 0}, +{ 12, s_3_60, -1, 1, 0}, +{ 12, s_3_61, -1, 1, 0}, +{ 9, s_3_62, -1, 1, 0}, +{ 12, s_3_63, 62, 1, 0}, +{ 12, s_3_64, 62, 1, 0}, +{ 15, s_3_65, 64, 1, 0}, +{ 12, s_3_66, 62, 1, 0}, +{ 12, s_3_67, 62, 1, 0}, +{ 9, s_3_68, -1, 1, 0}, +{ 12, s_3_69, 68, 1, 0}, +{ 9, s_3_70, -1, 1, 0}, +{ 3, s_3_71, -1, 1, 0}, +{ 6, s_3_72, 71, 1, 0}, +{ 6, s_3_73, 71, 1, 0}, +{ 9, s_3_74, 73, 1, 0}, +{ 15, s_3_75, 74, 1, 0}, +{ 15, s_3_76, 71, 1, 0}, +{ 12, s_3_77, 71, 1, 0}, +{ 12, s_3_78, 71, 1, 0}, +{ 6, s_3_79, 71, 1, 0}, +{ 6, s_3_80, 71, 1, 0}, +{ 9, s_3_81, -1, 1, 0}, +{ 12, s_3_82, 81, 1, 0}, +{ 9, s_3_83, -1, 1, 0}, +{ 12, s_3_84, 83, 1, 0}, +{ 12, s_3_85, 83, 1, 0}, +{ 6, s_3_86, -1, 1, 0}, +{ 9, s_3_87, 86, 1, 0}, +{ 9, s_3_88, 86, 1, 0}, +{ 12, s_3_89, -1, 1, 0}, +{ 12, s_3_90, -1, 1, 0} }; static const symbol s_0[] = { 0xE0, 0xA4, 0x8F }; @@ -281,32 +281,32 @@ static const symbol s_4[] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8C }; static const symbol s_5[] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA5, 0x87 }; static const symbol s_6[] = { 0xE0, 0xA4, 0xA4, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0xB0 }; -static int r_remove_category_1(struct SN_env * z) { /* backwardmode */ +static int r_remove_category_1(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 54 */ - among_var = find_among_b(z, a_0, 17); /* substring, line 54 */ + z->ket = z->c; + among_var = find_among_b(z, a_0, 17); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 54 */ - switch (among_var) { /* among, line 54 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 58 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m1 = z->l - z->c; (void)m1; /* or, line 59 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 59 */ - if (!(eq_s_b(z, 3, s_0))) goto lab3; /* literal, line 59 */ + { int m1 = z->l - z->c; (void)m1; + { int m2 = z->l - z->c; (void)m2; + if (!(eq_s_b(z, 3, s_0))) goto lab3; goto lab2; lab3: z->c = z->l - m2; - if (!(eq_s_b(z, 3, s_1))) goto lab1; /* literal, line 59 */ + if (!(eq_s_b(z, 3, s_1))) goto lab1; } lab2: goto lab0; lab1: z->c = z->l - m1; - { int ret = slice_del(z); /* delete, line 59 */ + { int ret = slice_del(z); if (ret < 0) return ret; } } @@ -316,46 +316,46 @@ static int r_remove_category_1(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_check_category_2(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 64 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((262 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 64 */ +static int r_check_category_2(struct SN_env * z) { + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((262 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_1, 3))) return 0; - z->bra = z->c; /* ], line 64 */ + z->bra = z->c; return 1; } -static int r_remove_category_2(struct SN_env * z) { /* backwardmode */ +static int r_remove_category_2(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 70 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((262 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 70 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((262 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_2, 3); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 70 */ - switch (among_var) { /* among, line 70 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 71 */ - if (!(eq_s_b(z, 6, s_2))) goto lab1; /* literal, line 71 */ + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 6, s_2))) goto lab1; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 6, s_3))) goto lab2; /* literal, line 71 */ + if (!(eq_s_b(z, 6, s_3))) goto lab2; goto lab0; lab2: z->c = z->l - m1; - if (!(eq_s_b(z, 6, s_4))) goto lab3; /* literal, line 71 */ + if (!(eq_s_b(z, 6, s_4))) goto lab3; goto lab0; lab3: z->c = z->l - m1; - if (!(eq_s_b(z, 6, s_5))) return 0; /* literal, line 71 */ + if (!(eq_s_b(z, 6, s_5))) return 0; } lab0: - { int ret = slice_del(z); /* delete, line 71 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(eq_s_b(z, 9, s_6))) return 0; /* literal, line 72 */ - { int ret = slice_del(z); /* delete, line 72 */ + if (!(eq_s_b(z, 9, s_6))) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -363,37 +363,36 @@ static int r_remove_category_2(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_remove_category_3(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 77 */ - if (!(find_among_b(z, a_3, 91))) return 0; /* substring, line 77 */ - z->bra = z->c; /* ], line 77 */ - { int ret = slice_del(z); /* delete, line 79 */ +static int r_remove_category_3(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_3, 91))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int nepali_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - z->lb = z->c; z->c = z->l; /* backwards, line 86 */ +extern int nepali_UTF_8_stem(struct SN_env * z) { + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 87 */ - { int ret = r_remove_category_1(z); /* call remove_category_1, line 87 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_remove_category_1(z); if (ret < 0) return ret; } z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 88 */ -/* repeat, line 89 */ - - while(1) { int m3 = z->l - z->c; (void)m3; - { int m4 = z->l - z->c; (void)m4; /* do, line 89 */ - { int m5 = z->l - z->c; (void)m5; /* and, line 89 */ - { int ret = r_check_category_2(z); /* call check_category_2, line 89 */ + { int m2 = z->l - z->c; (void)m2; + while(1) { + int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + { int ret = r_check_category_2(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } z->c = z->l - m5; - { int ret = r_remove_category_2(z); /* call remove_category_2, line 89 */ + { int ret = r_remove_category_2(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } @@ -401,7 +400,7 @@ extern int nepali_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab2: z->c = z->l - m4; } - { int ret = r_remove_category_3(z); /* call remove_category_3, line 89 */ + { int ret = r_remove_category_3(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } @@ -416,7 +415,7 @@ extern int nepali_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * nepali_UTF_8_create_env(void) { return SN_create_env(0, 0, 0); } +extern struct SN_env * nepali_UTF_8_create_env(void) { return SN_create_env(0, 0); } extern void nepali_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c b/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c index e333b1dfffe3..73c840878fb4 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -57,35 +57,35 @@ static const symbol s_0_28[3] = { 'a', 's', 't' }; static const struct among a_0[29] = { -/* 0 */ { 1, s_0_0, -1, 1, 0}, -/* 1 */ { 1, s_0_1, -1, 1, 0}, -/* 2 */ { 3, s_0_2, 1, 1, 0}, -/* 3 */ { 4, s_0_3, 1, 1, 0}, -/* 4 */ { 4, s_0_4, 1, 1, 0}, -/* 5 */ { 3, s_0_5, 1, 1, 0}, -/* 6 */ { 3, s_0_6, 1, 1, 0}, -/* 7 */ { 6, s_0_7, 6, 1, 0}, -/* 8 */ { 4, s_0_8, 1, 3, 0}, -/* 9 */ { 2, s_0_9, -1, 1, 0}, -/* 10 */ { 5, s_0_10, 9, 1, 0}, -/* 11 */ { 2, s_0_11, -1, 1, 0}, -/* 12 */ { 2, s_0_12, -1, 1, 0}, -/* 13 */ { 5, s_0_13, 12, 1, 0}, -/* 14 */ { 1, s_0_14, -1, 2, 0}, -/* 15 */ { 2, s_0_15, 14, 1, 0}, -/* 16 */ { 2, s_0_16, 14, 1, 0}, -/* 17 */ { 4, s_0_17, 16, 1, 0}, -/* 18 */ { 5, s_0_18, 16, 1, 0}, -/* 19 */ { 4, s_0_19, 16, 1, 0}, -/* 20 */ { 7, s_0_20, 19, 1, 0}, -/* 21 */ { 3, s_0_21, 14, 1, 0}, -/* 22 */ { 6, s_0_22, 21, 1, 0}, -/* 23 */ { 3, s_0_23, 14, 1, 0}, -/* 24 */ { 3, s_0_24, 14, 1, 0}, -/* 25 */ { 2, s_0_25, -1, 1, 0}, -/* 26 */ { 3, s_0_26, 25, 1, 0}, -/* 27 */ { 3, s_0_27, -1, 3, 0}, -/* 28 */ { 3, s_0_28, -1, 1, 0} +{ 1, s_0_0, -1, 1, 0}, +{ 1, s_0_1, -1, 1, 0}, +{ 3, s_0_2, 1, 1, 0}, +{ 4, s_0_3, 1, 1, 0}, +{ 4, s_0_4, 1, 1, 0}, +{ 3, s_0_5, 1, 1, 0}, +{ 3, s_0_6, 1, 1, 0}, +{ 6, s_0_7, 6, 1, 0}, +{ 4, s_0_8, 1, 3, 0}, +{ 2, s_0_9, -1, 1, 0}, +{ 5, s_0_10, 9, 1, 0}, +{ 2, s_0_11, -1, 1, 0}, +{ 2, s_0_12, -1, 1, 0}, +{ 5, s_0_13, 12, 1, 0}, +{ 1, s_0_14, -1, 2, 0}, +{ 2, s_0_15, 14, 1, 0}, +{ 2, s_0_16, 14, 1, 0}, +{ 4, s_0_17, 16, 1, 0}, +{ 5, s_0_18, 16, 1, 0}, +{ 4, s_0_19, 16, 1, 0}, +{ 7, s_0_20, 19, 1, 0}, +{ 3, s_0_21, 14, 1, 0}, +{ 6, s_0_22, 21, 1, 0}, +{ 3, s_0_23, 14, 1, 0}, +{ 3, s_0_24, 14, 1, 0}, +{ 2, s_0_25, -1, 1, 0}, +{ 3, s_0_26, 25, 1, 0}, +{ 3, s_0_27, -1, 3, 0}, +{ 3, s_0_28, -1, 1, 0} }; static const symbol s_1_0[2] = { 'd', 't' }; @@ -93,8 +93,8 @@ static const symbol s_1_1[2] = { 'v', 't' }; static const struct among a_1[2] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0} }; static const symbol s_2_0[3] = { 'l', 'e', 'g' }; @@ -111,17 +111,17 @@ static const symbol s_2_10[7] = { 'h', 'e', 't', 's', 'l', 'o', 'v' }; static const struct among a_2[11] = { -/* 0 */ { 3, s_2_0, -1, 1, 0}, -/* 1 */ { 4, s_2_1, 0, 1, 0}, -/* 2 */ { 2, s_2_2, -1, 1, 0}, -/* 3 */ { 3, s_2_3, 2, 1, 0}, -/* 4 */ { 3, s_2_4, 2, 1, 0}, -/* 5 */ { 4, s_2_5, 4, 1, 0}, -/* 6 */ { 3, s_2_6, -1, 1, 0}, -/* 7 */ { 3, s_2_7, -1, 1, 0}, -/* 8 */ { 4, s_2_8, 7, 1, 0}, -/* 9 */ { 4, s_2_9, 7, 1, 0}, -/* 10 */ { 7, s_2_10, 9, 1, 0} +{ 3, s_2_0, -1, 1, 0}, +{ 4, s_2_1, 0, 1, 0}, +{ 2, s_2_2, -1, 1, 0}, +{ 3, s_2_3, 2, 1, 0}, +{ 3, s_2_4, 2, 1, 0}, +{ 4, s_2_5, 4, 1, 0}, +{ 3, s_2_6, -1, 1, 0}, +{ 3, s_2_7, -1, 1, 0}, +{ 4, s_2_8, 7, 1, 0}, +{ 4, s_2_9, 7, 1, 0}, +{ 7, s_2_10, 9, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; @@ -130,66 +130,66 @@ static const unsigned char g_s_ending[] = { 119, 125, 149, 1 }; static const symbol s_0[] = { 'e', 'r' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 28 */ - { int c_test1 = z->c; /* test, line 30 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 30 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + { int c_test1 = z->c; + { int ret = skip_utf8(z->p, z->c, z->l, 3); if (ret < 0) return 0; z->c = ret; } - z->I[1] = z->c; /* setmark x, line 30 */ + z->I[0] = z->c; z->c = c_test1; } - if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 31 */ - { /* gopast */ /* non v, line 31 */ + if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; + { int ret = in_grouping_U(z, g_v, 97, 248, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 31 */ - /* try, line 32 */ - if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 32 */ - z->I[0] = z->I[1]; /* $p1 = , line 32 */ + z->I[1] = z->c; + + if (!(z->I[1] < z->I[0])) goto lab0; + z->I[1] = z->I[0]; lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { /* backwardmode */ +static int r_main_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 38 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 38 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 38 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_0, 29); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 38 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 39 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 44 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m2 = z->l - z->c; (void)m2; /* or, line 46 */ - if (in_grouping_b_U(z, g_s_ending, 98, 122, 0)) goto lab1; /* grouping s_ending, line 46 */ + { int m2 = z->l - z->c; (void)m2; + if (in_grouping_b_U(z, g_s_ending, 98, 122, 0)) goto lab1; goto lab0; lab1: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'k') return 0; /* literal, line 46 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'k') return 0; z->c--; - if (out_grouping_b_U(z, g_v, 97, 248, 0)) return 0; /* non v, line 46 */ + if (out_grouping_b_U(z, g_v, 97, 248, 0)) return 0; } lab0: - { int ret = slice_del(z); /* delete, line 46 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 48 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; @@ -197,71 +197,71 @@ static int r_main_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 53 */ +static int r_consonant_pair(struct SN_env * z) { + { int m_test1 = z->l - z->c; - { int mlimit2; /* setlimit, line 54 */ - if (z->c < z->I[0]) return 0; - mlimit2 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 54 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit2; return 0; } /* substring, line 54 */ + { int mlimit2; + if (z->c < z->I[1]) return 0; + mlimit2 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit2; return 0; } if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit2; return 0; } - z->bra = z->c; /* ], line 54 */ + z->bra = z->c; z->lb = mlimit2; } z->c = z->l - m_test1; } - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 59 */ + z->c = ret; } - z->bra = z->c; /* ], line 59 */ - { int ret = slice_del(z); /* delete, line 59 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_other_suffix(struct SN_env * z) { /* backwardmode */ +static int r_other_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 63 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 63 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 63 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_2, 11))) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 63 */ + z->bra = z->c; z->lb = mlimit1; } - { int ret = slice_del(z); /* delete, line 67 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int norwegian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 74 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 74 */ +extern int norwegian_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 75 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 76 */ - { int ret = r_main_suffix(z); /* call main_suffix, line 76 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_main_suffix(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 77 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 77 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 78 */ - { int ret = r_other_suffix(z); /* call other_suffix, line 78 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_other_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; @@ -270,7 +270,7 @@ extern int norwegian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * norwegian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * norwegian_UTF_8_create_env(void) { return SN_create_env(0, 2); } extern void norwegian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_porter.c b/src/backend/snowball/libstemmer/stem_UTF_8_porter.c index 961a06cbf92d..f42aa161fb4d 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_porter.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_porter.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -39,10 +39,10 @@ static const symbol s_0_3[2] = { 's', 's' }; static const struct among a_0[4] = { -/* 0 */ { 1, s_0_0, -1, 3, 0}, -/* 1 */ { 3, s_0_1, 0, 2, 0}, -/* 2 */ { 4, s_0_2, 0, 1, 0}, -/* 3 */ { 2, s_0_3, 0, -1, 0} +{ 1, s_0_0, -1, 3, 0}, +{ 3, s_0_1, 0, 2, 0}, +{ 4, s_0_2, 0, 1, 0}, +{ 2, s_0_3, 0, -1, 0} }; static const symbol s_1_1[2] = { 'b', 'b' }; @@ -60,19 +60,19 @@ static const symbol s_1_12[2] = { 'i', 'z' }; static const struct among a_1[13] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 2, s_1_1, 0, 2, 0}, -/* 2 */ { 2, s_1_2, 0, 2, 0}, -/* 3 */ { 2, s_1_3, 0, 2, 0}, -/* 4 */ { 2, s_1_4, 0, 2, 0}, -/* 5 */ { 2, s_1_5, 0, 1, 0}, -/* 6 */ { 2, s_1_6, 0, 2, 0}, -/* 7 */ { 2, s_1_7, 0, 2, 0}, -/* 8 */ { 2, s_1_8, 0, 2, 0}, -/* 9 */ { 2, s_1_9, 0, 2, 0}, -/* 10 */ { 2, s_1_10, 0, 1, 0}, -/* 11 */ { 2, s_1_11, 0, 2, 0}, -/* 12 */ { 2, s_1_12, 0, 1, 0} +{ 0, 0, -1, 3, 0}, +{ 2, s_1_1, 0, 2, 0}, +{ 2, s_1_2, 0, 2, 0}, +{ 2, s_1_3, 0, 2, 0}, +{ 2, s_1_4, 0, 2, 0}, +{ 2, s_1_5, 0, 1, 0}, +{ 2, s_1_6, 0, 2, 0}, +{ 2, s_1_7, 0, 2, 0}, +{ 2, s_1_8, 0, 2, 0}, +{ 2, s_1_9, 0, 2, 0}, +{ 2, s_1_10, 0, 1, 0}, +{ 2, s_1_11, 0, 2, 0}, +{ 2, s_1_12, 0, 1, 0} }; static const symbol s_2_0[2] = { 'e', 'd' }; @@ -81,9 +81,9 @@ static const symbol s_2_2[3] = { 'i', 'n', 'g' }; static const struct among a_2[3] = { -/* 0 */ { 2, s_2_0, -1, 2, 0}, -/* 1 */ { 3, s_2_1, 0, 1, 0}, -/* 2 */ { 3, s_2_2, -1, 2, 0} +{ 2, s_2_0, -1, 2, 0}, +{ 3, s_2_1, 0, 1, 0}, +{ 3, s_2_2, -1, 2, 0} }; static const symbol s_3_0[4] = { 'a', 'n', 'c', 'i' }; @@ -109,26 +109,26 @@ static const symbol s_3_19[7] = { 'o', 'u', 's', 'n', 'e', 's', 's' }; static const struct among a_3[20] = { -/* 0 */ { 4, s_3_0, -1, 3, 0}, -/* 1 */ { 4, s_3_1, -1, 2, 0}, -/* 2 */ { 4, s_3_2, -1, 4, 0}, -/* 3 */ { 3, s_3_3, -1, 6, 0}, -/* 4 */ { 4, s_3_4, -1, 9, 0}, -/* 5 */ { 5, s_3_5, -1, 11, 0}, -/* 6 */ { 5, s_3_6, -1, 5, 0}, -/* 7 */ { 5, s_3_7, -1, 9, 0}, -/* 8 */ { 6, s_3_8, -1, 13, 0}, -/* 9 */ { 5, s_3_9, -1, 12, 0}, -/* 10 */ { 6, s_3_10, -1, 1, 0}, -/* 11 */ { 7, s_3_11, 10, 8, 0}, -/* 12 */ { 5, s_3_12, -1, 9, 0}, -/* 13 */ { 5, s_3_13, -1, 8, 0}, -/* 14 */ { 7, s_3_14, 13, 7, 0}, -/* 15 */ { 4, s_3_15, -1, 7, 0}, -/* 16 */ { 4, s_3_16, -1, 8, 0}, -/* 17 */ { 7, s_3_17, -1, 12, 0}, -/* 18 */ { 7, s_3_18, -1, 10, 0}, -/* 19 */ { 7, s_3_19, -1, 11, 0} +{ 4, s_3_0, -1, 3, 0}, +{ 4, s_3_1, -1, 2, 0}, +{ 4, s_3_2, -1, 4, 0}, +{ 3, s_3_3, -1, 6, 0}, +{ 4, s_3_4, -1, 9, 0}, +{ 5, s_3_5, -1, 11, 0}, +{ 5, s_3_6, -1, 5, 0}, +{ 5, s_3_7, -1, 9, 0}, +{ 6, s_3_8, -1, 13, 0}, +{ 5, s_3_9, -1, 12, 0}, +{ 6, s_3_10, -1, 1, 0}, +{ 7, s_3_11, 10, 8, 0}, +{ 5, s_3_12, -1, 9, 0}, +{ 5, s_3_13, -1, 8, 0}, +{ 7, s_3_14, 13, 7, 0}, +{ 4, s_3_15, -1, 7, 0}, +{ 4, s_3_16, -1, 8, 0}, +{ 7, s_3_17, -1, 12, 0}, +{ 7, s_3_18, -1, 10, 0}, +{ 7, s_3_19, -1, 11, 0} }; static const symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' }; @@ -141,13 +141,13 @@ static const symbol s_4_6[4] = { 'n', 'e', 's', 's' }; static const struct among a_4[7] = { -/* 0 */ { 5, s_4_0, -1, 2, 0}, -/* 1 */ { 5, s_4_1, -1, 3, 0}, -/* 2 */ { 5, s_4_2, -1, 1, 0}, -/* 3 */ { 5, s_4_3, -1, 2, 0}, -/* 4 */ { 4, s_4_4, -1, 2, 0}, -/* 5 */ { 3, s_4_5, -1, 3, 0}, -/* 6 */ { 4, s_4_6, -1, 3, 0} +{ 5, s_4_0, -1, 2, 0}, +{ 5, s_4_1, -1, 3, 0}, +{ 5, s_4_2, -1, 1, 0}, +{ 5, s_4_3, -1, 2, 0}, +{ 4, s_4_4, -1, 2, 0}, +{ 3, s_4_5, -1, 3, 0}, +{ 4, s_4_6, -1, 3, 0} }; static const symbol s_5_0[2] = { 'i', 'c' }; @@ -172,25 +172,25 @@ static const symbol s_5_18[2] = { 'o', 'u' }; static const struct among a_5[19] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 4, s_5_1, -1, 1, 0}, -/* 2 */ { 4, s_5_2, -1, 1, 0}, -/* 3 */ { 4, s_5_3, -1, 1, 0}, -/* 4 */ { 4, s_5_4, -1, 1, 0}, -/* 5 */ { 3, s_5_5, -1, 1, 0}, -/* 6 */ { 3, s_5_6, -1, 1, 0}, -/* 7 */ { 3, s_5_7, -1, 1, 0}, -/* 8 */ { 3, s_5_8, -1, 1, 0}, -/* 9 */ { 2, s_5_9, -1, 1, 0}, -/* 10 */ { 3, s_5_10, -1, 1, 0}, -/* 11 */ { 3, s_5_11, -1, 2, 0}, -/* 12 */ { 2, s_5_12, -1, 1, 0}, -/* 13 */ { 3, s_5_13, -1, 1, 0}, -/* 14 */ { 3, s_5_14, -1, 1, 0}, -/* 15 */ { 3, s_5_15, -1, 1, 0}, -/* 16 */ { 4, s_5_16, 15, 1, 0}, -/* 17 */ { 5, s_5_17, 16, 1, 0}, -/* 18 */ { 2, s_5_18, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 4, s_5_1, -1, 1, 0}, +{ 4, s_5_2, -1, 1, 0}, +{ 4, s_5_3, -1, 1, 0}, +{ 4, s_5_4, -1, 1, 0}, +{ 3, s_5_5, -1, 1, 0}, +{ 3, s_5_6, -1, 1, 0}, +{ 3, s_5_7, -1, 1, 0}, +{ 3, s_5_8, -1, 1, 0}, +{ 2, s_5_9, -1, 1, 0}, +{ 3, s_5_10, -1, 1, 0}, +{ 3, s_5_11, -1, 2, 0}, +{ 2, s_5_12, -1, 1, 0}, +{ 3, s_5_13, -1, 1, 0}, +{ 3, s_5_14, -1, 1, 0}, +{ 3, s_5_15, -1, 1, 0}, +{ 4, s_5_16, 15, 1, 0}, +{ 5, s_5_17, 16, 1, 0}, +{ 2, s_5_18, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1 }; @@ -222,43 +222,43 @@ static const symbol s_21[] = { 'Y' }; static const symbol s_22[] = { 'Y' }; static const symbol s_23[] = { 'y' }; -static int r_shortv(struct SN_env * z) { /* backwardmode */ - if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) return 0; /* non v_WXY, line 19 */ - if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 19 */ - if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* non v, line 19 */ +static int r_shortv(struct SN_env * z) { + if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) return 0; + if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; + if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 21 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 22 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_Step_1a(struct SN_env * z) { /* backwardmode */ +static int r_Step_1a(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 25 */ - if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; /* substring, line 25 */ + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; among_var = find_among_b(z, a_0, 4); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 25 */ - switch (among_var) { /* among, line 25 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 26 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 27 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 29 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -266,72 +266,72 @@ static int r_Step_1a(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1b(struct SN_env * z) { /* backwardmode */ +static int r_Step_1b(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 34 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 34 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; among_var = find_among_b(z, a_2, 3); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 34 */ - switch (among_var) { /* among, line 34 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R1(z); /* call R1, line 35 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_2); /* <-, line 35 */ + { int ret = slice_from_s(z, 2, s_2); if (ret < 0) return ret; } break; case 2: - { int m_test1 = z->l - z->c; /* test, line 38 */ - { /* gopast */ /* grouping v, line 38 */ + { int m_test1 = z->l - z->c; + { int ret = out_grouping_b_U(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } z->c = z->l - m_test1; } - { int ret = slice_del(z); /* delete, line 38 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m_test2 = z->l - z->c; /* test, line 39 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 39 */ + { int m_test2 = z->l - z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else among_var = find_among_b(z, a_1, 13); if (!(among_var)) return 0; z->c = z->l - m_test2; } - switch (among_var) { /* among, line 39 */ + switch (among_var) { case 1: { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ + ret = insert_s(z, z->c, z->c, 1, s_3); z->c = saved_c; } if (ret < 0) return ret; } break; case 2: - z->ket = z->c; /* [, line 44 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 44 */ + z->c = ret; } - z->bra = z->c; /* ], line 44 */ - { int ret = slice_del(z); /* delete, line 44 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - if (z->c != z->I[0]) return 0; /* atmark, line 45 */ - { int m_test3 = z->l - z->c; /* test, line 45 */ - { int ret = r_shortv(z); /* call shortv, line 45 */ + if (z->c != z->I[1]) return 0; + { int m_test3 = z->l - z->c; + { int ret = r_shortv(z); if (ret <= 0) return ret; } z->c = z->l - m_test3; } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ + ret = insert_s(z, z->c, z->c, 1, s_4); z->c = saved_c; } if (ret < 0) return ret; @@ -343,103 +343,103 @@ static int r_Step_1b(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_1c(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 52 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 52 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 52 */ +static int r_Step_1c(struct SN_env * z) { + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 52 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; z->c--; } lab0: - z->bra = z->c; /* ], line 52 */ - { /* gopast */ /* grouping v, line 53 */ + z->bra = z->c; + { int ret = out_grouping_b_U(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - { int ret = slice_from_s(z, 1, s_5); /* <-, line 54 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { /* backwardmode */ +static int r_Step_2(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 58 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 58 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_3, 20); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 58 */ - { int ret = r_R1(z); /* call R1, line 58 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 58 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_6); /* <-, line 59 */ + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_7); /* <-, line 60 */ + { int ret = slice_from_s(z, 4, s_7); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_8); /* <-, line 61 */ + { int ret = slice_from_s(z, 4, s_8); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_9); /* <-, line 62 */ + { int ret = slice_from_s(z, 4, s_9); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_10); /* <-, line 63 */ + { int ret = slice_from_s(z, 3, s_10); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 64 */ + { int ret = slice_from_s(z, 1, s_11); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_12); /* <-, line 66 */ + { int ret = slice_from_s(z, 3, s_12); if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 3, s_13); /* <-, line 68 */ + { int ret = slice_from_s(z, 3, s_13); if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 2, s_14); /* <-, line 69 */ + { int ret = slice_from_s(z, 2, s_14); if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 3, s_15); /* <-, line 72 */ + { int ret = slice_from_s(z, 3, s_15); if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_16); /* <-, line 74 */ + { int ret = slice_from_s(z, 3, s_16); if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_17); /* <-, line 76 */ + { int ret = slice_from_s(z, 3, s_17); if (ret < 0) return ret; } break; case 13: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 77 */ + { int ret = slice_from_s(z, 3, s_18); if (ret < 0) return ret; } break; @@ -447,29 +447,29 @@ static int r_Step_2(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_3(struct SN_env * z) { /* backwardmode */ +static int r_Step_3(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 82 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 82 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_4, 7); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 82 */ - { int ret = r_R1(z); /* call R1, line 82 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 82 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_19); /* <-, line 83 */ + { int ret = slice_from_s(z, 2, s_19); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_20); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_20); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -477,34 +477,34 @@ static int r_Step_3(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_4(struct SN_env * z) { /* backwardmode */ +static int r_Step_4(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 92 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 92 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_5, 19); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 92 */ - { int ret = r_R2(z); /* call R2, line 92 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 92 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 95 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int m1 = z->l - z->c; (void)m1; /* or, line 96 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 96 */ + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 96 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -512,24 +512,24 @@ static int r_Step_4(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_Step_5a(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 101 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 101 */ +static int r_Step_5a(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; - z->bra = z->c; /* ], line 101 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 102 */ - { int ret = r_R2(z); /* call R2, line 102 */ + z->bra = z->c; + { int m1 = z->l - z->c; (void)m1; + { int ret = r_R2(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); /* call R1, line 102 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - { int ret = r_shortv(z); /* call shortv, line 102 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_shortv(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } @@ -539,66 +539,65 @@ static int r_Step_5a(struct SN_env * z) { /* backwardmode */ } } lab0: - { int ret = slice_del(z); /* delete, line 103 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_Step_5b(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 107 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 107 */ +static int r_Step_5b(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - z->bra = z->c; /* ], line 107 */ - { int ret = r_R2(z); /* call R2, line 108 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 108 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 109 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int porter_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset Y_found, line 115 */ - { int c1 = z->c; /* do, line 116 */ - z->bra = z->c; /* [, line 116 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab0; /* literal, line 116 */ +extern int porter_UTF_8_stem(struct SN_env * z) { + z->I[2] = 0; + { int c1 = z->c; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab0; z->c++; - z->ket = z->c; /* ], line 116 */ - { int ret = slice_from_s(z, 1, s_21); /* <-, line 116 */ + z->ket = z->c; + { int ret = slice_from_s(z, 1, s_21); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 116 */ + z->I[2] = 1; lab0: z->c = c1; } - { int c2 = z->c; /* do, line 117 */ -/* repeat, line 117 */ - - while(1) { int c3 = z->c; - while(1) { /* goto, line 117 */ + { int c2 = z->c; + while(1) { + int c3 = z->c; + while(1) { int c4 = z->c; - if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab3; /* grouping v, line 117 */ - z->bra = z->c; /* [, line 117 */ - if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 117 */ + if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab3; + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; z->c++; - z->ket = z->c; /* ], line 117 */ + z->ket = z->c; z->c = c4; break; lab3: z->c = c4; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab2; - z->c = ret; /* goto, line 117 */ + z->c = ret; } } - { int ret = slice_from_s(z, 1, s_22); /* <-, line 117 */ + { int ret = slice_from_s(z, 1, s_22); if (ret < 0) return ret; } - z->B[0] = 1; /* set Y_found, line 117 */ + z->I[2] = 1; continue; lab2: z->c = c3; @@ -606,106 +605,105 @@ extern int porter_UTF_8_stem(struct SN_env * z) { /* forwardmode */ } z->c = c2; } - z->I[0] = z->l; /* $p1 = , line 119 */ - z->I[1] = z->l; /* $p2 = , line 120 */ - { int c5 = z->c; /* do, line 121 */ - { /* gopast */ /* grouping v, line 122 */ + z->I[1] = z->l; + z->I[0] = z->l; + { int c5 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 122 */ + { int ret = in_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 122 */ - { /* gopast */ /* grouping v, line 123 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 123 */ + { int ret = in_grouping_U(z, g_v, 97, 121, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 123 */ + z->I[0] = z->c; lab4: z->c = c5; } - z->lb = z->c; z->c = z->l; /* backwards, line 126 */ + z->lb = z->c; z->c = z->l; - { int m6 = z->l - z->c; (void)m6; /* do, line 127 */ - { int ret = r_Step_1a(z); /* call Step_1a, line 127 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_Step_1a(z); if (ret < 0) return ret; } z->c = z->l - m6; } - { int m7 = z->l - z->c; (void)m7; /* do, line 128 */ - { int ret = r_Step_1b(z); /* call Step_1b, line 128 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_Step_1b(z); if (ret < 0) return ret; } z->c = z->l - m7; } - { int m8 = z->l - z->c; (void)m8; /* do, line 129 */ - { int ret = r_Step_1c(z); /* call Step_1c, line 129 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_Step_1c(z); if (ret < 0) return ret; } z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 130 */ - { int ret = r_Step_2(z); /* call Step_2, line 130 */ + { int m9 = z->l - z->c; (void)m9; + { int ret = r_Step_2(z); if (ret < 0) return ret; } z->c = z->l - m9; } - { int m10 = z->l - z->c; (void)m10; /* do, line 131 */ - { int ret = r_Step_3(z); /* call Step_3, line 131 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_Step_3(z); if (ret < 0) return ret; } z->c = z->l - m10; } - { int m11 = z->l - z->c; (void)m11; /* do, line 132 */ - { int ret = r_Step_4(z); /* call Step_4, line 132 */ + { int m11 = z->l - z->c; (void)m11; + { int ret = r_Step_4(z); if (ret < 0) return ret; } z->c = z->l - m11; } - { int m12 = z->l - z->c; (void)m12; /* do, line 133 */ - { int ret = r_Step_5a(z); /* call Step_5a, line 133 */ + { int m12 = z->l - z->c; (void)m12; + { int ret = r_Step_5a(z); if (ret < 0) return ret; } z->c = z->l - m12; } - { int m13 = z->l - z->c; (void)m13; /* do, line 134 */ - { int ret = r_Step_5b(z); /* call Step_5b, line 134 */ + { int m13 = z->l - z->c; (void)m13; + { int ret = r_Step_5b(z); if (ret < 0) return ret; } z->c = z->l - m13; } z->c = z->lb; - { int c14 = z->c; /* do, line 137 */ - if (!(z->B[0])) goto lab5; /* Boolean test Y_found, line 137 */ -/* repeat, line 137 */ - - while(1) { int c15 = z->c; - while(1) { /* goto, line 137 */ + { int c14 = z->c; + if (!(z->I[2])) goto lab5; + while(1) { + int c15 = z->c; + while(1) { int c16 = z->c; - z->bra = z->c; /* [, line 137 */ - if (z->c == z->l || z->p[z->c] != 'Y') goto lab7; /* literal, line 137 */ + z->bra = z->c; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab7; z->c++; - z->ket = z->c; /* ], line 137 */ + z->ket = z->c; z->c = c16; break; lab7: z->c = c16; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab6; - z->c = ret; /* goto, line 137 */ + z->c = ret; } } - { int ret = slice_from_s(z, 1, s_23); /* <-, line 137 */ + { int ret = slice_from_s(z, 1, s_23); if (ret < 0) return ret; } continue; @@ -719,7 +717,7 @@ extern int porter_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * porter_UTF_8_create_env(void) { return SN_create_env(0, 2, 1); } +extern struct SN_env * porter_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void porter_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c b/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c index 278fdff8d9a2..33b8852cb910 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -36,9 +36,9 @@ static const symbol s_0_2[2] = { 0xC3, 0xB5 }; static const struct among a_0[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 2, s_0_1, 0, 1, 0}, -/* 2 */ { 2, s_0_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 2, s_0_1, 0, 1, 0}, +{ 2, s_0_2, 0, 2, 0} }; static const symbol s_1_1[2] = { 'a', '~' }; @@ -46,9 +46,9 @@ static const symbol s_1_2[2] = { 'o', '~' }; static const struct among a_1[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 2, s_1_1, 0, 1, 0}, -/* 2 */ { 2, s_1_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 2, s_1_1, 0, 1, 0}, +{ 2, s_1_2, 0, 2, 0} }; static const symbol s_2_0[2] = { 'i', 'c' }; @@ -58,10 +58,10 @@ static const symbol s_2_3[2] = { 'i', 'v' }; static const struct among a_2[4] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 2, s_2_2, -1, -1, 0}, -/* 3 */ { 2, s_2_3, -1, 1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 2, s_2_2, -1, -1, 0}, +{ 2, s_2_3, -1, 1, 0} }; static const symbol s_3_0[4] = { 'a', 'n', 't', 'e' }; @@ -70,9 +70,9 @@ static const symbol s_3_2[5] = { 0xC3, 0xAD, 'v', 'e', 'l' }; static const struct among a_3[3] = { -/* 0 */ { 4, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0}, -/* 2 */ { 5, s_3_2, -1, 1, 0} +{ 4, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0}, +{ 5, s_3_2, -1, 1, 0} }; static const symbol s_4_0[2] = { 'i', 'c' }; @@ -81,9 +81,9 @@ static const symbol s_4_2[2] = { 'i', 'v' }; static const struct among a_4[3] = { -/* 0 */ { 2, s_4_0, -1, 1, 0}, -/* 1 */ { 4, s_4_1, -1, 1, 0}, -/* 2 */ { 2, s_4_2, -1, 1, 0} +{ 2, s_4_0, -1, 1, 0}, +{ 4, s_4_1, -1, 1, 0}, +{ 2, s_4_2, -1, 1, 0} }; static const symbol s_5_0[3] = { 'i', 'c', 'a' }; @@ -134,51 +134,51 @@ static const symbol s_5_44[4] = { 'i', 'v', 'o', 's' }; static const struct among a_5[45] = { -/* 0 */ { 3, s_5_0, -1, 1, 0}, -/* 1 */ { 6, s_5_1, -1, 1, 0}, -/* 2 */ { 6, s_5_2, -1, 4, 0}, -/* 3 */ { 5, s_5_3, -1, 2, 0}, -/* 4 */ { 3, s_5_4, -1, 9, 0}, -/* 5 */ { 5, s_5_5, -1, 1, 0}, -/* 6 */ { 3, s_5_6, -1, 1, 0}, -/* 7 */ { 4, s_5_7, -1, 1, 0}, -/* 8 */ { 3, s_5_8, -1, 8, 0}, -/* 9 */ { 3, s_5_9, -1, 1, 0}, -/* 10 */ { 5, s_5_10, -1, 7, 0}, -/* 11 */ { 4, s_5_11, -1, 1, 0}, -/* 12 */ { 5, s_5_12, -1, 6, 0}, -/* 13 */ { 6, s_5_13, 12, 5, 0}, -/* 14 */ { 5, s_5_14, -1, 1, 0}, -/* 15 */ { 5, s_5_15, -1, 1, 0}, -/* 16 */ { 3, s_5_16, -1, 1, 0}, -/* 17 */ { 4, s_5_17, -1, 1, 0}, -/* 18 */ { 3, s_5_18, -1, 1, 0}, -/* 19 */ { 6, s_5_19, -1, 1, 0}, -/* 20 */ { 6, s_5_20, -1, 1, 0}, -/* 21 */ { 3, s_5_21, -1, 8, 0}, -/* 22 */ { 6, s_5_22, -1, 1, 0}, -/* 23 */ { 6, s_5_23, -1, 3, 0}, -/* 24 */ { 4, s_5_24, -1, 1, 0}, -/* 25 */ { 4, s_5_25, -1, 1, 0}, -/* 26 */ { 7, s_5_26, -1, 4, 0}, -/* 27 */ { 6, s_5_27, -1, 2, 0}, -/* 28 */ { 4, s_5_28, -1, 9, 0}, -/* 29 */ { 6, s_5_29, -1, 1, 0}, -/* 30 */ { 4, s_5_30, -1, 1, 0}, -/* 31 */ { 5, s_5_31, -1, 1, 0}, -/* 32 */ { 4, s_5_32, -1, 8, 0}, -/* 33 */ { 4, s_5_33, -1, 1, 0}, -/* 34 */ { 6, s_5_34, -1, 7, 0}, -/* 35 */ { 6, s_5_35, -1, 1, 0}, -/* 36 */ { 5, s_5_36, -1, 1, 0}, -/* 37 */ { 7, s_5_37, -1, 1, 0}, -/* 38 */ { 7, s_5_38, -1, 3, 0}, -/* 39 */ { 4, s_5_39, -1, 1, 0}, -/* 40 */ { 5, s_5_40, -1, 1, 0}, -/* 41 */ { 4, s_5_41, -1, 1, 0}, -/* 42 */ { 7, s_5_42, -1, 1, 0}, -/* 43 */ { 7, s_5_43, -1, 1, 0}, -/* 44 */ { 4, s_5_44, -1, 8, 0} +{ 3, s_5_0, -1, 1, 0}, +{ 6, s_5_1, -1, 1, 0}, +{ 6, s_5_2, -1, 4, 0}, +{ 5, s_5_3, -1, 2, 0}, +{ 3, s_5_4, -1, 9, 0}, +{ 5, s_5_5, -1, 1, 0}, +{ 3, s_5_6, -1, 1, 0}, +{ 4, s_5_7, -1, 1, 0}, +{ 3, s_5_8, -1, 8, 0}, +{ 3, s_5_9, -1, 1, 0}, +{ 5, s_5_10, -1, 7, 0}, +{ 4, s_5_11, -1, 1, 0}, +{ 5, s_5_12, -1, 6, 0}, +{ 6, s_5_13, 12, 5, 0}, +{ 5, s_5_14, -1, 1, 0}, +{ 5, s_5_15, -1, 1, 0}, +{ 3, s_5_16, -1, 1, 0}, +{ 4, s_5_17, -1, 1, 0}, +{ 3, s_5_18, -1, 1, 0}, +{ 6, s_5_19, -1, 1, 0}, +{ 6, s_5_20, -1, 1, 0}, +{ 3, s_5_21, -1, 8, 0}, +{ 6, s_5_22, -1, 1, 0}, +{ 6, s_5_23, -1, 3, 0}, +{ 4, s_5_24, -1, 1, 0}, +{ 4, s_5_25, -1, 1, 0}, +{ 7, s_5_26, -1, 4, 0}, +{ 6, s_5_27, -1, 2, 0}, +{ 4, s_5_28, -1, 9, 0}, +{ 6, s_5_29, -1, 1, 0}, +{ 4, s_5_30, -1, 1, 0}, +{ 5, s_5_31, -1, 1, 0}, +{ 4, s_5_32, -1, 8, 0}, +{ 4, s_5_33, -1, 1, 0}, +{ 6, s_5_34, -1, 7, 0}, +{ 6, s_5_35, -1, 1, 0}, +{ 5, s_5_36, -1, 1, 0}, +{ 7, s_5_37, -1, 1, 0}, +{ 7, s_5_38, -1, 3, 0}, +{ 4, s_5_39, -1, 1, 0}, +{ 5, s_5_40, -1, 1, 0}, +{ 4, s_5_41, -1, 1, 0}, +{ 7, s_5_42, -1, 1, 0}, +{ 7, s_5_43, -1, 1, 0}, +{ 4, s_5_44, -1, 8, 0} }; static const symbol s_6_0[3] = { 'a', 'd', 'a' }; @@ -304,126 +304,126 @@ static const symbol s_6_119[4] = { 'i', 'r', 0xC3, 0xA1 }; static const struct among a_6[120] = { -/* 0 */ { 3, s_6_0, -1, 1, 0}, -/* 1 */ { 3, s_6_1, -1, 1, 0}, -/* 2 */ { 2, s_6_2, -1, 1, 0}, -/* 3 */ { 4, s_6_3, 2, 1, 0}, -/* 4 */ { 4, s_6_4, 2, 1, 0}, -/* 5 */ { 4, s_6_5, 2, 1, 0}, -/* 6 */ { 3, s_6_6, -1, 1, 0}, -/* 7 */ { 3, s_6_7, -1, 1, 0}, -/* 8 */ { 3, s_6_8, -1, 1, 0}, -/* 9 */ { 3, s_6_9, -1, 1, 0}, -/* 10 */ { 4, s_6_10, -1, 1, 0}, -/* 11 */ { 4, s_6_11, -1, 1, 0}, -/* 12 */ { 4, s_6_12, -1, 1, 0}, -/* 13 */ { 4, s_6_13, -1, 1, 0}, -/* 14 */ { 4, s_6_14, -1, 1, 0}, -/* 15 */ { 4, s_6_15, -1, 1, 0}, -/* 16 */ { 2, s_6_16, -1, 1, 0}, -/* 17 */ { 4, s_6_17, 16, 1, 0}, -/* 18 */ { 4, s_6_18, 16, 1, 0}, -/* 19 */ { 4, s_6_19, 16, 1, 0}, -/* 20 */ { 2, s_6_20, -1, 1, 0}, -/* 21 */ { 3, s_6_21, 20, 1, 0}, -/* 22 */ { 5, s_6_22, 21, 1, 0}, -/* 23 */ { 5, s_6_23, 21, 1, 0}, -/* 24 */ { 5, s_6_24, 21, 1, 0}, -/* 25 */ { 4, s_6_25, 20, 1, 0}, -/* 26 */ { 4, s_6_26, 20, 1, 0}, -/* 27 */ { 4, s_6_27, 20, 1, 0}, -/* 28 */ { 4, s_6_28, 20, 1, 0}, -/* 29 */ { 2, s_6_29, -1, 1, 0}, -/* 30 */ { 4, s_6_30, 29, 1, 0}, -/* 31 */ { 4, s_6_31, 29, 1, 0}, -/* 32 */ { 4, s_6_32, 29, 1, 0}, -/* 33 */ { 5, s_6_33, 29, 1, 0}, -/* 34 */ { 5, s_6_34, 29, 1, 0}, -/* 35 */ { 5, s_6_35, 29, 1, 0}, -/* 36 */ { 3, s_6_36, -1, 1, 0}, -/* 37 */ { 3, s_6_37, -1, 1, 0}, -/* 38 */ { 4, s_6_38, -1, 1, 0}, -/* 39 */ { 4, s_6_39, -1, 1, 0}, -/* 40 */ { 4, s_6_40, -1, 1, 0}, -/* 41 */ { 5, s_6_41, -1, 1, 0}, -/* 42 */ { 5, s_6_42, -1, 1, 0}, -/* 43 */ { 5, s_6_43, -1, 1, 0}, -/* 44 */ { 2, s_6_44, -1, 1, 0}, -/* 45 */ { 2, s_6_45, -1, 1, 0}, -/* 46 */ { 2, s_6_46, -1, 1, 0}, -/* 47 */ { 2, s_6_47, -1, 1, 0}, -/* 48 */ { 4, s_6_48, 47, 1, 0}, -/* 49 */ { 4, s_6_49, 47, 1, 0}, -/* 50 */ { 3, s_6_50, 47, 1, 0}, -/* 51 */ { 5, s_6_51, 50, 1, 0}, -/* 52 */ { 5, s_6_52, 50, 1, 0}, -/* 53 */ { 5, s_6_53, 50, 1, 0}, -/* 54 */ { 4, s_6_54, 47, 1, 0}, -/* 55 */ { 4, s_6_55, 47, 1, 0}, -/* 56 */ { 4, s_6_56, 47, 1, 0}, -/* 57 */ { 4, s_6_57, 47, 1, 0}, -/* 58 */ { 2, s_6_58, -1, 1, 0}, -/* 59 */ { 5, s_6_59, 58, 1, 0}, -/* 60 */ { 5, s_6_60, 58, 1, 0}, -/* 61 */ { 5, s_6_61, 58, 1, 0}, -/* 62 */ { 4, s_6_62, 58, 1, 0}, -/* 63 */ { 4, s_6_63, 58, 1, 0}, -/* 64 */ { 4, s_6_64, 58, 1, 0}, -/* 65 */ { 5, s_6_65, 58, 1, 0}, -/* 66 */ { 5, s_6_66, 58, 1, 0}, -/* 67 */ { 5, s_6_67, 58, 1, 0}, -/* 68 */ { 5, s_6_68, 58, 1, 0}, -/* 69 */ { 5, s_6_69, 58, 1, 0}, -/* 70 */ { 5, s_6_70, 58, 1, 0}, -/* 71 */ { 2, s_6_71, -1, 1, 0}, -/* 72 */ { 3, s_6_72, 71, 1, 0}, -/* 73 */ { 3, s_6_73, 71, 1, 0}, -/* 74 */ { 5, s_6_74, 73, 1, 0}, -/* 75 */ { 5, s_6_75, 73, 1, 0}, -/* 76 */ { 5, s_6_76, 73, 1, 0}, -/* 77 */ { 6, s_6_77, 73, 1, 0}, -/* 78 */ { 6, s_6_78, 73, 1, 0}, -/* 79 */ { 6, s_6_79, 73, 1, 0}, -/* 80 */ { 7, s_6_80, 73, 1, 0}, -/* 81 */ { 7, s_6_81, 73, 1, 0}, -/* 82 */ { 7, s_6_82, 73, 1, 0}, -/* 83 */ { 6, s_6_83, 73, 1, 0}, -/* 84 */ { 5, s_6_84, 73, 1, 0}, -/* 85 */ { 7, s_6_85, 84, 1, 0}, -/* 86 */ { 7, s_6_86, 84, 1, 0}, -/* 87 */ { 7, s_6_87, 84, 1, 0}, -/* 88 */ { 4, s_6_88, -1, 1, 0}, -/* 89 */ { 4, s_6_89, -1, 1, 0}, -/* 90 */ { 4, s_6_90, -1, 1, 0}, -/* 91 */ { 7, s_6_91, 90, 1, 0}, -/* 92 */ { 7, s_6_92, 90, 1, 0}, -/* 93 */ { 7, s_6_93, 90, 1, 0}, -/* 94 */ { 7, s_6_94, 90, 1, 0}, -/* 95 */ { 6, s_6_95, 90, 1, 0}, -/* 96 */ { 8, s_6_96, 95, 1, 0}, -/* 97 */ { 8, s_6_97, 95, 1, 0}, -/* 98 */ { 8, s_6_98, 95, 1, 0}, -/* 99 */ { 4, s_6_99, -1, 1, 0}, -/*100 */ { 6, s_6_100, 99, 1, 0}, -/*101 */ { 6, s_6_101, 99, 1, 0}, -/*102 */ { 6, s_6_102, 99, 1, 0}, -/*103 */ { 8, s_6_103, 99, 1, 0}, -/*104 */ { 8, s_6_104, 99, 1, 0}, -/*105 */ { 8, s_6_105, 99, 1, 0}, -/*106 */ { 4, s_6_106, -1, 1, 0}, -/*107 */ { 5, s_6_107, -1, 1, 0}, -/*108 */ { 5, s_6_108, -1, 1, 0}, -/*109 */ { 5, s_6_109, -1, 1, 0}, -/*110 */ { 5, s_6_110, -1, 1, 0}, -/*111 */ { 5, s_6_111, -1, 1, 0}, -/*112 */ { 5, s_6_112, -1, 1, 0}, -/*113 */ { 5, s_6_113, -1, 1, 0}, -/*114 */ { 2, s_6_114, -1, 1, 0}, -/*115 */ { 2, s_6_115, -1, 1, 0}, -/*116 */ { 2, s_6_116, -1, 1, 0}, -/*117 */ { 4, s_6_117, -1, 1, 0}, -/*118 */ { 4, s_6_118, -1, 1, 0}, -/*119 */ { 4, s_6_119, -1, 1, 0} +{ 3, s_6_0, -1, 1, 0}, +{ 3, s_6_1, -1, 1, 0}, +{ 2, s_6_2, -1, 1, 0}, +{ 4, s_6_3, 2, 1, 0}, +{ 4, s_6_4, 2, 1, 0}, +{ 4, s_6_5, 2, 1, 0}, +{ 3, s_6_6, -1, 1, 0}, +{ 3, s_6_7, -1, 1, 0}, +{ 3, s_6_8, -1, 1, 0}, +{ 3, s_6_9, -1, 1, 0}, +{ 4, s_6_10, -1, 1, 0}, +{ 4, s_6_11, -1, 1, 0}, +{ 4, s_6_12, -1, 1, 0}, +{ 4, s_6_13, -1, 1, 0}, +{ 4, s_6_14, -1, 1, 0}, +{ 4, s_6_15, -1, 1, 0}, +{ 2, s_6_16, -1, 1, 0}, +{ 4, s_6_17, 16, 1, 0}, +{ 4, s_6_18, 16, 1, 0}, +{ 4, s_6_19, 16, 1, 0}, +{ 2, s_6_20, -1, 1, 0}, +{ 3, s_6_21, 20, 1, 0}, +{ 5, s_6_22, 21, 1, 0}, +{ 5, s_6_23, 21, 1, 0}, +{ 5, s_6_24, 21, 1, 0}, +{ 4, s_6_25, 20, 1, 0}, +{ 4, s_6_26, 20, 1, 0}, +{ 4, s_6_27, 20, 1, 0}, +{ 4, s_6_28, 20, 1, 0}, +{ 2, s_6_29, -1, 1, 0}, +{ 4, s_6_30, 29, 1, 0}, +{ 4, s_6_31, 29, 1, 0}, +{ 4, s_6_32, 29, 1, 0}, +{ 5, s_6_33, 29, 1, 0}, +{ 5, s_6_34, 29, 1, 0}, +{ 5, s_6_35, 29, 1, 0}, +{ 3, s_6_36, -1, 1, 0}, +{ 3, s_6_37, -1, 1, 0}, +{ 4, s_6_38, -1, 1, 0}, +{ 4, s_6_39, -1, 1, 0}, +{ 4, s_6_40, -1, 1, 0}, +{ 5, s_6_41, -1, 1, 0}, +{ 5, s_6_42, -1, 1, 0}, +{ 5, s_6_43, -1, 1, 0}, +{ 2, s_6_44, -1, 1, 0}, +{ 2, s_6_45, -1, 1, 0}, +{ 2, s_6_46, -1, 1, 0}, +{ 2, s_6_47, -1, 1, 0}, +{ 4, s_6_48, 47, 1, 0}, +{ 4, s_6_49, 47, 1, 0}, +{ 3, s_6_50, 47, 1, 0}, +{ 5, s_6_51, 50, 1, 0}, +{ 5, s_6_52, 50, 1, 0}, +{ 5, s_6_53, 50, 1, 0}, +{ 4, s_6_54, 47, 1, 0}, +{ 4, s_6_55, 47, 1, 0}, +{ 4, s_6_56, 47, 1, 0}, +{ 4, s_6_57, 47, 1, 0}, +{ 2, s_6_58, -1, 1, 0}, +{ 5, s_6_59, 58, 1, 0}, +{ 5, s_6_60, 58, 1, 0}, +{ 5, s_6_61, 58, 1, 0}, +{ 4, s_6_62, 58, 1, 0}, +{ 4, s_6_63, 58, 1, 0}, +{ 4, s_6_64, 58, 1, 0}, +{ 5, s_6_65, 58, 1, 0}, +{ 5, s_6_66, 58, 1, 0}, +{ 5, s_6_67, 58, 1, 0}, +{ 5, s_6_68, 58, 1, 0}, +{ 5, s_6_69, 58, 1, 0}, +{ 5, s_6_70, 58, 1, 0}, +{ 2, s_6_71, -1, 1, 0}, +{ 3, s_6_72, 71, 1, 0}, +{ 3, s_6_73, 71, 1, 0}, +{ 5, s_6_74, 73, 1, 0}, +{ 5, s_6_75, 73, 1, 0}, +{ 5, s_6_76, 73, 1, 0}, +{ 6, s_6_77, 73, 1, 0}, +{ 6, s_6_78, 73, 1, 0}, +{ 6, s_6_79, 73, 1, 0}, +{ 7, s_6_80, 73, 1, 0}, +{ 7, s_6_81, 73, 1, 0}, +{ 7, s_6_82, 73, 1, 0}, +{ 6, s_6_83, 73, 1, 0}, +{ 5, s_6_84, 73, 1, 0}, +{ 7, s_6_85, 84, 1, 0}, +{ 7, s_6_86, 84, 1, 0}, +{ 7, s_6_87, 84, 1, 0}, +{ 4, s_6_88, -1, 1, 0}, +{ 4, s_6_89, -1, 1, 0}, +{ 4, s_6_90, -1, 1, 0}, +{ 7, s_6_91, 90, 1, 0}, +{ 7, s_6_92, 90, 1, 0}, +{ 7, s_6_93, 90, 1, 0}, +{ 7, s_6_94, 90, 1, 0}, +{ 6, s_6_95, 90, 1, 0}, +{ 8, s_6_96, 95, 1, 0}, +{ 8, s_6_97, 95, 1, 0}, +{ 8, s_6_98, 95, 1, 0}, +{ 4, s_6_99, -1, 1, 0}, +{ 6, s_6_100, 99, 1, 0}, +{ 6, s_6_101, 99, 1, 0}, +{ 6, s_6_102, 99, 1, 0}, +{ 8, s_6_103, 99, 1, 0}, +{ 8, s_6_104, 99, 1, 0}, +{ 8, s_6_105, 99, 1, 0}, +{ 4, s_6_106, -1, 1, 0}, +{ 5, s_6_107, -1, 1, 0}, +{ 5, s_6_108, -1, 1, 0}, +{ 5, s_6_109, -1, 1, 0}, +{ 5, s_6_110, -1, 1, 0}, +{ 5, s_6_111, -1, 1, 0}, +{ 5, s_6_112, -1, 1, 0}, +{ 5, s_6_113, -1, 1, 0}, +{ 2, s_6_114, -1, 1, 0}, +{ 2, s_6_115, -1, 1, 0}, +{ 2, s_6_116, -1, 1, 0}, +{ 4, s_6_117, -1, 1, 0}, +{ 4, s_6_118, -1, 1, 0}, +{ 4, s_6_119, -1, 1, 0} }; static const symbol s_7_0[1] = { 'a' }; @@ -436,13 +436,13 @@ static const symbol s_7_6[2] = { 0xC3, 0xB3 }; static const struct among a_7[7] = { -/* 0 */ { 1, s_7_0, -1, 1, 0}, -/* 1 */ { 1, s_7_1, -1, 1, 0}, -/* 2 */ { 1, s_7_2, -1, 1, 0}, -/* 3 */ { 2, s_7_3, -1, 1, 0}, -/* 4 */ { 2, s_7_4, -1, 1, 0}, -/* 5 */ { 2, s_7_5, -1, 1, 0}, -/* 6 */ { 2, s_7_6, -1, 1, 0} +{ 1, s_7_0, -1, 1, 0}, +{ 1, s_7_1, -1, 1, 0}, +{ 1, s_7_2, -1, 1, 0}, +{ 2, s_7_3, -1, 1, 0}, +{ 2, s_7_4, -1, 1, 0}, +{ 2, s_7_5, -1, 1, 0}, +{ 2, s_7_6, -1, 1, 0} }; static const symbol s_8_0[1] = { 'e' }; @@ -452,10 +452,10 @@ static const symbol s_8_3[2] = { 0xC3, 0xAA }; static const struct among a_8[4] = { -/* 0 */ { 1, s_8_0, -1, 1, 0}, -/* 1 */ { 2, s_8_1, -1, 2, 0}, -/* 2 */ { 2, s_8_2, -1, 1, 0}, -/* 3 */ { 2, s_8_3, -1, 1, 0} +{ 1, s_8_0, -1, 1, 0}, +{ 2, s_8_1, -1, 2, 0}, +{ 2, s_8_2, -1, 1, 0}, +{ 2, s_8_3, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 19, 12, 2 }; @@ -472,31 +472,30 @@ static const symbol s_8[] = { 'a', 't' }; static const symbol s_9[] = { 'i', 'r' }; static const symbol s_10[] = { 'c' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ +static int r_prelude(struct SN_env * z) { int among_var; -/* repeat, line 36 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 37 */ - if (z->c + 1 >= z->l || (z->p[z->c + 1] != 163 && z->p[z->c + 1] != 181)) among_var = 3; else /* substring, line 37 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 163 && z->p[z->c + 1] != 181)) among_var = 3; else among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 37 */ - switch (among_var) { /* among, line 37 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_0); /* <-, line 38 */ + { int ret = slice_from_s(z, 2, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_1); /* <-, line 39 */ + { int ret = slice_from_s(z, 2, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 40 */ + z->c = ret; } break; } @@ -508,16 +507,16 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 46 */ - z->I[1] = z->l; /* $p1 = , line 47 */ - z->I[2] = z->l; /* $p2 = , line 48 */ - { int c1 = z->c; /* do, line 50 */ - { int c2 = z->c; /* or, line 52 */ - if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ - { int c3 = z->c; /* or, line 51 */ - if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab4; /* non v, line 51 */ - { /* gopast */ /* grouping v, line 51 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab4; + { int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab4; z->c += ret; @@ -525,8 +524,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ - { /* gopast */ /* non v, line 51 */ + if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; + { int ret = in_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab2; z->c += ret; @@ -536,10 +535,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab0; /* non v, line 53 */ - { int c4 = z->c; /* or, line 53 */ - if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab6; /* non v, line 53 */ - { /* gopast */ /* grouping v, line 53 */ + if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab6; + { int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab6; z->c += ret; @@ -547,74 +546,73 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab0; /* grouping v, line 53 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab0; + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 53 */ + z->c = ret; } } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 54 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 56 */ - { /* gopast */ /* grouping v, line 57 */ + { int c5 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 57 */ + { int ret = in_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 57 */ - { /* gopast */ /* grouping v, line 58 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 58 */ + { int ret = in_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 58 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 62 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 63 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else /* substring, line 63 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 63 */ - switch (among_var) { /* among, line 63 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 2, s_2); /* <-, line 64 */ + { int ret = slice_from_s(z, 2, s_2); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_3); /* <-, line 65 */ + { int ret = slice_from_s(z, 2, s_3); if (ret < 0) return ret; } break; case 3: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 66 */ + z->c = ret; } break; } @@ -626,91 +624,91 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 72 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 73 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 74 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 77 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((823330 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 77 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((823330 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_5, 45); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 77 */ - switch (among_var) { /* among, line 77 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 93 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 93 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 98 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_4); /* <-, line 98 */ + { int ret = slice_from_s(z, 3, s_4); if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); /* call R2, line 102 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_5); /* <-, line 102 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 106 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_6); /* <-, line 106 */ + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } break; case 5: - { int ret = r_R1(z); /* call R1, line 110 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ - z->ket = z->c; /* [, line 112 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } /* substring, line 112 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } among_var = find_among_b(z, a_2, 4); if (!(among_var)) { z->c = z->l - m1; goto lab0; } - z->bra = z->c; /* ], line 112 */ - { int ret = r_R2(z); /* call R2, line 112 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 112 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - switch (among_var) { /* among, line 112 */ + switch (among_var) { case 1: - z->ket = z->c; /* [, line 113 */ - if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m1; goto lab0; } /* literal, line 113 */ - z->bra = z->c; /* ], line 113 */ - { int ret = r_R2(z); /* call R2, line 113 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 113 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -720,22 +718,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 6: - { int ret = r_R2(z); /* call R2, line 122 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 122 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 123 */ - z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m2; goto lab1; } /* substring, line 124 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m2; goto lab1; } if (!(find_among_b(z, a_3, 3))) { z->c = z->l - m2; goto lab1; } - z->bra = z->c; /* ], line 124 */ - { int ret = r_R2(z); /* call R2, line 127 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 127 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab1: @@ -743,22 +741,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 7: - { int ret = r_R2(z); /* call R2, line 134 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ - z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } - z->bra = z->c; /* ], line 136 */ - { int ret = r_R2(z); /* call R2, line 139 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab2; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 139 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: @@ -766,21 +764,21 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 146 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 146 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 147 */ - z->ket = z->c; /* [, line 148 */ - if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m4; goto lab3; } /* literal, line 148 */ - z->bra = z->c; /* ], line 148 */ - { int ret = r_R2(z); /* call R2, line 148 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m4; goto lab3; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 148 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab3: @@ -788,12 +786,12 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = r_RV(z); /* call RV, line 153 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 153 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; z->c--; - { int ret = slice_from_s(z, 2, s_9); /* <-, line 154 */ + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; @@ -801,15 +799,15 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 159 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 160 */ - if (!(find_among_b(z, a_6, 120))) { z->lb = mlimit1; return 0; } /* substring, line 160 */ - z->bra = z->c; /* ], line 160 */ - { int ret = slice_del(z); /* delete, line 179 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (!(find_among_b(z, a_6, 120))) { z->lb = mlimit1; return 0; } + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } z->lb = mlimit1; @@ -817,65 +815,65 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 184 */ - if (!(find_among_b(z, a_7, 7))) return 0; /* substring, line 184 */ - z->bra = z->c; /* ], line 184 */ - { int ret = r_RV(z); /* call RV, line 187 */ +static int r_residual_suffix(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_7, 7))) return 0; + z->bra = z->c; + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 187 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_residual_form(struct SN_env * z) { /* backwardmode */ +static int r_residual_form(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 192 */ - among_var = find_among_b(z, a_8, 4); /* substring, line 192 */ + z->ket = z->c; + among_var = find_among_b(z, a_8, 4); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 192 */ - switch (among_var) { /* among, line 192 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 194 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 194 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 194 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 194 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab1; /* literal, line 194 */ + z->ket = z->c; + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab1; z->c--; - z->bra = z->c; /* ], line 194 */ - { int m_test2 = z->l - z->c; /* test, line 194 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'g') goto lab1; /* literal, line 194 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'g') goto lab1; z->c--; z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 195 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; z->c--; - z->bra = z->c; /* ], line 195 */ - { int m_test3 = z->l - z->c; /* test, line 195 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'c') return 0; /* literal, line 195 */ + z->bra = z->c; + { int m_test3 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') return 0; z->c--; z->c = z->l - m_test3; } } lab0: - { int ret = r_RV(z); /* call RV, line 195 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 195 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 196 */ + { int ret = slice_from_s(z, 1, s_10); if (ret < 0) return ret; } break; @@ -883,52 +881,52 @@ static int r_residual_form(struct SN_env * z) { /* backwardmode */ return 1; } -extern int portuguese_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 202 */ - { int ret = r_prelude(z); /* call prelude, line 202 */ +extern int portuguese_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 203 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 203 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 204 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 205 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 209 */ - { int m4 = z->l - z->c; (void)m4; /* and, line 207 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 206 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 206 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab3; lab4: z->c = z->l - m5; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 206 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: z->c = z->l - m4; - { int m6 = z->l - z->c; (void)m6; /* do, line 207 */ - z->ket = z->c; /* [, line 207 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab5; /* literal, line 207 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab5; z->c--; - z->bra = z->c; /* ], line 207 */ - { int m_test7 = z->l - z->c; /* test, line 207 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab5; /* literal, line 207 */ + z->bra = z->c; + { int m_test7 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab5; z->c--; z->c = z->l - m_test7; } - { int ret = r_RV(z); /* call RV, line 207 */ + { int ret = r_RV(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 207 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab5: @@ -938,7 +936,7 @@ extern int portuguese_UTF_8_stem(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = z->l - m3; - { int ret = r_residual_suffix(z); /* call residual_suffix, line 209 */ + { int ret = r_residual_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -947,15 +945,15 @@ extern int portuguese_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m8 = z->l - z->c; (void)m8; /* do, line 211 */ - { int ret = r_residual_form(z); /* call residual_form, line 211 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_residual_form(z); if (ret < 0) return ret; } z->c = z->l - m8; } z->c = z->lb; - { int c9 = z->c; /* do, line 213 */ - { int ret = r_postlude(z); /* call postlude, line 213 */ + { int c9 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c9; @@ -963,7 +961,7 @@ extern int portuguese_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * portuguese_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * portuguese_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void portuguese_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c b/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c index d9594d5cd7c5..55e99f617bcc 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -37,9 +37,9 @@ static const symbol s_0_2[1] = { 'U' }; static const struct among a_0[3] = { -/* 0 */ { 0, 0, -1, 3, 0}, -/* 1 */ { 1, s_0_1, 0, 1, 0}, -/* 2 */ { 1, s_0_2, 0, 2, 0} +{ 0, 0, -1, 3, 0}, +{ 1, s_0_1, 0, 1, 0}, +{ 1, s_0_2, 0, 2, 0} }; static const symbol s_1_0[2] = { 'e', 'a' }; @@ -61,22 +61,22 @@ static const symbol s_1_15[5] = { 'i', 'i', 'l', 'o', 'r' }; static const struct among a_1[16] = { -/* 0 */ { 2, s_1_0, -1, 3, 0}, -/* 1 */ { 5, s_1_1, -1, 7, 0}, -/* 2 */ { 3, s_1_2, -1, 2, 0}, -/* 3 */ { 3, s_1_3, -1, 4, 0}, -/* 4 */ { 5, s_1_4, -1, 7, 0}, -/* 5 */ { 3, s_1_5, -1, 3, 0}, -/* 6 */ { 3, s_1_6, -1, 5, 0}, -/* 7 */ { 4, s_1_7, 6, 4, 0}, -/* 8 */ { 3, s_1_8, -1, 4, 0}, -/* 9 */ { 4, s_1_9, -1, 6, 0}, -/* 10 */ { 2, s_1_10, -1, 4, 0}, -/* 11 */ { 4, s_1_11, -1, 1, 0}, -/* 12 */ { 2, s_1_12, -1, 1, 0}, -/* 13 */ { 4, s_1_13, -1, 3, 0}, -/* 14 */ { 4, s_1_14, -1, 4, 0}, -/* 15 */ { 5, s_1_15, 14, 4, 0} +{ 2, s_1_0, -1, 3, 0}, +{ 5, s_1_1, -1, 7, 0}, +{ 3, s_1_2, -1, 2, 0}, +{ 3, s_1_3, -1, 4, 0}, +{ 5, s_1_4, -1, 7, 0}, +{ 3, s_1_5, -1, 3, 0}, +{ 3, s_1_6, -1, 5, 0}, +{ 4, s_1_7, 6, 4, 0}, +{ 3, s_1_8, -1, 4, 0}, +{ 4, s_1_9, -1, 6, 0}, +{ 2, s_1_10, -1, 4, 0}, +{ 4, s_1_11, -1, 1, 0}, +{ 2, s_1_12, -1, 1, 0}, +{ 4, s_1_13, -1, 3, 0}, +{ 4, s_1_14, -1, 4, 0}, +{ 5, s_1_15, 14, 4, 0} }; static const symbol s_2_0[5] = { 'i', 'c', 'a', 'l', 'a' }; @@ -128,52 +128,52 @@ static const symbol s_2_45[6] = { 'i', 't', 'i', 'v', 0xC4, 0x83 }; static const struct among a_2[46] = { -/* 0 */ { 5, s_2_0, -1, 4, 0}, -/* 1 */ { 5, s_2_1, -1, 4, 0}, -/* 2 */ { 5, s_2_2, -1, 5, 0}, -/* 3 */ { 5, s_2_3, -1, 6, 0}, -/* 4 */ { 5, s_2_4, -1, 4, 0}, -/* 5 */ { 7, s_2_5, -1, 5, 0}, -/* 6 */ { 7, s_2_6, -1, 6, 0}, -/* 7 */ { 6, s_2_7, -1, 5, 0}, -/* 8 */ { 6, s_2_8, -1, 6, 0}, -/* 9 */ { 7, s_2_9, -1, 5, 0}, -/* 10 */ { 7, s_2_10, -1, 4, 0}, -/* 11 */ { 9, s_2_11, -1, 1, 0}, -/* 12 */ { 9, s_2_12, -1, 2, 0}, -/* 13 */ { 7, s_2_13, -1, 3, 0}, -/* 14 */ { 5, s_2_14, -1, 4, 0}, -/* 15 */ { 5, s_2_15, -1, 5, 0}, -/* 16 */ { 5, s_2_16, -1, 6, 0}, -/* 17 */ { 5, s_2_17, -1, 4, 0}, -/* 18 */ { 5, s_2_18, -1, 5, 0}, -/* 19 */ { 7, s_2_19, 18, 4, 0}, -/* 20 */ { 5, s_2_20, -1, 6, 0}, -/* 21 */ { 6, s_2_21, -1, 5, 0}, -/* 22 */ { 7, s_2_22, -1, 4, 0}, -/* 23 */ { 9, s_2_23, -1, 1, 0}, -/* 24 */ { 7, s_2_24, -1, 3, 0}, -/* 25 */ { 5, s_2_25, -1, 4, 0}, -/* 26 */ { 5, s_2_26, -1, 5, 0}, -/* 27 */ { 5, s_2_27, -1, 6, 0}, -/* 28 */ { 7, s_2_28, -1, 4, 0}, -/* 29 */ { 9, s_2_29, -1, 1, 0}, -/* 30 */ { 7, s_2_30, -1, 3, 0}, -/* 31 */ { 9, s_2_31, -1, 4, 0}, -/* 32 */ { 11, s_2_32, -1, 1, 0}, -/* 33 */ { 9, s_2_33, -1, 3, 0}, -/* 34 */ { 4, s_2_34, -1, 4, 0}, -/* 35 */ { 4, s_2_35, -1, 5, 0}, -/* 36 */ { 6, s_2_36, 35, 4, 0}, -/* 37 */ { 4, s_2_37, -1, 6, 0}, -/* 38 */ { 5, s_2_38, -1, 5, 0}, -/* 39 */ { 4, s_2_39, -1, 4, 0}, -/* 40 */ { 4, s_2_40, -1, 5, 0}, -/* 41 */ { 4, s_2_41, -1, 6, 0}, -/* 42 */ { 6, s_2_42, -1, 4, 0}, -/* 43 */ { 6, s_2_43, -1, 4, 0}, -/* 44 */ { 6, s_2_44, -1, 5, 0}, -/* 45 */ { 6, s_2_45, -1, 6, 0} +{ 5, s_2_0, -1, 4, 0}, +{ 5, s_2_1, -1, 4, 0}, +{ 5, s_2_2, -1, 5, 0}, +{ 5, s_2_3, -1, 6, 0}, +{ 5, s_2_4, -1, 4, 0}, +{ 7, s_2_5, -1, 5, 0}, +{ 7, s_2_6, -1, 6, 0}, +{ 6, s_2_7, -1, 5, 0}, +{ 6, s_2_8, -1, 6, 0}, +{ 7, s_2_9, -1, 5, 0}, +{ 7, s_2_10, -1, 4, 0}, +{ 9, s_2_11, -1, 1, 0}, +{ 9, s_2_12, -1, 2, 0}, +{ 7, s_2_13, -1, 3, 0}, +{ 5, s_2_14, -1, 4, 0}, +{ 5, s_2_15, -1, 5, 0}, +{ 5, s_2_16, -1, 6, 0}, +{ 5, s_2_17, -1, 4, 0}, +{ 5, s_2_18, -1, 5, 0}, +{ 7, s_2_19, 18, 4, 0}, +{ 5, s_2_20, -1, 6, 0}, +{ 6, s_2_21, -1, 5, 0}, +{ 7, s_2_22, -1, 4, 0}, +{ 9, s_2_23, -1, 1, 0}, +{ 7, s_2_24, -1, 3, 0}, +{ 5, s_2_25, -1, 4, 0}, +{ 5, s_2_26, -1, 5, 0}, +{ 5, s_2_27, -1, 6, 0}, +{ 7, s_2_28, -1, 4, 0}, +{ 9, s_2_29, -1, 1, 0}, +{ 7, s_2_30, -1, 3, 0}, +{ 9, s_2_31, -1, 4, 0}, +{ 11, s_2_32, -1, 1, 0}, +{ 9, s_2_33, -1, 3, 0}, +{ 4, s_2_34, -1, 4, 0}, +{ 4, s_2_35, -1, 5, 0}, +{ 6, s_2_36, 35, 4, 0}, +{ 4, s_2_37, -1, 6, 0}, +{ 5, s_2_38, -1, 5, 0}, +{ 4, s_2_39, -1, 4, 0}, +{ 4, s_2_40, -1, 5, 0}, +{ 4, s_2_41, -1, 6, 0}, +{ 6, s_2_42, -1, 4, 0}, +{ 6, s_2_43, -1, 4, 0}, +{ 6, s_2_44, -1, 5, 0}, +{ 6, s_2_45, -1, 6, 0} }; static const symbol s_3_0[3] = { 'i', 'c', 'a' }; @@ -241,68 +241,68 @@ static const symbol s_3_61[4] = { 'i', 'v', 0xC4, 0x83 }; static const struct among a_3[62] = { -/* 0 */ { 3, s_3_0, -1, 1, 0}, -/* 1 */ { 5, s_3_1, -1, 1, 0}, -/* 2 */ { 5, s_3_2, -1, 1, 0}, -/* 3 */ { 4, s_3_3, -1, 1, 0}, -/* 4 */ { 3, s_3_4, -1, 1, 0}, -/* 5 */ { 3, s_3_5, -1, 1, 0}, -/* 6 */ { 4, s_3_6, -1, 1, 0}, -/* 7 */ { 4, s_3_7, -1, 3, 0}, -/* 8 */ { 3, s_3_8, -1, 1, 0}, -/* 9 */ { 3, s_3_9, -1, 1, 0}, -/* 10 */ { 2, s_3_10, -1, 1, 0}, -/* 11 */ { 3, s_3_11, -1, 1, 0}, -/* 12 */ { 5, s_3_12, -1, 1, 0}, -/* 13 */ { 5, s_3_13, -1, 1, 0}, -/* 14 */ { 4, s_3_14, -1, 3, 0}, -/* 15 */ { 4, s_3_15, -1, 2, 0}, -/* 16 */ { 4, s_3_16, -1, 1, 0}, -/* 17 */ { 3, s_3_17, -1, 1, 0}, -/* 18 */ { 5, s_3_18, 17, 1, 0}, -/* 19 */ { 3, s_3_19, -1, 1, 0}, -/* 20 */ { 4, s_3_20, -1, 1, 0}, -/* 21 */ { 4, s_3_21, -1, 3, 0}, -/* 22 */ { 3, s_3_22, -1, 1, 0}, -/* 23 */ { 3, s_3_23, -1, 1, 0}, -/* 24 */ { 3, s_3_24, -1, 1, 0}, -/* 25 */ { 5, s_3_25, -1, 1, 0}, -/* 26 */ { 5, s_3_26, -1, 1, 0}, -/* 27 */ { 4, s_3_27, -1, 2, 0}, -/* 28 */ { 5, s_3_28, -1, 1, 0}, -/* 29 */ { 3, s_3_29, -1, 1, 0}, -/* 30 */ { 3, s_3_30, -1, 1, 0}, -/* 31 */ { 5, s_3_31, 30, 1, 0}, -/* 32 */ { 3, s_3_32, -1, 1, 0}, -/* 33 */ { 4, s_3_33, -1, 1, 0}, -/* 34 */ { 4, s_3_34, -1, 3, 0}, -/* 35 */ { 3, s_3_35, -1, 1, 0}, -/* 36 */ { 5, s_3_36, -1, 3, 0}, -/* 37 */ { 3, s_3_37, -1, 1, 0}, -/* 38 */ { 5, s_3_38, -1, 1, 0}, -/* 39 */ { 4, s_3_39, -1, 1, 0}, -/* 40 */ { 7, s_3_40, -1, 1, 0}, -/* 41 */ { 4, s_3_41, -1, 1, 0}, -/* 42 */ { 4, s_3_42, -1, 1, 0}, -/* 43 */ { 3, s_3_43, -1, 3, 0}, -/* 44 */ { 4, s_3_44, -1, 1, 0}, -/* 45 */ { 2, s_3_45, -1, 1, 0}, -/* 46 */ { 2, s_3_46, -1, 1, 0}, -/* 47 */ { 2, s_3_47, -1, 1, 0}, -/* 48 */ { 3, s_3_48, -1, 1, 0}, -/* 49 */ { 3, s_3_49, -1, 3, 0}, -/* 50 */ { 2, s_3_50, -1, 1, 0}, -/* 51 */ { 2, s_3_51, -1, 1, 0}, -/* 52 */ { 4, s_3_52, -1, 1, 0}, -/* 53 */ { 6, s_3_53, -1, 1, 0}, -/* 54 */ { 6, s_3_54, -1, 1, 0}, -/* 55 */ { 5, s_3_55, -1, 1, 0}, -/* 56 */ { 4, s_3_56, -1, 1, 0}, -/* 57 */ { 4, s_3_57, -1, 1, 0}, -/* 58 */ { 5, s_3_58, -1, 1, 0}, -/* 59 */ { 5, s_3_59, -1, 3, 0}, -/* 60 */ { 4, s_3_60, -1, 1, 0}, -/* 61 */ { 4, s_3_61, -1, 1, 0} +{ 3, s_3_0, -1, 1, 0}, +{ 5, s_3_1, -1, 1, 0}, +{ 5, s_3_2, -1, 1, 0}, +{ 4, s_3_3, -1, 1, 0}, +{ 3, s_3_4, -1, 1, 0}, +{ 3, s_3_5, -1, 1, 0}, +{ 4, s_3_6, -1, 1, 0}, +{ 4, s_3_7, -1, 3, 0}, +{ 3, s_3_8, -1, 1, 0}, +{ 3, s_3_9, -1, 1, 0}, +{ 2, s_3_10, -1, 1, 0}, +{ 3, s_3_11, -1, 1, 0}, +{ 5, s_3_12, -1, 1, 0}, +{ 5, s_3_13, -1, 1, 0}, +{ 4, s_3_14, -1, 3, 0}, +{ 4, s_3_15, -1, 2, 0}, +{ 4, s_3_16, -1, 1, 0}, +{ 3, s_3_17, -1, 1, 0}, +{ 5, s_3_18, 17, 1, 0}, +{ 3, s_3_19, -1, 1, 0}, +{ 4, s_3_20, -1, 1, 0}, +{ 4, s_3_21, -1, 3, 0}, +{ 3, s_3_22, -1, 1, 0}, +{ 3, s_3_23, -1, 1, 0}, +{ 3, s_3_24, -1, 1, 0}, +{ 5, s_3_25, -1, 1, 0}, +{ 5, s_3_26, -1, 1, 0}, +{ 4, s_3_27, -1, 2, 0}, +{ 5, s_3_28, -1, 1, 0}, +{ 3, s_3_29, -1, 1, 0}, +{ 3, s_3_30, -1, 1, 0}, +{ 5, s_3_31, 30, 1, 0}, +{ 3, s_3_32, -1, 1, 0}, +{ 4, s_3_33, -1, 1, 0}, +{ 4, s_3_34, -1, 3, 0}, +{ 3, s_3_35, -1, 1, 0}, +{ 5, s_3_36, -1, 3, 0}, +{ 3, s_3_37, -1, 1, 0}, +{ 5, s_3_38, -1, 1, 0}, +{ 4, s_3_39, -1, 1, 0}, +{ 7, s_3_40, -1, 1, 0}, +{ 4, s_3_41, -1, 1, 0}, +{ 4, s_3_42, -1, 1, 0}, +{ 3, s_3_43, -1, 3, 0}, +{ 4, s_3_44, -1, 1, 0}, +{ 2, s_3_45, -1, 1, 0}, +{ 2, s_3_46, -1, 1, 0}, +{ 2, s_3_47, -1, 1, 0}, +{ 3, s_3_48, -1, 1, 0}, +{ 3, s_3_49, -1, 3, 0}, +{ 2, s_3_50, -1, 1, 0}, +{ 2, s_3_51, -1, 1, 0}, +{ 4, s_3_52, -1, 1, 0}, +{ 6, s_3_53, -1, 1, 0}, +{ 6, s_3_54, -1, 1, 0}, +{ 5, s_3_55, -1, 1, 0}, +{ 4, s_3_56, -1, 1, 0}, +{ 4, s_3_57, -1, 1, 0}, +{ 5, s_3_58, -1, 1, 0}, +{ 5, s_3_59, -1, 3, 0}, +{ 4, s_3_60, -1, 1, 0}, +{ 4, s_3_61, -1, 1, 0} }; static const symbol s_4_0[2] = { 'e', 'a' }; @@ -402,100 +402,100 @@ static const symbol s_4_93[5] = { 'e', 'a', 'z', 0xC4, 0x83 }; static const struct among a_4[94] = { -/* 0 */ { 2, s_4_0, -1, 1, 0}, -/* 1 */ { 2, s_4_1, -1, 1, 0}, -/* 2 */ { 3, s_4_2, -1, 1, 0}, -/* 3 */ { 4, s_4_3, -1, 1, 0}, -/* 4 */ { 3, s_4_4, -1, 1, 0}, -/* 5 */ { 4, s_4_5, -1, 1, 0}, -/* 6 */ { 3, s_4_6, -1, 1, 0}, -/* 7 */ { 3, s_4_7, -1, 1, 0}, -/* 8 */ { 3, s_4_8, -1, 1, 0}, -/* 9 */ { 4, s_4_9, -1, 1, 0}, -/* 10 */ { 2, s_4_10, -1, 2, 0}, -/* 11 */ { 3, s_4_11, 10, 1, 0}, -/* 12 */ { 4, s_4_12, 10, 2, 0}, -/* 13 */ { 3, s_4_13, 10, 1, 0}, -/* 14 */ { 3, s_4_14, 10, 1, 0}, -/* 15 */ { 4, s_4_15, 10, 1, 0}, -/* 16 */ { 5, s_4_16, -1, 1, 0}, -/* 17 */ { 6, s_4_17, -1, 1, 0}, -/* 18 */ { 3, s_4_18, -1, 1, 0}, -/* 19 */ { 2, s_4_19, -1, 1, 0}, -/* 20 */ { 3, s_4_20, 19, 1, 0}, -/* 21 */ { 3, s_4_21, 19, 1, 0}, -/* 22 */ { 3, s_4_22, -1, 2, 0}, -/* 23 */ { 5, s_4_23, -1, 1, 0}, -/* 24 */ { 6, s_4_24, -1, 1, 0}, -/* 25 */ { 2, s_4_25, -1, 1, 0}, -/* 26 */ { 3, s_4_26, -1, 1, 0}, -/* 27 */ { 4, s_4_27, -1, 1, 0}, -/* 28 */ { 5, s_4_28, -1, 2, 0}, -/* 29 */ { 6, s_4_29, 28, 1, 0}, -/* 30 */ { 7, s_4_30, 28, 2, 0}, -/* 31 */ { 6, s_4_31, 28, 1, 0}, -/* 32 */ { 6, s_4_32, 28, 1, 0}, -/* 33 */ { 7, s_4_33, 28, 1, 0}, -/* 34 */ { 4, s_4_34, -1, 1, 0}, -/* 35 */ { 4, s_4_35, -1, 1, 0}, -/* 36 */ { 5, s_4_36, -1, 1, 0}, -/* 37 */ { 3, s_4_37, -1, 1, 0}, -/* 38 */ { 4, s_4_38, -1, 2, 0}, -/* 39 */ { 5, s_4_39, 38, 1, 0}, -/* 40 */ { 5, s_4_40, 38, 1, 0}, -/* 41 */ { 4, s_4_41, -1, 2, 0}, -/* 42 */ { 4, s_4_42, -1, 2, 0}, -/* 43 */ { 7, s_4_43, -1, 1, 0}, -/* 44 */ { 8, s_4_44, -1, 2, 0}, -/* 45 */ { 9, s_4_45, 44, 1, 0}, -/* 46 */ { 10, s_4_46, 44, 2, 0}, -/* 47 */ { 9, s_4_47, 44, 1, 0}, -/* 48 */ { 9, s_4_48, 44, 1, 0}, -/* 49 */ { 10, s_4_49, 44, 1, 0}, -/* 50 */ { 7, s_4_50, -1, 1, 0}, -/* 51 */ { 7, s_4_51, -1, 1, 0}, -/* 52 */ { 8, s_4_52, -1, 1, 0}, -/* 53 */ { 5, s_4_53, -1, 2, 0}, -/* 54 */ { 2, s_4_54, -1, 1, 0}, -/* 55 */ { 3, s_4_55, 54, 1, 0}, -/* 56 */ { 3, s_4_56, 54, 1, 0}, -/* 57 */ { 2, s_4_57, -1, 2, 0}, -/* 58 */ { 4, s_4_58, 57, 1, 0}, -/* 59 */ { 5, s_4_59, 57, 2, 0}, -/* 60 */ { 4, s_4_60, 57, 1, 0}, -/* 61 */ { 4, s_4_61, 57, 1, 0}, -/* 62 */ { 5, s_4_62, 57, 1, 0}, -/* 63 */ { 2, s_4_63, -1, 2, 0}, -/* 64 */ { 3, s_4_64, -1, 2, 0}, -/* 65 */ { 5, s_4_65, 64, 1, 0}, -/* 66 */ { 6, s_4_66, 64, 2, 0}, -/* 67 */ { 7, s_4_67, 66, 1, 0}, -/* 68 */ { 8, s_4_68, 66, 2, 0}, -/* 69 */ { 7, s_4_69, 66, 1, 0}, -/* 70 */ { 7, s_4_70, 66, 1, 0}, -/* 71 */ { 8, s_4_71, 66, 1, 0}, -/* 72 */ { 5, s_4_72, 64, 1, 0}, -/* 73 */ { 5, s_4_73, 64, 1, 0}, -/* 74 */ { 6, s_4_74, 64, 1, 0}, -/* 75 */ { 3, s_4_75, -1, 2, 0}, -/* 76 */ { 2, s_4_76, -1, 1, 0}, -/* 77 */ { 3, s_4_77, 76, 1, 0}, -/* 78 */ { 3, s_4_78, 76, 1, 0}, -/* 79 */ { 4, s_4_79, -1, 1, 0}, -/* 80 */ { 5, s_4_80, -1, 1, 0}, -/* 81 */ { 2, s_4_81, -1, 1, 0}, -/* 82 */ { 6, s_4_82, -1, 1, 0}, -/* 83 */ { 4, s_4_83, -1, 1, 0}, -/* 84 */ { 5, s_4_84, -1, 2, 0}, -/* 85 */ { 6, s_4_85, 84, 1, 0}, -/* 86 */ { 7, s_4_86, 84, 2, 0}, -/* 87 */ { 6, s_4_87, 84, 1, 0}, -/* 88 */ { 6, s_4_88, 84, 1, 0}, -/* 89 */ { 7, s_4_89, 84, 1, 0}, -/* 90 */ { 4, s_4_90, -1, 1, 0}, -/* 91 */ { 4, s_4_91, -1, 1, 0}, -/* 92 */ { 5, s_4_92, -1, 1, 0}, -/* 93 */ { 5, s_4_93, -1, 1, 0} +{ 2, s_4_0, -1, 1, 0}, +{ 2, s_4_1, -1, 1, 0}, +{ 3, s_4_2, -1, 1, 0}, +{ 4, s_4_3, -1, 1, 0}, +{ 3, s_4_4, -1, 1, 0}, +{ 4, s_4_5, -1, 1, 0}, +{ 3, s_4_6, -1, 1, 0}, +{ 3, s_4_7, -1, 1, 0}, +{ 3, s_4_8, -1, 1, 0}, +{ 4, s_4_9, -1, 1, 0}, +{ 2, s_4_10, -1, 2, 0}, +{ 3, s_4_11, 10, 1, 0}, +{ 4, s_4_12, 10, 2, 0}, +{ 3, s_4_13, 10, 1, 0}, +{ 3, s_4_14, 10, 1, 0}, +{ 4, s_4_15, 10, 1, 0}, +{ 5, s_4_16, -1, 1, 0}, +{ 6, s_4_17, -1, 1, 0}, +{ 3, s_4_18, -1, 1, 0}, +{ 2, s_4_19, -1, 1, 0}, +{ 3, s_4_20, 19, 1, 0}, +{ 3, s_4_21, 19, 1, 0}, +{ 3, s_4_22, -1, 2, 0}, +{ 5, s_4_23, -1, 1, 0}, +{ 6, s_4_24, -1, 1, 0}, +{ 2, s_4_25, -1, 1, 0}, +{ 3, s_4_26, -1, 1, 0}, +{ 4, s_4_27, -1, 1, 0}, +{ 5, s_4_28, -1, 2, 0}, +{ 6, s_4_29, 28, 1, 0}, +{ 7, s_4_30, 28, 2, 0}, +{ 6, s_4_31, 28, 1, 0}, +{ 6, s_4_32, 28, 1, 0}, +{ 7, s_4_33, 28, 1, 0}, +{ 4, s_4_34, -1, 1, 0}, +{ 4, s_4_35, -1, 1, 0}, +{ 5, s_4_36, -1, 1, 0}, +{ 3, s_4_37, -1, 1, 0}, +{ 4, s_4_38, -1, 2, 0}, +{ 5, s_4_39, 38, 1, 0}, +{ 5, s_4_40, 38, 1, 0}, +{ 4, s_4_41, -1, 2, 0}, +{ 4, s_4_42, -1, 2, 0}, +{ 7, s_4_43, -1, 1, 0}, +{ 8, s_4_44, -1, 2, 0}, +{ 9, s_4_45, 44, 1, 0}, +{ 10, s_4_46, 44, 2, 0}, +{ 9, s_4_47, 44, 1, 0}, +{ 9, s_4_48, 44, 1, 0}, +{ 10, s_4_49, 44, 1, 0}, +{ 7, s_4_50, -1, 1, 0}, +{ 7, s_4_51, -1, 1, 0}, +{ 8, s_4_52, -1, 1, 0}, +{ 5, s_4_53, -1, 2, 0}, +{ 2, s_4_54, -1, 1, 0}, +{ 3, s_4_55, 54, 1, 0}, +{ 3, s_4_56, 54, 1, 0}, +{ 2, s_4_57, -1, 2, 0}, +{ 4, s_4_58, 57, 1, 0}, +{ 5, s_4_59, 57, 2, 0}, +{ 4, s_4_60, 57, 1, 0}, +{ 4, s_4_61, 57, 1, 0}, +{ 5, s_4_62, 57, 1, 0}, +{ 2, s_4_63, -1, 2, 0}, +{ 3, s_4_64, -1, 2, 0}, +{ 5, s_4_65, 64, 1, 0}, +{ 6, s_4_66, 64, 2, 0}, +{ 7, s_4_67, 66, 1, 0}, +{ 8, s_4_68, 66, 2, 0}, +{ 7, s_4_69, 66, 1, 0}, +{ 7, s_4_70, 66, 1, 0}, +{ 8, s_4_71, 66, 1, 0}, +{ 5, s_4_72, 64, 1, 0}, +{ 5, s_4_73, 64, 1, 0}, +{ 6, s_4_74, 64, 1, 0}, +{ 3, s_4_75, -1, 2, 0}, +{ 2, s_4_76, -1, 1, 0}, +{ 3, s_4_77, 76, 1, 0}, +{ 3, s_4_78, 76, 1, 0}, +{ 4, s_4_79, -1, 1, 0}, +{ 5, s_4_80, -1, 1, 0}, +{ 2, s_4_81, -1, 1, 0}, +{ 6, s_4_82, -1, 1, 0}, +{ 4, s_4_83, -1, 1, 0}, +{ 5, s_4_84, -1, 2, 0}, +{ 6, s_4_85, 84, 1, 0}, +{ 7, s_4_86, 84, 2, 0}, +{ 6, s_4_87, 84, 1, 0}, +{ 6, s_4_88, 84, 1, 0}, +{ 7, s_4_89, 84, 1, 0}, +{ 4, s_4_90, -1, 1, 0}, +{ 4, s_4_91, -1, 1, 0}, +{ 5, s_4_92, -1, 1, 0}, +{ 5, s_4_93, -1, 1, 0} }; static const symbol s_5_0[1] = { 'a' }; @@ -506,11 +506,11 @@ static const symbol s_5_4[2] = { 0xC4, 0x83 }; static const struct among a_5[5] = { -/* 0 */ { 1, s_5_0, -1, 1, 0}, -/* 1 */ { 1, s_5_1, -1, 1, 0}, -/* 2 */ { 2, s_5_2, 1, 1, 0}, -/* 3 */ { 1, s_5_3, -1, 1, 0}, -/* 4 */ { 2, s_5_4, -1, 1, 0} +{ 1, s_5_0, -1, 1, 0}, +{ 1, s_5_1, -1, 1, 0}, +{ 2, s_5_2, 1, 1, 0}, +{ 1, s_5_3, -1, 1, 0}, +{ 2, s_5_4, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 4 }; @@ -536,30 +536,29 @@ static const symbol s_17[] = { 0xC5, 0xA3 }; static const symbol s_18[] = { 't' }; static const symbol s_19[] = { 'i', 's', 't' }; -static int r_prelude(struct SN_env * z) { /* forwardmode */ -/* repeat, line 32 */ - - while(1) { int c1 = z->c; - while(1) { /* goto, line 32 */ +static int r_prelude(struct SN_env * z) { + while(1) { + int c1 = z->c; + while(1) { int c2 = z->c; - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; /* grouping v, line 33 */ - z->bra = z->c; /* [, line 33 */ - { int c3 = z->c; /* or, line 33 */ - if (z->c == z->l || z->p[z->c] != 'u') goto lab3; /* literal, line 33 */ + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; + z->bra = z->c; + { int c3 = z->c; + if (z->c == z->l || z->p[z->c] != 'u') goto lab3; z->c++; - z->ket = z->c; /* ], line 33 */ - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab3; /* grouping v, line 33 */ - { int ret = slice_from_s(z, 1, s_0); /* <-, line 33 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab3; + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } goto lab2; lab3: z->c = c3; - if (z->c == z->l || z->p[z->c] != 'i') goto lab1; /* literal, line 34 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab1; z->c++; - z->ket = z->c; /* ], line 34 */ - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; /* grouping v, line 34 */ - { int ret = slice_from_s(z, 1, s_1); /* <-, line 34 */ + z->ket = z->c; + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } } @@ -568,9 +567,9 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ break; lab1: z->c = c2; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* goto, line 32 */ + z->c = ret; } } continue; @@ -581,16 +580,16 @@ static int r_prelude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 40 */ - z->I[1] = z->l; /* $p1 = , line 41 */ - z->I[2] = z->l; /* $p2 = , line 42 */ - { int c1 = z->c; /* do, line 44 */ - { int c2 = z->c; /* or, line 46 */ - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; /* grouping v, line 45 */ - { int c3 = z->c; /* or, line 45 */ - if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab4; /* non v, line 45 */ - { /* gopast */ /* grouping v, line 45 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab4; + { int ret = out_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab4; z->c += ret; @@ -598,8 +597,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; /* grouping v, line 45 */ - { /* gopast */ /* non v, line 45 */ + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; + { int ret = in_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab2; z->c += ret; @@ -609,10 +608,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab0; /* non v, line 47 */ - { int c4 = z->c; /* or, line 47 */ - if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab6; /* non v, line 47 */ - { /* gopast */ /* grouping v, line 47 */ + if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab6; + { int ret = out_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab6; z->c += ret; @@ -620,74 +619,73 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab0; /* grouping v, line 47 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab0; + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 47 */ + z->c = ret; } } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 48 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 50 */ - { /* gopast */ /* grouping v, line 51 */ + { int c5 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 51 */ + { int ret = in_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 51 */ - { /* gopast */ /* grouping v, line 52 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 52 */ + { int ret = in_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 52 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 56 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 58 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 58 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 58 */ - switch (among_var) { /* among, line 58 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 59 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 3: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 61 */ + z->c = ret; } break; } @@ -699,70 +697,70 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 68 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 69 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 70 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_step_0(struct SN_env * z) { /* backwardmode */ +static int r_step_0(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 73 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 73 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_1, 16); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 73 */ - { int ret = r_R1(z); /* call R1, line 73 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 73 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 75 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 77 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 81 */ + { int ret = slice_from_s(z, 1, s_6); if (ret < 0) return ret; } break; case 5: - { int m1 = z->l - z->c; (void)m1; /* not, line 83 */ - if (!(eq_s_b(z, 2, s_7))) goto lab0; /* literal, line 83 */ + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 2, s_7))) goto lab0; return 0; lab0: z->c = z->l - m1; } - { int ret = slice_from_s(z, 1, s_8); /* <-, line 83 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_9); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 4, s_10); /* <-, line 87 */ + { int ret = slice_from_s(z, 4, s_10); if (ret < 0) return ret; } break; @@ -770,61 +768,60 @@ static int r_step_0(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_combo_suffix(struct SN_env * z) { /* backwardmode */ +static int r_combo_suffix(struct SN_env * z) { int among_var; - { int m_test1 = z->l - z->c; /* test, line 91 */ - z->ket = z->c; /* [, line 92 */ - among_var = find_among_b(z, a_2, 46); /* substring, line 92 */ + { int m_test1 = z->l - z->c; + z->ket = z->c; + among_var = find_among_b(z, a_2, 46); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 92 */ - { int ret = r_R1(z); /* call R1, line 92 */ + z->bra = z->c; + { int ret = r_R1(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 93 */ + switch (among_var) { case 1: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_11); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_13); /* <-, line 107 */ + { int ret = slice_from_s(z, 2, s_13); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_14); /* <-, line 113 */ + { int ret = slice_from_s(z, 2, s_14); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 2, s_15); /* <-, line 118 */ + { int ret = slice_from_s(z, 2, s_15); if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 122 */ + { int ret = slice_from_s(z, 2, s_16); if (ret < 0) return ret; } break; } - z->B[0] = 1; /* set standard_suffix_removed, line 125 */ + z->I[3] = 1; z->c = z->l - m_test1; } return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->B[0] = 0; /* unset standard_suffix_removed, line 130 */ -/* repeat, line 131 */ - - while(1) { int m1 = z->l - z->c; (void)m1; - { int ret = r_combo_suffix(z); /* call combo_suffix, line 131 */ + z->I[3] = 0; + while(1) { + int m1 = z->l - z->c; (void)m1; + { int ret = r_combo_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -833,63 +830,63 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ z->c = z->l - m1; break; } - z->ket = z->c; /* [, line 132 */ - among_var = find_among_b(z, a_3, 62); /* substring, line 132 */ + z->ket = z->c; + among_var = find_among_b(z, a_3, 62); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 132 */ - { int ret = r_R2(z); /* call R2, line 132 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 133 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 149 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(eq_s_b(z, 2, s_17))) return 0; /* literal, line 152 */ - z->bra = z->c; /* ], line 152 */ - { int ret = slice_from_s(z, 1, s_18); /* <-, line 152 */ + if (!(eq_s_b(z, 2, s_17))) return 0; + z->bra = z->c; + { int ret = slice_from_s(z, 1, s_18); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_19); /* <-, line 156 */ + { int ret = slice_from_s(z, 3, s_19); if (ret < 0) return ret; } break; } - z->B[0] = 1; /* set standard_suffix_removed, line 160 */ + z->I[3] = 1; return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 164 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 165 */ - among_var = find_among_b(z, a_4, 94); /* substring, line 165 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + among_var = find_among_b(z, a_4, 94); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 165 */ - switch (among_var) { /* among, line 165 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* or, line 200 */ - if (out_grouping_b_U(z, g_v, 97, 259, 0)) goto lab1; /* non v, line 200 */ + { int m2 = z->l - z->c; (void)m2; + if (out_grouping_b_U(z, g_v, 97, 259, 0)) goto lab1; goto lab0; lab1: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->lb = mlimit1; return 0; } /* literal, line 200 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->lb = mlimit1; return 0; } z->c--; } lab0: - { int ret = slice_del(z); /* delete, line 200 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 214 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -899,51 +896,51 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 219 */ - if (!(find_among_b(z, a_5, 5))) return 0; /* substring, line 219 */ - z->bra = z->c; /* ], line 219 */ - { int ret = r_RV(z); /* call RV, line 219 */ +static int r_vowel_suffix(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_5, 5))) return 0; + z->bra = z->c; + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 220 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -extern int romanian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 226 */ - { int ret = r_prelude(z); /* call prelude, line 226 */ +extern int romanian_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_prelude(z); if (ret < 0) return ret; } z->c = c1; } - /* do, line 227 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 227 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 228 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 229 */ - { int ret = r_step_0(z); /* call step_0, line 229 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_step_0(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 230 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 230 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_standard_suffix(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 231 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 231 */ - if (!(z->B[0])) goto lab2; /* Boolean test standard_suffix_removed, line 231 */ + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + if (!(z->I[3])) goto lab2; goto lab1; lab2: z->c = z->l - m5; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 231 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -952,15 +949,15 @@ extern int romanian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m4; } - { int m6 = z->l - z->c; (void)m6; /* do, line 232 */ - { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 232 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_vowel_suffix(z); if (ret < 0) return ret; } z->c = z->l - m6; } z->c = z->lb; - { int c7 = z->c; /* do, line 234 */ - { int ret = r_postlude(z); /* call postlude, line 234 */ + { int c7 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c7; @@ -968,7 +965,7 @@ extern int romanian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * romanian_UTF_8_create_env(void) { return SN_create_env(0, 3, 1); } +extern struct SN_env * romanian_UTF_8_create_env(void) { return SN_create_env(0, 4); } extern void romanian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_russian.c b/src/backend/snowball/libstemmer/stem_UTF_8_russian.c index fb69a847cf4e..2bbf14441c93 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_russian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_russian.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -43,15 +43,15 @@ static const symbol s_0_8[8] = { 0xD0, 0xB8, 0xD0, 0xB2, 0xD1, 0x88, 0xD0, 0xB8 static const struct among a_0[9] = { -/* 0 */ { 10, s_0_0, -1, 1, 0}, -/* 1 */ { 12, s_0_1, 0, 2, 0}, -/* 2 */ { 12, s_0_2, 0, 2, 0}, -/* 3 */ { 2, s_0_3, -1, 1, 0}, -/* 4 */ { 4, s_0_4, 3, 2, 0}, -/* 5 */ { 4, s_0_5, 3, 2, 0}, -/* 6 */ { 6, s_0_6, -1, 1, 0}, -/* 7 */ { 8, s_0_7, 6, 2, 0}, -/* 8 */ { 8, s_0_8, 6, 2, 0} +{ 10, s_0_0, -1, 1, 0}, +{ 12, s_0_1, 0, 2, 0}, +{ 12, s_0_2, 0, 2, 0}, +{ 2, s_0_3, -1, 1, 0}, +{ 4, s_0_4, 3, 2, 0}, +{ 4, s_0_5, 3, 2, 0}, +{ 6, s_0_6, -1, 1, 0}, +{ 8, s_0_7, 6, 2, 0}, +{ 8, s_0_8, 6, 2, 0} }; static const symbol s_1_0[6] = { 0xD0, 0xB5, 0xD0, 0xBC, 0xD1, 0x83 }; @@ -83,32 +83,32 @@ static const symbol s_1_25[6] = { 0xD0, 0xBE, 0xD0, 0xB3, 0xD0, 0xBE }; static const struct among a_1[26] = { -/* 0 */ { 6, s_1_0, -1, 1, 0}, -/* 1 */ { 6, s_1_1, -1, 1, 0}, -/* 2 */ { 4, s_1_2, -1, 1, 0}, -/* 3 */ { 4, s_1_3, -1, 1, 0}, -/* 4 */ { 4, s_1_4, -1, 1, 0}, -/* 5 */ { 4, s_1_5, -1, 1, 0}, -/* 6 */ { 4, s_1_6, -1, 1, 0}, -/* 7 */ { 4, s_1_7, -1, 1, 0}, -/* 8 */ { 4, s_1_8, -1, 1, 0}, -/* 9 */ { 4, s_1_9, -1, 1, 0}, -/* 10 */ { 4, s_1_10, -1, 1, 0}, -/* 11 */ { 4, s_1_11, -1, 1, 0}, -/* 12 */ { 4, s_1_12, -1, 1, 0}, -/* 13 */ { 4, s_1_13, -1, 1, 0}, -/* 14 */ { 6, s_1_14, -1, 1, 0}, -/* 15 */ { 6, s_1_15, -1, 1, 0}, -/* 16 */ { 4, s_1_16, -1, 1, 0}, -/* 17 */ { 4, s_1_17, -1, 1, 0}, -/* 18 */ { 4, s_1_18, -1, 1, 0}, -/* 19 */ { 4, s_1_19, -1, 1, 0}, -/* 20 */ { 4, s_1_20, -1, 1, 0}, -/* 21 */ { 4, s_1_21, -1, 1, 0}, -/* 22 */ { 4, s_1_22, -1, 1, 0}, -/* 23 */ { 4, s_1_23, -1, 1, 0}, -/* 24 */ { 6, s_1_24, -1, 1, 0}, -/* 25 */ { 6, s_1_25, -1, 1, 0} +{ 6, s_1_0, -1, 1, 0}, +{ 6, s_1_1, -1, 1, 0}, +{ 4, s_1_2, -1, 1, 0}, +{ 4, s_1_3, -1, 1, 0}, +{ 4, s_1_4, -1, 1, 0}, +{ 4, s_1_5, -1, 1, 0}, +{ 4, s_1_6, -1, 1, 0}, +{ 4, s_1_7, -1, 1, 0}, +{ 4, s_1_8, -1, 1, 0}, +{ 4, s_1_9, -1, 1, 0}, +{ 4, s_1_10, -1, 1, 0}, +{ 4, s_1_11, -1, 1, 0}, +{ 4, s_1_12, -1, 1, 0}, +{ 4, s_1_13, -1, 1, 0}, +{ 6, s_1_14, -1, 1, 0}, +{ 6, s_1_15, -1, 1, 0}, +{ 4, s_1_16, -1, 1, 0}, +{ 4, s_1_17, -1, 1, 0}, +{ 4, s_1_18, -1, 1, 0}, +{ 4, s_1_19, -1, 1, 0}, +{ 4, s_1_20, -1, 1, 0}, +{ 4, s_1_21, -1, 1, 0}, +{ 4, s_1_22, -1, 1, 0}, +{ 4, s_1_23, -1, 1, 0}, +{ 6, s_1_24, -1, 1, 0}, +{ 6, s_1_25, -1, 1, 0} }; static const symbol s_2_0[4] = { 0xD0, 0xB2, 0xD1, 0x88 }; @@ -122,14 +122,14 @@ static const symbol s_2_7[4] = { 0xD0, 0xBD, 0xD0, 0xBD }; static const struct among a_2[8] = { -/* 0 */ { 4, s_2_0, -1, 1, 0}, -/* 1 */ { 6, s_2_1, 0, 2, 0}, -/* 2 */ { 6, s_2_2, 0, 2, 0}, -/* 3 */ { 2, s_2_3, -1, 1, 0}, -/* 4 */ { 4, s_2_4, 3, 1, 0}, -/* 5 */ { 6, s_2_5, 4, 2, 0}, -/* 6 */ { 4, s_2_6, -1, 1, 0}, -/* 7 */ { 4, s_2_7, -1, 1, 0} +{ 4, s_2_0, -1, 1, 0}, +{ 6, s_2_1, 0, 2, 0}, +{ 6, s_2_2, 0, 2, 0}, +{ 2, s_2_3, -1, 1, 0}, +{ 4, s_2_4, 3, 1, 0}, +{ 6, s_2_5, 4, 2, 0}, +{ 4, s_2_6, -1, 1, 0}, +{ 4, s_2_7, -1, 1, 0} }; static const symbol s_3_0[4] = { 0xD1, 0x81, 0xD1, 0x8C }; @@ -137,8 +137,8 @@ static const symbol s_3_1[4] = { 0xD1, 0x81, 0xD1, 0x8F }; static const struct among a_3[2] = { -/* 0 */ { 4, s_3_0, -1, 1, 0}, -/* 1 */ { 4, s_3_1, -1, 1, 0} +{ 4, s_3_0, -1, 1, 0}, +{ 4, s_3_1, -1, 1, 0} }; static const symbol s_4_0[4] = { 0xD1, 0x8B, 0xD1, 0x82 }; @@ -190,52 +190,52 @@ static const symbol s_4_45[6] = { 0xD0, 0xBD, 0xD0, 0xBD, 0xD0, 0xBE }; static const struct among a_4[46] = { -/* 0 */ { 4, s_4_0, -1, 2, 0}, -/* 1 */ { 4, s_4_1, -1, 1, 0}, -/* 2 */ { 6, s_4_2, 1, 2, 0}, -/* 3 */ { 4, s_4_3, -1, 2, 0}, -/* 4 */ { 4, s_4_4, -1, 1, 0}, -/* 5 */ { 6, s_4_5, 4, 2, 0}, -/* 6 */ { 4, s_4_6, -1, 2, 0}, -/* 7 */ { 4, s_4_7, -1, 1, 0}, -/* 8 */ { 6, s_4_8, 7, 2, 0}, -/* 9 */ { 4, s_4_9, -1, 1, 0}, -/* 10 */ { 6, s_4_10, 9, 2, 0}, -/* 11 */ { 6, s_4_11, 9, 2, 0}, -/* 12 */ { 6, s_4_12, -1, 1, 0}, -/* 13 */ { 6, s_4_13, -1, 2, 0}, -/* 14 */ { 2, s_4_14, -1, 2, 0}, -/* 15 */ { 4, s_4_15, 14, 2, 0}, -/* 16 */ { 4, s_4_16, -1, 1, 0}, -/* 17 */ { 6, s_4_17, 16, 2, 0}, -/* 18 */ { 6, s_4_18, 16, 2, 0}, -/* 19 */ { 4, s_4_19, -1, 1, 0}, -/* 20 */ { 6, s_4_20, 19, 2, 0}, -/* 21 */ { 6, s_4_21, -1, 1, 0}, -/* 22 */ { 6, s_4_22, -1, 2, 0}, -/* 23 */ { 6, s_4_23, -1, 1, 0}, -/* 24 */ { 8, s_4_24, 23, 2, 0}, -/* 25 */ { 8, s_4_25, 23, 2, 0}, -/* 26 */ { 4, s_4_26, -1, 1, 0}, -/* 27 */ { 6, s_4_27, 26, 2, 0}, -/* 28 */ { 6, s_4_28, 26, 2, 0}, -/* 29 */ { 2, s_4_29, -1, 1, 0}, -/* 30 */ { 4, s_4_30, 29, 2, 0}, -/* 31 */ { 4, s_4_31, 29, 2, 0}, -/* 32 */ { 2, s_4_32, -1, 1, 0}, -/* 33 */ { 4, s_4_33, 32, 2, 0}, -/* 34 */ { 4, s_4_34, 32, 2, 0}, -/* 35 */ { 4, s_4_35, -1, 2, 0}, -/* 36 */ { 4, s_4_36, -1, 1, 0}, -/* 37 */ { 4, s_4_37, -1, 2, 0}, -/* 38 */ { 2, s_4_38, -1, 1, 0}, -/* 39 */ { 4, s_4_39, 38, 2, 0}, -/* 40 */ { 4, s_4_40, -1, 1, 0}, -/* 41 */ { 6, s_4_41, 40, 2, 0}, -/* 42 */ { 6, s_4_42, 40, 2, 0}, -/* 43 */ { 4, s_4_43, -1, 1, 0}, -/* 44 */ { 6, s_4_44, 43, 2, 0}, -/* 45 */ { 6, s_4_45, 43, 1, 0} +{ 4, s_4_0, -1, 2, 0}, +{ 4, s_4_1, -1, 1, 0}, +{ 6, s_4_2, 1, 2, 0}, +{ 4, s_4_3, -1, 2, 0}, +{ 4, s_4_4, -1, 1, 0}, +{ 6, s_4_5, 4, 2, 0}, +{ 4, s_4_6, -1, 2, 0}, +{ 4, s_4_7, -1, 1, 0}, +{ 6, s_4_8, 7, 2, 0}, +{ 4, s_4_9, -1, 1, 0}, +{ 6, s_4_10, 9, 2, 0}, +{ 6, s_4_11, 9, 2, 0}, +{ 6, s_4_12, -1, 1, 0}, +{ 6, s_4_13, -1, 2, 0}, +{ 2, s_4_14, -1, 2, 0}, +{ 4, s_4_15, 14, 2, 0}, +{ 4, s_4_16, -1, 1, 0}, +{ 6, s_4_17, 16, 2, 0}, +{ 6, s_4_18, 16, 2, 0}, +{ 4, s_4_19, -1, 1, 0}, +{ 6, s_4_20, 19, 2, 0}, +{ 6, s_4_21, -1, 1, 0}, +{ 6, s_4_22, -1, 2, 0}, +{ 6, s_4_23, -1, 1, 0}, +{ 8, s_4_24, 23, 2, 0}, +{ 8, s_4_25, 23, 2, 0}, +{ 4, s_4_26, -1, 1, 0}, +{ 6, s_4_27, 26, 2, 0}, +{ 6, s_4_28, 26, 2, 0}, +{ 2, s_4_29, -1, 1, 0}, +{ 4, s_4_30, 29, 2, 0}, +{ 4, s_4_31, 29, 2, 0}, +{ 2, s_4_32, -1, 1, 0}, +{ 4, s_4_33, 32, 2, 0}, +{ 4, s_4_34, 32, 2, 0}, +{ 4, s_4_35, -1, 2, 0}, +{ 4, s_4_36, -1, 1, 0}, +{ 4, s_4_37, -1, 2, 0}, +{ 2, s_4_38, -1, 1, 0}, +{ 4, s_4_39, 38, 2, 0}, +{ 4, s_4_40, -1, 1, 0}, +{ 6, s_4_41, 40, 2, 0}, +{ 6, s_4_42, 40, 2, 0}, +{ 4, s_4_43, -1, 1, 0}, +{ 6, s_4_44, 43, 2, 0}, +{ 6, s_4_45, 43, 1, 0} }; static const symbol s_5_0[2] = { 0xD1, 0x83 }; @@ -277,42 +277,42 @@ static const symbol s_5_35[2] = { 0xD0, 0xBE }; static const struct among a_5[36] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 4, s_5_1, -1, 1, 0}, -/* 2 */ { 6, s_5_2, 1, 1, 0}, -/* 3 */ { 4, s_5_3, -1, 1, 0}, -/* 4 */ { 2, s_5_4, -1, 1, 0}, -/* 5 */ { 2, s_5_5, -1, 1, 0}, -/* 6 */ { 2, s_5_6, -1, 1, 0}, -/* 7 */ { 4, s_5_7, 6, 1, 0}, -/* 8 */ { 4, s_5_8, 6, 1, 0}, -/* 9 */ { 2, s_5_9, -1, 1, 0}, -/* 10 */ { 4, s_5_10, 9, 1, 0}, -/* 11 */ { 4, s_5_11, 9, 1, 0}, -/* 12 */ { 2, s_5_12, -1, 1, 0}, -/* 13 */ { 4, s_5_13, -1, 1, 0}, -/* 14 */ { 4, s_5_14, -1, 1, 0}, -/* 15 */ { 2, s_5_15, -1, 1, 0}, -/* 16 */ { 4, s_5_16, 15, 1, 0}, -/* 17 */ { 4, s_5_17, 15, 1, 0}, -/* 18 */ { 2, s_5_18, -1, 1, 0}, -/* 19 */ { 4, s_5_19, 18, 1, 0}, -/* 20 */ { 4, s_5_20, 18, 1, 0}, -/* 21 */ { 6, s_5_21, 18, 1, 0}, -/* 22 */ { 8, s_5_22, 21, 1, 0}, -/* 23 */ { 6, s_5_23, 18, 1, 0}, -/* 24 */ { 2, s_5_24, -1, 1, 0}, -/* 25 */ { 4, s_5_25, 24, 1, 0}, -/* 26 */ { 6, s_5_26, 25, 1, 0}, -/* 27 */ { 4, s_5_27, 24, 1, 0}, -/* 28 */ { 4, s_5_28, 24, 1, 0}, -/* 29 */ { 4, s_5_29, -1, 1, 0}, -/* 30 */ { 6, s_5_30, 29, 1, 0}, -/* 31 */ { 4, s_5_31, -1, 1, 0}, -/* 32 */ { 4, s_5_32, -1, 1, 0}, -/* 33 */ { 6, s_5_33, 32, 1, 0}, -/* 34 */ { 4, s_5_34, -1, 1, 0}, -/* 35 */ { 2, s_5_35, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 4, s_5_1, -1, 1, 0}, +{ 6, s_5_2, 1, 1, 0}, +{ 4, s_5_3, -1, 1, 0}, +{ 2, s_5_4, -1, 1, 0}, +{ 2, s_5_5, -1, 1, 0}, +{ 2, s_5_6, -1, 1, 0}, +{ 4, s_5_7, 6, 1, 0}, +{ 4, s_5_8, 6, 1, 0}, +{ 2, s_5_9, -1, 1, 0}, +{ 4, s_5_10, 9, 1, 0}, +{ 4, s_5_11, 9, 1, 0}, +{ 2, s_5_12, -1, 1, 0}, +{ 4, s_5_13, -1, 1, 0}, +{ 4, s_5_14, -1, 1, 0}, +{ 2, s_5_15, -1, 1, 0}, +{ 4, s_5_16, 15, 1, 0}, +{ 4, s_5_17, 15, 1, 0}, +{ 2, s_5_18, -1, 1, 0}, +{ 4, s_5_19, 18, 1, 0}, +{ 4, s_5_20, 18, 1, 0}, +{ 6, s_5_21, 18, 1, 0}, +{ 8, s_5_22, 21, 1, 0}, +{ 6, s_5_23, 18, 1, 0}, +{ 2, s_5_24, -1, 1, 0}, +{ 4, s_5_25, 24, 1, 0}, +{ 6, s_5_26, 25, 1, 0}, +{ 4, s_5_27, 24, 1, 0}, +{ 4, s_5_28, 24, 1, 0}, +{ 4, s_5_29, -1, 1, 0}, +{ 6, s_5_30, 29, 1, 0}, +{ 4, s_5_31, -1, 1, 0}, +{ 4, s_5_32, -1, 1, 0}, +{ 6, s_5_33, 32, 1, 0}, +{ 4, s_5_34, -1, 1, 0}, +{ 2, s_5_35, -1, 1, 0} }; static const symbol s_6_0[6] = { 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x82 }; @@ -320,8 +320,8 @@ static const symbol s_6_1[8] = { 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x82, 0xD1, 0x8C static const struct among a_6[2] = { -/* 0 */ { 6, s_6_0, -1, 1, 0}, -/* 1 */ { 8, s_6_1, -1, 1, 0} +{ 6, s_6_0, -1, 1, 0}, +{ 8, s_6_1, -1, 1, 0} }; static const symbol s_7_0[6] = { 0xD0, 0xB5, 0xD0, 0xB9, 0xD1, 0x88 }; @@ -331,10 +331,10 @@ static const symbol s_7_3[2] = { 0xD0, 0xBD }; static const struct among a_7[4] = { -/* 0 */ { 6, s_7_0, -1, 1, 0}, -/* 1 */ { 2, s_7_1, -1, 3, 0}, -/* 2 */ { 8, s_7_2, -1, 1, 0}, -/* 3 */ { 2, s_7_3, -1, 2, 0} +{ 6, s_7_0, -1, 1, 0}, +{ 2, s_7_1, -1, 3, 0}, +{ 8, s_7_2, -1, 1, 0}, +{ 2, s_7_3, -1, 2, 0} }; static const unsigned char g_v[] = { 33, 65, 8, 232 }; @@ -352,65 +352,65 @@ static const symbol s_9[] = { 0xD1, 0x91 }; static const symbol s_10[] = { 0xD0, 0xB5 }; static const symbol s_11[] = { 0xD0, 0xB8 }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 61 */ - z->I[1] = z->l; /* $p2 = , line 62 */ - { int c1 = z->c; /* do, line 63 */ - { /* gopast */ /* grouping v, line 64 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int ret = out_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark pV, line 64 */ - { /* gopast */ /* non v, line 64 */ + z->I[1] = z->c; + { int ret = in_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* grouping v, line 65 */ + { int ret = out_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 65 */ + { int ret = in_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 65 */ + z->I[0] = z->c; lab0: z->c = c1; } return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 71 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_perfective_gerund(struct SN_env * z) { /* backwardmode */ +static int r_perfective_gerund(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 74 */ - among_var = find_among_b(z, a_0, 9); /* substring, line 74 */ + z->ket = z->c; + among_var = find_among_b(z, a_0, 9); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 74 */ - switch (among_var) { /* among, line 74 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 78 */ - if (!(eq_s_b(z, 2, s_0))) goto lab1; /* literal, line 78 */ + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 2, s_0))) goto lab1; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_1))) return 0; /* literal, line 78 */ + if (!(eq_s_b(z, 2, s_1))) return 0; } lab0: - { int ret = slice_del(z); /* delete, line 78 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 85 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -418,42 +418,42 @@ static int r_perfective_gerund(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_adjective(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 90 */ - if (!(find_among_b(z, a_1, 26))) return 0; /* substring, line 90 */ - z->bra = z->c; /* ], line 90 */ - { int ret = slice_del(z); /* delete, line 99 */ +static int r_adjective(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_1, 26))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_adjectival(struct SN_env * z) { /* backwardmode */ +static int r_adjectival(struct SN_env * z) { int among_var; - { int ret = r_adjective(z); /* call adjective, line 104 */ + { int ret = r_adjective(z); if (ret <= 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ - z->ket = z->c; /* [, line 112 */ - among_var = find_among_b(z, a_2, 8); /* substring, line 112 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + among_var = find_among_b(z, a_2, 8); if (!(among_var)) { z->c = z->l - m1; goto lab0; } - z->bra = z->c; /* ], line 112 */ - switch (among_var) { /* among, line 112 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* or, line 117 */ - if (!(eq_s_b(z, 2, s_2))) goto lab2; /* literal, line 117 */ + { int m2 = z->l - z->c; (void)m2; + if (!(eq_s_b(z, 2, s_2))) goto lab2; goto lab1; lab2: z->c = z->l - m2; - if (!(eq_s_b(z, 2, s_3))) { z->c = z->l - m1; goto lab0; } /* literal, line 117 */ + if (!(eq_s_b(z, 2, s_3))) { z->c = z->l - m1; goto lab0; } } lab1: - { int ret = slice_del(z); /* delete, line 117 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 124 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -464,39 +464,39 @@ static int r_adjectival(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_reflexive(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 131 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 140 && z->p[z->c - 1] != 143)) return 0; /* substring, line 131 */ +static int r_reflexive(struct SN_env * z) { + z->ket = z->c; + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 140 && z->p[z->c - 1] != 143)) return 0; if (!(find_among_b(z, a_3, 2))) return 0; - z->bra = z->c; /* ], line 131 */ - { int ret = slice_del(z); /* delete, line 134 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_verb(struct SN_env * z) { /* backwardmode */ +static int r_verb(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 139 */ - among_var = find_among_b(z, a_4, 46); /* substring, line 139 */ + z->ket = z->c; + among_var = find_among_b(z, a_4, 46); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 139 */ - switch (among_var) { /* among, line 139 */ + z->bra = z->c; + switch (among_var) { case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - if (!(eq_s_b(z, 2, s_4))) goto lab1; /* literal, line 145 */ + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 2, s_4))) goto lab1; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_5))) return 0; /* literal, line 145 */ + if (!(eq_s_b(z, 2, s_5))) return 0; } lab0: - { int ret = slice_del(z); /* delete, line 145 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 153 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -504,57 +504,57 @@ static int r_verb(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_noun(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 162 */ - if (!(find_among_b(z, a_5, 36))) return 0; /* substring, line 162 */ - z->bra = z->c; /* ], line 162 */ - { int ret = slice_del(z); /* delete, line 169 */ +static int r_noun(struct SN_env * z) { + z->ket = z->c; + if (!(find_among_b(z, a_5, 36))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_derivational(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 178 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 130 && z->p[z->c - 1] != 140)) return 0; /* substring, line 178 */ +static int r_derivational(struct SN_env * z) { + z->ket = z->c; + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 130 && z->p[z->c - 1] != 140)) return 0; if (!(find_among_b(z, a_6, 2))) return 0; - z->bra = z->c; /* ], line 178 */ - { int ret = r_R2(z); /* call R2, line 178 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 181 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_tidy_up(struct SN_env * z) { /* backwardmode */ +static int r_tidy_up(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 186 */ - among_var = find_among_b(z, a_7, 4); /* substring, line 186 */ + z->ket = z->c; + among_var = find_among_b(z, a_7, 4); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 186 */ - switch (among_var) { /* among, line 186 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 190 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 191 */ - if (!(eq_s_b(z, 2, s_6))) return 0; /* literal, line 191 */ - z->bra = z->c; /* ], line 191 */ - if (!(eq_s_b(z, 2, s_7))) return 0; /* literal, line 191 */ - { int ret = slice_del(z); /* delete, line 191 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_6))) return 0; + z->bra = z->c; + if (!(eq_s_b(z, 2, s_7))) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (!(eq_s_b(z, 2, s_8))) return 0; /* literal, line 194 */ - { int ret = slice_del(z); /* delete, line 194 */ + if (!(eq_s_b(z, 2, s_8))) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 196 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -562,26 +562,25 @@ static int r_tidy_up(struct SN_env * z) { /* backwardmode */ return 1; } -extern int russian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 205 */ -/* repeat, line 205 */ - - while(1) { int c2 = z->c; - while(1) { /* goto, line 205 */ +extern int russian_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + while(1) { + int c2 = z->c; + while(1) { int c3 = z->c; - z->bra = z->c; /* [, line 205 */ - if (!(eq_s(z, 2, s_9))) goto lab2; /* literal, line 205 */ - z->ket = z->c; /* ], line 205 */ + z->bra = z->c; + if (!(eq_s(z, 2, s_9))) goto lab2; + z->ket = z->c; z->c = c3; break; lab2: z->c = c3; - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab1; - z->c = ret; /* goto, line 205 */ + z->c = ret; } } - { int ret = slice_from_s(z, 2, s_10); /* <-, line 205 */ + { int ret = slice_from_s(z, 2, s_10); if (ret < 0) return ret; } continue; @@ -591,49 +590,49 @@ extern int russian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ } z->c = c1; } - /* do, line 207 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 207 */ + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 208 */ + z->lb = z->c; z->c = z->l; - { int mlimit4; /* setlimit, line 208 */ - if (z->c < z->I[0]) return 0; - mlimit4 = z->lb; z->lb = z->I[0]; - { int m5 = z->l - z->c; (void)m5; /* do, line 209 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 210 */ - { int ret = r_perfective_gerund(z); /* call perfective_gerund, line 210 */ + { int mlimit4; + if (z->c < z->I[1]) return 0; + mlimit4 = z->lb; z->lb = z->I[1]; + { int m5 = z->l - z->c; (void)m5; + { int m6 = z->l - z->c; (void)m6; + { int ret = r_perfective_gerund(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab4; lab5: z->c = z->l - m6; - { int m7 = z->l - z->c; (void)m7; /* try, line 211 */ - { int ret = r_reflexive(z); /* call reflexive, line 211 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_reflexive(z); if (ret == 0) { z->c = z->l - m7; goto lab6; } if (ret < 0) return ret; } lab6: ; } - { int m8 = z->l - z->c; (void)m8; /* or, line 212 */ - { int ret = r_adjectival(z); /* call adjectival, line 212 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_adjectival(z); if (ret == 0) goto lab8; if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m8; - { int ret = r_verb(z); /* call verb, line 212 */ + { int ret = r_verb(z); if (ret == 0) goto lab9; if (ret < 0) return ret; } goto lab7; lab9: z->c = z->l - m8; - { int ret = r_noun(z); /* call noun, line 212 */ + { int ret = r_noun(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } @@ -645,24 +644,24 @@ extern int russian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab3: z->c = z->l - m5; } - { int m9 = z->l - z->c; (void)m9; /* try, line 215 */ - z->ket = z->c; /* [, line 215 */ - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m9; goto lab10; } /* literal, line 215 */ - z->bra = z->c; /* ], line 215 */ - { int ret = slice_del(z); /* delete, line 215 */ + { int m9 = z->l - z->c; (void)m9; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m9; goto lab10; } + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } lab10: ; } - { int m10 = z->l - z->c; (void)m10; /* do, line 218 */ - { int ret = r_derivational(z); /* call derivational, line 218 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_derivational(z); if (ret < 0) return ret; } z->c = z->l - m10; } - { int m11 = z->l - z->c; (void)m11; /* do, line 219 */ - { int ret = r_tidy_up(z); /* call tidy_up, line 219 */ + { int m11 = z->l - z->c; (void)m11; + { int ret = r_tidy_up(z); if (ret < 0) return ret; } z->c = z->l - m11; @@ -673,7 +672,7 @@ extern int russian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * russian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * russian_UTF_8_create_env(void) { return SN_create_env(0, 2); } extern void russian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_serbian.c b/src/backend/snowball/libstemmer/stem_UTF_8_serbian.c new file mode 100644 index 000000000000..5b1ea9ad46a3 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_serbian.c @@ -0,0 +1,6543 @@ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int serbian_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_Step_3(struct SN_env * z); +static int r_Step_2(struct SN_env * z); +static int r_Step_1(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_prelude(struct SN_env * z); +static int r_cyr_to_lat(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * serbian_UTF_8_create_env(void); +extern void serbian_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[2] = { 0xD0, 0xB0 }; +static const symbol s_0_1[2] = { 0xD0, 0xB1 }; +static const symbol s_0_2[2] = { 0xD0, 0xB2 }; +static const symbol s_0_3[2] = { 0xD0, 0xB3 }; +static const symbol s_0_4[2] = { 0xD0, 0xB4 }; +static const symbol s_0_5[2] = { 0xD0, 0xB5 }; +static const symbol s_0_6[2] = { 0xD0, 0xB6 }; +static const symbol s_0_7[2] = { 0xD0, 0xB7 }; +static const symbol s_0_8[2] = { 0xD0, 0xB8 }; +static const symbol s_0_9[2] = { 0xD0, 0xBA }; +static const symbol s_0_10[2] = { 0xD0, 0xBB }; +static const symbol s_0_11[2] = { 0xD0, 0xBC }; +static const symbol s_0_12[2] = { 0xD0, 0xBD }; +static const symbol s_0_13[2] = { 0xD0, 0xBE }; +static const symbol s_0_14[2] = { 0xD0, 0xBF }; +static const symbol s_0_15[2] = { 0xD1, 0x80 }; +static const symbol s_0_16[2] = { 0xD1, 0x81 }; +static const symbol s_0_17[2] = { 0xD1, 0x82 }; +static const symbol s_0_18[2] = { 0xD1, 0x83 }; +static const symbol s_0_19[2] = { 0xD1, 0x84 }; +static const symbol s_0_20[2] = { 0xD1, 0x85 }; +static const symbol s_0_21[2] = { 0xD1, 0x86 }; +static const symbol s_0_22[2] = { 0xD1, 0x87 }; +static const symbol s_0_23[2] = { 0xD1, 0x88 }; +static const symbol s_0_24[2] = { 0xD1, 0x92 }; +static const symbol s_0_25[2] = { 0xD1, 0x98 }; +static const symbol s_0_26[2] = { 0xD1, 0x99 }; +static const symbol s_0_27[2] = { 0xD1, 0x9A }; +static const symbol s_0_28[2] = { 0xD1, 0x9B }; +static const symbol s_0_29[2] = { 0xD1, 0x9F }; + +static const struct among a_0[30] = +{ +{ 2, s_0_0, -1, 1, 0}, +{ 2, s_0_1, -1, 2, 0}, +{ 2, s_0_2, -1, 3, 0}, +{ 2, s_0_3, -1, 4, 0}, +{ 2, s_0_4, -1, 5, 0}, +{ 2, s_0_5, -1, 7, 0}, +{ 2, s_0_6, -1, 8, 0}, +{ 2, s_0_7, -1, 9, 0}, +{ 2, s_0_8, -1, 10, 0}, +{ 2, s_0_9, -1, 12, 0}, +{ 2, s_0_10, -1, 13, 0}, +{ 2, s_0_11, -1, 15, 0}, +{ 2, s_0_12, -1, 16, 0}, +{ 2, s_0_13, -1, 18, 0}, +{ 2, s_0_14, -1, 19, 0}, +{ 2, s_0_15, -1, 20, 0}, +{ 2, s_0_16, -1, 21, 0}, +{ 2, s_0_17, -1, 22, 0}, +{ 2, s_0_18, -1, 24, 0}, +{ 2, s_0_19, -1, 25, 0}, +{ 2, s_0_20, -1, 26, 0}, +{ 2, s_0_21, -1, 27, 0}, +{ 2, s_0_22, -1, 28, 0}, +{ 2, s_0_23, -1, 30, 0}, +{ 2, s_0_24, -1, 6, 0}, +{ 2, s_0_25, -1, 11, 0}, +{ 2, s_0_26, -1, 14, 0}, +{ 2, s_0_27, -1, 17, 0}, +{ 2, s_0_28, -1, 23, 0}, +{ 2, s_0_29, -1, 29, 0} +}; + +static const symbol s_1_0[4] = { 'd', 'a', 'b', 'a' }; +static const symbol s_1_1[5] = { 'a', 'j', 'a', 'c', 'a' }; +static const symbol s_1_2[5] = { 'e', 'j', 'a', 'c', 'a' }; +static const symbol s_1_3[5] = { 'l', 'j', 'a', 'c', 'a' }; +static const symbol s_1_4[5] = { 'n', 'j', 'a', 'c', 'a' }; +static const symbol s_1_5[5] = { 'o', 'j', 'a', 'c', 'a' }; +static const symbol s_1_6[5] = { 'a', 'l', 'a', 'c', 'a' }; +static const symbol s_1_7[5] = { 'e', 'l', 'a', 'c', 'a' }; +static const symbol s_1_8[5] = { 'o', 'l', 'a', 'c', 'a' }; +static const symbol s_1_9[4] = { 'm', 'a', 'c', 'a' }; +static const symbol s_1_10[4] = { 'n', 'a', 'c', 'a' }; +static const symbol s_1_11[4] = { 'r', 'a', 'c', 'a' }; +static const symbol s_1_12[4] = { 's', 'a', 'c', 'a' }; +static const symbol s_1_13[4] = { 'v', 'a', 'c', 'a' }; +static const symbol s_1_14[5] = { 0xC5, 0xA1, 'a', 'c', 'a' }; +static const symbol s_1_15[4] = { 'a', 'o', 'c', 'a' }; +static const symbol s_1_16[5] = { 'a', 'c', 'a', 'k', 'a' }; +static const symbol s_1_17[5] = { 'a', 'j', 'a', 'k', 'a' }; +static const symbol s_1_18[5] = { 'o', 'j', 'a', 'k', 'a' }; +static const symbol s_1_19[5] = { 'a', 'n', 'a', 'k', 'a' }; +static const symbol s_1_20[5] = { 'a', 't', 'a', 'k', 'a' }; +static const symbol s_1_21[5] = { 'e', 't', 'a', 'k', 'a' }; +static const symbol s_1_22[5] = { 'i', 't', 'a', 'k', 'a' }; +static const symbol s_1_23[5] = { 'o', 't', 'a', 'k', 'a' }; +static const symbol s_1_24[5] = { 'u', 't', 'a', 'k', 'a' }; +static const symbol s_1_25[6] = { 'a', 0xC4, 0x8D, 'a', 'k', 'a' }; +static const symbol s_1_26[5] = { 'e', 's', 'a', 'm', 'a' }; +static const symbol s_1_27[5] = { 'i', 'z', 'a', 'm', 'a' }; +static const symbol s_1_28[6] = { 'j', 'a', 'c', 'i', 'm', 'a' }; +static const symbol s_1_29[6] = { 'n', 'i', 'c', 'i', 'm', 'a' }; +static const symbol s_1_30[6] = { 't', 'i', 'c', 'i', 'm', 'a' }; +static const symbol s_1_31[8] = { 't', 'e', 't', 'i', 'c', 'i', 'm', 'a' }; +static const symbol s_1_32[6] = { 'z', 'i', 'c', 'i', 'm', 'a' }; +static const symbol s_1_33[6] = { 'a', 't', 'c', 'i', 'm', 'a' }; +static const symbol s_1_34[6] = { 'u', 't', 'c', 'i', 'm', 'a' }; +static const symbol s_1_35[6] = { 0xC4, 0x8D, 'c', 'i', 'm', 'a' }; +static const symbol s_1_36[6] = { 'p', 'e', 's', 'i', 'm', 'a' }; +static const symbol s_1_37[6] = { 'i', 'n', 'z', 'i', 'm', 'a' }; +static const symbol s_1_38[6] = { 'l', 'o', 'z', 'i', 'm', 'a' }; +static const symbol s_1_39[6] = { 'm', 'e', 't', 'a', 'r', 'a' }; +static const symbol s_1_40[7] = { 'c', 'e', 'n', 't', 'a', 'r', 'a' }; +static const symbol s_1_41[6] = { 'i', 's', 't', 'a', 'r', 'a' }; +static const symbol s_1_42[5] = { 'e', 'k', 'a', 't', 'a' }; +static const symbol s_1_43[5] = { 'a', 'n', 'a', 't', 'a' }; +static const symbol s_1_44[6] = { 'n', 's', 't', 'a', 'v', 'a' }; +static const symbol s_1_45[7] = { 'k', 'u', 's', 't', 'a', 'v', 'a' }; +static const symbol s_1_46[4] = { 'a', 'j', 'a', 'c' }; +static const symbol s_1_47[4] = { 'e', 'j', 'a', 'c' }; +static const symbol s_1_48[4] = { 'l', 'j', 'a', 'c' }; +static const symbol s_1_49[4] = { 'n', 'j', 'a', 'c' }; +static const symbol s_1_50[5] = { 'a', 'n', 'j', 'a', 'c' }; +static const symbol s_1_51[4] = { 'o', 'j', 'a', 'c' }; +static const symbol s_1_52[4] = { 'a', 'l', 'a', 'c' }; +static const symbol s_1_53[4] = { 'e', 'l', 'a', 'c' }; +static const symbol s_1_54[4] = { 'o', 'l', 'a', 'c' }; +static const symbol s_1_55[3] = { 'm', 'a', 'c' }; +static const symbol s_1_56[3] = { 'n', 'a', 'c' }; +static const symbol s_1_57[3] = { 'r', 'a', 'c' }; +static const symbol s_1_58[3] = { 's', 'a', 'c' }; +static const symbol s_1_59[3] = { 'v', 'a', 'c' }; +static const symbol s_1_60[4] = { 0xC5, 0xA1, 'a', 'c' }; +static const symbol s_1_61[4] = { 'j', 'e', 'b', 'e' }; +static const symbol s_1_62[4] = { 'o', 'l', 'c', 'e' }; +static const symbol s_1_63[4] = { 'k', 'u', 's', 'e' }; +static const symbol s_1_64[4] = { 'r', 'a', 'v', 'e' }; +static const symbol s_1_65[4] = { 's', 'a', 'v', 'e' }; +static const symbol s_1_66[5] = { 0xC5, 0xA1, 'a', 'v', 'e' }; +static const symbol s_1_67[4] = { 'b', 'a', 'c', 'i' }; +static const symbol s_1_68[4] = { 'j', 'a', 'c', 'i' }; +static const symbol s_1_69[7] = { 't', 'v', 'e', 'n', 'i', 'c', 'i' }; +static const symbol s_1_70[5] = { 's', 'n', 'i', 'c', 'i' }; +static const symbol s_1_71[6] = { 't', 'e', 't', 'i', 'c', 'i' }; +static const symbol s_1_72[5] = { 'b', 'o', 'j', 'c', 'i' }; +static const symbol s_1_73[5] = { 'v', 'o', 'j', 'c', 'i' }; +static const symbol s_1_74[5] = { 'o', 'j', 's', 'c', 'i' }; +static const symbol s_1_75[4] = { 'a', 't', 'c', 'i' }; +static const symbol s_1_76[4] = { 'i', 't', 'c', 'i' }; +static const symbol s_1_77[4] = { 'u', 't', 'c', 'i' }; +static const symbol s_1_78[4] = { 0xC4, 0x8D, 'c', 'i' }; +static const symbol s_1_79[4] = { 'p', 'e', 's', 'i' }; +static const symbol s_1_80[4] = { 'i', 'n', 'z', 'i' }; +static const symbol s_1_81[4] = { 'l', 'o', 'z', 'i' }; +static const symbol s_1_82[4] = { 'a', 'c', 'a', 'k' }; +static const symbol s_1_83[4] = { 'u', 's', 'a', 'k' }; +static const symbol s_1_84[4] = { 'a', 't', 'a', 'k' }; +static const symbol s_1_85[4] = { 'e', 't', 'a', 'k' }; +static const symbol s_1_86[4] = { 'i', 't', 'a', 'k' }; +static const symbol s_1_87[4] = { 'o', 't', 'a', 'k' }; +static const symbol s_1_88[4] = { 'u', 't', 'a', 'k' }; +static const symbol s_1_89[5] = { 'a', 0xC4, 0x8D, 'a', 'k' }; +static const symbol s_1_90[5] = { 'u', 0xC5, 0xA1, 'a', 'k' }; +static const symbol s_1_91[4] = { 'i', 'z', 'a', 'm' }; +static const symbol s_1_92[5] = { 't', 'i', 'c', 'a', 'n' }; +static const symbol s_1_93[5] = { 'c', 'a', 'j', 'a', 'n' }; +static const symbol s_1_94[6] = { 0xC4, 0x8D, 'a', 'j', 'a', 'n' }; +static const symbol s_1_95[6] = { 'v', 'o', 'l', 'j', 'a', 'n' }; +static const symbol s_1_96[5] = { 'e', 's', 'k', 'a', 'n' }; +static const symbol s_1_97[4] = { 'a', 'l', 'a', 'n' }; +static const symbol s_1_98[5] = { 'b', 'i', 'l', 'a', 'n' }; +static const symbol s_1_99[5] = { 'g', 'i', 'l', 'a', 'n' }; +static const symbol s_1_100[5] = { 'n', 'i', 'l', 'a', 'n' }; +static const symbol s_1_101[5] = { 'r', 'i', 'l', 'a', 'n' }; +static const symbol s_1_102[5] = { 's', 'i', 'l', 'a', 'n' }; +static const symbol s_1_103[5] = { 't', 'i', 'l', 'a', 'n' }; +static const symbol s_1_104[6] = { 'a', 'v', 'i', 'l', 'a', 'n' }; +static const symbol s_1_105[5] = { 'l', 'a', 'r', 'a', 'n' }; +static const symbol s_1_106[4] = { 'e', 'r', 'a', 'n' }; +static const symbol s_1_107[4] = { 'a', 's', 'a', 'n' }; +static const symbol s_1_108[4] = { 'e', 's', 'a', 'n' }; +static const symbol s_1_109[5] = { 'd', 'u', 's', 'a', 'n' }; +static const symbol s_1_110[5] = { 'k', 'u', 's', 'a', 'n' }; +static const symbol s_1_111[4] = { 'a', 't', 'a', 'n' }; +static const symbol s_1_112[6] = { 'p', 'l', 'e', 't', 'a', 'n' }; +static const symbol s_1_113[5] = { 't', 'e', 't', 'a', 'n' }; +static const symbol s_1_114[5] = { 'a', 'n', 't', 'a', 'n' }; +static const symbol s_1_115[6] = { 'p', 'r', 'a', 'v', 'a', 'n' }; +static const symbol s_1_116[6] = { 's', 't', 'a', 'v', 'a', 'n' }; +static const symbol s_1_117[5] = { 's', 'i', 'v', 'a', 'n' }; +static const symbol s_1_118[5] = { 't', 'i', 'v', 'a', 'n' }; +static const symbol s_1_119[4] = { 'o', 'z', 'a', 'n' }; +static const symbol s_1_120[6] = { 't', 'i', 0xC4, 0x8D, 'a', 'n' }; +static const symbol s_1_121[5] = { 'a', 0xC5, 0xA1, 'a', 'n' }; +static const symbol s_1_122[6] = { 'd', 'u', 0xC5, 0xA1, 'a', 'n' }; +static const symbol s_1_123[5] = { 'm', 'e', 't', 'a', 'r' }; +static const symbol s_1_124[6] = { 'c', 'e', 'n', 't', 'a', 'r' }; +static const symbol s_1_125[5] = { 'i', 's', 't', 'a', 'r' }; +static const symbol s_1_126[4] = { 'e', 'k', 'a', 't' }; +static const symbol s_1_127[4] = { 'e', 'n', 'a', 't' }; +static const symbol s_1_128[4] = { 'o', 's', 'c', 'u' }; +static const symbol s_1_129[6] = { 'o', 0xC5, 0xA1, 0xC4, 0x87, 'u' }; + +static const struct among a_1[130] = +{ +{ 4, s_1_0, -1, 73, 0}, +{ 5, s_1_1, -1, 12, 0}, +{ 5, s_1_2, -1, 14, 0}, +{ 5, s_1_3, -1, 13, 0}, +{ 5, s_1_4, -1, 85, 0}, +{ 5, s_1_5, -1, 15, 0}, +{ 5, s_1_6, -1, 82, 0}, +{ 5, s_1_7, -1, 83, 0}, +{ 5, s_1_8, -1, 84, 0}, +{ 4, s_1_9, -1, 75, 0}, +{ 4, s_1_10, -1, 76, 0}, +{ 4, s_1_11, -1, 81, 0}, +{ 4, s_1_12, -1, 80, 0}, +{ 4, s_1_13, -1, 79, 0}, +{ 5, s_1_14, -1, 18, 0}, +{ 4, s_1_15, -1, 82, 0}, +{ 5, s_1_16, -1, 55, 0}, +{ 5, s_1_17, -1, 16, 0}, +{ 5, s_1_18, -1, 17, 0}, +{ 5, s_1_19, -1, 78, 0}, +{ 5, s_1_20, -1, 58, 0}, +{ 5, s_1_21, -1, 59, 0}, +{ 5, s_1_22, -1, 60, 0}, +{ 5, s_1_23, -1, 61, 0}, +{ 5, s_1_24, -1, 62, 0}, +{ 6, s_1_25, -1, 54, 0}, +{ 5, s_1_26, -1, 67, 0}, +{ 5, s_1_27, -1, 87, 0}, +{ 6, s_1_28, -1, 5, 0}, +{ 6, s_1_29, -1, 23, 0}, +{ 6, s_1_30, -1, 24, 0}, +{ 8, s_1_31, 30, 21, 0}, +{ 6, s_1_32, -1, 25, 0}, +{ 6, s_1_33, -1, 58, 0}, +{ 6, s_1_34, -1, 62, 0}, +{ 6, s_1_35, -1, 74, 0}, +{ 6, s_1_36, -1, 2, 0}, +{ 6, s_1_37, -1, 19, 0}, +{ 6, s_1_38, -1, 1, 0}, +{ 6, s_1_39, -1, 68, 0}, +{ 7, s_1_40, -1, 69, 0}, +{ 6, s_1_41, -1, 70, 0}, +{ 5, s_1_42, -1, 86, 0}, +{ 5, s_1_43, -1, 53, 0}, +{ 6, s_1_44, -1, 22, 0}, +{ 7, s_1_45, -1, 29, 0}, +{ 4, s_1_46, -1, 12, 0}, +{ 4, s_1_47, -1, 14, 0}, +{ 4, s_1_48, -1, 13, 0}, +{ 4, s_1_49, -1, 85, 0}, +{ 5, s_1_50, 49, 11, 0}, +{ 4, s_1_51, -1, 15, 0}, +{ 4, s_1_52, -1, 82, 0}, +{ 4, s_1_53, -1, 83, 0}, +{ 4, s_1_54, -1, 84, 0}, +{ 3, s_1_55, -1, 75, 0}, +{ 3, s_1_56, -1, 76, 0}, +{ 3, s_1_57, -1, 81, 0}, +{ 3, s_1_58, -1, 80, 0}, +{ 3, s_1_59, -1, 79, 0}, +{ 4, s_1_60, -1, 18, 0}, +{ 4, s_1_61, -1, 88, 0}, +{ 4, s_1_62, -1, 84, 0}, +{ 4, s_1_63, -1, 27, 0}, +{ 4, s_1_64, -1, 42, 0}, +{ 4, s_1_65, -1, 52, 0}, +{ 5, s_1_66, -1, 51, 0}, +{ 4, s_1_67, -1, 89, 0}, +{ 4, s_1_68, -1, 5, 0}, +{ 7, s_1_69, -1, 20, 0}, +{ 5, s_1_70, -1, 26, 0}, +{ 6, s_1_71, -1, 21, 0}, +{ 5, s_1_72, -1, 4, 0}, +{ 5, s_1_73, -1, 3, 0}, +{ 5, s_1_74, -1, 66, 0}, +{ 4, s_1_75, -1, 58, 0}, +{ 4, s_1_76, -1, 60, 0}, +{ 4, s_1_77, -1, 62, 0}, +{ 4, s_1_78, -1, 74, 0}, +{ 4, s_1_79, -1, 2, 0}, +{ 4, s_1_80, -1, 19, 0}, +{ 4, s_1_81, -1, 1, 0}, +{ 4, s_1_82, -1, 55, 0}, +{ 4, s_1_83, -1, 57, 0}, +{ 4, s_1_84, -1, 58, 0}, +{ 4, s_1_85, -1, 59, 0}, +{ 4, s_1_86, -1, 60, 0}, +{ 4, s_1_87, -1, 61, 0}, +{ 4, s_1_88, -1, 62, 0}, +{ 5, s_1_89, -1, 54, 0}, +{ 5, s_1_90, -1, 56, 0}, +{ 4, s_1_91, -1, 87, 0}, +{ 5, s_1_92, -1, 65, 0}, +{ 5, s_1_93, -1, 7, 0}, +{ 6, s_1_94, -1, 6, 0}, +{ 6, s_1_95, -1, 77, 0}, +{ 5, s_1_96, -1, 63, 0}, +{ 4, s_1_97, -1, 40, 0}, +{ 5, s_1_98, -1, 33, 0}, +{ 5, s_1_99, -1, 37, 0}, +{ 5, s_1_100, -1, 39, 0}, +{ 5, s_1_101, -1, 38, 0}, +{ 5, s_1_102, -1, 36, 0}, +{ 5, s_1_103, -1, 34, 0}, +{ 6, s_1_104, -1, 35, 0}, +{ 5, s_1_105, -1, 9, 0}, +{ 4, s_1_106, -1, 8, 0}, +{ 4, s_1_107, -1, 91, 0}, +{ 4, s_1_108, -1, 10, 0}, +{ 5, s_1_109, -1, 31, 0}, +{ 5, s_1_110, -1, 28, 0}, +{ 4, s_1_111, -1, 47, 0}, +{ 6, s_1_112, -1, 50, 0}, +{ 5, s_1_113, -1, 49, 0}, +{ 5, s_1_114, -1, 32, 0}, +{ 6, s_1_115, -1, 44, 0}, +{ 6, s_1_116, -1, 43, 0}, +{ 5, s_1_117, -1, 46, 0}, +{ 5, s_1_118, -1, 45, 0}, +{ 4, s_1_119, -1, 41, 0}, +{ 6, s_1_120, -1, 64, 0}, +{ 5, s_1_121, -1, 90, 0}, +{ 6, s_1_122, -1, 30, 0}, +{ 5, s_1_123, -1, 68, 0}, +{ 6, s_1_124, -1, 69, 0}, +{ 5, s_1_125, -1, 70, 0}, +{ 4, s_1_126, -1, 86, 0}, +{ 4, s_1_127, -1, 48, 0}, +{ 4, s_1_128, -1, 72, 0}, +{ 6, s_1_129, -1, 71, 0} +}; + +static const symbol s_2_0[3] = { 'a', 'c', 'a' }; +static const symbol s_2_1[3] = { 'e', 'c', 'a' }; +static const symbol s_2_2[3] = { 'u', 'c', 'a' }; +static const symbol s_2_3[2] = { 'g', 'a' }; +static const symbol s_2_4[5] = { 'a', 'c', 'e', 'g', 'a' }; +static const symbol s_2_5[5] = { 'e', 'c', 'e', 'g', 'a' }; +static const symbol s_2_6[5] = { 'u', 'c', 'e', 'g', 'a' }; +static const symbol s_2_7[8] = { 'a', 'n', 'j', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_8[8] = { 'e', 'n', 'j', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_9[8] = { 's', 'n', 'j', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_10[9] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_11[6] = { 'k', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_12[7] = { 's', 'k', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_13[8] = { 0xC5, 0xA1, 'k', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_14[7] = { 'e', 'l', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_15[6] = { 'n', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_16[7] = { 'o', 's', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_17[7] = { 'a', 't', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_18[9] = { 'e', 'v', 'i', 't', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_19[9] = { 'o', 'v', 'i', 't', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_20[8] = { 'a', 's', 't', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_21[7] = { 'a', 'v', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_22[7] = { 'e', 'v', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_23[7] = { 'i', 'v', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_24[7] = { 'o', 'v', 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_25[8] = { 'o', 0xC5, 0xA1, 'i', 'j', 'e', 'g', 'a' }; +static const symbol s_2_26[6] = { 'a', 'n', 'j', 'e', 'g', 'a' }; +static const symbol s_2_27[6] = { 'e', 'n', 'j', 'e', 'g', 'a' }; +static const symbol s_2_28[6] = { 's', 'n', 'j', 'e', 'g', 'a' }; +static const symbol s_2_29[7] = { 0xC5, 0xA1, 'n', 'j', 'e', 'g', 'a' }; +static const symbol s_2_30[4] = { 'k', 'e', 'g', 'a' }; +static const symbol s_2_31[5] = { 's', 'k', 'e', 'g', 'a' }; +static const symbol s_2_32[6] = { 0xC5, 0xA1, 'k', 'e', 'g', 'a' }; +static const symbol s_2_33[5] = { 'e', 'l', 'e', 'g', 'a' }; +static const symbol s_2_34[4] = { 'n', 'e', 'g', 'a' }; +static const symbol s_2_35[5] = { 'a', 'n', 'e', 'g', 'a' }; +static const symbol s_2_36[5] = { 'e', 'n', 'e', 'g', 'a' }; +static const symbol s_2_37[5] = { 's', 'n', 'e', 'g', 'a' }; +static const symbol s_2_38[6] = { 0xC5, 0xA1, 'n', 'e', 'g', 'a' }; +static const symbol s_2_39[5] = { 'o', 's', 'e', 'g', 'a' }; +static const symbol s_2_40[5] = { 'a', 't', 'e', 'g', 'a' }; +static const symbol s_2_41[7] = { 'e', 'v', 'i', 't', 'e', 'g', 'a' }; +static const symbol s_2_42[7] = { 'o', 'v', 'i', 't', 'e', 'g', 'a' }; +static const symbol s_2_43[6] = { 'a', 's', 't', 'e', 'g', 'a' }; +static const symbol s_2_44[5] = { 'a', 'v', 'e', 'g', 'a' }; +static const symbol s_2_45[5] = { 'e', 'v', 'e', 'g', 'a' }; +static const symbol s_2_46[5] = { 'i', 'v', 'e', 'g', 'a' }; +static const symbol s_2_47[5] = { 'o', 'v', 'e', 'g', 'a' }; +static const symbol s_2_48[6] = { 'a', 0xC4, 0x87, 'e', 'g', 'a' }; +static const symbol s_2_49[6] = { 'e', 0xC4, 0x87, 'e', 'g', 'a' }; +static const symbol s_2_50[6] = { 'u', 0xC4, 0x87, 'e', 'g', 'a' }; +static const symbol s_2_51[6] = { 'o', 0xC5, 0xA1, 'e', 'g', 'a' }; +static const symbol s_2_52[5] = { 'a', 'c', 'o', 'g', 'a' }; +static const symbol s_2_53[5] = { 'e', 'c', 'o', 'g', 'a' }; +static const symbol s_2_54[5] = { 'u', 'c', 'o', 'g', 'a' }; +static const symbol s_2_55[6] = { 'a', 'n', 'j', 'o', 'g', 'a' }; +static const symbol s_2_56[6] = { 'e', 'n', 'j', 'o', 'g', 'a' }; +static const symbol s_2_57[6] = { 's', 'n', 'j', 'o', 'g', 'a' }; +static const symbol s_2_58[7] = { 0xC5, 0xA1, 'n', 'j', 'o', 'g', 'a' }; +static const symbol s_2_59[4] = { 'k', 'o', 'g', 'a' }; +static const symbol s_2_60[5] = { 's', 'k', 'o', 'g', 'a' }; +static const symbol s_2_61[6] = { 0xC5, 0xA1, 'k', 'o', 'g', 'a' }; +static const symbol s_2_62[4] = { 'l', 'o', 'g', 'a' }; +static const symbol s_2_63[5] = { 'e', 'l', 'o', 'g', 'a' }; +static const symbol s_2_64[4] = { 'n', 'o', 'g', 'a' }; +static const symbol s_2_65[6] = { 'c', 'i', 'n', 'o', 'g', 'a' }; +static const symbol s_2_66[7] = { 0xC4, 0x8D, 'i', 'n', 'o', 'g', 'a' }; +static const symbol s_2_67[5] = { 'o', 's', 'o', 'g', 'a' }; +static const symbol s_2_68[5] = { 'a', 't', 'o', 'g', 'a' }; +static const symbol s_2_69[7] = { 'e', 'v', 'i', 't', 'o', 'g', 'a' }; +static const symbol s_2_70[7] = { 'o', 'v', 'i', 't', 'o', 'g', 'a' }; +static const symbol s_2_71[6] = { 'a', 's', 't', 'o', 'g', 'a' }; +static const symbol s_2_72[5] = { 'a', 'v', 'o', 'g', 'a' }; +static const symbol s_2_73[5] = { 'e', 'v', 'o', 'g', 'a' }; +static const symbol s_2_74[5] = { 'i', 'v', 'o', 'g', 'a' }; +static const symbol s_2_75[5] = { 'o', 'v', 'o', 'g', 'a' }; +static const symbol s_2_76[6] = { 'a', 0xC4, 0x87, 'o', 'g', 'a' }; +static const symbol s_2_77[6] = { 'e', 0xC4, 0x87, 'o', 'g', 'a' }; +static const symbol s_2_78[6] = { 'u', 0xC4, 0x87, 'o', 'g', 'a' }; +static const symbol s_2_79[6] = { 'o', 0xC5, 0xA1, 'o', 'g', 'a' }; +static const symbol s_2_80[3] = { 'u', 'g', 'a' }; +static const symbol s_2_81[3] = { 'a', 'j', 'a' }; +static const symbol s_2_82[4] = { 'c', 'a', 'j', 'a' }; +static const symbol s_2_83[4] = { 'l', 'a', 'j', 'a' }; +static const symbol s_2_84[4] = { 'r', 'a', 'j', 'a' }; +static const symbol s_2_85[5] = { 0xC4, 0x87, 'a', 'j', 'a' }; +static const symbol s_2_86[5] = { 0xC4, 0x8D, 'a', 'j', 'a' }; +static const symbol s_2_87[5] = { 0xC4, 0x91, 'a', 'j', 'a' }; +static const symbol s_2_88[4] = { 'b', 'i', 'j', 'a' }; +static const symbol s_2_89[4] = { 'c', 'i', 'j', 'a' }; +static const symbol s_2_90[4] = { 'd', 'i', 'j', 'a' }; +static const symbol s_2_91[4] = { 'f', 'i', 'j', 'a' }; +static const symbol s_2_92[4] = { 'g', 'i', 'j', 'a' }; +static const symbol s_2_93[6] = { 'a', 'n', 'j', 'i', 'j', 'a' }; +static const symbol s_2_94[6] = { 'e', 'n', 'j', 'i', 'j', 'a' }; +static const symbol s_2_95[6] = { 's', 'n', 'j', 'i', 'j', 'a' }; +static const symbol s_2_96[7] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'a' }; +static const symbol s_2_97[4] = { 'k', 'i', 'j', 'a' }; +static const symbol s_2_98[5] = { 's', 'k', 'i', 'j', 'a' }; +static const symbol s_2_99[6] = { 0xC5, 0xA1, 'k', 'i', 'j', 'a' }; +static const symbol s_2_100[4] = { 'l', 'i', 'j', 'a' }; +static const symbol s_2_101[5] = { 'e', 'l', 'i', 'j', 'a' }; +static const symbol s_2_102[4] = { 'm', 'i', 'j', 'a' }; +static const symbol s_2_103[4] = { 'n', 'i', 'j', 'a' }; +static const symbol s_2_104[6] = { 'g', 'a', 'n', 'i', 'j', 'a' }; +static const symbol s_2_105[6] = { 'm', 'a', 'n', 'i', 'j', 'a' }; +static const symbol s_2_106[6] = { 'p', 'a', 'n', 'i', 'j', 'a' }; +static const symbol s_2_107[6] = { 'r', 'a', 'n', 'i', 'j', 'a' }; +static const symbol s_2_108[6] = { 't', 'a', 'n', 'i', 'j', 'a' }; +static const symbol s_2_109[4] = { 'p', 'i', 'j', 'a' }; +static const symbol s_2_110[4] = { 'r', 'i', 'j', 'a' }; +static const symbol s_2_111[6] = { 'r', 'a', 'r', 'i', 'j', 'a' }; +static const symbol s_2_112[4] = { 's', 'i', 'j', 'a' }; +static const symbol s_2_113[5] = { 'o', 's', 'i', 'j', 'a' }; +static const symbol s_2_114[4] = { 't', 'i', 'j', 'a' }; +static const symbol s_2_115[5] = { 'a', 't', 'i', 'j', 'a' }; +static const symbol s_2_116[7] = { 'e', 'v', 'i', 't', 'i', 'j', 'a' }; +static const symbol s_2_117[7] = { 'o', 'v', 'i', 't', 'i', 'j', 'a' }; +static const symbol s_2_118[5] = { 'o', 't', 'i', 'j', 'a' }; +static const symbol s_2_119[6] = { 'a', 's', 't', 'i', 'j', 'a' }; +static const symbol s_2_120[5] = { 'a', 'v', 'i', 'j', 'a' }; +static const symbol s_2_121[5] = { 'e', 'v', 'i', 'j', 'a' }; +static const symbol s_2_122[5] = { 'i', 'v', 'i', 'j', 'a' }; +static const symbol s_2_123[5] = { 'o', 'v', 'i', 'j', 'a' }; +static const symbol s_2_124[4] = { 'z', 'i', 'j', 'a' }; +static const symbol s_2_125[6] = { 'o', 0xC5, 0xA1, 'i', 'j', 'a' }; +static const symbol s_2_126[5] = { 0xC5, 0xBE, 'i', 'j', 'a' }; +static const symbol s_2_127[4] = { 'a', 'n', 'j', 'a' }; +static const symbol s_2_128[4] = { 'e', 'n', 'j', 'a' }; +static const symbol s_2_129[4] = { 's', 'n', 'j', 'a' }; +static const symbol s_2_130[5] = { 0xC5, 0xA1, 'n', 'j', 'a' }; +static const symbol s_2_131[2] = { 'k', 'a' }; +static const symbol s_2_132[3] = { 's', 'k', 'a' }; +static const symbol s_2_133[4] = { 0xC5, 0xA1, 'k', 'a' }; +static const symbol s_2_134[3] = { 'a', 'l', 'a' }; +static const symbol s_2_135[5] = { 'a', 'c', 'a', 'l', 'a' }; +static const symbol s_2_136[8] = { 'a', 's', 't', 'a', 'j', 'a', 'l', 'a' }; +static const symbol s_2_137[8] = { 'i', 's', 't', 'a', 'j', 'a', 'l', 'a' }; +static const symbol s_2_138[8] = { 'o', 's', 't', 'a', 'j', 'a', 'l', 'a' }; +static const symbol s_2_139[5] = { 'i', 'j', 'a', 'l', 'a' }; +static const symbol s_2_140[6] = { 'i', 'n', 'j', 'a', 'l', 'a' }; +static const symbol s_2_141[4] = { 'n', 'a', 'l', 'a' }; +static const symbol s_2_142[5] = { 'i', 'r', 'a', 'l', 'a' }; +static const symbol s_2_143[5] = { 'u', 'r', 'a', 'l', 'a' }; +static const symbol s_2_144[4] = { 't', 'a', 'l', 'a' }; +static const symbol s_2_145[6] = { 'a', 's', 't', 'a', 'l', 'a' }; +static const symbol s_2_146[6] = { 'i', 's', 't', 'a', 'l', 'a' }; +static const symbol s_2_147[6] = { 'o', 's', 't', 'a', 'l', 'a' }; +static const symbol s_2_148[5] = { 'a', 'v', 'a', 'l', 'a' }; +static const symbol s_2_149[5] = { 'e', 'v', 'a', 'l', 'a' }; +static const symbol s_2_150[5] = { 'i', 'v', 'a', 'l', 'a' }; +static const symbol s_2_151[5] = { 'o', 'v', 'a', 'l', 'a' }; +static const symbol s_2_152[5] = { 'u', 'v', 'a', 'l', 'a' }; +static const symbol s_2_153[6] = { 'a', 0xC4, 0x8D, 'a', 'l', 'a' }; +static const symbol s_2_154[3] = { 'e', 'l', 'a' }; +static const symbol s_2_155[3] = { 'i', 'l', 'a' }; +static const symbol s_2_156[5] = { 'a', 'c', 'i', 'l', 'a' }; +static const symbol s_2_157[6] = { 'l', 'u', 'c', 'i', 'l', 'a' }; +static const symbol s_2_158[4] = { 'n', 'i', 'l', 'a' }; +static const symbol s_2_159[8] = { 'a', 's', 't', 'a', 'n', 'i', 'l', 'a' }; +static const symbol s_2_160[8] = { 'i', 's', 't', 'a', 'n', 'i', 'l', 'a' }; +static const symbol s_2_161[8] = { 'o', 's', 't', 'a', 'n', 'i', 'l', 'a' }; +static const symbol s_2_162[6] = { 'r', 'o', 's', 'i', 'l', 'a' }; +static const symbol s_2_163[6] = { 'j', 'e', 't', 'i', 'l', 'a' }; +static const symbol s_2_164[5] = { 'o', 'z', 'i', 'l', 'a' }; +static const symbol s_2_165[6] = { 'a', 0xC4, 0x8D, 'i', 'l', 'a' }; +static const symbol s_2_166[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 'l', 'a' }; +static const symbol s_2_167[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 'l', 'a' }; +static const symbol s_2_168[3] = { 'o', 'l', 'a' }; +static const symbol s_2_169[4] = { 'a', 's', 'l', 'a' }; +static const symbol s_2_170[4] = { 'n', 'u', 'l', 'a' }; +static const symbol s_2_171[4] = { 'g', 'a', 'm', 'a' }; +static const symbol s_2_172[6] = { 'l', 'o', 'g', 'a', 'm', 'a' }; +static const symbol s_2_173[5] = { 'u', 'g', 'a', 'm', 'a' }; +static const symbol s_2_174[5] = { 'a', 'j', 'a', 'm', 'a' }; +static const symbol s_2_175[6] = { 'c', 'a', 'j', 'a', 'm', 'a' }; +static const symbol s_2_176[6] = { 'l', 'a', 'j', 'a', 'm', 'a' }; +static const symbol s_2_177[6] = { 'r', 'a', 'j', 'a', 'm', 'a' }; +static const symbol s_2_178[7] = { 0xC4, 0x87, 'a', 'j', 'a', 'm', 'a' }; +static const symbol s_2_179[7] = { 0xC4, 0x8D, 'a', 'j', 'a', 'm', 'a' }; +static const symbol s_2_180[7] = { 0xC4, 0x91, 'a', 'j', 'a', 'm', 'a' }; +static const symbol s_2_181[6] = { 'b', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_182[6] = { 'c', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_183[6] = { 'd', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_184[6] = { 'f', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_185[6] = { 'g', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_186[6] = { 'l', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_187[6] = { 'm', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_188[6] = { 'n', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_189[8] = { 'g', 'a', 'n', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_190[8] = { 'm', 'a', 'n', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_191[8] = { 'p', 'a', 'n', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_192[8] = { 'r', 'a', 'n', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_193[8] = { 't', 'a', 'n', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_194[6] = { 'p', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_195[6] = { 'r', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_196[6] = { 's', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_197[6] = { 't', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_198[6] = { 'z', 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_199[7] = { 0xC5, 0xBE, 'i', 'j', 'a', 'm', 'a' }; +static const symbol s_2_200[5] = { 'a', 'l', 'a', 'm', 'a' }; +static const symbol s_2_201[7] = { 'i', 'j', 'a', 'l', 'a', 'm', 'a' }; +static const symbol s_2_202[6] = { 'n', 'a', 'l', 'a', 'm', 'a' }; +static const symbol s_2_203[5] = { 'e', 'l', 'a', 'm', 'a' }; +static const symbol s_2_204[5] = { 'i', 'l', 'a', 'm', 'a' }; +static const symbol s_2_205[6] = { 'r', 'a', 'm', 'a', 'm', 'a' }; +static const symbol s_2_206[6] = { 'l', 'e', 'm', 'a', 'm', 'a' }; +static const symbol s_2_207[5] = { 'i', 'n', 'a', 'm', 'a' }; +static const symbol s_2_208[6] = { 'c', 'i', 'n', 'a', 'm', 'a' }; +static const symbol s_2_209[7] = { 0xC4, 0x8D, 'i', 'n', 'a', 'm', 'a' }; +static const symbol s_2_210[4] = { 'r', 'a', 'm', 'a' }; +static const symbol s_2_211[5] = { 'a', 'r', 'a', 'm', 'a' }; +static const symbol s_2_212[5] = { 'd', 'r', 'a', 'm', 'a' }; +static const symbol s_2_213[5] = { 'e', 'r', 'a', 'm', 'a' }; +static const symbol s_2_214[5] = { 'o', 'r', 'a', 'm', 'a' }; +static const symbol s_2_215[6] = { 'b', 'a', 's', 'a', 'm', 'a' }; +static const symbol s_2_216[6] = { 'g', 'a', 's', 'a', 'm', 'a' }; +static const symbol s_2_217[6] = { 'j', 'a', 's', 'a', 'm', 'a' }; +static const symbol s_2_218[6] = { 'k', 'a', 's', 'a', 'm', 'a' }; +static const symbol s_2_219[6] = { 'n', 'a', 's', 'a', 'm', 'a' }; +static const symbol s_2_220[6] = { 't', 'a', 's', 'a', 'm', 'a' }; +static const symbol s_2_221[6] = { 'v', 'a', 's', 'a', 'm', 'a' }; +static const symbol s_2_222[5] = { 'e', 's', 'a', 'm', 'a' }; +static const symbol s_2_223[5] = { 'i', 's', 'a', 'm', 'a' }; +static const symbol s_2_224[5] = { 'e', 't', 'a', 'm', 'a' }; +static const symbol s_2_225[6] = { 'e', 's', 't', 'a', 'm', 'a' }; +static const symbol s_2_226[6] = { 'i', 's', 't', 'a', 'm', 'a' }; +static const symbol s_2_227[6] = { 'k', 's', 't', 'a', 'm', 'a' }; +static const symbol s_2_228[6] = { 'o', 's', 't', 'a', 'm', 'a' }; +static const symbol s_2_229[5] = { 'a', 'v', 'a', 'm', 'a' }; +static const symbol s_2_230[5] = { 'e', 'v', 'a', 'm', 'a' }; +static const symbol s_2_231[5] = { 'i', 'v', 'a', 'm', 'a' }; +static const symbol s_2_232[7] = { 'b', 'a', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_233[7] = { 'g', 'a', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_234[7] = { 'j', 'a', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_235[7] = { 'k', 'a', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_236[7] = { 'n', 'a', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_237[7] = { 't', 'a', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_238[7] = { 'v', 'a', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_239[6] = { 'e', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_240[6] = { 'i', 0xC5, 0xA1, 'a', 'm', 'a' }; +static const symbol s_2_241[4] = { 'l', 'e', 'm', 'a' }; +static const symbol s_2_242[5] = { 'a', 'c', 'i', 'm', 'a' }; +static const symbol s_2_243[5] = { 'e', 'c', 'i', 'm', 'a' }; +static const symbol s_2_244[5] = { 'u', 'c', 'i', 'm', 'a' }; +static const symbol s_2_245[5] = { 'a', 'j', 'i', 'm', 'a' }; +static const symbol s_2_246[6] = { 'c', 'a', 'j', 'i', 'm', 'a' }; +static const symbol s_2_247[6] = { 'l', 'a', 'j', 'i', 'm', 'a' }; +static const symbol s_2_248[6] = { 'r', 'a', 'j', 'i', 'm', 'a' }; +static const symbol s_2_249[7] = { 0xC4, 0x87, 'a', 'j', 'i', 'm', 'a' }; +static const symbol s_2_250[7] = { 0xC4, 0x8D, 'a', 'j', 'i', 'm', 'a' }; +static const symbol s_2_251[7] = { 0xC4, 0x91, 'a', 'j', 'i', 'm', 'a' }; +static const symbol s_2_252[6] = { 'b', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_253[6] = { 'c', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_254[6] = { 'd', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_255[6] = { 'f', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_256[6] = { 'g', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_257[8] = { 'a', 'n', 'j', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_258[8] = { 'e', 'n', 'j', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_259[8] = { 's', 'n', 'j', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_260[9] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_261[6] = { 'k', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_262[7] = { 's', 'k', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_263[8] = { 0xC5, 0xA1, 'k', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_264[6] = { 'l', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_265[7] = { 'e', 'l', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_266[6] = { 'm', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_267[6] = { 'n', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_268[8] = { 'g', 'a', 'n', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_269[8] = { 'm', 'a', 'n', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_270[8] = { 'p', 'a', 'n', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_271[8] = { 'r', 'a', 'n', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_272[8] = { 't', 'a', 'n', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_273[6] = { 'p', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_274[6] = { 'r', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_275[6] = { 's', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_276[7] = { 'o', 's', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_277[6] = { 't', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_278[7] = { 'a', 't', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_279[9] = { 'e', 'v', 'i', 't', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_280[9] = { 'o', 'v', 'i', 't', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_281[8] = { 'a', 's', 't', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_282[7] = { 'a', 'v', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_283[7] = { 'e', 'v', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_284[7] = { 'i', 'v', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_285[7] = { 'o', 'v', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_286[6] = { 'z', 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_287[8] = { 'o', 0xC5, 0xA1, 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_288[7] = { 0xC5, 0xBE, 'i', 'j', 'i', 'm', 'a' }; +static const symbol s_2_289[6] = { 'a', 'n', 'j', 'i', 'm', 'a' }; +static const symbol s_2_290[6] = { 'e', 'n', 'j', 'i', 'm', 'a' }; +static const symbol s_2_291[6] = { 's', 'n', 'j', 'i', 'm', 'a' }; +static const symbol s_2_292[7] = { 0xC5, 0xA1, 'n', 'j', 'i', 'm', 'a' }; +static const symbol s_2_293[4] = { 'k', 'i', 'm', 'a' }; +static const symbol s_2_294[5] = { 's', 'k', 'i', 'm', 'a' }; +static const symbol s_2_295[6] = { 0xC5, 0xA1, 'k', 'i', 'm', 'a' }; +static const symbol s_2_296[5] = { 'a', 'l', 'i', 'm', 'a' }; +static const symbol s_2_297[7] = { 'i', 'j', 'a', 'l', 'i', 'm', 'a' }; +static const symbol s_2_298[6] = { 'n', 'a', 'l', 'i', 'm', 'a' }; +static const symbol s_2_299[5] = { 'e', 'l', 'i', 'm', 'a' }; +static const symbol s_2_300[5] = { 'i', 'l', 'i', 'm', 'a' }; +static const symbol s_2_301[7] = { 'o', 'z', 'i', 'l', 'i', 'm', 'a' }; +static const symbol s_2_302[5] = { 'o', 'l', 'i', 'm', 'a' }; +static const symbol s_2_303[6] = { 'l', 'e', 'm', 'i', 'm', 'a' }; +static const symbol s_2_304[4] = { 'n', 'i', 'm', 'a' }; +static const symbol s_2_305[5] = { 'a', 'n', 'i', 'm', 'a' }; +static const symbol s_2_306[5] = { 'i', 'n', 'i', 'm', 'a' }; +static const symbol s_2_307[6] = { 'c', 'i', 'n', 'i', 'm', 'a' }; +static const symbol s_2_308[7] = { 0xC4, 0x8D, 'i', 'n', 'i', 'm', 'a' }; +static const symbol s_2_309[5] = { 'o', 'n', 'i', 'm', 'a' }; +static const symbol s_2_310[5] = { 'a', 'r', 'i', 'm', 'a' }; +static const symbol s_2_311[5] = { 'd', 'r', 'i', 'm', 'a' }; +static const symbol s_2_312[5] = { 'e', 'r', 'i', 'm', 'a' }; +static const symbol s_2_313[5] = { 'o', 'r', 'i', 'm', 'a' }; +static const symbol s_2_314[6] = { 'b', 'a', 's', 'i', 'm', 'a' }; +static const symbol s_2_315[6] = { 'g', 'a', 's', 'i', 'm', 'a' }; +static const symbol s_2_316[6] = { 'j', 'a', 's', 'i', 'm', 'a' }; +static const symbol s_2_317[6] = { 'k', 'a', 's', 'i', 'm', 'a' }; +static const symbol s_2_318[6] = { 'n', 'a', 's', 'i', 'm', 'a' }; +static const symbol s_2_319[6] = { 't', 'a', 's', 'i', 'm', 'a' }; +static const symbol s_2_320[6] = { 'v', 'a', 's', 'i', 'm', 'a' }; +static const symbol s_2_321[5] = { 'e', 's', 'i', 'm', 'a' }; +static const symbol s_2_322[5] = { 'i', 's', 'i', 'm', 'a' }; +static const symbol s_2_323[5] = { 'o', 's', 'i', 'm', 'a' }; +static const symbol s_2_324[5] = { 'a', 't', 'i', 'm', 'a' }; +static const symbol s_2_325[7] = { 'i', 'k', 'a', 't', 'i', 'm', 'a' }; +static const symbol s_2_326[6] = { 'l', 'a', 't', 'i', 'm', 'a' }; +static const symbol s_2_327[5] = { 'e', 't', 'i', 'm', 'a' }; +static const symbol s_2_328[7] = { 'e', 'v', 'i', 't', 'i', 'm', 'a' }; +static const symbol s_2_329[7] = { 'o', 'v', 'i', 't', 'i', 'm', 'a' }; +static const symbol s_2_330[6] = { 'a', 's', 't', 'i', 'm', 'a' }; +static const symbol s_2_331[6] = { 'e', 's', 't', 'i', 'm', 'a' }; +static const symbol s_2_332[6] = { 'i', 's', 't', 'i', 'm', 'a' }; +static const symbol s_2_333[6] = { 'k', 's', 't', 'i', 'm', 'a' }; +static const symbol s_2_334[6] = { 'o', 's', 't', 'i', 'm', 'a' }; +static const symbol s_2_335[7] = { 'i', 0xC5, 0xA1, 't', 'i', 'm', 'a' }; +static const symbol s_2_336[5] = { 'a', 'v', 'i', 'm', 'a' }; +static const symbol s_2_337[5] = { 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_338[7] = { 'a', 'j', 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_339[8] = { 'c', 'a', 'j', 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_340[8] = { 'l', 'a', 'j', 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_341[8] = { 'r', 'a', 'j', 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_342[9] = { 0xC4, 0x87, 'a', 'j', 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_343[9] = { 0xC4, 0x8D, 'a', 'j', 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_344[9] = { 0xC4, 0x91, 'a', 'j', 'e', 'v', 'i', 'm', 'a' }; +static const symbol s_2_345[5] = { 'i', 'v', 'i', 'm', 'a' }; +static const symbol s_2_346[5] = { 'o', 'v', 'i', 'm', 'a' }; +static const symbol s_2_347[6] = { 'g', 'o', 'v', 'i', 'm', 'a' }; +static const symbol s_2_348[7] = { 'u', 'g', 'o', 'v', 'i', 'm', 'a' }; +static const symbol s_2_349[6] = { 'l', 'o', 'v', 'i', 'm', 'a' }; +static const symbol s_2_350[7] = { 'o', 'l', 'o', 'v', 'i', 'm', 'a' }; +static const symbol s_2_351[6] = { 'm', 'o', 'v', 'i', 'm', 'a' }; +static const symbol s_2_352[7] = { 'o', 'n', 'o', 'v', 'i', 'm', 'a' }; +static const symbol s_2_353[6] = { 's', 't', 'v', 'i', 'm', 'a' }; +static const symbol s_2_354[7] = { 0xC5, 0xA1, 't', 'v', 'i', 'm', 'a' }; +static const symbol s_2_355[6] = { 'a', 0xC4, 0x87, 'i', 'm', 'a' }; +static const symbol s_2_356[6] = { 'e', 0xC4, 0x87, 'i', 'm', 'a' }; +static const symbol s_2_357[6] = { 'u', 0xC4, 0x87, 'i', 'm', 'a' }; +static const symbol s_2_358[7] = { 'b', 'a', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_359[7] = { 'g', 'a', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_360[7] = { 'j', 'a', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_361[7] = { 'k', 'a', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_362[7] = { 'n', 'a', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_363[7] = { 't', 'a', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_364[7] = { 'v', 'a', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_365[6] = { 'e', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_366[6] = { 'i', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_367[6] = { 'o', 0xC5, 0xA1, 'i', 'm', 'a' }; +static const symbol s_2_368[2] = { 'n', 'a' }; +static const symbol s_2_369[3] = { 'a', 'n', 'a' }; +static const symbol s_2_370[5] = { 'a', 'c', 'a', 'n', 'a' }; +static const symbol s_2_371[5] = { 'u', 'r', 'a', 'n', 'a' }; +static const symbol s_2_372[4] = { 't', 'a', 'n', 'a' }; +static const symbol s_2_373[5] = { 'a', 'v', 'a', 'n', 'a' }; +static const symbol s_2_374[5] = { 'e', 'v', 'a', 'n', 'a' }; +static const symbol s_2_375[5] = { 'i', 'v', 'a', 'n', 'a' }; +static const symbol s_2_376[5] = { 'u', 'v', 'a', 'n', 'a' }; +static const symbol s_2_377[6] = { 'a', 0xC4, 0x8D, 'a', 'n', 'a' }; +static const symbol s_2_378[5] = { 'a', 'c', 'e', 'n', 'a' }; +static const symbol s_2_379[6] = { 'l', 'u', 'c', 'e', 'n', 'a' }; +static const symbol s_2_380[6] = { 'a', 0xC4, 0x8D, 'e', 'n', 'a' }; +static const symbol s_2_381[7] = { 'l', 'u', 0xC4, 0x8D, 'e', 'n', 'a' }; +static const symbol s_2_382[3] = { 'i', 'n', 'a' }; +static const symbol s_2_383[4] = { 'c', 'i', 'n', 'a' }; +static const symbol s_2_384[5] = { 'a', 'n', 'i', 'n', 'a' }; +static const symbol s_2_385[5] = { 0xC4, 0x8D, 'i', 'n', 'a' }; +static const symbol s_2_386[3] = { 'o', 'n', 'a' }; +static const symbol s_2_387[3] = { 'a', 'r', 'a' }; +static const symbol s_2_388[3] = { 'd', 'r', 'a' }; +static const symbol s_2_389[3] = { 'e', 'r', 'a' }; +static const symbol s_2_390[3] = { 'o', 'r', 'a' }; +static const symbol s_2_391[4] = { 'b', 'a', 's', 'a' }; +static const symbol s_2_392[4] = { 'g', 'a', 's', 'a' }; +static const symbol s_2_393[4] = { 'j', 'a', 's', 'a' }; +static const symbol s_2_394[4] = { 'k', 'a', 's', 'a' }; +static const symbol s_2_395[4] = { 'n', 'a', 's', 'a' }; +static const symbol s_2_396[4] = { 't', 'a', 's', 'a' }; +static const symbol s_2_397[4] = { 'v', 'a', 's', 'a' }; +static const symbol s_2_398[3] = { 'e', 's', 'a' }; +static const symbol s_2_399[3] = { 'i', 's', 'a' }; +static const symbol s_2_400[3] = { 'o', 's', 'a' }; +static const symbol s_2_401[3] = { 'a', 't', 'a' }; +static const symbol s_2_402[5] = { 'i', 'k', 'a', 't', 'a' }; +static const symbol s_2_403[4] = { 'l', 'a', 't', 'a' }; +static const symbol s_2_404[3] = { 'e', 't', 'a' }; +static const symbol s_2_405[5] = { 'e', 'v', 'i', 't', 'a' }; +static const symbol s_2_406[5] = { 'o', 'v', 'i', 't', 'a' }; +static const symbol s_2_407[4] = { 'a', 's', 't', 'a' }; +static const symbol s_2_408[4] = { 'e', 's', 't', 'a' }; +static const symbol s_2_409[4] = { 'i', 's', 't', 'a' }; +static const symbol s_2_410[4] = { 'k', 's', 't', 'a' }; +static const symbol s_2_411[4] = { 'o', 's', 't', 'a' }; +static const symbol s_2_412[4] = { 'n', 'u', 't', 'a' }; +static const symbol s_2_413[5] = { 'i', 0xC5, 0xA1, 't', 'a' }; +static const symbol s_2_414[3] = { 'a', 'v', 'a' }; +static const symbol s_2_415[3] = { 'e', 'v', 'a' }; +static const symbol s_2_416[5] = { 'a', 'j', 'e', 'v', 'a' }; +static const symbol s_2_417[6] = { 'c', 'a', 'j', 'e', 'v', 'a' }; +static const symbol s_2_418[6] = { 'l', 'a', 'j', 'e', 'v', 'a' }; +static const symbol s_2_419[6] = { 'r', 'a', 'j', 'e', 'v', 'a' }; +static const symbol s_2_420[7] = { 0xC4, 0x87, 'a', 'j', 'e', 'v', 'a' }; +static const symbol s_2_421[7] = { 0xC4, 0x8D, 'a', 'j', 'e', 'v', 'a' }; +static const symbol s_2_422[7] = { 0xC4, 0x91, 'a', 'j', 'e', 'v', 'a' }; +static const symbol s_2_423[3] = { 'i', 'v', 'a' }; +static const symbol s_2_424[3] = { 'o', 'v', 'a' }; +static const symbol s_2_425[4] = { 'g', 'o', 'v', 'a' }; +static const symbol s_2_426[5] = { 'u', 'g', 'o', 'v', 'a' }; +static const symbol s_2_427[4] = { 'l', 'o', 'v', 'a' }; +static const symbol s_2_428[5] = { 'o', 'l', 'o', 'v', 'a' }; +static const symbol s_2_429[4] = { 'm', 'o', 'v', 'a' }; +static const symbol s_2_430[5] = { 'o', 'n', 'o', 'v', 'a' }; +static const symbol s_2_431[4] = { 's', 't', 'v', 'a' }; +static const symbol s_2_432[5] = { 0xC5, 0xA1, 't', 'v', 'a' }; +static const symbol s_2_433[4] = { 'a', 0xC4, 0x87, 'a' }; +static const symbol s_2_434[4] = { 'e', 0xC4, 0x87, 'a' }; +static const symbol s_2_435[4] = { 'u', 0xC4, 0x87, 'a' }; +static const symbol s_2_436[5] = { 'b', 'a', 0xC5, 0xA1, 'a' }; +static const symbol s_2_437[5] = { 'g', 'a', 0xC5, 0xA1, 'a' }; +static const symbol s_2_438[5] = { 'j', 'a', 0xC5, 0xA1, 'a' }; +static const symbol s_2_439[5] = { 'k', 'a', 0xC5, 0xA1, 'a' }; +static const symbol s_2_440[5] = { 'n', 'a', 0xC5, 0xA1, 'a' }; +static const symbol s_2_441[5] = { 't', 'a', 0xC5, 0xA1, 'a' }; +static const symbol s_2_442[5] = { 'v', 'a', 0xC5, 0xA1, 'a' }; +static const symbol s_2_443[4] = { 'e', 0xC5, 0xA1, 'a' }; +static const symbol s_2_444[4] = { 'i', 0xC5, 0xA1, 'a' }; +static const symbol s_2_445[4] = { 'o', 0xC5, 0xA1, 'a' }; +static const symbol s_2_446[3] = { 'a', 'c', 'e' }; +static const symbol s_2_447[3] = { 'e', 'c', 'e' }; +static const symbol s_2_448[3] = { 'u', 'c', 'e' }; +static const symbol s_2_449[4] = { 'l', 'u', 'c', 'e' }; +static const symbol s_2_450[6] = { 'a', 's', 't', 'a', 'd', 'e' }; +static const symbol s_2_451[6] = { 'i', 's', 't', 'a', 'd', 'e' }; +static const symbol s_2_452[6] = { 'o', 's', 't', 'a', 'd', 'e' }; +static const symbol s_2_453[2] = { 'g', 'e' }; +static const symbol s_2_454[4] = { 'l', 'o', 'g', 'e' }; +static const symbol s_2_455[3] = { 'u', 'g', 'e' }; +static const symbol s_2_456[3] = { 'a', 'j', 'e' }; +static const symbol s_2_457[4] = { 'c', 'a', 'j', 'e' }; +static const symbol s_2_458[4] = { 'l', 'a', 'j', 'e' }; +static const symbol s_2_459[4] = { 'r', 'a', 'j', 'e' }; +static const symbol s_2_460[6] = { 'a', 's', 't', 'a', 'j', 'e' }; +static const symbol s_2_461[6] = { 'i', 's', 't', 'a', 'j', 'e' }; +static const symbol s_2_462[6] = { 'o', 's', 't', 'a', 'j', 'e' }; +static const symbol s_2_463[5] = { 0xC4, 0x87, 'a', 'j', 'e' }; +static const symbol s_2_464[5] = { 0xC4, 0x8D, 'a', 'j', 'e' }; +static const symbol s_2_465[5] = { 0xC4, 0x91, 'a', 'j', 'e' }; +static const symbol s_2_466[3] = { 'i', 'j', 'e' }; +static const symbol s_2_467[4] = { 'b', 'i', 'j', 'e' }; +static const symbol s_2_468[4] = { 'c', 'i', 'j', 'e' }; +static const symbol s_2_469[4] = { 'd', 'i', 'j', 'e' }; +static const symbol s_2_470[4] = { 'f', 'i', 'j', 'e' }; +static const symbol s_2_471[4] = { 'g', 'i', 'j', 'e' }; +static const symbol s_2_472[6] = { 'a', 'n', 'j', 'i', 'j', 'e' }; +static const symbol s_2_473[6] = { 'e', 'n', 'j', 'i', 'j', 'e' }; +static const symbol s_2_474[6] = { 's', 'n', 'j', 'i', 'j', 'e' }; +static const symbol s_2_475[7] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'e' }; +static const symbol s_2_476[4] = { 'k', 'i', 'j', 'e' }; +static const symbol s_2_477[5] = { 's', 'k', 'i', 'j', 'e' }; +static const symbol s_2_478[6] = { 0xC5, 0xA1, 'k', 'i', 'j', 'e' }; +static const symbol s_2_479[4] = { 'l', 'i', 'j', 'e' }; +static const symbol s_2_480[5] = { 'e', 'l', 'i', 'j', 'e' }; +static const symbol s_2_481[4] = { 'm', 'i', 'j', 'e' }; +static const symbol s_2_482[4] = { 'n', 'i', 'j', 'e' }; +static const symbol s_2_483[6] = { 'g', 'a', 'n', 'i', 'j', 'e' }; +static const symbol s_2_484[6] = { 'm', 'a', 'n', 'i', 'j', 'e' }; +static const symbol s_2_485[6] = { 'p', 'a', 'n', 'i', 'j', 'e' }; +static const symbol s_2_486[6] = { 'r', 'a', 'n', 'i', 'j', 'e' }; +static const symbol s_2_487[6] = { 't', 'a', 'n', 'i', 'j', 'e' }; +static const symbol s_2_488[4] = { 'p', 'i', 'j', 'e' }; +static const symbol s_2_489[4] = { 'r', 'i', 'j', 'e' }; +static const symbol s_2_490[4] = { 's', 'i', 'j', 'e' }; +static const symbol s_2_491[5] = { 'o', 's', 'i', 'j', 'e' }; +static const symbol s_2_492[4] = { 't', 'i', 'j', 'e' }; +static const symbol s_2_493[5] = { 'a', 't', 'i', 'j', 'e' }; +static const symbol s_2_494[7] = { 'e', 'v', 'i', 't', 'i', 'j', 'e' }; +static const symbol s_2_495[7] = { 'o', 'v', 'i', 't', 'i', 'j', 'e' }; +static const symbol s_2_496[6] = { 'a', 's', 't', 'i', 'j', 'e' }; +static const symbol s_2_497[5] = { 'a', 'v', 'i', 'j', 'e' }; +static const symbol s_2_498[5] = { 'e', 'v', 'i', 'j', 'e' }; +static const symbol s_2_499[5] = { 'i', 'v', 'i', 'j', 'e' }; +static const symbol s_2_500[5] = { 'o', 'v', 'i', 'j', 'e' }; +static const symbol s_2_501[4] = { 'z', 'i', 'j', 'e' }; +static const symbol s_2_502[6] = { 'o', 0xC5, 0xA1, 'i', 'j', 'e' }; +static const symbol s_2_503[5] = { 0xC5, 0xBE, 'i', 'j', 'e' }; +static const symbol s_2_504[4] = { 'a', 'n', 'j', 'e' }; +static const symbol s_2_505[4] = { 'e', 'n', 'j', 'e' }; +static const symbol s_2_506[4] = { 's', 'n', 'j', 'e' }; +static const symbol s_2_507[5] = { 0xC5, 0xA1, 'n', 'j', 'e' }; +static const symbol s_2_508[3] = { 'u', 'j', 'e' }; +static const symbol s_2_509[6] = { 'l', 'u', 'c', 'u', 'j', 'e' }; +static const symbol s_2_510[5] = { 'i', 'r', 'u', 'j', 'e' }; +static const symbol s_2_511[7] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'e' }; +static const symbol s_2_512[2] = { 'k', 'e' }; +static const symbol s_2_513[3] = { 's', 'k', 'e' }; +static const symbol s_2_514[4] = { 0xC5, 0xA1, 'k', 'e' }; +static const symbol s_2_515[3] = { 'a', 'l', 'e' }; +static const symbol s_2_516[5] = { 'a', 'c', 'a', 'l', 'e' }; +static const symbol s_2_517[8] = { 'a', 's', 't', 'a', 'j', 'a', 'l', 'e' }; +static const symbol s_2_518[8] = { 'i', 's', 't', 'a', 'j', 'a', 'l', 'e' }; +static const symbol s_2_519[8] = { 'o', 's', 't', 'a', 'j', 'a', 'l', 'e' }; +static const symbol s_2_520[5] = { 'i', 'j', 'a', 'l', 'e' }; +static const symbol s_2_521[6] = { 'i', 'n', 'j', 'a', 'l', 'e' }; +static const symbol s_2_522[4] = { 'n', 'a', 'l', 'e' }; +static const symbol s_2_523[5] = { 'i', 'r', 'a', 'l', 'e' }; +static const symbol s_2_524[5] = { 'u', 'r', 'a', 'l', 'e' }; +static const symbol s_2_525[4] = { 't', 'a', 'l', 'e' }; +static const symbol s_2_526[6] = { 'a', 's', 't', 'a', 'l', 'e' }; +static const symbol s_2_527[6] = { 'i', 's', 't', 'a', 'l', 'e' }; +static const symbol s_2_528[6] = { 'o', 's', 't', 'a', 'l', 'e' }; +static const symbol s_2_529[5] = { 'a', 'v', 'a', 'l', 'e' }; +static const symbol s_2_530[5] = { 'e', 'v', 'a', 'l', 'e' }; +static const symbol s_2_531[5] = { 'i', 'v', 'a', 'l', 'e' }; +static const symbol s_2_532[5] = { 'o', 'v', 'a', 'l', 'e' }; +static const symbol s_2_533[5] = { 'u', 'v', 'a', 'l', 'e' }; +static const symbol s_2_534[6] = { 'a', 0xC4, 0x8D, 'a', 'l', 'e' }; +static const symbol s_2_535[3] = { 'e', 'l', 'e' }; +static const symbol s_2_536[3] = { 'i', 'l', 'e' }; +static const symbol s_2_537[5] = { 'a', 'c', 'i', 'l', 'e' }; +static const symbol s_2_538[6] = { 'l', 'u', 'c', 'i', 'l', 'e' }; +static const symbol s_2_539[4] = { 'n', 'i', 'l', 'e' }; +static const symbol s_2_540[6] = { 'r', 'o', 's', 'i', 'l', 'e' }; +static const symbol s_2_541[6] = { 'j', 'e', 't', 'i', 'l', 'e' }; +static const symbol s_2_542[5] = { 'o', 'z', 'i', 'l', 'e' }; +static const symbol s_2_543[6] = { 'a', 0xC4, 0x8D, 'i', 'l', 'e' }; +static const symbol s_2_544[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 'l', 'e' }; +static const symbol s_2_545[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 'l', 'e' }; +static const symbol s_2_546[3] = { 'o', 'l', 'e' }; +static const symbol s_2_547[4] = { 'a', 's', 'l', 'e' }; +static const symbol s_2_548[4] = { 'n', 'u', 'l', 'e' }; +static const symbol s_2_549[4] = { 'r', 'a', 'm', 'e' }; +static const symbol s_2_550[4] = { 'l', 'e', 'm', 'e' }; +static const symbol s_2_551[5] = { 'a', 'c', 'o', 'm', 'e' }; +static const symbol s_2_552[5] = { 'e', 'c', 'o', 'm', 'e' }; +static const symbol s_2_553[5] = { 'u', 'c', 'o', 'm', 'e' }; +static const symbol s_2_554[6] = { 'a', 'n', 'j', 'o', 'm', 'e' }; +static const symbol s_2_555[6] = { 'e', 'n', 'j', 'o', 'm', 'e' }; +static const symbol s_2_556[6] = { 's', 'n', 'j', 'o', 'm', 'e' }; +static const symbol s_2_557[7] = { 0xC5, 0xA1, 'n', 'j', 'o', 'm', 'e' }; +static const symbol s_2_558[4] = { 'k', 'o', 'm', 'e' }; +static const symbol s_2_559[5] = { 's', 'k', 'o', 'm', 'e' }; +static const symbol s_2_560[6] = { 0xC5, 0xA1, 'k', 'o', 'm', 'e' }; +static const symbol s_2_561[5] = { 'e', 'l', 'o', 'm', 'e' }; +static const symbol s_2_562[4] = { 'n', 'o', 'm', 'e' }; +static const symbol s_2_563[6] = { 'c', 'i', 'n', 'o', 'm', 'e' }; +static const symbol s_2_564[7] = { 0xC4, 0x8D, 'i', 'n', 'o', 'm', 'e' }; +static const symbol s_2_565[5] = { 'o', 's', 'o', 'm', 'e' }; +static const symbol s_2_566[5] = { 'a', 't', 'o', 'm', 'e' }; +static const symbol s_2_567[7] = { 'e', 'v', 'i', 't', 'o', 'm', 'e' }; +static const symbol s_2_568[7] = { 'o', 'v', 'i', 't', 'o', 'm', 'e' }; +static const symbol s_2_569[6] = { 'a', 's', 't', 'o', 'm', 'e' }; +static const symbol s_2_570[5] = { 'a', 'v', 'o', 'm', 'e' }; +static const symbol s_2_571[5] = { 'e', 'v', 'o', 'm', 'e' }; +static const symbol s_2_572[5] = { 'i', 'v', 'o', 'm', 'e' }; +static const symbol s_2_573[5] = { 'o', 'v', 'o', 'm', 'e' }; +static const symbol s_2_574[6] = { 'a', 0xC4, 0x87, 'o', 'm', 'e' }; +static const symbol s_2_575[6] = { 'e', 0xC4, 0x87, 'o', 'm', 'e' }; +static const symbol s_2_576[6] = { 'u', 0xC4, 0x87, 'o', 'm', 'e' }; +static const symbol s_2_577[6] = { 'o', 0xC5, 0xA1, 'o', 'm', 'e' }; +static const symbol s_2_578[2] = { 'n', 'e' }; +static const symbol s_2_579[3] = { 'a', 'n', 'e' }; +static const symbol s_2_580[5] = { 'a', 'c', 'a', 'n', 'e' }; +static const symbol s_2_581[5] = { 'u', 'r', 'a', 'n', 'e' }; +static const symbol s_2_582[4] = { 't', 'a', 'n', 'e' }; +static const symbol s_2_583[6] = { 'a', 's', 't', 'a', 'n', 'e' }; +static const symbol s_2_584[6] = { 'i', 's', 't', 'a', 'n', 'e' }; +static const symbol s_2_585[6] = { 'o', 's', 't', 'a', 'n', 'e' }; +static const symbol s_2_586[5] = { 'a', 'v', 'a', 'n', 'e' }; +static const symbol s_2_587[5] = { 'e', 'v', 'a', 'n', 'e' }; +static const symbol s_2_588[5] = { 'i', 'v', 'a', 'n', 'e' }; +static const symbol s_2_589[5] = { 'u', 'v', 'a', 'n', 'e' }; +static const symbol s_2_590[6] = { 'a', 0xC4, 0x8D, 'a', 'n', 'e' }; +static const symbol s_2_591[5] = { 'a', 'c', 'e', 'n', 'e' }; +static const symbol s_2_592[6] = { 'l', 'u', 'c', 'e', 'n', 'e' }; +static const symbol s_2_593[6] = { 'a', 0xC4, 0x8D, 'e', 'n', 'e' }; +static const symbol s_2_594[7] = { 'l', 'u', 0xC4, 0x8D, 'e', 'n', 'e' }; +static const symbol s_2_595[3] = { 'i', 'n', 'e' }; +static const symbol s_2_596[4] = { 'c', 'i', 'n', 'e' }; +static const symbol s_2_597[5] = { 'a', 'n', 'i', 'n', 'e' }; +static const symbol s_2_598[5] = { 0xC4, 0x8D, 'i', 'n', 'e' }; +static const symbol s_2_599[3] = { 'o', 'n', 'e' }; +static const symbol s_2_600[3] = { 'a', 'r', 'e' }; +static const symbol s_2_601[3] = { 'd', 'r', 'e' }; +static const symbol s_2_602[3] = { 'e', 'r', 'e' }; +static const symbol s_2_603[3] = { 'o', 'r', 'e' }; +static const symbol s_2_604[3] = { 'a', 's', 'e' }; +static const symbol s_2_605[4] = { 'b', 'a', 's', 'e' }; +static const symbol s_2_606[5] = { 'a', 'c', 'a', 's', 'e' }; +static const symbol s_2_607[4] = { 'g', 'a', 's', 'e' }; +static const symbol s_2_608[4] = { 'j', 'a', 's', 'e' }; +static const symbol s_2_609[8] = { 'a', 's', 't', 'a', 'j', 'a', 's', 'e' }; +static const symbol s_2_610[8] = { 'i', 's', 't', 'a', 'j', 'a', 's', 'e' }; +static const symbol s_2_611[8] = { 'o', 's', 't', 'a', 'j', 'a', 's', 'e' }; +static const symbol s_2_612[6] = { 'i', 'n', 'j', 'a', 's', 'e' }; +static const symbol s_2_613[4] = { 'k', 'a', 's', 'e' }; +static const symbol s_2_614[4] = { 'n', 'a', 's', 'e' }; +static const symbol s_2_615[5] = { 'i', 'r', 'a', 's', 'e' }; +static const symbol s_2_616[5] = { 'u', 'r', 'a', 's', 'e' }; +static const symbol s_2_617[4] = { 't', 'a', 's', 'e' }; +static const symbol s_2_618[4] = { 'v', 'a', 's', 'e' }; +static const symbol s_2_619[5] = { 'a', 'v', 'a', 's', 'e' }; +static const symbol s_2_620[5] = { 'e', 'v', 'a', 's', 'e' }; +static const symbol s_2_621[5] = { 'i', 'v', 'a', 's', 'e' }; +static const symbol s_2_622[5] = { 'o', 'v', 'a', 's', 'e' }; +static const symbol s_2_623[5] = { 'u', 'v', 'a', 's', 'e' }; +static const symbol s_2_624[3] = { 'e', 's', 'e' }; +static const symbol s_2_625[3] = { 'i', 's', 'e' }; +static const symbol s_2_626[5] = { 'a', 'c', 'i', 's', 'e' }; +static const symbol s_2_627[6] = { 'l', 'u', 'c', 'i', 's', 'e' }; +static const symbol s_2_628[6] = { 'r', 'o', 's', 'i', 's', 'e' }; +static const symbol s_2_629[6] = { 'j', 'e', 't', 'i', 's', 'e' }; +static const symbol s_2_630[3] = { 'o', 's', 'e' }; +static const symbol s_2_631[8] = { 'a', 's', 't', 'a', 'd', 'o', 's', 'e' }; +static const symbol s_2_632[8] = { 'i', 's', 't', 'a', 'd', 'o', 's', 'e' }; +static const symbol s_2_633[8] = { 'o', 's', 't', 'a', 'd', 'o', 's', 'e' }; +static const symbol s_2_634[3] = { 'a', 't', 'e' }; +static const symbol s_2_635[5] = { 'a', 'c', 'a', 't', 'e' }; +static const symbol s_2_636[5] = { 'i', 'k', 'a', 't', 'e' }; +static const symbol s_2_637[4] = { 'l', 'a', 't', 'e' }; +static const symbol s_2_638[5] = { 'i', 'r', 'a', 't', 'e' }; +static const symbol s_2_639[5] = { 'u', 'r', 'a', 't', 'e' }; +static const symbol s_2_640[4] = { 't', 'a', 't', 'e' }; +static const symbol s_2_641[5] = { 'a', 'v', 'a', 't', 'e' }; +static const symbol s_2_642[5] = { 'e', 'v', 'a', 't', 'e' }; +static const symbol s_2_643[5] = { 'i', 'v', 'a', 't', 'e' }; +static const symbol s_2_644[5] = { 'u', 'v', 'a', 't', 'e' }; +static const symbol s_2_645[6] = { 'a', 0xC4, 0x8D, 'a', 't', 'e' }; +static const symbol s_2_646[3] = { 'e', 't', 'e' }; +static const symbol s_2_647[8] = { 'a', 's', 't', 'a', 'd', 'e', 't', 'e' }; +static const symbol s_2_648[8] = { 'i', 's', 't', 'a', 'd', 'e', 't', 'e' }; +static const symbol s_2_649[8] = { 'o', 's', 't', 'a', 'd', 'e', 't', 'e' }; +static const symbol s_2_650[8] = { 'a', 's', 't', 'a', 'j', 'e', 't', 'e' }; +static const symbol s_2_651[8] = { 'i', 's', 't', 'a', 'j', 'e', 't', 'e' }; +static const symbol s_2_652[8] = { 'o', 's', 't', 'a', 'j', 'e', 't', 'e' }; +static const symbol s_2_653[5] = { 'i', 'j', 'e', 't', 'e' }; +static const symbol s_2_654[6] = { 'i', 'n', 'j', 'e', 't', 'e' }; +static const symbol s_2_655[5] = { 'u', 'j', 'e', 't', 'e' }; +static const symbol s_2_656[8] = { 'l', 'u', 'c', 'u', 'j', 'e', 't', 'e' }; +static const symbol s_2_657[7] = { 'i', 'r', 'u', 'j', 'e', 't', 'e' }; +static const symbol s_2_658[9] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'e', 't', 'e' }; +static const symbol s_2_659[4] = { 'n', 'e', 't', 'e' }; +static const symbol s_2_660[8] = { 'a', 's', 't', 'a', 'n', 'e', 't', 'e' }; +static const symbol s_2_661[8] = { 'i', 's', 't', 'a', 'n', 'e', 't', 'e' }; +static const symbol s_2_662[8] = { 'o', 's', 't', 'a', 'n', 'e', 't', 'e' }; +static const symbol s_2_663[6] = { 'a', 's', 't', 'e', 't', 'e' }; +static const symbol s_2_664[3] = { 'i', 't', 'e' }; +static const symbol s_2_665[5] = { 'a', 'c', 'i', 't', 'e' }; +static const symbol s_2_666[6] = { 'l', 'u', 'c', 'i', 't', 'e' }; +static const symbol s_2_667[4] = { 'n', 'i', 't', 'e' }; +static const symbol s_2_668[8] = { 'a', 's', 't', 'a', 'n', 'i', 't', 'e' }; +static const symbol s_2_669[8] = { 'i', 's', 't', 'a', 'n', 'i', 't', 'e' }; +static const symbol s_2_670[8] = { 'o', 's', 't', 'a', 'n', 'i', 't', 'e' }; +static const symbol s_2_671[6] = { 'r', 'o', 's', 'i', 't', 'e' }; +static const symbol s_2_672[6] = { 'j', 'e', 't', 'i', 't', 'e' }; +static const symbol s_2_673[6] = { 'a', 's', 't', 'i', 't', 'e' }; +static const symbol s_2_674[5] = { 'e', 'v', 'i', 't', 'e' }; +static const symbol s_2_675[5] = { 'o', 'v', 'i', 't', 'e' }; +static const symbol s_2_676[6] = { 'a', 0xC4, 0x8D, 'i', 't', 'e' }; +static const symbol s_2_677[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 't', 'e' }; +static const symbol s_2_678[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 't', 'e' }; +static const symbol s_2_679[4] = { 'a', 'j', 't', 'e' }; +static const symbol s_2_680[6] = { 'u', 'r', 'a', 'j', 't', 'e' }; +static const symbol s_2_681[5] = { 't', 'a', 'j', 't', 'e' }; +static const symbol s_2_682[7] = { 'a', 's', 't', 'a', 'j', 't', 'e' }; +static const symbol s_2_683[7] = { 'i', 's', 't', 'a', 'j', 't', 'e' }; +static const symbol s_2_684[7] = { 'o', 's', 't', 'a', 'j', 't', 'e' }; +static const symbol s_2_685[6] = { 'a', 'v', 'a', 'j', 't', 'e' }; +static const symbol s_2_686[6] = { 'e', 'v', 'a', 'j', 't', 'e' }; +static const symbol s_2_687[6] = { 'i', 'v', 'a', 'j', 't', 'e' }; +static const symbol s_2_688[6] = { 'u', 'v', 'a', 'j', 't', 'e' }; +static const symbol s_2_689[4] = { 'i', 'j', 't', 'e' }; +static const symbol s_2_690[7] = { 'l', 'u', 'c', 'u', 'j', 't', 'e' }; +static const symbol s_2_691[6] = { 'i', 'r', 'u', 'j', 't', 'e' }; +static const symbol s_2_692[8] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 't', 'e' }; +static const symbol s_2_693[4] = { 'a', 's', 't', 'e' }; +static const symbol s_2_694[6] = { 'a', 'c', 'a', 's', 't', 'e' }; +static const symbol s_2_695[9] = { 'a', 's', 't', 'a', 'j', 'a', 's', 't', 'e' }; +static const symbol s_2_696[9] = { 'i', 's', 't', 'a', 'j', 'a', 's', 't', 'e' }; +static const symbol s_2_697[9] = { 'o', 's', 't', 'a', 'j', 'a', 's', 't', 'e' }; +static const symbol s_2_698[7] = { 'i', 'n', 'j', 'a', 's', 't', 'e' }; +static const symbol s_2_699[6] = { 'i', 'r', 'a', 's', 't', 'e' }; +static const symbol s_2_700[6] = { 'u', 'r', 'a', 's', 't', 'e' }; +static const symbol s_2_701[5] = { 't', 'a', 's', 't', 'e' }; +static const symbol s_2_702[6] = { 'a', 'v', 'a', 's', 't', 'e' }; +static const symbol s_2_703[6] = { 'e', 'v', 'a', 's', 't', 'e' }; +static const symbol s_2_704[6] = { 'i', 'v', 'a', 's', 't', 'e' }; +static const symbol s_2_705[6] = { 'o', 'v', 'a', 's', 't', 'e' }; +static const symbol s_2_706[6] = { 'u', 'v', 'a', 's', 't', 'e' }; +static const symbol s_2_707[7] = { 'a', 0xC4, 0x8D, 'a', 's', 't', 'e' }; +static const symbol s_2_708[4] = { 'e', 's', 't', 'e' }; +static const symbol s_2_709[4] = { 'i', 's', 't', 'e' }; +static const symbol s_2_710[6] = { 'a', 'c', 'i', 's', 't', 'e' }; +static const symbol s_2_711[7] = { 'l', 'u', 'c', 'i', 's', 't', 'e' }; +static const symbol s_2_712[5] = { 'n', 'i', 's', 't', 'e' }; +static const symbol s_2_713[7] = { 'r', 'o', 's', 'i', 's', 't', 'e' }; +static const symbol s_2_714[7] = { 'j', 'e', 't', 'i', 's', 't', 'e' }; +static const symbol s_2_715[7] = { 'a', 0xC4, 0x8D, 'i', 's', 't', 'e' }; +static const symbol s_2_716[8] = { 'l', 'u', 0xC4, 0x8D, 'i', 's', 't', 'e' }; +static const symbol s_2_717[8] = { 'r', 'o', 0xC5, 0xA1, 'i', 's', 't', 'e' }; +static const symbol s_2_718[4] = { 'k', 's', 't', 'e' }; +static const symbol s_2_719[4] = { 'o', 's', 't', 'e' }; +static const symbol s_2_720[9] = { 'a', 's', 't', 'a', 'd', 'o', 's', 't', 'e' }; +static const symbol s_2_721[9] = { 'i', 's', 't', 'a', 'd', 'o', 's', 't', 'e' }; +static const symbol s_2_722[9] = { 'o', 's', 't', 'a', 'd', 'o', 's', 't', 'e' }; +static const symbol s_2_723[5] = { 'n', 'u', 's', 't', 'e' }; +static const symbol s_2_724[5] = { 'i', 0xC5, 0xA1, 't', 'e' }; +static const symbol s_2_725[3] = { 'a', 'v', 'e' }; +static const symbol s_2_726[3] = { 'e', 'v', 'e' }; +static const symbol s_2_727[5] = { 'a', 'j', 'e', 'v', 'e' }; +static const symbol s_2_728[6] = { 'c', 'a', 'j', 'e', 'v', 'e' }; +static const symbol s_2_729[6] = { 'l', 'a', 'j', 'e', 'v', 'e' }; +static const symbol s_2_730[6] = { 'r', 'a', 'j', 'e', 'v', 'e' }; +static const symbol s_2_731[7] = { 0xC4, 0x87, 'a', 'j', 'e', 'v', 'e' }; +static const symbol s_2_732[7] = { 0xC4, 0x8D, 'a', 'j', 'e', 'v', 'e' }; +static const symbol s_2_733[7] = { 0xC4, 0x91, 'a', 'j', 'e', 'v', 'e' }; +static const symbol s_2_734[3] = { 'i', 'v', 'e' }; +static const symbol s_2_735[3] = { 'o', 'v', 'e' }; +static const symbol s_2_736[4] = { 'g', 'o', 'v', 'e' }; +static const symbol s_2_737[5] = { 'u', 'g', 'o', 'v', 'e' }; +static const symbol s_2_738[4] = { 'l', 'o', 'v', 'e' }; +static const symbol s_2_739[5] = { 'o', 'l', 'o', 'v', 'e' }; +static const symbol s_2_740[4] = { 'm', 'o', 'v', 'e' }; +static const symbol s_2_741[5] = { 'o', 'n', 'o', 'v', 'e' }; +static const symbol s_2_742[4] = { 'a', 0xC4, 0x87, 'e' }; +static const symbol s_2_743[4] = { 'e', 0xC4, 0x87, 'e' }; +static const symbol s_2_744[4] = { 'u', 0xC4, 0x87, 'e' }; +static const symbol s_2_745[4] = { 'a', 0xC4, 0x8D, 'e' }; +static const symbol s_2_746[5] = { 'l', 'u', 0xC4, 0x8D, 'e' }; +static const symbol s_2_747[4] = { 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_748[5] = { 'b', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_749[5] = { 'g', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_750[5] = { 'j', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_751[9] = { 'a', 's', 't', 'a', 'j', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_752[9] = { 'i', 's', 't', 'a', 'j', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_753[9] = { 'o', 's', 't', 'a', 'j', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_754[7] = { 'i', 'n', 'j', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_755[5] = { 'k', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_756[5] = { 'n', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_757[6] = { 'i', 'r', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_758[6] = { 'u', 'r', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_759[5] = { 't', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_760[5] = { 'v', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_761[6] = { 'a', 'v', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_762[6] = { 'e', 'v', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_763[6] = { 'i', 'v', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_764[6] = { 'o', 'v', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_765[6] = { 'u', 'v', 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_766[7] = { 'a', 0xC4, 0x8D, 'a', 0xC5, 0xA1, 'e' }; +static const symbol s_2_767[4] = { 'e', 0xC5, 0xA1, 'e' }; +static const symbol s_2_768[4] = { 'i', 0xC5, 0xA1, 'e' }; +static const symbol s_2_769[7] = { 'j', 'e', 't', 'i', 0xC5, 0xA1, 'e' }; +static const symbol s_2_770[7] = { 'a', 0xC4, 0x8D, 'i', 0xC5, 0xA1, 'e' }; +static const symbol s_2_771[8] = { 'l', 'u', 0xC4, 0x8D, 'i', 0xC5, 0xA1, 'e' }; +static const symbol s_2_772[8] = { 'r', 'o', 0xC5, 0xA1, 'i', 0xC5, 0xA1, 'e' }; +static const symbol s_2_773[4] = { 'o', 0xC5, 0xA1, 'e' }; +static const symbol s_2_774[9] = { 'a', 's', 't', 'a', 'd', 'o', 0xC5, 0xA1, 'e' }; +static const symbol s_2_775[9] = { 'i', 's', 't', 'a', 'd', 'o', 0xC5, 0xA1, 'e' }; +static const symbol s_2_776[9] = { 'o', 's', 't', 'a', 'd', 'o', 0xC5, 0xA1, 'e' }; +static const symbol s_2_777[4] = { 'a', 'c', 'e', 'g' }; +static const symbol s_2_778[4] = { 'e', 'c', 'e', 'g' }; +static const symbol s_2_779[4] = { 'u', 'c', 'e', 'g' }; +static const symbol s_2_780[7] = { 'a', 'n', 'j', 'i', 'j', 'e', 'g' }; +static const symbol s_2_781[7] = { 'e', 'n', 'j', 'i', 'j', 'e', 'g' }; +static const symbol s_2_782[7] = { 's', 'n', 'j', 'i', 'j', 'e', 'g' }; +static const symbol s_2_783[8] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'e', 'g' }; +static const symbol s_2_784[5] = { 'k', 'i', 'j', 'e', 'g' }; +static const symbol s_2_785[6] = { 's', 'k', 'i', 'j', 'e', 'g' }; +static const symbol s_2_786[7] = { 0xC5, 0xA1, 'k', 'i', 'j', 'e', 'g' }; +static const symbol s_2_787[6] = { 'e', 'l', 'i', 'j', 'e', 'g' }; +static const symbol s_2_788[5] = { 'n', 'i', 'j', 'e', 'g' }; +static const symbol s_2_789[6] = { 'o', 's', 'i', 'j', 'e', 'g' }; +static const symbol s_2_790[6] = { 'a', 't', 'i', 'j', 'e', 'g' }; +static const symbol s_2_791[8] = { 'e', 'v', 'i', 't', 'i', 'j', 'e', 'g' }; +static const symbol s_2_792[8] = { 'o', 'v', 'i', 't', 'i', 'j', 'e', 'g' }; +static const symbol s_2_793[7] = { 'a', 's', 't', 'i', 'j', 'e', 'g' }; +static const symbol s_2_794[6] = { 'a', 'v', 'i', 'j', 'e', 'g' }; +static const symbol s_2_795[6] = { 'e', 'v', 'i', 'j', 'e', 'g' }; +static const symbol s_2_796[6] = { 'i', 'v', 'i', 'j', 'e', 'g' }; +static const symbol s_2_797[6] = { 'o', 'v', 'i', 'j', 'e', 'g' }; +static const symbol s_2_798[7] = { 'o', 0xC5, 0xA1, 'i', 'j', 'e', 'g' }; +static const symbol s_2_799[5] = { 'a', 'n', 'j', 'e', 'g' }; +static const symbol s_2_800[5] = { 'e', 'n', 'j', 'e', 'g' }; +static const symbol s_2_801[5] = { 's', 'n', 'j', 'e', 'g' }; +static const symbol s_2_802[6] = { 0xC5, 0xA1, 'n', 'j', 'e', 'g' }; +static const symbol s_2_803[3] = { 'k', 'e', 'g' }; +static const symbol s_2_804[4] = { 'e', 'l', 'e', 'g' }; +static const symbol s_2_805[3] = { 'n', 'e', 'g' }; +static const symbol s_2_806[4] = { 'a', 'n', 'e', 'g' }; +static const symbol s_2_807[4] = { 'e', 'n', 'e', 'g' }; +static const symbol s_2_808[4] = { 's', 'n', 'e', 'g' }; +static const symbol s_2_809[5] = { 0xC5, 0xA1, 'n', 'e', 'g' }; +static const symbol s_2_810[4] = { 'o', 's', 'e', 'g' }; +static const symbol s_2_811[4] = { 'a', 't', 'e', 'g' }; +static const symbol s_2_812[4] = { 'a', 'v', 'e', 'g' }; +static const symbol s_2_813[4] = { 'e', 'v', 'e', 'g' }; +static const symbol s_2_814[4] = { 'i', 'v', 'e', 'g' }; +static const symbol s_2_815[4] = { 'o', 'v', 'e', 'g' }; +static const symbol s_2_816[5] = { 'a', 0xC4, 0x87, 'e', 'g' }; +static const symbol s_2_817[5] = { 'e', 0xC4, 0x87, 'e', 'g' }; +static const symbol s_2_818[5] = { 'u', 0xC4, 0x87, 'e', 'g' }; +static const symbol s_2_819[5] = { 'o', 0xC5, 0xA1, 'e', 'g' }; +static const symbol s_2_820[4] = { 'a', 'c', 'o', 'g' }; +static const symbol s_2_821[4] = { 'e', 'c', 'o', 'g' }; +static const symbol s_2_822[4] = { 'u', 'c', 'o', 'g' }; +static const symbol s_2_823[5] = { 'a', 'n', 'j', 'o', 'g' }; +static const symbol s_2_824[5] = { 'e', 'n', 'j', 'o', 'g' }; +static const symbol s_2_825[5] = { 's', 'n', 'j', 'o', 'g' }; +static const symbol s_2_826[6] = { 0xC5, 0xA1, 'n', 'j', 'o', 'g' }; +static const symbol s_2_827[3] = { 'k', 'o', 'g' }; +static const symbol s_2_828[4] = { 's', 'k', 'o', 'g' }; +static const symbol s_2_829[5] = { 0xC5, 0xA1, 'k', 'o', 'g' }; +static const symbol s_2_830[4] = { 'e', 'l', 'o', 'g' }; +static const symbol s_2_831[3] = { 'n', 'o', 'g' }; +static const symbol s_2_832[5] = { 'c', 'i', 'n', 'o', 'g' }; +static const symbol s_2_833[6] = { 0xC4, 0x8D, 'i', 'n', 'o', 'g' }; +static const symbol s_2_834[4] = { 'o', 's', 'o', 'g' }; +static const symbol s_2_835[4] = { 'a', 't', 'o', 'g' }; +static const symbol s_2_836[6] = { 'e', 'v', 'i', 't', 'o', 'g' }; +static const symbol s_2_837[6] = { 'o', 'v', 'i', 't', 'o', 'g' }; +static const symbol s_2_838[5] = { 'a', 's', 't', 'o', 'g' }; +static const symbol s_2_839[4] = { 'a', 'v', 'o', 'g' }; +static const symbol s_2_840[4] = { 'e', 'v', 'o', 'g' }; +static const symbol s_2_841[4] = { 'i', 'v', 'o', 'g' }; +static const symbol s_2_842[4] = { 'o', 'v', 'o', 'g' }; +static const symbol s_2_843[5] = { 'a', 0xC4, 0x87, 'o', 'g' }; +static const symbol s_2_844[5] = { 'e', 0xC4, 0x87, 'o', 'g' }; +static const symbol s_2_845[5] = { 'u', 0xC4, 0x87, 'o', 'g' }; +static const symbol s_2_846[5] = { 'o', 0xC5, 0xA1, 'o', 'g' }; +static const symbol s_2_847[2] = { 'a', 'h' }; +static const symbol s_2_848[4] = { 'a', 'c', 'a', 'h' }; +static const symbol s_2_849[7] = { 'a', 's', 't', 'a', 'j', 'a', 'h' }; +static const symbol s_2_850[7] = { 'i', 's', 't', 'a', 'j', 'a', 'h' }; +static const symbol s_2_851[7] = { 'o', 's', 't', 'a', 'j', 'a', 'h' }; +static const symbol s_2_852[5] = { 'i', 'n', 'j', 'a', 'h' }; +static const symbol s_2_853[4] = { 'i', 'r', 'a', 'h' }; +static const symbol s_2_854[4] = { 'u', 'r', 'a', 'h' }; +static const symbol s_2_855[3] = { 't', 'a', 'h' }; +static const symbol s_2_856[4] = { 'a', 'v', 'a', 'h' }; +static const symbol s_2_857[4] = { 'e', 'v', 'a', 'h' }; +static const symbol s_2_858[4] = { 'i', 'v', 'a', 'h' }; +static const symbol s_2_859[4] = { 'o', 'v', 'a', 'h' }; +static const symbol s_2_860[4] = { 'u', 'v', 'a', 'h' }; +static const symbol s_2_861[5] = { 'a', 0xC4, 0x8D, 'a', 'h' }; +static const symbol s_2_862[2] = { 'i', 'h' }; +static const symbol s_2_863[4] = { 'a', 'c', 'i', 'h' }; +static const symbol s_2_864[4] = { 'e', 'c', 'i', 'h' }; +static const symbol s_2_865[4] = { 'u', 'c', 'i', 'h' }; +static const symbol s_2_866[5] = { 'l', 'u', 'c', 'i', 'h' }; +static const symbol s_2_867[7] = { 'a', 'n', 'j', 'i', 'j', 'i', 'h' }; +static const symbol s_2_868[7] = { 'e', 'n', 'j', 'i', 'j', 'i', 'h' }; +static const symbol s_2_869[7] = { 's', 'n', 'j', 'i', 'j', 'i', 'h' }; +static const symbol s_2_870[8] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'i', 'h' }; +static const symbol s_2_871[5] = { 'k', 'i', 'j', 'i', 'h' }; +static const symbol s_2_872[6] = { 's', 'k', 'i', 'j', 'i', 'h' }; +static const symbol s_2_873[7] = { 0xC5, 0xA1, 'k', 'i', 'j', 'i', 'h' }; +static const symbol s_2_874[6] = { 'e', 'l', 'i', 'j', 'i', 'h' }; +static const symbol s_2_875[5] = { 'n', 'i', 'j', 'i', 'h' }; +static const symbol s_2_876[6] = { 'o', 's', 'i', 'j', 'i', 'h' }; +static const symbol s_2_877[6] = { 'a', 't', 'i', 'j', 'i', 'h' }; +static const symbol s_2_878[8] = { 'e', 'v', 'i', 't', 'i', 'j', 'i', 'h' }; +static const symbol s_2_879[8] = { 'o', 'v', 'i', 't', 'i', 'j', 'i', 'h' }; +static const symbol s_2_880[7] = { 'a', 's', 't', 'i', 'j', 'i', 'h' }; +static const symbol s_2_881[6] = { 'a', 'v', 'i', 'j', 'i', 'h' }; +static const symbol s_2_882[6] = { 'e', 'v', 'i', 'j', 'i', 'h' }; +static const symbol s_2_883[6] = { 'i', 'v', 'i', 'j', 'i', 'h' }; +static const symbol s_2_884[6] = { 'o', 'v', 'i', 'j', 'i', 'h' }; +static const symbol s_2_885[7] = { 'o', 0xC5, 0xA1, 'i', 'j', 'i', 'h' }; +static const symbol s_2_886[5] = { 'a', 'n', 'j', 'i', 'h' }; +static const symbol s_2_887[5] = { 'e', 'n', 'j', 'i', 'h' }; +static const symbol s_2_888[5] = { 's', 'n', 'j', 'i', 'h' }; +static const symbol s_2_889[6] = { 0xC5, 0xA1, 'n', 'j', 'i', 'h' }; +static const symbol s_2_890[3] = { 'k', 'i', 'h' }; +static const symbol s_2_891[4] = { 's', 'k', 'i', 'h' }; +static const symbol s_2_892[5] = { 0xC5, 0xA1, 'k', 'i', 'h' }; +static const symbol s_2_893[4] = { 'e', 'l', 'i', 'h' }; +static const symbol s_2_894[3] = { 'n', 'i', 'h' }; +static const symbol s_2_895[5] = { 'c', 'i', 'n', 'i', 'h' }; +static const symbol s_2_896[6] = { 0xC4, 0x8D, 'i', 'n', 'i', 'h' }; +static const symbol s_2_897[4] = { 'o', 's', 'i', 'h' }; +static const symbol s_2_898[5] = { 'r', 'o', 's', 'i', 'h' }; +static const symbol s_2_899[4] = { 'a', 't', 'i', 'h' }; +static const symbol s_2_900[5] = { 'j', 'e', 't', 'i', 'h' }; +static const symbol s_2_901[6] = { 'e', 'v', 'i', 't', 'i', 'h' }; +static const symbol s_2_902[6] = { 'o', 'v', 'i', 't', 'i', 'h' }; +static const symbol s_2_903[5] = { 'a', 's', 't', 'i', 'h' }; +static const symbol s_2_904[4] = { 'a', 'v', 'i', 'h' }; +static const symbol s_2_905[4] = { 'e', 'v', 'i', 'h' }; +static const symbol s_2_906[4] = { 'i', 'v', 'i', 'h' }; +static const symbol s_2_907[4] = { 'o', 'v', 'i', 'h' }; +static const symbol s_2_908[5] = { 'a', 0xC4, 0x87, 'i', 'h' }; +static const symbol s_2_909[5] = { 'e', 0xC4, 0x87, 'i', 'h' }; +static const symbol s_2_910[5] = { 'u', 0xC4, 0x87, 'i', 'h' }; +static const symbol s_2_911[5] = { 'a', 0xC4, 0x8D, 'i', 'h' }; +static const symbol s_2_912[6] = { 'l', 'u', 0xC4, 0x8D, 'i', 'h' }; +static const symbol s_2_913[5] = { 'o', 0xC5, 0xA1, 'i', 'h' }; +static const symbol s_2_914[6] = { 'r', 'o', 0xC5, 0xA1, 'i', 'h' }; +static const symbol s_2_915[7] = { 'a', 's', 't', 'a', 'd', 'o', 'h' }; +static const symbol s_2_916[7] = { 'i', 's', 't', 'a', 'd', 'o', 'h' }; +static const symbol s_2_917[7] = { 'o', 's', 't', 'a', 'd', 'o', 'h' }; +static const symbol s_2_918[4] = { 'a', 'c', 'u', 'h' }; +static const symbol s_2_919[4] = { 'e', 'c', 'u', 'h' }; +static const symbol s_2_920[4] = { 'u', 'c', 'u', 'h' }; +static const symbol s_2_921[5] = { 'a', 0xC4, 0x87, 'u', 'h' }; +static const symbol s_2_922[5] = { 'e', 0xC4, 0x87, 'u', 'h' }; +static const symbol s_2_923[5] = { 'u', 0xC4, 0x87, 'u', 'h' }; +static const symbol s_2_924[3] = { 'a', 'c', 'i' }; +static const symbol s_2_925[5] = { 'a', 'c', 'e', 'c', 'i' }; +static const symbol s_2_926[4] = { 'i', 'e', 'c', 'i' }; +static const symbol s_2_927[5] = { 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_928[7] = { 'i', 'r', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_929[7] = { 'u', 'r', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_930[8] = { 'a', 's', 't', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_931[8] = { 'i', 's', 't', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_932[8] = { 'o', 's', 't', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_933[7] = { 'a', 'v', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_934[7] = { 'e', 'v', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_935[7] = { 'i', 'v', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_936[7] = { 'u', 'v', 'a', 'j', 'u', 'c', 'i' }; +static const symbol s_2_937[5] = { 'u', 'j', 'u', 'c', 'i' }; +static const symbol s_2_938[8] = { 'l', 'u', 'c', 'u', 'j', 'u', 'c', 'i' }; +static const symbol s_2_939[7] = { 'i', 'r', 'u', 'j', 'u', 'c', 'i' }; +static const symbol s_2_940[4] = { 'l', 'u', 'c', 'i' }; +static const symbol s_2_941[4] = { 'n', 'u', 'c', 'i' }; +static const symbol s_2_942[5] = { 'e', 't', 'u', 'c', 'i' }; +static const symbol s_2_943[6] = { 'a', 's', 't', 'u', 'c', 'i' }; +static const symbol s_2_944[2] = { 'g', 'i' }; +static const symbol s_2_945[3] = { 'u', 'g', 'i' }; +static const symbol s_2_946[3] = { 'a', 'j', 'i' }; +static const symbol s_2_947[4] = { 'c', 'a', 'j', 'i' }; +static const symbol s_2_948[4] = { 'l', 'a', 'j', 'i' }; +static const symbol s_2_949[4] = { 'r', 'a', 'j', 'i' }; +static const symbol s_2_950[5] = { 0xC4, 0x87, 'a', 'j', 'i' }; +static const symbol s_2_951[5] = { 0xC4, 0x8D, 'a', 'j', 'i' }; +static const symbol s_2_952[5] = { 0xC4, 0x91, 'a', 'j', 'i' }; +static const symbol s_2_953[4] = { 'b', 'i', 'j', 'i' }; +static const symbol s_2_954[4] = { 'c', 'i', 'j', 'i' }; +static const symbol s_2_955[4] = { 'd', 'i', 'j', 'i' }; +static const symbol s_2_956[4] = { 'f', 'i', 'j', 'i' }; +static const symbol s_2_957[4] = { 'g', 'i', 'j', 'i' }; +static const symbol s_2_958[6] = { 'a', 'n', 'j', 'i', 'j', 'i' }; +static const symbol s_2_959[6] = { 'e', 'n', 'j', 'i', 'j', 'i' }; +static const symbol s_2_960[6] = { 's', 'n', 'j', 'i', 'j', 'i' }; +static const symbol s_2_961[7] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'i' }; +static const symbol s_2_962[4] = { 'k', 'i', 'j', 'i' }; +static const symbol s_2_963[5] = { 's', 'k', 'i', 'j', 'i' }; +static const symbol s_2_964[6] = { 0xC5, 0xA1, 'k', 'i', 'j', 'i' }; +static const symbol s_2_965[4] = { 'l', 'i', 'j', 'i' }; +static const symbol s_2_966[5] = { 'e', 'l', 'i', 'j', 'i' }; +static const symbol s_2_967[4] = { 'm', 'i', 'j', 'i' }; +static const symbol s_2_968[4] = { 'n', 'i', 'j', 'i' }; +static const symbol s_2_969[6] = { 'g', 'a', 'n', 'i', 'j', 'i' }; +static const symbol s_2_970[6] = { 'm', 'a', 'n', 'i', 'j', 'i' }; +static const symbol s_2_971[6] = { 'p', 'a', 'n', 'i', 'j', 'i' }; +static const symbol s_2_972[6] = { 'r', 'a', 'n', 'i', 'j', 'i' }; +static const symbol s_2_973[6] = { 't', 'a', 'n', 'i', 'j', 'i' }; +static const symbol s_2_974[4] = { 'p', 'i', 'j', 'i' }; +static const symbol s_2_975[4] = { 'r', 'i', 'j', 'i' }; +static const symbol s_2_976[4] = { 's', 'i', 'j', 'i' }; +static const symbol s_2_977[5] = { 'o', 's', 'i', 'j', 'i' }; +static const symbol s_2_978[4] = { 't', 'i', 'j', 'i' }; +static const symbol s_2_979[5] = { 'a', 't', 'i', 'j', 'i' }; +static const symbol s_2_980[7] = { 'e', 'v', 'i', 't', 'i', 'j', 'i' }; +static const symbol s_2_981[7] = { 'o', 'v', 'i', 't', 'i', 'j', 'i' }; +static const symbol s_2_982[6] = { 'a', 's', 't', 'i', 'j', 'i' }; +static const symbol s_2_983[5] = { 'a', 'v', 'i', 'j', 'i' }; +static const symbol s_2_984[5] = { 'e', 'v', 'i', 'j', 'i' }; +static const symbol s_2_985[5] = { 'i', 'v', 'i', 'j', 'i' }; +static const symbol s_2_986[5] = { 'o', 'v', 'i', 'j', 'i' }; +static const symbol s_2_987[4] = { 'z', 'i', 'j', 'i' }; +static const symbol s_2_988[6] = { 'o', 0xC5, 0xA1, 'i', 'j', 'i' }; +static const symbol s_2_989[5] = { 0xC5, 0xBE, 'i', 'j', 'i' }; +static const symbol s_2_990[4] = { 'a', 'n', 'j', 'i' }; +static const symbol s_2_991[4] = { 'e', 'n', 'j', 'i' }; +static const symbol s_2_992[4] = { 's', 'n', 'j', 'i' }; +static const symbol s_2_993[5] = { 0xC5, 0xA1, 'n', 'j', 'i' }; +static const symbol s_2_994[2] = { 'k', 'i' }; +static const symbol s_2_995[3] = { 's', 'k', 'i' }; +static const symbol s_2_996[4] = { 0xC5, 0xA1, 'k', 'i' }; +static const symbol s_2_997[3] = { 'a', 'l', 'i' }; +static const symbol s_2_998[5] = { 'a', 'c', 'a', 'l', 'i' }; +static const symbol s_2_999[8] = { 'a', 's', 't', 'a', 'j', 'a', 'l', 'i' }; +static const symbol s_2_1000[8] = { 'i', 's', 't', 'a', 'j', 'a', 'l', 'i' }; +static const symbol s_2_1001[8] = { 'o', 's', 't', 'a', 'j', 'a', 'l', 'i' }; +static const symbol s_2_1002[5] = { 'i', 'j', 'a', 'l', 'i' }; +static const symbol s_2_1003[6] = { 'i', 'n', 'j', 'a', 'l', 'i' }; +static const symbol s_2_1004[4] = { 'n', 'a', 'l', 'i' }; +static const symbol s_2_1005[5] = { 'i', 'r', 'a', 'l', 'i' }; +static const symbol s_2_1006[5] = { 'u', 'r', 'a', 'l', 'i' }; +static const symbol s_2_1007[4] = { 't', 'a', 'l', 'i' }; +static const symbol s_2_1008[6] = { 'a', 's', 't', 'a', 'l', 'i' }; +static const symbol s_2_1009[6] = { 'i', 's', 't', 'a', 'l', 'i' }; +static const symbol s_2_1010[6] = { 'o', 's', 't', 'a', 'l', 'i' }; +static const symbol s_2_1011[5] = { 'a', 'v', 'a', 'l', 'i' }; +static const symbol s_2_1012[5] = { 'e', 'v', 'a', 'l', 'i' }; +static const symbol s_2_1013[5] = { 'i', 'v', 'a', 'l', 'i' }; +static const symbol s_2_1014[5] = { 'o', 'v', 'a', 'l', 'i' }; +static const symbol s_2_1015[5] = { 'u', 'v', 'a', 'l', 'i' }; +static const symbol s_2_1016[6] = { 'a', 0xC4, 0x8D, 'a', 'l', 'i' }; +static const symbol s_2_1017[3] = { 'e', 'l', 'i' }; +static const symbol s_2_1018[3] = { 'i', 'l', 'i' }; +static const symbol s_2_1019[5] = { 'a', 'c', 'i', 'l', 'i' }; +static const symbol s_2_1020[6] = { 'l', 'u', 'c', 'i', 'l', 'i' }; +static const symbol s_2_1021[4] = { 'n', 'i', 'l', 'i' }; +static const symbol s_2_1022[6] = { 'r', 'o', 's', 'i', 'l', 'i' }; +static const symbol s_2_1023[6] = { 'j', 'e', 't', 'i', 'l', 'i' }; +static const symbol s_2_1024[5] = { 'o', 'z', 'i', 'l', 'i' }; +static const symbol s_2_1025[6] = { 'a', 0xC4, 0x8D, 'i', 'l', 'i' }; +static const symbol s_2_1026[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 'l', 'i' }; +static const symbol s_2_1027[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 'l', 'i' }; +static const symbol s_2_1028[3] = { 'o', 'l', 'i' }; +static const symbol s_2_1029[4] = { 'a', 's', 'l', 'i' }; +static const symbol s_2_1030[4] = { 'n', 'u', 'l', 'i' }; +static const symbol s_2_1031[4] = { 'r', 'a', 'm', 'i' }; +static const symbol s_2_1032[4] = { 'l', 'e', 'm', 'i' }; +static const symbol s_2_1033[2] = { 'n', 'i' }; +static const symbol s_2_1034[3] = { 'a', 'n', 'i' }; +static const symbol s_2_1035[5] = { 'a', 'c', 'a', 'n', 'i' }; +static const symbol s_2_1036[5] = { 'u', 'r', 'a', 'n', 'i' }; +static const symbol s_2_1037[4] = { 't', 'a', 'n', 'i' }; +static const symbol s_2_1038[5] = { 'a', 'v', 'a', 'n', 'i' }; +static const symbol s_2_1039[5] = { 'e', 'v', 'a', 'n', 'i' }; +static const symbol s_2_1040[5] = { 'i', 'v', 'a', 'n', 'i' }; +static const symbol s_2_1041[5] = { 'u', 'v', 'a', 'n', 'i' }; +static const symbol s_2_1042[6] = { 'a', 0xC4, 0x8D, 'a', 'n', 'i' }; +static const symbol s_2_1043[5] = { 'a', 'c', 'e', 'n', 'i' }; +static const symbol s_2_1044[6] = { 'l', 'u', 'c', 'e', 'n', 'i' }; +static const symbol s_2_1045[6] = { 'a', 0xC4, 0x8D, 'e', 'n', 'i' }; +static const symbol s_2_1046[7] = { 'l', 'u', 0xC4, 0x8D, 'e', 'n', 'i' }; +static const symbol s_2_1047[3] = { 'i', 'n', 'i' }; +static const symbol s_2_1048[4] = { 'c', 'i', 'n', 'i' }; +static const symbol s_2_1049[5] = { 0xC4, 0x8D, 'i', 'n', 'i' }; +static const symbol s_2_1050[3] = { 'o', 'n', 'i' }; +static const symbol s_2_1051[3] = { 'a', 'r', 'i' }; +static const symbol s_2_1052[3] = { 'd', 'r', 'i' }; +static const symbol s_2_1053[3] = { 'e', 'r', 'i' }; +static const symbol s_2_1054[3] = { 'o', 'r', 'i' }; +static const symbol s_2_1055[4] = { 'b', 'a', 's', 'i' }; +static const symbol s_2_1056[4] = { 'g', 'a', 's', 'i' }; +static const symbol s_2_1057[4] = { 'j', 'a', 's', 'i' }; +static const symbol s_2_1058[4] = { 'k', 'a', 's', 'i' }; +static const symbol s_2_1059[4] = { 'n', 'a', 's', 'i' }; +static const symbol s_2_1060[4] = { 't', 'a', 's', 'i' }; +static const symbol s_2_1061[4] = { 'v', 'a', 's', 'i' }; +static const symbol s_2_1062[3] = { 'e', 's', 'i' }; +static const symbol s_2_1063[3] = { 'i', 's', 'i' }; +static const symbol s_2_1064[3] = { 'o', 's', 'i' }; +static const symbol s_2_1065[4] = { 'a', 'v', 's', 'i' }; +static const symbol s_2_1066[6] = { 'a', 'c', 'a', 'v', 's', 'i' }; +static const symbol s_2_1067[6] = { 'i', 'r', 'a', 'v', 's', 'i' }; +static const symbol s_2_1068[5] = { 't', 'a', 'v', 's', 'i' }; +static const symbol s_2_1069[6] = { 'e', 't', 'a', 'v', 's', 'i' }; +static const symbol s_2_1070[7] = { 'a', 's', 't', 'a', 'v', 's', 'i' }; +static const symbol s_2_1071[7] = { 'i', 's', 't', 'a', 'v', 's', 'i' }; +static const symbol s_2_1072[7] = { 'o', 's', 't', 'a', 'v', 's', 'i' }; +static const symbol s_2_1073[4] = { 'i', 'v', 's', 'i' }; +static const symbol s_2_1074[5] = { 'n', 'i', 'v', 's', 'i' }; +static const symbol s_2_1075[7] = { 'r', 'o', 's', 'i', 'v', 's', 'i' }; +static const symbol s_2_1076[5] = { 'n', 'u', 'v', 's', 'i' }; +static const symbol s_2_1077[3] = { 'a', 't', 'i' }; +static const symbol s_2_1078[5] = { 'a', 'c', 'a', 't', 'i' }; +static const symbol s_2_1079[8] = { 'a', 's', 't', 'a', 'j', 'a', 't', 'i' }; +static const symbol s_2_1080[8] = { 'i', 's', 't', 'a', 'j', 'a', 't', 'i' }; +static const symbol s_2_1081[8] = { 'o', 's', 't', 'a', 'j', 'a', 't', 'i' }; +static const symbol s_2_1082[6] = { 'i', 'n', 'j', 'a', 't', 'i' }; +static const symbol s_2_1083[5] = { 'i', 'k', 'a', 't', 'i' }; +static const symbol s_2_1084[4] = { 'l', 'a', 't', 'i' }; +static const symbol s_2_1085[5] = { 'i', 'r', 'a', 't', 'i' }; +static const symbol s_2_1086[5] = { 'u', 'r', 'a', 't', 'i' }; +static const symbol s_2_1087[4] = { 't', 'a', 't', 'i' }; +static const symbol s_2_1088[6] = { 'a', 's', 't', 'a', 't', 'i' }; +static const symbol s_2_1089[6] = { 'i', 's', 't', 'a', 't', 'i' }; +static const symbol s_2_1090[6] = { 'o', 's', 't', 'a', 't', 'i' }; +static const symbol s_2_1091[5] = { 'a', 'v', 'a', 't', 'i' }; +static const symbol s_2_1092[5] = { 'e', 'v', 'a', 't', 'i' }; +static const symbol s_2_1093[5] = { 'i', 'v', 'a', 't', 'i' }; +static const symbol s_2_1094[5] = { 'o', 'v', 'a', 't', 'i' }; +static const symbol s_2_1095[5] = { 'u', 'v', 'a', 't', 'i' }; +static const symbol s_2_1096[6] = { 'a', 0xC4, 0x8D, 'a', 't', 'i' }; +static const symbol s_2_1097[3] = { 'e', 't', 'i' }; +static const symbol s_2_1098[3] = { 'i', 't', 'i' }; +static const symbol s_2_1099[5] = { 'a', 'c', 'i', 't', 'i' }; +static const symbol s_2_1100[6] = { 'l', 'u', 'c', 'i', 't', 'i' }; +static const symbol s_2_1101[4] = { 'n', 'i', 't', 'i' }; +static const symbol s_2_1102[6] = { 'r', 'o', 's', 'i', 't', 'i' }; +static const symbol s_2_1103[6] = { 'j', 'e', 't', 'i', 't', 'i' }; +static const symbol s_2_1104[5] = { 'e', 'v', 'i', 't', 'i' }; +static const symbol s_2_1105[5] = { 'o', 'v', 'i', 't', 'i' }; +static const symbol s_2_1106[6] = { 'a', 0xC4, 0x8D, 'i', 't', 'i' }; +static const symbol s_2_1107[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 't', 'i' }; +static const symbol s_2_1108[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 't', 'i' }; +static const symbol s_2_1109[4] = { 'a', 's', 't', 'i' }; +static const symbol s_2_1110[4] = { 'e', 's', 't', 'i' }; +static const symbol s_2_1111[4] = { 'i', 's', 't', 'i' }; +static const symbol s_2_1112[4] = { 'k', 's', 't', 'i' }; +static const symbol s_2_1113[4] = { 'o', 's', 't', 'i' }; +static const symbol s_2_1114[4] = { 'n', 'u', 't', 'i' }; +static const symbol s_2_1115[3] = { 'a', 'v', 'i' }; +static const symbol s_2_1116[3] = { 'e', 'v', 'i' }; +static const symbol s_2_1117[5] = { 'a', 'j', 'e', 'v', 'i' }; +static const symbol s_2_1118[6] = { 'c', 'a', 'j', 'e', 'v', 'i' }; +static const symbol s_2_1119[6] = { 'l', 'a', 'j', 'e', 'v', 'i' }; +static const symbol s_2_1120[6] = { 'r', 'a', 'j', 'e', 'v', 'i' }; +static const symbol s_2_1121[7] = { 0xC4, 0x87, 'a', 'j', 'e', 'v', 'i' }; +static const symbol s_2_1122[7] = { 0xC4, 0x8D, 'a', 'j', 'e', 'v', 'i' }; +static const symbol s_2_1123[7] = { 0xC4, 0x91, 'a', 'j', 'e', 'v', 'i' }; +static const symbol s_2_1124[3] = { 'i', 'v', 'i' }; +static const symbol s_2_1125[3] = { 'o', 'v', 'i' }; +static const symbol s_2_1126[4] = { 'g', 'o', 'v', 'i' }; +static const symbol s_2_1127[5] = { 'u', 'g', 'o', 'v', 'i' }; +static const symbol s_2_1128[4] = { 'l', 'o', 'v', 'i' }; +static const symbol s_2_1129[5] = { 'o', 'l', 'o', 'v', 'i' }; +static const symbol s_2_1130[4] = { 'm', 'o', 'v', 'i' }; +static const symbol s_2_1131[5] = { 'o', 'n', 'o', 'v', 'i' }; +static const symbol s_2_1132[5] = { 'i', 'e', 0xC4, 0x87, 'i' }; +static const symbol s_2_1133[7] = { 'a', 0xC4, 0x8D, 'e', 0xC4, 0x87, 'i' }; +static const symbol s_2_1134[6] = { 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1135[8] = { 'i', 'r', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1136[8] = { 'u', 'r', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1137[9] = { 'a', 's', 't', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1138[9] = { 'i', 's', 't', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1139[9] = { 'o', 's', 't', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1140[8] = { 'a', 'v', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1141[8] = { 'e', 'v', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1142[8] = { 'i', 'v', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1143[8] = { 'u', 'v', 'a', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1144[6] = { 'u', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1145[8] = { 'i', 'r', 'u', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1146[10] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1147[5] = { 'n', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1148[6] = { 'e', 't', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1149[7] = { 'a', 's', 't', 'u', 0xC4, 0x87, 'i' }; +static const symbol s_2_1150[4] = { 'a', 0xC4, 0x8D, 'i' }; +static const symbol s_2_1151[5] = { 'l', 'u', 0xC4, 0x8D, 'i' }; +static const symbol s_2_1152[5] = { 'b', 'a', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1153[5] = { 'g', 'a', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1154[5] = { 'j', 'a', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1155[5] = { 'k', 'a', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1156[5] = { 'n', 'a', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1157[5] = { 't', 'a', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1158[5] = { 'v', 'a', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1159[4] = { 'e', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1160[4] = { 'i', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1161[4] = { 'o', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1162[5] = { 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1163[7] = { 'i', 'r', 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1164[6] = { 't', 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1165[7] = { 'e', 't', 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1166[8] = { 'a', 's', 't', 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1167[8] = { 'i', 's', 't', 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1168[8] = { 'o', 's', 't', 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1169[8] = { 'a', 0xC4, 0x8D, 'a', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1170[5] = { 'i', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1171[6] = { 'n', 'i', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1172[9] = { 'r', 'o', 0xC5, 0xA1, 'i', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1173[6] = { 'n', 'u', 'v', 0xC5, 0xA1, 'i' }; +static const symbol s_2_1174[2] = { 'a', 'j' }; +static const symbol s_2_1175[4] = { 'u', 'r', 'a', 'j' }; +static const symbol s_2_1176[3] = { 't', 'a', 'j' }; +static const symbol s_2_1177[4] = { 'a', 'v', 'a', 'j' }; +static const symbol s_2_1178[4] = { 'e', 'v', 'a', 'j' }; +static const symbol s_2_1179[4] = { 'i', 'v', 'a', 'j' }; +static const symbol s_2_1180[4] = { 'u', 'v', 'a', 'j' }; +static const symbol s_2_1181[2] = { 'i', 'j' }; +static const symbol s_2_1182[4] = { 'a', 'c', 'o', 'j' }; +static const symbol s_2_1183[4] = { 'e', 'c', 'o', 'j' }; +static const symbol s_2_1184[4] = { 'u', 'c', 'o', 'j' }; +static const symbol s_2_1185[7] = { 'a', 'n', 'j', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1186[7] = { 'e', 'n', 'j', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1187[7] = { 's', 'n', 'j', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1188[8] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1189[5] = { 'k', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1190[6] = { 's', 'k', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1191[7] = { 0xC5, 0xA1, 'k', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1192[6] = { 'e', 'l', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1193[5] = { 'n', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1194[6] = { 'o', 's', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1195[8] = { 'e', 'v', 'i', 't', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1196[8] = { 'o', 'v', 'i', 't', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1197[7] = { 'a', 's', 't', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1198[6] = { 'a', 'v', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1199[6] = { 'e', 'v', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1200[6] = { 'i', 'v', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1201[6] = { 'o', 'v', 'i', 'j', 'o', 'j' }; +static const symbol s_2_1202[7] = { 'o', 0xC5, 0xA1, 'i', 'j', 'o', 'j' }; +static const symbol s_2_1203[5] = { 'a', 'n', 'j', 'o', 'j' }; +static const symbol s_2_1204[5] = { 'e', 'n', 'j', 'o', 'j' }; +static const symbol s_2_1205[5] = { 's', 'n', 'j', 'o', 'j' }; +static const symbol s_2_1206[6] = { 0xC5, 0xA1, 'n', 'j', 'o', 'j' }; +static const symbol s_2_1207[3] = { 'k', 'o', 'j' }; +static const symbol s_2_1208[4] = { 's', 'k', 'o', 'j' }; +static const symbol s_2_1209[5] = { 0xC5, 0xA1, 'k', 'o', 'j' }; +static const symbol s_2_1210[4] = { 'a', 'l', 'o', 'j' }; +static const symbol s_2_1211[4] = { 'e', 'l', 'o', 'j' }; +static const symbol s_2_1212[3] = { 'n', 'o', 'j' }; +static const symbol s_2_1213[5] = { 'c', 'i', 'n', 'o', 'j' }; +static const symbol s_2_1214[6] = { 0xC4, 0x8D, 'i', 'n', 'o', 'j' }; +static const symbol s_2_1215[4] = { 'o', 's', 'o', 'j' }; +static const symbol s_2_1216[4] = { 'a', 't', 'o', 'j' }; +static const symbol s_2_1217[6] = { 'e', 'v', 'i', 't', 'o', 'j' }; +static const symbol s_2_1218[6] = { 'o', 'v', 'i', 't', 'o', 'j' }; +static const symbol s_2_1219[5] = { 'a', 's', 't', 'o', 'j' }; +static const symbol s_2_1220[4] = { 'a', 'v', 'o', 'j' }; +static const symbol s_2_1221[4] = { 'e', 'v', 'o', 'j' }; +static const symbol s_2_1222[4] = { 'i', 'v', 'o', 'j' }; +static const symbol s_2_1223[4] = { 'o', 'v', 'o', 'j' }; +static const symbol s_2_1224[5] = { 'a', 0xC4, 0x87, 'o', 'j' }; +static const symbol s_2_1225[5] = { 'e', 0xC4, 0x87, 'o', 'j' }; +static const symbol s_2_1226[5] = { 'u', 0xC4, 0x87, 'o', 'j' }; +static const symbol s_2_1227[5] = { 'o', 0xC5, 0xA1, 'o', 'j' }; +static const symbol s_2_1228[5] = { 'l', 'u', 'c', 'u', 'j' }; +static const symbol s_2_1229[4] = { 'i', 'r', 'u', 'j' }; +static const symbol s_2_1230[6] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j' }; +static const symbol s_2_1231[2] = { 'a', 'l' }; +static const symbol s_2_1232[4] = { 'i', 'r', 'a', 'l' }; +static const symbol s_2_1233[4] = { 'u', 'r', 'a', 'l' }; +static const symbol s_2_1234[2] = { 'e', 'l' }; +static const symbol s_2_1235[2] = { 'i', 'l' }; +static const symbol s_2_1236[2] = { 'a', 'm' }; +static const symbol s_2_1237[4] = { 'a', 'c', 'a', 'm' }; +static const symbol s_2_1238[4] = { 'i', 'r', 'a', 'm' }; +static const symbol s_2_1239[4] = { 'u', 'r', 'a', 'm' }; +static const symbol s_2_1240[3] = { 't', 'a', 'm' }; +static const symbol s_2_1241[4] = { 'a', 'v', 'a', 'm' }; +static const symbol s_2_1242[4] = { 'e', 'v', 'a', 'm' }; +static const symbol s_2_1243[4] = { 'i', 'v', 'a', 'm' }; +static const symbol s_2_1244[4] = { 'u', 'v', 'a', 'm' }; +static const symbol s_2_1245[5] = { 'a', 0xC4, 0x8D, 'a', 'm' }; +static const symbol s_2_1246[2] = { 'e', 'm' }; +static const symbol s_2_1247[4] = { 'a', 'c', 'e', 'm' }; +static const symbol s_2_1248[4] = { 'e', 'c', 'e', 'm' }; +static const symbol s_2_1249[4] = { 'u', 'c', 'e', 'm' }; +static const symbol s_2_1250[7] = { 'a', 's', 't', 'a', 'd', 'e', 'm' }; +static const symbol s_2_1251[7] = { 'i', 's', 't', 'a', 'd', 'e', 'm' }; +static const symbol s_2_1252[7] = { 'o', 's', 't', 'a', 'd', 'e', 'm' }; +static const symbol s_2_1253[4] = { 'a', 'j', 'e', 'm' }; +static const symbol s_2_1254[5] = { 'c', 'a', 'j', 'e', 'm' }; +static const symbol s_2_1255[5] = { 'l', 'a', 'j', 'e', 'm' }; +static const symbol s_2_1256[5] = { 'r', 'a', 'j', 'e', 'm' }; +static const symbol s_2_1257[7] = { 'a', 's', 't', 'a', 'j', 'e', 'm' }; +static const symbol s_2_1258[7] = { 'i', 's', 't', 'a', 'j', 'e', 'm' }; +static const symbol s_2_1259[7] = { 'o', 's', 't', 'a', 'j', 'e', 'm' }; +static const symbol s_2_1260[6] = { 0xC4, 0x87, 'a', 'j', 'e', 'm' }; +static const symbol s_2_1261[6] = { 0xC4, 0x8D, 'a', 'j', 'e', 'm' }; +static const symbol s_2_1262[6] = { 0xC4, 0x91, 'a', 'j', 'e', 'm' }; +static const symbol s_2_1263[4] = { 'i', 'j', 'e', 'm' }; +static const symbol s_2_1264[7] = { 'a', 'n', 'j', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1265[7] = { 'e', 'n', 'j', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1266[7] = { 's', 'n', 'j', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1267[8] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1268[5] = { 'k', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1269[6] = { 's', 'k', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1270[7] = { 0xC5, 0xA1, 'k', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1271[5] = { 'l', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1272[6] = { 'e', 'l', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1273[5] = { 'n', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1274[7] = { 'r', 'a', 'r', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1275[5] = { 's', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1276[6] = { 'o', 's', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1277[6] = { 'a', 't', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1278[8] = { 'e', 'v', 'i', 't', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1279[8] = { 'o', 'v', 'i', 't', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1280[6] = { 'o', 't', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1281[7] = { 'a', 's', 't', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1282[6] = { 'a', 'v', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1283[6] = { 'e', 'v', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1284[6] = { 'i', 'v', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1285[6] = { 'o', 'v', 'i', 'j', 'e', 'm' }; +static const symbol s_2_1286[7] = { 'o', 0xC5, 0xA1, 'i', 'j', 'e', 'm' }; +static const symbol s_2_1287[5] = { 'a', 'n', 'j', 'e', 'm' }; +static const symbol s_2_1288[5] = { 'e', 'n', 'j', 'e', 'm' }; +static const symbol s_2_1289[5] = { 'i', 'n', 'j', 'e', 'm' }; +static const symbol s_2_1290[5] = { 's', 'n', 'j', 'e', 'm' }; +static const symbol s_2_1291[6] = { 0xC5, 0xA1, 'n', 'j', 'e', 'm' }; +static const symbol s_2_1292[4] = { 'u', 'j', 'e', 'm' }; +static const symbol s_2_1293[7] = { 'l', 'u', 'c', 'u', 'j', 'e', 'm' }; +static const symbol s_2_1294[6] = { 'i', 'r', 'u', 'j', 'e', 'm' }; +static const symbol s_2_1295[8] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'e', 'm' }; +static const symbol s_2_1296[3] = { 'k', 'e', 'm' }; +static const symbol s_2_1297[4] = { 's', 'k', 'e', 'm' }; +static const symbol s_2_1298[5] = { 0xC5, 0xA1, 'k', 'e', 'm' }; +static const symbol s_2_1299[4] = { 'e', 'l', 'e', 'm' }; +static const symbol s_2_1300[3] = { 'n', 'e', 'm' }; +static const symbol s_2_1301[4] = { 'a', 'n', 'e', 'm' }; +static const symbol s_2_1302[7] = { 'a', 's', 't', 'a', 'n', 'e', 'm' }; +static const symbol s_2_1303[7] = { 'i', 's', 't', 'a', 'n', 'e', 'm' }; +static const symbol s_2_1304[7] = { 'o', 's', 't', 'a', 'n', 'e', 'm' }; +static const symbol s_2_1305[4] = { 'e', 'n', 'e', 'm' }; +static const symbol s_2_1306[4] = { 's', 'n', 'e', 'm' }; +static const symbol s_2_1307[5] = { 0xC5, 0xA1, 'n', 'e', 'm' }; +static const symbol s_2_1308[5] = { 'b', 'a', 's', 'e', 'm' }; +static const symbol s_2_1309[5] = { 'g', 'a', 's', 'e', 'm' }; +static const symbol s_2_1310[5] = { 'j', 'a', 's', 'e', 'm' }; +static const symbol s_2_1311[5] = { 'k', 'a', 's', 'e', 'm' }; +static const symbol s_2_1312[5] = { 'n', 'a', 's', 'e', 'm' }; +static const symbol s_2_1313[5] = { 't', 'a', 's', 'e', 'm' }; +static const symbol s_2_1314[5] = { 'v', 'a', 's', 'e', 'm' }; +static const symbol s_2_1315[4] = { 'e', 's', 'e', 'm' }; +static const symbol s_2_1316[4] = { 'i', 's', 'e', 'm' }; +static const symbol s_2_1317[4] = { 'o', 's', 'e', 'm' }; +static const symbol s_2_1318[4] = { 'a', 't', 'e', 'm' }; +static const symbol s_2_1319[4] = { 'e', 't', 'e', 'm' }; +static const symbol s_2_1320[6] = { 'e', 'v', 'i', 't', 'e', 'm' }; +static const symbol s_2_1321[6] = { 'o', 'v', 'i', 't', 'e', 'm' }; +static const symbol s_2_1322[5] = { 'a', 's', 't', 'e', 'm' }; +static const symbol s_2_1323[5] = { 'i', 's', 't', 'e', 'm' }; +static const symbol s_2_1324[6] = { 'i', 0xC5, 0xA1, 't', 'e', 'm' }; +static const symbol s_2_1325[4] = { 'a', 'v', 'e', 'm' }; +static const symbol s_2_1326[4] = { 'e', 'v', 'e', 'm' }; +static const symbol s_2_1327[4] = { 'i', 'v', 'e', 'm' }; +static const symbol s_2_1328[5] = { 'a', 0xC4, 0x87, 'e', 'm' }; +static const symbol s_2_1329[5] = { 'e', 0xC4, 0x87, 'e', 'm' }; +static const symbol s_2_1330[5] = { 'u', 0xC4, 0x87, 'e', 'm' }; +static const symbol s_2_1331[6] = { 'b', 'a', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1332[6] = { 'g', 'a', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1333[6] = { 'j', 'a', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1334[6] = { 'k', 'a', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1335[6] = { 'n', 'a', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1336[6] = { 't', 'a', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1337[6] = { 'v', 'a', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1338[5] = { 'e', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1339[5] = { 'i', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1340[5] = { 'o', 0xC5, 0xA1, 'e', 'm' }; +static const symbol s_2_1341[2] = { 'i', 'm' }; +static const symbol s_2_1342[4] = { 'a', 'c', 'i', 'm' }; +static const symbol s_2_1343[4] = { 'e', 'c', 'i', 'm' }; +static const symbol s_2_1344[4] = { 'u', 'c', 'i', 'm' }; +static const symbol s_2_1345[5] = { 'l', 'u', 'c', 'i', 'm' }; +static const symbol s_2_1346[7] = { 'a', 'n', 'j', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1347[7] = { 'e', 'n', 'j', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1348[7] = { 's', 'n', 'j', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1349[8] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1350[5] = { 'k', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1351[6] = { 's', 'k', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1352[7] = { 0xC5, 0xA1, 'k', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1353[6] = { 'e', 'l', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1354[5] = { 'n', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1355[6] = { 'o', 's', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1356[6] = { 'a', 't', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1357[8] = { 'e', 'v', 'i', 't', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1358[8] = { 'o', 'v', 'i', 't', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1359[7] = { 'a', 's', 't', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1360[6] = { 'a', 'v', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1361[6] = { 'e', 'v', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1362[6] = { 'i', 'v', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1363[6] = { 'o', 'v', 'i', 'j', 'i', 'm' }; +static const symbol s_2_1364[7] = { 'o', 0xC5, 0xA1, 'i', 'j', 'i', 'm' }; +static const symbol s_2_1365[5] = { 'a', 'n', 'j', 'i', 'm' }; +static const symbol s_2_1366[5] = { 'e', 'n', 'j', 'i', 'm' }; +static const symbol s_2_1367[5] = { 's', 'n', 'j', 'i', 'm' }; +static const symbol s_2_1368[6] = { 0xC5, 0xA1, 'n', 'j', 'i', 'm' }; +static const symbol s_2_1369[3] = { 'k', 'i', 'm' }; +static const symbol s_2_1370[4] = { 's', 'k', 'i', 'm' }; +static const symbol s_2_1371[5] = { 0xC5, 0xA1, 'k', 'i', 'm' }; +static const symbol s_2_1372[4] = { 'e', 'l', 'i', 'm' }; +static const symbol s_2_1373[3] = { 'n', 'i', 'm' }; +static const symbol s_2_1374[5] = { 'c', 'i', 'n', 'i', 'm' }; +static const symbol s_2_1375[6] = { 0xC4, 0x8D, 'i', 'n', 'i', 'm' }; +static const symbol s_2_1376[4] = { 'o', 's', 'i', 'm' }; +static const symbol s_2_1377[5] = { 'r', 'o', 's', 'i', 'm' }; +static const symbol s_2_1378[4] = { 'a', 't', 'i', 'm' }; +static const symbol s_2_1379[5] = { 'j', 'e', 't', 'i', 'm' }; +static const symbol s_2_1380[6] = { 'e', 'v', 'i', 't', 'i', 'm' }; +static const symbol s_2_1381[6] = { 'o', 'v', 'i', 't', 'i', 'm' }; +static const symbol s_2_1382[5] = { 'a', 's', 't', 'i', 'm' }; +static const symbol s_2_1383[4] = { 'a', 'v', 'i', 'm' }; +static const symbol s_2_1384[4] = { 'e', 'v', 'i', 'm' }; +static const symbol s_2_1385[4] = { 'i', 'v', 'i', 'm' }; +static const symbol s_2_1386[4] = { 'o', 'v', 'i', 'm' }; +static const symbol s_2_1387[5] = { 'a', 0xC4, 0x87, 'i', 'm' }; +static const symbol s_2_1388[5] = { 'e', 0xC4, 0x87, 'i', 'm' }; +static const symbol s_2_1389[5] = { 'u', 0xC4, 0x87, 'i', 'm' }; +static const symbol s_2_1390[5] = { 'a', 0xC4, 0x8D, 'i', 'm' }; +static const symbol s_2_1391[6] = { 'l', 'u', 0xC4, 0x8D, 'i', 'm' }; +static const symbol s_2_1392[5] = { 'o', 0xC5, 0xA1, 'i', 'm' }; +static const symbol s_2_1393[6] = { 'r', 'o', 0xC5, 0xA1, 'i', 'm' }; +static const symbol s_2_1394[4] = { 'a', 'c', 'o', 'm' }; +static const symbol s_2_1395[4] = { 'e', 'c', 'o', 'm' }; +static const symbol s_2_1396[4] = { 'u', 'c', 'o', 'm' }; +static const symbol s_2_1397[3] = { 'g', 'o', 'm' }; +static const symbol s_2_1398[5] = { 'l', 'o', 'g', 'o', 'm' }; +static const symbol s_2_1399[4] = { 'u', 'g', 'o', 'm' }; +static const symbol s_2_1400[5] = { 'b', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1401[5] = { 'c', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1402[5] = { 'd', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1403[5] = { 'f', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1404[5] = { 'g', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1405[5] = { 'l', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1406[5] = { 'm', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1407[5] = { 'n', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1408[7] = { 'g', 'a', 'n', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1409[7] = { 'm', 'a', 'n', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1410[7] = { 'p', 'a', 'n', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1411[7] = { 'r', 'a', 'n', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1412[7] = { 't', 'a', 'n', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1413[5] = { 'p', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1414[5] = { 'r', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1415[5] = { 's', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1416[5] = { 't', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1417[5] = { 'z', 'i', 'j', 'o', 'm' }; +static const symbol s_2_1418[6] = { 0xC5, 0xBE, 'i', 'j', 'o', 'm' }; +static const symbol s_2_1419[5] = { 'a', 'n', 'j', 'o', 'm' }; +static const symbol s_2_1420[5] = { 'e', 'n', 'j', 'o', 'm' }; +static const symbol s_2_1421[5] = { 's', 'n', 'j', 'o', 'm' }; +static const symbol s_2_1422[6] = { 0xC5, 0xA1, 'n', 'j', 'o', 'm' }; +static const symbol s_2_1423[3] = { 'k', 'o', 'm' }; +static const symbol s_2_1424[4] = { 's', 'k', 'o', 'm' }; +static const symbol s_2_1425[5] = { 0xC5, 0xA1, 'k', 'o', 'm' }; +static const symbol s_2_1426[4] = { 'a', 'l', 'o', 'm' }; +static const symbol s_2_1427[6] = { 'i', 'j', 'a', 'l', 'o', 'm' }; +static const symbol s_2_1428[5] = { 'n', 'a', 'l', 'o', 'm' }; +static const symbol s_2_1429[4] = { 'e', 'l', 'o', 'm' }; +static const symbol s_2_1430[4] = { 'i', 'l', 'o', 'm' }; +static const symbol s_2_1431[6] = { 'o', 'z', 'i', 'l', 'o', 'm' }; +static const symbol s_2_1432[4] = { 'o', 'l', 'o', 'm' }; +static const symbol s_2_1433[5] = { 'r', 'a', 'm', 'o', 'm' }; +static const symbol s_2_1434[5] = { 'l', 'e', 'm', 'o', 'm' }; +static const symbol s_2_1435[3] = { 'n', 'o', 'm' }; +static const symbol s_2_1436[4] = { 'a', 'n', 'o', 'm' }; +static const symbol s_2_1437[4] = { 'i', 'n', 'o', 'm' }; +static const symbol s_2_1438[5] = { 'c', 'i', 'n', 'o', 'm' }; +static const symbol s_2_1439[6] = { 'a', 'n', 'i', 'n', 'o', 'm' }; +static const symbol s_2_1440[6] = { 0xC4, 0x8D, 'i', 'n', 'o', 'm' }; +static const symbol s_2_1441[4] = { 'o', 'n', 'o', 'm' }; +static const symbol s_2_1442[4] = { 'a', 'r', 'o', 'm' }; +static const symbol s_2_1443[4] = { 'd', 'r', 'o', 'm' }; +static const symbol s_2_1444[4] = { 'e', 'r', 'o', 'm' }; +static const symbol s_2_1445[4] = { 'o', 'r', 'o', 'm' }; +static const symbol s_2_1446[5] = { 'b', 'a', 's', 'o', 'm' }; +static const symbol s_2_1447[5] = { 'g', 'a', 's', 'o', 'm' }; +static const symbol s_2_1448[5] = { 'j', 'a', 's', 'o', 'm' }; +static const symbol s_2_1449[5] = { 'k', 'a', 's', 'o', 'm' }; +static const symbol s_2_1450[5] = { 'n', 'a', 's', 'o', 'm' }; +static const symbol s_2_1451[5] = { 't', 'a', 's', 'o', 'm' }; +static const symbol s_2_1452[5] = { 'v', 'a', 's', 'o', 'm' }; +static const symbol s_2_1453[4] = { 'e', 's', 'o', 'm' }; +static const symbol s_2_1454[4] = { 'i', 's', 'o', 'm' }; +static const symbol s_2_1455[4] = { 'o', 's', 'o', 'm' }; +static const symbol s_2_1456[4] = { 'a', 't', 'o', 'm' }; +static const symbol s_2_1457[6] = { 'i', 'k', 'a', 't', 'o', 'm' }; +static const symbol s_2_1458[5] = { 'l', 'a', 't', 'o', 'm' }; +static const symbol s_2_1459[4] = { 'e', 't', 'o', 'm' }; +static const symbol s_2_1460[6] = { 'e', 'v', 'i', 't', 'o', 'm' }; +static const symbol s_2_1461[6] = { 'o', 'v', 'i', 't', 'o', 'm' }; +static const symbol s_2_1462[5] = { 'a', 's', 't', 'o', 'm' }; +static const symbol s_2_1463[5] = { 'e', 's', 't', 'o', 'm' }; +static const symbol s_2_1464[5] = { 'i', 's', 't', 'o', 'm' }; +static const symbol s_2_1465[5] = { 'k', 's', 't', 'o', 'm' }; +static const symbol s_2_1466[5] = { 'o', 's', 't', 'o', 'm' }; +static const symbol s_2_1467[4] = { 'a', 'v', 'o', 'm' }; +static const symbol s_2_1468[4] = { 'e', 'v', 'o', 'm' }; +static const symbol s_2_1469[4] = { 'i', 'v', 'o', 'm' }; +static const symbol s_2_1470[4] = { 'o', 'v', 'o', 'm' }; +static const symbol s_2_1471[5] = { 'l', 'o', 'v', 'o', 'm' }; +static const symbol s_2_1472[5] = { 'm', 'o', 'v', 'o', 'm' }; +static const symbol s_2_1473[5] = { 's', 't', 'v', 'o', 'm' }; +static const symbol s_2_1474[6] = { 0xC5, 0xA1, 't', 'v', 'o', 'm' }; +static const symbol s_2_1475[5] = { 'a', 0xC4, 0x87, 'o', 'm' }; +static const symbol s_2_1476[5] = { 'e', 0xC4, 0x87, 'o', 'm' }; +static const symbol s_2_1477[5] = { 'u', 0xC4, 0x87, 'o', 'm' }; +static const symbol s_2_1478[6] = { 'b', 'a', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1479[6] = { 'g', 'a', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1480[6] = { 'j', 'a', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1481[6] = { 'k', 'a', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1482[6] = { 'n', 'a', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1483[6] = { 't', 'a', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1484[6] = { 'v', 'a', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1485[5] = { 'e', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1486[5] = { 'i', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1487[5] = { 'o', 0xC5, 0xA1, 'o', 'm' }; +static const symbol s_2_1488[2] = { 'a', 'n' }; +static const symbol s_2_1489[4] = { 'a', 'c', 'a', 'n' }; +static const symbol s_2_1490[4] = { 'i', 'r', 'a', 'n' }; +static const symbol s_2_1491[4] = { 'u', 'r', 'a', 'n' }; +static const symbol s_2_1492[3] = { 't', 'a', 'n' }; +static const symbol s_2_1493[4] = { 'a', 'v', 'a', 'n' }; +static const symbol s_2_1494[4] = { 'e', 'v', 'a', 'n' }; +static const symbol s_2_1495[4] = { 'i', 'v', 'a', 'n' }; +static const symbol s_2_1496[4] = { 'u', 'v', 'a', 'n' }; +static const symbol s_2_1497[5] = { 'a', 0xC4, 0x8D, 'a', 'n' }; +static const symbol s_2_1498[4] = { 'a', 'c', 'e', 'n' }; +static const symbol s_2_1499[5] = { 'l', 'u', 'c', 'e', 'n' }; +static const symbol s_2_1500[5] = { 'a', 0xC4, 0x8D, 'e', 'n' }; +static const symbol s_2_1501[6] = { 'l', 'u', 0xC4, 0x8D, 'e', 'n' }; +static const symbol s_2_1502[4] = { 'a', 'n', 'i', 'n' }; +static const symbol s_2_1503[2] = { 'a', 'o' }; +static const symbol s_2_1504[4] = { 'a', 'c', 'a', 'o' }; +static const symbol s_2_1505[7] = { 'a', 's', 't', 'a', 'j', 'a', 'o' }; +static const symbol s_2_1506[7] = { 'i', 's', 't', 'a', 'j', 'a', 'o' }; +static const symbol s_2_1507[7] = { 'o', 's', 't', 'a', 'j', 'a', 'o' }; +static const symbol s_2_1508[5] = { 'i', 'n', 'j', 'a', 'o' }; +static const symbol s_2_1509[4] = { 'i', 'r', 'a', 'o' }; +static const symbol s_2_1510[4] = { 'u', 'r', 'a', 'o' }; +static const symbol s_2_1511[3] = { 't', 'a', 'o' }; +static const symbol s_2_1512[5] = { 'a', 's', 't', 'a', 'o' }; +static const symbol s_2_1513[5] = { 'i', 's', 't', 'a', 'o' }; +static const symbol s_2_1514[5] = { 'o', 's', 't', 'a', 'o' }; +static const symbol s_2_1515[4] = { 'a', 'v', 'a', 'o' }; +static const symbol s_2_1516[4] = { 'e', 'v', 'a', 'o' }; +static const symbol s_2_1517[4] = { 'i', 'v', 'a', 'o' }; +static const symbol s_2_1518[4] = { 'o', 'v', 'a', 'o' }; +static const symbol s_2_1519[4] = { 'u', 'v', 'a', 'o' }; +static const symbol s_2_1520[5] = { 'a', 0xC4, 0x8D, 'a', 'o' }; +static const symbol s_2_1521[2] = { 'g', 'o' }; +static const symbol s_2_1522[3] = { 'u', 'g', 'o' }; +static const symbol s_2_1523[2] = { 'i', 'o' }; +static const symbol s_2_1524[4] = { 'a', 'c', 'i', 'o' }; +static const symbol s_2_1525[5] = { 'l', 'u', 'c', 'i', 'o' }; +static const symbol s_2_1526[3] = { 'l', 'i', 'o' }; +static const symbol s_2_1527[3] = { 'n', 'i', 'o' }; +static const symbol s_2_1528[5] = { 'r', 'a', 'r', 'i', 'o' }; +static const symbol s_2_1529[3] = { 's', 'i', 'o' }; +static const symbol s_2_1530[5] = { 'r', 'o', 's', 'i', 'o' }; +static const symbol s_2_1531[5] = { 'j', 'e', 't', 'i', 'o' }; +static const symbol s_2_1532[4] = { 'o', 't', 'i', 'o' }; +static const symbol s_2_1533[5] = { 'a', 0xC4, 0x8D, 'i', 'o' }; +static const symbol s_2_1534[6] = { 'l', 'u', 0xC4, 0x8D, 'i', 'o' }; +static const symbol s_2_1535[6] = { 'r', 'o', 0xC5, 0xA1, 'i', 'o' }; +static const symbol s_2_1536[4] = { 'b', 'i', 'j', 'o' }; +static const symbol s_2_1537[4] = { 'c', 'i', 'j', 'o' }; +static const symbol s_2_1538[4] = { 'd', 'i', 'j', 'o' }; +static const symbol s_2_1539[4] = { 'f', 'i', 'j', 'o' }; +static const symbol s_2_1540[4] = { 'g', 'i', 'j', 'o' }; +static const symbol s_2_1541[4] = { 'l', 'i', 'j', 'o' }; +static const symbol s_2_1542[4] = { 'm', 'i', 'j', 'o' }; +static const symbol s_2_1543[4] = { 'n', 'i', 'j', 'o' }; +static const symbol s_2_1544[4] = { 'p', 'i', 'j', 'o' }; +static const symbol s_2_1545[4] = { 'r', 'i', 'j', 'o' }; +static const symbol s_2_1546[4] = { 's', 'i', 'j', 'o' }; +static const symbol s_2_1547[4] = { 't', 'i', 'j', 'o' }; +static const symbol s_2_1548[4] = { 'z', 'i', 'j', 'o' }; +static const symbol s_2_1549[5] = { 0xC5, 0xBE, 'i', 'j', 'o' }; +static const symbol s_2_1550[4] = { 'a', 'n', 'j', 'o' }; +static const symbol s_2_1551[4] = { 'e', 'n', 'j', 'o' }; +static const symbol s_2_1552[4] = { 's', 'n', 'j', 'o' }; +static const symbol s_2_1553[5] = { 0xC5, 0xA1, 'n', 'j', 'o' }; +static const symbol s_2_1554[2] = { 'k', 'o' }; +static const symbol s_2_1555[3] = { 's', 'k', 'o' }; +static const symbol s_2_1556[4] = { 0xC5, 0xA1, 'k', 'o' }; +static const symbol s_2_1557[3] = { 'a', 'l', 'o' }; +static const symbol s_2_1558[5] = { 'a', 'c', 'a', 'l', 'o' }; +static const symbol s_2_1559[8] = { 'a', 's', 't', 'a', 'j', 'a', 'l', 'o' }; +static const symbol s_2_1560[8] = { 'i', 's', 't', 'a', 'j', 'a', 'l', 'o' }; +static const symbol s_2_1561[8] = { 'o', 's', 't', 'a', 'j', 'a', 'l', 'o' }; +static const symbol s_2_1562[5] = { 'i', 'j', 'a', 'l', 'o' }; +static const symbol s_2_1563[6] = { 'i', 'n', 'j', 'a', 'l', 'o' }; +static const symbol s_2_1564[4] = { 'n', 'a', 'l', 'o' }; +static const symbol s_2_1565[5] = { 'i', 'r', 'a', 'l', 'o' }; +static const symbol s_2_1566[5] = { 'u', 'r', 'a', 'l', 'o' }; +static const symbol s_2_1567[4] = { 't', 'a', 'l', 'o' }; +static const symbol s_2_1568[6] = { 'a', 's', 't', 'a', 'l', 'o' }; +static const symbol s_2_1569[6] = { 'i', 's', 't', 'a', 'l', 'o' }; +static const symbol s_2_1570[6] = { 'o', 's', 't', 'a', 'l', 'o' }; +static const symbol s_2_1571[5] = { 'a', 'v', 'a', 'l', 'o' }; +static const symbol s_2_1572[5] = { 'e', 'v', 'a', 'l', 'o' }; +static const symbol s_2_1573[5] = { 'i', 'v', 'a', 'l', 'o' }; +static const symbol s_2_1574[5] = { 'o', 'v', 'a', 'l', 'o' }; +static const symbol s_2_1575[5] = { 'u', 'v', 'a', 'l', 'o' }; +static const symbol s_2_1576[6] = { 'a', 0xC4, 0x8D, 'a', 'l', 'o' }; +static const symbol s_2_1577[3] = { 'e', 'l', 'o' }; +static const symbol s_2_1578[3] = { 'i', 'l', 'o' }; +static const symbol s_2_1579[5] = { 'a', 'c', 'i', 'l', 'o' }; +static const symbol s_2_1580[6] = { 'l', 'u', 'c', 'i', 'l', 'o' }; +static const symbol s_2_1581[4] = { 'n', 'i', 'l', 'o' }; +static const symbol s_2_1582[6] = { 'r', 'o', 's', 'i', 'l', 'o' }; +static const symbol s_2_1583[6] = { 'j', 'e', 't', 'i', 'l', 'o' }; +static const symbol s_2_1584[6] = { 'a', 0xC4, 0x8D, 'i', 'l', 'o' }; +static const symbol s_2_1585[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 'l', 'o' }; +static const symbol s_2_1586[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 'l', 'o' }; +static const symbol s_2_1587[4] = { 'a', 's', 'l', 'o' }; +static const symbol s_2_1588[4] = { 'n', 'u', 'l', 'o' }; +static const symbol s_2_1589[3] = { 'a', 'm', 'o' }; +static const symbol s_2_1590[5] = { 'a', 'c', 'a', 'm', 'o' }; +static const symbol s_2_1591[4] = { 'r', 'a', 'm', 'o' }; +static const symbol s_2_1592[5] = { 'i', 'r', 'a', 'm', 'o' }; +static const symbol s_2_1593[5] = { 'u', 'r', 'a', 'm', 'o' }; +static const symbol s_2_1594[4] = { 't', 'a', 'm', 'o' }; +static const symbol s_2_1595[5] = { 'a', 'v', 'a', 'm', 'o' }; +static const symbol s_2_1596[5] = { 'e', 'v', 'a', 'm', 'o' }; +static const symbol s_2_1597[5] = { 'i', 'v', 'a', 'm', 'o' }; +static const symbol s_2_1598[5] = { 'u', 'v', 'a', 'm', 'o' }; +static const symbol s_2_1599[6] = { 'a', 0xC4, 0x8D, 'a', 'm', 'o' }; +static const symbol s_2_1600[3] = { 'e', 'm', 'o' }; +static const symbol s_2_1601[8] = { 'a', 's', 't', 'a', 'd', 'e', 'm', 'o' }; +static const symbol s_2_1602[8] = { 'i', 's', 't', 'a', 'd', 'e', 'm', 'o' }; +static const symbol s_2_1603[8] = { 'o', 's', 't', 'a', 'd', 'e', 'm', 'o' }; +static const symbol s_2_1604[8] = { 'a', 's', 't', 'a', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1605[8] = { 'i', 's', 't', 'a', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1606[8] = { 'o', 's', 't', 'a', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1607[5] = { 'i', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1608[6] = { 'i', 'n', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1609[5] = { 'u', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1610[8] = { 'l', 'u', 'c', 'u', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1611[7] = { 'i', 'r', 'u', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1612[9] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'e', 'm', 'o' }; +static const symbol s_2_1613[4] = { 'l', 'e', 'm', 'o' }; +static const symbol s_2_1614[4] = { 'n', 'e', 'm', 'o' }; +static const symbol s_2_1615[8] = { 'a', 's', 't', 'a', 'n', 'e', 'm', 'o' }; +static const symbol s_2_1616[8] = { 'i', 's', 't', 'a', 'n', 'e', 'm', 'o' }; +static const symbol s_2_1617[8] = { 'o', 's', 't', 'a', 'n', 'e', 'm', 'o' }; +static const symbol s_2_1618[5] = { 'e', 't', 'e', 'm', 'o' }; +static const symbol s_2_1619[6] = { 'a', 's', 't', 'e', 'm', 'o' }; +static const symbol s_2_1620[3] = { 'i', 'm', 'o' }; +static const symbol s_2_1621[5] = { 'a', 'c', 'i', 'm', 'o' }; +static const symbol s_2_1622[6] = { 'l', 'u', 'c', 'i', 'm', 'o' }; +static const symbol s_2_1623[4] = { 'n', 'i', 'm', 'o' }; +static const symbol s_2_1624[8] = { 'a', 's', 't', 'a', 'n', 'i', 'm', 'o' }; +static const symbol s_2_1625[8] = { 'i', 's', 't', 'a', 'n', 'i', 'm', 'o' }; +static const symbol s_2_1626[8] = { 'o', 's', 't', 'a', 'n', 'i', 'm', 'o' }; +static const symbol s_2_1627[6] = { 'r', 'o', 's', 'i', 'm', 'o' }; +static const symbol s_2_1628[5] = { 'e', 't', 'i', 'm', 'o' }; +static const symbol s_2_1629[6] = { 'j', 'e', 't', 'i', 'm', 'o' }; +static const symbol s_2_1630[6] = { 'a', 's', 't', 'i', 'm', 'o' }; +static const symbol s_2_1631[6] = { 'a', 0xC4, 0x8D, 'i', 'm', 'o' }; +static const symbol s_2_1632[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 'm', 'o' }; +static const symbol s_2_1633[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 'm', 'o' }; +static const symbol s_2_1634[4] = { 'a', 'j', 'm', 'o' }; +static const symbol s_2_1635[6] = { 'u', 'r', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1636[5] = { 't', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1637[7] = { 'a', 's', 't', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1638[7] = { 'i', 's', 't', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1639[7] = { 'o', 's', 't', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1640[6] = { 'a', 'v', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1641[6] = { 'e', 'v', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1642[6] = { 'i', 'v', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1643[6] = { 'u', 'v', 'a', 'j', 'm', 'o' }; +static const symbol s_2_1644[4] = { 'i', 'j', 'm', 'o' }; +static const symbol s_2_1645[4] = { 'u', 'j', 'm', 'o' }; +static const symbol s_2_1646[7] = { 'l', 'u', 'c', 'u', 'j', 'm', 'o' }; +static const symbol s_2_1647[6] = { 'i', 'r', 'u', 'j', 'm', 'o' }; +static const symbol s_2_1648[8] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'm', 'o' }; +static const symbol s_2_1649[4] = { 'a', 's', 'm', 'o' }; +static const symbol s_2_1650[6] = { 'a', 'c', 'a', 's', 'm', 'o' }; +static const symbol s_2_1651[9] = { 'a', 's', 't', 'a', 'j', 'a', 's', 'm', 'o' }; +static const symbol s_2_1652[9] = { 'i', 's', 't', 'a', 'j', 'a', 's', 'm', 'o' }; +static const symbol s_2_1653[9] = { 'o', 's', 't', 'a', 'j', 'a', 's', 'm', 'o' }; +static const symbol s_2_1654[7] = { 'i', 'n', 'j', 'a', 's', 'm', 'o' }; +static const symbol s_2_1655[6] = { 'i', 'r', 'a', 's', 'm', 'o' }; +static const symbol s_2_1656[6] = { 'u', 'r', 'a', 's', 'm', 'o' }; +static const symbol s_2_1657[5] = { 't', 'a', 's', 'm', 'o' }; +static const symbol s_2_1658[6] = { 'a', 'v', 'a', 's', 'm', 'o' }; +static const symbol s_2_1659[6] = { 'e', 'v', 'a', 's', 'm', 'o' }; +static const symbol s_2_1660[6] = { 'i', 'v', 'a', 's', 'm', 'o' }; +static const symbol s_2_1661[6] = { 'o', 'v', 'a', 's', 'm', 'o' }; +static const symbol s_2_1662[6] = { 'u', 'v', 'a', 's', 'm', 'o' }; +static const symbol s_2_1663[7] = { 'a', 0xC4, 0x8D, 'a', 's', 'm', 'o' }; +static const symbol s_2_1664[4] = { 'i', 's', 'm', 'o' }; +static const symbol s_2_1665[6] = { 'a', 'c', 'i', 's', 'm', 'o' }; +static const symbol s_2_1666[7] = { 'l', 'u', 'c', 'i', 's', 'm', 'o' }; +static const symbol s_2_1667[5] = { 'n', 'i', 's', 'm', 'o' }; +static const symbol s_2_1668[7] = { 'r', 'o', 's', 'i', 's', 'm', 'o' }; +static const symbol s_2_1669[7] = { 'j', 'e', 't', 'i', 's', 'm', 'o' }; +static const symbol s_2_1670[7] = { 'a', 0xC4, 0x8D, 'i', 's', 'm', 'o' }; +static const symbol s_2_1671[8] = { 'l', 'u', 0xC4, 0x8D, 'i', 's', 'm', 'o' }; +static const symbol s_2_1672[8] = { 'r', 'o', 0xC5, 0xA1, 'i', 's', 'm', 'o' }; +static const symbol s_2_1673[9] = { 'a', 's', 't', 'a', 'd', 'o', 's', 'm', 'o' }; +static const symbol s_2_1674[9] = { 'i', 's', 't', 'a', 'd', 'o', 's', 'm', 'o' }; +static const symbol s_2_1675[9] = { 'o', 's', 't', 'a', 'd', 'o', 's', 'm', 'o' }; +static const symbol s_2_1676[5] = { 'n', 'u', 's', 'm', 'o' }; +static const symbol s_2_1677[2] = { 'n', 'o' }; +static const symbol s_2_1678[3] = { 'a', 'n', 'o' }; +static const symbol s_2_1679[5] = { 'a', 'c', 'a', 'n', 'o' }; +static const symbol s_2_1680[5] = { 'u', 'r', 'a', 'n', 'o' }; +static const symbol s_2_1681[4] = { 't', 'a', 'n', 'o' }; +static const symbol s_2_1682[5] = { 'a', 'v', 'a', 'n', 'o' }; +static const symbol s_2_1683[5] = { 'e', 'v', 'a', 'n', 'o' }; +static const symbol s_2_1684[5] = { 'i', 'v', 'a', 'n', 'o' }; +static const symbol s_2_1685[5] = { 'u', 'v', 'a', 'n', 'o' }; +static const symbol s_2_1686[6] = { 'a', 0xC4, 0x8D, 'a', 'n', 'o' }; +static const symbol s_2_1687[5] = { 'a', 'c', 'e', 'n', 'o' }; +static const symbol s_2_1688[6] = { 'l', 'u', 'c', 'e', 'n', 'o' }; +static const symbol s_2_1689[6] = { 'a', 0xC4, 0x8D, 'e', 'n', 'o' }; +static const symbol s_2_1690[7] = { 'l', 'u', 0xC4, 0x8D, 'e', 'n', 'o' }; +static const symbol s_2_1691[3] = { 'i', 'n', 'o' }; +static const symbol s_2_1692[4] = { 'c', 'i', 'n', 'o' }; +static const symbol s_2_1693[5] = { 0xC4, 0x8D, 'i', 'n', 'o' }; +static const symbol s_2_1694[3] = { 'a', 't', 'o' }; +static const symbol s_2_1695[5] = { 'i', 'k', 'a', 't', 'o' }; +static const symbol s_2_1696[4] = { 'l', 'a', 't', 'o' }; +static const symbol s_2_1697[3] = { 'e', 't', 'o' }; +static const symbol s_2_1698[5] = { 'e', 'v', 'i', 't', 'o' }; +static const symbol s_2_1699[5] = { 'o', 'v', 'i', 't', 'o' }; +static const symbol s_2_1700[4] = { 'a', 's', 't', 'o' }; +static const symbol s_2_1701[4] = { 'e', 's', 't', 'o' }; +static const symbol s_2_1702[4] = { 'i', 's', 't', 'o' }; +static const symbol s_2_1703[4] = { 'k', 's', 't', 'o' }; +static const symbol s_2_1704[4] = { 'o', 's', 't', 'o' }; +static const symbol s_2_1705[4] = { 'n', 'u', 't', 'o' }; +static const symbol s_2_1706[3] = { 'n', 'u', 'o' }; +static const symbol s_2_1707[3] = { 'a', 'v', 'o' }; +static const symbol s_2_1708[3] = { 'e', 'v', 'o' }; +static const symbol s_2_1709[3] = { 'i', 'v', 'o' }; +static const symbol s_2_1710[3] = { 'o', 'v', 'o' }; +static const symbol s_2_1711[4] = { 's', 't', 'v', 'o' }; +static const symbol s_2_1712[5] = { 0xC5, 0xA1, 't', 'v', 'o' }; +static const symbol s_2_1713[2] = { 'a', 's' }; +static const symbol s_2_1714[4] = { 'a', 'c', 'a', 's' }; +static const symbol s_2_1715[4] = { 'i', 'r', 'a', 's' }; +static const symbol s_2_1716[4] = { 'u', 'r', 'a', 's' }; +static const symbol s_2_1717[3] = { 't', 'a', 's' }; +static const symbol s_2_1718[4] = { 'a', 'v', 'a', 's' }; +static const symbol s_2_1719[4] = { 'e', 'v', 'a', 's' }; +static const symbol s_2_1720[4] = { 'i', 'v', 'a', 's' }; +static const symbol s_2_1721[4] = { 'u', 'v', 'a', 's' }; +static const symbol s_2_1722[2] = { 'e', 's' }; +static const symbol s_2_1723[7] = { 'a', 's', 't', 'a', 'd', 'e', 's' }; +static const symbol s_2_1724[7] = { 'i', 's', 't', 'a', 'd', 'e', 's' }; +static const symbol s_2_1725[7] = { 'o', 's', 't', 'a', 'd', 'e', 's' }; +static const symbol s_2_1726[7] = { 'a', 's', 't', 'a', 'j', 'e', 's' }; +static const symbol s_2_1727[7] = { 'i', 's', 't', 'a', 'j', 'e', 's' }; +static const symbol s_2_1728[7] = { 'o', 's', 't', 'a', 'j', 'e', 's' }; +static const symbol s_2_1729[4] = { 'i', 'j', 'e', 's' }; +static const symbol s_2_1730[5] = { 'i', 'n', 'j', 'e', 's' }; +static const symbol s_2_1731[4] = { 'u', 'j', 'e', 's' }; +static const symbol s_2_1732[7] = { 'l', 'u', 'c', 'u', 'j', 'e', 's' }; +static const symbol s_2_1733[6] = { 'i', 'r', 'u', 'j', 'e', 's' }; +static const symbol s_2_1734[3] = { 'n', 'e', 's' }; +static const symbol s_2_1735[7] = { 'a', 's', 't', 'a', 'n', 'e', 's' }; +static const symbol s_2_1736[7] = { 'i', 's', 't', 'a', 'n', 'e', 's' }; +static const symbol s_2_1737[7] = { 'o', 's', 't', 'a', 'n', 'e', 's' }; +static const symbol s_2_1738[4] = { 'e', 't', 'e', 's' }; +static const symbol s_2_1739[5] = { 'a', 's', 't', 'e', 's' }; +static const symbol s_2_1740[2] = { 'i', 's' }; +static const symbol s_2_1741[4] = { 'a', 'c', 'i', 's' }; +static const symbol s_2_1742[5] = { 'l', 'u', 'c', 'i', 's' }; +static const symbol s_2_1743[3] = { 'n', 'i', 's' }; +static const symbol s_2_1744[5] = { 'r', 'o', 's', 'i', 's' }; +static const symbol s_2_1745[5] = { 'j', 'e', 't', 'i', 's' }; +static const symbol s_2_1746[2] = { 'a', 't' }; +static const symbol s_2_1747[4] = { 'a', 'c', 'a', 't' }; +static const symbol s_2_1748[7] = { 'a', 's', 't', 'a', 'j', 'a', 't' }; +static const symbol s_2_1749[7] = { 'i', 's', 't', 'a', 'j', 'a', 't' }; +static const symbol s_2_1750[7] = { 'o', 's', 't', 'a', 'j', 'a', 't' }; +static const symbol s_2_1751[5] = { 'i', 'n', 'j', 'a', 't' }; +static const symbol s_2_1752[4] = { 'i', 'r', 'a', 't' }; +static const symbol s_2_1753[4] = { 'u', 'r', 'a', 't' }; +static const symbol s_2_1754[3] = { 't', 'a', 't' }; +static const symbol s_2_1755[5] = { 'a', 's', 't', 'a', 't' }; +static const symbol s_2_1756[5] = { 'i', 's', 't', 'a', 't' }; +static const symbol s_2_1757[5] = { 'o', 's', 't', 'a', 't' }; +static const symbol s_2_1758[4] = { 'a', 'v', 'a', 't' }; +static const symbol s_2_1759[4] = { 'e', 'v', 'a', 't' }; +static const symbol s_2_1760[4] = { 'i', 'v', 'a', 't' }; +static const symbol s_2_1761[6] = { 'i', 'r', 'i', 'v', 'a', 't' }; +static const symbol s_2_1762[4] = { 'o', 'v', 'a', 't' }; +static const symbol s_2_1763[4] = { 'u', 'v', 'a', 't' }; +static const symbol s_2_1764[5] = { 'a', 0xC4, 0x8D, 'a', 't' }; +static const symbol s_2_1765[2] = { 'i', 't' }; +static const symbol s_2_1766[4] = { 'a', 'c', 'i', 't' }; +static const symbol s_2_1767[5] = { 'l', 'u', 'c', 'i', 't' }; +static const symbol s_2_1768[5] = { 'r', 'o', 's', 'i', 't' }; +static const symbol s_2_1769[5] = { 'j', 'e', 't', 'i', 't' }; +static const symbol s_2_1770[5] = { 'a', 0xC4, 0x8D, 'i', 't' }; +static const symbol s_2_1771[6] = { 'l', 'u', 0xC4, 0x8D, 'i', 't' }; +static const symbol s_2_1772[6] = { 'r', 'o', 0xC5, 0xA1, 'i', 't' }; +static const symbol s_2_1773[3] = { 'n', 'u', 't' }; +static const symbol s_2_1774[6] = { 'a', 's', 't', 'a', 'd', 'u' }; +static const symbol s_2_1775[6] = { 'i', 's', 't', 'a', 'd', 'u' }; +static const symbol s_2_1776[6] = { 'o', 's', 't', 'a', 'd', 'u' }; +static const symbol s_2_1777[2] = { 'g', 'u' }; +static const symbol s_2_1778[4] = { 'l', 'o', 'g', 'u' }; +static const symbol s_2_1779[3] = { 'u', 'g', 'u' }; +static const symbol s_2_1780[3] = { 'a', 'h', 'u' }; +static const symbol s_2_1781[5] = { 'a', 'c', 'a', 'h', 'u' }; +static const symbol s_2_1782[8] = { 'a', 's', 't', 'a', 'j', 'a', 'h', 'u' }; +static const symbol s_2_1783[8] = { 'i', 's', 't', 'a', 'j', 'a', 'h', 'u' }; +static const symbol s_2_1784[8] = { 'o', 's', 't', 'a', 'j', 'a', 'h', 'u' }; +static const symbol s_2_1785[6] = { 'i', 'n', 'j', 'a', 'h', 'u' }; +static const symbol s_2_1786[5] = { 'i', 'r', 'a', 'h', 'u' }; +static const symbol s_2_1787[5] = { 'u', 'r', 'a', 'h', 'u' }; +static const symbol s_2_1788[5] = { 'a', 'v', 'a', 'h', 'u' }; +static const symbol s_2_1789[5] = { 'e', 'v', 'a', 'h', 'u' }; +static const symbol s_2_1790[5] = { 'i', 'v', 'a', 'h', 'u' }; +static const symbol s_2_1791[5] = { 'o', 'v', 'a', 'h', 'u' }; +static const symbol s_2_1792[5] = { 'u', 'v', 'a', 'h', 'u' }; +static const symbol s_2_1793[6] = { 'a', 0xC4, 0x8D, 'a', 'h', 'u' }; +static const symbol s_2_1794[3] = { 'a', 'j', 'u' }; +static const symbol s_2_1795[4] = { 'c', 'a', 'j', 'u' }; +static const symbol s_2_1796[5] = { 'a', 'c', 'a', 'j', 'u' }; +static const symbol s_2_1797[4] = { 'l', 'a', 'j', 'u' }; +static const symbol s_2_1798[4] = { 'r', 'a', 'j', 'u' }; +static const symbol s_2_1799[5] = { 'i', 'r', 'a', 'j', 'u' }; +static const symbol s_2_1800[5] = { 'u', 'r', 'a', 'j', 'u' }; +static const symbol s_2_1801[4] = { 't', 'a', 'j', 'u' }; +static const symbol s_2_1802[6] = { 'a', 's', 't', 'a', 'j', 'u' }; +static const symbol s_2_1803[6] = { 'i', 's', 't', 'a', 'j', 'u' }; +static const symbol s_2_1804[6] = { 'o', 's', 't', 'a', 'j', 'u' }; +static const symbol s_2_1805[5] = { 'a', 'v', 'a', 'j', 'u' }; +static const symbol s_2_1806[5] = { 'e', 'v', 'a', 'j', 'u' }; +static const symbol s_2_1807[5] = { 'i', 'v', 'a', 'j', 'u' }; +static const symbol s_2_1808[5] = { 'u', 'v', 'a', 'j', 'u' }; +static const symbol s_2_1809[5] = { 0xC4, 0x87, 'a', 'j', 'u' }; +static const symbol s_2_1810[5] = { 0xC4, 0x8D, 'a', 'j', 'u' }; +static const symbol s_2_1811[6] = { 'a', 0xC4, 0x8D, 'a', 'j', 'u' }; +static const symbol s_2_1812[5] = { 0xC4, 0x91, 'a', 'j', 'u' }; +static const symbol s_2_1813[3] = { 'i', 'j', 'u' }; +static const symbol s_2_1814[4] = { 'b', 'i', 'j', 'u' }; +static const symbol s_2_1815[4] = { 'c', 'i', 'j', 'u' }; +static const symbol s_2_1816[4] = { 'd', 'i', 'j', 'u' }; +static const symbol s_2_1817[4] = { 'f', 'i', 'j', 'u' }; +static const symbol s_2_1818[4] = { 'g', 'i', 'j', 'u' }; +static const symbol s_2_1819[6] = { 'a', 'n', 'j', 'i', 'j', 'u' }; +static const symbol s_2_1820[6] = { 'e', 'n', 'j', 'i', 'j', 'u' }; +static const symbol s_2_1821[6] = { 's', 'n', 'j', 'i', 'j', 'u' }; +static const symbol s_2_1822[7] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'u' }; +static const symbol s_2_1823[4] = { 'k', 'i', 'j', 'u' }; +static const symbol s_2_1824[4] = { 'l', 'i', 'j', 'u' }; +static const symbol s_2_1825[5] = { 'e', 'l', 'i', 'j', 'u' }; +static const symbol s_2_1826[4] = { 'm', 'i', 'j', 'u' }; +static const symbol s_2_1827[4] = { 'n', 'i', 'j', 'u' }; +static const symbol s_2_1828[6] = { 'g', 'a', 'n', 'i', 'j', 'u' }; +static const symbol s_2_1829[6] = { 'm', 'a', 'n', 'i', 'j', 'u' }; +static const symbol s_2_1830[6] = { 'p', 'a', 'n', 'i', 'j', 'u' }; +static const symbol s_2_1831[6] = { 'r', 'a', 'n', 'i', 'j', 'u' }; +static const symbol s_2_1832[6] = { 't', 'a', 'n', 'i', 'j', 'u' }; +static const symbol s_2_1833[4] = { 'p', 'i', 'j', 'u' }; +static const symbol s_2_1834[4] = { 'r', 'i', 'j', 'u' }; +static const symbol s_2_1835[6] = { 'r', 'a', 'r', 'i', 'j', 'u' }; +static const symbol s_2_1836[4] = { 's', 'i', 'j', 'u' }; +static const symbol s_2_1837[5] = { 'o', 's', 'i', 'j', 'u' }; +static const symbol s_2_1838[4] = { 't', 'i', 'j', 'u' }; +static const symbol s_2_1839[5] = { 'a', 't', 'i', 'j', 'u' }; +static const symbol s_2_1840[5] = { 'o', 't', 'i', 'j', 'u' }; +static const symbol s_2_1841[5] = { 'a', 'v', 'i', 'j', 'u' }; +static const symbol s_2_1842[5] = { 'e', 'v', 'i', 'j', 'u' }; +static const symbol s_2_1843[5] = { 'i', 'v', 'i', 'j', 'u' }; +static const symbol s_2_1844[5] = { 'o', 'v', 'i', 'j', 'u' }; +static const symbol s_2_1845[4] = { 'z', 'i', 'j', 'u' }; +static const symbol s_2_1846[6] = { 'o', 0xC5, 0xA1, 'i', 'j', 'u' }; +static const symbol s_2_1847[5] = { 0xC5, 0xBE, 'i', 'j', 'u' }; +static const symbol s_2_1848[4] = { 'a', 'n', 'j', 'u' }; +static const symbol s_2_1849[4] = { 'e', 'n', 'j', 'u' }; +static const symbol s_2_1850[4] = { 's', 'n', 'j', 'u' }; +static const symbol s_2_1851[5] = { 0xC5, 0xA1, 'n', 'j', 'u' }; +static const symbol s_2_1852[3] = { 'u', 'j', 'u' }; +static const symbol s_2_1853[6] = { 'l', 'u', 'c', 'u', 'j', 'u' }; +static const symbol s_2_1854[5] = { 'i', 'r', 'u', 'j', 'u' }; +static const symbol s_2_1855[7] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'u' }; +static const symbol s_2_1856[2] = { 'k', 'u' }; +static const symbol s_2_1857[3] = { 's', 'k', 'u' }; +static const symbol s_2_1858[4] = { 0xC5, 0xA1, 'k', 'u' }; +static const symbol s_2_1859[3] = { 'a', 'l', 'u' }; +static const symbol s_2_1860[5] = { 'i', 'j', 'a', 'l', 'u' }; +static const symbol s_2_1861[4] = { 'n', 'a', 'l', 'u' }; +static const symbol s_2_1862[3] = { 'e', 'l', 'u' }; +static const symbol s_2_1863[3] = { 'i', 'l', 'u' }; +static const symbol s_2_1864[5] = { 'o', 'z', 'i', 'l', 'u' }; +static const symbol s_2_1865[3] = { 'o', 'l', 'u' }; +static const symbol s_2_1866[4] = { 'r', 'a', 'm', 'u' }; +static const symbol s_2_1867[5] = { 'a', 'c', 'e', 'm', 'u' }; +static const symbol s_2_1868[5] = { 'e', 'c', 'e', 'm', 'u' }; +static const symbol s_2_1869[5] = { 'u', 'c', 'e', 'm', 'u' }; +static const symbol s_2_1870[8] = { 'a', 'n', 'j', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1871[8] = { 'e', 'n', 'j', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1872[8] = { 's', 'n', 'j', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1873[9] = { 0xC5, 0xA1, 'n', 'j', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1874[6] = { 'k', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1875[7] = { 's', 'k', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1876[8] = { 0xC5, 0xA1, 'k', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1877[7] = { 'e', 'l', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1878[6] = { 'n', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1879[7] = { 'o', 's', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1880[7] = { 'a', 't', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1881[9] = { 'e', 'v', 'i', 't', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1882[9] = { 'o', 'v', 'i', 't', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1883[8] = { 'a', 's', 't', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1884[7] = { 'a', 'v', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1885[7] = { 'e', 'v', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1886[7] = { 'i', 'v', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1887[7] = { 'o', 'v', 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1888[8] = { 'o', 0xC5, 0xA1, 'i', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1889[6] = { 'a', 'n', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1890[6] = { 'e', 'n', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1891[6] = { 's', 'n', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1892[7] = { 0xC5, 0xA1, 'n', 'j', 'e', 'm', 'u' }; +static const symbol s_2_1893[4] = { 'k', 'e', 'm', 'u' }; +static const symbol s_2_1894[5] = { 's', 'k', 'e', 'm', 'u' }; +static const symbol s_2_1895[6] = { 0xC5, 0xA1, 'k', 'e', 'm', 'u' }; +static const symbol s_2_1896[4] = { 'l', 'e', 'm', 'u' }; +static const symbol s_2_1897[5] = { 'e', 'l', 'e', 'm', 'u' }; +static const symbol s_2_1898[4] = { 'n', 'e', 'm', 'u' }; +static const symbol s_2_1899[5] = { 'a', 'n', 'e', 'm', 'u' }; +static const symbol s_2_1900[5] = { 'e', 'n', 'e', 'm', 'u' }; +static const symbol s_2_1901[5] = { 's', 'n', 'e', 'm', 'u' }; +static const symbol s_2_1902[6] = { 0xC5, 0xA1, 'n', 'e', 'm', 'u' }; +static const symbol s_2_1903[5] = { 'o', 's', 'e', 'm', 'u' }; +static const symbol s_2_1904[5] = { 'a', 't', 'e', 'm', 'u' }; +static const symbol s_2_1905[7] = { 'e', 'v', 'i', 't', 'e', 'm', 'u' }; +static const symbol s_2_1906[7] = { 'o', 'v', 'i', 't', 'e', 'm', 'u' }; +static const symbol s_2_1907[6] = { 'a', 's', 't', 'e', 'm', 'u' }; +static const symbol s_2_1908[5] = { 'a', 'v', 'e', 'm', 'u' }; +static const symbol s_2_1909[5] = { 'e', 'v', 'e', 'm', 'u' }; +static const symbol s_2_1910[5] = { 'i', 'v', 'e', 'm', 'u' }; +static const symbol s_2_1911[5] = { 'o', 'v', 'e', 'm', 'u' }; +static const symbol s_2_1912[6] = { 'a', 0xC4, 0x87, 'e', 'm', 'u' }; +static const symbol s_2_1913[6] = { 'e', 0xC4, 0x87, 'e', 'm', 'u' }; +static const symbol s_2_1914[6] = { 'u', 0xC4, 0x87, 'e', 'm', 'u' }; +static const symbol s_2_1915[6] = { 'o', 0xC5, 0xA1, 'e', 'm', 'u' }; +static const symbol s_2_1916[5] = { 'a', 'c', 'o', 'm', 'u' }; +static const symbol s_2_1917[5] = { 'e', 'c', 'o', 'm', 'u' }; +static const symbol s_2_1918[5] = { 'u', 'c', 'o', 'm', 'u' }; +static const symbol s_2_1919[6] = { 'a', 'n', 'j', 'o', 'm', 'u' }; +static const symbol s_2_1920[6] = { 'e', 'n', 'j', 'o', 'm', 'u' }; +static const symbol s_2_1921[6] = { 's', 'n', 'j', 'o', 'm', 'u' }; +static const symbol s_2_1922[7] = { 0xC5, 0xA1, 'n', 'j', 'o', 'm', 'u' }; +static const symbol s_2_1923[4] = { 'k', 'o', 'm', 'u' }; +static const symbol s_2_1924[5] = { 's', 'k', 'o', 'm', 'u' }; +static const symbol s_2_1925[6] = { 0xC5, 0xA1, 'k', 'o', 'm', 'u' }; +static const symbol s_2_1926[5] = { 'e', 'l', 'o', 'm', 'u' }; +static const symbol s_2_1927[4] = { 'n', 'o', 'm', 'u' }; +static const symbol s_2_1928[6] = { 'c', 'i', 'n', 'o', 'm', 'u' }; +static const symbol s_2_1929[7] = { 0xC4, 0x8D, 'i', 'n', 'o', 'm', 'u' }; +static const symbol s_2_1930[5] = { 'o', 's', 'o', 'm', 'u' }; +static const symbol s_2_1931[5] = { 'a', 't', 'o', 'm', 'u' }; +static const symbol s_2_1932[7] = { 'e', 'v', 'i', 't', 'o', 'm', 'u' }; +static const symbol s_2_1933[7] = { 'o', 'v', 'i', 't', 'o', 'm', 'u' }; +static const symbol s_2_1934[6] = { 'a', 's', 't', 'o', 'm', 'u' }; +static const symbol s_2_1935[5] = { 'a', 'v', 'o', 'm', 'u' }; +static const symbol s_2_1936[5] = { 'e', 'v', 'o', 'm', 'u' }; +static const symbol s_2_1937[5] = { 'i', 'v', 'o', 'm', 'u' }; +static const symbol s_2_1938[5] = { 'o', 'v', 'o', 'm', 'u' }; +static const symbol s_2_1939[6] = { 'a', 0xC4, 0x87, 'o', 'm', 'u' }; +static const symbol s_2_1940[6] = { 'e', 0xC4, 0x87, 'o', 'm', 'u' }; +static const symbol s_2_1941[6] = { 'u', 0xC4, 0x87, 'o', 'm', 'u' }; +static const symbol s_2_1942[6] = { 'o', 0xC5, 0xA1, 'o', 'm', 'u' }; +static const symbol s_2_1943[2] = { 'n', 'u' }; +static const symbol s_2_1944[3] = { 'a', 'n', 'u' }; +static const symbol s_2_1945[6] = { 'a', 's', 't', 'a', 'n', 'u' }; +static const symbol s_2_1946[6] = { 'i', 's', 't', 'a', 'n', 'u' }; +static const symbol s_2_1947[6] = { 'o', 's', 't', 'a', 'n', 'u' }; +static const symbol s_2_1948[3] = { 'i', 'n', 'u' }; +static const symbol s_2_1949[4] = { 'c', 'i', 'n', 'u' }; +static const symbol s_2_1950[5] = { 'a', 'n', 'i', 'n', 'u' }; +static const symbol s_2_1951[5] = { 0xC4, 0x8D, 'i', 'n', 'u' }; +static const symbol s_2_1952[3] = { 'o', 'n', 'u' }; +static const symbol s_2_1953[3] = { 'a', 'r', 'u' }; +static const symbol s_2_1954[3] = { 'd', 'r', 'u' }; +static const symbol s_2_1955[3] = { 'e', 'r', 'u' }; +static const symbol s_2_1956[3] = { 'o', 'r', 'u' }; +static const symbol s_2_1957[4] = { 'b', 'a', 's', 'u' }; +static const symbol s_2_1958[4] = { 'g', 'a', 's', 'u' }; +static const symbol s_2_1959[4] = { 'j', 'a', 's', 'u' }; +static const symbol s_2_1960[4] = { 'k', 'a', 's', 'u' }; +static const symbol s_2_1961[4] = { 'n', 'a', 's', 'u' }; +static const symbol s_2_1962[4] = { 't', 'a', 's', 'u' }; +static const symbol s_2_1963[4] = { 'v', 'a', 's', 'u' }; +static const symbol s_2_1964[3] = { 'e', 's', 'u' }; +static const symbol s_2_1965[3] = { 'i', 's', 'u' }; +static const symbol s_2_1966[3] = { 'o', 's', 'u' }; +static const symbol s_2_1967[3] = { 'a', 't', 'u' }; +static const symbol s_2_1968[5] = { 'i', 'k', 'a', 't', 'u' }; +static const symbol s_2_1969[4] = { 'l', 'a', 't', 'u' }; +static const symbol s_2_1970[3] = { 'e', 't', 'u' }; +static const symbol s_2_1971[5] = { 'e', 'v', 'i', 't', 'u' }; +static const symbol s_2_1972[5] = { 'o', 'v', 'i', 't', 'u' }; +static const symbol s_2_1973[4] = { 'a', 's', 't', 'u' }; +static const symbol s_2_1974[4] = { 'e', 's', 't', 'u' }; +static const symbol s_2_1975[4] = { 'i', 's', 't', 'u' }; +static const symbol s_2_1976[4] = { 'k', 's', 't', 'u' }; +static const symbol s_2_1977[4] = { 'o', 's', 't', 'u' }; +static const symbol s_2_1978[5] = { 'i', 0xC5, 0xA1, 't', 'u' }; +static const symbol s_2_1979[3] = { 'a', 'v', 'u' }; +static const symbol s_2_1980[3] = { 'e', 'v', 'u' }; +static const symbol s_2_1981[3] = { 'i', 'v', 'u' }; +static const symbol s_2_1982[3] = { 'o', 'v', 'u' }; +static const symbol s_2_1983[4] = { 'l', 'o', 'v', 'u' }; +static const symbol s_2_1984[4] = { 'm', 'o', 'v', 'u' }; +static const symbol s_2_1985[4] = { 's', 't', 'v', 'u' }; +static const symbol s_2_1986[5] = { 0xC5, 0xA1, 't', 'v', 'u' }; +static const symbol s_2_1987[5] = { 'b', 'a', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1988[5] = { 'g', 'a', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1989[5] = { 'j', 'a', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1990[5] = { 'k', 'a', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1991[5] = { 'n', 'a', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1992[5] = { 't', 'a', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1993[5] = { 'v', 'a', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1994[4] = { 'e', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1995[4] = { 'i', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1996[4] = { 'o', 0xC5, 0xA1, 'u' }; +static const symbol s_2_1997[4] = { 'a', 'v', 'a', 'v' }; +static const symbol s_2_1998[4] = { 'e', 'v', 'a', 'v' }; +static const symbol s_2_1999[4] = { 'i', 'v', 'a', 'v' }; +static const symbol s_2_2000[4] = { 'u', 'v', 'a', 'v' }; +static const symbol s_2_2001[3] = { 'k', 'o', 'v' }; +static const symbol s_2_2002[3] = { 'a', 0xC5, 0xA1 }; +static const symbol s_2_2003[5] = { 'i', 'r', 'a', 0xC5, 0xA1 }; +static const symbol s_2_2004[5] = { 'u', 'r', 'a', 0xC5, 0xA1 }; +static const symbol s_2_2005[4] = { 't', 'a', 0xC5, 0xA1 }; +static const symbol s_2_2006[5] = { 'a', 'v', 'a', 0xC5, 0xA1 }; +static const symbol s_2_2007[5] = { 'e', 'v', 'a', 0xC5, 0xA1 }; +static const symbol s_2_2008[5] = { 'i', 'v', 'a', 0xC5, 0xA1 }; +static const symbol s_2_2009[5] = { 'u', 'v', 'a', 0xC5, 0xA1 }; +static const symbol s_2_2010[6] = { 'a', 0xC4, 0x8D, 'a', 0xC5, 0xA1 }; +static const symbol s_2_2011[3] = { 'e', 0xC5, 0xA1 }; +static const symbol s_2_2012[8] = { 'a', 's', 't', 'a', 'd', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2013[8] = { 'i', 's', 't', 'a', 'd', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2014[8] = { 'o', 's', 't', 'a', 'd', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2015[8] = { 'a', 's', 't', 'a', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2016[8] = { 'i', 's', 't', 'a', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2017[8] = { 'o', 's', 't', 'a', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2018[5] = { 'i', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2019[6] = { 'i', 'n', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2020[5] = { 'u', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2021[7] = { 'i', 'r', 'u', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2022[9] = { 'l', 'u', 0xC4, 0x8D, 'u', 'j', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2023[4] = { 'n', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2024[8] = { 'a', 's', 't', 'a', 'n', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2025[8] = { 'i', 's', 't', 'a', 'n', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2026[8] = { 'o', 's', 't', 'a', 'n', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2027[5] = { 'e', 't', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2028[6] = { 'a', 's', 't', 'e', 0xC5, 0xA1 }; +static const symbol s_2_2029[3] = { 'i', 0xC5, 0xA1 }; +static const symbol s_2_2030[4] = { 'n', 'i', 0xC5, 0xA1 }; +static const symbol s_2_2031[6] = { 'j', 'e', 't', 'i', 0xC5, 0xA1 }; +static const symbol s_2_2032[6] = { 'a', 0xC4, 0x8D, 'i', 0xC5, 0xA1 }; +static const symbol s_2_2033[7] = { 'l', 'u', 0xC4, 0x8D, 'i', 0xC5, 0xA1 }; +static const symbol s_2_2034[7] = { 'r', 'o', 0xC5, 0xA1, 'i', 0xC5, 0xA1 }; + +static const struct among a_2[2035] = +{ +{ 3, s_2_0, -1, 124, 0}, +{ 3, s_2_1, -1, 125, 0}, +{ 3, s_2_2, -1, 126, 0}, +{ 2, s_2_3, -1, 20, 0}, +{ 5, s_2_4, 3, 124, 0}, +{ 5, s_2_5, 3, 125, 0}, +{ 5, s_2_6, 3, 126, 0}, +{ 8, s_2_7, 3, 84, 0}, +{ 8, s_2_8, 3, 85, 0}, +{ 8, s_2_9, 3, 122, 0}, +{ 9, s_2_10, 3, 86, 0}, +{ 6, s_2_11, 3, 95, 0}, +{ 7, s_2_12, 11, 1, 0}, +{ 8, s_2_13, 11, 2, 0}, +{ 7, s_2_14, 3, 83, 0}, +{ 6, s_2_15, 3, 13, 0}, +{ 7, s_2_16, 3, 123, 0}, +{ 7, s_2_17, 3, 120, 0}, +{ 9, s_2_18, 3, 92, 0}, +{ 9, s_2_19, 3, 93, 0}, +{ 8, s_2_20, 3, 94, 0}, +{ 7, s_2_21, 3, 77, 0}, +{ 7, s_2_22, 3, 78, 0}, +{ 7, s_2_23, 3, 79, 0}, +{ 7, s_2_24, 3, 80, 0}, +{ 8, s_2_25, 3, 91, 0}, +{ 6, s_2_26, 3, 84, 0}, +{ 6, s_2_27, 3, 85, 0}, +{ 6, s_2_28, 3, 122, 0}, +{ 7, s_2_29, 3, 86, 0}, +{ 4, s_2_30, 3, 95, 0}, +{ 5, s_2_31, 30, 1, 0}, +{ 6, s_2_32, 30, 2, 0}, +{ 5, s_2_33, 3, 83, 0}, +{ 4, s_2_34, 3, 13, 0}, +{ 5, s_2_35, 34, 10, 0}, +{ 5, s_2_36, 34, 87, 0}, +{ 5, s_2_37, 34, 159, 0}, +{ 6, s_2_38, 34, 88, 0}, +{ 5, s_2_39, 3, 123, 0}, +{ 5, s_2_40, 3, 120, 0}, +{ 7, s_2_41, 3, 92, 0}, +{ 7, s_2_42, 3, 93, 0}, +{ 6, s_2_43, 3, 94, 0}, +{ 5, s_2_44, 3, 77, 0}, +{ 5, s_2_45, 3, 78, 0}, +{ 5, s_2_46, 3, 79, 0}, +{ 5, s_2_47, 3, 80, 0}, +{ 6, s_2_48, 3, 14, 0}, +{ 6, s_2_49, 3, 15, 0}, +{ 6, s_2_50, 3, 16, 0}, +{ 6, s_2_51, 3, 91, 0}, +{ 5, s_2_52, 3, 124, 0}, +{ 5, s_2_53, 3, 125, 0}, +{ 5, s_2_54, 3, 126, 0}, +{ 6, s_2_55, 3, 84, 0}, +{ 6, s_2_56, 3, 85, 0}, +{ 6, s_2_57, 3, 122, 0}, +{ 7, s_2_58, 3, 86, 0}, +{ 4, s_2_59, 3, 95, 0}, +{ 5, s_2_60, 59, 1, 0}, +{ 6, s_2_61, 59, 2, 0}, +{ 4, s_2_62, 3, 19, 0}, +{ 5, s_2_63, 62, 83, 0}, +{ 4, s_2_64, 3, 13, 0}, +{ 6, s_2_65, 64, 137, 0}, +{ 7, s_2_66, 64, 89, 0}, +{ 5, s_2_67, 3, 123, 0}, +{ 5, s_2_68, 3, 120, 0}, +{ 7, s_2_69, 3, 92, 0}, +{ 7, s_2_70, 3, 93, 0}, +{ 6, s_2_71, 3, 94, 0}, +{ 5, s_2_72, 3, 77, 0}, +{ 5, s_2_73, 3, 78, 0}, +{ 5, s_2_74, 3, 79, 0}, +{ 5, s_2_75, 3, 80, 0}, +{ 6, s_2_76, 3, 14, 0}, +{ 6, s_2_77, 3, 15, 0}, +{ 6, s_2_78, 3, 16, 0}, +{ 6, s_2_79, 3, 91, 0}, +{ 3, s_2_80, 3, 18, 0}, +{ 3, s_2_81, -1, 109, 0}, +{ 4, s_2_82, 81, 26, 0}, +{ 4, s_2_83, 81, 30, 0}, +{ 4, s_2_84, 81, 31, 0}, +{ 5, s_2_85, 81, 28, 0}, +{ 5, s_2_86, 81, 27, 0}, +{ 5, s_2_87, 81, 29, 0}, +{ 4, s_2_88, -1, 32, 0}, +{ 4, s_2_89, -1, 33, 0}, +{ 4, s_2_90, -1, 34, 0}, +{ 4, s_2_91, -1, 40, 0}, +{ 4, s_2_92, -1, 39, 0}, +{ 6, s_2_93, -1, 84, 0}, +{ 6, s_2_94, -1, 85, 0}, +{ 6, s_2_95, -1, 122, 0}, +{ 7, s_2_96, -1, 86, 0}, +{ 4, s_2_97, -1, 95, 0}, +{ 5, s_2_98, 97, 1, 0}, +{ 6, s_2_99, 97, 2, 0}, +{ 4, s_2_100, -1, 24, 0}, +{ 5, s_2_101, 100, 83, 0}, +{ 4, s_2_102, -1, 37, 0}, +{ 4, s_2_103, -1, 13, 0}, +{ 6, s_2_104, 103, 9, 0}, +{ 6, s_2_105, 103, 6, 0}, +{ 6, s_2_106, 103, 7, 0}, +{ 6, s_2_107, 103, 8, 0}, +{ 6, s_2_108, 103, 5, 0}, +{ 4, s_2_109, -1, 41, 0}, +{ 4, s_2_110, -1, 42, 0}, +{ 6, s_2_111, 110, 21, 0}, +{ 4, s_2_112, -1, 23, 0}, +{ 5, s_2_113, 112, 123, 0}, +{ 4, s_2_114, -1, 44, 0}, +{ 5, s_2_115, 114, 120, 0}, +{ 7, s_2_116, 114, 92, 0}, +{ 7, s_2_117, 114, 93, 0}, +{ 5, s_2_118, 114, 22, 0}, +{ 6, s_2_119, 114, 94, 0}, +{ 5, s_2_120, -1, 77, 0}, +{ 5, s_2_121, -1, 78, 0}, +{ 5, s_2_122, -1, 79, 0}, +{ 5, s_2_123, -1, 80, 0}, +{ 4, s_2_124, -1, 45, 0}, +{ 6, s_2_125, -1, 91, 0}, +{ 5, s_2_126, -1, 38, 0}, +{ 4, s_2_127, -1, 84, 0}, +{ 4, s_2_128, -1, 85, 0}, +{ 4, s_2_129, -1, 122, 0}, +{ 5, s_2_130, -1, 86, 0}, +{ 2, s_2_131, -1, 95, 0}, +{ 3, s_2_132, 131, 1, 0}, +{ 4, s_2_133, 131, 2, 0}, +{ 3, s_2_134, -1, 104, 0}, +{ 5, s_2_135, 134, 128, 0}, +{ 8, s_2_136, 134, 106, 0}, +{ 8, s_2_137, 134, 107, 0}, +{ 8, s_2_138, 134, 108, 0}, +{ 5, s_2_139, 134, 47, 0}, +{ 6, s_2_140, 134, 114, 0}, +{ 4, s_2_141, 134, 46, 0}, +{ 5, s_2_142, 134, 100, 0}, +{ 5, s_2_143, 134, 105, 0}, +{ 4, s_2_144, 134, 113, 0}, +{ 6, s_2_145, 144, 110, 0}, +{ 6, s_2_146, 144, 111, 0}, +{ 6, s_2_147, 144, 112, 0}, +{ 5, s_2_148, 134, 97, 0}, +{ 5, s_2_149, 134, 96, 0}, +{ 5, s_2_150, 134, 98, 0}, +{ 5, s_2_151, 134, 76, 0}, +{ 5, s_2_152, 134, 99, 0}, +{ 6, s_2_153, 134, 102, 0}, +{ 3, s_2_154, -1, 83, 0}, +{ 3, s_2_155, -1, 116, 0}, +{ 5, s_2_156, 155, 124, 0}, +{ 6, s_2_157, 155, 121, 0}, +{ 4, s_2_158, 155, 103, 0}, +{ 8, s_2_159, 158, 110, 0}, +{ 8, s_2_160, 158, 111, 0}, +{ 8, s_2_161, 158, 112, 0}, +{ 6, s_2_162, 155, 127, 0}, +{ 6, s_2_163, 155, 118, 0}, +{ 5, s_2_164, 155, 48, 0}, +{ 6, s_2_165, 155, 101, 0}, +{ 7, s_2_166, 155, 117, 0}, +{ 7, s_2_167, 155, 90, 0}, +{ 3, s_2_168, -1, 50, 0}, +{ 4, s_2_169, -1, 115, 0}, +{ 4, s_2_170, -1, 13, 0}, +{ 4, s_2_171, -1, 20, 0}, +{ 6, s_2_172, 171, 19, 0}, +{ 5, s_2_173, 171, 18, 0}, +{ 5, s_2_174, -1, 109, 0}, +{ 6, s_2_175, 174, 26, 0}, +{ 6, s_2_176, 174, 30, 0}, +{ 6, s_2_177, 174, 31, 0}, +{ 7, s_2_178, 174, 28, 0}, +{ 7, s_2_179, 174, 27, 0}, +{ 7, s_2_180, 174, 29, 0}, +{ 6, s_2_181, -1, 32, 0}, +{ 6, s_2_182, -1, 33, 0}, +{ 6, s_2_183, -1, 34, 0}, +{ 6, s_2_184, -1, 40, 0}, +{ 6, s_2_185, -1, 39, 0}, +{ 6, s_2_186, -1, 35, 0}, +{ 6, s_2_187, -1, 37, 0}, +{ 6, s_2_188, -1, 36, 0}, +{ 8, s_2_189, 188, 9, 0}, +{ 8, s_2_190, 188, 6, 0}, +{ 8, s_2_191, 188, 7, 0}, +{ 8, s_2_192, 188, 8, 0}, +{ 8, s_2_193, 188, 5, 0}, +{ 6, s_2_194, -1, 41, 0}, +{ 6, s_2_195, -1, 42, 0}, +{ 6, s_2_196, -1, 43, 0}, +{ 6, s_2_197, -1, 44, 0}, +{ 6, s_2_198, -1, 45, 0}, +{ 7, s_2_199, -1, 38, 0}, +{ 5, s_2_200, -1, 104, 0}, +{ 7, s_2_201, 200, 47, 0}, +{ 6, s_2_202, 200, 46, 0}, +{ 5, s_2_203, -1, 119, 0}, +{ 5, s_2_204, -1, 116, 0}, +{ 6, s_2_205, -1, 52, 0}, +{ 6, s_2_206, -1, 51, 0}, +{ 5, s_2_207, -1, 11, 0}, +{ 6, s_2_208, 207, 137, 0}, +{ 7, s_2_209, 207, 89, 0}, +{ 4, s_2_210, -1, 52, 0}, +{ 5, s_2_211, 210, 53, 0}, +{ 5, s_2_212, 210, 54, 0}, +{ 5, s_2_213, 210, 55, 0}, +{ 5, s_2_214, 210, 56, 0}, +{ 6, s_2_215, -1, 135, 0}, +{ 6, s_2_216, -1, 131, 0}, +{ 6, s_2_217, -1, 129, 0}, +{ 6, s_2_218, -1, 133, 0}, +{ 6, s_2_219, -1, 132, 0}, +{ 6, s_2_220, -1, 130, 0}, +{ 6, s_2_221, -1, 134, 0}, +{ 5, s_2_222, -1, 152, 0}, +{ 5, s_2_223, -1, 154, 0}, +{ 5, s_2_224, -1, 70, 0}, +{ 6, s_2_225, -1, 71, 0}, +{ 6, s_2_226, -1, 72, 0}, +{ 6, s_2_227, -1, 73, 0}, +{ 6, s_2_228, -1, 74, 0}, +{ 5, s_2_229, -1, 77, 0}, +{ 5, s_2_230, -1, 78, 0}, +{ 5, s_2_231, -1, 79, 0}, +{ 7, s_2_232, -1, 63, 0}, +{ 7, s_2_233, -1, 64, 0}, +{ 7, s_2_234, -1, 61, 0}, +{ 7, s_2_235, -1, 62, 0}, +{ 7, s_2_236, -1, 60, 0}, +{ 7, s_2_237, -1, 59, 0}, +{ 7, s_2_238, -1, 65, 0}, +{ 6, s_2_239, -1, 66, 0}, +{ 6, s_2_240, -1, 67, 0}, +{ 4, s_2_241, -1, 51, 0}, +{ 5, s_2_242, -1, 124, 0}, +{ 5, s_2_243, -1, 125, 0}, +{ 5, s_2_244, -1, 126, 0}, +{ 5, s_2_245, -1, 109, 0}, +{ 6, s_2_246, 245, 26, 0}, +{ 6, s_2_247, 245, 30, 0}, +{ 6, s_2_248, 245, 31, 0}, +{ 7, s_2_249, 245, 28, 0}, +{ 7, s_2_250, 245, 27, 0}, +{ 7, s_2_251, 245, 29, 0}, +{ 6, s_2_252, -1, 32, 0}, +{ 6, s_2_253, -1, 33, 0}, +{ 6, s_2_254, -1, 34, 0}, +{ 6, s_2_255, -1, 40, 0}, +{ 6, s_2_256, -1, 39, 0}, +{ 8, s_2_257, -1, 84, 0}, +{ 8, s_2_258, -1, 85, 0}, +{ 8, s_2_259, -1, 122, 0}, +{ 9, s_2_260, -1, 86, 0}, +{ 6, s_2_261, -1, 95, 0}, +{ 7, s_2_262, 261, 1, 0}, +{ 8, s_2_263, 261, 2, 0}, +{ 6, s_2_264, -1, 35, 0}, +{ 7, s_2_265, 264, 83, 0}, +{ 6, s_2_266, -1, 37, 0}, +{ 6, s_2_267, -1, 13, 0}, +{ 8, s_2_268, 267, 9, 0}, +{ 8, s_2_269, 267, 6, 0}, +{ 8, s_2_270, 267, 7, 0}, +{ 8, s_2_271, 267, 8, 0}, +{ 8, s_2_272, 267, 5, 0}, +{ 6, s_2_273, -1, 41, 0}, +{ 6, s_2_274, -1, 42, 0}, +{ 6, s_2_275, -1, 43, 0}, +{ 7, s_2_276, 275, 123, 0}, +{ 6, s_2_277, -1, 44, 0}, +{ 7, s_2_278, 277, 120, 0}, +{ 9, s_2_279, 277, 92, 0}, +{ 9, s_2_280, 277, 93, 0}, +{ 8, s_2_281, 277, 94, 0}, +{ 7, s_2_282, -1, 77, 0}, +{ 7, s_2_283, -1, 78, 0}, +{ 7, s_2_284, -1, 79, 0}, +{ 7, s_2_285, -1, 80, 0}, +{ 6, s_2_286, -1, 45, 0}, +{ 8, s_2_287, -1, 91, 0}, +{ 7, s_2_288, -1, 38, 0}, +{ 6, s_2_289, -1, 84, 0}, +{ 6, s_2_290, -1, 85, 0}, +{ 6, s_2_291, -1, 122, 0}, +{ 7, s_2_292, -1, 86, 0}, +{ 4, s_2_293, -1, 95, 0}, +{ 5, s_2_294, 293, 1, 0}, +{ 6, s_2_295, 293, 2, 0}, +{ 5, s_2_296, -1, 104, 0}, +{ 7, s_2_297, 296, 47, 0}, +{ 6, s_2_298, 296, 46, 0}, +{ 5, s_2_299, -1, 83, 0}, +{ 5, s_2_300, -1, 116, 0}, +{ 7, s_2_301, 300, 48, 0}, +{ 5, s_2_302, -1, 50, 0}, +{ 6, s_2_303, -1, 51, 0}, +{ 4, s_2_304, -1, 13, 0}, +{ 5, s_2_305, 304, 10, 0}, +{ 5, s_2_306, 304, 11, 0}, +{ 6, s_2_307, 306, 137, 0}, +{ 7, s_2_308, 306, 89, 0}, +{ 5, s_2_309, 304, 12, 0}, +{ 5, s_2_310, -1, 53, 0}, +{ 5, s_2_311, -1, 54, 0}, +{ 5, s_2_312, -1, 55, 0}, +{ 5, s_2_313, -1, 56, 0}, +{ 6, s_2_314, -1, 135, 0}, +{ 6, s_2_315, -1, 131, 0}, +{ 6, s_2_316, -1, 129, 0}, +{ 6, s_2_317, -1, 133, 0}, +{ 6, s_2_318, -1, 132, 0}, +{ 6, s_2_319, -1, 130, 0}, +{ 6, s_2_320, -1, 134, 0}, +{ 5, s_2_321, -1, 57, 0}, +{ 5, s_2_322, -1, 58, 0}, +{ 5, s_2_323, -1, 123, 0}, +{ 5, s_2_324, -1, 120, 0}, +{ 7, s_2_325, 324, 68, 0}, +{ 6, s_2_326, 324, 69, 0}, +{ 5, s_2_327, -1, 70, 0}, +{ 7, s_2_328, -1, 92, 0}, +{ 7, s_2_329, -1, 93, 0}, +{ 6, s_2_330, -1, 94, 0}, +{ 6, s_2_331, -1, 71, 0}, +{ 6, s_2_332, -1, 72, 0}, +{ 6, s_2_333, -1, 73, 0}, +{ 6, s_2_334, -1, 74, 0}, +{ 7, s_2_335, -1, 75, 0}, +{ 5, s_2_336, -1, 77, 0}, +{ 5, s_2_337, -1, 78, 0}, +{ 7, s_2_338, 337, 109, 0}, +{ 8, s_2_339, 338, 26, 0}, +{ 8, s_2_340, 338, 30, 0}, +{ 8, s_2_341, 338, 31, 0}, +{ 9, s_2_342, 338, 28, 0}, +{ 9, s_2_343, 338, 27, 0}, +{ 9, s_2_344, 338, 29, 0}, +{ 5, s_2_345, -1, 79, 0}, +{ 5, s_2_346, -1, 80, 0}, +{ 6, s_2_347, 346, 20, 0}, +{ 7, s_2_348, 347, 17, 0}, +{ 6, s_2_349, 346, 82, 0}, +{ 7, s_2_350, 349, 49, 0}, +{ 6, s_2_351, 346, 81, 0}, +{ 7, s_2_352, 346, 12, 0}, +{ 6, s_2_353, -1, 3, 0}, +{ 7, s_2_354, -1, 4, 0}, +{ 6, s_2_355, -1, 14, 0}, +{ 6, s_2_356, -1, 15, 0}, +{ 6, s_2_357, -1, 16, 0}, +{ 7, s_2_358, -1, 63, 0}, +{ 7, s_2_359, -1, 64, 0}, +{ 7, s_2_360, -1, 61, 0}, +{ 7, s_2_361, -1, 62, 0}, +{ 7, s_2_362, -1, 60, 0}, +{ 7, s_2_363, -1, 59, 0}, +{ 7, s_2_364, -1, 65, 0}, +{ 6, s_2_365, -1, 66, 0}, +{ 6, s_2_366, -1, 67, 0}, +{ 6, s_2_367, -1, 91, 0}, +{ 2, s_2_368, -1, 13, 0}, +{ 3, s_2_369, 368, 10, 0}, +{ 5, s_2_370, 369, 128, 0}, +{ 5, s_2_371, 369, 105, 0}, +{ 4, s_2_372, 369, 113, 0}, +{ 5, s_2_373, 369, 97, 0}, +{ 5, s_2_374, 369, 96, 0}, +{ 5, s_2_375, 369, 98, 0}, +{ 5, s_2_376, 369, 99, 0}, +{ 6, s_2_377, 369, 102, 0}, +{ 5, s_2_378, 368, 124, 0}, +{ 6, s_2_379, 368, 121, 0}, +{ 6, s_2_380, 368, 101, 0}, +{ 7, s_2_381, 368, 117, 0}, +{ 3, s_2_382, 368, 11, 0}, +{ 4, s_2_383, 382, 137, 0}, +{ 5, s_2_384, 382, 10, 0}, +{ 5, s_2_385, 382, 89, 0}, +{ 3, s_2_386, 368, 12, 0}, +{ 3, s_2_387, -1, 53, 0}, +{ 3, s_2_388, -1, 54, 0}, +{ 3, s_2_389, -1, 55, 0}, +{ 3, s_2_390, -1, 56, 0}, +{ 4, s_2_391, -1, 135, 0}, +{ 4, s_2_392, -1, 131, 0}, +{ 4, s_2_393, -1, 129, 0}, +{ 4, s_2_394, -1, 133, 0}, +{ 4, s_2_395, -1, 132, 0}, +{ 4, s_2_396, -1, 130, 0}, +{ 4, s_2_397, -1, 134, 0}, +{ 3, s_2_398, -1, 57, 0}, +{ 3, s_2_399, -1, 58, 0}, +{ 3, s_2_400, -1, 123, 0}, +{ 3, s_2_401, -1, 120, 0}, +{ 5, s_2_402, 401, 68, 0}, +{ 4, s_2_403, 401, 69, 0}, +{ 3, s_2_404, -1, 70, 0}, +{ 5, s_2_405, -1, 92, 0}, +{ 5, s_2_406, -1, 93, 0}, +{ 4, s_2_407, -1, 94, 0}, +{ 4, s_2_408, -1, 71, 0}, +{ 4, s_2_409, -1, 72, 0}, +{ 4, s_2_410, -1, 73, 0}, +{ 4, s_2_411, -1, 74, 0}, +{ 4, s_2_412, -1, 13, 0}, +{ 5, s_2_413, -1, 75, 0}, +{ 3, s_2_414, -1, 77, 0}, +{ 3, s_2_415, -1, 78, 0}, +{ 5, s_2_416, 415, 109, 0}, +{ 6, s_2_417, 416, 26, 0}, +{ 6, s_2_418, 416, 30, 0}, +{ 6, s_2_419, 416, 31, 0}, +{ 7, s_2_420, 416, 28, 0}, +{ 7, s_2_421, 416, 27, 0}, +{ 7, s_2_422, 416, 29, 0}, +{ 3, s_2_423, -1, 79, 0}, +{ 3, s_2_424, -1, 80, 0}, +{ 4, s_2_425, 424, 20, 0}, +{ 5, s_2_426, 425, 17, 0}, +{ 4, s_2_427, 424, 82, 0}, +{ 5, s_2_428, 427, 49, 0}, +{ 4, s_2_429, 424, 81, 0}, +{ 5, s_2_430, 424, 12, 0}, +{ 4, s_2_431, -1, 3, 0}, +{ 5, s_2_432, -1, 4, 0}, +{ 4, s_2_433, -1, 14, 0}, +{ 4, s_2_434, -1, 15, 0}, +{ 4, s_2_435, -1, 16, 0}, +{ 5, s_2_436, -1, 63, 0}, +{ 5, s_2_437, -1, 64, 0}, +{ 5, s_2_438, -1, 61, 0}, +{ 5, s_2_439, -1, 62, 0}, +{ 5, s_2_440, -1, 60, 0}, +{ 5, s_2_441, -1, 59, 0}, +{ 5, s_2_442, -1, 65, 0}, +{ 4, s_2_443, -1, 66, 0}, +{ 4, s_2_444, -1, 67, 0}, +{ 4, s_2_445, -1, 91, 0}, +{ 3, s_2_446, -1, 124, 0}, +{ 3, s_2_447, -1, 125, 0}, +{ 3, s_2_448, -1, 126, 0}, +{ 4, s_2_449, 448, 121, 0}, +{ 6, s_2_450, -1, 110, 0}, +{ 6, s_2_451, -1, 111, 0}, +{ 6, s_2_452, -1, 112, 0}, +{ 2, s_2_453, -1, 20, 0}, +{ 4, s_2_454, 453, 19, 0}, +{ 3, s_2_455, 453, 18, 0}, +{ 3, s_2_456, -1, 104, 0}, +{ 4, s_2_457, 456, 26, 0}, +{ 4, s_2_458, 456, 30, 0}, +{ 4, s_2_459, 456, 31, 0}, +{ 6, s_2_460, 456, 106, 0}, +{ 6, s_2_461, 456, 107, 0}, +{ 6, s_2_462, 456, 108, 0}, +{ 5, s_2_463, 456, 28, 0}, +{ 5, s_2_464, 456, 27, 0}, +{ 5, s_2_465, 456, 29, 0}, +{ 3, s_2_466, -1, 116, 0}, +{ 4, s_2_467, 466, 32, 0}, +{ 4, s_2_468, 466, 33, 0}, +{ 4, s_2_469, 466, 34, 0}, +{ 4, s_2_470, 466, 40, 0}, +{ 4, s_2_471, 466, 39, 0}, +{ 6, s_2_472, 466, 84, 0}, +{ 6, s_2_473, 466, 85, 0}, +{ 6, s_2_474, 466, 122, 0}, +{ 7, s_2_475, 466, 86, 0}, +{ 4, s_2_476, 466, 95, 0}, +{ 5, s_2_477, 476, 1, 0}, +{ 6, s_2_478, 476, 2, 0}, +{ 4, s_2_479, 466, 35, 0}, +{ 5, s_2_480, 479, 83, 0}, +{ 4, s_2_481, 466, 37, 0}, +{ 4, s_2_482, 466, 13, 0}, +{ 6, s_2_483, 482, 9, 0}, +{ 6, s_2_484, 482, 6, 0}, +{ 6, s_2_485, 482, 7, 0}, +{ 6, s_2_486, 482, 8, 0}, +{ 6, s_2_487, 482, 5, 0}, +{ 4, s_2_488, 466, 41, 0}, +{ 4, s_2_489, 466, 42, 0}, +{ 4, s_2_490, 466, 43, 0}, +{ 5, s_2_491, 490, 123, 0}, +{ 4, s_2_492, 466, 44, 0}, +{ 5, s_2_493, 492, 120, 0}, +{ 7, s_2_494, 492, 92, 0}, +{ 7, s_2_495, 492, 93, 0}, +{ 6, s_2_496, 492, 94, 0}, +{ 5, s_2_497, 466, 77, 0}, +{ 5, s_2_498, 466, 78, 0}, +{ 5, s_2_499, 466, 79, 0}, +{ 5, s_2_500, 466, 80, 0}, +{ 4, s_2_501, 466, 45, 0}, +{ 6, s_2_502, 466, 91, 0}, +{ 5, s_2_503, 466, 38, 0}, +{ 4, s_2_504, -1, 84, 0}, +{ 4, s_2_505, -1, 85, 0}, +{ 4, s_2_506, -1, 122, 0}, +{ 5, s_2_507, -1, 86, 0}, +{ 3, s_2_508, -1, 25, 0}, +{ 6, s_2_509, 508, 121, 0}, +{ 5, s_2_510, 508, 100, 0}, +{ 7, s_2_511, 508, 117, 0}, +{ 2, s_2_512, -1, 95, 0}, +{ 3, s_2_513, 512, 1, 0}, +{ 4, s_2_514, 512, 2, 0}, +{ 3, s_2_515, -1, 104, 0}, +{ 5, s_2_516, 515, 128, 0}, +{ 8, s_2_517, 515, 106, 0}, +{ 8, s_2_518, 515, 107, 0}, +{ 8, s_2_519, 515, 108, 0}, +{ 5, s_2_520, 515, 47, 0}, +{ 6, s_2_521, 515, 114, 0}, +{ 4, s_2_522, 515, 46, 0}, +{ 5, s_2_523, 515, 100, 0}, +{ 5, s_2_524, 515, 105, 0}, +{ 4, s_2_525, 515, 113, 0}, +{ 6, s_2_526, 525, 110, 0}, +{ 6, s_2_527, 525, 111, 0}, +{ 6, s_2_528, 525, 112, 0}, +{ 5, s_2_529, 515, 97, 0}, +{ 5, s_2_530, 515, 96, 0}, +{ 5, s_2_531, 515, 98, 0}, +{ 5, s_2_532, 515, 76, 0}, +{ 5, s_2_533, 515, 99, 0}, +{ 6, s_2_534, 515, 102, 0}, +{ 3, s_2_535, -1, 83, 0}, +{ 3, s_2_536, -1, 116, 0}, +{ 5, s_2_537, 536, 124, 0}, +{ 6, s_2_538, 536, 121, 0}, +{ 4, s_2_539, 536, 103, 0}, +{ 6, s_2_540, 536, 127, 0}, +{ 6, s_2_541, 536, 118, 0}, +{ 5, s_2_542, 536, 48, 0}, +{ 6, s_2_543, 536, 101, 0}, +{ 7, s_2_544, 536, 117, 0}, +{ 7, s_2_545, 536, 90, 0}, +{ 3, s_2_546, -1, 50, 0}, +{ 4, s_2_547, -1, 115, 0}, +{ 4, s_2_548, -1, 13, 0}, +{ 4, s_2_549, -1, 52, 0}, +{ 4, s_2_550, -1, 51, 0}, +{ 5, s_2_551, -1, 124, 0}, +{ 5, s_2_552, -1, 125, 0}, +{ 5, s_2_553, -1, 126, 0}, +{ 6, s_2_554, -1, 84, 0}, +{ 6, s_2_555, -1, 85, 0}, +{ 6, s_2_556, -1, 122, 0}, +{ 7, s_2_557, -1, 86, 0}, +{ 4, s_2_558, -1, 95, 0}, +{ 5, s_2_559, 558, 1, 0}, +{ 6, s_2_560, 558, 2, 0}, +{ 5, s_2_561, -1, 83, 0}, +{ 4, s_2_562, -1, 13, 0}, +{ 6, s_2_563, 562, 137, 0}, +{ 7, s_2_564, 562, 89, 0}, +{ 5, s_2_565, -1, 123, 0}, +{ 5, s_2_566, -1, 120, 0}, +{ 7, s_2_567, -1, 92, 0}, +{ 7, s_2_568, -1, 93, 0}, +{ 6, s_2_569, -1, 94, 0}, +{ 5, s_2_570, -1, 77, 0}, +{ 5, s_2_571, -1, 78, 0}, +{ 5, s_2_572, -1, 79, 0}, +{ 5, s_2_573, -1, 80, 0}, +{ 6, s_2_574, -1, 14, 0}, +{ 6, s_2_575, -1, 15, 0}, +{ 6, s_2_576, -1, 16, 0}, +{ 6, s_2_577, -1, 91, 0}, +{ 2, s_2_578, -1, 13, 0}, +{ 3, s_2_579, 578, 10, 0}, +{ 5, s_2_580, 579, 128, 0}, +{ 5, s_2_581, 579, 105, 0}, +{ 4, s_2_582, 579, 113, 0}, +{ 6, s_2_583, 582, 110, 0}, +{ 6, s_2_584, 582, 111, 0}, +{ 6, s_2_585, 582, 112, 0}, +{ 5, s_2_586, 579, 97, 0}, +{ 5, s_2_587, 579, 96, 0}, +{ 5, s_2_588, 579, 98, 0}, +{ 5, s_2_589, 579, 99, 0}, +{ 6, s_2_590, 579, 102, 0}, +{ 5, s_2_591, 578, 124, 0}, +{ 6, s_2_592, 578, 121, 0}, +{ 6, s_2_593, 578, 101, 0}, +{ 7, s_2_594, 578, 117, 0}, +{ 3, s_2_595, 578, 11, 0}, +{ 4, s_2_596, 595, 137, 0}, +{ 5, s_2_597, 595, 10, 0}, +{ 5, s_2_598, 595, 89, 0}, +{ 3, s_2_599, 578, 12, 0}, +{ 3, s_2_600, -1, 53, 0}, +{ 3, s_2_601, -1, 54, 0}, +{ 3, s_2_602, -1, 55, 0}, +{ 3, s_2_603, -1, 56, 0}, +{ 3, s_2_604, -1, 161, 0}, +{ 4, s_2_605, 604, 135, 0}, +{ 5, s_2_606, 604, 128, 0}, +{ 4, s_2_607, 604, 131, 0}, +{ 4, s_2_608, 604, 129, 0}, +{ 8, s_2_609, 608, 138, 0}, +{ 8, s_2_610, 608, 139, 0}, +{ 8, s_2_611, 608, 140, 0}, +{ 6, s_2_612, 608, 150, 0}, +{ 4, s_2_613, 604, 133, 0}, +{ 4, s_2_614, 604, 132, 0}, +{ 5, s_2_615, 604, 155, 0}, +{ 5, s_2_616, 604, 156, 0}, +{ 4, s_2_617, 604, 130, 0}, +{ 4, s_2_618, 604, 134, 0}, +{ 5, s_2_619, 618, 144, 0}, +{ 5, s_2_620, 618, 145, 0}, +{ 5, s_2_621, 618, 146, 0}, +{ 5, s_2_622, 618, 148, 0}, +{ 5, s_2_623, 618, 147, 0}, +{ 3, s_2_624, -1, 57, 0}, +{ 3, s_2_625, -1, 58, 0}, +{ 5, s_2_626, 625, 124, 0}, +{ 6, s_2_627, 625, 121, 0}, +{ 6, s_2_628, 625, 127, 0}, +{ 6, s_2_629, 625, 149, 0}, +{ 3, s_2_630, -1, 123, 0}, +{ 8, s_2_631, 630, 141, 0}, +{ 8, s_2_632, 630, 142, 0}, +{ 8, s_2_633, 630, 143, 0}, +{ 3, s_2_634, -1, 104, 0}, +{ 5, s_2_635, 634, 128, 0}, +{ 5, s_2_636, 634, 68, 0}, +{ 4, s_2_637, 634, 69, 0}, +{ 5, s_2_638, 634, 100, 0}, +{ 5, s_2_639, 634, 105, 0}, +{ 4, s_2_640, 634, 113, 0}, +{ 5, s_2_641, 634, 97, 0}, +{ 5, s_2_642, 634, 96, 0}, +{ 5, s_2_643, 634, 98, 0}, +{ 5, s_2_644, 634, 99, 0}, +{ 6, s_2_645, 634, 102, 0}, +{ 3, s_2_646, -1, 70, 0}, +{ 8, s_2_647, 646, 110, 0}, +{ 8, s_2_648, 646, 111, 0}, +{ 8, s_2_649, 646, 112, 0}, +{ 8, s_2_650, 646, 106, 0}, +{ 8, s_2_651, 646, 107, 0}, +{ 8, s_2_652, 646, 108, 0}, +{ 5, s_2_653, 646, 116, 0}, +{ 6, s_2_654, 646, 114, 0}, +{ 5, s_2_655, 646, 25, 0}, +{ 8, s_2_656, 655, 121, 0}, +{ 7, s_2_657, 655, 100, 0}, +{ 9, s_2_658, 655, 117, 0}, +{ 4, s_2_659, 646, 13, 0}, +{ 8, s_2_660, 659, 110, 0}, +{ 8, s_2_661, 659, 111, 0}, +{ 8, s_2_662, 659, 112, 0}, +{ 6, s_2_663, 646, 115, 0}, +{ 3, s_2_664, -1, 116, 0}, +{ 5, s_2_665, 664, 124, 0}, +{ 6, s_2_666, 664, 121, 0}, +{ 4, s_2_667, 664, 13, 0}, +{ 8, s_2_668, 667, 110, 0}, +{ 8, s_2_669, 667, 111, 0}, +{ 8, s_2_670, 667, 112, 0}, +{ 6, s_2_671, 664, 127, 0}, +{ 6, s_2_672, 664, 118, 0}, +{ 6, s_2_673, 664, 115, 0}, +{ 5, s_2_674, 664, 92, 0}, +{ 5, s_2_675, 664, 93, 0}, +{ 6, s_2_676, 664, 101, 0}, +{ 7, s_2_677, 664, 117, 0}, +{ 7, s_2_678, 664, 90, 0}, +{ 4, s_2_679, -1, 104, 0}, +{ 6, s_2_680, 679, 105, 0}, +{ 5, s_2_681, 679, 113, 0}, +{ 7, s_2_682, 681, 106, 0}, +{ 7, s_2_683, 681, 107, 0}, +{ 7, s_2_684, 681, 108, 0}, +{ 6, s_2_685, 679, 97, 0}, +{ 6, s_2_686, 679, 96, 0}, +{ 6, s_2_687, 679, 98, 0}, +{ 6, s_2_688, 679, 99, 0}, +{ 4, s_2_689, -1, 116, 0}, +{ 7, s_2_690, -1, 121, 0}, +{ 6, s_2_691, -1, 100, 0}, +{ 8, s_2_692, -1, 117, 0}, +{ 4, s_2_693, -1, 94, 0}, +{ 6, s_2_694, 693, 128, 0}, +{ 9, s_2_695, 693, 106, 0}, +{ 9, s_2_696, 693, 107, 0}, +{ 9, s_2_697, 693, 108, 0}, +{ 7, s_2_698, 693, 114, 0}, +{ 6, s_2_699, 693, 100, 0}, +{ 6, s_2_700, 693, 105, 0}, +{ 5, s_2_701, 693, 113, 0}, +{ 6, s_2_702, 693, 97, 0}, +{ 6, s_2_703, 693, 96, 0}, +{ 6, s_2_704, 693, 98, 0}, +{ 6, s_2_705, 693, 76, 0}, +{ 6, s_2_706, 693, 99, 0}, +{ 7, s_2_707, 693, 102, 0}, +{ 4, s_2_708, -1, 71, 0}, +{ 4, s_2_709, -1, 72, 0}, +{ 6, s_2_710, 709, 124, 0}, +{ 7, s_2_711, 709, 121, 0}, +{ 5, s_2_712, 709, 103, 0}, +{ 7, s_2_713, 709, 127, 0}, +{ 7, s_2_714, 709, 118, 0}, +{ 7, s_2_715, 709, 101, 0}, +{ 8, s_2_716, 709, 117, 0}, +{ 8, s_2_717, 709, 90, 0}, +{ 4, s_2_718, -1, 73, 0}, +{ 4, s_2_719, -1, 74, 0}, +{ 9, s_2_720, 719, 110, 0}, +{ 9, s_2_721, 719, 111, 0}, +{ 9, s_2_722, 719, 112, 0}, +{ 5, s_2_723, -1, 13, 0}, +{ 5, s_2_724, -1, 75, 0}, +{ 3, s_2_725, -1, 77, 0}, +{ 3, s_2_726, -1, 78, 0}, +{ 5, s_2_727, 726, 109, 0}, +{ 6, s_2_728, 727, 26, 0}, +{ 6, s_2_729, 727, 30, 0}, +{ 6, s_2_730, 727, 31, 0}, +{ 7, s_2_731, 727, 28, 0}, +{ 7, s_2_732, 727, 27, 0}, +{ 7, s_2_733, 727, 29, 0}, +{ 3, s_2_734, -1, 79, 0}, +{ 3, s_2_735, -1, 80, 0}, +{ 4, s_2_736, 735, 20, 0}, +{ 5, s_2_737, 736, 17, 0}, +{ 4, s_2_738, 735, 82, 0}, +{ 5, s_2_739, 738, 49, 0}, +{ 4, s_2_740, 735, 81, 0}, +{ 5, s_2_741, 735, 12, 0}, +{ 4, s_2_742, -1, 14, 0}, +{ 4, s_2_743, -1, 15, 0}, +{ 4, s_2_744, -1, 16, 0}, +{ 4, s_2_745, -1, 101, 0}, +{ 5, s_2_746, -1, 117, 0}, +{ 4, s_2_747, -1, 104, 0}, +{ 5, s_2_748, 747, 63, 0}, +{ 5, s_2_749, 747, 64, 0}, +{ 5, s_2_750, 747, 61, 0}, +{ 9, s_2_751, 750, 106, 0}, +{ 9, s_2_752, 750, 107, 0}, +{ 9, s_2_753, 750, 108, 0}, +{ 7, s_2_754, 750, 114, 0}, +{ 5, s_2_755, 747, 62, 0}, +{ 5, s_2_756, 747, 60, 0}, +{ 6, s_2_757, 747, 100, 0}, +{ 6, s_2_758, 747, 105, 0}, +{ 5, s_2_759, 747, 59, 0}, +{ 5, s_2_760, 747, 65, 0}, +{ 6, s_2_761, 760, 97, 0}, +{ 6, s_2_762, 760, 96, 0}, +{ 6, s_2_763, 760, 98, 0}, +{ 6, s_2_764, 760, 76, 0}, +{ 6, s_2_765, 760, 99, 0}, +{ 7, s_2_766, 747, 102, 0}, +{ 4, s_2_767, -1, 66, 0}, +{ 4, s_2_768, -1, 67, 0}, +{ 7, s_2_769, 768, 118, 0}, +{ 7, s_2_770, 768, 101, 0}, +{ 8, s_2_771, 768, 117, 0}, +{ 8, s_2_772, 768, 90, 0}, +{ 4, s_2_773, -1, 91, 0}, +{ 9, s_2_774, 773, 110, 0}, +{ 9, s_2_775, 773, 111, 0}, +{ 9, s_2_776, 773, 112, 0}, +{ 4, s_2_777, -1, 124, 0}, +{ 4, s_2_778, -1, 125, 0}, +{ 4, s_2_779, -1, 126, 0}, +{ 7, s_2_780, -1, 84, 0}, +{ 7, s_2_781, -1, 85, 0}, +{ 7, s_2_782, -1, 122, 0}, +{ 8, s_2_783, -1, 86, 0}, +{ 5, s_2_784, -1, 95, 0}, +{ 6, s_2_785, 784, 1, 0}, +{ 7, s_2_786, 784, 2, 0}, +{ 6, s_2_787, -1, 83, 0}, +{ 5, s_2_788, -1, 13, 0}, +{ 6, s_2_789, -1, 123, 0}, +{ 6, s_2_790, -1, 120, 0}, +{ 8, s_2_791, -1, 92, 0}, +{ 8, s_2_792, -1, 93, 0}, +{ 7, s_2_793, -1, 94, 0}, +{ 6, s_2_794, -1, 77, 0}, +{ 6, s_2_795, -1, 78, 0}, +{ 6, s_2_796, -1, 79, 0}, +{ 6, s_2_797, -1, 80, 0}, +{ 7, s_2_798, -1, 91, 0}, +{ 5, s_2_799, -1, 84, 0}, +{ 5, s_2_800, -1, 85, 0}, +{ 5, s_2_801, -1, 122, 0}, +{ 6, s_2_802, -1, 86, 0}, +{ 3, s_2_803, -1, 95, 0}, +{ 4, s_2_804, -1, 83, 0}, +{ 3, s_2_805, -1, 13, 0}, +{ 4, s_2_806, 805, 10, 0}, +{ 4, s_2_807, 805, 87, 0}, +{ 4, s_2_808, 805, 159, 0}, +{ 5, s_2_809, 805, 88, 0}, +{ 4, s_2_810, -1, 123, 0}, +{ 4, s_2_811, -1, 120, 0}, +{ 4, s_2_812, -1, 77, 0}, +{ 4, s_2_813, -1, 78, 0}, +{ 4, s_2_814, -1, 79, 0}, +{ 4, s_2_815, -1, 80, 0}, +{ 5, s_2_816, -1, 14, 0}, +{ 5, s_2_817, -1, 15, 0}, +{ 5, s_2_818, -1, 16, 0}, +{ 5, s_2_819, -1, 91, 0}, +{ 4, s_2_820, -1, 124, 0}, +{ 4, s_2_821, -1, 125, 0}, +{ 4, s_2_822, -1, 126, 0}, +{ 5, s_2_823, -1, 84, 0}, +{ 5, s_2_824, -1, 85, 0}, +{ 5, s_2_825, -1, 122, 0}, +{ 6, s_2_826, -1, 86, 0}, +{ 3, s_2_827, -1, 95, 0}, +{ 4, s_2_828, 827, 1, 0}, +{ 5, s_2_829, 827, 2, 0}, +{ 4, s_2_830, -1, 83, 0}, +{ 3, s_2_831, -1, 13, 0}, +{ 5, s_2_832, 831, 137, 0}, +{ 6, s_2_833, 831, 89, 0}, +{ 4, s_2_834, -1, 123, 0}, +{ 4, s_2_835, -1, 120, 0}, +{ 6, s_2_836, -1, 92, 0}, +{ 6, s_2_837, -1, 93, 0}, +{ 5, s_2_838, -1, 94, 0}, +{ 4, s_2_839, -1, 77, 0}, +{ 4, s_2_840, -1, 78, 0}, +{ 4, s_2_841, -1, 79, 0}, +{ 4, s_2_842, -1, 80, 0}, +{ 5, s_2_843, -1, 14, 0}, +{ 5, s_2_844, -1, 15, 0}, +{ 5, s_2_845, -1, 16, 0}, +{ 5, s_2_846, -1, 91, 0}, +{ 2, s_2_847, -1, 104, 0}, +{ 4, s_2_848, 847, 128, 0}, +{ 7, s_2_849, 847, 106, 0}, +{ 7, s_2_850, 847, 107, 0}, +{ 7, s_2_851, 847, 108, 0}, +{ 5, s_2_852, 847, 114, 0}, +{ 4, s_2_853, 847, 100, 0}, +{ 4, s_2_854, 847, 105, 0}, +{ 3, s_2_855, 847, 113, 0}, +{ 4, s_2_856, 847, 97, 0}, +{ 4, s_2_857, 847, 96, 0}, +{ 4, s_2_858, 847, 98, 0}, +{ 4, s_2_859, 847, 76, 0}, +{ 4, s_2_860, 847, 99, 0}, +{ 5, s_2_861, 847, 102, 0}, +{ 2, s_2_862, -1, 116, 0}, +{ 4, s_2_863, 862, 124, 0}, +{ 4, s_2_864, 862, 125, 0}, +{ 4, s_2_865, 862, 126, 0}, +{ 5, s_2_866, 865, 121, 0}, +{ 7, s_2_867, 862, 84, 0}, +{ 7, s_2_868, 862, 85, 0}, +{ 7, s_2_869, 862, 122, 0}, +{ 8, s_2_870, 862, 86, 0}, +{ 5, s_2_871, 862, 95, 0}, +{ 6, s_2_872, 871, 1, 0}, +{ 7, s_2_873, 871, 2, 0}, +{ 6, s_2_874, 862, 83, 0}, +{ 5, s_2_875, 862, 13, 0}, +{ 6, s_2_876, 862, 123, 0}, +{ 6, s_2_877, 862, 120, 0}, +{ 8, s_2_878, 862, 92, 0}, +{ 8, s_2_879, 862, 93, 0}, +{ 7, s_2_880, 862, 94, 0}, +{ 6, s_2_881, 862, 77, 0}, +{ 6, s_2_882, 862, 78, 0}, +{ 6, s_2_883, 862, 79, 0}, +{ 6, s_2_884, 862, 80, 0}, +{ 7, s_2_885, 862, 91, 0}, +{ 5, s_2_886, 862, 84, 0}, +{ 5, s_2_887, 862, 85, 0}, +{ 5, s_2_888, 862, 122, 0}, +{ 6, s_2_889, 862, 86, 0}, +{ 3, s_2_890, 862, 95, 0}, +{ 4, s_2_891, 890, 1, 0}, +{ 5, s_2_892, 890, 2, 0}, +{ 4, s_2_893, 862, 83, 0}, +{ 3, s_2_894, 862, 13, 0}, +{ 5, s_2_895, 894, 137, 0}, +{ 6, s_2_896, 894, 89, 0}, +{ 4, s_2_897, 862, 123, 0}, +{ 5, s_2_898, 897, 127, 0}, +{ 4, s_2_899, 862, 120, 0}, +{ 5, s_2_900, 862, 118, 0}, +{ 6, s_2_901, 862, 92, 0}, +{ 6, s_2_902, 862, 93, 0}, +{ 5, s_2_903, 862, 94, 0}, +{ 4, s_2_904, 862, 77, 0}, +{ 4, s_2_905, 862, 78, 0}, +{ 4, s_2_906, 862, 79, 0}, +{ 4, s_2_907, 862, 80, 0}, +{ 5, s_2_908, 862, 14, 0}, +{ 5, s_2_909, 862, 15, 0}, +{ 5, s_2_910, 862, 16, 0}, +{ 5, s_2_911, 862, 101, 0}, +{ 6, s_2_912, 862, 117, 0}, +{ 5, s_2_913, 862, 91, 0}, +{ 6, s_2_914, 913, 90, 0}, +{ 7, s_2_915, -1, 110, 0}, +{ 7, s_2_916, -1, 111, 0}, +{ 7, s_2_917, -1, 112, 0}, +{ 4, s_2_918, -1, 124, 0}, +{ 4, s_2_919, -1, 125, 0}, +{ 4, s_2_920, -1, 126, 0}, +{ 5, s_2_921, -1, 14, 0}, +{ 5, s_2_922, -1, 15, 0}, +{ 5, s_2_923, -1, 16, 0}, +{ 3, s_2_924, -1, 124, 0}, +{ 5, s_2_925, -1, 124, 0}, +{ 4, s_2_926, -1, 162, 0}, +{ 5, s_2_927, -1, 161, 0}, +{ 7, s_2_928, 927, 155, 0}, +{ 7, s_2_929, 927, 156, 0}, +{ 8, s_2_930, 927, 138, 0}, +{ 8, s_2_931, 927, 139, 0}, +{ 8, s_2_932, 927, 140, 0}, +{ 7, s_2_933, 927, 144, 0}, +{ 7, s_2_934, 927, 145, 0}, +{ 7, s_2_935, 927, 146, 0}, +{ 7, s_2_936, 927, 147, 0}, +{ 5, s_2_937, -1, 157, 0}, +{ 8, s_2_938, 937, 121, 0}, +{ 7, s_2_939, 937, 155, 0}, +{ 4, s_2_940, -1, 121, 0}, +{ 4, s_2_941, -1, 164, 0}, +{ 5, s_2_942, -1, 153, 0}, +{ 6, s_2_943, -1, 136, 0}, +{ 2, s_2_944, -1, 20, 0}, +{ 3, s_2_945, 944, 18, 0}, +{ 3, s_2_946, -1, 109, 0}, +{ 4, s_2_947, 946, 26, 0}, +{ 4, s_2_948, 946, 30, 0}, +{ 4, s_2_949, 946, 31, 0}, +{ 5, s_2_950, 946, 28, 0}, +{ 5, s_2_951, 946, 27, 0}, +{ 5, s_2_952, 946, 29, 0}, +{ 4, s_2_953, -1, 32, 0}, +{ 4, s_2_954, -1, 33, 0}, +{ 4, s_2_955, -1, 34, 0}, +{ 4, s_2_956, -1, 40, 0}, +{ 4, s_2_957, -1, 39, 0}, +{ 6, s_2_958, -1, 84, 0}, +{ 6, s_2_959, -1, 85, 0}, +{ 6, s_2_960, -1, 122, 0}, +{ 7, s_2_961, -1, 86, 0}, +{ 4, s_2_962, -1, 95, 0}, +{ 5, s_2_963, 962, 1, 0}, +{ 6, s_2_964, 962, 2, 0}, +{ 4, s_2_965, -1, 35, 0}, +{ 5, s_2_966, 965, 83, 0}, +{ 4, s_2_967, -1, 37, 0}, +{ 4, s_2_968, -1, 13, 0}, +{ 6, s_2_969, 968, 9, 0}, +{ 6, s_2_970, 968, 6, 0}, +{ 6, s_2_971, 968, 7, 0}, +{ 6, s_2_972, 968, 8, 0}, +{ 6, s_2_973, 968, 5, 0}, +{ 4, s_2_974, -1, 41, 0}, +{ 4, s_2_975, -1, 42, 0}, +{ 4, s_2_976, -1, 43, 0}, +{ 5, s_2_977, 976, 123, 0}, +{ 4, s_2_978, -1, 44, 0}, +{ 5, s_2_979, 978, 120, 0}, +{ 7, s_2_980, 978, 92, 0}, +{ 7, s_2_981, 978, 93, 0}, +{ 6, s_2_982, 978, 94, 0}, +{ 5, s_2_983, -1, 77, 0}, +{ 5, s_2_984, -1, 78, 0}, +{ 5, s_2_985, -1, 79, 0}, +{ 5, s_2_986, -1, 80, 0}, +{ 4, s_2_987, -1, 45, 0}, +{ 6, s_2_988, -1, 91, 0}, +{ 5, s_2_989, -1, 38, 0}, +{ 4, s_2_990, -1, 84, 0}, +{ 4, s_2_991, -1, 85, 0}, +{ 4, s_2_992, -1, 122, 0}, +{ 5, s_2_993, -1, 86, 0}, +{ 2, s_2_994, -1, 95, 0}, +{ 3, s_2_995, 994, 1, 0}, +{ 4, s_2_996, 994, 2, 0}, +{ 3, s_2_997, -1, 104, 0}, +{ 5, s_2_998, 997, 128, 0}, +{ 8, s_2_999, 997, 106, 0}, +{ 8, s_2_1000, 997, 107, 0}, +{ 8, s_2_1001, 997, 108, 0}, +{ 5, s_2_1002, 997, 47, 0}, +{ 6, s_2_1003, 997, 114, 0}, +{ 4, s_2_1004, 997, 46, 0}, +{ 5, s_2_1005, 997, 100, 0}, +{ 5, s_2_1006, 997, 105, 0}, +{ 4, s_2_1007, 997, 113, 0}, +{ 6, s_2_1008, 1007, 110, 0}, +{ 6, s_2_1009, 1007, 111, 0}, +{ 6, s_2_1010, 1007, 112, 0}, +{ 5, s_2_1011, 997, 97, 0}, +{ 5, s_2_1012, 997, 96, 0}, +{ 5, s_2_1013, 997, 98, 0}, +{ 5, s_2_1014, 997, 76, 0}, +{ 5, s_2_1015, 997, 99, 0}, +{ 6, s_2_1016, 997, 102, 0}, +{ 3, s_2_1017, -1, 83, 0}, +{ 3, s_2_1018, -1, 116, 0}, +{ 5, s_2_1019, 1018, 124, 0}, +{ 6, s_2_1020, 1018, 121, 0}, +{ 4, s_2_1021, 1018, 103, 0}, +{ 6, s_2_1022, 1018, 127, 0}, +{ 6, s_2_1023, 1018, 118, 0}, +{ 5, s_2_1024, 1018, 48, 0}, +{ 6, s_2_1025, 1018, 101, 0}, +{ 7, s_2_1026, 1018, 117, 0}, +{ 7, s_2_1027, 1018, 90, 0}, +{ 3, s_2_1028, -1, 50, 0}, +{ 4, s_2_1029, -1, 115, 0}, +{ 4, s_2_1030, -1, 13, 0}, +{ 4, s_2_1031, -1, 52, 0}, +{ 4, s_2_1032, -1, 51, 0}, +{ 2, s_2_1033, -1, 13, 0}, +{ 3, s_2_1034, 1033, 10, 0}, +{ 5, s_2_1035, 1034, 128, 0}, +{ 5, s_2_1036, 1034, 105, 0}, +{ 4, s_2_1037, 1034, 113, 0}, +{ 5, s_2_1038, 1034, 97, 0}, +{ 5, s_2_1039, 1034, 96, 0}, +{ 5, s_2_1040, 1034, 98, 0}, +{ 5, s_2_1041, 1034, 99, 0}, +{ 6, s_2_1042, 1034, 102, 0}, +{ 5, s_2_1043, 1033, 124, 0}, +{ 6, s_2_1044, 1033, 121, 0}, +{ 6, s_2_1045, 1033, 101, 0}, +{ 7, s_2_1046, 1033, 117, 0}, +{ 3, s_2_1047, 1033, 11, 0}, +{ 4, s_2_1048, 1047, 137, 0}, +{ 5, s_2_1049, 1047, 89, 0}, +{ 3, s_2_1050, 1033, 12, 0}, +{ 3, s_2_1051, -1, 53, 0}, +{ 3, s_2_1052, -1, 54, 0}, +{ 3, s_2_1053, -1, 55, 0}, +{ 3, s_2_1054, -1, 56, 0}, +{ 4, s_2_1055, -1, 135, 0}, +{ 4, s_2_1056, -1, 131, 0}, +{ 4, s_2_1057, -1, 129, 0}, +{ 4, s_2_1058, -1, 133, 0}, +{ 4, s_2_1059, -1, 132, 0}, +{ 4, s_2_1060, -1, 130, 0}, +{ 4, s_2_1061, -1, 134, 0}, +{ 3, s_2_1062, -1, 152, 0}, +{ 3, s_2_1063, -1, 154, 0}, +{ 3, s_2_1064, -1, 123, 0}, +{ 4, s_2_1065, -1, 161, 0}, +{ 6, s_2_1066, 1065, 128, 0}, +{ 6, s_2_1067, 1065, 155, 0}, +{ 5, s_2_1068, 1065, 160, 0}, +{ 6, s_2_1069, 1068, 153, 0}, +{ 7, s_2_1070, 1068, 141, 0}, +{ 7, s_2_1071, 1068, 142, 0}, +{ 7, s_2_1072, 1068, 143, 0}, +{ 4, s_2_1073, -1, 162, 0}, +{ 5, s_2_1074, 1073, 158, 0}, +{ 7, s_2_1075, 1073, 127, 0}, +{ 5, s_2_1076, -1, 164, 0}, +{ 3, s_2_1077, -1, 104, 0}, +{ 5, s_2_1078, 1077, 128, 0}, +{ 8, s_2_1079, 1077, 106, 0}, +{ 8, s_2_1080, 1077, 107, 0}, +{ 8, s_2_1081, 1077, 108, 0}, +{ 6, s_2_1082, 1077, 114, 0}, +{ 5, s_2_1083, 1077, 68, 0}, +{ 4, s_2_1084, 1077, 69, 0}, +{ 5, s_2_1085, 1077, 100, 0}, +{ 5, s_2_1086, 1077, 105, 0}, +{ 4, s_2_1087, 1077, 113, 0}, +{ 6, s_2_1088, 1087, 110, 0}, +{ 6, s_2_1089, 1087, 111, 0}, +{ 6, s_2_1090, 1087, 112, 0}, +{ 5, s_2_1091, 1077, 97, 0}, +{ 5, s_2_1092, 1077, 96, 0}, +{ 5, s_2_1093, 1077, 98, 0}, +{ 5, s_2_1094, 1077, 76, 0}, +{ 5, s_2_1095, 1077, 99, 0}, +{ 6, s_2_1096, 1077, 102, 0}, +{ 3, s_2_1097, -1, 70, 0}, +{ 3, s_2_1098, -1, 116, 0}, +{ 5, s_2_1099, 1098, 124, 0}, +{ 6, s_2_1100, 1098, 121, 0}, +{ 4, s_2_1101, 1098, 103, 0}, +{ 6, s_2_1102, 1098, 127, 0}, +{ 6, s_2_1103, 1098, 118, 0}, +{ 5, s_2_1104, 1098, 92, 0}, +{ 5, s_2_1105, 1098, 93, 0}, +{ 6, s_2_1106, 1098, 101, 0}, +{ 7, s_2_1107, 1098, 117, 0}, +{ 7, s_2_1108, 1098, 90, 0}, +{ 4, s_2_1109, -1, 94, 0}, +{ 4, s_2_1110, -1, 71, 0}, +{ 4, s_2_1111, -1, 72, 0}, +{ 4, s_2_1112, -1, 73, 0}, +{ 4, s_2_1113, -1, 74, 0}, +{ 4, s_2_1114, -1, 13, 0}, +{ 3, s_2_1115, -1, 77, 0}, +{ 3, s_2_1116, -1, 78, 0}, +{ 5, s_2_1117, 1116, 109, 0}, +{ 6, s_2_1118, 1117, 26, 0}, +{ 6, s_2_1119, 1117, 30, 0}, +{ 6, s_2_1120, 1117, 31, 0}, +{ 7, s_2_1121, 1117, 28, 0}, +{ 7, s_2_1122, 1117, 27, 0}, +{ 7, s_2_1123, 1117, 29, 0}, +{ 3, s_2_1124, -1, 79, 0}, +{ 3, s_2_1125, -1, 80, 0}, +{ 4, s_2_1126, 1125, 20, 0}, +{ 5, s_2_1127, 1126, 17, 0}, +{ 4, s_2_1128, 1125, 82, 0}, +{ 5, s_2_1129, 1128, 49, 0}, +{ 4, s_2_1130, 1125, 81, 0}, +{ 5, s_2_1131, 1125, 12, 0}, +{ 5, s_2_1132, -1, 116, 0}, +{ 7, s_2_1133, -1, 101, 0}, +{ 6, s_2_1134, -1, 104, 0}, +{ 8, s_2_1135, 1134, 100, 0}, +{ 8, s_2_1136, 1134, 105, 0}, +{ 9, s_2_1137, 1134, 106, 0}, +{ 9, s_2_1138, 1134, 107, 0}, +{ 9, s_2_1139, 1134, 108, 0}, +{ 8, s_2_1140, 1134, 97, 0}, +{ 8, s_2_1141, 1134, 96, 0}, +{ 8, s_2_1142, 1134, 98, 0}, +{ 8, s_2_1143, 1134, 99, 0}, +{ 6, s_2_1144, -1, 25, 0}, +{ 8, s_2_1145, 1144, 100, 0}, +{ 10, s_2_1146, 1144, 117, 0}, +{ 5, s_2_1147, -1, 13, 0}, +{ 6, s_2_1148, -1, 70, 0}, +{ 7, s_2_1149, -1, 115, 0}, +{ 4, s_2_1150, -1, 101, 0}, +{ 5, s_2_1151, -1, 117, 0}, +{ 5, s_2_1152, -1, 63, 0}, +{ 5, s_2_1153, -1, 64, 0}, +{ 5, s_2_1154, -1, 61, 0}, +{ 5, s_2_1155, -1, 62, 0}, +{ 5, s_2_1156, -1, 60, 0}, +{ 5, s_2_1157, -1, 59, 0}, +{ 5, s_2_1158, -1, 65, 0}, +{ 4, s_2_1159, -1, 66, 0}, +{ 4, s_2_1160, -1, 67, 0}, +{ 4, s_2_1161, -1, 91, 0}, +{ 5, s_2_1162, -1, 104, 0}, +{ 7, s_2_1163, 1162, 100, 0}, +{ 6, s_2_1164, 1162, 113, 0}, +{ 7, s_2_1165, 1164, 70, 0}, +{ 8, s_2_1166, 1164, 110, 0}, +{ 8, s_2_1167, 1164, 111, 0}, +{ 8, s_2_1168, 1164, 112, 0}, +{ 8, s_2_1169, 1162, 102, 0}, +{ 5, s_2_1170, -1, 116, 0}, +{ 6, s_2_1171, 1170, 103, 0}, +{ 9, s_2_1172, 1170, 90, 0}, +{ 6, s_2_1173, -1, 13, 0}, +{ 2, s_2_1174, -1, 104, 0}, +{ 4, s_2_1175, 1174, 105, 0}, +{ 3, s_2_1176, 1174, 113, 0}, +{ 4, s_2_1177, 1174, 97, 0}, +{ 4, s_2_1178, 1174, 96, 0}, +{ 4, s_2_1179, 1174, 98, 0}, +{ 4, s_2_1180, 1174, 99, 0}, +{ 2, s_2_1181, -1, 116, 0}, +{ 4, s_2_1182, -1, 124, 0}, +{ 4, s_2_1183, -1, 125, 0}, +{ 4, s_2_1184, -1, 126, 0}, +{ 7, s_2_1185, -1, 84, 0}, +{ 7, s_2_1186, -1, 85, 0}, +{ 7, s_2_1187, -1, 122, 0}, +{ 8, s_2_1188, -1, 86, 0}, +{ 5, s_2_1189, -1, 95, 0}, +{ 6, s_2_1190, 1189, 1, 0}, +{ 7, s_2_1191, 1189, 2, 0}, +{ 6, s_2_1192, -1, 83, 0}, +{ 5, s_2_1193, -1, 13, 0}, +{ 6, s_2_1194, -1, 123, 0}, +{ 8, s_2_1195, -1, 92, 0}, +{ 8, s_2_1196, -1, 93, 0}, +{ 7, s_2_1197, -1, 94, 0}, +{ 6, s_2_1198, -1, 77, 0}, +{ 6, s_2_1199, -1, 78, 0}, +{ 6, s_2_1200, -1, 79, 0}, +{ 6, s_2_1201, -1, 80, 0}, +{ 7, s_2_1202, -1, 91, 0}, +{ 5, s_2_1203, -1, 84, 0}, +{ 5, s_2_1204, -1, 85, 0}, +{ 5, s_2_1205, -1, 122, 0}, +{ 6, s_2_1206, -1, 86, 0}, +{ 3, s_2_1207, -1, 95, 0}, +{ 4, s_2_1208, 1207, 1, 0}, +{ 5, s_2_1209, 1207, 2, 0}, +{ 4, s_2_1210, -1, 104, 0}, +{ 4, s_2_1211, -1, 83, 0}, +{ 3, s_2_1212, -1, 13, 0}, +{ 5, s_2_1213, 1212, 137, 0}, +{ 6, s_2_1214, 1212, 89, 0}, +{ 4, s_2_1215, -1, 123, 0}, +{ 4, s_2_1216, -1, 120, 0}, +{ 6, s_2_1217, -1, 92, 0}, +{ 6, s_2_1218, -1, 93, 0}, +{ 5, s_2_1219, -1, 94, 0}, +{ 4, s_2_1220, -1, 77, 0}, +{ 4, s_2_1221, -1, 78, 0}, +{ 4, s_2_1222, -1, 79, 0}, +{ 4, s_2_1223, -1, 80, 0}, +{ 5, s_2_1224, -1, 14, 0}, +{ 5, s_2_1225, -1, 15, 0}, +{ 5, s_2_1226, -1, 16, 0}, +{ 5, s_2_1227, -1, 91, 0}, +{ 5, s_2_1228, -1, 121, 0}, +{ 4, s_2_1229, -1, 100, 0}, +{ 6, s_2_1230, -1, 117, 0}, +{ 2, s_2_1231, -1, 104, 0}, +{ 4, s_2_1232, 1231, 100, 0}, +{ 4, s_2_1233, 1231, 105, 0}, +{ 2, s_2_1234, -1, 119, 0}, +{ 2, s_2_1235, -1, 116, 0}, +{ 2, s_2_1236, -1, 104, 0}, +{ 4, s_2_1237, 1236, 128, 0}, +{ 4, s_2_1238, 1236, 100, 0}, +{ 4, s_2_1239, 1236, 105, 0}, +{ 3, s_2_1240, 1236, 113, 0}, +{ 4, s_2_1241, 1236, 97, 0}, +{ 4, s_2_1242, 1236, 96, 0}, +{ 4, s_2_1243, 1236, 98, 0}, +{ 4, s_2_1244, 1236, 99, 0}, +{ 5, s_2_1245, 1236, 102, 0}, +{ 2, s_2_1246, -1, 119, 0}, +{ 4, s_2_1247, 1246, 124, 0}, +{ 4, s_2_1248, 1246, 125, 0}, +{ 4, s_2_1249, 1246, 126, 0}, +{ 7, s_2_1250, 1246, 110, 0}, +{ 7, s_2_1251, 1246, 111, 0}, +{ 7, s_2_1252, 1246, 112, 0}, +{ 4, s_2_1253, 1246, 104, 0}, +{ 5, s_2_1254, 1253, 26, 0}, +{ 5, s_2_1255, 1253, 30, 0}, +{ 5, s_2_1256, 1253, 31, 0}, +{ 7, s_2_1257, 1253, 106, 0}, +{ 7, s_2_1258, 1253, 107, 0}, +{ 7, s_2_1259, 1253, 108, 0}, +{ 6, s_2_1260, 1253, 28, 0}, +{ 6, s_2_1261, 1253, 27, 0}, +{ 6, s_2_1262, 1253, 29, 0}, +{ 4, s_2_1263, 1246, 116, 0}, +{ 7, s_2_1264, 1263, 84, 0}, +{ 7, s_2_1265, 1263, 85, 0}, +{ 7, s_2_1266, 1263, 123, 0}, +{ 8, s_2_1267, 1263, 86, 0}, +{ 5, s_2_1268, 1263, 95, 0}, +{ 6, s_2_1269, 1268, 1, 0}, +{ 7, s_2_1270, 1268, 2, 0}, +{ 5, s_2_1271, 1263, 24, 0}, +{ 6, s_2_1272, 1271, 83, 0}, +{ 5, s_2_1273, 1263, 13, 0}, +{ 7, s_2_1274, 1263, 21, 0}, +{ 5, s_2_1275, 1263, 23, 0}, +{ 6, s_2_1276, 1275, 123, 0}, +{ 6, s_2_1277, 1263, 120, 0}, +{ 8, s_2_1278, 1263, 92, 0}, +{ 8, s_2_1279, 1263, 93, 0}, +{ 6, s_2_1280, 1263, 22, 0}, +{ 7, s_2_1281, 1263, 94, 0}, +{ 6, s_2_1282, 1263, 77, 0}, +{ 6, s_2_1283, 1263, 78, 0}, +{ 6, s_2_1284, 1263, 79, 0}, +{ 6, s_2_1285, 1263, 80, 0}, +{ 7, s_2_1286, 1263, 91, 0}, +{ 5, s_2_1287, 1246, 84, 0}, +{ 5, s_2_1288, 1246, 85, 0}, +{ 5, s_2_1289, 1246, 114, 0}, +{ 5, s_2_1290, 1246, 122, 0}, +{ 6, s_2_1291, 1246, 86, 0}, +{ 4, s_2_1292, 1246, 25, 0}, +{ 7, s_2_1293, 1292, 121, 0}, +{ 6, s_2_1294, 1292, 100, 0}, +{ 8, s_2_1295, 1292, 117, 0}, +{ 3, s_2_1296, 1246, 95, 0}, +{ 4, s_2_1297, 1296, 1, 0}, +{ 5, s_2_1298, 1296, 2, 0}, +{ 4, s_2_1299, 1246, 83, 0}, +{ 3, s_2_1300, 1246, 13, 0}, +{ 4, s_2_1301, 1300, 10, 0}, +{ 7, s_2_1302, 1301, 110, 0}, +{ 7, s_2_1303, 1301, 111, 0}, +{ 7, s_2_1304, 1301, 112, 0}, +{ 4, s_2_1305, 1300, 87, 0}, +{ 4, s_2_1306, 1300, 159, 0}, +{ 5, s_2_1307, 1300, 88, 0}, +{ 5, s_2_1308, 1246, 135, 0}, +{ 5, s_2_1309, 1246, 131, 0}, +{ 5, s_2_1310, 1246, 129, 0}, +{ 5, s_2_1311, 1246, 133, 0}, +{ 5, s_2_1312, 1246, 132, 0}, +{ 5, s_2_1313, 1246, 130, 0}, +{ 5, s_2_1314, 1246, 134, 0}, +{ 4, s_2_1315, 1246, 152, 0}, +{ 4, s_2_1316, 1246, 154, 0}, +{ 4, s_2_1317, 1246, 123, 0}, +{ 4, s_2_1318, 1246, 120, 0}, +{ 4, s_2_1319, 1246, 70, 0}, +{ 6, s_2_1320, 1246, 92, 0}, +{ 6, s_2_1321, 1246, 93, 0}, +{ 5, s_2_1322, 1246, 94, 0}, +{ 5, s_2_1323, 1246, 151, 0}, +{ 6, s_2_1324, 1246, 75, 0}, +{ 4, s_2_1325, 1246, 77, 0}, +{ 4, s_2_1326, 1246, 78, 0}, +{ 4, s_2_1327, 1246, 79, 0}, +{ 5, s_2_1328, 1246, 14, 0}, +{ 5, s_2_1329, 1246, 15, 0}, +{ 5, s_2_1330, 1246, 16, 0}, +{ 6, s_2_1331, 1246, 63, 0}, +{ 6, s_2_1332, 1246, 64, 0}, +{ 6, s_2_1333, 1246, 61, 0}, +{ 6, s_2_1334, 1246, 62, 0}, +{ 6, s_2_1335, 1246, 60, 0}, +{ 6, s_2_1336, 1246, 59, 0}, +{ 6, s_2_1337, 1246, 65, 0}, +{ 5, s_2_1338, 1246, 66, 0}, +{ 5, s_2_1339, 1246, 67, 0}, +{ 5, s_2_1340, 1246, 91, 0}, +{ 2, s_2_1341, -1, 116, 0}, +{ 4, s_2_1342, 1341, 124, 0}, +{ 4, s_2_1343, 1341, 125, 0}, +{ 4, s_2_1344, 1341, 126, 0}, +{ 5, s_2_1345, 1344, 121, 0}, +{ 7, s_2_1346, 1341, 84, 0}, +{ 7, s_2_1347, 1341, 85, 0}, +{ 7, s_2_1348, 1341, 122, 0}, +{ 8, s_2_1349, 1341, 86, 0}, +{ 5, s_2_1350, 1341, 95, 0}, +{ 6, s_2_1351, 1350, 1, 0}, +{ 7, s_2_1352, 1350, 2, 0}, +{ 6, s_2_1353, 1341, 83, 0}, +{ 5, s_2_1354, 1341, 13, 0}, +{ 6, s_2_1355, 1341, 123, 0}, +{ 6, s_2_1356, 1341, 120, 0}, +{ 8, s_2_1357, 1341, 92, 0}, +{ 8, s_2_1358, 1341, 93, 0}, +{ 7, s_2_1359, 1341, 94, 0}, +{ 6, s_2_1360, 1341, 77, 0}, +{ 6, s_2_1361, 1341, 78, 0}, +{ 6, s_2_1362, 1341, 79, 0}, +{ 6, s_2_1363, 1341, 80, 0}, +{ 7, s_2_1364, 1341, 91, 0}, +{ 5, s_2_1365, 1341, 84, 0}, +{ 5, s_2_1366, 1341, 85, 0}, +{ 5, s_2_1367, 1341, 122, 0}, +{ 6, s_2_1368, 1341, 86, 0}, +{ 3, s_2_1369, 1341, 95, 0}, +{ 4, s_2_1370, 1369, 1, 0}, +{ 5, s_2_1371, 1369, 2, 0}, +{ 4, s_2_1372, 1341, 83, 0}, +{ 3, s_2_1373, 1341, 13, 0}, +{ 5, s_2_1374, 1373, 137, 0}, +{ 6, s_2_1375, 1373, 89, 0}, +{ 4, s_2_1376, 1341, 123, 0}, +{ 5, s_2_1377, 1376, 127, 0}, +{ 4, s_2_1378, 1341, 120, 0}, +{ 5, s_2_1379, 1341, 118, 0}, +{ 6, s_2_1380, 1341, 92, 0}, +{ 6, s_2_1381, 1341, 93, 0}, +{ 5, s_2_1382, 1341, 94, 0}, +{ 4, s_2_1383, 1341, 77, 0}, +{ 4, s_2_1384, 1341, 78, 0}, +{ 4, s_2_1385, 1341, 79, 0}, +{ 4, s_2_1386, 1341, 80, 0}, +{ 5, s_2_1387, 1341, 14, 0}, +{ 5, s_2_1388, 1341, 15, 0}, +{ 5, s_2_1389, 1341, 16, 0}, +{ 5, s_2_1390, 1341, 101, 0}, +{ 6, s_2_1391, 1341, 117, 0}, +{ 5, s_2_1392, 1341, 91, 0}, +{ 6, s_2_1393, 1392, 90, 0}, +{ 4, s_2_1394, -1, 124, 0}, +{ 4, s_2_1395, -1, 125, 0}, +{ 4, s_2_1396, -1, 126, 0}, +{ 3, s_2_1397, -1, 20, 0}, +{ 5, s_2_1398, 1397, 19, 0}, +{ 4, s_2_1399, 1397, 18, 0}, +{ 5, s_2_1400, -1, 32, 0}, +{ 5, s_2_1401, -1, 33, 0}, +{ 5, s_2_1402, -1, 34, 0}, +{ 5, s_2_1403, -1, 40, 0}, +{ 5, s_2_1404, -1, 39, 0}, +{ 5, s_2_1405, -1, 35, 0}, +{ 5, s_2_1406, -1, 37, 0}, +{ 5, s_2_1407, -1, 36, 0}, +{ 7, s_2_1408, 1407, 9, 0}, +{ 7, s_2_1409, 1407, 6, 0}, +{ 7, s_2_1410, 1407, 7, 0}, +{ 7, s_2_1411, 1407, 8, 0}, +{ 7, s_2_1412, 1407, 5, 0}, +{ 5, s_2_1413, -1, 41, 0}, +{ 5, s_2_1414, -1, 42, 0}, +{ 5, s_2_1415, -1, 43, 0}, +{ 5, s_2_1416, -1, 44, 0}, +{ 5, s_2_1417, -1, 45, 0}, +{ 6, s_2_1418, -1, 38, 0}, +{ 5, s_2_1419, -1, 84, 0}, +{ 5, s_2_1420, -1, 85, 0}, +{ 5, s_2_1421, -1, 122, 0}, +{ 6, s_2_1422, -1, 86, 0}, +{ 3, s_2_1423, -1, 95, 0}, +{ 4, s_2_1424, 1423, 1, 0}, +{ 5, s_2_1425, 1423, 2, 0}, +{ 4, s_2_1426, -1, 104, 0}, +{ 6, s_2_1427, 1426, 47, 0}, +{ 5, s_2_1428, 1426, 46, 0}, +{ 4, s_2_1429, -1, 83, 0}, +{ 4, s_2_1430, -1, 116, 0}, +{ 6, s_2_1431, 1430, 48, 0}, +{ 4, s_2_1432, -1, 50, 0}, +{ 5, s_2_1433, -1, 52, 0}, +{ 5, s_2_1434, -1, 51, 0}, +{ 3, s_2_1435, -1, 13, 0}, +{ 4, s_2_1436, 1435, 10, 0}, +{ 4, s_2_1437, 1435, 11, 0}, +{ 5, s_2_1438, 1437, 137, 0}, +{ 6, s_2_1439, 1437, 10, 0}, +{ 6, s_2_1440, 1437, 89, 0}, +{ 4, s_2_1441, 1435, 12, 0}, +{ 4, s_2_1442, -1, 53, 0}, +{ 4, s_2_1443, -1, 54, 0}, +{ 4, s_2_1444, -1, 55, 0}, +{ 4, s_2_1445, -1, 56, 0}, +{ 5, s_2_1446, -1, 135, 0}, +{ 5, s_2_1447, -1, 131, 0}, +{ 5, s_2_1448, -1, 129, 0}, +{ 5, s_2_1449, -1, 133, 0}, +{ 5, s_2_1450, -1, 132, 0}, +{ 5, s_2_1451, -1, 130, 0}, +{ 5, s_2_1452, -1, 134, 0}, +{ 4, s_2_1453, -1, 57, 0}, +{ 4, s_2_1454, -1, 58, 0}, +{ 4, s_2_1455, -1, 123, 0}, +{ 4, s_2_1456, -1, 120, 0}, +{ 6, s_2_1457, 1456, 68, 0}, +{ 5, s_2_1458, 1456, 69, 0}, +{ 4, s_2_1459, -1, 70, 0}, +{ 6, s_2_1460, -1, 92, 0}, +{ 6, s_2_1461, -1, 93, 0}, +{ 5, s_2_1462, -1, 94, 0}, +{ 5, s_2_1463, -1, 71, 0}, +{ 5, s_2_1464, -1, 72, 0}, +{ 5, s_2_1465, -1, 73, 0}, +{ 5, s_2_1466, -1, 74, 0}, +{ 4, s_2_1467, -1, 77, 0}, +{ 4, s_2_1468, -1, 78, 0}, +{ 4, s_2_1469, -1, 79, 0}, +{ 4, s_2_1470, -1, 80, 0}, +{ 5, s_2_1471, 1470, 82, 0}, +{ 5, s_2_1472, 1470, 81, 0}, +{ 5, s_2_1473, -1, 3, 0}, +{ 6, s_2_1474, -1, 4, 0}, +{ 5, s_2_1475, -1, 14, 0}, +{ 5, s_2_1476, -1, 15, 0}, +{ 5, s_2_1477, -1, 16, 0}, +{ 6, s_2_1478, -1, 63, 0}, +{ 6, s_2_1479, -1, 64, 0}, +{ 6, s_2_1480, -1, 61, 0}, +{ 6, s_2_1481, -1, 62, 0}, +{ 6, s_2_1482, -1, 60, 0}, +{ 6, s_2_1483, -1, 59, 0}, +{ 6, s_2_1484, -1, 65, 0}, +{ 5, s_2_1485, -1, 66, 0}, +{ 5, s_2_1486, -1, 67, 0}, +{ 5, s_2_1487, -1, 91, 0}, +{ 2, s_2_1488, -1, 104, 0}, +{ 4, s_2_1489, 1488, 128, 0}, +{ 4, s_2_1490, 1488, 100, 0}, +{ 4, s_2_1491, 1488, 105, 0}, +{ 3, s_2_1492, 1488, 113, 0}, +{ 4, s_2_1493, 1488, 97, 0}, +{ 4, s_2_1494, 1488, 96, 0}, +{ 4, s_2_1495, 1488, 98, 0}, +{ 4, s_2_1496, 1488, 99, 0}, +{ 5, s_2_1497, 1488, 102, 0}, +{ 4, s_2_1498, -1, 124, 0}, +{ 5, s_2_1499, -1, 121, 0}, +{ 5, s_2_1500, -1, 101, 0}, +{ 6, s_2_1501, -1, 117, 0}, +{ 4, s_2_1502, -1, 10, 0}, +{ 2, s_2_1503, -1, 104, 0}, +{ 4, s_2_1504, 1503, 128, 0}, +{ 7, s_2_1505, 1503, 106, 0}, +{ 7, s_2_1506, 1503, 107, 0}, +{ 7, s_2_1507, 1503, 108, 0}, +{ 5, s_2_1508, 1503, 114, 0}, +{ 4, s_2_1509, 1503, 100, 0}, +{ 4, s_2_1510, 1503, 105, 0}, +{ 3, s_2_1511, 1503, 113, 0}, +{ 5, s_2_1512, 1511, 110, 0}, +{ 5, s_2_1513, 1511, 111, 0}, +{ 5, s_2_1514, 1511, 112, 0}, +{ 4, s_2_1515, 1503, 97, 0}, +{ 4, s_2_1516, 1503, 96, 0}, +{ 4, s_2_1517, 1503, 98, 0}, +{ 4, s_2_1518, 1503, 76, 0}, +{ 4, s_2_1519, 1503, 99, 0}, +{ 5, s_2_1520, 1503, 102, 0}, +{ 2, s_2_1521, -1, 20, 0}, +{ 3, s_2_1522, 1521, 18, 0}, +{ 2, s_2_1523, -1, 116, 0}, +{ 4, s_2_1524, 1523, 124, 0}, +{ 5, s_2_1525, 1523, 121, 0}, +{ 3, s_2_1526, 1523, 24, 0}, +{ 3, s_2_1527, 1523, 103, 0}, +{ 5, s_2_1528, 1523, 21, 0}, +{ 3, s_2_1529, 1523, 23, 0}, +{ 5, s_2_1530, 1529, 127, 0}, +{ 5, s_2_1531, 1523, 118, 0}, +{ 4, s_2_1532, 1523, 22, 0}, +{ 5, s_2_1533, 1523, 101, 0}, +{ 6, s_2_1534, 1523, 117, 0}, +{ 6, s_2_1535, 1523, 90, 0}, +{ 4, s_2_1536, -1, 32, 0}, +{ 4, s_2_1537, -1, 33, 0}, +{ 4, s_2_1538, -1, 34, 0}, +{ 4, s_2_1539, -1, 40, 0}, +{ 4, s_2_1540, -1, 39, 0}, +{ 4, s_2_1541, -1, 35, 0}, +{ 4, s_2_1542, -1, 37, 0}, +{ 4, s_2_1543, -1, 36, 0}, +{ 4, s_2_1544, -1, 41, 0}, +{ 4, s_2_1545, -1, 42, 0}, +{ 4, s_2_1546, -1, 43, 0}, +{ 4, s_2_1547, -1, 44, 0}, +{ 4, s_2_1548, -1, 45, 0}, +{ 5, s_2_1549, -1, 38, 0}, +{ 4, s_2_1550, -1, 84, 0}, +{ 4, s_2_1551, -1, 85, 0}, +{ 4, s_2_1552, -1, 122, 0}, +{ 5, s_2_1553, -1, 86, 0}, +{ 2, s_2_1554, -1, 95, 0}, +{ 3, s_2_1555, 1554, 1, 0}, +{ 4, s_2_1556, 1554, 2, 0}, +{ 3, s_2_1557, -1, 104, 0}, +{ 5, s_2_1558, 1557, 128, 0}, +{ 8, s_2_1559, 1557, 106, 0}, +{ 8, s_2_1560, 1557, 107, 0}, +{ 8, s_2_1561, 1557, 108, 0}, +{ 5, s_2_1562, 1557, 47, 0}, +{ 6, s_2_1563, 1557, 114, 0}, +{ 4, s_2_1564, 1557, 46, 0}, +{ 5, s_2_1565, 1557, 100, 0}, +{ 5, s_2_1566, 1557, 105, 0}, +{ 4, s_2_1567, 1557, 113, 0}, +{ 6, s_2_1568, 1567, 110, 0}, +{ 6, s_2_1569, 1567, 111, 0}, +{ 6, s_2_1570, 1567, 112, 0}, +{ 5, s_2_1571, 1557, 97, 0}, +{ 5, s_2_1572, 1557, 96, 0}, +{ 5, s_2_1573, 1557, 98, 0}, +{ 5, s_2_1574, 1557, 76, 0}, +{ 5, s_2_1575, 1557, 99, 0}, +{ 6, s_2_1576, 1557, 102, 0}, +{ 3, s_2_1577, -1, 83, 0}, +{ 3, s_2_1578, -1, 116, 0}, +{ 5, s_2_1579, 1578, 124, 0}, +{ 6, s_2_1580, 1578, 121, 0}, +{ 4, s_2_1581, 1578, 103, 0}, +{ 6, s_2_1582, 1578, 127, 0}, +{ 6, s_2_1583, 1578, 118, 0}, +{ 6, s_2_1584, 1578, 101, 0}, +{ 7, s_2_1585, 1578, 117, 0}, +{ 7, s_2_1586, 1578, 90, 0}, +{ 4, s_2_1587, -1, 115, 0}, +{ 4, s_2_1588, -1, 13, 0}, +{ 3, s_2_1589, -1, 104, 0}, +{ 5, s_2_1590, 1589, 128, 0}, +{ 4, s_2_1591, 1589, 52, 0}, +{ 5, s_2_1592, 1591, 100, 0}, +{ 5, s_2_1593, 1591, 105, 0}, +{ 4, s_2_1594, 1589, 113, 0}, +{ 5, s_2_1595, 1589, 97, 0}, +{ 5, s_2_1596, 1589, 96, 0}, +{ 5, s_2_1597, 1589, 98, 0}, +{ 5, s_2_1598, 1589, 99, 0}, +{ 6, s_2_1599, 1589, 102, 0}, +{ 3, s_2_1600, -1, 119, 0}, +{ 8, s_2_1601, 1600, 110, 0}, +{ 8, s_2_1602, 1600, 111, 0}, +{ 8, s_2_1603, 1600, 112, 0}, +{ 8, s_2_1604, 1600, 106, 0}, +{ 8, s_2_1605, 1600, 107, 0}, +{ 8, s_2_1606, 1600, 108, 0}, +{ 5, s_2_1607, 1600, 116, 0}, +{ 6, s_2_1608, 1600, 114, 0}, +{ 5, s_2_1609, 1600, 25, 0}, +{ 8, s_2_1610, 1609, 121, 0}, +{ 7, s_2_1611, 1609, 100, 0}, +{ 9, s_2_1612, 1609, 117, 0}, +{ 4, s_2_1613, 1600, 51, 0}, +{ 4, s_2_1614, 1600, 13, 0}, +{ 8, s_2_1615, 1614, 110, 0}, +{ 8, s_2_1616, 1614, 111, 0}, +{ 8, s_2_1617, 1614, 112, 0}, +{ 5, s_2_1618, 1600, 70, 0}, +{ 6, s_2_1619, 1600, 115, 0}, +{ 3, s_2_1620, -1, 116, 0}, +{ 5, s_2_1621, 1620, 124, 0}, +{ 6, s_2_1622, 1620, 121, 0}, +{ 4, s_2_1623, 1620, 13, 0}, +{ 8, s_2_1624, 1623, 110, 0}, +{ 8, s_2_1625, 1623, 111, 0}, +{ 8, s_2_1626, 1623, 112, 0}, +{ 6, s_2_1627, 1620, 127, 0}, +{ 5, s_2_1628, 1620, 70, 0}, +{ 6, s_2_1629, 1628, 118, 0}, +{ 6, s_2_1630, 1620, 115, 0}, +{ 6, s_2_1631, 1620, 101, 0}, +{ 7, s_2_1632, 1620, 117, 0}, +{ 7, s_2_1633, 1620, 90, 0}, +{ 4, s_2_1634, -1, 104, 0}, +{ 6, s_2_1635, 1634, 105, 0}, +{ 5, s_2_1636, 1634, 113, 0}, +{ 7, s_2_1637, 1636, 106, 0}, +{ 7, s_2_1638, 1636, 107, 0}, +{ 7, s_2_1639, 1636, 108, 0}, +{ 6, s_2_1640, 1634, 97, 0}, +{ 6, s_2_1641, 1634, 96, 0}, +{ 6, s_2_1642, 1634, 98, 0}, +{ 6, s_2_1643, 1634, 99, 0}, +{ 4, s_2_1644, -1, 116, 0}, +{ 4, s_2_1645, -1, 25, 0}, +{ 7, s_2_1646, 1645, 121, 0}, +{ 6, s_2_1647, 1645, 100, 0}, +{ 8, s_2_1648, 1645, 117, 0}, +{ 4, s_2_1649, -1, 104, 0}, +{ 6, s_2_1650, 1649, 128, 0}, +{ 9, s_2_1651, 1649, 106, 0}, +{ 9, s_2_1652, 1649, 107, 0}, +{ 9, s_2_1653, 1649, 108, 0}, +{ 7, s_2_1654, 1649, 114, 0}, +{ 6, s_2_1655, 1649, 100, 0}, +{ 6, s_2_1656, 1649, 105, 0}, +{ 5, s_2_1657, 1649, 113, 0}, +{ 6, s_2_1658, 1649, 97, 0}, +{ 6, s_2_1659, 1649, 96, 0}, +{ 6, s_2_1660, 1649, 98, 0}, +{ 6, s_2_1661, 1649, 76, 0}, +{ 6, s_2_1662, 1649, 99, 0}, +{ 7, s_2_1663, 1649, 102, 0}, +{ 4, s_2_1664, -1, 116, 0}, +{ 6, s_2_1665, 1664, 124, 0}, +{ 7, s_2_1666, 1664, 121, 0}, +{ 5, s_2_1667, 1664, 103, 0}, +{ 7, s_2_1668, 1664, 127, 0}, +{ 7, s_2_1669, 1664, 118, 0}, +{ 7, s_2_1670, 1664, 101, 0}, +{ 8, s_2_1671, 1664, 117, 0}, +{ 8, s_2_1672, 1664, 90, 0}, +{ 9, s_2_1673, -1, 110, 0}, +{ 9, s_2_1674, -1, 111, 0}, +{ 9, s_2_1675, -1, 112, 0}, +{ 5, s_2_1676, -1, 13, 0}, +{ 2, s_2_1677, -1, 13, 0}, +{ 3, s_2_1678, 1677, 104, 0}, +{ 5, s_2_1679, 1678, 128, 0}, +{ 5, s_2_1680, 1678, 105, 0}, +{ 4, s_2_1681, 1678, 113, 0}, +{ 5, s_2_1682, 1678, 97, 0}, +{ 5, s_2_1683, 1678, 96, 0}, +{ 5, s_2_1684, 1678, 98, 0}, +{ 5, s_2_1685, 1678, 99, 0}, +{ 6, s_2_1686, 1678, 102, 0}, +{ 5, s_2_1687, 1677, 124, 0}, +{ 6, s_2_1688, 1677, 121, 0}, +{ 6, s_2_1689, 1677, 101, 0}, +{ 7, s_2_1690, 1677, 117, 0}, +{ 3, s_2_1691, 1677, 11, 0}, +{ 4, s_2_1692, 1691, 137, 0}, +{ 5, s_2_1693, 1691, 89, 0}, +{ 3, s_2_1694, -1, 120, 0}, +{ 5, s_2_1695, 1694, 68, 0}, +{ 4, s_2_1696, 1694, 69, 0}, +{ 3, s_2_1697, -1, 70, 0}, +{ 5, s_2_1698, -1, 92, 0}, +{ 5, s_2_1699, -1, 93, 0}, +{ 4, s_2_1700, -1, 94, 0}, +{ 4, s_2_1701, -1, 71, 0}, +{ 4, s_2_1702, -1, 72, 0}, +{ 4, s_2_1703, -1, 73, 0}, +{ 4, s_2_1704, -1, 74, 0}, +{ 4, s_2_1705, -1, 13, 0}, +{ 3, s_2_1706, -1, 13, 0}, +{ 3, s_2_1707, -1, 77, 0}, +{ 3, s_2_1708, -1, 78, 0}, +{ 3, s_2_1709, -1, 79, 0}, +{ 3, s_2_1710, -1, 80, 0}, +{ 4, s_2_1711, -1, 3, 0}, +{ 5, s_2_1712, -1, 4, 0}, +{ 2, s_2_1713, -1, 161, 0}, +{ 4, s_2_1714, 1713, 128, 0}, +{ 4, s_2_1715, 1713, 155, 0}, +{ 4, s_2_1716, 1713, 156, 0}, +{ 3, s_2_1717, 1713, 160, 0}, +{ 4, s_2_1718, 1713, 144, 0}, +{ 4, s_2_1719, 1713, 145, 0}, +{ 4, s_2_1720, 1713, 146, 0}, +{ 4, s_2_1721, 1713, 147, 0}, +{ 2, s_2_1722, -1, 163, 0}, +{ 7, s_2_1723, 1722, 141, 0}, +{ 7, s_2_1724, 1722, 142, 0}, +{ 7, s_2_1725, 1722, 143, 0}, +{ 7, s_2_1726, 1722, 138, 0}, +{ 7, s_2_1727, 1722, 139, 0}, +{ 7, s_2_1728, 1722, 140, 0}, +{ 4, s_2_1729, 1722, 162, 0}, +{ 5, s_2_1730, 1722, 150, 0}, +{ 4, s_2_1731, 1722, 157, 0}, +{ 7, s_2_1732, 1731, 121, 0}, +{ 6, s_2_1733, 1731, 155, 0}, +{ 3, s_2_1734, 1722, 164, 0}, +{ 7, s_2_1735, 1734, 141, 0}, +{ 7, s_2_1736, 1734, 142, 0}, +{ 7, s_2_1737, 1734, 143, 0}, +{ 4, s_2_1738, 1722, 153, 0}, +{ 5, s_2_1739, 1722, 136, 0}, +{ 2, s_2_1740, -1, 162, 0}, +{ 4, s_2_1741, 1740, 124, 0}, +{ 5, s_2_1742, 1740, 121, 0}, +{ 3, s_2_1743, 1740, 158, 0}, +{ 5, s_2_1744, 1740, 127, 0}, +{ 5, s_2_1745, 1740, 149, 0}, +{ 2, s_2_1746, -1, 104, 0}, +{ 4, s_2_1747, 1746, 128, 0}, +{ 7, s_2_1748, 1746, 106, 0}, +{ 7, s_2_1749, 1746, 107, 0}, +{ 7, s_2_1750, 1746, 108, 0}, +{ 5, s_2_1751, 1746, 114, 0}, +{ 4, s_2_1752, 1746, 100, 0}, +{ 4, s_2_1753, 1746, 105, 0}, +{ 3, s_2_1754, 1746, 113, 0}, +{ 5, s_2_1755, 1754, 110, 0}, +{ 5, s_2_1756, 1754, 111, 0}, +{ 5, s_2_1757, 1754, 112, 0}, +{ 4, s_2_1758, 1746, 97, 0}, +{ 4, s_2_1759, 1746, 96, 0}, +{ 4, s_2_1760, 1746, 98, 0}, +{ 6, s_2_1761, 1760, 100, 0}, +{ 4, s_2_1762, 1746, 76, 0}, +{ 4, s_2_1763, 1746, 99, 0}, +{ 5, s_2_1764, 1746, 102, 0}, +{ 2, s_2_1765, -1, 116, 0}, +{ 4, s_2_1766, 1765, 124, 0}, +{ 5, s_2_1767, 1765, 121, 0}, +{ 5, s_2_1768, 1765, 127, 0}, +{ 5, s_2_1769, 1765, 118, 0}, +{ 5, s_2_1770, 1765, 101, 0}, +{ 6, s_2_1771, 1765, 117, 0}, +{ 6, s_2_1772, 1765, 90, 0}, +{ 3, s_2_1773, -1, 13, 0}, +{ 6, s_2_1774, -1, 110, 0}, +{ 6, s_2_1775, -1, 111, 0}, +{ 6, s_2_1776, -1, 112, 0}, +{ 2, s_2_1777, -1, 20, 0}, +{ 4, s_2_1778, 1777, 19, 0}, +{ 3, s_2_1779, 1777, 18, 0}, +{ 3, s_2_1780, -1, 104, 0}, +{ 5, s_2_1781, 1780, 128, 0}, +{ 8, s_2_1782, 1780, 106, 0}, +{ 8, s_2_1783, 1780, 107, 0}, +{ 8, s_2_1784, 1780, 108, 0}, +{ 6, s_2_1785, 1780, 114, 0}, +{ 5, s_2_1786, 1780, 100, 0}, +{ 5, s_2_1787, 1780, 105, 0}, +{ 5, s_2_1788, 1780, 97, 0}, +{ 5, s_2_1789, 1780, 96, 0}, +{ 5, s_2_1790, 1780, 98, 0}, +{ 5, s_2_1791, 1780, 76, 0}, +{ 5, s_2_1792, 1780, 99, 0}, +{ 6, s_2_1793, 1780, 102, 0}, +{ 3, s_2_1794, -1, 104, 0}, +{ 4, s_2_1795, 1794, 26, 0}, +{ 5, s_2_1796, 1795, 128, 0}, +{ 4, s_2_1797, 1794, 30, 0}, +{ 4, s_2_1798, 1794, 31, 0}, +{ 5, s_2_1799, 1798, 100, 0}, +{ 5, s_2_1800, 1798, 105, 0}, +{ 4, s_2_1801, 1794, 113, 0}, +{ 6, s_2_1802, 1801, 106, 0}, +{ 6, s_2_1803, 1801, 107, 0}, +{ 6, s_2_1804, 1801, 108, 0}, +{ 5, s_2_1805, 1794, 97, 0}, +{ 5, s_2_1806, 1794, 96, 0}, +{ 5, s_2_1807, 1794, 98, 0}, +{ 5, s_2_1808, 1794, 99, 0}, +{ 5, s_2_1809, 1794, 28, 0}, +{ 5, s_2_1810, 1794, 27, 0}, +{ 6, s_2_1811, 1810, 102, 0}, +{ 5, s_2_1812, 1794, 29, 0}, +{ 3, s_2_1813, -1, 116, 0}, +{ 4, s_2_1814, 1813, 32, 0}, +{ 4, s_2_1815, 1813, 33, 0}, +{ 4, s_2_1816, 1813, 34, 0}, +{ 4, s_2_1817, 1813, 40, 0}, +{ 4, s_2_1818, 1813, 39, 0}, +{ 6, s_2_1819, 1813, 84, 0}, +{ 6, s_2_1820, 1813, 85, 0}, +{ 6, s_2_1821, 1813, 122, 0}, +{ 7, s_2_1822, 1813, 86, 0}, +{ 4, s_2_1823, 1813, 95, 0}, +{ 4, s_2_1824, 1813, 24, 0}, +{ 5, s_2_1825, 1824, 83, 0}, +{ 4, s_2_1826, 1813, 37, 0}, +{ 4, s_2_1827, 1813, 13, 0}, +{ 6, s_2_1828, 1827, 9, 0}, +{ 6, s_2_1829, 1827, 6, 0}, +{ 6, s_2_1830, 1827, 7, 0}, +{ 6, s_2_1831, 1827, 8, 0}, +{ 6, s_2_1832, 1827, 5, 0}, +{ 4, s_2_1833, 1813, 41, 0}, +{ 4, s_2_1834, 1813, 42, 0}, +{ 6, s_2_1835, 1834, 21, 0}, +{ 4, s_2_1836, 1813, 23, 0}, +{ 5, s_2_1837, 1836, 123, 0}, +{ 4, s_2_1838, 1813, 44, 0}, +{ 5, s_2_1839, 1838, 120, 0}, +{ 5, s_2_1840, 1838, 22, 0}, +{ 5, s_2_1841, 1813, 77, 0}, +{ 5, s_2_1842, 1813, 78, 0}, +{ 5, s_2_1843, 1813, 79, 0}, +{ 5, s_2_1844, 1813, 80, 0}, +{ 4, s_2_1845, 1813, 45, 0}, +{ 6, s_2_1846, 1813, 91, 0}, +{ 5, s_2_1847, 1813, 38, 0}, +{ 4, s_2_1848, -1, 84, 0}, +{ 4, s_2_1849, -1, 85, 0}, +{ 4, s_2_1850, -1, 122, 0}, +{ 5, s_2_1851, -1, 86, 0}, +{ 3, s_2_1852, -1, 25, 0}, +{ 6, s_2_1853, 1852, 121, 0}, +{ 5, s_2_1854, 1852, 100, 0}, +{ 7, s_2_1855, 1852, 117, 0}, +{ 2, s_2_1856, -1, 95, 0}, +{ 3, s_2_1857, 1856, 1, 0}, +{ 4, s_2_1858, 1856, 2, 0}, +{ 3, s_2_1859, -1, 104, 0}, +{ 5, s_2_1860, 1859, 47, 0}, +{ 4, s_2_1861, 1859, 46, 0}, +{ 3, s_2_1862, -1, 83, 0}, +{ 3, s_2_1863, -1, 116, 0}, +{ 5, s_2_1864, 1863, 48, 0}, +{ 3, s_2_1865, -1, 50, 0}, +{ 4, s_2_1866, -1, 52, 0}, +{ 5, s_2_1867, -1, 124, 0}, +{ 5, s_2_1868, -1, 125, 0}, +{ 5, s_2_1869, -1, 126, 0}, +{ 8, s_2_1870, -1, 84, 0}, +{ 8, s_2_1871, -1, 85, 0}, +{ 8, s_2_1872, -1, 122, 0}, +{ 9, s_2_1873, -1, 86, 0}, +{ 6, s_2_1874, -1, 95, 0}, +{ 7, s_2_1875, 1874, 1, 0}, +{ 8, s_2_1876, 1874, 2, 0}, +{ 7, s_2_1877, -1, 83, 0}, +{ 6, s_2_1878, -1, 13, 0}, +{ 7, s_2_1879, -1, 123, 0}, +{ 7, s_2_1880, -1, 120, 0}, +{ 9, s_2_1881, -1, 92, 0}, +{ 9, s_2_1882, -1, 93, 0}, +{ 8, s_2_1883, -1, 94, 0}, +{ 7, s_2_1884, -1, 77, 0}, +{ 7, s_2_1885, -1, 78, 0}, +{ 7, s_2_1886, -1, 79, 0}, +{ 7, s_2_1887, -1, 80, 0}, +{ 8, s_2_1888, -1, 91, 0}, +{ 6, s_2_1889, -1, 84, 0}, +{ 6, s_2_1890, -1, 85, 0}, +{ 6, s_2_1891, -1, 122, 0}, +{ 7, s_2_1892, -1, 86, 0}, +{ 4, s_2_1893, -1, 95, 0}, +{ 5, s_2_1894, 1893, 1, 0}, +{ 6, s_2_1895, 1893, 2, 0}, +{ 4, s_2_1896, -1, 51, 0}, +{ 5, s_2_1897, 1896, 83, 0}, +{ 4, s_2_1898, -1, 13, 0}, +{ 5, s_2_1899, 1898, 10, 0}, +{ 5, s_2_1900, 1898, 87, 0}, +{ 5, s_2_1901, 1898, 159, 0}, +{ 6, s_2_1902, 1898, 88, 0}, +{ 5, s_2_1903, -1, 123, 0}, +{ 5, s_2_1904, -1, 120, 0}, +{ 7, s_2_1905, -1, 92, 0}, +{ 7, s_2_1906, -1, 93, 0}, +{ 6, s_2_1907, -1, 94, 0}, +{ 5, s_2_1908, -1, 77, 0}, +{ 5, s_2_1909, -1, 78, 0}, +{ 5, s_2_1910, -1, 79, 0}, +{ 5, s_2_1911, -1, 80, 0}, +{ 6, s_2_1912, -1, 14, 0}, +{ 6, s_2_1913, -1, 15, 0}, +{ 6, s_2_1914, -1, 16, 0}, +{ 6, s_2_1915, -1, 91, 0}, +{ 5, s_2_1916, -1, 124, 0}, +{ 5, s_2_1917, -1, 125, 0}, +{ 5, s_2_1918, -1, 126, 0}, +{ 6, s_2_1919, -1, 84, 0}, +{ 6, s_2_1920, -1, 85, 0}, +{ 6, s_2_1921, -1, 122, 0}, +{ 7, s_2_1922, -1, 86, 0}, +{ 4, s_2_1923, -1, 95, 0}, +{ 5, s_2_1924, 1923, 1, 0}, +{ 6, s_2_1925, 1923, 2, 0}, +{ 5, s_2_1926, -1, 83, 0}, +{ 4, s_2_1927, -1, 13, 0}, +{ 6, s_2_1928, 1927, 137, 0}, +{ 7, s_2_1929, 1927, 89, 0}, +{ 5, s_2_1930, -1, 123, 0}, +{ 5, s_2_1931, -1, 120, 0}, +{ 7, s_2_1932, -1, 92, 0}, +{ 7, s_2_1933, -1, 93, 0}, +{ 6, s_2_1934, -1, 94, 0}, +{ 5, s_2_1935, -1, 77, 0}, +{ 5, s_2_1936, -1, 78, 0}, +{ 5, s_2_1937, -1, 79, 0}, +{ 5, s_2_1938, -1, 80, 0}, +{ 6, s_2_1939, -1, 14, 0}, +{ 6, s_2_1940, -1, 15, 0}, +{ 6, s_2_1941, -1, 16, 0}, +{ 6, s_2_1942, -1, 91, 0}, +{ 2, s_2_1943, -1, 13, 0}, +{ 3, s_2_1944, 1943, 10, 0}, +{ 6, s_2_1945, 1944, 110, 0}, +{ 6, s_2_1946, 1944, 111, 0}, +{ 6, s_2_1947, 1944, 112, 0}, +{ 3, s_2_1948, 1943, 11, 0}, +{ 4, s_2_1949, 1948, 137, 0}, +{ 5, s_2_1950, 1948, 10, 0}, +{ 5, s_2_1951, 1948, 89, 0}, +{ 3, s_2_1952, 1943, 12, 0}, +{ 3, s_2_1953, -1, 53, 0}, +{ 3, s_2_1954, -1, 54, 0}, +{ 3, s_2_1955, -1, 55, 0}, +{ 3, s_2_1956, -1, 56, 0}, +{ 4, s_2_1957, -1, 135, 0}, +{ 4, s_2_1958, -1, 131, 0}, +{ 4, s_2_1959, -1, 129, 0}, +{ 4, s_2_1960, -1, 133, 0}, +{ 4, s_2_1961, -1, 132, 0}, +{ 4, s_2_1962, -1, 130, 0}, +{ 4, s_2_1963, -1, 134, 0}, +{ 3, s_2_1964, -1, 57, 0}, +{ 3, s_2_1965, -1, 58, 0}, +{ 3, s_2_1966, -1, 123, 0}, +{ 3, s_2_1967, -1, 120, 0}, +{ 5, s_2_1968, 1967, 68, 0}, +{ 4, s_2_1969, 1967, 69, 0}, +{ 3, s_2_1970, -1, 70, 0}, +{ 5, s_2_1971, -1, 92, 0}, +{ 5, s_2_1972, -1, 93, 0}, +{ 4, s_2_1973, -1, 94, 0}, +{ 4, s_2_1974, -1, 71, 0}, +{ 4, s_2_1975, -1, 72, 0}, +{ 4, s_2_1976, -1, 73, 0}, +{ 4, s_2_1977, -1, 74, 0}, +{ 5, s_2_1978, -1, 75, 0}, +{ 3, s_2_1979, -1, 77, 0}, +{ 3, s_2_1980, -1, 78, 0}, +{ 3, s_2_1981, -1, 79, 0}, +{ 3, s_2_1982, -1, 80, 0}, +{ 4, s_2_1983, 1982, 82, 0}, +{ 4, s_2_1984, 1982, 81, 0}, +{ 4, s_2_1985, -1, 3, 0}, +{ 5, s_2_1986, -1, 4, 0}, +{ 5, s_2_1987, -1, 63, 0}, +{ 5, s_2_1988, -1, 64, 0}, +{ 5, s_2_1989, -1, 61, 0}, +{ 5, s_2_1990, -1, 62, 0}, +{ 5, s_2_1991, -1, 60, 0}, +{ 5, s_2_1992, -1, 59, 0}, +{ 5, s_2_1993, -1, 65, 0}, +{ 4, s_2_1994, -1, 66, 0}, +{ 4, s_2_1995, -1, 67, 0}, +{ 4, s_2_1996, -1, 91, 0}, +{ 4, s_2_1997, -1, 97, 0}, +{ 4, s_2_1998, -1, 96, 0}, +{ 4, s_2_1999, -1, 98, 0}, +{ 4, s_2_2000, -1, 99, 0}, +{ 3, s_2_2001, -1, 95, 0}, +{ 3, s_2_2002, -1, 104, 0}, +{ 5, s_2_2003, 2002, 100, 0}, +{ 5, s_2_2004, 2002, 105, 0}, +{ 4, s_2_2005, 2002, 113, 0}, +{ 5, s_2_2006, 2002, 97, 0}, +{ 5, s_2_2007, 2002, 96, 0}, +{ 5, s_2_2008, 2002, 98, 0}, +{ 5, s_2_2009, 2002, 99, 0}, +{ 6, s_2_2010, 2002, 102, 0}, +{ 3, s_2_2011, -1, 119, 0}, +{ 8, s_2_2012, 2011, 110, 0}, +{ 8, s_2_2013, 2011, 111, 0}, +{ 8, s_2_2014, 2011, 112, 0}, +{ 8, s_2_2015, 2011, 106, 0}, +{ 8, s_2_2016, 2011, 107, 0}, +{ 8, s_2_2017, 2011, 108, 0}, +{ 5, s_2_2018, 2011, 116, 0}, +{ 6, s_2_2019, 2011, 114, 0}, +{ 5, s_2_2020, 2011, 25, 0}, +{ 7, s_2_2021, 2020, 100, 0}, +{ 9, s_2_2022, 2020, 117, 0}, +{ 4, s_2_2023, 2011, 13, 0}, +{ 8, s_2_2024, 2023, 110, 0}, +{ 8, s_2_2025, 2023, 111, 0}, +{ 8, s_2_2026, 2023, 112, 0}, +{ 5, s_2_2027, 2011, 70, 0}, +{ 6, s_2_2028, 2011, 115, 0}, +{ 3, s_2_2029, -1, 116, 0}, +{ 4, s_2_2030, 2029, 103, 0}, +{ 6, s_2_2031, 2029, 118, 0}, +{ 6, s_2_2032, 2029, 101, 0}, +{ 7, s_2_2033, 2029, 117, 0}, +{ 7, s_2_2034, 2029, 90, 0} +}; + +static const symbol s_3_0[1] = { 'a' }; +static const symbol s_3_1[3] = { 'o', 'g', 'a' }; +static const symbol s_3_2[3] = { 'a', 'm', 'a' }; +static const symbol s_3_3[3] = { 'i', 'm', 'a' }; +static const symbol s_3_4[3] = { 'e', 'n', 'a' }; +static const symbol s_3_5[1] = { 'e' }; +static const symbol s_3_6[2] = { 'o', 'g' }; +static const symbol s_3_7[4] = { 'a', 'n', 'o', 'g' }; +static const symbol s_3_8[4] = { 'e', 'n', 'o', 'g' }; +static const symbol s_3_9[4] = { 'a', 'n', 'i', 'h' }; +static const symbol s_3_10[4] = { 'e', 'n', 'i', 'h' }; +static const symbol s_3_11[1] = { 'i' }; +static const symbol s_3_12[3] = { 'a', 'n', 'i' }; +static const symbol s_3_13[3] = { 'e', 'n', 'i' }; +static const symbol s_3_14[4] = { 'a', 'n', 'o', 'j' }; +static const symbol s_3_15[4] = { 'e', 'n', 'o', 'j' }; +static const symbol s_3_16[4] = { 'a', 'n', 'i', 'm' }; +static const symbol s_3_17[4] = { 'e', 'n', 'i', 'm' }; +static const symbol s_3_18[2] = { 'o', 'm' }; +static const symbol s_3_19[4] = { 'e', 'n', 'o', 'm' }; +static const symbol s_3_20[1] = { 'o' }; +static const symbol s_3_21[3] = { 'a', 'n', 'o' }; +static const symbol s_3_22[3] = { 'e', 'n', 'o' }; +static const symbol s_3_23[3] = { 'o', 's', 't' }; +static const symbol s_3_24[1] = { 'u' }; +static const symbol s_3_25[3] = { 'e', 'n', 'u' }; + +static const struct among a_3[26] = +{ +{ 1, s_3_0, -1, 1, 0}, +{ 3, s_3_1, 0, 1, 0}, +{ 3, s_3_2, 0, 1, 0}, +{ 3, s_3_3, 0, 1, 0}, +{ 3, s_3_4, 0, 1, 0}, +{ 1, s_3_5, -1, 1, 0}, +{ 2, s_3_6, -1, 1, 0}, +{ 4, s_3_7, 6, 1, 0}, +{ 4, s_3_8, 6, 1, 0}, +{ 4, s_3_9, -1, 1, 0}, +{ 4, s_3_10, -1, 1, 0}, +{ 1, s_3_11, -1, 1, 0}, +{ 3, s_3_12, 11, 1, 0}, +{ 3, s_3_13, 11, 1, 0}, +{ 4, s_3_14, -1, 1, 0}, +{ 4, s_3_15, -1, 1, 0}, +{ 4, s_3_16, -1, 1, 0}, +{ 4, s_3_17, -1, 1, 0}, +{ 2, s_3_18, -1, 1, 0}, +{ 4, s_3_19, 18, 1, 0}, +{ 1, s_3_20, -1, 1, 0}, +{ 3, s_3_21, 20, 1, 0}, +{ 3, s_3_22, 20, 1, 0}, +{ 3, s_3_23, -1, 1, 0}, +{ 1, s_3_24, -1, 1, 0}, +{ 3, s_3_25, 24, 1, 0} +}; + +static const unsigned char g_v[] = { 17, 65, 16 }; + +static const unsigned char g_sa[] = { 65, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 128 }; + +static const unsigned char g_ca[] = { 119, 95, 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 16 }; + +static const unsigned char g_rg[] = { 1 }; + +static const symbol s_0[] = { 'a' }; +static const symbol s_1[] = { 'b' }; +static const symbol s_2[] = { 'v' }; +static const symbol s_3[] = { 'g' }; +static const symbol s_4[] = { 'd' }; +static const symbol s_5[] = { 0xC4, 0x91 }; +static const symbol s_6[] = { 'e' }; +static const symbol s_7[] = { 0xC5, 0xBE }; +static const symbol s_8[] = { 'z' }; +static const symbol s_9[] = { 'i' }; +static const symbol s_10[] = { 'j' }; +static const symbol s_11[] = { 'k' }; +static const symbol s_12[] = { 'l' }; +static const symbol s_13[] = { 'l', 'j' }; +static const symbol s_14[] = { 'm' }; +static const symbol s_15[] = { 'n' }; +static const symbol s_16[] = { 'n', 'j' }; +static const symbol s_17[] = { 'o' }; +static const symbol s_18[] = { 'p' }; +static const symbol s_19[] = { 'r' }; +static const symbol s_20[] = { 's' }; +static const symbol s_21[] = { 't' }; +static const symbol s_22[] = { 0xC4, 0x87 }; +static const symbol s_23[] = { 'u' }; +static const symbol s_24[] = { 'f' }; +static const symbol s_25[] = { 'h' }; +static const symbol s_26[] = { 'c' }; +static const symbol s_27[] = { 0xC4, 0x8D }; +static const symbol s_28[] = { 'd', 0xC5, 0xBE }; +static const symbol s_29[] = { 0xC5, 0xA1 }; +static const symbol s_30[] = { 'i', 'j', 'e' }; +static const symbol s_31[] = { 'e' }; +static const symbol s_32[] = { 'j', 'e' }; +static const symbol s_33[] = { 'e' }; +static const symbol s_34[] = { 'd', 'j' }; +static const symbol s_35[] = { 0xC4, 0x91 }; +static const symbol s_36[] = { 'l', 'o', 'g', 'a' }; +static const symbol s_37[] = { 'p', 'e', 'h' }; +static const symbol s_38[] = { 'v', 'o', 'j', 'k', 'a' }; +static const symbol s_39[] = { 'b', 'o', 'j', 'k', 'a' }; +static const symbol s_40[] = { 'j', 'a', 'k' }; +static const symbol s_41[] = { 0xC4, 0x8D, 'a', 'j', 'n', 'i' }; +static const symbol s_42[] = { 'c', 'a', 'j', 'n', 'i' }; +static const symbol s_43[] = { 'e', 'r', 'n', 'i' }; +static const symbol s_44[] = { 'l', 'a', 'r', 'n', 'i' }; +static const symbol s_45[] = { 'e', 's', 'n', 'i' }; +static const symbol s_46[] = { 'a', 'n', 'j', 'c', 'a' }; +static const symbol s_47[] = { 'a', 'j', 'c', 'a' }; +static const symbol s_48[] = { 'l', 'j', 'c', 'a' }; +static const symbol s_49[] = { 'e', 'j', 'c', 'a' }; +static const symbol s_50[] = { 'o', 'j', 'c', 'a' }; +static const symbol s_51[] = { 'a', 'j', 'k', 'a' }; +static const symbol s_52[] = { 'o', 'j', 'k', 'a' }; +static const symbol s_53[] = { 0xC5, 0xA1, 'c', 'a' }; +static const symbol s_54[] = { 'i', 'n', 'g' }; +static const symbol s_55[] = { 't', 'v', 'e', 'n', 'i', 'k' }; +static const symbol s_56[] = { 't', 'e', 't', 'i', 'k', 'a' }; +static const symbol s_57[] = { 'n', 's', 't', 'v', 'a' }; +static const symbol s_58[] = { 'n', 'i', 'k' }; +static const symbol s_59[] = { 't', 'i', 'k' }; +static const symbol s_60[] = { 'z', 'i', 'k' }; +static const symbol s_61[] = { 's', 'n', 'i', 'k' }; +static const symbol s_62[] = { 'k', 'u', 's', 'i' }; +static const symbol s_63[] = { 'k', 'u', 's', 'n', 'i' }; +static const symbol s_64[] = { 'k', 'u', 's', 't', 'v', 'a' }; +static const symbol s_65[] = { 'd', 'u', 0xC5, 0xA1, 'n', 'i' }; +static const symbol s_66[] = { 'd', 'u', 's', 'n', 'i' }; +static const symbol s_67[] = { 'a', 'n', 't', 'n', 'i' }; +static const symbol s_68[] = { 'b', 'i', 'l', 'n', 'i' }; +static const symbol s_69[] = { 't', 'i', 'l', 'n', 'i' }; +static const symbol s_70[] = { 'a', 'v', 'i', 'l', 'n', 'i' }; +static const symbol s_71[] = { 's', 'i', 'l', 'n', 'i' }; +static const symbol s_72[] = { 'g', 'i', 'l', 'n', 'i' }; +static const symbol s_73[] = { 'r', 'i', 'l', 'n', 'i' }; +static const symbol s_74[] = { 'n', 'i', 'l', 'n', 'i' }; +static const symbol s_75[] = { 'a', 'l', 'n', 'i' }; +static const symbol s_76[] = { 'o', 'z', 'n', 'i' }; +static const symbol s_77[] = { 'r', 'a', 'v', 'i' }; +static const symbol s_78[] = { 's', 't', 'a', 'v', 'n', 'i' }; +static const symbol s_79[] = { 'p', 'r', 'a', 'v', 'n', 'i' }; +static const symbol s_80[] = { 't', 'i', 'v', 'n', 'i' }; +static const symbol s_81[] = { 's', 'i', 'v', 'n', 'i' }; +static const symbol s_82[] = { 'a', 't', 'n', 'i' }; +static const symbol s_83[] = { 'e', 'n', 't', 'a' }; +static const symbol s_84[] = { 't', 'e', 't', 'n', 'i' }; +static const symbol s_85[] = { 'p', 'l', 'e', 't', 'n', 'i' }; +static const symbol s_86[] = { 0xC5, 0xA1, 'a', 'v', 'i' }; +static const symbol s_87[] = { 's', 'a', 'v', 'i' }; +static const symbol s_88[] = { 'a', 'n', 't', 'a' }; +static const symbol s_89[] = { 'a', 0xC4, 0x8D, 'k', 'a' }; +static const symbol s_90[] = { 'a', 'c', 'k', 'a' }; +static const symbol s_91[] = { 'u', 0xC5, 0xA1, 'k', 'a' }; +static const symbol s_92[] = { 'u', 's', 'k', 'a' }; +static const symbol s_93[] = { 'a', 't', 'k', 'a' }; +static const symbol s_94[] = { 'e', 't', 'k', 'a' }; +static const symbol s_95[] = { 'i', 't', 'k', 'a' }; +static const symbol s_96[] = { 'o', 't', 'k', 'a' }; +static const symbol s_97[] = { 'u', 't', 'k', 'a' }; +static const symbol s_98[] = { 'e', 's', 'k', 'n', 'a' }; +static const symbol s_99[] = { 't', 'i', 0xC4, 0x8D, 'n', 'i' }; +static const symbol s_100[] = { 't', 'i', 'c', 'n', 'i' }; +static const symbol s_101[] = { 'o', 'j', 's', 'k', 'a' }; +static const symbol s_102[] = { 'e', 's', 'm', 'a' }; +static const symbol s_103[] = { 'm', 'e', 't', 'r', 'a' }; +static const symbol s_104[] = { 'c', 'e', 'n', 't', 'r', 'a' }; +static const symbol s_105[] = { 'i', 's', 't', 'r', 'a' }; +static const symbol s_106[] = { 'o', 's', 't', 'i' }; +static const symbol s_107[] = { 'o', 's', 't', 'i' }; +static const symbol s_108[] = { 'd', 'b', 'a' }; +static const symbol s_109[] = { 0xC4, 0x8D, 'k', 'a' }; +static const symbol s_110[] = { 'm', 'c', 'a' }; +static const symbol s_111[] = { 'n', 'c', 'a' }; +static const symbol s_112[] = { 'v', 'o', 'l', 'j', 'n', 'i' }; +static const symbol s_113[] = { 'a', 'n', 'k', 'i' }; +static const symbol s_114[] = { 'v', 'c', 'a' }; +static const symbol s_115[] = { 's', 'c', 'a' }; +static const symbol s_116[] = { 'r', 'c', 'a' }; +static const symbol s_117[] = { 'a', 'l', 'c', 'a' }; +static const symbol s_118[] = { 'e', 'l', 'c', 'a' }; +static const symbol s_119[] = { 'o', 'l', 'c', 'a' }; +static const symbol s_120[] = { 'n', 'j', 'c', 'a' }; +static const symbol s_121[] = { 'e', 'k', 't', 'a' }; +static const symbol s_122[] = { 'i', 'z', 'm', 'a' }; +static const symbol s_123[] = { 'j', 'e', 'b', 'i' }; +static const symbol s_124[] = { 'b', 'a', 'c', 'i' }; +static const symbol s_125[] = { 'a', 0xC5, 0xA1, 'n', 'i' }; +static const symbol s_126[] = { 'a', 's', 'n', 'i' }; +static const symbol s_127[] = { 's', 'k' }; +static const symbol s_128[] = { 0xC5, 0xA1, 'k' }; +static const symbol s_129[] = { 's', 't', 'v' }; +static const symbol s_130[] = { 0xC5, 0xA1, 't', 'v' }; +static const symbol s_131[] = { 't', 'a', 'n', 'i', 'j' }; +static const symbol s_132[] = { 'm', 'a', 'n', 'i', 'j' }; +static const symbol s_133[] = { 'p', 'a', 'n', 'i', 'j' }; +static const symbol s_134[] = { 'r', 'a', 'n', 'i', 'j' }; +static const symbol s_135[] = { 'g', 'a', 'n', 'i', 'j' }; +static const symbol s_136[] = { 'a', 'n' }; +static const symbol s_137[] = { 'i', 'n' }; +static const symbol s_138[] = { 'o', 'n' }; +static const symbol s_139[] = { 'n' }; +static const symbol s_140[] = { 'a', 0xC4, 0x87 }; +static const symbol s_141[] = { 'e', 0xC4, 0x87 }; +static const symbol s_142[] = { 'u', 0xC4, 0x87 }; +static const symbol s_143[] = { 'u', 'g', 'o', 'v' }; +static const symbol s_144[] = { 'u', 'g' }; +static const symbol s_145[] = { 'l', 'o', 'g' }; +static const symbol s_146[] = { 'g' }; +static const symbol s_147[] = { 'r', 'a', 'r', 'i' }; +static const symbol s_148[] = { 'o', 't', 'i' }; +static const symbol s_149[] = { 's', 'i' }; +static const symbol s_150[] = { 'l', 'i' }; +static const symbol s_151[] = { 'u', 'j' }; +static const symbol s_152[] = { 'c', 'a', 'j' }; +static const symbol s_153[] = { 0xC4, 0x8D, 'a', 'j' }; +static const symbol s_154[] = { 0xC4, 0x87, 'a', 'j' }; +static const symbol s_155[] = { 0xC4, 0x91, 'a', 'j' }; +static const symbol s_156[] = { 'l', 'a', 'j' }; +static const symbol s_157[] = { 'r', 'a', 'j' }; +static const symbol s_158[] = { 'b', 'i', 'j' }; +static const symbol s_159[] = { 'c', 'i', 'j' }; +static const symbol s_160[] = { 'd', 'i', 'j' }; +static const symbol s_161[] = { 'l', 'i', 'j' }; +static const symbol s_162[] = { 'n', 'i', 'j' }; +static const symbol s_163[] = { 'm', 'i', 'j' }; +static const symbol s_164[] = { 0xC5, 0xBE, 'i', 'j' }; +static const symbol s_165[] = { 'g', 'i', 'j' }; +static const symbol s_166[] = { 'f', 'i', 'j' }; +static const symbol s_167[] = { 'p', 'i', 'j' }; +static const symbol s_168[] = { 'r', 'i', 'j' }; +static const symbol s_169[] = { 's', 'i', 'j' }; +static const symbol s_170[] = { 't', 'i', 'j' }; +static const symbol s_171[] = { 'z', 'i', 'j' }; +static const symbol s_172[] = { 'n', 'a', 'l' }; +static const symbol s_173[] = { 'i', 'j', 'a', 'l' }; +static const symbol s_174[] = { 'o', 'z', 'i', 'l' }; +static const symbol s_175[] = { 'o', 'l', 'o', 'v' }; +static const symbol s_176[] = { 'o', 'l' }; +static const symbol s_177[] = { 'l', 'e', 'm' }; +static const symbol s_178[] = { 'r', 'a', 'm' }; +static const symbol s_179[] = { 'a', 'r' }; +static const symbol s_180[] = { 'd', 'r' }; +static const symbol s_181[] = { 'e', 'r' }; +static const symbol s_182[] = { 'o', 'r' }; +static const symbol s_183[] = { 'e', 's' }; +static const symbol s_184[] = { 'i', 's' }; +static const symbol s_185[] = { 't', 'a', 0xC5, 0xA1 }; +static const symbol s_186[] = { 'n', 'a', 0xC5, 0xA1 }; +static const symbol s_187[] = { 'j', 'a', 0xC5, 0xA1 }; +static const symbol s_188[] = { 'k', 'a', 0xC5, 0xA1 }; +static const symbol s_189[] = { 'b', 'a', 0xC5, 0xA1 }; +static const symbol s_190[] = { 'g', 'a', 0xC5, 0xA1 }; +static const symbol s_191[] = { 'v', 'a', 0xC5, 0xA1 }; +static const symbol s_192[] = { 'e', 0xC5, 0xA1 }; +static const symbol s_193[] = { 'i', 0xC5, 0xA1 }; +static const symbol s_194[] = { 'i', 'k', 'a', 't' }; +static const symbol s_195[] = { 'l', 'a', 't' }; +static const symbol s_196[] = { 'e', 't' }; +static const symbol s_197[] = { 'e', 's', 't' }; +static const symbol s_198[] = { 'i', 's', 't' }; +static const symbol s_199[] = { 'k', 's', 't' }; +static const symbol s_200[] = { 'o', 's', 't' }; +static const symbol s_201[] = { 'i', 0xC5, 0xA1, 't' }; +static const symbol s_202[] = { 'o', 'v', 'a' }; +static const symbol s_203[] = { 'a', 'v' }; +static const symbol s_204[] = { 'e', 'v' }; +static const symbol s_205[] = { 'i', 'v' }; +static const symbol s_206[] = { 'o', 'v' }; +static const symbol s_207[] = { 'm', 'o', 'v' }; +static const symbol s_208[] = { 'l', 'o', 'v' }; +static const symbol s_209[] = { 'e', 'l' }; +static const symbol s_210[] = { 'a', 'n', 'j' }; +static const symbol s_211[] = { 'e', 'n', 'j' }; +static const symbol s_212[] = { 0xC5, 0xA1, 'n', 'j' }; +static const symbol s_213[] = { 'e', 'n' }; +static const symbol s_214[] = { 0xC5, 0xA1, 'n' }; +static const symbol s_215[] = { 0xC4, 0x8D, 'i', 'n' }; +static const symbol s_216[] = { 'r', 'o', 0xC5, 0xA1, 'i' }; +static const symbol s_217[] = { 'o', 0xC5, 0xA1 }; +static const symbol s_218[] = { 'e', 'v', 'i', 't' }; +static const symbol s_219[] = { 'o', 'v', 'i', 't' }; +static const symbol s_220[] = { 'a', 's', 't' }; +static const symbol s_221[] = { 'k' }; +static const symbol s_222[] = { 'e', 'v', 'a' }; +static const symbol s_223[] = { 'a', 'v', 'a' }; +static const symbol s_224[] = { 'i', 'v', 'a' }; +static const symbol s_225[] = { 'u', 'v', 'a' }; +static const symbol s_226[] = { 'i', 'r' }; +static const symbol s_227[] = { 'a', 0xC4, 0x8D }; +static const symbol s_228[] = { 'a', 0xC4, 0x8D, 'a' }; +static const symbol s_229[] = { 'n', 'i' }; +static const symbol s_230[] = { 'a' }; +static const symbol s_231[] = { 'u', 'r' }; +static const symbol s_232[] = { 'a', 's', 't', 'a', 'j' }; +static const symbol s_233[] = { 'i', 's', 't', 'a', 'j' }; +static const symbol s_234[] = { 'o', 's', 't', 'a', 'j' }; +static const symbol s_235[] = { 'a', 'j' }; +static const symbol s_236[] = { 'a', 's', 't', 'a' }; +static const symbol s_237[] = { 'i', 's', 't', 'a' }; +static const symbol s_238[] = { 'o', 's', 't', 'a' }; +static const symbol s_239[] = { 't', 'a' }; +static const symbol s_240[] = { 'i', 'n', 'j' }; +static const symbol s_241[] = { 'a', 's' }; +static const symbol s_242[] = { 'i' }; +static const symbol s_243[] = { 'l', 'u', 0xC4, 0x8D }; +static const symbol s_244[] = { 'j', 'e', 't', 'i' }; +static const symbol s_245[] = { 'e' }; +static const symbol s_246[] = { 'a', 't' }; +static const symbol s_247[] = { 'l', 'u', 'c' }; +static const symbol s_248[] = { 's', 'n', 'j' }; +static const symbol s_249[] = { 'o', 's' }; +static const symbol s_250[] = { 'a', 'c' }; +static const symbol s_251[] = { 'e', 'c' }; +static const symbol s_252[] = { 'u', 'c' }; +static const symbol s_253[] = { 'r', 'o', 's', 'i' }; +static const symbol s_254[] = { 'a', 'c', 'a' }; +static const symbol s_255[] = { 'j', 'a', 's' }; +static const symbol s_256[] = { 't', 'a', 's' }; +static const symbol s_257[] = { 'g', 'a', 's' }; +static const symbol s_258[] = { 'n', 'a', 's' }; +static const symbol s_259[] = { 'k', 'a', 's' }; +static const symbol s_260[] = { 'v', 'a', 's' }; +static const symbol s_261[] = { 'b', 'a', 's' }; +static const symbol s_262[] = { 'a', 's' }; +static const symbol s_263[] = { 'c', 'i', 'n' }; +static const symbol s_264[] = { 'a', 's', 't', 'a', 'j' }; +static const symbol s_265[] = { 'i', 's', 't', 'a', 'j' }; +static const symbol s_266[] = { 'o', 's', 't', 'a', 'j' }; +static const symbol s_267[] = { 'a', 's', 't', 'a' }; +static const symbol s_268[] = { 'i', 's', 't', 'a' }; +static const symbol s_269[] = { 'o', 's', 't', 'a' }; +static const symbol s_270[] = { 'a', 'v', 'a' }; +static const symbol s_271[] = { 'e', 'v', 'a' }; +static const symbol s_272[] = { 'i', 'v', 'a' }; +static const symbol s_273[] = { 'u', 'v', 'a' }; +static const symbol s_274[] = { 'o', 'v', 'a' }; +static const symbol s_275[] = { 'j', 'e', 't', 'i' }; +static const symbol s_276[] = { 'i', 'n', 'j' }; +static const symbol s_277[] = { 'i', 's', 't' }; +static const symbol s_278[] = { 'e', 's' }; +static const symbol s_279[] = { 'e', 't' }; +static const symbol s_280[] = { 'i', 's' }; +static const symbol s_281[] = { 'i', 'r' }; +static const symbol s_282[] = { 'u', 'r' }; +static const symbol s_283[] = { 'u', 'j' }; +static const symbol s_284[] = { 'n', 'i' }; +static const symbol s_285[] = { 's', 'n' }; +static const symbol s_286[] = { 't', 'a' }; +static const symbol s_287[] = { 'a' }; +static const symbol s_288[] = { 'i' }; +static const symbol s_289[] = { 'e' }; +static const symbol s_290[] = { 'n' }; + +static int r_cyr_to_lat(struct SN_env * z) { + int among_var; + { int c1 = z->c; + while(1) { + int c2 = z->c; + while(1) { + int c3 = z->c; + z->bra = z->c; + among_var = find_among(z, a_0, 30); + if (!(among_var)) goto lab2; + z->ket = z->c; + switch (among_var) { + case 1: + { int ret = slice_from_s(z, 1, s_0); + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 1, s_1); + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 1, s_2); + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 1, s_3); + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 1, s_4); + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 2, s_5); + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 1, s_6); + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 2, s_7); + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 1, s_8); + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 1, s_9); + if (ret < 0) return ret; + } + break; + case 11: + { int ret = slice_from_s(z, 1, s_10); + if (ret < 0) return ret; + } + break; + case 12: + { int ret = slice_from_s(z, 1, s_11); + if (ret < 0) return ret; + } + break; + case 13: + { int ret = slice_from_s(z, 1, s_12); + if (ret < 0) return ret; + } + break; + case 14: + { int ret = slice_from_s(z, 2, s_13); + if (ret < 0) return ret; + } + break; + case 15: + { int ret = slice_from_s(z, 1, s_14); + if (ret < 0) return ret; + } + break; + case 16: + { int ret = slice_from_s(z, 1, s_15); + if (ret < 0) return ret; + } + break; + case 17: + { int ret = slice_from_s(z, 2, s_16); + if (ret < 0) return ret; + } + break; + case 18: + { int ret = slice_from_s(z, 1, s_17); + if (ret < 0) return ret; + } + break; + case 19: + { int ret = slice_from_s(z, 1, s_18); + if (ret < 0) return ret; + } + break; + case 20: + { int ret = slice_from_s(z, 1, s_19); + if (ret < 0) return ret; + } + break; + case 21: + { int ret = slice_from_s(z, 1, s_20); + if (ret < 0) return ret; + } + break; + case 22: + { int ret = slice_from_s(z, 1, s_21); + if (ret < 0) return ret; + } + break; + case 23: + { int ret = slice_from_s(z, 2, s_22); + if (ret < 0) return ret; + } + break; + case 24: + { int ret = slice_from_s(z, 1, s_23); + if (ret < 0) return ret; + } + break; + case 25: + { int ret = slice_from_s(z, 1, s_24); + if (ret < 0) return ret; + } + break; + case 26: + { int ret = slice_from_s(z, 1, s_25); + if (ret < 0) return ret; + } + break; + case 27: + { int ret = slice_from_s(z, 1, s_26); + if (ret < 0) return ret; + } + break; + case 28: + { int ret = slice_from_s(z, 2, s_27); + if (ret < 0) return ret; + } + break; + case 29: + { int ret = slice_from_s(z, 3, s_28); + if (ret < 0) return ret; + } + break; + case 30: + { int ret = slice_from_s(z, 2, s_29); + if (ret < 0) return ret; + } + break; + } + z->c = c3; + break; + lab2: + z->c = c3; + { int ret = skip_utf8(z->p, z->c, z->l, 1); + if (ret < 0) goto lab1; + z->c = ret; + } + } + continue; + lab1: + z->c = c2; + break; + } + z->c = c1; + } + return 1; +} + +static int r_prelude(struct SN_env * z) { + { int c1 = z->c; + while(1) { + int c2 = z->c; + while(1) { + int c3 = z->c; + if (in_grouping_U(z, g_ca, 98, 382, 0)) goto lab2; + z->bra = z->c; + if (!(eq_s(z, 3, s_30))) goto lab2; + z->ket = z->c; + if (in_grouping_U(z, g_ca, 98, 382, 0)) goto lab2; + { int ret = slice_from_s(z, 1, s_31); + if (ret < 0) return ret; + } + z->c = c3; + break; + lab2: + z->c = c3; + { int ret = skip_utf8(z->p, z->c, z->l, 1); + if (ret < 0) goto lab1; + z->c = ret; + } + } + continue; + lab1: + z->c = c2; + break; + } + z->c = c1; + } + { int c4 = z->c; + while(1) { + int c5 = z->c; + while(1) { + int c6 = z->c; + if (in_grouping_U(z, g_ca, 98, 382, 0)) goto lab5; + z->bra = z->c; + if (!(eq_s(z, 2, s_32))) goto lab5; + z->ket = z->c; + if (in_grouping_U(z, g_ca, 98, 382, 0)) goto lab5; + { int ret = slice_from_s(z, 1, s_33); + if (ret < 0) return ret; + } + z->c = c6; + break; + lab5: + z->c = c6; + { int ret = skip_utf8(z->p, z->c, z->l, 1); + if (ret < 0) goto lab4; + z->c = ret; + } + } + continue; + lab4: + z->c = c5; + break; + } + z->c = c4; + } + { int c7 = z->c; + while(1) { + int c8 = z->c; + while(1) { + int c9 = z->c; + z->bra = z->c; + if (!(eq_s(z, 2, s_34))) goto lab8; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_35); + if (ret < 0) return ret; + } + z->c = c9; + break; + lab8: + z->c = c9; + { int ret = skip_utf8(z->p, z->c, z->l, 1); + if (ret < 0) goto lab7; + z->c = ret; + } + } + continue; + lab7: + z->c = c8; + break; + } + z->c = c7; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[1] = 1; + { int c1 = z->c; + { + int ret = out_grouping_U(z, g_sa, 263, 382, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + z->I[1] = 0; + lab0: + z->c = c1; + } + z->I[0] = z->l; + { int c2 = z->c; + { + int ret = out_grouping_U(z, g_v, 97, 117, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[0] = z->c; + if (!(z->I[0] < 2)) goto lab1; + { + int ret = in_grouping_U(z, g_v, 97, 117, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[0] = z->c; + lab1: + z->c = c2; + } + { int c3 = z->c; + while(1) { + if (z->c == z->l || z->p[z->c] != 'r') goto lab3; + z->c++; + break; + lab3: + { int ret = skip_utf8(z->p, z->c, z->l, 1); + if (ret < 0) goto lab2; + z->c = ret; + } + } + { int c4 = z->c; + if (!(z->c >= 2)) goto lab5; + goto lab4; + lab5: + z->c = c4; + { + int ret = in_grouping_U(z, g_rg, 114, 114, 1); + if (ret < 0) goto lab2; + z->c += ret; + } + } + lab4: + if (!((z->I[0] - z->c) > 1)) goto lab2; + z->I[0] = z->c; + lab2: + z->c = c3; + } + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; + return 1; +} + +static int r_Step_1(struct SN_env * z) { + int among_var; + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3435050 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; + among_var = find_among_b(z, a_1, 130); + if (!(among_var)) return 0; + z->bra = z->c; + switch (among_var) { + case 1: + { int ret = slice_from_s(z, 4, s_36); + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 3, s_37); + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 5, s_38); + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 5, s_39); + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 3, s_40); + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 6, s_41); + if (ret < 0) return ret; + } + break; + case 7: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 5, s_42); + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 4, s_43); + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 5, s_44); + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 4, s_45); + if (ret < 0) return ret; + } + break; + case 11: + { int ret = slice_from_s(z, 5, s_46); + if (ret < 0) return ret; + } + break; + case 12: + { int ret = slice_from_s(z, 4, s_47); + if (ret < 0) return ret; + } + break; + case 13: + { int ret = slice_from_s(z, 4, s_48); + if (ret < 0) return ret; + } + break; + case 14: + { int ret = slice_from_s(z, 4, s_49); + if (ret < 0) return ret; + } + break; + case 15: + { int ret = slice_from_s(z, 4, s_50); + if (ret < 0) return ret; + } + break; + case 16: + { int ret = slice_from_s(z, 4, s_51); + if (ret < 0) return ret; + } + break; + case 17: + { int ret = slice_from_s(z, 4, s_52); + if (ret < 0) return ret; + } + break; + case 18: + { int ret = slice_from_s(z, 4, s_53); + if (ret < 0) return ret; + } + break; + case 19: + { int ret = slice_from_s(z, 3, s_54); + if (ret < 0) return ret; + } + break; + case 20: + { int ret = slice_from_s(z, 6, s_55); + if (ret < 0) return ret; + } + break; + case 21: + { int ret = slice_from_s(z, 6, s_56); + if (ret < 0) return ret; + } + break; + case 22: + { int ret = slice_from_s(z, 5, s_57); + if (ret < 0) return ret; + } + break; + case 23: + { int ret = slice_from_s(z, 3, s_58); + if (ret < 0) return ret; + } + break; + case 24: + { int ret = slice_from_s(z, 3, s_59); + if (ret < 0) return ret; + } + break; + case 25: + { int ret = slice_from_s(z, 3, s_60); + if (ret < 0) return ret; + } + break; + case 26: + { int ret = slice_from_s(z, 4, s_61); + if (ret < 0) return ret; + } + break; + case 27: + { int ret = slice_from_s(z, 4, s_62); + if (ret < 0) return ret; + } + break; + case 28: + { int ret = slice_from_s(z, 5, s_63); + if (ret < 0) return ret; + } + break; + case 29: + { int ret = slice_from_s(z, 6, s_64); + if (ret < 0) return ret; + } + break; + case 30: + { int ret = slice_from_s(z, 6, s_65); + if (ret < 0) return ret; + } + break; + case 31: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 5, s_66); + if (ret < 0) return ret; + } + break; + case 32: + { int ret = slice_from_s(z, 5, s_67); + if (ret < 0) return ret; + } + break; + case 33: + { int ret = slice_from_s(z, 5, s_68); + if (ret < 0) return ret; + } + break; + case 34: + { int ret = slice_from_s(z, 5, s_69); + if (ret < 0) return ret; + } + break; + case 35: + { int ret = slice_from_s(z, 6, s_70); + if (ret < 0) return ret; + } + break; + case 36: + { int ret = slice_from_s(z, 5, s_71); + if (ret < 0) return ret; + } + break; + case 37: + { int ret = slice_from_s(z, 5, s_72); + if (ret < 0) return ret; + } + break; + case 38: + { int ret = slice_from_s(z, 5, s_73); + if (ret < 0) return ret; + } + break; + case 39: + { int ret = slice_from_s(z, 5, s_74); + if (ret < 0) return ret; + } + break; + case 40: + { int ret = slice_from_s(z, 4, s_75); + if (ret < 0) return ret; + } + break; + case 41: + { int ret = slice_from_s(z, 4, s_76); + if (ret < 0) return ret; + } + break; + case 42: + { int ret = slice_from_s(z, 4, s_77); + if (ret < 0) return ret; + } + break; + case 43: + { int ret = slice_from_s(z, 6, s_78); + if (ret < 0) return ret; + } + break; + case 44: + { int ret = slice_from_s(z, 6, s_79); + if (ret < 0) return ret; + } + break; + case 45: + { int ret = slice_from_s(z, 5, s_80); + if (ret < 0) return ret; + } + break; + case 46: + { int ret = slice_from_s(z, 5, s_81); + if (ret < 0) return ret; + } + break; + case 47: + { int ret = slice_from_s(z, 4, s_82); + if (ret < 0) return ret; + } + break; + case 48: + { int ret = slice_from_s(z, 4, s_83); + if (ret < 0) return ret; + } + break; + case 49: + { int ret = slice_from_s(z, 5, s_84); + if (ret < 0) return ret; + } + break; + case 50: + { int ret = slice_from_s(z, 6, s_85); + if (ret < 0) return ret; + } + break; + case 51: + { int ret = slice_from_s(z, 5, s_86); + if (ret < 0) return ret; + } + break; + case 52: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_87); + if (ret < 0) return ret; + } + break; + case 53: + { int ret = slice_from_s(z, 4, s_88); + if (ret < 0) return ret; + } + break; + case 54: + { int ret = slice_from_s(z, 5, s_89); + if (ret < 0) return ret; + } + break; + case 55: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_90); + if (ret < 0) return ret; + } + break; + case 56: + { int ret = slice_from_s(z, 5, s_91); + if (ret < 0) return ret; + } + break; + case 57: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_92); + if (ret < 0) return ret; + } + break; + case 58: + { int ret = slice_from_s(z, 4, s_93); + if (ret < 0) return ret; + } + break; + case 59: + { int ret = slice_from_s(z, 4, s_94); + if (ret < 0) return ret; + } + break; + case 60: + { int ret = slice_from_s(z, 4, s_95); + if (ret < 0) return ret; + } + break; + case 61: + { int ret = slice_from_s(z, 4, s_96); + if (ret < 0) return ret; + } + break; + case 62: + { int ret = slice_from_s(z, 4, s_97); + if (ret < 0) return ret; + } + break; + case 63: + { int ret = slice_from_s(z, 5, s_98); + if (ret < 0) return ret; + } + break; + case 64: + { int ret = slice_from_s(z, 6, s_99); + if (ret < 0) return ret; + } + break; + case 65: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 5, s_100); + if (ret < 0) return ret; + } + break; + case 66: + { int ret = slice_from_s(z, 5, s_101); + if (ret < 0) return ret; + } + break; + case 67: + { int ret = slice_from_s(z, 4, s_102); + if (ret < 0) return ret; + } + break; + case 68: + { int ret = slice_from_s(z, 5, s_103); + if (ret < 0) return ret; + } + break; + case 69: + { int ret = slice_from_s(z, 6, s_104); + if (ret < 0) return ret; + } + break; + case 70: + { int ret = slice_from_s(z, 5, s_105); + if (ret < 0) return ret; + } + break; + case 71: + { int ret = slice_from_s(z, 4, s_106); + if (ret < 0) return ret; + } + break; + case 72: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_107); + if (ret < 0) return ret; + } + break; + case 73: + { int ret = slice_from_s(z, 3, s_108); + if (ret < 0) return ret; + } + break; + case 74: + { int ret = slice_from_s(z, 4, s_109); + if (ret < 0) return ret; + } + break; + case 75: + { int ret = slice_from_s(z, 3, s_110); + if (ret < 0) return ret; + } + break; + case 76: + { int ret = slice_from_s(z, 3, s_111); + if (ret < 0) return ret; + } + break; + case 77: + { int ret = slice_from_s(z, 6, s_112); + if (ret < 0) return ret; + } + break; + case 78: + { int ret = slice_from_s(z, 4, s_113); + if (ret < 0) return ret; + } + break; + case 79: + { int ret = slice_from_s(z, 3, s_114); + if (ret < 0) return ret; + } + break; + case 80: + { int ret = slice_from_s(z, 3, s_115); + if (ret < 0) return ret; + } + break; + case 81: + { int ret = slice_from_s(z, 3, s_116); + if (ret < 0) return ret; + } + break; + case 82: + { int ret = slice_from_s(z, 4, s_117); + if (ret < 0) return ret; + } + break; + case 83: + { int ret = slice_from_s(z, 4, s_118); + if (ret < 0) return ret; + } + break; + case 84: + { int ret = slice_from_s(z, 4, s_119); + if (ret < 0) return ret; + } + break; + case 85: + { int ret = slice_from_s(z, 4, s_120); + if (ret < 0) return ret; + } + break; + case 86: + { int ret = slice_from_s(z, 4, s_121); + if (ret < 0) return ret; + } + break; + case 87: + { int ret = slice_from_s(z, 4, s_122); + if (ret < 0) return ret; + } + break; + case 88: + { int ret = slice_from_s(z, 4, s_123); + if (ret < 0) return ret; + } + break; + case 89: + { int ret = slice_from_s(z, 4, s_124); + if (ret < 0) return ret; + } + break; + case 90: + { int ret = slice_from_s(z, 5, s_125); + if (ret < 0) return ret; + } + break; + case 91: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_126); + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_2(struct SN_env * z) { + int among_var; + z->ket = z->c; + among_var = find_among_b(z, a_2, 2035); + if (!(among_var)) return 0; + z->bra = z->c; + { int ret = r_R1(z); + if (ret <= 0) return ret; + } + switch (among_var) { + case 1: + { int ret = slice_from_s(z, 2, s_127); + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 3, s_128); + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 3, s_129); + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 4, s_130); + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 5, s_131); + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 5, s_132); + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 5, s_133); + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 5, s_134); + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 5, s_135); + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 2, s_136); + if (ret < 0) return ret; + } + break; + case 11: + { int ret = slice_from_s(z, 2, s_137); + if (ret < 0) return ret; + } + break; + case 12: + { int ret = slice_from_s(z, 2, s_138); + if (ret < 0) return ret; + } + break; + case 13: + { int ret = slice_from_s(z, 1, s_139); + if (ret < 0) return ret; + } + break; + case 14: + { int ret = slice_from_s(z, 3, s_140); + if (ret < 0) return ret; + } + break; + case 15: + { int ret = slice_from_s(z, 3, s_141); + if (ret < 0) return ret; + } + break; + case 16: + { int ret = slice_from_s(z, 3, s_142); + if (ret < 0) return ret; + } + break; + case 17: + { int ret = slice_from_s(z, 4, s_143); + if (ret < 0) return ret; + } + break; + case 18: + { int ret = slice_from_s(z, 2, s_144); + if (ret < 0) return ret; + } + break; + case 19: + { int ret = slice_from_s(z, 3, s_145); + if (ret < 0) return ret; + } + break; + case 20: + { int ret = slice_from_s(z, 1, s_146); + if (ret < 0) return ret; + } + break; + case 21: + { int ret = slice_from_s(z, 4, s_147); + if (ret < 0) return ret; + } + break; + case 22: + { int ret = slice_from_s(z, 3, s_148); + if (ret < 0) return ret; + } + break; + case 23: + { int ret = slice_from_s(z, 2, s_149); + if (ret < 0) return ret; + } + break; + case 24: + { int ret = slice_from_s(z, 2, s_150); + if (ret < 0) return ret; + } + break; + case 25: + { int ret = slice_from_s(z, 2, s_151); + if (ret < 0) return ret; + } + break; + case 26: + { int ret = slice_from_s(z, 3, s_152); + if (ret < 0) return ret; + } + break; + case 27: + { int ret = slice_from_s(z, 4, s_153); + if (ret < 0) return ret; + } + break; + case 28: + { int ret = slice_from_s(z, 4, s_154); + if (ret < 0) return ret; + } + break; + case 29: + { int ret = slice_from_s(z, 4, s_155); + if (ret < 0) return ret; + } + break; + case 30: + { int ret = slice_from_s(z, 3, s_156); + if (ret < 0) return ret; + } + break; + case 31: + { int ret = slice_from_s(z, 3, s_157); + if (ret < 0) return ret; + } + break; + case 32: + { int ret = slice_from_s(z, 3, s_158); + if (ret < 0) return ret; + } + break; + case 33: + { int ret = slice_from_s(z, 3, s_159); + if (ret < 0) return ret; + } + break; + case 34: + { int ret = slice_from_s(z, 3, s_160); + if (ret < 0) return ret; + } + break; + case 35: + { int ret = slice_from_s(z, 3, s_161); + if (ret < 0) return ret; + } + break; + case 36: + { int ret = slice_from_s(z, 3, s_162); + if (ret < 0) return ret; + } + break; + case 37: + { int ret = slice_from_s(z, 3, s_163); + if (ret < 0) return ret; + } + break; + case 38: + { int ret = slice_from_s(z, 4, s_164); + if (ret < 0) return ret; + } + break; + case 39: + { int ret = slice_from_s(z, 3, s_165); + if (ret < 0) return ret; + } + break; + case 40: + { int ret = slice_from_s(z, 3, s_166); + if (ret < 0) return ret; + } + break; + case 41: + { int ret = slice_from_s(z, 3, s_167); + if (ret < 0) return ret; + } + break; + case 42: + { int ret = slice_from_s(z, 3, s_168); + if (ret < 0) return ret; + } + break; + case 43: + { int ret = slice_from_s(z, 3, s_169); + if (ret < 0) return ret; + } + break; + case 44: + { int ret = slice_from_s(z, 3, s_170); + if (ret < 0) return ret; + } + break; + case 45: + { int ret = slice_from_s(z, 3, s_171); + if (ret < 0) return ret; + } + break; + case 46: + { int ret = slice_from_s(z, 3, s_172); + if (ret < 0) return ret; + } + break; + case 47: + { int ret = slice_from_s(z, 4, s_173); + if (ret < 0) return ret; + } + break; + case 48: + { int ret = slice_from_s(z, 4, s_174); + if (ret < 0) return ret; + } + break; + case 49: + { int ret = slice_from_s(z, 4, s_175); + if (ret < 0) return ret; + } + break; + case 50: + { int ret = slice_from_s(z, 2, s_176); + if (ret < 0) return ret; + } + break; + case 51: + { int ret = slice_from_s(z, 3, s_177); + if (ret < 0) return ret; + } + break; + case 52: + { int ret = slice_from_s(z, 3, s_178); + if (ret < 0) return ret; + } + break; + case 53: + { int ret = slice_from_s(z, 2, s_179); + if (ret < 0) return ret; + } + break; + case 54: + { int ret = slice_from_s(z, 2, s_180); + if (ret < 0) return ret; + } + break; + case 55: + { int ret = slice_from_s(z, 2, s_181); + if (ret < 0) return ret; + } + break; + case 56: + { int ret = slice_from_s(z, 2, s_182); + if (ret < 0) return ret; + } + break; + case 57: + { int ret = slice_from_s(z, 2, s_183); + if (ret < 0) return ret; + } + break; + case 58: + { int ret = slice_from_s(z, 2, s_184); + if (ret < 0) return ret; + } + break; + case 59: + { int ret = slice_from_s(z, 4, s_185); + if (ret < 0) return ret; + } + break; + case 60: + { int ret = slice_from_s(z, 4, s_186); + if (ret < 0) return ret; + } + break; + case 61: + { int ret = slice_from_s(z, 4, s_187); + if (ret < 0) return ret; + } + break; + case 62: + { int ret = slice_from_s(z, 4, s_188); + if (ret < 0) return ret; + } + break; + case 63: + { int ret = slice_from_s(z, 4, s_189); + if (ret < 0) return ret; + } + break; + case 64: + { int ret = slice_from_s(z, 4, s_190); + if (ret < 0) return ret; + } + break; + case 65: + { int ret = slice_from_s(z, 4, s_191); + if (ret < 0) return ret; + } + break; + case 66: + { int ret = slice_from_s(z, 3, s_192); + if (ret < 0) return ret; + } + break; + case 67: + { int ret = slice_from_s(z, 3, s_193); + if (ret < 0) return ret; + } + break; + case 68: + { int ret = slice_from_s(z, 4, s_194); + if (ret < 0) return ret; + } + break; + case 69: + { int ret = slice_from_s(z, 3, s_195); + if (ret < 0) return ret; + } + break; + case 70: + { int ret = slice_from_s(z, 2, s_196); + if (ret < 0) return ret; + } + break; + case 71: + { int ret = slice_from_s(z, 3, s_197); + if (ret < 0) return ret; + } + break; + case 72: + { int ret = slice_from_s(z, 3, s_198); + if (ret < 0) return ret; + } + break; + case 73: + { int ret = slice_from_s(z, 3, s_199); + if (ret < 0) return ret; + } + break; + case 74: + { int ret = slice_from_s(z, 3, s_200); + if (ret < 0) return ret; + } + break; + case 75: + { int ret = slice_from_s(z, 4, s_201); + if (ret < 0) return ret; + } + break; + case 76: + { int ret = slice_from_s(z, 3, s_202); + if (ret < 0) return ret; + } + break; + case 77: + { int ret = slice_from_s(z, 2, s_203); + if (ret < 0) return ret; + } + break; + case 78: + { int ret = slice_from_s(z, 2, s_204); + if (ret < 0) return ret; + } + break; + case 79: + { int ret = slice_from_s(z, 2, s_205); + if (ret < 0) return ret; + } + break; + case 80: + { int ret = slice_from_s(z, 2, s_206); + if (ret < 0) return ret; + } + break; + case 81: + { int ret = slice_from_s(z, 3, s_207); + if (ret < 0) return ret; + } + break; + case 82: + { int ret = slice_from_s(z, 3, s_208); + if (ret < 0) return ret; + } + break; + case 83: + { int ret = slice_from_s(z, 2, s_209); + if (ret < 0) return ret; + } + break; + case 84: + { int ret = slice_from_s(z, 3, s_210); + if (ret < 0) return ret; + } + break; + case 85: + { int ret = slice_from_s(z, 3, s_211); + if (ret < 0) return ret; + } + break; + case 86: + { int ret = slice_from_s(z, 4, s_212); + if (ret < 0) return ret; + } + break; + case 87: + { int ret = slice_from_s(z, 2, s_213); + if (ret < 0) return ret; + } + break; + case 88: + { int ret = slice_from_s(z, 3, s_214); + if (ret < 0) return ret; + } + break; + case 89: + { int ret = slice_from_s(z, 4, s_215); + if (ret < 0) return ret; + } + break; + case 90: + { int ret = slice_from_s(z, 5, s_216); + if (ret < 0) return ret; + } + break; + case 91: + { int ret = slice_from_s(z, 3, s_217); + if (ret < 0) return ret; + } + break; + case 92: + { int ret = slice_from_s(z, 4, s_218); + if (ret < 0) return ret; + } + break; + case 93: + { int ret = slice_from_s(z, 4, s_219); + if (ret < 0) return ret; + } + break; + case 94: + { int ret = slice_from_s(z, 3, s_220); + if (ret < 0) return ret; + } + break; + case 95: + { int ret = slice_from_s(z, 1, s_221); + if (ret < 0) return ret; + } + break; + case 96: + { int ret = slice_from_s(z, 3, s_222); + if (ret < 0) return ret; + } + break; + case 97: + { int ret = slice_from_s(z, 3, s_223); + if (ret < 0) return ret; + } + break; + case 98: + { int ret = slice_from_s(z, 3, s_224); + if (ret < 0) return ret; + } + break; + case 99: + { int ret = slice_from_s(z, 3, s_225); + if (ret < 0) return ret; + } + break; + case 100: + { int ret = slice_from_s(z, 2, s_226); + if (ret < 0) return ret; + } + break; + case 101: + { int ret = slice_from_s(z, 3, s_227); + if (ret < 0) return ret; + } + break; + case 102: + { int ret = slice_from_s(z, 4, s_228); + if (ret < 0) return ret; + } + break; + case 103: + { int ret = slice_from_s(z, 2, s_229); + if (ret < 0) return ret; + } + break; + case 104: + { int ret = slice_from_s(z, 1, s_230); + if (ret < 0) return ret; + } + break; + case 105: + { int ret = slice_from_s(z, 2, s_231); + if (ret < 0) return ret; + } + break; + case 106: + { int ret = slice_from_s(z, 5, s_232); + if (ret < 0) return ret; + } + break; + case 107: + { int ret = slice_from_s(z, 5, s_233); + if (ret < 0) return ret; + } + break; + case 108: + { int ret = slice_from_s(z, 5, s_234); + if (ret < 0) return ret; + } + break; + case 109: + { int ret = slice_from_s(z, 2, s_235); + if (ret < 0) return ret; + } + break; + case 110: + { int ret = slice_from_s(z, 4, s_236); + if (ret < 0) return ret; + } + break; + case 111: + { int ret = slice_from_s(z, 4, s_237); + if (ret < 0) return ret; + } + break; + case 112: + { int ret = slice_from_s(z, 4, s_238); + if (ret < 0) return ret; + } + break; + case 113: + { int ret = slice_from_s(z, 2, s_239); + if (ret < 0) return ret; + } + break; + case 114: + { int ret = slice_from_s(z, 3, s_240); + if (ret < 0) return ret; + } + break; + case 115: + { int ret = slice_from_s(z, 2, s_241); + if (ret < 0) return ret; + } + break; + case 116: + { int ret = slice_from_s(z, 1, s_242); + if (ret < 0) return ret; + } + break; + case 117: + { int ret = slice_from_s(z, 4, s_243); + if (ret < 0) return ret; + } + break; + case 118: + { int ret = slice_from_s(z, 4, s_244); + if (ret < 0) return ret; + } + break; + case 119: + { int ret = slice_from_s(z, 1, s_245); + if (ret < 0) return ret; + } + break; + case 120: + { int ret = slice_from_s(z, 2, s_246); + if (ret < 0) return ret; + } + break; + case 121: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_247); + if (ret < 0) return ret; + } + break; + case 122: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_248); + if (ret < 0) return ret; + } + break; + case 123: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_249); + if (ret < 0) return ret; + } + break; + case 124: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_250); + if (ret < 0) return ret; + } + break; + case 125: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_251); + if (ret < 0) return ret; + } + break; + case 126: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_252); + if (ret < 0) return ret; + } + break; + case 127: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_253); + if (ret < 0) return ret; + } + break; + case 128: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_254); + if (ret < 0) return ret; + } + break; + case 129: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_255); + if (ret < 0) return ret; + } + break; + case 130: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_256); + if (ret < 0) return ret; + } + break; + case 131: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_257); + if (ret < 0) return ret; + } + break; + case 132: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_258); + if (ret < 0) return ret; + } + break; + case 133: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_259); + if (ret < 0) return ret; + } + break; + case 134: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_260); + if (ret < 0) return ret; + } + break; + case 135: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_261); + if (ret < 0) return ret; + } + break; + case 136: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_262); + if (ret < 0) return ret; + } + break; + case 137: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_263); + if (ret < 0) return ret; + } + break; + case 138: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 5, s_264); + if (ret < 0) return ret; + } + break; + case 139: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 5, s_265); + if (ret < 0) return ret; + } + break; + case 140: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 5, s_266); + if (ret < 0) return ret; + } + break; + case 141: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_267); + if (ret < 0) return ret; + } + break; + case 142: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_268); + if (ret < 0) return ret; + } + break; + case 143: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_269); + if (ret < 0) return ret; + } + break; + case 144: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_270); + if (ret < 0) return ret; + } + break; + case 145: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_271); + if (ret < 0) return ret; + } + break; + case 146: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_272); + if (ret < 0) return ret; + } + break; + case 147: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_273); + if (ret < 0) return ret; + } + break; + case 148: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_274); + if (ret < 0) return ret; + } + break; + case 149: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 4, s_275); + if (ret < 0) return ret; + } + break; + case 150: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_276); + if (ret < 0) return ret; + } + break; + case 151: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 3, s_277); + if (ret < 0) return ret; + } + break; + case 152: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_278); + if (ret < 0) return ret; + } + break; + case 153: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_279); + if (ret < 0) return ret; + } + break; + case 154: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_280); + if (ret < 0) return ret; + } + break; + case 155: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_281); + if (ret < 0) return ret; + } + break; + case 156: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_282); + if (ret < 0) return ret; + } + break; + case 157: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_283); + if (ret < 0) return ret; + } + break; + case 158: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_284); + if (ret < 0) return ret; + } + break; + case 159: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_285); + if (ret < 0) return ret; + } + break; + case 160: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 2, s_286); + if (ret < 0) return ret; + } + break; + case 161: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 1, s_287); + if (ret < 0) return ret; + } + break; + case 162: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 1, s_288); + if (ret < 0) return ret; + } + break; + case 163: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 1, s_289); + if (ret < 0) return ret; + } + break; + case 164: + if (!(z->I[1])) return 0; + { int ret = slice_from_s(z, 1, s_290); + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Step_3(struct SN_env * z) { + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3188642 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; + if (!(find_among_b(z, a_3, 26))) return 0; + z->bra = z->c; + { int ret = r_R1(z); + if (ret <= 0) return ret; + } + { int ret = slice_from_s(z, 0, 0); + if (ret < 0) return ret; + } + return 1; +} + +extern int serbian_UTF_8_stem(struct SN_env * z) { + + { int ret = r_cyr_to_lat(z); + if (ret < 0) return ret; + } + + { int ret = r_prelude(z); + if (ret < 0) return ret; + } + + { int ret = r_mark_regions(z); + if (ret < 0) return ret; + } + z->lb = z->c; z->c = z->l; + + { int m1 = z->l - z->c; (void)m1; + { int ret = r_Step_1(z); + if (ret < 0) return ret; + } + z->c = z->l - m1; + } + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_Step_2(z); + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m3; + { int ret = r_Step_3(z); + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + } + lab1: + lab0: + z->c = z->l - m2; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * serbian_UTF_8_create_env(void) { return SN_create_env(0, 2); } + +extern void serbian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c b/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c index 237d743ca8a9..d77726ed9855 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -39,12 +39,12 @@ static const symbol s_0_5[2] = { 0xC3, 0xBA }; static const struct among a_0[6] = { -/* 0 */ { 0, 0, -1, 6, 0}, -/* 1 */ { 2, s_0_1, 0, 1, 0}, -/* 2 */ { 2, s_0_2, 0, 2, 0}, -/* 3 */ { 2, s_0_3, 0, 3, 0}, -/* 4 */ { 2, s_0_4, 0, 4, 0}, -/* 5 */ { 2, s_0_5, 0, 5, 0} +{ 0, 0, -1, 6, 0}, +{ 2, s_0_1, 0, 1, 0}, +{ 2, s_0_2, 0, 2, 0}, +{ 2, s_0_3, 0, 3, 0}, +{ 2, s_0_4, 0, 4, 0}, +{ 2, s_0_5, 0, 5, 0} }; static const symbol s_1_0[2] = { 'l', 'a' }; @@ -63,19 +63,19 @@ static const symbol s_1_12[3] = { 'n', 'o', 's' }; static const struct among a_1[13] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 4, s_1_1, 0, -1, 0}, -/* 2 */ { 2, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0}, -/* 4 */ { 2, s_1_4, -1, -1, 0}, -/* 5 */ { 2, s_1_5, -1, -1, 0}, -/* 6 */ { 4, s_1_6, 5, -1, 0}, -/* 7 */ { 3, s_1_7, -1, -1, 0}, -/* 8 */ { 5, s_1_8, 7, -1, 0}, -/* 9 */ { 3, s_1_9, -1, -1, 0}, -/* 10 */ { 3, s_1_10, -1, -1, 0}, -/* 11 */ { 5, s_1_11, 10, -1, 0}, -/* 12 */ { 3, s_1_12, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 4, s_1_1, 0, -1, 0}, +{ 2, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0}, +{ 2, s_1_4, -1, -1, 0}, +{ 2, s_1_5, -1, -1, 0}, +{ 4, s_1_6, 5, -1, 0}, +{ 3, s_1_7, -1, -1, 0}, +{ 5, s_1_8, 7, -1, 0}, +{ 3, s_1_9, -1, -1, 0}, +{ 3, s_1_10, -1, -1, 0}, +{ 5, s_1_11, 10, -1, 0}, +{ 3, s_1_12, -1, -1, 0} }; static const symbol s_2_0[4] = { 'a', 'n', 'd', 'o' }; @@ -92,17 +92,17 @@ static const symbol s_2_10[3] = { 0xC3, 0xAD, 'r' }; static const struct among a_2[11] = { -/* 0 */ { 4, s_2_0, -1, 6, 0}, -/* 1 */ { 5, s_2_1, -1, 6, 0}, -/* 2 */ { 5, s_2_2, -1, 7, 0}, -/* 3 */ { 5, s_2_3, -1, 2, 0}, -/* 4 */ { 6, s_2_4, -1, 1, 0}, -/* 5 */ { 2, s_2_5, -1, 6, 0}, -/* 6 */ { 2, s_2_6, -1, 6, 0}, -/* 7 */ { 2, s_2_7, -1, 6, 0}, -/* 8 */ { 3, s_2_8, -1, 3, 0}, -/* 9 */ { 3, s_2_9, -1, 4, 0}, -/* 10 */ { 3, s_2_10, -1, 5, 0} +{ 4, s_2_0, -1, 6, 0}, +{ 5, s_2_1, -1, 6, 0}, +{ 5, s_2_2, -1, 7, 0}, +{ 5, s_2_3, -1, 2, 0}, +{ 6, s_2_4, -1, 1, 0}, +{ 2, s_2_5, -1, 6, 0}, +{ 2, s_2_6, -1, 6, 0}, +{ 2, s_2_7, -1, 6, 0}, +{ 3, s_2_8, -1, 3, 0}, +{ 3, s_2_9, -1, 4, 0}, +{ 3, s_2_10, -1, 5, 0} }; static const symbol s_3_0[2] = { 'i', 'c' }; @@ -112,10 +112,10 @@ static const symbol s_3_3[2] = { 'i', 'v' }; static const struct among a_3[4] = { -/* 0 */ { 2, s_3_0, -1, -1, 0}, -/* 1 */ { 2, s_3_1, -1, -1, 0}, -/* 2 */ { 2, s_3_2, -1, -1, 0}, -/* 3 */ { 2, s_3_3, -1, 1, 0} +{ 2, s_3_0, -1, -1, 0}, +{ 2, s_3_1, -1, -1, 0}, +{ 2, s_3_2, -1, -1, 0}, +{ 2, s_3_3, -1, 1, 0} }; static const symbol s_4_0[4] = { 'a', 'b', 'l', 'e' }; @@ -124,9 +124,9 @@ static const symbol s_4_2[4] = { 'a', 'n', 't', 'e' }; static const struct among a_4[3] = { -/* 0 */ { 4, s_4_0, -1, 1, 0}, -/* 1 */ { 4, s_4_1, -1, 1, 0}, -/* 2 */ { 4, s_4_2, -1, 1, 0} +{ 4, s_4_0, -1, 1, 0}, +{ 4, s_4_1, -1, 1, 0}, +{ 4, s_4_2, -1, 1, 0} }; static const symbol s_5_0[2] = { 'i', 'c' }; @@ -135,9 +135,9 @@ static const symbol s_5_2[2] = { 'i', 'v' }; static const struct among a_5[3] = { -/* 0 */ { 2, s_5_0, -1, 1, 0}, -/* 1 */ { 4, s_5_1, -1, 1, 0}, -/* 2 */ { 2, s_5_2, -1, 1, 0} +{ 2, s_5_0, -1, 1, 0}, +{ 4, s_5_1, -1, 1, 0}, +{ 2, s_5_2, -1, 1, 0} }; static const symbol s_6_0[3] = { 'i', 'c', 'a' }; @@ -189,52 +189,52 @@ static const symbol s_6_45[4] = { 'i', 'v', 'o', 's' }; static const struct among a_6[46] = { -/* 0 */ { 3, s_6_0, -1, 1, 0}, -/* 1 */ { 5, s_6_1, -1, 2, 0}, -/* 2 */ { 5, s_6_2, -1, 5, 0}, -/* 3 */ { 5, s_6_3, -1, 2, 0}, -/* 4 */ { 3, s_6_4, -1, 1, 0}, -/* 5 */ { 4, s_6_5, -1, 1, 0}, -/* 6 */ { 3, s_6_6, -1, 9, 0}, -/* 7 */ { 4, s_6_7, -1, 1, 0}, -/* 8 */ { 6, s_6_8, -1, 3, 0}, -/* 9 */ { 4, s_6_9, -1, 8, 0}, -/* 10 */ { 4, s_6_10, -1, 1, 0}, -/* 11 */ { 4, s_6_11, -1, 1, 0}, -/* 12 */ { 4, s_6_12, -1, 2, 0}, -/* 13 */ { 5, s_6_13, -1, 7, 0}, -/* 14 */ { 6, s_6_14, 13, 6, 0}, -/* 15 */ { 6, s_6_15, -1, 2, 0}, -/* 16 */ { 6, s_6_16, -1, 4, 0}, -/* 17 */ { 3, s_6_17, -1, 1, 0}, -/* 18 */ { 4, s_6_18, -1, 1, 0}, -/* 19 */ { 3, s_6_19, -1, 1, 0}, -/* 20 */ { 7, s_6_20, -1, 1, 0}, -/* 21 */ { 7, s_6_21, -1, 1, 0}, -/* 22 */ { 3, s_6_22, -1, 9, 0}, -/* 23 */ { 4, s_6_23, -1, 2, 0}, -/* 24 */ { 4, s_6_24, -1, 1, 0}, -/* 25 */ { 6, s_6_25, -1, 2, 0}, -/* 26 */ { 6, s_6_26, -1, 5, 0}, -/* 27 */ { 6, s_6_27, -1, 2, 0}, -/* 28 */ { 4, s_6_28, -1, 1, 0}, -/* 29 */ { 5, s_6_29, -1, 1, 0}, -/* 30 */ { 4, s_6_30, -1, 9, 0}, -/* 31 */ { 5, s_6_31, -1, 1, 0}, -/* 32 */ { 7, s_6_32, -1, 3, 0}, -/* 33 */ { 6, s_6_33, -1, 8, 0}, -/* 34 */ { 5, s_6_34, -1, 1, 0}, -/* 35 */ { 5, s_6_35, -1, 1, 0}, -/* 36 */ { 7, s_6_36, -1, 2, 0}, -/* 37 */ { 7, s_6_37, -1, 4, 0}, -/* 38 */ { 6, s_6_38, -1, 2, 0}, -/* 39 */ { 5, s_6_39, -1, 2, 0}, -/* 40 */ { 4, s_6_40, -1, 1, 0}, -/* 41 */ { 5, s_6_41, -1, 1, 0}, -/* 42 */ { 4, s_6_42, -1, 1, 0}, -/* 43 */ { 8, s_6_43, -1, 1, 0}, -/* 44 */ { 8, s_6_44, -1, 1, 0}, -/* 45 */ { 4, s_6_45, -1, 9, 0} +{ 3, s_6_0, -1, 1, 0}, +{ 5, s_6_1, -1, 2, 0}, +{ 5, s_6_2, -1, 5, 0}, +{ 5, s_6_3, -1, 2, 0}, +{ 3, s_6_4, -1, 1, 0}, +{ 4, s_6_5, -1, 1, 0}, +{ 3, s_6_6, -1, 9, 0}, +{ 4, s_6_7, -1, 1, 0}, +{ 6, s_6_8, -1, 3, 0}, +{ 4, s_6_9, -1, 8, 0}, +{ 4, s_6_10, -1, 1, 0}, +{ 4, s_6_11, -1, 1, 0}, +{ 4, s_6_12, -1, 2, 0}, +{ 5, s_6_13, -1, 7, 0}, +{ 6, s_6_14, 13, 6, 0}, +{ 6, s_6_15, -1, 2, 0}, +{ 6, s_6_16, -1, 4, 0}, +{ 3, s_6_17, -1, 1, 0}, +{ 4, s_6_18, -1, 1, 0}, +{ 3, s_6_19, -1, 1, 0}, +{ 7, s_6_20, -1, 1, 0}, +{ 7, s_6_21, -1, 1, 0}, +{ 3, s_6_22, -1, 9, 0}, +{ 4, s_6_23, -1, 2, 0}, +{ 4, s_6_24, -1, 1, 0}, +{ 6, s_6_25, -1, 2, 0}, +{ 6, s_6_26, -1, 5, 0}, +{ 6, s_6_27, -1, 2, 0}, +{ 4, s_6_28, -1, 1, 0}, +{ 5, s_6_29, -1, 1, 0}, +{ 4, s_6_30, -1, 9, 0}, +{ 5, s_6_31, -1, 1, 0}, +{ 7, s_6_32, -1, 3, 0}, +{ 6, s_6_33, -1, 8, 0}, +{ 5, s_6_34, -1, 1, 0}, +{ 5, s_6_35, -1, 1, 0}, +{ 7, s_6_36, -1, 2, 0}, +{ 7, s_6_37, -1, 4, 0}, +{ 6, s_6_38, -1, 2, 0}, +{ 5, s_6_39, -1, 2, 0}, +{ 4, s_6_40, -1, 1, 0}, +{ 5, s_6_41, -1, 1, 0}, +{ 4, s_6_42, -1, 1, 0}, +{ 8, s_6_43, -1, 1, 0}, +{ 8, s_6_44, -1, 1, 0}, +{ 4, s_6_45, -1, 9, 0} }; static const symbol s_7_0[2] = { 'y', 'a' }; @@ -252,18 +252,18 @@ static const symbol s_7_11[3] = { 'y', 0xC3, 0xB3 }; static const struct among a_7[12] = { -/* 0 */ { 2, s_7_0, -1, 1, 0}, -/* 1 */ { 2, s_7_1, -1, 1, 0}, -/* 2 */ { 3, s_7_2, -1, 1, 0}, -/* 3 */ { 3, s_7_3, -1, 1, 0}, -/* 4 */ { 5, s_7_4, -1, 1, 0}, -/* 5 */ { 5, s_7_5, -1, 1, 0}, -/* 6 */ { 2, s_7_6, -1, 1, 0}, -/* 7 */ { 3, s_7_7, -1, 1, 0}, -/* 8 */ { 3, s_7_8, -1, 1, 0}, -/* 9 */ { 4, s_7_9, -1, 1, 0}, -/* 10 */ { 5, s_7_10, -1, 1, 0}, -/* 11 */ { 3, s_7_11, -1, 1, 0} +{ 2, s_7_0, -1, 1, 0}, +{ 2, s_7_1, -1, 1, 0}, +{ 3, s_7_2, -1, 1, 0}, +{ 3, s_7_3, -1, 1, 0}, +{ 5, s_7_4, -1, 1, 0}, +{ 5, s_7_5, -1, 1, 0}, +{ 2, s_7_6, -1, 1, 0}, +{ 3, s_7_7, -1, 1, 0}, +{ 3, s_7_8, -1, 1, 0}, +{ 4, s_7_9, -1, 1, 0}, +{ 5, s_7_10, -1, 1, 0}, +{ 3, s_7_11, -1, 1, 0} }; static const symbol s_8_0[3] = { 'a', 'b', 'a' }; @@ -365,102 +365,102 @@ static const symbol s_8_95[3] = { 'i', 0xC3, 0xB3 }; static const struct among a_8[96] = { -/* 0 */ { 3, s_8_0, -1, 2, 0}, -/* 1 */ { 3, s_8_1, -1, 2, 0}, -/* 2 */ { 3, s_8_2, -1, 2, 0}, -/* 3 */ { 3, s_8_3, -1, 2, 0}, -/* 4 */ { 4, s_8_4, -1, 2, 0}, -/* 5 */ { 3, s_8_5, -1, 2, 0}, -/* 6 */ { 5, s_8_6, 5, 2, 0}, -/* 7 */ { 5, s_8_7, 5, 2, 0}, -/* 8 */ { 5, s_8_8, 5, 2, 0}, -/* 9 */ { 2, s_8_9, -1, 2, 0}, -/* 10 */ { 2, s_8_10, -1, 2, 0}, -/* 11 */ { 2, s_8_11, -1, 2, 0}, -/* 12 */ { 3, s_8_12, -1, 2, 0}, -/* 13 */ { 4, s_8_13, -1, 2, 0}, -/* 14 */ { 4, s_8_14, -1, 2, 0}, -/* 15 */ { 4, s_8_15, -1, 2, 0}, -/* 16 */ { 2, s_8_16, -1, 2, 0}, -/* 17 */ { 4, s_8_17, 16, 2, 0}, -/* 18 */ { 4, s_8_18, 16, 2, 0}, -/* 19 */ { 5, s_8_19, 16, 2, 0}, -/* 20 */ { 4, s_8_20, 16, 2, 0}, -/* 21 */ { 6, s_8_21, 20, 2, 0}, -/* 22 */ { 6, s_8_22, 20, 2, 0}, -/* 23 */ { 6, s_8_23, 20, 2, 0}, -/* 24 */ { 2, s_8_24, -1, 1, 0}, -/* 25 */ { 4, s_8_25, 24, 2, 0}, -/* 26 */ { 5, s_8_26, 24, 2, 0}, -/* 27 */ { 4, s_8_27, -1, 2, 0}, -/* 28 */ { 5, s_8_28, -1, 2, 0}, -/* 29 */ { 5, s_8_29, -1, 2, 0}, -/* 30 */ { 5, s_8_30, -1, 2, 0}, -/* 31 */ { 5, s_8_31, -1, 2, 0}, -/* 32 */ { 3, s_8_32, -1, 2, 0}, -/* 33 */ { 3, s_8_33, -1, 2, 0}, -/* 34 */ { 4, s_8_34, -1, 2, 0}, -/* 35 */ { 5, s_8_35, -1, 2, 0}, -/* 36 */ { 2, s_8_36, -1, 2, 0}, -/* 37 */ { 2, s_8_37, -1, 2, 0}, -/* 38 */ { 2, s_8_38, -1, 2, 0}, -/* 39 */ { 2, s_8_39, -1, 2, 0}, -/* 40 */ { 4, s_8_40, 39, 2, 0}, -/* 41 */ { 4, s_8_41, 39, 2, 0}, -/* 42 */ { 4, s_8_42, 39, 2, 0}, -/* 43 */ { 4, s_8_43, 39, 2, 0}, -/* 44 */ { 5, s_8_44, 39, 2, 0}, -/* 45 */ { 4, s_8_45, 39, 2, 0}, -/* 46 */ { 6, s_8_46, 45, 2, 0}, -/* 47 */ { 6, s_8_47, 45, 2, 0}, -/* 48 */ { 6, s_8_48, 45, 2, 0}, -/* 49 */ { 2, s_8_49, -1, 1, 0}, -/* 50 */ { 4, s_8_50, 49, 2, 0}, -/* 51 */ { 5, s_8_51, 49, 2, 0}, -/* 52 */ { 5, s_8_52, -1, 2, 0}, -/* 53 */ { 5, s_8_53, -1, 2, 0}, -/* 54 */ { 6, s_8_54, -1, 2, 0}, -/* 55 */ { 5, s_8_55, -1, 2, 0}, -/* 56 */ { 7, s_8_56, 55, 2, 0}, -/* 57 */ { 7, s_8_57, 55, 2, 0}, -/* 58 */ { 7, s_8_58, 55, 2, 0}, -/* 59 */ { 5, s_8_59, -1, 2, 0}, -/* 60 */ { 6, s_8_60, -1, 2, 0}, -/* 61 */ { 6, s_8_61, -1, 2, 0}, -/* 62 */ { 6, s_8_62, -1, 2, 0}, -/* 63 */ { 4, s_8_63, -1, 2, 0}, -/* 64 */ { 4, s_8_64, -1, 1, 0}, -/* 65 */ { 6, s_8_65, 64, 2, 0}, -/* 66 */ { 6, s_8_66, 64, 2, 0}, -/* 67 */ { 6, s_8_67, 64, 2, 0}, -/* 68 */ { 4, s_8_68, -1, 2, 0}, -/* 69 */ { 4, s_8_69, -1, 2, 0}, -/* 70 */ { 4, s_8_70, -1, 2, 0}, -/* 71 */ { 7, s_8_71, 70, 2, 0}, -/* 72 */ { 7, s_8_72, 70, 2, 0}, -/* 73 */ { 8, s_8_73, 70, 2, 0}, -/* 74 */ { 6, s_8_74, 70, 2, 0}, -/* 75 */ { 8, s_8_75, 74, 2, 0}, -/* 76 */ { 8, s_8_76, 74, 2, 0}, -/* 77 */ { 8, s_8_77, 74, 2, 0}, -/* 78 */ { 4, s_8_78, -1, 1, 0}, -/* 79 */ { 6, s_8_79, 78, 2, 0}, -/* 80 */ { 6, s_8_80, 78, 2, 0}, -/* 81 */ { 6, s_8_81, 78, 2, 0}, -/* 82 */ { 7, s_8_82, 78, 2, 0}, -/* 83 */ { 8, s_8_83, 78, 2, 0}, -/* 84 */ { 4, s_8_84, -1, 2, 0}, -/* 85 */ { 5, s_8_85, -1, 2, 0}, -/* 86 */ { 5, s_8_86, -1, 2, 0}, -/* 87 */ { 5, s_8_87, -1, 2, 0}, -/* 88 */ { 3, s_8_88, -1, 2, 0}, -/* 89 */ { 4, s_8_89, -1, 2, 0}, -/* 90 */ { 4, s_8_90, -1, 2, 0}, -/* 91 */ { 4, s_8_91, -1, 2, 0}, -/* 92 */ { 4, s_8_92, -1, 2, 0}, -/* 93 */ { 4, s_8_93, -1, 2, 0}, -/* 94 */ { 4, s_8_94, -1, 2, 0}, -/* 95 */ { 3, s_8_95, -1, 2, 0} +{ 3, s_8_0, -1, 2, 0}, +{ 3, s_8_1, -1, 2, 0}, +{ 3, s_8_2, -1, 2, 0}, +{ 3, s_8_3, -1, 2, 0}, +{ 4, s_8_4, -1, 2, 0}, +{ 3, s_8_5, -1, 2, 0}, +{ 5, s_8_6, 5, 2, 0}, +{ 5, s_8_7, 5, 2, 0}, +{ 5, s_8_8, 5, 2, 0}, +{ 2, s_8_9, -1, 2, 0}, +{ 2, s_8_10, -1, 2, 0}, +{ 2, s_8_11, -1, 2, 0}, +{ 3, s_8_12, -1, 2, 0}, +{ 4, s_8_13, -1, 2, 0}, +{ 4, s_8_14, -1, 2, 0}, +{ 4, s_8_15, -1, 2, 0}, +{ 2, s_8_16, -1, 2, 0}, +{ 4, s_8_17, 16, 2, 0}, +{ 4, s_8_18, 16, 2, 0}, +{ 5, s_8_19, 16, 2, 0}, +{ 4, s_8_20, 16, 2, 0}, +{ 6, s_8_21, 20, 2, 0}, +{ 6, s_8_22, 20, 2, 0}, +{ 6, s_8_23, 20, 2, 0}, +{ 2, s_8_24, -1, 1, 0}, +{ 4, s_8_25, 24, 2, 0}, +{ 5, s_8_26, 24, 2, 0}, +{ 4, s_8_27, -1, 2, 0}, +{ 5, s_8_28, -1, 2, 0}, +{ 5, s_8_29, -1, 2, 0}, +{ 5, s_8_30, -1, 2, 0}, +{ 5, s_8_31, -1, 2, 0}, +{ 3, s_8_32, -1, 2, 0}, +{ 3, s_8_33, -1, 2, 0}, +{ 4, s_8_34, -1, 2, 0}, +{ 5, s_8_35, -1, 2, 0}, +{ 2, s_8_36, -1, 2, 0}, +{ 2, s_8_37, -1, 2, 0}, +{ 2, s_8_38, -1, 2, 0}, +{ 2, s_8_39, -1, 2, 0}, +{ 4, s_8_40, 39, 2, 0}, +{ 4, s_8_41, 39, 2, 0}, +{ 4, s_8_42, 39, 2, 0}, +{ 4, s_8_43, 39, 2, 0}, +{ 5, s_8_44, 39, 2, 0}, +{ 4, s_8_45, 39, 2, 0}, +{ 6, s_8_46, 45, 2, 0}, +{ 6, s_8_47, 45, 2, 0}, +{ 6, s_8_48, 45, 2, 0}, +{ 2, s_8_49, -1, 1, 0}, +{ 4, s_8_50, 49, 2, 0}, +{ 5, s_8_51, 49, 2, 0}, +{ 5, s_8_52, -1, 2, 0}, +{ 5, s_8_53, -1, 2, 0}, +{ 6, s_8_54, -1, 2, 0}, +{ 5, s_8_55, -1, 2, 0}, +{ 7, s_8_56, 55, 2, 0}, +{ 7, s_8_57, 55, 2, 0}, +{ 7, s_8_58, 55, 2, 0}, +{ 5, s_8_59, -1, 2, 0}, +{ 6, s_8_60, -1, 2, 0}, +{ 6, s_8_61, -1, 2, 0}, +{ 6, s_8_62, -1, 2, 0}, +{ 4, s_8_63, -1, 2, 0}, +{ 4, s_8_64, -1, 1, 0}, +{ 6, s_8_65, 64, 2, 0}, +{ 6, s_8_66, 64, 2, 0}, +{ 6, s_8_67, 64, 2, 0}, +{ 4, s_8_68, -1, 2, 0}, +{ 4, s_8_69, -1, 2, 0}, +{ 4, s_8_70, -1, 2, 0}, +{ 7, s_8_71, 70, 2, 0}, +{ 7, s_8_72, 70, 2, 0}, +{ 8, s_8_73, 70, 2, 0}, +{ 6, s_8_74, 70, 2, 0}, +{ 8, s_8_75, 74, 2, 0}, +{ 8, s_8_76, 74, 2, 0}, +{ 8, s_8_77, 74, 2, 0}, +{ 4, s_8_78, -1, 1, 0}, +{ 6, s_8_79, 78, 2, 0}, +{ 6, s_8_80, 78, 2, 0}, +{ 6, s_8_81, 78, 2, 0}, +{ 7, s_8_82, 78, 2, 0}, +{ 8, s_8_83, 78, 2, 0}, +{ 4, s_8_84, -1, 2, 0}, +{ 5, s_8_85, -1, 2, 0}, +{ 5, s_8_86, -1, 2, 0}, +{ 5, s_8_87, -1, 2, 0}, +{ 3, s_8_88, -1, 2, 0}, +{ 4, s_8_89, -1, 2, 0}, +{ 4, s_8_90, -1, 2, 0}, +{ 4, s_8_91, -1, 2, 0}, +{ 4, s_8_92, -1, 2, 0}, +{ 4, s_8_93, -1, 2, 0}, +{ 4, s_8_94, -1, 2, 0}, +{ 3, s_8_95, -1, 2, 0} }; static const symbol s_9_0[1] = { 'a' }; @@ -474,14 +474,14 @@ static const symbol s_9_7[2] = { 0xC3, 0xB3 }; static const struct among a_9[8] = { -/* 0 */ { 1, s_9_0, -1, 1, 0}, -/* 1 */ { 1, s_9_1, -1, 2, 0}, -/* 2 */ { 1, s_9_2, -1, 1, 0}, -/* 3 */ { 2, s_9_3, -1, 1, 0}, -/* 4 */ { 2, s_9_4, -1, 1, 0}, -/* 5 */ { 2, s_9_5, -1, 2, 0}, -/* 6 */ { 2, s_9_6, -1, 1, 0}, -/* 7 */ { 2, s_9_7, -1, 1, 0} +{ 1, s_9_0, -1, 1, 0}, +{ 1, s_9_1, -1, 2, 0}, +{ 1, s_9_2, -1, 1, 0}, +{ 2, s_9_3, -1, 1, 0}, +{ 2, s_9_4, -1, 1, 0}, +{ 2, s_9_5, -1, 2, 0}, +{ 2, s_9_6, -1, 1, 0}, +{ 2, s_9_7, -1, 1, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 10 }; @@ -503,16 +503,16 @@ static const symbol s_13[] = { 'e', 'n', 't', 'e' }; static const symbol s_14[] = { 'a', 't' }; static const symbol s_15[] = { 'a', 't' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $pV = , line 33 */ - z->I[1] = z->l; /* $p1 = , line 34 */ - z->I[2] = z->l; /* $p2 = , line 35 */ - { int c1 = z->c; /* do, line 37 */ - { int c2 = z->c; /* or, line 39 */ - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ - { int c3 = z->c; /* or, line 38 */ - if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab4; /* non v, line 38 */ - { /* gopast */ /* grouping v, line 38 */ +static int r_mark_regions(struct SN_env * z) { + z->I[2] = z->l; + z->I[1] = z->l; + z->I[0] = z->l; + { int c1 = z->c; + { int c2 = z->c; + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; + { int c3 = z->c; + if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab4; + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab4; z->c += ret; @@ -520,8 +520,8 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ - { /* gopast */ /* non v, line 38 */ + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; + { int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab2; z->c += ret; @@ -531,10 +531,10 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab0; /* non v, line 40 */ - { int c4 = z->c; /* or, line 40 */ - if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab6; /* non v, line 40 */ - { /* gopast */ /* grouping v, line 40 */ + if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab0; + { int c4 = z->c; + if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab6; + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab6; z->c += ret; @@ -542,89 +542,88 @@ static int r_mark_regions(struct SN_env * z) { /* forwardmode */ goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab0; /* grouping v, line 40 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab0; + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 40 */ + z->c = ret; } } lab5: ; } lab1: - z->I[0] = z->c; /* setmark pV, line 41 */ + z->I[2] = z->c; lab0: z->c = c1; } - { int c5 = z->c; /* do, line 43 */ - { /* gopast */ /* grouping v, line 44 */ + { int c5 = z->c; + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 44 */ + { int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 44 */ - { /* gopast */ /* grouping v, line 45 */ + z->I[1] = z->c; + { int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - { /* gopast */ /* non v, line 45 */ + { int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab7; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 45 */ + z->I[0] = z->c; lab7: z->c = c5; } return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ +static int r_postlude(struct SN_env * z) { int among_var; -/* repeat, line 49 */ - - while(1) { int c1 = z->c; - z->bra = z->c; /* [, line 50 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((67641858 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else /* substring, line 50 */ + while(1) { + int c1 = z->c; + z->bra = z->c; + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((67641858 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else among_var = find_among(z, a_0, 6); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 50 */ - switch (among_var) { /* among, line 50 */ + z->ket = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_0); /* <-, line 51 */ + { int ret = slice_from_s(z, 1, s_0); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_1); /* <-, line 52 */ + { int ret = slice_from_s(z, 1, s_1); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_2); /* <-, line 53 */ + { int ret = slice_from_s(z, 1, s_2); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_3); /* <-, line 54 */ + { int ret = slice_from_s(z, 1, s_3); if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 55 */ + { int ret = slice_from_s(z, 1, s_4); if (ret < 0) return ret; } break; case 6: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + { int ret = skip_utf8(z->p, z->c, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 57 */ + z->c = ret; } break; } @@ -636,73 +635,73 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_RV(struct SN_env * z) { /* backwardmode */ - if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 63 */ +static int r_RV(struct SN_env * z) { + if (!(z->I[2] <= z->c)) return 0; return 1; } -static int r_R1(struct SN_env * z) { /* backwardmode */ - if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 64 */ +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; return 1; } -static int r_R2(struct SN_env * z) { /* backwardmode */ - if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 65 */ +static int r_R2(struct SN_env * z) { + if (!(z->I[0] <= z->c)) return 0; return 1; } -static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ +static int r_attached_pronoun(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 68 */ + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_1, 13))) return 0; - z->bra = z->c; /* ], line 68 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* substring, line 72 */ + z->bra = z->c; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; among_var = find_among_b(z, a_2, 11); if (!(among_var)) return 0; - { int ret = r_RV(z); /* call RV, line 72 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - switch (among_var) { /* among, line 72 */ + switch (among_var) { case 1: - z->bra = z->c; /* ], line 73 */ - { int ret = slice_from_s(z, 5, s_5); /* <-, line 73 */ + z->bra = z->c; + { int ret = slice_from_s(z, 5, s_5); if (ret < 0) return ret; } break; case 2: - z->bra = z->c; /* ], line 74 */ - { int ret = slice_from_s(z, 4, s_6); /* <-, line 74 */ + z->bra = z->c; + { int ret = slice_from_s(z, 4, s_6); if (ret < 0) return ret; } break; case 3: - z->bra = z->c; /* ], line 75 */ - { int ret = slice_from_s(z, 2, s_7); /* <-, line 75 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_7); if (ret < 0) return ret; } break; case 4: - z->bra = z->c; /* ], line 76 */ - { int ret = slice_from_s(z, 2, s_8); /* <-, line 76 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_8); if (ret < 0) return ret; } break; case 5: - z->bra = z->c; /* ], line 77 */ - { int ret = slice_from_s(z, 2, s_9); /* <-, line 77 */ + z->bra = z->c; + { int ret = slice_from_s(z, 2, s_9); if (ret < 0) return ret; } break; case 6: - { int ret = slice_del(z); /* delete, line 81 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 7: - if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 82 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 82 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -710,38 +709,38 @@ static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ +static int r_standard_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 87 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + z->ket = z->c; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; among_var = find_among_b(z, a_6, 46); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 87 */ - switch (among_var) { /* among, line 87 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_R2(z); /* call R2, line 99 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 99 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); /* call R2, line 105 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 105 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 106 */ - z->ket = z->c; /* [, line 106 */ - if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m1; goto lab0; } /* literal, line 106 */ - z->bra = z->c; /* ], line 106 */ - { int ret = r_R2(z); /* call R2, line 106 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -749,59 +748,59 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 3: - { int ret = r_R2(z); /* call R2, line 111 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_11); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_11); if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); /* call R2, line 115 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_12); /* <-, line 115 */ + { int ret = slice_from_s(z, 1, s_12); if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); /* call R2, line 119 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_13); /* <-, line 119 */ + { int ret = slice_from_s(z, 4, s_13); if (ret < 0) return ret; } break; case 6: - { int ret = r_R1(z); /* call R1, line 123 */ + { int ret = r_R1(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 123 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 124 */ - z->ket = z->c; /* [, line 125 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 125 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } among_var = find_among_b(z, a_3, 4); if (!(among_var)) { z->c = z->l - m2; goto lab1; } - z->bra = z->c; /* ], line 125 */ - { int ret = r_R2(z); /* call R2, line 125 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 125 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - switch (among_var) { /* among, line 125 */ + switch (among_var) { case 1: - z->ket = z->c; /* [, line 126 */ - if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m2; goto lab1; } /* literal, line 126 */ - z->bra = z->c; /* ], line 126 */ - { int ret = r_R2(z); /* call R2, line 126 */ + z->ket = z->c; + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m2; goto lab1; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 126 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -811,22 +810,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 7: - { int ret = r_R2(z); /* call R2, line 135 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 135 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 136 */ - z->ket = z->c; /* [, line 137 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m3; goto lab2; } /* substring, line 137 */ + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m3; goto lab2; } if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } - z->bra = z->c; /* ], line 137 */ - { int ret = r_R2(z); /* call R2, line 140 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m3; goto lab2; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 140 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab2: @@ -834,22 +833,22 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 8: - { int ret = r_R2(z); /* call R2, line 147 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 147 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 148 */ - z->ket = z->c; /* [, line 149 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m4; goto lab3; } /* substring, line 149 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m4; goto lab3; } if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m4; goto lab3; } - z->bra = z->c; /* ], line 149 */ - { int ret = r_R2(z); /* call R2, line 152 */ + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 152 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab3: @@ -857,21 +856,21 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ } break; case 9: - { int ret = r_R2(z); /* call R2, line 159 */ + { int ret = r_R2(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 159 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* try, line 160 */ - z->ket = z->c; /* [, line 161 */ - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m5; goto lab4; } /* literal, line 161 */ - z->bra = z->c; /* ], line 161 */ - { int ret = r_R2(z); /* call R2, line 161 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m5; goto lab4; } + z->bra = z->c; + { int ret = r_R2(z); if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 161 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab4: @@ -882,56 +881,56 @@ static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_y_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_y_verb_suffix(struct SN_env * z) { - { int mlimit1; /* setlimit, line 168 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 168 */ - if (!(find_among_b(z, a_7, 12))) { z->lb = mlimit1; return 0; } /* substring, line 168 */ - z->bra = z->c; /* ], line 168 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + if (!(find_among_b(z, a_7, 12))) { z->lb = mlimit1; return 0; } + z->bra = z->c; z->lb = mlimit1; } - if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 171 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; z->c--; - { int ret = slice_del(z); /* delete, line 171 */ + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ +static int r_verb_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 176 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 176 */ - among_var = find_among_b(z, a_8, 96); /* substring, line 176 */ + { int mlimit1; + if (z->c < z->I[2]) return 0; + mlimit1 = z->lb; z->lb = z->I[2]; + z->ket = z->c; + among_var = find_among_b(z, a_8, 96); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 176 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 176 */ + switch (among_var) { case 1: - { int m2 = z->l - z->c; (void)m2; /* try, line 179 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m2; goto lab0; } z->c--; - { int m_test3 = z->l - z->c; /* test, line 179 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + { int m_test3 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m2; goto lab0; } z->c--; z->c = z->l - m_test3; } lab0: ; } - z->bra = z->c; /* ], line 179 */ - { int ret = slice_del(z); /* delete, line 179 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 200 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -939,43 +938,43 @@ static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ +static int r_residual_suffix(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 205 */ - among_var = find_among_b(z, a_9, 8); /* substring, line 205 */ + z->ket = z->c; + among_var = find_among_b(z, a_9, 8); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 205 */ - switch (among_var) { /* among, line 205 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = r_RV(z); /* call RV, line 208 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 208 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = r_RV(z); /* call RV, line 210 */ + { int ret = r_RV(z); if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 210 */ + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* try, line 210 */ - z->ket = z->c; /* [, line 210 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m1; goto lab0; } z->c--; - z->bra = z->c; /* ], line 210 */ - { int m_test2 = z->l - z->c; /* test, line 210 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + z->bra = z->c; + { int m_test2 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m1; goto lab0; } z->c--; z->c = z->l - m_test2; } - { int ret = r_RV(z); /* call RV, line 210 */ + { int ret = r_RV(z); if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 210 */ + { int ret = slice_del(z); if (ret < 0) return ret; } lab0: @@ -986,36 +985,36 @@ static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int spanish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - /* do, line 216 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 216 */ +extern int spanish_UTF_8_stem(struct SN_env * z) { + + { int ret = r_mark_regions(z); if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 217 */ + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 218 */ - { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 218 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_attached_pronoun(z); if (ret < 0) return ret; } z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 219 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 219 */ - { int ret = r_standard_suffix(z); /* call standard_suffix, line 219 */ + { int m2 = z->l - z->c; (void)m2; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_standard_suffix(z); if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: z->c = z->l - m3; - { int ret = r_y_verb_suffix(z); /* call y_verb_suffix, line 220 */ + { int ret = r_y_verb_suffix(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } goto lab1; lab3: z->c = z->l - m3; - { int ret = r_verb_suffix(z); /* call verb_suffix, line 221 */ + { int ret = r_verb_suffix(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -1024,15 +1023,15 @@ extern int spanish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 223 */ - { int ret = r_residual_suffix(z); /* call residual_suffix, line 223 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_residual_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; } z->c = z->lb; - { int c5 = z->c; /* do, line 225 */ - { int ret = r_postlude(z); /* call postlude, line 225 */ + { int c5 = z->c; + { int ret = r_postlude(z); if (ret < 0) return ret; } z->c = c5; @@ -1040,7 +1039,7 @@ extern int spanish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * spanish_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } +extern struct SN_env * spanish_UTF_8_create_env(void) { return SN_create_env(0, 3); } extern void spanish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c b/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c index b53fcccedea4..f2c445d04f20 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -65,43 +65,43 @@ static const symbol s_0_36[3] = { 'a', 's', 't' }; static const struct among a_0[37] = { -/* 0 */ { 1, s_0_0, -1, 1, 0}, -/* 1 */ { 4, s_0_1, 0, 1, 0}, -/* 2 */ { 4, s_0_2, 0, 1, 0}, -/* 3 */ { 7, s_0_3, 2, 1, 0}, -/* 4 */ { 4, s_0_4, 0, 1, 0}, -/* 5 */ { 2, s_0_5, -1, 1, 0}, -/* 6 */ { 1, s_0_6, -1, 1, 0}, -/* 7 */ { 3, s_0_7, 6, 1, 0}, -/* 8 */ { 4, s_0_8, 6, 1, 0}, -/* 9 */ { 4, s_0_9, 6, 1, 0}, -/* 10 */ { 3, s_0_10, 6, 1, 0}, -/* 11 */ { 4, s_0_11, 6, 1, 0}, -/* 12 */ { 2, s_0_12, -1, 1, 0}, -/* 13 */ { 5, s_0_13, 12, 1, 0}, -/* 14 */ { 4, s_0_14, 12, 1, 0}, -/* 15 */ { 5, s_0_15, 12, 1, 0}, -/* 16 */ { 3, s_0_16, -1, 1, 0}, -/* 17 */ { 2, s_0_17, -1, 1, 0}, -/* 18 */ { 2, s_0_18, -1, 1, 0}, -/* 19 */ { 5, s_0_19, 18, 1, 0}, -/* 20 */ { 2, s_0_20, -1, 1, 0}, -/* 21 */ { 1, s_0_21, -1, 2, 0}, -/* 22 */ { 2, s_0_22, 21, 1, 0}, -/* 23 */ { 5, s_0_23, 22, 1, 0}, -/* 24 */ { 5, s_0_24, 22, 1, 0}, -/* 25 */ { 5, s_0_25, 22, 1, 0}, -/* 26 */ { 2, s_0_26, 21, 1, 0}, -/* 27 */ { 4, s_0_27, 26, 1, 0}, -/* 28 */ { 5, s_0_28, 26, 1, 0}, -/* 29 */ { 3, s_0_29, 21, 1, 0}, -/* 30 */ { 5, s_0_30, 29, 1, 0}, -/* 31 */ { 6, s_0_31, 29, 1, 0}, -/* 32 */ { 4, s_0_32, 21, 1, 0}, -/* 33 */ { 2, s_0_33, -1, 1, 0}, -/* 34 */ { 5, s_0_34, -1, 1, 0}, -/* 35 */ { 3, s_0_35, -1, 1, 0}, -/* 36 */ { 3, s_0_36, -1, 1, 0} +{ 1, s_0_0, -1, 1, 0}, +{ 4, s_0_1, 0, 1, 0}, +{ 4, s_0_2, 0, 1, 0}, +{ 7, s_0_3, 2, 1, 0}, +{ 4, s_0_4, 0, 1, 0}, +{ 2, s_0_5, -1, 1, 0}, +{ 1, s_0_6, -1, 1, 0}, +{ 3, s_0_7, 6, 1, 0}, +{ 4, s_0_8, 6, 1, 0}, +{ 4, s_0_9, 6, 1, 0}, +{ 3, s_0_10, 6, 1, 0}, +{ 4, s_0_11, 6, 1, 0}, +{ 2, s_0_12, -1, 1, 0}, +{ 5, s_0_13, 12, 1, 0}, +{ 4, s_0_14, 12, 1, 0}, +{ 5, s_0_15, 12, 1, 0}, +{ 3, s_0_16, -1, 1, 0}, +{ 2, s_0_17, -1, 1, 0}, +{ 2, s_0_18, -1, 1, 0}, +{ 5, s_0_19, 18, 1, 0}, +{ 2, s_0_20, -1, 1, 0}, +{ 1, s_0_21, -1, 2, 0}, +{ 2, s_0_22, 21, 1, 0}, +{ 5, s_0_23, 22, 1, 0}, +{ 5, s_0_24, 22, 1, 0}, +{ 5, s_0_25, 22, 1, 0}, +{ 2, s_0_26, 21, 1, 0}, +{ 4, s_0_27, 26, 1, 0}, +{ 5, s_0_28, 26, 1, 0}, +{ 3, s_0_29, 21, 1, 0}, +{ 5, s_0_30, 29, 1, 0}, +{ 6, s_0_31, 29, 1, 0}, +{ 4, s_0_32, 21, 1, 0}, +{ 2, s_0_33, -1, 1, 0}, +{ 5, s_0_34, -1, 1, 0}, +{ 3, s_0_35, -1, 1, 0}, +{ 3, s_0_36, -1, 1, 0} }; static const symbol s_1_0[2] = { 'd', 'd' }; @@ -114,13 +114,13 @@ static const symbol s_1_6[2] = { 't', 't' }; static const struct among a_1[7] = { -/* 0 */ { 2, s_1_0, -1, -1, 0}, -/* 1 */ { 2, s_1_1, -1, -1, 0}, -/* 2 */ { 2, s_1_2, -1, -1, 0}, -/* 3 */ { 2, s_1_3, -1, -1, 0}, -/* 4 */ { 2, s_1_4, -1, -1, 0}, -/* 5 */ { 2, s_1_5, -1, -1, 0}, -/* 6 */ { 2, s_1_6, -1, -1, 0} +{ 2, s_1_0, -1, -1, 0}, +{ 2, s_1_1, -1, -1, 0}, +{ 2, s_1_2, -1, -1, 0}, +{ 2, s_1_3, -1, -1, 0}, +{ 2, s_1_4, -1, -1, 0}, +{ 2, s_1_5, -1, -1, 0}, +{ 2, s_1_6, -1, -1, 0} }; static const symbol s_2_0[2] = { 'i', 'g' }; @@ -131,11 +131,11 @@ static const symbol s_2_4[5] = { 'l', 0xC3, 0xB6, 's', 't' }; static const struct among a_2[5] = { -/* 0 */ { 2, s_2_0, -1, 1, 0}, -/* 1 */ { 3, s_2_1, 0, 1, 0}, -/* 2 */ { 3, s_2_2, -1, 1, 0}, -/* 3 */ { 5, s_2_3, -1, 3, 0}, -/* 4 */ { 5, s_2_4, -1, 2, 0} +{ 2, s_2_0, -1, 1, 0}, +{ 3, s_2_1, 0, 1, 0}, +{ 3, s_2_2, -1, 1, 0}, +{ 5, s_2_3, -1, 3, 0}, +{ 5, s_2_4, -1, 2, 0} }; static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 32 }; @@ -145,52 +145,52 @@ static const unsigned char g_s_ending[] = { 119, 127, 149 }; static const symbol s_0[] = { 'l', 0xC3, 0xB6, 's' }; static const symbol s_1[] = { 'f', 'u', 'l', 'l' }; -static int r_mark_regions(struct SN_env * z) { /* forwardmode */ - z->I[0] = z->l; /* $p1 = , line 28 */ - { int c_test1 = z->c; /* test, line 29 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 29 */ +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + { int c_test1 = z->c; + { int ret = skip_utf8(z->p, z->c, z->l, 3); if (ret < 0) return 0; z->c = ret; } - z->I[1] = z->c; /* setmark x, line 29 */ + z->I[0] = z->c; z->c = c_test1; } - if (out_grouping_U(z, g_v, 97, 246, 1) < 0) return 0; /* goto */ /* grouping v, line 30 */ - { /* gopast */ /* non v, line 30 */ + if (out_grouping_U(z, g_v, 97, 246, 1) < 0) return 0; + { int ret = in_grouping_U(z, g_v, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 30 */ - /* try, line 31 */ - if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 31 */ - z->I[0] = z->I[1]; /* $p1 = , line 31 */ + z->I[1] = z->c; + + if (!(z->I[1] < z->I[0])) goto lab0; + z->I[1] = z->I[0]; lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { /* backwardmode */ +static int r_main_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 37 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 37 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 37 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_0, 37); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 37 */ + z->bra = z->c; z->lb = mlimit1; } - switch (among_var) { /* among, line 38 */ + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 44 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - if (in_grouping_b_U(z, g_s_ending, 98, 121, 0)) return 0; /* grouping s_ending, line 46 */ - { int ret = slice_del(z); /* delete, line 46 */ + if (in_grouping_b_U(z, g_s_ending, 98, 121, 0)) return 0; + { int ret = slice_del(z); if (ret < 0) return ret; } break; @@ -198,22 +198,22 @@ static int r_main_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ +static int r_consonant_pair(struct SN_env * z) { - { int mlimit1; /* setlimit, line 50 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - { int m2 = z->l - z->c; (void)m2; /* and, line 52 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* among, line 51 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + { int m2 = z->l - z->c; (void)m2; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit1; return 0; } z->c = z->l - m2; - z->ket = z->c; /* [, line 52 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + z->ket = z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) { z->lb = mlimit1; return 0; } - z->c = ret; /* next, line 52 */ + z->c = ret; } - z->bra = z->c; /* ], line 52 */ - { int ret = slice_del(z); /* delete, line 52 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } } @@ -222,30 +222,30 @@ static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_other_suffix(struct SN_env * z) { /* backwardmode */ +static int r_other_suffix(struct SN_env * z) { int among_var; - { int mlimit1; /* setlimit, line 55 */ - if (z->c < z->I[0]) return 0; - mlimit1 = z->lb; z->lb = z->I[0]; - z->ket = z->c; /* [, line 56 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 56 */ + { int mlimit1; + if (z->c < z->I[1]) return 0; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } among_var = find_among_b(z, a_2, 5); if (!(among_var)) { z->lb = mlimit1; return 0; } - z->bra = z->c; /* ], line 56 */ - switch (among_var) { /* among, line 56 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_del(z); /* delete, line 57 */ + { int ret = slice_del(z); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_0); /* <-, line 58 */ + { int ret = slice_from_s(z, 4, s_0); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_1); /* <-, line 59 */ + { int ret = slice_from_s(z, 4, s_1); if (ret < 0) return ret; } break; @@ -255,29 +255,29 @@ static int r_other_suffix(struct SN_env * z) { /* backwardmode */ return 1; } -extern int swedish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 66 */ - { int ret = r_mark_regions(z); /* call mark_regions, line 66 */ +extern int swedish_UTF_8_stem(struct SN_env * z) { + { int c1 = z->c; + { int ret = r_mark_regions(z); if (ret < 0) return ret; } z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 67 */ + z->lb = z->c; z->c = z->l; - { int m2 = z->l - z->c; (void)m2; /* do, line 68 */ - { int ret = r_main_suffix(z); /* call main_suffix, line 68 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_main_suffix(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 69 */ - { int ret = r_consonant_pair(z); /* call consonant_pair, line 69 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_consonant_pair(z); if (ret < 0) return ret; } z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 70 */ - { int ret = r_other_suffix(z); /* call other_suffix, line 70 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_other_suffix(z); if (ret < 0) return ret; } z->c = z->l - m4; @@ -286,7 +286,7 @@ extern int swedish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * swedish_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } +extern struct SN_env * swedish_UTF_8_create_env(void) { return SN_create_env(0, 2); } extern void swedish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_tamil.c b/src/backend/snowball/libstemmer/stem_UTF_8_tamil.c index ac038a8e37ba..6f70b83b2996 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_tamil.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_tamil.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -48,16 +48,16 @@ static const symbol s_0_9[3] = { 0xE0, 0xAE, 0xB5 }; static const struct among a_0[10] = { -/* 0 */ { 3, s_0_0, -1, -1, 0}, -/* 1 */ { 3, s_0_1, -1, -1, 0}, -/* 2 */ { 3, s_0_2, -1, -1, 0}, -/* 3 */ { 3, s_0_3, -1, -1, 0}, -/* 4 */ { 3, s_0_4, -1, -1, 0}, -/* 5 */ { 3, s_0_5, -1, -1, 0}, -/* 6 */ { 3, s_0_6, -1, -1, 0}, -/* 7 */ { 3, s_0_7, -1, -1, 0}, -/* 8 */ { 3, s_0_8, -1, -1, 0}, -/* 9 */ { 3, s_0_9, -1, -1, 0} +{ 3, s_0_0, -1, -1, 0}, +{ 3, s_0_1, -1, -1, 0}, +{ 3, s_0_2, -1, -1, 0}, +{ 3, s_0_3, -1, -1, 0}, +{ 3, s_0_4, -1, -1, 0}, +{ 3, s_0_5, -1, -1, 0}, +{ 3, s_0_6, -1, -1, 0}, +{ 3, s_0_7, -1, -1, 0}, +{ 3, s_0_8, -1, -1, 0}, +{ 3, s_0_9, -1, -1, 0} }; static const symbol s_1_0[12] = { 0xE0, 0xAE, 0xA8, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x8D }; @@ -66,9 +66,9 @@ static const symbol s_1_2[9] = { 0xE0, 0xAE, 0xA8, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, static const struct among a_1[3] = { -/* 0 */ { 12, s_1_0, -1, -1, 0}, -/* 1 */ { 6, s_1_1, -1, -1, 0}, -/* 2 */ { 9, s_1_2, -1, -1, 0} +{ 12, s_1_0, -1, -1, 0}, +{ 6, s_1_1, -1, -1, 0}, +{ 9, s_1_2, -1, -1, 0} }; static const symbol s_2_0[3] = { 0xE0, 0xAF, 0x80 }; @@ -77,9 +77,9 @@ static const symbol s_2_2[3] = { 0xE0, 0xAE, 0xBF }; static const struct among a_2[3] = { -/* 0 */ { 3, s_2_0, -1, -1, 0}, -/* 1 */ { 3, s_2_1, -1, -1, 0}, -/* 2 */ { 3, s_2_2, -1, -1, 0} +{ 3, s_2_0, -1, -1, 0}, +{ 3, s_2_1, -1, -1, 0}, +{ 3, s_2_2, -1, -1, 0} }; static const symbol s_3_0[3] = { 0xE0, 0xAE, 0x95 }; @@ -91,12 +91,12 @@ static const symbol s_3_5[3] = { 0xE0, 0xAE, 0xB1 }; static const struct among a_3[6] = { -/* 0 */ { 3, s_3_0, -1, -1, 0}, -/* 1 */ { 3, s_3_1, -1, -1, 0}, -/* 2 */ { 3, s_3_2, -1, -1, 0}, -/* 3 */ { 3, s_3_3, -1, -1, 0}, -/* 4 */ { 3, s_3_4, -1, -1, 0}, -/* 5 */ { 3, s_3_5, -1, -1, 0} +{ 3, s_3_0, -1, -1, 0}, +{ 3, s_3_1, -1, -1, 0}, +{ 3, s_3_2, -1, -1, 0}, +{ 3, s_3_3, -1, -1, 0}, +{ 3, s_3_4, -1, -1, 0}, +{ 3, s_3_5, -1, -1, 0} }; static const symbol s_4_0[3] = { 0xE0, 0xAE, 0x95 }; @@ -108,12 +108,12 @@ static const symbol s_4_5[3] = { 0xE0, 0xAE, 0xB1 }; static const struct among a_4[6] = { -/* 0 */ { 3, s_4_0, -1, -1, 0}, -/* 1 */ { 3, s_4_1, -1, -1, 0}, -/* 2 */ { 3, s_4_2, -1, -1, 0}, -/* 3 */ { 3, s_4_3, -1, -1, 0}, -/* 4 */ { 3, s_4_4, -1, -1, 0}, -/* 5 */ { 3, s_4_5, -1, -1, 0} +{ 3, s_4_0, -1, -1, 0}, +{ 3, s_4_1, -1, -1, 0}, +{ 3, s_4_2, -1, -1, 0}, +{ 3, s_4_3, -1, -1, 0}, +{ 3, s_4_4, -1, -1, 0}, +{ 3, s_4_5, -1, -1, 0} }; static const symbol s_5_0[3] = { 0xE0, 0xAE, 0x95 }; @@ -125,12 +125,12 @@ static const symbol s_5_5[3] = { 0xE0, 0xAE, 0xB1 }; static const struct among a_5[6] = { -/* 0 */ { 3, s_5_0, -1, -1, 0}, -/* 1 */ { 3, s_5_1, -1, -1, 0}, -/* 2 */ { 3, s_5_2, -1, -1, 0}, -/* 3 */ { 3, s_5_3, -1, -1, 0}, -/* 4 */ { 3, s_5_4, -1, -1, 0}, -/* 5 */ { 3, s_5_5, -1, -1, 0} +{ 3, s_5_0, -1, -1, 0}, +{ 3, s_5_1, -1, -1, 0}, +{ 3, s_5_2, -1, -1, 0}, +{ 3, s_5_3, -1, -1, 0}, +{ 3, s_5_4, -1, -1, 0}, +{ 3, s_5_5, -1, -1, 0} }; static const symbol s_6_0[3] = { 0xE0, 0xAE, 0xAF }; @@ -142,12 +142,12 @@ static const symbol s_6_5[3] = { 0xE0, 0xAE, 0xB5 }; static const struct among a_6[6] = { -/* 0 */ { 3, s_6_0, -1, -1, 0}, -/* 1 */ { 3, s_6_1, -1, -1, 0}, -/* 2 */ { 3, s_6_2, -1, -1, 0}, -/* 3 */ { 3, s_6_3, -1, -1, 0}, -/* 4 */ { 3, s_6_4, -1, -1, 0}, -/* 5 */ { 3, s_6_5, -1, -1, 0} +{ 3, s_6_0, -1, -1, 0}, +{ 3, s_6_1, -1, -1, 0}, +{ 3, s_6_2, -1, -1, 0}, +{ 3, s_6_3, -1, -1, 0}, +{ 3, s_6_4, -1, -1, 0}, +{ 3, s_6_5, -1, -1, 0} }; static const symbol s_7_0[3] = { 0xE0, 0xAE, 0x99 }; @@ -159,12 +159,12 @@ static const symbol s_7_5[3] = { 0xE0, 0xAE, 0xAE }; static const struct among a_7[6] = { -/* 0 */ { 3, s_7_0, -1, -1, 0}, -/* 1 */ { 3, s_7_1, -1, -1, 0}, -/* 2 */ { 3, s_7_2, -1, -1, 0}, -/* 3 */ { 3, s_7_3, -1, -1, 0}, -/* 4 */ { 3, s_7_4, -1, -1, 0}, -/* 5 */ { 3, s_7_5, -1, -1, 0} +{ 3, s_7_0, -1, -1, 0}, +{ 3, s_7_1, -1, -1, 0}, +{ 3, s_7_2, -1, -1, 0}, +{ 3, s_7_3, -1, -1, 0}, +{ 3, s_7_4, -1, -1, 0}, +{ 3, s_7_5, -1, -1, 0} }; static const symbol s_8_0[6] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x8D }; @@ -173,9 +173,9 @@ static const symbol s_8_2[3] = { 0xE0, 0xAE, 0xB5 }; static const struct among a_8[3] = { -/* 0 */ { 6, s_8_0, -1, -1, 0}, -/* 1 */ { 3, s_8_1, -1, -1, 0}, -/* 2 */ { 3, s_8_2, -1, -1, 0} +{ 6, s_8_0, -1, -1, 0}, +{ 3, s_8_1, -1, -1, 0}, +{ 3, s_8_2, -1, -1, 0} }; static const symbol s_9_0[3] = { 0xE0, 0xAF, 0x80 }; @@ -189,14 +189,14 @@ static const symbol s_9_7[3] = { 0xE0, 0xAE, 0xBF }; static const struct among a_9[8] = { -/* 0 */ { 3, s_9_0, -1, -1, 0}, -/* 1 */ { 3, s_9_1, -1, -1, 0}, -/* 2 */ { 3, s_9_2, -1, -1, 0}, -/* 3 */ { 3, s_9_3, -1, -1, 0}, -/* 4 */ { 3, s_9_4, -1, -1, 0}, -/* 5 */ { 3, s_9_5, -1, -1, 0}, -/* 6 */ { 3, s_9_6, -1, -1, 0}, -/* 7 */ { 3, s_9_7, -1, -1, 0} +{ 3, s_9_0, -1, -1, 0}, +{ 3, s_9_1, -1, -1, 0}, +{ 3, s_9_2, -1, -1, 0}, +{ 3, s_9_3, -1, -1, 0}, +{ 3, s_9_4, -1, -1, 0}, +{ 3, s_9_5, -1, -1, 0}, +{ 3, s_9_6, -1, -1, 0}, +{ 3, s_9_7, -1, -1, 0} }; static const symbol s_10_0[3] = { 0xE0, 0xAF, 0x80 }; @@ -210,14 +210,14 @@ static const symbol s_10_7[3] = { 0xE0, 0xAE, 0xBF }; static const struct among a_10[8] = { -/* 0 */ { 3, s_10_0, -1, -1, 0}, -/* 1 */ { 3, s_10_1, -1, -1, 0}, -/* 2 */ { 3, s_10_2, -1, -1, 0}, -/* 3 */ { 3, s_10_3, -1, -1, 0}, -/* 4 */ { 3, s_10_4, -1, -1, 0}, -/* 5 */ { 3, s_10_5, -1, -1, 0}, -/* 6 */ { 3, s_10_6, -1, -1, 0}, -/* 7 */ { 3, s_10_7, -1, -1, 0} +{ 3, s_10_0, -1, -1, 0}, +{ 3, s_10_1, -1, -1, 0}, +{ 3, s_10_2, -1, -1, 0}, +{ 3, s_10_3, -1, -1, 0}, +{ 3, s_10_4, -1, -1, 0}, +{ 3, s_10_5, -1, -1, 0}, +{ 3, s_10_6, -1, -1, 0}, +{ 3, s_10_7, -1, -1, 0} }; static const symbol s_11_0[3] = { 0xE0, 0xAE, 0x85 }; @@ -226,9 +226,9 @@ static const symbol s_11_2[3] = { 0xE0, 0xAE, 0x89 }; static const struct among a_11[3] = { -/* 0 */ { 3, s_11_0, -1, -1, 0}, -/* 1 */ { 3, s_11_1, -1, -1, 0}, -/* 2 */ { 3, s_11_2, -1, -1, 0} +{ 3, s_11_0, -1, -1, 0}, +{ 3, s_11_1, -1, -1, 0}, +{ 3, s_11_2, -1, -1, 0} }; static const symbol s_12_0[3] = { 0xE0, 0xAE, 0x95 }; @@ -244,16 +244,16 @@ static const symbol s_12_9[3] = { 0xE0, 0xAE, 0xB5 }; static const struct among a_12[10] = { -/* 0 */ { 3, s_12_0, -1, -1, 0}, -/* 1 */ { 3, s_12_1, -1, -1, 0}, -/* 2 */ { 3, s_12_2, -1, -1, 0}, -/* 3 */ { 3, s_12_3, -1, -1, 0}, -/* 4 */ { 3, s_12_4, -1, -1, 0}, -/* 5 */ { 3, s_12_5, -1, -1, 0}, -/* 6 */ { 3, s_12_6, -1, -1, 0}, -/* 7 */ { 3, s_12_7, -1, -1, 0}, -/* 8 */ { 3, s_12_8, -1, -1, 0}, -/* 9 */ { 3, s_12_9, -1, -1, 0} +{ 3, s_12_0, -1, -1, 0}, +{ 3, s_12_1, -1, -1, 0}, +{ 3, s_12_2, -1, -1, 0}, +{ 3, s_12_3, -1, -1, 0}, +{ 3, s_12_4, -1, -1, 0}, +{ 3, s_12_5, -1, -1, 0}, +{ 3, s_12_6, -1, -1, 0}, +{ 3, s_12_7, -1, -1, 0}, +{ 3, s_12_8, -1, -1, 0}, +{ 3, s_12_9, -1, -1, 0} }; static const symbol s_13_0[3] = { 0xE0, 0xAE, 0x95 }; @@ -265,12 +265,12 @@ static const symbol s_13_5[3] = { 0xE0, 0xAE, 0xB1 }; static const struct among a_13[6] = { -/* 0 */ { 3, s_13_0, -1, -1, 0}, -/* 1 */ { 3, s_13_1, -1, -1, 0}, -/* 2 */ { 3, s_13_2, -1, -1, 0}, -/* 3 */ { 3, s_13_3, -1, -1, 0}, -/* 4 */ { 3, s_13_4, -1, -1, 0}, -/* 5 */ { 3, s_13_5, -1, -1, 0} +{ 3, s_13_0, -1, -1, 0}, +{ 3, s_13_1, -1, -1, 0}, +{ 3, s_13_2, -1, -1, 0}, +{ 3, s_13_3, -1, -1, 0}, +{ 3, s_13_4, -1, -1, 0}, +{ 3, s_13_5, -1, -1, 0} }; static const symbol s_14_0[3] = { 0xE0, 0xAF, 0x87 }; @@ -279,9 +279,9 @@ static const symbol s_14_2[3] = { 0xE0, 0xAE, 0xBE }; static const struct among a_14[3] = { -/* 0 */ { 3, s_14_0, -1, -1, 0}, -/* 1 */ { 3, s_14_1, -1, -1, 0}, -/* 2 */ { 3, s_14_2, -1, -1, 0} +{ 3, s_14_0, -1, -1, 0}, +{ 3, s_14_1, -1, -1, 0}, +{ 3, s_14_2, -1, -1, 0} }; static const symbol s_15_0[6] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xBF }; @@ -289,8 +289,8 @@ static const symbol s_15_1[6] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xBF }; static const struct among a_15[2] = { -/* 0 */ { 6, s_15_0, -1, -1, 0}, -/* 1 */ { 6, s_15_1, -1, -1, 0} +{ 6, s_15_0, -1, -1, 0}, +{ 6, s_15_1, -1, -1, 0} }; static const symbol s_16_0[3] = { 0xE0, 0xAF, 0x80 }; @@ -304,14 +304,14 @@ static const symbol s_16_7[3] = { 0xE0, 0xAE, 0xBF }; static const struct among a_16[8] = { -/* 0 */ { 3, s_16_0, -1, -1, 0}, -/* 1 */ { 3, s_16_1, -1, -1, 0}, -/* 2 */ { 3, s_16_2, -1, -1, 0}, -/* 3 */ { 3, s_16_3, -1, -1, 0}, -/* 4 */ { 3, s_16_4, -1, -1, 0}, -/* 5 */ { 3, s_16_5, -1, -1, 0}, -/* 6 */ { 3, s_16_6, -1, -1, 0}, -/* 7 */ { 3, s_16_7, -1, -1, 0} +{ 3, s_16_0, -1, -1, 0}, +{ 3, s_16_1, -1, -1, 0}, +{ 3, s_16_2, -1, -1, 0}, +{ 3, s_16_3, -1, -1, 0}, +{ 3, s_16_4, -1, -1, 0}, +{ 3, s_16_5, -1, -1, 0}, +{ 3, s_16_6, -1, -1, 0}, +{ 3, s_16_7, -1, -1, 0} }; static const symbol s_17_0[15] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; @@ -330,19 +330,19 @@ static const symbol s_17_12[15] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xB1, 0xE0, 0x static const struct among a_17[13] = { -/* 0 */ { 15, s_17_0, -1, -1, 0}, -/* 1 */ { 18, s_17_1, -1, -1, 0}, -/* 2 */ { 9, s_17_2, -1, -1, 0}, -/* 3 */ { 12, s_17_3, -1, -1, 0}, -/* 4 */ { 18, s_17_4, -1, -1, 0}, -/* 5 */ { 21, s_17_5, -1, -1, 0}, -/* 6 */ { 12, s_17_6, -1, -1, 0}, -/* 7 */ { 15, s_17_7, -1, -1, 0}, -/* 8 */ { 9, s_17_8, -1, -1, 0}, -/* 9 */ { 18, s_17_9, 8, -1, 0}, -/* 10 */ { 15, s_17_10, -1, -1, 0}, -/* 11 */ { 9, s_17_11, -1, -1, 0}, -/* 12 */ { 15, s_17_12, -1, -1, 0} +{ 15, s_17_0, -1, -1, 0}, +{ 18, s_17_1, -1, -1, 0}, +{ 9, s_17_2, -1, -1, 0}, +{ 12, s_17_3, -1, -1, 0}, +{ 18, s_17_4, -1, -1, 0}, +{ 21, s_17_5, -1, -1, 0}, +{ 12, s_17_6, -1, -1, 0}, +{ 15, s_17_7, -1, -1, 0}, +{ 9, s_17_8, -1, -1, 0}, +{ 18, s_17_9, 8, -1, 0}, +{ 15, s_17_10, -1, -1, 0}, +{ 9, s_17_11, -1, -1, 0}, +{ 15, s_17_12, -1, -1, 0} }; static const symbol s_18_0[3] = { 0xE0, 0xAE, 0x95 }; @@ -354,12 +354,12 @@ static const symbol s_18_5[3] = { 0xE0, 0xAE, 0xB1 }; static const struct among a_18[6] = { -/* 0 */ { 3, s_18_0, -1, -1, 0}, -/* 1 */ { 3, s_18_1, -1, -1, 0}, -/* 2 */ { 3, s_18_2, -1, -1, 0}, -/* 3 */ { 3, s_18_3, -1, -1, 0}, -/* 4 */ { 3, s_18_4, -1, -1, 0}, -/* 5 */ { 3, s_18_5, -1, -1, 0} +{ 3, s_18_0, -1, -1, 0}, +{ 3, s_18_1, -1, -1, 0}, +{ 3, s_18_2, -1, -1, 0}, +{ 3, s_18_3, -1, -1, 0}, +{ 3, s_18_4, -1, -1, 0}, +{ 3, s_18_5, -1, -1, 0} }; static const symbol s_19_0[3] = { 0xE0, 0xAE, 0x95 }; @@ -371,12 +371,12 @@ static const symbol s_19_5[3] = { 0xE0, 0xAE, 0xB1 }; static const struct among a_19[6] = { -/* 0 */ { 3, s_19_0, -1, -1, 0}, -/* 1 */ { 3, s_19_1, -1, -1, 0}, -/* 2 */ { 3, s_19_2, -1, -1, 0}, -/* 3 */ { 3, s_19_3, -1, -1, 0}, -/* 4 */ { 3, s_19_4, -1, -1, 0}, -/* 5 */ { 3, s_19_5, -1, -1, 0} +{ 3, s_19_0, -1, -1, 0}, +{ 3, s_19_1, -1, -1, 0}, +{ 3, s_19_2, -1, -1, 0}, +{ 3, s_19_3, -1, -1, 0}, +{ 3, s_19_4, -1, -1, 0}, +{ 3, s_19_5, -1, -1, 0} }; static const symbol s_20_0[3] = { 0xE0, 0xAF, 0x80 }; @@ -390,14 +390,14 @@ static const symbol s_20_7[3] = { 0xE0, 0xAE, 0xBF }; static const struct among a_20[8] = { -/* 0 */ { 3, s_20_0, -1, -1, 0}, -/* 1 */ { 3, s_20_1, -1, -1, 0}, -/* 2 */ { 3, s_20_2, -1, -1, 0}, -/* 3 */ { 3, s_20_3, -1, -1, 0}, -/* 4 */ { 3, s_20_4, -1, -1, 0}, -/* 5 */ { 3, s_20_5, -1, -1, 0}, -/* 6 */ { 3, s_20_6, -1, -1, 0}, -/* 7 */ { 3, s_20_7, -1, -1, 0} +{ 3, s_20_0, -1, -1, 0}, +{ 3, s_20_1, -1, -1, 0}, +{ 3, s_20_2, -1, -1, 0}, +{ 3, s_20_3, -1, -1, 0}, +{ 3, s_20_4, -1, -1, 0}, +{ 3, s_20_5, -1, -1, 0}, +{ 3, s_20_6, -1, -1, 0}, +{ 3, s_20_7, -1, -1, 0} }; static const symbol s_21_0[3] = { 0xE0, 0xAF, 0x80 }; @@ -411,14 +411,14 @@ static const symbol s_21_7[3] = { 0xE0, 0xAE, 0xBF }; static const struct among a_21[8] = { -/* 0 */ { 3, s_21_0, -1, -1, 0}, -/* 1 */ { 3, s_21_1, -1, -1, 0}, -/* 2 */ { 3, s_21_2, -1, -1, 0}, -/* 3 */ { 3, s_21_3, -1, -1, 0}, -/* 4 */ { 3, s_21_4, -1, -1, 0}, -/* 5 */ { 3, s_21_5, -1, -1, 0}, -/* 6 */ { 3, s_21_6, -1, -1, 0}, -/* 7 */ { 3, s_21_7, -1, -1, 0} +{ 3, s_21_0, -1, -1, 0}, +{ 3, s_21_1, -1, -1, 0}, +{ 3, s_21_2, -1, -1, 0}, +{ 3, s_21_3, -1, -1, 0}, +{ 3, s_21_4, -1, -1, 0}, +{ 3, s_21_5, -1, -1, 0}, +{ 3, s_21_6, -1, -1, 0}, +{ 3, s_21_7, -1, -1, 0} }; static const symbol s_22_0[9] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; @@ -426,8 +426,8 @@ static const symbol s_22_1[24] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8A, 0xE0, 0xA static const struct among a_22[2] = { -/* 0 */ { 9, s_22_0, -1, -1, 0}, -/* 1 */ { 24, s_22_1, -1, -1, 0} +{ 9, s_22_0, -1, -1, 0}, +{ 24, s_22_1, -1, -1, 0} }; static const symbol s_23_0[3] = { 0xE0, 0xAE, 0x85 }; @@ -445,18 +445,18 @@ static const symbol s_23_11[3] = { 0xE0, 0xAE, 0x94 }; static const struct among a_23[12] = { -/* 0 */ { 3, s_23_0, -1, -1, 0}, -/* 1 */ { 3, s_23_1, -1, -1, 0}, -/* 2 */ { 3, s_23_2, -1, -1, 0}, -/* 3 */ { 3, s_23_3, -1, -1, 0}, -/* 4 */ { 3, s_23_4, -1, -1, 0}, -/* 5 */ { 3, s_23_5, -1, -1, 0}, -/* 6 */ { 3, s_23_6, -1, -1, 0}, -/* 7 */ { 3, s_23_7, -1, -1, 0}, -/* 8 */ { 3, s_23_8, -1, -1, 0}, -/* 9 */ { 3, s_23_9, -1, -1, 0}, -/* 10 */ { 3, s_23_10, -1, -1, 0}, -/* 11 */ { 3, s_23_11, -1, -1, 0} +{ 3, s_23_0, -1, -1, 0}, +{ 3, s_23_1, -1, -1, 0}, +{ 3, s_23_2, -1, -1, 0}, +{ 3, s_23_3, -1, -1, 0}, +{ 3, s_23_4, -1, -1, 0}, +{ 3, s_23_5, -1, -1, 0}, +{ 3, s_23_6, -1, -1, 0}, +{ 3, s_23_7, -1, -1, 0}, +{ 3, s_23_8, -1, -1, 0}, +{ 3, s_23_9, -1, -1, 0}, +{ 3, s_23_10, -1, -1, 0}, +{ 3, s_23_11, -1, -1, 0} }; static const symbol s_24_0[3] = { 0xE0, 0xAF, 0x80 }; @@ -470,14 +470,14 @@ static const symbol s_24_7[3] = { 0xE0, 0xAE, 0xBF }; static const struct among a_24[8] = { -/* 0 */ { 3, s_24_0, -1, -1, 0}, -/* 1 */ { 3, s_24_1, -1, -1, 0}, -/* 2 */ { 3, s_24_2, -1, -1, 0}, -/* 3 */ { 3, s_24_3, -1, -1, 0}, -/* 4 */ { 3, s_24_4, -1, -1, 0}, -/* 5 */ { 3, s_24_5, -1, -1, 0}, -/* 6 */ { 3, s_24_6, -1, -1, 0}, -/* 7 */ { 3, s_24_7, -1, -1, 0} +{ 3, s_24_0, -1, -1, 0}, +{ 3, s_24_1, -1, -1, 0}, +{ 3, s_24_2, -1, -1, 0}, +{ 3, s_24_3, -1, -1, 0}, +{ 3, s_24_4, -1, -1, 0}, +{ 3, s_24_5, -1, -1, 0}, +{ 3, s_24_6, -1, -1, 0}, +{ 3, s_24_7, -1, -1, 0} }; static const symbol s_25_0[18] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D }; @@ -489,12 +489,12 @@ static const symbol s_25_5[9] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE static const struct among a_25[6] = { -/* 0 */ { 18, s_25_0, -1, -1, 0}, -/* 1 */ { 21, s_25_1, -1, -1, 0}, -/* 2 */ { 12, s_25_2, -1, -1, 0}, -/* 3 */ { 15, s_25_3, -1, -1, 0}, -/* 4 */ { 18, s_25_4, -1, -1, 0}, -/* 5 */ { 9, s_25_5, -1, -1, 0} +{ 18, s_25_0, -1, -1, 0}, +{ 21, s_25_1, -1, -1, 0}, +{ 12, s_25_2, -1, -1, 0}, +{ 15, s_25_3, -1, -1, 0}, +{ 18, s_25_4, -1, -1, 0}, +{ 9, s_25_5, -1, -1, 0} }; static const symbol s_0[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x8B }; @@ -654,76 +654,76 @@ static const symbol s_153[] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x81 }; static const symbol s_154[] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81 }; static const symbol s_155[] = { 0xE0, 0xAF, 0x8D }; -static int r_has_min_length(struct SN_env * z) { /* forwardmode */ - if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 100 */ +static int r_has_min_length(struct SN_env * z) { + if (!(len_utf8(z->p) > 4)) return 0; return 1; } -static int r_fix_va_start(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* or, line 104 */ - { int c2 = z->c; /* and, line 104 */ - { int c3 = z->c; /* try, line 104 */ - if (!(eq_s(z, 6, s_0))) { z->c = c3; goto lab2; } /* literal, line 104 */ +static int r_fix_va_start(struct SN_env * z) { + { int c1 = z->c; + { int c2 = z->c; + { int c3 = z->c; + if (!(eq_s(z, 6, s_0))) { z->c = c3; goto lab2; } lab2: ; } z->c = c2; - z->bra = z->c; /* [, line 104 */ + z->bra = z->c; } - if (!(eq_s(z, 6, s_1))) goto lab1; /* literal, line 104 */ - z->ket = z->c; /* ], line 104 */ - { int ret = slice_from_s(z, 3, s_2); /* <-, line 104 */ + if (!(eq_s(z, 6, s_1))) goto lab1; + z->ket = z->c; + { int ret = slice_from_s(z, 3, s_2); if (ret < 0) return ret; } goto lab0; lab1: z->c = c1; - { int c4 = z->c; /* and, line 105 */ - { int c5 = z->c; /* try, line 105 */ - if (!(eq_s(z, 6, s_3))) { z->c = c5; goto lab4; } /* literal, line 105 */ + { int c4 = z->c; + { int c5 = z->c; + if (!(eq_s(z, 6, s_3))) { z->c = c5; goto lab4; } lab4: ; } z->c = c4; - z->bra = z->c; /* [, line 105 */ + z->bra = z->c; } - if (!(eq_s(z, 6, s_4))) goto lab3; /* literal, line 105 */ - z->ket = z->c; /* ], line 105 */ - { int ret = slice_from_s(z, 3, s_5); /* <-, line 105 */ + if (!(eq_s(z, 6, s_4))) goto lab3; + z->ket = z->c; + { int ret = slice_from_s(z, 3, s_5); if (ret < 0) return ret; } goto lab0; lab3: z->c = c1; - { int c6 = z->c; /* and, line 106 */ - { int c7 = z->c; /* try, line 106 */ - if (!(eq_s(z, 6, s_6))) { z->c = c7; goto lab6; } /* literal, line 106 */ + { int c6 = z->c; + { int c7 = z->c; + if (!(eq_s(z, 6, s_6))) { z->c = c7; goto lab6; } lab6: ; } z->c = c6; - z->bra = z->c; /* [, line 106 */ + z->bra = z->c; } - if (!(eq_s(z, 6, s_7))) goto lab5; /* literal, line 106 */ - z->ket = z->c; /* ], line 106 */ - { int ret = slice_from_s(z, 3, s_8); /* <-, line 106 */ + if (!(eq_s(z, 6, s_7))) goto lab5; + z->ket = z->c; + { int ret = slice_from_s(z, 3, s_8); if (ret < 0) return ret; } goto lab0; lab5: z->c = c1; - { int c8 = z->c; /* and, line 107 */ - { int c9 = z->c; /* try, line 107 */ - if (!(eq_s(z, 6, s_9))) { z->c = c9; goto lab7; } /* literal, line 107 */ + { int c8 = z->c; + { int c9 = z->c; + if (!(eq_s(z, 6, s_9))) { z->c = c9; goto lab7; } lab7: ; } z->c = c8; - z->bra = z->c; /* [, line 107 */ + z->bra = z->c; } - if (!(eq_s(z, 6, s_10))) return 0; /* literal, line 107 */ - z->ket = z->c; /* ], line 107 */ - { int ret = slice_from_s(z, 3, s_11); /* <-, line 107 */ + if (!(eq_s(z, 6, s_10))) return 0; + z->ket = z->c; + { int ret = slice_from_s(z, 3, s_11); if (ret < 0) return ret; } } @@ -731,12 +731,11 @@ static int r_fix_va_start(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_fix_endings(struct SN_env * z) { /* forwardmode */ - { int c1 = z->c; /* do, line 111 */ -/* repeat, line 111 */ - - while(1) { int c2 = z->c; - { int ret = r_fix_ending(z); /* call fix_ending, line 111 */ +static int r_fix_endings(struct SN_env * z) { + { int c1 = z->c; + while(1) { + int c2 = z->c; + { int ret = r_fix_ending(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } @@ -750,17 +749,17 @@ static int r_fix_endings(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_remove_question_prefixes(struct SN_env * z) { /* forwardmode */ - z->bra = z->c; /* [, line 115 */ - if (!(eq_s(z, 3, s_12))) return 0; /* literal, line 115 */ - if (!(find_among(z, a_0, 10))) return 0; /* among, line 115 */ - if (!(eq_s(z, 3, s_13))) return 0; /* literal, line 115 */ - z->ket = z->c; /* ], line 115 */ - { int ret = slice_del(z); /* delete, line 115 */ +static int r_remove_question_prefixes(struct SN_env * z) { + z->bra = z->c; + if (!(eq_s(z, 3, s_12))) return 0; + if (!(find_among(z, a_0, 10))) return 0; + if (!(eq_s(z, 3, s_13))) return 0; + z->ket = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int c1 = z->c; /* do, line 116 */ - { int ret = r_fix_va_start(z); /* call fix_va_start, line 116 */ + { int c1 = z->c; + { int ret = r_fix_va_start(z); if (ret < 0) return ret; } z->c = c1; @@ -768,232 +767,232 @@ static int r_remove_question_prefixes(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_fix_ending(struct SN_env * z) { /* forwardmode */ - if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 121 */ - z->lb = z->c; z->c = z->l; /* backwards, line 122 */ +static int r_fix_ending(struct SN_env * z) { + if (!(len_utf8(z->p) > 3)) return 0; + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* or, line 124 */ - z->ket = z->c; /* [, line 123 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 164)) goto lab1; /* among, line 123 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 164)) goto lab1; if (!(find_among_b(z, a_1, 3))) goto lab1; - z->bra = z->c; /* ], line 123 */ - { int ret = slice_del(z); /* delete, line 123 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 125 */ - if (!(eq_s_b(z, 6, s_14))) goto lab2; /* literal, line 125 */ - { int m_test2 = z->l - z->c; /* test, line 125 */ - if (!(find_among_b(z, a_2, 3))) goto lab2; /* among, line 125 */ + z->ket = z->c; + if (!(eq_s_b(z, 6, s_14))) goto lab2; + { int m_test2 = z->l - z->c; + if (!(find_among_b(z, a_2, 3))) goto lab2; z->c = z->l - m_test2; } - z->bra = z->c; /* ], line 125 */ - { int ret = slice_del(z); /* delete, line 125 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab2: z->c = z->l - m1; - z->ket = z->c; /* [, line 127 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 127 */ - if (!(eq_s_b(z, 12, s_15))) goto lab5; /* literal, line 127 */ + z->ket = z->c; + { int m3 = z->l - z->c; (void)m3; + if (!(eq_s_b(z, 12, s_15))) goto lab5; goto lab4; lab5: z->c = z->l - m3; - if (!(eq_s_b(z, 12, s_16))) goto lab3; /* literal, line 127 */ + if (!(eq_s_b(z, 12, s_16))) goto lab3; } lab4: - z->bra = z->c; /* ], line 127 */ - { int ret = slice_from_s(z, 6, s_17); /* <-, line 127 */ + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_17); if (ret < 0) return ret; } goto lab0; lab3: z->c = z->l - m1; - z->ket = z->c; /* [, line 129 */ - if (!(eq_s_b(z, 12, s_18))) goto lab6; /* literal, line 129 */ - z->bra = z->c; /* ], line 129 */ - { int ret = slice_from_s(z, 6, s_19); /* <-, line 129 */ + z->ket = z->c; + if (!(eq_s_b(z, 12, s_18))) goto lab6; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_19); if (ret < 0) return ret; } goto lab0; lab6: z->c = z->l - m1; - z->ket = z->c; /* [, line 132 */ - if (!(eq_s_b(z, 12, s_20))) goto lab7; /* literal, line 132 */ - z->bra = z->c; /* ], line 132 */ - { int ret = slice_from_s(z, 6, s_21); /* <-, line 132 */ + z->ket = z->c; + if (!(eq_s_b(z, 12, s_20))) goto lab7; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_21); if (ret < 0) return ret; } goto lab0; lab7: z->c = z->l - m1; - z->ket = z->c; /* [, line 134 */ - if (!(eq_s_b(z, 12, s_22))) goto lab8; /* literal, line 134 */ - z->bra = z->c; /* ], line 134 */ - { int ret = slice_from_s(z, 6, s_23); /* <-, line 134 */ + z->ket = z->c; + if (!(eq_s_b(z, 12, s_22))) goto lab8; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_23); if (ret < 0) return ret; } goto lab0; lab8: z->c = z->l - m1; - if (!(z->B[1])) goto lab9; /* Boolean test found_vetrumai_urupu, line 136 */ - z->ket = z->c; /* [, line 136 */ - if (!(eq_s_b(z, 12, s_24))) goto lab9; /* literal, line 136 */ - { int m_test4 = z->l - z->c; /* test, line 136 */ - { int m5 = z->l - z->c; (void)m5; /* not, line 136 */ - if (!(eq_s_b(z, 3, s_25))) goto lab10; /* literal, line 136 */ + if (!(z->I[0])) goto lab9; + z->ket = z->c; + if (!(eq_s_b(z, 12, s_24))) goto lab9; + { int m_test4 = z->l - z->c; + { int m5 = z->l - z->c; (void)m5; + if (!(eq_s_b(z, 3, s_25))) goto lab10; goto lab9; lab10: z->c = z->l - m5; } z->c = z->l - m_test4; } - z->bra = z->c; /* ], line 136 */ - { int ret = slice_from_s(z, 6, s_26); /* <-, line 136 */ + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_26); if (ret < 0) return ret; } - z->bra = z->c; /* ], line 136 */ + z->bra = z->c; goto lab0; lab9: z->c = z->l - m1; - z->ket = z->c; /* [, line 138 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 138 */ - if (!(eq_s_b(z, 9, s_27))) goto lab13; /* literal, line 138 */ + z->ket = z->c; + { int m6 = z->l - z->c; (void)m6; + if (!(eq_s_b(z, 9, s_27))) goto lab13; goto lab12; lab13: z->c = z->l - m6; - if (!(eq_s_b(z, 15, s_28))) goto lab11; /* literal, line 138 */ + if (!(eq_s_b(z, 15, s_28))) goto lab11; } lab12: - z->bra = z->c; /* ], line 138 */ - { int ret = slice_from_s(z, 3, s_29); /* <-, line 138 */ + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_29); if (ret < 0) return ret; } goto lab0; lab11: z->c = z->l - m1; - z->ket = z->c; /* [, line 140 */ - if (!(eq_s_b(z, 3, s_30))) goto lab14; /* literal, line 140 */ - if (!(find_among_b(z, a_3, 6))) goto lab14; /* among, line 140 */ - if (!(eq_s_b(z, 3, s_31))) goto lab14; /* literal, line 140 */ - if (!(find_among_b(z, a_4, 6))) goto lab14; /* among, line 140 */ - z->bra = z->c; /* ], line 140 */ - { int ret = slice_del(z); /* delete, line 140 */ + z->ket = z->c; + if (!(eq_s_b(z, 3, s_30))) goto lab14; + if (!(find_among_b(z, a_3, 6))) goto lab14; + if (!(eq_s_b(z, 3, s_31))) goto lab14; + if (!(find_among_b(z, a_4, 6))) goto lab14; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab14: z->c = z->l - m1; - z->ket = z->c; /* [, line 142 */ - if (!(eq_s_b(z, 9, s_32))) goto lab15; /* literal, line 142 */ - z->bra = z->c; /* ], line 142 */ - { int ret = slice_from_s(z, 3, s_33); /* <-, line 142 */ + z->ket = z->c; + if (!(eq_s_b(z, 9, s_32))) goto lab15; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_33); if (ret < 0) return ret; } goto lab0; lab15: z->c = z->l - m1; - z->ket = z->c; /* [, line 144 */ - if (!(eq_s_b(z, 3, s_34))) goto lab16; /* literal, line 144 */ - if (!(find_among_b(z, a_5, 6))) goto lab16; /* among, line 144 */ - z->bra = z->c; /* ], line 144 */ - { int ret = slice_del(z); /* delete, line 144 */ + z->ket = z->c; + if (!(eq_s_b(z, 3, s_34))) goto lab16; + if (!(find_among_b(z, a_5, 6))) goto lab16; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab16: z->c = z->l - m1; - z->ket = z->c; /* [, line 146 */ - if (!(eq_s_b(z, 3, s_35))) goto lab17; /* literal, line 146 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 146 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((4030464 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab19; /* among, line 146 */ + z->ket = z->c; + if (!(eq_s_b(z, 3, s_35))) goto lab17; + { int m7 = z->l - z->c; (void)m7; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((4030464 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab19; if (!(find_among_b(z, a_6, 6))) goto lab19; goto lab18; lab19: z->c = z->l - m7; - if (!(find_among_b(z, a_7, 6))) goto lab17; /* among, line 146 */ + if (!(find_among_b(z, a_7, 6))) goto lab17; } lab18: - if (!(eq_s_b(z, 3, s_36))) goto lab17; /* literal, line 146 */ - z->bra = z->c; /* ], line 146 */ - { int ret = slice_from_s(z, 3, s_37); /* <-, line 146 */ + if (!(eq_s_b(z, 3, s_36))) goto lab17; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_37); if (ret < 0) return ret; } goto lab0; lab17: z->c = z->l - m1; - z->ket = z->c; /* [, line 148 */ - if (!(find_among_b(z, a_8, 3))) goto lab20; /* among, line 148 */ - z->bra = z->c; /* ], line 148 */ - { int ret = slice_del(z); /* delete, line 148 */ + z->ket = z->c; + if (!(find_among_b(z, a_8, 3))) goto lab20; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab20: z->c = z->l - m1; - z->ket = z->c; /* [, line 150 */ - if (!(eq_s_b(z, 6, s_38))) goto lab21; /* literal, line 150 */ - { int m_test8 = z->l - z->c; /* test, line 150 */ - { int m9 = z->l - z->c; (void)m9; /* not, line 150 */ - if (!(find_among_b(z, a_9, 8))) goto lab22; /* among, line 150 */ + z->ket = z->c; + if (!(eq_s_b(z, 6, s_38))) goto lab21; + { int m_test8 = z->l - z->c; + { int m9 = z->l - z->c; (void)m9; + if (!(find_among_b(z, a_9, 8))) goto lab22; goto lab21; lab22: z->c = z->l - m9; } z->c = z->l - m_test8; } - z->bra = z->c; /* ], line 150 */ - { int ret = slice_del(z); /* delete, line 150 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab21: z->c = z->l - m1; - z->ket = z->c; /* [, line 152 */ - if (!(eq_s_b(z, 6, s_39))) goto lab23; /* literal, line 152 */ - { int m_test10 = z->l - z->c; /* test, line 152 */ - { int m11 = z->l - z->c; (void)m11; /* not, line 152 */ - if (!(eq_s_b(z, 3, s_40))) goto lab24; /* literal, line 152 */ + z->ket = z->c; + if (!(eq_s_b(z, 6, s_39))) goto lab23; + { int m_test10 = z->l - z->c; + { int m11 = z->l - z->c; (void)m11; + if (!(eq_s_b(z, 3, s_40))) goto lab24; goto lab23; lab24: z->c = z->l - m11; } z->c = z->l - m_test10; } - z->bra = z->c; /* ], line 152 */ - { int ret = slice_from_s(z, 6, s_41); /* <-, line 152 */ + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_41); if (ret < 0) return ret; } goto lab0; lab23: z->c = z->l - m1; - z->ket = z->c; /* [, line 154 */ - if (!(eq_s_b(z, 6, s_42))) goto lab25; /* literal, line 154 */ - z->bra = z->c; /* ], line 154 */ - { int ret = slice_del(z); /* delete, line 154 */ + z->ket = z->c; + if (!(eq_s_b(z, 6, s_42))) goto lab25; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab25: z->c = z->l - m1; - z->ket = z->c; /* [, line 156 */ - if (!(eq_s_b(z, 3, s_43))) return 0; /* literal, line 156 */ - { int m_test12 = z->l - z->c; /* test, line 156 */ - { int m13 = z->l - z->c; (void)m13; /* or, line 156 */ - if (!(find_among_b(z, a_10, 8))) goto lab27; /* among, line 156 */ + z->ket = z->c; + if (!(eq_s_b(z, 3, s_43))) return 0; + { int m_test12 = z->l - z->c; + { int m13 = z->l - z->c; (void)m13; + if (!(find_among_b(z, a_10, 8))) goto lab27; goto lab26; lab27: z->c = z->l - m13; - if (!(eq_s_b(z, 3, s_44))) return 0; /* literal, line 156 */ + if (!(eq_s_b(z, 3, s_44))) return 0; } lab26: z->c = z->l - m_test12; } - z->bra = z->c; /* ], line 156 */ - { int ret = slice_del(z); /* delete, line 156 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } } @@ -1002,20 +1001,20 @@ static int r_fix_ending(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_remove_pronoun_prefixes(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset found_a_match, line 161 */ - z->bra = z->c; /* [, line 162 */ - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 4 || !((672 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; /* among, line 162 */ +static int r_remove_pronoun_prefixes(struct SN_env * z) { + z->I[1] = 0; + z->bra = z->c; + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 4 || !((672 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; if (!(find_among(z, a_11, 3))) return 0; - if (!(find_among(z, a_12, 10))) return 0; /* among, line 162 */ - if (!(eq_s(z, 3, s_45))) return 0; /* literal, line 162 */ - z->ket = z->c; /* ], line 162 */ - { int ret = slice_del(z); /* delete, line 162 */ + if (!(find_among(z, a_12, 10))) return 0; + if (!(eq_s(z, 3, s_45))) return 0; + z->ket = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 163 */ - { int c1 = z->c; /* do, line 164 */ - { int ret = r_fix_va_start(z); /* call fix_va_start, line 164 */ + z->I[1] = 1; + { int c1 = z->c; + { int ret = r_fix_va_start(z); if (ret < 0) return ret; } z->c = c1; @@ -1023,122 +1022,122 @@ static int r_remove_pronoun_prefixes(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_remove_plural_suffix(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset found_a_match, line 168 */ - z->lb = z->c; z->c = z->l; /* backwards, line 169 */ +static int r_remove_plural_suffix(struct SN_env * z) { + z->I[1] = 0; + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* or, line 170 */ - z->ket = z->c; /* [, line 170 */ - if (!(eq_s_b(z, 18, s_46))) goto lab1; /* literal, line 170 */ - { int m_test2 = z->l - z->c; /* test, line 170 */ - { int m3 = z->l - z->c; (void)m3; /* not, line 170 */ - if (!(find_among_b(z, a_13, 6))) goto lab2; /* among, line 170 */ + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(eq_s_b(z, 18, s_46))) goto lab1; + { int m_test2 = z->l - z->c; + { int m3 = z->l - z->c; (void)m3; + if (!(find_among_b(z, a_13, 6))) goto lab2; goto lab1; lab2: z->c = z->l - m3; } z->c = z->l - m_test2; } - z->bra = z->c; /* ], line 170 */ - { int ret = slice_from_s(z, 3, s_47); /* <-, line 170 */ + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_47); if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 171 */ - if (!(eq_s_b(z, 15, s_48))) goto lab3; /* literal, line 171 */ - z->bra = z->c; /* ], line 171 */ - { int ret = slice_from_s(z, 6, s_49); /* <-, line 171 */ + z->ket = z->c; + if (!(eq_s_b(z, 15, s_48))) goto lab3; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_49); if (ret < 0) return ret; } goto lab0; lab3: z->c = z->l - m1; - z->ket = z->c; /* [, line 172 */ - if (!(eq_s_b(z, 15, s_50))) goto lab4; /* literal, line 172 */ - z->bra = z->c; /* ], line 172 */ - { int ret = slice_from_s(z, 6, s_51); /* <-, line 172 */ + z->ket = z->c; + if (!(eq_s_b(z, 15, s_50))) goto lab4; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_51); if (ret < 0) return ret; } goto lab0; lab4: z->c = z->l - m1; - z->ket = z->c; /* [, line 173 */ - if (!(eq_s_b(z, 9, s_52))) return 0; /* literal, line 173 */ - z->bra = z->c; /* ], line 173 */ - { int ret = slice_del(z); /* delete, line 173 */ + z->ket = z->c; + if (!(eq_s_b(z, 9, s_52))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } } lab0: - z->B[0] = 1; /* set found_a_match, line 174 */ + z->I[1] = 1; z->c = z->lb; return 1; } -static int r_remove_question_suffixes(struct SN_env * z) { /* forwardmode */ - { int ret = r_has_min_length(z); /* call has_min_length, line 179 */ +static int r_remove_question_suffixes(struct SN_env * z) { + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - z->B[0] = 0; /* unset found_a_match, line 180 */ - z->lb = z->c; z->c = z->l; /* backwards, line 181 */ - - { int m1 = z->l - z->c; (void)m1; /* do, line 182 */ - z->ket = z->c; /* [, line 183 */ - if (!(find_among_b(z, a_14, 3))) goto lab0; /* among, line 183 */ - z->bra = z->c; /* ], line 183 */ - { int ret = slice_from_s(z, 3, s_53); /* <-, line 183 */ + z->I[1] = 0; + z->lb = z->c; z->c = z->l; + + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + if (!(find_among_b(z, a_14, 3))) goto lab0; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_53); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 184 */ + z->I[1] = 1; lab0: z->c = z->l - m1; } z->c = z->lb; - /* do, line 187 */ - { int ret = r_fix_endings(z); /* call fix_endings, line 187 */ + + { int ret = r_fix_endings(z); if (ret < 0) return ret; } return 1; } -static int r_remove_command_suffixes(struct SN_env * z) { /* forwardmode */ - { int ret = r_has_min_length(z); /* call has_min_length, line 191 */ +static int r_remove_command_suffixes(struct SN_env * z) { + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - z->B[0] = 0; /* unset found_a_match, line 192 */ - z->lb = z->c; z->c = z->l; /* backwards, line 193 */ + z->I[1] = 0; + z->lb = z->c; z->c = z->l; - z->ket = z->c; /* [, line 194 */ - if (z->c - 5 <= z->lb || z->p[z->c - 1] != 191) return 0; /* among, line 194 */ + z->ket = z->c; + if (z->c - 5 <= z->lb || z->p[z->c - 1] != 191) return 0; if (!(find_among_b(z, a_15, 2))) return 0; - z->bra = z->c; /* ], line 194 */ - { int ret = slice_del(z); /* delete, line 194 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 195 */ + z->I[1] = 1; z->c = z->lb; return 1; } -static int r_remove_um(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset found_a_match, line 200 */ - { int ret = r_has_min_length(z); /* call has_min_length, line 201 */ +static int r_remove_um(struct SN_env * z) { + z->I[1] = 0; + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 202 */ + z->lb = z->c; z->c = z->l; - z->ket = z->c; /* [, line 202 */ - if (!(eq_s_b(z, 9, s_54))) return 0; /* literal, line 202 */ - z->bra = z->c; /* ], line 202 */ - { int ret = slice_from_s(z, 3, s_55); /* <-, line 202 */ + z->ket = z->c; + if (!(eq_s_b(z, 9, s_54))) return 0; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_55); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 203 */ + z->I[1] = 1; z->c = z->lb; - { int c1 = z->c; /* do, line 205 */ - { int ret = r_fix_ending(z); /* call fix_ending, line 205 */ + { int c1 = z->c; + { int ret = r_fix_ending(z); if (ret < 0) return ret; } z->c = c1; @@ -1146,65 +1145,65 @@ static int r_remove_um(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_remove_common_word_endings(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset found_a_match, line 212 */ - { int ret = r_has_min_length(z); /* call has_min_length, line 213 */ +static int r_remove_common_word_endings(struct SN_env * z) { + z->I[1] = 0; + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 214 */ + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* or, line 231 */ - { int m_test2 = z->l - z->c; /* test, line 215 */ - z->ket = z->c; /* [, line 215 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 215 */ - if (!(eq_s_b(z, 12, s_56))) goto lab3; /* literal, line 215 */ + { int m1 = z->l - z->c; (void)m1; + { int m_test2 = z->l - z->c; + z->ket = z->c; + { int m3 = z->l - z->c; (void)m3; + if (!(eq_s_b(z, 12, s_56))) goto lab3; goto lab2; lab3: z->c = z->l - m3; - if (!(eq_s_b(z, 15, s_57))) goto lab4; /* literal, line 216 */ + if (!(eq_s_b(z, 15, s_57))) goto lab4; goto lab2; lab4: z->c = z->l - m3; - if (!(eq_s_b(z, 12, s_58))) goto lab5; /* literal, line 217 */ + if (!(eq_s_b(z, 12, s_58))) goto lab5; goto lab2; lab5: z->c = z->l - m3; - if (!(eq_s_b(z, 15, s_59))) goto lab6; /* literal, line 218 */ + if (!(eq_s_b(z, 15, s_59))) goto lab6; goto lab2; lab6: z->c = z->l - m3; - if (!(eq_s_b(z, 9, s_60))) goto lab7; /* literal, line 219 */ + if (!(eq_s_b(z, 9, s_60))) goto lab7; goto lab2; lab7: z->c = z->l - m3; - if (!(eq_s_b(z, 12, s_61))) goto lab8; /* literal, line 220 */ + if (!(eq_s_b(z, 12, s_61))) goto lab8; goto lab2; lab8: z->c = z->l - m3; - if (!(eq_s_b(z, 15, s_62))) goto lab9; /* literal, line 221 */ + if (!(eq_s_b(z, 15, s_62))) goto lab9; goto lab2; lab9: z->c = z->l - m3; - if (!(eq_s_b(z, 12, s_63))) goto lab10; /* literal, line 222 */ + if (!(eq_s_b(z, 12, s_63))) goto lab10; goto lab2; lab10: z->c = z->l - m3; - if (!(eq_s_b(z, 12, s_64))) goto lab11; /* literal, line 223 */ + if (!(eq_s_b(z, 12, s_64))) goto lab11; goto lab2; lab11: z->c = z->l - m3; - if (!(eq_s_b(z, 9, s_65))) goto lab12; /* literal, line 224 */ + if (!(eq_s_b(z, 9, s_65))) goto lab12; goto lab2; lab12: z->c = z->l - m3; - if (!(eq_s_b(z, 15, s_66))) goto lab13; /* literal, line 225 */ + if (!(eq_s_b(z, 15, s_66))) goto lab13; goto lab2; lab13: z->c = z->l - m3; - if (!(eq_s_b(z, 9, s_67))) goto lab14; /* literal, line 226 */ - { int m_test4 = z->l - z->c; /* test, line 226 */ - { int m5 = z->l - z->c; (void)m5; /* not, line 226 */ - if (!(find_among_b(z, a_16, 8))) goto lab15; /* among, line 226 */ + if (!(eq_s_b(z, 9, s_67))) goto lab14; + { int m_test4 = z->l - z->c; + { int m5 = z->l - z->c; (void)m5; + if (!(find_among_b(z, a_16, 8))) goto lab15; goto lab14; lab15: z->c = z->l - m5; @@ -1214,57 +1213,57 @@ static int r_remove_common_word_endings(struct SN_env * z) { /* forwardmode */ goto lab2; lab14: z->c = z->l - m3; - if (!(eq_s_b(z, 6, s_68))) goto lab16; /* literal, line 227 */ + if (!(eq_s_b(z, 6, s_68))) goto lab16; goto lab2; lab16: z->c = z->l - m3; - if (!(eq_s_b(z, 9, s_69))) goto lab1; /* literal, line 228 */ + if (!(eq_s_b(z, 9, s_69))) goto lab1; } lab2: - z->bra = z->c; /* ], line 228 */ - { int ret = slice_from_s(z, 3, s_70); /* <-, line 228 */ + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_70); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 229 */ + z->I[1] = 1; z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m_test6 = z->l - z->c; /* test, line 232 */ - z->ket = z->c; /* [, line 232 */ - if (!(find_among_b(z, a_17, 13))) return 0; /* among, line 232 */ - z->bra = z->c; /* ], line 245 */ - { int ret = slice_del(z); /* delete, line 245 */ + { int m_test6 = z->l - z->c; + z->ket = z->c; + if (!(find_among_b(z, a_17, 13))) return 0; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 246 */ + z->I[1] = 1; z->c = z->l - m_test6; } } lab0: z->c = z->lb; - /* do, line 249 */ - { int ret = r_fix_endings(z); /* call fix_endings, line 249 */ + + { int ret = r_fix_endings(z); if (ret < 0) return ret; } return 1; } -static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset found_a_match, line 253 */ - z->B[1] = 0; /* unset found_vetrumai_urupu, line 254 */ - { int ret = r_has_min_length(z); /* call has_min_length, line 255 */ +static int r_remove_vetrumai_urupukal(struct SN_env * z) { + z->I[1] = 0; + z->I[0] = 0; + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 256 */ - - { int m1 = z->l - z->c; (void)m1; /* or, line 259 */ - { int m_test2 = z->l - z->c; /* test, line 258 */ - z->ket = z->c; /* [, line 258 */ - if (!(eq_s_b(z, 6, s_71))) goto lab1; /* literal, line 258 */ - z->bra = z->c; /* ], line 258 */ - { int ret = slice_del(z); /* delete, line 258 */ + z->lb = z->c; z->c = z->l; + + { int m1 = z->l - z->c; (void)m1; + { int m_test2 = z->l - z->c; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_71))) goto lab1; + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } z->c = z->l - m_test2; @@ -1272,20 +1271,20 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ goto lab0; lab1: z->c = z->l - m1; - { int m_test3 = z->l - z->c; /* test, line 260 */ - z->ket = z->c; /* [, line 260 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 261 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 260 */ - if (!(eq_s_b(z, 9, s_72))) goto lab6; /* literal, line 260 */ + { int m_test3 = z->l - z->c; + z->ket = z->c; + { int m4 = z->l - z->c; (void)m4; + { int m5 = z->l - z->c; (void)m5; + if (!(eq_s_b(z, 9, s_72))) goto lab6; goto lab5; lab6: z->c = z->l - m5; - if (!(eq_s_b(z, 3, s_73))) goto lab4; /* literal, line 261 */ + if (!(eq_s_b(z, 3, s_73))) goto lab4; } lab5: - { int m_test6 = z->l - z->c; /* test, line 261 */ - { int m7 = z->l - z->c; (void)m7; /* not, line 261 */ - if (!(find_among_b(z, a_18, 6))) goto lab7; /* among, line 261 */ + { int m_test6 = z->l - z->c; + { int m7 = z->l - z->c; (void)m7; + if (!(find_among_b(z, a_18, 6))) goto lab7; goto lab4; lab7: z->c = z->l - m7; @@ -1295,16 +1294,16 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ goto lab3; lab4: z->c = z->l - m4; - if (!(eq_s_b(z, 3, s_74))) goto lab2; /* literal, line 262 */ - { int m_test8 = z->l - z->c; /* test, line 262 */ - if (!(find_among_b(z, a_19, 6))) goto lab2; /* among, line 262 */ - if (!(eq_s_b(z, 3, s_75))) goto lab2; /* literal, line 262 */ + if (!(eq_s_b(z, 3, s_74))) goto lab2; + { int m_test8 = z->l - z->c; + if (!(find_among_b(z, a_19, 6))) goto lab2; + if (!(eq_s_b(z, 3, s_75))) goto lab2; z->c = z->l - m_test8; } } lab3: - z->bra = z->c; /* ], line 263 */ - { int ret = slice_from_s(z, 3, s_76); /* <-, line 263 */ + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_76); if (ret < 0) return ret; } z->c = z->l - m_test3; @@ -1312,29 +1311,29 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ goto lab0; lab2: z->c = z->l - m1; - { int m_test9 = z->l - z->c; /* test, line 266 */ - z->ket = z->c; /* [, line 266 */ - { int m10 = z->l - z->c; (void)m10; /* or, line 267 */ - if (!(eq_s_b(z, 9, s_77))) goto lab10; /* literal, line 267 */ + { int m_test9 = z->l - z->c; + z->ket = z->c; + { int m10 = z->l - z->c; (void)m10; + if (!(eq_s_b(z, 9, s_77))) goto lab10; goto lab9; lab10: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_78))) goto lab11; /* literal, line 268 */ + if (!(eq_s_b(z, 9, s_78))) goto lab11; goto lab9; lab11: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_79))) goto lab12; /* literal, line 269 */ + if (!(eq_s_b(z, 9, s_79))) goto lab12; goto lab9; lab12: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_80))) goto lab13; /* literal, line 270 */ + if (!(eq_s_b(z, 9, s_80))) goto lab13; goto lab9; lab13: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_81))) goto lab14; /* literal, line 271 */ - { int m_test11 = z->l - z->c; /* test, line 271 */ - { int m12 = z->l - z->c; (void)m12; /* not, line 271 */ - if (!(eq_s_b(z, 3, s_82))) goto lab15; /* literal, line 271 */ + if (!(eq_s_b(z, 9, s_81))) goto lab14; + { int m_test11 = z->l - z->c; + { int m12 = z->l - z->c; (void)m12; + if (!(eq_s_b(z, 3, s_82))) goto lab15; goto lab14; lab15: z->c = z->l - m12; @@ -1344,39 +1343,39 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ goto lab9; lab14: z->c = z->l - m10; - if (!(eq_s_b(z, 15, s_83))) goto lab16; /* literal, line 272 */ + if (!(eq_s_b(z, 15, s_83))) goto lab16; goto lab9; lab16: z->c = z->l - m10; - if (!(eq_s_b(z, 21, s_84))) goto lab17; /* literal, line 273 */ + if (!(eq_s_b(z, 21, s_84))) goto lab17; goto lab9; lab17: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_85))) goto lab18; /* literal, line 274 */ + if (!(eq_s_b(z, 9, s_85))) goto lab18; goto lab9; lab18: z->c = z->l - m10; - if (!(len_utf8(z->p) >= 7)) goto lab19; /* $( >= ), line 275 */ - if (!(eq_s_b(z, 12, s_86))) goto lab19; /* literal, line 275 */ + if (!(len_utf8(z->p) >= 7)) goto lab19; + if (!(eq_s_b(z, 12, s_86))) goto lab19; goto lab9; lab19: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_87))) goto lab20; /* literal, line 276 */ + if (!(eq_s_b(z, 9, s_87))) goto lab20; goto lab9; lab20: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_88))) goto lab21; /* literal, line 277 */ + if (!(eq_s_b(z, 9, s_88))) goto lab21; goto lab9; lab21: z->c = z->l - m10; - if (!(eq_s_b(z, 12, s_89))) goto lab22; /* literal, line 278 */ + if (!(eq_s_b(z, 12, s_89))) goto lab22; goto lab9; lab22: z->c = z->l - m10; - if (!(eq_s_b(z, 6, s_90))) goto lab23; /* literal, line 279 */ - { int m_test13 = z->l - z->c; /* test, line 279 */ - { int m14 = z->l - z->c; (void)m14; /* not, line 279 */ - if (!(find_among_b(z, a_20, 8))) goto lab24; /* among, line 279 */ + if (!(eq_s_b(z, 6, s_90))) goto lab23; + { int m_test13 = z->l - z->c; + { int m14 = z->l - z->c; (void)m14; + if (!(find_among_b(z, a_20, 8))) goto lab24; goto lab23; lab24: z->c = z->l - m14; @@ -1386,11 +1385,11 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ goto lab9; lab23: z->c = z->l - m10; - if (!(eq_s_b(z, 9, s_91))) goto lab8; /* literal, line 280 */ + if (!(eq_s_b(z, 9, s_91))) goto lab8; } lab9: - z->bra = z->c; /* ], line 281 */ - { int ret = slice_from_s(z, 3, s_92); /* <-, line 281 */ + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_92); if (ret < 0) return ret; } z->c = z->l - m_test9; @@ -1398,37 +1397,37 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ goto lab0; lab8: z->c = z->l - m1; - { int m_test15 = z->l - z->c; /* test, line 284 */ - z->ket = z->c; /* [, line 284 */ - { int m16 = z->l - z->c; (void)m16; /* or, line 285 */ - if (!(eq_s_b(z, 9, s_93))) goto lab27; /* literal, line 285 */ + { int m_test15 = z->l - z->c; + z->ket = z->c; + { int m16 = z->l - z->c; (void)m16; + if (!(eq_s_b(z, 9, s_93))) goto lab27; goto lab26; lab27: z->c = z->l - m16; - if (!(eq_s_b(z, 12, s_94))) goto lab28; /* literal, line 286 */ + if (!(eq_s_b(z, 12, s_94))) goto lab28; goto lab26; lab28: z->c = z->l - m16; - if (!(eq_s_b(z, 12, s_95))) goto lab29; /* literal, line 287 */ + if (!(eq_s_b(z, 12, s_95))) goto lab29; goto lab26; lab29: z->c = z->l - m16; - if (!(eq_s_b(z, 12, s_96))) goto lab30; /* literal, line 288 */ + if (!(eq_s_b(z, 12, s_96))) goto lab30; goto lab26; lab30: z->c = z->l - m16; - if (!(eq_s_b(z, 12, s_97))) goto lab31; /* literal, line 289 */ + if (!(eq_s_b(z, 12, s_97))) goto lab31; goto lab26; lab31: z->c = z->l - m16; - if (!(eq_s_b(z, 12, s_98))) goto lab32; /* literal, line 290 */ + if (!(eq_s_b(z, 12, s_98))) goto lab32; goto lab26; lab32: z->c = z->l - m16; - if (!(eq_s_b(z, 6, s_99))) goto lab25; /* literal, line 291 */ - { int m_test17 = z->l - z->c; /* test, line 291 */ - { int m18 = z->l - z->c; (void)m18; /* not, line 291 */ - if (!(find_among_b(z, a_21, 8))) goto lab33; /* among, line 291 */ + if (!(eq_s_b(z, 6, s_99))) goto lab25; + { int m_test17 = z->l - z->c; + { int m18 = z->l - z->c; (void)m18; + if (!(find_among_b(z, a_21, 8))) goto lab33; goto lab25; lab33: z->c = z->l - m18; @@ -1437,8 +1436,8 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ } } lab26: - z->bra = z->c; /* ], line 292 */ - { int ret = slice_del(z); /* delete, line 292 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } z->c = z->l - m_test15; @@ -1446,45 +1445,44 @@ static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ goto lab0; lab25: z->c = z->l - m1; - { int m_test19 = z->l - z->c; /* test, line 295 */ - z->ket = z->c; /* [, line 295 */ - if (!(eq_s_b(z, 3, s_100))) return 0; /* literal, line 295 */ - z->bra = z->c; /* ], line 295 */ - { int ret = slice_from_s(z, 3, s_101); /* <-, line 295 */ + { int m_test19 = z->l - z->c; + z->ket = z->c; + if (!(eq_s_b(z, 3, s_100))) return 0; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_101); if (ret < 0) return ret; } z->c = z->l - m_test19; } } lab0: - z->B[0] = 1; /* set found_a_match, line 297 */ - z->B[1] = 1; /* set found_vetrumai_urupu, line 298 */ - { int m20 = z->l - z->c; (void)m20; /* do, line 299 */ - z->ket = z->c; /* [, line 299 */ - if (!(eq_s_b(z, 9, s_102))) goto lab34; /* literal, line 299 */ - z->bra = z->c; /* ], line 299 */ - { int ret = slice_from_s(z, 3, s_103); /* <-, line 299 */ + z->I[1] = 1; + z->I[0] = 1; + { int m20 = z->l - z->c; (void)m20; + z->ket = z->c; + if (!(eq_s_b(z, 9, s_102))) goto lab34; + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_103); if (ret < 0) return ret; } lab34: z->c = z->l - m20; } z->c = z->lb; - /* do, line 301 */ - { int ret = r_fix_endings(z); /* call fix_endings, line 301 */ + + { int ret = r_fix_endings(z); if (ret < 0) return ret; } return 1; } -static int r_remove_tense_suffixes(struct SN_env * z) { /* forwardmode */ - z->B[0] = 1; /* set found_a_match, line 305 */ -/* repeat, line 306 */ - - while(1) { int c1 = z->c; - if (!(z->B[0])) goto lab0; /* Boolean test found_a_match, line 306 */ - { int c2 = z->c; /* do, line 306 */ - { int ret = r_remove_tense_suffix(z); /* call remove_tense_suffix, line 306 */ +static int r_remove_tense_suffixes(struct SN_env * z) { + z->I[1] = 1; + while(1) { + int c1 = z->c; + if (!(z->I[1])) goto lab0; + { int c2 = z->c; + { int ret = r_remove_tense_suffix(z); if (ret < 0) return ret; } z->c = c2; @@ -1497,60 +1495,60 @@ static int r_remove_tense_suffixes(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_remove_tense_suffix(struct SN_env * z) { /* forwardmode */ - z->B[0] = 0; /* unset found_a_match, line 310 */ - { int ret = r_has_min_length(z); /* call has_min_length, line 311 */ +static int r_remove_tense_suffix(struct SN_env * z) { + z->I[1] = 0; + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 312 */ + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 313 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 320 */ - { int m_test3 = z->l - z->c; /* test, line 314 */ - z->ket = z->c; /* [, line 314 */ - if (z->c - 8 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 141)) goto lab2; /* among, line 314 */ + { int m1 = z->l - z->c; (void)m1; + { int m2 = z->l - z->c; (void)m2; + { int m_test3 = z->l - z->c; + z->ket = z->c; + if (z->c - 8 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 141)) goto lab2; if (!(find_among_b(z, a_22, 2))) goto lab2; - z->bra = z->c; /* ], line 317 */ - { int ret = slice_del(z); /* delete, line 317 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 318 */ + z->I[1] = 1; z->c = z->l - m_test3; } goto lab1; lab2: z->c = z->l - m2; - { int m_test4 = z->l - z->c; /* test, line 321 */ - z->ket = z->c; /* [, line 321 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 322 */ - if (!(eq_s_b(z, 12, s_104))) goto lab5; /* literal, line 322 */ + { int m_test4 = z->l - z->c; + z->ket = z->c; + { int m5 = z->l - z->c; (void)m5; + if (!(eq_s_b(z, 12, s_104))) goto lab5; goto lab4; lab5: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_105))) goto lab6; /* literal, line 323 */ + if (!(eq_s_b(z, 12, s_105))) goto lab6; goto lab4; lab6: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_106))) goto lab7; /* literal, line 324 */ + if (!(eq_s_b(z, 9, s_106))) goto lab7; goto lab4; lab7: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_107))) goto lab8; /* literal, line 325 */ + if (!(eq_s_b(z, 12, s_107))) goto lab8; goto lab4; lab8: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_108))) goto lab9; /* literal, line 326 */ + if (!(eq_s_b(z, 12, s_108))) goto lab9; goto lab4; lab9: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_109))) goto lab10; /* literal, line 327 */ + if (!(eq_s_b(z, 12, s_109))) goto lab10; goto lab4; lab10: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_110))) goto lab11; /* literal, line 328 */ - { int m_test6 = z->l - z->c; /* test, line 328 */ - { int m7 = z->l - z->c; (void)m7; /* not, line 328 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((1951712 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab12; /* among, line 328 */ + if (!(eq_s_b(z, 9, s_110))) goto lab11; + { int m_test6 = z->l - z->c; + { int m7 = z->l - z->c; (void)m7; + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((1951712 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab12; if (!(find_among_b(z, a_23, 12))) goto lab12; goto lab11; lab12: @@ -1561,58 +1559,58 @@ static int r_remove_tense_suffix(struct SN_env * z) { /* forwardmode */ goto lab4; lab11: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_111))) goto lab13; /* literal, line 329 */ + if (!(eq_s_b(z, 9, s_111))) goto lab13; goto lab4; lab13: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_112))) goto lab14; /* literal, line 330 */ + if (!(eq_s_b(z, 9, s_112))) goto lab14; goto lab4; lab14: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_113))) goto lab15; /* literal, line 331 */ + if (!(eq_s_b(z, 9, s_113))) goto lab15; goto lab4; lab15: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_114))) goto lab16; /* literal, line 332 */ + if (!(eq_s_b(z, 9, s_114))) goto lab16; goto lab4; lab16: z->c = z->l - m5; - if (!(eq_s_b(z, 3, s_115))) goto lab17; /* literal, line 333 */ + if (!(eq_s_b(z, 3, s_115))) goto lab17; goto lab4; lab17: z->c = z->l - m5; - if (!(eq_s_b(z, 3, s_116))) goto lab18; /* literal, line 333 */ + if (!(eq_s_b(z, 3, s_116))) goto lab18; goto lab4; lab18: z->c = z->l - m5; - if (!(eq_s_b(z, 3, s_117))) goto lab19; /* literal, line 333 */ + if (!(eq_s_b(z, 3, s_117))) goto lab19; goto lab4; lab19: z->c = z->l - m5; - if (!(eq_s_b(z, 3, s_118))) goto lab20; /* literal, line 333 */ + if (!(eq_s_b(z, 3, s_118))) goto lab20; goto lab4; lab20: z->c = z->l - m5; - if (!(eq_s_b(z, 3, s_119))) goto lab21; /* literal, line 333 */ + if (!(eq_s_b(z, 3, s_119))) goto lab21; goto lab4; lab21: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_120))) goto lab22; /* literal, line 334 */ + if (!(eq_s_b(z, 9, s_120))) goto lab22; goto lab4; lab22: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_121))) goto lab23; /* literal, line 335 */ + if (!(eq_s_b(z, 9, s_121))) goto lab23; goto lab4; lab23: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_122))) goto lab24; /* literal, line 336 */ + if (!(eq_s_b(z, 9, s_122))) goto lab24; goto lab4; lab24: z->c = z->l - m5; - if (!(eq_s_b(z, 6, s_123))) goto lab25; /* literal, line 337 */ - { int m_test8 = z->l - z->c; /* test, line 337 */ - { int m9 = z->l - z->c; (void)m9; /* not, line 337 */ - if (!(find_among_b(z, a_24, 8))) goto lab26; /* among, line 337 */ + if (!(eq_s_b(z, 6, s_123))) goto lab25; + { int m_test8 = z->l - z->c; + { int m9 = z->l - z->c; (void)m9; + if (!(find_among_b(z, a_24, 8))) goto lab26; goto lab25; lab26: z->c = z->l - m9; @@ -1622,58 +1620,58 @@ static int r_remove_tense_suffix(struct SN_env * z) { /* forwardmode */ goto lab4; lab25: z->c = z->l - m5; - if (!(eq_s_b(z, 15, s_124))) goto lab27; /* literal, line 338 */ + if (!(eq_s_b(z, 15, s_124))) goto lab27; goto lab4; lab27: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_125))) goto lab28; /* literal, line 339 */ + if (!(eq_s_b(z, 9, s_125))) goto lab28; goto lab4; lab28: z->c = z->l - m5; - if (!(eq_s_b(z, 9, s_126))) goto lab29; /* literal, line 340 */ + if (!(eq_s_b(z, 9, s_126))) goto lab29; goto lab4; lab29: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_127))) goto lab30; /* literal, line 341 */ + if (!(eq_s_b(z, 12, s_127))) goto lab30; goto lab4; lab30: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_128))) goto lab31; /* literal, line 342 */ + if (!(eq_s_b(z, 12, s_128))) goto lab31; goto lab4; lab31: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_129))) goto lab32; /* literal, line 343 */ + if (!(eq_s_b(z, 12, s_129))) goto lab32; goto lab4; lab32: z->c = z->l - m5; - if (!(eq_s_b(z, 12, s_130))) goto lab33; /* literal, line 344 */ + if (!(eq_s_b(z, 12, s_130))) goto lab33; goto lab4; lab33: z->c = z->l - m5; - if (!(eq_s_b(z, 6, s_131))) goto lab34; /* literal, line 345 */ + if (!(eq_s_b(z, 6, s_131))) goto lab34; goto lab4; lab34: z->c = z->l - m5; - if (!(eq_s_b(z, 6, s_132))) goto lab3; /* literal, line 346 */ + if (!(eq_s_b(z, 6, s_132))) goto lab3; } lab4: - z->bra = z->c; /* ], line 347 */ - { int ret = slice_del(z); /* delete, line 347 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 348 */ + z->I[1] = 1; z->c = z->l - m_test4; } goto lab1; lab3: z->c = z->l - m2; - { int m_test10 = z->l - z->c; /* test, line 351 */ - z->ket = z->c; /* [, line 351 */ - { int m11 = z->l - z->c; (void)m11; /* or, line 352 */ - if (!(eq_s_b(z, 9, s_133))) goto lab37; /* literal, line 352 */ - { int m_test12 = z->l - z->c; /* test, line 352 */ - { int m13 = z->l - z->c; (void)m13; /* not, line 352 */ - if (!(eq_s_b(z, 3, s_134))) goto lab38; /* literal, line 352 */ + { int m_test10 = z->l - z->c; + z->ket = z->c; + { int m11 = z->l - z->c; (void)m11; + if (!(eq_s_b(z, 9, s_133))) goto lab37; + { int m_test12 = z->l - z->c; + { int m13 = z->l - z->c; (void)m13; + if (!(eq_s_b(z, 3, s_134))) goto lab38; goto lab37; lab38: z->c = z->l - m13; @@ -1683,102 +1681,102 @@ static int r_remove_tense_suffix(struct SN_env * z) { /* forwardmode */ goto lab36; lab37: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_135))) goto lab39; /* literal, line 353 */ + if (!(eq_s_b(z, 9, s_135))) goto lab39; goto lab36; lab39: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_136))) goto lab40; /* literal, line 354 */ + if (!(eq_s_b(z, 9, s_136))) goto lab40; goto lab36; lab40: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_137))) goto lab41; /* literal, line 355 */ + if (!(eq_s_b(z, 9, s_137))) goto lab41; goto lab36; lab41: z->c = z->l - m11; - if (!(eq_s_b(z, 3, s_138))) goto lab42; /* literal, line 356 */ + if (!(eq_s_b(z, 3, s_138))) goto lab42; goto lab36; lab42: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_139))) goto lab43; /* literal, line 357 */ + if (!(eq_s_b(z, 9, s_139))) goto lab43; goto lab36; lab43: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_140))) goto lab44; /* literal, line 358 */ + if (!(eq_s_b(z, 9, s_140))) goto lab44; goto lab36; lab44: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_141))) goto lab45; /* literal, line 359 */ + if (!(eq_s_b(z, 9, s_141))) goto lab45; goto lab36; lab45: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_142))) goto lab46; /* literal, line 360 */ + if (!(eq_s_b(z, 9, s_142))) goto lab46; goto lab36; lab46: z->c = z->l - m11; - if (!(eq_s_b(z, 12, s_143))) goto lab47; /* literal, line 361 */ + if (!(eq_s_b(z, 12, s_143))) goto lab47; goto lab36; lab47: z->c = z->l - m11; - if (!(eq_s_b(z, 12, s_144))) goto lab48; /* literal, line 362 */ + if (!(eq_s_b(z, 12, s_144))) goto lab48; goto lab36; lab48: z->c = z->l - m11; - if (!(eq_s_b(z, 12, s_145))) goto lab49; /* literal, line 363 */ + if (!(eq_s_b(z, 12, s_145))) goto lab49; goto lab36; lab49: z->c = z->l - m11; - if (!(eq_s_b(z, 12, s_146))) goto lab50; /* literal, line 364 */ + if (!(eq_s_b(z, 12, s_146))) goto lab50; goto lab36; lab50: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_147))) goto lab51; /* literal, line 365 */ + if (!(eq_s_b(z, 9, s_147))) goto lab51; goto lab36; lab51: z->c = z->l - m11; - if (!(eq_s_b(z, 12, s_148))) goto lab52; /* literal, line 366 */ + if (!(eq_s_b(z, 12, s_148))) goto lab52; goto lab36; lab52: z->c = z->l - m11; - if (!(eq_s_b(z, 12, s_149))) goto lab53; /* literal, line 367 */ + if (!(eq_s_b(z, 12, s_149))) goto lab53; goto lab36; lab53: z->c = z->l - m11; - if (!(eq_s_b(z, 9, s_150))) goto lab54; /* literal, line 368 */ + if (!(eq_s_b(z, 9, s_150))) goto lab54; goto lab36; lab54: z->c = z->l - m11; - if (!(eq_s_b(z, 12, s_151))) goto lab35; /* literal, line 369 */ + if (!(eq_s_b(z, 12, s_151))) goto lab35; } lab36: - z->bra = z->c; /* ], line 370 */ - { int ret = slice_from_s(z, 3, s_152); /* <-, line 370 */ + z->bra = z->c; + { int ret = slice_from_s(z, 3, s_152); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 371 */ + z->I[1] = 1; z->c = z->l - m_test10; } goto lab1; lab35: z->c = z->l - m2; - { int m_test14 = z->l - z->c; /* test, line 374 */ - z->ket = z->c; /* [, line 374 */ - { int m15 = z->l - z->c; (void)m15; /* or, line 374 */ - if (!(eq_s_b(z, 6, s_153))) goto lab56; /* literal, line 374 */ + { int m_test14 = z->l - z->c; + z->ket = z->c; + { int m15 = z->l - z->c; (void)m15; + if (!(eq_s_b(z, 6, s_153))) goto lab56; goto lab55; lab56: z->c = z->l - m15; - if (!(eq_s_b(z, 6, s_154))) goto lab0; /* literal, line 374 */ + if (!(eq_s_b(z, 6, s_154))) goto lab0; } lab55: - { int m_test16 = z->l - z->c; /* test, line 374 */ - if (!(eq_s_b(z, 3, s_155))) goto lab0; /* literal, line 374 */ + { int m_test16 = z->l - z->c; + if (!(eq_s_b(z, 3, s_155))) goto lab0; z->c = z->l - m_test16; } - z->bra = z->c; /* ], line 374 */ - { int ret = slice_del(z); /* delete, line 374 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 375 */ + z->I[1] = 1; z->c = z->l - m_test14; } } @@ -1786,87 +1784,87 @@ static int r_remove_tense_suffix(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m1; } - { int m17 = z->l - z->c; (void)m17; /* do, line 378 */ - z->ket = z->c; /* [, line 378 */ - if (z->c - 8 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 177)) goto lab57; /* among, line 378 */ + { int m17 = z->l - z->c; (void)m17; + z->ket = z->c; + if (z->c - 8 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 177)) goto lab57; if (!(find_among_b(z, a_25, 6))) goto lab57; - z->bra = z->c; /* ], line 385 */ - { int ret = slice_del(z); /* delete, line 385 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->B[0] = 1; /* set found_a_match, line 386 */ + z->I[1] = 1; lab57: z->c = z->l - m17; } z->c = z->lb; - /* do, line 389 */ - { int ret = r_fix_endings(z); /* call fix_endings, line 389 */ + + { int ret = r_fix_endings(z); if (ret < 0) return ret; } return 1; } -extern int tamil_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - z->B[1] = 0; /* unset found_vetrumai_urupu, line 393 */ - { int c1 = z->c; /* do, line 394 */ - { int ret = r_fix_ending(z); /* call fix_ending, line 394 */ +extern int tamil_UTF_8_stem(struct SN_env * z) { + z->I[0] = 0; + { int c1 = z->c; + { int ret = r_fix_ending(z); if (ret < 0) return ret; } z->c = c1; } - { int ret = r_has_min_length(z); /* call has_min_length, line 395 */ + { int ret = r_has_min_length(z); if (ret <= 0) return ret; } - { int c2 = z->c; /* do, line 396 */ - { int ret = r_remove_question_prefixes(z); /* call remove_question_prefixes, line 396 */ + { int c2 = z->c; + { int ret = r_remove_question_prefixes(z); if (ret < 0) return ret; } z->c = c2; } - { int c3 = z->c; /* do, line 397 */ - { int ret = r_remove_pronoun_prefixes(z); /* call remove_pronoun_prefixes, line 397 */ + { int c3 = z->c; + { int ret = r_remove_pronoun_prefixes(z); if (ret < 0) return ret; } z->c = c3; } - { int c4 = z->c; /* do, line 398 */ - { int ret = r_remove_question_suffixes(z); /* call remove_question_suffixes, line 398 */ + { int c4 = z->c; + { int ret = r_remove_question_suffixes(z); if (ret < 0) return ret; } z->c = c4; } - { int c5 = z->c; /* do, line 399 */ - { int ret = r_remove_um(z); /* call remove_um, line 399 */ + { int c5 = z->c; + { int ret = r_remove_um(z); if (ret < 0) return ret; } z->c = c5; } - { int c6 = z->c; /* do, line 400 */ - { int ret = r_remove_common_word_endings(z); /* call remove_common_word_endings, line 400 */ + { int c6 = z->c; + { int ret = r_remove_common_word_endings(z); if (ret < 0) return ret; } z->c = c6; } - { int c7 = z->c; /* do, line 401 */ - { int ret = r_remove_vetrumai_urupukal(z); /* call remove_vetrumai_urupukal, line 401 */ + { int c7 = z->c; + { int ret = r_remove_vetrumai_urupukal(z); if (ret < 0) return ret; } z->c = c7; } - { int c8 = z->c; /* do, line 402 */ - { int ret = r_remove_plural_suffix(z); /* call remove_plural_suffix, line 402 */ + { int c8 = z->c; + { int ret = r_remove_plural_suffix(z); if (ret < 0) return ret; } z->c = c8; } - { int c9 = z->c; /* do, line 403 */ - { int ret = r_remove_command_suffixes(z); /* call remove_command_suffixes, line 403 */ + { int c9 = z->c; + { int ret = r_remove_command_suffixes(z); if (ret < 0) return ret; } z->c = c9; } - { int c10 = z->c; /* do, line 404 */ - { int ret = r_remove_tense_suffixes(z); /* call remove_tense_suffixes, line 404 */ + { int c10 = z->c; + { int ret = r_remove_tense_suffixes(z); if (ret < 0) return ret; } z->c = c10; @@ -1874,7 +1872,7 @@ extern int tamil_UTF_8_stem(struct SN_env * z) { /* forwardmode */ return 1; } -extern struct SN_env * tamil_UTF_8_create_env(void) { return SN_create_env(0, 0, 2); } +extern struct SN_env * tamil_UTF_8_create_env(void) { return SN_create_env(0, 2); } extern void tamil_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c b/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c index 5c4b11c0ffb4..41edce668c5c 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c @@ -1,4 +1,4 @@ -/* Generated by Snowball 2.0.0 - https://snowballstem.org/ */ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ #include "header.h" @@ -74,16 +74,16 @@ static const symbol s_0_9[4] = { 'n', 0xC3, 0xBC, 'z' }; static const struct among a_0[10] = { -/* 0 */ { 1, s_0_0, -1, -1, 0}, -/* 1 */ { 1, s_0_1, -1, -1, 0}, -/* 2 */ { 3, s_0_2, -1, -1, 0}, -/* 3 */ { 3, s_0_3, -1, -1, 0}, -/* 4 */ { 3, s_0_4, -1, -1, 0}, -/* 5 */ { 3, s_0_5, -1, -1, 0}, -/* 6 */ { 4, s_0_6, -1, -1, 0}, -/* 7 */ { 4, s_0_7, -1, -1, 0}, -/* 8 */ { 4, s_0_8, -1, -1, 0}, -/* 9 */ { 4, s_0_9, -1, -1, 0} +{ 1, s_0_0, -1, -1, 0}, +{ 1, s_0_1, -1, -1, 0}, +{ 3, s_0_2, -1, -1, 0}, +{ 3, s_0_3, -1, -1, 0}, +{ 3, s_0_4, -1, -1, 0}, +{ 3, s_0_5, -1, -1, 0}, +{ 4, s_0_6, -1, -1, 0}, +{ 4, s_0_7, -1, -1, 0}, +{ 4, s_0_8, -1, -1, 0}, +{ 4, s_0_9, -1, -1, 0} }; static const symbol s_1_0[4] = { 'l', 'e', 'r', 'i' }; @@ -91,8 +91,8 @@ static const symbol s_1_1[5] = { 'l', 'a', 'r', 0xC4, 0xB1 }; static const struct among a_1[2] = { -/* 0 */ { 4, s_1_0, -1, -1, 0}, -/* 1 */ { 5, s_1_1, -1, -1, 0} +{ 4, s_1_0, -1, -1, 0}, +{ 5, s_1_1, -1, -1, 0} }; static const symbol s_2_0[2] = { 'n', 'i' }; @@ -102,10 +102,10 @@ static const symbol s_2_3[3] = { 'n', 0xC3, 0xBC }; static const struct among a_2[4] = { -/* 0 */ { 2, s_2_0, -1, -1, 0}, -/* 1 */ { 2, s_2_1, -1, -1, 0}, -/* 2 */ { 3, s_2_2, -1, -1, 0}, -/* 3 */ { 3, s_2_3, -1, -1, 0} +{ 2, s_2_0, -1, -1, 0}, +{ 2, s_2_1, -1, -1, 0}, +{ 3, s_2_2, -1, -1, 0}, +{ 3, s_2_3, -1, -1, 0} }; static const symbol s_3_0[2] = { 'i', 'n' }; @@ -115,10 +115,10 @@ static const symbol s_3_3[3] = { 0xC3, 0xBC, 'n' }; static const struct among a_3[4] = { -/* 0 */ { 2, s_3_0, -1, -1, 0}, -/* 1 */ { 2, s_3_1, -1, -1, 0}, -/* 2 */ { 3, s_3_2, -1, -1, 0}, -/* 3 */ { 3, s_3_3, -1, -1, 0} +{ 2, s_3_0, -1, -1, 0}, +{ 2, s_3_1, -1, -1, 0}, +{ 3, s_3_2, -1, -1, 0}, +{ 3, s_3_3, -1, -1, 0} }; static const symbol s_4_0[1] = { 'a' }; @@ -126,8 +126,8 @@ static const symbol s_4_1[1] = { 'e' }; static const struct among a_4[2] = { -/* 0 */ { 1, s_4_0, -1, -1, 0}, -/* 1 */ { 1, s_4_1, -1, -1, 0} +{ 1, s_4_0, -1, -1, 0}, +{ 1, s_4_1, -1, -1, 0} }; static const symbol s_5_0[2] = { 'n', 'a' }; @@ -135,8 +135,8 @@ static const symbol s_5_1[2] = { 'n', 'e' }; static const struct among a_5[2] = { -/* 0 */ { 2, s_5_0, -1, -1, 0}, -/* 1 */ { 2, s_5_1, -1, -1, 0} +{ 2, s_5_0, -1, -1, 0}, +{ 2, s_5_1, -1, -1, 0} }; static const symbol s_6_0[2] = { 'd', 'a' }; @@ -146,10 +146,10 @@ static const symbol s_6_3[2] = { 't', 'e' }; static const struct among a_6[4] = { -/* 0 */ { 2, s_6_0, -1, -1, 0}, -/* 1 */ { 2, s_6_1, -1, -1, 0}, -/* 2 */ { 2, s_6_2, -1, -1, 0}, -/* 3 */ { 2, s_6_3, -1, -1, 0} +{ 2, s_6_0, -1, -1, 0}, +{ 2, s_6_1, -1, -1, 0}, +{ 2, s_6_2, -1, -1, 0}, +{ 2, s_6_3, -1, -1, 0} }; static const symbol s_7_0[3] = { 'n', 'd', 'a' }; @@ -157,8 +157,8 @@ static const symbol s_7_1[3] = { 'n', 'd', 'e' }; static const struct among a_7[2] = { -/* 0 */ { 3, s_7_0, -1, -1, 0}, -/* 1 */ { 3, s_7_1, -1, -1, 0} +{ 3, s_7_0, -1, -1, 0}, +{ 3, s_7_1, -1, -1, 0} }; static const symbol s_8_0[3] = { 'd', 'a', 'n' }; @@ -168,10 +168,10 @@ static const symbol s_8_3[3] = { 't', 'e', 'n' }; static const struct among a_8[4] = { -/* 0 */ { 3, s_8_0, -1, -1, 0}, -/* 1 */ { 3, s_8_1, -1, -1, 0}, -/* 2 */ { 3, s_8_2, -1, -1, 0}, -/* 3 */ { 3, s_8_3, -1, -1, 0} +{ 3, s_8_0, -1, -1, 0}, +{ 3, s_8_1, -1, -1, 0}, +{ 3, s_8_2, -1, -1, 0}, +{ 3, s_8_3, -1, -1, 0} }; static const symbol s_9_0[4] = { 'n', 'd', 'a', 'n' }; @@ -179,8 +179,8 @@ static const symbol s_9_1[4] = { 'n', 'd', 'e', 'n' }; static const struct among a_9[2] = { -/* 0 */ { 4, s_9_0, -1, -1, 0}, -/* 1 */ { 4, s_9_1, -1, -1, 0} +{ 4, s_9_0, -1, -1, 0}, +{ 4, s_9_1, -1, -1, 0} }; static const symbol s_10_0[2] = { 'l', 'a' }; @@ -188,8 +188,8 @@ static const symbol s_10_1[2] = { 'l', 'e' }; static const struct among a_10[2] = { -/* 0 */ { 2, s_10_0, -1, -1, 0}, -/* 1 */ { 2, s_10_1, -1, -1, 0} +{ 2, s_10_0, -1, -1, 0}, +{ 2, s_10_1, -1, -1, 0} }; static const symbol s_11_0[2] = { 'c', 'a' }; @@ -197,8 +197,8 @@ static const symbol s_11_1[2] = { 'c', 'e' }; static const struct among a_11[2] = { -/* 0 */ { 2, s_11_0, -1, -1, 0}, -/* 1 */ { 2, s_11_1, -1, -1, 0} +{ 2, s_11_0, -1, -1, 0}, +{ 2, s_11_1, -1, -1, 0} }; static const symbol s_12_0[2] = { 'i', 'm' }; @@ -208,10 +208,10 @@ static const symbol s_12_3[3] = { 0xC3, 0xBC, 'm' }; static const struct among a_12[4] = { -/* 0 */ { 2, s_12_0, -1, -1, 0}, -/* 1 */ { 2, s_12_1, -1, -1, 0}, -/* 2 */ { 3, s_12_2, -1, -1, 0}, -/* 3 */ { 3, s_12_3, -1, -1, 0} +{ 2, s_12_0, -1, -1, 0}, +{ 2, s_12_1, -1, -1, 0}, +{ 3, s_12_2, -1, -1, 0}, +{ 3, s_12_3, -1, -1, 0} }; static const symbol s_13_0[3] = { 's', 'i', 'n' }; @@ -221,10 +221,10 @@ static const symbol s_13_3[4] = { 's', 0xC3, 0xBC, 'n' }; static const struct among a_13[4] = { -/* 0 */ { 3, s_13_0, -1, -1, 0}, -/* 1 */ { 3, s_13_1, -1, -1, 0}, -/* 2 */ { 4, s_13_2, -1, -1, 0}, -/* 3 */ { 4, s_13_3, -1, -1, 0} +{ 3, s_13_0, -1, -1, 0}, +{ 3, s_13_1, -1, -1, 0}, +{ 4, s_13_2, -1, -1, 0}, +{ 4, s_13_3, -1, -1, 0} }; static const symbol s_14_0[2] = { 'i', 'z' }; @@ -234,10 +234,10 @@ static const symbol s_14_3[3] = { 0xC3, 0xBC, 'z' }; static const struct among a_14[4] = { -/* 0 */ { 2, s_14_0, -1, -1, 0}, -/* 1 */ { 2, s_14_1, -1, -1, 0}, -/* 2 */ { 3, s_14_2, -1, -1, 0}, -/* 3 */ { 3, s_14_3, -1, -1, 0} +{ 2, s_14_0, -1, -1, 0}, +{ 2, s_14_1, -1, -1, 0}, +{ 3, s_14_2, -1, -1, 0}, +{ 3, s_14_3, -1, -1, 0} }; static const symbol s_15_0[5] = { 's', 'i', 'n', 'i', 'z' }; @@ -247,10 +247,10 @@ static const symbol s_15_3[7] = { 's', 0xC3, 0xBC, 'n', 0xC3, 0xBC, 'z' }; static const struct among a_15[4] = { -/* 0 */ { 5, s_15_0, -1, -1, 0}, -/* 1 */ { 5, s_15_1, -1, -1, 0}, -/* 2 */ { 7, s_15_2, -1, -1, 0}, -/* 3 */ { 7, s_15_3, -1, -1, 0} +{ 5, s_15_0, -1, -1, 0}, +{ 5, s_15_1, -1, -1, 0}, +{ 7, s_15_2, -1, -1, 0}, +{ 7, s_15_3, -1, -1, 0} }; static const symbol s_16_0[3] = { 'l', 'a', 'r' }; @@ -258,8 +258,8 @@ static const symbol s_16_1[3] = { 'l', 'e', 'r' }; static const struct among a_16[2] = { -/* 0 */ { 3, s_16_0, -1, -1, 0}, -/* 1 */ { 3, s_16_1, -1, -1, 0} +{ 3, s_16_0, -1, -1, 0}, +{ 3, s_16_1, -1, -1, 0} }; static const symbol s_17_0[3] = { 'n', 'i', 'z' }; @@ -269,10 +269,10 @@ static const symbol s_17_3[4] = { 'n', 0xC3, 0xBC, 'z' }; static const struct among a_17[4] = { -/* 0 */ { 3, s_17_0, -1, -1, 0}, -/* 1 */ { 3, s_17_1, -1, -1, 0}, -/* 2 */ { 4, s_17_2, -1, -1, 0}, -/* 3 */ { 4, s_17_3, -1, -1, 0} +{ 3, s_17_0, -1, -1, 0}, +{ 3, s_17_1, -1, -1, 0}, +{ 4, s_17_2, -1, -1, 0}, +{ 4, s_17_3, -1, -1, 0} }; static const symbol s_18_0[3] = { 'd', 'i', 'r' }; @@ -286,14 +286,14 @@ static const symbol s_18_7[4] = { 't', 0xC3, 0xBC, 'r' }; static const struct among a_18[8] = { -/* 0 */ { 3, s_18_0, -1, -1, 0}, -/* 1 */ { 3, s_18_1, -1, -1, 0}, -/* 2 */ { 3, s_18_2, -1, -1, 0}, -/* 3 */ { 3, s_18_3, -1, -1, 0}, -/* 4 */ { 4, s_18_4, -1, -1, 0}, -/* 5 */ { 4, s_18_5, -1, -1, 0}, -/* 6 */ { 4, s_18_6, -1, -1, 0}, -/* 7 */ { 4, s_18_7, -1, -1, 0} +{ 3, s_18_0, -1, -1, 0}, +{ 3, s_18_1, -1, -1, 0}, +{ 3, s_18_2, -1, -1, 0}, +{ 3, s_18_3, -1, -1, 0}, +{ 4, s_18_4, -1, -1, 0}, +{ 4, s_18_5, -1, -1, 0}, +{ 4, s_18_6, -1, -1, 0}, +{ 4, s_18_7, -1, -1, 0} }; static const symbol s_19_0[7] = { 'c', 'a', 's', 0xC4, 0xB1, 'n', 'a' }; @@ -301,8 +301,8 @@ static const symbol s_19_1[6] = { 'c', 'e', 's', 'i', 'n', 'e' }; static const struct among a_19[2] = { -/* 0 */ { 7, s_19_0, -1, -1, 0}, -/* 1 */ { 6, s_19_1, -1, -1, 0} +{ 7, s_19_0, -1, -1, 0}, +{ 6, s_19_1, -1, -1, 0} }; static const symbol s_20_0[2] = { 'd', 'i' }; @@ -340,38 +340,38 @@ static const symbol s_20_31[3] = { 't', 0xC3, 0xBC }; static const struct among a_20[32] = { -/* 0 */ { 2, s_20_0, -1, -1, 0}, -/* 1 */ { 2, s_20_1, -1, -1, 0}, -/* 2 */ { 3, s_20_2, -1, -1, 0}, -/* 3 */ { 3, s_20_3, -1, -1, 0}, -/* 4 */ { 3, s_20_4, -1, -1, 0}, -/* 5 */ { 3, s_20_5, -1, -1, 0}, -/* 6 */ { 4, s_20_6, -1, -1, 0}, -/* 7 */ { 4, s_20_7, -1, -1, 0}, -/* 8 */ { 4, s_20_8, -1, -1, 0}, -/* 9 */ { 4, s_20_9, -1, -1, 0}, -/* 10 */ { 3, s_20_10, -1, -1, 0}, -/* 11 */ { 3, s_20_11, -1, -1, 0}, -/* 12 */ { 3, s_20_12, -1, -1, 0}, -/* 13 */ { 3, s_20_13, -1, -1, 0}, -/* 14 */ { 4, s_20_14, -1, -1, 0}, -/* 15 */ { 4, s_20_15, -1, -1, 0}, -/* 16 */ { 4, s_20_16, -1, -1, 0}, -/* 17 */ { 4, s_20_17, -1, -1, 0}, -/* 18 */ { 3, s_20_18, -1, -1, 0}, -/* 19 */ { 3, s_20_19, -1, -1, 0}, -/* 20 */ { 3, s_20_20, -1, -1, 0}, -/* 21 */ { 3, s_20_21, -1, -1, 0}, -/* 22 */ { 4, s_20_22, -1, -1, 0}, -/* 23 */ { 4, s_20_23, -1, -1, 0}, -/* 24 */ { 4, s_20_24, -1, -1, 0}, -/* 25 */ { 4, s_20_25, -1, -1, 0}, -/* 26 */ { 2, s_20_26, -1, -1, 0}, -/* 27 */ { 2, s_20_27, -1, -1, 0}, -/* 28 */ { 3, s_20_28, -1, -1, 0}, -/* 29 */ { 3, s_20_29, -1, -1, 0}, -/* 30 */ { 3, s_20_30, -1, -1, 0}, -/* 31 */ { 3, s_20_31, -1, -1, 0} +{ 2, s_20_0, -1, -1, 0}, +{ 2, s_20_1, -1, -1, 0}, +{ 3, s_20_2, -1, -1, 0}, +{ 3, s_20_3, -1, -1, 0}, +{ 3, s_20_4, -1, -1, 0}, +{ 3, s_20_5, -1, -1, 0}, +{ 4, s_20_6, -1, -1, 0}, +{ 4, s_20_7, -1, -1, 0}, +{ 4, s_20_8, -1, -1, 0}, +{ 4, s_20_9, -1, -1, 0}, +{ 3, s_20_10, -1, -1, 0}, +{ 3, s_20_11, -1, -1, 0}, +{ 3, s_20_12, -1, -1, 0}, +{ 3, s_20_13, -1, -1, 0}, +{ 4, s_20_14, -1, -1, 0}, +{ 4, s_20_15, -1, -1, 0}, +{ 4, s_20_16, -1, -1, 0}, +{ 4, s_20_17, -1, -1, 0}, +{ 3, s_20_18, -1, -1, 0}, +{ 3, s_20_19, -1, -1, 0}, +{ 3, s_20_20, -1, -1, 0}, +{ 3, s_20_21, -1, -1, 0}, +{ 4, s_20_22, -1, -1, 0}, +{ 4, s_20_23, -1, -1, 0}, +{ 4, s_20_24, -1, -1, 0}, +{ 4, s_20_25, -1, -1, 0}, +{ 2, s_20_26, -1, -1, 0}, +{ 2, s_20_27, -1, -1, 0}, +{ 3, s_20_28, -1, -1, 0}, +{ 3, s_20_29, -1, -1, 0}, +{ 3, s_20_30, -1, -1, 0}, +{ 3, s_20_31, -1, -1, 0} }; static const symbol s_21_0[2] = { 's', 'a' }; @@ -385,14 +385,14 @@ static const symbol s_21_7[3] = { 's', 'e', 'n' }; static const struct among a_21[8] = { -/* 0 */ { 2, s_21_0, -1, -1, 0}, -/* 1 */ { 2, s_21_1, -1, -1, 0}, -/* 2 */ { 3, s_21_2, -1, -1, 0}, -/* 3 */ { 3, s_21_3, -1, -1, 0}, -/* 4 */ { 3, s_21_4, -1, -1, 0}, -/* 5 */ { 3, s_21_5, -1, -1, 0}, -/* 6 */ { 3, s_21_6, -1, -1, 0}, -/* 7 */ { 3, s_21_7, -1, -1, 0} +{ 2, s_21_0, -1, -1, 0}, +{ 2, s_21_1, -1, -1, 0}, +{ 3, s_21_2, -1, -1, 0}, +{ 3, s_21_3, -1, -1, 0}, +{ 3, s_21_4, -1, -1, 0}, +{ 3, s_21_5, -1, -1, 0}, +{ 3, s_21_6, -1, -1, 0}, +{ 3, s_21_7, -1, -1, 0} }; static const symbol s_22_0[4] = { 'm', 'i', 0xC5, 0x9F }; @@ -402,10 +402,10 @@ static const symbol s_22_3[5] = { 'm', 0xC3, 0xBC, 0xC5, 0x9F }; static const struct among a_22[4] = { -/* 0 */ { 4, s_22_0, -1, -1, 0}, -/* 1 */ { 4, s_22_1, -1, -1, 0}, -/* 2 */ { 5, s_22_2, -1, -1, 0}, -/* 3 */ { 5, s_22_3, -1, -1, 0} +{ 4, s_22_0, -1, -1, 0}, +{ 4, s_22_1, -1, -1, 0}, +{ 5, s_22_2, -1, -1, 0}, +{ 5, s_22_3, -1, -1, 0} }; static const symbol s_23_0[1] = { 'b' }; @@ -415,10 +415,10 @@ static const symbol s_23_3[2] = { 0xC4, 0x9F }; static const struct among a_23[4] = { -/* 0 */ { 1, s_23_0, -1, 1, 0}, -/* 1 */ { 1, s_23_1, -1, 2, 0}, -/* 2 */ { 1, s_23_2, -1, 3, 0}, -/* 3 */ { 2, s_23_3, -1, 4, 0} +{ 1, s_23_0, -1, 1, 0}, +{ 1, s_23_1, -1, 2, 0}, +{ 1, s_23_2, -1, 3, 0}, +{ 2, s_23_3, -1, 4, 0} }; static const unsigned char g_vowel[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 8, 0, 0, 0, 0, 0, 0, 1 }; @@ -456,52 +456,52 @@ static const symbol s_15[] = { 0xC3, 0xBC }; static const symbol s_16[] = { 'a', 'd' }; static const symbol s_17[] = { 's', 'o', 'y' }; -static int r_check_vowel_harmony(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 110 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 112 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 114 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'a') goto lab1; /* literal, line 114 */ +static int r_check_vowel_harmony(struct SN_env * z) { + { int m_test1 = z->l - z->c; + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'a') goto lab1; z->c--; - if (out_grouping_b_U(z, g_vowel1, 97, 305, 1) < 0) goto lab1; /* goto */ /* grouping vowel1, line 114 */ + if (out_grouping_b_U(z, g_vowel1, 97, 305, 1) < 0) goto lab1; goto lab0; lab1: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab2; /* literal, line 115 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab2; z->c--; - if (out_grouping_b_U(z, g_vowel2, 101, 252, 1) < 0) goto lab2; /* goto */ /* grouping vowel2, line 115 */ + if (out_grouping_b_U(z, g_vowel2, 101, 252, 1) < 0) goto lab2; goto lab0; lab2: z->c = z->l - m2; - if (!(eq_s_b(z, 2, s_0))) goto lab3; /* literal, line 116 */ - if (out_grouping_b_U(z, g_vowel3, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel3, line 116 */ + if (!(eq_s_b(z, 2, s_0))) goto lab3; + if (out_grouping_b_U(z, g_vowel3, 97, 305, 1) < 0) goto lab3; goto lab0; lab3: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab4; /* literal, line 117 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab4; z->c--; - if (out_grouping_b_U(z, g_vowel4, 101, 105, 1) < 0) goto lab4; /* goto */ /* grouping vowel4, line 117 */ + if (out_grouping_b_U(z, g_vowel4, 101, 105, 1) < 0) goto lab4; goto lab0; lab4: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; /* literal, line 118 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; z->c--; - if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab5; /* goto */ /* grouping vowel5, line 118 */ + if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab5; goto lab0; lab5: z->c = z->l - m2; - if (!(eq_s_b(z, 2, s_1))) goto lab6; /* literal, line 119 */ - if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) goto lab6; /* goto */ /* grouping vowel6, line 119 */ + if (!(eq_s_b(z, 2, s_1))) goto lab6; + if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) goto lab6; goto lab0; lab6: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab7; /* literal, line 120 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab7; z->c--; - if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab7; /* goto */ /* grouping vowel5, line 120 */ + if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab7; goto lab0; lab7: z->c = z->l - m2; - if (!(eq_s_b(z, 2, s_2))) return 0; /* literal, line 121 */ - if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) return 0; /* goto */ /* grouping vowel6, line 121 */ + if (!(eq_s_b(z, 2, s_2))) return 0; + if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) return 0; } lab0: z->c = z->l - m_test1; @@ -509,20 +509,20 @@ static int r_check_vowel_harmony(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* or, line 132 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'n') goto lab1; /* literal, line 131 */ +static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'n') goto lab1; z->c--; - { int m_test2 = z->l - z->c; /* test, line 131 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* grouping vowel, line 131 */ + { int m_test2 = z->l - z->c; + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m3 = z->l - z->c; (void)m3; /* not, line 133 */ - { int m_test4 = z->l - z->c; /* test, line 133 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'n') goto lab2; /* literal, line 133 */ + { int m3 = z->l - z->c; (void)m3; + { int m_test4 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'n') goto lab2; z->c--; z->c = z->l - m_test4; } @@ -530,12 +530,12 @@ static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z) { /* backw lab2: z->c = z->l - m3; } - { int m_test5 = z->l - z->c; /* test, line 133 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int m_test5 = z->l - z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 133 */ + z->c = ret; } - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* grouping vowel, line 133 */ + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; z->c = z->l - m_test5; } } @@ -543,20 +543,20 @@ static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z) { /* backw return 1; } -static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* or, line 143 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 142 */ +static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; z->c--; - { int m_test2 = z->l - z->c; /* test, line 142 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* grouping vowel, line 142 */ + { int m_test2 = z->l - z->c; + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m3 = z->l - z->c; (void)m3; /* not, line 144 */ - { int m_test4 = z->l - z->c; /* test, line 144 */ - if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab2; /* literal, line 144 */ + { int m3 = z->l - z->c; (void)m3; + { int m_test4 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab2; z->c--; z->c = z->l - m_test4; } @@ -564,12 +564,12 @@ static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z) { /* backw lab2: z->c = z->l - m3; } - { int m_test5 = z->l - z->c; /* test, line 144 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int m_test5 = z->l - z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 144 */ + z->c = ret; } - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* grouping vowel, line 144 */ + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; z->c = z->l - m_test5; } } @@ -577,20 +577,20 @@ static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z) { /* backw return 1; } -static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* or, line 153 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 152 */ +static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; z->c--; - { int m_test2 = z->l - z->c; /* test, line 152 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* grouping vowel, line 152 */ + { int m_test2 = z->l - z->c; + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m3 = z->l - z->c; (void)m3; /* not, line 154 */ - { int m_test4 = z->l - z->c; /* test, line 154 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab2; /* literal, line 154 */ + { int m3 = z->l - z->c; (void)m3; + { int m_test4 = z->l - z->c; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab2; z->c--; z->c = z->l - m_test4; } @@ -598,12 +598,12 @@ static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z) { /* backw lab2: z->c = z->l - m3; } - { int m_test5 = z->l - z->c; /* test, line 154 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int m_test5 = z->l - z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 154 */ + z->c = ret; } - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* grouping vowel, line 154 */ + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; z->c = z->l - m_test5; } } @@ -611,31 +611,31 @@ static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z) { /* backw return 1; } -static int r_mark_suffix_with_optional_U_vowel(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* or, line 159 */ - if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab1; /* grouping U, line 158 */ - { int m_test2 = z->l - z->c; /* test, line 158 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* non vowel, line 158 */ +static int r_mark_suffix_with_optional_U_vowel(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab1; + { int m_test2 = z->l - z->c; + if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m3 = z->l - z->c; (void)m3; /* not, line 160 */ - { int m_test4 = z->l - z->c; /* test, line 160 */ - if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab2; /* grouping U, line 160 */ + { int m3 = z->l - z->c; (void)m3; + { int m_test4 = z->l - z->c; + if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab2; z->c = z->l - m_test4; } return 0; lab2: z->c = z->l - m3; } - { int m_test5 = z->l - z->c; /* test, line 160 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + { int m_test5 = z->l - z->c; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); if (ret < 0) return 0; - z->c = ret; /* next, line 160 */ + z->c = ret; } - if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* non vowel, line 160 */ + if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; z->c = z->l - m_test5; } } @@ -643,288 +643,288 @@ static int r_mark_suffix_with_optional_U_vowel(struct SN_env * z) { /* backwardm return 1; } -static int r_mark_possessives(struct SN_env * z) { /* backwardmode */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((67133440 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 165 */ +static int r_mark_possessives(struct SN_env * z) { + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((67133440 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_0, 10))) return 0; - { int ret = r_mark_suffix_with_optional_U_vowel(z); /* call mark_suffix_with_optional_U_vowel, line 167 */ + { int ret = r_mark_suffix_with_optional_U_vowel(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_sU(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 171 */ +static int r_mark_sU(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; /* grouping U, line 172 */ - { int ret = r_mark_suffix_with_optional_s_consonant(z); /* call mark_suffix_with_optional_s_consonant, line 173 */ + if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; + { int ret = r_mark_suffix_with_optional_s_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_lArI(struct SN_env * z) { /* backwardmode */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 177)) return 0; /* among, line 177 */ +static int r_mark_lArI(struct SN_env * z) { + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 177)) return 0; if (!(find_among_b(z, a_1, 2))) return 0; return 1; } -static int r_mark_yU(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 181 */ +static int r_mark_yU(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; /* grouping U, line 182 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 183 */ + if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_nU(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 187 */ +static int r_mark_nU(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (!(find_among_b(z, a_2, 4))) return 0; /* among, line 188 */ + if (!(find_among_b(z, a_2, 4))) return 0; return 1; } -static int r_mark_nUn(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 192 */ +static int r_mark_nUn(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 193 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 110) return 0; if (!(find_among_b(z, a_3, 4))) return 0; - { int ret = r_mark_suffix_with_optional_n_consonant(z); /* call mark_suffix_with_optional_n_consonant, line 194 */ + { int ret = r_mark_suffix_with_optional_n_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_yA(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 198 */ +static int r_mark_yA(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 199 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; if (!(find_among_b(z, a_4, 2))) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 200 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_nA(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 204 */ +static int r_mark_nA(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 205 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; if (!(find_among_b(z, a_5, 2))) return 0; return 1; } -static int r_mark_DA(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 209 */ +static int r_mark_DA(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 210 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; if (!(find_among_b(z, a_6, 4))) return 0; return 1; } -static int r_mark_ndA(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 214 */ +static int r_mark_ndA(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 215 */ + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; if (!(find_among_b(z, a_7, 2))) return 0; return 1; } -static int r_mark_DAn(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 219 */ +static int r_mark_DAn(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 220 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; if (!(find_among_b(z, a_8, 4))) return 0; return 1; } -static int r_mark_ndAn(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 224 */ +static int r_mark_ndAn(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 225 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 110) return 0; if (!(find_among_b(z, a_9, 2))) return 0; return 1; } -static int r_mark_ylA(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 229 */ +static int r_mark_ylA(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 230 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; if (!(find_among_b(z, a_10, 2))) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 231 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_ki(struct SN_env * z) { /* backwardmode */ - if (!(eq_s_b(z, 2, s_3))) return 0; /* literal, line 235 */ +static int r_mark_ki(struct SN_env * z) { + if (!(eq_s_b(z, 2, s_3))) return 0; return 1; } -static int r_mark_ncA(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 239 */ +static int r_mark_ncA(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 240 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; if (!(find_among_b(z, a_11, 2))) return 0; - { int ret = r_mark_suffix_with_optional_n_consonant(z); /* call mark_suffix_with_optional_n_consonant, line 241 */ + { int ret = r_mark_suffix_with_optional_n_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_yUm(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 245 */ +static int r_mark_yUm(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 109) return 0; /* among, line 246 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 109) return 0; if (!(find_among_b(z, a_12, 4))) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 247 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_sUn(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 251 */ +static int r_mark_sUn(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 252 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; if (!(find_among_b(z, a_13, 4))) return 0; return 1; } -static int r_mark_yUz(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 256 */ +static int r_mark_yUz(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 122) return 0; /* among, line 257 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 122) return 0; if (!(find_among_b(z, a_14, 4))) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 258 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_sUnUz(struct SN_env * z) { /* backwardmode */ - if (z->c - 4 <= z->lb || z->p[z->c - 1] != 122) return 0; /* among, line 262 */ +static int r_mark_sUnUz(struct SN_env * z) { + if (z->c - 4 <= z->lb || z->p[z->c - 1] != 122) return 0; if (!(find_among_b(z, a_15, 4))) return 0; return 1; } -static int r_mark_lAr(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 266 */ +static int r_mark_lAr(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; /* among, line 267 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; if (!(find_among_b(z, a_16, 2))) return 0; return 1; } -static int r_mark_nUz(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 271 */ +static int r_mark_nUz(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 122) return 0; /* among, line 272 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 122) return 0; if (!(find_among_b(z, a_17, 4))) return 0; return 1; } -static int r_mark_DUr(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 276 */ +static int r_mark_DUr(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; /* among, line 277 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; if (!(find_among_b(z, a_18, 8))) return 0; return 1; } -static int r_mark_cAsInA(struct SN_env * z) { /* backwardmode */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 281 */ +static int r_mark_cAsInA(struct SN_env * z) { + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; if (!(find_among_b(z, a_19, 2))) return 0; return 1; } -static int r_mark_yDU(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 285 */ +static int r_mark_yDU(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (!(find_among_b(z, a_20, 32))) return 0; /* among, line 286 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 290 */ + if (!(find_among_b(z, a_20, 32))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_ysA(struct SN_env * z) { /* backwardmode */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((26658 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 295 */ +static int r_mark_ysA(struct SN_env * z) { + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((26658 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; if (!(find_among_b(z, a_21, 8))) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 296 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_ymUs_(struct SN_env * z) { /* backwardmode */ - { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 300 */ +static int r_mark_ymUs_(struct SN_env * z) { + { int ret = r_check_vowel_harmony(z); if (ret <= 0) return ret; } - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 159) return 0; /* among, line 301 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 159) return 0; if (!(find_among_b(z, a_22, 4))) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 302 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_mark_yken(struct SN_env * z) { /* backwardmode */ - if (!(eq_s_b(z, 3, s_4))) return 0; /* literal, line 306 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 306 */ +static int r_mark_yken(struct SN_env * z) { + if (!(eq_s_b(z, 3, s_4))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); if (ret <= 0) return ret; } return 1; } -static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 310 */ - z->B[0] = 1; /* set continue_stemming_noun_suffixes, line 311 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 313 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 312 */ - { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 312 */ +static int r_stem_nominal_verb_suffixes(struct SN_env * z) { + z->ket = z->c; + z->I[0] = 1; + { int m1 = z->l - z->c; (void)m1; + { int m2 = z->l - z->c; (void)m2; + { int ret = r_mark_ymUs_(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } goto lab2; lab3: z->c = z->l - m2; - { int ret = r_mark_yDU(z); /* call mark_yDU, line 312 */ + { int ret = r_mark_yDU(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab2; lab4: z->c = z->l - m2; - { int ret = r_mark_ysA(z); /* call mark_ysA, line 312 */ + { int ret = r_mark_ysA(z); if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab2; lab5: z->c = z->l - m2; - { int ret = r_mark_yken(z); /* call mark_yken, line 312 */ + { int ret = r_mark_yken(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } @@ -933,40 +933,40 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab1: z->c = z->l - m1; - { int ret = r_mark_cAsInA(z); /* call mark_cAsInA, line 314 */ + { int ret = r_mark_cAsInA(z); if (ret == 0) goto lab6; if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* or, line 314 */ - { int ret = r_mark_sUnUz(z); /* call mark_sUnUz, line 314 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_mark_sUnUz(z); if (ret == 0) goto lab8; if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m3; - { int ret = r_mark_lAr(z); /* call mark_lAr, line 314 */ + { int ret = r_mark_lAr(z); if (ret == 0) goto lab9; if (ret < 0) return ret; } goto lab7; lab9: z->c = z->l - m3; - { int ret = r_mark_yUm(z); /* call mark_yUm, line 314 */ + { int ret = r_mark_yUm(z); if (ret == 0) goto lab10; if (ret < 0) return ret; } goto lab7; lab10: z->c = z->l - m3; - { int ret = r_mark_sUn(z); /* call mark_sUn, line 314 */ + { int ret = r_mark_sUn(z); if (ret == 0) goto lab11; if (ret < 0) return ret; } goto lab7; lab11: z->c = z->l - m3; - { int ret = r_mark_yUz(z); /* call mark_yUz, line 314 */ + { int ret = r_mark_yUz(z); if (ret == 0) goto lab12; if (ret < 0) return ret; } @@ -975,46 +975,46 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ z->c = z->l - m3; } lab7: - { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 314 */ + { int ret = r_mark_ymUs_(z); if (ret == 0) goto lab6; if (ret < 0) return ret; } goto lab0; lab6: z->c = z->l - m1; - { int ret = r_mark_lAr(z); /* call mark_lAr, line 317 */ + { int ret = r_mark_lAr(z); if (ret == 0) goto lab13; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 317 */ - { int ret = slice_del(z); /* delete, line 317 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 317 */ - z->ket = z->c; /* [, line 317 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 317 */ - { int ret = r_mark_DUr(z); /* call mark_DUr, line 317 */ + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + { int m5 = z->l - z->c; (void)m5; + { int ret = r_mark_DUr(z); if (ret == 0) goto lab16; if (ret < 0) return ret; } goto lab15; lab16: z->c = z->l - m5; - { int ret = r_mark_yDU(z); /* call mark_yDU, line 317 */ + { int ret = r_mark_yDU(z); if (ret == 0) goto lab17; if (ret < 0) return ret; } goto lab15; lab17: z->c = z->l - m5; - { int ret = r_mark_ysA(z); /* call mark_ysA, line 317 */ + { int ret = r_mark_ysA(z); if (ret == 0) goto lab18; if (ret < 0) return ret; } goto lab15; lab18: z->c = z->l - m5; - { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 317 */ + { int ret = r_mark_ymUs_(z); if (ret == 0) { z->c = z->l - m4; goto lab14; } if (ret < 0) return ret; } @@ -1023,23 +1023,23 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ lab14: ; } - z->B[0] = 0; /* unset continue_stemming_noun_suffixes, line 318 */ + z->I[0] = 0; goto lab0; lab13: z->c = z->l - m1; - { int ret = r_mark_nUz(z); /* call mark_nUz, line 321 */ + { int ret = r_mark_nUz(z); if (ret == 0) goto lab19; if (ret < 0) return ret; } - { int m6 = z->l - z->c; (void)m6; /* or, line 321 */ - { int ret = r_mark_yDU(z); /* call mark_yDU, line 321 */ + { int m6 = z->l - z->c; (void)m6; + { int ret = r_mark_yDU(z); if (ret == 0) goto lab21; if (ret < 0) return ret; } goto lab20; lab21: z->c = z->l - m6; - { int ret = r_mark_ysA(z); /* call mark_ysA, line 321 */ + { int ret = r_mark_ysA(z); if (ret == 0) goto lab19; if (ret < 0) return ret; } @@ -1048,41 +1048,41 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab19: z->c = z->l - m1; - { int m7 = z->l - z->c; (void)m7; /* or, line 323 */ - { int ret = r_mark_sUnUz(z); /* call mark_sUnUz, line 323 */ + { int m7 = z->l - z->c; (void)m7; + { int ret = r_mark_sUnUz(z); if (ret == 0) goto lab24; if (ret < 0) return ret; } goto lab23; lab24: z->c = z->l - m7; - { int ret = r_mark_yUz(z); /* call mark_yUz, line 323 */ + { int ret = r_mark_yUz(z); if (ret == 0) goto lab25; if (ret < 0) return ret; } goto lab23; lab25: z->c = z->l - m7; - { int ret = r_mark_sUn(z); /* call mark_sUn, line 323 */ + { int ret = r_mark_sUn(z); if (ret == 0) goto lab26; if (ret < 0) return ret; } goto lab23; lab26: z->c = z->l - m7; - { int ret = r_mark_yUm(z); /* call mark_yUm, line 323 */ + { int ret = r_mark_yUm(z); if (ret == 0) goto lab22; if (ret < 0) return ret; } } lab23: - z->bra = z->c; /* ], line 323 */ - { int ret = slice_del(z); /* delete, line 323 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m8 = z->l - z->c; (void)m8; /* try, line 323 */ - z->ket = z->c; /* [, line 323 */ - { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 323 */ + { int m8 = z->l - z->c; (void)m8; + z->ket = z->c; + { int ret = r_mark_ymUs_(z); if (ret == 0) { z->c = z->l - m8; goto lab27; } if (ret < 0) return ret; } @@ -1092,45 +1092,45 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab22: z->c = z->l - m1; - { int ret = r_mark_DUr(z); /* call mark_DUr, line 325 */ + { int ret = r_mark_DUr(z); if (ret <= 0) return ret; } - z->bra = z->c; /* ], line 325 */ - { int ret = slice_del(z); /* delete, line 325 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m9 = z->l - z->c; (void)m9; /* try, line 325 */ - z->ket = z->c; /* [, line 325 */ - { int m10 = z->l - z->c; (void)m10; /* or, line 325 */ - { int ret = r_mark_sUnUz(z); /* call mark_sUnUz, line 325 */ + { int m9 = z->l - z->c; (void)m9; + z->ket = z->c; + { int m10 = z->l - z->c; (void)m10; + { int ret = r_mark_sUnUz(z); if (ret == 0) goto lab30; if (ret < 0) return ret; } goto lab29; lab30: z->c = z->l - m10; - { int ret = r_mark_lAr(z); /* call mark_lAr, line 325 */ + { int ret = r_mark_lAr(z); if (ret == 0) goto lab31; if (ret < 0) return ret; } goto lab29; lab31: z->c = z->l - m10; - { int ret = r_mark_yUm(z); /* call mark_yUm, line 325 */ + { int ret = r_mark_yUm(z); if (ret == 0) goto lab32; if (ret < 0) return ret; } goto lab29; lab32: z->c = z->l - m10; - { int ret = r_mark_sUn(z); /* call mark_sUn, line 325 */ + { int ret = r_mark_sUn(z); if (ret == 0) goto lab33; if (ret < 0) return ret; } goto lab29; lab33: z->c = z->l - m10; - { int ret = r_mark_yUz(z); /* call mark_yUz, line 325 */ + { int ret = r_mark_yUz(z); if (ret == 0) goto lab34; if (ret < 0) return ret; } @@ -1139,7 +1139,7 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ z->c = z->l - m10; } lab29: - { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 325 */ + { int ret = r_mark_ymUs_(z); if (ret == 0) { z->c = z->l - m9; goto lab28; } if (ret < 0) return ret; } @@ -1148,40 +1148,40 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ } } lab0: - z->bra = z->c; /* ], line 326 */ - { int ret = slice_del(z); /* delete, line 326 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } return 1; } -static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ - z->ket = z->c; /* [, line 331 */ - { int ret = r_mark_ki(z); /* call mark_ki, line 332 */ +static int r_stem_suffix_chain_before_ki(struct SN_env * z) { + z->ket = z->c; + { int ret = r_mark_ki(z); if (ret <= 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* or, line 340 */ - { int ret = r_mark_DA(z); /* call mark_DA, line 334 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_mark_DA(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 334 */ - { int ret = slice_del(z); /* delete, line 334 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 334 */ - z->ket = z->c; /* [, line 334 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 336 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 335 */ + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + { int m3 = z->l - z->c; (void)m3; + { int ret = r_mark_lAr(z); if (ret == 0) goto lab4; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 335 */ - { int ret = slice_del(z); /* delete, line 335 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m4 = z->l - z->c; (void)m4; /* try, line 335 */ - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 335 */ + { int m4 = z->l - z->c; (void)m4; + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m4; goto lab5; } if (ret < 0) return ret; } @@ -1191,25 +1191,25 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ goto lab3; lab4: z->c = z->l - m3; - { int ret = r_mark_possessives(z); /* call mark_possessives, line 337 */ + { int ret = r_mark_possessives(z); if (ret == 0) { z->c = z->l - m2; goto lab2; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 337 */ - { int ret = slice_del(z); /* delete, line 337 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* try, line 337 */ - z->ket = z->c; /* [, line 337 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 337 */ + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 337 */ - { int ret = slice_del(z); /* delete, line 337 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 337 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } @@ -1224,58 +1224,58 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ goto lab0; lab1: z->c = z->l - m1; - { int ret = r_mark_nUn(z); /* call mark_nUn, line 341 */ + { int ret = r_mark_nUn(z); if (ret == 0) goto lab7; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 341 */ - { int ret = slice_del(z); /* delete, line 341 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m6 = z->l - z->c; (void)m6; /* try, line 341 */ - z->ket = z->c; /* [, line 341 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 343 */ - { int ret = r_mark_lArI(z); /* call mark_lArI, line 342 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + { int m7 = z->l - z->c; (void)m7; + { int ret = r_mark_lArI(z); if (ret == 0) goto lab10; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 342 */ - { int ret = slice_del(z); /* delete, line 342 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab9; lab10: z->c = z->l - m7; - z->ket = z->c; /* [, line 344 */ - { int m8 = z->l - z->c; (void)m8; /* or, line 344 */ - { int ret = r_mark_possessives(z); /* call mark_possessives, line 344 */ + z->ket = z->c; + { int m8 = z->l - z->c; (void)m8; + { int ret = r_mark_possessives(z); if (ret == 0) goto lab13; if (ret < 0) return ret; } goto lab12; lab13: z->c = z->l - m8; - { int ret = r_mark_sU(z); /* call mark_sU, line 344 */ + { int ret = r_mark_sU(z); if (ret == 0) goto lab11; if (ret < 0) return ret; } } lab12: - z->bra = z->c; /* ], line 344 */ - { int ret = slice_del(z); /* delete, line 344 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m9 = z->l - z->c; (void)m9; /* try, line 344 */ - z->ket = z->c; /* [, line 344 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 344 */ + { int m9 = z->l - z->c; (void)m9; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m9; goto lab14; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 344 */ - { int ret = slice_del(z); /* delete, line 344 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 344 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m9; goto lab14; } if (ret < 0) return ret; } @@ -1285,7 +1285,7 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ goto lab9; lab11: z->c = z->l - m7; - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 346 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m6; goto lab8; } if (ret < 0) return ret; } @@ -1297,40 +1297,40 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ goto lab0; lab7: z->c = z->l - m1; - { int ret = r_mark_ndA(z); /* call mark_ndA, line 349 */ + { int ret = r_mark_ndA(z); if (ret <= 0) return ret; } - { int m10 = z->l - z->c; (void)m10; /* or, line 351 */ - { int ret = r_mark_lArI(z); /* call mark_lArI, line 350 */ + { int m10 = z->l - z->c; (void)m10; + { int ret = r_mark_lArI(z); if (ret == 0) goto lab16; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 350 */ - { int ret = slice_del(z); /* delete, line 350 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab15; lab16: z->c = z->l - m10; - { int ret = r_mark_sU(z); /* call mark_sU, line 352 */ + { int ret = r_mark_sU(z); if (ret == 0) goto lab17; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 352 */ - { int ret = slice_del(z); /* delete, line 352 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m11 = z->l - z->c; (void)m11; /* try, line 352 */ - z->ket = z->c; /* [, line 352 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 352 */ + { int m11 = z->l - z->c; (void)m11; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m11; goto lab18; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 352 */ - { int ret = slice_del(z); /* delete, line 352 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 352 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m11; goto lab18; } if (ret < 0) return ret; } @@ -1340,7 +1340,7 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ goto lab15; lab17: z->c = z->l - m10; - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 354 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret <= 0) return ret; } } @@ -1351,19 +1351,19 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ - { int m1 = z->l - z->c; (void)m1; /* or, line 361 */ - z->ket = z->c; /* [, line 360 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 360 */ +static int r_stem_noun_suffixes(struct SN_env * z) { + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) goto lab1; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 360 */ - { int ret = slice_del(z); /* delete, line 360 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* try, line 360 */ - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 360 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m2; goto lab2; } if (ret < 0) return ret; } @@ -1373,59 +1373,59 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 362 */ - { int ret = r_mark_ncA(z); /* call mark_ncA, line 362 */ + z->ket = z->c; + { int ret = r_mark_ncA(z); if (ret == 0) goto lab3; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 362 */ - { int ret = slice_del(z); /* delete, line 362 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* try, line 363 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 365 */ - z->ket = z->c; /* [, line 364 */ - { int ret = r_mark_lArI(z); /* call mark_lArI, line 364 */ + { int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + { int ret = r_mark_lArI(z); if (ret == 0) goto lab6; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 364 */ - { int ret = slice_del(z); /* delete, line 364 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab5; lab6: z->c = z->l - m4; - z->ket = z->c; /* [, line 366 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 366 */ - { int ret = r_mark_possessives(z); /* call mark_possessives, line 366 */ + z->ket = z->c; + { int m5 = z->l - z->c; (void)m5; + { int ret = r_mark_possessives(z); if (ret == 0) goto lab9; if (ret < 0) return ret; } goto lab8; lab9: z->c = z->l - m5; - { int ret = r_mark_sU(z); /* call mark_sU, line 366 */ + { int ret = r_mark_sU(z); if (ret == 0) goto lab7; if (ret < 0) return ret; } } lab8: - z->bra = z->c; /* ], line 366 */ - { int ret = slice_del(z); /* delete, line 366 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m6 = z->l - z->c; (void)m6; /* try, line 366 */ - z->ket = z->c; /* [, line 366 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 366 */ + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m6; goto lab10; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 366 */ - { int ret = slice_del(z); /* delete, line 366 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 366 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m6; goto lab10; } if (ret < 0) return ret; } @@ -1435,16 +1435,16 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab5; lab7: z->c = z->l - m4; - z->ket = z->c; /* [, line 368 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 368 */ + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m3; goto lab4; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 368 */ - { int ret = slice_del(z); /* delete, line 368 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 368 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m3; goto lab4; } if (ret < 0) return ret; } @@ -1456,52 +1456,52 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab3: z->c = z->l - m1; - z->ket = z->c; /* [, line 372 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 372 */ - { int ret = r_mark_ndA(z); /* call mark_ndA, line 372 */ + z->ket = z->c; + { int m7 = z->l - z->c; (void)m7; + { int ret = r_mark_ndA(z); if (ret == 0) goto lab13; if (ret < 0) return ret; } goto lab12; lab13: z->c = z->l - m7; - { int ret = r_mark_nA(z); /* call mark_nA, line 372 */ + { int ret = r_mark_nA(z); if (ret == 0) goto lab11; if (ret < 0) return ret; } } lab12: - { int m8 = z->l - z->c; (void)m8; /* or, line 375 */ - { int ret = r_mark_lArI(z); /* call mark_lArI, line 374 */ + { int m8 = z->l - z->c; (void)m8; + { int ret = r_mark_lArI(z); if (ret == 0) goto lab15; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 374 */ - { int ret = slice_del(z); /* delete, line 374 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab14; lab15: z->c = z->l - m8; - { int ret = r_mark_sU(z); /* call mark_sU, line 376 */ + { int ret = r_mark_sU(z); if (ret == 0) goto lab16; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 376 */ - { int ret = slice_del(z); /* delete, line 376 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m9 = z->l - z->c; (void)m9; /* try, line 376 */ - z->ket = z->c; /* [, line 376 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 376 */ + { int m9 = z->l - z->c; (void)m9; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m9; goto lab17; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 376 */ - { int ret = slice_del(z); /* delete, line 376 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 376 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m9; goto lab17; } if (ret < 0) return ret; } @@ -1511,7 +1511,7 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab14; lab16: z->c = z->l - m8; - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 378 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) goto lab11; if (ret < 0) return ret; } @@ -1520,41 +1520,41 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab11: z->c = z->l - m1; - z->ket = z->c; /* [, line 382 */ - { int m10 = z->l - z->c; (void)m10; /* or, line 382 */ - { int ret = r_mark_ndAn(z); /* call mark_ndAn, line 382 */ + z->ket = z->c; + { int m10 = z->l - z->c; (void)m10; + { int ret = r_mark_ndAn(z); if (ret == 0) goto lab20; if (ret < 0) return ret; } goto lab19; lab20: z->c = z->l - m10; - { int ret = r_mark_nU(z); /* call mark_nU, line 382 */ + { int ret = r_mark_nU(z); if (ret == 0) goto lab18; if (ret < 0) return ret; } } lab19: - { int m11 = z->l - z->c; (void)m11; /* or, line 382 */ - { int ret = r_mark_sU(z); /* call mark_sU, line 382 */ + { int m11 = z->l - z->c; (void)m11; + { int ret = r_mark_sU(z); if (ret == 0) goto lab22; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 382 */ - { int ret = slice_del(z); /* delete, line 382 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m12 = z->l - z->c; (void)m12; /* try, line 382 */ - z->ket = z->c; /* [, line 382 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 382 */ + { int m12 = z->l - z->c; (void)m12; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m12; goto lab23; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 382 */ - { int ret = slice_del(z); /* delete, line 382 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 382 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m12; goto lab23; } if (ret < 0) return ret; } @@ -1564,7 +1564,7 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab21; lab22: z->c = z->l - m11; - { int ret = r_mark_lArI(z); /* call mark_lArI, line 382 */ + { int ret = r_mark_lArI(z); if (ret == 0) goto lab18; if (ret < 0) return ret; } @@ -1573,37 +1573,37 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab18: z->c = z->l - m1; - z->ket = z->c; /* [, line 384 */ - { int ret = r_mark_DAn(z); /* call mark_DAn, line 384 */ + z->ket = z->c; + { int ret = r_mark_DAn(z); if (ret == 0) goto lab24; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 384 */ - { int ret = slice_del(z); /* delete, line 384 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m13 = z->l - z->c; (void)m13; /* try, line 384 */ - z->ket = z->c; /* [, line 384 */ - { int m14 = z->l - z->c; (void)m14; /* or, line 387 */ - { int ret = r_mark_possessives(z); /* call mark_possessives, line 386 */ + { int m13 = z->l - z->c; (void)m13; + z->ket = z->c; + { int m14 = z->l - z->c; (void)m14; + { int ret = r_mark_possessives(z); if (ret == 0) goto lab27; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 386 */ - { int ret = slice_del(z); /* delete, line 386 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m15 = z->l - z->c; (void)m15; /* try, line 386 */ - z->ket = z->c; /* [, line 386 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 386 */ + { int m15 = z->l - z->c; (void)m15; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m15; goto lab28; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 386 */ - { int ret = slice_del(z); /* delete, line 386 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 386 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m15; goto lab28; } if (ret < 0) return ret; } @@ -1613,16 +1613,16 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab26; lab27: z->c = z->l - m14; - { int ret = r_mark_lAr(z); /* call mark_lAr, line 388 */ + { int ret = r_mark_lAr(z); if (ret == 0) goto lab29; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 388 */ - { int ret = slice_del(z); /* delete, line 388 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m16 = z->l - z->c; (void)m16; /* try, line 388 */ - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 388 */ + { int m16 = z->l - z->c; (void)m16; + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m16; goto lab30; } if (ret < 0) return ret; } @@ -1632,7 +1632,7 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab26; lab29: z->c = z->l - m14; - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 390 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m13; goto lab25; } if (ret < 0) return ret; } @@ -1644,73 +1644,73 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab24: z->c = z->l - m1; - z->ket = z->c; /* [, line 394 */ - { int m17 = z->l - z->c; (void)m17; /* or, line 394 */ - { int ret = r_mark_nUn(z); /* call mark_nUn, line 394 */ + z->ket = z->c; + { int m17 = z->l - z->c; (void)m17; + { int ret = r_mark_nUn(z); if (ret == 0) goto lab33; if (ret < 0) return ret; } goto lab32; lab33: z->c = z->l - m17; - { int ret = r_mark_ylA(z); /* call mark_ylA, line 394 */ + { int ret = r_mark_ylA(z); if (ret == 0) goto lab31; if (ret < 0) return ret; } } lab32: - z->bra = z->c; /* ], line 394 */ - { int ret = slice_del(z); /* delete, line 394 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m18 = z->l - z->c; (void)m18; /* try, line 395 */ - { int m19 = z->l - z->c; (void)m19; /* or, line 397 */ - z->ket = z->c; /* [, line 396 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 396 */ + { int m18 = z->l - z->c; (void)m18; + { int m19 = z->l - z->c; (void)m19; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) goto lab36; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 396 */ - { int ret = slice_del(z); /* delete, line 396 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 396 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) goto lab36; if (ret < 0) return ret; } goto lab35; lab36: z->c = z->l - m19; - z->ket = z->c; /* [, line 398 */ - { int m20 = z->l - z->c; (void)m20; /* or, line 398 */ - { int ret = r_mark_possessives(z); /* call mark_possessives, line 398 */ + z->ket = z->c; + { int m20 = z->l - z->c; (void)m20; + { int ret = r_mark_possessives(z); if (ret == 0) goto lab39; if (ret < 0) return ret; } goto lab38; lab39: z->c = z->l - m20; - { int ret = r_mark_sU(z); /* call mark_sU, line 398 */ + { int ret = r_mark_sU(z); if (ret == 0) goto lab37; if (ret < 0) return ret; } } lab38: - z->bra = z->c; /* ], line 398 */ - { int ret = slice_del(z); /* delete, line 398 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m21 = z->l - z->c; (void)m21; /* try, line 398 */ - z->ket = z->c; /* [, line 398 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 398 */ + { int m21 = z->l - z->c; (void)m21; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m21; goto lab40; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 398 */ - { int ret = slice_del(z); /* delete, line 398 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 398 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m21; goto lab40; } if (ret < 0) return ret; } @@ -1720,7 +1720,7 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab35; lab37: z->c = z->l - m19; - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 400 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m18; goto lab34; } if (ret < 0) return ret; } @@ -1732,65 +1732,65 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab31: z->c = z->l - m1; - z->ket = z->c; /* [, line 404 */ - { int ret = r_mark_lArI(z); /* call mark_lArI, line 404 */ + z->ket = z->c; + { int ret = r_mark_lArI(z); if (ret == 0) goto lab41; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 404 */ - { int ret = slice_del(z); /* delete, line 404 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } goto lab0; lab41: z->c = z->l - m1; - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 406 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) goto lab42; if (ret < 0) return ret; } goto lab0; lab42: z->c = z->l - m1; - z->ket = z->c; /* [, line 408 */ - { int m22 = z->l - z->c; (void)m22; /* or, line 408 */ - { int ret = r_mark_DA(z); /* call mark_DA, line 408 */ + z->ket = z->c; + { int m22 = z->l - z->c; (void)m22; + { int ret = r_mark_DA(z); if (ret == 0) goto lab45; if (ret < 0) return ret; } goto lab44; lab45: z->c = z->l - m22; - { int ret = r_mark_yU(z); /* call mark_yU, line 408 */ + { int ret = r_mark_yU(z); if (ret == 0) goto lab46; if (ret < 0) return ret; } goto lab44; lab46: z->c = z->l - m22; - { int ret = r_mark_yA(z); /* call mark_yA, line 408 */ + { int ret = r_mark_yA(z); if (ret == 0) goto lab43; if (ret < 0) return ret; } } lab44: - z->bra = z->c; /* ], line 408 */ - { int ret = slice_del(z); /* delete, line 408 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m23 = z->l - z->c; (void)m23; /* try, line 408 */ - z->ket = z->c; /* [, line 408 */ - { int m24 = z->l - z->c; (void)m24; /* or, line 408 */ - { int ret = r_mark_possessives(z); /* call mark_possessives, line 408 */ + { int m23 = z->l - z->c; (void)m23; + z->ket = z->c; + { int m24 = z->l - z->c; (void)m24; + { int ret = r_mark_possessives(z); if (ret == 0) goto lab49; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 408 */ - { int ret = slice_del(z); /* delete, line 408 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m25 = z->l - z->c; (void)m25; /* try, line 408 */ - z->ket = z->c; /* [, line 408 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 408 */ + { int m25 = z->l - z->c; (void)m25; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m25; goto lab50; } if (ret < 0) return ret; } @@ -1800,18 +1800,18 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab48; lab49: z->c = z->l - m24; - { int ret = r_mark_lAr(z); /* call mark_lAr, line 408 */ + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m23; goto lab47; } if (ret < 0) return ret; } } lab48: - z->bra = z->c; /* ], line 408 */ - { int ret = slice_del(z); /* delete, line 408 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - z->ket = z->c; /* [, line 408 */ - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 408 */ + z->ket = z->c; + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m23; goto lab47; } if (ret < 0) return ret; } @@ -1821,35 +1821,35 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ goto lab0; lab43: z->c = z->l - m1; - z->ket = z->c; /* [, line 410 */ - { int m26 = z->l - z->c; (void)m26; /* or, line 410 */ - { int ret = r_mark_possessives(z); /* call mark_possessives, line 410 */ + z->ket = z->c; + { int m26 = z->l - z->c; (void)m26; + { int ret = r_mark_possessives(z); if (ret == 0) goto lab52; if (ret < 0) return ret; } goto lab51; lab52: z->c = z->l - m26; - { int ret = r_mark_sU(z); /* call mark_sU, line 410 */ + { int ret = r_mark_sU(z); if (ret <= 0) return ret; } } lab51: - z->bra = z->c; /* ], line 410 */ - { int ret = slice_del(z); /* delete, line 410 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int m27 = z->l - z->c; (void)m27; /* try, line 410 */ - z->ket = z->c; /* [, line 410 */ - { int ret = r_mark_lAr(z); /* call mark_lAr, line 410 */ + { int m27 = z->l - z->c; (void)m27; + z->ket = z->c; + { int ret = r_mark_lAr(z); if (ret == 0) { z->c = z->l - m27; goto lab53; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 410 */ - { int ret = slice_del(z); /* delete, line 410 */ + z->bra = z->c; + { int ret = slice_del(z); if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 410 */ + { int ret = r_stem_suffix_chain_before_ki(z); if (ret == 0) { z->c = z->l - m27; goto lab53; } if (ret < 0) return ret; } @@ -1861,30 +1861,30 @@ static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ return 1; } -static int r_post_process_last_consonants(struct SN_env * z) { /* backwardmode */ +static int r_post_process_last_consonants(struct SN_env * z) { int among_var; - z->ket = z->c; /* [, line 414 */ - among_var = find_among_b(z, a_23, 4); /* substring, line 414 */ + z->ket = z->c; + among_var = find_among_b(z, a_23, 4); if (!(among_var)) return 0; - z->bra = z->c; /* ], line 414 */ - switch (among_var) { /* among, line 414 */ + z->bra = z->c; + switch (among_var) { case 1: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 415 */ + { int ret = slice_from_s(z, 1, s_5); if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_6); /* <-, line 416 */ + { int ret = slice_from_s(z, 2, s_6); if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 417 */ + { int ret = slice_from_s(z, 1, s_7); if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 418 */ + { int ret = slice_from_s(z, 1, s_8); if (ret < 0) return ret; } break; @@ -1892,37 +1892,37 @@ static int r_post_process_last_consonants(struct SN_env * z) { /* backwardmode * return 1; } -static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwardmode */ - { int m_test1 = z->l - z->c; /* test, line 429 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 429 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'd') goto lab1; /* literal, line 429 */ +static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { + { int m_test1 = z->l - z->c; + { int m2 = z->l - z->c; (void)m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'd') goto lab1; z->c--; goto lab0; lab1: z->c = z->l - m2; - if (z->c <= z->lb || z->p[z->c - 1] != 'g') return 0; /* literal, line 429 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'g') return 0; z->c--; } lab0: z->c = z->l - m_test1; } - { int m3 = z->l - z->c; (void)m3; /* or, line 431 */ - { int m_test4 = z->l - z->c; /* test, line 430 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel, line 430 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 430 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'a') goto lab5; /* literal, line 430 */ + { int m3 = z->l - z->c; (void)m3; + { int m_test4 = z->l - z->c; + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab3; + { int m5 = z->l - z->c; (void)m5; + if (z->c <= z->lb || z->p[z->c - 1] != 'a') goto lab5; z->c--; goto lab4; lab5: z->c = z->l - m5; - if (!(eq_s_b(z, 2, s_9))) goto lab3; /* literal, line 430 */ + if (!(eq_s_b(z, 2, s_9))) goto lab3; } lab4: z->c = z->l - m_test4; } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 2, s_10); /* <+, line 430 */ + ret = insert_s(z, z->c, z->c, 2, s_10); z->c = saved_c; } if (ret < 0) return ret; @@ -1930,15 +1930,15 @@ static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwa goto lab2; lab3: z->c = z->l - m3; - { int m_test6 = z->l - z->c; /* test, line 432 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab6; /* goto */ /* grouping vowel, line 432 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 432 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab8; /* literal, line 432 */ + { int m_test6 = z->l - z->c; + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab6; + { int m7 = z->l - z->c; (void)m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab8; z->c--; goto lab7; lab8: z->c = z->l - m7; - if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab6; /* literal, line 432 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab6; z->c--; } lab7: @@ -1946,7 +1946,7 @@ static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwa } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_11); /* <+, line 432 */ + ret = insert_s(z, z->c, z->c, 1, s_11); z->c = saved_c; } if (ret < 0) return ret; @@ -1954,15 +1954,15 @@ static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwa goto lab2; lab6: z->c = z->l - m3; - { int m_test8 = z->l - z->c; /* test, line 434 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab9; /* goto */ /* grouping vowel, line 434 */ - { int m9 = z->l - z->c; (void)m9; /* or, line 434 */ - if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab11; /* literal, line 434 */ + { int m_test8 = z->l - z->c; + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab9; + { int m9 = z->l - z->c; (void)m9; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab11; z->c--; goto lab10; lab11: z->c = z->l - m9; - if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab9; /* literal, line 434 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab9; z->c--; } lab10: @@ -1970,7 +1970,7 @@ static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwa } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 1, s_12); /* <+, line 434 */ + ret = insert_s(z, z->c, z->c, 1, s_12); z->c = saved_c; } if (ret < 0) return ret; @@ -1978,21 +1978,21 @@ static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwa goto lab2; lab9: z->c = z->l - m3; - { int m_test10 = z->l - z->c; /* test, line 436 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 436 */ - { int m11 = z->l - z->c; (void)m11; /* or, line 436 */ - if (!(eq_s_b(z, 2, s_13))) goto lab13; /* literal, line 436 */ + { int m_test10 = z->l - z->c; + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; + { int m11 = z->l - z->c; (void)m11; + if (!(eq_s_b(z, 2, s_13))) goto lab13; goto lab12; lab13: z->c = z->l - m11; - if (!(eq_s_b(z, 2, s_14))) return 0; /* literal, line 436 */ + if (!(eq_s_b(z, 2, s_14))) return 0; } lab12: z->c = z->l - m_test10; } { int ret; { int saved_c = z->c; - ret = insert_s(z, z->c, z->c, 2, s_15); /* <+, line 436 */ + ret = insert_s(z, z->c, z->c, 2, s_15); z->c = saved_c; } if (ret < 0) return ret; @@ -2002,22 +2002,23 @@ static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwa return 1; } -static int r_is_reserved_word(struct SN_env * z) { /* backwardmode */ - if (!(eq_s_b(z, 2, s_16))) return 0; /* literal, line 440 */ - { int m1 = z->l - z->c; (void)m1; /* try, line 440 */ - if (!(eq_s_b(z, 3, s_17))) { z->c = z->l - m1; goto lab0; } /* literal, line 440 */ +static int r_is_reserved_word(struct SN_env * z) { + if (!(eq_s_b(z, 2, s_16))) return 0; + { int m1 = z->l - z->c; (void)m1; + if (!(eq_s_b(z, 3, s_17))) { z->c = z->l - m1; goto lab0; } lab0: ; } - if (z->c > z->lb) return 0; /* atlimit, line 440 */ + if (z->c > z->lb) return 0; return 1; } -static int r_more_than_one_syllable_word(struct SN_env * z) { /* forwardmode */ - { int c_test1 = z->c; /* test, line 447 */ +static int r_more_than_one_syllable_word(struct SN_env * z) { + { int c_test1 = z->c; { int i = 2; - while(1) { int c2 = z->c; - { /* gopast */ /* grouping vowel, line 447 */ + while(1) { + int c2 = z->c; + { int ret = out_grouping_U(z, g_vowel, 97, 305, 1); if (ret < 0) goto lab0; z->c += ret; @@ -2035,11 +2036,11 @@ static int r_more_than_one_syllable_word(struct SN_env * z) { /* forwardmode */ return 1; } -static int r_postlude(struct SN_env * z) { /* forwardmode */ - z->lb = z->c; z->c = z->l; /* backwards, line 451 */ +static int r_postlude(struct SN_env * z) { + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* not, line 452 */ - { int ret = r_is_reserved_word(z); /* call is_reserved_word, line 452 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_is_reserved_word(z); if (ret == 0) goto lab0; if (ret < 0) return ret; } @@ -2047,14 +2048,14 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ lab0: z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 453 */ - { int ret = r_append_U_to_stems_ending_with_d_or_g(z); /* call append_U_to_stems_ending_with_d_or_g, line 453 */ + { int m2 = z->l - z->c; (void)m2; + { int ret = r_append_U_to_stems_ending_with_d_or_g(z); if (ret < 0) return ret; } z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 454 */ - { int ret = r_post_process_last_consonants(z); /* call post_process_last_consonants, line 454 */ + { int m3 = z->l - z->c; (void)m3; + { int ret = r_post_process_last_consonants(z); if (ret < 0) return ret; } z->c = z->l - m3; @@ -2063,33 +2064,33 @@ static int r_postlude(struct SN_env * z) { /* forwardmode */ return 1; } -extern int turkish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ - { int ret = r_more_than_one_syllable_word(z); /* call more_than_one_syllable_word, line 460 */ +extern int turkish_UTF_8_stem(struct SN_env * z) { + { int ret = r_more_than_one_syllable_word(z); if (ret <= 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 462 */ + z->lb = z->c; z->c = z->l; - { int m1 = z->l - z->c; (void)m1; /* do, line 463 */ - { int ret = r_stem_nominal_verb_suffixes(z); /* call stem_nominal_verb_suffixes, line 463 */ + { int m1 = z->l - z->c; (void)m1; + { int ret = r_stem_nominal_verb_suffixes(z); if (ret < 0) return ret; } z->c = z->l - m1; } - if (!(z->B[0])) return 0; /* Boolean test continue_stemming_noun_suffixes, line 464 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 465 */ - { int ret = r_stem_noun_suffixes(z); /* call stem_noun_suffixes, line 465 */ + if (!(z->I[0])) return 0; + { int m2 = z->l - z->c; (void)m2; + { int ret = r_stem_noun_suffixes(z); if (ret < 0) return ret; } z->c = z->l - m2; } z->c = z->lb; - { int ret = r_postlude(z); /* call postlude, line 468 */ + { int ret = r_postlude(z); if (ret <= 0) return ret; } return 1; } -extern struct SN_env * turkish_UTF_8_create_env(void) { return SN_create_env(0, 0, 1); } +extern struct SN_env * turkish_UTF_8_create_env(void) { return SN_create_env(0, 1); } extern void turkish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_yiddish.c b/src/backend/snowball/libstemmer/stem_UTF_8_yiddish.c new file mode 100644 index 000000000000..c2fc20cd7b6b --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_yiddish.c @@ -0,0 +1,1368 @@ +/* Generated by Snowball 2.1.0 - https://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int yiddish_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_standard_suffix(struct SN_env * z); +static int r_R1plus3(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_prelude(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * yiddish_UTF_8_create_env(void); +extern void yiddish_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[10] = { 0xD7, 0x90, 0xD7, 0x93, 0xD7, 0x95, 0xD7, 0xA8, 0xD7, 0x9B }; +static const symbol s_0_1[8] = { 0xD7, 0x90, 0xD7, 0x94, 0xD7, 0x99, 0xD7, 0xA0 }; +static const symbol s_0_2[8] = { 0xD7, 0x90, 0xD7, 0x94, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_3[8] = { 0xD7, 0x90, 0xD7, 0x94, 0xD7, 0xB2, 0xD7, 0x9E }; +static const symbol s_0_4[6] = { 0xD7, 0x90, 0xD7, 0x95, 0xD7, 0x9E }; +static const symbol s_0_5[12] = { 0xD7, 0x90, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_6[10] = { 0xD7, 0x90, 0xD7, 0x99, 0xD7, 0x91, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_7[4] = { 0xD7, 0x90, 0xD7, 0xA0 }; +static const symbol s_0_8[6] = { 0xD7, 0x90, 0xD7, 0xA0, 0xD7, 0x98 }; +static const symbol s_0_9[14] = { 0xD7, 0x90, 0xD7, 0xA0, 0xD7, 0x98, 0xD7, 0xA7, 0xD7, 0xA2, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_0_10[12] = { 0xD7, 0x90, 0xD7, 0xA0, 0xD7, 0x99, 0xD7, 0x93, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_11[4] = { 0xD7, 0x90, 0xD7, 0xA4 }; +static const symbol s_0_12[8] = { 0xD7, 0x90, 0xD7, 0xA4, 0xD7, 0x99, 0xD7, 0xA8 }; +static const symbol s_0_13[10] = { 0xD7, 0x90, 0xD7, 0xA7, 0xD7, 0xA2, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_0_14[8] = { 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x90, 0xD7, 0xA4 }; +static const symbol s_0_15[8] = { 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x95, 0xD7, 0x9E }; +static const symbol s_0_16[14] = { 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_17[12] = { 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0x91, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_18[8] = { 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0xB1, 0xD7, 0xA1 }; +static const symbol s_0_19[8] = { 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0xB1, 0xD7, 0xA4 }; +static const symbol s_0_20[8] = { 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0xA0 }; +static const symbol s_0_21[8] = { 0xD7, 0x90, 0xD7, 0xB0, 0xD7, 0xA2, 0xD7, 0xA7 }; +static const symbol s_0_22[6] = { 0xD7, 0x90, 0xD7, 0xB1, 0xD7, 0xA1 }; +static const symbol s_0_23[6] = { 0xD7, 0x90, 0xD7, 0xB1, 0xD7, 0xA4 }; +static const symbol s_0_24[6] = { 0xD7, 0x90, 0xD7, 0xB2, 0xD7, 0xA0 }; +static const symbol s_0_25[4] = { 0xD7, 0x91, 0xD7, 0x90 }; +static const symbol s_0_26[4] = { 0xD7, 0x91, 0xD7, 0xB2 }; +static const symbol s_0_27[8] = { 0xD7, 0x93, 0xD7, 0x95, 0xD7, 0xA8, 0xD7, 0x9B }; +static const symbol s_0_28[6] = { 0xD7, 0x93, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_29[6] = { 0xD7, 0x9E, 0xD7, 0x99, 0xD7, 0x98 }; +static const symbol s_0_30[6] = { 0xD7, 0xA0, 0xD7, 0x90, 0xD7, 0x9B }; +static const symbol s_0_31[6] = { 0xD7, 0xA4, 0xD7, 0x90, 0xD7, 0xA8 }; +static const symbol s_0_32[10] = { 0xD7, 0xA4, 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x91, 0xD7, 0xB2 }; +static const symbol s_0_33[10] = { 0xD7, 0xA4, 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0xB1, 0xD7, 0xA1 }; +static const symbol s_0_34[16] = { 0xD7, 0xA4, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x90, 0xD7, 0xA0, 0xD7, 0x93, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_0_35[4] = { 0xD7, 0xA6, 0xD7, 0x95 }; +static const symbol s_0_36[14] = { 0xD7, 0xA6, 0xD7, 0x95, 0xD7, 0x96, 0xD7, 0x90, 0xD7, 0x9E, 0xD7, 0xA2, 0xD7, 0xA0 }; +static const symbol s_0_37[10] = { 0xD7, 0xA6, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0xB1, 0xD7, 0xA4 }; +static const symbol s_0_38[10] = { 0xD7, 0xA6, 0xD7, 0x95, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_0_39[4] = { 0xD7, 0xA6, 0xD7, 0xA2 }; + +static const struct among a_0[40] = +{ +{ 10, s_0_0, -1, 1, 0}, +{ 8, s_0_1, -1, 1, 0}, +{ 8, s_0_2, -1, 1, 0}, +{ 8, s_0_3, -1, 1, 0}, +{ 6, s_0_4, -1, 1, 0}, +{ 12, s_0_5, -1, 1, 0}, +{ 10, s_0_6, -1, 1, 0}, +{ 4, s_0_7, -1, 1, 0}, +{ 6, s_0_8, 7, 1, 0}, +{ 14, s_0_9, 8, 1, 0}, +{ 12, s_0_10, 7, 1, 0}, +{ 4, s_0_11, -1, 1, 0}, +{ 8, s_0_12, 11, 1, 0}, +{ 10, s_0_13, -1, 1, 0}, +{ 8, s_0_14, -1, 1, 0}, +{ 8, s_0_15, -1, 1, 0}, +{ 14, s_0_16, -1, 1, 0}, +{ 12, s_0_17, -1, 1, 0}, +{ 8, s_0_18, -1, 1, 0}, +{ 8, s_0_19, -1, 1, 0}, +{ 8, s_0_20, -1, 1, 0}, +{ 8, s_0_21, -1, 1, 0}, +{ 6, s_0_22, -1, 1, 0}, +{ 6, s_0_23, -1, 1, 0}, +{ 6, s_0_24, -1, 1, 0}, +{ 4, s_0_25, -1, 1, 0}, +{ 4, s_0_26, -1, 1, 0}, +{ 8, s_0_27, -1, 1, 0}, +{ 6, s_0_28, -1, 1, 0}, +{ 6, s_0_29, -1, 1, 0}, +{ 6, s_0_30, -1, 1, 0}, +{ 6, s_0_31, -1, 1, 0}, +{ 10, s_0_32, 31, 1, 0}, +{ 10, s_0_33, 31, 1, 0}, +{ 16, s_0_34, -1, 1, 0}, +{ 4, s_0_35, -1, 1, 0}, +{ 14, s_0_36, 35, 1, 0}, +{ 10, s_0_37, 35, 1, 0}, +{ 10, s_0_38, 35, 1, 0}, +{ 4, s_0_39, -1, 1, 0} +}; + +static const symbol s_1_0[6] = { 0xD7, 0x93, 0xD7, 0x96, 0xD7, 0xA9 }; +static const symbol s_1_1[6] = { 0xD7, 0xA9, 0xD7, 0x98, 0xD7, 0xA8 }; +static const symbol s_1_2[6] = { 0xD7, 0xA9, 0xD7, 0x98, 0xD7, 0xA9 }; +static const symbol s_1_3[6] = { 0xD7, 0xA9, 0xD7, 0xA4, 0xD7, 0xA8 }; + +static const struct among a_1[4] = +{ +{ 6, s_1_0, -1, -1, 0}, +{ 6, s_1_1, -1, -1, 0}, +{ 6, s_1_2, -1, -1, 0}, +{ 6, s_1_3, -1, -1, 0} +}; + +static const symbol s_2_0[6] = { 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_2_1[6] = { 0xD7, 0xA1, 0xD7, 0x98, 0xD7, 0x95 }; +static const symbol s_2_2[2] = { 0xD7, 0x98 }; +static const symbol s_2_3[10] = { 0xD7, 0x91, 0xD7, 0xA8, 0xD7, 0x90, 0xD7, 0x9B, 0xD7, 0x98 }; +static const symbol s_2_4[4] = { 0xD7, 0xA1, 0xD7, 0x98 }; +static const symbol s_2_5[6] = { 0xD7, 0x99, 0xD7, 0xA1, 0xD7, 0x98 }; +static const symbol s_2_6[4] = { 0xD7, 0xA2, 0xD7, 0x98 }; +static const symbol s_2_7[8] = { 0xD7, 0xA9, 0xD7, 0x90, 0xD7, 0xA4, 0xD7, 0x98 }; +static const symbol s_2_8[6] = { 0xD7, 0x94, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_2_9[6] = { 0xD7, 0xA7, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_2_10[8] = { 0xD7, 0x99, 0xD7, 0xA7, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_2_11[6] = { 0xD7, 0x9C, 0xD7, 0xA2, 0xD7, 0x9B }; +static const symbol s_2_12[8] = { 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0xA2, 0xD7, 0x9B }; +static const symbol s_2_13[6] = { 0xD7, 0x99, 0xD7, 0x96, 0xD7, 0x9E }; +static const symbol s_2_14[4] = { 0xD7, 0x99, 0xD7, 0x9E }; +static const symbol s_2_15[4] = { 0xD7, 0xA2, 0xD7, 0x9E }; +static const symbol s_2_16[8] = { 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0x9E }; +static const symbol s_2_17[10] = { 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0x9E }; +static const symbol s_2_18[2] = { 0xD7, 0xA0 }; +static const symbol s_2_19[10] = { 0xD7, 0xA7, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0x91, 0xD7, 0xA0 }; +static const symbol s_2_20[8] = { 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0x91, 0xD7, 0xA0 }; +static const symbol s_2_21[10] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0x91, 0xD7, 0xA0 }; +static const symbol s_2_22[10] = { 0xD7, 0xA9, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0x91, 0xD7, 0xA0 }; +static const symbol s_2_23[8] = { 0xD7, 0x94, 0xD7, 0xB1, 0xD7, 0x91, 0xD7, 0xA0 }; +static const symbol s_2_24[10] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_2_25[10] = { 0xD7, 0x96, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_2_26[12] = { 0xD7, 0xA9, 0xD7, 0x9C, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_2_27[12] = { 0xD7, 0xA6, 0xD7, 0xB0, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_2_28[8] = { 0xD7, 0x91, 0xD7, 0xB1, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_2_29[10] = { 0xD7, 0x91, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x93, 0xD7, 0xA0 }; +static const symbol s_2_30[8] = { 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0x96, 0xD7, 0xA0 }; +static const symbol s_2_31[4] = { 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_32[10] = { 'G', 'E', 0xD7, 0x91, 0xD7, 0x99, 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_33[10] = { 'G', 'E', 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_34[10] = { 'G', 'E', 0xD7, 0x9E, 0xD7, 0x99, 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_35[10] = { 0xD7, 0xA9, 0xD7, 0xA0, 0xD7, 0x99, 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_36[6] = { 0xD7, 0xA1, 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_37[8] = { 0xD7, 0x99, 0xD7, 0xA1, 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_38[6] = { 0xD7, 0xA2, 0xD7, 0x98, 0xD7, 0xA0 }; +static const symbol s_2_39[10] = { 'G', 'E', 0xD7, 0x91, 0xD7, 0x99, 0xD7, 0xA1, 0xD7, 0xA0 }; +static const symbol s_2_40[10] = { 0xD7, 0xA9, 0xD7, 0x9E, 0xD7, 0x99, 0xD7, 0xA1, 0xD7, 0xA0 }; +static const symbol s_2_41[10] = { 'G', 'E', 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0xA1, 0xD7, 0xA0 }; +static const symbol s_2_42[4] = { 0xD7, 0xA2, 0xD7, 0xA0 }; +static const symbol s_2_43[12] = { 0xD7, 0x92, 0xD7, 0x90, 0xD7, 0xA0, 0xD7, 0x92, 0xD7, 0xA2, 0xD7, 0xA0 }; +static const symbol s_2_44[8] = { 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0xA2, 0xD7, 0xA0 }; +static const symbol s_2_45[10] = { 0xD7, 0xA0, 0xD7, 0x95, 0xD7, 0x9E, 0xD7, 0xA2, 0xD7, 0xA0 }; +static const symbol s_2_46[10] = { 0xD7, 0x99, 0xD7, 0x96, 0xD7, 0x9E, 0xD7, 0xA2, 0xD7, 0xA0 }; +static const symbol s_2_47[12] = { 0xD7, 0xA9, 0xD7, 0x98, 0xD7, 0x90, 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0xA0 }; +static const symbol s_2_48[12] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0xA7, 0xD7, 0xA0 }; +static const symbol s_2_49[14] = { 0xD7, 0xA4, 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x9C, 0xD7, 0xB1, 0xD7, 0xA8, 0xD7, 0xA0 }; +static const symbol s_2_50[10] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0xB1, 0xD7, 0xA8, 0xD7, 0xA0 }; +static const symbol s_2_51[10] = { 0xD7, 0xB0, 0xD7, 0x95, 0xD7, 0x98, 0xD7, 0xA9, 0xD7, 0xA0 }; +static const symbol s_2_52[6] = { 0xD7, 0x92, 0xD7, 0xB2, 0xD7, 0xA0 }; +static const symbol s_2_53[2] = { 0xD7, 0xA1 }; +static const symbol s_2_54[4] = { 0xD7, 0x98, 0xD7, 0xA1 }; +static const symbol s_2_55[6] = { 0xD7, 0xA2, 0xD7, 0x98, 0xD7, 0xA1 }; +static const symbol s_2_56[4] = { 0xD7, 0xA0, 0xD7, 0xA1 }; +static const symbol s_2_57[6] = { 0xD7, 0x98, 0xD7, 0xA0, 0xD7, 0xA1 }; +static const symbol s_2_58[6] = { 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA1 }; +static const symbol s_2_59[4] = { 0xD7, 0xA2, 0xD7, 0xA1 }; +static const symbol s_2_60[6] = { 0xD7, 0x99, 0xD7, 0xA2, 0xD7, 0xA1 }; +static const symbol s_2_61[8] = { 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0xA2, 0xD7, 0xA1 }; +static const symbol s_2_62[6] = { 0xD7, 0xA2, 0xD7, 0xA8, 0xD7, 0xA1 }; +static const symbol s_2_63[10] = { 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0xA8, 0xD7, 0xA1 }; +static const symbol s_2_64[2] = { 0xD7, 0xA2 }; +static const symbol s_2_65[4] = { 0xD7, 0x98, 0xD7, 0xA2 }; +static const symbol s_2_66[6] = { 0xD7, 0xA1, 0xD7, 0x98, 0xD7, 0xA2 }; +static const symbol s_2_67[6] = { 0xD7, 0xA2, 0xD7, 0x98, 0xD7, 0xA2 }; +static const symbol s_2_68[4] = { 0xD7, 0x99, 0xD7, 0xA2 }; +static const symbol s_2_69[6] = { 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0xA2 }; +static const symbol s_2_70[6] = { 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA2 }; +static const symbol s_2_71[8] = { 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA2 }; +static const symbol s_2_72[4] = { 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_2_73[6] = { 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_2_74[8] = { 0xD7, 0xA1, 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_2_75[8] = { 0xD7, 0xA2, 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_2_76[8] = { 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_2_77[10] = { 0xD7, 0x98, 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_2_78[4] = { 0xD7, 0x95, 0xD7, 0xAA }; + +static const struct among a_2[79] = +{ +{ 6, s_2_0, -1, 1, 0}, +{ 6, s_2_1, -1, 1, 0}, +{ 2, s_2_2, -1, 1, 0}, +{ 10, s_2_3, 2, 31, 0}, +{ 4, s_2_4, 2, 1, 0}, +{ 6, s_2_5, 4, 33, 0}, +{ 4, s_2_6, 2, 1, 0}, +{ 8, s_2_7, 2, 1, 0}, +{ 6, s_2_8, 2, 1, 0}, +{ 6, s_2_9, 2, 1, 0}, +{ 8, s_2_10, 9, 1, 0}, +{ 6, s_2_11, -1, 1, 0}, +{ 8, s_2_12, 11, 1, 0}, +{ 6, s_2_13, -1, 1, 0}, +{ 4, s_2_14, -1, 1, 0}, +{ 4, s_2_15, -1, 1, 0}, +{ 8, s_2_16, 15, 3, 0}, +{ 10, s_2_17, 16, 4, 0}, +{ 2, s_2_18, -1, 1, 0}, +{ 10, s_2_19, 18, 14, 0}, +{ 8, s_2_20, 18, 15, 0}, +{ 10, s_2_21, 20, 12, 0}, +{ 10, s_2_22, 20, 7, 0}, +{ 8, s_2_23, 18, 27, 0}, +{ 10, s_2_24, 18, 17, 0}, +{ 10, s_2_25, 18, 22, 0}, +{ 12, s_2_26, 18, 25, 0}, +{ 12, s_2_27, 18, 24, 0}, +{ 8, s_2_28, 18, 26, 0}, +{ 10, s_2_29, 18, 20, 0}, +{ 8, s_2_30, 18, 11, 0}, +{ 4, s_2_31, 18, 4, 0}, +{ 10, s_2_32, 31, 9, 0}, +{ 10, s_2_33, 31, 13, 0}, +{ 10, s_2_34, 31, 8, 0}, +{ 10, s_2_35, 31, 19, 0}, +{ 6, s_2_36, 31, 1, 0}, +{ 8, s_2_37, 36, 1, 0}, +{ 6, s_2_38, 31, 1, 0}, +{ 10, s_2_39, 18, 10, 0}, +{ 10, s_2_40, 18, 18, 0}, +{ 10, s_2_41, 18, 16, 0}, +{ 4, s_2_42, 18, 1, 0}, +{ 12, s_2_43, 42, 5, 0}, +{ 8, s_2_44, 42, 1, 0}, +{ 10, s_2_45, 42, 6, 0}, +{ 10, s_2_46, 42, 1, 0}, +{ 12, s_2_47, 42, 29, 0}, +{ 12, s_2_48, 18, 23, 0}, +{ 14, s_2_49, 18, 28, 0}, +{ 10, s_2_50, 18, 30, 0}, +{ 10, s_2_51, 18, 21, 0}, +{ 6, s_2_52, 18, 5, 0}, +{ 2, s_2_53, -1, 1, 0}, +{ 4, s_2_54, 53, 4, 0}, +{ 6, s_2_55, 54, 1, 0}, +{ 4, s_2_56, 53, 1, 0}, +{ 6, s_2_57, 56, 4, 0}, +{ 6, s_2_58, 56, 3, 0}, +{ 4, s_2_59, 53, 1, 0}, +{ 6, s_2_60, 59, 2, 0}, +{ 8, s_2_61, 59, 1, 0}, +{ 6, s_2_62, 53, 1, 0}, +{ 10, s_2_63, 62, 1, 0}, +{ 2, s_2_64, -1, 1, 0}, +{ 4, s_2_65, 64, 4, 0}, +{ 6, s_2_66, 65, 1, 0}, +{ 6, s_2_67, 65, 1, 0}, +{ 4, s_2_68, 64, -1, 0}, +{ 6, s_2_69, 64, 1, 0}, +{ 6, s_2_70, 64, 3, 0}, +{ 8, s_2_71, 70, 4, 0}, +{ 4, s_2_72, -1, 1, 0}, +{ 6, s_2_73, 72, 4, 0}, +{ 8, s_2_74, 73, 1, 0}, +{ 8, s_2_75, 73, 1, 0}, +{ 8, s_2_76, 72, 3, 0}, +{ 10, s_2_77, 76, 4, 0}, +{ 4, s_2_78, -1, 32, 0} +}; + +static const symbol s_3_0[6] = { 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_3_1[8] = { 0xD7, 0xA9, 0xD7, 0x90, 0xD7, 0xA4, 0xD7, 0x98 }; +static const symbol s_3_2[6] = { 0xD7, 0x94, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_3_3[6] = { 0xD7, 0xA7, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_3_4[8] = { 0xD7, 0x99, 0xD7, 0xA7, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_3_5[2] = { 0xD7, 0x9C }; + +static const struct among a_3[6] = +{ +{ 6, s_3_0, -1, 1, 0}, +{ 8, s_3_1, -1, 1, 0}, +{ 6, s_3_2, -1, 1, 0}, +{ 6, s_3_3, -1, 1, 0}, +{ 8, s_3_4, 3, 1, 0}, +{ 2, s_3_5, -1, 2, 0} +}; + +static const symbol s_4_0[4] = { 0xD7, 0x99, 0xD7, 0x92 }; +static const symbol s_4_1[4] = { 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_4_2[6] = { 0xD7, 0x93, 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_4_3[8] = { 0xD7, 0xA0, 0xD7, 0x93, 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_4_4[10] = { 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0x93, 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_4_5[8] = { 0xD7, 0x91, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_4_6[8] = { 0xD7, 0x92, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_4_7[6] = { 0xD7, 0xA0, 0xD7, 0x99, 0xD7, 0xA7 }; +static const symbol s_4_8[4] = { 0xD7, 0x99, 0xD7, 0xA9 }; + +static const struct among a_4[9] = +{ +{ 4, s_4_0, -1, 1, 0}, +{ 4, s_4_1, -1, 1, 0}, +{ 6, s_4_2, 1, 1, 0}, +{ 8, s_4_3, 2, 1, 0}, +{ 10, s_4_4, 3, 1, 0}, +{ 8, s_4_5, 1, -1, 0}, +{ 8, s_4_6, 1, -1, 0}, +{ 6, s_4_7, 1, 1, 0}, +{ 4, s_4_8, -1, 1, 0} +}; + +static const unsigned char g_niked[] = { 255, 155, 6 }; + +static const unsigned char g_vowel[] = { 33, 2, 4, 0, 6 }; + +static const unsigned char g_consonant[] = { 239, 254, 253, 131 }; + +static const symbol s_0[] = { 0xD7, 0x95, 0xD7, 0x95 }; +static const symbol s_1[] = { 0xD6, 0xBC }; +static const symbol s_2[] = { 0xD7, 0xB0 }; +static const symbol s_3[] = { 0xD7, 0x95, 0xD7, 0x99 }; +static const symbol s_4[] = { 0xD6, 0xB4 }; +static const symbol s_5[] = { 0xD7, 0xB1 }; +static const symbol s_6[] = { 0xD7, 0x99, 0xD7, 0x99 }; +static const symbol s_7[] = { 0xD6, 0xB4 }; +static const symbol s_8[] = { 0xD7, 0xB2 }; +static const symbol s_9[] = { 0xD7, 0x9A }; +static const symbol s_10[] = { 0xD7, 0x9B }; +static const symbol s_11[] = { 0xD7, 0x9D }; +static const symbol s_12[] = { 0xD7, 0x9E }; +static const symbol s_13[] = { 0xD7, 0x9F }; +static const symbol s_14[] = { 0xD7, 0xA0 }; +static const symbol s_15[] = { 0xD7, 0xA3 }; +static const symbol s_16[] = { 0xD7, 0xA4 }; +static const symbol s_17[] = { 0xD7, 0xA5 }; +static const symbol s_18[] = { 0xD7, 0xA6 }; +static const symbol s_19[] = { 0xD7, 0x92, 0xD7, 0xA2, 0xD7, 0x9C, 0xD7, 0x98 }; +static const symbol s_20[] = { 0xD7, 0x92, 0xD7, 0xA2, 0xD7, 0x91, 0xD7, 0xA0 }; +static const symbol s_21[] = { 0xD7, 0x92, 0xD7, 0xA2 }; +static const symbol s_22[] = { 'G', 'E' }; +static const symbol s_23[] = { 0xD7, 0xA6, 0xD7, 0x95, 0xD7, 0x92, 0xD7, 0xA0 }; +static const symbol s_24[] = { 0xD7, 0xA6, 0xD7, 0x95, 0xD7, 0xA7, 0xD7, 0x98 }; +static const symbol s_25[] = { 0xD7, 0xA6, 0xD7, 0x95, 0xD7, 0xA7, 0xD7, 0xA0 }; +static const symbol s_26[] = { 0xD7, 0x92, 0xD7, 0xA2, 0xD7, 0x91, 0xD7, 0xA0 }; +static const symbol s_27[] = { 0xD7, 0x92, 0xD7, 0xA2 }; +static const symbol s_28[] = { 'G', 'E' }; +static const symbol s_29[] = { 0xD7, 0xA6, 0xD7, 0x95 }; +static const symbol s_30[] = { 'T', 'S', 'U' }; +static const symbol s_31[] = { 0xD7, 0x99, 0xD7, 0xA2 }; +static const symbol s_32[] = { 0xD7, 0x92, 0xD7, 0x90, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_33[] = { 0xD7, 0x92, 0xD7, 0xB2 }; +static const symbol s_34[] = { 0xD7, 0xA0, 0xD7, 0x95, 0xD7, 0x9E }; +static const symbol s_35[] = { 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0x9E }; +static const symbol s_36[] = { 0xD7, 0x9E, 0xD7, 0x99, 0xD7, 0x98 }; +static const symbol s_37[] = { 0xD7, 0x9E, 0xD7, 0xB2, 0xD7, 0x93 }; +static const symbol s_38[] = { 0xD7, 0x91, 0xD7, 0x99, 0xD7, 0x98 }; +static const symbol s_39[] = { 0xD7, 0x91, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_40[] = { 0xD7, 0x91, 0xD7, 0x99, 0xD7, 0xA1 }; +static const symbol s_41[] = { 0xD7, 0x91, 0xD7, 0xB2, 0xD7, 0xA1 }; +static const symbol s_42[] = { 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0x96 }; +static const symbol s_43[] = { 0xD7, 0xB0, 0xD7, 0xB2, 0xD7, 0x96 }; +static const symbol s_44[] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0x91 }; +static const symbol s_45[] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_46[] = { 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0x98 }; +static const symbol s_47[] = { 0xD7, 0x9C, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_48[] = { 0xD7, 0xA7, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0x91 }; +static const symbol s_49[] = { 0xD7, 0xA7, 0xD7, 0x9C, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_50[] = { 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0x91 }; +static const symbol s_51[] = { 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_52[] = { 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0xA1 }; +static const symbol s_53[] = { 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0xA1 }; +static const symbol s_54[] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0x92 }; +static const symbol s_55[] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0xB2, 0xD7, 0x92 }; +static const symbol s_56[] = { 0xD7, 0xA9, 0xD7, 0x9E, 0xD7, 0x99, 0xD7, 0xA1 }; +static const symbol s_57[] = { 0xD7, 0xA9, 0xD7, 0x9E, 0xD7, 0xB2, 0xD7, 0xA1 }; +static const symbol s_58[] = { 0xD7, 0xA9, 0xD7, 0xA0, 0xD7, 0x99, 0xD7, 0x98 }; +static const symbol s_59[] = { 0xD7, 0xA9, 0xD7, 0xA0, 0xD7, 0xB2, 0xD7, 0x93 }; +static const symbol s_60[] = { 0xD7, 0xA9, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0x91 }; +static const symbol s_61[] = { 0xD7, 0xA9, 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_62[] = { 0xD7, 0x91, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x93 }; +static const symbol s_63[] = { 0xD7, 0x91, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x93 }; +static const symbol s_64[] = { 0xD7, 0xB0, 0xD7, 0x95, 0xD7, 0x98, 0xD7, 0xA9 }; +static const symbol s_65[] = { 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0x98, 0xD7, 0xA9 }; +static const symbol s_66[] = { 0xD7, 0x96, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_67[] = { 0xD7, 0x96, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_68[] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0xA7 }; +static const symbol s_69[] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0xA7 }; +static const symbol s_70[] = { 0xD7, 0xA6, 0xD7, 0xB0, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_71[] = { 0xD7, 0xA6, 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_72[] = { 0xD7, 0xA9, 0xD7, 0x9C, 0xD7, 0x95, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_73[] = { 0xD7, 0xA9, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_74[] = { 0xD7, 0x91, 0xD7, 0xB1, 0xD7, 0x92 }; +static const symbol s_75[] = { 0xD7, 0x91, 0xD7, 0xB2, 0xD7, 0x92 }; +static const symbol s_76[] = { 0xD7, 0x94, 0xD7, 0xB1, 0xD7, 0x91 }; +static const symbol s_77[] = { 0xD7, 0x94, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_78[] = { 0xD7, 0xA4, 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x9C, 0xD7, 0xB1, 0xD7, 0xA8 }; +static const symbol s_79[] = { 0xD7, 0xA4, 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0xA8 }; +static const symbol s_80[] = { 0xD7, 0xA9, 0xD7, 0x98, 0xD7, 0x90, 0xD7, 0xA0 }; +static const symbol s_81[] = { 0xD7, 0xA9, 0xD7, 0x98, 0xD7, 0xB2 }; +static const symbol s_82[] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0xB1, 0xD7, 0xA8 }; +static const symbol s_83[] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_84[] = { 0xD7, 0x98 }; +static const symbol s_85[] = { 0xD7, 0x91, 0xD7, 0xA8, 0xD7, 0x90, 0xD7, 0x9B }; +static const symbol s_86[] = { 0xD7, 0x92, 0xD7, 0xA2 }; +static const symbol s_87[] = { 0xD7, 0x91, 0xD7, 0xA8, 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_88[] = { 0xD7, 0x92, 0xD7, 0xB2 }; +static const symbol s_89[] = { 0xD7, 0xA0, 0xD7, 0xA2, 0xD7, 0x9E }; +static const symbol s_90[] = { 0xD7, 0xA9, 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_91[] = { 0xD7, 0x9E, 0xD7, 0xB2, 0xD7, 0x93 }; +static const symbol s_92[] = { 0xD7, 0x91, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_93[] = { 0xD7, 0x91, 0xD7, 0xB2, 0xD7, 0xA1 }; +static const symbol s_94[] = { 0xD7, 0xB0, 0xD7, 0xB2, 0xD7, 0x96 }; +static const symbol s_95[] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_96[] = { 0xD7, 0x9C, 0xD7, 0xB2, 0xD7, 0x98 }; +static const symbol s_97[] = { 0xD7, 0xA7, 0xD7, 0x9C, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_98[] = { 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_99[] = { 0xD7, 0xA8, 0xD7, 0xB2, 0xD7, 0xA1 }; +static const symbol s_100[] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0xB2, 0xD7, 0x92 }; +static const symbol s_101[] = { 0xD7, 0xA9, 0xD7, 0x9E, 0xD7, 0xB2, 0xD7, 0xA1 }; +static const symbol s_102[] = { 0xD7, 0xA9, 0xD7, 0xA0, 0xD7, 0xB2, 0xD7, 0x93 }; +static const symbol s_103[] = { 0xD7, 0x91, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x93 }; +static const symbol s_104[] = { 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0x98, 0xD7, 0xA9 }; +static const symbol s_105[] = { 0xD7, 0x96, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_106[] = { 0xD7, 0x98, 0xD7, 0xA8, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0xA7 }; +static const symbol s_107[] = { 0xD7, 0xA6, 0xD7, 0xB0, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_108[] = { 0xD7, 0xA9, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_109[] = { 0xD7, 0x91, 0xD7, 0xB2, 0xD7, 0x92 }; +static const symbol s_110[] = { 0xD7, 0x94, 0xD7, 0xB2, 0xD7, 0x91 }; +static const symbol s_111[] = { 0xD7, 0xA4, 0xD7, 0x90, 0xD7, 0xA8, 0xD7, 0x9C, 0xD7, 0x99, 0xD7, 0xA8 }; +static const symbol s_112[] = { 0xD7, 0xA9, 0xD7, 0x98, 0xD7, 0xB2 }; +static const symbol s_113[] = { 0xD7, 0xA9, 0xD7, 0xB0, 0xD7, 0xA2, 0xD7, 0xA8 }; +static const symbol s_114[] = { 0xD7, 0x91, 0xD7, 0xA8, 0xD7, 0xA2, 0xD7, 0xA0, 0xD7, 0x92 }; +static const symbol s_115[] = { 0xD7, 0x94 }; +static const symbol s_116[] = { 0xD7, 0x92 }; +static const symbol s_117[] = { 0xD7, 0xA9 }; +static const symbol s_118[] = { 0xD7, 0x99, 0xD7, 0xA1 }; +static const symbol s_119[] = { 'G', 'E' }; +static const symbol s_120[] = { 'T', 'S', 'U' }; + +static int r_prelude(struct SN_env * z) { + { int c1 = z->c; + while(1) { + int c2 = z->c; + while(1) { + int c3 = z->c; + { int c4 = z->c; + z->bra = z->c; + if (!(eq_s(z, 4, s_0))) goto lab4; + z->ket = z->c; + { int c5 = z->c; + if (!(eq_s(z, 2, s_1))) goto lab5; + goto lab4; + lab5: + z->c = c5; + } + { int ret = slice_from_s(z, 2, s_2); + if (ret < 0) return ret; + } + goto lab3; + lab4: + z->c = c4; + z->bra = z->c; + if (!(eq_s(z, 4, s_3))) goto lab6; + z->ket = z->c; + { int c6 = z->c; + if (!(eq_s(z, 2, s_4))) goto lab7; + goto lab6; + lab7: + z->c = c6; + } + { int ret = slice_from_s(z, 2, s_5); + if (ret < 0) return ret; + } + goto lab3; + lab6: + z->c = c4; + z->bra = z->c; + if (!(eq_s(z, 4, s_6))) goto lab8; + z->ket = z->c; + { int c7 = z->c; + if (!(eq_s(z, 2, s_7))) goto lab9; + goto lab8; + lab9: + z->c = c7; + } + { int ret = slice_from_s(z, 2, s_8); + if (ret < 0) return ret; + } + goto lab3; + lab8: + z->c = c4; + z->bra = z->c; + if (!(eq_s(z, 2, s_9))) goto lab10; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_10); + if (ret < 0) return ret; + } + goto lab3; + lab10: + z->c = c4; + z->bra = z->c; + if (!(eq_s(z, 2, s_11))) goto lab11; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_12); + if (ret < 0) return ret; + } + goto lab3; + lab11: + z->c = c4; + z->bra = z->c; + if (!(eq_s(z, 2, s_13))) goto lab12; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_14); + if (ret < 0) return ret; + } + goto lab3; + lab12: + z->c = c4; + z->bra = z->c; + if (!(eq_s(z, 2, s_15))) goto lab13; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_16); + if (ret < 0) return ret; + } + goto lab3; + lab13: + z->c = c4; + z->bra = z->c; + if (!(eq_s(z, 2, s_17))) goto lab2; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_18); + if (ret < 0) return ret; + } + } + lab3: + z->c = c3; + break; + lab2: + z->c = c3; + { int ret = skip_utf8(z->p, z->c, z->l, 1); + if (ret < 0) goto lab1; + z->c = ret; + } + } + continue; + lab1: + z->c = c2; + break; + } + z->c = c1; + } + { int c8 = z->c; + while(1) { + int c9 = z->c; + while(1) { + int c10 = z->c; + z->bra = z->c; + if (in_grouping_U(z, g_niked, 1456, 1474, 0)) goto lab16; + z->ket = z->c; + { int ret = slice_del(z); + if (ret < 0) return ret; + } + z->c = c10; + break; + lab16: + z->c = c10; + { int ret = skip_utf8(z->p, z->c, z->l, 1); + if (ret < 0) goto lab15; + z->c = ret; + } + } + continue; + lab15: + z->c = c9; + break; + } + z->c = c8; + } + return 1; +} + +static int r_mark_regions(struct SN_env * z) { + z->I[1] = z->l; + { int c1 = z->c; + { int c2 = z->c; + { int c_test3 = z->c; + { int c4 = z->c; + if (!(eq_s(z, 8, s_19))) goto lab4; + goto lab3; + lab4: + z->c = c4; + if (!(eq_s(z, 8, s_20))) goto lab2; + } + lab3: + z->c = c_test3; + } + goto lab1; + lab2: + z->c = c2; + z->bra = z->c; + if (!(eq_s(z, 4, s_21))) { z->c = c1; goto lab0; } + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_22); + if (ret < 0) return ret; + } + } + lab1: + lab0: + ; + } + { int c5 = z->c; + if (!(find_among(z, a_0, 40))) { z->c = c5; goto lab5; } + { int c6 = z->c; + { int c_test7 = z->c; + { int c8 = z->c; + if (!(eq_s(z, 8, s_23))) goto lab9; + goto lab8; + lab9: + z->c = c8; + if (!(eq_s(z, 8, s_24))) goto lab10; + goto lab8; + lab10: + z->c = c8; + if (!(eq_s(z, 8, s_25))) goto lab7; + } + lab8: + if (z->c < z->l) goto lab7; + z->c = c_test7; + } + goto lab6; + lab7: + z->c = c6; + { int c_test9 = z->c; + if (!(eq_s(z, 8, s_26))) goto lab11; + z->c = c_test9; + } + goto lab6; + lab11: + z->c = c6; + z->bra = z->c; + if (!(eq_s(z, 4, s_27))) goto lab12; + z->ket = z->c; + { int ret = slice_from_s(z, 2, s_28); + if (ret < 0) return ret; + } + goto lab6; + lab12: + z->c = c6; + z->bra = z->c; + if (!(eq_s(z, 4, s_29))) { z->c = c5; goto lab5; } + z->ket = z->c; + { int ret = slice_from_s(z, 3, s_30); + if (ret < 0) return ret; + } + } + lab6: + lab5: + ; + } + { int c_test10 = z->c; + { int ret = skip_utf8(z->p, z->c, z->l, 3); + if (ret < 0) return 0; + z->c = ret; + } + z->I[0] = z->c; + z->c = c_test10; + } + { int c11 = z->c; + if (z->c + 5 >= z->l || (z->p[z->c + 5] != 169 && z->p[z->c + 5] != 168)) { z->c = c11; goto lab13; } + if (!(find_among(z, a_1, 4))) { z->c = c11; goto lab13; } + lab13: + ; + } + { int c12 = z->c; + if (in_grouping_U(z, g_consonant, 1489, 1520, 0)) goto lab14; + if (in_grouping_U(z, g_consonant, 1489, 1520, 0)) goto lab14; + if (in_grouping_U(z, g_consonant, 1489, 1520, 0)) goto lab14; + z->I[1] = z->c; + return 0; + lab14: + z->c = c12; + } + if (out_grouping_U(z, g_vowel, 1488, 1522, 1) < 0) return 0; + while(1) { + if (in_grouping_U(z, g_vowel, 1488, 1522, 0)) goto lab15; + continue; + lab15: + break; + } + z->I[1] = z->c; + + if (!(z->I[1] < z->I[0])) goto lab16; + z->I[1] = z->I[0]; +lab16: + return 1; +} + +static int r_R1(struct SN_env * z) { + if (!(z->I[1] <= z->c)) return 0; + return 1; +} + +static int r_R1plus3(struct SN_env * z) { + if (!(z->I[1] <= (z->c + 6))) return 0; + return 1; +} + +static int r_standard_suffix(struct SN_env * z) { + int among_var; + { int m1 = z->l - z->c; (void)m1; + z->ket = z->c; + among_var = find_among_b(z, a_2, 79); + if (!(among_var)) goto lab0; + z->bra = z->c; + switch (among_var) { + case 1: + { int ret = r_R1(z); + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + { int ret = slice_del(z); + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R1(z); + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + { int ret = slice_from_s(z, 4, s_31); + if (ret < 0) return ret; + } + break; + case 3: + { int ret = r_R1(z); + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + { int ret = slice_del(z); + if (ret < 0) return ret; + } + { int m2 = z->l - z->c; (void)m2; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_32))) goto lab1; + z->bra = z->c; + { int ret = slice_from_s(z, 4, s_33); + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m2; + } + { int m3 = z->l - z->c; (void)m3; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_34))) goto lab2; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_35); + if (ret < 0) return ret; + } + goto lab0; + lab2: + z->c = z->l - m3; + } + { int m4 = z->l - z->c; (void)m4; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_36))) goto lab3; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_37); + if (ret < 0) return ret; + } + goto lab0; + lab3: + z->c = z->l - m4; + } + { int m5 = z->l - z->c; (void)m5; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_38))) goto lab4; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_39); + if (ret < 0) return ret; + } + goto lab0; + lab4: + z->c = z->l - m5; + } + { int m6 = z->l - z->c; (void)m6; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_40))) goto lab5; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_41); + if (ret < 0) return ret; + } + goto lab0; + lab5: + z->c = z->l - m6; + } + { int m7 = z->l - z->c; (void)m7; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_42))) goto lab6; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_43); + if (ret < 0) return ret; + } + goto lab0; + lab6: + z->c = z->l - m7; + } + { int m8 = z->l - z->c; (void)m8; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_44))) goto lab7; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_45); + if (ret < 0) return ret; + } + goto lab0; + lab7: + z->c = z->l - m8; + } + { int m9 = z->l - z->c; (void)m9; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_46))) goto lab8; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_47); + if (ret < 0) return ret; + } + goto lab0; + lab8: + z->c = z->l - m9; + } + { int m10 = z->l - z->c; (void)m10; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_48))) goto lab9; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_49); + if (ret < 0) return ret; + } + goto lab0; + lab9: + z->c = z->l - m10; + } + { int m11 = z->l - z->c; (void)m11; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_50))) goto lab10; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_51); + if (ret < 0) return ret; + } + goto lab0; + lab10: + z->c = z->l - m11; + } + { int m12 = z->l - z->c; (void)m12; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_52))) goto lab11; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_53); + if (ret < 0) return ret; + } + goto lab0; + lab11: + z->c = z->l - m12; + } + { int m13 = z->l - z->c; (void)m13; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_54))) goto lab12; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_55); + if (ret < 0) return ret; + } + goto lab0; + lab12: + z->c = z->l - m13; + } + { int m14 = z->l - z->c; (void)m14; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_56))) goto lab13; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_57); + if (ret < 0) return ret; + } + goto lab0; + lab13: + z->c = z->l - m14; + } + { int m15 = z->l - z->c; (void)m15; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_58))) goto lab14; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_59); + if (ret < 0) return ret; + } + goto lab0; + lab14: + z->c = z->l - m15; + } + { int m16 = z->l - z->c; (void)m16; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_60))) goto lab15; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_61); + if (ret < 0) return ret; + } + goto lab0; + lab15: + z->c = z->l - m16; + } + { int m17 = z->l - z->c; (void)m17; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_62))) goto lab16; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_63); + if (ret < 0) return ret; + } + goto lab0; + lab16: + z->c = z->l - m17; + } + { int m18 = z->l - z->c; (void)m18; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_64))) goto lab17; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_65); + if (ret < 0) return ret; + } + goto lab0; + lab17: + z->c = z->l - m18; + } + { int m19 = z->l - z->c; (void)m19; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_66))) goto lab18; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_67); + if (ret < 0) return ret; + } + goto lab0; + lab18: + z->c = z->l - m19; + } + { int m20 = z->l - z->c; (void)m20; + z->ket = z->c; + if (!(eq_s_b(z, 10, s_68))) goto lab19; + z->bra = z->c; + { int ret = slice_from_s(z, 10, s_69); + if (ret < 0) return ret; + } + goto lab0; + lab19: + z->c = z->l - m20; + } + { int m21 = z->l - z->c; (void)m21; + z->ket = z->c; + if (!(eq_s_b(z, 10, s_70))) goto lab20; + z->bra = z->c; + { int ret = slice_from_s(z, 10, s_71); + if (ret < 0) return ret; + } + goto lab0; + lab20: + z->c = z->l - m21; + } + { int m22 = z->l - z->c; (void)m22; + z->ket = z->c; + if (!(eq_s_b(z, 10, s_72))) goto lab21; + z->bra = z->c; + { int ret = slice_from_s(z, 10, s_73); + if (ret < 0) return ret; + } + goto lab0; + lab21: + z->c = z->l - m22; + } + { int m23 = z->l - z->c; (void)m23; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_74))) goto lab22; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_75); + if (ret < 0) return ret; + } + goto lab0; + lab22: + z->c = z->l - m23; + } + { int m24 = z->l - z->c; (void)m24; + z->ket = z->c; + if (!(eq_s_b(z, 6, s_76))) goto lab23; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_77); + if (ret < 0) return ret; + } + goto lab0; + lab23: + z->c = z->l - m24; + } + { int m25 = z->l - z->c; (void)m25; + z->ket = z->c; + if (!(eq_s_b(z, 12, s_78))) goto lab24; + z->bra = z->c; + { int ret = slice_from_s(z, 12, s_79); + if (ret < 0) return ret; + } + goto lab0; + lab24: + z->c = z->l - m25; + } + { int m26 = z->l - z->c; (void)m26; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_80))) goto lab25; + z->bra = z->c; + { int ret = slice_from_s(z, 6, s_81); + if (ret < 0) return ret; + } + goto lab0; + lab25: + z->c = z->l - m26; + } + { int m27 = z->l - z->c; (void)m27; + z->ket = z->c; + if (!(eq_s_b(z, 8, s_82))) goto lab26; + z->bra = z->c; + { int ret = slice_from_s(z, 8, s_83); + if (ret < 0) return ret; + } + goto lab0; + lab26: + z->c = z->l - m27; + } + break; + case 4: + { int m28 = z->l - z->c; (void)m28; + { int ret = r_R1(z); + if (ret == 0) goto lab28; + if (ret < 0) return ret; + } + { int ret = slice_del(z); + if (ret < 0) return ret; + } + goto lab27; + lab28: + z->c = z->l - m28; + { int ret = slice_from_s(z, 2, s_84); + if (ret < 0) return ret; + } + } + lab27: + z->ket = z->c; + if (!(eq_s_b(z, 8, s_85))) goto lab0; + { int m29 = z->l - z->c; (void)m29; + if (!(eq_s_b(z, 4, s_86))) { z->c = z->l - m29; goto lab29; } + lab29: + ; + } + z->bra = z->c; + { int ret = slice_from_s(z, 10, s_87); + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 4, s_88); + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 6, s_89); + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 8, s_90); + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 6, s_91); + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 6, s_92); + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 6, s_93); + if (ret < 0) return ret; + } + break; + case 11: + { int ret = slice_from_s(z, 6, s_94); + if (ret < 0) return ret; + } + break; + case 12: + { int ret = slice_from_s(z, 8, s_95); + if (ret < 0) return ret; + } + break; + case 13: + { int ret = slice_from_s(z, 6, s_96); + if (ret < 0) return ret; + } + break; + case 14: + { int ret = slice_from_s(z, 8, s_97); + if (ret < 0) return ret; + } + break; + case 15: + { int ret = slice_from_s(z, 6, s_98); + if (ret < 0) return ret; + } + break; + case 16: + { int ret = slice_from_s(z, 6, s_99); + if (ret < 0) return ret; + } + break; + case 17: + { int ret = slice_from_s(z, 8, s_100); + if (ret < 0) return ret; + } + break; + case 18: + { int ret = slice_from_s(z, 8, s_101); + if (ret < 0) return ret; + } + break; + case 19: + { int ret = slice_from_s(z, 8, s_102); + if (ret < 0) return ret; + } + break; + case 20: + { int ret = slice_from_s(z, 8, s_103); + if (ret < 0) return ret; + } + break; + case 21: + { int ret = slice_from_s(z, 8, s_104); + if (ret < 0) return ret; + } + break; + case 22: + { int ret = slice_from_s(z, 8, s_105); + if (ret < 0) return ret; + } + break; + case 23: + { int ret = slice_from_s(z, 10, s_106); + if (ret < 0) return ret; + } + break; + case 24: + { int ret = slice_from_s(z, 10, s_107); + if (ret < 0) return ret; + } + break; + case 25: + { int ret = slice_from_s(z, 10, s_108); + if (ret < 0) return ret; + } + break; + case 26: + { int ret = slice_from_s(z, 6, s_109); + if (ret < 0) return ret; + } + break; + case 27: + { int ret = slice_from_s(z, 6, s_110); + if (ret < 0) return ret; + } + break; + case 28: + { int ret = slice_from_s(z, 12, s_111); + if (ret < 0) return ret; + } + break; + case 29: + { int ret = slice_from_s(z, 6, s_112); + if (ret < 0) return ret; + } + break; + case 30: + { int ret = slice_from_s(z, 8, s_113); + if (ret < 0) return ret; + } + break; + case 31: + { int ret = slice_from_s(z, 10, s_114); + if (ret < 0) return ret; + } + break; + case 32: + { int ret = r_R1(z); + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + { int ret = slice_from_s(z, 2, s_115); + if (ret < 0) return ret; + } + break; + case 33: + { int m30 = z->l - z->c; (void)m30; + { int m31 = z->l - z->c; (void)m31; + if (!(eq_s_b(z, 2, s_116))) goto lab33; + goto lab32; + lab33: + z->c = z->l - m31; + if (!(eq_s_b(z, 2, s_117))) goto lab31; + } + lab32: + { int m32 = z->l - z->c; (void)m32; + { int ret = r_R1plus3(z); + if (ret == 0) { z->c = z->l - m32; goto lab34; } + if (ret < 0) return ret; + } + { int ret = slice_from_s(z, 4, s_118); + if (ret < 0) return ret; + } + lab34: + ; + } + goto lab30; + lab31: + z->c = z->l - m30; + { int ret = r_R1(z); + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + { int ret = slice_del(z); + if (ret < 0) return ret; + } + } + lab30: + break; + } + lab0: + z->c = z->l - m1; + } + { int m33 = z->l - z->c; (void)m33; + z->ket = z->c; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((285474816 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab35; + among_var = find_among_b(z, a_3, 6); + if (!(among_var)) goto lab35; + z->bra = z->c; + switch (among_var) { + case 1: + { int ret = r_R1(z); + if (ret == 0) goto lab35; + if (ret < 0) return ret; + } + { int ret = slice_del(z); + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R1(z); + if (ret == 0) goto lab35; + if (ret < 0) return ret; + } + if (in_grouping_b_U(z, g_consonant, 1489, 1520, 0)) goto lab35; + { int ret = slice_del(z); + if (ret < 0) return ret; + } + break; + } + lab35: + z->c = z->l - m33; + } + { int m34 = z->l - z->c; (void)m34; + z->ket = z->c; + among_var = find_among_b(z, a_4, 9); + if (!(among_var)) goto lab36; + z->bra = z->c; + switch (among_var) { + case 1: + { int ret = r_R1(z); + if (ret == 0) goto lab36; + if (ret < 0) return ret; + } + { int ret = slice_del(z); + if (ret < 0) return ret; + } + break; + } + lab36: + z->c = z->l - m34; + } + { int m35 = z->l - z->c; (void)m35; + while(1) { + int m36 = z->l - z->c; (void)m36; + while(1) { + int m37 = z->l - z->c; (void)m37; + z->ket = z->c; + { int m38 = z->l - z->c; (void)m38; + if (!(eq_s_b(z, 2, s_119))) goto lab41; + goto lab40; + lab41: + z->c = z->l - m38; + if (!(eq_s_b(z, 3, s_120))) goto lab39; + } + lab40: + z->bra = z->c; + { int ret = slice_del(z); + if (ret < 0) return ret; + } + z->c = z->l - m37; + break; + lab39: + z->c = z->l - m37; + { int ret = skip_b_utf8(z->p, z->c, z->lb, 1); + if (ret < 0) goto lab38; + z->c = ret; + } + } + continue; + lab38: + z->c = z->l - m36; + break; + } + z->c = z->l - m35; + } + return 1; +} + +extern int yiddish_UTF_8_stem(struct SN_env * z) { + + { int ret = r_prelude(z); + if (ret < 0) return ret; + } + { int c1 = z->c; + { int ret = r_mark_regions(z); + if (ret < 0) return ret; + } + z->c = c1; + } + z->lb = z->c; z->c = z->l; + + + { int ret = r_standard_suffix(z); + if (ret < 0) return ret; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * yiddish_UTF_8_create_env(void) { return SN_create_env(0, 2); } + +extern void yiddish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/utilities.c b/src/backend/snowball/libstemmer/utilities.c index 681bca09c2f6..1ecd2410fe7e 100644 --- a/src/backend/snowball/libstemmer/utilities.c +++ b/src/backend/snowball/libstemmer/utilities.c @@ -18,38 +18,48 @@ extern void lose_s(symbol * p) { } /* - new_p = skip_utf8(p, c, lb, l, n); skips n characters forwards from p + c - if n +ve, or n characters backwards from p + c - 1 if n -ve. new_p is the new - position, or -1 on failure. + new_p = skip_utf8(p, c, l, n); skips n characters forwards from p + c. + new_p is the new position, or -1 on failure. -- used to implement hop and next in the utf8 case. */ -extern int skip_utf8(const symbol * p, int c, int lb, int l, int n) { +extern int skip_utf8(const symbol * p, int c, int limit, int n) { int b; - if (n >= 0) { - for (; n > 0; n--) { - if (c >= l) return -1; - b = p[c++]; - if (b >= 0xC0) { /* 1100 0000 */ - while (c < l) { - b = p[c]; - if (b >= 0xC0 || b < 0x80) break; - /* break unless b is 10------ */ - c++; - } + if (n < 0) return -1; + for (; n > 0; n--) { + if (c >= limit) return -1; + b = p[c++]; + if (b >= 0xC0) { /* 1100 0000 */ + while (c < limit) { + b = p[c]; + if (b >= 0xC0 || b < 0x80) break; + /* break unless b is 10------ */ + c++; } } - } else { - for (; n < 0; n++) { - if (c <= lb) return -1; - b = p[--c]; - if (b >= 0x80) { /* 1000 0000 */ - while (c > lb) { - b = p[c]; - if (b >= 0xC0) break; /* 1100 0000 */ - c--; - } + } + return c; +} + +/* + new_p = skip_b_utf8(p, c, lb, n); skips n characters backwards from p + c - 1 + new_p is the new position, or -1 on failure. + + -- used to implement hop and next in the utf8 case. +*/ + +extern int skip_b_utf8(const symbol * p, int c, int limit, int n) { + int b; + if (n < 0) return -1; + for (; n > 0; n--) { + if (c <= limit) return -1; + b = p[--c]; + if (b >= 0x80) { /* 1000 0000 */ + while (c > limit) { + b = p[c]; + if (b >= 0xC0) break; /* 1100 0000 */ + c--; } } } @@ -76,7 +86,7 @@ static int get_utf8(const symbol * p, int c, int l, int * slot) { *slot = (b0 & 0xF) << 12 | b1 << 6 | b2; return 3; } - *slot = (b0 & 0xE) << 18 | b1 << 12 | b2 << 6 | (p[c] & 0x3F); + *slot = (b0 & 0x7) << 18 | b1 << 12 | b2 << 6 | (p[c] & 0x3F); return 4; } @@ -100,7 +110,7 @@ static int get_b_utf8(const symbol * p, int c, int lb, int * slot) { *slot = (b & 0xF) << 12 | a; return 3; } - *slot = (p[--c] & 0xE) << 18 | (b & 0x3F) << 12 | a; + *slot = (p[--c] & 0x7) << 18 | (b & 0x3F) << 12 | a; return 4; } @@ -226,7 +236,7 @@ extern int find_among(struct SN_env * z, const struct among * v, int v_size) { int j = v_size; int c = z->c; int l = z->l; - symbol * q = z->p + c; + const symbol * q = z->p + c; const struct among * w; @@ -291,7 +301,7 @@ extern int find_among_b(struct SN_env * z, const struct among * v, int v_size) { int j = v_size; int c = z->c; int lb = z->lb; - symbol * q = z->p + c - 1; + const symbol * q = z->p + c - 1; const struct among * w; diff --git a/src/backend/snowball/snowball.sql.in b/src/backend/snowball/snowball.sql.in index 0d47facd0020..3397fb1e02c3 100644 --- a/src/backend/snowball/snowball.sql.in +++ b/src/backend/snowball/snowball.sql.in @@ -1,7 +1,7 @@ /* * text search configuration for _LANGNAME_ language * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * src/backend/snowball/snowball.sql.in * diff --git a/src/backend/snowball/snowball_func.sql.in b/src/backend/snowball/snowball_func.sql.in index 8e2063b7330d..cb1eaca4fb5f 100644 --- a/src/backend/snowball/snowball_func.sql.in +++ b/src/backend/snowball/snowball_func.sql.in @@ -1,7 +1,7 @@ /* * Create underlying C functions for Snowball stemmers * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * src/backend/snowball/snowball_func.sql.in * diff --git a/src/backend/statistics/dependencies.c b/src/backend/statistics/dependencies.c index 9cc123dab4b7..b099e204e93a 100644 --- a/src/backend/statistics/dependencies.c +++ b/src/backend/statistics/dependencies.c @@ -3,7 +3,7 @@ * dependencies.c * POSTGRES functional dependencies * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -71,15 +71,15 @@ static void generate_dependencies(DependencyGenerator state); static DependencyGenerator DependencyGenerator_init(int n, int k); static void DependencyGenerator_free(DependencyGenerator state); static AttrNumber *DependencyGenerator_next(DependencyGenerator state); -static double dependency_degree(int numrows, HeapTuple *rows, int k, - AttrNumber *dependency, VacAttrStats **stats, Bitmapset *attrs); +static double dependency_degree(StatsBuildData *data, int k, AttrNumber *dependency); static bool dependency_is_fully_matched(MVDependency *dependency, Bitmapset *attnums); static bool dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum); +static bool dependency_is_compatible_expression(Node *clause, Index relid, + List *statlist, Node **expr); static MVDependency *find_strongest_dependency(MVDependencies **dependencies, - int ndependencies, - Bitmapset *attnums); + int ndependencies, Bitmapset *attnums); static Selectivity clauselist_apply_dependencies(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, @@ -220,16 +220,13 @@ DependencyGenerator_next(DependencyGenerator state) * the last one. */ static double -dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, - VacAttrStats **stats, Bitmapset *attrs) +dependency_degree(StatsBuildData *data, int k, AttrNumber *dependency) { int i, nitems; MultiSortSupport mss; SortItem *items; - AttrNumber *attnums; AttrNumber *attnums_dep; - int numattrs; /* counters valid within a group */ int group_size = 0; @@ -245,15 +242,12 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, mss = multi_sort_init(k); /* - * Transform the attrs from bitmap to an array to make accessing the i-th - * member easier, and then construct a filtered version with only attnums - * referenced by the dependency we validate. + * Translate the array of indexes to regular attnums for the dependency + * (we will need this to identify the columns in StatsBuildData). */ - attnums = build_attnums_array(attrs, &numattrs); - attnums_dep = (AttrNumber *) palloc(k * sizeof(AttrNumber)); for (i = 0; i < k; i++) - attnums_dep[i] = attnums[dependency[i]]; + attnums_dep[i] = data->attnums[dependency[i]]; /* * Verify the dependency (a,b,...)->z, using a rather simple algorithm: @@ -271,7 +265,7 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, /* prepare the sort function for the dimensions */ for (i = 0; i < k; i++) { - VacAttrStats *colstat = stats[dependency[i]]; + VacAttrStats *colstat = data->stats[dependency[i]]; TypeCacheEntry *type; type = lookup_type_cache(colstat->attrtypid, TYPECACHE_LT_OPR); @@ -290,8 +284,7 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, * descriptor. For now that assumption holds, but it might change in the * future for example if we support statistics on multiple tables. */ - items = build_sorted_items(numrows, &nitems, rows, stats[0]->tupDesc, - mss, k, attnums_dep); + items = build_sorted_items(data, &nitems, mss, k, attnums_dep); /* * Walk through the sorted array, split it into rows according to the @@ -337,11 +330,10 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, pfree(items); pfree(mss); - pfree(attnums); pfree(attnums_dep); /* Compute the 'degree of validity' as (supporting/total). */ - return (n_supporting_rows * 1.0 / numrows); + return (n_supporting_rows * 1.0 / data->numrows); } /* @@ -361,23 +353,15 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, * (c) -> b */ MVDependencies * -statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, - VacAttrStats **stats) +statext_dependencies_build(StatsBuildData *data) { int i, k; - int numattrs; - AttrNumber *attnums; /* result */ MVDependencies *dependencies = NULL; - /* - * Transform the bms into an array, to make accessing i-th member easier. - */ - attnums = build_attnums_array(attrs, &numattrs); - - Assert(numattrs >= 2); + Assert(data->nattnums >= 2); /* * We'll try build functional dependencies starting from the smallest ones @@ -385,12 +369,12 @@ statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, * included in the statistics object. We start from the smallest ones * because we want to be able to skip already implied ones. */ - for (k = 2; k <= numattrs; k++) + for (k = 2; k <= data->nattnums; k++) { AttrNumber *dependency; /* array with k elements */ /* prepare a DependencyGenerator of variation */ - DependencyGenerator DependencyGenerator = DependencyGenerator_init(numattrs, k); + DependencyGenerator DependencyGenerator = DependencyGenerator_init(data->nattnums, k); /* generate all possible variations of k values (out of n) */ while ((dependency = DependencyGenerator_next(DependencyGenerator))) @@ -399,7 +383,7 @@ statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, MVDependency *d; /* compute how valid the dependency seems */ - degree = dependency_degree(numrows, rows, k, dependency, stats, attrs); + degree = dependency_degree(data, k, dependency); /* * if the dependency seems entirely invalid, don't store it @@ -414,7 +398,7 @@ statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, d->degree = degree; d->nattributes = k; for (i = 0; i < k; i++) - d->attributes[i] = attnums[dependency[i]]; + d->attributes[i] = data->attnums[dependency[i]]; /* initialize the list of dependencies */ if (dependencies == NULL) @@ -640,7 +624,7 @@ statext_dependencies_load(Oid mvoid) Anum_pg_statistic_ext_data_stxddependencies, &isnull); if (isnull) elog(ERROR, - "requested statistic kind \"%c\" is not yet built for statistics object %u", + "requested statistics kind \"%c\" is not yet built for statistics object %u", STATS_EXT_DEPENDENCIES, mvoid); result = statext_dependencies_deserialize(DatumGetByteaPP(deps)); @@ -748,6 +732,7 @@ static bool dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) { Var *var; + Node *clause_expr; if (IsA(clause, RestrictInfo)) { @@ -775,9 +760,9 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) /* Make sure non-selected argument is a pseudoconstant. */ if (is_pseudo_constant_clause(lsecond(expr->args))) - var = linitial(expr->args); + clause_expr = linitial(expr->args); else if (is_pseudo_constant_clause(linitial(expr->args))) - var = lsecond(expr->args); + clause_expr = lsecond(expr->args); else return false; @@ -806,8 +791,8 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) /* * Reject ALL() variant, we only care about ANY/IN. * - * FIXME Maybe we should check if all the values are the same, and - * allow ALL in that case? Doesn't seem very practical, though. + * XXX Maybe we should check if all the values are the same, and allow + * ALL in that case? Doesn't seem very practical, though. */ if (!expr->useOr) return false; @@ -823,7 +808,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) if (!is_pseudo_constant_clause(lsecond(expr->args))) return false; - var = linitial(expr->args); + clause_expr = linitial(expr->args); /* * If it's not an "=" operator, just ignore the clause, as it's not @@ -839,13 +824,13 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) } else if (is_orclause(clause)) { - BoolExpr *expr = (BoolExpr *) clause; + BoolExpr *bool_expr = (BoolExpr *) clause; ListCell *lc; /* start with no attribute number */ *attnum = InvalidAttrNumber; - foreach(lc, expr->args) + foreach(lc, bool_expr->args) { AttrNumber clause_attnum; @@ -860,6 +845,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) if (*attnum == InvalidAttrNumber) *attnum = clause_attnum; + /* ensure all the variables are the same (same attnum) */ if (*attnum != clause_attnum) return false; } @@ -873,7 +859,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) * "NOT x" can be interpreted as "x = false", so get the argument and * proceed with seeing if it's a suitable Var. */ - var = (Var *) get_notclausearg(clause); + clause_expr = (Node *) get_notclausearg(clause); } else { @@ -881,20 +867,23 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) * A boolean expression "x" can be interpreted as "x = true", so * proceed with seeing if it's a suitable Var. */ - var = (Var *) clause; + clause_expr = (Node *) clause; } /* * We may ignore any RelabelType node above the operand. (There won't be * more than one, since eval_const_expressions has been applied already.) */ - if (IsA(var, RelabelType)) - var = (Var *) ((RelabelType *) var)->arg; + if (IsA(clause_expr, RelabelType)) + clause_expr = (Node *) ((RelabelType *) clause_expr)->arg; /* We only support plain Vars for now */ - if (!IsA(var, Var)) + if (!IsA(clause_expr, Var)) return false; + /* OK, we know we have a Var */ + var = (Var *) clause_expr; + /* Ensure Var is from the correct relation */ if (var->varno != relid) return false; @@ -984,7 +973,7 @@ find_strongest_dependency(MVDependencies **dependencies, int ndependencies, /* * clauselist_apply_dependencies * Apply the specified functional dependencies to a list of clauses and - * return the estimated selecvitity of the clauses that are compatible + * return the estimated selectivity of the clauses that are compatible * with any of the given dependencies. * * This will estimate all not-already-estimated clauses that are compatible @@ -1074,9 +1063,8 @@ clauselist_apply_dependencies(PlannerInfo *root, List *clauses, } } - simple_sel = clauselist_selectivity_simple(root, attr_clauses, varRelid, - jointype, sjinfo, NULL, - false); /* no damping */ + simple_sel = clauselist_selectivity_ext(root, attr_clauses, varRelid, + jointype, sjinfo, false, false); attr_sel[attidx++] = simple_sel; } @@ -1159,6 +1147,212 @@ clauselist_apply_dependencies(PlannerInfo *root, List *clauses, return s1; } +/* + * dependency_is_compatible_expression + * Determines if the expression is compatible with functional dependencies + * + * Similar to dependency_is_compatible_clause, but doesn't enforce that the + * expression is a simple Var. OTOH we check that there's at least one + * statistics object matching the expression. + */ +static bool +dependency_is_compatible_expression(Node *clause, Index relid, List *statlist, Node **expr) +{ + List *vars; + ListCell *lc, + *lc2; + Node *clause_expr; + + if (IsA(clause, RestrictInfo)) + { + RestrictInfo *rinfo = (RestrictInfo *) clause; + + /* Pseudoconstants are not interesting (they couldn't contain a Var) */ + if (rinfo->pseudoconstant) + return false; + + /* Clauses referencing multiple, or no, varnos are incompatible */ + if (bms_membership(rinfo->clause_relids) != BMS_SINGLETON) + return false; + + clause = (Node *) rinfo->clause; + } + + if (is_opclause(clause)) + { + /* If it's an opclause, check for Var = Const or Const = Var. */ + OpExpr *expr = (OpExpr *) clause; + + /* Only expressions with two arguments are candidates. */ + if (list_length(expr->args) != 2) + return false; + + /* Make sure non-selected argument is a pseudoconstant. */ + if (is_pseudo_constant_clause(lsecond(expr->args))) + clause_expr = linitial(expr->args); + else if (is_pseudo_constant_clause(linitial(expr->args))) + clause_expr = lsecond(expr->args); + else + return false; + + /* + * If it's not an "=" operator, just ignore the clause, as it's not + * compatible with functional dependencies. + * + * This uses the function for estimating selectivity, not the operator + * directly (a bit awkward, but well ...). + * + * XXX this is pretty dubious; probably it'd be better to check btree + * or hash opclass membership, so as not to be fooled by custom + * selectivity functions, and to be more consistent with decisions + * elsewhere in the planner. + */ + if (get_oprrest(expr->opno) != F_EQSEL) + return false; + + /* OK to proceed with checking "var" */ + } + else if (IsA(clause, ScalarArrayOpExpr)) + { + /* If it's an scalar array operator, check for Var IN Const. */ + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) clause; + + /* + * Reject ALL() variant, we only care about ANY/IN. + * + * FIXME Maybe we should check if all the values are the same, and + * allow ALL in that case? Doesn't seem very practical, though. + */ + if (!expr->useOr) + return false; + + /* Only expressions with two arguments are candidates. */ + if (list_length(expr->args) != 2) + return false; + + /* + * We know it's always (Var IN Const), so we assume the var is the + * first argument, and pseudoconstant is the second one. + */ + if (!is_pseudo_constant_clause(lsecond(expr->args))) + return false; + + clause_expr = linitial(expr->args); + + /* + * If it's not an "=" operator, just ignore the clause, as it's not + * compatible with functional dependencies. The operator is identified + * simply by looking at which function it uses to estimate + * selectivity. That's a bit strange, but it's what other similar + * places do. + */ + if (get_oprrest(expr->opno) != F_EQSEL) + return false; + + /* OK to proceed with checking "var" */ + } + else if (is_orclause(clause)) + { + BoolExpr *bool_expr = (BoolExpr *) clause; + ListCell *lc; + + /* start with no expression (we'll use the first match) */ + *expr = NULL; + + foreach(lc, bool_expr->args) + { + Node *or_expr = NULL; + + /* + * Had we found incompatible expression in the arguments, treat + * the whole expression as incompatible. + */ + if (!dependency_is_compatible_expression((Node *) lfirst(lc), relid, + statlist, &or_expr)) + return false; + + if (*expr == NULL) + *expr = or_expr; + + /* ensure all the expressions are the same */ + if (!equal(or_expr, *expr)) + return false; + } + + /* the expression is already checked by the recursive call */ + return true; + } + else if (is_notclause(clause)) + { + /* + * "NOT x" can be interpreted as "x = false", so get the argument and + * proceed with seeing if it's a suitable Var. + */ + clause_expr = (Node *) get_notclausearg(clause); + } + else + { + /* + * A boolean expression "x" can be interpreted as "x = true", so + * proceed with seeing if it's a suitable Var. + */ + clause_expr = (Node *) clause; + } + + /* + * We may ignore any RelabelType node above the operand. (There won't be + * more than one, since eval_const_expressions has been applied already.) + */ + if (IsA(clause_expr, RelabelType)) + clause_expr = (Node *) ((RelabelType *) clause_expr)->arg; + + vars = pull_var_clause(clause_expr, 0); + + foreach(lc, vars) + { + Var *var = (Var *) lfirst(lc); + + /* Ensure Var is from the correct relation */ + if (var->varno != relid) + return false; + + /* We also better ensure the Var is from the current level */ + if (var->varlevelsup != 0) + return false; + + /* Also ignore system attributes (we don't allow stats on those) */ + if (!AttrNumberIsForUserDefinedAttr(var->varattno)) + return false; + } + + /* + * Check if we actually have a matching statistics for the expression. + * + * XXX Maybe this is an overkill. We'll eliminate the expressions later. + */ + foreach(lc, statlist) + { + StatisticExtInfo *info = (StatisticExtInfo *) lfirst(lc); + + /* ignore stats without dependencies */ + if (info->kind != STATS_EXT_DEPENDENCIES) + continue; + + foreach(lc2, info->exprs) + { + Node *stat_expr = (Node *) lfirst(lc2); + + if (equal(clause_expr, stat_expr)) + { + *expr = stat_expr; + return true; + } + } + } + + return false; +} + /* * dependencies_clauselist_selectivity * Return the estimated selectivity of (a subset of) the given clauses @@ -1206,17 +1400,11 @@ dependencies_clauselist_selectivity(PlannerInfo *root, MVDependency **dependencies; int ndependencies; int i; - RangeTblEntry *rte = planner_rt_fetch(rel->relid, root); + AttrNumber attnum_offset; - /* - * When dealing with regular inheritance trees, ignore extended stats - * (which were built without data from child rels, and thus do not - * represent them). For partitioned tables data there's no data in the - * non-leaf relations, so we build stats only for the inheritance tree. - * So for partitioned tables we do consider extended stats. - */ - if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE) - return 1.0; + /* unique expressions */ + Node **unique_exprs; + int unique_exprs_cnt; /* check if there's any stats that might be useful for us. */ if (!has_stats_of_kind(rel->statlist, STATS_EXT_DEPENDENCIES)) @@ -1225,6 +1413,15 @@ dependencies_clauselist_selectivity(PlannerInfo *root, list_attnums = (AttrNumber *) palloc(sizeof(AttrNumber) * list_length(clauses)); + /* + * We allocate space as if every clause was a unique expression, although + * that's probably overkill. Some will be simple column references that + * we'll translate to attnums, and there might be duplicates. But it's + * easier and cheaper to just do one allocation than repalloc later. + */ + unique_exprs = (Node **) palloc(sizeof(Node *) * list_length(clauses)); + unique_exprs_cnt = 0; + /* * Pre-process the clauses list to extract the attnums seen in each item. * We need to determine if there's any clauses which will be useful for @@ -1235,31 +1432,129 @@ dependencies_clauselist_selectivity(PlannerInfo *root, * * We also skip clauses that we already estimated using different types of * statistics (we treat them as incompatible). + * + * To handle expressions, we assign them negative attnums, as if it was a + * system attribute (this is fine, as we only allow extended stats on user + * attributes). And then we offset everything by the number of + * expressions, so that we can store the values in a bitmapset. */ listidx = 0; foreach(l, clauses) { Node *clause = (Node *) lfirst(l); AttrNumber attnum; + Node *expr = NULL; - if (!bms_is_member(listidx, *estimatedclauses) && - dependency_is_compatible_clause(clause, rel->relid, &attnum)) + /* ignore clause by default */ + list_attnums[listidx] = InvalidAttrNumber; + + if (!bms_is_member(listidx, *estimatedclauses)) { - list_attnums[listidx] = attnum; - clauses_attnums = bms_add_member(clauses_attnums, attnum); + /* + * If it's a simple column reference, just extract the attnum. If + * it's an expression, assign a negative attnum as if it was a + * system attribute. + */ + if (dependency_is_compatible_clause(clause, rel->relid, &attnum)) + { + list_attnums[listidx] = attnum; + } + else if (dependency_is_compatible_expression(clause, rel->relid, + rel->statlist, + &expr)) + { + /* special attnum assigned to this expression */ + attnum = InvalidAttrNumber; + + Assert(expr != NULL); + + /* If the expression is duplicate, use the same attnum. */ + for (i = 0; i < unique_exprs_cnt; i++) + { + if (equal(unique_exprs[i], expr)) + { + /* negative attribute number to expression */ + attnum = -(i + 1); + break; + } + } + + /* not found in the list, so add it */ + if (attnum == InvalidAttrNumber) + { + unique_exprs[unique_exprs_cnt++] = expr; + + /* after incrementing the value, to get -1, -2, ... */ + attnum = (-unique_exprs_cnt); + } + + /* remember which attnum was assigned to this clause */ + list_attnums[listidx] = attnum; + } } - else - list_attnums[listidx] = InvalidAttrNumber; listidx++; } + Assert(listidx == list_length(clauses)); + + /* + * How much we need to offset the attnums? If there are no expressions, + * then no offset is needed. Otherwise we need to offset enough for the + * lowest value (-unique_exprs_cnt) to become 1. + */ + if (unique_exprs_cnt > 0) + attnum_offset = (unique_exprs_cnt + 1); + else + attnum_offset = 0; + + /* + * Now that we know how many expressions there are, we can offset the + * values just enough to build the bitmapset. + */ + for (i = 0; i < list_length(clauses); i++) + { + AttrNumber attnum; + + /* ignore incompatible or already estimated clauses */ + if (list_attnums[i] == InvalidAttrNumber) + continue; + + /* make sure the attnum is in the expected range */ + Assert(list_attnums[i] >= (-unique_exprs_cnt)); + Assert(list_attnums[i] <= MaxHeapAttributeNumber); + + /* make sure the attnum is positive (valid AttrNumber) */ + attnum = list_attnums[i] + attnum_offset; + + /* + * Either it's a regular attribute, or it's an expression, in which + * case we must not have seen it before (expressions are unique). + * + * XXX Check whether it's a regular attribute has to be done using the + * original attnum, while the second check has to use the value with + * an offset. + */ + Assert(AttrNumberIsForUserDefinedAttr(list_attnums[i]) || + !bms_is_member(attnum, clauses_attnums)); + + /* + * Remember the offset attnum, both for attributes and expressions. + * We'll pass list_attnums to clauselist_apply_dependencies, which + * uses it to identify clauses in a bitmap. We could also pass the + * offset, but this is more convenient. + */ + list_attnums[i] = attnum; + + clauses_attnums = bms_add_member(clauses_attnums, attnum); + } + /* - * If there's not at least two distinct attnums then reject the whole list - * of clauses. We must return 1.0 so the calling function's selectivity is - * unaffected. + * If there's not at least two distinct attnums and expressions, then + * reject the whole list of clauses. We must return 1.0 so the calling + * function's selectivity is unaffected. */ - if (bms_num_members(clauses_attnums) < 2) + if (bms_membership(clauses_attnums) != BMS_MULTIPLE) { bms_free(clauses_attnums); pfree(list_attnums); @@ -1285,26 +1580,203 @@ dependencies_clauselist_selectivity(PlannerInfo *root, foreach(l, rel->statlist) { StatisticExtInfo *stat = (StatisticExtInfo *) lfirst(l); - Bitmapset *matched; - int num_matched; + int nmatched; + int nexprs; + int k; + MVDependencies *deps; /* skip statistics that are not of the correct type */ if (stat->kind != STATS_EXT_DEPENDENCIES) continue; - matched = bms_intersect(clauses_attnums, stat->keys); - num_matched = bms_num_members(matched); - bms_free(matched); + /* + * Count matching attributes - we have to undo the attnum offsets. The + * input attribute numbers are not offset (expressions are not + * included in stat->keys, so it's not necessary). But we need to + * offset it before checking against clauses_attnums. + */ + nmatched = 0; + k = -1; + while ((k = bms_next_member(stat->keys, k)) >= 0) + { + AttrNumber attnum = (AttrNumber) k; + + /* skip expressions */ + if (!AttrNumberIsForUserDefinedAttr(attnum)) + continue; + + /* apply the same offset as above */ + attnum += attnum_offset; + + if (bms_is_member(attnum, clauses_attnums)) + nmatched++; + } + + /* count matching expressions */ + nexprs = 0; + for (i = 0; i < unique_exprs_cnt; i++) + { + ListCell *lc; + + foreach(lc, stat->exprs) + { + Node *stat_expr = (Node *) lfirst(lc); + + /* try to match it */ + if (equal(stat_expr, unique_exprs[i])) + nexprs++; + } + } - /* skip objects matching fewer than two attributes from clauses */ - if (num_matched < 2) + /* + * Skip objects matching fewer than two attributes/expressions from + * clauses. + */ + if (nmatched + nexprs < 2) continue; - func_dependencies[nfunc_dependencies] - = statext_dependencies_load(stat->statOid); + deps = statext_dependencies_load(stat->statOid); + + /* + * The expressions may be represented by different attnums in the + * stats, we need to remap them to be consistent with the clauses. + * That will make the later steps (e.g. picking the strongest item and + * so on) much simpler and cheaper, because it won't need to care + * about the offset at all. + * + * When we're at it, we can ignore dependencies that are not fully + * matched by clauses (i.e. referencing attributes or expressions that + * are not in the clauses). + * + * We have to do this for all statistics, as long as there are any + * expressions - we need to shift the attnums in all dependencies. + * + * XXX Maybe we should do this always, because it also eliminates some + * of the dependencies early. It might be cheaper than having to walk + * the longer list in find_strongest_dependency later, especially as + * we need to do that repeatedly? + * + * XXX We have to do this even when there are no expressions in + * clauses, otherwise find_strongest_dependency may fail for stats + * with expressions (due to lookup of negative value in bitmap). So we + * need to at least filter out those dependencies. Maybe we could do + * it in a cheaper way (if there are no expr clauses, we can just + * discard all negative attnums without any lookups). + */ + if (unique_exprs_cnt > 0 || stat->exprs != NIL) + { + int ndeps = 0; - total_ndeps += func_dependencies[nfunc_dependencies]->ndeps; - nfunc_dependencies++; + for (i = 0; i < deps->ndeps; i++) + { + bool skip = false; + MVDependency *dep = deps->deps[i]; + int j; + + for (j = 0; j < dep->nattributes; j++) + { + int idx; + Node *expr; + int k; + AttrNumber unique_attnum = InvalidAttrNumber; + AttrNumber attnum; + + /* undo the per-statistics offset */ + attnum = dep->attributes[j]; + + /* + * For regular attributes we can simply check if it + * matches any clause. If there's no matching clause, we + * can just ignore it. We need to offset the attnum + * though. + */ + if (AttrNumberIsForUserDefinedAttr(attnum)) + { + dep->attributes[j] = attnum + attnum_offset; + + if (!bms_is_member(dep->attributes[j], clauses_attnums)) + { + skip = true; + break; + } + + continue; + } + + /* + * the attnum should be a valid system attnum (-1, -2, + * ...) + */ + Assert(AttributeNumberIsValid(attnum)); + + /* + * For expressions, we need to do two translations. First + * we have to translate the negative attnum to index in + * the list of expressions (in the statistics object). + * Then we need to see if there's a matching clause. The + * index of the unique expression determines the attnum + * (and we offset it). + */ + idx = -(1 + attnum); + + /* Is the expression index is valid? */ + Assert((idx >= 0) && (idx < list_length(stat->exprs))); + + expr = (Node *) list_nth(stat->exprs, idx); + + /* try to find the expression in the unique list */ + for (k = 0; k < unique_exprs_cnt; k++) + { + /* + * found a matching unique expression, use the attnum + * (derived from index of the unique expression) + */ + if (equal(unique_exprs[k], expr)) + { + unique_attnum = -(k + 1) + attnum_offset; + break; + } + } + + /* + * Found no matching expression, so we can simply skip + * this dependency, because there's no chance it will be + * fully covered. + */ + if (unique_attnum == InvalidAttrNumber) + { + skip = true; + break; + } + + /* otherwise remap it to the new attnum */ + dep->attributes[j] = unique_attnum; + } + + /* if found a matching dependency, keep it */ + if (!skip) + { + /* maybe we've skipped something earlier, so move it */ + if (ndeps != i) + deps->deps[ndeps] = deps->deps[i]; + + ndeps++; + } + } + + deps->ndeps = ndeps; + } + + /* + * It's possible we've removed all dependencies, in which case we + * don't bother adding it to the list. + */ + if (deps->ndeps > 0) + { + func_dependencies[nfunc_dependencies] = deps; + total_ndeps += deps->ndeps; + nfunc_dependencies++; + } } /* if no matching stats could be found then we've nothing to do */ @@ -1313,12 +1785,13 @@ dependencies_clauselist_selectivity(PlannerInfo *root, pfree(func_dependencies); bms_free(clauses_attnums); pfree(list_attnums); + pfree(unique_exprs); return 1.0; } /* * Work out which dependencies we can apply, starting with the - * widest/stongest ones, and proceeding to smaller/weaker ones. + * widest/strongest ones, and proceeding to smaller/weaker ones. */ dependencies = (MVDependency **) palloc(sizeof(MVDependency *) * total_ndeps); @@ -1360,6 +1833,7 @@ dependencies_clauselist_selectivity(PlannerInfo *root, pfree(func_dependencies); bms_free(clauses_attnums); pfree(list_attnums); + pfree(unique_exprs); return s1; } diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index d332da8c9333..5a3cac432402 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -6,7 +6,7 @@ * Generic code supporting statistics objects created via CREATE STATISTICS. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,6 +24,7 @@ #include "catalog/pg_collation.h" #include "catalog/pg_statistic_ext.h" #include "catalog/pg_statistic_ext_data.h" +#include "executor/executor.h" #include "commands/progress.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" @@ -36,13 +37,16 @@ #include "statistics/statistics.h" #include "utils/acl.h" #include "utils/array.h" +#include "utils/attoptcache.h" #include "utils/builtins.h" +#include "utils/datum.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" #include "utils/selfuncs.h" #include "utils/syscache.h" +#include "utils/typcache.h" /* * To avoid consuming too much memory during analysis and/or too much space @@ -65,20 +69,40 @@ typedef struct StatExtEntry char *schema; /* statistics object's schema */ char *name; /* statistics object's name */ Bitmapset *columns; /* attribute numbers covered by the object */ - List *types; /* 'char' list of enabled statistic kinds */ + List *types; /* 'char' list of enabled statistics kinds */ int stattarget; /* statistics target (-1 for default) */ + List *exprs; /* expressions */ } StatExtEntry; static List *fetch_statentries_for_relation(Relation pg_statext, Oid relid); -static VacAttrStats **lookup_var_attr_stats(Relation rel, Bitmapset *attrs, +static VacAttrStats **lookup_var_attr_stats(Relation rel, Bitmapset *attrs, List *exprs, int nvacatts, VacAttrStats **vacatts); -static void statext_store(Oid relid, +static void statext_store(Oid statOid, MVNDistinct *ndistinct, MVDependencies *dependencies, - MCVList *mcv, VacAttrStats **stats); + MCVList *mcv, Datum exprs, VacAttrStats **stats); static int statext_compute_stattarget(int stattarget, int natts, VacAttrStats **stats); +/* Information needed to analyze a single simple expression. */ +typedef struct AnlExprData +{ + Node *expr; /* expression to analyze */ + VacAttrStats *vacattrstat; /* statistics attrs to analyze */ +} AnlExprData; + +static void compute_expr_stats(Relation onerel, double totalrows, + AnlExprData *exprdata, int nexprs, + HeapTuple *rows, int numrows); +static Datum serialize_expr_stats(AnlExprData *exprdata, int nexprs); +static Datum expr_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull); +static AnlExprData *build_expr_data(List *exprs, int stattarget); + +static StatsBuildData *make_build_data(Relation onerel, StatExtEntry *stat, + int numrows, HeapTuple *rows, + VacAttrStats **stats, int stattarget); + + /* * Compute requested extended stats, using the rows sampled for the plain * (single-column) stats. @@ -93,21 +117,25 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, { Relation pg_stext; ListCell *lc; - List *stats; + List *statslist; MemoryContext cxt; MemoryContext oldcxt; int64 ext_cnt; + /* Do nothing if there are no columns to analyze. */ + if (!natts) + return; + cxt = AllocSetContextCreate(CurrentMemoryContext, "BuildRelationExtStatistics", ALLOCSET_DEFAULT_SIZES); oldcxt = MemoryContextSwitchTo(cxt); pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock); - stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel)); + statslist = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel)); /* report this phase */ - if (stats != NIL) + if (statslist != NIL) { const int index[] = { PROGRESS_ANALYZE_PHASE, @@ -115,28 +143,30 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, }; const int64 val[] = { PROGRESS_ANALYZE_PHASE_COMPUTE_EXT_STATS, - list_length(stats) + list_length(statslist) }; pgstat_progress_update_multi_param(2, index, val); } ext_cnt = 0; - foreach(lc, stats) + foreach(lc, statslist) { StatExtEntry *stat = (StatExtEntry *) lfirst(lc); MVNDistinct *ndistinct = NULL; MVDependencies *dependencies = NULL; MCVList *mcv = NULL; + Datum exprstats = (Datum) 0; VacAttrStats **stats; ListCell *lc2; int stattarget; + StatsBuildData *data; /* * Check if we can build these stats based on the column analyzed. If * not, report this fact (except in autovacuum) and move on. */ - stats = lookup_var_attr_stats(onerel, stat->columns, + stats = lookup_var_attr_stats(onerel, stat->columns, stat->exprs, natts, vacattrstats); if (!stats) { @@ -151,10 +181,6 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, continue; } - /* check allowed number of dimensions */ - Assert(bms_num_members(stat->columns) >= 2 && - bms_num_members(stat->columns) <= STATS_MAX_DIMENSIONS); - /* compute statistics target for this statistics */ stattarget = statext_compute_stattarget(stat->stattarget, bms_num_members(stat->columns), @@ -168,28 +194,49 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, if (stattarget == 0) continue; + /* evaluate expressions (if the statistics has any) */ + data = make_build_data(onerel, stat, numrows, rows, stats, stattarget); + /* compute statistic of each requested type */ foreach(lc2, stat->types) { char t = (char) lfirst_int(lc2); if (t == STATS_EXT_NDISTINCT) - ndistinct = statext_ndistinct_build(totalrows, numrows, rows, - stat->columns, stats); + ndistinct = statext_ndistinct_build(totalrows, data); else if (t == STATS_EXT_DEPENDENCIES) - dependencies = statext_dependencies_build(numrows, rows, - stat->columns, stats); + dependencies = statext_dependencies_build(data); else if (t == STATS_EXT_MCV) - mcv = statext_mcv_build(numrows, rows, stat->columns, stats, - totalrows, stattarget); + mcv = statext_mcv_build(data, totalrows, stattarget); + else if (t == STATS_EXT_EXPRESSIONS) + { + AnlExprData *exprdata; + int nexprs; + + /* should not happen, thanks to checks when defining stats */ + if (!stat->exprs) + elog(ERROR, "requested expression stats, but there are no expressions"); + + exprdata = build_expr_data(stat->exprs, stattarget); + nexprs = list_length(stat->exprs); + + compute_expr_stats(onerel, totalrows, + exprdata, nexprs, + rows, numrows); + + exprstats = serialize_expr_stats(exprdata, nexprs); + } } /* store the statistics in the catalog */ - statext_store(stat->statOid, ndistinct, dependencies, mcv, stats); + statext_store(stat->statOid, ndistinct, dependencies, mcv, exprstats, stats); /* for reporting progress */ pgstat_progress_update_param(PROGRESS_ANALYZE_EXT_STATS_COMPUTED, ++ext_cnt); + + /* free the build data (allocated as a single chunk) */ + pfree(data); } table_close(pg_stext, RowExclusiveLock); @@ -208,7 +255,7 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, * that would require additional columns. * * See statext_compute_stattarget for details about how we compute statistics - * target for a statistics objects (from the object target, attribute targets + * target for a statistics object (from the object target, attribute targets * and default statistics target). */ int @@ -222,6 +269,10 @@ ComputeExtStatisticsRows(Relation onerel, MemoryContext oldcxt; int result = 0; + /* If there are no columns to analyze, just return 0. */ + if (!natts) + return 0; + cxt = AllocSetContextCreate(CurrentMemoryContext, "ComputeExtStatisticsRows", ALLOCSET_DEFAULT_SIZES); @@ -233,7 +284,7 @@ ComputeExtStatisticsRows(Relation onerel, foreach(lc, lstats) { StatExtEntry *stat = (StatExtEntry *) lfirst(lc); - int stattarget = stat->stattarget; + int stattarget; VacAttrStats **stats; int nattrs = bms_num_members(stat->columns); @@ -242,7 +293,7 @@ ComputeExtStatisticsRows(Relation onerel, * analyzed. If not, ignore it (don't report anything, we'll do that * during the actual build BuildRelationExtStatistics). */ - stats = lookup_var_attr_stats(onerel, stat->columns, + stats = lookup_var_attr_stats(onerel, stat->columns, stat->exprs, natts, vacattrstats); if (!stats) @@ -308,7 +359,7 @@ statext_compute_stattarget(int stattarget, int nattrs, VacAttrStats **stats) */ for (i = 0; i < nattrs; i++) { - /* keep the maximmum statistics target */ + /* keep the maximum statistics target */ if (stats[i]->attr->attstattarget > stattarget) stattarget = stats[i]->attr->attstattarget; } @@ -350,6 +401,10 @@ statext_is_kind_built(HeapTuple htup, char type) attnum = Anum_pg_statistic_ext_data_stxdmcv; break; + case STATS_EXT_EXPRESSIONS: + attnum = Anum_pg_statistic_ext_data_stxdexpr; + break; + default: elog(ERROR, "unexpected statistics type requested: %d", type); } @@ -389,6 +444,7 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid) ArrayType *arr; char *enabled; Form_pg_statistic_ext staForm; + List *exprs = NIL; entry = palloc0(sizeof(StatExtEntry)); staForm = (Form_pg_statistic_ext) GETSTRUCT(htup); @@ -416,10 +472,40 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid) { Assert((enabled[i] == STATS_EXT_NDISTINCT) || (enabled[i] == STATS_EXT_DEPENDENCIES) || - (enabled[i] == STATS_EXT_MCV)); + (enabled[i] == STATS_EXT_MCV) || + (enabled[i] == STATS_EXT_EXPRESSIONS)); entry->types = lappend_int(entry->types, (int) enabled[i]); } + /* decode expression (if any) */ + datum = SysCacheGetAttr(STATEXTOID, htup, + Anum_pg_statistic_ext_stxexprs, &isnull); + + if (!isnull) + { + char *exprsString; + + exprsString = TextDatumGetCString(datum); + exprs = (List *) stringToNode(exprsString); + + pfree(exprsString); + + /* + * Run the expressions through eval_const_expressions. This is not + * just an optimization, but is necessary, because the planner + * will be comparing them to similarly-processed qual clauses, and + * may fail to detect valid matches without this. We must not use + * canonicalize_qual, however, since these aren't qual + * expressions. + */ + exprs = (List *) eval_const_expressions(NULL, (Node *) exprs); + + /* May as well fix opfuncids too */ + fix_opfuncids((Node *) exprs); + } + + entry->exprs = exprs; + result = lappend(result, entry); } @@ -428,6 +514,187 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid) return result; } +/* + * examine_attribute -- pre-analysis of a single column + * + * Determine whether the column is analyzable; if so, create and initialize + * a VacAttrStats struct for it. If not, return NULL. + */ +static VacAttrStats * +examine_attribute(Node *expr) +{ + HeapTuple typtuple; + VacAttrStats *stats; + int i; + bool ok; + + /* + * Create the VacAttrStats struct. Note that we only have a copy of the + * fixed fields of the pg_attribute tuple. + */ + stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats)); + + /* fake the attribute */ + stats->attr = (Form_pg_attribute) palloc0(ATTRIBUTE_FIXED_PART_SIZE); + stats->attr->attstattarget = -1; + + /* + * When analyzing an expression, believe the expression tree's type not + * the column datatype --- the latter might be the opckeytype storage type + * of the opclass, which is not interesting for our purposes. (Note: if + * we did anything with non-expression statistics columns, we'd need to + * figure out where to get the correct type info from, but for now that's + * not a problem.) It's not clear whether anyone will care about the + * typmod, but we store that too just in case. + */ + stats->attrtypid = exprType(expr); + stats->attrtypmod = exprTypmod(expr); + stats->attrcollid = exprCollation(expr); + + typtuple = SearchSysCacheCopy1(TYPEOID, + ObjectIdGetDatum(stats->attrtypid)); + if (!HeapTupleIsValid(typtuple)) + elog(ERROR, "cache lookup failed for type %u", stats->attrtypid); + stats->attrtype = (Form_pg_type) GETSTRUCT(typtuple); + + /* + * We don't actually analyze individual attributes, so no need to set the + * memory context. + */ + stats->anl_context = NULL; + stats->tupattnum = InvalidAttrNumber; + + /* + * The fields describing the stats->stavalues[n] element types default to + * the type of the data being analyzed, but the type-specific typanalyze + * function can change them if it wants to store something else. + */ + for (i = 0; i < STATISTIC_NUM_SLOTS; i++) + { + stats->statypid[i] = stats->attrtypid; + stats->statyplen[i] = stats->attrtype->typlen; + stats->statypbyval[i] = stats->attrtype->typbyval; + stats->statypalign[i] = stats->attrtype->typalign; + } + + /* + * Call the type-specific typanalyze function. If none is specified, use + * std_typanalyze(). + */ + if (OidIsValid(stats->attrtype->typanalyze)) + ok = DatumGetBool(OidFunctionCall1(stats->attrtype->typanalyze, + PointerGetDatum(stats))); + else + ok = std_typanalyze(stats); + + if (!ok || stats->compute_stats == NULL || stats->minrows <= 0) + { + heap_freetuple(typtuple); + pfree(stats->attr); + pfree(stats); + return NULL; + } + + return stats; +} + +/* + * examine_expression -- pre-analysis of a single expression + * + * Determine whether the expression is analyzable; if so, create and initialize + * a VacAttrStats struct for it. If not, return NULL. + */ +static VacAttrStats * +examine_expression(Node *expr, int stattarget) +{ + HeapTuple typtuple; + VacAttrStats *stats; + int i; + bool ok; + + Assert(expr != NULL); + + /* + * Create the VacAttrStats struct. + */ + stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats)); + + /* + * When analyzing an expression, believe the expression tree's type. + */ + stats->attrtypid = exprType(expr); + stats->attrtypmod = exprTypmod(expr); + + /* + * We don't allow collation to be specified in CREATE STATISTICS, so we + * have to use the collation specified for the expression. It's possible + * to specify the collation in the expression "(col COLLATE "en_US")" in + * which case exprCollation() does the right thing. + */ + stats->attrcollid = exprCollation(expr); + + /* + * We don't have any pg_attribute for expressions, so let's fake something + * reasonable into attstattarget, which is the only thing std_typanalyze + * needs. + */ + stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_FIXED_PART_SIZE); + + /* + * We can't have statistics target specified for the expression, so we + * could use either the default_statistics_target, or the target computed + * for the extended statistics. The second option seems more reasonable. + */ + stats->attr->attstattarget = stattarget; + + /* initialize some basic fields */ + stats->attr->attrelid = InvalidOid; + stats->attr->attnum = InvalidAttrNumber; + stats->attr->atttypid = stats->attrtypid; + + typtuple = SearchSysCacheCopy1(TYPEOID, + ObjectIdGetDatum(stats->attrtypid)); + if (!HeapTupleIsValid(typtuple)) + elog(ERROR, "cache lookup failed for type %u", stats->attrtypid); + + stats->attrtype = (Form_pg_type) GETSTRUCT(typtuple); + stats->anl_context = CurrentMemoryContext; /* XXX should be using + * something else? */ + stats->tupattnum = InvalidAttrNumber; + + /* + * The fields describing the stats->stavalues[n] element types default to + * the type of the data being analyzed, but the type-specific typanalyze + * function can change them if it wants to store something else. + */ + for (i = 0; i < STATISTIC_NUM_SLOTS; i++) + { + stats->statypid[i] = stats->attrtypid; + stats->statyplen[i] = stats->attrtype->typlen; + stats->statypbyval[i] = stats->attrtype->typbyval; + stats->statypalign[i] = stats->attrtype->typalign; + } + + /* + * Call the type-specific typanalyze function. If none is specified, use + * std_typanalyze(). + */ + if (OidIsValid(stats->attrtype->typanalyze)) + ok = DatumGetBool(OidFunctionCall1(stats->attrtype->typanalyze, + PointerGetDatum(stats))); + else + ok = std_typanalyze(stats); + + if (!ok || stats->compute_stats == NULL || stats->minrows <= 0) + { + heap_freetuple(typtuple); + pfree(stats); + return NULL; + } + + return stats; +} + /* * Using 'vacatts' of size 'nvacatts' as input data, return a newly built * VacAttrStats array which includes only the items corresponding to @@ -436,15 +703,18 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid) * to the caller that the stats should not be built. */ static VacAttrStats ** -lookup_var_attr_stats(Relation rel, Bitmapset *attrs, +lookup_var_attr_stats(Relation rel, Bitmapset *attrs, List *exprs, int nvacatts, VacAttrStats **vacatts) { int i = 0; int x = -1; + int natts; VacAttrStats **stats; + ListCell *lc; - stats = (VacAttrStats **) - palloc(bms_num_members(attrs) * sizeof(VacAttrStats *)); + natts = bms_num_members(attrs) + list_length(exprs); + + stats = (VacAttrStats **) palloc(natts * sizeof(VacAttrStats *)); /* lookup VacAttrStats info for the requested columns (same attnum) */ while ((x = bms_next_member(attrs, x)) >= 0) @@ -481,6 +751,24 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, i++; } + /* also add info for expressions */ + foreach(lc, exprs) + { + Node *expr = (Node *) lfirst(lc); + + stats[i] = examine_attribute(expr); + + /* + * XXX We need tuple descriptor later, and we just grab it from + * stats[0]->tupDesc (see e.g. statext_mcv_build). But as coded + * examine_attribute does not set that, so just grab it from the first + * vacatts element. + */ + stats[i]->tupDesc = vacatts[0]->tupDesc; + + i++; + } + return stats; } @@ -492,7 +780,7 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, static void statext_store(Oid statOid, MVNDistinct *ndistinct, MVDependencies *dependencies, - MCVList *mcv, VacAttrStats **stats) + MCVList *mcv, Datum exprs, VacAttrStats **stats) { Relation pg_stextdata; HeapTuple stup, @@ -533,11 +821,17 @@ statext_store(Oid statOid, nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = (data == NULL); values[Anum_pg_statistic_ext_data_stxdmcv - 1] = PointerGetDatum(data); } + if (exprs != (Datum) 0) + { + nulls[Anum_pg_statistic_ext_data_stxdexpr - 1] = false; + values[Anum_pg_statistic_ext_data_stxdexpr - 1] = exprs; + } /* always replace the value (either by bytea or NULL) */ replaces[Anum_pg_statistic_ext_data_stxdndistinct - 1] = true; replaces[Anum_pg_statistic_ext_data_stxddependencies - 1] = true; replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; + replaces[Anum_pg_statistic_ext_data_stxdexpr - 1] = true; /* there should already be a pg_statistic_ext_data tuple */ oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statOid)); @@ -660,37 +954,6 @@ compare_datums_simple(Datum a, Datum b, SortSupport ssup) return ApplySortComparator(a, false, b, false, ssup); } -/* simple counterpart to qsort_arg */ -void * -bsearch_arg(const void *key, const void *base, size_t nmemb, size_t size, - int (*compar) (const void *, const void *, void *), - void *arg) -{ - size_t l, - u, - idx; - const void *p; - int comparison; - - l = 0; - u = nmemb; - while (l < u) - { - idx = (l + u) / 2; - p = (void *) (((const char *) base) + (idx * size)); - comparison = (*compar) (key, p, arg); - - if (comparison < 0) - u = idx; - else if (comparison > 0) - l = idx + 1; - else - return (void *) p; - } - - return NULL; -} - /* * build_attnums_array * Transforms a bitmap into an array of AttrNumber values. @@ -700,7 +963,7 @@ bsearch_arg(const void *key, const void *base, size_t nmemb, size_t size, * is not necessary here (and when querying the bitmap). */ AttrNumber * -build_attnums_array(Bitmapset *attrs, int *numattrs) +build_attnums_array(Bitmapset *attrs, int nexprs, int *numattrs) { int i, j; @@ -716,16 +979,19 @@ build_attnums_array(Bitmapset *attrs, int *numattrs) j = -1; while ((j = bms_next_member(attrs, j)) >= 0) { + int attnum = (j - nexprs); + /* * Make sure the bitmap contains only user-defined attributes. As * bitmaps can't contain negative values, this can be violated in two * ways. Firstly, the bitmap might contain 0 as a member, and secondly * the integer value might be larger than MaxAttrNumber. */ - Assert(AttrNumberIsForUserDefinedAttr(j)); - Assert(j <= MaxAttrNumber); + Assert(AttributeNumberIsValid(attnum)); + Assert(attnum <= MaxAttrNumber); + Assert(attnum >= (-nexprs)); - attnums[i++] = (AttrNumber) j; + attnums[i++] = (AttrNumber) attnum; /* protect against overflows */ Assert(i <= num); @@ -742,29 +1008,31 @@ build_attnums_array(Bitmapset *attrs, int *numattrs) * can simply pfree the return value to release all of it. */ SortItem * -build_sorted_items(int numrows, int *nitems, HeapTuple *rows, TupleDesc tdesc, - MultiSortSupport mss, int numattrs, AttrNumber *attnums) +build_sorted_items(StatsBuildData *data, int *nitems, + MultiSortSupport mss, + int numattrs, AttrNumber *attnums) { int i, j, len, - idx; - int nvalues = numrows * numattrs; + nrows; + int nvalues = data->numrows * numattrs; SortItem *items; Datum *values; bool *isnull; char *ptr; + int *typlen; /* Compute the total amount of memory we need (both items and values). */ - len = numrows * sizeof(SortItem) + nvalues * (sizeof(Datum) + sizeof(bool)); + len = data->numrows * sizeof(SortItem) + nvalues * (sizeof(Datum) + sizeof(bool)); /* Allocate the memory and split it into the pieces. */ ptr = palloc0(len); /* items to sort */ items = (SortItem *) ptr; - ptr += numrows * sizeof(SortItem); + ptr += data->numrows * sizeof(SortItem); /* values and null flags */ values = (Datum *) ptr; @@ -777,21 +1045,47 @@ build_sorted_items(int numrows, int *nitems, HeapTuple *rows, TupleDesc tdesc, Assert((ptr - (char *) items) == len); /* fix the pointers to Datum and bool arrays */ - idx = 0; - for (i = 0; i < numrows; i++) + nrows = 0; + for (i = 0; i < data->numrows; i++) { - bool toowide = false; + items[nrows].values = &values[nrows * numattrs]; + items[nrows].isnull = &isnull[nrows * numattrs]; + + nrows++; + } - items[idx].values = &values[idx * numattrs]; - items[idx].isnull = &isnull[idx * numattrs]; + /* build a local cache of typlen for all attributes */ + typlen = (int *) palloc(sizeof(int) * data->nattnums); + for (i = 0; i < data->nattnums; i++) + typlen[i] = get_typlen(data->stats[i]->attrtypid); + + nrows = 0; + for (i = 0; i < data->numrows; i++) + { + bool toowide = false; /* load the values/null flags from sample rows */ for (j = 0; j < numattrs; j++) { Datum value; bool isnull; + int attlen; + AttrNumber attnum = attnums[j]; + + int idx; + + /* match attnum to the pre-calculated data */ + for (idx = 0; idx < data->nattnums; idx++) + { + if (attnum == data->attnums[idx]) + break; + } + + Assert(idx < data->nattnums); - value = heap_getattr(rows[i], attnums[j], tdesc, &isnull); + value = data->values[idx][i]; + isnull = data->nulls[idx][i]; + attlen = typlen[idx]; /* * If this is a varlena value, check if it's too wide and if yes @@ -802,8 +1096,7 @@ build_sorted_items(int numrows, int *nitems, HeapTuple *rows, TupleDesc tdesc, * on the assumption that those are small (below WIDTH_THRESHOLD) * and will be discarded at the end of analyze. */ - if ((!isnull) && - (TupleDescAttr(tdesc, attnums[j] - 1)->attlen == -1)) + if ((!isnull) && (attlen == -1)) { if (toast_raw_datum_size(value) > WIDTH_THRESHOLD) { @@ -814,21 +1107,21 @@ build_sorted_items(int numrows, int *nitems, HeapTuple *rows, TupleDesc tdesc, value = PointerGetDatum(PG_DETOAST_DATUM(value)); } - items[idx].values[j] = value; - items[idx].isnull[j] = isnull; + items[nrows].values[j] = value; + items[nrows].isnull[j] = isnull; } if (toowide) continue; - idx++; + nrows++; } /* store the actual number of items (ignoring the too-wide ones) */ - *nitems = idx; + *nitems = nrows; /* all items were too wide */ - if (idx == 0) + if (nrows == 0) { /* everything is allocated as a single chunk */ pfree(items); @@ -836,7 +1129,7 @@ build_sorted_items(int numrows, int *nitems, HeapTuple *rows, TupleDesc tdesc, } /* do the sort, using the multi-sort */ - qsort_arg((void *) items, idx, sizeof(SortItem), + qsort_arg((void *) items, nrows, sizeof(SortItem), multi_sort_compare, mss); return items; @@ -862,6 +1155,63 @@ has_stats_of_kind(List *stats, char requiredkind) return false; } +/* + * stat_find_expression + * Search for an expression in statistics object's list of expressions. + * + * Returns the index of the expression in the statistics object's list of + * expressions, or -1 if not found. + */ +static int +stat_find_expression(StatisticExtInfo *stat, Node *expr) +{ + ListCell *lc; + int idx; + + idx = 0; + foreach(lc, stat->exprs) + { + Node *stat_expr = (Node *) lfirst(lc); + + if (equal(stat_expr, expr)) + return idx; + idx++; + } + + /* Expression not found */ + return -1; +} + +/* + * stat_covers_expressions + * Test whether a statistics object covers all expressions in a list. + * + * Returns true if all expressions are covered. If expr_idxs is non-NULL, it + * is populated with the indexes of the expressions found. + */ +static bool +stat_covers_expressions(StatisticExtInfo *stat, List *exprs, + Bitmapset **expr_idxs) +{ + ListCell *lc; + + foreach(lc, exprs) + { + Node *expr = (Node *) lfirst(lc); + int expr_idx; + + expr_idx = stat_find_expression(stat, expr); + if (expr_idx == -1) + return false; + + if (expr_idxs != NULL) + *expr_idxs = bms_add_member(*expr_idxs, expr_idx); + } + + /* If we reach here, all expressions are covered */ + return true; +} + /* * choose_best_statistics * Look for and return statistics with the specified 'requiredkind' which @@ -882,7 +1232,8 @@ has_stats_of_kind(List *stats, char requiredkind) */ StatisticExtInfo * choose_best_statistics(List *stats, char requiredkind, - Bitmapset **clause_attnums, int nclauses) + Bitmapset **clause_attnums, List **clause_exprs, + int nclauses) { ListCell *lc; StatisticExtInfo *best_match = NULL; @@ -893,7 +1244,8 @@ choose_best_statistics(List *stats, char requiredkind, { int i; StatisticExtInfo *info = (StatisticExtInfo *) lfirst(lc); - Bitmapset *matched = NULL; + Bitmapset *matched_attnums = NULL; + Bitmapset *matched_exprs = NULL; int num_matched; int numkeys; @@ -902,35 +1254,47 @@ choose_best_statistics(List *stats, char requiredkind, continue; /* - * Collect attributes in remaining (unestimated) clauses fully covered - * by this statistic object. + * Collect attributes and expressions in remaining (unestimated) + * clauses fully covered by this statistic object. + * + * We know already estimated clauses have both clause_attnums and + * clause_exprs set to NULL. We leave the pointers NULL if already + * estimated, or we reset them to NULL after estimating the clause. */ for (i = 0; i < nclauses; i++) { + Bitmapset *expr_idxs = NULL; + /* ignore incompatible/estimated clauses */ - if (!clause_attnums[i]) + if (!clause_attnums[i] && !clause_exprs[i]) continue; /* ignore clauses that are not covered by this object */ - if (!bms_is_subset(clause_attnums[i], info->keys)) + if (!bms_is_subset(clause_attnums[i], info->keys) || + !stat_covers_expressions(info, clause_exprs[i], &expr_idxs)) continue; - matched = bms_add_members(matched, clause_attnums[i]); + /* record attnums and indexes of expressions covered */ + matched_attnums = bms_add_members(matched_attnums, clause_attnums[i]); + matched_exprs = bms_add_members(matched_exprs, expr_idxs); } - num_matched = bms_num_members(matched); - bms_free(matched); + num_matched = bms_num_members(matched_attnums) + bms_num_members(matched_exprs); + + bms_free(matched_attnums); + bms_free(matched_exprs); /* * save the actual number of keys in the stats so that we can choose * the narrowest stats with the most matching keys. */ - numkeys = bms_num_members(info->keys); + numkeys = bms_num_members(info->keys) + list_length(info->exprs); /* - * Use this object when it increases the number of matched clauses or - * when it matches the same number of attributes but these stats have - * fewer keys than any previous match. + * Use this object when it increases the number of matched attributes + * and expressions or when it matches the same number of attributes + * and expressions but these stats have fewer keys than any previous + * match. */ if (num_matched > best_num_matched || (num_matched == best_num_matched && numkeys < best_match_keys)) @@ -955,7 +1319,8 @@ choose_best_statistics(List *stats, char requiredkind, */ static bool statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, - Index relid, Bitmapset **attnums) + Index relid, Bitmapset **attnums, + List **exprs) { /* Look inside any binary-compatible relabeling (as in examine_variable) */ if (IsA(clause, RelabelType)) @@ -983,19 +1348,19 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, return true; } - /* (Var op Const) or (Const op Var) */ + /* (Var/Expr op Const) or (Const op Var/Expr) */ if (is_opclause(clause)) { RangeTblEntry *rte = root->simple_rte_array[relid]; OpExpr *expr = (OpExpr *) clause; - Var *var; + Node *clause_expr; /* Only expressions with two arguments are considered compatible. */ if (list_length(expr->args) != 2) return false; - /* Check if the expression has the right shape (one Var, one Const) */ - if (!examine_clause_args(expr->args, &var, NULL, NULL)) + /* Check if the expression has the right shape */ + if (!examine_opclause_args(expr->args, &clause_expr, NULL, NULL)) return false; /* @@ -1013,7 +1378,7 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, case F_SCALARLESEL: case F_SCALARGTSEL: case F_SCALARGESEL: - /* supported, will continue with inspection of the Var */ + /* supported, will continue with inspection of the Var/Expr */ break; default: @@ -1035,23 +1400,29 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, !get_func_leakproof(get_opcode(expr->opno))) return false; - return statext_is_compatible_clause_internal(root, (Node *) var, - relid, attnums); + /* Check (Var op Const) or (Const op Var) clauses by recursing. */ + if (IsA(clause_expr, Var)) + return statext_is_compatible_clause_internal(root, clause_expr, + relid, attnums, exprs); + + /* Otherwise we have (Expr op Const) or (Const op Expr). */ + *exprs = lappend(*exprs, clause_expr); + return true; } - /* Var IN Array */ + /* Var/Expr IN Array */ if (IsA(clause, ScalarArrayOpExpr)) { RangeTblEntry *rte = root->simple_rte_array[relid]; ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) clause; - Var *var; + Node *clause_expr; /* Only expressions with two arguments are considered compatible. */ if (list_length(expr->args) != 2) return false; /* Check if the expression has the right shape (one Var, one Const) */ - if (!examine_clause_args(expr->args, &var, NULL, NULL)) + if (!examine_opclause_args(expr->args, &clause_expr, NULL, NULL)) return false; /* @@ -1069,7 +1440,7 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, case F_SCALARLESEL: case F_SCALARGTSEL: case F_SCALARGESEL: - /* supported, will continue with inspection of the Var */ + /* supported, will continue with inspection of the Var/Expr */ break; default: @@ -1091,8 +1462,14 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, !get_func_leakproof(get_opcode(expr->opno))) return false; - return statext_is_compatible_clause_internal(root, (Node *) var, - relid, attnums); + /* Check Var IN Array clauses by recursing. */ + if (IsA(clause_expr, Var)) + return statext_is_compatible_clause_internal(root, clause_expr, + relid, attnums, exprs); + + /* Otherwise we have Expr IN Array. */ + *exprs = lappend(*exprs, clause_expr); + return true; } /* AND/OR/NOT clause */ @@ -1125,56 +1502,89 @@ statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, */ if (!statext_is_compatible_clause_internal(root, (Node *) lfirst(lc), - relid, attnums)) + relid, attnums, exprs)) return false; } return true; } - /* Var IS NULL */ + /* Var/Expr IS NULL */ if (IsA(clause, NullTest)) { NullTest *nt = (NullTest *) clause; - /* - * Only simple (Var IS NULL) expressions supported for now. Maybe we - * could use examine_variable to fix this? - */ - if (!IsA(nt->arg, Var)) - return false; + /* Check Var IS NULL clauses by recursing. */ + if (IsA(nt->arg, Var)) + return statext_is_compatible_clause_internal(root, (Node *) (nt->arg), + relid, attnums, exprs); - return statext_is_compatible_clause_internal(root, (Node *) (nt->arg), - relid, attnums); + /* Otherwise we have Expr IS NULL. */ + *exprs = lappend(*exprs, nt->arg); + return true; } - return false; + /* + * Treat any other expressions as bare expressions to be matched against + * expressions in statistics objects. + */ + *exprs = lappend(*exprs, clause); + return true; } /* * statext_is_compatible_clause * Determines if the clause is compatible with MCV lists. * - * Currently, we only support three types of clauses: + * Currently, we only support the following types of clauses: * - * (a) OpExprs of the form (Var op Const), or (Const op Var), where the op - * is one of ("=", "<", ">", ">=", "<=") + * (a) OpExprs of the form (Var/Expr op Const), or (Const op Var/Expr), where + * the op is one of ("=", "<", ">", ">=", "<=") * - * (b) (Var IS [NOT] NULL) + * (b) (Var/Expr IS [NOT] NULL) * * (c) combinations using AND/OR/NOT * + * (d) ScalarArrayOpExprs of the form (Var/Expr op ANY (array)) or (Var/Expr + * op ALL (array)) + * * In the future, the range of supported clauses may be expanded to more * complex cases, for example (Var op Var). */ static bool statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, - Bitmapset **attnums) + Bitmapset **attnums, List **exprs) { RangeTblEntry *rte = root->simple_rte_array[relid]; RestrictInfo *rinfo = (RestrictInfo *) clause; + int clause_relid; Oid userid; + /* + * Special-case handling for bare BoolExpr AND clauses, because the + * restrictinfo machinery doesn't build RestrictInfos on top of AND + * clauses. + */ + if (is_andclause(clause)) + { + BoolExpr *expr = (BoolExpr *) clause; + ListCell *lc; + + /* + * Check that each sub-clause is compatible. We expect these to be + * RestrictInfos. + */ + foreach(lc, expr->args) + { + if (!statext_is_compatible_clause(root, (Node *) lfirst(lc), + relid, attnums, exprs)) + return false; + } + + return true; + } + + /* Otherwise it must be a RestrictInfo. */ if (!IsA(rinfo, RestrictInfo)) return false; @@ -1182,25 +1592,36 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, if (rinfo->pseudoconstant) return false; - /* clauses referencing multiple varnos are incompatible */ - if (bms_membership(rinfo->clause_relids) != BMS_SINGLETON) + /* Clauses referencing other varnos are incompatible. */ + if (!bms_get_singleton_member(rinfo->clause_relids, &clause_relid) || + clause_relid != relid) return false; /* Check the clause and determine what attributes it references. */ if (!statext_is_compatible_clause_internal(root, (Node *) rinfo->clause, - relid, attnums)) + relid, attnums, exprs)) return false; /* - * Check that the user has permission to read all these attributes. Use + * Check that the user has permission to read all required attributes. Use * checkAsUser if it's set, in case we're accessing the table via a view. */ userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); if (pg_class_aclcheck(rte->relid, userid, ACL_SELECT) != ACLCHECK_OK) { + Bitmapset *clause_attnums = NULL; + /* Don't have table privilege, must check individual columns */ - if (bms_is_member(InvalidAttrNumber, *attnums)) + if (*exprs != NIL) + { + pull_varattnos((Node *) exprs, relid, &clause_attnums); + clause_attnums = bms_add_members(clause_attnums, *attnums); + } + else + clause_attnums = *attnums; + + if (bms_is_member(InvalidAttrNumber, clause_attnums)) { /* Have a whole-row reference, must have access to all columns */ if (pg_attribute_aclcheck_all(rte->relid, userid, ACL_SELECT, @@ -1212,7 +1633,7 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, /* Check the columns referenced by the clause */ int attnum = -1; - while ((attnum = bms_next_member(*attnums, attnum)) >= 0) + while ((attnum = bms_next_member(clause_attnums, attnum)) >= 0) { if (pg_attribute_aclcheck(rte->relid, attnum, userid, ACL_SELECT) != ACLCHECK_OK) @@ -1240,10 +1661,10 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, * One of the main challenges with using MCV lists is how to extrapolate the * estimate to the data not covered by the MCV list. To do that, we compute * not only the "MCV selectivity" (selectivities for MCV items matching the - * supplied clauses), but also a couple of derived selectivities: + * supplied clauses), but also the following related selectivities: * - * - simple selectivity: Computed without extended statistic, i.e. as if the - * columns/clauses were independent + * - simple selectivity: Computed without extended statistics, i.e. as if the + * columns/clauses were independent. * * - base selectivity: Similar to simple selectivity, but is computed using * the extended statistic by adding up the base frequencies (that we compute @@ -1251,30 +1672,9 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, * * - total selectivity: Selectivity covered by the whole MCV list. * - * - other selectivity: A selectivity estimate for data not covered by the MCV - * list (i.e. satisfying the clauses, but not common enough to make it into - * the MCV list) - * - * Note: While simple and base selectivities are defined in a quite similar - * way, the values are computed differently and are not therefore equal. The - * simple selectivity is computed as a product of per-clause estimates, while - * the base selectivity is computed by adding up base frequencies of matching - * items of the multi-column MCV list. So the values may differ for two main - * reasons - (a) the MCV list may not cover 100% of the data and (b) some of - * the MCV items did not match the estimated clauses. - * - * As both (a) and (b) reduce the base selectivity value, it generally holds - * that (simple_selectivity >= base_selectivity). If the MCV list covers all - * the data, the values may be equal. - * - * So, (simple_selectivity - base_selectivity) is an estimate for the part - * not covered by the MCV list, and (mcv_selectivity - base_selectivity) may - * be seen as a correction for the part covered by the MCV list. Those two - * statements are actually equivalent. - * - * Note: Due to rounding errors and minor differences in how the estimates - * are computed, the inequality may not always hold. Which is why we clamp - * the selectivities to prevent strange estimate (negative etc.). + * These are passed to mcv_combine_selectivities() which combines them to + * produce a selectivity estimate that makes use of both per-column statistics + * and the multi-column MCV statistics. * * 'estimatedclauses' is an input/output parameter. We set bits for the * 0-based 'clauses' indexes we estimate for and also skip clause items that @@ -1283,38 +1683,32 @@ statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, static Selectivity statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, - RelOptInfo *rel, Bitmapset **estimatedclauses) + RelOptInfo *rel, Bitmapset **estimatedclauses, + bool is_or) { ListCell *l; - Bitmapset **list_attnums; + Bitmapset **list_attnums; /* attnums extracted from the clause */ + List **list_exprs; /* expressions matched to any statistic */ int listidx; - Selectivity sel = 1.0; - RangeTblEntry *rte = planner_rt_fetch(rel->relid, root); - - /* - * When dealing with regular inheritance trees, ignore extended stats - * (which were built without data from child rels, and thus do not - * represent them). For partitioned tables data there's no data in the - * non-leaf relations, so we build stats only for the inheritance tree. - * So for partitioned tables we do consider extended stats. - */ - if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE) - return 1.0; + Selectivity sel = (is_or) ? 0.0 : 1.0; /* check if there's any stats that might be useful for us. */ if (!has_stats_of_kind(rel->statlist, STATS_EXT_MCV)) - return 1.0; + return sel; list_attnums = (Bitmapset **) palloc(sizeof(Bitmapset *) * list_length(clauses)); + /* expressions extracted from complex expressions */ + list_exprs = (List **) palloc(sizeof(Node *) * list_length(clauses)); + /* - * Pre-process the clauses list to extract the attnums seen in each item. - * We need to determine if there's any clauses which will be useful for - * selectivity estimations with extended stats. Along the way we'll record - * all of the attnums for each clause in a list which we'll reference - * later so we don't need to repeat the same work again. We'll also keep - * track of all attnums seen. + * Pre-process the clauses list to extract the attnums and expressions + * seen in each item. We need to determine if there are any clauses which + * will be useful for selectivity estimations with extended stats. Along + * the way we'll record all of the attnums and expressions for each clause + * in lists which we'll reference later so we don't need to repeat the + * same work again. * * We also skip clauses that we already estimated using different types of * statistics (we treat them as incompatible). @@ -1324,12 +1718,19 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli { Node *clause = (Node *) lfirst(l); Bitmapset *attnums = NULL; + List *exprs = NIL; if (!bms_is_member(listidx, *estimatedclauses) && - statext_is_compatible_clause(root, clause, rel->relid, &attnums)) + statext_is_compatible_clause(root, clause, rel->relid, &attnums, &exprs)) + { list_attnums[listidx] = attnums; + list_exprs[listidx] = exprs; + } else + { list_attnums[listidx] = NULL; + list_exprs[listidx] = NIL; + } listidx++; } @@ -1339,16 +1740,12 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli { StatisticExtInfo *stat; List *stat_clauses; - Selectivity simple_sel, - mcv_sel, - mcv_basesel, - mcv_totalsel, - other_sel, - stat_sel; + Bitmapset *simple_clauses; /* find the best suited statistics object for these attnums */ stat = choose_best_statistics(rel->statlist, STATS_EXT_MCV, - list_attnums, list_length(clauses)); + list_attnums, list_exprs, + list_length(clauses)); /* * if no (additional) matching stats could be found then we've nothing @@ -1363,61 +1760,204 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli /* now filter the clauses to be estimated using the selected MCV */ stat_clauses = NIL; - listidx = 0; + /* record which clauses are simple (single column or expression) */ + simple_clauses = NULL; + + listidx = -1; foreach(l, clauses) { + /* Increment the index before we decide if to skip the clause. */ + listidx++; + /* - * If the clause is compatible with the selected statistics, mark - * it as estimated and add it to the list to estimate. + * Ignore clauses from which we did not extract any attnums or + * expressions (this needs to be consistent with what we do in + * choose_best_statistics). + * + * This also eliminates already estimated clauses - both those + * estimated before and during applying extended statistics. + * + * XXX This check is needed because both bms_is_subset and + * stat_covers_expressions return true for empty attnums and + * expressions. */ - if (list_attnums[listidx] != NULL && - bms_is_subset(list_attnums[listidx], stat->keys)) - { - stat_clauses = lappend(stat_clauses, (Node *) lfirst(l)); - *estimatedclauses = bms_add_member(*estimatedclauses, listidx); + if (!list_attnums[listidx] && !list_exprs[listidx]) + continue; - bms_free(list_attnums[listidx]); - list_attnums[listidx] = NULL; - } + /* + * The clause was not estimated yet, and we've extracted either + * attnums of expressions from it. Ignore it if it's not fully + * covered by the chosen statistics. + * + * We need to check both attributes and expressions, and reject if + * either is not covered. + */ + if (!bms_is_subset(list_attnums[listidx], stat->keys) || + !stat_covers_expressions(stat, list_exprs[listidx], NULL)) + continue; - listidx++; + /* + * Now we know the clause is compatible (we have either attnums or + * expressions extracted from it), and was not estimated yet. + */ + + /* record simple clauses (single column or expression) */ + if ((list_attnums[listidx] == NULL && + list_length(list_exprs[listidx]) == 1) || + (list_exprs[listidx] == NIL && + bms_membership(list_attnums[listidx]) == BMS_SINGLETON)) + simple_clauses = bms_add_member(simple_clauses, + list_length(stat_clauses)); + + /* add clause to list and mark it as estimated */ + stat_clauses = lappend(stat_clauses, (Node *) lfirst(l)); + *estimatedclauses = bms_add_member(*estimatedclauses, listidx); + + /* + * Reset the pointers, so that choose_best_statistics knows this + * clause was estimated and does not consider it again. + */ + bms_free(list_attnums[listidx]); + list_attnums[listidx] = NULL; + + list_free(list_exprs[listidx]); + list_exprs[listidx] = NULL; } - /* - * First compute "simple" selectivity, i.e. without the extended - * statistics, and essentially assuming independence of the - * columns/clauses. We'll then use the various selectivities computed - * from MCV list to improve it. - */ - simple_sel = clauselist_selectivity_simple(root, stat_clauses, varRelid, - jointype, sjinfo, NULL, - false); /* no damping */ + if (is_or) + { + bool *or_matches = NULL; + Selectivity simple_or_sel = 0.0, + stat_sel = 0.0; + MCVList *mcv_list; - /* - * Now compute the multi-column estimate from the MCV list, along with - * the other selectivities (base & total selectivity). - */ - mcv_sel = mcv_clauselist_selectivity(root, stat, stat_clauses, varRelid, - jointype, sjinfo, rel, - &mcv_basesel, &mcv_totalsel); + /* Load the MCV list stored in the statistics object */ + mcv_list = statext_mcv_load(stat->statOid); - /* Estimated selectivity of values not covered by MCV matches */ - other_sel = simple_sel - mcv_basesel; - CLAMP_PROBABILITY(other_sel); + /* + * Compute the selectivity of the ORed list of clauses covered by + * this statistics object by estimating each in turn and combining + * them using the formula P(A OR B) = P(A) + P(B) - P(A AND B). + * This allows us to use the multivariate MCV stats to better + * estimate the individual terms and their overlap. + * + * Each time we iterate this formula, the clause "A" above is + * equal to all the clauses processed so far, combined with "OR". + */ + listidx = 0; + foreach(l, stat_clauses) + { + Node *clause = (Node *) lfirst(l); + Selectivity simple_sel, + overlap_simple_sel, + mcv_sel, + mcv_basesel, + overlap_mcvsel, + overlap_basesel, + mcv_totalsel, + clause_sel, + overlap_sel; + + /* + * "Simple" selectivity of the next clause and its overlap + * with any of the previous clauses. These are our initial + * estimates of P(B) and P(A AND B), assuming independence of + * columns/clauses. + */ + simple_sel = clause_selectivity_ext(root, clause, varRelid, + jointype, sjinfo, false, false); + + overlap_simple_sel = simple_or_sel * simple_sel; + + /* + * New "simple" selectivity of all clauses seen so far, + * assuming independence. + */ + simple_or_sel += simple_sel - overlap_simple_sel; + CLAMP_PROBABILITY(simple_or_sel); + + /* + * Multi-column estimate of this clause using MCV statistics, + * along with base and total selectivities, and corresponding + * selectivities for the overlap term P(A AND B). + */ + mcv_sel = mcv_clause_selectivity_or(root, stat, mcv_list, + clause, &or_matches, + &mcv_basesel, + &overlap_mcvsel, + &overlap_basesel, + &mcv_totalsel); + + /* + * Combine the simple and multi-column estimates. + * + * If this clause is a simple single-column clause, then we + * just use the simple selectivity estimate for it, since the + * multi-column statistics are unlikely to improve on that + * (and in fact could make it worse). For the overlap, we + * always make use of the multi-column statistics. + */ + if (bms_is_member(listidx, simple_clauses)) + clause_sel = simple_sel; + else + clause_sel = mcv_combine_selectivities(simple_sel, + mcv_sel, + mcv_basesel, + mcv_totalsel); + + overlap_sel = mcv_combine_selectivities(overlap_simple_sel, + overlap_mcvsel, + overlap_basesel, + mcv_totalsel); + + /* Factor these into the result for this statistics object */ + stat_sel += clause_sel - overlap_sel; + CLAMP_PROBABILITY(stat_sel); + + listidx++; + } - /* The non-MCV selectivity can't exceed the 1 - mcv_totalsel. */ - if (other_sel > 1.0 - mcv_totalsel) - other_sel = 1.0 - mcv_totalsel; + /* + * Factor the result for this statistics object into the overall + * result. We treat the results from each separate statistics + * object as independent of one another. + */ + sel = sel + stat_sel - sel * stat_sel; + } + else /* Implicitly-ANDed list of clauses */ + { + Selectivity simple_sel, + mcv_sel, + mcv_basesel, + mcv_totalsel, + stat_sel; - /* - * Overall selectivity is the combination of MCV and non-MCV - * estimates. - */ - stat_sel = mcv_sel + other_sel; - CLAMP_PROBABILITY(stat_sel); + /* + * "Simple" selectivity, i.e. without any extended statistics, + * essentially assuming independence of the columns/clauses. + */ + simple_sel = clauselist_selectivity_ext(root, stat_clauses, + varRelid, jointype, + sjinfo, false, false); - /* Factor the estimate from this MCV to the oveall estimate. */ - sel *= stat_sel; + /* + * Multi-column estimate using MCV statistics, along with base and + * total selectivities. + */ + mcv_sel = mcv_clauselist_selectivity(root, stat, stat_clauses, + varRelid, jointype, sjinfo, + rel, &mcv_basesel, + &mcv_totalsel); + + /* Combine the simple and multi-column estimates. */ + stat_sel = mcv_combine_selectivities(simple_sel, + mcv_sel, + mcv_basesel, + mcv_totalsel); + + /* Factor this into the overall result */ + sel *= stat_sel; + } } return sel; @@ -1430,13 +1970,21 @@ statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varReli Selectivity statext_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo, - RelOptInfo *rel, Bitmapset **estimatedclauses) + RelOptInfo *rel, Bitmapset **estimatedclauses, + bool is_or) { Selectivity sel; /* First, try estimating clauses using a multivariate MCV list. */ sel = statext_mcv_clauselist_selectivity(root, clauses, varRelid, jointype, - sjinfo, rel, estimatedclauses); + sjinfo, rel, estimatedclauses, is_or); + + /* + * Functional dependencies only work for clauses connected by AND, so for + * OR clauses we're done. + */ + if (is_or) + return sel; /* * Then, apply functional dependencies on the remaining clauses by calling @@ -1459,23 +2007,24 @@ statext_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, } /* - * examine_opclause_expression - * Split expression into Var and Const parts. + * examine_opclause_args + * Split an operator expression's arguments into Expr and Const parts. * - * Attempts to match the arguments to either (Var op Const) or (Const op Var), - * possibly with a RelabelType on top. When the expression matches this form, - * returns true, otherwise returns false. + * Attempts to match the arguments to either (Expr op Const) or (Const op + * Expr), possibly with a RelabelType on top. When the expression matches this + * form, returns true, otherwise returns false. * - * Optionally returns pointers to the extracted Var/Const nodes, when passed - * non-null pointers (varp, cstp and varonleftp). The varonleftp flag specifies - * on which side of the operator we found the Var node. + * Optionally returns pointers to the extracted Expr/Const nodes, when passed + * non-null pointers (exprp, cstp and expronleftp). The expronleftp flag + * specifies on which side of the operator we found the expression node. */ bool -examine_clause_args(List *args, Var **varp, Const **cstp, bool *varonleftp) +examine_opclause_args(List *args, Node **exprp, Const **cstp, + bool *expronleftp) { - Var *var; + Node *expr; Const *cst; - bool varonleft; + bool expronleft; Node *leftop, *rightop; @@ -1492,30 +2041,567 @@ examine_clause_args(List *args, Var **varp, Const **cstp, bool *varonleftp) if (IsA(rightop, RelabelType)) rightop = (Node *) ((RelabelType *) rightop)->arg; - if (IsA(leftop, Var) && IsA(rightop, Const)) + if (IsA(rightop, Const)) { - var = (Var *) leftop; + expr = (Node *) leftop; cst = (Const *) rightop; - varonleft = true; + expronleft = true; } - else if (IsA(leftop, Const) && IsA(rightop, Var)) + else if (IsA(leftop, Const)) { - var = (Var *) rightop; + expr = (Node *) rightop; cst = (Const *) leftop; - varonleft = false; + expronleft = false; } else return false; /* return pointers to the extracted parts if requested */ - if (varp) - *varp = var; + if (exprp) + *exprp = expr; if (cstp) *cstp = cst; - if (varonleftp) - *varonleftp = varonleft; + if (expronleftp) + *expronleftp = expronleft; return true; } + + +/* + * Compute statistics about expressions of a relation. + */ +static void +compute_expr_stats(Relation onerel, double totalrows, + AnlExprData *exprdata, int nexprs, + HeapTuple *rows, int numrows) +{ + MemoryContext expr_context, + old_context; + int ind, + i; + + expr_context = AllocSetContextCreate(CurrentMemoryContext, + "Analyze Expression", + ALLOCSET_DEFAULT_SIZES); + old_context = MemoryContextSwitchTo(expr_context); + + for (ind = 0; ind < nexprs; ind++) + { + AnlExprData *thisdata = &exprdata[ind]; + VacAttrStats *stats = thisdata->vacattrstat; + Node *expr = thisdata->expr; + TupleTableSlot *slot; + EState *estate; + ExprContext *econtext; + Datum *exprvals; + bool *exprnulls; + ExprState *exprstate; + int tcnt; + + /* Are we still in the main context? */ + Assert(CurrentMemoryContext == expr_context); + + /* + * Need an EState for evaluation of expressions. Create it in the + * per-expression context to be sure it gets cleaned up at the bottom + * of the loop. + */ + estate = CreateExecutorState(); + econtext = GetPerTupleExprContext(estate); + + /* Set up expression evaluation state */ + exprstate = ExecPrepareExpr((Expr *) expr, estate); + + /* Need a slot to hold the current heap tuple, too */ + slot = MakeSingleTupleTableSlot(RelationGetDescr(onerel), + &TTSOpsHeapTuple); + + /* Arrange for econtext's scan tuple to be the tuple under test */ + econtext->ecxt_scantuple = slot; + + /* Compute and save expression values */ + exprvals = (Datum *) palloc(numrows * sizeof(Datum)); + exprnulls = (bool *) palloc(numrows * sizeof(bool)); + + tcnt = 0; + for (i = 0; i < numrows; i++) + { + Datum datum; + bool isnull; + + /* + * Reset the per-tuple context each time, to reclaim any cruft + * left behind by evaluating the statistics expressions. + */ + ResetExprContext(econtext); + + /* Set up for expression evaluation */ + ExecStoreHeapTuple(rows[i], slot, false); + + /* + * Evaluate the expression. We do this in the per-tuple context so + * as not to leak memory, and then copy the result into the + * context created at the beginning of this function. + */ + datum = ExecEvalExprSwitchContext(exprstate, + GetPerTupleExprContext(estate), + &isnull); + if (isnull) + { + exprvals[tcnt] = (Datum) 0; + exprnulls[tcnt] = true; + } + else + { + /* Make sure we copy the data into the context. */ + Assert(CurrentMemoryContext == expr_context); + + exprvals[tcnt] = datumCopy(datum, + stats->attrtype->typbyval, + stats->attrtype->typlen); + exprnulls[tcnt] = false; + } + + tcnt++; + } + + /* + * Now we can compute the statistics for the expression columns. + * + * XXX Unlike compute_index_stats we don't need to switch and reset + * memory contexts here, because we're only computing stats for a + * single expression (and not iterating over many indexes), so we just + * do it in expr_context. Note that compute_stats copies the result + * into stats->anl_context, so it does not disappear. + */ + if (tcnt > 0) + { + AttributeOpts *aopt = + get_attribute_options(stats->attr->attrelid, + stats->attr->attnum); + + stats->exprvals = exprvals; + stats->exprnulls = exprnulls; + stats->rowstride = 1; + stats->compute_stats(stats, + expr_fetch_func, + tcnt, + tcnt); + + /* + * If the n_distinct option is specified, it overrides the above + * computation. + */ + if (aopt != NULL && aopt->n_distinct != 0.0) + stats->stadistinct = aopt->n_distinct; + } + + /* And clean up */ + MemoryContextSwitchTo(expr_context); + + ExecDropSingleTupleTableSlot(slot); + FreeExecutorState(estate); + MemoryContextResetAndDeleteChildren(expr_context); + } + + MemoryContextSwitchTo(old_context); + MemoryContextDelete(expr_context); +} + + +/* + * Fetch function for analyzing statistics object expressions. + * + * We have not bothered to construct tuples from the data, instead the data + * is just in Datum arrays. + */ +static Datum +expr_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull) +{ + int i; + + /* exprvals and exprnulls are already offset for proper column */ + i = rownum * stats->rowstride; + *isNull = stats->exprnulls[i]; + return stats->exprvals[i]; +} + +/* + * Build analyze data for a list of expressions. As this is not tied + * directly to a relation (table or index), we have to fake some of + * the fields in examine_expression(). + */ +static AnlExprData * +build_expr_data(List *exprs, int stattarget) +{ + int idx; + int nexprs = list_length(exprs); + AnlExprData *exprdata; + ListCell *lc; + + exprdata = (AnlExprData *) palloc0(nexprs * sizeof(AnlExprData)); + + idx = 0; + foreach(lc, exprs) + { + Node *expr = (Node *) lfirst(lc); + AnlExprData *thisdata = &exprdata[idx]; + + thisdata->expr = expr; + thisdata->vacattrstat = examine_expression(expr, stattarget); + idx++; + } + + return exprdata; +} + +/* form an array of pg_statistic rows (per update_attstats) */ +static Datum +serialize_expr_stats(AnlExprData *exprdata, int nexprs) +{ + int exprno; + Oid typOid; + Relation sd; + + ArrayBuildState *astate = NULL; + + sd = table_open(StatisticRelationId, RowExclusiveLock); + + /* lookup OID of composite type for pg_statistic */ + typOid = get_rel_type_id(StatisticRelationId); + if (!OidIsValid(typOid)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("relation \"%s\" does not have a composite type", + "pg_statistic"))); + + for (exprno = 0; exprno < nexprs; exprno++) + { + int i, + k; + VacAttrStats *stats = exprdata[exprno].vacattrstat; + + Datum values[Natts_pg_statistic]; + bool nulls[Natts_pg_statistic]; + HeapTuple stup; + + if (!stats->stats_valid) + { + astate = accumArrayResult(astate, + (Datum) 0, + true, + typOid, + CurrentMemoryContext); + continue; + } + + /* + * Construct a new pg_statistic tuple + */ + for (i = 0; i < Natts_pg_statistic; ++i) + { + nulls[i] = false; + } + + values[Anum_pg_statistic_starelid - 1] = ObjectIdGetDatum(InvalidOid); + values[Anum_pg_statistic_staattnum - 1] = Int16GetDatum(InvalidAttrNumber); + values[Anum_pg_statistic_stainherit - 1] = BoolGetDatum(false); + values[Anum_pg_statistic_stanullfrac - 1] = Float4GetDatum(stats->stanullfrac); + values[Anum_pg_statistic_stawidth - 1] = Int32GetDatum(stats->stawidth); + values[Anum_pg_statistic_stadistinct - 1] = Float4GetDatum(stats->stadistinct); + i = Anum_pg_statistic_stakind1 - 1; + for (k = 0; k < STATISTIC_NUM_SLOTS; k++) + { + values[i++] = Int16GetDatum(stats->stakind[k]); /* stakindN */ + } + i = Anum_pg_statistic_staop1 - 1; + for (k = 0; k < STATISTIC_NUM_SLOTS; k++) + { + values[i++] = ObjectIdGetDatum(stats->staop[k]); /* staopN */ + } + i = Anum_pg_statistic_stacoll1 - 1; + for (k = 0; k < STATISTIC_NUM_SLOTS; k++) + { + values[i++] = ObjectIdGetDatum(stats->stacoll[k]); /* stacollN */ + } + i = Anum_pg_statistic_stanumbers1 - 1; + for (k = 0; k < STATISTIC_NUM_SLOTS; k++) + { + int nnum = stats->numnumbers[k]; + + if (nnum > 0) + { + int n; + Datum *numdatums = (Datum *) palloc(nnum * sizeof(Datum)); + ArrayType *arry; + + for (n = 0; n < nnum; n++) + numdatums[n] = Float4GetDatum(stats->stanumbers[k][n]); + /* XXX knows more than it should about type float4: */ + arry = construct_array(numdatums, nnum, + FLOAT4OID, + sizeof(float4), true, TYPALIGN_INT); + values[i++] = PointerGetDatum(arry); /* stanumbersN */ + } + else + { + nulls[i] = true; + values[i++] = (Datum) 0; + } + } + i = Anum_pg_statistic_stavalues1 - 1; + for (k = 0; k < STATISTIC_NUM_SLOTS; k++) + { + if (stats->numvalues[k] > 0) + { + ArrayType *arry; + + arry = construct_array(stats->stavalues[k], + stats->numvalues[k], + stats->statypid[k], + stats->statyplen[k], + stats->statypbyval[k], + stats->statypalign[k]); + values[i++] = PointerGetDatum(arry); /* stavaluesN */ + } + else + { + nulls[i] = true; + values[i++] = (Datum) 0; + } + } + + stup = heap_form_tuple(RelationGetDescr(sd), values, nulls); + + astate = accumArrayResult(astate, + heap_copy_tuple_as_datum(stup, RelationGetDescr(sd)), + false, + typOid, + CurrentMemoryContext); + } + + table_close(sd, RowExclusiveLock); + + return makeArrayResult(astate, CurrentMemoryContext); +} + +/* + * Loads pg_statistic record from expression statistics for expression + * identified by the supplied index. + */ +HeapTuple +statext_expressions_load(Oid stxoid, int idx) +{ + bool isnull; + Datum value; + HeapTuple htup; + ExpandedArrayHeader *eah; + HeapTupleHeader td; + HeapTupleData tmptup; + HeapTuple tup; + + htup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(stxoid)); + if (!HeapTupleIsValid(htup)) + elog(ERROR, "cache lookup failed for statistics object %u", stxoid); + + value = SysCacheGetAttr(STATEXTDATASTXOID, htup, + Anum_pg_statistic_ext_data_stxdexpr, &isnull); + if (isnull) + elog(ERROR, + "requested statistics kind \"%c\" is not yet built for statistics object %u", + STATS_EXT_DEPENDENCIES, stxoid); + + eah = DatumGetExpandedArray(value); + + deconstruct_expanded_array(eah); + + td = DatumGetHeapTupleHeader(eah->dvalues[idx]); + + /* Build a temporary HeapTuple control structure */ + tmptup.t_len = HeapTupleHeaderGetDatumLength(td); + ItemPointerSetInvalid(&(tmptup.t_self)); + tmptup.t_tableOid = InvalidOid; + tmptup.t_data = td; + + tup = heap_copytuple(&tmptup); + + ReleaseSysCache(htup); + + return tup; +} + +/* + * Evaluate the expressions, so that we can use the results to build + * all the requested statistics types. This matters especially for + * expensive expressions, of course. + */ +static StatsBuildData * +make_build_data(Relation rel, StatExtEntry *stat, int numrows, HeapTuple *rows, + VacAttrStats **stats, int stattarget) +{ + /* evaluated expressions */ + StatsBuildData *result; + char *ptr; + Size len; + + int i; + int k; + int idx; + TupleTableSlot *slot; + EState *estate; + ExprContext *econtext; + List *exprstates = NIL; + int nkeys = bms_num_members(stat->columns) + list_length(stat->exprs); + ListCell *lc; + + /* allocate everything as a single chunk, so we can free it easily */ + len = MAXALIGN(sizeof(StatsBuildData)); + len += MAXALIGN(sizeof(AttrNumber) * nkeys); /* attnums */ + len += MAXALIGN(sizeof(VacAttrStats *) * nkeys); /* stats */ + + /* values */ + len += MAXALIGN(sizeof(Datum *) * nkeys); + len += nkeys * MAXALIGN(sizeof(Datum) * numrows); + + /* nulls */ + len += MAXALIGN(sizeof(bool *) * nkeys); + len += nkeys * MAXALIGN(sizeof(bool) * numrows); + + ptr = palloc(len); + + /* set the pointers */ + result = (StatsBuildData *) ptr; + ptr += MAXALIGN(sizeof(StatsBuildData)); + + /* attnums */ + result->attnums = (AttrNumber *) ptr; + ptr += MAXALIGN(sizeof(AttrNumber) * nkeys); + + /* stats */ + result->stats = (VacAttrStats **) ptr; + ptr += MAXALIGN(sizeof(VacAttrStats *) * nkeys); + + /* values */ + result->values = (Datum **) ptr; + ptr += MAXALIGN(sizeof(Datum *) * nkeys); + + /* nulls */ + result->nulls = (bool **) ptr; + ptr += MAXALIGN(sizeof(bool *) * nkeys); + + for (i = 0; i < nkeys; i++) + { + result->values[i] = (Datum *) ptr; + ptr += MAXALIGN(sizeof(Datum) * numrows); + + result->nulls[i] = (bool *) ptr; + ptr += MAXALIGN(sizeof(bool) * numrows); + } + + Assert((ptr - (char *) result) == len); + + /* we have it allocated, so let's fill the values */ + result->nattnums = nkeys; + result->numrows = numrows; + + /* fill the attribute info - first attributes, then expressions */ + idx = 0; + k = -1; + while ((k = bms_next_member(stat->columns, k)) >= 0) + { + result->attnums[idx] = k; + result->stats[idx] = stats[idx]; + + idx++; + } + + k = -1; + foreach(lc, stat->exprs) + { + Node *expr = (Node *) lfirst(lc); + + result->attnums[idx] = k; + result->stats[idx] = examine_expression(expr, stattarget); + + idx++; + k--; + } + + /* first extract values for all the regular attributes */ + for (i = 0; i < numrows; i++) + { + idx = 0; + k = -1; + while ((k = bms_next_member(stat->columns, k)) >= 0) + { + result->values[idx][i] = heap_getattr(rows[i], k, + result->stats[idx]->tupDesc, + &result->nulls[idx][i]); + + idx++; + } + } + + /* Need an EState for evaluation expressions. */ + estate = CreateExecutorState(); + econtext = GetPerTupleExprContext(estate); + + /* Need a slot to hold the current heap tuple, too */ + slot = MakeSingleTupleTableSlot(RelationGetDescr(rel), + &TTSOpsHeapTuple); + + /* Arrange for econtext's scan tuple to be the tuple under test */ + econtext->ecxt_scantuple = slot; + + /* Set up expression evaluation state */ + exprstates = ExecPrepareExprList(stat->exprs, estate); + + for (i = 0; i < numrows; i++) + { + /* + * Reset the per-tuple context each time, to reclaim any cruft left + * behind by evaluating the statistics object expressions. + */ + ResetExprContext(econtext); + + /* Set up for expression evaluation */ + ExecStoreHeapTuple(rows[i], slot, false); + + idx = bms_num_members(stat->columns); + foreach(lc, exprstates) + { + Datum datum; + bool isnull; + ExprState *exprstate = (ExprState *) lfirst(lc); + + /* + * XXX This probably leaks memory. Maybe we should use + * ExecEvalExprSwitchContext but then we need to copy the result + * somewhere else. + */ + datum = ExecEvalExpr(exprstate, + GetPerTupleExprContext(estate), + &isnull); + if (isnull) + { + result->values[idx][i] = (Datum) 0; + result->nulls[idx][i] = true; + } + else + { + result->values[idx][i] = (Datum) datum; + result->nulls[idx][i] = false; + } + + idx++; + } + } + + ExecDropSingleTupleTableSlot(slot); + FreeExecutorState(estate); + + return result; +} diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c index 6a262f154366..ef118952c74e 100644 --- a/src/backend/statistics/mcv.c +++ b/src/backend/statistics/mcv.c @@ -4,7 +4,7 @@ * POSTGRES multivariate MCV lists * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,6 +32,7 @@ #include "utils/fmgroids.h" #include "utils/fmgrprotos.h" #include "utils/lsyscache.h" +#include "utils/selfuncs.h" #include "utils/syscache.h" #include "utils/typcache.h" @@ -73,7 +74,7 @@ ((ndims) * sizeof(DimensionInfo)) + \ ((nitems) * ITEM_SIZE(ndims))) -static MultiSortSupport build_mss(VacAttrStats **stats, int numattrs); +static MultiSortSupport build_mss(StatsBuildData *data); static SortItem *build_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss, int *ndistinct); @@ -180,40 +181,41 @@ get_mincount_for_mcv_list(int samplerows, double totalrows) * */ MCVList * -statext_mcv_build(int numrows, HeapTuple *rows, Bitmapset *attrs, - VacAttrStats **stats, double totalrows, int stattarget) +statext_mcv_build(StatsBuildData *data, double totalrows, int stattarget) { int i, numattrs, + numrows, ngroups, nitems; - AttrNumber *attnums; double mincount; SortItem *items; SortItem *groups; MCVList *mcvlist = NULL; MultiSortSupport mss; - attnums = build_attnums_array(attrs, &numattrs); - /* comparator for all the columns */ - mss = build_mss(stats, numattrs); + mss = build_mss(data); /* sort the rows */ - items = build_sorted_items(numrows, &nitems, rows, stats[0]->tupDesc, - mss, numattrs, attnums); + items = build_sorted_items(data, &nitems, mss, + data->nattnums, data->attnums); if (!items) return NULL; + /* for convenience */ + numattrs = data->nattnums; + numrows = data->numrows; + /* transform the sorted rows into groups (sorted by frequency) */ groups = build_distinct_groups(nitems, items, mss, &ngroups); /* - * Maximum number of MCV items to store, based on the statistics target we - * computed for the statistics object (from target set for the object - * itself, attributes and the system default). In any case, we can't keep - * more groups than we have available. + * The maximum number of MCV items to store, based on the statistics + * target we computed for the statistics object (from the target set for + * the object itself, attributes and the system default). In any case, we + * can't keep more groups than we have available. */ nitems = stattarget; if (nitems > ngroups) @@ -232,7 +234,7 @@ statext_mcv_build(int numrows, HeapTuple *rows, Bitmapset *attrs, * to consider unexpectedly uncommon items (again, compared to the base * frequency), and the single-column algorithm does not have to. * - * We simply decide how many items to keep by computing minimum count + * We simply decide how many items to keep by computing the minimum count * using get_mincount_for_mcv_list() and then keep all items that seem to * be more common than that. */ @@ -253,9 +255,9 @@ statext_mcv_build(int numrows, HeapTuple *rows, Bitmapset *attrs, } /* - * At this point we know the number of items for the MCV list. There might - * be none (for uniform distribution with many groups), and in that case - * there will be no MCV list. Otherwise construct the MCV list. + * At this point, we know the number of items for the MCV list. There + * might be none (for uniform distribution with many groups), and in that + * case, there will be no MCV list. Otherwise, construct the MCV list. */ if (nitems > 0) { @@ -288,7 +290,7 @@ statext_mcv_build(int numrows, HeapTuple *rows, Bitmapset *attrs, /* store info about data type OIDs */ for (i = 0; i < numattrs; i++) - mcvlist->types[i] = stats[i]->attrtypid; + mcvlist->types[i] = data->stats[i]->attrtypid; /* Copy the first chunk of groups into the result. */ for (i = 0; i < nitems; i++) @@ -343,12 +345,13 @@ statext_mcv_build(int numrows, HeapTuple *rows, Bitmapset *attrs, /* * build_mss - * build MultiSortSupport for the attributes passed in attrs + * Build a MultiSortSupport for the given StatsBuildData. */ static MultiSortSupport -build_mss(VacAttrStats **stats, int numattrs) +build_mss(StatsBuildData *data) { int i; + int numattrs = data->nattnums; /* Sort by multiple columns (using array of SortSupport) */ MultiSortSupport mss = multi_sort_init(numattrs); @@ -356,7 +359,7 @@ build_mss(VacAttrStats **stats, int numattrs) /* prepare the sort functions for all the attributes */ for (i = 0; i < numattrs; i++) { - VacAttrStats *colstat = stats[i]; + VacAttrStats *colstat = data->stats[i]; TypeCacheEntry *type; type = lookup_type_cache(colstat->attrtypid, TYPECACHE_LT_OPR); @@ -372,7 +375,7 @@ build_mss(VacAttrStats **stats, int numattrs) /* * count_distinct_groups - * count distinct combinations of SortItems in the array + * Count distinct combinations of SortItems in the array. * * The array is assumed to be sorted according to the MultiSortSupport. */ @@ -397,7 +400,8 @@ count_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss) /* * compare_sort_item_count - * comparator for sorting items by count (frequencies) in descending order + * Comparator for sorting items by count (frequencies) in descending + * order. */ static int compare_sort_item_count(const void *a, const void *b) @@ -415,9 +419,10 @@ compare_sort_item_count(const void *a, const void *b) /* * build_distinct_groups - * build an array of SortItems for distinct groups and counts matching items + * Build an array of SortItems for distinct groups and counts matching + * items. * - * The input array is assumed to be sorted + * The 'items' array is assumed to be sorted. */ static SortItem * build_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss, @@ -474,7 +479,7 @@ sort_item_compare(const void *a, const void *b, void *arg) /* * build_column_frequencies - * compute frequencies of values in each column + * Compute frequencies of values in each column. * * This returns an array of SortItems for each attribute the MCV is built * on, with a frequency (number of occurrences) for each value. This is @@ -551,7 +556,7 @@ build_column_frequencies(SortItem *groups, int ngroups, /* * statext_mcv_load - * Load the MCV list for the indicated pg_statistic_ext tuple + * Load the MCV list for the indicated pg_statistic_ext tuple. */ MCVList * statext_mcv_load(Oid mvoid) @@ -569,7 +574,7 @@ statext_mcv_load(Oid mvoid) if (isnull) elog(ERROR, - "requested statistic kind \"%c\" is not yet built for statistics object %u", + "requested statistics kind \"%c\" is not yet built for statistics object %u", STATS_EXT_DEPENDENCIES, mvoid); result = statext_mcv_deserialize(DatumGetByteaP(mcvlist)); @@ -595,10 +600,11 @@ statext_mcv_load(Oid mvoid) * | header fields | dimension info | deduplicated values | items | * +---------------+----------------+---------------------+-------+ * - * Where dimension info stores information about type of K-th attribute (e.g. - * typlen, typbyval and length of deduplicated values). Deduplicated values - * store deduplicated values for each attribute. And items store the actual - * MCV list items, with values replaced by indexes into the arrays. + * Where dimension info stores information about the type of the K-th + * attribute (e.g. typlen, typbyval and length of deduplicated values). + * Deduplicated values store deduplicated values for each attribute. And + * items store the actual MCV list items, with values replaced by indexes into + * the arrays. * * When serializing the items, we use uint16 indexes. The number of MCV items * is limited by the statistics target (which is capped to 10k at the moment). @@ -638,10 +644,10 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats) /* * We'll include some rudimentary information about the attribute types * (length, by-val flag), so that we don't have to look them up while - * deserializating the MCV list (we already have the type OID in the - * header). This is safe, because when changing type of the attribute the - * statistics gets dropped automatically. We need to store the info about - * the arrays of deduplicated values anyway. + * deserializing the MCV list (we already have the type OID in the + * header). This is safe because when changing the type of the attribute + * the statistics gets dropped automatically. We need to store the info + * about the arrays of deduplicated values anyway. */ info = (DimensionInfo *) palloc0(sizeof(DimensionInfo) * ndims); @@ -694,8 +700,8 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats) /* * Walk through the array and eliminate duplicate values, but keep the - * ordering (so that we can do bsearch later). We know there's at - * least one item as (counts[dim] != 0), so we can skip the first + * ordering (so that we can do a binary search later). We know there's + * at least one item as (counts[dim] != 0), so we can skip the first * element. */ ndistinct = 1; /* number of distinct values */ @@ -784,10 +790,10 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats) Size len; /* - * For cstring, we do similar thing as for varlena - first we - * store the length as uint32 and then the data. We don't care - * about alignment, which means that during deserialization we - * need to copy the fields and only access the copies. + * cstring is handled similar to varlena - first we store the + * length as uint32 and then the data. We don't care about + * alignment, which means that during deserialization we need + * to copy the fields and only access the copies. */ /* c-strings include terminator, so +1 byte */ @@ -871,13 +877,13 @@ statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats) Datum tmp; /* - * For values passed by value, we need to copy just the - * significant bytes - we can't use memcpy directly, as that - * assumes little endian behavior. store_att_byval does - * almost what we need, but it requires properly aligned - * buffer - the output buffer does not guarantee that. So we - * simply use a local Datum variable (which guarantees proper - * alignment), and then copy the value from it. + * For byval types, we need to copy just the significant bytes + * - we can't use memcpy directly, as that assumes + * little-endian behavior. store_att_byval does almost what + * we need, but it requires a properly aligned buffer - the + * output buffer does not guarantee that. So we simply use a + * local Datum variable (which guarantees proper alignment), + * and then copy the value from it. */ store_att_byval(&tmp, value, info[dim].typlen); @@ -1522,6 +1528,61 @@ pg_mcv_list_send(PG_FUNCTION_ARGS) return byteasend(fcinfo); } +/* + * match the attribute/expression to a dimension of the statistic + * + * Match the attribute/expression to statistics dimension. Optionally + * determine the collation. + */ +static int +mcv_match_expression(Node *expr, Bitmapset *keys, List *exprs, Oid *collid) +{ + int idx = -1; + + if (IsA(expr, Var)) + { + /* simple Var, so just lookup using varattno */ + Var *var = (Var *) expr; + + if (collid) + *collid = var->varcollid; + + idx = bms_member_index(keys, var->varattno); + + /* make sure the index is valid */ + Assert((idx >= 0) && (idx <= bms_num_members(keys))); + } + else + { + ListCell *lc; + + /* expressions are stored after the simple columns */ + idx = bms_num_members(keys); + + if (collid) + *collid = exprCollation(expr); + + /* expression - lookup in stats expressions */ + foreach(lc, exprs) + { + Node *stat_expr = (Node *) lfirst(lc); + + if (equal(expr, stat_expr)) + break; + + idx++; + } + + /* make sure the index is valid */ + Assert((idx >= bms_num_members(keys)) && + (idx <= bms_num_members(keys) + list_length(exprs))); + } + + Assert((idx >= 0) && (idx < bms_num_members(keys) + list_length(exprs))); + + return idx; +} + /* * mcv_get_match_bitmap * Evaluate clauses using the MCV list, and update the match bitmap. @@ -1543,7 +1604,8 @@ pg_mcv_list_send(PG_FUNCTION_ARGS) */ static bool * mcv_get_match_bitmap(PlannerInfo *root, List *clauses, - Bitmapset *keys, MCVList *mcvlist, bool is_or) + Bitmapset *keys, List *exprs, + MCVList *mcvlist, bool is_or) { int i; ListCell *l; @@ -1581,77 +1643,80 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses, OpExpr *expr = (OpExpr *) clause; FmgrInfo opproc; - /* valid only after examine_clause_args returns true */ - Var *var; + /* valid only after examine_opclause_args returns true */ + Node *clause_expr; Const *cst; - bool varonleft; + bool expronleft; + int idx; + Oid collid; fmgr_info(get_opcode(expr->opno), &opproc); - /* extract the var and const from the expression */ - if (examine_clause_args(expr->args, &var, &cst, &varonleft)) + /* extract the var/expr and const from the expression */ + if (!examine_opclause_args(expr->args, &clause_expr, &cst, &expronleft)) + elog(ERROR, "incompatible clause"); + + /* match the attribute/expression to a dimension of the statistic */ + idx = mcv_match_expression(clause_expr, keys, exprs, &collid); + + Assert((idx >= 0) && (idx < bms_num_members(keys) + list_length(exprs))); + + /* + * Walk through the MCV items and evaluate the current clause. We + * can skip items that were already ruled out, and terminate if + * there are no remaining MCV items that might possibly match. + */ + for (i = 0; i < mcvlist->nitems; i++) { - int idx; + bool match = true; + MCVItem *item = &mcvlist->items[i]; - /* match the attribute to a dimension of the statistic */ - idx = bms_member_index(keys, var->varattno); + Assert(idx >= 0); /* - * Walk through the MCV items and evaluate the current clause. - * We can skip items that were already ruled out, and - * terminate if there are no remaining MCV items that might - * possibly match. + * When the MCV item or the Const value is NULL we can treat + * this as a mismatch. We must not call the operator because + * of strictness. */ - for (i = 0; i < mcvlist->nitems; i++) + if (item->isnull[idx] || cst->constisnull) { - bool match = true; - MCVItem *item = &mcvlist->items[i]; - - /* - * When the MCV item or the Const value is NULL we can - * treat this as a mismatch. We must not call the operator - * because of strictness. - */ - if (item->isnull[idx] || cst->constisnull) - { - matches[i] = RESULT_MERGE(matches[i], is_or, false); - continue; - } + matches[i] = RESULT_MERGE(matches[i], is_or, false); + continue; + } - /* - * Skip MCV items that can't change result in the bitmap. - * Once the value gets false for AND-lists, or true for - * OR-lists, we don't need to look at more clauses. - */ - if (RESULT_IS_FINAL(matches[i], is_or)) - continue; + /* + * Skip MCV items that can't change result in the bitmap. Once + * the value gets false for AND-lists, or true for OR-lists, + * we don't need to look at more clauses. + */ + if (RESULT_IS_FINAL(matches[i], is_or)) + continue; - /* - * First check whether the constant is below the lower - * boundary (in that case we can skip the bucket, because - * there's no overlap). - * - * We don't store collations used to build the statistics, - * but we can use the collation for the attribute itself, - * as stored in varcollid. We do reset the statistics - * after a type change (including collation change), so - * this is OK. We may need to relax this after allowing - * extended statistics on expressions. - */ - if (varonleft) - match = DatumGetBool(FunctionCall2Coll(&opproc, - var->varcollid, - item->values[idx], - cst->constvalue)); - else - match = DatumGetBool(FunctionCall2Coll(&opproc, - var->varcollid, - cst->constvalue, - item->values[idx])); - - /* update the match bitmap with the result */ - matches[i] = RESULT_MERGE(matches[i], is_or, match); - } + /* + * First check whether the constant is below the lower + * boundary (in that case we can skip the bucket, because + * there's no overlap). + * + * We don't store collations used to build the statistics, but + * we can use the collation for the attribute itself, as + * stored in varcollid. We do reset the statistics after a + * type change (including collation change), so this is OK. + * For expressions, we use the collation extracted from the + * expression itself. + */ + if (expronleft) + match = DatumGetBool(FunctionCall2Coll(&opproc, + collid, + item->values[idx], + cst->constvalue)); + else + match = DatumGetBool(FunctionCall2Coll(&opproc, + collid, + cst->constvalue, + item->values[idx])); + + /* update the match bitmap with the result */ + matches[i] = RESULT_MERGE(matches[i], is_or, match); } } else if (IsA(clause, ScalarArrayOpExpr)) @@ -1659,115 +1724,116 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses, ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) clause; FmgrInfo opproc; - /* valid only after examine_clause_args returns true */ - Var *var; + /* valid only after examine_opclause_args returns true */ + Node *clause_expr; Const *cst; - bool varonleft; + bool expronleft; + Oid collid; + int idx; + + /* array evaluation */ + ArrayType *arrayval; + int16 elmlen; + bool elmbyval; + char elmalign; + int num_elems; + Datum *elem_values; + bool *elem_nulls; fmgr_info(get_opcode(expr->opno), &opproc); - /* extract the var and const from the expression */ - if (examine_clause_args(expr->args, &var, &cst, &varonleft)) + /* extract the var/expr and const from the expression */ + if (!examine_opclause_args(expr->args, &clause_expr, &cst, &expronleft)) + elog(ERROR, "incompatible clause"); + + /* ScalarArrayOpExpr has the Var always on the left */ + Assert(expronleft); + + /* XXX what if (cst->constisnull == NULL)? */ + if (!cst->constisnull) { - int idx; + arrayval = DatumGetArrayTypeP(cst->constvalue); + get_typlenbyvalalign(ARR_ELEMTYPE(arrayval), + &elmlen, &elmbyval, &elmalign); + deconstruct_array(arrayval, + ARR_ELEMTYPE(arrayval), + elmlen, elmbyval, elmalign, + &elem_values, &elem_nulls, &num_elems); + } - ArrayType *arrayval; - int16 elmlen; - bool elmbyval; - char elmalign; - int num_elems; - Datum *elem_values; - bool *elem_nulls; + /* match the attribute/expression to a dimension of the statistic */ + idx = mcv_match_expression(clause_expr, keys, exprs, &collid); - /* ScalarArrayOpExpr has the Var always on the left */ - Assert(varonleft); + /* + * Walk through the MCV items and evaluate the current clause. We + * can skip items that were already ruled out, and terminate if + * there are no remaining MCV items that might possibly match. + */ + for (i = 0; i < mcvlist->nitems; i++) + { + int j; + bool match = (expr->useOr ? false : true); + MCVItem *item = &mcvlist->items[i]; - if (!cst->constisnull) + /* + * When the MCV item or the Const value is NULL we can treat + * this as a mismatch. We must not call the operator because + * of strictness. + */ + if (item->isnull[idx] || cst->constisnull) { - arrayval = DatumGetArrayTypeP(cst->constvalue); - get_typlenbyvalalign(ARR_ELEMTYPE(arrayval), - &elmlen, &elmbyval, &elmalign); - deconstruct_array(arrayval, - ARR_ELEMTYPE(arrayval), - elmlen, elmbyval, elmalign, - &elem_values, &elem_nulls, &num_elems); + matches[i] = RESULT_MERGE(matches[i], is_or, false); + continue; } - /* match the attribute to a dimension of the statistic */ - idx = bms_member_index(keys, var->varattno); - /* - * Walk through the MCV items and evaluate the current clause. - * We can skip items that were already ruled out, and - * terminate if there are no remaining MCV items that might - * possibly match. + * Skip MCV items that can't change result in the bitmap. Once + * the value gets false for AND-lists, or true for OR-lists, + * we don't need to look at more clauses. */ - for (i = 0; i < mcvlist->nitems; i++) + if (RESULT_IS_FINAL(matches[i], is_or)) + continue; + + for (j = 0; j < num_elems; j++) { - int j; - bool match = (expr->useOr ? false : true); - MCVItem *item = &mcvlist->items[i]; + Datum elem_value = elem_values[j]; + bool elem_isnull = elem_nulls[j]; + bool elem_match; - /* - * When the MCV item or the Const value is NULL we can - * treat this as a mismatch. We must not call the operator - * because of strictness. - */ - if (item->isnull[idx] || cst->constisnull) + /* NULL values always evaluate as not matching. */ + if (elem_isnull) { - matches[i] = RESULT_MERGE(matches[i], is_or, false); + match = RESULT_MERGE(match, expr->useOr, false); continue; } /* - * Skip MCV items that can't change result in the bitmap. - * Once the value gets false for AND-lists, or true for - * OR-lists, we don't need to look at more clauses. + * Stop evaluating the array elements once we reach a + * matching value that can't change - ALL() is the same as + * AND-list, ANY() is the same as OR-list. */ - if (RESULT_IS_FINAL(matches[i], is_or)) - continue; + if (RESULT_IS_FINAL(match, expr->useOr)) + break; - for (j = 0; j < num_elems; j++) - { - Datum elem_value = elem_values[j]; - bool elem_isnull = elem_nulls[j]; - bool elem_match; - - /* NULL values always evaluate as not matching. */ - if (elem_isnull) - { - match = RESULT_MERGE(match, expr->useOr, false); - continue; - } - - /* - * Stop evaluating the array elements once we reach - * match value that can't change - ALL() is the same - * as AND-list, ANY() is the same as OR-list. - */ - if (RESULT_IS_FINAL(match, expr->useOr)) - break; - - elem_match = DatumGetBool(FunctionCall2Coll(&opproc, - var->varcollid, - item->values[idx], - elem_value)); - - match = RESULT_MERGE(match, expr->useOr, elem_match); - } + elem_match = DatumGetBool(FunctionCall2Coll(&opproc, + collid, + item->values[idx], + elem_value)); - /* update the match bitmap with the result */ - matches[i] = RESULT_MERGE(matches[i], is_or, match); + match = RESULT_MERGE(match, expr->useOr, elem_match); } + + /* update the match bitmap with the result */ + matches[i] = RESULT_MERGE(matches[i], is_or, match); } } else if (IsA(clause, NullTest)) { NullTest *expr = (NullTest *) clause; - Var *var = (Var *) (expr->arg); + Node *clause_expr = (Node *) (expr->arg); - /* match the attribute to a dimension of the statistic */ - int idx = bms_member_index(keys, var->varattno); + /* match the attribute/expression to a dimension of the statistic */ + int idx = mcv_match_expression(clause_expr, keys, exprs, NULL); /* * Walk through the MCV items and evaluate the current clause. We @@ -1810,7 +1876,7 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses, Assert(list_length(bool_clauses) >= 2); /* build the match bitmap for the OR-clauses */ - bool_matches = mcv_get_match_bitmap(root, bool_clauses, keys, + bool_matches = mcv_get_match_bitmap(root, bool_clauses, keys, exprs, mcvlist, is_orclause(clause)); /* @@ -1838,7 +1904,7 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses, Assert(list_length(not_args) == 1); /* build the match bitmap for the NOT-clause */ - not_matches = mcv_get_match_bitmap(root, not_args, keys, + not_matches = mcv_get_match_bitmap(root, not_args, keys, exprs, mcvlist, false); /* @@ -1888,16 +1954,80 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses, } +/* + * mcv_combine_selectivities + * Combine per-column and multi-column MCV selectivity estimates. + * + * simple_sel is a "simple" selectivity estimate (produced without using any + * extended statistics, essentially assuming independence of columns/clauses). + * + * mcv_sel and mcv_basesel are sums of the frequencies and base frequencies of + * all matching MCV items. The difference (mcv_sel - mcv_basesel) is then + * essentially interpreted as a correction to be added to simple_sel, as + * described below. + * + * mcv_totalsel is the sum of the frequencies of all MCV items (not just the + * matching ones). This is used as an upper bound on the portion of the + * selectivity estimates not covered by the MCV statistics. + * + * Note: While simple and base selectivities are defined in a quite similar + * way, the values are computed differently and are not therefore equal. The + * simple selectivity is computed as a product of per-clause estimates, while + * the base selectivity is computed by adding up base frequencies of matching + * items of the multi-column MCV list. So the values may differ for two main + * reasons - (a) the MCV list may not cover 100% of the data and (b) some of + * the MCV items did not match the estimated clauses. + * + * As both (a) and (b) reduce the base selectivity value, it generally holds + * that (simple_sel >= mcv_basesel). If the MCV list covers all the data, the + * values may be equal. + * + * So, other_sel = (simple_sel - mcv_basesel) is an estimate for the part not + * covered by the MCV list, and (mcv_sel - mcv_basesel) may be seen as a + * correction for the part covered by the MCV list. Those two statements are + * actually equivalent. + */ +Selectivity +mcv_combine_selectivities(Selectivity simple_sel, + Selectivity mcv_sel, + Selectivity mcv_basesel, + Selectivity mcv_totalsel) +{ + Selectivity other_sel; + Selectivity sel; + + /* estimated selectivity of values not covered by MCV matches */ + other_sel = simple_sel - mcv_basesel; + CLAMP_PROBABILITY(other_sel); + + /* this non-MCV selectivity cannot exceed 1 - mcv_totalsel */ + if (other_sel > 1.0 - mcv_totalsel) + other_sel = 1.0 - mcv_totalsel; + + /* overall selectivity is the sum of the MCV and non-MCV parts */ + sel = mcv_sel + other_sel; + CLAMP_PROBABILITY(sel); + + return sel; +} + + /* * mcv_clauselist_selectivity - * Return the selectivity estimate computed using an MCV list. + * Use MCV statistics to estimate the selectivity of an implicitly-ANDed + * list of clauses. * - * First builds a bitmap of MCV items matching the clauses, and then sums - * the frequencies of matching items. + * This determines which MCV items match every clause in the list and returns + * the sum of the frequencies of those items. * - * It also produces two additional interesting selectivities - total - * selectivity of all the MCV items (not just the matching ones), and the - * base frequency computed on the assumption of independence. + * In addition, it returns the sum of the base frequencies of each of those + * items (that is the sum of the selectivities that each item would have if + * the columns were independent of one another), and the total selectivity of + * all the MCV items (not just the matching ones). These are expected to be + * used together with a "simple" selectivity estimate (one based only on + * per-column statistics) to produce an overall selectivity estimate that + * makes use of both per-column and multi-column statistics --- see + * mcv_combine_selectivities(). */ Selectivity mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, @@ -1917,7 +2047,8 @@ mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, mcv = statext_mcv_load(stat->statOid); /* build a match bitmap for the clauses */ - matches = mcv_get_match_bitmap(root, clauses, stat->keys, mcv, false); + matches = mcv_get_match_bitmap(root, clauses, stat->keys, stat->exprs, + mcv, false); /* sum frequencies for all the matching MCV items */ *basesel = 0.0; @@ -1928,7 +2059,6 @@ mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, if (matches[i] != false) { - /* XXX Shouldn't the basesel be outside the if condition? */ *basesel += mcv->items[i].base_frequency; s += mcv->items[i].frequency; } @@ -1936,3 +2066,94 @@ mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, return s; } + + +/* + * mcv_clause_selectivity_or + * Use MCV statistics to estimate the selectivity of a clause that + * appears in an ORed list of clauses. + * + * As with mcv_clauselist_selectivity() this determines which MCV items match + * the clause and returns both the sum of the frequencies and the sum of the + * base frequencies of those items, as well as the sum of the frequencies of + * all MCV items (not just the matching ones) so that this information can be + * used by mcv_combine_selectivities() to produce a selectivity estimate that + * makes use of both per-column and multi-column statistics. + * + * Additionally, we return information to help compute the overall selectivity + * of the ORed list of clauses assumed to contain this clause. This function + * is intended to be called for each clause in the ORed list of clauses, + * allowing the overall selectivity to be computed using the following + * algorithm: + * + * Suppose P[n] = P(C[1] OR C[2] OR ... OR C[n]) is the combined selectivity + * of the first n clauses in the list. Then the combined selectivity taking + * into account the next clause C[n+1] can be written as + * + * P[n+1] = P[n] + P(C[n+1]) - P((C[1] OR ... OR C[n]) AND C[n+1]) + * + * The final term above represents the overlap between the clauses examined so + * far and the (n+1)'th clause. To estimate its selectivity, we track the + * match bitmap for the ORed list of clauses examined so far and examine its + * intersection with the match bitmap for the (n+1)'th clause. + * + * We then also return the sums of the MCV item frequencies and base + * frequencies for the match bitmap intersection corresponding to the overlap + * term above, so that they can be combined with a simple selectivity estimate + * for that term. + * + * The parameter "or_matches" is an in/out parameter tracking the match bitmap + * for the clauses examined so far. The caller is expected to set it to NULL + * the first time it calls this function. + */ +Selectivity +mcv_clause_selectivity_or(PlannerInfo *root, StatisticExtInfo *stat, + MCVList *mcv, Node *clause, bool **or_matches, + Selectivity *basesel, Selectivity *overlap_mcvsel, + Selectivity *overlap_basesel, Selectivity *totalsel) +{ + Selectivity s = 0.0; + bool *new_matches; + int i; + + /* build the OR-matches bitmap, if not built already */ + if (*or_matches == NULL) + *or_matches = palloc0(sizeof(bool) * mcv->nitems); + + /* build the match bitmap for the new clause */ + new_matches = mcv_get_match_bitmap(root, list_make1(clause), stat->keys, + stat->exprs, mcv, false); + + /* + * Sum the frequencies for all the MCV items matching this clause and also + * those matching the overlap between this clause and any of the preceding + * clauses as described above. + */ + *basesel = 0.0; + *overlap_mcvsel = 0.0; + *overlap_basesel = 0.0; + *totalsel = 0.0; + for (i = 0; i < mcv->nitems; i++) + { + *totalsel += mcv->items[i].frequency; + + if (new_matches[i]) + { + s += mcv->items[i].frequency; + *basesel += mcv->items[i].base_frequency; + + if ((*or_matches)[i]) + { + *overlap_mcvsel += mcv->items[i].frequency; + *overlap_basesel += mcv->items[i].base_frequency; + } + } + + /* update the OR-matches bitmap for the next clause */ + (*or_matches)[i] = (*or_matches)[i] || new_matches[i]; + } + + pfree(new_matches); + + return s; +} diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c index 4b86f0ab2d13..4481312d61d3 100644 --- a/src/backend/statistics/mvdistinct.c +++ b/src/backend/statistics/mvdistinct.c @@ -13,7 +13,7 @@ * estimates are already available in pg_statistic. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -36,8 +36,7 @@ #include "utils/syscache.h" #include "utils/typcache.h" -static double ndistinct_for_combination(double totalrows, int numrows, - HeapTuple *rows, VacAttrStats **stats, +static double ndistinct_for_combination(double totalrows, StatsBuildData *data, int k, int *combination); static double estimate_ndistinct(double totalrows, int numrows, int d, int f1); static int n_choose_k(int n, int k); @@ -81,15 +80,18 @@ static void generate_combinations(CombinationGenerator *state); * * This computes the ndistinct estimate using the same estimator used * in analyze.c and then computes the coefficient. + * + * To handle expressions easily, we treat them as system attributes with + * negative attnums, and offset everything by number of expressions to + * allow using Bitmapsets. */ MVNDistinct * -statext_ndistinct_build(double totalrows, int numrows, HeapTuple *rows, - Bitmapset *attrs, VacAttrStats **stats) +statext_ndistinct_build(double totalrows, StatsBuildData *data) { MVNDistinct *result; int k; int itemcnt; - int numattrs = bms_num_members(attrs); + int numattrs = data->nattnums; int numcombs = num_combinations(numattrs); result = palloc(offsetof(MVNDistinct, items) + @@ -112,13 +114,19 @@ statext_ndistinct_build(double totalrows, int numrows, HeapTuple *rows, MVNDistinctItem *item = &result->items[itemcnt]; int j; - item->attrs = NULL; + item->attributes = palloc(sizeof(AttrNumber) * k); + item->nattributes = k; + + /* translate the indexes to attnums */ for (j = 0; j < k; j++) - item->attrs = bms_add_member(item->attrs, - stats[combination[j]]->attr->attnum); + { + item->attributes[j] = data->attnums[combination[j]]; + + Assert(AttributeNumberIsValid(item->attributes[j])); + } + item->ndistinct = - ndistinct_for_combination(totalrows, numrows, rows, - stats, k, combination); + ndistinct_for_combination(totalrows, data, k, combination); itemcnt++; Assert(itemcnt <= result->nitems); @@ -153,7 +161,7 @@ statext_ndistinct_load(Oid mvoid) Anum_pg_statistic_ext_data_stxdndistinct, &isnull); if (isnull) elog(ERROR, - "requested statistic kind \"%c\" is not yet built for statistics object %u", + "requested statistics kind \"%c\" is not yet built for statistics object %u", STATS_EXT_NDISTINCT, mvoid); result = statext_ndistinct_deserialize(DatumGetByteaPP(ndist)); @@ -189,7 +197,7 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct) { int nmembers; - nmembers = bms_num_members(ndistinct->items[i].attrs); + nmembers = ndistinct->items[i].nattributes; Assert(nmembers >= 2); len += SizeOfItem(nmembers); @@ -214,22 +222,15 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct) for (i = 0; i < ndistinct->nitems; i++) { MVNDistinctItem item = ndistinct->items[i]; - int nmembers = bms_num_members(item.attrs); - int x; + int nmembers = item.nattributes; memcpy(tmp, &item.ndistinct, sizeof(double)); tmp += sizeof(double); memcpy(tmp, &nmembers, sizeof(int)); tmp += sizeof(int); - x = -1; - while ((x = bms_next_member(item.attrs, x)) >= 0) - { - AttrNumber value = (AttrNumber) x; - - memcpy(tmp, &value, sizeof(AttrNumber)); - tmp += sizeof(AttrNumber); - } + memcpy(tmp, item.attributes, sizeof(AttrNumber) * nmembers); + tmp += nmembers * sizeof(AttrNumber); /* protect against overflows */ Assert(tmp <= ((char *) output + len)); @@ -301,27 +302,21 @@ statext_ndistinct_deserialize(bytea *data) for (i = 0; i < ndistinct->nitems; i++) { MVNDistinctItem *item = &ndistinct->items[i]; - int nelems; - - item->attrs = NULL; /* ndistinct value */ memcpy(&item->ndistinct, tmp, sizeof(double)); tmp += sizeof(double); /* number of attributes */ - memcpy(&nelems, tmp, sizeof(int)); + memcpy(&item->nattributes, tmp, sizeof(int)); tmp += sizeof(int); - Assert((nelems >= 2) && (nelems <= STATS_MAX_DIMENSIONS)); + Assert((item->nattributes >= 2) && (item->nattributes <= STATS_MAX_DIMENSIONS)); - while (nelems-- > 0) - { - AttrNumber attno; + item->attributes + = (AttrNumber *) palloc(item->nattributes * sizeof(AttrNumber)); - memcpy(&attno, tmp, sizeof(AttrNumber)); - tmp += sizeof(AttrNumber); - item->attrs = bms_add_member(item->attrs, attno); - } + memcpy(item->attributes, tmp, sizeof(AttrNumber) * item->nattributes); + tmp += sizeof(AttrNumber) * item->nattributes; /* still within the bytea */ Assert(tmp <= ((char *) data + VARSIZE_ANY(data))); @@ -369,17 +364,17 @@ pg_ndistinct_out(PG_FUNCTION_ARGS) for (i = 0; i < ndist->nitems; i++) { + int j; MVNDistinctItem item = ndist->items[i]; - int x = -1; - bool first = true; if (i > 0) appendStringInfoString(&str, ", "); - while ((x = bms_next_member(item.attrs, x)) >= 0) + for (j = 0; j < item.nattributes; j++) { - appendStringInfo(&str, "%s%d", first ? "\"" : ", ", x); - first = false; + AttrNumber attnum = item.attributes[j]; + + appendStringInfo(&str, "%s%d", (j == 0) ? "\"" : ", ", attnum); } appendStringInfo(&str, "\": %d", (int) item.ndistinct); } @@ -427,8 +422,8 @@ pg_ndistinct_send(PG_FUNCTION_ARGS) * combination of multiple columns. */ static double -ndistinct_for_combination(double totalrows, int numrows, HeapTuple *rows, - VacAttrStats **stats, int k, int *combination) +ndistinct_for_combination(double totalrows, StatsBuildData *data, + int k, int *combination) { int i, j; @@ -439,6 +434,7 @@ ndistinct_for_combination(double totalrows, int numrows, HeapTuple *rows, Datum *values; SortItem *items; MultiSortSupport mss; + int numrows = data->numrows; mss = multi_sort_init(k); @@ -467,25 +463,27 @@ ndistinct_for_combination(double totalrows, int numrows, HeapTuple *rows, */ for (i = 0; i < k; i++) { - VacAttrStats *colstat = stats[combination[i]]; + Oid typid; TypeCacheEntry *type; + Oid collid = InvalidOid; + VacAttrStats *colstat = data->stats[combination[i]]; + + typid = colstat->attrtypid; + collid = colstat->attrcollid; - type = lookup_type_cache(colstat->attrtypid, TYPECACHE_LT_OPR); + type = lookup_type_cache(typid, TYPECACHE_LT_OPR); if (type->lt_opr == InvalidOid) /* shouldn't happen */ elog(ERROR, "cache lookup failed for ordering operator for type %u", - colstat->attrtypid); + typid); /* prepare the sort function for this dimension */ - multi_sort_add_dimension(mss, i, type->lt_opr, colstat->attrcollid); + multi_sort_add_dimension(mss, i, type->lt_opr, collid); /* accumulate all the data for this dimension into the arrays */ for (j = 0; j < numrows; j++) { - items[j].values[i] = - heap_getattr(rows[j], - colstat->attr->attnum, - colstat->tupDesc, - &items[j].isnull[i]); + items[j].values[i] = data->values[combination[i]][j]; + items[j].isnull[i] = data->nulls[combination[i]][j]; } } diff --git a/src/backend/storage/buffer/README b/src/backend/storage/buffer/README index bc80777bb106..a775276ff2ce 100644 --- a/src/backend/storage/buffer/README +++ b/src/backend/storage/buffer/README @@ -145,14 +145,11 @@ held within the buffer. Each buffer header also contains an LWLock, the "buffer content lock", that *does* represent the right to access the data in the buffer. It is used per the rules above. -There is yet another set of per-buffer LWLocks, the io_in_progress locks, -that are used to wait for I/O on a buffer to complete. The process doing -a read or write takes exclusive lock for the duration, and processes that -need to wait for completion try to take shared locks (which they release -immediately upon obtaining). XXX on systems where an LWLock represents -nontrivial resources, it's fairly annoying to need so many locks. Possibly -we could use per-backend LWLocks instead (a buffer header would then contain -a field to show which backend is doing its I/O). +* The BM_IO_IN_PROGRESS flag acts as a kind of lock, used to wait for I/O on a +buffer to complete (and in releases before 14, it was accompanied by a +per-buffer LWLock). The process doing a read or write sets the flag for the +duration, and processes that need to wait for it to be cleared sleep on a +condition variable. Normal Buffer Replacement Strategy diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index 5fd463d287b8..1afd0519ca8e 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -3,7 +3,7 @@ * buf_init.c * buffer manager initialization routines * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,7 +26,7 @@ BufferDescPadded *BufferDescriptors; char *BufferBlocks; -LWLockMinimallyPadded *BufferIOLWLockArray = NULL; +ConditionVariableMinimallyPadded *BufferIOCVArray; WritebackContext BackendWritebackContext; CkptSortItem *CkptBufferIds; @@ -97,7 +97,7 @@ InitBufferPool(void) { bool foundBufs, foundDescs, - foundIOLocks, + foundIOCV, foundBufCkpt; /* Align descriptors to a cacheline boundary. */ @@ -110,11 +110,11 @@ InitBufferPool(void) ShmemInitStruct("Buffer Blocks", NBuffers * (Size) BLCKSZ, &foundBufs); - /* Align lwlocks to cacheline boundary */ - BufferIOLWLockArray = (LWLockMinimallyPadded *) - ShmemInitStruct("Buffer IO Locks", - NBuffers * (Size) sizeof(LWLockMinimallyPadded), - &foundIOLocks); + /* Align condition variables to cacheline boundary. */ + BufferIOCVArray = (ConditionVariableMinimallyPadded *) + ShmemInitStruct("Buffer IO Condition Variables", + NBuffers * sizeof(ConditionVariableMinimallyPadded), + &foundIOCV); /* * The array used to sort to-be-checkpointed buffer ids is located in @@ -127,10 +127,10 @@ InitBufferPool(void) ShmemInitStruct("Checkpoint BufferIds", NBuffers * sizeof(CkptSortItem), &foundBufCkpt); - if (foundDescs || foundBufs || foundIOLocks || foundBufCkpt) + if (foundDescs || foundBufs || foundIOCV || foundBufCkpt) { /* should find all of these, or none of them */ - Assert(foundDescs && foundBufs && foundIOLocks && foundBufCkpt); + Assert(foundDescs && foundBufs && foundIOCV && foundBufCkpt); /* note: this path is only taken in EXEC_BACKEND case */ } else @@ -160,8 +160,7 @@ InitBufferPool(void) LWLockInitialize(BufferDescriptorGetContentLock(buf), LWTRANCHE_BUFFER_CONTENT); - LWLockInitialize(BufferDescriptorGetIOLock(buf), - LWTRANCHE_BUFFER_IO); + ConditionVariableInit(BufferDescriptorGetIOCV(buf)); } /* Correct last entry of linked list */ @@ -202,16 +201,9 @@ BufferShmemSize(void) /* size of stuff controlled by freelist.c */ size = add_size(size, StrategyShmemSize()); - /* - * It would be nice to include the I/O locks in the BufferDesc, but that - * would increase the size of a BufferDesc to more than one cache line, - * and benchmarking has shown that keeping every BufferDesc aligned on a - * cache line boundary is important for performance. So, instead, the - * array of I/O locks is allocated in a separate tranche. Because those - * locks are not highly contended, we lay out the array with minimal - * padding. - */ - size = add_size(size, mul_size(NBuffers, sizeof(LWLockMinimallyPadded))); + /* size of I/O condition variables */ + size = add_size(size, mul_size(NBuffers, + sizeof(ConditionVariableMinimallyPadded))); /* to allow aligning the above */ size = add_size(size, PG_CACHE_LINE_SIZE); diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c index 4953ae9f8244..caa03ae12335 100644 --- a/src/backend/storage/buffer/buf_table.c +++ b/src/backend/storage/buffer/buf_table.c @@ -10,7 +10,7 @@ * before the lock is released (see notes in README). * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index ac935eaae8e9..fe7d7e44f4a3 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -82,6 +82,14 @@ #define RELS_BSEARCH_THRESHOLD 20 +/* + * This is the size (in the number of blocks) above which we scan the + * entire buffer pool to remove the buffers for all the pages of relation + * being dropped. For the relations with size below this threshold, we find + * the buffers by doing lookups in BufMapping table. + */ +#define BUF_DROP_FULL_SCAN_THRESHOLD (uint64) (NBuffers / 32) + typedef struct PrivateRefCountEntry { Buffer buffer; @@ -485,11 +493,15 @@ static BufferDesc *BufferAlloc(SMgrRelation smgr, BufferAccessStrategy strategy, bool *foundPtr); static void FlushBuffer(BufferDesc *buf, SMgrRelation reln); +static void FindAndDropRelFileNodeBuffers(RelFileNode rnode, + ForkNumber forkNum, + BlockNumber nForkBlock, + BlockNumber firstDelBlock); static void AtProcExit_Buffers(int code, Datum arg); static void CheckForBufferLeaks(void); static int rnode_comparator(const void *p1, const void *p2); -static int buffertag_comparator(const void *p1, const void *p2); -static int ckpt_buforder_comparator(const void *pa, const void *pb); +static inline int buffertag_comparator(const BufferTag *a, const BufferTag *b); +static inline int ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b); static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg); #ifdef MPROTECT_BUFFERS @@ -640,7 +652,7 @@ PrefetchSharedBuffer(SMgrRelation smgr_reln, * could be used by the caller to avoid the need for a later buffer lookup, but * it's not pinned, so the caller must recheck it. * - * 2. If the kernel has been asked to initiate I/O, the initated_io member is + * 2. If the kernel has been asked to initiate I/O, the initiated_io member is * true. Currently there is no way to know if the data was already cached by * the kernel and therefore didn't really initiate I/O, and no way to know when * the I/O completes other than using synchronous ReadBuffer(). @@ -678,6 +690,84 @@ PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum) } } +/* + * ReadRecentBuffer -- try to pin a block in a recently observed buffer + * + * Compared to ReadBuffer(), this avoids a buffer mapping lookup when it's + * successful. Return true if the buffer is valid and still has the expected + * tag. In that case, the buffer is pinned and the usage count is bumped. + */ +bool +ReadRecentBuffer(RelFileNode rnode, ForkNumber forkNum, BlockNumber blockNum, + Buffer recent_buffer) +{ + BufferDesc *bufHdr; + BufferTag tag; + uint32 buf_state; + bool have_private_ref; + + Assert(BufferIsValid(recent_buffer)); + + ResourceOwnerEnlargeBuffers(CurrentResourceOwner); + ReservePrivateRefCountEntry(); + INIT_BUFFERTAG(tag, rnode, forkNum, blockNum); + + if (BufferIsLocal(recent_buffer)) + { + bufHdr = GetBufferDescriptor(-recent_buffer - 1); + buf_state = pg_atomic_read_u32(&bufHdr->state); + + /* Is it still valid and holding the right tag? */ + if ((buf_state & BM_VALID) && BUFFERTAGS_EQUAL(tag, bufHdr->tag)) + { + /* Bump local buffer's ref and usage counts. */ + ResourceOwnerRememberBuffer(CurrentResourceOwner, recent_buffer); + LocalRefCount[-recent_buffer - 1]++; + if (BUF_STATE_GET_USAGECOUNT(buf_state) < BM_MAX_USAGE_COUNT) + pg_atomic_write_u32(&bufHdr->state, + buf_state + BUF_USAGECOUNT_ONE); + + return true; + } + } + else + { + bufHdr = GetBufferDescriptor(recent_buffer - 1); + have_private_ref = GetPrivateRefCount(recent_buffer) > 0; + + /* + * Do we already have this buffer pinned with a private reference? If + * so, it must be valid and it is safe to check the tag without + * locking. If not, we have to lock the header first and then check. + */ + if (have_private_ref) + buf_state = pg_atomic_read_u32(&bufHdr->state); + else + buf_state = LockBufHdr(bufHdr); + + if ((buf_state & BM_VALID) && BUFFERTAGS_EQUAL(tag, bufHdr->tag)) + { + /* + * It's now safe to pin the buffer. We can't pin first and ask + * questions later, because because it might confuse code paths + * like InvalidateBuffer() if we pinned a random non-matching + * buffer. + */ + if (have_private_ref) + PinBuffer(bufHdr, NULL); /* bump pin count */ + else + PinBuffer_Locked(bufHdr); /* pin for first time */ + + return true; + } + + /* If we locked the header above, now unlock. */ + if (!have_private_ref) + UnlockBufHdr(bufHdr, buf_state); + } + + return false; +} /* * ReadBuffer -- a shorthand for ReadBufferExtended, for reading from main @@ -705,7 +795,8 @@ ReadBuffer(Relation reln, BlockNumber blockNum) * * In RBM_NORMAL mode, the page is read from disk, and the page header is * validated. An error is thrown if the page header is not valid. (But - * note that an all-zero page is considered "valid"; see PageIsVerified().) + * note that an all-zero page is considered "valid"; see + * PageIsVerifiedExtended().) * * RBM_ZERO_ON_ERROR is like the normal mode, but if the page header is not * valid, the page is zeroed instead of throwing an error. This is intended @@ -1011,7 +1102,8 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, } /* check for garbage data */ - if (!PageIsVerified((Page) bufBlock, blockNum)) + if (!PageIsVerifiedExtended((Page) bufBlock, blockNum, + PIV_LOG_WARNING | PIV_REPORT_STAT)) { if (mode == RBM_ZERO_ON_ERROR || zero_damaged_pages) { @@ -1437,9 +1529,10 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, LWLockRelease(newPartitionLock); /* - * Buffer contents are currently invalid. Try to get the io_in_progress - * lock. If StartBufferIO returns false, then someone else managed to - * read it before we did, so there's nothing left for BufferAlloc() to do. + * Buffer contents are currently invalid. Try to obtain the right to + * start I/O. If StartBufferIO returns false, then someone else managed + * to read it before we did, so there's nothing left for BufferAlloc() to + * do. */ if (StartBufferIO(buf, true)) *foundPtr = false; @@ -1869,9 +1962,8 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner) */ VALGRIND_MAKE_MEM_NOACCESS(BufHdrGetBlock(buf), BLCKSZ); - /* I'd better not still hold any locks on the buffer */ + /* I'd better not still hold the buffer content lock */ Assert(!LWLockHeldByMe(BufferDescriptorGetContentLock(buf))); - Assert(!LWLockHeldByMe(BufferDescriptorGetIOLock(buf))); /* * Decrement the shared reference count. @@ -1927,6 +2019,13 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner) } } +#define ST_SORT sort_checkpoint_bufferids +#define ST_ELEMENT_TYPE CkptSortItem +#define ST_COMPARE(a, b) ckpt_buforder_comparator(a, b) +#define ST_SCOPE static +#define ST_DEFINE +#include + /* * BufferSync -- Write out all dirty buffers in the pool. * @@ -2031,8 +2130,7 @@ BufferSync(int flags) * end up writing to the tablespaces one-by-one; possibly overloading the * underlying system. */ - qsort(CkptBufferIds, num_to_scan, sizeof(CkptSortItem), - ckpt_buforder_comparator); + sort_checkpoint_bufferids(CkptBufferIds, num_to_scan); num_spaces = 0; @@ -2638,7 +2736,6 @@ InitBufferPoolAccess(void) memset(&PrivateRefCountArray, 0, sizeof(PrivateRefCountArray)); - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(int32); hash_ctl.entrysize = sizeof(PrivateRefCountEntry); @@ -2771,14 +2868,7 @@ PrintBufferLeakWarning(Buffer buffer) void CheckPointBuffers(int flags) { - TRACE_POSTGRESQL_BUFFER_CHECKPOINT_START(flags); - CheckpointStats.ckpt_write_t = GetCurrentTimestamp(); BufferSync(flags); - CheckpointStats.ckpt_sync_t = GetCurrentTimestamp(); - TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START(); - ProcessSyncRequests(); - CheckpointStats.ckpt_sync_end_t = GetCurrentTimestamp(); - TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE(); } @@ -2871,9 +2961,9 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln) uint32 buf_state; /* - * Acquire the buffer's io_in_progress lock. If StartBufferIO returns - * false, then someone else flushed the buffer before we could, so we need - * not do anything. + * Try to start an I/O operation. If StartBufferIO returns false, then + * someone else flushed the buffer before we could, so we need not do + * anything. */ if (!StartBufferIO(buf, false)) return; @@ -2938,7 +3028,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln) /* * Now it's safe to write buffer to disk. Note that no one else should * have been able to write it while we were busy with log flushing because - * we have the io_in_progress lock. + * only one process at a time can set the BM_IO_IN_PROGRESS bit. */ bufBlock = BufHdrGetBlock(buf); @@ -2976,7 +3066,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln) /* * Mark the buffer as clean (unless BM_JUST_DIRTIED has become set) and - * end the io_in_progress state. + * end the BM_IO_IN_PROGRESS state. */ TerminateBufferIO(buf, true, 0); @@ -3134,19 +3224,19 @@ BufferGetLSNAtomic(Buffer buffer) * later. It is also the responsibility of higher-level code to ensure * that no other process could be trying to load more pages of the * relation into buffers. - * - * XXX currently it sequentially searches the buffer pool, should be - * changed to more clever ways of searching. However, this routine - * is used only in code paths that aren't very performance-critical, - * and we shouldn't slow down the hot paths to make it faster ... * -------------------------------------------------------------------- */ void -DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum, +DropRelFileNodeBuffers(SMgrRelation smgr_reln, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock) { int i; int j; + RelFileNodeBackend rnode; + BlockNumber nForkBlock[MAX_FORKNUM]; + uint64 nBlocksToInvalidate = 0; + + rnode = smgr_reln->smgr_rnode; /* Temp tables use shared buffers in Greenplum */ /* If it's a local relation, it's localbuf.c's problem. */ @@ -3163,6 +3253,56 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum, } #endif + /* + * To remove all the pages of the specified relation forks from the buffer + * pool, we need to scan the entire buffer pool but we can optimize it by + * finding the buffers from BufMapping table provided we know the exact + * size of each fork of the relation. The exact size is required to ensure + * that we don't leave any buffer for the relation being dropped as + * otherwise the background writer or checkpointer can lead to a PANIC + * error while flushing buffers corresponding to files that don't exist. + * + * To know the exact size, we rely on the size cached for each fork by us + * during recovery which limits the optimization to recovery and on + * standbys but we can easily extend it once we have shared cache for + * relation size. + * + * In recovery, we cache the value returned by the first lseek(SEEK_END) + * and the future writes keeps the cached value up-to-date. See + * smgrextend. It is possible that the value of the first lseek is smaller + * than the actual number of existing blocks in the file due to buggy + * Linux kernels that might not have accounted for the recent write. But + * that should be fine because there must not be any buffers after that + * file size. + */ + for (i = 0; i < nforks; i++) + { + /* Get the number of blocks for a relation's fork */ + nForkBlock[i] = smgrnblocks_cached(smgr_reln, forkNum[i]); + + if (nForkBlock[i] == InvalidBlockNumber) + { + nBlocksToInvalidate = InvalidBlockNumber; + break; + } + + /* calculate the number of blocks to be invalidated */ + nBlocksToInvalidate += (nForkBlock[i] - firstDelBlock[i]); + } + + /* + * We apply the optimization iff the total number of blocks to invalidate + * is below the BUF_DROP_FULL_SCAN_THRESHOLD. + */ + if (BlockNumberIsValid(nBlocksToInvalidate) && + nBlocksToInvalidate < BUF_DROP_FULL_SCAN_THRESHOLD) + { + for (j = 0; j < nforks; j++) + FindAndDropRelFileNodeBuffers(rnode.node, forkNum[j], + nForkBlock[j], firstDelBlock[j]); + return; + } + for (i = 0; i < NBuffers; i++) { BufferDesc *bufHdr = GetBufferDescriptor(i); @@ -3214,31 +3354,36 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum, * -------------------------------------------------------------------- */ void -DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes) +DropRelFileNodesAllBuffers(SMgrRelation *smgr_reln, int nnodes) { - int i, - n = 0; + int i; + int j; + int n = 0; + SMgrRelation *rels; + BlockNumber (*block)[MAX_FORKNUM + 1]; + uint64 nBlocksToInvalidate = 0; RelFileNode *nodes; + bool cached = true; bool use_bsearch; if (nnodes == 0) return; - nodes = palloc(sizeof(RelFileNode) * nnodes); /* non-local relations */ + rels = palloc(sizeof(SMgrRelation) * nnodes); /* non-local relations */ /* Temp tables use shared buffers in Greenplum */ /* If it's a local relation, it's localbuf.c's problem. */ for (i = 0; i < nnodes; i++) { #if 0 - if (RelFileNodeBackendIsTemp(rnodes[i])) + if (RelFileNodeBackendIsTemp(smgr_reln[i]->smgr_rnode)) { - if (rnodes[i].backend == MyBackendId) - DropRelFileNodeAllLocalBuffers(rnodes[i].node); + if (smgr_reln[i]->smgr_rnode.backend == MyBackendId) + DropRelFileNodeAllLocalBuffers(smgr_reln[i]->smgr_rnode.node); } else #endif - nodes[n++] = rnodes[i].node; + rels[n++] = smgr_reln[i]; } /* @@ -3247,10 +3392,72 @@ DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes) */ if (n == 0) { - pfree(nodes); + pfree(rels); + return; + } + + /* + * This is used to remember the number of blocks for all the relations + * forks. + */ + block = (BlockNumber (*)[MAX_FORKNUM + 1]) + palloc(sizeof(BlockNumber) * n * (MAX_FORKNUM + 1)); + + /* + * We can avoid scanning the entire buffer pool if we know the exact size + * of each of the given relation forks. See DropRelFileNodeBuffers. + */ + for (i = 0; i < n && cached; i++) + { + for (j = 0; j <= MAX_FORKNUM; j++) + { + /* Get the number of blocks for a relation's fork. */ + block[i][j] = smgrnblocks_cached(rels[i], j); + + /* We need to only consider the relation forks that exists. */ + if (block[i][j] == InvalidBlockNumber) + { + if (!smgrexists(rels[i], j)) + continue; + cached = false; + break; + } + + /* calculate the total number of blocks to be invalidated */ + nBlocksToInvalidate += block[i][j]; + } + } + + /* + * We apply the optimization iff the total number of blocks to invalidate + * is below the BUF_DROP_FULL_SCAN_THRESHOLD. + */ + if (cached && nBlocksToInvalidate < BUF_DROP_FULL_SCAN_THRESHOLD) + { + for (i = 0; i < n; i++) + { + for (j = 0; j <= MAX_FORKNUM; j++) + { + /* ignore relation forks that doesn't exist */ + if (!BlockNumberIsValid(block[i][j])) + continue; + + /* drop all the buffers for a particular relation fork */ + FindAndDropRelFileNodeBuffers(rels[i]->smgr_rnode.node, + j, block[i][j], 0); + } + } + + pfree(block); + pfree(rels); return; } + pfree(block); + nodes = palloc(sizeof(RelFileNode) * n); /* non-local relations */ + for (i = 0; i < n; i++) + nodes[i] = rels[i]->smgr_rnode.node; + /* * For low number of relations to drop just use a simple walk through, to * save the bsearch overhead. The threshold to use is rather a guess than @@ -3306,6 +3513,66 @@ DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes) } pfree(nodes); + pfree(rels); +} + +/* --------------------------------------------------------------------- + * FindAndDropRelFileNodeBuffers + * + * This function performs look up in BufMapping table and removes from the + * buffer pool all the pages of the specified relation fork that has block + * number >= firstDelBlock. (In particular, with firstDelBlock = 0, all + * pages are removed.) + * -------------------------------------------------------------------- + */ +static void +FindAndDropRelFileNodeBuffers(RelFileNode rnode, ForkNumber forkNum, + BlockNumber nForkBlock, + BlockNumber firstDelBlock) +{ + BlockNumber curBlock; + + for (curBlock = firstDelBlock; curBlock < nForkBlock; curBlock++) + { + uint32 bufHash; /* hash value for tag */ + BufferTag bufTag; /* identity of requested block */ + LWLock *bufPartitionLock; /* buffer partition lock for it */ + int buf_id; + BufferDesc *bufHdr; + uint32 buf_state; + + /* create a tag so we can lookup the buffer */ + INIT_BUFFERTAG(bufTag, rnode, forkNum, curBlock); + + /* determine its hash code and partition lock ID */ + bufHash = BufTableHashCode(&bufTag); + bufPartitionLock = BufMappingPartitionLock(bufHash); + + /* Check that it is in the buffer pool. If not, do nothing. */ + LWLockAcquire(bufPartitionLock, LW_SHARED); + buf_id = BufTableLookup(&bufTag, bufHash); + LWLockRelease(bufPartitionLock); + + if (buf_id < 0) + continue; + + bufHdr = GetBufferDescriptor(buf_id); + + /* + * We need to lock the buffer header and recheck if the buffer is + * still associated with the same block because the buffer could be + * evicted by some other backend loading blocks for a different + * relation after we release lock on the BufMapping table. + */ + buf_state = LockBufHdr(bufHdr); + + if (RelFileNodeEquals(bufHdr->tag.rnode, rnode) && + bufHdr->tag.forkNum == forkNum && + bufHdr->tag.blockNum >= firstDelBlock) + InvalidateBuffer(bufHdr); /* releases spinlock */ + else + UnlockBufHdr(bufHdr, buf_state); + } } /* --------------------------------------------------------------------- @@ -3420,8 +3687,7 @@ PrintPinnedBufs(void) * XXX currently it sequentially searches the buffer pool, should be * changed to more clever ways of searching. This routine is not * used in any performance-critical code paths, so it's not worth - * adding additional overhead to normal paths to make it go faster; - * but see also DropRelFileNodeBuffers. + * adding additional overhead to normal paths to make it go faster. * -------------------------------------------------------------------- */ void @@ -3987,6 +4253,8 @@ LockBufferForCleanup(Buffer buffer) { BufferDesc *bufHdr; char *new_status = NULL; + TimestampTz waitStart = 0; + bool logged_recovery_conflict = false; Assert(BufferIsPinned(buffer)); Assert(PinCountWaitBuf == NULL); @@ -4022,6 +4290,16 @@ LockBufferForCleanup(Buffer buffer) /* Successfully acquired exclusive lock with pincount 1 */ UnlockBufHdr(bufHdr, buf_state); + /* + * Emit the log message if recovery conflict on buffer pin was + * resolved but the startup process waited longer than + * deadlock_timeout for it. + */ + if (logged_recovery_conflict) + LogRecoveryConflict(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, + waitStart, GetCurrentTimestamp(), + NULL, false); + /* Report change to non-waiting status */ if (new_status) { @@ -4060,6 +4338,34 @@ LockBufferForCleanup(Buffer buffer) new_status[len] = '\0'; /* truncate off " waiting" */ } + /* + * Emit the log message if the startup process is waiting longer + * than deadlock_timeout for recovery conflict on buffer pin. + * + * Skip this if first time through because the startup process has + * not started waiting yet in this case. So, the wait start + * timestamp is set after this logic. + */ + if (waitStart != 0 && !logged_recovery_conflict) + { + TimestampTz now = GetCurrentTimestamp(); + + if (TimestampDifferenceExceeds(waitStart, now, + DeadlockTimeout)) + { + LogRecoveryConflict(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, + waitStart, now, NULL, true); + logged_recovery_conflict = true; + } + } + + /* + * Set the wait start timestamp if logging is enabled and first + * time through. + */ + if (log_recovery_conflict_waits && waitStart == 0) + waitStart = GetCurrentTimestamp(); + /* Publish the bufid that Startup process waits on */ SetStartupBufferPinWaitBufId(buffer - 1); /* Set alarm and then wait to be signaled by UnpinBuffer() */ @@ -4221,7 +4527,7 @@ IsBufferCleanupOK(Buffer buffer) * Functions for buffer I/O handling * * Note: We assume that nested buffer I/O never occurs. - * i.e at most one io_in_progress lock is held per proc. + * i.e at most one BM_IO_IN_PROGRESS bit is set per proc. * * Also note that these are used only for shared buffers, not local ones. */ @@ -4232,13 +4538,9 @@ IsBufferCleanupOK(Buffer buffer) static void WaitIO(BufferDesc *buf) { - /* - * Changed to wait until there's no IO - Inoue 01/13/2000 - * - * Note this is *necessary* because an error abort in the process doing - * I/O could release the io_in_progress_lock prematurely. See - * AbortBufferIO. - */ + ConditionVariable *cv = BufferDescriptorGetIOCV(buf); + + ConditionVariablePrepareToSleep(cv); for (;;) { uint32 buf_state; @@ -4253,9 +4555,9 @@ WaitIO(BufferDesc *buf) if (!(buf_state & BM_IO_IN_PROGRESS)) break; - LWLockAcquire(BufferDescriptorGetIOLock(buf), LW_SHARED); - LWLockRelease(BufferDescriptorGetIOLock(buf)); + ConditionVariableSleep(cv, WAIT_EVENT_BUFFER_IO); } + ConditionVariableCancelSleep(); } /* @@ -4267,7 +4569,7 @@ WaitIO(BufferDesc *buf) * In some scenarios there are race conditions in which multiple backends * could attempt the same I/O operation concurrently. If someone else * has already started I/O on this buffer then we will block on the - * io_in_progress lock until he's done. + * I/O condition variable until he's done. * * Input operations are only attempted on buffers that are not BM_VALID, * and output operations only on buffers that are BM_VALID and BM_DIRTY, @@ -4285,25 +4587,11 @@ StartBufferIO(BufferDesc *buf, bool forInput) for (;;) { - /* - * Grab the io_in_progress lock so that other processes can wait for - * me to finish the I/O. - */ - LWLockAcquire(BufferDescriptorGetIOLock(buf), LW_EXCLUSIVE); - buf_state = LockBufHdr(buf); if (!(buf_state & BM_IO_IN_PROGRESS)) break; - - /* - * The only way BM_IO_IN_PROGRESS could be set when the io_in_progress - * lock isn't held is if the process doing the I/O is recovering from - * an error (see AbortBufferIO). If that's the case, we must wait for - * him to get unwedged. - */ UnlockBufHdr(buf, buf_state); - LWLockRelease(BufferDescriptorGetIOLock(buf)); WaitIO(buf); } @@ -4313,7 +4601,6 @@ StartBufferIO(BufferDesc *buf, bool forInput) { /* someone else already did the I/O */ UnlockBufHdr(buf, buf_state); - LWLockRelease(BufferDescriptorGetIOLock(buf)); return false; } @@ -4335,7 +4622,6 @@ StartBufferIO(BufferDesc *buf, bool forInput) * (Assumptions) * My process is executing IO for the buffer * BM_IO_IN_PROGRESS bit is set for the buffer - * We hold the buffer's io_in_progress lock * The buffer is Pinned * * If clear_dirty is true and BM_JUST_DIRTIED is not set, we clear the @@ -4367,12 +4653,7 @@ TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits) InProgressBuf = NULL; -#ifdef MPROTECT_BUFFERS - /* XXX: should this be PROT_NONE if called from AbortBufferIO? */ - if (!LWLockHeldByMe(BufferDescriptorGetContentLock(buf))) - BufferMProtect(buf, PROT_READ); -#endif - LWLockRelease(BufferDescriptorGetIOLock(buf)); + ConditionVariableBroadcast(BufferDescriptorGetIOCV(buf)); } /* @@ -4393,14 +4674,6 @@ AbortBufferIO(void) { uint32 buf_state; - /* - * Since LWLockReleaseAll has already been called, we're not holding - * the buffer's io_in_progress_lock. We have to re-acquire it so that - * we can use TerminateBufferIO. Anyone who's executing WaitIO on the - * buffer will be in a busy spin until we succeed in doing this. - */ - LWLockAcquire(BufferDescriptorGetIOLock(buf), LW_EXCLUSIVE); - buf_state = LockBufHdr(buf); Assert(buf_state & BM_IO_IN_PROGRESS); if (IsForInput) @@ -4561,11 +4834,9 @@ WaitBufHdrUnlocked(BufferDesc *buf) /* * BufferTag comparator. */ -static int -buffertag_comparator(const void *a, const void *b) +static inline int +buffertag_comparator(const BufferTag *ba, const BufferTag *bb) { - const BufferTag *ba = (const BufferTag *) a; - const BufferTag *bb = (const BufferTag *) b; int ret; ret = rnode_comparator(&ba->rnode, &bb->rnode); @@ -4592,12 +4863,9 @@ buffertag_comparator(const void *a, const void *b) * It is important that tablespaces are compared first, the logic balancing * writes between tablespaces relies on it. */ -static int -ckpt_buforder_comparator(const void *pa, const void *pb) +static inline int +ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b) { - const CkptSortItem *a = (const CkptSortItem *) pa; - const CkptSortItem *b = (const CkptSortItem *) pb; - /* compare tablespace */ if (a->tsId < b->tsId) return -1; @@ -4688,6 +4956,13 @@ ScheduleBufferTagForWriteback(WritebackContext *context, BufferTag *tag) IssuePendingWritebacks(context); } +#define ST_SORT sort_pending_writebacks +#define ST_ELEMENT_TYPE PendingWriteback +#define ST_COMPARE(a, b) buffertag_comparator(&a->tag, &b->tag) +#define ST_SCOPE static +#define ST_DEFINE +#include + /* * Issue all pending writeback requests, previously scheduled with * ScheduleBufferTagForWriteback, to the OS. @@ -4707,8 +4982,7 @@ IssuePendingWritebacks(WritebackContext *context) * Executing the writes in-order can make them a lot faster, and allows to * merge writeback requests to consecutive blocks into larger writebacks. */ - qsort(&context->pending_writebacks, context->nr_pending, - sizeof(PendingWriteback), buffertag_comparator); + sort_pending_writebacks(context->pending_writebacks, context->nr_pending); /* * Coalesce neighbouring writes, but nothing else. For that we iterate diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index c6581a8647fe..333657f23a98 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -4,7 +4,7 @@ * routines for managing the buffer pool's replacement strategy. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index 723116c2babb..62371b4522c1 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -4,7 +4,7 @@ * local buffer manager. Fast buffer manager for temporary tables, * which never need to be WAL-logged or checkpointed, etc. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * @@ -480,7 +480,6 @@ InitLocalBuffers(void) } /* Create the lookup hash table */ - MemSet(&info, 0, sizeof(info)); info.keysize = sizeof(BufferTag); info.entrysize = sizeof(LocalBufferLookupEnt); diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c index 404297b8d29f..659e4adf5b27 100644 --- a/src/backend/storage/file/buffile.c +++ b/src/backend/storage/file/buffile.c @@ -3,7 +3,7 @@ * buffile.c * Management of large buffered temporary files. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,10 +32,14 @@ * (by opening multiple fd.c temporary files). This is an essential feature * for sorts and hashjoins on large amounts of data. * - * BufFile supports temporary files that can be made read-only and shared with - * other backends, as infrastructure for parallel execution. Such files need - * to be created as a member of a SharedFileSet that all participants are - * attached to. + * BufFile supports temporary files that can be shared with other backends, as + * infrastructure for parallel execution. Such files need to be created as a + * member of a SharedFileSet that all participants are attached to. + * + * BufFile also supports temporary files that can be used by the single backend + * when the corresponding files need to be survived across the transaction and + * need to be opened and closed multiple times. Such files need to be created + * as a member of a SharedFileSet. *------------------------------------------------------------------------- */ @@ -390,7 +394,7 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name, workfile_set *work * backends and render it read-only. */ BufFile * -BufFileOpenShared(SharedFileSet *fileset, const char *name) +BufFileOpenShared(SharedFileSet *fileset, const char *name, int mode) { BufFile *file; char segment_name[MAXPGPATH]; @@ -414,7 +418,7 @@ BufFileOpenShared(SharedFileSet *fileset, const char *name) } /* Try to load a segment. */ SharedSegmentName(segment_name, name, nfiles); - files[nfiles] = SharedFileSetOpen(fileset, segment_name); + files[nfiles] = SharedFileSetOpen(fileset, segment_name, mode); if (files[nfiles] <= 0) break; ++nfiles; @@ -434,7 +438,7 @@ BufFileOpenShared(SharedFileSet *fileset, const char *name) file = makeBufFileCommon(nfiles); file->files = files; - file->readOnly = true; /* Can't write to files opened this way */ + file->readOnly = (mode == O_RDONLY) ? true : false; file->fileset = fileset; file->name = pstrdup(name); @@ -910,6 +914,7 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence) newOffset = (file->curOffset + file->pos) + offset; break; case SEEK_END: + /* * The file size of the last file gives us the end offset of that * file. @@ -922,9 +927,9 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence) ereport(ERROR, (errcode_for_file_access(), errmsg("could not determine size of temporary file \"%s\" from BufFile \"%s\": %m", - FilePathName(file->files[file->numFiles - 1]), - file->name))); - break; + FilePathName(file->files[file->numFiles - 1]), + file->name))); + break; default: elog(ERROR, "invalid whence: %d", whence); return EOF; @@ -1491,3 +1496,98 @@ BufFileLoadCompressedBuffer(BufFile *file, void *buffer, size_t bufsize) } #endif /* USE_ZSTD */ + +/* + * Truncate a BufFile created by BufFileCreateShared up to the given fileno and + * the offset. + */ +void +BufFileTruncateShared(BufFile *file, int fileno, off_t offset) +{ + int numFiles = file->numFiles; + int newFile = fileno; + off_t newOffset = file->curOffset; + char segment_name[MAXPGPATH]; + int i; + + /* + * Loop over all the files up to the given fileno and remove the files + * that are greater than the fileno and truncate the given file up to the + * offset. Note that we also remove the given fileno if the offset is 0 + * provided it is not the first file in which we truncate it. + */ + for (i = file->numFiles - 1; i >= fileno; i--) + { + if ((i != fileno || offset == 0) && i != 0) + { + SharedSegmentName(segment_name, file->name, i); + FileClose(file->files[i]); + if (!SharedFileSetDelete(file->fileset, segment_name, true)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not delete shared fileset \"%s\": %m", + segment_name))); + numFiles--; + newOffset = MAX_PHYSICAL_FILESIZE; + + /* + * This is required to indicate that we have deleted the given + * fileno. + */ + if (i == fileno) + newFile--; + } + else + { + if (FileTruncate(file->files[i], offset, + WAIT_EVENT_BUFFILE_TRUNCATE) < 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not truncate file \"%s\": %m", + FilePathName(file->files[i])))); + newOffset = offset; + } + } + + file->numFiles = numFiles; + + /* + * If the truncate point is within existing buffer then we can just adjust + * pos within buffer. + */ + if (newFile == file->curFile && + newOffset >= file->curOffset && + newOffset <= file->curOffset + file->nbytes) + { + /* No need to reset the current pos if the new pos is greater. */ + if (newOffset <= file->curOffset + file->pos) + file->pos = (int) (newOffset - file->curOffset); + + /* Adjust the nbytes for the current buffer. */ + file->nbytes = (int) (newOffset - file->curOffset); + } + else if (newFile == file->curFile && + newOffset < file->curOffset) + { + /* + * The truncate point is within the existing file but prior to the + * current position, so we can forget the current buffer and reset the + * current position. + */ + file->curOffset = newOffset; + file->pos = 0; + file->nbytes = 0; + } + else if (newFile < file->curFile) + { + /* + * The truncate point is prior to the current file, so need to reset + * the current position accordingly. + */ + file->curFile = newFile; + file->curOffset = newOffset; + file->pos = 0; + file->nbytes = 0; + } + /* Nothing to do, if the truncate point is beyond current file. */ +} diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c index 0cf598dd0c64..0c436247d983 100644 --- a/src/backend/storage/file/copydir.c +++ b/src/backend/storage/file/copydir.c @@ -3,7 +3,7 @@ * copydir.c * copies a directory * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * While "xcopy /e /i /q" works fine for copying directories, on Windows XP @@ -22,6 +22,7 @@ #include #include +#include "access/xlog.h" #include "miscadmin.h" #include "pgstat.h" #include "storage/copydir.h" @@ -63,9 +64,26 @@ copydir(char *fromdir, char *todir, bool recurse) snprintf(tofile, sizeof(tofile), "%s/%s", todir, xlde->d_name); if (lstat(fromfile, &fst) < 0) + { + /* + * During WAL replay the checkpointer can unlink files of + * dropped relations from under us (deferred unlinks happen at + * restartpoints), so a vanished source file is expected here + * and must not kill the startup process; the primary's copy + * skipped it the same way. + */ + if (errno == ENOENT && InRecovery) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("skipping vanished file \"%s\" during replay", + fromfile))); + continue; + } ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", fromfile))); + } if (S_ISDIR(fst.st_mode)) { @@ -156,9 +174,21 @@ copy_file(char *fromfile, char *tofile) */ srcfd = OpenTransientFile(fromfile, O_RDONLY | PG_BINARY); if (srcfd < 0) + { + /* See copydir(): tolerate files vanishing during WAL replay. */ + if (errno == ENOENT && InRecovery) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("skipping vanished file \"%s\" during replay", + fromfile))); + pfree(buffer); + return; + } ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\": %m", fromfile))); + } dstfd = OpenTransientFile(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY); if (dstfd < 0) diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 77777e6d45b5..0d438971379d 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2007-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -74,9 +74,11 @@ #include "postgres.h" +#include #include #include #include +#include #ifndef WIN32 #include #endif @@ -92,8 +94,10 @@ #include "catalog/pg_tablespace.h" #include "cdb/cdbvars.h" #include "common/file_perm.h" +#include "common/file_utils.h" #include "miscadmin.h" #include "pgstat.h" +#include "port/pg_iovec.h" #include "portability/mem.h" #include "storage/fd.h" #include "storage/ipc.h" @@ -165,6 +169,9 @@ int max_safe_fds = FD_MINFREE; /* default if not changed */ /* Whether it is safe to continue running after fsync() fails. */ bool data_sync_retry = false; +/* How SyncDataDirectory() should do its job. */ +int recovery_init_sync_method = RECOVERY_INIT_SYNC_METHOD_FSYNC; + /* Debugging.... */ #ifdef FDDEBUG @@ -651,6 +658,33 @@ gp_retry_close(int fd) { return err; } +/* + * Truncate a file to a given length by name. + */ +int +pg_truncate(const char *path, off_t length) +{ +#ifdef WIN32 + int save_errno; + int ret; + int fd; + + fd = OpenTransientFile(path, O_RDWR | PG_BINARY); + if (fd >= 0) + { + ret = ftruncate(fd, 0); + save_errno = errno; + CloseTransientFile(fd); + errno = save_errno; + } + else + ret = -1; + + return ret; +#else + return truncate(path, length); +#endif +} /* * fsync_fname -- fsync a file or directory, handling errors properly @@ -797,17 +831,20 @@ durable_unlink(const char *fname, int elevel) } /* - * durable_rename_excl -- rename a file in a durable manner, without - * overwriting an existing target file + * durable_rename_excl -- rename a file in a durable manner. * - * Similar to durable_rename(), except that this routine will fail if the - * target file already exists. + * Similar to durable_rename(), except that this routine tries (but does not + * guarantee) not to overwrite the target file. * * Note that a crash in an unfortunate moment can leave you with two links to * the target file. * * Log errors with the caller specified severity. * + * On Windows, using a hard link followed by unlink() causes concurrency + * issues, while a simple rename() does not cause that, so be careful when + * changing the logic of this routine. + * * Returns 0 if the operation succeeded, -1 otherwise. Note that errno is not * valid upon return. */ @@ -821,6 +858,7 @@ durable_rename_excl(const char *oldfile, const char *newfile, int elevel) if (fsync_fname_ext(oldfile, false, false, elevel) != 0) return -1; +#ifdef HAVE_WORKING_LINK if (link(oldfile, newfile) < 0) { ereport(elevel, @@ -830,6 +868,16 @@ durable_rename_excl(const char *oldfile, const char *newfile, int elevel) return -1; } unlink(oldfile); +#else + if (rename(oldfile, newfile) < 0) + { + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not rename file \"%s\" to \"%s\": %m", + oldfile, newfile))); + return -1; + } +#endif /* * Make change persistent in case of an OS crash, both the new entry and @@ -1515,8 +1563,6 @@ PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode) DO_DB(elog(LOG, "PathNameOpenFile: success %d", vfdP->fd)); - Insert(file); - vfdP->fileName = fnamecopy; /* Saved flags are adjusted to be OK for re-opening file */ vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL); @@ -1525,6 +1571,8 @@ PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode) vfdP->fdstate = 0x0; vfdP->resowner = NULL; + Insert(file); + return file; } @@ -1806,18 +1854,17 @@ PathNameCreateTemporaryFile(const char *path, bool error_on_failure) /* * Open a file that was created with PathNameCreateTemporaryFile, possibly in * another backend. Files opened this way don't count against the - * temp_file_limit of the caller, are read-only and are automatically closed - * at the end of the transaction but are not deleted on close. + * temp_file_limit of the caller, are automatically closed at the end of the + * transaction but are not deleted on close. */ File -PathNameOpenTemporaryFile(const char *path) +PathNameOpenTemporaryFile(const char *path, int mode) { File file; ResourceOwnerEnlargeFiles(CurrentResourceOwner); - /* We open the file read-only. */ - file = PathNameOpenFile(path, O_RDONLY | PG_BINARY); + file = PathNameOpenFile(path, mode | PG_BINARY); /* If no such file, then we don't raise an error. */ if (file <= 0 && errno != ENOENT) @@ -1950,7 +1997,9 @@ FileClose(File file) /* in any case do the unlink */ if (unlink(vfdP->fileName)) - elog(DEBUG1, "could not unlink file \"%s\": %m", vfdP->fileName); + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not delete file \"%s\": %m", vfdP->fileName))); /* and last report the stat results */ if (stat_errno == 0) @@ -1958,7 +2007,9 @@ FileClose(File file) else { errno = stat_errno; - elog(DEBUG1, "could not stat file \"%s\": %m", vfdP->fileName); + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", vfdP->fileName))); } } @@ -3131,11 +3182,13 @@ CleanupTempFiles(bool isCommit, bool isProcExit) * remove any leftover files created by OpenTemporaryFile and any leftover * temporary relation files created by mdcreate. * - * NOTE: we could, but don't, call this during a post-backend-crash restart - * cycle. The argument for not doing it is that someone might want to examine - * the temp files for debugging purposes. This does however mean that - * OpenTemporaryFile had better allow for collision with an existing temp - * file name. + * During post-backend-crash restart cycle, this routine is called when + * remove_temp_files_after_crash GUC is enabled. Multiple crashes while + * queries are using temp files could result in useless storage usage that can + * only be reclaimed by a service restart. The argument against enabling it is + * that someone might want to examine the temporary files for debugging + * purposes. This does however mean that OpenTemporaryFile had better allow for + * collision with an existing temp file name. * * NOTE: this function and its subroutines generally report syscall failures * with ereport(LOG) and keep going. Removing temp files is not so critical @@ -3396,9 +3449,31 @@ SyncAllXLogFiles(void) walkdir("pg_wal", datadir_fsync_fname, false, LOG); ereport(LOG, (errmsg("synchronization of the wal directory finishes."))); } +#ifdef HAVE_SYNCFS +static void +do_syncfs(const char *path) +{ + int fd; + + fd = OpenTransientFile(path, O_RDONLY); + if (fd < 0) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", path))); + return; + } + if (syncfs(fd) < 0) + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not synchronize file system for file \"%s\": %m", path))); + CloseTransientFile(fd); +} +#endif /* - * Issue fsync recursively on PGDATA and all its contents. + * Issue fsync recursively on PGDATA and all its contents, or issue syncfs for + * all potential filesystem, depending on recovery_init_sync_method setting. * * We fsync regular files and directories wherever they are, but we * follow symlinks only for pg_wal and immediately under pg_tblspc. @@ -3450,6 +3525,42 @@ SyncDataDirectory(void) xlog_is_symlink = true; #endif +#ifdef HAVE_SYNCFS + if (recovery_init_sync_method == RECOVERY_INIT_SYNC_METHOD_SYNCFS) + { + DIR *dir; + struct dirent *de; + + /* + * On Linux, we don't have to open every single file one by one. We + * can use syncfs() to sync whole filesystems. We only expect + * filesystem boundaries to exist where we tolerate symlinks, namely + * pg_wal and the tablespaces, so we call syncfs() for each of those + * directories. + */ + + /* Sync the top level pgdata directory. */ + do_syncfs("."); + /* If any tablespaces are configured, sync each of those. */ + dir = AllocateDir("pg_tblspc"); + while ((de = ReadDirExtended(dir, "pg_tblspc", LOG))) + { + char path[MAXPGPATH]; + + if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) + continue; + + snprintf(path, MAXPGPATH, "pg_tblspc/%s", de->d_name); + do_syncfs(path); + } + FreeDir(dir); + /* If pg_wal is a symlink, process that too. */ + if (xlog_is_symlink) + do_syncfs("pg_wal"); + return; + } +#endif /* !HAVE_SYNCFS */ + /* * If possible, hint to the kernel that we're soon going to fsync the data * directory and its contents. Errors in this step are even less @@ -3506,8 +3617,6 @@ walkdir(const char *path, while ((de = ReadDirExtended(dir, path, elevel)) != NULL) { char subpath[MAXPGPATH * 2]; - struct stat fst; - int sret; CHECK_FOR_INTERRUPTS(); @@ -3517,23 +3626,23 @@ walkdir(const char *path, snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name); - if (process_symlinks) - sret = stat(subpath, &fst); - else - sret = lstat(subpath, &fst); - - if (sret < 0) + switch (get_dirent_type(subpath, de, process_symlinks, elevel)) { - ereport(elevel, - (errcode_for_file_access(), - errmsg("could not stat file \"%s\": %m", subpath))); - continue; - } + case PGFILETYPE_REG: + (*action) (subpath, false, elevel); + break; + case PGFILETYPE_DIR: + walkdir(subpath, action, false, elevel); + break; + default: - if (S_ISREG(fst.st_mode)) - (*action) (subpath, false, elevel); - else if (S_ISDIR(fst.st_mode)) - walkdir(subpath, action, false, elevel); + /* + * Errors are already reported directly by get_dirent_type(), + * and any remaining symlinks and unknown file types are + * ignored. + */ + break; + } } FreeDir(dir); /* we ignore any error here */ @@ -3794,3 +3903,67 @@ data_sync_elevel(int elevel) { return data_sync_retry ? elevel : PANIC; } + +/* + * A convenience wrapper for pg_pwritev() that retries on partial write. If an + * error is returned, it is unspecified how much has been written. + */ +ssize_t +pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset) +{ + struct iovec iov_copy[PG_IOV_MAX]; + ssize_t sum = 0; + ssize_t part; + + /* We'd better have space to make a copy, in case we need to retry. */ + if (iovcnt > PG_IOV_MAX) + { + errno = EINVAL; + return -1; + } + + for (;;) + { + /* Write as much as we can. */ + part = pg_pwritev(fd, iov, iovcnt, offset); + if (part < 0) + return -1; + +#ifdef SIMULATE_SHORT_WRITE + part = Min(part, 4096); +#endif + + /* Count our progress. */ + sum += part; + offset += part; + + /* Step over iovecs that are done. */ + while (iovcnt > 0 && iov->iov_len <= part) + { + part -= iov->iov_len; + ++iov; + --iovcnt; + } + + /* Are they all done? */ + if (iovcnt == 0) + { + /* We don't expect the kernel to write more than requested. */ + Assert(part == 0); + break; + } + + /* + * Move whatever's left to the front of our mutable copy and adjust + * the leading iovec. + */ + Assert(iovcnt > 0); + memmove(iov_copy, iov, sizeof(*iov) * iovcnt); + Assert(iov->iov_len > part); + iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part; + iov_copy[0].iov_len -= part; + iov = iov_copy; + } + + return sum; +} diff --git a/src/backend/storage/file/reinit.c b/src/backend/storage/file/reinit.c index 11b16f0dfee0..167696975266 100644 --- a/src/backend/storage/file/reinit.c +++ b/src/backend/storage/file/reinit.c @@ -3,7 +3,7 @@ * reinit.c * Reinitialization of unlogged relations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -33,7 +33,7 @@ static void ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, typedef struct { - char oid[OIDCHARS + 1]; + Oid reloid; /* hash key */ } unlogged_relation_entry; /* @@ -175,10 +175,11 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op) * need to be reset. Otherwise, this cleanup operation would be * O(n^2). */ - memset(&ctl, 0, sizeof(ctl)); - ctl.keysize = sizeof(unlogged_relation_entry); + ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(unlogged_relation_entry); - hash = hash_create("unlogged hash", 32, &ctl, HASH_ELEM); + ctl.hcxt = CurrentMemoryContext; + hash = hash_create("unlogged relation OIDs", 32, &ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); /* Scan the directory. */ dbspace_dir = AllocateDir(dbspacedirname); @@ -201,9 +202,8 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op) * Put the OID portion of the name into the hash table, if it * isn't already. */ - memset(ent.oid, 0, sizeof(ent.oid)); - memcpy(ent.oid, de->d_name, oidchars); - hash_search(hash, &ent, HASH_ENTER, NULL); + ent.reloid = atooid(de->d_name); + (void) hash_search(hash, &ent, HASH_ENTER, NULL); } /* Done with the first pass. */ @@ -227,7 +227,6 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op) { ForkNumber forkNum; int oidchars; - bool found; unlogged_relation_entry ent; /* Skip anything that doesn't look like a relation data file. */ @@ -241,14 +240,10 @@ ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, int op) /* * See whether the OID portion of the name shows up in the hash - * table. + * table. If so, nuke it! */ - memset(ent.oid, 0, sizeof(ent.oid)); - memcpy(ent.oid, de->d_name, oidchars); - hash_search(hash, &ent, HASH_FIND, &found); - - /* If so, nuke it! */ - if (found) + ent.reloid = atooid(de->d_name); + if (hash_search(hash, &ent, HASH_FIND, NULL)) { snprintf(rm_path, sizeof(rm_path), "%s/%s", dbspacedirname, de->d_name); diff --git a/src/backend/storage/file/sharedfileset.c b/src/backend/storage/file/sharedfileset.c index 16b7594756c6..ed37c940adc7 100644 --- a/src/backend/storage/file/sharedfileset.c +++ b/src/backend/storage/file/sharedfileset.c @@ -3,7 +3,7 @@ * sharedfileset.c * Shared temporary file management. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -13,6 +13,10 @@ * files can be discovered by name, and a shared ownership semantics so that * shared files survive until the last user detaches. * + * SharedFileSets can be used by backends when the temporary files need to be + * opened/closed multiple times and the underlying files need to survive across + * transactions. + * *------------------------------------------------------------------------- */ @@ -25,25 +29,36 @@ #include "common/hashfn.h" #include "miscadmin.h" #include "storage/dsm.h" +#include "storage/ipc.h" #include "storage/sharedfileset.h" #include "utils/builtins.h" +static List *filesetlist = NIL; + static void SharedFileSetOnDetach(dsm_segment *segment, Datum datum); +static void SharedFileSetDeleteOnProcExit(int status, Datum arg); static void SharedFileSetPath(char *path, SharedFileSet *fileset, Oid tablespace); static void SharedFilePath(char *path, SharedFileSet *fileset, const char *name); static Oid ChooseTablespace(const SharedFileSet *fileset, const char *name); /* - * Initialize a space for temporary files that can be opened for read-only - * access by other backends. Other backends must attach to it before - * accessing it. Associate this SharedFileSet with 'seg'. Any contained - * files will be deleted when the last backend detaches. + * Initialize a space for temporary files that can be opened by other backends. + * Other backends must attach to it before accessing it. Associate this + * SharedFileSet with 'seg'. Any contained files will be deleted when the + * last backend detaches. + * + * We can also use this interface if the temporary files are used only by + * single backend but the files need to be opened and closed multiple times + * and also the underlying files need to survive across transactions. For + * such cases, dsm segment 'seg' should be passed as NULL. Callers are + * expected to explicitly remove such files by using SharedFileSetDelete/ + * SharedFileSetDeleteAll or we remove such files on proc exit. * * Files will be distributed over the tablespaces configured in * temp_tablespaces. * * Under the covers the set is one or more directories which will eventually - * be deleted when there are no backends attached. + * be deleted. */ void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg) @@ -84,7 +99,25 @@ SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg) } /* Register our cleanup callback. */ - on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset)); + if (seg) + on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset)); + else + { + static bool registered_cleanup = false; + + if (!registered_cleanup) + { + /* + * We must not have registered any fileset before registering the + * fileset clean up. + */ + Assert(filesetlist == NIL); + on_proc_exit(SharedFileSetDeleteOnProcExit, 0); + registered_cleanup = true; + } + + filesetlist = lcons((void *) fileset, filesetlist); + } } /* @@ -147,13 +180,13 @@ SharedFileSetCreate(SharedFileSet *fileset, const char *name) * another backend. */ File -SharedFileSetOpen(SharedFileSet *fileset, const char *name) +SharedFileSetOpen(SharedFileSet *fileset, const char *name, int mode) { char path[MAXPGPATH]; File file; SharedFilePath(path, fileset, name); - file = PathNameOpenTemporaryFile(path); + file = PathNameOpenTemporaryFile(path, mode); return file; } @@ -192,6 +225,9 @@ SharedFileSetDeleteAll(SharedFileSet *fileset) SharedFileSetPath(dirpath, fileset, fileset->tablespaces[i]); PathNameDeleteTemporaryDir(dirpath); } + + /* Unregister the shared fileset */ + SharedFileSetUnregister(fileset); } /* @@ -222,6 +258,62 @@ SharedFileSetOnDetach(dsm_segment *segment, Datum datum) SharedFileSetDeleteAll(fileset); } +/* + * Callback function that will be invoked on the process exit. This will + * process the list of all the registered sharedfilesets and delete the + * underlying files. + */ +static void +SharedFileSetDeleteOnProcExit(int status, Datum arg) +{ + /* + * Remove all the pending shared fileset entries. We don't use foreach() + * here because SharedFileSetDeleteAll will remove the current element in + * filesetlist. Though we have used foreach_delete_current() to remove the + * element from filesetlist it could only fix up the state of one of the + * loops, see SharedFileSetUnregister. + */ + while (list_length(filesetlist) > 0) + { + SharedFileSet *fileset = (SharedFileSet *) linitial(filesetlist); + + SharedFileSetDeleteAll(fileset); + } + + filesetlist = NIL; +} + +/* + * Unregister the shared fileset entry registered for cleanup on proc exit. + */ +void +SharedFileSetUnregister(SharedFileSet *input_fileset) +{ + ListCell *l; + + /* + * If the caller is following the dsm based cleanup then we don't maintain + * the filesetlist so return. + */ + if (filesetlist == NIL) + return; + + foreach(l, filesetlist) + { + SharedFileSet *fileset = (SharedFileSet *) lfirst(l); + + /* Remove the entry from the list */ + if (input_fileset == fileset) + { + filesetlist = foreach_delete_current(filesetlist, l); + return; + } + } + + /* Should have found a match */ + Assert(false); +} + /* * Build the path for the directory holding the files backing a SharedFileSet * in a given tablespace. diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index fc7fe851bc7c..796b915156b4 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding free space in relations * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/freespace/fsmpage.c b/src/backend/storage/freespace/fsmpage.c index 50f0ada756d2..88ae51e5265f 100644 --- a/src/backend/storage/freespace/fsmpage.c +++ b/src/backend/storage/freespace/fsmpage.c @@ -4,7 +4,7 @@ * routines to search and manipulate one FSM page. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/freespace/indexfsm.c b/src/backend/storage/freespace/indexfsm.c index d975c3364b48..d66e10b89d29 100644 --- a/src/backend/storage/freespace/indexfsm.c +++ b/src/backend/storage/freespace/indexfsm.c @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding free pages in relations * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c index 3e200e02cc22..5c05297a2aa7 100644 --- a/src/backend/storage/ipc/barrier.c +++ b/src/backend/storage/ipc/barrier.c @@ -3,7 +3,7 @@ * barrier.c * Barriers for synchronizing cooperating processes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * From Wikipedia[1]: "In parallel computing, a barrier is a type of @@ -205,6 +205,28 @@ BarrierArriveAndDetach(Barrier *barrier) return BarrierDetachImpl(barrier, true); } +/* + * Arrive at a barrier, and detach all but the last to arrive. Returns true if + * the caller was the last to arrive, and is therefore still attached. + */ +bool +BarrierArriveAndDetachExceptLast(Barrier *barrier) +{ + SpinLockAcquire(&barrier->mutex); + if (barrier->participants > 1) + { + --barrier->participants; + SpinLockRelease(&barrier->mutex); + + return false; + } + Assert(barrier->participants == 1); + ++barrier->phase; + SpinLockRelease(&barrier->mutex); + + return true; +} + /* * Attach to a barrier. All waiting participants will now wait for this * participant to call BarrierArriveAndWait(), BarrierDetach() or diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index dffbd8e82a2a..b461a5f7e96e 100644 --- a/src/backend/storage/ipc/dsm.c +++ b/src/backend/storage/ipc/dsm.c @@ -14,7 +14,7 @@ * hard postmaster crash, remaining segments will be removed, if they * still exist, at the next postmaster startup. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -771,8 +771,12 @@ dsm_detach(dsm_segment *seg) /* * Invoke registered callbacks. Just in case one of those callbacks * throws a further error that brings us back here, pop the callback - * before invoking it, to avoid infinite error recursion. + * before invoking it, to avoid infinite error recursion. Don't allow + * interrupts while running the individual callbacks in non-error code + * paths, to avoid leaving cleanup work unfinished if we're interrupted by + * a statement timeout or similar. */ + HOLD_INTERRUPTS(); while (!slist_is_empty(&seg->on_detach)) { slist_node *node; @@ -788,6 +792,7 @@ dsm_detach(dsm_segment *seg) function(seg, arg); } + RESUME_INTERRUPTS(); /* * Try to remove the mapping, if one exists. Normally, there will be, but diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c index 7e65fea71089..1487cb7588c1 100644 --- a/src/backend/storage/ipc/dsm_impl.c +++ b/src/backend/storage/ipc/dsm_impl.c @@ -36,7 +36,7 @@ * * As ever, Windows requires its own implementation. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c index 4fcc53b4237f..29ea85907dad 100644 --- a/src/backend/storage/ipc/ipc.c +++ b/src/backend/storage/ipc/ipc.c @@ -8,7 +8,7 @@ * exit-time cleanup for either a postmaster or a backend. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -408,9 +408,9 @@ on_shmem_exit(pg_on_exit_callback function, Datum arg) * cancel_before_shmem_exit * * this function removes a previously-registered before_shmem_exit - * callback. For simplicity, only the latest entry can be - * removed. (We could work harder but there is no need for - * current uses.) + * callback. We only look at the latest entry for removal, as we + * expect callers to add and remove temporary before_shmem_exit + * callbacks in strict LIFO order. * ---------------------------------------------------------------- */ void @@ -421,6 +421,41 @@ cancel_before_shmem_exit(pg_on_exit_callback function, Datum arg) == function && before_shmem_exit_list[before_shmem_exit_index - 1].arg == arg) --before_shmem_exit_index; + else + elog(ERROR, "before_shmem_exit callback (%p,0x%llx) is not the latest entry", + function, (long long) arg); +} + +/* ---------------------------------------------------------------- + * cancel_before_shmem_exit_if_latest + * + * Like cancel_before_shmem_exit(), but instead of raising an error when + * the requested callback is not the latest entry (or is not registered + * at all), it leaves the list unchanged and returns false. Returns true + * if the callback was the latest entry and was removed. + * + * GPDB: this restores the pre-PG14 lenient behavior for callers that may + * legitimately try to cancel a callback out of strict LIFO order or that + * may not have been registered. ResetTempNamespace() uses it during + * gang-loss recovery: the temp-namespace cleanup callback may be absent + * (temp namespace not yet committed) or no longer the latest entry, and + * it is harmless to leave registered (RemoveTempRelationsCallback() is a + * no-op once myTempNamespace is reset). Throwing here would turn a + * recoverable gang loss into a PANIC during transaction abort. + * ---------------------------------------------------------------- + */ +bool +cancel_before_shmem_exit_if_latest(pg_on_exit_callback function, Datum arg) +{ + if (before_shmem_exit_index > 0 && + before_shmem_exit_list[before_shmem_exit_index - 1].function + == function && + before_shmem_exit_list[before_shmem_exit_index - 1].arg == arg) + { + --before_shmem_exit_index; + return true; + } + return false; } /* ---------------------------------------------------------------- @@ -440,3 +475,20 @@ on_exit_reset(void) on_proc_exit_index = 0; reset_on_dsm_detach(); } + +/* ---------------------------------------------------------------- + * check_on_shmem_exit_lists_are_empty + * + * Debugging check that no shmem cleanup handlers have been registered + * prematurely in the current process. + * ---------------------------------------------------------------- + */ +void +check_on_shmem_exit_lists_are_empty(void) +{ + if (before_shmem_exit_index) + elog(FATAL, "before_shmem_exit has been called prematurely"); + if (on_shmem_exit_index) + elog(FATAL, "on_shmem_exit has been called prematurely"); + /* Checking DSM detach state seems unnecessary given the above */ +} diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index b827eaafc2a4..5757a2e739e1 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -3,7 +3,7 @@ * ipci.c * POSTGRES inter-process communication initialization code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -183,6 +183,7 @@ CreateSharedMemoryAndSemaphores(void) size = add_size(size, ReplicationOriginShmemSize()); size = add_size(size, WalSndShmemSize()); size = add_size(size, WalRcvShmemSize()); + size = add_size(size, PgArchShmemSize()); size = add_size(size, ApplyLauncherShmemSize()); size = add_size(size, FTSReplicationStatusShmemSize()); size = add_size(size, SnapMgrShmemSize()); @@ -352,6 +353,7 @@ CreateSharedMemoryAndSemaphores(void) ReplicationOriginShmemInit(); WalSndShmemInit(); WalRcvShmemInit(); + PgArchShmemInit(); ApplyLauncherShmemInit(); FTSReplicationStatusShmemInit(); diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index e7f9107fbf8c..ca4ee1e9553c 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -3,26 +3,27 @@ * latch.c * Routines for inter-process latches * - * The Unix implementation uses the so-called self-pipe trick to overcome the - * race condition involved with poll() (or epoll_wait() on linux) and setting - * a global flag in the signal handler. When a latch is set and the current - * process is waiting for it, the signal handler wakes up the poll() in - * WaitLatch by writing a byte to a pipe. A signal by itself doesn't interrupt - * poll() on all platforms, and even on platforms where it does, a signal that - * arrives just before the poll() call does not prevent poll() from entering - * sleep. An incoming byte on a pipe however reliably interrupts the sleep, - * and causes poll() to return immediately even if the signal arrives before - * poll() begins. + * The poll() implementation uses the so-called self-pipe trick to overcome the + * race condition involved with poll() and setting a global flag in the signal + * handler. When a latch is set and the current process is waiting for it, the + * signal handler wakes up the poll() in WaitLatch by writing a byte to a pipe. + * A signal by itself doesn't interrupt poll() on all platforms, and even on + * platforms where it does, a signal that arrives just before the poll() call + * does not prevent poll() from entering sleep. An incoming byte on a pipe + * however reliably interrupts the sleep, and causes poll() to return + * immediately even if the signal arrives before poll() begins. * - * When SetLatch is called from the same process that owns the latch, - * SetLatch writes the byte directly to the pipe. If it's owned by another - * process, SIGUSR1 is sent and the signal handler in the waiting process - * writes the byte to the pipe on behalf of the signaling process. + * The epoll() implementation overcomes the race with a different technique: it + * keeps SIGURG blocked and consumes from a signalfd() descriptor instead. We + * don't need to register a signal handler or create our own self-pipe. We + * assume that any system that has Linux epoll() also has Linux signalfd(). + * + * The kqueue() implementation waits for SIGURG with EVFILT_SIGNAL. * * The Windows implementation uses Windows events that are inherited by all * postmaster child processes. There's no need for the self-pipe trick there. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -46,6 +47,7 @@ #include #endif +#include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" @@ -79,6 +81,10 @@ #error "no wait set implementation available" #endif +#ifdef WAIT_USE_EPOLL +#include +#endif + /* typedef in latch.h */ struct WaitEventSet { @@ -139,7 +145,14 @@ static WaitEventSet *LatchWaitSet; #ifndef WIN32 /* Are we currently in WaitLatch? The signal handler would like to know. */ static volatile sig_atomic_t waiting = false; +#endif +#ifdef WAIT_USE_EPOLL +/* On Linux, we'll receive SIGURG via a signalfd file descriptor. */ +static int signal_fd = -1; +#endif + +#if defined(WAIT_USE_POLL) /* Read and write ends of the self-pipe */ static int selfpipe_readfd = -1; static int selfpipe_writefd = -1; @@ -148,9 +161,13 @@ static int selfpipe_writefd = -1; static int selfpipe_owner_pid = 0; /* Private function prototypes */ +static void latch_sigurg_handler(SIGNAL_ARGS); static void sendSelfPipeByte(void); -static void drainSelfPipe(void); -#endif /* WIN32 */ +#endif + +#if defined(WAIT_USE_POLL) || defined(WAIT_USE_EPOLL) +static void drain(void); +#endif #if defined(WAIT_USE_EPOLL) static void WaitEventAdjustEpoll(WaitEventSet *set, WaitEvent *event, int action); @@ -174,7 +191,7 @@ static inline int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, void InitializeLatchSupport(void) { -#ifndef WIN32 +#if defined(WAIT_USE_POLL) int pipefd[2]; if (IsUnderPostmaster) @@ -244,8 +261,28 @@ InitializeLatchSupport(void) /* Tell fd.c about these two long-lived FDs */ ReserveExternalFD(); ReserveExternalFD(); -#else - /* currently, nothing to do here for Windows */ + + pqsignal(SIGURG, latch_sigurg_handler); +#endif + +#ifdef WAIT_USE_EPOLL + sigset_t signalfd_mask; + + /* Block SIGURG, because we'll receive it through a signalfd. */ + sigaddset(&UnBlockSig, SIGURG); + + /* Set up the signalfd to receive SIGURG notifications. */ + sigemptyset(&signalfd_mask); + sigaddset(&signalfd_mask, SIGURG); + signal_fd = signalfd(-1, &signalfd_mask, SFD_NONBLOCK | SFD_CLOEXEC); + if (signal_fd < 0) + elog(FATAL, "signalfd() failed"); + ReserveExternalFD(); +#endif + +#ifdef WAIT_USE_KQUEUE + /* Ignore SIGURG, because we'll receive it via kqueue. */ + pqsignal(SIGURG, SIG_IGN); #endif } @@ -267,6 +304,33 @@ InitializeLatchWaitSet(void) Assert(latch_pos == LatchWaitSetLatchPos); } +void +ShutdownLatchSupport(void) +{ +#if defined(WAIT_USE_POLL) + pqsignal(SIGURG, SIG_IGN); +#endif + + if (LatchWaitSet) + { + FreeWaitEventSet(LatchWaitSet); + LatchWaitSet = NULL; + } + +#if defined(WAIT_USE_POLL) + close(selfpipe_readfd); + close(selfpipe_writefd); + selfpipe_readfd = -1; + selfpipe_writefd = -1; + selfpipe_owner_pid = InvalidPid; +#endif + +#if defined(WAIT_USE_EPOLL) + close(signal_fd); + signal_fd = -1; +#endif +} + /* * Initialize a process-local latch. */ @@ -274,13 +338,14 @@ void InitLatch(Latch *latch) { latch->is_set = false; + latch->maybe_sleeping = false; latch->owner_pid = MyProcPid; latch->is_shared = false; -#ifndef WIN32 +#if defined(WAIT_USE_POLL) /* Assert InitializeLatchSupport has been called in this process */ Assert(selfpipe_readfd >= 0 && selfpipe_owner_pid == MyProcPid); -#else +#elif defined(WAIT_USE_WIN32) latch->event = CreateEvent(NULL, TRUE, FALSE, NULL); if (latch->event == NULL) elog(ERROR, "CreateEvent failed: error code %lu", GetLastError()); @@ -321,6 +386,7 @@ InitSharedLatch(Latch *latch) #endif latch->is_set = false; + latch->maybe_sleeping = false; latch->owner_pid = 0; latch->is_shared = true; } @@ -333,10 +399,6 @@ InitSharedLatch(Latch *latch) * any sort of locking here, meaning that we could fail to detect the error * if two processes try to own the same latch at about the same time. If * there is any risk of that, caller must provide an interlock to prevent it. - * - * In any process that calls OwnLatch(), make sure that - * latch_sigusr1_handler() is called from the SIGUSR1 signal handler, - * as shared latches use SIGUSR1 for inter-process communication. */ void OwnLatch(Latch *latch) @@ -344,7 +406,7 @@ OwnLatch(Latch *latch) /* Sanity checks */ Assert(latch->is_shared); -#ifndef WIN32 +#if defined(WAIT_USE_POLL) /* Assert InitializeLatchSupport has been called in this process */ Assert(selfpipe_readfd >= 0 && selfpipe_owner_pid == MyProcPid); #endif @@ -524,13 +586,17 @@ SetLatch(Latch *latch) latch->is_set = true; + pg_memory_barrier(); + if (!latch->maybe_sleeping) + return; + #ifndef WIN32 /* * See if anyone's waiting for the latch. It can be the current process if - * we're in a signal handler. We use the self-pipe to wake up the - * poll()/epoll_wait() in that case. If it's another process, send a - * signal. + * we're in a signal handler. We use the self-pipe or SIGURG to ourselves + * to wake up WaitEventSetWaitBlock() without races in that case. If it's + * another process, send a signal. * * Fetch owner_pid only once, in case the latch is concurrently getting * owned or disowned. XXX: This assumes that pid_t is atomic, which isn't @@ -553,11 +619,17 @@ SetLatch(Latch *latch) return; else if (owner_pid == MyProcPid) { +#if defined(WAIT_USE_POLL) if (waiting) sendSelfPipeByte(); +#else + if (waiting) + kill(MyProcPid, SIGURG); +#endif } else - kill(owner_pid, SIGUSR1); + kill(owner_pid, SIGURG); + #else /* @@ -590,6 +662,7 @@ ResetLatch(Latch *latch) { /* Only the owner should reset the latch */ Assert(latch->owner_pid == MyProcPid); + Assert(latch->maybe_sleeping == false); latch->is_set = false; @@ -667,31 +740,12 @@ CreateWaitEventSet(MemoryContext context, int nevents) /* treat this as though epoll_create1 itself returned EMFILE */ elog(ERROR, "epoll_create1 failed: %m"); } -#ifdef EPOLL_CLOEXEC set->epoll_fd = epoll_create1(EPOLL_CLOEXEC); if (set->epoll_fd < 0) { ReleaseExternalFD(); elog(ERROR, "epoll_create1 failed: %m"); } -#else - /* cope with ancient glibc lacking epoll_create1 (e.g., RHEL5) */ - set->epoll_fd = epoll_create(nevents); - if (set->epoll_fd < 0) - { - ReleaseExternalFD(); - elog(ERROR, "epoll_create failed: %m"); - } - if (fcntl(set->epoll_fd, F_SETFD, FD_CLOEXEC) == -1) - { - int save_errno = errno; - - close(set->epoll_fd); - ReleaseExternalFD(); - errno = save_errno; - elog(ERROR, "fcntl(F_SETFD) failed on epoll descriptor: %m"); - } -#endif /* EPOLL_CLOEXEC */ #elif defined(WAIT_USE_KQUEUE) if (!AcquireExternalFD()) { @@ -737,7 +791,7 @@ CreateWaitEventSet(MemoryContext context, int nevents) * * Note: preferably, this shouldn't have to free any resources that could be * inherited across an exec(). If it did, we'd likely leak those resources in - * many scenarios. For the epoll case, we ensure that by setting FD_CLOEXEC + * many scenarios. For the epoll case, we ensure that by setting EPOLL_CLOEXEC * when the FD is created. For the Windows case, we assume that the handles * involved are non-inheritable. */ @@ -852,8 +906,15 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, { set->latch = latch; set->latch_pos = event->pos; -#ifndef WIN32 +#if defined(WAIT_USE_POLL) event->fd = selfpipe_readfd; +#elif defined(WAIT_USE_EPOLL) + event->fd = signal_fd; +#else + event->fd = PGINVALID_SOCKET; +#ifdef WAIT_USE_EPOLL + return event->pos; +#endif #endif } else if (events == WL_POSTMASTER_DEATH) @@ -925,7 +986,23 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch) if (events == WL_LATCH_SET) { + if (latch && latch->owner_pid != MyProcPid) + elog(ERROR, "cannot wait on a latch owned by another process"); set->latch = latch; + + /* + * On Unix, we don't need to modify the kernel object because the + * underlying pipe (if there is one) is the same for all latches so we + * can return immediately. On Windows, we need to update our array of + * handles, but we leave the old one in place and tolerate spurious + * wakeups if the latch is disabled. + */ +#if defined(WAIT_USE_WIN32) + if (!latch) + return; +#else + return; +#endif } #if defined(WAIT_USE_EPOLL) @@ -985,9 +1062,8 @@ WaitEventAdjustEpoll(WaitEventSet *set, WaitEvent *event, int action) if (rc < 0) ereport(ERROR, (errcode_for_socket_access(), - /* translator: %s is a syscall name, such as "poll()" */ - errmsg("%s failed: %m", - "epoll_ctl()"))); + errmsg("%s() failed: %m", + "epoll_ctl"))); } #endif @@ -1058,6 +1134,18 @@ WaitEventAdjustKqueueAddPostmaster(struct kevent *k_ev, WaitEvent *event) AccessWaitEvent(k_ev) = event; } +static inline void +WaitEventAdjustKqueueAddLatch(struct kevent *k_ev, WaitEvent *event) +{ + /* For now latch can only be added, not removed. */ + k_ev->ident = SIGURG; + k_ev->filter = EVFILT_SIGNAL; + k_ev->flags = EV_ADD; + k_ev->fflags = 0; + k_ev->data = 0; + AccessWaitEvent(k_ev) = event; +} + /* * old_events is the previous event mask, used to compute what has changed. */ @@ -1089,6 +1177,11 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events) */ WaitEventAdjustKqueueAddPostmaster(&k_ev[count++], event); } + else if (event->events == WL_LATCH_SET) + { + /* We detect latch wakeup using a signal event. */ + WaitEventAdjustKqueueAddLatch(&k_ev[count++], event); + } else { /* @@ -1096,11 +1189,9 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events) * old event mask to the new event mask, since kevent treats readable * and writable as separate events. */ - if (old_events == WL_LATCH_SET || - (old_events & WL_SOCKET_READABLE)) + if (old_events & WL_SOCKET_READABLE) old_filt_read = true; - if (event->events == WL_LATCH_SET || - (event->events & WL_SOCKET_READABLE)) + if (event->events & WL_SOCKET_READABLE) new_filt_read = true; if (old_events & WL_SOCKET_WRITEABLE) old_filt_write = true; @@ -1134,14 +1225,14 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events) if (rc < 0) { - if (event->events == WL_POSTMASTER_DEATH && errno == ESRCH) + if (event->events == WL_POSTMASTER_DEATH && + (errno == ESRCH || errno == EACCES)) set->report_postmaster_not_running = true; else ereport(ERROR, (errcode_for_socket_access(), - /* translator: %s is a syscall name, such as "poll()" */ - errmsg("%s failed: %m", - "kevent()"))); + errmsg("%s() failed: %m", + "kevent"))); } else if (event->events == WL_POSTMASTER_DEATH && PostmasterPid != getppid() && @@ -1188,11 +1279,11 @@ WaitEventAdjustWin32(WaitEventSet *set, WaitEvent *event) { *handle = WSACreateEvent(); if (*handle == WSA_INVALID_EVENT) - elog(ERROR, "failed to create event for socket: error code %u", + elog(ERROR, "failed to create event for socket: error code %d", WSAGetLastError()); } if (WSAEventSelect(event->fd, *handle, flags) != 0) - elog(ERROR, "failed to set up event for socket: error code %u", + elog(ERROR, "failed to set up event for socket: error code %d", WSAGetLastError()); Assert(event->fd != PGINVALID_SOCKET); @@ -1263,7 +1354,7 @@ WaitEventSetWait(WaitEventSet *set, long timeout, * the pipe-buffer fill up we're still ok, because the pipe is in * nonblocking mode. It's unlikely for that to happen, because the * self pipe isn't filled unless we're blocking (waiting = true), or - * from inside a signal handler in latch_sigusr1_handler(). + * from inside a signal handler in latch_sigurg_handler(). * * On windows, we'll also notice if there's a pending event for the * latch when blocking, but there's no danger of anything filling up, @@ -1274,6 +1365,14 @@ WaitEventSetWait(WaitEventSet *set, long timeout, * ordering, so that we cannot miss seeing is_set if a notification * has already been queued. */ + if (set->latch && !set->latch->is_set) + { + /* about to sleep on a latch */ + set->latch->maybe_sleeping = true; + pg_memory_barrier(); + /* and recheck */ + } + if (set->latch && set->latch->is_set) { occurred_events->fd = PGINVALID_SOCKET; @@ -1284,6 +1383,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout, occurred_events++; returned_events++; + /* could have been set above */ + set->latch->maybe_sleeping = false; + break; } @@ -1295,6 +1397,12 @@ WaitEventSetWait(WaitEventSet *set, long timeout, rc = WaitEventSetWaitBlock(set, cur_timeout, occurred_events, nevents); + if (set->latch) + { + Assert(set->latch->maybe_sleeping); + set->latch->maybe_sleeping = false; + } + if (rc == -1) break; /* timeout occurred */ else @@ -1352,9 +1460,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, waiting = false; ereport(ERROR, (errcode_for_socket_access(), - /* translator: %s is a syscall name, such as "poll()" */ - errmsg("%s failed: %m", - "epoll_wait()"))); + errmsg("%s() failed: %m", + "epoll_wait"))); } return 0; } @@ -1384,10 +1491,10 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, if (cur_event->events == WL_LATCH_SET && cur_epoll_event->events & (EPOLLIN | EPOLLERR | EPOLLHUP)) { - /* There's data in the self-pipe, clear it. */ - drainSelfPipe(); + /* Drain the signalfd. */ + drain(); - if (set->latch->is_set) + if (set->latch && set->latch->is_set) { occurred_events->fd = PGINVALID_SOCKET; occurred_events->events = WL_LATCH_SET; @@ -1478,7 +1585,10 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, timeout_p = &timeout; } - /* Report events discovered by WaitEventAdjustKqueue(). */ + /* + * Report postmaster events discovered by WaitEventAdjustKqueue() or an + * earlier call to WaitEventSetWait(). + */ if (unlikely(set->report_postmaster_not_running)) { if (set->exit_on_postmaster_death) @@ -1502,9 +1612,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, waiting = false; ereport(ERROR, (errcode_for_socket_access(), - /* translator: %s is a syscall name, such as "poll()" */ - errmsg("%s failed: %m", - "kevent()"))); + errmsg("%s() failed: %m", + "kevent"))); } return 0; } @@ -1532,12 +1641,9 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, occurred_events->events = 0; if (cur_event->events == WL_LATCH_SET && - cur_kqueue_event->filter == EVFILT_READ) + cur_kqueue_event->filter == EVFILT_SIGNAL) { - /* There's data in the self-pipe, clear it. */ - drainSelfPipe(); - - if (set->latch->is_set) + if (set->latch && set->latch->is_set) { occurred_events->fd = PGINVALID_SOCKET; occurred_events->events = WL_LATCH_SET; @@ -1549,6 +1655,13 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, cur_kqueue_event->filter == EVFILT_PROC && (cur_kqueue_event->fflags & NOTE_EXIT) != 0) { + /* + * The kernel will tell this kqueue object only once about the + * exit of the postmaster, so let's remember that for next time so + * that we provide level-triggered semantics. + */ + set->report_postmaster_not_running = true; + if (set->exit_on_postmaster_death) proc_exit(1); occurred_events->fd = PGINVALID_SOCKET; @@ -1615,9 +1728,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, waiting = false; ereport(ERROR, (errcode_for_socket_access(), - /* translator: %s is a syscall name, such as "poll()" */ - errmsg("%s failed: %m", - "poll()"))); + errmsg("%s() failed: %m", + "poll"))); } return 0; } @@ -1644,9 +1756,9 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, (cur_pollfd->revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL))) { /* There's data in the self-pipe, clear it. */ - drainSelfPipe(); + drain(); - if (set->latch->is_set) + if (set->latch && set->latch->is_set) { occurred_events->fd = PGINVALID_SOCKET; occurred_events->events = WL_LATCH_SET; @@ -1810,10 +1922,14 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, if (cur_event->events == WL_LATCH_SET) { - if (!ResetEvent(set->latch->event)) + /* + * We cannot use set->latch->event to reset the fired event if we + * aren't waiting on this latch now. + */ + if (!ResetEvent(set->handles[cur_event->pos + 1])) elog(ERROR, "ResetEvent failed: error code %lu", GetLastError()); - if (set->latch->is_set) + if (set->latch && set->latch->is_set) { occurred_events->fd = PGINVALID_SOCKET; occurred_events->events = WL_LATCH_SET; @@ -1851,7 +1967,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, ZeroMemory(&resEvents, sizeof(resEvents)); if (WSAEnumNetworkEvents(cur_event->fd, handle, &resEvents) != 0) - elog(ERROR, "failed to enumerate network events: error code %u", + elog(ERROR, "failed to enumerate network events: error code %d", WSAGetLastError()); if ((cur_event->events & WL_SOCKET_READABLE) && (resEvents.lNetworkEvents & FD_READ)) @@ -1901,26 +2017,33 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, #endif /* - * SetLatch uses SIGUSR1 to wake up the process waiting on the latch. - * - * Wake up WaitLatch, if we're waiting. (We might not be, since SIGUSR1 is - * overloaded for multiple purposes; or we might not have reached WaitLatch - * yet, in which case we don't need to fill the pipe either.) + * Get the number of wait events registered in a given WaitEventSet. + */ +int +GetNumRegisteredWaitEvents(WaitEventSet *set) +{ + return set->nevents; +} + +#if defined(WAIT_USE_POLL) + +/* + * SetLatch uses SIGURG to wake up the process waiting on the latch. * - * NB: when calling this in a signal handler, be sure to save and restore - * errno around it. + * Wake up WaitLatch, if we're waiting. */ -#ifndef WIN32 -void -latch_sigusr1_handler(void) +static void +latch_sigurg_handler(SIGNAL_ARGS) { + int save_errno = errno; + if (waiting) sendSelfPipeByte(); + + errno = save_errno; } -#endif /* !WIN32 */ /* Send one byte to the self-pipe, to wake up WaitLatch */ -#ifndef WIN32 static void sendSelfPipeByte(void) { @@ -1950,45 +2073,58 @@ sendSelfPipeByte(void) return; } } -#endif /* !WIN32 */ + +#endif + +#if defined(WAIT_USE_POLL) || defined(WAIT_USE_EPOLL) /* - * Read all available data from the self-pipe + * Read all available data from self-pipe or signalfd. * * Note: this is only called when waiting = true. If it fails and doesn't * return, it must reset that flag first (though ideally, this will never * happen). */ -#ifndef WIN32 static void -drainSelfPipe(void) +drain(void) { - /* - * There shouldn't normally be more than one byte in the pipe, or maybe a - * few bytes if multiple processes run SetLatch at the same instant. - */ - char buf[16]; + char buf[1024]; int rc; + int fd; + +#ifdef WAIT_USE_POLL + fd = selfpipe_readfd; +#else + fd = signal_fd; +#endif for (;;) { - rc = read(selfpipe_readfd, buf, sizeof(buf)); + rc = read(fd, buf, sizeof(buf)); if (rc < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) - break; /* the pipe is empty */ + break; /* the descriptor is empty */ else if (errno == EINTR) continue; /* retry */ else { waiting = false; +#ifdef WAIT_USE_POLL elog(ERROR, "read() on self-pipe failed: %m"); +#else + elog(ERROR, "read() on signalfd failed: %m"); +#endif } } else if (rc == 0) { waiting = false; +#ifdef WAIT_USE_POLL elog(ERROR, "unexpected EOF on self-pipe"); +#else + elog(ERROR, "unexpected EOF on signalfd"); +#endif } else if (rc < sizeof(buf)) { @@ -1998,4 +2134,5 @@ drainSelfPipe(void) /* else buffer wasn't big enough, so read again */ } } -#endif /* !WIN32 */ + +#endif diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c index 94c65877c18d..280c2395c9ed 100644 --- a/src/backend/storage/ipc/pmsignal.c +++ b/src/backend/storage/ipc/pmsignal.c @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pmsignal.c - * routines for signaling the postmaster from its child processes + * routines for signaling between the postmaster and its child processes * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -55,6 +55,10 @@ * but carries the extra information that the child is a WAL sender. * WAL senders too start in ACTIVE state, but switch to WALSENDER once they * start streaming the WAL (and they never go back to ACTIVE after that). + * + * We also have a shared-memory field that is used for communication in + * the opposite direction, from postmaster to children: it tells why the + * postmaster has broadcasted SIGQUIT signals, if indeed it has done so. */ #define PM_CHILD_UNUSED 0 /* these values must fit in sig_atomic_t */ @@ -65,8 +69,10 @@ /* "typedef struct PMSignalData PMSignalData" appears in pmsignal.h */ struct PMSignalData { - /* per-reason flags */ + /* per-reason flags for signaling the postmaster */ sig_atomic_t PMSignalFlags[NUM_PMSIGNALS]; + /* global flags for signals from postmaster to children */ + QuitSignalReason sigquit_reason; /* why SIGQUIT was sent */ /* per-child-process flags */ int num_child_flags; /* # of entries in PMChildFlags[] */ int next_child_flag; /* next slot to try to assign */ @@ -134,6 +140,7 @@ PMSignalShmemInit(void) if (!found) { + /* initialize all flags to zeroes */ MemSet(unvolatize(PMSignalData *, PMSignalState), 0, PMSignalShmemSize()); PMSignalState->num_child_flags = MaxLivePostmasterChildren(); } @@ -171,6 +178,34 @@ CheckPostmasterSignal(PMSignalReason reason) return false; } +/* + * SetQuitSignalReason - broadcast the reason for a system shutdown. + * Should be called by postmaster before sending SIGQUIT to children. + * + * Note: in a crash-and-restart scenario, the "reason" field gets cleared + * as a part of rebuilding shared memory; the postmaster need not do it + * explicitly. + */ +void +SetQuitSignalReason(QuitSignalReason reason) +{ + PMSignalState->sigquit_reason = reason; +} + +/* + * GetQuitSignalReason - obtain the reason for a system shutdown. + * Called by child processes when they receive SIGQUIT. + * If the postmaster hasn't actually sent SIGQUIT, will return PMQUIT_NOT_SENT. + */ +QuitSignalReason +GetQuitSignalReason(void) +{ + /* This is called in signal handlers, so be extra paranoid. */ + if (!IsUnderPostmaster || PMSignalState == NULL) + return PMQUIT_NOT_SENT; + return PMSignalState->sigquit_reason; +} + /* * AssignPostmasterChildSlot - select an unused slot for a new postmaster diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 4bb244bf2e43..e0dabfe3ef37 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -34,7 +34,7 @@ * happen, it would tie up KnownAssignedXids indefinitely, so we protect * ourselves by pruning the array when a valid list of running XIDs arrives. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -143,7 +143,7 @@ typedef struct ProcArrayStruct * different types of relations. As e.g. a normal user defined table in one * database is inaccessible to backends connected to another database, a test * specific to a relation can be more aggressive than a test for a shared - * relation. Currently we track three different states: + * relation. Currently we track four different states: * * 1) GlobalVisSharedRels, which only considers an XID's * effects visible-to-everyone if neither snapshots in any database, nor a @@ -158,13 +158,16 @@ typedef struct ProcArrayStruct * I.e. the difference to GlobalVisSharedRels is that * snapshot in other databases are ignored. * - * 3) GlobalVisCatalogRels, which only considers an XID's + * 3) GlobalVisDataRels, which only considers an XID's * effects visible-to-everyone if neither snapshots in the current * database, nor a replication slot's xmin consider XID as running. * * I.e. the difference to GlobalVisCatalogRels is that * replication slot's catalog_xmin is not taken into account. * + * 4) GlobalVisTempRels, which only considers the current session, as temp + * tables are not visible to other sessions. + * * GlobalVisTestFor(relation) returns the appropriate state * for the relation. * @@ -246,6 +249,13 @@ typedef struct ComputeXidHorizonsResult * defined tables. */ TransactionId data_oldest_nonremovable; + + /* + * Oldest xid for which deleted tuples need to be retained in this + * session's temporary tables. + */ + TransactionId temp_oldest_nonremovable; + } ComputeXidHorizonsResult; @@ -270,12 +280,13 @@ static TransactionId standbySnapshotPendingXmin; /* * State for visibility checks on different types of relations. See struct - * GlobalVisState for details. As shared, catalog, and user defined + * GlobalVisState for details. As shared, catalog, normal and temporary * relations can have different horizons, one such state exists for each. */ static GlobalVisState GlobalVisSharedRels; static GlobalVisState GlobalVisCatalogRels; static GlobalVisState GlobalVisDataRels; +static GlobalVisState GlobalVisTempRels; /* * This backend's RecentXmin at the last time the accurate xmin horizon was @@ -449,6 +460,7 @@ ProcArrayAdd(PGPROC *proc) { ProcArrayStruct *arrayP = procArray; int index; + int movecount; /* See ProcGlobal comment explaining why both locks are held */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); @@ -479,33 +491,48 @@ ProcArrayAdd(PGPROC *proc) */ for (index = 0; index < arrayP->numProcs; index++) { - /* - * If we are the first PGPROC or if we have found our right position - * in the array, break - */ - if ((arrayP->pgprocnos[index] == -1) || (arrayP->pgprocnos[index] > proc->pgprocno)) + int procno PG_USED_FOR_ASSERTS_ONLY = arrayP->pgprocnos[index]; + + Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS)); + Assert(allProcs[procno].pgxactoff == index); + + /* If we have found our right position in the array, break */ + if (arrayP->pgprocnos[index] > proc->pgprocno) break; } - memmove(&arrayP->pgprocnos[index + 1], &arrayP->pgprocnos[index], - (arrayP->numProcs - index) * sizeof(*arrayP->pgprocnos)); - memmove(&ProcGlobal->xids[index + 1], &ProcGlobal->xids[index], - (arrayP->numProcs - index) * sizeof(*ProcGlobal->xids)); - memmove(&ProcGlobal->subxidStates[index + 1], &ProcGlobal->subxidStates[index], - (arrayP->numProcs - index) * sizeof(*ProcGlobal->subxidStates)); - memmove(&ProcGlobal->vacuumFlags[index + 1], &ProcGlobal->vacuumFlags[index], - (arrayP->numProcs - index) * sizeof(*ProcGlobal->vacuumFlags)); + movecount = arrayP->numProcs - index; + memmove(&arrayP->pgprocnos[index + 1], + &arrayP->pgprocnos[index], + movecount * sizeof(*arrayP->pgprocnos)); + memmove(&ProcGlobal->xids[index + 1], + &ProcGlobal->xids[index], + movecount * sizeof(*ProcGlobal->xids)); + memmove(&ProcGlobal->subxidStates[index + 1], + &ProcGlobal->subxidStates[index], + movecount * sizeof(*ProcGlobal->subxidStates)); + memmove(&ProcGlobal->statusFlags[index + 1], + &ProcGlobal->statusFlags[index], + movecount * sizeof(*ProcGlobal->statusFlags)); arrayP->pgprocnos[index] = proc->pgprocno; + proc->pgxactoff = index; ProcGlobal->xids[index] = proc->xid; ProcGlobal->subxidStates[index] = proc->subxidStatus; - ProcGlobal->vacuumFlags[index] = proc->vacuumFlags; + ProcGlobal->statusFlags[index] = proc->statusFlags; arrayP->numProcs++; + /* adjust pgxactoff for all following PGPROCs */ + index++; for (; index < arrayP->numProcs; index++) { - allProcs[arrayP->pgprocnos[index]].pgxactoff = index; + int procno = arrayP->pgprocnos[index]; + + Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS)); + Assert(allProcs[procno].pgxactoff == index - 1); + + allProcs[procno].pgxactoff = index; } /* @@ -530,7 +557,8 @@ void ProcArrayRemove(PGPROC *proc, TransactionId latestXid) { ProcArrayStruct *arrayP = procArray; - int index; + int myoff; + int movecount; #ifdef XIDCACHE_DEBUG /* dump stats at backend shutdown, but not prepared-xact end */ @@ -542,11 +570,14 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid) LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - Assert(ProcGlobal->allProcs[arrayP->pgprocnos[proc->pgxactoff]].pgxactoff == proc->pgxactoff); + myoff = proc->pgxactoff; + + Assert(myoff >= 0 && myoff < arrayP->numProcs); + Assert(ProcGlobal->allProcs[arrayP->pgprocnos[myoff]].pgxactoff == myoff); if (TransactionIdIsValid(latestXid)) { - Assert(TransactionIdIsValid(ProcGlobal->xids[proc->pgxactoff])); + Assert(TransactionIdIsValid(ProcGlobal->xids[myoff])); /* Advance global latestCompletedXid while holding the lock */ MaintainLatestCompletedXid(latestXid); @@ -554,14 +585,14 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid) /* Same with xactCompletionCount */ ShmemVariableCache->xactCompletionCount++; - ProcGlobal->xids[proc->pgxactoff] = 0; - ProcGlobal->subxidStates[proc->pgxactoff].overflowed = false; - ProcGlobal->subxidStates[proc->pgxactoff].count = 0; + ProcGlobal->xids[myoff] = InvalidTransactionId; + ProcGlobal->subxidStates[myoff].overflowed = false; + ProcGlobal->subxidStates[myoff].count = 0; } else { /* Shouldn't be trying to remove a live transaction here */ - Assert(!TransactionIdIsValid(ProcGlobal->xids[proc->pgxactoff])); + Assert(!TransactionIdIsValid(ProcGlobal->xids[myoff])); } if (Gp_role == GP_ROLE_DISPATCH) @@ -580,44 +611,51 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid) Assert(TransactionIdIsValid(ProcGlobal->xids[proc->pgxactoff] == 0)); Assert(TransactionIdIsValid(ProcGlobal->subxidStates[proc->pgxactoff].count == 0)); Assert(TransactionIdIsValid(ProcGlobal->subxidStates[proc->pgxactoff].overflowed == false)); - ProcGlobal->vacuumFlags[proc->pgxactoff] = 0; + ProcGlobal->statusFlags[proc->pgxactoff] = 0; + Assert(!TransactionIdIsValid(ProcGlobal->xids[myoff])); + Assert(ProcGlobal->subxidStates[myoff].count == 0); + Assert(ProcGlobal->subxidStates[myoff].overflowed == false); + + ProcGlobal->statusFlags[myoff] = 0; + + /* Keep the PGPROC array sorted. See notes above */ + movecount = arrayP->numProcs - myoff - 1; + memmove(&arrayP->pgprocnos[myoff], + &arrayP->pgprocnos[myoff + 1], + movecount * sizeof(*arrayP->pgprocnos)); + memmove(&ProcGlobal->xids[myoff], + &ProcGlobal->xids[myoff + 1], + movecount * sizeof(*ProcGlobal->xids)); + memmove(&ProcGlobal->subxidStates[myoff], + &ProcGlobal->subxidStates[myoff + 1], + movecount * sizeof(*ProcGlobal->subxidStates)); + memmove(&ProcGlobal->statusFlags[myoff], + &ProcGlobal->statusFlags[myoff + 1], + movecount * sizeof(*ProcGlobal->statusFlags)); + + arrayP->pgprocnos[arrayP->numProcs - 1] = -1; /* for debugging */ + arrayP->numProcs--; - for (index = 0; index < arrayP->numProcs; index++) + /* + * Adjust pgxactoff of following procs for removed PGPROC (note that + * numProcs already has been decremented). + */ + for (int index = myoff; index < arrayP->numProcs; index++) { - if (arrayP->pgprocnos[index] == proc->pgprocno) - { - /* Keep the PGPROC array sorted. See notes above */ - memmove(&arrayP->pgprocnos[index], &arrayP->pgprocnos[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*arrayP->pgprocnos)); - memmove(&ProcGlobal->xids[index], &ProcGlobal->xids[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->xids)); - memmove(&ProcGlobal->subxidStates[index], &ProcGlobal->subxidStates[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->subxidStates)); - memmove(&ProcGlobal->vacuumFlags[index], &ProcGlobal->vacuumFlags[index + 1], - (arrayP->numProcs - index - 1) * sizeof(*ProcGlobal->vacuumFlags)); - - arrayP->pgprocnos[arrayP->numProcs - 1] = -1; /* for debugging */ - arrayP->numProcs--; - - /* adjust for removed PGPROC */ - for (; index < arrayP->numProcs; index++) - allProcs[arrayP->pgprocnos[index]].pgxactoff--; + int procno = arrayP->pgprocnos[index]; - /* - * Release in reversed acquisition order, to reduce frequency of - * having to wait for XidGenLock while holding ProcArrayLock. - */ - LWLockRelease(XidGenLock); - LWLockRelease(ProcArrayLock); - return; - } + Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS)); + Assert(allProcs[procno].pgxactoff - 1 == index); + + allProcs[procno].pgxactoff = index; } - /* Oops */ + /* + * Release in reversed acquisition order, to reduce frequency of having to + * wait for XidGenLock while holding ProcArrayLock. + */ LWLockRelease(XidGenLock); LWLockRelease(ProcArrayLock); - - elog(LOG, "failed to find proc %p in ProcArray", proc); } @@ -719,13 +757,38 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid) /* must be cleared with xid/xmin: */ /* avoid unnecessarily dirtying shared cachelines */ - if (proc->vacuumFlags & PROC_VACUUM_STATE_MASK) + if (proc->statusFlags & PROC_VACUUM_STATE_MASK) { + /* + * If we have no XID, we don't need to lock, since we won't affect + * anyone else's calculation of a snapshot. We might change their + * estimate of global xmin, but that's OK. + */ + Assert(!TransactionIdIsValid(proc->xid)); + Assert(proc->subxidStatus.count == 0); + Assert(!proc->subxidStatus.overflowed); + + proc->lxid = InvalidLocalTransactionId; + proc->xmin = InvalidTransactionId; + proc->delayChkpt = false; /* be sure this is cleared in abort */ + proc->recoveryConflictPending = false; + + /* must be cleared with xid/xmin: */ + /* avoid unnecessarily dirtying shared cachelines */ + if (proc->statusFlags & PROC_VACUUM_STATE_MASK) + { + Assert(!LWLockHeldByMe(ProcArrayLock)); + LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); + Assert(proc->statusFlags == ProcGlobal->statusFlags[proc->pgxactoff]); + proc->statusFlags &= ~PROC_VACUUM_STATE_MASK; + ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags; + LWLockRelease(ProcArrayLock); + } Assert(!LWLockHeldByMe(ProcArrayLock)); LWLockAcquire(ProcArrayLock, LW_SHARED); - Assert(proc->vacuumFlags == ProcGlobal->vacuumFlags[proc->pgxactoff]); - proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK; - ProcGlobal->vacuumFlags[proc->pgxactoff] = proc->vacuumFlags; + Assert(proc->statusFlags == ProcGlobal->statusFlags[proc->pgxactoff]); + proc->statusFlags &= ~PROC_VACUUM_STATE_MASK; + ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags; LWLockRelease(ProcArrayLock); } @@ -742,7 +805,11 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid) { size_t pgxactoff = proc->pgxactoff; - Assert(LWLockHeldByMe(ProcArrayLock)); + /* + * Note: we need exclusive lock here because we're going to change other + * processes' PGPROC entries. + */ + Assert(LWLockHeldByMeInMode(ProcArrayLock, LW_EXCLUSIVE)); Assert(TransactionIdIsValid(ProcGlobal->xids[pgxactoff])); Assert(ProcGlobal->xids[pgxactoff] == proc->xid); @@ -755,10 +822,10 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid) /* must be cleared with xid/xmin: */ /* avoid unnecessarily dirtying shared cachelines */ - if (proc->vacuumFlags & PROC_VACUUM_STATE_MASK) + if (proc->statusFlags & PROC_VACUUM_STATE_MASK) { - proc->vacuumFlags &= ~PROC_VACUUM_STATE_MASK; - ProcGlobal->vacuumFlags[proc->pgxactoff] = proc->vacuumFlags; + proc->statusFlags &= ~PROC_VACUUM_STATE_MASK; + ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags; } /* Clear the subtransaction-XID cache too while holding the lock */ @@ -943,7 +1010,8 @@ ProcArrayClearTransaction(PGPROC *proc) proc->localDistribXactData.state = LOCALDISTRIBXACT_STATE_NONE; - Assert(!(proc->vacuumFlags & PROC_VACUUM_STATE_MASK)); + Assert(!(proc->statusFlags & PROC_VACUUM_STATE_MASK)); + Assert(!(proc->statusFlags & PROC_VACUUM_STATE_MASK)); Assert(!proc->delayChkpt); /* @@ -1274,6 +1342,11 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) */ MaintainLatestCompletedXidRecovery(running->latestCompletedXid); + /* + * NB: No need to increment ShmemVariableCache->xactCompletionCount here, + * nobody can see it yet. + */ + LWLockRelease(ProcArrayLock); /* ShmemVariableCache->nextXid must be beyond any observed xid. */ @@ -1664,16 +1737,22 @@ TransactionIdIsActive(TransactionId xid) * well as "internally" by GlobalVisUpdate() (see comment above struct * GlobalVisState). * - * See the definition of ComputedXidHorizonsResult for the various computed + * See the definition of ComputeXidHorizonsResult for the various computed * horizons. * - * For VACUUM separate horizons (used to to decide which deleted tuples must + * For VACUUM separate horizons (used to decide which deleted tuples must * be preserved), for shared and non-shared tables are computed. For shared * relations backends in all databases must be considered, but for non-shared * relations that's not required, since only backends in my own database could * ever see the tuples in them. Also, we can ignore concurrently running lazy * VACUUMs because (a) they must be working on other tables, and (b) they - * don't need to do snapshot-based lookups. + * don't need to do snapshot-based lookups. Similarly, for the non-catalog + * horizon, we can ignore CREATE INDEX CONCURRENTLY and REINDEX CONCURRENTLY + * when they are working on non-partial, non-expressional indexes, for the + * same reasons and because they can't run in transaction blocks. (They are + * not possible to ignore for catalogs, because CIC and RC do some catalog + * operations.) Do note that this means that CIC and RC must use a lock level + * that conflicts with VACUUM. * * This also computes a horizon used to truncate pg_subtrans. For that * backends in all databases have to be considered, and concurrently running @@ -1730,9 +1809,6 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) bool in_recovery = RecoveryInProgress(); TransactionId *other_xids = ProcGlobal->xids; - /* inferred after ProcArrayLock is released */ - h->catalog_oldest_nonremovable = InvalidTransactionId; - LWLockAcquire(ProcArrayLock, LW_SHARED); h->latest_completed = ShmemVariableCache->latestCompletedXid; @@ -1752,7 +1828,25 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) h->oldest_considered_running = initial; h->shared_oldest_nonremovable = initial; + h->catalog_oldest_nonremovable = initial; h->data_oldest_nonremovable = initial; + + /* + * Only modifications made by this backend affect the horizon for + * temporary relations. Instead of a check in each iteration of the + * loop over all PGPROCs it is cheaper to just initialize to the + * current top-level xid any. + * + * Without an assigned xid we could use a horizon as aggressive as + * ReadNewTransactionid(), but we can get away with the much cheaper + * latestCompletedXid + 1: If this backend has no xid there, by + * definition, can't be any newer changes in the temp table than + * latestCompletedXid. + */ + if (TransactionIdIsValid(MyProc->xid)) + h->temp_oldest_nonremovable = MyProc->xid; + else + h->temp_oldest_nonremovable = initial; } /* @@ -1767,7 +1861,7 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) { int pgprocno = arrayP->pgprocnos[index]; PGPROC *proc = &allProcs[pgprocno]; - int8 vacuumFlags = ProcGlobal->vacuumFlags[index]; + int8 statusFlags = ProcGlobal->statusFlags[index]; TransactionId xid; TransactionId xmin; @@ -1784,8 +1878,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) */ xmin = TransactionIdOlder(xmin, xid); - /* if neither is set, this proc doesn't influence the horizon */ - if (!TransactionIdIsValid(xmin)) + /* if neither is set, this proc doesn't influence the horizon */ + if (!TransactionIdIsValid(xmin)) continue; /* @@ -1802,10 +1896,10 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) * removed, as long as pg_subtrans is not truncated) or doing logical * decoding (which manages xmin separately, check below). */ - if (vacuumFlags & (PROC_IN_VACUUM | PROC_IN_LOGICAL_DECODING)) + if (statusFlags & (PROC_IN_VACUUM | PROC_IN_LOGICAL_DECODING)) continue; - /* shared tables need to take backends in all database into account */ + /* shared tables need to take backends in all databases into account */ h->shared_oldest_nonremovable = TransactionIdOlder(h->shared_oldest_nonremovable, xmin); @@ -1814,16 +1908,38 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) * the shared horizon. But in recovery we cannot compute an accurate * per-database horizon as all xids are managed via the * KnownAssignedXids machinery. + * + * Be careful to compute a pessimistic value when MyDatabaseId is not + * set. If this is a backend in the process of starting up, we may not + * use a "too aggressive" horizon (otherwise we could end up using it + * to prune still needed data away). If the current backend never + * connects to a database that is harmless, because + * data_oldest_nonremovable will never be utilized. */ if (in_recovery || - proc->databaseId == MyDatabaseId || + MyDatabaseId == InvalidOid || proc->databaseId == MyDatabaseId || proc->databaseId == 0) /* always include WalSender */ { - h->data_oldest_nonremovable = - TransactionIdOlder(h->data_oldest_nonremovable, xmin); + /* + * We can ignore this backend if it's running CREATE INDEX + * CONCURRENTLY or REINDEX CONCURRENTLY on a "safe" index -- but + * only on vacuums of user-defined tables. + */ + if (!(statusFlags & PROC_IN_SAFE_IC)) + h->data_oldest_nonremovable = + TransactionIdOlder(h->data_oldest_nonremovable, xmin); + + /* Catalog tables need to consider all backends in this db */ + h->catalog_oldest_nonremovable = + TransactionIdOlder(h->catalog_oldest_nonremovable, xmin); + } } + /* catalog horizon should never be later than data */ + Assert(TransactionIdPrecedesOrEquals(h->catalog_oldest_nonremovable, + h->data_oldest_nonremovable)); + /* * If in recovery fetch oldest xid in KnownAssignedXids, will be applied * after lock is released. @@ -1845,6 +1961,9 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) TransactionIdOlder(h->shared_oldest_nonremovable, kaxmin); h->data_oldest_nonremovable = TransactionIdOlder(h->data_oldest_nonremovable, kaxmin); + h->catalog_oldest_nonremovable = + TransactionIdOlder(h->catalog_oldest_nonremovable, kaxmin); + /* temp relations cannot be accessed in recovery */ } else { @@ -1870,6 +1989,10 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) h->data_oldest_nonremovable = TransactionIdRetreatedBy(h->data_oldest_nonremovable, vacuum_defer_cleanup_age); + h->catalog_oldest_nonremovable = + TransactionIdRetreatedBy(h->catalog_oldest_nonremovable, + vacuum_defer_cleanup_age); + /* defer doesn't apply to temp relations */ } /* @@ -1891,7 +2014,9 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) h->shared_oldest_nonremovable = TransactionIdOlder(h->shared_oldest_nonremovable, h->slot_catalog_xmin); - h->catalog_oldest_nonremovable = h->data_oldest_nonremovable; + h->catalog_oldest_nonremovable = + TransactionIdOlder(h->catalog_oldest_nonremovable, + h->slot_xmin); h->catalog_oldest_nonremovable = TransactionIdOlder(h->catalog_oldest_nonremovable, h->slot_catalog_xmin); @@ -1929,6 +2054,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h) h->catalog_oldest_nonremovable)); Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running, h->data_oldest_nonremovable)); + Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running, + h->temp_oldest_nonremovable)); Assert(!TransactionIdIsValid(h->slot_xmin) || TransactionIdPrecedesOrEquals(h->oldest_considered_running, h->slot_xmin)); @@ -1983,10 +2110,13 @@ GetLocalOldestNonRemovableTransactionId(Relation rel) ComputeXidHorizons(&horizons); /* select horizon appropriate for relation */ - if (rel == NULL || rel->rd_rel->relisshared) + if (rel == NULL || rel->rd_rel->relisshared || RecoveryInProgress()) return horizons.shared_oldest_nonremovable; - else if (RelationIsAccessibleInLogicalDecoding(rel)) + else if (IsCatalogRelation(rel) || + RelationIsAccessibleInLogicalDecoding(rel)) return horizons.catalog_oldest_nonremovable; + else if (RELATION_IS_LOCAL(rel)) + return horizons.temp_oldest_nonremovable; else return horizons.data_oldest_nonremovable; } @@ -2627,7 +2757,7 @@ GetSnapshotDataInitOldSnapshot(Snapshot snapshot) static bool GetSnapshotDataReuse(Snapshot snapshot) { - uint64 curXactCompletionCount; + uint64 curXactCompletionCount; Assert(LWLockHeldByMe(ProcArrayLock)); @@ -2651,8 +2781,8 @@ GetSnapshotDataReuse(Snapshot snapshot) * holding ProcArrayLock) exclusively). Thus the xactCompletionCount check * ensures we would detect if the snapshot would have changed. * - * As the snapshot contents are the same as it was before, it is is safe - * to re-enter the snapshot's xmin into the PGPROC array. None of the rows + * As the snapshot contents are the same as it was before, it is safe to + * re-enter the snapshot's xmin into the PGPROC array. None of the rows * visible under the snapshot could already have been removed (that'd * require the set of running transactions to change) and it fulfills the * requirement that concurrent GetSnapshotData() calls yield the same @@ -2699,8 +2829,8 @@ GetSnapshotDataReuse(Snapshot snapshot) * RecentXmin: the xmin computed for the most recent snapshot. XIDs * older than this are known not running any more. * - * And try to advance the bounds of GlobalVisSharedRels, GlobalVisCatalogRels, - * GlobalVisDataRels for the benefit of theGlobalVisTest* family of functions. + * And try to advance the bounds of GlobalVis{Shared,Catalog,Data,Temp}Rels + * for the benefit of the GlobalVisTest* family of functions. * * Note: this function should probably not be called with an argument that's * not statically allocated (see xip allocation below). @@ -2899,7 +3029,7 @@ GetSnapshotData(Snapshot snapshot, DtxContext distributedTransactionContext) TransactionId *xip = snapshot->xip; int *pgprocnos = arrayP->pgprocnos; XidCacheStatus *subxidStates = ProcGlobal->subxidStates; - uint8 *allVacuumFlags = ProcGlobal->vacuumFlags; + uint8 *allStatusFlags = ProcGlobal->statusFlags; /* * First collect set of pgxactoff/xids that need to be included in the @@ -2909,7 +3039,7 @@ GetSnapshotData(Snapshot snapshot, DtxContext distributedTransactionContext) { /* Fetch xid just once - see GetNewTransactionId */ TransactionId xid = UINT32_ACCESS_ONCE(other_xids[pgxactoff]); - uint8 vacuumFlags; + uint8 statusFlags; Assert(allProcs[arrayP->pgprocnos[pgxactoff]].pgxactoff == pgxactoff); @@ -2929,10 +3059,10 @@ GetSnapshotData(Snapshot snapshot, DtxContext distributedTransactionContext) continue; /* - * The only way we are able to get here with a non-normal xid - * is during bootstrap - with this backend using - * BootstrapTransactionId. But the above test should filter - * that out. + * The only way we are able to get here with a non-normal xid is + * during bootstrap - with this backend using + * BootstrapTransactionId. But the above test should filter that + * out. */ Assert(TransactionIdIsNormal(xid)); @@ -2948,8 +3078,8 @@ GetSnapshotData(Snapshot snapshot, DtxContext distributedTransactionContext) * Skip over backends doing logical decoding which manages xmin * separately (check below) and ones running LAZY VACUUM. */ - vacuumFlags = allVacuumFlags[pgxactoff]; - if (vacuumFlags & (PROC_IN_LOGICAL_DECODING | PROC_IN_VACUUM)) + statusFlags = allStatusFlags[pgxactoff]; + if (statusFlags & (PROC_IN_LOGICAL_DECODING | PROC_IN_VACUUM)) continue; if (NormalTransactionIdPrecedes(xid, xmin)) @@ -3134,6 +3264,15 @@ GetSnapshotData(Snapshot snapshot, DtxContext distributedTransactionContext) GlobalVisDataRels.definitely_needed = FullTransactionIdNewer(def_vis_fxid_data, GlobalVisDataRels.definitely_needed); + /* See temp_oldest_nonremovable computation in ComputeXidHorizons() */ + if (TransactionIdIsNormal(myxid)) + GlobalVisTempRels.definitely_needed = + FullXidRelativeTo(latest_completed, myxid); + else + { + GlobalVisTempRels.definitely_needed = latest_completed; + FullTransactionIdAdvance(&GlobalVisTempRels.definitely_needed); + } /* * Check if we know that we can initialize or increase the lower @@ -3152,6 +3291,8 @@ GetSnapshotData(Snapshot snapshot, DtxContext distributedTransactionContext) GlobalVisDataRels.maybe_needed = FullTransactionIdNewer(GlobalVisDataRels.maybe_needed, oldestfxid); + /* accurate value known */ + GlobalVisTempRels.maybe_needed = GlobalVisTempRels.definitely_needed; } RecentXmin = xmin; @@ -3238,12 +3379,12 @@ ProcArrayInstallImportedXmin(TransactionId xmin, { int pgprocno = arrayP->pgprocnos[index]; PGPROC *proc = &allProcs[pgprocno]; - int vacuumFlags = ProcGlobal->vacuumFlags[index]; + int statusFlags = ProcGlobal->statusFlags[index]; TransactionId xid; #if 0 /* Ignore procs running LAZY VACUUM */ - if (vacuumFlags & PROC_IN_VACUUM) + if (statusFlags & PROC_IN_VACUUM) continue; #endif @@ -3942,7 +4083,7 @@ IsBackendPid(int pid) * If excludeXmin0 is true, skip processes with xmin = 0. * If allDbs is false, skip processes attached to other databases. * If excludeVacuum isn't zero, skip processes for which - * (vacuumFlags & excludeVacuum) is not zero. + * (statusFlags & excludeVacuum) is not zero. * * Note: the purpose of the limitXmin and excludeXmin0 parameters is to * allow skipping backends whose oldest live snapshot is no older than @@ -3976,12 +4117,12 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, { int pgprocno = arrayP->pgprocnos[index]; PGPROC *proc = &allProcs[pgprocno]; - uint8 vacuumFlags = ProcGlobal->vacuumFlags[index]; + uint8 statusFlags = ProcGlobal->statusFlags[index]; if (proc == MyProc) continue; - if (excludeVacuum & vacuumFlags) + if (excludeVacuum & statusFlags) continue; if (allDbs || proc->databaseId == MyDatabaseId) @@ -4120,6 +4261,13 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid) */ pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode) +{ + return SignalVirtualTransaction(vxid, sigmode, true); +} + +pid_t +SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, + bool conflictPending) { ProcArrayStruct *arrayP = procArray; int index; @@ -4138,7 +4286,7 @@ CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode) if (procvxid.backendId == vxid.backendId && procvxid.localTransactionId == vxid.localTransactionId) { - proc->recoveryConflictPending = true; + proc->recoveryConflictPending = conflictPending; pid = proc->pid; if (pid != 0) { @@ -4285,7 +4433,6 @@ CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending) { ProcArrayStruct *arrayP = procArray; int index; - pid_t pid = 0; /* tell all backends to die */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); @@ -4298,6 +4445,7 @@ CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending) if (databaseid == InvalidOid || proc->databaseId == databaseid) { VirtualTransactionId procvxid; + pid_t pid; GET_VXID_FROM_PGPROC(procvxid, *proc); @@ -4440,7 +4588,7 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared) { int pgprocno = arrayP->pgprocnos[index]; PGPROC *proc = &allProcs[pgprocno]; - uint8 vacuumFlags = ProcGlobal->vacuumFlags[index]; + uint8 statusFlags = ProcGlobal->statusFlags[index]; if (proc->databaseId != databaseId) continue; @@ -4454,7 +4602,7 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared) else { (*nbackends)++; - if ((vacuumFlags & PROC_IS_AUTOVACUUM) && + if ((statusFlags & PROC_IS_AUTOVACUUM) && nautovacs < MAXAUTOVACPIDS) autovac_pids[nautovacs++] = proc->pid; } @@ -4523,7 +4671,7 @@ TerminateOtherDBBackends(Oid databaseId) if (nprepared > 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("database \"%s\" is being used by prepared transaction", + errmsg("database \"%s\" is being used by prepared transactions", get_database_name(databaseId)), errdetail_plural("There is %d prepared transaction using the database.", "There are %d prepared transactions using the database.", @@ -4559,7 +4707,7 @@ TerminateOtherDBBackends(Oid databaseId) /* Users can signal backends they have role membership in. */ if (!has_privs_of_role(GetUserId(), proc->roleId) && - !has_privs_of_role(GetUserId(), DEFAULT_ROLE_SIGNAL_BACKENDID)) + !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be a member of the role whose process is being terminated or member of pg_signal_backend"))); @@ -4722,6 +4870,9 @@ XidCacheRemoveRunningXids(TransactionId xid, /* Also advance global latestCompletedXid while holding the lock */ MaintainLatestCompletedXid(latestXid); + /* ... and xactCompletionCount */ + ShmemVariableCache->xactCompletionCount++; + LWLockRelease(ProcArrayLock); } @@ -4823,6 +4974,8 @@ GlobalVisTestFor(Relation rel) state = &GlobalVisSharedRels; else if (need_catalog) state = &GlobalVisCatalogRels; + else if (RELATION_IS_LOCAL(rel)) + state = &GlobalVisTempRels; else state = &GlobalVisDataRels; @@ -4873,6 +5026,9 @@ GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons) GlobalVisDataRels.maybe_needed = FullXidRelativeTo(horizons->latest_completed, GetDistOldestXmin(horizons->data_oldest_nonremovable)); + GlobalVisTempRels.maybe_needed = + FullXidRelativeTo(horizons->latest_completed, + horizons->temp_oldest_nonremovable); /* * In longer running transactions it's possible that transactions we @@ -4888,6 +5044,7 @@ GlobalVisUpdateApply(ComputeXidHorizonsResult *horizons) GlobalVisDataRels.definitely_needed = FullTransactionIdNewer(GlobalVisDataRels.maybe_needed, GlobalVisDataRels.definitely_needed); + GlobalVisTempRels.definitely_needed = GlobalVisTempRels.maybe_needed; ComputeXidHorizonsResultLastXmin = RecentXmin; } @@ -5008,7 +5165,7 @@ GlobalVisTestNonRemovableHorizon(GlobalVisState *state) * GlobalVisTestIsRemovableFullXid(), see their comments. */ bool -GlobalVisIsRemovableFullXid(Relation rel, FullTransactionId fxid) +GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid) { GlobalVisState *state; @@ -5037,7 +5194,7 @@ GlobalVisCheckRemovableXid(Relation rel, TransactionId xid) * * Be very careful about when to use this function. It can only safely be used * when there is a guarantee that xid is within MaxTransactionId / 2 xids of - * rel. That e.g. can be guaranteed if the the caller assures a snapshot is + * rel. That e.g. can be guaranteed if the caller assures a snapshot is * held by the backend and xid is from a table (where vacuum/freezing ensures * the xid has to be within that range), or if xid is from the procarray and * prevents xid wraparound that way. @@ -5211,6 +5368,9 @@ ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, /* As in ProcArrayEndTransaction, advance latestCompletedXid */ MaintainLatestCompletedXidRecovery(max_xid); + /* ... and xactCompletionCount */ + ShmemVariableCache->xactCompletionCount++; + LWLockRelease(ProcArrayLock); } diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 541c8d1acbaf..743573e61c4d 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -4,7 +4,7 @@ * Routines for interprocess signaling * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -18,19 +18,21 @@ #include #include "access/parallel.h" +#include "port/pg_bitutils.h" #include "commands/async.h" #include "miscadmin.h" #include "pgstat.h" #include "replication/walsender.h" +#include "storage/condition_variable.h" #include "storage/ipc.h" #include "storage/latch.h" #include "storage/proc.h" #include "storage/shmem.h" #include "storage/sinval.h" -#include "tcop/tcopprot.h" -#include "utils/resgroup.h" - #include "cdb/cdbvars.h" +#include "tcop/tcopprot.h" +#include "utils/memutils.h" +#include "utils/resource_manager.h" /* * The SIGUSR1 signal is multiplexed to support signaling multiple event @@ -61,10 +63,11 @@ */ typedef struct { - pid_t pss_pid; - sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]; + volatile pid_t pss_pid; + volatile sig_atomic_t pss_signalFlags[NUM_PROCSIGNALS]; pg_atomic_uint64 pss_barrierGeneration; pg_atomic_uint32 pss_barrierCheckMask; + ConditionVariable pss_barrierCV; } ProcSignalSlot; /* @@ -90,12 +93,17 @@ typedef struct #define BARRIER_SHOULD_CHECK(flags, type) \ (((flags) & (((uint32) 1) << (uint32) (type))) != 0) +/* Clear the relevant type bit from the flags. */ +#define BARRIER_CLEAR_BIT(flags, type) \ + ((flags) &= ~(((uint32) 1) << (uint32) (type))) + static ProcSignalHeader *ProcSignal = NULL; -static volatile ProcSignalSlot *MyProcSignalSlot = NULL; +static ProcSignalSlot *MyProcSignalSlot = NULL; static bool CheckProcSignal(ProcSignalReason reason); static void CleanupProcSignalState(int status, Datum arg); -static void ProcessBarrierPlaceholder(void); +static void ResetProcSignalBarrierBits(uint32 flags); +static bool ProcessBarrierPlaceholder(void); /* * ProcSignalShmemSize @@ -139,6 +147,7 @@ ProcSignalShmemInit(void) MemSet(slot->pss_signalFlags, 0, sizeof(slot->pss_signalFlags)); pg_atomic_init_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX); pg_atomic_init_u32(&slot->pss_barrierCheckMask, 0); + ConditionVariableInit(&slot->pss_barrierCV); } } } @@ -153,7 +162,7 @@ ProcSignalShmemInit(void) void ProcSignalInit(int pss_idx) { - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; uint64 barrier_generation; Assert(pss_idx >= 1 && pss_idx <= NumProcSignalSlots); @@ -205,7 +214,7 @@ static void CleanupProcSignalState(int status, Datum arg) { int pss_idx = DatumGetInt32(arg); - volatile ProcSignalSlot *slot; + ProcSignalSlot *slot; slot = &ProcSignal->psh_slot[pss_idx - 1]; Assert(slot == MyProcSignalSlot); @@ -234,6 +243,7 @@ CleanupProcSignalState(int status, Datum arg) * no barrier waits block on it. */ pg_atomic_write_u64(&slot->pss_barrierGeneration, PG_UINT64_MAX); + ConditionVariableBroadcast(&slot->pss_barrierCV); slot->pss_pid = 0; } @@ -379,41 +389,31 @@ EmitProcSignalBarrier(ProcSignalBarrierType type) /* * WaitForProcSignalBarrier - wait until it is guaranteed that all changes * requested by a specific call to EmitProcSignalBarrier() have taken effect. - * - * We expect that the barrier will normally be absorbed very quickly by other - * backends, so we start by waiting just 1/8 of a second and then back off - * by a factor of two every time we time out, to a maximum wait time of - * 1 second. */ void WaitForProcSignalBarrier(uint64 generation) { - long timeout = 125L; - Assert(generation <= pg_atomic_read_u64(&ProcSignal->psh_barrierGeneration)); for (int i = NumProcSignalSlots - 1; i >= 0; i--) { - volatile ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; + ProcSignalSlot *slot = &ProcSignal->psh_slot[i]; uint64 oldval; + /* + * It's important that we check only pss_barrierGeneration here and + * not pss_barrierCheckMask. Bits in pss_barrierCheckMask get cleared + * before the barrier is actually absorbed, but pss_barrierGeneration + * is updated only afterward. + */ oldval = pg_atomic_read_u64(&slot->pss_barrierGeneration); while (oldval < generation) { - int events; - - CHECK_FOR_INTERRUPTS(); - - events = - WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, - timeout, WAIT_EVENT_PROC_SIGNAL_BARRIER); - ResetLatch(MyLatch); - + ConditionVariableSleep(&slot->pss_barrierCV, + WAIT_EVENT_PROC_SIGNAL_BARRIER); oldval = pg_atomic_read_u64(&slot->pss_barrierGeneration); - if (events & WL_TIMEOUT) - timeout = Min(timeout * 2, 1000L); } + ConditionVariableCancelSleep(); } /* @@ -433,7 +433,7 @@ WaitForProcSignalBarrier(uint64 generation) * cannot safely access the barrier generation inside the signal handler as * 64bit atomics might use spinlock based emulation, even for reads. As this * routine only gets called when PROCSIG_BARRIER is sent that won't cause a - * lot fo unnecessary work. + * lot of unnecessary work. */ static void HandleProcSignalBarrierInterrupt(void) @@ -456,7 +456,7 @@ ProcessProcSignalBarrier(void) { uint64 local_gen; uint64 shared_gen; - uint32 flags; + volatile uint32 flags; Assert(MyProcSignalSlot); @@ -485,21 +485,92 @@ ProcessProcSignalBarrier(void) * read of the barrier generation above happens before we atomically * extract the flags, and that any subsequent state changes happen * afterward. + * + * NB: In order to avoid race conditions, we must zero + * pss_barrierCheckMask first and only afterwards try to do barrier + * processing. If we did it in the other order, someone could send us + * another barrier of some type right after we called the + * barrier-processing function but before we cleared the bit. We would + * have no way of knowing that the bit needs to stay set in that case, so + * the need to call the barrier-processing function again would just get + * forgotten. So instead, we tentatively clear all the bits and then put + * back any for which we don't manage to successfully absorb the barrier. */ flags = pg_atomic_exchange_u32(&MyProcSignalSlot->pss_barrierCheckMask, 0); /* - * Process each type of barrier. It's important that nothing we call from - * here throws an error, because pss_barrierCheckMask has already been - * cleared. If we jumped out of here before processing all barrier types, - * then we'd forget about the need to do so later. - * - * NB: It ought to be OK to call the barrier-processing functions - * unconditionally, but it's more efficient to call only the ones that - * might need us to do something based on the flags. + * If there are no flags set, then we can skip doing any real work. + * Otherwise, establish a PG_TRY block, so that we don't lose track of + * which types of barrier processing are needed if an ERROR occurs. */ - if (BARRIER_SHOULD_CHECK(flags, PROCSIGNAL_BARRIER_PLACEHOLDER)) - ProcessBarrierPlaceholder(); + if (flags != 0) + { + bool success = true; + + PG_TRY(); + { + /* + * Process each type of barrier. The barrier-processing functions + * should normally return true, but may return false if the + * barrier can't be absorbed at the current time. This should be + * rare, because it's pretty expensive. Every single + * CHECK_FOR_INTERRUPTS() will return here until we manage to + * absorb the barrier, and that cost will add up in a hurry. + * + * NB: It ought to be OK to call the barrier-processing functions + * unconditionally, but it's more efficient to call only the ones + * that might need us to do something based on the flags. + */ + while (flags != 0) + { + ProcSignalBarrierType type; + bool processed = true; + + type = (ProcSignalBarrierType) pg_rightmost_one_pos32(flags); + switch (type) + { + case PROCSIGNAL_BARRIER_PLACEHOLDER: + processed = ProcessBarrierPlaceholder(); + break; + } + + /* + * To avoid an infinite loop, we must always unset the bit in + * flags. + */ + BARRIER_CLEAR_BIT(flags, type); + + /* + * If we failed to process the barrier, reset the shared bit + * so we try again later, and set a flag so that we don't bump + * our generation. + */ + if (!processed) + { + ResetProcSignalBarrierBits(((uint32) 1) << type); + success = false; + } + } + } + PG_CATCH(); + { + /* + * If an ERROR occurred, we'll need to try again later to handle + * that barrier type and any others that haven't been handled yet + * or weren't successfully absorbed. + */ + ResetProcSignalBarrierBits(flags); + PG_RE_THROW(); + } + PG_END_TRY(); + + /* + * If some barrier types were not successfully absorbed, we will have + * to try again later. + */ + if (!success) + return; + } /* * State changes related to all types of barriers that might have been @@ -509,9 +580,23 @@ ProcessProcSignalBarrier(void) * next called. */ pg_atomic_write_u64(&MyProcSignalSlot->pss_barrierGeneration, shared_gen); + ConditionVariableBroadcast(&MyProcSignalSlot->pss_barrierCV); } +/* + * If it turns out that we couldn't absorb one or more barrier types, either + * because the barrier-processing functions returned false or due to an error, + * arrange for processing to be retried later. + */ static void +ResetProcSignalBarrierBits(uint32 flags) +{ + pg_atomic_fetch_or_u32(&MyProcSignalSlot->pss_barrierCheckMask, flags); + ProcSignalBarrierPending = true; + InterruptPending = true; +} + +static bool ProcessBarrierPlaceholder(void) { /* @@ -521,7 +606,12 @@ ProcessBarrierPlaceholder(void) * appropriately descriptive. Get rid of this function and instead have * ProcessBarrierSomethingElse. Most likely, that function should live in * the file pertaining to that subsystem, rather than here. + * + * The return value should be 'true' if the barrier was successfully + * absorbed and 'false' if not. Note that returning 'false' can lead to + * very frequent retries, so try hard to make that an uncommon case. */ + return true; } /* @@ -586,6 +676,9 @@ procsignal_sigusr1_handler(SIGNAL_ARGS) if (CheckProcSignal(PROCSIG_BARRIER)) HandleProcSignalBarrierInterrupt(); + if (CheckProcSignal(PROCSIG_LOG_MEMORY_CONTEXT)) + HandleLogMemoryContextInterrupt(); + if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_DATABASE)) RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_DATABASE); @@ -612,7 +705,5 @@ procsignal_sigusr1_handler(SIGNAL_ARGS) SetLatch(MyLatch); - latch_sigusr1_handler(); - errno = save_errno; } diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c index 07efec07f25e..069cb2013997 100644 --- a/src/backend/storage/ipc/shm_mq.c +++ b/src/backend/storage/ipc/shm_mq.c @@ -8,7 +8,7 @@ * and only the receiver may receive. This is intended to allow a user * backend to communicate with worker backends that it has registered. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/storage/ipc/shm_mq.c @@ -24,6 +24,7 @@ #include "storage/procsignal.h" #include "storage/shm_mq.h" #include "storage/spin.h" +#include "utils/memutils.h" /* * This structure represents the actual queue, stored in shared memory. @@ -360,6 +361,13 @@ shm_mq_sendv(shm_mq_handle *mqh, shm_mq_iovec *iov, int iovcnt, bool nowait) for (i = 0; i < iovcnt; ++i) nbytes += iov[i].len; + /* Prevent writing messages overwhelming the receiver. */ + if (nbytes > MaxAllocSize) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("cannot send a message of size %zu via shared memory queue", + nbytes))); + /* Try to write, or finish writing, the length word into the buffer. */ while (!mqh->mqh_length_word_complete) { @@ -675,6 +683,17 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait) } nbytes = mqh->mqh_expected_bytes; + /* + * Should be disallowed on the sending side already, but better check and + * error out on the receiver side as well rather than trying to read a + * prohibitively large message. + */ + if (nbytes > MaxAllocSize) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("invalid message size %zu in shared memory queue", + nbytes))); + if (mqh->mqh_partial_bytes == 0) { /* @@ -703,8 +722,13 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait) { Size newbuflen = Max(mqh->mqh_buflen, MQH_INITIAL_BUFSIZE); + /* + * Double the buffer size until the payload fits, but limit to + * MaxAllocSize. + */ while (newbuflen < nbytes) newbuflen *= 2; + newbuflen = Min(newbuflen, MaxAllocSize); if (mqh->mqh_buffer != NULL) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index f2272cc4f43f..4b02c39e310a 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -3,7 +3,7 @@ * shm_toc.c * shared memory segment table of contents * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/storage/ipc/shm_toc.c @@ -266,8 +266,8 @@ shm_toc_estimate(shm_toc_estimator *e) Size sz; sz = offsetof(shm_toc, toc_entry); - sz += add_size(sz, mul_size(e->number_of_keys, sizeof(shm_toc_entry))); - sz += add_size(sz, e->space_for_chunks); + sz = add_size(sz, mul_size(e->number_of_keys, sizeof(shm_toc_entry))); + sz = add_size(sz, e->space_for_chunks); return BUFFERALIGN(sz); } diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index e7437084509d..b68570a454b5 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -3,7 +3,7 @@ * shmem.c * create shared memory and initialize shared memory data structures. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -327,7 +327,6 @@ void InitShmemIndex(void) { HASHCTL info; - int hash_flags; /* * Create the shared memory shmem index. @@ -339,11 +338,11 @@ InitShmemIndex(void) */ info.keysize = SHMEM_INDEX_KEYSIZE; info.entrysize = sizeof(ShmemIndexEnt); - hash_flags = HASH_ELEM; ShmemIndex = ShmemInitHash("ShmemIndex", SHMEM_INDEX_SIZE, SHMEM_INDEX_SIZE, - &info, hash_flags); + &info, + HASH_ELEM | HASH_STRINGS); } /* @@ -364,6 +363,11 @@ InitShmemIndex(void) * whose maximum size is certain, this should be equal to max_size; that * ensures that no run-time out-of-shared-memory failures can occur. * + * *infoP and hash_flags must specify at least the entry sizes and key + * comparison semantics (see hash_create()). Flag bits and values specific + * to shared-memory hash tables are added here, except that callers may + * choose to specify HASH_PARTITION and/or HASH_FIXED_SIZE. + * * Note: before Postgres 9.0, this function returned NULL for some failure * cases. Now, it always throws error instead, so callers need not check * for NULL. diff --git a/src/backend/storage/ipc/shmqueue.c b/src/backend/storage/ipc/shmqueue.c index d52b28f0fa76..dc3238cecfab 100644 --- a/src/backend/storage/ipc/shmqueue.c +++ b/src/backend/storage/ipc/shmqueue.c @@ -3,7 +3,7 @@ * shmqueue.c * shared memory linked lists * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c index f92a85e68ed0..8bc3c639908d 100644 --- a/src/backend/storage/ipc/signalfuncs.c +++ b/src/backend/storage/ipc/signalfuncs.c @@ -3,7 +3,7 @@ * signalfuncs.c * Functions for signaling backends * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,6 +18,7 @@ #include "catalog/pg_authid.h" #include "miscadmin.h" +#include "pgstat.h" #include "postmaster/syslogger.h" #include "storage/pmsignal.h" #include "storage/proc.h" @@ -77,7 +78,7 @@ pg_signal_backend(int pid, int sig, char *msg) /* Users can signal backends they have role membership in. */ if (!has_privs_of_role(GetUserId(), proc->roleId) && - !has_privs_of_role(GetUserId(), DEFAULT_ROLE_SIGNAL_BACKENDID)) + !has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND)) return SIGNAL_BACKEND_NOPERMISSION; /* If the user supplied a message to the signalled backend */ @@ -162,15 +163,91 @@ pg_cancel_backend_msg(PG_FUNCTION_ARGS) } /* - * Signal to terminate a backend process. This is allowed if you are a member - * of the role whose process is being terminated. + * Wait until there is no backend process with the given PID and return true. + * On timeout, a warning is emitted and false is returned. + */ +static bool +pg_wait_until_termination(int pid, int64 timeout) +{ + /* + * Wait in steps of waittime milliseconds until this function exits or + * timeout. + */ + int64 waittime = 100; + + /* + * Initially remaining time is the entire timeout specified by the user. + */ + int64 remainingtime = timeout; + + /* + * Check existence of the backend. If the backend still exists, then wait + * for waittime milliseconds, again check for the existence. Repeat this + * until timeout or an error occurs or a pending interrupt such as query + * cancel gets processed. + */ + do + { + if (remainingtime < waittime) + waittime = remainingtime; + + if (kill(pid, 0) == -1) + { + if (errno == ESRCH) + return true; + else + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("could not check the existence of the backend with PID %d: %m", + pid))); + } + + /* Process interrupts, if any, before waiting */ + CHECK_FOR_INTERRUPTS(); + + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + waittime, + WAIT_EVENT_BACKEND_TERMINATION); + + ResetLatch(MyLatch); + + remainingtime -= waittime; + } while (remainingtime > 0); + + ereport(WARNING, + (errmsg("backend with PID %d did not terminate within %lld milliseconds", + pid, (long long int) timeout))); + + return false; +} + +/* + * Send a signal to terminate a backend process. This is allowed if you are a + * member of the role whose process is being terminated. If the timeout input + * argument is 0, then this function just signals the backend and returns + * true. If timeout is nonzero, then it waits until no process has the given + * PID; if the process ends within the timeout, true is returned, and if the + * timeout is exceeded, a warning is emitted and false is returned. * * Note that only superusers can signal superuser-owned processes. */ Datum pg_terminate_backend(PG_FUNCTION_ARGS) { - int r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM, NULL); + int pid; + int r; + int timeout; /* milliseconds */ + + pid = PG_GETARG_INT32(0); + timeout = PG_GETARG_INT64(1); + + if (timeout < 0) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"timeout\" must not be negative"))); + + r = pg_signal_backend(pid, SIGTERM, NULL); if (r == SIGNAL_BACKEND_NOSUPERUSER) ereport(ERROR, @@ -182,7 +259,11 @@ pg_terminate_backend(PG_FUNCTION_ARGS) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be a member of the role whose process is being terminated or member of pg_signal_backend"))); - PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); + /* Wait only on success and if actually requested */ + if (r == SIGNAL_BACKEND_SUCCESS && timeout > 0) + PG_RETURN_BOOL(pg_wait_until_termination(pid, timeout)); + else + PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); } Datum diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c index 35ff659bb0c2..1c78affce984 100644 --- a/src/backend/storage/ipc/sinval.c +++ b/src/backend/storage/ipc/sinval.c @@ -3,7 +3,7 @@ * sinval.c * POSTGRES shared cache invalidation communication code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c index a9477ccb4a30..946bd8e3cb5c 100644 --- a/src/backend/storage/ipc/sinvaladt.c +++ b/src/backend/storage/ipc/sinvaladt.c @@ -3,7 +3,7 @@ * sinvaladt.c * POSTGRES shared cache invalidation data manager. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index 212cd30d84c5..51c507484724 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -7,7 +7,7 @@ * AccessExclusiveLocks and starting snapshots for Hot Standby mode. * Plus conflict recovery processing. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -39,9 +39,14 @@ int vacuum_defer_cleanup_age; int max_standby_archive_delay = 30 * 1000; int max_standby_streaming_delay = 30 * 1000; +bool log_recovery_conflict_waits = false; static HTAB *RecoveryLockLists; +/* Flags set by timeout handlers */ +static volatile sig_atomic_t got_standby_deadlock_timeout = false; +static volatile sig_atomic_t got_standby_lock_timeout = false; + static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, @@ -49,6 +54,7 @@ static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlis static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason); static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts); static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks); +static const char *get_recovery_conflict_desc(ProcSignalReason reason); /* * Keep track of all the locks owned by a given transaction. @@ -81,7 +87,6 @@ InitRecoveryTransactionEnvironment(void) * Initialize the hash table for tracking the list of locks held by each * transaction. */ - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(TransactionId); hash_ctl.entrysize = sizeof(RecoveryLockListsEntry); RecoveryLockLists = hash_create("RecoveryLockLists", @@ -122,10 +127,25 @@ InitRecoveryTransactionEnvironment(void) * * Prepare to switch from hot standby mode to normal operation. Shut down * recovery-time transaction tracking. + * + * This must be called even in shutdown of startup process if transaction + * tracking has been initialized. Otherwise some locks the tracked + * transactions were holding will not be released and and may interfere with + * the processes still running (but will exit soon later) at the exit of + * startup process. */ void ShutdownRecoveryTransactionEnvironment(void) { + /* + * Do nothing if RecoveryLockLists is NULL because which means that + * transaction tracking has not been yet initialized or has been already + * shutdowned. This prevents transaction tracking from being shutdowned + * unexpectedly more than once. + */ + if (RecoveryLockLists == NULL) + return; + /* Mark all tracked in-progress transactions as finished. */ ExpireAllKnownAssignedTransactionIds(); @@ -215,15 +235,101 @@ WaitExceedsMaxStandbyDelay(uint32 wait_event_info) return false; } +/* + * Log the recovery conflict. + * + * wait_start is the timestamp when the caller started to wait. + * now is the timestamp when this function has been called. + * wait_list is the list of virtual transaction ids assigned to + * conflicting processes. still_waiting indicates whether + * the startup process is still waiting for the recovery conflict + * to be resolved or not. + */ +void +LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, + TimestampTz now, VirtualTransactionId *wait_list, + bool still_waiting) +{ + long secs; + int usecs; + long msecs; + StringInfoData buf; + int nprocs = 0; + + /* + * There must be no conflicting processes when the recovery conflict has + * already been resolved. + */ + Assert(still_waiting || wait_list == NULL); + + TimestampDifference(wait_start, now, &secs, &usecs); + msecs = secs * 1000 + usecs / 1000; + usecs = usecs % 1000; + + if (wait_list) + { + VirtualTransactionId *vxids; + + /* Construct a string of list of the conflicting processes */ + vxids = wait_list; + while (VirtualTransactionIdIsValid(*vxids)) + { + PGPROC *proc = BackendIdGetProc(vxids->backendId); + + /* proc can be NULL if the target backend is not active */ + if (proc) + { + if (nprocs == 0) + { + initStringInfo(&buf); + appendStringInfo(&buf, "%d", proc->pid); + } + else + appendStringInfo(&buf, ", %d", proc->pid); + + nprocs++; + } + + vxids++; + } + } + + /* + * If wait_list is specified, report the list of PIDs of active + * conflicting backends in a detail message. Note that if all the backends + * in the list are not active, no detail message is logged. + */ + if (still_waiting) + { + ereport(LOG, + errmsg("recovery still waiting after %ld.%03d ms: %s", + msecs, usecs, get_recovery_conflict_desc(reason)), + nprocs > 0 ? errdetail_log_plural("Conflicting process: %s.", + "Conflicting processes: %s.", + nprocs, buf.data) : 0); + } + else + { + ereport(LOG, + errmsg("recovery finished waiting after %ld.%03d ms: %s", + msecs, usecs, get_recovery_conflict_desc(reason))); + } + + if (nprocs > 0) + pfree(buf.data); +} + /* * This is the main executioner for any query backend that conflicts with * recovery processing. Judgement has already been passed on it within * a specific rmgr. Here we just issue the orders to the procs. The procs * then throw the required error as instructed. * - * If report_waiting is true, "waiting" is reported in PS display if necessary. - * If the caller has already reported that, report_waiting should be false. - * Otherwise, "waiting" is reported twice unexpectedly. + * If report_waiting is true, "waiting" is reported in PS display and the + * wait for recovery conflict is reported in the log, if necessary. If + * the caller is responsible for reporting them, report_waiting should be + * false. Otherwise, both the caller and this function report the same + * thing unexpectedly. */ static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, @@ -231,15 +337,16 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, bool report_waiting) { TimestampTz waitStart = 0; - char *new_status; + char *new_status = NULL; + bool logged_recovery_conflict = false; /* Fast exit, to avoid a kernel call if there's no work to be done. */ if (!VirtualTransactionIdIsValid(*waitlist)) return; - if (report_waiting) + /* Set the wait start timestamp for reporting */ + if (report_waiting && (log_recovery_conflict_waits || update_process_title)) waitStart = GetCurrentTimestamp(); - new_status = NULL; /* we haven't changed the ps display */ while (VirtualTransactionIdIsValid(*waitlist)) { @@ -286,6 +393,49 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, if (pid != 0) pg_usleep(5000L); } + + if (waitStart != 0 && (!logged_recovery_conflict || new_status == NULL)) + { + TimestampTz now = 0; + bool maybe_log_conflict; + bool maybe_update_title; + + maybe_log_conflict = (log_recovery_conflict_waits && !logged_recovery_conflict); + maybe_update_title = (update_process_title && new_status == NULL); + + /* Get the current timestamp if not report yet */ + if (maybe_log_conflict || maybe_update_title) + now = GetCurrentTimestamp(); + + /* + * Report via ps if we have been waiting for more than 500 + * msec (should that be configurable?) + */ + if (maybe_update_title && + TimestampDifferenceExceeds(waitStart, now, 500)) + { + const char *old_status; + int len; + + old_status = get_ps_display(&len); + new_status = (char *) palloc(len + 8 + 1); + memcpy(new_status, old_status, len); + strcpy(new_status + len, " waiting"); + set_ps_display(new_status); + new_status[len] = '\0'; /* truncate off " waiting" */ + } + + /* + * Emit the log message if the startup process is waiting + * longer than deadlock_timeout for recovery conflict. + */ + if (maybe_log_conflict && + TimestampDifferenceExceeds(waitStart, now, DeadlockTimeout)) + { + LogRecoveryConflict(reason, waitStart, now, waitlist, true); + logged_recovery_conflict = true; + } + } } /* Reset ps display if we changed it */ @@ -299,6 +449,14 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, waitlist++; } + /* + * Emit the log message if recovery conflict was resolved but the startup + * process waited longer than deadlock_timeout for it. + */ + if (logged_recovery_conflict) + LogRecoveryConflict(reason, waitStart, GetCurrentTimestamp(), + NULL, false); + /* Reset ps display if we changed it */ if (new_status) { @@ -313,13 +471,15 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode VirtualTransactionId *backends; /* - * If we get passed InvalidTransactionId then we are a little surprised, - * but it is theoretically possible in normal running. It also happens - * when replaying already applied WAL records after a standby crash or - * restart, or when replaying an XLOG_HEAP2_VISIBLE record that marks as - * frozen a page which was already all-visible. If latestRemovedXid is - * invalid then there is no conflict. That rule applies across all record - * types that suffer from this conflict. + * If we get passed InvalidTransactionId then we do nothing (no conflict). + * + * This can happen when replaying already-applied WAL records after a + * standby crash or restart, or when replaying an XLOG_HEAP2_VISIBLE + * record that marks as frozen a page which was already all-visible. It's + * also quite common with records generated during index deletion + * (original execution of the deletion can reason that a recovery conflict + * which is sufficient for the deletion operation must take place before + * replay of the deletion record itself). */ if (!TransactionIdIsValid(latestRemovedXid)) return; @@ -333,6 +493,34 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode true); } +/* + * Variant of ResolveRecoveryConflictWithSnapshot that works with + * FullTransactionId values + */ +void +ResolveRecoveryConflictWithSnapshotFullXid(FullTransactionId latestRemovedFullXid, + RelFileNode node) +{ + /* + * ResolveRecoveryConflictWithSnapshot operates on 32-bit TransactionIds, + * so truncate the logged FullTransactionId. If the logged value is very + * old, so that XID wrap-around already happened on it, there can't be any + * snapshots that still see it. + */ + FullTransactionId nextXid = ReadNextFullTransactionId(); + uint64 diff; + + diff = U64FromFullTransactionId(nextXid) - + U64FromFullTransactionId(latestRemovedFullXid); + if (diff < MaxTransactionId / 2) + { + TransactionId latestRemovedXid; + + latestRemovedXid = XidFromFullTransactionId(latestRemovedFullXid); + ResolveRecoveryConflictWithSnapshot(latestRemovedXid, node); + } +} + void ResolveRecoveryConflictWithTablespace(Oid tsid) { @@ -403,19 +591,52 @@ ResolveRecoveryConflictWithDatabase(Oid dbid) * lock. As we are already queued to be granted the lock, no new lock * requests conflicting with ours will be granted in the meantime. * - * Deadlocks involving the Startup process and an ordinary backend process - * will be detected by the deadlock detector within the ordinary backend. + * We also must check for deadlocks involving the Startup process and + * hot-standby backend processes. If deadlock_timeout is reached in + * this function, all the backends holding the conflicting locks are + * requested to check themselves for deadlocks. + * + * logging_conflict should be true if the recovery conflict has not been + * logged yet even though logging is enabled. After deadlock_timeout is + * reached and the request for deadlock check is sent, we wait again to + * be signaled by the release of the lock if logging_conflict is false. + * Otherwise we return without waiting again so that the caller can report + * the recovery conflict. In this case, then, this function is called again + * with logging_conflict=false (because the recovery conflict has already + * been logged) and we will wait again for the lock to be released. */ void -ResolveRecoveryConflictWithLock(LOCKTAG locktag) +ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict) { TimestampTz ltime; + TimestampTz now; Assert(InHotStandby); ltime = GetStandbyLimitTime(); + now = GetCurrentTimestamp(); - if (GetCurrentTimestamp() >= ltime) + /* + * Update waitStart if first time through after the startup process + * started waiting for the lock. It should not be updated every time + * ResolveRecoveryConflictWithLock() is called during the wait. + * + * Use the current time obtained for comparison with ltime as waitStart + * (i.e., the time when this process started waiting for the lock). Since + * getting the current time newly can cause overhead, we reuse the + * already-obtained time to avoid that overhead. + * + * Note that waitStart is updated without holding the lock table's + * partition lock, to avoid the overhead by additional lock acquisition. + * This can cause "waitstart" in pg_locks to become NULL for a very short + * period of time after the wait started even though "granted" is false. + * This is OK in practice because we can assume that users are likely to + * look at "waitstart" when waiting for the lock for a long time. + */ + if (pg_atomic_read_u64(&MyProc->waitStart) == 0) + pg_atomic_write_u64(&MyProc->waitStart, now); + + if (now >= ltime && ltime != 0) { /* * We're already behind, so clear a path as quickly as possible. @@ -437,19 +658,85 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag) else { /* - * Wait (or wait again) until ltime + * Wait (or wait again) until ltime, and check for deadlocks as well + * if we will be waiting longer than deadlock_timeout */ - EnableTimeoutParams timeouts[1]; + EnableTimeoutParams timeouts[2]; + int cnt = 0; - timeouts[0].id = STANDBY_LOCK_TIMEOUT; - timeouts[0].type = TMPARAM_AT; - timeouts[0].fin_time = ltime; - enable_timeouts(timeouts, 1); + if (ltime != 0) + { + got_standby_lock_timeout = false; + timeouts[cnt].id = STANDBY_LOCK_TIMEOUT; + timeouts[cnt].type = TMPARAM_AT; + timeouts[cnt].fin_time = ltime; + cnt++; + } + + got_standby_deadlock_timeout = false; + timeouts[cnt].id = STANDBY_DEADLOCK_TIMEOUT; + timeouts[cnt].type = TMPARAM_AFTER; + timeouts[cnt].delay_ms = DeadlockTimeout; + cnt++; + + enable_timeouts(timeouts, cnt); } /* Wait to be signaled by the release of the Relation Lock */ ProcWaitForSignal(PG_WAIT_LOCK | locktag.locktag_type); + /* + * Exit if ltime is reached. Then all the backends holding conflicting + * locks will be canceled in the next ResolveRecoveryConflictWithLock() + * call. + */ + if (got_standby_lock_timeout) + goto cleanup; + + if (got_standby_deadlock_timeout) + { + VirtualTransactionId *backends; + + backends = GetLockConflicts(&locktag, AccessExclusiveLock, NULL); + + /* Quick exit if there's no work to be done */ + if (!VirtualTransactionIdIsValid(*backends)) + goto cleanup; + + /* + * Send signals to all the backends holding the conflicting locks, to + * ask them to check themselves for deadlocks. + */ + while (VirtualTransactionIdIsValid(*backends)) + { + SignalVirtualTransaction(*backends, + PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, + false); + backends++; + } + + /* + * Exit if the recovery conflict has not been logged yet even though + * logging is enabled, so that the caller can log that. Then + * RecoveryConflictWithLock() is called again and we will wait again + * for the lock to be released. + */ + if (logging_conflict) + goto cleanup; + + /* + * Wait again here to be signaled by the release of the Relation Lock, + * to prevent the subsequent RecoveryConflictWithLock() from causing + * deadlock_timeout and sending a request for deadlocks check again. + * Otherwise the request continues to be sent every deadlock_timeout + * until the relation locks are released or ltime is reached. + */ + got_standby_deadlock_timeout = false; + ProcWaitForSignal(PG_WAIT_LOCK | locktag.locktag_type); + } + +cleanup: + /* * Clear any timeout requests established above. We assume here that the * Startup process doesn't have any other outstanding timeouts than those @@ -457,6 +744,8 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag) * timeouts individually, but that'd be slower. */ disable_all_timeouts(false); + got_standby_lock_timeout = false; + got_standby_deadlock_timeout = false; } /* @@ -495,15 +784,7 @@ ResolveRecoveryConflictWithBufferPin(void) ltime = GetStandbyLimitTime(); - if (ltime == 0) - { - /* - * We're willing to wait forever for conflicts, so set timeout for - * deadlock check only - */ - enable_timeout_after(STANDBY_DEADLOCK_TIMEOUT, DeadlockTimeout); - } - else if (GetCurrentTimestamp() >= ltime) + if (GetCurrentTimestamp() >= ltime && ltime != 0) { /* * We're already behind, so clear a path as quickly as possible. @@ -517,19 +798,54 @@ ResolveRecoveryConflictWithBufferPin(void) * waiting longer than deadlock_timeout */ EnableTimeoutParams timeouts[2]; + int cnt = 0; - timeouts[0].id = STANDBY_TIMEOUT; - timeouts[0].type = TMPARAM_AT; - timeouts[0].fin_time = ltime; - timeouts[1].id = STANDBY_DEADLOCK_TIMEOUT; - timeouts[1].type = TMPARAM_AFTER; - timeouts[1].delay_ms = DeadlockTimeout; - enable_timeouts(timeouts, 2); + if (ltime != 0) + { + timeouts[cnt].id = STANDBY_TIMEOUT; + timeouts[cnt].type = TMPARAM_AT; + timeouts[cnt].fin_time = ltime; + cnt++; + } + + got_standby_deadlock_timeout = false; + timeouts[cnt].id = STANDBY_DEADLOCK_TIMEOUT; + timeouts[cnt].type = TMPARAM_AFTER; + timeouts[cnt].delay_ms = DeadlockTimeout; + cnt++; + + enable_timeouts(timeouts, cnt); } - /* Wait to be signaled by UnpinBuffer() */ + /* + * Wait to be signaled by UnpinBuffer(). + * + * We assume that only UnpinBuffer() and the timeout requests established + * above can wake us up here. WakeupRecovery() called by walreceiver or + * SIGHUP signal handler, etc cannot do that because it uses the different + * latch from that ProcWaitForSignal() waits on. + */ ProcWaitForSignal(PG_WAIT_BUFFER_PIN); + if (got_standby_deadlock_timeout) + { + /* + * Send out a request for hot-standby backends to check themselves for + * deadlocks. + * + * XXX The subsequent ResolveRecoveryConflictWithBufferPin() will wait + * to be signaled by UnpinBuffer() again and send a request for + * deadlocks check if deadlock_timeout happens. This causes the + * request to continue to be sent every deadlock_timeout until the + * buffer is unpinned or ltime is reached. This would increase the + * workload in the startup process and backends. In practice it may + * not be so harmful because the period that the buffer is kept pinned + * is basically no so long. But we should fix this? + */ + SendRecoveryConflictWithBufferPin( + PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK); + } + /* * Clear any timeout requests established above. We assume here that the * Startup process doesn't have any other timeouts than what this function @@ -537,6 +853,7 @@ ResolveRecoveryConflictWithBufferPin(void) * individually, but that'd be slower. */ disable_all_timeouts(false); + got_standby_deadlock_timeout = false; } static void @@ -596,13 +913,12 @@ CheckRecoveryConflictDeadlock(void) /* * StandbyDeadLockHandler() will be called if STANDBY_DEADLOCK_TIMEOUT - * occurs before STANDBY_TIMEOUT. Send out a request for hot-standby - * backends to check themselves for deadlocks. + * occurs before STANDBY_TIMEOUT. */ void StandbyDeadLockHandler(void) { - SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK); + got_standby_deadlock_timeout = true; } /* @@ -621,11 +937,11 @@ StandbyTimeoutHandler(void) /* * StandbyLockTimeoutHandler() will be called if STANDBY_LOCK_TIMEOUT is exceeded. - * This doesn't need to do anything, simply waking up is enough. */ void StandbyLockTimeoutHandler(void) { + got_standby_lock_timeout = true; } /* @@ -1015,7 +1331,7 @@ LogCurrentRunningXacts(RunningTransactions CurrRunningXacts) elog(trace_recovery(DEBUG2), "snapshot of %u running transactions overflowed (lsn %X/%X oldest xid %u latest complete %u next xid %u)", CurrRunningXacts->xcnt, - (uint32) (recptr >> 32), (uint32) recptr, + LSN_FORMAT_ARGS(recptr), CurrRunningXacts->oldestRunningXid, CurrRunningXacts->latestCompletedXid, CurrRunningXacts->nextXid); @@ -1023,7 +1339,7 @@ LogCurrentRunningXacts(RunningTransactions CurrRunningXacts) elog(trace_recovery(DEBUG2), "snapshot of %u+%u running transaction ids (lsn %X/%X oldest xid %u latest complete %u next xid %u)", CurrRunningXacts->xcnt, CurrRunningXacts->subxcnt, - (uint32) (recptr >> 32), (uint32) recptr, + LSN_FORMAT_ARGS(recptr), CurrRunningXacts->oldestRunningXid, CurrRunningXacts->latestCompletedXid, CurrRunningXacts->nextXid); @@ -1123,3 +1439,36 @@ LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, nmsgs * sizeof(SharedInvalidationMessage)); XLogInsert(RM_STANDBY_ID, XLOG_INVALIDATIONS); } + +/* Return the description of recovery conflict */ +static const char * +get_recovery_conflict_desc(ProcSignalReason reason) +{ + const char *reasonDesc = _("unknown reason"); + + switch (reason) + { + case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN: + reasonDesc = _("recovery conflict on buffer pin"); + break; + case PROCSIG_RECOVERY_CONFLICT_LOCK: + reasonDesc = _("recovery conflict on lock"); + break; + case PROCSIG_RECOVERY_CONFLICT_TABLESPACE: + reasonDesc = _("recovery conflict on tablespace"); + break; + case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT: + reasonDesc = _("recovery conflict on snapshot"); + break; + case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK: + reasonDesc = _("recovery conflict on buffer deadlock"); + break; + case PROCSIG_RECOVERY_CONFLICT_DATABASE: + reasonDesc = _("recovery conflict on database"); + break; + default: + break; + } + + return reasonDesc; +} diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index 20130e47b76c..bee234bffc96 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -19,7 +19,7 @@ * memory context given to inv_open (for LargeObjectDesc structs). * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/lmgr/README.barrier b/src/backend/storage/lmgr/README.barrier index 4e37a4acbe7a..f78e5ac8f6f4 100644 --- a/src/backend/storage/lmgr/README.barrier +++ b/src/backend/storage/lmgr/README.barrier @@ -38,7 +38,7 @@ Surprisingly, however, the second backend could also end up with foo = 0 and bar = 1. The compiler might swap the order of the two stores performed by the first backend, or the two loads performed by the second backend. Even if it doesn't, on a machine with weak memory ordering (such as PowerPC -or Itanium) the CPU might choose to execute either the loads or the stores +or ARM) the CPU might choose to execute either the loads or the stores out of order. This surprising result can lead to bugs. A common pattern where this actually does result in a bug is when adding items @@ -103,7 +103,7 @@ performed before the barrier, and vice-versa. Although this code will work, it is needlessly inefficient. On systems with strong memory ordering (such as x86), the CPU never reorders loads with other -loads, nor stores with other stores. It can, however, allow a load to +loads, nor stores with other stores. It can, however, allow a load to be performed before a subsequent store. To avoid emitting unnecessary memory instructions, we provide two additional primitives: pg_read_barrier(), and pg_write_barrier(). When a memory barrier is being used to separate two @@ -155,18 +155,16 @@ Although this may compile down to a single machine-language instruction, the CPU will execute that instruction by reading the current value of foo, adding one to it, and then storing the result back to the original address. If two CPUs try to do this simultaneously, both may do their reads before -either one does their writes. Eventually we might be able to use an atomic -fetch-and-add instruction for this specific case on architectures that support -it, but we can't rely on that being available everywhere, and we currently -have no support for it at all. Use a lock. +either one does their writes. Such a case could be made safe by using an +atomic variable and an atomic add. See port/atomics.h. 2. Eight-byte loads and stores aren't necessarily atomic. We assume in various places in the source code that an aligned four-byte load or store is atomic, and that other processes therefore won't see a half-set value. Sadly, the same can't be said for eight-byte value: on some platforms, an aligned eight-byte load or store will generate two four-byte operations. If -you need an atomic eight-byte read or write, you must make it atomic with a -lock. +you need an atomic eight-byte read or write, you must either serialize access +with a lock or use an atomic variable. 3. No ordering guarantees. While memory barriers ensure that any given process performs loads and stores to shared memory in order, they don't diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c index 2ec00397b491..80d70c154cf7 100644 --- a/src/backend/storage/lmgr/condition_variable.c +++ b/src/backend/storage/lmgr/condition_variable.c @@ -8,7 +8,7 @@ * interrupted, unlike LWLock waits. Condition variables are safe * to use within dynamic shared memory segments. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/storage/lmgr/condition_variable.c @@ -165,8 +165,6 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, /* Reset latch before examining the state of the wait list. */ ResetLatch(MyLatch); - CHECK_FOR_INTERRUPTS(); - /* * If this process has been taken out of the wait list, then we know * that it has been signaled by ConditionVariableSignal (or @@ -190,6 +188,15 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, } SpinLockRelease(&cv->mutex); + /* + * Check for interrupts, and return spuriously if that caused the + * current sleep target to change (meaning that interrupt handler code + * waited for a different condition variable). + */ + CHECK_FOR_INTERRUPTS(); + if (cv != cv_sleep_target) + done = true; + /* We were signaled, so return */ if (done) return false; diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index a9c1d01d4166..e66a5565d39d 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -7,7 +7,7 @@ * detection and resolution algorithms. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -623,17 +623,17 @@ FindLockCycleRecurseMember(PGPROC *checkProc, * that an autovacuum won't be canceled with less than * deadlock_timeout grace period. * - * Note we read vacuumFlags without any locking. This is + * Note we read statusFlags without any locking. This is * OK only for checking the PROC_IS_AUTOVACUUM flag, * because that flag is set at process start and never * reset. There is logic elsewhere to avoid canceling an * autovacuum that is working to prevent XID wraparound - * problems (which needs to read a different vacuumFlag + * problems (which needs to read a different statusFlags * bit), but we don't do that here to avoid grabbing * ProcArrayLock. */ if (checkProc == MyProc && - proc->vacuumFlags & PROC_IS_AUTOVACUUM) + proc->statusFlags & PROC_IS_AUTOVACUUM) blocking_autovacuum_proc = proc; /* We're done looking at this proclock */ diff --git a/src/backend/storage/lmgr/generate-lwlocknames.pl b/src/backend/storage/lmgr/generate-lwlocknames.pl index ca54acdfb0f8..8a44946594d4 100644 --- a/src/backend/storage/lmgr/generate-lwlocknames.pl +++ b/src/backend/storage/lmgr/generate-lwlocknames.pl @@ -1,10 +1,10 @@ #!/usr/bin/perl # # Generate lwlocknames.h and lwlocknames.c from lwlocknames.txt -# Copyright (c) 2000-2020, PostgreSQL Global Development Group +# Copyright (c) 2000-2021, PostgreSQL Global Development Group -use warnings; use strict; +use warnings; my $lastlockidx = -1; my $continue = "\n"; diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c index 2b6db36e0f5d..61e938f11ecc 100644 --- a/src/backend/storage/lmgr/lmgr.c +++ b/src/backend/storage/lmgr/lmgr.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,6 +25,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "storage/lmgr.h" +#include "storage/proc.h" #include "storage/procarray.h" #include "storage/sinvaladt.h" #include "utils/inval.h" @@ -1005,8 +1006,7 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress) /* * Note: GetLockConflicts() never reports our own xid, hence we need not - * check for that. Also, prepared xacts are not reported, which is fine - * since they certainly aren't going to do anything anymore. + * check for that. Also, prepared xacts are reported and awaited. */ /* Finally wait for each such transaction to complete */ diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index c513f161c992..2c8f686919fd 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -3,7 +3,7 @@ * lock.c * POSTGRES primary lock mechanism * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -460,7 +460,6 @@ InitLocks(void) * Allocate hash table for LOCK structs. This stores per-locked-object * information. */ - MemSet(&info, 0, sizeof(info)); info.keysize = sizeof(LOCKTAG); info.entrysize = sizeof(LOCK); info.num_partitions = NUM_LOCK_PARTITIONS; @@ -3219,9 +3218,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock) * so use of this function has to be thought about carefully. * * Note we never include the current xact's vxid in the result array, - * since an xact never blocks itself. Also, prepared transactions are - * ignored, which is a bit more debatable but is appropriate for current - * uses of the result. + * since an xact never blocks itself. */ VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp) @@ -3246,19 +3243,21 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp) /* * Allocate memory to store results, and fill with InvalidVXID. We only - * need enough space for MaxBackends + a terminator, since prepared xacts - * don't count. InHotStandby allocate once in TopMemoryContext. + * need enough space for MaxBackends + max_prepared_xacts + a terminator. + * InHotStandby allocate once in TopMemoryContext. */ if (InHotStandby) { if (vxids == NULL) vxids = (VirtualTransactionId *) MemoryContextAlloc(TopMemoryContext, - sizeof(VirtualTransactionId) * (MaxBackends + 1)); + sizeof(VirtualTransactionId) * + (MaxBackends + max_prepared_xacts + 1)); } else vxids = (VirtualTransactionId *) - palloc0(sizeof(VirtualTransactionId) * (MaxBackends + 1)); + palloc0(sizeof(VirtualTransactionId) * + (MaxBackends + max_prepared_xacts + 1)); /* Compute hash code and partition lock, and look up conflicting modes. */ hashcode = LockTagHashCode(locktag); @@ -3333,13 +3332,9 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp) /* Conflict! */ GET_VXID_FROM_PGPROC(vxid, *proc); - /* - * If we see an invalid VXID, then either the xact has already - * committed (or aborted), or it's a prepared xact. In either - * case we may ignore it. - */ if (VirtualTransactionIdIsValid(vxid)) vxids[count++] = vxid; + /* else, xact already committed or aborted */ /* No need to examine remaining slots. */ break; @@ -3398,11 +3393,6 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp) GET_VXID_FROM_PGPROC(vxid, *proc); - /* - * If we see an invalid VXID, then either the xact has already - * committed (or aborted), or it's a prepared xact. In either - * case we may ignore it. - */ if (VirtualTransactionIdIsValid(vxid)) { int i; @@ -3414,6 +3404,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp) if (i >= fast_count) vxids[count++] = vxid; } + /* else, xact already committed or aborted */ } } @@ -3423,7 +3414,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp) LWLockRelease(partitionLock); - if (count > MaxBackends) /* should never happen */ + if (count > MaxBackends + max_prepared_xacts) /* should never happen */ elog(PANIC, "too many conflicting locks found"); vxids[count].backendId = InvalidBackendId; @@ -4085,6 +4076,13 @@ GetLockStatusData(void) instance->pid = proc->pid; instance->leaderPid = proc->pid; instance->fastpath = true; + + /* + * Successfully taking fast path lock means there were no + * conflicting locks. + */ + instance->waitStart = 0; + instance->databaseId = proc->databaseId; instance->mppSessionId = proc->mppSessionId; instance->mppIsWriter = proc->mppIsWriter; @@ -4117,6 +4115,8 @@ GetLockStatusData(void) instance->pid = proc->pid; instance->leaderPid = proc->pid; instance->fastpath = true; + instance->waitStart = 0; + instance->databaseId = proc->databaseId; instance->mppSessionId = proc->mppSessionId; instance->mppIsWriter = proc->mppIsWriter; @@ -4181,6 +4181,8 @@ GetLockStatusData(void) tmGxact->gxid : proc->localDistribXactData.distribXid; instance->holdTillEndXact = proclock->tag.myLock->holdTillEndXact; + instance->waitStart = (TimestampTz) pg_atomic_read_u64(&proc->waitStart); + el++; } @@ -4939,6 +4941,21 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait) Assert(VirtualTransactionIdIsValid(vxid)); + if (VirtualTransactionIdIsPreparedXact(vxid)) + { + LockAcquireResult lar; + + /* + * Prepared transactions don't hold vxid locks. The + * LocalTransactionId is always a normal, locked XID. + */ + SET_LOCKTAG_TRANSACTION(tag, vxid.localTransactionId); + lar = LockAcquire(&tag, ShareLock, false, !wait); + if (lar != LOCKACQUIRE_NOT_AVAIL) + LockRelease(&tag, ShareLock, false); + return lar != LOCKACQUIRE_NOT_AVAIL; + } + SET_LOCKTAG_VIRTUALTRANSACTION(tag, vxid); /* diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index 286a009dbe91..fbee56a04ed3 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -20,7 +20,7 @@ * appropriate value for a free lock. The meaning of the variable is up to * the caller, the lightweight lock code just assigns and compares it. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -146,8 +146,6 @@ static const char *const BuiltinTrancheNames[] = { "WALInsert", /* LWTRANCHE_BUFFER_CONTENT: */ "BufferContent", - /* LWTRANCHE_BUFFER_IO: */ - "BufferIO", /* LWTRANCHE_REPLICATION_ORIGIN_STATE: */ "ReplicationOriginState", /* LWTRANCHE_REPLICATION_SLOT_IO: */ @@ -344,7 +342,6 @@ init_lwlock_stats(void) ALLOCSET_DEFAULT_SIZES); MemoryContextAllowInCriticalSection(lwlock_stats_cxt, true); - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(lwlock_stats_key); ctl.entrysize = sizeof(lwlock_stats); ctl.hcxt = lwlock_stats_cxt; @@ -472,8 +469,7 @@ CreateLWLocks(void) StaticAssertStmt(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS, "MAX_BACKENDS too big for lwlock.c"); - StaticAssertStmt(sizeof(LWLock) <= LWLOCK_MINIMAL_SIZE && - sizeof(LWLock) <= LWLOCK_PADDED_SIZE, + StaticAssertStmt(sizeof(LWLock) <= LWLOCK_PADDED_SIZE, "Miscalculated LWLock padding"); if (!IsUnderPostmaster) @@ -527,18 +523,17 @@ InitializeLWLocks(void) LWLockInitialize(&lock->lock, id); /* Initialize buffer mapping LWLocks in main array */ - lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS; + lock = MainLWLockArray + BUFFER_MAPPING_LWLOCK_OFFSET; for (id = 0; id < NUM_BUFFER_PARTITIONS; id++, lock++) LWLockInitialize(&lock->lock, LWTRANCHE_BUFFER_MAPPING); /* Initialize lmgrs' LWLocks in main array */ - lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS + NUM_BUFFER_PARTITIONS; + lock = MainLWLockArray + LOCK_MANAGER_LWLOCK_OFFSET; for (id = 0; id < NUM_LOCK_PARTITIONS; id++, lock++) LWLockInitialize(&lock->lock, LWTRANCHE_LOCK_MANAGER); /* Initialize predicate lmgrs' LWLocks in main array */ - lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS + - NUM_BUFFER_PARTITIONS + NUM_LOCK_PARTITIONS; + lock = MainLWLockArray + PREDICATELOCK_MANAGER_LWLOCK_OFFSET; for (id = 0; id < NUM_PREDICATELOCK_PARTITIONS; id++, lock++) LWLockInitialize(&lock->lock, LWTRANCHE_PREDICATE_LOCK_MANAGER); @@ -1325,7 +1320,8 @@ LWLockAcquire(LWLock *lock, LWLockMode mode) #endif LWLockReportWaitStart(lock); - TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_WAIT_START_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode); for (;;) { @@ -1347,7 +1343,8 @@ LWLockAcquire(LWLock *lock, LWLockMode mode) } #endif - TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_WAIT_DONE_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode); LWLockReportWaitEnd(); LOG_LWDEBUG("LWLockAcquire", lock, "awakened"); @@ -1356,7 +1353,8 @@ LWLockAcquire(LWLock *lock, LWLockMode mode) result = false; } - TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_ACQUIRE_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), mode); /* Add lock to list of locks held by this backend */ held_lwlocks[num_held_lwlocks].lock = lock; @@ -1407,14 +1405,16 @@ LWLockConditionalAcquire(LWLock *lock, LWLockMode mode) RESUME_INTERRUPTS(); LOG_LWDEBUG("LWLockConditionalAcquire", lock, "failed"); - TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), mode); } else { /* Add lock to list of locks held by this backend */ held_lwlocks[num_held_lwlocks].lock = lock; held_lwlocks[num_held_lwlocks++].mode = mode; - TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), mode); } return !mustwait; } @@ -1486,7 +1486,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) #endif LWLockReportWaitStart(lock); - TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_WAIT_START_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode); for (;;) { @@ -1504,7 +1505,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) Assert(nwaiters < MAX_BACKENDS); } #endif - TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_WAIT_DONE_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode); LWLockReportWaitEnd(); LOG_LWDEBUG("LWLockAcquireOrWait", lock, "awakened"); @@ -1534,7 +1536,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) /* Failed to get lock, so release interrupt holdoff */ RESUME_INTERRUPTS(); LOG_LWDEBUG("LWLockAcquireOrWait", lock, "failed"); - TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), mode); } else { @@ -1542,7 +1545,8 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode) /* Add lock to list of locks held by this backend */ held_lwlocks[num_held_lwlocks].lock = lock; held_lwlocks[num_held_lwlocks++].mode = mode; - TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), mode); + if (TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), mode); } return !mustwait; @@ -1702,7 +1706,8 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval) #endif LWLockReportWaitStart(lock); - TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), LW_EXCLUSIVE); + if (TRACE_POSTGRESQL_LWLOCK_WAIT_START_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), LW_EXCLUSIVE); for (;;) { @@ -1721,7 +1726,8 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval) } #endif - TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), LW_EXCLUSIVE); + if (TRACE_POSTGRESQL_LWLOCK_WAIT_DONE_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), LW_EXCLUSIVE); LWLockReportWaitEnd(); LOG_LWDEBUG("LWLockWaitForVar", lock, "awakened"); @@ -1729,8 +1735,6 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval) /* Now loop back and check the status of the lock again. */ } - TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), LW_EXCLUSIVE); - /* * Fix the process wait semaphore's count for any absorbed wakeups. */ @@ -1849,6 +1853,8 @@ LWLockRelease(LWLock *lock) /* nobody else can have that kind of lock */ Assert(!(oldstate & LW_VAL_EXCLUSIVE)); + if (TRACE_POSTGRESQL_LWLOCK_RELEASE_ENABLED()) + TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock)); /* * We're still waiting for backends to get scheduled, don't wake them up @@ -1872,8 +1878,6 @@ LWLockRelease(LWLock *lock) LWLockWakeup(lock); } - TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock)); - /* * Now okay to allow cancel/die interrupts. */ diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt index 77fdf74695f7..bb2f3de69152 100644 --- a/src/backend/storage/lmgr/lwlocknames.txt +++ b/src/backend/storage/lmgr/lwlocknames.txt @@ -15,7 +15,7 @@ SInvalWriteLock 6 WALBufMappingLock 7 WALWriteLock 8 ControlFileLock 9 -CheckpointLock 10 +# 10 was CheckpointLock XactSLRULock 11 SubtransSLRULock 12 MultiXactGenLock 13 diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 706536d0cf69..f5668bdb4ff0 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -135,7 +135,7 @@ * - Protects both PredXact and SerializableXidHash. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -438,7 +438,7 @@ static void SetPossibleUnsafeConflict(SERIALIZABLEXACT *roXact, SERIALIZABLEXACT static void ReleaseRWConflict(RWConflict conflict); static void FlagSxactUnsafe(SERIALIZABLEXACT *sxact); -static bool SerialPagePrecedesLogically(int p, int q); +static bool SerialPagePrecedesLogically(int page1, int page2); static void SerialInit(void); static void SerialAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo); static SerCommitSeqNo SerialGetMinConflictCommitSeqNo(TransactionId xid); @@ -784,28 +784,80 @@ FlagSxactUnsafe(SERIALIZABLEXACT *sxact) /*------------------------------------------------------------------------*/ /* - * We will work on the page range of 0..SERIAL_MAX_PAGE. - * Compares using wraparound logic, as is required by slru.c. + * Decide whether a Serial page number is "older" for truncation purposes. + * Analogous to CLOGPagePrecedes(). */ static bool -SerialPagePrecedesLogically(int p, int q) +SerialPagePrecedesLogically(int page1, int page2) { - int diff; + TransactionId xid1; + TransactionId xid2; + + xid1 = ((TransactionId) page1) * SERIAL_ENTRIESPERPAGE; + xid1 += FirstNormalTransactionId + 1; + xid2 = ((TransactionId) page2) * SERIAL_ENTRIESPERPAGE; + xid2 += FirstNormalTransactionId + 1; + + return (TransactionIdPrecedes(xid1, xid2) && + TransactionIdPrecedes(xid1, xid2 + SERIAL_ENTRIESPERPAGE - 1)); +} + +#ifdef USE_ASSERT_CHECKING +static void +SerialPagePrecedesLogicallyUnitTests(void) +{ + int per_page = SERIAL_ENTRIESPERPAGE, + offset = per_page / 2; + int newestPage, + oldestPage, + headPage, + targetPage; + TransactionId newestXact, + oldestXact; + + /* GetNewTransactionId() has assigned the last XID it can safely use. */ + newestPage = 2 * SLRU_PAGES_PER_SEGMENT - 1; /* nothing special */ + newestXact = newestPage * per_page + offset; + Assert(newestXact / per_page == newestPage); + oldestXact = newestXact + 1; + oldestXact -= 1U << 31; + oldestPage = oldestXact / per_page; /* - * We have to compare modulo (SERIAL_MAX_PAGE+1)/2. Both inputs should be - * in the range 0..SERIAL_MAX_PAGE. + * In this scenario, the SLRU headPage pertains to the last ~1000 XIDs + * assigned. oldestXact finishes, ~2B XIDs having elapsed since it + * started. Further transactions cause us to summarize oldestXact to + * tailPage. Function must return false so SerialAdd() doesn't zero + * tailPage (which may contain entries for other old, recently-finished + * XIDs) and half the SLRU. Reaching this requires burning ~2B XIDs in + * single-user mode, a negligible possibility. */ - Assert(p >= 0 && p <= SERIAL_MAX_PAGE); - Assert(q >= 0 && q <= SERIAL_MAX_PAGE); - - diff = p - q; - if (diff >= ((SERIAL_MAX_PAGE + 1) / 2)) - diff -= SERIAL_MAX_PAGE + 1; - else if (diff < -((int) (SERIAL_MAX_PAGE + 1) / 2)) - diff += SERIAL_MAX_PAGE + 1; - return diff < 0; + headPage = newestPage; + targetPage = oldestPage; + Assert(!SerialPagePrecedesLogically(headPage, targetPage)); + + /* + * In this scenario, the SLRU headPage pertains to oldestXact. We're + * summarizing an XID near newestXact. (Assume few other XIDs used + * SERIALIZABLE, hence the minimal headPage advancement. Assume + * oldestXact was long-running and only recently reached the SLRU.) + * Function must return true to make SerialAdd() create targetPage. + * + * Today's implementation mishandles this case, but it doesn't matter + * enough to fix. Verify that the defect affects just one page by + * asserting correct treatment of its prior page. Reaching this case + * requires burning ~2B XIDs in single-user mode, a negligible + * possibility. Moreover, if it does happen, the consequence would be + * mild, namely a new transaction failing in SimpleLruReadPage(). + */ + headPage = oldestPage; + targetPage = newestPage; + Assert(SerialPagePrecedesLogically(headPage, targetPage - 1)); +#if 0 + Assert(SerialPagePrecedesLogically(headPage, targetPage)); +#endif } +#endif /* * Initialize for the tracking of old serializable committed xids. @@ -821,9 +873,11 @@ SerialInit(void) SerialSlruCtl->PagePrecedes = SerialPagePrecedesLogically; SimpleLruInit(SerialSlruCtl, "Serial", NUM_SERIAL_BUFFERS, 0, SerialSLRULock, "pg_serial", - LWTRANCHE_SERIAL_BUFFER); - /* Override default assumption that writes should be fsync'd */ - SerialSlruCtl->do_fsync = false; + LWTRANCHE_SERIAL_BUFFER, SYNC_HANDLER_NONE); +#ifdef USE_ASSERT_CHECKING + SerialPagePrecedesLogicallyUnitTests(); +#endif + SlruPagePrecedesUnitTests(SerialSlruCtl, SERIAL_ENTRIESPERPAGE); /* * Create or attach to the SerialControl structure. @@ -1032,7 +1086,7 @@ CheckPointPredicate(void) } else { - /* + /*---------- * The SLRU is no longer needed. Truncate to head before we set head * invalid. * @@ -1041,6 +1095,25 @@ CheckPointPredicate(void) * that we leave behind will appear to be new again. In that case it * won't be removed until XID horizon advances enough to make it * current again. + * + * XXX: This should happen in vac_truncate_clog(), not in checkpoints. + * Consider this scenario, starting from a system with no in-progress + * transactions and VACUUM FREEZE having maximized oldestXact: + * - Start a SERIALIZABLE transaction. + * - Start, finish, and summarize a SERIALIZABLE transaction, creating + * one SLRU page. + * - Consume XIDs to reach xidStopLimit. + * - Finish all transactions. Due to the long-running SERIALIZABLE + * transaction, earlier checkpoints did not touch headPage. The + * next checkpoint will change it, but that checkpoint happens after + * the end of the scenario. + * - VACUUM to advance XID limits. + * - Consume ~2M XIDs, crossing the former xidWrapLimit. + * - Start, finish, and summarize a SERIALIZABLE transaction. + * SerialAdd() declines to create the targetPage, because headPage + * is not regarded as in the past relative to that targetPage. The + * transaction instigating the summarize fails in + * SimpleLruReadPage(). */ tailPage = serialControl->headPage; serialControl->headPage = -1; @@ -1052,7 +1125,7 @@ CheckPointPredicate(void) SimpleLruTruncate(SerialSlruCtl, tailPage); /* - * Flush dirty SLRU pages to disk + * Write dirty SLRU pages to disk * * This is not actually necessary from a correctness point of view. We do * it merely as a debugging aid. @@ -1061,7 +1134,7 @@ CheckPointPredicate(void) * before deleting the file in which they sit, which would be completely * pointless. */ - SimpleLruFlush(SerialSlruCtl, true); + SimpleLruWriteAll(SerialSlruCtl, true); } /*------------------------------------------------------------------------*/ @@ -1098,7 +1171,6 @@ InitPredicateLocks(void) * Allocate hash table for PREDICATELOCKTARGET structs. This stores * per-predicate-lock-target information. */ - MemSet(&info, 0, sizeof(info)); info.keysize = sizeof(PREDICATELOCKTARGETTAG); info.entrysize = sizeof(PREDICATELOCKTARGET); info.num_partitions = NUM_PREDICATELOCK_PARTITIONS; @@ -1131,7 +1203,6 @@ InitPredicateLocks(void) * Allocate hash table for PREDICATELOCK structs. This stores per * xact-lock-of-a-target information. */ - MemSet(&info, 0, sizeof(info)); info.keysize = sizeof(PREDICATELOCKTAG); info.entrysize = sizeof(PREDICATELOCK); info.hash = predicatelock_hash; @@ -1214,7 +1285,6 @@ InitPredicateLocks(void) * Allocate hash table for SERIALIZABLEXID structs. This stores per-xid * information for serializable transactions which have accessed data. */ - MemSet(&info, 0, sizeof(info)); info.keysize = sizeof(SERIALIZABLEXIDTAG); info.entrysize = sizeof(SERIALIZABLEXID); @@ -1532,7 +1602,7 @@ GetSafeSnapshot(Snapshot origSnapshot) /* else, need to retry... */ ereport(DEBUG2, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("deferrable snapshot was unsafe; trying a new one"))); + errmsg_internal("deferrable snapshot was unsafe; trying a new one"))); ReleasePredicateLocks(false, false); } @@ -1855,7 +1925,6 @@ CreateLocalPredicateLockHash(void) /* Initialize the backend-local hash table of parent locks */ Assert(LocalPredicateLockHash == NULL); - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(PREDICATELOCKTARGETTAG); hash_ctl.entrysize = sizeof(LOCALPREDICATELOCK); LocalPredicateLockHash = hash_create("Local predicate lock", diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index b6f8e5124b5c..2f35582937a7 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -79,6 +79,7 @@ int StatementTimeout = 0; int LockTimeout = 0; int IdleInTransactionSessionTimeout = 0; int IdleSessionGangTimeout = 0; +int IdleSessionTimeout = 0; bool log_lock_waits = false; /* Pointer to this process's PGPROC struct, if any */ @@ -125,7 +126,7 @@ ProcGlobalShmemSize(void) { Size size = 0; Size TotalProcs = - add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts)); + add_size(MaxBackends, add_size(NUM_AUXILIARY_PROCS, max_prepared_xacts)); /* ProcGlobal */ size = add_size(size, sizeof(PROC_HDR)); @@ -134,7 +135,7 @@ ProcGlobalShmemSize(void) size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids))); size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates))); - size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->vacuumFlags))); + size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags))); return size; } @@ -236,8 +237,8 @@ InitProcGlobal(void) MemSet(ProcGlobal->xids, 0, TotalProcs * sizeof(*ProcGlobal->xids)); ProcGlobal->subxidStates = (XidCacheStatus *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->subxidStates)); MemSet(ProcGlobal->subxidStates, 0, TotalProcs * sizeof(*ProcGlobal->subxidStates)); - ProcGlobal->vacuumFlags = (uint8 *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->vacuumFlags)); - MemSet(ProcGlobal->vacuumFlags, 0, TotalProcs * sizeof(*ProcGlobal->vacuumFlags)); + ProcGlobal->statusFlags = (uint8 *) ShmemAlloc(TotalProcs * sizeof(*ProcGlobal->statusFlags)); + MemSet(ProcGlobal->statusFlags, 0, TotalProcs * sizeof(*ProcGlobal->statusFlags)); /* * Also allocate a separate array of TMGXACT structures out of the same @@ -314,6 +315,7 @@ InitProcGlobal(void) */ pg_atomic_init_u32(&(procs[i].procArrayGroupNext), INVALID_PGPROCNO); pg_atomic_init_u32(&(procs[i].clogGroupNext), INVALID_PGPROCNO); + pg_atomic_init_u64(&(procs[i].waitStart), 0); } /* @@ -467,10 +469,10 @@ InitProcess(void) MyProc->tempNamespaceId = InvalidOid; MyProc->isBackgroundWorker = IsBackgroundWorker; MyProc->delayChkpt = false; - MyProc->vacuumFlags = 0; + MyProc->statusFlags = 0; /* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */ if (IsAutoVacuumWorkerProcess()) - MyProc->vacuumFlags |= PROC_IS_AUTOVACUUM; + MyProc->statusFlags |= PROC_IS_AUTOVACUUM; MyProc->lwWaiting = false; MyProc->lwWaitMode = 0; MyProc->waitLock = NULL; @@ -524,6 +526,7 @@ InitProcess(void) } /* Initialise for sync rep */ + pg_atomic_write_u64(&MyProc->waitStart, 0); #ifdef USE_ASSERT_CHECKING { int i; @@ -568,6 +571,9 @@ InitProcess(void) OwnLatch(&MyProc->procLatch); SwitchToSharedLatch(); + /* now that we have a proc, report wait events to shared memory */ + pgstat_set_wait_event_storage(&MyProc->wait_event_info); + /* * We might be reusing a semaphore that belonged to a failed process. So * be careful and reinitialize its value here. (This is not strictly @@ -715,11 +721,12 @@ InitAuxiliaryProcess(void) MyProc->tempNamespaceId = InvalidOid; MyProc->isBackgroundWorker = IsBackgroundWorker; MyProc->delayChkpt = false; - MyProc->vacuumFlags = 0; + MyProc->statusFlags = 0; MyProc->lwWaiting = false; MyProc->lwWaitMode = 0; MyProc->waitLock = NULL; MyProc->waitProcLock = NULL; + pg_atomic_write_u64(&MyProc->waitStart, 0); #ifdef USE_ASSERT_CHECKING { int i; @@ -738,6 +745,9 @@ InitAuxiliaryProcess(void) OwnLatch(&MyProc->procLatch); SwitchToSharedLatch(); + /* now that we have a proc, report wait events to shared memory */ + pgstat_set_wait_event_storage(&MyProc->wait_event_info); + /* Check that group locking fields are in a proper initial state. */ Assert(MyProc->lockGroupLeader == NULL); Assert(dlist_is_empty(&MyProc->lockGroupMembers)); @@ -1091,10 +1101,15 @@ ProcKill(int code, Datum arg) /* * Reset MyLatch to the process local one. This is so that signal * handlers et al can continue using the latch after the shared latch - * isn't ours anymore. After that clear MyProc and disown the shared - * latch. + * isn't ours anymore. + * + * Similarly, stop reporting wait events to MyProc->wait_event_info. + * + * After that clear MyProc and disown the shared latch. */ SwitchBackToLocalLatch(); + pgstat_reset_wait_event_storage(); + proc = MyProc; MyProc = NULL; lockHolderProcPtr = NULL; @@ -1161,13 +1176,10 @@ AuxiliaryProcKill(int code, Datum arg) /* Cancel any pending condition variable sleep, too */ ConditionVariableCancelSleep(); - /* - * Reset MyLatch to the process local one. This is so that signal - * handlers et al can continue using the latch after the shared latch - * isn't ours anymore. After that clear MyProc and disown the shared - * latch. - */ + /* look at the equivalent ProcKill() code for comments */ SwitchBackToLocalLatch(); + pgstat_reset_wait_event_storage(); + proc = MyProc; MyProc = NULL; lockHolderProcPtr = NULL; @@ -1277,8 +1289,10 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) LWLock *partitionLock = LockHashPartitionLock(hashcode); PROC_QUEUE *waitQueue = &(lock->waitProcs); LOCKMASK myHeldLocks = MyProc->heldLocks; + TimestampTz standbyWaitStart = 0; bool early_deadlock = false; bool allow_autovacuum_cancel = true; + bool logged_recovery_conflict = false; ProcWaitStatus myWaitStatus; PGPROC *proc; PGPROC *leader = MyProc->lockGroupLeader; @@ -1445,8 +1459,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) /* * Set timer so we can wake up after awhile and check for a deadlock. If a * deadlock is detected, the handler sets MyProc->waitStatus = - * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure rather - * than success. + * PROC_WAIT_STATUS_ERROR, allowing us to know that we must report failure + * rather than success. * * By delaying the check until we've waited for a bit, we can avoid * running the rather expensive deadlock-check code in most cases. @@ -1473,6 +1487,31 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) } else enable_timeout_after(DEADLOCK_TIMEOUT, DeadlockTimeout); + + /* + * Use the current time obtained for the deadlock timeout timer as + * waitStart (i.e., the time when this process started waiting for the + * lock). Since getting the current time newly can cause overhead, we + * reuse the already-obtained time to avoid that overhead. + * + * Note that waitStart is updated without holding the lock table's + * partition lock, to avoid the overhead by additional lock + * acquisition. This can cause "waitstart" in pg_locks to become NULL + * for a very short period of time after the wait started even though + * "granted" is false. This is OK in practice because we can assume + * that users are likely to look at "waitstart" when waiting for the + * lock for a long time. + */ + pg_atomic_write_u64(&MyProc->waitStart, + get_timeout_start_time(DEADLOCK_TIMEOUT)); + } + else if (log_recovery_conflict_waits) + { + /* + * Set the wait start timestamp if logging is enabled and in hot + * standby. + */ + standbyWaitStart = GetCurrentTimestamp(); } /* @@ -1493,8 +1532,43 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) { if (InHotStandby) { - /* Set a timer and wait for that or for the Lock to be granted */ - ResolveRecoveryConflictWithLock(locallock->tag.lock); + bool maybe_log_conflict = + (standbyWaitStart != 0 && !logged_recovery_conflict); + + /* Set a timer and wait for that or for the lock to be granted */ + ResolveRecoveryConflictWithLock(locallock->tag.lock, + maybe_log_conflict); + + /* + * Emit the log message if the startup process is waiting longer + * than deadlock_timeout for recovery conflict on lock. + */ + if (maybe_log_conflict) + { + TimestampTz now = GetCurrentTimestamp(); + + if (TimestampDifferenceExceeds(standbyWaitStart, now, + DeadlockTimeout)) + { + VirtualTransactionId *vxids; + int cnt; + + vxids = GetLockConflicts(&locallock->tag.lock, + AccessExclusiveLock, &cnt); + + /* + * Log the recovery conflict and the list of PIDs of + * backends holding the conflicting lock. Note that we do + * logging even if there are no such backends right now + * because the startup process here has already waited + * longer than deadlock_timeout. + */ + LogRecoveryConflict(PROCSIG_RECOVERY_CONFLICT_LOCK, + standbyWaitStart, now, + cnt > 0 ? vxids : NULL, true); + logged_recovery_conflict = true; + } + } } else { @@ -1511,9 +1585,9 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) } /* - * waitStatus could change from PROC_WAIT_STATUS_WAITING to something else - * asynchronously. Read it just once per loop to prevent surprising - * behavior (such as missing log messages). + * waitStatus could change from PROC_WAIT_STATUS_WAITING to something + * else asynchronously. Read it just once per loop to prevent + * surprising behavior (such as missing log messages). */ myWaitStatus = *((volatile ProcWaitStatus *) &MyProc->waitStatus); @@ -1524,41 +1598,59 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) if (deadlock_state == DS_BLOCKED_BY_AUTOVACUUM && allow_autovacuum_cancel) { PGPROC *autovac = GetBlockingAutoVacuumPgproc(); - uint8 vacuumFlags; + uint8 statusFlags; + uint8 lockmethod_copy; + LOCKTAG locktag_copy; + /* + * Grab info we need, then release lock immediately. Note this + * coding means that there is a tiny chance that the process + * terminates its current transaction and starts a different one + * before we have a change to send the signal; the worst possible + * consequence is that a for-wraparound vacuum is cancelled. But + * that could happen in any case unless we were to do kill() with + * the lock held, which is much more undesirable. + */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); + statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff]; + lockmethod_copy = lock->tag.locktag_lockmethodid; + locktag_copy = lock->tag; + LWLockRelease(ProcArrayLock); /* * Only do it if the worker is not working to protect against Xid * wraparound. */ - vacuumFlags = ProcGlobal->vacuumFlags[proc->pgxactoff]; - if ((vacuumFlags & PROC_IS_AUTOVACUUM) && - !(vacuumFlags & PROC_VACUUM_FOR_WRAPAROUND)) + if ((statusFlags & PROC_IS_AUTOVACUUM) && + !(statusFlags & PROC_VACUUM_FOR_WRAPAROUND)) { int pid = autovac->pid; - StringInfoData locktagbuf; - StringInfoData logbuf; /* errdetail for server log */ - - initStringInfo(&locktagbuf); - initStringInfo(&logbuf); - DescribeLockTag(&locktagbuf, &lock->tag); - appendStringInfo(&logbuf, - _("Process %d waits for %s on %s."), - MyProcPid, - GetLockmodeName(lock->tag.locktag_lockmethodid, - lockmode), - locktagbuf.data); - - /* release lock as quickly as possible */ - LWLockRelease(ProcArrayLock); - /* send the autovacuum worker Back to Old Kent Road */ - ereport(DEBUG1, - (errmsg("sending cancel to blocking autovacuum PID %d", - pid), - errdetail_log("%s", logbuf.data))); + /* report the case, if configured to do so */ + if (message_level_is_interesting(DEBUG1)) + { + StringInfoData locktagbuf; + StringInfoData logbuf; /* errdetail for server log */ + + initStringInfo(&locktagbuf); + initStringInfo(&logbuf); + DescribeLockTag(&locktagbuf, &locktag_copy); + appendStringInfo(&logbuf, + "Process %d waits for %s on %s.", + MyProcPid, + GetLockmodeName(lockmethod_copy, lockmode), + locktagbuf.data); + + ereport(DEBUG1, + (errmsg_internal("sending cancel to blocking autovacuum PID %d", + pid), + errdetail_log("%s", logbuf.data))); + + pfree(locktagbuf.data); + pfree(logbuf.data); + } + /* send the autovacuum worker Back to Old Kent Road */ if (kill(pid, SIGINT) < 0) { /* @@ -1576,14 +1668,9 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) (errmsg("could not send signal to process %d: %m", pid))); } - - pfree(logbuf.data); - pfree(locktagbuf.data); } - else - LWLockRelease(ProcArrayLock); - /* prevent signal from being resent more than once */ + /* prevent signal from being sent again more than once */ allow_autovacuum_cancel = false; } @@ -1714,11 +1801,12 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) /* * Currently, the deadlock checker always kicks its own - * process, which means that we'll only see PROC_WAIT_STATUS_ERROR when - * deadlock_state == DS_HARD_DEADLOCK, and there's no need to - * print redundant messages. But for completeness and - * future-proofing, print a message if it looks like someone - * else kicked us off the lock. + * process, which means that we'll only see + * PROC_WAIT_STATUS_ERROR when deadlock_state == + * DS_HARD_DEADLOCK, and there's no need to print redundant + * messages. But for completeness and future-proofing, print + * a message if it looks like someone else kicked us off the + * lock. */ if (deadlock_state != DS_HARD_DEADLOCK) ereport(LOG, @@ -1763,6 +1851,15 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) disable_timeout(DEADLOCK_TIMEOUT, false); } + /* + * Emit the log message if recovery conflict on lock was resolved but the + * startup process waited longer than deadlock_timeout for it. + */ + if (InHotStandby && logged_recovery_conflict) + LogRecoveryConflict(PROCSIG_RECOVERY_CONFLICT_LOCK, + standbyWaitStart, GetCurrentTimestamp(), + NULL, false); + /* * Re-acquire the lock table's partition lock. We have to do this to hold * off cancel/die interrupts before we can mess with lockAwaited (else we @@ -1824,6 +1921,7 @@ ProcWakeup(PGPROC *proc, ProcWaitStatus waitStatus) proc->waitLock = NULL; proc->waitProcLock = NULL; proc->waitStatus = waitStatus; + pg_atomic_write_u64(&MyProc->waitStart, 0); /* And awaken it */ SetLatch(&proc->procLatch); @@ -1964,9 +2062,9 @@ CheckDeadLock(void) * preserve the flexibility to kill some other transaction than the * one detecting the deadlock.) * - * RemoveFromWaitQueue sets MyProc->waitStatus to PROC_WAIT_STATUS_ERROR, so - * ProcSleep will report an error after we return from the signal - * handler. + * RemoveFromWaitQueue sets MyProc->waitStatus to + * PROC_WAIT_STATUS_ERROR, so ProcSleep will report an error after we + * return from the signal handler. */ Assert(MyProc->waitLock != NULL); if (Gp_role == GP_ROLE_DISPATCH && IsResQueueEnabled() && @@ -2034,6 +2132,9 @@ CheckDeadLockAlert(void) * Have to set the latch again, even if handle_sig_alarm already did. Back * then got_deadlock_timeout wasn't yet set... It's unlikely that this * ever would be a problem, but setting a set latch again is cheap. + * + * Note that, when this function runs inside procsignal_sigusr1_handler(), + * the handler function sets the latch again after the latch is set here. */ SetLatch(MyLatch); errno = save_errno; diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c index 32830923a9f0..e27a53e8623f 100644 --- a/src/backend/storage/lmgr/s_lock.c +++ b/src/backend/storage/lmgr/s_lock.c @@ -36,7 +36,7 @@ * the probability of unintended failure) than to fix the total time * spent. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/lmgr/spin.c b/src/backend/storage/lmgr/spin.c index 9f7eae933922..557672caddad 100644 --- a/src/backend/storage/lmgr/spin.c +++ b/src/backend/storage/lmgr/spin.c @@ -11,7 +11,7 @@ * is too slow to be very useful :-( * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -37,7 +37,7 @@ #define NUM_EMULATION_SEMAPHORES (NUM_SPINLOCK_SEMAPHORES + NUM_ATOMICS_SEMAPHORES) #else #define NUM_EMULATION_SEMAPHORES (NUM_SPINLOCK_SEMAPHORES) -#endif /* DISABLE_ATOMICS */ +#endif /* DISABLE_ATOMICS */ PGSemaphore *SpinlockSemaArray; diff --git a/src/backend/storage/page/Makefile b/src/backend/storage/page/Makefile index 10021e2bb31e..da539b113a69 100644 --- a/src/backend/storage/page/Makefile +++ b/src/backend/storage/page/Makefile @@ -19,5 +19,5 @@ OBJS = \ include $(top_srcdir)/src/backend/common.mk -# important optimizations flags for checksum.c -checksum.o: CFLAGS += ${CFLAGS_VECTOR} +# Provide special optimization flags for checksum.c +checksum.o: CFLAGS += ${CFLAGS_UNROLL_LOOPS} ${CFLAGS_VECTORIZE} diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index d708117a4067..82ca91f59774 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -3,7 +3,7 @@ * bufpage.c * POSTGRES standard buffer page code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -61,7 +61,7 @@ PageInit(Page page, Size pageSize, Size specialSize) /* - * PageIsVerified + * PageIsVerifiedExtended * Check that the page header and checksum (if any) appear valid. * * This is called when a page has just been read in from disk. The idea is @@ -77,9 +77,15 @@ PageInit(Page page, Size pageSize, Size specialSize) * allow zeroed pages here, and are careful that the page access macros * treat such a page as empty and without free space. Eventually, VACUUM * will clean up such a page and make it usable. + * + * If flag PIV_LOG_WARNING is set, a WARNING is logged in the event of + * a checksum failure. + * + * If flag PIV_REPORT_STAT is set, a checksum failure is reported directly + * to pgstat. */ bool -PageIsVerified(Page page, BlockNumber blkno) +PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags) { PageHeader p = (PageHeader) page; size_t *pagebytes; @@ -140,12 +146,14 @@ PageIsVerified(Page page, BlockNumber blkno) */ if (checksum_failure) { - ereport(WARNING, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("page verification failed, calculated checksum %u but expected %u", - checksum, p->pd_checksum))); + if ((flags & PIV_LOG_WARNING) != 0) + ereport(WARNING, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("page verification failed, calculated checksum %u but expected %u", + checksum, p->pd_checksum))); - pgstat_report_checksum_failure(); + if ((flags & PIV_REPORT_STAT) != 0) + pgstat_report_checksum_failure(); if (header_sane && ignore_checksum_failure) return true; @@ -243,13 +251,26 @@ PageAddItemExtended(Page page, if (PageHasFreeLinePointers(phdr)) { /* - * Look for "recyclable" (unused) ItemId. We check for no storage - * as well, just to be paranoid --- unused items should never have - * storage. + * Scan line pointer array to locate a "recyclable" (unused) + * ItemId. + * + * Always use earlier items first. PageTruncateLinePointerArray + * can only truncate unused items when they appear as a contiguous + * group at the end of the line pointer array. */ - for (offsetNumber = 1; offsetNumber < limit; offsetNumber++) + for (offsetNumber = FirstOffsetNumber; + offsetNumber < limit; /* limit is maxoff+1 */ + offsetNumber++) { itemId = PageGetItemId(phdr, offsetNumber); + + /* + * We check for no storage as well, just to be paranoid; + * unused items should never have storage. Assert() that the + * invariant is respected too. + */ + Assert(ItemIdIsUsed(itemId) || !ItemIdHasStorage(itemId)); + if (!ItemIdIsUsed(itemId) && !ItemIdHasStorage(itemId)) break; } @@ -411,51 +432,250 @@ PageRestoreTempPage(Page tempPage, Page oldPage) } /* - * sorting support for PageRepairFragmentation and PageIndexMultiDelete + * Tuple defrag support for PageRepairFragmentation and PageIndexMultiDelete */ -typedef struct itemIdSortData +typedef struct itemIdCompactData { uint16 offsetindex; /* linp array index */ int16 itemoff; /* page offset of item data */ uint16 alignedlen; /* MAXALIGN(item data len) */ -} itemIdSortData; -typedef itemIdSortData *itemIdSort; - -static int -itemoffcompare(const void *itemidp1, const void *itemidp2) -{ - /* Sort in decreasing itemoff order */ - return ((itemIdSort) itemidp2)->itemoff - - ((itemIdSort) itemidp1)->itemoff; -} +} itemIdCompactData; +typedef itemIdCompactData *itemIdCompact; /* * After removing or marking some line pointers unused, move the tuples to - * remove the gaps caused by the removed items. + * remove the gaps caused by the removed items and reorder them back into + * reverse line pointer order in the page. + * + * This function can often be fairly hot, so it pays to take some measures to + * make it as optimal as possible. + * + * Callers may pass 'presorted' as true if the 'itemidbase' array is sorted in + * descending order of itemoff. When this is true we can just memmove() + * tuples towards the end of the page. This is quite a common case as it's + * the order that tuples are initially inserted into pages. When we call this + * function to defragment the tuples in the page then any new line pointers + * added to the page will keep that presorted order, so hitting this case is + * still very common for tables that are commonly updated. + * + * When the 'itemidbase' array is not presorted then we're unable to just + * memmove() tuples around freely. Doing so could cause us to overwrite the + * memory belonging to a tuple we've not moved yet. In this case, we copy all + * the tuples that need to be moved into a temporary buffer. We can then + * simply memcpy() out of that temp buffer back into the page at the correct + * location. Tuples are copied back into the page in the same order as the + * 'itemidbase' array, so we end up reordering the tuples back into reverse + * line pointer order. This will increase the chances of hitting the + * presorted case the next time around. + * + * Callers must ensure that nitems is > 0 */ static void -compactify_tuples(itemIdSort itemidbase, int nitems, Page page) +compactify_tuples(itemIdCompact itemidbase, int nitems, Page page, bool presorted) { PageHeader phdr = (PageHeader) page; Offset upper; + Offset copy_tail; + Offset copy_head; + itemIdCompact itemidptr; int i; - /* sort itemIdSortData array into decreasing itemoff order */ - qsort((char *) itemidbase, nitems, sizeof(itemIdSortData), - itemoffcompare); + /* Code within will not work correctly if nitems == 0 */ + Assert(nitems > 0); - upper = phdr->pd_special; - for (i = 0; i < nitems; i++) + if (presorted) { - itemIdSort itemidptr = &itemidbase[i]; - ItemId lp; - lp = PageGetItemId(page, itemidptr->offsetindex + 1); - upper -= itemidptr->alignedlen; +#ifdef USE_ASSERT_CHECKING + { + /* + * Verify we've not gotten any new callers that are incorrectly + * passing a true presorted value. + */ + Offset lastoff = phdr->pd_special; + + for (i = 0; i < nitems; i++) + { + itemidptr = &itemidbase[i]; + + Assert(lastoff > itemidptr->itemoff); + + lastoff = itemidptr->itemoff; + } + } +#endif /* USE_ASSERT_CHECKING */ + + /* + * 'itemidbase' is already in the optimal order, i.e, lower item + * pointers have a higher offset. This allows us to memmove() the + * tuples up to the end of the page without having to worry about + * overwriting other tuples that have not been moved yet. + * + * There's a good chance that there are tuples already right at the + * end of the page that we can simply skip over because they're + * already in the correct location within the page. We'll do that + * first... + */ + upper = phdr->pd_special; + i = 0; + do + { + itemidptr = &itemidbase[i]; + if (upper != itemidptr->itemoff + itemidptr->alignedlen) + break; + upper -= itemidptr->alignedlen; + + i++; + } while (i < nitems); + + /* + * Now that we've found the first tuple that needs to be moved, we can + * do the tuple compactification. We try and make the least number of + * memmove() calls and only call memmove() when there's a gap. When + * we see a gap we just move all tuples after the gap up until the + * point of the last move operation. + */ + copy_tail = copy_head = itemidptr->itemoff + itemidptr->alignedlen; + for (; i < nitems; i++) + { + ItemId lp; + + itemidptr = &itemidbase[i]; + lp = PageGetItemId(page, itemidptr->offsetindex + 1); + + if (copy_head != itemidptr->itemoff + itemidptr->alignedlen) + { + memmove((char *) page + upper, + page + copy_head, + copy_tail - copy_head); + + /* + * We've now moved all tuples already seen, but not the + * current tuple, so we set the copy_tail to the end of this + * tuple so it can be moved in another iteration of the loop. + */ + copy_tail = itemidptr->itemoff + itemidptr->alignedlen; + } + /* shift the target offset down by the length of this tuple */ + upper -= itemidptr->alignedlen; + /* point the copy_head to the start of this tuple */ + copy_head = itemidptr->itemoff; + + /* update the line pointer to reference the new offset */ + lp->lp_off = upper; + + } + + /* move the remaining tuples. */ memmove((char *) page + upper, - (char *) page + itemidptr->itemoff, - itemidptr->alignedlen); - lp->lp_off = upper; + page + copy_head, + copy_tail - copy_head); + } + else + { + PGAlignedBlock scratch; + char *scratchptr = scratch.data; + + /* + * Non-presorted case: The tuples in the itemidbase array may be in + * any order. So, in order to move these to the end of the page we + * must make a temp copy of each tuple that needs to be moved before + * we copy them back into the page at the new offset. + * + * If a large percentage of tuples have been pruned (>75%) then we'll + * copy these into the temp buffer tuple-by-tuple, otherwise, we'll + * just do a single memcpy() for all tuples that need to be moved. + * When so many tuples have been removed there's likely to be a lot of + * gaps and it's unlikely that many non-movable tuples remain at the + * end of the page. + */ + if (nitems < PageGetMaxOffsetNumber(page) / 4) + { + i = 0; + do + { + itemidptr = &itemidbase[i]; + memcpy(scratchptr + itemidptr->itemoff, page + itemidptr->itemoff, + itemidptr->alignedlen); + i++; + } while (i < nitems); + + /* Set things up for the compactification code below */ + i = 0; + itemidptr = &itemidbase[0]; + upper = phdr->pd_special; + } + else + { + upper = phdr->pd_special; + + /* + * Many tuples are likely to already be in the correct location. + * There's no need to copy these into the temp buffer. Instead + * we'll just skip forward in the itemidbase array to the position + * that we do need to move tuples from so that the code below just + * leaves these ones alone. + */ + i = 0; + do + { + itemidptr = &itemidbase[i]; + if (upper != itemidptr->itemoff + itemidptr->alignedlen) + break; + upper -= itemidptr->alignedlen; + + i++; + } while (i < nitems); + + /* Copy all tuples that need to be moved into the temp buffer */ + memcpy(scratchptr + phdr->pd_upper, + page + phdr->pd_upper, + upper - phdr->pd_upper); + } + + /* + * Do the tuple compactification. itemidptr is already pointing to + * the first tuple that we're going to move. Here we collapse the + * memcpy calls for adjacent tuples into a single call. This is done + * by delaying the memcpy call until we find a gap that needs to be + * closed. + */ + copy_tail = copy_head = itemidptr->itemoff + itemidptr->alignedlen; + for (; i < nitems; i++) + { + ItemId lp; + + itemidptr = &itemidbase[i]; + lp = PageGetItemId(page, itemidptr->offsetindex + 1); + + /* copy pending tuples when we detect a gap */ + if (copy_head != itemidptr->itemoff + itemidptr->alignedlen) + { + memcpy((char *) page + upper, + scratchptr + copy_head, + copy_tail - copy_head); + + /* + * We've now copied all tuples already seen, but not the + * current tuple, so we set the copy_tail to the end of this + * tuple. + */ + copy_tail = itemidptr->itemoff + itemidptr->alignedlen; + } + /* shift the target offset down by the length of this tuple */ + upper -= itemidptr->alignedlen; + /* point the copy_head to the start of this tuple */ + copy_head = itemidptr->itemoff; + + /* update the line pointer to reference the new offset */ + lp->lp_off = upper; + + } + + /* Copy the remaining chunk */ + memcpy((char *) page + upper, + scratchptr + copy_head, + copy_tail - copy_head); } phdr->pd_upper = upper; @@ -464,12 +684,26 @@ compactify_tuples(itemIdSort itemidbase, int nitems, Page page) /* * PageRepairFragmentation * - * Frees fragmented space on a page. - * It doesn't remove unused line pointers! Please don't change this. + * Frees fragmented space on a heap page following pruning. * * This routine is usable for heap pages only, but see PageIndexMultiDelete. * - * As a side effect, the page's PD_HAS_FREE_LINES hint bit is updated. + * Never removes unused line pointers. PageTruncateLinePointerArray can + * safely remove some unused line pointers. It ought to be safe for this + * routine to free unused line pointers in roughly the same way, but it's not + * clear that that would be beneficial. + * + * PageTruncateLinePointerArray is only called during VACUUM's second pass + * over the heap. Any unused line pointers that it sees are likely to have + * been set to LP_UNUSED (from LP_DEAD) immediately before the time it is + * called. On the other hand, many tables have the vast majority of all + * required pruning performed opportunistically (not during VACUUM). And so + * there is, in general, a good chance that even large groups of unused line + * pointers that we see here will be recycled quickly. + * + * Caller had better have a super-exclusive lock on page's buffer. As a side + * effect the page's PD_HAS_FREE_LINES hint bit will be set or unset as + * needed. */ void PageRepairFragmentation(Page page) @@ -477,14 +711,16 @@ PageRepairFragmentation(Page page) Offset pd_lower = ((PageHeader) page)->pd_lower; Offset pd_upper = ((PageHeader) page)->pd_upper; Offset pd_special = ((PageHeader) page)->pd_special; - itemIdSortData itemidbase[MaxHeapTuplesPerPage]; - itemIdSort itemidptr; + Offset last_offset; + itemIdCompactData itemidbase[MaxHeapTuplesPerPage]; + itemIdCompact itemidptr; ItemId lp; int nline, nstorage, nunused; int i; Size totallen; + bool presorted = true; /* For now */ /* * It's worth the trouble to be more paranoid here than in most places, @@ -509,6 +745,7 @@ PageRepairFragmentation(Page page) nline = PageGetMaxOffsetNumber(page); itemidptr = itemidbase; nunused = totallen = 0; + last_offset = pd_special; for (i = FirstOffsetNumber; i <= nline; i++) { lp = PageGetItemId(page, i); @@ -518,6 +755,12 @@ PageRepairFragmentation(Page page) { itemidptr->offsetindex = i - 1; itemidptr->itemoff = ItemIdGetOffset(lp); + + if (last_offset > itemidptr->itemoff) + last_offset = itemidptr->itemoff; + else + presorted = false; + if (unlikely(itemidptr->itemoff < (int) pd_upper || itemidptr->itemoff >= (int) pd_special)) ereport(ERROR, @@ -552,16 +795,99 @@ PageRepairFragmentation(Page page) errmsg("corrupted item lengths: total %u, available space %u", (unsigned int) totallen, pd_special - pd_lower))); - compactify_tuples(itemidbase, nstorage, page); + compactify_tuples(itemidbase, nstorage, page, presorted); } - /* Set hint bit for PageAddItem */ + /* Set hint bit for PageAddItemExtended */ if (nunused > 0) PageSetHasFreeLinePointers(page); else PageClearHasFreeLinePointers(page); } +/* + * PageTruncateLinePointerArray + * + * Removes unused line pointers at the end of the line pointer array. + * + * This routine is usable for heap pages only. It is called by VACUUM during + * its second pass over the heap. We expect at least one LP_UNUSED line + * pointer on the page (if VACUUM didn't have an LP_DEAD item on the page that + * it just set to LP_UNUSED then it should not call here). + * + * We avoid truncating the line pointer array to 0 items, if necessary by + * leaving behind a single remaining LP_UNUSED item. This is a little + * arbitrary, but it seems like a good idea to avoid leaving a PageIsEmpty() + * page behind. + * + * Caller can have either an exclusive lock or a super-exclusive lock on + * page's buffer. The page's PD_HAS_FREE_LINES hint bit will be set or unset + * based on whether or not we leave behind any remaining LP_UNUSED items. + */ +void +PageTruncateLinePointerArray(Page page) +{ + PageHeader phdr = (PageHeader) page; + bool countdone = false, + sethint = false; + int nunusedend = 0; + + /* Scan line pointer array back-to-front */ + for (int i = PageGetMaxOffsetNumber(page); i >= FirstOffsetNumber; i--) + { + ItemId lp = PageGetItemId(page, i); + + if (!countdone && i > FirstOffsetNumber) + { + /* + * Still determining which line pointers from the end of the array + * will be truncated away. Either count another line pointer as + * safe to truncate, or notice that it's not safe to truncate + * additional line pointers (stop counting line pointers). + */ + if (!ItemIdIsUsed(lp)) + nunusedend++; + else + countdone = true; + } + else + { + /* + * Once we've stopped counting we still need to figure out if + * there are any remaining LP_UNUSED line pointers somewhere more + * towards the front of the array. + */ + if (!ItemIdIsUsed(lp)) + { + /* + * This is an unused line pointer that we won't be truncating + * away -- so there is at least one. Set hint on page. + */ + sethint = true; + break; + } + } + } + + if (nunusedend > 0) + { + phdr->pd_lower -= sizeof(ItemIdData) * nunusedend; + +#ifdef CLOBBER_FREED_MEMORY + memset((char *) page + phdr->pd_lower, 0x7F, + sizeof(ItemIdData) * nunusedend); +#endif + } + else + Assert(sethint); + + /* Set hint bit for PageAddItemExtended */ + if (sethint) + PageSetHasFreeLinePointers(page); + else + PageClearHasFreeLinePointers(page); +} + /* * PageGetFreeSpace * Returns the size of the free (allocatable) space on a page, @@ -831,9 +1157,10 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems) Offset pd_lower = phdr->pd_lower; Offset pd_upper = phdr->pd_upper; Offset pd_special = phdr->pd_special; - itemIdSortData itemidbase[MaxIndexTuplesPerPage]; + Offset last_offset; + itemIdCompactData itemidbase[MaxIndexTuplesPerPage]; ItemIdData newitemids[MaxIndexTuplesPerPage]; - itemIdSort itemidptr; + itemIdCompact itemidptr; ItemId lp; int nline, nused; @@ -842,6 +1169,7 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems) unsigned offset; int nextitm; OffsetNumber offnum; + bool presorted = true; /* For now */ Assert(nitems <= MaxIndexTuplesPerPage); @@ -883,6 +1211,7 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems) totallen = 0; nused = 0; nextitm = 0; + last_offset = pd_special; for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum)) { lp = PageGetItemId(page, offnum); @@ -906,6 +1235,12 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems) { itemidptr->offsetindex = nused; /* where it will go */ itemidptr->itemoff = offset; + + if (last_offset > itemidptr->itemoff) + last_offset = itemidptr->itemoff; + else + presorted = false; + itemidptr->alignedlen = MAXALIGN(size); totallen += itemidptr->alignedlen; newitemids[nused] = *lp; @@ -932,7 +1267,10 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems) phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData); /* and compactify the tuple data */ - compactify_tuples(itemidbase, nused, page); + if (nused > 0) + compactify_tuples(itemidbase, nused, page, presorted); + else + phdr->pd_upper = pd_special; } diff --git a/src/backend/storage/page/checksum.c b/src/backend/storage/page/checksum.c index e010691c9f2a..6462ddd81261 100644 --- a/src/backend/storage/page/checksum.c +++ b/src/backend/storage/page/checksum.c @@ -3,7 +3,7 @@ * checksum.c * Checksum implementation for data pages. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/page/itemptr.c b/src/backend/storage/page/itemptr.c index bc0a7076334c..2211e93d97c3 100644 --- a/src/backend/storage/page/itemptr.c +++ b/src/backend/storage/page/itemptr.c @@ -3,7 +3,7 @@ * itemptr.c * POSTGRES disk item pointer code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -75,15 +75,10 @@ ItemPointerCompare(ItemPointer arg1, ItemPointer arg2) static char * ItemPointerToBuffer(char *buffer, ItemPointer tid) { - // Do not assert valid ItemPointer -- it is ok if it is (0,0)... BlockNumber blockNumber = BlockIdGetBlockNumber(&tid->ip_blkid); OffsetNumber offsetNumber = tid->ip_posid; - - sprintf(buffer, - "(%u,%u)", - blockNumber, - offsetNumber); + sprintf(buffer, "(%u,%u)", blockNumber, offsetNumber); return buffer; } @@ -101,3 +96,62 @@ ItemPointerToString2(ItemPointer tid) { return ItemPointerToBuffer(itemPointerBuffer2, tid); } + +/* + * ItemPointerInc + * Increment 'pointer' by 1 only paying attention to the ItemPointer's + * type's range limits and not MaxOffsetNumber and FirstOffsetNumber. + * This may result in 'pointer' becoming !OffsetNumberIsValid. + * + * If the pointer is already the maximum possible values permitted by the + * range of the ItemPointer's types, then do nothing. + */ +void +ItemPointerInc(ItemPointer pointer) +{ + BlockNumber blk = ItemPointerGetBlockNumberNoCheck(pointer); + OffsetNumber off = ItemPointerGetOffsetNumberNoCheck(pointer); + + if (off == PG_UINT16_MAX) + { + if (blk != InvalidBlockNumber) + { + off = 0; + blk++; + } + } + else + off++; + + ItemPointerSet(pointer, blk, off); +} + +/* + * ItemPointerDec + * Decrement 'pointer' by 1 only paying attention to the ItemPointer's + * type's range limits and not MaxOffsetNumber and FirstOffsetNumber. + * This may result in 'pointer' becoming !OffsetNumberIsValid. + * + * If the pointer is already the minimum possible values permitted by the + * range of the ItemPointer's types, then do nothing. This does rely on + * FirstOffsetNumber being 1 rather than 0. + */ +void +ItemPointerDec(ItemPointer pointer) +{ + BlockNumber blk = ItemPointerGetBlockNumberNoCheck(pointer); + OffsetNumber off = ItemPointerGetOffsetNumberNoCheck(pointer); + + if (off == 0) + { + if (blk != 0) + { + off = PG_UINT16_MAX; + blk--; + } + } + else + off--; + + ItemPointerSet(pointer, blk, off); +} diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 18ced8df11bd..e6dc0032e9da 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -10,7 +10,7 @@ * It doesn't matter whether the bits are on spinning rust or some other * storage technology. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -345,19 +345,8 @@ do_truncate(const char *path) { int save_errno; int ret; - int fd; - /* truncate(2) would be easier here, but Windows hasn't got it */ - fd = OpenTransientFile(path, O_RDWR | PG_BINARY); - if (fd >= 0) - { - ret = ftruncate(fd, 0); - save_errno = errno; - CloseTransientFile(fd); - errno = save_errno; - } - else - ret = -1; + ret = pg_truncate(path, 0); /* Log a warning here to avoid repetition in callers. */ if (ret < 0 && errno != ENOENT) @@ -823,9 +812,11 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum) { - MdfdVec *v = mdopenfork(reln, forknum, EXTENSION_FAIL); + MdfdVec *v; BlockNumber nblocks; - BlockNumber segno = 0; + BlockNumber segno; + + mdopenfork(reln, forknum, EXTENSION_FAIL); /* mdopen has opened the first segment */ Assert(reln->md_num_open_segs[forknum] > 0); @@ -1044,7 +1035,7 @@ register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg) if (!RegisterSyncRequest(&tag, SYNC_REQUEST, false /* retryOnError */ )) { ereport(DEBUG1, - (errmsg("could not forward fsync request because request queue is full"))); + (errmsg_internal("could not forward fsync request because request queue is full"))); if (FileSync(seg->mdfd_vfd, WAIT_EVENT_DATA_FILE_SYNC) < 0) ereport(data_sync_elevel(ERROR), diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 6168292e242c..ab3a0aa493b5 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -6,9 +6,7 @@ * All file system operations in POSTGRES dispatch through these * routines. * - * Portions Copyright (c) 2006-2008, Greenplum inc - * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -208,7 +206,6 @@ smgropen(RelFileNode rnode, BackendId backend, SMgrImpl which) /* First time through: initialize the hash table */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(RelFileNodeBackend); ctl.entrysize = sizeof(SMgrRelationData); SMgrRelationHash = hash_create("smgr relation table", 400, @@ -464,6 +461,12 @@ smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo) if (nrels == 0) return; + /* + * Get rid of any remaining buffers for the relations. bufmgr will just + * drop them without bothering to write the contents. + */ + DropRelFileNodesAllBuffers(rels, nrels); + /* * create an array which contains all relations to be dropped, and close * each relation's forks at the smgr level while at it @@ -480,12 +483,6 @@ smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo) (*rels[i]->storageManager).smgr_close(rels[i], forknum); } - /* - * Get rid of any remaining buffers for the relations. bufmgr will just - * drop them without bothering to write the contents. - */ - DropRelFileNodesAllBuffers(rnodes, nrels); - /* * It'd be nice to tell the stats collector to forget them immediately, * too. But we can't because we don't know the OIDs. @@ -626,6 +623,28 @@ smgrnblocks(SMgrRelation reln, ForkNumber forknum) { BlockNumber result; + /* Check and return if we get the cached value for the number of blocks. */ + result = smgrnblocks_cached(reln, forknum); + if (result != InvalidBlockNumber) + return result; + + result = smgrsw[reln->smgr_which].smgr_nblocks(reln, forknum); + + reln->smgr_cached_nblocks[forknum] = result; + + return result; +} + +/* + * smgrnblocks_cached() -- Get the cached number of blocks in the supplied + * relation. + * + * Returns an InvalidBlockNumber when not in recovery and when the relation + * fork size is not cached. + */ +BlockNumber +smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum) +{ /* * For now, we only use cached values in recovery due to lack of a shared * invalidation mechanism for changes in file size. @@ -633,11 +652,7 @@ smgrnblocks(SMgrRelation reln, ForkNumber forknum) if (InRecovery && reln->smgr_cached_nblocks[forknum] != InvalidBlockNumber) return reln->smgr_cached_nblocks[forknum]; - result = (*reln->storageManager).smgr_nblocks(reln, forknum); - - reln->smgr_cached_nblocks[forknum] = result; - - return result; + return InvalidBlockNumber; } /* @@ -659,7 +674,7 @@ smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, BlockNumber *nb * Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will * just drop them without bothering to write the contents. */ - DropRelFileNodeBuffers(reln->smgr_rnode, forknum, nforks, nblocks); + DropRelFileNodeBuffers(reln, forknum, nforks, nblocks); /* * Send a shared-inval message to force other backends to close any smgr diff --git a/src/backend/storage/sync/sync.c b/src/backend/storage/sync/sync.c index 9f2d7df2ae15..6149dda59786 100644 --- a/src/backend/storage/sync/sync.c +++ b/src/backend/storage/sync/sync.c @@ -3,7 +3,7 @@ * sync.c * File synchronization management code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,6 +18,9 @@ #include #include +#include "access/commit_ts.h" +#include "access/clog.h" +#include "access/multixact.h" #include "access/xlog.h" #include "access/xlogutils.h" #include "commands/tablespace.h" @@ -92,18 +95,41 @@ typedef struct SyncOps const FileTag *candidate); } SyncOps; +/* + * These indexes must correspond to the values of the SyncRequestHandler enum. + */ static const SyncOps syncsw[] = { /* magnetic disk */ - { + [SYNC_HANDLER_MD] = { .sync_syncfiletag = mdsyncfiletag, .sync_unlinkfiletag = mdunlinkfiletag, .sync_filetagmatches = mdfiletagmatches }, - /* append-optimized storage */ - { + /* + * Append-optimized (AO/AOCS) segment files. aosyncfiletag() lives in + * md.c; the deferred unlink only targets the base segfile and the filter + * matches by database, so md's handlers are correct for AO too. + */ + [SYNC_HANDLER_AO] = { .sync_syncfiletag = aosyncfiletag, .sync_unlinkfiletag = mdunlinkfiletag, .sync_filetagmatches = mdfiletagmatches + }, + /* pg_xact */ + [SYNC_HANDLER_CLOG] = { + .sync_syncfiletag = clogsyncfiletag + }, + /* pg_commit_ts */ + [SYNC_HANDLER_COMMIT_TS] = { + .sync_syncfiletag = committssyncfiletag + }, + /* pg_multixact/offsets */ + [SYNC_HANDLER_MULTIXACT_OFFSET] = { + .sync_syncfiletag = multixactoffsetssyncfiletag + }, + /* pg_multixact/members */ + [SYNC_HANDLER_MULTIXACT_MEMBER] = { + .sync_syncfiletag = multixactmemberssyncfiletag } }; @@ -136,7 +162,6 @@ InitSync(void) ALLOCSET_DEFAULT_SIZES); MemoryContextAllowInCriticalSection(pendingOpsCxt, true); - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(FileTag); hash_ctl.entrysize = sizeof(PendingFsyncEntry); hash_ctl.hcxt = pendingOpsCxt; @@ -440,8 +465,8 @@ ProcessSyncRequests(void) else ereport(DEBUG1, (errcode_for_file_access(), - errmsg("could not fsync file \"%s\" but retrying: %m", - path))); + errmsg_internal("could not fsync file \"%s\" but retrying: %m", + path))); /* * Absorb incoming requests and check to see if a cancel @@ -547,8 +572,8 @@ RememberSyncRequest(const FileTag *ftag, SyncRequestType type) (void *) ftag, HASH_ENTER, &found); - /* if new entry, initialize it */ - if (!found) + /* if new entry, or was previously canceled, initialize it */ + if (!found || entry->canceled) { entry->cycle_ctr = sync_cycle_ctr; entry->canceled = false; diff --git a/src/backend/tcop/cmdtag.c b/src/backend/tcop/cmdtag.c index b9fbff612f2a..e208c7dcfac6 100644 --- a/src/backend/tcop/cmdtag.c +++ b/src/backend/tcop/cmdtag.c @@ -3,7 +3,7 @@ * cmdtag.c * Data and routines for commandtag names and enumeration. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c index 8dfe57a7d098..309b10962afa 100644 --- a/src/backend/tcop/dest.c +++ b/src/backend/tcop/dest.c @@ -4,7 +4,7 @@ * support for communication destinations * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -213,16 +213,23 @@ EndCommand(const QueryCompletion *qc, CommandDest dest, bool force_undecorated_o } } +/* ---------------- + * EndReplicationCommand - stripped down version of EndCommand + * + * For use by replication commands. + * ---------------- + */ +void +EndReplicationCommand(const char *commandTag) +{ + pq_putmessage('C', commandTag, strlen(commandTag) + 1); +} + /* ---------------- * NullCommand - tell dest that an empty query string was recognized * - * In FE/BE protocol version 1.0, this hack is necessary to support - * libpq's crufty way of determining whether a multiple-command - * query string is done. In protocol 2.0 it's probably not really - * necessary to distinguish empty queries anymore, but we still do it - * for backwards compatibility with 1.0. In protocol 3.0 it has some - * use again, since it ensures that there will be a recognizable end - * to the response to an Execute message. + * This ensures that there will be a recognizable end to the response + * to an Execute message in the extended query protocol. * ---------------- */ void @@ -234,14 +241,8 @@ NullCommand(CommandDest dest) case DestRemoteExecute: case DestRemoteSimple: - /* - * tell the fe that we saw an empty query string. In protocols - * before 3.0 this has a useless empty-string message body. - */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - pq_putemptymessage('I'); - else - pq_putmessage('I', "", 1); + /* Tell the FE that we saw an empty query string */ + pq_putemptymessage('I'); break; case DestNone: @@ -276,7 +277,6 @@ ReadyForQuery(CommandDest dest) case DestRemote: case DestRemoteExecute: case DestRemoteSimple: - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) { StringInfoData buf; @@ -295,8 +295,6 @@ ReadyForQuery(CommandDest dest) pq_sendbyte(&buf, TransactionBlockStatusCode()); pq_endmessage(&buf); } - else - pq_putemptymessage('Z'); /* Flush output at end of cycle in any case. */ pq_flush(); break; diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c index e793984a9f3e..6343dd269b45 100644 --- a/src/backend/tcop/fastpath.c +++ b/src/backend/tcop/fastpath.c @@ -3,7 +3,7 @@ * fastpath.c * routines to handle function requests from the frontend * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -58,98 +58,24 @@ struct fp_info static int16 parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip, FunctionCallInfo fcinfo); -static int16 parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip, - FunctionCallInfo fcinfo); - - -/* ---------------- - * GetOldFunctionMessage - * - * In pre-3.0 protocol, there is no length word on the message, so we have - * to have code that understands the message layout to absorb the message - * into a buffer. We want to do this before we start execution, so that - * we do not lose sync with the frontend if there's an error. - * - * The caller should already have initialized buf to empty. - * ---------------- - */ -int -GetOldFunctionMessage(StringInfo buf) -{ - int32 ibuf; - int nargs; - - /* Dummy string argument */ - if (pq_getstring(buf)) - return EOF; - /* Function OID */ - if (pq_getbytes((char *) &ibuf, 4)) - return EOF; - appendBinaryStringInfo(buf, (char *) &ibuf, 4); - /* Number of arguments */ - if (pq_getbytes((char *) &ibuf, 4)) - return EOF; - appendBinaryStringInfo(buf, (char *) &ibuf, 4); - nargs = pg_ntoh32(ibuf); - /* For each argument ... */ - while (nargs-- > 0) - { - int argsize; - - /* argsize */ - if (pq_getbytes((char *) &ibuf, 4)) - return EOF; - appendBinaryStringInfo(buf, (char *) &ibuf, 4); - argsize = pg_ntoh32(ibuf); - if (argsize < -1) - { - /* FATAL here since no hope of regaining message sync */ - ereport(FATAL, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid argument size %d in function call message", - argsize))); - } - /* and arg contents */ - if (argsize > 0) - { - /* Allocate space for arg */ - enlargeStringInfo(buf, argsize); - /* And grab it */ - if (pq_getbytes(buf->data + buf->len, argsize)) - return EOF; - buf->len += argsize; - /* Place a trailing null per StringInfo convention */ - buf->data[buf->len] = '\0'; - } - } - return 0; -} /* ---------------- * SendFunctionResult - * - * Note: although this routine doesn't check, the format had better be 1 - * (binary) when talking to a pre-3.0 client. * ---------------- */ static void SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format) { - bool newstyle = (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3); StringInfoData buf; pq_beginmessage(&buf, 'V'); if (isnull) { - if (newstyle) - pq_sendint32(&buf, -1); + pq_sendint32(&buf, -1); } else { - if (!newstyle) - pq_sendbyte(&buf, 'G'); - if (format == 0) { Oid typoutput; @@ -180,9 +106,6 @@ SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format) errmsg("unsupported format code: %d", format))); } - if (!newstyle) - pq_sendbyte(&buf, '0'); - pq_endmessage(&buf); } @@ -198,7 +121,6 @@ fetch_fp_info(Oid func_id, struct fp_info *fip) HeapTuple func_htp; Form_pg_proc pp; - Assert(OidIsValid(func_id)); Assert(fip != NULL); /* @@ -212,8 +134,6 @@ fetch_fp_info(Oid func_id, struct fp_info *fip) MemSet(fip, 0, sizeof(struct fp_info)); fip->funcid = InvalidOid; - fmgr_info(func_id, &fip->flinfo); - func_htp = SearchSysCache1(PROCOID, ObjectIdGetDatum(func_id)); if (!HeapTupleIsValid(func_htp)) ereport(ERROR, @@ -221,6 +141,13 @@ fetch_fp_info(Oid func_id, struct fp_info *fip) errmsg("function with OID %u does not exist", func_id))); pp = (Form_pg_proc) GETSTRUCT(func_htp); + /* reject pg_proc entries that are unsafe to call via fastpath */ + if (pp->prokind != PROKIND_FUNCTION || pp->proretset) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot call function \"%s\" via fastpath interface", + NameStr(pp->proname)))); + /* watch out for catalog entries with more than FUNC_MAX_ARGS args */ if (pp->pronargs > FUNC_MAX_ARGS) elog(ERROR, "function %s has more than %d arguments", @@ -233,6 +160,8 @@ fetch_fp_info(Oid func_id, struct fp_info *fip) ReleaseSysCache(func_htp); + fmgr_info(func_id, &fip->flinfo); + /* * This must be last! */ @@ -288,9 +217,6 @@ HandleFunctionRequest(StringInfo msgBuf) /* * Begin parsing the buffer contents. */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - (void) pq_getmsgstring(msgBuf); /* dummy string */ - fid = (Oid) pq_getmsgint(msgBuf, 4); /* function oid */ /* @@ -334,10 +260,7 @@ HandleFunctionRequest(StringInfo msgBuf) */ InitFunctionCallInfoData(*fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL); - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - rformat = parse_fcall_arguments(msgBuf, fip, fcinfo); - else - rformat = parse_fcall_arguments_20(msgBuf, fip, fcinfo); + rformat = parse_fcall_arguments(msgBuf, fip, fcinfo); /* Verify we reached the end of the message where expected. */ pq_getmsgend(msgBuf); @@ -533,81 +456,3 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip, /* Return result format code */ return (int16) pq_getmsgint(msgBuf, 2); } - -/* - * Parse function arguments in a 2.0 protocol message - * - * Argument values are loaded into *fcinfo, and the desired result format - * is returned. - */ -static int16 -parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip, - FunctionCallInfo fcinfo) -{ - int nargs; - int i; - StringInfoData abuf; - - nargs = pq_getmsgint(msgBuf, 4); /* # of arguments */ - - if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS) - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("function call message contains %d arguments but function requires %d", - nargs, fip->flinfo.fn_nargs))); - - fcinfo->nargs = nargs; - - initStringInfo(&abuf); - - /* - * Copy supplied arguments into arg vector. In protocol 2.0 these are - * always assumed to be supplied in binary format. - * - * Note: although the original protocol 2.0 code did not have any way for - * the frontend to specify a NULL argument, we now choose to interpret - * length == -1 as meaning a NULL. - */ - for (i = 0; i < nargs; ++i) - { - int argsize; - Oid typreceive; - Oid typioparam; - - getTypeBinaryInputInfo(fip->argtypes[i], &typreceive, &typioparam); - - argsize = pq_getmsgint(msgBuf, 4); - if (argsize == -1) - { - fcinfo->args[i].isnull = true; - fcinfo->args[i].value = OidReceiveFunctionCall(typreceive, NULL, - typioparam, -1); - continue; - } - fcinfo->args[i].isnull = false; - if (argsize < 0) - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid argument size %d in function call message", - argsize))); - - /* Reset abuf to empty, and insert raw data into it */ - resetStringInfo(&abuf); - appendBinaryStringInfo(&abuf, - pq_getmsgbytes(msgBuf, argsize), - argsize); - - fcinfo->args[i].value = OidReceiveFunctionCall(typreceive, &abuf, - typioparam, -1); - - /* Trouble if it didn't eat the whole buffer */ - if (abuf.cursor != abuf.len) - ereport(ERROR, - (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), - errmsg("incorrect binary data format in function argument %d", - i + 1))); - } - - /* Desired result format is always binary in protocol 2.0 */ - return 1; -} diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index aac611af5c2e..ca43eeafb4c3 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -3,7 +3,7 @@ * postgres.c * POSTGRES C Backend Interface * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -73,6 +73,7 @@ #include "rewrite/rewriteHandler.h" #include "storage/bufmgr.h" #include "storage/ipc.h" +#include "storage/pmsignal.h" #include "storage/proc.h" #include "storage/procsignal.h" #include "storage/sinval.h" @@ -128,8 +129,20 @@ int max_stack_depth = 100; int PostAuthDelay = 0; /* Time between checks that the client is still connected. */ -int client_connection_check_interval = 0; +int client_connection_check_interval = 0; +/* ---------------- + * private typedefs etc + * ---------------- + */ + +/* type of argument for bind_param_error_callback */ +typedef struct BindParamCbData +{ + const char *portalName; + int paramno; /* zero-based param number, or -1 initially */ + const char *paramval; /* textual input string, if available */ +} BindParamCbData; /* * Hook for extensions, to get notified when query cancel or DIE signal is @@ -235,12 +248,13 @@ static int InteractiveBackend(StringInfo inBuf); static int interactive_getc(void); static int SocketBackend(StringInfo inBuf); static int ReadCommand(StringInfo inBuf); -static void forbidden_in_wal_sender(int firstchar); +static void forbidden_in_wal_sender(char firstchar); static bool check_log_statement(List *stmt_list); static int errdetail_execute(List *raw_parsetree_list); static int errdetail_params(ParamListInfo params); static int errdetail_abort(void); static int errdetail_recovery_conflict(void); +static void bind_param_error_callback(void *arg); static void start_xact_command(void); static void finish_xact_command(void); static bool IsTransactionExitStmt(Node *parsetree); @@ -428,6 +442,7 @@ static int SocketBackend(StringInfo inBuf) { int qtype; + int maxmsglen = 0; /* * Get message type code from the frontend. @@ -452,7 +467,7 @@ SocketBackend(StringInfo inBuf) whereToSendOutput = DestNone; ereport(DEBUG1, (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), - errmsg("unexpected EOF on client connection"))); + errmsg_internal("unexpected EOF on client connection"))); } return qtype; } @@ -460,7 +475,9 @@ SocketBackend(StringInfo inBuf) /* * Validate message type code before trying to read body; if we have lost * sync, better to say "command unknown" than to run out of memory because - * we used garbage as a length word. + * we used garbage as a length word. We can also select a type-dependent + * limit on what a sane length word could be. (The limit could be chosen + * more granularly, but it's not clear it's worth fussing over.) * * This also gives us a place to set the doing_extended_query_message flag * as soon as possible. @@ -468,35 +485,17 @@ SocketBackend(StringInfo inBuf) switch (qtype) { case 'Q': /* simple query */ + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = false; - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - { - /* old style without length word; convert */ - if (pq_getstring(inBuf)) - { - if (IsTransactionState()) - ereport(COMMERROR, - (errcode(ERRCODE_CONNECTION_FAILURE), - errmsg("unexpected EOF on client connection with an open transaction"))); - else - { - /* - * Can't send DEBUG log messages to client at this - * point. Since we're disconnecting right away, we - * don't need to restore whereToSendOutput. - */ - whereToSendOutput = DestNone; - ereport(DEBUG1, - (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), - errmsg("unexpected EOF on client connection"))); - } - return EOF; - } - } break; case 'M': /* Greenplum Database dispatched statement from QD */ + /* The dispatched 'M' message carries the serialized plan/query + * and can be large, like 'Q'. Without this PG14 added a default + * maxmsglen of 0, so pq_getmessage rejected every dispatch with + * "invalid message length". */ + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = false; /* don't support old protocols with this. */ @@ -510,6 +509,7 @@ SocketBackend(StringInfo inBuf) case 'T': /* Greenplum Database dispatched transaction protocol from QD */ + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = false; /* don't support old protocols with this. */ @@ -522,73 +522,48 @@ SocketBackend(StringInfo inBuf) break; case 'F': /* fastpath function call */ + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; doing_extended_query_message = false; - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - { - if (GetOldFunctionMessage(inBuf)) - { - if (IsTransactionState()) - ereport(COMMERROR, - (errcode(ERRCODE_CONNECTION_FAILURE), - errmsg("unexpected EOF on client connection with an open transaction"))); - else - { - /* - * Can't send DEBUG log messages to client at this - * point. Since we're disconnecting right away, we - * don't need to restore whereToSendOutput. - */ - whereToSendOutput = DestNone; - ereport(DEBUG1, - (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST), - errmsg("unexpected EOF on client connection"))); - } - return EOF; - } - } break; case 'X': /* terminate */ + maxmsglen = PQ_SMALL_MESSAGE_LIMIT; doing_extended_query_message = false; ignore_till_sync = false; break; case 'B': /* bind */ + case 'P': /* parse */ + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; + doing_extended_query_message = true; + break; + case 'C': /* close */ case 'D': /* describe */ case 'E': /* execute */ case 'H': /* flush */ - case 'P': /* parse */ + maxmsglen = PQ_SMALL_MESSAGE_LIMIT; doing_extended_query_message = true; - /* these are only legal in protocol 3 */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - ereport(FATAL, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid frontend message type %d", qtype))); break; case 'S': /* sync */ + maxmsglen = PQ_SMALL_MESSAGE_LIMIT; /* stop any active skip-till-Sync */ ignore_till_sync = false; /* mark not-extended, so that a new error doesn't begin skip */ doing_extended_query_message = false; - /* only legal in protocol 3 */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - ereport(FATAL, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid frontend message type %d", qtype))); break; case 'd': /* copy data */ + maxmsglen = PQ_LARGE_MESSAGE_LIMIT; + doing_extended_query_message = false; + break; + case 'c': /* copy done */ case 'f': /* copy fail */ case '?': /* Greenplum sequence response */ + maxmsglen = PQ_SMALL_MESSAGE_LIMIT; doing_extended_query_message = false; - /* these are only legal in protocol 3 */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) - ereport(FATAL, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("invalid frontend message type %d", qtype))); break; default: @@ -601,6 +576,7 @@ SocketBackend(StringInfo inBuf) ereport(FATAL, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("invalid frontend message type %d", qtype))); + maxmsglen = 0; /* keep compiler quiet */ break; } @@ -609,13 +585,8 @@ SocketBackend(StringInfo inBuf) * after the type code; we can read the message contents independently of * the type. */ - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - { - if (pq_getmessage(inBuf, 0)) - return EOF; /* suitable message already logged */ - } - else - pq_endmsgread(); + if (pq_getmessage(inBuf, maxmsglen)) + return EOF; /* suitable message already logged */ RESUME_CANCEL_INTERRUPTS(); return qtype; @@ -726,7 +697,7 @@ ProcessClientWriteInterrupt(bool blocked) { /* * Don't mess with whereToSendOutput if ProcessInterrupts wouldn't - * do anything. + * service ProcDiePending. */ if (InterruptHoldoffCount == 0 && CritSectionCount == 0) { @@ -772,7 +743,7 @@ pg_parse_query(const char *query_string) if (log_parser_stats) ResetUsage(); - raw_parsetree_list = raw_parser(query_string); + raw_parsetree_list = raw_parser(query_string, RAW_PARSE_DEFAULT); if (log_parser_stats) ShowUsage("PARSER STATISTICS"); @@ -857,6 +828,7 @@ pg_analyze_and_rewrite_params(RawStmt *parsetree, ParseState *pstate; Query *query; List *querytree_list; + JumbleState *jstate = NULL; Assert(query_string != NULL); /* required as of 8.4 */ @@ -875,11 +847,16 @@ pg_analyze_and_rewrite_params(RawStmt *parsetree, query = transformTopLevelStmt(pstate, parsetree); + if (IsQueryIdEnabled()) + jstate = JumbleQuery(query, query_string); + if (post_parse_analyze_hook) - (*post_parse_analyze_hook) (pstate, query); + (*post_parse_analyze_hook) (pstate, query, jstate); free_parsestate(pstate); + pgstat_report_query_id(query->queryId, false); + if (log_parser_stats) ShowUsage("PARSE ANALYSIS STATISTICS"); @@ -1098,6 +1075,7 @@ pg_plan_queries(List *querytrees, const char *query_string, int cursorOptions, stmt->utilityStmt = query->utilityStmt; stmt->stmt_location = query->stmt_location; stmt->stmt_len = query->stmt_len; + stmt->queryId = query->queryId; } else { @@ -1761,6 +1739,8 @@ exec_simple_query(const char *query_string) DestReceiver *receiver; int16 format; + pgstat_report_query_id(0, true); + /* * Get the command name for use in status display (it also becomes the * default completion tag, down inside PortalRun). Set ps_status and @@ -2091,9 +2071,9 @@ exec_parse_message(const char *query_string, /* string to execute */ ResetUsage(); ereport(DEBUG2, - (errmsg("parse %s: %s", - *stmt_name ? stmt_name : "", - query_string))); + (errmsg_internal("parse %s: %s", + *stmt_name ? stmt_name : "", + query_string))); /* * Start up a transaction command so we can run parse analysis etc. (Note @@ -2371,9 +2351,9 @@ exec_bind_message(StringInfo input_message) elog((Debug_print_full_dtm ? LOG : DEBUG5), "Bind: portal %s stmt_name %s", portal_name, stmt_name); ereport(DEBUG2, - (errmsg("bind %s to %s", - *portal_name ? portal_name : "", - *stmt_name ? stmt_name : ""))); + (errmsg_internal("bind %s to %s", + *portal_name ? portal_name : "", + *stmt_name ? stmt_name : ""))); /* Find prepared statement */ if (stmt_name[0] != '\0') @@ -2507,6 +2487,19 @@ exec_bind_message(StringInfo input_message) if (numParams > 0) { char **knownTextValues = NULL; /* allocate on first use */ + BindParamCbData one_param_data; + + /* + * Set up an error callback so that if there's an error in this phase, + * we can report the specific parameter causing the problem. + */ + one_param_data.portalName = portal->name; + one_param_data.paramno = -1; + one_param_data.paramval = NULL; + params_errcxt.previous = error_context_stack; + params_errcxt.callback = bind_param_error_callback; + params_errcxt.arg = (void *) &one_param_data; + error_context_stack = ¶ms_errcxt; params = makeParamList(numParams); @@ -2520,6 +2513,9 @@ exec_bind_message(StringInfo input_message) char csave; int16 pformat; + one_param_data.paramno = paramno; + one_param_data.paramval = NULL; + plength = pq_getmsgint(input_message, 4); isNull = (plength == -1); @@ -2573,8 +2569,13 @@ exec_bind_message(StringInfo input_message) else pstring = pg_client_to_server(pbuf.data, plength); + /* Now we can log the input string in case of error */ + one_param_data.paramval = pstring; + pval = OidInputFunctionCall(typinput, pstring, typioparam, -1); + one_param_data.paramval = NULL; + /* * If we might need to log parameters later, save a copy of * the converted string in MessageContext; then free the @@ -2664,10 +2665,13 @@ exec_bind_message(StringInfo input_message) params->params[paramno].ptype = ptype; } + /* Pop the per-parameter error callback */ + error_context_stack = error_context_stack->previous; + /* * Once all parameters have been received, prepare for printing them - * in errors, if configured to do so. (This is saved in the portal, - * so that they'll appear when the query is executed later.) + * in future errors, if configured to do so. (This is saved in the + * portal, so that they'll appear when the query is executed later.) */ if (log_parameter_max_length_on_error != 0) params->paramValuesStr = @@ -2681,7 +2685,10 @@ exec_bind_message(StringInfo input_message) /* Done storing stuff in portal's context */ MemoryContextSwitchTo(oldContext); - /* Set the error callback so that parameters are logged, as needed */ + /* + * Set up another error callback so that all the parameters are logged if + * we get an error during the rest of the BIND processing. + */ params_data.portalName = portal->name; params_data.params = params; params_errcxt.previous = error_context_stack; @@ -2705,7 +2712,7 @@ exec_bind_message(StringInfo input_message) * will be generated in MessageContext. The plan refcount will be * assigned to the Portal, so it will be released at portal destruction. */ - cplan = GetCachedPlan(psrc, params, false, NULL, NULL); + cplan = GetCachedPlan(psrc, params, NULL, NULL, NULL); /* * Now we can define the portal. @@ -3246,6 +3253,55 @@ errdetail_recovery_conflict(void) return 0; } +/* + * bind_param_error_callback + * + * Error context callback used while parsing parameters in a Bind message + */ +static void +bind_param_error_callback(void *arg) +{ + BindParamCbData *data = (BindParamCbData *) arg; + StringInfoData buf; + char *quotedval; + + if (data->paramno < 0) + return; + + /* If we have a textual value, quote it, and trim if necessary */ + if (data->paramval) + { + initStringInfo(&buf); + appendStringInfoStringQuoted(&buf, data->paramval, + log_parameter_max_length_on_error); + quotedval = buf.data; + } + else + quotedval = NULL; + + if (data->portalName && data->portalName[0] != '\0') + { + if (quotedval) + errcontext("portal \"%s\" parameter $%d = %s", + data->portalName, data->paramno + 1, quotedval); + else + errcontext("portal \"%s\" parameter $%d", + data->portalName, data->paramno + 1); + } + else + { + if (quotedval) + errcontext("unnamed portal parameter $%d = %s", + data->paramno + 1, quotedval); + else + errcontext("unnamed portal parameter $%d", + data->paramno + 1); + } + + if (quotedval) + pfree(quotedval); +} + /* * exec_describe_statement_message * @@ -3540,6 +3596,8 @@ drop_unnamed_stmt(void) * * * @param SIGNAL_ARGS -- so the signature matches a signal handler. Nore that + * Either some backend has bought the farm, or we've been told to shut down + * "immediately"; so we need to stop what we're doing and exit. */ void quickdie(SIGNAL_ARGS) @@ -3576,18 +3634,48 @@ quickdie(SIGNAL_ARGS) * wrong, so there's not much to lose. Assuming the postmaster is still * running, it will SIGKILL us soon if we get stuck for some reason. * - * Ideally this should be ereport(FATAL), but then we'd not get control - * back... + * One thing we can do to make this a tad safer is to clear the error + * context stack, so that context callbacks are not called. That's a lot + * less code that could be reached here, and the context info is unlikely + * to be very relevant to a SIGQUIT report anyway. + */ + error_context_stack = NULL; + + /* + * When responding to a postmaster-issued signal, we send the message only + * to the client; sending to the server log just creates log spam, plus + * it's more code that we need to hope will work in a signal handler. + * + * Ideally these should be ereport(FATAL), but then we'd not get control + * back to force the correct type of process exit. */ - ereport(WARNING, - (errcode(ERRCODE_CRASH_SHUTDOWN), - errmsg("terminating connection because of crash of another server process"), - errdetail("The postmaster has commanded this server process to roll back" - " the current transaction and exit, because another" - " server process exited abnormally and possibly corrupted" - " shared memory."), - errhint("In a moment you should be able to reconnect to the" - " database and repeat your command."))); + switch (GetQuitSignalReason()) + { + case PMQUIT_NOT_SENT: + /* Hmm, SIGQUIT arrived out of the blue */ + ereport(WARNING, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating connection because of unexpected SIGQUIT signal"))); + break; + case PMQUIT_FOR_CRASH: + /* A crash-and-restart cycle is in progress */ + ereport(WARNING_CLIENT_ONLY, + (errcode(ERRCODE_CRASH_SHUTDOWN), + errmsg("terminating connection because of crash of another server process"), + errdetail("The postmaster has commanded this server process to roll back" + " the current transaction and exit, because another" + " server process exited abnormally and possibly corrupted" + " shared memory."), + errhint("In a moment you should be able to reconnect to the" + " database and repeat your command."))); + break; + case PMQUIT_FOR_STOP: + /* Immediate-mode stop */ + ereport(WARNING_CLIENT_ONLY, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating connection due to immediate shutdown command"))); + break; + } /* * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here @@ -3622,6 +3710,9 @@ die(SIGNAL_ARGS) ProcDiePending = true; } + /* for the statistics collector */ + pgStatSessionEndCause = DISCONNECT_KILLED; + /* If we're still here, waken anything waiting on the process latch */ SetLatch(MyLatch); @@ -3761,11 +3852,23 @@ RecoveryConflictInterrupt(ProcSignalReason reason) case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN: /* - * If we aren't blocking the Startup process there is nothing - * more to do. + * If PROCSIG_RECOVERY_CONFLICT_BUFFERPIN is requested but we + * aren't blocking the Startup process there is nothing more + * to do. + * + * When PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK is + * requested, if we're waiting for locks and the startup + * process is not waiting for buffer pin (i.e., also waiting + * for locks), we set the flag so that ProcSleep() will check + * for deadlocks. */ if (!HoldingBufferPinThatDelaysRecovery()) + { + if (reason == PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK && + GetStartupBufferPinWaitBufId() < 0) + CheckDeadLockAlert(); return; + } MyProc->recoveryConflictPending = true; @@ -3859,6 +3962,11 @@ RecoveryConflictInterrupt(ProcSignalReason reason) * * Parameters filename and lineno contain the file name and the line number where * ProcessInterrupts was invoked, respectively. + * Note: if INTERRUPTS_CAN_BE_PROCESSED() is true, then ProcessInterrupts + * is guaranteed to clear the InterruptPending flag before returning. + * (This is not the same as guaranteeing that it's still clear when we + * return; another interrupt could have arrived. But we promise that + * any pre-existing one will have been serviced.) */ void ProcessInterrupts(const char* filename, int lineno) @@ -3891,7 +3999,7 @@ ProcessInterrupts(const char* filename, int lineno) else if (IsLogicalLauncher()) { ereport(DEBUG1, - (errmsg("logical replication launcher shutting down"))); + (errmsg_internal("logical replication launcher shutting down"))); /* * The logical replication launcher can be stopped at any time. @@ -3917,6 +4025,11 @@ ProcessInterrupts(const char* filename, int lineno) errmsg("terminating connection due to conflict with recovery"), errdetail_recovery_conflict())); } + else if (IsBackgroundWorker) + ereport(FATAL, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating background worker \"%s\" due to administrator command", + MyBgworkerEntry->bgw_type))); else { if (HasCancelMessage()) @@ -3997,7 +4110,11 @@ ProcessInterrupts(const char* filename, int lineno) { /* * Re-arm InterruptPending so that we process the cancel request as - * soon as we're done reading the message. + * soon as we're done reading the message. (XXX this is seriously + * ugly: it complicates INTERRUPTS_CAN_BE_PROCESSED(), and it means we + * can't use that macro directly as the initial test in this function, + * meaning that this code also creates opportunities for other bugs to + * appear.) */ InterruptPending = true; } @@ -4115,11 +4232,25 @@ ProcessInterrupts(const char* filename, int lineno) IdleGangTimeoutPending = false; } + if (IdleSessionTimeoutPending) + { + /* As above, ignore the signal if the GUC has been reset to zero. */ + if (IdleSessionTimeout > 0) + ereport(FATAL, + (errcode(ERRCODE_IDLE_SESSION_TIMEOUT), + errmsg("terminating connection due to idle-session timeout"))); + else + IdleSessionTimeoutPending = false; + } + if (ProcSignalBarrierPending) ProcessProcSignalBarrier(); if (ParallelMessagePending) HandleParallelMessages(); + + if (LogMemoryContextPending) + ProcessLogMemoryContextInterrupt(); } /* @@ -4463,7 +4594,7 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, * postmaster/postmaster.c (the option sets should not conflict) and with * the common help() function in main/main.c. */ - while ((flag = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lMm:N:nOo:Pp:r:S:sTt:v:W:-:")) != -1) + while ((flag = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lMmN:nOPp:r:S:sTt:v:W:-:")) != -1) { switch (flag) { @@ -4564,10 +4695,6 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx, SetConfigOption("allow_system_table_mods", "true", ctx, gucsource); break; - case 'o': - errs++; - break; - case 'P': SetConfigOption("ignore_system_indexes", "true", ctx, gucsource); break; @@ -4760,6 +4887,7 @@ PostgresMain(int argc, char *argv[], * Save our main thread-id for comparison during signals. */ main_tid = pthread_self(); + bool idle_session_timeout_enabled = false; /* Initialize startup process environment if necessary. */ if (!IsUnderPostmaster) @@ -4811,7 +4939,8 @@ PostgresMain(int argc, char *argv[], } /* - * Set up signal handlers and masks. + * Set up signal handlers. (InitPostmasterChild or InitStandaloneProcess + * has already set up BlockSig and made that the active signal mask.) * * Note that postmaster blocked all signals before forking child process, * so there is no race condition whereby we might receive a signal before @@ -4833,6 +4962,9 @@ PostgresMain(int argc, char *argv[], pqsignal(SIGTERM, die); /* cancel current query and exit */ /* + * In a postmaster child backend, replace SignalHandlerForCrashExit + * with quickdie, so we can tell the client we're dying. + * * In a standalone backend, SIGQUIT can be generated from the keyboard * easily, while SIGTERM cannot, so we make both signals do die() * rather than quickdie(). @@ -4873,16 +5005,6 @@ PostgresMain(int argc, char *argv[], #endif } - pqinitmask(); - - if (IsUnderPostmaster) - { - /* We allow SIGQUIT (quickdie) at all times */ - sigdelset(&BlockSig, SIGQUIT); - } - - PG_SETMASK(&BlockSig); /* block everything except SIGQUIT */ - if (!IsUnderPostmaster) { /* @@ -5290,6 +5412,14 @@ PostgresMain(int argc, char *argv[], strncat(activity, "idle", remain); set_ps_display(activity); pgstat_report_activity(STATE_IDLE, NULL); + + /* Start the idle-session timer */ + if (IdleSessionTimeout > 0) + { + idle_session_timeout_enabled = true; + enable_timeout_after(IDLE_SESSION_TIMEOUT, + IdleSessionTimeout); + } } /* Start the idle-gang timer */ @@ -5299,6 +5429,8 @@ PostgresMain(int argc, char *argv[], enable_timeout_after(IDLE_GANG_TIMEOUT, IdleSessionGangTimeout); } + /* Report any recently-changed GUC options */ + ReportChangedGUCOptions(); ReadyForQuery(whereToSendOutput); send_ready_for_query = false; @@ -5335,6 +5467,26 @@ PostgresMain(int argc, char *argv[], /* * (4) disable async signal conditions again. + * (4) turn off the idle-in-transaction and idle-session timeouts, if + * active. We do this before step (5) so that any last-moment timeout + * is certain to be detected in step (5). + * + * At most one of these timeouts will be active, so there's no need to + * worry about combining the timeout.c calls into one. + */ + if (idle_in_transaction_timeout_enabled) + { + disable_timeout(IDLE_IN_TRANSACTION_SESSION_TIMEOUT, false); + idle_in_transaction_timeout_enabled = false; + } + if (idle_session_timeout_enabled) + { + disable_timeout(IDLE_SESSION_TIMEOUT, false); + idle_session_timeout_enabled = false; + } + + /* + * (5) disable async signal conditions again. * * Query cancel is supposed to be a no-op when there is no query in * progress, so if a query cancel arrived while we were idle, just @@ -5845,9 +5997,15 @@ PostgresMain(int argc, char *argv[], * means unexpected loss of frontend connection. Either way, * perform normal shutdown. */ - case 'X': case EOF: + /* for the statistics collector */ + pgStatSessionEndCause = DISCONNECT_CLIENT_EOF; + + /* FALLTHROUGH */ + + case 'X': + /* * Reset whereToSendOutput to prevent ereport from attempting * to send any more messages to client. @@ -5904,7 +6062,7 @@ PostgresMain(int argc, char *argv[], * message was received, and is used to construct the error message. */ static void -forbidden_in_wal_sender(int firstchar) +forbidden_in_wal_sender(char firstchar) { if (am_walsender) { diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index bb9cd05fa71b..839f2e9dcbcf 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -597,6 +597,13 @@ PortalStart(Portal portal, ParamListInfo params, else PushActiveSnapshot(GetTransactionSnapshot()); + /* + * We could remember the snapshot in portal->portalSnapshot, + * but presently there seems no need to, as this code path + * cannot be used for non-atomic execution. Hence there can't + * be any commit/abort that might destroy the snapshot. + */ + /* * Create QueryDesc in portal's context; for the moment, set * the destination to DestNone. @@ -1296,52 +1303,34 @@ PortalRunUtility(Portal portal, PlannedStmt *pstmt, bool isTopLevel, bool setHoldSnapshot, DestReceiver *dest, QueryCompletion *qc) { - Node *utilityStmt = pstmt->utilityStmt; - Snapshot snapshot; - /* - * Set snapshot if utility stmt needs one. Most reliable way to do this - * seems to be to enumerate those that do not need one; this is a short - * list. Transaction control, LOCK, and SET must *not* set a snapshot - * since they need to be executable at the start of a transaction-snapshot - * mode transaction without freezing a snapshot. By extension we allow - * SHOW not to set a snapshot. The other stmts listed are just efficiency - * hacks. Beware of listing anything that can modify the database --- if, - * say, it has to update an index with expressions that invoke - * user-defined functions, then it had better have a snapshot. + * Set snapshot if utility stmt needs one. */ - if (!(IsA(utilityStmt, TransactionStmt) || - IsA(utilityStmt, LockStmt) || - IsA(utilityStmt, VariableSetStmt) || - IsA(utilityStmt, VariableShowStmt) || - IsA(utilityStmt, ConstraintsSetStmt) || - /* efficiency hacks from here down */ - IsA(utilityStmt, FetchStmt) || - IsA(utilityStmt, ListenStmt) || - IsA(utilityStmt, NotifyStmt) || - IsA(utilityStmt, UnlistenStmt) || - IsA(utilityStmt, CheckPointStmt))) + if (PlannedStmtRequiresSnapshot(pstmt)) { - snapshot = GetTransactionSnapshot(); + Snapshot snapshot = GetTransactionSnapshot(); + /* If told to, register the snapshot we're using and save in portal */ if (setHoldSnapshot) { snapshot = RegisterSnapshot(snapshot); portal->holdSnapshot = snapshot; } + /* In any case, make the snapshot active and remember it in portal */ PushActiveSnapshot(snapshot); /* PushActiveSnapshot might have copied the snapshot */ - snapshot = GetActiveSnapshot(); + portal->portalSnapshot = GetActiveSnapshot(); } else - snapshot = NULL; + portal->portalSnapshot = NULL; /* check if this utility statement need to be involved into resource queue * mgmt */ - ResHandleUtilityStmt(portal, utilityStmt); + ResHandleUtilityStmt(portal, pstmt->utilityStmt); ProcessUtility(pstmt, - portal->sourceText ? portal->sourceText : "(Source text for portal is not available)", + portal->sourceText, + (portal->cplan != NULL), /* protect tree if in plancache */ isTopLevel ? PROCESS_UTILITY_TOPLEVEL : PROCESS_UTILITY_QUERY, portal->portalParams, portal->queryEnv, @@ -1352,13 +1341,17 @@ PortalRunUtility(Portal portal, PlannedStmt *pstmt, MemoryContextSwitchTo(portal->portalContext); /* - * Some utility commands may pop the ActiveSnapshot stack from under us, - * so be careful to only pop the stack if our snapshot is still at the - * top. + * Some utility commands (e.g., VACUUM) pop the ActiveSnapshot stack from + * under us, so don't complain if it's now empty. Otherwise, our snapshot + * should be the top one; pop it. Note that this could be a different + * snapshot from the one we made above; see EnsurePortalSnapshotExists. */ - if (snapshot != NULL && ActiveSnapshotSet() && - snapshot == GetActiveSnapshot()) + if (portal->portalSnapshot != NULL && ActiveSnapshotSet()) + { + Assert(portal->portalSnapshot == GetActiveSnapshot()); PopActiveSnapshot(); + } + portal->portalSnapshot = NULL; } /* @@ -1440,6 +1433,12 @@ PortalRunMulti(Portal portal, * from what holdSnapshot has.) */ PushCopiedSnapshot(snapshot); + + /* + * As for PORTAL_ONE_SELECT portals, it does not seem + * necessary to maintain portal->portalSnapshot here. + */ + active_snapshot_set = true; } else @@ -1498,19 +1497,30 @@ PortalRunMulti(Portal portal, } } - /* - * Increment command counter between queries, but not after the last - * one. - */ - if (lnext(portal->stmts, stmtlist_item) != NULL) - CommandCounterIncrement(); - /* * Clear subsidiary contexts to recover temporary memory. */ Assert(portal->portalContext == CurrentMemoryContext); MemoryContextDeleteChildren(portal->portalContext); + + /* + * Avoid crashing if portal->stmts has been reset. This can only + * occur if a CALL or DO utility statement executed an internal + * COMMIT/ROLLBACK (cf PortalReleaseCachedPlan). The CALL or DO must + * have been the only statement in the portal, so there's nothing left + * for us to do; but we don't want to dereference a now-dangling list + * pointer. + */ + if (portal->stmts == NIL) + break; + + /* + * Increment command counter between queries, but not after the last + * one. + */ + if (lnext(portal->stmts, stmtlist_item) != NULL) + CommandCounterIncrement(); } /* Pop the snapshot if we pushed one. */ @@ -1924,3 +1934,78 @@ PortalBackoffEntryInit(Portal portal) BackoffBackendEntryInit(gp_session_id, gp_command_count, portal->queueId); } } + +/* + * PlannedStmtRequiresSnapshot - what it says on the tin + */ +bool +PlannedStmtRequiresSnapshot(PlannedStmt *pstmt) +{ + Node *utilityStmt = pstmt->utilityStmt; + + /* If it's not a utility statement, it definitely needs a snapshot */ + if (utilityStmt == NULL) + return true; + + /* + * Most utility statements need a snapshot, and the default presumption + * about new ones should be that they do too. Hence, enumerate those that + * do not need one. + * + * Transaction control, LOCK, and SET must *not* set a snapshot, since + * they need to be executable at the start of a transaction-snapshot-mode + * transaction without freezing a snapshot. By extension we allow SHOW + * not to set a snapshot. The other stmts listed are just efficiency + * hacks. Beware of listing anything that can modify the database --- if, + * say, it has to update an index with expressions that invoke + * user-defined functions, then it had better have a snapshot. + */ + if (IsA(utilityStmt, TransactionStmt) || + IsA(utilityStmt, LockStmt) || + IsA(utilityStmt, VariableSetStmt) || + IsA(utilityStmt, VariableShowStmt) || + IsA(utilityStmt, ConstraintsSetStmt) || + /* efficiency hacks from here down */ + IsA(utilityStmt, FetchStmt) || + IsA(utilityStmt, ListenStmt) || + IsA(utilityStmt, NotifyStmt) || + IsA(utilityStmt, UnlistenStmt) || + IsA(utilityStmt, CheckPointStmt)) + return false; + + return true; +} + +/* + * EnsurePortalSnapshotExists - recreate Portal-level snapshot, if needed + * + * Generally, we will have an active snapshot whenever we are executing + * inside a Portal, unless the Portal's query is one of the utility + * statements exempted from that rule (see PlannedStmtRequiresSnapshot). + * However, procedures and DO blocks can commit or abort the transaction, + * and thereby destroy all snapshots. This function can be called to + * re-establish the Portal-level snapshot when none exists. + */ +void +EnsurePortalSnapshotExists(void) +{ + Portal portal; + + /* + * Nothing to do if a snapshot is set. (We take it on faith that the + * outermost active snapshot belongs to some Portal; or if there is no + * Portal, it's somebody else's responsibility to manage things.) + */ + if (ActiveSnapshotSet()) + return; + + /* Otherwise, we'd better have an active Portal */ + portal = ActivePortal; + Assert(portal != NULL); + Assert(portal->portalSnapshot == NULL); + + /* Create a new snapshot and make it active */ + PushActiveSnapshot(GetTransactionSnapshot()); + /* PushActiveSnapshot might have copied the snapshot */ + portal->portalSnapshot = GetActiveSnapshot(); +} diff --git a/src/backend/tcop/test/postgres_test.c b/src/backend/tcop/test/postgres_test.c index c247eba707f8..512d00d7b9f8 100644 --- a/src/backend/tcop/test/postgres_test.c +++ b/src/backend/tcop/test/postgres_test.c @@ -21,16 +21,18 @@ _errfinish_impl() #include "../postgres.c" #define EXPECT_EREPORT(LOG_LEVEL) \ - expect_value(errstart, elevel, (LOG_LEVEL)); \ - expect_any(errstart, domain); \ if (LOG_LEVEL < ERROR) \ { \ + expect_value(errstart, elevel, (LOG_LEVEL)); \ + expect_any(errstart, domain); \ will_return(errstart, false); \ } \ - else \ - { \ - will_return_with_sideeffect(errstart, false, &_errfinish_impl, NULL); \ - } \ + else \ + { \ + expect_value(errstart_cold, elevel, (LOG_LEVEL)); \ + expect_any(errstart_cold, domain); \ + will_return_with_sideeffect(errstart_cold, false, &_errfinish_impl, NULL); \ + } \ /* List with multiple elements, return FALSE. */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 5e523a465b87..da2f2609576b 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -5,7 +5,7 @@ * commands. At one time acted as an interface between the Lisp and C * systems. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -23,6 +23,7 @@ #include "access/xlog.h" #include "catalog/catalog.h" #include "catalog/gp_partition_template.h" +#include "catalog/index.h" #include "catalog/namespace.h" #include "catalog/partition.h" #include "catalog/pg_inherits.h" @@ -501,6 +502,7 @@ CheckRestrictedOperation(const char *cmdname) * * pstmt: PlannedStmt wrapper for the utility statement * queryString: original source text of command + * readOnlyTree: if true, pstmt's node tree must not be modified * context: identifies source of statement (toplevel client command, * non-toplevel client command, subcommand of a larger utility command) * params: parameters to use during execution @@ -526,6 +528,7 @@ CheckRestrictedOperation(const char *cmdname) void ProcessUtility(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, @@ -543,11 +546,11 @@ ProcessUtility(PlannedStmt *pstmt, * call standard_ProcessUtility(). */ if (ProcessUtility_hook) - (*ProcessUtility_hook) (pstmt, queryString, + (*ProcessUtility_hook) (pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); else - standard_ProcessUtility(pstmt, queryString, + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); } @@ -566,13 +569,14 @@ ProcessUtility(PlannedStmt *pstmt, void standard_ProcessUtility(PlannedStmt *pstmt, const char *queryString, + bool readOnlyTree, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc) { - Node *parsetree = pstmt->utilityStmt; + Node *parsetree; bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL); bool isAtomicContext = (!(context == PROCESS_UTILITY_TOPLEVEL || context == PROCESS_UTILITY_QUERY_NONATOMIC) || IsTransactionBlock()); ParseState *pstate; @@ -581,6 +585,18 @@ standard_ProcessUtility(PlannedStmt *pstmt, /* This can recurse, so check for excessive recursion */ check_stack_depth(); + /* + * If the given node tree is read-only, make a copy to ensure that parse + * transformations don't damage the original tree. This could be + * refactored to avoid making unnecessary copies in more cases, but it's + * not clear that it's worth a great deal of trouble over. Statements + * that are complex enough to be expensive to copy are exactly the ones + * we'd need to copy, so that only marginal savings seem possible. + */ + if (readOnlyTree) + pstmt = copyObject(pstmt); + parsetree = pstmt->utilityStmt; + /* Prohibit read/write commands in read-only states. */ readonly_flags = ClassifyUtilityCommandAsReadOnly(parsetree); if (readonly_flags != COMMAND_IS_STRICTLY_READ_ONLY && @@ -928,7 +944,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, break; case T_ClusterStmt: - cluster((ClusterStmt *) parsetree, isTopLevel); + cluster(pstate, (ClusterStmt *) parsetree, isTopLevel); break; case T_VacuumStmt: @@ -1092,36 +1108,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, PreventInTransactionBlock(isTopLevel, "REINDEX CONCURRENTLY"); - switch (stmt->kind) - { - case REINDEX_OBJECT_INDEX: - ReindexIndex(stmt, isTopLevel); - break; - case REINDEX_OBJECT_TABLE: - ReindexTable(stmt, isTopLevel); - break; - case REINDEX_OBJECT_SCHEMA: - case REINDEX_OBJECT_SYSTEM: - case REINDEX_OBJECT_DATABASE: - - /* - * This cannot run inside a user transaction block; if - * we were inside a transaction, then its commit- and - * start-transaction-command calls would not have the - * intended effect! - */ - if (Gp_role == GP_ROLE_DISPATCH) - PreventInTransactionBlock(isTopLevel, - (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" : - (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" : - "REINDEX DATABASE"); - ReindexMultipleTables(stmt->name, stmt->kind, stmt->options, stmt->concurrent); - break; - default: - elog(ERROR, "unrecognized object type: %d", - (int) stmt->kind); - break; - } + ExecReindex(pstate, stmt, isTopLevel); } break; @@ -1310,8 +1297,8 @@ ProcessUtilitySlow(ParseState *pstate, case T_CreateForeignTableStmt: { List *stmts; - ListCell *l; List *more_stmts = NIL; + RangeVar *table_rv = NULL; /* Run parse analysis ... */ /* @@ -1328,11 +1315,18 @@ ProcessUtilitySlow(ParseState *pstate, stmts = transformCreateStmt((CreateStmt *) parsetree, queryString); - /* ... and do it */ + /* + * ... and do it. We can't use foreach() because we may + * modify the list midway through, so pick off the elements + * one at a time, the hard way. (GPDB: partitions generated + * below are re-fed through "more_stmts" and the label.) + */ process_more_stmts: - foreach(l, stmts) + while (stmts != NIL) { - Node *stmt = (Node *) lfirst(l); + Node *stmt = (Node *) linitial(stmts); + + stmts = list_delete_first(stmts); if (IsA(stmt, CreateStmt)) { @@ -1341,6 +1335,9 @@ ProcessUtilitySlow(ParseState *pstate, Datum toast_options; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; + /* Remember transformed RangeVar for LIKE */ + table_rv = cstmt->relation; + /* * If this T_CreateStmt was dispatched and we're a QE * receiving it, extract the relkind and relstorage from @@ -1400,6 +1397,19 @@ ProcessUtilitySlow(ParseState *pstate, */ CommandCounterIncrement(); + /* + * parse and validate reloptions for the toast + * table + */ + toast_options = transformRelOptions((Datum) 0, + cstmt->options, + "toast", + validnsps, + true, + false); + (void) heap_reloptions(RELKIND_TOASTVALUE, + toast_options, + true); if (relKind != RELKIND_COMPOSITE_TYPE) { /* @@ -1450,21 +1460,39 @@ ProcessUtilitySlow(ParseState *pstate, } else if (IsA(stmt, CreateForeignTableStmt)) { + CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) stmt; + + /* Remember transformed RangeVar for LIKE */ + table_rv = cstmt->base.relation; + /* Create the table itself */ - address = DefineRelation((CreateStmt *) stmt, + address = DefineRelation(&cstmt->base, RELKIND_FOREIGN_TABLE, InvalidOid, NULL, - queryString, - true, - true, + queryString, true, true, NULL); - CreateForeignTable((CreateForeignTableStmt *) stmt, - address.objectId, - false /* skip_permission_checks */); + CreateForeignTable(cstmt, + address.objectId, false); EventTriggerCollectSimpleCommand(address, secondaryObject, stmt); } + else if (IsA(stmt, TableLikeClause)) + { + /* + * Do delayed processing of LIKE options. This + * will result in additional sub-statements for us + * to process. Those should get done before any + * remaining actions, so prepend them to "stmts". + */ + TableLikeClause *like = (TableLikeClause *) stmt; + List *morestmts; + + Assert(table_rv != NULL); + + morestmts = expandTableLikeClause(table_rv, like); + stmts = list_concat(morestmts, stmts); + } else { /* @@ -1483,6 +1511,7 @@ ProcessUtilitySlow(ParseState *pstate, ProcessUtility(wrapper, queryString, + false, PROCESS_UTILITY_SUBCOMMAND, params, NULL, @@ -1491,7 +1520,7 @@ ProcessUtilitySlow(ParseState *pstate, } /* Need CCI between commands */ - if (lnext(stmts, l) != NULL) + if (stmts != NIL) CommandCounterIncrement(); } if (more_stmts) @@ -1514,6 +1543,25 @@ ProcessUtilitySlow(ParseState *pstate, AlterTableStmt *atstmt = (AlterTableStmt *) parsetree; Oid relid; LOCKMODE lockmode; + ListCell *cell; + + /* + * Disallow ALTER TABLE .. DETACH CONCURRENTLY in a + * transaction block or function. (Perhaps it could be + * allowed in a procedure, but don't hold your breath.) + */ + foreach(cell, atstmt->cmds) + { + AlterTableCmd *cmd = (AlterTableCmd *) lfirst(cell); + + /* Disallow DETACH CONCURRENTLY in a transaction block */ + if (cmd->subtype == AT_DetachPartition) + { + if (((PartitionCmd *) cmd->def)->concurrent) + PreventInTransactionBlock(isTopLevel, + "ALTER TABLE ... DETACH CONCURRENTLY"); + } + } /* * Figure out lock mode, and acquire lock. This also does @@ -1732,6 +1780,7 @@ ProcessUtilitySlow(ParseState *pstate, /* Recurse for anything else */ ProcessUtility(wrapper, queryString, + false, PROCESS_UTILITY_SUBCOMMAND, params, NULL, @@ -1747,6 +1796,7 @@ ProcessUtilitySlow(ParseState *pstate, IndexStmt *stmt = (IndexStmt *) parsetree; Oid relid; LOCKMODE lockmode; + bool is_alter_table; if (stmt->concurrent) PreventInTransactionBlock(isTopLevel, @@ -1816,6 +1866,17 @@ ProcessUtilitySlow(ParseState *pstate, list_free(inheritors); } + /* + * If the IndexStmt is already transformed, it must have + * come from generateClonedIndexStmt, which in current + * usage means it came from expandTableLikeClause rather + * than from original parse analysis. And that means we + * must treat it like ALTER TABLE ADD INDEX, not CREATE. + * (This is a bit grotty, but currently it doesn't seem + * worth adding a separate bool field for the purpose.) + */ + is_alter_table = stmt->transformed; + /* Run parse analysis ... */ stmt = transformIndexStmt(relid, stmt, queryString); @@ -1827,13 +1888,34 @@ ProcessUtilitySlow(ParseState *pstate, InvalidOid, /* no predefined OID */ InvalidOid, /* no parent index */ InvalidOid, /* no parent constraint */ - false, /* is_alter_table */ + is_alter_table, true, /* check_rights */ true, /* check_not_in_use */ false, /* skip_build */ false, /* quiet */ false /* is_new_table */); + /* + * GPDB: is_alter_table made DefineIndex() skip the QE + * dispatch on the assumption that an enclosing ALTER + * TABLE will be dispatched as a whole, but a transformed + * IndexStmt here came from expandTableLikeClause() and + * has no such enclosing command. Dispatch it ourselves, + * or the index oids preassigned on the QD are never sent + * ("oids were assigned, but not dispatched to QEs") and + * the LIKE'd index is missing on the segments. + */ + if (Gp_role == GP_ROLE_DISPATCH && is_alter_table) + { + stmt->oldNode = InvalidOid; + CdbDispatchUtilityStatement((Node *) stmt, + DF_CANCEL_ON_ERROR | + DF_WITH_SNAPSHOT | + DF_NEED_TWO_PHASE, + GetAssignedOidsForDispatch(), + NULL); + } + /* * Add the CREATE INDEX node itself to stash right away; * if there were any commands stashed in the ALTER TABLE @@ -1928,7 +2010,17 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreateFunctionStmt: /* CREATE FUNCTION */ - address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree); + + /* + * GPDB: parse analysis of a SQL-standard body (BEGIN + * ATOMIC / RETURN) inside CreateFunction() scribbles on + * the raw sql_body tree. Execute a copy so the original + * statement is dispatched to the QEs unmodified and their + * own parse analysis starts from the raw tree (cf. + * ExecDropStmt's copy-before-execute). + */ + address = CreateFunction(pstate, + copyObject((CreateFunctionStmt *) parsetree)); break; case T_AlterFunctionStmt: /* ALTER FUNCTION */ @@ -2142,7 +2234,8 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_AlterSubscriptionStmt: - address = AlterSubscription((AlterSubscriptionStmt *) parsetree); + address = AlterSubscription((AlterSubscriptionStmt *) parsetree, + isTopLevel); break; case T_DropSubscriptionStmt: @@ -2152,7 +2245,34 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_CreateStatsStmt: - address = CreateStatistics((CreateStatsStmt *) parsetree); + { + Oid relid; + CreateStatsStmt *stmt = (CreateStatsStmt *) parsetree; + RangeVar *rel = (RangeVar *) linitial(stmt->relations); + + if (!IsA(rel, RangeVar)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only a single relation is allowed in CREATE STATISTICS"))); + + /* + * CREATE STATISTICS will influence future execution plans + * but does not interfere with currently executing plans. + * So it should be enough to take ShareUpdateExclusiveLock + * on relation, conflicting with ANALYZE and other DDL + * that sets statistical information, but not with normal + * queries. + * + * XXX RangeVarCallbackOwnsRelation not needed here, to + * keep the same behavior as before. + */ + relid = RangeVarGetRelid(rel, ShareUpdateExclusiveLock, false); + + /* Run parse analysis ... */ + stmt = transformStatsStmt(relid, stmt, queryString); + + address = CreateStatistics(stmt); + } break; case T_AlterStatsStmt: @@ -2233,6 +2353,7 @@ ProcessUtilityForAlterTable(Node *stmt, AlterTableUtilityContext *context) { ProcessUtility(wrapper, context->queryString, + false, PROCESS_UTILITY_SUBCOMMAND, context->params, context->queryEnv, @@ -2702,6 +2823,10 @@ CreateCommandTag(Node *parsetree) tag = CMDTAG_SELECT; break; + case T_PLAssignStmt: + tag = CMDTAG_SELECT; + break; + /* utility statements --- same whether raw or cooked */ case T_TransactionStmt: { @@ -3627,6 +3752,10 @@ GetCommandLogLevel(Node *parsetree) lev = LOGSTMT_ALL; break; + case T_PLAssignStmt: + lev = LOGSTMT_ALL; + break; + /* utility statements --- same whether raw or cooked */ case T_TransactionStmt: lev = LOGSTMT_ALL; diff --git a/src/backend/tsearch/Makefile b/src/backend/tsearch/Makefile index 7c669b1abc97..cdb259eca581 100644 --- a/src/backend/tsearch/Makefile +++ b/src/backend/tsearch/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/tsearch # -# Copyright (c) 2006-2020, PostgreSQL Global Development Group +# Copyright (c) 2006-2021, PostgreSQL Global Development Group # # src/backend/tsearch/Makefile # diff --git a/src/backend/tsearch/dict.c b/src/backend/tsearch/dict.c index 835b6721a9f8..1e1ccdac2908 100644 --- a/src/backend/tsearch/dict.c +++ b/src/backend/tsearch/dict.c @@ -3,7 +3,7 @@ * dict.c * Standard interface to dictionary * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dict_ispell.c b/src/backend/tsearch/dict_ispell.c index ecb15dcffd87..d93f6018cec0 100644 --- a/src/backend/tsearch/dict_ispell.c +++ b/src/backend/tsearch/dict_ispell.c @@ -3,7 +3,7 @@ * dict_ispell.c * Ispell dictionary interface * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dict_simple.c b/src/backend/tsearch/dict_simple.c index 5b74deb02c7d..9cd4b6bae55e 100644 --- a/src/backend/tsearch/dict_simple.c +++ b/src/backend/tsearch/dict_simple.c @@ -3,7 +3,7 @@ * dict_simple.c * Simple dictionary: just lowercase and check for stopword * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dict_synonym.c b/src/backend/tsearch/dict_synonym.c index e732e66dace0..ed885ca5551d 100644 --- a/src/backend/tsearch/dict_synonym.c +++ b/src/backend/tsearch/dict_synonym.c @@ -3,7 +3,7 @@ * dict_synonym.c * Synonym dictionary: replace word by its synonym * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dict_thesaurus.c b/src/backend/tsearch/dict_thesaurus.c index cb0835982d85..a95ed0891dd1 100644 --- a/src/backend/tsearch/dict_thesaurus.c +++ b/src/backend/tsearch/dict_thesaurus.c @@ -3,7 +3,7 @@ * dict_thesaurus.c * Thesaurus dictionary: phrase to phrase substitution * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -286,11 +286,6 @@ thesaurusRead(const char *filename, DictThesaurus *d) (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("unexpected end of line"))); - /* - * Note: currently, tsearch_readline can't return lines exceeding 4KB, - * so overflow of the word counts is impossible. But that may not - * always be true, so let's check. - */ if (nwrd != (uint16) nwrd || posinsubst != (uint16) posinsubst) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), diff --git a/src/backend/tsearch/regis.c b/src/backend/tsearch/regis.c index 2edd4faa8ec0..80017177222d 100644 --- a/src/backend/tsearch/regis.c +++ b/src/backend/tsearch/regis.c @@ -3,7 +3,7 @@ * regis.c * Fast regex subset * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c index 8aab96d3b066..ebc89604ac20 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -3,7 +3,7 @@ * spell.c * Normalizing word with ISpell * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * Ispell dictionary * ----------------- @@ -654,6 +654,17 @@ FindWord(IspellDict *Conf, const char *word, const char *affixflag, int flag) return 0; } +/* + * Context reset/delete callback for a regular expression used in an affix + */ +static void +regex_affix_deletion_callback(void *arg) +{ + aff_regex_struct *pregex = (aff_regex_struct *) arg; + + pg_regfree(&(pregex->regex)); +} + /* * Adds a new affix rule to the Affix field. * @@ -716,6 +727,7 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask, int err; pg_wchar *wmask; char *tmask; + aff_regex_struct *pregex; Affix->issimple = 0; Affix->isregis = 0; @@ -729,18 +741,32 @@ NIAddAffix(IspellDict *Conf, const char *flag, char flagflags, const char *mask, wmask = (pg_wchar *) tmpalloc((masklen + 1) * sizeof(pg_wchar)); wmasklen = pg_mb2wchar_with_len(tmask, wmask, masklen); - err = pg_regcomp(&(Affix->reg.regex), wmask, wmasklen, + /* + * The regex engine stores its stuff using malloc not palloc, so we + * must arrange to explicitly clean up the regex when the dictionary's + * context is cleared. That means the regex_t has to stay in a fixed + * location within the context; we can't keep it directly in the AFFIX + * struct, since we may sort and resize the array of AFFIXes. + */ + Affix->reg.pregex = pregex = palloc(sizeof(aff_regex_struct)); + + err = pg_regcomp(&(pregex->regex), wmask, wmasklen, REG_ADVANCED | REG_NOSUB, DEFAULT_COLLATION_OID); if (err) { char errstr[100]; - pg_regerror(err, &(Affix->reg.regex), errstr, sizeof(errstr)); + pg_regerror(err, &(pregex->regex), errstr, sizeof(errstr)); ereport(ERROR, (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), errmsg("invalid regular expression: %s", errstr))); } + + pregex->mcallback.func = regex_affix_deletion_callback; + pregex->mcallback.arg = (void *) pregex; + MemoryContextRegisterResetCallback(CurrentMemoryContext, + &pregex->mcallback); } Affix->flagflags = flagflags; @@ -1710,7 +1736,7 @@ void NISortDictionary(IspellDict *Conf) { int i; - int naffix = 0; + int naffix; int curaffix; /* compress affixes */ @@ -1994,7 +2020,7 @@ NISortAffixes(IspellDict *Conf) (const unsigned char *) Affix->repl, (ptr - 1)->len)) { - /* leave only unique and minimals suffixes */ + /* leave only unique and minimal suffixes */ ptr->affix = Affix->repl; ptr->len = Affix->replen; ptr->issuffix = issuffix; @@ -2124,7 +2150,6 @@ CheckAffix(const char *word, size_t len, AFFIX *Affix, int flagflags, char *neww } else { - int err; pg_wchar *data; size_t data_len; int newword_len; @@ -2134,7 +2159,8 @@ CheckAffix(const char *word, size_t len, AFFIX *Affix, int flagflags, char *neww data = (pg_wchar *) palloc((newword_len + 1) * sizeof(pg_wchar)); data_len = pg_mb2wchar_with_len(newword, data, newword_len); - if (!(err = pg_regexec(&(Affix->reg.regex), data, data_len, 0, NULL, 0, NULL, 0))) + if (pg_regexec(&(Affix->reg.pregex->regex), data, data_len, + 0, NULL, 0, NULL, 0) == REG_OKAY) { pfree(data); return newword; diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c index e7cd6264db27..f4ddfc01059e 100644 --- a/src/backend/tsearch/to_tsany.c +++ b/src/backend/tsearch/to_tsany.c @@ -3,7 +3,7 @@ * to_tsany.c * to_ts* function definitions * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -20,10 +20,20 @@ #include "utils/jsonfuncs.h" +/* + * Opaque data structure, which is passed by parse_tsquery() to pushval_morph(). + */ typedef struct MorphOpaque { Oid cfg_id; - int qoperator; /* query operator */ + + /* + * Single tsquery morph could be parsed into multiple words. When these + * words reside in adjacent positions, they are connected using this + * operator. Usually, that is OP_PHRASE, which requires word positions of + * a complex morph to exactly match the tsvector. + */ + int qoperator; } MorphOpaque; typedef struct TSVectorBuildState @@ -573,7 +583,14 @@ to_tsquery_byid(PG_FUNCTION_ARGS) MorphOpaque data; data.cfg_id = PG_GETARG_OID(0); - data.qoperator = OP_AND; + + /* + * Passing OP_PHRASE as a qoperator makes tsquery require matching of word + * positions of a complex morph exactly match the tsvector. Also, when + * the complex morphs are connected with OP_PHRASE operator, we connect + * all their words into the OP_PHRASE sequence. + */ + data.qoperator = OP_PHRASE; query = parse_tsquery(text_to_cstring(in), pushval_morph, @@ -603,6 +620,12 @@ plainto_tsquery_byid(PG_FUNCTION_ARGS) MorphOpaque data; data.cfg_id = PG_GETARG_OID(0); + + /* + * parse_tsquery() with P_TSQ_PLAIN flag takes the whole input text as a + * single morph. Passing OP_PHRASE as a qoperator makes tsquery require + * matching of all words independently on their positions. + */ data.qoperator = OP_AND; query = parse_tsquery(text_to_cstring(in), @@ -634,6 +657,12 @@ phraseto_tsquery_byid(PG_FUNCTION_ARGS) MorphOpaque data; data.cfg_id = PG_GETARG_OID(0); + + /* + * parse_tsquery() with P_TSQ_PLAIN flag takes the whole input text as a + * single morph. Passing OP_PHRASE as a qoperator makes tsquery require + * matching of word positions. + */ data.qoperator = OP_PHRASE; query = parse_tsquery(text_to_cstring(in), @@ -665,7 +694,13 @@ websearch_to_tsquery_byid(PG_FUNCTION_ARGS) data.cfg_id = PG_GETARG_OID(0); - data.qoperator = OP_AND; + /* + * Passing OP_PHRASE as a qoperator makes tsquery require matching of word + * positions of a complex morph exactly match the tsvector. Also, when + * the complex morphs are given in quotes, we connect all their words into + * the OP_PHRASE sequence. + */ + data.qoperator = OP_PHRASE; query = parse_tsquery(text_to_cstring(in), pushval_morph, diff --git a/src/backend/tsearch/ts_locale.c b/src/backend/tsearch/ts_locale.c index 4a7fa607ce78..a2dccaa64146 100644 --- a/src/backend/tsearch/ts_locale.c +++ b/src/backend/tsearch/ts_locale.c @@ -3,7 +3,7 @@ * ts_locale.c * locale compatibility layer for tsearch * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -14,6 +14,7 @@ #include "postgres.h" #include "catalog/pg_collation.h" +#include "common/string.h" #include "storage/fd.h" #include "tsearch/ts_locale.h" #include "tsearch/ts_public.h" @@ -139,6 +140,7 @@ tsearch_readline_begin(tsearch_readline_state *stp, return false; stp->filename = filename; stp->lineno = 0; + initStringInfo(&stp->buf); stp->curline = NULL; /* Setup error traceback support for ereport() */ stp->cb.callback = tsearch_readline_callback; @@ -156,13 +158,43 @@ tsearch_readline_begin(tsearch_readline_state *stp, char * tsearch_readline(tsearch_readline_state *stp) { - char *result; + char *recoded; + /* Advance line number to use in error reports */ stp->lineno++; - stp->curline = NULL; - result = t_readline(stp->fp); - stp->curline = result; - return result; + + /* Clear curline, it's no longer relevant */ + if (stp->curline) + { + if (stp->curline != stp->buf.data) + pfree(stp->curline); + stp->curline = NULL; + } + + /* Collect next line, if there is one */ + if (!pg_get_line_buf(stp->fp, &stp->buf)) + return NULL; + + /* Validate the input as UTF-8, then convert to DB encoding if needed */ + recoded = pg_any_to_server(stp->buf.data, stp->buf.len, PG_UTF8); + + /* Save the correctly-encoded string for possible error reports */ + stp->curline = recoded; /* might be equal to buf.data */ + + /* + * We always return a freshly pstrdup'd string. This is clearly necessary + * if pg_any_to_server() returned buf.data, and we need a second copy even + * if encoding conversion did occur. The caller is entitled to pfree the + * returned string at any time, which would leave curline pointing to + * recycled storage, causing problems if an error occurs after that point. + * (It's preferable to return the result of pstrdup instead of the output + * of pg_any_to_server, because the conversion result tends to be + * over-allocated. Since callers might save the result string directly + * into a long-lived dictionary structure, we don't want it to be a larger + * palloc chunk than necessary. We'll reclaim the conversion result on + * the next call.) + */ + return pstrdup(recoded); } /* @@ -171,7 +203,18 @@ tsearch_readline(tsearch_readline_state *stp) void tsearch_readline_end(tsearch_readline_state *stp) { + /* Suppress use of curline in any error reported below */ + if (stp->curline) + { + if (stp->curline != stp->buf.data) + pfree(stp->curline); + stp->curline = NULL; + } + + /* Release other resources */ + pfree(stp->buf.data); FreeFile(stp->fp); + /* Pop the error context stack */ error_context_stack = stp->cb.previous; } @@ -187,8 +230,7 @@ tsearch_readline_callback(void *arg) /* * We can't include the text of the config line for errors that occur - * during t_readline() itself. This is only partly a consequence of our - * arms-length use of that routine: the major cause of such errors is + * during tsearch_readline() itself. The major cause of such errors is * encoding violations, and we daren't try to print error messages * containing badly-encoded data. */ @@ -204,43 +246,6 @@ tsearch_readline_callback(void *arg) } -/* - * Read the next line from a tsearch data file (expected to be in UTF-8), and - * convert it to database encoding if needed. The returned string is palloc'd. - * NULL return means EOF. - * - * Note: direct use of this function is now deprecated. Go through - * tsearch_readline() to provide better error reporting. - */ -char * -t_readline(FILE *fp) -{ - int len; - char *recoded; - char buf[4096]; /* lines must not be longer than this */ - - if (fgets(buf, sizeof(buf), fp) == NULL) - return NULL; - - len = strlen(buf); - - /* Make sure the input is valid UTF-8 */ - (void) pg_verify_mbstr(PG_UTF8, buf, len, false); - - /* And convert */ - recoded = pg_any_to_server(buf, len, PG_UTF8); - if (recoded == buf) - { - /* - * conversion didn't pstrdup, so we must. We can use the length of the - * original string, because no conversion was done. - */ - recoded = pnstrdup(recoded, len); - } - - return recoded; -} - /* * lowerstr --- fold null-terminated string to lower case * diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c index 1c0f94e79759..92d95b4bd497 100644 --- a/src/backend/tsearch/ts_parse.c +++ b/src/backend/tsearch/ts_parse.c @@ -3,7 +3,7 @@ * ts_parse.c * main parse functions for tsearch * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/ts_selfuncs.c b/src/backend/tsearch/ts_selfuncs.c index e74b85a6900b..be2546a86ea4 100644 --- a/src/backend/tsearch/ts_selfuncs.c +++ b/src/backend/tsearch/ts_selfuncs.c @@ -3,7 +3,7 @@ * ts_selfuncs.c * Selectivity estimation functions for text search operators. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/ts_typanalyze.c b/src/backend/tsearch/ts_typanalyze.c index a9973990cce4..1ebba4b3f569 100644 --- a/src/backend/tsearch/ts_typanalyze.c +++ b/src/backend/tsearch/ts_typanalyze.c @@ -3,7 +3,7 @@ * ts_typanalyze.c * functions for gathering statistics from tsvector columns * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -180,7 +180,6 @@ compute_tsvector_stats(VacAttrStats *stats, * worry about overflowing the initial size. Also we don't need to pay any * attention to locking and memory management. */ - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(LexemeHashKey); hash_ctl.entrysize = sizeof(TrackItem); hash_ctl.hash = lexeme_hash; diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c index 3bc6b32095fc..ed16a2e25a2a 100644 --- a/src/backend/tsearch/ts_utils.c +++ b/src/backend/tsearch/ts_utils.c @@ -3,7 +3,7 @@ * ts_utils.c * various support functions * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c index 9c1fc7b10142..71882dced99a 100644 --- a/src/backend/tsearch/wparser.c +++ b/src/backend/tsearch/wparser.c @@ -3,7 +3,7 @@ * wparser.c * Standard interface to word parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/wparser_def.c b/src/backend/tsearch/wparser_def.c index 7b29062a97ea..559dff635588 100644 --- a/src/backend/tsearch/wparser_def.c +++ b/src/backend/tsearch/wparser_def.c @@ -3,7 +3,7 @@ * wparser_def.c * Default text search parser * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/Gen_dummy_probes.pl b/src/backend/utils/Gen_dummy_probes.pl index cb0ad5a75cf5..4852103daf4b 100644 --- a/src/backend/utils/Gen_dummy_probes.pl +++ b/src/backend/utils/Gen_dummy_probes.pl @@ -4,7 +4,7 @@ # Gen_dummy_probes.pl # Perl script that generates probes.h file when dtrace is not available # -# Portions Copyright (c) 2008-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 2008-2021, PostgreSQL Global Development Group # # # IDENTIFICATION @@ -135,6 +135,12 @@ () $CondReg ||= $s; } + # s/$/ do {} while (0)/ + { + $s = s /$/ do {} while (0)/s; + $CondReg ||= $s; + } + # P { if (/^(.*)/) { print $1, "\n"; } diff --git a/src/backend/utils/Gen_dummy_probes.pl.prolog b/src/backend/utils/Gen_dummy_probes.pl.prolog new file mode 100644 index 000000000000..1c8993377d62 --- /dev/null +++ b/src/backend/utils/Gen_dummy_probes.pl.prolog @@ -0,0 +1,19 @@ +#! /usr/bin/perl -w +#------------------------------------------------------------------------- +# +# Gen_dummy_probes.pl +# Perl script that generates probes.h file when dtrace is not available +# +# Portions Copyright (c) 2008-2021, PostgreSQL Global Development Group +# +# +# IDENTIFICATION +# src/backend/utils/Gen_dummy_probes.pl +# +# This program was generated by running perl's s2p over Gen_dummy_probes.sed +# +#------------------------------------------------------------------------- + +# turn off perlcritic for autogenerated code +## no critic + diff --git a/src/backend/utils/Gen_dummy_probes.sed b/src/backend/utils/Gen_dummy_probes.sed index 3c9eac6e4f74..6e29d86afaf6 100644 --- a/src/backend/utils/Gen_dummy_probes.sed +++ b/src/backend/utils/Gen_dummy_probes.sed @@ -1,7 +1,7 @@ #------------------------------------------------------------------------- # sed script to create dummy probes.h file when dtrace is not available # -# Copyright (c) 2008-2020, PostgreSQL Global Development Group +# Copyright (c) 2008-2021, PostgreSQL Global Development Group # # src/backend/utils/Gen_dummy_probes.sed #------------------------------------------------------------------------- @@ -19,5 +19,6 @@ s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6)/ s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7)/ s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8)/ +s/$/ do {} while (0)/ P s/(.*$/_ENABLED() (0)/ diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl index b7c7b4c8fae1..881568defd7e 100644 --- a/src/backend/utils/Gen_fmgrtab.pl +++ b/src/backend/utils/Gen_fmgrtab.pl @@ -5,7 +5,7 @@ # Perl script that generates fmgroids.h, fmgrprotos.h, and fmgrtab.c # from pg_proc.dat # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # @@ -64,22 +64,27 @@ # Collect certain fields from pg_proc.dat. my @fmgr = (); +my %proname_counts; foreach my $row (@{ $catalog_data{pg_proc} }) { my %bki_values = %$row; - # Select out just the rows for internal-language procedures. - next if $bki_values{prolang} ne 'internal'; - push @fmgr, { oid => $bki_values{oid}, + name => $bki_values{proname}, + lang => $bki_values{prolang}, + kind => $bki_values{prokind}, strict => $bki_values{proisstrict}, retset => $bki_values{proretset}, nargs => $bki_values{pronargs}, + args => $bki_values{proargtypes}, prosrc => $bki_values{prosrc}, }; + + # Count so that we can detect overloaded pronames. + $proname_counts{ $bki_values{proname} }++; } # Emit headers for both files @@ -104,7 +109,7 @@ * These macros can be used to avoid a catalog lookup when a specific * fmgr-callable function needs to be referenced. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -122,13 +127,10 @@ /* * Constant macros for the OIDs of entries in pg_proc. * - * NOTE: macros are named after the prosrc value, ie the actual C name - * of the implementing function, not the proname which may be overloaded. - * For example, we want to be able to assign different macro names to both - * char_text() and name_text() even though these both appear with proname - * 'text'. If the same C function appears in more than one pg_proc entry, - * its equivalent macro will be defined with the lowest OID among those - * entries. + * F_XXX macros are named after the proname field; if that is not unique, + * we append the proargtypes field, replacing spaces with underscores. + * For example, we have F_OIDEQ because that proname is unique, but + * F_POW_FLOAT8_FLOAT8 (among others) because that proname is not. */ OFH @@ -138,7 +140,7 @@ * fmgrprotos.h * Prototypes for built-in functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -164,7 +166,7 @@ * fmgrtab.c * The function manager's table of internal functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -186,14 +188,22 @@ TFH -# Emit #define's and extern's -- only one per prosrc value +# Emit fmgroids.h and fmgrprotos.h entries in OID order. my %seenit; foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr) { - next if $seenit{ $s->{prosrc} }; - $seenit{ $s->{prosrc} } = 1; - print $ofh "#define F_" . uc $s->{prosrc} . " $s->{oid}\n"; - print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n"; + my $sqlname = $s->{name}; + $sqlname .= "_" . $s->{args} if ($proname_counts{ $s->{name} } > 1); + $sqlname =~ s/\s+/_/g; + print $ofh "#define F_" . uc $sqlname . " $s->{oid}\n"; + # We want only one extern per internal-language, non-aggregate function + if ( $s->{lang} eq 'internal' + && $s->{kind} ne 'a' + && !$seenit{ $s->{prosrc} }) + { + $seenit{ $s->{prosrc} } = 1; + print $pfh "extern Datum $s->{prosrc}(PG_FUNCTION_ARGS);\n"; + } } # Create the fmgr_builtins table, collect data for fmgr_builtin_oid_index @@ -206,22 +216,18 @@ my $fmgr_count = 0; foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr) { + next if $s->{lang} ne 'internal'; + # We do not need entries for aggregate functions + next if $s->{kind} eq 'a'; + + print $tfh ",\n" if ($fmgr_count > 0); print $tfh " { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }"; $fmgr_builtin_oid_index[ $s->{oid} ] = $fmgr_count++; $last_builtin_oid = $s->{oid}; - - if ($fmgr_count <= $#fmgr) - { - print $tfh ",\n"; - } - else - { - print $tfh "\n"; - } } -print $tfh "};\n"; +print $tfh "\n};\n"; printf $tfh qq| const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)); diff --git a/src/backend/utils/Makefile b/src/backend/utils/Makefile index e4915439e6aa..2922fa5dbd87 100644 --- a/src/backend/utils/Makefile +++ b/src/backend/utils/Makefile @@ -14,7 +14,7 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global OBJS = fmgrtab.o session_state.o -SUBDIRS = adt cache datumstream error fmgr gdd hash init mb misc mmgr resowner \ +SUBDIRS = activity adt cache datumstream error fmgr gdd hash init mb misc mmgr resowner \ resgroup resscheduler sort time gp workfile_manager resource_manager hyperloglog # location of Catalog.pm diff --git a/src/backend/utils/README.Gen_dummy_probes b/src/backend/utils/README.Gen_dummy_probes new file mode 100644 index 000000000000..e17060ef2480 --- /dev/null +++ b/src/backend/utils/README.Gen_dummy_probes @@ -0,0 +1,27 @@ +# Generating dummy probes + +If Postgres isn't configured with dtrace enabled, we need to generate +dummy probes for the entries in probes.d, that do nothing. + +This is accomplished in Unix via the sed script `Gen_dummy_probes.sed`. We +used to use this in MSVC builds using the perl utility `psed`, which mimicked +sed. However, that utility disappeared from Windows perl distributions and so +we converted the sed script to a perl script to be used in MSVC builds. + +We still keep the sed script as the authoritative source for generating +these dummy probes because except on Windows perl is not a hard requirement +when building from a tarball. + +So, if you need to change the way dummy probes are generated, first change +the sed script, and when it's working generate the perl script. This can +be accomplished by using the perl utility s2p. + +s2p is no longer part of the perl core, so it might not be on your system, +but it is available on CPAN and also in many package systems. e.g. +on Fedora it can be installed using `cpan App::s2p` or +`dnf install perl-App-s2p`. + +The Makefile contains a recipe for regenerating Gen_dummy_probes.pl, so all +you need to do is once you have s2p installed is `make Gen_dummy_probes.pl` +Note that in a VPATH build this will generate the file in the vpath tree, +not the source tree. diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile new file mode 100644 index 000000000000..59196f278d87 --- /dev/null +++ b/src/backend/utils/activity/Makefile @@ -0,0 +1,21 @@ +#------------------------------------------------------------------------- +# +# Makefile for backend/utils/activity +# +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/backend/utils/activity/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/backend/utils/activity +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global + +OBJS = \ + backend_progress.o \ + backend_status.o \ + wait_event.o + +include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/utils/activity/backend_progress.c b/src/backend/utils/activity/backend_progress.c new file mode 100644 index 000000000000..6743e68cef69 --- /dev/null +++ b/src/backend/utils/activity/backend_progress.c @@ -0,0 +1,112 @@ +/* ---------- + * progress.c + * + * Command progress reporting infrastructure. + * + * Copyright (c) 2001-2021, PostgreSQL Global Development Group + * + * src/backend/postmaster/progress.c + * ---------- + */ +#include "postgres.h" + +#include "port/atomics.h" /* for memory barriers */ +#include "utils/backend_progress.h" +#include "utils/backend_status.h" + + +/*----------- + * pgstat_progress_start_command() - + * + * Set st_progress_command (and st_progress_command_target) in own backend + * entry. Also, zero-initialize st_progress_param array. + *----------- + */ +void +pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + + if (!beentry || !pgstat_track_activities) + return; + + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + beentry->st_progress_command = cmdtype; + beentry->st_progress_command_target = relid; + MemSet(&beentry->st_progress_param, 0, sizeof(beentry->st_progress_param)); + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + +/*----------- + * pgstat_progress_update_param() - + * + * Update index'th member in st_progress_param[] of own backend entry. + *----------- + */ +void +pgstat_progress_update_param(int index, int64 val) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + + Assert(index >= 0 && index < PGSTAT_NUM_PROGRESS_PARAM); + + if (!beentry || !pgstat_track_activities) + return; + + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + beentry->st_progress_param[index] = val; + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + +/*----------- + * pgstat_progress_update_multi_param() - + * + * Update multiple members in st_progress_param[] of own backend entry. + * This is atomic; readers won't see intermediate states. + *----------- + */ +void +pgstat_progress_update_multi_param(int nparam, const int *index, + const int64 *val) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + int i; + + if (!beentry || !pgstat_track_activities || nparam == 0) + return; + + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + + for (i = 0; i < nparam; ++i) + { + Assert(index[i] >= 0 && index[i] < PGSTAT_NUM_PROGRESS_PARAM); + + beentry->st_progress_param[index[i]] = val[i]; + } + + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + +/*----------- + * pgstat_progress_end_command() - + * + * Reset st_progress_command (and st_progress_command_target) in own backend + * entry. This signals the end of the command. + *----------- + */ +void +pgstat_progress_end_command(void) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + + if (!beentry || !pgstat_track_activities) + return; + + if (beentry->st_progress_command == PROGRESS_COMMAND_INVALID) + return; + + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + beentry->st_progress_command = PROGRESS_COMMAND_INVALID; + beentry->st_progress_command_target = InvalidOid; + PGSTAT_END_WRITE_ACTIVITY(beentry); +} diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c new file mode 100644 index 000000000000..944e8ca28a27 --- /dev/null +++ b/src/backend/utils/activity/backend_status.c @@ -0,0 +1,1158 @@ +/* ---------- + * backend_status.c + * Backend status reporting infrastructure. + * + * Copyright (c) 2001-2021, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/postmaster/backend_status.c + * ---------- + */ +#include "postgres.h" + +#include "access/xact.h" +#include "libpq/libpq.h" +#include "miscadmin.h" +#include "pg_trace.h" +#include "pgstat.h" +#include "port/atomics.h" /* for memory barriers */ +#include "storage/ipc.h" +#include "storage/proc.h" /* for MyProc */ +#include "storage/sinvaladt.h" +#include "utils/ascii.h" +#include "utils/backend_status.h" +#include "utils/guc.h" /* for application_name */ +#include "utils/memutils.h" + +#include "cdb/cdbvars.h" /* gp_session_id */ + + +/* ---------- + * Total number of backends including auxiliary + * + * We reserve a slot for each possible BackendId, plus one for each + * possible auxiliary process type. (This scheme assumes there is not + * more than one of any auxiliary process type at a time.) MaxBackends + * includes autovacuum workers and background workers as well. + * ---------- + */ +#define NumBackendStatSlots (MaxBackends + NUM_AUXPROCTYPES) + + +/* ---------- + * GUC parameters + * ---------- + */ +bool pgstat_track_activities = false; +int pgstat_track_activity_query_size = 1024; + + +/* exposed so that progress.c can access it */ +PgBackendStatus *MyBEEntry = NULL; + + +static PgBackendStatus *BackendStatusArray = NULL; +static char *BackendAppnameBuffer = NULL; +static char *BackendClientHostnameBuffer = NULL; +static char *BackendActivityBuffer = NULL; +static Size BackendActivityBufferSize = 0; +#ifdef USE_SSL +static PgBackendSSLStatus *BackendSslStatusBuffer = NULL; +#endif +#ifdef ENABLE_GSS +static PgBackendGSSStatus *BackendGssStatusBuffer = NULL; +#endif + + +/* Status for backends including auxiliary */ +static LocalPgBackendStatus *localBackendStatusTable = NULL; + +/* Total number of backends including auxiliary */ +static int localNumBackends = 0; + +static MemoryContext backendStatusSnapContext; + + +static void pgstat_beshutdown_hook(int code, Datum arg); +static void pgstat_read_current_status(void); +static void pgstat_setup_backend_status_context(void); + + +/* + * Report shared-memory space needed by CreateSharedBackendStatus. + */ +Size +BackendStatusShmemSize(void) +{ + Size size; + + /* BackendStatusArray: */ + size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots); + /* BackendAppnameBuffer: */ + size = add_size(size, + mul_size(NAMEDATALEN, NumBackendStatSlots)); + /* BackendClientHostnameBuffer: */ + size = add_size(size, + mul_size(NAMEDATALEN, NumBackendStatSlots)); + /* BackendActivityBuffer: */ + size = add_size(size, + mul_size(pgstat_track_activity_query_size, NumBackendStatSlots)); +#ifdef USE_SSL + /* BackendSslStatusBuffer: */ + size = add_size(size, + mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots)); +#endif +#ifdef ENABLE_GSS + /* BackendGssStatusBuffer: */ + size = add_size(size, + mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots)); +#endif + return size; +} + +/* + * Initialize the shared status array and several string buffers + * during postmaster startup. + */ +void +CreateSharedBackendStatus(void) +{ + Size size; + bool found; + int i; + char *buffer; + + /* Create or attach to the shared array */ + size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots); + BackendStatusArray = (PgBackendStatus *) + ShmemInitStruct("Backend Status Array", size, &found); + + if (!found) + { + /* + * We're the first - initialize. + */ + MemSet(BackendStatusArray, 0, size); + } + + /* Create or attach to the shared appname buffer */ + size = mul_size(NAMEDATALEN, NumBackendStatSlots); + BackendAppnameBuffer = (char *) + ShmemInitStruct("Backend Application Name Buffer", size, &found); + + if (!found) + { + MemSet(BackendAppnameBuffer, 0, size); + + /* Initialize st_appname pointers. */ + buffer = BackendAppnameBuffer; + for (i = 0; i < NumBackendStatSlots; i++) + { + BackendStatusArray[i].st_appname = buffer; + buffer += NAMEDATALEN; + } + } + + /* Create or attach to the shared client hostname buffer */ + size = mul_size(NAMEDATALEN, NumBackendStatSlots); + BackendClientHostnameBuffer = (char *) + ShmemInitStruct("Backend Client Host Name Buffer", size, &found); + + if (!found) + { + MemSet(BackendClientHostnameBuffer, 0, size); + + /* Initialize st_clienthostname pointers. */ + buffer = BackendClientHostnameBuffer; + for (i = 0; i < NumBackendStatSlots; i++) + { + BackendStatusArray[i].st_clienthostname = buffer; + buffer += NAMEDATALEN; + } + } + + /* Create or attach to the shared activity buffer */ + BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size, + NumBackendStatSlots); + BackendActivityBuffer = (char *) + ShmemInitStruct("Backend Activity Buffer", + BackendActivityBufferSize, + &found); + + if (!found) + { + MemSet(BackendActivityBuffer, 0, BackendActivityBufferSize); + + /* Initialize st_activity pointers. */ + buffer = BackendActivityBuffer; + for (i = 0; i < NumBackendStatSlots; i++) + { + BackendStatusArray[i].st_activity_raw = buffer; + buffer += pgstat_track_activity_query_size; + } + } + +#ifdef USE_SSL + /* Create or attach to the shared SSL status buffer */ + size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots); + BackendSslStatusBuffer = (PgBackendSSLStatus *) + ShmemInitStruct("Backend SSL Status Buffer", size, &found); + + if (!found) + { + PgBackendSSLStatus *ptr; + + MemSet(BackendSslStatusBuffer, 0, size); + + /* Initialize st_sslstatus pointers. */ + ptr = BackendSslStatusBuffer; + for (i = 0; i < NumBackendStatSlots; i++) + { + BackendStatusArray[i].st_sslstatus = ptr; + ptr++; + } + } +#endif + +#ifdef ENABLE_GSS + /* Create or attach to the shared GSSAPI status buffer */ + size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots); + BackendGssStatusBuffer = (PgBackendGSSStatus *) + ShmemInitStruct("Backend GSS Status Buffer", size, &found); + + if (!found) + { + PgBackendGSSStatus *ptr; + + MemSet(BackendGssStatusBuffer, 0, size); + + /* Initialize st_gssstatus pointers. */ + ptr = BackendGssStatusBuffer; + for (i = 0; i < NumBackendStatSlots; i++) + { + BackendStatusArray[i].st_gssstatus = ptr; + ptr++; + } + } +#endif +} + +/* + * Initialize pgstats backend activity state, and set up our on-proc-exit + * hook. Called from InitPostgres and AuxiliaryProcessMain. For auxiliary + * process, MyBackendId is invalid. Otherwise, MyBackendId must be set, but we + * must not have started any transaction yet (since the exit hook must run + * after the last transaction exit). + * + * NOTE: MyDatabaseId isn't set yet; so the shutdown hook has to be careful. + */ +void +pgstat_beinit(void) +{ + /* Initialize MyBEEntry */ + if (MyBackendId != InvalidBackendId) + { + Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends); + MyBEEntry = &BackendStatusArray[MyBackendId - 1]; + } + else + { + /* Must be an auxiliary process */ + Assert(MyAuxProcType != NotAnAuxProcess); + + /* + * Assign the MyBEEntry for an auxiliary process. Since it doesn't + * have a BackendId, the slot is statically allocated based on the + * auxiliary process type (MyAuxProcType). Backends use slots indexed + * in the range from 1 to MaxBackends (inclusive), so we use + * MaxBackends + AuxBackendType + 1 as the index of the slot for an + * auxiliary process. + */ + MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType]; + } + + /* Set up a process-exit hook to clean up */ + on_shmem_exit(pgstat_beshutdown_hook, 0); +} + + +/* ---------- + * pgstat_bestart() - + * + * Initialize this backend's entry in the PgBackendStatus array. + * Called from InitPostgres. + * + * Apart from auxiliary processes, MyBackendId, MyDatabaseId, + * session userid, and application_name must be set for a + * backend (hence, this cannot be combined with pgbestat_beinit). + * Note also that we must be inside a transaction if this isn't an aux + * process, as we may need to do encoding conversion on some strings. + * ---------- + */ +void +pgstat_bestart(void) +{ + volatile PgBackendStatus *vbeentry = MyBEEntry; + PgBackendStatus lbeentry; +#ifdef USE_SSL + PgBackendSSLStatus lsslstatus; +#endif +#ifdef ENABLE_GSS + PgBackendGSSStatus lgssstatus; +#endif + + /* pgstats state must be initialized from pgstat_beinit() */ + Assert(vbeentry != NULL); + + /* + * To minimize the time spent modifying the PgBackendStatus entry, and + * avoid risk of errors inside the critical section, we first copy the + * shared-memory struct to a local variable, then modify the data in the + * local variable, then copy the local variable back to shared memory. + * Only the last step has to be inside the critical section. + * + * Most of the data we copy from shared memory is just going to be + * overwritten, but the struct's not so large that it's worth the + * maintenance hassle to copy only the needful fields. + */ + memcpy(&lbeentry, + unvolatize(PgBackendStatus *, vbeentry), + sizeof(PgBackendStatus)); + + /* These structs can just start from zeroes each time, though */ +#ifdef USE_SSL + memset(&lsslstatus, 0, sizeof(lsslstatus)); +#endif +#ifdef ENABLE_GSS + memset(&lgssstatus, 0, sizeof(lgssstatus)); +#endif + + /* + * Now fill in all the fields of lbeentry, except for strings that are + * out-of-line data. Those have to be handled separately, below. + */ + lbeentry.st_procpid = MyProcPid; + lbeentry.st_backendType = MyBackendType; + lbeentry.st_proc_start_timestamp = MyStartTimestamp; + lbeentry.st_activity_start_timestamp = 0; + lbeentry.st_state_start_timestamp = 0; + lbeentry.st_xact_start_timestamp = 0; + lbeentry.st_databaseid = MyDatabaseId; + + /* We have userid for client-backends, wal-sender and bgworker processes */ + if (lbeentry.st_backendType == B_BACKEND + || lbeentry.st_backendType == B_WAL_SENDER + || lbeentry.st_backendType == B_BG_WORKER) + lbeentry.st_userid = GetSessionUserId(); + else + lbeentry.st_userid = InvalidOid; + + lbeentry.st_session_id = gp_session_id; /* GPDB only */ + + /* + * We may not have a MyProcPort (eg, if this is the autovacuum process). + * If so, use all-zeroes client address, which is dealt with specially in + * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port. + */ + if (MyProcPort) + memcpy(&lbeentry.st_clientaddr, &MyProcPort->raddr, + sizeof(lbeentry.st_clientaddr)); + else + MemSet(&lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr)); + +#ifdef USE_SSL + if (MyProcPort && MyProcPort->ssl_in_use) + { + lbeentry.st_ssl = true; + lsslstatus.ssl_bits = be_tls_get_cipher_bits(MyProcPort); + strlcpy(lsslstatus.ssl_version, be_tls_get_version(MyProcPort), NAMEDATALEN); + strlcpy(lsslstatus.ssl_cipher, be_tls_get_cipher(MyProcPort), NAMEDATALEN); + be_tls_get_peer_subject_name(MyProcPort, lsslstatus.ssl_client_dn, NAMEDATALEN); + be_tls_get_peer_serial(MyProcPort, lsslstatus.ssl_client_serial, NAMEDATALEN); + be_tls_get_peer_issuer_name(MyProcPort, lsslstatus.ssl_issuer_dn, NAMEDATALEN); + } + else + { + lbeentry.st_ssl = false; + } +#else + lbeentry.st_ssl = false; +#endif + +#ifdef ENABLE_GSS + if (MyProcPort && MyProcPort->gss != NULL) + { + const char *princ = be_gssapi_get_princ(MyProcPort); + + lbeentry.st_gss = true; + lgssstatus.gss_auth = be_gssapi_get_auth(MyProcPort); + lgssstatus.gss_enc = be_gssapi_get_enc(MyProcPort); + if (princ) + strlcpy(lgssstatus.gss_princ, princ, NAMEDATALEN); + } + else + { + lbeentry.st_gss = false; + } +#else + lbeentry.st_gss = false; +#endif + + lbeentry.st_state = STATE_UNDEFINED; + lbeentry.st_progress_command = PROGRESS_COMMAND_INVALID; + lbeentry.st_progress_command_target = InvalidOid; + lbeentry.st_rsgid = InvalidOid; /* GPDB: resource group */ + lbeentry.st_query_id = UINT64CONST(0); + + /* + * we don't zero st_progress_param here to save cycles; nobody should + * examine it until st_progress_command has been set to something other + * than PROGRESS_COMMAND_INVALID + */ + + /* + * We're ready to enter the critical section that fills the shared-memory + * status entry. We follow the protocol of bumping st_changecount before + * and after; and make sure it's even afterwards. We use a volatile + * pointer here to ensure the compiler doesn't try to get cute. + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(vbeentry); + + /* make sure we'll memcpy the same st_changecount back */ + lbeentry.st_changecount = vbeentry->st_changecount; + + memcpy(unvolatize(PgBackendStatus *, vbeentry), + &lbeentry, + sizeof(PgBackendStatus)); + + /* + * We can write the out-of-line strings and structs using the pointers + * that are in lbeentry; this saves some de-volatilizing messiness. + */ + lbeentry.st_appname[0] = '\0'; + if (MyProcPort && MyProcPort->remote_hostname) + strlcpy(lbeentry.st_clienthostname, MyProcPort->remote_hostname, + NAMEDATALEN); + else + lbeentry.st_clienthostname[0] = '\0'; + lbeentry.st_activity_raw[0] = '\0'; + /* Also make sure the last byte in each string area is always 0 */ + lbeentry.st_appname[NAMEDATALEN - 1] = '\0'; + lbeentry.st_clienthostname[NAMEDATALEN - 1] = '\0'; + lbeentry.st_activity_raw[pgstat_track_activity_query_size - 1] = '\0'; + +#ifdef USE_SSL + memcpy(lbeentry.st_sslstatus, &lsslstatus, sizeof(PgBackendSSLStatus)); +#endif +#ifdef ENABLE_GSS + memcpy(lbeentry.st_gssstatus, &lgssstatus, sizeof(PgBackendGSSStatus)); +#endif + + PGSTAT_END_WRITE_ACTIVITY(vbeentry); + + /* + * GPDB: Initialize per-portal statistics hash for resource queues. + */ + pgstat_init_localportalhash(); + + /* Update app name to current GUC setting */ + if (application_name) + pgstat_report_appname(application_name); +} + +/* + * Clear out our entry in the PgBackendStatus array. + */ +static void +pgstat_beshutdown_hook(int code, Datum arg) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + + /* + * Clear my status entry, following the protocol of bumping st_changecount + * before and after. We use a volatile pointer here to ensure the + * compiler doesn't try to get cute. + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + + beentry->st_procpid = 0; /* mark invalid */ + beentry->st_session_id = 0; /* GPDB: clear session id */ + + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + +/* + * Discard any data collected in the current transaction. Any subsequent + * request will cause new snapshots to be read. + * + * This is also invoked during transaction commit or abort to discard the + * no-longer-wanted snapshot. + */ +void +pgstat_clear_backend_activity_snapshot(void) +{ + /* Release memory, if any was allocated */ + if (backendStatusSnapContext) + { + MemoryContextDelete(backendStatusSnapContext); + backendStatusSnapContext = NULL; + } + + /* Reset variables */ + localBackendStatusTable = NULL; + localNumBackends = 0; +} + +static void +pgstat_setup_backend_status_context(void) +{ + if (!backendStatusSnapContext) + backendStatusSnapContext = AllocSetContextCreate(TopMemoryContext, + "Backend Status Snapshot", + ALLOCSET_SMALL_SIZES); +} + + +/* ---------- + * pgstat_report_activity() - + * + * Called from tcop/postgres.c to report what the backend is actually doing + * (but note cmd_str can be NULL for certain cases). + * + * All updates of the status entry follow the protocol of bumping + * st_changecount before and after. We use a volatile pointer here to + * ensure the compiler doesn't try to get cute. + * ---------- + */ +void +pgstat_report_activity(BackendState state, const char *cmd_str) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + TimestampTz start_timestamp; + TimestampTz current_timestamp; + int len = 0; + + TRACE_POSTGRESQL_STATEMENT_STATUS(cmd_str); + + if (!beentry) + return; + + if (!pgstat_track_activities) + { + if (beentry->st_state != STATE_DISABLED) + { + volatile PGPROC *proc = MyProc; + + /* + * track_activities is disabled, but we last reported a + * non-disabled state. As our final update, change the state and + * clear fields we will not be updating anymore. + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + beentry->st_state = STATE_DISABLED; + beentry->st_state_start_timestamp = 0; + beentry->st_activity_raw[0] = '\0'; + beentry->st_activity_start_timestamp = 0; + /* st_xact_start_timestamp and wait_event_info are also disabled */ + beentry->st_xact_start_timestamp = 0; + beentry->st_query_id = UINT64CONST(0); + proc->wait_event_info = 0; + PGSTAT_END_WRITE_ACTIVITY(beentry); + } + return; + } + + /* + * To minimize the time spent modifying the entry, and avoid risk of + * errors inside the critical section, fetch all the needed data first. + */ + start_timestamp = GetCurrentStatementStartTimestamp(); + if (cmd_str != NULL) + { + /* + * Compute length of to-be-stored string unaware of multi-byte + * characters. For speed reasons that'll get corrected on read, rather + * than computed every write. + */ + len = Min(strlen(cmd_str), pgstat_track_activity_query_size - 1); + } + current_timestamp = GetCurrentTimestamp(); + + /* + * If the state has changed from "active" or "idle in transaction", + * calculate the duration. + */ + if ((beentry->st_state == STATE_RUNNING || + beentry->st_state == STATE_FASTPATH || + beentry->st_state == STATE_IDLEINTRANSACTION || + beentry->st_state == STATE_IDLEINTRANSACTION_ABORTED) && + state != beentry->st_state) + { + long secs; + int usecs; + + TimestampDifference(beentry->st_state_start_timestamp, + current_timestamp, + &secs, &usecs); + + if (beentry->st_state == STATE_RUNNING || + beentry->st_state == STATE_FASTPATH) + pgstat_count_conn_active_time(secs * 1000000 + usecs); + else + pgstat_count_conn_txn_idle_time(secs * 1000000 + usecs); + } + + /* + * Now update the status entry + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + + beentry->st_state = state; + beentry->st_state_start_timestamp = current_timestamp; + + /* + * If a new query is started, we reset the query identifier as it'll only + * be known after parse analysis, to avoid reporting last query's + * identifier. + */ + if (state == STATE_RUNNING) + beentry->st_query_id = UINT64CONST(0); + + if (cmd_str != NULL) + { + memcpy((char *) beentry->st_activity_raw, cmd_str, len); + beentry->st_activity_raw[len] = '\0'; + beentry->st_activity_start_timestamp = start_timestamp; + } + + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + +/* -------- + * pgstat_report_query_id() - + * + * Called to update top-level query identifier. + * -------- + */ +void +pgstat_report_query_id(uint64 query_id, bool force) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + + /* + * if track_activities is disabled, st_query_id should already have been + * reset + */ + if (!beentry || !pgstat_track_activities) + return; + + /* + * We only report the top-level query identifiers. The stored query_id is + * reset when a backend calls pgstat_report_activity(STATE_RUNNING), or + * with an explicit call to this function using the force flag. If the + * saved query identifier is not zero it means that it's not a top-level + * command, so ignore the one provided unless it's an explicit call to + * reset the identifier. + */ + if (beentry->st_query_id != 0 && !force) + return; + + /* + * Update my status entry, following the protocol of bumping + * st_changecount before and after. We use a volatile pointer here to + * ensure the compiler doesn't try to get cute. + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + beentry->st_query_id = query_id; + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + + +/* ---------- + * pgstat_report_appname() - + * + * Called to update our application name. + * ---------- + */ +void +pgstat_report_appname(const char *appname) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + int len; + + if (!beentry) + return; + + /* This should be unnecessary if GUC did its job, but be safe */ + len = pg_mbcliplen(appname, strlen(appname), NAMEDATALEN - 1); + + /* + * Update my status entry, following the protocol of bumping + * st_changecount before and after. We use a volatile pointer here to + * ensure the compiler doesn't try to get cute. + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + + memcpy((char *) beentry->st_appname, appname, len); + beentry->st_appname[len] = '\0'; + + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + +/* + * Report current transaction start timestamp as the specified value. + * Zero means there is no active transaction. + */ +void +pgstat_report_xact_timestamp(TimestampTz tstamp) +{ + volatile PgBackendStatus *beentry = MyBEEntry; + + if (!pgstat_track_activities || !beentry) + return; + + /* + * Update my status entry, following the protocol of bumping + * st_changecount before and after. We use a volatile pointer here to + * ensure the compiler doesn't try to get cute. + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + + beentry->st_xact_start_timestamp = tstamp; + + PGSTAT_END_WRITE_ACTIVITY(beentry); +} + +/* ---------- + * pgstat_read_current_status() - + * + * Copy the current contents of the PgBackendStatus array to local memory, + * if not already done in this transaction. + * ---------- + */ +static void +pgstat_read_current_status(void) +{ + volatile PgBackendStatus *beentry; + LocalPgBackendStatus *localtable; + LocalPgBackendStatus *localentry; + char *localappname, + *localclienthostname, + *localactivity; +#ifdef USE_SSL + PgBackendSSLStatus *localsslstatus; +#endif +#ifdef ENABLE_GSS + PgBackendGSSStatus *localgssstatus; +#endif + int i; + + if (localBackendStatusTable) + return; /* already done */ + + pgstat_setup_backend_status_context(); + + /* + * Allocate storage for local copy of state data. We can presume that + * none of these requests overflow size_t, because we already calculated + * the same values using mul_size during shmem setup. However, with + * probably-silly values of pgstat_track_activity_query_size and + * max_connections, the localactivity buffer could exceed 1GB, so use + * "huge" allocation for that one. + */ + localtable = (LocalPgBackendStatus *) + MemoryContextAlloc(backendStatusSnapContext, + sizeof(LocalPgBackendStatus) * NumBackendStatSlots); + localappname = (char *) + MemoryContextAlloc(backendStatusSnapContext, + NAMEDATALEN * NumBackendStatSlots); + localclienthostname = (char *) + MemoryContextAlloc(backendStatusSnapContext, + NAMEDATALEN * NumBackendStatSlots); + localactivity = (char *) + MemoryContextAllocHuge(backendStatusSnapContext, + pgstat_track_activity_query_size * NumBackendStatSlots); +#ifdef USE_SSL + localsslstatus = (PgBackendSSLStatus *) + MemoryContextAlloc(backendStatusSnapContext, + sizeof(PgBackendSSLStatus) * NumBackendStatSlots); +#endif +#ifdef ENABLE_GSS + localgssstatus = (PgBackendGSSStatus *) + MemoryContextAlloc(backendStatusSnapContext, + sizeof(PgBackendGSSStatus) * NumBackendStatSlots); +#endif + + localNumBackends = 0; + + beentry = BackendStatusArray; + localentry = localtable; + for (i = 1; i <= NumBackendStatSlots; i++) + { + /* + * Follow the protocol of retrying if st_changecount changes while we + * copy the entry, or if it's odd. (The check for odd is needed to + * cover the case where we are able to completely copy the entry while + * the source backend is between increment steps.) We use a volatile + * pointer here to ensure the compiler doesn't try to get cute. + */ + for (;;) + { + int before_changecount; + int after_changecount; + + pgstat_begin_read_activity(beentry, before_changecount); + + localentry->backendStatus.st_procpid = beentry->st_procpid; + /* Skip all the data-copying work if entry is not in use */ + if (localentry->backendStatus.st_procpid > 0) + { + memcpy(&localentry->backendStatus, unvolatize(PgBackendStatus *, beentry), sizeof(PgBackendStatus)); + + /* + * For each PgBackendStatus field that is a pointer, copy the + * pointed-to data, then adjust the local copy of the pointer + * field to point at the local copy of the data. + * + * strcpy is safe even if the string is modified concurrently, + * because there's always a \0 at the end of the buffer. + */ + strcpy(localappname, (char *) beentry->st_appname); + localentry->backendStatus.st_appname = localappname; + strcpy(localclienthostname, (char *) beentry->st_clienthostname); + localentry->backendStatus.st_clienthostname = localclienthostname; + strcpy(localactivity, (char *) beentry->st_activity_raw); + localentry->backendStatus.st_activity_raw = localactivity; +#ifdef USE_SSL + if (beentry->st_ssl) + { + memcpy(localsslstatus, beentry->st_sslstatus, sizeof(PgBackendSSLStatus)); + localentry->backendStatus.st_sslstatus = localsslstatus; + } +#endif +#ifdef ENABLE_GSS + if (beentry->st_gss) + { + memcpy(localgssstatus, beentry->st_gssstatus, sizeof(PgBackendGSSStatus)); + localentry->backendStatus.st_gssstatus = localgssstatus; + } +#endif + } + + pgstat_end_read_activity(beentry, after_changecount); + + if (pgstat_read_activity_complete(before_changecount, + after_changecount)) + break; + + /* Make sure we can break out of loop if stuck... */ + CHECK_FOR_INTERRUPTS(); + } + + beentry++; + /* Only valid entries get included into the local array */ + if (localentry->backendStatus.st_procpid > 0) + { + BackendIdGetTransactionIds(i, + &localentry->backend_xid, + &localentry->backend_xmin); + + localentry++; + localappname += NAMEDATALEN; + localclienthostname += NAMEDATALEN; + localactivity += pgstat_track_activity_query_size; +#ifdef USE_SSL + localsslstatus++; +#endif +#ifdef ENABLE_GSS + localgssstatus++; +#endif + localNumBackends++; + } + } + + /* Set the pointer only after completion of a valid table */ + localBackendStatusTable = localtable; +} + + +/* ---------- + * pgstat_get_backend_current_activity() - + * + * Return a string representing the current activity of the backend with + * the specified PID. This looks directly at the BackendStatusArray, + * and so will provide current information regardless of the age of our + * transaction's snapshot of the status array. + * + * It is the caller's responsibility to invoke this only for backends whose + * state is expected to remain stable while the result is in use. The + * only current use is in deadlock reporting, where we can expect that + * the target backend is blocked on a lock. (There are corner cases + * where the target's wait could get aborted while we are looking at it, + * but the very worst consequence is to return a pointer to a string + * that's been changed, so we won't worry too much.) + * + * Note: return strings for special cases match pg_stat_get_backend_activity. + * ---------- + */ +const char * +pgstat_get_backend_current_activity(int pid, bool checkUser) +{ + PgBackendStatus *beentry; + int i; + + beentry = BackendStatusArray; + for (i = 1; i <= MaxBackends; i++) + { + /* + * Although we expect the target backend's entry to be stable, that + * doesn't imply that anyone else's is. To avoid identifying the + * wrong backend, while we check for a match to the desired PID we + * must follow the protocol of retrying if st_changecount changes + * while we examine the entry, or if it's odd. (This might be + * unnecessary, since fetching or storing an int is almost certainly + * atomic, but let's play it safe.) We use a volatile pointer here to + * ensure the compiler doesn't try to get cute. + */ + volatile PgBackendStatus *vbeentry = beentry; + bool found; + + for (;;) + { + int before_changecount; + int after_changecount; + + pgstat_begin_read_activity(vbeentry, before_changecount); + + found = (vbeentry->st_procpid == pid); + + pgstat_end_read_activity(vbeentry, after_changecount); + + if (pgstat_read_activity_complete(before_changecount, + after_changecount)) + break; + + /* Make sure we can break out of loop if stuck... */ + CHECK_FOR_INTERRUPTS(); + } + + if (found) + { + /* Now it is safe to use the non-volatile pointer */ + if (checkUser && !superuser() && beentry->st_userid != GetUserId()) + return ""; + else if (*(beentry->st_activity_raw) == '\0') + return ""; + else + { + /* this'll leak a bit of memory, but that seems acceptable */ + return pgstat_clip_activity(beentry->st_activity_raw); + } + } + + beentry++; + } + + /* If we get here, caller is in error ... */ + return ""; +} + +/* ---------- + * pgstat_get_crashed_backend_activity() - + * + * Return a string representing the current activity of the backend with + * the specified PID. Like the function above, but reads shared memory with + * the expectation that it may be corrupt. On success, copy the string + * into the "buffer" argument and return that pointer. On failure, + * return NULL. + * + * This function is only intended to be used by the postmaster to report the + * query that crashed a backend. In particular, no attempt is made to + * follow the correct concurrency protocol when accessing the + * BackendStatusArray. But that's OK, in the worst case we'll return a + * corrupted message. We also must take care not to trip on ereport(ERROR). + * ---------- + */ +const char * +pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen) +{ + volatile PgBackendStatus *beentry; + int i; + + beentry = BackendStatusArray; + + /* + * We probably shouldn't get here before shared memory has been set up, + * but be safe. + */ + if (beentry == NULL || BackendActivityBuffer == NULL) + return NULL; + + for (i = 1; i <= MaxBackends; i++) + { + if (beentry->st_procpid == pid) + { + /* Read pointer just once, so it can't change after validation */ + const char *activity = beentry->st_activity_raw; + const char *activity_last; + + /* + * We mustn't access activity string before we verify that it + * falls within the BackendActivityBuffer. To make sure that the + * entire string including its ending is contained within the + * buffer, subtract one activity length from the buffer size. + */ + activity_last = BackendActivityBuffer + BackendActivityBufferSize + - pgstat_track_activity_query_size; + + if (activity < BackendActivityBuffer || + activity > activity_last) + return NULL; + + /* If no string available, no point in a report */ + if (activity[0] == '\0') + return NULL; + + /* + * Copy only ASCII-safe characters so we don't run into encoding + * problems when reporting the message; and be sure not to run off + * the end of memory. As only ASCII characters are reported, it + * doesn't seem necessary to perform multibyte aware clipping. + */ + ascii_safe_strlcpy(buffer, activity, + Min(buflen, pgstat_track_activity_query_size)); + + return buffer; + } + + beentry++; + } + + /* PID not found */ + return NULL; +} + +/* ---------- + * pgstat_get_my_query_id() - + * + * Return current backend's query identifier. + */ +uint64 +pgstat_get_my_query_id(void) +{ + if (!MyBEEntry) + return 0; + + /* + * There's no need for a lock around pgstat_begin_read_activity / + * pgstat_end_read_activity here as it's only called from + * pg_stat_get_activity which is already protected, or from the same + * backend which means that there won't be concurrent writes. + */ + return MyBEEntry->st_query_id; +} + + +/* ---------- + * pgstat_fetch_stat_beentry() - + * + * Support function for the SQL-callable pgstat* functions. Returns + * our local copy of the current-activity entry for one backend. + * + * NB: caller is responsible for a check if the user is permitted to see + * this info (especially the querystring). + * ---------- + */ +PgBackendStatus * +pgstat_fetch_stat_beentry(int beid) +{ + pgstat_read_current_status(); + + if (beid < 1 || beid > localNumBackends) + return NULL; + + return &localBackendStatusTable[beid - 1].backendStatus; +} + + +/* ---------- + * pgstat_fetch_stat_local_beentry() - + * + * Like pgstat_fetch_stat_beentry() but with locally computed additions (like + * xid and xmin values of the backend) + * + * NB: caller is responsible for a check if the user is permitted to see + * this info (especially the querystring). + * ---------- + */ +LocalPgBackendStatus * +pgstat_fetch_stat_local_beentry(int beid) +{ + pgstat_read_current_status(); + + if (beid < 1 || beid > localNumBackends) + return NULL; + + return &localBackendStatusTable[beid - 1]; +} + + +/* ---------- + * pgstat_fetch_stat_numbackends() - + * + * Support function for the SQL-callable pgstat* functions. Returns + * the maximum current backend id. + * ---------- + */ +int +pgstat_fetch_stat_numbackends(void) +{ + pgstat_read_current_status(); + + return localNumBackends; +} + +/* + * Convert a potentially unsafely truncated activity string (see + * PgBackendStatus.st_activity_raw's documentation) into a correctly truncated + * one. + * + * The returned string is allocated in the caller's memory context and may be + * freed. + */ +char * +pgstat_clip_activity(const char *raw_activity) +{ + char *activity; + int rawlen; + int cliplen; + + /* + * Some callers, like pgstat_get_backend_current_activity(), do not + * guarantee that the buffer isn't concurrently modified. We try to take + * care that the buffer is always terminated by a NUL byte regardless, but + * let's still be paranoid about the string's length. In those cases the + * underlying buffer is guaranteed to be pgstat_track_activity_query_size + * large. + */ + activity = pnstrdup(raw_activity, pgstat_track_activity_query_size - 1); + + /* now double-guaranteed to be NUL terminated */ + rawlen = strlen(activity); + + /* + * All supported server-encodings make it possible to determine the length + * of a multi-byte character from its first byte (this is not the case for + * client encodings, see GB18030). As st_activity is always stored using + * server encoding, this allows us to perform multi-byte aware truncation, + * even if the string earlier was truncated in the middle of a multi-byte + * character. + */ + cliplen = pg_mbcliplen(activity, rawlen, + pgstat_track_activity_query_size - 1); + + activity[cliplen] = '\0'; + + return activity; +} diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c new file mode 100644 index 000000000000..f7be407dbf5c --- /dev/null +++ b/src/backend/utils/activity/wait_event.c @@ -0,0 +1,793 @@ +/* ---------- + * wait_event.c + * Wait event reporting infrastructure. + * + * Copyright (c) 2001-2021, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/postmaster/wait_event.c + * + * NOTES + * + * To make pgstat_report_wait_start() and pgstat_report_wait_end() as + * lightweight as possible, they do not check if shared memory (MyProc + * specifically, where the wait event is stored) is already available. Instead + * we initially set my_wait_event_info to a process local variable, which then + * is redirected to shared memory using pgstat_set_wait_event_storage(). For + * the same reason pgstat_track_activities is not checked - the check adds + * more work than it saves. + * + * ---------- + */ +#include "postgres.h" + +#include "storage/lmgr.h" /* for GetLockNameFromTagType */ +#include "storage/lwlock.h" /* for GetLWLockIdentifier */ +#include "utils/wait_event.h" + + +static const char *pgstat_get_wait_activity(WaitEventActivity w); +static const char *pgstat_get_wait_client(WaitEventClient w); +static const char *pgstat_get_wait_ipc(WaitEventIPC w); +static const char *pgstat_get_wait_timeout(WaitEventTimeout w); +static const char *pgstat_get_wait_io(WaitEventIO w); + + +static uint32 local_my_wait_event_info; +uint32 *my_wait_event_info = &local_my_wait_event_info; + + +/* + * Configure wait event reporting to report wait events to *wait_event_info. + * *wait_event_info needs to be valid until pgstat_reset_wait_event_storage() + * is called. + * + * Expected to be called during backend startup, to point my_wait_event_info + * into shared memory. + */ +void +pgstat_set_wait_event_storage(uint32 *wait_event_info) +{ + my_wait_event_info = wait_event_info; +} + +/* + * Reset wait event storage location. + * + * Expected to be called during backend shutdown, before the location set up + * pgstat_set_wait_event_storage() becomes invalid. + */ +void +pgstat_reset_wait_event_storage(void) +{ + my_wait_event_info = &local_my_wait_event_info; +} + +/* ---------- + * pgstat_get_wait_event_type() - + * + * Return a string representing the current wait event type, backend is + * waiting on. + */ +const char * +pgstat_get_wait_event_type(uint32 wait_event_info) +{ + uint32 classId; + const char *event_type; + + /* report process as not waiting. */ + if (wait_event_info == 0) + return NULL; + + classId = wait_event_info & 0xFF000000; + + switch (classId) + { + case PG_WAIT_LWLOCK: + event_type = "LWLock"; + break; + case PG_WAIT_LOCK: + event_type = "Lock"; + break; + case PG_WAIT_BUFFER_PIN: + event_type = "BufferPin"; + break; + case PG_WAIT_ACTIVITY: + event_type = "Activity"; + break; + case PG_WAIT_CLIENT: + event_type = "Client"; + break; + case PG_WAIT_EXTENSION: + event_type = "Extension"; + break; + case PG_WAIT_IPC: + event_type = "IPC"; + break; + case PG_WAIT_TIMEOUT: + event_type = "Timeout"; + break; + case PG_WAIT_IO: + event_type = "IO"; + break; + case PG_WAIT_RESOURCE_GROUP: + event_type = "ResourceGroup"; + break; + case PG_WAIT_RESOURCE_QUEUE: + event_type = "ResourceQueue"; + break; + case PG_WAIT_REPLICATION: + event_type = "Replication"; + break; + default: + event_type = "???"; + break; + } + + return event_type; +} + +/* ---------- + * pgstat_get_wait_event() - + * + * Return a string representing the current wait event, backend is + * waiting on. + */ +const char * +pgstat_get_wait_event(uint32 wait_event_info) +{ + uint32 classId; + uint16 eventId; + const char *event_name; + + /* report process as not waiting. */ + if (wait_event_info == 0) + return NULL; + + classId = wait_event_info & 0xFF000000; + eventId = wait_event_info & 0x0000FFFF; + + switch (classId) + { + case PG_WAIT_LWLOCK: + event_name = GetLWLockIdentifier(classId, eventId); + break; + case PG_WAIT_LOCK: + event_name = GetLockNameFromTagType(eventId); + break; + case PG_WAIT_BUFFER_PIN: + event_name = "BufferPin"; + break; + case PG_WAIT_ACTIVITY: + { + WaitEventActivity w = (WaitEventActivity) wait_event_info; + + event_name = pgstat_get_wait_activity(w); + break; + } + case PG_WAIT_CLIENT: + { + WaitEventClient w = (WaitEventClient) wait_event_info; + + event_name = pgstat_get_wait_client(w); + break; + } + case PG_WAIT_EXTENSION: + event_name = "Extension"; + break; + case PG_WAIT_IPC: + { + WaitEventIPC w = (WaitEventIPC) wait_event_info; + + event_name = pgstat_get_wait_ipc(w); + break; + } + case PG_WAIT_TIMEOUT: + { + WaitEventTimeout w = (WaitEventTimeout) wait_event_info; + + event_name = pgstat_get_wait_timeout(w); + break; + } + case PG_WAIT_IO: + { + WaitEventIO w = (WaitEventIO) wait_event_info; + + event_name = pgstat_get_wait_io(w); + break; + } + case PG_WAIT_RESOURCE_GROUP: + + /* + * We don't pass details for resource groups via event id, since + * it's an uint16 and resource group id is an Oid. + * + * Here should be never used, pg_stat_get_activity() will get the + * information from backend entry. + */ + event_name = "ResourceGroup"; + break; + case PG_WAIT_RESOURCE_QUEUE: + event_name = "ResourceQueue"; + break; + case PG_WAIT_REPLICATION: + event_name = "Replication"; + break; + default: + event_name = "unknown wait event"; + break; + } + + return event_name; +} + +/* ---------- + * pgstat_get_wait_activity() - + * + * Convert WaitEventActivity to string. + * ---------- + */ +static const char * +pgstat_get_wait_activity(WaitEventActivity w) +{ + const char *event_name = "unknown wait event"; + + switch (w) + { + case WAIT_EVENT_ARCHIVER_MAIN: + event_name = "ArchiverMain"; + break; + case WAIT_EVENT_AUTOVACUUM_MAIN: + event_name = "AutoVacuumMain"; + break; + case WAIT_EVENT_BGWRITER_HIBERNATE: + event_name = "BgWriterHibernate"; + break; + case WAIT_EVENT_BGWRITER_MAIN: + event_name = "BgWriterMain"; + break; + case WAIT_EVENT_CHECKPOINTER_MAIN: + event_name = "CheckpointerMain"; + break; + case WAIT_EVENT_LOGICAL_APPLY_MAIN: + event_name = "LogicalApplyMain"; + break; + case WAIT_EVENT_LOGICAL_LAUNCHER_MAIN: + event_name = "LogicalLauncherMain"; + break; + case WAIT_EVENT_PGSTAT_MAIN: + event_name = "PgStatMain"; + break; + case WAIT_EVENT_RECOVERY_WAL_STREAM: + event_name = "RecoveryWalStream"; + break; + case WAIT_EVENT_SYSLOGGER_MAIN: + event_name = "SysLoggerMain"; + break; + case WAIT_EVENT_WAL_RECEIVER_MAIN: + event_name = "WalReceiverMain"; + break; + case WAIT_EVENT_WAL_SENDER_MAIN: + event_name = "WalSenderMain"; + break; + case WAIT_EVENT_WAL_WRITER_MAIN: + event_name = "WalWriterMain"; + break; + + /* GPDB additions */ + case WAIT_EVENT_BACKOFF_MAIN: + event_name = "BackoffSweeperMain"; + break; +#ifdef USE_INTERNAL_FTS + case WAIT_EVENT_FTS_PROBE_MAIN: + event_name = "FtsProbeMain"; + break; +#endif + case WAIT_EVENT_GLOBAL_DEADLOCK_DETECTOR_MAIN: + event_name = "GlobalDeadLockDetectorMain"; + break; + /* no default case, so that compiler will warn */ + } + + return event_name; +} + +/* ---------- + * pgstat_get_wait_client() - + * + * Convert WaitEventClient to string. + * ---------- + */ +static const char * +pgstat_get_wait_client(WaitEventClient w) +{ + const char *event_name = "unknown wait event"; + + switch (w) + { + case WAIT_EVENT_CLIENT_READ: + event_name = "ClientRead"; + break; + case WAIT_EVENT_CLIENT_WRITE: + event_name = "ClientWrite"; + break; + case WAIT_EVENT_GSS_OPEN_SERVER: + event_name = "GSSOpenServer"; + break; + case WAIT_EVENT_LIBPQWALRECEIVER_CONNECT: + event_name = "LibPQWalReceiverConnect"; + break; + case WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE: + event_name = "LibPQWalReceiverReceive"; + break; + case WAIT_EVENT_SSL_OPEN_SERVER: + event_name = "SSLOpenServer"; + break; + case WAIT_EVENT_WAL_SENDER_WAIT_WAL: + event_name = "WalSenderWaitForWAL"; + break; + case WAIT_EVENT_WAL_SENDER_WRITE_DATA: + event_name = "WalSenderWriteData"; + break; + /* no default case, so that compiler will warn */ + } + + return event_name; +} + +/* ---------- + * pgstat_get_wait_ipc() - + * + * Convert WaitEventIPC to string. + * ---------- + */ +static const char * +pgstat_get_wait_ipc(WaitEventIPC w) +{ + const char *event_name = "unknown wait event"; + + switch (w) + { + case WAIT_EVENT_APPEND_READY: + event_name = "AppendReady"; + break; + case WAIT_EVENT_BACKEND_TERMINATION: + event_name = "BackendTermination"; + break; + case WAIT_EVENT_BACKUP_WAIT_WAL_ARCHIVE: + event_name = "BackupWaitWalArchive"; + break; + case WAIT_EVENT_BGWORKER_SHUTDOWN: + event_name = "BgWorkerShutdown"; + break; + case WAIT_EVENT_BGWORKER_STARTUP: + event_name = "BgWorkerStartup"; + break; + case WAIT_EVENT_BTREE_PAGE: + event_name = "BtreePage"; + break; + case WAIT_EVENT_BUFFER_IO: + event_name = "BufferIO"; + break; + case WAIT_EVENT_CHECKPOINT_DONE: + event_name = "CheckpointDone"; + break; + case WAIT_EVENT_CHECKPOINT_START: + event_name = "CheckpointStart"; + break; + case WAIT_EVENT_EXECUTE_GATHER: + event_name = "ExecuteGather"; + break; + case WAIT_EVENT_HASH_BATCH_ALLOCATE: + event_name = "HashBatchAllocate"; + break; + case WAIT_EVENT_HASH_BATCH_ELECT: + event_name = "HashBatchElect"; + break; + case WAIT_EVENT_HASH_BATCH_LOAD: + event_name = "HashBatchLoad"; + break; + case WAIT_EVENT_HASH_BUILD_ALLOCATE: + event_name = "HashBuildAllocate"; + break; + case WAIT_EVENT_HASH_BUILD_ELECT: + event_name = "HashBuildElect"; + break; + case WAIT_EVENT_HASH_BUILD_HASH_INNER: + event_name = "HashBuildHashInner"; + break; + case WAIT_EVENT_HASH_BUILD_HASH_OUTER: + event_name = "HashBuildHashOuter"; + break; + case WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATE: + event_name = "HashGrowBatchesAllocate"; + break; + case WAIT_EVENT_HASH_GROW_BATCHES_DECIDE: + event_name = "HashGrowBatchesDecide"; + break; + case WAIT_EVENT_HASH_GROW_BATCHES_ELECT: + event_name = "HashGrowBatchesElect"; + break; + case WAIT_EVENT_HASH_GROW_BATCHES_FINISH: + event_name = "HashGrowBatchesFinish"; + break; + case WAIT_EVENT_HASH_GROW_BATCHES_REPARTITION: + event_name = "HashGrowBatchesRepartition"; + break; + case WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATE: + event_name = "HashGrowBucketsAllocate"; + break; + case WAIT_EVENT_HASH_GROW_BUCKETS_ELECT: + event_name = "HashGrowBucketsElect"; + break; + case WAIT_EVENT_HASH_GROW_BUCKETS_REINSERT: + event_name = "HashGrowBucketsReinsert"; + break; + case WAIT_EVENT_LOGICAL_SYNC_DATA: + event_name = "LogicalSyncData"; + break; + case WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE: + event_name = "LogicalSyncStateChange"; + break; + case WAIT_EVENT_MQ_INTERNAL: + event_name = "MessageQueueInternal"; + break; + case WAIT_EVENT_MQ_PUT_MESSAGE: + event_name = "MessageQueuePutMessage"; + break; + case WAIT_EVENT_MQ_RECEIVE: + event_name = "MessageQueueReceive"; + break; + case WAIT_EVENT_MQ_SEND: + event_name = "MessageQueueSend"; + break; + case WAIT_EVENT_PARALLEL_BITMAP_SCAN: + event_name = "ParallelBitmapScan"; + break; + case WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN: + event_name = "ParallelCreateIndexScan"; + break; + case WAIT_EVENT_PARALLEL_FINISH: + event_name = "ParallelFinish"; + break; + case WAIT_EVENT_PROCARRAY_GROUP_UPDATE: + event_name = "ProcArrayGroupUpdate"; + break; + case WAIT_EVENT_PROC_SIGNAL_BARRIER: + event_name = "ProcSignalBarrier"; + break; + case WAIT_EVENT_PROMOTE: + event_name = "Promote"; + break; + case WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT: + event_name = "RecoveryConflictSnapshot"; + break; + case WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE: + event_name = "RecoveryConflictTablespace"; + break; + case WAIT_EVENT_RECOVERY_PAUSE: + event_name = "RecoveryPause"; + break; + case WAIT_EVENT_REPLICATION_ORIGIN_DROP: + event_name = "ReplicationOriginDrop"; + break; + case WAIT_EVENT_REPLICATION_SLOT_DROP: + event_name = "ReplicationSlotDrop"; + break; + case WAIT_EVENT_SAFE_SNAPSHOT: + event_name = "SafeSnapshot"; + break; + case WAIT_EVENT_SYNC_REP: + event_name = "SyncRep"; + break; + case WAIT_EVENT_WAL_RECEIVER_EXIT: + event_name = "WalReceiverExit"; + break; + case WAIT_EVENT_WAL_RECEIVER_WAIT_START: + event_name = "WalReceiverWaitStart"; + break; + case WAIT_EVENT_XACT_GROUP_UPDATE: + event_name = "XactGroupUpdate"; + break; + + /* GPDB additions */ + case WAIT_EVENT_DTX_RECOVERY: + event_name = "DtxRecovery"; + break; + case WAIT_EVENT_SHAREINPUT_SCAN: + event_name = "ShareInputScan"; + break; + case WAIT_EVENT_INTERCONNECT: + event_name = "Interconnect"; + break; + case WAIT_EVENT_GANG_ASSIGN: + event_name = "Dispatch/Gang-Assign"; + break; + case WAIT_EVENT_DISP_FINISH: + event_name = "Dispatch/Finish"; + break; + case WAIT_EVENT_DISP_RESULT: + event_name = "Dispatch/Result"; + break; + /* no default case, so that compiler will warn */ + } + + return event_name; +} + +/* ---------- + * pgstat_get_wait_timeout() - + * + * Convert WaitEventTimeout to string. + * ---------- + */ +static const char * +pgstat_get_wait_timeout(WaitEventTimeout w) +{ + const char *event_name = "unknown wait event"; + + switch (w) + { + case WAIT_EVENT_BASE_BACKUP_THROTTLE: + event_name = "BaseBackupThrottle"; + break; + case WAIT_EVENT_PG_SLEEP: + event_name = "PgSleep"; + break; + case WAIT_EVENT_RECOVERY_APPLY_DELAY: + event_name = "RecoveryApplyDelay"; + break; + case WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL: + event_name = "RecoveryRetrieveRetryInterval"; + break; + case WAIT_EVENT_VACUUM_DELAY: + event_name = "VacuumDelay"; + break; + /* no default case, so that compiler will warn */ + } + + return event_name; +} + +/* ---------- + * pgstat_get_wait_io() - + * + * Convert WaitEventIO to string. + * ---------- + */ +static const char * +pgstat_get_wait_io(WaitEventIO w) +{ + const char *event_name = "unknown wait event"; + + switch (w) + { + case WAIT_EVENT_BASEBACKUP_READ: + event_name = "BaseBackupRead"; + break; + case WAIT_EVENT_BUFFILE_READ: + event_name = "BufFileRead"; + break; + case WAIT_EVENT_BUFFILE_WRITE: + event_name = "BufFileWrite"; + break; + case WAIT_EVENT_BUFFILE_TRUNCATE: + event_name = "BufFileTruncate"; + break; + case WAIT_EVENT_CONTROL_FILE_READ: + event_name = "ControlFileRead"; + break; + case WAIT_EVENT_CONTROL_FILE_SYNC: + event_name = "ControlFileSync"; + break; + case WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE: + event_name = "ControlFileSyncUpdate"; + break; + case WAIT_EVENT_CONTROL_FILE_WRITE: + event_name = "ControlFileWrite"; + break; + case WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE: + event_name = "ControlFileWriteUpdate"; + break; + case WAIT_EVENT_COPY_FILE_READ: + event_name = "CopyFileRead"; + break; + case WAIT_EVENT_COPY_FILE_WRITE: + event_name = "CopyFileWrite"; + break; + case WAIT_EVENT_DATA_FILE_EXTEND: + event_name = "DataFileExtend"; + break; + case WAIT_EVENT_DATA_FILE_FLUSH: + event_name = "DataFileFlush"; + break; + case WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC: + event_name = "DataFileImmediateSync"; + break; + case WAIT_EVENT_DATA_FILE_PREFETCH: + event_name = "DataFilePrefetch"; + break; + case WAIT_EVENT_DATA_FILE_READ: + event_name = "DataFileRead"; + break; + case WAIT_EVENT_DATA_FILE_SYNC: + event_name = "DataFileSync"; + break; + case WAIT_EVENT_DATA_FILE_TRUNCATE: + event_name = "DataFileTruncate"; + break; + case WAIT_EVENT_DATA_FILE_WRITE: + event_name = "DataFileWrite"; + break; + case WAIT_EVENT_DSM_FILL_ZERO_WRITE: + event_name = "DSMFillZeroWrite"; + break; + case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_READ: + event_name = "LockFileAddToDataDirRead"; + break; + case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_SYNC: + event_name = "LockFileAddToDataDirSync"; + break; + case WAIT_EVENT_LOCK_FILE_ADDTODATADIR_WRITE: + event_name = "LockFileAddToDataDirWrite"; + break; + case WAIT_EVENT_LOCK_FILE_CREATE_READ: + event_name = "LockFileCreateRead"; + break; + case WAIT_EVENT_LOCK_FILE_CREATE_SYNC: + event_name = "LockFileCreateSync"; + break; + case WAIT_EVENT_LOCK_FILE_CREATE_WRITE: + event_name = "LockFileCreateWrite"; + break; + case WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ: + event_name = "LockFileReCheckDataDirRead"; + break; + case WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC: + event_name = "LogicalRewriteCheckpointSync"; + break; + case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC: + event_name = "LogicalRewriteMappingSync"; + break; + case WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE: + event_name = "LogicalRewriteMappingWrite"; + break; + case WAIT_EVENT_LOGICAL_REWRITE_SYNC: + event_name = "LogicalRewriteSync"; + break; + case WAIT_EVENT_LOGICAL_REWRITE_TRUNCATE: + event_name = "LogicalRewriteTruncate"; + break; + case WAIT_EVENT_LOGICAL_REWRITE_WRITE: + event_name = "LogicalRewriteWrite"; + break; + case WAIT_EVENT_RELATION_MAP_READ: + event_name = "RelationMapRead"; + break; + case WAIT_EVENT_RELATION_MAP_SYNC: + event_name = "RelationMapSync"; + break; + case WAIT_EVENT_RELATION_MAP_WRITE: + event_name = "RelationMapWrite"; + break; + case WAIT_EVENT_REORDER_BUFFER_READ: + event_name = "ReorderBufferRead"; + break; + case WAIT_EVENT_REORDER_BUFFER_WRITE: + event_name = "ReorderBufferWrite"; + break; + case WAIT_EVENT_REORDER_LOGICAL_MAPPING_READ: + event_name = "ReorderLogicalMappingRead"; + break; + case WAIT_EVENT_REPLICATION_SLOT_READ: + event_name = "ReplicationSlotRead"; + break; + case WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC: + event_name = "ReplicationSlotRestoreSync"; + break; + case WAIT_EVENT_REPLICATION_SLOT_SYNC: + event_name = "ReplicationSlotSync"; + break; + case WAIT_EVENT_REPLICATION_SLOT_WRITE: + event_name = "ReplicationSlotWrite"; + break; + case WAIT_EVENT_SLRU_FLUSH_SYNC: + event_name = "SLRUFlushSync"; + break; + case WAIT_EVENT_SLRU_READ: + event_name = "SLRURead"; + break; + case WAIT_EVENT_SLRU_SYNC: + event_name = "SLRUSync"; + break; + case WAIT_EVENT_SLRU_WRITE: + event_name = "SLRUWrite"; + break; + case WAIT_EVENT_SNAPBUILD_READ: + event_name = "SnapbuildRead"; + break; + case WAIT_EVENT_SNAPBUILD_SYNC: + event_name = "SnapbuildSync"; + break; + case WAIT_EVENT_SNAPBUILD_WRITE: + event_name = "SnapbuildWrite"; + break; + case WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC: + event_name = "TimelineHistoryFileSync"; + break; + case WAIT_EVENT_TIMELINE_HISTORY_FILE_WRITE: + event_name = "TimelineHistoryFileWrite"; + break; + case WAIT_EVENT_TIMELINE_HISTORY_READ: + event_name = "TimelineHistoryRead"; + break; + case WAIT_EVENT_TIMELINE_HISTORY_SYNC: + event_name = "TimelineHistorySync"; + break; + case WAIT_EVENT_TIMELINE_HISTORY_WRITE: + event_name = "TimelineHistoryWrite"; + break; + case WAIT_EVENT_TWOPHASE_FILE_READ: + event_name = "TwophaseFileRead"; + break; + case WAIT_EVENT_TWOPHASE_FILE_SYNC: + event_name = "TwophaseFileSync"; + break; + case WAIT_EVENT_TWOPHASE_FILE_WRITE: + event_name = "TwophaseFileWrite"; + break; + case WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ: + event_name = "WALSenderTimelineHistoryRead"; + break; + case WAIT_EVENT_WAL_BOOTSTRAP_SYNC: + event_name = "WALBootstrapSync"; + break; + case WAIT_EVENT_WAL_BOOTSTRAP_WRITE: + event_name = "WALBootstrapWrite"; + break; + case WAIT_EVENT_WAL_COPY_READ: + event_name = "WALCopyRead"; + break; + case WAIT_EVENT_WAL_COPY_SYNC: + event_name = "WALCopySync"; + break; + case WAIT_EVENT_WAL_COPY_WRITE: + event_name = "WALCopyWrite"; + break; + case WAIT_EVENT_WAL_INIT_SYNC: + event_name = "WALInitSync"; + break; + case WAIT_EVENT_WAL_INIT_WRITE: + event_name = "WALInitWrite"; + break; + case WAIT_EVENT_WAL_READ: + event_name = "WALRead"; + break; + case WAIT_EVENT_WAL_SYNC: + event_name = "WALSync"; + break; + case WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN: + event_name = "WALSyncMethodAssign"; + break; + case WAIT_EVENT_WAL_WRITE: + event_name = "WALWrite"; + break; + case WAIT_EVENT_LOGICAL_CHANGES_READ: + event_name = "LogicalChangesRead"; + break; + case WAIT_EVENT_LOGICAL_CHANGES_WRITE: + event_name = "LogicalChangesWrite"; + break; + case WAIT_EVENT_LOGICAL_SUBXACT_READ: + event_name = "LogicalSubxactRead"; + break; + case WAIT_EVENT_LOGICAL_SUBXACT_WRITE: + event_name = "LogicalSubxactWrite"; + break; + + /* no default case, so that compiler will warn */ + } + + return event_name; +} diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 6f18b06ca4b8..bd5479c546bb 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -9,6 +9,8 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) +override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) + # keep this list arranged alphabetically or it gets to be a mess OBJS = \ acl.o \ @@ -18,12 +20,13 @@ OBJS = \ array_typanalyze.o \ array_userfuncs.o \ arrayfuncs.o \ + arraysubs.o \ arrayutils.o \ ascii.o \ bool.o \ cash.o \ char.o \ - cryptohashes.o \ + cryptohashfuncs.o \ date.o \ datetime.o \ datum.o \ @@ -50,6 +53,7 @@ OBJS = \ jsonb_op.o \ jsonb_util.o \ jsonfuncs.o \ + jsonbsubs.o \ jsonpath.o \ jsonpath_exec.o \ jsonpath_gram.o \ @@ -58,7 +62,10 @@ OBJS = \ lockfuncs.o \ mac.o \ mac8.o \ + mcxtfuncs.o \ misc.o \ + multirangetypes.o \ + multirangetypes_selfuncs.o \ name.o \ network.o \ network_gist.o \ @@ -125,6 +132,9 @@ clean distclean maintainer-clean: like.o: like.c like_match.c +# Some code in numeric.c benefits from auto-vectorization +numeric.o: CFLAGS += ${CFLAGS_VECTORIZE} + varlena.o: varlena.c levenshtein.c # GPDB additions diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 5ead3dc88e7c..ef8478c36dad 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -3,7 +3,7 @@ * acl.c * Basic access control list data structures manipulation routines. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,6 +22,7 @@ #include "catalog/pg_auth_members.h" #include "catalog/pg_authid.h" #include "catalog/pg_class.h" +#include "catalog/pg_database.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" #include "commands/proclang.h" @@ -52,33 +53,25 @@ typedef struct /* * We frequently need to test whether a given role is a member of some other * role. In most of these tests the "given role" is the same, namely the - * active current user. So we can optimize it by keeping a cached list of - * all the roles the "given role" is a member of, directly or indirectly. - * The cache is flushed whenever we detect a change in pg_auth_members. - * - * There are actually two caches, one computed under "has_privs" rules - * (do not recurse where rolinherit isn't true) and one computed under - * "is_member" rules (recurse regardless of rolinherit). + * active current user. So we can optimize it by keeping cached lists of all + * the roles the "given role" is a member of, directly or indirectly. * * Possibly this mechanism should be generalized to allow caching membership * info for multiple roles? * - * The has_privs cache is: - * cached_privs_role is the role OID the cache is for. - * cached_privs_roles is an OID list of roles that cached_privs_role - * has the privileges of (always including itself). - * The cache is valid if cached_privs_role is not InvalidOid. - * - * The is_member cache is similarly: - * cached_member_role is the role OID the cache is for. - * cached_membership_roles is an OID list of roles that cached_member_role - * is a member of (always including itself). - * The cache is valid if cached_member_role is not InvalidOid. + * Each element of cached_roles is an OID list of constituent roles for the + * corresponding element of cached_role (always including the cached_role + * itself). One cache has ROLERECURSE_PRIVS semantics, and the other has + * ROLERECURSE_MEMBERS semantics. */ -static Oid cached_privs_role = InvalidOid; -static List *cached_privs_roles = NIL; -static Oid cached_member_role = InvalidOid; -static List *cached_membership_roles = NIL; +enum RoleRecurseType +{ + ROLERECURSE_PRIVS = 0, /* recurse if rolinherit */ + ROLERECURSE_MEMBERS = 1 /* recurse unconditionally */ +}; +static Oid cached_role[] = {InvalidOid, InvalidOid}; +static List *cached_roles[] = {NIL, NIL}; +static uint32 cached_db_hash; static const char *getid(const char *s, char *n); @@ -2545,8 +2538,7 @@ column_privilege_check(Oid tableoid, AttrNumber attnum, Oid roleid, AclMode mode) { AclResult aclresult; - HeapTuple attTuple; - Form_pg_attribute attributeForm; + bool is_missing = false; /* * If convert_column_name failed, we can just return -1 immediately. @@ -2555,42 +2547,25 @@ column_privilege_check(Oid tableoid, AttrNumber attnum, return -1; /* - * First check if we have the privilege at the table level. We check - * existence of the pg_class row before risking calling pg_class_aclcheck. - * Note: it might seem there's a race condition against concurrent DROP, - * but really it's safe because there will be no syscache flush between - * here and there. So if we see the row in the syscache, so will - * pg_class_aclcheck. + * Check for column-level privileges first. This serves in part as a check + * on whether the column even exists, so we need to do it before checking + * table-level privilege. */ - if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(tableoid))) + aclresult = pg_attribute_aclcheck_ext(tableoid, attnum, roleid, + mode, &is_missing); + if (aclresult == ACLCHECK_OK) + return 1; + else if (is_missing) return -1; - aclresult = pg_class_aclcheck(tableoid, roleid, mode); - + /* Next check if we have the privilege at the table level */ + aclresult = pg_class_aclcheck_ext(tableoid, roleid, mode, &is_missing); if (aclresult == ACLCHECK_OK) - return true; - - /* - * No table privilege, so try per-column privileges. Again, we have to - * check for dropped attribute first, and we rely on the syscache not to - * notice a concurrent drop before pg_attribute_aclcheck fetches the row. - */ - attTuple = SearchSysCache2(ATTNUM, - ObjectIdGetDatum(tableoid), - Int16GetDatum(attnum)); - if (!HeapTupleIsValid(attTuple)) - return -1; - attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple); - if (attributeForm->attisdropped) - { - ReleaseSysCache(attTuple); + return 1; + else if (is_missing) return -1; - } - ReleaseSysCache(attTuple); - - aclresult = pg_attribute_aclcheck(tableoid, attnum, roleid, mode); - - return (aclresult == ACLCHECK_OK); + else + return 0; } /* @@ -4822,13 +4797,24 @@ initialize_acl(void) { if (!IsBootstrapProcessingMode()) { + cached_db_hash = + GetSysCacheHashValue1(DATABASEOID, + ObjectIdGetDatum(MyDatabaseId)); + /* - * In normal mode, set a callback on any syscache invalidation of - * pg_auth_members rows + * In normal mode, set a callback on any syscache invalidation of rows + * of pg_auth_members (for roles_is_member_of()), pg_authid (for + * has_rolinherit()), or pg_database (for roles_is_member_of()) */ CacheRegisterSyscacheCallback(AUTHMEMROLEMEM, RoleMembershipCacheCallback, (Datum) 0); + CacheRegisterSyscacheCallback(AUTHOID, + RoleMembershipCacheCallback, + (Datum) 0); + CacheRegisterSyscacheCallback(DATABASEOID, + RoleMembershipCacheCallback, + (Datum) 0); } } @@ -4839,9 +4825,16 @@ initialize_acl(void) static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue) { + if (cacheid == DATABASEOID && + hashvalue != cached_db_hash && + hashvalue != 0) + { + return; /* ignore pg_database changes for other DBs */ + } + /* Force membership caches to be recomputed on next use */ - cached_privs_role = InvalidOid; - cached_member_role = InvalidOid; + cached_role[ROLERECURSE_PRIVS] = InvalidOid; + cached_role[ROLERECURSE_MEMBERS] = InvalidOid; } @@ -4863,114 +4856,55 @@ has_rolinherit(Oid roleid) /* - * Get a list of roles that the specified roleid has the privileges of + * Get a list of roles that the specified roleid is a member of * - * This is defined not to recurse through roles that don't have rolinherit - * set; for such roles, membership implies the ability to do SET ROLE, but - * the privileges are not available until you've done so. + * Type ROLERECURSE_PRIVS recurses only through roles that have rolinherit + * set, while ROLERECURSE_MEMBERS recurses through all roles. This sets + * *is_admin==true if and only if role "roleid" has an ADMIN OPTION membership + * in role "admin_of". * * Since indirect membership testing is relatively expensive, we cache * a list of memberships. Hence, the result is only guaranteed good until - * the next call of roles_has_privs_of()! + * the next call of roles_is_member_of()! * * For the benefit of select_best_grantor, the result is defined to be * in breadth-first order, ie, closer relationships earlier. */ static List * -roles_has_privs_of(Oid roleid) +roles_is_member_of(Oid roleid, enum RoleRecurseType type, + Oid admin_of, bool *is_admin) { + Oid dba; List *roles_list; ListCell *l; - List *new_cached_privs_roles; + List *new_cached_roles; MemoryContext oldctx; - /* If cache is already valid, just return the list */ - if (OidIsValid(cached_privs_role) && cached_privs_role == roleid) - return cached_privs_roles; + Assert(OidIsValid(admin_of) == PointerIsValid(is_admin)); + + /* If cache is valid and ADMIN OPTION not sought, just return the list */ + if (cached_role[type] == roleid && !OidIsValid(admin_of) && + OidIsValid(cached_role[type])) + return cached_roles[type]; /* - * Find all the roles that roleid is a member of, including multi-level - * recursion. The role itself will always be the first element of the - * resulting list. - * - * Each element of the list is scanned to see if it adds any indirect - * memberships. We can use a single list as both the record of - * already-found memberships and the agenda of roles yet to be scanned. - * This is a bit tricky but works because the foreach() macro doesn't - * fetch the next list element until the bottom of the loop. + * Role expansion happens in a non-database backend when guc.c checks + * ROLE_PG_READ_ALL_SETTINGS for a physical walsender SHOW command. In + * that case, no role gets pg_database_owner. */ - roles_list = list_make1_oid(roleid); - - foreach(l, roles_list) + if (!OidIsValid(MyDatabaseId)) + dba = InvalidOid; + else { - Oid memberid = lfirst_oid(l); - CatCList *memlist; - int i; - - /* Ignore non-inheriting roles */ - if (!has_rolinherit(memberid)) - continue; + HeapTuple dbtup; - /* Find roles that memberid is directly a member of */ - memlist = SearchSysCacheList1(AUTHMEMMEMROLE, - ObjectIdGetDatum(memberid)); - for (i = 0; i < memlist->n_members; i++) - { - HeapTuple tup = &memlist->members[i]->tuple; - Oid otherid = ((Form_pg_auth_members) GETSTRUCT(tup))->roleid; - - /* - * Even though there shouldn't be any loops in the membership - * graph, we must test for having already seen this role. It is - * legal for instance to have both A->B and A->C->B. - */ - roles_list = list_append_unique_oid(roles_list, otherid); - } - ReleaseSysCacheList(memlist); + dbtup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId)); + if (!HeapTupleIsValid(dbtup)) + elog(ERROR, "cache lookup failed for database %u", MyDatabaseId); + dba = ((Form_pg_database) GETSTRUCT(dbtup))->datdba; + ReleaseSysCache(dbtup); } - /* - * Copy the completed list into TopMemoryContext so it will persist. - */ - oldctx = MemoryContextSwitchTo(TopMemoryContext); - new_cached_privs_roles = list_copy(roles_list); - MemoryContextSwitchTo(oldctx); - list_free(roles_list); - - /* - * Now safe to assign to state variable - */ - cached_privs_role = InvalidOid; /* just paranoia */ - list_free(cached_privs_roles); - cached_privs_roles = new_cached_privs_roles; - cached_privs_role = roleid; - - /* And now we can return the answer */ - return cached_privs_roles; -} - - -/* - * Get a list of roles that the specified roleid is a member of - * - * This is defined to recurse through roles regardless of rolinherit. - * - * Since indirect membership testing is relatively expensive, we cache - * a list of memberships. Hence, the result is only guaranteed good until - * the next call of roles_is_member_of()! - */ -static List * -roles_is_member_of(Oid roleid) -{ - List *roles_list; - ListCell *l; - List *new_cached_membership_roles; - MemoryContext oldctx; - - /* If cache is already valid, just return the list */ - if (OidIsValid(cached_member_role) && cached_member_role == roleid) - return cached_membership_roles; - /* * Find all the roles that roleid is a member of, including multi-level * recursion. The role itself will always be the first element of the @@ -4990,6 +4924,9 @@ roles_is_member_of(Oid roleid) CatCList *memlist; int i; + if (type == ROLERECURSE_PRIVS && !has_rolinherit(memberid)) + continue; /* ignore non-inheriting roles */ + /* Find roles that memberid is directly a member of */ memlist = SearchSysCacheList1(AUTHMEMMEMROLE, ObjectIdGetDatum(memberid)); @@ -4998,6 +4935,15 @@ roles_is_member_of(Oid roleid) HeapTuple tup = &memlist->members[i]->tuple; Oid otherid = ((Form_pg_auth_members) GETSTRUCT(tup))->roleid; + /* + * While otherid==InvalidOid shouldn't appear in the catalog, the + * OidIsValid() avoids crashing if that arises. + */ + if (otherid == admin_of && + ((Form_pg_auth_members) GETSTRUCT(tup))->admin_option && + OidIsValid(admin_of)) + *is_admin = true; + /* * Even though there shouldn't be any loops in the membership * graph, we must test for having already seen this role. It is @@ -5006,26 +4952,31 @@ roles_is_member_of(Oid roleid) roles_list = list_append_unique_oid(roles_list, otherid); } ReleaseSysCacheList(memlist); + + /* implement pg_database_owner implicit membership */ + if (memberid == dba && OidIsValid(dba)) + roles_list = list_append_unique_oid(roles_list, + ROLE_PG_DATABASE_OWNER); } /* * Copy the completed list into TopMemoryContext so it will persist. */ oldctx = MemoryContextSwitchTo(TopMemoryContext); - new_cached_membership_roles = list_copy(roles_list); + new_cached_roles = list_copy(roles_list); MemoryContextSwitchTo(oldctx); list_free(roles_list); /* * Now safe to assign to state variable */ - cached_member_role = InvalidOid; /* just paranoia */ - list_free(cached_membership_roles); - cached_membership_roles = new_cached_membership_roles; - cached_member_role = roleid; + cached_role[type] = InvalidOid; /* just paranoia */ + list_free(cached_roles[type]); + cached_roles[type] = new_cached_roles; + cached_role[type] = roleid; /* And now we can return the answer */ - return cached_membership_roles; + return cached_roles[type]; } @@ -5051,7 +5002,9 @@ has_privs_of_role(Oid member, Oid role) * Find all the roles that member has the privileges of, including * multi-level recursion, then see if target role is any one of them. */ - return list_member_oid(roles_has_privs_of(member), role); + return list_member_oid(roles_is_member_of(member, ROLERECURSE_PRIVS, + InvalidOid, NULL), + role); } @@ -5075,7 +5028,9 @@ is_member_of_role(Oid member, Oid role) * Find all the roles that member is a member of, including multi-level * recursion, then see if target role is any one of them. */ - return list_member_oid(roles_is_member_of(member), role); + return list_member_oid(roles_is_member_of(member, ROLERECURSE_MEMBERS, + InvalidOid, NULL), + role); } /* @@ -5109,7 +5064,9 @@ is_member_of_role_nosuper(Oid member, Oid role) * Find all the roles that member is a member of, including multi-level * recursion, then see if target role is any one of them. */ - return list_member_oid(roles_is_member_of(member), role); + return list_member_oid(roles_is_member_of(member, ROLERECURSE_MEMBERS, + InvalidOid, NULL), + role); } @@ -5122,8 +5079,6 @@ bool is_admin_of_role(Oid member, Oid role) { bool result = false; - List *roles_list; - ListCell *l; if (superuser_arg(member)) return true; @@ -5161,44 +5116,7 @@ is_admin_of_role(Oid member, Oid role) return member == GetSessionUserId() && !InLocalUserIdChange() && !InSecurityRestrictedOperation(); - /* - * Find all the roles that member is a member of, including multi-level - * recursion. We build a list in the same way that is_member_of_role does - * to track visited and unvisited roles. - */ - roles_list = list_make1_oid(member); - - foreach(l, roles_list) - { - Oid memberid = lfirst_oid(l); - CatCList *memlist; - int i; - - /* Find roles that memberid is directly a member of */ - memlist = SearchSysCacheList1(AUTHMEMMEMROLE, - ObjectIdGetDatum(memberid)); - for (i = 0; i < memlist->n_members; i++) - { - HeapTuple tup = &memlist->members[i]->tuple; - Oid otherid = ((Form_pg_auth_members) GETSTRUCT(tup))->roleid; - - if (otherid == role && - ((Form_pg_auth_members) GETSTRUCT(tup))->admin_option) - { - /* Found what we came for, so can stop searching */ - result = true; - break; - } - - roles_list = list_append_unique_oid(roles_list, otherid); - } - ReleaseSysCacheList(memlist); - if (result) - break; - } - - list_free(roles_list); - + (void) roles_is_member_of(member, ROLERECURSE_MEMBERS, role, &result); return result; } @@ -5270,10 +5188,11 @@ select_best_grantor(Oid roleId, AclMode privileges, /* * Otherwise we have to do a careful search to see if roleId has the * privileges of any suitable role. Note: we can hang onto the result of - * roles_has_privs_of() throughout this loop, because aclmask_direct() + * roles_is_member_of() throughout this loop, because aclmask_direct() * doesn't query any role memberships. */ - roles_list = roles_has_privs_of(roleId); + roles_list = roles_is_member_of(roleId, ROLERECURSE_PRIVS, + InvalidOid, NULL); /* initialize candidate result as default */ *grantorId = roleId; @@ -5365,6 +5284,7 @@ get_rolespec_oid(const RoleSpec *role, bool missing_ok) oid = get_role_oid(role->rolename, missing_ok); break; + case ROLESPEC_CURRENT_ROLE: case ROLESPEC_CURRENT_USER: oid = GetUserId(); break; @@ -5407,6 +5327,7 @@ get_rolespec_tuple(const RoleSpec *role) errmsg("role \"%s\" does not exist", role->rolename))); break; + case ROLESPEC_CURRENT_ROLE: case ROLESPEC_CURRENT_USER: tuple = SearchSysCache1(AUTHOID, GetUserId()); if (!HeapTupleIsValid(tuple)) diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c index 220cd8fc52fe..569412fcacf5 100644 --- a/src/backend/utils/adt/amutils.c +++ b/src/backend/utils/adt/amutils.c @@ -3,7 +3,7 @@ * amutils.c * SQL-level APIs related to index access methods. * - * Copyright (c) 2016-2020, PostgreSQL Global Development Group + * Copyright (c) 2016-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/array_expanded.c b/src/backend/utils/adt/array_expanded.c index 18de2dd352f6..60511f639d36 100644 --- a/src/backend/utils/adt/array_expanded.c +++ b/src/backend/utils/adt/array_expanded.c @@ -3,7 +3,7 @@ * array_expanded.c * Basic functions for manipulating expanded arrays. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/array_selfuncs.c b/src/backend/utils/adt/array_selfuncs.c index d97e60a3ab5b..23de5d922644 100644 --- a/src/backend/utils/adt/array_selfuncs.c +++ b/src/backend/utils/adt/array_selfuncs.c @@ -3,7 +3,7 @@ * array_selfuncs.c * Functions for selectivity estimation of array operators * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/array_typanalyze.c b/src/backend/utils/adt/array_typanalyze.c index 4912cabc6176..c5008a0c1691 100644 --- a/src/backend/utils/adt/array_typanalyze.c +++ b/src/backend/utils/adt/array_typanalyze.c @@ -3,7 +3,7 @@ * array_typanalyze.c * Functions for gathering statistics from array columns * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -277,7 +277,6 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, * worry about overflowing the initial size. Also we don't need to pay any * attention to locking and memory management. */ - MemSet(&elem_hash_ctl, 0, sizeof(elem_hash_ctl)); elem_hash_ctl.keysize = sizeof(Datum); elem_hash_ctl.entrysize = sizeof(TrackItem); elem_hash_ctl.hash = element_hash; @@ -289,7 +288,6 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_CONTEXT); /* hashtable for array distinct elements counts */ - MemSet(&count_hash_ctl, 0, sizeof(count_hash_ctl)); count_hash_ctl.keysize = sizeof(int); count_hash_ctl.entrysize = sizeof(DECountItem); count_hash_ctl.hcxt = CurrentMemoryContext; diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c index 38d294788028..c421ce509886 100644 --- a/src/backend/utils/adt/array_userfuncs.c +++ b/src/backend/utils/adt/array_userfuncs.c @@ -3,7 +3,7 @@ * array_userfuncs.c * Misc user-visible array support functions * - * Copyright (c) 2003-2020, PostgreSQL Global Development Group + * Copyright (c) 2003-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/array_userfuncs.c @@ -432,6 +432,7 @@ array_cat(PG_FUNCTION_ARGS) /* Do this mainly for overflow checking */ nitems = ArrayGetNItems(ndims, dims); + ArrayCheckBounds(ndims, dims, lbs); /* build the result array */ ndatabytes = ndatabytes1 + ndatabytes2; diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 62d886e00209..e6d9d7914c02 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -3,7 +3,7 @@ * arrayfuncs.c * Support functions for arrays. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -374,6 +374,8 @@ array_in(PG_FUNCTION_ARGS) /* This checks for overflow of the array dimensions */ nitems = ArrayGetNItems(ndim, dim); + ArrayCheckBounds(ndim, dim, lBound); + /* Empty array? */ if (nitems == 0) PG_RETURN_ARRAYTYPE_P(construct_empty_array(element_type)); @@ -1344,24 +1346,11 @@ array_recv(PG_FUNCTION_ARGS) { dim[i] = pq_getmsgint(buf, 4); lBound[i] = pq_getmsgint(buf, 4); - - /* - * Check overflow of upper bound. (ArrayGetNItems() below checks that - * dim[i] >= 0) - */ - if (dim[i] != 0) - { - int ub = lBound[i] + dim[i] - 1; - - if (lBound[i] > ub) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("integer out of range"))); - } } /* This checks for overflow of array dimensions */ nitems = ArrayGetNItems(ndim, dim); + ArrayCheckBounds(ndim, dim, lBound); /* * We arrange to look up info about element type, including its receive @@ -2046,7 +2035,8 @@ array_get_element_expanded(Datum arraydatum, * array bound. * * NOTE: we assume it is OK to scribble on the provided subscript arrays - * lowerIndx[] and upperIndx[]. These are generally just temporaries. + * lowerIndx[] and upperIndx[]; also, these arrays must be of size MAXDIM + * even when nSubscripts is less. These are generally just temporaries. */ Datum array_get_slice(Datum arraydatum, @@ -2266,7 +2256,7 @@ array_set_element(Datum arraydatum, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("wrong number of array subscripts"))); - if (indx[0] < 0 || indx[0] * elmlen >= arraytyplen) + if (indx[0] < 0 || indx[0] >= arraytyplen / elmlen) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("array subscript out of range"))); @@ -2381,10 +2371,13 @@ array_set_element(Datum arraydatum, } } + /* This checks for overflow of the array dimensions */ + newnitems = ArrayGetNItems(ndim, dim); + ArrayCheckBounds(ndim, dim, lb); + /* * Compute sizes of items and areas to copy */ - newnitems = ArrayGetNItems(ndim, dim); if (newhasnulls) overheadlen = ARR_OVERHEAD_WITHNULLS(ndim, newnitems); else @@ -2583,8 +2576,11 @@ array_set_element_expanded(Datum arraydatum, /* * Copy new element into array's context, if needed (we assume it's - * already detoasted, so no junk should be created). If we fail further - * down, this memory is leaked, but that's reasonably harmless. + * already detoasted, so no junk should be created). Doing this before + * we've made any significant changes ensures that our behavior is sane + * even when the source is a reference to some element of this same array. + * If we fail further down, this memory is leaked, but that's reasonably + * harmless. */ if (!eah->typbyval && !isNull) { @@ -2639,6 +2635,13 @@ array_set_element_expanded(Datum arraydatum, } } + /* Check for overflow of the array dimensions */ + if (dimschanged) + { + (void) ArrayGetNItems(ndim, dim); + ArrayCheckBounds(ndim, dim, lb); + } + /* Now we can calculate linear offset of target item in array */ offset = ArrayGetOffset(nSubscripts, dim, lb, indx); @@ -2774,7 +2777,8 @@ array_set_element_expanded(Datum arraydatum, * (XXX TODO: allow a corresponding behavior for multidimensional arrays) * * NOTE: we assume it is OK to scribble on the provided index arrays - * lowerIndx[] and upperIndx[]. These are generally just temporaries. + * lowerIndx[] and upperIndx[]; also, these arrays must be of size MAXDIM + * even when nSubscripts is less. These are generally just temporaries. * * NOTE: For assignments, we throw an error for silly subscripts etc, * rather than returning a NULL or empty array as the fetch operations do. @@ -2957,6 +2961,7 @@ array_set_slice(Datum arraydatum, /* Do this mainly to check for overflow */ nitems = ArrayGetNItems(ndim, dim); + ArrayCheckBounds(ndim, dim, lb); /* * Make sure source array has enough entries. Note we ignore the shape of @@ -3377,7 +3382,9 @@ construct_md_array(Datum *elems, errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", ndims, MAXDIM))); + /* This checks for overflow of the array dimensions */ nelems = ArrayGetNItems(ndims, dims); + ArrayCheckBounds(ndims, dims, lbs); /* if ndims <= 0 or any dims[i] == 0, return empty array */ if (nelems <= 0) @@ -4122,7 +4129,7 @@ hash_array_extended(PG_FUNCTION_ARGS) typalign = typentry->typalign; InitFunctionCallInfoData(*locfcinfo, &typentry->hash_extended_proc_finfo, 2, - InvalidOid, NULL, NULL); + PG_GET_COLLATION(), NULL, NULL); /* Loop over source data */ nitems = ArrayGetNItems(ndims, dims); @@ -5513,6 +5520,10 @@ makeArrayResultArr(ArrayBuildStateArr *astate, int dataoffset, nbytes; + /* Check for overflow of the array dimensions */ + (void) ArrayGetNItems(astate->ndims, astate->dims); + ArrayCheckBounds(astate->ndims, astate->dims, astate->lbs); + /* Compute required space */ nbytes = astate->nbytes; if (astate->nullbitmap != NULL) @@ -5942,7 +5953,9 @@ array_fill_internal(ArrayType *dims, ArrayType *lbs, lbsv = deflbs; } + /* This checks for overflow of the array dimensions */ nitems = ArrayGetNItems(ndims, dimv); + ArrayCheckBounds(ndims, dimv, lbsv); /* fast track for empty array */ if (nitems <= 0) @@ -6695,3 +6708,46 @@ width_bucket_array_variable(Datum operand, return left; } + +/* + * Trim the last N elements from an array by building an appropriate slice. + * Only the first dimension is trimmed. + */ +Datum +trim_array(PG_FUNCTION_ARGS) +{ + ArrayType *v = PG_GETARG_ARRAYTYPE_P(0); + int n = PG_GETARG_INT32(1); + int array_length = ARR_DIMS(v)[0]; + int16 elmlen; + bool elmbyval; + char elmalign; + int lower[MAXDIM]; + int upper[MAXDIM]; + bool lowerProvided[MAXDIM]; + bool upperProvided[MAXDIM]; + Datum result; + + /* Per spec, throw an error if out of bounds */ + if (n < 0 || n > array_length) + ereport(ERROR, + (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), + errmsg("number of elements to trim must be between 0 and %d", + array_length))); + + /* Set all the bounds as unprovided except the first upper bound */ + memset(lowerProvided, false, sizeof(lowerProvided)); + memset(upperProvided, false, sizeof(upperProvided)); + upper[0] = ARR_LBOUND(v)[0] + array_length - n - 1; + upperProvided[0] = true; + + /* Fetch the needed information about the element type */ + get_typlenbyvalalign(ARR_ELEMTYPE(v), &elmlen, &elmbyval, &elmalign); + + /* Get the slice */ + result = array_get_slice(PointerGetDatum(v), 1, + upper, lower, upperProvided, lowerProvided, + -1, elmlen, elmbyval, elmalign); + + PG_RETURN_DATUM(result); +} diff --git a/src/backend/utils/adt/arraysubs.c b/src/backend/utils/adt/arraysubs.c new file mode 100644 index 000000000000..1d910d14dbc9 --- /dev/null +++ b/src/backend/utils/adt/arraysubs.c @@ -0,0 +1,577 @@ +/*------------------------------------------------------------------------- + * + * arraysubs.c + * Subscripting support functions for arrays. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/adt/arraysubs.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "executor/execExpr.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "nodes/subscripting.h" +#include "parser/parse_coerce.h" +#include "parser/parse_expr.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "utils/lsyscache.h" + + +/* SubscriptingRefState.workspace for array subscripting execution */ +typedef struct ArraySubWorkspace +{ + /* Values determined during expression compilation */ + Oid refelemtype; /* OID of the array element type */ + int16 refattrlength; /* typlen of array type */ + int16 refelemlength; /* typlen of the array element type */ + bool refelembyval; /* is the element type pass-by-value? */ + char refelemalign; /* typalign of the element type */ + + /* + * Subscript values converted to integers. Note that these arrays must be + * of length MAXDIM even when dealing with fewer subscripts, because + * array_get/set_slice may scribble on the extra entries. + */ + int upperindex[MAXDIM]; + int lowerindex[MAXDIM]; +} ArraySubWorkspace; + + +/* + * Finish parse analysis of a SubscriptingRef expression for an array. + * + * Transform the subscript expressions, coerce them to integers, + * and determine the result type of the SubscriptingRef node. + */ +static void +array_subscript_transform(SubscriptingRef *sbsref, + List *indirection, + ParseState *pstate, + bool isSlice, + bool isAssignment) +{ + List *upperIndexpr = NIL; + List *lowerIndexpr = NIL; + ListCell *idx; + + /* + * Transform the subscript expressions, and separate upper and lower + * bounds into two lists. + * + * If we have a container slice expression, we convert any non-slice + * indirection items to slices by treating the single subscript as the + * upper bound and supplying an assumed lower bound of 1. + */ + foreach(idx, indirection) + { + A_Indices *ai = lfirst_node(A_Indices, idx); + Node *subexpr; + + if (isSlice) + { + if (ai->lidx) + { + subexpr = transformExpr(pstate, ai->lidx, pstate->p_expr_kind); + /* If it's not int4 already, try to coerce */ + subexpr = coerce_to_target_type(pstate, + subexpr, exprType(subexpr), + INT4OID, -1, + COERCION_ASSIGNMENT, + COERCE_IMPLICIT_CAST, + -1); + if (subexpr == NULL) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("array subscript must have type integer"), + parser_errposition(pstate, exprLocation(ai->lidx)))); + } + else if (!ai->is_slice) + { + /* Make a constant 1 */ + subexpr = (Node *) makeConst(INT4OID, + -1, + InvalidOid, + sizeof(int32), + Int32GetDatum(1), + false, + true); /* pass by value */ + } + else + { + /* Slice with omitted lower bound, put NULL into the list */ + subexpr = NULL; + } + lowerIndexpr = lappend(lowerIndexpr, subexpr); + } + else + Assert(ai->lidx == NULL && !ai->is_slice); + + if (ai->uidx) + { + subexpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind); + /* If it's not int4 already, try to coerce */ + subexpr = coerce_to_target_type(pstate, + subexpr, exprType(subexpr), + INT4OID, -1, + COERCION_ASSIGNMENT, + COERCE_IMPLICIT_CAST, + -1); + if (subexpr == NULL) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("array subscript must have type integer"), + parser_errposition(pstate, exprLocation(ai->uidx)))); + } + else + { + /* Slice with omitted upper bound, put NULL into the list */ + Assert(isSlice && ai->is_slice); + subexpr = NULL; + } + upperIndexpr = lappend(upperIndexpr, subexpr); + } + + /* ... and store the transformed lists into the SubscriptRef node */ + sbsref->refupperindexpr = upperIndexpr; + sbsref->reflowerindexpr = lowerIndexpr; + + /* Verify subscript list lengths are within implementation limit */ + if (list_length(upperIndexpr) > MAXDIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", + list_length(upperIndexpr), MAXDIM))); + /* We need not check lowerIndexpr separately */ + + /* + * Determine the result type of the subscripting operation. It's the same + * as the array type if we're slicing, else it's the element type. In + * either case, the typmod is the same as the array's, so we need not + * change reftypmod. + */ + if (isSlice) + sbsref->refrestype = sbsref->refcontainertype; + else + sbsref->refrestype = sbsref->refelemtype; +} + +/* + * During execution, process the subscripts in a SubscriptingRef expression. + * + * The subscript expressions are already evaluated in Datum form in the + * SubscriptingRefState's arrays. Check and convert them as necessary. + * + * If any subscript is NULL, we throw error in assignment cases, or in fetch + * cases set result to NULL and return false (instructing caller to skip the + * rest of the SubscriptingRef sequence). + * + * We convert all the subscripts to plain integers and save them in the + * sbsrefstate->workspace arrays. + */ +static bool +array_subscript_check_subscripts(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state; + ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace; + + /* Process upper subscripts */ + for (int i = 0; i < sbsrefstate->numupper; i++) + { + if (sbsrefstate->upperprovided[i]) + { + /* If any index expr yields NULL, result is NULL or error */ + if (sbsrefstate->upperindexnull[i]) + { + if (sbsrefstate->isassignment) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("array subscript in assignment must not be null"))); + *op->resnull = true; + return false; + } + workspace->upperindex[i] = DatumGetInt32(sbsrefstate->upperindex[i]); + } + } + + /* Likewise for lower subscripts */ + for (int i = 0; i < sbsrefstate->numlower; i++) + { + if (sbsrefstate->lowerprovided[i]) + { + /* If any index expr yields NULL, result is NULL or error */ + if (sbsrefstate->lowerindexnull[i]) + { + if (sbsrefstate->isassignment) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("array subscript in assignment must not be null"))); + *op->resnull = true; + return false; + } + workspace->lowerindex[i] = DatumGetInt32(sbsrefstate->lowerindex[i]); + } + } + + return true; +} + +/* + * Evaluate SubscriptingRef fetch for an array element. + * + * Source container is in step's result variable (it's known not NULL, since + * we set fetch_strict to true), and indexes have already been evaluated into + * workspace array. + */ +static void +array_subscript_fetch(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace; + + /* Should not get here if source array (or any subscript) is null */ + Assert(!(*op->resnull)); + + *op->resvalue = array_get_element(*op->resvalue, + sbsrefstate->numupper, + workspace->upperindex, + workspace->refattrlength, + workspace->refelemlength, + workspace->refelembyval, + workspace->refelemalign, + op->resnull); +} + +/* + * Evaluate SubscriptingRef fetch for an array slice. + * + * Source container is in step's result variable (it's known not NULL, since + * we set fetch_strict to true), and indexes have already been evaluated into + * workspace array. + */ +static void +array_subscript_fetch_slice(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace; + + /* Should not get here if source array (or any subscript) is null */ + Assert(!(*op->resnull)); + + *op->resvalue = array_get_slice(*op->resvalue, + sbsrefstate->numupper, + workspace->upperindex, + workspace->lowerindex, + sbsrefstate->upperprovided, + sbsrefstate->lowerprovided, + workspace->refattrlength, + workspace->refelemlength, + workspace->refelembyval, + workspace->refelemalign); + /* The slice is never NULL, so no need to change *op->resnull */ +} + +/* + * Evaluate SubscriptingRef assignment for an array element assignment. + * + * Input container (possibly null) is in result area, replacement value is in + * SubscriptingRefState's replacevalue/replacenull. + */ +static void +array_subscript_assign(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace; + Datum arraySource = *op->resvalue; + + /* + * For an assignment to a fixed-length array type, both the original array + * and the value to be assigned into it must be non-NULL, else we punt and + * return the original array. + */ + if (workspace->refattrlength > 0) + { + if (*op->resnull || sbsrefstate->replacenull) + return; + } + + /* + * For assignment to varlena arrays, we handle a NULL original array by + * substituting an empty (zero-dimensional) array; insertion of the new + * element will result in a singleton array value. It does not matter + * whether the new element is NULL. + */ + if (*op->resnull) + { + arraySource = PointerGetDatum(construct_empty_array(workspace->refelemtype)); + *op->resnull = false; + } + + *op->resvalue = array_set_element(arraySource, + sbsrefstate->numupper, + workspace->upperindex, + sbsrefstate->replacevalue, + sbsrefstate->replacenull, + workspace->refattrlength, + workspace->refelemlength, + workspace->refelembyval, + workspace->refelemalign); + /* The result is never NULL, so no need to change *op->resnull */ +} + +/* + * Evaluate SubscriptingRef assignment for an array slice assignment. + * + * Input container (possibly null) is in result area, replacement value is in + * SubscriptingRefState's replacevalue/replacenull. + */ +static void +array_subscript_assign_slice(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace; + Datum arraySource = *op->resvalue; + + /* + * For an assignment to a fixed-length array type, both the original array + * and the value to be assigned into it must be non-NULL, else we punt and + * return the original array. + */ + if (workspace->refattrlength > 0) + { + if (*op->resnull || sbsrefstate->replacenull) + return; + } + + /* + * For assignment to varlena arrays, we handle a NULL original array by + * substituting an empty (zero-dimensional) array; insertion of the new + * element will result in a singleton array value. It does not matter + * whether the new element is NULL. + */ + if (*op->resnull) + { + arraySource = PointerGetDatum(construct_empty_array(workspace->refelemtype)); + *op->resnull = false; + } + + *op->resvalue = array_set_slice(arraySource, + sbsrefstate->numupper, + workspace->upperindex, + workspace->lowerindex, + sbsrefstate->upperprovided, + sbsrefstate->lowerprovided, + sbsrefstate->replacevalue, + sbsrefstate->replacenull, + workspace->refattrlength, + workspace->refelemlength, + workspace->refelembyval, + workspace->refelemalign); + /* The result is never NULL, so no need to change *op->resnull */ +} + +/* + * Compute old array element value for a SubscriptingRef assignment + * expression. Will only be called if the new-value subexpression + * contains SubscriptingRef or FieldStore. This is the same as the + * regular fetch case, except that we have to handle a null array, + * and the value should be stored into the SubscriptingRefState's + * prevvalue/prevnull fields. + */ +static void +array_subscript_fetch_old(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace; + + if (*op->resnull) + { + /* whole array is null, so any element is too */ + sbsrefstate->prevvalue = (Datum) 0; + sbsrefstate->prevnull = true; + } + else + sbsrefstate->prevvalue = array_get_element(*op->resvalue, + sbsrefstate->numupper, + workspace->upperindex, + workspace->refattrlength, + workspace->refelemlength, + workspace->refelembyval, + workspace->refelemalign, + &sbsrefstate->prevnull); +} + +/* + * Compute old array slice value for a SubscriptingRef assignment + * expression. Will only be called if the new-value subexpression + * contains SubscriptingRef or FieldStore. This is the same as the + * regular fetch case, except that we have to handle a null array, + * and the value should be stored into the SubscriptingRefState's + * prevvalue/prevnull fields. + * + * Note: this is presently dead code, because the new value for a + * slice would have to be an array, so it couldn't directly contain a + * FieldStore; nor could it contain a SubscriptingRef assignment, since + * we consider adjacent subscripts to index one multidimensional array + * not nested array types. Future generalizations might make this + * reachable, however. + */ +static void +array_subscript_fetch_old_slice(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + ArraySubWorkspace *workspace = (ArraySubWorkspace *) sbsrefstate->workspace; + + if (*op->resnull) + { + /* whole array is null, so any slice is too */ + sbsrefstate->prevvalue = (Datum) 0; + sbsrefstate->prevnull = true; + } + else + { + sbsrefstate->prevvalue = array_get_slice(*op->resvalue, + sbsrefstate->numupper, + workspace->upperindex, + workspace->lowerindex, + sbsrefstate->upperprovided, + sbsrefstate->lowerprovided, + workspace->refattrlength, + workspace->refelemlength, + workspace->refelembyval, + workspace->refelemalign); + /* slices of non-null arrays are never null */ + sbsrefstate->prevnull = false; + } +} + +/* + * Set up execution state for an array subscript operation. + */ +static void +array_exec_setup(const SubscriptingRef *sbsref, + SubscriptingRefState *sbsrefstate, + SubscriptExecSteps *methods) +{ + bool is_slice = (sbsrefstate->numlower != 0); + ArraySubWorkspace *workspace; + + /* + * Enforce the implementation limit on number of array subscripts. This + * check isn't entirely redundant with checking at parse time; conceivably + * the expression was stored by a backend with a different MAXDIM value. + */ + if (sbsrefstate->numupper > MAXDIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", + sbsrefstate->numupper, MAXDIM))); + + /* Should be impossible if parser is sane, but check anyway: */ + if (sbsrefstate->numlower != 0 && + sbsrefstate->numupper != sbsrefstate->numlower) + elog(ERROR, "upper and lower index lists are not same length"); + + /* + * Allocate type-specific workspace. + */ + workspace = (ArraySubWorkspace *) palloc(sizeof(ArraySubWorkspace)); + sbsrefstate->workspace = workspace; + + /* + * Collect datatype details we'll need at execution. + */ + workspace->refelemtype = sbsref->refelemtype; + workspace->refattrlength = get_typlen(sbsref->refcontainertype); + get_typlenbyvalalign(sbsref->refelemtype, + &workspace->refelemlength, + &workspace->refelembyval, + &workspace->refelemalign); + + /* + * Pass back pointers to appropriate step execution functions. + */ + methods->sbs_check_subscripts = array_subscript_check_subscripts; + if (is_slice) + { + methods->sbs_fetch = array_subscript_fetch_slice; + methods->sbs_assign = array_subscript_assign_slice; + methods->sbs_fetch_old = array_subscript_fetch_old_slice; + } + else + { + methods->sbs_fetch = array_subscript_fetch; + methods->sbs_assign = array_subscript_assign; + methods->sbs_fetch_old = array_subscript_fetch_old; + } +} + +/* + * array_subscript_handler + * Subscripting handler for standard varlena arrays. + * + * This should be used only for "true" array types, which have array headers + * as understood by the varlena array routines, and are referenced by the + * element type's pg_type.typarray field. + */ +Datum +array_subscript_handler(PG_FUNCTION_ARGS) +{ + static const SubscriptRoutines sbsroutines = { + .transform = array_subscript_transform, + .exec_setup = array_exec_setup, + .fetch_strict = true, /* fetch returns NULL for NULL inputs */ + .fetch_leakproof = true, /* fetch returns NULL for bad subscript */ + .store_leakproof = false /* ... but assignment throws error */ + }; + + PG_RETURN_POINTER(&sbsroutines); +} + +/* + * raw_array_subscript_handler + * Subscripting handler for "raw" arrays. + * + * A "raw" array just contains N independent instances of the element type. + * Currently we require both the element type and the array type to be fixed + * length, but it wouldn't be too hard to relax that for the array type. + * + * As of now, all the support code is shared with standard varlena arrays. + * We may split those into separate code paths, but probably that would yield + * only marginal speedups. The main point of having a separate handler is + * so that pg_type.typsubscript clearly indicates the type's semantics. + */ +Datum +raw_array_subscript_handler(PG_FUNCTION_ARGS) +{ + static const SubscriptRoutines sbsroutines = { + .transform = array_subscript_transform, + .exec_setup = array_exec_setup, + .fetch_strict = true, /* fetch returns NULL for NULL inputs */ + .fetch_leakproof = true, /* fetch returns NULL for bad subscript */ + .store_leakproof = false /* ... but assignment throws error */ + }; + + PG_RETURN_POINTER(&sbsroutines); +} diff --git a/src/backend/utils/adt/arrayutils.c b/src/backend/utils/adt/arrayutils.c index bc4360aaec0c..6988edd93619 100644 --- a/src/backend/utils/adt/arrayutils.c +++ b/src/backend/utils/adt/arrayutils.c @@ -3,7 +3,7 @@ * arrayutils.c * This file contains some support routines required for array functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,6 +16,7 @@ #include "postgres.h" #include "catalog/pg_type.h" +#include "common/int.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/memutils.h" @@ -111,6 +112,36 @@ ArrayGetNItems(int ndim, const int *dims) return (int) ret; } +/* + * Verify sanity of proposed lower-bound values for an array + * + * The lower-bound values must not be so large as to cause overflow when + * calculating subscripts, e.g. lower bound 2147483640 with length 10 + * must be disallowed. We actually insist that dims[i] + lb[i] be + * computable without overflow, meaning that an array with last subscript + * equal to INT_MAX will be disallowed. + * + * It is assumed that the caller already called ArrayGetNItems, so that + * overflowed (negative) dims[] values have been eliminated. + */ +void +ArrayCheckBounds(int ndim, const int *dims, const int *lb) +{ + int i; + + for (i = 0; i < ndim; i++) + { + /* PG_USED_FOR_ASSERTS_ONLY prevents variable-isn't-read warnings */ + int32 sum PG_USED_FOR_ASSERTS_ONLY; + + if (pg_add_s32_overflow(dims[i], lb[i], &sum)) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("array lower bound is too large: %d", + lb[i]))); + } +} + /* * Compute ranges (sub-array dimensions) for an array slice * diff --git a/src/backend/utils/adt/ascii.c b/src/backend/utils/adt/ascii.c index 3aa8a5e7d21b..9dfff9dbef40 100644 --- a/src/backend/utils/adt/ascii.c +++ b/src/backend/utils/adt/ascii.c @@ -2,7 +2,7 @@ * ascii.c * The PostgreSQL routine for string to ascii conversion. * - * Portions Copyright (c) 1999-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/ascii.c diff --git a/src/backend/utils/adt/bool.c b/src/backend/utils/adt/bool.c index 340607f93645..fe11d1ae9463 100644 --- a/src/backend/utils/adt/bool.c +++ b/src/backend/utils/adt/bool.c @@ -3,7 +3,7 @@ * bool.c * Functions for the built-in type "bool". * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index 6515fc8ec695..d093ce80386f 100644 --- a/src/backend/utils/adt/cash.c +++ b/src/backend/utils/adt/cash.c @@ -1042,7 +1042,7 @@ cash_numeric(PG_FUNCTION_ARGS) fpoint = 2; /* convert the integral money value to numeric */ - result = DirectFunctionCall1(int8_numeric, Int64GetDatum(money)); + result = NumericGetDatum(int64_to_numeric(money)); /* scale appropriately, if needed */ if (fpoint > 0) @@ -1056,8 +1056,7 @@ cash_numeric(PG_FUNCTION_ARGS) scale = 1; for (i = 0; i < fpoint; i++) scale *= 10; - numeric_scale = DirectFunctionCall1(int8_numeric, - Int64GetDatum(scale)); + numeric_scale = NumericGetDatum(int64_to_numeric(scale)); /* * Given integral inputs approaching INT64_MAX, select_div_scale() @@ -1107,7 +1106,7 @@ numeric_cash(PG_FUNCTION_ARGS) scale *= 10; /* multiply the input amount by scale factor */ - numeric_scale = DirectFunctionCall1(int8_numeric, Int64GetDatum(scale)); + numeric_scale = NumericGetDatum(int64_to_numeric(scale)); amount = DirectFunctionCall2(numeric_mul, amount, numeric_scale); /* note that numeric_int8 will round to nearest integer for us */ diff --git a/src/backend/utils/adt/char.c b/src/backend/utils/adt/char.c index 20ea1366d053..e620d47eb520 100644 --- a/src/backend/utils/adt/char.c +++ b/src/backend/utils/adt/char.c @@ -4,7 +4,7 @@ * Functions for the built-in type "char" (not to be confused with * bpchar, which is the SQL CHAR(n) type). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/cryptohashes.c b/src/backend/utils/adt/cryptohashes.c deleted file mode 100644 index e897660927ff..000000000000 --- a/src/backend/utils/adt/cryptohashes.c +++ /dev/null @@ -1,169 +0,0 @@ -/*------------------------------------------------------------------------- - * - * cryptohashes.c - * Cryptographic hash functions - * - * Portions Copyright (c) 2018-2020, PostgreSQL Global Development Group - * - * - * IDENTIFICATION - * src/backend/utils/adt/cryptohashes.c - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include "common/md5.h" -#include "common/sha2.h" -#include "utils/builtins.h" - - -/* - * MD5 - */ - -/* MD5 produces a 16 byte (128 bit) hash; double it for hex */ -#define MD5_HASH_LEN 32 - -/* - * Create an MD5 hash of a text value and return it as hex string. - */ -Datum -md5_text(PG_FUNCTION_ARGS) -{ - text *in_text = PG_GETARG_TEXT_PP(0); - size_t len; - char hexsum[MD5_HASH_LEN + 1]; - - /* Calculate the length of the buffer using varlena metadata */ - len = VARSIZE_ANY_EXHDR(in_text); - - /* get the hash result */ - if (pg_md5_hash(VARDATA_ANY(in_text), len, hexsum) == false) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - - /* convert to text and return it */ - PG_RETURN_TEXT_P(cstring_to_text(hexsum)); -} - -/* - * Create an MD5 hash of a bytea value and return it as a hex string. - */ -Datum -md5_bytea(PG_FUNCTION_ARGS) -{ - bytea *in = PG_GETARG_BYTEA_PP(0); - size_t len; - char hexsum[MD5_HASH_LEN + 1]; - - len = VARSIZE_ANY_EXHDR(in); - if (pg_md5_hash(VARDATA_ANY(in), len, hexsum) == false) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); - - PG_RETURN_TEXT_P(cstring_to_text(hexsum)); -} - - -/* - * SHA-2 variants - */ - -Datum -sha224_bytea(PG_FUNCTION_ARGS) -{ - bytea *in = PG_GETARG_BYTEA_PP(0); - const uint8 *data; - size_t len; - pg_sha224_ctx ctx; - unsigned char buf[PG_SHA224_DIGEST_LENGTH]; - bytea *result; - - len = VARSIZE_ANY_EXHDR(in); - data = (unsigned char *) VARDATA_ANY(in); - - pg_sha224_init(&ctx); - pg_sha224_update(&ctx, data, len); - pg_sha224_final(&ctx, buf); - - result = palloc(sizeof(buf) + VARHDRSZ); - SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); - memcpy(VARDATA(result), buf, sizeof(buf)); - - PG_RETURN_BYTEA_P(result); -} - -Datum -sha256_bytea(PG_FUNCTION_ARGS) -{ - bytea *in = PG_GETARG_BYTEA_PP(0); - const uint8 *data; - size_t len; - pg_sha256_ctx ctx; - unsigned char buf[PG_SHA256_DIGEST_LENGTH]; - bytea *result; - - len = VARSIZE_ANY_EXHDR(in); - data = (unsigned char *) VARDATA_ANY(in); - - pg_sha256_init(&ctx); - pg_sha256_update(&ctx, data, len); - pg_sha256_final(&ctx, buf); - - result = palloc(sizeof(buf) + VARHDRSZ); - SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); - memcpy(VARDATA(result), buf, sizeof(buf)); - - PG_RETURN_BYTEA_P(result); -} - -Datum -sha384_bytea(PG_FUNCTION_ARGS) -{ - bytea *in = PG_GETARG_BYTEA_PP(0); - const uint8 *data; - size_t len; - pg_sha384_ctx ctx; - unsigned char buf[PG_SHA384_DIGEST_LENGTH]; - bytea *result; - - len = VARSIZE_ANY_EXHDR(in); - data = (unsigned char *) VARDATA_ANY(in); - - pg_sha384_init(&ctx); - pg_sha384_update(&ctx, data, len); - pg_sha384_final(&ctx, buf); - - result = palloc(sizeof(buf) + VARHDRSZ); - SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); - memcpy(VARDATA(result), buf, sizeof(buf)); - - PG_RETURN_BYTEA_P(result); -} - -Datum -sha512_bytea(PG_FUNCTION_ARGS) -{ - bytea *in = PG_GETARG_BYTEA_PP(0); - const uint8 *data; - size_t len; - pg_sha512_ctx ctx; - unsigned char buf[PG_SHA512_DIGEST_LENGTH]; - bytea *result; - - len = VARSIZE_ANY_EXHDR(in); - data = (unsigned char *) VARDATA_ANY(in); - - pg_sha512_init(&ctx); - pg_sha512_update(&ctx, data, len); - pg_sha512_final(&ctx, buf); - - result = palloc(sizeof(buf) + VARHDRSZ); - SET_VARSIZE(result, sizeof(buf) + VARHDRSZ); - memcpy(VARDATA(result), buf, sizeof(buf)); - - PG_RETURN_BYTEA_P(result); -} diff --git a/src/backend/utils/adt/cryptohashfuncs.c b/src/backend/utils/adt/cryptohashfuncs.c new file mode 100644 index 000000000000..6a0f0258e60a --- /dev/null +++ b/src/backend/utils/adt/cryptohashfuncs.c @@ -0,0 +1,161 @@ +/*------------------------------------------------------------------------- + * + * cryptohashfuncs.c + * Cryptographic hash functions + * + * Portions Copyright (c) 2018-2021, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/utils/adt/cryptohashfuncs.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "common/cryptohash.h" +#include "common/md5.h" +#include "common/sha2.h" +#include "utils/builtins.h" + + +/* + * MD5 + */ + +/* MD5 produces a 16 byte (128 bit) hash; double it for hex */ +#define MD5_HASH_LEN 32 + +/* + * Create an MD5 hash of a text value and return it as hex string. + */ +Datum +md5_text(PG_FUNCTION_ARGS) +{ + text *in_text = PG_GETARG_TEXT_PP(0); + size_t len; + char hexsum[MD5_HASH_LEN + 1]; + + /* Calculate the length of the buffer using varlena metadata */ + len = VARSIZE_ANY_EXHDR(in_text); + + /* get the hash result */ + if (pg_md5_hash(VARDATA_ANY(in_text), len, hexsum) == false) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + + /* convert to text and return it */ + PG_RETURN_TEXT_P(cstring_to_text(hexsum)); +} + +/* + * Create an MD5 hash of a bytea value and return it as a hex string. + */ +Datum +md5_bytea(PG_FUNCTION_ARGS) +{ + bytea *in = PG_GETARG_BYTEA_PP(0); + size_t len; + char hexsum[MD5_HASH_LEN + 1]; + + len = VARSIZE_ANY_EXHDR(in); + if (pg_md5_hash(VARDATA_ANY(in), len, hexsum) == false) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"))); + + PG_RETURN_TEXT_P(cstring_to_text(hexsum)); +} + +/* + * Internal routine to compute a cryptohash with the given bytea input. + */ +static inline bytea * +cryptohash_internal(pg_cryptohash_type type, bytea *input) +{ + const uint8 *data; + const char *typestr = NULL; + int digest_len = 0; + size_t len; + pg_cryptohash_ctx *ctx; + bytea *result; + + switch (type) + { + case PG_SHA224: + typestr = "SHA224"; + digest_len = PG_SHA224_DIGEST_LENGTH; + break; + case PG_SHA256: + typestr = "SHA256"; + digest_len = PG_SHA256_DIGEST_LENGTH; + break; + case PG_SHA384: + typestr = "SHA384"; + digest_len = PG_SHA384_DIGEST_LENGTH; + break; + case PG_SHA512: + typestr = "SHA512"; + digest_len = PG_SHA512_DIGEST_LENGTH; + break; + case PG_MD5: + case PG_SHA1: + elog(ERROR, "unsupported cryptohash type %d", type); + break; + } + + result = palloc0(digest_len + VARHDRSZ); + len = VARSIZE_ANY_EXHDR(input); + data = (unsigned char *) VARDATA_ANY(input); + + ctx = pg_cryptohash_create(type); + if (pg_cryptohash_init(ctx) < 0) + elog(ERROR, "could not initialize %s context", typestr); + if (pg_cryptohash_update(ctx, data, len) < 0) + elog(ERROR, "could not update %s context", typestr); + if (pg_cryptohash_final(ctx, (unsigned char *) VARDATA(result), + digest_len) < 0) + elog(ERROR, "could not finalize %s context", typestr); + pg_cryptohash_free(ctx); + + SET_VARSIZE(result, digest_len + VARHDRSZ); + + return result; +} + +/* + * SHA-2 variants + */ + +Datum +sha224_bytea(PG_FUNCTION_ARGS) +{ + bytea *result = cryptohash_internal(PG_SHA224, PG_GETARG_BYTEA_PP(0)); + + PG_RETURN_BYTEA_P(result); +} + +Datum +sha256_bytea(PG_FUNCTION_ARGS) +{ + bytea *result = cryptohash_internal(PG_SHA256, PG_GETARG_BYTEA_PP(0)); + + PG_RETURN_BYTEA_P(result); +} + +Datum +sha384_bytea(PG_FUNCTION_ARGS) +{ + bytea *result = cryptohash_internal(PG_SHA384, PG_GETARG_BYTEA_PP(0)); + + PG_RETURN_BYTEA_P(result); +} + +Datum +sha512_bytea(PG_FUNCTION_ARGS) +{ + bytea *result = cryptohash_internal(PG_SHA512, PG_GETARG_BYTEA_PP(0)); + + PG_RETURN_BYTEA_P(result); +} diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index b1a71a307742..4b45d2b14439 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -3,7 +3,7 @@ * date.c * implements DATE and TIME data types specified in SQL standard * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * @@ -31,6 +31,7 @@ #include "utils/builtins.h" #include "utils/date.h" #include "utils/datetime.h" +#include "utils/numeric.h" #include "utils/sortsupport.h" /* @@ -299,20 +300,31 @@ EncodeSpecialDate(DateADT dt, char *str) DateADT GetSQLCurrentDate(void) { - TimestampTz ts; - struct pg_tm tt, - *tm = &tt; - fsec_t fsec; - int tz; + struct pg_tm tm; - ts = GetCurrentTransactionStartTimestamp(); + static int cache_year = 0; + static int cache_mon = 0; + static int cache_mday = 0; + static DateADT cache_date; - if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); + GetCurrentDateTime(&tm); - return date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; + /* + * date2j involves several integer divisions; moreover, unless our session + * lives across local midnight, we don't really have to do it more than + * once. So it seems worth having a separate cache here. + */ + if (tm.tm_year != cache_year || + tm.tm_mon != cache_mon || + tm.tm_mday != cache_mday) + { + cache_date = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - POSTGRES_EPOCH_JDATE; + cache_year = tm.tm_year; + cache_mon = tm.tm_mon; + cache_mday = tm.tm_mday; + } + + return cache_date; } /* @@ -322,18 +334,12 @@ TimeTzADT * GetSQLCurrentTime(int32 typmod) { TimeTzADT *result; - TimestampTz ts; struct pg_tm tt, *tm = &tt; fsec_t fsec; int tz; - ts = GetCurrentTransactionStartTimestamp(); - - if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); + GetCurrentTimeUsec(tm, &fsec, &tz); result = (TimeTzADT *) palloc(sizeof(TimeTzADT)); tm2timetz(tm, fsec, tz, result); @@ -348,18 +354,12 @@ TimeADT GetSQLLocalTime(int32 typmod) { TimeADT result; - TimestampTz ts; struct pg_tm tt, *tm = &tt; fsec_t fsec; int tz; - ts = GetCurrentTransactionStartTimestamp(); - - if (timestamp2tm(ts, &tz, tm, &fsec, NULL, NULL) != 0) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); + GetCurrentTimeUsec(tm, &fsec, &tz); tm2time(tm, fsec, &result); AdjustTimeForTypmod(&result, typmod); @@ -555,15 +555,24 @@ date_mii(PG_FUNCTION_ARGS) /* * Promote date to timestamp. * - * On overflow error is thrown if 'overflow' is NULL. Otherwise, '*overflow' - * is set to -1 (+1) when result value exceed lower (upper) boundary and zero - * returned. + * On successful conversion, *overflow is set to zero if it's not NULL. + * + * If the date is finite but out of the valid range for timestamp, then: + * if overflow is NULL, we throw an out-of-range error. + * if overflow is not NULL, we store +1 or -1 there to indicate the sign + * of the overflow, and return the appropriate timestamp infinity. + * + * Note: *overflow = -1 is actually not possible currently, since both + * datatypes have the same lower bound, Julian day zero. */ Timestamp date2timestamp_opt_overflow(DateADT dateVal, int *overflow) { Timestamp result; + if (overflow) + *overflow = 0; + if (DATE_IS_NOBEGIN(dateVal)) TIMESTAMP_NOBEGIN(result); else if (DATE_IS_NOEND(dateVal)) @@ -571,7 +580,6 @@ date2timestamp_opt_overflow(DateADT dateVal, int *overflow) else { /* - * Date's range is wider than timestamp's, so check for boundaries. * Since dates have the same minimum values as timestamps, only upper * boundary need be checked for overflow. */ @@ -580,7 +588,8 @@ date2timestamp_opt_overflow(DateADT dateVal, int *overflow) if (overflow) { *overflow = 1; - return (Timestamp) 0; + TIMESTAMP_NOEND(result); + return result; } else { @@ -598,7 +607,7 @@ date2timestamp_opt_overflow(DateADT dateVal, int *overflow) } /* - * Single-argument version of date2timestamp_opt_overflow(). + * Promote date to timestamp, throwing error for overflow. */ static TimestampTz date2timestamp(DateADT dateVal) @@ -609,9 +618,12 @@ date2timestamp(DateADT dateVal) /* * Promote date to timestamp with time zone. * - * On overflow error is thrown if 'overflow' is NULL. Otherwise, '*overflow' - * is set to -1 (+1) when result value exceed lower (upper) boundary and zero - * returned. + * On successful conversion, *overflow is set to zero if it's not NULL. + * + * If the date is finite but out of the valid range for timestamptz, then: + * if overflow is NULL, we throw an out-of-range error. + * if overflow is not NULL, we store +1 or -1 there to indicate the sign + * of the overflow, and return the appropriate timestamptz infinity. */ TimestampTz date2timestamptz_opt_overflow(DateADT dateVal, int *overflow) @@ -621,6 +633,9 @@ date2timestamptz_opt_overflow(DateADT dateVal, int *overflow) *tm = &tt; int tz; + if (overflow) + *overflow = 0; + if (DATE_IS_NOBEGIN(dateVal)) TIMESTAMP_NOBEGIN(result); else if (DATE_IS_NOEND(dateVal)) @@ -628,7 +643,6 @@ date2timestamptz_opt_overflow(DateADT dateVal, int *overflow) else { /* - * Date's range is wider than timestamp's, so check for boundaries. * Since dates have the same minimum values as timestamps, only upper * boundary need be checked for overflow. */ @@ -637,7 +651,8 @@ date2timestamptz_opt_overflow(DateADT dateVal, int *overflow) if (overflow) { *overflow = 1; - return (TimestampTz) 0; + TIMESTAMP_NOEND(result); + return result; } else { @@ -665,13 +680,15 @@ date2timestamptz_opt_overflow(DateADT dateVal, int *overflow) if (overflow) { if (result < MIN_TIMESTAMP) + { *overflow = -1; + TIMESTAMP_NOBEGIN(result); + } else { - Assert(result >= END_TIMESTAMP); *overflow = 1; + TIMESTAMP_NOEND(result); } - return (TimestampTz) 0; } else { @@ -686,7 +703,7 @@ date2timestamptz_opt_overflow(DateADT dateVal, int *overflow) } /* - * Single-argument version of date2timestamptz_opt_overflow(). + * Promote date to timestamptz, throwing error for overflow. */ static TimestampTz date2timestamptz(DateADT dateVal) @@ -727,16 +744,30 @@ date2timestamp_no_overflow(DateADT dateVal) * Crosstype comparison functions for dates */ +int32 +date_cmp_timestamp_internal(DateADT dateVal, Timestamp dt2) +{ + Timestamp dt1; + int overflow; + + dt1 = date2timestamp_opt_overflow(dateVal, &overflow); + if (overflow > 0) + { + /* dt1 is larger than any finite timestamp, but less than infinity */ + return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1; + } + Assert(overflow == 0); /* -1 case cannot occur */ + + return timestamp_cmp_internal(dt1, dt2); +} + Datum date_eq_timestamp(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); - Timestamp dt1; - - dt1 = date2timestamp(dateVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt2) == 0); } Datum @@ -744,11 +775,8 @@ date_ne_timestamp(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); - Timestamp dt1; - dt1 = date2timestamp(dateVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt2) != 0); } Datum @@ -756,11 +784,8 @@ date_lt_timestamp(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); - Timestamp dt1; - dt1 = date2timestamp(dateVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt2) < 0); } Datum @@ -768,11 +793,8 @@ date_gt_timestamp(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); - Timestamp dt1; - dt1 = date2timestamp(dateVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt2) > 0); } Datum @@ -780,11 +802,8 @@ date_le_timestamp(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); - Timestamp dt1; - - dt1 = date2timestamp(dateVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt2) <= 0); } Datum @@ -792,11 +811,8 @@ date_ge_timestamp(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); - Timestamp dt1; - - dt1 = date2timestamp(dateVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt2) >= 0); } Datum @@ -804,11 +820,29 @@ date_cmp_timestamp(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); Timestamp dt2 = PG_GETARG_TIMESTAMP(1); - Timestamp dt1; - dt1 = date2timestamp(dateVal); + PG_RETURN_INT32(date_cmp_timestamp_internal(dateVal, dt2)); +} + +int32 +date_cmp_timestamptz_internal(DateADT dateVal, TimestampTz dt2) +{ + TimestampTz dt1; + int overflow; + + dt1 = date2timestamptz_opt_overflow(dateVal, &overflow); + if (overflow > 0) + { + /* dt1 is larger than any finite timestamp, but less than infinity */ + return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1; + } + if (overflow < 0) + { + /* dt1 is less than any finite timestamp, but more than -infinity */ + return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1; + } - PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2)); + return timestamptz_cmp_internal(dt1, dt2); } Datum @@ -816,11 +850,8 @@ date_eq_timestamptz(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - - dt1 = date2timestamptz(dateVal); - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) == 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt2) == 0); } Datum @@ -828,11 +859,8 @@ date_ne_timestamptz(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - - dt1 = date2timestamptz(dateVal); - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) != 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt2) != 0); } Datum @@ -840,11 +868,8 @@ date_lt_timestamptz(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - - dt1 = date2timestamptz(dateVal); - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) < 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt2) < 0); } Datum @@ -852,11 +877,8 @@ date_gt_timestamptz(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - dt1 = date2timestamptz(dateVal); - - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) > 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt2) > 0); } Datum @@ -864,11 +886,8 @@ date_le_timestamptz(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - dt1 = date2timestamptz(dateVal); - - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) <= 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt2) <= 0); } Datum @@ -876,11 +895,8 @@ date_ge_timestamptz(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - dt1 = date2timestamptz(dateVal); - - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) >= 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt2) >= 0); } Datum @@ -888,11 +904,8 @@ date_cmp_timestamptz(PG_FUNCTION_ARGS) { DateADT dateVal = PG_GETARG_DATEADT(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - - dt1 = date2timestamptz(dateVal); - PG_RETURN_INT32(timestamptz_cmp_internal(dt1, dt2)); + PG_RETURN_INT32(date_cmp_timestamptz_internal(dateVal, dt2)); } Datum @@ -900,11 +913,8 @@ timestamp_eq_date(PG_FUNCTION_ARGS) { Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); - Timestamp dt2; - dt2 = date2timestamp(dateVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt1) == 0); } Datum @@ -912,11 +922,8 @@ timestamp_ne_date(PG_FUNCTION_ARGS) { Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); - Timestamp dt2; - - dt2 = date2timestamp(dateVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt1) != 0); } Datum @@ -924,11 +931,8 @@ timestamp_lt_date(PG_FUNCTION_ARGS) { Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); - Timestamp dt2; - dt2 = date2timestamp(dateVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt1) > 0); } Datum @@ -936,11 +940,8 @@ timestamp_gt_date(PG_FUNCTION_ARGS) { Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); - Timestamp dt2; - - dt2 = date2timestamp(dateVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt1) < 0); } Datum @@ -948,11 +949,8 @@ timestamp_le_date(PG_FUNCTION_ARGS) { Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); - Timestamp dt2; - dt2 = date2timestamp(dateVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt1) >= 0); } Datum @@ -960,11 +958,8 @@ timestamp_ge_date(PG_FUNCTION_ARGS) { Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); - Timestamp dt2; - - dt2 = date2timestamp(dateVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0); + PG_RETURN_BOOL(date_cmp_timestamp_internal(dateVal, dt1) <= 0); } Datum @@ -972,11 +967,8 @@ timestamp_cmp_date(PG_FUNCTION_ARGS) { Timestamp dt1 = PG_GETARG_TIMESTAMP(0); DateADT dateVal = PG_GETARG_DATEADT(1); - Timestamp dt2; - - dt2 = date2timestamp(dateVal); - PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2)); + PG_RETURN_INT32(-date_cmp_timestamp_internal(dateVal, dt1)); } Datum @@ -984,11 +976,8 @@ timestamptz_eq_date(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); - TimestampTz dt2; - dt2 = date2timestamptz(dateVal); - - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) == 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt1) == 0); } Datum @@ -996,11 +985,8 @@ timestamptz_ne_date(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); - TimestampTz dt2; - - dt2 = date2timestamptz(dateVal); - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) != 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt1) != 0); } Datum @@ -1008,11 +994,8 @@ timestamptz_lt_date(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); - TimestampTz dt2; - dt2 = date2timestamptz(dateVal); - - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) < 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt1) > 0); } Datum @@ -1020,11 +1003,8 @@ timestamptz_gt_date(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); - TimestampTz dt2; - - dt2 = date2timestamptz(dateVal); - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) > 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt1) < 0); } Datum @@ -1032,11 +1012,8 @@ timestamptz_le_date(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); - TimestampTz dt2; - dt2 = date2timestamptz(dateVal); - - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) <= 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt1) >= 0); } Datum @@ -1044,11 +1021,8 @@ timestamptz_ge_date(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); - TimestampTz dt2; - - dt2 = date2timestamptz(dateVal); - PG_RETURN_BOOL(timestamptz_cmp_internal(dt1, dt2) >= 0); + PG_RETURN_BOOL(date_cmp_timestamptz_internal(dateVal, dt1) <= 0); } Datum @@ -1056,11 +1030,8 @@ timestamptz_cmp_date(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); DateADT dateVal = PG_GETARG_DATEADT(1); - TimestampTz dt2; - - dt2 = date2timestamptz(dateVal); - PG_RETURN_INT32(timestamptz_cmp_internal(dt1, dt2)); + PG_RETURN_INT32(-date_cmp_timestamptz_internal(dateVal, dt1)); } /* @@ -1080,6 +1051,7 @@ in_range_date_interval(PG_FUNCTION_ARGS) Timestamp valStamp; Timestamp baseStamp; + /* XXX we could support out-of-range cases here, perhaps */ valStamp = date2timestamp(val); baseStamp = date2timestamp(base); @@ -1092,6 +1064,182 @@ in_range_date_interval(PG_FUNCTION_ARGS) } +/* extract_date() + * Extract specified field from date type. + */ +Datum +extract_date(PG_FUNCTION_ARGS) +{ + text *units = PG_GETARG_TEXT_PP(0); + DateADT date = PG_GETARG_DATEADT(1); + int64 intresult; + int type, + val; + char *lowunits; + int year, + mon, + mday; + + lowunits = downcase_truncate_identifier(VARDATA_ANY(units), + VARSIZE_ANY_EXHDR(units), + false); + + type = DecodeUnits(0, lowunits, &val); + if (type == UNKNOWN_FIELD) + type = DecodeSpecial(0, lowunits, &val); + + if (DATE_NOT_FINITE(date) && (type == UNITS || type == RESERV)) + { + switch (val) + { + /* Oscillating units */ + case DTK_DAY: + case DTK_MONTH: + case DTK_QUARTER: + case DTK_WEEK: + case DTK_DOW: + case DTK_ISODOW: + case DTK_DOY: + PG_RETURN_NULL(); + break; + + /* Monotonically-increasing units */ + case DTK_YEAR: + case DTK_DECADE: + case DTK_CENTURY: + case DTK_MILLENNIUM: + case DTK_JULIAN: + case DTK_ISOYEAR: + case DTK_EPOCH: + if (DATE_IS_NOBEGIN(date)) + PG_RETURN_NUMERIC(DatumGetNumeric(DirectFunctionCall3(numeric_in, + CStringGetDatum("-Infinity"), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)))); + else + PG_RETURN_NUMERIC(DatumGetNumeric(DirectFunctionCall3(numeric_in, + CStringGetDatum("Infinity"), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)))); + default: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("date units \"%s\" not supported", + lowunits))); + } + } + else if (type == UNITS) + { + j2date(date + POSTGRES_EPOCH_JDATE, &year, &mon, &mday); + + switch (val) + { + case DTK_DAY: + intresult = mday; + break; + + case DTK_MONTH: + intresult = mon; + break; + + case DTK_QUARTER: + intresult = (mon - 1) / 3 + 1; + break; + + case DTK_WEEK: + intresult = date2isoweek(year, mon, mday); + break; + + case DTK_YEAR: + if (year > 0) + intresult = year; + else + /* there is no year 0, just 1 BC and 1 AD */ + intresult = year - 1; + break; + + case DTK_DECADE: + /* see comments in timestamp_part */ + if (year >= 0) + intresult = year / 10; + else + intresult = -((8 - (year - 1)) / 10); + break; + + case DTK_CENTURY: + /* see comments in timestamp_part */ + if (year > 0) + intresult = (year + 99) / 100; + else + intresult = -((99 - (year - 1)) / 100); + break; + + case DTK_MILLENNIUM: + /* see comments in timestamp_part */ + if (year > 0) + intresult = (year + 999) / 1000; + else + intresult = -((999 - (year - 1)) / 1000); + break; + + case DTK_JULIAN: + intresult = date + POSTGRES_EPOCH_JDATE; + break; + + case DTK_ISOYEAR: + intresult = date2isoyear(year, mon, mday); + /* Adjust BC years */ + if (intresult <= 0) + intresult -= 1; + break; + + case DTK_DOW: + case DTK_ISODOW: + intresult = j2day(date + POSTGRES_EPOCH_JDATE); + if (val == DTK_ISODOW && intresult == 0) + intresult = 7; + break; + + case DTK_DOY: + intresult = date2j(year, mon, mday) - date2j(year, 1, 1) + 1; + break; + + default: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("date units \"%s\" not supported", + lowunits))); + intresult = 0; + } + } + else if (type == RESERV) + { + switch (val) + { + case DTK_EPOCH: + intresult = ((int64) date + POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY; + break; + + default: + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("date units \"%s\" not supported", + lowunits))); + intresult = 0; + } + } + else + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("date units \"%s\" not recognized", lowunits))); + intresult = 0; + } + + PG_RETURN_NUMERIC(int64_to_numeric(intresult)); +} + + /* Add an interval to a date, giving a new date. * Must handle both positive and negative intervals. * @@ -2052,15 +2200,15 @@ in_range_time_interval(PG_FUNCTION_ARGS) } -/* time_part() +/* time_part() and extract_time() * Extract specified field from time type. */ -Datum -time_part(PG_FUNCTION_ARGS) +static Datum +time_part_common(PG_FUNCTION_ARGS, bool retnumeric) { text *units = PG_GETARG_TEXT_PP(0); TimeADT time = PG_GETARG_TIMEADT(1); - float8 result; + int64 intresult; int type, val; char *lowunits; @@ -2084,23 +2232,37 @@ time_part(PG_FUNCTION_ARGS) switch (val) { case DTK_MICROSEC: - result = tm->tm_sec * 1000000.0 + fsec; + intresult = tm->tm_sec * INT64CONST(1000000) + fsec; break; case DTK_MILLISEC: - result = tm->tm_sec * 1000.0 + fsec / 1000.0; + if (retnumeric) + /*--- + * tm->tm_sec * 1000 + fsec / 1000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3)); + else + PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0); break; case DTK_SECOND: - result = tm->tm_sec + fsec / 1000000.0; + if (retnumeric) + /*--- + * tm->tm_sec + fsec / 1'000'000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6)); + else + PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0); break; case DTK_MINUTE: - result = tm->tm_min; + intresult = tm->tm_min; break; case DTK_HOUR: - result = tm->tm_hour; + intresult = tm->tm_hour; break; case DTK_TZ: @@ -2119,12 +2281,15 @@ time_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("\"time\" units \"%s\" not recognized", lowunits))); - result = 0; + intresult = 0; } } else if (type == RESERV && val == DTK_EPOCH) { - result = time / 1000000.0; + if (retnumeric) + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(time, 6)); + else + PG_RETURN_FLOAT8(time / 1000000.0); } else { @@ -2132,10 +2297,25 @@ time_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("\"time\" units \"%s\" not recognized", lowunits))); - result = 0; + intresult = 0; } - PG_RETURN_FLOAT8(result); + if (retnumeric) + PG_RETURN_NUMERIC(int64_to_numeric(intresult)); + else + PG_RETURN_FLOAT8(intresult); +} + +Datum +time_part(PG_FUNCTION_ARGS) +{ + return time_part_common(fcinfo, false); +} + +Datum +extract_time(PG_FUNCTION_ARGS) +{ + return time_part_common(fcinfo, true); } @@ -2789,15 +2969,15 @@ datetimetz_timestamptz(PG_FUNCTION_ARGS) } -/* timetz_part() +/* timetz_part() and extract_timetz() * Extract specified field from time type. */ -Datum -timetz_part(PG_FUNCTION_ARGS) +static Datum +timetz_part_common(PG_FUNCTION_ARGS, bool retnumeric) { text *units = PG_GETARG_TEXT_PP(0); TimeTzADT *time = PG_GETARG_TIMETZADT_P(1); - float8 result; + int64 intresult; int type, val; char *lowunits; @@ -2812,7 +2992,6 @@ timetz_part(PG_FUNCTION_ARGS) if (type == UNITS) { - double dummy; int tz; fsec_t fsec; struct pg_tm tt, @@ -2823,38 +3002,49 @@ timetz_part(PG_FUNCTION_ARGS) switch (val) { case DTK_TZ: - result = -tz; + intresult = -tz; break; case DTK_TZ_MINUTE: - result = -tz; - result /= SECS_PER_MINUTE; - FMODULO(result, dummy, (double) SECS_PER_MINUTE); + intresult = (-tz / SECS_PER_MINUTE) % MINS_PER_HOUR; break; case DTK_TZ_HOUR: - dummy = -tz; - FMODULO(dummy, result, (double) SECS_PER_HOUR); + intresult = -tz / SECS_PER_HOUR; break; case DTK_MICROSEC: - result = tm->tm_sec * 1000000.0 + fsec; + intresult = tm->tm_sec * INT64CONST(1000000) + fsec; break; case DTK_MILLISEC: - result = tm->tm_sec * 1000.0 + fsec / 1000.0; + if (retnumeric) + /*--- + * tm->tm_sec * 1000 + fsec / 1000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3)); + else + PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0); break; case DTK_SECOND: - result = tm->tm_sec + fsec / 1000000.0; + if (retnumeric) + /*--- + * tm->tm_sec + fsec / 1'000'000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6)); + else + PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0); break; case DTK_MINUTE: - result = tm->tm_min; + intresult = tm->tm_min; break; case DTK_HOUR: - result = tm->tm_hour; + intresult = tm->tm_hour; break; case DTK_DAY: @@ -2869,12 +3059,19 @@ timetz_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("\"time with time zone\" units \"%s\" not recognized", lowunits))); - result = 0; + intresult = 0; } } else if (type == RESERV && val == DTK_EPOCH) { - result = time->time / 1000000.0 + time->zone; + if (retnumeric) + /*--- + * time->time / 1'000'000 + time->zone + * = (time->time + time->zone * 1'000'000) / 1'000'000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(time->time + time->zone * INT64CONST(1000000), 6)); + else + PG_RETURN_FLOAT8(time->time / 1000000.0 + time->zone); } else { @@ -2882,10 +3079,26 @@ timetz_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("\"time with time zone\" units \"%s\" not recognized", lowunits))); - result = 0; + intresult = 0; } - PG_RETURN_FLOAT8(result); + if (retnumeric) + PG_RETURN_NUMERIC(int64_to_numeric(intresult)); + else + PG_RETURN_FLOAT8(intresult); +} + + +Datum +timetz_part(PG_FUNCTION_ARGS) +{ + return timetz_part_common(fcinfo, false); +} + +Datum +extract_timetz(PG_FUNCTION_ARGS) +{ + return timetz_part_common(fcinfo, true); } /* timetz_zone() diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index d3197a9df071..9b1484054305 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -3,7 +3,7 @@ * datetime.c * Support functions for date/time types. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -353,35 +353,80 @@ j2day(int date) /* * GetCurrentDateTime() * - * Get the transaction start time ("now()") broken down as a struct pg_tm. + * Get the transaction start time ("now()") broken down as a struct pg_tm, + * converted according to the session timezone setting. + * + * This is just a convenience wrapper for GetCurrentTimeUsec, to cover the + * case where caller doesn't need either fractional seconds or tz offset. */ void GetCurrentDateTime(struct pg_tm *tm) { - int tz; fsec_t fsec; - timestamp2tm(GetCurrentTransactionStartTimestamp(), &tz, tm, &fsec, - NULL, NULL); - /* Note: don't pass NULL tzp to timestamp2tm; affects behavior */ + GetCurrentTimeUsec(tm, &fsec, NULL); } /* * GetCurrentTimeUsec() * * Get the transaction start time ("now()") broken down as a struct pg_tm, - * including fractional seconds and timezone offset. + * including fractional seconds and timezone offset. The time is converted + * according to the session timezone setting. + * + * Callers may pass tzp = NULL if they don't need the offset, but this does + * not affect the conversion behavior (unlike timestamp2tm()). + * + * Internally, we cache the result, since this could be called many times + * in a transaction, within which now() doesn't change. */ void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp) { - int tz; + TimestampTz cur_ts = GetCurrentTransactionStartTimestamp(); + + /* + * The cache key must include both current time and current timezone. By + * representing the timezone by just a pointer, we're assuming that + * distinct timezone settings could never have the same pointer value. + * This is true by virtue of the hashtable used inside pg_tzset(); + * however, it might need another look if we ever allow entries in that + * hash to be recycled. + */ + static TimestampTz cache_ts = 0; + static pg_tz *cache_timezone = NULL; + static struct pg_tm cache_tm; + static fsec_t cache_fsec; + static int cache_tz; + + if (cur_ts != cache_ts || session_timezone != cache_timezone) + { + /* + * Make sure cache is marked invalid in case of error after partial + * update within timestamp2tm. + */ + cache_timezone = NULL; + + /* + * Perform the computation, storing results into cache. We do not + * really expect any error here, since current time surely ought to be + * within range, but check just for sanity's sake. + */ + if (timestamp2tm(cur_ts, &cache_tz, &cache_tm, &cache_fsec, + NULL, session_timezone) != 0) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timestamp out of range"))); + + /* OK, so mark the cache valid. */ + cache_ts = cur_ts; + cache_timezone = session_timezone; + } - timestamp2tm(GetCurrentTransactionStartTimestamp(), &tz, tm, fsec, - NULL, NULL); - /* Note: don't pass NULL tzp to timestamp2tm; affects behavior */ + *tm = cache_tm; + *fsec = cache_fsec; if (tzp != NULL) - *tzp = tz; + *tzp = cache_tz; } @@ -4454,6 +4499,7 @@ EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str) else if (is_before) *cp++ = '-'; cp = AppendSeconds(cp, sec, fsec, MAX_INTERVAL_PRECISION, false); + /* We output "ago", not negatives, so use abs(). */ sprintf(cp, " sec%s", (abs(sec) != 1 || fsec != 0) ? "s" : ""); is_zero = false; diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c index 3706b549b740..ea5509f3f635 100644 --- a/src/backend/utils/adt/datum.c +++ b/src/backend/utils/adt/datum.c @@ -3,7 +3,7 @@ * datum.c * POSTGRES Datum (abstract data type) manipulation routines. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 26d4fd4ac9de..8b2ff7d1e782 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -2,7 +2,7 @@ * dbsize.c * Database object size functions, and related inquiries * - * Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Copyright (c) 2002-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/dbsize.c @@ -173,7 +173,7 @@ calculate_database_size(Oid dbOid) */ aclresult = pg_database_aclcheck(dbOid, GetUserId(), ACL_CONNECT); if (aclresult != ACLCHECK_OK && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS)) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS)) { aclcheck_error(aclresult, OBJECT_DATABASE, get_database_name(dbOid)); @@ -280,7 +280,7 @@ calculate_tablespace_size(Oid tblspcOid) * is default for current database. */ if (tblspcOid != MyDatabaseTableSpace && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS)) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS)) { aclresult = pg_tablespace_aclcheck(tblspcOid, GetUserId(), ACL_CREATE); if (aclresult != ACLCHECK_OK) @@ -831,14 +831,6 @@ numeric_to_cstring(Numeric n) return DatumGetCString(DirectFunctionCall1(numeric_out, d)); } -static Numeric -int64_to_numeric(int64 v) -{ - Datum d = Int64GetDatum(v); - - return DatumGetNumeric(DirectFunctionCall1(int8_numeric, d)); -} - static bool numeric_is_less(Numeric a, Numeric b) { @@ -867,9 +859,9 @@ numeric_half_rounded(Numeric n) Datum two; Datum result; - zero = DirectFunctionCall1(int8_numeric, Int64GetDatum(0)); - one = DirectFunctionCall1(int8_numeric, Int64GetDatum(1)); - two = DirectFunctionCall1(int8_numeric, Int64GetDatum(2)); + zero = NumericGetDatum(int64_to_numeric(0)); + one = NumericGetDatum(int64_to_numeric(1)); + two = NumericGetDatum(int64_to_numeric(2)); if (DatumGetBool(DirectFunctionCall2(numeric_ge, d, zero))) d = DirectFunctionCall2(numeric_add, d, one); @@ -884,12 +876,10 @@ static Numeric numeric_shift_right(Numeric n, unsigned count) { Datum d = NumericGetDatum(n); - Datum divisor_int64; Datum divisor_numeric; Datum result; - divisor_int64 = Int64GetDatum((int64) (1LL << count)); - divisor_numeric = DirectFunctionCall1(int8_numeric, divisor_int64); + divisor_numeric = NumericGetDatum(int64_to_numeric(((int64) 1) << count)); result = DirectFunctionCall2(numeric_div_trunc, d, divisor_numeric); return DatumGetNumeric(result); } @@ -1084,8 +1074,7 @@ pg_size_bytes(PG_FUNCTION_ARGS) { Numeric mul_num; - mul_num = DatumGetNumeric(DirectFunctionCall1(int8_numeric, - Int64GetDatum(multiplier))); + mul_num = int64_to_numeric(multiplier); num = DatumGetNumeric(DirectFunctionCall2(numeric_mul, NumericGetDatum(mul_num), @@ -1130,7 +1119,7 @@ pg_relation_filenode(PG_FUNCTION_ARGS) { if (relform->relfilenode) result = relform->relfilenode; - else /* Consult the relation mapper */ + else /* Consult the relation mapper */ result = RelationMapOidToFilenode(relid, relform->relisshared); } @@ -1166,7 +1155,11 @@ pg_filenode_relation(PG_FUNCTION_ARGS) { Oid reltablespace = PG_GETARG_OID(0); Oid relfilenode = PG_GETARG_OID(1); - Oid heaprel = InvalidOid; + Oid heaprel; + + /* test needed so RelidByRelfilenode doesn't misbehave */ + if (!OidIsValid(relfilenode)) + PG_RETURN_NULL(); heaprel = RelidByRelfilenode(reltablespace, relfilenode); @@ -1209,17 +1202,17 @@ pg_relation_filepath(PG_FUNCTION_ARGS) rnode.dbNode = MyDatabaseId; if (relform->relfilenode) rnode.relNode = relform->relfilenode; - else /* Consult the relation mapper */ + else /* Consult the relation mapper */ rnode.relNode = RelationMapOidToFilenode(relid, relform->relisshared); } else { - /* no storage, return NULL */ - rnode.relNode = InvalidOid; - /* some compilers generate warnings without these next two lines */ - rnode.dbNode = InvalidOid; - rnode.spcNode = InvalidOid; + /* no storage, return NULL */ + rnode.relNode = InvalidOid; + /* some compilers generate warnings without these next two lines */ + rnode.dbNode = InvalidOid; + rnode.spcNode = InvalidOid; } if (!OidIsValid(rnode.relNode)) diff --git a/src/backend/utils/adt/domains.c b/src/backend/utils/adt/domains.c index 41e1a1b610b3..0a36772fc031 100644 --- a/src/backend/utils/adt/domains.c +++ b/src/backend/utils/adt/domains.c @@ -19,7 +19,7 @@ * to evaluate them in. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c index a609d49c12c2..8449aaac56ac 100644 --- a/src/backend/utils/adt/encode.c +++ b/src/backend/utils/adt/encode.c @@ -3,7 +3,7 @@ * encode.c * Various data encoding/decoding things. * - * Copyright (c) 2001-2020, PostgreSQL Global Development Group + * Copyright (c) 2001-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -15,6 +15,7 @@ #include +#include "common/hex.h" #include "mb/pg_wchar.h" #include "utils/builtins.h" #include "utils/memutils.h" @@ -31,10 +32,12 @@ */ struct pg_encoding { - uint64 (*encode_len) (const char *data, size_t dlen); - uint64 (*decode_len) (const char *data, size_t dlen); - uint64 (*encode) (const char *data, size_t dlen, char *res); - uint64 (*decode) (const char *data, size_t dlen, char *res); + uint64 (*encode_len) (const char *src, size_t srclen); + uint64 (*decode_len) (const char *src, size_t srclen); + uint64 (*encode) (const char *src, size_t srclen, + char *dst, size_t dstlen); + uint64 (*decode) (const char *src, size_t srclen, + char *dst, size_t dstlen); }; static const struct pg_encoding *pg_find_encoding(const char *name); @@ -80,11 +83,7 @@ binary_encode(PG_FUNCTION_ARGS) result = palloc(VARHDRSZ + resultlen); - res = enc->encode(dataptr, datalen, VARDATA(result)); - - /* Make this FATAL 'cause we've trodden on memory ... */ - if (res > resultlen) - elog(FATAL, "overflow - encode estimate too small"); + res = enc->encode(dataptr, datalen, VARDATA(result), resultlen); SET_VARSIZE(result, VARHDRSZ + res); @@ -128,11 +127,7 @@ binary_decode(PG_FUNCTION_ARGS) result = palloc(VARHDRSZ + resultlen); - res = enc->decode(dataptr, datalen, VARDATA(result)); - - /* Make this FATAL 'cause we've trodden on memory ... */ - if (res > resultlen) - elog(FATAL, "overflow - decode estimate too small"); + res = enc->decode(dataptr, datalen, VARDATA(result), resultlen); SET_VARSIZE(result, VARHDRSZ + res); @@ -144,95 +139,20 @@ binary_decode(PG_FUNCTION_ARGS) * HEX */ -static const char hextbl[] = "0123456789abcdef"; - -static const int8 hexlookup[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -}; - -uint64 -hex_encode(const char *src, size_t len, char *dst) -{ - const char *end = src + len; - - while (src < end) - { - *dst++ = hextbl[(*src >> 4) & 0xF]; - *dst++ = hextbl[*src & 0xF]; - src++; - } - return (uint64) len * 2; -} - -static inline char -get_hex(const char *cp) -{ - unsigned char c = (unsigned char) *cp; - int res = -1; - - if (c < 127) - res = hexlookup[c]; - - if (res < 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid hexadecimal digit: \"%.*s\"", - pg_mblen(cp), cp))); - - return (char) res; -} - -uint64 -hex_decode(const char *src, size_t len, char *dst) -{ - const char *s, - *srcend; - char v1, - v2, - *p; - - srcend = src + len; - s = src; - p = dst; - while (s < srcend) - { - if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r') - { - s++; - continue; - } - v1 = get_hex(s) << 4; - s++; - if (s >= srcend) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid hexadecimal data: odd number of digits"))); - - v2 = get_hex(s); - s++; - *p++ = v1 | v2; - } - - return p - dst; -} - +/* + * Those two wrappers are still needed to match with the layer of + * src/common/. + */ static uint64 hex_enc_len(const char *src, size_t srclen) { - return (uint64) srclen << 1; + return pg_hex_enc_len(srclen); } static uint64 hex_dec_len(const char *src, size_t srclen) { - return (uint64) srclen >> 1; + return pg_hex_dec_len(srclen); } /* @@ -254,12 +174,12 @@ static const int8 b64lookup[128] = { }; static uint64 -pg_base64_encode(const char *src, size_t len, char *dst) +pg_base64_encode(const char *src, size_t srclen, char *dst, size_t dstlen) { char *p, *lend = dst + 76; const char *s, - *end = src + len; + *end = src + srclen; int pos = 2; uint32 buf = 0; @@ -275,6 +195,8 @@ pg_base64_encode(const char *src, size_t len, char *dst) /* write it out */ if (pos < 0) { + if ((p - dst + 4) > dstlen) + elog(ERROR, "overflow of destination buffer in base64 encoding"); *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = _base64[(buf >> 6) & 0x3f]; @@ -285,25 +207,30 @@ pg_base64_encode(const char *src, size_t len, char *dst) } if (p >= lend) { + if ((p - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in base64 encoding"); *p++ = '\n'; lend = p + 76; } } if (pos != 2) { + if ((p - dst + 4) > dstlen) + elog(ERROR, "overflow of destination buffer in base64 encoding"); *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '='; *p++ = '='; } + Assert((p - dst) <= dstlen); return p - dst; } static uint64 -pg_base64_decode(const char *src, size_t len, char *dst) +pg_base64_decode(const char *src, size_t srclen, char *dst, size_t dstlen) { - const char *srcend = src + len, + const char *srcend = src + srclen, *s = src; char *p = dst; char c; @@ -351,11 +278,21 @@ pg_base64_decode(const char *src, size_t len, char *dst) pos++; if (pos == 4) { + if ((p - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in base64 decoding"); *p++ = (buf >> 16) & 255; if (end == 0 || end > 1) + { + if ((p - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in base64 decoding"); *p++ = (buf >> 8) & 255; + } if (end == 0 || end > 2) + { + if ((p - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in base64 decoding"); *p++ = buf & 255; + } buf = 0; pos = 0; } @@ -367,6 +304,7 @@ pg_base64_decode(const char *src, size_t len, char *dst) errmsg("invalid base64 end sequence"), errhint("Input data is missing padding, is truncated, or is otherwise corrupted."))); + Assert((p - dst) <= dstlen); return p - dst; } @@ -402,7 +340,7 @@ pg_base64_dec_len(const char *src, size_t srclen) #define DIG(VAL) ((VAL) + '0') static uint64 -esc_encode(const char *src, size_t srclen, char *dst) +esc_encode(const char *src, size_t srclen, char *dst, size_t dstlen) { const char *end = src + srclen; char *rp = dst; @@ -414,6 +352,8 @@ esc_encode(const char *src, size_t srclen, char *dst) if (c == '\0' || IS_HIGHBIT_SET(c)) { + if ((rp - dst + 4) > dstlen) + elog(ERROR, "overflow of destination buffer in escape encoding"); rp[0] = '\\'; rp[1] = DIG(c >> 6); rp[2] = DIG((c >> 3) & 7); @@ -423,6 +363,8 @@ esc_encode(const char *src, size_t srclen, char *dst) } else if (c == '\\') { + if ((rp - dst + 2) > dstlen) + elog(ERROR, "overflow of destination buffer in escape encoding"); rp[0] = '\\'; rp[1] = '\\'; rp += 2; @@ -430,6 +372,8 @@ esc_encode(const char *src, size_t srclen, char *dst) } else { + if ((rp - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in escape encoding"); *rp++ = c; len++; } @@ -437,11 +381,12 @@ esc_encode(const char *src, size_t srclen, char *dst) src++; } + Assert((rp - dst) <= dstlen); return len; } static uint64 -esc_decode(const char *src, size_t srclen, char *dst) +esc_decode(const char *src, size_t srclen, char *dst, size_t dstlen) { const char *end = src + srclen; char *rp = dst; @@ -450,7 +395,11 @@ esc_decode(const char *src, size_t srclen, char *dst) while (src < end) { if (src[0] != '\\') + { + if ((rp - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in escape decoding"); *rp++ = *src++; + } else if (src + 3 < end && (src[1] >= '0' && src[1] <= '3') && (src[2] >= '0' && src[2] <= '7') && @@ -462,12 +411,16 @@ esc_decode(const char *src, size_t srclen, char *dst) val <<= 3; val += VAL(src[2]); val <<= 3; + if ((rp - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in escape decoding"); *rp++ = val + VAL(src[3]); src += 4; } else if (src + 1 < end && (src[1] == '\\')) { + if ((rp - dst + 1) > dstlen) + elog(ERROR, "overflow of destination buffer in escape decoding"); *rp++ = '\\'; src += 2; } @@ -485,6 +438,7 @@ esc_decode(const char *src, size_t srclen, char *dst) len++; } + Assert((rp - dst) <= dstlen); return len; } @@ -566,7 +520,7 @@ static const struct { "hex", { - hex_enc_len, hex_dec_len, hex_encode, hex_decode + hex_enc_len, hex_dec_len, pg_hex_encode, pg_hex_decode } }, { diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c index 5ead794e3492..0d892132a841 100644 --- a/src/backend/utils/adt/enum.c +++ b/src/backend/utils/adt/enum.c @@ -3,7 +3,7 @@ * enum.c * I/O functions, operators, aggregates etc for enum types * - * Copyright (c) 2006-2020, PostgreSQL Global Development Group + * Copyright (c) 2006-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -16,7 +16,6 @@ #include "access/genam.h" #include "access/htup_details.h" #include "access/table.h" -#include "catalog/indexing.h" #include "catalog/pg_enum.h" #include "libpq/pqformat.h" #include "storage/procarray.h" @@ -83,12 +82,12 @@ check_safe_enum_use(HeapTuple enumval_tup) return; /* - * Check if the enum value is blacklisted. If not, it's safe, because it + * Check if the enum value is uncommitted. If not, it's safe, because it * was made during CREATE TYPE AS ENUM and can't be shorter-lived than its * owning type. (This'd also be false for values made by other * transactions; but the previous tests should have handled all of those.) */ - if (!EnumBlacklisted(en->oid)) + if (!EnumUncommitted(en->oid)) return; /* diff --git a/src/backend/utils/adt/expandeddatum.c b/src/backend/utils/adt/expandeddatum.c index 3c3552355600..cb0adfaa2152 100644 --- a/src/backend/utils/adt/expandeddatum.c +++ b/src/backend/utils/adt/expandeddatum.c @@ -3,7 +3,7 @@ * expandeddatum.c * Support functions for "expanded" value representations. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/expandedrecord.c b/src/backend/utils/adt/expandedrecord.c index ec12ec54fc82..e19491ecf744 100644 --- a/src/backend/utils/adt/expandedrecord.c +++ b/src/backend/utils/adt/expandedrecord.c @@ -7,7 +7,7 @@ * store values of named composite types, domains over named composite types, * and record types (registered or anonymous). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 203fc0eac29b..62aad160ae02 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -3,7 +3,7 @@ * float.c * Functions for the built-in floating-point types. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/format_type.c b/src/backend/utils/adt/format_type.c index f2816e4f37f7..0e8e06545758 100644 --- a/src/backend/utils/adt/format_type.c +++ b/src/backend/utils/adt/format_type.c @@ -4,7 +4,7 @@ * Display type names "nicely". * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,6 +22,7 @@ #include "catalog/pg_type.h" #include "mb/pg_wchar.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/numeric.h" #include "utils/syscache.h" @@ -138,15 +139,14 @@ format_type_extended(Oid type_oid, int32 typemod, bits16 flags) typeform = (Form_pg_type) GETSTRUCT(tuple); /* - * Check if it's a regular (variable length) array type. Fixed-length - * array types such as "name" shouldn't get deconstructed. As of Postgres - * 8.1, rather than checking typlen we check the toast property, and don't + * Check if it's a "true" array type. Pseudo-array types such as "name" + * shouldn't get deconstructed. Also check the toast property, and don't * deconstruct "plain storage" array types --- this is because we don't * want to show oidvector as oid[]. */ array_base_type = typeform->typelem; - if (array_base_type != InvalidOid && + if (IsTrueArrayType(typeform) && typeform->typstorage != TYPSTORAGE_PLAIN) { /* Switch our attention to the array element type */ diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index a43cda318722..846fcb97b60f 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -4,7 +4,7 @@ * src/backend/utils/adt/formatting.c * * - * Portions Copyright (c) 1999-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2021, PostgreSQL Global Development Group * * * TO_CHAR(); TO_TIMESTAMP(); TO_DATE(); TO_NUMBER(); @@ -1381,10 +1381,12 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw, { int chlen; - if (flags & STD_FLAG) + if ((flags & STD_FLAG) && *str != '"') { /* - * Standard mode, allow only following separators: "-./,':; " + * Standard mode, allow only following separators: "-./,':; ". + * However, we support double quotes even in standard mode + * (see below). This is our extension of standard mode. */ if (strchr("-./,':; ", *str) == NULL) ereport(ERROR, @@ -1510,8 +1512,7 @@ static const char * get_th(char *num, int type) { int len = strlen(num), - last, - seclast; + last; last = *(num + (len - 1)); if (!isdigit((unsigned char) last)) @@ -1523,7 +1524,7 @@ get_th(char *num, int type) * All "teens" (1[0-9]) get 'TH/th', while [02-9][123] still get * 'ST/st', 'ND/nd', 'RD/rd', respectively */ - if ((len > 1) && ((seclast = num[len - 2]) == '1')) + if ((len > 1) && (num[len - 2] == '1')) last = 0; switch (last) @@ -3206,18 +3207,61 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col s += strlen(s); break; case DCH_RM: - if (!tm->tm_mon) - break; - sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -4, - rm_months_upper[MONTHS_PER_YEAR - tm->tm_mon]); - s += strlen(s); - break; + /* FALLTHROUGH */ case DCH_rm: - if (!tm->tm_mon) + + /* + * For intervals, values like '12 month' will be reduced to 0 + * month and some years. These should be processed. + */ + if (!tm->tm_mon && !tm->tm_year) break; - sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -4, - rm_months_lower[MONTHS_PER_YEAR - tm->tm_mon]); - s += strlen(s); + else + { + int mon = 0; + const char *const *months; + + if (n->key->id == DCH_RM) + months = rm_months_upper; + else + months = rm_months_lower; + + /* + * Compute the position in the roman-numeral array. Note + * that the contents of the array are reversed, December + * being first and January last. + */ + if (tm->tm_mon == 0) + { + /* + * This case is special, and tracks the case of full + * interval years. + */ + mon = tm->tm_year >= 0 ? 0 : MONTHS_PER_YEAR - 1; + } + else if (tm->tm_mon < 0) + { + /* + * Negative case. In this case, the calculation is + * reversed, where -1 means December, -2 November, + * etc. + */ + mon = -1 * (tm->tm_mon + 1); + } + else + { + /* + * Common case, with a strictly positive value. The + * position in the array matches with the value of + * tm_mon. + */ + mon = MONTHS_PER_YEAR - tm->tm_mon; + } + + sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -4, + months[mon]); + s += strlen(s); + } break; case DCH_W: sprintf(s, "%d", (tm->tm_mday - 1) / 7 + 1); @@ -3347,7 +3391,19 @@ DCH_from_char(FormatNode *node, const char *in, TmFromChar *out, } else { - s += pg_mblen(s); + int chlen = pg_mblen(s); + + /* + * Standard mode requires strict match of format characters. + */ + if (std && n->type == NODE_TYPE_CHAR && + strncmp(s, n->character, chlen) != 0) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("unmatched format character \"%s\"", + n->character)))); + + s += chlen; } continue; } @@ -4567,8 +4623,11 @@ do_to_timestamp(text *date_txt, text *fmt, Oid collid, bool std, { /* If a 4-digit year is provided, we use that and ignore CC. */ tm->tm_year = tmfc.year; - if (tmfc.bc && tm->tm_year > 0) - tm->tm_year = -(tm->tm_year - 1); + if (tmfc.bc) + tm->tm_year = -tm->tm_year; + /* correct for our representation of BC years */ + if (tm->tm_year < 0) + tm->tm_year++; } fmask |= DTK_M(YEAR); } @@ -4943,9 +5002,9 @@ NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree) static char * int_to_roman(int number) { - int len = 0, - num = 0; - char *p = NULL, + int len, + num; + char *p, *result, numstr[12]; @@ -4961,7 +5020,7 @@ int_to_roman(int number) for (p = numstr; *p != '\0'; p++, --len) { - num = *p - 49; /* 48 ascii + 1 */ + num = *p - ('0' + 1); if (num < 0) continue; @@ -6082,10 +6141,8 @@ numeric_to_number(PG_FUNCTION_ARGS) if (IS_MULTI(&Num)) { Numeric x; - Numeric a = DatumGetNumeric(DirectFunctionCall1(int4_numeric, - Int32GetDatum(10))); - Numeric b = DatumGetNumeric(DirectFunctionCall1(int4_numeric, - Int32GetDatum(-Num.multi))); + Numeric a = int64_to_numeric(10); + Numeric b = int64_to_numeric(-Num.multi); x = DatumGetNumeric(DirectFunctionCall2(numeric_power, NumericGetDatum(a), @@ -6129,7 +6186,7 @@ numeric_to_char(PG_FUNCTION_ARGS) x = DatumGetNumeric(DirectFunctionCall2(numeric_round, NumericGetDatum(value), Int32GetDatum(0))); - numstr = orgnum = + numstr = int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4, NumericGetDatum(x)))); } @@ -6174,10 +6231,8 @@ numeric_to_char(PG_FUNCTION_ARGS) if (IS_MULTI(&Num)) { - Numeric a = DatumGetNumeric(DirectFunctionCall1(int4_numeric, - Int32GetDatum(10))); - Numeric b = DatumGetNumeric(DirectFunctionCall1(int4_numeric, - Int32GetDatum(Num.multi))); + Numeric a = int64_to_numeric(10); + Numeric b = int64_to_numeric(Num.multi); x = DatumGetNumeric(DirectFunctionCall2(numeric_power, NumericGetDatum(a), @@ -6250,7 +6305,7 @@ int4_to_char(PG_FUNCTION_ARGS) * On DateType depend part (int32) */ if (IS_ROMAN(&Num)) - numstr = orgnum = int_to_roman(value); + numstr = int_to_roman(value); else if (IS_EEEE(&Num)) { /* we can do it easily because float8 won't lose any precision */ @@ -6346,16 +6401,13 @@ int8_to_char(PG_FUNCTION_ARGS) if (IS_ROMAN(&Num)) { /* Currently don't support int8 conversion to roman... */ - numstr = orgnum = int_to_roman(DatumGetInt32(DirectFunctionCall1(int84, Int64GetDatum(value)))); + numstr = int_to_roman(DatumGetInt32(DirectFunctionCall1(int84, Int64GetDatum(value)))); } else if (IS_EEEE(&Num)) { /* to avoid loss of precision, must go via numeric not float8 */ - Numeric val; - - val = DatumGetNumeric(DirectFunctionCall1(int8_numeric, - Int64GetDatum(value))); - orgnum = numeric_out_sci(val, Num.post); + orgnum = numeric_out_sci(int64_to_numeric(value), + Num.post); /* * numeric_out_sci() does not emit a sign for positive numbers. We @@ -6445,13 +6497,12 @@ float4_to_char(PG_FUNCTION_ARGS) int out_pre_spaces = 0, sign = 0; char *numstr, - *orgnum, *p; NUM_TOCHAR_prepare; if (IS_ROMAN(&Num)) - numstr = orgnum = int_to_roman((int) rint(value)); + numstr = int_to_roman((int) rint(value)); else if (IS_EEEE(&Num)) { if (isnan(value) || isinf(value)) @@ -6467,20 +6518,19 @@ float4_to_char(PG_FUNCTION_ARGS) } else { - numstr = orgnum = psprintf("%+.*e", Num.post, value); + numstr = psprintf("%+.*e", Num.post, value); /* * Swap a leading positive sign for a space. */ - if (*orgnum == '+') - *orgnum = ' '; - - numstr = orgnum; + if (*numstr == '+') + *numstr = ' '; } } else { float4 val = value; + char *orgnum; int numstr_pre_len; if (IS_MULTI(&Num)) @@ -6491,7 +6541,7 @@ float4_to_char(PG_FUNCTION_ARGS) Num.pre += Num.multi; } - orgnum = (char *) psprintf("%.0f", fabs(val)); + orgnum = psprintf("%.0f", fabs(val)); numstr_pre_len = strlen(orgnum); /* adjust post digits to fit max float digits */ @@ -6549,13 +6599,12 @@ float8_to_char(PG_FUNCTION_ARGS) int out_pre_spaces = 0, sign = 0; char *numstr, - *orgnum, *p; NUM_TOCHAR_prepare; if (IS_ROMAN(&Num)) - numstr = orgnum = int_to_roman((int) rint(value)); + numstr = int_to_roman((int) rint(value)); else if (IS_EEEE(&Num)) { if (isnan(value) || isinf(value)) @@ -6571,20 +6620,19 @@ float8_to_char(PG_FUNCTION_ARGS) } else { - numstr = orgnum = (char *) psprintf("%+.*e", Num.post, value); + numstr = psprintf("%+.*e", Num.post, value); /* * Swap a leading positive sign for a space. */ - if (*orgnum == '+') - *orgnum = ' '; - - numstr = orgnum; + if (*numstr == '+') + *numstr = ' '; } } else { float8 val = value; + char *orgnum; int numstr_pre_len; if (IS_MULTI(&Num)) @@ -6594,6 +6642,7 @@ float8_to_char(PG_FUNCTION_ARGS) val = value * multi; Num.pre += Num.multi; } + orgnum = psprintf("%.0f", fabs(val)); numstr_pre_len = strlen(orgnum); diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index 1052fea9e69a..b4a1c8b57502 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -4,7 +4,7 @@ * Functions for direct access to files * * - * Copyright (c) 2004-2020, PostgreSQL Global Development Group + * Copyright (c) 2004-2021, PostgreSQL Global Development Group * * Author: Andreas Pflug * @@ -75,10 +75,13 @@ convert_and_check_filename(text *arg) * files on the server as the PG user, so no need to do any further checks * here. */ - if (is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_SERVER_FILES)) + if (is_member_of_role(GetUserId(), ROLE_PG_READ_SERVER_FILES)) return filename; - /* User isn't a member of the default role, so check if it's allowable */ + /* + * User isn't a member of the pg_read_server_files role, so check if it's + * allowable + */ if (is_absolute_path(filename)) { /* Disallow '/a/b/data/..' */ @@ -181,16 +184,15 @@ read_binary_file(const char *filename, int64 seek_offset, int64 bytes_to_read, #define MIN_READ_SIZE 4096 /* - * If not at end of file, and sbuf.len is equal to - * MaxAllocSize - 1, then either the file is too large, or - * there is nothing left to read. Attempt to read one more - * byte to see if the end of file has been reached. If not, - * the file is too large; we'd rather give the error message - * for that ourselves. + * If not at end of file, and sbuf.len is equal to MaxAllocSize - + * 1, then either the file is too large, or there is nothing left + * to read. Attempt to read one more byte to see if the end of + * file has been reached. If not, the file is too large; we'd + * rather give the error message for that ourselves. */ if (sbuf.len == MaxAllocSize - 1) { - char rbuf[1]; + char rbuf[1]; if (fread(rbuf, 1, 1, file) != 0 || !feof(file)) ereport(ERROR, @@ -275,7 +277,7 @@ pg_read_file(PG_FUNCTION_ARGS) errmsg("must be superuser to read files with adminpack 1.0"), /* translator: %s is a SQL function name */ errhint("Consider using %s, which is part of core, instead.", - "pg_file_read()"))); + "pg_read_file()"))); /* handle optional arguments */ if (PG_NARGS() >= 3) diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index a7db78395888..9484dbc22737 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -13,7 +13,7 @@ * - circle * - polygon * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1055,13 +1055,20 @@ line_send(PG_FUNCTION_ARGS) static inline void line_construct(LINE *result, Point *pt, float8 m) { - if (m == DBL_MAX) + if (isinf(m)) { /* vertical - use "x = C" */ result->A = -1.0; result->B = 0.0; result->C = pt->x; } + else if (m == 0) + { + /* horizontal - use "y = C" */ + result->A = 0.0; + result->B = -1.0; + result->C = pt->y; + } else { /* use "mx - y + yinter = 0" */ @@ -1155,9 +1162,6 @@ line_horizontal(PG_FUNCTION_ARGS) /* * Check whether the two lines are the same - * - * We consider NaNs values to be equal to each other to let those lines - * to be found. */ Datum line_eq(PG_FUNCTION_ARGS) @@ -1166,21 +1170,28 @@ line_eq(PG_FUNCTION_ARGS) LINE *l2 = PG_GETARG_LINE_P(1); float8 ratio; - if (!FPzero(l2->A) && !isnan(l2->A)) + /* If any NaNs are involved, insist on exact equality */ + if (unlikely(isnan(l1->A) || isnan(l1->B) || isnan(l1->C) || + isnan(l2->A) || isnan(l2->B) || isnan(l2->C))) + { + PG_RETURN_BOOL(float8_eq(l1->A, l2->A) && + float8_eq(l1->B, l2->B) && + float8_eq(l1->C, l2->C)); + } + + /* Otherwise, lines whose parameters are proportional are the same */ + if (!FPzero(l2->A)) ratio = float8_div(l1->A, l2->A); - else if (!FPzero(l2->B) && !isnan(l2->B)) + else if (!FPzero(l2->B)) ratio = float8_div(l1->B, l2->B); - else if (!FPzero(l2->C) && !isnan(l2->C)) + else if (!FPzero(l2->C)) ratio = float8_div(l1->C, l2->C); else ratio = 1.0; - PG_RETURN_BOOL((FPeq(l1->A, float8_mul(ratio, l2->A)) && - FPeq(l1->B, float8_mul(ratio, l2->B)) && - FPeq(l1->C, float8_mul(ratio, l2->C))) || - (float8_eq(l1->A, l2->A) && - float8_eq(l1->B, l2->B) && - float8_eq(l1->C, l2->C))); + PG_RETURN_BOOL(FPeq(l1->A, float8_mul(ratio, l2->A)) && + FPeq(l1->B, float8_mul(ratio, l2->B)) && + FPeq(l1->C, float8_mul(ratio, l2->C))); } @@ -1197,7 +1208,7 @@ line_sl(LINE *line) if (FPzero(line->A)) return 0.0; if (FPzero(line->B)) - return DBL_MAX; + return get_float8_infinity(); return float8_div(line->A, -line->B); } @@ -1209,7 +1220,7 @@ static inline float8 line_invsl(LINE *line) { if (FPzero(line->A)) - return DBL_MAX; + return get_float8_infinity(); if (FPzero(line->B)) return 0.0; return float8_div(line->B, line->A); @@ -1930,15 +1941,16 @@ point_ne(PG_FUNCTION_ARGS) /* * Check whether the two points are the same - * - * We consider NaNs coordinates to be equal to each other to let those points - * to be found. */ static inline bool point_eq_point(Point *pt1, Point *pt2) { - return ((FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y)) || - (float8_eq(pt1->x, pt2->x) && float8_eq(pt1->y, pt2->y))); + /* If any NaNs are involved, insist on exact equality */ + if (unlikely(isnan(pt1->x) || isnan(pt1->y) || + isnan(pt2->x) || isnan(pt2->y))) + return (float8_eq(pt1->x, pt2->x) && float8_eq(pt1->y, pt2->y)); + + return (FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y)); } @@ -1974,13 +1986,13 @@ point_slope(PG_FUNCTION_ARGS) /* * Return slope of two points * - * Note that this function returns DBL_MAX when the points are the same. + * Note that this function returns Inf when the points are the same. */ static inline float8 point_sl(Point *pt1, Point *pt2) { if (FPeq(pt1->x, pt2->x)) - return DBL_MAX; + return get_float8_infinity(); if (FPeq(pt1->y, pt2->y)) return 0.0; return float8_div(float8_mi(pt1->y, pt2->y), float8_mi(pt1->x, pt2->x)); @@ -1998,7 +2010,7 @@ point_invsl(Point *pt1, Point *pt2) if (FPeq(pt1->x, pt2->x)) return 0.0; if (FPeq(pt1->y, pt2->y)) - return DBL_MAX; + return get_float8_infinity(); return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y)); } diff --git a/src/backend/utils/adt/geo_selfuncs.c b/src/backend/utils/adt/geo_selfuncs.c index 89cf8d32e791..db941244efae 100644 --- a/src/backend/utils/adt/geo_selfuncs.c +++ b/src/backend/utils/adt/geo_selfuncs.c @@ -4,7 +4,7 @@ * Selectivity routines registered in the operator catalog in the * "oprrest" and "oprjoin" attributes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/geo_spgist.c b/src/backend/utils/adt/geo_spgist.c index de7e6fa40425..6ee75d008c0b 100644 --- a/src/backend/utils/adt/geo_spgist.c +++ b/src/backend/utils/adt/geo_spgist.c @@ -62,7 +62,7 @@ * except the root. For the root node, we are setting the boundaries * that we don't yet have as infinity. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -749,8 +749,13 @@ spg_box_quad_leaf_consistent(PG_FUNCTION_ARGS) /* All tests are exact. */ out->recheck = false; - /* leafDatum is what it is... */ - out->leafValue = in->leafDatum; + /* + * Don't return leafValue unless told to; this is used for both box and + * polygon opclasses, and in the latter case the leaf datum is not even of + * the right type to return. + */ + if (in->returnData) + out->leafValue = leaf; /* Perform the required comparison(s) */ for (i = 0; i < in->nkeys; i++) diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index 418c13e1b4cd..e9f108425c5a 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -3,7 +3,7 @@ * int.c * Functions for the built-in integer types (except int8). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index 005f68d85391..2168080dcce9 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -3,7 +3,7 @@ * int8.c * Internal 64-bit integer operations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index a7a91b72f69b..30ca2cf6c81b 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -3,7 +3,7 @@ * json.c * JSON data type support. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -990,7 +990,7 @@ catenate_stringinfo_string(StringInfo buffer, const char *addon) Datum json_build_object(PG_FUNCTION_ARGS) { - int nargs = PG_NARGS(); + int nargs; int i; const char *sep = ""; StringInfo result; diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index 1e9ca046c699..8d1e7fbf9108 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -3,7 +3,7 @@ * jsonb.c * I/O routines for jsonb type * - * Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Copyright (c) 2014-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/jsonb.c diff --git a/src/backend/utils/adt/jsonb_gin.c b/src/backend/utils/adt/jsonb_gin.c index aee3d9d6733e..37499bc56226 100644 --- a/src/backend/utils/adt/jsonb_gin.c +++ b/src/backend/utils/adt/jsonb_gin.c @@ -3,7 +3,7 @@ * jsonb_gin.c * GIN support functions for jsonb * - * Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Copyright (c) 2014-2021, PostgreSQL Global Development Group * * We provide two opclasses for jsonb indexing: jsonb_ops and jsonb_path_ops. * For their description see json.sgml and comments in jsonb.h. diff --git a/src/backend/utils/adt/jsonb_op.c b/src/backend/utils/adt/jsonb_op.c index dc17e17f9b46..6e85e5c36b39 100644 --- a/src/backend/utils/adt/jsonb_op.c +++ b/src/backend/utils/adt/jsonb_op.c @@ -3,7 +3,7 @@ * jsonb_op.c * Special operators for jsonb only, used by various index access methods * - * Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Copyright (c) 2014-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index 4eeffa142434..571118779590 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -3,7 +3,7 @@ * jsonb_util.c * converting between Jsonb and JsonbValues, and iterating. * - * Copyright (c) 2014-2020, PostgreSQL Global Development Group + * Copyright (c) 2014-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -68,18 +68,25 @@ static JsonbValue *pushJsonbValueScalar(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *scalarVal); +void +JsonbToJsonbValue(Jsonb *jsonb, JsonbValue *val) +{ + val->type = jbvBinary; + val->val.binary.data = &jsonb->root; + val->val.binary.len = VARSIZE(jsonb) - VARHDRSZ; +} + /* * Turn an in-memory JsonbValue into a Jsonb for on-disk storage. * - * There isn't a JsonbToJsonbValue(), because generally we find it more - * convenient to directly iterate through the Jsonb representation and only - * really convert nested scalar values. JsonbIteratorNext() does this, so that - * clients of the iteration code don't have to directly deal with the binary - * representation (JsonbDeepContains() is a notable exception, although all - * exceptions are internal to this module). In general, functions that accept - * a JsonbValue argument are concerned with the manipulation of scalar values, - * or simple containers of scalar values, where it would be inconvenient to - * deal with a great amount of other state. + * Generally we find it more convenient to directly iterate through the Jsonb + * representation and only really convert nested scalar values. + * JsonbIteratorNext() does this, so that clients of the iteration code don't + * have to directly deal with the binary representation (JsonbDeepContains() is + * a notable exception, although all exceptions are internal to this module). + * In general, functions that accept a JsonbValue argument are concerned with + * the manipulation of scalar values, or simple containers of scalar values, + * where it would be inconvenient to deal with a great amount of other state. */ Jsonb * JsonbValueToJsonb(JsonbValue *val) @@ -563,6 +570,30 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, JsonbValue *res = NULL; JsonbValue v; JsonbIteratorToken tok; + int i; + + if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvObject) + { + pushJsonbValue(pstate, WJB_BEGIN_OBJECT, NULL); + for (i = 0; i < jbval->val.object.nPairs; i++) + { + pushJsonbValue(pstate, WJB_KEY, &jbval->val.object.pairs[i].key); + pushJsonbValue(pstate, WJB_VALUE, &jbval->val.object.pairs[i].value); + } + + return pushJsonbValue(pstate, WJB_END_OBJECT, NULL); + } + + if (jbval && (seq == WJB_ELEM || seq == WJB_VALUE) && jbval->type == jbvArray) + { + pushJsonbValue(pstate, WJB_BEGIN_ARRAY, NULL); + for (i = 0; i < jbval->val.array.nElems; i++) + { + pushJsonbValue(pstate, WJB_ELEM, &jbval->val.array.elems[i]); + } + + return pushJsonbValue(pstate, WJB_END_ARRAY, NULL); + } if (!jbval || (seq != WJB_ELEM && seq != WJB_VALUE) || jbval->type != jbvBinary) @@ -573,9 +604,30 @@ pushJsonbValue(JsonbParseState **pstate, JsonbIteratorToken seq, /* unpack the binary and add each piece to the pstate */ it = JsonbIteratorInit(jbval->val.binary.data); + + if ((jbval->val.binary.data->header & JB_FSCALAR) && *pstate) + { + tok = JsonbIteratorNext(&it, &v, true); + Assert(tok == WJB_BEGIN_ARRAY); + Assert(v.type == jbvArray && v.val.array.rawScalar); + + tok = JsonbIteratorNext(&it, &v, true); + Assert(tok == WJB_ELEM); + + res = pushJsonbValueScalar(pstate, seq, &v); + + tok = JsonbIteratorNext(&it, &v, true); + Assert(tok == WJB_END_ARRAY); + Assert(it == NULL); + + return res; + } + while ((tok = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) res = pushJsonbValueScalar(pstate, tok, - tok < WJB_BEGIN_ARRAY ? &v : NULL); + tok < WJB_BEGIN_ARRAY || + (tok == WJB_BEGIN_ARRAY && + v.val.array.rawScalar) ? &v : NULL); return res; } diff --git a/src/backend/utils/adt/jsonbsubs.c b/src/backend/utils/adt/jsonbsubs.c new file mode 100644 index 000000000000..47a89457dbee --- /dev/null +++ b/src/backend/utils/adt/jsonbsubs.c @@ -0,0 +1,417 @@ +/*------------------------------------------------------------------------- + * + * jsonbsubs.c + * Subscripting support functions for jsonb. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/adt/jsonbsubs.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "executor/execExpr.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "nodes/subscripting.h" +#include "parser/parse_coerce.h" +#include "parser/parse_expr.h" +#include "utils/jsonb.h" +#include "utils/jsonfuncs.h" +#include "utils/builtins.h" +#include "utils/lsyscache.h" + + +/* SubscriptingRefState.workspace for jsonb subscripting execution */ +typedef struct JsonbSubWorkspace +{ + bool expectArray; /* jsonb root is expected to be an array */ + Oid *indexOid; /* OID of coerced subscript expression, could + * be only integer or text */ + Datum *index; /* Subscript values in Datum format */ +} JsonbSubWorkspace; + + +/* + * Finish parse analysis of a SubscriptingRef expression for a jsonb. + * + * Transform the subscript expressions, coerce them to text, + * and determine the result type of the SubscriptingRef node. + */ +static void +jsonb_subscript_transform(SubscriptingRef *sbsref, + List *indirection, + ParseState *pstate, + bool isSlice, + bool isAssignment) +{ + List *upperIndexpr = NIL; + ListCell *idx; + + /* + * Transform and convert the subscript expressions. Jsonb subscripting + * does not support slices, look only and the upper index. + */ + foreach(idx, indirection) + { + A_Indices *ai = lfirst_node(A_Indices, idx); + Node *subExpr; + + if (isSlice) + { + Node *expr = ai->uidx ? ai->uidx : ai->lidx; + + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("jsonb subscript does not support slices"), + parser_errposition(pstate, exprLocation(expr)))); + } + + if (ai->uidx) + { + Oid subExprType = InvalidOid, + targetType = UNKNOWNOID; + + subExpr = transformExpr(pstate, ai->uidx, pstate->p_expr_kind); + subExprType = exprType(subExpr); + + if (subExprType != UNKNOWNOID) + { + Oid targets[2] = {INT4OID, TEXTOID}; + + /* + * Jsonb can handle multiple subscript types, but cases when a + * subscript could be coerced to multiple target types must be + * avoided, similar to overloaded functions. It could be + * possibly extend with jsonpath in the future. + */ + for (int i = 0; i < 2; i++) + { + if (can_coerce_type(1, &subExprType, &targets[i], COERCION_IMPLICIT)) + { + /* + * One type has already succeeded, it means there are + * two coercion targets possible, failure. + */ + if (targetType != UNKNOWNOID) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("subscript type is not supported"), + errhint("Jsonb subscript must be coerced " + "only to one type, integer or text."), + parser_errposition(pstate, exprLocation(subExpr)))); + + targetType = targets[i]; + } + } + + /* + * No suitable types were found, failure. + */ + if (targetType == UNKNOWNOID) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("subscript type is not supported"), + errhint("Jsonb subscript must be coerced to either integer or text"), + parser_errposition(pstate, exprLocation(subExpr)))); + } + else + targetType = TEXTOID; + + /* + * We known from can_coerce_type that coercion will succeed, so + * coerce_type could be used. Note the implicit coercion context, + * which is required to handle subscripts of different types, + * similar to overloaded functions. + */ + subExpr = coerce_type(pstate, + subExpr, subExprType, + targetType, -1, + COERCION_IMPLICIT, + COERCE_IMPLICIT_CAST, + -1); + if (subExpr == NULL) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("jsonb subscript must have text type"), + parser_errposition(pstate, exprLocation(subExpr)))); + } + else + { + /* + * Slice with omitted upper bound. Should not happen as we already + * errored out on slice earlier, but handle this just in case. + */ + Assert(isSlice && ai->is_slice); + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("jsonb subscript does not support slices"), + parser_errposition(pstate, exprLocation(ai->uidx)))); + } + + upperIndexpr = lappend(upperIndexpr, subExpr); + } + + /* store the transformed lists into the SubscriptRef node */ + sbsref->refupperindexpr = upperIndexpr; + sbsref->reflowerindexpr = NIL; + + /* Determine the result type of the subscripting operation; always jsonb */ + sbsref->refrestype = JSONBOID; + sbsref->reftypmod = -1; +} + +/* + * During execution, process the subscripts in a SubscriptingRef expression. + * + * The subscript expressions are already evaluated in Datum form in the + * SubscriptingRefState's arrays. Check and convert them as necessary. + * + * If any subscript is NULL, we throw error in assignment cases, or in fetch + * cases set result to NULL and return false (instructing caller to skip the + * rest of the SubscriptingRef sequence). + */ +static bool +jsonb_subscript_check_subscripts(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state; + JsonbSubWorkspace *workspace = (JsonbSubWorkspace *) sbsrefstate->workspace; + + /* + * In case if the first subscript is an integer, the source jsonb is + * expected to be an array. This information is not used directly, all + * such cases are handled within corresponding jsonb assign functions. But + * if the source jsonb is NULL the expected type will be used to construct + * an empty source. + */ + if (sbsrefstate->numupper > 0 && sbsrefstate->upperprovided[0] && + !sbsrefstate->upperindexnull[0] && workspace->indexOid[0] == INT4OID) + workspace->expectArray = true; + + /* Process upper subscripts */ + for (int i = 0; i < sbsrefstate->numupper; i++) + { + if (sbsrefstate->upperprovided[i]) + { + /* If any index expr yields NULL, result is NULL or error */ + if (sbsrefstate->upperindexnull[i]) + { + if (sbsrefstate->isassignment) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("jsonb subscript in assignment must not be null"))); + *op->resnull = true; + return false; + } + + /* + * For jsonb fetch and assign functions we need to provide path in + * text format. Convert if it's not already text. + */ + if (workspace->indexOid[i] == INT4OID) + { + Datum datum = sbsrefstate->upperindex[i]; + char *cs = DatumGetCString(DirectFunctionCall1(int4out, datum)); + + workspace->index[i] = CStringGetTextDatum(cs); + } + else + workspace->index[i] = sbsrefstate->upperindex[i]; + } + } + + return true; +} + +/* + * Evaluate SubscriptingRef fetch for a jsonb element. + * + * Source container is in step's result variable (it's known not NULL, since + * we set fetch_strict to true). + */ +static void +jsonb_subscript_fetch(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + JsonbSubWorkspace *workspace = (JsonbSubWorkspace *) sbsrefstate->workspace; + Jsonb *jsonbSource; + + /* Should not get here if source jsonb (or any subscript) is null */ + Assert(!(*op->resnull)); + + jsonbSource = DatumGetJsonbP(*op->resvalue); + *op->resvalue = jsonb_get_element(jsonbSource, + workspace->index, + sbsrefstate->numupper, + op->resnull, + false); +} + +/* + * Evaluate SubscriptingRef assignment for a jsonb element assignment. + * + * Input container (possibly null) is in result area, replacement value is in + * SubscriptingRefState's replacevalue/replacenull. + */ +static void +jsonb_subscript_assign(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + JsonbSubWorkspace *workspace = (JsonbSubWorkspace *) sbsrefstate->workspace; + Jsonb *jsonbSource; + JsonbValue replacevalue; + + if (sbsrefstate->replacenull) + replacevalue.type = jbvNull; + else + JsonbToJsonbValue(DatumGetJsonbP(sbsrefstate->replacevalue), + &replacevalue); + + /* + * In case if the input container is null, set up an empty jsonb and + * proceed with the assignment. + */ + if (*op->resnull) + { + JsonbValue newSource; + + /* + * To avoid any surprising results, set up an empty jsonb array in + * case of an array is expected (i.e. the first subscript is integer), + * otherwise jsonb object. + */ + if (workspace->expectArray) + { + newSource.type = jbvArray; + newSource.val.array.nElems = 0; + newSource.val.array.rawScalar = false; + } + else + { + newSource.type = jbvObject; + newSource.val.object.nPairs = 0; + } + + jsonbSource = JsonbValueToJsonb(&newSource); + *op->resnull = false; + } + else + jsonbSource = DatumGetJsonbP(*op->resvalue); + + *op->resvalue = jsonb_set_element(jsonbSource, + workspace->index, + sbsrefstate->numupper, + &replacevalue); + /* The result is never NULL, so no need to change *op->resnull */ +} + +/* + * Compute old jsonb element value for a SubscriptingRef assignment + * expression. Will only be called if the new-value subexpression + * contains SubscriptingRef or FieldStore. This is the same as the + * regular fetch case, except that we have to handle a null jsonb, + * and the value should be stored into the SubscriptingRefState's + * prevvalue/prevnull fields. + */ +static void +jsonb_subscript_fetch_old(ExprState *state, + ExprEvalStep *op, + ExprContext *econtext) +{ + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; + + if (*op->resnull) + { + /* whole jsonb is null, so any element is too */ + sbsrefstate->prevvalue = (Datum) 0; + sbsrefstate->prevnull = true; + } + else + { + Jsonb *jsonbSource = DatumGetJsonbP(*op->resvalue); + + sbsrefstate->prevvalue = jsonb_get_element(jsonbSource, + sbsrefstate->upperindex, + sbsrefstate->numupper, + &sbsrefstate->prevnull, + false); + } +} + +/* + * Set up execution state for a jsonb subscript operation. Opposite to the + * arrays subscription, there is no limit for number of subscripts as jsonb + * type itself doesn't have nesting limits. + */ +static void +jsonb_exec_setup(const SubscriptingRef *sbsref, + SubscriptingRefState *sbsrefstate, + SubscriptExecSteps *methods) +{ + JsonbSubWorkspace *workspace; + ListCell *lc; + int nupper = sbsref->refupperindexpr->length; + char *ptr; + + /* Allocate type-specific workspace with space for per-subscript data */ + workspace = palloc0(MAXALIGN(sizeof(JsonbSubWorkspace)) + + nupper * (sizeof(Datum) + sizeof(Oid))); + workspace->expectArray = false; + ptr = ((char *) workspace) + MAXALIGN(sizeof(JsonbSubWorkspace)); + + /* + * This coding assumes sizeof(Datum) >= sizeof(Oid), else we might + * misalign the indexOid pointer + */ + workspace->index = (Datum *) ptr; + ptr += nupper * sizeof(Datum); + workspace->indexOid = (Oid *) ptr; + + sbsrefstate->workspace = workspace; + + /* Collect subscript data types necessary at execution time */ + foreach(lc, sbsref->refupperindexpr) + { + Node *expr = lfirst(lc); + int i = foreach_current_index(lc); + + workspace->indexOid[i] = exprType(expr); + } + + /* + * Pass back pointers to appropriate step execution functions. + */ + methods->sbs_check_subscripts = jsonb_subscript_check_subscripts; + methods->sbs_fetch = jsonb_subscript_fetch; + methods->sbs_assign = jsonb_subscript_assign; + methods->sbs_fetch_old = jsonb_subscript_fetch_old; +} + +/* + * jsonb_subscript_handler + * Subscripting handler for jsonb. + * + */ +Datum +jsonb_subscript_handler(PG_FUNCTION_ARGS) +{ + static const SubscriptRoutines sbsroutines = { + .transform = jsonb_subscript_transform, + .exec_setup = jsonb_exec_setup, + .fetch_strict = true, /* fetch returns NULL for NULL inputs */ + .fetch_leakproof = true, /* fetch returns NULL for bad subscript */ + .store_leakproof = false /* ... but assignment throws error */ + }; + + PG_RETURN_POINTER(&sbsroutines); +} diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index b1a62deea6e8..09fcff67299b 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -3,7 +3,7 @@ * jsonfuncs.c * Functions to process JSON data types. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,6 +19,7 @@ #include "access/htup_details.h" #include "catalog/pg_type.h" #include "common/jsonapi.h" +#include "common/string.h" #include "fmgr.h" #include "funcapi.h" #include "lib/stringinfo.h" @@ -26,6 +27,7 @@ #include "miscadmin.h" #include "utils/array.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" #include "utils/hsearch.h" #include "utils/json.h" #include "utils/jsonb.h" @@ -43,6 +45,8 @@ #define JB_PATH_INSERT_AFTER 0x0010 #define JB_PATH_CREATE_OR_INSERT \ (JB_PATH_INSERT_BEFORE | JB_PATH_INSERT_AFTER | JB_PATH_CREATE) +#define JB_PATH_FILL_GAPS 0x0020 +#define JB_PATH_CONSISTENT_POSITION 0x0040 /* state for json_object_keys */ typedef struct OkeysState @@ -462,16 +466,16 @@ static JsonbValue *IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, JsonbParseState **state); static JsonbValue *setPath(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, - JsonbParseState **st, int level, Jsonb *newval, + JsonbParseState **st, int level, JsonbValue *newval, int op_type); static void setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, int level, - Jsonb *newval, uint32 npairs, int op_type); + JsonbValue *newval, uint32 npairs, int op_type); static void setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, - int level, Jsonb *newval, uint32 nelems, int op_type); -static void addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb); + int level, + JsonbValue *newval, uint32 nelems, int op_type); /* function supporting iterate_json_values */ static void iterate_values_scalar(void *state, char *token, JsonTokenType tokentype); @@ -637,30 +641,19 @@ report_json_context(JsonLexContext *lex) const char *context_start; const char *context_end; const char *line_start; - int line_number; char *ctxt; int ctxtlen; const char *prefix; const char *suffix; /* Choose boundaries for the part of the input we will display */ - context_start = lex->input; + line_start = lex->line_start; + context_start = line_start; context_end = lex->token_terminator; - line_start = context_start; - line_number = 1; - for (;;) + + /* Advance until we are close enough to context_end */ + while (context_end - context_start >= 50 && context_start < context_end) { - /* Always advance over newlines */ - if (context_start < context_end && *context_start == '\n') - { - context_start++; - line_start = context_start; - line_number++; - continue; - } - /* Otherwise, done as soon as we are close enough to context_end */ - if (context_end - context_start < 50) - break; /* Advance to next multibyte character */ if (IS_HIGHBIT_SET(*context_start)) context_start += pg_mblen(context_start); @@ -689,10 +682,8 @@ report_json_context(JsonLexContext *lex) prefix = (context_start > line_start) ? "..." : ""; suffix = (lex->token_type != JSON_TOKEN_END && context_end - lex->input < lex->input_length && *context_end != '\n' && *context_end != '\r') ? "..." : ""; - errcontext("JSON data, line %d: %s%s%s", - line_number, prefix, ctxt, suffix); - - return 0; + return errcontext("JSON data, line %d: %s%s%s", + lex->line_number, prefix, ctxt, suffix); } @@ -1025,15 +1016,15 @@ get_path_all(FunctionCallInfo fcinfo, bool as_text) */ if (*tpath[i] != '\0') { - long ind; + int ind; char *endptr; errno = 0; - ind = strtol(tpath[i], &endptr, 10); - if (*endptr == '\0' && errno == 0 && ind <= INT_MAX && ind >= INT_MIN) - ipath[i] = (int) ind; - else + ind = strtoint(tpath[i], &endptr, 10); + if (endptr == tpath[i] || *endptr != '\0' || errno != 0) ipath[i] = INT_MIN; + else + ipath[i] = ind; } else ipath[i] = INT_MIN; @@ -1449,13 +1440,9 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) ArrayType *path = PG_GETARG_ARRAYTYPE_P(1); Datum *pathtext; bool *pathnulls; + bool isnull; int npath; - int i; - bool have_object = false, - have_array = false; - JsonbValue *jbvp = NULL; - JsonbValue jbvbuf; - JsonbContainer *container; + Datum res; /* * If the array contains any null elements, return NULL, on the grounds @@ -1470,9 +1457,26 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) deconstruct_array(path, TEXTOID, -1, false, TYPALIGN_INT, &pathtext, &pathnulls, &npath); - /* Identify whether we have object, array, or scalar at top-level */ - container = &jb->root; + res = jsonb_get_element(jb, pathtext, npath, &isnull, as_text); + + if (isnull) + PG_RETURN_NULL(); + else + PG_RETURN_DATUM(res); +} + +Datum +jsonb_get_element(Jsonb *jb, Datum *path, int npath, bool *isnull, bool as_text) +{ + JsonbContainer *container = &jb->root; + JsonbValue *jbvp = NULL; + int i; + bool have_object = false, + have_array = false; + + *isnull = false; + /* Identify whether we have object, array, or scalar at top-level */ if (JB_ROOT_IS_OBJECT(jb)) have_object = true; else if (JB_ROOT_IS_ARRAY(jb) && !JB_ROOT_IS_SCALAR(jb)) @@ -1497,9 +1501,9 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) { if (as_text) { - PG_RETURN_TEXT_P(cstring_to_text(JsonbToCString(NULL, - container, - VARSIZE(jb)))); + return PointerGetDatum(cstring_to_text(JsonbToCString(NULL, + container, + VARSIZE(jb)))); } else { @@ -1513,22 +1517,24 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) if (have_object) { jbvp = getKeyJsonValueFromContainer(container, - VARDATA(pathtext[i]), - VARSIZE(pathtext[i]) - VARHDRSZ, - &jbvbuf); + VARDATA(path[i]), + VARSIZE(path[i]) - VARHDRSZ, + NULL); } else if (have_array) { - long lindex; + int lindex; uint32 index; - char *indextext = TextDatumGetCString(pathtext[i]); + char *indextext = TextDatumGetCString(path[i]); char *endptr; errno = 0; - lindex = strtol(indextext, &endptr, 10); - if (endptr == indextext || *endptr != '\0' || errno != 0 || - lindex > INT_MAX || lindex < INT_MIN) - PG_RETURN_NULL(); + lindex = strtoint(indextext, &endptr, 10); + if (endptr == indextext || *endptr != '\0' || errno != 0) + { + *isnull = true; + return PointerGetDatum(NULL); + } if (lindex >= 0) { @@ -1545,8 +1551,11 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) nelements = JsonContainerSize(container); - if (-lindex > nelements) - PG_RETURN_NULL(); + if (lindex == INT_MIN || -lindex > nelements) + { + *isnull = true; + return PointerGetDatum(NULL); + } else index = nelements + lindex; } @@ -1556,11 +1565,15 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) else { /* scalar, extraction yields a null */ - PG_RETURN_NULL(); + *isnull = true; + return PointerGetDatum(NULL); } if (jbvp == NULL) - PG_RETURN_NULL(); + { + *isnull = true; + return PointerGetDatum(NULL); + } else if (i == npath - 1) break; @@ -1582,9 +1595,12 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) if (as_text) { if (jbvp->type == jbvNull) - PG_RETURN_NULL(); + { + *isnull = true; + return PointerGetDatum(NULL); + } - PG_RETURN_TEXT_P(JsonbValueAsText(jbvp)); + return PointerGetDatum(JsonbValueAsText(jbvp)); } else { @@ -1595,6 +1611,129 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) } } +Datum +jsonb_set_element(Jsonb *jb, Datum *path, int path_len, + JsonbValue *newval) +{ + JsonbValue *res; + JsonbParseState *state = NULL; + JsonbIterator *it; + bool *path_nulls = palloc0(path_len * sizeof(bool)); + + if (newval->type == jbvArray && newval->val.array.rawScalar) + *newval = newval->val.array.elems[0]; + + it = JsonbIteratorInit(&jb->root); + + res = setPath(&it, path, path_nulls, path_len, &state, 0, newval, + JB_PATH_CREATE | JB_PATH_FILL_GAPS | + JB_PATH_CONSISTENT_POSITION); + + pfree(path_nulls); + + PG_RETURN_JSONB_P(JsonbValueToJsonb(res)); +} + +static void +push_null_elements(JsonbParseState **ps, int num) +{ + JsonbValue null; + + null.type = jbvNull; + + while (num-- > 0) + pushJsonbValue(ps, WJB_ELEM, &null); +} + +/* + * Prepare a new structure containing nested empty objects and arrays + * corresponding to the specified path, and assign a new value at the end of + * this path. E.g. the path [a][0][b] with the new value 1 will produce the + * structure {a: [{b: 1}]}. + * + * Caller is responsible to make sure such path does not exist yet. + */ +static void +push_path(JsonbParseState **st, int level, Datum *path_elems, + bool *path_nulls, int path_len, JsonbValue *newval) +{ + /* + * tpath contains expected type of an empty jsonb created at each level + * higher or equal than the current one, either jbvObject or jbvArray. + * Since it contains only information about path slice from level to the + * end, the access index must be normalized by level. + */ + enum jbvType *tpath = palloc0((path_len - level) * sizeof(enum jbvType)); + JsonbValue newkey; + + /* + * Create first part of the chain with beginning tokens. For the current + * level WJB_BEGIN_OBJECT/WJB_BEGIN_ARRAY was already created, so start + * with the next one. + */ + for (int i = level + 1; i < path_len; i++) + { + char *c, + *badp; + int lindex; + + if (path_nulls[i]) + break; + + /* + * Try to convert to an integer to find out the expected type, object + * or array. + */ + c = TextDatumGetCString(path_elems[i]); + errno = 0; + lindex = strtoint(c, &badp, 10); + if (badp == c || *badp != '\0' || errno != 0) + { + /* text, an object is expected */ + newkey.type = jbvString; + newkey.val.string.len = VARSIZE_ANY_EXHDR(path_elems[i]); + newkey.val.string.val = VARDATA_ANY(path_elems[i]); + + (void) pushJsonbValue(st, WJB_BEGIN_OBJECT, NULL); + (void) pushJsonbValue(st, WJB_KEY, &newkey); + + tpath[i - level] = jbvObject; + } + else + { + /* integer, an array is expected */ + (void) pushJsonbValue(st, WJB_BEGIN_ARRAY, NULL); + + push_null_elements(st, lindex); + + tpath[i - level] = jbvArray; + } + } + + /* Insert an actual value for either an object or array */ + if (tpath[(path_len - level) - 1] == jbvArray) + { + (void) pushJsonbValue(st, WJB_ELEM, newval); + } + else + (void) pushJsonbValue(st, WJB_VALUE, newval); + + /* + * Close everything up to the last but one level. The last one will be + * closed outside of this function. + */ + for (int i = path_len - 1; i > level; i--) + { + if (path_nulls[i]) + break; + + if (tpath[i - level] == jbvObject) + (void) pushJsonbValue(st, WJB_END_OBJECT, NULL); + else + (void) pushJsonbValue(st, WJB_END_ARRAY, NULL); + } +} + /* * Return the text representation of the given JsonbValue. */ @@ -3013,7 +3152,7 @@ prepare_column_cache(ColumnIOData *column, column->io.composite.base_typmod = typmod; column->io.composite.domain_info = NULL; } - else if (type->typlen == -1 && OidIsValid(type->typelem)) + else if (IsTrueArrayType(type)) { column->typcat = TYPECAT_ARRAY; column->io.array.element_info = MemoryContextAllocZero(mcxt, @@ -3440,14 +3579,13 @@ get_json_object_as_hash(char *json, int len, const char *funcname) JsonLexContext *lex = makeJsonLexContextCstringLen(json, len, GetDatabaseEncoding(), true); JsonSemAction *sem; - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = NAMEDATALEN; ctl.entrysize = sizeof(JsonHashEntry); ctl.hcxt = CurrentMemoryContext; tab = hash_create("json object hashtable", 100, &ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_STRINGS | HASH_CONTEXT); state = palloc0(sizeof(JHashState)); sem = palloc0(sizeof(JsonSemAction)); @@ -3832,14 +3970,13 @@ populate_recordset_object_start(void *state) return; /* Object at level 1: set up a new hash table for this object */ - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = NAMEDATALEN; ctl.entrysize = sizeof(JsonHashEntry); ctl.hcxt = CurrentMemoryContext; _state->json_hash = hash_create("json object hashtable", 100, &ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_STRINGS | HASH_CONTEXT); } static void @@ -4154,58 +4291,6 @@ jsonb_strip_nulls(PG_FUNCTION_ARGS) PG_RETURN_POINTER(JsonbValueToJsonb(res)); } -/* - * Add values from the jsonb to the parse state. - * - * If the parse state container is an object, the jsonb is pushed as - * a value, not a key. - * - * This needs to be done using an iterator because pushJsonbValue doesn't - * like getting jbvBinary values, so we can't just push jb as a whole. - */ -static void -addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb) -{ - JsonbIterator *it; - JsonbValue *o = &(*jbps)->contVal; - JsonbValue v; - JsonbIteratorToken type; - - it = JsonbIteratorInit(&jb->root); - - Assert(o->type == jbvArray || o->type == jbvObject); - - if (JB_ROOT_IS_SCALAR(jb)) - { - (void) JsonbIteratorNext(&it, &v, false); /* skip array header */ - Assert(v.type == jbvArray); - (void) JsonbIteratorNext(&it, &v, false); /* fetch scalar value */ - - switch (o->type) - { - case jbvArray: - (void) pushJsonbValue(jbps, WJB_ELEM, &v); - break; - case jbvObject: - (void) pushJsonbValue(jbps, WJB_VALUE, &v); - break; - default: - elog(ERROR, "unexpected parent of nested structure"); - } - } - else - { - while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) - { - if (type == WJB_KEY || type == WJB_VALUE || type == WJB_ELEM) - (void) pushJsonbValue(jbps, type, &v); - else - (void) pushJsonbValue(jbps, type, NULL); - } - } - -} - /* * SQL function jsonb_pretty (jsonb) * @@ -4477,7 +4562,8 @@ jsonb_set(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB_P(0); ArrayType *path = PG_GETARG_ARRAYTYPE_P(1); - Jsonb *newval = PG_GETARG_JSONB_P(2); + Jsonb *newjsonb = PG_GETARG_JSONB_P(2); + JsonbValue newval; bool create = PG_GETARG_BOOL(3); JsonbValue *res = NULL; Datum *path_elems; @@ -4486,6 +4572,8 @@ jsonb_set(PG_FUNCTION_ARGS) JsonbIterator *it; JsonbParseState *st = NULL; + JsonbToJsonbValue(newjsonb, &newval); + if (ARR_NDIM(path) > 1) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), @@ -4508,7 +4596,7 @@ jsonb_set(PG_FUNCTION_ARGS) it = JsonbIteratorInit(&in->root); res = setPath(&it, path_elems, path_nulls, path_len, &st, - 0, newval, create ? JB_PATH_CREATE : JB_PATH_REPLACE); + 0, &newval, create ? JB_PATH_CREATE : JB_PATH_REPLACE); Assert(res != NULL); @@ -4635,7 +4723,8 @@ jsonb_insert(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB_P(0); ArrayType *path = PG_GETARG_ARRAYTYPE_P(1); - Jsonb *newval = PG_GETARG_JSONB_P(2); + Jsonb *newjsonb = PG_GETARG_JSONB_P(2); + JsonbValue newval; bool after = PG_GETARG_BOOL(3); JsonbValue *res = NULL; Datum *path_elems; @@ -4644,6 +4733,8 @@ jsonb_insert(PG_FUNCTION_ARGS) JsonbIterator *it; JsonbParseState *st = NULL; + JsonbToJsonbValue(newjsonb, &newval); + if (ARR_NDIM(path) > 1) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), @@ -4662,7 +4753,7 @@ jsonb_insert(PG_FUNCTION_ARGS) it = JsonbIteratorInit(&in->root); - res = setPath(&it, path_elems, path_nulls, path_len, &st, 0, newval, + res = setPath(&it, path_elems, path_nulls, path_len, &st, 0, &newval, after ? JB_PATH_INSERT_AFTER : JB_PATH_INSERT_BEFORE); Assert(res != NULL); @@ -4689,36 +4780,39 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, rk1, rk2; - r1 = rk1 = JsonbIteratorNext(it1, &v1, false); - r2 = rk2 = JsonbIteratorNext(it2, &v2, false); + rk1 = JsonbIteratorNext(it1, &v1, false); + rk2 = JsonbIteratorNext(it2, &v2, false); /* - * Both elements are objects. + * JsonbIteratorNext reports raw scalars as if they were single-element + * arrays; hence we only need consider "object" and "array" cases here. */ if (rk1 == WJB_BEGIN_OBJECT && rk2 == WJB_BEGIN_OBJECT) { /* - * Append the all tokens from v1 to res, except last WJB_END_OBJECT + * Both inputs are objects. + * + * Append all the tokens from v1 to res, except last WJB_END_OBJECT * (because res will not be finished yet). */ - pushJsonbValue(state, r1, NULL); + pushJsonbValue(state, rk1, NULL); while ((r1 = JsonbIteratorNext(it1, &v1, true)) != WJB_END_OBJECT) pushJsonbValue(state, r1, &v1); /* - * Append the all tokens from v2 to res, include last WJB_END_OBJECT - * (the concatenation will be completed). + * Append all the tokens from v2 to res, including last WJB_END_OBJECT + * (the concatenation will be completed). Any duplicate keys will + * automatically override the value from the first object. */ while ((r2 = JsonbIteratorNext(it2, &v2, true)) != WJB_DONE) res = pushJsonbValue(state, r2, r2 != WJB_END_OBJECT ? &v2 : NULL); } - - /* - * Both elements are arrays (either can be scalar). - */ else if (rk1 == WJB_BEGIN_ARRAY && rk2 == WJB_BEGIN_ARRAY) { - pushJsonbValue(state, r1, NULL); + /* + * Both inputs are arrays. + */ + pushJsonbValue(state, rk1, NULL); while ((r1 = JsonbIteratorNext(it1, &v1, true)) != WJB_END_ARRAY) { @@ -4734,48 +4828,40 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, res = pushJsonbValue(state, WJB_END_ARRAY, NULL /* signal to sort */ ); } - /* have we got array || object or object || array? */ - else if (((rk1 == WJB_BEGIN_ARRAY && !(*it1)->isScalar) && rk2 == WJB_BEGIN_OBJECT) || - (rk1 == WJB_BEGIN_OBJECT && (rk2 == WJB_BEGIN_ARRAY && !(*it2)->isScalar))) + else if (rk1 == WJB_BEGIN_OBJECT) { - - JsonbIterator **it_array = rk1 == WJB_BEGIN_ARRAY ? it1 : it2; - JsonbIterator **it_object = rk1 == WJB_BEGIN_OBJECT ? it1 : it2; - - bool prepend = (rk1 == WJB_BEGIN_OBJECT); + /* + * We have object || array. + */ + Assert(rk2 == WJB_BEGIN_ARRAY); pushJsonbValue(state, WJB_BEGIN_ARRAY, NULL); - if (prepend) - { - pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL); - while ((r1 = JsonbIteratorNext(it_object, &v1, true)) != WJB_DONE) - pushJsonbValue(state, r1, r1 != WJB_END_OBJECT ? &v1 : NULL); - - while ((r2 = JsonbIteratorNext(it_array, &v2, true)) != WJB_DONE) - res = pushJsonbValue(state, r2, r2 != WJB_END_ARRAY ? &v2 : NULL); - } - else - { - while ((r1 = JsonbIteratorNext(it_array, &v1, true)) != WJB_END_ARRAY) - pushJsonbValue(state, r1, &v1); + pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL); + while ((r1 = JsonbIteratorNext(it1, &v1, true)) != WJB_DONE) + pushJsonbValue(state, r1, r1 != WJB_END_OBJECT ? &v1 : NULL); - pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL); - while ((r2 = JsonbIteratorNext(it_object, &v2, true)) != WJB_DONE) - pushJsonbValue(state, r2, r2 != WJB_END_OBJECT ? &v2 : NULL); - - res = pushJsonbValue(state, WJB_END_ARRAY, NULL); - } + while ((r2 = JsonbIteratorNext(it2, &v2, true)) != WJB_DONE) + res = pushJsonbValue(state, r2, r2 != WJB_END_ARRAY ? &v2 : NULL); } else { /* - * This must be scalar || object or object || scalar, as that's all - * that's left. Both of these make no sense, so error out. + * We have array || object. */ - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid concatenation of jsonb objects"))); + Assert(rk1 == WJB_BEGIN_ARRAY); + Assert(rk2 == WJB_BEGIN_OBJECT); + + pushJsonbValue(state, WJB_BEGIN_ARRAY, NULL); + + while ((r1 = JsonbIteratorNext(it1, &v1, true)) != WJB_END_ARRAY) + pushJsonbValue(state, r1, &v1); + + pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL); + while ((r2 = JsonbIteratorNext(it2, &v2, true)) != WJB_DONE) + pushJsonbValue(state, r2, r2 != WJB_END_OBJECT ? &v2 : NULL); + + res = pushJsonbValue(state, WJB_END_ARRAY, NULL); } return res; @@ -4792,13 +4878,28 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, * Bits JB_PATH_INSERT_BEFORE and JB_PATH_INSERT_AFTER in op_type * behave as JB_PATH_CREATE if new value is inserted in JsonbObject. * + * If JB_PATH_FILL_GAPS bit is set, this will change an assignment logic in + * case if target is an array. The assignment index will not be restricted by + * number of elements in the array, and if there are any empty slots between + * last element of the array and a new one they will be filled with nulls. If + * the index is negative, it still will be considered an index from the end + * of the array. Of a part of the path is not present and this part is more + * than just one last element, this flag will instruct to create the whole + * chain of corresponding objects and insert the value. + * + * JB_PATH_CONSISTENT_POSITION for an array indicates that the caller wants to + * keep values with fixed indices. Indices for existing elements could be + * changed (shifted forward) in case if the array is prepended with a new value + * and a negative index out of the range, so this behavior will be prevented + * and return an error. + * * All path elements before the last must already exist * whatever bits in op_type are set, or nothing is done. */ static JsonbValue * setPath(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, - JsonbParseState **st, int level, Jsonb *newval, int op_type) + JsonbParseState **st, int level, JsonbValue *newval, int op_type) { JsonbValue v; JsonbIteratorToken r; @@ -4817,6 +4918,21 @@ setPath(JsonbIterator **it, Datum *path_elems, switch (r) { case WJB_BEGIN_ARRAY: + + /* + * If instructed complain about attempts to replace whithin a raw + * scalar value. This happens even when current level is equal to + * path_len, because the last path key should also correspond to + * an object or an array, not raw scalar. + */ + if ((op_type & JB_PATH_FILL_GAPS) && (level <= path_len - 1) && + v.val.array.rawScalar) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("cannot replace existing key"), + errdetail("The path assumes key is a composite object, " + "but it is a scalar value."))); + (void) pushJsonbValue(st, r, NULL); setPathArray(it, path_elems, path_nulls, path_len, st, level, newval, v.val.array.nElems, op_type); @@ -4834,6 +4950,20 @@ setPath(JsonbIterator **it, Datum *path_elems, break; case WJB_ELEM: case WJB_VALUE: + + /* + * If instructed complain about attempts to replace whithin a + * scalar value. This happens even when current level is equal to + * path_len, because the last path key should also correspond to + * an object or an array, not an element or value. + */ + if ((op_type & JB_PATH_FILL_GAPS) && (level <= path_len - 1)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("cannot replace existing key"), + errdetail("The path assumes key is a composite object, " + "but it is a scalar value."))); + res = pushJsonbValue(st, r, &v); break; default: @@ -4851,11 +4981,11 @@ setPath(JsonbIterator **it, Datum *path_elems, static void setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, int level, - Jsonb *newval, uint32 npairs, int op_type) + JsonbValue *newval, uint32 npairs, int op_type) { - JsonbValue v; int i; - JsonbValue k; + JsonbValue k, + v; bool done = false; if (level >= path_len || path_nulls[level]) @@ -4872,7 +5002,7 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, newkey.val.string.val = VARDATA_ANY(path_elems[level]); (void) pushJsonbValue(st, WJB_KEY, &newkey); - addJsonbToParseState(st, newval); + (void) pushJsonbValue(st, WJB_VALUE, newval); } for (i = 0; i < npairs; i++) @@ -4886,6 +5016,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, memcmp(k.val.string.val, VARDATA_ANY(path_elems[level]), k.val.string.len) == 0) { + done = true; + if (level == path_len - 1) { /* @@ -4903,9 +5035,8 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, if (!(op_type & JB_PATH_DELETE)) { (void) pushJsonbValue(st, WJB_KEY, &k); - addJsonbToParseState(st, newval); + (void) pushJsonbValue(st, WJB_VALUE, newval); } - done = true; } else { @@ -4926,7 +5057,7 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, newkey.val.string.val = VARDATA_ANY(path_elems[level]); (void) pushJsonbValue(st, WJB_KEY, &newkey); - addJsonbToParseState(st, newval); + (void) pushJsonbValue(st, WJB_VALUE, newval); } (void) pushJsonbValue(st, r, &k); @@ -4950,6 +5081,31 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, } } } + + /*-- + * If we got here there are only few possibilities: + * - no target path was found, and an open object with some keys/values was + * pushed into the state + * - an object is empty, only WJB_BEGIN_OBJECT is pushed + * + * In both cases if instructed to create the path when not present, + * generate the whole chain of empty objects and insert the new value + * there. + */ + if (!done && (op_type & JB_PATH_FILL_GAPS) && (level < path_len - 1)) + { + JsonbValue newkey; + + newkey.type = jbvString; + newkey.val.string.len = VARSIZE_ANY_EXHDR(path_elems[level]); + newkey.val.string.val = VARDATA_ANY(path_elems[level]); + + (void) pushJsonbValue(st, WJB_KEY, &newkey); + (void) push_path(st, level, path_elems, path_nulls, + path_len, newval); + + /* Result is closed with WJB_END_OBJECT outside of this function */ + } } /* @@ -4958,7 +5114,7 @@ setPathObject(JsonbIterator **it, Datum *path_elems, bool *path_nulls, static void setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, int path_len, JsonbParseState **st, int level, - Jsonb *newval, uint32 nelems, int op_type) + JsonbValue *newval, uint32 nelems, int op_type) { JsonbValue v; int idx, @@ -4969,18 +5125,15 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, if (level < path_len && !path_nulls[level]) { char *c = TextDatumGetCString(path_elems[level]); - long lindex; char *badp; errno = 0; - lindex = strtol(c, &badp, 10); - if (errno != 0 || badp == c || *badp != '\0' || lindex > INT_MAX || - lindex < INT_MIN) + idx = strtoint(c, &badp, 10); + if (badp == c || *badp != '\0' || errno != 0) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("path element at position %d is not an integer: \"%s\"", level + 1, c))); - idx = lindex; } else idx = nelems; @@ -4988,25 +5141,48 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, if (idx < 0) { if (-idx > nelems) - idx = INT_MIN; + { + /* + * If asked to keep elements position consistent, it's not allowed + * to prepend the array. + */ + if (op_type & JB_PATH_CONSISTENT_POSITION) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("path element at position %d is out of range: %d", + level + 1, idx))); + else + idx = INT_MIN; + } else idx = nelems + idx; } - if (idx > 0 && idx > nelems) - idx = nelems; + /* + * Filling the gaps means there are no limits on the positive index are + * imposed, we can set any element. Otherwise limit the index by nelems. + */ + if (!(op_type & JB_PATH_FILL_GAPS)) + { + if (idx > 0 && idx > nelems) + idx = nelems; + } /* * if we're creating, and idx == INT_MIN, we prepend the new value to the * array also if the array is empty - in which case we don't really care * what the idx value is */ - if ((idx == INT_MIN || nelems == 0) && (level == path_len - 1) && (op_type & JB_PATH_CREATE_OR_INSERT)) { Assert(newval != NULL); - addJsonbToParseState(st, newval); + + if (op_type & JB_PATH_FILL_GAPS && nelems == 0 && idx > 0) + push_null_elements(st, idx); + + (void) pushJsonbValue(st, WJB_ELEM, newval); + done = true; } @@ -5017,12 +5193,14 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, if (i == idx && level < path_len) { + done = true; + if (level == path_len - 1) { r = JsonbIteratorNext(it, &v, true); /* skip */ if (op_type & (JB_PATH_INSERT_BEFORE | JB_PATH_CREATE)) - addJsonbToParseState(st, newval); + (void) pushJsonbValue(st, WJB_ELEM, newval); /* * We should keep current value only in case of @@ -5033,9 +5211,7 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, (void) pushJsonbValue(st, r, &v); if (op_type & (JB_PATH_INSERT_AFTER | JB_PATH_REPLACE)) - addJsonbToParseState(st, newval); - - done = true; + (void) pushJsonbValue(st, WJB_ELEM, newval); } else (void) setPath(it, path_elems, path_nulls, path_len, @@ -5063,14 +5239,42 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, (void) pushJsonbValue(st, r, r < WJB_BEGIN_ARRAY ? &v : NULL); } } - - if ((op_type & JB_PATH_CREATE_OR_INSERT) && !done && - level == path_len - 1 && i == nelems - 1) - { - addJsonbToParseState(st, newval); - } } } + + if ((op_type & JB_PATH_CREATE_OR_INSERT) && !done && level == path_len - 1) + { + /* + * If asked to fill the gaps, idx could be bigger than nelems, so + * prepend the new element with nulls if that's the case. + */ + if (op_type & JB_PATH_FILL_GAPS && idx > nelems) + push_null_elements(st, idx - nelems); + + (void) pushJsonbValue(st, WJB_ELEM, newval); + done = true; + } + + /*-- + * If we got here there are only few possibilities: + * - no target path was found, and an open array with some keys/values was + * pushed into the state + * - an array is empty, only WJB_BEGIN_ARRAY is pushed + * + * In both cases if instructed to create the path when not present, + * generate the whole chain of empty objects and insert the new value + * there. + */ + if (!done && (op_type & JB_PATH_FILL_GAPS) && (level < path_len - 1)) + { + if (idx > 0) + push_null_elements(st, idx - nelems); + + (void) push_path(st, level, path_elems, path_nulls, + path_len, newval); + + /* Result is closed with WJB_END_OBJECT outside of this function */ + } } /* diff --git a/src/backend/utils/adt/jsonpath.c b/src/backend/utils/adt/jsonpath.c index 3c0dc38a7f84..fa22546f22d5 100644 --- a/src/backend/utils/adt/jsonpath.c +++ b/src/backend/utils/adt/jsonpath.c @@ -53,7 +53,7 @@ * | |__| |__||________________________||___________________| | * |_______________________________________________________________________| * - * Copyright (c) 2019-2020, PostgreSQL Global Development Group + * Copyright (c) 2019-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/jsonpath.c @@ -660,7 +660,7 @@ printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, else if (v->content.anybounds.first == v->content.anybounds.last) { if (v->content.anybounds.first == PG_UINT32_MAX) - appendStringInfo(buf, "**{last}"); + appendStringInfoString(buf, "**{last}"); else appendStringInfo(buf, "**{%u}", v->content.anybounds.first); diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index f146767bfc3a..078aaef53928 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -35,7 +35,7 @@ * executeItemOptUnwrapTarget() function have 'unwrap' argument, which indicates * whether unwrapping of array is needed. When unwrap == true, each of array * members is passed to executeItemOptUnwrapTarget() again but with unwrap == false - * in order to evade subsequent array unwrapping. + * in order to avoid subsequent array unwrapping. * * All boolean expressions (predicates) are evaluated by executeBoolItem() * function, which returns tri-state JsonPathBool. When error is occurred @@ -49,7 +49,7 @@ * we calculate operands first. Then we check that results are numeric * singleton lists, calculate the result and pass it to the next path item. * - * Copyright (c) 2019-2020, PostgreSQL Global Development Group + * Copyright (c) 2019-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/jsonpath_exec.c @@ -263,7 +263,7 @@ static int compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, * implement @? and @@ operators, which in turn are intended to have an * index support. Thus, it's desirable to make it easier to achieve * consistency between index scan results and sequential scan results. - * So, we throw as less errors as possible. Regarding this function, + * So, we throw as few errors as possible. Regarding this function, * such behavior also matches behavior of JSON_EXISTS() clause of * SQL/JSON. Regarding jsonb_path_match(), this function doesn't have * an analogy in SQL/JSON, so we define its behavior on our own. @@ -842,9 +842,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, lastjbv = hasNext ? &tmpjbv : palloc(sizeof(*lastjbv)); lastjbv->type = jbvNumeric; - lastjbv->val.numeric = - DatumGetNumeric(DirectFunctionCall1(int4_numeric, - Int32GetDatum(last))); + lastjbv->val.numeric = int64_to_numeric(last); res = executeNextItem(cxt, jsp, &elem, lastjbv, found, hasNext); @@ -1012,9 +1010,7 @@ executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, jb = palloc(sizeof(*jb)); jb->type = jbvNumeric; - jb->val.numeric = - DatumGetNumeric(DirectFunctionCall1(int4_numeric, - Int32GetDatum(size))); + jb->val.numeric = int64_to_numeric(size); res = executeNextItem(cxt, jsp, NULL, jb, found, false); } @@ -1837,16 +1833,22 @@ executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, /* * According to SQL/JSON standard enumerate ISO formats for: date, * timetz, time, timestamptz, timestamp. + * + * We also support ISO 8601 for timestamps, because to_json[b]() + * functions use this format. */ static const char *fmt_str[] = { "yyyy-mm-dd", - "HH24:MI:SS TZH:TZM", - "HH24:MI:SS TZH", + "HH24:MI:SSTZH:TZM", + "HH24:MI:SSTZH", "HH24:MI:SS", - "yyyy-mm-dd HH24:MI:SS TZH:TZM", - "yyyy-mm-dd HH24:MI:SS TZH", - "yyyy-mm-dd HH24:MI:SS" + "yyyy-mm-dd HH24:MI:SSTZH:TZM", + "yyyy-mm-dd HH24:MI:SSTZH", + "yyyy-mm-dd HH24:MI:SS", + "yyyy-mm-dd\"T\"HH24:MI:SSTZH:TZM", + "yyyy-mm-dd\"T\"HH24:MI:SSTZH", + "yyyy-mm-dd\"T\"HH24:MI:SS" }; /* cache for format texts */ @@ -1979,8 +1981,7 @@ executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, id += (int64) cxt->baseObject.id * INT64CONST(10000000000); idval.type = jbvNumeric; - idval.val.numeric = DatumGetNumeric(DirectFunctionCall1(int8_numeric, - Int64GetDatum(id))); + idval.val.numeric = int64_to_numeric(id); it = JsonbIteratorInit(jbc); @@ -2587,9 +2588,9 @@ checkTimezoneIsUsedForCast(bool useTz, const char *type1, const char *type2) if (!useTz) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert value from %s to %s without timezone usage", + errmsg("cannot convert value from %s to %s without time zone usage", type1, type2), - errhint("Use *_tz() function for timezone support."))); + errhint("Use *_tz() function for time zone support."))); } /* Convert time datum to timetz datum */ @@ -2601,93 +2602,36 @@ castTimeToTimeTz(Datum time, bool useTz) return DirectFunctionCall1(time_timetz, time); } -/*--- - * Compares 'ts1' and 'ts2' timestamp, assuming that ts1 might be overflowed - * during cast from another datatype. - * - * 'overflow1' specifies overflow of 'ts1' value: - * 0 - no overflow, - * -1 - exceed lower boundary, - * 1 - exceed upper boundary. - */ -static int -cmpTimestampWithOverflow(Timestamp ts1, int overflow1, Timestamp ts2) -{ - /* - * All the timestamps we deal with in jsonpath are produced by - * to_datetime() method. So, they should be valid. - */ - Assert(IS_VALID_TIMESTAMP(ts2)); - - /* - * Timestamp, which exceed lower (upper) bound, is always lower (higher) - * than any valid timestamp except minus (plus) infinity. - */ - if (overflow1) - { - if (overflow1 < 0) - { - if (TIMESTAMP_IS_NOBEGIN(ts2)) - return 1; - else - return -1; - } - if (overflow1 > 0) - { - if (TIMESTAMP_IS_NOEND(ts2)) - return -1; - else - return 1; - } - } - - return timestamp_cmp_internal(ts1, ts2); -} - /* - * Compare date to timestamptz without throwing overflow error during cast. + * Compare date to timestamp. + * Note that this doesn't involve any timezone considerations. */ static int cmpDateToTimestamp(DateADT date1, Timestamp ts2, bool useTz) { - TimestampTz ts1; - int overflow = 0; - - ts1 = date2timestamp_opt_overflow(date1, &overflow); - - return cmpTimestampWithOverflow(ts1, overflow, ts2); + return date_cmp_timestamp_internal(date1, ts2); } /* - * Compare date to timestamptz without throwing overflow error during cast. + * Compare date to timestamptz. */ static int cmpDateToTimestampTz(DateADT date1, TimestampTz tstz2, bool useTz) { - TimestampTz tstz1; - int overflow = 0; - checkTimezoneIsUsedForCast(useTz, "date", "timestamptz"); - tstz1 = date2timestamptz_opt_overflow(date1, &overflow); - - return cmpTimestampWithOverflow(tstz1, overflow, tstz2); + return date_cmp_timestamptz_internal(date1, tstz2); } /* - * Compare timestamp to timestamptz without throwing overflow error during cast. + * Compare timestamp to timestamptz. */ static int cmpTimestampToTimestampTz(Timestamp ts1, TimestampTz tstz2, bool useTz) { - TimestampTz tstz1; - int overflow = 0; - checkTimezoneIsUsedForCast(useTz, "timestamp", "timestamptz"); - tstz1 = timestamp2timestamptz_opt_overflow(ts1, &overflow); - - return cmpTimestampWithOverflow(tstz1, overflow, tstz2); + return timestamp_cmp_timestamptz_internal(ts1, tstz2); } /* diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y index 88ef9550e9db..de3d97931ef4 100644 --- a/src/backend/utils/adt/jsonpath_gram.y +++ b/src/backend/utils/adt/jsonpath_gram.y @@ -6,7 +6,7 @@ * * Transforms tokenized jsonpath into tree of JsonPathParseItem structs. * - * Copyright (c) 2019-2020, PostgreSQL Global Development Group + * Copyright (c) 2019-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/jsonpath_gram.y @@ -153,7 +153,7 @@ scalar_value: | FALSE_P { $$ = makeItemBool(false); } | NUMERIC_P { $$ = makeItemNumeric(&$1); } | INT_P { $$ = makeItemNumeric(&$1); } - | VARIABLE_P { $$ = makeItemVariable(&$1); } + | VARIABLE_P { $$ = makeItemVariable(&$1); } ; comp_op: @@ -175,12 +175,12 @@ predicate: | expr comp_op expr { $$ = makeItemBinary($2, $1, $3); } | predicate AND_P predicate { $$ = makeItemBinary(jpiAnd, $1, $3); } | predicate OR_P predicate { $$ = makeItemBinary(jpiOr, $1, $3); } - | NOT_P delimited_predicate { $$ = makeItemUnary(jpiNot, $2); } + | NOT_P delimited_predicate { $$ = makeItemUnary(jpiNot, $2); } | '(' predicate ')' IS_P UNKNOWN_P { $$ = makeItemUnary(jpiIsUnknown, $2); } | expr STARTS_P WITH_P starts_with_initial { $$ = makeItemBinary(jpiStartsWith, $1, $4); } - | expr LIKE_REGEX_P STRING_P { $$ = makeItemLikeRegex($1, &$3, NULL); } + | expr LIKE_REGEX_P STRING_P { $$ = makeItemLikeRegex($1, &$3, NULL); } | expr LIKE_REGEX_P STRING_P FLAG_P STRING_P { $$ = makeItemLikeRegex($1, &$3, &$5); } ; @@ -441,7 +441,7 @@ makeItemList(List *list) while (end->next) end = end->next; - for_each_cell(cell, list, list_second_cell(list)) + for_each_from(cell, list, 1) { JsonPathParseItem *c = (JsonPathParseItem *) lfirst(cell); diff --git a/src/backend/utils/adt/jsonpath_scan.l b/src/backend/utils/adt/jsonpath_scan.l index f723462a1f75..72d4c5e946a8 100644 --- a/src/backend/utils/adt/jsonpath_scan.l +++ b/src/backend/utils/adt/jsonpath_scan.l @@ -7,7 +7,7 @@ * Splits jsonpath string into tokens represented as JsonPathString structs. * Decodes unicode and hex escaped strings. * - * Copyright (c) 2019-2020, PostgreSQL Global Development Group + * Copyright (c) 2019-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/jsonpath_scan.l diff --git a/src/backend/utils/adt/levenshtein.c b/src/backend/utils/adt/levenshtein.c index d11278c505be..f8979776d0d5 100644 --- a/src/backend/utils/adt/levenshtein.c +++ b/src/backend/utils/adt/levenshtein.c @@ -16,7 +16,7 @@ * PHP 4.0.6 distribution for inspiration. Configurable penalty costs * extension is introduced by Volkan YAZICI (7/95). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/adt/like_match.c b/src/backend/utils/adt/like_match.c index ee30170fbb44..2f32cdaf020a 100644 --- a/src/backend/utils/adt/like_match.c +++ b/src/backend/utils/adt/like_match.c @@ -16,7 +16,7 @@ * do_like_escape - name of function if wanted - needs CHAREQ and CopyAdvChar * MATCH_LOWER - define for case (4) to specify case folding for 1-byte chars * - * Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/like_match.c diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.c index bcfbaa1c3d18..241e6f0f598a 100644 --- a/src/backend/utils/adt/like_support.c +++ b/src/backend/utils/adt/like_support.c @@ -23,7 +23,7 @@ * from LIKE to indexscan limits rather harder than one might think ... * but that's the basic idea.) * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1442,9 +1442,18 @@ regex_selectivity(const char *patt, int pattlen, bool case_insensitive, sel *= FULL_WILDCARD_SEL; } - /* If there's a fixed prefix, discount its selectivity */ + /* + * If there's a fixed prefix, discount its selectivity. We have to be + * careful here since a very long prefix could result in pow's result + * underflowing to zero (in which case "sel" probably has as well). + */ if (fixed_prefix_len > 0) - sel /= pow(FIXED_CHAR_SEL, fixed_prefix_len); + { + double prefixsel = pow(FIXED_CHAR_SEL, fixed_prefix_len); + + if (prefixsel > 0.0) + sel /= prefixsel; + } /* Make sure result stays in range */ CLAMP_PROBABILITY(sel); diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c index f410ec055a6d..c930fbd709ac 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -3,7 +3,7 @@ * lockfuncs.c * Functions for SQL access to various lock-manager capabilities. * - * Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Copyright (c) 2002-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/lockfuncs.c @@ -75,7 +75,7 @@ typedef struct } PG_Lock_Status; /* Number of columns in pg_locks output */ -#define NUM_LOCK_STATUS_COLUMNS 18 +#define NUM_LOCK_STATUS_COLUMNS 19 /* * VXIDGetDatum - Construct a text representation of a VXID @@ -154,16 +154,19 @@ pg_lock_status(PG_FUNCTION_ARGS) BOOLOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 15, "fastpath", BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 16, "waitstart", + TIMESTAMPTZOID, -1, 0); /* * These next columns are specific to GPDB */ - TupleDescInitEntry(tupdesc, (AttrNumber) 16, "mppSessionId", + TupleDescInitEntry(tupdesc, (AttrNumber) 17, "mppSessionId", INT4OID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 17, "mppIsWriter", + TupleDescInitEntry(tupdesc, (AttrNumber) 18, "mppIsWriter", BOOLOID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 18, "gp_segment_id", + TupleDescInitEntry(tupdesc, (AttrNumber) 19, "gp_segment_id", INT4OID, -1, 0); + funcctx->tuple_desc = BlessTupleDesc(tupdesc); /* @@ -493,11 +496,10 @@ pg_lock_status(PG_FUNCTION_ARGS) values[13] = BoolGetDatum(granted); values[14] = BoolGetDatum(instance->fastpath); - values[15] = Int32GetDatum(instance->mppSessionId); - - values[16] = BoolGetDatum(instance->mppIsWriter); - - values[17] = Int32GetDatum(GpIdentity.segindex); + values[15] = (Datum) 0; /* waitstart: filled by caller */ + values[16] = Int32GetDatum(instance->mppSessionId); + values[17] = BoolGetDatum(instance->mppIsWriter); + values[18] = Int32GetDatum(GpIdentity.segindex); tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); @@ -581,9 +583,10 @@ pg_lock_status(PG_FUNCTION_ARGS) values[12] = CStringGetTextDatum(PQgetvalue(mystatus->segresults[whichresultset], whichrow, 12)); values[13] = BoolGetDatum(strncmp(PQgetvalue(mystatus->segresults[whichresultset], whichrow,13),"t",1)==0); values[14] = BoolGetDatum(strncmp(PQgetvalue(mystatus->segresults[whichresultset], whichrow,14),"t",1)==0); - values[15] = Int32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow,15))); - values[16] = BoolGetDatum(strncmp(PQgetvalue(mystatus->segresults[whichresultset], whichrow,16),"t",1)==0); - values[17] = Int32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow,17))); + values[15] = (Datum) 0; /* waitstart */ + values[16] = Int32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow,16))); + values[17] = BoolGetDatum(strncmp(PQgetvalue(mystatus->segresults[whichresultset], whichrow,17),"t",1)==0); + values[18] = Int32GetDatum(atoi(PQgetvalue(mystatus->segresults[whichresultset], whichrow,18))); /* * Copy the null info over. It should all match properly. @@ -592,7 +595,6 @@ pg_lock_status(PG_FUNCTION_ARGS) { nulls[i] = PQgetisnull(mystatus->segresults[whichresultset], whichrow, i); } - tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, result); @@ -662,15 +664,17 @@ pg_lock_status(PG_FUNCTION_ARGS) values[12] = CStringGetTextDatum("SIReadLock"); values[13] = BoolGetDatum(true); values[14] = BoolGetDatum(false); + nulls[15] = true; /* waitstart */ /* - * GPDB_91_MERGE_FIXME: what to set these GPDB-specific fields to? - * These commented-out values are copy-pasted from the code above - * for normal locks. + * The GPDB-specific columns (mppSessionId, mppIsWriter, + * gp_segment_id) are not meaningful for predicate locks; leave them + * NULL rather than reading uninitialized values[] (which would be a + * garbage read in heap_form_tuple). */ - //values[14] = Int32GetDatum(proc->mppSessionId); - //values[15] = BoolGetDatum(proc->mppIsWriter); - //values[16] = Int32GetDatum(Gp_segment); + nulls[16] = true; + nulls[17] = true; + nulls[18] = true; tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); @@ -908,10 +912,10 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS) * Check if any of these are in the list of interesting PIDs, that being * the sessions that the isolation tester is running. We don't use * "arrayoverlaps" here, because it would lead to cache lookups and one of - * our goals is to run quickly under CLOBBER_CACHE_ALWAYS. We expect - * blocking_pids to be usually empty and otherwise a very small number in - * isolation tester cases, so make that the outer loop of a naive search - * for a match. + * our goals is to run quickly with debug_invalidate_system_caches_always + * > 0. We expect blocking_pids to be usually empty and otherwise a very + * small number in isolation tester cases, so make that the outer loop of + * a naive search for a match. */ for (i = 0; i < num_blocking_pids; i++) for (j = 0; j < num_interesting_pids; j++) @@ -923,7 +927,7 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS) /* * Check if blocked_pid is waiting for a safe snapshot. We could in * theory check the resulting array of blocker PIDs against the - * interesting PIDs whitelist, but since there is no danger of autovacuum + * interesting PIDs list, but since there is no danger of autovacuum * blocking GetSafeSnapshot there seems to be no point in expending cycles * on allocating a buffer and searching for overlap; so it's presently * sufficient for the isolation tester's purposes to use a single element diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c index 8aeddc686326..844d8814e67f 100644 --- a/src/backend/utils/adt/mac.c +++ b/src/backend/utils/adt/mac.c @@ -3,7 +3,7 @@ * mac.c * PostgreSQL type definitions for 6 byte, EUI-48, MAC addresses. * - * Portions Copyright (c) 1998-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1998-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/mac.c diff --git a/src/backend/utils/adt/mac8.c b/src/backend/utils/adt/mac8.c index b7b2968b926c..41753fac6fd8 100644 --- a/src/backend/utils/adt/mac8.c +++ b/src/backend/utils/adt/mac8.c @@ -11,7 +11,7 @@ * The following code is written with the assumption that the OUI field * size is 24 bits. * - * Portions Copyright (c) 1998-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1998-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/mac8.c diff --git a/src/backend/utils/adt/mcxtfuncs.c b/src/backend/utils/adt/mcxtfuncs.c new file mode 100644 index 000000000000..0d52613bc32a --- /dev/null +++ b/src/backend/utils/adt/mcxtfuncs.c @@ -0,0 +1,217 @@ +/*------------------------------------------------------------------------- + * + * mcxtfuncs.c + * Functions to show backend memory context. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/adt/mcxtfuncs.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "funcapi.h" +#include "miscadmin.h" +#include "mb/pg_wchar.h" +#include "storage/proc.h" +#include "storage/procarray.h" +#include "utils/builtins.h" + +/* ---------- + * The max bytes for showing identifiers of MemoryContext. + * ---------- + */ +#define MEMORY_CONTEXT_IDENT_DISPLAY_SIZE 1024 + +/* + * PutMemoryContextsStatsTupleStore + * One recursion level for pg_get_backend_memory_contexts. + */ +static void +PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore, + TupleDesc tupdesc, MemoryContext context, + const char *parent, int level) +{ +#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 9 + + Datum values[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS]; + bool nulls[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS]; + MemoryContextCounters stat; + MemoryContext child; + const char *name; + const char *ident; + + AssertArg(MemoryContextIsValid(context)); + + name = context->name; + ident = context->ident; + + /* + * To be consistent with logging output, we label dynahash contexts with + * just the hash table name as with MemoryContextStatsPrint(). + */ + if (ident && strcmp(name, "dynahash") == 0) + { + name = ident; + ident = NULL; + } + + /* Examine the context itself */ + memset(&stat, 0, sizeof(stat)); + (*context->methods->stats) (context, NULL, (void *) &level, &stat, true); + + memset(values, 0, sizeof(values)); + memset(nulls, 0, sizeof(nulls)); + + if (name) + values[0] = CStringGetTextDatum(name); + else + nulls[0] = true; + + if (ident) + { + int idlen = strlen(ident); + char clipped_ident[MEMORY_CONTEXT_IDENT_DISPLAY_SIZE]; + + /* + * Some identifiers such as SQL query string can be very long, + * truncate oversize identifiers. + */ + if (idlen >= MEMORY_CONTEXT_IDENT_DISPLAY_SIZE) + idlen = pg_mbcliplen(ident, idlen, MEMORY_CONTEXT_IDENT_DISPLAY_SIZE - 1); + + memcpy(clipped_ident, ident, idlen); + clipped_ident[idlen] = '\0'; + values[1] = CStringGetTextDatum(clipped_ident); + } + else + nulls[1] = true; + + if (parent) + values[2] = CStringGetTextDatum(parent); + else + nulls[2] = true; + + values[3] = Int32GetDatum(level); + values[4] = Int64GetDatum(stat.totalspace); + values[5] = Int64GetDatum(stat.nblocks); + values[6] = Int64GetDatum(stat.freespace); + values[7] = Int64GetDatum(stat.freechunks); + values[8] = Int64GetDatum(stat.totalspace - stat.freespace); + tuplestore_putvalues(tupstore, tupdesc, values, nulls); + + for (child = context->firstchild; child != NULL; child = child->nextchild) + { + PutMemoryContextsStatsTupleStore(tupstore, tupdesc, + child, name, level + 1); + } +} + +/* + * pg_get_backend_memory_contexts + * SQL SRF showing backend memory context. + */ +Datum +pg_get_backend_memory_contexts(PG_FUNCTION_ARGS) +{ + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + TupleDesc tupdesc; + Tuplestorestate *tupstore; + MemoryContext per_query_ctx; + MemoryContext oldcontext; + + /* check to see if caller supports us returning a tuplestore */ + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("materialize mode required, but it is not allowed in this context"))); + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; + oldcontext = MemoryContextSwitchTo(per_query_ctx); + + tupstore = tuplestore_begin_heap(true, false, work_mem); + rsinfo->returnMode = SFRM_Materialize; + rsinfo->setResult = tupstore; + rsinfo->setDesc = tupdesc; + + MemoryContextSwitchTo(oldcontext); + + PutMemoryContextsStatsTupleStore(tupstore, tupdesc, + TopMemoryContext, NULL, 0); + + /* clean up and return the tuplestore */ + tuplestore_donestoring(tupstore); + + return (Datum) 0; +} + +/* + * pg_log_backend_memory_contexts + * Signal a backend process to log its memory contexts. + * + * Only superusers are allowed to signal to log the memory contexts + * because allowing any users to issue this request at an unbounded + * rate would cause lots of log messages and which can lead to + * denial of service. + * + * On receipt of this signal, a backend sets the flag in the signal + * handler, which causes the next CHECK_FOR_INTERRUPTS() to log the + * memory contexts. + */ +Datum +pg_log_backend_memory_contexts(PG_FUNCTION_ARGS) +{ + int pid = PG_GETARG_INT32(0); + PGPROC *proc; + + /* Only allow superusers to log memory contexts. */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be a superuser to log memory contexts"))); + + proc = BackendPidGetProc(pid); + + /* + * BackendPidGetProc returns NULL if the pid isn't valid; but by the time + * we reach kill(), a process for which we get a valid proc here might + * have terminated on its own. There's no way to acquire a lock on an + * arbitrary process to prevent that. But since this mechanism is usually + * used to debug a backend running and consuming lots of memory, that it + * might end on its own first and its memory contexts are not logged is + * not a problem. + */ + if (proc == NULL) + { + /* + * This is just a warning so a loop-through-resultset will not abort + * if one backend terminated on its own during the run. + */ + ereport(WARNING, + (errmsg("PID %d is not a PostgreSQL server process", pid))); + PG_RETURN_BOOL(false); + } + + if (SendProcSignal(pid, PROCSIG_LOG_MEMORY_CONTEXT, proc->backendId) < 0) + { + /* Again, just a warning to allow loops */ + ereport(WARNING, + (errmsg("could not send signal to process %d: %m", pid))); + PG_RETURN_BOOL(false); + } + + PG_RETURN_BOOL(true); +} diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index dd5335c1c38d..3c5a9038d676 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -3,7 +3,7 @@ * misc.c * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,6 +25,7 @@ #include "catalog/catalog.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" +#include "catalog/system_fk_info.h" #include "commands/dbcommands.h" #include "commands/tablespace.h" #include "common/keywords.h" @@ -35,8 +36,10 @@ #include "postmaster/syslogger.h" #include "rewrite/rewriteHandler.h" #include "storage/fd.h" +#include "storage/latch.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/ruleutils.h" #include "utils/timestamp.h" @@ -429,12 +432,16 @@ pg_get_keywords(PG_FUNCTION_ARGS) funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - tupdesc = CreateTemplateTupleDesc(3); + tupdesc = CreateTemplateTupleDesc(5); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode", CHAROID, -1, 0); - TupleDescInitEntry(tupdesc, (AttrNumber) 3, "catdesc", + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "barelabel", + BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "catdesc", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "baredesc", TEXTOID, -1, 0); funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc); @@ -446,7 +453,7 @@ pg_get_keywords(PG_FUNCTION_ARGS) if (funcctx->call_cntr < ScanKeywords.num_keywords) { - char *values[3]; + char *values[5]; HeapTuple tuple; /* cast-away-const is ugly but alternatives aren't much better */ @@ -458,26 +465,37 @@ pg_get_keywords(PG_FUNCTION_ARGS) { case UNRESERVED_KEYWORD: values[1] = "U"; - values[2] = _("unreserved"); + values[3] = _("unreserved"); break; case COL_NAME_KEYWORD: values[1] = "C"; - values[2] = _("unreserved (cannot be function or type name)"); + values[3] = _("unreserved (cannot be function or type name)"); break; case TYPE_FUNC_NAME_KEYWORD: values[1] = "T"; - values[2] = _("reserved (can be function or type name)"); + values[3] = _("reserved (can be function or type name)"); break; case RESERVED_KEYWORD: values[1] = "R"; - values[2] = _("reserved"); + values[3] = _("reserved"); break; default: /* shouldn't be possible */ values[1] = NULL; - values[2] = NULL; + values[3] = NULL; break; } + if (ScanKeywordBareLabel[funcctx->call_cntr]) + { + values[2] = "true"; + values[4] = _("can be bare label"); + } + else + { + values[2] = "false"; + values[4] = _("requires AS"); + } + tuple = BuildTupleFromCStrings(funcctx->attinmeta, values); SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); @@ -487,6 +505,84 @@ pg_get_keywords(PG_FUNCTION_ARGS) } +/* Function to return the list of catalog foreign key relationships */ +Datum +pg_get_catalog_foreign_keys(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + FmgrInfo *arrayinp; + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + TupleDesc tupdesc; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + tupdesc = CreateTemplateTupleDesc(6); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "fktable", + REGCLASSOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "fkcols", + TEXTARRAYOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "pktable", + REGCLASSOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "pkcols", + TEXTARRAYOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "is_array", + BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 6, "is_opt", + BOOLOID, -1, 0); + + funcctx->tuple_desc = BlessTupleDesc(tupdesc); + + /* + * We use array_in to convert the C strings in sys_fk_relationships[] + * to text arrays. But we cannot use DirectFunctionCallN to call + * array_in, and it wouldn't be very efficient if we could. Fill an + * FmgrInfo to use for the call. + */ + arrayinp = (FmgrInfo *) palloc(sizeof(FmgrInfo)); + fmgr_info(F_ARRAY_IN, arrayinp); + funcctx->user_fctx = arrayinp; + + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + arrayinp = (FmgrInfo *) funcctx->user_fctx; + + if (funcctx->call_cntr < lengthof(sys_fk_relationships)) + { + const SysFKRelationship *fkrel = &sys_fk_relationships[funcctx->call_cntr]; + Datum values[6]; + bool nulls[6]; + HeapTuple tuple; + + memset(nulls, false, sizeof(nulls)); + + values[0] = ObjectIdGetDatum(fkrel->fk_table); + values[1] = FunctionCall3(arrayinp, + CStringGetDatum(fkrel->fk_columns), + ObjectIdGetDatum(TEXTOID), + Int32GetDatum(-1)); + values[2] = ObjectIdGetDatum(fkrel->pk_table); + values[3] = FunctionCall3(arrayinp, + CStringGetDatum(fkrel->pk_columns), + ObjectIdGetDatum(TEXTOID), + Int32GetDatum(-1)); + values[4] = BoolGetDatum(fkrel->is_array); + values[5] = BoolGetDatum(fkrel->is_opt); + + tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); + + SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple)); + } + + SRF_RETURN_DONE(funcctx); +} + + /* * Return the type of the argument. */ diff --git a/src/backend/utils/adt/multirangetypes.c b/src/backend/utils/adt/multirangetypes.c new file mode 100644 index 000000000000..7aeec7617fc5 --- /dev/null +++ b/src/backend/utils/adt/multirangetypes.c @@ -0,0 +1,2791 @@ +/*------------------------------------------------------------------------- + * + * multirangetypes.c + * I/O functions, operators, and support functions for multirange types. + * + * The stored (serialized) format of a multirange value is: + * + * 12 bytes: MultirangeType struct including varlena header, multirange + * type's OID and the number of ranges in the multirange. + * 4 * (rangesCount - 1) bytes: 32-bit items pointing to the each range + * in the multirange starting from + * the second one. + * 1 * rangesCount bytes : 8-bit flags for each range in the multirange + * The rest of the multirange are range bound values pointed by multirange + * items. + * + * Majority of items contain lengths of corresponding range bound values. + * Thanks to that items are typically low numbers. This makes multiranges + * compression-friendly. Every MULTIRANGE_ITEM_OFFSET_STRIDE item contains + * an offset of the corresponding range bound values. That allows fast lookups + * for a particular range index. Offsets are counted starting from the end of + * flags aligned to the bound type. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/adt/multirangetypes.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/tupmacs.h" +#include "common/hashfn.h" +#include "lib/stringinfo.h" +#include "libpq/pqformat.h" +#include "miscadmin.h" +#include "utils/builtins.h" +#include "utils/lsyscache.h" +#include "utils/rangetypes.h" +#include "utils/multirangetypes.h" +#include "utils/array.h" +#include "utils/memutils.h" + +/* fn_extra cache entry for one of the range I/O functions */ +typedef struct MultirangeIOData +{ + TypeCacheEntry *typcache; /* multirange type's typcache entry */ + FmgrInfo typioproc; /* range type's I/O proc */ + Oid typioparam; /* range type's I/O parameter */ +} MultirangeIOData; + +typedef enum +{ + MULTIRANGE_BEFORE_RANGE, + MULTIRANGE_IN_RANGE, + MULTIRANGE_IN_RANGE_ESCAPED, + MULTIRANGE_IN_RANGE_QUOTED, + MULTIRANGE_IN_RANGE_QUOTED_ESCAPED, + MULTIRANGE_AFTER_RANGE, + MULTIRANGE_FINISHED, +} MultirangeParseState; + +/* + * Macros for accessing past MultirangeType parts of multirange: items, flags + * and boundaries. + */ +#define MultirangeGetItemsPtr(mr) ((uint32 *) ((Pointer) (mr) + \ + sizeof(MultirangeType))) +#define MultirangeGetFlagsPtr(mr) ((uint8 *) ((Pointer) (mr) + \ + sizeof(MultirangeType) + ((mr)->rangeCount - 1) * sizeof(uint32))) +#define MultirangeGetBoundariesPtr(mr, align) ((Pointer) (mr) + \ + att_align_nominal(sizeof(MultirangeType) + \ + ((mr)->rangeCount - 1) * sizeof(uint32) + \ + (mr)->rangeCount * sizeof(uint8), (align))) + +#define MULTIRANGE_ITEM_OFF_BIT 0x80000000 +#define MULTIRANGE_ITEM_GET_OFFLEN(item) ((item) & 0x7FFFFFFF) +#define MULTIRANGE_ITEM_HAS_OFF(item) ((item) & MULTIRANGE_ITEM_OFF_BIT) +#define MULTIRANGE_ITEM_OFFSET_STRIDE 4 + +typedef int (*multirange_bsearch_comparison) (TypeCacheEntry *typcache, + RangeBound *lower, + RangeBound *upper, + void *key, + bool *match); + +static MultirangeIOData *get_multirange_io_data(FunctionCallInfo fcinfo, + Oid mltrngtypid, + IOFuncSelector func); +static int32 multirange_canonicalize(TypeCacheEntry *rangetyp, + int32 input_range_count, + RangeType **ranges); + +/* + *---------------------------------------------------------- + * I/O FUNCTIONS + *---------------------------------------------------------- + */ + +/* + * Converts string to multirange. + * + * We expect curly brackets to bound the list, with zero or more ranges + * separated by commas. We accept whitespace anywhere: before/after our + * brackets and around the commas. Ranges can be the empty literal or some + * stuff inside parens/brackets. Mostly we delegate parsing the individual + * range contents to range_in, but we have to detect quoting and + * backslash-escaping which can happen for range bounds. Backslashes can + * escape something inside or outside a quoted string, and a quoted string + * can escape quote marks with either backslashes or double double-quotes. + */ +Datum +multirange_in(PG_FUNCTION_ARGS) +{ + char *input_str = PG_GETARG_CSTRING(0); + Oid mltrngtypoid = PG_GETARG_OID(1); + Oid typmod = PG_GETARG_INT32(2); + TypeCacheEntry *rangetyp; + int32 ranges_seen = 0; + int32 range_count = 0; + int32 range_capacity = 8; + RangeType *range; + RangeType **ranges = palloc(range_capacity * sizeof(RangeType *)); + MultirangeIOData *cache; + MultirangeType *ret; + MultirangeParseState parse_state; + const char *ptr = input_str; + const char *range_str_begin = NULL; + int32 range_str_len; + char *range_str; + + cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_input); + rangetyp = cache->typcache->rngtype; + + /* consume whitespace */ + while (*ptr != '\0' && isspace((unsigned char) *ptr)) + ptr++; + + if (*ptr == '{') + ptr++; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("malformed multirange literal: \"%s\"", + input_str), + errdetail("Missing left brace."))); + + /* consume ranges */ + parse_state = MULTIRANGE_BEFORE_RANGE; + for (; parse_state != MULTIRANGE_FINISHED; ptr++) + { + char ch = *ptr; + + if (ch == '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("malformed multirange literal: \"%s\"", + input_str), + errdetail("Unexpected end of input."))); + + /* skip whitespace */ + if (isspace((unsigned char) ch)) + continue; + + switch (parse_state) + { + case MULTIRANGE_BEFORE_RANGE: + if (ch == '[' || ch == '(') + { + range_str_begin = ptr; + parse_state = MULTIRANGE_IN_RANGE; + } + else if (ch == '}' && ranges_seen == 0) + parse_state = MULTIRANGE_FINISHED; + else if (pg_strncasecmp(ptr, RANGE_EMPTY_LITERAL, + strlen(RANGE_EMPTY_LITERAL)) == 0) + { + ranges_seen++; + /* nothing to do with an empty range */ + ptr += strlen(RANGE_EMPTY_LITERAL) - 1; + parse_state = MULTIRANGE_AFTER_RANGE; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("malformed multirange literal: \"%s\"", + input_str), + errdetail("Expected range start."))); + break; + case MULTIRANGE_IN_RANGE: + if (ch == ']' || ch == ')') + { + range_str_len = ptr - range_str_begin + 1; + range_str = pnstrdup(range_str_begin, range_str_len); + if (range_capacity == range_count) + { + range_capacity *= 2; + ranges = (RangeType **) + repalloc(ranges, range_capacity * sizeof(RangeType *)); + } + ranges_seen++; + range = DatumGetRangeTypeP(InputFunctionCall(&cache->typioproc, + range_str, + cache->typioparam, + typmod)); + if (!RangeIsEmpty(range)) + ranges[range_count++] = range; + parse_state = MULTIRANGE_AFTER_RANGE; + } + else + { + if (ch == '"') + parse_state = MULTIRANGE_IN_RANGE_QUOTED; + else if (ch == '\\') + parse_state = MULTIRANGE_IN_RANGE_ESCAPED; + + /* + * We will include this character into range_str once we + * find the end of the range value. + */ + } + break; + case MULTIRANGE_IN_RANGE_ESCAPED: + + /* + * We will include this character into range_str once we find + * the end of the range value. + */ + parse_state = MULTIRANGE_IN_RANGE; + break; + case MULTIRANGE_IN_RANGE_QUOTED: + if (ch == '"') + if (*(ptr + 1) == '"') + { + /* two quote marks means an escaped quote mark */ + ptr++; + } + else + parse_state = MULTIRANGE_IN_RANGE; + else if (ch == '\\') + parse_state = MULTIRANGE_IN_RANGE_QUOTED_ESCAPED; + + /* + * We will include this character into range_str once we find + * the end of the range value. + */ + break; + case MULTIRANGE_AFTER_RANGE: + if (ch == ',') + parse_state = MULTIRANGE_BEFORE_RANGE; + else if (ch == '}') + parse_state = MULTIRANGE_FINISHED; + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("malformed multirange literal: \"%s\"", + input_str), + errdetail("Expected comma or end of multirange."))); + break; + case MULTIRANGE_IN_RANGE_QUOTED_ESCAPED: + + /* + * We will include this character into range_str once we find + * the end of the range value. + */ + parse_state = MULTIRANGE_IN_RANGE_QUOTED; + break; + default: + elog(ERROR, "unknown parse state: %d", parse_state); + } + } + + /* consume whitespace */ + while (*ptr != '\0' && isspace((unsigned char) *ptr)) + ptr++; + + if (*ptr != '\0') + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("malformed multirange literal: \"%s\"", + input_str), + errdetail("Junk after closing right brace."))); + + ret = make_multirange(mltrngtypoid, rangetyp, range_count, ranges); + PG_RETURN_MULTIRANGE_P(ret); +} + +Datum +multirange_out(PG_FUNCTION_ARGS) +{ + MultirangeType *multirange = PG_GETARG_MULTIRANGE_P(0); + Oid mltrngtypoid = MultirangeTypeGetOid(multirange); + MultirangeIOData *cache; + StringInfoData buf; + RangeType *range; + char *rangeStr; + int32 range_count; + int32 i; + RangeType **ranges; + + cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_output); + + initStringInfo(&buf); + + appendStringInfoChar(&buf, '{'); + + multirange_deserialize(cache->typcache->rngtype, multirange, &range_count, &ranges); + for (i = 0; i < range_count; i++) + { + if (i > 0) + appendStringInfoChar(&buf, ','); + range = ranges[i]; + rangeStr = OutputFunctionCall(&cache->typioproc, RangeTypePGetDatum(range)); + appendStringInfoString(&buf, rangeStr); + } + + appendStringInfoChar(&buf, '}'); + + PG_RETURN_CSTRING(buf.data); +} + +/* + * Binary representation: First a int32-sized count of ranges, followed by + * ranges in their native binary representation. + */ +Datum +multirange_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + Oid mltrngtypoid = PG_GETARG_OID(1); + int32 typmod = PG_GETARG_INT32(2); + MultirangeIOData *cache; + uint32 range_count; + RangeType **ranges; + MultirangeType *ret; + StringInfoData tmpbuf; + + cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_receive); + + range_count = pq_getmsgint(buf, 4); + ranges = palloc(range_count * sizeof(RangeType *)); + + initStringInfo(&tmpbuf); + for (int i = 0; i < range_count; i++) + { + uint32 range_len = pq_getmsgint(buf, 4); + const char *range_data = pq_getmsgbytes(buf, range_len); + + resetStringInfo(&tmpbuf); + appendBinaryStringInfo(&tmpbuf, range_data, range_len); + + ranges[i] = DatumGetRangeTypeP(ReceiveFunctionCall(&cache->typioproc, + &tmpbuf, + cache->typioparam, + typmod)); + } + pfree(tmpbuf.data); + + pq_getmsgend(buf); + + ret = make_multirange(mltrngtypoid, cache->typcache->rngtype, + range_count, ranges); + PG_RETURN_MULTIRANGE_P(ret); +} + +Datum +multirange_send(PG_FUNCTION_ARGS) +{ + MultirangeType *multirange = PG_GETARG_MULTIRANGE_P(0); + Oid mltrngtypoid = MultirangeTypeGetOid(multirange); + StringInfo buf = makeStringInfo(); + RangeType **ranges; + int32 range_count; + MultirangeIOData *cache; + + cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_send); + + /* construct output */ + pq_begintypsend(buf); + + pq_sendint32(buf, multirange->rangeCount); + + multirange_deserialize(cache->typcache->rngtype, multirange, &range_count, &ranges); + for (int i = 0; i < range_count; i++) + { + Datum range; + + range = RangeTypePGetDatum(ranges[i]); + range = PointerGetDatum(SendFunctionCall(&cache->typioproc, range)); + + pq_sendint32(buf, VARSIZE(range) - VARHDRSZ); + pq_sendbytes(buf, VARDATA(range), VARSIZE(range) - VARHDRSZ); + } + + PG_RETURN_BYTEA_P(pq_endtypsend(buf)); +} + +/* + * get_multirange_io_data: get cached information needed for multirange type I/O + * + * The multirange I/O functions need a bit more cached info than other multirange + * functions, so they store a MultirangeIOData struct in fn_extra, not just a + * pointer to a type cache entry. + */ +static MultirangeIOData * +get_multirange_io_data(FunctionCallInfo fcinfo, Oid mltrngtypid, IOFuncSelector func) +{ + MultirangeIOData *cache = (MultirangeIOData *) fcinfo->flinfo->fn_extra; + + if (cache == NULL || cache->typcache->type_id != mltrngtypid) + { + Oid typiofunc; + int16 typlen; + bool typbyval; + char typalign; + char typdelim; + + cache = (MultirangeIOData *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + sizeof(MultirangeIOData)); + cache->typcache = lookup_type_cache(mltrngtypid, TYPECACHE_MULTIRANGE_INFO); + if (cache->typcache->rngtype == NULL) + elog(ERROR, "type %u is not a multirange type", mltrngtypid); + + /* get_type_io_data does more than we need, but is convenient */ + get_type_io_data(cache->typcache->rngtype->type_id, + func, + &typlen, + &typbyval, + &typalign, + &typdelim, + &cache->typioparam, + &typiofunc); + + if (!OidIsValid(typiofunc)) + { + /* this could only happen for receive or send */ + if (func == IOFunc_receive) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("no binary input function available for type %s", + format_type_be(cache->typcache->rngtype->type_id)))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("no binary output function available for type %s", + format_type_be(cache->typcache->rngtype->type_id)))); + } + fmgr_info_cxt(typiofunc, &cache->typioproc, + fcinfo->flinfo->fn_mcxt); + + fcinfo->flinfo->fn_extra = (void *) cache; + } + + return cache; +} + +/* + * Converts a list of arbitrary ranges into a list that is sorted and merged. + * Changes the contents of `ranges`. + * + * Returns the number of slots actually used, which may be less than + * input_range_count but never more. + * + * We assume that no input ranges are null, but empties are okay. + */ +static int32 +multirange_canonicalize(TypeCacheEntry *rangetyp, int32 input_range_count, + RangeType **ranges) +{ + RangeType *lastRange = NULL; + RangeType *currentRange; + int32 i; + int32 output_range_count = 0; + + /* Sort the ranges so we can find the ones that overlap/meet. */ + qsort_arg(ranges, input_range_count, sizeof(RangeType *), range_compare, + rangetyp); + + /* Now merge where possible: */ + for (i = 0; i < input_range_count; i++) + { + currentRange = ranges[i]; + if (RangeIsEmpty(currentRange)) + continue; + + if (lastRange == NULL) + { + ranges[output_range_count++] = lastRange = currentRange; + continue; + } + + /* + * range_adjacent_internal gives true if *either* A meets B or B meets + * A, which is not quite want we want, but we rely on the sorting + * above to rule out B meets A ever happening. + */ + if (range_adjacent_internal(rangetyp, lastRange, currentRange)) + { + /* The two ranges touch (without overlap), so merge them: */ + ranges[output_range_count - 1] = lastRange = + range_union_internal(rangetyp, lastRange, currentRange, false); + } + else if (range_before_internal(rangetyp, lastRange, currentRange)) + { + /* There's a gap, so make a new entry: */ + lastRange = ranges[output_range_count] = currentRange; + output_range_count++; + } + else + { + /* They must overlap, so merge them: */ + ranges[output_range_count - 1] = lastRange = + range_union_internal(rangetyp, lastRange, currentRange, true); + } + } + + return output_range_count; +} + +/* + *---------------------------------------------------------- + * SUPPORT FUNCTIONS + * + * These functions aren't in pg_proc, but are useful for + * defining new generic multirange functions in C. + *---------------------------------------------------------- + */ + +/* + * multirange_get_typcache: get cached information about a multirange type + * + * This is for use by multirange-related functions that follow the convention + * of using the fn_extra field as a pointer to the type cache entry for + * the multirange type. Functions that need to cache more information than + * that must fend for themselves. + */ +TypeCacheEntry * +multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid) +{ + TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra; + + if (typcache == NULL || + typcache->type_id != mltrngtypid) + { + typcache = lookup_type_cache(mltrngtypid, TYPECACHE_MULTIRANGE_INFO); + if (typcache->rngtype == NULL) + elog(ERROR, "type %u is not a multirange type", mltrngtypid); + fcinfo->flinfo->fn_extra = (void *) typcache; + } + + return typcache; +} + + +/* + * Estimate size occupied by serialized multirange. + */ +static Size +multirange_size_estimate(TypeCacheEntry *rangetyp, int32 range_count, + RangeType **ranges) +{ + char elemalign = rangetyp->rngelemtype->typalign; + Size size; + int32 i; + + /* + * Count space for MultirangeType struct, items and flags. + */ + size = att_align_nominal(sizeof(MultirangeType) + + Max(range_count - 1, 0) * sizeof(uint32) + + range_count * sizeof(uint8), elemalign); + + /* Count space for range bounds */ + for (i = 0; i < range_count; i++) + size += att_align_nominal(VARSIZE(ranges[i]) - + sizeof(RangeType) - + sizeof(char), elemalign); + + return size; +} + +/* + * Write multirange data into pre-allocated space. + */ +static void +write_multirange_data(MultirangeType *multirange, TypeCacheEntry *rangetyp, + int32 range_count, RangeType **ranges) +{ + uint32 *items; + uint32 prev_offset = 0; + uint8 *flags; + int32 i; + Pointer begin, + ptr; + char elemalign = rangetyp->rngelemtype->typalign; + + items = MultirangeGetItemsPtr(multirange); + flags = MultirangeGetFlagsPtr(multirange); + ptr = begin = MultirangeGetBoundariesPtr(multirange, elemalign); + for (i = 0; i < range_count; i++) + { + uint32 len; + + if (i > 0) + { + /* + * Every range, except the first one, has an item. Every + * MULTIRANGE_ITEM_OFFSET_STRIDE item contains an offset, others + * contain lengths. + */ + items[i - 1] = ptr - begin; + if ((i % MULTIRANGE_ITEM_OFFSET_STRIDE) != 0) + items[i - 1] -= prev_offset; + else + items[i - 1] |= MULTIRANGE_ITEM_OFF_BIT; + prev_offset = ptr - begin; + } + flags[i] = *((Pointer) ranges[i] + VARSIZE(ranges[i]) - sizeof(char)); + len = VARSIZE(ranges[i]) - sizeof(RangeType) - sizeof(char); + memcpy(ptr, (Pointer) (ranges[i] + 1), len); + ptr += att_align_nominal(len, elemalign); + } +} + + +/* + * This serializes the multirange from a list of non-null ranges. It also + * sorts the ranges and merges any that touch. The ranges should already be + * detoasted, and there should be no NULLs. This should be used by most + * callers. + * + * Note that we may change the `ranges` parameter (the pointers, but not + * any already-existing RangeType contents). + */ +MultirangeType * +make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, + RangeType **ranges) +{ + MultirangeType *multirange; + Size size; + + /* Sort and merge input ranges. */ + range_count = multirange_canonicalize(rangetyp, range_count, ranges); + + /* Note: zero-fill is required here, just as in heap tuples */ + size = multirange_size_estimate(rangetyp, range_count, ranges); + multirange = palloc0(size); + SET_VARSIZE(multirange, size); + + /* Now fill in the datum */ + multirange->multirangetypid = mltrngtypoid; + multirange->rangeCount = range_count; + + write_multirange_data(multirange, rangetyp, range_count, ranges); + + return multirange; +} + +/* + * Get offset of bounds values of the i'th range in the multirange. + */ +static uint32 +multirange_get_bounds_offset(const MultirangeType *multirange, int32 i) +{ + uint32 *items = MultirangeGetItemsPtr(multirange); + uint32 offset = 0; + + /* + * Summarize lengths till we meet an offset. + */ + while (i > 0) + { + offset += MULTIRANGE_ITEM_GET_OFFLEN(items[i - 1]); + if (MULTIRANGE_ITEM_HAS_OFF(items[i - 1])) + break; + i--; + } + return offset; +} + +/* + * Fetch the i'th range from the multirange. + */ +RangeType * +multirange_get_range(TypeCacheEntry *rangetyp, + const MultirangeType *multirange, int i) +{ + uint32 offset; + uint8 flags; + Pointer begin, + ptr; + int16 typlen = rangetyp->rngelemtype->typlen; + char typalign = rangetyp->rngelemtype->typalign; + uint32 len; + RangeType *range; + + Assert(i < multirange->rangeCount); + + offset = multirange_get_bounds_offset(multirange, i); + flags = MultirangeGetFlagsPtr(multirange)[i]; + ptr = begin = MultirangeGetBoundariesPtr(multirange, typalign) + offset; + + /* + * Calculate the size of bound values. In principle, we could get offset + * of the next range bound values and calculate accordingly. But range + * bound values are aligned, so we have to walk the values to get the + * exact size. + */ + if (RANGE_HAS_LBOUND(flags)) + ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr); + if (RANGE_HAS_UBOUND(flags)) + ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr); + len = (ptr - begin) + sizeof(RangeType) + sizeof(uint8); + + range = palloc0(len); + SET_VARSIZE(range, len); + range->rangetypid = rangetyp->type_id; + + memcpy(range + 1, begin, ptr - begin); + *((uint8 *) (range + 1) + (ptr - begin)) = flags; + + return range; +} + +/* + * Fetch bounds from the i'th range of the multirange. This is the shortcut for + * doing the same thing as multirange_get_range() + range_deserialize(), but + * performing fewer operations. + */ +void +multirange_get_bounds(TypeCacheEntry *rangetyp, + const MultirangeType *multirange, + uint32 i, RangeBound *lower, RangeBound *upper) +{ + uint32 offset; + uint8 flags; + Pointer ptr; + int16 typlen = rangetyp->rngelemtype->typlen; + char typalign = rangetyp->rngelemtype->typalign; + bool typbyval = rangetyp->rngelemtype->typbyval; + Datum lbound; + Datum ubound; + + Assert(i < multirange->rangeCount); + + offset = multirange_get_bounds_offset(multirange, i); + flags = MultirangeGetFlagsPtr(multirange)[i]; + ptr = MultirangeGetBoundariesPtr(multirange, typalign) + offset; + + /* multirange can't contain empty ranges */ + Assert((flags & RANGE_EMPTY) == 0); + + /* fetch lower bound, if any */ + if (RANGE_HAS_LBOUND(flags)) + { + /* att_align_pointer cannot be necessary here */ + lbound = fetch_att(ptr, typbyval, typlen); + ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr); + } + else + lbound = (Datum) 0; + + /* fetch upper bound, if any */ + if (RANGE_HAS_UBOUND(flags)) + { + ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr); + ubound = fetch_att(ptr, typbyval, typlen); + /* no need for att_addlength_pointer */ + } + else + ubound = (Datum) 0; + + /* emit results */ + lower->val = lbound; + lower->infinite = (flags & RANGE_LB_INF) != 0; + lower->inclusive = (flags & RANGE_LB_INC) != 0; + lower->lower = true; + + upper->val = ubound; + upper->infinite = (flags & RANGE_UB_INF) != 0; + upper->inclusive = (flags & RANGE_UB_INC) != 0; + upper->lower = false; +} + +/* + * Construct union range from the multirange. + */ +RangeType * +multirange_get_union_range(TypeCacheEntry *rangetyp, + const MultirangeType *mr) +{ + RangeBound lower, + upper, + tmp; + + if (MultirangeIsEmpty(mr)) + return make_empty_range(rangetyp); + + multirange_get_bounds(rangetyp, mr, 0, &lower, &tmp); + multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper); + + return make_range(rangetyp, &lower, &upper, false); +} + + +/* + * multirange_deserialize: deconstruct a multirange value + * + * NB: the given multirange object must be fully detoasted; it cannot have a + * short varlena header. + */ +void +multirange_deserialize(TypeCacheEntry *rangetyp, + const MultirangeType *multirange, int32 *range_count, + RangeType ***ranges) +{ + *range_count = multirange->rangeCount; + + /* Convert each ShortRangeType into a RangeType */ + if (*range_count > 0) + { + int i; + + *ranges = palloc(*range_count * sizeof(RangeType *)); + for (i = 0; i < *range_count; i++) + (*ranges)[i] = multirange_get_range(rangetyp, multirange, i); + } + else + { + *ranges = NULL; + } +} + +MultirangeType * +make_empty_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp) +{ + return make_multirange(mltrngtypoid, rangetyp, 0, NULL); +} + +/* + * Similar to range_overlaps_internal(), but takes range bounds instead of + * ranges as arguments. + */ +static bool +range_bounds_overlaps(TypeCacheEntry *typcache, + RangeBound *lower1, RangeBound *upper1, + RangeBound *lower2, RangeBound *upper2) +{ + if (range_cmp_bounds(typcache, lower1, lower2) >= 0 && + range_cmp_bounds(typcache, lower1, upper2) <= 0) + return true; + + if (range_cmp_bounds(typcache, lower2, lower1) >= 0 && + range_cmp_bounds(typcache, lower2, upper1) <= 0) + return true; + + return false; +} + +/* + * Similar to range_contains_internal(), but takes range bounds instead of + * ranges as arguments. + */ +static bool +range_bounds_contains(TypeCacheEntry *typcache, + RangeBound *lower1, RangeBound *upper1, + RangeBound *lower2, RangeBound *upper2) +{ + if (range_cmp_bounds(typcache, lower1, lower2) <= 0 && + range_cmp_bounds(typcache, upper1, upper2) >= 0) + return true; + + return false; +} + +/* + * Check if the given key matches any range in multirange using binary search. + * If the required range isn't found, that counts as a mismatch. When the + * required range is found, the comparison function can still report this as + * either match or mismatch. For instance, if we search for containment, we can + * found a range, which is overlapping but not containing the key range, and + * that would count as a mismatch. + */ +static bool +multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, + void *key, multirange_bsearch_comparison cmp_func) +{ + uint32 l, + u, + idx; + int comparison; + bool match = false; + + l = 0; + u = mr->rangeCount; + while (l < u) + { + RangeBound lower, + upper; + + idx = (l + u) / 2; + multirange_get_bounds(typcache, mr, idx, &lower, &upper); + comparison = (*cmp_func) (typcache, &lower, &upper, key, &match); + + if (comparison < 0) + u = idx; + else if (comparison > 0) + l = idx + 1; + else + return match; + } + + return false; +} + +/* + *---------------------------------------------------------- + * GENERIC FUNCTIONS + *---------------------------------------------------------- + */ + +/* + * Construct multirange value from zero or more ranges. Since this is a + * variadic function we get passed an array. The array must contain ranges + * that match our return value, and there must be no NULLs. + */ +Datum +multirange_constructor2(PG_FUNCTION_ARGS) +{ + Oid mltrngtypid = get_fn_expr_rettype(fcinfo->flinfo); + Oid rngtypid; + TypeCacheEntry *typcache; + TypeCacheEntry *rangetyp; + ArrayType *rangeArray; + int range_count; + Datum *elements; + bool *nulls; + RangeType **ranges; + int dims; + int i; + + typcache = multirange_get_typcache(fcinfo, mltrngtypid); + rangetyp = typcache->rngtype; + + /* + * A no-arg invocation should call multirange_constructor0 instead, but + * returning an empty range is what that does. + */ + + if (PG_NARGS() == 0) + PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, 0, NULL)); + + /* + * This check should be guaranteed by our signature, but let's do it just + * in case. + */ + + if (PG_ARGISNULL(0)) + elog(ERROR, + "multirange values cannot contain NULL members"); + + rangeArray = PG_GETARG_ARRAYTYPE_P(0); + + dims = ARR_NDIM(rangeArray); + if (dims > 1) + ereport(ERROR, + (errcode(ERRCODE_CARDINALITY_VIOLATION), + errmsg("multiranges cannot be constructed from multidimensional arrays"))); + + rngtypid = ARR_ELEMTYPE(rangeArray); + if (rngtypid != rangetyp->type_id) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type %u does not match constructor type", rngtypid))); + + /* + * Be careful: we can still be called with zero ranges, like this: + * `int4multirange(variadic '{}'::int4range[]) + */ + if (dims == 0) + { + range_count = 0; + ranges = NULL; + } + else + { + deconstruct_array(rangeArray, rngtypid, rangetyp->typlen, rangetyp->typbyval, + rangetyp->typalign, &elements, &nulls, &range_count); + + ranges = palloc0(range_count * sizeof(RangeType *)); + for (i = 0; i < range_count; i++) + { + if (nulls[i]) + ereport(ERROR, + (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), + errmsg("multirange values cannot contain NULL members"))); + + /* make_multirange will do its own copy */ + ranges[i] = DatumGetRangeTypeP(elements[i]); + } + } + + PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, range_count, ranges)); +} + +/* + * Construct multirange value from a single range. It'd be nice if we could + * just use multirange_constructor2 for this case, but we need a non-variadic + * single-arg function to let us define a CAST from a range to its multirange. + */ +Datum +multirange_constructor1(PG_FUNCTION_ARGS) +{ + Oid mltrngtypid = get_fn_expr_rettype(fcinfo->flinfo); + Oid rngtypid; + TypeCacheEntry *typcache; + TypeCacheEntry *rangetyp; + RangeType *range; + + typcache = multirange_get_typcache(fcinfo, mltrngtypid); + rangetyp = typcache->rngtype; + + /* + * This check should be guaranteed by our signature, but let's do it just + * in case. + */ + + if (PG_ARGISNULL(0)) + elog(ERROR, + "multirange values cannot contain NULL members"); + + range = PG_GETARG_RANGE_P(0); + + /* Make sure the range type matches. */ + rngtypid = RangeTypeGetOid(range); + if (rngtypid != rangetyp->type_id) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("type %u does not match constructor type", rngtypid))); + + PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, 1, &range)); +} + +/* + * Constructor just like multirange_constructor1, but opr_sanity gets angry + * if the same internal function handles multiple functions with different arg + * counts. + */ +Datum +multirange_constructor0(PG_FUNCTION_ARGS) +{ + Oid mltrngtypid; + TypeCacheEntry *typcache; + TypeCacheEntry *rangetyp; + + /* This should always be called without arguments */ + if (PG_NARGS() != 0) + elog(ERROR, + "niladic multirange constructor must not receive arguments"); + + mltrngtypid = get_fn_expr_rettype(fcinfo->flinfo); + typcache = multirange_get_typcache(fcinfo, mltrngtypid); + rangetyp = typcache->rngtype; + + PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, 0, NULL)); +} + + +/* multirange, multirange -> multirange type functions */ + +/* multirange union */ +Datum +multirange_union(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + int32 range_count1; + int32 range_count2; + int32 range_count3; + RangeType **ranges1; + RangeType **ranges2; + RangeType **ranges3; + + if (MultirangeIsEmpty(mr1)) + PG_RETURN_MULTIRANGE_P(mr2); + if (MultirangeIsEmpty(mr2)) + PG_RETURN_MULTIRANGE_P(mr1); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + multirange_deserialize(typcache->rngtype, mr1, &range_count1, &ranges1); + multirange_deserialize(typcache->rngtype, mr2, &range_count2, &ranges2); + + range_count3 = range_count1 + range_count2; + ranges3 = palloc0(range_count3 * sizeof(RangeType *)); + memcpy(ranges3, ranges1, range_count1 * sizeof(RangeType *)); + memcpy(ranges3 + range_count1, ranges2, range_count2 * sizeof(RangeType *)); + PG_RETURN_MULTIRANGE_P(make_multirange(typcache->type_id, typcache->rngtype, + range_count3, ranges3)); +} + +/* multirange minus */ +Datum +multirange_minus(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + Oid mltrngtypoid = MultirangeTypeGetOid(mr1); + TypeCacheEntry *typcache; + TypeCacheEntry *rangetyp; + int32 range_count1; + int32 range_count2; + RangeType **ranges1; + RangeType **ranges2; + + typcache = multirange_get_typcache(fcinfo, mltrngtypoid); + rangetyp = typcache->rngtype; + + if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2)) + PG_RETURN_MULTIRANGE_P(mr1); + + multirange_deserialize(typcache->rngtype, mr1, &range_count1, &ranges1); + multirange_deserialize(typcache->rngtype, mr2, &range_count2, &ranges2); + + PG_RETURN_MULTIRANGE_P(multirange_minus_internal(mltrngtypoid, + rangetyp, + range_count1, + ranges1, + range_count2, + ranges2)); +} + +MultirangeType * +multirange_minus_internal(Oid mltrngtypoid, TypeCacheEntry *rangetyp, + int32 range_count1, RangeType **ranges1, + int32 range_count2, RangeType **ranges2) +{ + RangeType *r1; + RangeType *r2; + RangeType **ranges3; + int32 range_count3; + int32 i1; + int32 i2; + + /* + * Worst case: every range in ranges1 makes a different cut to some range + * in ranges2. + */ + ranges3 = palloc0((range_count1 + range_count2) * sizeof(RangeType *)); + range_count3 = 0; + + /* + * For each range in mr1, keep subtracting until it's gone or the ranges + * in mr2 have passed it. After a subtraction we assign what's left back + * to r1. The parallel progress through mr1 and mr2 is similar to + * multirange_overlaps_multirange_internal. + */ + r2 = ranges2[0]; + for (i1 = 0, i2 = 0; i1 < range_count1; i1++) + { + r1 = ranges1[i1]; + + /* Discard r2s while r2 << r1 */ + while (r2 != NULL && range_before_internal(rangetyp, r2, r1)) + { + r2 = ++i2 >= range_count2 ? NULL : ranges2[i2]; + } + + while (r2 != NULL) + { + if (range_split_internal(rangetyp, r1, r2, &ranges3[range_count3], &r1)) + { + /* + * If r2 takes a bite out of the middle of r1, we need two + * outputs + */ + range_count3++; + r2 = ++i2 >= range_count2 ? NULL : ranges2[i2]; + + } + else if (range_overlaps_internal(rangetyp, r1, r2)) + { + /* + * If r2 overlaps r1, replace r1 with r1 - r2. + */ + r1 = range_minus_internal(rangetyp, r1, r2); + + /* + * If r2 goes past r1, then we need to stay with it, in case + * it hits future r1s. Otherwise we need to keep r1, in case + * future r2s hit it. Since we already subtracted, there's no + * point in using the overright/overleft calls. + */ + if (RangeIsEmpty(r1) || range_before_internal(rangetyp, r1, r2)) + break; + else + r2 = ++i2 >= range_count2 ? NULL : ranges2[i2]; + + } + else + { + /* + * This and all future r2s are past r1, so keep them. Also + * assign whatever is left of r1 to the result. + */ + break; + } + } + + /* + * Nothing else can remove anything from r1, so keep it. Even if r1 is + * empty here, make_multirange will remove it. + */ + ranges3[range_count3++] = r1; + } + + return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3); +} + +/* multirange intersection */ +Datum +multirange_intersect(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + Oid mltrngtypoid = MultirangeTypeGetOid(mr1); + TypeCacheEntry *typcache; + TypeCacheEntry *rangetyp; + int32 range_count1; + int32 range_count2; + RangeType **ranges1; + RangeType **ranges2; + + typcache = multirange_get_typcache(fcinfo, mltrngtypoid); + rangetyp = typcache->rngtype; + + if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2)) + PG_RETURN_MULTIRANGE_P(make_empty_multirange(mltrngtypoid, rangetyp)); + + multirange_deserialize(rangetyp, mr1, &range_count1, &ranges1); + multirange_deserialize(rangetyp, mr2, &range_count2, &ranges2); + + PG_RETURN_MULTIRANGE_P(multirange_intersect_internal(mltrngtypoid, + rangetyp, + range_count1, + ranges1, + range_count2, + ranges2)); +} + +MultirangeType * +multirange_intersect_internal(Oid mltrngtypoid, TypeCacheEntry *rangetyp, + int32 range_count1, RangeType **ranges1, + int32 range_count2, RangeType **ranges2) +{ + RangeType *r1; + RangeType *r2; + RangeType **ranges3; + int32 range_count3; + int32 i1; + int32 i2; + + if (range_count1 == 0 || range_count2 == 0) + return make_multirange(mltrngtypoid, rangetyp, 0, NULL); + + /*----------------------------------------------- + * Worst case is a stitching pattern like this: + * + * mr1: --- --- --- --- + * mr2: --- --- --- + * mr3: - - - - - - + * + * That seems to be range_count1 + range_count2 - 1, + * but one extra won't hurt. + *----------------------------------------------- + */ + ranges3 = palloc0((range_count1 + range_count2) * sizeof(RangeType *)); + range_count3 = 0; + + /* + * For each range in mr1, keep intersecting until the ranges in mr2 have + * passed it. The parallel progress through mr1 and mr2 is similar to + * multirange_minus_multirange_internal, but we don't have to assign back + * to r1. + */ + r2 = ranges2[0]; + for (i1 = 0, i2 = 0; i1 < range_count1; i1++) + { + r1 = ranges1[i1]; + + /* Discard r2s while r2 << r1 */ + while (r2 != NULL && range_before_internal(rangetyp, r2, r1)) + { + r2 = ++i2 >= range_count2 ? NULL : ranges2[i2]; + } + + while (r2 != NULL) + { + if (range_overlaps_internal(rangetyp, r1, r2)) + { + /* Keep the overlapping part */ + ranges3[range_count3++] = range_intersect_internal(rangetyp, r1, r2); + + /* If we "used up" all of r2, go to the next one... */ + if (range_overleft_internal(rangetyp, r2, r1)) + r2 = ++i2 >= range_count2 ? NULL : ranges2[i2]; + + /* ...otherwise go to the next r1 */ + else + break; + } + else + /* We're past r1, so move to the next one */ + break; + } + + /* If we're out of r2s, there can be no more intersections */ + if (r2 == NULL) + break; + } + + return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3); +} + +/* + * range_agg_transfn: combine adjacent/overlapping ranges. + * + * All we do here is gather the input ranges into an array + * so that the finalfn can sort and combine them. + */ +Datum +range_agg_transfn(PG_FUNCTION_ARGS) +{ + MemoryContext aggContext; + Oid rngtypoid; + ArrayBuildState *state; + + if (!AggCheckCallContext(fcinfo, &aggContext)) + elog(ERROR, "range_agg_transfn called in non-aggregate context"); + + rngtypoid = get_fn_expr_argtype(fcinfo->flinfo, 1); + if (!type_is_range(rngtypoid)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("range_agg must be called with a range"))); + + if (PG_ARGISNULL(0)) + state = initArrayResult(rngtypoid, aggContext, false); + else + state = (ArrayBuildState *) PG_GETARG_POINTER(0); + + /* skip NULLs */ + if (!PG_ARGISNULL(1)) + accumArrayResult(state, PG_GETARG_DATUM(1), false, rngtypoid, aggContext); + + PG_RETURN_POINTER(state); +} + +/* + * range_agg_finalfn: use our internal array to merge touching ranges. + */ +Datum +range_agg_finalfn(PG_FUNCTION_ARGS) +{ + MemoryContext aggContext; + Oid mltrngtypoid; + TypeCacheEntry *typcache; + ArrayBuildState *state; + int32 range_count; + RangeType **ranges; + int i; + + if (!AggCheckCallContext(fcinfo, &aggContext)) + elog(ERROR, "range_agg_finalfn called in non-aggregate context"); + + state = PG_ARGISNULL(0) ? NULL : (ArrayBuildState *) PG_GETARG_POINTER(0); + if (state == NULL) + /* This shouldn't be possible, but just in case.... */ + PG_RETURN_NULL(); + + /* Also return NULL if we had zero inputs, like other aggregates */ + range_count = state->nelems; + if (range_count == 0) + PG_RETURN_NULL(); + + mltrngtypoid = get_fn_expr_rettype(fcinfo->flinfo); + typcache = multirange_get_typcache(fcinfo, mltrngtypoid); + + ranges = palloc0(range_count * sizeof(RangeType *)); + for (i = 0; i < range_count; i++) + ranges[i] = DatumGetRangeTypeP(state->dvalues[i]); + + PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypoid, typcache->rngtype, range_count, ranges)); +} + +Datum +multirange_intersect_agg_transfn(PG_FUNCTION_ARGS) +{ + MemoryContext aggContext; + Oid mltrngtypoid; + TypeCacheEntry *typcache; + MultirangeType *result; + MultirangeType *current; + int32 range_count1; + int32 range_count2; + RangeType **ranges1; + RangeType **ranges2; + + if (!AggCheckCallContext(fcinfo, &aggContext)) + elog(ERROR, "multirange_intersect_agg_transfn called in non-aggregate context"); + + mltrngtypoid = get_fn_expr_argtype(fcinfo->flinfo, 1); + if (!type_is_multirange(mltrngtypoid)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("range_intersect_agg must be called with a multirange"))); + + typcache = multirange_get_typcache(fcinfo, mltrngtypoid); + + /* strictness ensures these are non-null */ + result = PG_GETARG_MULTIRANGE_P(0); + current = PG_GETARG_MULTIRANGE_P(1); + + multirange_deserialize(typcache->rngtype, result, &range_count1, &ranges1); + multirange_deserialize(typcache->rngtype, current, &range_count2, &ranges2); + + result = multirange_intersect_internal(mltrngtypoid, + typcache->rngtype, + range_count1, + ranges1, + range_count2, + ranges2); + PG_RETURN_RANGE_P(result); +} + + +/* multirange -> element type functions */ + +/* extract lower bound value */ +Datum +multirange_lower(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + TypeCacheEntry *typcache; + RangeBound lower; + RangeBound upper; + + if (MultirangeIsEmpty(mr)) + PG_RETURN_NULL(); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + multirange_get_bounds(typcache->rngtype, mr, 0, + &lower, &upper); + + if (!lower.infinite) + PG_RETURN_DATUM(lower.val); + else + PG_RETURN_NULL(); +} + +/* extract upper bound value */ +Datum +multirange_upper(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + TypeCacheEntry *typcache; + RangeBound lower; + RangeBound upper; + + if (MultirangeIsEmpty(mr)) + PG_RETURN_NULL(); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1, + &lower, &upper); + + if (!upper.infinite) + PG_RETURN_DATUM(upper.val); + else + PG_RETURN_NULL(); +} + + +/* multirange -> bool functions */ + +/* is multirange empty? */ +Datum +multirange_empty(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + + PG_RETURN_BOOL(MultirangeIsEmpty(mr)); +} + +/* is lower bound inclusive? */ +Datum +multirange_lower_inc(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + TypeCacheEntry *typcache; + RangeBound lower; + RangeBound upper; + + if (MultirangeIsEmpty(mr)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + multirange_get_bounds(typcache->rngtype, mr, 0, + &lower, &upper); + + PG_RETURN_BOOL(lower.inclusive); +} + +/* is upper bound inclusive? */ +Datum +multirange_upper_inc(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + TypeCacheEntry *typcache; + RangeBound lower; + RangeBound upper; + + if (MultirangeIsEmpty(mr)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1, + &lower, &upper); + + PG_RETURN_BOOL(upper.inclusive); +} + +/* is lower bound infinite? */ +Datum +multirange_lower_inf(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + TypeCacheEntry *typcache; + RangeBound lower; + RangeBound upper; + + if (MultirangeIsEmpty(mr)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + multirange_get_bounds(typcache->rngtype, mr, 0, + &lower, &upper); + + PG_RETURN_BOOL(lower.infinite); +} + +/* is upper bound infinite? */ +Datum +multirange_upper_inf(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + TypeCacheEntry *typcache; + RangeBound lower; + RangeBound upper; + + if (MultirangeIsEmpty(mr)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1, + &lower, &upper); + + PG_RETURN_BOOL(upper.infinite); +} + + + +/* multirange, element -> bool functions */ + +/* contains? */ +Datum +multirange_contains_elem(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + Datum val = PG_GETARG_DATUM(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(multirange_contains_elem_internal(typcache->rngtype, mr, val)); +} + +/* contained by? */ +Datum +elem_contained_by_multirange(PG_FUNCTION_ARGS) +{ + Datum val = PG_GETARG_DATUM(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(multirange_contains_elem_internal(typcache->rngtype, mr, val)); +} + +/* + * Comparison function for checking if any range of multirange contains given + * key element using binary search. + */ +static int +multirange_elem_bsearch_comparison(TypeCacheEntry *typcache, + RangeBound *lower, RangeBound *upper, + void *key, bool *match) +{ + Datum val = *((Datum *) key); + int cmp; + + if (!lower->infinite) + { + cmp = DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo, + typcache->rng_collation, + lower->val, val)); + if (cmp > 0 || (cmp == 0 && !lower->inclusive)) + return -1; + } + + if (!upper->infinite) + { + cmp = DatumGetInt32(FunctionCall2Coll(&typcache->rng_cmp_proc_finfo, + typcache->rng_collation, + upper->val, val)); + if (cmp < 0 || (cmp == 0 && !upper->inclusive)) + return 1; + } + + *match = true; + return 0; +} + +/* + * Test whether multirange mr contains a specific element value. + */ +bool +multirange_contains_elem_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr, Datum val) +{ + if (MultirangeIsEmpty(mr)) + return false; + + return multirange_bsearch_match(rangetyp, mr, &val, + multirange_elem_bsearch_comparison); +} + +/* multirange, range -> bool functions */ + +/* contains? */ +Datum +multirange_contains_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(multirange_contains_range_internal(typcache->rngtype, mr, r)); +} + +Datum +range_contains_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_contains_multirange_internal(typcache->rngtype, r, mr)); +} + +/* contained by? */ +Datum +range_contained_by_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(multirange_contains_range_internal(typcache->rngtype, mr, r)); +} + +Datum +multirange_contained_by_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_contains_multirange_internal(typcache->rngtype, r, mr)); +} + +/* + * Comparison function for checking if any range of multirange contains given + * key range using binary search. + */ +static int +multirange_range_contains_bsearch_comparison(TypeCacheEntry *typcache, + RangeBound *lower, RangeBound *upper, + void *key, bool *match) +{ + RangeBound *keyLower = (RangeBound *) key; + RangeBound *keyUpper = (RangeBound *) key + 1; + + /* Check if key range is strictly in the left or in the right */ + if (range_cmp_bounds(typcache, keyUpper, lower) < 0) + return -1; + if (range_cmp_bounds(typcache, keyLower, upper) > 0) + return 1; + + /* + * At this point we found overlapping range. But we have to check if it + * really contains the key range. Anyway, we have to stop our search + * here, because multirange contains only non-overlapping ranges. + */ + *match = range_bounds_contains(typcache, lower, upper, keyLower, keyUpper); + + return 0; +} + +/* + * Test whether multirange mr contains a specific range r. + */ +bool +multirange_contains_range_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr, + const RangeType *r) +{ + RangeBound bounds[2]; + bool empty; + + /* + * Every multirange contains an infinite number of empty ranges, even an + * empty one. + */ + if (RangeIsEmpty(r)) + return true; + + if (MultirangeIsEmpty(mr)) + return false; + + range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty); + Assert(!empty); + + return multirange_bsearch_match(rangetyp, mr, bounds, + multirange_range_contains_bsearch_comparison); +} + +/* + * Test whether range r contains a multirange mr. + */ +bool +range_contains_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound lower1, + upper1, + lower2, + upper2, + tmp; + bool empty; + + /* + * Every range contains an infinite number of empty multiranges, even an + * empty one. + */ + if (MultirangeIsEmpty(mr)) + return true; + + if (RangeIsEmpty(r)) + return false; + + /* Range contains multirange iff it contains its union range. */ + range_deserialize(rangetyp, r, &lower1, &upper1, &empty); + Assert(!empty); + multirange_get_bounds(rangetyp, mr, 0, &lower2, &tmp); + multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper2); + + return range_bounds_contains(rangetyp, &lower1, &upper1, &lower2, &upper2); +} + + +/* multirange, multirange -> bool functions */ + +/* equality (internal version) */ +bool +multirange_eq_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2) +{ + int32 range_count_1; + int32 range_count_2; + int32 i; + RangeBound lower1, + upper1, + lower2, + upper2; + + /* Different types should be prevented by ANYMULTIRANGE matching rules */ + if (MultirangeTypeGetOid(mr1) != MultirangeTypeGetOid(mr2)) + elog(ERROR, "multirange types do not match"); + + range_count_1 = mr1->rangeCount; + range_count_2 = mr2->rangeCount; + + if (range_count_1 != range_count_2) + return false; + + for (i = 0; i < range_count_1; i++) + { + multirange_get_bounds(rangetyp, mr1, i, &lower1, &upper1); + multirange_get_bounds(rangetyp, mr2, i, &lower2, &upper2); + + if (range_cmp_bounds(rangetyp, &lower1, &lower2) != 0 || + range_cmp_bounds(rangetyp, &upper1, &upper2) != 0) + return false; + } + + return true; +} + +/* equality */ +Datum +multirange_eq(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + PG_RETURN_BOOL(multirange_eq_internal(typcache->rngtype, mr1, mr2)); +} + +/* inequality (internal version) */ +bool +multirange_ne_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2) +{ + return (!multirange_eq_internal(rangetyp, mr1, mr2)); +} + +/* inequality */ +Datum +multirange_ne(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + PG_RETURN_BOOL(multirange_ne_internal(typcache->rngtype, mr1, mr2)); +} + +/* overlaps? */ +Datum +range_overlaps_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_overlaps_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_overlaps_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_overlaps_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_overlaps_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + PG_RETURN_BOOL(multirange_overlaps_multirange_internal(typcache->rngtype, mr1, mr2)); +} + +/* + * Comparison function for checking if any range of multirange overlaps given + * key range using binary search. + */ +static int +multirange_range_overlaps_bsearch_comparison(TypeCacheEntry *typcache, + RangeBound *lower, RangeBound *upper, + void *key, bool *match) +{ + RangeBound *keyLower = (RangeBound *) key; + RangeBound *keyUpper = (RangeBound *) key + 1; + + if (range_cmp_bounds(typcache, keyUpper, lower) < 0) + return -1; + if (range_cmp_bounds(typcache, keyLower, upper) > 0) + return 1; + + *match = true; + return 0; +} + +bool +range_overlaps_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound bounds[2]; + bool empty; + + /* + * Empties never overlap, even with empties. (This seems strange since + * they *do* contain each other, but we want to follow how ranges work.) + */ + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + return false; + + range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty); + Assert(!empty); + + return multirange_bsearch_match(rangetyp, mr, bounds, + multirange_range_overlaps_bsearch_comparison); +} + +bool +multirange_overlaps_multirange_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2) +{ + int32 range_count1; + int32 range_count2; + int32 i1; + int32 i2; + RangeBound lower1, + upper1, + lower2, + upper2; + + /* + * Empties never overlap, even with empties. (This seems strange since + * they *do* contain each other, but we want to follow how ranges work.) + */ + if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2)) + return false; + + range_count1 = mr1->rangeCount; + range_count2 = mr2->rangeCount; + + /* + * Every range in mr1 gets a chance to overlap with the ranges in mr2, but + * we can use their ordering to avoid O(n^2). This is similar to + * range_overlaps_multirange where r1 : r2 :: mrr : r, but there if we + * don't find an overlap with r we're done, and here if we don't find an + * overlap with r2 we try the next r2. + */ + i1 = 0; + multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1); + for (i1 = 0, i2 = 0; i2 < range_count2; i2++) + { + multirange_get_bounds(rangetyp, mr2, i2, &lower2, &upper2); + + /* Discard r1s while r1 << r2 */ + while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0) + { + if (++i1 >= range_count1) + return false; + multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1); + } + + /* + * If r1 && r2, we're done, otherwise we failed to find an overlap for + * r2, so go to the next one. + */ + if (range_bounds_overlaps(rangetyp, &lower1, &upper1, &lower2, &upper2)) + return true; + } + + /* We looked through all of mr2 without finding an overlap */ + return false; +} + +/* does not extend to right of? */ +bool +range_overleft_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound lower1, + upper1, + lower2, + upper2; + bool empty; + + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + PG_RETURN_BOOL(false); + + + range_deserialize(rangetyp, r, &lower1, &upper1, &empty); + Assert(!empty); + multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, + &lower2, &upper2); + + PG_RETURN_BOOL(range_cmp_bounds(rangetyp, &upper1, &upper2) <= 0); +} + +Datum +range_overleft_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_overleft_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_overleft_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + RangeBound lower1, + upper1, + lower2, + upper2; + bool empty; + + if (MultirangeIsEmpty(mr) || RangeIsEmpty(r)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1, + &lower1, &upper1); + range_deserialize(typcache->rngtype, r, &lower2, &upper2, &empty); + Assert(!empty); + + PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &upper1, &upper2) <= 0); +} + +Datum +multirange_overleft_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + RangeBound lower1, + upper1, + lower2, + upper2; + + if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + multirange_get_bounds(typcache->rngtype, mr1, mr1->rangeCount - 1, + &lower1, &upper1); + multirange_get_bounds(typcache->rngtype, mr2, mr2->rangeCount - 1, + &lower2, &upper2); + + PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &upper1, &upper2) <= 0); +} + +/* does not extend to left of? */ +bool +range_overright_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound lower1, + upper1, + lower2, + upper2; + bool empty; + + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + PG_RETURN_BOOL(false); + + range_deserialize(rangetyp, r, &lower1, &upper1, &empty); + Assert(!empty); + multirange_get_bounds(rangetyp, mr, 0, &lower2, &upper2); + + return (range_cmp_bounds(rangetyp, &lower1, &lower2) >= 0); +} + +Datum +range_overright_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_overright_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_overright_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + RangeBound lower1, + upper1, + lower2, + upper2; + bool empty; + + if (MultirangeIsEmpty(mr) || RangeIsEmpty(r)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + multirange_get_bounds(typcache->rngtype, mr, 0, &lower1, &upper1); + range_deserialize(typcache->rngtype, r, &lower2, &upper2, &empty); + Assert(!empty); + + PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &lower1, &lower2) >= 0); +} + +Datum +multirange_overright_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + RangeBound lower1, + upper1, + lower2, + upper2; + + if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2)) + PG_RETURN_BOOL(false); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + multirange_get_bounds(typcache->rngtype, mr1, 0, &lower1, &upper1); + multirange_get_bounds(typcache->rngtype, mr2, 0, &lower2, &upper2); + + PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &lower1, &lower2) >= 0); +} + +/* contains? */ +Datum +multirange_contains_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + PG_RETURN_BOOL(multirange_contains_multirange_internal(typcache->rngtype, mr1, mr2)); +} + +/* contained by? */ +Datum +multirange_contained_by_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + PG_RETURN_BOOL(multirange_contains_multirange_internal(typcache->rngtype, mr2, mr1)); +} + +/* + * Test whether multirange mr1 contains every range from another multirange mr2. + */ +bool +multirange_contains_multirange_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2) +{ + int32 range_count1 = mr1->rangeCount; + int32 range_count2 = mr2->rangeCount; + int i1, + i2; + RangeBound lower1, + upper1, + lower2, + upper2; + + /* + * We follow the same logic for empties as ranges: - an empty multirange + * contains an empty range/multirange. - an empty multirange can't contain + * any other range/multirange. - an empty multirange is contained by any + * other range/multirange. + */ + + if (range_count2 == 0) + return true; + if (range_count1 == 0) + return false; + + /* + * Every range in mr2 must be contained by some range in mr1. To avoid + * O(n^2) we walk through both ranges in tandem. + */ + i1 = 0; + multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1); + for (i2 = 0; i2 < range_count2; i2++) + { + multirange_get_bounds(rangetyp, mr2, i2, &lower2, &upper2); + + /* Discard r1s while r1 << r2 */ + while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0) + { + if (++i1 >= range_count1) + return false; + multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1); + } + + /* + * If r1 @> r2, go to the next r2, otherwise return false (since every + * r1[n] and r1[n+1] must have a gap). Note this will give weird + * answers if you don't canonicalize, e.g. with a custom + * int2multirange {[1,1], [2,2]} there is a "gap". But that is + * consistent with other range operators, e.g. '[1,1]'::int2range -|- + * '[2,2]'::int2range is false. + */ + if (!range_bounds_contains(rangetyp, &lower1, &upper1, + &lower2, &upper2)) + return false; + } + + /* All ranges in mr2 are satisfied */ + return true; +} + +/* strictly left of? */ +Datum +range_before_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_before_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_before_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_after_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_before_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + PG_RETURN_BOOL(multirange_before_multirange_internal(typcache->rngtype, mr1, mr2)); +} + +/* strictly right of? */ +Datum +range_after_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_after_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_after_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_before_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_after_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + PG_RETURN_BOOL(multirange_before_multirange_internal(typcache->rngtype, mr2, mr1)); +} + +/* strictly left of? (internal version) */ +bool +range_before_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound lower1, + upper1, + lower2, + upper2; + bool empty; + + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + return false; + + range_deserialize(rangetyp, r, &lower1, &upper1, &empty); + Assert(!empty); + + multirange_get_bounds(rangetyp, mr, 0, &lower2, &upper2); + + return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0); +} + +bool +multirange_before_multirange_internal(TypeCacheEntry *rangetyp, + const MultirangeType *mr1, + const MultirangeType *mr2) +{ + RangeBound lower1, + upper1, + lower2, + upper2; + + if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2)) + return false; + + multirange_get_bounds(rangetyp, mr1, mr1->rangeCount - 1, + &lower1, &upper1); + multirange_get_bounds(rangetyp, mr2, 0, + &lower2, &upper2); + + return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0); +} + +/* strictly right of? (internal version) */ +bool +range_after_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound lower1, + upper1, + lower2, + upper2; + bool empty; + int32 range_count; + + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + return false; + + range_deserialize(rangetyp, r, &lower1, &upper1, &empty); + Assert(!empty); + + range_count = mr->rangeCount; + multirange_get_bounds(rangetyp, mr, range_count - 1, + &lower2, &upper2); + + return (range_cmp_bounds(rangetyp, &lower1, &upper2) > 0); +} + +bool +range_adjacent_multirange_internal(TypeCacheEntry *rangetyp, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound lower1, + upper1, + lower2, + upper2; + bool empty; + int32 range_count; + + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + return false; + + range_deserialize(rangetyp, r, &lower1, &upper1, &empty); + Assert(!empty); + + range_count = mr->rangeCount; + multirange_get_bounds(rangetyp, mr, 0, + &lower2, &upper2); + + if (bounds_adjacent(rangetyp, upper1, lower2)) + return true; + + if (range_count > 1) + multirange_get_bounds(rangetyp, mr, range_count - 1, + &lower2, &upper2); + + if (bounds_adjacent(rangetyp, upper2, lower1)) + return true; + + return false; +} + +/* adjacent to? */ +Datum +range_adjacent_multirange(PG_FUNCTION_ARGS) +{ + RangeType *r = PG_GETARG_RANGE_P(0); + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_adjacent_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_adjacent_range(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + RangeType *r = PG_GETARG_RANGE_P(1); + TypeCacheEntry *typcache; + + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + return false; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + + PG_RETURN_BOOL(range_adjacent_multirange_internal(typcache->rngtype, r, mr)); +} + +Datum +multirange_adjacent_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + TypeCacheEntry *typcache; + int32 range_count1; + int32 range_count2; + RangeBound lower1, + upper1, + lower2, + upper2; + + if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2)) + return false; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + range_count1 = mr1->rangeCount; + range_count2 = mr2->rangeCount; + multirange_get_bounds(typcache->rngtype, mr1, range_count1 - 1, + &lower1, &upper1); + multirange_get_bounds(typcache->rngtype, mr2, 0, + &lower2, &upper2); + if (bounds_adjacent(typcache->rngtype, upper1, lower2)) + PG_RETURN_BOOL(true); + + if (range_count1 > 1) + multirange_get_bounds(typcache->rngtype, mr1, 0, + &lower1, &upper1); + if (range_count2 > 1) + multirange_get_bounds(typcache->rngtype, mr2, range_count2 - 1, + &lower2, &upper2); + if (bounds_adjacent(typcache->rngtype, upper2, lower1)) + PG_RETURN_BOOL(true); + PG_RETURN_BOOL(false); +} + +/* Btree support */ + +/* btree comparator */ +Datum +multirange_cmp(PG_FUNCTION_ARGS) +{ + MultirangeType *mr1 = PG_GETARG_MULTIRANGE_P(0); + MultirangeType *mr2 = PG_GETARG_MULTIRANGE_P(1); + int32 range_count_1; + int32 range_count_2; + int32 range_count_max; + int32 i; + TypeCacheEntry *typcache; + int cmp = 0; /* If both are empty we'll use this. */ + + /* Different types should be prevented by ANYMULTIRANGE matching rules */ + if (MultirangeTypeGetOid(mr1) != MultirangeTypeGetOid(mr2)) + elog(ERROR, "multirange types do not match"); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1)); + + range_count_1 = mr1->rangeCount; + range_count_2 = mr2->rangeCount; + + /* Loop over source data */ + range_count_max = Max(range_count_1, range_count_2); + for (i = 0; i < range_count_max; i++) + { + RangeBound lower1, + upper1, + lower2, + upper2; + + /* + * If one multirange is shorter, it's as if it had empty ranges at the + * end to extend its length. An empty range compares earlier than any + * other range, so the shorter multirange comes before the longer. + * This is the same behavior as in other types, e.g. in strings 'aaa' + * < 'aaaaaa'. + */ + if (i >= range_count_1) + { + cmp = -1; + break; + } + if (i >= range_count_2) + { + cmp = 1; + break; + } + + multirange_get_bounds(typcache->rngtype, mr1, i, &lower1, &upper1); + multirange_get_bounds(typcache->rngtype, mr2, i, &lower2, &upper2); + + cmp = range_cmp_bounds(typcache->rngtype, &lower1, &lower2); + if (cmp == 0) + cmp = range_cmp_bounds(typcache->rngtype, &upper1, &upper2); + if (cmp != 0) + break; + } + + PG_FREE_IF_COPY(mr1, 0); + PG_FREE_IF_COPY(mr2, 1); + + PG_RETURN_INT32(cmp); +} + +/* inequality operators using the multirange_cmp function */ +Datum +multirange_lt(PG_FUNCTION_ARGS) +{ + int cmp = multirange_cmp(fcinfo); + + PG_RETURN_BOOL(cmp < 0); +} + +Datum +multirange_le(PG_FUNCTION_ARGS) +{ + int cmp = multirange_cmp(fcinfo); + + PG_RETURN_BOOL(cmp <= 0); +} + +Datum +multirange_ge(PG_FUNCTION_ARGS) +{ + int cmp = multirange_cmp(fcinfo); + + PG_RETURN_BOOL(cmp >= 0); +} + +Datum +multirange_gt(PG_FUNCTION_ARGS) +{ + int cmp = multirange_cmp(fcinfo); + + PG_RETURN_BOOL(cmp > 0); +} + +/* multirange -> range functions */ + +/* Find the smallest range that includes everything in the multirange */ +Datum +range_merge_from_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + Oid mltrngtypoid = MultirangeTypeGetOid(mr); + TypeCacheEntry *typcache; + RangeType *result; + + typcache = multirange_get_typcache(fcinfo, mltrngtypoid); + + if (MultirangeIsEmpty(mr)) + { + result = make_empty_range(typcache->rngtype); + } + else if (mr->rangeCount == 1) + { + result = multirange_get_range(typcache->rngtype, mr, 0); + } + else + { + RangeBound firstLower, + firstUpper, + lastLower, + lastUpper; + + multirange_get_bounds(typcache->rngtype, mr, 0, + &firstLower, &firstUpper); + multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1, + &lastLower, &lastUpper); + + result = make_range(typcache->rngtype, &firstLower, &lastUpper, false); + } + + PG_RETURN_RANGE_P(result); +} + +/* Hash support */ + +/* hash a multirange value */ +Datum +hash_multirange(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + uint32 result = 1; + TypeCacheEntry *typcache, + *scache; + int32 range_count, + i; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + scache = typcache->rngtype->rngelemtype; + if (!OidIsValid(scache->hash_proc_finfo.fn_oid)) + { + scache = lookup_type_cache(scache->type_id, + TYPECACHE_HASH_PROC_FINFO); + if (!OidIsValid(scache->hash_proc_finfo.fn_oid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not identify a hash function for type %s", + format_type_be(scache->type_id)))); + } + + range_count = mr->rangeCount; + for (i = 0; i < range_count; i++) + { + RangeBound lower, + upper; + uint8 flags = MultirangeGetFlagsPtr(mr)[i]; + uint32 lower_hash; + uint32 upper_hash; + uint32 range_hash; + + multirange_get_bounds(typcache->rngtype, mr, i, &lower, &upper); + + if (RANGE_HAS_LBOUND(flags)) + lower_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo, + typcache->rngtype->rng_collation, + lower.val)); + else + lower_hash = 0; + + if (RANGE_HAS_UBOUND(flags)) + upper_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo, + typcache->rngtype->rng_collation, + upper.val)); + else + upper_hash = 0; + + /* Merge hashes of flags and bounds */ + range_hash = hash_uint32((uint32) flags); + range_hash ^= lower_hash; + range_hash = (range_hash << 1) | (range_hash >> 31); + range_hash ^= upper_hash; + + /* + * Use the same approach as hash_array to combine the individual + * elements' hash values: + */ + result = (result << 5) - result + range_hash; + } + + PG_FREE_IF_COPY(mr, 0); + + PG_RETURN_UINT32(result); +} + +/* + * Returns 64-bit value by hashing a value to a 64-bit value, with a seed. + * Otherwise, similar to hash_multirange. + */ +Datum +hash_multirange_extended(PG_FUNCTION_ARGS) +{ + MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0); + Datum seed = PG_GETARG_DATUM(1); + uint64 result = 1; + TypeCacheEntry *typcache, + *scache; + int32 range_count, + i; + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + scache = typcache->rngtype->rngelemtype; + if (!OidIsValid(scache->hash_extended_proc_finfo.fn_oid)) + { + scache = lookup_type_cache(scache->type_id, + TYPECACHE_HASH_EXTENDED_PROC_FINFO); + if (!OidIsValid(scache->hash_extended_proc_finfo.fn_oid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not identify a hash function for type %s", + format_type_be(scache->type_id)))); + } + + range_count = mr->rangeCount; + for (i = 0; i < range_count; i++) + { + RangeBound lower, + upper; + uint8 flags = MultirangeGetFlagsPtr(mr)[i]; + uint64 lower_hash; + uint64 upper_hash; + uint64 range_hash; + + multirange_get_bounds(typcache->rngtype, mr, i, &lower, &upper); + + if (RANGE_HAS_LBOUND(flags)) + lower_hash = DatumGetUInt64(FunctionCall2Coll(&scache->hash_extended_proc_finfo, + typcache->rngtype->rng_collation, + lower.val, + seed)); + else + lower_hash = 0; + + if (RANGE_HAS_UBOUND(flags)) + upper_hash = DatumGetUInt64(FunctionCall2Coll(&scache->hash_extended_proc_finfo, + typcache->rngtype->rng_collation, + upper.val, + seed)); + else + upper_hash = 0; + + /* Merge hashes of flags and bounds */ + range_hash = DatumGetUInt64(hash_uint32_extended((uint32) flags, + DatumGetInt64(seed))); + range_hash ^= lower_hash; + range_hash = ROTATE_HIGH_AND_LOW_32BITS(range_hash); + range_hash ^= upper_hash; + + /* + * Use the same approach as hash_array to combine the individual + * elements' hash values: + */ + result = (result << 5) - result + range_hash; + } + + PG_FREE_IF_COPY(mr, 0); + + PG_RETURN_UINT64(result); +} diff --git a/src/backend/utils/adt/multirangetypes_selfuncs.c b/src/backend/utils/adt/multirangetypes_selfuncs.c new file mode 100644 index 000000000000..551176bc2137 --- /dev/null +++ b/src/backend/utils/adt/multirangetypes_selfuncs.c @@ -0,0 +1,1325 @@ +/*------------------------------------------------------------------------- + * + * multirangetypes_selfuncs.c + * Functions for selectivity estimation of multirange operators + * + * Estimates are based on histograms of lower and upper bounds, and the + * fraction of empty multiranges. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/adt/multirangetypes_selfuncs.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include + +#include "access/htup_details.h" +#include "catalog/pg_operator.h" +#include "catalog/pg_statistic.h" +#include "catalog/pg_type.h" +#include "utils/float.h" +#include "utils/fmgrprotos.h" +#include "utils/lsyscache.h" +#include "utils/rangetypes.h" +#include "utils/multirangetypes.h" +#include "utils/selfuncs.h" +#include "utils/typcache.h" + +static double calc_multirangesel(TypeCacheEntry *typcache, + VariableStatData *vardata, + const MultirangeType *constval, Oid operator); +static double default_multirange_selectivity(Oid operator); +static double default_multirange_selectivity(Oid operator); +static double calc_hist_selectivity(TypeCacheEntry *typcache, + VariableStatData *vardata, + const MultirangeType *constval, + Oid operator); +static double calc_hist_selectivity_scalar(TypeCacheEntry *typcache, + const RangeBound *constbound, + const RangeBound *hist, + int hist_nvalues, bool equal); +static int rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, + const RangeBound *hist, int hist_length, bool equal); +static float8 get_position(TypeCacheEntry *typcache, const RangeBound *value, + const RangeBound *hist1, const RangeBound *hist2); +static float8 get_len_position(double value, double hist1, double hist2); +static float8 get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, + const RangeBound *bound2); +static int length_hist_bsearch(Datum *length_hist_values, + int length_hist_nvalues, double value, + bool equal); +static double calc_length_hist_frac(Datum *length_hist_values, + int length_hist_nvalues, double length1, + double length2, bool equal); +static double calc_hist_selectivity_contained(TypeCacheEntry *typcache, + const RangeBound *lower, + RangeBound *upper, + const RangeBound *hist_lower, + int hist_nvalues, + Datum *length_hist_values, + int length_hist_nvalues); +static double calc_hist_selectivity_contains(TypeCacheEntry *typcache, + const RangeBound *lower, + const RangeBound *upper, + const RangeBound *hist_lower, + int hist_nvalues, + Datum *length_hist_values, + int length_hist_nvalues); + +/* + * Returns a default selectivity estimate for given operator, when we don't + * have statistics or cannot use them for some reason. + */ +static double +default_multirange_selectivity(Oid operator) +{ + switch (operator) + { + case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RANGE_OP: + case OID_RANGE_OVERLAPS_MULTIRANGE_OP: + return 0.01; + + case OID_RANGE_CONTAINS_MULTIRANGE_OP: + case OID_RANGE_MULTIRANGE_CONTAINED_OP: + case OID_MULTIRANGE_CONTAINS_RANGE_OP: + case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP: + case OID_MULTIRANGE_RANGE_CONTAINED_OP: + case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP: + return 0.005; + + case OID_MULTIRANGE_CONTAINS_ELEM_OP: + case OID_MULTIRANGE_ELEM_CONTAINED_OP: + + /* + * "multirange @> elem" is more or less identical to a scalar + * inequality "A >= b AND A <= c". + */ + return DEFAULT_MULTIRANGE_INEQ_SEL; + + case OID_MULTIRANGE_LESS_OP: + case OID_MULTIRANGE_LESS_EQUAL_OP: + case OID_MULTIRANGE_GREATER_OP: + case OID_MULTIRANGE_GREATER_EQUAL_OP: + case OID_MULTIRANGE_LEFT_RANGE_OP: + case OID_MULTIRANGE_LEFT_MULTIRANGE_OP: + case OID_RANGE_LEFT_MULTIRANGE_OP: + case OID_MULTIRANGE_RIGHT_RANGE_OP: + case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP: + case OID_RANGE_RIGHT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP: + case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP: + case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP: + /* these are similar to regular scalar inequalities */ + return DEFAULT_INEQ_SEL; + + default: + + /* + * all multirange operators should be handled above, but just in + * case + */ + return 0.01; + } +} + +/* + * multirangesel -- restriction selectivity for multirange operators + */ +Datum +multirangesel(PG_FUNCTION_ARGS) +{ + PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); + Oid operator = PG_GETARG_OID(1); + List *args = (List *) PG_GETARG_POINTER(2); + int varRelid = PG_GETARG_INT32(3); + VariableStatData vardata; + Node *other; + bool varonleft; + Selectivity selec; + TypeCacheEntry *typcache = NULL; + MultirangeType *constmultirange = NULL; + RangeType *constrange = NULL; + + /* + * If expression is not (variable op something) or (something op + * variable), then punt and return a default estimate. + */ + if (!get_restriction_variable(root, args, varRelid, + &vardata, &other, &varonleft)) + PG_RETURN_FLOAT8(default_multirange_selectivity(operator)); + + /* + * Can't do anything useful if the something is not a constant, either. + */ + if (!IsA(other, Const)) + { + ReleaseVariableStats(vardata); + PG_RETURN_FLOAT8(default_multirange_selectivity(operator)); + } + + /* + * All the multirange operators are strict, so we can cope with a NULL + * constant right away. + */ + if (((Const *) other)->constisnull) + { + ReleaseVariableStats(vardata); + PG_RETURN_FLOAT8(0.0); + } + + /* + * If var is on the right, commute the operator, so that we can assume the + * var is on the left in what follows. + */ + if (!varonleft) + { + /* we have other Op var, commute to make var Op other */ + operator = get_commutator(operator); + if (!operator) + { + /* Use default selectivity (should we raise an error instead?) */ + ReleaseVariableStats(vardata); + PG_RETURN_FLOAT8(default_multirange_selectivity(operator)); + } + } + + /* + * OK, there's a Var and a Const we're dealing with here. We need the + * Const to be of same multirange type as the column, else we can't do + * anything useful. (Such cases will likely fail at runtime, but here we'd + * rather just return a default estimate.) + * + * If the operator is "multirange @> element", the constant should be of + * the element type of the multirange column. Convert it to a multirange + * that includes only that single point, so that we don't need special + * handling for that in what follows. + */ + if (operator == OID_MULTIRANGE_CONTAINS_ELEM_OP) + { + typcache = multirange_get_typcache(fcinfo, vardata.vartype); + + if (((Const *) other)->consttype == typcache->rngtype->rngelemtype->type_id) + { + RangeBound lower, + upper; + + lower.inclusive = true; + lower.val = ((Const *) other)->constvalue; + lower.infinite = false; + lower.lower = true; + upper.inclusive = true; + upper.val = ((Const *) other)->constvalue; + upper.infinite = false; + upper.lower = false; + constrange = range_serialize(typcache->rngtype, &lower, &upper, false); + constmultirange = make_multirange(typcache->type_id, typcache->rngtype, + 1, &constrange); + } + } + else if (operator == OID_RANGE_MULTIRANGE_CONTAINED_OP || + operator == OID_MULTIRANGE_CONTAINS_RANGE_OP || + operator == OID_MULTIRANGE_OVERLAPS_RANGE_OP || + operator == OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP || + operator == OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP || + operator == OID_MULTIRANGE_LEFT_RANGE_OP || + operator == OID_MULTIRANGE_RIGHT_RANGE_OP) + { + /* + * Promote a range in "multirange OP range" just like we do an element + * in "multirange OP element". + */ + typcache = multirange_get_typcache(fcinfo, vardata.vartype); + if (((Const *) other)->consttype == typcache->rngtype->type_id) + { + constrange = DatumGetRangeTypeP(((Const *) other)->constvalue); + constmultirange = make_multirange(typcache->type_id, typcache->rngtype, + 1, &constrange); + } + } + else if (operator == OID_RANGE_OVERLAPS_MULTIRANGE_OP || + operator == OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP || + operator == OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP || + operator == OID_RANGE_LEFT_MULTIRANGE_OP || + operator == OID_RANGE_RIGHT_MULTIRANGE_OP || + operator == OID_RANGE_CONTAINS_MULTIRANGE_OP || + operator == OID_MULTIRANGE_ELEM_CONTAINED_OP || + operator == OID_MULTIRANGE_RANGE_CONTAINED_OP) + { + /* + * Here, the Var is the elem/range, not the multirange. For now we + * just punt and return the default estimate. In future we could + * disassemble the multirange constant to do something more + * intelligent. + */ + } + else if (((Const *) other)->consttype == vardata.vartype) + { + /* Both sides are the same multirange type */ + typcache = multirange_get_typcache(fcinfo, vardata.vartype); + + constmultirange = DatumGetMultirangeTypeP(((Const *) other)->constvalue); + } + + /* + * If we got a valid constant on one side of the operator, proceed to + * estimate using statistics. Otherwise punt and return a default constant + * estimate. Note that calc_multirangesel need not handle + * OID_MULTIRANGE_*_CONTAINED_OP. + */ + if (constmultirange) + selec = calc_multirangesel(typcache, &vardata, constmultirange, operator); + else + selec = default_multirange_selectivity(operator); + + ReleaseVariableStats(vardata); + + CLAMP_PROBABILITY(selec); + + PG_RETURN_FLOAT8((float8) selec); +} + +static double +calc_multirangesel(TypeCacheEntry *typcache, VariableStatData *vardata, + const MultirangeType *constval, Oid operator) +{ + double hist_selec; + double selec; + float4 empty_frac, + null_frac; + + /* + * First look up the fraction of NULLs and empty multiranges from + * pg_statistic. + */ + if (HeapTupleIsValid(vardata->statsTuple)) + { + Form_pg_statistic stats; + AttStatsSlot sslot; + + stats = (Form_pg_statistic) GETSTRUCT(vardata->statsTuple); + null_frac = stats->stanullfrac; + + /* Try to get fraction of empty multiranges */ + if (get_attstatsslot(&sslot, vardata->statsTuple, + STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM, + InvalidOid, + ATTSTATSSLOT_NUMBERS)) + { + if (sslot.nnumbers != 1) + elog(ERROR, "invalid empty fraction statistic"); /* shouldn't happen */ + empty_frac = sslot.numbers[0]; + free_attstatsslot(&sslot); + } + else + { + /* No empty fraction statistic. Assume no empty ranges. */ + empty_frac = 0.0; + } + } + else + { + /* + * No stats are available. Follow through the calculations below + * anyway, assuming no NULLs and no empty multiranges. This still + * allows us to give a better-than-nothing estimate based on whether + * the constant is an empty multirange or not. + */ + null_frac = 0.0; + empty_frac = 0.0; + } + + if (MultirangeIsEmpty(constval)) + { + /* + * An empty multirange matches all multiranges, all empty multiranges, + * or nothing, depending on the operator + */ + switch (operator) + { + /* these return false if either argument is empty */ + case OID_RANGE_OVERLAPS_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RANGE_OP: + case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP: + case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP: + case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP: + case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP: + case OID_MULTIRANGE_LEFT_MULTIRANGE_OP: + case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP: + /* nothing is less than an empty multirange */ + case OID_MULTIRANGE_LESS_OP: + selec = 0.0; + break; + + /* + * only empty multiranges can be contained by an empty + * multirange + */ + case OID_MULTIRANGE_RANGE_CONTAINED_OP: + case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP: + /* only empty ranges are <= an empty multirange */ + case OID_MULTIRANGE_LESS_EQUAL_OP: + selec = empty_frac; + break; + + /* everything contains an empty multirange */ + case OID_MULTIRANGE_CONTAINS_RANGE_OP: + case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP: + /* everything is >= an empty multirange */ + case OID_MULTIRANGE_GREATER_EQUAL_OP: + selec = 1.0; + break; + + /* all non-empty multiranges are > an empty multirange */ + case OID_MULTIRANGE_GREATER_OP: + selec = 1.0 - empty_frac; + break; + + /* an element cannot be empty */ + case OID_MULTIRANGE_ELEM_CONTAINED_OP: + case OID_MULTIRANGE_CONTAINS_ELEM_OP: + default: + elog(ERROR, "unexpected operator %u", operator); + selec = 0.0; /* keep compiler quiet */ + break; + } + } + else + { + /* + * Calculate selectivity using bound histograms. If that fails for + * some reason, e.g no histogram in pg_statistic, use the default + * constant estimate for the fraction of non-empty values. This is + * still somewhat better than just returning the default estimate, + * because this still takes into account the fraction of empty and + * NULL tuples, if we had statistics for them. + */ + hist_selec = calc_hist_selectivity(typcache, vardata, constval, + operator); + if (hist_selec < 0.0) + hist_selec = default_multirange_selectivity(operator); + + /* + * Now merge the results for the empty multiranges and histogram + * calculations, realizing that the histogram covers only the + * non-null, non-empty values. + */ + if (operator == OID_MULTIRANGE_ELEM_CONTAINED_OP || + operator == OID_MULTIRANGE_RANGE_CONTAINED_OP || + operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP) + { + /* empty is contained by anything non-empty */ + selec = (1.0 - empty_frac) * hist_selec + empty_frac; + } + else + { + /* with any other operator, empty Op non-empty matches nothing */ + selec = (1.0 - empty_frac) * hist_selec; + } + } + + /* all multirange operators are strict */ + selec *= (1.0 - null_frac); + + /* result should be in range, but make sure... */ + CLAMP_PROBABILITY(selec); + + return selec; +} + +/* + * Calculate multirange operator selectivity using histograms of multirange bounds. + * + * This estimate is for the portion of values that are not empty and not + * NULL. + */ +static double +calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata, + const MultirangeType *constval, Oid operator) +{ + TypeCacheEntry *rng_typcache = typcache->rngtype; + AttStatsSlot hslot; + AttStatsSlot lslot; + int nhist; + RangeBound *hist_lower; + RangeBound *hist_upper; + int i; + RangeBound const_lower; + RangeBound const_upper; + RangeBound tmp; + double hist_selec; + + /* Can't use the histogram with insecure multirange support functions */ + if (!statistic_proc_security_check(vardata, + rng_typcache->rng_cmp_proc_finfo.fn_oid)) + return -1; + if (OidIsValid(rng_typcache->rng_subdiff_finfo.fn_oid) && + !statistic_proc_security_check(vardata, + rng_typcache->rng_subdiff_finfo.fn_oid)) + return -1; + + /* Try to get histogram of ranges */ + if (!(HeapTupleIsValid(vardata->statsTuple) && + get_attstatsslot(&hslot, vardata->statsTuple, + STATISTIC_KIND_BOUNDS_HISTOGRAM, InvalidOid, + ATTSTATSSLOT_VALUES))) + return -1.0; + + /* check that it's a histogram, not just a dummy entry */ + if (hslot.nvalues < 2) + { + free_attstatsslot(&hslot); + return -1.0; + } + + /* + * Convert histogram of ranges into histograms of its lower and upper + * bounds. + */ + nhist = hslot.nvalues; + hist_lower = (RangeBound *) palloc(sizeof(RangeBound) * nhist); + hist_upper = (RangeBound *) palloc(sizeof(RangeBound) * nhist); + for (i = 0; i < nhist; i++) + { + bool empty; + + range_deserialize(rng_typcache, DatumGetRangeTypeP(hslot.values[i]), + &hist_lower[i], &hist_upper[i], &empty); + /* The histogram should not contain any empty ranges */ + if (empty) + elog(ERROR, "bounds histogram contains an empty range"); + } + + /* @> and @< also need a histogram of range lengths */ + if (operator == OID_MULTIRANGE_CONTAINS_RANGE_OP || + operator == OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP || + operator == OID_MULTIRANGE_RANGE_CONTAINED_OP || + operator == OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP) + { + if (!(HeapTupleIsValid(vardata->statsTuple) && + get_attstatsslot(&lslot, vardata->statsTuple, + STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM, + InvalidOid, + ATTSTATSSLOT_VALUES))) + { + free_attstatsslot(&hslot); + return -1.0; + } + + /* check that it's a histogram, not just a dummy entry */ + if (lslot.nvalues < 2) + { + free_attstatsslot(&lslot); + free_attstatsslot(&hslot); + return -1.0; + } + } + else + memset(&lslot, 0, sizeof(lslot)); + + /* Extract the bounds of the constant value. */ + Assert(constval->rangeCount > 0); + multirange_get_bounds(rng_typcache, constval, 0, + &const_lower, &tmp); + multirange_get_bounds(rng_typcache, constval, constval->rangeCount - 1, + &tmp, &const_upper); + + /* + * Calculate selectivity comparing the lower or upper bound of the + * constant with the histogram of lower or upper bounds. + */ + switch (operator) + { + case OID_MULTIRANGE_LESS_OP: + + /* + * The regular b-tree comparison operators (<, <=, >, >=) compare + * the lower bounds first, and the upper bounds for values with + * equal lower bounds. Estimate that by comparing the lower bounds + * only. This gives a fairly accurate estimate assuming there + * aren't many rows with a lower bound equal to the constant's + * lower bound. + */ + hist_selec = + calc_hist_selectivity_scalar(rng_typcache, &const_lower, + hist_lower, nhist, false); + break; + + case OID_MULTIRANGE_LESS_EQUAL_OP: + hist_selec = + calc_hist_selectivity_scalar(rng_typcache, &const_lower, + hist_lower, nhist, true); + break; + + case OID_MULTIRANGE_GREATER_OP: + hist_selec = + 1 - calc_hist_selectivity_scalar(rng_typcache, &const_lower, + hist_lower, nhist, false); + break; + + case OID_MULTIRANGE_GREATER_EQUAL_OP: + hist_selec = + 1 - calc_hist_selectivity_scalar(rng_typcache, &const_lower, + hist_lower, nhist, true); + break; + + case OID_RANGE_LEFT_MULTIRANGE_OP: + case OID_MULTIRANGE_LEFT_RANGE_OP: + case OID_MULTIRANGE_LEFT_MULTIRANGE_OP: + /* var << const when upper(var) < lower(const) */ + hist_selec = + calc_hist_selectivity_scalar(rng_typcache, &const_lower, + hist_upper, nhist, false); + break; + + case OID_RANGE_RIGHT_MULTIRANGE_OP: + case OID_MULTIRANGE_RIGHT_RANGE_OP: + case OID_MULTIRANGE_RIGHT_MULTIRANGE_OP: + /* var >> const when lower(var) > upper(const) */ + hist_selec = + 1 - calc_hist_selectivity_scalar(rng_typcache, &const_upper, + hist_lower, nhist, true); + break; + + case OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RIGHT_MULTIRANGE_OP: + /* compare lower bounds */ + hist_selec = + 1 - calc_hist_selectivity_scalar(rng_typcache, &const_lower, + hist_lower, nhist, false); + break; + + case OID_RANGE_OVERLAPS_LEFT_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP: + case OID_MULTIRANGE_OVERLAPS_LEFT_MULTIRANGE_OP: + /* compare upper bounds */ + hist_selec = + calc_hist_selectivity_scalar(rng_typcache, &const_upper, + hist_upper, nhist, true); + break; + + case OID_RANGE_OVERLAPS_MULTIRANGE_OP: + case OID_MULTIRANGE_OVERLAPS_RANGE_OP: + case OID_MULTIRANGE_OVERLAPS_MULTIRANGE_OP: + case OID_MULTIRANGE_CONTAINS_ELEM_OP: + + /* + * A && B <=> NOT (A << B OR A >> B). + * + * Since A << B and A >> B are mutually exclusive events we can + * sum their probabilities to find probability of (A << B OR A >> + * B). + * + * "multirange @> elem" is equivalent to "multirange && + * {[elem,elem]}". The caller already constructed the singular + * range from the element constant, so just treat it the same as + * &&. + */ + hist_selec = + calc_hist_selectivity_scalar(rng_typcache, + &const_lower, hist_upper, + nhist, false); + hist_selec += + (1.0 - calc_hist_selectivity_scalar(rng_typcache, + &const_upper, hist_lower, + nhist, true)); + hist_selec = 1.0 - hist_selec; + break; + + case OID_MULTIRANGE_CONTAINS_RANGE_OP: + case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP: + hist_selec = + calc_hist_selectivity_contains(rng_typcache, &const_lower, + &const_upper, hist_lower, nhist, + lslot.values, lslot.nvalues); + break; + + case OID_MULTIRANGE_RANGE_CONTAINED_OP: + case OID_MULTIRANGE_MULTIRANGE_CONTAINED_OP: + case OID_RANGE_MULTIRANGE_CONTAINED_OP: + if (const_lower.infinite) + { + /* + * Lower bound no longer matters. Just estimate the fraction + * with an upper bound <= const upper bound + */ + hist_selec = + calc_hist_selectivity_scalar(rng_typcache, &const_upper, + hist_upper, nhist, true); + } + else if (const_upper.infinite) + { + hist_selec = + 1.0 - calc_hist_selectivity_scalar(rng_typcache, &const_lower, + hist_lower, nhist, false); + } + else + { + hist_selec = + calc_hist_selectivity_contained(rng_typcache, &const_lower, + &const_upper, hist_lower, nhist, + lslot.values, lslot.nvalues); + } + break; + + default: + elog(ERROR, "unknown multirange operator %u", operator); + hist_selec = -1.0; /* keep compiler quiet */ + break; + } + + free_attstatsslot(&lslot); + free_attstatsslot(&hslot); + + return hist_selec; +} + + +/* + * Look up the fraction of values less than (or equal, if 'equal' argument + * is true) a given const in a histogram of range bounds. + */ +static double +calc_hist_selectivity_scalar(TypeCacheEntry *typcache, const RangeBound *constbound, + const RangeBound *hist, int hist_nvalues, bool equal) +{ + Selectivity selec; + int index; + + /* + * Find the histogram bin the given constant falls into. Estimate + * selectivity as the number of preceding whole bins. + */ + index = rbound_bsearch(typcache, constbound, hist, hist_nvalues, equal); + selec = (Selectivity) (Max(index, 0)) / (Selectivity) (hist_nvalues - 1); + + /* Adjust using linear interpolation within the bin */ + if (index >= 0 && index < hist_nvalues - 1) + selec += get_position(typcache, constbound, &hist[index], + &hist[index + 1]) / (Selectivity) (hist_nvalues - 1); + + return selec; +} + +/* + * Binary search on an array of range bounds. Returns greatest index of range + * bound in array which is less(less or equal) than given range bound. If all + * range bounds in array are greater or equal(greater) than given range bound, + * return -1. When "equal" flag is set conditions in brackets are used. + * + * This function is used in scalar operator selectivity estimation. Another + * goal of this function is to find a histogram bin where to stop + * interpolation of portion of bounds which are less or equal to given bound. + */ +static int +rbound_bsearch(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist, + int hist_length, bool equal) +{ + int lower = -1, + upper = hist_length - 1, + cmp, + middle; + + while (lower < upper) + { + middle = (lower + upper + 1) / 2; + cmp = range_cmp_bounds(typcache, &hist[middle], value); + + if (cmp < 0 || (equal && cmp == 0)) + lower = middle; + else + upper = middle - 1; + } + return lower; +} + + +/* + * Binary search on length histogram. Returns greatest index of range length in + * histogram which is less than (less than or equal) the given length value. If + * all lengths in the histogram are greater than (greater than or equal) the + * given length, returns -1. + */ +static int +length_hist_bsearch(Datum *length_hist_values, int length_hist_nvalues, + double value, bool equal) +{ + int lower = -1, + upper = length_hist_nvalues - 1, + middle; + + while (lower < upper) + { + double middleval; + + middle = (lower + upper + 1) / 2; + + middleval = DatumGetFloat8(length_hist_values[middle]); + if (middleval < value || (equal && middleval <= value)) + lower = middle; + else + upper = middle - 1; + } + return lower; +} + +/* + * Get relative position of value in histogram bin in [0,1] range. + */ +static float8 +get_position(TypeCacheEntry *typcache, const RangeBound *value, const RangeBound *hist1, + const RangeBound *hist2) +{ + bool has_subdiff = OidIsValid(typcache->rng_subdiff_finfo.fn_oid); + float8 position; + + if (!hist1->infinite && !hist2->infinite) + { + float8 bin_width; + + /* + * Both bounds are finite. Assuming the subtype's comparison function + * works sanely, the value must be finite, too, because it lies + * somewhere between the bounds. If it doesn't, arbitrarily return + * 0.5. + */ + if (value->infinite) + return 0.5; + + /* Can't interpolate without subdiff function */ + if (!has_subdiff) + return 0.5; + + /* Calculate relative position using subdiff function. */ + bin_width = DatumGetFloat8(FunctionCall2Coll(&typcache->rng_subdiff_finfo, + typcache->rng_collation, + hist2->val, + hist1->val)); + if (isnan(bin_width) || bin_width <= 0.0) + return 0.5; /* punt for NaN or zero-width bin */ + + position = DatumGetFloat8(FunctionCall2Coll(&typcache->rng_subdiff_finfo, + typcache->rng_collation, + value->val, + hist1->val)) + / bin_width; + + if (isnan(position)) + return 0.5; /* punt for NaN from subdiff, Inf/Inf, etc */ + + /* Relative position must be in [0,1] range */ + position = Max(position, 0.0); + position = Min(position, 1.0); + return position; + } + else if (hist1->infinite && !hist2->infinite) + { + /* + * Lower bin boundary is -infinite, upper is finite. If the value is + * -infinite, return 0.0 to indicate it's equal to the lower bound. + * Otherwise return 1.0 to indicate it's infinitely far from the lower + * bound. + */ + return ((value->infinite && value->lower) ? 0.0 : 1.0); + } + else if (!hist1->infinite && hist2->infinite) + { + /* same as above, but in reverse */ + return ((value->infinite && !value->lower) ? 1.0 : 0.0); + } + else + { + /* + * If both bin boundaries are infinite, they should be equal to each + * other, and the value should also be infinite and equal to both + * bounds. (But don't Assert that, to avoid crashing if a user creates + * a datatype with a broken comparison function). + * + * Assume the value to lie in the middle of the infinite bounds. + */ + return 0.5; + } +} + + +/* + * Get relative position of value in a length histogram bin in [0,1] range. + */ +static double +get_len_position(double value, double hist1, double hist2) +{ + if (!isinf(hist1) && !isinf(hist2)) + { + /* + * Both bounds are finite. The value should be finite too, because it + * lies somewhere between the bounds. If it doesn't, just return + * something. + */ + if (isinf(value)) + return 0.5; + + return 1.0 - (hist2 - value) / (hist2 - hist1); + } + else if (isinf(hist1) && !isinf(hist2)) + { + /* + * Lower bin boundary is -infinite, upper is finite. Return 1.0 to + * indicate the value is infinitely far from the lower bound. + */ + return 1.0; + } + else if (isinf(hist1) && isinf(hist2)) + { + /* same as above, but in reverse */ + return 0.0; + } + else + { + /* + * If both bin boundaries are infinite, they should be equal to each + * other, and the value should also be infinite and equal to both + * bounds. (But don't Assert that, to avoid crashing unnecessarily if + * the caller messes up) + * + * Assume the value to lie in the middle of the infinite bounds. + */ + return 0.5; + } +} + +/* + * Measure distance between two range bounds. + */ +static float8 +get_distance(TypeCacheEntry *typcache, const RangeBound *bound1, const RangeBound *bound2) +{ + bool has_subdiff = OidIsValid(typcache->rng_subdiff_finfo.fn_oid); + + if (!bound1->infinite && !bound2->infinite) + { + /* + * Neither bound is infinite, use subdiff function or return default + * value of 1.0 if no subdiff is available. + */ + if (has_subdiff) + { + float8 res; + + res = DatumGetFloat8(FunctionCall2Coll(&typcache->rng_subdiff_finfo, + typcache->rng_collation, + bound2->val, + bound1->val)); + /* Reject possible NaN result, also negative result */ + if (isnan(res) || res < 0.0) + return 1.0; + else + return res; + } + else + return 1.0; + } + else if (bound1->infinite && bound2->infinite) + { + /* Both bounds are infinite */ + if (bound1->lower == bound2->lower) + return 0.0; + else + return get_float8_infinity(); + } + else + { + /* One bound is infinite, the other is not */ + return get_float8_infinity(); + } +} + +/* + * Calculate the average of function P(x), in the interval [length1, length2], + * where P(x) is the fraction of tuples with length < x (or length <= x if + * 'equal' is true). + */ +static double +calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues, + double length1, double length2, bool equal) +{ + double frac; + double A, + B, + PA, + PB; + double pos; + int i; + double area; + + Assert(length2 >= length1); + + if (length2 < 0.0) + return 0.0; /* shouldn't happen, but doesn't hurt to check */ + + /* All lengths in the table are <= infinite. */ + if (isinf(length2) && equal) + return 1.0; + + /*---------- + * The average of a function between A and B can be calculated by the + * formula: + * + * B + * 1 / + * ------- | P(x)dx + * B - A / + * A + * + * The geometrical interpretation of the integral is the area under the + * graph of P(x). P(x) is defined by the length histogram. We calculate + * the area in a piecewise fashion, iterating through the length histogram + * bins. Each bin is a trapezoid: + * + * P(x2) + * /| + * / | + * P(x1)/ | + * | | + * | | + * ---+---+-- + * x1 x2 + * + * where x1 and x2 are the boundaries of the current histogram, and P(x1) + * and P(x1) are the cumulative fraction of tuples at the boundaries. + * + * The area of each trapezoid is 1/2 * (P(x2) + P(x1)) * (x2 - x1) + * + * The first bin contains the lower bound passed by the caller, so we + * use linear interpolation between the previous and next histogram bin + * boundary to calculate P(x1). Likewise for the last bin: we use linear + * interpolation to calculate P(x2). For the bins in between, x1 and x2 + * lie on histogram bin boundaries, so P(x1) and P(x2) are simply: + * P(x1) = (bin index) / (number of bins) + * P(x2) = (bin index + 1 / (number of bins) + */ + + /* First bin, the one that contains lower bound */ + i = length_hist_bsearch(length_hist_values, length_hist_nvalues, length1, equal); + if (i >= length_hist_nvalues - 1) + return 1.0; + + if (i < 0) + { + i = 0; + pos = 0.0; + } + else + { + /* interpolate length1's position in the bin */ + pos = get_len_position(length1, + DatumGetFloat8(length_hist_values[i]), + DatumGetFloat8(length_hist_values[i + 1])); + } + PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1); + B = length1; + + /* + * In the degenerate case that length1 == length2, simply return + * P(length1). This is not merely an optimization: if length1 == length2, + * we'd divide by zero later on. + */ + if (length2 == length1) + return PB; + + /* + * Loop through all the bins, until we hit the last bin, the one that + * contains the upper bound. (if lower and upper bounds are in the same + * bin, this falls out immediately) + */ + area = 0.0; + for (; i < length_hist_nvalues - 1; i++) + { + double bin_upper = DatumGetFloat8(length_hist_values[i + 1]); + + /* check if we've reached the last bin */ + if (!(bin_upper < length2 || (equal && bin_upper <= length2))) + break; + + /* the upper bound of previous bin is the lower bound of this bin */ + A = B; + PA = PB; + + B = bin_upper; + PB = (double) i / (double) (length_hist_nvalues - 1); + + /* + * Add the area of this trapezoid to the total. The point of the + * if-check is to avoid NaN, in the corner case that PA == PB == 0, + * and B - A == Inf. The area of a zero-height trapezoid (PA == PB == + * 0) is zero, regardless of the width (B - A). + */ + if (PA > 0 || PB > 0) + area += 0.5 * (PB + PA) * (B - A); + } + + /* Last bin */ + A = B; + PA = PB; + + B = length2; /* last bin ends at the query upper bound */ + if (i >= length_hist_nvalues - 1) + pos = 0.0; + else + { + if (DatumGetFloat8(length_hist_values[i]) == DatumGetFloat8(length_hist_values[i + 1])) + pos = 0.0; + else + pos = get_len_position(length2, + DatumGetFloat8(length_hist_values[i]), + DatumGetFloat8(length_hist_values[i + 1])); + } + PB = (((double) i) + pos) / (double) (length_hist_nvalues - 1); + + if (PA > 0 || PB > 0) + area += 0.5 * (PB + PA) * (B - A); + + /* + * Ok, we have calculated the area, ie. the integral. Divide by width to + * get the requested average. + * + * Avoid NaN arising from infinite / infinite. This happens at least if + * length2 is infinite. It's not clear what the correct value would be in + * that case, so 0.5 seems as good as any value. + */ + if (isinf(area) && isinf(length2)) + frac = 0.5; + else + frac = area / (length2 - length1); + + return frac; +} + +/* + * Calculate selectivity of "var <@ const" operator, ie. estimate the fraction + * of multiranges that fall within the constant lower and upper bounds. This uses + * the histograms of range lower bounds and range lengths, on the assumption + * that the range lengths are independent of the lower bounds. + * + * The caller has already checked that constant lower and upper bounds are + * finite. + */ +static double +calc_hist_selectivity_contained(TypeCacheEntry *typcache, + const RangeBound *lower, RangeBound *upper, + const RangeBound *hist_lower, int hist_nvalues, + Datum *length_hist_values, int length_hist_nvalues) +{ + int i, + upper_index; + float8 prev_dist; + double bin_width; + double upper_bin_width; + double sum_frac; + + /* + * Begin by finding the bin containing the upper bound, in the lower bound + * histogram. Any range with a lower bound > constant upper bound can't + * match, ie. there are no matches in bins greater than upper_index. + */ + upper->inclusive = !upper->inclusive; + upper->lower = true; + upper_index = rbound_bsearch(typcache, upper, hist_lower, hist_nvalues, + false); + + /* + * If the upper bound value is below the histogram's lower limit, there + * are no matches. + */ + if (upper_index < 0) + return 0.0; + + /* + * If the upper bound value is at or beyond the histogram's upper limit, + * start our loop at the last actual bin, as though the upper bound were + * within that bin; get_position will clamp its result to 1.0 anyway. + * (This corresponds to assuming that the data population above the + * histogram's upper limit is empty, exactly like what we just assumed for + * the lower limit.) + */ + upper_index = Min(upper_index, hist_nvalues - 2); + + /* + * Calculate upper_bin_width, ie. the fraction of the (upper_index, + * upper_index + 1) bin which is greater than upper bound of query range + * using linear interpolation of subdiff function. + */ + upper_bin_width = get_position(typcache, upper, + &hist_lower[upper_index], + &hist_lower[upper_index + 1]); + + /* + * In the loop, dist and prev_dist are the distance of the "current" bin's + * lower and upper bounds from the constant upper bound. + * + * bin_width represents the width of the current bin. Normally it is 1.0, + * meaning a full width bin, but can be less in the corner cases: start + * and end of the loop. We start with bin_width = upper_bin_width, because + * we begin at the bin containing the upper bound. + */ + prev_dist = 0.0; + bin_width = upper_bin_width; + + sum_frac = 0.0; + for (i = upper_index; i >= 0; i--) + { + double dist; + double length_hist_frac; + bool final_bin = false; + + /* + * dist -- distance from upper bound of query range to lower bound of + * the current bin in the lower bound histogram. Or to the lower bound + * of the constant range, if this is the final bin, containing the + * constant lower bound. + */ + if (range_cmp_bounds(typcache, &hist_lower[i], lower) < 0) + { + dist = get_distance(typcache, lower, upper); + + /* + * Subtract from bin_width the portion of this bin that we want to + * ignore. + */ + bin_width -= get_position(typcache, lower, &hist_lower[i], + &hist_lower[i + 1]); + if (bin_width < 0.0) + bin_width = 0.0; + final_bin = true; + } + else + dist = get_distance(typcache, &hist_lower[i], upper); + + /* + * Estimate the fraction of tuples in this bin that are narrow enough + * to not exceed the distance to the upper bound of the query range. + */ + length_hist_frac = calc_length_hist_frac(length_hist_values, + length_hist_nvalues, + prev_dist, dist, true); + + /* + * Add the fraction of tuples in this bin, with a suitable length, to + * the total. + */ + sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1); + + if (final_bin) + break; + + bin_width = 1.0; + prev_dist = dist; + } + + return sum_frac; +} + +/* + * Calculate selectivity of "var @> const" operator, ie. estimate the fraction + * of multiranges that contain the constant lower and upper bounds. This uses + * the histograms of range lower bounds and range lengths, on the assumption + * that the range lengths are independent of the lower bounds. + */ +static double +calc_hist_selectivity_contains(TypeCacheEntry *typcache, + const RangeBound *lower, const RangeBound *upper, + const RangeBound *hist_lower, int hist_nvalues, + Datum *length_hist_values, int length_hist_nvalues) +{ + int i, + lower_index; + double bin_width, + lower_bin_width; + double sum_frac; + float8 prev_dist; + + /* Find the bin containing the lower bound of query range. */ + lower_index = rbound_bsearch(typcache, lower, hist_lower, hist_nvalues, + true); + + /* + * If the lower bound value is below the histogram's lower limit, there + * are no matches. + */ + if (lower_index < 0) + return 0.0; + + /* + * If the lower bound value is at or beyond the histogram's upper limit, + * start our loop at the last actual bin, as though the upper bound were + * within that bin; get_position will clamp its result to 1.0 anyway. + * (This corresponds to assuming that the data population above the + * histogram's upper limit is empty, exactly like what we just assumed for + * the lower limit.) + */ + lower_index = Min(lower_index, hist_nvalues - 2); + + /* + * Calculate lower_bin_width, ie. the fraction of the of (lower_index, + * lower_index + 1) bin which is greater than lower bound of query range + * using linear interpolation of subdiff function. + */ + lower_bin_width = get_position(typcache, lower, &hist_lower[lower_index], + &hist_lower[lower_index + 1]); + + /* + * Loop through all the lower bound bins, smaller than the query lower + * bound. In the loop, dist and prev_dist are the distance of the + * "current" bin's lower and upper bounds from the constant upper bound. + * We begin from query lower bound, and walk backwards, so the first bin's + * upper bound is the query lower bound, and its distance to the query + * upper bound is the length of the query range. + * + * bin_width represents the width of the current bin. Normally it is 1.0, + * meaning a full width bin, except for the first bin, which is only + * counted up to the constant lower bound. + */ + prev_dist = get_distance(typcache, lower, upper); + sum_frac = 0.0; + bin_width = lower_bin_width; + for (i = lower_index; i >= 0; i--) + { + float8 dist; + double length_hist_frac; + + /* + * dist -- distance from upper bound of query range to current value + * of lower bound histogram or lower bound of query range (if we've + * reach it). + */ + dist = get_distance(typcache, &hist_lower[i], upper); + + /* + * Get average fraction of length histogram which covers intervals + * longer than (or equal to) distance to upper bound of query range. + */ + length_hist_frac = + 1.0 - calc_length_hist_frac(length_hist_values, + length_hist_nvalues, + prev_dist, dist, false); + + sum_frac += length_hist_frac * bin_width / (double) (hist_nvalues - 1); + + bin_width = 1.0; + prev_dist = dist; + } + + return sum_frac; +} diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c index a3ce3f3d1e18..602a724d2f8f 100644 --- a/src/backend/utils/adt/name.c +++ b/src/backend/utils/adt/name.c @@ -9,7 +9,7 @@ * always use NAMEDATALEN as the symbolic constant! - jolly 8/21/95 * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -234,7 +234,7 @@ namestrcpy(Name name, const char *str) { /* NB: We need to zero-pad the destination. */ strncpy(NameStr(*name), str, NAMEDATALEN); - NameStr(*name)[NAMEDATALEN-1] = '\0'; + NameStr(*name)[NAMEDATALEN - 1] = '\0'; } /* diff --git a/src/backend/utils/adt/network_gist.c b/src/backend/utils/adt/network_gist.c index 9813a1d2b8ca..54e8edcdbd07 100644 --- a/src/backend/utils/adt/network_gist.c +++ b/src/backend/utils/adt/network_gist.c @@ -34,7 +34,7 @@ * twice as fast as for a simpler design in which a single field doubles as * the common prefix length and the minimum ip_bits value. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/network_selfuncs.c b/src/backend/utils/adt/network_selfuncs.c index 955e0ee87f80..dca2c6321236 100644 --- a/src/backend/utils/adt/network_selfuncs.c +++ b/src/backend/utils/adt/network_selfuncs.c @@ -7,7 +7,7 @@ * operators. Estimates are based on null fraction, most common values, * and histogram of inet/cidr columns. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/network_spgist.c b/src/backend/utils/adt/network_spgist.c index 4a0b0073c738..e496a470d0ab 100644 --- a/src/backend/utils/adt/network_spgist.c +++ b/src/backend/utils/adt/network_spgist.c @@ -21,7 +21,7 @@ * the address family, everything goes into node 0 (which will probably * lead to creating an allTheSame tuple). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index f4472245ae1a..ad682c7b6c3e 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -11,7 +11,7 @@ * Transactions on Mathematical Software, Vol. 24, No. 4, December 1998, * pages 359-367. * - * Copyright (c) 1998-2020, PostgreSQL Global Development Group + * Copyright (c) 1998-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/numeric.c @@ -486,48 +486,44 @@ static void dump_var(const char *str, NumericVar *var); #define quick_init_var(v) \ do { \ - (v)->buf = (v)->ndb; \ - (v)->digits = NULL; \ + (v)->buf = (v)->ndb; \ + (v)->digits = NULL; \ } while (0) - +/* + * GPDB: NumericVar carries a local digit buffer (ndb[]); init_var must point + * buf at that local buffer (via quick_init_var), not leave it NULL. Upstream + * PG14's "memset(v, 0, sizeof(NumericVar))" leaves buf == NULL, so the GPDB + * digitbuf_free() macro ("if (buf != ndb) pfree(buf)") would pfree(NULL). + */ #define init_var(v) \ do { \ - quick_init_var((v)); \ + quick_init_var((v)); \ (v)->ndigits = (v)->weight = (v)->sign = (v)->dscale = 0; \ } while (0) - -#define digitbuf_alloc(ndigits) \ +#define digitbuf_alloc(ndigits) \ ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit))) -#define digitbuf_free(v) \ +#define digitbuf_free(v) \ do { \ - if ((v)->buf != (v)->ndb) \ - { \ - pfree((v)->buf); \ - (v)->buf = (v)->ndb; \ - } \ + if ((v)->buf != (v)->ndb) \ + { \ + pfree((v)->buf); \ + (v)->buf = (v)->ndb; \ + } \ } while (0) -#define free_var(v) \ - digitbuf_free((v)); +#define free_var(v) digitbuf_free((v)) -/* - * init_alloc_var() - - * - * Init a var and allocate digit buffer of ndigits digits (plus a spare - * digit for rounding). - * Called when first using a var. - */ -#define init_alloc_var(v, n) \ - do { \ - (v)->buf = (v)->ndb; \ - (v)->ndigits = (n); \ - if ((n) > NUMERIC_LOCAL_NMAX) \ - (v)->buf = digitbuf_alloc((n) + 1); \ - (v)->buf[0] = 0; \ - (v)->digits = (v)->buf + 1; \ +#define init_alloc_var(v, n) \ + do { \ + (v)->buf = (v)->ndb; \ + (v)->ndigits = (n); \ + if ((n) > NUMERIC_LOCAL_NMAX) \ + (v)->buf = digitbuf_alloc((n) + 1); \ + (v)->buf[0] = 0; \ + (v)->digits = (v)->buf + 1; \ } while (0) #define NUMERIC_DIGITS(num) (NUMERIC_HEADER_IS_SHORT(num) ? \ @@ -634,7 +630,8 @@ static void round_var(NumericVar *var, int rscale); static void trunc_var(NumericVar *var, int rscale); static void strip_var(NumericVar *var); static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2, - const NumericVar *count_var, NumericVar *result_var); + const NumericVar *count_var, bool reversed_bounds, + NumericVar *result_var); static void accum_sum_add(NumericSumAccum *accum, const NumericVar *var1); static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val); @@ -1786,10 +1783,11 @@ width_bucket_numeric(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), errmsg("operand, lower bound, and upper bound cannot be NaN"))); - else + /* We allow "operand" to be infinite; cmp_numerics will cope */ + if (NUMERIC_IS_INF(bound1) || NUMERIC_IS_INF(bound2)) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), - errmsg("operand, lower bound, and upper bound cannot be infinity"))); + errmsg("lower and upper bounds must be finite"))); } quick_init_var(&result_var); @@ -1813,8 +1811,8 @@ width_bucket_numeric(PG_FUNCTION_ARGS) else if (cmp_numerics(operand, bound2) >= 0) add_var(&count_var, &const_one, &result_var); else - compute_bucket(operand, bound1, bound2, - &count_var, &result_var); + compute_bucket(operand, bound1, bound2, &count_var, false, + &result_var); break; /* bound1 > bound2 */ @@ -1824,8 +1822,8 @@ width_bucket_numeric(PG_FUNCTION_ARGS) else if (cmp_numerics(operand, bound2) <= 0) add_var(&count_var, &const_one, &result_var); else - compute_bucket(operand, bound1, bound2, - &count_var, &result_var); + compute_bucket(operand, bound1, bound2, &count_var, true, + &result_var); break; } @@ -1844,11 +1842,13 @@ width_bucket_numeric(PG_FUNCTION_ARGS) /* * If 'operand' is not outside the bucket range, determine the correct * bucket for it to go. The calculations performed by this function - * are derived directly from the SQL2003 spec. + * are derived directly from the SQL2003 spec. Note however that we + * multiply by count before dividing, to avoid unnecessary roundoff error. */ static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2, - const NumericVar *count_var, NumericVar *result_var) + const NumericVar *count_var, bool reversed_bounds, + NumericVar *result_var) { NumericVar bound1_var; NumericVar bound2_var; @@ -1858,23 +1858,21 @@ compute_bucket(Numeric operand, Numeric bound1, Numeric bound2, init_var_from_num(bound2, &bound2_var); init_var_from_num(operand, &operand_var); - if (cmp_var(&bound1_var, &bound2_var) < 0) + if (!reversed_bounds) { sub_var(&operand_var, &bound1_var, &operand_var); sub_var(&bound2_var, &bound1_var, &bound2_var); - div_var(&operand_var, &bound2_var, result_var, - select_div_scale(&operand_var, &bound2_var), true); } else { sub_var(&bound1_var, &operand_var, &operand_var); - sub_var(&bound1_var, &bound2_var, &bound1_var); - div_var(&operand_var, &bound1_var, result_var, - select_div_scale(&operand_var, &bound1_var), true); + sub_var(&bound1_var, &bound2_var, &bound2_var); } - mul_var(result_var, count_var, result_var, - result_var->dscale + count_var->dscale); + mul_var(&operand_var, count_var, &operand_var, + operand_var.dscale + count_var->dscale); + div_var(&operand_var, &bound2_var, result_var, + select_div_scale(&operand_var, &bound2_var), true); add_var(result_var, &const_one, result_var); floor_var(result_var, result_var); @@ -4412,23 +4410,90 @@ numeric_trim_scale(PG_FUNCTION_ARGS) * ---------------------------------------------------------------------- */ - -Datum -int4_numeric(PG_FUNCTION_ARGS) +Numeric +int64_to_numeric(int64 val) { - int32 val = PG_GETARG_INT32(0); Numeric res; NumericVar result; quick_init_var(&result); - int64_to_numericvar((int64) val, &result); + int64_to_numericvar(val, &result); res = make_result(&result); free_var(&result); - PG_RETURN_NUMERIC(res); + return res; +} + +/* + * Convert val1/(10**val2) to numeric. This is much faster than normal + * numeric division. + */ +Numeric +int64_div_fast_to_numeric(int64 val1, int log10val2) +{ + Numeric res; + NumericVar result; + int64 saved_val1 = val1; + int w; + int m; + + /* how much to decrease the weight by */ + w = log10val2 / DEC_DIGITS; + /* how much is left */ + m = log10val2 % DEC_DIGITS; + + /* + * If there is anything left, multiply the dividend by what's left, then + * shift the weight by one more. + */ + if (m > 0) + { + static int pow10[] = {1, 10, 100, 1000}; + + StaticAssertStmt(lengthof(pow10) == DEC_DIGITS, "mismatch with DEC_DIGITS"); + if (unlikely(pg_mul_s64_overflow(val1, pow10[DEC_DIGITS - m], &val1))) + { + /* + * If it doesn't fit, do the whole computation in numeric the slow + * way. Note that va1l may have been overwritten, so use + * saved_val1 instead. + */ + int val2 = 1; + + for (int i = 0; i < log10val2; i++) + val2 *= 10; + res = numeric_div_opt_error(int64_to_numeric(saved_val1), int64_to_numeric(val2), NULL); + res = DatumGetNumeric(DirectFunctionCall2(numeric_round, + NumericGetDatum(res), + Int32GetDatum(log10val2))); + return res; + } + w++; + } + + init_var(&result); + + int64_to_numericvar(val1, &result); + + result.weight -= w; + result.dscale += w * DEC_DIGITS - (DEC_DIGITS - m); + + res = make_result(&result); + + free_var(&result); + + return res; +} + +Datum +int4_numeric(PG_FUNCTION_ARGS) +{ + int32 val = PG_GETARG_INT32(0); + + PG_RETURN_NUMERIC(int64_to_numeric(val)); } int32 @@ -4452,11 +4517,11 @@ numeric_int4_opt_error(Numeric num, bool *have_error) if (NUMERIC_IS_NAN(num)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert NaN to integer"))); + errmsg("cannot convert NaN to %s", "integer"))); else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert infinity to integer"))); + errmsg("cannot convert infinity to %s", "integer"))); } } @@ -4513,18 +4578,8 @@ Datum int8_numeric(PG_FUNCTION_ARGS) { int64 val = PG_GETARG_INT64(0); - Numeric res; - NumericVar result; - - quick_init_var(&result); - - int64_to_numericvar(val, &result); - res = make_result(&result); - - free_var(&result); - - PG_RETURN_NUMERIC(res); + PG_RETURN_NUMERIC(int64_to_numeric(val)); } @@ -4540,11 +4595,11 @@ numeric_int8(PG_FUNCTION_ARGS) if (NUMERIC_IS_NAN(num)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert NaN to bigint"))); + errmsg("cannot convert NaN to %s", "bigint"))); else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert infinity to bigint"))); + errmsg("cannot convert infinity to %s", "bigint"))); } /* Convert to variable format and thence to int8 */ @@ -4563,18 +4618,8 @@ Datum int2_numeric(PG_FUNCTION_ARGS) { int16 val = PG_GETARG_INT16(0); - Numeric res; - NumericVar result; - - quick_init_var(&result); - - int64_to_numericvar((int64) val, &result); - - res = make_result(&result); - - free_var(&result); - PG_RETURN_NUMERIC(res); + PG_RETURN_NUMERIC(int64_to_numeric(val)); } @@ -4591,11 +4636,11 @@ numeric_int2(PG_FUNCTION_ARGS) if (NUMERIC_IS_NAN(num)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert NaN to smallint"))); + errmsg("cannot convert NaN to %s", "smallint"))); else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert infinity to smallint"))); + errmsg("cannot convert infinity to %s", "smallint"))); } /* Convert to variable format and thence to int8 */ @@ -4782,11 +4827,11 @@ numeric_pg_lsn(PG_FUNCTION_ARGS) if (NUMERIC_IS_NAN(num)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert NaN to pg_lsn"))); + errmsg("cannot convert NaN to %s", "pg_lsn"))); else ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert infinity to pg_lsn"))); + errmsg("cannot convert infinity to %s", "pg_lsn"))); } /* Convert to variable format and thence to pg_lsn */ @@ -5653,11 +5698,7 @@ int2_accum(PG_FUNCTION_ARGS) #ifdef HAVE_INT128 do_int128_accum(state, (int128) PG_GETARG_INT16(1)); #else - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, - PG_GETARG_DATUM(1))); - do_numeric_accum(state, newval); + do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT16(1))); #endif } @@ -5680,11 +5721,7 @@ int4_accum(PG_FUNCTION_ARGS) #ifdef HAVE_INT128 do_int128_accum(state, (int128) PG_GETARG_INT32(1)); #else - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, - PG_GETARG_DATUM(1))); - do_numeric_accum(state, newval); + do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT32(1))); #endif } @@ -5703,13 +5740,7 @@ int8_accum(PG_FUNCTION_ARGS) state = makeNumericAggState(fcinfo, true); if (!PG_ARGISNULL(1)) - { - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, - PG_GETARG_DATUM(1))); - do_numeric_accum(state, newval); - } + do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1))); PG_RETURN_POINTER(state); } @@ -5943,11 +5974,7 @@ int8_avg_accum(PG_FUNCTION_ARGS) #ifdef HAVE_INT128 do_int128_accum(state, (int128) PG_GETARG_INT64(1)); #else - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, - PG_GETARG_DATUM(1))); - do_numeric_accum(state, newval); + do_numeric_accum(state, int64_to_numeric(PG_GETARG_INT64(1))); #endif } @@ -6150,13 +6177,8 @@ int2_accum_inv(PG_FUNCTION_ARGS) #ifdef HAVE_INT128 do_int128_discard(state, (int128) PG_GETARG_INT16(1)); #else - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, - PG_GETARG_DATUM(1))); - /* Should never fail, all inputs have dscale 0 */ - if (!do_numeric_discard(state, newval)) + if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT16(1)))) elog(ERROR, "do_numeric_discard failed unexpectedly"); #endif } @@ -6180,13 +6202,8 @@ int4_accum_inv(PG_FUNCTION_ARGS) #ifdef HAVE_INT128 do_int128_discard(state, (int128) PG_GETARG_INT32(1)); #else - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, - PG_GETARG_DATUM(1))); - /* Should never fail, all inputs have dscale 0 */ - if (!do_numeric_discard(state, newval)) + if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT32(1)))) elog(ERROR, "do_numeric_discard failed unexpectedly"); #endif } @@ -6207,13 +6224,8 @@ int8_accum_inv(PG_FUNCTION_ARGS) if (!PG_ARGISNULL(1)) { - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, - PG_GETARG_DATUM(1))); - /* Should never fail, all inputs have dscale 0 */ - if (!do_numeric_discard(state, newval)) + if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1)))) elog(ERROR, "do_numeric_discard failed unexpectedly"); } @@ -6236,13 +6248,8 @@ int8_avg_accum_inv(PG_FUNCTION_ARGS) #ifdef HAVE_INT128 do_int128_discard(state, (int128) PG_GETARG_INT64(1)); #else - Numeric newval; - - newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, - PG_GETARG_DATUM(1))); - /* Should never fail, all inputs have dscale 0 */ - if (!do_numeric_discard(state, newval)) + if (!do_numeric_discard(state, int64_to_numeric(PG_GETARG_INT64(1)))) elog(ERROR, "do_numeric_discard failed unexpectedly"); #endif } @@ -6297,8 +6304,7 @@ numeric_poly_avg(PG_FUNCTION_ARGS) int128_to_numericvar(state->sumX, &result); - countd = DirectFunctionCall1(int8_numeric, - Int64GetDatumFast(state->N)); + countd = NumericGetDatum(int64_to_numeric(state->N)); sumd = NumericGetDatum(make_result(&result)); free_var(&result); @@ -6334,7 +6340,7 @@ numeric_avg(PG_FUNCTION_ARGS) if (state->nInfcount > 0) PG_RETURN_NUMERIC(make_result(&const_ninf)); - N_datum = DirectFunctionCall1(int8_numeric, Int64GetDatum(state->N)); + N_datum = NumericGetDatum(int64_to_numeric(state->N)); init_var(&sumX_var); accum_sum_final(&state->sumX, &sumX_var); @@ -6794,7 +6800,6 @@ Datum int8_sum(PG_FUNCTION_ARGS) { Numeric oldsum; - Datum newval; if (PG_ARGISNULL(0)) { @@ -6802,8 +6807,7 @@ int8_sum(PG_FUNCTION_ARGS) if (PG_ARGISNULL(1)) PG_RETURN_NULL(); /* still no non-null */ /* This is the first non-null input. */ - newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1)); - PG_RETURN_DATUM(newval); + PG_RETURN_NUMERIC(int64_to_numeric(PG_GETARG_INT64(1))); } /* @@ -6819,10 +6823,9 @@ int8_sum(PG_FUNCTION_ARGS) PG_RETURN_NUMERIC(oldsum); /* OK to do the addition. */ - newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1)); - PG_RETURN_DATUM(DirectFunctionCall2(numeric_add, - NumericGetDatum(oldsum), newval)); + NumericGetDatum(oldsum), + NumericGetDatum(int64_to_numeric(PG_GETARG_INT64(1))))); } /* @@ -7000,10 +7003,8 @@ int8_avg(PG_FUNCTION_ARGS) if (transdata->count == 0) PG_RETURN_NULL(); - countd = DirectFunctionCall1(int8_numeric, - Int64GetDatumFast(transdata->count)); - sumd = DirectFunctionCall1(int8_numeric, - Int64GetDatumFast(transdata->sum)); + countd = NumericGetDatum(int64_to_numeric(transdata->count)); + sumd = NumericGetDatum(int64_to_numeric(transdata->sum)); PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd)); } @@ -8743,11 +8744,22 @@ mul_var(const NumericVar *var1, const NumericVar *var2, NumericVar *result, * Add the appropriate multiple of var2 into the accumulator. * * As above, digits of var2 can be ignored if they don't contribute, - * so we only include digits for which i1+i2+2 <= res_ndigits - 1. + * so we only include digits for which i1+i2+2 < res_ndigits. + * + * This inner loop is the performance bottleneck for multiplication, + * so we want to keep it simple enough so that it can be + * auto-vectorized. Accordingly, process the digits left-to-right + * even though schoolbook multiplication would suggest right-to-left. + * Since we aren't propagating carries in this loop, the order does + * not matter. */ - for (i2 = Min(var2ndigits - 1, res_ndigits - i1 - 3), i = i1 + i2 + 2; - i2 >= 0; i2--) - dig[i--] += var1digit * var2digits[i2]; + { + int i2limit = Min(var2ndigits, res_ndigits - i1 - 2); + int *dig_i1_2 = &dig[i1 + 2]; + + for (i2 = 0; i2 < i2limit; i2++) + dig_i1_2[i2] += var1digit * var2digits[i2]; + } } /* @@ -10761,7 +10773,7 @@ power_var_int(const NumericVar *base, int exp, NumericVar *result, int rscale) * to around log10(abs(exp)) digits, so work with this many extra digits * of precision (plus a few more for good measure). */ - sig_digits += (int) log(Abs(exp)) + 8; + sig_digits += (int) log(fabs((double) exp)) + 8; /* * Now we can proceed with the multiplications. diff --git a/src/backend/utils/adt/numutils.c b/src/backend/utils/adt/numutils.c index 412ae361d2c0..b93096f288f3 100644 --- a/src/backend/utils/adt/numutils.c +++ b/src/backend/utils/adt/numutils.c @@ -3,7 +3,7 @@ * numutils.c * utility functions for I/O of built-in numeric types. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c index 4ac691966247..fd94e0c88182 100644 --- a/src/backend/utils/adt/oid.c +++ b/src/backend/utils/adt/oid.c @@ -3,7 +3,7 @@ * oid.c * Functions for the built-in type Oid ... also oidvector. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c index 76e666474e84..f737aa6fbde7 100644 --- a/src/backend/utils/adt/oracle_compat.c +++ b/src/backend/utils/adt/oracle_compat.c @@ -2,7 +2,7 @@ * oracle_compat.c * Oracle compatible functions. * - * Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Copyright (c) 1996-2021, PostgreSQL Global Development Group * * Author: Edmund Mergl * Multibyte enhancement: Tatsuo Ishii @@ -24,6 +24,8 @@ static text *dotrim(const char *string, int stringlen, const char *set, int setlen, bool doltrim, bool dortrim); +static bytea *dobyteatrim(bytea *string, bytea *set, + bool doltrim, bool dortrim); /******************************************************************** @@ -521,27 +523,12 @@ dotrim(const char *string, int stringlen, return cstring_to_text_with_len(string, stringlen); } -/******************************************************************** - * - * byteatrim - * - * Syntax: - * - * bytea byteatrim(bytea string, bytea set) - * - * Purpose: - * - * Returns string with characters removed from the front and back - * up to the first character not in set. - * - * Cloned from btrim and modified as required. - ********************************************************************/ - -Datum -byteatrim(PG_FUNCTION_ARGS) +/* + * Common implementation for bytea versions of btrim, ltrim, rtrim + */ +bytea * +dobyteatrim(bytea *string, bytea *set, bool doltrim, bool dortrim) { - bytea *string = PG_GETARG_BYTEA_PP(0); - bytea *set = PG_GETARG_BYTEA_PP(1); bytea *ret; char *ptr, *end, @@ -556,7 +543,7 @@ byteatrim(PG_FUNCTION_ARGS) setlen = VARSIZE_ANY_EXHDR(set); if (stringlen <= 0 || setlen <= 0) - PG_RETURN_BYTEA_P(string); + return string; m = stringlen; ptr = VARDATA_ANY(string); @@ -564,39 +551,126 @@ byteatrim(PG_FUNCTION_ARGS) ptr2start = VARDATA_ANY(set); end2 = ptr2start + setlen - 1; - while (m > 0) + if (doltrim) { - ptr2 = ptr2start; - while (ptr2 <= end2) + while (m > 0) { - if (*ptr == *ptr2) + ptr2 = ptr2start; + while (ptr2 <= end2) + { + if (*ptr == *ptr2) + break; + ++ptr2; + } + if (ptr2 > end2) break; - ++ptr2; + ptr++; + m--; } - if (ptr2 > end2) - break; - ptr++; - m--; } - while (m > 0) + if (dortrim) { - ptr2 = ptr2start; - while (ptr2 <= end2) + while (m > 0) { - if (*end == *ptr2) + ptr2 = ptr2start; + while (ptr2 <= end2) + { + if (*end == *ptr2) + break; + ++ptr2; + } + if (ptr2 > end2) break; - ++ptr2; + end--; + m--; } - if (ptr2 > end2) - break; - end--; - m--; } ret = (bytea *) palloc(VARHDRSZ + m); SET_VARSIZE(ret, VARHDRSZ + m); memcpy(VARDATA(ret), ptr, m); + return ret; +} + +/******************************************************************** + * + * byteatrim + * + * Syntax: + * + * bytea byteatrim(bytea string, bytea set) + * + * Purpose: + * + * Returns string with characters removed from the front and back + * up to the first character not in set. + * + * Cloned from btrim and modified as required. + ********************************************************************/ + +Datum +byteatrim(PG_FUNCTION_ARGS) +{ + bytea *string = PG_GETARG_BYTEA_PP(0); + bytea *set = PG_GETARG_BYTEA_PP(1); + bytea *ret; + + ret = dobyteatrim(string, set, true, true); + + PG_RETURN_BYTEA_P(ret); +} + +/******************************************************************** + * + * bytealtrim + * + * Syntax: + * + * bytea bytealtrim(bytea string, bytea set) + * + * Purpose: + * + * Returns string with initial characters removed up to the first + * character not in set. + * + ********************************************************************/ + +Datum +bytealtrim(PG_FUNCTION_ARGS) +{ + bytea *string = PG_GETARG_BYTEA_PP(0); + bytea *set = PG_GETARG_BYTEA_PP(1); + bytea *ret; + + ret = dobyteatrim(string, set, true, false); + + PG_RETURN_BYTEA_P(ret); +} + +/******************************************************************** + * + * byteartrim + * + * Syntax: + * + * bytea byteartrim(bytea string, bytea set) + * + * Purpose: + * + * Returns string with final characters removed after the last + * character not in set. + * + ********************************************************************/ + +Datum +byteartrim(PG_FUNCTION_ARGS) +{ + bytea *string = PG_GETARG_BYTEA_PP(0); + bytea *set = PG_GETARG_BYTEA_PP(1); + bytea *ret; + + ret = dobyteatrim(string, set, false, true); PG_RETURN_BYTEA_P(ret); } diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c index 0167a6231e88..04ce69d11b94 100644 --- a/src/backend/utils/adt/orderedsetaggs.c +++ b/src/backend/utils/adt/orderedsetaggs.c @@ -3,7 +3,7 @@ * orderedsetaggs.c * Ordered-set aggregate functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c index c1120403fd98..03660d5db6c7 100644 --- a/src/backend/utils/adt/partitionfuncs.c +++ b/src/backend/utils/adt/partitionfuncs.c @@ -3,7 +3,7 @@ * partitionfuncs.c * Functions for accessing partition-related metadata * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 2b671801357d..113928915382 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -2,7 +2,7 @@ * * PostgreSQL locale utilities * - * Portions Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2002-2021, PostgreSQL Global Development Group * * src/backend/utils/adt/pg_locale.c * @@ -104,20 +104,6 @@ char *localized_full_months[12 + 1]; static bool CurrentLocaleConvValid = false; static bool CurrentLCTimeValid = false; -/* Environment variable storage area */ - -#define LC_ENV_BUFSIZE (NAMEDATALEN + 20) - -static char lc_collate_envbuf[LC_ENV_BUFSIZE]; -static char lc_ctype_envbuf[LC_ENV_BUFSIZE]; - -#ifdef LC_MESSAGES -static char lc_messages_envbuf[LC_ENV_BUFSIZE]; -#endif -static char lc_monetary_envbuf[LC_ENV_BUFSIZE]; -static char lc_numeric_envbuf[LC_ENV_BUFSIZE]; -static char lc_time_envbuf[LC_ENV_BUFSIZE]; - /* Cache for collation-related knowledge */ typedef struct @@ -159,7 +145,6 @@ pg_perm_setlocale(int category, const char *locale) { char *result; const char *envvar; - char *envbuf; #ifndef WIN32 result = setlocale(category, locale); @@ -195,7 +180,7 @@ pg_perm_setlocale(int category, const char *locale) */ if (category == LC_CTYPE) { - static char save_lc_ctype[LC_ENV_BUFSIZE]; + static char save_lc_ctype[NAMEDATALEN + 20]; /* copy setlocale() return value before callee invokes it again */ strlcpy(save_lc_ctype, result, sizeof(save_lc_ctype)); @@ -212,16 +197,13 @@ pg_perm_setlocale(int category, const char *locale) { case LC_COLLATE: envvar = "LC_COLLATE"; - envbuf = lc_collate_envbuf; break; case LC_CTYPE: envvar = "LC_CTYPE"; - envbuf = lc_ctype_envbuf; break; #ifdef LC_MESSAGES case LC_MESSAGES: envvar = "LC_MESSAGES"; - envbuf = lc_messages_envbuf; #ifdef WIN32 result = IsoLocaleName(locale); if (result == NULL) @@ -232,26 +214,19 @@ pg_perm_setlocale(int category, const char *locale) #endif /* LC_MESSAGES */ case LC_MONETARY: envvar = "LC_MONETARY"; - envbuf = lc_monetary_envbuf; break; case LC_NUMERIC: envvar = "LC_NUMERIC"; - envbuf = lc_numeric_envbuf; break; case LC_TIME: envvar = "LC_TIME"; - envbuf = lc_time_envbuf; break; default: elog(FATAL, "unrecognized LC category: %d", category); - envvar = NULL; /* keep compiler quiet */ - envbuf = NULL; - return NULL; + return NULL; /* keep compiler quiet */ } - snprintf(envbuf, LC_ENV_BUFSIZE - 1, "%s=%s", envvar, result); - - if (putenv(envbuf)) + if (setenv(envvar, result, 1) != 0) return NULL; return result; @@ -1293,7 +1268,6 @@ lookup_collation_cache(Oid collation, bool set_flags) /* First time through, initialize the hash table */ HASHCTL ctl; - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(collation_cache_entry); collation_cache = hash_create("Collation cache", 100, &ctl, @@ -1617,7 +1591,7 @@ pg_newlocale_from_collation(Oid collid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("ICU is not supported in this build"), \ - errhint("You need to rebuild PostgreSQL using --with-icu."))); + errhint("You need to rebuild PostgreSQL using %s.", "--with-icu"))); #endif /* not USE_ICU */ } @@ -1699,28 +1673,28 @@ get_collation_actual_version(char collprovider, const char *collcollate) } else #endif - if (collprovider == COLLPROVIDER_LIBC) + if (collprovider == COLLPROVIDER_LIBC && + pg_strcasecmp("C", collcollate) != 0 && + pg_strncasecmp("C.", collcollate, 2) != 0 && + pg_strcasecmp("POSIX", collcollate) != 0) { #if defined(__GLIBC__) - char *copy = pstrdup(collcollate); - char *copy_suffix = strstr(copy, "."); - bool need_version = true; - - /* - * Check for names like C.UTF-8 by chopping off the encoding suffix on - * our temporary copy, so we can skip the version. - */ - if (copy_suffix) - *copy_suffix = '\0'; - if (pg_strcasecmp("c", copy) == 0 || - pg_strcasecmp("posix", copy) == 0) - need_version = false; - pfree(copy); - if (!need_version) - return NULL; - /* Use the glibc version because we don't have anything better. */ collversion = pstrdup(gnu_get_libc_version()); +#elif defined(LC_VERSION_MASK) + locale_t loc; + + /* Look up FreeBSD collation version. */ + loc = newlocale(LC_COLLATE, collcollate, NULL); + if (loc) + { + collversion = + pstrdup(querylocale(LC_COLLATE_MASK | LC_VERSION_MASK, loc)); + freelocale(loc); + } + else + ereport(ERROR, + (errmsg("could not load locale \"%s\"", collcollate))); #elif defined(WIN32) && _WIN32_WINNT >= 0x0600 /* * If we are targeting Windows Vista and above, we can ask for a name @@ -1730,19 +1704,25 @@ get_collation_actual_version(char collprovider, const char *collcollate) NLSVERSIONINFOEX version = {sizeof(NLSVERSIONINFOEX)}; WCHAR wide_collcollate[LOCALE_NAME_MAX_LENGTH]; - /* These would be invalid arguments, but have no version. */ - if (pg_strcasecmp("c", collcollate) == 0 || - pg_strcasecmp("posix", collcollate) == 0) - return NULL; - - /* For all other names, ask the OS. */ MultiByteToWideChar(CP_ACP, 0, collcollate, -1, wide_collcollate, LOCALE_NAME_MAX_LENGTH); if (!GetNLSVersionEx(COMPARE_STRING, wide_collcollate, &version)) + { + /* + * GetNLSVersionEx() wants a language tag such as "en-US", not a + * locale name like "English_United States.1252". Until those + * values can be prevented from entering the system, or 100% + * reliably converted to the more useful tag format, tolerate the + * resulting error and report that we have no version data. + */ + if (GetLastError() == ERROR_INVALID_PARAMETER) + return NULL; + ereport(ERROR, (errmsg("could not get collation version for locale \"%s\": error code %lu", collcollate, GetLastError()))); + } collversion = psprintf("%d.%d,%d.%d", (version.dwNLSVersion >> 8) & 0xFFFF, version.dwNLSVersion & 0xFF, diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c index ad0a7bd869d1..b41dfe9eb0b5 100644 --- a/src/backend/utils/adt/pg_lsn.c +++ b/src/backend/utils/adt/pg_lsn.c @@ -3,7 +3,7 @@ * pg_lsn.c * Operations for the pg_lsn datatype. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -83,14 +83,8 @@ pg_lsn_out(PG_FUNCTION_ARGS) XLogRecPtr lsn = PG_GETARG_LSN(0); char buf[MAXPG_LSNLEN + 1]; char *result; - uint32 id, - off; - - /* Decode ID and offset */ - id = (uint32) (lsn >> 32); - off = (uint32) lsn; - snprintf(buf, sizeof buf, "%X/%X", id, off); + snprintf(buf, sizeof buf, "%X/%X", LSN_FORMAT_ARGS(lsn)); result = pstrdup(buf); PG_RETURN_CSTRING(result); } diff --git a/src/backend/utils/adt/pg_upgrade_support.c b/src/backend/utils/adt/pg_upgrade_support.c index 4b7e1b35abfc..57cc0facb6be 100644 --- a/src/backend/utils/adt/pg_upgrade_support.c +++ b/src/backend/utils/adt/pg_upgrade_support.c @@ -5,7 +5,7 @@ * to control oid and relfilenode assignment, and do other special * hacks needed for pg_upgrade. * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/backend/utils/adt/pg_upgrade_support.c */ @@ -66,6 +66,28 @@ binary_upgrade_set_next_array_pg_type_oid(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +Datum +binary_upgrade_set_next_multirange_pg_type_oid(PG_FUNCTION_ARGS) +{ + Oid typoid = PG_GETARG_OID(0); + + CHECK_IS_BINARY_UPGRADE; + binary_upgrade_next_mrng_pg_type_oid = typoid; + + PG_RETURN_VOID(); +} + +Datum +binary_upgrade_set_next_multirange_array_pg_type_oid(PG_FUNCTION_ARGS) +{ + Oid typoid = PG_GETARG_OID(0); + + CHECK_IS_BINARY_UPGRADE; + binary_upgrade_next_mrng_array_pg_type_oid = typoid; + + PG_RETURN_VOID(); +} + Datum binary_upgrade_set_next_heap_pg_class_oid(PG_FUNCTION_ARGS) { diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index a2c14ab2cf47..3a43381b0502 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -3,7 +3,7 @@ * pgstatfuncs.c * Functions for accessing the statistics collector data * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,6 +26,7 @@ #include "pgstat.h" #include "postmaster/bgworker_internals.h" #include "postmaster/postmaster.h" +#include "replication/slot.h" #include "storage/proc.h" #include "storage/procarray.h" #include "utils/acl.h" @@ -39,7 +40,7 @@ #define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var)))) -#define HAS_PGSTAT_PERMISSIONS(role) (is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role)) +#define HAS_PGSTAT_PERMISSIONS(role) (is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role)) /* Global bgwriter statistics, from bgwriter.c */ extern PgStat_MsgBgWriter bgwriterStats; @@ -500,6 +501,8 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) cmdtype = PROGRESS_COMMAND_CREATE_INDEX; else if (pg_strcasecmp(cmd, "BASEBACKUP") == 0) cmdtype = PROGRESS_COMMAND_BASEBACKUP; + else if (pg_strcasecmp(cmd, "COPY") == 0) + cmdtype = PROGRESS_COMMAND_COPY; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -712,7 +715,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) pfree(clipped_activity); /* leader_pid */ - nulls[29] = true; + nulls[28] = true; proc = BackendPidGetProc(beentry->st_procpid); if (proc != NULL) @@ -777,8 +780,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) */ if (leader && leader->pid != beentry->st_procpid) { - values[29] = Int32GetDatum(leader->pid); - nulls[29] = false; + values[28] = Int32GetDatum(leader->pid); + nulls[28] = false; } } @@ -907,46 +910,49 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version); values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher); values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits); - values[22] = BoolGetDatum(beentry->st_sslstatus->ssl_compression); if (beentry->st_sslstatus->ssl_client_dn[0]) - values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn); + values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn); else - nulls[23] = true; + nulls[22] = true; if (beentry->st_sslstatus->ssl_client_serial[0]) - values[24] = DirectFunctionCall3(numeric_in, + values[23] = DirectFunctionCall3(numeric_in, CStringGetDatum(beentry->st_sslstatus->ssl_client_serial), ObjectIdGetDatum(InvalidOid), Int32GetDatum(-1)); else - nulls[24] = true; + nulls[23] = true; if (beentry->st_sslstatus->ssl_issuer_dn[0]) - values[25] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn); + values[24] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn); else - nulls[25] = true; + nulls[24] = true; } else { values[18] = BoolGetDatum(false); /* ssl */ - nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = nulls[25] = true; + nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true; } /* GSSAPI information */ if (beentry->st_gss) { - values[26] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */ - values[27] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ); - values[28] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */ + values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */ + values[26] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ); + values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */ } else { - values[26] = BoolGetDatum(false); /* gss_auth */ - nulls[27] = true; /* No GSS principal */ - values[28] = BoolGetDatum(false); /* GSS Encryption not in + values[25] = BoolGetDatum(false); /* gss_auth */ + nulls[26] = true; /* No GSS principal */ + values[27] = BoolGetDatum(false); /* GSS Encryption not in * use */ } + if (beentry->st_query_id == 0) + nulls[29] = true; + else + values[29] = UInt64GetDatum(beentry->st_query_id); values[30] = Int32GetDatum(beentry->st_session_id); /* GPDB */ @@ -1690,6 +1696,100 @@ pg_stat_get_db_blk_write_time(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(result); } +Datum +pg_stat_get_db_session_time(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + double result = 0.0; + PgStat_StatDBEntry *dbentry; + + /* convert counter from microsec to millisec for display */ + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) != NULL) + result = ((double) dbentry->total_session_time) / 1000.0; + + PG_RETURN_FLOAT8(result); +} + +Datum +pg_stat_get_db_active_time(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + double result = 0.0; + PgStat_StatDBEntry *dbentry; + + /* convert counter from microsec to millisec for display */ + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) != NULL) + result = ((double) dbentry->total_active_time) / 1000.0; + + PG_RETURN_FLOAT8(result); +} + +Datum +pg_stat_get_db_idle_in_transaction_time(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + double result = 0.0; + PgStat_StatDBEntry *dbentry; + + /* convert counter from microsec to millisec for display */ + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) != NULL) + result = ((double) dbentry->total_idle_in_xact_time) / 1000.0; + + PG_RETURN_FLOAT8(result); +} + +Datum +pg_stat_get_db_sessions(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result = 0; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) != NULL) + result = (int64) (dbentry->n_sessions); + + PG_RETURN_INT64(result); +} + +Datum +pg_stat_get_db_sessions_abandoned(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result = 0; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) != NULL) + result = (int64) (dbentry->n_sessions_abandoned); + + PG_RETURN_INT64(result); +} + +Datum +pg_stat_get_db_sessions_fatal(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result = 0; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) != NULL) + result = (int64) (dbentry->n_sessions_fatal); + + PG_RETURN_INT64(result); +} + +Datum +pg_stat_get_db_sessions_killed(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result = 0; + PgStat_StatDBEntry *dbentry; + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) != NULL) + result = (int64) (dbentry->n_sessions_killed); + + PG_RETURN_INT64(result); +} + Datum pg_stat_get_bgwriter_timed_checkpoints(PG_FUNCTION_ARGS) { @@ -1758,6 +1858,74 @@ pg_stat_get_buf_alloc(PG_FUNCTION_ARGS) PG_RETURN_INT64(pgstat_fetch_global()->buf_alloc); } +/* + * Returns statistics of WAL activity + */ +Datum +pg_stat_get_wal(PG_FUNCTION_ARGS) +{ +#define PG_STAT_GET_WAL_COLS 9 + TupleDesc tupdesc; + Datum values[PG_STAT_GET_WAL_COLS]; + bool nulls[PG_STAT_GET_WAL_COLS]; + char buf[256]; + PgStat_WalStats *wal_stats; + + /* Initialise values and NULL flags arrays */ + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); + + /* Initialise attributes information in the tuple descriptor */ + tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_WAL_COLS); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "wal_records", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "wal_fpi", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "wal_bytes", + NUMERICOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "wal_buffers_full", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "wal_write", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 6, "wal_sync", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "wal_write_time", + FLOAT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 8, "wal_sync_time", + FLOAT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 9, "stats_reset", + TIMESTAMPTZOID, -1, 0); + + BlessTupleDesc(tupdesc); + + /* Get statistics about WAL activity */ + wal_stats = pgstat_fetch_stat_wal(); + + /* Fill values and NULLs */ + values[0] = Int64GetDatum(wal_stats->wal_records); + values[1] = Int64GetDatum(wal_stats->wal_fpi); + + /* Convert to numeric. */ + snprintf(buf, sizeof buf, UINT64_FORMAT, wal_stats->wal_bytes); + values[2] = DirectFunctionCall3(numeric_in, + CStringGetDatum(buf), + ObjectIdGetDatum(0), + Int32GetDatum(-1)); + + values[3] = Int64GetDatum(wal_stats->wal_buffers_full); + values[4] = Int64GetDatum(wal_stats->wal_write); + values[5] = Int64GetDatum(wal_stats->wal_sync); + + /* Convert counters from microsec to millisec for display */ + values[6] = Float8GetDatum(((double) wal_stats->wal_write_time) / 1000.0); + values[7] = Float8GetDatum(((double) wal_stats->wal_sync_time) / 1000.0); + + values[8] = TimestampTzGetDatum(wal_stats->stat_reset_timestamp); + + /* Returns the record as Datum */ + PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); +} + /* * Returns statistics of SLRU caches. */ @@ -2182,6 +2350,45 @@ pg_stat_reset_slru(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +/* Reset replication slots stats (a specific one or all of them). */ +Datum +pg_stat_reset_replication_slot(PG_FUNCTION_ARGS) +{ + char *target = NULL; + + if (!PG_ARGISNULL(0)) + { + ReplicationSlot *slot; + + target = text_to_cstring(PG_GETARG_TEXT_PP(0)); + + /* + * Check if the slot exists with the given name. It is possible that + * by the time this message is executed the slot is dropped but at + * least this check will ensure that the given name is for a valid + * slot. + */ + slot = SearchNamedReplicationSlot(target, true); + + if (!slot) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("replication slot \"%s\" does not exist", + target))); + + /* + * Nothing to do for physical slots as we collect stats only for + * logical slots. + */ + if (SlotIsPhysical(slot)) + PG_RETURN_VOID(); + } + + pgstat_reset_replslot_counter(target); + + PG_RETURN_VOID(); +} + Datum pg_stat_get_archiver(PG_FUNCTION_ARGS) { @@ -2247,3 +2454,78 @@ pg_stat_get_archiver(PG_FUNCTION_ARGS) /* Returns the record as Datum */ PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); } + +/* + * Get the statistics for the replication slot. If the slot statistics is not + * available, return all-zeroes stats. + */ +Datum +pg_stat_get_replication_slot(PG_FUNCTION_ARGS) +{ +#define PG_STAT_GET_REPLICATION_SLOT_COLS 10 + text *slotname_text = PG_GETARG_TEXT_P(0); + NameData slotname; + TupleDesc tupdesc; + Datum values[10]; + bool nulls[10]; + PgStat_StatReplSlotEntry *slotent; + PgStat_StatReplSlotEntry allzero; + + /* Initialise values and NULL flags arrays */ + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); + + /* Initialise attributes information in the tuple descriptor */ + tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_REPLICATION_SLOT_COLS); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "slot_name", + TEXTOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "spill_txns", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "spill_count", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "spill_bytes", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 5, "stream_txns", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stream_count", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stream_bytes", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 8, "total_txns", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 9, "total_bytes", + INT8OID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 10, "stats_reset", + TIMESTAMPTZOID, -1, 0); + BlessTupleDesc(tupdesc); + + namestrcpy(&slotname, text_to_cstring(slotname_text)); + slotent = pgstat_fetch_replslot(slotname); + if (!slotent) + { + /* + * If the slot is not found, initialise its stats. This is possible if + * the create slot message is lost. + */ + memset(&allzero, 0, sizeof(PgStat_StatReplSlotEntry)); + slotent = &allzero; + } + + values[0] = CStringGetTextDatum(NameStr(slotname)); + values[1] = Int64GetDatum(slotent->spill_txns); + values[2] = Int64GetDatum(slotent->spill_count); + values[3] = Int64GetDatum(slotent->spill_bytes); + values[4] = Int64GetDatum(slotent->stream_txns); + values[5] = Int64GetDatum(slotent->stream_count); + values[6] = Int64GetDatum(slotent->stream_bytes); + values[7] = Int64GetDatum(slotent->total_txns); + values[8] = Int64GetDatum(slotent->total_bytes); + + if (slotent->stat_reset_timestamp == 0) + nulls[9] = true; + else + values[9] = TimestampTzGetDatum(slotent->stat_reset_timestamp); + + /* Returns the record as Datum */ + PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); +} diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c index 460653a64f98..bc24a5399cf6 100644 --- a/src/backend/utils/adt/pseudotypes.c +++ b/src/backend/utils/adt/pseudotypes.c @@ -11,7 +11,7 @@ * we do better?) * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,6 +26,7 @@ #include "utils/array.h" #include "utils/builtins.h" #include "utils/rangetypes.h" +#include "utils/multirangetypes.h" /* @@ -227,6 +228,43 @@ anycompatiblerange_out(PG_FUNCTION_ARGS) return range_out(fcinfo); } +/* + * anycompatiblemultirange + * + * We may as well allow output, since multirange_out will in fact work. + */ +PSEUDOTYPE_DUMMY_INPUT_FUNC(anycompatiblemultirange); + +Datum +anycompatiblemultirange_out(PG_FUNCTION_ARGS) +{ + return multirange_out(fcinfo); +} + +/* + * anymultirange_in - input routine for pseudo-type ANYMULTIRANGE. + */ +Datum +anymultirange_in(PG_FUNCTION_ARGS) +{ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type %s", "anymultirange"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + +/* + * anymultirange_out - output routine for pseudo-type ANYMULTIRANGE. + * + * We may as well allow this, since multirange_out will in fact work. + */ +Datum +anymultirange_out(PG_FUNCTION_ARGS) +{ + return multirange_out(fcinfo); +} + /* * void * diff --git a/src/backend/utils/adt/quote.c b/src/backend/utils/adt/quote.c index 906bf329b8de..8de4eace9eda 100644 --- a/src/backend/utils/adt/quote.c +++ b/src/backend/utils/adt/quote.c @@ -3,7 +3,7 @@ * quote.c * Functions for quoting identifiers and literals * - * Portions Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2000-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c index 01ad8bc240b4..815175a654e3 100644 --- a/src/backend/utils/adt/rangetypes.c +++ b/src/backend/utils/adt/rangetypes.c @@ -19,7 +19,7 @@ * value; we must detoast it first. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -43,8 +43,6 @@ #include "utils/timestamp.h" -#define RANGE_EMPTY_LITERAL "empty" - /* fn_extra cache entry for one of the range I/O functions */ typedef struct RangeIOData { @@ -957,7 +955,25 @@ range_minus(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE_P(0); RangeType *r2 = PG_GETARG_RANGE_P(1); + RangeType *ret; TypeCacheEntry *typcache; + + /* Different types should be prevented by ANYRANGE matching rules */ + if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2)) + elog(ERROR, "range types do not match"); + + typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); + + ret = range_minus_internal(typcache, r1, r2); + if (ret) + PG_RETURN_RANGE_P(ret); + else + PG_RETURN_NULL(); +} + +RangeType * +range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2) +{ RangeBound lower1, lower2; RangeBound upper1, @@ -969,18 +985,12 @@ range_minus(PG_FUNCTION_ARGS) cmp_u1l2, cmp_u1u2; - /* Different types should be prevented by ANYRANGE matching rules */ - if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2)) - elog(ERROR, "range types do not match"); - - typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); - range_deserialize(typcache, r1, &lower1, &upper1, &empty1); range_deserialize(typcache, r2, &lower2, &upper2, &empty2); /* if either is empty, r1 is the correct answer */ if (empty1 || empty2) - PG_RETURN_RANGE_P(r1); + return r1; cmp_l1l2 = range_cmp_bounds(typcache, &lower1, &lower2); cmp_l1u2 = range_cmp_bounds(typcache, &lower1, &upper2); @@ -993,34 +1003,34 @@ range_minus(PG_FUNCTION_ARGS) errmsg("result of range difference would not be contiguous"))); if (cmp_l1u2 > 0 || cmp_u1l2 < 0) - PG_RETURN_RANGE_P(r1); + return r1; if (cmp_l1l2 >= 0 && cmp_u1u2 <= 0) - PG_RETURN_RANGE_P(make_empty_range(typcache)); + return make_empty_range(typcache); if (cmp_l1l2 <= 0 && cmp_u1l2 >= 0 && cmp_u1u2 <= 0) { lower2.inclusive = !lower2.inclusive; lower2.lower = false; /* it will become the upper bound */ - PG_RETURN_RANGE_P(make_range(typcache, &lower1, &lower2, false)); + return make_range(typcache, &lower1, &lower2, false); } if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0) { upper2.inclusive = !upper2.inclusive; upper2.lower = true; /* it will become the lower bound */ - PG_RETURN_RANGE_P(make_range(typcache, &upper2, &upper1, false)); + return make_range(typcache, &upper2, &upper1, false); } elog(ERROR, "unexpected case in range_minus"); - PG_RETURN_NULL(); + return NULL; } /* * Set union. If strict is true, it is an error that the two input ranges * are not adjacent or overlapping. */ -static RangeType * +RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict) { @@ -1101,6 +1111,19 @@ range_intersect(PG_FUNCTION_ARGS) RangeType *r1 = PG_GETARG_RANGE_P(0); RangeType *r2 = PG_GETARG_RANGE_P(1); TypeCacheEntry *typcache; + + /* Different types should be prevented by ANYRANGE matching rules */ + if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2)) + elog(ERROR, "range types do not match"); + + typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); + + PG_RETURN_RANGE_P(range_intersect_internal(typcache, r1, r2)); +} + +RangeType * +range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2) +{ RangeBound lower1, lower2; RangeBound upper1, @@ -1110,17 +1133,11 @@ range_intersect(PG_FUNCTION_ARGS) RangeBound *result_lower; RangeBound *result_upper; - /* Different types should be prevented by ANYRANGE matching rules */ - if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2)) - elog(ERROR, "range types do not match"); - - typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); - range_deserialize(typcache, r1, &lower1, &upper1, &empty1); range_deserialize(typcache, r2, &lower2, &upper2, &empty2); - if (empty1 || empty2 || !DatumGetBool(range_overlaps(fcinfo))) - PG_RETURN_RANGE_P(make_empty_range(typcache)); + if (empty1 || empty2 || !range_overlaps_internal(typcache, r1, r2)) + return make_empty_range(typcache); if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0) result_lower = &lower1; @@ -1132,9 +1149,81 @@ range_intersect(PG_FUNCTION_ARGS) else result_upper = &upper2; - PG_RETURN_RANGE_P(make_range(typcache, result_lower, result_upper, false)); + return make_range(typcache, result_lower, result_upper, false); } +/* range, range -> range, range functions */ + +/* + * range_split_internal - if r2 intersects the middle of r1, leaving non-empty + * ranges on both sides, then return true and set output1 and output2 to the + * results of r1 - r2 (in order). Otherwise return false and don't set output1 + * or output2. Neither input range should be empty. + */ +bool +range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, + RangeType **output1, RangeType **output2) +{ + RangeBound lower1, + lower2; + RangeBound upper1, + upper2; + bool empty1, + empty2; + + range_deserialize(typcache, r1, &lower1, &upper1, &empty1); + range_deserialize(typcache, r2, &lower2, &upper2, &empty2); + + if (range_cmp_bounds(typcache, &lower1, &lower2) < 0 && + range_cmp_bounds(typcache, &upper1, &upper2) > 0) + { + /* + * Need to invert inclusive/exclusive for the lower2 and upper2 + * points. They can't be infinite though. We're allowed to overwrite + * these RangeBounds since they only exist locally. + */ + lower2.inclusive = !lower2.inclusive; + lower2.lower = false; + upper2.inclusive = !upper2.inclusive; + upper2.lower = true; + + *output1 = make_range(typcache, &lower1, &lower2, false); + *output2 = make_range(typcache, &upper2, &upper1, false); + return true; + } + + return false; +} + +/* range -> range aggregate functions */ + +Datum +range_intersect_agg_transfn(PG_FUNCTION_ARGS) +{ + MemoryContext aggContext; + Oid rngtypoid; + TypeCacheEntry *typcache; + RangeType *result; + RangeType *current; + + if (!AggCheckCallContext(fcinfo, &aggContext)) + elog(ERROR, "range_intersect_agg_transfn called in non-aggregate context"); + + rngtypoid = get_fn_expr_argtype(fcinfo->flinfo, 1); + if (!type_is_range(rngtypoid)) + ereport(ERROR, (errmsg("range_intersect_agg must be called with a range"))); + + typcache = range_get_typcache(fcinfo, rngtypoid); + + /* strictness ensures these are non-null */ + result = PG_GETARG_RANGE_P(0); + current = PG_GETARG_RANGE_P(1); + + result = range_intersect_internal(typcache, result, current); + PG_RETURN_RANGE_P(result); +} + + /* Btree support */ /* btree comparator */ @@ -1937,6 +2026,46 @@ range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, b1->val, b2->val)); } +/* + * qsort callback for sorting ranges. + * + * Two empty ranges compare equal; an empty range sorts to the left of any + * non-empty range. Two non-empty ranges are sorted by lower bound first + * and by upper bound next. + */ +int +range_compare(const void *key1, const void *key2, void *arg) +{ + RangeType *r1 = *(RangeType **) key1; + RangeType *r2 = *(RangeType **) key2; + TypeCacheEntry *typcache = (TypeCacheEntry *) arg; + RangeBound lower1; + RangeBound upper1; + RangeBound lower2; + RangeBound upper2; + bool empty1; + bool empty2; + int cmp; + + range_deserialize(typcache, r1, &lower1, &upper1, &empty1); + range_deserialize(typcache, r2, &lower2, &upper2, &empty2); + + if (empty1 && empty2) + cmp = 0; + else if (empty1) + cmp = -1; + else if (empty2) + cmp = 1; + else + { + cmp = range_cmp_bounds(typcache, &lower1, &lower2); + if (cmp == 0) + cmp = range_cmp_bounds(typcache, &upper1, &upper2); + } + + return cmp; +} + /* * Build an empty range value of the type indicated by the typcache entry. */ diff --git a/src/backend/utils/adt/rangetypes_gist.c b/src/backend/utils/adt/rangetypes_gist.c index 75069c3ac2c8..69515b06782e 100644 --- a/src/backend/utils/adt/rangetypes_gist.c +++ b/src/backend/utils/adt/rangetypes_gist.c @@ -3,7 +3,7 @@ * rangetypes_gist.c * GiST support for range types. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,6 +19,7 @@ #include "utils/datum.h" #include "utils/float.h" #include "utils/fmgrprotos.h" +#include "utils/multirangetypes.h" #include "utils/rangetypes.h" /* @@ -135,12 +136,30 @@ typedef struct static RangeType *range_super_union(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2); -static bool range_gist_consistent_int(TypeCacheEntry *typcache, - StrategyNumber strategy, const RangeType *key, - Datum query); -static bool range_gist_consistent_leaf(TypeCacheEntry *typcache, - StrategyNumber strategy, const RangeType *key, - Datum query); +static bool range_gist_consistent_int_range(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const RangeType *query); +static bool range_gist_consistent_int_multirange(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const MultirangeType *query); +static bool range_gist_consistent_int_element(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + Datum query); +static bool range_gist_consistent_leaf_range(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const RangeType *query); +static bool range_gist_consistent_leaf_multirange(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const MultirangeType *query); +static bool range_gist_consistent_leaf_element(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + Datum query); static void range_gist_fallback_split(TypeCacheEntry *typcache, GistEntryVector *entryvec, GIST_SPLITVEC *v); @@ -174,8 +193,8 @@ range_gist_consistent(PG_FUNCTION_ARGS) GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); Datum query = PG_GETARG_DATUM(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - - /* Oid subtype = PG_GETARG_OID(3); */ + bool result; + Oid subtype = PG_GETARG_OID(3); bool *recheck = (bool *) PG_GETARG_POINTER(4); RangeType *key = DatumGetRangeTypeP(entry->key); TypeCacheEntry *typcache; @@ -185,12 +204,119 @@ range_gist_consistent(PG_FUNCTION_ARGS) typcache = range_get_typcache(fcinfo, RangeTypeGetOid(key)); + /* + * Perform consistent checking using function corresponding to key type + * (leaf or internal) and query subtype (range, multirange, or element). + * Note that invalid subtype means that query type matches key type + * (range). + */ if (GIST_LEAF(entry)) - PG_RETURN_BOOL(range_gist_consistent_leaf(typcache, strategy, - key, query)); + { + if (!OidIsValid(subtype) || subtype == ANYRANGEOID) + result = range_gist_consistent_leaf_range(typcache, strategy, key, + DatumGetRangeTypeP(query)); + else if (subtype == ANYMULTIRANGEOID) + result = range_gist_consistent_leaf_multirange(typcache, strategy, key, + DatumGetMultirangeTypeP(query)); + else + result = range_gist_consistent_leaf_element(typcache, strategy, + key, query); + } else - PG_RETURN_BOOL(range_gist_consistent_int(typcache, strategy, - key, query)); + { + if (!OidIsValid(subtype) || subtype == ANYRANGEOID) + result = range_gist_consistent_int_range(typcache, strategy, key, + DatumGetRangeTypeP(query)); + else if (subtype == ANYMULTIRANGEOID) + result = range_gist_consistent_int_multirange(typcache, strategy, key, + DatumGetMultirangeTypeP(query)); + else + result = range_gist_consistent_int_element(typcache, strategy, + key, query); + } + PG_RETURN_BOOL(result); +} + +/* + * GiST compress method for multiranges: multirange is approximated as union + * range with no gaps. + */ +Datum +multirange_gist_compress(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + + if (entry->leafkey) + { + MultirangeType *mr = DatumGetMultirangeTypeP(entry->key); + RangeType *r; + TypeCacheEntry *typcache; + GISTENTRY *retval = palloc(sizeof(GISTENTRY)); + + typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr)); + r = multirange_get_union_range(typcache->rngtype, mr); + + gistentryinit(*retval, RangeTypePGetDatum(r), + entry->rel, entry->page, entry->offset, false); + + PG_RETURN_POINTER(retval); + } + + PG_RETURN_POINTER(entry); +} + +/* GiST query consistency check for multiranges */ +Datum +multirange_gist_consistent(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + Datum query = PG_GETARG_DATUM(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + bool result; + Oid subtype = PG_GETARG_OID(3); + bool *recheck = (bool *) PG_GETARG_POINTER(4); + RangeType *key = DatumGetRangeTypeP(entry->key); + TypeCacheEntry *typcache; + + /* + * All operators served by this function are inexact because multirange is + * approximated by union range with no gaps. + */ + *recheck = true; + + typcache = range_get_typcache(fcinfo, RangeTypeGetOid(key)); + + /* + * Perform consistent checking using function corresponding to key type + * (leaf or internal) and query subtype (range, multirange, or element). + * Note that invalid subtype means that query type matches key type + * (multirange). + */ + if (GIST_LEAF(entry)) + { + if (!OidIsValid(subtype) || subtype == ANYMULTIRANGEOID) + result = range_gist_consistent_leaf_multirange(typcache, strategy, key, + DatumGetMultirangeTypeP(query)); + else if (subtype == ANYRANGEOID) + result = range_gist_consistent_leaf_range(typcache, strategy, key, + DatumGetRangeTypeP(query)); + else + result = range_gist_consistent_leaf_element(typcache, strategy, + key, query); + } + else + { + if (!OidIsValid(subtype) || subtype == ANYMULTIRANGEOID) + result = range_gist_consistent_int_multirange(typcache, strategy, key, + DatumGetMultirangeTypeP(query)); + else if (subtype == ANYRANGEOID) + result = range_gist_consistent_int_range(typcache, strategy, key, + DatumGetRangeTypeP(query)); + else + result = range_gist_consistent_int_element(typcache, strategy, + key, query); + } + PG_RETURN_BOOL(result); } /* form union range */ @@ -758,49 +884,67 @@ range_super_union(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2) return result; } +static bool +multirange_union_range_equal(TypeCacheEntry *typcache, + const RangeType *r, + const MultirangeType *mr) +{ + RangeBound lower1, + upper1, + lower2, + upper2, + tmp; + bool empty; + + if (RangeIsEmpty(r) || MultirangeIsEmpty(mr)) + return (RangeIsEmpty(r) && MultirangeIsEmpty(mr)); + + range_deserialize(typcache, r, &lower1, &upper1, &empty); + Assert(!empty); + multirange_get_bounds(typcache, mr, 0, &lower2, &tmp); + multirange_get_bounds(typcache, mr, mr->rangeCount - 1, &tmp, &upper2); + + return (range_cmp_bounds(typcache, &lower1, &lower2) == 0 && + range_cmp_bounds(typcache, &upper1, &upper2) == 0); +} + /* - * GiST consistent test on an index internal page + * GiST consistent test on an index internal page with range query */ static bool -range_gist_consistent_int(TypeCacheEntry *typcache, StrategyNumber strategy, - const RangeType *key, Datum query) +range_gist_consistent_int_range(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const RangeType *query) { switch (strategy) { case RANGESTRAT_BEFORE: - if (RangeIsEmpty(key) || RangeIsEmpty(DatumGetRangeTypeP(query))) + if (RangeIsEmpty(key) || RangeIsEmpty(query)) return false; - return (!range_overright_internal(typcache, key, - DatumGetRangeTypeP(query))); + return (!range_overright_internal(typcache, key, query)); case RANGESTRAT_OVERLEFT: - if (RangeIsEmpty(key) || RangeIsEmpty(DatumGetRangeTypeP(query))) + if (RangeIsEmpty(key) || RangeIsEmpty(query)) return false; - return (!range_after_internal(typcache, key, - DatumGetRangeTypeP(query))); + return (!range_after_internal(typcache, key, query)); case RANGESTRAT_OVERLAPS: - return range_overlaps_internal(typcache, key, - DatumGetRangeTypeP(query)); + return range_overlaps_internal(typcache, key, query); case RANGESTRAT_OVERRIGHT: - if (RangeIsEmpty(key) || RangeIsEmpty(DatumGetRangeTypeP(query))) + if (RangeIsEmpty(key) || RangeIsEmpty(query)) return false; - return (!range_before_internal(typcache, key, - DatumGetRangeTypeP(query))); + return (!range_before_internal(typcache, key, query)); case RANGESTRAT_AFTER: - if (RangeIsEmpty(key) || RangeIsEmpty(DatumGetRangeTypeP(query))) + if (RangeIsEmpty(key) || RangeIsEmpty(query)) return false; - return (!range_overleft_internal(typcache, key, - DatumGetRangeTypeP(query))); + return (!range_overleft_internal(typcache, key, query)); case RANGESTRAT_ADJACENT: - if (RangeIsEmpty(key) || RangeIsEmpty(DatumGetRangeTypeP(query))) + if (RangeIsEmpty(key) || RangeIsEmpty(query)) return false; - if (range_adjacent_internal(typcache, key, - DatumGetRangeTypeP(query))) + if (range_adjacent_internal(typcache, key, query)) return true; - return range_overlaps_internal(typcache, key, - DatumGetRangeTypeP(query)); + return range_overlaps_internal(typcache, key, query); case RANGESTRAT_CONTAINS: - return range_contains_internal(typcache, key, - DatumGetRangeTypeP(query)); + return range_contains_internal(typcache, key, query); case RANGESTRAT_CONTAINED_BY: /* @@ -810,20 +954,16 @@ range_gist_consistent_int(TypeCacheEntry *typcache, StrategyNumber strategy, */ if (RangeIsOrContainsEmpty(key)) return true; - return range_overlaps_internal(typcache, key, - DatumGetRangeTypeP(query)); - case RANGESTRAT_CONTAINS_ELEM: - return range_contains_elem_internal(typcache, key, query); + return range_overlaps_internal(typcache, key, query); case RANGESTRAT_EQ: /* * If query is empty, descend only if the key is or contains any * empty ranges. Otherwise, descend if key contains query. */ - if (RangeIsEmpty(DatumGetRangeTypeP(query))) + if (RangeIsEmpty(query)) return RangeIsOrContainsEmpty(key); - return range_contains_internal(typcache, key, - DatumGetRangeTypeP(query)); + return range_contains_internal(typcache, key, query); default: elog(ERROR, "unrecognized range strategy: %d", strategy); return false; /* keep compiler quiet */ @@ -831,42 +971,169 @@ range_gist_consistent_int(TypeCacheEntry *typcache, StrategyNumber strategy, } /* - * GiST consistent test on an index leaf page + * GiST consistent test on an index internal page with multirange query */ static bool -range_gist_consistent_leaf(TypeCacheEntry *typcache, StrategyNumber strategy, - const RangeType *key, Datum query) +range_gist_consistent_int_multirange(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const MultirangeType *query) { switch (strategy) { case RANGESTRAT_BEFORE: - return range_before_internal(typcache, key, - DatumGetRangeTypeP(query)); + if (RangeIsEmpty(key) || MultirangeIsEmpty(query)) + return false; + return (!range_overright_multirange_internal(typcache, key, query)); case RANGESTRAT_OVERLEFT: - return range_overleft_internal(typcache, key, - DatumGetRangeTypeP(query)); + if (RangeIsEmpty(key) || MultirangeIsEmpty(query)) + return false; + return (!range_after_multirange_internal(typcache, key, query)); case RANGESTRAT_OVERLAPS: - return range_overlaps_internal(typcache, key, - DatumGetRangeTypeP(query)); + return range_overlaps_multirange_internal(typcache, key, query); case RANGESTRAT_OVERRIGHT: - return range_overright_internal(typcache, key, - DatumGetRangeTypeP(query)); + if (RangeIsEmpty(key) || MultirangeIsEmpty(query)) + return false; + return (!range_before_multirange_internal(typcache, key, query)); case RANGESTRAT_AFTER: - return range_after_internal(typcache, key, - DatumGetRangeTypeP(query)); + if (RangeIsEmpty(key) || MultirangeIsEmpty(query)) + return false; + return (!range_overleft_multirange_internal(typcache, key, query)); case RANGESTRAT_ADJACENT: - return range_adjacent_internal(typcache, key, - DatumGetRangeTypeP(query)); + if (RangeIsEmpty(key) || MultirangeIsEmpty(query)) + return false; + if (range_adjacent_multirange_internal(typcache, key, query)) + return true; + return range_overlaps_multirange_internal(typcache, key, query); case RANGESTRAT_CONTAINS: - return range_contains_internal(typcache, key, - DatumGetRangeTypeP(query)); + return range_contains_multirange_internal(typcache, key, query); case RANGESTRAT_CONTAINED_BY: - return range_contained_by_internal(typcache, key, - DatumGetRangeTypeP(query)); + + /* + * Empty ranges are contained by anything, so if key is or + * contains any empty ranges, we must descend into it. Otherwise, + * descend only if key overlaps the query. + */ + if (RangeIsOrContainsEmpty(key)) + return true; + return range_overlaps_multirange_internal(typcache, key, query); + case RANGESTRAT_EQ: + + /* + * If query is empty, descend only if the key is or contains any + * empty ranges. Otherwise, descend if key contains query. + */ + if (MultirangeIsEmpty(query)) + return RangeIsOrContainsEmpty(key); + return range_contains_multirange_internal(typcache, key, query); + default: + elog(ERROR, "unrecognized range strategy: %d", strategy); + return false; /* keep compiler quiet */ + } +} + +/* + * GiST consistent test on an index internal page with element query + */ +static bool +range_gist_consistent_int_element(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + Datum query) +{ + switch (strategy) + { case RANGESTRAT_CONTAINS_ELEM: return range_contains_elem_internal(typcache, key, query); + default: + elog(ERROR, "unrecognized range strategy: %d", strategy); + return false; /* keep compiler quiet */ + } +} + +/* + * GiST consistent test on an index leaf page with range query + */ +static bool +range_gist_consistent_leaf_range(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const RangeType *query) +{ + switch (strategy) + { + case RANGESTRAT_BEFORE: + return range_before_internal(typcache, key, query); + case RANGESTRAT_OVERLEFT: + return range_overleft_internal(typcache, key, query); + case RANGESTRAT_OVERLAPS: + return range_overlaps_internal(typcache, key, query); + case RANGESTRAT_OVERRIGHT: + return range_overright_internal(typcache, key, query); + case RANGESTRAT_AFTER: + return range_after_internal(typcache, key, query); + case RANGESTRAT_ADJACENT: + return range_adjacent_internal(typcache, key, query); + case RANGESTRAT_CONTAINS: + return range_contains_internal(typcache, key, query); + case RANGESTRAT_CONTAINED_BY: + return range_contained_by_internal(typcache, key, query); + case RANGESTRAT_EQ: + return range_eq_internal(typcache, key, query); + default: + elog(ERROR, "unrecognized range strategy: %d", strategy); + return false; /* keep compiler quiet */ + } +} + +/* + * GiST consistent test on an index leaf page with multirange query + */ +static bool +range_gist_consistent_leaf_multirange(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + const MultirangeType *query) +{ + switch (strategy) + { + case RANGESTRAT_BEFORE: + return range_before_multirange_internal(typcache, key, query); + case RANGESTRAT_OVERLEFT: + return range_overleft_multirange_internal(typcache, key, query); + case RANGESTRAT_OVERLAPS: + return range_overlaps_multirange_internal(typcache, key, query); + case RANGESTRAT_OVERRIGHT: + return range_overright_multirange_internal(typcache, key, query); + case RANGESTRAT_AFTER: + return range_after_multirange_internal(typcache, key, query); + case RANGESTRAT_ADJACENT: + return range_adjacent_multirange_internal(typcache, key, query); + case RANGESTRAT_CONTAINS: + return range_contains_multirange_internal(typcache, key, query); + case RANGESTRAT_CONTAINED_BY: + return multirange_contains_range_internal(typcache, query, key); case RANGESTRAT_EQ: - return range_eq_internal(typcache, key, DatumGetRangeTypeP(query)); + return multirange_union_range_equal(typcache, key, query); + default: + elog(ERROR, "unrecognized range strategy: %d", strategy); + return false; /* keep compiler quiet */ + } +} + +/* + * GiST consistent test on an index leaf page with element query + */ +static bool +range_gist_consistent_leaf_element(TypeCacheEntry *typcache, + StrategyNumber strategy, + const RangeType *key, + Datum query) +{ + switch (strategy) + { + case RANGESTRAT_CONTAINS_ELEM: + return range_contains_elem_internal(typcache, key, query); default: elog(ERROR, "unrecognized range strategy: %d", strategy); return false; /* keep compiler quiet */ diff --git a/src/backend/utils/adt/rangetypes_selfuncs.c b/src/backend/utils/adt/rangetypes_selfuncs.c index 25dd84f4df62..a6c3c450ac9e 100644 --- a/src/backend/utils/adt/rangetypes_selfuncs.c +++ b/src/backend/utils/adt/rangetypes_selfuncs.c @@ -6,7 +6,7 @@ * Estimates are based on histograms of lower and upper bounds, and the * fraction of empty ranges. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/rangetypes_spgist.c b/src/backend/utils/adt/rangetypes_spgist.c index 9bbef531495c..f29de6aab488 100644 --- a/src/backend/utils/adt/rangetypes_spgist.c +++ b/src/backend/utils/adt/rangetypes_spgist.c @@ -25,7 +25,7 @@ * This implementation only uses the comparison function of the range element * datatype, therefore it works for any range type. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/adt/rangetypes_typanalyze.c b/src/backend/utils/adt/rangetypes_typanalyze.c index 603f303e0feb..0d01252cd7c7 100644 --- a/src/backend/utils/adt/rangetypes_typanalyze.c +++ b/src/backend/utils/adt/rangetypes_typanalyze.c @@ -13,7 +13,7 @@ * come from different tuples. In theory, the standard scalar selectivity * functions could be used with the combined histogram. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -30,11 +30,13 @@ #include "utils/fmgrprotos.h" #include "utils/lsyscache.h" #include "utils/rangetypes.h" +#include "utils/multirangetypes.h" static int float8_qsort_cmp(const void *a1, const void *a2); static int range_bound_qsort_cmp(const void *a1, const void *a2, void *arg); static void compute_range_stats(VacAttrStats *stats, - AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows); + AnalyzeAttrFetchFunc fetchfunc, int samplerows, + double totalrows); /* * range_typanalyze -- typanalyze function for range columns @@ -60,6 +62,33 @@ range_typanalyze(PG_FUNCTION_ARGS) PG_RETURN_BOOL(true); } +/* + * multirange_typanalyze -- typanalyze function for multirange columns + * + * We do the same analysis as for ranges, but on the smallest range that + * completely includes the multirange. + */ +Datum +multirange_typanalyze(PG_FUNCTION_ARGS) +{ + VacAttrStats *stats = (VacAttrStats *) PG_GETARG_POINTER(0); + TypeCacheEntry *typcache; + Form_pg_attribute attr = stats->attr; + + /* Get information about multirange type; note column might be a domain */ + typcache = multirange_get_typcache(fcinfo, getBaseType(stats->attrtypid)); + + if (attr->attstattarget < 0) + attr->attstattarget = default_statistics_target; + + stats->compute_stats = compute_range_stats; + stats->extra_data = typcache; + /* same as in std_typanalyze */ + stats->minrows = 300 * attr->attstattarget; + + PG_RETURN_BOOL(true); +} + /* * Comparison function for sorting float8s, used for range lengths. */ @@ -98,7 +127,8 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows) { TypeCacheEntry *typcache = (TypeCacheEntry *) stats->extra_data; - bool has_subdiff = OidIsValid(typcache->rng_subdiff_finfo.fn_oid); + TypeCacheEntry *mltrng_typcache = NULL; + bool has_subdiff; int null_cnt = 0; int non_null_cnt = 0; int non_empty_cnt = 0; @@ -112,6 +142,15 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, *uppers; double total_width = 0; + if (typcache->typtype == TYPTYPE_MULTIRANGE) + { + mltrng_typcache = typcache; + typcache = typcache->rngtype; + } + else + Assert(typcache->typtype == TYPTYPE_RANGE); + has_subdiff = OidIsValid(typcache->rng_subdiff_finfo.fn_oid); + /* Allocate memory to hold range bounds and lengths of the sample ranges. */ lowers = (RangeBound *) palloc(sizeof(RangeBound) * samplerows); uppers = (RangeBound *) palloc(sizeof(RangeBound) * samplerows); @@ -123,6 +162,7 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, Datum value; bool isnull, empty; + MultirangeType *multirange; RangeType *range; RangeBound lower, upper; @@ -145,8 +185,31 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, total_width += VARSIZE_ANY(DatumGetPointer(value)); /* Get range and deserialize it for further analysis. */ - range = DatumGetRangeTypeP(value); - range_deserialize(typcache, range, &lower, &upper, &empty); + if (mltrng_typcache != NULL) + { + /* Treat multiranges like a big range without gaps. */ + multirange = DatumGetMultirangeTypeP(value); + if (!MultirangeIsEmpty(multirange)) + { + RangeBound tmp; + + multirange_get_bounds(typcache, multirange, 0, + &lower, &tmp); + multirange_get_bounds(typcache, multirange, + multirange->rangeCount - 1, + &tmp, &upper); + empty = false; + } + else + { + empty = true; + } + } + else + { + range = DatumGetRangeTypeP(value); + range_deserialize(typcache, range, &lower, &upper, &empty); + } if (!empty) { @@ -262,6 +325,13 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, stats->stakind[slot_idx] = STATISTIC_KIND_BOUNDS_HISTOGRAM; stats->stavalues[slot_idx] = bound_hist_values; stats->numvalues[slot_idx] = num_hist; + + /* Store ranges even if we're analyzing a multirange column */ + stats->statypid[slot_idx] = typcache->type_id; + stats->statyplen[slot_idx] = typcache->typlen; + stats->statypbyval[slot_idx] = typcache->typbyval; + stats->statypalign[slot_idx] = typcache->typalign; + slot_idx++; } diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c index c70c5eeeb37f..a32c5c82ab43 100644 --- a/src/backend/utils/adt/regexp.c +++ b/src/backend/utils/adt/regexp.c @@ -3,7 +3,7 @@ * regexp.c * Postgres' interface to the regular expression package. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 6c1ee9c92df3..e4fb9d31d92a 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -8,7 +8,7 @@ * special I/O conversion routines. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -93,7 +93,7 @@ regprocin(PG_FUNCTION_ARGS) * pg_proc entries in the current search path. */ names = stringToQualifiedNameList(pro_name_or_oid); - clist = FuncnameGetCandidates(names, -1, NIL, false, false, false); + clist = FuncnameGetCandidates(names, -1, NIL, false, false, false, false); if (clist == NULL) ereport(ERROR, @@ -127,7 +127,7 @@ to_regproc(PG_FUNCTION_ARGS) * entries in the current search path. */ names = stringToQualifiedNameList(pro_name); - clist = FuncnameGetCandidates(names, -1, NIL, false, false, true); + clist = FuncnameGetCandidates(names, -1, NIL, false, false, false, true); if (clist == NULL || clist->next != NULL) PG_RETURN_NULL(); @@ -175,7 +175,7 @@ regprocout(PG_FUNCTION_ARGS) * qualify it. */ clist = FuncnameGetCandidates(list_make1(makeString(proname)), - -1, NIL, false, false, false); + -1, NIL, false, false, false, false); if (clist != NULL && clist->next == NULL && clist->oid == proid) nspname = NULL; @@ -262,7 +262,8 @@ regprocedurein(PG_FUNCTION_ARGS) */ parseNameAndArgTypes(pro_name_or_oid, false, &names, &nargs, argtypes); - clist = FuncnameGetCandidates(names, nargs, NIL, false, false, false); + clist = FuncnameGetCandidates(names, nargs, NIL, false, false, + false, false); for (; clist; clist = clist->next) { @@ -301,7 +302,7 @@ to_regprocedure(PG_FUNCTION_ARGS) */ parseNameAndArgTypes(pro_name, false, &names, &nargs, argtypes); - clist = FuncnameGetCandidates(names, nargs, NIL, false, false, true); + clist = FuncnameGetCandidates(names, nargs, NIL, false, false, false, true); for (; clist; clist = clist->next) { diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 06cf16d9d716..96269fc2adb6 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -14,7 +14,7 @@ * plan --- consider improving this someday. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * src/backend/utils/adt/ri_triggers.c * @@ -101,7 +101,10 @@ typedef struct RI_ConstraintInfo { Oid constraint_id; /* OID of pg_constraint entry (hash key) */ bool valid; /* successfully initialized? */ - uint32 oidHashValue; /* hash value of pg_constraint OID */ + Oid constraint_root_id; /* OID of topmost ancestor constraint; + * same as constraint_id if not inherited */ + uint32 oidHashValue; /* hash value of constraint_id */ + uint32 rootHashValue; /* hash value of constraint_root_id */ NameData conname; /* name of the FK constraint */ Oid pk_relid; /* referenced relation */ Oid fk_relid; /* referencing relation */ @@ -207,6 +210,7 @@ static void ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, static const RI_ConstraintInfo *ri_FetchConstraintInfo(Trigger *trigger, Relation trig_rel, bool rel_is_pk); static const RI_ConstraintInfo *ri_LoadConstraintInfo(Oid constraintOid); +static Oid get_ri_constraint_root(Oid constrOid); static SPIPlanPtr ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes, RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel); static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, @@ -388,11 +392,15 @@ RI_FKey_check(TriggerData *trigdata) /* * Now check that foreign key exists in PK table + * + * XXX detectNewRows must be true when a partitioned table is on the + * referenced side. The reason is that our snapshot must be fresh in + * order for the hack in find_inheritance_children() to work. */ ri_PerformCheck(riinfo, &qkey, qplan, fk_rel, pk_rel, NULL, newslot, - false, + pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE, SPI_OK_SELECT); if (SPI_finish() != SPI_OK_FINISH) @@ -1663,7 +1671,7 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) appendStringInfo(&querybuf, ") WHERE %s AND (", constraintDef); else - appendStringInfo(&querybuf, ") WHERE ("); + appendStringInfoString(&querybuf, ") WHERE ("); sep = ""; for (i = 0; i < riinfo->nkeys; i++) @@ -1892,7 +1900,7 @@ ri_GenerateQualCollation(StringInfo buf, Oid collation) * Construct a hashtable key for a prepared SPI plan of an FK constraint. * * key: output argument, *key is filled in based on the other arguments - * riinfo: info from pg_constraint entry + * riinfo: info derived from pg_constraint entry * constr_queryno: an internal number identifying the query type * (see RI_PLAN_XXX constants at head of file) * ---------- @@ -1902,10 +1910,27 @@ ri_BuildQueryKey(RI_QueryKey *key, const RI_ConstraintInfo *riinfo, int32 constr_queryno) { /* + * Inherited constraints with a common ancestor can share ri_query_cache + * entries for all query types except RI_PLAN_CHECK_LOOKUPPK_FROM_PK. + * Except in that case, the query processes the other table involved in + * the FK constraint (i.e., not the table on which the trigger has been + * fired), and so it will be the same for all members of the inheritance + * tree. So we may use the root constraint's OID in the hash key, rather + * than the constraint's own OID. This avoids creating duplicate SPI + * plans, saving lots of work and memory when there are many partitions + * with similar FK constraints. + * + * (Note that we must still have a separate RI_ConstraintInfo for each + * constraint, because partitions can have different column orders, + * resulting in different pk_attnums[] or fk_attnums[] array contents.) + * * We assume struct RI_QueryKey contains no padding bytes, else we'd need * to use memset to clear them. */ - key->constr_id = riinfo->constraint_id; + if (constr_queryno != RI_PLAN_CHECK_LOOKUPPK_FROM_PK) + key->constr_id = riinfo->constraint_root_id; + else + key->constr_id = riinfo->constraint_id; key->constr_queryno = constr_queryno; } @@ -2051,8 +2076,15 @@ ri_LoadConstraintInfo(Oid constraintOid) /* And extract data */ Assert(riinfo->constraint_id == constraintOid); + if (OidIsValid(conForm->conparentid)) + riinfo->constraint_root_id = + get_ri_constraint_root(conForm->conparentid); + else + riinfo->constraint_root_id = constraintOid; riinfo->oidHashValue = GetSysCacheHashValue1(CONSTROID, ObjectIdGetDatum(constraintOid)); + riinfo->rootHashValue = GetSysCacheHashValue1(CONSTROID, + ObjectIdGetDatum(riinfo->constraint_root_id)); memcpy(&riinfo->conname, &conForm->conname, sizeof(NameData)); riinfo->pk_relid = conForm->confrelid; riinfo->fk_relid = conForm->conrelid; @@ -2082,6 +2114,30 @@ ri_LoadConstraintInfo(Oid constraintOid) return riinfo; } +/* + * get_ri_constraint_root + * Returns the OID of the constraint's root parent + */ +static Oid +get_ri_constraint_root(Oid constrOid) +{ + for (;;) + { + HeapTuple tuple; + Oid constrParentOid; + + tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constrOid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for constraint %u", constrOid); + constrParentOid = ((Form_pg_constraint) GETSTRUCT(tuple))->conparentid; + ReleaseSysCache(tuple); + if (!OidIsValid(constrParentOid)) + break; /* we reached the root constraint */ + constrOid = constrParentOid; + } + return constrOid; +} + /* * Callback for pg_constraint inval events * @@ -2117,7 +2173,14 @@ InvalidateConstraintCacheCallBack(Datum arg, int cacheid, uint32 hashvalue) RI_ConstraintInfo *riinfo = dlist_container(RI_ConstraintInfo, valid_link, iter.cur); - if (hashvalue == 0 || riinfo->oidHashValue == hashvalue) + /* + * We must invalidate not only entries directly matching the given + * hash value, but also child entries, in case the invalidation + * affects a root constraint. + */ + if (hashvalue == 0 || + riinfo->oidHashValue == hashvalue || + riinfo->rootHashValue == hashvalue) { riinfo->valid = false; /* Remove invalidated entries from the list, too */ @@ -2130,9 +2193,6 @@ InvalidateConstraintCacheCallBack(Datum arg, int cacheid, uint32 hashvalue) /* * Prepare execution plan for a query to enforce an RI restriction - * - * If cache_plan is true, the plan is saved into our plan hashtable - * so that we don't need to plan it again. */ static SPIPlanPtr ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes, @@ -2543,7 +2603,6 @@ ri_InitHashTables(void) { HASHCTL ctl; - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RI_ConstraintInfo); ri_constraint_cache = hash_create("RI constraint cache", @@ -2555,14 +2614,12 @@ ri_InitHashTables(void) InvalidateConstraintCacheCallBack, (Datum) 0); - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(RI_QueryKey); ctl.entrysize = sizeof(RI_QueryHashEntry); ri_query_cache = hash_create("RI query cache", RI_INIT_QUERYHASHSIZE, &ctl, HASH_ELEM | HASH_BLOBS); - memset(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(RI_CompareKey); ctl.entrysize = sizeof(RI_CompareHashEntry); ri_compare_cache = hash_create("RI compare cache", diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c index f30d5eadc2d2..65771f2323b7 100644 --- a/src/backend/utils/adt/rowtypes.c +++ b/src/backend/utils/adt/rowtypes.c @@ -3,7 +3,7 @@ * rowtypes.c * I/O and comparison functions for generic composite types. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,6 +19,7 @@ #include "access/detoast.h" #include "access/htup_details.h" #include "catalog/pg_type.h" +#include "common/hashfn.h" #include "funcapi.h" #include "libpq/pqformat.h" #include "miscadmin.h" @@ -1784,3 +1785,251 @@ btrecordimagecmp(PG_FUNCTION_ARGS) { PG_RETURN_INT32(record_image_cmp(fcinfo)); } + + +/* + * Row type hash functions + */ + +Datum +hash_record(PG_FUNCTION_ARGS) +{ + HeapTupleHeader record = PG_GETARG_HEAPTUPLEHEADER(0); + uint32 result = 0; + Oid tupType; + int32 tupTypmod; + TupleDesc tupdesc; + HeapTupleData tuple; + int ncolumns; + RecordCompareData *my_extra; + Datum *values; + bool *nulls; + + check_stack_depth(); /* recurses for record-type columns */ + + /* Extract type info from tuple */ + tupType = HeapTupleHeaderGetTypeId(record); + tupTypmod = HeapTupleHeaderGetTypMod(record); + tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); + ncolumns = tupdesc->natts; + + /* Build temporary HeapTuple control structure */ + tuple.t_len = HeapTupleHeaderGetDatumLength(record); + ItemPointerSetInvalid(&(tuple.t_self)); + tuple.t_tableOid = InvalidOid; + tuple.t_data = record; + + /* + * We arrange to look up the needed hashing info just once per series of + * calls, assuming the record type doesn't change underneath us. + */ + my_extra = (RecordCompareData *) fcinfo->flinfo->fn_extra; + if (my_extra == NULL || + my_extra->ncolumns < ncolumns) + { + fcinfo->flinfo->fn_extra = + MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + offsetof(RecordCompareData, columns) + + ncolumns * sizeof(ColumnCompareData)); + my_extra = (RecordCompareData *) fcinfo->flinfo->fn_extra; + my_extra->ncolumns = ncolumns; + my_extra->record1_type = InvalidOid; + my_extra->record1_typmod = 0; + } + + if (my_extra->record1_type != tupType || + my_extra->record1_typmod != tupTypmod) + { + MemSet(my_extra->columns, 0, ncolumns * sizeof(ColumnCompareData)); + my_extra->record1_type = tupType; + my_extra->record1_typmod = tupTypmod; + } + + /* Break down the tuple into fields */ + values = (Datum *) palloc(ncolumns * sizeof(Datum)); + nulls = (bool *) palloc(ncolumns * sizeof(bool)); + heap_deform_tuple(&tuple, tupdesc, values, nulls); + + for (int i = 0; i < ncolumns; i++) + { + Form_pg_attribute att; + TypeCacheEntry *typentry; + uint32 element_hash; + + att = TupleDescAttr(tupdesc, i); + + if (att->attisdropped) + continue; + + /* + * Lookup the hash function if not done already + */ + typentry = my_extra->columns[i].typentry; + if (typentry == NULL || + typentry->type_id != att->atttypid) + { + typentry = lookup_type_cache(att->atttypid, + TYPECACHE_HASH_PROC_FINFO); + if (!OidIsValid(typentry->hash_proc_finfo.fn_oid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not identify a hash function for type %s", + format_type_be(typentry->type_id)))); + my_extra->columns[i].typentry = typentry; + } + + /* Compute hash of element */ + if (nulls[i]) + { + element_hash = 0; + } + else + { + LOCAL_FCINFO(locfcinfo, 1); + + InitFunctionCallInfoData(*locfcinfo, &typentry->hash_proc_finfo, 1, + att->attcollation, NULL, NULL); + locfcinfo->args[0].value = values[i]; + locfcinfo->args[0].isnull = false; + element_hash = DatumGetUInt32(FunctionCallInvoke(locfcinfo)); + + /* We don't expect hash support functions to return null */ + Assert(!locfcinfo->isnull); + } + + /* see hash_array() */ + result = (result << 5) - result + element_hash; + } + + pfree(values); + pfree(nulls); + ReleaseTupleDesc(tupdesc); + + /* Avoid leaking memory when handed toasted input. */ + PG_FREE_IF_COPY(record, 0); + + PG_RETURN_UINT32(result); +} + +Datum +hash_record_extended(PG_FUNCTION_ARGS) +{ + HeapTupleHeader record = PG_GETARG_HEAPTUPLEHEADER(0); + uint64 seed = PG_GETARG_INT64(1); + uint64 result = 0; + Oid tupType; + int32 tupTypmod; + TupleDesc tupdesc; + HeapTupleData tuple; + int ncolumns; + RecordCompareData *my_extra; + Datum *values; + bool *nulls; + + check_stack_depth(); /* recurses for record-type columns */ + + /* Extract type info from tuple */ + tupType = HeapTupleHeaderGetTypeId(record); + tupTypmod = HeapTupleHeaderGetTypMod(record); + tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); + ncolumns = tupdesc->natts; + + /* Build temporary HeapTuple control structure */ + tuple.t_len = HeapTupleHeaderGetDatumLength(record); + ItemPointerSetInvalid(&(tuple.t_self)); + tuple.t_tableOid = InvalidOid; + tuple.t_data = record; + + /* + * We arrange to look up the needed hashing info just once per series of + * calls, assuming the record type doesn't change underneath us. + */ + my_extra = (RecordCompareData *) fcinfo->flinfo->fn_extra; + if (my_extra == NULL || + my_extra->ncolumns < ncolumns) + { + fcinfo->flinfo->fn_extra = + MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + offsetof(RecordCompareData, columns) + + ncolumns * sizeof(ColumnCompareData)); + my_extra = (RecordCompareData *) fcinfo->flinfo->fn_extra; + my_extra->ncolumns = ncolumns; + my_extra->record1_type = InvalidOid; + my_extra->record1_typmod = 0; + } + + if (my_extra->record1_type != tupType || + my_extra->record1_typmod != tupTypmod) + { + MemSet(my_extra->columns, 0, ncolumns * sizeof(ColumnCompareData)); + my_extra->record1_type = tupType; + my_extra->record1_typmod = tupTypmod; + } + + /* Break down the tuple into fields */ + values = (Datum *) palloc(ncolumns * sizeof(Datum)); + nulls = (bool *) palloc(ncolumns * sizeof(bool)); + heap_deform_tuple(&tuple, tupdesc, values, nulls); + + for (int i = 0; i < ncolumns; i++) + { + Form_pg_attribute att; + TypeCacheEntry *typentry; + uint64 element_hash; + + att = TupleDescAttr(tupdesc, i); + + if (att->attisdropped) + continue; + + /* + * Lookup the hash function if not done already + */ + typentry = my_extra->columns[i].typentry; + if (typentry == NULL || + typentry->type_id != att->atttypid) + { + typentry = lookup_type_cache(att->atttypid, + TYPECACHE_HASH_EXTENDED_PROC_FINFO); + if (!OidIsValid(typentry->hash_extended_proc_finfo.fn_oid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not identify an extended hash function for type %s", + format_type_be(typentry->type_id)))); + my_extra->columns[i].typentry = typentry; + } + + /* Compute hash of element */ + if (nulls[i]) + { + element_hash = 0; + } + else + { + LOCAL_FCINFO(locfcinfo, 2); + + InitFunctionCallInfoData(*locfcinfo, &typentry->hash_extended_proc_finfo, 2, + att->attcollation, NULL, NULL); + locfcinfo->args[0].value = values[i]; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = Int64GetDatum(seed); + locfcinfo->args[0].isnull = false; + element_hash = DatumGetUInt64(FunctionCallInvoke(locfcinfo)); + + /* We don't expect hash support functions to return null */ + Assert(!locfcinfo->isnull); + } + + /* see hash_array_extended() */ + result = (result << 5) - result + element_hash; + } + + pfree(values); + pfree(nulls); + ReleaseTupleDesc(tupdesc); + + /* Avoid leaking memory when handed toasted input. */ + PG_FREE_IF_COPY(record, 0); + + PG_RETURN_UINT64(result); +} diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 810d93a4529a..adb7eb113588 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -4,7 +4,7 @@ * Functions to convert stored expressions/querytrees back to * source text * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,8 +24,6 @@ #include "access/relation.h" #include "access/sysattr.h" #include "access/table.h" -#include "catalog/dependency.h" -#include "catalog/indexing.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_am.h" #include "catalog/pg_authid.h" @@ -180,6 +178,10 @@ typedef struct List *outer_tlist; /* referent for OUTER_VAR Vars */ List *inner_tlist; /* referent for INNER_VAR Vars */ List *index_tlist; /* referent for INDEX_VAR Vars */ + /* Special namespace representing a function signature: */ + char *funcname; + int numargs; + char **argnames; } deparse_namespace; /* @@ -344,7 +346,8 @@ static char *pg_get_indexdef_worker(Oid indexrelid, int colno, bool attrsOnly, bool keysOnly, bool showTblSpc, bool inherits, int prettyFlags, bool missing_ok); -static char *pg_get_statisticsobj_worker(Oid statextid, bool missing_ok); +static char *pg_get_statisticsobj_worker(Oid statextid, bool columns_only, + bool missing_ok); static char *pg_get_partkeydef_worker(Oid relid, int prettyFlags, bool attrsOnly, bool missing_ok); static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, @@ -355,6 +358,7 @@ static int print_function_arguments(StringInfo buf, HeapTuple proctup, bool print_table_args, bool print_defaults); static void print_function_rettype(StringInfo buf, HeapTuple proctup); static void print_function_trftypes(StringInfo buf, HeapTuple proctup); +static void print_function_sqlbody(StringInfo buf, HeapTuple proctup); static void set_rtable_names(deparse_namespace *dpns, List *parent_namespaces, Bitmapset *rels_used); static void set_deparse_for_query(deparse_namespace *dpns, Query *query, @@ -449,6 +453,7 @@ static void get_agg_expr(Aggref *aggref, deparse_context *context, static void get_agg_combine_expr(Node *node, deparse_context *context, void *callback_arg); static void get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context); +static bool get_func_sql_syntax(FuncExpr *expr, deparse_context *context); static void get_coercion_expr(Node *arg, deparse_context *context, Oid resulttype, int32 resulttypmod, Node *parentNode); @@ -1514,7 +1519,36 @@ pg_get_statisticsobjdef(PG_FUNCTION_ARGS) Oid statextid = PG_GETARG_OID(0); char *res; - res = pg_get_statisticsobj_worker(statextid, true); + res = pg_get_statisticsobj_worker(statextid, false, true); + + if (res == NULL) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(string_to_text(res)); +} + +/* + * Internal version for use by ALTER TABLE. + * Includes a tablespace clause in the result. + * Returns a palloc'd C string; no pretty-printing. + */ +char * +pg_get_statisticsobjdef_string(Oid statextid) +{ + return pg_get_statisticsobj_worker(statextid, false, false); +} + +/* + * pg_get_statisticsobjdef_columns + * Get columns and expressions for an extended statistics object + */ +Datum +pg_get_statisticsobjdef_columns(PG_FUNCTION_ARGS) +{ + Oid statextid = PG_GETARG_OID(0); + char *res; + + res = pg_get_statisticsobj_worker(statextid, true, true); if (res == NULL) PG_RETURN_NULL(); @@ -1526,7 +1560,7 @@ pg_get_statisticsobjdef(PG_FUNCTION_ARGS) * Internal workhorse to decompile an extended statistics object. */ static char * -pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) +pg_get_statisticsobj_worker(Oid statextid, bool columns_only, bool missing_ok) { Form_pg_statistic_ext statextrec; HeapTuple statexttup; @@ -1541,6 +1575,11 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) bool dependencies_enabled; bool mcv_enabled; int i; + List *context; + ListCell *lc; + List *exprs = NIL; + bool has_exprs; + int ncolumns; statexttup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statextid)); @@ -1551,75 +1590,114 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) elog(ERROR, "cache lookup failed for statistics object %u", statextid); } - statextrec = (Form_pg_statistic_ext) GETSTRUCT(statexttup); - - initStringInfo(&buf); + /* has the statistics expressions? */ + has_exprs = !heap_attisnull(statexttup, Anum_pg_statistic_ext_stxexprs, NULL); - nsp = get_namespace_name(statextrec->stxnamespace); - appendStringInfo(&buf, "CREATE STATISTICS %s", - quote_qualified_identifier(nsp, - NameStr(statextrec->stxname))); + statextrec = (Form_pg_statistic_ext) GETSTRUCT(statexttup); /* - * Decode the stxkind column so that we know which stats types to print. + * Get the statistics expressions, if any. (NOTE: we do not use the + * relcache versions of the expressions, because we want to display + * non-const-folded expressions.) */ - datum = SysCacheGetAttr(STATEXTOID, statexttup, - Anum_pg_statistic_ext_stxkind, &isnull); - Assert(!isnull); - arr = DatumGetArrayTypeP(datum); - if (ARR_NDIM(arr) != 1 || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != CHAROID) - elog(ERROR, "stxkind is not a 1-D char array"); - enabled = (char *) ARR_DATA_PTR(arr); - - ndistinct_enabled = false; - dependencies_enabled = false; - mcv_enabled = false; - - for (i = 0; i < ARR_DIMS(arr)[0]; i++) + if (has_exprs) { - if (enabled[i] == STATS_EXT_NDISTINCT) - ndistinct_enabled = true; - if (enabled[i] == STATS_EXT_DEPENDENCIES) - dependencies_enabled = true; - if (enabled[i] == STATS_EXT_MCV) - mcv_enabled = true; + Datum exprsDatum; + bool isnull; + char *exprsString; + + exprsDatum = SysCacheGetAttr(STATEXTOID, statexttup, + Anum_pg_statistic_ext_stxexprs, &isnull); + Assert(!isnull); + exprsString = TextDatumGetCString(exprsDatum); + exprs = (List *) stringToNode(exprsString); + pfree(exprsString); } + else + exprs = NIL; - /* - * If any option is disabled, then we'll need to append the types clause - * to show which options are enabled. We omit the types clause on purpose - * when all options are enabled, so a pg_dump/pg_restore will create all - * statistics types on a newer postgres version, if the statistics had all - * options enabled on the original version. - */ - if (!ndistinct_enabled || !dependencies_enabled || !mcv_enabled) + /* count the number of columns (attributes and expressions) */ + ncolumns = statextrec->stxkeys.dim1 + list_length(exprs); + + initStringInfo(&buf); + + if (!columns_only) { - bool gotone = false; + nsp = get_namespace_name(statextrec->stxnamespace); + appendStringInfo(&buf, "CREATE STATISTICS %s", + quote_qualified_identifier(nsp, + NameStr(statextrec->stxname))); - appendStringInfoString(&buf, " ("); + /* + * Decode the stxkind column so that we know which stats types to + * print. + */ + datum = SysCacheGetAttr(STATEXTOID, statexttup, + Anum_pg_statistic_ext_stxkind, &isnull); + Assert(!isnull); + arr = DatumGetArrayTypeP(datum); + if (ARR_NDIM(arr) != 1 || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != CHAROID) + elog(ERROR, "stxkind is not a 1-D char array"); + enabled = (char *) ARR_DATA_PTR(arr); + + ndistinct_enabled = false; + dependencies_enabled = false; + mcv_enabled = false; - if (ndistinct_enabled) + for (i = 0; i < ARR_DIMS(arr)[0]; i++) { - appendStringInfoString(&buf, "ndistinct"); - gotone = true; + if (enabled[i] == STATS_EXT_NDISTINCT) + ndistinct_enabled = true; + else if (enabled[i] == STATS_EXT_DEPENDENCIES) + dependencies_enabled = true; + else if (enabled[i] == STATS_EXT_MCV) + mcv_enabled = true; + + /* ignore STATS_EXT_EXPRESSIONS (it's built automatically) */ } - if (dependencies_enabled) + /* + * If any option is disabled, then we'll need to append the types + * clause to show which options are enabled. We omit the types clause + * on purpose when all options are enabled, so a pg_dump/pg_restore + * will create all statistics types on a newer postgres version, if + * the statistics had all options enabled on the original version. + * + * But if the statistics is defined on just a single column, it has to + * be an expression statistics. In that case we don't need to specify + * kinds. + */ + if ((!ndistinct_enabled || !dependencies_enabled || !mcv_enabled) && + (ncolumns > 1)) { - appendStringInfo(&buf, "%sdependencies", gotone ? ", " : ""); - gotone = true; - } + bool gotone = false; - if (mcv_enabled) - appendStringInfo(&buf, "%smcv", gotone ? ", " : ""); + appendStringInfoString(&buf, " ("); - appendStringInfoChar(&buf, ')'); - } + if (ndistinct_enabled) + { + appendStringInfoString(&buf, "ndistinct"); + gotone = true; + } + + if (dependencies_enabled) + { + appendStringInfo(&buf, "%sdependencies", gotone ? ", " : ""); + gotone = true; + } + + if (mcv_enabled) + appendStringInfo(&buf, "%smcv", gotone ? ", " : ""); + + appendStringInfoChar(&buf, ')'); + } - appendStringInfoString(&buf, " ON "); + appendStringInfoString(&buf, " ON "); + } + /* decode simple column references */ for (colno = 0; colno < statextrec->stxkeys.dim1; colno++) { AttrNumber attnum = statextrec->stxkeys.values[colno]; @@ -1633,14 +1711,109 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) appendStringInfoString(&buf, quote_identifier(attname)); } - appendStringInfo(&buf, " FROM %s", - generate_relation_name(statextrec->stxrelid, NIL)); + context = deparse_context_for(get_relation_name(statextrec->stxrelid), + statextrec->stxrelid); + + foreach(lc, exprs) + { + Node *expr = (Node *) lfirst(lc); + char *str; + int prettyFlags = PRETTYFLAG_INDENT; + + str = deparse_expression_pretty(expr, context, false, false, + prettyFlags, 0); + + if (colno > 0) + appendStringInfoString(&buf, ", "); + + /* Need parens if it's not a bare function call */ + if (looks_like_function(expr)) + appendStringInfoString(&buf, str); + else + appendStringInfo(&buf, "(%s)", str); + + colno++; + } + + if (!columns_only) + appendStringInfo(&buf, " FROM %s", + generate_relation_name(statextrec->stxrelid, NIL)); ReleaseSysCache(statexttup); return buf.data; } +/* + * Generate text array of expressions for statistics object. + */ +Datum +pg_get_statisticsobjdef_expressions(PG_FUNCTION_ARGS) +{ + Oid statextid = PG_GETARG_OID(0); + Form_pg_statistic_ext statextrec; + HeapTuple statexttup; + Datum datum; + bool isnull; + List *context; + ListCell *lc; + List *exprs = NIL; + bool has_exprs; + char *tmp; + ArrayBuildState *astate = NULL; + + statexttup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statextid)); + + if (!HeapTupleIsValid(statexttup)) + PG_RETURN_NULL(); + + /* Does the stats object have expressions? */ + has_exprs = !heap_attisnull(statexttup, Anum_pg_statistic_ext_stxexprs, NULL); + + /* no expressions? we're done */ + if (!has_exprs) + { + ReleaseSysCache(statexttup); + PG_RETURN_NULL(); + } + + statextrec = (Form_pg_statistic_ext) GETSTRUCT(statexttup); + + /* + * Get the statistics expressions, and deparse them into text values. + */ + datum = SysCacheGetAttr(STATEXTOID, statexttup, + Anum_pg_statistic_ext_stxexprs, &isnull); + + Assert(!isnull); + tmp = TextDatumGetCString(datum); + exprs = (List *) stringToNode(tmp); + pfree(tmp); + + context = deparse_context_for(get_relation_name(statextrec->stxrelid), + statextrec->stxrelid); + + foreach(lc, exprs) + { + Node *expr = (Node *) lfirst(lc); + char *str; + int prettyFlags = PRETTYFLAG_INDENT; + + str = deparse_expression_pretty(expr, context, false, false, + prettyFlags, 0); + + astate = accumArrayResult(astate, + PointerGetDatum(cstring_to_text(str)), + false, + TEXTOID, + CurrentMemoryContext); + } + + ReleaseSysCache(statexttup); + + PG_RETURN_DATUM(makeArrayResult(astate, CurrentMemoryContext)); +} + /* * pg_get_partkeydef * @@ -2153,7 +2326,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, appendStringInfoChar(&buf, ')'); - indexId = get_constraint_index(constraintId); + indexId = conForm->conindid; /* Build including column list (from pg_index.indkeys) */ indtup = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId)); @@ -2813,37 +2986,46 @@ pg_get_functiondef(PG_FUNCTION_ARGS) } /* And finally the function definition ... */ - appendStringInfoString(&buf, "AS "); - - tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_probin, &isnull); - if (!isnull) + tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosqlbody, &isnull); + if (proc->prolang == SQLlanguageId && !isnull) { - simple_quote_literal(&buf, TextDatumGetCString(tmp)); - appendStringInfoString(&buf, ", "); /* assume prosrc isn't null */ + print_function_sqlbody(&buf, proctup); } + else + { + appendStringInfoString(&buf, "AS "); - tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull); - if (isnull) - elog(ERROR, "null prosrc"); - prosrc = TextDatumGetCString(tmp); + tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_probin, &isnull); + if (!isnull) + { + simple_quote_literal(&buf, TextDatumGetCString(tmp)); + appendStringInfoString(&buf, ", "); /* assume prosrc isn't null */ + } - /* - * We always use dollar quoting. Figure out a suitable delimiter. - * - * Since the user is likely to be editing the function body string, we - * shouldn't use a short delimiter that he might easily create a conflict - * with. Hence prefer "$function$"/"$procedure$", but extend if needed. - */ - initStringInfo(&dq); - appendStringInfoChar(&dq, '$'); - appendStringInfoString(&dq, (isfunction ? "function" : "procedure")); - while (strstr(prosrc, dq.data) != NULL) - appendStringInfoChar(&dq, 'x'); - appendStringInfoChar(&dq, '$'); + tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull); + if (isnull) + elog(ERROR, "null prosrc"); + prosrc = TextDatumGetCString(tmp); - appendBinaryStringInfo(&buf, dq.data, dq.len); - appendStringInfoString(&buf, prosrc); - appendBinaryStringInfo(&buf, dq.data, dq.len); + /* + * We always use dollar quoting. Figure out a suitable delimiter. + * + * Since the user is likely to be editing the function body string, we + * shouldn't use a short delimiter that he might easily create a + * conflict with. Hence prefer "$function$"/"$procedure$", but extend + * if needed. + */ + initStringInfo(&dq); + appendStringInfoChar(&dq, '$'); + appendStringInfoString(&dq, (isfunction ? "function" : "procedure")); + while (strstr(prosrc, dq.data) != NULL) + appendStringInfoChar(&dq, 'x'); + appendStringInfoChar(&dq, '$'); + + appendBinaryStringInfo(&buf, dq.data, dq.len); + appendStringInfoString(&buf, prosrc); + appendBinaryStringInfo(&buf, dq.data, dq.len); + } appendStringInfoChar(&buf, '\n'); @@ -3048,7 +3230,15 @@ print_function_arguments(StringInfo buf, HeapTuple proctup, switch (argmode) { case PROARGMODE_IN: - modename = ""; + + /* + * For procedures, explicitly mark all argument modes, so as + * to avoid ambiguity with the SQL syntax for DROP PROCEDURE. + */ + if (proc->prokind == PROKIND_PROCEDURE) + modename = "IN "; + else + modename = ""; isinput = true; break; case PROARGMODE_INOUT: @@ -3140,13 +3330,14 @@ print_function_trftypes(StringInfo buf, HeapTuple proctup) { int i; - appendStringInfoString(buf, "\n TRANSFORM "); + appendStringInfoString(buf, " TRANSFORM "); for (i = 0; i < ntypes; i++) { if (i != 0) appendStringInfoString(buf, ", "); appendStringInfo(buf, "FOR TYPE %s", format_type_be(trftypes[i])); } + appendStringInfoChar(buf, '\n'); } } @@ -3226,6 +3417,83 @@ pg_get_function_arg_default(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(string_to_text(str)); } +static void +print_function_sqlbody(StringInfo buf, HeapTuple proctup) +{ + int numargs; + Oid *argtypes; + char **argnames; + char *argmodes; + deparse_namespace dpns = {0}; + Datum tmp; + bool isnull; + Node *n; + + dpns.funcname = pstrdup(NameStr(((Form_pg_proc) GETSTRUCT(proctup))->proname)); + numargs = get_func_arg_info(proctup, + &argtypes, &argnames, &argmodes); + dpns.numargs = numargs; + dpns.argnames = argnames; + + tmp = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosqlbody, &isnull); + Assert(!isnull); + n = stringToNode(TextDatumGetCString(tmp)); + + if (IsA(n, List)) + { + List *stmts; + ListCell *lc; + + stmts = linitial(castNode(List, n)); + + appendStringInfoString(buf, "BEGIN ATOMIC\n"); + + foreach(lc, stmts) + { + Query *query = lfirst_node(Query, lc); + + get_query_def(query, buf, list_make1(&dpns), NULL, PRETTYFLAG_INDENT, WRAP_COLUMN_DEFAULT, 1); + appendStringInfoChar(buf, ';'); + appendStringInfoChar(buf, '\n'); + } + + appendStringInfoString(buf, "END"); + } + else + { + get_query_def(castNode(Query, n), buf, list_make1(&dpns), NULL, 0, WRAP_COLUMN_DEFAULT, 0); + } +} + +Datum +pg_get_function_sqlbody(PG_FUNCTION_ARGS) +{ + Oid funcid = PG_GETARG_OID(0); + StringInfoData buf; + HeapTuple proctup; + bool isnull; + + initStringInfo(&buf); + + /* Look up the function */ + proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); + if (!HeapTupleIsValid(proctup)) + PG_RETURN_NULL(); + + SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosqlbody, &isnull); + if (isnull) + { + ReleaseSysCache(proctup); + PG_RETURN_NULL(); + } + + print_function_sqlbody(&buf, proctup); + + ReleaseSysCache(proctup); + + PG_RETURN_TEXT_P(cstring_to_text(buf.data)); +} + /* * deparse_expression - General utility for deparsing expressions @@ -3479,14 +3747,14 @@ set_rtable_names(deparse_namespace *dpns, List *parent_namespaces, * We use a hash table to hold known names, so that this process is O(N) * not O(N^2) for N names. */ - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = NAMEDATALEN; hash_ctl.entrysize = sizeof(NameHashEntry); hash_ctl.hcxt = CurrentMemoryContext; names_hash = hash_create("set_rtable_names names", list_length(dpns->rtable), &hash_ctl, - HASH_ELEM | HASH_CONTEXT); + HASH_ELEM | HASH_STRINGS | HASH_CONTEXT); + /* Preload the hash table with names appearing in parent_namespaces */ foreach(lc, parent_namespaces) { @@ -4586,9 +4854,7 @@ set_deparse_plan(deparse_namespace *dpns, Plan *plan) * We special-case Append and MergeAppend to pretend that the first child * plan is the OUTER referent; we have to interpret OUTER Vars in their * tlists according to one of the children, and the first one is the most - * natural choice. Likewise special-case ModifyTable to pretend that the - * first child plan is the OUTER referent; this is to support RETURNING - * lists containing references to non-target relations. + * natural choice. */ if (IsA(plan, Append)) dpns->outer_plan = linitial(((Append *) plan)->appendplans); @@ -4606,8 +4872,6 @@ set_deparse_plan(deparse_namespace *dpns, Plan *plan) } else if (IsA(plan, MergeAppend)) dpns->outer_plan = linitial(((MergeAppend *) plan)->mergeplans); - else if (IsA(plan, ModifyTable)) - dpns->outer_plan = linitial(((ModifyTable *) plan)->plans); else dpns->outer_plan = outerPlan(plan); @@ -4771,7 +5035,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, bool is_instead; char *ev_qual; char *ev_action; - List *actions = NIL; + List *actions; Relation ev_relation; TupleDesc viewResultDesc = NULL; int fno; @@ -4801,14 +5065,16 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, Assert(!isnull); is_instead = DatumGetBool(dat); - /* these could be nulls */ fno = SPI_fnumber(rulettc, "ev_qual"); ev_qual = SPI_getvalue(ruletup, rulettc, fno); + Assert(ev_qual != NULL); fno = SPI_fnumber(rulettc, "ev_action"); ev_action = SPI_getvalue(ruletup, rulettc, fno); - if (ev_action != NULL) - actions = (List *) stringToNode(ev_action); + Assert(ev_action != NULL); + actions = (List *) stringToNode(ev_action); + if (actions == NIL) + elog(ERROR, "invalid empty ev_action list"); ev_relation = table_open(ev_class, AccessShareLock); @@ -4858,9 +5124,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, generate_qualified_relation_name(ev_class)); /* If the rule has an event qualification, add it */ - if (ev_qual == NULL) - ev_qual = ""; - if (strlen(ev_qual) > 0 && strcmp(ev_qual, "<>") != 0) + if (strcmp(ev_qual, "<>") != 0) { Node *qual; Query *query; @@ -4932,10 +5196,6 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, } appendStringInfoString(buf, ");"); } - else if (list_length(actions) == 0) - { - appendStringInfoString(buf, "NOTHING;"); - } else { Query *query; @@ -4965,7 +5225,7 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, bool is_instead; char *ev_qual; char *ev_action; - List *actions = NIL; + List *actions; Relation ev_relation; int fno; Datum dat; @@ -4989,14 +5249,14 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, Assert(!isnull); is_instead = DatumGetBool(dat); - /* these could be nulls */ fno = SPI_fnumber(rulettc, "ev_qual"); ev_qual = SPI_getvalue(ruletup, rulettc, fno); + Assert(ev_qual != NULL); fno = SPI_fnumber(rulettc, "ev_action"); ev_action = SPI_getvalue(ruletup, rulettc, fno); - if (ev_action != NULL) - actions = (List *) stringToNode(ev_action); + Assert(ev_action != NULL); + actions = (List *) stringToNode(ev_action); if (list_length(actions) != 1) { @@ -5221,6 +5481,64 @@ get_with_clause(Query *query, deparse_context *context) if (PRETTY_INDENT(context)) appendContextKeyword(context, "", 0, 0, 0); appendStringInfoChar(buf, ')'); + + if (cte->search_clause) + { + bool first = true; + ListCell *lc; + + appendStringInfo(buf, " SEARCH %s FIRST BY ", + cte->search_clause->search_breadth_first ? "BREADTH" : "DEPTH"); + + foreach(lc, cte->search_clause->search_col_list) + { + if (first) + first = false; + else + appendStringInfoString(buf, ", "); + appendStringInfoString(buf, + quote_identifier(strVal(lfirst(lc)))); + } + + appendStringInfo(buf, " SET %s", quote_identifier(cte->search_clause->search_seq_column)); + } + + if (cte->cycle_clause) + { + bool first = true; + ListCell *lc; + + appendStringInfoString(buf, " CYCLE "); + + foreach(lc, cte->cycle_clause->cycle_col_list) + { + if (first) + first = false; + else + appendStringInfoString(buf, ", "); + appendStringInfoString(buf, + quote_identifier(strVal(lfirst(lc)))); + } + + appendStringInfo(buf, " SET %s", quote_identifier(cte->cycle_clause->cycle_mark_column)); + + { + Const *cmv = castNode(Const, cte->cycle_clause->cycle_mark_value); + Const *cmd = castNode(Const, cte->cycle_clause->cycle_mark_default); + + if (!(cmv->consttype == BOOLOID && !cmv->constisnull && DatumGetBool(cmv->constvalue) == true && + cmd->consttype == BOOLOID && !cmd->constisnull && DatumGetBool(cmd->constvalue) == false)) + { + appendStringInfoString(buf, " TO "); + get_rule_expr(cte->cycle_clause->cycle_mark_value, context, false); + appendStringInfoString(buf, " DEFAULT "); + get_rule_expr(cte->cycle_clause->cycle_mark_default, context, false); + } + } + + appendStringInfo(buf, " USING %s", quote_identifier(cte->cycle_clause->cycle_path_column)); + } + sep = ", "; } @@ -5302,7 +5620,7 @@ get_select_query_def(Query *query, deparse_context *context, appendContextKeyword(context, " FETCH FIRST ", -PRETTYINDENT_STD, PRETTYINDENT_STD, 0); get_rule_expr(query->limitCount, context, false); - appendStringInfo(buf, " ROWS WITH TIES"); + appendStringInfoString(buf, " ROWS WITH TIES"); } else { @@ -5499,7 +5817,10 @@ get_basic_select_query(Query *query, deparse_context *context, /* * Build up the query string - first we say SELECT */ - appendStringInfoString(buf, "SELECT"); + if (query->isReturn) + appendStringInfoString(buf, "RETURN"); + else + appendStringInfoString(buf, "SELECT"); /* Add the DISTINCT clause if given */ if (query->distinctClause != NIL) @@ -5544,6 +5865,8 @@ get_basic_select_query(Query *query, deparse_context *context, appendContextKeyword(context, " GROUP BY ", -PRETTYINDENT_STD, PRETTYINDENT_STD, 1); + if (query->groupDistinct) + appendStringInfoString(buf, "DISTINCT "); save_exprkind = context->special_exprkind; context->special_exprkind = EXPR_KIND_GROUP_BY; @@ -7630,6 +7953,50 @@ get_parameter(Param *param, deparse_context *context) return; } + /* + * If it's an external parameter, see if the outermost namespace provides + * function argument names. + */ + if (param->paramkind == PARAM_EXTERN) + { + dpns = lfirst(list_tail(context->namespaces)); + if (dpns->argnames) + { + char *argname = dpns->argnames[param->paramid - 1]; + + if (argname) + { + bool should_qualify = false; + ListCell *lc; + + /* + * Qualify the parameter name if there are any other deparse + * namespaces with range tables. This avoids qualifying in + * trivial cases like "RETURN a + b", but makes it safe in all + * other cases. + */ + foreach(lc, context->namespaces) + { + deparse_namespace *dpns = lfirst(lc); + + if (list_length(dpns->rtable_names) > 0) + { + should_qualify = true; + break; + } + } + if (should_qualify) + { + appendStringInfoString(context->buf, quote_identifier(dpns->funcname)); + appendStringInfoChar(context->buf, '.'); + } + + appendStringInfoString(context->buf, quote_identifier(argname)); + return; + } + } + } + /* * Not PARAM_EXEC, or couldn't find referent: just print $N. */ @@ -8202,7 +8569,7 @@ get_rule_expr(Node *node, deparse_context *context, { BoolExpr *expr = (BoolExpr *) node; Node *first_arg = linitial(expr->args); - ListCell *arg = list_second_cell(expr->args); + ListCell *arg; switch (expr->boolop) { @@ -8211,12 +8578,11 @@ get_rule_expr(Node *node, deparse_context *context, appendStringInfoChar(buf, '('); get_rule_expr_paren(first_arg, context, false, node); - while (arg) + for_each_from(arg, expr->args, 1) { appendStringInfoString(buf, " AND "); get_rule_expr_paren((Node *) lfirst(arg), context, false, node); - arg = lnext(expr->args, arg); } if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, ')'); @@ -8227,12 +8593,11 @@ get_rule_expr(Node *node, deparse_context *context, appendStringInfoChar(buf, '('); get_rule_expr_paren(first_arg, context, false, node); - while (arg) + for_each_from(arg, expr->args, 1) { appendStringInfoString(buf, " OR "); get_rule_expr_paren((Node *) lfirst(arg), context, false, node); - arg = lnext(expr->args, arg); } if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, ')'); @@ -8281,7 +8646,12 @@ get_rule_expr(Node *node, deparse_context *context, AlternativeSubPlan *asplan = (AlternativeSubPlan *) node; ListCell *lc; - /* As above, this can only happen during EXPLAIN */ + /* + * This case cannot be reached in normal usage, since no + * AlternativeSubPlan can appear either in parsetrees or + * finished plan trees. We keep it just in case somebody + * wants to use this code to print planner data structures. + */ appendStringInfoString(buf, "(alternatives: "); foreach(lc, asplan->subplans) { @@ -9462,7 +9832,8 @@ looks_like_function(Node *node) { case T_FuncExpr: /* OK, unless it's going to deparse as a cast */ - return (((FuncExpr *) node)->funcformat == COERCE_EXPLICIT_CALL); + return (((FuncExpr *) node)->funcformat == COERCE_EXPLICIT_CALL || + ((FuncExpr *) node)->funcformat == COERCE_SQL_SYNTAX); case T_NullIfExpr: case T_CoalesceExpr: case T_MinMaxExpr: @@ -9504,35 +9875,14 @@ get_oper_expr(OpExpr *expr, deparse_context *context) } else { - /* unary operator --- but which side? */ + /* prefix operator */ Node *arg = (Node *) linitial(args); - HeapTuple tp; - Form_pg_operator optup; - - tp = SearchSysCache1(OPEROID, ObjectIdGetDatum(opno)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for operator %u", opno); - optup = (Form_pg_operator) GETSTRUCT(tp); - switch (optup->oprkind) - { - case 'l': - appendStringInfo(buf, "%s ", - generate_operator_name(opno, - InvalidOid, - exprType(arg))); - get_rule_expr_paren(arg, context, true, (Node *) expr); - break; - case 'r': - get_rule_expr_paren(arg, context, true, (Node *) expr); - appendStringInfo(buf, " %s", - generate_operator_name(opno, - exprType(arg), - InvalidOid)); - break; - default: - elog(ERROR, "bogus oprkind: %d", optup->oprkind); - } - ReleaseSysCache(tp); + + appendStringInfo(buf, "%s ", + generate_operator_name(opno, + InvalidOid, + exprType(arg))); + get_rule_expr_paren(arg, context, true, (Node *) expr); } if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, ')'); @@ -9585,6 +9935,17 @@ get_func_expr(FuncExpr *expr, deparse_context *context, return; } + /* + * If the function was called using one of the SQL spec's random special + * syntaxes, try to reproduce that. If we don't recognize the function, + * fall through. + */ + if (expr->funcformat == COERCE_SQL_SYNTAX) + { + if (get_func_sql_syntax(expr, context)) + return; + } + /* * Normal function: display as proname(args). First we need to extract * the argument datatypes. @@ -9903,6 +10264,246 @@ get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context) } } +/* + * get_func_sql_syntax - Parse back a SQL-syntax function call + * + * Returns true if we successfully deparsed, false if we did not + * recognize the function. + */ +static bool +get_func_sql_syntax(FuncExpr *expr, deparse_context *context) +{ + StringInfo buf = context->buf; + Oid funcoid = expr->funcid; + + switch (funcoid) + { + case F_TIMEZONE_INTERVAL_TIMESTAMP: + case F_TIMEZONE_INTERVAL_TIMESTAMPTZ: + case F_TIMEZONE_INTERVAL_TIMETZ: + case F_TIMEZONE_TEXT_TIMESTAMP: + case F_TIMEZONE_TEXT_TIMESTAMPTZ: + case F_TIMEZONE_TEXT_TIMETZ: + /* AT TIME ZONE ... note reversed argument order */ + appendStringInfoChar(buf, '('); + get_rule_expr((Node *) lsecond(expr->args), context, false); + appendStringInfoString(buf, " AT TIME ZONE "); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoChar(buf, ')'); + return true; + + case F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_INTERVAL: + case F_OVERLAPS_TIMESTAMPTZ_INTERVAL_TIMESTAMPTZ_TIMESTAMPTZ: + case F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_INTERVAL: + case F_OVERLAPS_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ_TIMESTAMPTZ: + case F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_INTERVAL: + case F_OVERLAPS_TIMESTAMP_INTERVAL_TIMESTAMP_TIMESTAMP: + case F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_INTERVAL: + case F_OVERLAPS_TIMESTAMP_TIMESTAMP_TIMESTAMP_TIMESTAMP: + case F_OVERLAPS_TIMETZ_TIMETZ_TIMETZ_TIMETZ: + case F_OVERLAPS_TIME_INTERVAL_TIME_INTERVAL: + case F_OVERLAPS_TIME_INTERVAL_TIME_TIME: + case F_OVERLAPS_TIME_TIME_TIME_INTERVAL: + case F_OVERLAPS_TIME_TIME_TIME_TIME: + /* (x1, x2) OVERLAPS (y1, y2) */ + appendStringInfoString(buf, "(("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoString(buf, ", "); + get_rule_expr((Node *) lsecond(expr->args), context, false); + appendStringInfoString(buf, ") OVERLAPS ("); + get_rule_expr((Node *) lthird(expr->args), context, false); + appendStringInfoString(buf, ", "); + get_rule_expr((Node *) lfourth(expr->args), context, false); + appendStringInfoString(buf, "))"); + return true; + + case F_EXTRACT_TEXT_DATE: + case F_EXTRACT_TEXT_TIME: + case F_EXTRACT_TEXT_TIMETZ: + case F_EXTRACT_TEXT_TIMESTAMP: + case F_EXTRACT_TEXT_TIMESTAMPTZ: + case F_EXTRACT_TEXT_INTERVAL: + /* EXTRACT (x FROM y) */ + appendStringInfoString(buf, "EXTRACT("); + { + Const *con = (Const *) linitial(expr->args); + + Assert(IsA(con, Const) && + con->consttype == TEXTOID && + !con->constisnull); + appendStringInfoString(buf, TextDatumGetCString(con->constvalue)); + } + appendStringInfoString(buf, " FROM "); + get_rule_expr((Node *) lsecond(expr->args), context, false); + appendStringInfoChar(buf, ')'); + return true; + + case F_IS_NORMALIZED: + /* IS xxx NORMALIZED */ + appendStringInfoString(buf, "(("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoString(buf, ") IS"); + if (list_length(expr->args) == 2) + { + Const *con = (Const *) lsecond(expr->args); + + Assert(IsA(con, Const) && + con->consttype == TEXTOID && + !con->constisnull); + appendStringInfo(buf, " %s", + TextDatumGetCString(con->constvalue)); + } + appendStringInfoString(buf, " NORMALIZED)"); + return true; + + case F_PG_COLLATION_FOR: + /* COLLATION FOR */ + appendStringInfoString(buf, "COLLATION FOR ("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoChar(buf, ')'); + return true; + + /* + * XXX EXTRACT, a/k/a date_part(), is intentionally not covered + * yet. Add it after we change the return type to numeric. + */ + + case F_NORMALIZE: + /* NORMALIZE() */ + appendStringInfoString(buf, "NORMALIZE("); + get_rule_expr((Node *) linitial(expr->args), context, false); + if (list_length(expr->args) == 2) + { + Const *con = (Const *) lsecond(expr->args); + + Assert(IsA(con, Const) && + con->consttype == TEXTOID && + !con->constisnull); + appendStringInfo(buf, ", %s", + TextDatumGetCString(con->constvalue)); + } + appendStringInfoChar(buf, ')'); + return true; + + case F_OVERLAY_BIT_BIT_INT4: + case F_OVERLAY_BIT_BIT_INT4_INT4: + case F_OVERLAY_BYTEA_BYTEA_INT4: + case F_OVERLAY_BYTEA_BYTEA_INT4_INT4: + case F_OVERLAY_TEXT_TEXT_INT4: + case F_OVERLAY_TEXT_TEXT_INT4_INT4: + /* OVERLAY() */ + appendStringInfoString(buf, "OVERLAY("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoString(buf, " PLACING "); + get_rule_expr((Node *) lsecond(expr->args), context, false); + appendStringInfoString(buf, " FROM "); + get_rule_expr((Node *) lthird(expr->args), context, false); + if (list_length(expr->args) == 4) + { + appendStringInfoString(buf, " FOR "); + get_rule_expr((Node *) lfourth(expr->args), context, false); + } + appendStringInfoChar(buf, ')'); + return true; + + case F_POSITION_BIT_BIT: + case F_POSITION_BYTEA_BYTEA: + case F_POSITION_TEXT_TEXT: + /* POSITION() ... extra parens since args are b_expr not a_expr */ + appendStringInfoString(buf, "POSITION(("); + get_rule_expr((Node *) lsecond(expr->args), context, false); + appendStringInfoString(buf, ") IN ("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoString(buf, "))"); + return true; + + case F_SUBSTRING_BIT_INT4: + case F_SUBSTRING_BIT_INT4_INT4: + case F_SUBSTRING_BYTEA_INT4: + case F_SUBSTRING_BYTEA_INT4_INT4: + case F_SUBSTRING_TEXT_INT4: + case F_SUBSTRING_TEXT_INT4_INT4: + /* SUBSTRING FROM/FOR (i.e., integer-position variants) */ + appendStringInfoString(buf, "SUBSTRING("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoString(buf, " FROM "); + get_rule_expr((Node *) lsecond(expr->args), context, false); + if (list_length(expr->args) == 3) + { + appendStringInfoString(buf, " FOR "); + get_rule_expr((Node *) lthird(expr->args), context, false); + } + appendStringInfoChar(buf, ')'); + return true; + + case F_SUBSTRING_TEXT_TEXT_TEXT: + /* SUBSTRING SIMILAR/ESCAPE */ + appendStringInfoString(buf, "SUBSTRING("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoString(buf, " SIMILAR "); + get_rule_expr((Node *) lsecond(expr->args), context, false); + appendStringInfoString(buf, " ESCAPE "); + get_rule_expr((Node *) lthird(expr->args), context, false); + appendStringInfoChar(buf, ')'); + return true; + + case F_BTRIM_BYTEA_BYTEA: + case F_BTRIM_TEXT: + case F_BTRIM_TEXT_TEXT: + /* TRIM() */ + appendStringInfoString(buf, "TRIM(BOTH"); + if (list_length(expr->args) == 2) + { + appendStringInfoChar(buf, ' '); + get_rule_expr((Node *) lsecond(expr->args), context, false); + } + appendStringInfoString(buf, " FROM "); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoChar(buf, ')'); + return true; + + case F_LTRIM_BYTEA_BYTEA: + case F_LTRIM_TEXT: + case F_LTRIM_TEXT_TEXT: + /* TRIM() */ + appendStringInfoString(buf, "TRIM(LEADING"); + if (list_length(expr->args) == 2) + { + appendStringInfoChar(buf, ' '); + get_rule_expr((Node *) lsecond(expr->args), context, false); + } + appendStringInfoString(buf, " FROM "); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoChar(buf, ')'); + return true; + + case F_RTRIM_BYTEA_BYTEA: + case F_RTRIM_TEXT: + case F_RTRIM_TEXT_TEXT: + /* TRIM() */ + appendStringInfoString(buf, "TRIM(TRAILING"); + if (list_length(expr->args) == 2) + { + appendStringInfoChar(buf, ' '); + get_rule_expr((Node *) lsecond(expr->args), context, false); + } + appendStringInfoString(buf, " FROM "); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoChar(buf, ')'); + return true; + + case F_XMLEXISTS: + /* XMLEXISTS ... extra parens because args are c_expr */ + appendStringInfoString(buf, "XMLEXISTS(("); + get_rule_expr((Node *) linitial(expr->args), context, false); + appendStringInfoString(buf, ") PASSING ("); + get_rule_expr((Node *) lsecond(expr->args), context, false); + appendStringInfoString(buf, "))"); + return true; + } + return false; +} + /* ---------- * get_coercion_expr * @@ -10562,7 +11163,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); if (!IsA(rtfunc->funcexpr, FuncExpr) || - ((FuncExpr *) rtfunc->funcexpr)->funcid != F_ARRAY_UNNEST || + ((FuncExpr *) rtfunc->funcexpr)->funcid != F_UNNEST_ANYARRAY || rtfunc->funccolnames != NIL) { all_unnest = false; @@ -10775,6 +11376,10 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) appendStringInfoString(buf, quote_identifier(colname)); } appendStringInfoChar(buf, ')'); + + if (j->join_using_alias) + appendStringInfo(buf, " AS %s", + quote_identifier(j->join_using_alias->aliasname)); } else if (j->quals) { @@ -11473,7 +12078,7 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes, if (!force_qualify) p_result = func_get_detail(list_make1(makeString(proname)), NIL, argnames, nargs, argtypes, - !use_variadic, true, + !use_variadic, true, false, &p_funcid, &p_rettype, &p_retset, &p_nvargs, &p_vatype, &p_true_typeids, NULL); @@ -11542,10 +12147,6 @@ generate_operator_name(Oid operid, Oid arg1, Oid arg2) p_result = left_oper(NULL, list_make1(makeString(oprname)), arg2, true, -1); break; - case 'r': - p_result = right_oper(NULL, list_make1(makeString(oprname)), arg1, - true, -1); - break; default: elog(ERROR, "unrecognized oprkind: %d", operform->oprkind); p_result = NULL; /* keep compiler quiet */ @@ -11933,7 +12534,7 @@ get_range_partbound_string(List *bound_datums) memset(&context, 0, sizeof(deparse_context)); context.buf = buf; - appendStringInfoString(buf, "("); + appendStringInfoChar(buf, '('); sep = ""; foreach(cell, bound_datums) { diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index f90450730ced..9e4c162a9ff4 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -12,7 +12,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -657,7 +657,7 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, /* * The calculation so far gave us a selectivity for the "<=" case. - * We'll have one less tuple for "<" and one additional tuple for + * We'll have one fewer tuple for "<" and one additional tuple for * ">=", the latter of which we'll reverse the selectivity for * below, so we can simply subtract one tuple for both cases. The * cases that need this adjustment can be identified by iseq being @@ -2239,7 +2239,7 @@ rowcomparesel(PlannerInfo *root, /* * Otherwise, it's a join if there's more than one relation used. */ - is_join_clause = (NumRelids((Node *) opargs) > 1); + is_join_clause = (NumRelids(root, (Node *) opargs) > 1); } if (is_join_clause) @@ -3279,6 +3279,7 @@ typedef struct Node *var; /* might be an expression, not just a Var */ RelOptInfo *rel; /* relation it belongs to */ double ndistinct; /* # distinct values */ + bool isdefault; /* true if DEFAULT_NUM_DISTINCT was used */ } GroupVarInfo; static List * @@ -3325,6 +3326,7 @@ add_unique_group_var(PlannerInfo *root, List *varinfos, varinfo->var = var; varinfo->rel = vardata->rel; varinfo->ndistinct = ndistinct; + varinfo->isdefault = isdefault; varinfos = lappend(varinfos, varinfo); return varinfos; } @@ -3349,6 +3351,12 @@ add_unique_group_var(PlannerInfo *root, List *varinfos, * pgset - NULL, or a List** pointing to a grouping set to filter the * groupExprs against * + * Outputs: + * estinfo - When passed as non-NULL, the function will set bits in the + * "flags" field in order to provide callers with additional information + * about the estimation. Currently, we only set the SELFLAG_USED_DEFAULT + * bit if we used any default values in the estimation. + * * Given the lack of any cross-correlation statistics in the system, it's * impossible to do anything really trustworthy with GROUP BY conditions * involving multiple Vars. We should however avoid assuming the worst @@ -3396,7 +3404,7 @@ add_unique_group_var(PlannerInfo *root, List *varinfos, */ double estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, - List **pgset) + List **pgset, EstimationInfo *estinfo) { List *varinfos = NIL; double srf_multiplier = 1.0; @@ -3404,6 +3412,10 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, ListCell *l; int i; + /* Zero the estinfo output parameter, if non-NULL */ + if (estinfo != NULL) + memset(estinfo, 0, sizeof(EstimationInfo)); + /* * We don't ever want to return an estimate of zero groups, as that tends * to lead to division-by-zero and other unpleasantness. The input_rows @@ -3468,6 +3480,14 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, * If examine_variable is able to deduce anything about the GROUP BY * expression, treat it as a single variable even if it's really more * complicated. + * + * XXX This has the consequence that if there's a statistics on the + * expression, we don't split it into individual Vars. This affects + * our selection of statistics in estimate_multivariate_ndistinct, + * because it's probably better to use more accurate estimate for each + * expression and treat them as independent, than to combine estimates + * for the extracted variables when we don't know how that relates to + * the expressions. */ examine_variable(root, groupexpr, 0, &vardata); if (HeapTupleIsValid(getStatsTuple(&vardata)) || vardata.isunique) @@ -3557,7 +3577,7 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, * for remaining Vars on other rels. */ relvarinfos = lappend(relvarinfos, varinfo1); - for_each_cell(l, varinfos, list_second_cell(varinfos)) + for_each_from(l, varinfos, 1) { GroupVarInfo *varinfo2 = (GroupVarInfo *) lfirst(l); @@ -3607,6 +3627,14 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, if (relmaxndistinct < varinfo2->ndistinct) relmaxndistinct = varinfo2->ndistinct; relvarcount++; + + /* + * When varinfo2's isdefault is set then we'd better set + * the SELFLAG_USED_DEFAULT bit in the EstimationInfo. + */ + if (estinfo != NULL && varinfo2->isdefault) + estinfo->flags |= SELFLAG_USED_DEFAULT; + } /* we're done with this relation */ @@ -3877,12 +3905,14 @@ estimate_hash_bucket_stats(PlannerInfo *root, Node *hashkey, double nbuckets, * won't store them. Is this a problem? */ double -estimate_hashagg_tablesize(Path *path, const AggClauseCosts *agg_costs, - double dNumGroups) +estimate_hashagg_tablesize(PlannerInfo *root, Path *path, + const AggClauseCosts *agg_costs, double dNumGroups) { - Size hashentrysize = hash_agg_entry_size(agg_costs->numAggs, - path->pathtarget->width, - agg_costs->transitionSpace); + Size hashentrysize; + + hashentrysize = hash_agg_entry_size(list_length(root->aggtransinfos), + path->pathtarget->width, + agg_costs->transitionSpace); /* * Note that this disregards the effect of fill-factor and growth policy @@ -3916,12 +3946,13 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, List **varinfos, double *ndistinct) { ListCell *lc; + RangeTblEntry *rte; Bitmapset *attnums = NULL; - int nmatches; + int nmatches_vars; + int nmatches_exprs; Oid statOid = InvalidOid; MVNDistinct *stats; - Bitmapset *matched = NULL; - RangeTblEntry *rte; + StatisticExtInfo *matched_info = NULL; /* bail out immediately if the table has no extended statistics */ if (!rel->statlist) @@ -3958,20 +3989,66 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, } /* look for the ndistinct statistics matching the most vars */ - nmatches = 1; /* we require at least two matches */ + nmatches_vars = 0; /* we require at least two matches */ + nmatches_exprs = 0; foreach(lc, rel->statlist) { + ListCell *lc2; StatisticExtInfo *info = (StatisticExtInfo *) lfirst(lc); - Bitmapset *shared; - int nshared; + int nshared_vars = 0; + int nshared_exprs = 0; /* skip statistics of other kinds */ if (info->kind != STATS_EXT_NDISTINCT) continue; - /* compute attnums shared by the vars and the statistics object */ - shared = bms_intersect(info->keys, attnums); - nshared = bms_num_members(shared); + /* + * Determine how many expressions (and variables in non-matched + * expressions) match. We'll then use these numbers to pick the + * statistics object that best matches the clauses. + */ + foreach(lc2, *varinfos) + { + ListCell *lc3; + GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc2); + AttrNumber attnum; + + Assert(varinfo->rel == rel); + + /* simple Var, search in statistics keys directly */ + if (IsA(varinfo->var, Var)) + { + attnum = ((Var *) varinfo->var)->varattno; + + /* + * Ignore system attributes - we don't support statistics on + * them, so can't match them (and it'd fail as the values are + * negative). + */ + if (!AttrNumberIsForUserDefinedAttr(attnum)) + continue; + + if (bms_is_member(attnum, info->keys)) + nshared_vars++; + + continue; + } + + /* expression - see if it's in the statistics */ + foreach(lc3, info->exprs) + { + Node *expr = (Node *) lfirst(lc3); + + if (equal(varinfo->var, expr)) + { + nshared_exprs++; + break; + } + } + } + + if (nshared_vars + nshared_exprs < 2) + continue; /* * Does this statistics object match more columns than the currently @@ -3980,18 +4057,21 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, * XXX This should break ties using name of the object, or something * like that, to make the outcome stable. */ - if (nshared > nmatches) + if ((nshared_exprs > nmatches_exprs) || + (((nshared_exprs == nmatches_exprs)) && (nshared_vars > nmatches_vars))) { statOid = info->statOid; - nmatches = nshared; - matched = shared; + nmatches_vars = nshared_vars; + nmatches_exprs = nshared_exprs; + matched_info = info; } } /* No match? */ if (statOid == InvalidOid) return false; - Assert(nmatches > 1 && matched != NULL); + + Assert(nmatches_vars + nmatches_exprs > 1); stats = statext_ndistinct_load(statOid); @@ -4004,20 +4084,135 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, int i; List *newlist = NIL; MVNDistinctItem *item = NULL; + ListCell *lc2; + Bitmapset *matched = NULL; + AttrNumber attnum_offset; + + /* + * How much we need to offset the attnums? If there are no + * expressions, no offset is needed. Otherwise offset enough to move + * the lowest one (which is equal to number of expressions) to 1. + */ + if (matched_info->exprs) + attnum_offset = (list_length(matched_info->exprs) + 1); + else + attnum_offset = 0; + + /* see what actually matched */ + foreach(lc2, *varinfos) + { + ListCell *lc3; + int idx; + bool found = false; + + GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc2); + + /* + * Process a simple Var expression, by matching it to keys + * directly. If there's a matching expression, we'll try matching + * it later. + */ + if (IsA(varinfo->var, Var)) + { + AttrNumber attnum = ((Var *) varinfo->var)->varattno; + + /* + * Ignore expressions on system attributes. Can't rely on the + * bms check for negative values. + */ + if (!AttrNumberIsForUserDefinedAttr(attnum)) + continue; + + /* Is the variable covered by the statistics? */ + if (!bms_is_member(attnum, matched_info->keys)) + continue; + + attnum = attnum + attnum_offset; + + /* ensure sufficient offset */ + Assert(AttrNumberIsForUserDefinedAttr(attnum)); + + matched = bms_add_member(matched, attnum); + + found = true; + } + + /* + * XXX Maybe we should allow searching the expressions even if we + * found an attribute matching the expression? That would handle + * trivial expressions like "(a)" but it seems fairly useless. + */ + if (found) + continue; + + /* expression - see if it's in the statistics */ + idx = 0; + foreach(lc3, matched_info->exprs) + { + Node *expr = (Node *) lfirst(lc3); + + if (equal(varinfo->var, expr)) + { + AttrNumber attnum = -(idx + 1); + + attnum = attnum + attnum_offset; + + /* ensure sufficient offset */ + Assert(AttrNumberIsForUserDefinedAttr(attnum)); + + matched = bms_add_member(matched, attnum); + + /* there should be just one matching expression */ + break; + } + + idx++; + } + } /* Find the specific item that exactly matches the combination */ for (i = 0; i < stats->nitems; i++) { + int j; MVNDistinctItem *tmpitem = &stats->items[i]; - if (bms_subset_compare(tmpitem->attrs, matched) == BMS_EQUAL) + if (tmpitem->nattributes != bms_num_members(matched)) + continue; + + /* assume it's the right item */ + item = tmpitem; + + /* check that all item attributes/expressions fit the match */ + for (j = 0; j < tmpitem->nattributes; j++) { - item = tmpitem; - break; + AttrNumber attnum = tmpitem->attributes[j]; + + /* + * Thanks to how we constructed the matched bitmap above, we + * can just offset all attnums the same way. + */ + attnum = attnum + attnum_offset; + + if (!bms_is_member(attnum, matched)) + { + /* nah, it's not this item */ + item = NULL; + break; + } } + + /* + * If the item has all the matched attributes, we know it's the + * right one - there can't be a better one. matching more. + */ + if (item) + break; } - /* make sure we found an item */ + /* + * Make sure we found an item. There has to be one, because ndistinct + * statistics includes all combinations of attributes. + */ if (!item) elog(ERROR, "corrupt MVNDistinct entry"); @@ -4025,21 +4220,66 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, foreach(lc, *varinfos) { GroupVarInfo *varinfo = (GroupVarInfo *) lfirst(lc); - AttrNumber attnum; + ListCell *lc3; + bool found = false; - if (!IsA(varinfo->var, Var)) + /* + * Let's look at plain variables first, because it's the most + * common case and the check is quite cheap. We can simply get the + * attnum and check (with an offset) matched bitmap. + */ + if (IsA(varinfo->var, Var)) { - newlist = lappend(newlist, varinfo); + AttrNumber attnum = ((Var *) varinfo->var)->varattno; + + /* + * If it's a system attribute, we're done. We don't support + * extended statistics on system attributes, so it's clearly + * not matched. Just keep the expression and continue. + */ + if (!AttrNumberIsForUserDefinedAttr(attnum)) + { + newlist = lappend(newlist, varinfo); + continue; + } + + /* apply the same offset as above */ + attnum += attnum_offset; + + /* if it's not matched, keep the varinfo */ + if (!bms_is_member(attnum, matched)) + newlist = lappend(newlist, varinfo); + + /* The rest of the loop deals with complex expressions. */ continue; } - attnum = ((Var *) varinfo->var)->varattno; + /* + * Process complex expressions, not just simple Vars. + * + * First, we search for an exact match of an expression. If we + * find one, we can just discard the whole GroupExprInfo, with all + * the variables we extracted from it. + * + * Otherwise we inspect the individual vars, and try matching it + * to variables in the item. + */ + foreach(lc3, matched_info->exprs) + { + Node *expr = (Node *) lfirst(lc3); - if (!AttrNumberIsForUserDefinedAttr(attnum)) + if (equal(varinfo->var, expr)) + { + found = true; + break; + } + } + + /* found exact match, skip */ + if (found) continue; - if (!bms_is_member(attnum, matched)) - newlist = lappend(newlist, varinfo); + newlist = lappend(newlist, varinfo); } *varinfos = newlist; @@ -4740,6 +4980,13 @@ get_join_variables(PlannerInfo *root, List *args, SpecialJoinInfo *sjinfo, *join_is_reversed = false; } +/* statext_expressions_load copies the tuple, so just pfree it. */ +static void +ReleaseDummy(HeapTuple tuple) +{ + pfree(tuple); +} + /* * This method returns a pointer to the largest child relation for an inherited (incl partitioned) * relation. If there are multiple levels in the hierarchy, we delve down recursively till we @@ -4935,7 +5182,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, * membership. Note that when varRelid isn't zero, only vars of that * relation are considered "real" vars. */ - varnos = pull_varnos(basenode); + varnos = pull_varnos(root, basenode); onerel = NULL; @@ -4994,6 +5241,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, * operator we are estimating for. FIXME later. */ ListCell *ilist; + ListCell *slist; foreach(ilist, onerel->indexlist) { @@ -5150,6 +5398,129 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, if (HeapTupleIsValid(getStatsTuple(vardata))) break; } + + /* + * Search extended statistics for one with a matching expression. + * There might be multiple ones, so just grab the first one. In the + * future, we might consider the statistics target (and pick the most + * accurate statistics) and maybe some other parameters. + */ + foreach(slist, onerel->statlist) + { + StatisticExtInfo *info = (StatisticExtInfo *) lfirst(slist); + ListCell *expr_item; + int pos; + + /* + * Stop once we've found statistics for the expression (either + * from extended stats, or for an index in the preceding loop). + */ + if (vardata->statsTuple) + break; + + /* skip stats without per-expression stats */ + if (info->kind != STATS_EXT_EXPRESSIONS) + continue; + + pos = 0; + foreach(expr_item, info->exprs) + { + Node *expr = (Node *) lfirst(expr_item); + + Assert(expr); + + /* strip RelabelType before comparing it */ + if (expr && IsA(expr, RelabelType)) + expr = (Node *) ((RelabelType *) expr)->arg; + + /* found a match, see if we can extract pg_statistic row */ + if (equal(node, expr)) + { + HeapTuple t = statext_expressions_load(info->statOid, pos); + + /* Get index's table for permission check */ + RangeTblEntry *rte; + Oid userid; + + vardata->statsTuple = t; + + /* + * XXX Not sure if we should cache the tuple somewhere. + * Now we just create a new copy every time. + */ + vardata->freefunc = ReleaseDummy; + + rte = planner_rt_fetch(onerel->relid, root); + Assert(rte->rtekind == RTE_RELATION); + + /* + * Use checkAsUser if it's set, in case we're accessing + * the table via a view. + */ + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); + + /* + * For simplicity, we insist on the whole table being + * selectable, rather than trying to identify which + * column(s) the statistics depends on. Also require all + * rows to be selectable --- there must be no + * securityQuals from security barrier views or RLS + * policies. + */ + vardata->acl_ok = + rte->securityQuals == NIL && + (pg_class_aclcheck(rte->relid, userid, + ACL_SELECT) == ACLCHECK_OK); + + /* + * If the user doesn't have permissions to access an + * inheritance child relation, check the permissions of + * the table actually mentioned in the query, since most + * likely the user does have that permission. Note that + * whole-table select privilege on the parent doesn't + * quite guarantee that the user could read all columns of + * the child. But in practice it's unlikely that any + * interesting security violation could result from + * allowing access to the expression stats, so we allow it + * anyway. See similar code in examine_simple_variable() + * for additional comments. + */ + if (!vardata->acl_ok && + root->append_rel_array != NULL) + { + AppendRelInfo *appinfo; + Index varno = onerel->relid; + + appinfo = root->append_rel_array[varno]; + while (appinfo && + planner_rt_fetch(appinfo->parent_relid, + root)->rtekind == RTE_RELATION) + { + varno = appinfo->parent_relid; + appinfo = root->append_rel_array[varno]; + } + if (varno != onerel->relid) + { + /* Repeat access check on this rel */ + rte = planner_rt_fetch(varno, root); + Assert(rte->rtekind == RTE_RELATION); + + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); + + vardata->acl_ok = + rte->securityQuals == NIL && + (pg_class_aclcheck(rte->relid, + userid, + ACL_SELECT) == ACLCHECK_OK); + } + } + + break; + } + + pos++; + } + } } } @@ -5367,7 +5738,8 @@ examine_simple_variable(PlannerInfo *root, Var *var, * of learning something even with it. */ if (subquery->setOperations || - subquery->groupClause) + subquery->groupClause || + subquery->groupingSets) return; /* diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c index 1091b51c0337..5f2ad0ed2ad0 100644 --- a/src/backend/utils/adt/tid.c +++ b/src/backend/utils/adt/tid.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -47,6 +47,8 @@ #define DELIM ',' #define NTIDARGS 2 +static ItemPointer currtid_for_view(Relation viewrel, ItemPointer tid); + /* ---------------------------------------------------------------- * tidin * ---------------------------------------------------------------- @@ -275,12 +277,44 @@ hashtidextended(PG_FUNCTION_ARGS) * Maybe these implementations should be moved to another place */ -static ItemPointerData Current_last_tid = {{0, 0}, 0}; - -void -setLastTid(const ItemPointer tid) +/* + * Utility wrapper for current CTID functions. + * Returns the latest version of a tuple pointing at "tid" for + * relation "rel". + */ +static ItemPointer +currtid_internal(Relation rel, ItemPointer tid) { - Current_last_tid = *tid; + ItemPointer result; + AclResult aclresult; + Snapshot snapshot; + TableScanDesc scan; + + result = (ItemPointer) palloc(sizeof(ItemPointerData)); + + aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), + ACL_SELECT); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), + RelationGetRelationName(rel)); + + if (rel->rd_rel->relkind == RELKIND_VIEW) + return currtid_for_view(rel, tid); + + if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) + elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"", + get_namespace_name(RelationGetNamespace(rel)), + RelationGetRelationName(rel)); + + ItemPointerCopy(tid, result); + + snapshot = RegisterSnapshot(GetLatestSnapshot()); + scan = table_beginscan_tid(rel, snapshot); + table_tuple_get_latest_tid(scan, result); + table_endscan(scan); + UnregisterSnapshot(snapshot); + + return result; } /* @@ -288,7 +322,7 @@ setLastTid(const ItemPointer tid) * CTID should be defined in the view and it must * correspond to the CTID of a base relation. */ -static Datum +static ItemPointer currtid_for_view(Relation viewrel, ItemPointer tid) { TupleDesc att = RelationGetDescr(viewrel); @@ -338,12 +372,12 @@ currtid_for_view(Relation viewrel, ItemPointer tid) rte = rt_fetch(var->varno, query->rtable); if (rte) { - Datum result; + ItemPointer result; + Relation rel; - result = DirectFunctionCall2(currtid_byreloid, - ObjectIdGetDatum(rte->relid), - PointerGetDatum(tid)); - table_close(viewrel, AccessShareLock); + rel = table_open(rte->relid, AccessShareLock); + result = currtid_internal(rel, tid); + table_close(rel, AccessShareLock); return result; } } @@ -352,81 +386,14 @@ currtid_for_view(Relation viewrel, ItemPointer tid) } } elog(ERROR, "currtid cannot handle this view"); - return (Datum) 0; + return NULL; } - /* - * This function originates from PostgreSQL, - * is currently not supported by GPDB - MPP-7886. - * The problem is that calling function - * heapam.c::heap_get_latest_tid below fails to return - * the current number of blocks for the examined relation + * currtid_byrelname + * Get the latest tuple version of the tuple pointing at a CTID, for a + * given relation name. */ - -Datum -currtid_byreloid(PG_FUNCTION_ARGS) -{ - Oid reloid = PG_GETARG_OID(0); - ItemPointer tid = PG_GETARG_ITEMPOINTER(1); - ItemPointer result; - Relation rel; - AclResult aclresult; - Snapshot snapshot; - TableScanDesc scan; - - /* - * Immediately inform client that the function is not supported - */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function currtid is not supported by GPDB"))); - - result = (ItemPointer) palloc(sizeof(ItemPointerData)); - if (!reloid) - { - *result = Current_last_tid; - PG_RETURN_ITEMPOINTER(result); - } - - rel = table_open(reloid, AccessShareLock); - - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_SELECT); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), - RelationGetRelationName(rel)); - - if (rel->rd_rel->relkind == RELKIND_VIEW) - return currtid_for_view(rel, tid); - - if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) - elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"", - get_namespace_name(RelationGetNamespace(rel)), - RelationGetRelationName(rel)); - - ItemPointerCopy(tid, result); - - snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = table_beginscan_tid(rel, snapshot); - table_tuple_get_latest_tid(scan, result); - table_endscan(scan); - UnregisterSnapshot(snapshot); - - table_close(rel, AccessShareLock); - - PG_RETURN_ITEMPOINTER(result); -} - - -/* - * This function originates from PostgreSQL, - * is currently not supported by GPDB - MPP-7886. - * The problem is that calling function - * heapam.c::heap_get_latest_tid below fails to return - * the current number of blocks for the examined relation - */ - Datum currtid_byrelname(PG_FUNCTION_ARGS) { @@ -435,9 +402,6 @@ currtid_byrelname(PG_FUNCTION_ARGS) ItemPointer result; RangeVar *relrv; Relation rel; - AclResult aclresult; - Snapshot snapshot; - TableScanDesc scan; /* * Immediately inform client that the function is not supported @@ -449,28 +413,8 @@ currtid_byrelname(PG_FUNCTION_ARGS) relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = table_openrv(relrv, AccessShareLock); - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_SELECT); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), - RelationGetRelationName(rel)); - - if (rel->rd_rel->relkind == RELKIND_VIEW) - return currtid_for_view(rel, tid); - - if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)) - elog(ERROR, "cannot look at latest visible tid for relation \"%s.%s\"", - get_namespace_name(RelationGetNamespace(rel)), - RelationGetRelationName(rel)); - - result = (ItemPointer) palloc(sizeof(ItemPointerData)); - ItemPointerCopy(tid, result); - - snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = table_beginscan_tid(rel, snapshot); - table_tuple_get_latest_tid(scan, result); - table_endscan(scan); - UnregisterSnapshot(snapshot); + /* grab the latest tuple version associated to this CTID */ + result = currtid_internal(rel, tid); table_close(rel, AccessShareLock); diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index bd5ca0c65c41..1eaa27413d93 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -3,7 +3,7 @@ * timestamp.c * Functions for the built-in SQL types "timestamp" and "interval". * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,6 +22,7 @@ #include "access/xact.h" #include "catalog/pg_type.h" +#include "common/int.h" #include "common/int128.h" #include "funcapi.h" #include "libpq/pqformat.h" @@ -35,6 +36,7 @@ #include "utils/date.h" #include "utils/datetime.h" #include "utils/float.h" +#include "utils/numeric.h" /* * gcc's -ffast-math switch breaks routines that expect exact results from @@ -909,17 +911,21 @@ make_timestamp_internal(int year, int month, int day, TimeOffset date; TimeOffset time; int dterr; + bool bc = false; Timestamp result; tm.tm_year = year; tm.tm_mon = month; tm.tm_mday = day; - /* - * Note: we'll reject zero or negative year values. Perhaps negatives - * should be allowed to represent BC years? - */ - dterr = ValidateDate(DTK_DATE_M, false, false, false, &tm); + /* Handle negative years as BC */ + if (tm.tm_year < 0) + { + bc = true; + tm.tm_year = -tm.tm_year; + } + + dterr = ValidateDate(DTK_DATE_M, false, false, bc, &tm); if (dterr != 0) ereport(ERROR, @@ -1990,12 +1996,14 @@ timeofday(PG_FUNCTION_ARGS) * TimestampDifference -- convert the difference between two timestamps * into integer seconds and microseconds * + * This is typically used to calculate a wait timeout for select(2), + * which explains the otherwise-odd choice of output format. + * * Both inputs must be ordinary finite timestamps (in current usage, * they'll be results from GetCurrentTimestamp()). * - * We expect start_time <= stop_time. If not, we return zeros; for current - * callers there is no need to be tense about which way division rounds on - * negative inputs. + * We expect start_time <= stop_time. If not, we return zeros, + * since then we're already past the previously determined stop_time. */ void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, @@ -2015,6 +2023,36 @@ TimestampDifference(TimestampTz start_time, TimestampTz stop_time, } } +/* + * TimestampDifferenceMilliseconds -- convert the difference between two + * timestamps into integer milliseconds + * + * This is typically used to calculate a wait timeout for WaitLatch() + * or a related function. The choice of "long" as the result type + * is to harmonize with that. It is caller's responsibility that the + * input timestamps not be so far apart as to risk overflow of "long" + * (which'd happen at about 25 days on machines with 32-bit "long"). + * + * Both inputs must be ordinary finite timestamps (in current usage, + * they'll be results from GetCurrentTimestamp()). + * + * We expect start_time <= stop_time. If not, we return zero, + * since then we're already past the previously determined stop_time. + * + * Note we round up any fractional millisecond, since waiting for just + * less than the intended timeout is undesirable. + */ +long +TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time) +{ + TimestampTz diff = stop_time - start_time; + + if (diff <= 0) + return 0; + else + return (long) ((diff + 999) / 1000); +} + /* * TimestampDifferenceExceeds -- report whether the difference between two * timestamps is >= a threshold (expressed in milliseconds) @@ -2505,16 +2543,34 @@ timestamp_hash_extended(PG_FUNCTION_ARGS) * Cross-type comparison functions for timestamp vs timestamptz */ +int32 +timestamp_cmp_timestamptz_internal(Timestamp timestampVal, TimestampTz dt2) +{ + TimestampTz dt1; + int overflow; + + dt1 = timestamp2timestamptz_opt_overflow(timestampVal, &overflow); + if (overflow > 0) + { + /* dt1 is larger than any finite timestamp, but less than infinity */ + return TIMESTAMP_IS_NOEND(dt2) ? -1 : +1; + } + if (overflow < 0) + { + /* dt1 is less than any finite timestamp, but more than -infinity */ + return TIMESTAMP_IS_NOBEGIN(dt2) ? +1 : -1; + } + + return timestamptz_cmp_internal(dt1, dt2); +} + Datum timestamp_eq_timestamptz(PG_FUNCTION_ARGS) { Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - - dt1 = timestamp2timestamptz(timestampVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) == 0); } Datum @@ -2522,11 +2578,8 @@ timestamp_ne_timestamptz(PG_FUNCTION_ARGS) { Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - dt1 = timestamp2timestamptz(timestampVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) != 0); } Datum @@ -2534,11 +2587,8 @@ timestamp_lt_timestamptz(PG_FUNCTION_ARGS) { Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - - dt1 = timestamp2timestamptz(timestampVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) < 0); } Datum @@ -2546,11 +2596,8 @@ timestamp_gt_timestamptz(PG_FUNCTION_ARGS) { Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - - dt1 = timestamp2timestamptz(timestampVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) > 0); } Datum @@ -2558,11 +2605,8 @@ timestamp_le_timestamptz(PG_FUNCTION_ARGS) { Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - dt1 = timestamp2timestamptz(timestampVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) <= 0); } Datum @@ -2570,11 +2614,8 @@ timestamp_ge_timestamptz(PG_FUNCTION_ARGS) { Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - dt1 = timestamp2timestamptz(timestampVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt2) >= 0); } Datum @@ -2582,11 +2623,8 @@ timestamp_cmp_timestamptz(PG_FUNCTION_ARGS) { Timestamp timestampVal = PG_GETARG_TIMESTAMP(0); TimestampTz dt2 = PG_GETARG_TIMESTAMPTZ(1); - TimestampTz dt1; - dt1 = timestamp2timestamptz(timestampVal); - - PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2)); + PG_RETURN_INT32(timestamp_cmp_timestamptz_internal(timestampVal, dt2)); } Datum @@ -2594,11 +2632,8 @@ timestamptz_eq_timestamp(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); - TimestampTz dt2; - - dt2 = timestamp2timestamptz(timestampVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) == 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) == 0); } Datum @@ -2606,11 +2641,8 @@ timestamptz_ne_timestamp(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); - TimestampTz dt2; - - dt2 = timestamp2timestamptz(timestampVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) != 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) != 0); } Datum @@ -2618,11 +2650,8 @@ timestamptz_lt_timestamp(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); - TimestampTz dt2; - - dt2 = timestamp2timestamptz(timestampVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) < 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) > 0); } Datum @@ -2630,11 +2659,8 @@ timestamptz_gt_timestamp(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); - TimestampTz dt2; - - dt2 = timestamp2timestamptz(timestampVal); - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) > 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) < 0); } Datum @@ -2642,11 +2668,8 @@ timestamptz_le_timestamp(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); - TimestampTz dt2; - dt2 = timestamp2timestamptz(timestampVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) <= 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) >= 0); } Datum @@ -2654,11 +2677,8 @@ timestamptz_ge_timestamp(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); - TimestampTz dt2; - dt2 = timestamp2timestamptz(timestampVal); - - PG_RETURN_BOOL(timestamp_cmp_internal(dt1, dt2) >= 0); + PG_RETURN_BOOL(timestamp_cmp_timestamptz_internal(timestampVal, dt1) <= 0); } Datum @@ -2666,11 +2686,8 @@ timestamptz_cmp_timestamp(PG_FUNCTION_ARGS) { TimestampTz dt1 = PG_GETARG_TIMESTAMPTZ(0); Timestamp timestampVal = PG_GETARG_TIMESTAMP(1); - TimestampTz dt2; - dt2 = timestamp2timestamptz(timestampVal); - - PG_RETURN_INT32(timestamp_cmp_internal(dt1, dt2)); + PG_RETURN_INT32(-timestamp_cmp_timestamptz_internal(timestampVal, dt1)); } @@ -4455,6 +4472,50 @@ timestamptz_li_value(float8 f, TimestampTz y0, TimestampTz y1) *---------------------------------------------------------*/ +/* timestamp_bin() + * Bin timestamp into specified interval. + */ +Datum +timestamp_bin(PG_FUNCTION_ARGS) +{ + Interval *stride = PG_GETARG_INTERVAL_P(0); + Timestamp timestamp = PG_GETARG_TIMESTAMP(1); + Timestamp origin = PG_GETARG_TIMESTAMP(2); + Timestamp result, + tm_diff, + stride_usecs, + tm_delta; + + if (TIMESTAMP_NOT_FINITE(timestamp)) + PG_RETURN_TIMESTAMP(timestamp); + + if (TIMESTAMP_NOT_FINITE(origin)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("origin out of range"))); + + if (stride->month != 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("timestamps cannot be binned into intervals containing months or years"))); + + stride_usecs = stride->day * USECS_PER_DAY + stride->time; + + tm_diff = timestamp - origin; + tm_delta = tm_diff - tm_diff % stride_usecs; + + /* + * Make sure the returned timestamp is at the start of the bin, even if + * the origin is in the future. + */ + if (origin > timestamp && stride_usecs > 1) + tm_delta -= stride_usecs; + + result = origin + tm_delta; + + PG_RETURN_TIMESTAMP(result); +} + /* timestamp_trunc() * Truncate timestamp to specified units. */ @@ -4589,6 +4650,50 @@ timestamp_trunc(PG_FUNCTION_ARGS) PG_RETURN_TIMESTAMP(result); } +/* timestamptz_bin() + * Bin timestamptz into specified interval using specified origin. + */ +Datum +timestamptz_bin(PG_FUNCTION_ARGS) +{ + Interval *stride = PG_GETARG_INTERVAL_P(0); + TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1); + TimestampTz origin = PG_GETARG_TIMESTAMPTZ(2); + TimestampTz result, + stride_usecs, + tm_diff, + tm_delta; + + if (TIMESTAMP_NOT_FINITE(timestamp)) + PG_RETURN_TIMESTAMPTZ(timestamp); + + if (TIMESTAMP_NOT_FINITE(origin)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("origin out of range"))); + + if (stride->month != 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("timestamps cannot be binned into intervals containing months or years"))); + + stride_usecs = stride->day * USECS_PER_DAY + stride->time; + + tm_diff = timestamp - origin; + tm_delta = tm_diff - tm_diff % stride_usecs; + + /* + * Make sure the returned timestamp is at the start of the bin, even if + * the origin is in the future. + */ + if (origin > timestamp && stride_usecs > 1) + tm_delta -= stride_usecs; + + result = origin + tm_delta; + + PG_RETURN_TIMESTAMPTZ(result); +} + /* * Common code for timestamptz_trunc() and timestamptz_trunc_zone(). * @@ -5166,15 +5271,15 @@ NonFiniteTimestampTzPart(int type, int unit, char *lowunits, } } -/* timestamp_part() +/* timestamp_part() and extract_timestamp() * Extract specified field from timestamp. */ -Datum -timestamp_part(PG_FUNCTION_ARGS) +static Datum +timestamp_part_common(PG_FUNCTION_ARGS, bool retnumeric) { text *units = PG_GETARG_TEXT_PP(0); Timestamp timestamp = PG_GETARG_TIMESTAMP(1); - float8 result; + int64 intresult; Timestamp epoch; int type, val; @@ -5193,11 +5298,28 @@ timestamp_part(PG_FUNCTION_ARGS) if (TIMESTAMP_NOT_FINITE(timestamp)) { - result = NonFiniteTimestampTzPart(type, val, lowunits, - TIMESTAMP_IS_NOBEGIN(timestamp), - false); - if (result) - PG_RETURN_FLOAT8(result); + double r = NonFiniteTimestampTzPart(type, val, lowunits, + TIMESTAMP_IS_NOBEGIN(timestamp), + false); + + if (r) + { + if (retnumeric) + { + if (r < 0) + return DirectFunctionCall3(numeric_in, + CStringGetDatum("-Infinity"), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + else if (r > 0) + return DirectFunctionCall3(numeric_in, + CStringGetDatum("Infinity"), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + } + else + PG_RETURN_FLOAT8(r); + } else PG_RETURN_NULL(); } @@ -5212,47 +5334,61 @@ timestamp_part(PG_FUNCTION_ARGS) switch (val) { case DTK_MICROSEC: - result = tm->tm_sec * 1000000.0 + fsec; + intresult = tm->tm_sec * INT64CONST(1000000) + fsec; break; case DTK_MILLISEC: - result = tm->tm_sec * 1000.0 + fsec / 1000.0; + if (retnumeric) + /*--- + * tm->tm_sec * 1000 + fsec / 1000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3)); + else + PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0); break; case DTK_SECOND: - result = tm->tm_sec + fsec / 1000000.0; + if (retnumeric) + /*--- + * tm->tm_sec + fsec / 1'000'000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6)); + else + PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0); break; case DTK_MINUTE: - result = tm->tm_min; + intresult = tm->tm_min; break; case DTK_HOUR: - result = tm->tm_hour; + intresult = tm->tm_hour; break; case DTK_DAY: - result = tm->tm_mday; + intresult = tm->tm_mday; break; case DTK_MONTH: - result = tm->tm_mon; + intresult = tm->tm_mon; break; case DTK_QUARTER: - result = (tm->tm_mon - 1) / 3 + 1; + intresult = (tm->tm_mon - 1) / 3 + 1; break; case DTK_WEEK: - result = (float8) date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday); + intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday); break; case DTK_YEAR: if (tm->tm_year > 0) - result = tm->tm_year; + intresult = tm->tm_year; else /* there is no year 0, just 1 BC and 1 AD */ - result = tm->tm_year - 1; + intresult = tm->tm_year - 1; break; case DTK_DECADE: @@ -5263,9 +5399,9 @@ timestamp_part(PG_FUNCTION_ARGS) * is 11 BC thru 2 BC... */ if (tm->tm_year >= 0) - result = tm->tm_year / 10; + intresult = tm->tm_year / 10; else - result = -((8 - (tm->tm_year - 1)) / 10); + intresult = -((8 - (tm->tm_year - 1)) / 10); break; case DTK_CENTURY: @@ -5277,43 +5413,50 @@ timestamp_part(PG_FUNCTION_ARGS) * ---- */ if (tm->tm_year > 0) - result = (tm->tm_year + 99) / 100; + intresult = (tm->tm_year + 99) / 100; else /* caution: C division may have negative remainder */ - result = -((99 - (tm->tm_year - 1)) / 100); + intresult = -((99 - (tm->tm_year - 1)) / 100); break; case DTK_MILLENNIUM: /* see comments above. */ if (tm->tm_year > 0) - result = (tm->tm_year + 999) / 1000; + intresult = (tm->tm_year + 999) / 1000; else - result = -((999 - (tm->tm_year - 1)) / 1000); + intresult = -((999 - (tm->tm_year - 1)) / 1000); break; case DTK_JULIAN: - result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday); - result += ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + - tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY; + if (retnumeric) + PG_RETURN_NUMERIC(numeric_add_opt_error(int64_to_numeric(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)), + numeric_div_opt_error(int64_to_numeric(((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) * INT64CONST(1000000) + fsec), + int64_to_numeric(SECS_PER_DAY * INT64CONST(1000000)), + NULL), + NULL)); + else + PG_RETURN_FLOAT8(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + + ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + + tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY); break; case DTK_ISOYEAR: - result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday); + intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday); /* Adjust BC years */ - if (result <= 0) - result -= 1; + if (intresult <= 0) + intresult -= 1; break; case DTK_DOW: case DTK_ISODOW: - result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); - if (val == DTK_ISODOW && result == 0) - result = 7; + intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); + if (val == DTK_ISODOW && intresult == 0) + intresult = 7; break; case DTK_DOY: - result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - - date2j(tm->tm_year, 1, 1) + 1); + intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + - date2j(tm->tm_year, 1, 1) + 1); break; case DTK_TZ: @@ -5324,7 +5467,7 @@ timestamp_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("timestamp units \"%s\" not supported", lowunits))); - result = 0; + intresult = 0; } } else if (type == RESERV) @@ -5333,11 +5476,37 @@ timestamp_part(PG_FUNCTION_ARGS) { case DTK_EPOCH: epoch = SetEpochTimestamp(); - /* try to avoid precision loss in subtraction */ - if (timestamp < (PG_INT64_MAX + epoch)) - result = (timestamp - epoch) / 1000000.0; + /* (timestamp - epoch) / 1000000 */ + if (retnumeric) + { + Numeric result; + + if (timestamp < (PG_INT64_MAX + epoch)) + result = int64_div_fast_to_numeric(timestamp - epoch, 6); + else + { + result = numeric_div_opt_error(numeric_sub_opt_error(int64_to_numeric(timestamp), + int64_to_numeric(epoch), + NULL), + int64_to_numeric(1000000), + NULL); + result = DatumGetNumeric(DirectFunctionCall2(numeric_round, + NumericGetDatum(result), + Int32GetDatum(6))); + } + PG_RETURN_NUMERIC(result); + } else - result = ((float8) timestamp - epoch) / 1000000.0; + { + float8 result; + + /* try to avoid precision loss in subtraction */ + if (timestamp < (PG_INT64_MAX + epoch)) + result = (timestamp - epoch) / 1000000.0; + else + result = ((float8) timestamp - epoch) / 1000000.0; + PG_RETURN_FLOAT8(result); + } break; default: @@ -5345,7 +5514,7 @@ timestamp_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("timestamp units \"%s\" not supported", lowunits))); - result = 0; + intresult = 0; } } @@ -5354,27 +5523,41 @@ timestamp_part(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("timestamp units \"%s\" not recognized", lowunits))); - result = 0; + intresult = 0; } - PG_RETURN_FLOAT8(result); + if (retnumeric) + PG_RETURN_NUMERIC(int64_to_numeric(intresult)); + else + PG_RETURN_FLOAT8(intresult); +} + +Datum +timestamp_part(PG_FUNCTION_ARGS) +{ + return timestamp_part_common(fcinfo, false); } -/* timestamptz_part() +Datum +extract_timestamp(PG_FUNCTION_ARGS) +{ + return timestamp_part_common(fcinfo, true); +} + +/* timestamptz_part() and extract_timestamptz() * Extract specified field from timestamp with time zone. */ -Datum -timestamptz_part(PG_FUNCTION_ARGS) +static Datum +timestamptz_part_common(PG_FUNCTION_ARGS, bool retnumeric) { text *units = PG_GETARG_TEXT_PP(0); TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1); - float8 result; + int64 intresult; Timestamp epoch; int tz = 0; int type, val; char *lowunits; - double dummy; fsec_t fsec; struct pg_tm tt, *tm = &tt; @@ -5389,11 +5572,28 @@ timestamptz_part(PG_FUNCTION_ARGS) if (TIMESTAMP_NOT_FINITE(timestamp)) { - result = NonFiniteTimestampTzPart(type, val, lowunits, - TIMESTAMP_IS_NOBEGIN(timestamp), - true); - if (result) - PG_RETURN_FLOAT8(result); + double r = NonFiniteTimestampTzPart(type, val, lowunits, + TIMESTAMP_IS_NOBEGIN(timestamp), + true); + + if (r) + { + if (retnumeric) + { + if (r < 0) + return DirectFunctionCall3(numeric_in, + CStringGetDatum("-Infinity"), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + else if (r > 0) + return DirectFunctionCall3(numeric_in, + CStringGetDatum("Infinity"), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + } + else + PG_RETURN_FLOAT8(r); + } else PG_RETURN_NULL(); } @@ -5408,111 +5608,129 @@ timestamptz_part(PG_FUNCTION_ARGS) switch (val) { case DTK_TZ: - result = -tz; + intresult = -tz; break; case DTK_TZ_MINUTE: - result = -tz; - result /= MINS_PER_HOUR; - FMODULO(result, dummy, (double) MINS_PER_HOUR); + intresult = (-tz / SECS_PER_MINUTE) % MINS_PER_HOUR; break; case DTK_TZ_HOUR: - dummy = -tz; - FMODULO(dummy, result, (double) SECS_PER_HOUR); + intresult = -tz / SECS_PER_HOUR; break; case DTK_MICROSEC: - result = tm->tm_sec * 1000000.0 + fsec; + intresult = tm->tm_sec * INT64CONST(1000000) + fsec; break; case DTK_MILLISEC: - result = tm->tm_sec * 1000.0 + fsec / 1000.0; + if (retnumeric) + /*--- + * tm->tm_sec * 1000 + fsec / 1000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3)); + else + PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0); break; case DTK_SECOND: - result = tm->tm_sec + fsec / 1000000.0; + if (retnumeric) + /*--- + * tm->tm_sec + fsec / 1'000'000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6)); + else + PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0); break; case DTK_MINUTE: - result = tm->tm_min; + intresult = tm->tm_min; break; case DTK_HOUR: - result = tm->tm_hour; + intresult = tm->tm_hour; break; case DTK_DAY: - result = tm->tm_mday; + intresult = tm->tm_mday; break; case DTK_MONTH: - result = tm->tm_mon; + intresult = tm->tm_mon; break; case DTK_QUARTER: - result = (tm->tm_mon - 1) / 3 + 1; + intresult = (tm->tm_mon - 1) / 3 + 1; break; case DTK_WEEK: - result = (float8) date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday); + intresult = date2isoweek(tm->tm_year, tm->tm_mon, tm->tm_mday); break; case DTK_YEAR: if (tm->tm_year > 0) - result = tm->tm_year; + intresult = tm->tm_year; else /* there is no year 0, just 1 BC and 1 AD */ - result = tm->tm_year - 1; + intresult = tm->tm_year - 1; break; case DTK_DECADE: /* see comments in timestamp_part */ if (tm->tm_year > 0) - result = tm->tm_year / 10; + intresult = tm->tm_year / 10; else - result = -((8 - (tm->tm_year - 1)) / 10); + intresult = -((8 - (tm->tm_year - 1)) / 10); break; case DTK_CENTURY: /* see comments in timestamp_part */ if (tm->tm_year > 0) - result = (tm->tm_year + 99) / 100; + intresult = (tm->tm_year + 99) / 100; else - result = -((99 - (tm->tm_year - 1)) / 100); + intresult = -((99 - (tm->tm_year - 1)) / 100); break; case DTK_MILLENNIUM: /* see comments in timestamp_part */ if (tm->tm_year > 0) - result = (tm->tm_year + 999) / 1000; + intresult = (tm->tm_year + 999) / 1000; else - result = -((999 - (tm->tm_year - 1)) / 1000); + intresult = -((999 - (tm->tm_year - 1)) / 1000); break; case DTK_JULIAN: - result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday); - result += ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + - tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY; + if (retnumeric) + PG_RETURN_NUMERIC(numeric_add_opt_error(int64_to_numeric(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)), + numeric_div_opt_error(int64_to_numeric(((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) * INT64CONST(1000000) + fsec), + int64_to_numeric(SECS_PER_DAY * INT64CONST(1000000)), + NULL), + NULL)); + else + PG_RETURN_FLOAT8(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + + ((((tm->tm_hour * MINS_PER_HOUR) + tm->tm_min) * SECS_PER_MINUTE) + + tm->tm_sec + (fsec / 1000000.0)) / (double) SECS_PER_DAY); break; case DTK_ISOYEAR: - result = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday); + intresult = date2isoyear(tm->tm_year, tm->tm_mon, tm->tm_mday); /* Adjust BC years */ - if (result <= 0) - result -= 1; + if (intresult <= 0) + intresult -= 1; break; case DTK_DOW: case DTK_ISODOW: - result = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); - if (val == DTK_ISODOW && result == 0) - result = 7; + intresult = j2day(date2j(tm->tm_year, tm->tm_mon, tm->tm_mday)); + if (val == DTK_ISODOW && intresult == 0) + intresult = 7; break; case DTK_DOY: - result = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - - date2j(tm->tm_year, 1, 1) + 1); + intresult = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + - date2j(tm->tm_year, 1, 1) + 1); break; default: @@ -5520,7 +5738,7 @@ timestamptz_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("timestamp with time zone units \"%s\" not supported", lowunits))); - result = 0; + intresult = 0; } } @@ -5530,11 +5748,37 @@ timestamptz_part(PG_FUNCTION_ARGS) { case DTK_EPOCH: epoch = SetEpochTimestamp(); - /* try to avoid precision loss in subtraction */ - if (timestamp < (PG_INT64_MAX + epoch)) - result = (timestamp - epoch) / 1000000.0; + /* (timestamp - epoch) / 1000000 */ + if (retnumeric) + { + Numeric result; + + if (timestamp < (PG_INT64_MAX + epoch)) + result = int64_div_fast_to_numeric(timestamp - epoch, 6); + else + { + result = numeric_div_opt_error(numeric_sub_opt_error(int64_to_numeric(timestamp), + int64_to_numeric(epoch), + NULL), + int64_to_numeric(1000000), + NULL); + result = DatumGetNumeric(DirectFunctionCall2(numeric_round, + NumericGetDatum(result), + Int32GetDatum(6))); + } + PG_RETURN_NUMERIC(result); + } else - result = ((float8) timestamp - epoch) / 1000000.0; + { + float8 result; + + /* try to avoid precision loss in subtraction */ + if (timestamp < (PG_INT64_MAX + epoch)) + result = (timestamp - epoch) / 1000000.0; + else + result = ((float8) timestamp - epoch) / 1000000.0; + PG_RETURN_FLOAT8(result); + } break; default: @@ -5542,7 +5786,7 @@ timestamptz_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("timestamp with time zone units \"%s\" not supported", lowunits))); - result = 0; + intresult = 0; } } else @@ -5552,22 +5796,37 @@ timestamptz_part(PG_FUNCTION_ARGS) errmsg("timestamp with time zone units \"%s\" not recognized", lowunits))); - result = 0; + intresult = 0; } - PG_RETURN_FLOAT8(result); + if (retnumeric) + PG_RETURN_NUMERIC(int64_to_numeric(intresult)); + else + PG_RETURN_FLOAT8(intresult); +} + +Datum +timestamptz_part(PG_FUNCTION_ARGS) +{ + return timestamptz_part_common(fcinfo, false); +} + +Datum +extract_timestamptz(PG_FUNCTION_ARGS) +{ + return timestamptz_part_common(fcinfo, true); } -/* interval_part() +/* interval_part() and extract_interval() * Extract specified field from interval. */ -Datum -interval_part(PG_FUNCTION_ARGS) +static Datum +interval_part_common(PG_FUNCTION_ARGS, bool retnumeric) { text *units = PG_GETARG_TEXT_PP(0); Interval *interval = PG_GETARG_INTERVAL_P(1); - float8 result; + int64 intresult; int type, val; char *lowunits; @@ -5590,54 +5849,68 @@ interval_part(PG_FUNCTION_ARGS) switch (val) { case DTK_MICROSEC: - result = tm->tm_sec * 1000000.0 + fsec; + intresult = tm->tm_sec * INT64CONST(1000000) + fsec; break; case DTK_MILLISEC: - result = tm->tm_sec * 1000.0 + fsec / 1000.0; + if (retnumeric) + /*--- + * tm->tm_sec * 1000 + fsec / 1000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 3)); + else + PG_RETURN_FLOAT8(tm->tm_sec * 1000.0 + fsec / 1000.0); break; case DTK_SECOND: - result = tm->tm_sec + fsec / 1000000.0; + if (retnumeric) + /*--- + * tm->tm_sec + fsec / 1'000'000 + * = (tm->tm_sec * 1'000'000 + fsec) / 1'000'000 + */ + PG_RETURN_NUMERIC(int64_div_fast_to_numeric(tm->tm_sec * INT64CONST(1000000) + fsec, 6)); + else + PG_RETURN_FLOAT8(tm->tm_sec + fsec / 1000000.0); break; case DTK_MINUTE: - result = tm->tm_min; + intresult = tm->tm_min; break; case DTK_HOUR: - result = tm->tm_hour; + intresult = tm->tm_hour; break; case DTK_DAY: - result = tm->tm_mday; + intresult = tm->tm_mday; break; case DTK_MONTH: - result = tm->tm_mon; + intresult = tm->tm_mon; break; case DTK_QUARTER: - result = (tm->tm_mon / 3) + 1; + intresult = (tm->tm_mon / 3) + 1; break; case DTK_YEAR: - result = tm->tm_year; + intresult = tm->tm_year; break; case DTK_DECADE: /* caution: C division may have negative remainder */ - result = tm->tm_year / 10; + intresult = tm->tm_year / 10; break; case DTK_CENTURY: /* caution: C division may have negative remainder */ - result = tm->tm_year / 100; + intresult = tm->tm_year / 100; break; case DTK_MILLENNIUM: /* caution: C division may have negative remainder */ - result = tm->tm_year / 1000; + intresult = tm->tm_year / 1000; break; default: @@ -5645,22 +5918,60 @@ interval_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("interval units \"%s\" not supported", lowunits))); - result = 0; + intresult = 0; } - } else { elog(ERROR, "could not convert interval to tm"); - result = 0; + intresult = 0; } } else if (type == RESERV && val == DTK_EPOCH) { - result = interval->time / 1000000.0; - result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR); - result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR); - result += ((double) SECS_PER_DAY) * interval->day; + if (retnumeric) + { + Numeric result; + int64 secs_from_day_month; + int64 val; + + /* this always fits into int64 */ + secs_from_day_month = ((int64) DAYS_PER_YEAR * (interval->month / MONTHS_PER_YEAR) + + (int64) DAYS_PER_MONTH * (interval->month % MONTHS_PER_YEAR) + + interval->day) * SECS_PER_DAY; + + /*--- + * result = secs_from_day_month + interval->time / 1'000'000 + * = (secs_from_day_month * 1'000'000 + interval->time) / 1'000'000 + */ + + /* + * Try the computation inside int64; if it overflows, do it in + * numeric (slower). This overflow happens around 10^9 days, so + * not common in practice. + */ + if (!pg_mul_s64_overflow(secs_from_day_month, 1000000, &val) && + !pg_add_s64_overflow(val, interval->time, &val)) + result = int64_div_fast_to_numeric(val, 6); + else + result = + numeric_add_opt_error(int64_div_fast_to_numeric(interval->time, 6), + int64_to_numeric(secs_from_day_month), + NULL); + + PG_RETURN_NUMERIC(result); + } + else + { + float8 result; + + result = interval->time / 1000000.0; + result += ((double) DAYS_PER_YEAR * SECS_PER_DAY) * (interval->month / MONTHS_PER_YEAR); + result += ((double) DAYS_PER_MONTH * SECS_PER_DAY) * (interval->month % MONTHS_PER_YEAR); + result += ((double) SECS_PER_DAY) * interval->day; + + PG_RETURN_FLOAT8(result); + } } else { @@ -5668,10 +5979,25 @@ interval_part(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("interval units \"%s\" not recognized", lowunits))); - result = 0; + intresult = 0; } - PG_RETURN_FLOAT8(result); + if (retnumeric) + PG_RETURN_NUMERIC(int64_to_numeric(intresult)); + else + PG_RETURN_FLOAT8(intresult); +} + +Datum +interval_part(PG_FUNCTION_ARGS) +{ + return interval_part_common(fcinfo, false); +} + +Datum +extract_interval(PG_FUNCTION_ARGS) +{ + return interval_part_common(fcinfo, true); } @@ -5832,9 +6158,12 @@ timestamp_timestamptz(PG_FUNCTION_ARGS) /* * Convert timestamp to timestamp with time zone. * - * On overflow error is thrown if 'overflow' is NULL. Otherwise, '*overflow' - * is set to -1 (+1) when result value exceed lower (upper) boundary and zero - * returned. + * On successful conversion, *overflow is set to zero if it's not NULL. + * + * If the timestamp is finite but out of the valid range for timestamptz, then: + * if overflow is NULL, we throw an out-of-range error. + * if overflow is not NULL, we store +1 or -1 there to indicate the sign + * of the overflow, and return the appropriate timestamptz infinity. */ TimestampTz timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow) @@ -5845,10 +6174,14 @@ timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow) fsec_t fsec = 0; int tz; + if (overflow) + *overflow = 0; + if (TIMESTAMP_NOT_FINITE(timestamp)) return timestamp; - if (!timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL)) + /* We don't expect this to fail, but check it pro forma */ + if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0) { tz = DetermineTimeZoneOffset(tm, session_timezone); @@ -5861,13 +6194,16 @@ timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow) else if (overflow) { if (result < MIN_TIMESTAMP) + { *overflow = -1; + TIMESTAMP_NOBEGIN(result); + } else { - Assert(result >= END_TIMESTAMP); *overflow = 1; + TIMESTAMP_NOEND(result); } - return (TimestampTz) 0; + return result; } } @@ -5879,7 +6215,7 @@ timestamp2timestamptz_opt_overflow(Timestamp timestamp, int *overflow) } /* - * Single-argument version of timestamp2timestamptz_opt_overflow(). + * Promote timestamp to timestamptz, throwing error for overflow. */ static TimestampTz timestamp2timestamptz(Timestamp timestamp) diff --git a/src/backend/utils/adt/trigfuncs.c b/src/backend/utils/adt/trigfuncs.c index 41377270ed27..cc28cfd186b1 100644 --- a/src/backend/utils/adt/trigfuncs.c +++ b/src/backend/utils/adt/trigfuncs.c @@ -4,7 +4,7 @@ * Builtin functions for useful trigger support. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/utils/adt/trigfuncs.c diff --git a/src/backend/utils/adt/tsginidx.c b/src/backend/utils/adt/tsginidx.c index b3e3ffc57763..7e0e31f69df6 100644 --- a/src/backend/utils/adt/tsginidx.c +++ b/src/backend/utils/adt/tsginidx.c @@ -3,7 +3,7 @@ * tsginidx.c * GIN support functions for tsvector_ops * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -175,7 +175,6 @@ typedef struct QueryItem *first_item; GinTernaryValue *check; int *map_item_operand; - bool *need_recheck; } GinChkVal; /* @@ -186,25 +185,22 @@ checkcondition_gin(void *checkval, QueryOperand *val, ExecPhraseData *data) { GinChkVal *gcv = (GinChkVal *) checkval; int j; - - /* - * if any val requiring a weight is used or caller needs position - * information then set recheck flag - */ - if (val->weight != 0 || data != NULL) - *(gcv->need_recheck) = true; + GinTernaryValue result; /* convert item's number to corresponding entry's (operand's) number */ j = gcv->map_item_operand[((QueryItem *) val) - gcv->first_item]; + /* determine presence of current entry in indexed value */ + result = gcv->check[j]; + /* - * return presence of current entry in indexed value; but TRUE becomes - * MAYBE in the presence of a query requiring recheck + * If any val requiring a weight is used or caller needs position + * information then we must recheck, so replace TRUE with MAYBE. */ - if (gcv->check[j] == GIN_TRUE) + if (result == GIN_TRUE) { if (val->weight != 0 || data != NULL) - return TS_MAYBE; + result = GIN_MAYBE; } /* @@ -212,7 +208,7 @@ checkcondition_gin(void *checkval, QueryOperand *val, ExecPhraseData *data) * assignments. We could use a switch statement to map the values if that * ever stops being true, but it seems unlikely to happen. */ - return (TSTernaryValue) gcv->check[j]; + return (TSTernaryValue) result; } Datum @@ -244,12 +240,23 @@ gin_tsquery_consistent(PG_FUNCTION_ARGS) "sizes of GinTernaryValue and bool are not equal"); gcv.check = (GinTernaryValue *) check; gcv.map_item_operand = (int *) (extra_data[0]); - gcv.need_recheck = recheck; - res = TS_execute(GETQUERY(query), - &gcv, - TS_EXEC_PHRASE_NO_POS, - checkcondition_gin); + switch (TS_execute_ternary(GETQUERY(query), + &gcv, + TS_EXEC_PHRASE_NO_POS, + checkcondition_gin)) + { + case TS_NO: + res = false; + break; + case TS_YES: + res = true; + break; + case TS_MAYBE: + res = true; + *recheck = true; + break; + } } PG_RETURN_BOOL(res); @@ -266,10 +273,6 @@ gin_tsquery_triconsistent(PG_FUNCTION_ARGS) /* int32 nkeys = PG_GETARG_INT32(3); */ Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); GinTernaryValue res = GIN_FALSE; - bool recheck; - - /* Initially assume query doesn't require recheck */ - recheck = false; if (query->size > 0) { @@ -282,13 +285,11 @@ gin_tsquery_triconsistent(PG_FUNCTION_ARGS) gcv.first_item = GETQUERY(query); gcv.check = check; gcv.map_item_operand = (int *) (extra_data[0]); - gcv.need_recheck = &recheck; - if (TS_execute(GETQUERY(query), - &gcv, - TS_EXEC_PHRASE_NO_POS, - checkcondition_gin)) - res = recheck ? GIN_MAYBE : GIN_TRUE; + res = TS_execute_ternary(GETQUERY(query), + &gcv, + TS_EXEC_PHRASE_NO_POS, + checkcondition_gin); } PG_RETURN_GIN_TERNARY_VALUE(res); diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c index a601965bd83e..c09eefdda231 100644 --- a/src/backend/utils/adt/tsgistidx.c +++ b/src/backend/utils/adt/tsgistidx.c @@ -3,7 +3,7 @@ * tsgistidx.c * GiST support functions for tsvector_ops * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index 092e8a130bfc..b2ca0d2f8a24 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -3,7 +3,7 @@ * tsquery.c * I/O functions for tsquery * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -77,7 +77,6 @@ struct TSQueryParserStateData char *buf; /* current scan point */ int count; /* nesting count, incremented by (, * decremented by ) */ - bool in_quotes; /* phrase in quotes "" */ ts_parserstate state; /* polish (prefix) notation in list, filled in by push* functions */ @@ -235,9 +234,6 @@ parse_or_operator(TSQueryParserState pstate) { char *ptr = pstate->buf; - if (pstate->in_quotes) - return false; - /* it should begin with "OR" literal */ if (pg_strncasecmp(ptr, "or", 2) != 0) return false; @@ -398,38 +394,29 @@ gettoken_query_websearch(TSQueryParserState state, int8 *operator, state->buf++; state->state = WAITOPERAND; - if (state->in_quotes) - continue; - *operator = OP_NOT; return PT_OPR; } else if (t_iseq(state->buf, '"')) { + /* Everything in quotes is processed as a single token */ + + /* skip opening quote */ state->buf++; + *strval = state->buf; - if (!state->in_quotes) - { - state->state = WAITOPERAND; + /* iterate to the closing quote or end of the string */ + while (*state->buf != '\0' && !t_iseq(state->buf, '"')) + state->buf++; + *lenval = state->buf - *strval; - if (strchr(state->buf, '"')) - { - /* quoted text should be ordered <-> */ - state->in_quotes = true; - return PT_OPEN; - } + /* skip closing quote if not end of the string */ + if (*state->buf != '\0') + state->buf++; - /* web search tolerates missing quotes */ - continue; - } - else - { - /* we have to provide an operand */ - state->in_quotes = false; - state->state = WAITOPERATOR; - pushStop(state); - return PT_CLOSE; - } + state->state = WAITOPERATOR; + state->count++; + return PT_VAL; } else if (ISOPERATOR(state->buf)) { @@ -467,24 +454,13 @@ gettoken_query_websearch(TSQueryParserState state, int8 *operator, case WAITOPERATOR: if (t_iseq(state->buf, '"')) { - if (!state->in_quotes) - { - /* - * put implicit AND after an operand and handle this - * quote in WAITOPERAND - */ - state->state = WAITOPERAND; - *operator = OP_AND; - return PT_OPR; - } - else - { - state->buf++; - - /* just close quotes */ - state->in_quotes = false; - return PT_CLOSE; - } + /* + * put implicit AND after an operand and handle this quote + * in WAITOPERAND + */ + state->state = WAITOPERAND; + *operator = OP_AND; + return PT_OPR; } else if (parse_or_operator(state)) { @@ -498,18 +474,8 @@ gettoken_query_websearch(TSQueryParserState state, int8 *operator, } else if (!t_isspace(state->buf)) { - if (state->in_quotes) - { - /* put implicit <-> after an operand */ - *operator = OP_PHRASE; - *weight = 1; - } - else - { - /* put implicit AND after an operand */ - *operator = OP_AND; - } - + /* put implicit AND after an operand */ + *operator = OP_AND; state->state = WAITOPERAND; return PT_OPR; } @@ -846,7 +812,6 @@ parse_tsquery(char *buf, state.buffer = buf; state.buf = buf; state.count = 0; - state.in_quotes = false; state.state = WAITFIRSTOPERAND; state.polstr = NIL; diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c index 2481cf8c7bf5..82ae284403a4 100644 --- a/src/backend/utils/adt/tsquery_cleanup.c +++ b/src/backend/utils/adt/tsquery_cleanup.c @@ -4,7 +4,7 @@ * Cleanup query from NOT values and/or stopword * Utility functions to correct work. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery_gist.c b/src/backend/utils/adt/tsquery_gist.c index ea18a350188a..14d7343afa7c 100644 --- a/src/backend/utils/adt/tsquery_gist.c +++ b/src/backend/utils/adt/tsquery_gist.c @@ -3,7 +3,7 @@ * tsquery_gist.c * GiST index support for tsquery * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery_op.c b/src/backend/utils/adt/tsquery_op.c index ea40804110c7..0575b55272b3 100644 --- a/src/backend/utils/adt/tsquery_op.c +++ b/src/backend/utils/adt/tsquery_op.c @@ -3,7 +3,7 @@ * tsquery_op.c * Various operations with tsquery * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery_rewrite.c b/src/backend/utils/adt/tsquery_rewrite.c index 1be89e833c85..cf0cc974ae5c 100644 --- a/src/backend/utils/adt/tsquery_rewrite.c +++ b/src/backend/utils/adt/tsquery_rewrite.c @@ -3,7 +3,7 @@ * tsquery_rewrite.c * Utilities for reconstructing tsquery * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c index e5c684e289ea..7f936427b5fd 100644 --- a/src/backend/utils/adt/tsquery_util.c +++ b/src/backend/utils/adt/tsquery_util.c @@ -3,7 +3,7 @@ * tsquery_util.c * Utilities for tsquery datatype * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c index c88ebfc7d411..977f70047932 100644 --- a/src/backend/utils/adt/tsrank.c +++ b/src/backend/utils/adt/tsrank.c @@ -3,7 +3,7 @@ * tsrank.c * rank tsvector by tsquery * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -857,8 +857,7 @@ calc_rank_cd(const float4 *arrdata, TSVector txt, TSQuery query, int method) double Wdoc = 0.0; double invws[lengthof(weights)]; double SumDist = 0.0, - PrevExtPos = 0.0, - CurExtPos = 0.0; + PrevExtPos = 0.0; int NExtent = 0; QueryRepresentation qr; @@ -889,6 +888,7 @@ calc_rank_cd(const float4 *arrdata, TSVector txt, TSQuery query, int method) { double Cpos = 0.0; double InvSum = 0.0; + double CurExtPos; int nNoise; DocRepresentation *ptr = ext.begin; diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c index cd3bb9b63e31..b02fecc0811c 100644 --- a/src/backend/utils/adt/tsvector.c +++ b/src/backend/utils/adt/tsvector.c @@ -3,7 +3,7 @@ * tsvector.c * I/O functions for tsvector * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c index 756a48a167ad..9236ebcc8fe5 100644 --- a/src/backend/utils/adt/tsvector_op.c +++ b/src/backend/utils/adt/tsvector_op.c @@ -3,7 +3,7 @@ * tsvector_op.c * operations over tsvector * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -1854,6 +1854,18 @@ TS_execute(QueryItem *curitem, void *arg, uint32 flags, return TS_execute_recurse(curitem, arg, flags, chkcond) != TS_NO; } +/* + * Evaluate tsquery boolean expression. + * + * This is the same as TS_execute except that TS_MAYBE is returned as-is. + */ +TSTernaryValue +TS_execute_ternary(QueryItem *curitem, void *arg, uint32 flags, + TSExecuteCallback chkcond) +{ + return TS_execute_recurse(curitem, arg, flags, chkcond); +} + /* * TS_execute recursion for operators above any phrase operator. Here we do * not need to worry about lexeme positions. As soon as we hit an OP_PHRASE diff --git a/src/backend/utils/adt/tsvector_parser.c b/src/backend/utils/adt/tsvector_parser.c index cfc181c20dfc..c2df4093e6be 100644 --- a/src/backend/utils/adt/tsvector_parser.c +++ b/src/backend/utils/adt/tsvector_parser.c @@ -3,7 +3,7 @@ * tsvector_parser.c * Parser for tsvector * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index c906ee789d92..b02c9fcf984a 100644 --- a/src/backend/utils/adt/uuid.c +++ b/src/backend/utils/adt/uuid.c @@ -3,7 +3,7 @@ * uuid.c * Functions for the built-in type "uuid". * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/uuid.c diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index d40cb24bc2c2..58c15bd320f0 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -20,7 +20,7 @@ * * Code originally contributed by Adriaan Joubert. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -37,6 +37,7 @@ #include "libpq/pqformat.h" #include "nodes/nodeFuncs.h" #include "nodes/supportnodes.h" +#include "port/pg_bitutils.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/varbit.h" @@ -1060,7 +1061,7 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified) len, ishift, i; - int e, + int32 e, s1, e1; bits8 *r, @@ -1073,18 +1074,24 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified) { e1 = bitlen + 1; } - else + else if (l < 0) + { + /* SQL99 says to throw an error for E < S, i.e., negative length */ + ereport(ERROR, + (errcode(ERRCODE_SUBSTRING_ERROR), + errmsg("negative substring length not allowed"))); + e1 = -1; /* silence stupider compilers */ + } + else if (pg_add_s32_overflow(s, l, &e)) { - e = s + l; - /* - * A negative value for L is the only way for the end position to be - * before the start. SQL99 says to throw an error. + * L could be large enough for S + L to overflow, in which case the + * substring must run to end of string. */ - if (e < s) - ereport(ERROR, - (errcode(ERRCODE_SUBSTRING_ERROR), - errmsg("negative substring length not allowed"))); + e1 = bitlen + 1; + } + else + { e1 = Min(e, bitlen + 1); } if (s1 > bitlen || e1 <= s1) @@ -1196,6 +1203,19 @@ bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl) return result; } +/* + * bit_count + * + * Returns the number of bits set in a bit string. + */ +Datum +bit_bit_count(PG_FUNCTION_ARGS) +{ + VarBit *arg = PG_GETARG_VARBIT_P(0); + + PG_RETURN_INT64(pg_popcount((char *) VARBITS(arg), VARBITBYTES(arg))); +} + /* * bitlength, bitoctetlength * Return the length of a bit string diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index b595ab9569cf..8fc84649f195 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -3,7 +3,7 @@ * varchar.c * Functions for the built-in types char(n) and varchar(n). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 0f63a3532cbc..44bfc09b0096 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -3,7 +3,7 @@ * varlena.c * Functions for the variable-length built-in types. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,14 +18,17 @@ #include #include "access/detoast.h" +#include "access/toast_compression.h" #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/hashfn.h" +#include "common/hex.h" #include "common/int.h" #include "common/unicode_norm.h" #include "lib/hyperloglog.h" #include "libpq/pqformat.h" #include "miscadmin.h" +#include "nodes/execnodes.h" #include "parser/scansup.h" #include "port/pg_bswap.h" #include "regex/regex.h" @@ -50,7 +53,7 @@ typedef struct varlena VarString; typedef struct { bool is_multibyte; /* T if multibyte encoding */ - bool is_multibyte_char_in_char; + bool is_multibyte_char_in_char; /* need to check char boundaries? */ char *str1; /* haystack string */ char *str2; /* needle string */ @@ -92,6 +95,17 @@ typedef struct pg_locale_t locale; } VarStringSortSupport; +/* + * Output data for split_text(): we output either to an array or a table. + * tupstore and tupdesc must be set up in advance to output to a table. + */ +typedef struct +{ + ArrayBuildState *astate; + Tuplestorestate *tupstore; + TupleDesc tupdesc; +} SplitTextOutputData; + /* * This should be large enough that most strings will fit, but small enough * that we feel comfortable putting it on the stack @@ -139,7 +153,11 @@ static bytea *bytea_substring(Datum str, bool length_not_specified); static bytea *bytea_overlay(bytea *t1, bytea *t2, int sp, int sl); static void appendStringInfoText(StringInfo str, const text *t); -static Datum text_to_array_internal(PG_FUNCTION_ARGS); +static bool split_text(FunctionCallInfo fcinfo, SplitTextOutputData *tstate); +static void split_text_accum_result(SplitTextOutputData *tstate, + text *field_value, + text *null_string, + Oid collation); static text *array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, const char *fldsep, const char *null_string); static StringInfo makeStringAggState(FunctionCallInfo fcinfo); @@ -287,10 +305,12 @@ byteain(PG_FUNCTION_ARGS) if (inputText[0] == '\\' && inputText[1] == 'x') { size_t len = strlen(inputText); + uint64 dstlen = pg_hex_dec_len(len - 2); - bc = (len - 2) / 2 + VARHDRSZ; /* maximum possible length */ + bc = dstlen + VARHDRSZ; /* maximum possible length */ result = palloc(bc); - bc = hex_decode(inputText + 2, len - 2, VARDATA(result)); + + bc = pg_hex_decode(inputText + 2, len - 2, VARDATA(result), dstlen); SET_VARSIZE(result, bc + VARHDRSZ); /* actual length */ PG_RETURN_BYTEA_P(result); @@ -379,11 +399,15 @@ byteaout(PG_FUNCTION_ARGS) if (bytea_output == BYTEA_OUTPUT_HEX) { + uint64 dstlen = pg_hex_enc_len(VARSIZE_ANY_EXHDR(vlena)); + /* Print hex format */ - rp = result = palloc(VARSIZE_ANY_EXHDR(vlena) * 2 + 2 + 1); + rp = result = palloc(dstlen + 2 + 1); *rp++ = '\\'; *rp++ = 'x'; - rp += hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp); + + rp += pg_hex_encode(VARDATA_ANY(vlena), VARSIZE_ANY_EXHDR(vlena), rp, + dstlen); } else if (bytea_output == BYTEA_OUTPUT_ESCAPE) { @@ -851,29 +875,38 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified) int32 S = start; /* start position */ int32 S1; /* adjusted start position */ int32 L1; /* adjusted substring length */ + int32 E; /* end position */ + + /* + * SQL99 says S can be zero or negative, but we still must fetch from the + * start of the string. + */ + S1 = Max(S, 1); /* life is easy if the encoding max length is 1 */ if (eml == 1) { - S1 = Max(S, 1); - if (length_not_specified) /* special case - get length to end of * string */ L1 = -1; - else + else if (length < 0) + { + /* SQL99 says to throw an error for E < S, i.e., negative length */ + ereport(ERROR, + (errcode(ERRCODE_SUBSTRING_ERROR), + errmsg("negative substring length not allowed"))); + L1 = -1; /* silence stupider compilers */ + } + else if (pg_add_s32_overflow(S, length, &E)) { - /* end position */ - int E = S + length; - /* - * A negative value for L is the only way for the end position to - * be before the start. SQL99 says to throw an error. + * L could be large enough for S + L to overflow, in which case + * the substring must run to end of string. */ - if (E < S) - ereport(ERROR, - (errcode(ERRCODE_SUBSTRING_ERROR), - errmsg("negative substring length not allowed"))); - + L1 = -1; + } + else + { /* * A zero or negative value for the end position can happen if the * start was negative or one. SQL99 says to return a zero-length @@ -887,8 +920,8 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified) /* * If the start position is past the end of the string, SQL99 says to - * return a zero-length string -- PG_GETARG_TEXT_P_SLICE() will do - * that for us. Convert to zero-based starting position + * return a zero-length string -- DatumGetTextPSlice() will do that + * for us. We need only convert S1 to zero-based starting position. */ return DatumGetTextPSlice(str, S1 - 1, L1); } @@ -909,12 +942,6 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified) char *s; text *ret; - /* - * if S is past the end of the string, the tuple toaster will return a - * zero-length string to us - */ - S1 = Max(S, 1); - /* * We need to start at position zero because there is no way to know * in advance which byte offset corresponds to the supplied start @@ -925,19 +952,24 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified) if (length_not_specified) /* special case - get length to end of * string */ slice_size = L1 = -1; - else + else if (length < 0) + { + /* SQL99 says to throw an error for E < S, i.e., negative length */ + ereport(ERROR, + (errcode(ERRCODE_SUBSTRING_ERROR), + errmsg("negative substring length not allowed"))); + slice_size = L1 = -1; /* silence stupider compilers */ + } + else if (pg_add_s32_overflow(S, length, &E)) { - int E = S + length; - /* - * A negative value for L is the only way for the end position to - * be before the start. SQL99 says to throw an error. + * L could be large enough for S + L to overflow, in which case + * the substring must run to end of string. */ - if (E < S) - ereport(ERROR, - (errcode(ERRCODE_SUBSTRING_ERROR), - errmsg("negative substring length not allowed"))); - + slice_size = L1 = -1; + } + else + { /* * A zero or negative value for the end position can happen if the * start was negative or one. SQL99 says to return a zero-length @@ -955,8 +987,10 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified) /* * Total slice size in bytes can't be any longer than the start * position plus substring length times the encoding max length. + * If that overflows, we can just use -1. */ - slice_size = (S1 + L1) * eml; + if (pg_mul_s32_overflow(E, eml, &slice_size)) + slice_size = -1; } /* @@ -1423,8 +1457,7 @@ text_position_next_internal(char *start_ptr, TextPositionState *state) /* * Return a pointer to the current match. * - * The returned pointer points into correct position in the original - * the haystack string. + * The returned pointer points into the original haystack string. */ static char * text_position_get_match_ptr(TextPositionState *state) @@ -1455,12 +1488,27 @@ text_position_get_match_pos(TextPositionState *state) } } +/* + * Reset search state to the initial state installed by text_position_setup. + * + * The next call to text_position_next will search from the beginning + * of the string. + */ +static void +text_position_reset(TextPositionState *state) +{ + state->last_match = NULL; + state->refpoint = state->str1; + state->refpos = 0; +} + static void text_position_cleanup(TextPositionState *state) { /* no cleanup needed */ } + static void check_collation_set(Oid collid) { @@ -3278,9 +3326,13 @@ bytea_substring(Datum str, int L, bool length_not_specified) { - int S1; /* adjusted start position */ - int L1; /* adjusted substring length */ + int32 S1; /* adjusted start position */ + int32 L1; /* adjusted substring length */ + int32 E; /* end position */ + /* + * The logic here should generally match text_substring(). + */ S1 = Max(S, 1); if (length_not_specified) @@ -3291,20 +3343,24 @@ bytea_substring(Datum str, */ L1 = -1; } - else + else if (L < 0) + { + /* SQL99 says to throw an error for E < S, i.e., negative length */ + ereport(ERROR, + (errcode(ERRCODE_SUBSTRING_ERROR), + errmsg("negative substring length not allowed"))); + L1 = -1; /* silence stupider compilers */ + } + else if (pg_add_s32_overflow(S, L, &E)) { - /* end position */ - int E = S + L; - /* - * A negative value for L is the only way for the end position to be - * before the start. SQL99 says to throw an error. + * L could be large enough for S + L to overflow, in which case the + * substring must run to end of string. */ - if (E < S) - ereport(ERROR, - (errcode(ERRCODE_SUBSTRING_ERROR), - errmsg("negative substring length not allowed"))); - + L1 = -1; + } + else + { /* * A zero or negative value for the end position can happen if the * start was negative or one. SQL99 says to return a zero-length @@ -3319,7 +3375,7 @@ bytea_substring(Datum str, /* * If the start position is past the end of the string, SQL99 says to * return a zero-length string -- DatumGetByteaPSlice() will do that for - * us. Convert to zero-based starting position + * us. We need only convert S1 to zero-based starting position. */ return DatumGetByteaPSlice(str, S1 - 1, L1); } @@ -3384,6 +3440,17 @@ bytea_overlay(bytea *t1, bytea *t2, int sp, int sl) return result; } +/* + * bit_count + */ +Datum +bytea_bit_count(PG_FUNCTION_ARGS) +{ + bytea *t1 = PG_GETARG_BYTEA_PP(0); + + PG_RETURN_INT64(pg_popcount(VARDATA_ANY(t1), VARSIZE_ANY_EXHDR(t1))); +} + /* * byteapos - * Return the position of the specified substring. @@ -4564,13 +4631,12 @@ replace_text_regexp(text *src_text, void *regexp, } /* - * split_text - * parse input string - * return ord item (1 based) - * based on provided field separator + * split_part + * parse input string based on provided field separator + * return N'th item (1 based, negative counts from end) */ Datum -split_text(PG_FUNCTION_ARGS) +split_part(PG_FUNCTION_ARGS) { text *inputstring = PG_GETARG_TEXT_PP(0); text *fldsep = PG_GETARG_TEXT_PP(1); @@ -4584,10 +4650,10 @@ split_text(PG_FUNCTION_ARGS) bool found; /* field number is 1 based */ - if (fldnum < 1) + if (fldnum == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("field position must be greater than zero"))); + errmsg("field position must not be zero"))); inputstring_len = VARSIZE_ANY_EXHDR(inputstring); fldsep_len = VARSIZE_ANY_EXHDR(fldsep); @@ -4596,33 +4662,72 @@ split_text(PG_FUNCTION_ARGS) if (inputstring_len < 1) PG_RETURN_TEXT_P(cstring_to_text("")); - /* empty field separator */ + /* handle empty field separator */ if (fldsep_len < 1) { - text_position_cleanup(&state); - /* if first field, return input string, else empty string */ - if (fldnum == 1) + /* if first or last field, return input string, else empty string */ + if (fldnum == 1 || fldnum == -1) PG_RETURN_TEXT_P(inputstring); else PG_RETURN_TEXT_P(cstring_to_text("")); } + /* find the first field separator */ text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state); - /* identify bounds of first field */ - start_ptr = VARDATA_ANY(inputstring); found = text_position_next(&state); /* special case if fldsep not found at all */ if (!found) { text_position_cleanup(&state); - /* if field 1 requested, return input string, else empty string */ - if (fldnum == 1) + /* if first or last field, return input string, else empty string */ + if (fldnum == 1 || fldnum == -1) PG_RETURN_TEXT_P(inputstring); else PG_RETURN_TEXT_P(cstring_to_text("")); } + + /* + * take care of a negative field number (i.e. count from the right) by + * converting to a positive field number; we need total number of fields + */ + if (fldnum < 0) + { + /* we found a fldsep, so there are at least two fields */ + int numfields = 2; + + while (text_position_next(&state)) + numfields++; + + /* special case of last field does not require an extra pass */ + if (fldnum == -1) + { + start_ptr = text_position_get_match_ptr(&state) + fldsep_len; + end_ptr = VARDATA_ANY(inputstring) + inputstring_len; + text_position_cleanup(&state); + PG_RETURN_TEXT_P(cstring_to_text_with_len(start_ptr, + end_ptr - start_ptr)); + } + + /* else, convert fldnum to positive notation */ + fldnum += numfields + 1; + + /* if nonexistent field, return empty string */ + if (fldnum <= 0) + { + text_position_cleanup(&state); + PG_RETURN_TEXT_P(cstring_to_text("")); + } + + /* reset to pointing at first match, but now with positive fldnum */ + text_position_reset(&state); + found = text_position_next(&state); + Assert(found); + } + + /* identify bounds of first field */ + start_ptr = VARDATA_ANY(inputstring); end_ptr = text_position_get_match_ptr(&state); while (found && --fldnum > 0) @@ -4679,7 +4784,19 @@ text_isequal(text *txt1, text *txt2, Oid collid) Datum text_to_array(PG_FUNCTION_ARGS) { - return text_to_array_internal(fcinfo); + SplitTextOutputData tstate; + + /* For array output, tstate should start as all zeroes */ + memset(&tstate, 0, sizeof(tstate)); + + if (!split_text(fcinfo, &tstate)) + PG_RETURN_NULL(); + + if (tstate.astate == NULL) + PG_RETURN_ARRAYTYPE_P(construct_empty_array(TEXTOID)); + + PG_RETURN_ARRAYTYPE_P(makeArrayResult(tstate.astate, + CurrentMemoryContext)); } /* @@ -4693,30 +4810,90 @@ text_to_array(PG_FUNCTION_ARGS) Datum text_to_array_null(PG_FUNCTION_ARGS) { - return text_to_array_internal(fcinfo); + return text_to_array(fcinfo); } /* - * common code for text_to_array and text_to_array_null functions + * text_to_table + * parse input string and return table of elements, + * based on provided field separator + */ +Datum +text_to_table(PG_FUNCTION_ARGS) +{ + ReturnSetInfo *rsi = (ReturnSetInfo *) fcinfo->resultinfo; + SplitTextOutputData tstate; + MemoryContext old_cxt; + + /* check to see if caller supports us returning a tuplestore */ + if (rsi == NULL || !IsA(rsi, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsi->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("materialize mode required, but it is not allowed in this context"))); + + /* OK, prepare tuplestore in per-query memory */ + old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory); + + tstate.astate = NULL; + tstate.tupdesc = CreateTupleDescCopy(rsi->expectedDesc); + tstate.tupstore = tuplestore_begin_heap(true, false, work_mem); + + MemoryContextSwitchTo(old_cxt); + + (void) split_text(fcinfo, &tstate); + + tuplestore_donestoring(tstate.tupstore); + + rsi->returnMode = SFRM_Materialize; + rsi->setResult = tstate.tupstore; + rsi->setDesc = tstate.tupdesc; + + return (Datum) 0; +} + +/* + * text_to_table_null + * parse input string and return table of elements, + * based on provided field separator and null string + * + * This is a separate entry point only to prevent the regression tests from + * complaining about different argument sets for the same internal function. + */ +Datum +text_to_table_null(PG_FUNCTION_ARGS) +{ + return text_to_table(fcinfo); +} + +/* + * Common code for text_to_array, text_to_array_null, text_to_table + * and text_to_table_null functions. * * These are not strict so we have to test for null inputs explicitly. + * Returns false if result is to be null, else returns true. + * + * Note that if the result is valid but empty (zero elements), we return + * without changing *tstate --- caller must handle that case, too. */ -static Datum -text_to_array_internal(PG_FUNCTION_ARGS) +static bool +split_text(FunctionCallInfo fcinfo, SplitTextOutputData *tstate) { text *inputstring; text *fldsep; text *null_string; + Oid collation = PG_GET_COLLATION(); int inputstring_len; int fldsep_len; char *start_ptr; text *result_text; - bool is_null; - ArrayBuildState *astate = NULL; /* when input string is NULL, then result is NULL too */ if (PG_ARGISNULL(0)) - PG_RETURN_NULL(); + return false; inputstring = PG_GETARG_TEXT_PP(0); @@ -4743,35 +4920,19 @@ text_to_array_internal(PG_FUNCTION_ARGS) inputstring_len = VARSIZE_ANY_EXHDR(inputstring); fldsep_len = VARSIZE_ANY_EXHDR(fldsep); - /* return empty array for empty input string */ + /* return empty set for empty input string */ if (inputstring_len < 1) - PG_RETURN_ARRAYTYPE_P(construct_empty_array(TEXTOID)); + return true; - /* - * empty field separator: return the input string as a one-element - * array - */ + /* empty field separator: return input string as a one-element set */ if (fldsep_len < 1) { - Datum elems[1]; - bool nulls[1]; - int dims[1]; - int lbs[1]; - - /* single element can be a NULL too */ - is_null = null_string ? text_isequal(inputstring, null_string, PG_GET_COLLATION()) : false; - - elems[0] = PointerGetDatum(inputstring); - nulls[0] = is_null; - dims[0] = 1; - lbs[0] = 1; - /* XXX: this hardcodes assumptions about the text type */ - PG_RETURN_ARRAYTYPE_P(construct_md_array(elems, nulls, - 1, dims, lbs, - TEXTOID, -1, false, TYPALIGN_INT)); + split_text_accum_result(tstate, inputstring, + null_string, collation); + return true; } - text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state); + text_position_setup(inputstring, fldsep, collation, &state); start_ptr = VARDATA_ANY(inputstring); @@ -4797,16 +4958,12 @@ text_to_array_internal(PG_FUNCTION_ARGS) chunk_len = end_ptr - start_ptr; } - /* must build a temp text datum to pass to accumArrayResult */ + /* build a temp text datum to pass to split_text_accum_result */ result_text = cstring_to_text_with_len(start_ptr, chunk_len); - is_null = null_string ? text_isequal(result_text, null_string, PG_GET_COLLATION()) : false; /* stash away this field */ - astate = accumArrayResult(astate, - PointerGetDatum(result_text), - is_null, - TEXTOID, - CurrentMemoryContext); + split_text_accum_result(tstate, result_text, + null_string, collation); pfree(result_text); @@ -4821,16 +4978,12 @@ text_to_array_internal(PG_FUNCTION_ARGS) else { /* - * When fldsep is NULL, each character in the inputstring becomes an - * element in the result array. The separator is effectively the - * space between characters. + * When fldsep is NULL, each character in the input string becomes a + * separate element in the result set. The separator is effectively + * the space between characters. */ inputstring_len = VARSIZE_ANY_EXHDR(inputstring); - /* return empty array for empty input string */ - if (inputstring_len < 1) - PG_RETURN_ARRAYTYPE_P(construct_empty_array(TEXTOID)); - start_ptr = VARDATA_ANY(inputstring); while (inputstring_len > 0) @@ -4839,16 +4992,12 @@ text_to_array_internal(PG_FUNCTION_ARGS) CHECK_FOR_INTERRUPTS(); - /* must build a temp text datum to pass to accumArrayResult */ + /* build a temp text datum to pass to split_text_accum_result */ result_text = cstring_to_text_with_len(start_ptr, chunk_len); - is_null = null_string ? text_isequal(result_text, null_string, PG_GET_COLLATION()) : false; /* stash away this field */ - astate = accumArrayResult(astate, - PointerGetDatum(result_text), - is_null, - TEXTOID, - CurrentMemoryContext); + split_text_accum_result(tstate, result_text, + null_string, collation); pfree(result_text); @@ -4857,8 +5006,47 @@ text_to_array_internal(PG_FUNCTION_ARGS) } } - PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, - CurrentMemoryContext)); + return true; +} + +/* + * Add text item to result set (table or array). + * + * This is also responsible for checking to see if the item matches + * the null_string, in which case we should emit NULL instead. + */ +static void +split_text_accum_result(SplitTextOutputData *tstate, + text *field_value, + text *null_string, + Oid collation) +{ + bool is_null = false; + + if (null_string && text_isequal(field_value, null_string, collation)) + is_null = true; + + if (tstate->tupstore) + { + Datum values[1]; + bool nulls[1]; + + values[0] = PointerGetDatum(field_value); + nulls[0] = is_null; + + tuplestore_putvalues(tstate->tupstore, + tstate->tupdesc, + values, + nulls); + } + else + { + tstate->astate = accumArrayResult(tstate->astate, + PointerGetDatum(field_value), + is_null, + TEXTOID, + CurrentMemoryContext); + } } /* @@ -5123,6 +5311,59 @@ pg_column_size(PG_FUNCTION_ARGS) PG_RETURN_INT32(result); } +/* + * Return the compression method stored in the compressed attribute. Return + * NULL for non varlena type or uncompressed data. + */ +Datum +pg_column_compression(PG_FUNCTION_ARGS) +{ + int typlen; + char *result; + ToastCompressionId cmid; + + /* On first call, get the input type's typlen, and save at *fn_extra */ + if (fcinfo->flinfo->fn_extra == NULL) + { + /* Lookup the datatype of the supplied argument */ + Oid argtypeid = get_fn_expr_argtype(fcinfo->flinfo, 0); + + typlen = get_typlen(argtypeid); + if (typlen == 0) /* should not happen */ + elog(ERROR, "cache lookup failed for type %u", argtypeid); + + fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, + sizeof(int)); + *((int *) fcinfo->flinfo->fn_extra) = typlen; + } + else + typlen = *((int *) fcinfo->flinfo->fn_extra); + + if (typlen != -1) + PG_RETURN_NULL(); + + /* get the compression method id stored in the compressed varlena */ + cmid = toast_get_compression_id((struct varlena *) + DatumGetPointer(PG_GETARG_DATUM(0))); + if (cmid == TOAST_INVALID_COMPRESSION_ID) + PG_RETURN_NULL(); + + /* convert compression method id to compression method name */ + switch (cmid) + { + case TOAST_PGLZ_COMPRESSION_ID: + result = "pglz"; + break; + case TOAST_LZ4_COMPRESSION_ID: + result = "lz4"; + break; + default: + elog(ERROR, "invalid compression method id %d", cmid); + } + + PG_RETURN_TEXT_P(cstring_to_text(result)); +} + /* * string_agg - Concatenates values and returns string. * @@ -6082,7 +6323,7 @@ unicode_normalize_func(PG_FUNCTION_ARGS) /* * Check whether the string is in the specified Unicode normalization form. * - * This is done by convering the string to the specified normal form and then + * This is done by converting the string to the specified normal form and then * comparing that to the original string. To speed that up, we also apply the * "quick check" algorithm specified in UAX #15, which can give a yes or no * answer for many strings by just scanning the string once. @@ -6139,3 +6380,214 @@ unicode_is_normalized(PG_FUNCTION_ARGS) PG_RETURN_BOOL(result); } + +/* + * Check if first n chars are hexadecimal digits + */ +static bool +isxdigits_n(const char *instr, size_t n) +{ + for (size_t i = 0; i < n; i++) + if (!isxdigit((unsigned char) instr[i])) + return false; + + return true; +} + +static unsigned int +hexval(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 0xA; + if (c >= 'A' && c <= 'F') + return c - 'A' + 0xA; + elog(ERROR, "invalid hexadecimal digit"); + return 0; /* not reached */ +} + +/* + * Translate string with hexadecimal digits to number + */ +static unsigned int +hexval_n(const char *instr, size_t n) +{ + unsigned int result = 0; + + for (size_t i = 0; i < n; i++) + result += hexval(instr[i]) << (4 * (n - i - 1)); + + return result; +} + +/* + * Replaces Unicode escape sequences by Unicode characters + */ +Datum +unistr(PG_FUNCTION_ARGS) +{ + text *input_text = PG_GETARG_TEXT_PP(0); + char *instr; + int len; + StringInfoData str; + text *result; + pg_wchar pair_first = 0; + char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1]; + + instr = VARDATA_ANY(input_text); + len = VARSIZE_ANY_EXHDR(input_text); + + initStringInfo(&str); + + while (len > 0) + { + if (instr[0] == '\\') + { + if (len >= 2 && + instr[1] == '\\') + { + if (pair_first) + goto invalid_pair; + appendStringInfoChar(&str, '\\'); + instr += 2; + len -= 2; + } + else if ((len >= 5 && isxdigits_n(instr + 1, 4)) || + (len >= 6 && instr[1] == 'u' && isxdigits_n(instr + 2, 4))) + { + pg_wchar unicode; + int offset = instr[1] == 'u' ? 2 : 1; + + unicode = hexval_n(instr + offset, 4); + + if (!is_valid_unicode_codepoint(unicode)) + ereport(ERROR, + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid Unicode code point: %04X", unicode)); + + if (pair_first) + { + if (is_utf16_surrogate_second(unicode)) + { + unicode = surrogate_pair_to_codepoint(pair_first, unicode); + pair_first = 0; + } + else + goto invalid_pair; + } + else if (is_utf16_surrogate_second(unicode)) + goto invalid_pair; + + if (is_utf16_surrogate_first(unicode)) + pair_first = unicode; + else + { + pg_unicode_to_server(unicode, (unsigned char *) cbuf); + appendStringInfoString(&str, cbuf); + } + + instr += 4 + offset; + len -= 4 + offset; + } + else if (len >= 8 && instr[1] == '+' && isxdigits_n(instr + 2, 6)) + { + pg_wchar unicode; + + unicode = hexval_n(instr + 2, 6); + + if (!is_valid_unicode_codepoint(unicode)) + ereport(ERROR, + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid Unicode code point: %04X", unicode)); + + if (pair_first) + { + if (is_utf16_surrogate_second(unicode)) + { + unicode = surrogate_pair_to_codepoint(pair_first, unicode); + pair_first = 0; + } + else + goto invalid_pair; + } + else if (is_utf16_surrogate_second(unicode)) + goto invalid_pair; + + if (is_utf16_surrogate_first(unicode)) + pair_first = unicode; + else + { + pg_unicode_to_server(unicode, (unsigned char *) cbuf); + appendStringInfoString(&str, cbuf); + } + + instr += 8; + len -= 8; + } + else if (len >= 10 && instr[1] == 'U' && isxdigits_n(instr + 2, 8)) + { + pg_wchar unicode; + + unicode = hexval_n(instr + 2, 8); + + if (!is_valid_unicode_codepoint(unicode)) + ereport(ERROR, + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid Unicode code point: %04X", unicode)); + + if (pair_first) + { + if (is_utf16_surrogate_second(unicode)) + { + unicode = surrogate_pair_to_codepoint(pair_first, unicode); + pair_first = 0; + } + else + goto invalid_pair; + } + else if (is_utf16_surrogate_second(unicode)) + goto invalid_pair; + + if (is_utf16_surrogate_first(unicode)) + pair_first = unicode; + else + { + pg_unicode_to_server(unicode, (unsigned char *) cbuf); + appendStringInfoString(&str, cbuf); + } + + instr += 10; + len -= 10; + } + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid Unicode escape"), + errhint("Unicode escapes must be \\XXXX, \\+XXXXXX, \\uXXXX, or \\UXXXXXXXX."))); + } + else + { + if (pair_first) + goto invalid_pair; + + appendStringInfoChar(&str, *instr++); + len--; + } + } + + /* unfinished surrogate pair? */ + if (pair_first) + goto invalid_pair; + + result = cstring_to_text_with_len(str.data, str.len); + pfree(str.data); + + PG_RETURN_TEXT_P(result); + +invalid_pair: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid Unicode surrogate pair"))); + PG_RETURN_NULL(); /* keep compiler quiet */ +} diff --git a/src/backend/utils/adt/version.c b/src/backend/utils/adt/version.c index b9e6c6db20fb..aa4ba3e85eef 100644 --- a/src/backend/utils/adt/version.c +++ b/src/backend/utils/adt/version.c @@ -3,7 +3,7 @@ * version.c * Returns the PostgreSQL version string * - * Copyright (c) 1998-2020, PostgreSQL Global Development Group + * Copyright (c) 1998-2021, PostgreSQL Global Development Group * * IDENTIFICATION * diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c index f0c8ae686dd4..9c127617d1e1 100644 --- a/src/backend/utils/adt/windowfuncs.c +++ b/src/backend/utils/adt/windowfuncs.c @@ -3,7 +3,7 @@ * windowfuncs.c * Standard window functions defined in SQL spec. * - * Portions Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2000-2021, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/xid.c b/src/backend/utils/adt/xid.c index 20389aff1d12..24c1c9373265 100644 --- a/src/backend/utils/adt/xid.c +++ b/src/backend/utils/adt/xid.c @@ -3,7 +3,7 @@ * xid.c * POSTGRES transaction identifier and command identifier datatypes. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -23,9 +23,6 @@ #include "utils/builtins.h" #include "utils/xid8.h" -#define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n)) -#define PG_RETURN_TRANSACTIONID(x) return TransactionIdGetDatum(x) - #define PG_GETARG_COMMANDID(n) DatumGetCommandId(PG_GETARG_DATUM(n)) #define PG_RETURN_COMMANDID(x) return CommandIdGetDatum(x) diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c index c4401f4adf72..cc2b4ac7979a 100644 --- a/src/backend/utils/adt/xid8funcs.c +++ b/src/backend/utils/adt/xid8funcs.c @@ -15,7 +15,7 @@ * users. The txid_XXX variants should eventually be dropped. * * - * Copyright (c) 2003-2020, PostgreSQL Global Development Group + * Copyright (c) 2003-2021, PostgreSQL Global Development Group * Author: Jan Wieck, Afilias USA INC. * 64-bit txids: Marko Kreen, Skype Technologies * diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 52a959763500..5b566cda6e1a 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -4,7 +4,7 @@ * XML data type support. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/utils/adt/xml.c @@ -223,7 +223,7 @@ const TableFuncRoutine XmlTableRoutine = (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), \ errmsg("unsupported XML feature"), \ errdetail("This functionality requires the server to be built with libxml support."), \ - errhint("You need to rebuild PostgreSQL using --with-libxml."))) + errhint("You need to rebuild PostgreSQL using %s.", "--with-libxml"))) /* from SQL/XML:2008 section 4.9 */ @@ -4556,13 +4556,7 @@ XmlTableFetchRow(TableFuncScanState *state) xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableFetchRow"); - /* - * XmlTable returns table - set of composite values. The error context, is - * used for producement more values, between two calls, there can be - * created and used another libxml2 error context. It is libxml2 global - * value, so it should be refreshed any time before any libxml2 usage, - * that is finished by returning some value. - */ + /* Propagate our own error context to libxml2 */ xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler); if (xtCxt->xpathobj == NULL) @@ -4616,7 +4610,7 @@ XmlTableGetValue(TableFuncScanState *state, int colnum, xtCxt->xpathobj->type == XPATH_NODESET && xtCxt->xpathobj->nodesetval != NULL); - /* Propagate context related error context to libxml2 */ + /* Propagate our own error context to libxml2 */ xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler); *isnull = false; @@ -4759,7 +4753,7 @@ XmlTableDestroyOpaque(TableFuncScanState *state) xtCxt = GetXmlTableBuilderPrivateData(state, "XmlTableDestroyOpaque"); - /* Propagate context related error context to libxml2 */ + /* Propagate our own error context to libxml2 */ xmlSetStructuredErrorFunc((void *) xtCxt->xmlerrcxt, xml_errorHandler); if (xtCxt->xpathscomp != NULL) diff --git a/src/backend/utils/cache/attoptcache.c b/src/backend/utils/cache/attoptcache.c index 05ac366b40d4..72d89cb64164 100644 --- a/src/backend/utils/cache/attoptcache.c +++ b/src/backend/utils/cache/attoptcache.c @@ -6,7 +6,7 @@ * Attribute options are cached separately from the fixed-size portion of * pg_attribute entries, which are handled by the relcache. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -79,7 +79,6 @@ InitializeAttoptCache(void) HASHCTL ctl; /* Initialize the hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(AttoptCacheKey); ctl.entrysize = sizeof(AttoptCacheEntry); AttoptCacheHash = diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 7c66dcab1a46..90f01cdae507 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -3,7 +3,7 @@ * catcache.c * System catalog cache for tuples matching a key. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1077,8 +1077,9 @@ InitCatCachePhase2(CatCache *cache, bool touch_index) * criticalRelcachesBuilt), we don't have to worry anymore. * * Similarly, during backend startup we have to be able to use the - * pg_authid and pg_auth_members syscaches for authentication even if - * we don't yet have relcache entries for those catalogs' indexes. + * pg_authid, pg_auth_members and pg_database syscaches for + * authentication even if we don't yet have relcache entries for those + * catalogs' indexes. */ static bool IndexScanOK(CatCache *cache, ScanKey cur_skey) @@ -1111,6 +1112,7 @@ IndexScanOK(CatCache *cache, ScanKey cur_skey) case AUTHNAME: case AUTHOID: case AUTHMEMMEMROLE: + case DATABASEOID: /* * Protect authentication lookups occurring before relcache has @@ -1560,7 +1562,7 @@ GetCatCacheHashValue(CatCache *cache, * It doesn't make any sense to specify all of the cache's key columns * here: since the key is unique, there could be at most one match, so * you ought to use SearchCatCache() instead. Hence this function takes - * one less Datum argument than SearchCatCache() does. + * one fewer Datum argument than SearchCatCache() does. * * The caller must not modify the list object or the pointed-to tuples, * and must call ReleaseCatCacheList() when done with the list. diff --git a/src/backend/utils/cache/evtcache.c b/src/backend/utils/cache/evtcache.c index 73d091d1f63c..460b720a6512 100644 --- a/src/backend/utils/cache/evtcache.c +++ b/src/backend/utils/cache/evtcache.c @@ -3,7 +3,7 @@ * evtcache.c * Special-purpose cache for event trigger data. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,7 +16,6 @@ #include "access/genam.h" #include "access/htup_details.h" #include "access/relation.h" -#include "catalog/indexing.h" #include "catalog/pg_event_trigger.h" #include "catalog/pg_type.h" #include "commands/trigger.h" @@ -119,7 +118,6 @@ BuildEventTriggerCache(void) EventTriggerCacheState = ETCS_REBUILD_STARTED; /* Create new hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(EventTriggerEvent); ctl.entrysize = sizeof(EventTriggerCacheEntry); ctl.hcxt = EventTriggerCacheContext; diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index be8188ae92c0..834ce04b3caf 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -89,7 +89,7 @@ * support the decoding of the in-progress transactions. See * CommandEndInvalidationMessages. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -109,6 +109,7 @@ #include "storage/sinval.h" #include "storage/smgr.h" #include "utils/catcache.h" +#include "utils/guc.h" #include "utils/inval.h" #include "utils/memdebug.h" #include "utils/memutils.h" @@ -182,6 +183,8 @@ static SharedInvalidationMessage *SharedInvalidMessagesArray; static int numSharedInvalidMessagesArray; static int maxSharedInvalidMessagesArray; +/* GUC storage */ +int debug_invalidate_system_caches_always = 0; /* * Dynamically-registered callback functions. Current implementation @@ -667,9 +670,9 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg) else if (msg->id == SHAREDINVALSNAPSHOT_ID) { /* We only care about our own database and shared catalogs */ - if (msg->rm.dbId == InvalidOid) + if (msg->sn.dbId == InvalidOid) InvalidateCatalogSnapshot(); - else if (msg->rm.dbId == MyDatabaseId) + else if (msg->sn.dbId == MyDatabaseId) InvalidateCatalogSnapshot(); } else @@ -739,35 +742,33 @@ AcceptInvalidationMessages(void) /* * Test code to force cache flushes anytime a flush could happen. * - * If used with CLOBBER_FREED_MEMORY, CLOBBER_CACHE_ALWAYS provides a - * fairly thorough test that the system contains no cache-flush hazards. - * However, it also makes the system unbelievably slow --- the regression - * tests take about 100 times longer than normal. + * This helps detect intermittent faults caused by code that reads a cache + * entry and then performs an action that could invalidate the entry, but + * rarely actually does so. This can spot issues that would otherwise + * only arise with badly timed concurrent DDL, for example. + * + * The default debug_invalidate_system_caches_always = 0 does no forced + * cache flushes. * - * If you're a glutton for punishment, try CLOBBER_CACHE_RECURSIVELY. This - * slows things by at least a factor of 10000, so I wouldn't suggest + * If used with CLOBBER_FREED_MEMORY, + * debug_invalidate_system_caches_always = 1 (CLOBBER_CACHE_ALWAYS) + * provides a fairly thorough test that the system contains no cache-flush + * hazards. However, it also makes the system unbelievably slow --- the + * regression tests take about 100 times longer than normal. + * + * If you're a glutton for punishment, try + * debug_invalidate_system_caches_always = 3 (CLOBBER_CACHE_RECURSIVELY). + * This slows things by at least a factor of 10000, so I wouldn't suggest * trying to run the entire regression tests that way. It's useful to try * a few simple tests, to make sure that cache reload isn't subject to * internal cache-flush hazards, but after you've done a few thousand * recursive reloads it's unlikely you'll learn more. */ -#if defined(CLOBBER_CACHE_ALWAYS) - { - static bool in_recursion = false; - - if (!in_recursion) - { - in_recursion = true; - InvalidateSystemCaches(); - in_recursion = false; - } - } -#elif defined(CLOBBER_CACHE_RECURSIVELY) +#ifdef CLOBBER_CACHE_ENABLED { static int recursion_depth = 0; - /* Maximum depth is arbitrary depending on your threshold of pain */ - if (recursion_depth < 3) + if (recursion_depth < debug_invalidate_system_caches_always) { recursion_depth++; InvalidateSystemCaches(); diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index ea3796ebd1d5..35edbd60e0e1 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2007-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -1021,10 +1021,37 @@ get_attnum(Oid relid, const char *attname) return InvalidAttrNumber; } +/* + * get_attstattarget + * + * Given the relation id and the attribute number, + * return the "attstattarget" field from the attribute relation. + * + * Errors if not found. + */ +int +get_attstattarget(Oid relid, AttrNumber attnum) +{ + HeapTuple tp; + Form_pg_attribute att_tup; + int result; + + tp = SearchSysCache2(ATTNUM, + ObjectIdGetDatum(relid), + Int16GetDatum(attnum)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for attribute %d of relation %u", + attnum, relid); + att_tup = (Form_pg_attribute) GETSTRUCT(tp); + result = att_tup->attstattarget; + ReleaseSysCache(tp); + return result; +} + /* * get_attgenerated * - * Given the relation id and the attribute name, + * Given the relation id and the attribute number, * return the "attgenerated" field from the attribute relation. * * Errors if not found. @@ -1257,6 +1284,33 @@ get_constraint_name(Oid conoid) return NULL; } +/* + * get_constraint_index + * Given the OID of a unique, primary-key, or exclusion constraint, + * return the OID of the underlying index. + * + * Return InvalidOid if the index couldn't be found; this suggests the + * given OID is bogus, but we leave it to caller to decide what to do. + */ +Oid +get_constraint_index(Oid conoid) +{ + HeapTuple tp; + + tp = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conoid)); + if (HeapTupleIsValid(tp)) + { + Form_pg_constraint contup = (Form_pg_constraint) GETSTRUCT(tp); + Oid result; + + result = contup->conindid; + ReleaseSysCache(tp); + return result; + } + else + return InvalidOid; +} + /* ---------- LANGUAGE CACHE ---------- */ char * @@ -1521,13 +1575,18 @@ op_hashjoinable(Oid opno, Oid inputtype) TypeCacheEntry *typentry; /* As in op_mergejoinable, let the typcache handle the hard cases */ - /* Eventually we'll need a similar case for record_eq ... */ if (opno == ARRAY_EQ_OP) { typentry = lookup_type_cache(inputtype, TYPECACHE_HASH_PROC); if (typentry->hash_proc == F_HASH_ARRAY) result = true; } + else if (opno == RECORD_EQ_OP) + { + typentry = lookup_type_cache(inputtype, TYPECACHE_HASH_PROC); + if (typentry->hash_proc == F_HASH_RECORD) + result = true; + } else { /* For all other operators, rely on pg_operator.oprcanhash */ @@ -3124,6 +3183,16 @@ type_is_range(Oid typid) return (get_typtype(typid) == TYPTYPE_RANGE); } +/* + * type_is_multirange + * Returns true if the given type is a multirange type. + */ +bool +type_is_multirange(Oid typid) +{ + return (get_typtype(typid) == TYPTYPE_MULTIRANGE); +} + /* * get_type_category_preferred * @@ -3175,8 +3244,9 @@ get_typ_typrelid(Oid typid) * * Given the type OID, get the typelem (InvalidOid if not an array type). * - * NB: this only considers varlena arrays to be true arrays; InvalidOid is - * returned if the input is a fixed-length array type. + * NB: this only succeeds for "true" arrays having array_subscript_handler + * as typsubscript. For other types, InvalidOid is returned independently + * of whether they have typelem or typsubscript set. */ Oid get_element_type(Oid typid) @@ -3189,7 +3259,7 @@ get_element_type(Oid typid) Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp); Oid result; - if (typtup->typlen == -1) + if (IsTrueArrayType(typtup)) result = typtup->typelem; else result = InvalidOid; @@ -3272,7 +3342,7 @@ get_base_element_type(Oid typid) Oid result; /* This test must match get_element_type */ - if (typTup->typlen == -1) + if (IsTrueArrayType(typTup)) result = typTup->typelem; else result = InvalidOid; @@ -3507,6 +3577,61 @@ type_is_collatable(Oid typid) } +/* + * get_typsubscript + * + * Given the type OID, return the type's subscripting handler's OID, + * if it has one. + * + * If typelemp isn't NULL, we also store the type's typelem value there. + * This saves some callers an extra catalog lookup. + */ +RegProcedure +get_typsubscript(Oid typid, Oid *typelemp) +{ + HeapTuple tp; + + tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); + if (HeapTupleIsValid(tp)) + { + Form_pg_type typform = (Form_pg_type) GETSTRUCT(tp); + RegProcedure handler = typform->typsubscript; + + if (typelemp) + *typelemp = typform->typelem; + ReleaseSysCache(tp); + return handler; + } + else + { + if (typelemp) + *typelemp = InvalidOid; + return InvalidOid; + } +} + +/* + * getSubscriptingRoutines + * + * Given the type OID, fetch the type's subscripting methods struct. + * Return NULL if type is not subscriptable. + * + * If typelemp isn't NULL, we also store the type's typelem value there. + * This saves some callers an extra catalog lookup. + */ +const struct SubscriptRoutines * +getSubscriptingRoutines(Oid typid, Oid *typelemp) +{ + RegProcedure typsubscript = get_typsubscript(typid, typelemp); + + if (!OidIsValid(typsubscript)) + return NULL; + + return (const struct SubscriptRoutines *) + DatumGetPointer(OidFunctionCall0(typsubscript)); +} + + /* ---------- STATISTICS CACHE ---------- */ /* @@ -3817,7 +3942,7 @@ get_namespace_name_or_temp(Oid nspid) return get_namespace_name(nspid); } -/* ---------- PG_RANGE CACHE ---------- */ +/* ---------- PG_RANGE CACHES ---------- */ /* * get_range_subtype @@ -4574,6 +4699,56 @@ get_range_collation(Oid rangeOid) return InvalidOid; } +/* + * get_range_multirange + * Returns the multirange type of a given range type + * + * Returns InvalidOid if the type is not a range type. + */ +Oid +get_range_multirange(Oid rangeOid) +{ + HeapTuple tp; + + tp = SearchSysCache1(RANGETYPE, ObjectIdGetDatum(rangeOid)); + if (HeapTupleIsValid(tp)) + { + Form_pg_range rngtup = (Form_pg_range) GETSTRUCT(tp); + Oid result; + + result = rngtup->rngmultitypid; + ReleaseSysCache(tp); + return result; + } + else + return InvalidOid; +} + +/* + * get_multirange_range + * Returns the range type of a given multirange + * + * Returns InvalidOid if the type is not a multirange. + */ +Oid +get_multirange_range(Oid multirangeOid) +{ + HeapTuple tp; + + tp = SearchSysCache1(RANGEMULTIRANGE, ObjectIdGetDatum(multirangeOid)); + if (HeapTupleIsValid(tp)) + { + Form_pg_range rngtup = (Form_pg_range) GETSTRUCT(tp); + Oid result; + + result = rngtup->rngtypid; + ReleaseSysCache(tp); + return result; + } + else + return InvalidOid; +} + /* ---------- PG_INDEX CACHE ---------- */ /* diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c index acf8a44f30fc..21e60f0c5e81 100644 --- a/src/backend/utils/cache/partcache.c +++ b/src/backend/utils/cache/partcache.c @@ -4,7 +4,7 @@ * Support routines for manipulating partition information cached in * relcache * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -341,6 +341,7 @@ generate_partition_qual(Relation rel) bool isnull; List *my_qual = NIL, *result = NIL; + Oid parentrelid; Relation parent; /* Guard against stack overflow due to overly deep partition tree */ @@ -350,9 +351,14 @@ generate_partition_qual(Relation rel) if (rel->rd_partcheckvalid) return copyObject(rel->rd_partcheck); - /* Grab at least an AccessShareLock on the parent table */ - parent = relation_open(get_partition_parent(RelationGetRelid(rel)), - AccessShareLock); + /* + * Grab at least an AccessShareLock on the parent table. Must do this + * even if the partition has been partially detached, because transactions + * concurrent with the detach might still be trying to use a partition + * descriptor that includes it. + */ + parentrelid = get_partition_parent(RelationGetRelid(rel), true); + parent = relation_open(parentrelid, AccessShareLock); /* Get pg_class.relpartbound */ tuple = SearchSysCache1(RELOID, RelationGetRelid(rel)); diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index f9c22710e6d1..96d81db56d8e 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -44,7 +44,7 @@ * if the old one gets invalidated. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -542,7 +542,7 @@ ReleaseGenericPlan(CachedPlanSource *plansource) Assert(plan->magic == CACHEDPLAN_MAGIC); plansource->gplan = NULL; - ReleaseCachedPlan(plan, false); + ReleaseCachedPlan(plan, NULL); } } @@ -930,8 +930,9 @@ BuildCachedPlan(CachedPlanSource *plansource, List *qlist, * rejected a generic plan, it's possible to reach here with is_valid * false due to an invalidation while making the generic plan. In theory * the invalidation must be a false positive, perhaps a consequence of an - * sinval reset event or the CLOBBER_CACHE_ALWAYS debug code. But for - * safety, let's treat it as real and redo the RevalidateCachedQuery call. + * sinval reset event or the debug_invalidate_system_caches_always code. + * But for safety, let's treat it as real and redo the + * RevalidateCachedQuery call. */ if (!plansource->is_valid) qlist = RevalidateCachedQuery(plansource, queryEnv, intoClause); @@ -1249,9 +1250,9 @@ cached_plan_cost(CachedPlan *plan, bool include_planner) * execution. * * On return, the refcount of the plan has been incremented; a later - * ReleaseCachedPlan() call is expected. The refcount has been reported - * to the CurrentResourceOwner if useResOwner is true (note that that must - * only be true if it's a "saved" CachedPlanSource). + * ReleaseCachedPlan() call is expected. If "owner" is not NULL then + * the refcount has been reported to that ResourceOwner (note that this + * is only supported for "saved" CachedPlanSources). * * Note: if any replanning activity is required, the caller's memory context * is used for that work. @@ -1266,7 +1267,8 @@ cached_plan_cost(CachedPlan *plan, bool include_planner) */ CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, - bool useResOwner, QueryEnvironment *queryEnv, IntoClause *intoClause) + ResourceOwner owner, QueryEnvironment *queryEnv, + IntoClause *intoClause) { CachedPlan *plan = NULL; List *qlist; @@ -1276,7 +1278,7 @@ GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); Assert(plansource->is_complete); /* This seems worth a real test, though */ - if (useResOwner && !plansource->is_saved) + if (owner && !plansource->is_saved) elog(ERROR, "cannot apply ResourceOwner to non-saved cached plan"); /* Make sure the querytree list is valid and we have parse-time locks */ @@ -1355,11 +1357,11 @@ GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, Assert(plan != NULL); /* Flag the plan as in use by caller */ - if (useResOwner) - ResourceOwnerEnlargePlanCacheRefs(CurrentResourceOwner); + if (owner) + ResourceOwnerEnlargePlanCacheRefs(owner); plan->refcount++; - if (useResOwner) - ResourceOwnerRememberPlanCacheRef(CurrentResourceOwner, plan); + if (owner) + ResourceOwnerRememberPlanCacheRef(owner, plan); /* * Saved plans should be under CacheMemoryContext so they will not go away @@ -1380,21 +1382,21 @@ GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, * ReleaseCachedPlan: release active use of a cached plan. * * This decrements the reference count, and frees the plan if the count - * has thereby gone to zero. If useResOwner is true, it is assumed that - * the reference count is managed by the CurrentResourceOwner. + * has thereby gone to zero. If "owner" is not NULL, it is assumed that + * the reference count is managed by that ResourceOwner. * - * Note: useResOwner = false is used for releasing references that are in + * Note: owner == NULL is used for releasing references that are in * persistent data structures, such as the parent CachedPlanSource or a * Portal. Transient references should be protected by a resource owner. */ void -ReleaseCachedPlan(CachedPlan *plan, bool useResOwner) +ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner) { Assert(plan->magic == CACHEDPLAN_MAGIC); - if (useResOwner) + if (owner) { Assert(plan->is_saved); - ResourceOwnerForgetPlanCacheRef(CurrentResourceOwner, plan); + ResourceOwnerForgetPlanCacheRef(owner, plan); } Assert(plan->refcount > 0); plan->refcount--; diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index f79f3bd7b180..7e84482aec16 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2009, Greenplum inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -101,15 +101,15 @@ #define RELCACHE_INIT_FILEMAGIC 0x773266 /* version ID value */ /* - * Default policy for whether to apply RECOVER_RELATION_BUILD_MEMORY: - * do so in clobber-cache builds but not otherwise. This choice can be - * overridden at compile time with -DRECOVER_RELATION_BUILD_MEMORY=1 or =0. + * Whether to bother checking if relation cache memory needs to be freed + * eagerly. See also RelationBuildDesc() and pg_config_manual.h. */ -#ifndef RECOVER_RELATION_BUILD_MEMORY -#if defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY) -#define RECOVER_RELATION_BUILD_MEMORY 1 +#if defined(RECOVER_RELATION_BUILD_MEMORY) && (RECOVER_RELATION_BUILD_MEMORY != 0) +#define MAYBE_RECOVER_RELATION_BUILD_MEMORY 1 #else #define RECOVER_RELATION_BUILD_MEMORY 0 +#ifdef CLOBBER_CACHE_ENABLED +#define MAYBE_RECOVER_RELATION_BUILD_MEMORY 1 #endif #endif @@ -294,7 +294,8 @@ static void RelationInitPhysicalAddr(Relation relation); static void load_critical_index(Oid indexoid, Oid heapoid); static TupleDesc GetPgClassDescriptor(void); static TupleDesc GetPgIndexDescriptor(void); -static void AttrDefaultFetch(Relation relation); +static void AttrDefaultFetch(Relation relation, int ndef); +static int AttrDefaultCmp(const void *a, const void *b); static void CheckConstraintFetch(Relation relation); static int CheckConstraintCmp(const void *a, const void *b); static void InitIndexAmRoutine(Relation relation); @@ -520,7 +521,6 @@ RelationBuildTupleDesc(Relation relation) ScanKeyData skey[2]; int need; TupleConstr *constr; - AttrDefault *attrdef = NULL; AttrMissing *attrmiss = NULL; int ndef = 0; @@ -529,8 +529,8 @@ RelationBuildTupleDesc(Relation relation) relation->rd_rel->reltype ? relation->rd_rel->reltype : RECORDOID; relation->rd_att->tdtypmod = -1; /* just to be sure */ - constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext, - sizeof(TupleConstr)); + constr = (TupleConstr *) MemoryContextAllocZero(CacheMemoryContext, + sizeof(TupleConstr)); constr->has_not_null = false; constr->has_generated_stored = false; @@ -574,10 +574,9 @@ RelationBuildTupleDesc(Relation relation) attnum = attp->attnum; if (attnum <= 0 || attnum > RelationGetNumberOfAttributes(relation)) - elog(ERROR, "invalid attribute number %d for %s", + elog(ERROR, "invalid attribute number %d for relation \"%s\"", attp->attnum, RelationGetRelationName(relation)); - memcpy(TupleDescAttr(relation->rd_att, attnum - 1), attp, ATTRIBUTE_FIXED_PART_SIZE); @@ -587,22 +586,10 @@ RelationBuildTupleDesc(Relation relation) constr->has_not_null = true; if (attp->attgenerated == ATTRIBUTE_GENERATED_STORED) constr->has_generated_stored = true; - - /* If the column has a default, fill it into the attrdef array */ if (attp->atthasdef) - { - if (attrdef == NULL) - attrdef = (AttrDefault *) - MemoryContextAllocZero(CacheMemoryContext, - RelationGetNumberOfAttributes(relation) * - sizeof(AttrDefault)); - attrdef[ndef].adnum = attnum; - attrdef[ndef].adbin = NULL; - ndef++; - } - /* Likewise for a missing value */ + /* If the column has a "missing" value, put it in the attrmiss array */ if (attp->atthasmissing) { Datum missingval; @@ -665,7 +652,7 @@ RelationBuildTupleDesc(Relation relation) table_close(pg_attribute_desc, AccessShareLock); if (need != 0) - elog(ERROR, "catalog is missing %d attribute(s) for relid %u", + elog(ERROR, "pg_attribute catalog is missing %d attribute(s) for relation OID %u", need, RelationGetRelid(relation)); /* @@ -697,33 +684,19 @@ RelationBuildTupleDesc(Relation relation) constr->has_generated_stored || ndef > 0 || attrmiss || - relation->rd_rel->relchecks) + relation->rd_rel->relchecks > 0) { relation->rd_att->constr = constr; if (ndef > 0) /* DEFAULTs */ - { - if (ndef < RelationGetNumberOfAttributes(relation)) - constr->defval = (AttrDefault *) - repalloc(attrdef, ndef * sizeof(AttrDefault)); - else - constr->defval = attrdef; - constr->num_defval = ndef; - AttrDefaultFetch(relation); - } + AttrDefaultFetch(relation, ndef); else constr->num_defval = 0; constr->missing = attrmiss; if (relation->rd_rel->relchecks > 0) /* CHECKs */ - { - constr->num_check = relation->rd_rel->relchecks; - constr->check = (ConstrCheck *) - MemoryContextAllocZero(CacheMemoryContext, - constr->num_check * sizeof(ConstrCheck)); CheckConstraintFetch(relation); - } else constr->num_check = 0; } @@ -1057,19 +1030,25 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) * scope, and relcache loads shouldn't happen so often that it's essential * to recover transient data before end of statement/transaction. However * that's definitely not true in clobber-cache test builds, and perhaps - * it's not true in other cases. If RECOVER_RELATION_BUILD_MEMORY is not - * zero, arrange to allocate the junk in a temporary context that we'll - * free before returning. Make it a child of caller's context so that it - * will get cleaned up appropriately if we error out partway through. + * it's not true in other cases. + * + * When cache clobbering is enabled or when forced to by + * RECOVER_RELATION_BUILD_MEMORY=1, arrange to allocate the junk in a + * temporary context that we'll free before returning. Make it a child of + * caller's context so that it will get cleaned up appropriately if we + * error out partway through. */ -#if RECOVER_RELATION_BUILD_MEMORY - MemoryContext tmpcxt; - MemoryContext oldcxt; +#ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY + MemoryContext tmpcxt = NULL; + MemoryContext oldcxt = NULL; - tmpcxt = AllocSetContextCreate(CurrentMemoryContext, - "RelationBuildDesc workspace", - ALLOCSET_DEFAULT_SIZES); - oldcxt = MemoryContextSwitchTo(tmpcxt); + if (RECOVER_RELATION_BUILD_MEMORY || debug_invalidate_system_caches_always > 0) + { + tmpcxt = AllocSetContextCreate(CurrentMemoryContext, + "RelationBuildDesc workspace", + ALLOCSET_DEFAULT_SIZES); + oldcxt = MemoryContextSwitchTo(tmpcxt); + } #endif /* @@ -1082,10 +1061,13 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) */ if (!HeapTupleIsValid(pg_class_tuple)) { -#if RECOVER_RELATION_BUILD_MEMORY - /* Return to caller's context, and blow away the temporary context */ - MemoryContextSwitchTo(oldcxt); - MemoryContextDelete(tmpcxt); +#ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY + if (tmpcxt) + { + /* Return to caller's context, and blow away the temporary context */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(tmpcxt); + } #endif return NULL; } @@ -1191,7 +1173,10 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) relation->rd_partkey = NULL; relation->rd_partkeycxt = NULL; relation->rd_partdesc = NULL; + relation->rd_partdesc_nodetached = NULL; + relation->rd_partdesc_nodetached_xmin = InvalidTransactionId; relation->rd_pdcxt = NULL; + relation->rd_pddcxt = NULL; relation->rd_partcheck = NIL; relation->rd_partcheckvalid = false; relation->rd_partcheckcxt = NULL; @@ -1286,21 +1271,16 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) if (insertIt) RelationCacheInsert(relation, true); - /* - * For RelationNeedsWAL() to answer correctly on parallel workers, restore - * rd_firstRelfilenodeSubid. No subtransactions start or end while in - * parallel mode, so the specific SubTransactionId does not matter. - */ - if (IsParallelWorker() && RelFileNodeSkippingWAL(relation->rd_node)) - relation->rd_firstRelfilenodeSubid = TopSubTransactionId; - /* It's fully valid */ relation->rd_isvalid = true; -#if RECOVER_RELATION_BUILD_MEMORY - /* Return to caller's context, and blow away the temporary context */ - MemoryContextSwitchTo(oldcxt); - MemoryContextDelete(tmpcxt); +#ifdef MAYBE_RECOVER_RELATION_BUILD_MEMORY + if (tmpcxt) + { + /* Return to caller's context, and blow away the temporary context */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(tmpcxt); + } #endif return relation; @@ -1316,6 +1296,8 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) static void RelationInitPhysicalAddr(Relation relation) { + Oid oldnode = relation->rd_node.relNode; + /* these relations kinds never have storage */ if (!RELKIND_HAS_STORAGE(relation->rd_rel->relkind)) return; @@ -1373,6 +1355,19 @@ RelationInitPhysicalAddr(Relation relation) elog(ERROR, "could not find relation mapping for relation \"%s\", OID %u", RelationGetRelationName(relation), relation->rd_id); } + + /* + * For RelationNeedsWAL() to answer correctly on parallel workers, restore + * rd_firstRelfilenodeSubid. No subtransactions start or end while in + * parallel mode, so the specific SubTransactionId does not matter. + */ + if (IsParallelWorker() && oldnode != relation->rd_node.relNode) + { + if (RelFileNodeSkippingWAL(relation->rd_node)) + relation->rd_firstRelfilenodeSubid = TopSubTransactionId; + else + relation->rd_firstRelfilenodeSubid = InvalidSubTransactionId; + } } /* @@ -1642,7 +1637,6 @@ LookupOpclassInfo(Oid operatorClassOid, /* First time through: initialize the opclass cache */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(OpClassCacheEnt); OpClassCache = hash_create("Operator class cache", 64, @@ -1682,8 +1676,9 @@ LookupOpclassInfo(Oid operatorClassOid, * while we are loading the info, and it's very hard to provoke that if * this happens only once per opclass per backend. */ -#if defined(CLOBBER_CACHE_ALWAYS) - opcentry->valid = false; +#ifdef CLOBBER_CACHE_ENABLED + if (debug_invalidate_system_caches_always > 0) + opcentry->valid = false; #endif if (opcentry->valid) @@ -1797,7 +1792,7 @@ RelationInitTableAccessMethod(Relation relation) * seem prudent to show that in the catalog. So just overwrite it * here. */ - relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID; + relation->rd_amhandler = F_HEAP_TABLEAM_HANDLER; } else if (IsCatalogRelation(relation)) { @@ -1805,7 +1800,7 @@ RelationInitTableAccessMethod(Relation relation) * Avoid doing a syscache lookup for catalog tables. */ Assert(relation->rd_rel->relam == HEAP_TABLE_AM_OID); - relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID; + relation->rd_amhandler = F_HEAP_TABLEAM_HANDLER; } else { @@ -1919,7 +1914,7 @@ formrdesc(const char *relationName, Oid relationReltype, relation->rd_rel->relreplident = REPLICA_IDENTITY_NOTHING; relation->rd_rel->relpages = 0; - relation->rd_rel->reltuples = 0; + relation->rd_rel->reltuples = -1; relation->rd_rel->relallvisible = 0; relation->rd_rel->relkind = RELKIND_RELATION; relation->rd_rel->relnatts = (int16) natts; @@ -2176,10 +2171,16 @@ RelationClose(Relation relation) * stale partition descriptors it has. This is unlikely, so check to see * if there are child contexts before expending a call to mcxt.c. */ - if (RelationHasReferenceCountZero(relation) && - relation->rd_pdcxt != NULL && - relation->rd_pdcxt->firstchild != NULL) - MemoryContextDeleteChildren(relation->rd_pdcxt); + if (RelationHasReferenceCountZero(relation)) + { + if (relation->rd_pdcxt != NULL && + relation->rd_pdcxt->firstchild != NULL) + MemoryContextDeleteChildren(relation->rd_pdcxt); + + if (relation->rd_pddcxt != NULL && + relation->rd_pddcxt->firstchild != NULL) + MemoryContextDeleteChildren(relation->rd_pddcxt); + } #ifdef RELCACHE_FORCE_RELEASE if (RelationHasReferenceCountZero(relation) && @@ -2438,6 +2439,7 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) FreeTriggerDesc(relation->trigdesc); list_free_deep(relation->rd_fkeylist); list_free(relation->rd_indexlist); + list_free(relation->rd_statlist); bms_free(relation->rd_indexattr); bms_free(relation->rd_keyattr); bms_free(relation->rd_pkattr); @@ -2464,6 +2466,8 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) MemoryContextDelete(relation->rd_partkeycxt); if (relation->rd_pdcxt) MemoryContextDelete(relation->rd_pdcxt); + if (relation->rd_pddcxt) + MemoryContextDelete(relation->rd_pddcxt); if (relation->rd_partcheckcxt) MemoryContextDelete(relation->rd_partcheckcxt); pfree(relation); @@ -2731,7 +2735,7 @@ RelationClearRelation(Relation relation, bool rebuild) SWAPFIELD(PartitionKey, rd_partkey); SWAPFIELD(MemoryContext, rd_partkeycxt); } - if (newrel->rd_pdcxt != NULL) + if (newrel->rd_pdcxt != NULL || newrel->rd_pddcxt != NULL) { /* * We are rebuilding a partitioned relation with a non-zero @@ -2759,13 +2763,22 @@ RelationClearRelation(Relation relation, bool rebuild) * newrel. */ relation->rd_partdesc = NULL; /* ensure rd_partdesc is invalid */ + relation->rd_partdesc_nodetached = NULL; + relation->rd_partdesc_nodetached_xmin = InvalidTransactionId; if (relation->rd_pdcxt != NULL) /* probably never happens */ MemoryContextSetParent(newrel->rd_pdcxt, relation->rd_pdcxt); else relation->rd_pdcxt = newrel->rd_pdcxt; + if (relation->rd_pddcxt != NULL) + MemoryContextSetParent(newrel->rd_pddcxt, relation->rd_pddcxt); + else + relation->rd_pddcxt = newrel->rd_pddcxt; /* drop newrel's pointers so we don't destroy it below */ newrel->rd_partdesc = NULL; + newrel->rd_partdesc_nodetached = NULL; + newrel->rd_partdesc_nodetached_xmin = InvalidTransactionId; newrel->rd_pdcxt = NULL; + newrel->rd_pddcxt = NULL; } #undef SWAPFIELD @@ -3050,7 +3063,7 @@ static void AssertPendingSyncConsistency(Relation relation) { bool relcache_verdict = - relation->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT && + RelationIsPermanent(relation) && ((relation->rd_createSubid != InvalidSubTransactionId && RELKIND_HAS_STORAGE(relation->rd_rel->relkind)) || relation->rd_firstRelfilenodeSubid != InvalidSubTransactionId); @@ -3657,6 +3670,13 @@ RelationBuildLocalRelation(const char *relname, rel->rd_rel->relam = accessmtd; + /* + * RelationInitTableAccessMethod will do syscache lookups, so we mustn't + * run it in CacheMemoryContext. Fortunately, the remaining steps don't + * require a long-lived current context. + */ + MemoryContextSwitchTo(oldcxt); + if (relkind == RELKIND_RELATION || relkind == RELKIND_SEQUENCE || relkind == RELKIND_TOASTVALUE || @@ -3685,11 +3705,6 @@ RelationBuildLocalRelation(const char *relname, */ EOXactListAdd(rel); - /* - * done building relcache entry. - */ - MemoryContextSwitchTo(oldcxt); - /* It's fully valid */ rel->rd_isvalid = true; @@ -3841,7 +3856,7 @@ RelationSetNewRelfilenode(Relation relation, char persistence) if (relation->rd_rel->relkind != RELKIND_SEQUENCE) { classform->relpages = 0; /* it's empty until further notice */ - classform->reltuples = 0; + classform->reltuples = -1; classform->relallvisible = 0; } classform->relfrozenxid = freezeXid; @@ -3916,7 +3931,6 @@ RelationCacheInitialize(void) /* * create hashtable that indexes the relcache */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(RelIdCacheEnt); RelationIdCache = hash_create("Relcache by OID", INITRELCACHESIZE, @@ -4402,21 +4416,29 @@ GetPgIndexDescriptor(void) /* * Load any default attribute value definitions for the relation. + * + * ndef is the number of attributes that were marked atthasdef. + * + * Note: we don't make it a hard error to be missing some pg_attrdef records. + * We can limp along as long as nothing needs to use the default value. Code + * that fails to find an expected AttrDefault record should throw an error. */ static void -AttrDefaultFetch(Relation relation) +AttrDefaultFetch(Relation relation, int ndef) { - AttrDefault *attrdef = relation->rd_att->constr->defval; - int ndef = relation->rd_att->constr->num_defval; + AttrDefault *attrdef; Relation adrel; SysScanDesc adscan; ScanKeyData skey; HeapTuple htup; - Datum val; - bool isnull; - int found; - int i; + int found = 0; + /* Allocate array with room for as many entries as expected */ + attrdef = (AttrDefault *) + MemoryContextAllocZero(CacheMemoryContext, + ndef * sizeof(AttrDefault)); + + /* Search pg_attrdef for relevant entries */ ScanKeyInit(&skey, Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -4425,65 +4447,94 @@ AttrDefaultFetch(Relation relation) adrel = table_open(AttrDefaultRelationId, AccessShareLock); adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, NULL, 1, &skey); - found = 0; while (HeapTupleIsValid(htup = systable_getnext(adscan))) { Form_pg_attrdef adform = (Form_pg_attrdef) GETSTRUCT(htup); - Form_pg_attribute attr = TupleDescAttr(relation->rd_att, adform->adnum - 1); + Datum val; + bool isnull; - for (i = 0; i < ndef; i++) + /* protect limited size of array */ + if (found >= ndef) { - if (adform->adnum != attrdef[i].adnum) - continue; - if (attrdef[i].adbin != NULL) - elog(WARNING, "multiple attrdef records found for attr %s of rel %s", - NameStr(attr->attname), - RelationGetRelationName(relation)); - else - found++; - - val = fastgetattr(htup, - Anum_pg_attrdef_adbin, - adrel->rd_att, &isnull); - if (isnull) - elog(WARNING, "null adbin for attr %s of rel %s", - NameStr(attr->attname), - RelationGetRelationName(relation)); - else - { - /* detoast and convert to cstring in caller's context */ - char *s = TextDatumGetCString(val); - - attrdef[i].adbin = MemoryContextStrdup(CacheMemoryContext, s); - pfree(s); - } + elog(WARNING, "unexpected pg_attrdef record found for attribute %d of relation \"%s\"", + adform->adnum, RelationGetRelationName(relation)); break; } - if (i >= ndef) - elog(WARNING, "unexpected attrdef record found for attr %d of rel %s", + val = fastgetattr(htup, + Anum_pg_attrdef_adbin, + adrel->rd_att, &isnull); + if (isnull) + elog(WARNING, "null adbin for attribute %d of relation \"%s\"", adform->adnum, RelationGetRelationName(relation)); + else + { + /* detoast and convert to cstring in caller's context */ + char *s = TextDatumGetCString(val); + + attrdef[found].adnum = adform->adnum; + attrdef[found].adbin = MemoryContextStrdup(CacheMemoryContext, s); + pfree(s); + found++; + } } systable_endscan(adscan); table_close(adrel, AccessShareLock); + + if (found != ndef) + elog(WARNING, "%d pg_attrdef record(s) missing for relation \"%s\"", + ndef - found, RelationGetRelationName(relation)); + + /* + * Sort the AttrDefault entries by adnum, for the convenience of + * equalTupleDescs(). (Usually, they already will be in order, but this + * might not be so if systable_getnext isn't using an index.) + */ + if (found > 1) + qsort(attrdef, found, sizeof(AttrDefault), AttrDefaultCmp); + + /* Install array only after it's fully valid */ + relation->rd_att->constr->defval = attrdef; + relation->rd_att->constr->num_defval = found; +} + +/* + * qsort comparator to sort AttrDefault entries by adnum + */ +static int +AttrDefaultCmp(const void *a, const void *b) +{ + const AttrDefault *ada = (const AttrDefault *) a; + const AttrDefault *adb = (const AttrDefault *) b; + + return ada->adnum - adb->adnum; } /* * Load any check constraints for the relation. + * + * As with defaults, if we don't find the expected number of them, just warn + * here. The executor should throw an error if an INSERT/UPDATE is attempted. */ static void CheckConstraintFetch(Relation relation) { - ConstrCheck *check = relation->rd_att->constr->check; - int ncheck = relation->rd_att->constr->num_check; + ConstrCheck *check; + int ncheck = relation->rd_rel->relchecks; Relation conrel; SysScanDesc conscan; ScanKeyData skey[1]; HeapTuple htup; int found = 0; + /* Allocate array with room for as many entries as expected */ + check = (ConstrCheck *) + MemoryContextAllocZero(CacheMemoryContext, + ncheck * sizeof(ConstrCheck)); + + /* Search pg_constraint for relevant entries */ ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -4498,16 +4549,18 @@ CheckConstraintFetch(Relation relation) Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(htup); Datum val; bool isnull; - char *s; /* We want check constraints only */ if (conform->contype != CONSTRAINT_CHECK) continue; + /* protect limited size of array */ if (found >= ncheck) - elog(ERROR, - "pg_class reports %d constraint record(s) for rel %s, but found extra in pg_constraint", - ncheck, RelationGetRelationName(relation)); + { + elog(WARNING, "unexpected pg_constraint record found for relation \"%s\"", + RelationGetRelationName(relation)); + break; + } check[found].ccvalid = conform->convalidated; check[found].ccnoinherit = conform->connoinherit; @@ -4519,27 +4572,36 @@ CheckConstraintFetch(Relation relation) Anum_pg_constraint_conbin, conrel->rd_att, &isnull); if (isnull) - elog(ERROR, "null conbin for rel %s", + elog(WARNING, "null conbin for relation \"%s\"", RelationGetRelationName(relation)); + else + { + /* detoast and convert to cstring in caller's context */ + char *s = TextDatumGetCString(val); - /* detoast and convert to cstring in caller's context */ - s = TextDatumGetCString(val); - check[found].ccbin = MemoryContextStrdup(CacheMemoryContext, s); - pfree(s); - - found++; + check[found].ccbin = MemoryContextStrdup(CacheMemoryContext, s); + pfree(s); + found++; + } } systable_endscan(conscan); table_close(conrel, AccessShareLock); if (found != ncheck) - elog(ERROR, "%d constraint record(s) missing for rel %s", + elog(WARNING, "%d pg_constraint record(s) missing for relation \"%s\"", ncheck - found, RelationGetRelationName(relation)); - /* Sort the records so that CHECKs are applied in a deterministic order */ - if (ncheck > 1) - qsort(check, ncheck, sizeof(ConstrCheck), CheckConstraintCmp); + /* + * Sort the records by name. This ensures that CHECKs are applied in a + * deterministic order, and it also makes equalTupleDescs() faster. + */ + if (found > 1) + qsort(check, found, sizeof(ConstrCheck), CheckConstraintCmp); + + /* Install array only after it's fully valid */ + relation->rd_att->constr->check = check; + relation->rd_att->constr->num_check = found; } /* @@ -5351,6 +5413,86 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) } } +/* + * RelationGetIdentityKeyBitmap -- get a bitmap of replica identity attribute + * numbers + * + * A bitmap of index attribute numbers for the configured replica identity + * index is returned. + * + * See also comments of RelationGetIndexAttrBitmap(). + * + * This is a special purpose function used during logical replication. Here, + * unlike RelationGetIndexAttrBitmap(), we don't acquire a lock on the required + * index as we build the cache entry using a historic snapshot and all the + * later changes are absorbed while decoding WAL. Due to this reason, we don't + * need to retry here in case of a change in the set of indexes. + */ +Bitmapset * +RelationGetIdentityKeyBitmap(Relation relation) +{ + Bitmapset *idindexattrs = NULL; /* columns in the replica identity */ + Relation indexDesc; + int i; + Oid replidindex; + MemoryContext oldcxt; + + /* Quick exit if we already computed the result */ + if (relation->rd_idattr != NULL) + return bms_copy(relation->rd_idattr); + + /* Fast path if definitely no indexes */ + if (!RelationGetForm(relation)->relhasindex) + return NULL; + + /* Historic snapshot must be set. */ + Assert(HistoricSnapshotActive()); + + replidindex = RelationGetReplicaIndex(relation); + + /* Fall out if there is no replica identity index */ + if (!OidIsValid(replidindex)) + return NULL; + + /* Look up the description for the replica identity index */ + indexDesc = RelationIdGetRelation(replidindex); + + if (!RelationIsValid(indexDesc)) + elog(ERROR, "could not open relation with OID %u", + relation->rd_replidindex); + + /* Add referenced attributes to idindexattrs */ + for (i = 0; i < indexDesc->rd_index->indnatts; i++) + { + int attrnum = indexDesc->rd_index->indkey.values[i]; + + /* + * We don't include non-key columns into idindexattrs bitmaps. See + * RelationGetIndexAttrBitmap. + */ + if (attrnum != 0) + { + if (i < indexDesc->rd_index->indnkeyatts) + idindexattrs = bms_add_member(idindexattrs, + attrnum - FirstLowInvalidHeapAttributeNumber); + } + } + + RelationClose(indexDesc); + + /* Don't leak the old values of these bitmaps, if any */ + bms_free(relation->rd_idattr); + relation->rd_idattr = NULL; + + /* Now save copy of the bitmap in the relcache entry */ + oldcxt = MemoryContextSwitchTo(CacheMemoryContext); + relation->rd_idattr = bms_copy(idindexattrs); + MemoryContextSwitchTo(oldcxt); + + /* We return our original working copy for caller to play with */ + return idindexattrs; +} + /* * RelationGetExclusionInfo -- get info about index's exclusion constraint * @@ -6092,7 +6234,10 @@ load_relcache_init_file(bool shared) rel->rd_partkey = NULL; rel->rd_partkeycxt = NULL; rel->rd_partdesc = NULL; + rel->rd_partdesc_nodetached = NULL; + rel->rd_partdesc_nodetached_xmin = InvalidTransactionId; rel->rd_pdcxt = NULL; + rel->rd_pddcxt = NULL; rel->rd_partcheck = NIL; rel->rd_partcheckvalid = false; rel->rd_partcheckcxt = NULL; diff --git a/src/backend/utils/cache/relfilenodemap.c b/src/backend/utils/cache/relfilenodemap.c index 3acda32d17af..56d7c73d3398 100644 --- a/src/backend/utils/cache/relfilenodemap.c +++ b/src/backend/utils/cache/relfilenodemap.c @@ -3,7 +3,7 @@ * relfilenodemap.c * relfilenode to oid mapping cache. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,7 +16,6 @@ #include "access/genam.h" #include "access/htup_details.h" #include "access/table.h" -#include "catalog/indexing.h" #include "catalog/pg_class.h" #include "catalog/pg_tablespace.h" #include "miscadmin.h" @@ -111,17 +110,15 @@ InitializeRelfilenodeMap(void) relfilenode_skey[0].sk_attno = Anum_pg_class_reltablespace; relfilenode_skey[1].sk_attno = Anum_pg_class_relfilenode; - /* Initialize the hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); - ctl.keysize = sizeof(RelfilenodeMapKey); - ctl.entrysize = sizeof(RelfilenodeMapEntry); - ctl.hcxt = CacheMemoryContext; - /* * Only create the RelfilenodeMapHash now, so we don't end up partially * initialized when fmgr_info_cxt() above ERRORs out with an out of memory * error. */ + ctl.keysize = sizeof(RelfilenodeMapKey); + ctl.entrysize = sizeof(RelfilenodeMapEntry); + ctl.hcxt = CacheMemoryContext; + RelfilenodeMapHash = hash_create("RelfilenodeMap cache", 64, &ctl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c index 6b337a403efb..a853da345886 100644 --- a/src/backend/utils/cache/relmapper.c +++ b/src/backend/utils/cache/relmapper.c @@ -28,7 +28,7 @@ * all these files commit in a single map file update rather than being tied * to transaction commit. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -143,7 +143,7 @@ static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode, bool add_okay); static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, bool add_okay); -static void load_relmap_file(bool shared); +static void load_relmap_file(bool shared, bool lock_held); static void write_relmap_file(bool shared, RelMapFile *newmap, bool write_wal, bool send_sinval, bool preserve_files, Oid dbid, Oid tsid, const char *dbpath); @@ -412,12 +412,12 @@ RelationMapInvalidate(bool shared) if (shared) { if (shared_map.magic == RELMAPPER_FILEMAGIC) - load_relmap_file(true); + load_relmap_file(true, false); } else { if (local_map.magic == RELMAPPER_FILEMAGIC) - load_relmap_file(false); + load_relmap_file(false, false); } } @@ -432,9 +432,9 @@ void RelationMapInvalidateAll(void) { if (shared_map.magic == RELMAPPER_FILEMAGIC) - load_relmap_file(true); + load_relmap_file(true, false); if (local_map.magic == RELMAPPER_FILEMAGIC) - load_relmap_file(false); + load_relmap_file(false, false); } /* @@ -619,7 +619,7 @@ RelationMapInitializePhase2(void) /* * Load the shared map file, die on error. */ - load_relmap_file(true); + load_relmap_file(true, false); } /* @@ -640,7 +640,7 @@ RelationMapInitializePhase3(void) /* * Load the local map file, die on error. */ - load_relmap_file(false); + load_relmap_file(false, false); } /* @@ -702,7 +702,7 @@ RestoreRelationMap(char *startAddress) * Note that the local case requires DatabasePath to be set up. */ static void -load_relmap_file(bool shared) +load_relmap_file(bool shared, bool lock_held) { RelMapFile *map; char mapfilename[MAXPGPATH]; @@ -732,12 +732,15 @@ load_relmap_file(bool shared) mapfilename))); /* - * Note: we could take RelationMappingLock in shared mode here, but it - * seems unnecessary since our read() should be atomic against any - * concurrent updater's write(). If the file is updated shortly after we - * look, the sinval signaling mechanism will make us re-read it before we - * are able to access any relation that's affected by the change. + * Grab the lock to prevent the file from being updated while we read it, + * unless the caller is already holding the lock. If the file is updated + * shortly after we look, the sinval signaling mechanism will make us + * re-read it before we are able to access any relation that's affected by + * the change. */ + if (!lock_held) + LWLockAcquire(RelationMappingLock, LW_SHARED); + pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_READ); r = read(fd, map, sizeof(RelMapFile)); if (r != sizeof(RelMapFile)) @@ -754,6 +757,9 @@ load_relmap_file(bool shared) } pgstat_report_wait_end(); + if (!lock_held) + LWLockRelease(RelationMappingLock); + if (CloseTransientFile(fd) != 0) ereport(FATAL, (errcode_for_file_access(), @@ -935,8 +941,15 @@ write_relmap_file(bool shared, RelMapFile *newmap, } } - /* Success, update permanent copy */ - memcpy(realmap, newmap, sizeof(RelMapFile)); + /* + * Success, update permanent copy. During bootstrap, we might be working + * on the permanent copy itself, in which case skip the memcpy() to avoid + * invoking nominally-undefined behavior. + */ + if (realmap != newmap) + memcpy(realmap, newmap, sizeof(RelMapFile)); + else + Assert(!send_sinval); /* must be bootstrapping */ /* Critical section done */ if (write_wal) @@ -969,7 +982,7 @@ perform_relmap_update(bool shared, const RelMapFile *updates) LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE); /* Be certain we see any other updates just made */ - load_relmap_file(shared); + load_relmap_file(shared, true); /* Prepare updated data in a local variable */ if (shared) @@ -1024,12 +1037,13 @@ relmap_redo(XLogReaderState *record) * preserve files, either. * * There shouldn't be anyone else updating relmaps during WAL replay, - * so we don't bother to take the RelationMappingLock. We would need - * to do so if load_relmap_file needed to interlock against writers. + * but grab the lock to interlock against load_relmap_file(). */ + LWLockAcquire(RelationMappingLock, LW_EXCLUSIVE); write_relmap_file((xlrec->dbid == InvalidOid), &newmap, false, true, false, xlrec->dbid, xlrec->tsid, dbpath); + LWLockRelease(RelationMappingLock); pfree(dbpath); } diff --git a/src/backend/utils/cache/spccache.c b/src/backend/utils/cache/spccache.c index e0c3c1b1c117..5870f436df82 100644 --- a/src/backend/utils/cache/spccache.c +++ b/src/backend/utils/cache/spccache.c @@ -8,7 +8,7 @@ * be a measurable performance gain from doing this, but that might change * in the future as we add more options. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -79,7 +79,6 @@ InitializeTableSpaceCache(void) HASHCTL ctl; /* Initialize the hash table. */ - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(TableSpaceCacheEntry); TableSpaceCacheHash = diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 1d540c19110f..b6cf8f65d43e 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2007-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,9 +25,9 @@ #include "miscadmin.h" #include "access/heapam.h" +#include "catalog/indexing.h" #include "access/htup_details.h" #include "access/sysattr.h" -#include "catalog/indexing.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_am.h" #include "catalog/pg_amop.h" @@ -104,7 +104,7 @@ There must be a unique index underlying each syscache (ie, an index whose key is the same as that of the cache). If there is not one - already, add definitions for it to include/catalog/indexing.h: you need + already, add definitions for it to include/catalog/pg_*.h: you need to add a DECLARE_UNIQUE_INDEX macro and a #define for the index OID. (Adding an index requires a catversion.h update, while simply adding/deleting caches only requires a recompile.) @@ -690,6 +690,18 @@ static const struct cachedesc cacheinfo[] = { }, 64 }, + {RangeRelationId, /* RANGEMULTIRANGE */ + RangeMultirangeTypidIndexId, + 1, + { + Anum_pg_range_rngmultitypid, + 0, + 0, + 0 + }, + 4 + }, + {RangeRelationId, /* RANGETYPE */ RangeTypidIndexId, 1, diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c index 1641271cfe74..384107b6bac3 100644 --- a/src/backend/utils/cache/ts_cache.c +++ b/src/backend/utils/cache/ts_cache.c @@ -17,7 +17,7 @@ * any database access. * * - * Copyright (c) 2006-2020, PostgreSQL Global Development Group + * Copyright (c) 2006-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/cache/ts_cache.c @@ -30,7 +30,6 @@ #include "access/htup_details.h" #include "access/table.h" #include "access/xact.h" -#include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_ts_config.h" #include "catalog/pg_ts_config_map.h" @@ -118,7 +117,6 @@ lookup_ts_parser_cache(Oid prsId) /* First time through: initialize the hash table */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(TSParserCacheEntry); TSParserCacheHash = hash_create("Tsearch parser cache", 4, @@ -216,7 +214,6 @@ lookup_ts_dictionary_cache(Oid dictId) /* First time through: initialize the hash table */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(TSDictionaryCacheEntry); TSDictionaryCacheHash = hash_create("Tsearch dictionary cache", 8, @@ -366,7 +363,6 @@ init_ts_config_cache(void) { HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(TSConfigCacheEntry); TSConfigCacheHash = hash_create("Tsearch configuration cache", 16, diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index e9254bde7af4..b44ac3d70cad 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -31,7 +31,7 @@ * constraint changes are also tracked properly. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -50,7 +50,6 @@ #include "access/relation.h" #include "access/session.h" #include "access/table.h" -#include "catalog/indexing.h" #include "catalog/pg_am.h" #include "catalog/pg_constraint.h" #include "catalog/pg_enum.h" @@ -99,8 +98,10 @@ static TypeCacheEntry *firstDomainTypeEntry = NULL; #define TCFLAGS_CHECKED_FIELD_PROPERTIES 0x004000 #define TCFLAGS_HAVE_FIELD_EQUALITY 0x008000 #define TCFLAGS_HAVE_FIELD_COMPARE 0x010000 -#define TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS 0x020000 -#define TCFLAGS_DOMAIN_BASE_IS_COMPOSITE 0x040000 +#define TCFLAGS_HAVE_FIELD_HASHING 0x020000 +#define TCFLAGS_HAVE_FIELD_EXTENDED_HASHING 0x040000 +#define TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS 0x080000 +#define TCFLAGS_DOMAIN_BASE_IS_COMPOSITE 0x100000 /* The flags associated with equality/comparison/hashing are all but these: */ #define TCFLAGS_OPERATOR_FLAGS \ @@ -287,6 +288,7 @@ static uint64 tupledesc_id_counter = INVALID_TUPLEDESC_IDENTIFIER; static void load_typcache_tupdesc(TypeCacheEntry *typentry); static void load_rangetype_info(TypeCacheEntry *typentry); +static void load_multirangetype_info(TypeCacheEntry *typentry); static void load_domaintype_info(TypeCacheEntry *typentry); static int dcs_cmp(const void *a, const void *b); static void decr_dcc_refcount(DomainConstraintCache *dcc); @@ -299,10 +301,15 @@ static bool array_element_has_extended_hashing(TypeCacheEntry *typentry); static void cache_array_element_properties(TypeCacheEntry *typentry); static bool record_fields_have_equality(TypeCacheEntry *typentry); static bool record_fields_have_compare(TypeCacheEntry *typentry); +static bool record_fields_have_hashing(TypeCacheEntry *typentry); +static bool record_fields_have_extended_hashing(TypeCacheEntry *typentry); static void cache_record_field_properties(TypeCacheEntry *typentry); static bool range_element_has_hashing(TypeCacheEntry *typentry); static bool range_element_has_extended_hashing(TypeCacheEntry *typentry); static void cache_range_element_properties(TypeCacheEntry *typentry); +static bool multirange_element_has_hashing(TypeCacheEntry *typentry); +static bool multirange_element_has_extended_hashing(TypeCacheEntry *typentry); +static void cache_multirange_element_properties(TypeCacheEntry *typentry); static void TypeCacheRelCallback(Datum arg, Oid relid); static void TypeCacheTypCallback(Datum arg, int cacheid, uint32 hashvalue); static void TypeCacheOpcCallback(Datum arg, int cacheid, uint32 hashvalue); @@ -339,7 +346,6 @@ lookup_type_cache(Oid type_id, int flags) /* First time through: initialize the hash table */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(Oid); ctl.entrysize = sizeof(TypeCacheEntry); TypeCacheHash = hash_create("Type information cache", 64, @@ -404,6 +410,7 @@ lookup_type_cache(Oid type_id, int flags) typentry->typstorage = typtup->typstorage; typentry->typtype = typtup->typtype; typentry->typrelid = typtup->typrelid; + typentry->typsubscript = typtup->typsubscript; typentry->typelem = typtup->typelem; typentry->typcollation = typtup->typcollation; typentry->flags |= TCFLAGS_HAVE_PG_TYPE_DATA; @@ -448,6 +455,7 @@ lookup_type_cache(Oid type_id, int flags) typentry->typstorage = typtup->typstorage; typentry->typtype = typtup->typtype; typentry->typrelid = typtup->typrelid; + typentry->typsubscript = typtup->typsubscript; typentry->typelem = typtup->typelem; typentry->typcollation = typtup->typcollation; typentry->flags |= TCFLAGS_HAVE_PG_TYPE_DATA; @@ -554,8 +562,8 @@ lookup_type_cache(Oid type_id, int flags) * to see if the element type or column types support equality. If * not, array_eq or record_eq would fail at runtime, so we don't want * to report that the type has equality. (We can omit similar - * checking for ranges because ranges can't be created in the first - * place unless their subtypes support equality.) + * checking for ranges and multiranges because ranges can't be created + * in the first place unless their subtypes support equality.) */ if (eq_opr == ARRAY_EQ_OP && !array_element_has_equality(typentry)) @@ -592,7 +600,7 @@ lookup_type_cache(Oid type_id, int flags) /* * As above, make sure array_cmp or record_cmp will succeed; but again - * we need no special check for ranges. + * we need no special check for ranges or multiranges. */ if (lt_opr == ARRAY_LT_OP && !array_element_has_compare(typentry)) @@ -617,7 +625,7 @@ lookup_type_cache(Oid type_id, int flags) /* * As above, make sure array_cmp or record_cmp will succeed; but again - * we need no special check for ranges. + * we need no special check for ranges or multiranges. */ if (gt_opr == ARRAY_GT_OP && !array_element_has_compare(typentry)) @@ -642,7 +650,7 @@ lookup_type_cache(Oid type_id, int flags) /* * As above, make sure array_cmp or record_cmp will succeed; but again - * we need no special check for ranges. + * we need no special check for ranges or multiranges. */ if (cmp_proc == F_BTARRAYCMP && !array_element_has_compare(typentry)) @@ -679,19 +687,24 @@ lookup_type_cache(Oid type_id, int flags) HASHSTANDARD_PROC); /* - * As above, make sure hash_array will succeed. We don't currently - * support hashing for composite types, but when we do, we'll need - * more logic here to check that case too. + * As above, make sure hash_array, hash_record, or hash_range will + * succeed. */ if (hash_proc == F_HASH_ARRAY && !array_element_has_hashing(typentry)) hash_proc = InvalidOid; + else if (hash_proc == F_HASH_RECORD && + !record_fields_have_hashing(typentry)) + hash_proc = InvalidOid; + else if (hash_proc == F_HASH_RANGE && + !range_element_has_hashing(typentry)) + hash_proc = InvalidOid; /* - * Likewise for hash_range. + * Likewise for hash_multirange. */ - if (hash_proc == F_HASH_RANGE && - !range_element_has_hashing(typentry)) + if (hash_proc == F_HASH_MULTIRANGE && + !multirange_element_has_hashing(typentry)) hash_proc = InvalidOid; /* Force update of hash_proc_finfo only if we're changing state */ @@ -723,19 +736,24 @@ lookup_type_cache(Oid type_id, int flags) HASHEXTENDED_PROC); /* - * As above, make sure hash_array_extended will succeed. We don't - * currently support hashing for composite types, but when we do, - * we'll need more logic here to check that case too. + * As above, make sure hash_array_extended, hash_record_extended, or + * hash_range_extended will succeed. */ if (hash_extended_proc == F_HASH_ARRAY_EXTENDED && !array_element_has_extended_hashing(typentry)) hash_extended_proc = InvalidOid; + else if (hash_extended_proc == F_HASH_RECORD_EXTENDED && + !record_fields_have_extended_hashing(typentry)) + hash_extended_proc = InvalidOid; + else if (hash_extended_proc == F_HASH_RANGE_EXTENDED && + !range_element_has_extended_hashing(typentry)) + hash_extended_proc = InvalidOid; /* - * Likewise for hash_range_extended. + * Likewise for hash_multirange_extended. */ - if (hash_extended_proc == F_HASH_RANGE_EXTENDED && - !range_element_has_extended_hashing(typentry)) + if (hash_extended_proc == F_HASH_MULTIRANGE_EXTENDED && + !multirange_element_has_extended_hashing(typentry)) hash_extended_proc = InvalidOid; /* Force update of proc finfo only if we're changing state */ @@ -817,6 +835,16 @@ lookup_type_cache(Oid type_id, int flags) (void) lookup_type_cache(typentry->rngelemtype->type_id, 0); } + /* + * If requested, get information about a multirange type + */ + if ((flags & TYPECACHE_MULTIRANGE_INFO) && + typentry->rngtype == NULL && + typentry->typtype == TYPTYPE_MULTIRANGE) + { + load_multirangetype_info(typentry); + } + /* * If requested, get information about a domain type */ @@ -928,6 +956,22 @@ load_rangetype_info(TypeCacheEntry *typentry) typentry->rngelemtype = lookup_type_cache(subtypeOid, 0); } +/* + * load_multirangetype_info --- helper routine to set up multirange type + * information + */ +static void +load_multirangetype_info(TypeCacheEntry *typentry) +{ + Oid rangetypeOid; + + rangetypeOid = get_multirange_range(typentry->type_id); + if (!OidIsValid(rangetypeOid)) + elog(ERROR, "cache lookup failed for multirange type %u", + typentry->type_id); + + typentry->rngtype = lookup_type_cache(rangetypeOid, TYPECACHE_RANGE_INFO); +} /* * load_domaintype_info --- helper routine to set up domain constraint info @@ -1449,6 +1493,22 @@ record_fields_have_compare(TypeCacheEntry *typentry) return (typentry->flags & TCFLAGS_HAVE_FIELD_COMPARE) != 0; } +static bool +record_fields_have_hashing(TypeCacheEntry *typentry) +{ + if (!(typentry->flags & TCFLAGS_CHECKED_FIELD_PROPERTIES)) + cache_record_field_properties(typentry); + return (typentry->flags & TCFLAGS_HAVE_FIELD_HASHING) != 0; +} + +static bool +record_fields_have_extended_hashing(TypeCacheEntry *typentry) +{ + if (!(typentry->flags & TCFLAGS_CHECKED_FIELD_PROPERTIES)) + cache_record_field_properties(typentry); + return (typentry->flags & TCFLAGS_HAVE_FIELD_EXTENDED_HASHING) != 0; +} + static void cache_record_field_properties(TypeCacheEntry *typentry) { @@ -1458,8 +1518,12 @@ cache_record_field_properties(TypeCacheEntry *typentry) * everything will (we may get a failure at runtime ...) */ if (typentry->type_id == RECORDOID) + { typentry->flags |= (TCFLAGS_HAVE_FIELD_EQUALITY | - TCFLAGS_HAVE_FIELD_COMPARE); + TCFLAGS_HAVE_FIELD_COMPARE | + TCFLAGS_HAVE_FIELD_HASHING | + TCFLAGS_HAVE_FIELD_EXTENDED_HASHING); + } else if (typentry->typtype == TYPTYPE_COMPOSITE) { TupleDesc tupdesc; @@ -1476,7 +1540,9 @@ cache_record_field_properties(TypeCacheEntry *typentry) /* Have each property if all non-dropped fields have the property */ newflags = (TCFLAGS_HAVE_FIELD_EQUALITY | - TCFLAGS_HAVE_FIELD_COMPARE); + TCFLAGS_HAVE_FIELD_COMPARE | + TCFLAGS_HAVE_FIELD_HASHING | + TCFLAGS_HAVE_FIELD_EXTENDED_HASHING); for (i = 0; i < tupdesc->natts; i++) { TypeCacheEntry *fieldentry; @@ -1487,11 +1553,17 @@ cache_record_field_properties(TypeCacheEntry *typentry) fieldentry = lookup_type_cache(attr->atttypid, TYPECACHE_EQ_OPR | - TYPECACHE_CMP_PROC); + TYPECACHE_CMP_PROC | + TYPECACHE_HASH_PROC | + TYPECACHE_HASH_EXTENDED_PROC); if (!OidIsValid(fieldentry->eq_opr)) newflags &= ~TCFLAGS_HAVE_FIELD_EQUALITY; if (!OidIsValid(fieldentry->cmp_proc)) newflags &= ~TCFLAGS_HAVE_FIELD_COMPARE; + if (!OidIsValid(fieldentry->hash_proc)) + newflags &= ~TCFLAGS_HAVE_FIELD_HASHING; + if (!OidIsValid(fieldentry->hash_extended_proc)) + newflags &= ~TCFLAGS_HAVE_FIELD_EXTENDED_HASHING; /* We can drop out of the loop once we disprove all bits */ if (newflags == 0) @@ -1516,23 +1588,27 @@ cache_record_field_properties(TypeCacheEntry *typentry) } baseentry = lookup_type_cache(typentry->domainBaseType, TYPECACHE_EQ_OPR | - TYPECACHE_CMP_PROC); + TYPECACHE_CMP_PROC | + TYPECACHE_HASH_PROC | + TYPECACHE_HASH_EXTENDED_PROC); if (baseentry->typtype == TYPTYPE_COMPOSITE) { typentry->flags |= TCFLAGS_DOMAIN_BASE_IS_COMPOSITE; typentry->flags |= baseentry->flags & (TCFLAGS_HAVE_FIELD_EQUALITY | - TCFLAGS_HAVE_FIELD_COMPARE); + TCFLAGS_HAVE_FIELD_COMPARE | + TCFLAGS_HAVE_FIELD_HASHING | + TCFLAGS_HAVE_FIELD_EXTENDED_HASHING); } } typentry->flags |= TCFLAGS_CHECKED_FIELD_PROPERTIES; } /* - * Likewise, some helper functions for range types. + * Likewise, some helper functions for range and multirange types. * * We can borrow the flag bits for array element properties to use for range * element properties, since those flag bits otherwise have no use in a - * range type's typcache entry. + * range or multirange type's typcache entry. */ static bool @@ -1575,6 +1651,46 @@ cache_range_element_properties(TypeCacheEntry *typentry) typentry->flags |= TCFLAGS_CHECKED_ELEM_PROPERTIES; } +static bool +multirange_element_has_hashing(TypeCacheEntry *typentry) +{ + if (!(typentry->flags & TCFLAGS_CHECKED_ELEM_PROPERTIES)) + cache_multirange_element_properties(typentry); + return (typentry->flags & TCFLAGS_HAVE_ELEM_HASHING) != 0; +} + +static bool +multirange_element_has_extended_hashing(TypeCacheEntry *typentry) +{ + if (!(typentry->flags & TCFLAGS_CHECKED_ELEM_PROPERTIES)) + cache_multirange_element_properties(typentry); + return (typentry->flags & TCFLAGS_HAVE_ELEM_EXTENDED_HASHING) != 0; +} + +static void +cache_multirange_element_properties(TypeCacheEntry *typentry) +{ + /* load up range link if we didn't already */ + if (typentry->rngtype == NULL && + typentry->typtype == TYPTYPE_MULTIRANGE) + load_multirangetype_info(typentry); + + if (typentry->rngtype != NULL && typentry->rngtype->rngelemtype != NULL) + { + TypeCacheEntry *elementry; + + /* might need to calculate subtype's hash function properties */ + elementry = lookup_type_cache(typentry->rngtype->rngelemtype->type_id, + TYPECACHE_HASH_PROC | + TYPECACHE_HASH_EXTENDED_PROC); + if (OidIsValid(elementry->hash_proc)) + typentry->flags |= TCFLAGS_HAVE_ELEM_HASHING; + if (OidIsValid(elementry->hash_extended_proc)) + typentry->flags |= TCFLAGS_HAVE_ELEM_EXTENDED_HASHING; + } + typentry->flags |= TCFLAGS_CHECKED_ELEM_PROPERTIES; +} + /* * Make sure that RecordCacheArray and RecordIdentifierArray are large enough * to store 'typmod'. @@ -1842,7 +1958,6 @@ assign_record_type_typmod(TupleDesc tupDesc) /* First time through: initialize the hash table */ HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = sizeof(TupleDesc); /* just the pointer */ ctl.entrysize = sizeof(RecordCacheEntry); ctl.hash = record_type_typmod_hash; @@ -2742,7 +2857,7 @@ find_or_make_matching_shared_tupledesc(TupleDesc tupdesc) Assert(record_table_entry->key.shared); result = (TupleDesc) dsa_get_address(CurrentSession->area, - record_table_entry->key.shared); + record_table_entry->key.u.shared_tupdesc); Assert(result->tdrefcount == -1); return result; diff --git a/src/backend/utils/datumstream/datumstreamblock.c b/src/backend/utils/datumstream/datumstreamblock.c index 3715f91d6138..86c80e0c756f 100755 --- a/src/backend/utils/datumstream/datumstreamblock.c +++ b/src/backend/utils/datumstream/datumstreamblock.c @@ -5498,16 +5498,16 @@ VarlenaInfoToBuffer(char *buffer, uint8 * p) if (VARATT_IS_EXTERNAL(p)) { struct varatt_external *ext = (struct varatt_external *) p; - bool externalIsCompressed = (ext->va_extsize != ext->va_rawsize - VARHDRSZ); + bool externalIsCompressed = VARATT_EXTERNAL_IS_COMPRESSED(*ext); sprintf(buffer, "external (header ptr %p, header alignment %u, header 0x%.8x): " - "va_rawsize: %d, va_extsize %d, valueid %u, toastrelid %u (compressed %s)", + "va_rawsize: %d, va_extinfo %u, valueid %u, toastrelid %u (compressed %s)", p, alignment, *((uint32 *) p), ext->va_rawsize, - ext->va_extsize, + ext->va_extinfo, ext->va_valueid, ext->va_toastrelid, (externalIsCompressed ? "true" : "false")); @@ -5534,7 +5534,7 @@ VarlenaInfoToBuffer(char *buffer, uint8 * p) p, alignment, *((uint32 *) p), - (int32) comp->va_compressed.va_rawsize, + (int32) comp->va_compressed.va_tcinfo, (int32) VARSIZE_ANY(p), VARDATA_ANY(p)); } diff --git a/src/backend/utils/errcodes.txt b/src/backend/utils/errcodes.txt index 89ec0deb5328..74521e106e74 100644 --- a/src/backend/utils/errcodes.txt +++ b/src/backend/utils/errcodes.txt @@ -5,6 +5,7 @@ # Portions Copyright (c) 2005-2008, Greenplum inc. # Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. # Copyright (c) 2003-2020, PostgreSQL Global Development Group +# Copyright (c) 2003-2021, PostgreSQL Global Development Group # # This list serves as the basis for generating source files containing error # codes. It is kept in a common format to make sure all these source files have @@ -449,6 +450,7 @@ Section: Class 57 - Operator Intervention 57P03 E ERRCODE_CANNOT_CONNECT_NOW cannot_connect_now 57P04 E ERRCODE_DATABASE_DROPPED database_dropped 57M02 E ERRCODE_MIRROR_READY mirror_ready +57P05 E ERRCODE_IDLE_SESSION_TIMEOUT idle_session_timeout Section: Class 58 - System Error (errors external to PostgreSQL itself) diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c index dc0805c6d4c7..90387c74392a 100644 --- a/src/backend/utils/error/assert.c +++ b/src/backend/utils/error/assert.c @@ -1,20 +1,15 @@ /*------------------------------------------------------------------------- * * assert.c - * Assert code. + * Assert support code. * - * Portions Copyright (c) 2005-2009, Greenplum inc - * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION * src/backend/utils/error/assert.c * - * NOTE - * This should eventually work with elog() - * *------------------------------------------------------------------------- */ #include "postgres.h" @@ -29,6 +24,10 @@ /* * ExceptionalCondition - Handles the failure of an Assert() + * + * We intentionally do not go through elog() here, on the grounds of + * wanting to minimize the amount of infrastructure that has to be + * working to report an assertion failure. */ void ExceptionalCondition(const char *conditionName, @@ -36,23 +35,21 @@ ExceptionalCondition(const char *conditionName, const char *fileName, int lineNumber) { - /* CDB: Try to tell the QD or client what happened. */ + /* Report the failure on stderr (or local equivalent) */ if (!PointerIsValid(conditionName) || !PointerIsValid(fileName) || !PointerIsValid(errorType)) - ereport(FATAL, - errFatalReturn(gp_reraise_signal), - errmsg("TRAP: ExceptionalCondition: bad arguments")); + write_stderr("TRAP: ExceptionalCondition: bad arguments in PID %d\n", + (int) getpid()); else - ereport(FATAL, - errFatalReturn(gp_reraise_signal), - errmsg("Unexpected internal error"), - errdetail("%s(\"%s\", File: \"%s\", Line: %d)\n", - errorType, conditionName, fileName, lineNumber)); - + write_stderr("TRAP: %s(\"%s\", File: \"%s\", Line: %d, PID: %d)\n", + errorType, conditionName, + fileName, lineNumber, (int) getpid()); + /* Usually this shouldn't be needed, but make sure the msg went out */ fflush(stderr); + /* If we have support for it, dump a simple backtrace */ #ifdef HAVE_BACKTRACE_SYMBOLS { void *buf[100]; @@ -63,12 +60,12 @@ ExceptionalCondition(const char *conditionName, } #endif -#ifdef SLEEP_ON_ASSERT - /* - * It would be nice to use pg_usleep() here, but only does 2000 sec or 33 - * minutes, which seems too short. + * If configured to do so, sleep indefinitely to allow user to attach a + * debugger. It would be nice to use pg_usleep() here, but that can sleep + * at most 2G usec or ~33 minutes, which seems too short. */ +#ifdef SLEEP_ON_ASSERT sleep(1000000); #endif diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 96170dc38330..019a3b4c7526 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -45,7 +45,7 @@ * * Portions Copyright (c) 2005-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -79,6 +79,7 @@ #include "libpq/pqsignal.h" #include "mb/pg_wchar.h" #include "miscadmin.h" +#include "pgstat.h" #include "postmaster/bgworker.h" #include "postmaster/postmaster.h" #include "postmaster/syslogger.h" @@ -229,21 +230,106 @@ static void send_message_to_server_log(ErrorData *edata); static void write_pipe_chunks(char *data, int len, int dest); static void send_message_to_frontend(ErrorData *edata); static const char *error_severity(int elevel); -static void append_with_tabs(StringInfo buf, const char *str); -static bool is_log_level_output(int elevel, int log_min_level); -static void write_pipe_chunks(char *data, int len, int dest); -static void write_csvlog(ErrorData *edata); static void elog_debug_linger(ErrorData *edata); - -/* GPDB: wrapper function to silence unused result warning */ static inline void ignore_returned_result(long long int result) { (void) result; } +static void append_with_tabs(StringInfo buf, const char *str); -static void setup_formatted_log_time(void); -static void setup_formatted_start_time(void); + +/* + * is_log_level_output -- is elevel logically >= log_min_level? + * + * We use this for tests that should consider LOG to sort out-of-order, + * between ERROR and FATAL. Generally this is the right thing for testing + * whether a message should go to the postmaster log, whereas a simple >= + * test is correct for testing whether the message should go to the client. + */ +static inline bool +is_log_level_output(int elevel, int log_min_level) +{ + if (elevel == LOG || elevel == LOG_SERVER_ONLY) + { + if (log_min_level == LOG || log_min_level <= ERROR) + return true; + } + else if (elevel == WARNING_CLIENT_ONLY) + { + /* never sent to log, regardless of log_min_level */ + return false; + } + else if (log_min_level == LOG) + { + /* elevel != LOG */ + if (elevel >= FATAL) + return true; + } + /* Neither is LOG */ + else if (elevel >= log_min_level) + return true; + + return false; +} + +/* + * Policy-setting subroutines. These are fairly simple, but it seems wise + * to have the code in just one place. + */ + +/* + * should_output_to_server --- should message of given elevel go to the log? + */ +static inline bool +should_output_to_server(int elevel) +{ + return is_log_level_output(elevel, log_min_messages); +} + +/* + * should_output_to_client --- should message of given elevel go to the client? + */ +static inline bool +should_output_to_client(int elevel) +{ + if (whereToSendOutput == DestRemote && elevel != LOG_SERVER_ONLY) + { + /* + * client_min_messages is honored only after we complete the + * authentication handshake. This is required both for security + * reasons and because many clients can't handle NOTICE messages + * during authentication. + */ + if (ClientAuthInProgress) + return (elevel >= ERROR); + else + return (elevel >= client_min_messages || elevel == INFO); + } + return false; +} + + +/* + * message_level_is_interesting --- would ereport/elog do anything? + * + * Returns true if ereport/elog with this elevel will not be a no-op. + * This is useful to short-circuit any expensive preparatory work that + * might be needed for a logging message. There is no point in + * prepending this to a bare ereport/elog call, however. + */ +bool +message_level_is_interesting(int elevel) +{ + /* + * Keep this in sync with the decision-making in errstart(). + */ + if (elevel >= ERROR || + should_output_to_server(elevel) || + should_output_to_client(elevel)) + return true; + return false; +} /* @@ -278,6 +364,20 @@ err_gettext(const char *str) #endif } +/* + * errstart_cold + * A simple wrapper around errstart, but hinted to be "cold". Supporting + * compilers are more likely to move code for branches containing this + * function into an area away from the calling function's code. This can + * result in more commonly executed code being more compact and fitting + * on fewer cache lines. + */ +pg_attribute_cold bool +errstart_cold(int elevel, const char *domain) +{ + return errstart(elevel, domain); +} + /* * errstart --- begin an error-reporting cycle * @@ -381,27 +481,8 @@ errstart(int elevel, const char *domain) * warning or less and not enabled for logging, just return false without * starting up any error logging machinery. */ - - /* Determine whether message is enabled for server log output */ - output_to_server = is_log_level_output(elevel, log_min_messages); - - /* Determine whether message is enabled for client output */ - if (whereToSendOutput == DestRemote && elevel != LOG_SERVER_ONLY) - { - /* - * client_min_messages is honored only after we complete the - * authentication handshake. This is required both for security - * reasons and because many clients can't handle NOTICE messages - * during authentication. - */ - if (ClientAuthInProgress) - output_to_client = (elevel >= ERROR); - else - output_to_client = (elevel >= client_min_messages || - elevel == INFO); - } - - /* Skip processing effort if non-error message will not be output */ + output_to_server = should_output_to_server(elevel); + output_to_client = should_output_to_client(elevel); if (elevel < ERROR && !output_to_server && !output_to_client) return false; @@ -479,9 +560,10 @@ errstart(int elevel, const char *domain) if (elevel >= ERROR) { edata->sqlerrcode = ERRCODE_INTERNAL_ERROR; + /* GPDB: internal errors report their source location */ edata->omit_location = false; } - else if (elevel == WARNING) + else if (elevel >= WARNING) edata->sqlerrcode = ERRCODE_WARNING; else edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION; @@ -559,6 +641,10 @@ errfinish(const char *filename, int lineno, const char *funcname) slash = strrchr(filename, '/'); if (slash) filename = slash + 1; + /* Some Windows compilers use backslashes in __FILE__ strings */ + slash = strrchr(filename, '\\'); + if (slash) + filename = slash + 1; } edata->filename = filename; @@ -626,9 +712,6 @@ errfinish(const char *filename, int lineno, const char *funcname) * what we want for NOTICE messages, but not for fatal exits.) This hack * is necessary because of poor design of old-style copy protocol. */ - if (elevel >= FATAL && whereToSendOutput == DestRemote) - pq_endcopyout(true); - /* CDB: If fatal internal error, linger so user can attach a debugger. */ if (elevel == FATAL && edata->sqlerrcode == ERRCODE_INTERNAL_ERROR && @@ -709,6 +792,13 @@ errfinish(const char *filename, int lineno, const char *funcname) fflush(stdout); fflush(stderr); + /* + * Let the statistics collector know. Only mark the session as + * terminated by fatal error if there is no other known cause. + */ + if (pgStatSessionEndCause == DISCONNECT_NORMAL) + pgStatSessionEndCause = DISCONNECT_FATAL; + /* * Do normal process-exit cleanup, then return exit code 1 to indicate * FATAL termination. The postmaster may or may not consider this @@ -941,10 +1031,7 @@ errcode_for_socket_access(void) switch (edata->saved_errno) { /* Loss of connection */ - case EPIPE: -#ifdef ECONNRESET - case ECONNRESET: -#endif + case ALL_CONNECTION_FAILURE_ERRNOS: edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE; break; @@ -1338,6 +1425,29 @@ errhint(const char *fmt,...) } +/* + * errhint_plural --- add a hint error message text to the current error, + * with support for pluralization of the message text + */ +int +errhint_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) +{ + ErrorData *edata = &errordata[errordata_stack_depth]; + MemoryContext oldcontext; + + recursion_depth++; + CHECK_STACK_DEPTH(); + oldcontext = MemoryContextSwitchTo(edata->assoc_context); + + EVALUATE_MESSAGE_PLURAL(edata->domain, hint, false); + + MemoryContextSwitchTo(oldcontext); + recursion_depth--; + return 0; /* return value does not matter */ +} + + /* * errcontext_msg --- add a context error message text to the current error * @@ -1345,7 +1455,7 @@ errhint(const char *fmt,...) * context information. We assume earlier calls represent more-closely-nested * states. */ -void +int errcontext_msg(const char *fmt,...) { ErrorData *edata = &errordata[errordata_stack_depth]; @@ -1360,6 +1470,7 @@ errcontext_msg(const char *fmt,...) MemoryContextSwitchTo(oldcontext); recursion_depth--; errno = edata->saved_errno; /*CDB*/ + return 0; } /* @@ -1371,7 +1482,7 @@ errcontext_msg(const char *fmt,...) * a set_errcontext_domain() call to specify the domain. This is usually * done transparently by the errcontext() macro. */ -void +int set_errcontext_domain(const char *domain) { ErrorData *edata = &errordata[errordata_stack_depth]; @@ -1381,6 +1492,7 @@ set_errcontext_domain(const char *domain) /* the default text domain is the backend's */ edata->context_domain = domain ? domain : PG_TEXTDOMAIN("postgres"); + return 0; } @@ -1440,7 +1552,7 @@ errfunction(const char *funcname) /* * errposition --- add cursor position to the current error */ -void +int errposition(int cursorpos) { ErrorData *edata = &errordata[errordata_stack_depth]; @@ -1449,6 +1561,8 @@ errposition(int cursorpos) CHECK_STACK_DEPTH(); edata->cursorpos = cursorpos; + + return 0; } /* @@ -2013,16 +2127,10 @@ pg_re_throw(void) /* * At least in principle, the increase in severity could have changed - * where-to-output decisions, so recalculate. This should stay in - * sync with errstart(), which see for comments. + * where-to-output decisions, so recalculate. */ - if (IsPostmasterEnvironment) - edata->output_to_server = is_log_level_output(FATAL, - log_min_messages); - else - edata->output_to_server = (FATAL >= log_min_messages); - if (whereToSendOutput == DestRemote) - edata->output_to_client = true; + edata->output_to_server = should_output_to_server(FATAL); + edata->output_to_client = should_output_to_client(FATAL); /* * We can use errfinish() for the rest, but we don't want it to call @@ -2542,6 +2650,7 @@ write_eventlog(int level, const char *line, int len) eventlevel = EVENTLOG_INFORMATION_TYPE; break; case WARNING: + case WARNING_CLIENT_ONLY: eventlevel = EVENTLOG_WARNING_TYPE; break; case ERROR: @@ -2749,6 +2858,8 @@ write_console(const char *line, int len) * Conversion on non-win32 platforms is not implemented yet. It requires * non-throw version of pg_do_encoding_conversion(), that converts * unconvertable characters to '?' without errors. + * + * XXX: We have a no-throw version now. It doesn't convert to '?' though. */ #endif @@ -3271,6 +3382,14 @@ log_line_prefix(StringInfo buf, ErrorData *edata) else appendStringInfoString(buf, unpack_sql_state(edata->sqlerrcode)); break; + case 'Q': + if (padding != 0) + appendStringInfo(buf, "%*lld", padding, + (long long) pgstat_get_my_query_id()); + else + appendStringInfo(buf, "%lld", + (long long) pgstat_get_my_query_id()); + break; default: /* format error - ignore it */ break; @@ -3513,6 +3632,10 @@ write_csvlog(ErrorData *edata) if (leader && leader->pid != MyProcPid) appendStringInfo(&buf, "%d", leader->pid); } + appendStringInfoChar(&buf, ','); + + /* query id */ + appendStringInfo(&buf, "%lld", (long long) pgstat_get_my_query_id()); appendStringInfoChar(&buf, '\n'); @@ -4441,6 +4564,7 @@ send_message_to_server_log(ErrorData *edata) break; case NOTICE: case WARNING: + case WARNING_CLIENT_ONLY: syslog_level = LOG_NOTICE; break; case ERROR: @@ -4634,10 +4758,14 @@ send_message_to_frontend(ErrorData *edata) { StringInfoData msgbuf; - /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */ - pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E'); - - if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) + /* + * We no longer support pre-3.0 FE/BE protocol, except here. If a client + * tries to connect using an older protocol version, it's nice to send the + * "protocol version not supported" error in a format the client + * understands. If protocol hasn't been set yet, early in backend + * startup, assume modern protocol. + */ + if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3 || FrontendProtocol == 0) { /* New style with separate fields */ const char *sev; @@ -4645,6 +4773,9 @@ send_message_to_frontend(ErrorData *edata) int ssval; int i; + /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */ + pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E'); + sev = error_severity(edata->elevel); pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY); err_sendstring(&msgbuf, _(sev)); @@ -4760,6 +4891,8 @@ send_message_to_frontend(ErrorData *edata) } pq_sendbyte(&msgbuf, '\0'); /* terminator */ + + pq_endmessage(&msgbuf); } else { @@ -4770,30 +4903,19 @@ send_message_to_frontend(ErrorData *edata) appendStringInfo(&buf, "%s: ", _(error_severity(edata->elevel))); - if (edata->show_funcname && edata->funcname) - appendStringInfo(&buf, "%s: ", edata->funcname); - if (edata->message) appendStringInfoString(&buf, edata->message); else appendStringInfoString(&buf, _("missing error text")); - if (edata->cursorpos > 0) - appendStringInfo(&buf, _(" at character %d"), - edata->cursorpos); - else if (edata->internalpos > 0) - appendStringInfo(&buf, _(" at character %d"), - edata->internalpos); - appendStringInfoChar(&buf, '\n'); - err_sendstring(&msgbuf, buf.data); + /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */ + pq_putmessage_v2((edata->elevel < ERROR) ? 'N' : 'E', buf.data, buf.len + 1); pfree(buf.data); } - pq_endmessage(&msgbuf); - /* * This flush is normally not necessary, since postgres.c will flush out * waiting data when control returns to the main loop. But it seems best @@ -4842,6 +4964,7 @@ error_severity(int elevel) prefix = gettext_noop("NOTICE"); break; case WARNING: + case WARNING_CLIENT_ONLY: prefix = gettext_noop("WARNING"); break; case ERROR: @@ -4971,35 +5094,6 @@ write_stderr(const char *fmt,...) } -/* - * is_log_level_output -- is elevel logically >= log_min_level? - * - * We use this for tests that should consider LOG to sort out-of-order, - * between ERROR and FATAL. Generally this is the right thing for testing - * whether a message should go to the postmaster log, whereas a simple >= - * test is correct for testing whether the message should go to the client. - */ -static bool -is_log_level_output(int elevel, int log_min_level) -{ - if (elevel == LOG || elevel == LOG_SERVER_ONLY) - { - if (log_min_level == LOG || log_min_level <= ERROR) - return true; - } - else if (log_min_level == LOG) - { - /* elevel != LOG */ - if (elevel >= FATAL) - return true; - } - /* Neither is LOG */ - else if (elevel >= log_min_level) - return true; - - return false; -} - /* * Adjust the level of a recovery-related message per trace_recovery_messages. * diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index bd01b543baf9..7dacd87b98c5 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -3,7 +3,7 @@ * dfmgr.c * Dynamic function manager code. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -728,13 +728,12 @@ find_rendezvous_variable(const char *varName) { HASHCTL ctl; - MemSet(&ctl, 0, sizeof(ctl)); ctl.keysize = NAMEDATALEN; ctl.entrysize = sizeof(rendezvousHashEntry); rendezvousHash = hash_create("Rendezvous variable hash", 16, &ctl, - HASH_ELEM); + HASH_ELEM | HASH_STRINGS); } /* Find or create the hashtable entry for this varName */ diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index 05d87da41e9e..fcd55772dfd4 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -3,7 +3,7 @@ * fmgr.c * The Postgres function manager. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -275,7 +275,7 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, * If *mod == NULL and *fn != NULL, the function is implemented by a symbol in * the main binary. * - * If *mod != NULL and *fn !=NULL the function is implemented in an extension + * If *mod != NULL and *fn != NULL the function is implemented in an extension * shared object. * * The returned module and function names are pstrdup'ed into the current @@ -290,14 +290,11 @@ fmgr_symbol(Oid functionId, char **mod, char **fn) Datum prosrcattr; Datum probinattr; - /* Otherwise we need the pg_proc entry */ procedureTuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId)); if (!HeapTupleIsValid(procedureTuple)) elog(ERROR, "cache lookup failed for function %u", functionId); procedureStruct = (Form_pg_proc) GETSTRUCT(procedureTuple); - /* - */ if (procedureStruct->prosecdef || !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) || FmgrHookIsNeeded(functionId)) @@ -567,7 +564,6 @@ record_C_func(HeapTuple procedureTuple, { HASHCTL hash_ctl; - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(Oid); hash_ctl.entrysize = sizeof(CFuncHashTabEntry); CFuncHash = hash_create("CFuncHash", @@ -2009,7 +2005,7 @@ get_fn_opclass_options(FmgrInfo *flinfo) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("opclass options info is absent in function call context"))); + errmsg("operator class options info is absent in function call context"))); return NULL; } diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c index 1a0d9320fdec..8510b62c94a1 100644 --- a/src/backend/utils/fmgr/funcapi.c +++ b/src/backend/utils/fmgr/funcapi.c @@ -4,7 +4,7 @@ * Utility and convenience functions for fmgr functions that return * sets and/or composite types, or deal with VARIADIC inputs. * - * Copyright (c) 2002-2020, PostgreSQL Global Development Group + * Copyright (c) 2002-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/fmgr/funcapi.c @@ -36,6 +36,7 @@ typedef struct polymorphic_actuals Oid anyelement_type; /* anyelement mapping, if known */ Oid anyarray_type; /* anyarray mapping, if known */ Oid anyrange_type; /* anyrange mapping, if known */ + Oid anymultirange_type; /* anymultirange mapping, if known */ } polymorphic_actuals; static void shutdown_MultiFuncCall(Datum arg); @@ -47,6 +48,7 @@ static TypeFuncClass internal_get_result_type(Oid funcid, static void resolve_anyelement_from_others(polymorphic_actuals *actuals); static void resolve_anyarray_from_others(polymorphic_actuals *actuals); static void resolve_anyrange_from_others(polymorphic_actuals *actuals); +static void resolve_anymultirange_from_others(polymorphic_actuals *actuals); static bool resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, Node *call_expr); @@ -539,6 +541,34 @@ resolve_anyelement_from_others(polymorphic_actuals *actuals) format_type_be(range_base_type)))); actuals->anyelement_type = range_typelem; } + else if (OidIsValid(actuals->anymultirange_type)) + { + /* Use the element type based on the multirange type */ + Oid multirange_base_type; + Oid multirange_typelem; + Oid range_base_type; + Oid range_typelem; + + multirange_base_type = getBaseType(actuals->anymultirange_type); + multirange_typelem = get_multirange_range(multirange_base_type); + if (!OidIsValid(multirange_typelem)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("argument declared %s is not a multirange type but type %s", + "anymultirange", + format_type_be(multirange_base_type)))); + + range_base_type = getBaseType(multirange_typelem); + range_typelem = get_range_subtype(range_base_type); + + if (!OidIsValid(range_typelem)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("argument declared %s does not contain a range type but type %s", + "anymultirange", + format_type_be(range_base_type)))); + actuals->anyelement_type = range_typelem; + } else elog(ERROR, "could not determine polymorphic type"); } @@ -576,10 +606,53 @@ static void resolve_anyrange_from_others(polymorphic_actuals *actuals) { /* - * We can't deduce a range type from other polymorphic inputs, because - * there may be multiple range types with the same subtype. + * We can't deduce a range type from other polymorphic array or base + * types, because there may be multiple range types with the same subtype, + * but we can deduce it from a polymorphic multirange type. + */ + if (OidIsValid(actuals->anymultirange_type)) + { + /* Use the element type based on the multirange type */ + Oid multirange_base_type = getBaseType(actuals->anymultirange_type); + Oid multirange_typelem = get_multirange_range(multirange_base_type); + + if (!OidIsValid(multirange_typelem)) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("argument declared %s is not a multirange type but type %s", + "anymultirange", + format_type_be(multirange_base_type)))); + actuals->anyrange_type = multirange_typelem; + } + else + elog(ERROR, "could not determine polymorphic type"); +} + +/* + * Resolve actual type of ANYMULTIRANGE from other polymorphic inputs + */ +static void +resolve_anymultirange_from_others(polymorphic_actuals *actuals) +{ + /* + * We can't deduce a multirange type from polymorphic array or base types, + * because there may be multiple range types with the same subtype, but we + * can deduce it from a polymorphic range type. */ - elog(ERROR, "could not determine polymorphic type"); + if (OidIsValid(actuals->anyrange_type)) + { + Oid range_base_type = getBaseType(actuals->anyrange_type); + Oid multirange_typeid = get_range_multirange(range_base_type); + + if (!OidIsValid(multirange_typeid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("could not find multirange type for data type %s", + format_type_be(actuals->anyrange_type)))); + actuals->anymultirange_type = multirange_typeid; + } + else + elog(ERROR, "could not determine polymorphic type"); } /* @@ -602,9 +675,11 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, bool have_anyelement_result = false; bool have_anyarray_result = false; bool have_anyrange_result = false; + bool have_anymultirange_result = false; bool have_anycompatible_result = false; bool have_anycompatible_array_result = false; bool have_anycompatible_range_result = false; + bool have_anycompatible_multirange_result = false; polymorphic_actuals poly_actuals; polymorphic_actuals anyc_actuals; Oid anycollation = InvalidOid; @@ -630,6 +705,10 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, have_polymorphic_result = true; have_anyrange_result = true; break; + case ANYMULTIRANGEOID: + have_polymorphic_result = true; + have_anymultirange_result = true; + break; case ANYCOMPATIBLEOID: case ANYCOMPATIBLENONARRAYOID: have_polymorphic_result = true; @@ -643,6 +722,10 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, have_polymorphic_result = true; have_anycompatible_range_result = true; break; + case ANYCOMPATIBLEMULTIRANGEOID: + have_polymorphic_result = true; + have_anycompatible_multirange_result = true; + break; default: break; } @@ -696,6 +779,15 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, return false; } break; + case ANYMULTIRANGEOID: + if (!OidIsValid(poly_actuals.anymultirange_type)) + { + poly_actuals.anymultirange_type = + get_call_expr_argtype(call_expr, i); + if (!OidIsValid(poly_actuals.anymultirange_type)) + return false; + } + break; case ANYCOMPATIBLEOID: case ANYCOMPATIBLENONARRAYOID: if (!OidIsValid(anyc_actuals.anyelement_type)) @@ -724,6 +816,15 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, return false; } break; + case ANYCOMPATIBLEMULTIRANGEOID: + if (!OidIsValid(anyc_actuals.anymultirange_type)) + { + anyc_actuals.anymultirange_type = + get_call_expr_argtype(call_expr, i); + if (!OidIsValid(anyc_actuals.anymultirange_type)) + return false; + } + break; default: break; } @@ -739,6 +840,9 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, if (have_anyrange_result && !OidIsValid(poly_actuals.anyrange_type)) resolve_anyrange_from_others(&poly_actuals); + if (have_anymultirange_result && !OidIsValid(poly_actuals.anymultirange_type)) + resolve_anymultirange_from_others(&poly_actuals); + if (have_anycompatible_result && !OidIsValid(anyc_actuals.anyelement_type)) resolve_anyelement_from_others(&anyc_actuals); @@ -748,6 +852,9 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, if (have_anycompatible_range_result && !OidIsValid(anyc_actuals.anyrange_type)) resolve_anyrange_from_others(&anyc_actuals); + if (have_anycompatible_multirange_result && !OidIsValid(anyc_actuals.anymultirange_type)) + resolve_anymultirange_from_others(&anyc_actuals); + /* * Identify the collation to use for polymorphic OUT parameters. (It'll * necessarily be the same for both anyelement and anyarray, likewise for @@ -816,6 +923,14 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, 0); /* no collation should be attached to a range type */ break; + case ANYMULTIRANGEOID: + TupleDescInitEntry(tupdesc, i + 1, + NameStr(att->attname), + poly_actuals.anymultirange_type, + -1, + 0); + /* no collation should be attached to a multirange type */ + break; case ANYCOMPATIBLEOID: case ANYCOMPATIBLENONARRAYOID: TupleDescInitEntry(tupdesc, i + 1, @@ -841,6 +956,14 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args, 0); /* no collation should be attached to a range type */ break; + case ANYCOMPATIBLEMULTIRANGEOID: + TupleDescInitEntry(tupdesc, i + 1, + NameStr(att->attname), + anyc_actuals.anymultirange_type, + -1, + 0); + /* no collation should be attached to a multirange type */ + break; default: break; } @@ -870,9 +993,11 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, bool have_anyelement_result = false; bool have_anyarray_result = false; bool have_anyrange_result = false; + bool have_anymultirange_result = false; bool have_anycompatible_result = false; bool have_anycompatible_array_result = false; bool have_anycompatible_range_result = false; + bool have_anycompatible_multirange_result = false; polymorphic_actuals poly_actuals; polymorphic_actuals anyc_actuals; int inargno; @@ -948,6 +1073,24 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, argtypes[i] = poly_actuals.anyrange_type; } break; + case ANYMULTIRANGEOID: + if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE) + { + have_polymorphic_result = true; + have_anymultirange_result = true; + } + else + { + if (!OidIsValid(poly_actuals.anymultirange_type)) + { + poly_actuals.anymultirange_type = + get_call_expr_argtype(call_expr, inargno); + if (!OidIsValid(poly_actuals.anymultirange_type)) + return false; + } + argtypes[i] = poly_actuals.anymultirange_type; + } + break; case ANYCOMPATIBLEOID: case ANYCOMPATIBLENONARRAYOID: if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE) @@ -1003,6 +1146,24 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, argtypes[i] = anyc_actuals.anyrange_type; } break; + case ANYCOMPATIBLEMULTIRANGEOID: + if (argmode == PROARGMODE_OUT || argmode == PROARGMODE_TABLE) + { + have_polymorphic_result = true; + have_anycompatible_multirange_result = true; + } + else + { + if (!OidIsValid(anyc_actuals.anymultirange_type)) + { + anyc_actuals.anymultirange_type = + get_call_expr_argtype(call_expr, inargno); + if (!OidIsValid(anyc_actuals.anymultirange_type)) + return false; + } + argtypes[i] = anyc_actuals.anymultirange_type; + } + break; default: break; } @@ -1024,6 +1185,9 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, if (have_anyrange_result && !OidIsValid(poly_actuals.anyrange_type)) resolve_anyrange_from_others(&poly_actuals); + if (have_anymultirange_result && !OidIsValid(poly_actuals.anymultirange_type)) + resolve_anymultirange_from_others(&poly_actuals); + if (have_anycompatible_result && !OidIsValid(anyc_actuals.anyelement_type)) resolve_anyelement_from_others(&anyc_actuals); @@ -1033,6 +1197,9 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, if (have_anycompatible_range_result && !OidIsValid(anyc_actuals.anyrange_type)) resolve_anyrange_from_others(&anyc_actuals); + if (have_anycompatible_multirange_result && !OidIsValid(anyc_actuals.anymultirange_type)) + resolve_anymultirange_from_others(&anyc_actuals); + /* And finally replace the output column types as needed */ for (i = 0; i < numargs; i++) { @@ -1049,6 +1216,9 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, case ANYRANGEOID: argtypes[i] = poly_actuals.anyrange_type; break; + case ANYMULTIRANGEOID: + argtypes[i] = poly_actuals.anymultirange_type; + break; case ANYCOMPATIBLEOID: case ANYCOMPATIBLENONARRAYOID: argtypes[i] = anyc_actuals.anyelement_type; @@ -1059,6 +1229,9 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes, case ANYCOMPATIBLERANGEOID: argtypes[i] = anyc_actuals.anyrange_type; break; + case ANYCOMPATIBLEMULTIRANGEOID: + argtypes[i] = anyc_actuals.anymultirange_type; + break; default: break; } @@ -1088,6 +1261,7 @@ get_type_func_class(Oid typid, Oid *base_typeid) case TYPTYPE_BASE: case TYPTYPE_ENUM: case TYPTYPE_RANGE: + case TYPTYPE_MULTIRANGE: return TYPEFUNC_SCALAR; case TYPTYPE_DOMAIN: *base_typeid = typid = getBaseType(typid); @@ -1159,7 +1333,7 @@ get_func_arg_info(HeapTuple procTup, numargs < 0 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "proallargtypes is not a 1-D Oid array"); + elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls"); Assert(numargs >= procStruct->pronargs); *p_argtypes = (Oid *) palloc(numargs * sizeof(Oid)); memcpy(*p_argtypes, ARR_DATA_PTR(arr), @@ -1206,7 +1380,8 @@ get_func_arg_info(HeapTuple procTup, ARR_DIMS(arr)[0] != numargs || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != CHAROID) - elog(ERROR, "proargmodes is not a 1-D char array"); + elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls", + numargs); *p_argmodes = (char *) palloc(numargs * sizeof(char)); memcpy(*p_argmodes, ARR_DATA_PTR(arr), numargs * sizeof(char)); @@ -1218,7 +1393,9 @@ get_func_arg_info(HeapTuple procTup, /* * get_func_trftypes * - * Returns the number of transformed types used by function. + * Returns the number of transformed types used by the function. + * If there are any, a palloc'd array of the type OIDs is returned + * into *p_trftypes. */ int get_func_trftypes(HeapTuple procTup, @@ -1246,8 +1423,7 @@ get_func_trftypes(HeapTuple procTup, nelems < 0 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "protrftypes is not a 1-D Oid array"); - Assert(nelems >= ((Form_pg_proc) GETSTRUCT(procTup))->pronargs); + elog(ERROR, "protrftypes is not a 1-D Oid array or it contains nulls"); *p_trftypes = (Oid *) palloc(nelems * sizeof(Oid)); memcpy(*p_trftypes, ARR_DATA_PTR(arr), nelems * sizeof(Oid)); @@ -1296,7 +1472,7 @@ get_func_input_arg_names(Datum proargnames, Datum proargmodes, if (ARR_NDIM(arr) != 1 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != TEXTOID) - elog(ERROR, "proargnames is not a 1-D text array"); + elog(ERROR, "proargnames is not a 1-D text array or it contains nulls"); deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT, &argnames, NULL, &numargs); if (proargmodes != PointerGetDatum(NULL)) @@ -1306,7 +1482,8 @@ get_func_input_arg_names(Datum proargnames, Datum proargmodes, ARR_DIMS(arr)[0] != numargs || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != CHAROID) - elog(ERROR, "proargmodes is not a 1-D char array"); + elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls", + numargs); argmodes = (char *) ARR_DATA_PTR(arr); } else @@ -1402,14 +1579,15 @@ get_func_result_name(Oid functionId) numargs < 0 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != CHAROID) - elog(ERROR, "proargmodes is not a 1-D char array"); + elog(ERROR, "proargmodes is not a 1-D char array or it contains nulls"); argmodes = (char *) ARR_DATA_PTR(arr); arr = DatumGetArrayTypeP(proargnames); /* ensure not toasted */ if (ARR_NDIM(arr) != 1 || ARR_DIMS(arr)[0] != numargs || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != TEXTOID) - elog(ERROR, "proargnames is not a 1-D text array"); + elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls", + numargs); deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT, &argnames, NULL, &nargnames); Assert(nargnames == numargs); @@ -1540,14 +1718,15 @@ build_function_result_tupdesc_d(char prokind, numargs < 0 || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "proallargtypes is not a 1-D Oid array"); + elog(ERROR, "proallargtypes is not a 1-D Oid array or it contains nulls"); argtypes = (Oid *) ARR_DATA_PTR(arr); arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */ if (ARR_NDIM(arr) != 1 || ARR_DIMS(arr)[0] != numargs || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != CHAROID) - elog(ERROR, "proargmodes is not a 1-D char array"); + elog(ERROR, "proargmodes is not a 1-D char array of length %d or it contains nulls", + numargs); argmodes = (char *) ARR_DATA_PTR(arr); if (proargnames != PointerGetDatum(NULL)) { @@ -1556,7 +1735,8 @@ build_function_result_tupdesc_d(char prokind, ARR_DIMS(arr)[0] != numargs || ARR_HASNULL(arr) || ARR_ELEMTYPE(arr) != TEXTOID) - elog(ERROR, "proargnames is not a 1-D text array"); + elog(ERROR, "proargnames is not a 1-D text array of length %d or it contains nulls", + numargs); deconstruct_array(arr, TEXTOID, -1, false, TYPALIGN_INT, &argnames, NULL, &nargnames); Assert(nargnames == numargs); diff --git a/src/backend/utils/fmgr/test/dfmgr_test.c b/src/backend/utils/fmgr/test/dfmgr_test.c index 951c7ecc9102..331f6f96dba0 100755 --- a/src/backend/utils/fmgr/test/dfmgr_test.c +++ b/src/backend/utils/fmgr/test/dfmgr_test.c @@ -68,16 +68,18 @@ errdetail_internal_impl(const char* fmt, ...) #include "../dfmgr.c" #define EXPECT_EREPORT(LOG_LEVEL) \ - expect_any(errstart, elevel); \ - expect_any(errstart, domain); \ if (LOG_LEVEL < ERROR) \ { \ - will_return(errstart, false); \ + expect_any(errstart, elevel); \ + expect_any(errstart, domain); \ + will_return(errstart, false); \ + } \ + else \ + { \ + expect_any(errstart_cold, elevel); \ + expect_any(errstart_cold, domain); \ + will_return(errstart_cold, true); \ } \ - else \ - { \ - will_return(errstart, true);\ - } \ /* diff --git a/src/backend/utils/generate-errcodes.pl b/src/backend/utils/generate-errcodes.pl index 868a163578d7..c5cdd388138d 100644 --- a/src/backend/utils/generate-errcodes.pl +++ b/src/backend/utils/generate-errcodes.pl @@ -1,10 +1,10 @@ #!/usr/bin/perl # # Generate the errcodes.h header from errcodes.txt -# Copyright (c) 2000-2020, PostgreSQL Global Development Group +# Copyright (c) 2000-2021, PostgreSQL Global Development Group -use warnings; use strict; +use warnings; print "/* autogenerated from src/backend/utils/errcodes.txt, do not edit */\n"; diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c index 3b3570f2a35d..9e719ec64085 100644 --- a/src/backend/utils/hash/dynahash.c +++ b/src/backend/utils/hash/dynahash.c @@ -30,11 +30,12 @@ * dynahash.c provides support for these types of lookup keys: * * 1. Null-terminated C strings (truncated if necessary to fit in keysize), - * compared as though by strcmp(). This is the default behavior. + * compared as though by strcmp(). This is selected by specifying the + * HASH_STRINGS flag to hash_create. * * 2. Arbitrary binary data of size keysize, compared as though by memcmp(). * (Caller must ensure there are no undefined padding bits in the keys!) - * This is selected by specifying HASH_BLOBS flag to hash_create. + * This is selected by specifying the HASH_BLOBS flag to hash_create. * * 3. More complex key behavior can be selected by specifying user-supplied * hashing, comparison, and/or key-copying functions. At least a hashing @@ -47,11 +48,11 @@ * locks. * - Shared memory hashes are allocated in a fixed size area at startup and * are discoverable by name from other processes. - * - Because entries don't need to be moved in the case of hash conflicts, has - * better performance for large entries + * - Because entries don't need to be moved in the case of hash conflicts, + * dynahash has better performance for large entries. * - Guarantees stable pointers to entries. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -122,7 +123,6 @@ #define DEF_SEGSIZE 256 #define DEF_SEGSIZE_SHIFT 8 /* must be log2(DEF_SEGSIZE) */ #define DEF_DIRSIZE 256 -#define DEF_FFACTOR 1 /* default fill factor */ /* Number of freelists to be used for a partitioned hash table. */ #define NUM_FREELISTS 32 @@ -191,7 +191,6 @@ struct HASHHDR Size keysize; /* hash key length in bytes */ Size entrysize; /* total user element size in bytes */ long num_partitions; /* # partitions (must be power of 2), or 0 */ - long ffactor; /* target fill factor */ long max_dsize; /* 'dsize' limit if directory is fixed size */ long ssize; /* segment size --- must be power of 2 */ int sshift; /* segment shift = log2(ssize) */ @@ -318,6 +317,28 @@ string_compare(const char *key1, const char *key2, Size keysize) * *info: additional table parameters, as indicated by flags * flags: bitmask indicating which parameters to take from *info * + * The flags value *must* include HASH_ELEM. (Formerly, this was nominally + * optional, but the default keysize and entrysize values were useless.) + * The flags value must also include exactly one of HASH_STRINGS, HASH_BLOBS, + * or HASH_FUNCTION, to define the key hashing semantics (C strings, + * binary blobs, or custom, respectively). Callers specifying a custom + * hash function will likely also want to use HASH_COMPARE, and perhaps + * also HASH_KEYCOPY, to control key comparison and copying. + * Another often-used flag is HASH_CONTEXT, to allocate the hash table + * under info->hcxt rather than under TopMemoryContext; the default + * behavior is only suitable for session-lifespan hash tables. + * Other flags bits are special-purpose and seldom used, except for those + * associated with shared-memory hash tables, for which see ShmemInitHash(). + * + * Fields in *info are read only when the associated flags bit is set. + * It is not necessary to initialize other fields of *info. + * Neither tabname nor *info need persist after the hash_create() call. + * + * Note: It is deprecated for callers of hash_create() to explicitly specify + * string_hash, tag_hash, uint32_hash, or oid_hash. Just set HASH_STRINGS or + * HASH_BLOBS. Use HASH_FUNCTION only when you want something other than + * one of these. + * * Note: for a shared-memory hashtable, nelem needs to be a pretty good * estimate, since we can't expand the table on the fly. But an unshared * hashtable can be expanded on-the-fly, so it's better for nelem to be @@ -325,11 +346,19 @@ string_compare(const char *key1, const char *key2, Size keysize) * large nelem will penalize hash_seq_search speed without buying much. */ HTAB * -hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) +hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags) { HTAB *hashp; HASHHDR *hctl; + /* + * Hash tables now allocate space for key and data, but you have to say + * how much space to allocate. + */ + Assert(flags & HASH_ELEM); + Assert(info->keysize > 0); + Assert(info->entrysize >= info->keysize); + /* * For shared hash tables, we have a local hash header (HTAB struct) that * we allocate in TopMemoryContext; all else is in shared memory. @@ -372,28 +401,43 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) * Select the appropriate hash function (see comments at head of file). */ if (flags & HASH_FUNCTION) + { + Assert(!(flags & (HASH_BLOBS | HASH_STRINGS))); hashp->hash = info->hash; + } else if (flags & HASH_BLOBS) { + Assert(!(flags & HASH_STRINGS)); /* We can optimize hashing for common key sizes */ - Assert(flags & HASH_ELEM); if (info->keysize == sizeof(uint32)) hashp->hash = uint32_hash; else hashp->hash = tag_hash; } else - hashp->hash = string_hash; /* default hash function */ + { + /* + * string_hash used to be considered the default hash method, and in a + * non-assert build it effectively still is. But we now consider it + * an assertion error to not say HASH_STRINGS explicitly. To help + * catch mistaken usage of HASH_STRINGS, we also insist on a + * reasonably long string length: if the keysize is only 4 or 8 bytes, + * it's almost certainly an integer or pointer not a string. + */ + Assert(flags & HASH_STRINGS); + Assert(info->keysize > 8); + + hashp->hash = string_hash; + } /* * If you don't specify a match function, it defaults to string_compare if - * you used string_hash (either explicitly or by default) and to memcmp - * otherwise. + * you used string_hash, and to memcmp otherwise. * * Note: explicitly specifying string_hash is deprecated, because this * might not work for callers in loadable modules on some platforms due to * referencing a trampoline instead of the string_hash function proper. - * Just let it default, eh? + * Specify HASH_STRINGS instead. */ if (flags & HASH_COMPARE) hashp->match = info->match; @@ -497,8 +541,6 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) /* ssize had better be a power of 2 */ Assert(hctl->ssize == (1L << hctl->sshift)); } - if (flags & HASH_FFACTOR) - hctl->ffactor = info->ffactor; /* * SHM hash tables have fixed directory size passed by the caller. @@ -509,16 +551,9 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) hctl->dsize = info->dsize; } - /* - * hash table now allocates space for key and data but you have to say how - * much space to allocate - */ - if (flags & HASH_ELEM) - { - Assert(info->entrysize >= info->keysize); - hctl->keysize = info->keysize; - hctl->entrysize = info->entrysize; - } + /* remember the entry sizes, too */ + hctl->keysize = info->keysize; + hctl->entrysize = info->entrysize; /* make local copies of heavily-used constant fields */ hashp->keysize = hctl->keysize; @@ -597,14 +632,8 @@ hdefault(HTAB *hashp) hctl->dsize = DEF_DIRSIZE; hctl->nsegs = 0; - /* rather pointless defaults for key & entry size */ - hctl->keysize = sizeof(char *); - hctl->entrysize = 2 * sizeof(char *); - hctl->num_partitions = 0; /* not partitioned */ - hctl->ffactor = DEF_FFACTOR; - /* table has no fixed maximum size */ hctl->max_dsize = NO_MAX_DSIZE; @@ -670,11 +699,10 @@ init_htab(HTAB *hashp, long nelem) SpinLockInit(&(hctl->freeList[i].mutex)); /* - * Divide number of elements by the fill factor to determine a desired - * number of buckets. Allocate space for the next greater power of two - * number of buckets + * Allocate space for the next greater power of two number of buckets, + * assuming a desired maximum load factor of 1. */ - nbuckets = next_pow2_int((nelem - 1) / hctl->ffactor + 1); + nbuckets = next_pow2_int(nelem); /* * In a partitioned table, nbuckets must be at least equal to @@ -733,7 +761,6 @@ init_htab(HTAB *hashp, long nelem) "DIRECTORY SIZE ", hctl->dsize, "SEGMENT SIZE ", hctl->ssize, "SEGMENT SHIFT ", hctl->sshift, - "FILL FACTOR ", hctl->ffactor, "MAX BUCKET ", hctl->max_bucket, "HIGH MASK ", hctl->high_mask, "LOW MASK ", hctl->low_mask, @@ -761,7 +788,7 @@ hash_estimate_size(long num_entries, Size entrysize) elementAllocCnt; /* estimate number of buckets wanted */ - nBuckets = next_pow2_long((num_entries - 1) / DEF_FFACTOR + 1); + nBuckets = next_pow2_long(num_entries); /* # of segments needed for nBuckets */ nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1); /* directory entries */ @@ -804,7 +831,7 @@ hash_select_dirsize(long num_entries) nDirEntries; /* estimate number of buckets wanted */ - nBuckets = next_pow2_long((num_entries - 1) / DEF_FFACTOR + 1); + nBuckets = next_pow2_long(num_entries); /* # of segments needed for nBuckets */ nSegments = next_pow2_long((nBuckets - 1) / DEF_SEGSIZE + 1); /* directory entries */ @@ -971,11 +998,10 @@ hash_search_with_hash_value(HTAB *hashp, { /* * Can't split if running in partitioned mode, nor if frozen, nor if - * table is the subject of any active hash_seq_search scans. Strange - * order of these tests is to try to check cheaper conditions first. + * table is the subject of any active hash_seq_search scans. */ - if (!IS_PARTITIONED(hctl) && !hashp->frozen && - hctl->freeList[0].nentries / (long) (hctl->max_bucket + 1) >= hctl->ffactor && + if (hctl->freeList[0].nentries > (long) hctl->max_bucket && + !IS_PARTITIONED(hctl) && !hashp->frozen && !has_seq_scans(hashp)) (void) expand_table(hashp); } diff --git a/src/backend/utils/hash/pg_crc.c b/src/backend/utils/hash/pg_crc.c index 41e9597fb009..77e3f6e65531 100644 --- a/src/backend/utils/hash/pg_crc.c +++ b/src/backend/utils/hash/pg_crc.c @@ -7,7 +7,7 @@ * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from * http://ross.net/crc/download/crc_v3.txt or several other net sites. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index 45a70b6161de..5f414d8c3222 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -3,7 +3,7 @@ * globals.c * global variable declarations * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -36,15 +36,17 @@ volatile sig_atomic_t ProcDiePending = false; volatile sig_atomic_t CheckClientConnectionPending = false; volatile sig_atomic_t ClientConnectionLost = false; volatile sig_atomic_t IdleInTransactionSessionTimeoutPending = false; +volatile sig_atomic_t IdleSessionTimeoutPending = false; volatile sig_atomic_t ProcSignalBarrierPending = false; volatile sig_atomic_t IdleGangTimeoutPending = false; /* * GPDB: Make these signed integers (instead of uint32) to detect garbage * negative values. */ -volatile int32 InterruptHoldoffCount = 0; -volatile int32 QueryCancelHoldoffCount = 0; -volatile int32 CritSectionCount = 0; +volatile uint32 InterruptHoldoffCount = 0; +volatile uint32 QueryCancelHoldoffCount = 0; +volatile uint32 CritSectionCount = 0; +volatile sig_atomic_t LogMemoryContextPending = false; int MyProcPid; pg_time_t MyStartTime; @@ -160,7 +162,7 @@ int max_parallel_workers = 8; int MaxBackends = 0; int VacuumCostPageHit = 1; /* GUC parameters for vacuum */ -int VacuumCostPageMiss = 10; +int VacuumCostPageMiss = 2; int VacuumCostPageDirty = 20; int VacuumCostLimit = 200; double VacuumCostDelay = 0; diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 50d6054cebc0..aab612dd6914 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -3,7 +3,7 @@ * miscinit.c * miscellaneous initialization support stuff * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,11 +32,13 @@ #include "catalog/pg_authid.h" #include "common/file_perm.h" #include "libpq/libpq.h" +#include "libpq/pqsignal.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/autovacuum.h" #include "postmaster/fts.h" +#include "postmaster/interrupt.h" #include "postmaster/postmaster.h" #include "postmaster/startup.h" #include "replication/walsender.h" @@ -126,6 +128,11 @@ InitPostmasterChild(void) /* We don't want the postmaster's proc_exit() handlers */ on_exit_reset(); + /* In EXEC_BACKEND case we will not have inherited BlockSig etc values */ +#ifdef EXEC_BACKEND + pqinitmask(); +#endif + /* Initialize process-local latch support */ InitializeLatchSupport(); MyLatch = &LocalLatchData; @@ -143,6 +150,18 @@ InitPostmasterChild(void) elog(FATAL, "setsid() failed: %m"); #endif + /* + * Every postmaster child process is expected to respond promptly to + * SIGQUIT at all times. Therefore we centrally remove SIGQUIT from + * BlockSig and install a suitable signal handler. (Client-facing + * processes may choose to replace this default choice of handler with + * quickdie().) All other blockable signals remain blocked for now. + */ + pqsignal(SIGQUIT, SignalHandlerForCrashExit); + + sigdelset(&BlockSig, SIGQUIT); + PG_SETMASK(&BlockSig); + /* Request a signal if the postmaster dies, if possible. */ PostmasterDeathSignalInit(); } @@ -165,6 +184,13 @@ InitStandaloneProcess(const char *argv0) InitLatch(MyLatch); InitializeLatchWaitSet(); + /* + * For consistency with InitPostmasterChild, initialize signal mask here. + * But we don't unblock SIGQUIT or provide a default handler for it. + */ + pqinitmask(); + PG_SETMASK(&BlockSig); + /* Compute paths, no postmaster to inherit from */ if (my_exec_path[0] == '\0') { @@ -186,7 +212,8 @@ SwitchToSharedLatch(void) MyLatch = &MyProc->procLatch; if (FeBeWaitSet) - ModifyWaitEvent(FeBeWaitSet, 1, WL_LATCH_SET, MyLatch); + ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetLatchPos, WL_LATCH_SET, + MyLatch); /* * Set the shared latch as the local one might have been set. This @@ -205,7 +232,8 @@ SwitchBackToLocalLatch(void) MyLatch = &LocalLatchData; if (FeBeWaitSet) - ModifyWaitEvent(FeBeWaitSet, 1, WL_LATCH_SET, MyLatch); + ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetLatchPos, WL_LATCH_SET, + MyLatch); SetLatch(MyLatch); } @@ -1711,7 +1739,7 @@ load_libraries(const char *libraries, const char *gucname, bool restricted) } load_file(filename, restricted); ereport(DEBUG1, - (errmsg("loaded library \"%s\"", filename))); + (errmsg_internal("loaded library \"%s\"", filename))); if (expanded) pfree(expanded); } diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 8fec3489eb94..175de265ae60 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -3,7 +3,7 @@ * postinit.c * postgres initialization utilities * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,7 +28,6 @@ #include "access/xact.h" #include "access/xlog.h" #include "catalog/catalog.h" -#include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_authid.h" #include "catalog/pg_database.h" @@ -93,6 +92,7 @@ static void StatementTimeoutHandler(void); static void LockTimeoutHandler(void); static void IdleInTransactionSessionTimeoutHandler(void); static void IdleGangTimeoutHandler(void); +static void IdleSessionTimeoutHandler(void); static void ClientCheckTimeoutHandler(void); static bool ThereIsAtLeastOneRole(void); static void process_startup_options(Port *port, bool am_superuser); @@ -301,62 +301,50 @@ PerformAuthentication(Port *port) if (Log_connections) { + StringInfoData logmsg; + + initStringInfo(&logmsg); if (am_walsender) - { + appendStringInfo(&logmsg, _("replication connection authorized: user=%s"), + port->user_name); + else + appendStringInfo(&logmsg, _("connection authorized: user=%s"), + port->user_name); + if (!am_walsender) + appendStringInfo(&logmsg, _(" database=%s"), port->database_name); + + if (port->application_name != NULL) + appendStringInfo(&logmsg, _(" application_name=%s"), + port->application_name); + #ifdef USE_SSL - if (port->ssl_in_use) - ereport(LOG, - (port->application_name != NULL - ? errmsg("replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", - port->user_name, - port->application_name, - be_tls_get_version(port), - be_tls_get_cipher(port), - be_tls_get_cipher_bits(port), - be_tls_get_compression(port) ? _("on") : _("off")) - : errmsg("replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", - port->user_name, - be_tls_get_version(port), - be_tls_get_cipher(port), - be_tls_get_cipher_bits(port), - be_tls_get_compression(port) ? _("on") : _("off")))); - else + if (port->ssl_in_use) + appendStringInfo(&logmsg, _(" SSL enabled (protocol=%s, cipher=%s, bits=%d)"), + be_tls_get_version(port), + be_tls_get_cipher(port), + be_tls_get_cipher_bits(port)); #endif - ereport(LOG, - (port->application_name != NULL - ? errmsg("replication connection authorized: user=%s application_name=%s", - port->user_name, - port->application_name) - : errmsg("replication connection authorized: user=%s", - port->user_name))); - } - else +#ifdef ENABLE_GSS + if (port->gss) { -#ifdef USE_SSL - if (port->ssl_in_use) - ereport(LOG, - (port->application_name != NULL - ? errmsg("connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", - port->user_name, port->database_name, port->application_name, - be_tls_get_version(port), - be_tls_get_cipher(port), - be_tls_get_cipher_bits(port), - be_tls_get_compression(port) ? _("on") : _("off")) - : errmsg("connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", - port->user_name, port->database_name, - be_tls_get_version(port), - be_tls_get_cipher(port), - be_tls_get_cipher_bits(port), - be_tls_get_compression(port) ? _("on") : _("off")))); + const char *princ = be_gssapi_get_princ(port); + + if (princ) + appendStringInfo(&logmsg, + _(" GSS (authenticated=%s, encrypted=%s, principal=%s)"), + be_gssapi_get_auth(port) ? _("yes") : _("no"), + be_gssapi_get_enc(port) ? _("yes") : _("no"), + princ); else -#endif - ereport(LOG, - (port->application_name != NULL - ? errmsg("connection authorized: user=%s database=%s application_name=%s", - port->user_name, port->database_name, port->application_name) - : errmsg("connection authorized: user=%s database=%s", - port->user_name, port->database_name))); + appendStringInfo(&logmsg, + _(" GSS (authenticated=%s, encrypted=%s)"), + be_gssapi_get_auth(port) ? _("yes") : _("no"), + be_gssapi_get_enc(port) ? _("yes") : _("no")); } +#endif + + ereport(LOG, errmsg_internal("%s", logmsg.data)); + pfree(logmsg.data); } set_ps_display("startup"); @@ -725,6 +713,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, RegisterTimeout(IDLE_IN_TRANSACTION_SESSION_TIMEOUT, IdleInTransactionSessionTimeoutHandler); RegisterTimeout(IDLE_GANG_TIMEOUT, IdleGangTimeoutHandler); + RegisterTimeout(IDLE_SESSION_TIMEOUT, IdleSessionTimeoutHandler); RegisterTimeout(CLIENT_CONNECTION_CHECK_TIMEOUT, ClientCheckTimeoutHandler); } @@ -785,6 +774,10 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, if (!bootstrap) pgstat_initialize(); + /* Initialize status reporting */ + if (!bootstrap) + pgstat_beinit(); + /* * Load relcache entries for the shared system catalogs. This must create * at least entries for pg_database and catalogs used for authentication. @@ -1522,12 +1515,20 @@ IdleGangTimeoutHandler(void) SetLatch(MyLatch); } +static void +IdleSessionTimeoutHandler(void) +{ + IdleSessionTimeoutPending = true; + InterruptPending = true; + SetLatch(MyLatch); +} + static void ClientCheckTimeoutHandler(void) { CheckClientConnectionPending = true; InterruptPending = true; - SetLatch(&MyProc->procLatch); + SetLatch(MyLatch); } /* diff --git a/src/backend/utils/init/test/postinit_test.c b/src/backend/utils/init/test/postinit_test.c index 8c487092602b..e6edf7b9af94 100644 --- a/src/backend/utils/init/test/postinit_test.c +++ b/src/backend/utils/init/test/postinit_test.c @@ -17,16 +17,18 @@ _errfinish_impl() static void expect_ereport(int expect_elevel) { - expect_value(errstart, elevel, expect_elevel); - expect_any(errstart, domain); if (expect_elevel < ERROR) { + expect_value(errstart, elevel, expect_elevel); + expect_any(errstart, domain); will_return(errstart, false); } - else - { - will_return_with_sideeffect(errstart, false, &_errfinish_impl, NULL); - } + else + { + expect_value(errstart_cold, elevel, expect_elevel); + expect_any(errstart_cold, domain); + will_return_with_sideeffect(errstart_cold, false, &_errfinish_impl, NULL); + } } #include "../postinit.c" diff --git a/src/backend/utils/mb/Unicode/Makefile b/src/backend/utils/mb/Unicode/Makefile index da307d8eb95c..ed6fc07e0880 100644 --- a/src/backend/utils/mb/Unicode/Makefile +++ b/src/backend/utils/mb/Unicode/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/backend/utils/mb/Unicode # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/Makefile # diff --git a/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl b/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl index 84c9c5354130..67b6b432113f 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_BIG5.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl index 1596b64238f1..88c561b32d0e 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2020, PostgreSQL Global Development Group +# Copyright (c) 2007-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_GB18030.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl index 6d1681a18a35..ea558dba68b1 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2020, PostgreSQL Global Development Group +# Copyright (c) 2007-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl index d8bed27e1b1e..bd50f63dbaf0 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl # @@ -80,7 +80,7 @@ } } -# extract only SJIS characers +# extract only SJIS characters foreach my $i (grep defined $_->{sjis}, @mapping) { my $sjis = $i->{sjis}; diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl index b560f9f37eaf..a037493fd16e 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl index 0f52183ff5fa..7f49be8ad1d2 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl b/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl index 57e63b4004a2..61c47970fc68 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2020, PostgreSQL Global Development Group +# Copyright (c) 2007-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_GB18030.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl b/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl index 0bcea9e0d4f3..0f4bfe8af899 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl b/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl index b86714dd46df..710d5ce3c880 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2020, PostgreSQL Global Development Group +# Copyright (c) 2007-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl b/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl index 5f4512ec87ed..bb1f51c04486 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_SJIS.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_UHC.pl b/src/backend/utils/mb/Unicode/UCS_to_UHC.pl index 3282106d7f07..cc416bd4bfbe 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_UHC.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_UHC.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2020, PostgreSQL Global Development Group +# Copyright (c) 2007-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_GB18030.pl # diff --git a/src/backend/utils/mb/Unicode/UCS_to_most.pl b/src/backend/utils/mb/Unicode/UCS_to_most.pl index 8a7b26a5c5f3..4f974388d75f 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_most.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_most.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_most.pl # diff --git a/src/backend/utils/mb/Unicode/convutils.pm b/src/backend/utils/mb/Unicode/convutils.pm index 9d97061c6fe6..5ad38514beea 100644 --- a/src/backend/utils/mb/Unicode/convutils.pm +++ b/src/backend/utils/mb/Unicode/convutils.pm @@ -1,5 +1,5 @@ # -# Copyright (c) 2001-2020, PostgreSQL Global Development Group +# Copyright (c) 2001-2021, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/convutils.pm @@ -381,7 +381,7 @@ sub print_radix_table header => "Dummy map, for invalid values", min_idx => 0, max_idx => $widest_range, - label => "dummy map" + label => "dummy map" }; ### diff --git a/src/backend/utils/mb/conv.c b/src/backend/utils/mb/conv.c index 54dcf71fb756..33e9c9a9e3c3 100644 --- a/src/backend/utils/mb/conv.c +++ b/src/backend/utils/mb/conv.c @@ -2,7 +2,7 @@ * * Utility functions for conversion procs. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -25,15 +25,20 @@ * tab holds conversion entries for the source charset * starting from 128 (0x80). each entry in the table holds the corresponding * code point for the target charset, or 0 if there is no equivalent code. + * + * Returns the number of input bytes consumed. If noError is true, this can + * be less than 'len'. */ -void +int local2local(const unsigned char *l, unsigned char *p, int len, int src_encoding, int dest_encoding, - const unsigned char *tab) + const unsigned char *tab, + bool noError) { + const unsigned char *start = l; unsigned char c1, c2; @@ -41,7 +46,11 @@ local2local(const unsigned char *l, { c1 = *l; if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(src_encoding, (const char *) l, len); + } if (!IS_HIGHBIT_SET(c1)) *p++ = c1; else @@ -50,13 +59,19 @@ local2local(const unsigned char *l, if (c2) *p++ = c2; else + { + if (noError) + break; report_untranslatable_char(src_encoding, dest_encoding, (const char *) l, len); + } } l++; len--; } *p = '\0'; + + return l - start; } /* @@ -66,18 +81,26 @@ local2local(const unsigned char *l, * p is the output area (must be large enough!) * lc is the mule character set id for the local encoding * encoding is the PG identifier for the local encoding + * + * Returns the number of input bytes consumed. If noError is true, this can + * be less than 'len'. */ -void +int latin2mic(const unsigned char *l, unsigned char *p, int len, - int lc, int encoding) + int lc, int encoding, bool noError) { + const unsigned char *start = l; int c1; while (len > 0) { c1 = *l; if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(encoding, (const char *) l, len); + } if (IS_HIGHBIT_SET(c1)) *p++ = lc; *p++ = c1; @@ -85,6 +108,8 @@ latin2mic(const unsigned char *l, unsigned char *p, int len, len--; } *p = '\0'; + + return l - start; } /* @@ -94,18 +119,26 @@ latin2mic(const unsigned char *l, unsigned char *p, int len, * p is the output area (must be large enough!) * lc is the mule character set id for the local encoding * encoding is the PG identifier for the local encoding + * + * Returns the number of input bytes consumed. If noError is true, this can + * be less than 'len'. */ -void +int mic2latin(const unsigned char *mic, unsigned char *p, int len, - int lc, int encoding) + int lc, int encoding, bool noError) { + const unsigned char *start = mic; int c1; while (len > 0) { c1 = *mic; if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (!IS_HIGHBIT_SET(c1)) { /* easy for ASCII */ @@ -118,17 +151,27 @@ mic2latin(const unsigned char *mic, unsigned char *p, int len, int l = pg_mule_mblen(mic); if (len < l) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (l != 2 || c1 != lc || !IS_HIGHBIT_SET(mic[1])) + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, encoding, (const char *) mic, len); + } *p++ = mic[1]; mic += 2; len -= 2; } } *p = '\0'; + + return mic - start; } @@ -143,15 +186,20 @@ mic2latin(const unsigned char *mic, unsigned char *p, int len, * tab holds conversion entries for the local charset * starting from 128 (0x80). each entry in the table holds the corresponding * code point for the mule encoding, or 0 if there is no equivalent code. + * + * Returns the number of input bytes consumed. If noError is true, this can + * be less than 'len'. */ -void +int latin2mic_with_table(const unsigned char *l, unsigned char *p, int len, int lc, int encoding, - const unsigned char *tab) + const unsigned char *tab, + bool noError) { + const unsigned char *start = l; unsigned char c1, c2; @@ -159,7 +207,11 @@ latin2mic_with_table(const unsigned char *l, { c1 = *l; if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(encoding, (const char *) l, len); + } if (!IS_HIGHBIT_SET(c1)) *p++ = c1; else @@ -171,13 +223,19 @@ latin2mic_with_table(const unsigned char *l, *p++ = c2; } else + { + if (noError) + break; report_untranslatable_char(encoding, PG_MULE_INTERNAL, (const char *) l, len); + } } l++; len--; } *p = '\0'; + + return l - start; } /* @@ -191,15 +249,20 @@ latin2mic_with_table(const unsigned char *l, * tab holds conversion entries for the mule internal code's second byte, * starting from 128 (0x80). each entry in the table holds the corresponding * code point for the local charset, or 0 if there is no equivalent code. + * + * Returns the number of input bytes consumed. If noError is true, this can + * be less than 'len'. */ -void +int mic2latin_with_table(const unsigned char *mic, unsigned char *p, int len, int lc, int encoding, - const unsigned char *tab) + const unsigned char *tab, + bool noError) { + const unsigned char *start = mic; unsigned char c1, c2; @@ -207,7 +270,11 @@ mic2latin_with_table(const unsigned char *mic, { c1 = *mic; if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (!IS_HIGHBIT_SET(c1)) { /* easy for ASCII */ @@ -220,11 +287,17 @@ mic2latin_with_table(const unsigned char *mic, int l = pg_mule_mblen(mic); if (len < l) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (l != 2 || c1 != lc || !IS_HIGHBIT_SET(mic[1]) || (c2 = tab[mic[1] - HIGHBIT]) == 0) { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, encoding, (const char *) mic, len); break; /* keep compiler quiet */ @@ -235,6 +308,8 @@ mic2latin_with_table(const unsigned char *mic, } } *p = '\0'; + + return mic - start; } /* @@ -424,18 +499,22 @@ pg_mb_radix_conv(const pg_mb_radix_tree *rt, * is applied. An error is raised if no match is found. * * See pg_wchar.h for more details about the data structures used here. + * + * Returns the number of input bytes consumed. If noError is true, this can + * be less than 'len'. */ -void +int UtfToLocal(const unsigned char *utf, int len, unsigned char *iso, const pg_mb_radix_tree *map, const pg_utf_to_local_combined *cmap, int cmapsize, utf_local_conversion_func conv_func, - int encoding) + int encoding, bool noError) { uint32 iutf; int l; const pg_utf_to_local_combined *cp; + const unsigned char *start = utf; if (!PG_VALID_ENCODING(encoding)) ereport(ERROR, @@ -505,10 +584,19 @@ UtfToLocal(const unsigned char *utf, int len, l = pg_utf_mblen(utf); if (len < l) + { + /* need more data to decide if this is a combined char */ + utf -= l_save; break; + } if (!pg_utf8_islegal(utf, l)) + { + if (!noError) + report_invalid_encoding(PG_UTF8, (const char *) utf, len); + utf -= l_save; break; + } /* We assume ASCII character cannot be in combined map */ if (l > 1) @@ -584,15 +672,20 @@ UtfToLocal(const unsigned char *utf, int len, } /* failed to translate this character */ + utf -= l; + if (noError) + break; report_untranslatable_char(PG_UTF8, encoding, - (const char *) (utf - l), len); + (const char *) utf, len); } /* if we broke out of loop early, must be invalid input */ - if (len > 0) + if (len > 0 && !noError) report_invalid_encoding(PG_UTF8, (const char *) utf, len); *iso = '\0'; + + return utf - start; } /* @@ -616,18 +709,23 @@ UtfToLocal(const unsigned char *utf, int len, * (if provided) is applied. An error is raised if no match is found. * * See pg_wchar.h for more details about the data structures used here. + * + * Returns the number of input bytes consumed. If noError is true, this can + * be less than 'len'. */ -void +int LocalToUtf(const unsigned char *iso, int len, unsigned char *utf, const pg_mb_radix_tree *map, const pg_local_to_utf_combined *cmap, int cmapsize, utf_local_conversion_func conv_func, - int encoding) + int encoding, + bool noError) { uint32 iiso; int l; const pg_local_to_utf_combined *cp; + const unsigned char *start = iso; if (!PG_VALID_ENCODING(encoding)) ereport(ERROR, @@ -653,7 +751,7 @@ LocalToUtf(const unsigned char *iso, int len, continue; } - l = pg_encoding_verifymb(encoding, (const char *) iso, len); + l = pg_encoding_verifymbchar(encoding, (const char *) iso, len); if (l < 0) break; @@ -723,13 +821,18 @@ LocalToUtf(const unsigned char *iso, int len, } /* failed to translate this character */ + iso -= l; + if (noError) + break; report_untranslatable_char(encoding, PG_UTF8, - (const char *) (iso - l), len); + (const char *) iso, len); } /* if we broke out of loop early, must be invalid input */ - if (len > 0) + if (len > 0 && !noError) report_invalid_encoding(encoding, (const char *) iso, len); *utf = '\0'; + + return iso - start; } diff --git a/src/backend/utils/mb/conversion_procs/Makefile b/src/backend/utils/mb/conversion_procs/Makefile index e6e844af783b..a2e935e84c45 100644 --- a/src/backend/utils/mb/conversion_procs/Makefile +++ b/src/backend/utils/mb/conversion_procs/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/utils/mb/conversion_procs # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/utils/mb/conversion_procs/Makefile diff --git a/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c b/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c index 376b48ca611c..368c2deb5e4b 100644 --- a/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c @@ -2,7 +2,7 @@ * * Cyrillic and MULE_INTERNAL * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -44,8 +44,11 @@ PG_FUNCTION_INFO_V1(win866_to_iso); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -306,12 +309,14 @@ koi8r_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_MULE_INTERNAL); - latin2mic(src, dest, len, LC_KOI8_R, PG_KOI8R); + converted = latin2mic(src, dest, len, LC_KOI8_R, PG_KOI8R, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -320,12 +325,14 @@ mic_to_koi8r(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_KOI8R); - mic2latin(src, dest, len, LC_KOI8_R, PG_KOI8R); + converted = mic2latin(src, dest, len, LC_KOI8_R, PG_KOI8R, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -334,12 +341,14 @@ iso_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_MULE_INTERNAL); - latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_ISO_8859_5, iso2koi); + converted = latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_ISO_8859_5, iso2koi, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -348,12 +357,14 @@ mic_to_iso(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_ISO_8859_5); - mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_ISO_8859_5, koi2iso); + converted = mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_ISO_8859_5, koi2iso, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -362,12 +373,14 @@ win1251_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_MULE_INTERNAL); - latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_WIN1251, win12512koi); + converted = latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_WIN1251, win12512koi, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -376,12 +389,14 @@ mic_to_win1251(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_WIN1251); - mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_WIN1251, koi2win1251); + converted = mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_WIN1251, koi2win1251, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -390,12 +405,14 @@ win866_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_MULE_INTERNAL); - latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_WIN866, win8662koi); + converted = latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_WIN866, win8662koi, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -404,12 +421,14 @@ mic_to_win866(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_WIN866); - mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_WIN866, koi2win866); + converted = mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_WIN866, koi2win866, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -418,12 +437,14 @@ koi8r_to_win1251(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_WIN1251); - local2local(src, dest, len, PG_KOI8R, PG_WIN1251, koi2win1251); + converted = local2local(src, dest, len, PG_KOI8R, PG_WIN1251, koi2win1251, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -432,12 +453,14 @@ win1251_to_koi8r(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_KOI8R); - local2local(src, dest, len, PG_WIN1251, PG_KOI8R, win12512koi); + converted = local2local(src, dest, len, PG_WIN1251, PG_KOI8R, win12512koi, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -446,12 +469,14 @@ koi8r_to_win866(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_WIN866); - local2local(src, dest, len, PG_KOI8R, PG_WIN866, koi2win866); + converted = local2local(src, dest, len, PG_KOI8R, PG_WIN866, koi2win866, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -460,12 +485,14 @@ win866_to_koi8r(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_KOI8R); - local2local(src, dest, len, PG_WIN866, PG_KOI8R, win8662koi); + converted = local2local(src, dest, len, PG_WIN866, PG_KOI8R, win8662koi, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -474,12 +501,14 @@ win866_to_win1251(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_WIN1251); - local2local(src, dest, len, PG_WIN866, PG_WIN1251, win8662win1251); + converted = local2local(src, dest, len, PG_WIN866, PG_WIN1251, win8662win1251, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -488,12 +517,14 @@ win1251_to_win866(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_WIN866); - local2local(src, dest, len, PG_WIN1251, PG_WIN866, win12512win866); + converted = local2local(src, dest, len, PG_WIN1251, PG_WIN866, win12512win866, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -502,12 +533,14 @@ iso_to_koi8r(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_KOI8R); - local2local(src, dest, len, PG_ISO_8859_5, PG_KOI8R, iso2koi); + converted = local2local(src, dest, len, PG_ISO_8859_5, PG_KOI8R, iso2koi, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -516,12 +549,14 @@ koi8r_to_iso(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_ISO_8859_5); - local2local(src, dest, len, PG_KOI8R, PG_ISO_8859_5, koi2iso); + converted = local2local(src, dest, len, PG_KOI8R, PG_ISO_8859_5, koi2iso, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -530,12 +565,14 @@ iso_to_win1251(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_WIN1251); - local2local(src, dest, len, PG_ISO_8859_5, PG_WIN1251, iso2win1251); + converted = local2local(src, dest, len, PG_ISO_8859_5, PG_WIN1251, iso2win1251, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -544,12 +581,14 @@ win1251_to_iso(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_ISO_8859_5); - local2local(src, dest, len, PG_WIN1251, PG_ISO_8859_5, win12512iso); + converted = local2local(src, dest, len, PG_WIN1251, PG_ISO_8859_5, win12512iso, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -558,12 +597,14 @@ iso_to_win866(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_WIN866); - local2local(src, dest, len, PG_ISO_8859_5, PG_WIN866, iso2win866); + converted = local2local(src, dest, len, PG_ISO_8859_5, PG_WIN866, iso2win866, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -572,10 +613,12 @@ win866_to_iso(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_ISO_8859_5); - local2local(src, dest, len, PG_WIN866, PG_ISO_8859_5, win8662iso); + converted = local2local(src, dest, len, PG_WIN866, PG_ISO_8859_5, win8662iso, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c b/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c index 9ba6bd304052..a3fd35bd4063 100644 --- a/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c +++ b/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c @@ -2,7 +2,7 @@ * * EUC_JIS_2004, SHIFT_JIS_2004 * - * Copyright (c) 2007-2020, PostgreSQL Global Development Group + * Copyright (c) 2007-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c @@ -19,8 +19,8 @@ PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(euc_jis_2004_to_shift_jis_2004); PG_FUNCTION_INFO_V1(shift_jis_2004_to_euc_jis_2004); -static void euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len); -static void shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len); +static int euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len, bool noError); +static int shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len, bool noError); /* ---------- * conv_proc( @@ -28,8 +28,11 @@ static void shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -39,12 +42,14 @@ euc_jis_2004_to_shift_jis_2004(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JIS_2004, PG_SHIFT_JIS_2004); - euc_jis_20042shift_jis_2004(src, dest, len); + converted = euc_jis_20042shift_jis_2004(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -53,20 +58,23 @@ shift_jis_2004_to_euc_jis_2004(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_SHIFT_JIS_2004, PG_EUC_JIS_2004); - shift_jis_20042euc_jis_2004(src, dest, len); + converted = shift_jis_20042euc_jis_2004(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } /* * EUC_JIS_2004 -> SHIFT_JIS_2004 */ -static void -euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len) +static int +euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len, bool noError) { + const unsigned char *start = euc; int c1, ku, ten; @@ -79,19 +87,27 @@ euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_JIS_2004, (const char *) euc, len); + } *p++ = c1; euc++; len--; continue; } - l = pg_encoding_verifymb(PG_EUC_JIS_2004, (const char *) euc, len); + l = pg_encoding_verifymbchar(PG_EUC_JIS_2004, (const char *) euc, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_JIS_2004, (const char *) euc, len); + } if (c1 == SS2 && l == 2) /* JIS X 0201 kana? */ { @@ -121,8 +137,12 @@ euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len) *p++ = (ku + 0x19b) >> 1; } else + { + if (noError) + break; report_invalid_encoding(PG_EUC_JIS_2004, (const char *) euc, len); + } } if (ku % 2) @@ -132,8 +152,12 @@ euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len) else if (ten >= 64 && ten <= 94) *p++ = ten + 0x40; else + { + if (noError) + break; report_invalid_encoding(PG_EUC_JIS_2004, (const char *) euc, len); + } } else *p++ = ten + 0x9e; @@ -149,8 +173,12 @@ euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len) else if (ku >= 63 && ku <= 94) *p++ = (ku + 0x181) >> 1; else + { + if (noError) + break; report_invalid_encoding(PG_EUC_JIS_2004, (const char *) euc, len); + } if (ku % 2) { @@ -159,20 +187,30 @@ euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len) else if (ten >= 64 && ten <= 94) *p++ = ten + 0x40; else + { + if (noError) + break; report_invalid_encoding(PG_EUC_JIS_2004, (const char *) euc, len); + } } else *p++ = ten + 0x9e; } else + { + if (noError) + break; report_invalid_encoding(PG_EUC_JIS_2004, (const char *) euc, len); + } euc += l; len -= l; } *p = '\0'; + + return euc - start; } /* @@ -212,9 +250,10 @@ get_ten(int b, int *ku) * SHIFT_JIS_2004 ---> EUC_JIS_2004 */ -static void -shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len) +static int +shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len, bool noError) { + const unsigned char *start = sjis; int c1; int ku, ten, @@ -230,19 +269,27 @@ shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_SHIFT_JIS_2004, (const char *) sjis, len); + } *p++ = c1; sjis++; len--; continue; } - l = pg_encoding_verifymb(PG_SHIFT_JIS_2004, (const char *) sjis, len); + l = pg_encoding_verifymbchar(PG_SHIFT_JIS_2004, (const char *) sjis, len); if (l < 0 || l > len) + { + if (noError) + break; report_invalid_encoding(PG_SHIFT_JIS_2004, (const char *) sjis, len); + } if (c1 >= 0xa1 && c1 <= 0xdf && l == 1) { @@ -266,8 +313,12 @@ shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len ku = (c1 << 1) - 0x100; ten = get_ten(c2, &kubun); if (ten < 0) + { + if (noError) + break; report_invalid_encoding(PG_SHIFT_JIS_2004, (const char *) sjis, len); + } ku -= kubun; } else if (c1 >= 0xe0 && c1 <= 0xef) /* plane 1 62ku-94ku */ @@ -275,9 +326,12 @@ shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len ku = (c1 << 1) - 0x180; ten = get_ten(c2, &kubun); if (ten < 0) + { + if (noError) + break; report_invalid_encoding(PG_SHIFT_JIS_2004, - (const char *) sjis, len); + } ku -= kubun; } else if (c1 >= 0xf0 && c1 <= 0xf3) /* plane 2 @@ -286,8 +340,12 @@ shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len plane = 2; ten = get_ten(c2, &kubun); if (ten < 0) + { + if (noError) + break; report_invalid_encoding(PG_SHIFT_JIS_2004, (const char *) sjis, len); + } switch (c1) { case 0xf0: @@ -309,16 +367,24 @@ shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len plane = 2; ten = get_ten(c2, &kubun); if (ten < 0) + { + if (noError) + break; report_invalid_encoding(PG_SHIFT_JIS_2004, (const char *) sjis, len); + } if (c1 == 0xf4 && kubun == 1) ku = 15; else ku = (c1 << 1) - 0x19a - kubun; } else + { + if (noError) + break; report_invalid_encoding(PG_SHIFT_JIS_2004, (const char *) sjis, len); + } if (plane == 2) *p++ = SS3; @@ -330,4 +396,6 @@ shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len len -= l; } *p = '\0'; + + return sjis - start; } diff --git a/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c b/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c index 59c6c3bb1296..09b3c2e75bfe 100644 --- a/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c @@ -2,7 +2,7 @@ * * EUC_CN and MULE_INTERNAL * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -26,13 +26,16 @@ PG_FUNCTION_INFO_V1(mic_to_euc_cn); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ -static void euc_cn2mic(const unsigned char *euc, unsigned char *p, int len); -static void mic2euc_cn(const unsigned char *mic, unsigned char *p, int len); +static int euc_cn2mic(const unsigned char *euc, unsigned char *p, int len, bool noError); +static int mic2euc_cn(const unsigned char *mic, unsigned char *p, int len, bool noError); Datum euc_cn_to_mic(PG_FUNCTION_ARGS) @@ -40,12 +43,14 @@ euc_cn_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_CN, PG_MULE_INTERNAL); - euc_cn2mic(src, dest, len); + converted = euc_cn2mic(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -54,20 +59,23 @@ mic_to_euc_cn(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_EUC_CN); - mic2euc_cn(src, dest, len); + converted = mic2euc_cn(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } /* * EUC_CN ---> MIC */ -static void -euc_cn2mic(const unsigned char *euc, unsigned char *p, int len) +static int +euc_cn2mic(const unsigned char *euc, unsigned char *p, int len, bool noError) { + const unsigned char *start = euc; int c1; while (len > 0) @@ -76,7 +84,11 @@ euc_cn2mic(const unsigned char *euc, unsigned char *p, int len) if (IS_HIGHBIT_SET(c1)) { if (len < 2 || !IS_HIGHBIT_SET(euc[1])) + { + if (noError) + break; report_invalid_encoding(PG_EUC_CN, (const char *) euc, len); + } *p++ = LC_GB2312_80; *p++ = c1; *p++ = euc[1]; @@ -86,21 +98,28 @@ euc_cn2mic(const unsigned char *euc, unsigned char *p, int len) else { /* should be ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_CN, (const char *) euc, len); + } *p++ = c1; euc++; len--; } } *p = '\0'; + + return euc - start; } /* * MIC ---> EUC_CN */ -static void -mic2euc_cn(const unsigned char *mic, unsigned char *p, int len) +static int +mic2euc_cn(const unsigned char *mic, unsigned char *p, int len, bool noError) { + const unsigned char *start = mic; int c1; while (len > 0) @@ -109,11 +128,19 @@ mic2euc_cn(const unsigned char *mic, unsigned char *p, int len) if (IS_HIGHBIT_SET(c1)) { if (c1 != LC_GB2312_80) + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, PG_EUC_CN, (const char *) mic, len); + } if (len < 3 || !IS_HIGHBIT_SET(mic[1]) || !IS_HIGHBIT_SET(mic[2])) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } mic++; *p++ = *mic++; *p++ = *mic++; @@ -122,12 +149,18 @@ mic2euc_cn(const unsigned char *mic, unsigned char *p, int len) else { /* should be ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } *p++ = c1; mic++; len--; } } *p = '\0'; + + return mic - start; } diff --git a/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c b/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c index 4ca8e2126e4a..2e68708893dc 100644 --- a/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c +++ b/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c @@ -2,7 +2,7 @@ * * EUC_JP, SJIS and MULE_INTERNAL * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -42,17 +42,20 @@ PG_FUNCTION_INFO_V1(mic_to_sjis); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ -static void sjis2mic(const unsigned char *sjis, unsigned char *p, int len); -static void mic2sjis(const unsigned char *mic, unsigned char *p, int len); -static void euc_jp2mic(const unsigned char *euc, unsigned char *p, int len); -static void mic2euc_jp(const unsigned char *mic, unsigned char *p, int len); -static void euc_jp2sjis(const unsigned char *mic, unsigned char *p, int len); -static void sjis2euc_jp(const unsigned char *mic, unsigned char *p, int len); +static int sjis2mic(const unsigned char *sjis, unsigned char *p, int len, bool noError); +static int mic2sjis(const unsigned char *mic, unsigned char *p, int len, bool noError); +static int euc_jp2mic(const unsigned char *euc, unsigned char *p, int len, bool noError); +static int mic2euc_jp(const unsigned char *mic, unsigned char *p, int len, bool noError); +static int euc_jp2sjis(const unsigned char *mic, unsigned char *p, int len, bool noError); +static int sjis2euc_jp(const unsigned char *mic, unsigned char *p, int len, bool noError); Datum euc_jp_to_sjis(PG_FUNCTION_ARGS) @@ -60,12 +63,14 @@ euc_jp_to_sjis(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JP, PG_SJIS); - euc_jp2sjis(src, dest, len); + converted = euc_jp2sjis(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -74,12 +79,14 @@ sjis_to_euc_jp(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_EUC_JP); - sjis2euc_jp(src, dest, len); + converted = sjis2euc_jp(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -88,12 +95,14 @@ euc_jp_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JP, PG_MULE_INTERNAL); - euc_jp2mic(src, dest, len); + converted = euc_jp2mic(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -102,12 +111,14 @@ mic_to_euc_jp(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_EUC_JP); - mic2euc_jp(src, dest, len); + converted = mic2euc_jp(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -116,12 +127,14 @@ sjis_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_MULE_INTERNAL); - sjis2mic(src, dest, len); + converted = sjis2mic(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -130,20 +143,23 @@ mic_to_sjis(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_SJIS); - mic2sjis(src, dest, len); + converted = mic2sjis(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } /* * SJIS ---> MIC */ -static void -sjis2mic(const unsigned char *sjis, unsigned char *p, int len) +static int +sjis2mic(const unsigned char *sjis, unsigned char *p, int len, bool noError) { + const unsigned char *start = sjis; int c1, c2, i, @@ -167,7 +183,11 @@ sjis2mic(const unsigned char *sjis, unsigned char *p, int len) * JIS X0208, X0212, user defined extended characters */ if (len < 2 || !ISSJISHEAD(c1) || !ISSJISTAIL(sjis[1])) + { + if (noError) + break; report_invalid_encoding(PG_SJIS, (const char *) sjis, len); + } c2 = sjis[1]; k = (c1 << 8) + c2; if (k >= 0xed40 && k < 0xf040) @@ -257,21 +277,28 @@ sjis2mic(const unsigned char *sjis, unsigned char *p, int len) else { /* should be ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_SJIS, (const char *) sjis, len); + } *p++ = c1; sjis++; len--; } } *p = '\0'; + + return sjis - start; } /* * MIC ---> SJIS */ -static void -mic2sjis(const unsigned char *mic, unsigned char *p, int len) +static int +mic2sjis(const unsigned char *mic, unsigned char *p, int len, bool noError) { + const unsigned char *start = mic; int c1, c2, k, @@ -284,17 +311,25 @@ mic2sjis(const unsigned char *mic, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } *p++ = c1; mic++; len--; continue; } - l = pg_encoding_verifymb(PG_MULE_INTERNAL, (const char *) mic, len); + l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (c1 == LC_JISX0201K) *p++ = mic[1]; else if (c1 == LC_JISX0208) @@ -350,20 +385,27 @@ mic2sjis(const unsigned char *mic, unsigned char *p, int len) } } else + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, PG_SJIS, (const char *) mic, len); + } mic += l; len -= l; } *p = '\0'; + + return mic - start; } /* * EUC_JP ---> MIC */ -static void -euc_jp2mic(const unsigned char *euc, unsigned char *p, int len) +static int +euc_jp2mic(const unsigned char *euc, unsigned char *p, int len, bool noError) { + const unsigned char *start = euc; int c1; int l; @@ -374,17 +416,25 @@ euc_jp2mic(const unsigned char *euc, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_JP, (const char *) euc, len); + } *p++ = c1; euc++; len--; continue; } - l = pg_encoding_verifymb(PG_EUC_JP, (const char *) euc, len); + l = pg_encoding_verifymbchar(PG_EUC_JP, (const char *) euc, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_JP, (const char *) euc, len); + } if (c1 == SS2) { /* 1 byte kana? */ *p++ = LC_JISX0201K; @@ -406,14 +456,17 @@ euc_jp2mic(const unsigned char *euc, unsigned char *p, int len) len -= l; } *p = '\0'; + + return euc - start; } /* * MIC ---> EUC_JP */ -static void -mic2euc_jp(const unsigned char *mic, unsigned char *p, int len) +static int +mic2euc_jp(const unsigned char *mic, unsigned char *p, int len, bool noError) { + const unsigned char *start = mic; int c1; int l; @@ -424,17 +477,25 @@ mic2euc_jp(const unsigned char *mic, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } *p++ = c1; mic++; len--; continue; } - l = pg_encoding_verifymb(PG_MULE_INTERNAL, (const char *) mic, len); + l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (c1 == LC_JISX0201K) { *p++ = SS2; @@ -452,20 +513,27 @@ mic2euc_jp(const unsigned char *mic, unsigned char *p, int len) *p++ = mic[2]; } else + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, PG_EUC_JP, (const char *) mic, len); + } mic += l; len -= l; } *p = '\0'; + + return mic - start; } /* * EUC_JP -> SJIS */ -static void -euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len) +static int +euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len, bool noError) { + const unsigned char *start = euc; int c1, c2, k; @@ -478,17 +546,25 @@ euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_JP, (const char *) euc, len); + } *p++ = c1; euc++; len--; continue; } - l = pg_encoding_verifymb(PG_EUC_JP, (const char *) euc, len); + l = pg_encoding_verifymbchar(PG_EUC_JP, (const char *) euc, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_JP, (const char *) euc, len); + } if (c1 == SS2) { /* hankaku kana? */ @@ -551,14 +627,17 @@ euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len) len -= l; } *p = '\0'; + + return euc - start; } /* * SJIS ---> EUC_JP */ -static void -sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len) +static int +sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len, bool noError) { + const unsigned char *start = sjis; int c1, c2, i, @@ -573,17 +652,25 @@ sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_SJIS, (const char *) sjis, len); + } *p++ = c1; sjis++; len--; continue; } - l = pg_encoding_verifymb(PG_SJIS, (const char *) sjis, len); + l = pg_encoding_verifymbchar(PG_SJIS, (const char *) sjis, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_SJIS, (const char *) sjis, len); + } if (c1 >= 0xa1 && c1 <= 0xdf) { /* JIS X0201 (1 byte kana) */ @@ -680,4 +767,6 @@ sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len) len -= l; } *p = '\0'; + + return sjis - start; } diff --git a/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c b/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c index 4d7876a666ee..3b85f0c1861a 100644 --- a/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c @@ -2,7 +2,7 @@ * * EUC_KR and MULE_INTERNAL * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -26,13 +26,16 @@ PG_FUNCTION_INFO_V1(mic_to_euc_kr); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ -static void euc_kr2mic(const unsigned char *euc, unsigned char *p, int len); -static void mic2euc_kr(const unsigned char *mic, unsigned char *p, int len); +static int euc_kr2mic(const unsigned char *euc, unsigned char *p, int len, bool noError); +static int mic2euc_kr(const unsigned char *mic, unsigned char *p, int len, bool noError); Datum euc_kr_to_mic(PG_FUNCTION_ARGS) @@ -40,12 +43,14 @@ euc_kr_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_KR, PG_MULE_INTERNAL); - euc_kr2mic(src, dest, len); + converted = euc_kr2mic(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -54,20 +59,23 @@ mic_to_euc_kr(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_EUC_KR); - mic2euc_kr(src, dest, len); + converted = mic2euc_kr(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } /* * EUC_KR ---> MIC */ -static void -euc_kr2mic(const unsigned char *euc, unsigned char *p, int len) +static int +euc_kr2mic(const unsigned char *euc, unsigned char *p, int len, bool noError) { + const unsigned char *start = euc; int c1; int l; @@ -76,10 +84,14 @@ euc_kr2mic(const unsigned char *euc, unsigned char *p, int len) c1 = *euc; if (IS_HIGHBIT_SET(c1)) { - l = pg_encoding_verifymb(PG_EUC_KR, (const char *) euc, len); + l = pg_encoding_verifymbchar(PG_EUC_KR, (const char *) euc, len); if (l != 2) + { + if (noError) + break; report_invalid_encoding(PG_EUC_KR, (const char *) euc, len); + } *p++ = LC_KS5601; *p++ = c1; *p++ = euc[1]; @@ -89,22 +101,29 @@ euc_kr2mic(const unsigned char *euc, unsigned char *p, int len) else { /* should be ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_KR, (const char *) euc, len); + } *p++ = c1; euc++; len--; } } *p = '\0'; + + return euc - start; } /* * MIC ---> EUC_KR */ -static void -mic2euc_kr(const unsigned char *mic, unsigned char *p, int len) +static int +mic2euc_kr(const unsigned char *mic, unsigned char *p, int len, bool noError) { + const unsigned char *start = mic; int c1; int l; @@ -115,27 +134,41 @@ mic2euc_kr(const unsigned char *mic, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } *p++ = c1; mic++; len--; continue; } - l = pg_encoding_verifymb(PG_MULE_INTERNAL, (const char *) mic, len); + l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (c1 == LC_KS5601) { *p++ = mic[1]; *p++ = mic[2]; } else + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, PG_EUC_KR, (const char *) mic, len); + } mic += l; len -= l; } *p = '\0'; + + return mic - start; } diff --git a/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c b/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c index 82a22b9bebf8..4bf8acda99fe 100644 --- a/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c +++ b/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c @@ -2,7 +2,7 @@ * * EUC_TW, BIG5 and MULE_INTERNAL * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,15 +32,20 @@ PG_FUNCTION_INFO_V1(mic_to_big5); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ -static void big52mic(const unsigned char *big5, unsigned char *p, int len); -static void mic2big5(const unsigned char *mic, unsigned char *p, int len); -static void euc_tw2mic(const unsigned char *euc, unsigned char *p, int len); -static void mic2euc_tw(const unsigned char *mic, unsigned char *p, int len); +static int euc_tw2big5(const unsigned char *euc, unsigned char *p, int len, bool noError); +static int big52euc_tw(const unsigned char *euc, unsigned char *p, int len, bool noError); +static int big52mic(const unsigned char *big5, unsigned char *p, int len, bool noError); +static int mic2big5(const unsigned char *mic, unsigned char *p, int len, bool noError); +static int euc_tw2mic(const unsigned char *euc, unsigned char *p, int len, bool noError); +static int mic2euc_tw(const unsigned char *mic, unsigned char *p, int len, bool noError); Datum euc_tw_to_big5(PG_FUNCTION_ARGS) @@ -48,16 +53,14 @@ euc_tw_to_big5(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); - unsigned char *buf; + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_TW, PG_BIG5); - buf = palloc(len * ENCODING_GROWTH_RATE + 1); - euc_tw2mic(src, buf, len); - mic2big5(buf, dest, strlen((char *) buf)); - pfree(buf); + converted = euc_tw2big5(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -66,16 +69,14 @@ big5_to_euc_tw(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); - unsigned char *buf; + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_BIG5, PG_EUC_TW); - buf = palloc(len * ENCODING_GROWTH_RATE + 1); - big52mic(src, buf, len); - mic2euc_tw(buf, dest, strlen((char *) buf)); - pfree(buf); + converted = big52euc_tw(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -84,12 +85,14 @@ euc_tw_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_TW, PG_MULE_INTERNAL); - euc_tw2mic(src, dest, len); + converted = euc_tw2mic(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -98,12 +101,14 @@ mic_to_euc_tw(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_EUC_TW); - mic2euc_tw(src, dest, len); + converted = mic2euc_tw(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -112,12 +117,14 @@ big5_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_BIG5, PG_MULE_INTERNAL); - big52mic(src, dest, len); + converted = big52mic(src, dest, len, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -126,20 +133,179 @@ mic_to_big5(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_BIG5); - mic2big5(src, dest, len); + converted = mic2big5(src, dest, len, noError); + + PG_RETURN_INT32(converted); +} + + +/* + * EUC_TW ---> Big5 + */ +static int +euc_tw2big5(const unsigned char *euc, unsigned char *p, int len, bool noError) +{ + const unsigned char *start = euc; + unsigned char c1; + unsigned short big5buf, + cnsBuf; + unsigned char lc; + int l; + + while (len > 0) + { + c1 = *euc; + if (IS_HIGHBIT_SET(c1)) + { + /* Verify and decode the next EUC_TW input character */ + l = pg_encoding_verifymbchar(PG_EUC_TW, (const char *) euc, len); + if (l < 0) + { + if (noError) + break; + report_invalid_encoding(PG_EUC_TW, + (const char *) euc, len); + } + if (c1 == SS2) + { + c1 = euc[1]; /* plane No. */ + if (c1 == 0xa1) + lc = LC_CNS11643_1; + else if (c1 == 0xa2) + lc = LC_CNS11643_2; + else + lc = c1 - 0xa3 + LC_CNS11643_3; + cnsBuf = (euc[2] << 8) | euc[3]; + } + else + { /* CNS11643-1 */ + lc = LC_CNS11643_1; + cnsBuf = (c1 << 8) | euc[1]; + } + + /* Write it out in Big5 */ + big5buf = CNStoBIG5(cnsBuf, lc); + if (big5buf == 0) + { + if (noError) + break; + report_untranslatable_char(PG_EUC_TW, PG_BIG5, + (const char *) euc, len); + } + *p++ = (big5buf >> 8) & 0x00ff; + *p++ = big5buf & 0x00ff; + + euc += l; + len -= l; + } + else + { /* should be ASCII */ + if (c1 == 0) + { + if (noError) + break; + report_invalid_encoding(PG_EUC_TW, + (const char *) euc, len); + } + *p++ = c1; + euc++; + len--; + } + } + *p = '\0'; + + return euc - start; +} + +/* + * Big5 ---> EUC_TW + */ +static int +big52euc_tw(const unsigned char *big5, unsigned char *p, int len, bool noError) +{ + const unsigned char *start = big5; + unsigned short c1; + unsigned short big5buf, + cnsBuf; + unsigned char lc; + int l; + + while (len > 0) + { + /* Verify and decode the next Big5 input character */ + c1 = *big5; + if (IS_HIGHBIT_SET(c1)) + { + l = pg_encoding_verifymbchar(PG_BIG5, (const char *) big5, len); + if (l < 0) + { + if (noError) + break; + report_invalid_encoding(PG_BIG5, + (const char *) big5, len); + } + big5buf = (c1 << 8) | big5[1]; + cnsBuf = BIG5toCNS(big5buf, &lc); + + if (lc == LC_CNS11643_1) + { + *p++ = (cnsBuf >> 8) & 0x00ff; + *p++ = cnsBuf & 0x00ff; + } + else if (lc == LC_CNS11643_2) + { + *p++ = SS2; + *p++ = 0xa2; + *p++ = (cnsBuf >> 8) & 0x00ff; + *p++ = cnsBuf & 0x00ff; + } + else if (lc >= LC_CNS11643_3 && lc <= LC_CNS11643_7) + { + *p++ = SS2; + *p++ = lc - LC_CNS11643_3 + 0xa3; + *p++ = (cnsBuf >> 8) & 0x00ff; + *p++ = cnsBuf & 0x00ff; + } + else + { + if (noError) + break; + report_untranslatable_char(PG_BIG5, PG_EUC_TW, + (const char *) big5, len); + } + + big5 += l; + len -= l; + } + else + { + /* ASCII */ + if (c1 == 0) + report_invalid_encoding(PG_BIG5, + (const char *) big5, len); + *p++ = c1; + big5++; + len--; + continue; + } + } + *p = '\0'; - PG_RETURN_VOID(); + return big5 - start; } /* * EUC_TW ---> MIC */ -static void -euc_tw2mic(const unsigned char *euc, unsigned char *p, int len) +static int +euc_tw2mic(const unsigned char *euc, unsigned char *p, int len, bool noError) { + const unsigned char *start = euc; int c1; int l; @@ -148,10 +314,14 @@ euc_tw2mic(const unsigned char *euc, unsigned char *p, int len) c1 = *euc; if (IS_HIGHBIT_SET(c1)) { - l = pg_encoding_verifymb(PG_EUC_TW, (const char *) euc, len); + l = pg_encoding_verifymbchar(PG_EUC_TW, (const char *) euc, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_TW, (const char *) euc, len); + } if (c1 == SS2) { c1 = euc[1]; /* plane No. */ @@ -180,22 +350,29 @@ euc_tw2mic(const unsigned char *euc, unsigned char *p, int len) else { /* should be ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_EUC_TW, (const char *) euc, len); + } *p++ = c1; euc++; len--; } } *p = '\0'; + + return euc - start; } /* * MIC ---> EUC_TW */ -static void -mic2euc_tw(const unsigned char *mic, unsigned char *p, int len) +static int +mic2euc_tw(const unsigned char *mic, unsigned char *p, int len, bool noError) { + const unsigned char *start = mic; int c1; int l; @@ -206,17 +383,25 @@ mic2euc_tw(const unsigned char *mic, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } *p++ = c1; mic++; len--; continue; } - l = pg_encoding_verifymb(PG_MULE_INTERNAL, (const char *) mic, len); + l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (c1 == LC_CNS11643_1) { *p++ = mic[1]; @@ -238,20 +423,27 @@ mic2euc_tw(const unsigned char *mic, unsigned char *p, int len) *p++ = mic[3]; } else + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, PG_EUC_TW, (const char *) mic, len); + } mic += l; len -= l; } *p = '\0'; + + return mic - start; } /* * Big5 ---> MIC */ -static void -big52mic(const unsigned char *big5, unsigned char *p, int len) +static int +big52mic(const unsigned char *big5, unsigned char *p, int len, bool noError) { + const unsigned char *start = big5; unsigned short c1; unsigned short big5buf, cnsBuf; @@ -265,17 +457,25 @@ big52mic(const unsigned char *big5, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_BIG5, (const char *) big5, len); + } *p++ = c1; big5++; len--; continue; } - l = pg_encoding_verifymb(PG_BIG5, (const char *) big5, len); + l = pg_encoding_verifymbchar(PG_BIG5, (const char *) big5, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_BIG5, (const char *) big5, len); + } big5buf = (c1 << 8) | big5[1]; cnsBuf = BIG5toCNS(big5buf, &lc); if (lc != 0) @@ -288,20 +488,27 @@ big52mic(const unsigned char *big5, unsigned char *p, int len) *p++ = cnsBuf & 0x00ff; } else + { + if (noError) + break; report_untranslatable_char(PG_BIG5, PG_MULE_INTERNAL, (const char *) big5, len); + } big5 += l; len -= l; } *p = '\0'; + + return big5 - start; } /* * MIC ---> Big5 */ -static void -mic2big5(const unsigned char *mic, unsigned char *p, int len) +static int +mic2big5(const unsigned char *mic, unsigned char *p, int len, bool noError) { + const unsigned char *start = mic; unsigned short c1; unsigned short big5buf, cnsBuf; @@ -314,17 +521,25 @@ mic2big5(const unsigned char *mic, unsigned char *p, int len) { /* ASCII */ if (c1 == 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } *p++ = c1; mic++; len--; continue; } - l = pg_encoding_verifymb(PG_MULE_INTERNAL, (const char *) mic, len); + l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len); if (l < 0) + { + if (noError) + break; report_invalid_encoding(PG_MULE_INTERNAL, (const char *) mic, len); + } if (c1 == LC_CNS11643_1 || c1 == LC_CNS11643_2 || c1 == LCPRV2_B) { if (c1 == LCPRV2_B) @@ -338,16 +553,26 @@ mic2big5(const unsigned char *mic, unsigned char *p, int len) } big5buf = CNStoBIG5(cnsBuf, c1); if (big5buf == 0) + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, PG_BIG5, (const char *) mic, len); + } *p++ = (big5buf >> 8) & 0x00ff; *p++ = big5buf & 0x00ff; } else + { + if (noError) + break; report_untranslatable_char(PG_MULE_INTERNAL, PG_BIG5, (const char *) mic, len); + } mic += l; len -= l; } *p = '\0'; + + return mic - start; } diff --git a/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c b/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c index f424f8814598..8610fcb69aa8 100644 --- a/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c +++ b/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c @@ -2,7 +2,7 @@ * * LATIN2 and WIN1250 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -30,8 +30,11 @@ PG_FUNCTION_INFO_V1(win1250_to_latin2); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -82,12 +85,14 @@ latin2_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_LATIN2, PG_MULE_INTERNAL); - latin2mic(src, dest, len, LC_ISO8859_2, PG_LATIN2); + converted = latin2mic(src, dest, len, LC_ISO8859_2, PG_LATIN2, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -96,12 +101,14 @@ mic_to_latin2(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_LATIN2); - mic2latin(src, dest, len, LC_ISO8859_2, PG_LATIN2); + converted = mic2latin(src, dest, len, LC_ISO8859_2, PG_LATIN2, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -110,13 +117,15 @@ win1250_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1250, PG_MULE_INTERNAL); - latin2mic_with_table(src, dest, len, LC_ISO8859_2, PG_WIN1250, - win1250_2_iso88592); + converted = latin2mic_with_table(src, dest, len, LC_ISO8859_2, PG_WIN1250, + win1250_2_iso88592, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -125,13 +134,15 @@ mic_to_win1250(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_WIN1250); - mic2latin_with_table(src, dest, len, LC_ISO8859_2, PG_WIN1250, - iso88592_2_win1250); + converted = mic2latin_with_table(src, dest, len, LC_ISO8859_2, PG_WIN1250, + iso88592_2_win1250, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -140,12 +151,15 @@ latin2_to_win1250(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_LATIN2, PG_WIN1250); - local2local(src, dest, len, PG_LATIN2, PG_WIN1250, iso88592_2_win1250); + converted = local2local(src, dest, len, PG_LATIN2, PG_WIN1250, + iso88592_2_win1250, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -154,10 +168,13 @@ win1250_to_latin2(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1250, PG_LATIN2); - local2local(src, dest, len, PG_WIN1250, PG_LATIN2, win1250_2_iso88592); + converted = local2local(src, dest, len, PG_WIN1250, PG_LATIN2, + win1250_2_iso88592, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c b/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c index a358a707c113..bff27d1c2959 100644 --- a/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c @@ -2,7 +2,7 @@ * * LATINn and MULE_INTERNAL * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -30,8 +30,11 @@ PG_FUNCTION_INFO_V1(mic_to_latin4); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -42,12 +45,14 @@ latin1_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_LATIN1, PG_MULE_INTERNAL); - latin2mic(src, dest, len, LC_ISO8859_1, PG_LATIN1); + converted = latin2mic(src, dest, len, LC_ISO8859_1, PG_LATIN1, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,12 +61,14 @@ mic_to_latin1(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_LATIN1); - mic2latin(src, dest, len, LC_ISO8859_1, PG_LATIN1); + converted = mic2latin(src, dest, len, LC_ISO8859_1, PG_LATIN1, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -70,12 +77,14 @@ latin3_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_LATIN3, PG_MULE_INTERNAL); - latin2mic(src, dest, len, LC_ISO8859_3, PG_LATIN3); + converted = latin2mic(src, dest, len, LC_ISO8859_3, PG_LATIN3, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -84,12 +93,14 @@ mic_to_latin3(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_LATIN3); - mic2latin(src, dest, len, LC_ISO8859_3, PG_LATIN3); + converted = mic2latin(src, dest, len, LC_ISO8859_3, PG_LATIN3, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -98,12 +109,14 @@ latin4_to_mic(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_LATIN4, PG_MULE_INTERNAL); - latin2mic(src, dest, len, LC_ISO8859_4, PG_LATIN4); + converted = latin2mic(src, dest, len, LC_ISO8859_4, PG_LATIN4, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -112,10 +125,12 @@ mic_to_latin4(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_LATIN4); - mic2latin(src, dest, len, LC_ISO8859_4, PG_LATIN4); + converted = mic2latin(src, dest, len, LC_ISO8859_4, PG_LATIN4, noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c b/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c index 75ed49ac54e5..3838b15cab91 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c @@ -2,7 +2,7 @@ * * BIG5 <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_big5); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ big5_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_BIG5, PG_UTF8); - LocalToUtf(src, len, dest, - &big5_to_unicode_tree, - NULL, 0, - NULL, - PG_BIG5); + converted = LocalToUtf(src, len, dest, + &big5_to_unicode_tree, + NULL, 0, + NULL, + PG_BIG5, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_big5(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_BIG5); - UtfToLocal(src, len, dest, - &big5_from_unicode_tree, - NULL, 0, - NULL, - PG_BIG5); + converted = UtfToLocal(src, len, dest, + &big5_from_unicode_tree, + NULL, 0, + NULL, + PG_BIG5, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c b/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c index 90ad316111a5..75719fe5f1b2 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c @@ -2,7 +2,7 @@ * * UTF8 and Cyrillic * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -33,8 +33,11 @@ PG_FUNCTION_INFO_V1(koi8u_to_utf8); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -44,16 +47,19 @@ utf8_to_koi8r(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_KOI8R); - UtfToLocal(src, len, dest, - &koi8r_from_unicode_tree, - NULL, 0, - NULL, - PG_KOI8R); + converted = UtfToLocal(src, len, dest, + &koi8r_from_unicode_tree, + NULL, 0, + NULL, + PG_KOI8R, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -62,16 +68,19 @@ koi8r_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_UTF8); - LocalToUtf(src, len, dest, - &koi8r_to_unicode_tree, - NULL, 0, - NULL, - PG_KOI8R); + converted = LocalToUtf(src, len, dest, + &koi8r_to_unicode_tree, + NULL, 0, + NULL, + PG_KOI8R, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -80,16 +89,19 @@ utf8_to_koi8u(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_KOI8U); - UtfToLocal(src, len, dest, - &koi8u_from_unicode_tree, - NULL, 0, - NULL, - PG_KOI8U); + converted = UtfToLocal(src, len, dest, + &koi8u_from_unicode_tree, + NULL, 0, + NULL, + PG_KOI8U, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -98,14 +110,17 @@ koi8u_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8U, PG_UTF8); - LocalToUtf(src, len, dest, - &koi8u_to_unicode_tree, - NULL, 0, - NULL, - PG_KOI8U); + converted = LocalToUtf(src, len, dest, + &koi8u_to_unicode_tree, + NULL, 0, + NULL, + PG_KOI8U, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c index 018312489cbc..5391001951ac 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c @@ -2,7 +2,7 @@ * * EUC_JIS_2004 <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_euc_jis_2004); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ euc_jis_2004_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JIS_2004, PG_UTF8); - LocalToUtf(src, len, dest, - &euc_jis_2004_to_unicode_tree, - LUmapEUC_JIS_2004_combined, lengthof(LUmapEUC_JIS_2004_combined), - NULL, - PG_EUC_JIS_2004); + converted = LocalToUtf(src, len, dest, + &euc_jis_2004_to_unicode_tree, + LUmapEUC_JIS_2004_combined, lengthof(LUmapEUC_JIS_2004_combined), + NULL, + PG_EUC_JIS_2004, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_euc_jis_2004(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_EUC_JIS_2004); - UtfToLocal(src, len, dest, - &euc_jis_2004_from_unicode_tree, - ULmapEUC_JIS_2004_combined, lengthof(ULmapEUC_JIS_2004_combined), - NULL, - PG_EUC_JIS_2004); + converted = UtfToLocal(src, len, dest, + &euc_jis_2004_from_unicode_tree, + ULmapEUC_JIS_2004_combined, lengthof(ULmapEUC_JIS_2004_combined), + NULL, + PG_EUC_JIS_2004, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c index 62182a9ba8b5..c87d1bf2398e 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c @@ -2,7 +2,7 @@ * * EUC_CN <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_euc_cn); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ euc_cn_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_CN, PG_UTF8); - LocalToUtf(src, len, dest, - &euc_cn_to_unicode_tree, - NULL, 0, - NULL, - PG_EUC_CN); + converted = LocalToUtf(src, len, dest, + &euc_cn_to_unicode_tree, + NULL, 0, + NULL, + PG_EUC_CN, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_euc_cn(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_EUC_CN); - UtfToLocal(src, len, dest, - &euc_cn_from_unicode_tree, - NULL, 0, - NULL, - PG_EUC_CN); + converted = UtfToLocal(src, len, dest, + &euc_cn_from_unicode_tree, + NULL, 0, + NULL, + PG_EUC_CN, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c index dc5abb5dfd46..6a55134db211 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c @@ -2,7 +2,7 @@ * * EUC_JP <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_euc_jp); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ euc_jp_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JP, PG_UTF8); - LocalToUtf(src, len, dest, - &euc_jp_to_unicode_tree, - NULL, 0, - NULL, - PG_EUC_JP); + converted = LocalToUtf(src, len, dest, + &euc_jp_to_unicode_tree, + NULL, 0, + NULL, + PG_EUC_JP, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_euc_jp(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_EUC_JP); - UtfToLocal(src, len, dest, - &euc_jp_from_unicode_tree, - NULL, 0, - NULL, - PG_EUC_JP); + converted = UtfToLocal(src, len, dest, + &euc_jp_from_unicode_tree, + NULL, 0, + NULL, + PG_EUC_JP, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c index 088a38d83907..fe1924e2fec9 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c @@ -2,7 +2,7 @@ * * EUC_KR <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_euc_kr); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ euc_kr_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_KR, PG_UTF8); - LocalToUtf(src, len, dest, - &euc_kr_to_unicode_tree, - NULL, 0, - NULL, - PG_EUC_KR); + converted = LocalToUtf(src, len, dest, + &euc_kr_to_unicode_tree, + NULL, 0, + NULL, + PG_EUC_KR, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_euc_kr(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_EUC_KR); - UtfToLocal(src, len, dest, - &euc_kr_from_unicode_tree, - NULL, 0, - NULL, - PG_EUC_KR); + converted = UtfToLocal(src, len, dest, + &euc_kr_from_unicode_tree, + NULL, 0, + NULL, + PG_EUC_KR, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c index a9fe94f88b88..68215659b577 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c @@ -2,7 +2,7 @@ * * EUC_TW <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_euc_tw); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ euc_tw_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_TW, PG_UTF8); - LocalToUtf(src, len, dest, - &euc_tw_to_unicode_tree, - NULL, 0, - NULL, - PG_EUC_TW); + converted = LocalToUtf(src, len, dest, + &euc_tw_to_unicode_tree, + NULL, 0, + NULL, + PG_EUC_TW, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_euc_tw(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_EUC_TW); - UtfToLocal(src, len, dest, - &euc_tw_from_unicode_tree, - NULL, 0, - NULL, - PG_EUC_TW); + converted = UtfToLocal(src, len, dest, + &euc_tw_from_unicode_tree, + NULL, 0, + NULL, + PG_EUC_TW, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c b/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c index 96909b588592..e1a59c39a4db 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c @@ -2,7 +2,7 @@ * * GB18030 <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -183,8 +183,11 @@ conv_utf8_to_18030(uint32 code) * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -193,16 +196,19 @@ gb18030_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_GB18030, PG_UTF8); - LocalToUtf(src, len, dest, - &gb18030_to_unicode_tree, - NULL, 0, - conv_18030_to_utf8, - PG_GB18030); + converted = LocalToUtf(src, len, dest, + &gb18030_to_unicode_tree, + NULL, 0, + conv_18030_to_utf8, + PG_GB18030, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -211,14 +217,17 @@ utf8_to_gb18030(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_GB18030); - UtfToLocal(src, len, dest, - &gb18030_from_unicode_tree, - NULL, 0, - conv_utf8_to_18030, - PG_GB18030); + converted = UtfToLocal(src, len, dest, + &gb18030_from_unicode_tree, + NULL, 0, + conv_utf8_to_18030, + PG_GB18030, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c b/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c index 78bbcd3ce7dd..881386d53477 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c @@ -2,7 +2,7 @@ * * GBK <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_gbk); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ gbk_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_GBK, PG_UTF8); - LocalToUtf(src, len, dest, - &gbk_to_unicode_tree, - NULL, 0, - NULL, - PG_GBK); + converted = LocalToUtf(src, len, dest, + &gbk_to_unicode_tree, + NULL, 0, + NULL, + PG_GBK, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_gbk(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_GBK); - UtfToLocal(src, len, dest, - &gbk_from_unicode_tree, - NULL, 0, - NULL, - PG_GBK); + converted = UtfToLocal(src, len, dest, + &gbk_from_unicode_tree, + NULL, 0, + NULL, + PG_GBK, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c index 348524f4a2c9..d93a521badf2 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c @@ -2,7 +2,7 @@ * * ISO 8859 2-16 <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -52,8 +52,11 @@ PG_FUNCTION_INFO_V1(utf8_to_iso8859); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -100,6 +103,7 @@ iso8859_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); int i; CHECK_ENCODING_CONVERSION_ARGS(-1, PG_UTF8); @@ -108,12 +112,15 @@ iso8859_to_utf8(PG_FUNCTION_ARGS) { if (encoding == maps[i].encoding) { - LocalToUtf(src, len, dest, - maps[i].map1, - NULL, 0, - NULL, - encoding); - PG_RETURN_VOID(); + int converted; + + converted = LocalToUtf(src, len, dest, + maps[i].map1, + NULL, 0, + NULL, + encoding, + noError); + PG_RETURN_INT32(converted); } } @@ -122,7 +129,7 @@ iso8859_to_utf8(PG_FUNCTION_ARGS) errmsg("unexpected encoding ID %d for ISO 8859 character sets", encoding))); - PG_RETURN_VOID(); + PG_RETURN_INT32(0); } Datum @@ -132,6 +139,7 @@ utf8_to_iso8859(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); int i; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, -1); @@ -140,12 +148,15 @@ utf8_to_iso8859(PG_FUNCTION_ARGS) { if (encoding == maps[i].encoding) { - UtfToLocal(src, len, dest, - maps[i].map2, - NULL, 0, - NULL, - encoding); - PG_RETURN_VOID(); + int converted; + + converted = UtfToLocal(src, len, dest, + maps[i].map2, + NULL, 0, + NULL, + encoding, + noError); + PG_RETURN_INT32(converted); } } @@ -154,5 +165,5 @@ utf8_to_iso8859(PG_FUNCTION_ARGS) errmsg("unexpected encoding ID %d for ISO 8859 character sets", encoding))); - PG_RETURN_VOID(); + PG_RETURN_INT32(0); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c index 2cdca9f780d8..d0dc4cca3788 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c @@ -2,7 +2,7 @@ * * ISO8859_1 <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -26,8 +26,11 @@ PG_FUNCTION_INFO_V1(utf8_to_iso8859_1); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -37,6 +40,8 @@ iso8859_1_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + unsigned char *start = src; unsigned short c; CHECK_ENCODING_CONVERSION_ARGS(PG_LATIN1, PG_UTF8); @@ -45,7 +50,11 @@ iso8859_1_to_utf8(PG_FUNCTION_ARGS) { c = *src; if (c == 0) + { + if (noError) + break; report_invalid_encoding(PG_LATIN1, (const char *) src, len); + } if (!IS_HIGHBIT_SET(c)) *dest++ = c; else @@ -58,7 +67,7 @@ iso8859_1_to_utf8(PG_FUNCTION_ARGS) } *dest = '\0'; - PG_RETURN_VOID(); + PG_RETURN_INT32(src - start); } Datum @@ -67,6 +76,8 @@ utf8_to_iso8859_1(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + unsigned char *start = src; unsigned short c, c1; @@ -76,7 +87,11 @@ utf8_to_iso8859_1(PG_FUNCTION_ARGS) { c = *src; if (c == 0) + { + if (noError) + break; report_invalid_encoding(PG_UTF8, (const char *) src, len); + } /* fast path for ASCII-subset characters */ if (!IS_HIGHBIT_SET(c)) { @@ -89,10 +104,18 @@ utf8_to_iso8859_1(PG_FUNCTION_ARGS) int l = pg_utf_mblen(src); if (l > len || !pg_utf8_islegal(src, l)) + { + if (noError) + break; report_invalid_encoding(PG_UTF8, (const char *) src, len); + } if (l != 2) + { + if (noError) + break; report_untranslatable_char(PG_UTF8, PG_LATIN1, (const char *) src, len); + } c1 = src[1] & 0x3f; c = ((c & 0x1f) << 6) | c1; if (c >= 0x80 && c <= 0xff) @@ -102,11 +125,15 @@ utf8_to_iso8859_1(PG_FUNCTION_ARGS) len -= 2; } else + { + if (noError) + break; report_untranslatable_char(PG_UTF8, PG_LATIN1, (const char *) src, len); + } } } *dest = '\0'; - PG_RETURN_VOID(); + PG_RETURN_INT32(src - start); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c b/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c index e09a7c8e41eb..317daa2d5eed 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c @@ -2,7 +2,7 @@ * * JOHAB <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_johab); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ johab_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_JOHAB, PG_UTF8); - LocalToUtf(src, len, dest, - &johab_to_unicode_tree, - NULL, 0, - NULL, - PG_JOHAB); + converted = LocalToUtf(src, len, dest, + &johab_to_unicode_tree, + NULL, 0, + NULL, + PG_JOHAB, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_johab(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_JOHAB); - UtfToLocal(src, len, dest, - &johab_from_unicode_tree, - NULL, 0, - NULL, - PG_JOHAB); + converted = UtfToLocal(src, len, dest, + &johab_from_unicode_tree, + NULL, 0, + NULL, + PG_JOHAB, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c b/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c index c56fa80a4bba..4c9348aba59f 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c @@ -2,7 +2,7 @@ * * SJIS <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_sjis); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ sjis_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_UTF8); - LocalToUtf(src, len, dest, - &sjis_to_unicode_tree, - NULL, 0, - NULL, - PG_SJIS); + converted = LocalToUtf(src, len, dest, + &sjis_to_unicode_tree, + NULL, 0, + NULL, + PG_SJIS, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_sjis(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_SJIS); - UtfToLocal(src, len, dest, - &sjis_from_unicode_tree, - NULL, 0, - NULL, - PG_SJIS); + converted = UtfToLocal(src, len, dest, + &sjis_from_unicode_tree, + NULL, 0, + NULL, + PG_SJIS, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c b/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c index 458500998d49..1fffdc5930c2 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c @@ -2,7 +2,7 @@ * * SHIFT_JIS_2004 <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_shift_jis_2004); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ shift_jis_2004_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_SHIFT_JIS_2004, PG_UTF8); - LocalToUtf(src, len, dest, - &shift_jis_2004_to_unicode_tree, - LUmapSHIFT_JIS_2004_combined, lengthof(LUmapSHIFT_JIS_2004_combined), - NULL, - PG_SHIFT_JIS_2004); + converted = LocalToUtf(src, len, dest, + &shift_jis_2004_to_unicode_tree, + LUmapSHIFT_JIS_2004_combined, lengthof(LUmapSHIFT_JIS_2004_combined), + NULL, + PG_SHIFT_JIS_2004, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_shift_jis_2004(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_SHIFT_JIS_2004); - UtfToLocal(src, len, dest, - &shift_jis_2004_from_unicode_tree, - ULmapSHIFT_JIS_2004_combined, lengthof(ULmapSHIFT_JIS_2004_combined), - NULL, - PG_SHIFT_JIS_2004); + converted = UtfToLocal(src, len, dest, + &shift_jis_2004_from_unicode_tree, + ULmapSHIFT_JIS_2004_combined, lengthof(ULmapSHIFT_JIS_2004_combined), + NULL, + PG_SHIFT_JIS_2004, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c b/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c index 3226ed032583..d9471dad097c 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c @@ -2,7 +2,7 @@ * * UHC <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -28,8 +28,11 @@ PG_FUNCTION_INFO_V1(utf8_to_uhc); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ Datum @@ -38,16 +41,19 @@ uhc_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UHC, PG_UTF8); - LocalToUtf(src, len, dest, - &uhc_to_unicode_tree, - NULL, 0, - NULL, - PG_UHC); + converted = LocalToUtf(src, len, dest, + &uhc_to_unicode_tree, + NULL, 0, + NULL, + PG_UHC, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } Datum @@ -56,14 +62,17 @@ utf8_to_uhc(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); + int converted; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_UHC); - UtfToLocal(src, len, dest, - &uhc_from_unicode_tree, - NULL, 0, - NULL, - PG_UHC); + converted = UtfToLocal(src, len, dest, + &uhc_from_unicode_tree, + NULL, 0, + NULL, + PG_UHC, + noError); - PG_RETURN_VOID(); + PG_RETURN_INT32(converted); } diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c b/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c index 1a0074d063cc..110ba5677d03 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c @@ -2,7 +2,7 @@ * * WIN <--> UTF8 * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -48,8 +48,11 @@ PG_FUNCTION_INFO_V1(utf8_to_win); * INTEGER, -- destination encoding id * CSTRING, -- source string (null terminated C string) * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; + * INTEGER, -- source string length + * BOOL -- if true, don't throw an error if conversion fails + * ) returns INTEGER; + * + * Returns the number of bytes successfully converted. * ---------- */ @@ -81,6 +84,7 @@ win_to_utf8(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); int i; CHECK_ENCODING_CONVERSION_ARGS(-1, PG_UTF8); @@ -89,12 +93,15 @@ win_to_utf8(PG_FUNCTION_ARGS) { if (encoding == maps[i].encoding) { - LocalToUtf(src, len, dest, - maps[i].map1, - NULL, 0, - NULL, - encoding); - PG_RETURN_VOID(); + int converted; + + converted = LocalToUtf(src, len, dest, + maps[i].map1, + NULL, 0, + NULL, + encoding, + noError); + PG_RETURN_INT32(converted); } } @@ -103,7 +110,7 @@ win_to_utf8(PG_FUNCTION_ARGS) errmsg("unexpected encoding ID %d for WIN character sets", encoding))); - PG_RETURN_VOID(); + PG_RETURN_INT32(0); } Datum @@ -113,6 +120,7 @@ utf8_to_win(PG_FUNCTION_ARGS) unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); int len = PG_GETARG_INT32(4); + bool noError = PG_GETARG_BOOL(5); int i; CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, -1); @@ -121,12 +129,15 @@ utf8_to_win(PG_FUNCTION_ARGS) { if (encoding == maps[i].encoding) { - UtfToLocal(src, len, dest, - maps[i].map2, - NULL, 0, - NULL, - encoding); - PG_RETURN_VOID(); + int converted; + + converted = UtfToLocal(src, len, dest, + maps[i].map2, + NULL, 0, + NULL, + encoding, + noError); + PG_RETURN_INT32(converted); } } @@ -135,5 +146,5 @@ utf8_to_win(PG_FUNCTION_ARGS) errmsg("unexpected encoding ID %d for WIN character sets", encoding))); - PG_RETURN_VOID(); + PG_RETURN_INT32(0); } diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c index 98f3e864f4d9..be52103fe699 100644 --- a/src/backend/utils/mb/mbutils.c +++ b/src/backend/utils/mb/mbutils.c @@ -23,7 +23,7 @@ * the result is validly encoded according to the destination encoding. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -408,12 +408,13 @@ pg_do_encoding_conversion(unsigned char *src, int len, MemoryContextAllocHuge(CurrentMemoryContext, (Size) len * MAX_CONVERSION_GROWTH + 1); - OidFunctionCall5(proc, - Int32GetDatum(src_encoding), - Int32GetDatum(dest_encoding), - CStringGetDatum((char *)src), - CStringGetDatum((char *)result), - Int32GetDatum(len)); + (void) OidFunctionCall6(proc, + Int32GetDatum(src_encoding), + Int32GetDatum(dest_encoding), + CStringGetDatum(src), + CStringGetDatum(result), + Int32GetDatum(len), + BoolGetDatum(false)); /* * If the result is large, it's worth repalloc'ing to release any extra @@ -437,6 +438,62 @@ pg_do_encoding_conversion(unsigned char *src, int len, return result; } +/* + * Convert src string to another encoding. + * + * This function has a different API than the other conversion functions. + * The caller should've looked up the conversion function using + * FindDefaultConversionProc(). Unlike the other functions, the converted + * result is not palloc'd. It is written to the caller-supplied buffer + * instead. + * + * src_encoding - encoding to convert from + * dest_encoding - encoding to convert to + * src, srclen - input buffer and its length in bytes + * dest, destlen - destination buffer and its size in bytes + * + * The output is null-terminated. + * + * If destlen < srclen * MAX_CONVERSION_LENGTH + 1, the converted output + * wouldn't necessarily fit in the output buffer, and the function will not + * convert the whole input. + * + * TODO: The conversion function interface is not great. Firstly, it + * would be nice to pass through the destination buffer size to the + * conversion function, so that if you pass a shorter destination buffer, it + * could still continue to fill up the whole buffer. Currently, we have to + * assume worst case expansion and stop the conversion short, even if there + * is in fact space left in the destination buffer. Secondly, it would be + * nice to return the number of bytes written to the caller, to avoid a call + * to strlen(). + */ +int +pg_do_encoding_conversion_buf(Oid proc, + int src_encoding, + int dest_encoding, + unsigned char *src, int srclen, + unsigned char *dest, int destlen, + bool noError) +{ + Datum result; + + /* + * If the destination buffer is not large enough to hold the result in the + * worst case, limit the input size passed to the conversion function. + */ + if ((Size) srclen >= ((destlen - 1) / (Size) MAX_CONVERSION_GROWTH)) + srclen = ((destlen - 1) / (Size) MAX_CONVERSION_GROWTH); + + result = OidFunctionCall6(proc, + Int32GetDatum(src_encoding), + Int32GetDatum(dest_encoding), + CStringGetDatum(src), + CStringGetDatum(dest), + Int32GetDatum(srclen), + BoolGetDatum(noError)); + return DatumGetInt32(result); +} + /* * Convert string to encoding encoding_name. The source * encoding is the DB encoding. @@ -521,7 +578,7 @@ pg_convert(PG_FUNCTION_ARGS) /* make sure that source string is valid */ len = VARSIZE_ANY_EXHDR(string); src_str = VARDATA_ANY(string); - pg_verify_mbstr_len(src_encoding, src_str, len, false); + (void) pg_verify_mbstr(src_encoding, src_str, len, false); /* perform conversion */ dest_str = (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, src_str), @@ -794,12 +851,13 @@ perform_default_encoding_conversion(const char *src, int len, MemoryContextAllocHuge(CurrentMemoryContext, (Size) len * MAX_CONVERSION_GROWTH + 1); - FunctionCall5(flinfo, + FunctionCall6(flinfo, Int32GetDatum(src_encoding), Int32GetDatum(dest_encoding), CStringGetDatum((char *) src), CStringGetDatum(result), - Int32GetDatum(len)); + Int32GetDatum(len), + BoolGetDatum(false)); /* * Release extra space if there might be a lot --- see comments in @@ -881,12 +939,13 @@ pg_unicode_to_server(pg_wchar c, unsigned char *s) c_as_utf8[c_as_utf8_len] = '\0'; /* Convert, or throw error if we can't */ - FunctionCall5(Utf8ToServerConvProc, + FunctionCall6(Utf8ToServerConvProc, Int32GetDatum(PG_UTF8), Int32GetDatum(server_encoding), CStringGetDatum(c_as_utf8), CStringGetDatum(s), - Int32GetDatum(c_as_utf8_len)); + Int32GetDatum(c_as_utf8_len), + BoolGetDatum(false)); } @@ -1344,10 +1403,10 @@ static bool pg_generic_charinc(unsigned char *charptr, int len) { unsigned char *lastbyte = charptr + len - 1; - mbverifier mbverify; + mbchar_verifier mbverify; /* We can just invoke the character verifier directly. */ - mbverify = pg_wchar_table[GetDatabaseEncoding()].mbverify; + mbverify = pg_wchar_table[GetDatabaseEncoding()].mbverifychar; while (*lastbyte < (unsigned char) 255) { @@ -1574,8 +1633,7 @@ pg_database_encoding_max_length(void) bool pg_verifymbstr(const char *mbstr, int len, bool noError) { - return - pg_verify_mbstr_len(GetDatabaseEncoding(), mbstr, len, noError) >= 0; + return pg_verify_mbstr(GetDatabaseEncoding(), mbstr, len, noError); } /* @@ -1585,7 +1643,18 @@ pg_verifymbstr(const char *mbstr, int len, bool noError) bool pg_verify_mbstr(int encoding, const char *mbstr, int len, bool noError) { - return pg_verify_mbstr_len(encoding, mbstr, len, noError) >= 0; + int oklen; + + Assert(PG_VALID_ENCODING(encoding)); + + oklen = pg_wchar_table[encoding].mbverifystr((const unsigned char *) mbstr, len); + if (oklen != len) + { + if (noError) + return false; + report_invalid_encoding(encoding, mbstr + oklen, len - oklen); + } + return true; } /* @@ -1598,11 +1667,14 @@ pg_verify_mbstr(int encoding, const char *mbstr, int len, bool noError) * If OK, return length of string in the encoding. * If a problem is found, return -1 when noError is * true; when noError is false, ereport() a descriptive message. + * + * Note: We cannot use the faster encoding-specific mbverifystr() function + * here, because we need to count the number of characters in the string. */ int pg_verify_mbstr_len(int encoding, const char *mbstr, int len, bool noError) { - mbverifier mbverify; + mbchar_verifier mbverifychar; int mb_len; Assert(PG_VALID_ENCODING(encoding)); @@ -1622,7 +1694,7 @@ pg_verify_mbstr_len(int encoding, const char *mbstr, int len, bool noError) } /* fetch function pointer just once */ - mbverify = pg_wchar_table[encoding].mbverify; + mbverifychar = pg_wchar_table[encoding].mbverifychar; mb_len = 0; @@ -1645,7 +1717,7 @@ pg_verify_mbstr_len(int encoding, const char *mbstr, int len, bool noError) report_invalid_encoding(encoding, mbstr, len); } - l = (*mbverify) ((const unsigned char *) mbstr, len); + l = (*mbverifychar) ((const unsigned char *) mbstr, len); if (l < 0) { diff --git a/src/backend/utils/mb/stringinfo_mb.c b/src/backend/utils/mb/stringinfo_mb.c index 5f51f538c180..1fd6c63d3d70 100644 --- a/src/backend/utils/mb/stringinfo_mb.c +++ b/src/backend/utils/mb/stringinfo_mb.c @@ -8,7 +8,7 @@ * code. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/Makefile b/src/backend/utils/misc/Makefile index a6438a7caafa..8be3918af8c3 100644 --- a/src/backend/utils/misc/Makefile +++ b/src/backend/utils/misc/Makefile @@ -25,6 +25,7 @@ OBJS = \ pg_rusage.o \ ps_status.o \ queryenvironment.o \ + queryjumble.o \ rls.o \ sampling.o \ superuser.o \ diff --git a/src/backend/utils/misc/check_guc b/src/backend/utils/misc/check_guc index 55d79d918b49..627ef106ad52 100755 --- a/src/backend/utils/misc/check_guc +++ b/src/backend/utils/misc/check_guc @@ -16,7 +16,7 @@ ## if an option is valid but shows up in only one file (guc.c but not ## postgresql.conf.sample), it should be listed here so that it ## can be ignored -INTENTIONALLY_NOT_INCLUDED="debug_deadlocks \ +INTENTIONALLY_NOT_INCLUDED="debug_deadlocks in_hot_standby \ is_superuser lc_collate lc_ctype lc_messages lc_monetary lc_numeric lc_time \ pre_auth_delay role seed server_encoding server_version server_version_num \ session_authorization trace_lock_oidmin trace_lock_table trace_locks trace_lwlocks \ diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index b1eb66677ef6..47358c81a07e 100644 --- a/src/backend/utils/misc/guc-file.l +++ b/src/backend/utils/misc/guc-file.l @@ -2,7 +2,7 @@ /* * Scanner for the configuration file * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/backend/utils/misc/guc-file.l */ @@ -70,7 +70,6 @@ static void record_config_file_error(const char *errmsg, ConfigVariable **tail_p); static int GUC_flex_fatal(const char *msg); -static char *GUC_scanstr(const char *s); /* LCOV_EXCL_START */ @@ -298,7 +297,7 @@ ProcessConfigFileInternal(GucContext context, bool applySettings, int elevel) * Try to find the variable; but do not create a custom placeholder if * it's not there already. */ - record = find_option(item->name, false, elevel); + record = find_option(item->name, false, true, elevel); if (record) { @@ -322,12 +321,12 @@ ProcessConfigFileInternal(GucContext context, bool applySettings, int elevel) /* Now mark it as present in file */ record->status |= GUC_IS_IN_FILE; } - else if (strchr(item->name, GUC_QUALIFIER_SEPARATOR) == NULL) + else if (!valid_custom_variable_name(item->name)) { /* Invalid non-custom variable, so complain */ ereport(elevel, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\" in file \"%s\" line %u", + errmsg("unrecognized configuration parameter \"%s\" in file \"%s\" line %d", item->name, item->filename, item->sourceline))); item->errmsg = pstrdup("unrecognized configuration parameter"); @@ -816,7 +815,7 @@ ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel, token != GUC_UNQUOTED_STRING) goto parse_error; if (token == GUC_STRING) /* strip quotes and escapes */ - opt_value = GUC_scanstr(yytext); + opt_value = DeescapeQuotedString(yytext); else opt_value = pstrdup(yytext); @@ -1151,22 +1150,25 @@ FreeConfigVariable(ConfigVariable *item) /* - * scanstr + * DeescapeQuotedString * * Strip the quotes surrounding the given string, and collapse any embedded * '' sequences and backslash escapes. * - * the string returned is palloc'd and should eventually be pfree'd by the + * The string returned is palloc'd and should eventually be pfree'd by the * caller. + * + * This is exported because it is also used by the bootstrap scanner. */ -static char * -GUC_scanstr(const char *s) +char * +DeescapeQuotedString(const char *s) { char *newStr; int len, i, j; + /* We just Assert that there are leading and trailing quotes */ Assert(s != NULL && s[0] == '\''); len = strlen(s); Assert(len >= 2); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 2c5c3f50f633..70b5bc1878a0 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -8,7 +8,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * Written by Peter Eisentraut . * * IDENTIFICATION @@ -38,6 +38,7 @@ #include "access/gin.h" #include "access/rmgr.h" #include "access/tableam.h" +#include "access/toast_compression.h" #include "access/transam.h" #include "access/twophase.h" #include "access/xact.h" @@ -91,6 +92,7 @@ #include "tcop/tcopprot.h" #include "tsearch/ts_cache.h" #include "utils/acl.h" +#include "utils/backend_status.h" #include "utils/builtins.h" #include "utils/bytea.h" #include "utils/faultinjector.h" @@ -102,9 +104,11 @@ #include "utils/plancache.h" #include "utils/portal.h" #include "utils/ps_status.h" +#include "utils/queryjumble.h" #include "utils/rls.h" #include "utils/snapmgr.h" #include "utils/tzparser.h" +#include "utils/inval.h" #include "utils/varlena.h" #include "utils/xml.h" #include "cdb/cdbdisp_query.h" @@ -220,6 +224,7 @@ static bool check_cluster_name(char **newval, void **extra, GucSource source); static const char *show_unix_socket_permissions(void); static const char *show_log_file_mode(void); static const char *show_data_directory_mode(void); +static const char *show_in_hot_standby(void); static bool check_backtrace_functions(char **newval, void **extra, GucSource source); static void assign_backtrace_functions(const char *newval, void *extra); static bool check_recovery_target_timeline(char **newval, void **extra, GucSource source); @@ -410,6 +415,23 @@ static const struct config_enum_entry backslash_quote_options[] = { {NULL, 0, false} }; +/* + * Although only "on", "off", and "auto" are documented, we accept + * all the likely variants of "on" and "off". + */ +static const struct config_enum_entry compute_query_id_options[] = { + {"auto", COMPUTE_QUERY_ID_AUTO, false}, + {"on", COMPUTE_QUERY_ID_ON, false}, + {"off", COMPUTE_QUERY_ID_OFF, false}, + {"true", COMPUTE_QUERY_ID_ON, true}, + {"false", COMPUTE_QUERY_ID_OFF, true}, + {"yes", COMPUTE_QUERY_ID_ON, true}, + {"no", COMPUTE_QUERY_ID_OFF, true}, + {"1", COMPUTE_QUERY_ID_ON, true}, + {"0", COMPUTE_QUERY_ID_OFF, true}, + {NULL, 0, false} +}; + /* * Although only "on", "off", and "partition" are documented, we * accept all the likely variants of "on" and "off". @@ -501,6 +523,14 @@ const struct config_enum_entry ssl_protocol_versions_info[] = { StaticAssertDecl(lengthof(ssl_protocol_versions_info) == (PG_TLS1_3_VERSION + 2), "array length mismatch"); +static struct config_enum_entry recovery_init_sync_method_options[] = { + {"fsync", RECOVERY_INIT_SYNC_METHOD_FSYNC, false}, +#ifdef HAVE_SYNCFS + {"syncfs", RECOVERY_INIT_SYNC_METHOD_SYNCFS, false}, +#endif + {NULL, 0, false} +}; + static struct config_enum_entry shared_memory_options[] = { #ifndef WIN32 {"sysv", SHMEM_TYPE_SYSV, false}, @@ -514,6 +544,14 @@ static struct config_enum_entry shared_memory_options[] = { {NULL, 0, false} }; +static struct config_enum_entry default_toast_compression_options[] = { + {"pglz", TOAST_PGLZ_COMPRESSION, false}, +#ifdef USE_LZ4 + {"lz4", TOAST_LZ4_COMPRESSION, false}, +#endif + {NULL, 0, false} +}; + /* * Options for enum values stored in other modules */ @@ -626,6 +664,7 @@ static int wal_block_size; static bool data_checksums; static bool integer_datetimes; static bool assert_enabled; +static bool in_hot_standby; static char *recovery_target_timeline_string; static char *recovery_target_string; static char *recovery_target_xid_string; @@ -692,14 +731,12 @@ const char *const config_group_names[] = gettext_noop("Ungrouped"), /* FILE_LOCATIONS */ gettext_noop("File Locations"), - /* CONN_AUTH */ - gettext_noop("Connections and Authentication"), /* CONN_AUTH_SETTINGS */ gettext_noop("Connections and Authentication / Connection Settings"), - /* CONN_AUTH_AUTH */ - gettext_noop("Connections and Authentication / Authentication"), - /* CONN_AUTH_SSL */ - gettext_noop("Connections and Authentication / SSL"), + /* CONN_AUTH_AUTH */ + gettext_noop("Connections and Authentication / Authentication"), + /* CONN_AUTH_SSL */ + gettext_noop("Connections and Authentication / SSL"), /* EXTERNAL_TABLES */ gettext_noop("External Tables"), /* APPENDONLY_TABLES */ @@ -732,8 +769,6 @@ const char *const config_group_names[] = gettext_noop("Write-Ahead Log / Archive Recovery"), /* WAL_RECOVERY_TARGET */ gettext_noop("Write-Ahead Log / Recovery Target"), - /* REPLICATION */ - gettext_noop("Replication"), /* REPLICATION_SENDING */ gettext_noop("Replication / Sending Servers"), /* REPLICATION_PRIMARY */ @@ -742,8 +777,6 @@ const char *const config_group_names[] = gettext_noop("Replication / Standby Servers"), /* REPLICATION_SUBSCRIBERS */ gettext_noop("Replication / Subscribers"), - /* QUERY_TUNING */ - gettext_noop("Query Tuning"), /* QUERY_TUNING_METHOD */ gettext_noop("Query Tuning / Planner Method Configuration"), /* QUERY_TUNING_COST */ @@ -759,11 +792,11 @@ const char *const config_group_names[] = /* LOGGING_WHAT */ gettext_noop("Reporting and Logging / What to Log"), /* PROCESS_TITLE */ - gettext_noop("Process Title"), + gettext_noop("Reporting and Logging / Process Title"), /* STATS */ gettext_noop("Statistics"), /* STATS_ANALYZE */ - gettext_noop("Statistics / ANALYZE Database Contents"), + gettext_noop("Statistics / Analyze"), /* STATS_MONITORING */ gettext_noop("Statistics / Monitoring"), /* STATS_COLLECTOR */ @@ -790,7 +823,7 @@ const char *const config_group_names[] = gettext_noop("Version and Platform Compatibility / Other Platforms and Clients"), /* COMPAT_OPTIONS_IGNORED */ gettext_noop("Version and Platform Compatibility / Ignored"), - /* ERROR_HANDLING */ + /* ERROR_HANDLING_OPTIONS */ gettext_noop("Error Handling"), /* GP_ARRAY_CONFIGURATION */ gettext_noop(PACKAGE_NAME " / Array Configuration"), @@ -1060,6 +1093,23 @@ static struct config_bool ConfigureNamesBool[] = true, NULL, NULL, NULL }, + { + {"enable_resultcache", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of result caching."), + NULL, + GUC_EXPLAIN + }, + &enable_resultcache, + /* + * GPDB: off by default. Result Cache (Memoize) is not integrated with + * the MPP planner/executor -- a generated ResultCache plan node trips + * "unrecognized node type" in expression_tree_mutator() and is also + * absent from the binary plan-dispatch (outfast.c/readfast.c). Until + * it is properly supported, leave it disabled so it is never generated. + */ + false, + NULL, NULL, NULL + }, { {"enable_nestloop", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of nested-loop join plans."), @@ -1142,7 +1192,7 @@ static struct config_bool ConfigureNamesBool[] = }, { {"enable_partition_pruning", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables plan-time and run-time partition pruning."), + gettext_noop("Enables plan-time and execution-time partition pruning."), gettext_noop("Allows the query planner and executor to compare partition " "bounds to conditions in the query to determine which " "partitions must be scanned."), @@ -1155,13 +1205,23 @@ static struct config_bool ConfigureNamesBool[] = { {"geqo", PGC_USERSET, DEFUNCT_OPTIONS, gettext_noop("Unused. Syntax check only for PostgreSQL compatibility."), - NULL, + NULL, GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE }, &defunct_bool, false, NULL, NULL, NULL }, + { + {"enable_async_append", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables the planner's use of async append plans."), + NULL, + GUC_EXPLAIN + }, + &enable_async_append, + true, + NULL, NULL, NULL + }, { /* Not for general use --- used by SET SESSION AUTHORIZATION */ @@ -1184,7 +1244,7 @@ static struct config_bool ConfigureNamesBool[] = check_bonjour, NULL, NULL }, { - {"track_commit_timestamp", PGC_POSTMASTER, REPLICATION, + {"track_commit_timestamp", PGC_POSTMASTER, REPLICATION_SENDING, gettext_noop("Collects transaction commit time."), NULL }, @@ -1297,7 +1357,7 @@ static struct config_bool ConfigureNamesBool[] = { {"wal_log_hints", PGC_POSTMASTER, WAL_SETTINGS, - gettext_noop("Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications."), + gettext_noop("Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modification."), NULL }, &wal_log_hints, @@ -1404,6 +1464,16 @@ static struct config_bool ConfigureNamesBool[] = true, NULL, NULL, NULL }, + { + {"remove_temp_files_after_crash", PGC_SIGHUP, DEVELOPER_OPTIONS, + gettext_noop("Remove temporary files after backend crash."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &remove_temp_files_after_crash, + true, + NULL, NULL, NULL + }, { {"log_duration", PGC_SUSET, LOGGING_WHAT, @@ -1528,6 +1598,15 @@ static struct config_bool ConfigureNamesBool[] = false, NULL, NULL, NULL }, + { + {"track_wal_io_timing", PGC_SUSET, STATS_COLLECTOR, + gettext_noop("Collects timing statistics for WAL I/O activity."), + NULL + }, + &track_wal_io_timing, + false, + NULL, NULL, NULL + }, { {"update_process_title", PGC_SUSET, PROCESS_TITLE, @@ -1616,7 +1695,15 @@ static struct config_bool ConfigureNamesBool[] = false, NULL, NULL, NULL }, - + { + {"log_recovery_conflict_waits", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Logs standby recovery conflict waits."), + NULL + }, + &log_recovery_conflict_waits, + false, + NULL, NULL, NULL + }, { {"log_hostname", PGC_SIGHUP, LOGGING_WHAT, gettext_noop("Logs the host name in the connection logs."), @@ -1654,7 +1741,8 @@ static struct config_bool ConfigureNamesBool[] = { {"default_transaction_read_only", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Sets the default read-only status of new transactions."), - NULL + NULL, + GUC_REPORT }, &DefaultXactReadOnly, false, @@ -1700,7 +1788,7 @@ static struct config_bool ConfigureNamesBool[] = }, { {"check_function_bodies", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Check function bodies during CREATE FUNCTION."), + gettext_noop("Check routine bodies during CREATE FUNCTION and CREATE PROCEDURE."), NULL }, &check_function_bodies, @@ -1808,7 +1896,7 @@ static struct config_bool ConfigureNamesBool[] = { {"integer_datetimes", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Datetimes are integer based."), + gettext_noop("Shows whether datetimes are integer based."), NULL, GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE }, @@ -1889,7 +1977,18 @@ static struct config_bool ConfigureNamesBool[] = }, { - {"allow_system_table_mods", PGC_USERSET, CUSTOM_OPTIONS, + {"in_hot_standby", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows whether hot standby is currently active."), + NULL, + GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &in_hot_standby, + false, + NULL, NULL, show_in_hot_standby + }, + + { + {"allow_system_table_mods", PGC_SUSET, DEVELOPER_OPTIONS, gettext_noop("Allows modifications of the structure of system tables."), NULL, GUC_NOT_IN_SAMPLE | GUC_NO_SHOW_ALL @@ -1922,16 +2021,6 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, - { - {"operator_precedence_warning", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Emit a warning for constructs that changed meaning since PostgreSQL 9.4."), - NULL, - }, - &operator_precedence_warning, - false, - NULL, NULL, NULL - }, - { {"quote_all_identifiers", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, gettext_noop("When generating SQL fragments, quote all identifiers."), @@ -1976,7 +2065,7 @@ static struct config_bool ConfigureNamesBool[] = { {"parallel_leader_participation", PGC_USERSET, RESOURCES_ASYNCHRONOUS, gettext_noop("Controls whether Gather and Gather Merge also run subplans."), - gettext_noop("Should gather nodes also run subplans, or just gather tuples?"), + gettext_noop("Should gather nodes also run subplans or just gather tuples?"), GUC_EXPLAIN }, ¶llel_leader_participation, @@ -1997,7 +2086,7 @@ static struct config_bool ConfigureNamesBool[] = { {"jit_debugging_support", PGC_SU_BACKEND, DEVELOPER_OPTIONS, - gettext_noop("Register JIT compiled function with debugger."), + gettext_noop("Register JIT-compiled functions with debugger."), NULL, GUC_NOT_IN_SAMPLE }, @@ -2036,7 +2125,7 @@ static struct config_bool ConfigureNamesBool[] = { {"jit_profiling_support", PGC_SU_BACKEND, DEVELOPER_OPTIONS, - gettext_noop("Register JIT compiled function with perf profiler."), + gettext_noop("Register JIT-compiled functions with perf profiler."), NULL, GUC_NOT_IN_SAMPLE }, @@ -2356,7 +2445,7 @@ static struct config_int ConfigureNamesInt[] = { {"data_directory_mode", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Mode of the data directory."), + gettext_noop("Shows the mode of the data directory."), gettext_noop("The parameter value is a numeric mode specification " "in the form accepted by the chmod and umask system " "calls. (To use the customary octal format the number " @@ -2447,7 +2536,7 @@ static struct config_int ConfigureNamesInt[] = NULL }, &VacuumCostPageMiss, - 10, 0, 10000, + 2, 0, 10000, NULL, NULL, NULL }, @@ -2561,6 +2650,17 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"idle_session_timeout", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the maximum allowed idle time between queries, when not in a transaction."), + gettext_noop("A value of 0 turns off the timeout."), + GUC_UNIT_MS + }, + &IdleSessionTimeout, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + { {"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Minimum age at which VACUUM should freeze a table row."), @@ -2607,7 +2707,25 @@ static struct config_int ConfigureNamesInt[] = NULL }, &vacuum_defer_cleanup_age, - 0, 0, 1000000, + 0, 0, 1000000, /* see ComputeXidHorizons */ + NULL, NULL, NULL + }, + { + {"vacuum_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Age at which VACUUM should trigger failsafe to avoid a wraparound outage."), + NULL + }, + &vacuum_failsafe_age, + 1600000000, 0, 2100000000, + NULL, NULL, NULL + }, + { + {"vacuum_multixact_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Multixact age at which VACUUM should trigger failsafe to avoid a wraparound outage."), + NULL + }, + &vacuum_multixact_failsafe_age, + 1600000000, 0, 2100000000, NULL, NULL, NULL }, @@ -2789,7 +2907,7 @@ static struct config_int ConfigureNamesInt[] = { {"wal_skip_threshold", PGC_USERSET, WAL_SETTINGS, - gettext_noop("Size of new file to fsync instead of writing WAL."), + gettext_noop("Minimum size of new file to fsync instead of writing WAL."), NULL, GUC_UNIT_KB }, @@ -2893,7 +3011,7 @@ static struct config_int ConfigureNamesInt[] = gettext_noop("Sets the minimum execution time above which " "a sample of statements will be logged." " Sampling is determined by log_statement_sample_rate."), - gettext_noop("Zero log a sample of all queries. -1 turns this feature off."), + gettext_noop("Zero logs a sample of all queries. -1 turns this feature off."), GUC_UNIT_MS }, &log_min_duration_sample, @@ -2985,7 +3103,7 @@ static struct config_int ConfigureNamesInt[] = PGC_USERSET, RESOURCES_ASYNCHRONOUS, gettext_noop("Number of simultaneous requests that can be handled efficiently by the disk subsystem."), - gettext_noop("For RAID arrays, this should be approximately the number of drive spindles in the array."), + NULL, GUC_EXPLAIN }, &effective_io_concurrency, @@ -3198,7 +3316,7 @@ static struct config_int ConfigureNamesInt[] = }, { {"autovacuum_vacuum_insert_threshold", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums"), + gettext_noop("Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums."), NULL }, &autovacuum_vac_ins_thresh, @@ -3222,7 +3340,11 @@ static struct config_int ConfigureNamesInt[] = GUC_NOT_IN_SAMPLE | GUC_NO_SHOW_ALL }, &autovacuum_freeze_max_age, - /* see pg_resetwal if you change the upper-limit value */ + + /* + * see pg_resetwal and vacuum_failsafe_age if you change the + * upper-limit value. + */ 200000000, 100000, 2000000000, NULL, NULL, NULL }, @@ -3302,7 +3424,7 @@ static struct config_int ConfigureNamesInt[] = }, { - {"tcp_keepalives_idle", PGC_USERSET, CLIENT_CONN_OTHER, + {"tcp_keepalives_idle", PGC_USERSET, CONN_AUTH_SETTINGS, gettext_noop("Time between issuing TCP keepalives."), gettext_noop("A value of 0 uses the system default."), GUC_UNIT_S @@ -3313,7 +3435,7 @@ static struct config_int ConfigureNamesInt[] = }, { - {"tcp_keepalives_interval", PGC_USERSET, CLIENT_CONN_OTHER, + {"tcp_keepalives_interval", PGC_USERSET, CONN_AUTH_SETTINGS, gettext_noop("Time between TCP keepalive retransmits."), gettext_noop("A value of 0 uses the system default."), GUC_UNIT_S @@ -3335,7 +3457,7 @@ static struct config_int ConfigureNamesInt[] = }, { - {"tcp_keepalives_count", PGC_USERSET, CLIENT_CONN_OTHER, + {"tcp_keepalives_count", PGC_USERSET, CONN_AUTH_SETTINGS, gettext_noop("Maximum number of TCP keepalive retransmits."), gettext_noop("This controls the number of consecutive keepalive retransmits that can be " "lost before a connection is considered dead. A value of 0 uses the " @@ -3414,7 +3536,7 @@ static struct config_int ConfigureNamesInt[] = }, { - {"track_activity_query_size", PGC_POSTMASTER, RESOURCES_MEM, + {"track_activity_query_size", PGC_POSTMASTER, STATS_COLLECTOR, gettext_noop("Sets the size reserved for pg_stat_activity.query, in bytes."), NULL, GUC_UNIT_BYTE @@ -3436,7 +3558,7 @@ static struct config_int ConfigureNamesInt[] = }, { - {"tcp_user_timeout", PGC_USERSET, CLIENT_CONN_OTHER, + {"tcp_user_timeout", PGC_USERSET, CONN_AUTH_SETTINGS, gettext_noop("TCP user timeout."), gettext_noop("A value of 0 uses the system default."), GUC_UNIT_MS @@ -3468,6 +3590,29 @@ static struct config_int ConfigureNamesInt[] = check_huge_page_size, NULL, NULL }, + { + {"debug_invalidate_system_caches_always", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Aggressively invalidate system caches for debugging purposes."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &debug_invalidate_system_caches_always, +#ifdef CLOBBER_CACHE_ENABLED + /* Set default based on older compile-time-only cache clobber macros */ +#if defined(CLOBBER_CACHE_RECURSIVELY) + 3, +#elif defined(CLOBBER_CACHE_ALWAYS) + 1, +#else + 0, +#endif + 0, 5, +#else /* not CLOBBER_CACHE_ENABLED */ + 0, 0, 0, +#endif /* not CLOBBER_CACHE_ENABLED */ + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL @@ -3568,7 +3713,7 @@ static struct config_real ConfigureNamesReal[] = { {"jit_optimize_above_cost", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Optimize JITed functions if query is more expensive."), + gettext_noop("Optimize JIT-compiled functions if query is more expensive."), gettext_noop("-1 disables optimization."), GUC_EXPLAIN }, @@ -3712,17 +3857,7 @@ static struct config_real ConfigureNamesReal[] = NULL }, &CheckPointCompletionTarget, - 0.5, 0.0, 1.0, - NULL, NULL, NULL - }, - - { - {"vacuum_cleanup_index_scale_factor", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Number of tuple inserts prior to index cleanup as a fraction of reltuples."), - NULL - }, - &vacuum_cleanup_index_scale_factor, - 0.1, 0.0, 1e10, + 0.9, 0.0, 1.0, NULL, NULL, NULL }, @@ -3738,9 +3873,8 @@ static struct config_real ConfigureNamesReal[] = { {"log_transaction_sample_rate", PGC_SUSET, LOGGING_WHEN, - gettext_noop("Set the fraction of transactions to log for new transactions."), - gettext_noop("Logs all statements from a fraction of transactions. " - "Use a value between 0.0 (never log) and 1.0 (log all " + gettext_noop("Sets the fraction of transactions from which to log all statements."), + gettext_noop("Use a value between 0.0 (never log) and 1.0 (log all " "statements for all transactions).") }, &log_xact_sample_rate, @@ -3769,8 +3903,8 @@ static struct config_string ConfigureNamesString[] = }, { - {"restore_command", PGC_POSTMASTER, WAL_ARCHIVE_RECOVERY, - gettext_noop("Sets the shell command that will retrieve an archived WAL file."), + {"restore_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, + gettext_noop("Sets the shell command that will be called to retrieve an archived WAL file."), NULL }, &recoveryRestoreCommand, @@ -4000,7 +4134,7 @@ static struct config_string ConfigureNamesString[] = /* See main.c about why defaults for LC_foo are not all alike */ { - {"lc_collate", PGC_INTERNAL, CLIENT_CONN_LOCALE, + {"lc_collate", PGC_INTERNAL, PRESET_OPTIONS, gettext_noop("Shows the collation order locale."), NULL, GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE @@ -4011,7 +4145,7 @@ static struct config_string ConfigureNamesString[] = }, { - {"lc_ctype", PGC_INTERNAL, CLIENT_CONN_LOCALE, + {"lc_ctype", PGC_INTERNAL, PRESET_OPTIONS, gettext_noop("Shows the character classification and case conversion locale."), NULL, GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE @@ -4107,8 +4241,8 @@ static struct config_string ConfigureNamesString[] = { /* Can't be set in postgresql.conf */ - {"server_encoding", PGC_INTERNAL, CLIENT_CONN_LOCALE, - gettext_noop("Sets the server (database) character set encoding."), + {"server_encoding", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Shows the server (database) character set encoding."), NULL, GUC_IS_NAME | GUC_REPORT | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE }, @@ -4245,7 +4379,7 @@ static struct config_string ConfigureNamesString[] = {"unix_socket_directories", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the directories where Unix-domain sockets will be created."), NULL, - GUC_SUPERUSER_ONLY + GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_SUPERUSER_ONLY }, &Unix_socket_directories, #ifdef HAVE_UNIX_SOCKETS @@ -4328,7 +4462,7 @@ static struct config_string ConfigureNamesString[] = { {"ssl_library", PGC_INTERNAL, PRESET_OPTIONS, - gettext_noop("Name of the SSL library."), + gettext_noop("Shows the name of the SSL library."), NULL, GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE }, @@ -4381,6 +4515,16 @@ static struct config_string ConfigureNamesString[] = NULL, NULL, NULL }, + { + {"ssl_crl_dir", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Location of the SSL certificate revocation list directory."), + NULL + }, + &ssl_crl_dir, + "", + NULL, NULL, NULL + }, + { {"stats_temp_directory", PGC_SIGHUP, STATS_COLLECTOR, gettext_noop("Writes temporary statistics files to the specified directory."), @@ -4560,6 +4704,16 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"compute_query_id", PGC_SUSET, STATS_MONITORING, + gettext_noop("Compute query identifiers."), + NULL + }, + &compute_query_id, + COMPUTE_QUERY_ID_AUTO, compute_query_id_options, + NULL, NULL, NULL + }, + { {"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER, gettext_noop("Enables the planner to use constraints to optimize queries."), @@ -4584,6 +4738,17 @@ static struct config_enum ConfigureNamesEnum[] = * reason why assign hook function method didn't work in * past. Use the check hook to change 'newval'. */ + {"default_toast_compression", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default compression method for compressible values."), + NULL + }, + &default_toast_compression, + TOAST_PGLZ_COMPRESSION, + default_toast_compression_options, + NULL, NULL, NULL + }, + + { {"default_transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Sets the transaction isolation level of each new transaction."), NULL @@ -4742,7 +4907,7 @@ static struct config_enum ConfigureNamesEnum[] = { {"wal_level", PGC_POSTMASTER, WAL_SETTINGS, - gettext_noop("Set the level of information written to the WAL."), + gettext_noop("Sets the level of information written to the WAL."), NULL }, &wal_level, @@ -4813,10 +4978,10 @@ static struct config_enum ConfigureNamesEnum[] = }, { - {"force_parallel_mode", PGC_USERSET, QUERY_TUNING_OTHER, + {"force_parallel_mode", PGC_USERSET, DEVELOPER_OPTIONS, gettext_noop("Forces use of parallel query facilities."), gettext_noop("If possible, run query using a parallel worker and with parallel restrictions."), - GUC_EXPLAIN + GUC_NOT_IN_SAMPLE | GUC_EXPLAIN }, &force_parallel_mode, FORCE_PARALLEL_OFF, force_parallel_mode_options, @@ -4870,6 +5035,15 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"recovery_init_sync_method", PGC_SIGHUP, ERROR_HANDLING_OPTIONS, + gettext_noop("Sets the method for synchronizing the data directory before crash recovery."), + }, + &recovery_init_sync_method, + RECOVERY_INIT_SYNC_METHOD_FSYNC, recovery_init_sync_method_options, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL @@ -4908,6 +5082,8 @@ static bool guc_dirty; /* true if need to do commit/abort work */ static bool reporting_enabled; /* true to enable GUC_REPORT */ +static bool report_needed; /* true if any GUC_REPORT reports are needed */ + static int GUCNestLevel = 0; /* 1 when in main transaction */ @@ -5189,15 +5365,14 @@ gp_guc_list_init(void) switch (gconf->group) { - case QUERY_TUNING: - case QUERY_TUNING_COST: - case QUERY_TUNING_OTHER: + case QUERY_TUNING_METHOD: explain = true; + no_plan = true; break; - case QUERY_TUNING_METHOD: + case QUERY_TUNING_COST: + case QUERY_TUNING_OTHER: explain = true; - no_plan = true; break; case RESOURCES_MEM: @@ -5407,6 +5582,46 @@ add_guc_variable(struct config_generic *var, int elevel) return true; } +/* + * Decide whether a proposed custom variable name is allowed. + * + * It must be two or more identifiers separated by dots, where the rules + * for what is an identifier agree with scan.l. (If you change this rule, + * adjust the errdetail in find_option().) + */ +static bool +valid_custom_variable_name(const char *name) +{ + bool saw_sep = false; + bool name_start = true; + + for (const char *p = name; *p; p++) + { + if (*p == GUC_QUALIFIER_SEPARATOR) + { + if (name_start) + return false; /* empty name component */ + saw_sep = true; + name_start = true; + } + else if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz", *p) != NULL || + IS_HIGHBIT_SET(*p)) + { + /* okay as first or non-first character */ + name_start = false; + } + else if (!name_start && strchr("0123456789_$", *p) != NULL) + /* okay as non-first character */ ; + else + return false; + } + if (name_start) + return false; /* empty name component */ + /* OK if we found at least one separator */ + return saw_sep; +} + /* * Create and add a placeholder variable for a custom variable name. */ @@ -5454,12 +5669,23 @@ add_placeholder_variable(const char *name, int elevel) } /* - * Look up option NAME. If it exists, return a pointer to its record, - * else return NULL. If create_placeholders is true, we'll create a - * placeholder record for a valid-looking custom variable name. + * Look up option "name". If it exists, return a pointer to its record. + * Otherwise, if create_placeholders is true and name is a valid-looking + * custom variable name, we'll create and return a placeholder record. + * Otherwise, if skip_errors is true, then we silently return NULL for + * an unrecognized or invalid name. Otherwise, the error is reported at + * error level elevel (and we return NULL if that's less than ERROR). + * + * Note: internal errors, primarily out-of-memory, draw an elevel-level + * report and NULL return regardless of skip_errors. Hence, callers must + * handle a NULL return whenever elevel < ERROR, but they should not need + * to emit any additional error message. (In practice, internal errors + * can only happen when create_placeholders is true, so callers passing + * false need not think terribly hard about this.) */ struct config_generic * -find_option(const char *name, bool create_placeholders, int elevel) +find_option(const char *name, bool create_placeholders, bool skip_errors, + int elevel) { const char **key = &name; struct config_generic **res; @@ -5487,19 +5713,38 @@ find_option(const char *name, bool create_placeholders, int elevel) for (i = 0; map_old_guc_names[i] != NULL; i += 2) { if (guc_name_compare(name, map_old_guc_names[i]) == 0) - return find_option(map_old_guc_names[i + 1], false, elevel); + return find_option(map_old_guc_names[i + 1], false, + skip_errors, elevel); } if (create_placeholders) { /* - * Check if the name is qualified, and if so, add a placeholder. + * Check if the name is valid, and if so, add a placeholder. If it + * doesn't contain a separator, don't assume that it was meant to be a + * placeholder. */ if (strchr(name, GUC_QUALIFIER_SEPARATOR) != NULL) - return add_placeholder_variable(name, elevel); + { + if (valid_custom_variable_name(name)) + return add_placeholder_variable(name, elevel); + /* A special error message seems desirable here */ + if (!skip_errors) + ereport(elevel, + (errcode(ERRCODE_INVALID_NAME), + errmsg("invalid configuration parameter name \"%s\"", + name), + errdetail("Custom parameter names must be two or more simple identifiers separated by dots."))); + return NULL; + } } /* Unknown name */ + if (!skip_errors) + ereport(elevel, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("unrecognized configuration parameter \"%s\"", + name))); return NULL; } @@ -5665,6 +5910,7 @@ InitializeOneGUCOption(struct config_generic *gconf) gconf->reset_scontext = PGC_INTERNAL; gconf->stack = NULL; gconf->extra = NULL; + gconf->last_reported = NULL; gconf->sourcefile = NULL; gconf->sourceline = 0; @@ -6041,7 +6287,10 @@ ResetAllOptions(void) gconf->scontext = gconf->reset_scontext; if (gconf->flags & GUC_REPORT) - ReportGUCOption(gconf); + { + gconf->status |= GUC_NEEDS_REPORT; + report_needed = true; + } } } @@ -6428,7 +6677,10 @@ AtEOXact_GUC(bool isCommit, int nestLevel) /* Report new value if we changed it */ if (changed && (gconf->flags & GUC_REPORT)) - ReportGUCOption(gconf); + { + gconf->status |= GUC_NEEDS_REPORT; + report_needed = true; + } /* * If a guc's value changed on QD, @@ -6471,15 +6723,21 @@ BeginReportingGUCOptions(void) gp_guc_list_init(); /* - * Don't do anything unless talking to an interactive frontend of protocol - * 3.0 or later. + * Don't do anything unless talking to an interactive frontend. */ - if (whereToSendOutput != DestRemote || - PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) + if (whereToSendOutput != DestRemote) return; reporting_enabled = true; + /* + * Hack for in_hot_standby: initialize with the value we're about to send. + * (This could be out of date by the time we actually send it, in which + * case the next ReportChangedGUCOptions call will send a duplicate + * report.) + */ + in_hot_standby = RecoveryInProgress(); + /* Transmit initial values of interesting variables */ for (i = 0; i < num_guc_variables; i++) { @@ -6488,17 +6746,77 @@ BeginReportingGUCOptions(void) if (conf->flags & GUC_REPORT) ReportGUCOption(conf); } + + report_needed = false; +} + +/* + * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables + * + * This is called just before we wait for a new client query. + * + * By handling things this way, we ensure that a ParameterStatus message + * is sent at most once per variable per query, even if the variable + * changed multiple times within the query. That's quite possible when + * using features such as function SET clauses. Function SET clauses + * also tend to cause values to change intraquery but eventually revert + * to their prevailing values; ReportGUCOption is responsible for avoiding + * redundant reports in such cases. + */ +void +ReportChangedGUCOptions(void) +{ + /* Quick exit if not (yet) enabled */ + if (!reporting_enabled) + return; + + /* + * Since in_hot_standby isn't actually changed by normal GUC actions, we + * need a hack to check whether a new value needs to be reported to the + * client. For speed, we rely on the assumption that it can never + * transition from false to true. + */ + if (in_hot_standby && !RecoveryInProgress()) + { + struct config_generic *record; + + record = find_option("in_hot_standby", false, false, ERROR); + Assert(record != NULL); + record->status |= GUC_NEEDS_REPORT; + report_needed = true; + in_hot_standby = false; + } + + /* Quick exit if no values have been changed */ + if (!report_needed) + return; + + /* Transmit new values of interesting variables */ + for (int i = 0; i < num_guc_variables; i++) + { + struct config_generic *conf = guc_variables[i]; + + if ((conf->flags & GUC_REPORT) && (conf->status & GUC_NEEDS_REPORT)) + ReportGUCOption(conf); + } + + report_needed = false; } /* * ReportGUCOption: if appropriate, transmit option value to frontend + * + * We need not transmit the value if it's the same as what we last + * transmitted. However, clear the NEEDS_REPORT flag in any case. */ static void ReportGUCOption(struct config_generic *record) { - if (reporting_enabled && (record->flags & GUC_REPORT)) + char *val = _ShowOption(record, false); + + if (record->last_reported == NULL || + strcmp(val, record->last_reported) != 0) { - char *val = _ShowOption(record, false); StringInfoData msgbuf; pq_beginmessage(&msgbuf, 'S'); @@ -6506,8 +6824,19 @@ ReportGUCOption(struct config_generic *record) pq_sendstring(&msgbuf, val); pq_endmessage(&msgbuf); - pfree(val); + /* + * We need a long-lifespan copy. If strdup() fails due to OOM, we'll + * set last_reported to NULL and thereby possibly make a duplicate + * report later. + */ + if (record->last_reported) + free(record->last_reported); + record->last_reported = strdup(val); } + + pfree(val); + + record->status &= ~GUC_NEEDS_REPORT; } /* @@ -7162,6 +7491,10 @@ parse_and_validate_value(struct config_generic *record, * its standard choice of ereport level. However some callers need to be * able to override that choice; they should pass the ereport level to use. * + * is_reload should be true only when called from read_nondefault_variables() + * or RestoreGUCState(), where we are trying to load some other process's + * GUC settings into a new process. + * * Return value: * +1: the value is valid and was successfully applied. * 0: the name or value is invalid (but see below). @@ -7221,14 +7554,9 @@ set_config_option(const char *name, const char *value, (errcode(ERRCODE_INVALID_TRANSACTION_STATE), errmsg("cannot set parameters during a parallel operation"))); - record = find_option(name, true, elevel); + record = find_option(name, true, false, elevel); if (record == NULL) - { - ereport(elevel, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", name))); return 0; - } /* * Check if option can be set by the user. @@ -7484,6 +7812,10 @@ set_config_option(const char *name, const char *value, if (prohibitValueChange) { + /* Release newextra, unless it's reset_extra */ + if (newextra && !extra_field_used(&conf->gen, newextra)) + free(newextra); + if (*conf->variable != newval) { record->status |= GUC_PENDING_RESTART; @@ -7574,6 +7906,10 @@ set_config_option(const char *name, const char *value, if (prohibitValueChange) { + /* Release newextra, unless it's reset_extra */ + if (newextra && !extra_field_used(&conf->gen, newextra)) + free(newextra); + if (*conf->variable != newval) { record->status |= GUC_PENDING_RESTART; @@ -7664,6 +8000,10 @@ set_config_option(const char *name, const char *value, if (prohibitValueChange) { + /* Release newextra, unless it's reset_extra */ + if (newextra && !extra_field_used(&conf->gen, newextra)) + free(newextra); + if (*conf->variable != newval) { record->status |= GUC_PENDING_RESTART; @@ -7770,9 +8110,21 @@ set_config_option(const char *name, const char *value, if (prohibitValueChange) { + bool newval_different; + /* newval shouldn't be NULL, so we're a bit sloppy here */ - if (*conf->variable == NULL || newval == NULL || - strcmp(*conf->variable, newval) != 0) + newval_different = (*conf->variable == NULL || + newval == NULL || + strcmp(*conf->variable, newval) != 0); + + /* Release newval, unless it's reset_val */ + if (newval && !string_field_used(conf, newval)) + free(newval); + /* Release newextra, unless it's reset_extra */ + if (newextra && !extra_field_used(&conf->gen, newextra)) + free(newextra); + + if (newval_different) { record->status |= GUC_PENDING_RESTART; ereport(elevel, @@ -7867,6 +8219,10 @@ set_config_option(const char *name, const char *value, if (prohibitValueChange) { + /* Release newextra, unless it's reset_extra */ + if (newextra && !extra_field_used(&conf->gen, newextra)) + free(newextra); + if (*conf->variable != newval) { record->status |= GUC_PENDING_RESTART; @@ -7929,7 +8285,10 @@ set_config_option(const char *name, const char *value, } if (changeVal && (record->flags & GUC_REPORT)) - ReportGUCOption(record); + { + record->status |= GUC_NEEDS_REPORT; + report_needed = true; + } return changeVal ? 1 : -1; } @@ -7950,10 +8309,10 @@ set_config_sourcefile(const char *name, char *sourcefile, int sourceline) */ elevel = IsUnderPostmaster ? DEBUG3 : LOG; - record = find_option(name, true, elevel); + record = find_option(name, true, false, elevel); /* should not happen */ if (record == NULL) - elog(ERROR, "unrecognized configuration parameter \"%s\"", name); + return; sourcefile = guc_strdup(elevel, sourcefile); if (record->sourcefile) @@ -8002,19 +8361,12 @@ GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged) struct config_generic *record; static char buffer[256]; - record = find_option(name, false, ERROR); + record = find_option(name, false, missing_ok, ERROR); if (record == NULL) - { - if (missing_ok) - return NULL; - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", - name))); - } + return NULL; if (restrict_privileged && (record->flags & GUC_SUPERUSER_ONLY) && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS)) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or a member of pg_read_all_settings to examine \"%s\"", @@ -8058,13 +8410,10 @@ GetConfigOptionResetString(const char *name) struct config_generic *record; static char buffer[256]; - record = find_option(name, false, ERROR); - if (record == NULL) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", name))); + record = find_option(name, false, false, ERROR); + Assert(record != NULL); if ((record->flags & GUC_SUPERUSER_ONLY) && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS)) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or a member of pg_read_all_settings to examine \"%s\"", @@ -8106,16 +8455,9 @@ GetConfigOptionFlags(const char *name, bool missing_ok) { struct config_generic *record; - record = find_option(name, false, WARNING); + record = find_option(name, false, missing_ok, ERROR); if (record == NULL) - { - if (missing_ok) - return 0; - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", - name))); - } + return 0; return record->flags; } @@ -8147,7 +8489,7 @@ flatten_set_variable_args(const char *name, List *args) * Get flags for the variable; if it's not known, use default flags. * (Caller might throw error later, but not our business to do so here.) */ - record = find_option(name, false, WARNING); + record = find_option(name, false, true, WARNING); if (record) flags = record->flags; else @@ -8442,11 +8784,8 @@ AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt) { struct config_generic *record; - record = find_option(name, false, ERROR); - if (record == NULL) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", name))); + record = find_option(name, false, false, ERROR); + Assert(record != NULL); /* * Don't allow parameters that can't be set in configuration files to @@ -9485,7 +9824,7 @@ ShowAllGUCConfig(DestReceiver *dest) if ((conf->flags & GUC_NO_SHOW_ALL) || ((conf->flags & GUC_SUPERUSER_ONLY) && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS))) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))) continue; /* assign to the values array */ @@ -9605,7 +9944,7 @@ get_explain_guc_options(int *num) /* return only options visible to the current user */ if ((conf->flags & GUC_NO_SHOW_ALL) || ((conf->flags & GUC_SUPERUSER_ONLY) && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS))) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))) continue; /* skip GUC variables that match the built-in default */ @@ -9630,23 +9969,16 @@ GetConfigOptionByName(const char *name, const char **varname, bool missing_ok) { struct config_generic *record; - record = find_option(name, false, ERROR); + record = find_option(name, false, missing_ok, ERROR); if (record == NULL) { - if (missing_ok) - { - if (varname) - *varname = NULL; - return NULL; - } - - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", name))); + if (varname) + *varname = NULL; + return NULL; } if ((record->flags & GUC_SUPERUSER_ONLY) && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS)) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or a member of pg_read_all_settings to examine \"%s\"", @@ -9677,7 +10009,7 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow) { if ((conf->flags & GUC_NO_SHOW_ALL) || ((conf->flags & GUC_SUPERUSER_ONLY) && - !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS))) + !is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS))) *noshow = true; else *noshow = false; @@ -9872,7 +10204,7 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow) * insufficiently-privileged users. */ if (conf->source == PGC_S_FILE && - is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS)) + is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_SETTINGS)) { values[14] = conf->sourcefile; snprintf(buffer, sizeof(buffer), "%d", conf->sourceline); @@ -10466,12 +10798,6 @@ read_nondefault_variables(void) GucSource varsource; GucContext varscontext; - /* - * Assert that PGC_BACKEND/PGC_SU_BACKEND case in set_config_option() will - * do the right thing. - */ - Assert(IsInitProcessingMode()); - /* * Open file */ @@ -10494,7 +10820,7 @@ read_nondefault_variables(void) if ((varname = read_string_with_null(fp)) == NULL) break; - if ((record = find_option(varname, true, FATAL)) == NULL) + if ((record = find_option(varname, true, false, FATAL)) == NULL) elog(FATAL, "failed to locate variable \"%s\" in exec config params file", varname); if ((varvalue = read_string_with_null(fp)) == NULL) @@ -10525,30 +10851,43 @@ read_nondefault_variables(void) /* * can_skip_gucvar: - * When serializing, determine whether to skip this GUC. When restoring, the - * negation of this test determines whether to restore the compiled-in default - * value before processing serialized values. - * - * A PGC_S_DEFAULT setting on the serialize side will typically match new - * postmaster children, but that can be false when got_SIGHUP == true and the - * pending configuration change modifies this setting. Nonetheless, we omit - * PGC_S_DEFAULT settings from serialization and make up for that by restoring - * defaults before applying serialized values. - * - * PGC_POSTMASTER variables always have the same value in every child of a - * particular postmaster. Most PGC_INTERNAL variables are compile-time - * constants; a few, like server_encoding and lc_ctype, are handled specially - * outside the serialize/restore procedure. Therefore, SerializeGUCState() - * never sends these, and RestoreGUCState() never changes them. + * Decide whether SerializeGUCState can skip sending this GUC variable, + * or whether RestoreGUCState can skip resetting this GUC to default. * - * Role is a special variable in the sense that its current value can be an - * invalid value and there are multiple ways by which that can happen (like - * after setting the role, someone drops it). So we handle it outside of - * serialize/restore machinery. + * It is somewhat magical and fragile that the same test works for both cases. + * Realize in particular that we are very likely selecting different sets of + * GUCs on the leader and worker sides! Be sure you've understood the + * comments here and in RestoreGUCState thoroughly before changing this. */ static bool can_skip_gucvar(struct config_generic *gconf) { + /* + * We can skip GUCs that are guaranteed to have the same values in leaders + * and workers. (Note it is critical that the leader and worker have the + * same idea of which GUCs fall into this category. It's okay to consider + * context and name for this purpose, since those are unchanging + * properties of a GUC.) + * + * PGC_POSTMASTER variables always have the same value in every child of a + * particular postmaster, so the worker will certainly have the right + * value already. Likewise, PGC_INTERNAL variables are set by special + * mechanisms (if indeed they aren't compile-time constants). So we may + * always skip these. + * + * Role must be handled specially because its current value can be an + * invalid value (for instance, if someone dropped the role since we set + * it). So if we tried to serialize it normally, we might get a failure. + * We skip it here, and use another mechanism to ensure the worker has the + * right value. + * + * For all other GUCs, we skip if the GUC has its compiled-in default + * value (i.e., source == PGC_S_DEFAULT). On the leader side, this means + * we don't send GUCs that have their default values, which typically + * saves lots of work. On the worker side, this means we don't need to + * reset the GUC to default because it already has that value. See + * comments in RestoreGUCState for more info. + */ return gconf->context == PGC_POSTMASTER || gconf->context == PGC_INTERNAL || gconf->source == PGC_S_DEFAULT || strcmp(gconf->name, "role") == 0; @@ -10566,6 +10905,7 @@ estimate_variable_size(struct config_generic *gconf) Size size; Size valsize = 0; + /* Skippable GUCs consume zero space. */ if (can_skip_gucvar(gconf)) return 0; @@ -10730,6 +11070,7 @@ static void serialize_variable(char **destptr, Size *maxbytes, struct config_generic *gconf) { + /* Ignore skippable GUCs. */ if (can_skip_gucvar(gconf)) return; @@ -10877,8 +11218,14 @@ guc_restore_error_context_callback(void *arg) /* * RestoreGUCState: - * Reads the GUC state at the specified address and updates the GUCs with the - * values read from the GUC state. + * Reads the GUC state at the specified address and sets this process's + * GUCs to match. + * + * Note that this provides the worker with only a very shallow view of the + * leader's GUC state: we'll know about the currently active values, but not + * about stacked or reset values. That's fine since the worker is just + * executing one part of a query, within which the active values won't change + * and the stacked values are invisible. */ void RestoreGUCState(void *gucstate) @@ -10895,10 +11242,100 @@ RestoreGUCState(void *gucstate) int i; ErrorContextCallback error_context_callback; - /* See comment at can_skip_gucvar(). */ + /* + * First, ensure that all potentially-shippable GUCs are reset to their + * default values. We must not touch those GUCs that the leader will + * never ship, while there is no need to touch those that are shippable + * but already have their default values. Thus, this ends up being the + * same test that SerializeGUCState uses, even though the sets of + * variables involved may well be different since the leader's set of + * variables-not-at-default-values can differ from the set that are + * not-default in this freshly started worker. + * + * Once we have set all the potentially-shippable GUCs to default values, + * restoring the GUCs that the leader sent (because they had non-default + * values over there) leads us to exactly the set of GUC values that the + * leader has. This is true even though the worker may have initially + * absorbed postgresql.conf settings that the leader hasn't yet seen, or + * ALTER USER/DATABASE SET settings that were established after the leader + * started. + * + * Note that ensuring all the potential target GUCs are at PGC_S_DEFAULT + * also ensures that set_config_option won't refuse to set them because of + * source-priority comparisons. + */ for (i = 0; i < num_guc_variables; i++) - if (!can_skip_gucvar(guc_variables[i])) - InitializeOneGUCOption(guc_variables[i]); + { + struct config_generic *gconf = guc_variables[i]; + + /* Do nothing if non-shippable or if already at PGC_S_DEFAULT. */ + if (can_skip_gucvar(gconf)) + continue; + + /* + * We can use InitializeOneGUCOption to reset the GUC to default, but + * first we must free any existing subsidiary data to avoid leaking + * memory. The stack must be empty, but we have to clean up all other + * fields. Beware that there might be duplicate value or "extra" + * pointers. + */ + Assert(gconf->stack == NULL); + if (gconf->extra) + free(gconf->extra); + if (gconf->last_reported) /* probably can't happen */ + free(gconf->last_reported); + if (gconf->sourcefile) + free(gconf->sourcefile); + switch (gconf->vartype) + { + case PGC_BOOL: + { + struct config_bool *conf = (struct config_bool *) gconf; + + if (conf->reset_extra && conf->reset_extra != gconf->extra) + free(conf->reset_extra); + break; + } + case PGC_INT: + { + struct config_int *conf = (struct config_int *) gconf; + + if (conf->reset_extra && conf->reset_extra != gconf->extra) + free(conf->reset_extra); + break; + } + case PGC_REAL: + { + struct config_real *conf = (struct config_real *) gconf; + + if (conf->reset_extra && conf->reset_extra != gconf->extra) + free(conf->reset_extra); + break; + } + case PGC_STRING: + { + struct config_string *conf = (struct config_string *) gconf; + + if (*conf->variable) + free(*conf->variable); + if (conf->reset_val && conf->reset_val != *conf->variable) + free(conf->reset_val); + if (conf->reset_extra && conf->reset_extra != gconf->extra) + free(conf->reset_extra); + break; + } + case PGC_ENUM: + { + struct config_enum *conf = (struct config_enum *) gconf; + + if (conf->reset_extra && conf->reset_extra != gconf->extra) + free(conf->reset_extra); + break; + } + } + /* Now we can reset the struct to PGS_S_DEFAULT state. */ + InitializeOneGUCOption(gconf); + } /* First item is the length of the subsequent data */ memcpy(&len, gucstate, sizeof(len)); @@ -10912,6 +11349,7 @@ RestoreGUCState(void *gucstate) error_context_callback.arg = NULL; error_context_stack = &error_context_callback; + /* Restore all the listed GUCs. */ while (srcptr < srcend) { int result; @@ -11010,6 +11448,8 @@ ProcessGUCArray(ArrayType *array, char *s; char *name; char *value; + char *namecopy; + char *valuecopy; d = array_ref(array, 1, &i, -1 /* varlenarray */ , @@ -11034,13 +11474,18 @@ ProcessGUCArray(ArrayType *array, continue; } - (void) set_config_option(name, value, + /* free malloc'd strings immediately to avoid leak upon error */ + namecopy = pstrdup(name); + free(name); + valuecopy = pstrdup(value); + free(value); + + (void) set_config_option(namecopy, valuecopy, context, source, action, true, 0, false); - free(name); - if (value) - free(value); + pfree(namecopy); + pfree(valuecopy); pfree(s); } } @@ -11065,7 +11510,7 @@ GUCArrayAdd(ArrayType *array, const char *name, const char *value) (void) validate_option_array_item(name, value, false); /* normalize name (converts obsolete GUC names to modern spellings) */ - record = find_option(name, false, WARNING); + record = find_option(name, false, true, WARNING); if (record) name = record->name; @@ -11144,7 +11589,7 @@ GUCArrayDelete(ArrayType *array, const char *name) (void) validate_option_array_item(name, NULL, false); /* normalize name (converts obsolete GUC names to modern spellings) */ - record = find_option(name, false, WARNING); + record = find_option(name, false, true, WARNING); if (record) name = record->name; @@ -11291,7 +11736,7 @@ validate_option_array_item(const char *name, const char *value, * SUSET and user is superuser). * * name is not known, but exists or can be created as a placeholder (i.e., - * it has a prefixed name). We allow this case if you're a superuser, + * it has a valid custom name). We allow this case if you're a superuser, * otherwise not. Superusers are assumed to know what they're doing. We * can't allow it for other users, because when the placeholder is * resolved it might turn out to be a SUSET variable; @@ -11300,16 +11745,11 @@ validate_option_array_item(const char *name, const char *value, * name is not known and can't be created as a placeholder. Throw error, * unless skipIfNoPermissions is true, in which case return false. */ - gconf = find_option(name, true, WARNING); + gconf = find_option(name, true, skipIfNoPermissions, ERROR); if (!gconf) { /* not known, failed to make a placeholder */ - if (skipIfNoPermissions) - return false; - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("unrecognized configuration parameter \"%s\"", - name))); + return false; } if (gconf->flags & GUC_CUSTOM_PLACEHOLDER) @@ -11472,34 +11912,50 @@ static bool call_string_check_hook(struct config_string *conf, char **newval, void **extra, GucSource source, int elevel) { + volatile bool result = true; + /* Quick success if no hook */ if (!conf->check_hook) return true; - /* Reset variables that might be set by hook */ - GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE; - GUC_check_errmsg_string = NULL; - GUC_check_errdetail_string = NULL; - GUC_check_errhint_string = NULL; + /* + * If elevel is ERROR, or if the check_hook itself throws an elog + * (undesirable, but not always avoidable), make sure we don't leak the + * already-malloc'd newval string. + */ + PG_TRY(); + { + /* Reset variables that might be set by hook */ + GUC_check_errcode_value = ERRCODE_INVALID_PARAMETER_VALUE; + GUC_check_errmsg_string = NULL; + GUC_check_errdetail_string = NULL; + GUC_check_errhint_string = NULL; - if (!conf->check_hook(newval, extra, source)) + if (!conf->check_hook(newval, extra, source)) + { + ereport(elevel, + (errcode(GUC_check_errcode_value), + GUC_check_errmsg_string ? + errmsg_internal("%s", GUC_check_errmsg_string) : + errmsg("invalid value for parameter \"%s\": \"%s\"", + conf->gen.name, *newval ? *newval : ""), + GUC_check_errdetail_string ? + errdetail_internal("%s", GUC_check_errdetail_string) : 0, + GUC_check_errhint_string ? + errhint("%s", GUC_check_errhint_string) : 0)); + /* Flush any strings created in ErrorContext */ + FlushErrorState(); + result = false; + } + } + PG_CATCH(); { - ereport(elevel, - (errcode(GUC_check_errcode_value), - GUC_check_errmsg_string ? - errmsg_internal("%s", GUC_check_errmsg_string) : - errmsg("invalid value for parameter \"%s\": \"%s\"", - conf->gen.name, *newval ? *newval : ""), - GUC_check_errdetail_string ? - errdetail_internal("%s", GUC_check_errdetail_string) : 0, - GUC_check_errhint_string ? - errhint("%s", GUC_check_errhint_string) : 0)); - /* Flush any strings created in ErrorContext */ - FlushErrorState(); - return false; + free(*newval); + PG_RE_THROW(); } + PG_END_TRY(); - return true; + return result; } static bool @@ -11721,8 +12177,9 @@ check_temp_buffers(int *newval, void **extra, GucSource source) { /* * Once local buffers have been initialized, it's too late to change this. + * However, if this is only a test call, allow it. */ - if (NLocBuffer && NLocBuffer != *newval) + if (source != PGC_S_TEST && NLocBuffer && NLocBuffer != *newval) { GUC_check_errdetail("\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session."); return false; @@ -11869,7 +12326,7 @@ assign_tcp_keepalives_idle(int newval, void *extra) * once we set it we might fail to unset it. So there seems little point * in fully implementing the check-then-assign GUC API for these * variables. Instead we just do the assignment on demand. pqcomm.c - * reports any problems via elog(LOG). + * reports any problems via ereport(LOG). * * This approach means that the GUC value might have little to do with the * actual kernel value, so we use a show_hook that retrieves the kernel @@ -12039,7 +12496,7 @@ check_client_connection_check_interval(int *newval, void **extra, GucSource sour /* Linux and OSX only, for now. See pq_check_connection(). */ if (*newval != 0) { - GUC_check_errdetail("client_connection_check_interval must be set to 0 on platforms that lack POLLRDHUP and not OSX."; + GUC_check_errdetail("client_connection_check_interval must be set to 0 on platforms that lack POLLRDHUP and not OSX."); return false; } #endif @@ -12060,6 +12517,7 @@ check_huge_page_size(int *newval, void **extra, GucSource source) return true; } + static void assign_pgstat_temp_directory(const char *newval, void *extra) { @@ -12141,6 +12599,18 @@ show_data_directory_mode(void) return buf; } +static const char * +show_in_hot_standby(void) +{ + /* + * We display the actual state based on shared memory, so that this GUC + * reports up-to-date state if examined intra-query. The underlying + * variable in_hot_standby changes only when we transmit a new value to + * the client. + */ + return RecoveryInProgress() ? "on" : "off"; +} + /* * We split the input string, where commas separate function names * and certain whitespace chars are ignored, into a \0-separated (and @@ -12306,7 +12776,7 @@ check_recovery_target_xid(char **newval, void **extra, GucSource source) TransactionId *myextra; errno = 0; - xid = (TransactionId) strtoul(*newval, NULL, 0); + xid = (TransactionId) pg_strtouint64(*newval, NULL, 0); if (errno == EINVAL || errno == ERANGE) return false; diff --git a/src/backend/utils/misc/guc_gp.c b/src/backend/utils/misc/guc_gp.c index 733fdbd8a265..fde440c529af 100644 --- a/src/backend/utils/misc/guc_gp.c +++ b/src/backend/utils/misc/guc_gp.c @@ -95,7 +95,7 @@ static void assign_pljava_classpath_insecure(bool newval, void *extra); static bool check_gp_resource_group_bypass(bool *newval, void **extra, GucSource source); static int guc_array_compare(const void *a, const void *b); -extern struct config_generic *find_option(const char *name, bool create_placeholders, int elevel); +extern struct config_generic *find_option(const char *name, bool create_placeholders, bool skip_errors, int elevel); extern int listenerBacklog; @@ -4872,7 +4872,7 @@ check_pljava_classpath_insecure(bool *newval, void **extra, GucSource source) { if ( *newval == true ) { - struct config_generic *pljava_cp = find_option("pljava_classpath", false, ERROR); + struct config_generic *pljava_cp = find_option("pljava_classpath", false, false, ERROR); if (pljava_cp != NULL) { pljava_cp->context = PGC_USERSET; @@ -4891,7 +4891,7 @@ assign_pljava_classpath_insecure(bool newval, void *extra) { if ( newval == true ) { - struct config_generic *pljava_cp = find_option("pljava_classpath", false, ERROR); + struct config_generic *pljava_cp = find_option("pljava_classpath", false, false, ERROR); if (pljava_cp != NULL) { pljava_cp->context = PGC_USERSET; diff --git a/src/backend/utils/misc/help_config.c b/src/backend/utils/misc/help_config.c index c0120e109081..d97243ddc8b1 100644 --- a/src/backend/utils/misc/help_config.c +++ b/src/backend/utils/misc/help_config.c @@ -7,7 +7,7 @@ * or GUC_DISALLOW_IN_FILE are not displayed, unless the user specifically * requests that variable by name * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/misc/help_config.c diff --git a/src/backend/utils/misc/pg_config.c b/src/backend/utils/misc/pg_config.c index 7a79cbff92c9..34d77db75a14 100644 --- a/src/backend/utils/misc/pg_config.c +++ b/src/backend/utils/misc/pg_config.c @@ -3,7 +3,7 @@ * pg_config.c * Expose same output as pg_config except as an SRF * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index 609231275893..209a20a8827d 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -5,7 +5,7 @@ * Routines to expose the contents of the control data file via * a set of SQL functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -94,9 +94,9 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) */ tupdesc = CreateTemplateTupleDesc(18); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn", - LSNOID, -1, 0); + PG_LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn", - LSNOID, -1, 0); + PG_LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "redo_wal_file", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "timeline_id", @@ -223,13 +223,13 @@ pg_control_recovery(PG_FUNCTION_ARGS) */ tupdesc = CreateTemplateTupleDesc(5); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "min_recovery_end_lsn", - LSNOID, -1, 0); + PG_LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "min_recovery_end_timeline", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "backup_start_lsn", - LSNOID, -1, 0); + PG_LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "backup_end_lsn", - LSNOID, -1, 0); + PG_LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 5, "end_of_backup_record_required", BOOLOID, -1, 0); tupdesc = BlessTupleDesc(tupdesc); diff --git a/src/backend/utils/misc/pg_rusage.c b/src/backend/utils/misc/pg_rusage.c index 64a6af3152b0..bb5d9e7c8501 100644 --- a/src/backend/utils/misc/pg_rusage.c +++ b/src/backend/utils/misc/pg_rusage.c @@ -4,7 +4,7 @@ * Resource usage measurement support routines. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 628cc94272e4..e3dcaa8a03ea 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -95,6 +95,10 @@ #tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; # 0 selects the system default +#client_connection_check_interval = 0 # time between checks for client + # disconnection while running queries; + # 0 for never + # - Authentication - #authentication_timeout = 1min # 1s-600s @@ -102,7 +106,7 @@ #db_user_namespace = off # GSSAPI using Kerberos -#krb_server_keyfile = '' +#krb_server_keyfile = 'FILE:${sysconfdir}/krb5.keytab' #krb_caseins_users = off # - SSL - @@ -111,6 +115,7 @@ #ssl_ca_file = '' #ssl_cert_file = 'server.crt' #ssl_crl_file = '' +#ssl_crl_dir = '' #ssl_key_file = 'server.key' #ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers #ssl_prefer_server_ciphers = on @@ -174,23 +179,23 @@ max_prepared_transactions = 250 # can be 0 or more #vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) #vacuum_cost_page_hit = 1 # 0-10000 credits -#vacuum_cost_page_miss = 10 # 0-10000 credits +#vacuum_cost_page_miss = 2 # 0-10000 credits #vacuum_cost_page_dirty = 20 # 0-10000 credits #vacuum_cost_limit = 200 # 1-10000 credits # - Asynchronous Behavior - +#backend_flush_after = 0 # measured in pages, 0 disables #effective_io_concurrency = 1 # 1-1000; 0 disables prefetching #maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching #max_worker_processes = 8 # (change requires restart) -#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers #max_parallel_workers_per_gather = 2 # taken from max_parallel_workers -#parallel_leader_participation = on +#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers #max_parallel_workers = 8 # maximum number of max_worker_processes that # can be used in parallel operations +#parallel_leader_participation = on #old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate # (change requires restart) -#backend_flush_after = 0 # measured in pages, 0 disables #------------------------------------------------------------------------------ @@ -209,14 +214,14 @@ max_prepared_transactions = 250 # can be 0 or more #wal_sync_method = fsync # the default is the first option # supported by the operating system: # open_datasync - # fdatasync (default on Linux) + # fdatasync (default on Linux and FreeBSD) # fsync # fsync_writethrough # open_sync #full_page_writes = on # recover from partial page writes -#wal_compression = off # enable compression of full-page writes #wal_log_hints = off # also do full page writes of non-critical updates # (change requires restart) +#wal_compression = off # enable compression of full-page writes #wal_init_zero = on # zero-fill new WAL files #wal_recycle = on # recycle WAL files #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers @@ -231,11 +236,11 @@ max_prepared_transactions = 250 # can be 0 or more # - Checkpoints - #checkpoint_timeout = 5min # range 30s-1d -#max_wal_size = 1GB -#min_wal_size = 80MB -#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 +#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0 #checkpoint_flush_after = 0 # measured in pages, 0 disables #checkpoint_warning = 30s # 0 disables +#max_wal_size = 1GB +#min_wal_size = 80MB # - Archiving - @@ -256,7 +261,6 @@ max_prepared_transactions = 250 # can be 0 or more # placeholders: %p = path of file to restore # %f = file name only # e.g. 'cp /mnt/server/archivedir/%f %p' - # (change requires restart) #archive_cleanup_command = '' # command to execute at every restartpoint #recovery_end_command = '' # command to execute at completion of recovery @@ -295,12 +299,11 @@ max_prepared_transactions = 250 # can be 0 or more #max_wal_senders = 10 # max number of walsender processes # (change requires restart) +#max_replication_slots = 10 # max number of replication slots + # (change requires restart) #wal_keep_size = 0 # in megabytes; 0 disables #max_slot_wal_keep_size = -1 # in megabytes; -1 disables #wal_sender_timeout = 60s # in milliseconds; 0 disables - -#max_replication_slots = 10 # max number of replication slots - # (change requires restart) #track_commit_timestamp = off # collect timestamp of transaction commit # (change requires restart) @@ -357,21 +360,26 @@ max_prepared_transactions = 250 # can be 0 or more # - Planner Method Configuration - +#enable_async_append = on #enable_bitmapscan = on +#enable_gathermerge = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_incremental_sort = on #enable_indexscan = on #enable_indexonlyscan = on #enable_material = on +#enable_resultcache = on #enable_mergejoin = on #enable_nestloop = on #enable_parallel_append = on +#enable_parallel_hash = on +#enable_partition_pruning = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off #enable_seqscan = on #enable_sort = on -#enable_incremental_sort = on #enable_tidscan = on -#enable_partitionwise_join = off -#enable_partitionwise_aggregate = off -#enable_parallel_hash = on -#enable_partition_pruning = on #gp_enable_multiphase_agg = on #gp_enable_preunique = on @@ -395,6 +403,10 @@ max_prepared_transactions = 250 # can be 0 or more # GPDB_96_MERGE_FIXME: figure out the appropriate values for the parallel gucs #parallel_tuple_cost = 0.1 # same scale as above #parallel_setup_cost = 1000.0 # same scale as above +#parallel_tuple_cost = 0.1 # same scale as above +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB +#effective_cache_size = 4GB #jit_above_cost = 100000 # perform JIT compilation if available # and query more expensive than this; @@ -410,15 +422,23 @@ max_prepared_transactions = 250 # can be 0 or more #effective_cache_size = 16GB #gp_motion_cost_per_row = 0.0 # (same) (if 0, 2*cpu_tuple_cost is used) +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 +#geqo_effort = 5 # range 1-10 +#geqo_pool_size = 0 # selects default based on effort +#geqo_generations = 0 # selects default based on effort +#geqo_selection_bias = 2.0 # range 1.5-2.0 +#geqo_seed = 0.0 # range 0.0-1.0 # - Other Planner Options - #cursor_tuple_fraction = 0.1 # range 0.0-1.0 #from_collapse_limit = 20 #join_collapse_limit = 20 # 1 disables collapsing of explicit - # JOIN clauses -#force_parallel_mode = off #jit = on # allow JIT compilation + # JOIN clauses #plan_cache_mode = auto # auto, force_generic_plan or # force_custom_plan @@ -440,6 +460,11 @@ optimizer_analyze_root_partition = on # stats collection on root partitions #log_file_mode = 0600 # creation mode for log files, # begin with 0 to use octal notation +#log_rotation_age = 1d # Automatic rotation of logfiles will + # happen after that time. 0 disables. +#log_rotation_size = 10MB # Automatic rotation of logfiles will + # happen after that much log output. + # 0 disables. #log_truncate_on_rotation = off # If on, an existing log file with the # same name as the new log file will be # truncated rather than appended to. @@ -448,11 +473,16 @@ optimizer_analyze_root_partition = on # stats collection on root partitions # or size-driven rotation. Default is # off, meaning append to existing files # in all cases. -#log_rotation_age = 1d # Automatic rotation of logfiles will - # happen after that time. 0 disables. -#log_rotation_size = 10MB # Automatic rotation of logfiles will - # happen after that much log output. - # 0 disables. + +# These are relevant when logging to syslog: +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on + +# This is only relevant when logging to eventlog (Windows): +# (change requires restart) +#event_source = 'PostgreSQL' # - When to Log - @@ -512,6 +542,11 @@ optimizer_analyze_root_partition = on # stats collection on root partitions #debug_print_slice_table = off #debug_print_plan = off #debug_pretty_print = on +#log_autovacuum_min_duration = -1 # log autovacuum activity; + # -1 disables, 0 logs all actions and + # their durations, > 0 logs only + # actions running at least this number + # of milliseconds. #log_checkpoints = off #log_connections = off #log_disconnections = off @@ -530,6 +565,7 @@ optimizer_analyze_root_partition = on # stats collection on root partitions # %t = timestamp without milliseconds # %m = timestamp with milliseconds # %n = timestamp with milliseconds (as a Unix epoch) + # %Q = query ID (0 if none or not computed) # %i = command tag # %e = SQL state # %c = session ID @@ -542,6 +578,8 @@ optimizer_analyze_root_partition = on # stats collection on root partitions # %% = '%' # e.g. '<%u%%%d> ' #log_lock_waits = off # log lock waits >= deadlock_timeout +#log_recovery_conflict_waits = off # log standby recovery conflict waits + # >= deadlock_timeout #log_parameter_max_length = -1 # when logging statements, limit logged # bind-parameter values to N bytes; # -1 means print in full, 0 disables @@ -556,6 +594,7 @@ optimizer_analyze_root_partition = on # stats collection on root partitions #log_timezone = 'GMT' # actually, defaults to TZ environment # setting + #------------------------------------------------------------------------------ # PROCESS TITLE #------------------------------------------------------------------------------ @@ -585,10 +624,12 @@ optimizer_analyze_root_partition = on # stats collection on root partitions # - Query and Index Statistics Collector - #track_activities = on +#track_activity_query_size = 1024 # (change requires restart) +#track_counts = on #track_counts = off #track_io_timing = off +#track_wal_io_timing = off #track_functions = none # none, pl, all -#track_activity_query_size = 1024 # (change requires restart) #stats_temp_directory = 'pg_stat_tmp' #stats_queue_level = off @@ -596,10 +637,11 @@ optimizer_analyze_root_partition = on # stats collection on root partitions # - Monitoring - +#compute_query_id = auto +#log_statement_stats = off #log_parser_stats = off #log_planner_stats = off #log_executor_stats = off -#log_statement_stats = off #------------------------------------------------------------------------------ # AUTOVACUUM @@ -607,10 +649,6 @@ optimizer_analyze_root_partition = on # stats collection on root partitions #autovacuum = on # Enable autovacuum subprocess? 'on' # requires track_counts to also be on. -#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and - # their durations, > 0 logs only - # actions running at least this number - # of milliseconds. #autovacuum_max_workers = 3 # max number of autovacuum subprocesses # (change requires restart) #autovacuum_naptime = 1min # time between autovacuum runs @@ -655,10 +693,11 @@ optimizer_analyze_root_partition = on # stats collection on root partitions # error #search_path = '"$user", public' # schema names #row_security = on +#default_table_access_method = 'heap' #default_tablespace = '' # a tablespace name, '' uses the default +#default_toast_compression = 'pglz' # 'pglz' or 'lz4' #temp_tablespaces = '' # a list of tablespace names, '' uses # only default tablespace -#default_table_access_method = 'heap' #check_function_bodies = on #default_transaction_isolation = 'read committed' #default_transaction_read_only = off @@ -668,17 +707,16 @@ optimizer_analyze_root_partition = on # stats collection on root partitions #statement_timeout = 0 # in milliseconds, 0 is disabled #lock_timeout = 0 # in milliseconds, 0 is disabled #idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled -#vacuum_freeze_min_age = 50000000 +#idle_session_timeout = 0 # in milliseconds, 0 is disabled #vacuum_freeze_table_age = 150000000 -#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_freeze_min_age = 50000000 +#vacuum_failsafe_age = 1600000000 #vacuum_multixact_freeze_table_age = 150000000 -#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples - # before index cleanup, 0 always performs - # index cleanup +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_failsafe_age = 1600000000 #bytea_output = 'hex' # hex, escape #xmlbinary = 'base64' #xmloption = 'content' -#gin_fuzzy_search_limit = 0 #gin_pending_list_limit = 4MB # - Locale and Formatting - @@ -710,14 +748,15 @@ optimizer_analyze_root_partition = on # stats collection on root partitions # - Shared Library Preloading - -#shared_preload_libraries = '' # (change requires restart) #local_preload_libraries = '' #session_preload_libraries = '' +#shared_preload_libraries = '' # (change requires restart) #jit_provider = 'llvmjit' # JIT library to use # - Other Defaults - #dynamic_library_path = '$libdir' +#gin_fuzzy_search_limit = 0 #------------------------------------------------------------------------------ @@ -765,7 +804,6 @@ gp_resqueue_memory_policy = 'eager_free' # memory request based queueing. #backslash_quote = safe_encoding # on, off, or safe_encoding #escape_string_warning = on #lo_compat_privileges = off -#operator_precedence_warning = off #quote_all_identifiers = off #standard_conforming_strings = on #synchronize_seqscans = on @@ -805,6 +843,7 @@ gp_vmem_protect_limit = 8192 #Virtual memory limit (in MB). #data_sync_retry = off # retry or panic on failure to fsync # data? # (change requires restart) +#recovery_init_sync_method = fsync # fsync, syncfs (Linux 5.8+) #------------------------------------------------------------------------------ diff --git a/src/backend/utils/misc/queryenvironment.c b/src/backend/utils/misc/queryenvironment.c index 31de81f353eb..86d61d083bfd 100644 --- a/src/backend/utils/misc/queryenvironment.c +++ b/src/backend/utils/misc/queryenvironment.c @@ -11,7 +11,7 @@ * on callers, since this is an opaque structure. This is the reason to * require a create function. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/queryjumble.c b/src/backend/utils/misc/queryjumble.c new file mode 100644 index 000000000000..9f2cd1f12769 --- /dev/null +++ b/src/backend/utils/misc/queryjumble.c @@ -0,0 +1,858 @@ +/*------------------------------------------------------------------------- + * + * queryjumble.c + * Query normalization and fingerprinting. + * + * Normalization is a process whereby similar queries, typically differing only + * in their constants (though the exact rules are somewhat more subtle than + * that) are recognized as equivalent, and are tracked as a single entry. This + * is particularly useful for non-prepared queries. + * + * Normalization is implemented by fingerprinting queries, selectively + * serializing those fields of each query tree's nodes that are judged to be + * essential to the query. This is referred to as a query jumble. This is + * distinct from a regular serialization in that various extraneous + * information is ignored as irrelevant or not essential to the query, such + * as the collations of Vars and, most notably, the values of constants. + * + * This jumble is acquired at the end of parse analysis of each query, and + * a 64-bit hash of it is stored into the query's Query.queryId field. + * The server then copies this value around, making it available in plan + * tree(s) generated from the query. The executor can then use this value + * to blame query costs on the proper queryId. + * + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/misc/queryjumble.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "common/hashfn.h" +#include "miscadmin.h" +#include "parser/scansup.h" +#include "utils/queryjumble.h" + +#define JUMBLE_SIZE 1024 /* query serialization buffer size */ + +/* GUC parameters */ +int compute_query_id = COMPUTE_QUERY_ID_AUTO; + +/* True when compute_query_id is ON, or AUTO and a module requests them */ +bool query_id_enabled = false; + +static uint64 compute_utility_query_id(const char *str, int query_location, int query_len); +static void AppendJumble(JumbleState *jstate, + const unsigned char *item, Size size); +static void JumbleQueryInternal(JumbleState *jstate, Query *query); +static void JumbleRangeTable(JumbleState *jstate, List *rtable); +static void JumbleRowMarks(JumbleState *jstate, List *rowMarks); +static void JumbleExpr(JumbleState *jstate, Node *node); +static void RecordConstLocation(JumbleState *jstate, int location); + +/* + * Given a possibly multi-statement source string, confine our attention to the + * relevant part of the string. + */ +const char * +CleanQuerytext(const char *query, int *location, int *len) +{ + int query_location = *location; + int query_len = *len; + + /* First apply starting offset, unless it's -1 (unknown). */ + if (query_location >= 0) + { + Assert(query_location <= strlen(query)); + query += query_location; + /* Length of 0 (or -1) means "rest of string" */ + if (query_len <= 0) + query_len = strlen(query); + else + Assert(query_len <= strlen(query)); + } + else + { + /* If query location is unknown, distrust query_len as well */ + query_location = 0; + query_len = strlen(query); + } + + /* + * Discard leading and trailing whitespace, too. Use scanner_isspace() + * not libc's isspace(), because we want to match the lexer's behavior. + */ + while (query_len > 0 && scanner_isspace(query[0])) + query++, query_location++, query_len--; + while (query_len > 0 && scanner_isspace(query[query_len - 1])) + query_len--; + + *location = query_location; + *len = query_len; + + return query; +} + +JumbleState * +JumbleQuery(Query *query, const char *querytext) +{ + JumbleState *jstate = NULL; + + Assert(IsQueryIdEnabled()); + + if (query->utilityStmt) + { + query->queryId = compute_utility_query_id(querytext, + query->stmt_location, + query->stmt_len); + } + else + { + jstate = (JumbleState *) palloc(sizeof(JumbleState)); + + /* Set up workspace for query jumbling */ + jstate->jumble = (unsigned char *) palloc(JUMBLE_SIZE); + jstate->jumble_len = 0; + jstate->clocations_buf_size = 32; + jstate->clocations = (LocationLen *) + palloc(jstate->clocations_buf_size * sizeof(LocationLen)); + jstate->clocations_count = 0; + jstate->highest_extern_param_id = 0; + + /* Compute query ID and mark the Query node with it */ + JumbleQueryInternal(jstate, query); + query->queryId = DatumGetUInt64(hash_any_extended(jstate->jumble, + jstate->jumble_len, + 0)); + + /* + * If we are unlucky enough to get a hash of zero, use 1 instead, to + * prevent confusion with the utility-statement case. + */ + if (query->queryId == UINT64CONST(0)) + query->queryId = UINT64CONST(1); + } + + return jstate; +} + +/* + * Enables query identifier computation. + * + * Third-party plugins can use this function to inform core that they require + * a query identifier to be computed. + */ +void +EnableQueryId(void) +{ + if (compute_query_id != COMPUTE_QUERY_ID_OFF) + query_id_enabled = true; +} + +/* + * Compute a query identifier for the given utility query string. + */ +static uint64 +compute_utility_query_id(const char *query_text, int query_location, int query_len) +{ + uint64 queryId; + const char *sql; + + /* + * Confine our attention to the relevant part of the string, if the query + * is a portion of a multi-statement source string. + */ + sql = CleanQuerytext(query_text, &query_location, &query_len); + + queryId = DatumGetUInt64(hash_any_extended((const unsigned char *) sql, + query_len, 0)); + + /* + * If we are unlucky enough to get a hash of zero(invalid), use queryID as + * 2 instead, queryID 1 is already in use for normal statements. + */ + if (queryId == UINT64CONST(0)) + queryId = UINT64CONST(2); + + return queryId; +} + +/* + * AppendJumble: Append a value that is substantive in a given query to + * the current jumble. + */ +static void +AppendJumble(JumbleState *jstate, const unsigned char *item, Size size) +{ + unsigned char *jumble = jstate->jumble; + Size jumble_len = jstate->jumble_len; + + /* + * Whenever the jumble buffer is full, we hash the current contents and + * reset the buffer to contain just that hash value, thus relying on the + * hash to summarize everything so far. + */ + while (size > 0) + { + Size part_size; + + if (jumble_len >= JUMBLE_SIZE) + { + uint64 start_hash; + + start_hash = DatumGetUInt64(hash_any_extended(jumble, + JUMBLE_SIZE, 0)); + memcpy(jumble, &start_hash, sizeof(start_hash)); + jumble_len = sizeof(start_hash); + } + part_size = Min(size, JUMBLE_SIZE - jumble_len); + memcpy(jumble + jumble_len, item, part_size); + jumble_len += part_size; + item += part_size; + size -= part_size; + } + jstate->jumble_len = jumble_len; +} + +/* + * Wrappers around AppendJumble to encapsulate details of serialization + * of individual local variable elements. + */ +#define APP_JUMB(item) \ + AppendJumble(jstate, (const unsigned char *) &(item), sizeof(item)) +#define APP_JUMB_STRING(str) \ + AppendJumble(jstate, (const unsigned char *) (str), strlen(str) + 1) + +/* + * JumbleQueryInternal: Selectively serialize the query tree, appending + * significant data to the "query jumble" while ignoring nonsignificant data. + * + * Rule of thumb for what to include is that we should ignore anything not + * semantically significant (such as alias names) as well as anything that can + * be deduced from child nodes (else we'd just be double-hashing that piece + * of information). + */ +static void +JumbleQueryInternal(JumbleState *jstate, Query *query) +{ + Assert(IsA(query, Query)); + Assert(query->utilityStmt == NULL); + + APP_JUMB(query->commandType); + /* resultRelation is usually predictable from commandType */ + JumbleExpr(jstate, (Node *) query->cteList); + JumbleRangeTable(jstate, query->rtable); + JumbleExpr(jstate, (Node *) query->jointree); + JumbleExpr(jstate, (Node *) query->targetList); + JumbleExpr(jstate, (Node *) query->onConflict); + JumbleExpr(jstate, (Node *) query->returningList); + JumbleExpr(jstate, (Node *) query->groupClause); + APP_JUMB(query->groupDistinct); + JumbleExpr(jstate, (Node *) query->groupingSets); + JumbleExpr(jstate, query->havingQual); + JumbleExpr(jstate, (Node *) query->windowClause); + JumbleExpr(jstate, (Node *) query->distinctClause); + JumbleExpr(jstate, (Node *) query->sortClause); + JumbleExpr(jstate, query->limitOffset); + JumbleExpr(jstate, query->limitCount); + APP_JUMB(query->limitOption); + JumbleRowMarks(jstate, query->rowMarks); + JumbleExpr(jstate, query->setOperations); +} + +/* + * Jumble a range table + */ +static void +JumbleRangeTable(JumbleState *jstate, List *rtable) +{ + ListCell *lc; + + foreach(lc, rtable) + { + RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); + + APP_JUMB(rte->rtekind); + switch (rte->rtekind) + { + case RTE_RELATION: + APP_JUMB(rte->relid); + JumbleExpr(jstate, (Node *) rte->tablesample); + APP_JUMB(rte->inh); + break; + case RTE_SUBQUERY: + JumbleQueryInternal(jstate, rte->subquery); + break; + case RTE_JOIN: + APP_JUMB(rte->jointype); + break; + case RTE_FUNCTION: + JumbleExpr(jstate, (Node *) rte->functions); + break; + case RTE_TABLEFUNC: + JumbleExpr(jstate, (Node *) rte->tablefunc); + break; + case RTE_VALUES: + JumbleExpr(jstate, (Node *) rte->values_lists); + break; + case RTE_CTE: + + /* + * Depending on the CTE name here isn't ideal, but it's the + * only info we have to identify the referenced WITH item. + */ + APP_JUMB_STRING(rte->ctename); + APP_JUMB(rte->ctelevelsup); + break; + case RTE_NAMEDTUPLESTORE: + APP_JUMB_STRING(rte->enrname); + break; + case RTE_RESULT: + break; + default: + elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); + break; + } + } +} + +/* + * Jumble a rowMarks list + */ +static void +JumbleRowMarks(JumbleState *jstate, List *rowMarks) +{ + ListCell *lc; + + foreach(lc, rowMarks) + { + RowMarkClause *rowmark = lfirst_node(RowMarkClause, lc); + + if (!rowmark->pushedDown) + { + APP_JUMB(rowmark->rti); + APP_JUMB(rowmark->strength); + APP_JUMB(rowmark->waitPolicy); + } + } +} + +/* + * Jumble an expression tree + * + * In general this function should handle all the same node types that + * expression_tree_walker() does, and therefore it's coded to be as parallel + * to that function as possible. However, since we are only invoked on + * queries immediately post-parse-analysis, we need not handle node types + * that only appear in planning. + * + * Note: the reason we don't simply use expression_tree_walker() is that the + * point of that function is to support tree walkers that don't care about + * most tree node types, but here we care about all types. We should complain + * about any unrecognized node type. + */ +static void +JumbleExpr(JumbleState *jstate, Node *node) +{ + ListCell *temp; + + if (node == NULL) + return; + + /* Guard against stack overflow due to overly complex expressions */ + check_stack_depth(); + + /* + * We always emit the node's NodeTag, then any additional fields that are + * considered significant, and then we recurse to any child nodes. + */ + APP_JUMB(node->type); + + switch (nodeTag(node)) + { + case T_Var: + { + Var *var = (Var *) node; + + APP_JUMB(var->varno); + APP_JUMB(var->varattno); + APP_JUMB(var->varlevelsup); + } + break; + case T_Const: + { + Const *c = (Const *) node; + + /* We jumble only the constant's type, not its value */ + APP_JUMB(c->consttype); + /* Also, record its parse location for query normalization */ + RecordConstLocation(jstate, c->location); + } + break; + case T_Param: + { + Param *p = (Param *) node; + + APP_JUMB(p->paramkind); + APP_JUMB(p->paramid); + APP_JUMB(p->paramtype); + /* Also, track the highest external Param id */ + if (p->paramkind == PARAM_EXTERN && + p->paramid > jstate->highest_extern_param_id) + jstate->highest_extern_param_id = p->paramid; + } + break; + case T_Aggref: + { + Aggref *expr = (Aggref *) node; + + APP_JUMB(expr->aggfnoid); + JumbleExpr(jstate, (Node *) expr->aggdirectargs); + JumbleExpr(jstate, (Node *) expr->args); + JumbleExpr(jstate, (Node *) expr->aggorder); + JumbleExpr(jstate, (Node *) expr->aggdistinct); + JumbleExpr(jstate, (Node *) expr->aggfilter); + } + break; + case T_GroupingFunc: + { + GroupingFunc *grpnode = (GroupingFunc *) node; + + JumbleExpr(jstate, (Node *) grpnode->refs); + APP_JUMB(grpnode->agglevelsup); + } + break; + case T_WindowFunc: + { + WindowFunc *expr = (WindowFunc *) node; + + APP_JUMB(expr->winfnoid); + APP_JUMB(expr->winref); + JumbleExpr(jstate, (Node *) expr->args); + JumbleExpr(jstate, (Node *) expr->aggfilter); + } + break; + case T_SubscriptingRef: + { + SubscriptingRef *sbsref = (SubscriptingRef *) node; + + JumbleExpr(jstate, (Node *) sbsref->refupperindexpr); + JumbleExpr(jstate, (Node *) sbsref->reflowerindexpr); + JumbleExpr(jstate, (Node *) sbsref->refexpr); + JumbleExpr(jstate, (Node *) sbsref->refassgnexpr); + } + break; + case T_FuncExpr: + { + FuncExpr *expr = (FuncExpr *) node; + + APP_JUMB(expr->funcid); + JumbleExpr(jstate, (Node *) expr->args); + } + break; + case T_NamedArgExpr: + { + NamedArgExpr *nae = (NamedArgExpr *) node; + + APP_JUMB(nae->argnumber); + JumbleExpr(jstate, (Node *) nae->arg); + } + break; + case T_OpExpr: + case T_DistinctExpr: /* struct-equivalent to OpExpr */ + case T_NullIfExpr: /* struct-equivalent to OpExpr */ + { + OpExpr *expr = (OpExpr *) node; + + APP_JUMB(expr->opno); + JumbleExpr(jstate, (Node *) expr->args); + } + break; + case T_ScalarArrayOpExpr: + { + ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node; + + APP_JUMB(expr->opno); + APP_JUMB(expr->useOr); + JumbleExpr(jstate, (Node *) expr->args); + } + break; + case T_BoolExpr: + { + BoolExpr *expr = (BoolExpr *) node; + + APP_JUMB(expr->boolop); + JumbleExpr(jstate, (Node *) expr->args); + } + break; + case T_SubLink: + { + SubLink *sublink = (SubLink *) node; + + APP_JUMB(sublink->subLinkType); + APP_JUMB(sublink->subLinkId); + JumbleExpr(jstate, (Node *) sublink->testexpr); + JumbleQueryInternal(jstate, castNode(Query, sublink->subselect)); + } + break; + case T_FieldSelect: + { + FieldSelect *fs = (FieldSelect *) node; + + APP_JUMB(fs->fieldnum); + JumbleExpr(jstate, (Node *) fs->arg); + } + break; + case T_FieldStore: + { + FieldStore *fstore = (FieldStore *) node; + + JumbleExpr(jstate, (Node *) fstore->arg); + JumbleExpr(jstate, (Node *) fstore->newvals); + } + break; + case T_RelabelType: + { + RelabelType *rt = (RelabelType *) node; + + APP_JUMB(rt->resulttype); + JumbleExpr(jstate, (Node *) rt->arg); + } + break; + case T_CoerceViaIO: + { + CoerceViaIO *cio = (CoerceViaIO *) node; + + APP_JUMB(cio->resulttype); + JumbleExpr(jstate, (Node *) cio->arg); + } + break; + case T_ArrayCoerceExpr: + { + ArrayCoerceExpr *acexpr = (ArrayCoerceExpr *) node; + + APP_JUMB(acexpr->resulttype); + JumbleExpr(jstate, (Node *) acexpr->arg); + JumbleExpr(jstate, (Node *) acexpr->elemexpr); + } + break; + case T_ConvertRowtypeExpr: + { + ConvertRowtypeExpr *crexpr = (ConvertRowtypeExpr *) node; + + APP_JUMB(crexpr->resulttype); + JumbleExpr(jstate, (Node *) crexpr->arg); + } + break; + case T_CollateExpr: + { + CollateExpr *ce = (CollateExpr *) node; + + APP_JUMB(ce->collOid); + JumbleExpr(jstate, (Node *) ce->arg); + } + break; + case T_CaseExpr: + { + CaseExpr *caseexpr = (CaseExpr *) node; + + JumbleExpr(jstate, (Node *) caseexpr->arg); + foreach(temp, caseexpr->args) + { + CaseWhen *when = lfirst_node(CaseWhen, temp); + + JumbleExpr(jstate, (Node *) when->expr); + JumbleExpr(jstate, (Node *) when->result); + } + JumbleExpr(jstate, (Node *) caseexpr->defresult); + } + break; + case T_CaseTestExpr: + { + CaseTestExpr *ct = (CaseTestExpr *) node; + + APP_JUMB(ct->typeId); + } + break; + case T_ArrayExpr: + JumbleExpr(jstate, (Node *) ((ArrayExpr *) node)->elements); + break; + case T_RowExpr: + JumbleExpr(jstate, (Node *) ((RowExpr *) node)->args); + break; + case T_RowCompareExpr: + { + RowCompareExpr *rcexpr = (RowCompareExpr *) node; + + APP_JUMB(rcexpr->rctype); + JumbleExpr(jstate, (Node *) rcexpr->largs); + JumbleExpr(jstate, (Node *) rcexpr->rargs); + } + break; + case T_CoalesceExpr: + JumbleExpr(jstate, (Node *) ((CoalesceExpr *) node)->args); + break; + case T_MinMaxExpr: + { + MinMaxExpr *mmexpr = (MinMaxExpr *) node; + + APP_JUMB(mmexpr->op); + JumbleExpr(jstate, (Node *) mmexpr->args); + } + break; + case T_SQLValueFunction: + { + SQLValueFunction *svf = (SQLValueFunction *) node; + + APP_JUMB(svf->op); + /* type is fully determined by op */ + APP_JUMB(svf->typmod); + } + break; + case T_XmlExpr: + { + XmlExpr *xexpr = (XmlExpr *) node; + + APP_JUMB(xexpr->op); + JumbleExpr(jstate, (Node *) xexpr->named_args); + JumbleExpr(jstate, (Node *) xexpr->args); + } + break; + case T_NullTest: + { + NullTest *nt = (NullTest *) node; + + APP_JUMB(nt->nulltesttype); + JumbleExpr(jstate, (Node *) nt->arg); + } + break; + case T_BooleanTest: + { + BooleanTest *bt = (BooleanTest *) node; + + APP_JUMB(bt->booltesttype); + JumbleExpr(jstate, (Node *) bt->arg); + } + break; + case T_CoerceToDomain: + { + CoerceToDomain *cd = (CoerceToDomain *) node; + + APP_JUMB(cd->resulttype); + JumbleExpr(jstate, (Node *) cd->arg); + } + break; + case T_CoerceToDomainValue: + { + CoerceToDomainValue *cdv = (CoerceToDomainValue *) node; + + APP_JUMB(cdv->typeId); + } + break; + case T_SetToDefault: + { + SetToDefault *sd = (SetToDefault *) node; + + APP_JUMB(sd->typeId); + } + break; + case T_CurrentOfExpr: + { + CurrentOfExpr *ce = (CurrentOfExpr *) node; + + APP_JUMB(ce->cvarno); + if (ce->cursor_name) + APP_JUMB_STRING(ce->cursor_name); + APP_JUMB(ce->cursor_param); + } + break; + case T_NextValueExpr: + { + NextValueExpr *nve = (NextValueExpr *) node; + + APP_JUMB(nve->seqid); + APP_JUMB(nve->typeId); + } + break; + case T_InferenceElem: + { + InferenceElem *ie = (InferenceElem *) node; + + APP_JUMB(ie->infercollid); + APP_JUMB(ie->inferopclass); + JumbleExpr(jstate, ie->expr); + } + break; + case T_TargetEntry: + { + TargetEntry *tle = (TargetEntry *) node; + + APP_JUMB(tle->resno); + APP_JUMB(tle->ressortgroupref); + JumbleExpr(jstate, (Node *) tle->expr); + } + break; + case T_RangeTblRef: + { + RangeTblRef *rtr = (RangeTblRef *) node; + + APP_JUMB(rtr->rtindex); + } + break; + case T_JoinExpr: + { + JoinExpr *join = (JoinExpr *) node; + + APP_JUMB(join->jointype); + APP_JUMB(join->isNatural); + APP_JUMB(join->rtindex); + JumbleExpr(jstate, join->larg); + JumbleExpr(jstate, join->rarg); + JumbleExpr(jstate, join->quals); + } + break; + case T_FromExpr: + { + FromExpr *from = (FromExpr *) node; + + JumbleExpr(jstate, (Node *) from->fromlist); + JumbleExpr(jstate, from->quals); + } + break; + case T_OnConflictExpr: + { + OnConflictExpr *conf = (OnConflictExpr *) node; + + APP_JUMB(conf->action); + JumbleExpr(jstate, (Node *) conf->arbiterElems); + JumbleExpr(jstate, conf->arbiterWhere); + JumbleExpr(jstate, (Node *) conf->onConflictSet); + JumbleExpr(jstate, conf->onConflictWhere); + APP_JUMB(conf->constraint); + APP_JUMB(conf->exclRelIndex); + JumbleExpr(jstate, (Node *) conf->exclRelTlist); + } + break; + case T_List: + foreach(temp, (List *) node) + { + JumbleExpr(jstate, (Node *) lfirst(temp)); + } + break; + case T_IntList: + foreach(temp, (List *) node) + { + APP_JUMB(lfirst_int(temp)); + } + break; + case T_SortGroupClause: + { + SortGroupClause *sgc = (SortGroupClause *) node; + + APP_JUMB(sgc->tleSortGroupRef); + APP_JUMB(sgc->eqop); + APP_JUMB(sgc->sortop); + APP_JUMB(sgc->nulls_first); + } + break; + case T_GroupingSet: + { + GroupingSet *gsnode = (GroupingSet *) node; + + JumbleExpr(jstate, (Node *) gsnode->content); + } + break; + case T_WindowClause: + { + WindowClause *wc = (WindowClause *) node; + + APP_JUMB(wc->winref); + APP_JUMB(wc->frameOptions); + JumbleExpr(jstate, (Node *) wc->partitionClause); + JumbleExpr(jstate, (Node *) wc->orderClause); + JumbleExpr(jstate, wc->startOffset); + JumbleExpr(jstate, wc->endOffset); + } + break; + case T_CommonTableExpr: + { + CommonTableExpr *cte = (CommonTableExpr *) node; + + /* we store the string name because RTE_CTE RTEs need it */ + APP_JUMB_STRING(cte->ctename); + APP_JUMB(cte->ctematerialized); + JumbleQueryInternal(jstate, castNode(Query, cte->ctequery)); + } + break; + case T_SetOperationStmt: + { + SetOperationStmt *setop = (SetOperationStmt *) node; + + APP_JUMB(setop->op); + APP_JUMB(setop->all); + JumbleExpr(jstate, setop->larg); + JumbleExpr(jstate, setop->rarg); + } + break; + case T_RangeTblFunction: + { + RangeTblFunction *rtfunc = (RangeTblFunction *) node; + + JumbleExpr(jstate, rtfunc->funcexpr); + } + break; + case T_TableFunc: + { + TableFunc *tablefunc = (TableFunc *) node; + + JumbleExpr(jstate, tablefunc->docexpr); + JumbleExpr(jstate, tablefunc->rowexpr); + JumbleExpr(jstate, (Node *) tablefunc->colexprs); + } + break; + case T_TableSampleClause: + { + TableSampleClause *tsc = (TableSampleClause *) node; + + APP_JUMB(tsc->tsmhandler); + JumbleExpr(jstate, (Node *) tsc->args); + JumbleExpr(jstate, (Node *) tsc->repeatable); + } + break; + default: + /* Only a warning, since we can stumble along anyway */ + elog(WARNING, "unrecognized node type: %d", + (int) nodeTag(node)); + break; + } +} + +/* + * Record location of constant within query string of query tree + * that is currently being walked. + */ +static void +RecordConstLocation(JumbleState *jstate, int location) +{ + /* -1 indicates unknown or undefined location */ + if (location >= 0) + { + /* enlarge array if needed */ + if (jstate->clocations_count >= jstate->clocations_buf_size) + { + jstate->clocations_buf_size *= 2; + jstate->clocations = (LocationLen *) + repalloc(jstate->clocations, + jstate->clocations_buf_size * + sizeof(LocationLen)); + } + jstate->clocations[jstate->clocations_count].location = location; + /* initialize lengths to -1 to simplify third-party module usage */ + jstate->clocations[jstate->clocations_count].length = -1; + jstate->clocations_count++; + } +} diff --git a/src/backend/utils/misc/rls.c b/src/backend/utils/misc/rls.c index 016fe511eb7d..13d25154dbe9 100644 --- a/src/backend/utils/misc/rls.c +++ b/src/backend/utils/misc/rls.c @@ -3,7 +3,7 @@ * rls.c * RLS-related utility functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/sampling.c b/src/backend/utils/misc/sampling.c index 361c15614e7c..0c327e823f71 100644 --- a/src/backend/utils/misc/sampling.c +++ b/src/backend/utils/misc/sampling.c @@ -3,7 +3,7 @@ * sampling.c * Relation block sampling routines. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c index 2f730404db39..c05d98dcfdc0 100644 --- a/src/backend/utils/misc/superuser.c +++ b/src/backend/utils/misc/superuser.c @@ -9,7 +9,7 @@ * the single-user case works. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/timeout.c b/src/backend/utils/misc/timeout.c index f1c9518b0c40..95a273d9cfbd 100644 --- a/src/backend/utils/misc/timeout.c +++ b/src/backend/utils/misc/timeout.c @@ -3,7 +3,7 @@ * timeout.c * Routines to multiplex SIGALRM interrupts for multiple timeout reasons. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -53,18 +53,29 @@ static timeout_params *volatile active_timeouts[MAX_TIMEOUTS]; /* * Flag controlling whether the signal handler is allowed to do anything. - * We leave this "false" when we're not expecting interrupts, just in case. + * This is useful to avoid race conditions with the handler. Note in + * particular that this lets us make changes in the data structures without + * tediously disabling and re-enabling the timer signal. Most of the time, + * no interrupt would happen anyway during such critical sections, but if + * one does, this rule ensures it's safe. Leaving the signal enabled across + * multiple operations can greatly reduce the number of kernel calls we make, + * too. See comments in schedule_alarm() about that. * - * Note that we don't bother to reset any pending timer interrupt when we - * disable the signal handler; it's not really worth the cycles to do so, - * since the probability of the interrupt actually occurring while we have - * it disabled is low. See comments in schedule_alarm() about that. + * We leave this "false" when we're not expecting interrupts, just in case. */ static volatile sig_atomic_t alarm_enabled = false; #define disable_alarm() (alarm_enabled = false) #define enable_alarm() (alarm_enabled = true) +/* + * State recording if and when we next expect the interrupt to fire. + * Note that the signal handler will unconditionally reset signal_pending to + * false, so that can change asynchronously even when alarm_enabled is false. + */ +static volatile sig_atomic_t signal_pending = false; +static TimestampTz signal_due_at = 0; /* valid only when signal_pending */ + /***************************************************************************** * Internal helper functions @@ -185,7 +196,11 @@ enable_timeout(TimeoutId id, TimestampTz now, TimestampTz fin_time) * Schedule alarm for the next active timeout, if any * * We assume the caller has obtained the current time, or a close-enough - * approximation. + * approximation. (It's okay if a tick or two has passed since "now", or + * if a little more time elapses before we reach the kernel call; that will + * cause us to ask for an interrupt a tick or two later than the nearest + * timeout, which is no big deal. Passing a "now" value that's in the future + * would be bad though.) */ static void schedule_alarm(TimestampTz now) @@ -193,21 +208,38 @@ schedule_alarm(TimestampTz now) if (num_active_timeouts > 0) { struct itimerval timeval; + TimestampTz nearest_timeout; long secs; int usecs; MemSet(&timeval, 0, sizeof(struct itimerval)); - /* Get the time remaining till the nearest pending timeout */ - TimestampDifference(now, active_timeouts[0]->fin_time, - &secs, &usecs); - /* - * It's possible that the difference is less than a microsecond; - * ensure we don't cancel, rather than set, the interrupt. + * Get the time remaining till the nearest pending timeout. If it is + * negative, assume that we somehow missed an interrupt, and force + * signal_pending off. This gives us a chance to recover if the + * kernel drops a timeout request for some reason. */ - if (secs == 0 && usecs == 0) + nearest_timeout = active_timeouts[0]->fin_time; + if (now > nearest_timeout) + { + signal_pending = false; + /* force an interrupt as soon as possible */ + secs = 0; usecs = 1; + } + else + { + TimestampDifference(now, nearest_timeout, + &secs, &usecs); + + /* + * It's possible that the difference is less than a microsecond; + * ensure we don't cancel, rather than set, the interrupt. + */ + if (secs == 0 && usecs == 0) + usecs = 1; + } timeval.it_value.tv_sec = secs; timeval.it_value.tv_usec = usecs; @@ -218,7 +250,7 @@ schedule_alarm(TimestampTz now) * interrupt could occur before we can set alarm_enabled, so that the * signal handler would fail to do anything. * - * Because we didn't bother to reset the timer in disable_alarm(), + * Because we didn't bother to disable the timer in disable_alarm(), * it's possible that a previously-set interrupt will fire between * enable_alarm() and setitimer(). This is safe, however. There are * two possible outcomes: @@ -244,9 +276,60 @@ schedule_alarm(TimestampTz now) */ enable_alarm(); + /* + * If there is already an interrupt pending that's at or before the + * needed time, we need not do anything more. The signal handler will + * do the right thing in the first case, and re-schedule the interrupt + * for later in the second case. It might seem that the extra + * interrupt is wasted work, but it's not terribly much work, and this + * method has very significant advantages in the common use-case where + * we repeatedly set a timeout that we don't expect to reach and then + * cancel it. Instead of invoking setitimer() every time the timeout + * is set or canceled, we perform one interrupt and a re-scheduling + * setitimer() call at intervals roughly equal to the timeout delay. + * For example, with statement_timeout = 1s and a throughput of + * thousands of queries per second, this method requires an interrupt + * and setitimer() call roughly once a second, rather than thousands + * of setitimer() calls per second. + * + * Because of the possible passage of time between when we obtained + * "now" and when we reach setitimer(), the kernel's opinion of when + * to trigger the interrupt is likely to be a bit later than + * signal_due_at. That's fine, for the same reasons described above. + */ + if (signal_pending && nearest_timeout >= signal_due_at) + return; + + /* + * As with calling enable_alarm(), we must set signal_pending *before* + * calling setitimer(); if we did it after, the signal handler could + * trigger before we set it, leaving us with a false opinion that a + * signal is still coming. + * + * Other race conditions involved with setting/checking signal_pending + * are okay, for the reasons described above. One additional point is + * that the signal handler could fire after we set signal_due_at, but + * still before the setitimer() call. Then the handler could + * overwrite signal_due_at with a value it computes, which will be the + * same as or perhaps later than what we just computed. After we + * perform setitimer(), the net effect would be that signal_due_at + * gives a time later than when the interrupt will really happen; + * which is a safe situation. + */ + signal_due_at = nearest_timeout; + signal_pending = true; + /* Set the alarm timer */ if (setitimer(ITIMER_REAL, &timeval, NULL) != 0) + { + /* + * Clearing signal_pending here is a bit pro forma, but not + * entirely so, since something in the FATAL exit path could try + * to use timeout facilities. + */ + signal_pending = false; elog(FATAL, "could not enable SIGALRM timer: %m"); + } } } @@ -279,6 +362,12 @@ handle_sig_alarm(SIGNAL_ARGS) */ SetLatch(MyLatch); + /* + * Always reset signal_pending, even if !alarm_enabled, since indeed no + * signal is now pending. + */ + signal_pending = false; + /* * Fire any pending timeouts, but only if we're enabled to do so. */ @@ -591,7 +680,7 @@ disable_timeouts(const DisableTimeoutParams *timeouts, int count) } /* - * Disable SIGALRM and remove all timeouts from the active list, + * Disable the signal handler, remove all timeouts from the active list, * and optionally reset their timeout indicators. */ void @@ -602,18 +691,10 @@ disable_all_timeouts(bool keep_indicators) disable_alarm(); /* - * Only bother to reset the timer if we think it's active. We could just - * let the interrupt happen anyway, but it's probably a bit cheaper to do - * setitimer() than to let the useless interrupt happen. + * We used to disable the timer interrupt here, but in common usage + * patterns it's cheaper to leave it enabled; that may save us from having + * to enable it again shortly. See comments in schedule_alarm(). */ - if (num_active_timeouts > 0) - { - struct itimerval timeval; - - MemSet(&timeval, 0, sizeof(struct itimerval)); - if (setitimer(ITIMER_REAL, &timeval, NULL) != 0) - elog(FATAL, "could not disable SIGALRM timer: %m"); - } num_active_timeouts = 0; diff --git a/src/backend/utils/misc/tzparser.c b/src/backend/utils/misc/tzparser.c index 46b2b0ca98dd..d2aa5ee87d5d 100644 --- a/src/backend/utils/misc/tzparser.c +++ b/src/backend/utils/misc/tzparser.c @@ -11,7 +11,7 @@ * PG_TRY if necessary. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index a5a2fa8bc5fd..077333bda9f6 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -9,7 +9,7 @@ * * Portions Copyright (c) 2007-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -360,7 +360,8 @@ static Size AllocSetGetChunkSpace(MemoryContext context, void *pointer); static bool AllocSetIsEmpty(MemoryContext context); static void AllocSetStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals); + MemoryContextCounters *totals, + bool print_to_stderr); static void AllocSetDeclareAccountingRoot(MemoryContext context); static Size AllocSetGetCurrentUsage(MemoryContext context); @@ -1554,11 +1555,12 @@ AllocSetIsEmpty(MemoryContext context) * printfunc: if not NULL, pass a human-readable stats string to this. * passthru: pass this pointer through to printfunc. * totals: if not NULL, add stats about this context into *totals. + * print_to_stderr: print stats to stderr if true, elog otherwise. */ static void AllocSetStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals) + MemoryContextCounters *totals, bool print_to_stderr) { AllocSet set = (AllocSet) context; Size nblocks = 0; @@ -1597,7 +1599,7 @@ AllocSetStats(MemoryContext context, "%zu total in %zd blocks; %zu free (%zd chunks); %zu used", totalspace, nblocks, freespace, freechunks, totalspace - freespace); - printfunc(context, passthru, stats_string); + printfunc(context, passthru, stats_string, print_to_stderr); } if (totals) diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c index 6e5e41242978..7e2a20b9417c 100644 --- a/src/backend/utils/mmgr/dsa.c +++ b/src/backend/utils/mmgr/dsa.c @@ -39,7 +39,7 @@ * empty and be returned to the free page manager, and whole segments can * become empty and be returned to the operating system. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c index 77f16f9b21bf..e4ee1aab979e 100644 --- a/src/backend/utils/mmgr/freepage.c +++ b/src/backend/utils/mmgr/freepage.c @@ -42,7 +42,7 @@ * where memory fragmentation is very severe, only a tiny fraction of * the pages under management are consumed by this btree. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mmgr/generation.c b/src/backend/utils/mmgr/generation.c index 66255070660f..c5b58209dd5a 100644 --- a/src/backend/utils/mmgr/generation.c +++ b/src/backend/utils/mmgr/generation.c @@ -6,7 +6,7 @@ * Generation is a custom MemoryContext implementation designed for cases of * chunks with similar lifespan. * - * Portions Copyright (c) 2017-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/mmgr/generation.c @@ -155,7 +155,8 @@ static Size GenerationGetChunkSpace(MemoryContext context, void *pointer); static bool GenerationIsEmpty(MemoryContext context); static void GenerationStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals); + MemoryContextCounters *totals, + bool print_to_stderr); #ifdef MEMORY_CONTEXT_CHECKING static void GenerationCheck(MemoryContext context); @@ -665,6 +666,7 @@ GenerationIsEmpty(MemoryContext context) * printfunc: if not NULL, pass a human-readable stats string to this. * passthru: pass this pointer through to printfunc. * totals: if not NULL, add stats about this context into *totals. + * print_to_stderr: print stats to stderr if true, elog otherwise. * * XXX freespace only accounts for empty space at the end of the block, not * space of freed chunks (which is unknown). @@ -672,7 +674,7 @@ GenerationIsEmpty(MemoryContext context) static void GenerationStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals) + MemoryContextCounters *totals, bool print_to_stderr) { GenerationContext *set = (GenerationContext *) context; Size nblocks = 0; @@ -704,7 +706,7 @@ GenerationStats(MemoryContext context, "%zu total in %zd blocks (%zd chunks); %zu free (%zd chunks); %zu used", totalspace, nblocks, nchunks, freespace, nfreechunks, totalspace - freespace); - printfunc(context, passthru, stats_string); + printfunc(context, passthru, stats_string, print_to_stderr); } if (totals) diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index 056989c062a8..6118b6cf41a6 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -11,7 +11,7 @@ * * Portions Copyright (c) 2007-2008, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -23,10 +23,12 @@ #include "postgres.h" -#include "funcapi.h" #include "mb/pg_wchar.h" #include "miscadmin.h" -#include "utils/builtins.h" +#include "storage/proc.h" +#include "storage/procarray.h" +#include "storage/procsignal.h" +#include "utils/fmgrprotos.h" #include "utils/memdebug.h" #include "utils/memutils.h" @@ -74,9 +76,11 @@ MemoryContext PortalContext = NULL; static void MemoryContextCallResetCallbacks(MemoryContext context); static void MemoryContextStatsInternal(MemoryContext context, int level, bool print, int max_children, - MemoryContextCounters *totals); + MemoryContextCounters *totals, + bool print_to_stderr); static void MemoryContextStatsPrint(MemoryContext context, void *passthru, - const char *stats_string); + const char *stats_string, + bool print_to_stderr); /* * You should not do memory allocations within a critical section, because @@ -94,11 +98,6 @@ static void MemoryContextStatsPrint(MemoryContext context, void *passthru, #define AssertNotInCriticalSection(context) #endif -/* ---------- - * The max bytes for showing identifiers of MemoryContext. - * ---------- - */ -#define MEMORY_CONTEXT_IDENT_DISPLAY_SIZE 1024 /***************************************************************************** * EXPORTED ROUTINES * @@ -644,7 +643,7 @@ MemoryContextMemAllocated(MemoryContext context, bool recurse) if (recurse) { - MemoryContext child = context->firstchild; + MemoryContext child; for (child = context->firstchild; child != NULL; @@ -667,28 +666,52 @@ void MemoryContextStats(MemoryContext context) { /* A hard-wired limit on the number of children is usually good enough */ - MemoryContextStatsDetail(context, 100); + MemoryContextStatsDetail(context, 100, true); } /* * MemoryContextStatsDetail * * Entry point for use if you want to vary the number of child contexts shown. + * + * If print_to_stderr is true, print statistics about the memory contexts + * with fprintf(stderr), otherwise use ereport(). */ void -MemoryContextStatsDetail(MemoryContext context, int max_children) +MemoryContextStatsDetail(MemoryContext context, int max_children, + bool print_to_stderr) { MemoryContextCounters grand_totals; memset(&grand_totals, 0, sizeof(grand_totals)); - MemoryContextStatsInternal(context, 0, true, max_children, &grand_totals); + MemoryContextStatsInternal(context, 0, true, max_children, &grand_totals, print_to_stderr); + + if (print_to_stderr) + fprintf(stderr, + "Grand total: %zu bytes in %zd blocks; %zu free (%zd chunks); %zu used\n", + grand_totals.totalspace, grand_totals.nblocks, + grand_totals.freespace, grand_totals.freechunks, + grand_totals.totalspace - grand_totals.freespace); + else - fprintf(stderr, - "Grand total: %zu bytes in %zd blocks; %zu free (%zd chunks); %zu used\n", - grand_totals.totalspace, grand_totals.nblocks, - grand_totals.freespace, grand_totals.freechunks, - grand_totals.totalspace - grand_totals.freespace); + /* + * Use LOG_SERVER_ONLY to prevent the memory contexts from being sent + * to the connected client. + * + * We don't buffer the information about all memory contexts in a + * backend into StringInfo and log it as one message. Otherwise which + * may require the buffer to be enlarged very much and lead to OOM + * error since there can be a large number of memory contexts in a + * backend. Instead, we log one message per memory context. + */ + ereport(LOG_SERVER_ONLY, + (errhidestmt(true), + errhidecontext(true), + errmsg_internal("Grand total: %zu bytes in %zd blocks; %zu free (%zd chunks); %zu used", + grand_totals.totalspace, grand_totals.nblocks, + grand_totals.freespace, grand_totals.freechunks, + grand_totals.totalspace - grand_totals.freespace))); } /* @@ -701,7 +724,8 @@ MemoryContextStatsDetail(MemoryContext context, int max_children) static void MemoryContextStatsInternal(MemoryContext context, int level, bool print, int max_children, - MemoryContextCounters *totals) + MemoryContextCounters *totals, + bool print_to_stderr) { MemoryContextCounters local_totals; MemoryContext child; @@ -713,7 +737,7 @@ MemoryContextStatsInternal(MemoryContext context, int level, context->methods->stats(context, print ? MemoryContextStatsPrint : NULL, (void *) &level, - totals); + totals, print_to_stderr); /* * Examine children. If there are more than max_children of them, we do @@ -728,11 +752,13 @@ MemoryContextStatsInternal(MemoryContext context, int level, if (ichild < max_children) MemoryContextStatsInternal(child, level + 1, print, max_children, - totals); + totals, + print_to_stderr); else MemoryContextStatsInternal(child, level + 1, false, max_children, - &local_totals); + &local_totals, + print_to_stderr); } /* Deal with excess children */ @@ -740,18 +766,33 @@ MemoryContextStatsInternal(MemoryContext context, int level, { if (print) { - int i; - - for (i = 0; i <= level; i++) - fprintf(stderr, " "); - fprintf(stderr, - "%d more child contexts containing %zu total in %zd blocks; %zu free (%zd chunks); %zu used\n", - ichild - max_children, - local_totals.totalspace, - local_totals.nblocks, - local_totals.freespace, - local_totals.freechunks, - local_totals.totalspace - local_totals.freespace); + if (print_to_stderr) + { + int i; + + for (i = 0; i <= level; i++) + fprintf(stderr, " "); + fprintf(stderr, + "%d more child contexts containing %zu total in %zd blocks; %zu free (%zd chunks); %zu used\n", + ichild - max_children, + local_totals.totalspace, + local_totals.nblocks, + local_totals.freespace, + local_totals.freechunks, + local_totals.totalspace - local_totals.freespace); + } + else + ereport(LOG_SERVER_ONLY, + (errhidestmt(true), + errhidecontext(true), + errmsg_internal("level: %d; %d more child contexts containing %zu total in %zd blocks; %zu free (%zd chunks); %zu used", + level, + ichild - max_children, + local_totals.totalspace, + local_totals.nblocks, + local_totals.freespace, + local_totals.freechunks, + local_totals.totalspace - local_totals.freespace))); } if (totals) @@ -773,11 +814,13 @@ MemoryContextStatsInternal(MemoryContext context, int level, */ static void MemoryContextStatsPrint(MemoryContext context, void *passthru, - const char *stats_string) + const char *stats_string, + bool print_to_stderr) { int level = *(int *) passthru; const char *name = context->name; const char *ident = context->ident; + char truncated_ident[110]; int i; /* @@ -791,9 +834,8 @@ MemoryContextStatsPrint(MemoryContext context, void *passthru, ident = NULL; } - for (i = 0; i < level; i++) - fprintf(stderr, " "); - fprintf(stderr, "%s: %s", name, stats_string); + truncated_ident[0] = '\0'; + if (ident) { /* @@ -805,24 +847,41 @@ MemoryContextStatsPrint(MemoryContext context, void *passthru, int idlen = strlen(ident); bool truncated = false; + strcpy(truncated_ident, ": "); + i = strlen(truncated_ident); + if (idlen > 100) { idlen = pg_mbcliplen(ident, idlen, 100); truncated = true; } - fprintf(stderr, ": "); + while (idlen-- > 0) { unsigned char c = *ident++; if (c < ' ') c = ' '; - fputc(c, stderr); + truncated_ident[i++] = c; } + truncated_ident[i] = '\0'; + if (truncated) - fprintf(stderr, "..."); + strcat(truncated_ident, "..."); } - fputc('\n', stderr); + + if (print_to_stderr) + { + for (i = 0; i < level; i++) + fprintf(stderr, " "); + fprintf(stderr, "%s: %s%s\n", name, stats_string, truncated_ident); + } + else + ereport(LOG_SERVER_ONLY, + (errhidestmt(true), + errhidecontext(true), + errmsg_internal("level: %d; %s: %s%s", + level, name, stats_string, truncated_ident))); } /* @@ -1185,6 +1244,52 @@ MemoryContextAllocExtended(MemoryContext context, Size size, int flags) return ret; } +/* + * HandleLogMemoryContextInterrupt + * Handle receipt of an interrupt indicating logging of memory + * contexts. + * + * All the actual work is deferred to ProcessLogMemoryContextInterrupt(), + * because we cannot safely emit a log message inside the signal handler. + */ +void +HandleLogMemoryContextInterrupt(void) +{ + InterruptPending = true; + LogMemoryContextPending = true; + /* latch will be set by procsignal_sigusr1_handler */ +} + +/* + * ProcessLogMemoryContextInterrupt + * Perform logging of memory contexts of this backend process. + * + * Any backend that participates in ProcSignal signaling must arrange + * to call this function if we see LogMemoryContextPending set. + * It is called from CHECK_FOR_INTERRUPTS(), which is enough because + * the target process for logging of memory contexts is a backend. + */ +void +ProcessLogMemoryContextInterrupt(void) +{ + LogMemoryContextPending = false; + + ereport(LOG, + (errmsg("logging memory contexts of PID %d", MyProcPid))); + + /* + * When a backend process is consuming huge memory, logging all its memory + * contexts might overrun available disk space. To prevent this, we limit + * the number of child contexts to log per parent to 100. + * + * As with MemoryContextStats(), we suppose that practical cases where the + * dump gets long will typically be huge numbers of siblings under the + * same parent context; while the additional debugging value from seeing + * details about individual siblings beyond 100 will not be large. + */ + MemoryContextStatsDetail(TopMemoryContext, 100, false); +} + void * palloc(Size size) { @@ -1460,133 +1565,3 @@ pchomp(const char *in) n--; return pnstrdup(in, n); } - -/* - * PutMemoryContextsStatsTupleStore - * One recursion level for pg_get_backend_memory_contexts. - */ -static void -PutMemoryContextsStatsTupleStore(Tuplestorestate *tupstore, - TupleDesc tupdesc, MemoryContext context, - const char *parent, int level) -{ -#define PG_GET_BACKEND_MEMORY_CONTEXTS_COLS 9 - - Datum values[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS]; - bool nulls[PG_GET_BACKEND_MEMORY_CONTEXTS_COLS]; - MemoryContextCounters stat; - MemoryContext child; - const char *name; - const char *ident; - - AssertArg(MemoryContextIsValid(context)); - - name = context->name; - ident = context->ident; - - /* - * To be consistent with logging output, we label dynahash contexts - * with just the hash table name as with MemoryContextStatsPrint(). - */ - if (ident && strcmp(name, "dynahash") == 0) - { - name = ident; - ident = NULL; - } - - /* Examine the context itself */ - memset(&stat, 0, sizeof(stat)); - (*context->methods->stats) (context, NULL, (void *) &level, &stat); - - memset(values, 0, sizeof(values)); - memset(nulls, 0, sizeof(nulls)); - - if (name) - values[0] = CStringGetTextDatum(name); - else - nulls[0] = true; - - if (ident) - { - int idlen = strlen(ident); - char clipped_ident[MEMORY_CONTEXT_IDENT_DISPLAY_SIZE]; - - /* - * Some identifiers such as SQL query string can be very long, - * truncate oversize identifiers. - */ - if (idlen >= MEMORY_CONTEXT_IDENT_DISPLAY_SIZE) - idlen = pg_mbcliplen(ident, idlen, MEMORY_CONTEXT_IDENT_DISPLAY_SIZE - 1); - - memcpy(clipped_ident, ident, idlen); - clipped_ident[idlen] = '\0'; - values[1] = CStringGetTextDatum(clipped_ident); - } - else - nulls[1] = true; - - if (parent) - values[2] = CStringGetTextDatum(parent); - else - nulls[2] = true; - - values[3] = Int32GetDatum(level); - values[4] = Int64GetDatum(stat.totalspace); - values[5] = Int64GetDatum(stat.nblocks); - values[6] = Int64GetDatum(stat.freespace); - values[7] = Int64GetDatum(stat.freechunks); - values[8] = Int64GetDatum(stat.totalspace - stat.freespace); - tuplestore_putvalues(tupstore, tupdesc, values, nulls); - - for (child = context->firstchild; child != NULL; child = child->nextchild) - { - PutMemoryContextsStatsTupleStore(tupstore, tupdesc, - child, name, level + 1); - } -} - -/* - * pg_get_backend_memory_contexts - * SQL SRF showing backend memory context. - */ -Datum -pg_get_backend_memory_contexts(PG_FUNCTION_ARGS) -{ - ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; - TupleDesc tupdesc; - Tuplestorestate *tupstore; - MemoryContext per_query_ctx; - MemoryContext oldcontext; - - /* check to see if caller supports us returning a tuplestore */ - if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("set-valued function called in context that cannot accept a set"))); - if (!(rsinfo->allowedModes & SFRM_Materialize)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("materialize mode required, but it is not allowed in this context"))); - - /* Build a tuple descriptor for our result type */ - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - elog(ERROR, "return type must be a row type"); - - per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; - oldcontext = MemoryContextSwitchTo(per_query_ctx); - - tupstore = tuplestore_begin_heap(true, false, work_mem); - rsinfo->returnMode = SFRM_Materialize; - rsinfo->setResult = tupstore; - rsinfo->setDesc = tupdesc; - - MemoryContextSwitchTo(oldcontext); - - PutMemoryContextsStatsTupleStore(tupstore, tupdesc, - TopMemoryContext, NULL, 0); - - /* clean up and return the tuplestore */ - tuplestore_donestoring(tupstore); - - return (Datum) 0; -} diff --git a/src/backend/utils/mmgr/memdebug.c b/src/backend/utils/mmgr/memdebug.c index 812025b76e22..3644c7f6067a 100644 --- a/src/backend/utils/mmgr/memdebug.c +++ b/src/backend/utils/mmgr/memdebug.c @@ -5,7 +5,7 @@ * public API of the memory management subsystem. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/utils/mmgr/memdebug.c diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c index c9a73deb0feb..498e392b1621 100644 --- a/src/backend/utils/mmgr/portalmem.c +++ b/src/backend/utils/mmgr/portalmem.c @@ -10,7 +10,7 @@ * * Portions Copyright (c) 2006-2009, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -126,7 +126,7 @@ EnablePortalManager(void) * create, initially */ PortalHashTable = hash_create("Portal hash", PORTALS_PER_USER, - &ctl, HASH_ELEM); + &ctl, HASH_ELEM | HASH_STRINGS); } /* @@ -240,8 +240,8 @@ CreatePortal(const char *name, bool allowDup, bool dupSilent) /* put portal in table (sets portal->name) */ PortalHashTableInsert(portal, name); - /* reuse portal->name copy */ - MemoryContextSetIdentifier(portal->portalContext, portal->name); + /* for named portals reuse portal->name copy */ + MemoryContextSetIdentifier(portal->portalContext, portal->name[0] ? portal->name : ""); return portal; } @@ -332,7 +332,7 @@ PortalReleaseCachedPlan(Portal portal) { if (portal->cplan) { - ReleaseCachedPlan(portal->cplan, false); + ReleaseCachedPlan(portal->cplan, NULL); portal->cplan = NULL; /* @@ -524,6 +524,9 @@ PortalDrop(Portal portal, bool isTopCommit) portal->cleanup = NULL; } + /* There shouldn't be an active snapshot anymore, except after error */ + Assert(portal->portalSnapshot == NULL || !isTopCommit); + /* * Remove portal from hash table. Because we do this here, we will not * come back to try to remove the portal again if there's any error in the @@ -736,6 +739,8 @@ PreCommit_Portals(bool isPrepare) portal->holdSnapshot = NULL; } portal->resowner = NULL; + /* Clear portalSnapshot too, for cleanliness */ + portal->portalSnapshot = NULL; continue; } @@ -1412,3 +1417,54 @@ HoldPinnedPortals(void) } } } + +/* + * Drop the outer active snapshots for all portals, so that no snapshots + * remain active. + * + * Like HoldPinnedPortals, this must be called when initiating a COMMIT or + * ROLLBACK inside a procedure. This has to be separate from that since it + * should not be run until we're done with steps that are likely to fail. + * + * It's tempting to fold this into PreCommit_Portals, but to do so, we'd + * need to clean up snapshot management in VACUUM and perhaps other places. + */ +void +ForgetPortalSnapshots(void) +{ + HASH_SEQ_STATUS status; + PortalHashEnt *hentry; + int numPortalSnaps = 0; + int numActiveSnaps = 0; + + /* First, scan PortalHashTable and clear portalSnapshot fields */ + hash_seq_init(&status, PortalHashTable); + + while ((hentry = (PortalHashEnt *) hash_seq_search(&status)) != NULL) + { + Portal portal = hentry->portal; + + if (portal->portalSnapshot != NULL) + { + portal->portalSnapshot = NULL; + numPortalSnaps++; + } + /* portal->holdSnapshot will be cleaned up in PreCommit_Portals */ + } + + /* + * Now, pop all the active snapshots, which should be just those that were + * portal snapshots. Ideally we'd drive this directly off the portal + * scan, but there's no good way to visit the portals in the correct + * order. So just cross-check after the fact. + */ + while (ActiveSnapshotSet()) + { + PopActiveSnapshot(); + numActiveSnaps++; + } + + if (numPortalSnaps != numActiveSnaps) + elog(ERROR, "portal snapshots (%d) did not account for all active snapshots (%d)", + numPortalSnaps, numActiveSnaps); +} diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c index 574d18037050..c58bf9233230 100644 --- a/src/backend/utils/mmgr/slab.c +++ b/src/backend/utils/mmgr/slab.c @@ -7,7 +7,7 @@ * numbers of equally-sized objects are allocated (and freed). * * - * Portions Copyright (c) 2017-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/mmgr/slab.c @@ -135,7 +135,8 @@ static Size SlabGetChunkSpace(MemoryContext context, void *pointer); static bool SlabIsEmpty(MemoryContext context); static void SlabStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals); + MemoryContextCounters *totals, + bool print_to_stderr); #ifdef MEMORY_CONTEXT_CHECKING static void SlabCheck(MemoryContext context); #endif @@ -632,11 +633,13 @@ SlabIsEmpty(MemoryContext context) * printfunc: if not NULL, pass a human-readable stats string to this. * passthru: pass this pointer through to printfunc. * totals: if not NULL, add stats about this context into *totals. + * print_to_stderr: print stats to stderr if true, elog otherwise. */ static void SlabStats(MemoryContext context, MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals) + MemoryContextCounters *totals, + bool print_to_stderr) { SlabContext *slab = castNode(SlabContext, context); Size nblocks = 0; @@ -671,7 +674,7 @@ SlabStats(MemoryContext context, "%zu total in %zd blocks; %zu free (%zd chunks); %zu used", totalspace, nblocks, freespace, freechunks, totalspace - freespace); - printfunc(context, passthru, stats_string); + printfunc(context, passthru, stats_string, print_to_stderr); } if (totals) diff --git a/src/backend/utils/mmgr/test/runaway_cleaner_test.c b/src/backend/utils/mmgr/test/runaway_cleaner_test.c index 296cc5f593d9..26e0b6a0a502 100755 --- a/src/backend/utils/mmgr/test/runaway_cleaner_test.c +++ b/src/backend/utils/mmgr/test/runaway_cleaner_test.c @@ -6,16 +6,18 @@ #include "../runaway_cleaner.c" #define EXPECT_EREPORT(LOG_LEVEL) \ - expect_any(errstart, elevel); \ - expect_any(errstart, domain); \ if (LOG_LEVEL < ERROR) \ { \ - will_return(errstart, false); \ + expect_any(errstart, elevel); \ + expect_any(errstart, domain); \ + will_return(errstart, false); \ } \ - else \ - { \ - will_return_with_sideeffect(errstart, false, &_ExceptionalCondition, NULL); \ - } + else \ + { \ + expect_any(errstart_cold, elevel); \ + expect_any(errstart_cold, domain); \ + will_return_with_sideeffect(errstart_cold, false, &_ExceptionalCondition, NULL); \ + } #define CHECK_FOR_RUNAWAY_CLEANUP_MEMORY_LOGGING() \ will_be_called(write_stderr); \ diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d index f2a214bfda43..c51b81a6d5a0 100644 --- a/src/backend/utils/probes.d +++ b/src/backend/utils/probes.d @@ -1,7 +1,7 @@ /* ---------- * DTrace probes for PostgreSQL backend * - * Copyright (c) 2006-2020, PostgreSQL Global Development Group + * Copyright (c) 2006-2021, PostgreSQL Global Development Group * * src/backend/utils/probes.d * ---------- diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c index ac6bb6e2cba0..cd1404a753a1 100644 --- a/src/backend/utils/resowner/resowner.c +++ b/src/backend/utils/resowner/resowner.c @@ -9,7 +9,7 @@ * See utils/resowner/README for more info. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,7 +20,9 @@ */ #include "postgres.h" +#include "common/cryptohash.h" #include "common/hashfn.h" +#include "common/hmac.h" #include "jit/jit.h" #include "storage/bufmgr.h" #include "storage/ipc.h" @@ -132,6 +134,8 @@ typedef struct ResourceOwnerData ResourceArray filearr; /* open temporary files */ ResourceArray dsmarr; /* dynamic shmem segments */ ResourceArray jitarr; /* JIT contexts */ + ResourceArray cryptohasharr; /* cryptohash contexts */ + ResourceArray hmacarr; /* HMAC contexts */ /* We can remember up to MAX_RESOWNER_LOCKS references to local locks. */ int nlocks; /* number of owned locks */ @@ -179,6 +183,8 @@ static void PrintTupleDescLeakWarning(TupleDesc tupdesc); static void PrintSnapshotLeakWarning(Snapshot snapshot); static void PrintFileLeakWarning(File file); static void PrintDSMLeakWarning(dsm_segment *seg); +static void PrintCryptoHashLeakWarning(Datum handle); +static void PrintHMACLeakWarning(Datum handle); /***************************************************************************** @@ -448,6 +454,8 @@ ResourceOwnerCreate(ResourceOwner parent, const char *name) ResourceArrayInit(&(owner->filearr), FileGetDatum(-1)); ResourceArrayInit(&(owner->dsmarr), PointerGetDatum(NULL)); ResourceArrayInit(&(owner->jitarr), PointerGetDatum(NULL)); + ResourceArrayInit(&(owner->cryptohasharr), PointerGetDatum(NULL)); + ResourceArrayInit(&(owner->hmacarr), PointerGetDatum(NULL)); return owner; } @@ -566,6 +574,27 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, jit_release_context(context); } + + /* Ditto for cryptohash contexts */ + while (ResourceArrayGetAny(&(owner->cryptohasharr), &foundres)) + { + pg_cryptohash_ctx *context = + (pg_cryptohash_ctx *) PointerGetDatum(foundres); + + if (isCommit) + PrintCryptoHashLeakWarning(foundres); + pg_cryptohash_free(context); + } + + /* Ditto for HMAC contexts */ + while (ResourceArrayGetAny(&(owner->hmacarr), &foundres)) + { + pg_hmac_ctx *context = (pg_hmac_ctx *) PointerGetDatum(foundres); + + if (isCommit) + PrintHMACLeakWarning(foundres); + pg_hmac_free(context); + } } else if (phase == RESOURCE_RELEASE_LOCKS) { @@ -653,7 +682,7 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, if (isCommit) PrintPlanCacheLeakWarning(res); - ReleaseCachedPlan(res, true); + ReleaseCachedPlan(res, owner); } /* Ditto for tupdesc references */ @@ -707,18 +736,14 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, void ResourceOwnerReleaseAllPlanCacheRefs(ResourceOwner owner) { - ResourceOwner save; Datum foundres; - save = CurrentResourceOwner; - CurrentResourceOwner = owner; while (ResourceArrayGetAny(&(owner->planrefarr), &foundres)) { CachedPlan *res = (CachedPlan *) DatumGetPointer(foundres); - ReleaseCachedPlan(res, true); + ReleaseCachedPlan(res, owner); } - CurrentResourceOwner = save; } /* @@ -744,6 +769,8 @@ ResourceOwnerDelete(ResourceOwner owner) Assert(owner->filearr.nitems == 0); Assert(owner->dsmarr.nitems == 0); Assert(owner->jitarr.nitems == 0); + Assert(owner->cryptohasharr.nitems == 0); + Assert(owner->hmacarr.nitems == 0); Assert(owner->nlocks == 0 || owner->nlocks == MAX_RESOWNER_LOCKS + 1); /* @@ -771,6 +798,8 @@ ResourceOwnerDelete(ResourceOwner owner) ResourceArrayFree(&(owner->filearr)); ResourceArrayFree(&(owner->dsmarr)); ResourceArrayFree(&(owner->jitarr)); + ResourceArrayFree(&(owner->cryptohasharr)); + ResourceArrayFree(&(owner->hmacarr)); pfree(owner); } @@ -1390,6 +1419,96 @@ ResourceOwnerForgetJIT(ResourceOwner owner, Datum handle) DatumGetPointer(handle), owner->name); } +/* + * Make sure there is room for at least one more entry in a ResourceOwner's + * cryptohash context reference array. + * + * This is separate from actually inserting an entry because if we run out of + * memory, it's critical to do so *before* acquiring the resource. + */ +void +ResourceOwnerEnlargeCryptoHash(ResourceOwner owner) +{ + ResourceArrayEnlarge(&(owner->cryptohasharr)); +} + +/* + * Remember that a cryptohash context is owned by a ResourceOwner + * + * Caller must have previously done ResourceOwnerEnlargeCryptoHash() + */ +void +ResourceOwnerRememberCryptoHash(ResourceOwner owner, Datum handle) +{ + ResourceArrayAdd(&(owner->cryptohasharr), handle); +} + +/* + * Forget that a cryptohash context is owned by a ResourceOwner + */ +void +ResourceOwnerForgetCryptoHash(ResourceOwner owner, Datum handle) +{ + if (!ResourceArrayRemove(&(owner->cryptohasharr), handle)) + elog(ERROR, "cryptohash context %p is not owned by resource owner %s", + DatumGetPointer(handle), owner->name); +} + +/* + * Debugging subroutine + */ +static void +PrintCryptoHashLeakWarning(Datum handle) +{ + elog(WARNING, "cryptohash context reference leak: context %p still referenced", + DatumGetPointer(handle)); +} + +/* + * Make sure there is room for at least one more entry in a ResourceOwner's + * hmac context reference array. + * + * This is separate from actually inserting an entry because if we run out of + * memory, it's critical to do so *before* acquiring the resource. + */ +void +ResourceOwnerEnlargeHMAC(ResourceOwner owner) +{ + ResourceArrayEnlarge(&(owner->hmacarr)); +} + +/* + * Remember that a HMAC context is owned by a ResourceOwner + * + * Caller must have previously done ResourceOwnerEnlargeHMAC() + */ +void +ResourceOwnerRememberHMAC(ResourceOwner owner, Datum handle) +{ + ResourceArrayAdd(&(owner->hmacarr), handle); +} + +/* + * Forget that a HMAC context is owned by a ResourceOwner + */ +void +ResourceOwnerForgetHMAC(ResourceOwner owner, Datum handle) +{ + if (!ResourceArrayRemove(&(owner->hmacarr), handle)) + elog(ERROR, "HMAC context %p is not owned by resource owner %s", + DatumGetPointer(handle), owner->name); +} + +/* + * Debugging subroutine + */ +static void +PrintHMACLeakWarning(Datum handle) +{ + elog(WARNING, "HMAC context reference leak: context %p still referenced", + DatumGetPointer(handle)); +} + /* * Cdb: walk through a resource owner and it's childrens */ diff --git a/src/backend/utils/sort/.gitignore b/src/backend/utils/sort/.gitignore deleted file mode 100644 index f2958633e61d..000000000000 --- a/src/backend/utils/sort/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/qsort_tuple.c diff --git a/src/backend/utils/sort/Makefile b/src/backend/utils/sort/Makefile index 7ac3659261e3..26f65fcaf7ad 100644 --- a/src/backend/utils/sort/Makefile +++ b/src/backend/utils/sort/Makefile @@ -21,12 +21,4 @@ OBJS = \ tuplesort.o \ tuplestore.o -tuplesort.o: qsort_tuple.c - -qsort_tuple.c: gen_qsort_tuple.pl - $(PERL) $(srcdir)/gen_qsort_tuple.pl $< > $@ - include $(top_srcdir)/src/backend/common.mk - -maintainer-clean: - rm -f qsort_tuple.c diff --git a/src/backend/utils/sort/gen_qsort_tuple.pl b/src/backend/utils/sort/gen_qsort_tuple.pl deleted file mode 100644 index eb0f7c5814f4..000000000000 --- a/src/backend/utils/sort/gen_qsort_tuple.pl +++ /dev/null @@ -1,271 +0,0 @@ -#!/usr/bin/perl - -# -# gen_qsort_tuple.pl -# -# This script generates specialized versions of the quicksort algorithm for -# tuple sorting. The quicksort code is derived from the NetBSD code. The -# code generated by this script runs significantly faster than vanilla qsort -# when used to sort tuples. This speedup comes from a number of places. -# The major effects are (1) inlining simple tuple comparators is much faster -# than jumping through a function pointer and (2) swap and vecswap operations -# specialized to the particular data type of interest (in this case, SortTuple) -# are faster than the generic routines. -# -# Modifications from vanilla NetBSD source: -# Add do ... while() macro fix -# Remove __inline, _DIAGASSERTs, __P -# Remove ill-considered "swap_cnt" switch to insertion sort, -# in favor of a simple check for presorted input. -# Take care to recurse on the smaller partition, to bound stack usage. -# -# Instead of sorting arbitrary objects, we're always sorting SortTuples. -# Add CHECK_FOR_INTERRUPTS(). -# -# CAUTION: if you change this file, see also qsort.c and qsort_arg.c -# - -use strict; -use warnings; - -my $SUFFIX; -my $EXTRAARGS; -my $EXTRAPARAMS; -my $CMPPARAMS; - -emit_qsort_boilerplate(); - -$SUFFIX = 'tuple'; -$EXTRAARGS = ', SortTupleComparator cmp_tuple, Tuplesortstate *state'; -$EXTRAPARAMS = ', cmp_tuple, state'; -$CMPPARAMS = ', state'; -emit_qsort_implementation(); - -$SUFFIX = 'ssup'; -$EXTRAARGS = ', SortSupport ssup'; -$EXTRAPARAMS = ', ssup'; -$CMPPARAMS = ', ssup'; -print <<'EOM'; - -#define cmp_ssup(a, b, ssup) \ - ApplySortComparator((a)->datum1, (a)->isnull1, \ - (b)->datum1, (b)->isnull1, ssup) - -EOM -emit_qsort_implementation(); - -sub emit_qsort_boilerplate -{ - print <<'EOM'; -/* - * autogenerated by src/backend/utils/sort/gen_qsort_tuple.pl, do not edit! - * - * This file is included by tuplesort.c, rather than compiled separately. - */ - -/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Qsort routine based on J. L. Bentley and M. D. McIlroy, - * "Engineering a sort function", - * Software--Practice and Experience 23 (1993) 1249-1265. - * - * We have modified their original by adding a check for already-sorted input, - * which seems to be a win per discussions on pgsql-hackers around 2006-03-21. - * - * Also, we recurse on the smaller partition and iterate on the larger one, - * which ensures we cannot recurse more than log(N) levels (since the - * partition recursed to is surely no more than half of the input). Bentley - * and McIlroy explicitly rejected doing this on the grounds that it's "not - * worth the effort", but we have seen crashes in the field due to stack - * overrun, so that judgment seems wrong. - */ - -static void -swapfunc(SortTuple *a, SortTuple *b, size_t n) -{ - do - { - SortTuple t = *a; - *a++ = *b; - *b++ = t; - } while (--n > 0); -} - -#define swap(a, b) \ - do { \ - SortTuple t = *(a); \ - *(a) = *(b); \ - *(b) = t; \ - } while (0) - -#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n) - -EOM - - return; -} - -sub emit_qsort_implementation -{ - print < 0 ? b : - (cmp_$SUFFIX(a, c$CMPPARAMS) < 0 ? a : c)); -} - -static void -qsort_$SUFFIX(SortTuple *a, size_t n$EXTRAARGS) -{ - SortTuple *pa, - *pb, - *pc, - *pd, - *pl, - *pm, - *pn; - size_t d1, - d2; - int r, - presorted; - -loop: - CHECK_FOR_INTERRUPTS(); - if (n < 7) - { - for (pm = a + 1; pm < a + n; pm++) - for (pl = pm; pl > a && cmp_$SUFFIX(pl - 1, pl$CMPPARAMS) > 0; pl--) - swap(pl, pl - 1); - return; - } - presorted = 1; - for (pm = a + 1; pm < a + n; pm++) - { - CHECK_FOR_INTERRUPTS(); - if (cmp_$SUFFIX(pm - 1, pm$CMPPARAMS) > 0) - { - presorted = 0; - break; - } - } - if (presorted) - return; - pm = a + (n / 2); - if (n > 7) - { - pl = a; - pn = a + (n - 1); - if (n > 40) - { - size_t d = (n / 8); - - pl = med3_$SUFFIX(pl, pl + d, pl + 2 * d$EXTRAPARAMS); - pm = med3_$SUFFIX(pm - d, pm, pm + d$EXTRAPARAMS); - pn = med3_$SUFFIX(pn - 2 * d, pn - d, pn$EXTRAPARAMS); - } - pm = med3_$SUFFIX(pl, pm, pn$EXTRAPARAMS); - } - swap(a, pm); - pa = pb = a + 1; - pc = pd = a + (n - 1); - for (;;) - { - while (pb <= pc && (r = cmp_$SUFFIX(pb, a$CMPPARAMS)) <= 0) - { - if (r == 0) - { - swap(pa, pb); - pa++; - } - pb++; - CHECK_FOR_INTERRUPTS(); - } - while (pb <= pc && (r = cmp_$SUFFIX(pc, a$CMPPARAMS)) >= 0) - { - if (r == 0) - { - swap(pc, pd); - pd--; - } - pc--; - CHECK_FOR_INTERRUPTS(); - } - if (pb > pc) - break; - swap(pb, pc); - pb++; - pc--; - } - pn = a + n; - d1 = Min(pa - a, pb - pa); - vecswap(a, pb - d1, d1); - d1 = Min(pd - pc, pn - pd - 1); - vecswap(pb, pn - d1, d1); - d1 = pb - pa; - d2 = pd - pc; - if (d1 <= d2) - { - /* Recurse on left partition, then iterate on right partition */ - if (d1 > 1) - qsort_$SUFFIX(a, d1$EXTRAPARAMS); - if (d2 > 1) - { - /* Iterate rather than recurse to save stack space */ - /* qsort_$SUFFIX(pn - d2, d2$EXTRAPARAMS); */ - a = pn - d2; - n = d2; - goto loop; - } - } - else - { - /* Recurse on right partition, then iterate on left partition */ - if (d2 > 1) - qsort_$SUFFIX(pn - d2, d2$EXTRAPARAMS); - if (d1 > 1) - { - /* Iterate rather than recurse to save stack space */ - /* qsort_$SUFFIX(a, d1$EXTRAPARAMS); */ - n = d1; - goto loop; - } - } -} -EOM - - return; -} diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c index 37589c59e089..d2eb4b3c7281 100644 --- a/src/backend/utils/sort/logtape.c +++ b/src/backend/utils/sort/logtape.c @@ -67,7 +67,7 @@ * There will always be the same number of runs as input tapes, and the same * number of input tapes as participants (worker Tuplesortstates). * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -78,6 +78,8 @@ #include "postgres.h" +#include + #include "storage/buffile.h" #include "utils/builtins.h" #include "utils/logtape.h" @@ -210,6 +212,7 @@ struct LogicalTapeSet long *freeBlocks; /* resizable array holding minheap */ long nFreeBlocks; /* # of currently free blocks */ Size freeBlocksLen; /* current allocated length of freeBlocks[] */ + bool enable_prealloc; /* preallocate write blocks? */ /* The array of logical tapes. */ int nTapes; /* # of logical tapes in set */ @@ -218,6 +221,7 @@ struct LogicalTapeSet static void ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer); static void ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer); +static long ltsGetBlock(LogicalTapeSet *lts, LogicalTape *lt); static long ltsGetFreeBlock(LogicalTapeSet *lts); static long ltsGetPreallocBlock(LogicalTapeSet *lts, LogicalTape *lt); static void ltsReleaseBlock(LogicalTapeSet *lts, long blocknum); @@ -245,12 +249,8 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer) * that's past the current end of file, fill the space between the current * end of file and the target block with zeros. * - * This should happen rarely, otherwise you are not writing very - * sequentially. In current use, this only happens when the sort ends - * writing a run, and switches to another tape. The last block of the - * previous tape isn't flushed to disk until the end of the sort, so you - * get one-block hole, where the last block of the previous tape will - * later go. + * This can happen either when tapes preallocate blocks; or for the last + * block of a tape which might not have been flushed. * * Note that BufFile concatenation can leave "holes" in BufFile between * worker-owned block ranges. These are tracked for reporting purposes @@ -376,8 +376,20 @@ parent_offset(unsigned long i) } /* - * Select the lowest currently unused block by taking the first element from - * the freelist min heap. + * Get the next block for writing. + */ +static long +ltsGetBlock(LogicalTapeSet *lts, LogicalTape *lt) +{ + if (lts->enable_prealloc) + return ltsGetPreallocBlock(lts, lt); + else + return ltsGetFreeBlock(lts); +} + +/* + * Select the lowest currently unused block from the tape set's global free + * list min heap. */ static long ltsGetFreeBlock(LogicalTapeSet *lts) @@ -433,7 +445,8 @@ ltsGetFreeBlock(LogicalTapeSet *lts) /* * Return the lowest free block number from the tape's preallocation list. - * Refill the preallocation list if necessary. + * Refill the preallocation list with blocks from the tape set's free list if + * necessary. */ static long ltsGetPreallocBlock(LogicalTapeSet *lts, LogicalTape *lt) @@ -494,7 +507,7 @@ ltsReleaseBlock(LogicalTapeSet *lts, long blocknum) * If the freelist becomes very large, just return and leak this free * block. */ - if (lts->freeBlocksLen * 2 > MaxAllocSize) + if (lts->freeBlocksLen * 2 * sizeof(long) > MaxAllocSize) return; lts->freeBlocksLen *= 2; @@ -556,7 +569,7 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, lt = <s->tapes[i]; pg_itoa(i, filename); - file = BufFileOpenShared(fileset, filename); + file = BufFileOpenShared(fileset, filename, O_RDONLY); filesize = BufFileSize(file); /* @@ -674,8 +687,8 @@ ltsInitReadBuffer(LogicalTapeSet *lts, LogicalTape *lt) * infrastructure that may be lifted in the future. */ LogicalTapeSet * -LogicalTapeSetCreate(int ntapes, TapeShare *shared, SharedFileSet *fileset, - int worker) +LogicalTapeSetCreate(int ntapes, bool preallocate, TapeShare *shared, + SharedFileSet *fileset, int worker) { LogicalTapeSet *lts; int i; @@ -692,6 +705,7 @@ LogicalTapeSetCreate(int ntapes, TapeShare *shared, SharedFileSet *fileset, lts->freeBlocksLen = 32; /* reasonable initial guess */ lts->freeBlocks = (long *) palloc(lts->freeBlocksLen * sizeof(long)); lts->nFreeBlocks = 0; + lts->enable_prealloc = preallocate; lts->nTapes = ntapes; lts->tapes = (LogicalTape *) palloc(ntapes * sizeof(LogicalTape)); @@ -789,7 +803,7 @@ LogicalTapeWrite(LogicalTapeSet *lts, int tapenum, Assert(lt->firstBlockNumber == -1); Assert(lt->pos == 0); - lt->curBlockNumber = ltsGetPreallocBlock(lts, lt); + lt->curBlockNumber = ltsGetBlock(lts, lt); lt->firstBlockNumber = lt->curBlockNumber; TapeBlockGetTrailer(lt->buffer)->prev = -1L; @@ -813,7 +827,7 @@ LogicalTapeWrite(LogicalTapeSet *lts, int tapenum, * First allocate the next block, so that we can store it in the * 'next' pointer of this block. */ - nextBlockNumber = ltsGetPreallocBlock(lts, lt); + nextBlockNumber = ltsGetBlock(lts, lt); /* set the next-pointer and dump the current block. */ TapeBlockGetTrailer(lt->buffer)->next = nextBlockNumber; @@ -1259,9 +1273,20 @@ LogicalTapeTell(LogicalTapeSet *lts, int tapenum, /* * Obtain total disk space currently used by a LogicalTapeSet, in blocks. + * + * This should not be called while there are open write buffers; otherwise it + * may not account for buffered data. */ long LogicalTapeSetBlocks(LogicalTapeSet *lts) { - return lts->nBlocksAllocated - lts->nHoleBlocks; +#ifdef USE_ASSERT_CHECKING + for (int i = 0; i < lts->nTapes; i++) + { + LogicalTape *lt = <s->tapes[i]; + + Assert(!lt->writing || lt->buffer == NULL); + } +#endif + return lts->nBlocksWritten - lts->nHoleBlocks; } diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c index f018cf015b88..65e18eff8f20 100644 --- a/src/backend/utils/sort/sharedtuplestore.c +++ b/src/backend/utils/sort/sharedtuplestore.c @@ -10,7 +10,7 @@ * scan where each backend reads an arbitrary subset of the tuples that were * written. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -561,14 +561,14 @@ sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, void *meta_data) sts_filename(name, accessor, accessor->read_participant); accessor->read_file = - BufFileOpenShared(accessor->fileset, name); + BufFileOpenShared(accessor->fileset, name, O_RDONLY); } /* Seek and load the chunk header. */ if (BufFileSeekBlock(accessor->read_file, read_page) != 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not seek block %u in shared tuplestore temporary file", + errmsg("could not seek to block %u in shared tuplestore temporary file", read_page))); nread = BufFileRead(accessor->read_file, &chunk_header, STS_CHUNK_HEADER_SIZE); diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c index fcfe6e831a19..6a889ec189fd 100644 --- a/src/backend/utils/sort/sortsupport.c +++ b/src/backend/utils/sort/sortsupport.c @@ -4,7 +4,7 @@ * Support routines for accelerated sorting. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -15,6 +15,7 @@ #include "postgres.h" +#include "access/gist.h" #include "access/nbtree.h" #include "catalog/pg_am.h" #include "fmgr.h" @@ -175,3 +176,36 @@ PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, FinishSortSupportFunction(opfamily, opcintype, ssup); } + +/* + * Fill in SortSupport given a GiST index relation + * + * Caller must previously have zeroed the SortSupportData structure and then + * filled in ssup_cxt, ssup_attno, ssup_collation, and ssup_nulls_first. This + * will fill in ssup_reverse (always false for GiST index build), as well as + * the comparator function pointer. + */ +void +PrepareSortSupportFromGistIndexRel(Relation indexRel, SortSupport ssup) +{ + Oid opfamily = indexRel->rd_opfamily[ssup->ssup_attno - 1]; + Oid opcintype = indexRel->rd_opcintype[ssup->ssup_attno - 1]; + Oid sortSupportFunction; + + Assert(ssup->comparator == NULL); + + if (indexRel->rd_rel->relam != GIST_AM_OID) + elog(ERROR, "unexpected non-gist AM: %u", indexRel->rd_rel->relam); + ssup->ssup_reverse = false; + + /* + * Look up the sort support function. This is simpler than for B-tree + * indexes because we don't support the old-style btree comparators. + */ + sortSupportFunction = get_opfamily_proc(opfamily, opcintype, opcintype, + GIST_SORTSUPPORT_PROC); + if (!OidIsValid(sortSupportFunction)) + elog(ERROR, "missing support function %d(%u,%u) in opfamily %u", + GIST_SORTSUPPORT_PROC, opcintype, opcintype, opfamily); + OidFunctionCall1(sortSupportFunction, PointerGetDatum(ssup)); +} diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index 47b56710e331..e37fca12ca51 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -83,7 +83,7 @@ * produce exactly one output run from their partial input. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -687,8 +687,27 @@ static void tuplesort_updatemax(Tuplesortstate *state); * reduces to ApplySortComparator(), that is single-key MinimalTuple sorts * and Datum sorts. */ -#include "qsort_tuple.c" +#define ST_SORT qsort_tuple +#define ST_ELEMENT_TYPE SortTuple +#define ST_COMPARE_RUNTIME_POINTER +#define ST_COMPARE_ARG_TYPE Tuplesortstate +#define ST_CHECK_FOR_INTERRUPTS +#define ST_SCOPE static +#define ST_DECLARE +#define ST_DEFINE +#include "lib/sort_template.h" + +#define ST_SORT qsort_ssup +#define ST_ELEMENT_TYPE SortTuple +#define ST_COMPARE(a, b, ssup) \ + ApplySortComparator((a)->datum1, (a)->isnull1, \ + (b)->datum1, (b)->isnull1, (ssup)) +#define ST_COMPARE_ARG_TYPE SortSupportData +#define ST_CHECK_FOR_INTERRUPTS +#define ST_SCOPE static +#define ST_DEFINE +#include "lib/sort_template.h" /* * tuplesort_begin_xxx @@ -1180,6 +1199,63 @@ tuplesort_begin_index_hash(Relation heapRel, return state; } +Tuplesortstate * +tuplesort_begin_index_gist(Relation heapRel, + Relation indexRel, + int workMem, + SortCoordinate coordinate, + bool randomAccess) +{ + Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate, + randomAccess); + MemoryContext oldcontext; + int i; + + oldcontext = MemoryContextSwitchTo(state->sortcontext); + +#ifdef TRACE_SORT + if (trace_sort) + elog(LOG, + "begin index sort: workMem = %d, randomAccess = %c", + workMem, randomAccess ? 't' : 'f'); +#endif + + state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel); + + state->comparetup = comparetup_index_btree; + state->copytup = copytup_index; + state->writetup = writetup_index; + state->readtup = readtup_index; + + state->heapRel = heapRel; + state->indexRel = indexRel; + + /* Prepare SortSupport data for each column */ + state->sortKeys = (SortSupport) palloc0(state->nKeys * + sizeof(SortSupportData)); + + for (i = 0; i < state->nKeys; i++) + { + SortSupport sortKey = state->sortKeys + i; + + sortKey->ssup_cxt = CurrentMemoryContext; + sortKey->ssup_collation = indexRel->rd_indcollation[i]; + sortKey->ssup_nulls_first = false; + sortKey->ssup_attno = i + 1; + /* Convey if abbreviation optimization is applicable in principle */ + sortKey->abbreviate = (i == 0); + + AssertState(sortKey->ssup_attno != 0); + + /* Look for a sort support function */ + PrepareSortSupportFromGistIndexRel(indexRel, sortKey); + } + + MemoryContextSwitchTo(oldcontext); + + return state; +} + Tuplesortstate * tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, bool nullsFirstFlag, int workMem, @@ -2637,7 +2713,7 @@ inittapes(Tuplesortstate *state, bool mergeruns) /* Create the tape set and allocate the per-tape data arrays */ inittapestate(state, maxTapes); state->tapeset = - LogicalTapeSetCreate(maxTapes, NULL, + LogicalTapeSetCreate(maxTapes, false, NULL, state->shared ? &state->shared->fileset : NULL, state->worker); @@ -4785,8 +4861,9 @@ leader_takeover_tapes(Tuplesortstate *state) * randomAccess is disallowed for parallel sorts. */ inittapestate(state, nParticipants + 1); - state->tapeset = LogicalTapeSetCreate(nParticipants + 1, shared->tapes, - &shared->fileset, state->worker); + state->tapeset = LogicalTapeSetCreate(nParticipants + 1, false, + shared->tapes, &shared->fileset, + state->worker); /* mergeruns() relies on currentRun for # of runs (in one-pass cases) */ state->currentRun = nParticipants; diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c index 62715b4be1ad..dc1617bfed52 100644 --- a/src/backend/utils/sort/tuplestore.c +++ b/src/backend/utils/sort/tuplestore.c @@ -67,6 +67,7 @@ * Portions Copyright (c) 2007-2010, Greenplum Inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -1774,7 +1775,7 @@ tuplestore_open_shared(SharedFileSet *fileset, const char *filename) state->writetup = writetup_forbidden; state->readtup = readtup_heap; - state->myfile = BufFileOpenShared(fileset, filename); + state->myfile = BufFileOpenShared(fileset, filename, O_RDONLY); state->readptrs[0].file = 0; state->readptrs[0].offset = 0L; state->status = TSS_READFILE; diff --git a/src/backend/utils/test/session_state_test.c b/src/backend/utils/test/session_state_test.c index 1abef16fb8d0..03c3abaebad5 100755 --- a/src/backend/utils/test/session_state_test.c +++ b/src/backend/utils/test/session_state_test.c @@ -19,16 +19,18 @@ will_be_called_with_sideeffect(ExceptionalCondition, &_ExceptionalCondition, NULL);\ #define EXPECT_EREPORT(LOG_LEVEL) \ - expect_any(errstart, elevel); \ - expect_any(errstart, domain); \ if (LOG_LEVEL < ERROR) \ { \ - will_return(errstart, false); \ + expect_any(errstart, elevel); \ + expect_any(errstart, domain); \ + will_return(errstart, false); \ + } \ + else \ + { \ + expect_any(errstart_cold, elevel); \ + expect_any(errstart_cold, domain); \ + will_return_with_sideeffect(errstart_cold, false, &_ExceptionalCondition, NULL); \ } \ - else \ - { \ - will_return_with_sideeffect(errstart, false, &_ExceptionalCondition, NULL);\ - } \ #undef PG_RE_THROW #define PG_RE_THROW() siglongjmp(*PG_exception_stack, 1) diff --git a/src/backend/utils/time/combocid.c b/src/backend/utils/time/combocid.c index 88cb1558647c..de63a19e4fa6 100644 --- a/src/backend/utils/time/combocid.c +++ b/src/backend/utils/time/combocid.c @@ -14,8 +14,8 @@ * real cmin and cmax using a backend-private array, which is managed by * this module. * - * To allow reusing existing combo cids, we also keep a hash table that - * maps cmin,cmax pairs to combo cids. This keeps the data structure size + * To allow reusing existing combo CIDs, we also keep a hash table that + * maps cmin,cmax pairs to combo CIDs. This keeps the data structure size * reasonable in most cases, since the number of unique pairs used by any * one transaction is likely to be small. * @@ -34,7 +34,7 @@ * reader processes can access the writer's shared array to look up combo * CIDs. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -58,7 +58,7 @@ #include "storage/dsm.h" #include "utils/resowner.h" -/* Hash table to lookup combo cids by cmin and cmax */ +/* Hash table to lookup combo CIDs by cmin and cmax */ static HTAB *comboHash = NULL; /* Key and entry structures for the hash table */ @@ -84,7 +84,7 @@ typedef ComboCidEntryData *ComboCidEntry; /* * An array of cmin,cmax pairs, indexed by combo command id. - * To convert a combo cid to cmin and cmax, you do a simple array lookup. + * To convert a combo CID to cmin and cmax, you do a simple array lookup. */ static ComboCidKey comboCids = NULL; static int usedComboCids = 0; /* number of elements in comboCids */ @@ -258,7 +258,6 @@ GetComboCommandId(CommandId cmin, CommandId cmax) sizeComboCids = CCID_ARRAY_SIZE; usedComboCids = 0; - memset(&hash_ctl, 0, sizeof(hash_ctl)); hash_ctl.keysize = sizeof(ComboCidKeyData); hash_ctl.entrysize = sizeof(ComboCidEntryData); hash_ctl.hcxt = TopTransactionContext; @@ -295,11 +294,11 @@ GetComboCommandId(CommandId cmin, CommandId cmax) if (found) { - /* Reuse an existing combo cid */ + /* Reuse an existing combo CID */ return entry->combocid; } - /* We have to create a new combo cid; we already made room in the array */ + /* We have to create a new combo CID; we already made room in the array */ combocid = usedComboCids; comboCids[combocid].cmin = cmin; @@ -349,7 +348,7 @@ GetRealCmax(CommandId combocid) } /* - * Estimate the amount of space required to serialize the current ComboCID + * Estimate the amount of space required to serialize the current combo CID * state. */ Size @@ -360,14 +359,14 @@ EstimateComboCIDStateSpace(void) /* Add space required for saving usedComboCids */ size = sizeof(int); - /* Add space required for saving the combocids key */ + /* Add space required for saving ComboCidKeyData */ size = add_size(size, mul_size(sizeof(ComboCidKeyData), usedComboCids)); return size; } /* - * Serialize the ComboCID state into the memory, beginning at start_address. + * Serialize the combo CID state into the memory, beginning at start_address. * maxsize should be at least as large as the value returned by * EstimateComboCIDStateSpace. */ @@ -376,7 +375,7 @@ SerializeComboCIDState(Size maxsize, char *start_address) { char *endptr; - /* First, we store the number of currently-existing ComboCIDs. */ + /* First, we store the number of currently-existing combo CIDs. */ *(int *) start_address = usedComboCids; /* If maxsize is too small, throw an error. */ @@ -392,9 +391,9 @@ SerializeComboCIDState(Size maxsize, char *start_address) } /* - * Read the ComboCID state at the specified address and initialize this - * backend with the same ComboCIDs. This is only valid in a backend that - * currently has no ComboCIDs (and only makes sense if the transaction state + * Read the combo CID state at the specified address and initialize this + * backend with the same combo CIDs. This is only valid in a backend that + * currently has no combo CIDs (and only makes sense if the transaction state * is serialized and restored as well). */ void @@ -407,11 +406,11 @@ RestoreComboCIDState(char *comboCIDstate) Assert(!comboCids && !comboHash); - /* First, we retrieve the number of ComboCIDs that were serialized. */ + /* First, we retrieve the number of combo CIDs that were serialized. */ num_elements = *(int *) comboCIDstate; keydata = (ComboCidKeyData *) (comboCIDstate + sizeof(int)); - /* Use GetComboCommandId to restore each ComboCID. */ + /* Use GetComboCommandId to restore each combo CID. */ for (i = 0; i < num_elements; i++) { cid = GetComboCommandId(keydata[i].cmin, keydata[i].cmax); diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c index 1264caa2d7db..4f53f22cc224 100644 --- a/src/backend/utils/time/snapmgr.c +++ b/src/backend/utils/time/snapmgr.c @@ -35,7 +35,7 @@ * stack is empty. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -64,6 +64,7 @@ #include "storage/spin.h" #include "utils/builtins.h" #include "utils/memutils.h" +#include "utils/old_snapshot.h" #include "utils/rel.h" #include "utils/resowner_private.h" #include "utils/snapmgr.h" @@ -82,59 +83,7 @@ */ int old_snapshot_threshold; /* number of minutes, -1 disables */ -/* - * Structure for dealing with old_snapshot_threshold implementation. - */ -typedef struct OldSnapshotControlData -{ - /* - * Variables for old snapshot handling are shared among processes and are - * only allowed to move forward. - */ - slock_t mutex_current; /* protect current_timestamp */ - TimestampTz current_timestamp; /* latest snapshot timestamp */ - slock_t mutex_latest_xmin; /* protect latest_xmin and next_map_update */ - TransactionId latest_xmin; /* latest snapshot xmin */ - TimestampTz next_map_update; /* latest snapshot valid up to */ - slock_t mutex_threshold; /* protect threshold fields */ - TimestampTz threshold_timestamp; /* earlier snapshot is old */ - TransactionId threshold_xid; /* earlier xid may be gone */ - - /* - * Keep one xid per minute for old snapshot error handling. - * - * Use a circular buffer with a head offset, a count of entries currently - * used, and a timestamp corresponding to the xid at the head offset. A - * count_used value of zero means that there are no times stored; a - * count_used value of OLD_SNAPSHOT_TIME_MAP_ENTRIES means that the buffer - * is full and the head must be advanced to add new entries. Use - * timestamps aligned to minute boundaries, since that seems less - * surprising than aligning based on the first usage timestamp. The - * latest bucket is effectively stored within latest_xmin. The circular - * buffer is updated when we get a new xmin value that doesn't fall into - * the same interval. - * - * It is OK if the xid for a given time slot is from earlier than - * calculated by adding the number of minutes corresponding to the - * (possibly wrapped) distance from the head offset to the time of the - * head entry, since that just results in the vacuuming of old tuples - * being slightly less aggressive. It would not be OK for it to be off in - * the other direction, since it might result in vacuuming tuples that are - * still expected to be there. - * - * Use of an SLRU was considered but not chosen because it is more - * heavyweight than is needed for this, and would probably not be any less - * code to implement. - * - * Persistence is not needed. - */ - int head_offset; /* subscript of oldest tracked time */ - TimestampTz head_timestamp; /* time corresponding to head xid */ - int count_used; /* how many slots are in use */ - TransactionId xid_by_minute[FLEXIBLE_ARRAY_MEMBER]; -} OldSnapshotControlData; - -static volatile OldSnapshotControlData *oldSnapshotControl; +volatile OldSnapshotControlData *oldSnapshotControl; /* @@ -2005,7 +1954,11 @@ TransactionIdLimitedForOldSnapshots(TransactionId recentXmin, Assert(OldSnapshotThresholdActive()); Assert(limit_ts != NULL && limit_xid != NULL); - if (!RelationAllowsEarlyPruning(relation)) + /* + * TestForOldSnapshot() assumes early pruning advances the page LSN, so we + * can't prune early when skipping WAL. + */ + if (!RelationAllowsEarlyPruning(relation) || !RelationNeedsWAL(relation)) return false; ts = GetSnapshotCurrentTimestamp(); @@ -2045,8 +1998,8 @@ TransactionIdLimitedForOldSnapshots(TransactionId recentXmin, if (ts == threshold_timestamp) { /* - * Current timestamp is in same bucket as the the last limit that - * was applied. Reuse. + * Current timestamp is in same bucket as the last limit that was + * applied. Reuse. */ xlimit = threshold_xid; } @@ -2190,10 +2143,32 @@ MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, TransactionId xmin) else { /* We need a new bucket, but it might not be the very next one. */ - int advance = ((ts - oldSnapshotControl->head_timestamp) - / USECS_PER_MINUTE); + int distance_to_new_tail; + int distance_to_current_tail; + int advance; - oldSnapshotControl->head_timestamp = ts; + /* + * Our goal is for the new "tail" of the mapping, that is, the entry + * which is newest and thus furthest from the "head" entry, to + * correspond to "ts". Since there's one entry per minute, the + * distance between the current head and the new tail is just the + * number of minutes of difference between ts and the current + * head_timestamp. + * + * The distance from the current head to the current tail is one less + * than the number of entries in the mapping, because the entry at the + * head_offset is for 0 minutes after head_timestamp. + * + * The difference between these two values is the number of minutes by + * which we need to advance the mapping, either adding new entries or + * rotating old ones out. + */ + distance_to_new_tail = + (ts - oldSnapshotControl->head_timestamp) / USECS_PER_MINUTE; + distance_to_current_tail = + oldSnapshotControl->count_used - 1; + advance = distance_to_new_tail - distance_to_current_tail; + Assert(advance > 0); if (advance >= OLD_SNAPSHOT_TIME_MAP_ENTRIES) { @@ -2201,6 +2176,7 @@ MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, TransactionId xmin) oldSnapshotControl->head_offset = 0; oldSnapshotControl->count_used = 1; oldSnapshotControl->xid_by_minute[0] = xmin; + oldSnapshotControl->head_timestamp = ts; } else { @@ -2219,6 +2195,7 @@ MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, TransactionId xmin) else oldSnapshotControl->head_offset = old_head + 1; oldSnapshotControl->xid_by_minute[old_head] = xmin; + oldSnapshotControl->head_timestamp += USECS_PER_MINUTE; } else { diff --git a/src/bin/Makefile b/src/bin/Makefile index 489db46385ed..0ae1f082c4c7 100644 --- a/src/bin/Makefile +++ b/src/bin/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin (client programs) # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/Makefile @@ -18,6 +18,7 @@ unittest-check: SUBDIRS = \ initdb \ + pg_amcheck \ pg_archivecleanup \ pg_basebackup \ pg_checksums \ diff --git a/src/bin/gpfdist/regress/Makefile b/src/bin/gpfdist/regress/Makefile index fff37177107f..ac2912d9f7f6 100644 --- a/src/bin/gpfdist/regress/Makefile +++ b/src/bin/gpfdist/regress/Makefile @@ -15,7 +15,7 @@ OPENSSL_MINOR_VERSION := $(shell echo '$(OPENSSL_VERSION)' | cut -d' ' -f2 | cut OPENSSL_FIX_VERSION := $(shell echo '$(OPENSSL_VERSION)' | cut -d' ' -f2 | cut -d. -f3 | sed 's/[^0-9]*//g') ifeq ($(enable_gpfdist),yes) -ifeq ($(with_openssl),yes) +ifeq ($(with_ssl),openssl) ifeq (1,$(shell [ $(OPENSSL_MAJOR_VERSION) -gt 1 ] || ( [ $(OPENSSL_MAJOR_VERSION) -eq 1 ] && [ $(OPENSSL_MINOR_VERSION) -ge 1 ] && [ $(OPENSSL_FIX_VERSION) -ge 1 ] ) && echo 1 )) REGRESS += gpfdist_ssl gpfdists_multiCA else @@ -32,8 +32,12 @@ endif REGRESS_OPTS = --init-file=init_file installcheck: watchdog ipv4v6_ports + # gpfdist appends to writable external table output files, so files left + # by a previous installcheck inflate the row counts the tests read back. + # Start each run from a clean slate. + rm -f data/gpfdist2/lineitem.tbl.w data/gpfdist2/lineitem.tbl.out.zst data/wet.out ifeq ($(enable_gpfdist),yes) -ifeq ($(with_openssl),yes) +ifeq ($(with_ssl),openssl) rm -rf data/gpfdist_ssl/certs_server_no_verify mkdir data/gpfdist_ssl/certs_server_no_verify rm -rf data/gpfdist_ssl/certs_matching diff --git a/src/bin/gpfdist/regress/output/gpfdist2.source b/src/bin/gpfdist/regress/output/gpfdist2.source index ec38f1e887a5..21ba5f7fff90 100644 --- a/src/bin/gpfdist/regress/output/gpfdist2.source +++ b/src/bin/gpfdist/regress/output/gpfdist2.source @@ -585,7 +585,7 @@ FORMAT 'text' CREATE INDEX index ON ext_lineitem (L_ORDERKEY); ERROR: cannot create index on foreign table "ext_lineitem" TRUNCATE ext_lineitem; -ERROR: "ext_lineitem" is not a table +ERROR: cannot truncate foreign table "ext_lineitem" DELETE FROM ext_lineitem where L_ORDERKEY > 10; ERROR: cannot delete from foreign table "ext_lineitem" UPDATE ext_lineitem SET L_ORDERKEY = 10 where L_ORDERKEY > 10; diff --git a/src/bin/gpfdist/remote_regress/Makefile b/src/bin/gpfdist/remote_regress/Makefile index f187de117c7e..1652e3d6978c 100644 --- a/src/bin/gpfdist/remote_regress/Makefile +++ b/src/bin/gpfdist/remote_regress/Makefile @@ -6,7 +6,7 @@ default: installcheck REGRESS = ifeq ($(enable_gpfdist),yes) -ifeq ($(with_openssl),yes) +ifeq ($(with_ssl),openssl) REGRESS += gpfdist_ssl endif endif @@ -19,7 +19,7 @@ pre_installcheck: mkdir data cp -rf ../regress/data/* data/ ifeq ($(enable_gpfdist),yes) -ifeq ($(with_openssl),yes) +ifeq ($(with_ssl),openssl) cp -rf $(MASTER_DATA_DIRECTORY)/gpfdists data/gpfdist_ssl/certs_matching cp data/gpfdist_ssl/certs_matching/root.crt data/gpfdist_ssl/certs_not_matching scp -r -P ${REMOTE_PORT} ./data/gpfdist_ssl ${REMOTE_USER}@${REMOTE_HOST}: diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile index 7e2375478081..a620a5bea061 100644 --- a/src/bin/initdb/Makefile +++ b/src/bin/initdb/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/initdb # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/initdb/Makefile diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c index 764ead97d34e..3c2b8d4e298f 100644 --- a/src/bin/initdb/findtimezone.c +++ b/src/bin/initdb/findtimezone.c @@ -3,7 +3,7 @@ * findtimezone.c * Functions for determining the default timezone to use. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/initdb/findtimezone.c @@ -195,6 +195,7 @@ build_time_t(int year, int month, int day) tm.tm_mday = day; tm.tm_mon = month - 1; tm.tm_year = year - 1900; + tm.tm_isdst = -1; return mktime(&tm); } diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 6088713dd609..e455b5c4aa6f 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -67,6 +67,7 @@ #include "common/file_utils.h" #include "common/logging.h" #include "common/restricted_token.h" +#include "common/string.h" #include "common/username.h" #include "fe_utils/string_utils.h" #include "getaddrinfo.h" @@ -161,6 +162,7 @@ static char *info_schema_file; static char *cdb_init_d_dir; static char *features_file; static char *system_views_file; +static char *system_functions_file; static bool success = false; static bool made_new_pgdata = false; static bool found_existing_pgdata = false; @@ -255,6 +257,7 @@ static void bootstrap_template1(void); static void setup_auth(FILE *cmdfd); static void get_su_pwd(); static void setup_depend(FILE *cmdfd); +static void setup_run_file(FILE *cmdfd, const char *filename); static void setup_sysviews(FILE *cmdfd); static void setup_description(FILE *cmdfd); #if 0 @@ -339,12 +342,9 @@ escape_quotes(const char *src) /* * Escape a field value to be inserted into the BKI data. - * Here, we first run the value through escape_quotes (which - * will be inverted by the backend's scanstr() function) and - * then overlay special processing of double quotes, which - * bootscanner.l will only accept as data if converted to octal - * representation ("\042"). We always wrap the value in double - * quotes, even if that isn't strictly necessary. + * Run the value through escape_quotes (which will be inverted + * by the backend's DeescapeQuotedString() function), then wrap + * the value in single quotes, even if that isn't strictly necessary. */ static char * escape_quotes_bki(const char *src) @@ -353,30 +353,13 @@ escape_quotes_bki(const char *src) char *data = escape_quotes(src); char *resultp; char *datap; - int nquotes = 0; - /* count double quotes in data */ - datap = data; - while ((datap = strchr(datap, '"')) != NULL) - { - nquotes++; - datap++; - } - - result = (char *) pg_malloc(strlen(data) + 3 + nquotes * 3); + result = (char *) pg_malloc(strlen(data) + 3); resultp = result; - *resultp++ = '"'; + *resultp++ = '\''; for (datap = data; *datap; datap++) - { - if (*datap == '"') - { - strcpy(resultp, "\\042"); - resultp += 4; - } - else - *resultp++ = *datap; - } - *resultp++ = '"'; + *resultp++ = *datap; + *resultp++ = '\''; *resultp = '\0'; free(data); @@ -1525,8 +1508,14 @@ get_su_pwd(void) */ printf("\n"); fflush(stdout); - simple_prompt("Enter new superuser password: ", pwd1, sizeof(pwd1), false); - simple_prompt("Enter it again: ", pwd2, sizeof(pwd2), false); + { + char *p1 = simple_prompt("Enter new superuser password: ", false); + char *p2 = simple_prompt("Enter it again: ", false); + strlcpy(pwd1, p1, sizeof(pwd1)); + strlcpy(pwd2, p2, sizeof(pwd2)); + free(p1); + free(p2); + } if (strcmp(pwd1, pwd2) != 0) { fprintf(stderr, _("Passwords didn't match.\n")); @@ -1678,6 +1667,35 @@ setup_depend(FILE *cmdfd) PG_CMD_PUTS(*line); } +/* + * Run a SQL file of system-object definitions (e.g. system_functions.sql) + * through the bootstrap backend, one logical line at a time. + * + * GPDB: system_functions.sql installs the real bodies of the ~46 internal SQL + * functions whose pg_proc.dat entry carries the placeholder prosrc + * 'see system_functions.sql'. This step was lost in the PG merge; without it + * those functions (col_description, obj_description, ...) try to execute the + * literal placeholder text and fail with 'syntax error at or near "see"'. + */ +static void +setup_run_file(FILE *cmdfd, const char *filename) +{ + char **line; + char **lines; + + lines = readfile(filename); + + for (line = lines; *line != NULL; line++) + { + PG_CMD_PUTS(*line); + free(*line); + } + + PG_CMD_PUTS("\n\n"); + + free(lines); +} + /* * set up system views */ @@ -2802,6 +2820,7 @@ setup_data_file_paths(void) set_input(&dictionary_file, "snowball_create.sql"); set_input(&info_schema_file, "information_schema.sql"); set_input(&features_file, "sql_features.txt"); + set_input(&system_functions_file, "system_functions.sql"); set_input(&system_views_file, "system_views.sql"); set_input(&cdb_init_d_dir, "cdb_init.d"); @@ -2830,6 +2849,7 @@ setup_data_file_paths(void) check_input(dictionary_file); check_input(info_schema_file); check_input(features_file); + check_input(system_functions_file); check_input(system_views_file); } @@ -3166,6 +3186,12 @@ initialize_data_directory(void) setup_auth(cmdfd); + /* + * Install the real bodies of internal SQL functions defined in + * system_functions.sql (must run before setup_depend so they are pinned). + */ + setup_run_file(cmdfd, system_functions_file); + setup_depend(cmdfd); /* diff --git a/src/bin/initdb/nls.mk b/src/bin/initdb/nls.mk index 25eb45720fe7..fe7bdfc04a5f 100644 --- a/src/bin/initdb/nls.mk +++ b/src/bin/initdb/nls.mk @@ -1,6 +1,6 @@ # src/bin/initdb/nls.mk CATALOG_NAME = initdb -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr uk vi zh_CN +AVAIL_LANGUAGES = cs de el es fr he it ja ko pl pt_BR ru sv tr uk vi zh_CN GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) findtimezone.c initdb.c ../../common/exec.c ../../common/fe_memutils.c ../../common/file_utils.c ../../common/pgfnames.c ../../common/restricted_token.c ../../common/rmtree.c ../../common/username.c ../../common/wait_error.c ../../port/dirmod.c GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) simple_prompt GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/initdb/po/cs.po b/src/bin/initdb/po/cs.po new file mode 100644 index 000000000000..b31d41448b4a --- /dev/null +++ b/src/bin/initdb/po/cs.po @@ -0,0 +1,1162 @@ +# Czech translation of initdb +# +# Karel Žák, 2004. +# Zdeněk Kotala, 2009, 2011, 2012, 2013. +# Tomáš Vondra , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: initdb-cs (PostgreSQL 9.3)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:15+0000\n" +"PO-Revision-Date: 2020-10-31 21:46+0100\n" +"Last-Translator: Tomas Vondra \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.4.1\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "chyba: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "varování: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "nelze získat aktuální adresář: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "neplatný binární soubor\"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "nelze číst binární soubor \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "nelze najít \"%s\" ke spuštění" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "nelze změnit adresář na \"%s\" : %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "nelze přečíst symbolický odkaz \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "volání pclose selhalo: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: initdb.c:325 +#, c-format +msgid "out of memory" +msgstr "nedostatek paměti" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek paměti\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nelze duplikovat null pointer (interní chyba)\n" + +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "nelze získat informace o souboru \"%s\": %m" + +#: ../../common/file_utils.c:158 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "nelze otevřít adresář \"%s\": %m" + +#: ../../common/file_utils.c:192 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "nelze číst z adresáře \"%s\": %m" + +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "nelze otevřít soubor \"%s\": %m" + +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "nelze provést fsync souboru \"%s\": %m" + +#: ../../common/file_utils.c:375 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "soubor \"%s\" nelze přejmenovat na \"%s\": %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "nelze zavřít adresář \"%s\": %m" + +#: ../../common/restricted_token.c:64 +#, c-format +#| msgid "could not load library \"%s\": %s" +msgid "could not load library \"%s\": error code %lu" +msgstr "nelze načíst knihovnu \"%s\": kód chyby %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +#| msgid "cannot create restricted tokens on this platform" +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "na této platformě nelze vytvářet vyhrazené tokeny: kód chyby %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "nelze otevřít token procesu: chybový kód %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "nelze alokovat SIDs: chybový kód %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "nelze vytvořit vyhrazený token: chybový kód %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "nelze nastartovat proces pro příkaz \"%s\": chybový kód %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "nelze znovu spustit s vyhrazeným tokenem: chybový kód %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "nelze získat návratový kód z podprovesu: chybový kód %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "nelze získat informace o souboru nebo adresáři \"%s\": %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "nelze smazat soubor nebo adresář \"%s\": %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "nelze určit efektivní user ID: %ld: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "uživatel neexistuje" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "vyhledání uživatelského jména selhalo: chybový kód %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "příkaz není spustitelný" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "příkaz nenalezen" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "potomek skončil s návratovým kódem %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "potomek byl ukončen vyjímkou 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "potomek byl ukončen signálem %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "potomek skončil s nerozponaným stavem %d" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "nelze nastavit propojení \"%s\": %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "nelze najít funkci pro \"%s\": %s\n" + +#: initdb.c:481 initdb.c:1505 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "nelze otevřít soubor \"%s\" pro čtení: %m" + +#: initdb.c:536 initdb.c:846 initdb.c:872 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "nelze otevřít soubor \"%s\" pro zápis: %m" + +#: initdb.c:543 initdb.c:550 initdb.c:852 initdb.c:877 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "nelze zapsat soubor \"%s\": %m" + +#: initdb.c:568 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "nelze spustit příkaz \"%s\": %m" + +#: initdb.c:586 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "odstraňuji datový adresář \"%s\"" + +#: initdb.c:588 +#, c-format +msgid "failed to remove data directory" +msgstr "selhalo odstranění datového adresáře" + +#: initdb.c:592 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "odstraňuji obsah datového adresáře \"%s\"" + +#: initdb.c:595 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "selhalo odstranění obsahu datového adresáře" + +#: initdb.c:600 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "odstraňuji WAL adresář \"%s\"" + +#: initdb.c:602 +#, c-format +msgid "failed to remove WAL directory" +msgstr "selhalo odstranění WAL adresáře" + +#: initdb.c:606 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "odstraňuji obsah WAL adresáře \"%s\"" + +#: initdb.c:608 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "selhalo odstranění obsahu WAL adresáře" + +#: initdb.c:615 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "datový adresář \"%s\" nebyl na žádost uživatele odstraněn" + +#: initdb.c:619 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "WAL adresář \"%s\" nebyl na žádost uživatele odstraněn" + +#: initdb.c:637 +#, c-format +msgid "cannot be run as root" +msgstr "nelze spouštět jako root" + +#: initdb.c:639 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Prosím přihlaste se jako (neprivilegovaný) uživatel, který bude vlastníkem\n" +"serverového procesu (například pomocí příkazu \"su\").\n" + +#: initdb.c:672 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "\"%s\" není platný název kódování znaků" + +#: initdb.c:805 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "soubor \"%s\" neexistuje" + +#: initdb.c:807 initdb.c:814 initdb.c:823 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"To znamená, že vaše instalace je poškozena, nebo jste\n" +"zadal chybný adresář v parametru -L při spuštění.\n" + +#: initdb.c:812 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "nelze přistupit k souboru \"%s\": %m" + +#: initdb.c:821 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "soubor \"%s\" není běžný soubor" + +#: initdb.c:966 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "vybírám implementaci dynamické sdílené paměti ... " + +#: initdb.c:975 +#, c-format +msgid "selecting default max_connections ... " +msgstr "vybírám implicitní nastavení max_connections ... " + +#: initdb.c:1006 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "vybírám implicitní nastavení shared_buffers ... " + +#: initdb.c:1040 +#, c-format +msgid "selecting default time zone ... " +msgstr "vybírám implicitní časovou zónu ... " + +#: initdb.c:1074 +msgid "creating configuration files ... " +msgstr "vytvářím konfigurační soubory ... " + +#: initdb.c:1227 initdb.c:1246 initdb.c:1332 initdb.c:1347 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "nelze změnit práva pro \"%s\": %m" + +#: initdb.c:1369 +#, c-format +msgid "running bootstrap script ... " +msgstr "spouštím bootstrap script ... " + +#: initdb.c:1381 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "vstupní soubor \"%s\" nenáleží PostgreSQL %s" + +#: initdb.c:1384 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "Zkontrolujte vaši instalaci nebo zadejte platnou cestu pomocí parametru -L.\n" + +#: initdb.c:1482 +msgid "Enter new superuser password: " +msgstr "Zadejte nové heslo pro superuživatele: " + +#: initdb.c:1483 +msgid "Enter it again: " +msgstr "Zadejte ho znovu: " + +#: initdb.c:1486 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Hesla nesouhlasí.\n" + +#: initdb.c:1512 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "nemohu přečíst heslo ze souboru \"%s\": %m" + +#: initdb.c:1515 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "soubor s hesly \"%s\" je prázdný" + +#: initdb.c:2043 +#, c-format +msgid "caught signal\n" +msgstr "signál obdržen\n" + +#: initdb.c:2049 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "nemohu zapsat do potomka: %s\n" + +#: initdb.c:2057 +#, c-format +msgid "ok\n" +msgstr "ok\n" + +#: initdb.c:2147 +#, c-format +msgid "setlocale() failed" +msgstr "setlocale() selhalo" + +#: initdb.c:2168 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "selhala obnova staré locale \"%s\"" + +#: initdb.c:2177 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "neplatný název národního nastavení (locale) \"%s\"" + +#: initdb.c:2188 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "neplatné nastavení locale; zkontrolujte LANG a LC_* proměnné prostředí" + +#: initdb.c:2215 +#, c-format +msgid "encoding mismatch" +msgstr "nesouhlasí kódování znaků" + +#: initdb.c:2217 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"Vybrané kódování znaků (%s) a kódování použité vybraným\n" +"národním nastavením (%s) si neodpovídají. To může vést k neočekávanému\n" +"chování různých funkcí pro manipulaci s řetězci. Pro opravu této situace\n" +"spusťte znovu %s a buď nespecifikujte kódování znaků explicitně, nebo\n" +"vyberte takovou kombinaci, která si odpovídá.\n" + +#: initdb.c:2289 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s inicializuji PostgreSQL klastr\n" +"\n" + +#: initdb.c:2290 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: initdb.c:2291 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [PŘEPÍNAČ]... [DATAADR]\n" + +#: initdb.c:2292 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Přepínače:\n" + +#: initdb.c:2293 +#, c-format +msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgstr " -A, --auth=METODA výchozí autentizační metoda pro lokální spojení\n" + +#: initdb.c:2294 +#, c-format +msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgstr " --auth-host=METHOD výchozí autentikační metoda pro lokální TCP/IP spojení\n" + +#: initdb.c:2295 +#, c-format +msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgstr " --auth-local=METHOD výchozí autentikační metoda pro spojení pro lokální socket\n" + +#: initdb.c:2296 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]DATAADR umístění tohoto databázového klastru\n" + +#: initdb.c:2297 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, --encoding=KÓDOVÁNÍ nastavení výchozího kódování pro nové databáze\n" + +#: initdb.c:2298 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr " -g, --allow-group-access povolit čtení/spouštění pro skupinu na datovém adresáři\n" + +#: initdb.c:2299 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr " --locale=LOCALE nastavení implicitního národního nastavení pro novou databázi\n" + +#: initdb.c:2300 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate, --lc-ctype, --lc-messages=LOCALE\n" +" --lc-monetary, --lc-numeric, --lc-time=LOCALE\n" +" nastaví implicitní národním nastavení\n" +" v příslušných kategoriích (výchozí hodnoty se \n" +" vezmou z nastavení prostředí)\n" + +#: initdb.c:2304 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale ekvivalent --locale=C\n" + +#: initdb.c:2305 +#, c-format +msgid " --pwfile=FILE read password for the new superuser from file\n" +msgstr " --pwfile=SOUBOR načti heslo pro nového superuživatele ze souboru\n" + +#: initdb.c:2306 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=CFG\n" +" implicitní configurace fulltextového vyhledávání\n" + +#: initdb.c:2308 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=JMÉNO jméno databázového superuživatele\n" + +#: initdb.c:2309 +#, c-format +msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt zeptej se na heslo pro nového superuživatele\n" + +#: initdb.c:2310 +#, c-format +msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, --waldir=WALDIR umístění adresáře s transakčním logem\n" + +#: initdb.c:2311 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE velikost WAL segmentů, v megabytech\n" + +#: initdb.c:2312 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Méně často používané přepínače:\n" + +#: initdb.c:2313 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug generuj spoustu ladicích informací\n" + +#: initdb.c:2314 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums použij kontrolní součty datových stránek\n" + +#: initdb.c:2315 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L DIRECTORY kde se nalézají vstupní soubory\n" + +#: initdb.c:2316 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean neuklízet po chybách\n" + +#: initdb.c:2317 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync nečekat na bezpečné zapsání změn na disk\n" + +#: initdb.c:2318 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show ukaž interní nastavení\n" + +#: initdb.c:2319 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only pouze provést sync datového adresáře\n" + +#: initdb.c:2320 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Ostatní přepínače:\n" + +#: initdb.c:2321 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version vypiš informace o verzi, potom skonči\n" + +#: initdb.c:2322 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ukaž tuto nápovědu, potom skonči\n" + +#: initdb.c:2323 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"Pokud není specifikován datový adresář, použije se proměnná\n" +"prostředí PGDATA.\n" + +#: initdb.c:2325 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Chyby hlašte na <%s>.\n" + +#: initdb.c:2326 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#: initdb.c:2354 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "neplatná autentikační metoda \"%s\" pro \"%s\" spojení" + +#: initdb.c:2370 +#, c-format +msgid "must specify a password for the superuser to enable %s authentication" +msgstr "musíte zadat heslo superuživatele pro použití autentizace typu %s" + +#: initdb.c:2397 +#, c-format +msgid "no data directory specified" +msgstr "není specifikován datový adresář" + +#: initdb.c:2399 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"Musíte zadat adresář, ve kterém se bude nacházet tato databáze.\n" +"Učiňte tak buď použitím přepínače -D nebo nastavením proměnné\n" +"prostředí PGDATA.\n" + +#: initdb.c:2434 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Program \"%s\" je vyžadován aplikací %s, ale nebyl nalezen ve stejném\n" +"adresáři jako \"%s\".\n" +"Zkontrolujte vaši instalaci." + +#: initdb.c:2439 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Program \"%s\" byl nalezen pomocí \"%s\",\n" +"ale nebyl ve stejné verzi jako %s.\n" +"Zkontrolujte vaši instalaci." + +#: initdb.c:2458 +#, c-format +msgid "input file location must be an absolute path" +msgstr "cesta k umístění vstupního souboru musí být absolutní" + +#: initdb.c:2475 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "Databázový klastr bude inicializován s locale %s.\n" + +#: initdb.c:2478 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"Databázový klastr bude inicializován s národním nastavením\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2502 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "nemohu najít vhodné kódování pro locale \"%s\"" + +#: initdb.c:2504 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "Spusťte znovu %s s přepínačem -E.\n" + +#: initdb.c:2505 initdb.c:3127 initdb.c:3148 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: initdb.c:2518 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"Kódování %s vyplývající z locale není povoleno jako kódování na serveru.\n" +"Implicitní kódování databáze bude nastaveno na %s.\n" + +#: initdb.c:2523 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "locale \"%s\" vyžaduje nepodporované kódování \"%s\"" + +#: initdb.c:2526 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"Kódování %s není povoleno jako kódování na serveru.\n" +"Pusťte znovu %s s jiným nastavením locale.\n" + +#: initdb.c:2535 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "Výchozí kódování pro databáze bylo odpovídajícím způsobem nastaveno na %s.\n" + +#: initdb.c:2597 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "nemohu najít vhodnou konfiguraci fulltextového vyhledávání \"%s\"" + +#: initdb.c:2608 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "vhodná konfigurace fulltextového vyhledávání pro locale \"%s\" není známa" + +#: initdb.c:2613 +#, c-format +msgid "specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "zvolená konfigurace fulltextového vyhledávání \"%s\" nemusí souhlasit s locale \"%s\"" + +#: initdb.c:2618 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "Implicitní konfigurace fulltextového vyhledávání bude nastavena na \"%s\".\n" + +#: initdb.c:2662 initdb.c:2744 +#, c-format +msgid "creating directory %s ... " +msgstr "vytvářím adresář %s ... " + +#: initdb.c:2668 initdb.c:2750 initdb.c:2815 initdb.c:2877 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "nelze vytvořit adresář \"%s\": %m" + +#: initdb.c:2679 initdb.c:2762 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "opravuji oprávnění pro existující adresář %s ... " + +#: initdb.c:2685 initdb.c:2768 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "nelze změnit práva adresáře \"%s\": %m" + +#: initdb.c:2699 initdb.c:2782 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "adresář \"%s\" existuje, ale není prázdný" + +#: initdb.c:2704 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Pokud chcete v tomto adresáři inicializovat databázi, odstraňte nebo\n" +"vyprázdněte adresář \"%s\" nebo spusťte %s\n" +"s argumentem jiným než \"%s\".\n" + +#: initdb.c:2712 initdb.c:2794 initdb.c:3163 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "nelze přístoupit k adresáři \"%s\": %m" + +#: initdb.c:2735 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "cesta k umístění WAL adresáře musí být absolutní" + +#: initdb.c:2787 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"Pokud v tomto adresáři chcete ukládat transakční log, odstraňte nebo\n" +"vyprázdněte adresář \"%s\".\n" + +#: initdb.c:2801 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "nelze vytvořit symbolický odkaz na \"%s\": %m" + +#: initdb.c:2806 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "na této platformě nejsou podporovány symbolické linky" + +#: initdb.c:2830 +#, c-format +msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" +msgstr "Obsahuje neviditelný soubor / soubor s tečkou na začátku názvu, možná proto že se jedná o mount point.\n" + +#: initdb.c:2833 +#, c-format +msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "Obsahuje lost+found adresář, možná proto že se jedná o mount point.\n" + +#: initdb.c:2836 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Použití mount pointu přímo jako datového adresáře se nedoporučuje.\n" +"Vytvořte v mount pointu podadresář.\n" + +#: initdb.c:2862 +#, c-format +msgid "creating subdirectories ... " +msgstr "vytvářím adresáře ... " + +#: initdb.c:2908 +msgid "performing post-bootstrap initialization ... " +msgstr "provádím post-bootstrap inicializaci ... " + +#: initdb.c:3065 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Běžím v ladicím režimu.\n" + +#: initdb.c:3069 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "Běžím v režimu \"no-clean\". Chybné kroky nebudou uklizeny.\n" + +#: initdb.c:3146 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "příliš mnoho argumentů v příkazové řádce (první je \"%s\")" + +#: initdb.c:3167 initdb.c:3256 +msgid "syncing data to disk ... " +msgstr "zapisuji data na disk ... " + +#: initdb.c:3176 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "dotaz na heslo a soubor s heslem nemohou být vyžadovány najednou" + +#: initdb.c:3201 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "argument pro --wal-segsize musí být číslo" + +#: initdb.c:3206 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "argument pro --wal-segsize musí být mocnina 2 mezi 1 a 1024" + +#: initdb.c:3223 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "superuživatelské jméno \"%s\" není povoleno; názvy rolí nemohou začínat \"pg_\"" + +#: initdb.c:3227 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Soubory patřící k této databázi budou vlastněny uživatelem \"%s\".\n" +"Tento uživatel musí být také vlastníkem serverového procesu.\n" +"\n" + +#: initdb.c:3243 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Kontrolní součty datových stránek jsou zapnuty.\n" + +#: initdb.c:3245 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Kontrolní součty datových stránek jsou vypnuty.\n" + +#: initdb.c:3262 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"Zápis na disk přeskočen.\n" +"Datový adresář může být v případě pádu operačního systému poškozený.\n" + +#: initdb.c:3267 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "povoluji \"trust\" autentizační metodu pro lokální spojení" + +#: initdb.c:3268 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Toto můžete změnit upravením pg_hba.conf nebo použitím volby -A,\n" +"nebo --auth-local a --auth-host, při dalším spuštění initdb.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3293 +msgid "logfile" +msgstr "logfile" + +#: initdb.c:3295 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"Povedlo se. Můžete začít používat databázový server spuštěním:\n" +"\n" +" %s\n" +"\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "nelze číst symbolický link \"%s\"" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: nelze provést stat souboru \"%s\": %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s : nelze otevřít adresář \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: nelze načíst adresář \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít soubor \"%s\": %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "nelze otevřít adresář \"%s\": %s\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "potomek byl ukončen signálem %s" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: nedostatek paměti\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: nelze otevřít soubor \"%s\" pro čtení: %s\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s: nelze zapsat do souboru \"%s\": %s\n" + +#~ msgid "%s: could not execute command \"%s\": %s\n" +#~ msgstr "%s: nelze vykonat příkaz \"%s\": %s\n" + +#~ msgid "%s: failed to restore old locale \"%s\"\n" +#~ msgstr "%s: selhala obnova původní locale \"%s\"\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: nelze vytvořít adresář \"%s\": %s\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: nelze vytvořit symbolický link \"%s\": %s\n" + +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: odstraňuji adresář s transakčním logem \"%s\"\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: selhalo odstraňení adresáře s transakčním logem\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: odstraňuji obsah adresáře s transakčním logem \"%s\"\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: selhalo odstranění obsahu adresáře s transakčním logem\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "%s: adresář s transakčním logem \"%s\" nebyl na žádost uživatele odstraněn\n" + +#~ msgid "%s: could not obtain information about current user: %s\n" +#~ msgstr "%s: nelze získat informace o aktualním uživateli: %s\n" + +#~ msgid "%s: could not get current user name: %s\n" +#~ msgstr "%s: nelze získat jméno aktuálního uživatele: %s\n" + +#~ msgid "creating template1 database in %s/base/1 ... " +#~ msgstr "vytvářím databázi template1 v %s/base/1 ... " + +#~ msgid "initializing pg_authid ... " +#~ msgstr "inicializuji pg_authid ... " + +#~ msgid "setting password ... " +#~ msgstr "nastavuji heslo ... " + +#~ msgid "initializing dependencies ... " +#~ msgstr "inicializuji závislosti ... " + +#~ msgid "creating system views ... " +#~ msgstr "vytvářím systémové pohledy ... " + +#~ msgid "loading system objects' descriptions ... " +#~ msgstr "nahrávám popisy systémových objektů ... " + +#~ msgid "creating collations ... " +#~ msgstr "vytvářím collations ... " + +#~ msgid "%s: locale name too long, skipped: \"%s\"\n" +#~ msgstr "%s: jméno locale je příliš dlouhé, přeskakuji: %s\n" + +#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" +#~ msgstr "%s: jméno locale obsahuje ne-ASCII znaky, přeskakuji: %s\n" + +#~ msgid "No usable system locales were found.\n" +#~ msgstr "Nebylo nalezené žádné použitelné systémové nárovní nastavení (locales).\n" + +#~ msgid "Use the option \"--debug\" to see details.\n" +#~ msgstr "Pro více detailů použijte volbu \"--debug\".\n" + +#~ msgid "not supported on this platform\n" +#~ msgstr "na této platformě není podporováno\n" + +#~ msgid "creating conversions ... " +#~ msgstr "vytvářím konverze ... " + +#~ msgid "creating dictionaries ... " +#~ msgstr "vytvářím adresáře ... " + +#~ msgid "setting privileges on built-in objects ... " +#~ msgstr "nastavuji oprávnění pro vestavěné objekty ... " + +#~ msgid "creating information schema ... " +#~ msgstr "vytvářím informační schéma ... " + +#~ msgid "loading PL/pgSQL server-side language ... " +#~ msgstr "načítám PL/pgSQL jazyk ... " + +#~ msgid "vacuuming database template1 ... " +#~ msgstr "pouštím VACUUM na databázi template1 ... " + +#~ msgid "copying template1 to template0 ... " +#~ msgstr "kopíruji template1 do template0 ... " + +#~ msgid "copying template1 to postgres ... " +#~ msgstr "kopíruji template1 do postgres ... " + +#~ msgid "Using the top-level directory of a mount point is not recommended.\n" +#~ msgstr "Použití top-level adresáře mount pointu se nedoporučuje.\n" + +#~ msgid "%s: could not determine valid short version string\n" +#~ msgstr "%s: nemohu zjistit platné krátké označení verze\n" + +#~ msgid "%s: The password file was not generated. Please report this problem.\n" +#~ msgstr "%s: Soubor s hesly nebyl vytvořen. Prosíme oznamte tento problém tvůrcům.\n" + +#~ msgid "" +#~ "The program \"postgres\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Program \"postgres\" byl nalezen pomocí \"%s\",\n" +#~ "ale nebyl ve stejné verzi jako %s.\n" +#~ "Zkontrolujte vaši instalaci." + +#~ msgid "" +#~ "The program \"postgres\" is needed by %s but was not found in the\n" +#~ "same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Program \"postgres\" je vyžadován aplikací %s, ale nebyl nalezen ve\n" +#~ "stejném adresáři jako \"%s\".\n" +#~ "Zkontrolujte vaši instalaci." + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" diff --git a/src/bin/initdb/po/de.po b/src/bin/initdb/po/de.po new file mode 100644 index 000000000000..4543e9cad3d9 --- /dev/null +++ b/src/bin/initdb/po/de.po @@ -0,0 +1,1024 @@ +# German message translation file for initdb. +# Peter Eisentraut , 2003 - 2021. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-27 04:17+0000\n" +"PO-Revision-Date: 2021-04-27 07:33+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ungültige Programmdatei »%s«" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "konnte Programmdatei »%s« nicht lesen" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "konnte kein »%s« zum Ausführen finden" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() fehlgeschlagen: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: initdb.c:328 +#, c-format +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../../common/file_utils.c:87 ../../common/file_utils.c:451 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: ../../common/file_utils.c:166 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: ../../common/file_utils.c:200 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" + +#: ../../common/file_utils.c:232 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:365 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: ../../common/file_utils.c:303 ../../common/file_utils.c:373 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "konnte Datei »%s« nicht fsyncen: %m" + +#: ../../common/file_utils.c:383 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "konnte Datei »%s« nicht in »%s« umbenennen: %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "konnte Bibliothek »%s« nicht laden: Fehlercode %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "auf dieser Plattform können keine beschränkten Token erzeugt werden: Fehlercode %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "konnte Prozess-Token nicht öffnen: Fehlercode %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "konnte SIDs nicht erzeugen: Fehlercode %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "konnte beschränktes Token nicht erzeugen: Fehlercode %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "konnte Datei oder Verzeichnis »%s« nicht entfernen: %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "konnte effektive Benutzer-ID %ld nicht nachschlagen: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "Benutzer existiert nicht" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "Fehler beim Nachschlagen des Benutzernamens: Fehlercode %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "Befehl ist nicht ausführbar" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "Befehl nicht gefunden" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "Kindprozess hat mit Code %d beendet" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "Kindprozess wurde durch Ausnahme 0x%X beendet" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "Kindprozess wurde von Signal %d beendet: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "Kindprozess hat mit unbekanntem Status %d beendet" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "konnte Junction für »%s« nicht erzeugen: %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "konnte Junction für »%s« nicht ermitteln: %s\n" + +#: initdb.c:461 initdb.c:1493 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" + +#: initdb.c:505 initdb.c:827 initdb.c:853 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "konnte Datei »%s« nicht zum Schreiben öffnen: %m" + +#: initdb.c:512 initdb.c:519 initdb.c:833 initdb.c:858 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schreiben: %m" + +#: initdb.c:537 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "konnte Befehl »%s« nicht ausführen: %m" + +#: initdb.c:555 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "entferne Datenverzeichnis »%s«" + +#: initdb.c:557 +#, c-format +msgid "failed to remove data directory" +msgstr "konnte Datenverzeichnis nicht entfernen" + +#: initdb.c:561 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "entferne Inhalt des Datenverzeichnisses »%s«" + +#: initdb.c:564 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "konnte Inhalt des Datenverzeichnisses nicht entfernen" + +#: initdb.c:569 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "entferne WAL-Verzeichnis »%s«" + +#: initdb.c:571 +#, c-format +msgid "failed to remove WAL directory" +msgstr "konnte WAL-Verzeichnis nicht entfernen" + +#: initdb.c:575 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "entferne Inhalt des WAL-Verzeichnisses »%s«" + +#: initdb.c:577 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "konnte Inhalt des WAL-Verzeichnisses nicht entfernen" + +#: initdb.c:584 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "Datenverzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" + +#: initdb.c:588 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "WAL-Verzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" + +#: initdb.c:606 +#, c-format +msgid "cannot be run as root" +msgstr "kann nicht als root ausgeführt werden" + +#: initdb.c:608 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Bitte loggen Sie sich (z.B. mit »su«) als der (unprivilegierte) Benutzer\n" +"ein, der Eigentümer des Serverprozesses sein soll.\n" + +#: initdb.c:641 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "»%s« ist keine gültige Serverkodierung" + +#: initdb.c:786 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "Datei »%s« existiert nicht" + +#: initdb.c:788 initdb.c:795 initdb.c:804 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"Das könnte bedeuten, dass Ihre Installation fehlerhaft ist oder dass Sie das\n" +"falsche Verzeichnis mit der Kommandozeilenoption -L angegeben haben.\n" + +#: initdb.c:793 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "konnte nicht auf Datei »%s« zugreifen: %m" + +#: initdb.c:802 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "Datei »%s« ist keine normale Datei" + +#: initdb.c:947 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "wähle Implementierung von dynamischem Shared Memory ... " + +#: initdb.c:956 +#, c-format +msgid "selecting default max_connections ... " +msgstr "wähle Vorgabewert für max_connections ... " + +#: initdb.c:987 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "wähle Vorgabewert für shared_buffers ... " + +#: initdb.c:1021 +#, c-format +msgid "selecting default time zone ... " +msgstr "wähle Vorgabewert für Zeitzone ... " + +#: initdb.c:1055 +msgid "creating configuration files ... " +msgstr "erzeuge Konfigurationsdateien ... " + +#: initdb.c:1214 initdb.c:1233 initdb.c:1319 initdb.c:1334 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "konnte Zugriffsrechte von »%s« nicht ändern: %m" + +#: initdb.c:1356 +#, c-format +msgid "running bootstrap script ... " +msgstr "führe Bootstrap-Skript aus ... " + +#: initdb.c:1368 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "Eingabedatei »%s« gehört nicht zu PostgreSQL %s" + +#: initdb.c:1371 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "" +"Prüfen Sie Ihre Installation oder geben Sie den korrekten Pfad mit der\n" +"Option -L an.\n" + +#: initdb.c:1470 +msgid "Enter new superuser password: " +msgstr "Geben Sie das neue Superuser-Passwort ein: " + +#: initdb.c:1471 +msgid "Enter it again: " +msgstr "Geben Sie es noch einmal ein: " + +#: initdb.c:1474 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Passwörter stimmten nicht überein.\n" + +#: initdb.c:1501 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "konnte Passwort nicht aus Datei »%s« lesen: %m" + +#: initdb.c:1504 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "Passwortdatei »%s« ist leer" + +#: initdb.c:1995 +#, c-format +msgid "caught signal\n" +msgstr "Signal abgefangen\n" + +#: initdb.c:2001 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "konnte nicht an Kindprozess schreiben: %s\n" + +#: initdb.c:2009 +#, c-format +msgid "ok\n" +msgstr "ok\n" + +#: initdb.c:2099 +#, c-format +msgid "setlocale() failed" +msgstr "setlocale() fehlgeschlagen" + +#: initdb.c:2120 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "konnte alte Locale »%s« nicht wiederherstellen" + +#: initdb.c:2129 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "ungültiger Locale-Name: »%s«" + +#: initdb.c:2140 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "ungültige Locale-Einstellungen; prüfen Sie die Umgebungsvariablen LANG und LC_*" + +#: initdb.c:2167 +#, c-format +msgid "encoding mismatch" +msgstr "unpassende Kodierungen" + +#: initdb.c:2169 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"Die von Ihnen gewählte Kodierung (%s) und die von der gewählten\n" +"Locale verwendete Kodierung (%s) passen nicht zu einander. Das\n" +"würde in verschiedenen Zeichenkettenfunktionen zu Fehlverhalten\n" +"führen. Starten Sie %s erneut und geben Sie entweder keine\n" +"Kodierung explizit an oder wählen Sie eine passende Kombination.\n" + +#: initdb.c:2241 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s initialisiert einen PostgreSQL-Datenbankcluster.\n" +"\n" + +#: initdb.c:2242 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: initdb.c:2243 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPTION]... [DATENVERZEICHNIS]\n" + +#: initdb.c:2244 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Optionen:\n" + +#: initdb.c:2245 +#, c-format +msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgstr " -A, --auth=METHODE vorgegebene Authentifizierungsmethode für lokale Verbindungen\n" + +#: initdb.c:2246 +#, c-format +msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgstr "" +" --auth-host=METHODE vorgegebene Authentifizierungsmethode für lokale\n" +" TCP/IP-Verbindungen\n" + +#: initdb.c:2247 +#, c-format +msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgstr "" +" --auth-local=METHODE vorgegebene Authentifizierungsmethode für Verbindungen\n" +" auf lokalen Sockets\n" + +#: initdb.c:2248 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]DATENVERZ Datenverzeichnis für diesen Datenbankcluster\n" + +#: initdb.c:2249 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, --encoding=KODIERUNG setze Standardkodierung für neue Datenbanken\n" + +#: initdb.c:2250 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access Lese- und Ausführungsrechte am Datenverzeichnis\n" +" für Gruppe setzen\n" + +#: initdb.c:2251 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums Datenseitenprüfsummen verwenden\n" + +#: initdb.c:2252 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr " --locale=LOCALE setze Standardlocale für neue Datenbanken\n" + +#: initdb.c:2253 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" setze Standardlocale in der jeweiligen Kategorie\n" +" für neue Datenbanken (Voreinstellung aus der\n" +" Umgebung entnommen)\n" + +#: initdb.c:2257 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale entspricht --locale=C\n" + +#: initdb.c:2258 +#, c-format +msgid " --pwfile=FILE read password for the new superuser from file\n" +msgstr " --pwfile=DATEI lese Passwort des neuen Superusers aus Datei\n" + +#: initdb.c:2259 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=KFG\n" +" Standardtextsuchekonfiguration\n" + +#: initdb.c:2261 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=NAME Datenbank-Superusername\n" + +#: initdb.c:2262 +#, c-format +msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt frage nach Passwort für neuen Superuser\n" + +#: initdb.c:2263 +#, c-format +msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, --waldir=WALVERZ Verzeichnis für das Write-Ahead-Log\n" + +#: initdb.c:2264 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=ZAHL Größe eines WAL-Segments, in Megabyte\n" + +#: initdb.c:2265 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Weniger häufig verwendete Optionen:\n" + +#: initdb.c:2266 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug erzeuge eine Menge Debug-Ausgaben\n" + +#: initdb.c:2267 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L VERZEICHNIS wo sind die Eingabedateien zu finden\n" + +#: initdb.c:2268 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean nach Fehlern nicht aufräumen\n" + +#: initdb.c:2269 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: initdb.c:2270 +#, c-format +msgid " --no-instructions do not print instructions for next steps\n" +msgstr " --no-instructions Anleitung für nächste Schritte nicht ausgeben\n" + +#: initdb.c:2271 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show zeige interne Einstellungen\n" + +#: initdb.c:2272 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only nur Datenverzeichnis synchronisieren\n" + +#: initdb.c:2273 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Weitere Optionen:\n" + +#: initdb.c:2274 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: initdb.c:2275 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: initdb.c:2276 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"Wenn kein Datenverzeichnis angegeben ist, dann wird die Umgebungsvariable\n" +"PGDATA verwendet.\n" + +#: initdb.c:2278 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: initdb.c:2279 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: initdb.c:2307 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "ungültige Authentifizierungsmethode »%s« für »%s«-Verbindungen" + +#: initdb.c:2323 +#, c-format +msgid "must specify a password for the superuser to enable password authentication" +msgstr "Superuser-Passwort muss angegeben werden um Passwortauthentifizierung einzuschalten" + +#: initdb.c:2344 +#, c-format +msgid "no data directory specified" +msgstr "kein Datenverzeichnis angegeben" + +#: initdb.c:2346 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"Sie müssen das Verzeichnis angeben, wo dieses Datenbanksystem abgelegt\n" +"werden soll. Machen Sie dies entweder mit der Kommandozeilenoption -D\n" +"oder mit der Umgebungsvariable PGDATA.\n" + +#: initdb.c:2364 +#, c-format +msgid "could not set environment" +msgstr "konnte Umgebung nicht setzen" + +#: initdb.c:2384 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wird von %s benötigt, aber wurde nicht im\n" +"selben Verzeichnis wie »%s« gefunden.\n" +"Prüfen Sie Ihre Installation." + +#: initdb.c:2389 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wurde von %s gefunden,\n" +"aber es hatte nicht die gleiche Version wie %s.\n" +"Prüfen Sie Ihre Installation." + +#: initdb.c:2408 +#, c-format +msgid "input file location must be an absolute path" +msgstr "Eingabedatei muss absoluten Pfad haben" + +#: initdb.c:2425 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "Der Datenbankcluster wird mit der Locale »%s« initialisiert werden.\n" + +#: initdb.c:2428 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"Der Datenbankcluster wird mit folgenden Locales initialisiert werden:\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2452 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "konnte keine passende Kodierung für Locale »%s« finden" + +#: initdb.c:2454 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "Führen Sie %s erneut mit der Option -E aus.\n" + +#: initdb.c:2455 initdb.c:3089 initdb.c:3110 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: initdb.c:2468 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"Die von der Locale gesetzte Kodierung »%s« ist nicht als serverseitige Kodierung erlaubt.\n" +"Die Standarddatenbankkodierung wird stattdessen auf »%s« gesetzt.\n" + +#: initdb.c:2473 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "Locale »%s« benötigt nicht unterstützte Kodierung »%s«" + +#: initdb.c:2476 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"Kodierung »%s« ist nicht als serverseitige Kodierung erlaubt.\n" +"Starten Sie %s erneut mit einer anderen Locale-Wahl.\n" + +#: initdb.c:2485 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "Die Standarddatenbankkodierung wurde entsprechend auf »%s« gesetzt.\n" + +#: initdb.c:2551 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "konnte keine passende Textsuchekonfiguration für Locale »%s« finden" + +#: initdb.c:2562 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "passende Textsuchekonfiguration für Locale »%s« ist unbekannt" + +#: initdb.c:2567 +#, c-format +msgid "specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "angegebene Textsuchekonfiguration »%s« passt möglicherweise nicht zur Locale »%s«" + +#: initdb.c:2572 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "Die Standardtextsuchekonfiguration wird auf »%s« gesetzt.\n" + +#: initdb.c:2616 initdb.c:2698 +#, c-format +msgid "creating directory %s ... " +msgstr "erzeuge Verzeichnis %s ... " + +#: initdb.c:2622 initdb.c:2704 initdb.c:2769 initdb.c:2831 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" + +#: initdb.c:2633 initdb.c:2716 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "berichtige Zugriffsrechte des bestehenden Verzeichnisses %s ... " + +#: initdb.c:2639 initdb.c:2722 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "konnte Rechte des Verzeichnisses »%s« nicht ändern: %m" + +#: initdb.c:2653 initdb.c:2736 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "Verzeichnis »%s« existiert aber ist nicht leer" + +#: initdb.c:2658 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Wenn Sie ein neues Datenbanksystem erzeugen wollen, entfernen oder leeren\n" +"Sie das Verzeichnis »%s« or führen Sie %s\n" +"mit einem anderen Argument als »%s« aus.\n" + +#: initdb.c:2666 initdb.c:2748 initdb.c:3125 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" + +#: initdb.c:2689 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WAL-Verzeichnis muss absoluten Pfad haben" + +#: initdb.c:2741 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"Wenn Sie dort den WAL ablegen wollen, entfernen oder leeren Sie das\n" +"Verzeichnis »%s«.\n" + +#: initdb.c:2755 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" + +#: initdb.c:2760 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt" + +#: initdb.c:2784 +#, c-format +msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" +msgstr "Es enthält eine unsichtbare Datei (beginnt mit Punkt), vielleicht weil es ein Einhängepunkt ist.\n" + +#: initdb.c:2787 +#, c-format +msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "Es enthält ein Verzeichnis »lost+found«, vielleicht weil es ein Einhängepunkt ist.\n" + +#: initdb.c:2790 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Einen Einhängepunkt direkt als Datenverzeichnis zu verwenden wird nicht empfohlen.\n" +"Erzeugen Sie ein Unterverzeichnis unter dem Einhängepunkt.\n" + +#: initdb.c:2816 +#, c-format +msgid "creating subdirectories ... " +msgstr "erzeuge Unterverzeichnisse ... " + +#: initdb.c:2862 +msgid "performing post-bootstrap initialization ... " +msgstr "führe Post-Bootstrap-Initialisierung durch ... " + +#: initdb.c:3024 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Debug-Modus ist an.\n" + +#: initdb.c:3028 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "No-Clean-Modus ist an. Bei Fehlern wird nicht aufgeräumt.\n" + +#: initdb.c:3108 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: initdb.c:3129 initdb.c:3218 +msgid "syncing data to disk ... " +msgstr "synchronisiere Daten auf Festplatte ... " + +#: initdb.c:3138 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "Passwortprompt und Passwortdatei können nicht zusammen angegeben werden" + +#: initdb.c:3163 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "Argument von --wal-segsize muss eine Zahl sein" + +#: initdb.c:3168 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "Argument von --wal-segsize muss eine Zweierpotenz zwischen 1 und 1024 sein" + +#: initdb.c:3185 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "Superuser-Name »%s« nicht erlaubt; Rollennamen können nicht mit »pg_« anfangen" + +#: initdb.c:3189 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Die Dateien, die zu diesem Datenbanksystem gehören, werden dem Benutzer\n" +"»%s« gehören. Diesem Benutzer muss auch der Serverprozess gehören.\n" +"\n" + +#: initdb.c:3205 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Datenseitenprüfsummen sind eingeschaltet.\n" + +#: initdb.c:3207 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Datenseitenprüfsummen sind ausgeschaltet.\n" + +#: initdb.c:3224 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"Synchronisation auf Festplatte übersprungen.\n" +"Das Datenverzeichnis könnte verfälscht werden, falls das Betriebssystem abstürzt.\n" + +#: initdb.c:3229 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "Authentifizierung für lokale Verbindungen auf »trust« gesetzt" + +#: initdb.c:3230 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Sie können dies ändern, indem Sie pg_hba.conf bearbeiten oder beim\n" +"nächsten Aufruf von initdb die Option -A, oder --auth-local und\n" +"--auth-host, verwenden.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3260 +msgid "logfile" +msgstr "logdatei" + +#: initdb.c:3262 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"Erfolg. Sie können den Datenbankserver jetzt mit\n" +"\n" +" %s\n" +"\n" +"starten.\n" +"\n" diff --git a/src/bin/initdb/po/el.po b/src/bin/initdb/po/el.po new file mode 100644 index 000000000000..c5c41a8ff35d --- /dev/null +++ b/src/bin/initdb/po/el.po @@ -0,0 +1,1018 @@ +# Greek message translation file for initdb +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the initdb (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: initdb (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:47+0000\n" +"PO-Revision-Date: 2021-02-25 11:14+0100\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο:" + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα:" + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση:" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "δεν ήταν δυνατή η αναγνώριση του τρέχοντος καταλόγου: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "μη έγκυρο δυαδικό αρχείο “%s”" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "δεν ήταν δυνατή η ανάγνωση του δυαδικού αρχείου “%s”" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "δεν βρέθηκε το αρχείο “%s” για να εκτελεστεί" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "δεν ήταν δυνατή η μετάβαση στον κατάλογο “%s”: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του συμβολικού συνδέσμου “%s”: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s () απέτυχε: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: initdb.c:328 +#, c-format +msgid "out of memory" +msgstr "έλλειψη μνήμης" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "έλλειψη μνήμης\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "δεν ήταν δυνατή η αντιγραφή δείκτη null (εσωτερικό σφάλμα)\n" + +#: ../../common/file_utils.c:87 ../../common/file_utils.c:451 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση stat στο αρχείο “%s”: %m" + +#: ../../common/file_utils.c:166 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του καταλόγου “%s”: %m" + +#: ../../common/file_utils.c:200 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του καταλόγου “%s”: %m" + +#: ../../common/file_utils.c:232 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:365 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου “%s”: %m" + +#: ../../common/file_utils.c:303 ../../common/file_utils.c:373 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση της εντολής fsync στο αρχείο “%s”: %m" + +#: ../../common/file_utils.c:383 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "δεν ήταν δυνατή η μετονομασία του αρχείου “%s” σε “%s”: %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο του καταλόγου “%s”: %m" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "δεν ήταν δυνατή η φόρτωση της βιβλιοθήκης “%s”: κωδικός σφάλματος %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "δεν ήταν δυνατή η δημιουργία διακριτικών περιορισμού στην παρούσα πλατφόρμα: κωδικός σφάλματος %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "δεν ήταν δυνατό το άνοιγμα διακριτικού διεργασίας: κωδικός σφάλματος %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "δεν ήταν δυνατή η εκχώρηση SID: κωδικός σφάλματος %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "δεν ήταν δυνατή η δημιουργία διακριτικού διεργασίας: κωδικός σφάλματος %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "δεν ήταν δυνατή η εκκίνηση διεργασίας για την εντολή “%s”: κωδικός σφάλματος %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "δεν ήταν δυνατή η επανεκκίνηση με διακριτικό περιορισμού: κωδικός σφάλματος %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "δεν ήταν δυνατή η απόκτηση κωδικού εξόδου από την υποδιεργασία: κωδικός σφάλματος %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση stat στο αρχείο ή κατάλογο “%s”: %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η αφαίρεση αρχείου ή καταλόγου “%s”: %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "δεν ήταν δυνατή η αναζήτηση ενεργής ταυτότητας χρήστη %ld: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "ο χρήστης δεν υπάρχει" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "αποτυχία αναζήτησης ονόματος χρήστη: κωδικός σφάλματος % lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "εντολή μη εκτελέσιμη" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "εντολή δεν βρέθηκε" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "απόγονος διεργασίας τερμάτισε με κωδικό εξόδου %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "απόγονος διεργασίας τερματίστηκε με εξαίρεση 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "απόγονος διεργασίας τερματίστηκε με σήμα %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "απόγονος διεργασίας τερμάτισε με μη αναγνωρίσιμη κατάσταση %d" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "δεν ήταν δυνατός ο ορισμός διασταύρωσης για “%s”: %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "δεν ήταν δυνατή η απόκτηση διασταύρωσης για “%s”: %s\n" + +#: initdb.c:461 initdb.c:1493 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου “%s” για ανάγνωση: %m" + +#: initdb.c:505 initdb.c:827 initdb.c:853 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου “%s” για εγγραφή: %m" + +#: initdb.c:512 initdb.c:519 initdb.c:833 initdb.c:858 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εγγραφή αρχείου “%s”: %m" + +#: initdb.c:537 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση της εντολής “%s”: %m" + +#: initdb.c:555 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "αφαιρείται ο κατάλογος δεδομένων “%s”" + +#: initdb.c:557 +#, c-format +msgid "failed to remove data directory" +msgstr "απέτυχε η αφαίρεση καταλόγου δεδομένων" + +#: initdb.c:561 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "αφαιρούνται περιεχόμενα του καταλόγου δεδομένων “%s”" + +#: initdb.c:564 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "απέτυχε η αφαίρεση περιεχομένων του καταλόγου δεδομένων" + +#: initdb.c:569 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "αφαίρεση καταλόγου WAL “%s”" + +#: initdb.c:571 +#, c-format +msgid "failed to remove WAL directory" +msgstr "απέτυχε η αφαίρεση καταλόγου WAL" + +#: initdb.c:575 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "αφαιρούνται τα περιεχόμενα του καταλόγου WAL “%s”" + +#: initdb.c:577 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "απέτυχε η αφαίρεση περιεχόμενων του καταλόγου WAL" + +#: initdb.c:584 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "ο κατάλογος δεδομένων “%s” δεν αφαιρείται κατα απαίτηση του χρήστη" + +#: initdb.c:588 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "κατάλογος WAL “%s” δεν αφαιρέθηκε κατά απαίτηση του χρήστη" + +#: initdb.c:606 +#, c-format +msgid "cannot be run as root" +msgstr "δεν δύναται η εκτέλεση ως υπερχρήστης" + +#: initdb.c:608 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Παρακαλώ συνδεθείτε (χρησιμοποιώντας, π.χ. την εντολή “su”) ως ο (μη προνομιούχος) χρήστης που θα\n" +"είναι κάτοχος της διεργασίας του διακομιστή.\n" + +#: initdb.c:641 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "“%s” δεν είναι έγκυρο όνομα κωδικοποίησης διακομιστή" + +#: initdb.c:786 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "το αρχείο “%s” δεν υπάρχει" + +#: initdb.c:788 initdb.c:795 initdb.c:804 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"Αυτό μπορεί να σημαίνει ότι έχετε μια κατεστραμμένη εγκατάσταση ή\n" +"ορίσατε λάθος κατάλογο με την επιλογή επίκλησης -L.\n" + +#: initdb.c:793 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "δεν ήταν δυνατή η πρόσβαση του αρχείο “%s”: %m" + +#: initdb.c:802 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "το αρχείο “%s” δεν είναι ένα κανονικό αρχείο" + +#: initdb.c:947 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "επιλογή εφαρμογής δυναμικής κοινόχρηστης μνήμης ... " + +#: initdb.c:956 +#, c-format +msgid "selecting default max_connections ... " +msgstr "επιλογή προκαθορισμένης τιμής max_connections … " + +#: initdb.c:987 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "επιλογή προκαθορισμένης τιμής shared_buffers … " + +#: initdb.c:1021 +#, c-format +msgid "selecting default time zone ... " +msgstr "επιλογή προκαθορισμένης ζώνης ώρας … " + +#: initdb.c:1055 +msgid "creating configuration files ... " +msgstr "δημιουργία αρχείων ρύθμισης … " + +#: initdb.c:1214 initdb.c:1233 initdb.c:1319 initdb.c:1334 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "δεν ήταν δυνατή η αλλαγή δικαιωμάτων του “%s”: %m" + +#: initdb.c:1356 +#, c-format +msgid "running bootstrap script ... " +msgstr "εκτέλεση σεναρίου bootstrap … " + +#: initdb.c:1368 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "το αρχείο εισόδου “%s” δεν ανήκει στην PostgreSQL %s" + +#: initdb.c:1371 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "Ελέγξτε την εγκατάστασή σας ή καθορίστε τη σωστή διαδρομή χρησιμοποιώντας την επιλογή -L.\n" + +#: initdb.c:1470 +msgid "Enter new superuser password: " +msgstr "Εισάγετε νέο κωδικό πρόσβασης υπερχρήστη: " + +#: initdb.c:1471 +msgid "Enter it again: " +msgstr "Εισάγετε ξανά: " + +#: initdb.c:1474 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Οι κωδικοί πρόσβασης δεν είναι ίδιοι.\n" + +#: initdb.c:1501 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση κωδικού πρόσβασης από το αρχείο “%s”: %m" + +#: initdb.c:1504 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "αρχείο κωδικών πρόσβασης “%s” είναι άδειο" + +#: initdb.c:1995 +#, c-format +msgid "caught signal\n" +msgstr "συνελήφθει σήμα\n" + +#: initdb.c:2001 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "δεν ήταν δυνατή η εγγραφή στην απογονική διεργασία: %s\n" + +#: initdb.c:2009 +#, c-format +msgid "ok\n" +msgstr "εντάξει\n" + +#: initdb.c:2099 +#, c-format +msgid "setlocale() failed" +msgstr "εντολή setlocale() απέτυχε" + +#: initdb.c:2120 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "απέτυχε να επαναφέρει την παλαιά εντοπιότητα “%s”" + +#: initdb.c:2129 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "άκυρη ονομασία εντοπιότητας “%s”" + +#: initdb.c:2140 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "μη έγκυρες ρυθμίσεις εντοπιότητας, ελέγξτε τις μεταβλητές περιβάλλοντος LANG και LC_*" + +#: initdb.c:2167 +#, c-format +msgid "encoding mismatch" +msgstr "αναντιστοιχία κωδικοποίησης" + +#: initdb.c:2169 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"Η κωδικοποίηση που επιλέξατε (%s) και η κωδικοποίηση που\n" +"χρησιμοποιείται από την επιλεγμένη εντοπιότητα (%s) δεν ταιριάζουν. Αυτό θα οδηγούσε σε\n" +"κακή συμπεριφορά σε διάφορες συναρτήσεις επεξεργασίας συμβολοσειρών χαρακτήρων.\n" +"Επανεκτελέστε %s και είτε μην καθορίσετε ρητά κωδικοποίηση,\n" +"ή επιλέξτε έναν ταιριαστό συνδυασμό.\n" + +#: initdb.c:2241 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s αρχικοποιεί μία συστάδα PostgreSQL βάσης δεδομένων.\n" +"\n" + +#: initdb.c:2242 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: initdb.c:2243 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [ΕΠΙΛΟΓΕΣ]… [DATADIR]\n" + +#: initdb.c:2244 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Επιλογές:\n" + +#: initdb.c:2245 +#, c-format +msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgstr " -A, —auth=METHOD προκαθορισμένη μέθοδος ταυτοποίησης για τοπικές συνδέσεις\n" + +#: initdb.c:2246 +#, c-format +msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgstr " —auth-host=METHOD προκαθορισμένη μέθοδος ταυτοποίησης για τοπικές συνδέσεις πρωτοκόλλου TCP/IP\n" + +#: initdb.c:2247 +#, c-format +msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgstr " —auth-local=METHOD προκαθορισμένη μέθοδος ταυτοποίησης για συνδέσεις τοπικής υποδοχής\n" + +#: initdb.c:2248 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, —pgdata=]DATADIR τοποθεσία για αυτή τη συστάδα βάσης δεδομένων\n" + +#: initdb.c:2249 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, —encoding=ENCODING όρισε την προκαθορισμένη κωδικοποίηση για καινούριες βάσεις δεδομένων\n" + +#: initdb.c:2250 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr " -g, —allow-group-access επέτρεψε εγγραφή/ανάγνωση για την ομάδα στο κατάλογο δεδομένων\n" + +#: initdb.c:2251 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, —data-checksums χρησιμοποίησε αθροίσματα ελέγχου σελίδων δεδομένων\n" + +#: initdb.c:2252 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr " —locale=LOCALE όρισε την προκαθορισμένη εντοπιότητα για καινούριες βάσεις δεδομένων\n" + +#: initdb.c:2253 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category for\n" +" new databases (default taken from environment)\n" +msgstr "" +" —lc-collate=, —lc-ctype=, —lc-messages=LOCALE\n" +" —lc-monetary=, —lc-numeric=, —lc-time=LOCALE\n" +" όρισε την προκαθορισμένη εντοπιότητα για τις σχετικές κατηγορίες\n" +" καινούριων βάσεων δεδομένων (προκαθορισμένη τιμή διαβάζεται από το περιβάλλον)\n" + +#: initdb.c:2257 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " —no-locale ισοδύναμο με —locale=C\n" + +#: initdb.c:2258 +#, c-format +msgid " --pwfile=FILE read password for the new superuser from file\n" +msgstr " —pwfile=FILE διάβασε τον κωδικό πρόσβασης για τον νέο υπερχρήστη από το αρχείο\n" + +#: initdb.c:2259 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, —text-search-config=CFG\n" +" προκαθορισμένη ρύθμιση αναζήτησης κειμένου\n" + +#: initdb.c:2261 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, —username=NAME όνομα υπερχρήστη βάσης δεδομένων\n" + +#: initdb.c:2262 +#, c-format +msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, —pwprompt προτροπή για κωδικό πρόσβασης για τον νέο υπερχρήστη\n" + +#: initdb.c:2263 +#, c-format +msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, —waldir=WALDIR τοποθεσία για τον κατάλογο write-ahead log\n" + +#: initdb.c:2264 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " —wal-segsize=SIZE μέγεθος των τμημάτων WAL, σε megabytes\n" + +#: initdb.c:2265 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Λιγότερο συχνά χρησιμοποιούμενες επιλογές:\n" + +#: initdb.c:2266 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, —debug δημιούργησε πολλές καταγραφές αποσφαλμάτωσης\n" + +#: initdb.c:2267 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L DIRECTORY τοποθεσία εύρεσης αρχείων εισόδου\n" + +#: initdb.c:2268 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, —no-clean να μην καθαριστούν σφάλματα\n" + +#: initdb.c:2269 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, —no-sync να μην αναμένει την ασφαλή εγγραφή αλλαγών στον δίσκο\n" + +#: initdb.c:2270 +#, fuzzy, c-format +#| msgid " --no-subscriptions do not restore subscriptions\n" +msgid " --no-instructions do not print instructions for next steps\n" +msgstr " —no-publications να μην επαναφέρεις συνδρομές\n" + +#: initdb.c:2271 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, —show δείξε τις εσωτερικές ρυθμίσεις\n" + +#: initdb.c:2272 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, —sync-only συγχρόνισε μόνο τον κατάλογο δεδομένων\n" + +#: initdb.c:2273 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Άλλες επιλογές:\n" + +#: initdb.c:2274 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version δείξε πληροφορίες έκδοσης και έξοδος\n" + +#: initdb.c:2275 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help δείξε αυτό το μήνυμα βοήθειας και μετά έξοδος\n" + +#: initdb.c:2276 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"Εάν δεν έχει καθοριστεί ο κατάλογος δεδομένων, χρησιμοποιείται η\n" +"μεταβλητή περιβάλλοντος PGDATA.\n" + +#: initdb.c:2278 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: initdb.c:2279 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: initdb.c:2307 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "μη έγκυρη μέθοδος ταυτοποίησης “%s” για συνδέσεις “%s”" + +#: initdb.c:2323 +#, fuzzy, c-format +#| msgid "must specify a password for the superuser to enable %s authentication" +msgid "must specify a password for the superuser to enable password authentication" +msgstr "απαιτείται ο καθορισμός κωδικού πρόσβασης για τον υπερχρήστη για να την ενεργοποίηση του ελέγχου ταυτότητας %s" + +#: initdb.c:2344 +#, c-format +msgid "no data directory specified" +msgstr "δεν ορίστηκε κατάλογος δεδομένων" + +#: initdb.c:2346 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"Πρέπει να προσδιορίσετε τον κατάλογο όπου θα αποθηκεύονται τα δεδομένα για αυτό\n" +"το σύστημα βάσης δεδομένων. Αυτό μπορείτε να το κάνετε είτε με την επιλογή κλήσης -D\n" +"ή με τη μεταβλητή περιβάλλοντος PGDATA.\n" + +#: initdb.c:2364 +#, fuzzy, c-format +#| msgid "could not get server version" +msgid "could not set environment" +msgstr "δεν ήταν δυνατή η απόκτηση έκδοσης διακομιστή" + +#: initdb.c:2384 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Το πρόγραμμα \"%s\" απαιτείται από %s αλλά δεν βρέθηκε στο\n" +"ίδιος κατάλογος με το \"%s\".\n" +"Ελέγξτε την εγκατάστασή σας." + +#: initdb.c:2389 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Το πρόγραμμα \"%s\" βρέθηκε από το \"%s\"\n" +"αλλά δεν ήταν η ίδια εκδοχή με %s.\n" +"Ελέγξτε την εγκατάστασή σας." + +#: initdb.c:2408 +#, c-format +msgid "input file location must be an absolute path" +msgstr "η τοποθεσία του αρχείου εισόδου πρέπει να είναι μία πλήρης διαδρομή" + +#: initdb.c:2425 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "Η συστάδα βάσης δεδομένων θα αρχικοποιηθεί με εντοπιότητα “%s”.\n" + +#: initdb.c:2428 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"Η συστάδα βάσης δεδομένων θα αρχικοποιηθεί με εντοπιότητες\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2452 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "δεν μπόρεσε να βρεθεί κατάλληλη κωδικοποίηση για την εντοπιότητα “%s”" + +#: initdb.c:2454 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "Επανεκτελέστε %s με την επιλογή -E.\n" + +#: initdb.c:2455 initdb.c:3089 initdb.c:3110 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: initdb.c:2468 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"Η κωδικοποίηση \"%s\" που υπονοείται από τις τοπικές ρυθμίσεις δεν επιτρέπεται ως κωδικοποίηση από την πλευρά του διακομιστή.\n" +"Η προεπιλεγμένη κωδικοποίηση βάσης δεδομένων θα οριστεί σε \"%s\".\n" + +#: initdb.c:2473 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "εντοπιότητα “%s” προαπαιτεί τη μην υποστηριζόμενη κωδικοποίηση“%s”" + +#: initdb.c:2476 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"Η κωδικοποίηση \"%s\" δεν επιτρέπεται ως κωδικοποίηση από την πλευρά του διακομιστή.\n" +"Επανεκτελέστε %s με διαφορετική επιλογή εντοπιότητας.\n" + +#: initdb.c:2485 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "Η προεπιλεγμένη κωδικοποίηση βάσης δεδομένων έχει οριστεί ως \"%s\".\n" + +#: initdb.c:2551 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "δεν ήταν δυνατή η εύρεση κατάλληλων ρυθμίσεων για την μηχανή αναζήτησης για την εντοπιότητα “%s”" + +#: initdb.c:2562 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "οι κατάλληλες ρυθμίσεις για την μηχανή αναζήτησης για την εντοπιότητα “%s” δεν είναι γνωστές" + +#: initdb.c:2567 +#, c-format +msgid "specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "η ορισμένη ρύθμιση μηχανής αναζήτησης “%s” μπορεί να μην ταιριάζει με την εντοπιότητα “%s”" + +#: initdb.c:2572 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "Η προκαθορισμένη ρύθμιση μηχανής αναζήτησης θα οριστεί ως “%s”.\n" + +#: initdb.c:2616 initdb.c:2698 +#, c-format +msgid "creating directory %s ... " +msgstr "δημιουργία καταλόγου %s …" + +#: initdb.c:2622 initdb.c:2704 initdb.c:2769 initdb.c:2831 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η δημιουργία του καταλόγου “%s”: %m" + +#: initdb.c:2633 initdb.c:2716 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "διορθώνονται τα δικαιώματα του υπάρχοντος καταλόγου %s … " + +#: initdb.c:2639 initdb.c:2722 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η αλλαγή δικαιωμάτων του καταλόγου “%s”: %m" + +#: initdb.c:2653 initdb.c:2736 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "ο κατάλογος “%s” υπάρχει και δεν είναι άδειος" + +#: initdb.c:2658 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Εάν θέλετε να δημιουργήσετε ένα νέο σύστημα βάσης δεδομένων, διαγράψτε ή αδειάστε\n" +"τον κατάλογο \"%s\" ή εκτελέστε %s\n" +"με διαφορετική παράμετρο από \"%s\".\n" + +#: initdb.c:2666 initdb.c:2748 initdb.c:3125 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η πρόσβαση του καταλόγου “%s”: %m" + +#: initdb.c:2689 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "η τοποθεσία του καταλόγου WAL πρέπει να είναι μία πλήρης διαδρομή" + +#: initdb.c:2741 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"Εάν θέλετε να αποθηκεύσετε το WAL εκεί, είτε αφαιρέστε ή αδειάστε τον κατάλογο\n" +"\"%s\".\n" + +#: initdb.c:2755 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "δεν ήταν δυνατή η δημιουργία του συμβολικού συνδέσμου “%s”: %m" + +#: initdb.c:2760 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "συμβολικοί σύνδεσμοι δεν υποστηρίζονται στην παρούσα πλατφόρμα" + +#: initdb.c:2784 +#, c-format +msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" +msgstr "Περιέχει ένα αρχείο με πρόθεμα κουκκίδας/αόρατο, ίσως λόγω του ότι είναι ένα σημείο προσάρτησης.\n" + +#: initdb.c:2787 +#, c-format +msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "Περιέχει έναν κατάλογο lost+found, ίσως επειδή είναι ένα σημείο προσάρτησης.\n" + +#: initdb.c:2790 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Δεν προτείνεται η άμεση χρήση ενός σημείου προσάρτησης ως καταλόγου δεδομένων.\n" +"Δημιουργείστε έναν υποκατάλογο υπό του σημείου προσάρτησης.\n" + +#: initdb.c:2816 +#, c-format +msgid "creating subdirectories ... " +msgstr "δημιουργία υποκαταλόγων …" + +#: initdb.c:2862 +msgid "performing post-bootstrap initialization ... " +msgstr "πραγματοποίηση σταδίου αρχικοποίησης post-bootstrap … " + +#: initdb.c:3024 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Εκτέλεση σε λειτουργία αποσφαλμάτωσης.\n" + +#: initdb.c:3028 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "Εκτέλεση σε λειτουργία μη καθαρισμού. Τα σφάλματα δεν θα καθαριστούν.\n" + +#: initdb.c:3108 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (ο πρώτη είναι η “%s”)" + +#: initdb.c:3129 initdb.c:3218 +msgid "syncing data to disk ... " +msgstr "συγχρονίζονται δεδομένα στο δίσκο … " + +#: initdb.c:3138 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "η προτροπή κωδικού εισόδου και το αρχείο κωδικού εισόδου δεν δύναται να οριστούν ταυτόχρονα" + +#: initdb.c:3163 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "η παράμετρος —wal-segsize πρέπει να είναι αριθμός" + +#: initdb.c:3168 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "η παράμετρος —wal-segsize πρέπει να έχει τιμή δύναμης 2 μεταξύ 1 και 1024" + +#: initdb.c:3185 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "το όνομα υπερχρήστη “%s” δεν επιτρέπεται, τα ονόματα ρόλων δεν δύναται να αρχίζουν με “pg_”" + +#: initdb.c:3189 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Τα αρχεία που ανήκουν σε αυτό το σύστημα βάσης δεδομένων θα ανήκουν στο χρήστη \"%s\".\n" +"Αυτός ο χρήστης πρέπει επίσης να κατέχει τη διαδικασία διακομιστή.\n" +"\n" + +#: initdb.c:3205 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Τα αθροίσματα ελέγχου σελίδων δεδομένων είναι ενεργοποιημένα.\n" + +#: initdb.c:3207 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Τα αθροίσματα ελέγχου των σελίδων δεδομένων είναι απενεργοποιημένα.\n" + +#: initdb.c:3224 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"Ο συγχρονισμός με το δίσκο παραλείφθηκε.\n" +"Ο κατάλογος δεδομένων ενδέχεται να αλλοιωθεί εάν καταρρεύσει το λειτουργικού συστήματος.\n" + +#: initdb.c:3229 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "ενεργοποιείται η μέθοδος ταυτοποίησης “trust” για τοπικές συνδέσεις" + +#: initdb.c:3230 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Μπορείτε να το αλλάξετε αυτό με την επεξεργασία pg_hba.conf ή χρησιμοποιώντας την επιλογή -A, ή\n" +"--auth-τοπικό και --auth-host, την επόμενη φορά που θα εκτελέσετε initdb.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3260 +msgid "logfile" +msgstr "logfile" + +#: initdb.c:3262 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"Επιτυχία. Μπορείτε τώρα να εκκινήσετε τον διακομιστή βάσης δεδομένων χρησιμοποιώντας:\n" +"\n" +" %s\n" +"\n" + +#~ msgid "pclose failed: %m" +#~ msgstr "απέτυχε η εντολή pclose: %m" diff --git a/src/bin/initdb/po/es.po b/src/bin/initdb/po/es.po new file mode 100644 index 000000000000..deb8505a0e43 --- /dev/null +++ b/src/bin/initdb/po/es.po @@ -0,0 +1,1036 @@ +# Spanish translation of initdb. +# +# Copyright (c) 2004-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Álvaro Herrera , 2004-2013 +# Carlos Chapi , 2014-2021 +# +msgid "" +msgstr "" +"Project-Id-Version: initdb (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:47+0000\n" +"PO-Revision-Date: 2021-05-19 22:22-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "el binario «%s» no es válido" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "no se pudo leer el binario «%s»" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "no se pudo encontrar un «%s» para ejecutar" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() falló: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: initdb.c:328 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../../common/file_utils.c:87 ../../common/file_utils.c:451 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: ../../common/file_utils.c:166 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: ../../common/file_utils.c:200 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" + +#: ../../common/file_utils.c:232 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:365 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: ../../common/file_utils.c:303 ../../common/file_utils.c:373 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" + +#: ../../common/file_utils.c:383 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "no se pudo renombrar el archivo de «%s» a «%s»: %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "no se pudo cargar la biblioteca «%s»: código de error %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "no se pueden crear tokens restrigidos en esta plataforma: código de error %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "no se pudo abrir el token de proceso: código de error %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "no se pudo emplazar los SIDs: código de error %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "no se pudo crear el token restringido: código de error %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "no se pudo iniciar el proceso para la orden «%s»: código de error %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "no se pudo re-ejecutar con el token restringido: código de error %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "no se pudo obtener el código de salida del subproceso»: código de error %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "no se pudo hacer stat al archivo o directorio «%s»: %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "no se pudo borrar el archivo o el directorio «%s»: %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "no se pudo buscar el ID de usuario efectivo %ld: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "el usuario no existe" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "fallo en la búsqueda de nombre de usuario: código de error %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "la orden no es ejecutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "orden no encontrada" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "el proceso hijo terminó con código de salida %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "el proceso hijo fue terminado por una excepción 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "el proceso hijo terminó con código no reconocido %d" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "no se pudo definir un junction para «%s»: %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "no se pudo obtener junction para «%s»: %s\n" + +#: initdb.c:461 initdb.c:1493 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" + +#: initdb.c:505 initdb.c:827 initdb.c:853 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "no se pudo abrir el archivo «%s» para escritura: %m" + +#: initdb.c:512 initdb.c:519 initdb.c:833 initdb.c:858 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" + +#: initdb.c:537 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "no se pudo ejecutar la orden «%s»: %m" + +#: initdb.c:555 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "eliminando el directorio de datos «%s»" + +#: initdb.c:557 +#, c-format +msgid "failed to remove data directory" +msgstr "no se pudo eliminar el directorio de datos" + +#: initdb.c:561 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "eliminando el contenido del directorio «%s»" + +#: initdb.c:564 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "no se pudo eliminar el contenido del directorio de datos" + +#: initdb.c:569 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "eliminando el directorio de WAL «%s»" + +#: initdb.c:571 +#, c-format +msgid "failed to remove WAL directory" +msgstr "no se pudo eliminar el directorio de WAL" + +#: initdb.c:575 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "eliminando el contenido del directorio de WAL «%s»" + +#: initdb.c:577 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "no se pudo eliminar el contenido del directorio de WAL" + +#: initdb.c:584 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "directorio de datos «%s» no eliminado a petición del usuario" + +#: initdb.c:588 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "directorio de WAL «%s» no eliminado a petición del usuario" + +#: initdb.c:606 +#, c-format +msgid "cannot be run as root" +msgstr "no se puede ejecutar como «root»" + +#: initdb.c:608 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Por favor conéctese (usando, por ejemplo, «su») con un usuario no privilegiado,\n" +"quien ejecutará el proceso servidor.\n" + +#: initdb.c:641 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "«%s» no es un nombre válido de codificación" + +#: initdb.c:786 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "el archivo «%s» no existe" + +#: initdb.c:788 initdb.c:795 initdb.c:804 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"Esto puede significar que tiene una instalación corrupta o ha\n" +"identificado el directorio equivocado con la opción -L.\n" + +#: initdb.c:793 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "no se pudo acceder al archivo «%s»: %m" + +#: initdb.c:802 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "el archivo «%s» no es un archivo regular" + +#: initdb.c:947 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "seleccionando implementación de memoria compartida dinámica ... " + +#: initdb.c:956 +#, c-format +msgid "selecting default max_connections ... " +msgstr "seleccionando el valor para max_connections ... " + +#: initdb.c:987 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "seleccionando el valor para shared_buffers ... " + +#: initdb.c:1021 +#, c-format +msgid "selecting default time zone ... " +msgstr "seleccionando el huso horario por omisión ... " + +#: initdb.c:1055 +msgid "creating configuration files ... " +msgstr "creando archivos de configuración ... " + +#: initdb.c:1214 initdb.c:1233 initdb.c:1319 initdb.c:1334 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "no se pudo cambiar los permisos de «%s»: %m" + +#: initdb.c:1356 +#, c-format +msgid "running bootstrap script ... " +msgstr "ejecutando script de inicio (bootstrap) ... " + +#: initdb.c:1368 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "el archivo de entrada «%s» no pertenece a PostgreSQL %s" + +#: initdb.c:1371 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "Verifique su instalación o especifique la ruta correcta usando la opción -L.\n" + +#: initdb.c:1470 +msgid "Enter new superuser password: " +msgstr "Ingrese la nueva contraseña del superusuario: " + +#: initdb.c:1471 +msgid "Enter it again: " +msgstr "Ingrésela nuevamente: " + +#: initdb.c:1474 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Las constraseñas no coinciden.\n" + +#: initdb.c:1501 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "no se pudo leer la contraseña desde el archivo «%s»: %m" + +#: initdb.c:1504 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "el archivo de contraseña «%s» está vacío" + +#: initdb.c:1995 +#, c-format +msgid "caught signal\n" +msgstr "se ha capturado una señal\n" + +#: initdb.c:2001 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "no se pudo escribir al proceso hijo: %s\n" + +#: initdb.c:2009 +#, c-format +msgid "ok\n" +msgstr "hecho\n" + +#: initdb.c:2099 +#, c-format +msgid "setlocale() failed" +msgstr "setlocale() falló" + +#: initdb.c:2120 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "no se pudo restaurar la configuración regional anterior «%s»" + +#: initdb.c:2129 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "nombre de configuración regional «%s» no es válido" + +#: initdb.c:2140 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "configuración regional inválida; revise las variables de entorno LANG y LC_*" + +#: initdb.c:2167 +#, c-format +msgid "encoding mismatch" +msgstr "codificaciones no coinciden" + +#: initdb.c:2169 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"La codificación que seleccionó (%s) y la codificación de la configuración\n" +"regional elegida (%s) no coinciden. Esto llevaría a comportamientos\n" +"erráticos en ciertas funciones de procesamiento de cadenas de caracteres.\n" +"Ejecute %s nuevamente y no especifique una codificación, o bien especifique\n" +"una combinación adecuada.\n" + +#: initdb.c:2241 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s inicializa un cluster de base de datos PostgreSQL.\n" +"\n" + +#: initdb.c:2242 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: initdb.c:2243 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPCIÓN]... [DATADIR]\n" + +#: initdb.c:2244 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Opciones:\n" + +#: initdb.c:2245 +#, c-format +msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgstr "" +" -A, --auth=MÉTODO método de autentificación por omisión para\n" +" conexiones locales\n" + +#: initdb.c:2246 +#, c-format +msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgstr "" +" --auth-host=MÉTODO método de autentificación por omisión para\n" +" conexiones locales TCP/IP\n" + +#: initdb.c:2247 +#, c-format +msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgstr "" +" --auth-local=MÉTODO método de autentificación por omisión para\n" +" conexiones de socket local\n" + +#: initdb.c:2248 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]DATADIR ubicación para este cluster de bases de datos\n" + +#: initdb.c:2249 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, --encoding=CODIF codificación por omisión para nuevas bases de datos\n" + +#: initdb.c:2250 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access dar al grupo permisos de lectura/ejecución sobre\n" +" el directorio de datos\n" + +#: initdb.c:2251 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums activar sumas de verificación en páginas de datos\n" + +#: initdb.c:2252 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr "" +" --locale=LOCALE configuración regional por omisión para \n" +" nuevas bases de datos\n" + +#: initdb.c:2253 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" inicializar usando esta configuración regional\n" +" en la categoría respectiva (el valor por omisión\n" +" es tomado de variables de ambiente)\n" + +#: initdb.c:2257 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale equivalente a --locale=C\n" + +#: initdb.c:2258 +#, c-format +msgid " --pwfile=FILE read password for the new superuser from file\n" +msgstr " --pwfile=ARCHIVO leer contraseña del nuevo superusuario del archivo\n" + +#: initdb.c:2259 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=CONF\n" +" configuración de búsqueda en texto por omisión\n" + +#: initdb.c:2261 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=USUARIO nombre del superusuario del cluster\n" + +#: initdb.c:2262 +#, c-format +msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt pedir una contraseña para el nuevo superusuario\n" + +#: initdb.c:2263 +#, c-format +msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, --waldir=WALDIR ubicación del directorio WAL\n" + +#: initdb.c:2264 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=TAMAÑO tamaño de los segmentos de WAL, en megabytes\n" + +#: initdb.c:2265 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Opciones menos usadas:\n" + +#: initdb.c:2266 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug genera mucha salida de depuración\n" + +#: initdb.c:2267 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L DIRECTORIO donde encontrar los archivos de entrada\n" + +#: initdb.c:2268 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean no limpiar después de errores\n" + +#: initdb.c:2269 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: initdb.c:2270 +#, c-format +msgid " --no-instructions do not print instructions for next steps\n" +msgstr " --no-instructions no mostrar instrucciones para los siguientes pasos\n" + +#: initdb.c:2271 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show muestra variables internas\n" + +#: initdb.c:2272 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only sólo sincronizar el directorio de datos\n" + +#: initdb.c:2273 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Otras opciones:\n" + +#: initdb.c:2274 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de version y salir\n" + +#: initdb.c:2275 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: initdb.c:2276 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"Si el directorio de datos no es especificado, se usa la variable de\n" +"ambiente PGDATA.\n" + +#: initdb.c:2278 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: initdb.c:2279 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: initdb.c:2307 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "método de autentificación «%s» no válido para conexiones «%s»" + +#: initdb.c:2323 +#, c-format +msgid "must specify a password for the superuser to enable password authentication" +msgstr "debe especificar una contraseña al superusuario para activar autentificación mediante contraseña" + +#: initdb.c:2344 +#, c-format +msgid "no data directory specified" +msgstr "no se especificó un directorio de datos" + +#: initdb.c:2346 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"Debe especificar el directorio donde residirán los datos para este clúster.\n" +"Hágalo usando la opción -D o la variable de ambiente PGDATA.\n" + +#: initdb.c:2364 +#, c-format +msgid "could not set environment" +msgstr "no se pudo establecer el ambiente" + +#: initdb.c:2384 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%s necesita el programa «%s», pero no pudo encontrarlo en el mismo\n" +"directorio que «%s».\n" +"Verifique su instalación." + +#: initdb.c:2389 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"El programa «%s» fue encontrado por «%s»,\n" +"pero no es de la misma versión que %s.\n" +"Verifique su instalación." + +#: initdb.c:2408 +#, c-format +msgid "input file location must be an absolute path" +msgstr "la ubicación de archivos de entrada debe ser una ruta absoluta" + +#: initdb.c:2425 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "El cluster será inicializado con configuración regional «%s».\n" + +#: initdb.c:2428 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"El cluster será inicializado con las configuraciones regionales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2452 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "" +"no se pudo encontrar una codificación apropiada para\n" +"la configuración regional «%s»" + +#: initdb.c:2454 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "Ejecute %s con la opción -E.\n" + +#: initdb.c:2455 initdb.c:3089 initdb.c:3110 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Use «%s --help» para obtener mayor información.\n" + +#: initdb.c:2468 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"La codificación «%s», implícita en la configuración regional,\n" +"no puede ser usada como codificación del lado del servidor.\n" +"La codificación por omisión será «%s».\n" + +#: initdb.c:2473 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "la configuración regional «%s» requiere la codificación no soportada «%s»" + +#: initdb.c:2476 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"La codificación «%s» no puede ser usada como codificación del lado\n" +"del servidor.\n" +"Ejecute %s nuevamente con una selección de configuración regional diferente.\n" + +#: initdb.c:2485 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "La codificación por omisión ha sido por lo tanto definida a «%s».\n" + +#: initdb.c:2551 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "" +"no se pudo encontrar una configuración para búsqueda en texto apropiada\n" +"para la configuración regional «%s»" + +#: initdb.c:2562 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "la configuración de búsqueda en texto apropiada para la configuración regional «%s» es desconocida" + +#: initdb.c:2567 +#, c-format +msgid "specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "la configuración de búsqueda en texto «%s» especificada podría no coincidir con la configuración regional «%s»" + +#: initdb.c:2572 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "La configuración de búsqueda en texto ha sido definida a «%s».\n" + +#: initdb.c:2616 initdb.c:2698 +#, c-format +msgid "creating directory %s ... " +msgstr "creando el directorio %s ... " + +#: initdb.c:2622 initdb.c:2704 initdb.c:2769 initdb.c:2831 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" + +#: initdb.c:2633 initdb.c:2716 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "corrigiendo permisos en el directorio existente %s ... " + +#: initdb.c:2639 initdb.c:2722 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "no se pudo cambiar los permisos del directorio «%s»: %m" + +#: initdb.c:2653 initdb.c:2736 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "el directorio «%s» existe pero no está vacío" + +#: initdb.c:2658 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Si quiere crear un nuevo cluster de bases de datos, elimine o vacíe\n" +"el directorio «%s», o ejecute %s\n" +"con un argumento distinto de «%s».\n" + +#: initdb.c:2666 initdb.c:2748 initdb.c:3125 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "no se pudo acceder al directorio «%s»: %m" + +#: initdb.c:2689 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "la ubicación del directorio de WAL debe ser una ruta absoluta" + +#: initdb.c:2741 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"Si quiere almacenar el WAL ahí, elimine o vacíe el directorio\n" +"«%s».\n" + +#: initdb.c:2755 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "no se pudo crear el enlace simbólico «%s»: %m" + +#: initdb.c:2760 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "los enlaces simbólicos no están soportados en esta plataforma" + +#: initdb.c:2784 +#, c-format +msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" +msgstr "Contiene un archivo invisible, quizás por ser un punto de montaje.\n" + +#: initdb.c:2787 +#, c-format +msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "Contiene un directorio lost+found, quizás por ser un punto de montaje.\n" + +#: initdb.c:2790 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Usar un punto de montaje directamente como directorio de datos no es\n" +"recomendado. Cree un subdirectorio bajo el punto de montaje.\n" + +#: initdb.c:2816 +#, c-format +msgid "creating subdirectories ... " +msgstr "creando subdirectorios ... " + +#: initdb.c:2862 +msgid "performing post-bootstrap initialization ... " +msgstr "realizando inicialización post-bootstrap ... " + +#: initdb.c:3024 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Ejecutando en modo de depuración.\n" + +#: initdb.c:3028 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "Ejecutando en modo no-clean. Los errores no serán limpiados.\n" + +#: initdb.c:3108 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: initdb.c:3129 initdb.c:3218 +msgid "syncing data to disk ... " +msgstr "sincronizando los datos a disco ... " + +#: initdb.c:3138 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "" +"la petición de contraseña y el archivo de contraseña no pueden\n" +"ser especificados simultáneamente" + +#: initdb.c:3163 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "el argumento de --wal-segsize debe ser un número" + +#: initdb.c:3168 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "el argumento de --wal-segsize debe ser una potencia de 2 entre 1 y 1024" + +#: initdb.c:3185 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "nombre de superusuario «%s» no permitido; los nombres de rol no pueden comenzar con «pg_»" + +#: initdb.c:3189 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Los archivos de este cluster serán de propiedad del usuario «%s».\n" +"Este usuario también debe ser quien ejecute el proceso servidor.\n" +"\n" + +#: initdb.c:3205 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Las sumas de verificación en páginas de datos han sido activadas.\n" + +#: initdb.c:3207 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Las sumas de verificación en páginas de datos han sido desactivadas.\n" + +#: initdb.c:3224 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"La sincronización a disco se ha omitido.\n" +"El directorio de datos podría corromperse si el sistema operativo sufre\n" +"una caída.\n" + +#: initdb.c:3229 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "activando el método de autentificación «trust» para conexiones locales" + +#: initdb.c:3230 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Puede cambiar esto editando pg_hba.conf o usando el parámetro -A,\n" +"o --auth-local y --auth-host la próxima vez que ejecute initdb.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3260 +msgid "logfile" +msgstr "archivo_de_registro" + +#: initdb.c:3262 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"Completado. Ahora puede iniciar el servidor de bases de datos usando:\n" +"\n" +" %s\n" +"\n" + +#~ msgid "pclose failed: %m" +#~ msgstr "pclose falló: %m" diff --git a/src/bin/initdb/po/fr.po b/src/bin/initdb/po/fr.po new file mode 100644 index 000000000000..8566b394e1be --- /dev/null +++ b/src/bin/initdb/po/fr.po @@ -0,0 +1,1251 @@ +# translation of initdb.po to fr_fr +# french message translation file for initdb +# +# Use these quotes: « %s » +# +# Guillaume Lelarge , 2004-2009. +# Stéphane Schildknecht , 2009. +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-26 06:48+0000\n" +"PO-Revision-Date: 2021-04-26 11:36+0200\n" +"Last-Translator: Guillaume Lelarge \n" +"Language-Team: PostgreSQLfr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "binaire « %s » invalide" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "n'a pas pu lire le binaire « %s »" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "n'a pas pu trouver un « %s » à exécuter" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "échec de %s() : %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: initdb.c:328 +#, c-format +msgid "out of memory" +msgstr "mémoire épuisée" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" + +#: ../../common/file_utils.c:87 ../../common/file_utils.c:451 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "n'a pas pu tester le fichier « %s » : %m" + +#: ../../common/file_utils.c:166 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" + +#: ../../common/file_utils.c:200 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "n'a pas pu lire le répertoire « %s » : %m" + +#: ../../common/file_utils.c:232 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:365 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier « %s » : %m" + +#: ../../common/file_utils.c:303 ../../common/file_utils.c:373 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m" + +#: ../../common/file_utils.c:383 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "n'a pas pu renommer le fichier « %s » en « %s » : %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "n'a pas pu fermer le répertoire « %s » : %m" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "n'a pas pu charger la bibliothèque « %s » : code d'erreur %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "ne peut pas créer les jetons restreints sur cette plateforme : code d'erreur %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "n'a pas pu ouvrir le jeton du processus : code d'erreur %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "n'a pas pu allouer les SID : code d'erreur %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "n'a pas pu créer le jeton restreint : code d'erreur %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "n'a pas pu démarrer le processus pour la commande « %s » : code d'erreur %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "n'a pas pu ré-exécuter le jeton restreint : code d'erreur %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "n'a pas pu récupérer le code de statut du sous-processus : code d'erreur %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "" +"n'a pas pu récupérer les informations sur le fichier ou répertoire\n" +"« %s » : %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier ou répertoire « %s » : %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "n'a pas pu trouver l'identifiant réel %ld de l'utilisateur : %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "l'utilisateur n'existe pas" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "échec de la recherche du nom d'utilisateur : code erreur %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "commande non exécutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "commande introuvable" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "le processus fils a quitté avec le code de sortie %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "le processus fils a été terminé par l'exception 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "le processus fils a été terminé par le signal %d : %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "le processus fils a quitté avec un statut %d non reconnu" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "n'a pas pu configurer la jonction pour « %s » : %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "n'a pas pu obtenir la jonction pour « %s » : %s\n" + +#: initdb.c:461 initdb.c:1493 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %m" + +#: initdb.c:505 initdb.c:827 initdb.c:853 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » en écriture : %m" + +#: initdb.c:512 initdb.c:519 initdb.c:833 initdb.c:858 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "impossible d'écrire le fichier « %s » : %m" + +#: initdb.c:537 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "n'a pas pu exécuter la commande « %s » : %m" + +#: initdb.c:555 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "suppression du répertoire des données « %s »" + +#: initdb.c:557 +#, c-format +msgid "failed to remove data directory" +msgstr "échec de la suppression du répertoire des données" + +#: initdb.c:561 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "suppression du contenu du répertoire des données « %s »" + +#: initdb.c:564 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "échec de la suppression du contenu du répertoire des données" + +#: initdb.c:569 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "suppression du répertoire des journaux de transactions « %s »" + +#: initdb.c:571 +#, c-format +msgid "failed to remove WAL directory" +msgstr "échec de la suppression du répertoire des journaux de transactions" + +#: initdb.c:575 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "suppression du contenu du répertoire des journaux de transactions « %s »" + +#: initdb.c:577 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "échec de la suppression du contenu du répertoire des journaux de transactions" + +#: initdb.c:584 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "répertoire des données « %s » non supprimé à la demande de l'utilisateur" + +#: initdb.c:588 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "répertoire des journaux de transactions « %s » non supprimé à la demande de l'utilisateur" + +#: initdb.c:606 +#, c-format +msgid "cannot be run as root" +msgstr "ne peut pas être exécuté en tant que root" + +#: initdb.c:608 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Connectez-vous (par exemple en utilisant « su ») sous l'utilisateur (non\n" +" privilégié) qui sera propriétaire du processus serveur.\n" + +#: initdb.c:641 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "« %s » n'est pas un nom d'encodage serveur valide" + +#: initdb.c:786 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "le rôle « %s » n'existe pas" + +#: initdb.c:788 initdb.c:795 initdb.c:804 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"Cela peut signifier que votre installation est corrompue ou que vous avez\n" +"identifié le mauvais répertoire avec l'option -L.\n" + +#: initdb.c:793 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "n'a pas pu accéder au fichier « %s » : %m" + +#: initdb.c:802 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "le fichier « %s » n'est pas un fichier standard" + +#: initdb.c:947 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "sélection de l'implémentation de la mémoire partagée dynamique..." + +#: initdb.c:956 +#, c-format +msgid "selecting default max_connections ... " +msgstr "sélection de la valeur par défaut pour max_connections... " + +#: initdb.c:987 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "sélection de la valeur par défaut pour shared_buffers... " + +#: initdb.c:1021 +#, c-format +msgid "selecting default time zone ... " +msgstr "sélection du fuseau horaire par défaut... " + +#: initdb.c:1055 +msgid "creating configuration files ... " +msgstr "création des fichiers de configuration... " + +#: initdb.c:1214 initdb.c:1233 initdb.c:1319 initdb.c:1334 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "n'a pas pu modifier les droits de « %s » : %m" + +#: initdb.c:1356 +#, c-format +msgid "running bootstrap script ... " +msgstr "lancement du script bootstrap..." + +#: initdb.c:1368 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "le fichier en entrée « %s » n'appartient pas à PostgreSQL %s" + +#: initdb.c:1371 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "Vérifiez votre installation ou indiquez le bon chemin avec l'option -L.\n" + +#: initdb.c:1470 +msgid "Enter new superuser password: " +msgstr "Saisissez le nouveau mot de passe du super-utilisateur : " + +#: initdb.c:1471 +msgid "Enter it again: " +msgstr "Saisissez-le à nouveau : " + +#: initdb.c:1474 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Les mots de passe ne sont pas identiques.\n" + +#: initdb.c:1501 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "n'a pas pu lire le mot de passe à partir du fichier « %s » : %m" + +#: initdb.c:1504 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "le fichier de mots de passe « %s » est vide" + +#: initdb.c:1995 +#, c-format +msgid "caught signal\n" +msgstr "signal reçu\n" + +#: initdb.c:2001 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "n'a pas pu écrire au processus fils : %s\n" + +#: initdb.c:2009 +#, c-format +msgid "ok\n" +msgstr "ok\n" + +#: initdb.c:2099 +#, c-format +msgid "setlocale() failed" +msgstr "échec de setlocale()" + +#: initdb.c:2120 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "a échoué pour restaurer l'ancienne locale « %s »" + +#: initdb.c:2129 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "nom de locale « %s » invalide" + +#: initdb.c:2140 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "configuration invalide de la locale ; vérifiez les variables d'environnement LANG et LC_*" + +#: initdb.c:2167 +#, c-format +msgid "encoding mismatch" +msgstr "différence d'encodage" + +#: initdb.c:2169 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"L'encodage que vous avez sélectionné (%s) et celui que la locale\n" +"sélectionnée utilise (%s) ne sont pas compatibles. Cela peut conduire à\n" +"des erreurs dans les fonctions de manipulation de chaînes de caractères.\n" +"Ré-exécutez %s sans préciser d'encodage, ou en choisissant une combinaison\n" +"compatible.\n" + +#: initdb.c:2241 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s initialise un cluster PostgreSQL.\n" +"\n" + +#: initdb.c:2242 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: initdb.c:2243 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPTION]... [RÉP_DONNÉES]\n" + +#: initdb.c:2244 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Options :\n" + +#: initdb.c:2245 +#, c-format +msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgstr "" +" -A, --auth=MÉTHODE méthode d'authentification par défaut pour les\n" +" connexions locales\n" + +#: initdb.c:2246 +#, c-format +msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgstr "" +" --auth-host=MÉTHODE méthode d'authentification par défaut pour les\n" +" connexions locales TCP/IP\n" + +#: initdb.c:2247 +#, c-format +msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgstr "" +" --auth-local=MÉTHODE méthode d'authentification par défaut pour les\n" +" connexions locales socket\n" + +#: initdb.c:2248 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]RÉP_DONNÉES emplacement du cluster\n" + +#: initdb.c:2249 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr "" +" -E, --encoding=ENCODAGE initialise l'encodage par défaut des nouvelles\n" +" bases de données\n" + +#: initdb.c:2250 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access autorise la lecture/écriture pour le groupe sur\n" +" le répertoire des données\n" + +#: initdb.c:2251 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums utilise les sommes de contrôle pour les pages de données\n" + +#: initdb.c:2252 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr "" +" --locale=LOCALE initialise la locale par défaut pour les\n" +" nouvelles bases de données\n" + +#: initdb.c:2253 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" initialise la locale par défaut dans la\n" +" catégorie respective pour les nouvelles bases\n" +" de données (les valeurs par défaut sont prises\n" +" dans l'environnement)\n" + +#: initdb.c:2257 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale équivalent à --locale=C\n" + +#: initdb.c:2258 +#, c-format +msgid " --pwfile=FILE read password for the new superuser from file\n" +msgstr "" +" --pwfile=NOMFICHIER lit le mot de passe du nouveau\n" +" super-utilisateur à partir de ce fichier\n" + +#: initdb.c:2259 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=CFG\n" +" configuration par défaut de la recherche plein\n" +" texte\n" + +#: initdb.c:2261 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=NOM nom du super-utilisateur de la base de données\n" + +#: initdb.c:2262 +#, c-format +msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgstr "" +" -W, --pwprompt demande un mot de passe pour le nouveau\n" +" super-utilisateur\n" + +#: initdb.c:2263 +#, c-format +msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr "" +" -X, --waldir=RÉP_WAL emplacement du répertoire des journaux de\n" +" transactions\n" + +#: initdb.c:2264 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=TAILLE taille des segments WAL, en mégaoctets\n" + +#: initdb.c:2265 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Options moins utilisées :\n" + +#: initdb.c:2266 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug engendre un grand nombre de traces de débogage\n" + +#: initdb.c:2267 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr "" +" -L RÉPERTOIRE indique où trouver les fichiers servant à la\n" +" création du cluster\n" + +#: initdb.c:2268 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --noclean ne nettoie pas après des erreurs\n" + +#: initdb.c:2269 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --nosync n'attend pas que les modifications soient proprement écrites sur disque\n" + +#: initdb.c:2270 +#, c-format +msgid " --no-instructions do not print instructions for next steps\n" +msgstr " --no-instructions n'affiche pas les instructions des prochaines étapes\n" + +#: initdb.c:2271 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show affiche la configuration interne\n" + +#: initdb.c:2272 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only synchronise uniquement le répertoire des données\n" + +#: initdb.c:2273 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Autres options :\n" + +#: initdb.c:2274 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" + +#: initdb.c:2275 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" + +#: initdb.c:2276 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"Si le répertoire des données n'est pas indiqué, la variable d'environnement\n" +"PGDATA est utilisée.\n" + +#: initdb.c:2278 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapporter les bogues à <%s>.\n" + +#: initdb.c:2279 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil de %s : <%s>\n" + +#: initdb.c:2307 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "méthode d'authentification « %s » invalide pour « %s » connexions" + +#: initdb.c:2323 +#, c-format +msgid "must specify a password for the superuser to enable password authentication" +msgstr "doit indiquer un mot de passe pour le super-utilisateur afin d'activer l'authentification par mot de passe" + +#: initdb.c:2344 +#, c-format +msgid "no data directory specified" +msgstr "aucun répertoire de données indiqué" + +#: initdb.c:2346 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"Vous devez identifier le répertoire où résideront les données pour ce\n" +"système de bases de données. Faites-le soit avec l'option -D soit avec\n" +"la variable d'environnement PGDATA.\n" + +#: initdb.c:2364 +#, c-format +msgid "could not set environment" +msgstr "n'a pas pu configurer l'environnement" + +#: initdb.c:2384 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Le programme « %s » est nécessaire pour %s, mais n'a pas été trouvé\n" +"dans le même répertoire que « %s ».\n" +"Vérifiez votre installation." + +#: initdb.c:2389 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Le programme « %s » a été trouvé par « %s »,\n" +"mais n'est pas de la même version que %s.\n" +"Vérifiez votre installation." + +#: initdb.c:2408 +#, c-format +msgid "input file location must be an absolute path" +msgstr "l'emplacement du fichier d'entrée doit être indiqué avec un chemin absolu" + +#: initdb.c:2425 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "L'instance sera initialisée avec la locale « %s ».\n" + +#: initdb.c:2428 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"Le cluster sera initialisé avec les locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2452 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "n'a pas pu trouver un encodage adéquat pour la locale « %s »" + +#: initdb.c:2454 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "Relancez %s avec l'option -E.\n" + +#: initdb.c:2455 initdb.c:3089 initdb.c:3110 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayer « %s --help » pour plus d'informations.\n" + +#: initdb.c:2468 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"L'encodage « %s » a été déduit de la locale mais n'est pas autorisé en tant qu'encodage serveur.\n" +"L'encodage par défaut des bases de données sera configuré à « %s ».\n" + +#: initdb.c:2473 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "la locale « %s » nécessite l'encodage « %s » non supporté" + +#: initdb.c:2476 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"L'encodage « %s » n'est pas autorisé en tant qu'encodage serveur.\n" +"Ré-exécuter %s avec une locale différente.\n" + +#: initdb.c:2485 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "" +"L'encodage par défaut des bases de données a été configuré en conséquence\n" +"avec « %s ».\n" + +#: initdb.c:2551 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "n'a pas pu trouver la configuration de la recherche plein texte en adéquation avec la locale « %s »" + +#: initdb.c:2562 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "la configuration de la recherche plein texte convenable pour la locale « %s » est inconnue" + +#: initdb.c:2567 +#, c-format +msgid "specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "la configuration indiquée pour la recherche plein texte, « %s », pourrait ne pas correspondre à la locale « %s »" + +#: initdb.c:2572 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "La configuration de la recherche plein texte a été initialisée à « %s ».\n" + +#: initdb.c:2616 initdb.c:2698 +#, c-format +msgid "creating directory %s ... " +msgstr "création du répertoire %s... " + +#: initdb.c:2622 initdb.c:2704 initdb.c:2769 initdb.c:2831 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "n'a pas pu créer le répertoire « %s » : %m" + +#: initdb.c:2633 initdb.c:2716 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "correction des droits sur le répertoire existant %s... " + +#: initdb.c:2639 initdb.c:2722 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "n'a pas pu modifier les droits du répertoire « %s » : %m" + +#: initdb.c:2653 initdb.c:2736 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "le répertoire « %s » existe mais n'est pas vide" + +#: initdb.c:2658 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Si vous voulez créer un nouveau système de bases de données, supprimez ou\n" +"videz le répertoire « %s ».\n" +"Vous pouvez aussi exécuter %s avec un argument autre que « %s ».\n" + +#: initdb.c:2666 initdb.c:2748 initdb.c:3125 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "n'a pas pu accéder au répertoire « %s » : %m" + +#: initdb.c:2689 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "l'emplacement du répertoire des journaux de transactions doit être indiqué avec un chemin absolu" + +#: initdb.c:2741 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"Si vous voulez enregistrer ici le journal des transactions, supprimez ou\n" +"videz le répertoire « %s ».\n" + +#: initdb.c:2755 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "n'a pas pu créer le lien symbolique « %s » : %m" + +#: initdb.c:2760 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "les liens symboliques ne sont pas supportés sur cette plateforme" + +#: initdb.c:2784 +#, c-format +msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" +msgstr "Il contient un fichier invisible, peut-être parce qu'il s'agit d'un point de montage.\n" + +#: initdb.c:2787 +#, c-format +msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "Il contient un répertoire lost+found, peut-être parce qu'il s'agit d'un point de montage.\n" + +#: initdb.c:2790 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Utiliser un point de montage comme répertoire des données n'est pas recommandé.\n" +"Créez un sous-répertoire sous le point de montage.\n" + +#: initdb.c:2816 +#, c-format +msgid "creating subdirectories ... " +msgstr "création des sous-répertoires... " + +#: initdb.c:2862 +msgid "performing post-bootstrap initialization ... " +msgstr "exécution de l'initialisation après bootstrap... " + +#: initdb.c:3024 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Lancé en mode débogage.\n" + +#: initdb.c:3028 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "Lancé en mode « sans nettoyage ». Les erreurs ne seront pas nettoyées.\n" + +#: initdb.c:3108 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" + +#: initdb.c:3129 initdb.c:3218 +msgid "syncing data to disk ... " +msgstr "synchronisation des données sur disque... " + +#: initdb.c:3138 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "" +"les options d'invite du mot de passe et de fichier de mots de passe ne\n" +"peuvent pas être indiquées simultanément" + +#: initdb.c:3163 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "l'argument de --wal-segsize doit être un nombre" + +#: initdb.c:3168 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "l'argument de --wal-segsize doit être une puissance de 2 comprise entre 1 et 1024" + +#: initdb.c:3185 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "le nom de superutilisateur « %s » n'est pas autorisé ; les noms de rôle ne peuvent pas commencer par « pg_ »" + +#: initdb.c:3189 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Les fichiers de ce système de bases de données appartiendront à l'utilisateur « %s ».\n" +"Le processus serveur doit également lui appartenir.\n" +"\n" + +#: initdb.c:3205 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Les sommes de contrôle des pages de données sont activées.\n" + +#: initdb.c:3207 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Les sommes de contrôle des pages de données sont désactivées.\n" + +#: initdb.c:3224 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"Synchronisation sur disque ignorée.\n" +"Le répertoire des données pourrait être corrompu si le système d'exploitation s'arrêtait brutalement.\n" + +#: initdb.c:3229 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "activation de l'authentification « trust » pour les connexions locales" + +#: initdb.c:3230 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Vous pouvez changer cette configuration en éditant le fichier pg_hba.conf\n" +"ou en utilisant l'option -A, ou --auth-local et --auth-host au prochain\n" +"lancement d'initdb.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3260 +msgid "logfile" +msgstr "fichier_de_trace" + +#: initdb.c:3262 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"Succès. Vous pouvez maintenant lancer le serveur de bases de données en utilisant :\n" +"\n" +" %s\n" +"\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapporter les bogues à .\n" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu modifier le répertoire par « %s » : %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu renommer le fichier « %s » en « %s » : %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "n'a pas pu ouvrir le répertoire « %s » : %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "could not stat file or directory \"%s\": %s\n" +#~ msgstr "" +#~ "n'a pas pu récupérer les informations sur le fichier ou répertoire\n" +#~ "« %s » : %s\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s : mémoire épuisée\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » en lecture : %s\n" + +#~ msgid "%s: could not open file \"%s\" for writing: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » en écriture : %s\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu écrire le fichier « %s » : %s\n" + +#~ msgid "%s: could not execute command \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu exécuter la commande « %s » : %s\n" + +#~ msgid "%s: file \"%s\" does not exist\n" +#~ msgstr "%s : le fichier « %s » n'existe pas\n" + +#~ msgid "%s: could not access file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu accéder au fichier « %s » : %s\n" + +#~ msgid "%s: failed to restore old locale \"%s\"\n" +#~ msgstr "%s : n'a pas pu restaurer l'ancienne locale « %s »\n" + +#~ msgid "%s: invalid locale name \"%s\"\n" +#~ msgstr "%s : nom de locale invalide (« %s »)\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le répertoire « %s » : %s\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le lien symbolique « %s » : %s\n" + +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s : les liens symboliques ne sont pas supportés sur cette plateforme\n" + +#~ msgid "creating template1 database in %s/base/1 ... " +#~ msgstr "création de la base de données template1 dans %s/base/1... " + +#~ msgid "initializing pg_authid ... " +#~ msgstr "initialisation de pg_authid... " + +#~ msgid "setting password ... " +#~ msgstr "initialisation du mot de passe... " + +#~ msgid "initializing dependencies ... " +#~ msgstr "initialisation des dépendances... " + +#~ msgid "creating system views ... " +#~ msgstr "création des vues système... " + +#~ msgid "loading system objects' descriptions ... " +#~ msgstr "chargement de la description des objets système... " + +#~ msgid "creating collations ... " +#~ msgstr "création des collationnements... " + +#~ msgid "not supported on this platform\n" +#~ msgstr "non supporté sur cette plateforme\n" + +#~ msgid "creating conversions ... " +#~ msgstr "création des conversions... " + +#~ msgid "creating dictionaries ... " +#~ msgstr "création des dictionnaires... " + +#~ msgid "setting privileges on built-in objects ... " +#~ msgstr "initialisation des droits sur les objets internes... " + +#~ msgid "creating information schema ... " +#~ msgstr "création du schéma d'informations... " + +#~ msgid "loading PL/pgSQL server-side language ... " +#~ msgstr "chargement du langage PL/pgSQL... " + +#~ msgid "vacuuming database template1 ... " +#~ msgstr "lancement du vacuum sur la base de données template1... " + +#~ msgid "copying template1 to template0 ... " +#~ msgstr "copie de template1 vers template0... " + +#~ msgid "copying template1 to postgres ... " +#~ msgstr "copie de template1 vers postgres... " + +#~ msgid "%s: could not to allocate SIDs: error code %lu\n" +#~ msgstr "%s : n'a pas pu allouer les SID : code d'erreur %lu\n" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" + +#~ msgid "%s: The password file was not generated. Please report this problem.\n" +#~ msgstr "" +#~ "%s : le fichier de mots de passe n'a pas été créé.\n" +#~ "Merci de rapporter ce problème.\n" + +#~ msgid "%s: could not determine valid short version string\n" +#~ msgstr "%s : n'a pas pu déterminer une chaîne de version courte valide\n" + +#~ msgid "%s: unrecognized authentication method \"%s\"\n" +#~ msgstr "%s : méthode d'authentification « %s » inconnue.\n" + +#~ msgid "%s: could not get current user name: %s\n" +#~ msgstr "%s : n'a pas pu obtenir le nom de l'utilisateur courant : %s\n" + +#~ msgid "%s: could not obtain information about current user: %s\n" +#~ msgstr "%s : n'a pas pu obtenir d'informations sur l'utilisateur courant : %s\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu fermer le répertoire « %s » : %s\n" + +#~ msgid "Use the option \"--debug\" to see details.\n" +#~ msgstr "Utilisez l'option « --debug » pour voir le détail.\n" + +#~ msgid "No usable system locales were found.\n" +#~ msgstr "Aucune locale système utilisable n'a été trouvée.\n" + +#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" +#~ msgstr "%s : le nom de la locale contient des caractères non ASCII, ignoré : « %s »\n" + +#~ msgid "%s: locale name too long, skipped: \"%s\"\n" +#~ msgstr "%s : nom de locale trop long, ignoré : « %s »\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "" +#~ "%s : répertoire des journaux de transaction « %s » non supprimé à la demande\n" +#~ "de l'utilisateur\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s : échec de la suppression du contenu du répertoire des journaux de transaction\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s : suppression du contenu du répertoire des journaux de transaction « %s »\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s : échec de la suppression du répertoire des journaux de transaction\n" + +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s : suppression du répertoire des journaux de transaction « %s »\n" + +#~ msgid "" +#~ "The program \"postgres\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « postgres » a été trouvé par « %s » mais n'est pas de la même\n" +#~ "version que « %s ».\n" +#~ "Vérifiez votre installation." + +#~ msgid "" +#~ "The program \"postgres\" is needed by %s but was not found in the\n" +#~ "same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « postgres » est nécessaire à %s mais n'a pas été trouvé dans\n" +#~ "le même répertoire que « %s ».\n" +#~ "Vérifiez votre installation." + +#~ msgid "pclose failed: %m" +#~ msgstr "échec de pclose : %m" diff --git a/src/bin/initdb/po/ja.po b/src/bin/initdb/po/ja.po new file mode 100644 index 000000000000..420caed5af98 --- /dev/null +++ b/src/bin/initdb/po/ja.po @@ -0,0 +1,1127 @@ +# Japanese message translation file for initdb +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: initdb (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:53+0900\n" +"PO-Revision-Date: 2020-09-13 08:55+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "カレントディレクトリを特定できませんでした: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "バイナリ\"%s\"は無効です" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "バイナリ\"%s\"を読み取れませんでした" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "実行する\"%s\"がありませんでした" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "ディレクトリ\"%s\"に移動できませんでした: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pcloseが失敗しました: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: initdb.c:325 +#, c-format +msgid "out of memory" +msgstr "メモリ不足です" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ポインタを複製できません(内部エラー)。\n" + +#: ../../common/file_utils.c:84 ../../common/file_utils.c:186 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "ファイル\"%s\"のstatに失敗しました: %m" + +#: ../../common/file_utils.c:163 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: ../../common/file_utils.c:197 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m" + +#: ../../common/file_utils.c:229 ../../common/file_utils.c:288 +#: ../../common/file_utils.c:362 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: ../../common/file_utils.c:300 ../../common/file_utils.c:370 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "ファイル\"%s\"をfsyncできませんでした: %m" + +#: ../../common/file_utils.c:380 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "ライブラリ\"%s\"をロードできませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "このプラットフォームでは制限付きトークンを生成できません: エラーコード %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "プロセストークンをオープンできませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SIDを割り当てられませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "制限付きトークンを生成できませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "コマンド\"%s\"のためのプロセスを起動できませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "制限付きトークンで再実行できませんでした: %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "サブプロセスの終了コードを取得できませんでした: エラーコード %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "\"%s\"というファイルまたはディレクトリの情報を取得できませんでした。: %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "\"%s\"というファイルまたはディレクトリを削除できませんでした: %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "実効ユーザID %ld が見つかりませんでした: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "ユーザが存在しません" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "ユーザ名の参照に失敗: エラーコード %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "コマンドは実行形式ではありません" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "コマンドが見つかりません" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "子プロセスが終了コード%dで終了しました" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "子プロセスが例外0x%Xで終了しました" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "子プロセスはシグナル%dにより終了しました: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "子プロセスが未知のステータス%dで終了しました" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "\"%s\"のjunctionを設定できませんでした: %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "\"%s\"のjunctionを入手できませんでした: %s\n" + +#: initdb.c:481 initdb.c:1517 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "ファイル\"%s\"を読み取り用にオープンできませんでした: %m" + +#: initdb.c:536 initdb.c:852 initdb.c:878 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "ファイル\"%s\"を書き込み用にオープンできませんでした: %m" + +#: initdb.c:543 initdb.c:550 initdb.c:858 initdb.c:883 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "ファイル\"%s\"を書き出せませんでした: %m" + +#: initdb.c:568 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "コマンド\"%s\"を実行できませんでした: %m" + +#: initdb.c:586 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "データディレクトリ\"%s\"を削除しています" + +#: initdb.c:588 +#, c-format +msgid "failed to remove data directory" +msgstr "データディレクトリの削除に失敗しました" + +#: initdb.c:592 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "データディレクトリ\"%s\"の内容を削除しています" + +#: initdb.c:595 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "データディレクトリの内容の削除に失敗しました" + +#: initdb.c:600 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "WAL ディレクトリ\"%s\"を削除しています" + +#: initdb.c:602 +#, c-format +msgid "failed to remove WAL directory" +msgstr "WAL ディレクトリの削除に失敗しました" + +#: initdb.c:606 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "WAL ディレクトリ\"%s\"の中身を削除しています" + +#: initdb.c:608 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "WAL ディレクトリの中身の削除に失敗しました" + +#: initdb.c:615 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "ユーザの要求によりデータディレクトリ\"%s\"を削除しませんでした" + +#: initdb.c:619 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "ユーザの要求により WAL ディレクトリ\"%s\"を削除しませんでした" + +#: initdb.c:637 +#, c-format +msgid "cannot be run as root" +msgstr "root では実行できません" + +#: initdb.c:639 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"サーバプロセスの所有者となる(非特権)ユーザとして(例えば\"su\"を使用して)ログイン\n" +"してください。\n" + +#: initdb.c:672 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "\"%s\"は有効なサーバ符号化方式名ではありません" + +#: initdb.c:811 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "ファイル\"%s\"は存在しません" + +#: initdb.c:813 initdb.c:820 initdb.c:829 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"インストール先が破損しているか -L オプションで間違ったディレクトリを指定した\n" +"可能性があります。\n" + +#: initdb.c:818 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "ファイル\"%s\"にアクセスできませんでした: %m" + +#: initdb.c:827 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "ファイル\"%s\"は通常のファイルではありません" + +#: initdb.c:972 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "動的共有メモリの実装を選択しています ... " + +#: initdb.c:981 +#, c-format +msgid "selecting default max_connections ... " +msgstr "デフォルトのmax_connectionsを選択しています ... " + +#: initdb.c:1012 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "デフォルトのshared_buffersを選択しています ... " + +#: initdb.c:1046 +#, c-format +msgid "selecting default time zone ... " +msgstr "デフォルトの時間帯を選択しています ... " + +#: initdb.c:1080 +msgid "creating configuration files ... " +msgstr "設定ファイルを作成しています ... " + +#: initdb.c:1239 initdb.c:1258 initdb.c:1344 initdb.c:1359 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "\"%s\"の権限を変更できませんでした: %m" + +#: initdb.c:1381 +#, c-format +msgid "running bootstrap script ... " +msgstr "ブートストラップスクリプトを実行しています ... " + +#: initdb.c:1393 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "入力ファイル\"%s\"は PostgreSQL %s のものではありません" + +#: initdb.c:1396 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "インストール先を確認するか、-Lオプションを使用して正しいパスを指定してください。\n" + +#: initdb.c:1494 +msgid "Enter new superuser password: " +msgstr "新しいスーパユーザのパスワードを入力してください:" + +#: initdb.c:1495 +msgid "Enter it again: " +msgstr "再入力してください:" + +#: initdb.c:1498 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "パスワードが一致しません。\n" + +#: initdb.c:1524 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "ファイル\"%s\"からパスワードを読み取ることができませんでした: %m" + +#: initdb.c:1527 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "パスワードファイル\"%s\"が空です" + +#: initdb.c:2055 +#, c-format +msgid "caught signal\n" +msgstr "シグナルが発生しました\n" + +#: initdb.c:2061 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "子プロセスへの書き込みができませんでした: %s\n" + +#: initdb.c:2069 +#, c-format +msgid "ok\n" +msgstr "ok\n" + +#: initdb.c:2159 +#, c-format +msgid "setlocale() failed" +msgstr "setlocale()が失敗しました" + +#: initdb.c:2180 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "古いロケール\"%s\"を復元できませんでした" + +#: initdb.c:2189 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "ロケール名\"%s\"は不正です" + +#: initdb.c:2200 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "不正なロケール設定; 環境変数LANGおよびLC_* を確認してください" + +#: initdb.c:2227 +#, c-format +msgid "encoding mismatch" +msgstr "符号化方式が合いません" + +#: initdb.c:2229 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"選択した符号化方式(%s)と選択したロケールが使用する符号化方式(%s)が\n" +"合っていません。これにより各種の文字列処理関数が間違った動作をすることに\n" +"なります。明示的な符号化方式の指定を止めるか合致する組み合わせを\n" +"選択して %s を再実行してください\n" + +#: initdb.c:2301 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "%sはPostgreSQLデータベースクラスタを初期化します。\n" + +#: initdb.c:2302 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: initdb.c:2303 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPTION]... [DATADIR]\n" + +#: initdb.c:2304 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: initdb.c:2305 +#, c-format +msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgstr " -A, --auth=METHOD ローカル接続のデフォルト認証方式\n" + +#: initdb.c:2306 +#, c-format +msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgstr " --auth-host=METHOD ローカルTCP/IP接続のデフォルト認証方式\n" + +#: initdb.c:2307 +#, c-format +msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgstr " --auth-local=METHOD ローカルソケット接続のデフォルト認証方式\n" + +#: initdb.c:2308 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]DATADIR データベースクラスタの場所\n" + +#: initdb.c:2309 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, --encoding=ENCODING 新規データベースのデフォルト符号化方式\n" + +#: initdb.c:2310 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr " -g, --allow-group-access データディレクトリのグループ読み取り/実行を許可\n" + +#: initdb.c:2311 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr " --locale=LOCALE 新しいデータベースのデフォルトロケールをセット\n" + +#: initdb.c:2312 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate, --lc-ctype, --lc-messages=ロケール名\n" +" --lc-monetary, --lc-numeric, --lc-time=ロケール名\n" +" 新しいデータベースで使用する、おのおののカテゴリの\n" +" デフォルトロケールを設定(デフォルト値は環境変数から\n" +" 取得)\n" + +#: initdb.c:2316 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale --locale=C と同じ\n" + +#: initdb.c:2317 +#, c-format +msgid " --pwfile=FILE read password for the new superuser from file\n" +msgstr "" +" --pwfile=ファイル名 新しいスーパーユーザのパスワードをファイルから\n" +" 読み込む\n" + +#: initdb.c:2318 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=CFG\\\n" +" デフォルトのテキスト検索設定\n" + +#: initdb.c:2320 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=NAME データベーススーパーユーザの名前\n" + +#: initdb.c:2321 +#, c-format +msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt 新規スーパーユーザに対してパスワード入力を促す\n" + +#: initdb.c:2322 +#, c-format +msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, --waldir=WALDIR 先行書き込みログ用ディレクトリの位置\n" + +#: initdb.c:2323 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE WALセグメントのサイズ、メガバイト単位\n" + +#: initdb.c:2324 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"使用頻度の低いオプション:\n" + +#: initdb.c:2325 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug 多くのデバッグ用の出力を生成\n" + +#: initdb.c:2326 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums データページのチェックサムを使用\n" + +#: initdb.c:2327 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L DIRECTORY 入力ファイルの場所を指定\n" + +#: initdb.c:2328 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean エラー発生後のクリーンアップを行わない\n" + +#: initdb.c:2329 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync 変更の安全なディスクへの書き出しを待機しない\n" + +#: initdb.c:2330 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show 内部設定を表示\n" + +#: initdb.c:2331 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only データディレクトリのsyncのみを実行\n" + +#: initdb.c:2332 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"その他のオプション:\n" + +#: initdb.c:2333 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: initdb.c:2334 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: initdb.c:2335 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"データディレクトリが指定されない場合、PGDATA環境変数が使用されます。\n" + +#: initdb.c:2337 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: initdb.c:2338 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: initdb.c:2366 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "\"%2$s\"接続では認証方式\"%1$s\"は無効です" + +#: initdb.c:2382 +#, c-format +msgid "must specify a password for the superuser to enable password authentication" +msgstr "パスワード認証を有効にするにはスーパユーザのパスワードを指定する必要があります" + +#: initdb.c:2404 +#, c-format +msgid "no data directory specified" +msgstr "データディレクトリが指定されていません" + +#: initdb.c:2406 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"データベースシステムのデータを格納するディレクトリを指定する必要があります。\n" +"実行時オプション -D、もしくは、PGDATA環境変数で指定してください。\n" + +#: initdb.c:2441 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%2$sにはプログラム\"%1$s\"が必要ですが、\"%3$s\"と同じディレクトリ\n" +"にありませんでした。\n" +"インストール状況を確認してください。" + +#: initdb.c:2446 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じ\n" +"バージョンではありませんでした。\n" +"インストール状況を確認してください。" + +#: initdb.c:2465 +#, c-format +msgid "input file location must be an absolute path" +msgstr "入力ファイルの場所は絶対パスでなければなりません" + +#: initdb.c:2482 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "データベースクラスタはロケール\"%s\"で初期化されます。\n" + +#: initdb.c:2485 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"データベースクラスタは以下のロケールで初期化されます。\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2509 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "ロケール\"%s\"用に適切な符号化方式がありませんでした" + +#: initdb.c:2511 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "-Eオプションを付けて%sを再実行してください。\n" + +#: initdb.c:2512 initdb.c:3134 initdb.c:3155 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"で確認してください。\n" + +#: initdb.c:2525 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"ロケールにより暗黙的に指定される符号化方式\"%s\"はサーバ側の\n" +"符号化方式として使用できません。\n" +"デフォルトのデータベース符号化方式は代わりに\"%s\"に設定されます。\n" + +#: initdb.c:2530 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "ロケール\"%s\"は非サポートの符号化方式\"%s\"を必要とします" + +#: initdb.c:2533 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"符号化方式\"%s\"はサーバ側の符号化方式として使用できません。\n" +"別のロケールを選択して%sを再実行してください。\n" + +#: initdb.c:2542 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "デフォルトのデータベース符号化方式はそれに対応して%sに設定されました。\n" + +#: initdb.c:2604 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "ロケール\"%s\"用の適切なテキスト検索設定が見つかりませんでした" + +#: initdb.c:2615 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "ロケール\"%s\"に適したテキスト検索設定が不明です" + +#: initdb.c:2620 +#, c-format +msgid "specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "指定したテキスト検索設定\"%s\"がロケール\"%s\"に合わない可能性があります" + +#: initdb.c:2625 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "デフォルトのテキスト検索構成は %s に設定されます。\n" + +#: initdb.c:2669 initdb.c:2751 +#, c-format +msgid "creating directory %s ... " +msgstr "ディレクトリ%sを作成しています ... " + +#: initdb.c:2675 initdb.c:2757 initdb.c:2822 initdb.c:2884 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" + +#: initdb.c:2686 initdb.c:2769 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "ディレクトリ%sの権限を設定しています ... " + +#: initdb.c:2692 initdb.c:2775 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"の権限を変更できませんでした: %m" + +#: initdb.c:2706 initdb.c:2789 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "ディレクトリ\"%s\"は存在しますが、空ではありません" + +#: initdb.c:2711 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"新規にデータベースシステムを作成したいのであれば、ディレクトリ\n" +"\"%s\"を削除するか空にしてください。\n" +"または、%sを\"%s\"以外の引数で実行してください。\n" + +#: initdb.c:2719 initdb.c:2801 initdb.c:3170 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m" + +#: initdb.c:2742 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WAL ディレクトリの位置は、絶対パスでなければなりません" + +#: initdb.c:2794 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"そこにトランザクションログを格納したい場合は、ディレクトリ\"%s\"を削除するか\n" +"空にしてください。\n" + +#: initdb.c:2808 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を作成できませんでした: %m" + +#: initdb.c:2813 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "このプラットフォームでシンボリックリンクはサポートされていません" + +#: initdb.c:2837 +#, c-format +msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" +msgstr "先頭がドットまたは不可視なファイルが含まれています。マウントポイントであることが原因かもしれません\n" + +#: initdb.c:2840 +#, c-format +msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "lost+foundディレクトリが含まれています。マウントポイントであることが原因かもしれません\n" + +#: initdb.c:2843 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"マウントポイントであるディレクトリをデータディレクトリとして使用することは勧めません\n" +"マウントポイントの下にサブディレクトリを作成してください\n" + +#: initdb.c:2869 +#, c-format +msgid "creating subdirectories ... " +msgstr "サブディレクトリを作成しています ... " + +#: initdb.c:2915 +msgid "performing post-bootstrap initialization ... " +msgstr "ブートストラップ後の初期化を実行しています ... " + +#: initdb.c:3072 +#, c-format +msgid "Running in debug mode.\n" +msgstr "デバッグモードで実行しています。\n" + +#: initdb.c:3076 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "no-clean モードで実行しています。失敗した状況は削除されません。\n" + +#: initdb.c:3153 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "コマンドライン引数が多すぎます。(先頭は\"%s\")" + +#: initdb.c:3174 initdb.c:3263 +msgid "syncing data to disk ... " +msgstr "データをディスクに同期しています ... " + +#: initdb.c:3183 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "パスワードプロンプトとパスワードファイルは同時に指定できません" + +#: initdb.c:3208 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "--wal-segsize の引数は数値でなければなりません" + +#: initdb.c:3213 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "--wal-segsize のパラメータは1から1024の間の2の倍数でなければなりません" + +#: initdb.c:3230 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "スーパユーザ名\"%s\"は許可されません; ロール名は\"pg_\"で始めることはできません" + +#: initdb.c:3234 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"データベースシステム内のファイルの所有者はユーザ\"%s\"となります。\n" +"このユーザをサーバプロセスの所有者とする必要があります。\n" +"\n" + +#: initdb.c:3250 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "データページのチェックサムは有効です。\n" + +#: initdb.c:3252 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "データベージのチェックサムは無効です。\n" + +#: initdb.c:3269 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"ディスクへの同期がスキップされました。\n" +"オペレーティングシステムがクラッシュした場合データディレクトリは破損されるかもしれません。\n" + +#: initdb.c:3274 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "ローカル接続に対して\"trust\"認証を有効にします " + +#: initdb.c:3275 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"pg_hba.confを編集する、もしくは、次回initdbを実行する時に -A オプション、\n" +"あるいは --auth-local および --auth-host オプションを使用することで変更する\n" +"ことがきます。\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3300 +msgid "logfile" +msgstr "ログファイル" + +#: initdb.c:3302 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"成功しました。以下のようにしてデータベースサーバを起動することができます:\n" +"\n" +" %s\n" +"\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"をオープンできませんでした: %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"をfsyncできませんでした: %s\n" + +#~ msgid "%s: could not execute command \"%s\": %s\n" +#~ msgstr "%s: コマンド\"%s\"の実効に失敗しました: %s\n" + +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: トランザクションログディレクトリ\"%s\"を削除しています\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: トランザクションログディレクトリの削除に失敗しました\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: トランザクションログディレクトリ\"%s\"の内容を削除しています\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: トランザクションログディレクトリの内容の削除に失敗しました\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "%s: ユーザが要求したトランザクションログディレクトリ\"%s\"を削除しません\n" + +#~ msgid "%s: could not obtain information about current user: %s\n" +#~ msgstr "%s: 現在のユーザに関する情報を得ることができませんでした: %s\n" + +#~ msgid "%s: could not get current user name: %s\n" +#~ msgstr "%s: 現在のユーザ名を得ることができませんでした: %s\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"を作成できませんでした。: %s\n" + +#~ msgid "%s: file \"%s\" does not exist\n" +#~ msgstr "%s: ファイル\"%s\"がありません\n" + +#~ msgid "%s: could not access file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"にアクセスできませんでした: %s\n" + +#~ msgid "creating template1 database in %s/base/1 ... " +#~ msgstr "%s/base/1にtemplate1データベースを作成しています ... " + +#~ msgid "initializing pg_authid ... " +#~ msgstr "pg_authidを初期化しています ... " + +#~ msgid "setting password ... " +#~ msgstr "パスワードを設定しています ... " + +#~ msgid "initializing dependencies ... " +#~ msgstr "依存関係を初期化しています ... " + +#~ msgid "creating system views ... " +#~ msgstr "システムビューを作成しています ... " + +#~ msgid "loading system objects' descriptions ... " +#~ msgstr "システムオブジェクトの定義をロードしています ... " + +#~ msgid "creating collations ... " +#~ msgstr "照合順序を作成しています ... " + +#~ msgid "%s: locale name too long, skipped: \"%s\"\n" +#~ msgstr "%s: ロケール名が長過ぎますので飛ばします: \"%s\"\n" + +#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" +#~ msgstr "%s: ロケール名に非ASCII文字がありますので飛ばします: \"%s\"\n" + +#~ msgid "No usable system locales were found.\n" +#~ msgstr "使用できるシステムロケールが見つかりません\n" + +#~ msgid "Use the option \"--debug\" to see details.\n" +#~ msgstr "詳細を確認するためには\"--debug\"オプションを使用してください。\n" + +#~ msgid "not supported on this platform\n" +#~ msgstr "このプラットフォームではサポートされません\n" + +#~ msgid "creating conversions ... " +#~ msgstr "変換を作成しています ... " + +#~ msgid "creating dictionaries ... " +#~ msgstr "ディレクトリを作成しています ... " + +#~ msgid "setting privileges on built-in objects ... " +#~ msgstr "組み込みオブジェクトに権限を設定しています ... " + +#~ msgid "creating information schema ... " +#~ msgstr "情報スキーマを作成しています ... " + +#~ msgid "loading PL/pgSQL server-side language ... " +#~ msgstr "PL/pgSQL サーバサイド言語をロードしています ... " + +#~ msgid "vacuuming database template1 ... " +#~ msgstr "template1データベースをバキュームしています ... " + +#~ msgid "copying template1 to template0 ... " +#~ msgstr "template1からtemplate0へコピーしています ... " + +#~ msgid "copying template1 to postgres ... " +#~ msgstr "template1からpostgresへコピーしています ... " + +#~ msgid "%s: failed to restore old locale \"%s\"\n" +#~ msgstr "%s:古いロケール\"%s\"を戻すことができませんでした。\n" + +#~ msgid "%s: invalid locale name \"%s\"\n" +#~ msgstr "%s: ロケール名\"%s\"は無効です。\n" + +#~ msgid "%s: could not to allocate SIDs: error code %lu\n" +#~ msgstr "%s: SIDを割り当てられませんでした: エラーコード %lu\n" + +#~ msgid " -X, --xlogdir=XLOGDIR location for the transaction log directory\n" +#~ msgstr " -X, --xlogdir=XLOGDIR トランザクションログディレクトリの場所です\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"にアクセスできませんでした: %s\n" + +#~ msgid "%s: transaction log directory location must be an absolute path\n" +#~ msgstr "%s: トランザクションログのディレクトリの位置は、絶対パスでなければなりません\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: シンボリックリンク\"%s\"を作成できませんでした: %s\n" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "ディレクトリを\"%s\"に変更できませんでした" + +#~ msgid "%s: unrecognized authentication method \"%s\"\n" +#~ msgstr "%s: \"%s\"は未知の認証方式です\n" diff --git a/src/bin/initdb/po/ko.po b/src/bin/initdb/po/ko.po new file mode 100644 index 000000000000..72f9db7f21e3 --- /dev/null +++ b/src/bin/initdb/po/ko.po @@ -0,0 +1,1028 @@ +# Korean message translation file for PostgreSQL initdb +# Ioseph Kim , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: initdb (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 01:16+0000\n" +"PO-Revision-Date: 2020-10-05 17:52+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "현재 디렉터리를 알 수 없음: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "\"%s\" 파일은 잘못된 바이너리 파일입니다" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" 바이너리 파일을 읽을 수 없음" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "\"%s\" 실행 파일을 찾을 수 없음" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" 이름의 디렉터리로 이동할 수 없습니다: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "\"%s\" 심볼릭 링크 파일을 읽을 수 없음: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose 실패: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: initdb.c:325 +#, c-format +msgid "out of memory" +msgstr "메모리 부족" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null 포인터를 중복할 수 없음 (내부 오류)\n" + +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" 파일의 상태값을 알 수 없음: %m" + +#: ../../common/file_utils.c:158 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 열 수 없음: %m" + +#: ../../common/file_utils.c:192 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 읽을 수 없음: %m" + +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" 파일을 열 수 없음: %m" + +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "\"%s\" 파일 fsync 실패: %m" + +#: ../../common/file_utils.c:375 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "\"%s\" 파일을 \"%s\" 파일로 이름을 바꿀 수 없음: %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 닫을 수 없음: %m" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "\"%s\" 라이브러리를 불러 올 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "이 운영체제에서 restricted token을 만들 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "프로세스 토큰을 열 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SID를 할당할 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "제한된 토큰을 만들 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\" 명령용 프로세스를 시작할 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "제한된 토큰으로 재실행할 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "하위 프로세스의 종료 코드를 구할 수 없음: 오류 코드 %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "파일 또는 디렉터리 \"%s\"의 상태를 확인할 수 없음: %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "\"%s\" 파일 또는 디렉터리를 지울 수 없음: %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "%ld UID를 찾을 수 없음: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "사용자 없음" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "사용자 이름 찾기 실패: 오류 코드 %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "명령을 실행할 수 없음" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "해당 명령어 없음" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "하위 프로세스가 종료되었음, 종료 코드 %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "0x%X 예외로 하위 프로세스가 종료되었음." + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "하위 프로세스가 종료되었음, 시그널 %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "하위 프로세스가 종료되었음, 알수 없는 상태 %d" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "\"%s\" 파일의 연결을 설정할 수 없음: %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "\"%s\" 파일의 정션을 구할 수 없음: %s\n" + +#: initdb.c:481 initdb.c:1505 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" 파일 일기 모드로 열기 실패: %m" + +#: initdb.c:536 initdb.c:846 initdb.c:872 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "\"%s\" 파일 열기 실패: %m" + +#: initdb.c:543 initdb.c:550 initdb.c:852 initdb.c:877 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" 파일 쓰기 실패: %m" + +#: initdb.c:568 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "\"%s\" 명령을 실행할 수 없음: %m" + +#: initdb.c:586 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "\"%s\" 데이터 디렉터리를 지우는 중" + +#: initdb.c:588 +#, c-format +msgid "failed to remove data directory" +msgstr "데이터 디렉터리를 지우는데 실패" + +#: initdb.c:592 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "\"%s\" 데이터 디렉터리 안의 내용을 지우는 중" + +#: initdb.c:595 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "데이터 디렉터리 내용을 지우는데 실패" + +#: initdb.c:600 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "\"%s\" WAL 디렉터리를 지우는 중" + +#: initdb.c:602 +#, c-format +msgid "failed to remove WAL directory" +msgstr "WAL 디렉터리를 지우는데 실패" + +#: initdb.c:606 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "\"%s\" WAL 디렉터리 안의 내용을 지우는 중" + +#: initdb.c:608 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "WAL 디렉터리 내용을 지우는데 실패" + +#: initdb.c:615 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "\"%s\" 데이터 디렉터리가 사용자의 요청으로 삭제되지 않았음" + +#: initdb.c:619 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "\"%s\" WAL 디렉터리가 사용자의 요청으로 삭제되지 않았음" + +#: initdb.c:637 +#, c-format +msgid "cannot be run as root" +msgstr "root 권한으로 실행할 수 없음" + +#: initdb.c:639 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"시스템관리자 권한이 없는, 서버프로세스의 소유주가 될 일반 사용자로\n" +"로그인 해서(\"su\" 같은 명령 이용) 실행하십시오.\n" + +#: initdb.c:672 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "\"%s\" 인코딩은 서버 인코딩 이름을 사용할 수 없음" + +#: initdb.c:805 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "\"%s\" 파일 없음" + +#: initdb.c:807 initdb.c:814 initdb.c:823 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"설치가 잘못되었거나 –L 호출 옵션으로 식별한 디렉터리가\n" +"잘못되었을 수 있습니다.\n" + +#: initdb.c:812 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "\"%s\" 파일에 액세스할 수 없음: %m" + +#: initdb.c:821 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "\"%s\" 파일은 일반 파일이 아님" + +#: initdb.c:966 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "사용할 동적 공유 메모리 관리방식을 선택하는 중 ... " + +#: initdb.c:975 +#, c-format +msgid "selecting default max_connections ... " +msgstr "max_connections 초기값을 선택하는 중 ..." + +#: initdb.c:1006 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "기본 shared_buffers를 선택하는 중... " + +#: initdb.c:1040 +#, c-format +msgid "selecting default time zone ... " +msgstr "기본 지역 시간대를 선택 중 ... " + +#: initdb.c:1074 +msgid "creating configuration files ... " +msgstr "환경설정 파일을 만드는 중 ..." + +#: initdb.c:1227 initdb.c:1246 initdb.c:1332 initdb.c:1347 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "\"%s\" 접근 권한을 바꿀 수 없음: %m" + +#: initdb.c:1369 +#, c-format +msgid "running bootstrap script ... " +msgstr "부트스트랩 스크립트 실행 중 ... " + +#: initdb.c:1381 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "\"%s\" 입력 파일이 PostgreSQL %s 용이 아님" + +#: initdb.c:1384 +#, c-format +msgid "" +"Check your installation or specify the correct path using the option -L.\n" +msgstr "설치상태를 확인해 보고, -L 옵션으로 바른 경로를 지정하십시오.\n" + +#: initdb.c:1482 +msgid "Enter new superuser password: " +msgstr "새 superuser 암호를 입력하십시오:" + +#: initdb.c:1483 +msgid "Enter it again: " +msgstr "암호 확인:" + +#: initdb.c:1486 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "암호가 서로 틀립니다.\n" + +#: initdb.c:1512 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "\"%s\" 파일에서 암호를 읽을 수 없음: %m" + +#: initdb.c:1515 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "\"%s\" 패스워드 파일이 비어있음" + +#: initdb.c:2043 +#, c-format +msgid "caught signal\n" +msgstr "시스템의 간섭 신호(signal) 받았음\n" + +#: initdb.c:2049 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "하위 프로세스에 쓸 수 없음: %s\n" + +#: initdb.c:2057 +#, c-format +msgid "ok\n" +msgstr "완료\n" + +# # search5 끝 +# # advance 부분 +#: initdb.c:2147 +#, c-format +msgid "setlocale() failed" +msgstr "setlocale() 실패" + +#: initdb.c:2168 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "\"%s\" 옛 로케일을 복원할 수 없음" + +#: initdb.c:2177 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "\"%s\" 로케일 이름이 잘못됨" + +#: initdb.c:2188 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "잘못된 로케일 설정; LANG 또는 LC_* OS 환경 변수를 확인하세요" + +#: initdb.c:2215 +#, c-format +msgid "encoding mismatch" +msgstr "인코딩 불일치" + +#: initdb.c:2217 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"선택한 인코딩(%s)과 선택한 로케일에서 사용하는\n" +"인코딩(%s)이 일치하지 않습니다. 이로 인해\n" +"여러 문자열 처리 함수에 오작동이 발생할 수 있습니다.\n" +"%s을(를) 다시 실행하고 인코딩을 명시적으로 지정하지 않거나\n" +"일치하는 조합을 선택하십시오.\n" + +#: initdb.c:2289 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s PostgreSQL 데이터베이스 클러스터를 초기화 하는 프로그램.\n" +"\n" + +#: initdb.c:2290 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: initdb.c:2291 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [옵션]... [DATADIR]\n" + +#: initdb.c:2292 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"옵션들:\n" + +#: initdb.c:2293 +#, c-format +msgid "" +" -A, --auth=METHOD default authentication method for local " +"connections\n" +msgstr " -A, --auth=METHOD 로컬 연결의 기본 인증 방법\n" + +#: initdb.c:2294 +#, c-format +msgid "" +" --auth-host=METHOD default authentication method for local TCP/IP " +"connections\n" +msgstr " --auth-host=METHOD local TCP/IP 연결에 대한 기본 인증 방법\n" + +#: initdb.c:2295 +#, c-format +msgid "" +" --auth-local=METHOD default authentication method for local-socket " +"connections\n" +msgstr " --auth-local=METHOD local-socket 연결에 대한 기본 인증 방법\n" + +#: initdb.c:2296 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]DATADIR 새 데이터베이스 클러스터를 만들 디렉터리\n" + +#: initdb.c:2297 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, --encoding=ENCODING 새 데이터베이스의 기본 인코딩\n" + +#: initdb.c:2298 +#, c-format +msgid "" +" -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access 데이터 디렉터리를 그룹이 읽고 접근할 있게 함\n" + +#: initdb.c:2299 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr " --locale=LOCALE 새 데이터베이스의 기본 로케일 설정\n" + +#: initdb.c:2300 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category " +"for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" 새 데이터베이스의 각 범주에 기본 로케일 설정\n" +" (환경에서 가져온 기본 값)\n" + +#: initdb.c:2304 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale -locale=C와 같음\n" + +#: initdb.c:2305 +#, c-format +msgid "" +" --pwfile=FILE read password for the new superuser from file\n" +msgstr " --pwfile=FILE 파일에서 새 superuser의 암호 읽기\n" + +#: initdb.c:2306 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=CFG\n" +" 기본 텍스트 검색 구성\n" + +#: initdb.c:2308 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=NAME 데이터베이스 superuser 이름\n" + +#: initdb.c:2309 +#, c-format +msgid "" +" -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt 새 superuser 암호를 입력 받음\n" + +#: initdb.c:2310 +#, c-format +msgid "" +" -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, --waldir=WALDIR 트랜잭션 로그 디렉터리 위치\n" + +#: initdb.c:2311 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE WAL 조각 파일 크기, MB단위\n" + +#: initdb.c:2312 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"덜 일반적으로 사용되는 옵션들:\n" + +#: initdb.c:2313 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug 디버깅에 필요한 정보들도 함께 출력함\n" + +#: initdb.c:2314 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums 자료 페이지 체크섬 사용\n" + +#: initdb.c:2315 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L DIRECTORY 입력파일들이 있는 디렉터리\n" + +#: initdb.c:2316 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean 오류가 발생되었을 경우 그대로 둠\n" + +#: initdb.c:2317 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --no-sync 작업 완료 뒤 디스크 동기화 작업을 하지 않음\n" + +#: initdb.c:2318 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show 내부 설정값들을 보여줌\n" + +#: initdb.c:2319 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only 데이터 디렉터리만 동기화\n" + +#: initdb.c:2320 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"기타 옵션:\n" + +#: initdb.c:2321 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: initdb.c:2322 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: initdb.c:2323 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"데이터 디렉터리를 지정하지 않으면, PGDATA 환경 변수값을 사용합니다.\n" + +#: initdb.c:2325 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"문제점 보고 주소: <%s>\n" + +#: initdb.c:2326 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: initdb.c:2354 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "\"%s\" 인증 방법은 \"%s\" 연결에서는 사용할 수 없음" + +#: initdb.c:2370 +#, c-format +msgid "must specify a password for the superuser to enable %s authentication" +msgstr "%s 인증방식을 사용하려면, 반드시 superuser의 암호를 지정해야함" + +#: initdb.c:2397 +#, c-format +msgid "no data directory specified" +msgstr "데이터 디렉터리를 지정하지 않았음" + +#: initdb.c:2399 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"이 작업을 진행하려면, 반드시 이 데이터 디렉터리를 지정해 주어야합니다.\n" +"지정하는 방법은 -D 옵션의 값이나, PGDATA 환경 변수값으로 지정해 주면 됩니" +"다.\n" + +#: initdb.c:2434 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"\"%s\" 프로그램이 %s 작업에서 필요합니다. 그런데, 이 파일이\n" +"\"%s\" 파일이 있는 디렉터리안에 없습니다.\n" +"설치 상태를 확인해 주십시오." + +#: initdb.c:2439 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"%s\" 프로그램을 \"%s\" 작업 때문에 찾았지만 이 파일은\n" +"%s 프로그램의 버전과 다릅니다.\n" +"설치 상태를 확인해 주십시오." + +#: initdb.c:2458 +#, c-format +msgid "input file location must be an absolute path" +msgstr "입력 파일 위치는 반드시 절대경로여야함" + +#: initdb.c:2475 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "데이터베이스 클러스터는 \"%s\" 로케일으로 초기화될 것입니다.\n" + +#: initdb.c:2478 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"데이터베이스 클러스터는 다음 로케일으로 초기화될 것입니다.\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2502 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "\"%s\" 로케일에 알맞은 인코딩을 찾을 수 없음" + +#: initdb.c:2504 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "-E 옵션으로 %s 지정해 주십시오.\n" + +#: initdb.c:2505 initdb.c:3127 initdb.c:3148 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 자세한 정보를 보려면 \"%s --help\" 옵션을 사용하십시오.\n" + +#: initdb.c:2518 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"\"%s\" 인코딩을 서버측 인코딩으로 사용할 수 없습니다.\n" +"기본 데이터베이스는 \"%s\" 인코딩으로 지정됩니다.\n" + +#: initdb.c:2523 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "\"%s\" 로케일은 지원하지 않는 \"%s\" 인코딩을 필요로 함" + +#: initdb.c:2526 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"\"%s\" 인코딩을 서버측 인코딩으로 사용할 수 없습니다.\n" +"다른 로케일을 선택하고 %s을(를) 다시 실행하십시오.\n" + +#: initdb.c:2535 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "기본 데이터베이스 인코딩은 \"%s\" 인코딩으로 설정되었습니다.\n" + +#: initdb.c:2597 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "\"%s\" 로케일에 알맞은 전문검색 설정을 찾을 수 없음" + +#: initdb.c:2608 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "\"%s\" 로케일에 알맞은 전문검색 설정을 알 수 없음" + +#: initdb.c:2613 +#, c-format +msgid "" +"specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "지정한 \"%s\" 전문검색 설정은 \"%s\" 로케일과 일치하지 않음" + +#: initdb.c:2618 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "기본 텍스트 검색 구성이 \"%s\"(으)로 설정됩니다.\n" + +#: initdb.c:2662 initdb.c:2744 +#, c-format +msgid "creating directory %s ... " +msgstr "%s 디렉터리 만드는 중 ..." + +#: initdb.c:2668 initdb.c:2750 initdb.c:2815 initdb.c:2877 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 만들 수 없음: %m" + +#: initdb.c:2679 initdb.c:2762 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "이미 있는 %s 디렉터리의 액세스 권한을 고치는 중 ..." + +#: initdb.c:2685 initdb.c:2768 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "\"%s\" 디렉터리의 액세스 권한을 바꿀 수 없습니다: %m" + +#: initdb.c:2699 initdb.c:2782 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "\"%s\" 디렉터리가 있지만 비어 있지 않음" + +#: initdb.c:2704 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"새로운 데이터베이스 시스템을 만들려면\n" +"\"%s\" 디렉터리를 제거하거나 비우십시오. 또는 %s을(를)\n" +"\"%s\" 이외의 인수를 사용하여 실행하십시오.\n" + +#: initdb.c:2712 initdb.c:2794 initdb.c:3163 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 액세스할 수 없습니다: %m" + +#: initdb.c:2735 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WAL 디렉터리 위치는 절대 경로여야 함" + +#: initdb.c:2787 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"트랜잭션 로그를 해당 위치에 저장하려면\n" +"\"%s\" 디렉터리를 제거하거나 비우십시오.\n" + +#: initdb.c:2801 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "\"%s\" 심벌릭 링크를 만들 수 없음: %m" + +#: initdb.c:2806 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "이 플랫폼에서는 심볼 링크가 지원되지 않음" + +#: initdb.c:2830 +#, c-format +msgid "" +"It contains a dot-prefixed/invisible file, perhaps due to it being a mount " +"point.\n" +msgstr "" +"점(.)으로 시작하는 숨은 파일이 포함되어 있습니다. 마운트 최상위 디렉터리 같습" +"니다.\n" + +#: initdb.c:2833 +#, c-format +msgid "" +"It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "lost-found 디렉터리가 있습니다. 마운트 최상위 디렉터리 같습니다.\n" + +#: initdb.c:2836 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"마운트 최상위 디렉터리를 데이터 디렉터리로 사용하는 것은 권장하지 않습니다.\n" +"하위 디렉터리를 만들어서 그것을 데이터 디렉터리로 사용하세요.\n" + +#: initdb.c:2862 +#, c-format +msgid "creating subdirectories ... " +msgstr "하위 디렉터리 만드는 중 ..." + +#: initdb.c:2908 +msgid "performing post-bootstrap initialization ... " +msgstr "부트스트랩 다음 초기화 작업 중 ... " + +#: initdb.c:3065 +#, c-format +msgid "Running in debug mode.\n" +msgstr "디버그 모드로 실행 중.\n" + +#: initdb.c:3069 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "지저분 모드로 실행 중. 오류가 발생되어도 뒷정리를 안합니다.\n" + +#: initdb.c:3146 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "너무 많은 명령행 인자를 지정했습니다. (처음 \"%s\")" + +#: initdb.c:3167 initdb.c:3256 +msgid "syncing data to disk ... " +msgstr "자료를 디스크에 동기화 하는 중 ... " + +#: initdb.c:3176 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "" +"암호를 입력받는 옵션과 암호를 파일에서 가져오는 옵션은 동시에 사용될 수 없음" + +#: initdb.c:3201 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "--wal-segsize 옵션 값은 숫자여야 함" + +#: initdb.c:3206 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "--wal-segsize 옵션값은 1에서 1024사이 2^n 값이여야 함" + +#: initdb.c:3223 +#, c-format +msgid "" +"superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "" +"\"%s\" 사용자는 슈퍼유저 이름으로 쓸 수 없습니다. \"pg_\"로 시작하는롤 이름" +"은 허용하지 않음" + +#: initdb.c:3227 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"이 데이터베이스 시스템에서 만들어지는 파일들은 그 소유주가 \"%s\" id로\n" +"지정될 것입니다. 또한 이 사용자는 서버 프로세스의 소유주가 됩니다.\n" +"\n" + +#: initdb.c:3243 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "자료 페이지 체크섬 기능 사용함.\n" + +#: initdb.c:3245 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "자료 페이지 체크섬 기능 사용 하지 않음\n" + +#: initdb.c:3262 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"디스크 동기화 작업은 생략했습니다.\n" +"이 상태에서 OS가 갑자기 중지 되면 데이터 디렉토리 안에 있는 자료가 깨질 수 있" +"습니다.\n" + +#: initdb.c:3267 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "로컬 접속용 \"trust\" 인증을 설정 함" + +#: initdb.c:3268 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"이 값을 바꾸려면, pg_hba.conf 파일을 수정하든지,\n" +"다음번 initdb 명령을 사용할 때, -A 옵션 또는 --auth-local,\n" +"--auth-host 옵션을 사용해서 인증 방법을 지정할 수 있습니다.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3293 +msgid "logfile" +msgstr "로그파일" + +#: initdb.c:3295 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"작업완료. 이제 다음 명령을 이용해서 서버를 가동 할 수 있습니다:\n" +"\n" +" %s\n" +"\n" diff --git a/src/bin/initdb/po/ru.po b/src/bin/initdb/po/ru.po new file mode 100644 index 000000000000..0cfc218c9eb5 --- /dev/null +++ b/src/bin/initdb/po/ru.po @@ -0,0 +1,1161 @@ +# Russian message translation file for initdb +# Copyright (C) 2004-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Serguei A. Mokhov , 2004-2005. +# Oleg Bartunov , 2004. +# Sergey Burladyan , 2009. +# Andrey Sudnik , 2010. +# Dmitriy Olshevskiy , 2014. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: initdb (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2020-10-29 15:03+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не удалось определить текущий каталог: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "неверный исполняемый файл \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "не удалось прочитать исполняемый файл \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "не удалось найти запускаемый файл \"%s\"" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не удалось перейти в каталог \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не удалось прочитать символическую ссылку \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "ошибка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: initdb.c:325 +#, c-format +msgid "out of memory" +msgstr "нехватка памяти" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не удалось получить информацию о файле \"%s\": %m" + +#: ../../common/file_utils.c:158 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалось открыть каталог \"%s\": %m" + +#: ../../common/file_utils.c:192 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не удалось прочитать каталог \"%s\": %m" + +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" + +#: ../../common/file_utils.c:375 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "не удалось переименовать файл \"%s\" в \"%s\": %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не удалось закрыть каталог \"%s\": %m" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "не удалось загрузить библиотеку \"%s\" (код ошибки: %lu)" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "в этой ОС нельзя создавать ограниченные маркеры (код ошибки: %lu)" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "не удалось открыть маркер процесса (код ошибки: %lu)" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "не удалось подготовить структуры SID (код ошибки: %lu)" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "не удалось создать ограниченный маркер (код ошибки: %lu)" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "не удалось запустить процесс для команды \"%s\" (код ошибки: %lu)" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "не удалось перезапуститься с ограниченным маркером (код ошибки: %lu)" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "не удалось получить код выхода от подпроцесса (код ошибки: %lu)" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "не удалось получить информацию о файле или каталоге \"%s\": %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "ошибка при удалении файла или каталога \"%s\": %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "выяснить эффективный идентификатор пользователя (%ld) не удалось: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "пользователь не существует" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "распознать имя пользователя не удалось (код ошибки: %lu)" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "неисполняемая команда" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "команда не найдена" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "дочерний процесс завершился с кодом возврата %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "дочерний процесс прерван исключением 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "дочерний процесс завершён по сигналу %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "дочерний процесс завершился с нераспознанным состоянием %d" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "не удалось создать связь для каталога \"%s\": %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "не удалось получить связь для каталога \"%s\": %s\n" + +#: initdb.c:481 initdb.c:1505 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не удалось открыть файл \"%s\" для чтения: %m" + +#: initdb.c:536 initdb.c:846 initdb.c:872 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "не удалось открыть файл \"%s\" для записи: %m" + +#: initdb.c:543 initdb.c:550 initdb.c:852 initdb.c:877 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не удалось записать файл \"%s\": %m" + +#: initdb.c:568 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "не удалось выполнить команду \"%s\": %m" + +#: initdb.c:586 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "удаление каталога данных \"%s\"" + +#: initdb.c:588 +#, c-format +msgid "failed to remove data directory" +msgstr "ошибка при удалении каталога данных" + +#: initdb.c:592 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "удаление содержимого каталога данных \"%s\"" + +#: initdb.c:595 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "ошибка при удалении содержимого каталога данных" + +#: initdb.c:600 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "удаление каталога WAL \"%s\"" + +#: initdb.c:602 +#, c-format +msgid "failed to remove WAL directory" +msgstr "ошибка при удалении каталога WAL" + +#: initdb.c:606 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "удаление содержимого каталога WAL \"%s\"" + +#: initdb.c:608 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "ошибка при удалении содержимого каталога WAL" + +#: initdb.c:615 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "каталог данных \"%s\" не был удалён по запросу пользователя" + +#: initdb.c:619 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "каталог WAL \"%s\" не был удалён по запросу пользователя" + +#: initdb.c:637 +#, c-format +msgid "cannot be run as root" +msgstr "программу не должен запускать root" + +#: initdb.c:639 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Пожалуйста, переключитесь на обычного пользователя (например,\n" +"используя \"su\"), который будет запускать серверный процесс.\n" + +#: initdb.c:672 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "\"%s\" — некорректное имя серверной кодировки" + +#: initdb.c:805 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "файл \"%s\" не существует" + +#: initdb.c:807 initdb.c:814 initdb.c:823 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"Это означает, что ваша установка PostgreSQL испорчена или в параметре -L\n" +"задан неправильный каталог.\n" + +#: initdb.c:812 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "нет доступа к файлу \"%s\": %m" + +#: initdb.c:821 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "\"%s\" — не обычный файл" + +#: initdb.c:966 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "выбирается реализация динамической разделяемой памяти... " + +#: initdb.c:975 +#, c-format +msgid "selecting default max_connections ... " +msgstr "выбирается значение max_connections по умолчанию... " + +#: initdb.c:1006 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "выбирается значение shared_buffers по умолчанию... " + +#: initdb.c:1040 +#, c-format +msgid "selecting default time zone ... " +msgstr "выбирается часовой пояс по умолчанию... " + +#: initdb.c:1074 +msgid "creating configuration files ... " +msgstr "создание конфигурационных файлов... " + +#: initdb.c:1227 initdb.c:1246 initdb.c:1332 initdb.c:1347 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "не удалось поменять права для \"%s\": %m" + +#: initdb.c:1369 +#, c-format +msgid "running bootstrap script ... " +msgstr "выполняется подготовительный скрипт... " + +#: initdb.c:1381 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "входной файл \"%s\" не принадлежит PostgreSQL %s" + +#: initdb.c:1384 +#, c-format +msgid "" +"Check your installation or specify the correct path using the option -L.\n" +msgstr "" +"Проверьте правильность установки или укажите корректный путь в параметре -" +"L.\n" + +#: initdb.c:1482 +msgid "Enter new superuser password: " +msgstr "Введите новый пароль суперпользователя: " + +#: initdb.c:1483 +msgid "Enter it again: " +msgstr "Повторите его: " + +#: initdb.c:1486 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Пароли не совпадают.\n" + +#: initdb.c:1512 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "не удалось прочитать пароль из файла \"%s\": %m" + +#: initdb.c:1515 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "файл пароля \"%s\" пуст" + +#: initdb.c:2043 +#, c-format +msgid "caught signal\n" +msgstr "получен сигнал\n" + +#: initdb.c:2049 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "не удалось записать в поток дочернего процесса: %s\n" + +#: initdb.c:2057 +#, c-format +msgid "ok\n" +msgstr "ок\n" + +#: initdb.c:2147 +#, c-format +msgid "setlocale() failed" +msgstr "ошибка в setlocale()" + +#: initdb.c:2168 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "не удалось восстановить старую локаль \"%s\"" + +#: initdb.c:2177 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "ошибочное имя локали \"%s\"" + +#: initdb.c:2188 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "неверные установки локали; проверьте переменные окружения LANG и LC_*" + +#: initdb.c:2215 +#, c-format +msgid "encoding mismatch" +msgstr "несоответствие кодировки" + +#: initdb.c:2217 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"Выбранная вами кодировка (%s) не совпадает с кодировкой\n" +"локали (%s). Это может привести к неправильной работе\n" +"различных функций обработки текстовых строк.\n" +"Для исправления перезапустите %s, не указывая кодировку явно, \n" +"либо выберите подходящее сочетание параметров локализации.\n" + +#: initdb.c:2289 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s инициализирует кластер PostgreSQL.\n" +"\n" + +#: initdb.c:2290 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: initdb.c:2291 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [ПАРАМЕТР]... [КАТАЛОГ]\n" + +#: initdb.c:2292 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Параметры:\n" + +#: initdb.c:2293 +#, c-format +msgid "" +" -A, --auth=METHOD default authentication method for local " +"connections\n" +msgstr "" +" -A, --auth=МЕТОД метод проверки подлинности по умолчанию\n" +" для локальных подключений\n" + +#: initdb.c:2294 +#, c-format +msgid "" +" --auth-host=METHOD default authentication method for local TCP/IP " +"connections\n" +msgstr "" +" --auth-host=МЕТОД метод проверки подлинности по умолчанию\n" +" для локальных TCP/IP-подключений\n" + +#: initdb.c:2295 +#, c-format +msgid "" +" --auth-local=METHOD default authentication method for local-socket " +"connections\n" +msgstr "" +" --auth-local=МЕТОД метод проверки подлинности по умолчанию\n" +" для локальных подключений через сокет\n" + +#: initdb.c:2296 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]КАТАЛОГ расположение данных этого кластера БД\n" + +#: initdb.c:2297 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, --encoding=КОДИРОВКА кодировка по умолчанию для новых баз\n" + +#: initdb.c:2298 +#, c-format +msgid "" +" -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access разрешить чтение/выполнение в каталоге данных " +"для\n" +" группы\n" + +#: initdb.c:2299 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr " --locale=ЛОКАЛЬ локаль по умолчанию для новых баз\n" + +#: initdb.c:2300 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category " +"for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate=, --lc-ctype=, --lc-messages=ЛОКАЛЬ\n" +" --lc-monetary=, --lc-numeric=, --lc-time=ЛОКАЛЬ\n" +" установить соответствующий параметр локали\n" +" для новых баз (вместо значения из окружения)\n" + +#: initdb.c:2304 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale эквивалентно --locale=C\n" + +#: initdb.c:2305 +#, c-format +msgid "" +" --pwfile=FILE read password for the new superuser from file\n" +msgstr "" +" --pwfile=ФАЙЛ прочитать пароль суперпользователя из файла\n" + +#: initdb.c:2306 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=КОНФИГУРАЦИЯ\n" +" конфигурация текстового поиска по умолчанию\n" + +#: initdb.c:2308 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=ИМЯ имя суперпользователя БД\n" + +#: initdb.c:2309 +#, c-format +msgid "" +" -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt запросить пароль суперпользователя\n" + +#: initdb.c:2310 +#, c-format +msgid "" +" -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, --waldir=КАТАЛОГ расположение журнала предзаписи\n" + +#: initdb.c:2311 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=РАЗМЕР размер сегментов WAL (в мегабайтах)\n" + +#: initdb.c:2312 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Редко используемые параметры:\n" + +#: initdb.c:2313 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug выдавать много отладочных сообщений\n" + +#: initdb.c:2314 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums включить контроль целостности страниц\n" + +#: initdb.c:2315 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L КАТАЛОГ расположение входных файлов\n" + +#: initdb.c:2316 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean не очищать после ошибок\n" + +#: initdb.c:2317 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --no-sync не ждать завершения сохранения данных на диске\n" + +#: initdb.c:2318 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show показать внутренние установки\n" + +#: initdb.c:2319 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr "" +" -S, --sync-only только синхронизировать с ФС каталог данных\n" + +#: initdb.c:2320 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Другие параметры:\n" + +#: initdb.c:2321 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: initdb.c:2322 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: initdb.c:2323 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"Если каталог данных не указан, используется переменная окружения PGDATA.\n" + +#: initdb.c:2325 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: initdb.c:2326 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: initdb.c:2354 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "" +"нераспознанный метод проверки подлинности \"%s\" для подключений \"%s\"" + +#: initdb.c:2370 +#, c-format +msgid "must specify a password for the superuser to enable %s authentication" +msgstr "для применения метода %s необходимо указать пароль суперпользователя" + +#: initdb.c:2397 +#, c-format +msgid "no data directory specified" +msgstr "каталог данных не указан" + +#: initdb.c:2399 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"Вы должны указать, где будут располагаться данные этой СУБД.\n" +"Это можно сделать, добавив ключ -D или установив переменную\n" +"окружения PGDATA.\n" + +#: initdb.c:2434 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Программа \"%s\" нужна для %s, но она не найдена\n" +"в каталоге \"%s\".\n" +"Проверьте правильность установки СУБД." + +#: initdb.c:2439 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Программа \"%s\" найдена программой \"%s\",\n" +"но её версия отличается от версии %s.\n" +"Проверьте правильность установки СУБД." + +#: initdb.c:2458 +#, c-format +msgid "input file location must be an absolute path" +msgstr "расположение входных файлов должно задаваться абсолютным путём" + +#: initdb.c:2475 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "Кластер баз данных будет инициализирован с локалью \"%s\".\n" + +#: initdb.c:2478 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"Кластер баз данных будет инициализирован со следующими параметрами локали:\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2502 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "не удалось найти подходящую кодировку для локали \"%s\"" + +#: initdb.c:2504 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "Перезапустите %s с параметром -E.\n" + +#: initdb.c:2505 initdb.c:3127 initdb.c:3148 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: initdb.c:2518 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"Кодировка \"%s\", подразумеваемая локалью, не годится для сервера.\n" +"Вместо неё в качестве кодировки БД по умолчанию будет выбрана \"%s\".\n" + +#: initdb.c:2523 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "для локали \"%s\" требуется неподдерживаемая кодировка \"%s\"" + +#: initdb.c:2526 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"Кодировка \"%s\" недопустима в качестве кодировки сервера.\n" +"Перезапустите %s, выбрав другую локаль.\n" + +#: initdb.c:2535 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "" +"Кодировка БД по умолчанию, выбранная в соответствии с настройками: \"%s\".\n" + +#: initdb.c:2597 +#, c-format +msgid "could not find suitable text search configuration for locale \"%s\"" +msgstr "" +"не удалось найти подходящую конфигурацию текстового поиска для локали \"%s\"" + +#: initdb.c:2608 +#, c-format +msgid "suitable text search configuration for locale \"%s\" is unknown" +msgstr "" +"внимание: для локали \"%s\" нет известной конфигурации текстового поиска" + +#: initdb.c:2613 +#, c-format +msgid "" +"specified text search configuration \"%s\" might not match locale \"%s\"" +msgstr "" +"указанная конфигурация текстового поиска \"%s\" может не соответствовать " +"локали \"%s\"" + +#: initdb.c:2618 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "Выбрана конфигурация текстового поиска по умолчанию \"%s\".\n" + +#: initdb.c:2662 initdb.c:2744 +#, c-format +msgid "creating directory %s ... " +msgstr "создание каталога %s... " + +#: initdb.c:2668 initdb.c:2750 initdb.c:2815 initdb.c:2877 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не удалось создать каталог \"%s\": %m" + +#: initdb.c:2679 initdb.c:2762 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "исправление прав для существующего каталога %s... " + +#: initdb.c:2685 initdb.c:2768 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "не удалось поменять права для каталога \"%s\": %m" + +#: initdb.c:2699 initdb.c:2782 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "каталог \"%s\" существует, но он не пуст" + +#: initdb.c:2704 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Если вы хотите создать новую систему баз данных,\n" +"удалите или очистите каталог \"%s\",\n" +"либо при запуске %s в качестве пути укажите не \"%s\".\n" + +#: initdb.c:2712 initdb.c:2794 initdb.c:3163 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "нет доступа к каталогу \"%s\": %m" + +#: initdb.c:2735 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "расположение каталога WAL должно определяться абсолютным путём" + +#: initdb.c:2787 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"Если вы хотите хранить WAL здесь, удалите или очистите каталог\n" +"\"%s\".\n" + +#: initdb.c:2801 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "не удалось создать символическую ссылку \"%s\": %m" + +#: initdb.c:2806 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "символические ссылки не поддерживаются в этой ОС" + +#: initdb.c:2830 +#, c-format +msgid "" +"It contains a dot-prefixed/invisible file, perhaps due to it being a mount " +"point.\n" +msgstr "" +"Он содержит файл с точкой (невидимый), возможно это точка монтирования.\n" + +#: initdb.c:2833 +#, c-format +msgid "" +"It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "Он содержит подкаталог lost+found, возможно это точка монтирования.\n" + +#: initdb.c:2836 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Использовать в качестве каталога данных точку монтирования не " +"рекомендуется.\n" +"Создайте в монтируемом ресурсе подкаталог и используйте его.\n" + +#: initdb.c:2862 +#, c-format +msgid "creating subdirectories ... " +msgstr "создание подкаталогов... " + +#: initdb.c:2908 +msgid "performing post-bootstrap initialization ... " +msgstr "выполняется заключительная инициализация... " + +#: initdb.c:3065 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Программа запущена в режиме отладки.\n" + +#: initdb.c:3069 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "" +"Программа запущена в режиме 'no-clean' - очистки и исправления ошибок не " +"будет.\n" + +#: initdb.c:3146 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: initdb.c:3167 initdb.c:3256 +msgid "syncing data to disk ... " +msgstr "сохранение данных на диске... " + +#: initdb.c:3176 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "нельзя одновременно запросить пароль и прочитать пароль из файла" + +#: initdb.c:3201 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "аргументом --wal-segsize должно быть число" + +#: initdb.c:3206 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "аргументом --wal-segsize должна быть степень 2 от 1 до 1024" + +#: initdb.c:3223 +#, c-format +msgid "" +"superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "" +"имя \"%s\" для суперпользователя не допускается; имена ролей не могут " +"начинаться с \"pg_\"" + +#: initdb.c:3227 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Файлы, относящиеся к этой СУБД, будут принадлежать пользователю \"%s\".\n" +"От его имени также будет запускаться процесс сервера.\n" +"\n" + +#: initdb.c:3243 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Контроль целостности страниц данных включён.\n" + +#: initdb.c:3245 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Контроль целостности страниц данных отключён.\n" + +#: initdb.c:3262 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"Сохранение данных на диск пропускается.\n" +"Каталог данных может повредиться при сбое операционной системы.\n" + +#: initdb.c:3267 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "включение метода аутентификации \"trust\" для локальных подключений" + +#: initdb.c:3268 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Другой метод можно выбрать, отредактировав pg_hba.conf или используя ключи -" +"A,\n" +"--auth-local или --auth-host при следующем выполнении initdb.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3293 +msgid "logfile" +msgstr "файл_журнала" + +#: initdb.c:3295 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"Готово. Теперь вы можете запустить сервер баз данных:\n" +"\n" +" %s\n" +"\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: не удалось открыть каталог \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: не удалось прочитать каталог \"%s\": %s\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "дочерний процесс завершён по сигналу %s" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: нехватка памяти\n" + +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: удаление каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: ошибка при удалении каталога журнала транзакций\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: очистка каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: ошибка при очистке каталога журнала транзакций\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "" +#~ "%s: каталог журнала транзакций \"%s\" не был удалён по запросу " +#~ "пользователя\n" + +#~ msgid "%s: locale name too long, skipped: \"%s\"\n" +#~ msgstr "%s: слишком длинное имя локали, пропущено: \"%s\"\n" + +#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" +#~ msgstr "%s: имя локали содержит не ASCII-символы, пропущено: \"%s\"\n" + +#~ msgid "No usable system locales were found.\n" +#~ msgstr "Пригодные локали в системе не найдены.\n" + +#~ msgid "Use the option \"--debug\" to see details.\n" +#~ msgstr "Добавьте параметр \"--debug\", чтобы узнать подробности.\n" + +#~ msgid "creating template1 database in %s/base/1 ... " +#~ msgstr "создание базы template1 в %s/base/1... " + +#~ msgid "initializing pg_authid ... " +#~ msgstr "инициализация pg_authid... " + +#~ msgid "setting password ... " +#~ msgstr "установка пароля... " + +#~ msgid "initializing dependencies ... " +#~ msgstr "инициализация зависимостей... " + +#~ msgid "creating system views ... " +#~ msgstr "создание системных представлений... " + +#~ msgid "loading system objects' descriptions ... " +#~ msgstr "загрузка описаний системных объектов... " + +#~ msgid "creating collations ... " +#~ msgstr "создание правил сортировки... " + +#~ msgid "not supported on this platform\n" +#~ msgstr "не поддерживается в этой ОС\n" + +#~ msgid "creating conversions ... " +#~ msgstr "создание преобразований... " + +#~ msgid "creating dictionaries ... " +#~ msgstr "создание словарей... " + +#~ msgid "setting privileges on built-in objects ... " +#~ msgstr "установка прав для встроенных объектов... " + +#~ msgid "creating information schema ... " +#~ msgstr "создание информационной схемы... " + +#~ msgid "loading PL/pgSQL server-side language ... " +#~ msgstr "загрузка серверного языка PL/pgSQL... " + +#~ msgid "vacuuming database template1 ... " +#~ msgstr "очистка базы данных template1... " + +#~ msgid "copying template1 to template0 ... " +#~ msgstr "копирование template1 в template0... " + +#~ msgid "copying template1 to postgres ... " +#~ msgstr "копирование template1 в postgres... " + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: не удалось закрыть каталог \"%s\": %s\n" + +#~ msgid "%s: could not obtain information about current user: %s\n" +#~ msgstr "%s: не удалось получить информацию о текущем пользователе: %s\n" + +#~ msgid "%s: could not get current user name: %s\n" +#~ msgstr "%s: не удалось узнать имя текущего пользователя: %s\n" + +#~ msgid "Using the top-level directory of a mount point is not recommended.\n" +#~ msgstr "" +#~ "Использовать в качестве основного каталога точку монтирования не " +#~ "рекомендуется.\n" diff --git a/src/bin/initdb/po/uk.po b/src/bin/initdb/po/uk.po index 5cc3e5a0bd33..9851ac5e80d0 100644 --- a/src/bin/initdb/po/uk.po +++ b/src/bin/initdb/po/uk.po @@ -2,153 +2,160 @@ msgid "" msgstr "" "Project-Id-Version: postgresql\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-08 14:45+0000\n" -"PO-Revision-Date: 2019-12-20 20:30\n" +"POT-Creation-Date: 2020-09-21 21:16+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" "Last-Translator: pasha_golub\n" "Language-Team: Ukrainian\n" -"Language: uk_UA\n" +"Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" "X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" "X-Crowdin-Language: uk\n" -"X-Crowdin-File: /REL_12_STABLE/initdb.pot\n" +"X-Crowdin-File: /DEV_13/initdb.pot\n" +"X-Crowdin-File-ID: 484\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "збій: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "помилка: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "попередження: " -#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 #, c-format msgid "could not identify current directory: %m" msgstr "не вдалося визначити поточний каталог: %m" -#: ../../common/exec.c:157 +#: ../../common/exec.c:156 #, c-format msgid "invalid binary \"%s\"" msgstr "невірний бінарний файл \"%s\"" -#: ../../common/exec.c:207 +#: ../../common/exec.c:206 #, c-format msgid "could not read binary \"%s\"" msgstr "неможливо прочитати бінарний файл \"%s\"" -#: ../../common/exec.c:215 +#: ../../common/exec.c:214 #, c-format msgid "could not find a \"%s\" to execute" msgstr "неможливо знайти \"%s\" для виконання" -#: ../../common/exec.c:271 ../../common/exec.c:310 +#: ../../common/exec.c:270 ../../common/exec.c:309 #, c-format msgid "could not change directory to \"%s\": %m" -msgstr "не вдалося змінити каталог в \"%s\": %m" +msgstr "не вдалося змінити каталог на \"%s\": %m" -#: ../../common/exec.c:288 +#: ../../common/exec.c:287 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "не можливо прочитати символічне послання \"%s\": %m" -#: ../../common/exec.c:541 +#: ../../common/exec.c:410 #, c-format msgid "pclose failed: %m" msgstr "помилка pclose: %m" -#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 -#: initdb.c:339 +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: initdb.c:325 #, c-format msgid "out of memory" msgstr "недостатньо пам'яті" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 #, c-format msgid "out of memory\n" msgstr "недостатньо пам'яті\n" -#: ../../common/fe_memutils.c:92 +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" -#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 #, c-format msgid "could not stat file \"%s\": %m" msgstr "не вдалося отримати інформацію від файлу \"%s\": %m" -#: ../../common/file_utils.c:160 ../../common/pgfnames.c:48 +#: ../../common/file_utils.c:158 ../../common/pgfnames.c:48 #, c-format msgid "could not open directory \"%s\": %m" msgstr "не вдалося відкрити каталог \"%s\": %m" -#: ../../common/file_utils.c:194 ../../common/pgfnames.c:69 +#: ../../common/file_utils.c:192 ../../common/pgfnames.c:69 #, c-format msgid "could not read directory \"%s\": %m" msgstr "не вдалося прочитати каталог \"%s\": %m" -#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 -#: ../../common/file_utils.c:359 +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 #, c-format msgid "could not open file \"%s\": %m" msgstr "не можливо відкрити файл \"%s\": %m" -#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 #, c-format msgid "could not fsync file \"%s\": %m" -msgstr "не вдалося відкрити файл \"%s\": %m" +msgstr "не вдалося fsync файл \"%s\": %m" -#: ../../common/file_utils.c:377 +#: ../../common/file_utils.c:375 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" -msgstr "не можливо перейменувати файл \"%s\" на \"%s\": %m" +msgstr "не вдалося перейменувати файл \"%s\" на \"%s\": %m" #: ../../common/pgfnames.c:74 #, c-format msgid "could not close directory \"%s\": %m" msgstr "не вдалося закрити каталог \"%s\": %m" -#: ../../common/restricted_token.c:69 +#: ../../common/restricted_token.c:64 #, c-format -msgid "cannot create restricted tokens on this platform" -msgstr "не вдалося створити обмежені токени на цій платформі" +msgid "could not load library \"%s\": error code %lu" +msgstr "не вдалося завантажити бібліотеку \"%s\": код помилки %lu" -#: ../../common/restricted_token.c:78 +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "не вдалося створити обмежені токени на цій платформі: код помилки %lu" + +#: ../../common/restricted_token.c:82 #, c-format msgid "could not open process token: error code %lu" msgstr "не вдалося відкрити токен процесу: код помилки %lu" -#: ../../common/restricted_token.c:91 +#: ../../common/restricted_token.c:97 #, c-format msgid "could not allocate SIDs: error code %lu" msgstr "не вдалося виділити SID: код помилки %lu" -#: ../../common/restricted_token.c:110 +#: ../../common/restricted_token.c:119 #, c-format msgid "could not create restricted token: error code %lu" msgstr "не вдалося створити обмежений токен: код помилки %lu" -#: ../../common/restricted_token.c:131 +#: ../../common/restricted_token.c:140 #, c-format msgid "could not start process for command \"%s\": error code %lu" msgstr "не вдалося запустити процес для команди \"%s\": код помилки %lu" -#: ../../common/restricted_token.c:169 +#: ../../common/restricted_token.c:178 #, c-format msgid "could not re-execute with restricted token: error code %lu" msgstr "не вдалося перезапустити з обмеженим токеном: код помилки %lu" -#: ../../common/restricted_token.c:185 +#: ../../common/restricted_token.c:194 #, c-format msgid "could not get exit code from subprocess: error code %lu" msgstr "не вдалося отримати код завершення підпроцесу: код помилки %lu" @@ -217,222 +224,222 @@ msgstr "не вдалося встановити сполучення для \"% msgid "could not get junction for \"%s\": %s\n" msgstr "не вдалося встановити сполучення для \"%s\": %s\n" -#: initdb.c:495 initdb.c:1534 +#: initdb.c:481 initdb.c:1505 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "не вдалося відкрити файл \"%s\" для читання: %m" -#: initdb.c:550 initdb.c:858 initdb.c:884 +#: initdb.c:536 initdb.c:846 initdb.c:872 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "не вдалося відкрити файл \"%s\" для запису: %m" -#: initdb.c:557 initdb.c:564 initdb.c:864 initdb.c:889 +#: initdb.c:543 initdb.c:550 initdb.c:852 initdb.c:877 #, c-format msgid "could not write file \"%s\": %m" msgstr "не вдалося записати файл \"%s\": %m" -#: initdb.c:582 +#: initdb.c:568 #, c-format msgid "could not execute command \"%s\": %m" msgstr "не вдалося виконати команду \"%s\": %m" -#: initdb.c:600 +#: initdb.c:586 #, c-format msgid "removing data directory \"%s\"" msgstr "видалення даних з директорії \"%s\"" -#: initdb.c:602 +#: initdb.c:588 #, c-format msgid "failed to remove data directory" msgstr "не вдалося видалити дані директорії" -#: initdb.c:606 +#: initdb.c:592 #, c-format msgid "removing contents of data directory \"%s\"" msgstr "видалення даних з директорії \"%s\"" -#: initdb.c:609 +#: initdb.c:595 #, c-format msgid "failed to remove contents of data directory" msgstr "не вдалося видалити дані директорії" -#: initdb.c:614 +#: initdb.c:600 #, c-format msgid "removing WAL directory \"%s\"" msgstr "видалення WAL директорії \"%s\"" -#: initdb.c:616 +#: initdb.c:602 #, c-format msgid "failed to remove WAL directory" msgstr "не вдалося видалити директорію WAL" -#: initdb.c:620 +#: initdb.c:606 #, c-format msgid "removing contents of WAL directory \"%s\"" msgstr "видалення даних з директорії WAL \"%s\"" -#: initdb.c:622 +#: initdb.c:608 #, c-format msgid "failed to remove contents of WAL directory" msgstr "не вдалося видалити дані директорії WAL" -#: initdb.c:629 +#: initdb.c:615 #, c-format msgid "data directory \"%s\" not removed at user's request" msgstr "директорія даних \"%s\" не видалена за запитом користувача" -#: initdb.c:633 +#: initdb.c:619 #, c-format msgid "WAL directory \"%s\" not removed at user's request" msgstr "директорія WAL \"%s\" не видалена за запитом користувача" -#: initdb.c:651 +#: initdb.c:637 #, c-format msgid "cannot be run as root" msgstr "не може виконуватись як root" -#: initdb.c:653 +#: initdb.c:639 #, c-format msgid "Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" "own the server process.\n" msgstr "Будь ласка, увійдіть (за допомогою, наприклад, \"su\") як (непривілейований) користувач, від імені якого буде запущено серверний процес. \n" -#: initdb.c:686 +#: initdb.c:672 #, c-format msgid "\"%s\" is not a valid server encoding name" msgstr "\"%s\" невірне ім'я серверного кодування" -#: initdb.c:817 +#: initdb.c:805 #, c-format msgid "file \"%s\" does not exist" msgstr "файл \"%s\" не існує" -#: initdb.c:819 initdb.c:826 initdb.c:835 +#: initdb.c:807 initdb.c:814 initdb.c:823 #, c-format msgid "This might mean you have a corrupted installation or identified\n" "the wrong directory with the invocation option -L.\n" msgstr "Це означає, що ваша інсталяція пошкоджена або в параметрі -L задана неправильна директорія.\n" -#: initdb.c:824 +#: initdb.c:812 #, c-format msgid "could not access file \"%s\": %m" msgstr "немає доступу до файлу \"%s\": %m" -#: initdb.c:833 +#: initdb.c:821 #, c-format msgid "file \"%s\" is not a regular file" msgstr "файл \"%s\" не є звичайним файлом" -#: initdb.c:978 +#: initdb.c:966 #, c-format msgid "selecting dynamic shared memory implementation ... " msgstr "обирається реалізація динамічної спільної пам'яті ... " -#: initdb.c:987 +#: initdb.c:975 #, c-format msgid "selecting default max_connections ... " msgstr "обирається значення max_connections ... \n" " " -#: initdb.c:1018 +#: initdb.c:1006 #, c-format msgid "selecting default shared_buffers ... " msgstr "обирається значення shared_buffers... " -#: initdb.c:1052 +#: initdb.c:1040 #, c-format msgid "selecting default time zone ... " msgstr "обирається часовий пояс за замовчуванням ... " -#: initdb.c:1086 +#: initdb.c:1074 msgid "creating configuration files ... " msgstr "створення конфігураційних файлів... " -#: initdb.c:1239 initdb.c:1258 initdb.c:1344 initdb.c:1359 +#: initdb.c:1227 initdb.c:1246 initdb.c:1332 initdb.c:1347 #, c-format msgid "could not change permissions of \"%s\": %m" msgstr "неможливо змінити дозволи \"%s\": %m" -#: initdb.c:1381 +#: initdb.c:1369 #, c-format msgid "running bootstrap script ... " msgstr "виконуємо сценарій ініціалізації ... " -#: initdb.c:1393 +#: initdb.c:1381 #, c-format msgid "input file \"%s\" does not belong to PostgreSQL %s" msgstr "вхідний файл \"%s\" не належить PostgreSQL %s" -#: initdb.c:1396 +#: initdb.c:1384 #, c-format msgid "Check your installation or specify the correct path using the option -L.\n" msgstr "Перевірте вашу установку або вкажіть правильний перелік дій використання параметру-L.\n" -#: initdb.c:1511 +#: initdb.c:1482 msgid "Enter new superuser password: " msgstr "Введіть новий пароль для superuser: " -#: initdb.c:1512 +#: initdb.c:1483 msgid "Enter it again: " msgstr "Введіть знову: " -#: initdb.c:1515 +#: initdb.c:1486 #, c-format msgid "Passwords didn't match.\n" msgstr "Паролі не співпадають.\n" -#: initdb.c:1541 +#: initdb.c:1512 #, c-format msgid "could not read password from file \"%s\": %m" msgstr "не вдалося прочитати пароль з файлу \"%s\": %m" -#: initdb.c:1544 +#: initdb.c:1515 #, c-format msgid "password file \"%s\" is empty" msgstr "файл з паролями \"%s\" є порожнім" -#: initdb.c:2107 +#: initdb.c:2043 #, c-format msgid "caught signal\n" msgstr "отримано сигнал\n" -#: initdb.c:2113 +#: initdb.c:2049 #, c-format msgid "could not write to child process: %s\n" msgstr "не вдалося написати у дочірній процес: %s\n" -#: initdb.c:2121 +#: initdb.c:2057 #, c-format msgid "ok\n" msgstr "ok\n" -#: initdb.c:2211 +#: initdb.c:2147 #, c-format msgid "setlocale() failed" msgstr "setlocale() завершився невдало" -#: initdb.c:2232 +#: initdb.c:2168 #, c-format msgid "failed to restore old locale \"%s\"" msgstr "не вдалося відновити старі локалі \"%s\"" -#: initdb.c:2241 +#: initdb.c:2177 #, c-format msgid "invalid locale name \"%s\"" msgstr "не допустиме ім'я локалі \"%s\"" -#: initdb.c:2252 +#: initdb.c:2188 #, c-format msgid "invalid locale settings; check LANG and LC_* environment variables" msgstr "неприпустимі параметри локалі; перевірте LANG та LC_* змінні середовища" -#: initdb.c:2279 +#: initdb.c:2215 #, c-format msgid "encoding mismatch" msgstr "невідповідність кодування" -#: initdb.c:2281 +#: initdb.c:2217 #, c-format msgid "The encoding you selected (%s) and the encoding that the\n" "selected locale uses (%s) do not match. This would lead to\n" @@ -443,64 +450,64 @@ msgstr "Кодування, яке ви вибрали (%s), та кодуван "Це може спричинити некоректну поведінку у функціях, що обробляють символьні рядки.\n" "Перезапустіть %s і не вказуйте явне кодування або виберіть відповідну комбінацію.\n" -#: initdb.c:2353 +#: initdb.c:2289 #, c-format msgid "%s initializes a PostgreSQL database cluster.\n\n" msgstr "%s ініціалізує кластер баз даних PostgreSQL.\n\n" -#: initdb.c:2354 +#: initdb.c:2290 #, c-format msgid "Usage:\n" msgstr "Використання:\n" -#: initdb.c:2355 +#: initdb.c:2291 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [OPTION]... [DATADIR]\n" -#: initdb.c:2356 +#: initdb.c:2292 #, c-format msgid "\n" "Options:\n" msgstr "\n" "Параметри:\n" -#: initdb.c:2357 +#: initdb.c:2293 #, c-format msgid " -A, --auth=METHOD default authentication method for local connections\n" msgstr " -A, -- auth=METHOD метод аутентифікації за замовчуванням для локальних підключень\n" -#: initdb.c:2358 +#: initdb.c:2294 #, c-format msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" msgstr " --auth-host=METHOD метод аутентифікації за замовчуванням для локального TCP/IP підключення\n" -#: initdb.c:2359 +#: initdb.c:2295 #, c-format msgid " --auth-local=METHOD default authentication method for local-socket connections\n" msgstr " --auth-local=METHOD метод аутентифікації за замовчуванням для локального під'єднання через сокет\n" -#: initdb.c:2360 +#: initdb.c:2296 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D - pgdata =] DATADIR розташування кластеру цієї бази даних\n" -#: initdb.c:2361 +#: initdb.c:2297 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr " -E, --encoding=ENCODING встановлення кодування за замовчуванням для нової бази даних\n" -#: initdb.c:2362 +#: initdb.c:2298 #, c-format msgid " -g, --allow-group-access allow group read/execute on data directory\n" msgstr " -g, --allow-group-access дозволити читати/виконувати у каталозі даних для групи\n" -#: initdb.c:2363 +#: initdb.c:2299 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr " --locale=LOCALE встановлює локаль за замовчуванням для нових баз даних\n" -#: initdb.c:2364 +#: initdb.c:2300 #, c-format msgid " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" " --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" @@ -511,103 +518,103 @@ msgstr " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" " встановлення локалі за замовчуванням для відповідної категорії в\n" " нових базах даних (замість значення з середовища)\n" -#: initdb.c:2368 +#: initdb.c:2304 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale еквівалентно --locale=C\n" -#: initdb.c:2369 +#: initdb.c:2305 #, c-format msgid " --pwfile=FILE read password for the new superuser from file\n" msgstr " --pwfile=FILE прочитати пароль для нового суперкористувача з файлу\n" -#: initdb.c:2370 +#: initdb.c:2306 #, c-format msgid " -T, --text-search-config=CFG\n" " default text search configuration\n" msgstr " -T, --text-search-config=CFG конфігурація текстового пошуку за замовчуванням\n" -#: initdb.c:2372 +#: initdb.c:2308 #, c-format msgid " -U, --username=NAME database superuser name\n" msgstr " -U, --username=NAME ім'я суперкористувача бази даних\n" -#: initdb.c:2373 +#: initdb.c:2309 #, c-format msgid " -W, --pwprompt prompt for a password for the new superuser\n" msgstr " -W, --pwprompt запитувати пароль нового суперкористувача\n" -#: initdb.c:2374 +#: initdb.c:2310 #, c-format msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" msgstr " -X, --waldir=WALDIR розташування журналу попереднього запису\n" -#: initdb.c:2375 +#: initdb.c:2311 #, c-format msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" msgstr " --wal-segsize=SIZE розмір сегментів WAL у мегабайтах\n" -#: initdb.c:2376 +#: initdb.c:2312 #, c-format msgid "\n" "Less commonly used options:\n" msgstr "\n" "Рідковживані параметри:\n" -#: initdb.c:2377 +#: initdb.c:2313 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug генерувати багато налагоджувальних повідомлень\n" -#: initdb.c:2378 +#: initdb.c:2314 #, c-format msgid " -k, --data-checksums use data page checksums\n" msgstr " -k, --data-checksums використовувати контрольні суми сторінок\n" -#: initdb.c:2379 +#: initdb.c:2315 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr " -L DIRECTORY розташування вхідних файлів\n" -#: initdb.c:2380 +#: initdb.c:2316 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean не очищувати після помилок\n" " \n" -#: initdb.c:2381 +#: initdb.c:2317 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync не чекати на безпечний запис змін на диск\n" -#: initdb.c:2382 +#: initdb.c:2318 #, c-format msgid " -s, --show show internal settings\n" msgstr " -s, --show показати внутрішні налаштування\n" -#: initdb.c:2383 +#: initdb.c:2319 #, c-format msgid " -S, --sync-only only sync data directory\n" msgstr " -S, --sync-only синхронізувати тільки каталог даних\n" -#: initdb.c:2384 +#: initdb.c:2320 #, c-format msgid "\n" "Other options:\n" msgstr "\n" "Інші параметри:\n" -#: initdb.c:2385 +#: initdb.c:2321 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version вивести інформацію про версію і вийти\n" -#: initdb.c:2386 +#: initdb.c:2322 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показати цю довідку, потім вийти\n" -#: initdb.c:2387 +#: initdb.c:2323 #, c-format msgid "\n" "If the data directory is not specified, the environment variable PGDATA\n" @@ -615,64 +622,67 @@ msgid "\n" msgstr "\n" "Якщо каталог даних не вказано, використовується змінна середовища PGDATA.\n" -#: initdb.c:2389 +#: initdb.c:2325 #, c-format msgid "\n" -"Report bugs to .\n" +"Report bugs to <%s>.\n" msgstr "\n" -"Про помилки повідомляйте на .\n" +"Повідомляти про помилки на <%s>.\n" + +#: initdb.c:2326 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" -#: initdb.c:2417 +#: initdb.c:2354 #, c-format msgid "invalid authentication method \"%s\" for \"%s\" connections" msgstr "неприпустимий спосіб автентифікації \"%s\" для \"%s\" підключення" -#: initdb.c:2433 +#: initdb.c:2370 #, c-format msgid "must specify a password for the superuser to enable %s authentication" msgstr "необхідно вказати пароль суперкористувача для активації автентифікації %s" -#: initdb.c:2460 +#: initdb.c:2397 #, c-format msgid "no data directory specified" msgstr "каталог даних не вказано" -#: initdb.c:2462 +#: initdb.c:2399 #, c-format msgid "You must identify the directory where the data for this database system\n" "will reside. Do this with either the invocation option -D or the\n" "environment variable PGDATA.\n" msgstr "Вам потрібно ідентифікувати каталог, у якому будуть розташовані дані для цієї бази даних. Зробіть це за допомогою параметру -D або змінного середовища PGDATA.\n" -#: initdb.c:2497 +#: initdb.c:2434 #, c-format -msgid "The program \"postgres\" is needed by %s but was not found in the\n" +msgid "The program \"%s\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" "Check your installation." -msgstr "Програма \"postgres\" потрібна для %s, але не знайдена в тому \n" -"ж каталозі, що й \"%s\".\n" +msgstr "Програма \"%s\" потрібна для %s, але не знайдена в тому ж каталозі, що й \"%s\".\n" "Перевірте вашу установку." -#: initdb.c:2502 +#: initdb.c:2439 #, c-format -msgid "The program \"postgres\" was found by \"%s\"\n" +msgid "The program \"%s\" was found by \"%s\"\n" "but was not the same version as %s.\n" "Check your installation." -msgstr "Програма \"postgres\" була знайдена \"%s\", \n" -"але не була тієї ж версії, що й %s.\n" +msgstr "Програма \"%s\" була знайдена \"%s\", але не була тієї ж версії, що %s.\n" "Перевірте вашу установку." -#: initdb.c:2521 +#: initdb.c:2458 #, c-format msgid "input file location must be an absolute path" msgstr "розташування вхідного файлу має бути абсолютним шляхом" -#: initdb.c:2538 +#: initdb.c:2475 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "Кластер бази даних буде ініціалізовано з локалізацією \"%s\".\n" -#: initdb.c:2541 +#: initdb.c:2478 #, c-format msgid "The database cluster will be initialized with locales\n" " COLLATE: %s\n" @@ -689,206 +699,206 @@ msgstr "Кластер бази даних буде ініціалізовано " NUMERIC: %s\n" " TIME: %s\n" -#: initdb.c:2565 +#: initdb.c:2502 #, c-format msgid "could not find suitable encoding for locale \"%s\"" msgstr "не вдалося знайти відповідне кодування для локалі \"%s\"" -#: initdb.c:2567 +#: initdb.c:2504 #, c-format msgid "Rerun %s with the -E option.\n" msgstr "Перезапустіть %s з параметром -E.\n" -#: initdb.c:2568 initdb.c:3196 initdb.c:3217 +#: initdb.c:2505 initdb.c:3127 initdb.c:3148 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" -#: initdb.c:2581 +#: initdb.c:2518 #, c-format msgid "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" "The default database encoding will be set to \"%s\" instead.\n" msgstr "Кодування \"%s\", що очікується локалізацією, не дозволено у якості кодування сервера.\n" "Замість нього буде встановлене кодування \"%s\" за замовчуванням.\n" -#: initdb.c:2586 +#: initdb.c:2523 #, c-format msgid "locale \"%s\" requires unsupported encoding \"%s\"" msgstr "локалізація \"%s\" потребує кодування \"%s\", що не підтримується" -#: initdb.c:2589 +#: initdb.c:2526 #, c-format msgid "Encoding \"%s\" is not allowed as a server-side encoding.\n" "Rerun %s with a different locale selection.\n" msgstr "Кодування \"%s\" не дозволяється у якості кодування сервера.\n" "Перезапустіть %s, обравши іншу локалізацію.\n" -#: initdb.c:2598 +#: initdb.c:2535 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "Кодування бази даних за замовчуванням встановлено: \"%s\".\n" -#: initdb.c:2666 +#: initdb.c:2597 #, c-format msgid "could not find suitable text search configuration for locale \"%s\"" msgstr "не вдалося знайти відповідну конфігурацію текстового пошуку для локалі\"%s\"" -#: initdb.c:2677 +#: initdb.c:2608 #, c-format msgid "suitable text search configuration for locale \"%s\" is unknown" msgstr "відповідна конфігурація текстового пошуку для локалі \"%s\" невідома" -#: initdb.c:2682 +#: initdb.c:2613 #, c-format msgid "specified text search configuration \"%s\" might not match locale \"%s\"" msgstr "вказана конфігурація текстового пошуку \"%s\" може не підходити локалі \"%s\"" -#: initdb.c:2687 +#: initdb.c:2618 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" msgstr "Конфігурація текстового пошуку за замовчуванням буде встановлена в \"%s\".\n" -#: initdb.c:2731 initdb.c:2813 +#: initdb.c:2662 initdb.c:2744 #, c-format msgid "creating directory %s ... " msgstr "створення каталогу %s... " -#: initdb.c:2737 initdb.c:2819 initdb.c:2884 initdb.c:2946 +#: initdb.c:2668 initdb.c:2750 initdb.c:2815 initdb.c:2877 #, c-format msgid "could not create directory \"%s\": %m" msgstr "не вдалося створити каталог \"%s\": %m" -#: initdb.c:2748 initdb.c:2831 +#: initdb.c:2679 initdb.c:2762 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "виправляю дозволи для створеного каталогу %s... " -#: initdb.c:2754 initdb.c:2837 +#: initdb.c:2685 initdb.c:2768 #, c-format msgid "could not change permissions of directory \"%s\": %m" msgstr "не вдалося змінити дозволи каталогу \"%s\": %m" -#: initdb.c:2768 initdb.c:2851 +#: initdb.c:2699 initdb.c:2782 #, c-format msgid "directory \"%s\" exists but is not empty" msgstr "каталог \"%s\" існує, але він не порожній" -#: initdb.c:2773 +#: initdb.c:2704 #, c-format msgid "If you want to create a new database system, either remove or empty\n" "the directory \"%s\" or run %s\n" "with an argument other than \"%s\".\n" msgstr "Якщо ви хочете створити нову систему бази даних, видаліть або очистіть каталог \"%s\", або запустіть %s з іншим аргументом, ніж \"%s\".\n" -#: initdb.c:2781 initdb.c:2863 initdb.c:3232 +#: initdb.c:2712 initdb.c:2794 initdb.c:3163 #, c-format msgid "could not access directory \"%s\": %m" -msgstr "помилка доступу до каталогу \"%s\": %m" +msgstr "немає доступу до каталогу \"%s\": %m" -#: initdb.c:2804 +#: initdb.c:2735 #, c-format msgid "WAL directory location must be an absolute path" msgstr "розташування WAL каталогу має бути абсолютним шляхом" -#: initdb.c:2856 +#: initdb.c:2787 #, c-format msgid "If you want to store the WAL there, either remove or empty the directory\n" "\"%s\".\n" msgstr "Якщо ви хочете зберегти WAL, видаліть або спорожніть каталог \"%s\".\n" -#: initdb.c:2870 +#: initdb.c:2801 #, c-format msgid "could not create symbolic link \"%s\": %m" -msgstr "не можливо створити символічне послання \"%s\": %m" +msgstr "не вдалося створити символічне послання \"%s\": %m" -#: initdb.c:2875 +#: initdb.c:2806 #, c-format msgid "symlinks are not supported on this platform" msgstr "символічні посилання не підтримуються цією платформою" -#: initdb.c:2899 +#: initdb.c:2830 #, c-format msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" msgstr "Він містить файл з крапкою або невидимий файл, можливо це точка під'єднання.\n" -#: initdb.c:2902 +#: initdb.c:2833 #, c-format msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" msgstr "Він містить каталог lost+found, можливо це точка під'єднання.\n" -#: initdb.c:2905 +#: initdb.c:2836 #, c-format msgid "Using a mount point directly as the data directory is not recommended.\n" "Create a subdirectory under the mount point.\n" msgstr "Не рекомендується використовувати точку під'єднання у якості каталогу даних.\n" "Створіть підкаталог і використайте його.\n" -#: initdb.c:2931 +#: initdb.c:2862 #, c-format msgid "creating subdirectories ... " msgstr "створення підкаталогів... " -#: initdb.c:2977 +#: initdb.c:2908 msgid "performing post-bootstrap initialization ... " msgstr "виконується кінцева фаза ініціалізації ... " -#: initdb.c:3134 +#: initdb.c:3065 #, c-format msgid "Running in debug mode.\n" msgstr "Виконується у режимі налагодження.\n" -#: initdb.c:3138 +#: initdb.c:3069 #, c-format msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" msgstr "Виконується у режимі 'no-clean'. Помилки не будуть виправлені.\n" -#: initdb.c:3215 +#: initdb.c:3146 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "забагато аргументів у командному рядку (перший \"%s\")" -#: initdb.c:3236 initdb.c:3325 +#: initdb.c:3167 initdb.c:3256 msgid "syncing data to disk ... " msgstr "синхронізація даних з диском ... " -#: initdb.c:3245 +#: initdb.c:3176 #, c-format msgid "password prompt and password file cannot be specified together" msgstr "неможливо вказати одночасно пароль і файл паролю" -#: initdb.c:3270 +#: initdb.c:3201 #, c-format msgid "argument of --wal-segsize must be a number" msgstr "аргумент --wal-segsize повинен бути числом" -#: initdb.c:3275 +#: initdb.c:3206 #, c-format msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" msgstr "аргумент --wal-segsize повинен бути ступенем 2 між 1 і 1024" -#: initdb.c:3292 +#: initdb.c:3223 #, c-format msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" msgstr "неприпустиме ім'я суперкористувача \"%s\"; імена ролей не можуть починатися на \"pg_\"" -#: initdb.c:3296 +#: initdb.c:3227 #, c-format msgid "The files belonging to this database system will be owned by user \"%s\".\n" "This user must also own the server process.\n\n" msgstr "Файли цієї бази даних будуть належати користувачеві \"%s\".\n" "Від імені цього користувача повинен запускатися процес сервера.\n\n" -#: initdb.c:3312 +#: initdb.c:3243 #, c-format msgid "Data page checksums are enabled.\n" msgstr "Контроль цілісності сторінок даних увімкнено.\n" -#: initdb.c:3314 +#: initdb.c:3245 #, c-format msgid "Data page checksums are disabled.\n" msgstr "Контроль цілісності сторінок даних вимкнено.\n" -#: initdb.c:3331 +#: initdb.c:3262 #, c-format msgid "\n" "Sync to disk skipped.\n" @@ -897,12 +907,12 @@ msgstr "\n" "Синхронізація з диском пропущена.\n" "Каталог з даними може бути пошкоджено під час аварійного завершення роботи операційної системи.\n" -#: initdb.c:3336 +#: initdb.c:3267 #, c-format msgid "enabling \"trust\" authentication for local connections" msgstr "увімкнення автентифікації \"довіри\" для локальних підключень" -#: initdb.c:3337 +#: initdb.c:3268 #, c-format msgid "You can change this by editing pg_hba.conf or using the option -A, or\n" "--auth-local and --auth-host, the next time you run initdb.\n" @@ -910,11 +920,11 @@ msgstr "Ви можете змінити це, змінивши pg_hba.conf аб "--auth-local і --auth-host, наступний раз, коли ви запускаєте initdb.\n" #. translator: This is a placeholder in a shell command. -#: initdb.c:3362 +#: initdb.c:3293 msgid "logfile" msgstr "logfile" -#: initdb.c:3364 +#: initdb.c:3295 #, c-format msgid "\n" "Success. You can now start the database server using:\n\n" diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl index 8387b945d369..635ff79b475d 100644 --- a/src/bin/initdb/t/001_initdb.pl +++ b/src/bin/initdb/t/001_initdb.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # To test successful data directory creation with an additional feature, first # try to elaborate the "successful creation" test instead of adding a test. # Successful initdb consumes much time and I/O. diff --git a/src/bin/pg_amcheck/.gitignore b/src/bin/pg_amcheck/.gitignore new file mode 100644 index 000000000000..c21a14de316c --- /dev/null +++ b/src/bin/pg_amcheck/.gitignore @@ -0,0 +1,3 @@ +pg_amcheck + +/tmp_check/ diff --git a/src/bin/pg_amcheck/Makefile b/src/bin/pg_amcheck/Makefile new file mode 100644 index 000000000000..6192523f10d3 --- /dev/null +++ b/src/bin/pg_amcheck/Makefile @@ -0,0 +1,51 @@ +#------------------------------------------------------------------------- +# +# Makefile for src/bin/pg_amcheck +# +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/bin/pg_amcheck/Makefile +# +#------------------------------------------------------------------------- + +PGFILEDESC = "pg_amcheck - detect corruption within database relations" +PGAPPICON=win32 + +EXTRA_INSTALL=contrib/amcheck contrib/pageinspect + +subdir = src/bin/pg_amcheck +top_builddir = ../../.. +include $(top_builddir)/src/Makefile.global + +override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) +LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) + +OBJS = \ + $(WIN32RES) \ + pg_amcheck.o + +all: pg_amcheck + +pg_amcheck: $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils + $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) + + +install: all installdirs + $(INSTALL_PROGRAM) pg_amcheck$(X) '$(DESTDIR)$(bindir)/pg_amcheck$(X)' + +installdirs: + $(MKDIR_P) '$(DESTDIR)$(bindir)' + +uninstall: + rm -f '$(DESTDIR)$(bindir)/pg_amcheck$(X)' + +clean distclean maintainer-clean: + rm -f pg_amcheck$(X) $(OBJS) + rm -rf tmp_check + +check: + $(prove_check) + +installcheck: + $(prove_installcheck) diff --git a/src/bin/pg_amcheck/README b/src/bin/pg_amcheck/README new file mode 100644 index 000000000000..950f8a73667b --- /dev/null +++ b/src/bin/pg_amcheck/README @@ -0,0 +1,19 @@ +src/bin/pg_amcheck/README + +pg_amcheck is a command-line tool for running the amcheck extension. + +Running the regression tests +============================ + +NOTE: You must have given the --enable-tap-tests argument to configure. +Also, to use "make installcheck", you must have built and installed +contrib/amcheck and contrib/pageinspect in addition to the core code. + +Run + make check +or + make installcheck +You can use "make installcheck" if you previously did "make install". +In that case, the code in the installation tree is tested. With +"make check", a temporary installation tree is built from the current +sources and then tested. diff --git a/src/bin/pg_amcheck/nls.mk b/src/bin/pg_amcheck/nls.mk new file mode 100644 index 000000000000..cae6dc86ad95 --- /dev/null +++ b/src/bin/pg_amcheck/nls.mk @@ -0,0 +1,10 @@ +# src/bin/pg_amcheck/nls.mk +CATALOG_NAME = pg_amcheck +AVAIL_LANGUAGES = de el es fr zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ + pg_amcheck.c \ + ../../fe_utils/cancel.c \ + ../../fe_utils/connect_utils.c \ + ../../fe_utils/query_utils.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_amcheck/pg_amcheck.c b/src/bin/pg_amcheck/pg_amcheck.c new file mode 100644 index 000000000000..4bde16fb4bd4 --- /dev/null +++ b/src/bin/pg_amcheck/pg_amcheck.c @@ -0,0 +1,2172 @@ +/*------------------------------------------------------------------------- + * + * pg_amcheck.c + * Detects corruption within database relations. + * + * Copyright (c) 2017-2021, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/bin/pg_amcheck/pg_amcheck.c + * + *------------------------------------------------------------------------- + */ +#include "postgres_fe.h" + +#include + +#include "catalog/pg_am_d.h" +#include "catalog/pg_namespace_d.h" +#include "common/logging.h" +#include "common/username.h" +#include "fe_utils/cancel.h" +#include "fe_utils/option_utils.h" +#include "fe_utils/parallel_slot.h" +#include "fe_utils/query_utils.h" +#include "fe_utils/simple_list.h" +#include "fe_utils/string_utils.h" +#include "getopt_long.h" /* pgrminclude ignore */ +#include "pgtime.h" +#include "storage/block.h" + +typedef struct PatternInfo +{ + const char *pattern; /* Unaltered pattern from the command line */ + char *db_regex; /* Database regexp parsed from pattern, or + * NULL */ + char *nsp_regex; /* Schema regexp parsed from pattern, or NULL */ + char *rel_regex; /* Relation regexp parsed from pattern, or + * NULL */ + bool heap_only; /* true if rel_regex should only match heap + * tables */ + bool btree_only; /* true if rel_regex should only match btree + * indexes */ + bool matched; /* true if the pattern matched in any database */ +} PatternInfo; + +typedef struct PatternInfoArray +{ + PatternInfo *data; + size_t len; +} PatternInfoArray; + +/* pg_amcheck command line options controlled by user flags */ +typedef struct AmcheckOptions +{ + bool dbpattern; + bool alldb; + bool echo; + bool quiet; + bool verbose; + bool strict_names; + bool show_progress; + int jobs; + + /* + * Whether to install missing extensions, and optionally the name of the + * schema in which to install the extension's objects. + */ + bool install_missing; + char *install_schema; + + /* Objects to check or not to check, as lists of PatternInfo structs. */ + PatternInfoArray include; + PatternInfoArray exclude; + + /* + * As an optimization, if any pattern in the exclude list applies to heap + * tables, or similarly if any such pattern applies to btree indexes, or + * to schemas, then these will be true, otherwise false. These should + * always agree with what you'd conclude by grep'ing through the exclude + * list. + */ + bool excludetbl; + bool excludeidx; + bool excludensp; + + /* + * If any inclusion pattern exists, then we should only be checking + * matching relations rather than all relations, so this is true iff + * include is empty. + */ + bool allrel; + + /* heap table checking options */ + bool no_toast_expansion; + bool reconcile_toast; + bool on_error_stop; + int64 startblock; + int64 endblock; + const char *skip; + + /* btree index checking options */ + bool parent_check; + bool rootdescend; + bool heapallindexed; + + /* heap and btree hybrid option */ + bool no_btree_expansion; +} AmcheckOptions; + +static AmcheckOptions opts = { + .dbpattern = false, + .alldb = false, + .echo = false, + .quiet = false, + .verbose = false, + .strict_names = true, + .show_progress = false, + .jobs = 1, + .install_missing = false, + .install_schema = "pg_catalog", + .include = {NULL, 0}, + .exclude = {NULL, 0}, + .excludetbl = false, + .excludeidx = false, + .excludensp = false, + .allrel = true, + .no_toast_expansion = false, + .reconcile_toast = true, + .on_error_stop = false, + .startblock = -1, + .endblock = -1, + .skip = "none", + .parent_check = false, + .rootdescend = false, + .heapallindexed = false, + .no_btree_expansion = false +}; + +static const char *progname = NULL; + +/* Whether all relations have so far passed their corruption checks */ +static bool all_checks_pass = true; + +/* Time last progress report was displayed */ +static pg_time_t last_progress_report = 0; +static bool progress_since_last_stderr = false; + +typedef struct DatabaseInfo +{ + char *datname; + char *amcheck_schema; /* escaped, quoted literal */ +} DatabaseInfo; + +typedef struct RelationInfo +{ + const DatabaseInfo *datinfo; /* shared by other relinfos */ + Oid reloid; + bool is_heap; /* true if heap, false if btree */ + char *nspname; + char *relname; + int relpages; + int blocks_to_check; + char *sql; /* set during query run, pg_free'd after */ +} RelationInfo; + +/* + * Query for determining if contrib's amcheck is installed. If so, selects the + * namespace name where amcheck's functions can be found. + */ +static const char *amcheck_sql = +"SELECT n.nspname, x.extversion FROM pg_catalog.pg_extension x" +"\nJOIN pg_catalog.pg_namespace n ON x.extnamespace = n.oid" +"\nWHERE x.extname = 'amcheck'"; + +static void prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, + PGconn *conn); +static void prepare_btree_command(PQExpBuffer sql, RelationInfo *rel, + PGconn *conn); +static void run_command(ParallelSlot *slot, const char *sql); +static bool verify_heap_slot_handler(PGresult *res, PGconn *conn, + void *context); +static bool verify_btree_slot_handler(PGresult *res, PGconn *conn, void *context); +static void help(const char *progname); +static void progress_report(uint64 relations_total, uint64 relations_checked, + uint64 relpages_total, uint64 relpages_checked, + const char *datname, bool force, bool finished); + +static void append_database_pattern(PatternInfoArray *pia, const char *pattern, + int encoding); +static void append_schema_pattern(PatternInfoArray *pia, const char *pattern, + int encoding); +static void append_relation_pattern(PatternInfoArray *pia, const char *pattern, + int encoding); +static void append_heap_pattern(PatternInfoArray *pia, const char *pattern, + int encoding); +static void append_btree_pattern(PatternInfoArray *pia, const char *pattern, + int encoding); +static void compile_database_list(PGconn *conn, SimplePtrList *databases, + const char *initial_dbname); +static void compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations, + const DatabaseInfo *datinfo, + uint64 *pagecount); + +#define log_no_match(...) do { \ + if (opts.strict_names) \ + pg_log_generic(PG_LOG_ERROR, __VA_ARGS__); \ + else \ + pg_log_generic(PG_LOG_WARNING, __VA_ARGS__); \ + } while(0) + +#define FREE_AND_SET_NULL(x) do { \ + pg_free(x); \ + (x) = NULL; \ + } while (0) + +int +main(int argc, char *argv[]) +{ + PGconn *conn = NULL; + SimplePtrListCell *cell; + SimplePtrList databases = {NULL, NULL}; + SimplePtrList relations = {NULL, NULL}; + bool failed = false; + const char *latest_datname; + int parallel_workers; + ParallelSlotArray *sa; + PQExpBufferData sql; + uint64 reltotal = 0; + uint64 pageschecked = 0; + uint64 pagestotal = 0; + uint64 relprogress = 0; + int pattern_id; + + static struct option long_options[] = { + /* Connection options */ + {"host", required_argument, NULL, 'h'}, + {"port", required_argument, NULL, 'p'}, + {"username", required_argument, NULL, 'U'}, + {"no-password", no_argument, NULL, 'w'}, + {"password", no_argument, NULL, 'W'}, + {"maintenance-db", required_argument, NULL, 1}, + + /* check options */ + {"all", no_argument, NULL, 'a'}, + {"database", required_argument, NULL, 'd'}, + {"exclude-database", required_argument, NULL, 'D'}, + {"echo", no_argument, NULL, 'e'}, + {"index", required_argument, NULL, 'i'}, + {"exclude-index", required_argument, NULL, 'I'}, + {"jobs", required_argument, NULL, 'j'}, + {"progress", no_argument, NULL, 'P'}, + {"quiet", no_argument, NULL, 'q'}, + {"relation", required_argument, NULL, 'r'}, + {"exclude-relation", required_argument, NULL, 'R'}, + {"schema", required_argument, NULL, 's'}, + {"exclude-schema", required_argument, NULL, 'S'}, + {"table", required_argument, NULL, 't'}, + {"exclude-table", required_argument, NULL, 'T'}, + {"verbose", no_argument, NULL, 'v'}, + {"no-dependent-indexes", no_argument, NULL, 2}, + {"no-dependent-toast", no_argument, NULL, 3}, + {"exclude-toast-pointers", no_argument, NULL, 4}, + {"on-error-stop", no_argument, NULL, 5}, + {"skip", required_argument, NULL, 6}, + {"startblock", required_argument, NULL, 7}, + {"endblock", required_argument, NULL, 8}, + {"rootdescend", no_argument, NULL, 9}, + {"no-strict-names", no_argument, NULL, 10}, + {"heapallindexed", no_argument, NULL, 11}, + {"parent-check", no_argument, NULL, 12}, + {"install-missing", optional_argument, NULL, 13}, + + {NULL, 0, NULL, 0} + }; + + int optindex; + int c; + + const char *db = NULL; + const char *maintenance_db = NULL; + + const char *host = NULL; + const char *port = NULL; + const char *username = NULL; + enum trivalue prompt_password = TRI_DEFAULT; + int encoding = pg_get_encoding_from_locale(NULL, false); + ConnParams cparams; + + pg_logging_init(argv[0]); + progname = get_progname(argv[0]); + set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_amcheck")); + + handle_help_version_opts(argc, argv, progname, help); + + /* process command-line options */ + while ((c = getopt_long(argc, argv, "ad:D:eh:Hi:I:j:p:Pqr:R:s:S:t:T:U:wWv", + long_options, &optindex)) != -1) + { + char *endptr; + + switch (c) + { + case 'a': + opts.alldb = true; + break; + case 'd': + opts.dbpattern = true; + append_database_pattern(&opts.include, optarg, encoding); + break; + case 'D': + opts.dbpattern = true; + append_database_pattern(&opts.exclude, optarg, encoding); + break; + case 'e': + opts.echo = true; + break; + case 'h': + host = pg_strdup(optarg); + break; + case 'i': + opts.allrel = false; + append_btree_pattern(&opts.include, optarg, encoding); + break; + case 'I': + opts.excludeidx = true; + append_btree_pattern(&opts.exclude, optarg, encoding); + break; + case 'j': + opts.jobs = atoi(optarg); + if (opts.jobs < 1) + { + pg_log_error("number of parallel jobs must be at least 1"); + exit(1); + } + break; + case 'p': + port = pg_strdup(optarg); + break; + case 'P': + opts.show_progress = true; + break; + case 'q': + opts.quiet = true; + break; + case 'r': + opts.allrel = false; + append_relation_pattern(&opts.include, optarg, encoding); + break; + case 'R': + opts.excludeidx = true; + opts.excludetbl = true; + append_relation_pattern(&opts.exclude, optarg, encoding); + break; + case 's': + opts.allrel = false; + append_schema_pattern(&opts.include, optarg, encoding); + break; + case 'S': + opts.excludensp = true; + append_schema_pattern(&opts.exclude, optarg, encoding); + break; + case 't': + opts.allrel = false; + append_heap_pattern(&opts.include, optarg, encoding); + break; + case 'T': + opts.excludetbl = true; + append_heap_pattern(&opts.exclude, optarg, encoding); + break; + case 'U': + username = pg_strdup(optarg); + break; + case 'w': + prompt_password = TRI_NO; + break; + case 'W': + prompt_password = TRI_YES; + break; + case 'v': + opts.verbose = true; + pg_logging_increase_verbosity(); + break; + case 1: + maintenance_db = pg_strdup(optarg); + break; + case 2: + opts.no_btree_expansion = true; + break; + case 3: + opts.no_toast_expansion = true; + break; + case 4: + opts.reconcile_toast = false; + break; + case 5: + opts.on_error_stop = true; + break; + case 6: + if (pg_strcasecmp(optarg, "all-visible") == 0) + opts.skip = "all visible"; + else if (pg_strcasecmp(optarg, "all-frozen") == 0) + opts.skip = "all frozen"; + else + { + pg_log_error("invalid argument for option %s", "--skip"); + exit(1); + } + break; + case 7: + opts.startblock = strtol(optarg, &endptr, 10); + if (*endptr != '\0') + { + pg_log_error("invalid start block"); + exit(1); + } + if (opts.startblock > MaxBlockNumber || opts.startblock < 0) + { + pg_log_error("start block out of bounds"); + exit(1); + } + break; + case 8: + opts.endblock = strtol(optarg, &endptr, 10); + if (*endptr != '\0') + { + pg_log_error("invalid end block"); + exit(1); + } + if (opts.endblock > MaxBlockNumber || opts.endblock < 0) + { + pg_log_error("end block out of bounds"); + exit(1); + } + break; + case 9: + opts.rootdescend = true; + opts.parent_check = true; + break; + case 10: + opts.strict_names = false; + break; + case 11: + opts.heapallindexed = true; + break; + case 12: + opts.parent_check = true; + break; + case 13: + opts.install_missing = true; + if (optarg) + opts.install_schema = pg_strdup(optarg); + break; + default: + fprintf(stderr, + _("Try \"%s --help\" for more information.\n"), + progname); + exit(1); + } + } + + if (opts.endblock >= 0 && opts.endblock < opts.startblock) + { + pg_log_error("end block precedes start block"); + exit(1); + } + + /* + * A single non-option arguments specifies a database name or connection + * string. + */ + if (optind < argc) + { + db = argv[optind]; + optind++; + } + + if (optind < argc) + { + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + + /* fill cparams except for dbname, which is set below */ + cparams.pghost = host; + cparams.pgport = port; + cparams.pguser = username; + cparams.prompt_password = prompt_password; + cparams.dbname = NULL; + cparams.override_dbname = NULL; + + setup_cancel_handler(NULL); + + /* choose the database for our initial connection */ + if (opts.alldb) + { + if (db != NULL) + { + pg_log_error("cannot specify a database name with --all"); + exit(1); + } + cparams.dbname = maintenance_db; + } + else if (db != NULL) + { + if (opts.dbpattern) + { + pg_log_error("cannot specify both a database name and database patterns"); + exit(1); + } + cparams.dbname = db; + } + + if (opts.alldb || opts.dbpattern) + { + conn = connectMaintenanceDatabase(&cparams, progname, opts.echo); + compile_database_list(conn, &databases, NULL); + } + else + { + if (cparams.dbname == NULL) + { + if (getenv("PGDATABASE")) + cparams.dbname = getenv("PGDATABASE"); + else if (getenv("PGUSER")) + cparams.dbname = getenv("PGUSER"); + else + cparams.dbname = get_user_name_or_exit(progname); + } + conn = connectDatabase(&cparams, progname, opts.echo, false, true); + compile_database_list(conn, &databases, PQdb(conn)); + } + + if (databases.head == NULL) + { + if (conn != NULL) + disconnectDatabase(conn); + pg_log_error("no databases to check"); + exit(0); + } + + /* + * Compile a list of all relations spanning all databases to be checked. + */ + for (cell = databases.head; cell; cell = cell->next) + { + PGresult *result; + int ntups; + const char *amcheck_schema = NULL; + DatabaseInfo *dat = (DatabaseInfo *) cell->ptr; + + cparams.override_dbname = dat->datname; + if (conn == NULL || strcmp(PQdb(conn), dat->datname) != 0) + { + if (conn != NULL) + disconnectDatabase(conn); + conn = connectDatabase(&cparams, progname, opts.echo, false, true); + } + + /* + * Optionally install amcheck if not already installed in this + * database. + */ + if (opts.install_missing) + { + char *schema; + char *install_sql; + + /* + * Must re-escape the schema name for each database, as the + * escaping rules may change. + */ + schema = PQescapeIdentifier(conn, opts.install_schema, + strlen(opts.install_schema)); + install_sql = psprintf("CREATE EXTENSION IF NOT EXISTS amcheck WITH SCHEMA %s", + schema); + + executeCommand(conn, install_sql, opts.echo); + pfree(install_sql); + pfree(schema); + } + + /* + * Verify that amcheck is installed for this next database. User + * error could result in a database not having amcheck that should + * have it, but we also could be iterating over multiple databases + * where not all of them have amcheck installed (for example, + * 'template1'). + */ + result = executeQuery(conn, amcheck_sql, opts.echo); + if (PQresultStatus(result) != PGRES_TUPLES_OK) + { + /* Querying the catalog failed. */ + pg_log_error("database \"%s\": %s", + PQdb(conn), PQerrorMessage(conn)); + pg_log_info("query was: %s", amcheck_sql); + PQclear(result); + disconnectDatabase(conn); + exit(1); + } + ntups = PQntuples(result); + if (ntups == 0) + { + /* Querying the catalog succeeded, but amcheck is missing. */ + pg_log_warning("skipping database \"%s\": amcheck is not installed", + PQdb(conn)); + disconnectDatabase(conn); + conn = NULL; + continue; + } + amcheck_schema = PQgetvalue(result, 0, 0); + if (opts.verbose) + pg_log_info("in database \"%s\": using amcheck version \"%s\" in schema \"%s\"", + PQdb(conn), PQgetvalue(result, 0, 1), amcheck_schema); + dat->amcheck_schema = PQescapeIdentifier(conn, amcheck_schema, + strlen(amcheck_schema)); + PQclear(result); + + compile_relation_list_one_db(conn, &relations, dat, &pagestotal); + } + + /* + * Check that all inclusion patterns matched at least one schema or + * relation that we can check. + */ + for (pattern_id = 0; pattern_id < opts.include.len; pattern_id++) + { + PatternInfo *pat = &opts.include.data[pattern_id]; + + if (!pat->matched && (pat->nsp_regex != NULL || pat->rel_regex != NULL)) + { + failed = opts.strict_names; + + if (!opts.quiet || failed) + { + if (pat->heap_only) + log_no_match("no heap tables to check matching \"%s\"", + pat->pattern); + else if (pat->btree_only) + log_no_match("no btree indexes to check matching \"%s\"", + pat->pattern); + else if (pat->rel_regex == NULL) + log_no_match("no relations to check in schemas matching \"%s\"", + pat->pattern); + else + log_no_match("no relations to check matching \"%s\"", + pat->pattern); + } + } + } + + if (failed) + { + if (conn != NULL) + disconnectDatabase(conn); + exit(1); + } + + /* + * Set parallel_workers to the lesser of opts.jobs and the number of + * relations. + */ + parallel_workers = 0; + for (cell = relations.head; cell; cell = cell->next) + { + reltotal++; + if (parallel_workers < opts.jobs) + parallel_workers++; + } + + if (reltotal == 0) + { + if (conn != NULL) + disconnectDatabase(conn); + pg_log_error("no relations to check"); + exit(1); + } + progress_report(reltotal, relprogress, pagestotal, pageschecked, + NULL, true, false); + + /* + * Main event loop. + * + * We use server-side parallelism to check up to parallel_workers + * relations in parallel. The list of relations was computed in database + * order, which minimizes the number of connects and disconnects as we + * process the list. + */ + latest_datname = NULL; + sa = ParallelSlotsSetup(parallel_workers, &cparams, progname, opts.echo, + NULL); + if (conn != NULL) + { + ParallelSlotsAdoptConn(sa, conn); + conn = NULL; + } + + initPQExpBuffer(&sql); + for (relprogress = 0, cell = relations.head; cell; cell = cell->next) + { + ParallelSlot *free_slot; + RelationInfo *rel; + + rel = (RelationInfo *) cell->ptr; + + if (CancelRequested) + { + failed = true; + break; + } + + /* + * The list of relations is in database sorted order. If this next + * relation is in a different database than the last one seen, we are + * about to start checking this database. Note that other slots may + * still be working on relations from prior databases. + */ + latest_datname = rel->datinfo->datname; + + progress_report(reltotal, relprogress, pagestotal, pageschecked, + latest_datname, false, false); + + relprogress++; + pageschecked += rel->blocks_to_check; + + /* + * Get a parallel slot for the next amcheck command, blocking if + * necessary until one is available, or until a previously issued slot + * command fails, indicating that we should abort checking the + * remaining objects. + */ + free_slot = ParallelSlotsGetIdle(sa, rel->datinfo->datname); + if (!free_slot) + { + /* + * Something failed. We don't need to know what it was, because + * the handler should already have emitted the necessary error + * messages. + */ + failed = true; + break; + } + + if (opts.verbose) + PQsetErrorVerbosity(free_slot->connection, PQERRORS_VERBOSE); + else if (opts.quiet) + PQsetErrorVerbosity(free_slot->connection, PQERRORS_TERSE); + + /* + * Execute the appropriate amcheck command for this relation using our + * slot's database connection. We do not wait for the command to + * complete, nor do we perform any error checking, as that is done by + * the parallel slots and our handler callback functions. + */ + if (rel->is_heap) + { + if (opts.verbose) + { + if (opts.show_progress && progress_since_last_stderr) + fprintf(stderr, "\n"); + pg_log_info("checking heap table \"%s\".\"%s\".\"%s\"", + rel->datinfo->datname, rel->nspname, rel->relname); + progress_since_last_stderr = false; + } + prepare_heap_command(&sql, rel, free_slot->connection); + rel->sql = pstrdup(sql.data); /* pg_free'd after command */ + ParallelSlotSetHandler(free_slot, verify_heap_slot_handler, rel); + run_command(free_slot, rel->sql); + } + else + { + if (opts.verbose) + { + if (opts.show_progress && progress_since_last_stderr) + fprintf(stderr, "\n"); + + pg_log_info("checking btree index \"%s\".\"%s\".\"%s\"", + rel->datinfo->datname, rel->nspname, rel->relname); + progress_since_last_stderr = false; + } + prepare_btree_command(&sql, rel, free_slot->connection); + rel->sql = pstrdup(sql.data); /* pg_free'd after command */ + ParallelSlotSetHandler(free_slot, verify_btree_slot_handler, rel); + run_command(free_slot, rel->sql); + } + } + termPQExpBuffer(&sql); + + if (!failed) + { + + /* + * Wait for all slots to complete, or for one to indicate that an + * error occurred. Like above, we rely on the handler emitting the + * necessary error messages. + */ + if (sa && !ParallelSlotsWaitCompletion(sa)) + failed = true; + + progress_report(reltotal, relprogress, pagestotal, pageschecked, NULL, true, true); + } + + if (sa) + { + ParallelSlotsTerminate(sa); + FREE_AND_SET_NULL(sa); + } + + if (failed) + exit(1); + + if (!all_checks_pass) + exit(2); +} + +/* + * prepare_heap_command + * + * Creates a SQL command for running amcheck checking on the given heap + * relation. The command is phrased as a SQL query, with column order and + * names matching the expectations of verify_heap_slot_handler, which will + * receive and handle each row returned from the verify_heapam() function. + * + * sql: buffer into which the heap table checking command will be written + * rel: relation information for the heap table to be checked + * conn: the connection to be used, for string escaping purposes + */ +static void +prepare_heap_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn) +{ + resetPQExpBuffer(sql); + appendPQExpBuffer(sql, + "SELECT blkno, offnum, attnum, msg FROM %s.verify_heapam(" + "\nrelation := %u, on_error_stop := %s, check_toast := %s, skip := '%s'", + rel->datinfo->amcheck_schema, + rel->reloid, + opts.on_error_stop ? "true" : "false", + opts.reconcile_toast ? "true" : "false", + opts.skip); + + if (opts.startblock >= 0) + appendPQExpBuffer(sql, ", startblock := " INT64_FORMAT, opts.startblock); + if (opts.endblock >= 0) + appendPQExpBuffer(sql, ", endblock := " INT64_FORMAT, opts.endblock); + + appendPQExpBufferChar(sql, ')'); +} + +/* + * prepare_btree_command + * + * Creates a SQL command for running amcheck checking on the given btree index + * relation. The command does not select any columns, as btree checking + * functions do not return any, but rather return corruption information by + * raising errors, which verify_btree_slot_handler expects. + * + * sql: buffer into which the heap table checking command will be written + * rel: relation information for the index to be checked + * conn: the connection to be used, for string escaping purposes + */ +static void +prepare_btree_command(PQExpBuffer sql, RelationInfo *rel, PGconn *conn) +{ + resetPQExpBuffer(sql); + + /* + * Embed the database, schema, and relation name in the query, so if the + * check throws an error, the user knows which relation the error came + * from. + */ + if (opts.parent_check) + appendPQExpBuffer(sql, + "SELECT * FROM %s.bt_index_parent_check(" + "index := '%u'::regclass, heapallindexed := %s, " + "rootdescend := %s)", + rel->datinfo->amcheck_schema, + rel->reloid, + (opts.heapallindexed ? "true" : "false"), + (opts.rootdescend ? "true" : "false")); + else + appendPQExpBuffer(sql, + "SELECT * FROM %s.bt_index_check(" + "index := '%u'::regclass, heapallindexed := %s)", + rel->datinfo->amcheck_schema, + rel->reloid, + (opts.heapallindexed ? "true" : "false")); +} + +/* + * run_command + * + * Sends a command to the server without waiting for the command to complete. + * Logs an error if the command cannot be sent, but otherwise any errors are + * expected to be handled by a ParallelSlotHandler. + * + * If reconnecting to the database is necessary, the cparams argument may be + * modified. + * + * slot: slot with connection to the server we should use for the command + * sql: query to send + */ +static void +run_command(ParallelSlot *slot, const char *sql) +{ + if (opts.echo) + printf("%s\n", sql); + + if (PQsendQuery(slot->connection, sql) == 0) + { + pg_log_error("error sending command to database \"%s\": %s", + PQdb(slot->connection), + PQerrorMessage(slot->connection)); + pg_log_error("command was: %s", sql); + exit(1); + } +} + +/* + * should_processing_continue + * + * Checks a query result returned from a query (presumably issued on a slot's + * connection) to determine if parallel slots should continue issuing further + * commands. + * + * Note: Heap relation corruption is reported by verify_heapam() via the result + * set, rather than an ERROR, but running verify_heapam() on a corrupted heap + * table may still result in an error being returned from the server due to + * missing relation files, bad checksums, etc. The btree corruption checking + * functions always use errors to communicate corruption messages. We can't + * just abort processing because we got a mere ERROR. + * + * res: result from an executed sql query + */ +static bool +should_processing_continue(PGresult *res) +{ + const char *severity; + + switch (PQresultStatus(res)) + { + /* These are expected and ok */ + case PGRES_COMMAND_OK: + case PGRES_TUPLES_OK: + case PGRES_NONFATAL_ERROR: + break; + + /* This is expected but requires closer scrutiny */ + case PGRES_FATAL_ERROR: + severity = PQresultErrorField(res, PG_DIAG_SEVERITY_NONLOCALIZED); + if (strcmp(severity, "FATAL") == 0) + return false; + if (strcmp(severity, "PANIC") == 0) + return false; + break; + + /* These are unexpected */ + case PGRES_BAD_RESPONSE: + case PGRES_EMPTY_QUERY: + case PGRES_COPY_OUT: + case PGRES_COPY_IN: + case PGRES_COPY_BOTH: + case PGRES_SINGLE_TUPLE: + case PGRES_PIPELINE_SYNC: + case PGRES_PIPELINE_ABORTED: + return false; + } + return true; +} + +/* + * Returns a copy of the argument string with all lines indented four spaces. + * + * The caller should pg_free the result when finished with it. + */ +static char * +indent_lines(const char *str) +{ + PQExpBufferData buf; + const char *c; + char *result; + + initPQExpBuffer(&buf); + appendPQExpBufferStr(&buf, " "); + for (c = str; *c; c++) + { + appendPQExpBufferChar(&buf, *c); + if (c[0] == '\n' && c[1] != '\0') + appendPQExpBufferStr(&buf, " "); + } + result = pstrdup(buf.data); + termPQExpBuffer(&buf); + + return result; +} + +/* + * verify_heap_slot_handler + * + * ParallelSlotHandler that receives results from a heap table checking command + * created by prepare_heap_command and outputs the results for the user. + * + * res: result from an executed sql query + * conn: connection on which the sql query was executed + * context: the sql query being handled, as a cstring + */ +static bool +verify_heap_slot_handler(PGresult *res, PGconn *conn, void *context) +{ + RelationInfo *rel = (RelationInfo *) context; + + if (PQresultStatus(res) == PGRES_TUPLES_OK) + { + int i; + int ntups = PQntuples(res); + + if (ntups > 0) + all_checks_pass = false; + + for (i = 0; i < ntups; i++) + { + const char *msg; + + /* The message string should never be null, but check */ + if (PQgetisnull(res, i, 3)) + msg = "NO MESSAGE"; + else + msg = PQgetvalue(res, i, 3); + + if (!PQgetisnull(res, i, 2)) + printf("heap table \"%s\".\"%s\".\"%s\", block %s, offset %s, attribute %s:\n %s\n", + rel->datinfo->datname, rel->nspname, rel->relname, + PQgetvalue(res, i, 0), /* blkno */ + PQgetvalue(res, i, 1), /* offnum */ + PQgetvalue(res, i, 2), /* attnum */ + msg); + + else if (!PQgetisnull(res, i, 1)) + printf("heap table \"%s\".\"%s\".\"%s\", block %s, offset %s:\n %s\n", + rel->datinfo->datname, rel->nspname, rel->relname, + PQgetvalue(res, i, 0), /* blkno */ + PQgetvalue(res, i, 1), /* offnum */ + msg); + + else if (!PQgetisnull(res, i, 0)) + printf("heap table \"%s\".\"%s\".\"%s\", block %s:\n %s\n", + rel->datinfo->datname, rel->nspname, rel->relname, + PQgetvalue(res, i, 0), /* blkno */ + msg); + + else + printf("heap table \"%s\".\"%s\".\"%s\":\n %s\n", + rel->datinfo->datname, rel->nspname, rel->relname, msg); + } + } + else if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + char *msg = indent_lines(PQerrorMessage(conn)); + + all_checks_pass = false; + printf("heap table \"%s\".\"%s\".\"%s\":\n%s", + rel->datinfo->datname, rel->nspname, rel->relname, msg); + if (opts.verbose) + printf("query was: %s\n", rel->sql); + FREE_AND_SET_NULL(msg); + } + + FREE_AND_SET_NULL(rel->sql); + FREE_AND_SET_NULL(rel->nspname); + FREE_AND_SET_NULL(rel->relname); + + return should_processing_continue(res); +} + +/* + * verify_btree_slot_handler + * + * ParallelSlotHandler that receives results from a btree checking command + * created by prepare_btree_command and outputs them for the user. The results + * from the btree checking command is assumed to be empty, but when the results + * are an error code, the useful information about the corruption is expected + * in the connection's error message. + * + * res: result from an executed sql query + * conn: connection on which the sql query was executed + * context: unused + */ +static bool +verify_btree_slot_handler(PGresult *res, PGconn *conn, void *context) +{ + RelationInfo *rel = (RelationInfo *) context; + + if (PQresultStatus(res) == PGRES_TUPLES_OK) + { + int ntups = PQntuples(res); + + if (ntups != 1) + { + /* + * We expect the btree checking functions to return one void row + * each, so we should output some sort of warning if we get + * anything else, not because it indicates corruption, but because + * it suggests a mismatch between amcheck and pg_amcheck versions. + * + * In conjunction with --progress, anything written to stderr at + * this time would present strangely to the user without an extra + * newline, so we print one. If we were multithreaded, we'd have + * to avoid splitting this across multiple calls, but we're in an + * event loop, so it doesn't matter. + */ + if (opts.show_progress && progress_since_last_stderr) + fprintf(stderr, "\n"); + pg_log_warning("btree index \"%s\".\"%s\".\"%s\": btree checking function returned unexpected number of rows: %d", + rel->datinfo->datname, rel->nspname, rel->relname, ntups); + if (opts.verbose) + pg_log_info("query was: %s", rel->sql); + pg_log_warning("Are %s's and amcheck's versions compatible?", + progname); + progress_since_last_stderr = false; + } + } + else + { + char *msg = indent_lines(PQerrorMessage(conn)); + + all_checks_pass = false; + printf("btree index \"%s\".\"%s\".\"%s\":\n%s", + rel->datinfo->datname, rel->nspname, rel->relname, msg); + if (opts.verbose) + printf("query was: %s\n", rel->sql); + FREE_AND_SET_NULL(msg); + } + + FREE_AND_SET_NULL(rel->sql); + FREE_AND_SET_NULL(rel->nspname); + FREE_AND_SET_NULL(rel->relname); + + return should_processing_continue(res); +} + +/* + * help + * + * Prints help page for the program + * + * progname: the name of the executed program, such as "pg_amcheck" + */ +static void +help(const char *progname) +{ + printf(_("%s checks objects in a PostgreSQL database for corruption.\n\n"), progname); + printf(_("Usage:\n")); + printf(_(" %s [OPTION]... [DBNAME]\n"), progname); + printf(_("\nTarget options:\n")); + printf(_(" -a, --all check all databases\n")); + printf(_(" -d, --database=PATTERN check matching database(s)\n")); + printf(_(" -D, --exclude-database=PATTERN do NOT check matching database(s)\n")); + printf(_(" -i, --index=PATTERN check matching index(es)\n")); + printf(_(" -I, --exclude-index=PATTERN do NOT check matching index(es)\n")); + printf(_(" -r, --relation=PATTERN check matching relation(s)\n")); + printf(_(" -R, --exclude-relation=PATTERN do NOT check matching relation(s)\n")); + printf(_(" -s, --schema=PATTERN check matching schema(s)\n")); + printf(_(" -S, --exclude-schema=PATTERN do NOT check matching schema(s)\n")); + printf(_(" -t, --table=PATTERN check matching table(s)\n")); + printf(_(" -T, --exclude-table=PATTERN do NOT check matching table(s)\n")); + printf(_(" --no-dependent-indexes do NOT expand list of relations to include indexes\n")); + printf(_(" --no-dependent-toast do NOT expand list of relations to include TOAST tables\n")); + printf(_(" --no-strict-names do NOT require patterns to match objects\n")); + printf(_("\nTable checking options:\n")); + printf(_(" --exclude-toast-pointers do NOT follow relation TOAST pointers\n")); + printf(_(" --on-error-stop stop checking at end of first corrupt page\n")); + printf(_(" --skip=OPTION do NOT check \"all-frozen\" or \"all-visible\" blocks\n")); + printf(_(" --startblock=BLOCK begin checking table(s) at the given block number\n")); + printf(_(" --endblock=BLOCK check table(s) only up to the given block number\n")); + printf(_("\nB-tree index checking options:\n")); + printf(_(" --heapallindexed check all heap tuples are found within indexes\n")); + printf(_(" --parent-check check index parent/child relationships\n")); + printf(_(" --rootdescend search from root page to refind tuples\n")); + printf(_("\nConnection options:\n")); + printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); + printf(_(" -p, --port=PORT database server port\n")); + printf(_(" -U, --username=USERNAME user name to connect as\n")); + printf(_(" -w, --no-password never prompt for password\n")); + printf(_(" -W, --password force password prompt\n")); + printf(_(" --maintenance-db=DBNAME alternate maintenance database\n")); + printf(_("\nOther options:\n")); + printf(_(" -e, --echo show the commands being sent to the server\n")); + printf(_(" -j, --jobs=NUM use this many concurrent connections to the server\n")); + printf(_(" -q, --quiet don't write any messages\n")); + printf(_(" -P, --progress show progress information\n")); + printf(_(" -v, --verbose write a lot of output\n")); + printf(_(" -V, --version output version information, then exit\n")); + printf(_(" --install-missing install missing extensions\n")); + printf(_(" -?, --help show this help, then exit\n")); + + printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); + printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL); +} + +/* + * Print a progress report based on the global variables. + * + * Progress report is written at maximum once per second, unless the force + * parameter is set to true. + * + * If finished is set to true, this is the last progress report. The cursor + * is moved to the next line. + */ +static void +progress_report(uint64 relations_total, uint64 relations_checked, + uint64 relpages_total, uint64 relpages_checked, + const char *datname, bool force, bool finished) +{ + int percent_rel = 0; + int percent_pages = 0; + char checked_rel[32]; + char total_rel[32]; + char checked_pages[32]; + char total_pages[32]; + pg_time_t now; + + if (!opts.show_progress) + return; + + now = time(NULL); + if (now == last_progress_report && !force && !finished) + return; /* Max once per second */ + + last_progress_report = now; + if (relations_total) + percent_rel = (int) (relations_checked * 100 / relations_total); + if (relpages_total) + percent_pages = (int) (relpages_checked * 100 / relpages_total); + + /* + * Separate step to keep platform-dependent format code out of fprintf + * calls. We only test for INT64_FORMAT availability in snprintf, not + * fprintf. + */ + snprintf(checked_rel, sizeof(checked_rel), INT64_FORMAT, relations_checked); + snprintf(total_rel, sizeof(total_rel), INT64_FORMAT, relations_total); + snprintf(checked_pages, sizeof(checked_pages), INT64_FORMAT, relpages_checked); + snprintf(total_pages, sizeof(total_pages), INT64_FORMAT, relpages_total); + +#define VERBOSE_DATNAME_LENGTH 35 + if (opts.verbose) + { + if (!datname) + + /* + * No datname given, so clear the status line (used for first and + * last call) + */ + fprintf(stderr, + _("%*s/%s relations (%d%%) %*s/%s pages (%d%%) %*s"), + (int) strlen(total_rel), + checked_rel, total_rel, percent_rel, + (int) strlen(total_pages), + checked_pages, total_pages, percent_pages, + VERBOSE_DATNAME_LENGTH + 2, ""); + else + { + bool truncate = (strlen(datname) > VERBOSE_DATNAME_LENGTH); + + fprintf(stderr, + _("%*s/%s relations (%d%%) %*s/%s pages (%d%%), (%s%-*.*s)"), + (int) strlen(total_rel), + checked_rel, total_rel, percent_rel, + (int) strlen(total_pages), + checked_pages, total_pages, percent_pages, + /* Prefix with "..." if we do leading truncation */ + truncate ? "..." : "", + truncate ? VERBOSE_DATNAME_LENGTH - 3 : VERBOSE_DATNAME_LENGTH, + truncate ? VERBOSE_DATNAME_LENGTH - 3 : VERBOSE_DATNAME_LENGTH, + /* Truncate datname at beginning if it's too long */ + truncate ? datname + strlen(datname) - VERBOSE_DATNAME_LENGTH + 3 : datname); + } + } + else + fprintf(stderr, + _("%*s/%s relations (%d%%) %*s/%s pages (%d%%)"), + (int) strlen(total_rel), + checked_rel, total_rel, percent_rel, + (int) strlen(total_pages), + checked_pages, total_pages, percent_pages); + + /* + * Stay on the same line if reporting to a terminal and we're not done + * yet. + */ + if (!finished && isatty(fileno(stderr))) + { + fputc('\r', stderr); + progress_since_last_stderr = true; + } + else + fputc('\n', stderr); +} + +/* + * Extend the pattern info array to hold one additional initialized pattern + * info entry. + * + * Returns a pointer to the new entry. + */ +static PatternInfo * +extend_pattern_info_array(PatternInfoArray *pia) +{ + PatternInfo *result; + + pia->len++; + pia->data = (PatternInfo *) pg_realloc(pia->data, pia->len * sizeof(PatternInfo)); + result = &pia->data[pia->len - 1]; + memset(result, 0, sizeof(*result)); + + return result; +} + +/* + * append_database_pattern + * + * Adds the given pattern interpreted as a database name pattern. + * + * pia: the pattern info array to be appended + * pattern: the database name pattern + * encoding: client encoding for parsing the pattern + */ +static void +append_database_pattern(PatternInfoArray *pia, const char *pattern, int encoding) +{ + PQExpBufferData buf; + PatternInfo *info = extend_pattern_info_array(pia); + + initPQExpBuffer(&buf); + patternToSQLRegex(encoding, NULL, NULL, &buf, pattern, false); + info->pattern = pattern; + info->db_regex = pstrdup(buf.data); + + termPQExpBuffer(&buf); +} + +/* + * append_schema_pattern + * + * Adds the given pattern interpreted as a schema name pattern. + * + * pia: the pattern info array to be appended + * pattern: the schema name pattern + * encoding: client encoding for parsing the pattern + */ +static void +append_schema_pattern(PatternInfoArray *pia, const char *pattern, int encoding) +{ + PQExpBufferData dbbuf; + PQExpBufferData nspbuf; + PatternInfo *info = extend_pattern_info_array(pia); + + initPQExpBuffer(&dbbuf); + initPQExpBuffer(&nspbuf); + + patternToSQLRegex(encoding, NULL, &dbbuf, &nspbuf, pattern, false); + info->pattern = pattern; + if (dbbuf.data[0]) + { + opts.dbpattern = true; + info->db_regex = pstrdup(dbbuf.data); + } + if (nspbuf.data[0]) + info->nsp_regex = pstrdup(nspbuf.data); + + termPQExpBuffer(&dbbuf); + termPQExpBuffer(&nspbuf); +} + +/* + * append_relation_pattern_helper + * + * Adds to a list the given pattern interpreted as a relation pattern. + * + * pia: the pattern info array to be appended + * pattern: the relation name pattern + * encoding: client encoding for parsing the pattern + * heap_only: whether the pattern should only be matched against heap tables + * btree_only: whether the pattern should only be matched against btree indexes + */ +static void +append_relation_pattern_helper(PatternInfoArray *pia, const char *pattern, + int encoding, bool heap_only, bool btree_only) +{ + PQExpBufferData dbbuf; + PQExpBufferData nspbuf; + PQExpBufferData relbuf; + PatternInfo *info = extend_pattern_info_array(pia); + + initPQExpBuffer(&dbbuf); + initPQExpBuffer(&nspbuf); + initPQExpBuffer(&relbuf); + + patternToSQLRegex(encoding, &dbbuf, &nspbuf, &relbuf, pattern, false); + info->pattern = pattern; + if (dbbuf.data[0]) + { + opts.dbpattern = true; + info->db_regex = pstrdup(dbbuf.data); + } + if (nspbuf.data[0]) + info->nsp_regex = pstrdup(nspbuf.data); + if (relbuf.data[0]) + info->rel_regex = pstrdup(relbuf.data); + + termPQExpBuffer(&dbbuf); + termPQExpBuffer(&nspbuf); + termPQExpBuffer(&relbuf); + + info->heap_only = heap_only; + info->btree_only = btree_only; +} + +/* + * append_relation_pattern + * + * Adds the given pattern interpreted as a relation pattern, to be matched + * against both heap tables and btree indexes. + * + * pia: the pattern info array to be appended + * pattern: the relation name pattern + * encoding: client encoding for parsing the pattern + */ +static void +append_relation_pattern(PatternInfoArray *pia, const char *pattern, int encoding) +{ + append_relation_pattern_helper(pia, pattern, encoding, false, false); +} + +/* + * append_heap_pattern + * + * Adds the given pattern interpreted as a relation pattern, to be matched only + * against heap tables. + * + * pia: the pattern info array to be appended + * pattern: the relation name pattern + * encoding: client encoding for parsing the pattern + */ +static void +append_heap_pattern(PatternInfoArray *pia, const char *pattern, int encoding) +{ + append_relation_pattern_helper(pia, pattern, encoding, true, false); +} + +/* + * append_btree_pattern + * + * Adds the given pattern interpreted as a relation pattern, to be matched only + * against btree indexes. + * + * pia: the pattern info array to be appended + * pattern: the relation name pattern + * encoding: client encoding for parsing the pattern + */ +static void +append_btree_pattern(PatternInfoArray *pia, const char *pattern, int encoding) +{ + append_relation_pattern_helper(pia, pattern, encoding, false, true); +} + +/* + * append_db_pattern_cte + * + * Appends to the buffer the body of a Common Table Expression (CTE) containing + * the database portions filtered from the list of patterns expressed as two + * columns: + * + * pattern_id: the index of this pattern in pia->data[] + * rgx: the database regular expression parsed from the pattern + * + * Patterns without a database portion are skipped. Patterns with more than + * just a database portion are optionally skipped, depending on argument + * 'inclusive'. + * + * buf: the buffer to be appended + * pia: the array of patterns to be inserted into the CTE + * conn: the database connection + * inclusive: whether to include patterns with schema and/or relation parts + * + * Returns whether any database patterns were appended. + */ +static bool +append_db_pattern_cte(PQExpBuffer buf, const PatternInfoArray *pia, + PGconn *conn, bool inclusive) +{ + int pattern_id; + const char *comma; + bool have_values; + + comma = ""; + have_values = false; + for (pattern_id = 0; pattern_id < pia->len; pattern_id++) + { + PatternInfo *info = &pia->data[pattern_id]; + + if (info->db_regex != NULL && + (inclusive || (info->nsp_regex == NULL && info->rel_regex == NULL))) + { + if (!have_values) + appendPQExpBufferStr(buf, "\nVALUES"); + have_values = true; + appendPQExpBuffer(buf, "%s\n(%d, ", comma, pattern_id); + appendStringLiteralConn(buf, info->db_regex, conn); + appendPQExpBufferStr(buf, ")"); + comma = ","; + } + } + + if (!have_values) + appendPQExpBufferStr(buf, "\nSELECT NULL, NULL, NULL WHERE false"); + + return have_values; +} + +/* + * compile_database_list + * + * If any database patterns exist, or if --all was given, compiles a distinct + * list of databases to check using a SQL query based on the patterns plus the + * literal initial database name, if given. If no database patterns exist and + * --all was not given, the query is not necessary, and only the initial + * database name (if any) is added to the list. + * + * conn: connection to the initial database + * databases: the list onto which databases should be appended + * initial_dbname: an optional extra database name to include in the list + */ +static void +compile_database_list(PGconn *conn, SimplePtrList *databases, + const char *initial_dbname) +{ + PGresult *res; + PQExpBufferData sql; + int ntups; + int i; + bool fatal; + + if (initial_dbname) + { + DatabaseInfo *dat = (DatabaseInfo *) pg_malloc0(sizeof(DatabaseInfo)); + + /* This database is included. Add to list */ + if (opts.verbose) + pg_log_info("including database \"%s\"", initial_dbname); + + dat->datname = pstrdup(initial_dbname); + simple_ptr_list_append(databases, dat); + } + + initPQExpBuffer(&sql); + + /* Append the include patterns CTE. */ + appendPQExpBufferStr(&sql, "WITH include_raw (pattern_id, rgx) AS ("); + if (!append_db_pattern_cte(&sql, &opts.include, conn, true) && + !opts.alldb) + { + /* + * None of the inclusion patterns (if any) contain database portions, + * so there is no need to query the database to resolve database + * patterns. + * + * Since we're also not operating under --all, we don't need to query + * the exhaustive list of connectable databases, either. + */ + termPQExpBuffer(&sql); + return; + } + + /* Append the exclude patterns CTE. */ + appendPQExpBufferStr(&sql, "),\nexclude_raw (pattern_id, rgx) AS ("); + append_db_pattern_cte(&sql, &opts.exclude, conn, false); + appendPQExpBufferStr(&sql, "),"); + + /* + * Append the database CTE, which includes whether each database is + * connectable and also joins against exclude_raw to determine whether + * each database is excluded. + */ + appendPQExpBufferStr(&sql, + "\ndatabase (datname) AS (" + "\nSELECT d.datname " + "FROM pg_catalog.pg_database d " + "LEFT OUTER JOIN exclude_raw e " + "ON d.datname ~ e.rgx " + "\nWHERE d.datallowconn " + "AND e.pattern_id IS NULL" + ")," + + /* + * Append the include_pat CTE, which joins the include_raw CTE against the + * databases CTE to determine if all the inclusion patterns had matches, + * and whether each matched pattern had the misfortune of only matching + * excluded or unconnectable databases. + */ + "\ninclude_pat (pattern_id, checkable) AS (" + "\nSELECT i.pattern_id, " + "COUNT(*) FILTER (" + "WHERE d IS NOT NULL" + ") AS checkable" + "\nFROM include_raw i " + "LEFT OUTER JOIN database d " + "ON d.datname ~ i.rgx" + "\nGROUP BY i.pattern_id" + ")," + + /* + * Append the filtered_databases CTE, which selects from the database CTE + * optionally joined against the include_raw CTE to only select databases + * that match an inclusion pattern. This appears to duplicate what the + * include_pat CTE already did above, but here we want only databases, and + * there we wanted patterns. + */ + "\nfiltered_databases (datname) AS (" + "\nSELECT DISTINCT d.datname " + "FROM database d"); + if (!opts.alldb) + appendPQExpBufferStr(&sql, + " INNER JOIN include_raw i " + "ON d.datname ~ i.rgx"); + appendPQExpBufferStr(&sql, + ")" + + /* + * Select the checkable databases and the unmatched inclusion patterns. + */ + "\nSELECT pattern_id, datname FROM (" + "\nSELECT pattern_id, NULL::TEXT AS datname " + "FROM include_pat " + "WHERE checkable = 0 " + "UNION ALL" + "\nSELECT NULL, datname " + "FROM filtered_databases" + ") AS combined_records" + "\nORDER BY pattern_id NULLS LAST, datname"); + + res = executeQuery(conn, sql.data, opts.echo); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + pg_log_error("query failed: %s", PQerrorMessage(conn)); + pg_log_info("query was: %s", sql.data); + disconnectDatabase(conn); + exit(1); + } + termPQExpBuffer(&sql); + + ntups = PQntuples(res); + for (fatal = false, i = 0; i < ntups; i++) + { + int pattern_id = -1; + const char *datname = NULL; + + if (!PQgetisnull(res, i, 0)) + pattern_id = atoi(PQgetvalue(res, i, 0)); + if (!PQgetisnull(res, i, 1)) + datname = PQgetvalue(res, i, 1); + + if (pattern_id >= 0) + { + /* + * Current record pertains to an inclusion pattern that matched no + * checkable databases. + */ + fatal = opts.strict_names; + if (pattern_id >= opts.include.len) + { + pg_log_error("internal error: received unexpected database pattern_id %d", + pattern_id); + exit(1); + } + log_no_match("no connectable databases to check matching \"%s\"", + opts.include.data[pattern_id].pattern); + } + else + { + DatabaseInfo *dat; + + /* Current record pertains to a database */ + Assert(datname != NULL); + + /* Avoid entering a duplicate entry matching the initial_dbname */ + if (initial_dbname != NULL && strcmp(initial_dbname, datname) == 0) + continue; + + /* This database is included. Add to list */ + if (opts.verbose) + pg_log_info("including database \"%s\"", datname); + + dat = (DatabaseInfo *) pg_malloc0(sizeof(DatabaseInfo)); + dat->datname = pstrdup(datname); + simple_ptr_list_append(databases, dat); + } + } + PQclear(res); + + if (fatal) + { + if (conn != NULL) + disconnectDatabase(conn); + exit(1); + } +} + +/* + * append_rel_pattern_raw_cte + * + * Appends to the buffer the body of a Common Table Expression (CTE) containing + * the given patterns as six columns: + * + * pattern_id: the index of this pattern in pia->data[] + * db_regex: the database regexp parsed from the pattern, or NULL if the + * pattern had no database part + * nsp_regex: the namespace regexp parsed from the pattern, or NULL if the + * pattern had no namespace part + * rel_regex: the relname regexp parsed from the pattern, or NULL if the + * pattern had no relname part + * heap_only: true if the pattern applies only to heap tables (not indexes) + * btree_only: true if the pattern applies only to btree indexes (not tables) + * + * buf: the buffer to be appended + * patterns: the array of patterns to be inserted into the CTE + * conn: the database connection + */ +static void +append_rel_pattern_raw_cte(PQExpBuffer buf, const PatternInfoArray *pia, + PGconn *conn) +{ + int pattern_id; + const char *comma; + bool have_values; + + comma = ""; + have_values = false; + for (pattern_id = 0; pattern_id < pia->len; pattern_id++) + { + PatternInfo *info = &pia->data[pattern_id]; + + if (!have_values) + appendPQExpBufferStr(buf, "\nVALUES"); + have_values = true; + appendPQExpBuffer(buf, "%s\n(%d::INTEGER, ", comma, pattern_id); + if (info->db_regex == NULL) + appendPQExpBufferStr(buf, "NULL"); + else + appendStringLiteralConn(buf, info->db_regex, conn); + appendPQExpBufferStr(buf, "::TEXT, "); + if (info->nsp_regex == NULL) + appendPQExpBufferStr(buf, "NULL"); + else + appendStringLiteralConn(buf, info->nsp_regex, conn); + appendPQExpBufferStr(buf, "::TEXT, "); + if (info->rel_regex == NULL) + appendPQExpBufferStr(buf, "NULL"); + else + appendStringLiteralConn(buf, info->rel_regex, conn); + if (info->heap_only) + appendPQExpBufferStr(buf, "::TEXT, true::BOOLEAN"); + else + appendPQExpBufferStr(buf, "::TEXT, false::BOOLEAN"); + if (info->btree_only) + appendPQExpBufferStr(buf, ", true::BOOLEAN"); + else + appendPQExpBufferStr(buf, ", false::BOOLEAN"); + appendPQExpBufferStr(buf, ")"); + comma = ","; + } + + if (!have_values) + appendPQExpBufferStr(buf, + "\nSELECT NULL::INTEGER, NULL::TEXT, NULL::TEXT, " + "NULL::TEXT, NULL::BOOLEAN, NULL::BOOLEAN " + "WHERE false"); +} + +/* + * append_rel_pattern_filtered_cte + * + * Appends to the buffer a Common Table Expression (CTE) which selects + * all patterns from the named raw CTE, filtered by database. All patterns + * which have no database portion or whose database portion matches our + * connection's database name are selected, with other patterns excluded. + * + * The basic idea here is that if we're connected to database "foo" and we have + * patterns "foo.bar.baz", "alpha.beta" and "one.two.three", we only want to + * use the first two while processing relations in this database, as the third + * one is not relevant. + * + * buf: the buffer to be appended + * raw: the name of the CTE to select from + * filtered: the name of the CTE to create + * conn: the database connection + */ +static void +append_rel_pattern_filtered_cte(PQExpBuffer buf, const char *raw, + const char *filtered, PGconn *conn) +{ + appendPQExpBuffer(buf, + "\n%s (pattern_id, nsp_regex, rel_regex, heap_only, btree_only) AS (" + "\nSELECT pattern_id, nsp_regex, rel_regex, heap_only, btree_only " + "FROM %s r" + "\nWHERE (r.db_regex IS NULL " + "OR ", + filtered, raw); + appendStringLiteralConn(buf, PQdb(conn), conn); + appendPQExpBufferStr(buf, " ~ r.db_regex)"); + appendPQExpBufferStr(buf, + " AND (r.nsp_regex IS NOT NULL" + " OR r.rel_regex IS NOT NULL)" + "),"); +} + +/* + * compile_relation_list_one_db + * + * Compiles a list of relations to check within the currently connected + * database based on the user supplied options, sorted by descending size, + * and appends them to the given list of relations. + * + * The cells of the constructed list contain all information about the relation + * necessary to connect to the database and check the object, including which + * database to connect to, where contrib/amcheck is installed, and the Oid and + * type of object (heap table vs. btree index). Rather than duplicating the + * database details per relation, the relation structs use references to the + * same database object, provided by the caller. + * + * conn: connection to this next database, which should be the same as in 'dat' + * relations: list onto which the relations information should be appended + * dat: the database info struct for use by each relation + * pagecount: gets incremented by the number of blocks to check in all + * relations added + */ +static void +compile_relation_list_one_db(PGconn *conn, SimplePtrList *relations, + const DatabaseInfo *dat, + uint64 *pagecount) +{ + PGresult *res; + PQExpBufferData sql; + int ntups; + int i; + + initPQExpBuffer(&sql); + appendPQExpBufferStr(&sql, "WITH"); + + /* Append CTEs for the relation inclusion patterns, if any */ + if (!opts.allrel) + { + appendPQExpBufferStr(&sql, + " include_raw (pattern_id, db_regex, nsp_regex, rel_regex, heap_only, btree_only) AS ("); + append_rel_pattern_raw_cte(&sql, &opts.include, conn); + appendPQExpBufferStr(&sql, "\n),"); + append_rel_pattern_filtered_cte(&sql, "include_raw", "include_pat", conn); + } + + /* Append CTEs for the relation exclusion patterns, if any */ + if (opts.excludetbl || opts.excludeidx || opts.excludensp) + { + appendPQExpBufferStr(&sql, + " exclude_raw (pattern_id, db_regex, nsp_regex, rel_regex, heap_only, btree_only) AS ("); + append_rel_pattern_raw_cte(&sql, &opts.exclude, conn); + appendPQExpBufferStr(&sql, "\n),"); + append_rel_pattern_filtered_cte(&sql, "exclude_raw", "exclude_pat", conn); + } + + /* Append the relation CTE. */ + appendPQExpBufferStr(&sql, + " relation (pattern_id, oid, nspname, relname, reltoastrelid, relpages, is_heap, is_btree) AS (" + "\nSELECT DISTINCT ON (c.oid"); + if (!opts.allrel) + appendPQExpBufferStr(&sql, ", ip.pattern_id) ip.pattern_id,"); + else + appendPQExpBufferStr(&sql, ") NULL::INTEGER AS pattern_id,"); + appendPQExpBuffer(&sql, + "\nc.oid, n.nspname, c.relname, c.reltoastrelid, c.relpages, " + "c.relam = %u AS is_heap, " + "c.relam = %u AS is_btree" + "\nFROM pg_catalog.pg_class c " + "INNER JOIN pg_catalog.pg_namespace n " + "ON c.relnamespace = n.oid", + HEAP_TABLE_AM_OID, BTREE_AM_OID); + if (!opts.allrel) + appendPQExpBuffer(&sql, + "\nINNER JOIN include_pat ip" + "\nON (n.nspname ~ ip.nsp_regex OR ip.nsp_regex IS NULL)" + "\nAND (c.relname ~ ip.rel_regex OR ip.rel_regex IS NULL)" + "\nAND (c.relam = %u OR NOT ip.heap_only)" + "\nAND (c.relam = %u OR NOT ip.btree_only)", + HEAP_TABLE_AM_OID, BTREE_AM_OID); + if (opts.excludetbl || opts.excludeidx || opts.excludensp) + appendPQExpBuffer(&sql, + "\nLEFT OUTER JOIN exclude_pat ep" + "\nON (n.nspname ~ ep.nsp_regex OR ep.nsp_regex IS NULL)" + "\nAND (c.relname ~ ep.rel_regex OR ep.rel_regex IS NULL)" + "\nAND (c.relam = %u OR NOT ep.heap_only OR ep.rel_regex IS NULL)" + "\nAND (c.relam = %u OR NOT ep.btree_only OR ep.rel_regex IS NULL)", + HEAP_TABLE_AM_OID, BTREE_AM_OID); + + if (opts.excludetbl || opts.excludeidx || opts.excludensp) + appendPQExpBufferStr(&sql, "\nWHERE ep.pattern_id IS NULL"); + else + appendPQExpBufferStr(&sql, "\nWHERE true"); + + /* + * We need to be careful not to break the --no-dependent-toast and + * --no-dependent-indexes options. By default, the btree indexes, toast + * tables, and toast table btree indexes associated with primary heap + * tables are included, using their own CTEs below. We implement the + * --exclude-* options by not creating those CTEs, but that's no use if + * we've already selected the toast and indexes here. On the other hand, + * we want inclusion patterns that match indexes or toast tables to be + * honored. So, if inclusion patterns were given, we want to select all + * tables, toast tables, or indexes that match the patterns. But if no + * inclusion patterns were given, and we're simply matching all relations, + * then we only want to match the primary tables here. + */ + if (opts.allrel) + appendPQExpBuffer(&sql, + " AND c.relam = %u " + "AND c.relkind IN ('r', 'm', 't') " + "AND c.relnamespace != %u", + HEAP_TABLE_AM_OID, PG_TOAST_NAMESPACE); + else + appendPQExpBuffer(&sql, + " AND c.relam IN (%u, %u)" + "AND c.relkind IN ('r', 'm', 't', 'i') " + "AND ((c.relam = %u AND c.relkind IN ('r', 'm', 't')) OR " + "(c.relam = %u AND c.relkind = 'i'))", + HEAP_TABLE_AM_OID, BTREE_AM_OID, + HEAP_TABLE_AM_OID, BTREE_AM_OID); + + appendPQExpBufferStr(&sql, + "\nORDER BY c.oid)"); + + if (!opts.no_toast_expansion) + { + /* + * Include a CTE for toast tables associated with primary heap tables + * selected above, filtering by exclusion patterns (if any) that match + * toast table names. + */ + appendPQExpBufferStr(&sql, + ", toast (oid, nspname, relname, relpages) AS (" + "\nSELECT t.oid, 'pg_toast', t.relname, t.relpages" + "\nFROM pg_catalog.pg_class t " + "INNER JOIN relation r " + "ON r.reltoastrelid = t.oid"); + if (opts.excludetbl || opts.excludensp) + appendPQExpBufferStr(&sql, + "\nLEFT OUTER JOIN exclude_pat ep" + "\nON ('pg_toast' ~ ep.nsp_regex OR ep.nsp_regex IS NULL)" + "\nAND (t.relname ~ ep.rel_regex OR ep.rel_regex IS NULL)" + "\nAND ep.heap_only" + "\nWHERE ep.pattern_id IS NULL"); + appendPQExpBufferStr(&sql, + "\n)"); + } + if (!opts.no_btree_expansion) + { + /* + * Include a CTE for btree indexes associated with primary heap tables + * selected above, filtering by exclusion patterns (if any) that match + * btree index names. + */ + appendPQExpBuffer(&sql, + ", index (oid, nspname, relname, relpages) AS (" + "\nSELECT c.oid, r.nspname, c.relname, c.relpages " + "FROM relation r" + "\nINNER JOIN pg_catalog.pg_index i " + "ON r.oid = i.indrelid " + "INNER JOIN pg_catalog.pg_class c " + "ON i.indexrelid = c.oid"); + if (opts.excludeidx || opts.excludensp) + appendPQExpBufferStr(&sql, + "\nINNER JOIN pg_catalog.pg_namespace n " + "ON c.relnamespace = n.oid" + "\nLEFT OUTER JOIN exclude_pat ep " + "ON (n.nspname ~ ep.nsp_regex OR ep.nsp_regex IS NULL) " + "AND (c.relname ~ ep.rel_regex OR ep.rel_regex IS NULL) " + "AND ep.btree_only" + "\nWHERE ep.pattern_id IS NULL"); + else + appendPQExpBufferStr(&sql, + "\nWHERE true"); + appendPQExpBuffer(&sql, + " AND c.relam = %u " + "AND c.relkind = 'i'", + BTREE_AM_OID); + if (opts.no_toast_expansion) + appendPQExpBuffer(&sql, + " AND c.relnamespace != %u", + PG_TOAST_NAMESPACE); + appendPQExpBufferStr(&sql, "\n)"); + } + + if (!opts.no_toast_expansion && !opts.no_btree_expansion) + { + /* + * Include a CTE for btree indexes associated with toast tables of + * primary heap tables selected above, filtering by exclusion patterns + * (if any) that match the toast index names. + */ + appendPQExpBuffer(&sql, + ", toast_index (oid, nspname, relname, relpages) AS (" + "\nSELECT c.oid, 'pg_toast', c.relname, c.relpages " + "FROM toast t " + "INNER JOIN pg_catalog.pg_index i " + "ON t.oid = i.indrelid" + "\nINNER JOIN pg_catalog.pg_class c " + "ON i.indexrelid = c.oid"); + if (opts.excludeidx) + appendPQExpBufferStr(&sql, + "\nLEFT OUTER JOIN exclude_pat ep " + "ON ('pg_toast' ~ ep.nsp_regex OR ep.nsp_regex IS NULL) " + "AND (c.relname ~ ep.rel_regex OR ep.rel_regex IS NULL) " + "AND ep.btree_only " + "WHERE ep.pattern_id IS NULL"); + else + appendPQExpBufferStr(&sql, + "\nWHERE true"); + appendPQExpBuffer(&sql, + " AND c.relam = %u" + " AND c.relkind = 'i')", + BTREE_AM_OID); + } + + /* + * Roll-up distinct rows from CTEs. + * + * Relations that match more than one pattern may occur more than once in + * the list, and indexes and toast for primary relations may also have + * matched in their own right, so we rely on UNION to deduplicate the + * list. + */ + appendPQExpBuffer(&sql, + "\nSELECT pattern_id, is_heap, is_btree, oid, nspname, relname, relpages " + "FROM ("); + appendPQExpBufferStr(&sql, + /* Inclusion patterns that failed to match */ + "\nSELECT pattern_id, is_heap, is_btree, " + "NULL::OID AS oid, " + "NULL::TEXT AS nspname, " + "NULL::TEXT AS relname, " + "NULL::INTEGER AS relpages" + "\nFROM relation " + "WHERE pattern_id IS NOT NULL " + "UNION" + /* Primary relations */ + "\nSELECT NULL::INTEGER AS pattern_id, " + "is_heap, is_btree, oid, nspname, relname, relpages " + "FROM relation"); + if (!opts.no_toast_expansion) + appendPQExpBufferStr(&sql, + " UNION" + /* Toast tables for primary relations */ + "\nSELECT NULL::INTEGER AS pattern_id, TRUE AS is_heap, " + "FALSE AS is_btree, oid, nspname, relname, relpages " + "FROM toast"); + if (!opts.no_btree_expansion) + appendPQExpBufferStr(&sql, + " UNION" + /* Indexes for primary relations */ + "\nSELECT NULL::INTEGER AS pattern_id, FALSE AS is_heap, " + "TRUE AS is_btree, oid, nspname, relname, relpages " + "FROM index"); + if (!opts.no_toast_expansion && !opts.no_btree_expansion) + appendPQExpBufferStr(&sql, + " UNION" + /* Indexes for toast relations */ + "\nSELECT NULL::INTEGER AS pattern_id, FALSE AS is_heap, " + "TRUE AS is_btree, oid, nspname, relname, relpages " + "FROM toast_index"); + appendPQExpBufferStr(&sql, + "\n) AS combined_records " + "ORDER BY relpages DESC NULLS FIRST, oid"); + + res = executeQuery(conn, sql.data, opts.echo); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + pg_log_error("query failed: %s", PQerrorMessage(conn)); + pg_log_info("query was: %s", sql.data); + disconnectDatabase(conn); + exit(1); + } + termPQExpBuffer(&sql); + + ntups = PQntuples(res); + for (i = 0; i < ntups; i++) + { + int pattern_id = -1; + bool is_heap = false; + bool is_btree PG_USED_FOR_ASSERTS_ONLY = false; + Oid oid = InvalidOid; + const char *nspname = NULL; + const char *relname = NULL; + int relpages = 0; + + if (!PQgetisnull(res, i, 0)) + pattern_id = atoi(PQgetvalue(res, i, 0)); + if (!PQgetisnull(res, i, 1)) + is_heap = (PQgetvalue(res, i, 1)[0] == 't'); + if (!PQgetisnull(res, i, 2)) + is_btree = (PQgetvalue(res, i, 2)[0] == 't'); + if (!PQgetisnull(res, i, 3)) + oid = atooid(PQgetvalue(res, i, 3)); + if (!PQgetisnull(res, i, 4)) + nspname = PQgetvalue(res, i, 4); + if (!PQgetisnull(res, i, 5)) + relname = PQgetvalue(res, i, 5); + if (!PQgetisnull(res, i, 6)) + relpages = atoi(PQgetvalue(res, i, 6)); + + if (pattern_id >= 0) + { + /* + * Current record pertains to an inclusion pattern. Record that + * it matched. + */ + + if (pattern_id >= opts.include.len) + { + pg_log_error("internal error: received unexpected relation pattern_id %d", + pattern_id); + exit(1); + } + + opts.include.data[pattern_id].matched = true; + } + else + { + /* Current record pertains to a relation */ + + RelationInfo *rel = (RelationInfo *) pg_malloc0(sizeof(RelationInfo)); + + Assert(OidIsValid(oid)); + Assert((is_heap && !is_btree) || (is_btree && !is_heap)); + + rel->datinfo = dat; + rel->reloid = oid; + rel->is_heap = is_heap; + rel->nspname = pstrdup(nspname); + rel->relname = pstrdup(relname); + rel->relpages = relpages; + rel->blocks_to_check = relpages; + if (is_heap && (opts.startblock >= 0 || opts.endblock >= 0)) + { + /* + * We apply --startblock and --endblock to heap tables, but + * not btree indexes, and for progress purposes we need to + * track how many blocks we expect to check. + */ + if (opts.endblock >= 0 && rel->blocks_to_check > opts.endblock) + rel->blocks_to_check = opts.endblock + 1; + if (opts.startblock >= 0) + { + if (rel->blocks_to_check > opts.startblock) + rel->blocks_to_check -= opts.startblock; + else + rel->blocks_to_check = 0; + } + } + *pagecount += rel->blocks_to_check; + + simple_ptr_list_append(relations, rel); + } + } + PQclear(res); +} diff --git a/src/bin/pg_amcheck/po/de.po b/src/bin/pg_amcheck/po/de.po new file mode 100644 index 000000000000..ce036e3645e0 --- /dev/null +++ b/src/bin/pg_amcheck/po/de.po @@ -0,0 +1,461 @@ +# German message translation file for pg_amcheck +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_amcheck (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_amcheck (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 01:48+0000\n" +"PO-Revision-Date: 2021-05-14 10:03+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Abbruchsanforderung gesendet\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "Konnte Abbruchsanforderung nicht senden: " + +#: ../../fe_utils/connect_utils.c:92 +#, c-format +msgid "could not connect to database %s: out of memory" +msgstr "konnte nicht mit Datenbank %s verbinden: Speicher aufgebraucht" + +#: ../../fe_utils/connect_utils.c:120 +#, c-format +msgid "%s" +msgstr "%s" + +#: ../../fe_utils/query_utils.c:33 ../../fe_utils/query_utils.c:58 +#: pg_amcheck.c:1645 pg_amcheck.c:2084 +#, c-format +msgid "query failed: %s" +msgstr "Anfrage fehlgeschlagen: %s" + +#: ../../fe_utils/query_utils.c:34 ../../fe_utils/query_utils.c:59 +#: pg_amcheck.c:597 pg_amcheck.c:1116 pg_amcheck.c:1646 pg_amcheck.c:2085 +#, c-format +msgid "query was: %s" +msgstr "Anfrage war: %s" + +#: pg_amcheck.c:332 +#, c-format +msgid "number of parallel jobs must be at least 1" +msgstr "Anzahl paralleler Jobs muss mindestens 1 sein" + +#: pg_amcheck.c:405 +#, c-format +msgid "invalid argument for option %s" +msgstr "ungültiges Argument für Option %s" + +#: pg_amcheck.c:413 +#, c-format +msgid "invalid start block" +msgstr "ungültiger Startblock" + +#: pg_amcheck.c:418 +#, c-format +msgid "start block out of bounds" +msgstr "Startblock außerhalb des gültigen Bereichs" + +#: pg_amcheck.c:426 +#, c-format +msgid "invalid end block" +msgstr "ungültiger Endblock" + +#: pg_amcheck.c:431 +#, c-format +msgid "end block out of bounds" +msgstr "Endblock außerhalb des gültigen Bereichs" + +#: pg_amcheck.c:455 pg_amcheck.c:481 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_amcheck.c:463 +#, c-format +msgid "end block precedes start block" +msgstr "Endblock kommt vor dem Startblock" + +#: pg_amcheck.c:479 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_amcheck.c:500 +#, c-format +msgid "cannot specify a database name with --all" +msgstr "ein Datenbankname kann nicht mit --all angegeben werden" + +#: pg_amcheck.c:509 +#, c-format +msgid "cannot specify both a database name and database patterns" +msgstr "Datenbankname und Datenbankmuster können nicht zusammen angegeben werden" + +#: pg_amcheck.c:539 +#, c-format +msgid "no databases to check" +msgstr "keine zu prüfenden Datenbanken" + +#: pg_amcheck.c:595 +#, c-format +msgid "database \"%s\": %s" +msgstr "Datenbank »%s«: %s" + +#: pg_amcheck.c:606 +#, c-format +msgid "skipping database \"%s\": amcheck is not installed" +msgstr "Datenbank »%s« übersprungen: amcheck nicht installiert" + +#: pg_amcheck.c:614 +#, c-format +msgid "in database \"%s\": using amcheck version \"%s\" in schema \"%s\"" +msgstr "in Datenbank »%s«: verwende amcheck Version »%s« in Schema »%s«" + +#: pg_amcheck.c:676 +#, c-format +msgid "no relations to check" +msgstr "keine zu prüfenden Relationen" + +#: pg_amcheck.c:762 +#, c-format +msgid "checking heap table \"%s\".\"%s\".\"%s\"" +msgstr "prüfe Heap-Tabelle \"%s\".\"%s\".\"%s\"" + +#: pg_amcheck.c:778 +#, c-format +msgid "checking btree index \"%s\".\"%s\".\"%s\"" +msgstr "prüfe B-Tree-Index \"%s\".\"%s\".\"%s\"" + +#: pg_amcheck.c:911 +#, c-format +msgid "error sending command to database \"%s\": %s" +msgstr "Fehler beim Senden von Befehl an Datenbank »%s«: %s" + +#: pg_amcheck.c:914 +#, c-format +msgid "command was: %s" +msgstr "Befehl war: %s" + +#: pg_amcheck.c:1113 +#, c-format +msgid "btree index \"%s\".\"%s\".\"%s\": btree checking function returned unexpected number of rows: %d" +msgstr "" + +#: pg_amcheck.c:1117 +#, c-format +msgid "Are %s's and amcheck's versions compatible?" +msgstr "Sind die Versionen von %s und amcheck kompatibel?" + +#: pg_amcheck.c:1151 +#, c-format +msgid "" +"%s checks objects in a PostgreSQL database for corruption.\n" +"\n" +msgstr "%s prüft Objekte in einer PostgreSQL-Datenbank auf Beschädigung.\n\n" + +#: pg_amcheck.c:1152 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_amcheck.c:1153 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]... [DBNAME]\n" + +#: pg_amcheck.c:1154 +#, c-format +msgid "" +"\n" +"Target options:\n" +msgstr "" +"\n" +"Zieloptionen:\n" + +#: pg_amcheck.c:1155 +#, c-format +msgid " -a, --all check all databases\n" +msgstr " -a, --all alle Datenbanken prüfen\n" + +#: pg_amcheck.c:1156 +#, c-format +msgid " -d, --database=PATTERN check matching database(s)\n" +msgstr " -d, --database=MUSTER übereinstimmende Datenbanken prüfen\n" + +#: pg_amcheck.c:1157 +#, c-format +msgid " -D, --exclude-database=PATTERN do NOT check matching database(s)\n" +msgstr " -D, --exclude-database=MUSTER übereinstimmende Datenbanken NICHT prüfen\n" + +#: pg_amcheck.c:1158 +#, c-format +msgid " -i, --index=PATTERN check matching index(es)\n" +msgstr " -i, --index=MUSTER übereinstimmende Indexe prüfen\n" + +#: pg_amcheck.c:1159 +#, c-format +msgid " -I, --exclude-index=PATTERN do NOT check matching index(es)\n" +msgstr " -I, --exclude-index=MUSTER übereinstimmende Indexe NICHT prüfen\n" + +#: pg_amcheck.c:1160 +#, c-format +msgid " -r, --relation=PATTERN check matching relation(s)\n" +msgstr " -r, --relation=MUSTER übereinstimmende Relationen prüfen\n" + +#: pg_amcheck.c:1161 +#, c-format +msgid " -R, --exclude-relation=PATTERN do NOT check matching relation(s)\n" +msgstr " -R, --exclude-relation=MUSTER übereinstimmende Relationen NICHT prüfen\n" + +#: pg_amcheck.c:1162 +#, c-format +msgid " -s, --schema=PATTERN check matching schema(s)\n" +msgstr " -s, --schema=MUSTER übereinstimmende Schemas prüfen\n" + +#: pg_amcheck.c:1163 +#, c-format +msgid " -S, --exclude-schema=PATTERN do NOT check matching schema(s)\n" +msgstr " -S, --exclude-schema=MUSTER übereinstimmende Schemas NICHT prüfen\n" + +#: pg_amcheck.c:1164 +#, c-format +msgid " -t, --table=PATTERN check matching table(s)\n" +msgstr " -t, --table=MUSTER übereinstimmende Tabellen prüfen\n" + +#: pg_amcheck.c:1165 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT check matching table(s)\n" +msgstr " -T, --exclude-table=MUSTER übereinstimmende Tabellen NICHT prüfen\n" + +#: pg_amcheck.c:1166 +#, c-format +msgid " --no-dependent-indexes do NOT expand list of relations to include indexes\n" +msgstr " --no-dependent-indexes Liste der Relationen NICHT um Indexe erweitern\n" + +#: pg_amcheck.c:1167 +#, c-format +msgid " --no-dependent-toast do NOT expand list of relations to include TOAST tables\n" +msgstr " --no-dependent-toast Liste der Relationen NICHT um TOAST-Tabellen erweitern\n" + +#: pg_amcheck.c:1168 +#, c-format +msgid " --no-strict-names do NOT require patterns to match objects\n" +msgstr " --no-strict-names Muster müssen NICHT mit Objekten übereinstimmen\n" + +#: pg_amcheck.c:1169 +#, c-format +msgid "" +"\n" +"Table checking options:\n" +msgstr "" +"\n" +"Optionen für Tabellen:\n" + +#: pg_amcheck.c:1170 +#, c-format +msgid " --exclude-toast-pointers do NOT follow relation TOAST pointers\n" +msgstr " --exclude-toast-pointers TOAST-Zeigern NICHT folgen\n" + +#: pg_amcheck.c:1171 +#, c-format +msgid " --on-error-stop stop checking at end of first corrupt page\n" +msgstr " --on-error-stop Prüfung nach der ersten beschädigten Seite beenden\n" + +#: pg_amcheck.c:1172 +#, c-format +msgid " --skip=OPTION do NOT check \"all-frozen\" or \"all-visible\" blocks\n" +msgstr " --skip=OPTION Blöcke mit »all-frozen« oder »all-visible« NICHT prüfen\n" + +#: pg_amcheck.c:1173 +#, c-format +msgid " --startblock=BLOCK begin checking table(s) at the given block number\n" +msgstr "" + +#: pg_amcheck.c:1174 +#, c-format +msgid " --endblock=BLOCK check table(s) only up to the given block number\n" +msgstr "" + +#: pg_amcheck.c:1175 +#, c-format +msgid "" +"\n" +"B-tree index checking options:\n" +msgstr "" +"\n" +"Optionen für B-Tree-Indexe:\n" + +#: pg_amcheck.c:1176 +#, c-format +msgid " --heapallindexed check all heap tuples are found within indexes\n" +msgstr "" + +#: pg_amcheck.c:1177 +#, c-format +msgid " --parent-check check index parent/child relationships\n" +msgstr "" + +#: pg_amcheck.c:1178 +#, c-format +msgid " --rootdescend search from root page to refind tuples\n" +msgstr "" + +#: pg_amcheck.c:1179 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Verbindungsoptionen:\n" + +#: pg_amcheck.c:1180 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" + +#: pg_amcheck.c:1181 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, --port=PORT Port des Datenbankservers\n" + +#: pg_amcheck.c:1182 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, --username=NAME Datenbankbenutzername\n" + +#: pg_amcheck.c:1183 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password niemals nach Passwort fragen\n" + +#: pg_amcheck.c:1184 +#, c-format +msgid " -W, --password force password prompt\n" +msgstr " -W, --password Passwortfrage erzwingen\n" + +#: pg_amcheck.c:1185 +#, c-format +msgid " --maintenance-db=DBNAME alternate maintenance database\n" +msgstr " --maintenance-db=DBNAME alternative Wartungsdatenbank\n" + +#: pg_amcheck.c:1186 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Weitere Optionen:\n" + +#: pg_amcheck.c:1187 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr "" +" -e, --echo zeige die Befehle, die an den Server\n" +" gesendet werden\n" + +#: pg_amcheck.c:1188 +#, c-format +msgid " -j, --jobs=NUM use this many concurrent connections to the server\n" +msgstr "" +" -j, --jobs=NUM so viele parallele Verbindungen zum Server\n" +" verwenden\n" + +#: pg_amcheck.c:1189 +#, c-format +msgid " -q, --quiet don't write any messages\n" +msgstr " -q, --quiet unterdrücke alle Mitteilungen\n" + +#: pg_amcheck.c:1190 +#, c-format +msgid " -v, --verbose write a lot of output\n" +msgstr " -v, --verbose erzeuge viele Meldungen\n" + +#: pg_amcheck.c:1191 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_amcheck.c:1192 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress Fortschrittsinformationen zeigen\n" + +#: pg_amcheck.c:1193 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_amcheck.c:1194 +#, c-format +msgid " --install-missing install missing extensions\n" +msgstr " --install-missing fehlende Erweiterungen installieren\n" + +#: pg_amcheck.c:1196 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: pg_amcheck.c:1197 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: pg_amcheck.c:1255 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%) %*s" +msgstr "" + +#: pg_amcheck.c:1266 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%), (%s%-*.*s)" +msgstr "" + +#: pg_amcheck.c:1281 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%)" +msgstr "" + +#: pg_amcheck.c:1550 pg_amcheck.c:1692 +#, c-format +msgid "including database \"%s\"" +msgstr "Datenbank »%s« einbezogen" + +#: pg_amcheck.c:1672 +#, c-format +msgid "internal error: received unexpected database pattern_id %d" +msgstr "" + +#: pg_amcheck.c:2126 +#, c-format +msgid "internal error: received unexpected relation pattern_id %d" +msgstr "" diff --git a/src/bin/pg_amcheck/po/el.po b/src/bin/pg_amcheck/po/el.po new file mode 100644 index 000000000000..0df10aaa5c8e --- /dev/null +++ b/src/bin/pg_amcheck/po/el.po @@ -0,0 +1,465 @@ +# Greek message translation file for pg_amcheck +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_amcheck (PostgreSQL) package. +# Georgios Kokolatos , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_amcheck (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-17 03:48+0000\n" +"PO-Revision-Date: 2021-05-24 10:34+0200\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση: " + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Αίτηση ακύρωσης εστάλη\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "Δεν ήταν δυνατή η αποστολή αίτησης ακύρωσης: " + +#: ../../fe_utils/connect_utils.c:92 +#, c-format +msgid "could not connect to database %s: out of memory" +msgstr "δεν ήταν δυνατή η σύνδεση με τη βάσης δεδομένων %s: έλλειψη μνήμης" + +#: ../../fe_utils/connect_utils.c:120 +#, c-format +msgid "%s" +msgstr "%s" + +#: ../../fe_utils/query_utils.c:33 ../../fe_utils/query_utils.c:58 +#: pg_amcheck.c:1645 pg_amcheck.c:2084 +#, c-format +msgid "query failed: %s" +msgstr "το ερώτημα απέτυχε: %s" + +#: ../../fe_utils/query_utils.c:34 ../../fe_utils/query_utils.c:59 +#: pg_amcheck.c:597 pg_amcheck.c:1116 pg_amcheck.c:1646 pg_amcheck.c:2085 +#, c-format +msgid "query was: %s" +msgstr "το ερώτημα ήταν: %s" + +#: pg_amcheck.c:332 +#, c-format +msgid "number of parallel jobs must be at least 1" +msgstr "ο αριθμός παράλληλων εργασιών πρέπει να είναι τουλάχιστον 1" + +#: pg_amcheck.c:405 +#, c-format +msgid "invalid argument for option %s" +msgstr "μη έγκυρη παράμετρος για την επιλογή %s" + +#: pg_amcheck.c:413 +#, c-format +msgid "invalid start block" +msgstr "μη έγκυρο μπλοκ εκκίνησης" + +#: pg_amcheck.c:418 +#, c-format +msgid "start block out of bounds" +msgstr "μπλοκ εκκίνησης εκτός ορίων" + +#: pg_amcheck.c:426 +#, c-format +msgid "invalid end block" +msgstr "μη έγκυρο μπλοκ τερματισμού" + +#: pg_amcheck.c:431 +#, c-format +msgid "end block out of bounds" +msgstr "μπλοκ τερματισμού εκτός ορίων" + +#: pg_amcheck.c:455 pg_amcheck.c:481 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_amcheck.c:463 +#, c-format +msgid "end block precedes start block" +msgstr "μπλοκ τερματισμού προηγείται του μπλοκ εκκίνησης" + +#: pg_amcheck.c:479 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (ο πρώτη είναι η “%s”)" + +#: pg_amcheck.c:500 +#, c-format +msgid "cannot specify a database name with --all" +msgstr "δεν είναι δυνατό να οριστεί ένα όνομα βάσης δεδομένων μαζί με —all" + +#: pg_amcheck.c:509 +#, c-format +msgid "cannot specify both a database name and database patterns" +msgstr "δεν είναι δυνατός ο καθορισμός τόσο ενός ονόματος βάσης δεδομένων όσο και μοτίβων βάσης δεδομένων" + +#: pg_amcheck.c:539 +#, c-format +msgid "no databases to check" +msgstr "καθόλου βάσεις δεδομένων για έλεγχο" + +#: pg_amcheck.c:595 +#, c-format +msgid "database \"%s\": %s" +msgstr "βάση δεδομένων “%s”: %s" + +#: pg_amcheck.c:606 +#, c-format +msgid "skipping database \"%s\": amcheck is not installed" +msgstr "παρακάμπτει βάση δεδομένων “%s”: το amcheck δεν είναι εγκαταστημένο" + +#: pg_amcheck.c:614 +#, c-format +msgid "in database \"%s\": using amcheck version \"%s\" in schema \"%s\"" +msgstr "στη βάση δεδομένων \"%s\": χρησιμοποιώντας την έκδοση \"%s\" του amcheck στο σχήμα \"%s\"" + +#: pg_amcheck.c:676 +#, c-format +msgid "no relations to check" +msgstr "καθόλου σχέσεις για έλεγχο" + +#: pg_amcheck.c:762 +#, c-format +msgid "checking heap table \"%s\".\"%s\".\"%s\"" +msgstr "ελέγχει τον πίνακα heap “%s”.”%s”.”%s”" + +#: pg_amcheck.c:778 +#, c-format +msgid "checking btree index \"%s\".\"%s\".\"%s\"" +msgstr "ελέγχει το ευρετήριο btree “%s”.”%s”.”%s”" + +#: pg_amcheck.c:911 +#, c-format +msgid "error sending command to database \"%s\": %s" +msgstr "εντολή αποστολής σφάλματος στη βάση δεδομένων \"%s\": %s" + +#: pg_amcheck.c:914 +#, c-format +msgid "command was: %s" +msgstr "η εντολή ήταν: %s" + +#: pg_amcheck.c:1113 +#, c-format +msgid "btree index \"%s\".\"%s\".\"%s\": btree checking function returned unexpected number of rows: %d" +msgstr "ευρετήριο btree \"%s\". %s\".\" %s\": η συνάρτηση ελέγχου btree επέστρεψε απροσδόκητο αριθμό γραμμών: %d" + +#: pg_amcheck.c:1117 +#, c-format +msgid "Are %s's and amcheck's versions compatible?" +msgstr "Είναι συμβατές οι εκδόσεις του %s και του amcheck;" + +#: pg_amcheck.c:1151 +#, c-format +msgid "" +"%s checks objects in a PostgreSQL database for corruption.\n" +"\n" +msgstr "" +"%s ελέγχει αντικείμενα σε μια βάση δεδομένων PostgreSQL για αλλοίωση.\n" +"\n" + +#: pg_amcheck.c:1152 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_amcheck.c:1153 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]… [DBNAME]\n" + +#: pg_amcheck.c:1154 +#, c-format +msgid "" +"\n" +"Target options:\n" +msgstr "" +"\n" +"Επιλογές στόχου:\n" + +#: pg_amcheck.c:1155 +#, c-format +msgid " -a, --all check all databases\n" +msgstr " -a, —all έλεγξε όλες τις βάσεις δεδομένων\n" + +#: pg_amcheck.c:1156 +#, c-format +msgid " -d, --database=PATTERN check matching database(s)\n" +msgstr " -d, —database=PATTERN έλεγξε ταιριαστή(-ες) με το μοτίβο βάση(-εις) δεδομένων\n" + +#: pg_amcheck.c:1157 +#, c-format +msgid " -D, --exclude-database=PATTERN do NOT check matching database(s)\n" +msgstr " -D, —exclude-database=PATTERN να ΜΗΝ ελέγξει ταιριαστή(-ες) με το μοτίβο βάση(-εις) δεδομένων\n" + +#: pg_amcheck.c:1158 +#, c-format +msgid " -i, --index=PATTERN check matching index(es)\n" +msgstr " -i, —index=PATTERN έλεγξε ταιριαστό(-ά) με το μοτίβο ευρετήριο(-ά)\n" + +#: pg_amcheck.c:1159 +#, c-format +msgid " -I, --exclude-index=PATTERN do NOT check matching index(es)\n" +msgstr " -I, —exclude-index=PATTERN να ΜΗΝ ελέγξει ταιριαστό(-ά) με το μοτίβο ευρετήριο(-ά)\n" + +#: pg_amcheck.c:1160 +#, c-format +msgid " -r, --relation=PATTERN check matching relation(s)\n" +msgstr " -i, —index=PATTERN έλεγξε ταιριαστή(-ές) με το μοτίβο σχέση(-εις)\n" + +#: pg_amcheck.c:1161 +#, c-format +msgid " -R, --exclude-relation=PATTERN do NOT check matching relation(s)\n" +msgstr " -R, —exclude-relation=PATTERN να ΜΗΝ ελέγξει ταιριαστή(-ές) με το μοτίβο σχέση(-εις)\n" + +#: pg_amcheck.c:1162 +#, c-format +msgid " -s, --schema=PATTERN check matching schema(s)\n" +msgstr " -s, --schema=PATTERN έλεγξε ταιριαστό(-ά) με το μοτίβο σχήμα(-τα)\n" + +#: pg_amcheck.c:1163 +#, c-format +msgid " -S, --exclude-schema=PATTERN do NOT check matching schema(s)\n" +msgstr " -S, —exclude-schema=PATTERN να ΜΗΝ ελέγξει ταιριαστό(-ά) με το μοτίβο σχήμα(-τα)\n" + +#: pg_amcheck.c:1164 +#, c-format +msgid " -t, --table=PATTERN check matching table(s)\n" +msgstr " -t, —table=PATTERN έλεγξε ταιριαστό(-ούς) με το μοτίβο πίνακα(-ες)\n" + +#: pg_amcheck.c:1165 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT check matching table(s)\n" +msgstr " -T, —exclude-table=PATTERN να ΜΗΝ ελέγξει ταιριαστό(-ούς) με το μοτίβο πίνακα(-ες)\n" + +#: pg_amcheck.c:1166 +#, c-format +msgid " --no-dependent-indexes do NOT expand list of relations to include indexes\n" +msgstr " —no-dependent-indexes να ΜΗΝ επεκτείνεις τη λίστα σχέσεων ώστε να συμπεριλάβει ευρετήρια\n" + +#: pg_amcheck.c:1167 +#, c-format +msgid " --no-dependent-toast do NOT expand list of relations to include TOAST tables\n" +msgstr "" +" —no-dependent-toast να ΜΗΝ επεκτείνεις τη λίστα σχέσεων ώστε να συμπεριλάβει πίνακες TOAST\n" +"\n" + +#: pg_amcheck.c:1168 +#, c-format +msgid " --no-strict-names do NOT require patterns to match objects\n" +msgstr " —no-strict-names να ΜΗΝ απαιτήσει μοτίβα για την αντιστοίχιση αντικειμένων\n" + +#: pg_amcheck.c:1169 +#, c-format +msgid "" +"\n" +"Table checking options:\n" +msgstr "" +"\n" +"Επιλογές ελέγχου πίνακα:\n" + +#: pg_amcheck.c:1170 +#, c-format +msgid " --exclude-toast-pointers do NOT follow relation TOAST pointers\n" +msgstr " —exclude-toast-pointers να ΜΗΝ ακολουθήσει τους δείκτες σχέσεων TOAST\n" + +#: pg_amcheck.c:1171 +#, c-format +msgid " --on-error-stop stop checking at end of first corrupt page\n" +msgstr " —on-error-stop διακοπή ελέγχου στο τέλος της πρώτης αλλοιωμένης σελίδας\n" + +#: pg_amcheck.c:1172 +#, c-format +msgid " --skip=OPTION do NOT check \"all-frozen\" or \"all-visible\" blocks\n" +msgstr " —skip=OPTION να ΜΗΝ ελέγξει τα “all-frozen” ή “all-visible” μπλοκ\n" + +#: pg_amcheck.c:1173 +#, c-format +msgid " --startblock=BLOCK begin checking table(s) at the given block number\n" +msgstr " —startblock=BLOCK εκκίνηση του ελέγχου πίνακα(-ων) από τον δοσμένο αριθμό μπλοκ\n" + +#: pg_amcheck.c:1174 +#, c-format +msgid " --endblock=BLOCK check table(s) only up to the given block number\n" +msgstr "" +" —endblock=BLOCK τερματισμός του ελέγχου πίνακα(-ων) από τον δοσμένο αριθμό μπλοκ\n" +"\n" + +#: pg_amcheck.c:1175 +#, c-format +msgid "" +"\n" +"B-tree index checking options:\n" +msgstr "" +"\n" +"Επιλογές ελέγχου ευρετηρίου B-tree:\n" + +#: pg_amcheck.c:1176 +#, c-format +msgid " --heapallindexed check all heap tuples are found within indexes\n" +msgstr " —heapallindexed έλεγξε όλες τις πλειάδες πλείαδες που βρίσκονται στο εύρος ευρετηρίων\n" + +#: pg_amcheck.c:1177 +#, c-format +msgid " --parent-check check index parent/child relationships\n" +msgstr " —parent-check έλεγξε σχέσεις γονέα/απογόνου ευρετηρίου\n" + +#: pg_amcheck.c:1178 +#, c-format +msgid " --rootdescend search from root page to refind tuples\n" +msgstr " —rootdescend αναζήτησε από τη ριζική σελίδα για την επανεύρεση πλειάδων\n" + +#: pg_amcheck.c:1179 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Επιλογές σύνδεσης:\n" + +#: pg_amcheck.c:1180 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, —host=HOSTNAME διακομιστής βάσης δεδομένων ή κατάλογος υποδοχών\n" + +#: pg_amcheck.c:1181 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, —port=PORT θύρα διακομιστή βάσης δεδομένων\n" + +#: pg_amcheck.c:1182 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, —username=USERNAME όνομα χρήστη με το οποίο να συνδεθεί\n" + +#: pg_amcheck.c:1183 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, —no-password να μην ζητείται ποτέ κωδικός πρόσβασης\n" + +#: pg_amcheck.c:1184 +#, c-format +msgid " -W, --password force password prompt\n" +msgstr " -W, —password αναγκαστική προτροπή κωδικού πρόσβασης\n" + +#: pg_amcheck.c:1185 +#, c-format +msgid " --maintenance-db=DBNAME alternate maintenance database\n" +msgstr " —maintenance-db=DBNAME εναλλακτική βάση δεδομένων συντήρησης\n" + +#: pg_amcheck.c:1186 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Άλλες επιλογές:\n" + +#: pg_amcheck.c:1187 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr " -e, —echo εμφάνισε τις εντολές που αποστέλλονται στο διακομιστή\n" + +#: pg_amcheck.c:1188 +#, c-format +msgid " -j, --jobs=NUM use this many concurrent connections to the server\n" +msgstr " -j, —jobs=NUM χρησιμοποιήσε τόσες πολλές ταυτόχρονες συνδέσεις με το διακομιστή\n" + +#: pg_amcheck.c:1189 +#, c-format +msgid " -q, --quiet don't write any messages\n" +msgstr " -q, —quiet να μην γράψεις κανένα μήνυμα\n" + +#: pg_amcheck.c:1190 +#, c-format +msgid " -v, --verbose write a lot of output\n" +msgstr " -v, —verbose γράψε πολλά μηνύματα εξόδου\n" + +#: pg_amcheck.c:1191 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr ", —version εμφάνισε πληροφορίες έκδοσης, στη συνέχεια έξοδος\n" + +#: pg_amcheck.c:1192 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, —progress εμφάνισε πληροφορίες προόδου\n" + +#: pg_amcheck.c:1193 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, στη συνέχεια έξοδος\n" + +#: pg_amcheck.c:1194 +#, c-format +msgid " --install-missing install missing extensions\n" +msgstr " —install-missing εγκατάστησε επεκτάσεις που λείπουν\n" + +#: pg_amcheck.c:1196 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_amcheck.c:1197 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_amcheck.c:1255 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%) %*s" +msgstr "%*s/%s σχέσεις (%d%%) σελίδες %*s/%s (%d%%) %*s" + +#: pg_amcheck.c:1266 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%), (%s%-*.*s)" +msgstr "%*s/%s σχέσεις (%d%%) σελίδες %*s/%s (%d%%), (%s%-*.*s)" + +#: pg_amcheck.c:1281 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%)" +msgstr "%*s/%s σχέσεις (%d%%) σελίδες %*s/%s (%d%%)" + +#: pg_amcheck.c:1550 pg_amcheck.c:1692 +#, c-format +msgid "including database \"%s\"" +msgstr "συμπεριλαμβανομένης της βάσης δεδομένων \"%s\"" + +#: pg_amcheck.c:1672 +#, c-format +msgid "internal error: received unexpected database pattern_id %d" +msgstr "Εσωτερικό σφάλμα: ελήφθη μη αναμενόμενο pattern_id βάσης δεδομένων %d" + +#: pg_amcheck.c:2126 +#, c-format +msgid "internal error: received unexpected relation pattern_id %d" +msgstr "εσωτερικό σφάλμα: ελήφθη μη αναμενόμενο pattern_id σχέσης %d" diff --git a/src/bin/pg_amcheck/po/es.po b/src/bin/pg_amcheck/po/es.po new file mode 100644 index 000000000000..2118cc12bf8b --- /dev/null +++ b/src/bin/pg_amcheck/po/es.po @@ -0,0 +1,463 @@ +# Spanish translation file for pg_amcheck +# +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_amcheck (PostgreSQL) package. +# +# Carlos Chapi , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_amcheck (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:48+0000\n" +"PO-Revision-Date: 2021-05-19 18:24-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Petición de cancelación enviada\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "No se pudo enviar la petición de cancelación: " + +#: ../../fe_utils/connect_utils.c:92 +#, c-format +msgid "could not connect to database %s: out of memory" +msgstr "no se pudo conectar a la base de datos %s: memoria agotada" + +#: ../../fe_utils/connect_utils.c:120 +#, c-format +msgid "%s" +msgstr "%s" + +#: ../../fe_utils/query_utils.c:33 ../../fe_utils/query_utils.c:58 +#: pg_amcheck.c:1645 pg_amcheck.c:2084 +#, c-format +msgid "query failed: %s" +msgstr "la consulta falló: %s" + +#: ../../fe_utils/query_utils.c:34 ../../fe_utils/query_utils.c:59 +#: pg_amcheck.c:597 pg_amcheck.c:1116 pg_amcheck.c:1646 pg_amcheck.c:2085 +#, c-format +msgid "query was: %s" +msgstr "la consulta era: %s" + +#: pg_amcheck.c:332 +#, c-format +msgid "number of parallel jobs must be at least 1" +msgstr "número de trabajos en paralelo debe ser al menos 1" + +#: pg_amcheck.c:405 +#, c-format +msgid "invalid argument for option %s" +msgstr "argumento no válido para la opción %s" + +#: pg_amcheck.c:413 +#, c-format +msgid "invalid start block" +msgstr "bloque de inicio no válido" + +#: pg_amcheck.c:418 +#, c-format +msgid "start block out of bounds" +msgstr "bloque de inicio fuera de rango" + +#: pg_amcheck.c:426 +#, c-format +msgid "invalid end block" +msgstr "bloque final no válido" + +#: pg_amcheck.c:431 +#, c-format +msgid "end block out of bounds" +msgstr "bloque final fuera de rango" + +#: pg_amcheck.c:455 pg_amcheck.c:481 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_amcheck.c:463 +#, c-format +msgid "end block precedes start block" +msgstr "bloque final precede al bloque de inicio" + +#: pg_amcheck.c:479 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_amcheck.c:500 +#, c-format +msgid "cannot specify a database name with --all" +msgstr "no se puede especificar un nombre de base de datos al usar --all" + +#: pg_amcheck.c:509 +#, c-format +msgid "cannot specify both a database name and database patterns" +msgstr "no se puede especificar al mismo tiempo un nombre de base de datos junto con patrones de bases de datos" + +#: pg_amcheck.c:539 +#, c-format +msgid "no databases to check" +msgstr "no hay bases de datos para revisar" + +#: pg_amcheck.c:595 +#, c-format +msgid "database \"%s\": %s" +msgstr "base de datos «%s»: %s" + +#: pg_amcheck.c:606 +#, c-format +msgid "skipping database \"%s\": amcheck is not installed" +msgstr "omitiendo la base de datos «%s»: amcheck no está instalado" + +#: pg_amcheck.c:614 +#, c-format +msgid "in database \"%s\": using amcheck version \"%s\" in schema \"%s\"" +msgstr "en base de datos «%s»: usando amcheck versión «%s» en esquema «%s»" + +#: pg_amcheck.c:676 +#, c-format +msgid "no relations to check" +msgstr "no hay relaciones para revisar" + +#: pg_amcheck.c:762 +#, c-format +msgid "checking heap table \"%s\".\"%s\".\"%s\"" +msgstr "revisando tabla heap «%s».«%s».«%s»" + +#: pg_amcheck.c:778 +#, c-format +msgid "checking btree index \"%s\".\"%s\".\"%s\"" +msgstr "revisando índice btree «%s».«%s».«%s»" + +#: pg_amcheck.c:911 +#, c-format +msgid "error sending command to database \"%s\": %s" +msgstr "error al enviar orden a la base de datos «%s»: %s" + +#: pg_amcheck.c:914 +#, c-format +msgid "command was: %s" +msgstr "la orden era: %s" + +#: pg_amcheck.c:1113 +#, c-format +msgid "btree index \"%s\".\"%s\".\"%s\": btree checking function returned unexpected number of rows: %d" +msgstr "índice btree «%s».«%s».«%s»: la función de comprobación de btree devolvió un número inesperado de registros: %d" + +#: pg_amcheck.c:1117 +#, c-format +msgid "Are %s's and amcheck's versions compatible?" +msgstr "¿Son compatibles la versión de %s con la de amcheck?" + +#: pg_amcheck.c:1151 +#, c-format +msgid "" +"%s checks objects in a PostgreSQL database for corruption.\n" +"\n" +msgstr "" +"%s busca corrupción en objetos de una base de datos PostgreSQL.\n" +"\n" + +#: pg_amcheck.c:1152 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_amcheck.c:1153 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPCIÓN]... [BASE-DE-DATOS]\n" + +#: pg_amcheck.c:1154 +#, c-format +msgid "" +"\n" +"Target options:\n" +msgstr "" +"\n" +"Opciones de objetivo:\n" + +#: pg_amcheck.c:1155 +#, c-format +msgid " -a, --all check all databases\n" +msgstr " -a, --all revisar todas las bases de datos\n" + +#: pg_amcheck.c:1156 +#, c-format +msgid " -d, --database=PATTERN check matching database(s)\n" +msgstr " -d, --database=PATRÓN revisar la(s) base(s) de datos que coincida(n)\n" + +#: pg_amcheck.c:1157 +#, c-format +msgid " -D, --exclude-database=PATTERN do NOT check matching database(s)\n" +msgstr " -D, --exclude-database=PATRÓN NO revisar la(s) base(s) de datos que coincida(n)\n" + +#: pg_amcheck.c:1158 +#, c-format +msgid " -i, --index=PATTERN check matching index(es)\n" +msgstr " -i, --index=PATRÓN revisar el(los) índice(s) que coincida(n)\n" + +#: pg_amcheck.c:1159 +#, c-format +msgid " -I, --exclude-index=PATTERN do NOT check matching index(es)\n" +msgstr " -I, --exclude-index=PATRÓN NO revisar el(los) índice(s) que coincida(n)\n" + +#: pg_amcheck.c:1160 +#, c-format +msgid " -r, --relation=PATTERN check matching relation(s)\n" +msgstr " -r, --relation=PATRÓN revisar la(s) relación(es) que coincida(n)\n" + +#: pg_amcheck.c:1161 +#, c-format +msgid " -R, --exclude-relation=PATTERN do NOT check matching relation(s)\n" +msgstr " -R, --exclude-relation=PATRÓN NO revisar la(s) relación(es) que coincida(n)\n" + +#: pg_amcheck.c:1162 +#, c-format +msgid " -s, --schema=PATTERN check matching schema(s)\n" +msgstr " -s, --schema=PATRÓN revisar el(los) esquema(s) que coincida(n)\n" + +#: pg_amcheck.c:1163 +#, c-format +msgid " -S, --exclude-schema=PATTERN do NOT check matching schema(s)\n" +msgstr " -S, --exclude-schema=PATRÓN NO revisar el(los) esquema(s) que coincida(n)\n" + +#: pg_amcheck.c:1164 +#, c-format +msgid " -t, --table=PATTERN check matching table(s)\n" +msgstr " -t, --table=PATRÓN revisar la(s) tabla(s) que coincida(n)\n" + +#: pg_amcheck.c:1165 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT check matching table(s)\n" +msgstr " -T, --exclude-table=PATRÓN NO revisar la(s) tabla(s) que coincida(n)\n" + +#: pg_amcheck.c:1166 +#, c-format +msgid " --no-dependent-indexes do NOT expand list of relations to include indexes\n" +msgstr " --no-dependent-indexes NO expandir la lista de relaciones para incluir índices\n" + +#: pg_amcheck.c:1167 +#, c-format +msgid " --no-dependent-toast do NOT expand list of relations to include TOAST tables\n" +msgstr " --no-dependent-toast NO expandir lista de relaciones para incluir tablas TOAST\n" + +#: pg_amcheck.c:1168 +#, c-format +msgid " --no-strict-names do NOT require patterns to match objects\n" +msgstr " --no-strict-names NO requerir que los patrones coincidan con los objetos\n" + +#: pg_amcheck.c:1169 +#, c-format +msgid "" +"\n" +"Table checking options:\n" +msgstr "" +"\n" +"Opciones para revisión de tabla:\n" + +#: pg_amcheck.c:1170 +#, c-format +msgid " --exclude-toast-pointers do NOT follow relation TOAST pointers\n" +msgstr " --exclude-toast-pointers NO seguir punteros TOAST de la relación\n" + +#: pg_amcheck.c:1171 +#, c-format +msgid " --on-error-stop stop checking at end of first corrupt page\n" +msgstr " --on-error-stop detener la revisión al final de la primera página corrupta\n" + +#: pg_amcheck.c:1172 +#, c-format +msgid " --skip=OPTION do NOT check \"all-frozen\" or \"all-visible\" blocks\n" +msgstr " --skip=OPTION NO revisar bloques «all-frozen» u «all-visible»\n" + +#: pg_amcheck.c:1173 +#, c-format +msgid " --startblock=BLOCK begin checking table(s) at the given block number\n" +msgstr " --startblock=BLOQUE empezar la revisión de la(s) tabla(s) en el número de bloque especificado\n" + +#: pg_amcheck.c:1174 +#, c-format +msgid " --endblock=BLOCK check table(s) only up to the given block number\n" +msgstr " --endblock=BLOQUE solo revisar la(s) tabla(s) hasta el número de bloque especificado\n" + +#: pg_amcheck.c:1175 +#, c-format +msgid "" +"\n" +"B-tree index checking options:\n" +msgstr "" +"\n" +"Opciones para revisión de índices B-tree:\n" + +#: pg_amcheck.c:1176 +#, c-format +msgid " --heapallindexed check all heap tuples are found within indexes\n" +msgstr " --heapallindexed revisar que todas las tuplas heap se encuentren en los índices\n" + +#: pg_amcheck.c:1177 +#, c-format +msgid " --parent-check check index parent/child relationships\n" +msgstr " --parent-check revisar relaciones padre/hijo de índice\n" + +#: pg_amcheck.c:1178 +#, c-format +msgid " --rootdescend search from root page to refind tuples\n" +msgstr " --rootdescend buscar desde la página raíz para volver a encontrar tuplas\n" + +#: pg_amcheck.c:1179 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Opciones de conexión:\n" + +#: pg_amcheck.c:1180 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=ANFITRIÓN nombre del servidor o directorio del socket\n" + +#: pg_amcheck.c:1181 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, --port=PUERTO puerto del servidor de base de datos\n" + +#: pg_amcheck.c:1182 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, --username=USUARIO nombre de usuario para la conexión\n" + +#: pg_amcheck.c:1183 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password nunca pedir contraseña\n" + +#: pg_amcheck.c:1184 +#, c-format +msgid " -W, --password force password prompt\n" +msgstr " -W, --password forzar la petición de contraseña\n" + +#: pg_amcheck.c:1185 +#, c-format +msgid " --maintenance-db=DBNAME alternate maintenance database\n" +msgstr " --maintenance-db=BASE base de datos de mantención alternativa\n" + +#: pg_amcheck.c:1186 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Otras opciones:\n" + +#: pg_amcheck.c:1187 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr " -e, --echo mostrar las órdenes enviadas al servidor\n" + +#: pg_amcheck.c:1188 +#, c-format +msgid " -j, --jobs=NUM use this many concurrent connections to the server\n" +msgstr " -j, --jobs=NUM usar esta cantidad de conexiones concurrentes hacia el servidor\n" + +#: pg_amcheck.c:1189 +#, c-format +msgid " -q, --quiet don't write any messages\n" +msgstr " -q, --quiet no desplegar mensajes\n" + +#: pg_amcheck.c:1190 +#, c-format +msgid " -v, --verbose write a lot of output\n" +msgstr " -v, --verbose desplegar varios mensajes informativos\n" + +#: pg_amcheck.c:1191 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: pg_amcheck.c:1192 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress mostrar información de progreso\n" + +#: pg_amcheck.c:1193 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: pg_amcheck.c:1194 +#, c-format +msgid " --install-missing install missing extensions\n" +msgstr " --install-missing instalar extensiones faltantes\n" + +#: pg_amcheck.c:1196 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_amcheck.c:1197 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_amcheck.c:1255 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%) %*s" +msgstr "%*s/%s relaciones (%d%%) %*s/%s páginas (%d%%) %*s" + +#: pg_amcheck.c:1266 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%), (%s%-*.*s)" +msgstr "%*s/%s relaciones (%d%%) %*s/%s páginas (%d%%), (%s%-*.*s)" + +#: pg_amcheck.c:1281 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%)" +msgstr "%*s/%s relaciones (%d%%) %*s/%s páginas (%d%%)" + +#: pg_amcheck.c:1550 pg_amcheck.c:1692 +#, c-format +msgid "including database \"%s\"" +msgstr "incluyendo base de datos «%s»" + +#: pg_amcheck.c:1672 +#, c-format +msgid "internal error: received unexpected database pattern_id %d" +msgstr "error interno: se recibió pattern_id de base de datos inesperado (%d)" + +#: pg_amcheck.c:2126 +#, c-format +msgid "internal error: received unexpected relation pattern_id %d" +msgstr "error interno: se recibió pattern_id de relación inesperado (%d)" diff --git a/src/bin/pg_amcheck/po/fr.po b/src/bin/pg_amcheck/po/fr.po new file mode 100644 index 000000000000..f359e35aa02e --- /dev/null +++ b/src/bin/pg_amcheck/po/fr.po @@ -0,0 +1,489 @@ +# LANGUAGE message translation file for pg_amcheck +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_amcheck (PostgreSQL) package. +# FIRST AUTHOR , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_amcheck (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-14 06:18+0000\n" +"PO-Revision-Date: 2021-06-14 16:56+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Requête d'annulation envoyée\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "N'a pas pu envoyer la requête d'annulation : " + +#: ../../fe_utils/connect_utils.c:92 +#, c-format +msgid "could not connect to database %s: out of memory" +msgstr "n'a pas pu se connecter à la base de données %s : plus de mémoire" + +#: ../../fe_utils/connect_utils.c:120 +#, c-format +msgid "%s" +msgstr "%s" + +#: ../../fe_utils/query_utils.c:33 ../../fe_utils/query_utils.c:58 +#: pg_amcheck.c:1645 pg_amcheck.c:2084 +#, c-format +msgid "query failed: %s" +msgstr "échec de la requête : %s" + +#: ../../fe_utils/query_utils.c:34 ../../fe_utils/query_utils.c:59 +#: pg_amcheck.c:597 pg_amcheck.c:1116 pg_amcheck.c:1646 pg_amcheck.c:2085 +#, c-format +msgid "query was: %s" +msgstr "la requête était : %s" + +#: pg_amcheck.c:332 +#, c-format +msgid "number of parallel jobs must be at least 1" +msgstr "le nombre maximum de jobs en parallèle doit être au moins de 1" + +#: pg_amcheck.c:405 +#, c-format +msgid "invalid argument for option %s" +msgstr "argument invalide pour l'option %s" + +#: pg_amcheck.c:413 +#, c-format +msgid "invalid start block" +msgstr "bloc de début invalide" + +#: pg_amcheck.c:418 +#, c-format +msgid "start block out of bounds" +msgstr "bloc de début hors des limites" + +#: pg_amcheck.c:426 +#, c-format +msgid "invalid end block" +msgstr "bloc de fin invalide" + +#: pg_amcheck.c:431 +#, c-format +msgid "end block out of bounds" +msgstr "bloc de fin hors des limites" + +#: pg_amcheck.c:455 pg_amcheck.c:481 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: pg_amcheck.c:463 +#, c-format +msgid "end block precedes start block" +msgstr "le bloc de fin précède le bloc de début" + +#: pg_amcheck.c:479 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" + +#: pg_amcheck.c:500 +#, c-format +msgid "cannot specify a database name with --all" +msgstr "ne peut pas spécifier un nom de base de données avec --all" + +#: pg_amcheck.c:509 +#, c-format +msgid "cannot specify both a database name and database patterns" +msgstr "ne peut pas spécifier à la fois le nom d'une base de données et des motifs de noms de base" + +#: pg_amcheck.c:539 +#, c-format +msgid "no databases to check" +msgstr "aucune base de données à vérifier" + +#: pg_amcheck.c:595 +#, c-format +msgid "database \"%s\": %s" +msgstr "base de données « %s » : %s" + +#: pg_amcheck.c:606 +#, c-format +msgid "skipping database \"%s\": amcheck is not installed" +msgstr "ignore la base « %s » : amcheck n'est pas installé" + +#: pg_amcheck.c:614 +#, c-format +msgid "in database \"%s\": using amcheck version \"%s\" in schema \"%s\"" +msgstr "dans la base de données « %s » : utilisation de la version « %s » d'amcheck dans le schéma « %s »" + +#: pg_amcheck.c:676 +#, c-format +msgid "no relations to check" +msgstr "aucune relation à vérifier" + +#: pg_amcheck.c:762 +#, c-format +msgid "checking heap table \"%s\".\"%s\".\"%s\"" +msgstr "vérification de la table heap « %s %s\".\"%s\"" + +#: pg_amcheck.c:778 +#, c-format +msgid "checking btree index \"%s\".\"%s\".\"%s\"" +msgstr "vérification de l'index btree \"%s\".\"%s\".\"%s\"" + +#: pg_amcheck.c:911 +#, c-format +msgid "error sending command to database \"%s\": %s" +msgstr "erreur de l'envoi d'une commande à la base de données « %s » : %s" + +#: pg_amcheck.c:914 +#, c-format +msgid "command was: %s" +msgstr "la commande était : %s" + +#: pg_amcheck.c:1113 +#, c-format +msgid "btree index \"%s\".\"%s\".\"%s\": btree checking function returned unexpected number of rows: %d" +msgstr "index btree \"%s\".\"%s\".\"%s\" : la fonction de vérification de btree a renvoyé un nombre de lignes inattendu : %d" + +#: pg_amcheck.c:1117 +#, c-format +msgid "Are %s's and amcheck's versions compatible?" +msgstr "est-ce que les versions de %s et d'amcheck sont compatibles ?" + +#: pg_amcheck.c:1151 +#, c-format +msgid "" +"%s checks objects in a PostgreSQL database for corruption.\n" +"\n" +msgstr "" +"%s utilise le module amcheck pour vérifier les objets dans une base PostgreSQL pour corruption.\n" +"\n" + +#: pg_amcheck.c:1152 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: pg_amcheck.c:1153 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]... [NOMBASE]\n" + +#: pg_amcheck.c:1154 +#, c-format +msgid "" +"\n" +"Target options:\n" +msgstr "" +"\n" +"Options de la cible :\n" + +#: pg_amcheck.c:1155 +#, c-format +msgid " -a, --all check all databases\n" +msgstr " -a, --all vérifie toutes les bases\n" + +#: pg_amcheck.c:1156 +#, c-format +msgid " -d, --database=PATTERN check matching database(s)\n" +msgstr " -d, --database=MOTIF vérifie les bases correspondantes\n" + +#: pg_amcheck.c:1157 +#, c-format +msgid " -D, --exclude-database=PATTERN do NOT check matching database(s)\n" +msgstr " -D, --exclude-database=MOTIF ne vérifie PAS les bases correspondantes\n" + +#: pg_amcheck.c:1158 +#, c-format +msgid " -i, --index=PATTERN check matching index(es)\n" +msgstr " -i, --index=MOTIF vérifie les index correspondants\n" + +#: pg_amcheck.c:1159 +#, c-format +msgid " -I, --exclude-index=PATTERN do NOT check matching index(es)\n" +msgstr " -I, --exclude-index=MOTIF ne vérifie PAS les index correspondants\n" + +#: pg_amcheck.c:1160 +#, c-format +msgid " -r, --relation=PATTERN check matching relation(s)\n" +msgstr " -r, --relation=MOTIF vérifie les relations correspondantes\n" + +#: pg_amcheck.c:1161 +#, c-format +msgid " -R, --exclude-relation=PATTERN do NOT check matching relation(s)\n" +msgstr " -R, --exclude-relation=MOTIF ne vérifie PAS les relations correspondantes\n" + +#: pg_amcheck.c:1162 +#, c-format +msgid " -s, --schema=PATTERN check matching schema(s)\n" +msgstr " -s, --schema=MOTIF vérifie les schémas correspondants\n" + +#: pg_amcheck.c:1163 +#, c-format +msgid " -S, --exclude-schema=PATTERN do NOT check matching schema(s)\n" +msgstr " -S, --exclude-schema=MOTIF ne vérifie PAS les schémas correspondants\n" + +#: pg_amcheck.c:1164 +#, c-format +msgid " -t, --table=PATTERN check matching table(s)\n" +msgstr " -t, --table=MOTIF vérifie les tables correspondantes\n" + +#: pg_amcheck.c:1165 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT check matching table(s)\n" +msgstr " -T, --exclude-table=MOTIF ne vérifie PAS les tables correspondantes\n" + +#: pg_amcheck.c:1166 +#, c-format +msgid " --no-dependent-indexes do NOT expand list of relations to include indexes\n" +msgstr " --no-dependent-indexes n'étend PAS la liste des relations pour inclure les index\n" + +#: pg_amcheck.c:1167 +#, c-format +msgid " --no-dependent-toast do NOT expand list of relations to include TOAST tables\n" +msgstr " --no-dependent-toast n'étend PAS la liste des relations pour inclure les TOAST\n" + +#: pg_amcheck.c:1168 +#, c-format +msgid " --no-strict-names do NOT require patterns to match objects\n" +msgstr " --no-strict-names ne requiert PAS que les motifs correspondent à des objets\n" + +#: pg_amcheck.c:1169 +#, c-format +msgid "" +"\n" +"Table checking options:\n" +msgstr "" +"\n" +"Options de vérification des tables :\n" + +#: pg_amcheck.c:1170 +#, c-format +msgid " --exclude-toast-pointers do NOT follow relation TOAST pointers\n" +msgstr " --exclude-toast-pointers ne suit PAS les pointeurs de TOAST\n" + +#: pg_amcheck.c:1171 +#, c-format +msgid " --on-error-stop stop checking at end of first corrupt page\n" +msgstr " --on-error-stop arrête la vérification à la fin du premier bloc corrompu\n" + +#: pg_amcheck.c:1172 +#, c-format +msgid " --skip=OPTION do NOT check \"all-frozen\" or \"all-visible\" blocks\n" +msgstr " --skip=OPTION ne vérifie PAS les blocs « all-frozen » et « all-visible »\n" + +#: pg_amcheck.c:1173 +#, c-format +msgid " --startblock=BLOCK begin checking table(s) at the given block number\n" +msgstr " --startblock=BLOC commence la vérification des tables au numéro de bloc indiqué\n" + +#: pg_amcheck.c:1174 +#, c-format +msgid " --endblock=BLOCK check table(s) only up to the given block number\n" +msgstr " --endblock=BLOC vérifie les tables jusqu'au numéro de bloc indiqué\n" + +#: pg_amcheck.c:1175 +#, c-format +msgid "" +"\n" +"B-tree index checking options:\n" +msgstr "" +"\n" +"Options de vérification des index Btree :\n" + +#: pg_amcheck.c:1176 +#, c-format +msgid " --heapallindexed check all heap tuples are found within indexes\n" +msgstr " --heapallindexed vérifie que tous les enregistrements de la table sont référencés dans les index\n" + +#: pg_amcheck.c:1177 +#, c-format +msgid " --parent-check check index parent/child relationships\n" +msgstr " --parent-check vérifie les relations parent/enfants dans les index\n" + +#: pg_amcheck.c:1178 +#, c-format +msgid " --rootdescend search from root page to refind tuples\n" +msgstr " --rootdescend recherche à partir de la racine pour trouver les lignes\n" + +#: pg_amcheck.c:1179 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Options de connexion :\n" + +#: pg_amcheck.c:1180 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME IP/alias du serveur ou répertoire du socket\n" + +#: pg_amcheck.c:1181 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, --port=PORT port du serveur de bases de données\n" + +#: pg_amcheck.c:1182 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, --username=NOM_UTILSATEUR nom d'utilisateur pour la connexion\n" + +#: pg_amcheck.c:1183 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password ne demande jamais un mot de passe\n" + +#: pg_amcheck.c:1184 +#, c-format +msgid " -W, --password force password prompt\n" +msgstr " -W, --password force la saisie d'un mot de passe\n" + +#: pg_amcheck.c:1185 +#, c-format +msgid " --maintenance-db=DBNAME alternate maintenance database\n" +msgstr " --maintenance-db=NOM_BASE change la base de maintenance\n" + +#: pg_amcheck.c:1186 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Autres options :\n" + +#: pg_amcheck.c:1187 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr " -e, --echo affiche les commandes envoyées au serveur\n" + +#: pg_amcheck.c:1188 +#, c-format +msgid " -j, --jobs=NUM use this many concurrent connections to the server\n" +msgstr " -j, --jobs=NOMBRE utilise ce nombre de connexions simultanées au serveur\n" + +#: pg_amcheck.c:1189 +#, c-format +msgid " -q, --quiet don't write any messages\n" +msgstr " -q, --quiet n'écrit aucun message\n" + +#: pg_amcheck.c:1190 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress affiche la progression\n" + +#: pg_amcheck.c:1191 +#, c-format +msgid " -v, --verbose write a lot of output\n" +msgstr " -v, --verbose mode verbeux\n" + +#: pg_amcheck.c:1192 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" + +#: pg_amcheck.c:1193 +#, c-format +msgid " --install-missing install missing extensions\n" +msgstr " --install-missing installe les extensions manquantes\n" + +#: pg_amcheck.c:1194 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" + +#: pg_amcheck.c:1196 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapporter les bogues à <%s>.\n" + +#: pg_amcheck.c:1197 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil de %s : <%s>\n" + +#: pg_amcheck.c:1255 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%) %*s" +msgstr "relations %*s/%s (%d%%) pages %*s/%s (%d%%) %*s" + +#: pg_amcheck.c:1266 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%), (%s%-*.*s)" +msgstr "relations %*s/%s (%d%%) pages %*s/%s (%d%%), (%s%-*.*s)" + +#: pg_amcheck.c:1281 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%)" +msgstr "relations %*s/%s (%d%%) pages %*s/%s (%d%%)" + +#: pg_amcheck.c:1550 pg_amcheck.c:1692 +#, c-format +msgid "including database \"%s\"" +msgstr "en incluant la base de données : « %s »" + +#: pg_amcheck.c:1672 +#, c-format +msgid "internal error: received unexpected database pattern_id %d" +msgstr "erreur interne : a reçu un pattern_id %d inattendu de la base" + +#: pg_amcheck.c:2126 +#, c-format +msgid "internal error: received unexpected relation pattern_id %d" +msgstr "erreur interne : a reçu un pattern_id %d inattendu de la relation" + +#~ msgid "number of parallel jobs must be at least 1\n" +#~ msgstr "le nombre de jobs parallèles doit être au moins de 1\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help affiche cette aide, puis quitte\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version affiche la version, puis quitte\n" + +#~ msgid " -v, --verbose write a lot of output\n" +#~ msgstr " -v, --verbose mode verbeux\n" + +#~ msgid " -q, --quiet don't write any messages\n" +#~ msgstr " -q, --quiet n'écrit aucun message\n" + +#~ msgid " -e, --echo show the commands being sent to the server\n" +#~ msgstr " -e, --echo affiche les commandes envoyées au serveur\n" + +#~ msgid "" +#~ "\n" +#~ "Other Options:\n" +#~ msgstr "" +#~ "\n" +#~ "Autres options:\n" + +#~ msgid "invalid skip option" +#~ msgstr "option skip invalide" diff --git a/src/bin/pg_amcheck/po/zh_CN.po b/src/bin/pg_amcheck/po/zh_CN.po new file mode 100644 index 000000000000..8e1cff9f7b75 --- /dev/null +++ b/src/bin/pg_amcheck/po/zh_CN.po @@ -0,0 +1,460 @@ +# LANGUAGE message translation file for pg_amcheck +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_amcheck (PostgreSQL) package. +# Jie Zhang , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_amcheck (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-08 23:18+0000\n" +"PO-Revision-Date: 2021-06-09 18:00+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "致命的:" + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "错误: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "取消发送的请求\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "无法发送取消请求: " + +#: ../../fe_utils/connect_utils.c:92 +#, c-format +msgid "could not connect to database %s: out of memory" +msgstr "无法连接到数据库 %s:内存不足" + +#: ../../fe_utils/connect_utils.c:120 +#, c-format +msgid "%s" +msgstr "%s" + +#: ../../fe_utils/query_utils.c:33 ../../fe_utils/query_utils.c:58 +#: pg_amcheck.c:1645 pg_amcheck.c:2084 +#, c-format +msgid "query failed: %s" +msgstr "查询失败: %s" + +#: ../../fe_utils/query_utils.c:34 ../../fe_utils/query_utils.c:59 +#: pg_amcheck.c:597 pg_amcheck.c:1116 pg_amcheck.c:1646 pg_amcheck.c:2085 +#, c-format +msgid "query was: %s" +msgstr "查询是: %s" + +#: pg_amcheck.c:332 +#, c-format +msgid "number of parallel jobs must be at least 1" +msgstr "并行工作的数量必须至少为1" + +#: pg_amcheck.c:405 +#, c-format +msgid "invalid argument for option %s" +msgstr "选项%s的参数无效" + +#: pg_amcheck.c:413 +#, c-format +msgid "invalid start block" +msgstr "起始块无效" + +#: pg_amcheck.c:418 +#, c-format +msgid "start block out of bounds" +msgstr "起始块超出范围" + +#: pg_amcheck.c:426 +#, c-format +msgid "invalid end block" +msgstr "无效的结束块" + +#: pg_amcheck.c:431 +#, c-format +msgid "end block out of bounds" +msgstr "结束块超出范围" + +#: pg_amcheck.c:455 pg_amcheck.c:481 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "请用 \"%s --help\" 获取更多的信息.\n" + +#: pg_amcheck.c:463 +#, c-format +msgid "end block precedes start block" +msgstr "结束块在开始块之前" + +#: pg_amcheck.c:479 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "命令行参数太多 (第一个是 \"%s\")" + +#: pg_amcheck.c:500 +#, c-format +msgid "cannot specify a database name with --all" +msgstr "无法使用--all指定数据库名称" + +#: pg_amcheck.c:509 +#, c-format +msgid "cannot specify both a database name and database patterns" +msgstr "不能同时指定数据库名称和数据库模式" + +#: pg_amcheck.c:539 +#, c-format +msgid "no databases to check" +msgstr "没有要检查的数据库" + +#: pg_amcheck.c:595 +#, c-format +msgid "database \"%s\": %s" +msgstr "数据库 \"%s\": %s" + +#: pg_amcheck.c:606 +#, c-format +msgid "skipping database \"%s\": amcheck is not installed" +msgstr "正在跳过数据库\"%s\":未安装amcheck" + +#: pg_amcheck.c:614 +#, c-format +msgid "in database \"%s\": using amcheck version \"%s\" in schema \"%s\"" +msgstr "在数据库\"%1$s\"中:在模式\"%3$s\"中使用amcheck版本\"%2$s\"" + +#: pg_amcheck.c:676 +#, c-format +msgid "no relations to check" +msgstr "没有要检查的关系" + +#: pg_amcheck.c:762 +#, c-format +msgid "checking heap table \"%s\".\"%s\".\"%s\"" +msgstr "正在检查堆表\"%s\".\"%s\".\"%s\"" + +#: pg_amcheck.c:778 +#, c-format +msgid "checking btree index \"%s\".\"%s\".\"%s\"" +msgstr "检查btree索引\"%s\".\"%s\".\"%s\"" + +#: pg_amcheck.c:911 +#, c-format +msgid "error sending command to database \"%s\": %s" +msgstr "向数据库\"%s\"发送命令时出错: %s" + +#: pg_amcheck.c:914 +#, c-format +msgid "command was: %s" +msgstr "命令是: %s" + +#: pg_amcheck.c:1113 +#, c-format +msgid "btree index \"%s\".\"%s\".\"%s\": btree checking function returned unexpected number of rows: %d" +msgstr "B树索引\"%s\".\"%s\".\"%s\":B树检查函数返回了意外的行数: %d" + +#: pg_amcheck.c:1117 +#, c-format +msgid "Are %s's and amcheck's versions compatible?" +msgstr "%s和amcheck的版本兼容吗?" + +#: pg_amcheck.c:1151 +#, c-format +msgid "" +"%s checks objects in a PostgreSQL database for corruption.\n" +"\n" +msgstr "" +"%s检查PostgreSQL数据库中的对象是否损坏.\n" +"\n" + +#: pg_amcheck.c:1152 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_amcheck.c:1153 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [选项]... [数据库名字]\n" + +#: pg_amcheck.c:1154 +#, c-format +msgid "" +"\n" +"Target options:\n" +msgstr "" +"\n" +"目标选项:\n" + +#: pg_amcheck.c:1155 +#, c-format +msgid " -a, --all check all databases\n" +msgstr " -a, --all 检查所有数据库\n" + +#: pg_amcheck.c:1156 +#, c-format +msgid " -d, --database=PATTERN check matching database(s)\n" +msgstr " -d, --database=PATTERN 检查匹配的数据库\n" + +#: pg_amcheck.c:1157 +#, c-format +msgid " -D, --exclude-database=PATTERN do NOT check matching database(s)\n" +msgstr " -D, --exclude-database=PATTERN 不检查匹配的数据库\n" + +#: pg_amcheck.c:1158 +#, c-format +msgid " -i, --index=PATTERN check matching index(es)\n" +msgstr " -i, --index=PATTERN 检查匹配的索引\n" + +#: pg_amcheck.c:1159 +#, c-format +msgid " -I, --exclude-index=PATTERN do NOT check matching index(es)\n" +msgstr " -I, --exclude-index=PATTERN 不检查匹配的索引\n" + +#: pg_amcheck.c:1160 +#, c-format +msgid " -r, --relation=PATTERN check matching relation(s)\n" +msgstr " -r, --relation=PATTERN 检查匹配的关系\n" + +#: pg_amcheck.c:1161 +#, c-format +msgid " -R, --exclude-relation=PATTERN do NOT check matching relation(s)\n" +msgstr " -R, --exclude-relation=PATTERN 不检查匹配的关系\n" + +#: pg_amcheck.c:1162 +#, c-format +msgid " -s, --schema=PATTERN check matching schema(s)\n" +msgstr " -s, --schema=PATTERN 检查匹配的模式\n" + +#: pg_amcheck.c:1163 +#, c-format +msgid " -S, --exclude-schema=PATTERN do NOT check matching schema(s)\n" +msgstr " -S, --exclude-schema=PATTERN 不检查匹配模式\n" + +#: pg_amcheck.c:1164 +#, c-format +msgid " -t, --table=PATTERN check matching table(s)\n" +msgstr " -t, --table=PATTERN 检查匹配的表\n" + +#: pg_amcheck.c:1165 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT check matching table(s)\n" +msgstr " -T, --exclude-table=PATTERN 不检查匹的配表\n" + +#: pg_amcheck.c:1166 +#, c-format +msgid " --no-dependent-indexes do NOT expand list of relations to include indexes\n" +msgstr " --no-dependent-indexes 不要展开关系列表以包含索引\n" + +#: pg_amcheck.c:1167 +#, c-format +msgid " --no-dependent-toast do NOT expand list of relations to include TOAST tables\n" +msgstr " --no-dependent-toast 不要展开关系列表以包括TOAST表\n" + +#: pg_amcheck.c:1168 +#, c-format +msgid " --no-strict-names do NOT require patterns to match objects\n" +msgstr " --no-strict-names 不需要模式来匹配对象\n" + +#: pg_amcheck.c:1169 +#, c-format +msgid "" +"\n" +"Table checking options:\n" +msgstr "" +"\n" +"表检查选项:\n" + +#: pg_amcheck.c:1170 +#, c-format +msgid " --exclude-toast-pointers do NOT follow relation TOAST pointers\n" +msgstr " --exclude-toast-pointers 不要遵循关系TOAST指示\n" + +#: pg_amcheck.c:1171 +#, c-format +msgid " --on-error-stop stop checking at end of first corrupt page\n" +msgstr " --on-error-stop 在第一个损坏页的末尾停止检查\n" + +#: pg_amcheck.c:1172 +#, c-format +msgid " --skip=OPTION do NOT check \"all-frozen\" or \"all-visible\" blocks\n" +msgstr " --skip=OPTION 不要检查\"all-frozen\"或\"all-visible\"块\n" + +#: pg_amcheck.c:1173 +#, c-format +msgid " --startblock=BLOCK begin checking table(s) at the given block number\n" +msgstr " --startblock=BLOCK 在给定的块编号处开始检查表\n" + +#: pg_amcheck.c:1174 +#, c-format +msgid " --endblock=BLOCK check table(s) only up to the given block number\n" +msgstr " --endblock=BLOCK 检查表仅限于给定的块编号\n" + +#: pg_amcheck.c:1175 +#, c-format +msgid "" +"\n" +"B-tree index checking options:\n" +msgstr "" +"\n" +"B树索引检查选项:\n" + +#: pg_amcheck.c:1176 +#, c-format +msgid " --heapallindexed check all heap tuples are found within indexes\n" +msgstr " --heapallindexed 检查是否在索引中找到所有堆元组\n" + +#: pg_amcheck.c:1177 +#, c-format +msgid " --parent-check check index parent/child relationships\n" +msgstr " --parent-check 检查索引父/子关系\n" + +#: pg_amcheck.c:1178 +#, c-format +msgid " --rootdescend search from root page to refind tuples\n" +msgstr " --rootdescend 从根页搜索到重新填充元组\n" + +#: pg_amcheck.c:1179 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"联接选项:\n" + +#: pg_amcheck.c:1180 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME 数据库服务器主机或套接字目录\n" + +#: pg_amcheck.c:1181 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, --port=PORT 数据库服务器端口\n" + +#: pg_amcheck.c:1182 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, --username=USERNAME 要连接的用户名\n" + +#: pg_amcheck.c:1183 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password 从不提示输入密码\n" + +#: pg_amcheck.c:1184 +#, c-format +msgid " -W, --password force password prompt\n" +msgstr " -W, --password 强制密码提示\n" + +#: pg_amcheck.c:1185 +#, c-format +msgid " --maintenance-db=DBNAME alternate maintenance database\n" +msgstr " --maintenance-db=DBNAME 备用维护数据库\n" + +#: pg_amcheck.c:1186 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"其它选项:\n" + +#: pg_amcheck.c:1187 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr " -e, --echo 显示发送到服务端的命令\n" + +#: pg_amcheck.c:1188 +#, c-format +msgid " -j, --jobs=NUM use this many concurrent connections to the server\n" +msgstr " -j, --jobs=NUM 使用这么多到服务器的并发连接\n" + +#: pg_amcheck.c:1189 +#, c-format +msgid " -q, --quiet don't write any messages\n" +msgstr " -q, --quiet 不写任何信息\n" + +#: pg_amcheck.c:1190 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress 显示进度信息\n" + +#: pg_amcheck.c:1191 +#, c-format +msgid " -v, --verbose write a lot of output\n" +msgstr " -v, --verbose 写大量的输出\n" + +#: pg_amcheck.c:1192 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 输出版本信息, 然后退出\n" + +#: pg_amcheck.c:1193 +#, c-format +msgid " --install-missing install missing extensions\n" +msgstr " --install-missing 安装缺少的扩展\n" + +#: pg_amcheck.c:1194 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 显示此帮助信息, 然后退出\n" + +#: pg_amcheck.c:1196 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"臭虫报告至<%s>.\n" + +#: pg_amcheck.c:1197 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 主页: <%s>\n" + +#: pg_amcheck.c:1255 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%) %*s" +msgstr "%*s/%s 关系 (%d%%) %*s/%s 页 (%d%%) %*s" + +#: pg_amcheck.c:1266 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%), (%s%-*.*s)" +msgstr "%*s/%s 关系 (%d%%) %*s/%s 页 (%d%%), (%s%-*.*s)" + +#: pg_amcheck.c:1281 +#, c-format +msgid "%*s/%s relations (%d%%) %*s/%s pages (%d%%)" +msgstr "%*s/%s 关系 (%d%%) %*s/%s 页 (%d%%)" + +#: pg_amcheck.c:1550 pg_amcheck.c:1692 +#, c-format +msgid "including database \"%s\"" +msgstr "包含的数据库\"%s\"" + +#: pg_amcheck.c:1672 +#, c-format +msgid "internal error: received unexpected database pattern_id %d" +msgstr "内部错误:收到意外的数据库pattern_id %d" + +#: pg_amcheck.c:2126 +#, c-format +msgid "internal error: received unexpected relation pattern_id %d" +msgstr "内部错误:收到意外的关系pattern_id %d" diff --git a/src/bin/pg_amcheck/t/001_basic.pl b/src/bin/pg_amcheck/t/001_basic.pl new file mode 100644 index 000000000000..6f60e3ec1f50 --- /dev/null +++ b/src/bin/pg_amcheck/t/001_basic.pl @@ -0,0 +1,12 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use TestLib; +use Test::More tests => 8; + +program_help_ok('pg_amcheck'); +program_version_ok('pg_amcheck'); +program_options_handling_ok('pg_amcheck'); diff --git a/src/bin/pg_amcheck/t/002_nonesuch.pl b/src/bin/pg_amcheck/t/002_nonesuch.pl new file mode 100644 index 000000000000..5f712ee32acb --- /dev/null +++ b/src/bin/pg_amcheck/t/002_nonesuch.pl @@ -0,0 +1,266 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgresNode; +use TestLib; +use Test::More tests => 72; + +# Test set-up +my ($node, $port); +$node = get_new_node('test'); +$node->init; +$node->start; +$port = $node->port; + +# Load the amcheck extension, upon which pg_amcheck depends +$node->safe_psql('postgres', q(CREATE EXTENSION amcheck)); + +######################################### +# Test non-existent databases + +# Failing to connect to the initial database is an error. +$node->command_checks_all( + [ 'pg_amcheck', 'qqq' ], + 1, [qr/^$/], + [qr/FATAL: database "qqq" does not exist/], + 'checking a non-existent database'); + +# Failing to resolve a database pattern is an error by default. +$node->command_checks_all( + [ 'pg_amcheck', '-d', 'qqq', '-d', 'postgres' ], + 1, + [qr/^$/], + [qr/pg_amcheck: error: no connectable databases to check matching "qqq"/], + 'checking an unresolvable database pattern'); + +# But only a warning under --no-strict-names +$node->command_checks_all( + [ 'pg_amcheck', '--no-strict-names', '-d', 'qqq', '-d', 'postgres' ], + 0, + [qr/^$/], + [ + qr/pg_amcheck: warning: no connectable databases to check matching "qqq"/ + ], + 'checking an unresolvable database pattern under --no-strict-names'); + +# Check that a substring of an existent database name does not get interpreted +# as a matching pattern. +$node->command_checks_all( + [ 'pg_amcheck', '-d', 'post', '-d', 'postgres' ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: error: no connectable databases to check matching "post"/ + ], + 'checking an unresolvable database pattern (substring of existent database)' +); + +# Check that a superstring of an existent database name does not get interpreted +# as a matching pattern. +$node->command_checks_all( + [ 'pg_amcheck', '-d', 'postgresql', '-d', 'postgres' ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: error: no connectable databases to check matching "postgresql"/ + ], + 'checking an unresolvable database pattern (superstring of existent database)' +); + +######################################### +# Test connecting with a non-existent user + +# Failing to connect to the initial database due to bad username is an error. +$node->command_checks_all([ 'pg_amcheck', '-U', 'no_such_user', 'postgres' ], + 1, [qr/^$/], [], 'checking with a non-existent user'); + +######################################### +# Test checking databases without amcheck installed + +# Attempting to check a database by name where amcheck is not installed should +# raise a warning. If all databases are skipped, having no relations to check +# raises an error. +$node->command_checks_all( + [ 'pg_amcheck', 'template1' ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: warning: skipping database "template1": amcheck is not installed/, + qr/pg_amcheck: error: no relations to check/ + ], + 'checking a database by name without amcheck installed, no other databases' +); + +# Again, but this time with another database to check, so no error is raised. +$node->command_checks_all( + [ 'pg_amcheck', '-d', 'template1', '-d', 'postgres' ], + 0, + [qr/^$/], + [ + qr/pg_amcheck: warning: skipping database "template1": amcheck is not installed/ + ], + 'checking a database by name without amcheck installed, with other databases' +); + +# Again, but by way of checking all databases +$node->command_checks_all( + [ 'pg_amcheck', '--all' ], + 0, + [qr/^$/], + [ + qr/pg_amcheck: warning: skipping database "template1": amcheck is not installed/ + ], + 'checking a database by pattern without amcheck installed, with other databases' +); + +######################################### +# Test unreasonable patterns + +# Check three-part unreasonable pattern that has zero-length names +$node->command_checks_all( + [ 'pg_amcheck', '-d', 'postgres', '-t', '..' ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: error: no connectable databases to check matching "\.\."/ + ], + 'checking table pattern ".."'); + +# Again, but with non-trivial schema and relation parts +$node->command_checks_all( + [ 'pg_amcheck', '-d', 'postgres', '-t', '.foo.bar' ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: error: no connectable databases to check matching "\.foo\.bar"/ + ], + 'checking table pattern ".foo.bar"'); + +# Check two-part unreasonable pattern that has zero-length names +$node->command_checks_all( + [ 'pg_amcheck', '-d', 'postgres', '-t', '.' ], + 1, + [qr/^$/], + [qr/pg_amcheck: error: no heap tables to check matching "\."/], + 'checking table pattern "."'); + +######################################### +# Test checking non-existent databases, schemas, tables, and indexes + +# Use --no-strict-names and a single existent table so we only get warnings +# about the failed pattern matches +$node->command_checks_all( + [ + 'pg_amcheck', '--no-strict-names', + '-t', 'no_such_table', + '-t', 'no*such*table', + '-i', 'no_such_index', + '-i', 'no*such*index', + '-r', 'no_such_relation', + '-r', 'no*such*relation', + '-d', 'no_such_database', + '-d', 'no*such*database', + '-r', 'none.none', + '-r', 'none.none.none', + '-r', 'this.is.a.really.long.dotted.string', + '-r', 'postgres.none.none', + '-r', 'postgres.long.dotted.string', + '-r', 'postgres.pg_catalog.none', + '-r', 'postgres.none.pg_class', + '-t', 'postgres.pg_catalog.pg_class', # This exists + ], + 0, + [qr/^$/], + [ + qr/pg_amcheck: warning: no heap tables to check matching "no_such_table"/, + qr/pg_amcheck: warning: no heap tables to check matching "no\*such\*table"/, + qr/pg_amcheck: warning: no btree indexes to check matching "no_such_index"/, + qr/pg_amcheck: warning: no btree indexes to check matching "no\*such\*index"/, + qr/pg_amcheck: warning: no relations to check matching "no_such_relation"/, + qr/pg_amcheck: warning: no relations to check matching "no\*such\*relation"/, + qr/pg_amcheck: warning: no heap tables to check matching "no\*such\*table"/, + qr/pg_amcheck: warning: no connectable databases to check matching "no_such_database"/, + qr/pg_amcheck: warning: no connectable databases to check matching "no\*such\*database"/, + qr/pg_amcheck: warning: no relations to check matching "none\.none"/, + qr/pg_amcheck: warning: no connectable databases to check matching "none\.none\.none"/, + qr/pg_amcheck: warning: no connectable databases to check matching "this\.is\.a\.really\.long\.dotted\.string"/, + qr/pg_amcheck: warning: no relations to check matching "postgres\.none\.none"/, + qr/pg_amcheck: warning: no relations to check matching "postgres\.long\.dotted\.string"/, + qr/pg_amcheck: warning: no relations to check matching "postgres\.pg_catalog\.none"/, + qr/pg_amcheck: warning: no relations to check matching "postgres\.none\.pg_class"/, + ], + 'many unmatched patterns and one matched pattern under --no-strict-names' +); + +######################################### +# Test checking otherwise existent objects but in databases where they do not exist + +$node->safe_psql( + 'postgres', q( + CREATE TABLE public.foo (f integer); + CREATE INDEX foo_idx ON foo(f); +)); +$node->safe_psql('postgres', q(CREATE DATABASE another_db)); + +$node->command_checks_all( + [ + 'pg_amcheck', '-d', + 'postgres', '--no-strict-names', + '-t', 'template1.public.foo', + '-t', 'another_db.public.foo', + '-t', 'no_such_database.public.foo', + '-i', 'template1.public.foo_idx', + '-i', 'another_db.public.foo_idx', + '-i', 'no_such_database.public.foo_idx', + ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: warning: skipping database "template1": amcheck is not installed/, + qr/pg_amcheck: warning: no heap tables to check matching "template1\.public\.foo"/, + qr/pg_amcheck: warning: no heap tables to check matching "another_db\.public\.foo"/, + qr/pg_amcheck: warning: no connectable databases to check matching "no_such_database\.public\.foo"/, + qr/pg_amcheck: warning: no btree indexes to check matching "template1\.public\.foo_idx"/, + qr/pg_amcheck: warning: no btree indexes to check matching "another_db\.public\.foo_idx"/, + qr/pg_amcheck: warning: no connectable databases to check matching "no_such_database\.public\.foo_idx"/, + qr/pg_amcheck: error: no relations to check/, + ], + 'checking otherwise existent objets in the wrong databases'); + + +######################################### +# Test schema exclusion patterns + +# Check with only schema exclusion patterns +$node->command_checks_all( + [ + 'pg_amcheck', '--all', '--no-strict-names', '-S', + 'public', '-S', 'pg_catalog', '-S', + 'pg_toast', '-S', 'information_schema', + ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: warning: skipping database "template1": amcheck is not installed/, + qr/pg_amcheck: error: no relations to check/ + ], + 'schema exclusion patterns exclude all relations'); + +# Check with schema exclusion patterns overriding relation and schema inclusion patterns +$node->command_checks_all( + [ + 'pg_amcheck', '--all', '--no-strict-names', '-s', + 'public', '-s', 'pg_catalog', '-s', + 'pg_toast', '-s', 'information_schema', '-t', + 'pg_catalog.pg_class', '-S*' + ], + 1, + [qr/^$/], + [ + qr/pg_amcheck: warning: skipping database "template1": amcheck is not installed/, + qr/pg_amcheck: error: no relations to check/ + ], + 'schema exclusion pattern overrides all inclusion patterns'); diff --git a/src/bin/pg_amcheck/t/003_check.pl b/src/bin/pg_amcheck/t/003_check.pl new file mode 100644 index 000000000000..817eb4e1160d --- /dev/null +++ b/src/bin/pg_amcheck/t/003_check.pl @@ -0,0 +1,519 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgresNode; +use TestLib; + +use Fcntl qw(:seek); +use Test::More tests => 63; + +my ($node, $port, %corrupt_page, %remove_relation); + +# Returns the filesystem path for the named relation. +# +# Assumes the test node is running +sub relation_filepath +{ + my ($dbname, $relname) = @_; + + my $pgdata = $node->data_dir; + my $rel = + $node->safe_psql($dbname, qq(SELECT pg_relation_filepath('$relname'))); + die "path not found for relation $relname" unless defined $rel; + return "$pgdata/$rel"; +} + +# Returns the name of the toast relation associated with the named relation. +# +# Assumes the test node is running +sub relation_toast +{ + my ($dbname, $relname) = @_; + + my $rel = $node->safe_psql( + $dbname, qq( + SELECT c.reltoastrelid::regclass + FROM pg_catalog.pg_class c + WHERE c.oid = '$relname'::regclass + AND c.reltoastrelid != 0 + )); + return $rel; +} + +# Adds the relation file for the given (dbname, relname) to the list +# to be corrupted by means of overwriting junk in the first page. +# +# Assumes the test node is running. +sub plan_to_corrupt_first_page +{ + my ($dbname, $relname) = @_; + my $relpath = relation_filepath($dbname, $relname); + $corrupt_page{$relpath} = 1; +} + +# Adds the relation file for the given (dbname, relname) to the list +# to be corrupted by means of removing the file.. +# +# Assumes the test node is running +sub plan_to_remove_relation_file +{ + my ($dbname, $relname) = @_; + my $relpath = relation_filepath($dbname, $relname); + $remove_relation{$relpath} = 1; +} + +# For the given (dbname, relname), if a corresponding toast table +# exists, adds that toast table's relation file to the list to be +# corrupted by means of removing the file. +# +# Assumes the test node is running. +sub plan_to_remove_toast_file +{ + my ($dbname, $relname) = @_; + my $toastname = relation_toast($dbname, $relname); + plan_to_remove_relation_file($dbname, $toastname) if ($toastname); +} + +# Corrupts the first page of the given file path +sub corrupt_first_page +{ + my ($relpath) = @_; + + my $fh; + open($fh, '+<', $relpath) + or BAIL_OUT("open failed: $!"); + binmode $fh; + + # Corrupt some line pointers. The values are chosen to hit the + # various line-pointer-corruption checks in verify_heapam.c + # on both little-endian and big-endian architectures. + seek($fh, 32, SEEK_SET) + or BAIL_OUT("seek failed: $!"); + syswrite( + $fh, + pack("L*", + 0xAAA15550, 0xAAA0D550, 0x00010000, 0x00008000, + 0x0000800F, 0x001e8000, 0xFFFFFFFF) + ) or BAIL_OUT("syswrite failed: $!"); + close($fh) + or BAIL_OUT("close failed: $!"); +} + +# Stops the node, performs all the corruptions previously planned, and +# starts the node again. +# +sub perform_all_corruptions() +{ + $node->stop(); + for my $relpath (keys %corrupt_page) + { + corrupt_first_page($relpath); + } + for my $relpath (keys %remove_relation) + { + unlink($relpath); + } + $node->start; +} + +# Test set-up +$node = get_new_node('test'); +$node->init; +$node->append_conf('postgresql.conf', 'autovacuum=off'); +$node->start; +$port = $node->port; + +for my $dbname (qw(db1 db2 db3)) +{ + # Create the database + $node->safe_psql('postgres', qq(CREATE DATABASE $dbname)); + + # Load the amcheck extension, upon which pg_amcheck depends. Put the + # extension in an unexpected location to test that pg_amcheck finds it + # correctly. Create tables with names that look like pg_catalog names to + # check that pg_amcheck does not get confused by them. Create functions in + # schema public that look like amcheck functions to check that pg_amcheck + # does not use them. + $node->safe_psql( + $dbname, q( + CREATE SCHEMA amcheck_schema; + CREATE EXTENSION amcheck WITH SCHEMA amcheck_schema; + CREATE TABLE amcheck_schema.pg_database (junk text); + CREATE TABLE amcheck_schema.pg_namespace (junk text); + CREATE TABLE amcheck_schema.pg_class (junk text); + CREATE TABLE amcheck_schema.pg_operator (junk text); + CREATE TABLE amcheck_schema.pg_proc (junk text); + CREATE TABLE amcheck_schema.pg_tablespace (junk text); + + CREATE FUNCTION public.bt_index_check(index regclass, + heapallindexed boolean default false) + RETURNS VOID AS $$ + BEGIN + RAISE EXCEPTION 'Invoked wrong bt_index_check!'; + END; + $$ LANGUAGE plpgsql; + + CREATE FUNCTION public.bt_index_parent_check(index regclass, + heapallindexed boolean default false, + rootdescend boolean default false) + RETURNS VOID AS $$ + BEGIN + RAISE EXCEPTION 'Invoked wrong bt_index_parent_check!'; + END; + $$ LANGUAGE plpgsql; + + CREATE FUNCTION public.verify_heapam(relation regclass, + on_error_stop boolean default false, + check_toast boolean default false, + skip text default 'none', + startblock bigint default null, + endblock bigint default null, + blkno OUT bigint, + offnum OUT integer, + attnum OUT integer, + msg OUT text) + RETURNS SETOF record AS $$ + BEGIN + RAISE EXCEPTION 'Invoked wrong verify_heapam!'; + END; + $$ LANGUAGE plpgsql; + )); + + # Create schemas, tables and indexes in five separate + # schemas. The schemas are all identical to start, but + # we will corrupt them differently later. + # + for my $schema (qw(s1 s2 s3 s4 s5)) + { + $node->safe_psql( + $dbname, qq( + CREATE SCHEMA $schema; + CREATE SEQUENCE $schema.seq1; + CREATE SEQUENCE $schema.seq2; + CREATE TABLE $schema.t1 ( + i INTEGER, + b BOX, + ia int4[], + ir int4range, + t TEXT + ); + CREATE TABLE $schema.t2 ( + i INTEGER, + b BOX, + ia int4[], + ir int4range, + t TEXT + ); + CREATE VIEW $schema.t2_view AS ( + SELECT i*2, t FROM $schema.t2 + ); + ALTER TABLE $schema.t2 + ALTER COLUMN t + SET STORAGE EXTERNAL; + + INSERT INTO $schema.t1 (i, b, ia, ir, t) + (SELECT gs::INTEGER AS i, + box(point(gs,gs+5),point(gs*2,gs*3)) AS b, + array[gs, gs + 1]::int4[] AS ia, + int4range(gs, gs+100) AS ir, + repeat('foo', gs) AS t + FROM generate_series(1,10000,3000) AS gs); + + INSERT INTO $schema.t2 (i, b, ia, ir, t) + (SELECT gs::INTEGER AS i, + box(point(gs,gs+5),point(gs*2,gs*3)) AS b, + array[gs, gs + 1]::int4[] AS ia, + int4range(gs, gs+100) AS ir, + repeat('foo', gs) AS t + FROM generate_series(1,10000,3000) AS gs); + + CREATE MATERIALIZED VIEW $schema.t1_mv AS SELECT * FROM $schema.t1; + CREATE MATERIALIZED VIEW $schema.t2_mv AS SELECT * FROM $schema.t2; + + create table $schema.p1 (a int, b int) PARTITION BY list (a); + create table $schema.p2 (a int, b int) PARTITION BY list (a); + + create table $schema.p1_1 partition of $schema.p1 for values in (1, 2, 3); + create table $schema.p1_2 partition of $schema.p1 for values in (4, 5, 6); + create table $schema.p2_1 partition of $schema.p2 for values in (1, 2, 3); + create table $schema.p2_2 partition of $schema.p2 for values in (4, 5, 6); + + CREATE INDEX t1_btree ON $schema.t1 USING BTREE (i); + CREATE INDEX t2_btree ON $schema.t2 USING BTREE (i); + + CREATE INDEX t1_hash ON $schema.t1 USING HASH (i); + CREATE INDEX t2_hash ON $schema.t2 USING HASH (i); + + CREATE INDEX t1_brin ON $schema.t1 USING BRIN (i); + CREATE INDEX t2_brin ON $schema.t2 USING BRIN (i); + + CREATE INDEX t1_gist ON $schema.t1 USING GIST (b); + CREATE INDEX t2_gist ON $schema.t2 USING GIST (b); + + CREATE INDEX t1_gin ON $schema.t1 USING GIN (ia); + CREATE INDEX t2_gin ON $schema.t2 USING GIN (ia); + + CREATE INDEX t1_spgist ON $schema.t1 USING SPGIST (ir); + CREATE INDEX t2_spgist ON $schema.t2 USING SPGIST (ir); + )); + } +} + +# Database 'db1' corruptions +# + +# Corrupt indexes in schema "s1" +plan_to_remove_relation_file('db1', 's1.t1_btree'); +plan_to_corrupt_first_page('db1', 's1.t2_btree'); + +# Corrupt tables in schema "s2" +plan_to_remove_relation_file('db1', 's2.t1'); +plan_to_corrupt_first_page('db1', 's2.t2'); + +# Corrupt tables, partitions, matviews, and btrees in schema "s3" +plan_to_remove_relation_file('db1', 's3.t1'); +plan_to_corrupt_first_page('db1', 's3.t2'); + +plan_to_remove_relation_file('db1', 's3.t1_mv'); +plan_to_remove_relation_file('db1', 's3.p1_1'); + +plan_to_corrupt_first_page('db1', 's3.t2_mv'); +plan_to_corrupt_first_page('db1', 's3.p2_1'); + +plan_to_remove_relation_file('db1', 's3.t1_btree'); +plan_to_corrupt_first_page('db1', 's3.t2_btree'); + +# Corrupt toast table, partitions, and materialized views in schema "s4" +plan_to_remove_toast_file('db1', 's4.t2'); + +# Corrupt all other object types in schema "s5". We don't have amcheck support +# for these types, but we check that their corruption does not trigger any +# errors in pg_amcheck +plan_to_remove_relation_file('db1', 's5.seq1'); +plan_to_remove_relation_file('db1', 's5.t1_hash'); +plan_to_remove_relation_file('db1', 's5.t1_gist'); +plan_to_remove_relation_file('db1', 's5.t1_gin'); +plan_to_remove_relation_file('db1', 's5.t1_brin'); +plan_to_remove_relation_file('db1', 's5.t1_spgist'); + +plan_to_corrupt_first_page('db1', 's5.seq2'); +plan_to_corrupt_first_page('db1', 's5.t2_hash'); +plan_to_corrupt_first_page('db1', 's5.t2_gist'); +plan_to_corrupt_first_page('db1', 's5.t2_gin'); +plan_to_corrupt_first_page('db1', 's5.t2_brin'); +plan_to_corrupt_first_page('db1', 's5.t2_spgist'); + + +# Database 'db2' corruptions +# +plan_to_remove_relation_file('db2', 's1.t1'); +plan_to_remove_relation_file('db2', 's1.t1_btree'); + + +# Leave 'db3' uncorrupted +# + +# Standard first arguments to TestLib functions +my @cmd = ('pg_amcheck', '--quiet', '-p', $port); + +# Regular expressions to match various expected output +my $no_output_re = qr/^$/; +my $line_pointer_corruption_re = qr/line pointer/; +my $missing_file_re = qr/could not open file ".*": No such file or directory/; +my $index_missing_relation_fork_re = + qr/index ".*" lacks a main relation fork/; + +# We have created test databases with tables populated with data, but have not +# yet corrupted anything. As such, we expect no corruption and verify that +# none is reported +# +$node->command_checks_all([ @cmd, '-d', 'db1', '-d', 'db2', '-d', 'db3' ], + 0, [$no_output_re], [$no_output_re], 'pg_amcheck prior to corruption'); + +# Perform the corruptions we planned above using only a single database restart. +# +perform_all_corruptions(); + + +# Checking databases with amcheck installed and corrupt relations, pg_amcheck +# command itself should return exit status = 2, because tables and indexes are +# corrupt, not exit status = 1, which would mean the pg_amcheck command itself +# failed. Corruption messages should go to stdout, and nothing to stderr. +# +$node->command_checks_all( + [ @cmd, 'db1' ], + 2, + [ + $index_missing_relation_fork_re, $line_pointer_corruption_re, + $missing_file_re, + ], + [$no_output_re], + 'pg_amcheck all schemas, tables and indexes in database db1'); + +$node->command_checks_all( + [ @cmd, '-d', 'db1', '-d', 'db2', '-d', 'db3' ], + 2, + [ + $index_missing_relation_fork_re, $line_pointer_corruption_re, + $missing_file_re, + ], + [$no_output_re], + 'pg_amcheck all schemas, tables and indexes in databases db1, db2, and db3' +); + +# Scans of indexes in s1 should detect the specific corruption that we created +# above. For missing relation forks, we know what the error message looks +# like. For corrupted index pages, the error might vary depending on how the +# page was formatted on disk, including variations due to alignment differences +# between platforms, so we accept any non-empty error message. +# +# If we don't limit the check to databases with amcheck installed, we expect +# complaint on stderr, but otherwise stderr should be quiet. +# +$node->command_checks_all( + [ @cmd, '--all', '-s', 's1', '-i', 't1_btree' ], + 2, + [$index_missing_relation_fork_re], + [ + qr/pg_amcheck: warning: skipping database "postgres": amcheck is not installed/ + ], + 'pg_amcheck index s1.t1_btree reports missing main relation fork'); + +$node->command_checks_all( + [ @cmd, '-d', 'db1', '-s', 's1', '-i', 't2_btree' ], + 2, + [qr/.+/], # Any non-empty error message is acceptable + [$no_output_re], + 'pg_amcheck index s1.s2 reports index corruption'); + +# Checking db1.s1 with indexes excluded should show no corruptions because we +# did not corrupt any tables in db1.s1. Verify that both stdout and stderr +# are quiet. +# +$node->command_checks_all( + [ @cmd, '-t', 's1.*', '--no-dependent-indexes', 'db1' ], + 0, [$no_output_re], [$no_output_re], + 'pg_amcheck of db1.s1 excluding indexes'); + +# Checking db2.s1 should show table corruptions if indexes are excluded +# +$node->command_checks_all( + [ @cmd, '-t', 's1.*', '--no-dependent-indexes', 'db2' ], + 2, [$missing_file_re], [$no_output_re], + 'pg_amcheck of db2.s1 excluding indexes'); + +# In schema db1.s3, the tables and indexes are both corrupt. We should see +# corruption messages on stdout, and nothing on stderr. +# +$node->command_checks_all( + [ @cmd, '-s', 's3', 'db1' ], + 2, + [ + $index_missing_relation_fork_re, $line_pointer_corruption_re, + $missing_file_re, + ], + [$no_output_re], + 'pg_amcheck schema s3 reports table and index errors'); + +# In schema db1.s4, only toast tables are corrupt. Check that under default +# options the toast corruption is reported, but when excluding toast we get no +# error reports. +$node->command_checks_all([ @cmd, '-s', 's4', 'db1' ], + 2, [$missing_file_re], [$no_output_re], + 'pg_amcheck in schema s4 reports toast corruption'); + +$node->command_checks_all( + [ + @cmd, '--no-dependent-toast', '--exclude-toast-pointers', '-s', 's4', + 'db1' + ], + 0, + [$no_output_re], + [$no_output_re], + 'pg_amcheck in schema s4 excluding toast reports no corruption'); + +# Check that no corruption is reported in schema db1.s5 +$node->command_checks_all([ @cmd, '-s', 's5', 'db1' ], + 0, [$no_output_re], [$no_output_re], + 'pg_amcheck over schema s5 reports no corruption'); + +# In schema db1.s1, only indexes are corrupt. Verify that when we exclude +# the indexes, no corruption is reported about the schema. +# +$node->command_checks_all( + [ @cmd, '-s', 's1', '-I', 't1_btree', '-I', 't2_btree', 'db1' ], + 0, + [$no_output_re], + [$no_output_re], + 'pg_amcheck over schema s1 with corrupt indexes excluded reports no corruption' +); + +# In schema db1.s1, only indexes are corrupt. Verify that when we provide only +# table inclusions, and disable index expansion, no corruption is reported +# about the schema. +# +$node->command_checks_all( + [ @cmd, '-t', 's1.*', '--no-dependent-indexes', 'db1' ], + 0, + [$no_output_re], + [$no_output_re], + 'pg_amcheck over schema s1 with all indexes excluded reports no corruption' +); + +# In schema db1.s2, only tables are corrupt. Verify that when we exclude those +# tables that no corruption is reported. +# +$node->command_checks_all( + [ @cmd, '-s', 's2', '-T', 't1', '-T', 't2', 'db1' ], + 0, + [$no_output_re], + [$no_output_re], + 'pg_amcheck over schema s2 with corrupt tables excluded reports no corruption' +); + +# Check errors about bad block range command line arguments. We use schema s5 +# to avoid getting messages about corrupt tables or indexes. +# +command_fails_like( + [ @cmd, '-s', 's5', '--startblock', 'junk', 'db1' ], + qr/invalid start block/, + 'pg_amcheck rejects garbage startblock'); + +command_fails_like( + [ @cmd, '-s', 's5', '--endblock', '1234junk', 'db1' ], + qr/invalid end block/, + 'pg_amcheck rejects garbage endblock'); + +command_fails_like( + [ @cmd, '-s', 's5', '--startblock', '5', '--endblock', '4', 'db1' ], + qr/end block precedes start block/, + 'pg_amcheck rejects invalid block range'); + +# Check bt_index_parent_check alternates. We don't create any index corruption +# that would behave differently under these modes, so just smoke test that the +# arguments are handled sensibly. +# +$node->command_checks_all( + [ @cmd, '-s', 's1', '-i', 't1_btree', '--parent-check', 'db1' ], + 2, + [$index_missing_relation_fork_re], + [$no_output_re], + 'pg_amcheck smoke test --parent-check'); + +$node->command_checks_all( + [ + @cmd, '-s', 's1', '-i', 't1_btree', '--heapallindexed', + '--rootdescend', 'db1' + ], + 2, + [$index_missing_relation_fork_re], + [$no_output_re], + 'pg_amcheck smoke test --heapallindexed --rootdescend'); + +$node->command_checks_all( + [ @cmd, '-d', 'db1', '-d', 'db2', '-d', 'db3', '-S', 's*' ], + 0, [$no_output_re], [$no_output_re], + 'pg_amcheck excluding all corrupt schemas'); diff --git a/src/bin/pg_amcheck/t/004_verify_heapam.pl b/src/bin/pg_amcheck/t/004_verify_heapam.pl new file mode 100644 index 000000000000..b3a96e801690 --- /dev/null +++ b/src/bin/pg_amcheck/t/004_verify_heapam.pl @@ -0,0 +1,530 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use PostgresNode; +use TestLib; + +use Fcntl qw(:seek); +use Test::More; + +# This regression test demonstrates that the pg_amcheck binary correctly +# identifies specific kinds of corruption within pages. To test this, we need +# a mechanism to create corrupt pages with predictable, repeatable corruption. +# The postgres backend cannot be expected to help us with this, as its design +# is not consistent with the goal of intentionally corrupting pages. +# +# Instead, we create a table to corrupt, and with careful consideration of how +# postgresql lays out heap pages, we seek to offsets within the page and +# overwrite deliberately chosen bytes with specific values calculated to +# corrupt the page in expected ways. We then verify that pg_amcheck reports +# the corruption, and that it runs without crashing. Note that the backend +# cannot simply be started to run queries against the corrupt table, as the +# backend will crash, at least for some of the corruption types we generate. +# +# Autovacuum potentially touching the table in the background makes the exact +# behavior of this test harder to reason about. We turn it off to keep things +# simpler. We use a "belt and suspenders" approach, turning it off for the +# system generally in postgresql.conf, and turning it off specifically for the +# test table. +# +# This test depends on the table being written to the heap file exactly as we +# expect it to be, so we take care to arrange the columns of the table, and +# insert rows of the table, that give predictable sizes and locations within +# the table page. +# +# The HeapTupleHeaderData has 23 bytes of fixed size fields before the variable +# length t_bits[] array. We have exactly 3 columns in the table, so natts = 3, +# t_bits is 1 byte long, and t_hoff = MAXALIGN(23 + 1) = 24. +# +# We're not too fussy about which datatypes we use for the test, but we do care +# about some specific properties. We'd like to test both fixed size and +# varlena types. We'd like some varlena data inline and some toasted. And +# we'd like the layout of the table such that the datums land at predictable +# offsets within the tuple. We choose a structure without padding on all +# supported architectures: +# +# a BIGINT +# b TEXT +# c TEXT +# +# We always insert a 7-ascii character string into field 'b', which with a +# 1-byte varlena header gives an 8 byte inline value. We always insert a long +# text string in field 'c', long enough to force toast storage. +# +# We choose to read and write binary copies of our table's tuples, using perl's +# pack() and unpack() functions. Perl uses a packing code system in which: +# +# l = "signed 32-bit Long", +# L = "Unsigned 32-bit Long", +# S = "Unsigned 16-bit Short", +# C = "Unsigned 8-bit Octet", +# +# Each tuple in our table has a layout as follows: +# +# xx xx xx xx t_xmin: xxxx offset = 0 L +# xx xx xx xx t_xmax: xxxx offset = 4 L +# xx xx xx xx t_field3: xxxx offset = 8 L +# xx xx bi_hi: xx offset = 12 S +# xx xx bi_lo: xx offset = 14 S +# xx xx ip_posid: xx offset = 16 S +# xx xx t_infomask2: xx offset = 18 S +# xx xx t_infomask: xx offset = 20 S +# xx t_hoff: x offset = 22 C +# xx t_bits: x offset = 23 C +# xx xx xx xx xx xx xx xx 'a': xxxxxxxx offset = 24 LL +# xx xx xx xx xx xx xx xx 'b': xxxxxxxx offset = 32 CCCCCCCC +# xx xx xx xx xx xx xx xx 'c': xxxxxxxx offset = 40 CCllLL +# xx xx xx xx xx xx xx xx : xxxxxxxx ...continued +# xx xx : xx ...continued +# +# We could choose to read and write columns 'b' and 'c' in other ways, but +# it is convenient enough to do it this way. We define packing code +# constants here, where they can be compared easily against the layout. + +use constant HEAPTUPLE_PACK_CODE => 'LLLSSSSSCCLLCCCCCCCCCCllLL'; +use constant HEAPTUPLE_PACK_LENGTH => 58; # Total size + +# Read a tuple of our table from a heap page. +# +# Takes an open filehandle to the heap file, and the offset of the tuple. +# +# Rather than returning the binary data from the file, unpacks the data into a +# perl hash with named fields. These fields exactly match the ones understood +# by write_tuple(), below. Returns a reference to this hash. +# +sub read_tuple +{ + my ($fh, $offset) = @_; + my ($buffer, %tup); + seek($fh, $offset, SEEK_SET) + or BAIL_OUT("seek failed: $!"); + defined(sysread($fh, $buffer, HEAPTUPLE_PACK_LENGTH)) + or BAIL_OUT("sysread failed: $!"); + + @_ = unpack(HEAPTUPLE_PACK_CODE, $buffer); + %tup = ( + t_xmin => shift, + t_xmax => shift, + t_field3 => shift, + bi_hi => shift, + bi_lo => shift, + ip_posid => shift, + t_infomask2 => shift, + t_infomask => shift, + t_hoff => shift, + t_bits => shift, + a_1 => shift, + a_2 => shift, + b_header => shift, + b_body1 => shift, + b_body2 => shift, + b_body3 => shift, + b_body4 => shift, + b_body5 => shift, + b_body6 => shift, + b_body7 => shift, + c_va_header => shift, + c_va_vartag => shift, + c_va_rawsize => shift, + c_va_extinfo => shift, + c_va_valueid => shift, + c_va_toastrelid => shift); + # Stitch together the text for column 'b' + $tup{b} = join('', map { chr($tup{"b_body$_"}) } (1 .. 7)); + return \%tup; +} + +# Write a tuple of our table to a heap page. +# +# Takes an open filehandle to the heap file, the offset of the tuple, and a +# reference to a hash with the tuple values, as returned by read_tuple(). +# Writes the tuple fields from the hash into the heap file. +# +# The purpose of this function is to write a tuple back to disk with some +# subset of fields modified. The function does no error checking. Use +# cautiously. +# +sub write_tuple +{ + my ($fh, $offset, $tup) = @_; + my $buffer = pack( + HEAPTUPLE_PACK_CODE, + $tup->{t_xmin}, $tup->{t_xmax}, + $tup->{t_field3}, $tup->{bi_hi}, + $tup->{bi_lo}, $tup->{ip_posid}, + $tup->{t_infomask2}, $tup->{t_infomask}, + $tup->{t_hoff}, $tup->{t_bits}, + $tup->{a_1}, $tup->{a_2}, + $tup->{b_header}, $tup->{b_body1}, + $tup->{b_body2}, $tup->{b_body3}, + $tup->{b_body4}, $tup->{b_body5}, + $tup->{b_body6}, $tup->{b_body7}, + $tup->{c_va_header}, $tup->{c_va_vartag}, + $tup->{c_va_rawsize}, $tup->{c_va_extinfo}, + $tup->{c_va_valueid}, $tup->{c_va_toastrelid}); + seek($fh, $offset, SEEK_SET) + or BAIL_OUT("seek failed: $!"); + defined(syswrite($fh, $buffer, HEAPTUPLE_PACK_LENGTH)) + or BAIL_OUT("syswrite failed: $!"); + return; +} + +# Set umask so test directories and files are created with default permissions +umask(0077); + +# Set up the node. Once we create and corrupt the table, +# autovacuum workers visiting the table could crash the backend. +# Disable autovacuum so that won't happen. +my $node = get_new_node('test'); +$node->init; +$node->append_conf('postgresql.conf', 'autovacuum=off'); + +# Start the node and load the extensions. We depend on both +# amcheck and pageinspect for this test. +$node->start; +my $port = $node->port; +my $pgdata = $node->data_dir; +$node->safe_psql('postgres', "CREATE EXTENSION amcheck"); +$node->safe_psql('postgres', "CREATE EXTENSION pageinspect"); + +# Get a non-zero datfrozenxid +$node->safe_psql('postgres', qq(VACUUM FREEZE)); + +# Create the test table with precisely the schema that our corruption function +# expects. +$node->safe_psql( + 'postgres', qq( + CREATE TABLE public.test (a BIGINT, b TEXT, c TEXT); + ALTER TABLE public.test SET (autovacuum_enabled=false); + ALTER TABLE public.test ALTER COLUMN c SET STORAGE EXTERNAL; + CREATE INDEX test_idx ON public.test(a, b); + )); + +# We want (0 < datfrozenxid < test.relfrozenxid). To achieve this, we freeze +# an otherwise unused table, public.junk, prior to inserting data and freezing +# public.test +$node->safe_psql( + 'postgres', qq( + CREATE TABLE public.junk AS SELECT 'junk'::TEXT AS junk_column; + ALTER TABLE public.junk SET (autovacuum_enabled=false); + VACUUM FREEZE public.junk + )); + +my $rel = $node->safe_psql('postgres', + qq(SELECT pg_relation_filepath('public.test'))); +my $relpath = "$pgdata/$rel"; + +# Insert data and freeze public.test +use constant ROWCOUNT => 16; +$node->safe_psql( + 'postgres', qq( + INSERT INTO public.test (a, b, c) + VALUES ( + x'DEADF9F9DEADF9F9'::bigint, + 'abcdefg', + repeat('w', 10000) + ); + VACUUM FREEZE public.test + )) for (1 .. ROWCOUNT); + +my $relfrozenxid = $node->safe_psql('postgres', + q(select relfrozenxid from pg_class where relname = 'test')); +my $datfrozenxid = $node->safe_psql('postgres', + q(select datfrozenxid from pg_database where datname = 'postgres')); + +# Sanity check that our 'test' table has a relfrozenxid newer than the +# datfrozenxid for the database, and that the datfrozenxid is greater than the +# first normal xid. We rely on these invariants in some of our tests. +if ($datfrozenxid <= 3 || $datfrozenxid >= $relfrozenxid) +{ + $node->clean_node; + plan skip_all => + "Xid thresholds not as expected: got datfrozenxid = $datfrozenxid, relfrozenxid = $relfrozenxid"; + exit; +} + +# Find where each of the tuples is located on the page. +my @lp_off; +for my $tup (0 .. ROWCOUNT - 1) +{ + push( + @lp_off, + $node->safe_psql( + 'postgres', qq( +select lp_off from heap_page_items(get_raw_page('test', 'main', 0)) + offset $tup limit 1))); +} + +# Sanity check that our 'test' table on disk layout matches expectations. If +# this is not so, we will have to skip the test until somebody updates the test +# to work on this platform. +$node->stop; +my $file; +open($file, '+<', $relpath) + or BAIL_OUT("open failed: $!"); +binmode $file; + +my $ENDIANNESS; +for (my $tupidx = 0; $tupidx < ROWCOUNT; $tupidx++) +{ + my $offnum = $tupidx + 1; # offnum is 1-based, not zero-based + my $offset = $lp_off[$tupidx]; + my $tup = read_tuple($file, $offset); + + # Sanity-check that the data appears on the page where we expect. + my $a_1 = $tup->{a_1}; + my $a_2 = $tup->{a_2}; + my $b = $tup->{b}; + if ($a_1 != 0xDEADF9F9 || $a_2 != 0xDEADF9F9 || $b ne 'abcdefg') + { + close($file); # ignore errors on close; we're exiting anyway + $node->clean_node; + plan skip_all => + sprintf( + "Page layout differs from our expectations: expected (%x, %x, \"%s\"), got (%x, %x, \"%s\")", + 0xDEADF9F9, 0xDEADF9F9, "abcdefg", $a_1, $a_2, $b); + exit; + } + + # Determine endianness of current platform from the 1-byte varlena header + $ENDIANNESS = $tup->{b_header} == 0x11 ? "little" : "big"; +} +close($file) + or BAIL_OUT("close failed: $!"); +$node->start; + +# Ok, Xids and page layout look ok. We can run corruption tests. +plan tests => 19; + +# Check that pg_amcheck runs against the uncorrupted table without error. +$node->command_ok( + [ 'pg_amcheck', '-p', $port, 'postgres' ], + 'pg_amcheck test table, prior to corruption'); + +# Check that pg_amcheck runs against the uncorrupted table and index without error. +$node->command_ok([ 'pg_amcheck', '-p', $port, 'postgres' ], + 'pg_amcheck test table and index, prior to corruption'); + +$node->stop; + +# Some #define constants from access/htup_details.h for use while corrupting. +use constant HEAP_HASNULL => 0x0001; +use constant HEAP_XMAX_LOCK_ONLY => 0x0080; +use constant HEAP_XMIN_COMMITTED => 0x0100; +use constant HEAP_XMIN_INVALID => 0x0200; +use constant HEAP_XMAX_COMMITTED => 0x0400; +use constant HEAP_XMAX_INVALID => 0x0800; +use constant HEAP_NATTS_MASK => 0x07FF; +use constant HEAP_XMAX_IS_MULTI => 0x1000; +use constant HEAP_KEYS_UPDATED => 0x2000; + +# Helper function to generate a regular expression matching the header we +# expect verify_heapam() to return given which fields we expect to be non-null. +sub header +{ + my ($blkno, $offnum, $attnum) = @_; + return + qr/heap table "postgres"\."public"\."test", block $blkno, offset $offnum, attribute $attnum:\s+/ms + if (defined $attnum); + return + qr/heap table "postgres"\."public"\."test", block $blkno, offset $offnum:\s+/ms + if (defined $offnum); + return qr/heap table "postgres"\."public"\."test", block $blkno:\s+/ms + if (defined $blkno); + return qr/heap table "postgres"\."public"\."test":\s+/ms; +} + +# Corrupt the tuples, one type of corruption per tuple. Some types of +# corruption cause verify_heapam to skip to the next tuple without +# performing any remaining checks, so we can't exercise the system properly if +# we focus all our corruption on a single tuple. +# +my @expected; +open($file, '+<', $relpath) + or BAIL_OUT("open failed: $!"); +binmode $file; + +for (my $tupidx = 0; $tupidx < ROWCOUNT; $tupidx++) +{ + my $offnum = $tupidx + 1; # offnum is 1-based, not zero-based + my $offset = $lp_off[$tupidx]; + my $tup = read_tuple($file, $offset); + + my $header = header(0, $offnum, undef); + if ($offnum == 1) + { + # Corruptly set xmin < relfrozenxid + my $xmin = $relfrozenxid - 1; + $tup->{t_xmin} = $xmin; + $tup->{t_infomask} &= ~HEAP_XMIN_COMMITTED; + $tup->{t_infomask} &= ~HEAP_XMIN_INVALID; + + # Expected corruption report + push @expected, + qr/${header}xmin $xmin precedes relation freeze threshold 0:\d+/; + } + if ($offnum == 2) + { + # Corruptly set xmin < datfrozenxid + my $xmin = 3; + $tup->{t_xmin} = $xmin; + $tup->{t_infomask} &= ~HEAP_XMIN_COMMITTED; + $tup->{t_infomask} &= ~HEAP_XMIN_INVALID; + + push @expected, + qr/${$header}xmin $xmin precedes oldest valid transaction ID 0:\d+/; + } + elsif ($offnum == 3) + { + # Corruptly set xmin < datfrozenxid, further back, noting circularity + # of xid comparison. For a new cluster with epoch = 0, the corrupt + # xmin will be interpreted as in the future + $tup->{t_xmin} = 4026531839; + $tup->{t_infomask} &= ~HEAP_XMIN_COMMITTED; + $tup->{t_infomask} &= ~HEAP_XMIN_INVALID; + + push @expected, + qr/${$header}xmin 4026531839 equals or exceeds next valid transaction ID 0:\d+/; + } + elsif ($offnum == 4) + { + # Corruptly set xmax < relminmxid; + $tup->{t_xmax} = 4026531839; + $tup->{t_infomask} &= ~HEAP_XMAX_INVALID; + + push @expected, + qr/${$header}xmax 4026531839 equals or exceeds next valid transaction ID 0:\d+/; + } + elsif ($offnum == 5) + { + # Corrupt the tuple t_hoff, but keep it aligned properly + $tup->{t_hoff} += 128; + + push @expected, + qr/${$header}data begins at offset 152 beyond the tuple length 58/, + qr/${$header}tuple data should begin at byte 24, but actually begins at byte 152 \(3 attributes, no nulls\)/; + } + elsif ($offnum == 6) + { + # Corrupt the tuple t_hoff, wrong alignment + $tup->{t_hoff} += 3; + + push @expected, + qr/${$header}tuple data should begin at byte 24, but actually begins at byte 27 \(3 attributes, no nulls\)/; + } + elsif ($offnum == 7) + { + # Corrupt the tuple t_hoff, underflow but correct alignment + $tup->{t_hoff} -= 8; + + push @expected, + qr/${$header}tuple data should begin at byte 24, but actually begins at byte 16 \(3 attributes, no nulls\)/; + } + elsif ($offnum == 8) + { + # Corrupt the tuple t_hoff, underflow and wrong alignment + $tup->{t_hoff} -= 3; + + push @expected, + qr/${$header}tuple data should begin at byte 24, but actually begins at byte 21 \(3 attributes, no nulls\)/; + } + elsif ($offnum == 9) + { + # Corrupt the tuple to look like it has lots of attributes, not just 3 + $tup->{t_infomask2} |= HEAP_NATTS_MASK; + + push @expected, + qr/${$header}number of attributes 2047 exceeds maximum expected for table 3/; + } + elsif ($offnum == 10) + { + # Corrupt the tuple to look like it has lots of attributes, some of + # them null. This falsely creates the impression that the t_bits + # array is longer than just one byte, but t_hoff still says otherwise. + $tup->{t_infomask} |= HEAP_HASNULL; + $tup->{t_infomask2} |= HEAP_NATTS_MASK; + $tup->{t_bits} = 0xAA; + + push @expected, + qr/${$header}tuple data should begin at byte 280, but actually begins at byte 24 \(2047 attributes, has nulls\)/; + } + elsif ($offnum == 11) + { + # Same as above, but this time t_hoff plays along + $tup->{t_infomask} |= HEAP_HASNULL; + $tup->{t_infomask2} |= (HEAP_NATTS_MASK & 0x40); + $tup->{t_bits} = 0xAA; + $tup->{t_hoff} = 32; + + push @expected, + qr/${$header}number of attributes 67 exceeds maximum expected for table 3/; + } + elsif ($offnum == 12) + { + # Overwrite column 'b' 1-byte varlena header and initial characters to + # look like a long 4-byte varlena + # + # On little endian machines, bytes ending in two zero bits (xxxxxx00 bytes) + # are 4-byte length word, aligned, uncompressed data (up to 1G). We set the + # high six bits to 111111 and the lower two bits to 00, then the next three + # bytes with 0xFF using 0xFCFFFFFF. + # + # On big endian machines, bytes starting in two zero bits (00xxxxxx bytes) + # are 4-byte length word, aligned, uncompressed data (up to 1G). We set the + # low six bits to 111111 and the high two bits to 00, then the next three + # bytes with 0xFF using 0x3FFFFFFF. + # + $tup->{b_header} = $ENDIANNESS eq 'little' ? 0xFC : 0x3F; + $tup->{b_body1} = 0xFF; + $tup->{b_body2} = 0xFF; + $tup->{b_body3} = 0xFF; + + $header = header(0, $offnum, 1); + push @expected, + qr/${header}attribute with length \d+ ends at offset \d+ beyond total tuple length \d+/; + } + elsif ($offnum == 13) + { + # Corrupt the bits in column 'c' toast pointer + $tup->{c_va_valueid} = 0xFFFFFFFF; + + $header = header(0, $offnum, 2); + push @expected, qr/${header}toast value \d+ not found in toast table/; + } + elsif ($offnum == 14) + { + # Set both HEAP_XMAX_COMMITTED and HEAP_XMAX_IS_MULTI + $tup->{t_infomask} |= HEAP_XMAX_COMMITTED; + $tup->{t_infomask} |= HEAP_XMAX_IS_MULTI; + $tup->{t_xmax} = 4; + + push @expected, + qr/${header}multitransaction ID 4 equals or exceeds next valid multitransaction ID 1/; + } + elsif ($offnum == 15) # Last offnum must equal ROWCOUNT + { + # Set both HEAP_XMAX_COMMITTED and HEAP_XMAX_IS_MULTI + $tup->{t_infomask} |= HEAP_XMAX_COMMITTED; + $tup->{t_infomask} |= HEAP_XMAX_IS_MULTI; + $tup->{t_xmax} = 4000000000; + + push @expected, + qr/${header}multitransaction ID 4000000000 precedes relation minimum multitransaction ID threshold 1/; + } + write_tuple($file, $offset, $tup); +} +close($file) + or BAIL_OUT("close failed: $!"); +$node->start; + +# Run pg_amcheck against the corrupt table with epoch=0, comparing actual +# corruption messages against the expected messages +$node->command_checks_all( + [ 'pg_amcheck', '--no-dependent-indexes', '-p', $port, 'postgres' ], + 2, [@expected], [], 'Expected corruption message output'); + +$node->teardown_node; +$node->clean_node; diff --git a/src/bin/pg_amcheck/t/005_opclass_damage.pl b/src/bin/pg_amcheck/t/005_opclass_damage.pl new file mode 100644 index 000000000000..b65becae9d81 --- /dev/null +++ b/src/bin/pg_amcheck/t/005_opclass_damage.pl @@ -0,0 +1,59 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +# This regression test checks the behavior of the btree validation in the +# presence of breaking sort order changes. +# +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 5; + +my $node = get_new_node('test'); +$node->init; +$node->start; + +# Create a custom operator class and an index which uses it. +$node->safe_psql( + 'postgres', q( + CREATE EXTENSION amcheck; + + CREATE FUNCTION int4_asc_cmp (a int4, b int4) RETURNS int LANGUAGE sql AS $$ + SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$; + + CREATE OPERATOR CLASS int4_fickle_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4, int4), OPERATOR 2 <= (int4, int4), + OPERATOR 3 = (int4, int4), OPERATOR 4 >= (int4, int4), + OPERATOR 5 > (int4, int4), FUNCTION 1 int4_asc_cmp(int4, int4); + + CREATE TABLE int4tbl (i int4); + INSERT INTO int4tbl (SELECT * FROM generate_series(1,1000) gs); + CREATE INDEX fickleidx ON int4tbl USING btree (i int4_fickle_ops); +)); + +# We have not yet broken the index, so we should get no corruption +$node->command_like( + [ 'pg_amcheck', '--quiet', '-p', $node->port, 'postgres' ], + qr/^$/, + 'pg_amcheck all schemas, tables and indexes reports no corruption'); + +# Change the operator class to use a function which sorts in a different +# order to corrupt the btree index +$node->safe_psql( + 'postgres', q( + CREATE FUNCTION int4_desc_cmp (int4, int4) RETURNS int LANGUAGE sql AS $$ + SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN -1 ELSE 1 END; $$; + UPDATE pg_catalog.pg_amproc + SET amproc = 'int4_desc_cmp'::regproc + WHERE amproc = 'int4_asc_cmp'::regproc +)); + +# Index corruption should now be reported +$node->command_checks_all( + [ 'pg_amcheck', '-p', $node->port, 'postgres' ], + 2, + [qr/item order invariant violated for index "fickleidx"/], + [], + 'pg_amcheck all schemas, tables and indexes reports fickleidx corruption' +); diff --git a/src/bin/pg_archivecleanup/nls.mk b/src/bin/pg_archivecleanup/nls.mk index 20a09c8d78ed..51a6767d8d94 100644 --- a/src/bin/pg_archivecleanup/nls.mk +++ b/src/bin/pg_archivecleanup/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_archivecleanup/nls.mk CATALOG_NAME = pg_archivecleanup -AVAIL_LANGUAGES = cs de es fr ja ko pl ru sv tr uk vi zh_CN +AVAIL_LANGUAGES = cs de el es fr ja ko pl ru sv tr uk vi zh_CN GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_archivecleanup.c GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_archivecleanup/pg_archivecleanup.c b/src/bin/pg_archivecleanup/pg_archivecleanup.c index 81fa63c742e6..45f590c519fe 100644 --- a/src/bin/pg_archivecleanup/pg_archivecleanup.c +++ b/src/bin/pg_archivecleanup/pg_archivecleanup.c @@ -303,7 +303,7 @@ main(int argc, char **argv) switch (c) { case 'd': /* Debug mode */ - pg_logging_set_level(PG_LOG_DEBUG); + pg_logging_increase_verbosity(); break; case 'n': /* Dry-Run mode */ dryrun = true; diff --git a/src/bin/pg_archivecleanup/po/cs.po b/src/bin/pg_archivecleanup/po/cs.po index c7f87a76a848..3a9419cd5f18 100644 --- a/src/bin/pg_archivecleanup/po/cs.po +++ b/src/bin/pg_archivecleanup/po/cs.po @@ -7,71 +7,68 @@ msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-27 08:15+0000\n" -"PO-Revision-Date: 2019-09-28 11:28+0200\n" +"POT-Creation-Date: 2020-10-31 16:16+0000\n" +"PO-Revision-Date: 2020-10-31 21:37+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 2.4.1\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format -#| msgid "fatal\n" msgid "fatal: " msgstr "fatal: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format -#| msgid "SQL error: %s\n" msgid "error: " msgstr "error: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format -#| msgid "warning" msgid "warning: " msgstr "warning: " -#: pg_archivecleanup.c:68 +#: pg_archivecleanup.c:66 #, c-format msgid "archive location \"%s\" does not exist" msgstr "archivní lokace \"%s\" neexistuje" -#: pg_archivecleanup.c:154 +#: pg_archivecleanup.c:152 #, c-format msgid "could not remove file \"%s\": %m" msgstr "nelze odstranit soubor \"%s\": %m" -#: pg_archivecleanup.c:162 +#: pg_archivecleanup.c:160 #, c-format msgid "could not read archive location \"%s\": %m" msgstr "nelze načíst archivní lokaci \"%s\": %m" -#: pg_archivecleanup.c:165 +#: pg_archivecleanup.c:163 #, c-format msgid "could not close archive location \"%s\": %m" msgstr "nelze uzavřít archivní lokaci \"%s\": %m" -#: pg_archivecleanup.c:169 +#: pg_archivecleanup.c:167 #, c-format msgid "could not open archive location \"%s\": %m" msgstr "nelze otevřít archivní lokaci \"%s\": %m" -#: pg_archivecleanup.c:242 +#: pg_archivecleanup.c:240 #, c-format msgid "invalid file name argument" msgstr "chybný argument jména souboru" -#: pg_archivecleanup.c:243 pg_archivecleanup.c:316 pg_archivecleanup.c:337 -#: pg_archivecleanup.c:349 pg_archivecleanup.c:356 +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: pg_archivecleanup.c:256 +#: pg_archivecleanup.c:254 #, c-format msgid "" "%s removes older WAL files from PostgreSQL archives.\n" @@ -80,17 +77,17 @@ msgstr "" "%s odstraní starší WAL soubory z PostgreSQL archivů.\n" "\n" -#: pg_archivecleanup.c:257 +#: pg_archivecleanup.c:255 #, c-format msgid "Usage:\n" msgstr "Použití:\n" -#: pg_archivecleanup.c:258 +#: pg_archivecleanup.c:256 #, c-format msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" msgstr " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" -#: pg_archivecleanup.c:259 +#: pg_archivecleanup.c:257 #, c-format msgid "" "\n" @@ -99,32 +96,32 @@ msgstr "" "\n" "Přepínače:\n" -#: pg_archivecleanup.c:260 +#: pg_archivecleanup.c:258 #, c-format msgid " -d generate debug output (verbose mode)\n" msgstr " -d vygeneruje debug výstup (více informací)\n" -#: pg_archivecleanup.c:261 +#: pg_archivecleanup.c:259 #, c-format msgid " -n dry run, show the names of the files that would be removed\n" msgstr " -n zkušební běh, ukazuje jména souborů které by byly odstraněny\n" -#: pg_archivecleanup.c:262 +#: pg_archivecleanup.c:260 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version vypíše informaci o verzi, pak skončí\n" -#: pg_archivecleanup.c:263 +#: pg_archivecleanup.c:261 #, c-format msgid " -x EXT clean up files if they have this extension\n" msgstr " -x EXT vyčistí soubory pokud mají tuto příponu\n" -#: pg_archivecleanup.c:264 +#: pg_archivecleanup.c:262 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ukáže tuto nápovědu, a skončí\n" -#: pg_archivecleanup.c:265 +#: pg_archivecleanup.c:263 #, c-format msgid "" "\n" @@ -139,7 +136,7 @@ msgstr "" "e.g.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" -#: pg_archivecleanup.c:270 +#: pg_archivecleanup.c:268 #, c-format msgid "" "\n" @@ -152,38 +149,50 @@ msgstr "" "e.g.\n" " pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" -#: pg_archivecleanup.c:274 +#: pg_archivecleanup.c:272 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to <%s>.\n" msgstr "" "\n" -"Chyby hlaste na adresu .\n" +"Chyby hlašte na <%s>.\n" -#: pg_archivecleanup.c:336 +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#: pg_archivecleanup.c:335 #, c-format msgid "must specify archive location" msgstr "nutno zadat archivní lokaci" -#: pg_archivecleanup.c:348 +#: pg_archivecleanup.c:347 #, c-format msgid "must specify oldest kept WAL file" msgstr "nutno zadat nejstarčí uchovávaný WAL soubor" -#: pg_archivecleanup.c:355 +#: pg_archivecleanup.c:354 #, c-format msgid "too many command-line arguments" msgstr "příliš mnoho argumentů na příkazové řádce" -#~ msgid "%s: keeping WAL file \"%s\" and later\n" -#~ msgstr "%s: uchovávám WAL soubor \"%s\" a novější\n" +#~ msgid "%s: file \"%s\" would be removed\n" +#~ msgstr "%s: soubor \"%s\" by byl odstraněn\n" + +#~ msgid "%s: removing file \"%s\"\n" +#~ msgstr "%s: odstraňuji soubor \"%s\"\n" #~ msgid "%s: ERROR: could not remove file \"%s\": %s\n" #~ msgstr "%s: ERROR: nelze odstranit soubor \"%s\": %s\n" -#~ msgid "%s: removing file \"%s\"\n" -#~ msgstr "%s: odstraňuji soubor \"%s\"\n" +#~ msgid "%s: keeping WAL file \"%s\" and later\n" +#~ msgstr "%s: uchovávám WAL soubor \"%s\" a novější\n" -#~ msgid "%s: file \"%s\" would be removed\n" -#~ msgstr "%s: soubor \"%s\" by byl odstraněn\n" +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" diff --git a/src/bin/pg_archivecleanup/po/el.po b/src/bin/pg_archivecleanup/po/el.po new file mode 100644 index 000000000000..c400e19e7b5e --- /dev/null +++ b/src/bin/pg_archivecleanup/po/el.po @@ -0,0 +1,179 @@ +# Greek message translation file for pg_archivecleanup +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:48+0000\n" +"PO-Revision-Date: 2021-04-27 10:30+0200\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση: " + +#: pg_archivecleanup.c:66 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "η τοποθεσία της αρχειοθήκης \"%s\" δεν υπάρχει" + +#: pg_archivecleanup.c:152 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "δεν ήταν δυνατή η αφαίρεση του αρχείου \"%s\": %m" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "could not read archive location \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση της τοποθεσίας αρχειοθήκης \"%s\": %m" + +#: pg_archivecleanup.c:163 +#, c-format +msgid "could not close archive location \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο της τοποθεσίας αρχειοθήκης “%s”: %m" + +#: pg_archivecleanup.c:167 +#, c-format +msgid "could not open archive location \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα της τοποθεσίας αρχειοθήκης “%s”: %m" + +#: pg_archivecleanup.c:240 +#, c-format +msgid "invalid file name argument" +msgstr "μη έγκυρη παράμετρος ονόματος αρχείου" + +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_archivecleanup.c:254 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%s αφαιρεί παλαιότερα αρχεία WAL από αρχειοθήκες PostgreSQL.\n" +"\n" + +#: pg_archivecleanup.c:255 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_archivecleanup.c:256 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr " %s [ΕΠΙΛΟΓΗ]… ARCHIVELOCATION OLDESTKEPTWALFILE\n" + +#: pg_archivecleanup.c:257 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Επιλογές:\n" + +#: pg_archivecleanup.c:258 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d δημιουργία εξόδου αποσφαλμάτωσης (περιφραστική λειτουργία)\n" + +#: pg_archivecleanup.c:259 +#, c-format +msgid " -n dry run, show the names of the files that would be removed\n" +msgstr " -n ξηρή λειτουργία, εμφάνιση των ονομάτων των αρχείων που θα αφαιρεθούν\n" + +#: pg_archivecleanup.c:260 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης, στη συνέχεια έξοδος\n" + +#: pg_archivecleanup.c:261 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT εκκαθάριση αρχείων εάν περιέχουν αυτήν την επέκταση\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, στη συνέχεια έξοδος\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"Για χρήση ως archive_cleanup_command στο postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [ΕΠΙΛΟΓΗ]... ARCHIVELOCATION %%r’\n" +"π.χ.\n" +" archive_cleanup_command = ‘pg_archivecleanup /mnt/διακομιστής/αρχειοθήκη %%r’\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"Ή για χρήση ως αυτόνομο εκκαθαριστικό αρχειοθήκης:\n" +"π.χ.\n" +" pg_archivecleanup /mnt/server/archiverdir 0000000100000000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:272 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_archivecleanup.c:335 +#, c-format +msgid "must specify archive location" +msgstr "πρέπει να καθορίσετε τη τοποθεσία αρχειοθήκης" + +#: pg_archivecleanup.c:347 +#, c-format +msgid "must specify oldest kept WAL file" +msgstr "πρέπει να καθορίσετε το παλαιότερο κρατημένο αρχείο WAL" + +#: pg_archivecleanup.c:354 +#, c-format +msgid "too many command-line arguments" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών" diff --git a/src/bin/pg_archivecleanup/po/es.po b/src/bin/pg_archivecleanup/po/es.po new file mode 100644 index 000000000000..91289be776b4 --- /dev/null +++ b/src/bin/pg_archivecleanup/po/es.po @@ -0,0 +1,180 @@ +# Spanish message translation file for pg_archivecleanup +# Copyright (c) 2017-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Carlos Chapi , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-13 10:47+0000\n" +"PO-Revision-Date: 2020-09-12 23:13-0300\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: BlackCAT 1.0\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: pg_archivecleanup.c:66 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "ubicación de archivador «%s» no existe" + +#: pg_archivecleanup.c:152 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "no se pudo eliminar el archivo «%s»: %m" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "could not read archive location \"%s\": %m" +msgstr "no se pudo leer la ubicación del archivador «%s»: %m" + +#: pg_archivecleanup.c:163 +#, c-format +msgid "could not close archive location \"%s\": %m" +msgstr "no se pudo cerrar la ubicación del archivador «%s»: %m" + +#: pg_archivecleanup.c:167 +#, c-format +msgid "could not open archive location \"%s\": %m" +msgstr "no se pudo abrir la ubicación del archivador «%s»: %m" + +#: pg_archivecleanup.c:240 +#, c-format +msgid "invalid file name argument" +msgstr "el nombre de archivo usado como argumento no es válido" + +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_archivecleanup.c:254 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%s elimina archivos de WAL antiguos del archivador de PostgreSQL.\n" +"\n" + +#: pg_archivecleanup.c:255 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_archivecleanup.c:256 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr " %s [OPCIÓN].... UBICACIÓNARCHIVADOR WALMÁSANTIGUOAMANTENER\n" + +#: pg_archivecleanup.c:257 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Opciones:\n" + +#: pg_archivecleanup.c:258 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d genera salida de depuración (modo verboso)\n" + +#: pg_archivecleanup.c:259 +#, c-format +msgid " -n dry run, show the names of the files that would be removed\n" +msgstr " -n simulacro, muestra el nombre de los archivos que se eliminarían\n" + +#: pg_archivecleanup.c:260 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version muestra información de la versión, luego sale\n" + +#: pg_archivecleanup.c:261 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT hace limpieza de archivos que tengan esta extensión\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help muestra esta ayuda, luego sale\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"Para usar como archive_cleanup_command en postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPCIÓN]... UBICACIÓNARCHIVADOR %%r'\n" +"por ej.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/servidor/directorioarchivador %%r'\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"O para usar como un limpiador de archivador de forma independiente:\n" +"por ej.\n" +" pg_archivecleanup /mnt/servidor/directorioarchivador 000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:272 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_archivecleanup.c:335 +#, c-format +msgid "must specify archive location" +msgstr "debe especificar la ubicación del archivador" + +#: pg_archivecleanup.c:347 +#, c-format +msgid "must specify oldest kept WAL file" +msgstr "debe especificar el fichero WAL más antiguo a mantener" + +#: pg_archivecleanup.c:354 +#, c-format +msgid "too many command-line arguments" +msgstr "demasiados argumentos de línea de órdenes" diff --git a/src/bin/pg_archivecleanup/po/fr.po b/src/bin/pg_archivecleanup/po/fr.po new file mode 100644 index 000000000000..2280202a36ca --- /dev/null +++ b/src/bin/pg_archivecleanup/po/fr.po @@ -0,0 +1,201 @@ +# LANGUAGE message translation file for pg_archivecleanup +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-04-16 06:16+0000\n" +"PO-Revision-Date: 2020-04-16 13:39+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.3\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: pg_archivecleanup.c:66 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "l'emplacement d'archivage « %s » n'existe pas" + +#: pg_archivecleanup.c:152 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier « %s » : %m" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "could not read archive location \"%s\": %m" +msgstr "n'a pas pu lire l'emplacement de l'archive « %s » : %m" + +#: pg_archivecleanup.c:163 +#, c-format +msgid "could not close archive location \"%s\": %m" +msgstr "n'a pas pu fermer l'emplacement de l'archive « %s » : %m" + +#: pg_archivecleanup.c:167 +#, c-format +msgid "could not open archive location \"%s\": %m" +msgstr "n'a pas pu ouvrir l'emplacement de l'archive « %s » : %m" + +#: pg_archivecleanup.c:240 +#, c-format +msgid "invalid file name argument" +msgstr "argument du nom de fichier invalide" + +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: pg_archivecleanup.c:254 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%s supprime les anciens fichiers WAL des archives de PostgreSQL.\n" +"\n" + +#: pg_archivecleanup.c:255 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: pg_archivecleanup.c:256 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr " %s [OPTION]... EMPLACEMENTARCHIVE PLUSANCIENFICHIERWALCONSERVÉ\n" + +#: pg_archivecleanup.c:257 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Options :\n" + +#: pg_archivecleanup.c:258 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d affiche des informations de débugage (mode verbeux)\n" + +#: pg_archivecleanup.c:259 +#, c-format +msgid " -n dry run, show the names of the files that would be removed\n" +msgstr " -n test, affiche le nom des fichiers qui seraient supprimés\n" + +#: pg_archivecleanup.c:260 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version et quitte\n" + +#: pg_archivecleanup.c:261 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT nettoie les fichiers s'ils ont cette extension\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide et quitte\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"Pour utiliser comme archive_cleanup_command dans postgresql.conf :\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... EMPLACEMENTARCHIVE %%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/serveur/reparchives %%r'\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"Ou pour utiliser comme nettoyeur autonome d'archives :\n" +"e.g.\n" +" pg_archivecleanup /mnt/serveur/reparchives 000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:272 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapporter les bogues à <%s>.\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil de %s : <%s>\n" + +#: pg_archivecleanup.c:335 +#, c-format +msgid "must specify archive location" +msgstr "doit spécifier l'emplacement de l'archive" + +#: pg_archivecleanup.c:347 +#, c-format +msgid "must specify oldest kept WAL file" +msgstr "doit spécifier le plus ancien journal de transactions conservé" + +#: pg_archivecleanup.c:354 +#, c-format +msgid "too many command-line arguments" +msgstr "trop d'arguments en ligne de commande" + +#~ msgid "%s: file \"%s\" would be removed\n" +#~ msgstr "%s : le fichier « %s » serait supprimé\n" + +#~ msgid "%s: removing file \"%s\"\n" +#~ msgstr "%s : suppression du fichier « %s »\n" + +#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n" +#~ msgstr "%s : ERREUR : n'a pas pu supprimer le fichier « %s » : %s\n" + +#~ msgid "%s: keeping WAL file \"%s\" and later\n" +#~ msgstr "%s : conservation du fichier WAL « %s » et des suivants\n" + +#~ msgid "%s: too many parameters\n" +#~ msgstr "%s : trop de paramètres\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapporter les bogues à .\n" diff --git a/src/bin/pg_archivecleanup/po/ja.po b/src/bin/pg_archivecleanup/po/ja.po new file mode 100644 index 000000000000..9a5d1b277e10 --- /dev/null +++ b/src/bin/pg_archivecleanup/po/ja.po @@ -0,0 +1,190 @@ +# Japanese message translation file for pg_archivecleanup +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:54+0900\n" +"PO-Revision-Date: 2020-09-13 08:55+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: pg_archivecleanup.c:66 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "アーカイブの場所\"%s\"が存在しません" + +#: pg_archivecleanup.c:152 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "ファイル\"%s\"を削除できませんでした: %m" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "could not read archive location \"%s\": %m" +msgstr "アーカイブの場所\"%s\"を読み込めませんでした: %m" + +#: pg_archivecleanup.c:163 +#, c-format +msgid "could not close archive location \"%s\": %m" +msgstr "アーカイブの場所\"%s\"をクローズできませんでした: %m" + +#: pg_archivecleanup.c:167 +#, c-format +msgid "could not open archive location \"%s\": %m" +msgstr "アーカイブの場所\"%s\"をオープンできませんでした: %m" + +#: pg_archivecleanup.c:240 +#, c-format +msgid "invalid file name argument" +msgstr "ファイル名引数が無効です" + +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "\"%s --help\"で詳細が参照できます。\n" + +#: pg_archivecleanup.c:254 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%sはPostgreSQLのアーカイブから古いWALファイルを削除します。\n" +"\n" + +#: pg_archivecleanup.c:255 +#, c-format +msgid "Usage:\n" +msgstr "使用法:\n" + +#: pg_archivecleanup.c:256 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr "%s [オプション] ... {アーカイブの場所} {保存する最古の WAL ファイル名}\n" + +#: pg_archivecleanup.c:257 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: pg_archivecleanup.c:258 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d デバッグ情報を出力(冗長モード)\n" + +#: pg_archivecleanup.c:259 +#, c-format +msgid " -n dry run, show the names of the files that would be removed\n" +msgstr " -n リハーサル、削除対象のファイル名を表示\n" + +#: pg_archivecleanup.c:260 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を出力して終了\n" + +#: pg_archivecleanup.c:261 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT この拡張子を持つファイルを削除対象とする\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"postgresql.confでarchive_cleanup_commandとして使用する場合は以下のようにします:\n" +" archive_cleanup_command = 'pg_archivecleanup [オプション]... アーカイブの場所 %%r'\n" +"例としては:\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"もしくはスタンドアロンのアーカイブクリーナーとして使う場合は:\n" +"使用例\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:272 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_archivecleanup.c:335 +#, c-format +msgid "must specify archive location" +msgstr "アーカイブの場所を指定してください" + +#: pg_archivecleanup.c:347 +#, c-format +msgid "must specify oldest kept WAL file" +msgstr "保存する最古のWALファイルを指定してください" + +#: pg_archivecleanup.c:354 +#, c-format +msgid "too many command-line arguments" +msgstr "コマンドライン引数が多すぎます" + +#~ msgid "%s: file \"%s\" would be removed\n" +#~ msgstr "%s: ファイル \"%s\" は削除されます\n" + +#~ msgid "%s: removing file \"%s\"\n" +#~ msgstr "%s: ファイル \"%s\" を削除しています\n" + +#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n" +#~ msgstr "%s: エラー: ファイル \"%s\" を削除できませんでした: %s\n" + +#~ msgid "%s: keeping WAL file \"%s\" and later\n" +#~ msgstr "%s: WAL file \"%s\" とそれ以降の分を保存しています\n" diff --git a/src/bin/pg_archivecleanup/po/ko.po b/src/bin/pg_archivecleanup/po/ko.po new file mode 100644 index 000000000000..785839ab2fd4 --- /dev/null +++ b/src/bin/pg_archivecleanup/po/ko.po @@ -0,0 +1,184 @@ +# LANGUAGE message translation file for pg_archivecleanup +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 01:16+0000\n" +"PO-Revision-Date: 2020-10-05 17:51+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: pg_archivecleanup.c:66 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "\"%s\" 이름의 아카이브 위치가 없음" + +#: pg_archivecleanup.c:152 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "\"%s\" 파일을 삭제할 수 없음: %m" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "could not read archive location \"%s\": %m" +msgstr "\"%s\" 아카이브 위치를 읽을 수 없음: %m" + +#: pg_archivecleanup.c:163 +#, c-format +msgid "could not close archive location \"%s\": %m" +msgstr "\"%s\" 아카이브 위치를 닫을 수 없음: %m" + +#: pg_archivecleanup.c:167 +#, c-format +msgid "could not open archive location \"%s\": %m" +msgstr "\"%s\" 아카이브 위치를 열 수 없음: %m" + +#: pg_archivecleanup.c:240 +#, c-format +msgid "invalid file name argument" +msgstr "잘못된 파일 이름 매개변수" + +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 자세한 정보는 \"%s --help\" 명령을 참조하세요.\n" + +#: pg_archivecleanup.c:254 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%s 명령은 PostgreSQL 아카이브 보관소에서 오래된\n" +"WAL 파일을 지웁니다.\n" +"\n" + +#: pg_archivecleanup.c:255 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_archivecleanup.c:256 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr " %s [옵션]... 아카이브위치 보관할제일오래된파일\n" + +#: pg_archivecleanup.c:257 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"옵션들:\n" + +#: pg_archivecleanup.c:258 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d 보다 자세한 작업 내용 출력\n" + +#: pg_archivecleanup.c:259 +#, c-format +msgid "" +" -n dry run, show the names of the files that would be removed\n" +msgstr " -n 지울 대상만 확인하고 지우지는 않음\n" + +#: pg_archivecleanup.c:260 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: pg_archivecleanup.c:261 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT 해당 확장자 파일들을 작업 대상으로 함\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 도움말을 보여주고 마침\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION " +"%%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"postgresql.conf 파일에서 archive_cleanup_command 설정 방법:\n" +" archive_cleanup_command = 'pg_archivecleanup [옵션]... 아카이브위치 %%r'\n" +"사용예:\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"또는 명령행에서 독립적으로 사용하는 경우:\n" +"사용예:\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:272 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"문제점 보고 주소: <%s>\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: pg_archivecleanup.c:335 +#, c-format +msgid "must specify archive location" +msgstr "아카이브 위치는 지정해야 함" + +#: pg_archivecleanup.c:347 +#, c-format +msgid "must specify oldest kept WAL file" +msgstr "남길 가장 오래된 WAL 파일은 지정해야 함" + +#: pg_archivecleanup.c:354 +#, c-format +msgid "too many command-line arguments" +msgstr "너무 많은 명령행 인자를 지정했음" diff --git a/src/bin/pg_archivecleanup/po/ru.po b/src/bin/pg_archivecleanup/po/ru.po new file mode 100644 index 000000000000..ec22c128e841 --- /dev/null +++ b/src/bin/pg_archivecleanup/po/ru.po @@ -0,0 +1,204 @@ +# Russian message translation file for pg_archivecleanup +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Alexander Lakhin , 2017, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2020-09-03 12:40+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: pg_archivecleanup.c:66 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "расположение архива \"%s\" не существует" + +#: pg_archivecleanup.c:152 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "не удалось стереть файл \"%s\": %m" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "could not read archive location \"%s\": %m" +msgstr "не удалось прочитать расположение архива \"%s\": %m" + +#: pg_archivecleanup.c:163 +#, c-format +msgid "could not close archive location \"%s\": %m" +msgstr "не удалось закрыть расположение архива \"%s\": %m" + +#: pg_archivecleanup.c:167 +#, c-format +msgid "could not open archive location \"%s\": %m" +msgstr "не удалось открыть расположение архива \"%s\": %m" + +#: pg_archivecleanup.c:240 +#, c-format +msgid "invalid file name argument" +msgstr "неверный аргумент с именем файла" + +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_archivecleanup.c:254 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%s удаляет старые файлы WAL из архивов PostgreSQL.\n" +"\n" + +#: pg_archivecleanup.c:255 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: pg_archivecleanup.c:256 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr "" +" %s [ПАРАМЕТР]... РАСПОЛОЖЕНИЕ_АРХИВА СТАРЕЙШИЙ_СОХРАНЯЕМЫЙ_ФАЙЛ_WAL\n" + +#: pg_archivecleanup.c:257 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Параметры:\n" + +#: pg_archivecleanup.c:258 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d генерировать подробные сообщения (отладочный режим)\n" + +#: pg_archivecleanup.c:259 +#, c-format +msgid "" +" -n dry run, show the names of the files that would be removed\n" +msgstr "" +" -n холостой запуск, только показать имена файлов, которые " +"будут удалены\n" + +#: pg_archivecleanup.c:260 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +# well-spelled: РСШ +#: pg_archivecleanup.c:261 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x РСШ убрать файлы с заданным расширением\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION " +"%%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"Для использования в качестве archive_cleanup_command в postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [ПАРАМЕТР]... " +"РАСПОЛОЖЕНИЕ_АРХИВА %%r'\n" +"например:\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"Либо для использования в качестве отдельного средства очистки архива,\n" +"например:\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:272 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_archivecleanup.c:335 +#, c-format +msgid "must specify archive location" +msgstr "необходимо задать расположение архива" + +#: pg_archivecleanup.c:347 +#, c-format +msgid "must specify oldest kept WAL file" +msgstr "необходимо задать имя старейшего сохраняемого файла WAL" + +#: pg_archivecleanup.c:354 +#, c-format +msgid "too many command-line arguments" +msgstr "слишком много аргументов командной строки" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid "%s: file \"%s\" would be removed\n" +#~ msgstr "%s: файл \"%s\" не будет удалён\n" + +#~ msgid "%s: removing file \"%s\"\n" +#~ msgstr "%s: удаление файла \"%s\"\n" + +#~ msgid "%s: keeping WAL file \"%s\" and later\n" +#~ msgstr "%s: будет сохранён файл WAL \"%s\" и последующие\n" diff --git a/src/bin/pg_archivecleanup/po/uk.po b/src/bin/pg_archivecleanup/po/uk.po index 61b792b79159..3458cea869d9 100644 --- a/src/bin/pg_archivecleanup/po/uk.po +++ b/src/bin/pg_archivecleanup/po/uk.po @@ -2,118 +2,120 @@ msgid "" msgstr "" "Project-Id-Version: postgresql\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-08 14:46+0000\n" -"PO-Revision-Date: 2019-12-20 20:23\n" +"POT-Creation-Date: 2020-09-21 21:17+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" "Last-Translator: pasha_golub\n" "Language-Team: Ukrainian\n" -"Language: uk_UA\n" +"Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" "X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" "X-Crowdin-Language: uk\n" -"X-Crowdin-File: /REL_12_STABLE/pg_archivecleanup.pot\n" +"X-Crowdin-File: /DEV_13/pg_archivecleanup.pot\n" +"X-Crowdin-File-ID: 488\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "збій: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "помилка: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "попередження: " -#: pg_archivecleanup.c:68 +#: pg_archivecleanup.c:66 #, c-format msgid "archive location \"%s\" does not exist" msgstr "архівного розташування \"%s\" не існує" -#: pg_archivecleanup.c:154 +#: pg_archivecleanup.c:152 #, c-format msgid "could not remove file \"%s\": %m" msgstr "не можливо видалити файл \"%s\": %m" -#: pg_archivecleanup.c:162 +#: pg_archivecleanup.c:160 #, c-format msgid "could not read archive location \"%s\": %m" msgstr "не вдалося прочитати архівне розташування \"%s\":%m" -#: pg_archivecleanup.c:165 +#: pg_archivecleanup.c:163 #, c-format msgid "could not close archive location \"%s\": %m" msgstr "не вдалося закрити архівне розташування \"%s\":%m" -#: pg_archivecleanup.c:169 +#: pg_archivecleanup.c:167 #, c-format msgid "could not open archive location \"%s\": %m" msgstr "не вдалося відкрити архівне розташування \"%s\":%m" -#: pg_archivecleanup.c:242 +#: pg_archivecleanup.c:240 #, c-format msgid "invalid file name argument" msgstr "недійсна назва файла з аргументом" -#: pg_archivecleanup.c:243 pg_archivecleanup.c:316 pg_archivecleanup.c:337 -#: pg_archivecleanup.c:349 pg_archivecleanup.c:356 +#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" -#: pg_archivecleanup.c:256 +#: pg_archivecleanup.c:254 #, c-format msgid "%s removes older WAL files from PostgreSQL archives.\n\n" msgstr "%s видаляє старі WAL-файли з архівів PostgreSQL.\n\n" -#: pg_archivecleanup.c:257 +#: pg_archivecleanup.c:255 #, c-format msgid "Usage:\n" msgstr "Використання:\n" -#: pg_archivecleanup.c:258 +#: pg_archivecleanup.c:256 #, c-format msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" msgstr " %s [OPTION]... РОЗТАШУВАННЯ_АРХІВА НАЙДАВНІШИЙ_ЗБЕРЕЖЕНИЙ_WAL_ФАЙЛ\n" -#: pg_archivecleanup.c:259 +#: pg_archivecleanup.c:257 #, c-format msgid "\n" "Options:\n" msgstr "\n" "Параметри:\n" -#: pg_archivecleanup.c:260 +#: pg_archivecleanup.c:258 #, c-format msgid " -d generate debug output (verbose mode)\n" msgstr " -d генерує налагоджувальні повідомлення (детальний режим)\n" -#: pg_archivecleanup.c:261 +#: pg_archivecleanup.c:259 #, c-format msgid " -n dry run, show the names of the files that would be removed\n" msgstr " -n сухий запуск, показує тільки ті файли, які будуть видалені\n" -#: pg_archivecleanup.c:262 +#: pg_archivecleanup.c:260 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показати версію, потім вийти\n" -#: pg_archivecleanup.c:263 +#: pg_archivecleanup.c:261 #, c-format msgid " -x EXT clean up files if they have this extension\n" msgstr " -x EXT прибрати файли з цим розширенням\n" -#: pg_archivecleanup.c:264 +#: pg_archivecleanup.c:262 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показати цю довідку, потім вийти\n" -#: pg_archivecleanup.c:265 +#: pg_archivecleanup.c:263 #, c-format msgid "\n" "For use as archive_cleanup_command in postgresql.conf:\n" @@ -126,7 +128,7 @@ msgstr "\n" "напр.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" -#: pg_archivecleanup.c:270 +#: pg_archivecleanup.c:268 #, c-format msgid "\n" "Or for use as a standalone archive cleaner:\n" @@ -137,25 +139,37 @@ msgstr "\n" "наприклад:\n" " pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" -#: pg_archivecleanup.c:274 +#: pg_archivecleanup.c:272 #, c-format msgid "\n" -"Report bugs to .\n" +"Report bugs to <%s>.\n" msgstr "\n" -"Про помилки повідомляйте на .\n" +"Повідомляти про помилки на <%s>.\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" -#: pg_archivecleanup.c:336 +#: pg_archivecleanup.c:335 #, c-format msgid "must specify archive location" msgstr "необхідно вказати розташування архіва" -#: pg_archivecleanup.c:348 +#: pg_archivecleanup.c:347 #, c-format msgid "must specify oldest kept WAL file" msgstr "необхідно вказати найдавніший збережений WAL-файл" -#: pg_archivecleanup.c:355 +#: pg_archivecleanup.c:354 #, c-format msgid "too many command-line arguments" msgstr "занадто багато аргументів командного рядка" +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Про помилки повідомляйте на .\n" + diff --git a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl index 22782d304207..8134c2a62e81 100644 --- a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl +++ b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pg_basebackup/Makefile b/src/bin/pg_basebackup/Makefile index 2ca5bf204a0c..932c880e5aeb 100644 --- a/src/bin/pg_basebackup/Makefile +++ b/src/bin/pg_basebackup/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_basebackup # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/pg_basebackup/Makefile @@ -18,6 +18,9 @@ subdir = src/bin/pg_basebackup top_builddir = ../../.. include $(top_builddir)/src/Makefile.global +# make this available to TAP test scripts +export TAR + override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) diff --git a/src/bin/pg_basebackup/nls.mk b/src/bin/pg_basebackup/nls.mk index 1eae6f242302..2d521f068347 100644 --- a/src/bin/pg_basebackup/nls.mk +++ b/src/bin/pg_basebackup/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_basebackup/nls.mk CATALOG_NAME = pg_basebackup -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr vi zh_CN +AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr uk vi zh_CN GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_basebackup.c pg_receivewal.c pg_recvlogical.c receivelog.c streamutil.c walmethods.c ../../common/fe_memutils.c ../../common/file_utils.c ../../fe_utils/recovery_gen.c GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) simple_prompt tar_set_error GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 2c26cd248a28..1253fa744966 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -4,7 +4,7 @@ * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/pg_basebackup.c diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c index cd05f5fede18..0d15012c295f 100644 --- a/src/bin/pg_basebackup/pg_receivewal.c +++ b/src/bin/pg_basebackup/pg_receivewal.c @@ -5,7 +5,7 @@ * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/pg_receivewal.c @@ -115,14 +115,14 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished) /* we assume that we get called once at the end of each segment */ if (verbose && segment_finished) pg_log_info("finished segment at %X/%X (timeline %u)", - (uint32) (xlogpos >> 32), (uint32) xlogpos, + LSN_FORMAT_ARGS(xlogpos), timeline); if (!XLogRecPtrIsInvalid(endpos) && endpos < xlogpos) { if (verbose) pg_log_info("stopped log streaming at %X/%X (timeline %u)", - (uint32) (xlogpos >> 32), (uint32) xlogpos, + LSN_FORMAT_ARGS(xlogpos), timeline); time_to_stop = true; return true; @@ -139,7 +139,7 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished) if (verbose && prevtimeline != 0 && prevtimeline != timeline) pg_log_info("switched to timeline %u at %X/%X", timeline, - (uint32) (prevpos >> 32), (uint32) prevpos); + LSN_FORMAT_ARGS(prevpos)); prevtimeline = timeline; prevpos = xlogpos; @@ -269,8 +269,8 @@ FindStreamingStart(uint32 *tli) if (statbuf.st_size != WalSegSz) { - pg_log_warning("segment file \"%s\" has incorrect size %d, skipping", - dirent->d_name, (int) statbuf.st_size); + pg_log_warning("segment file \"%s\" has incorrect size %lld, skipping", + dirent->d_name, (long long int) statbuf.st_size); continue; } } @@ -420,7 +420,7 @@ StreamLog(void) */ if (verbose) pg_log_info("starting log streaming at %X/%X (timeline %u)", - (uint32) (stream.startpos >> 32), (uint32) stream.startpos, + LSN_FORMAT_ARGS(stream.startpos), stream.timeline); stream.stream_stop = stop_streaming; diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c index a4e0d6aeb29c..5efec160e884 100644 --- a/src/bin/pg_basebackup/pg_recvlogical.c +++ b/src/bin/pg_basebackup/pg_recvlogical.c @@ -3,7 +3,7 @@ * pg_recvlogical.c - receive data from a logical decoding slot in a streaming * fashion and write it to a local file. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/pg_recvlogical.c @@ -131,8 +131,8 @@ sendFeedback(PGconn *conn, TimestampTz now, bool force, bool replyRequested) if (verbose) pg_log_info("confirming write up to %X/%X, flush to %X/%X (slot %s)", - (uint32) (output_written_lsn >> 32), (uint32) output_written_lsn, - (uint32) (output_fsync_lsn >> 32), (uint32) output_fsync_lsn, + LSN_FORMAT_ARGS(output_written_lsn), + LSN_FORMAT_ARGS(output_fsync_lsn), replication_slot); replybuf[len] = 'r'; @@ -228,12 +228,12 @@ StreamLogicalLog(void) */ if (verbose) pg_log_info("starting log streaming at %X/%X (slot %s)", - (uint32) (startpos >> 32), (uint32) startpos, + LSN_FORMAT_ARGS(startpos), replication_slot); /* Initiate the replication stream at specified location */ appendPQExpBuffer(query, "START_REPLICATION SLOT \"%s\" LOGICAL %X/%X", - replication_slot, (uint32) (startpos >> 32), (uint32) startpos); + replication_slot, LSN_FORMAT_ARGS(startpos)); /* print options if there are any */ if (noptions) @@ -411,7 +411,7 @@ StreamLogicalLog(void) } else if (r < 0) { - pg_log_error("select() failed: %m"); + pg_log_error("%s() failed: %m", "select"); goto error; } @@ -1045,10 +1045,9 @@ prepareToTerminate(PGconn *conn, XLogRecPtr endpos, bool keepalive, XLogRecPtr l { if (keepalive) pg_log_info("end position %X/%X reached by keepalive", - (uint32) (endpos >> 32), (uint32) endpos); + LSN_FORMAT_ARGS(endpos)); else pg_log_info("end position %X/%X reached by WAL record at %X/%X", - (uint32) (endpos >> 32), (uint32) (endpos), - (uint32) (lsn >> 32), (uint32) lsn); + LSN_FORMAT_ARGS(endpos), LSN_FORMAT_ARGS(lsn)); } } diff --git a/src/bin/pg_basebackup/po/cs.po b/src/bin/pg_basebackup/po/cs.po index 043f6a90b542..f74b659741b5 100644 --- a/src/bin/pg_basebackup/po/cs.po +++ b/src/bin/pg_basebackup/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_basebackup-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-27 08:13+0000\n" -"PO-Revision-Date: 2019-09-27 17:10+0200\n" +"POT-Creation-Date: 2020-10-31 16:15+0000\n" +"PO-Revision-Date: 2020-10-31 21:35+0100\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -16,148 +16,167 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 2.4.1\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "fatal: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "chyba: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "varování: " #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 #, c-format msgid "out of memory\n" msgstr "nedostatek paměti\n" -#: ../../common/fe_memutils.c:92 +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "nelze duplikovat null pointer (interní chyba)\n" -#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 -#: pg_receivewal.c:267 pg_recvlogical.c:342 +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 +#: pg_receivewal.c:266 pg_recvlogical.c:340 #, c-format msgid "could not stat file \"%s\": %m" msgstr "nelze přistoupit k souboru \"%s\": %m" -#: ../../common/file_utils.c:160 pg_receivewal.c:170 +#: ../../common/file_utils.c:158 pg_receivewal.c:169 #, c-format msgid "could not open directory \"%s\": %m" msgstr "nelze otevřít adresář \"%s\": %m" -#: ../../common/file_utils.c:194 pg_receivewal.c:338 +#: ../../common/file_utils.c:192 pg_receivewal.c:337 #, c-format msgid "could not read directory \"%s\": %m" msgstr "nelze číst z adresáře \"%s\": %m" -#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 -#: ../../common/file_utils.c:359 pg_basebackup.c:1760 +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 ../../fe_utils/recovery_gen.c:134 #, c-format msgid "could not open file \"%s\": %m" msgstr "nelze otevřít soubor \"%s\": %m" -#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 -#: pg_recvlogical.c:195 +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 +#: pg_recvlogical.c:193 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "nelze provést fsync souboru \"%s\": %m" -#: ../../common/file_utils.c:377 +#: ../../common/file_utils.c:375 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "nelze přejmenovat soubor \"%s\" na \"%s\": %m" -#: pg_basebackup.c:171 +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "nedostatek paměti" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "nelze zapsat do souboru \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "nelze vytvořit soubor \"%s\": %m" + +#: pg_basebackup.c:224 #, c-format msgid "removing data directory \"%s\"" msgstr "odstraňuji datový adresář \"%s\"" -#: pg_basebackup.c:173 +#: pg_basebackup.c:226 #, c-format msgid "failed to remove data directory" msgstr "selhalo odstranění datového adresáře" -#: pg_basebackup.c:177 +#: pg_basebackup.c:230 #, c-format msgid "removing contents of data directory \"%s\"" msgstr "odstraňuji obsah datového adresáře \"%s\"" -#: pg_basebackup.c:179 +#: pg_basebackup.c:232 #, c-format msgid "failed to remove contents of data directory" msgstr "selhalo odstranění obsahu datového adresáře" -#: pg_basebackup.c:184 +#: pg_basebackup.c:237 #, c-format msgid "removing WAL directory \"%s\"" msgstr "odstraňuji WAL adresář \"%s\"" -#: pg_basebackup.c:186 +#: pg_basebackup.c:239 #, c-format msgid "failed to remove WAL directory" msgstr "selhalo odstranění WAL adresáře" -#: pg_basebackup.c:190 +#: pg_basebackup.c:243 #, c-format msgid "removing contents of WAL directory \"%s\"" msgstr "odstraňuji obsah WAL adresáře \"%s\"" -#: pg_basebackup.c:192 +#: pg_basebackup.c:245 #, c-format msgid "failed to remove contents of WAL directory" msgstr "selhalo odstranění obsahu WAL adresáře" -#: pg_basebackup.c:198 +#: pg_basebackup.c:251 #, c-format msgid "data directory \"%s\" not removed at user's request" msgstr "datový adresář \"%s\" nebyl na žádost uživatele odstraněn" -#: pg_basebackup.c:201 +#: pg_basebackup.c:254 #, c-format msgid "WAL directory \"%s\" not removed at user's request" msgstr "WAL adresář \"%s\" nebyl na žádost uživatele odstraněn" -#: pg_basebackup.c:205 +#: pg_basebackup.c:258 #, c-format msgid "changes to tablespace directories will not be undone" msgstr "změny v tablespace adresářích nebudou vráceny zpět" -#: pg_basebackup.c:246 +#: pg_basebackup.c:299 #, c-format msgid "directory name too long" msgstr "jméno adresáře je příliš dlouhé" -#: pg_basebackup.c:256 +#: pg_basebackup.c:309 #, c-format msgid "multiple \"=\" signs in tablespace mapping" msgstr "více \"=\" znaků v tablespace mapování" -#: pg_basebackup.c:268 +#: pg_basebackup.c:321 #, c-format msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" msgstr "chybný formát tablespace mapování \"%s\", musí být \"OLDDIR=NEWDIR\"" -#: pg_basebackup.c:280 +#: pg_basebackup.c:333 #, c-format msgid "old directory is not an absolute path in tablespace mapping: %s" msgstr "starý adresář v tablespace mapování není zadán jako absolutní cesta: %s" -#: pg_basebackup.c:287 +#: pg_basebackup.c:340 #, c-format msgid "new directory is not an absolute path in tablespace mapping: %s" msgstr "nový adresář v tablespace mapování není zadán jako absolutní cesta: %s" -#: pg_basebackup.c:326 +#: pg_basebackup.c:379 #, c-format msgid "" "%s takes a base backup of a running PostgreSQL server.\n" @@ -166,17 +185,17 @@ msgstr "" "%s vytvoří base backup běžícího PostgreSQL serveru.\n" "\n" -#: pg_basebackup.c:328 pg_receivewal.c:81 pg_recvlogical.c:78 +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 #, c-format msgid "Usage:\n" msgstr "Použití:\n" -#: pg_basebackup.c:329 pg_receivewal.c:82 pg_recvlogical.c:79 +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [VOLBA]...\n" -#: pg_basebackup.c:330 +#: pg_basebackup.c:383 #, c-format msgid "" "\n" @@ -185,17 +204,17 @@ msgstr "" "\n" "Volby ovlivňující výstup:\n" -#: pg_basebackup.c:331 +#: pg_basebackup.c:384 #, c-format msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" msgstr " -D, --pgdata=ADRESÁŘ ulož base backup do adresáře\n" -#: pg_basebackup.c:332 +#: pg_basebackup.c:385 #, c-format msgid " -F, --format=p|t output format (plain (default), tar)\n" msgstr " -F, --format=p|t výstupní formát (plain (výchozí), tar)\n" -#: pg_basebackup.c:333 +#: pg_basebackup.c:386 #, c-format msgid "" " -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" @@ -204,7 +223,7 @@ msgstr "" " -r, --max-rate=RATE maximální rychlost pro přenos datového adresáře\n" " (v kB/s, nebo použijte příponu \"k\" nebo \"M\")\n" -#: pg_basebackup.c:335 +#: pg_basebackup.c:388 #, c-format msgid "" " -R, --write-recovery-conf\n" @@ -213,7 +232,7 @@ msgstr "" " -R, --write-recovery-conf\n" " zapíše konfiguraci pro replikaci\n" -#: pg_basebackup.c:337 +#: pg_basebackup.c:390 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" @@ -222,12 +241,12 @@ msgstr "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" " přemístit tablespace z OLDDIR do NEWDIR\n" -#: pg_basebackup.c:339 +#: pg_basebackup.c:392 #, c-format msgid " --waldir=WALDIR location for the write-ahead log directory\n" msgstr " --waldir=WALDIR umístění adresáře s transakčním logem\n" -#: pg_basebackup.c:340 +#: pg_basebackup.c:393 #, c-format msgid "" " -X, --wal-method=none|fetch|stream\n" @@ -236,17 +255,17 @@ msgstr "" " -X, --wal-method=none|fetch|stream\n" " zahrne potřebné WAL soubory zvolenou metodou\n" -#: pg_basebackup.c:342 +#: pg_basebackup.c:395 #, c-format msgid " -z, --gzip compress tar output\n" msgstr " -z, --gzip komprimuj výstup taru\n" -#: pg_basebackup.c:343 +#: pg_basebackup.c:396 #, c-format msgid " -Z, --compress=0-9 compress tar output with given compression level\n" msgstr " -Z, --compress=0-9 komprimuj výstup taru zvolenou úrovní komprese\n" -#: pg_basebackup.c:344 +#: pg_basebackup.c:397 #, c-format msgid "" "\n" @@ -255,7 +274,7 @@ msgstr "" "\n" "Obecné volby:\n" -#: pg_basebackup.c:345 +#: pg_basebackup.c:398 #, c-format msgid "" " -c, --checkpoint=fast|spread\n" @@ -264,52 +283,84 @@ msgstr "" " -c, --checkpoint=fast|spread\n" " nastav fast nebo spread checkpointing\n" -#: pg_basebackup.c:347 +#: pg_basebackup.c:400 #, c-format msgid " -C, --create-slot create replication slot\n" msgstr " -C, --create-slot vytvoř replikační slot\n" -#: pg_basebackup.c:348 +#: pg_basebackup.c:401 #, c-format msgid " -l, --label=LABEL set backup label\n" msgstr " -l, --label=NÁZEV nastav jmenovku zálohy\n" -#: pg_basebackup.c:349 +#: pg_basebackup.c:402 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean neuklízet po chybě\n" -#: pg_basebackup.c:350 +#: pg_basebackup.c:403 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync nečekat na bezpečné zapsání změn na disk\n" -#: pg_basebackup.c:351 +#: pg_basebackup.c:404 #, c-format msgid " -P, --progress show progress information\n" msgstr " -P, --progress zobrazuj informace o průběhu\n" -#: pg_basebackup.c:352 pg_receivewal.c:91 +#: pg_basebackup.c:405 pg_receivewal.c:89 #, c-format msgid " -S, --slot=SLOTNAME replication slot to use\n" msgstr " -S, --slot=SLOTNAME použít tento replikační slot\n" -#: pg_basebackup.c:353 pg_receivewal.c:93 pg_recvlogical.c:99 +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 #, c-format msgid " -v, --verbose output verbose messages\n" msgstr " -v, --verbose zobrazuj podrobnější zprávy\n" -#: pg_basebackup.c:354 pg_receivewal.c:94 pg_recvlogical.c:100 +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version vypiš informace o verzi, potom skonči\n" -#: pg_basebackup.c:355 +#: pg_basebackup.c:408 +#, c-format +msgid "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" použij algoritmus pro kontrolní součet manifestu\n" + +#: pg_basebackup.c:410 +#, c-format +#| msgid "" +#| " --no-verify-checksums\n" +#| " do not verify checksums\n" +msgid "" +" --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr "" +" --manifest-force-encode\n" +" všechna jména souborů v manifestu kóduj pomocí hex\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr " --no-estimate-size neodhaduj velikost backupu na straně serveru\n" + +#: pg_basebackup.c:413 +#, c-format +#| msgid " --no-slot prevent creation of temporary replication slot\n" +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr " --no-manifest zamezí vytvoření backup manifestu\n" + +#: pg_basebackup.c:414 #, c-format msgid " --no-slot prevent creation of temporary replication slot\n" msgstr " --no-slot zamezí vytvoření dočasného replikačního slotu\n" -#: pg_basebackup.c:356 +#: pg_basebackup.c:415 #, c-format msgid "" " --no-verify-checksums\n" @@ -318,12 +369,12 @@ msgstr "" " --no-verify-checksums\n" " neověřovat kontrolní součty\n" -#: pg_basebackup.c:358 pg_receivewal.c:96 pg_recvlogical.c:101 +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ukaž tuto nápovědu, potom skonči\n" -#: pg_basebackup.c:359 pg_receivewal.c:97 pg_recvlogical.c:102 +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 #, c-format msgid "" "\n" @@ -332,22 +383,22 @@ msgstr "" "\n" "Volby spojení:\n" -#: pg_basebackup.c:360 pg_receivewal.c:98 +#: pg_basebackup.c:419 pg_receivewal.c:96 #, c-format msgid " -d, --dbname=CONNSTR connection string\n" msgstr " -d, --dbname=CONNSTR connection string\n" -#: pg_basebackup.c:361 pg_receivewal.c:99 pg_recvlogical.c:104 +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME host databázového serveru nebo adresář se sockety\n" -#: pg_basebackup.c:362 pg_receivewal.c:100 pg_recvlogical.c:105 +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT port databázového serveru\n" -#: pg_basebackup.c:363 +#: pg_basebackup.c:422 #, c-format msgid "" " -s, --status-interval=INTERVAL\n" @@ -356,87 +407,92 @@ msgstr "" " -s, --status-interval=INTERVAL\n" " čas mezi zasíláním packetů se stavem na server (ve vteřinách)\n" -#: pg_basebackup.c:365 pg_receivewal.c:101 pg_recvlogical.c:106 +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=JMÉNO připoj se jako uvedený databázový uživatel\n" -#: pg_basebackup.c:366 pg_receivewal.c:102 pg_recvlogical.c:107 +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password nikdy se neptej na heslo\n" -#: pg_basebackup.c:367 pg_receivewal.c:103 pg_recvlogical.c:108 +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password vynuť dotaz na heslo (mělo by se dít automaticky)\n" -#: pg_basebackup.c:368 pg_receivewal.c:107 pg_recvlogical.c:109 +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to <%s>.\n" msgstr "" "\n" -"Chyby hlaste na adresu .\n" +"Chyby hlašte na <%s>.\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" -#: pg_basebackup.c:411 +#: pg_basebackup.c:471 #, c-format msgid "could not read from ready pipe: %m" msgstr "nelze číst z ready roury: %m" -#: pg_basebackup.c:417 pg_basebackup.c:548 pg_basebackup.c:2098 +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 #: streamutil.c:450 #, c-format msgid "could not parse write-ahead log location \"%s\"" msgstr "nelze naparsovat pozici v transakčním logu \"%s\"" -#: pg_basebackup.c:513 pg_receivewal.c:442 +#: pg_basebackup.c:573 pg_receivewal.c:441 #, c-format msgid "could not finish writing WAL files: %m" msgstr "nelze dokončit zápis WAL souborů: %m" -#: pg_basebackup.c:560 +#: pg_basebackup.c:620 #, c-format msgid "could not create pipe for background process: %m" msgstr "nelze vytvořit roury pro background procesy: %m" -#: pg_basebackup.c:595 +#: pg_basebackup.c:655 #, c-format msgid "created temporary replication slot \"%s\"" msgstr "vytvořen dočasný replikační slot \"%s\"" -#: pg_basebackup.c:598 +#: pg_basebackup.c:658 #, c-format msgid "created replication slot \"%s\"" msgstr "vytvořen replikační slot \"%s\"" -#: pg_basebackup.c:618 pg_basebackup.c:671 pg_basebackup.c:1507 +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 #, c-format msgid "could not create directory \"%s\": %m" msgstr "nelze vytvořit adresář \"%s\": %m" -#: pg_basebackup.c:636 +#: pg_basebackup.c:696 #, c-format msgid "could not create background process: %m" msgstr "nelze vytvořit background procesy: %m" -#: pg_basebackup.c:648 +#: pg_basebackup.c:708 #, c-format msgid "could not create background thread: %m" msgstr "nelze vytvořit background vlákno: %m" -#: pg_basebackup.c:692 +#: pg_basebackup.c:752 #, c-format msgid "directory \"%s\" exists but is not empty" msgstr "adresář \"%s\" existuje, ale není prázdný" -#: pg_basebackup.c:699 +#: pg_basebackup.c:759 #, c-format msgid "could not access directory \"%s\": %m" msgstr "nelze přístoupit k adresáři \"%s\": %m" -#: pg_basebackup.c:760 +#: pg_basebackup.c:824 #, c-format msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" @@ -444,7 +500,7 @@ msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s" msgstr[1] "%*s/%s kB (100%%), %d/%d tablespacy %*s" msgstr[2] "%*s/%s kB (100%%), %d/%d tablespacy %*s" -#: pg_basebackup.c:772 +#: pg_basebackup.c:836 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" @@ -452,7 +508,7 @@ msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgstr[2] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" -#: pg_basebackup.c:788 +#: pg_basebackup.c:852 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" @@ -460,360 +516,378 @@ msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace" msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespaces" msgstr[2] "%*s/%s kB (%d%%), %d/%d tablespaces" -#: pg_basebackup.c:812 +#: pg_basebackup.c:877 #, c-format msgid "transfer rate \"%s\" is not a valid value" msgstr "přenosová rychlost \"%s\" není platná hodnota" -#: pg_basebackup.c:817 +#: pg_basebackup.c:882 #, c-format msgid "invalid transfer rate \"%s\": %m" msgstr "chybná přenosová rychlost \"%s\": %m" -#: pg_basebackup.c:826 +#: pg_basebackup.c:891 #, c-format msgid "transfer rate must be greater than zero" msgstr "přenosová rychlost musí být větší než nula" -#: pg_basebackup.c:858 +#: pg_basebackup.c:923 #, c-format msgid "invalid --max-rate unit: \"%s\"" msgstr "neplatná --max-rate jednotka: \"%s\"" -#: pg_basebackup.c:865 +#: pg_basebackup.c:930 #, c-format msgid "transfer rate \"%s\" exceeds integer range" msgstr "přenosová rychlost \"%s\" přečkračuje rozsah typu integer" -#: pg_basebackup.c:875 +#: pg_basebackup.c:940 #, c-format msgid "transfer rate \"%s\" is out of range" msgstr "přenosová rychlost \"%s\" je mimo rozsah" -#: pg_basebackup.c:897 +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "nelze získat COPY data stream: %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:965 +#, c-format +msgid "could not read COPY data: %s" +msgstr "nelze číst COPY data: %s" + +#: pg_basebackup.c:1007 #, c-format msgid "could not write to compressed file \"%s\": %s" msgstr "nelze zapsat do komprimovaného souboru \"%s\": %s" -#: pg_basebackup.c:907 pg_basebackup.c:1596 pg_basebackup.c:1766 +#: pg_basebackup.c:1071 #, c-format -msgid "could not write to file \"%s\": %m" -msgstr "nelze zapsat do souboru \"%s\": %m" +msgid "could not duplicate stdout: %m" +msgstr "nelze duplikovat stdout: %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "nelze otevřít výstupní soubor: %m" -#: pg_basebackup.c:972 pg_basebackup.c:992 pg_basebackup.c:1019 +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 #, c-format msgid "could not set compression level %d: %s" msgstr "nelze nastavit úroveň komprese %d: %s" -#: pg_basebackup.c:1039 +#: pg_basebackup.c:1155 #, c-format msgid "could not create compressed file \"%s\": %s" msgstr "nelze vytvořit komprimovaný soubor \"%s\": %s" -#: pg_basebackup.c:1050 pg_basebackup.c:1557 pg_basebackup.c:1778 -#, c-format -msgid "could not create file \"%s\": %m" -msgstr "nelze vytvořit soubor \"%s\": %m" - -#: pg_basebackup.c:1061 pg_basebackup.c:1416 -#, c-format -msgid "could not get COPY data stream: %s" -msgstr "nelze získat COPY data stream: %s" - -#: pg_basebackup.c:1146 +#: pg_basebackup.c:1267 #, c-format msgid "could not close compressed file \"%s\": %s" msgstr "nelze uzavřít komprimovaný soubor \"%s\": %s" -#: pg_basebackup.c:1158 pg_recvlogical.c:608 +#: pg_basebackup.c:1279 pg_recvlogical.c:632 #, c-format msgid "could not close file \"%s\": %m" msgstr "nelze uzavřít soubor \"%s\": %m" -#: pg_basebackup.c:1169 pg_basebackup.c:1445 pg_recvlogical.c:437 -#: receivelog.c:968 +#: pg_basebackup.c:1541 #, c-format -msgid "could not read COPY data: %s" -msgstr "nelze číst COPY data: %s" +msgid "COPY stream ended before last file was finished" +msgstr "COPY stream skončil před dokončením posledního souboru" -#: pg_basebackup.c:1459 +#: pg_basebackup.c:1570 #, c-format -msgid "invalid tar block header size: %d" -msgstr "neplatná velikost hlavičky tar bloku: %d" +msgid "invalid tar block header size: %zu" +msgstr "neplatná velikost hlavičky tar bloku: %zu" -#: pg_basebackup.c:1514 +#: pg_basebackup.c:1627 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "nelze nastavit přístupová práva na adresáři \"%s\": %m" -#: pg_basebackup.c:1537 +#: pg_basebackup.c:1651 #, c-format msgid "could not create symbolic link from \"%s\" to \"%s\": %m" msgstr "nelze vytvořit symbolický odkaz z \"%s\" na \"%s\": %m" -#: pg_basebackup.c:1544 +#: pg_basebackup.c:1658 #, c-format msgid "unrecognized link indicator \"%c\"" msgstr "nerozpoznaný indikátor odkazu \"%c\"" -#: pg_basebackup.c:1563 +#: pg_basebackup.c:1677 #, c-format msgid "could not set permissions on file \"%s\": %m" msgstr "nelze nastavit přístupová práva na souboru \"%s\": %m" -#: pg_basebackup.c:1620 -#, c-format -msgid "COPY stream ended before last file was finished" -msgstr "COPY stream skončil před dokončením posledního souboru" - -#: pg_basebackup.c:1647 pg_basebackup.c:1667 pg_basebackup.c:1681 -#: pg_basebackup.c:1727 -#, c-format -msgid "out of memory" -msgstr "nedostatek paměti" - -#: pg_basebackup.c:1819 +#: pg_basebackup.c:1831 #, c-format msgid "incompatible server version %s" msgstr "nekompatibilní verze serveru %s" -#: pg_basebackup.c:1834 +#: pg_basebackup.c:1846 #, c-format msgid "HINT: use -X none or -X fetch to disable log streaming" msgstr "HINT: použijte -X none nebo -X fetch pro vypnutí streamování logu" -#: pg_basebackup.c:1859 +#: pg_basebackup.c:1882 #, c-format msgid "initiating base backup, waiting for checkpoint to complete" msgstr "inicializuji base backup, čekám na dokončení checkpointu" -#: pg_basebackup.c:1883 pg_recvlogical.c:264 receivelog.c:484 receivelog.c:533 -#: receivelog.c:572 streamutil.c:299 streamutil.c:370 streamutil.c:422 +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:481 receivelog.c:530 +#: receivelog.c:569 streamutil.c:297 streamutil.c:370 streamutil.c:422 #: streamutil.c:533 streamutil.c:578 #, c-format msgid "could not send replication command \"%s\": %s" msgstr "nelze zaslat replikační příkaz \"%s\": %s" -#: pg_basebackup.c:1894 +#: pg_basebackup.c:1919 #, c-format msgid "could not initiate base backup: %s" msgstr "nelze inicializovat base backup: %s" -#: pg_basebackup.c:1900 +#: pg_basebackup.c:1925 #, c-format msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" msgstr "server vrátil neočekávanou odpověď na BASE_BACKUP příkaz; přišlo %d řádeka %d položek, ořekáváno %d řádek a %d položek" -#: pg_basebackup.c:1908 +#: pg_basebackup.c:1933 #, c-format msgid "checkpoint completed" msgstr "checkpoint dokončen" -#: pg_basebackup.c:1923 +#: pg_basebackup.c:1948 #, c-format msgid "write-ahead log start point: %s on timeline %u" msgstr "počáteční pozice we write-ahead logu: %s na timeline %u" -#: pg_basebackup.c:1932 +#: pg_basebackup.c:1957 #, c-format msgid "could not get backup header: %s" msgstr "nelze získat hlavičku zálohy: %s" -#: pg_basebackup.c:1938 +#: pg_basebackup.c:1963 #, c-format msgid "no data returned from server" msgstr "ze serveru nebyla vrácena žádná data" -#: pg_basebackup.c:1969 +#: pg_basebackup.c:1995 #, c-format msgid "can only write single tablespace to stdout, database has %d" msgstr "na stdout lze zapsat jen jeden tablespace, databáze má %d" -#: pg_basebackup.c:1981 +#: pg_basebackup.c:2007 #, c-format msgid "starting background WAL receiver" msgstr "starting background WAL receiver" -#: pg_basebackup.c:2011 +#: pg_basebackup.c:2046 #, c-format msgid "could not get write-ahead log end position from server: %s" msgstr "ze serveru nelze získat koncovou pozici v transakčním logu: %s" -#: pg_basebackup.c:2017 +#: pg_basebackup.c:2052 #, c-format msgid "no write-ahead log end position returned from server" msgstr "ze serveru nebyla vrácena žádná koncová pozice v transakčním logu" -#: pg_basebackup.c:2022 +#: pg_basebackup.c:2057 #, c-format msgid "write-ahead log end point: %s" msgstr "koncová pozice ve write-ahead logu: %s" -#: pg_basebackup.c:2033 +#: pg_basebackup.c:2068 #, c-format msgid "checksum error occurred" msgstr "došlo k chybě kontrolního součtu" -#: pg_basebackup.c:2038 +#: pg_basebackup.c:2073 #, c-format msgid "final receive failed: %s" msgstr "závěrečný receive selhal: %s" -#: pg_basebackup.c:2062 +#: pg_basebackup.c:2097 #, c-format msgid "waiting for background process to finish streaming ..." msgstr "čekám na background proces pro ukočení streamování ..." -#: pg_basebackup.c:2067 +#: pg_basebackup.c:2102 #, c-format msgid "could not send command to background pipe: %m" msgstr "nelze zaslat příkaz přes background rouru: %m" -#: pg_basebackup.c:2075 +#: pg_basebackup.c:2110 #, c-format msgid "could not wait for child process: %m" msgstr "nelze počkat na podřízený (child) proces: %m" -#: pg_basebackup.c:2080 +#: pg_basebackup.c:2115 #, c-format msgid "child %d died, expected %d" msgstr "potomek %d zemřel, očekáváno %d" -#: pg_basebackup.c:2085 streamutil.c:94 +#: pg_basebackup.c:2120 streamutil.c:92 #, c-format msgid "%s" msgstr "%s" -#: pg_basebackup.c:2110 +#: pg_basebackup.c:2145 #, c-format msgid "could not wait for child thread: %m" msgstr "nelze počkat na podřízené (child) vlákno: %m" -#: pg_basebackup.c:2116 +#: pg_basebackup.c:2151 #, c-format msgid "could not get child thread exit status: %m" msgstr "nelze získat návratový kód podřízeného vlákna: %m" -#: pg_basebackup.c:2121 +#: pg_basebackup.c:2156 #, c-format msgid "child thread exited with error %u" msgstr "podřízené vlákno skončilo s chybou %u" -#: pg_basebackup.c:2149 +#: pg_basebackup.c:2184 #, c-format msgid "syncing data to disk ..." msgstr "zapisuji data na disk ..." -#: pg_basebackup.c:2162 +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "přejmenovávám backup_manifest.tmp na backup_manifest" + +#: pg_basebackup.c:2220 #, c-format msgid "base backup completed" msgstr "base backup dokončen" -#: pg_basebackup.c:2243 +#: pg_basebackup.c:2305 #, c-format msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" msgstr "chybný formát výstupu \"%s\", musí být \"plain\" nebo \"tar\"" -#: pg_basebackup.c:2287 +#: pg_basebackup.c:2349 #, c-format msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" msgstr "neplatná wal-metoda \"%s\", musí být \"fetch\", \"stream\" nebo \"none\"" -#: pg_basebackup.c:2315 pg_receivewal.c:581 +#: pg_basebackup.c:2377 pg_receivewal.c:580 #, c-format msgid "invalid compression level \"%s\"" msgstr "chybná úroveň komprese \"%s\"" -#: pg_basebackup.c:2326 +#: pg_basebackup.c:2388 #, c-format msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" msgstr "chybný checkpoint argument \"%s\", musí být \"fast\" nebo \"spread\"" -#: pg_basebackup.c:2353 pg_receivewal.c:556 pg_recvlogical.c:796 +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 #, c-format msgid "invalid status interval \"%s\"" msgstr "neplatný interval zasílání stavu \"%s\"" -#: pg_basebackup.c:2371 pg_basebackup.c:2384 pg_basebackup.c:2395 -#: pg_basebackup.c:2406 pg_basebackup.c:2414 pg_basebackup.c:2422 -#: pg_basebackup.c:2432 pg_basebackup.c:2445 pg_basebackup.c:2453 -#: pg_basebackup.c:2464 pg_basebackup.c:2474 pg_receivewal.c:606 -#: pg_receivewal.c:619 pg_receivewal.c:627 pg_receivewal.c:637 -#: pg_receivewal.c:645 pg_receivewal.c:656 pg_recvlogical.c:822 -#: pg_recvlogical.c:835 pg_recvlogical.c:846 pg_recvlogical.c:854 -#: pg_recvlogical.c:862 pg_recvlogical.c:870 pg_recvlogical.c:878 -#: pg_recvlogical.c:886 pg_recvlogical.c:894 +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2527 +#: pg_basebackup.c:2538 pg_basebackup.c:2548 pg_basebackup.c:2565 +#: pg_basebackup.c:2573 pg_basebackup.c:2581 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: pg_basebackup.c:2382 pg_receivewal.c:617 pg_recvlogical.c:833 +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "příliš mnoho argumentů v příkazové řádce (první je \"%s\")" -#: pg_basebackup.c:2394 pg_receivewal.c:655 +#: pg_basebackup.c:2468 pg_receivewal.c:654 #, c-format msgid "no target directory specified" msgstr "nebyl zadán cílový adresář" -#: pg_basebackup.c:2405 +#: pg_basebackup.c:2479 #, c-format msgid "only tar mode backups can be compressed" msgstr "pouze tar zálohy mohou být komprimované" -#: pg_basebackup.c:2413 +#: pg_basebackup.c:2487 #, c-format msgid "cannot stream write-ahead logs in tar mode to stdout" msgstr "v tar módu s výstupem na stdout nelze streamovat write-ahead logy" -#: pg_basebackup.c:2421 +#: pg_basebackup.c:2495 #, c-format msgid "replication slots can only be used with WAL streaming" msgstr "replikační sloty lze použít pouze s WAL streamováním" -#: pg_basebackup.c:2431 +#: pg_basebackup.c:2505 #, c-format msgid "--no-slot cannot be used with slot name" msgstr "--no-slot nelze použít společně se jménem slotu" #. translator: second %s is an option name -#: pg_basebackup.c:2443 pg_receivewal.c:635 +#: pg_basebackup.c:2517 pg_receivewal.c:634 #, c-format msgid "%s needs a slot to be specified using --slot" msgstr "%s vyžaduje aby byl zadán slot pomocí --slot" -#: pg_basebackup.c:2452 +#: pg_basebackup.c:2526 #, c-format msgid "--create-slot and --no-slot are incompatible options" msgstr "--create-slot a --no-slot jsou nekompatibilní volby" -#: pg_basebackup.c:2463 +#: pg_basebackup.c:2537 #, c-format msgid "WAL directory location can only be specified in plain mode" msgstr "umístění WAL adresáře lze zadat pouze v plain módu" -#: pg_basebackup.c:2473 +#: pg_basebackup.c:2547 #, c-format msgid "WAL directory location must be an absolute path" msgstr "cesta k adresáři transakčního logu musí být absolutní" -#: pg_basebackup.c:2483 pg_receivewal.c:664 +#: pg_basebackup.c:2557 pg_receivewal.c:663 #, c-format msgid "this build does not support compression" msgstr "tento build nepodporuje kompresi" -#: pg_basebackup.c:2537 +#: pg_basebackup.c:2564 +#, c-format +#| msgid "--create-slot and --no-slot are incompatible options" +msgid "--progress and --no-estimate-size are incompatible options" +msgstr "--progress a --no-estimate-size jsou nekompatibilní volby" + +#: pg_basebackup.c:2572 +#, c-format +#| msgid "--create-slot and --no-slot are incompatible options" +msgid "--no-manifest and --manifest-checksums are incompatible options" +msgstr "--no-manifest a --manifest-checksums jsou nekompatibilní volby" + +#: pg_basebackup.c:2580 +#, c-format +#| msgid "--create-slot and --no-slot are incompatible options" +msgid "--no-manifest and --manifest-force-encode are incompatible options" +msgstr "--no-manifest a --manifest-force-encode jsou nekompatibilní volby" + +#: pg_basebackup.c:2639 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "nelze vytvořit symbolický odkaz na \"%s\": %m" -#: pg_basebackup.c:2541 +#: pg_basebackup.c:2643 #, c-format msgid "symlinks are not supported on this platform" msgstr "na této platformě nejsou symbolické linky podporovány" -#: pg_receivewal.c:79 +#: pg_receivewal.c:77 #, c-format msgid "" "%s receives PostgreSQL streaming write-ahead logs.\n" @@ -822,7 +896,7 @@ msgstr "" "%s přijímá PostgreSQL streamované transakční logy\n" "\n" -#: pg_receivewal.c:83 pg_recvlogical.c:84 +#: pg_receivewal.c:81 pg_recvlogical.c:81 #, c-format msgid "" "\n" @@ -831,32 +905,32 @@ msgstr "" "\n" "Obecné volby:\n" -#: pg_receivewal.c:84 +#: pg_receivewal.c:82 #, c-format msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" msgstr " -D, --directory=DIR soubory transakčního logu ukládej do tohoto adresáře\n" -#: pg_receivewal.c:85 pg_recvlogical.c:85 +#: pg_receivewal.c:83 pg_recvlogical.c:82 #, c-format msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" msgstr " -E, --endpos=LSN skončí po dosažení zadaného LSN\n" -#: pg_receivewal.c:86 pg_recvlogical.c:89 +#: pg_receivewal.c:84 pg_recvlogical.c:86 #, c-format msgid " --if-not-exists do not error if slot already exists when creating a slot\n" msgstr " --if-not-exists vytváření slotu neskončí chybou pokud slot již existuje\n" -#: pg_receivewal.c:87 pg_recvlogical.c:91 +#: pg_receivewal.c:85 pg_recvlogical.c:88 #, c-format msgid " -n, --no-loop do not loop on connection lost\n" msgstr " -n, --no-loop neopakovat pokus o spojení v případě selhání\n" -#: pg_receivewal.c:88 +#: pg_receivewal.c:86 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr " --no-sync nečekat na bezpečné zapsání změn na disk\n" -#: pg_receivewal.c:89 pg_recvlogical.c:96 +#: pg_receivewal.c:87 pg_recvlogical.c:93 #, c-format msgid "" " -s, --status-interval=SECS\n" @@ -865,17 +939,17 @@ msgstr "" " -s, --status-interval=SECS\n" " čas mezi zasíláním packetů se stavem na server (implicitně: %d)\n" -#: pg_receivewal.c:92 +#: pg_receivewal.c:90 #, c-format msgid " --synchronous flush write-ahead log immediately after writing\n" msgstr " --synchronous vynutí flush write-ahead logu okamžitě po zapsání\n" -#: pg_receivewal.c:95 +#: pg_receivewal.c:93 #, c-format msgid " -Z, --compress=0-9 compress logs with given compression level\n" msgstr " -Z, --compress=0-9 komprimuj logy zvolenou úrovní komprese\n" -#: pg_receivewal.c:104 +#: pg_receivewal.c:102 #, c-format msgid "" "\n" @@ -884,123 +958,123 @@ msgstr "" "\n" "Nepovinné volby:\n" -#: pg_receivewal.c:105 pg_recvlogical.c:81 +#: pg_receivewal.c:103 pg_recvlogical.c:78 #, c-format msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" msgstr " --create-slot vytvoří nový replikační slot (pro jméno slotu viz --slot)\n" -#: pg_receivewal.c:106 pg_recvlogical.c:82 +#: pg_receivewal.c:104 pg_recvlogical.c:79 #, c-format msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" msgstr " --drop-slot odstraní replikační slot (pro jméno slotu viz --slot)\n" -#: pg_receivewal.c:118 +#: pg_receivewal.c:117 #, c-format msgid "finished segment at %X/%X (timeline %u)" msgstr "dokončen segment na %X/%X (timeline %u)" -#: pg_receivewal.c:125 +#: pg_receivewal.c:124 #, c-format msgid "stopped log streaming at %X/%X (timeline %u)" msgstr "končím streamování logu na %X/%X (timeline %u)" -#: pg_receivewal.c:141 +#: pg_receivewal.c:140 #, c-format msgid "switched to timeline %u at %X/%X" msgstr "přepnuto na timeline %u v %X/%X" -#: pg_receivewal.c:151 +#: pg_receivewal.c:150 #, c-format msgid "received interrupt signal, exiting" msgstr "přijat signál k přerušení, ukončuji" -#: pg_receivewal.c:187 +#: pg_receivewal.c:186 #, c-format msgid "could not close directory \"%s\": %m" msgstr "zavřít adresář \"%s\": %m" -#: pg_receivewal.c:273 +#: pg_receivewal.c:272 #, c-format msgid "segment file \"%s\" has incorrect size %d, skipping" msgstr "segment soubor \"%s\" má neplatnou velikost %d, přeskakuji" -#: pg_receivewal.c:291 +#: pg_receivewal.c:290 #, c-format msgid "could not open compressed file \"%s\": %m" msgstr "nelze otevřít komprimovaný soubor \"%s\": %m" -#: pg_receivewal.c:297 +#: pg_receivewal.c:296 #, c-format msgid "could not seek in compressed file \"%s\": %m" msgstr "nelze nastavit pozici (seek) v komprimovaném souboru \"%s\": %m" -#: pg_receivewal.c:305 +#: pg_receivewal.c:304 #, c-format msgid "could not read compressed file \"%s\": %m" msgstr "nelze číst komprimovaný soubor \"%s\": %m" -#: pg_receivewal.c:308 +#: pg_receivewal.c:307 #, c-format msgid "could not read compressed file \"%s\": read %d of %zu" msgstr "nelze číst komprimovaný soubor \"%s\": přečteno %d z %zu" -#: pg_receivewal.c:319 +#: pg_receivewal.c:318 #, c-format msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" msgstr "komprimovaný segment soubor \"%s\" má po dekompresi neplatnou velikost %d, přeskakuji" -#: pg_receivewal.c:423 +#: pg_receivewal.c:422 #, c-format msgid "starting log streaming at %X/%X (timeline %u)" msgstr "začínám streamování logu na %X/%X (timeline %u)" -#: pg_receivewal.c:538 pg_recvlogical.c:738 +#: pg_receivewal.c:537 pg_recvlogical.c:762 #, c-format msgid "invalid port number \"%s\"" msgstr "neplatné číslo portu: \"%s\"" -#: pg_receivewal.c:566 pg_recvlogical.c:764 +#: pg_receivewal.c:565 pg_recvlogical.c:788 #, c-format msgid "could not parse end position \"%s\"" msgstr "nelze zpracovat koncovou pozici \"%s\"" -#: pg_receivewal.c:626 +#: pg_receivewal.c:625 #, c-format msgid "cannot use --create-slot together with --drop-slot" msgstr "nelze použít --create-slot společně s --drop-slot" -#: pg_receivewal.c:644 +#: pg_receivewal.c:643 #, c-format msgid "cannot use --synchronous together with --no-sync" msgstr "nelze použít --synchronous společně s --no-sync" -#: pg_receivewal.c:720 +#: pg_receivewal.c:719 #, c-format msgid "replication connection using slot \"%s\" is unexpectedly database specific" msgstr "replikační spojení používající slot \"%s\" je neočekávaně specifické pro databázi" -#: pg_receivewal.c:731 pg_recvlogical.c:942 +#: pg_receivewal.c:730 pg_recvlogical.c:966 #, c-format msgid "dropping replication slot \"%s\"" msgstr "odstraňuji replikační slot \"%s\"" -#: pg_receivewal.c:742 pg_recvlogical.c:952 +#: pg_receivewal.c:741 pg_recvlogical.c:976 #, c-format msgid "creating replication slot \"%s\"" msgstr "vytvářím replikační slot \"%s\"" -#: pg_receivewal.c:768 pg_recvlogical.c:977 +#: pg_receivewal.c:767 pg_recvlogical.c:1001 #, c-format msgid "disconnected" msgstr "odpojeno" #. translator: check source for value for %d -#: pg_receivewal.c:774 pg_recvlogical.c:983 +#: pg_receivewal.c:773 pg_recvlogical.c:1007 #, c-format msgid "disconnected; waiting %d seconds to try again" msgstr "odpojeno; čekám %d vteřin pro další pokus" -#: pg_recvlogical.c:76 +#: pg_recvlogical.c:73 #, c-format msgid "" "%s controls PostgreSQL logical decoding streams.\n" @@ -1009,7 +1083,7 @@ msgstr "" "%s ovládá streamy PostgreSQL logického dekódování.\n" "\n" -#: pg_recvlogical.c:80 +#: pg_recvlogical.c:77 #, c-format msgid "" "\n" @@ -1018,17 +1092,17 @@ msgstr "" "\n" "Akce která se má vykonat:\n" -#: pg_recvlogical.c:83 +#: pg_recvlogical.c:80 #, c-format msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" msgstr " --start start streaming in a replication slot (for the slot's name see --slot)\n" -#: pg_recvlogical.c:86 +#: pg_recvlogical.c:83 #, c-format msgid " -f, --file=FILE receive log into this file, - for stdout\n" msgstr " -f, --file=FILE log zapisuj do tohoto souboru, - pro stdout\n" -#: pg_recvlogical.c:87 +#: pg_recvlogical.c:84 #, c-format msgid "" " -F --fsync-interval=SECS\n" @@ -1037,12 +1111,12 @@ msgstr "" " -F --fsync-interval=SECS\n" " interval mezi voláním fsync na výstupním souboru (implicitně: %d)\n" -#: pg_recvlogical.c:90 +#: pg_recvlogical.c:87 #, c-format msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" msgstr " -I, --startpos=LSN kde v existujícím slotu má začít streamování\n" -#: pg_recvlogical.c:92 +#: pg_recvlogical.c:89 #, c-format msgid "" " -o, --option=NAME[=VALUE]\n" @@ -1053,162 +1127,162 @@ msgstr "" " předá volbu JMÉNO s nepovinnou hodnotou HODNOTA\n" " výstupnímu pluginu\n" -#: pg_recvlogical.c:95 +#: pg_recvlogical.c:92 #, c-format msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" msgstr " -P, --plugin=PLUGIN použije výstupní plugin PLUGIN (implicitně: %s)\n" -#: pg_recvlogical.c:98 +#: pg_recvlogical.c:95 #, c-format msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" msgstr " -S, --slot=SLOTNAME jméno logického replikačního slotu\n" -#: pg_recvlogical.c:103 +#: pg_recvlogical.c:100 #, c-format msgid " -d, --dbname=DBNAME database to connect to\n" msgstr " -d, --dbname=DBNAME databáze ke které se připojit\n" -#: pg_recvlogical.c:135 +#: pg_recvlogical.c:133 #, c-format msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" msgstr "potvrzuji zápis až do %X/%X, flush do %X/%X (slot %s)" -#: pg_recvlogical.c:159 receivelog.c:346 +#: pg_recvlogical.c:157 receivelog.c:343 #, c-format msgid "could not send feedback packet: %s" msgstr "nelze zaslat packet se zpětnou vazbou: %s" -#: pg_recvlogical.c:232 +#: pg_recvlogical.c:230 #, c-format msgid "starting log streaming at %X/%X (slot %s)" msgstr "začínám streamování logu na %X/%X (slot %s)" -#: pg_recvlogical.c:273 +#: pg_recvlogical.c:271 #, c-format msgid "streaming initiated" msgstr "streamování inicializováno" -#: pg_recvlogical.c:337 +#: pg_recvlogical.c:335 #, c-format msgid "could not open log file \"%s\": %m" msgstr "nelze otevřít log soubor \"%s\": %m" -#: pg_recvlogical.c:363 receivelog.c:876 +#: pg_recvlogical.c:361 receivelog.c:873 #, c-format msgid "invalid socket: %s" msgstr "neplatný socket: %s" -#: pg_recvlogical.c:416 receivelog.c:904 +#: pg_recvlogical.c:414 receivelog.c:901 #, c-format msgid "select() failed: %m" msgstr "volání select() selhalo: %m" -#: pg_recvlogical.c:423 receivelog.c:954 +#: pg_recvlogical.c:421 receivelog.c:951 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "nelze získat data z WAL streamu: %s" -#: pg_recvlogical.c:465 pg_recvlogical.c:516 receivelog.c:998 receivelog.c:1064 +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:995 receivelog.c:1061 #, c-format msgid "streaming header too small: %d" msgstr "hlavička streamu je příliš malá: %d" -#: pg_recvlogical.c:500 receivelog.c:836 +#: pg_recvlogical.c:498 receivelog.c:833 #, c-format msgid "unrecognized streaming header: \"%c\"" msgstr "nerozpoznaná hlavička streamu: \"%c\"" -#: pg_recvlogical.c:554 pg_recvlogical.c:566 +#: pg_recvlogical.c:552 pg_recvlogical.c:564 #, c-format msgid "could not write %u bytes to log file \"%s\": %m" msgstr "nelze zapsat %u bytů do log souboru \"%s\": %m" -#: pg_recvlogical.c:594 receivelog.c:632 receivelog.c:669 +#: pg_recvlogical.c:618 receivelog.c:629 receivelog.c:666 #, c-format msgid "unexpected termination of replication stream: %s" msgstr "neočekávané ukončení replikačního streamu: %s" -#: pg_recvlogical.c:718 +#: pg_recvlogical.c:742 #, c-format msgid "invalid fsync interval \"%s\"" msgstr "neplatný fsync interval \"%s\"" -#: pg_recvlogical.c:756 +#: pg_recvlogical.c:780 #, c-format msgid "could not parse start position \"%s\"" msgstr "nelze zpracovat počáteční pozici \"%s\"" -#: pg_recvlogical.c:845 +#: pg_recvlogical.c:869 #, c-format msgid "no slot specified" msgstr "slot není specifikován" -#: pg_recvlogical.c:853 +#: pg_recvlogical.c:877 #, c-format msgid "no target file specified" msgstr "nebyl zadán cílový soubor" -#: pg_recvlogical.c:861 +#: pg_recvlogical.c:885 #, c-format msgid "no database specified" msgstr "není specifikována databáze" -#: pg_recvlogical.c:869 +#: pg_recvlogical.c:893 #, c-format msgid "at least one action needs to be specified" msgstr "alespoň jedna akce musí být zadána" -#: pg_recvlogical.c:877 +#: pg_recvlogical.c:901 #, c-format msgid "cannot use --create-slot or --start together with --drop-slot" msgstr "nelze použít use-slot nebo --start společně s --drop-slot" -#: pg_recvlogical.c:885 +#: pg_recvlogical.c:909 #, c-format msgid "cannot use --create-slot or --drop-slot together with --startpos" msgstr "nelze použít --create-slot nebo --drop-slot společně s --startpos" -#: pg_recvlogical.c:893 +#: pg_recvlogical.c:917 #, c-format msgid "--endpos may only be specified with --start" msgstr "--endpos může být použito pouze společně s --start" -#: pg_recvlogical.c:924 +#: pg_recvlogical.c:948 #, c-format msgid "could not establish database-specific replication connection" msgstr "nelze otevřít database-specific replikační spojení" -#: pg_recvlogical.c:1023 +#: pg_recvlogical.c:1047 #, c-format msgid "end position %X/%X reached by keepalive" msgstr "koncová pozice %X/%X dosažena keepalive" -#: pg_recvlogical.c:1026 +#: pg_recvlogical.c:1050 #, c-format msgid "end position %X/%X reached by WAL record at %X/%X" msgstr "koncová pozice %X/%X doražena WAL záznamem na %X/%X" -#: receivelog.c:72 +#: receivelog.c:69 #, c-format msgid "could not create archive status file \"%s\": %s" msgstr "nelze vytvořit soubor se stavem archivace \"%s\": %s" -#: receivelog.c:119 +#: receivelog.c:116 #, c-format msgid "could not get size of write-ahead log file \"%s\": %s" msgstr "nelze získat velikost write-ahead log souboru \"%s\": %s" -#: receivelog.c:129 +#: receivelog.c:126 #, c-format msgid "could not open existing write-ahead log file \"%s\": %s" msgstr "nelze otevřít existující soubor transakčního logu \"%s\": %s" -#: receivelog.c:137 +#: receivelog.c:134 #, c-format msgid "could not fsync existing write-ahead log file \"%s\": %s" msgstr "nelze provést fsync existujícího souboru write-ahead logu \"%s\": %s" -#: receivelog.c:151 +#: receivelog.c:148 #, c-format msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" @@ -1216,161 +1290,161 @@ msgstr[0] "soubor transakčního logu \"%s\" má %d bytů, měl by mít 0 nebo % msgstr[1] "soubor transakčního logu \"%s\" má %d bytů, měl by mít 0 nebo %d" msgstr[2] "soubor transakčního logu \"%s\" má %d bytů, měl by mít 0 nebo %d" -#: receivelog.c:166 +#: receivelog.c:163 #, c-format msgid "could not open write-ahead log file \"%s\": %s" msgstr "nelze otevřít soubor write-ahead logu \"%s\": %s" -#: receivelog.c:192 +#: receivelog.c:189 #, c-format msgid "could not determine seek position in file \"%s\": %s" msgstr "nelze určit pozici pro seek v souboru \"%s\": %s" -#: receivelog.c:206 +#: receivelog.c:203 #, c-format msgid "not renaming \"%s%s\", segment is not complete" msgstr "nepřejmenovávám \"%s%s\", segment není kompletní" -#: receivelog.c:218 receivelog.c:303 receivelog.c:678 +#: receivelog.c:215 receivelog.c:300 receivelog.c:675 #, c-format msgid "could not close file \"%s\": %s" msgstr "nelze uzavřít soubor \"%s\": %s" -#: receivelog.c:275 +#: receivelog.c:272 #, c-format msgid "server reported unexpected history file name for timeline %u: %s" msgstr "server ohlásil neočekávané jméno souboru s historií pro timeline %u: %s" -#: receivelog.c:283 +#: receivelog.c:280 #, c-format msgid "could not create timeline history file \"%s\": %s" msgstr "nelze vytvořit soubor s timeline historií \"%s\": %s" -#: receivelog.c:290 +#: receivelog.c:287 #, c-format msgid "could not write timeline history file \"%s\": %s" msgstr "nelze zapsat do souboru s timeline historií \"%s\": %s" -#: receivelog.c:380 +#: receivelog.c:377 #, c-format msgid "incompatible server version %s; client does not support streaming from server versions older than %s" msgstr "nekompatibilní verze serveru %s; klient nepodporuje streamování ze serverů s verzí starší než %s" -#: receivelog.c:389 +#: receivelog.c:386 #, c-format msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" msgstr "nekompatibilní verze serveru %s; klient nepodporuje streamování ze serverů s verzí novější než %s" -#: receivelog.c:491 streamutil.c:430 streamutil.c:467 +#: receivelog.c:488 streamutil.c:430 streamutil.c:467 #, c-format msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" msgstr "nelze identifikovat systém, načteno %d řádek a %d položek, očekáváno %d řádek a %d nebo více položek" -#: receivelog.c:498 +#: receivelog.c:495 #, c-format msgid "system identifier does not match between base backup and streaming connection" msgstr "identifikátor systému mezi base backupem a streamovacím spojením neodpovídá" -#: receivelog.c:504 +#: receivelog.c:501 #, c-format msgid "starting timeline %u is not present in the server" msgstr "počáteční timeline %u není přitomna na serveru" -#: receivelog.c:545 +#: receivelog.c:542 #, c-format msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" msgstr "neočekávaná odpověď na TIMELINE_HISTORY příkaz: načteno %d řádek a %d položek, očekáváno %d řádek a %d položek" -#: receivelog.c:616 +#: receivelog.c:613 #, c-format msgid "server reported unexpected next timeline %u, following timeline %u" msgstr "server ohlásil neočekávanou další timeline %u, následující timeline %u" -#: receivelog.c:622 +#: receivelog.c:619 #, c-format msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" msgstr "server přestal streamovat timeline %u at %X/%X, ale začátek další timelineoznámil %u na %X/%X" -#: receivelog.c:662 +#: receivelog.c:659 #, c-format msgid "replication stream was terminated before stop point" msgstr "replikační stream byl ukončen před bodem zastavení (stop point)" -#: receivelog.c:708 +#: receivelog.c:705 #, c-format msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" msgstr "neočekávaný výsledek po konci timeline: získáno %d řádek a %d položek, očekáváno %d řádek a %d položek" -#: receivelog.c:717 +#: receivelog.c:714 #, c-format msgid "could not parse next timeline's starting point \"%s\"" msgstr "nelze naparsovat počáteční bod další timeline \"%s\"" -#: receivelog.c:766 receivelog.c:1018 +#: receivelog.c:763 receivelog.c:1015 #, c-format msgid "could not fsync file \"%s\": %s" msgstr "nelze provést fsync souboru \"%s\": %s" -#: receivelog.c:1081 +#: receivelog.c:1078 #, c-format msgid "received write-ahead log record for offset %u with no file open" msgstr "přijat záznam z transakčního logu pro offset %u bez otevřeného souboru" -#: receivelog.c:1091 +#: receivelog.c:1088 #, c-format msgid "got WAL data offset %08x, expected %08x" msgstr "získán WAL data offset %08x, očekáván %08x" -#: receivelog.c:1125 +#: receivelog.c:1122 #, c-format msgid "could not write %u bytes to WAL file \"%s\": %s" msgstr "nelze zapsat %u bytů do WAL souboru %s: %s" -#: receivelog.c:1150 receivelog.c:1190 receivelog.c:1221 +#: receivelog.c:1147 receivelog.c:1187 receivelog.c:1218 #, c-format msgid "could not send copy-end packet: %s" msgstr "nelze zaslat copy-end packet: %s" -#: streamutil.c:162 +#: streamutil.c:160 msgid "Password: " msgstr "Heslo: " -#: streamutil.c:187 +#: streamutil.c:185 #, c-format msgid "could not connect to server" msgstr "nelze se připojit k serveru" -#: streamutil.c:204 +#: streamutil.c:202 #, c-format msgid "could not connect to server: %s" msgstr "nelze se připojit k serveru: %s" -#: streamutil.c:233 +#: streamutil.c:231 #, c-format msgid "could not clear search_path: %s" msgstr "nelze vyčistit search_path: %s" -#: streamutil.c:249 +#: streamutil.c:247 #, c-format msgid "could not determine server setting for integer_datetimes" msgstr "nelze zjistit nastavení volby integer_datetimes na serveru" -#: streamutil.c:256 +#: streamutil.c:254 #, c-format msgid "integer_datetimes compile flag does not match server" msgstr "integer_datetimes přepínač kompilace neodpovídá serveru" -#: streamutil.c:307 +#: streamutil.c:305 #, c-format msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" msgstr "nelze identifikovat systém, načteno %d řádek a %d položek, očekáváno %d řádek a %d nebo více položek" -#: streamutil.c:317 +#: streamutil.c:315 #, c-format msgid "WAL segment size could not be parsed" msgstr "velikost WAL segmentu nelze naparsovat" -#: streamutil.c:332 +#: streamutil.c:333 #, c-format msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" @@ -1398,169 +1472,176 @@ msgstr "nelze vytvořit replikační slot \"%s\": načteno %d řádek a %d polo msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" msgstr "nelze odstranit replikační slot \"%s\": načteno %d řádek a %d položek, očekáváno %d řádek a %d položek" -#: walmethods.c:439 walmethods.c:928 +#: walmethods.c:438 walmethods.c:927 msgid "could not compress data" msgstr "nelze komprimovat data" -#: walmethods.c:471 +#: walmethods.c:470 msgid "could not reset compression stream" msgstr "nelze resetovat kompresní stream" -#: walmethods.c:569 +#: walmethods.c:568 msgid "could not initialize compression library" msgstr "nelze inicializovat kompresní knihovnu" -#: walmethods.c:581 +#: walmethods.c:580 msgid "implementation error: tar files can't have more than one open file" msgstr "chyba implementace: tar soubory nemohou mít otevřeno více než jeden soubor" -#: walmethods.c:595 +#: walmethods.c:594 msgid "could not create tar header" msgstr "nelze vytvořit tar hlavičku" -#: walmethods.c:609 walmethods.c:649 walmethods.c:844 walmethods.c:855 +#: walmethods.c:608 walmethods.c:648 walmethods.c:843 walmethods.c:854 msgid "could not change compression parameters" msgstr "nelze změnit kompresní stream" -#: walmethods.c:731 +#: walmethods.c:730 msgid "unlink not supported with compression" msgstr "unlink není podporován s kompresí" -#: walmethods.c:953 +#: walmethods.c:952 msgid "could not close compression stream" msgstr "nelze uzavřít kompresní stream" -#~ msgid " -x, --xlog include required WAL files in backup (fetch mode)\n" -#~ msgstr " -x, --xlog zahrne potřebné WAL soubory do zálohy (fetch mód)\n" +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: nelze načíst stav souboru \"%s\": %s\n" -#~ msgid "%s: could not parse file size\n" -#~ msgstr "%s: nelze načíst velikost souboru\n" +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít adresář \"%s\": %s\n" -#~ msgid "%s: could not parse file mode\n" -#~ msgstr "%s: nelze načíst mód souboru\n" +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: nelze načíst adresář \"%s\": %s\n" -#~ msgid "%s: cannot specify both --xlog and --xlog-method\n" -#~ msgstr "%s: volby --xlog a --xlog-method nelze zadat společně\n" +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít soubor \"%s\": %s\n" -#~ msgid "%s: could not parse transaction log file name \"%s\"\n" -#~ msgstr "%s: nelze naparsovat jméno souboru transakčního logu \"%s\"\n" +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: nelze vytvořít adresář \"%s\": %s\n" -#~ msgid "%s: could not stat transaction log file \"%s\": %s\n" -#~ msgstr "%s: nelze udělat stat souboru transakčního logu \"%s\": %s\n" +#~ msgid "%s: could not write to file \"%s\": %s\n" +#~ msgstr "%s: nelze zapsat do souboru \"%s\": %s\n" -#~ msgid "%s: could not pad transaction log file \"%s\": %s\n" -#~ msgstr "%s: nelze doplnit soubor transakčního logu \"%s\": %s\n" +#~ msgid "%s: could not close file \"%s\": %s\n" +#~ msgstr "%s: nelze uzavřít soubor \"%s\": %s\n" -#~ msgid "%s: could not seek to beginning of transaction log file \"%s\": %s\n" -#~ msgstr "%s: nelze skočit zpět na začátek souboru transakčního logu \"%s\": %s\n" +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: nedostatek paměti\n" -#~ msgid "%s: could not rename file \"%s\": %s\n" -#~ msgstr "%s: nelze přejmenovat soubor \"%s\": %s\n" +#~ msgid "%s: child process did not exit normally\n" +#~ msgstr "%s: podřízený proces neskončil standardně\n" -#~ msgid "%s: no start point returned from server\n" -#~ msgstr "%s: server nevráti žádný počáteční bod (start point)\n" +#~ msgid "%s: child process exited with error %d\n" +#~ msgstr "%s: podřízený proces skončil s chybou %d\n" -#~ msgid "%s: timeline does not match between base backup and streaming connection\n" -#~ msgstr "%s: timeline mezi base backupem a streamovacím spojením neodpovídá\n" +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: nelze vytvořit symbolický link \"%s\": %s\n" -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help zobraz tuto nápovědu, poté skonči\n" +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s: symlinks nejsou na této platformě podporovány\n" -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version zobraz informaci o verzi, poté skonči\n" +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: nelze uzavřít adresář \"%s\": %s\n" -#~ msgid "%s: invalid format of xlog location: %s\n" -#~ msgstr "%s: neplatný formát xlog pozice: %s\n" +#~ msgid "%s: invalid port number \"%s\"\n" +#~ msgstr "%s: neplatné číslo portu \"%s\"\n" -#~ msgid "%s: could not identify system: %s" -#~ msgstr "%s: nelze identifikovat systém: %s" +#~ msgid "%s: could not fsync log file \"%s\": %s\n" +#~ msgstr "%s: nelze provést fsync log souboru \"%s\": %s\n" -#~ msgid "%s: could not send base backup command: %s" -#~ msgstr "%s: nelze poslat base backup příkaz: %s" +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít logovací soubor \"%s\": %s\n" -#~ msgid " -v, --verbose output verbose messages\n" -#~ msgstr " -v, --verbose vypisuj podrobnější zprávy\n" +#~ msgid "%s: select() failed: %s\n" +#~ msgstr "%s: select() selhal: %s\n" -#~ msgid "%s: could not identify system: %s\n" -#~ msgstr "%s: nelze identifikovat systém: %s\n" +#~ msgid "%s: could not connect to server\n" +#~ msgstr "%s: nelze se připojit k serveru\n" -#~ msgid "%s: could not parse log start position from value \"%s\"\n" -#~ msgstr "%s: nelze naparsovat počáteční pozici logu z hodnoty \"%s\"\n" +#~ msgid "%s: could not connect to server: %s" +#~ msgstr "%s: nelze se připojit k serveru: %s" -#~ msgid "%s: Could not open WAL segment %s: %s\n" -#~ msgstr "%s: nelze otevřít WAL segment %s: %s\n" +#~ msgid "%s: could not clear search_path: %s" +#~ msgstr "%s: nelze vyčistit search_path: %s" -#~ msgid "%s: could not stat WAL segment %s: %s\n" -#~ msgstr "%s: nelze načíst stav WAL segmentu %s: %s\n" +#~ msgid "%s: could not read copy data: %s\n" +#~ msgstr "%s: nelze načíst copy data: %s\n" -#~ msgid "%s: could not pad WAL segment %s: %s\n" -#~ msgstr "%s: nelze doplnit WAL segment %s: %s\n" +#~ msgid "%s: could not close file %s: %s\n" +#~ msgstr "%s: nelze zavřít soubor %s: %s\n" #~ msgid "%s: could not get current position in file %s: %s\n" #~ msgstr "%s: nelze získat aktuální pozici v souboru %s: %s\n" -#~ msgid "%s: could not close file %s: %s\n" -#~ msgstr "%s: nelze zavřít soubor %s: %s\n" +#~ msgid "%s: could not pad WAL segment %s: %s\n" +#~ msgstr "%s: nelze doplnit WAL segment %s: %s\n" -#~ msgid "%s: could not read copy data: %s\n" -#~ msgstr "%s: nelze načíst copy data: %s\n" +#~ msgid "%s: could not stat WAL segment %s: %s\n" +#~ msgstr "%s: nelze načíst stav WAL segmentu %s: %s\n" -#~ msgid "%s: could not clear search_path: %s" -#~ msgstr "%s: nelze vyčistit search_path: %s" +#~ msgid "%s: Could not open WAL segment %s: %s\n" +#~ msgstr "%s: nelze otevřít WAL segment %s: %s\n" -#~ msgid "%s: could not connect to server: %s" -#~ msgstr "%s: nelze se připojit k serveru: %s" +#~ msgid "%s: could not parse log start position from value \"%s\"\n" +#~ msgstr "%s: nelze naparsovat počáteční pozici logu z hodnoty \"%s\"\n" -#~ msgid "%s: could not connect to server\n" -#~ msgstr "%s: nelze se připojit k serveru\n" +#~ msgid "%s: could not identify system: %s\n" +#~ msgstr "%s: nelze identifikovat systém: %s\n" -#~ msgid "%s: select() failed: %s\n" -#~ msgstr "%s: select() selhal: %s\n" +#~ msgid " -v, --verbose output verbose messages\n" +#~ msgstr " -v, --verbose vypisuj podrobnější zprávy\n" -#~ msgid "%s: could not open log file \"%s\": %s\n" -#~ msgstr "%s: nelze otevřít logovací soubor \"%s\": %s\n" +#~ msgid "%s: could not send base backup command: %s" +#~ msgstr "%s: nelze poslat base backup příkaz: %s" -#~ msgid "%s: could not fsync log file \"%s\": %s\n" -#~ msgstr "%s: nelze provést fsync log souboru \"%s\": %s\n" +#~ msgid "%s: could not identify system: %s" +#~ msgstr "%s: nelze identifikovat systém: %s" -#~ msgid "%s: invalid port number \"%s\"\n" -#~ msgstr "%s: neplatné číslo portu \"%s\"\n" +#~ msgid "%s: invalid format of xlog location: %s\n" +#~ msgstr "%s: neplatný formát xlog pozice: %s\n" -#~ msgid "%s: could not close directory \"%s\": %s\n" -#~ msgstr "%s: nelze uzavřít adresář \"%s\": %s\n" +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version zobraz informaci o verzi, poté skonči\n" -#~ msgid "%s: symlinks are not supported on this platform\n" -#~ msgstr "%s: symlinks nejsou na této platformě podporovány\n" +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help zobraz tuto nápovědu, poté skonči\n" -#~ msgid "%s: could not create symbolic link \"%s\": %s\n" -#~ msgstr "%s: nelze vytvořit symbolický link \"%s\": %s\n" +#~ msgid "%s: timeline does not match between base backup and streaming connection\n" +#~ msgstr "%s: timeline mezi base backupem a streamovacím spojením neodpovídá\n" -#~ msgid "%s: child process exited with error %d\n" -#~ msgstr "%s: podřízený proces skončil s chybou %d\n" +#~ msgid "%s: no start point returned from server\n" +#~ msgstr "%s: server nevráti žádný počáteční bod (start point)\n" -#~ msgid "%s: child process did not exit normally\n" -#~ msgstr "%s: podřízený proces neskončil standardně\n" +#~ msgid "%s: could not rename file \"%s\": %s\n" +#~ msgstr "%s: nelze přejmenovat soubor \"%s\": %s\n" -#~ msgid "%s: out of memory\n" -#~ msgstr "%s: nedostatek paměti\n" +#~ msgid "%s: could not seek to beginning of transaction log file \"%s\": %s\n" +#~ msgstr "%s: nelze skočit zpět na začátek souboru transakčního logu \"%s\": %s\n" -#~ msgid "%s: could not close file \"%s\": %s\n" -#~ msgstr "%s: nelze uzavřít soubor \"%s\": %s\n" +#~ msgid "%s: could not pad transaction log file \"%s\": %s\n" +#~ msgstr "%s: nelze doplnit soubor transakčního logu \"%s\": %s\n" -#~ msgid "%s: could not write to file \"%s\": %s\n" -#~ msgstr "%s: nelze zapsat do souboru \"%s\": %s\n" +#~ msgid "%s: could not stat transaction log file \"%s\": %s\n" +#~ msgstr "%s: nelze udělat stat souboru transakčního logu \"%s\": %s\n" -#~ msgid "%s: could not create directory \"%s\": %s\n" -#~ msgstr "%s: nelze vytvořít adresář \"%s\": %s\n" +#~ msgid "%s: could not parse transaction log file name \"%s\"\n" +#~ msgstr "%s: nelze naparsovat jméno souboru transakčního logu \"%s\"\n" -#~ msgid "%s: could not open file \"%s\": %s\n" -#~ msgstr "%s: nelze otevřít soubor \"%s\": %s\n" +#~ msgid "%s: cannot specify both --xlog and --xlog-method\n" +#~ msgstr "%s: volby --xlog a --xlog-method nelze zadat společně\n" -#~ msgid "%s: could not read directory \"%s\": %s\n" -#~ msgstr "%s: nelze načíst adresář \"%s\": %s\n" +#~ msgid "%s: could not parse file mode\n" +#~ msgstr "%s: nelze načíst mód souboru\n" -#~ msgid "%s: could not open directory \"%s\": %s\n" -#~ msgstr "%s: nelze otevřít adresář \"%s\": %s\n" +#~ msgid "%s: could not parse file size\n" +#~ msgstr "%s: nelze načíst velikost souboru\n" -#~ msgid "%s: could not stat file \"%s\": %s\n" -#~ msgstr "%s: nelze načíst stav souboru \"%s\": %s\n" +#~ msgid " -x, --xlog include required WAL files in backup (fetch mode)\n" +#~ msgstr " -x, --xlog zahrne potřebné WAL soubory do zálohy (fetch mód)\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" diff --git a/src/bin/pg_basebackup/po/de.po b/src/bin/pg_basebackup/po/de.po new file mode 100644 index 000000000000..1c25945d0a3c --- /dev/null +++ b/src/bin/pg_basebackup/po/de.po @@ -0,0 +1,1478 @@ +# German message translation file for pg_basebackup +# Copyright (C) 2011 - 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-29 03:17+0000\n" +"PO-Revision-Date: 2021-04-29 06:55+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../../common/file_utils.c:87 ../../common/file_utils.c:451 +#: pg_receivewal.c:266 pg_recvlogical.c:340 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: ../../common/file_utils.c:166 pg_receivewal.c:169 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: ../../common/file_utils.c:200 pg_receivewal.c:337 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" + +#: ../../common/file_utils.c:232 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:134 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: ../../common/file_utils.c:303 ../../common/file_utils.c:373 +#: pg_recvlogical.c:193 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "konnte Datei »%s« nicht fsyncen: %m" + +#: ../../common/file_utils.c:383 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "konnte Datei »%s« nicht in »%s« umbenennen: %m" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "konnte nicht in Datei »%s« schreiben: %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "konnte Datei »%s« nicht erstellen: %m" + +#: pg_basebackup.c:224 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "entferne Datenverzeichnis »%s«" + +#: pg_basebackup.c:226 +#, c-format +msgid "failed to remove data directory" +msgstr "konnte Datenverzeichnis nicht entfernen" + +#: pg_basebackup.c:230 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "entferne Inhalt des Datenverzeichnisses »%s«" + +#: pg_basebackup.c:232 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "konnte Inhalt des Datenverzeichnisses nicht entfernen" + +#: pg_basebackup.c:237 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "entferne WAL-Verzeichnis »%s«" + +#: pg_basebackup.c:239 +#, c-format +msgid "failed to remove WAL directory" +msgstr "konnte WAL-Verzeichnis nicht entfernen" + +#: pg_basebackup.c:243 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "entferne Inhalt des WAL-Verzeichnisses »%s«" + +#: pg_basebackup.c:245 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "konnte Inhalt des WAL-Verzeichnisses nicht entfernen" + +#: pg_basebackup.c:251 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "Datenverzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" + +#: pg_basebackup.c:254 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "WAL-Verzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" + +#: pg_basebackup.c:258 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "Änderungen in Tablespace-Verzeichnissen werden nicht rückgängig gemacht" + +#: pg_basebackup.c:299 +#, c-format +msgid "directory name too long" +msgstr "Verzeichnisname zu lang" + +#: pg_basebackup.c:309 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "mehrere »=«-Zeichen im Tablespace-Mapping" + +#: pg_basebackup.c:321 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "ungültiges Tablespace-Mapping-Format »%s«, muss »ALTES_VERZ=NEUES_VERZ« sein" + +#: pg_basebackup.c:333 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "altes Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s" + +#: pg_basebackup.c:340 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "neues Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s" + +#: pg_basebackup.c:379 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s erzeugt eine Basissicherung eines laufenden PostgreSQL-Servers.\n" +"\n" + +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPTION]...\n" + +#: pg_basebackup.c:383 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"Optionen die die Ausgabe kontrollieren:\n" + +#: pg_basebackup.c:384 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=VERZ Basissicherung in dieses Verzeichnis empfangen\n" + +#: pg_basebackup.c:385 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t Ausgabeformat (plain (Voreinstellung), tar)\n" + +#: pg_basebackup.c:386 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=RATE maximale Transferrate für Übertragung des Datenver-\n" +" zeichnisses (in kB/s, oder Suffix »k« oder »M« abgeben)\n" + +#: pg_basebackup.c:388 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" Konfiguration für Replikation schreiben\n" + +#: pg_basebackup.c:390 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=ALTES_VERZ=NEUES_VERZ\n" +" Tablespace in ALTES_VERZ nach NEUES_VERZ verlagern\n" + +#: pg_basebackup.c:392 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALVERZ Verzeichnis für das Write-Ahead-Log\n" + +#: pg_basebackup.c:393 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" benötigte WAL-Dateien mit angegebener Methode einbeziehen\n" + +#: pg_basebackup.c:395 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip Tar-Ausgabe komprimieren\n" + +#: pg_basebackup.c:396 +#, c-format +msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 Tar-Ausgabe mit angegebenem Niveau komprimieren\n" + +#: pg_basebackup.c:397 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Allgemeine Optionen:\n" + +#: pg_basebackup.c:398 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" schnelles oder verteiltes Checkpointing einstellen\n" + +#: pg_basebackup.c:400 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot Replikations-Slot erzeugen\n" + +#: pg_basebackup.c:401 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=LABEL Backup-Label setzen\n" + +#: pg_basebackup.c:402 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean nach Fehlern nicht aufräumen\n" + +#: pg_basebackup.c:403 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_basebackup.c:404 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress Fortschrittsinformationen zeigen\n" + +#: pg_basebackup.c:405 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=SLOTNAME zu verwendender Replikations-Slot\n" + +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose »Verbose«-Modus\n" + +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_basebackup.c:408 +#, c-format +msgid "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" Algorithmus für Manifest-Prüfsummen\n" + +#: pg_basebackup.c:410 +#, c-format +msgid "" +" --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr "" +" --manifest-force-encode\n" +" alle Dateinamen im Manifest hex-kodieren\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr " --no-estimate-size nicht die Backup-Größe auf dem Server schätzen\n" + +#: pg_basebackup.c:413 +#, c-format +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr " --no-manifest kein Backup-Manifest erzeugen\n" + +#: pg_basebackup.c:414 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot keinen temporären Replikations-Slot erzeugen\n" + +#: pg_basebackup.c:415 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" Prüfsummen nicht überprüfen\n" + +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Verbindungsoptionen:\n" + +#: pg_basebackup.c:419 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=VERBDG Verbindungsparameter\n" + +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" + +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT Portnummer des Datenbankservers\n" + +#: pg_basebackup.c:422 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in seconds)\n" +msgstr "" +" -s, --status-interval=INTERVALL\n" +" Zeit zwischen an Server gesendeten Statuspaketen (in Sekunden)\n" + +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME Datenbankbenutzername\n" + +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password niemals nach Passwort fragen\n" + +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password nach Passwort fragen (sollte automatisch geschehen)\n" + +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: pg_basebackup.c:471 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "konnte nicht aus bereiter Pipe lesen: %m" + +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "konnte Write-Ahead-Log-Position »%s« nicht interpretieren" + +#: pg_basebackup.c:573 pg_receivewal.c:441 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "konnte WAL-Dateien nicht zu Ende schreiben: %m" + +#: pg_basebackup.c:620 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "konnte Pipe für Hintergrundprozess nicht erzeugen: %m" + +#: pg_basebackup.c:655 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "temporärer Replikations-Slot »%s« wurde erzeugt" + +#: pg_basebackup.c:658 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "Replikations-Slot »%s« wurde erzeugt" + +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not create background process: %m" +msgstr "konnte Hintergrundprozess nicht erzeugen: %m" + +#: pg_basebackup.c:708 +#, c-format +msgid "could not create background thread: %m" +msgstr "konnte Hintergrund-Thread nicht erzeugen: %m" + +#: pg_basebackup.c:752 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "Verzeichnis »%s« existiert aber ist nicht leer" + +#: pg_basebackup.c:759 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" + +#: pg_basebackup.c:824 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d Tablespace %*s" +msgstr[1] "%*s/%s kB (100%%), %d/%d Tablespaces %*s" + +#: pg_basebackup.c:836 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d Tablespace (%s%-*.*s)" +msgstr[1] "%*s/%s kB (%d%%), %d/%d Tablespaces (%s%-*.*s)" + +#: pg_basebackup.c:852 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d Tablespace" +msgstr[1] "%*s/%s kB (%d%%), %d/%d Tablespaces" + +#: pg_basebackup.c:877 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "Transferrate »%s« ist kein gültiger Wert" + +#: pg_basebackup.c:882 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "ungültige Transferrate »%s«: %m" + +#: pg_basebackup.c:891 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "Transferrate muss größer als null sein" + +#: pg_basebackup.c:923 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "ungültige Einheit für --max-rate: »%s«" + +#: pg_basebackup.c:930 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "Transferrate »%s« überschreitet Bereich für ganze Zahlen" + +#: pg_basebackup.c:940 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "Transferrate »%s« ist außerhalb des gültigen Bereichs" + +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "konnte COPY-Datenstrom nicht empfangen: %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:964 +#, c-format +msgid "could not read COPY data: %s" +msgstr "konnte COPY-Daten nicht lesen: %s" + +#: pg_basebackup.c:1007 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "konnte nicht in komprimierte Datei »%s« schreiben: %s" + +#: pg_basebackup.c:1071 +#, c-format +msgid "could not duplicate stdout: %m" +msgstr "konnte Standardausgabe nicht duplizieren: %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "konnte Ausgabedatei nicht öffnen: %m" + +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "konnte Komprimierungsniveau %d nicht setzen: %s" + +#: pg_basebackup.c:1155 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "konnte komprimierte Datei »%s« nicht erzeugen: %s" + +#: pg_basebackup.c:1267 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "konnte komprimierte Datei »%s« nicht schließen: %s" + +#: pg_basebackup.c:1279 pg_recvlogical.c:632 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schließen: %m" + +#: pg_basebackup.c:1541 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "COPY-Strom endete vor dem Ende der letzten Datei" + +#: pg_basebackup.c:1570 +#, c-format +msgid "invalid tar block header size: %zu" +msgstr "ungültige Tar-Block-Kopf-Größe: %zu" + +#: pg_basebackup.c:1627 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "konnte Zugriffsrechte für Verzeichnis »%s« nicht setzen: %m" + +#: pg_basebackup.c:1651 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "konnte symbolische Verknüpfung von »%s« nach »%s« nicht erzeugen: %m" + +#: pg_basebackup.c:1658 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "unbekannter Verknüpfungsindikator »%c«" + +#: pg_basebackup.c:1677 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "konnte Zugriffsrechte von Datei »%s« nicht setzen: %m" + +#: pg_basebackup.c:1831 +#, c-format +msgid "incompatible server version %s" +msgstr "inkompatible Serverversion %s" + +#: pg_basebackup.c:1846 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "TIPP: -X none oder -X fetch verwenden um Log-Streaming abzuschalten" + +#: pg_basebackup.c:1882 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "Basissicherung eingeleitet, warte auf Abschluss des Checkpoints" + +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:480 receivelog.c:529 +#: receivelog.c:568 streamutil.c:297 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "konnte Replikationsbefehl »%s« nicht senden: %s" + +#: pg_basebackup.c:1919 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "konnte Basissicherung nicht starten: %s" + +#: pg_basebackup.c:1925 +#, c-format +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "unerwartete Antwort auf Befehl BASE_BACKUP: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" + +#: pg_basebackup.c:1933 +#, c-format +msgid "checkpoint completed" +msgstr "Checkpoint abgeschlossen" + +#: pg_basebackup.c:1948 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "Write-Ahead-Log-Startpunkt: %s auf Zeitleiste %u" + +#: pg_basebackup.c:1957 +#, c-format +msgid "could not get backup header: %s" +msgstr "konnte Kopf der Sicherung nicht empfangen: %s" + +#: pg_basebackup.c:1963 +#, c-format +msgid "no data returned from server" +msgstr "keine Daten vom Server zurückgegeben" + +#: pg_basebackup.c:1995 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "kann nur einen einzelnen Tablespace auf die Standardausgabe schreiben, Datenbank hat %d" + +#: pg_basebackup.c:2007 +#, c-format +msgid "starting background WAL receiver" +msgstr "Hintergrund-WAL-Receiver wird gestartet" + +#: pg_basebackup.c:2046 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "konnte Write-Ahead-Log-Endposition nicht vom Server empfangen: %s" + +#: pg_basebackup.c:2052 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "keine Write-Ahead-Log-Endposition vom Server zurückgegeben" + +#: pg_basebackup.c:2057 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "Write-Ahead-Log-Endposition: %s" + +#: pg_basebackup.c:2068 +#, c-format +msgid "checksum error occurred" +msgstr "ein Prüfsummenfehler ist aufgetreten" + +#: pg_basebackup.c:2073 +#, c-format +msgid "final receive failed: %s" +msgstr "letztes Empfangen fehlgeschlagen: %s" + +#: pg_basebackup.c:2097 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "warte bis Hintergrundprozess Streaming beendet hat ..." + +#: pg_basebackup.c:2102 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "konnte Befehl nicht an Hintergrund-Pipe senden: %m" + +#: pg_basebackup.c:2110 +#, c-format +msgid "could not wait for child process: %m" +msgstr "konnte nicht auf Kindprozess warten: %m" + +#: pg_basebackup.c:2115 +#, c-format +msgid "child %d died, expected %d" +msgstr "Kindprozess %d endete, aber %d wurde erwartet" + +#: pg_basebackup.c:2120 streamutil.c:92 streamutil.c:203 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2145 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "konnte nicht auf Kind-Thread warten: %m" + +#: pg_basebackup.c:2151 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "konnte Statuscode des Kind-Threads nicht ermitteln: %m" + +#: pg_basebackup.c:2156 +#, c-format +msgid "child thread exited with error %u" +msgstr "Kind-Thread hat mit Fehler %u beendet" + +#: pg_basebackup.c:2184 +#, c-format +msgid "syncing data to disk ..." +msgstr "synchronisiere Daten auf Festplatte ..." + +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "umbenennen von backup_manifest.tmp nach backup_manifest" + +#: pg_basebackup.c:2220 +#, c-format +msgid "base backup completed" +msgstr "Basissicherung abgeschlossen" + +#: pg_basebackup.c:2305 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" +msgstr "ungültiges Ausgabeformat »%s«, muss »plain« oder »tar« sein" + +#: pg_basebackup.c:2349 +#, c-format +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "ungültige Option »%s« für --wal-method, muss »fetch«, »stream« oder »none« sein" + +#: pg_basebackup.c:2377 pg_receivewal.c:580 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "ungültiges Komprimierungsniveau »%s«" + +#: pg_basebackup.c:2388 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "ungültiges Checkpoint-Argument »%s«, muss »fast« oder »spread« sein" + +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "ungültiges Statusintervall »%s«" + +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2528 +#: pg_basebackup.c:2539 pg_basebackup.c:2549 pg_basebackup.c:2567 +#: pg_basebackup.c:2576 pg_basebackup.c:2585 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_basebackup.c:2468 pg_receivewal.c:654 +#, c-format +msgid "no target directory specified" +msgstr "kein Zielverzeichnis angegeben" + +#: pg_basebackup.c:2479 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "nur Sicherungen im Tar-Modus können komprimiert werden" + +#: pg_basebackup.c:2487 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "im Tar-Modus können Write-Ahead-Logs nicht auf Standardausgabe geschrieben werden" + +#: pg_basebackup.c:2495 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "Replikations-Slots können nur mit WAL-Streaming verwendet werden" + +#: pg_basebackup.c:2505 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot kann nicht zusammen mit einem Slot-Namen verwendet werden" + +#. translator: second %s is an option name +#: pg_basebackup.c:2517 pg_receivewal.c:634 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "für %s muss ein Slot mit --slot angegeben werden" + +#: pg_basebackup.c:2526 pg_basebackup.c:2565 pg_basebackup.c:2574 +#: pg_basebackup.c:2583 +#, c-format +msgid "%s and %s are incompatible options" +msgstr "%s und %s sind inkompatible Optionen" + +#: pg_basebackup.c:2538 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "WAL-Verzeichnis kann nur im »plain«-Modus angegeben werden" + +#: pg_basebackup.c:2548 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WAL-Verzeichnis muss absoluten Pfad haben" + +#: pg_basebackup.c:2558 pg_receivewal.c:663 +#, c-format +msgid "this build does not support compression" +msgstr "diese Installation unterstützt keine Komprimierung" + +#: pg_basebackup.c:2643 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" + +#: pg_basebackup.c:2647 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt" + +#: pg_receivewal.c:77 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s empfängt PostgreSQL-Write-Ahead-Logs.\n" +"\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:81 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Optionen:\n" + +#: pg_receivewal.c:82 +#, c-format +msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr " -D, --directory=VERZ Write-Ahead-Log-Dateien in dieses Verzeichnis empfangen\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:82 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN nach Empfang der angegebenen LSN beenden\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:86 +#, c-format +msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgstr " --if-not-exists keinen Fehler ausgeben, wenn Slot beim Erzeugen schon existiert\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:88 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop bei Verbindungsverlust nicht erneut probieren\n" + +#: pg_receivewal.c:86 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:93 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server (default: %d)\n" +msgstr "" +" -s, --status-interval=SEK\n" +" Zeit zwischen an Server gesendeten Statuspaketen (Standard: %d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid " --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous Write-Ahead-Log sofort nach dem Schreiben flushen\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 Logs mit angegebenem Niveau komprimieren\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"Optionale Aktionen:\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:78 +#, c-format +msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgstr " --create-slot neuen Replikations-Slot erzeugen (Slot-Name siehe --slot)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:79 +#, c-format +msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgstr " --drop-slot Replikations-Slot löschen (Slot-Name siehe --slot)\n" + +#: pg_receivewal.c:117 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "Segment bei %X/%X abgeschlossen (Zeitleiste %u)" + +#: pg_receivewal.c:124 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "Log-Streaming gestoppt bei %X/%X (Zeitleiste %u)" + +#: pg_receivewal.c:140 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "auf Zeitleiste %u umgeschaltet bei %X/%X" + +#: pg_receivewal.c:150 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "Interrupt-Signal erhalten, beende" + +#: pg_receivewal.c:186 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" + +#: pg_receivewal.c:272 +#, c-format +msgid "segment file \"%s\" has incorrect size %lld, skipping" +msgstr "Segmentdatei »%s« hat falsche Größe %lld, wird übersprungen" + +#: pg_receivewal.c:290 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "konnte komprimierte Datei »%s« nicht öffnen: %m" + +#: pg_receivewal.c:296 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "konnte Positionszeiger in komprimierter Datei »%s« nicht setzen: %m" + +#: pg_receivewal.c:304 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "konnte komprimierte Datei »%s« nicht lesen: %m" + +#: pg_receivewal.c:307 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" + +#: pg_receivewal.c:318 +#, c-format +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "komprimierte Segmentdatei »%s« hat falsche unkomprimierte Größe %d, wird übersprungen" + +#: pg_receivewal.c:422 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "starte Log-Streaming bei %X/%X (Zeitleiste %u)" + +#: pg_receivewal.c:537 pg_recvlogical.c:762 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "ungültige Portnummer »%s«" + +#: pg_receivewal.c:565 pg_recvlogical.c:788 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "konnte Endposition »%s« nicht parsen" + +#: pg_receivewal.c:625 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "--create-slot kann nicht zusammen mit --drop-slot verwendet werden" + +#: pg_receivewal.c:643 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "--synchronous kann nicht zusammen mit --no-sync verwendet werden" + +#: pg_receivewal.c:719 +#, c-format +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "Replikationsverbindung, die Slot »%s« verwendet, ist unerwarteterweise datenbankspezifisch" + +#: pg_receivewal.c:730 pg_recvlogical.c:966 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "lösche Replikations-Slot »%s«" + +#: pg_receivewal.c:741 pg_recvlogical.c:976 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "erzeuge Replikations-Slot »%s«" + +#: pg_receivewal.c:767 pg_recvlogical.c:1001 +#, c-format +msgid "disconnected" +msgstr "Verbindung beendet" + +#. translator: check source for value for %d +#: pg_receivewal.c:773 pg_recvlogical.c:1007 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "Verbindung beendet; erneuter Versuch in %d Sekunden" + +#: pg_recvlogical.c:73 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s kontrolliert logische Dekodierungsströme von PostgreSQL.\n" +"\n" + +#: pg_recvlogical.c:77 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"Auszuführende Aktion:\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgstr " --start Streaming in einem Replikations-Slot starten (Slot-Name siehe --slot)\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=DATEI Log in diese Datei empfangen, - für Standardausgabe\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: %d)\n" +msgstr "" +" -F --fsync-interval=SEK\n" +" Zeit zwischen Fsyncs der Ausgabedatei (Standard: %d)\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgstr " -I, --startpos=LSN wo in einem bestehenden Slot das Streaming starten soll\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NAME[=WERT]\n" +" Option NAME mit optionalem Wert WERT an den\n" +" Ausgabe-Plugin übergeben\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr " -P, --plugin=PLUGIN Ausgabe-Plugin PLUGIN verwenden (Standard: %s)\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=SLOTNAME Name des logischen Replikations-Slots\n" + +#: pg_recvlogical.c:100 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=DBNAME Datenbank, mit der verbunden werden soll\n" + +#: pg_recvlogical.c:133 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "bestätige Schreiben bis %X/%X, Flush bis %X/%X (Slot %s)" + +#: pg_recvlogical.c:157 receivelog.c:342 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "konnte Rückmeldungspaket nicht senden: %s" + +#: pg_recvlogical.c:230 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "starte Log-Streaming bei %X/%X (Slot %s)" + +#: pg_recvlogical.c:271 +#, c-format +msgid "streaming initiated" +msgstr "Streaming eingeleitet" + +#: pg_recvlogical.c:335 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "konnte Logdatei »%s« nicht öffnen: %m" + +#: pg_recvlogical.c:361 receivelog.c:872 +#, c-format +msgid "invalid socket: %s" +msgstr "ungültiges Socket: %s" + +#: pg_recvlogical.c:414 receivelog.c:900 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() fehlgeschlagen: %m" + +#: pg_recvlogical.c:421 receivelog.c:950 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "konnte keine Daten vom WAL-Stream empfangen: %s" + +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:994 receivelog.c:1060 +#, c-format +msgid "streaming header too small: %d" +msgstr "Streaming-Header zu klein: %d" + +#: pg_recvlogical.c:498 receivelog.c:832 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "unbekannter Streaming-Header: »%c«" + +#: pg_recvlogical.c:552 pg_recvlogical.c:564 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "konnte %u Bytes nicht in Logdatei »%s« schreiben: %m" + +#: pg_recvlogical.c:618 receivelog.c:628 receivelog.c:665 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "unerwarteter Abbruch des Replikations-Streams: %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "ungültiges Fsync-Intervall »%s«" + +#: pg_recvlogical.c:780 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "konnte Startposition »%s« nicht parsen" + +#: pg_recvlogical.c:869 +#, c-format +msgid "no slot specified" +msgstr "kein Slot angegeben" + +#: pg_recvlogical.c:877 +#, c-format +msgid "no target file specified" +msgstr "keine Zieldatei angegeben" + +#: pg_recvlogical.c:885 +#, c-format +msgid "no database specified" +msgstr "keine Datenbank angegeben" + +#: pg_recvlogical.c:893 +#, c-format +msgid "at least one action needs to be specified" +msgstr "mindestens eine Aktion muss angegeben werden" + +#: pg_recvlogical.c:901 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "--create-slot oder --start kann nicht zusammen mit --drop-slot verwendet werden" + +#: pg_recvlogical.c:909 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "--create-slot oder --drop-slot kann nicht zusammen mit --startpos verwendet werden" + +#: pg_recvlogical.c:917 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos kann nur zusammen mit --start angegeben werden" + +#: pg_recvlogical.c:948 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "konnte keine datenbankspezifische Replikationsverbindung herstellen" + +#: pg_recvlogical.c:1047 +#, c-format +msgid "end position %X/%X reached by keepalive" +msgstr "Endposition %X/%X durch Keepalive erreicht" + +#: pg_recvlogical.c:1050 +#, c-format +msgid "end position %X/%X reached by WAL record at %X/%X" +msgstr "Endposition %X/%X erreicht durch WAL-Eintrag bei %X/%X" + +#: receivelog.c:68 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "konnte Archivstatusdatei »%s« nicht erstellen: %s" + +#: receivelog.c:115 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "konnte Größe der Write-Ahead-Log-Datei »%s« nicht ermittlen: %s" + +#: receivelog.c:125 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "konnte bestehende Write-Ahead-Log-Datei »%s« nicht öffnen: %s" + +#: receivelog.c:133 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "konnte bestehende Write-Ahead-Log-Datei »%s« nicht fsyncen: %s" + +#: receivelog.c:147 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "Write-Ahead-Log-Datei »%s« hat %d Byte, sollte 0 oder %d sein" +msgstr[1] "Write-Ahead-Log-Datei »%s« hat %d Bytes, sollte 0 oder %d sein" + +#: receivelog.c:162 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "konnte Write-Ahead-Log-Datei »%s« nicht öffnen: %s" + +#: receivelog.c:188 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "konnte Positionszeiger in Datei »%s« nicht ermitteln: %s" + +#: receivelog.c:202 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "»%s%s« wird nicht umbenannt, Segment ist noch nicht vollständig" + +#: receivelog.c:214 receivelog.c:299 receivelog.c:674 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "konnte Datei »%s« nicht schließen: %s" + +#: receivelog.c:271 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "Server berichtete unerwarteten History-Dateinamen für Zeitleiste %u: %s" + +#: receivelog.c:279 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "konnte Zeitleisten-History-Datei »%s« nicht erzeugen: %s" + +#: receivelog.c:286 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "konnte Zeitleisten-History-Datei »%s« nicht schreiben: %s" + +#: receivelog.c:376 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen älter als %s" + +#: receivelog.c:385 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen neuer als %s" + +#: receivelog.c:487 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet" + +#: receivelog.c:494 +#, c-format +msgid "system identifier does not match between base backup and streaming connection" +msgstr "Systemidentifikator stimmt nicht zwischen Basissicherung und Streaming-Verbindung überein" + +#: receivelog.c:500 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "Startzeitleiste %u ist auf dem Server nicht vorhanden" + +#: receivelog.c:541 +#, c-format +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "unerwartete Antwort auf Befehl TIMELINE_HISTORY: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" + +#: receivelog.c:612 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "Server berichtete unerwartete nächste Zeitleiste %u, folgend auf Zeitleiste %u" + +#: receivelog.c:618 +#, c-format +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "Server beendete Streaming von Zeitleiste %u bei %X/%X, aber gab an, dass nächste Zeitleiste %u bei %X/%X beginnt" + +#: receivelog.c:658 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "Replikationsstrom wurde vor Stopppunkt abgebrochen" + +#: receivelog.c:704 +#, c-format +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "unerwartete Ergebnismenge nach Ende der Zeitleiste: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" + +#: receivelog.c:713 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "konnte Startpunkt der nächsten Zeitleiste (»%s«) nicht interpretieren" + +#: receivelog.c:762 receivelog.c:1014 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "konnte Datei »%s« nicht fsyncen: %s" + +#: receivelog.c:1077 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "Write-Ahead-Log-Eintrag für Offset %u erhalten ohne offene Datei" + +#: receivelog.c:1087 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "WAL-Daten-Offset %08x erhalten, %08x erwartet" + +#: receivelog.c:1121 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "konnte %u Bytes nicht in WAL-Datei »%s« schreiben: %s" + +#: receivelog.c:1146 receivelog.c:1186 receivelog.c:1216 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "konnte COPY-Ende-Paket nicht senden: %s" + +#: streamutil.c:162 +msgid "Password: " +msgstr "Passwort: " + +#: streamutil.c:186 +#, c-format +msgid "could not connect to server" +msgstr "konnte nicht mit Server verbinden" + +#: streamutil.c:231 +#, c-format +msgid "could not clear search_path: %s" +msgstr "konnte search_path nicht auf leer setzen: %s" + +#: streamutil.c:247 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "konnte Servereinstellung für integer_datetimes nicht ermitteln" + +#: streamutil.c:254 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "Kompilieroption »integer_datetimes« stimmt nicht mit Server überein" + +#: streamutil.c:305 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "konnte WAL-Segmentgröße nicht ermitteln: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet" + +#: streamutil.c:315 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "WAL-Segmentgröße konnte nicht interpretiert werden" + +#: streamutil.c:333 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Server gab einen Wert von %d Byte an" +msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Server gab einen Wert von %d Bytes an" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "konnte Gruppenzugriffseinstellung nicht ermitteln: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "Gruppenzugriffseinstellung konnte nicht interpretiert werden: %s" + +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "konnte Replikations-Slot »%s« nicht löschen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" + +#: walmethods.c:438 walmethods.c:932 +msgid "could not compress data" +msgstr "konnte Daten nicht komprimieren" + +#: walmethods.c:470 +msgid "could not reset compression stream" +msgstr "konnte Komprimierungsstrom nicht zurücksetzen" + +#: walmethods.c:568 +msgid "could not initialize compression library" +msgstr "konnte Komprimierungsbibliothek nicht initialisieren" + +#: walmethods.c:580 +msgid "implementation error: tar files can't have more than one open file" +msgstr "Implementierungsfehler: Tar-Dateien können nicht mehr als eine offene Datei haben" + +#: walmethods.c:594 +msgid "could not create tar header" +msgstr "konnte Tar-Dateikopf nicht erzeugen" + +#: walmethods.c:608 walmethods.c:650 walmethods.c:847 walmethods.c:859 +msgid "could not change compression parameters" +msgstr "konnte Komprimierungsparameter nicht ändern" + +#: walmethods.c:734 +msgid "unlink not supported with compression" +msgstr "Unlink wird bei Komprimierung nicht unterstützt" + +#: walmethods.c:957 +msgid "could not close compression stream" +msgstr "konnte Komprimierungsstrom nicht schließen" diff --git a/src/bin/pg_basebackup/po/es.po b/src/bin/pg_basebackup/po/es.po new file mode 100644 index 000000000000..67c472c95992 --- /dev/null +++ b/src/bin/pg_basebackup/po/es.po @@ -0,0 +1,1496 @@ +# Spanish message translation file for pg_basebackup +# +# Copyright (c) 2011-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Álvaro Herrera , 2011-2014. +# Carlos Chapi , 2017-2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_basebackup (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:46+0000\n" +"PO-Revision-Date: 2021-05-20 21:24-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../../common/file_utils.c:87 ../../common/file_utils.c:451 +#: pg_receivewal.c:266 pg_recvlogical.c:340 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: ../../common/file_utils.c:166 pg_receivewal.c:169 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: ../../common/file_utils.c:200 pg_receivewal.c:337 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" + +#: ../../common/file_utils.c:232 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:134 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: ../../common/file_utils.c:303 ../../common/file_utils.c:373 +#: pg_recvlogical.c:193 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" + +#: ../../common/file_utils.c:383 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "no se pudo renombrar el archivo de «%s» a «%s»: %m" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "no se pudo escribir a archivo «%s»: %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "no se pudo crear archivo «%s»: %m" + +#: pg_basebackup.c:224 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "eliminando el directorio de datos «%s»" + +#: pg_basebackup.c:226 +#, c-format +msgid "failed to remove data directory" +msgstr "no se pudo eliminar el directorio de datos" + +#: pg_basebackup.c:230 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "eliminando el contenido del directorio «%s»" + +#: pg_basebackup.c:232 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "no se pudo eliminar el contenido del directorio de datos" + +#: pg_basebackup.c:237 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "eliminando el directorio de WAL «%s»" + +#: pg_basebackup.c:239 +#, c-format +msgid "failed to remove WAL directory" +msgstr "no se pudo eliminar el directorio de WAL" + +#: pg_basebackup.c:243 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "eliminando el contenido del directorio de WAL «%s»" + +#: pg_basebackup.c:245 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "no se pudo eliminar el contenido del directorio de WAL" + +#: pg_basebackup.c:251 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "directorio de datos «%s» no eliminado a petición del usuario" + +#: pg_basebackup.c:254 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "directorio de WAL «%s» no eliminado a petición del usuario" + +#: pg_basebackup.c:258 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "los cambios a los directorios de tablespaces no se desharán" + +#: pg_basebackup.c:299 +#, c-format +msgid "directory name too long" +msgstr "nombre de directorio demasiado largo" + +#: pg_basebackup.c:309 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "múltiples signos «=» en mapeo de tablespace" + +#: pg_basebackup.c:321 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "formato de mapeo de tablespace «%s» no válido, debe ser «ANTIGUO=NUEVO»" + +#: pg_basebackup.c:333 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "directorio antiguo no es una ruta absoluta en mapeo de tablespace: %s" + +#: pg_basebackup.c:340 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "directorio nuevo no es una ruta absoluta en mapeo de tablespace: %s" + +#: pg_basebackup.c:379 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s obtiene un respaldo base a partir de un servidor PostgreSQL en ejecución.\n" +"\n" + +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPCIÓN]...\n" + +#: pg_basebackup.c:383 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"Opciones que controlan la salida:\n" + +#: pg_basebackup.c:384 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=DIR directorio en el cual recibir el respaldo base\n" + +#: pg_basebackup.c:385 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t formato de salida (plano (por omisión), tar)\n" + +#: pg_basebackup.c:386 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=TASA máxima tasa a la que transferir el directorio de datos\n" +" (en kB/s, o use sufijos «k» o «M»)\n" + +#: pg_basebackup.c:388 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" escribe configuración para replicación\n" + +#: pg_basebackup.c:390 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=ANTIGUO=NUEVO\n" +" reubicar el directorio de tablespace de ANTIGUO a NUEVO\n" + +#: pg_basebackup.c:392 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=DIRWAL ubicación para el directorio WAL\n" + +#: pg_basebackup.c:393 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" incluye los archivos WAL necesarios,\n" +" en el modo especificado\n" + +#: pg_basebackup.c:395 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip comprimir la salida de tar\n" + +#: pg_basebackup.c:396 +#, c-format +msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 comprimir salida tar con el nivel de compresión dado\n" + +#: pg_basebackup.c:397 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Opciones generales:\n" + +#: pg_basebackup.c:398 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" utilizar checkpoint rápido o extendido\n" + +#: pg_basebackup.c:400 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot crear un slot de replicación\n" + +#: pg_basebackup.c:401 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=ETIQUETA establecer etiqueta del respaldo\n" + +#: pg_basebackup.c:402 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean no hacer limpieza tras errores\n" + +#: pg_basebackup.c:403 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_basebackup.c:404 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress mostrar información de progreso\n" + +#: pg_basebackup.c:405 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=NOMBRE slot de replicación a usar\n" + +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose desplegar mensajes verbosos\n" + +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión, luego salir\n" + +#: pg_basebackup.c:408 +#, c-format +msgid "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" usar algoritmo para sumas de comprobación del manifiesto\n" + +#: pg_basebackup.c:410 +#, c-format +msgid "" +" --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr "" +" --manifest-force-encode\n" +" codifica a hexadecimal todos los nombres de archivo en el manifiesto\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr " --no-estimate-size no estimar el tamaño del la copia de seguridad en el lado del servidor\n" + +#: pg_basebackup.c:413 +#, c-format +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr " --no-manifest suprimir la generación del manifiesto de la copia de seguridad\n" + +#: pg_basebackup.c:414 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot evitar la creación de un slot de replicación temporal\n" + +#: pg_basebackup.c:415 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" no verificar checksums\n" + +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda, luego salir\n" + +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Opciones de conexión:\n" + +#: pg_basebackup.c:419 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONSTR cadena de conexión\n" + +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=ANFITRIÓN dirección del servidor o directorio del socket\n" + +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT número de port del servidor\n" + +#: pg_basebackup.c:422 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in seconds)\n" +msgstr "" +" -s, --status-interval=INTERVALO (segundos)\n" +" tiempo entre envíos de paquetes de estado al servidor\n" + +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NOMBRE conectarse con el usuario especificado\n" + +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password nunca pedir contraseña\n" + +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr "" +" -W, --password forzar un prompt para la contraseña\n" +" (debería ser automático)\n" + +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_basebackup.c:471 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "no se pudo leer desde la tubería: %m" + +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "no se pudo interpretar la ubicación del WAL «%s»" + +#: pg_basebackup.c:573 pg_receivewal.c:441 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "no se pudo completar la escritura de archivos WAL: %m" + +#: pg_basebackup.c:620 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "no se pudo crear la tubería para el proceso en segundo plano: %m" + +#: pg_basebackup.c:655 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "se creó slot temporal de replicación «%s»" + +#: pg_basebackup.c:658 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "se creó el slot de replicación «%s»" + +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not create background process: %m" +msgstr "no se pudo lanzar el proceso en segundo plano: %m" + +#: pg_basebackup.c:708 +#, c-format +msgid "could not create background thread: %m" +msgstr "no se pudo lanzar el hilo en segundo plano: %m" + +#: pg_basebackup.c:752 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "el directorio «%s» existe pero no está vacío" + +#: pg_basebackup.c:759 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "no se pudo acceder al directorio «%s»: %m" + +#: pg_basebackup.c:824 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgstr[1] "%*s/%s kB (100%%), %d/%d tablespaces %*s" + +#: pg_basebackup.c:836 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" + +#: pg_basebackup.c:852 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace" +msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespaces" + +#: pg_basebackup.c:877 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "tasa de transferencia «%s» no es un valor válido" + +#: pg_basebackup.c:882 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "tasa de transferencia «%s» no válida: %m" + +#: pg_basebackup.c:891 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "tasa de transferencia debe ser mayor que cero" + +#: pg_basebackup.c:923 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "unidad de --max-rato no válida: «%s»" + +#: pg_basebackup.c:930 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "la tasa de transferencia «%s» excede el rango de enteros" + +#: pg_basebackup.c:940 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "la tasa de transferencia «%s» está fuera de rango" + +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "no se pudo obtener un flujo de datos COPY: %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:964 +#, c-format +msgid "could not read COPY data: %s" +msgstr "no fue posible leer datos COPY: %s" + +#: pg_basebackup.c:1007 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "no se pudo escribir al archivo comprimido «%s»: %s" + +#: pg_basebackup.c:1071 +#, c-format +msgid "could not duplicate stdout: %m" +msgstr "no se pudo duplicar stdout: %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "no se pudo abrir el archivo de salida: %m" + +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "no se pudo definir el nivel de compresión %d: %s" + +#: pg_basebackup.c:1155 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "no se pudo crear el archivo comprimido «%s»: %s" + +#: pg_basebackup.c:1267 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "no se pudo cerrar el archivo comprimido «%s»: %s" + +#: pg_basebackup.c:1279 pg_recvlogical.c:632 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" + +#: pg_basebackup.c:1541 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "el flujo COPY terminó antes que el último archivo estuviera completo" + +#: pg_basebackup.c:1570 +#, c-format +msgid "invalid tar block header size: %zu" +msgstr "tamaño de bloque de cabecera de tar no válido: %zu" + +#: pg_basebackup.c:1627 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "no se pudo definir los permisos del directorio «%s»: %m" + +#: pg_basebackup.c:1651 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "no se pudo crear un enlace simbólico desde «%s» a «%s»: %m" + +#: pg_basebackup.c:1658 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "indicador de enlace «%c» no reconocido" + +#: pg_basebackup.c:1677 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "no se pudo definir los permisos al archivo «%s»: %m" + +#: pg_basebackup.c:1831 +#, c-format +msgid "incompatible server version %s" +msgstr "versión del servidor %s incompatible" + +#: pg_basebackup.c:1846 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "SUGERENCIA: use -X none o -X fetch para deshabilitar el flujo de log" + +#: pg_basebackup.c:1882 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "iniciando el respaldo base, esperando que el checkpoint se complete" + +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:480 receivelog.c:529 +#: receivelog.c:568 streamutil.c:297 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "no se pudo ejecutar la orden de replicación «%s»: %s" + +#: pg_basebackup.c:1919 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "no se pudo iniciar el respaldo base: %s" + +#: pg_basebackup.c:1925 +#, c-format +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "el servidor envió una respuesta inesperada a la orden BASE_BACKUP; se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" + +#: pg_basebackup.c:1933 +#, c-format +msgid "checkpoint completed" +msgstr "el checkpoint se ha completado" + +#: pg_basebackup.c:1948 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "punto de inicio del WAL: %s en el timeline %u" + +#: pg_basebackup.c:1957 +#, c-format +msgid "could not get backup header: %s" +msgstr "no se pudo obtener la cabecera de respaldo: %s" + +#: pg_basebackup.c:1963 +#, c-format +msgid "no data returned from server" +msgstr "el servidor no retornó datos" + +#: pg_basebackup.c:1995 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "sólo se puede escribir un tablespace a stdout, la base de datos tiene %d" + +#: pg_basebackup.c:2007 +#, c-format +msgid "starting background WAL receiver" +msgstr "iniciando el receptor de WAL en segundo plano" + +#: pg_basebackup.c:2046 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "no se pudo obtener la posición final del WAL del servidor: %s" + +#: pg_basebackup.c:2052 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "el servidor no retornó la posición final del WAL" + +#: pg_basebackup.c:2057 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "posición final del WAL: %s" + +#: pg_basebackup.c:2068 +#, c-format +msgid "checksum error occurred" +msgstr "ocurrió un error de checksums" + +#: pg_basebackup.c:2073 +#, c-format +msgid "final receive failed: %s" +msgstr "la recepción final falló: %s" + +#: pg_basebackup.c:2097 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "esperando que el proceso en segundo plano complete el flujo..." + +#: pg_basebackup.c:2102 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "no se pudo enviar una orden a la tubería de segundo plano: %m" + +#: pg_basebackup.c:2110 +#, c-format +msgid "could not wait for child process: %m" +msgstr "no se pudo esperar al proceso hijo: %m" + +#: pg_basebackup.c:2115 +#, c-format +msgid "child %d died, expected %d" +msgstr "el hijo %d murió, pero se esperaba al %d" + +#: pg_basebackup.c:2120 streamutil.c:92 streamutil.c:203 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2145 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "no se pudo esperar el hilo hijo: %m" + +#: pg_basebackup.c:2151 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "no se pudo obtener la cabecera de respaldo: %m" + +#: pg_basebackup.c:2156 +#, c-format +msgid "child thread exited with error %u" +msgstr "el hilo hijo terminó con error %u" + +#: pg_basebackup.c:2184 +#, c-format +msgid "syncing data to disk ..." +msgstr "sincronizando datos a disco ..." + +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "renombrando backup_manifest.tmp a backup_manifest" + +#: pg_basebackup.c:2220 +#, c-format +msgid "base backup completed" +msgstr "el respaldo base se ha completado" + +#: pg_basebackup.c:2305 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" +msgstr "formato de salida «%s» no válido, debe ser «plain» o «tar»" + +#: pg_basebackup.c:2349 +#, c-format +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "opción de wal-method «%s» no válida, debe ser «fetch», «stream» o «none»" + +#: pg_basebackup.c:2377 pg_receivewal.c:580 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "valor de compresión «%s» no válido" + +#: pg_basebackup.c:2388 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "argumento de checkpoint «%s» no válido, debe ser «fast» o «spread»" + +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "intervalo de estado «%s» no válido" + +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2528 +#: pg_basebackup.c:2539 pg_basebackup.c:2549 pg_basebackup.c:2567 +#: pg_basebackup.c:2576 pg_basebackup.c:2585 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Use «%s --help» para obtener más información.\n" + +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_basebackup.c:2468 pg_receivewal.c:654 +#, c-format +msgid "no target directory specified" +msgstr "no se especificó un directorio de salida" + +#: pg_basebackup.c:2479 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "sólo los respaldos de modo tar pueden ser comprimidos" + +#: pg_basebackup.c:2487 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "no se puede enviar WALs en modo tar a stdout" + +#: pg_basebackup.c:2495 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "los slots de replicación sólo pueden usarse con flujo de WAL" + +#: pg_basebackup.c:2505 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "no se puede usar --no-slot junto con nombre de slot" + +#. translator: second %s is an option name +#: pg_basebackup.c:2517 pg_receivewal.c:634 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "la opcón %s necesita que se especifique un slot con --slot" + +#: pg_basebackup.c:2526 pg_basebackup.c:2565 pg_basebackup.c:2574 +#: pg_basebackup.c:2583 +#, c-format +msgid "%s and %s are incompatible options" +msgstr "%s y %s son opciones incompatibles" + +#: pg_basebackup.c:2538 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "la ubicación del directorio de WAL sólo puede especificarse en modo «plain»" + +#: pg_basebackup.c:2548 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "la ubicación del directorio de WAL debe ser una ruta absoluta" + +#: pg_basebackup.c:2558 pg_receivewal.c:663 +#, c-format +msgid "this build does not support compression" +msgstr "esta instalación no soporta compresión" + +#: pg_basebackup.c:2643 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "no se pudo crear el enlace simbólico «%s»: %m" + +#: pg_basebackup.c:2647 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "los enlaces simbólicos no están soportados en esta plataforma" + +#: pg_receivewal.c:77 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s recibe flujos del WAL de PostgreSQL.\n" +"\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:81 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Opciones:\n" + +#: pg_receivewal.c:82 +#, c-format +msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr " -D, --directory=DIR recibir los archivos de WAL en este directorio\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:82 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN salir luego de recibir el LSN especificado\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:86 +#, c-format +msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgstr " --if-not-exists no abandonar si el slot ya existe al crear un slot\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:88 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop no entrar en bucle al perder la conexión\n" + +#: pg_receivewal.c:86 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:93 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server (default: %d)\n" +msgstr "" +" -s, --status-interval=SECS\n" +" tiempo entre envíos de paquetes de estado al servidor\n" +" (por omisión: %d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid " --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous sincronizar el WAL inmediatamente después de escribir\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 comprimir los segmentos con el nivel de compresión especificado\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"Acciones optativas:\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:78 +#, c-format +msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgstr " --create-slot crear un nuevo slot de replicación (para el nombre, vea --slot)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:79 +#, c-format +msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgstr " --drop-slot eliminar un slot de replicación (para el nombre, vea --slot)\n" + +#: pg_receivewal.c:117 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "terminó el segmento en %X/%X (timeline %u)" + +#: pg_receivewal.c:124 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "detenido el flujo de log en %X/%X (timeline %u)" + +#: pg_receivewal.c:140 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "cambiado al timeline %u en %X/%X" + +#: pg_receivewal.c:150 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "se recibió una señal de interrupción, saliendo" + +#: pg_receivewal.c:186 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_receivewal.c:272 +#, c-format +msgid "segment file \"%s\" has incorrect size %lld, skipping" +msgstr "el archivo de segmento «%s» tiene tamaño incorrecto %lld, ignorando" + +#: pg_receivewal.c:290 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "no se pudo abrir el archivo comprimido «%s»: %m" + +#: pg_receivewal.c:296 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "no se pudo buscar en el archivo comprimido «%s»: %m" + +#: pg_receivewal.c:304 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "no se pudo leer el archivo comprimido «%s»: %m" + +#: pg_receivewal.c:307 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo comprimido «%s»: leídos %d de %zu" + +#: pg_receivewal.c:318 +#, c-format +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "el archivo de segmento «%s» tiene tamaño incorrecto %d al descomprimirse, ignorando" + +#: pg_receivewal.c:422 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "iniciando el flujo de log en %X/%X (timeline %u)" + +#: pg_receivewal.c:537 pg_recvlogical.c:762 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "número de puerto «%s» no válido" + +#: pg_receivewal.c:565 pg_recvlogical.c:788 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "no se pudo interpretar la posición final «%s»" + +#: pg_receivewal.c:625 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "no puede usarse --create-slot junto con --drop-slot" + +#: pg_receivewal.c:643 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "no puede usarse --synchronous junto con --no-sync" + +#: pg_receivewal.c:719 +#, c-format +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "la conexión de replicación usando el slot «%s» es inesperadamente específica a una base de datos" + +#: pg_receivewal.c:730 pg_recvlogical.c:966 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "eliminando el slot de replicación «%s»" + +#: pg_receivewal.c:741 pg_recvlogical.c:976 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "creando el slot de replicación «%s»" + +#: pg_receivewal.c:767 pg_recvlogical.c:1001 +#, c-format +msgid "disconnected" +msgstr "desconectado" + +#. translator: check source for value for %d +#: pg_receivewal.c:773 pg_recvlogical.c:1007 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "desconectado; esperando %d segundos para intentar nuevamente" + +#: pg_recvlogical.c:73 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s controla flujos de decodificación lógica de PostgreSQL.\n" +"\n" + +#: pg_recvlogical.c:77 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"Acciones a ejecutar:\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgstr " --start iniciar flujo en un slot de replicación (para el nombre, vea --slot)\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=ARCHIVO recibir el log en este archivo, - para stdout\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: %d)\n" +msgstr "" +" -F, --fsync-interval=SEGS\n" +" tiempo entre fsyncs del archivo de salida (omisión: %d)\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgstr " -I, --startpos=LSN dónde en un slot existente debe empezar el flujo\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NOMBRE[=VALOR]\n" +" pasar opción NOMBRE con valor opcional VALOR al\n" +" plugin de salida\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr " -P, --plugin=PLUGIN usar plug-in de salida PLUGIN (omisión: %s)\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=NOMBRE-SLOT nombre del slot de replicación lógica\n" + +#: pg_recvlogical.c:100 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=BASE base de datos a la cual conectarse\n" + +#: pg_recvlogical.c:133 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "confirmando escritura hasta %X/%X, fsync hasta %X/%X (slot %s)" + +#: pg_recvlogical.c:157 receivelog.c:342 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "no se pudo enviar el paquete de retroalimentación: %s" + +#: pg_recvlogical.c:230 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "iniciando el flujo de log en %X/%X (slot %s)" + +#: pg_recvlogical.c:271 +#, c-format +msgid "streaming initiated" +msgstr "flujo iniciado" + +#: pg_recvlogical.c:335 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "no se pudo abrir el archivo de registro «%s»: %m" + +#: pg_recvlogical.c:361 receivelog.c:872 +#, c-format +msgid "invalid socket: %s" +msgstr "el socket no es válido: %s" + +#: pg_recvlogical.c:414 receivelog.c:900 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() falló: %m" + +#: pg_recvlogical.c:421 receivelog.c:950 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "no se pudo recibir datos desde el flujo de WAL: %s" + +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:994 receivelog.c:1060 +#, c-format +msgid "streaming header too small: %d" +msgstr "cabecera de flujo demasiado pequeña: %d" + +#: pg_recvlogical.c:498 receivelog.c:832 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "cabecera de flujo no reconocida: «%c»" + +#: pg_recvlogical.c:552 pg_recvlogical.c:564 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "no se pudo escribir %u bytes al archivo de registro «%s»: %m" + +#: pg_recvlogical.c:618 receivelog.c:628 receivelog.c:665 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "término inesperado del flujo de replicación: %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "intervalo de fsync «%s» no válido" + +#: pg_recvlogical.c:780 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "no se pudo interpretar la posición de inicio «%s»" + +#: pg_recvlogical.c:869 +#, c-format +msgid "no slot specified" +msgstr "no se especificó slot" + +#: pg_recvlogical.c:877 +#, c-format +msgid "no target file specified" +msgstr "no se especificó un archivo de destino" + +#: pg_recvlogical.c:885 +#, c-format +msgid "no database specified" +msgstr "no se especificó una base de datos" + +#: pg_recvlogical.c:893 +#, c-format +msgid "at least one action needs to be specified" +msgstr "debe especificarse al menos una operación" + +#: pg_recvlogical.c:901 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "no puede usarse --create-slot o --start junto con --drop-slot" + +#: pg_recvlogical.c:909 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "no puede usarse --create-slot o --drop-slot junto con --startpos" + +#: pg_recvlogical.c:917 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos solo se puede utilizar con --start" + +#: pg_recvlogical.c:948 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "no se pudo establecer una conexión de replicación específica a una base de datos" + +#: pg_recvlogical.c:1047 +#, c-format +msgid "end position %X/%X reached by keepalive" +msgstr "ubicación de término %X/%X alcanzado por «keep-alive»" + +#: pg_recvlogical.c:1050 +#, c-format +msgid "end position %X/%X reached by WAL record at %X/%X" +msgstr "ubicación de término %X/%X alcanzado por registro WAL en %X/%X" + +#: receivelog.c:68 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "no se pudo crear el archivo de estado «%s»: %s" + +#: receivelog.c:115 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "no se pudo obtener el tamaño del archivo de WAL «%s»: %s" + +#: receivelog.c:125 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "no se pudo abrir el archivo de WAL «%s»: %s" + +#: receivelog.c:133 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "no se pudo sincronizar (fsync) el archivo de WAL «%s»: %s" + +#: receivelog.c:147 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "el archivo de WAL «%s» mide %d byte, debería ser 0 o %d" +msgstr[1] "el archivo de WAL «%s» mide %d bytes, debería ser 0 o %d" + +#: receivelog.c:162 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "no se pudo abrir archivo de WAL «%s»: %s" + +#: receivelog.c:188 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "no se pudo determinar la posición (seek) en el archivo «%s»: %s" + +#: receivelog.c:202 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "no se cambiará el nombre a «%s%s», el segmento no está completo" + +#: receivelog.c:214 receivelog.c:299 receivelog.c:674 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "no se pudo cerrar el archivo «%s»: %s" + +#: receivelog.c:271 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "el servidor reportó un nombre inesperado para el archivo de historia de timeline %u: %s" + +#: receivelog.c:279 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "no se pudo crear el archivo de historia de timeline «%s»: %s" + +#: receivelog.c:286 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "no se pudo escribir al archivo de historia de timeline «%s»: %s" + +#: receivelog.c:376 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "versión de servidor %s incompatible; el cliente no soporta flujos de servidores anteriores a la versión %s" + +#: receivelog.c:385 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "versión de servidor %s incompatible; el cliente no soporta flujos de servidores posteriores a %s" + +#: receivelog.c:487 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "no se pudo identificar al sistema: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d o más campos" + +#: receivelog.c:494 +#, c-format +msgid "system identifier does not match between base backup and streaming connection" +msgstr "el identificador de sistema no coincide entre el respaldo base y la conexión de flujo" + +#: receivelog.c:500 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "el timeline de inicio %u no está presente en el servidor" + +#: receivelog.c:541 +#, c-format +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "respuesta inesperada a la orden TIMELINE_HISTORY: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" + +#: receivelog.c:612 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "el servidor reportó un timeline siguiente %u inesperado, a continuación del timeline %u" + +#: receivelog.c:618 +#, c-format +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "el servidor paró la transmisión del timeline %u en %X/%X, pero reportó que el siguiente timeline %u comienza en %X/%X" + +#: receivelog.c:658 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "el flujo de replicación terminó antes del punto de término" + +#: receivelog.c:704 +#, c-format +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "respuesta inesperada después del fin-de-timeline: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" + +#: receivelog.c:713 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "no se pudo interpretar el punto de inicio del siguiente timeline «%s»" + +#: receivelog.c:762 receivelog.c:1014 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %s" + +#: receivelog.c:1077 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "se recibió un registro de WAL para el desplazamiento %u sin ningún archivo abierto" + +#: receivelog.c:1087 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "se obtuvo desplazamiento de datos WAL %08x, se esperaba %08x" + +#: receivelog.c:1121 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "no se pudo escribir %u bytes al archivo WAL «%s»: %s" + +#: receivelog.c:1146 receivelog.c:1186 receivelog.c:1216 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "no se pudo enviar el paquete copy-end: %s" + +#: streamutil.c:162 +msgid "Password: " +msgstr "Contraseña: " + +#: streamutil.c:186 +#, c-format +msgid "could not connect to server" +msgstr "no se pudo conectar al servidor" + +#: streamutil.c:231 +#, c-format +msgid "could not clear search_path: %s" +msgstr "no se pudo limpiar search_path: %s" + +#: streamutil.c:247 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "no se pudo determinar la opción integer_datetimes del servidor" + +#: streamutil.c:254 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "la opción de compilación integer_datetimes no coincide con el servidor" + +#: streamutil.c:305 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "no se pudo obtener el tamaño del segmento de WAL: se obtuvo %d filas y %d campos, se esperaban %d filas y %d o más campos" + +#: streamutil.c:315 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "el tamaño de segmento de WAL no pudo ser analizado" + +#: streamutil.c:333 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "el tamaño de segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el servidor remoto reportó un valor de %d byte" +msgstr[1] "el tamaño de segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el servidor remoto reportó un valor de %d bytes" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "no se pudo obtener el indicador de acceso de grupo: se obtuvo %d filas y %d campos, se esperaban %d filas y %d o más campos" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "el indicador de acceso de grupo no pudo ser analizado: %s" + +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "no se pudo create el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "no se pudo eliminar el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" + +#: walmethods.c:438 walmethods.c:932 +msgid "could not compress data" +msgstr "no se pudo comprimir datos" + +#: walmethods.c:470 +msgid "could not reset compression stream" +msgstr "no se pudo restablecer el flujo comprimido" + +#: walmethods.c:568 +msgid "could not initialize compression library" +msgstr "no se pudo inicializar la biblioteca de compresión" + +#: walmethods.c:580 +msgid "implementation error: tar files can't have more than one open file" +msgstr "error de implementación: los archivos tar no pueden tener abierto más de un fichero" + +#: walmethods.c:594 +msgid "could not create tar header" +msgstr "no se pudo crear la cabecera del archivo tar" + +#: walmethods.c:608 walmethods.c:650 walmethods.c:847 walmethods.c:859 +msgid "could not change compression parameters" +msgstr "no se pudo cambiar los parámetros de compresión" + +#: walmethods.c:734 +msgid "unlink not supported with compression" +msgstr "unlink no soportado con compresión" + +#: walmethods.c:957 +msgid "could not close compression stream" +msgstr "no se pudo cerrar el flujo comprimido" + +#~ msgid "could not connect to server: %s" +#~ msgstr "no se pudo conectar al servidor: %s" + +#~ msgid "select() failed: %m" +#~ msgstr "select() falló: %m" + +#~ msgid "--no-manifest and --manifest-force-encode are incompatible options" +#~ msgstr "--no-manifest y --manifest-force-encode son opciones incompatibles" + +#~ msgid "--no-manifest and --manifest-checksums are incompatible options" +#~ msgstr "--no-manifest y --manifest-checksums son opciones incompatibles" + +#~ msgid "--progress and --no-estimate-size are incompatible options" +#~ msgstr "--progress y --no-estimate-size son opciones incompatibles" diff --git a/src/bin/pg_basebackup/po/fr.po b/src/bin/pg_basebackup/po/fr.po new file mode 100644 index 000000000000..b6903d4a14a9 --- /dev/null +++ b/src/bin/pg_basebackup/po/fr.po @@ -0,0 +1,1774 @@ +# LANGUAGE message translation file for pg_basebackup +# Copyright (C) 2011 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-26 06:47+0000\n" +"PO-Revision-Date: 2021-04-26 11:37+0200\n" +"Last-Translator: Christophe Courtois \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" + +#: ../../common/file_utils.c:87 ../../common/file_utils.c:451 +#: pg_receivewal.c:266 pg_recvlogical.c:340 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "n'a pas pu tester le fichier « %s » : %m" + +#: ../../common/file_utils.c:166 pg_receivewal.c:169 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" + +#: ../../common/file_utils.c:200 pg_receivewal.c:337 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "n'a pas pu lire le répertoire « %s » : %m" + +#: ../../common/file_utils.c:232 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:134 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier « %s » : %m" + +#: ../../common/file_utils.c:303 ../../common/file_utils.c:373 +#: pg_recvlogical.c:193 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m" + +#: ../../common/file_utils.c:383 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "n'a pas pu renommer le fichier « %s » en « %s » : %m" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "mémoire épuisée" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "n'a pas pu écrire dans le fichier « %s » : %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "n'a pas pu créer le fichier « %s » : %m" + +#: pg_basebackup.c:224 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "suppression du répertoire des données « %s »" + +#: pg_basebackup.c:226 +#, c-format +msgid "failed to remove data directory" +msgstr "échec de la suppression du répertoire des données" + +#: pg_basebackup.c:230 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "suppression du contenu du répertoire des données « %s »" + +#: pg_basebackup.c:232 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "échec de la suppression du contenu du répertoire des données" + +#: pg_basebackup.c:237 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "suppression du répertoire des journaux de transactions « %s »" + +#: pg_basebackup.c:239 +#, c-format +msgid "failed to remove WAL directory" +msgstr "échec de la suppression du répertoire des journaux de transactions" + +#: pg_basebackup.c:243 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "suppression du contenu du répertoire des journaux de transactions « %s »" + +#: pg_basebackup.c:245 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "échec de la suppression du contenu du répertoire des journaux de transactions" + +#: pg_basebackup.c:251 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "répertoire des données « %s » non supprimé à la demande de l'utilisateur" + +#: pg_basebackup.c:254 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "répertoire des journaux de transactions « %s » non supprimé à la demande de l'utilisateur" + +#: pg_basebackup.c:258 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "les modifications des répertoires des tablespaces ne seront pas annulées" + +#: pg_basebackup.c:299 +#, c-format +msgid "directory name too long" +msgstr "nom du répertoire trop long" + +#: pg_basebackup.c:309 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "multiple signes « = » dans la correspondance de tablespace" + +#: pg_basebackup.c:321 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "format de correspondance de tablespace « %s » invalide, doit être « ANCIENREPERTOIRE=NOUVEAUREPERTOIRE »" + +#: pg_basebackup.c:333 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "l'ancien répertoire n'est pas un chemin absolu dans la correspondance de tablespace : %s" + +#: pg_basebackup.c:340 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "le nouveau répertoire n'est pas un chemin absolu dans la correspondance de tablespace : %s" + +#: pg_basebackup.c:379 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s prend une sauvegarde binaire d'un serveur PostgreSQL en cours d'exécution.\n" +"\n" + +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPTION]...\n" + +#: pg_basebackup.c:383 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"Options contrôlant la sortie :\n" + +#: pg_basebackup.c:384 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=RÉPERTOIRE reçoit la sauvegarde de base dans ce répertoire\n" + +#: pg_basebackup.c:385 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t format en sortie (plain (par défaut), tar)\n" + +#: pg_basebackup.c:386 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=TAUX taux maximum de transfert du répertoire de\n" +" données (en Ko/s, ou utiliser le suffixe « k »\n" +" ou « M »)\n" + +#: pg_basebackup.c:388 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr " -R, --write-recovery-conf écrit la configuration pour la réplication\n" + +#: pg_basebackup.c:390 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=ANCIENREP=NOUVEAUREP\n" +" déplacer le répertoire ANCIENREP en NOUVEAUREP\n" + +#: pg_basebackup.c:392 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr "" +" --waldir=RÉP_WAL emplacement du répertoire des journaux de\n" +" transactions\n" + +#: pg_basebackup.c:393 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" inclut les journaux de transactions requis avec\n" +" la méthode spécifiée\n" + +#: pg_basebackup.c:395 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip compresse la sortie tar\n" + +#: pg_basebackup.c:396 +#, c-format +msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr "" +" -Z, --compress=0-9 compresse la sortie tar avec le niveau de\n" +" compression indiqué\n" + +#: pg_basebackup.c:397 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Options générales :\n" + +#: pg_basebackup.c:398 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr " -c, --checkpoint=fast|spread exécute un CHECKPOINT rapide ou réparti\n" + +#: pg_basebackup.c:400 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " --create-slot créer un slot de réplication\n" + +#: pg_basebackup.c:401 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=LABEL configure le label de sauvegarde\n" + +#: pg_basebackup.c:402 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean ne nettoie pas en cas d'erreur\n" + +#: pg_basebackup.c:403 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync n'attend pas que les modifications soient proprement écrites sur disque\n" + +#: pg_basebackup.c:404 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress affiche la progression de la sauvegarde\n" + +#: pg_basebackup.c:405 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=NOMREP slot de réplication à utiliser\n" + +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose affiche des messages verbeux\n" + +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" + +#: pg_basebackup.c:408 +#, c-format +msgid "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" utilise cet algorithme pour les sommes de contrôle du manifeste\n" + +#: pg_basebackup.c:410 +#, c-format +msgid "" +" --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr "" +" --manifest-force-encode\n" +" encode tous les noms de fichier dans le manifeste en hexadécimal\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr " --no-estimate-size ne réalise pas d'estimation sur la taille de la sauvegarde côté serveur\n" + +#: pg_basebackup.c:413 +#, c-format +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr "" +" --no-manifest supprime la génération de manifeste de sauvegarde\n" +"\n" + +#: pg_basebackup.c:414 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot empêche la création de slots de réplication temporaires\n" + +#: pg_basebackup.c:415 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr " --no-verify-checksums ne vérifie pas les sommes de contrôle\n" + +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" + +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Options de connexion :\n" + +#: pg_basebackup.c:419 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONNSTR chaîne de connexion\n" + +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr "" +" -h, --host=NOMHÔTE hôte du serveur de bases de données ou\n" +" répertoire des sockets\n" + +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr "" +" -p, --port=PORT numéro de port du serveur de bases de\n" +" données\n" + +#: pg_basebackup.c:422 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in seconds)\n" +msgstr "" +" -s, --status-interval=INTERVAL durée entre l'envoi de paquets de statut au\n" +" serveur (en secondes)\n" + +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NOM se connecte avec cet utilisateur\n" + +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password ne demande jamais le mot de passe\n" + +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr "" +" -W, --password force la demande du mot de passe (devrait arriver\n" +" automatiquement)\n" + +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapporter les bogues à <%s>.\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil %s : <%s>\n" + +#: pg_basebackup.c:471 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "n'a pas pu lire à partir du tube : %m" + +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "n'a pas pu analyser l'emplacement du journal des transactions « %s »" + +#: pg_basebackup.c:573 pg_receivewal.c:441 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "n'a pas pu finir l'écriture dans les fichiers de transactions : %m" + +#: pg_basebackup.c:620 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "n'a pas pu créer un tube pour le processus en tâche de fond : %m" + +#: pg_basebackup.c:655 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "a créé le slot de réplication temporaire « %s »" + +#: pg_basebackup.c:658 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "a créé le slot de réplication « %s »" + +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "n'a pas pu créer le répertoire « %s » : %m" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not create background process: %m" +msgstr "n'a pas pu créer un processus en tâche de fond : %m" + +#: pg_basebackup.c:708 +#, c-format +msgid "could not create background thread: %m" +msgstr "n'a pas pu créer un thread en tâche de fond : %m" + +#: pg_basebackup.c:752 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "le répertoire « %s » existe mais n'est pas vide" + +#: pg_basebackup.c:759 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "n'a pas pu accéder au répertoire « %s » : %m" + +#: pg_basebackup.c:824 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s Ko (100%%), %d/%d tablespace %*s" +msgstr[1] "%*s/%s Ko (100%%), %d/%d tablespaces %*s" + +#: pg_basebackup.c:836 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s Ko (%d%%), %d/%d tablespace (%s%-*.*s)" +msgstr[1] "%*s/%s Ko (%d%%), %d/%d tablespaces (%s%-*.*s)" + +#: pg_basebackup.c:852 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s Ko (%d%%), %d/%d tablespace" +msgstr[1] "%*s/%s Ko (%d%%), %d/%d tablespaces" + +#: pg_basebackup.c:877 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "le taux de transfert « %s » ne correspond pas à une valeur valide" + +#: pg_basebackup.c:882 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "taux de transfert invalide (« %s ») : %m" + +#: pg_basebackup.c:891 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "le taux de transfert doit être supérieur à zéro" + +#: pg_basebackup.c:923 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "unité invalide pour --max-rate : « %s »" + +#: pg_basebackup.c:930 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "le taux de transfert « %s » dépasse l'échelle des entiers" + +#: pg_basebackup.c:940 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "le taux de transfert « %s » est en dehors des limites" + +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "n'a pas pu obtenir le flux de données de COPY : %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:964 +#, c-format +msgid "could not read COPY data: %s" +msgstr "n'a pas pu lire les données du COPY : %s" + +#: pg_basebackup.c:1007 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "n'a pas pu écrire dans le fichier compressé « %s » : %s" + +#: pg_basebackup.c:1071 +#, c-format +msgid "could not duplicate stdout: %m" +msgstr "n'a pas pu dupliquer la sortie (stdout) : %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "n'a pas pu ouvrir le fichier de sauvegarde : %m" + +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "n'a pas pu configurer le niveau de compression %d : %s" + +#: pg_basebackup.c:1155 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "n'a pas pu créer le fichier compressé « %s » : %s" + +#: pg_basebackup.c:1267 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "n'a pas pu fermer le fichier compressé « %s » : %s" + +#: pg_basebackup.c:1279 pg_recvlogical.c:632 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "n'a pas pu fermer le fichier « %s » : %m" + +#: pg_basebackup.c:1541 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "le flux COPY s'est terminé avant que le dernier fichier soit terminé" + +#: pg_basebackup.c:1570 +#, c-format +msgid "invalid tar block header size: %zu" +msgstr "taille invalide de l'en-tête de bloc du fichier tar : %zu" + +#: pg_basebackup.c:1627 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "n'a pas pu configurer les droits du répertoire « %s » : %m" + +#: pg_basebackup.c:1651 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "n'a pas pu créer le lien symbolique de « %s » vers « %s » : %m" + +#: pg_basebackup.c:1658 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "indicateur de lien « %c » non reconnu" + +#: pg_basebackup.c:1677 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "n'a pas pu initialiser les droits du fichier « %s » : %m" + +#: pg_basebackup.c:1831 +#, c-format +msgid "incompatible server version %s" +msgstr "version « %s » du serveur incompatible" + +#: pg_basebackup.c:1846 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "ASTUCE : utilisez -X none ou -X fetch pour désactiver la réplication en flux" + +#: pg_basebackup.c:1882 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "début de la sauvegarde de base, en attente de la fin du checkpoint" + +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:480 receivelog.c:529 +#: receivelog.c:568 streamutil.c:297 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "n'a pas pu envoyer la commande de réplication « %s » : %s" + +#: pg_basebackup.c:1919 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "n'a pas pu initier la sauvegarde de base : %s" + +#: pg_basebackup.c:1925 +#, c-format +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "le serveur a renvoyé une réponse inattendue à la commande BASE_BACKUP ; a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs" + +#: pg_basebackup.c:1933 +#, c-format +msgid "checkpoint completed" +msgstr "checkpoint terminé" + +#: pg_basebackup.c:1948 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "point de départ du journal de transactions : %s sur la timeline %u" + +#: pg_basebackup.c:1957 +#, c-format +msgid "could not get backup header: %s" +msgstr "n'a pas pu obtenir l'en-tête du serveur : %s" + +#: pg_basebackup.c:1963 +#, c-format +msgid "no data returned from server" +msgstr "aucune donnée renvoyée du serveur" + +#: pg_basebackup.c:1995 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "peut seulement écrire un tablespace sur la sortie standard, la base en a %d" + +#: pg_basebackup.c:2007 +#, c-format +msgid "starting background WAL receiver" +msgstr "lance le récepteur de journaux de transactions en tâche de fond" + +#: pg_basebackup.c:2046 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "n'a pas pu obtenir la position finale des journaux de transactions à partir du serveur : %s" + +#: pg_basebackup.c:2052 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "aucune position de fin du journal de transactions renvoyée par le serveur" + +#: pg_basebackup.c:2057 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "point final du journal de transactions : %s" + +#: pg_basebackup.c:2068 +#, c-format +msgid "checksum error occurred" +msgstr "erreur de somme de contrôle" + +#: pg_basebackup.c:2073 +#, c-format +msgid "final receive failed: %s" +msgstr "échec lors de la réception finale : %s" + +#: pg_basebackup.c:2097 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "en attente que le processus en tâche de fond termine le flux..." + +#: pg_basebackup.c:2102 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "n'a pas pu envoyer la commande au tube du processus : %m" + +#: pg_basebackup.c:2110 +#, c-format +msgid "could not wait for child process: %m" +msgstr "n'a pas pu attendre le processus fils : %m" + +#: pg_basebackup.c:2115 +#, c-format +msgid "child %d died, expected %d" +msgstr "le fils %d est mort, %d attendu" + +#: pg_basebackup.c:2120 streamutil.c:92 streamutil.c:203 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2145 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "n'a pas pu attendre le thread : %m" + +#: pg_basebackup.c:2151 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "n'a pas pu obtenir le code de sortie du thread : %m" + +#: pg_basebackup.c:2156 +#, c-format +msgid "child thread exited with error %u" +msgstr "le thread a quitté avec le code d'erreur %u" + +#: pg_basebackup.c:2184 +#, c-format +msgid "syncing data to disk ..." +msgstr "synchronisation des données sur disque..." + +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "renommage de backup_manifest.tmp en backup_manifest" + +#: pg_basebackup.c:2220 +#, c-format +msgid "base backup completed" +msgstr "sauvegarde de base terminée" + +#: pg_basebackup.c:2305 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" +msgstr "format de sortie « %s » invalide, doit être soit « plain » soit « tar »" + +#: pg_basebackup.c:2349 +#, c-format +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "option wal-method « %s » invalide, doit être soit « fetch » soit « stream » soit « none »" + +#: pg_basebackup.c:2377 pg_receivewal.c:580 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "niveau de compression « %s » invalide" + +#: pg_basebackup.c:2388 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "argument « %s » invalide pour le CHECKPOINT, doit être soit « fast » soit « spread »" + +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "intervalle « %s » invalide du statut" + +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2528 +#: pg_basebackup.c:2539 pg_basebackup.c:2549 pg_basebackup.c:2567 +#: pg_basebackup.c:2576 pg_basebackup.c:2585 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayer « %s --help » pour plus d'informations.\n" + +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" + +#: pg_basebackup.c:2468 pg_receivewal.c:654 +#, c-format +msgid "no target directory specified" +msgstr "aucun répertoire cible indiqué" + +#: pg_basebackup.c:2479 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "seules les sauvegardes en mode tar peuvent être compressées" + +#: pg_basebackup.c:2487 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "ne peut pas envoyer les journaux de transactions vers stdout en mode tar" + +#: pg_basebackup.c:2495 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "les slots de réplications peuvent seulement être utilisés avec la réplication en flux des WAL" + +#: pg_basebackup.c:2505 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot ne peut pas être utilisé avec un nom de slot" + +#. translator: second %s is an option name +#: pg_basebackup.c:2517 pg_receivewal.c:634 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "%s a besoin du slot avec l'option --slot" + +#: pg_basebackup.c:2526 pg_basebackup.c:2565 pg_basebackup.c:2574 +#: pg_basebackup.c:2583 +#, c-format +msgid "%s and %s are incompatible options" +msgstr "%s et %s sont des options incompatibles" + +#: pg_basebackup.c:2538 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "l'emplacement du répertoire des journaux de transactions doit être indiqué uniquement dans le mode plain" + +#: pg_basebackup.c:2548 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "l'emplacement du répertoire des journaux de transactions doit être indiqué avec un chemin absolu" + +#: pg_basebackup.c:2558 pg_receivewal.c:663 +#, c-format +msgid "this build does not support compression" +msgstr "cette construction ne supporte pas la compression" + +#: pg_basebackup.c:2643 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "n'a pas pu créer le lien symbolique « %s » : %m" + +#: pg_basebackup.c:2647 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "les liens symboliques ne sont pas supportés sur cette plateforme" + +#: pg_receivewal.c:77 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s reçoit le flux des journaux de transactions PostgreSQL.\n" +"\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:81 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Options :\n" + +#: pg_receivewal.c:82 +#, c-format +msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr "" +" -D, --directory=RÉP reçoit les journaux de transactions dans ce\n" +" répertoire\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:82 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN quitte après avoir reçu le LSN spécifié\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:86 +#, c-format +msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgstr "" +" --if-not-exists ne pas renvoyer une erreur si le slot existe\n" +" déjà lors de sa création\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:88 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop ne boucle pas en cas de perte de la connexion\n" + +#: pg_receivewal.c:86 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync n'attend pas que les modifications soient proprement écrites sur disque\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:93 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server (default: %d)\n" +msgstr "" +" -s, --status-interval=SECS durée entre l'envoi de paquets de statut au\n" +" (par défaut %d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid " --synchronous flush write-ahead log immediately after writing\n" +msgstr "" +" --synchronous vide le journal de transactions immédiatement\n" +" après son écriture\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr "" +" -Z, --compress=0-9 compresse la sortie tar avec le niveau de\n" +" compression indiqué\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"Actions optionnelles :\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:78 +#, c-format +msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgstr "" +" --create-slot créer un nouveau slot de réplication\n" +" (pour le nom du slot, voir --slot)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:79 +#, c-format +msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgstr "" +" --drop-slot supprimer un nouveau slot de réplication\n" +" (pour le nom du slot, voir --slot)\n" + +#: pg_receivewal.c:117 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "segment terminé à %X/%X (timeline %u)" + +#: pg_receivewal.c:124 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "arrêt du flux streaming à %X/%X (timeline %u)" + +#: pg_receivewal.c:140 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "a basculé sur la timeline %u à %X/%X" + +#: pg_receivewal.c:150 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "a reçu un signal d'interruption, quitte" + +#: pg_receivewal.c:186 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "n'a pas pu fermer le répertoire « %s » : %m" + +#: pg_receivewal.c:272 +#, c-format +msgid "segment file \"%s\" has incorrect size %lld, skipping" +msgstr "le segment « %s » a une taille incorrecte (%lld), ignoré" + +#: pg_receivewal.c:290 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier compressé « %s » : %m" + +#: pg_receivewal.c:296 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "n'a pas pu chercher dans le fichier compressé « %s » : %m" + +#: pg_receivewal.c:304 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "n'a pas pu lire le fichier compressé « %s » : %m" + +#: pg_receivewal.c:307 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "n'a pas pu lire le fichier compressé « %s » : a lu %d sur %zu" + +#: pg_receivewal.c:318 +#, c-format +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "le segment compressé « %s » a une taille %d non compressé incorrecte, ignoré" + +#: pg_receivewal.c:422 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "commence le flux des journaux à %X/%X (timeline %u)" + +#: pg_receivewal.c:537 pg_recvlogical.c:762 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "numéro de port invalide : « %s »" + +#: pg_receivewal.c:565 pg_recvlogical.c:788 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "n'a pas pu analyser la position finale « %s »" + +#: pg_receivewal.c:625 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "ne peut pas utiliser --create-slot avec --drop-slot" + +#: pg_receivewal.c:643 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "ne peut pas utiliser --synchronous avec --no-sync" + +#: pg_receivewal.c:719 +#, c-format +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "la connexion de réplication utilisant le slot « %s » est spécifique à une base, ce qui est inattendu" + +#: pg_receivewal.c:730 pg_recvlogical.c:966 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "suppression du slot de réplication « %s »" + +#: pg_receivewal.c:741 pg_recvlogical.c:976 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "création du slot de réplication « %s »" + +#: pg_receivewal.c:767 pg_recvlogical.c:1001 +#, c-format +msgid "disconnected" +msgstr "déconnecté" + +#. translator: check source for value for %d +#: pg_receivewal.c:773 pg_recvlogical.c:1007 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "déconnecté, attente de %d secondes avant une nouvelle tentative" + +#: pg_recvlogical.c:73 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s contrôle le flux des modifications logiques de PostgreSQL.\n" +"\n" + +#: pg_recvlogical.c:77 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"Action à réaliser :\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgstr "" +" --start lance le flux dans un slot de réplication (pour\n" +" le nom du slot, voir --slot)\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=NOMFICHIER trace la réception dans ce fichier, - pour stdout\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: %d)\n" +msgstr "" +" -F --fsync-interval=SECS durée entre les fsyncs vers le fichier de sortie\n" +" (par défaut %d)\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgstr "" +" -I, --startpos=LSN position de début du streaming dans le slot\n" +" existant\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NOM[=VALEUR] passe l'option NAME avec la valeur optionnelle\n" +" VALEUR au plugin en sortie\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr "" +" -P, --plugin=PLUGIN utilise le plugin PLUGIN en sortie\n" +" (par défaut %s)\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=NOMSLOT nom du slot de réplication logique\n" + +#: pg_recvlogical.c:100 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=NOMBASE base de données de connexion\n" + +#: pg_recvlogical.c:133 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "confirmation d'écriture jusqu'à %X/%X et de synchronisation jusqu'à %X/%X (slot %s)" + +#: pg_recvlogical.c:157 receivelog.c:342 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "n'a pas pu envoyer le paquet d'informations en retour : %s" + +#: pg_recvlogical.c:230 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "commence le flux des journaux à %X/%X (slot %s)" + +#: pg_recvlogical.c:271 +#, c-format +msgid "streaming initiated" +msgstr "flux lancé" + +#: pg_recvlogical.c:335 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier applicatif « %s » : %m" + +#: pg_recvlogical.c:361 receivelog.c:872 +#, c-format +msgid "invalid socket: %s" +msgstr "socket invalide : %s" + +#: pg_recvlogical.c:414 receivelog.c:900 +#, c-format +msgid "%s() failed: %m" +msgstr "échec de %s() : %m" + +#: pg_recvlogical.c:421 receivelog.c:950 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "n'a pas pu recevoir des données du flux de WAL : %s" + +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:994 receivelog.c:1060 +#, c-format +msgid "streaming header too small: %d" +msgstr "en-tête de flux trop petit : %d" + +#: pg_recvlogical.c:498 receivelog.c:832 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "entête non reconnu du flux : « %c »" + +#: pg_recvlogical.c:552 pg_recvlogical.c:564 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "n'a pas pu écrire %u octets dans le journal de transactions « %s » : %m" + +#: pg_recvlogical.c:618 receivelog.c:628 receivelog.c:665 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "fin inattendue du flux de réplication : %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "intervalle fsync « %s » invalide" + +#: pg_recvlogical.c:780 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "n'a pas pu analyser la position de départ « %s »" + +#: pg_recvlogical.c:869 +#, c-format +msgid "no slot specified" +msgstr "aucun slot de réplication indiqué" + +#: pg_recvlogical.c:877 +#, c-format +msgid "no target file specified" +msgstr "aucun fichier cible indiqué" + +#: pg_recvlogical.c:885 +#, c-format +msgid "no database specified" +msgstr "aucune base de données indiquée" + +#: pg_recvlogical.c:893 +#, c-format +msgid "at least one action needs to be specified" +msgstr "au moins une action doit être indiquée" + +#: pg_recvlogical.c:901 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "ne peut pas utiliser --create-slot ou --start avec --drop-slot" + +#: pg_recvlogical.c:909 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "ne peut pas utiliser --create-slot ou --drop-slot avec --startpos" + +#: pg_recvlogical.c:917 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos peut seulement être spécifié avec --start" + +#: pg_recvlogical.c:948 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "n'a pas pu établir une connexion de réplication spécifique à la base" + +#: pg_recvlogical.c:1047 +#, c-format +msgid "end position %X/%X reached by keepalive" +msgstr "position finale %X/%X atteinte par keepalive" + +#: pg_recvlogical.c:1050 +#, c-format +msgid "end position %X/%X reached by WAL record at %X/%X" +msgstr "position finale %X/%X atteinte à l'enregistrement WAL %X/%X" + +#: receivelog.c:68 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "n'a pas pu créer le fichier de statut d'archivage « %s » : %s" + +#: receivelog.c:115 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "n'a pas pu obtenir la taille du journal de transactions « %s » : %s" + +#: receivelog.c:125 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "n'a pas pu ouvrir le journal des transactions « %s » existant : %s" + +#: receivelog.c:133 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "n'a pas pu synchroniser sur disque le journal de transactions « %s » existant : %s" + +#: receivelog.c:147 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "le journal de transactions « %s » comprend %d octet, cela devrait être 0 ou %d" +msgstr[1] "le journal de transactions « %s » comprend %d octets, cela devrait être 0 ou %d" + +#: receivelog.c:162 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "n'a pas pu ouvrir le journal de transactions « %s » : %s" + +#: receivelog.c:188 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "n'a pas pu déterminer la position de recherche dans le fichier d'archive « %s » : %s" + +#: receivelog.c:202 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "pas de renommage de « %s%s », le segment n'est pas complet" + +#: receivelog.c:214 receivelog.c:299 receivelog.c:674 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "n'a pas pu fermer le fichier « %s » : %s" + +#: receivelog.c:271 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "le serveur a renvoyé un nom de fichier historique inattendu pour la timeline %u : %s" + +#: receivelog.c:279 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "n'a pas pu créer le fichier historique de la timeline « %s » : %s" + +#: receivelog.c:286 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "n'a pas pu écrire dans le fichier historique de la timeline « %s » : %s" + +#: receivelog.c:376 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "version %s du serveur incompatible ; le client ne supporte pas le streaming de versions plus anciennes que %s" + +#: receivelog.c:385 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "version %s du serveur incompatible ; le client ne supporte pas le streaming de versions plus récentes que %s" + +#: receivelog.c:487 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "n'a pas pu identifier le système : a récupéré %d lignes et %d champs, attendait %d lignes et %d champs (ou plus)." + +#: receivelog.c:494 +#, c-format +msgid "system identifier does not match between base backup and streaming connection" +msgstr "l'identifiant système ne correspond pas entre la sauvegarde des fichiers et la connexion de réplication" + +#: receivelog.c:500 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "la timeline %u de départ n'est pas dans le serveur" + +#: receivelog.c:541 +#, c-format +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "réponse inattendue à la commande TIMELINE_HISTORY : a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs" + +#: receivelog.c:612 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "le serveur a renvoyé une timeline suivante %u inattendue, après la timeline %u" + +#: receivelog.c:618 +#, c-format +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "le serveur a arrêté l'envoi de la timeline %u à %X/%X, mais a indiqué que la timeline suivante, %u, commence à %X/%X" + +#: receivelog.c:658 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "le flux de réplication a été abandonné avant d'arriver au point d'arrêt" + +#: receivelog.c:704 +#, c-format +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "ensemble de résultats inattendu après la fin de la timeline : a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs" + +#: receivelog.c:713 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "n'a pas pu analyser la position de départ de la prochaine timeline « %s »" + +#: receivelog.c:762 receivelog.c:1014 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %s" + +#: receivelog.c:1077 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "a reçu l'enregistrement du journal de transactions pour le décalage %u sans fichier ouvert" + +#: receivelog.c:1087 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "a obtenu le décalage %08x pour les données du journal, attendait %08x" + +#: receivelog.c:1121 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "n'a pas pu écrire %u octets dans le journal de transactions « %s » : %s" + +#: receivelog.c:1146 receivelog.c:1186 receivelog.c:1216 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "n'a pas pu envoyer le paquet de fin de copie : %s" + +#: streamutil.c:162 +msgid "Password: " +msgstr "Mot de passe : " + +#: streamutil.c:186 +#, c-format +msgid "could not connect to server" +msgstr "n'a pas pu se connecter au serveur" + +#: streamutil.c:231 +#, c-format +msgid "could not clear search_path: %s" +msgstr "n'a pas pu effacer search_path : %s" + +#: streamutil.c:247 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "n'a pas pu déterminer la configuration serveur de integer_datetimes" + +#: streamutil.c:254 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "l'option de compilation integer_datetimes ne correspond pas au serveur" + +#: streamutil.c:305 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "n'a pas pu récupéré la taille d'un segment WAL : a obtenu %d lignes et %d champs, attendait %d lignes et %d champs (ou plus)" + +#: streamutil.c:315 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "la taille du segment WAL n'a pas pu être analysée" + +#: streamutil.c:333 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "la taille d'un WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go mais le serveur distant a rapporté une valeur de %d octet" +msgstr[1] "la taille d'un WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go mais le serveur distant a rapporté une valeur de %d octets" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "n'a pas pu récupérer les options d'accès du groupe : a obtenu %d lignes et %d champs, attendait %d lignes et %d champs (ou plus)" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "l'option d'accès du groupe n'a pas pu être analysé : %s" + +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "n'a pas pu créer le slot de réplication « %s » : a récupéré %d lignes et %d champs, attendait %d lignes et %d champs" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "n'a pas pu supprimer le slot de réplication « %s » : a récupéré %d lignes et %d champs, attendait %d lignes et %d champs" + +#: walmethods.c:438 walmethods.c:932 +msgid "could not compress data" +msgstr "n'a pas pu compresser les données" + +#: walmethods.c:470 +msgid "could not reset compression stream" +msgstr "n'a pas pu réinitialiser le flux de compression" + +#: walmethods.c:568 +msgid "could not initialize compression library" +msgstr "n'a pas pu initialiser la bibliothèque de compression" + +#: walmethods.c:580 +msgid "implementation error: tar files can't have more than one open file" +msgstr "erreur d'implémentation : les fichiers tar ne peuvent pas avoir plus d'un fichier ouvert" + +#: walmethods.c:594 +msgid "could not create tar header" +msgstr "n'a pas pu créer l'en-tête du fichier tar" + +#: walmethods.c:608 walmethods.c:650 walmethods.c:847 walmethods.c:859 +msgid "could not change compression parameters" +msgstr "n'a pas pu modifier les paramètres de compression" + +#: walmethods.c:734 +msgid "unlink not supported with compression" +msgstr "suppression non supportée avec la compression" + +#: walmethods.c:957 +msgid "could not close compression stream" +msgstr "n'a pas pu fermer le flux de compression" + +#~ msgid "--create-slot and --no-slot are incompatible options" +#~ msgstr "--create-slot et --no-slot sont des options incompatibles" + +#~ msgid "--progress and --no-estimate-size are incompatible options" +#~ msgstr "--progress et --no-estimate-size sont des options incompatibles" + +#~ msgid "--no-manifest and --manifest-checksums are incompatible options" +#~ msgstr "--no-manifest et --manifest-checksums sont des options incompatibles" + +#~ msgid "--no-manifest and --manifest-force-encode are incompatible options" +#~ msgstr "--no-manifest et --manifest-force-encode sont des options incompatibles" + +#~ msgid "could not connect to server: %s" +#~ msgstr "n'a pas pu se connecter au serveur : %s" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapporter les bogues à .\n" + +#~ msgid "deflate failed" +#~ msgstr "échec en décompression" + +#~ msgid "deflateReset failed" +#~ msgstr "échec de deflateReset" + +#~ msgid "deflateInit2 failed" +#~ msgstr "échec de deflateInit2" + +#~ msgid "deflateParams failed" +#~ msgstr "échec de deflateParams" + +#~ msgid "deflateEnd failed" +#~ msgstr "échec de deflateEnd" + +#~ msgid " -x, --xlog include required WAL files in backup (fetch mode)\n" +#~ msgstr "" +#~ " -x, --xlog inclut les journaux de transactions nécessaires\n" +#~ " dans la sauvegarde (mode fetch)\n" + +#~ msgid "%s: cannot specify both --xlog and --xlog-method\n" +#~ msgstr "%s : ne peut pas spécifier à la fois --xlog et --xlog-method\n" + +#~ msgid "%s: WAL streaming can only be used in plain mode\n" +#~ msgstr "%s : le flux de journaux de transactions peut seulement être utilisé en mode plain\n" + +#~ msgid "%s: could not stat transaction log file \"%s\": %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu récupérer les informations sur le journal de transactions\n" +#~ "« %s » : %s\n" + +#~ msgid "%s: could not pad transaction log file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu remplir de zéros le journal de transactions « %s » : %s\n" + +#~ msgid "%s: could not seek to beginning of transaction log file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu rechercher le début du journal de transaction « %s » : %s\n" + +#~ msgid "%s: could not rename file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu renommer le fichier « %s » : %s\n" + +#~ msgid "%s: could not open timeline history file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le journal historique de la timeline « %s » : %s\n" + +#~ msgid "%s: could not parse file size\n" +#~ msgstr "%s : n'a pas pu analyser la taille du fichier\n" + +#~ msgid "%s: could not parse file mode\n" +#~ msgstr "%s : n'a pas pu analyser le mode du fichier\n" + +#~ msgid "%s: could not parse transaction log file name \"%s\"\n" +#~ msgstr "%s : n'a pas pu analyser le nom du journal de transactions « %s »\n" + +#~ msgid "%s: could not close file %s: %s\n" +#~ msgstr "%s : n'a pas pu fermer le fichier %s : %s\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version affiche la version puis quitte\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help affiche cette aide puis quitte\n" + +#~ msgid "%s: invalid format of xlog location: %s\n" +#~ msgstr "%s : format invalide de l'emplacement du journal de transactions : %s\n" + +#~ msgid "%s: could not identify system: %s" +#~ msgstr "%s : n'a pas pu identifier le système : %s" + +#~ msgid "%s: could not send base backup command: %s" +#~ msgstr "%s : n'a pas pu envoyer la commande de sauvegarde de base : %s" + +#~ msgid "%s: could not identify system: %s\n" +#~ msgstr "%s : n'a pas pu identifier le système : %s\n" + +#~ msgid "%s: could not parse log start position from value \"%s\"\n" +#~ msgstr "%s : n'a pas pu analyser la position de départ des WAL à partir de la valeur « %s »\n" + +#~ msgid "%s: could not open WAL segment %s: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le segment WAL %s : %s\n" + +#~ msgid "%s: could not stat WAL segment %s: %s\n" +#~ msgstr "%s : n'a pas pu récupérer les informations sur le segment WAL %s : %s\n" + +#~ msgid "%s: could not pad WAL segment %s: %s\n" +#~ msgstr "%s : n'a pas pu terminer le segment WAL %s : %s\n" + +#~ msgid "%s: could not seek back to beginning of WAL segment %s: %s\n" +#~ msgstr "%s : n'a pas pu se déplacer au début du segment WAL %s : %s\n" + +#~ msgid "%s: could not get current position in file %s: %s\n" +#~ msgstr "%s : n'a pas pu obtenir la position courant dans le fichier %s : %s\n" + +#~ msgid "%s: could not read copy data: %s\n" +#~ msgstr "%s : n'a pas pu lire les données du COPY : %s\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide et quitte\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version et quitte\n" + +#~ msgid "%s: keepalive message has incorrect size %d\n" +#~ msgstr "%s : le message keepalive a une taille %d incorrecte\n" + +#~ msgid "%s: timeline does not match between base backup and streaming connection\n" +#~ msgstr "" +#~ "%s : la timeline ne correspond pas entre la sauvegarde des fichiers et la\n" +#~ "connexion de réplication\n" + +#~ msgid "%s: no start point returned from server\n" +#~ msgstr "%s : aucun point de redémarrage renvoyé du serveur\n" + +#~ msgid "%s: socket not open" +#~ msgstr "%s : socket non ouvert" + +#~ msgid "%s: could not clear search_path: %s" +#~ msgstr "%s : n'a pas pu effacer search_path : %s" + +#~ msgid "%s: could not connect to server: %s" +#~ msgstr "%s : n'a pas pu se connecter au serveur : %s" + +#~ msgid "%s: could not connect to server\n" +#~ msgstr "%s : n'a pas pu se connecter au serveur\n" + +#~ msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" +#~ msgstr "" +#~ "%s : n'a pas pu identifier le système, a récupéré %d lignes et %d champs,\n" +#~ "attendait %d lignes et %d champs (ou plus)\n" + +#~ msgid "%s: could not open write-ahead log file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le journal de transactions « %s » : %s\n" + +#~ msgid "%s: could not create archive status file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le fichier de statut d'archivage « %s » : %s\n" + +#~ msgid "%s: could not receive data from WAL stream: %s" +#~ msgstr "%s : n'a pas pu recevoir des données du flux de WAL : %s" + +#~ msgid "%s: select() failed: %s\n" +#~ msgstr "%s : échec de select() : %s\n" + +#~ msgid "%s: invalid socket: %s" +#~ msgstr "%s : socket invalide : %s" + +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le journal applicatif « %s » : %s\n" + +#~ msgid "%s: could not fsync log file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n" + +#~ msgid "%s: invalid port number \"%s\"\n" +#~ msgstr "%s : numéro de port invalide : « %s »\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu fermer le répertoire « %s » : %s\n" + +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s : les liens symboliques ne sont pas supportés sur cette plateforme\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le lien symbolique « %s » : %s\n" + +#~ msgid "%s: WAL directory location must be an absolute path\n" +#~ msgstr "" +#~ "%s : l'emplacement du répertoire des journaux de transactions doit être\n" +#~ "indiqué avec un chemin absolu\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" + +#~ msgid "%s: child process exited with error %d\n" +#~ msgstr "%s : le processus fils a quitté avec le code erreur %d\n" + +#~ msgid "%s: child process did not exit normally\n" +#~ msgstr "%s : le processus fils n'a pas quitté normalement\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s : mémoire épuisée\n" + +#~ msgid "%s: could not set permissions on file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu configurer les droits sur le fichier « %s » : %s\n" + +#~ msgid "%s: could not set permissions on directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas configurer les droits sur le répertoire « %s » : %s\n" + +#~ msgid "%s: could not close file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu fermer le fichier « %s » : %s\n" + +#~ msgid "%s: could not create file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le fichier « %s » : %s\n" + +#~ msgid "%s: could not write to file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu écrire dans le fichier « %s » : %s\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" + +#~ msgid "%s: directory \"%s\" exists but is not empty\n" +#~ msgstr "%s : le répertoire « %s » existe mais n'est pas vide\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le répertoire « %s » : %s\n" + +#~ msgid "%s: WAL directory \"%s\" not removed at user's request\n" +#~ msgstr "%s : répertoire des journaux de transactions « %s » non supprimé à la demande de l'utilisateur\n" + +#~ msgid "%s: data directory \"%s\" not removed at user's request\n" +#~ msgstr "%s : répertoire des données « %s » non supprimé à la demande de l'utilisateur\n" + +#~ msgid "%s: failed to remove contents of WAL directory\n" +#~ msgstr "%s : échec de la suppression du contenu du répertoire des journaux de transactions\n" + +#~ msgid "%s: removing contents of WAL directory \"%s\"\n" +#~ msgstr "%s : suppression du contenu du répertoire des journaux de transactions « %s »\n" + +#~ msgid "%s: failed to remove WAL directory\n" +#~ msgstr "%s : échec de la suppression du répertoire des journaux de transactions\n" + +#~ msgid "%s: removing WAL directory \"%s\"\n" +#~ msgstr "%s : suppression du répertoire des journaux de transactions « %s »\n" + +#~ msgid "%s: failed to remove contents of data directory\n" +#~ msgstr "%s : échec de la suppression du contenu du répertoire des données\n" + +#~ msgid "%s: removing contents of data directory \"%s\"\n" +#~ msgstr "%s : suppression du contenu du répertoire des données « %s »\n" + +#~ msgid "%s: failed to remove data directory\n" +#~ msgstr "%s : échec de la suppression du répertoire des données\n" + +#~ msgid "%s: removing data directory \"%s\"\n" +#~ msgstr "%s : suppression du répertoire des données « %s »\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu renommer le fichier « %s » en « %s » : %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" + +#~ msgid "select() failed: %m" +#~ msgstr "échec de select() : %m" diff --git a/src/bin/pg_basebackup/po/ja.po b/src/bin/pg_basebackup/po/ja.po new file mode 100644 index 000000000000..1ecac3c55c32 --- /dev/null +++ b/src/bin/pg_basebackup/po/ja.po @@ -0,0 +1,1568 @@ +# Japanese message translation file for pg_basebackup +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# , 2013 +msgid "" +msgstr "" +"Project-Id-Version: pg_basebackup (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:54+0900\n" +"PO-Revision-Date: 2020-09-13 08:55+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ポインタを複製できません (内部エラー)\n" + +#: ../../common/file_utils.c:84 ../../common/file_utils.c:186 +#: pg_receivewal.c:266 pg_recvlogical.c:340 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "ファイル\"%s\"のstatに失敗しました: %m" + +#: ../../common/file_utils.c:163 pg_receivewal.c:169 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: ../../common/file_utils.c:197 pg_receivewal.c:337 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m" + +#: ../../common/file_utils.c:229 ../../common/file_utils.c:288 +#: ../../common/file_utils.c:362 ../../fe_utils/recovery_gen.c:134 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: ../../common/file_utils.c:300 ../../common/file_utils.c:370 +#: pg_recvlogical.c:193 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "ファイル\"%s\"をfsyncできませんでした: %m" + +#: ../../common/file_utils.c:380 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "メモリ不足です" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "ファイル\"%s\"を書き込めませんでした: %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "ファイル\"%s\"を作成できませんでした: %m" + +#: pg_basebackup.c:224 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "データディレクトリ\"%s\"を削除しています" + +#: pg_basebackup.c:226 +#, c-format +msgid "failed to remove data directory" +msgstr "データディレクトリの削除に失敗しました" + +#: pg_basebackup.c:230 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "データディレクトリ\"%s\"の内容を削除しています" + +#: pg_basebackup.c:232 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "データディレクトリの中身の削除に失敗しました" + +#: pg_basebackup.c:237 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "WAL ディレクトリ\"%s\"を削除しています" + +#: pg_basebackup.c:239 +#, c-format +msgid "failed to remove WAL directory" +msgstr "WAL ディレクトリの削除に失敗しました" + +#: pg_basebackup.c:243 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "WAL ディレクトリ\"%s\"の中身を削除しています" + +#: pg_basebackup.c:245 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "WAL ディレクトリの中身の削除に失敗しました" + +#: pg_basebackup.c:251 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "ユーザの要求により、データディレクトリ\"%s\"を削除しませんでした" + +#: pg_basebackup.c:254 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "ユーザの要求により、WAL ディレクトリ\"%s\"を削除しませんでした" + +#: pg_basebackup.c:258 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "テーブル空間用ディレクトリへの変更は取り消されません" + +#: pg_basebackup.c:299 +#, c-format +msgid "directory name too long" +msgstr "ディレクトリ名が長すぎます" + +#: pg_basebackup.c:309 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "テーブル空間のマッピングに複数の\"=\"記号があります" + +#: pg_basebackup.c:321 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "テーブル空間のマッピング形式\"%s\"が不正です。\"旧DIR=新DIR\"でなければなりません" + +#: pg_basebackup.c:333 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "テーブル空間のマッピングにおいて、旧ディレクトリが絶対パスではありません: %s" + +#: pg_basebackup.c:340 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "テーブル空間のマッピングにおいて、新ディレクトリが絶対パスではありません: %s" + +#: pg_basebackup.c:379 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%sは実行中のPostgreSQLサーバのベースバックアップを取得します。\n" +"\n" + +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [オプション]...\n" + +#: pg_basebackup.c:383 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"出力を制御するオプション:\n" + +#: pg_basebackup.c:384 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=DIRECTORY ベースバックアップをディレクトリ内に格納\n" + +#: pg_basebackup.c:385 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t 出力フォーマット(プレイン(デフォルト)またはtar)\n" + +#: pg_basebackup.c:386 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=RATE データディレクトリ転送の際の最大転送速度\n" +" (kB/s 単位、または 接尾辞 \"k\" か\"M\" を使用)\n" + +#: pg_basebackup.c:388 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" レプリケーションのための設定を書き込む\n" + +#: pg_basebackup.c:390 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=旧DIR=新DIR\n" +" テーブル空間を旧DIRから新DIRに移動する\n" + +#: pg_basebackup.c:392 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALDIR 先行書き込みログ用ディレクトリの位置\n" + +#: pg_basebackup.c:393 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" 要求されたWALファイルを指定のメソッドを使ってバック\n" +" アップに含める\n" + +#: pg_basebackup.c:395 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip tar の出力を圧縮する\n" + +#: pg_basebackup.c:396 +#, c-format +msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 指定した圧縮レベルで tar の出力を圧縮する\n" + +#: pg_basebackup.c:397 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"汎用オプション:\n" + +#: pg_basebackup.c:398 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" 高速または分散チェックポイント処理の指定\n" + +#: pg_basebackup.c:400 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot 新しいレプリケーションスロットを作成する\n" + +#: pg_basebackup.c:401 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=LABEL バックアップラベルの設定\n" + +#: pg_basebackup.c:402 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --noclean エラー発生後作成したファイルの削除を行わない\n" + +#: pg_basebackup.c:403 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --nosync ディスクへの安全な書き込みを待機しない\n" + +#: pg_basebackup.c:404 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress 進行状況の表示\n" + +#: pg_basebackup.c:405 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=スロット名 使用するレプリケーションスロット\n" + +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose 冗長メッセージの出力\n" + +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_basebackup.c:408 +#, c-format +msgid "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" 目録チェックサムに使用するアルゴリズム\n" + +#: pg_basebackup.c:410 +#, c-format +msgid "" +" --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr "" +" --manifest-force-encode\n" +" 目録中の全てのファイル名を16進エンコードする\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr " --no-estimate-size サーバ側でバックアップサイズを見積もらない\n" + +#: pg_basebackup.c:413 +#, c-format +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr " --no-manifest バックアップ目録の作成を省略する\n" + +#: pg_basebackup.c:414 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot 一時レプリケーションスロットの作成を行わない\n" + +#: pg_basebackup.c:415 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" チェックサムを検証しない\n" + +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"接続オプション:\n" + +#: pg_basebackup.c:419 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONNSTR 接続文字列\n" + +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME データベースサーバホストまたはソケットディレクトリ\n" + +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT データベースサーバのポート番号\n" + +#: pg_basebackup.c:422 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in seconds)\n" +msgstr "" +" -s, --status-interval=INTERVAL\n" +" サーバへ送出するステータスパケットの間隔(秒単位)\n" + +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME 指定したデータベースユーザで接続\n" + +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password パスワードの入力を要求しない\n" + +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password パスワード入力要求を強制(自動的に行われるはず)\n" + +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_basebackup.c:471 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "準備ができたパイプからの読み込みが失敗しました: %m" + +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "先行書き込みログの位置\"%s\"をパースできませんでした" + +#: pg_basebackup.c:573 pg_receivewal.c:441 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "WALファイルの書き込みを終了できませんでした: %m" + +#: pg_basebackup.c:620 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "バックグランドプロセス用のパイプを作成できませんでした: \"%m" + +#: pg_basebackup.c:655 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "一時レプリケーションスロット\"%s\"を作成しました" + +#: pg_basebackup.c:658 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "レプリケーションスロット\"%s\"を作成していました" + +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not create background process: %m" +msgstr "バックグラウンドプロセスを生成できませんでした: %m" + +#: pg_basebackup.c:708 +#, c-format +msgid "could not create background thread: %m" +msgstr "バックグラウンドスレッドを生成できませんでした: %m" + +#: pg_basebackup.c:752 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "ディレクトリ\"%s\"は存在しますが空ではありません" + +#: pg_basebackup.c:759 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m" + +#: pg_basebackup.c:824 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d テーブル空間 %*s" + +#: pg_basebackup.c:836 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d テーブル空間 (%s%-*.*s)" + +#: pg_basebackup.c:852 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d テーブル空間" + +#: pg_basebackup.c:877 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "転送速度\"%s\"は無効な値です" + +#: pg_basebackup.c:882 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "転送速度\"%s\"は無効です: %m" + +#: pg_basebackup.c:891 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "転送速度は0より大きな値でなければなりません" + +#: pg_basebackup.c:923 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "--max-rate の単位が不正です: \"%s\"" + +#: pg_basebackup.c:930 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "転送速度\"%s\"がintegerの範囲を超えています" + +#: pg_basebackup.c:940 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "転送速度\"%s\"が範囲外です" + +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "COPYデータストリームを取得できませんでした: %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:965 +#, c-format +msgid "could not read COPY data: %s" +msgstr "COPYデータを読み取ることができませんでした: %s" + +#: pg_basebackup.c:1007 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "圧縮ファイル\"%s\"に書き込めませんでした: %s" + +#: pg_basebackup.c:1071 +#, c-format +msgid "could not duplicate stdout: %m" +msgstr "標準出力の複製に失敗しました: %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "出力ファイルをオープンできませんでした: %m" + +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "圧縮レベルを%dに設定できませんでした: %s" + +#: pg_basebackup.c:1155 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "圧縮ファイル\"%s\"を作成できませんでした: %s" + +#: pg_basebackup.c:1267 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "圧縮ファイル\"%s\"を閉じることができませんでした: %s" + +#: pg_basebackup.c:1279 pg_recvlogical.c:632 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "ファイル\"%s\"をクローズできませんでした: %m" + +#: pg_basebackup.c:1541 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "最後のファイルが終わる前にCOPYストリームが終了しました" + +#: pg_basebackup.c:1570 +#, c-format +msgid "invalid tar block header size: %zu" +msgstr "無効なtarブロックヘッダサイズ: %zu" + +#: pg_basebackup.c:1627 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"に権限を設定できませんでした: %m" + +#: pg_basebackup.c:1651 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "\"%s\"から\"%s\"へのシンボリックリンクを作成できませんでした: %m" + +#: pg_basebackup.c:1658 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "リンク指示子\"%c\"を認識できません" + +#: pg_basebackup.c:1677 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "ファイル\"%s\"の権限を設定できませんでした: %m" + +#: pg_basebackup.c:1831 +#, c-format +msgid "incompatible server version %s" +msgstr "非互換のサーババージョン \"%s\"" + +#: pg_basebackup.c:1846 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "ヒント: -X none または -X fetch でログストリーミングを無効にできます" + +#: pg_basebackup.c:1882 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "ベースバックアップを開始しています - チェックポイントの完了を待機中" + +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:481 receivelog.c:530 +#: receivelog.c:569 streamutil.c:297 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "レプリケーションコマンド\"%s\"を送信できませんでした: %s" + +#: pg_basebackup.c:1919 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "ベースバックアップを開始できませんでした: %s" + +#: pg_basebackup.c:1925 +#, c-format +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "サーバが BASE_BACKUP コマンドに期待していない応答を返しました; %d行 %d列を受信しましたが期待は %d列 %d行でした" + +#: pg_basebackup.c:1933 +#, c-format +msgid "checkpoint completed" +msgstr "チェックポイントが完了しました" + +#: pg_basebackup.c:1948 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "先行書き込みログの開始ポイント: タイムライン %2$u 上の %1$s" + +#: pg_basebackup.c:1957 +#, c-format +msgid "could not get backup header: %s" +msgstr "バックアップヘッダを取得できませんでした: %s" + +#: pg_basebackup.c:1963 +#, c-format +msgid "no data returned from server" +msgstr "サーバからデータが返されませんでした" + +#: pg_basebackup.c:1995 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "標準出力に書き出せるテーブル空間は1つだけですが、データベースには%d個あります" + +#: pg_basebackup.c:2007 +#, c-format +msgid "starting background WAL receiver" +msgstr "バックグランドWAL受信処理を起動します" + +#: pg_basebackup.c:2046 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "サーバから先行書き込みログの終了位置を取得できませんでした: %s" + +#: pg_basebackup.c:2052 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "サーバから先行書き込みログの終了位置が返されませんでした" + +#: pg_basebackup.c:2057 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "先行書き込みログの終了ポイント: %s" + +#: pg_basebackup.c:2068 +#, c-format +msgid "checksum error occurred" +msgstr "チェックサムエラーが発生しました" + +#: pg_basebackup.c:2073 +#, c-format +msgid "final receive failed: %s" +msgstr "終端の受信に失敗しました: %s" + +#: pg_basebackup.c:2097 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "バックグランドプロセスがストリーミング処理が終わるまで待機します ..." + +#: pg_basebackup.c:2102 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "バックグランドへのパイプにコマンドを送信できませんでした: %m" + +#: pg_basebackup.c:2110 +#, c-format +msgid "could not wait for child process: %m" +msgstr "子プロセスの待機ができませんでした: %m" + +#: pg_basebackup.c:2115 +#, c-format +msgid "child %d died, expected %d" +msgstr "子プロセス %d が終了しましたが、期待していたのは %d でした" + +#: pg_basebackup.c:2120 streamutil.c:92 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2145 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "子スレッドの待機ができませんでした: %m" + +#: pg_basebackup.c:2151 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "子スレッドの終了ステータスを取得できませんでした: %m" + +#: pg_basebackup.c:2156 +#, c-format +msgid "child thread exited with error %u" +msgstr "子スレッドがエラー%uで終了しました" + +#: pg_basebackup.c:2184 +#, c-format +msgid "syncing data to disk ..." +msgstr "データをディスクに同期しています..." + +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "backup_manifest.tmp の名前を backup_manifest に変更してください" + +#: pg_basebackup.c:2220 +#, c-format +msgid "base backup completed" +msgstr "ベースバックアップが完了しました" + +#: pg_basebackup.c:2305 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" +msgstr "不正な出力フォーマット\"%s\"、\"plain\"か\"tar\"でなければなりません" + +#: pg_basebackup.c:2349 +#, c-format +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "不正な wal-method オプション\"%s\"、\"fetch\"、\"stream\" または \"none\" のいずれかでなければなりません" + +#: pg_basebackup.c:2377 pg_receivewal.c:580 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "無効な圧縮レベル \"%s\"" + +#: pg_basebackup.c:2388 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "不正な checkpoint の引数\"%s\"、\"fast\" または \"spreadでなければなりません" + +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "不正な status-interval \"%s\"" + +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2528 +#: pg_basebackup.c:2539 pg_basebackup.c:2549 pg_basebackup.c:2567 +#: pg_basebackup.c:2576 pg_basebackup.c:2585 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"で確認してください。\n" + +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "コマンドライン引数が多過ぎます(先頭は\"%s\"です)" + +#: pg_basebackup.c:2468 pg_receivewal.c:654 +#, c-format +msgid "no target directory specified" +msgstr "格納先ディレクトリが指定されていません" + +#: pg_basebackup.c:2479 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "tarモードでのバックアップのみが圧縮可能です" + +#: pg_basebackup.c:2487 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "標準出力への tar モードでは書き込み先行ログをストリーム出力できません" + +#: pg_basebackup.c:2495 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "レプリケーションスロットはWALストリーミングでのみ使用可能です" + +#: pg_basebackup.c:2505 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot はスロット名と同時には指定できません" + +#. translator: second %s is an option name +#: pg_basebackup.c:2517 pg_receivewal.c:634 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "%s は --slot でスロットを指定する必要があります" + +#: pg_basebackup.c:2526 pg_basebackup.c:2565 pg_basebackup.c:2574 +#: pg_basebackup.c:2583 +#, c-format +msgid "%s and %s are incompatible options" +msgstr "%s と %s は非互換なオプションです" + +#: pg_basebackup.c:2538 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "WALディレクトリの位置は plainモードでのみ指定可能です" + +#: pg_basebackup.c:2548 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WALディレクトリの位置は、絶対パスでなければなりません" + +#: pg_basebackup.c:2558 pg_receivewal.c:663 +#, c-format +msgid "this build does not support compression" +msgstr "このビルドでは圧縮をサポートしていません" + +#: pg_basebackup.c:2643 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を作成できませんでした: %m" + +#: pg_basebackup.c:2647 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "このプラットフォームでシンボリックリンクはサポートされていません" + +#: pg_receivewal.c:77 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%sはPostgreSQLの先行書き込みログストリームを受信します。\n" +"\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:81 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: pg_receivewal.c:82 +#, c-format +msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr " -D, --directory=DIR 受信した先行書き込みログの格納ディレクトリ\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:82 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN 指定したLSNの受信後に終了\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:86 +#, c-format +msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgstr "   --if-not-exists スロットの作成時に既に存在していてもエラーとしない\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:88 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop 接続断の際にループしない\n" + +#: pg_receivewal.c:86 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync ディスクへの安全な書き込みの待機を行わない\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:93 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server (default: %d)\n" +msgstr "" +" -s, --status-interval=SECS\n" +" サーバへ送出するステータスパケットの間隔\n" +" (デフォルト: %d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid " --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous 先行書き込みログを書き込み後直ちにフラッシュ\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 指定した圧縮レベルでログを圧縮\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"追加の動作:\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:78 +#, c-format +msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgstr "" +" --create-slot 新しいレプリケーションスロットを作成する\n" +" (スロット名については --slot を参照)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:79 +#, c-format +msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgstr "" +" --drop-slot レプリケーションスロットを削除する\n" +" (スロット名については --slot を参照)\n" + +#: pg_receivewal.c:117 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "%X/%X (タイムライン %u)でセグメントが完了" + +#: pg_receivewal.c:124 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "%X/%X (タイムライン %u)でログのストリーミングを停止しました" + +#: pg_receivewal.c:140 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "%3$X/%2$Xで タイムライン%1$uに切り替えました" + +#: pg_receivewal.c:150 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "割り込みシグナルを受信、終了します" + +#: pg_receivewal.c:186 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" + +#: pg_receivewal.c:272 +#, c-format +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "セグメントファイル\"%s\"のサイズ %d が不正です、スキップします" + +#: pg_receivewal.c:290 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "圧縮ファイル\"%s\"を開けませんでした: %m" + +#: pg_receivewal.c:296 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "圧縮ファイル\"%s\"でseekできませんでした: %m" + +#: pg_receivewal.c:304 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "圧縮ファイル\"%s\"を読めませんでした: %m" + +#: pg_receivewal.c:307 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "圧縮ファイル\"%1$s\"を読めませんでした: %3$zuバイトのうち%2$dバイトを読み込み済み" + +#: pg_receivewal.c:318 +#, c-format +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "圧縮セグメントファイル\"%s\"の展開後サイズ%dが不正です、スキップします" + +#: pg_receivewal.c:422 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "%X/%X (タイムライン %u)からログのストリーミングを開始" + +#: pg_receivewal.c:537 pg_recvlogical.c:762 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "不正なポート番号: \"%s\"" + +#: pg_receivewal.c:565 pg_recvlogical.c:788 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "終了位置\"%s\"をパースできませんでした" + +#: pg_receivewal.c:625 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "--create-slot は --drop-slot と同時には指定できません" + +#: pg_receivewal.c:643 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "--synchronous は --no-sync と同時には指定できません" + +#: pg_receivewal.c:719 +#, c-format +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "スロット\"%s\"を使用するレプリケーション接続で、想定に反してデータベースが指定されています" + +#: pg_receivewal.c:730 pg_recvlogical.c:966 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "レプリケーションスロット\"%s\"を削除しています" + +#: pg_receivewal.c:741 pg_recvlogical.c:976 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "レプリケーションスロット\"%s\"を作成しています" + +#: pg_receivewal.c:767 pg_recvlogical.c:1001 +#, c-format +msgid "disconnected" +msgstr "切断しました" + +#. translator: check source for value for %d +#: pg_receivewal.c:773 pg_recvlogical.c:1007 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "切断しました; %d秒待機して再試行します" + +#: pg_recvlogical.c:73 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s はPostgreSQLの論理デコードストリームを制御します。\n" +"\n" + +#: pg_recvlogical.c:77 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"実行する動作:\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgstr "" +" --start レプリケーションスロットでストリーミングを開始する\n" +" (スロット名については --slot を参照)\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=FILE このファイルにログを受け取る、 - で標準出力\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: %d)\n" +msgstr "" +" -F --fsync-interval=SECS\n" +" 出力ファイルへのfsync時間間隔(デフォルト: %d)\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgstr " -I, --startpos=LSN 既存スロット内のストリーミング開始位置\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NAME[=VALUE]\n" +" 出力プラグインにオプションNAMEをオプション値VALUEと\n" +" ともに渡す\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr " -P, --plugin=PLUGIN 出力プラグインPLUGINを使う(デフォルト: %s)\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=SLOTNAME 論理レプリケーションスロットの名前\n" + +#: pg_recvlogical.c:100 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=DBNAME 接続先データベース\n" + +#: pg_recvlogical.c:133 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "PrecPpg%X/%Xまでの書き込みと、%X/%X (スロット %s)までのフラッシュを確認しています" + +#: pg_recvlogical.c:157 receivelog.c:343 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "フィードバックパケットを送信できませんでした: %s" + +#: pg_recvlogical.c:230 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "%X/%X (スロット %s)からログのストリーミングを開始します" + +#: pg_recvlogical.c:271 +#, c-format +msgid "streaming initiated" +msgstr "ストリーミングを開始しました" + +#: pg_recvlogical.c:335 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "ロックファイル\"%s\"をオープンできませんでした: %m" + +#: pg_recvlogical.c:361 receivelog.c:873 +#, c-format +msgid "invalid socket: %s" +msgstr "無効なソケット: %s" + +#: pg_recvlogical.c:414 receivelog.c:901 +#, c-format +msgid "select() failed: %m" +msgstr "select()が失敗しました: %m" + +#: pg_recvlogical.c:421 receivelog.c:951 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "WAL ストリームからデータを受信できませんでした: %s" + +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:995 receivelog.c:1061 +#, c-format +msgid "streaming header too small: %d" +msgstr "ストリーミングヘッダが小さ過ぎます: %d" + +#: pg_recvlogical.c:498 receivelog.c:833 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "ストリーミングヘッダを認識できませんでした: \"%c\"" + +#: pg_recvlogical.c:552 pg_recvlogical.c:564 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "%u バイトをログファイル\"%s\"に書き込めませんでした: %m" + +#: pg_recvlogical.c:618 receivelog.c:629 receivelog.c:666 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "レプリケーションストリームが突然終了しました: %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "不正なfsync間隔 \"%s\"" + +#: pg_recvlogical.c:780 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "開始位置\"%s\"をパースできませんでした" + +#: pg_recvlogical.c:869 +#, c-format +msgid "no slot specified" +msgstr "スロットが指定されていません" + +#: pg_recvlogical.c:877 +#, c-format +msgid "no target file specified" +msgstr "ターゲットファイルが指定されていません" + +#: pg_recvlogical.c:885 +#, c-format +msgid "no database specified" +msgstr "データベースが指定されていません" + +#: pg_recvlogical.c:893 +#, c-format +msgid "at least one action needs to be specified" +msgstr "少なくとも一つのアクションを指定する必要があります" + +#: pg_recvlogical.c:901 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "--create-slot や --start は --drop-slot と同時には指定できません" + +#: pg_recvlogical.c:909 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "--create-slot や --drop-slot は --startpos と同時には指定できません" + +#: pg_recvlogical.c:917 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos は --start が指定されているときにのみ指定可能です" + +#: pg_recvlogical.c:948 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "データベース指定のレプリケーション接続が確立できませんでした" + +#: pg_recvlogical.c:1047 +#, c-format +msgid "end position %X/%X reached by keepalive" +msgstr "キープアライブで終了位置 %X/%X に到達しました " + +#: pg_recvlogical.c:1050 +#, c-format +msgid "end position %X/%X reached by WAL record at %X/%X" +msgstr "%X/%X のWALレコードで終了位置 %X/%X に到達しました" + +#: receivelog.c:69 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "アーカイブステータスファイル\"%s\"を作成できませんでした: %s" + +#: receivelog.c:116 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "先行書き込みログファイル\"%s\"のサイズを取得できませんでした: %s" + +#: receivelog.c:126 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "既存の先行書き込みログファイル\"%s\"をオープンできませんでした: %s" + +#: receivelog.c:134 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "既存の先行書き込みログファイル\"%s\"をfsyncできませんでした: %s" + +#: receivelog.c:148 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "先行書き込みログファイル\"%s\"は%dバイトですが、0または%dであるはずです" + +#: receivelog.c:163 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "先行書き込みログファイル\"%s\"をオープンできませんでした: %s" + +#: receivelog.c:189 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "ファイル\"%s\"のシーク位置を取得できませんでした: %s" + +#: receivelog.c:203 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "\"%s%s\"の名前を変更しません、セグメントが完全ではありません" + +#: receivelog.c:215 receivelog.c:300 receivelog.c:675 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "ファイル\"%s\"をクローズできませんでした: %s" + +#: receivelog.c:272 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "サーバがタイムライン%uに対する想定外の履歴ファイル名を通知してきました: %s" + +#: receivelog.c:280 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "タイムライン履歴ファイル\"%s\"を作成できませんでした: %s" + +#: receivelog.c:287 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "タイムライン履歴ファイル\"%s\"に書き込めませんでした: %s" + +#: receivelog.c:377 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "非互換のサーババージョン%s、クライアントは%sより古いサーババージョンからのストリーミングをサポートしていません" + +#: receivelog.c:386 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "非互換のサーババージョン%s、クライアントは%sより新しいサーババージョンからのストリーミングをサポートしていません" + +#: receivelog.c:488 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "システムを識別できませんでした: 受信したのは%d行%d列、想定は%d行%d列以上" + +#: receivelog.c:495 +#, c-format +msgid "system identifier does not match between base backup and streaming connection" +msgstr "システム識別子がベースバックアップとストリーミング接続の間で一致しません" + +#: receivelog.c:501 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "開始タイムライン%uがサーバに存在しません" + +#: receivelog.c:542 +#, c-format +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "TIMELINE_HISTORYコマンドへの想定外の応答: 受信したのは%d行%d列、想定は%d行%d列" + +#: receivelog.c:613 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "サーバがタイムライン%2$uに続いて想定外のタイムライン%1$uを通知してきました" + +#: receivelog.c:619 +#, c-format +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "サーバはタイムライン%uのストリーミングを%X/%Xで停止しました、しかし次のタイムライン%uが%X/%Xから開始すると通知してきています" + +#: receivelog.c:659 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "レプリケーションストリームが停止ポイントより前で終了しました" + +#: receivelog.c:705 +#, c-format +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "タイムライン終了後に想定外の結果セット: 受信したのは%d行%d列、想定は%d行%d列" + +#: receivelog.c:714 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "次のタイムラインの開始ポイント\"%s\"をパースできませんでした" + +#: receivelog.c:763 receivelog.c:1015 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "ファイル\"%s\"をfsyncできませんでした: %s" + +#: receivelog.c:1078 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "ファイルがオープンされていない状態で、オフセット%uに対する先行書き込みログレコードを受信しました" + +#: receivelog.c:1088 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "WALデータオフセット%08xを受信、想定は%08x" + +#: receivelog.c:1122 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "WALファイル\"%2$s\"に%1$uバイト書き込めませんでした: %3$s" + +#: receivelog.c:1147 receivelog.c:1187 receivelog.c:1218 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "コピー終端パケットを送信できませんでした: %s" + +#: streamutil.c:160 +msgid "Password: " +msgstr "パスワード: " + +#: streamutil.c:185 +#, c-format +msgid "could not connect to server" +msgstr "サーバに接続できませんでした" + +#: streamutil.c:202 +#, c-format +msgid "could not connect to server: %s" +msgstr "サーバに接続できませんでした: %s" + +#: streamutil.c:231 +#, c-format +msgid "could not clear search_path: %s" +msgstr "search_pathを消去できませんでした: %s" + +#: streamutil.c:247 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "integer_datetimesのサーバ設定を取得できませんでした" + +#: streamutil.c:254 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "integer_datetimesコンパイル時フラグがサーバと一致しません" + +#: streamutil.c:305 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "WALセグメントサイズを取得できませんでした: 受信したのは%d行で%d列、想定は%d行で%d列以上" + +#: streamutil.c:315 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "WALセグメントサイズがパースできませんでした" + +#: streamutil.c:333 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "WALセグメントのサイズ指定は1MBと1GBの間の2の累乗でなければなりません、しかし対向サーバは%dバイトと報告してきました" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "グループアクセスフラグを取得できませんでした: 受信したのは%d行で%d列、想定は%d行で%d列以上" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "グループアクセスフラグがパースできませんでした: %s" + +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "レプリケーションスロット\"%s\"を作成できませんでした: 受信したのは%d行%d列、想定は%d行%d列" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "レプリケーションスロット\"%s\"を削除できませんでした: 受信したのは%d行%d列、想定は%d行%d列" + +#: walmethods.c:438 walmethods.c:932 +msgid "could not compress data" +msgstr "データを圧縮できませんでした" + +#: walmethods.c:470 +msgid "could not reset compression stream" +msgstr "圧縮ストリームをリセットできませんでした" + +#: walmethods.c:568 +msgid "could not initialize compression library" +msgstr "圧縮ライブラリを初期化できませんでした" + +#: walmethods.c:580 +msgid "implementation error: tar files can't have more than one open file" +msgstr "実装エラー:tar ファイルが複数のオープンされたファイルを保持できません" + +#: walmethods.c:594 +msgid "could not create tar header" +msgstr "tar ヘッダを作成できませんでした" + +#: walmethods.c:608 walmethods.c:650 walmethods.c:847 walmethods.c:859 +msgid "could not change compression parameters" +msgstr "圧縮用パラメーターを変更できませんでした" + +#: walmethods.c:734 +msgid "unlink not supported with compression" +msgstr "圧縮モードにおける unlink はサポートしていません" + +#: walmethods.c:957 +msgid "could not close compression stream" +msgstr "圧縮ストリームをクローズできませんでした" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: \"%s\"ファイルをstatできませんでした: %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"をオープンできませんでした: %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"を読み取ることができませんでした。: %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"をオープンできませんでした: %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"をfsyncできませんでした: %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %s\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ \"%s\" を作成できませんでした: %s\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ \"%s\" にアクセスできませんでした: %s\n" + +#~ msgid "%s: could not write to file \"%s\": %s\n" +#~ msgstr "%s: ファイル \"%s\" に書き出すことができませんでした: %s\n" + +#~ msgid "%s: could not create file \"%s\": %s\n" +#~ msgstr "%s: ファイル \"%s\" を作成できませんでした: %s\n" + +#~ msgid "%s: could not close file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"を閉じることができませんでした: %s\n" + +#~ msgid "%s: could not set permissions on directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\"ディレクトリの権限を設定できませんでした: %s\n" + +#~ msgid "%s: could not set permissions on file \"%s\": %s\n" +#~ msgstr "%s: ファイル \"%s\" の権限を設定できませんでした: %s\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: メモリ不足です\n" + +#~ msgid "%s: child process did not exit normally\n" +#~ msgstr "%s: 子プロセスが正常に終了しませんでした\n" + +#~ msgid "%s: child process exited with error %d\n" +#~ msgstr "%s: 子プロセスが終了コード%dで終了しました\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: シンボリックリンク\"%s\"を作成できませんでした: %s\n" + +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s: シンボリックリンクはこのプラットフォームではサポートされていません\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ \"%s\" をクローズできませんでした: %s\n" + +#~ msgid "%s: invalid port number \"%s\"\n" +#~ msgstr "%s: 無効なポート番号です: \"%s\"\n" + +#~ msgid "%s: could not fsync log file \"%s\": %s\n" +#~ msgstr "%s: ログファイル\"%s\"をfsyncできませんでした: %s\n" + +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s: ログファイル \"%s\" をオープンできませんでした: %s\n" + +#~ msgid "%s: select() failed: %s\n" +#~ msgstr "%s: select()が失敗しました: %s\n" + +#~ msgid "%s: could not receive data from WAL stream: %s" +#~ msgstr "%s: WALストリームからデータを受信できませんでした: %s" + +#~ msgid "%s: could not create archive status file \"%s\": %s\n" +#~ msgstr "%s: アーカイブ状態ファイル \"%s\" を作成できませんでした: %s\n" + +#~ msgid "%s: could not open write-ahead log file \"%s\": %s\n" +#~ msgstr "%s: 先行書き込みログファイル \"%s\" をオープンできませんでした: %s\n" + +#~ msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" +#~ msgstr "%s: システムを識別できませんでした: 受信したのは %d 行で %d フィールド、期待していたのは%d 行で %d 以上のフィールドでした\n" + +#~ msgid "%s: could not connect to server\n" +#~ msgstr "%s: サーバに接続できませんでした\n" + +#~ msgid "%s: could not connect to server: %s" +#~ msgstr "%s: サーバに接続できませんでした: %s" diff --git a/src/bin/pg_basebackup/po/ko.po b/src/bin/pg_basebackup/po/ko.po new file mode 100644 index 000000000000..bbd19de74311 --- /dev/null +++ b/src/bin/pg_basebackup/po/ko.po @@ -0,0 +1,1588 @@ +# LANGUAGE message translation file for pg_basebackup +# Copyright (C) 2015 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2015 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_basebackup (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 01:15+0000\n" +"PO-Revision-Date: 2020-10-06 11:02+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null 포인터를 복제할 수 없음(내부 오류)\n" + +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 +#: pg_receivewal.c:266 pg_recvlogical.c:340 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" 파일의 상태값을 알 수 없음: %m" + +#: ../../common/file_utils.c:158 pg_receivewal.c:169 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 열 수 없음: %m" + +#: ../../common/file_utils.c:192 pg_receivewal.c:337 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 읽을 수 없음: %m" + +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 ../../fe_utils/recovery_gen.c:134 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" 파일을 열 수 없음: %m" + +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 +#: pg_recvlogical.c:193 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "\"%s\" 파일 fsync 실패: %m" + +#: ../../common/file_utils.c:375 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "\"%s\" 파일을 \"%s\" 파일로 이름을 바꿀 수 없음: %m" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "메모리 부족" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "\"%s\" 파일 쓰기 실패: %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "\"%s\" 파일을 만들 수 없음: %m" + +#: pg_basebackup.c:224 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "\"%s\" 디렉터리를 지우는 중" + +#: pg_basebackup.c:226 +#, c-format +msgid "failed to remove data directory" +msgstr "데이터 디렉터리 삭제 실패" + +#: pg_basebackup.c:230 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "\"%s\" 데이터 디렉터리의 내용을 지우는 중" + +#: pg_basebackup.c:232 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "데이터 디렉터리의 내용을 지울 수 없음" + +#: pg_basebackup.c:237 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "\"%s\" WAL 디렉터리를 지우는 중" + +#: pg_basebackup.c:239 +#, c-format +msgid "failed to remove WAL directory" +msgstr "WAL 디렉터리 삭제 실패" + +#: pg_basebackup.c:243 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "\"%s\" WAL 디렉터리 내용을 지우는 중" + +#: pg_basebackup.c:245 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "WAL 디렉터리의 내용을 지울 수 없음" + +#: pg_basebackup.c:251 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "사용자 요청으로 \"%s\" 데이터 디렉터리를 지우지 않았음" + +#: pg_basebackup.c:254 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "사용자 요청으로 \"%s\" WAL 디렉터리를 지우지 않았음" + +#: pg_basebackup.c:258 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "아직 마무리 되지 않은 테이블스페이스 디렉터리 변경함" + +#: pg_basebackup.c:299 +#, c-format +msgid "directory name too long" +msgstr "디렉터리 이름이 너무 김" + +#: pg_basebackup.c:309 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "테이블스페이스 맵핑 하는 곳에서 \"=\" 문자가 중복 되어 있음" + +#: pg_basebackup.c:321 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "" +"\"%s\" 형식의 테이블스페이스 맵핑이 잘못 되었음, \"OLDDIR=NEWDIR\" 형식이어" +"야 함" + +#: pg_basebackup.c:333 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "테이블스페이스 맵핑용 옛 디렉터리가 절대 경로가 아님: %s" + +#: pg_basebackup.c:340 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "테이블스페이스 맵핑용 새 디렉터리가 절대 경로가 아님: %s" + +#: pg_basebackup.c:379 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s 프로그램은 운영 중인 PostgreSQL 서버에 대해서 베이스 백업을 하는 도구입니" +"다.\n" +"\n" + +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [옵션]...\n" + +#: pg_basebackup.c:383 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"출력물을 제어야하는 옵션들:\n" + +#: pg_basebackup.c:384 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=디렉터리 베이스 백업 결과물이 저장될 디렉터리\n" + +#: pg_basebackup.c:385 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t 출력 형식 (plain (초기값), tar)\n" + +#: pg_basebackup.c:386 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=속도 최대 전송 속도\n" +" (단위는 kB/s, 또는 숫자 뒤에 \"k\" 또는 \"M\" 단위 " +"문자 지정 가능)\n" + +#: pg_basebackup.c:388 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" 복제를 위한 환경 설정 함\n" + +#: pg_basebackup.c:390 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=옛DIR=새DIR\n" +" 테이블스페이스 디렉터리 새 맵핑\n" + +#: pg_basebackup.c:392 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALDIR 트랜잭션 로그 디렉터리 지정\n" + +#: pg_basebackup.c:393 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" 필요한 WAL 파일을 백업하는 방법\n" + +#: pg_basebackup.c:395 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip tar 출력물을 압축\n" + +#: pg_basebackup.c:396 +#, c-format +msgid "" +" -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 압축된 tar 파일의 압축 수위 지정\n" + +#: pg_basebackup.c:397 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"일반 옵션들:\n" + +#: pg_basebackup.c:398 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" 체크포인트 방법\n" + +#: pg_basebackup.c:400 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot 새 복제 슬롯을 만듬\n" + +#: pg_basebackup.c:401 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=라벨 백업 라벨 지정\n" + +#: pg_basebackup.c:402 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean 오류 발생 시 정리하지 않음\n" + +#: pg_basebackup.c:403 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr " -N, --no-sync 디스크 쓰기 뒤 sync 작업 생략\n" + +#: pg_basebackup.c:404 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress 진행 과정 보여줌\n" + +#: pg_basebackup.c:405 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=슬롯이름 지정한 복제 슬롯을 사용함\n" + +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose 자세한 작업 메시지 보여줌\n" + +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보 보여주고 마침\n" + +#: pg_basebackup.c:408 +#, c-format +msgid "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" 사용할 manifest 체크섬 알고리즘\n" + +#: pg_basebackup.c:410 +#, c-format +msgid "" +" --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr "" +" --manifest-force-encode\n" +" manifest 내 모든 파일 이름을 16진수 인코딩함\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr " --no-estimate-size 서버측 백업 크기를 예상하지 않음\n" + +#: pg_basebackup.c:413 +#, c-format +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr " --no-manifest 백업 매니페스트 만들지 않음\n" + +#: pg_basebackup.c:414 +#, c-format +msgid "" +" --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot 임시 복제 슬롯 만들지 않음\n" + +#: pg_basebackup.c:415 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" 체크섬 검사 안함\n" + +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"연결 옵션들:\n" + +#: pg_basebackup.c:419 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=접속문자열 서버 접속 문자열\n" + +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=호스트이름 접속할 데이터베이스 서버나 소켓 디렉터리\n" + +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=포트 데이터베이스 서버 포트 번호\n" + +#: pg_basebackup.c:422 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in " +"seconds)\n" +msgstr "" +" -s, --status-interval=초\n" +" 초 단위 매번 서버로 상태 패킷을 보냄\n" + +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=사용자 접속할 특정 데이터베이스 사용자\n" + +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password 비밀번호 물어 보지 않음\n" + +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr "" +" -W, --password 항상 비밀번호 프롬프트 보임 (자동으로 판단 함)\n" + +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"문제점 보고 주소: <%s>\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: pg_basebackup.c:471 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "준비된 파이프로부터 읽기 실패: %m" + +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "트랜잭션 로그 위치 \"%s\" 분석 실패" + +#: pg_basebackup.c:573 pg_receivewal.c:441 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "WAL 파일 쓰기 마무리 실패: %m" + +#: pg_basebackup.c:620 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "백그라운드 프로세스를 위한 파이프 만들기 실패: %m" + +#: pg_basebackup.c:655 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "\"%s\" 임시 복제 슬롯을 만들 수 없음" + +#: pg_basebackup.c:658 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "\"%s\" 이름의 복제 슬롯을 만듦" + +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 만들 수 없음: %m" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not create background process: %m" +msgstr "백그라운드 프로세스 만들기 실패: %m" + +#: pg_basebackup.c:708 +#, c-format +msgid "could not create background thread: %m" +msgstr "백그라운드 스래드 만들기 실패: %m" + +#: pg_basebackup.c:752 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "\"%s\" 디렉터리가 있지만 비어 있지 않음" + +#: pg_basebackup.c:759 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 액세스할 수 없습니다: %m" + +#: pg_basebackup.c:824 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d 테이블스페이스 %*s" + +#: pg_basebackup.c:836 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d 테이블스페이스 (%s%-*.*s)" + +#: pg_basebackup.c:852 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d 테이블스페이스" + +#: pg_basebackup.c:877 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "\"%s\" 전송 속도는 잘못된 값임" + +#: pg_basebackup.c:882 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "잘못된 전송 속도 \"%s\": %m" + +#: pg_basebackup.c:891 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "전송 속도는 0보다 커야 함" + +#: pg_basebackup.c:923 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "잘못된 --max-rate 단위: \"%s\"" + +#: pg_basebackup.c:930 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "\"%s\" 전송 속도는 정수형 범위가 아님" + +#: pg_basebackup.c:940 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "\"%s\" 전송 속도는 범위 초과" + +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "COPY 데이터 스트림을 사용할 수 없음: %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:965 +#, c-format +msgid "could not read COPY data: %s" +msgstr "COPY 자료를 읽을 수 없음: %s" + +#: pg_basebackup.c:1007 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "\"%s\" 압축 파일 쓰기 실패: %s" + +#: pg_basebackup.c:1071 +#, c-format +msgid "could not duplicate stdout: %m" +msgstr "stdout을 중복할 수 없음: %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "출력파일을 열 수 없음: %m" + +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "잘못된 압축 수위 %d: %s" + +#: pg_basebackup.c:1155 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "\"%s\" 압축 파일 만들기 실패: %s" + +#: pg_basebackup.c:1267 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "\"%s\" 압축 파일 닫기 실패: %s" + +#: pg_basebackup.c:1279 pg_recvlogical.c:632 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "\"%s\" 파일을 닫을 수 없음: %m" + +#: pg_basebackup.c:1541 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "마지막 파일을 끝내기 전에 COPY 스트림이 끝났음" + +#: pg_basebackup.c:1570 +#, c-format +msgid "invalid tar block header size: %zu" +msgstr "잘못된 tar 블럭 헤더 크기: %zu" + +#: pg_basebackup.c:1627 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 액세스 권한을 지정할 수 없음: %m" + +#: pg_basebackup.c:1651 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "\"%s\" 파일을 \"%s\" 심볼릭 링크로 만들 수 없음: %m" + +#: pg_basebackup.c:1658 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "알 수 없는 링크 지시자 \"%c\"" + +#: pg_basebackup.c:1677 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "파일 \"%s\" 의 접근권한을 지정할 수 없음: %m" + +#: pg_basebackup.c:1831 +#, c-format +msgid "incompatible server version %s" +msgstr "호환하지 않는 서버 버전 %s" + +#: pg_basebackup.c:1846 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "" +"힌트: 트랜잭션 로그 스트리밍을 사용하지 않으려면 -X none 또는 -X fetch 옵션" +"을 사용하세요." + +#: pg_basebackup.c:1882 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "베이스 백업을 초기화 중, 체크포인트 완료를 기다리는 중" + +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:481 receivelog.c:530 +#: receivelog.c:569 streamutil.c:297 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "\"%s\" 복제 명령을 보낼 수 없음: %s" + +#: pg_basebackup.c:1919 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "베이스 백업을 초기화 할 수 없음: %s" + +#: pg_basebackup.c:1925 +#, c-format +msgid "" +"server returned unexpected response to BASE_BACKUP command; got %d rows and " +"%d fields, expected %d rows and %d fields" +msgstr "" +"서버가 BASE_BACKUP 명령에 대해서 잘못된 응답을 했습니다; 응답값: %d 로우, %d " +"필드, (기대값: %d 로우, %d 필드)" + +#: pg_basebackup.c:1933 +#, c-format +msgid "checkpoint completed" +msgstr "체크포인트 완료" + +#: pg_basebackup.c:1948 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "트랙잭션 로그 시작 위치: %s, 타임라인: %u" + +#: pg_basebackup.c:1957 +#, c-format +msgid "could not get backup header: %s" +msgstr "백업 헤더를 구할 수 없음: %s" + +#: pg_basebackup.c:1963 +#, c-format +msgid "no data returned from server" +msgstr "서버가 아무런 자료도 주지 않았음" + +#: pg_basebackup.c:1995 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "" +"표준 출력으로는 하나의 테이블스페이스만 쓸 수 있음, 데이터베이스는 %d 개의 테" +"이블 스페이스가 있음" + +#: pg_basebackup.c:2007 +#, c-format +msgid "starting background WAL receiver" +msgstr "백그라운드 WAL 수신자 시작 중" + +#: pg_basebackup.c:2046 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "서버에서 트랜잭션 로그 마지막 위치를 구할 수 없음: %s" + +#: pg_basebackup.c:2052 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "서버에서 트랜잭션 로그 마지막 위치가 수신 되지 않았음" + +#: pg_basebackup.c:2057 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "트랜잭션 로그 마지막 위치: %s" + +#: pg_basebackup.c:2068 +#, c-format +msgid "checksum error occurred" +msgstr "체크섬 오류 발생" + +#: pg_basebackup.c:2073 +#, c-format +msgid "final receive failed: %s" +msgstr "수신 작업 마무리 실패: %s" + +#: pg_basebackup.c:2097 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "스트리밍을 끝내기 위해서 백그라운드 프로세스를 기다리는 중 ..." + +#: pg_basebackup.c:2102 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "백그라운드 파이프로 명령을 보낼 수 없음: %m" + +#: pg_basebackup.c:2110 +#, c-format +msgid "could not wait for child process: %m" +msgstr "하위 프로세스를 기다릴 수 없음: %m" + +#: pg_basebackup.c:2115 +#, c-format +msgid "child %d died, expected %d" +msgstr "%d 개의 하위 프로세스가 종료됨, 기대값 %d" + +#: pg_basebackup.c:2120 streamutil.c:92 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2145 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "하위 스레드를 기다릴 수 없음: %m" + +#: pg_basebackup.c:2151 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "하위 스레드 종료 상태가 정상적이지 않음: %m" + +#: pg_basebackup.c:2156 +#, c-format +msgid "child thread exited with error %u" +msgstr "하위 스레드가 비정상 종료됨: 오류 코드 %u" + +#: pg_basebackup.c:2184 +#, c-format +msgid "syncing data to disk ..." +msgstr "자료를 디스크에 동기화 하는 중 ... " + +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "backup_manifest.tmp 파일을 backup_manifest로 바꾸는 중" + +#: pg_basebackup.c:2220 +#, c-format +msgid "base backup completed" +msgstr "베이스 백업 완료" + +#: pg_basebackup.c:2305 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" +msgstr "\"%s\" 값은 잘못된 출력 형식, \"plain\" 또는 \"tar\" 만 사용 가능" + +#: pg_basebackup.c:2349 +#, c-format +msgid "" +"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "" +"\"%s\" 값은 잘못된 wal-method 옵션값, \"fetch\", \"stream\" 또는 \"none\"만 " +"사용 가능" + +#: pg_basebackup.c:2377 pg_receivewal.c:580 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "잘못된 압축 수위 \"%s\"" + +#: pg_basebackup.c:2388 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "잘못된 체크포인트 옵션값 \"%s\", \"fast\" 또는 \"spread\"만 사용 가능" + +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "잘못된 상태값 간격: \"%s\"" + +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2527 +#: pg_basebackup.c:2538 pg_basebackup.c:2548 pg_basebackup.c:2565 +#: pg_basebackup.c:2573 pg_basebackup.c:2581 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "자제한 사항은 \"%s --help\" 명령으로 살펴보십시오.\n" + +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "너무 많은 명령행 인자를 지정했습니다. (처음 \"%s\")" + +#: pg_basebackup.c:2468 pg_receivewal.c:654 +#, c-format +msgid "no target directory specified" +msgstr "대상 디렉터리를 지정하지 않음" + +#: pg_basebackup.c:2479 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "tar 형식만 압축을 사용할 수 있음" + +#: pg_basebackup.c:2487 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "tar 방식에서 stdout으로 트랜잭션 로그 스트리밍 불가" + +#: pg_basebackup.c:2495 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "복제 슬롯은 WAL 스트리밍 방식에서만 사용할 수 있음" + +#: pg_basebackup.c:2505 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "슬롯 이름을 지정한 경우 --no-slot 옵션을 사용할 수 없음" + +#. translator: second %s is an option name +#: pg_basebackup.c:2517 pg_receivewal.c:634 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "%s 옵션은 --slot 옵션을 함께 사용해야 함" + +#: pg_basebackup.c:2526 +#, c-format +msgid "--create-slot and --no-slot are incompatible options" +msgstr "--create-slot 옵션과 -no-slot 옵션은 함께 사용할 수 없음" + +#: pg_basebackup.c:2537 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "트랜잭션 로그 디렉터리 위치는 plain 모드에서만 사용할 수 있음" + +#: pg_basebackup.c:2547 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "트랜잭션 로그 디렉터리 위치는 절대 경로여야 함" + +#: pg_basebackup.c:2557 pg_receivewal.c:663 +#, c-format +msgid "this build does not support compression" +msgstr "이 버전은 압축 하는 기능을 포함 하지 않고 빌드 되었습니다." + +#: pg_basebackup.c:2564 +#, c-format +msgid "--progress and --no-estimate-size are incompatible options" +msgstr "--progress 옵션과 --no-estimate-size 옵션은 함께 사용할 수 없음" + +#: pg_basebackup.c:2572 +#, c-format +msgid "--no-manifest and --manifest-checksums are incompatible options" +msgstr "--no-manifest 옵션과 --manifest-checksums 옵션은 함께 사용할 수 없음" + +#: pg_basebackup.c:2580 +#, c-format +msgid "--no-manifest and --manifest-force-encode are incompatible options" +msgstr "" +"--no-manifest 옵션과 --manifest-force-encode 옵션은 함께 사용할 수 없음" + +#: pg_basebackup.c:2639 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "\"%s\" 심벌릭 링크를 만들 수 없음: %m" + +#: pg_basebackup.c:2643 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "이 플랫폼에서는 심볼 링크가 지원되지 않음" + +#: pg_receivewal.c:77 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s 프로그램은 PostgreSQL 스트리밍 트랜잭션 로그를 수신하는 도구입니다.\n" +"\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:81 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"옵션들:\n" + +#: pg_receivewal.c:82 +#, c-format +msgid "" +" -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr "" +" -D, --directory=DIR 지정한 디렉터리로 트랜잭션 로그 파일을 백업함\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:82 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN 지정한 LSN까지 받고 종료함\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:86 +#, c-format +msgid "" +" --if-not-exists do not error if slot already exists when creating a " +"slot\n" +msgstr "" +" --if-not-exists 슬롯을 새로 만들 때 이미 있어도 오류 내지 않음\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:88 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop 접속이 끊겼을 때 재연결 하지 않음\n" + +#: pg_receivewal.c:86 +#, c-format +msgid "" +" --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr " --no-sync 디스크 쓰기 뒤 sync 작업 생략\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:93 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server " +"(default: %d)\n" +msgstr "" +" -s, --status-interval=초\n" +" 지정한 초 간격으로 서버로 상태 패킷을 보냄 (초기값: " +"%d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid "" +" --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous 쓰기 작업 후 즉시 트랜잭션 로그를 플러시 함\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 압축된 로그 파일의 압축 수위 지정\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"추가 기능:\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:78 +#, c-format +msgid "" +" --create-slot create a new replication slot (for the slot's name " +"see --slot)\n" +msgstr "" +" --create-slot 새 복제 슬롯을 만듬 (--slot 옵션에서 슬롯 이름 지" +"정)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:79 +#, c-format +msgid "" +" --drop-slot drop the replication slot (for the slot's name see " +"--slot)\n" +msgstr "" +" --drop-slot 복제 슬롯 삭제 (--slot 옵션에서 슬롯 이름 지정)\n" + +#: pg_receivewal.c:117 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "마무리된 세그먼트 위치: %X/%X (타임라인 %u)" + +#: pg_receivewal.c:124 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "로그 스트리밍 중지된 위치: %X/%X (타임라인 %u)" + +#: pg_receivewal.c:140 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "전환됨: 타임라인 %u, 위치 %X/%X" + +#: pg_receivewal.c:150 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "인터럽터 시그널을 받음, 종료함" + +#: pg_receivewal.c:186 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 닫을 수 없음: %m" + +#: pg_receivewal.c:272 +#, c-format +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "\"%s\" 조각 파일은 잘못된 크기임: %d, 무시함" + +#: pg_receivewal.c:290 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "\"%s\" 압축 파일 열기 실패: %m" + +#: pg_receivewal.c:296 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "\"%s\" 압축 파일 작업 위치 찾기 실패: %m" + +#: pg_receivewal.c:304 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "\"%s\" 압축 파일 읽기 실패: %m" + +#: pg_receivewal.c:307 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "\"%s\" 압축 파일을 읽을 수 없음: %d 읽음, 전체 %zu" + +#: pg_receivewal.c:318 +#, c-format +msgid "" +"compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "\"%s\" 압축 파일은 압축 풀었을 때 잘못된 크기임: %d, 무시함" + +#: pg_receivewal.c:422 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "로그 스트리밍 시작 위치: %X/%X (타임라인 %u)" + +#: pg_receivewal.c:537 pg_recvlogical.c:762 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "잘못된 포트 번호: \"%s\"" + +#: pg_receivewal.c:565 pg_recvlogical.c:788 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "시작 위치 구문이 잘못됨 \"%s\"" + +#: pg_receivewal.c:625 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "--create-slot 옵션과 --drop-slot 옵션을 함께 사용할 수 없음" + +#: pg_receivewal.c:643 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "--synchronous 옵션과 --no-sync 옵션을 함께 사용할 수 없음" + +#: pg_receivewal.c:719 +#, c-format +msgid "" +"replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "\"%s\" 슬롯을 이용한 복제 연결은 이 데이터베이스에서 사용할 수 없음" + +#: pg_receivewal.c:730 pg_recvlogical.c:966 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "\"%s\" 이름의 복제 슬롯을 삭제 중" + +#: pg_receivewal.c:741 pg_recvlogical.c:976 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "\"%s\" 이름의 복제 슬롯을 만드는 중" + +#: pg_receivewal.c:767 pg_recvlogical.c:1001 +#, c-format +msgid "disconnected" +msgstr "연결 끊김" + +#. translator: check source for value for %d +#: pg_receivewal.c:773 pg_recvlogical.c:1007 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "연결 끊김; 다시 연결 하기 위해 %d 초를 기다리는 중" + +#: pg_recvlogical.c:73 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s 프로그램은 논리 디코딩 스트림을 제어하는 도구입니다.\n" +"\n" + +#: pg_recvlogical.c:77 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"성능에 관계된 기능들:\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid "" +" --start start streaming in a replication slot (for the " +"slot's name see --slot)\n" +msgstr "" +" --start 복제 슬롯을 이용한 스트리밍 시작 (--slot 옵션에서 슬" +"롯 이름 지정)\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=파일 작업 로그를 해당 파일에 기록, 표준 출력은 -\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: " +"%d)\n" +msgstr "" +" -F --fsync-interval=초\n" +" 지정한 초 간격으로 파일 fsync 작업을 함 (초기값: " +"%d)\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid "" +" -I, --startpos=LSN where in an existing slot should the streaming " +"start\n" +msgstr " -I, --startpos=LSN 스트리밍을 시작할 기존 슬롯 위치\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=이름[=값]\n" +" 출력 플러그인에서 사용할 옵션들의 옵션 이름과 그 " +"값\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr " -P, --plugin=PLUGIN 사용할 출력 플러그인 (초기값: %s)\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=슬롯이름 논리 복제 슬롯 이름\n" + +#: pg_recvlogical.c:100 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=디비이름 접속할 데이터베이스\n" + +#: pg_recvlogical.c:133 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "쓰기 확인 위치: %X/%X, 플러시 위치 %X/%X (슬롯 %s)" + +#: pg_recvlogical.c:157 receivelog.c:343 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "피드백 패킷을 보낼 수 없음: %s" + +#: pg_recvlogical.c:230 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "로그 스트리밍 시작 함, 위치: %X/%X (슬롯 %s)" + +#: pg_recvlogical.c:271 +#, c-format +msgid "streaming initiated" +msgstr "스트리밍 초기화 됨" + +#: pg_recvlogical.c:335 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "\"%s\" 잠금파일을 열 수 없음: %m" + +#: pg_recvlogical.c:361 receivelog.c:873 +#, c-format +msgid "invalid socket: %s" +msgstr "잘못된 소켓: %s" + +#: pg_recvlogical.c:414 receivelog.c:901 +#, c-format +msgid "select() failed: %m" +msgstr "select() 실패: %m" + +#: pg_recvlogical.c:421 receivelog.c:951 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "WAL 스트림에서 자료 받기 실패: %s" + +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:995 receivelog.c:1061 +#, c-format +msgid "streaming header too small: %d" +msgstr "스트리밍 헤더 크기가 너무 작음: %d" + +#: pg_recvlogical.c:498 receivelog.c:833 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "알 수 없는 스트리밍 헤더: \"%c\"" + +#: pg_recvlogical.c:552 pg_recvlogical.c:564 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "%u 바이트 쓰기 실패, 로그파일 \"%s\": %m" + +#: pg_recvlogical.c:618 receivelog.c:629 receivelog.c:666 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "복제 스트림의 예상치 못한 종료: %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "\"%s\" 값은 잘못된 fsync 반복주기 임" + +#: pg_recvlogical.c:780 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "시작 위치 구문이 잘못됨 \"%s\"" + +#: pg_recvlogical.c:869 +#, c-format +msgid "no slot specified" +msgstr "슬롯을 지정하지 않았음" + +#: pg_recvlogical.c:877 +#, c-format +msgid "no target file specified" +msgstr "대상 파일을 지정하지 않았음" + +#: pg_recvlogical.c:885 +#, c-format +msgid "no database specified" +msgstr "데이터베이스 지정하지 않았음" + +#: pg_recvlogical.c:893 +#, c-format +msgid "at least one action needs to be specified" +msgstr "적어도 하나 이상의 작업 방법을 지정해야 함" + +#: pg_recvlogical.c:901 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "" +"--create-slot 옵션 또는 --start 옵션은 --drop-slot 옵션과 함께 사용할 수 없음" + +#: pg_recvlogical.c:909 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "" +" --create-slot 옵션이나 --drop-slot 옵션은 --startpos 옵션과 함께 쓸 수 없음" + +#: pg_recvlogical.c:917 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos 옵션은 --start 옵션과 함께 사용해야 함" + +#: pg_recvlogical.c:948 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "데이터베이스 의존적인 복제 연결을 할 수 없음" + +#: pg_recvlogical.c:1047 +#, c-format +msgid "end position %X/%X reached by keepalive" +msgstr "keepalive에 의해서 %X/%X 마지막 위치에 도달했음" + +#: pg_recvlogical.c:1050 +#, c-format +msgid "end position %X/%X reached by WAL record at %X/%X" +msgstr "%X/%X 마지막 위치가 WAL 레코드 %X/%X 위치에서 도달했음" + +#: receivelog.c:69 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "\"%s\" archive status 파일을 만들 수 없습니다: %s" + +#: receivelog.c:116 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "\"%s\" WAL 파일 크기를 알 수 없음: %s" + +#: receivelog.c:126 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "이미 있는 \"%s\" 트랜잭션 로그 파일을 열 수 없음: %s" + +#: receivelog.c:134 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "이미 있는 \"%s\" WAL 파일 fsync 실패: %s" + +#: receivelog.c:148 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "" +"\"%s\" 트랜잭션 로그파일의 크기가 %d 바이트임, 0 또는 %d 바이트여야 함" + +#: receivelog.c:163 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "\"%s\" WAL 파일을 열 수 없음: %s" + +#: receivelog.c:189 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "\"%s\" 파일의 시작 위치를 결정할 수 없음: %s" + +#: receivelog.c:203 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "\"%s%s\" 이름 변경 실패, 세그먼트가 완료되지 않았음" + +#: receivelog.c:215 receivelog.c:300 receivelog.c:675 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "\"%s\" 파일을 닫을 수 없음: %s" + +#: receivelog.c:272 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "타임라인 %u 번을 위한 내역 파일 이름이 잘못 되었음: %s" + +#: receivelog.c:280 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "\"%s\" 타임라인 내역 파일을 만들 수 없음: %s" + +#: receivelog.c:287 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "\"%s\" 타임라인 내역 파일에 쓸 수 없음: %s" + +#: receivelog.c:377 +#, c-format +msgid "" +"incompatible server version %s; client does not support streaming from " +"server versions older than %s" +msgstr "" +"%s 서버 버전은 호환되지 않음; 클라이언트는 %s 버전 보다 오래된 서버의 스트리" +"밍은 지원하지 않음" + +#: receivelog.c:386 +#, c-format +msgid "" +"incompatible server version %s; client does not support streaming from " +"server versions newer than %s" +msgstr "" +"%s 서버 버전은 호환되지 않음; 클라이언트는 %s 버전 보다 새로운 서버의 스트리" +"밍은 지원하지 않음" + +#: receivelog.c:488 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "" +"could not identify system: got %d rows and %d fields, expected %d rows and " +"%d or more fields" +msgstr "" +"시스템을 식별할 수 없음: 로우수 %d, 필드수 %d, 예상값: 로우수 %d, 필드수 %d " +"이상" + +#: receivelog.c:495 +#, c-format +msgid "" +"system identifier does not match between base backup and streaming connection" +msgstr "시스템 식별자가 베이스 백업과 스트리밍 연결에서 서로 다름" + +#: receivelog.c:501 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "%u 타임라인으로 시작하는 것을 서버에서 제공 하지 않음" + +#: receivelog.c:542 +#, c-format +msgid "" +"unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, " +"expected %d rows and %d fields" +msgstr "" +"TIMELINE_HISTORY 명령 결과가 잘못됨: 받은 값: 로우수 %d, 필드수 %d, 예상값: " +"로우수 %d, 필드수 %d" + +#: receivelog.c:613 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "서버가 잘못된 다음 타임라인 번호 %u 보고함, 이전 타임라인 번호 %u" + +#: receivelog.c:619 +#, c-format +msgid "" +"server stopped streaming timeline %u at %X/%X, but reported next timeline %u " +"to begin at %X/%X" +msgstr "" +"서버의 중지 위치: 타임라인 %u, 위치 %X/%X, 하지만 보고 받은 위치: 타임라인 " +"%u 위치 %X/%X" + +#: receivelog.c:659 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "복제 스트림이 중지 위치 전에 종료 되었음" + +#: receivelog.c:705 +#, c-format +msgid "" +"unexpected result set after end-of-timeline: got %d rows and %d fields, " +"expected %d rows and %d fields" +msgstr "" +"타임라인 끝에 잘못된 결과가 발견 됨: 로우수 %d, 필드수 %d / 예상값: 로우수 " +"%d, 필드수 %d" + +#: receivelog.c:714 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "다음 타임라인 시작 위치 분석 실패 \"%s\"" + +#: receivelog.c:763 receivelog.c:1015 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "\"%s\" 파일 fsync 실패: %s" + +#: receivelog.c:1078 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "%u 위치의 수신된 트랜잭션 로그 레코드에 파일을 열 수 없음" + +#: receivelog.c:1088 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "잘못된 WAL 자료 위치 %08x, 기대값 %08x" + +#: receivelog.c:1122 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "%u 바이트를 \"%s\" WAL 파일에 쓸 수 없음: %s" + +#: receivelog.c:1147 receivelog.c:1187 receivelog.c:1218 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "copy-end 패킷을 보낼 수 없음: %s" + +#: streamutil.c:160 +msgid "Password: " +msgstr "암호: " + +#: streamutil.c:185 +#, c-format +msgid "could not connect to server" +msgstr "서버 접속 실패" + +#: streamutil.c:202 +#, c-format +msgid "could not connect to server: %s" +msgstr "서버 접속 실패: %s" + +#: streamutil.c:231 +#, c-format +msgid "could not clear search_path: %s" +msgstr "search_path를 지울 수 없음: %s" + +#: streamutil.c:247 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "integer_datetimes 서버 설정을 알 수 없음" + +#: streamutil.c:254 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "integer_datetimes 컴파일 플래그가 서버와 일치하지 않음" + +#: streamutil.c:305 +#, c-format +msgid "" +"could not fetch WAL segment size: got %d rows and %d fields, expected %d " +"rows and %d or more fields" +msgstr "" +"WAL 조각 크기 계산 실패: 로우수 %d, 필드수 %d, 예상값: 로우수 %d, 필드수 %d " +"이상" + +#: streamutil.c:315 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "WAL 조각 크기 분석 못함" + +#: streamutil.c:333 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"remote server reported a value of %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"remote server reported a value of %d bytes" +msgstr[0] "" +"WAL 조각 파일 크기는 1MB에서 1GB사이 2의 제곱 크기여야 하는데, " +"원격 서버는 %d 바이트입니다." + +#: streamutil.c:378 +#, c-format +msgid "" +"could not fetch group access flag: got %d rows and %d fields, expected %d " +"rows and %d or more fields" +msgstr "" +"그룹 접근 플래그를 가져올 수 없음: 로우수 %d, 필드수 %d, 예상값: 로우수 %d, " +"필드수 %d 이상" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "그룹 접근 플래그를 분석 못함: %s" + +#: streamutil.c:544 +#, c-format +msgid "" +"could not create replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields" +msgstr "" +"\"%s\" 복제 슬롯을 만들 수 없음: 로우수 %d, 필드수 %d, 기대값 로우수 %d, 필드" +"수 %d" + +#: streamutil.c:588 +#, c-format +msgid "" +"could not drop replication slot \"%s\": got %d rows and %d fields, expected " +"%d rows and %d fields" +msgstr "" +"\"%s\" 복제 슬롯을 삭제할 수 없음: 로우수 %d, 필드수 %d, 기대값 로우수 %d, 필" +"드수 %d" + +#: walmethods.c:438 walmethods.c:927 +msgid "could not compress data" +msgstr "자료를 압축할 수 없음" + +#: walmethods.c:470 +msgid "could not reset compression stream" +msgstr "압축 스트림을 리셋할 수 없음" + +#: walmethods.c:568 +msgid "could not initialize compression library" +msgstr "압축 라이브러리를 초기화할 수 없음" + +#: walmethods.c:580 +msgid "implementation error: tar files can't have more than one open file" +msgstr "구현 오류: tar 파일은 하나 이상 열 수 없음" + +#: walmethods.c:594 +msgid "could not create tar header" +msgstr "tar 해더를 만들 수 없음" + +#: walmethods.c:608 walmethods.c:648 walmethods.c:843 walmethods.c:854 +msgid "could not change compression parameters" +msgstr "압축 매개 변수를 바꿀 수 없음" + +#: walmethods.c:730 +msgid "unlink not supported with compression" +msgstr "압축 상태에서 파일 삭제는 지원하지 않음" + +#: walmethods.c:952 +msgid "could not close compression stream" +msgstr "압축 스트림을 닫을 수 없음" diff --git a/src/bin/pg_basebackup/po/ru.po b/src/bin/pg_basebackup/po/ru.po new file mode 100644 index 000000000000..05722aed848d --- /dev/null +++ b/src/bin/pg_basebackup/po/ru.po @@ -0,0 +1,1775 @@ +# Russian message translation file for pg_basebackup +# Copyright (C) 2012-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_basebackup (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-11-09 07:34+0300\n" +"PO-Revision-Date: 2020-09-03 17:44+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 +#: pg_receivewal.c:266 pg_recvlogical.c:340 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не удалось получить информацию о файле \"%s\": %m" + +#: ../../common/file_utils.c:158 pg_receivewal.c:169 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалось открыть каталог \"%s\": %m" + +#: ../../common/file_utils.c:192 pg_receivewal.c:337 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не удалось прочитать каталог \"%s\": %m" + +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 ../../fe_utils/recovery_gen.c:134 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 +#: pg_recvlogical.c:193 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "не удалось синхронизировать с ФС файл \"%s\": %m" + +#: ../../common/file_utils.c:375 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "не удалось переименовать файл \"%s\" в \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "нехватка памяти" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "не удалось записать файл \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "не удалось создать файл \"%s\": %m" + +#: pg_basebackup.c:224 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "удаление каталога данных \"%s\"" + +#: pg_basebackup.c:226 +#, c-format +msgid "failed to remove data directory" +msgstr "ошибка при удалении каталога данных" + +#: pg_basebackup.c:230 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "удаление содержимого каталога данных \"%s\"" + +#: pg_basebackup.c:232 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "ошибка при удалении содержимого каталога данных" + +#: pg_basebackup.c:237 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "удаление каталога WAL \"%s\"" + +#: pg_basebackup.c:239 +#, c-format +msgid "failed to remove WAL directory" +msgstr "ошибка при удалении каталога WAL" + +#: pg_basebackup.c:243 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "удаление содержимого каталога WAL \"%s\"" + +#: pg_basebackup.c:245 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "ошибка при удалении содержимого каталога WAL" + +#: pg_basebackup.c:251 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "каталог данных \"%s\" не был удалён по запросу пользователя" + +#: pg_basebackup.c:254 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "каталог WAL \"%s\" не был удалён по запросу пользователя" + +#: pg_basebackup.c:258 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "изменения в каталогах табличных пространств не будут отменены" + +#: pg_basebackup.c:299 +#, c-format +msgid "directory name too long" +msgstr "слишком длинное имя каталога" + +#: pg_basebackup.c:309 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "несколько знаков \"=\" в сопоставлении табличного пространства" + +#: pg_basebackup.c:321 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "" +"сопоставление табл. пространства записано неверно: \"%s\"; должно быть " +"\"СТАРЫЙ_КАТАЛОГ=НОВЫЙ_КАТАЛОГ\"" + +#: pg_basebackup.c:333 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "" +"старый каталог в сопоставлении табл. пространства задан не абсолютным путём: " +"%s" + +#: pg_basebackup.c:340 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "" +"новый каталог в сопоставлении табл. пространства задан не абсолютным путём: " +"%s" + +#: pg_basebackup.c:379 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s делает базовую резервную копию работающего сервера PostgreSQL.\n" +"\n" + +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [ПАРАМЕТР]...\n" + +#: pg_basebackup.c:383 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"Параметры, управляющие выводом:\n" + +#: pg_basebackup.c:384 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=КАТАЛОГ сохранить базовую копию в указанный каталог\n" + +#: pg_basebackup.c:385 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr "" +" -F, --format=p|t формат вывода (p (по умолчанию) - простой, t - " +"tar)\n" + +#: pg_basebackup.c:386 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=СКОРОСТЬ макс. скорость передачи данных в целевой каталог\n" +" (в КБ/с, либо добавьте суффикс \"k\" или \"M\")\n" + +#: pg_basebackup.c:388 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" записать конфигурацию для репликации\n" + +#: pg_basebackup.c:390 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=СТАРЫЙ_КАТАЛОГ=НОВЫЙ_КАТАЛОГ\n" +" перенести табличное пространство из старого " +"каталога\n" +" в новый\n" + +#: pg_basebackup.c:392 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr "" +" --waldir=КАТАЛОГ_WAL\n" +" расположение каталога с журналом предзаписи\n" + +#: pg_basebackup.c:393 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" включить в копию требуемые файлы WAL, используя\n" +" заданный метод\n" + +#: pg_basebackup.c:395 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip сжать выходной tar\n" + +#: pg_basebackup.c:396 +#, c-format +msgid "" +" -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 установить уровень сжатия выходного архива\n" + +#: pg_basebackup.c:397 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Общие параметры:\n" + +#: pg_basebackup.c:398 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" режим быстрых или распределённых контрольных точек\n" + +#: pg_basebackup.c:400 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot создать слот репликации\n" + +#: pg_basebackup.c:401 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=МЕТКА установить метку резервной копии\n" + +#: pg_basebackup.c:402 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean не очищать после ошибок\n" + +#: pg_basebackup.c:403 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --no-sync не ждать завершения сохранения данных на диске\n" + +#: pg_basebackup.c:404 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress показывать прогресс операции\n" + +#: pg_basebackup.c:405 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=ИМЯ_СЛОТА использовать заданный слот репликации\n" + +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose выводить подробные сообщения\n" + +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_basebackup.c:408 +#, c-format +msgid "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr "" +" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" алгоритм подсчёта контрольных сумм в манифесте\n" + +# skip-rule: capital-letter-first +# well-spelled: шестнадц +#: pg_basebackup.c:410 +#, c-format +msgid "" +" --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr "" +" --manifest-force-encode\n" +" записывать все имена файлов в манифесте в шестнадц. " +"виде\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr "" +" --no-estimate-size не рассчитывать размер копии на стороне сервера\n" + +#: pg_basebackup.c:413 +#, c-format +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr " --no-manifest отключить создание манифеста копии\n" + +#: pg_basebackup.c:414 +#, c-format +msgid "" +" --no-slot prevent creation of temporary replication slot\n" +msgstr "" +" --no-slot предотвратить создание временного слота репликации\n" + +#: pg_basebackup.c:415 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" не проверять контрольные суммы\n" + +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Параметры подключения:\n" + +#: pg_basebackup.c:419 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=СТРОКА строка подключения\n" + +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=ИМЯ имя сервера баз данных или каталог сокетов\n" + +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=ПОРТ номер порта сервера БД\n" + +#: pg_basebackup.c:422 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in " +"seconds)\n" +msgstr "" +" -s, --status-interval=ИНТЕРВАЛ\n" +" интервал между передаваемыми серверу\n" +" пакетами состояния (в секундах)\n" + +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr "" +" -U, --username=NAME connect as specified database user\n" +" -U, --username=ИМЯ имя пользователя баз данных\n" + +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password не запрашивать пароль\n" + +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr "" +" -W, --password запрашивать пароль всегда (обычно не требуется)\n" + +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_basebackup.c:471 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "не удалось прочитать из готового канала: %m" + +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 +#: streamutil.c:449 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "не удалось разобрать положение в журнале предзаписи \"%s\"" + +#: pg_basebackup.c:573 pg_receivewal.c:441 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "не удалось завершить запись файлов WAL: %m" + +#: pg_basebackup.c:620 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "не удалось создать канал для фонового процесса: %m" + +#: pg_basebackup.c:655 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "создан временный слот репликации \"%s\"" + +#: pg_basebackup.c:658 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "создан слот репликации \"%s\"" + +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не удалось создать каталог \"%s\": %m" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not create background process: %m" +msgstr "не удалось создать фоновый процесс: %m" + +#: pg_basebackup.c:708 +#, c-format +msgid "could not create background thread: %m" +msgstr "не удалось создать фоновый поток выполнения: %m" + +#: pg_basebackup.c:752 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "каталог \"%s\" существует, но он не пуст" + +#: pg_basebackup.c:759 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "ошибка доступа к каталогу \"%s\": %m" + +#: pg_basebackup.c:824 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s КБ (100%%), табличное пространство %d/%d %*s" +msgstr[1] "%*s/%s КБ (100%%), табличное пространство %d/%d %*s" +msgstr[2] "%*s/%s КБ (100%%), табличное пространство %d/%d %*s" + +#: pg_basebackup.c:836 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s КБ (%d%%), табличное пространство %d/%d (%s%-*.*s)" +msgstr[1] "%*s/%s КБ (%d%%), табличное пространство %d/%d (%s%-*.*s)" +msgstr[2] "%*s/%s КБ (%d%%), табличное пространство %d/%d (%s%-*.*s)" + +#: pg_basebackup.c:852 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s КБ (%d%%), табличное пространство %d/%d" +msgstr[1] "%*s/%s КБ (%d%%), табличное пространство %d/%d" +msgstr[2] "%*s/%s КБ (%d%%), табличное пространство %d/%d" + +#: pg_basebackup.c:877 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "неверное значение (\"%s\") для скорости передачи данных" + +#: pg_basebackup.c:882 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "неверная скорость передачи данных \"%s\": %m" + +#: pg_basebackup.c:891 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "скорость передачи должна быть больше 0" + +#: pg_basebackup.c:923 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "неверная единица измерения в --max-rate: \"%s\"" + +#: pg_basebackup.c:930 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "скорость передачи \"%s\" вне целочисленного диапазона" + +#: pg_basebackup.c:940 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "скорость передачи \"%s\" вне диапазона" + +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "не удалось получить поток данных COPY: %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:965 +#, c-format +msgid "could not read COPY data: %s" +msgstr "не удалось прочитать данные COPY: %s" + +#: pg_basebackup.c:1007 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "не удалось записать сжатый файл \"%s\": %s" + +#: pg_basebackup.c:1071 +#, c-format +msgid "could not duplicate stdout: %m" +msgstr "не удалось продублировать stdout: %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "не удалось открыть выходной файл: %m" + +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "не удалось установить уровень сжатия %d: %s" + +#: pg_basebackup.c:1155 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "не удалось создать сжатый файл \"%s\": %s" + +#: pg_basebackup.c:1267 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "не удалось закрыть сжатый файл \"%s\": %s" + +#: pg_basebackup.c:1279 pg_recvlogical.c:632 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "не удалось закрыть файл \"%s\": %m" + +#: pg_basebackup.c:1541 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "поток COPY закончился до завершения последнего файла" + +#: pg_basebackup.c:1570 +#, c-format +msgid "invalid tar block header size: %zu" +msgstr "неверный размер заголовка блока tar: %zu" + +#: pg_basebackup.c:1627 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "не удалось установить права для каталога \"%s\": %m" + +#: pg_basebackup.c:1651 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "не удалось создать символическую ссылку \"%s\" в \"%s\": %m" + +#: pg_basebackup.c:1658 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "нераспознанный индикатор связи \"%c\"" + +#: pg_basebackup.c:1677 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "не удалось установить права доступа для файла \"%s\": %m" + +#: pg_basebackup.c:1831 +#, c-format +msgid "incompatible server version %s" +msgstr "несовместимая версия сервера %s" + +#: pg_basebackup.c:1846 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "" +"ПОДСКАЗКА: укажите -X none или -X fetch для отключения трансляции журнала" + +#: pg_basebackup.c:1882 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "" +"начинается базовое резервное копирование, ожидается завершение контрольной " +"точки" + +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:481 receivelog.c:530 +#: receivelog.c:569 streamutil.c:296 streamutil.c:369 streamutil.c:421 +#: streamutil.c:532 streamutil.c:577 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "не удалось передать команду репликации \"%s\": %s" + +#: pg_basebackup.c:1919 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "не удалось инициализировать базовое резервное копирование: %s" + +#: pg_basebackup.c:1925 +#, c-format +msgid "" +"server returned unexpected response to BASE_BACKUP command; got %d rows and " +"%d fields, expected %d rows and %d fields" +msgstr "" +"сервер вернул неожиданный ответ на команду BASE_BACKUP; получено строк: %d, " +"полей: %d, а ожидалось строк: %d, полей: %d" + +#: pg_basebackup.c:1933 +#, c-format +msgid "checkpoint completed" +msgstr "контрольная точка завершена" + +#: pg_basebackup.c:1948 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "стартовая точка в журнале предзаписи: %s на линии времени %u" + +#: pg_basebackup.c:1957 +#, c-format +msgid "could not get backup header: %s" +msgstr "не удалось получить заголовок резервной копии: %s" + +#: pg_basebackup.c:1963 +#, c-format +msgid "no data returned from server" +msgstr "сервер не вернул данные" + +#: pg_basebackup.c:1995 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "" +"в stdout можно вывести только одно табличное пространство, всего в СУБД их %d" + +#: pg_basebackup.c:2007 +#, c-format +msgid "starting background WAL receiver" +msgstr "запуск фонового процесса считывания WAL" + +#: pg_basebackup.c:2046 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "" +"не удалось получить от сервера конечную позицию в журнале предзаписи: %s" + +#: pg_basebackup.c:2052 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "сервер не передал конечную позицию в журнале предзаписи" + +#: pg_basebackup.c:2057 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "конечная точка в журнале предзаписи: %s" + +#: pg_basebackup.c:2068 +#, c-format +msgid "checksum error occurred" +msgstr "выявлена ошибка контрольной суммы" + +#: pg_basebackup.c:2073 +#, c-format +msgid "final receive failed: %s" +msgstr "ошибка в конце передачи: %s" + +#: pg_basebackup.c:2097 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "ожидание завершения потоковой передачи фоновым процессом..." + +#: pg_basebackup.c:2102 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "не удалось отправить команду в канал фонового процесса: %m" + +#: pg_basebackup.c:2110 +#, c-format +msgid "could not wait for child process: %m" +msgstr "сбой при ожидании дочернего процесса: %m" + +#: pg_basebackup.c:2115 +#, c-format +msgid "child %d died, expected %d" +msgstr "завершился дочерний процесс %d вместо ожидаемого %d" + +#: pg_basebackup.c:2120 streamutil.c:92 streamutil.c:202 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2145 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "сбой при ожидании дочернего потока: %m" + +#: pg_basebackup.c:2151 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "не удалось получить состояние завершения дочернего потока: %m" + +#: pg_basebackup.c:2156 +#, c-format +msgid "child thread exited with error %u" +msgstr "дочерний поток завершился с ошибкой %u" + +#: pg_basebackup.c:2184 +#, c-format +msgid "syncing data to disk ..." +msgstr "сохранение данных на диске..." + +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "переименование backup_manifest.tmp в backup_manifest" + +#: pg_basebackup.c:2220 +#, c-format +msgid "base backup completed" +msgstr "базовое резервное копирование завершено" + +#: pg_basebackup.c:2305 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" +msgstr "неверный формат вывода \"%s\", должен быть \"plain\" или \"tar\"" + +#: pg_basebackup.c:2349 +#, c-format +msgid "" +"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "" +"неверный аргумент для wal-method — \"%s\", допускается только \"fetch\", " +"\"stream\" или \"none\"" + +#: pg_basebackup.c:2377 pg_receivewal.c:580 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "неверный уровень сжатия \"%s\"" + +#: pg_basebackup.c:2388 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "" +"неверный аргумент режима контрольных точек \"%s\"; должен быть \"fast\" или " +"\"spread\"" + +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "неверный интервал сообщений о состоянии \"%s\"" + +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2527 +#: pg_basebackup.c:2538 pg_basebackup.c:2548 pg_basebackup.c:2565 +#: pg_basebackup.c:2573 pg_basebackup.c:2581 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: pg_basebackup.c:2468 pg_receivewal.c:654 +#, c-format +msgid "no target directory specified" +msgstr "целевой каталог не указан" + +#: pg_basebackup.c:2479 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "сжиматься могут только резервные копии в архиве tar" + +#: pg_basebackup.c:2487 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "транслировать журналы предзаписи в режиме tar в поток stdout нельзя" + +#: pg_basebackup.c:2495 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "слоты репликации можно использовать только при потоковой передаче WAL" + +#: pg_basebackup.c:2505 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot нельзя использовать с именем слота" + +#. translator: second %s is an option name +#: pg_basebackup.c:2517 pg_receivewal.c:634 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "для %s необходимо задать слот с помощью параметра --slot" + +#: pg_basebackup.c:2526 +#, c-format +msgid "--create-slot and --no-slot are incompatible options" +msgstr "параметры --create-slot и --no-slot несовместимы" + +#: pg_basebackup.c:2537 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "расположение каталога журнала WAL можно указать только в режиме plain" + +#: pg_basebackup.c:2547 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "расположение каталога журнала WAL должно определяться абсолютным путём" + +#: pg_basebackup.c:2557 pg_receivewal.c:663 +#, c-format +msgid "this build does not support compression" +msgstr "эта сборка программы не поддерживает сжатие" + +#: pg_basebackup.c:2564 +#, c-format +msgid "--progress and --no-estimate-size are incompatible options" +msgstr "параметры --progress и --no-estimate-size несовместимы" + +#: pg_basebackup.c:2572 +#, c-format +msgid "--no-manifest and --manifest-checksums are incompatible options" +msgstr "параметры --no-manifest и --manifest-checksums несовместимы" + +#: pg_basebackup.c:2580 +#, c-format +msgid "--no-manifest and --manifest-force-encode are incompatible options" +msgstr "параметры --no-manifest и --manifest-force-encode несовместимы" + +#: pg_basebackup.c:2639 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "не удалось создать символическую ссылку \"%s\": %m" + +#: pg_basebackup.c:2643 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "символические ссылки не поддерживаются в этой ОС" + +#: pg_receivewal.c:77 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s получает транслируемые журналы предзаписи PostgreSQL.\n" +"\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:81 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Параметры:\n" + +#: pg_receivewal.c:82 +#, c-format +msgid "" +" -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr "" +" -D, --directory=ПУТЬ сохранять файлы журнала предзаписи в данный " +"каталог\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:82 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr "" +" -E, --endpos=LSN определяет позицию, после которой нужно " +"остановиться\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:86 +#, c-format +msgid "" +" --if-not-exists do not error if slot already exists when creating a " +"slot\n" +msgstr "" +" --if-not-exists не выдавать ошибку при попытке создать уже " +"существующий слот\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:88 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop прерывать работу при потере соединения\n" + +#: pg_receivewal.c:86 +#, c-format +msgid "" +" --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" --no-sync не ждать надёжного сохранения изменений на диске\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:93 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server " +"(default: %d)\n" +msgstr "" +" -s, --status-interval=СЕК\n" +" интервал между отправкой статусных пакетов серверу " +"(по умолчанию: %d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid "" +" --synchronous flush write-ahead log immediately after writing\n" +msgstr "" +" --synchronous сбрасывать журнал предзаписи сразу после записи\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 установить уровень сжатия журналов\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"Дополнительные действия:\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:78 +#, c-format +msgid "" +" --create-slot create a new replication slot (for the slot's name " +"see --slot)\n" +msgstr "" +" --create-slot создать новый слот репликации (имя слота задаёт " +"параметр --slot)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:79 +#, c-format +msgid "" +" --drop-slot drop the replication slot (for the slot's name see " +"--slot)\n" +msgstr "" +" --drop-slot удалить слот репликации (имя слота задаёт параметр " +"--slot)\n" + +#: pg_receivewal.c:117 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "завершён сегмент %X/%X (линия времени %u)" + +#: pg_receivewal.c:124 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "завершена передача журнала с позиции %X/%X (линия времени %u)" + +#: pg_receivewal.c:140 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "переключение на линию времени %u (позиция %X/%X)" + +#: pg_receivewal.c:150 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "получен сигнал прерывания, работа завершается" + +#: pg_receivewal.c:186 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не удалось закрыть каталог \"%s\": %m" + +#: pg_receivewal.c:272 +#, c-format +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "файл сегмента \"%s\" имеет неправильный размер %d, файл пропускается" + +#: pg_receivewal.c:290 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "не удалось открыть сжатый файл \"%s\": %m" + +#: pg_receivewal.c:296 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "ошибка позиционирования в сжатом файле \"%s\": %m" + +#: pg_receivewal.c:304 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "не удалось прочитать сжатый файл \"%s\": %m" + +#: pg_receivewal.c:307 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "не удалось прочитать сжатый файл \"%s\" (прочитано байт: %d из %zu)" + +#: pg_receivewal.c:318 +#, c-format +msgid "" +"compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "" +"файл сжатого сегмента \"%s\" имеет неправильный исходный размер %d, файл " +"пропускается" + +#: pg_receivewal.c:422 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "начало передачи журнала с позиции %X/%X (линия времени %u)" + +#: pg_receivewal.c:537 pg_recvlogical.c:762 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "неверный номер порта \"%s\"" + +#: pg_receivewal.c:565 pg_recvlogical.c:788 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "не удалось разобрать конечную позицию \"%s\"" + +#: pg_receivewal.c:625 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "--create-slot нельзя применять вместе с --drop-slot" + +#: pg_receivewal.c:643 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "--synchronous нельзя применять вместе с --no-sync" + +#: pg_receivewal.c:719 +#, c-format +msgid "" +"replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "" +"подключение для репликации через слот \"%s\" оказалось привязано к базе " +"данных" + +#: pg_receivewal.c:730 pg_recvlogical.c:966 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "удаление слота репликации \"%s\"" + +#: pg_receivewal.c:741 pg_recvlogical.c:976 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "создание слота репликации \"%s\"" + +#: pg_receivewal.c:767 pg_recvlogical.c:1001 +#, c-format +msgid "disconnected" +msgstr "отключение" + +#. translator: check source for value for %d +#: pg_receivewal.c:773 pg_recvlogical.c:1007 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "отключение; через %d сек. последует повторное подключение" + +#: pg_recvlogical.c:73 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s управляет потоками логического декодирования PostgreSQL.\n" +"\n" + +#: pg_recvlogical.c:77 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"Действие, которое будет выполнено:\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid "" +" --start start streaming in a replication slot (for the " +"slot's name see --slot)\n" +msgstr "" +" --start начать передачу в слоте репликации (имя слота " +"задаёт параметр --slot)\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr "" +" -f, --file=ФАЙЛ сохранять журнал в этот файл, - обозначает stdout\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: " +"%d)\n" +msgstr "" +" -F --fsync-interval=СЕК\n" +" периодичность сброса на диск выходного файла (по " +"умолчанию: %d)\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid "" +" -I, --startpos=LSN where in an existing slot should the streaming " +"start\n" +msgstr "" +" -I, --startpos=LSN определяет, с какой позиции в существующем слоте " +"начнётся передача\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=ИМЯ[=ЗНАЧЕНИЕ]\n" +" передать параметр с заданным именем и " +"необязательным\n" +" значением модулю вывода\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr "" +" -P, --plugin=МОДУЛЬ использовать заданный модуль вывода (по умолчанию: " +"%s)\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=ИМЯ_СЛОТА имя слота логической репликации\n" + +#: pg_recvlogical.c:100 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=ИМЯ_БД целевая база данных\n" + +#: pg_recvlogical.c:133 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "подтверждается запись до %X/%X, синхронизация с ФС до %X/%X (слот %s)" + +#: pg_recvlogical.c:157 receivelog.c:343 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "не удалось отправить пакет ответа: %s" + +#: pg_recvlogical.c:230 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "начало передачи журнала с позиции %X/%X (слот %s)" + +#: pg_recvlogical.c:271 +#, c-format +msgid "streaming initiated" +msgstr "передача запущена" + +#: pg_recvlogical.c:335 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "не удалось открыть файл протокола \"%s\": %m" + +#: pg_recvlogical.c:361 receivelog.c:873 +#, c-format +msgid "invalid socket: %s" +msgstr "неверный сокет: %s" + +#: pg_recvlogical.c:414 receivelog.c:901 +#, c-format +msgid "select() failed: %m" +msgstr "ошибка в select(): %m" + +#: pg_recvlogical.c:421 receivelog.c:951 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "не удалось получить данные из потока WAL: %s" + +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:995 receivelog.c:1061 +#, c-format +msgid "streaming header too small: %d" +msgstr "заголовок потока слишком мал: %d" + +#: pg_recvlogical.c:498 receivelog.c:833 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "нераспознанный заголовок потока: \"%c\"" + +#: pg_recvlogical.c:552 pg_recvlogical.c:564 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "не удалось записать %u Б в файл журнала \"%s\": %m" + +#: pg_recvlogical.c:618 receivelog.c:629 receivelog.c:666 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "неожиданный конец потока репликации: %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "неверный интервал синхронизации с ФС \"%s\"" + +#: pg_recvlogical.c:780 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "не удалось разобрать начальную позицию \"%s\"" + +#: pg_recvlogical.c:869 +#, c-format +msgid "no slot specified" +msgstr "слот не указан" + +#: pg_recvlogical.c:877 +#, c-format +msgid "no target file specified" +msgstr "целевой файл не задан" + +#: pg_recvlogical.c:885 +#, c-format +msgid "no database specified" +msgstr "база данных не задана" + +#: pg_recvlogical.c:893 +#, c-format +msgid "at least one action needs to be specified" +msgstr "необходимо задать минимум одно действие" + +#: pg_recvlogical.c:901 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "--create-slot или --start нельзя применять вместе с --drop-slot" + +#: pg_recvlogical.c:909 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "--create-slot или --drop-slot нельзя применять вместе с --startpos" + +#: pg_recvlogical.c:917 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos можно задать только вместе с --start" + +#: pg_recvlogical.c:948 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "" +"не удалось установить подключение для репликации к определённой базе данных" + +#: pg_recvlogical.c:1047 +#, c-format +msgid "end position %X/%X reached by keepalive" +msgstr "конечная позиция %X/%X достигнута при обработке keepalive" + +#: pg_recvlogical.c:1050 +#, c-format +msgid "end position %X/%X reached by WAL record at %X/%X" +msgstr "конечная позиция %X/%X достигнута при обработке записи WAL %X/%X" + +#: receivelog.c:69 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "не удалось создать файл статуса архива \"%s\": %s" + +#: receivelog.c:116 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "не удалось получить размер файла журнала предзаписи \"%s\": %s" + +#: receivelog.c:126 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "не удалось открыть существующий файл журнала предзаписи \"%s\": %s" + +#: receivelog.c:134 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "" +"не удалось сбросить на диск существующий файл журнала предзаписи \"%s\": %s" + +#: receivelog.c:148 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "" +"файл журнала предзаписи \"%s\" имеет размер %d Б, а должен — 0 или %d" +msgstr[1] "" +"файл журнала предзаписи \"%s\" имеет размер %d Б, а должен — 0 или %d" +msgstr[2] "" +"файл журнала предзаписи \"%s\" имеет размер %d Б, а должен — 0 или %d" + +#: receivelog.c:163 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "не удалось открыть файл журнала предзаписи \"%s\": %s" + +#: receivelog.c:189 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "не удалось определить текущую позицию в файле \"%s\": %s" + +#: receivelog.c:203 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "файл \"%s%s\" не переименовывается, так как это не полный сегмент" + +#: receivelog.c:215 receivelog.c:300 receivelog.c:675 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "не удалось закрыть файл \"%s\": %s" + +#: receivelog.c:272 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "сервер сообщил неожиданное имя файла истории для линии времени %u: %s" + +#: receivelog.c:280 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "не удалось создать файл истории линии времени \"%s\": %s" + +#: receivelog.c:287 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "не удалось записать файл истории линии времени \"%s\": %s" + +#: receivelog.c:377 +#, c-format +msgid "" +"incompatible server version %s; client does not support streaming from " +"server versions older than %s" +msgstr "" +"несовместимая версия сервера %s; клиент не поддерживает репликацию с " +"серверов версии ниже %s" + +#: receivelog.c:386 +#, c-format +msgid "" +"incompatible server version %s; client does not support streaming from " +"server versions newer than %s" +msgstr "" +"несовместимая версия сервера %s; клиент не поддерживает репликацию с " +"серверов версии выше %s" + +#: receivelog.c:488 streamutil.c:429 streamutil.c:466 +#, c-format +msgid "" +"could not identify system: got %d rows and %d fields, expected %d rows and " +"%d or more fields" +msgstr "" +"не удалось идентифицировать систему; получено строк: %d, полей: %d " +"(ожидалось: %d и %d (или более))" + +#: receivelog.c:495 +#, c-format +msgid "" +"system identifier does not match between base backup and streaming connection" +msgstr "" +"системный идентификатор базовой резервной копии отличается от идентификатора " +"потоковой передачи" + +#: receivelog.c:501 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "на сервере нет начальной линии времени %u" + +#: receivelog.c:542 +#, c-format +msgid "" +"unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, " +"expected %d rows and %d fields" +msgstr "" +"сервер вернул неожиданный ответ на команду TIMELINE_HISTORY; получено строк: " +"%d, полей: %d, а ожидалось строк: %d, полей: %d" + +#: receivelog.c:613 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "сервер неожиданно сообщил линию времени %u после линии времени %u" + +#: receivelog.c:619 +#, c-format +msgid "" +"server stopped streaming timeline %u at %X/%X, but reported next timeline %u " +"to begin at %X/%X" +msgstr "" +"сервер прекратил передачу линии времени %u в %X/%X, но сообщил, что " +"следующая линии времени %u начнётся в %X/%X" + +#: receivelog.c:659 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "поток репликации закончился до точки остановки" + +#: receivelog.c:705 +#, c-format +msgid "" +"unexpected result set after end-of-timeline: got %d rows and %d fields, " +"expected %d rows and %d fields" +msgstr "" +"сервер вернул неожиданный набор данных после конца линии времени; получено " +"строк: %d, полей: %d, а ожидалось строк: %d, полей: %d" + +#: receivelog.c:714 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "не удалось разобрать начальную точку следующей линии времени \"%s\"" + +#: receivelog.c:763 receivelog.c:1015 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "не удалось синхронизировать с ФС файл \"%s\": %s" + +#: receivelog.c:1078 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "получена запись журнала предзаписи по смещению %u, но файл не открыт" + +#: receivelog.c:1088 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "получено смещение данных WAL %08x, но ожидалось %08x" + +#: receivelog.c:1122 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "не удалось записать %u Б в файл WAL \"%s\": %s" + +#: receivelog.c:1147 receivelog.c:1187 receivelog.c:1218 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "не удалось отправить пакет \"конец COPY\": %s" + +#: streamutil.c:160 +msgid "Password: " +msgstr "Пароль: " + +#: streamutil.c:185 +#, c-format +msgid "could not connect to server" +msgstr "не удалось подключиться к серверу" + +#: streamutil.c:230 +#, c-format +msgid "could not clear search_path: %s" +msgstr "не удалось очистить search_path: %s" + +#: streamutil.c:246 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "не удалось получить настройку сервера integer_datetimes" + +#: streamutil.c:253 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "флаг компиляции integer_datetimes не соответствует настройке сервера" + +#: streamutil.c:304 +#, c-format +msgid "" +"could not fetch WAL segment size: got %d rows and %d fields, expected %d " +"rows and %d or more fields" +msgstr "" +"не удалось извлечь размер сегмента WAL; получено строк: %d, полей: %d " +"(ожидалось: %d и %d (или более))" + +#: streamutil.c:314 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "разобрать размер сегмента WAL не удалось" + +#: streamutil.c:332 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"remote server reported a value of %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"remote server reported a value of %d bytes" +msgstr[0] "" +"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но удалённый сервер сообщил значение: %d" +msgstr[1] "" +"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но удалённый сервер сообщил значение: %d" +msgstr[2] "" +"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но удалённый сервер сообщил значение: %d" + +#: streamutil.c:377 +#, c-format +msgid "" +"could not fetch group access flag: got %d rows and %d fields, expected %d " +"rows and %d or more fields" +msgstr "" +"не удалось извлечь флаг доступа группы; получено строк: %d, полей: %d " +"(ожидалось: %d и %d (или более))" + +#: streamutil.c:386 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "не удалось разобрать флаг доступа группы: %s" + +#: streamutil.c:543 +#, c-format +msgid "" +"could not create replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields" +msgstr "" +"создать слот репликации \"%s\" не удалось; получено строк: %d, полей: %d " +"(ожидалось: %d и %d)" + +#: streamutil.c:587 +#, c-format +msgid "" +"could not drop replication slot \"%s\": got %d rows and %d fields, expected " +"%d rows and %d fields" +msgstr "" +"удалить слот репликации \"%s\" не получилось; получено строк: %d, полей: %d " +"(ожидалось: %d и %d)" + +#: walmethods.c:438 walmethods.c:927 +msgid "could not compress data" +msgstr "не удалось сжать данные" + +#: walmethods.c:470 +msgid "could not reset compression stream" +msgstr "не удалось сбросить поток сжатых данных" + +#: walmethods.c:568 +msgid "could not initialize compression library" +msgstr "не удалось инициализировать библиотеку сжатия" + +#: walmethods.c:580 +msgid "implementation error: tar files can't have more than one open file" +msgstr "" +"ошибка реализации: в файлах tar не может быть больше одно открытого файла" + +#: walmethods.c:594 +msgid "could not create tar header" +msgstr "не удалось создать заголовок tar" + +#: walmethods.c:608 walmethods.c:648 walmethods.c:843 walmethods.c:854 +msgid "could not change compression parameters" +msgstr "не удалось изменить параметры сжатия" + +#: walmethods.c:730 +msgid "unlink not supported with compression" +msgstr "со сжатием закрытие файла с удалением не поддерживается" + +#: walmethods.c:952 +msgid "could not close compression stream" +msgstr "не удалось закрыть поток сжатых данных" + +#~ msgid "could not connect to server: %s" +#~ msgstr "не удалось подключиться к серверу: %s" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: нехватка памяти\n" + +#~ msgid "%s: child process did not exit normally\n" +#~ msgstr "%s: дочерний процесс завершён ненормально\n" + +#~ msgid "%s: child process exited with error %d\n" +#~ msgstr "%s: дочерний процесс завершился с ошибкой %d\n" + +#~ msgid "%s: could not fsync log file \"%s\": %s\n" +#~ msgstr "%s: не удалось синхронизировать с ФС файл журнала \"%s\": %s\n" + +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: удаление каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: ошибка при удалении каталога журнала транзакций\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: очистка каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: ошибка при очистке каталога журнала транзакций\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "" +#~ "%s: каталог журнала транзакций \"%s\" не был удалён по запросу " +#~ "пользователя\n" + +#~ msgid "%s: could not open transaction log file \"%s\": %s\n" +#~ msgstr "%s: не удалось открыть файл журнала транзакций \"%s\": %s\n" + +#~ msgid "" +#~ " -x, --xlog include required WAL files in backup (fetch " +#~ "mode)\n" +#~ msgstr "" +#~ " -x, --xlog включить в копию требуемые файлы WAL (режим " +#~ "fetch)\n" + +#~ msgid "%s: cannot specify both --xlog and --xlog-method\n" +#~ msgstr "%s: указать и --xlog, и --xlog-method одновременно нельзя\n" + +#~ msgid "%s: WAL streaming can only be used in plain mode\n" +#~ msgstr "%s: потоковая передача WAL поддерживается только в режиме plain\n" + +#~ msgid "%s: could not stat transaction log file \"%s\": %s\n" +#~ msgstr "%s: не удалось проверить файл журнала транзакций \"%s\": %s\n" + +#~ msgid "%s: could not pad transaction log file \"%s\": %s\n" +#~ msgstr "%s: не удалось дополнить файл журнала транзакций \"%s\": %s\n" + +#~ msgid "%s: could not rename file \"%s\": %s\n" +#~ msgstr "%s: не удалось переименовать файл \"%s\": %s\n" + +#~ msgid "%s: could not open timeline history file \"%s\": %s\n" +#~ msgstr "%s: не удалось открыть файл истории линии времени \"%s\": %s\n" + +#~ msgid "%s: could not parse file size\n" +#~ msgstr "%s: не удалось разобрать размер файла\n" + +#~ msgid "%s: could not parse file mode\n" +#~ msgstr "%s: не удалось разобрать режим файла\n" + +#~ msgid "%s: socket not open" +#~ msgstr "%s: сокет не открыт" + +#~ msgid "%s: could not remove symbolic link \"%s\": %s\n" +#~ msgstr "%s: ошибка при удалении символической ссылки \"%s\": %s\n" + +#~ msgid "" +#~ "\n" +#~ "Replication options:\n" +#~ msgstr "" +#~ "\n" +#~ "Параметры репликации:\n" + +#~ msgid "%s: initializing replication slot \"%s\"\n" +#~ msgstr "%s: инициализируется слот репликации \"%s\"\n" + +#~ msgid "" +#~ "%s: could not init logical replication: got %d rows and %d fields, " +#~ "expected %d rows and %d fields\n" +#~ msgstr "" +#~ "%s: не удалось инициализировать логическую репликацию; получено строк: " +#~ "%d, полей: %d (ожидалось: %d и %d)\n" + +#~ msgid "%s: no start point returned from server\n" +#~ msgstr "%s: сервер не вернул стартовую точку\n" + +#~ msgid "" +#~ "%s: timeline does not match between base backup and streaming connection\n" +#~ msgstr "" +#~ "%s: линия времени базовой резервной копии отличается от линии времени " +#~ "потоковой передачи\n" + +#~ msgid "%s: keepalive message has incorrect size %d\n" +#~ msgstr "%s: контрольное сообщение имеет некорректный размер: %d\n" + +#~ msgid "%s: could not close file %s: %s\n" +#~ msgstr "%s: не удалось закрыть файл %s: %s\n" + +#~ msgid "%s: invalid format of xlog location: %s\n" +#~ msgstr "%s: неверный формат позиции в xlog: %s\n" + +#~ msgid "%s: could not identify system: %s" +#~ msgstr "%s: не удалось идентифицировать систему: %s" + +#~ msgid "%s: could not send base backup command: %s" +#~ msgstr "" +#~ "%s: не удалось отправить команду базового резервного копирования: %s" + +#~ msgid "%s: could not identify system: %s\n" +#~ msgstr "%s: не удалось идентифицировать систему: %s\n" + +#~ msgid "%s: could not open WAL segment %s: %s\n" +#~ msgstr "%s: не удалось открыть сегмент WAL %s: %s\n" + +#~ msgid "%s: could not stat WAL segment %s: %s\n" +#~ msgstr "%s: не удалось получить информацию о сегменте WAL %s: %s\n" + +#~ msgid "%s: could not pad WAL segment %s: %s\n" +#~ msgstr "%s: не удалось дополнить сегмент WAL %s: %s\n" + +#~ msgid "%s: could not get current position in file %s: %s\n" +#~ msgstr "%s: не удалось получить текущую позицию в файле %s: %s\n" diff --git a/src/bin/pg_basebackup/po/uk.po b/src/bin/pg_basebackup/po/uk.po new file mode 100644 index 000000000000..6c717a732189 --- /dev/null +++ b/src/bin/pg_basebackup/po/uk.po @@ -0,0 +1,1452 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:15+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: pasha_golub\n" +"Language-Team: Ukrainian\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_basebackup.pot\n" +"X-Crowdin-File-ID: 490\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "недостатньо пам'яті\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" + +#: ../../common/file_utils.c:79 ../../common/file_utils.c:181 +#: pg_receivewal.c:266 pg_recvlogical.c:340 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не вдалося отримати інформацію від файлу \"%s\": %m" + +#: ../../common/file_utils.c:158 pg_receivewal.c:169 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не вдалося відкрити каталог \"%s\": %m" + +#: ../../common/file_utils.c:192 pg_receivewal.c:337 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не вдалося прочитати каталог \"%s\": %m" + +#: ../../common/file_utils.c:224 ../../common/file_utils.c:283 +#: ../../common/file_utils.c:357 ../../fe_utils/recovery_gen.c:134 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" + +#: ../../common/file_utils.c:295 ../../common/file_utils.c:365 +#: pg_recvlogical.c:193 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "не вдалося fsync файл \"%s\": %m" + +#: ../../common/file_utils.c:375 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "не вдалося перейменувати файл \"%s\" на \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 pg_basebackup.c:1248 +#, c-format +msgid "out of memory" +msgstr "недостатньо пам'яті" + +#: ../../fe_utils/recovery_gen.c:140 pg_basebackup.c:1021 pg_basebackup.c:1714 +#: pg_basebackup.c:1770 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "неможливо записати до файлу \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 pg_basebackup.c:1166 pg_basebackup.c:1671 +#: pg_basebackup.c:1747 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "неможливо створити файл \"%s\": %m" + +#: pg_basebackup.c:224 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "видалення даних з директорії \"%s\"" + +#: pg_basebackup.c:226 +#, c-format +msgid "failed to remove data directory" +msgstr "не вдалося видалити дані директорії" + +#: pg_basebackup.c:230 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "видалення даних з директорії \"%s\"" + +#: pg_basebackup.c:232 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "не вдалося видалити дані директорії" + +#: pg_basebackup.c:237 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "видалення WAL директорії \"%s\"" + +#: pg_basebackup.c:239 +#, c-format +msgid "failed to remove WAL directory" +msgstr "не вдалося видалити директорію WAL" + +#: pg_basebackup.c:243 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "видалення даних з директорії WAL \"%s\"" + +#: pg_basebackup.c:245 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "не вдалося видалити дані директорії WAL" + +#: pg_basebackup.c:251 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "директорія даних \"%s\" не видалена за запитом користувача" + +#: pg_basebackup.c:254 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "директорія WAL \"%s\" не видалена за запитом користувача" + +#: pg_basebackup.c:258 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "зміни в каталогах табличних просторів незворотні" + +#: pg_basebackup.c:299 +#, c-format +msgid "directory name too long" +msgstr "ім'я директорії задовге" + +#: pg_basebackup.c:309 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "кілька знаків \"=\" зіставленні табличних просторів" + +#: pg_basebackup.c:321 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "неприпустимий табличний простір зіставлення формату \"%s\", має бути \"OLDDIR = NEWDIR\"" + +#: pg_basebackup.c:333 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "старий каталог не є абсолютним шляхом у зіставлення табличного простору: %s" + +#: pg_basebackup.c:340 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "новий каталог не є абсолютним шляхом у зіставлення табличного простору: %s" + +#: pg_basebackup.c:379 +#, c-format +msgid "%s takes a base backup of a running PostgreSQL server.\n\n" +msgstr "%s робить базову резервну копію працюючого сервера PostgreSQL.\n\n" + +#: pg_basebackup.c:381 pg_receivewal.c:79 pg_recvlogical.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Використання:\n" + +#: pg_basebackup.c:382 pg_receivewal.c:80 pg_recvlogical.c:76 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s: [OPTION]...\n" + +#: pg_basebackup.c:383 +#, c-format +msgid "\n" +"Options controlling the output:\n" +msgstr "\n" +"Параметри, що контролюють вивід:\n" + +#: pg_basebackup.c:384 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, -- pgdata=DIRECTORY директорія, в яку зберегти резервну копію бази\n" + +#: pg_basebackup.c:385 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|т формат виводу (звичайний за замовчуванням, tar)\n" + +#: pg_basebackup.c:386 +#, c-format +msgid " -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr " -r, --max-rate=RATE максимальна швидкість передавання даних до директорії\n" +" (у кБ/с або з використанням суфіксів \"k\" або \"М\")\n" + +#: pg_basebackup.c:388 +#, c-format +msgid " -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr " -R, --write-recovery-conf\n" +" записати конфігурацію для реплікації\n" + +#: pg_basebackup.c:390 +#, c-format +msgid " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" перенестb табличний простір з OLDDIR до NEWDIR\n" + +#: pg_basebackup.c:392 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr "--waldir=WALDIR розташування журналу попереднього запису\n" + +#: pg_basebackup.c:393 +#, c-format +msgid " -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr " -X, --wal-method=none|fetch|stream\n" +" додати необхідні WAL файли за допомогою вказаного методу\n" + +#: pg_basebackup.c:395 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip стиснути вихідний tar\n" + +#: pg_basebackup.c:396 +#, c-format +msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 рівень стискання вихідного архіву \n" + +#: pg_basebackup.c:397 +#, c-format +msgid "\n" +"General options:\n" +msgstr "\n" +"Основні налаштування:\n" + +#: pg_basebackup.c:398 +#, c-format +msgid " -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr " -c, --checkpoint=fast|spread\n" +" режим швидких або розділених контрольних точок\n" + +#: pg_basebackup.c:400 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot створити слот для реплікації\n" + +#: pg_basebackup.c:401 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=LABEL встановити мітку резервної копії\n" + +#: pg_basebackup.c:402 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean не очищати після помилок\n" + +#: pg_basebackup.c:403 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync не чекати завершення збереження даних на диску\n" + +#: pg_basebackup.c:404 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress відображати інформацію про прогрес\n" + +#: pg_basebackup.c:405 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=ИМ'Я_СЛОТА використовувати вказаний слот реплікації\n" + +#: pg_basebackup.c:406 pg_receivewal.c:91 pg_recvlogical.c:96 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose виводити детальні повідомлення\n" + +#: pg_basebackup.c:407 pg_receivewal.c:92 pg_recvlogical.c:97 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію і вийти\n" + +#: pg_basebackup.c:408 +#, c-format +msgid " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" +" use algorithm for manifest checksums\n" +msgstr " --manifest-checksums=SHA{224,256,384,512}|CRC32C|НЕ\n" +" використовувати алгоритм для контрольних сум маніфесту\n" + +#: pg_basebackup.c:410 +#, c-format +msgid " --manifest-force-encode\n" +" hex encode all file names in manifest\n" +msgstr " --manifest-force-encode\n" +" кодувати у hex всі імена файлів у маніфесті\n" + +#: pg_basebackup.c:412 +#, c-format +msgid " --no-estimate-size do not estimate backup size in server side\n" +msgstr " --no-estimate-size не оцінювати розмір резервної копії на стороні сервера\n" + +#: pg_basebackup.c:413 +#, c-format +msgid " --no-manifest suppress generation of backup manifest\n" +msgstr " --no-manifest пропустити створення маніфесту резервного копіювання\n" + +#: pg_basebackup.c:414 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot не створювати тимчасового слоту реплікації\n" + +#: pg_basebackup.c:415 +#, c-format +msgid " --no-verify-checksums\n" +" do not verify checksums\n" +msgstr " --no-verify-checksums\n" +" не перевіряти контрольні суми\n" + +#: pg_basebackup.c:417 pg_receivewal.c:94 pg_recvlogical.c:98 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати цю довідку потім вийти\n" + +#: pg_basebackup.c:418 pg_receivewal.c:95 pg_recvlogical.c:99 +#, c-format +msgid "\n" +"Connection options:\n" +msgstr "\n" +"Налаштування з'єднання:\n" + +#: pg_basebackup.c:419 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONNSTR рядок з'єднання\n" + +#: pg_basebackup.c:420 pg_receivewal.c:97 pg_recvlogical.c:101 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME хост сервера бази даних або каталог сокетів\n" + +#: pg_basebackup.c:421 pg_receivewal.c:98 pg_recvlogical.c:102 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT порт сервера бази даних\n" + +#: pg_basebackup.c:422 +#, c-format +msgid " -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in seconds)\n" +msgstr " -s, --status-interval=INTERVAL часу між пакетами статусу до сервера (у секундах)\n" + +#: pg_basebackup.c:424 pg_receivewal.c:99 pg_recvlogical.c:103 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME підключатись як вказаний користувач бази даних\n" + +#: pg_basebackup.c:425 pg_receivewal.c:100 pg_recvlogical.c:104 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password ніколи не питати пароль\n" + +#: pg_basebackup.c:426 pg_receivewal.c:101 pg_recvlogical.c:105 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password обов'язково питати пароль (повинно відбуватися автоматично)\n" + +#: pg_basebackup.c:427 pg_receivewal.c:105 pg_recvlogical.c:106 +#, c-format +msgid "\n" +"Report bugs to <%s>.\n" +msgstr "\n" +"Повідомляти про помилки на <%s>.\n" + +#: pg_basebackup.c:428 pg_receivewal.c:106 pg_recvlogical.c:107 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: pg_basebackup.c:471 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "не можливо прочитати з готових каналів: %m" + +#: pg_basebackup.c:477 pg_basebackup.c:608 pg_basebackup.c:2133 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "не вдалося проаналізувати наперед журнал локації \"%s\"" + +#: pg_basebackup.c:573 pg_receivewal.c:441 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "не можливо закінчити написання файлів WAL: %m" + +#: pg_basebackup.c:620 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "не можливо створити канал для фонового процесу: %m" + +#: pg_basebackup.c:655 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "створено слот тимчасових реплікацій \"%s\"" + +#: pg_basebackup.c:658 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "створено слот реплікацій \"%s\"" + +#: pg_basebackup.c:678 pg_basebackup.c:731 pg_basebackup.c:1620 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не вдалося створити каталог \"%s\": %m" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not create background process: %m" +msgstr "не можливо створити фоновий процес: %m" + +#: pg_basebackup.c:708 +#, c-format +msgid "could not create background thread: %m" +msgstr "не можливо створити фоновий потік: %m" + +#: pg_basebackup.c:752 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "каталог \"%s\" існує, але він не порожній" + +#: pg_basebackup.c:759 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "немає доступу до каталогу \"%s\": %m" + +#: pg_basebackup.c:824 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d табличний простір %*s" +msgstr[1] "%*s/%s kB (100%%), %d/%d табличних простори %*s" +msgstr[2] "%*s/%s kB (100%%), %d/%d табличних просторів %*s" +msgstr[3] "%*s/%s kB (100%%), %d/%d табличних просторів %*s" + +#: pg_basebackup.c:836 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d табличний простір (%s%-*.*s)" +msgstr[1] "%*s/%s kB (%d%%), %d/%d табличних простори (%s%-*.*s)" +msgstr[2] "%*s/%s kB (%d%%), %d/%d табличних просторів (%s%-*.*s)" +msgstr[3] "%*s/%s kB (%d%%), %d/%d табличних просторів (%s%-*.*s)" + +#: pg_basebackup.c:852 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d табличний простір" +msgstr[1] "%*s/%s kB (%d%%), %d/%d табличних простори" +msgstr[2] "%*s/%s kB (%d%%), %d/%d табличних просторів" +msgstr[3] "%*s/%s kB (%d%%), %d/%d табличних просторів" + +#: pg_basebackup.c:877 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "частота передач \"%s\" не є припустимим значенням" + +#: pg_basebackup.c:882 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "неприпустима частота передач \"%s\": %m" + +#: pg_basebackup.c:891 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "частота передач повинна бути більша за нуль" + +#: pg_basebackup.c:923 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "неприпустима одиниця виміру в --max-rate: \"%s\"" + +#: pg_basebackup.c:930 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "швидкість передачі \"%s\" перевищує діапазон цілого числа" + +#: pg_basebackup.c:940 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "швидкість передавання \"%s\" поза діапазоном" + +#: pg_basebackup.c:961 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "не вдалося отримати потік даних COPY: %s" + +#: pg_basebackup.c:981 pg_recvlogical.c:435 pg_recvlogical.c:607 +#: receivelog.c:965 +#, c-format +msgid "could not read COPY data: %s" +msgstr "не вдалося прочитати дані COPY: %s" + +#: pg_basebackup.c:1007 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "не вдалося записати до стиснутого файлу \"%s\": %s" + +#: pg_basebackup.c:1071 +#, c-format +msgid "could not duplicate stdout: %m" +msgstr "не вдалося дублювати stdout: %m" + +#: pg_basebackup.c:1078 +#, c-format +msgid "could not open output file: %m" +msgstr "не вдалося відкрити вихідний файл: %m" + +#: pg_basebackup.c:1085 pg_basebackup.c:1106 pg_basebackup.c:1135 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "не вдалося встановити рівень стискання %d: %s" + +#: pg_basebackup.c:1155 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "не вдалося створити стиснутий файл \"%s\": %s" + +#: pg_basebackup.c:1267 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "не вдалося закрити стиснутий файл \"%s\": %s" + +#: pg_basebackup.c:1279 pg_recvlogical.c:632 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "неможливо закрити файл \"%s\": %m" + +#: pg_basebackup.c:1541 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "потік COPY завершився до завершення останнього файлу" + +#: pg_basebackup.c:1570 +#, c-format +msgid "invalid tar block header size: %zu" +msgstr "неприпустимий розмір заголовка блоку tar: %zu" + +#: pg_basebackup.c:1627 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "не вдалося встановити права для каталогу \"%s\": %m" + +#: pg_basebackup.c:1651 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "не вдалося створити символічне послання з \"%s\" на \"%s\": %m" + +#: pg_basebackup.c:1658 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "нерозпізнаний індикатор зв'язку \"%c\"" + +#: pg_basebackup.c:1677 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "не вдалося встановити права на файл \"%s\": %m" + +#: pg_basebackup.c:1831 +#, c-format +msgid "incompatible server version %s" +msgstr "несумісна версія серверу %s" + +#: pg_basebackup.c:1846 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "ПІДКАЗКА: використайте -X none або -X fetch, щоб вимкнути потокову передачу журналу" + +#: pg_basebackup.c:1882 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "початок базового резервного копіювання, очікується завершення контрольної точки" + +#: pg_basebackup.c:1908 pg_recvlogical.c:262 receivelog.c:481 receivelog.c:530 +#: receivelog.c:569 streamutil.c:297 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "не вдалося відправити реплікаційну команду \"%s\": %s" + +#: pg_basebackup.c:1919 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "не вдалося почати базове резервне копіювання: %s" + +#: pg_basebackup.c:1925 +#, c-format +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "сервер повернув неочікувану відповідь на команду BASE_BACKUP; отримано %d рядків і %d полів, очікувалось %d рядків і %d полів" + +#: pg_basebackup.c:1933 +#, c-format +msgid "checkpoint completed" +msgstr "контрольна точка завершена" + +#: pg_basebackup.c:1948 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "стартова точка у випереджувальному журналюванні: %s на часовій шкалі %u" + +#: pg_basebackup.c:1957 +#, c-format +msgid "could not get backup header: %s" +msgstr "не вдалося отримати заголовок резервної копії: %s" + +#: pg_basebackup.c:1963 +#, c-format +msgid "no data returned from server" +msgstr "сервер не повернув дані" + +#: pg_basebackup.c:1995 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "можна записати лише один табличний простір в stdout, всього їх в базі даних %d" + +#: pg_basebackup.c:2007 +#, c-format +msgid "starting background WAL receiver" +msgstr "запуск фонового процесу зчитування WAL" + +#: pg_basebackup.c:2046 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "не вдалося отримати кінцеву позицію у випереджувальному журналюванні з сервера: %s" + +#: pg_basebackup.c:2052 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "сервер не повернув кінцеву позицію у випереджувальному журналюванні" + +#: pg_basebackup.c:2057 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "кінцева точка у випереджувальному журналюванні: %s" + +#: pg_basebackup.c:2068 +#, c-format +msgid "checksum error occurred" +msgstr "сталася помилка контрольної суми" + +#: pg_basebackup.c:2073 +#, c-format +msgid "final receive failed: %s" +msgstr "помилка в кінці передачі: %s" + +#: pg_basebackup.c:2097 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "очікування завершення потокового передавання фоновим процесом ..." + +#: pg_basebackup.c:2102 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "не вдалося надіслати команду до канала фонового процесу: %m" + +#: pg_basebackup.c:2110 +#, c-format +msgid "could not wait for child process: %m" +msgstr "збій при очікуванні дочірнього процесу: %m" + +#: pg_basebackup.c:2115 +#, c-format +msgid "child %d died, expected %d" +msgstr "завершився дочірній процес %d, очікувалося %d" + +#: pg_basebackup.c:2120 streamutil.c:92 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2145 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "неможливо дочекатися дочірнього потоку: %m" + +#: pg_basebackup.c:2151 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "не можливо отримати статус завершення дочірнього потоку: %m" + +#: pg_basebackup.c:2156 +#, c-format +msgid "child thread exited with error %u" +msgstr "дочірній потік завершився з помилкою %u" + +#: pg_basebackup.c:2184 +#, c-format +msgid "syncing data to disk ..." +msgstr "синхронізація даних з диском ..." + +#: pg_basebackup.c:2209 +#, c-format +msgid "renaming backup_manifest.tmp to backup_manifest" +msgstr "перейменування backup_manifest.tmp в backup_manifest" + +#: pg_basebackup.c:2220 +#, c-format +msgid "base backup completed" +msgstr "базове резервне копіювання завершено" + +#: pg_basebackup.c:2305 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"" +msgstr "неприпустимий формат виводу \"%s\", повинен бути \"plain\" або \"tar\"" + +#: pg_basebackup.c:2349 +#, c-format +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "неприпустимий параметр wal-method \"%s\", повинен бути \"fetch\", \"stream\" або \"none\"" + +#: pg_basebackup.c:2377 pg_receivewal.c:580 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "неприпустимий рівень стискання \"%s\"" + +#: pg_basebackup.c:2388 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "неприпустимий аргумент контрольної точки \"%s\", повинен бути \"fast\" або \"spread\"" + +#: pg_basebackup.c:2415 pg_receivewal.c:555 pg_recvlogical.c:820 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "неприпустимий інтервал повідомлень про стан \"%s\"" + +#: pg_basebackup.c:2445 pg_basebackup.c:2458 pg_basebackup.c:2469 +#: pg_basebackup.c:2480 pg_basebackup.c:2488 pg_basebackup.c:2496 +#: pg_basebackup.c:2506 pg_basebackup.c:2519 pg_basebackup.c:2527 +#: pg_basebackup.c:2538 pg_basebackup.c:2548 pg_basebackup.c:2565 +#: pg_basebackup.c:2573 pg_basebackup.c:2581 pg_receivewal.c:605 +#: pg_receivewal.c:618 pg_receivewal.c:626 pg_receivewal.c:636 +#: pg_receivewal.c:644 pg_receivewal.c:655 pg_recvlogical.c:846 +#: pg_recvlogical.c:859 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 pg_recvlogical.c:902 +#: pg_recvlogical.c:910 pg_recvlogical.c:918 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: pg_basebackup.c:2456 pg_receivewal.c:616 pg_recvlogical.c:857 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" + +#: pg_basebackup.c:2468 pg_receivewal.c:654 +#, c-format +msgid "no target directory specified" +msgstr "цільовий каталог не вказано" + +#: pg_basebackup.c:2479 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "лише резервні копії в архіві tar можуть стискатись" + +#: pg_basebackup.c:2487 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "транслювати випереджувальні журналювання в режимі tar в потік stdout не можна" + +#: pg_basebackup.c:2495 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "слоти реплікації можуть використовуватись тільки з потоковим передаванням WAL" + +#: pg_basebackup.c:2505 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot не можна використовувати з іменем слота" + +#. translator: second %s is an option name +#: pg_basebackup.c:2517 pg_receivewal.c:634 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "для %s потрібно вказати слот за допомогою --slot" + +#: pg_basebackup.c:2526 +#, c-format +msgid "--create-slot and --no-slot are incompatible options" +msgstr "параметри --create-slot і --no-slot несумісні" + +#: pg_basebackup.c:2537 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "розташування каталога WAL можна вказати лише в режимі plain" + +#: pg_basebackup.c:2547 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "розташування WAL каталогу має бути абсолютним шляхом" + +#: pg_basebackup.c:2557 pg_receivewal.c:663 +#, c-format +msgid "this build does not support compression" +msgstr "ця збірка не підтримує стискання" + +#: pg_basebackup.c:2564 +#, c-format +msgid "--progress and --no-estimate-size are incompatible options" +msgstr "--progress і --no-estimate-size є несумісними параметрами" + +#: pg_basebackup.c:2572 +#, c-format +msgid "--no-manifest and --manifest-checksums are incompatible options" +msgstr "--no-manifest і --manifest-checksums є несумісними параметрами" + +#: pg_basebackup.c:2580 +#, c-format +msgid "--no-manifest and --manifest-force-encode are incompatible options" +msgstr "--no-manifest і --manifest-force-encode є несумісними параметрами" + +#: pg_basebackup.c:2639 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "не вдалося створити символічне послання \"%s\": %m" + +#: pg_basebackup.c:2643 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "символічні посилання не підтримуються цією платформою" + +#: pg_receivewal.c:77 +#, c-format +msgid "%s receives PostgreSQL streaming write-ahead logs.\n\n" +msgstr "%s отримує передачу випереджувальних журналів PostgreSQL.\n\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:81 +#, c-format +msgid "\n" +"Options:\n" +msgstr "\n" +"Параметри:\n" + +#: pg_receivewal.c:82 +#, c-format +msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr " -D, --directory=DIR зберігати файли випереджувального журналювання до цього каталогу\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:82 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN вийти після отримання вказаного LSN\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:86 +#, c-format +msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgstr " --if-not-exists не видавати помилку, при створенні слота, якщо слот вже існує\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:88 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop переривати роботу при втраті підключення\n" + +#: pg_receivewal.c:86 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync не чекати безпечного збереження змін на диск\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:93 +#, c-format +msgid " -s, --status-interval=SECS\n" +" time between status packets sent to server (default: %d)\n" +msgstr " -s, --status-interval=SECS\n" +" інтервал між відправкою статусних пакетів серверу (за замовчуванням: %d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid " --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous очистити випереджувальне журналювання відразу після запису\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 стискати журнали заданим рівнем стискання\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "\n" +"Optional actions:\n" +msgstr "\n" +"Додаткові дії:\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:78 +#, c-format +msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgstr " --create-slot створити новий слот реплікації (ім'я слота задає параметр --slot)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:79 +#, c-format +msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgstr " --drop-slot видалити слот реплікації (ім'я слота задає параметр --slot)\n" + +#: pg_receivewal.c:117 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "завершено сегмент в позиції %X/%X (часова шкала %u)" + +#: pg_receivewal.c:124 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "зупинено потокове передавання журналу в позиції %X/%X (часова шкала %u)" + +#: pg_receivewal.c:140 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "переключено на часову шкалу %u в позиції %X/%X" + +#: pg_receivewal.c:150 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "отримано сигнал переривання, завершення роботи" + +#: pg_receivewal.c:186 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не вдалося закрити каталог \"%s\": %m" + +#: pg_receivewal.c:272 +#, c-format +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "файл сегмента \"%s\" має неправильний розмір %d, пропускається" + +#: pg_receivewal.c:290 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "не вдалося відкрити стиснутий файл \"%s\": %m" + +#: pg_receivewal.c:296 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "не вдалося знайти в стиснутому файлі \"%s\": %m" + +#: pg_receivewal.c:304 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "не вдалося прочитати стиснутий файл \"%s\": %m" + +#: pg_receivewal.c:307 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "не вдалося прочитати стиснутий файл \"%s\": прочитано %d з %zu" + +#: pg_receivewal.c:318 +#, c-format +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "файл стиснутого сегменту \"%s\" має неправильний розмір без стискання %d, пропускається" + +#: pg_receivewal.c:422 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "початок потокового передавання журналу в позиції %X/%X (часова шкала %u)" + +#: pg_receivewal.c:537 pg_recvlogical.c:762 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "неприпустимий номер порту \"%s\"" + +#: pg_receivewal.c:565 pg_recvlogical.c:788 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "не вдалося проаналізувати кінцеву позицію \"%s\"" + +#: pg_receivewal.c:625 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "використовувати --create-slot разом з --drop-slot не можна" + +#: pg_receivewal.c:643 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "використовувати --synchronous разом з --no-sync не можна" + +#: pg_receivewal.c:719 +#, c-format +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "підключення для реплікації з використанням слоту \"%s\" неочікувано виявилось прив'язаним до бази даних" + +#: pg_receivewal.c:730 pg_recvlogical.c:966 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "видалення слоту реплікації \"%s\"" + +#: pg_receivewal.c:741 pg_recvlogical.c:976 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "створення слоту реплікації \"%s\"" + +#: pg_receivewal.c:767 pg_recvlogical.c:1001 +#, c-format +msgid "disconnected" +msgstr "роз’єднано" + +#. translator: check source for value for %d +#: pg_receivewal.c:773 pg_recvlogical.c:1007 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "роз’єднано; через %d секунд буде повторна спроба" + +#: pg_recvlogical.c:73 +#, c-format +msgid "%s controls PostgreSQL logical decoding streams.\n\n" +msgstr "%s керує потоковими передаваннями логічного декодування PostgreSQL.\n\n" + +#: pg_recvlogical.c:77 +#, c-format +msgid "\n" +"Action to be performed:\n" +msgstr "\n" +"Дія до виконання:\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgstr " --start почати потокове передавання в слоті реплікації (ім'я слоту задає параметр --slot)\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=FILE зберігати журнал до цього файлу, - позначає stdout\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid " -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: %d)\n" +msgstr " -F --fsync-interval=SECS\n" +" час між fsyncs до файлу виводу (за замовчуванням: %d)\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgstr " -I, --startpos=LSN де в існуючому слоті слід почати потокове передавання\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid " -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr " -o, --option=NAME[=VALUE]\n" +" передати параметр NAME з додатковим значенням VALUE до\n" +" плагіну виводу\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr " -P, --plugin=PLUGIN використовувати плагін виводу PLUGIN (за замовчуванням: %s)\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=SLOTNAME ім'я слоту логічної реплікації\n" + +#: pg_recvlogical.c:100 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=DBNAME бази даних для підключення\n" + +#: pg_recvlogical.c:133 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "підтвердження запису до %X/%X, очищення до %X/%X (слот %s)" + +#: pg_recvlogical.c:157 receivelog.c:343 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "не вдалося відправити пакет зворотнього зв'язку: %s" + +#: pg_recvlogical.c:230 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "початок потокового передавання журналу в позиції %X/%X (слот %s)" + +#: pg_recvlogical.c:271 +#, c-format +msgid "streaming initiated" +msgstr "потокове передавання ініційовано" + +#: pg_recvlogical.c:335 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "не вдалося відкрити файл протоколу \"%s\": %m" + +#: pg_recvlogical.c:361 receivelog.c:873 +#, c-format +msgid "invalid socket: %s" +msgstr "неприпустимий сокет: %s" + +#: pg_recvlogical.c:414 receivelog.c:901 +#, c-format +msgid "select() failed: %m" +msgstr "помилка в select(): %m" + +#: pg_recvlogical.c:421 receivelog.c:951 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "не вдалося отримати дані з WAL потоку: %s" + +#: pg_recvlogical.c:463 pg_recvlogical.c:514 receivelog.c:995 receivelog.c:1061 +#, c-format +msgid "streaming header too small: %d" +msgstr "заголовок потокового передавання занадто малий: %d" + +#: pg_recvlogical.c:498 receivelog.c:833 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "нерозпізнаний заголовок потокового передавання: \"%c\"" + +#: pg_recvlogical.c:552 pg_recvlogical.c:564 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "не вдалося записати %u байт до файлу журналу \"%s\": %m" + +#: pg_recvlogical.c:618 receivelog.c:629 receivelog.c:666 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "неочікуване завершення роботи потоку реплікації: %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "неприпустимий інтервал fsync \"%s\"" + +#: pg_recvlogical.c:780 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "не вдалося аналізувати початкову позицію \"%s\"" + +#: pg_recvlogical.c:869 +#, c-format +msgid "no slot specified" +msgstr "слот не вказано" + +#: pg_recvlogical.c:877 +#, c-format +msgid "no target file specified" +msgstr "цільовий файл не вказано" + +#: pg_recvlogical.c:885 +#, c-format +msgid "no database specified" +msgstr "база даних не вказана" + +#: pg_recvlogical.c:893 +#, c-format +msgid "at least one action needs to be specified" +msgstr "необхідно вказати щонайменше одну дію" + +#: pg_recvlogical.c:901 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "використовувати --create-slot або --start разом з --drop-slot не можна" + +#: pg_recvlogical.c:909 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "використовувати --create-slot або --drop-slot разом з --startpos не можна" + +#: pg_recvlogical.c:917 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos можна вказати лише з --start" + +#: pg_recvlogical.c:948 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "не вдалося встановити підключення для реплікації до вказаної бази даних" + +#: pg_recvlogical.c:1047 +#, c-format +msgid "end position %X/%X reached by keepalive" +msgstr "кінцева позиція %X/%X досягнута наживо" + +#: pg_recvlogical.c:1050 +#, c-format +msgid "end position %X/%X reached by WAL record at %X/%X" +msgstr "кінцева позиція %X/%X досягнута WAL записом %X/%X" + +#: receivelog.c:69 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "не вдалося створити файл статусу архіву \"%s\": %s" + +#: receivelog.c:116 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "не вдалося отримати розмір файлу випереджувального журналювання \"%s\": %s" + +#: receivelog.c:126 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "не вдалося відкрити існуючий файл випереджувального журналювання \"%s\": %s" + +#: receivelog.c:134 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "не вдалося fsync існуючий файл випереджувального журналювання \"%s\": %s" + +#: receivelog.c:148 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "файл випереджувального журналювання \"%s\" має %d байт, а повинен мати 0 або %d" +msgstr[1] "файл випереджувального журналювання \"%s\" має %d байти, а повинен мати 0 або %d" +msgstr[2] "файл випереджувального журналювання \"%s\" має %d байтів, а повинен мати 0 або %d" +msgstr[3] "файл випереджувального журналювання \"%s\" має %d байтів, а повинен мати 0 або %d" + +#: receivelog.c:163 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "не вдалося відкрити файл випереджувального журналювання \"%s\": %s" + +#: receivelog.c:189 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "не вдалося визначити позицію у файлі \"%s\": %s" + +#: receivelog.c:203 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "не перейменовується \"%s%s\", сегмент не завершено" + +#: receivelog.c:215 receivelog.c:300 receivelog.c:675 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "не вдалося закрити файл \"%s\": %s" + +#: receivelog.c:272 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "сервер повідомив неочікуване ім'я файлу історії часової шкали %u: %s" + +#: receivelog.c:280 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "не вдалося створити файл історії часової шкали \"%s\": %s" + +#: receivelog.c:287 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "не вдалося записати файл історії часової шкали \"%s\": %s" + +#: receivelog.c:377 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "несумісна версія серверу %s; клієнт не підтримує потокове передавання з версій серверу старіших, ніж %s" + +#: receivelog.c:386 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "несумісна версія серверу %s; клієнт не підтримує потокове передавання з версій серверу новіших, ніж %s" + +#: receivelog.c:488 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "не вдалося ідентифікувати систему: отримано %d рядків і %d полів, очікувалось %d рядків і %d або більше полів" + +#: receivelog.c:495 +#, c-format +msgid "system identifier does not match between base backup and streaming connection" +msgstr "системний ідентифікатор базової резервної копії не відповідає ідентифікатору потокового передавання підключення" + +#: receivelog.c:501 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "початкова часова шкала %u не існує на сервері" + +#: receivelog.c:542 +#, c-format +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "неочікувана відповідь на команду TIMELINE_HISTORY: отримано %d рядків і %d полів, очікувалось %d рядків і %d полів" + +#: receivelog.c:613 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "сервер неочікувано повідомив наступну часову шкалу %u після часової шкали %u" + +#: receivelog.c:619 +#, c-format +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "сервер зупинив потокове передавання часової шкали %u в позиції %X/%X, але повідомив, що наступна часова шкала %u почнеться в позиції %X/%X" + +#: receivelog.c:659 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "потік реплікації перервано до точки зупинки" + +#: receivelog.c:705 +#, c-format +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "неочікуваний набір результатів після кінця часової шкали: отримано %d рядків і %d полів, очікувалось %d рядків і %d полів" + +#: receivelog.c:714 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "не вдалося аналізувати початкову точку наступної часової шкали \"%s\"" + +#: receivelog.c:763 receivelog.c:1015 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "не вдалося fsync файл \"%s\": %s" + +#: receivelog.c:1078 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "отримано запис випереджувального журналювання для зсуву %u з закритим файлом" + +#: receivelog.c:1088 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "отримано дані зсуву WAL %08x, очікувалось %08x" + +#: receivelog.c:1122 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "не вдалося записати %u байт до файла WAL \"%s\": %s" + +#: receivelog.c:1147 receivelog.c:1187 receivelog.c:1218 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "не вдалося відправити пакет кінця копіювання \"copy-end\": %s" + +#: streamutil.c:160 +msgid "Password: " +msgstr "Пароль: " + +#: streamutil.c:185 +#, c-format +msgid "could not connect to server" +msgstr "не вдалося підключитись до серверу" + +#: streamutil.c:202 +#, c-format +msgid "could not connect to server: %s" +msgstr "не вдалося підключитися до сервера: %s" + +#: streamutil.c:231 +#, c-format +msgid "could not clear search_path: %s" +msgstr "не вдалося очистити search_path: %s" + +#: streamutil.c:247 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "не вдалося визначити настроювання серверу для integer_datetimes" + +#: streamutil.c:254 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "параметри компіляції integer_datetimes не відповідають серверу" + +#: streamutil.c:305 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "не вдалося отримати розмір сегменту WAL: отримано %d рядків і %d полів, очікувалось %d рядків і %d або більше полів" + +#: streamutil.c:315 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "не вдалося аналізувати розмір сегмента WAL" + +#: streamutil.c:333 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байт" +msgstr[1] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байти" +msgstr[2] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байтів" +msgstr[3] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байтів" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "не вдалося вилучити позначку доступа групи: отримано %d рядків і %d полів, очікувалось %d рядків і %d або більше полів" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "не вдалося аналізувати позначку доступа групи: %s" + +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "не вдалося створити слот реплікації \"%s\": отримано %d рядків і %d полів, очікувалось %d рядків і %d полів" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "не вдалося видалити слот реплікації \"%s\": отримано %d рядків і %d полів, очікувалось %d рядків і %d полів" + +#: walmethods.c:438 walmethods.c:927 +msgid "could not compress data" +msgstr "не вдалося стиснути дані" + +#: walmethods.c:470 +msgid "could not reset compression stream" +msgstr "не вдалося скинути потік стискання" + +#: walmethods.c:568 +msgid "could not initialize compression library" +msgstr "не вдалося ініціалізувати бібліотеку стискання" + +#: walmethods.c:580 +msgid "implementation error: tar files can't have more than one open file" +msgstr "помилка реалізації: файли tar не можуть мати більше одного відкритого файлу" + +#: walmethods.c:594 +msgid "could not create tar header" +msgstr "не вдалося створити заголовок tar" + +#: walmethods.c:608 walmethods.c:648 walmethods.c:843 walmethods.c:854 +msgid "could not change compression parameters" +msgstr "не вдалося змінити параметри стискання" + +#: walmethods.c:730 +msgid "unlink not supported with compression" +msgstr "unink не підтримується зі стисканням" + +#: walmethods.c:952 +msgid "could not close compression stream" +msgstr "не вдалося закрити потік стискання" + diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c index d3f99d89c5c8..3952a3f94300 100644 --- a/src/bin/pg_basebackup/receivelog.c +++ b/src/bin/pg_basebackup/receivelog.c @@ -5,7 +5,7 @@ * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/receivelog.c @@ -46,8 +46,7 @@ static bool ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, i XLogRecPtr *blockpos); static PGresult *HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf, XLogRecPtr blockpos, XLogRecPtr *stoppos); -static bool CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos, - XLogRecPtr *stoppos); +static bool CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos); static long CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout, TimestampTz last_status); @@ -561,7 +560,7 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) /* Initiate the replication stream at specified location */ snprintf(query, sizeof(query), "START_REPLICATION %s%X/%X TIMELINE %u", slotcmd, - (uint32) (stream->startpos >> 32), (uint32) stream->startpos, + LSN_FORMAT_ARGS(stream->startpos), stream->timeline); res = PQexec(conn, query); if (PQresultStatus(res) != PGRES_COPY_BOTH) @@ -617,8 +616,8 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) if (stream->startpos > stoppos) { pg_log_error("server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X", - stream->timeline, (uint32) (stoppos >> 32), (uint32) stoppos, - newtimeline, (uint32) (stream->startpos >> 32), (uint32) stream->startpos); + stream->timeline, LSN_FORMAT_ARGS(stoppos), + newtimeline, LSN_FORMAT_ARGS(stream->startpos)); goto error; } @@ -747,7 +746,7 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream, /* * Check if we should continue streaming, or abort at this point. */ - if (!CheckCopyStreamStop(conn, stream, blockpos, stoppos)) + if (!CheckCopyStreamStop(conn, stream, blockpos)) goto error; now = feGetCurrentTimestamp(); @@ -825,7 +824,7 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream, * Check if we should continue streaming, or abort at this * point. */ - if (!CheckCopyStreamStop(conn, stream, blockpos, stoppos)) + if (!CheckCopyStreamStop(conn, stream, blockpos)) goto error; } else @@ -898,7 +897,7 @@ CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket) { if (errno == EINTR) return 0; /* Got a signal, so not an error */ - pg_log_error("select() failed: %m"); + pg_log_error("%s() failed: %m", "select"); return -1; } if (ret > 0 && FD_ISSET(connsocket, &input_mask)) @@ -1203,8 +1202,7 @@ HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf, * Check if we should continue streaming, or abort at this point. */ static bool -CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos, - XLogRecPtr *stoppos) +CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos) { if (still_sending && stream->stream_stop(blockpos, stream->timeline, false)) { diff --git a/src/bin/pg_basebackup/receivelog.h b/src/bin/pg_basebackup/receivelog.h index efe7620401a3..e04333bf81d7 100644 --- a/src/bin/pg_basebackup/receivelog.h +++ b/src/bin/pg_basebackup/receivelog.h @@ -2,7 +2,7 @@ * * receivelog.h * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/receivelog.h diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 19728740846e..af0e4c082661 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -5,7 +5,7 @@ * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/streamutil.c @@ -22,6 +22,7 @@ #include "common/fe_memutils.h" #include "common/file_perm.h" #include "common/logging.h" +#include "common/string.h" #include "datatype/timestamp.h" #include "port/pg_bswap.h" #include "pqexpbuffer.h" @@ -49,8 +50,7 @@ char *dbuser = NULL; char *dbport = NULL; char *dbname = NULL; int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */ -static bool have_password = false; -static char password[100]; +static char *password = NULL; PGconn *conn = NULL; /* @@ -150,20 +150,21 @@ GetConnection(void) } /* If -W was given, force prompt for password, but only the first time */ - need_password = (dbgetpassword == 1 && !have_password); + need_password = (dbgetpassword == 1 && !password); do { /* Get a new password if appropriate */ if (need_password) { - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; + if (password) + free(password); + password = simple_prompt("Password: ", false); need_password = false; } /* Use (or reuse, on a subsequent connection) password if we have it */ - if (have_password) + if (password) { keywords[i] = "password"; values[i] = password; @@ -199,8 +200,7 @@ GetConnection(void) if (PQstatus(tmpconn) != CONNECTION_OK) { - pg_log_error("could not connect to server: %s", - PQerrorMessage(tmpconn)); + pg_log_error("%s", PQerrorMessage(tmpconn)); PQfinish(tmpconn); free(values); free(keywords); diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h index 57448656e3df..10f87ad0c14b 100644 --- a/src/bin/pg_basebackup/streamutil.h +++ b/src/bin/pg_basebackup/streamutil.h @@ -2,7 +2,7 @@ * * streamutil.h * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/streamutil.h diff --git a/src/bin/pg_basebackup/t/020_pg_receivewal.pl b/src/bin/pg_basebackup/t/020_pg_receivewal.pl index 6e2f05118771..a547c97ef187 100644 --- a/src/bin/pg_basebackup/t/020_pg_receivewal.pl +++ b/src/bin/pg_basebackup/t/020_pg_receivewal.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl index 99154bcf3988..53f41814b0b2 100644 --- a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl +++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pg_basebackup/walmethods.c b/src/bin/pg_basebackup/walmethods.c index bd1947d623fe..a15bbb20e737 100644 --- a/src/bin/pg_basebackup/walmethods.c +++ b/src/bin/pg_basebackup/walmethods.c @@ -5,7 +5,7 @@ * NOTE! The caller must ensure that only one method is instantiated in * any given program, and that it's only instantiated once! * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/walmethods.c diff --git a/src/bin/pg_basebackup/walmethods.h b/src/bin/pg_basebackup/walmethods.h index 9a661c673ccd..fc4bb52cb742 100644 --- a/src/bin/pg_basebackup/walmethods.h +++ b/src/bin/pg_basebackup/walmethods.h @@ -2,7 +2,7 @@ * * walmethods.h * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/walmethods.h diff --git a/src/bin/pg_checksums/Makefile b/src/bin/pg_checksums/Makefile index b1cfa5733d61..ba62406105d1 100644 --- a/src/bin/pg_checksums/Makefile +++ b/src/bin/pg_checksums/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_checksums # -# Copyright (c) 1998-2020, PostgreSQL Global Development Group +# Copyright (c) 1998-2021, PostgreSQL Global Development Group # # src/bin/pg_checksums/Makefile # diff --git a/src/bin/pg_checksums/nls.mk b/src/bin/pg_checksums/nls.mk index f0532d81f1c2..a7a9423a53c4 100644 --- a/src/bin/pg_checksums/nls.mk +++ b/src/bin/pg_checksums/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_checksums/nls.mk CATALOG_NAME = pg_checksums -AVAIL_LANGUAGES = cs de es fr ja ko ru sv tr +AVAIL_LANGUAGES = cs de el es fr ja ko ru sv tr uk zh_CN GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_checksums.c GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_checksums/pg_checksums.c b/src/bin/pg_checksums/pg_checksums.c index 623e2d36db01..0dd9a5cda8b5 100644 --- a/src/bin/pg_checksums/pg_checksums.c +++ b/src/bin/pg_checksums/pg_checksums.c @@ -4,7 +4,7 @@ * Checks, enables or disables page level checksums for an offline * cluster * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_checksums/pg_checksums.c @@ -229,12 +229,19 @@ scan_file(const char *fn, BlockNumber segmentno) } blocks++; + /* + * Since the file size is counted as total_size for progress status + * information, the sizes of all pages including new ones in the file + * should be counted as current_size. Otherwise the progress reporting + * calculated using those counters may not reach 100%. + */ + current_size += r; + /* New pages have no checksum yet */ if (PageIsNew(header)) continue; csum = pg_checksum_page(buf.data, blockno + segmentno * RELSEG_SIZE); - current_size += r; if (mode == PG_MODE_CHECK) { if (csum != header->pd_checksum) @@ -635,7 +642,7 @@ main(int argc, char *argv[]) if (mode == PG_MODE_CHECK) { printf(_("Bad checksums: %s\n"), psprintf(INT64_FORMAT, badblocks)); - printf(_("Data checksum version: %d\n"), ControlFile->data_checksum_version); + printf(_("Data checksum version: %u\n"), ControlFile->data_checksum_version); if (badblocks > 0) exit(1); @@ -662,7 +669,7 @@ main(int argc, char *argv[]) update_controlfile(DataDir, ControlFile, do_sync); if (verbose) - printf(_("Data checksum version: %d\n"), ControlFile->data_checksum_version); + printf(_("Data checksum version: %u\n"), ControlFile->data_checksum_version); if (mode == PG_MODE_ENABLE) printf(_("Checksums enabled in cluster\n")); else diff --git a/src/bin/pg_checksums/po/cs.po b/src/bin/pg_checksums/po/cs.po index e928e572d6e4..df56be82bbf2 100644 --- a/src/bin/pg_checksums/po/cs.po +++ b/src/bin/pg_checksums/po/cs.po @@ -7,27 +7,27 @@ msgid "" msgstr "" "Project-Id-Version: pg_checksums (PostgreSQL) 12\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-27 08:15+0000\n" -"PO-Revision-Date: 2019-09-27 17:23+0200\n" +"POT-Creation-Date: 2020-10-31 16:17+0000\n" +"PO-Revision-Date: 2020-10-31 21:31+0100\n" +"Last-Translator: \n" +"Language-Team: \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: \n" -"Language-Team: \n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 2.4.1\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "fatal: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "error: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "warning: " @@ -125,180 +125,188 @@ msgstr "" #: pg_checksums.c:91 #, c-format -msgid "Report bugs to .\n" -msgstr "Chyby hlaste na adresu .\n" +msgid "Report bugs to <%s>.\n" +msgstr "Chyby hlašte na <%s>.\n" + +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" -#: pg_checksums.c:149 +#: pg_checksums.c:161 #, c-format msgid "%*s/%s MB (%d%%) computed" msgstr "%*s/%s MB (%d%%) zpracováno" -#: pg_checksums.c:186 +#: pg_checksums.c:207 #, c-format msgid "could not open file \"%s\": %m" msgstr "nelze otevřít soubor \"%s\": %m" -#: pg_checksums.c:202 +#: pg_checksums.c:223 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "nelze přečíst blok %u v souboru \"%s\": %m" -#: pg_checksums.c:205 +#: pg_checksums.c:226 #, c-format msgid "could not read block %u in file \"%s\": read %d of %d" msgstr "nelze přečíst blok %u v souboru \"%s\": načteno %d z %d" -#: pg_checksums.c:222 +#: pg_checksums.c:243 #, c-format msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" msgstr "ověření kontrolnícou součtů selhalo v souboru \"%s\", blok %u: spočtený kontrolní součet %X ale klok obsahuje %X" -#: pg_checksums.c:237 +#: pg_checksums.c:258 #, c-format msgid "seek failed for block %u in file \"%s\": %m" msgstr "nastavení pozice (seek) selhalo pro blok %u v souboru \"%s\": %m" -#: pg_checksums.c:246 +#: pg_checksums.c:267 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "nelze zapsat blok %u v souboru \"%s\": %m" -#: pg_checksums.c:249 +#: pg_checksums.c:270 #, c-format msgid "could not write block %u in file \"%s\": wrote %d of %d" msgstr "nelze zapsat blok %u v souboru \"%s\": zapsáno %d z %d" -#: pg_checksums.c:262 +#: pg_checksums.c:283 #, c-format msgid "checksums verified in file \"%s\"" msgstr "kontrolní součty ověřeny v souboru \"%s\"" -#: pg_checksums.c:264 +#: pg_checksums.c:285 #, c-format msgid "checksums enabled in file \"%s\"" msgstr "kontrolní součty zapnuty v souboru \"%s\"" -#: pg_checksums.c:289 +#: pg_checksums.c:310 #, c-format msgid "could not open directory \"%s\": %m" msgstr "nelze otevřít adresář \"%s\": %m" -#: pg_checksums.c:316 +#: pg_checksums.c:337 pg_checksums.c:416 #, c-format msgid "could not stat file \"%s\": %m" msgstr "nelze načíst informace o souboru \"%s\": %m" -#: pg_checksums.c:343 +#: pg_checksums.c:364 #, c-format msgid "invalid segment number %d in file name \"%s\"" msgstr "chybné číslo segmentu %d ve jménu souboru \"%s\"" -#: pg_checksums.c:431 +#: pg_checksums.c:497 #, c-format msgid "invalid filenode specification, must be numeric: %s" msgstr "chybně zadaný filenode, vyžadována číselná hodnota: %s" -#: pg_checksums.c:449 pg_checksums.c:465 pg_checksums.c:475 pg_checksums.c:484 +#: pg_checksums.c:515 pg_checksums.c:531 pg_checksums.c:541 pg_checksums.c:550 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: pg_checksums.c:464 +#: pg_checksums.c:530 #, c-format msgid "no data directory specified" msgstr "datový adresář nebyl zadán" -#: pg_checksums.c:473 +#: pg_checksums.c:539 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "příliš mnoho parametrů na příkazové řádce (první je \"%s\")" -#: pg_checksums.c:483 +#: pg_checksums.c:549 #, c-format msgid "option -f/--filenode can only be used with --check" msgstr "volba -f/--filenode může být použita pouze s volbou --check" -#: pg_checksums.c:493 +#: pg_checksums.c:559 #, c-format msgid "pg_control CRC value is incorrect" msgstr "pg_control CRC hodnota je neplatná" -#: pg_checksums.c:499 +#: pg_checksums.c:565 #, c-format msgid "cluster is not compatible with this version of pg_checksums" msgstr "cluster není kompatibilní s touto verzí pg_checksums" -#: pg_checksums.c:505 +#: pg_checksums.c:571 #, c-format msgid "database cluster is not compatible" msgstr "databázový cluster není kompatibilní" -#: pg_checksums.c:506 +#: pg_checksums.c:572 #, c-format msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" msgstr "Databázový cluster byl inicializován s bloky velikosti %u, ale pg_checksums byl zkompilován pro velikost bloku %u.\n" -#: pg_checksums.c:519 +#: pg_checksums.c:585 #, c-format msgid "cluster must be shut down" msgstr "cluster musí být vypnutý" -#: pg_checksums.c:526 +#: pg_checksums.c:592 #, c-format msgid "data checksums are not enabled in cluster" msgstr "kontrolní součty nejsou v clusteru zapnuty" -#: pg_checksums.c:533 +#: pg_checksums.c:599 #, c-format msgid "data checksums are already disabled in cluster" msgstr "kontrolní součty jsou v clusteru již vypnuty" -#: pg_checksums.c:540 +#: pg_checksums.c:606 #, c-format msgid "data checksums are already enabled in cluster" msgstr "kontrolní součty jsou v clusteru již zapnuty" -#: pg_checksums.c:569 +#: pg_checksums.c:632 #, c-format msgid "Checksum operation completed\n" msgstr "Operace s kontrolními součty dokončena\n" -#: pg_checksums.c:570 +#: pg_checksums.c:633 #, c-format msgid "Files scanned: %s\n" msgstr "Souborů přečteno: %s\n" -#: pg_checksums.c:571 +#: pg_checksums.c:634 #, c-format msgid "Blocks scanned: %s\n" msgstr "Přečtené datové bloky: %s\n" -#: pg_checksums.c:574 +#: pg_checksums.c:637 #, c-format msgid "Bad checksums: %s\n" msgstr "Chybné kontrolní součty: %s\n" -#: pg_checksums.c:575 pg_checksums.c:602 +#: pg_checksums.c:638 pg_checksums.c:665 #, c-format msgid "Data checksum version: %d\n" msgstr "Verze kontrolních součtů: %d\n" -#: pg_checksums.c:594 +#: pg_checksums.c:657 #, c-format msgid "syncing data directory" msgstr "provádím sync datového adresáře" -#: pg_checksums.c:598 +#: pg_checksums.c:661 #, c-format msgid "updating control file" msgstr "aktualizuji control coubor" -#: pg_checksums.c:604 +#: pg_checksums.c:667 #, c-format msgid "Checksums enabled in cluster\n" msgstr "Kontrolní součty zapnuty v clusteru\n" -#: pg_checksums.c:606 +#: pg_checksums.c:669 #, c-format msgid "Checksums disabled in cluster\n" msgstr "Kontrolní součty vypnuty v clusteru\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Chyby hlaste na adresu .\n" diff --git a/src/bin/pg_checksums/po/de.po b/src/bin/pg_checksums/po/de.po new file mode 100644 index 000000000000..d30fb2bd5564 --- /dev/null +++ b/src/bin/pg_checksums/po/de.po @@ -0,0 +1,310 @@ +# German message translation file for pg_checksums +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Peter Eisentraut , 2018 - 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-01-12 03:47+0000\n" +"PO-Revision-Date: 2021-01-12 09:21+0100\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: pg_checksums.c:75 +#, c-format +msgid "" +"%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s überprüft die Datenprüfsummen in einem PostgreSQL-Datenbankcluster oder schaltet sie ein oder aus.\n" +"\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPTION]... [DATENVERZEICHNIS]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Optionen:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]VERZ Datenbankverzeichnis\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, --check Datenprüfsummen prüfen (Voreinstellung)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, --disable Datenprüfsummen ausschalten\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, --enable Datenprüfsummen einschalten\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILENODE nur Relation mit angegebenem Filenode prüfen\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress Fortschrittsinformationen zeigen\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose »Verbose«-Modus\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_checksums.c:89 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Wenn kein Datenverzeichnis angegeben ist, wird die Umgebungsvariable\n" +"PGDATA verwendet.\n" +"\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Berichten Sie Fehler an <%s>.\n" + +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: pg_checksums.c:161 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "%*s/%s MB (%d%%) berechnet" + +#: pg_checksums.c:207 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: pg_checksums.c:223 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "konnte Block %u in Datei »%s« nicht lesen: %m" + +#: pg_checksums.c:226 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "konnte Block %u in Datei »%s« nicht lesen: %d von %d gelesen" + +#: pg_checksums.c:243 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "Prüfsummenprüfung fehlgeschlagen in Datei »%s«, Block %u: berechnete Prüfsumme ist %X, aber der Block enthält %X" + +#: pg_checksums.c:258 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "seek fehlgeschlagen für Block %u in Datei »%s«: %m" + +#: pg_checksums.c:267 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "konnte Block %u in Datei »%s« nicht schreiben: %m" + +#: pg_checksums.c:270 +#, c-format +msgid "could not write block %u in file \"%s\": wrote %d of %d" +msgstr "konnte Block %u in Datei »%s« nicht schreiben: %d von %d geschrieben" + +#: pg_checksums.c:283 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "Prüfsummen wurden überprüft in Datei »%s«" + +#: pg_checksums.c:285 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "Prüfsummen wurden eingeschaltet in Datei »%s«" + +#: pg_checksums.c:310 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: pg_checksums.c:337 pg_checksums.c:416 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: pg_checksums.c:364 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "ungültige Segmentnummer %d in Dateiname »%s«" + +#: pg_checksums.c:497 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "ungültige Relfilenode-Angabe, muss numerisch sein: %s" + +#: pg_checksums.c:515 pg_checksums.c:531 pg_checksums.c:541 pg_checksums.c:550 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_checksums.c:530 +#, c-format +msgid "no data directory specified" +msgstr "kein Datenverzeichnis angegeben" + +#: pg_checksums.c:539 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_checksums.c:549 +#, c-format +msgid "option -f/--filenode can only be used with --check" +msgstr "Option -f/--filenode kann nur mit --check verwendet werden" + +#: pg_checksums.c:559 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "CRC-Wert in pg_control ist falsch" + +#: pg_checksums.c:565 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "die Cluster sind nicht mit dieser Version von pg_checksums kompatibel" + +#: pg_checksums.c:571 +#, c-format +msgid "database cluster is not compatible" +msgstr "Datenbank-Cluster ist nicht kompatibel" + +#: pg_checksums.c:572 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "Der Datenbank-Cluster wurde mit Blockgröße %u initialisiert, aber pg_checksums wurde mit Blockgröße %u kompiliert.\n" + +#: pg_checksums.c:585 +#, c-format +msgid "cluster must be shut down" +msgstr "Cluster muss heruntergefahren sein" + +#: pg_checksums.c:592 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "Datenprüfsummen sind im Cluster nicht eingeschaltet" + +#: pg_checksums.c:599 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "Datenprüfsummen sind im Cluster bereits ausgeschaltet" + +#: pg_checksums.c:606 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "Datenprüfsummen sind im Cluster bereits eingeschaltet" + +#: pg_checksums.c:632 +#, c-format +msgid "Checksum operation completed\n" +msgstr "Prüfsummenoperation abgeschlossen\n" + +#: pg_checksums.c:633 +#, c-format +msgid "Files scanned: %s\n" +msgstr "Überprüfte Dateien: %s\n" + +#: pg_checksums.c:634 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "Überprüfte Blöcke: %s\n" + +#: pg_checksums.c:637 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "Falsche Prüfsummen: %s\n" + +#: pg_checksums.c:638 pg_checksums.c:665 +#, c-format +msgid "Data checksum version: %u\n" +msgstr "Datenprüfsummenversion: %u\n" + +#: pg_checksums.c:657 +#, c-format +msgid "syncing data directory" +msgstr "synchronisiere Datenverzeichnis" + +#: pg_checksums.c:661 +#, c-format +msgid "updating control file" +msgstr "aktualisiere Kontrolldatei" + +#: pg_checksums.c:667 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "Prüfsummen wurden im Cluster eingeschaltet\n" + +#: pg_checksums.c:669 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "Prüfsummen wurden im Cluster ausgeschaltet\n" diff --git a/src/bin/pg_checksums/po/el.po b/src/bin/pg_checksums/po/el.po new file mode 100644 index 000000000000..cb72eabcbece --- /dev/null +++ b/src/bin/pg_checksums/po/el.po @@ -0,0 +1,309 @@ +# Greek message translation file for pg_checksums +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_checksums (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_checksums (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:49+0000\n" +"PO-Revision-Date: 2021-04-28 11:54+0200\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση: " + +#: pg_checksums.c:75 +#, c-format +msgid "" +"%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s ενεργοποιεί, απενεργοποιεί ή επαληθεύει τα αθροίσματα ελέγχου δεδομένων σε μία συστάδα βάσεων δεδομένων PostgreSQL.\n" +"\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [ΕΠΙΛΟΓΕΣ]… [DATADIR]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Επιλογές:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-Δ, --pgdata=] Κατάλογος δεδομένων DATADIR\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, —check έλεγξε αθροίσματα ελέγχου δεδομένων (προεπιλογή)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, —disable απενεργοποίησε τα αθροίσματα ελέγχου δεδομένων\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, —enable ενεργοποίησε τα αθροίσματα ελέγχου δεδομένων\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, —filenode=FILENODE έλεγξε μόνο τη σχέση με το καθορισμένο filenode\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, —no-sync να μην αναμένει την ασφαλή εγγραφή αλλαγών στον δίσκο\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, —progress εμφάνισε πληροφορίες προόδου\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, —verbose περιφραστικά μηνύματα εξόδου\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης, στη συνέχεια έξοδος\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, στη συνέχεια έξοδος\n" + +#: pg_checksums.c:89 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Εάν δεν έχει καθοριστεί κατάλογος δεδομένων (DATADIR), χρησιμοποιείται η\n" +"μεταβλητή περιβάλλοντος PGDATA.\n" +"\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_checksums.c:161 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "%*s/%s MB (%d%%) Υπολογίζεται" + +#: pg_checksums.c:207 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου “%s”: %m" + +#: pg_checksums.c:223 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του μπλοκ %u στο αρχείο \"%s\": %m" + +#: pg_checksums.c:226 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "δεν ήταν δυνατή η ανάγνωση του μπλοκ %u στο αρχείο “%s”: ανάγνωσε %d από %d" + +#: pg_checksums.c:250 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "επαλήθευση του αθροίσματος ελέγχου απέτυχε στο αρχείο \"%s\", μπλοκ %u: υπολογισμένο άθροισμα ελέγχου %X αλλά το μπλοκ περιέχει %X" + +#: pg_checksums.c:265 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "αναζήτηση απέτυχε για μπλοκ %u στο αρχείο \"%s\": %m" + +#: pg_checksums.c:274 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εγγραφή μπλοκ %u στο αρχείο \"%s\": %m" + +#: pg_checksums.c:277 +#, c-format +msgid "could not write block %u in file \"%s\": wrote %d of %d" +msgstr "δεν ήταν δυνατή η εγγραφή μπλοκ %u στο αρχείο \"%s\": έγραψε %d από %d" + +#: pg_checksums.c:290 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "επαληθευμένα αθροίσματα ελέγχου στο αρχείο \"%s\"" + +#: pg_checksums.c:292 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "ενεργοποιημένα αθροίσματα ελέγχου στο αρχείο \"%s\"" + +#: pg_checksums.c:317 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του καταλόγου “%s”: %m" + +#: pg_checksums.c:344 pg_checksums.c:423 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση stat στο αρχείο “%s”: %m" + +#: pg_checksums.c:371 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "μη έγκυρος αριθμός τμήματος %d στο αρχείο με όνομα “%s”" + +#: pg_checksums.c:504 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "μη έγκυρη προδιαγραφή filenode, πρέπει να είναι αριθμητική: %s" + +#: pg_checksums.c:522 pg_checksums.c:538 pg_checksums.c:548 pg_checksums.c:557 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_checksums.c:537 +#, c-format +msgid "no data directory specified" +msgstr "δεν ορίστηκε κατάλογος δεδομένων" + +#: pg_checksums.c:546 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (πρώτη είναι η “%s”)" + +#: pg_checksums.c:556 +#, c-format +msgid "option -f/--filenode can only be used with --check" +msgstr "η επιλογή -f/--filenode μπορεί να χρησιμοποιηθεί μόνο μαζί με την --check" + +#: pg_checksums.c:566 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "η τιμή pg_control CRC είναι λανθασμένη" + +#: pg_checksums.c:572 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "η συστάδα δεν είναι συμβατή με αυτήν την έκδοση pg_checksums" + +#: pg_checksums.c:578 +#, c-format +msgid "database cluster is not compatible" +msgstr "η συστάδα βάσεων δεδομένων δεν είναι συμβατή" + +#: pg_checksums.c:579 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "Η συστάδα βάσεων δεδομένων αρχικοποιήθηκε με μέγεθος μπλοκ %u, αλλά το pg_checksums μεταγλωττίστηκε με μέγεθος μπλοκ %u .\n" + +#: pg_checksums.c:592 +#, c-format +msgid "cluster must be shut down" +msgstr "η συστάδα πρέπει να τερματιστεί" + +#: pg_checksums.c:599 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "τα αθροίσματα ελέγχου δεδομένων δεν είναι ενεργοποιημένα στη συστάδα" + +#: pg_checksums.c:606 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "τα αθροίσματα ελέγχου δεδομένων είναι ήδη απενεργοποιημένα στη συστάδα" + +#: pg_checksums.c:613 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "τα αθροίσματα ελέγχου δεδομένων είναι ήδη ενεργοποιημένα στη συστάδα" + +#: pg_checksums.c:639 +#, c-format +msgid "Checksum operation completed\n" +msgstr "Ολοκληρώθηκε η λειτουργία του αθροίσματος ελέγχου\n" + +#: pg_checksums.c:640 +#, c-format +msgid "Files scanned: %s\n" +msgstr "Αρχεία που σαρώθηκαν: %s\n" + +#: pg_checksums.c:641 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "Μπλοκ που σαρώθηκαν: %s\n" + +#: pg_checksums.c:644 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "Εσφαλμένα αθροίσματα ελέγχου: %s\n" + +#: pg_checksums.c:645 pg_checksums.c:672 +#, c-format +msgid "Data checksum version: %u\n" +msgstr "Έκδοση αθροισμάτων ελέγχου: %u\n" + +#: pg_checksums.c:664 +#, c-format +msgid "syncing data directory" +msgstr "συγχρονίζεται κατάλογος δεδομένων" + +#: pg_checksums.c:668 +#, c-format +msgid "updating control file" +msgstr "ενημερώνεται αρχείο ελέγχου" + +#: pg_checksums.c:674 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "τα αθροίσματα ελέγχου δεδομένων είναι ενεργοποιημένα στη συστάδα\n" + +#: pg_checksums.c:676 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "Τα αθροίσματα ελέγχου δεδομένων είναι απενεργοποιημένα στη συστάδα\n" diff --git a/src/bin/pg_checksums/po/es.po b/src/bin/pg_checksums/po/es.po new file mode 100644 index 000000000000..3b7e35c8cd07 --- /dev/null +++ b/src/bin/pg_checksums/po/es.po @@ -0,0 +1,312 @@ +# Spanish message translation file for pg_checksums +# +# Copyright (c) 2019-2019, PostgreSQL Global Development Group +# +# This file is distributed under the same license as the pg_checksums (PostgreSQL) package. +# Álvaro Herrera , 2019. +# Carlos Chapi , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_checksums (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:49+0000\n" +"PO-Revision-Date: 2021-05-20 21:25-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: pgsql-es-ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: pg_checksums.c:75 +#, c-format +msgid "" +"%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s activa, desactiva o verifica checksums de datos en un clúster PostgreSQL.\n" +"\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPCIÓN]... [DATADIR]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Opciones:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR directorio de datos\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, --check verificar checksums (por omisión)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, --disable desactivar checksums\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, --enable activar checksums\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILENODE verificar sólo la relación con el filenode dado\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress mostrar información de progreso\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose desplegar mensajes verbosos\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: pg_checksums.c:89 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Si no se especifica un directorio de datos (DATADIR), se utilizará\n" +"la variable de entorno PGDATA.\n" +"\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Reportar errores a <%s>.\n" + +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_checksums.c:161 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "%*s/%s MB (%d%%) calculado" + +#: pg_checksums.c:207 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: pg_checksums.c:223 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "no se pudo leer el bloque %u del archivo «%s»: %m" + +#: pg_checksums.c:226 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "no se pudo leer bloque %u en archivo «%s»: leídos %d de %d" + +#: pg_checksums.c:250 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "verificación de checksums falló en archivo «%s», bloque %u: checksum calculado %X pero bloque contiene %X" + +#: pg_checksums.c:265 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "posicionamiento (seek) falló para el bloque %u en archivo «%s»: %m" + +#: pg_checksums.c:274 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "no se pudo escribir el bloque %u en el archivo «%s»: %m" + +#: pg_checksums.c:277 +#, c-format +msgid "could not write block %u in file \"%s\": wrote %d of %d" +msgstr "no se pudo escribir el bloque %u en el archivo «%s»: se escribieron %d de %d" + +#: pg_checksums.c:290 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "checksums verificados en archivo «%s»" + +#: pg_checksums.c:292 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "checksums activados en archivo «%s»" + +#: pg_checksums.c:317 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_checksums.c:344 pg_checksums.c:423 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: pg_checksums.c:371 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "número de segmento %d no válido en nombre de archivo «%s»" + +#: pg_checksums.c:504 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "especificación de filenode no válida: deben ser numérica: %s" + +#: pg_checksums.c:522 pg_checksums.c:538 pg_checksums.c:548 pg_checksums.c:557 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_checksums.c:537 +#, c-format +msgid "no data directory specified" +msgstr "no se especificó el directorio de datos" + +#: pg_checksums.c:546 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_checksums.c:556 +#, c-format +msgid "option -f/--filenode can only be used with --check" +msgstr "la opción -f/--filenode sólo puede usarse con --check" + +#: pg_checksums.c:566 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "el valor de CRC de pg_control es incorrecto" + +#: pg_checksums.c:572 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "el clúster no es compatible con esta versión de pg_checksums" + +#: pg_checksums.c:578 +#, c-format +msgid "database cluster is not compatible" +msgstr "el clúster de bases de datos no es compatible" + +#: pg_checksums.c:579 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "El clúster fue inicializado con tamaño de bloque %u, pero pg_checksums fue compilado con tamaño de bloques %u.\n" + +#: pg_checksums.c:592 +#, c-format +msgid "cluster must be shut down" +msgstr "el clúster debe estar apagado" + +#: pg_checksums.c:599 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "los checksums de datos no están activados en el clúster" + +#: pg_checksums.c:606 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "los checksums de datos ya están desactivados en el clúster" + +#: pg_checksums.c:613 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "los checksums de datos ya están activados en el clúster" + +#: pg_checksums.c:639 +#, c-format +msgid "Checksum operation completed\n" +msgstr "Operación de checksums completa\n" + +#: pg_checksums.c:640 +#, c-format +msgid "Files scanned: %s\n" +msgstr "Archivos recorridos: %s\n" + +#: pg_checksums.c:641 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "Bloques recorridos: %s\n" + +#: pg_checksums.c:644 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "Checksums incorrectos: %s\n" + +#: pg_checksums.c:645 pg_checksums.c:672 +#, c-format +msgid "Data checksum version: %u\n" +msgstr "Versión de checksums de datos: %u\n" + +#: pg_checksums.c:664 +#, c-format +msgid "syncing data directory" +msgstr "sincronizando directorio de datos" + +#: pg_checksums.c:668 +#, c-format +msgid "updating control file" +msgstr "actualizando archivo de control" + +#: pg_checksums.c:674 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "Checksums activos en el clúster\n" + +#: pg_checksums.c:676 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "Checksums inactivos en el clúster\n" diff --git a/src/bin/pg_checksums/po/fr.po b/src/bin/pg_checksums/po/fr.po index 9d5f8ed24a3c..40633c5166c1 100644 --- a/src/bin/pg_checksums/po/fr.po +++ b/src/bin/pg_checksums/po/fr.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: pg_verify_checksums (PostgreSQL) 12\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2020-04-16 06:17+0000\n" -"PO-Revision-Date: 2020-04-16 13:40+0200\n" +"POT-Creation-Date: 2020-12-23 15:18+0000\n" +"PO-Revision-Date: 2020-12-24 11:45+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.3\n" +"X-Generator: Poedit 2.4.2\n" #: ../../../src/common/logging.c:236 #, c-format @@ -138,127 +138,127 @@ msgstr "page d'accueil de %s : <%s>\n" msgid "%*s/%s MB (%d%%) computed" msgstr "%*s/%s Mo (%d%%) traités" -#: pg_checksums.c:204 +#: pg_checksums.c:207 #, c-format msgid "could not open file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier « %s » : %m" -#: pg_checksums.c:220 +#: pg_checksums.c:223 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "n'a pas pu lire le bloc %u dans le fichier « %s » : %m" -#: pg_checksums.c:223 +#: pg_checksums.c:226 #, c-format msgid "could not read block %u in file \"%s\": read %d of %d" msgstr "n'a pas pu lire le bloc %u dans le fichier « %s » : %d lus sur %d" -#: pg_checksums.c:240 +#: pg_checksums.c:243 #, c-format msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" msgstr "échec de la vérification de la somme de contrôle dans le fichier « %s », bloc %u : somme de contrôle calculée %X, alors que le bloc contient %X" -#: pg_checksums.c:255 +#: pg_checksums.c:258 #, c-format msgid "seek failed for block %u in file \"%s\": %m" msgstr "n'a pas pu rechercher le bloc %u dans le fichier « %s » : %m" -#: pg_checksums.c:264 +#: pg_checksums.c:267 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "n'a pas pu écrire le bloc %u dans le fichier « %s » : %m" -#: pg_checksums.c:267 +#: pg_checksums.c:270 #, c-format msgid "could not write block %u in file \"%s\": wrote %d of %d" msgstr "n'a pas pu écrire le bloc %u du fichier « %s » : a écrit %d octets sur %d" -#: pg_checksums.c:280 +#: pg_checksums.c:283 #, c-format msgid "checksums verified in file \"%s\"" msgstr "sommes de contrôle vérifiées dans le fichier « %s »" -#: pg_checksums.c:282 +#: pg_checksums.c:285 #, c-format msgid "checksums enabled in file \"%s\"" msgstr "sommes de contrôle activées dans le fichier « %s »" -#: pg_checksums.c:307 +#: pg_checksums.c:310 #, c-format msgid "could not open directory \"%s\": %m" msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" -#: pg_checksums.c:334 pg_checksums.c:413 +#: pg_checksums.c:337 pg_checksums.c:416 #, c-format msgid "could not stat file \"%s\": %m" msgstr "n'a pas pu tester le fichier « %s » : %m" -#: pg_checksums.c:361 +#: pg_checksums.c:364 #, c-format msgid "invalid segment number %d in file name \"%s\"" msgstr "numéro de segment %d invalide dans le nom de fichier « %s »" -#: pg_checksums.c:494 +#: pg_checksums.c:497 #, c-format msgid "invalid filenode specification, must be numeric: %s" msgstr "spécification invalide du relfilnode, doit être numérique : %s" -#: pg_checksums.c:512 pg_checksums.c:528 pg_checksums.c:538 pg_checksums.c:547 +#: pg_checksums.c:515 pg_checksums.c:531 pg_checksums.c:541 pg_checksums.c:550 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayez « %s --help » pour plus d'informations.\n" -#: pg_checksums.c:527 +#: pg_checksums.c:530 #, c-format msgid "no data directory specified" msgstr "aucun répertoire de données indiqué" -#: pg_checksums.c:536 +#: pg_checksums.c:539 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" -#: pg_checksums.c:546 +#: pg_checksums.c:549 #, c-format msgid "option -f/--filenode can only be used with --check" msgstr "l'option « -f/--filenode » peut seulement être utilisée avec --check" -#: pg_checksums.c:556 +#: pg_checksums.c:559 #, c-format msgid "pg_control CRC value is incorrect" msgstr "la valeur CRC de pg_control n'est pas correcte" -#: pg_checksums.c:562 +#: pg_checksums.c:565 #, c-format msgid "cluster is not compatible with this version of pg_checksums" msgstr "l'instance n'est pas compatible avec cette version de pg_checksums" -#: pg_checksums.c:568 +#: pg_checksums.c:571 #, c-format msgid "database cluster is not compatible" msgstr "l'instance n'est pas compatible" -#: pg_checksums.c:569 +#: pg_checksums.c:572 #, c-format msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" msgstr "L'instance a été initialisée avec une taille de bloc à %u alors que pg_checksums a été compilé avec une taille de bloc à %u.\n" -#: pg_checksums.c:582 +#: pg_checksums.c:585 #, c-format msgid "cluster must be shut down" msgstr "l'instance doit être arrêtée" -#: pg_checksums.c:589 +#: pg_checksums.c:592 #, c-format msgid "data checksums are not enabled in cluster" msgstr "les sommes de contrôle sur les données ne sont pas activées sur cette instance" -#: pg_checksums.c:596 +#: pg_checksums.c:599 #, c-format msgid "data checksums are already disabled in cluster" msgstr "les sommes de contrôle sur les données sont déjà désactivées sur cette instance" -#: pg_checksums.c:603 +#: pg_checksums.c:606 #, c-format msgid "data checksums are already enabled in cluster" msgstr "les sommes de contrôle sur les données sont déjà activées sur cette instance" @@ -285,8 +285,8 @@ msgstr "Mauvaises sommes de contrôle : %s\n" #: pg_checksums.c:638 pg_checksums.c:665 #, c-format -msgid "Data checksum version: %d\n" -msgstr "Version des sommes de contrôle sur les données : %d\n" +msgid "Data checksum version: %u\n" +msgstr "Version des sommes de contrôle sur les données : %u\n" #: pg_checksums.c:657 #, c-format @@ -308,26 +308,26 @@ msgstr "Sommes de contrôle sur les données activées sur cette instance\n" msgid "Checksums disabled in cluster\n" msgstr "Sommes de contrôle sur les données désactivées sur cette instance\n" -#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" -#~ msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" - -#~ msgid "%s: no data directory specified\n" -#~ msgstr "%s : aucun répertoire de données indiqué\n" +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapporter les bogues à .\n" -#~ msgid "%s: could not stat file \"%s\": %s\n" -#~ msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version affiche la version puis quitte\n" -#~ msgid "%s: could not open directory \"%s\": %s\n" -#~ msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n" +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help affiche cette aide puis quitte\n" #~ msgid "%s: could not open file \"%s\": %s\n" #~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" -#~ msgid " -?, --help show this help, then exit\n" -#~ msgstr " -?, --help affiche cette aide puis quitte\n" +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n" -#~ msgid " -V, --version output version information, then exit\n" -#~ msgstr " -V, --version affiche la version puis quitte\n" +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" -#~ msgid "Report bugs to .\n" -#~ msgstr "Rapporter les bogues à .\n" +#~ msgid "%s: no data directory specified\n" +#~ msgstr "%s : aucun répertoire de données indiqué\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" diff --git a/src/bin/pg_checksums/po/ja.po b/src/bin/pg_checksums/po/ja.po index d789c5439682..f43465a0e408 100644 --- a/src/bin/pg_checksums/po/ja.po +++ b/src/bin/pg_checksums/po/ja.po @@ -4,29 +4,29 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_checksums (PostgreSQL 12 beta 1)\n" +"Project-Id-Version: pg_checksums (PostgreSQL 13)\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-06-06 18:38+0900\n" -"PO-Revision-Date: 2019-06-06 18:38+0900\n" +"POT-Creation-Date: 2020-08-21 15:54+0900\n" +"PO-Revision-Date: 2020-08-21 23:22+0900\n" "Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.5.4\n" +"X-Generator: Poedit 1.8.13\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:241 #, c-format msgid "fatal: " msgstr "致命的エラー: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:248 #, c-format msgid "error: " msgstr "エラー: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:255 #, c-format msgid "warning: " msgstr "警告: " @@ -34,12 +34,10 @@ msgstr "警告: " #: pg_checksums.c:75 #, c-format msgid "" -"%s enables, disables or verifies data checksums in a PostgreSQL database " -"cluster.\n" +"%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n" "\n" msgstr "" -"%s はPostgreSQLデータベースクラスタにおけるデータチェックサムの有効化、無効化" -"および検証を行います。\n" +"%s はPostgreSQLデータベースクラスタにおけるデータチェックサムの有効化、無効化および検証を行います。\n" "\n" #: pg_checksums.c:76 @@ -83,16 +81,12 @@ msgstr " -e, --enable データチェックサムを有効化\n" #: pg_checksums.c:83 #, c-format -msgid "" -" -f, --filenode=FILENODE check only relation with specified filenode\n" -msgstr "" -" -f, --filenode=FILENODE 指定したファイルノードのリレーションのみ検証\n" +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILENODE 指定したファイルノードのリレーションのみ検証\n" #: pg_checksums.c:84 #, c-format -msgid "" -" -N, --no-sync do not wait for changes to be written safely to " -"disk\n" +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync ディスクへの安全な書き込みを待機しない\n" #: pg_checksums.c:85 @@ -119,192 +113,201 @@ msgstr " -?, --help このヘルプを表示して終了\n" #, c-format msgid "" "\n" -"If no data directory (DATADIR) is specified, the environment variable " -"PGDATA\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" "is used.\n" "\n" msgstr "" "\n" -"データディレクトリ(DATADIR)が指定されない場合、PGDATA環境変数が使用されま" -"す。\n" +"データディレクトリ(DATADIR)が指定されない場合、PGDATA環境変数が使用されます。\n" "\n" #: pg_checksums.c:91 #, c-format -msgid "Report bugs to .\n" -msgstr "バグは に報告してください。\n" +msgid "Report bugs to <%s>.\n" +msgstr "バグは<%s>に報告してください。\n" + +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" -#: pg_checksums.c:149 +#: pg_checksums.c:161 #, c-format -#| msgid "%*s/%s kB (%d%%) copied" msgid "%*s/%s MB (%d%%) computed" msgstr "%*s/%s MB (%d%%) 完了" -#: pg_checksums.c:186 +#: pg_checksums.c:207 #, c-format msgid "could not open file \"%s\": %m" msgstr "ファイル\"%s\"をオープンできませんでした: %m" -#: pg_checksums.c:201 +#: pg_checksums.c:223 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "ファイル\"%2$s\"で%1$uブロックを読み取れませんでした: %3$m" + +#: pg_checksums.c:226 #, c-format msgid "could not read block %u in file \"%s\": read %d of %d" -msgstr "" -" ファイル\"%2$s\"のブロック%1$uが読み込めませんでした: %4$d中%3$d読み込み済み" +msgstr " ファイル\"%2$s\"のブロック%1$uが読み込めませんでした: %4$d中%3$d読み込み済み" -#: pg_checksums.c:218 +#: pg_checksums.c:243 #, c-format -msgid "" -"checksum verification failed in file \"%s\", block %u: calculated checksum " -"%X but block contains %X" -msgstr "" -"ファイル\"%s\" ブロック%uでチェックサム検証が失敗: 算出したチェックサム" -"は%X 、しかしブロック上の値は%X" +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "ファイル\"%s\" ブロック%uでチェックサム検証が失敗: 算出したチェックサムは%X 、しかしブロック上の値は%X" -#: pg_checksums.c:231 +#: pg_checksums.c:258 #, c-format msgid "seek failed for block %u in file \"%s\": %m" msgstr "ファイル\"%2$s\" ブロック%1$uへのシーク失敗: %3$m" -#: pg_checksums.c:238 +#: pg_checksums.c:267 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "ファイル\"%2$s\"で%1$uブロックが書き出せませんでした: %3$m" + +#: pg_checksums.c:270 #, c-format -msgid "could not update checksum of block %u in file \"%s\": %m" -msgstr "ファイル\"%2$s\" ブロック%1$uのチェックサム更新失敗: %3$m" +msgid "could not write block %u in file \"%s\": wrote %d of %d" +msgstr "ファイル\"%2$s\"のブロック%1$uの書き込みに失敗しました: %4$dバイト中%3$dバイトのみ書き込みました" -#: pg_checksums.c:251 +#: pg_checksums.c:283 #, c-format msgid "checksums verified in file \"%s\"" msgstr "ファイル\"%s\"のチェックサムは検証されました" -#: pg_checksums.c:253 +#: pg_checksums.c:285 #, c-format msgid "checksums enabled in file \"%s\"" msgstr "ファイル\"%s\"のチェックサムは有効化されました" -#: pg_checksums.c:278 +#: pg_checksums.c:310 #, c-format msgid "could not open directory \"%s\": %m" msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" -#: pg_checksums.c:305 +#: pg_checksums.c:337 pg_checksums.c:416 #, c-format msgid "could not stat file \"%s\": %m" msgstr "ファイル\"%s\"のstatに失敗しました: %m" -#: pg_checksums.c:332 +#: pg_checksums.c:364 #, c-format msgid "invalid segment number %d in file name \"%s\"" msgstr "ファイル名\"%2$s\"の不正なセグメント番号%1$d" -#: pg_checksums.c:420 +#: pg_checksums.c:497 #, c-format msgid "invalid filenode specification, must be numeric: %s" msgstr "不正なファイルノード指定、数値である必要があります: %s" -#: pg_checksums.c:438 pg_checksums.c:454 pg_checksums.c:464 pg_checksums.c:473 +#: pg_checksums.c:515 pg_checksums.c:531 pg_checksums.c:541 pg_checksums.c:550 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "詳細については\"%s --help\"を実行してください。\n" -#: pg_checksums.c:453 +#: pg_checksums.c:530 #, c-format msgid "no data directory specified" msgstr "データディレクトリが指定されていません" -#: pg_checksums.c:462 +#: pg_checksums.c:539 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "コマンドライン引数が多すぎます (最初は\"%s\")" -#: pg_checksums.c:472 +#: pg_checksums.c:549 #, c-format -msgid "--filenode option only possible with --check" -msgstr "--filenodeは--checkを指定したときのみ指定可能" +msgid "option -f/--filenode can only be used with --check" +msgstr "オプション-f/--filenodeは--checkを指定したときのみ指定可能" -#: pg_checksums.c:482 +#: pg_checksums.c:559 #, c-format msgid "pg_control CRC value is incorrect" msgstr "pg_controlのCRC値が正しくありません" -#: pg_checksums.c:488 +#: pg_checksums.c:565 #, c-format msgid "cluster is not compatible with this version of pg_checksums" msgstr "クラスタはこのバージョンのpg_checksumsと互換性がありません" -#: pg_checksums.c:494 +#: pg_checksums.c:571 #, c-format msgid "database cluster is not compatible" msgstr "データベースクラスタが非互換です" -#: pg_checksums.c:495 +#: pg_checksums.c:572 #, c-format -msgid "" -"The database cluster was initialized with block size %u, but pg_checksums " -"was compiled with block size %u.\n" -msgstr "" -"データベースクラスタはブロックサイズ%uで初期化されています、しかし" -"pg_checksumsはブロックサイズ%uでコンパイルされています。\n" +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "データベースクラスタはブロックサイズ%uで初期化されています、しかしpg_checksumsはブロックサイズ%uでコンパイルされています。\n" -#: pg_checksums.c:503 +#: pg_checksums.c:585 #, c-format msgid "cluster must be shut down" msgstr "クラスタはシャットダウンされていなければなりません" -#: pg_checksums.c:510 +#: pg_checksums.c:592 #, c-format msgid "data checksums are not enabled in cluster" msgstr "クラスタのデータチェックサムは有効になっていません" -#: pg_checksums.c:517 +#: pg_checksums.c:599 #, c-format msgid "data checksums are already disabled in cluster" msgstr "クラスタのデータチェックサムはすでに無効になっています" -#: pg_checksums.c:524 +#: pg_checksums.c:606 #, c-format msgid "data checksums are already enabled in cluster" msgstr "クラスタのデータチェックサムはすでに有効になっています" -#: pg_checksums.c:553 +#: pg_checksums.c:632 #, c-format msgid "Checksum operation completed\n" msgstr "チェックサム操作が完了しました\n" -#: pg_checksums.c:554 +#: pg_checksums.c:633 #, c-format msgid "Files scanned: %s\n" msgstr "スキャンしたファイル数: %s\n" -#: pg_checksums.c:555 +#: pg_checksums.c:634 #, c-format msgid "Blocks scanned: %s\n" msgstr "スキャンしたブロック数: %s\n" -#: pg_checksums.c:558 +#: pg_checksums.c:637 #, c-format msgid "Bad checksums: %s\n" msgstr "不正なチェックサム数: %s\n" -#: pg_checksums.c:559 pg_checksums.c:586 +#: pg_checksums.c:638 pg_checksums.c:665 #, c-format msgid "Data checksum version: %d\n" msgstr "データチェックサムバージョン: %d\n" -#: pg_checksums.c:578 +#: pg_checksums.c:657 #, c-format msgid "syncing data directory" msgstr "データディレクトリを同期しています" -#: pg_checksums.c:582 +#: pg_checksums.c:661 #, c-format msgid "updating control file" msgstr "コントロールファイルを更新しています" -#: pg_checksums.c:588 +#: pg_checksums.c:667 #, c-format msgid "Checksums enabled in cluster\n" msgstr "クラスタのチェックサムが有効化されました\n" -#: pg_checksums.c:590 +#: pg_checksums.c:669 #, c-format msgid "Checksums disabled in cluster\n" msgstr "クラスタのチェックサムが無効化されました\n" + +#~ msgid "could not update checksum of block %u in file \"%s\": %m" +#~ msgstr "ファイル\"%2$s\" ブロック%1$uのチェックサム更新失敗: %3$m" + +#~ msgid "Report bugs to .\n" +#~ msgstr "バグは に報告してください。\n" diff --git a/src/bin/pg_checksums/po/ko.po b/src/bin/pg_checksums/po/ko.po index d723be66586d..ff767cfc7df3 100644 --- a/src/bin/pg_checksums/po/ko.po +++ b/src/bin/pg_checksums/po/ko.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_checksums (PostgreSQL) 12\n" +"Project-Id-Version: pg_checksums (PostgreSQL) 13\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2020-02-09 20:17+0000\n" -"PO-Revision-Date: 2020-02-10 10:09+0900\n" +"POT-Creation-Date: 2020-10-05 20:47+0000\n" +"PO-Revision-Date: 2020-10-06 11:13+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: PostgreSQL Korea \n" "Language: ko\n" @@ -16,17 +16,17 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "심각: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "오류: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "경고: " @@ -131,30 +131,35 @@ msgstr "" #: pg_checksums.c:91 #, c-format -msgid "Report bugs to .\n" -msgstr "오류보고: .\n" +msgid "Report bugs to <%s>.\n" +msgstr "문제점 보고 주소: <%s>\n" -#: pg_checksums.c:149 +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: pg_checksums.c:161 #, c-format msgid "%*s/%s MB (%d%%) computed" msgstr "%*s/%s MB (%d%%) 계산됨" -#: pg_checksums.c:186 +#: pg_checksums.c:207 #, c-format msgid "could not open file \"%s\": %m" msgstr "\"%s\" 파일을 열 수 없음: %m" -#: pg_checksums.c:202 +#: pg_checksums.c:223 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "%u 블럭을 \"%s\" 파일에서 읽을 수 없음: %m" -#: pg_checksums.c:205 +#: pg_checksums.c:226 #, c-format msgid "could not read block %u in file \"%s\": read %d of %d" msgstr "%u 블럭을 \"%s\" 파일에서 읽을 수 없음: %d / %d 바이트만 읽음" -#: pg_checksums.c:222 +#: pg_checksums.c:243 #, c-format msgid "" "checksum verification failed in file \"%s\", block %u: calculated checksum " @@ -163,87 +168,87 @@ msgstr "" "\"%s\" 파일, %u 블럭의 체크섬 검사 실패: 계산된 체크섬은 %X 값이지만, 블럭에" "는 %X 값이 있음" -#: pg_checksums.c:237 +#: pg_checksums.c:258 #, c-format msgid "seek failed for block %u in file \"%s\": %m" msgstr "%u 블럭을 \"%s\" 파일에서 찾을 수 없음: %m" -#: pg_checksums.c:246 +#: pg_checksums.c:267 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "%u 블럭을 \"%s\" 파일에 쓸 수 없음: %m" -#: pg_checksums.c:249 +#: pg_checksums.c:270 #, c-format msgid "could not write block %u in file \"%s\": wrote %d of %d" msgstr "%u 블럭을 \"%s\" 파일에 쓸 수 없음: %d / %d 바이트만 씀" -#: pg_checksums.c:262 +#: pg_checksums.c:283 #, c-format msgid "checksums verified in file \"%s\"" msgstr "\"%s\" 파일 체크섬 검사 마침" -#: pg_checksums.c:264 +#: pg_checksums.c:285 #, c-format msgid "checksums enabled in file \"%s\"" msgstr "\"%s\" 파일 체크섬 활성화 함" -#: pg_checksums.c:289 +#: pg_checksums.c:310 #, c-format msgid "could not open directory \"%s\": %m" msgstr "\"%s\" 디렉터리 열 수 없음: %m" -#: pg_checksums.c:316 +#: pg_checksums.c:337 pg_checksums.c:416 #, c-format msgid "could not stat file \"%s\": %m" msgstr "\"%s\" 파일의 상태값을 알 수 없음: %m" -#: pg_checksums.c:343 +#: pg_checksums.c:364 #, c-format msgid "invalid segment number %d in file name \"%s\"" msgstr "잘못된 조각 번호 %d, 해당 파일: \"%s\"" -#: pg_checksums.c:431 +#: pg_checksums.c:497 #, c-format msgid "invalid filenode specification, must be numeric: %s" msgstr "파일노드 값이 이상함. 이 값은 숫자여야 함: %s" -#: pg_checksums.c:449 pg_checksums.c:465 pg_checksums.c:475 pg_checksums.c:484 +#: pg_checksums.c:515 pg_checksums.c:531 pg_checksums.c:541 pg_checksums.c:550 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "자제한 사항은 \"%s --help\" 명령으로 살펴보십시오.\n" -#: pg_checksums.c:464 +#: pg_checksums.c:530 #, c-format msgid "no data directory specified" msgstr "데이터 디렉터리를 지정하지 않았음" -#: pg_checksums.c:473 +#: pg_checksums.c:539 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "너무 많은 명령행 인수를 지정했음 (처음 \"%s\")" -#: pg_checksums.c:483 +#: pg_checksums.c:549 #, c-format msgid "option -f/--filenode can only be used with --check" msgstr "-f/--filenode 옵션은 --check 옵션만 사용할 수 있음" -#: pg_checksums.c:493 +#: pg_checksums.c:559 #, c-format msgid "pg_control CRC value is incorrect" msgstr "pg_control CRC 값이 잘못되었음" -#: pg_checksums.c:499 +#: pg_checksums.c:565 #, c-format msgid "cluster is not compatible with this version of pg_checksums" msgstr "해당 클러스터는 이 버전 pg_checksum과 호환되지 않음" -#: pg_checksums.c:505 +#: pg_checksums.c:571 #, c-format msgid "database cluster is not compatible" msgstr "데이터베이스 클러스터는 호환되지 않음" -#: pg_checksums.c:506 +#: pg_checksums.c:572 #, c-format msgid "" "The database cluster was initialized with block size %u, but pg_checksums " @@ -252,67 +257,67 @@ msgstr "" "이 데이터베이스 클러스터는 %u 블록 크기로 초기화 되었지만, pg_checksum은 %u " "블록 크기로 컴파일 되어있습니다.\n" -#: pg_checksums.c:519 +#: pg_checksums.c:585 #, c-format msgid "cluster must be shut down" msgstr "먼저 서버가 중지되어야 함" -#: pg_checksums.c:526 +#: pg_checksums.c:592 #, c-format msgid "data checksums are not enabled in cluster" msgstr "이 클러스터는 자료 체크섬이 비활성화 상태임" -#: pg_checksums.c:533 +#: pg_checksums.c:599 #, c-format msgid "data checksums are already disabled in cluster" msgstr "이 클러스터는 이미 자료 체크섬이 비활성화 상태임" -#: pg_checksums.c:540 +#: pg_checksums.c:606 #, c-format msgid "data checksums are already enabled in cluster" msgstr "이 클러스터는 이미 자료 체크섬이 활성화 상태임" -#: pg_checksums.c:569 +#: pg_checksums.c:632 #, c-format msgid "Checksum operation completed\n" msgstr "체크섬 작업 완료\n" -#: pg_checksums.c:570 +#: pg_checksums.c:633 #, c-format msgid "Files scanned: %s\n" msgstr "조사한 파일수: %s\n" -#: pg_checksums.c:571 +#: pg_checksums.c:634 #, c-format msgid "Blocks scanned: %s\n" msgstr "조사한 블럭수: %s\n" -#: pg_checksums.c:574 +#: pg_checksums.c:637 #, c-format msgid "Bad checksums: %s\n" msgstr "잘못된 체크섬: %s\n" -#: pg_checksums.c:575 pg_checksums.c:602 +#: pg_checksums.c:638 pg_checksums.c:665 #, c-format msgid "Data checksum version: %d\n" msgstr "자료 체크섬 버전: %d\n" -#: pg_checksums.c:594 +#: pg_checksums.c:657 #, c-format msgid "syncing data directory" msgstr "데이터 디렉터리 fsync 중" -#: pg_checksums.c:598 +#: pg_checksums.c:661 #, c-format msgid "updating control file" msgstr "컨트롤 파일 바꾸는 중" -#: pg_checksums.c:604 +#: pg_checksums.c:667 #, c-format msgid "Checksums enabled in cluster\n" msgstr "이 클러스터는 자료 체크섬 옵션이 활성화 되었음\n" -#: pg_checksums.c:606 +#: pg_checksums.c:669 #, c-format msgid "Checksums disabled in cluster\n" msgstr "이 클러스터는 자료 체크섬 옵션이 비활성화 되었음\n" diff --git a/src/bin/pg_checksums/po/ru.po b/src/bin/pg_checksums/po/ru.po index 2b0db344e0b3..8e48580af06a 100644 --- a/src/bin/pg_checksums/po/ru.po +++ b/src/bin/pg_checksums/po/ru.po @@ -1,10 +1,10 @@ -# Alexander Lakhin , 2019. +# Alexander Lakhin , 2019, 2020, 2021. msgid "" msgstr "" "Project-Id-Version: pg_verify_checksums (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-09 12:21+0300\n" -"PO-Revision-Date: 2019-09-09 13:32+0300\n" +"POT-Creation-Date: 2020-12-11 07:48+0300\n" +"PO-Revision-Date: 2021-02-08 07:59+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -12,17 +12,17 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "важно: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "ошибка: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "предупреждение: " @@ -131,30 +131,35 @@ msgstr "" #: pg_checksums.c:91 #, c-format -msgid "Report bugs to .\n" -msgstr "Об ошибках сообщайте по адресу .\n" +msgid "Report bugs to <%s>.\n" +msgstr "Об ошибках сообщайте по адресу <%s>.\n" -#: pg_checksums.c:149 +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_checksums.c:161 #, c-format msgid "%*s/%s MB (%d%%) computed" msgstr "%*s/%s МБ (%d%%) обработано" -#: pg_checksums.c:186 +#: pg_checksums.c:207 #, c-format msgid "could not open file \"%s\": %m" msgstr "не удалось открыть файл \"%s\": %m" -#: pg_checksums.c:202 +#: pg_checksums.c:223 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "не удалось прочитать блок %u в файле \"%s\": %m" -#: pg_checksums.c:205 +#: pg_checksums.c:226 #, c-format msgid "could not read block %u in file \"%s\": read %d of %d" msgstr "не удалось прочитать блок %u в файле \"%s\" (прочитано байт: %d из %d)" -#: pg_checksums.c:222 +#: pg_checksums.c:243 #, c-format msgid "" "checksum verification failed in file \"%s\", block %u: calculated checksum " @@ -163,87 +168,87 @@ msgstr "" "ошибка контрольных сумм в файле \"%s\", блоке %u: вычислена контрольная " "сумма %X, но блок содержит %X" -#: pg_checksums.c:237 +#: pg_checksums.c:258 #, c-format msgid "seek failed for block %u in file \"%s\": %m" msgstr "ошибка при переходе к блоку %u в файле \"%s\": %m" -#: pg_checksums.c:246 +#: pg_checksums.c:267 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "не удалось записать блок %u в файл \"%s\": %m" -#: pg_checksums.c:249 +#: pg_checksums.c:270 #, c-format msgid "could not write block %u in file \"%s\": wrote %d of %d" msgstr "не удалось записать блок %u в файле \"%s\" (записано байт: %d из %d)" -#: pg_checksums.c:262 +#: pg_checksums.c:283 #, c-format msgid "checksums verified in file \"%s\"" msgstr "контрольные суммы в файле \"%s\" проверены" -#: pg_checksums.c:264 +#: pg_checksums.c:285 #, c-format msgid "checksums enabled in file \"%s\"" msgstr "контрольные суммы в файле \"%s\" включены" -#: pg_checksums.c:289 +#: pg_checksums.c:310 #, c-format msgid "could not open directory \"%s\": %m" msgstr "не удалось открыть каталог \"%s\": %m" -#: pg_checksums.c:316 +#: pg_checksums.c:337 pg_checksums.c:416 #, c-format msgid "could not stat file \"%s\": %m" msgstr "не удалось получить информацию о файле \"%s\": %m" -#: pg_checksums.c:343 +#: pg_checksums.c:364 #, c-format msgid "invalid segment number %d in file name \"%s\"" msgstr "неверный номер сегмента %d в имени файла \"%s\"" -#: pg_checksums.c:431 +#: pg_checksums.c:497 #, c-format msgid "invalid filenode specification, must be numeric: %s" msgstr "неверное указание файлового узла, требуется число: %s" -#: pg_checksums.c:449 pg_checksums.c:465 pg_checksums.c:475 pg_checksums.c:484 +#: pg_checksums.c:515 pg_checksums.c:531 pg_checksums.c:541 pg_checksums.c:550 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" -#: pg_checksums.c:464 +#: pg_checksums.c:530 #, c-format msgid "no data directory specified" msgstr "каталог данных не указан" -#: pg_checksums.c:473 +#: pg_checksums.c:539 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "слишком много аргументов командной строки (первый: \"%s\")" -#: pg_checksums.c:483 +#: pg_checksums.c:549 #, c-format msgid "option -f/--filenode can only be used with --check" msgstr "параметр -f/--filenode можно использовать только с --check" -#: pg_checksums.c:493 +#: pg_checksums.c:559 #, c-format msgid "pg_control CRC value is incorrect" msgstr "ошибка контрольного значения в pg_control" -#: pg_checksums.c:499 +#: pg_checksums.c:565 #, c-format msgid "cluster is not compatible with this version of pg_checksums" msgstr "кластер несовместим с этой версией pg_checksums" -#: pg_checksums.c:505 +#: pg_checksums.c:571 #, c-format msgid "database cluster is not compatible" msgstr "несовместимый кластер баз данных" -#: pg_checksums.c:506 +#: pg_checksums.c:572 #, c-format msgid "" "The database cluster was initialized with block size %u, but pg_checksums " @@ -252,67 +257,70 @@ msgstr "" "Кластер баз данных был инициализирован с размером блока %u, а утилита " "pg_checksums скомпилирована для размера блока %u.\n" -#: pg_checksums.c:519 +#: pg_checksums.c:585 #, c-format msgid "cluster must be shut down" msgstr "кластер должен быть отключён" -#: pg_checksums.c:526 +#: pg_checksums.c:592 #, c-format msgid "data checksums are not enabled in cluster" msgstr "контрольные суммы в кластере не включены" -#: pg_checksums.c:533 +#: pg_checksums.c:599 #, c-format msgid "data checksums are already disabled in cluster" msgstr "контрольные суммы в кластере уже отключены" -#: pg_checksums.c:540 +#: pg_checksums.c:606 #, c-format msgid "data checksums are already enabled in cluster" msgstr "контрольные суммы в кластере уже включены" -#: pg_checksums.c:569 +#: pg_checksums.c:632 #, c-format msgid "Checksum operation completed\n" msgstr "Обработка контрольных сумм завершена\n" -#: pg_checksums.c:570 +#: pg_checksums.c:633 #, c-format msgid "Files scanned: %s\n" msgstr "Просканировано файлов: %s\n" -#: pg_checksums.c:571 +#: pg_checksums.c:634 #, c-format msgid "Blocks scanned: %s\n" msgstr "Просканировано блоков: %s\n" -#: pg_checksums.c:574 +#: pg_checksums.c:637 #, c-format msgid "Bad checksums: %s\n" msgstr "Неверные контрольные суммы: %s\n" -#: pg_checksums.c:575 pg_checksums.c:602 +#: pg_checksums.c:638 pg_checksums.c:665 #, c-format -msgid "Data checksum version: %d\n" -msgstr "Версия контрольных сумм данных: %d\n" +msgid "Data checksum version: %u\n" +msgstr "Версия контрольных сумм данных: %u\n" -#: pg_checksums.c:594 +#: pg_checksums.c:657 #, c-format msgid "syncing data directory" msgstr "синхронизация каталога данных" -#: pg_checksums.c:598 +#: pg_checksums.c:661 #, c-format msgid "updating control file" msgstr "модификация управляющего файла" -#: pg_checksums.c:604 +#: pg_checksums.c:667 #, c-format msgid "Checksums enabled in cluster\n" msgstr "Контрольные суммы в кластере включены\n" -#: pg_checksums.c:606 +#: pg_checksums.c:669 #, c-format msgid "Checksums disabled in cluster\n" msgstr "Контрольные суммы в кластере отключены\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Об ошибках сообщайте по адресу .\n" diff --git a/src/bin/pg_checksums/po/uk.po b/src/bin/pg_checksums/po/uk.po new file mode 100644 index 000000000000..15bfe6a47c79 --- /dev/null +++ b/src/bin/pg_checksums/po/uk.po @@ -0,0 +1,299 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:18+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: pasha_golub\n" +"Language-Team: Ukrainian\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_checksums.pot\n" +"X-Crowdin-File-ID: 492\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: pg_checksums.c:75 +#, c-format +msgid "%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n\n" +msgstr "%s активує, деактивує або перевіряє контрольні суми даних в кластері бази даних PostgreSQL.\n\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "Використання:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPTION]... [DATADIR]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "\n" +"Options:\n" +msgstr "\n" +"Параметри:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR каталог даних\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, --check перевірити контрольні суми даних (за замовчуванням)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, --disable вимкнути контрольні суми даних\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, --enable активувати контрольні суми даних\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILENODE перевіряти відношення лише із вказаним файлом\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync не чекати на безпечний запис змін на диск\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress показати інформацію про прогрес\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose виводити детальні повідомлення\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію, потім вийти\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати цю довідку, потім вийти\n" + +#: pg_checksums.c:89 +#, c-format +msgid "\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n\n" +msgstr "\n" +"Якщо каталог даних не вказано (DATADIR), використовується змінна середовища PGDATA.\n\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Повідомляти про помилки на <%s>.\n" + +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: pg_checksums.c:161 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "%*s/%s MB (%d%%) обчислено" + +#: pg_checksums.c:207 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" + +#: pg_checksums.c:223 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "не вдалося прочитати блок %u в файлі \"%s\": %m" + +#: pg_checksums.c:226 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "не вдалося прочитати блок %u у файлі \"%s\": прочитано %d з %d" + +#: pg_checksums.c:243 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "помилка перевірки контрольних сум у файлі \"%s\", блок %u: обчислена контрольна сума %X, але блок містить %X" + +#: pg_checksums.c:258 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "помилка пошуку для блоку %u у файлі \"%s\": %m" + +#: pg_checksums.c:267 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "не вдалося записати блок %u у файл \"%s\": %m" + +#: pg_checksums.c:270 +#, c-format +msgid "could not write block %u in file \"%s\": wrote %d of %d" +msgstr "не вдалося записати блок %u у файлі \"%s\": записано %d з %d" + +#: pg_checksums.c:283 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "контрольні суми у файлі \"%s\" перевірені" + +#: pg_checksums.c:285 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "контрольні суми у файлі \"%s\" активовані" + +#: pg_checksums.c:310 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не вдалося відкрити каталог \"%s\": %m" + +#: pg_checksums.c:337 pg_checksums.c:416 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не вдалося отримати інформацію від файлу \"%s\": %m" + +#: pg_checksums.c:364 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "неприпустимий номер сегменту %d в імені файлу \"%s\"" + +#: pg_checksums.c:497 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "неприпустима специфікація filenode, повинна бути числовою: %s" + +#: pg_checksums.c:515 pg_checksums.c:531 pg_checksums.c:541 pg_checksums.c:550 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: pg_checksums.c:530 +#, c-format +msgid "no data directory specified" +msgstr "каталог даних не вказано" + +#: pg_checksums.c:539 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" + +#: pg_checksums.c:549 +#, c-format +msgid "option -f/--filenode can only be used with --check" +msgstr "параметр -f/--filenode може бути використаний тільки з --check" + +#: pg_checksums.c:559 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "значення CRC pg_control неправильне" + +#: pg_checksums.c:565 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "кластер не сумісний з цією версією pg_checksum" + +#: pg_checksums.c:571 +#, c-format +msgid "database cluster is not compatible" +msgstr "кластер бази даних не сумісний" + +#: pg_checksums.c:572 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "Кластер бази даних було ініціалізовано з розміром блоку %u, але pg_checksums було скомпільовано з розміром блоку %u.\n" + +#: pg_checksums.c:585 +#, c-format +msgid "cluster must be shut down" +msgstr "кластер повинен бути закритий" + +#: pg_checksums.c:592 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "контрольні суми в кластері неактивовані" + +#: pg_checksums.c:599 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "контрольні суми вже неактивовані в кластері" + +#: pg_checksums.c:606 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "контрольні суми вже активовані в кластері" + +#: pg_checksums.c:632 +#, c-format +msgid "Checksum operation completed\n" +msgstr "Операція контрольної суми завершена\n" + +#: pg_checksums.c:633 +#, c-format +msgid "Files scanned: %s\n" +msgstr "Файлів відскановано: %s\n" + +#: pg_checksums.c:634 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "Блоків відскановано: %s\n" + +#: pg_checksums.c:637 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "Неправильні контрольні суми: %s\n" + +#: pg_checksums.c:638 pg_checksums.c:665 +#, c-format +msgid "Data checksum version: %d\n" +msgstr "Версія контрольних сум даних: %d\n" + +#: pg_checksums.c:657 +#, c-format +msgid "syncing data directory" +msgstr "синхронізація даних каталогу" + +#: pg_checksums.c:661 +#, c-format +msgid "updating control file" +msgstr "оновлення контрольного файлу" + +#: pg_checksums.c:667 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "Контрольні суми активовані в кластері\n" + +#: pg_checksums.c:669 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "Контрольні суми вимкнені у кластері\n" + diff --git a/src/bin/pg_checksums/po/zh_CN.po b/src/bin/pg_checksums/po/zh_CN.po new file mode 100644 index 000000000000..012872b87aad --- /dev/null +++ b/src/bin/pg_checksums/po/zh_CN.po @@ -0,0 +1,308 @@ +# LANGUAGE message translation file for pg_checksums +# Copyright (C) 2020 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_checksums (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-06-05 01:47+0000\n" +"PO-Revision-Date: 2020-06-21 16:00+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "致命的: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "错误: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: pg_checksums.c:75 +#, c-format +msgid "" +"%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s启用、禁用或验证PostgreSQL数据库群集中的数据校验和.\n" +"\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [选项]... [DATADIR]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"选项:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR 数据目录\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, --check 检查数据校验和(默认)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, --disable 禁用数据校验和\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, --enable 启用数据校验和\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILENODE 仅检查与指定filenode的关系\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync 不用等待变化安全写入磁盘\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress 显示进度信息\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose 输出详细的消息\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 输出版本信息, 然后退出\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 显示此帮助, 然后退出\n" + +#: pg_checksums.c:89 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"如果没有指定数据目录(DATADIR), 将使用\n" +"环境变量PGDATA.\n" +"\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "臭虫报告至 <%s>.\n" + +#: pg_checksums.c:92 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 主页: <%s>\n" + +#: pg_checksums.c:161 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "已计算%*s/%s MB (%d%%)" + +#: pg_checksums.c:204 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "无法打开文件 \"%s\": %m" + +#: pg_checksums.c:220 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "无法在文件\"%2$s\"中读取块%1$u: %3$m" + +#: pg_checksums.c:223 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "无法读取文件\"%2$s\"中的块%1$u:读取第%3$d个,共%4$d个" + +#: pg_checksums.c:240 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "校验和验证在文件\"%s\"中失败,块%u:计算的校验和 %X ,但块包含 %X" + +#: pg_checksums.c:255 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "在文件\"%2$s\"中查找块%1$u失败: %3$m" + +#: pg_checksums.c:264 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "无法在文件 \"%2$s\"中写入块%1$u: %3$m" + +#: pg_checksums.c:267 +#, c-format +msgid "could not write block %u in file \"%s\": wrote %d of %d" +msgstr "无法对文件\"%2$s\"写操作数据块%1$u: 已写入%3$d个,共%4$d个" + +#: pg_checksums.c:280 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "在文件\"%s\"中验证的校验和" + +#: pg_checksums.c:282 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "文件\"%s\"中启用的校验和" + +#: pg_checksums.c:307 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "无法打开目录 \"%s\": %m" + +#: pg_checksums.c:334 pg_checksums.c:413 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "无法取文件 \"%s\" 的状态: %m" + +#: pg_checksums.c:361 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "文件名\"%2$s\"中的无效段号%1$d" + +#: pg_checksums.c:494 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "filenode指定无效,必须是数字: %s" + +#: pg_checksums.c:512 pg_checksums.c:528 pg_checksums.c:538 pg_checksums.c:547 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "请用 \"%s --help\" 获取更多的信息.\n" + +#: pg_checksums.c:527 +#, c-format +msgid "no data directory specified" +msgstr "未指定数据目录" + +#: pg_checksums.c:536 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "命令行参数太多(第一个是\"%s\")" + +#: pg_checksums.c:546 +#, c-format +msgid "option -f/--filenode can only be used with --check" +msgstr " -f/--filenode选项只能与--check一起使用" + +#: pg_checksums.c:556 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "pg_control的CRC值不正确 " + +#: pg_checksums.c:562 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "群集与此版本的pg_checksums不兼容”" + +#: pg_checksums.c:568 +#, c-format +msgid "database cluster is not compatible" +msgstr "数据库群集不兼容" + +#: pg_checksums.c:569 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "数据库群集是用块大小%u初始化的,但pg_checksums是用块大小%u编译的.\n" + +#: pg_checksums.c:582 +#, c-format +msgid "cluster must be shut down" +msgstr "必须关闭群集" + +#: pg_checksums.c:589 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "群集中未启用数据校验和" + +#: pg_checksums.c:596 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "群集中已禁用数据校验和" + +#: pg_checksums.c:603 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "群集中已启用数据校验和" + +#: pg_checksums.c:632 +#, c-format +msgid "Checksum operation completed\n" +msgstr "校验和操作已完成\n" + +#: pg_checksums.c:633 +#, c-format +msgid "Files scanned: %s\n" +msgstr "扫描的文件: %s\n" + +#: pg_checksums.c:634 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "扫描的块: %s\n" + +#: pg_checksums.c:637 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "坏校验和: %s\n" + +#: pg_checksums.c:638 pg_checksums.c:665 +#, c-format +msgid "Data checksum version: %d\n" +msgstr "数据校验和版本: %d\n" + +#: pg_checksums.c:657 +#, c-format +msgid "syncing data directory" +msgstr "同步数据目录" + +#: pg_checksums.c:661 +#, c-format +msgid "updating control file" +msgstr "正在更新控制文件" + +#: pg_checksums.c:667 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "群集中启用的校验和\n" + +#: pg_checksums.c:669 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "在群集中禁用校验和\n" \ No newline at end of file diff --git a/src/bin/pg_checksums/t/001_basic.pl b/src/bin/pg_checksums/t/001_basic.pl index 4334c8060616..62e78a50438f 100644 --- a/src/bin/pg_checksums/t/001_basic.pl +++ b/src/bin/pg_checksums/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pg_checksums/t/002_actions.pl b/src/bin/pg_checksums/t/002_actions.pl index 4e4934532a30..af88b9479539 100644 --- a/src/bin/pg_checksums/t/002_actions.pl +++ b/src/bin/pg_checksums/t/002_actions.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Do basic sanity checks supported by pg_checksums using # an initialized cluster. @@ -5,6 +8,8 @@ use warnings; use PostgresNode; use TestLib; + +use Fcntl qw(:seek); use Test::More tests => 63; @@ -21,7 +26,7 @@ sub check_relation_corruption $node->safe_psql( 'postgres', - "SELECT a INTO $table FROM generate_series(1,10000) AS a; + "CREATE TABLE $table AS SELECT a FROM generate_series(1,10000) AS a; ALTER TABLE $table SET (autovacuum_enabled=false);"); $node->safe_psql('postgres', @@ -50,7 +55,7 @@ sub check_relation_corruption # Time to create some corruption open my $file, '+<', "$pgdata/$file_corrupted"; - seek($file, $pageheader_size, 0); + seek($file, $pageheader_size, SEEK_SET); syswrite($file, "\0\0\0\0\0\0\0\0\0"); close $file; diff --git a/src/bin/pg_config/Makefile b/src/bin/pg_config/Makefile index d3b5f1fa7591..fa60d602460b 100644 --- a/src/bin/pg_config/Makefile +++ b/src/bin/pg_config/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_config # -# Copyright (c) 1998-2020, PostgreSQL Global Development Group +# Copyright (c) 1998-2021, PostgreSQL Global Development Group # # src/bin/pg_config/Makefile # diff --git a/src/bin/pg_config/nls.mk b/src/bin/pg_config/nls.mk index ab032ee26ce3..77680fa23c0c 100644 --- a/src/bin/pg_config/nls.mk +++ b/src/bin/pg_config/nls.mk @@ -1,4 +1,4 @@ # src/bin/pg_config/nls.mk CATALOG_NAME = pg_config -AVAIL_LANGUAGES = cs de es fr he it ja ko nb pl pt_BR ro ru sv ta tr uk vi zh_CN zh_TW +AVAIL_LANGUAGES = cs de el es fr he it ja ko nb pl pt_BR ro ru sv ta tr uk vi zh_CN zh_TW GETTEXT_FILES = pg_config.c ../../common/config_info.c ../../common/exec.c diff --git a/src/bin/pg_config/pg_config.c b/src/bin/pg_config/pg_config.c index 5e78db83c1a3..6e7bf90447d0 100644 --- a/src/bin/pg_config/pg_config.c +++ b/src/bin/pg_config/pg_config.c @@ -15,7 +15,7 @@ * * This code is released under the terms of the PostgreSQL License. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * src/bin/pg_config/pg_config.c * diff --git a/src/bin/pg_config/po/cs.po b/src/bin/pg_config/po/cs.po new file mode 100644 index 000000000000..9a616830cb10 --- /dev/null +++ b/src/bin/pg_config/po/cs.po @@ -0,0 +1,280 @@ +# Czech message translation file for pg_config +# Copyright (C) 2012 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Tomas Vondra , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: pg_config-cs (PostgreSQL 9.3)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:14+0000\n" +"PO-Revision-Date: 2020-10-31 21:30+0100\n" +"Last-Translator: Tomas Vondra \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.4.1\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "nezaznamenáno" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "nelze získat aktuální adresář: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "neplatný binární soubor\"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "nelze číst binární soubor \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "nelze najít soubor \"%s\" ke spuštění" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "nelze změnit adresář na \"%s\" : %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "nelze přečíst symbolický odkaz \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "volání pclose selhalo: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "nedostatek paměti" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s poskytuje informace o nainstalované verzi PostgreSQL.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [PŘEPÍNAČ]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "Přepínače:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr " --bindir ukáže umístění spustitelných souborů\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir ukáže umístění souborů s dokumentací\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr " --htmldir ukáže umístění souborl s HTML dokumentací\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" --includedir ukáže umístění C hlavičkových souborů klientských\n" +" rozhraní\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr " --pkgincludedir ukáže umístění dalších C hlavičkových souborů\n" + +#: pg_config.c:84 +#, c-format +msgid " --includedir-server show location of C header files for the server\n" +msgstr " --includedir-server ukáže umístění C hlavičkových souborů pro server\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr " --libdir ukáže umístění knihoven\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr " --pkglibdir ukáže umístění dynamicky zaváděných modulů\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr " --localedir ukáže umístění souborů pro podporu locale\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir ukáže umístění souborů s manuálovými stránkami\n" + +#: pg_config.c:89 +#, c-format +msgid " --sharedir show location of architecture-independent support files\n" +msgstr " --sharedir ukáže umístění podpůrných souborů nezávislých na architektuře\n" + +#: pg_config.c:90 +#, c-format +msgid " --sysconfdir show location of system-wide configuration files\n" +msgstr " --sysconfdir ukáže umístění konfiguračních souborů platných pro celý systém\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr " --pgxs ukáže umístění makefile souboru pro rozšíření\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure ukáže přepínače použité pro \"configure\" skript ke\n" +" kompilaci PostgreSQL\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr " --cc ukáže hodnotu CC použitou při buildu PostgreSQL\n" + +#: pg_config.c:95 +#, c-format +msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr " --cppflags ukáže hodnotu CPPFLAGS použitou při buildu PostgreSQL\n" + +#: pg_config.c:96 +#, c-format +msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr " --cflags ukáže hodnotu CFLAGS použitou při buildu PostgreSQL\n" + +#: pg_config.c:97 +#, c-format +msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr " --cflags_sl ukáže hodnotu CFLAGS_SL použitou při buildu PostgreSQL\n" + +#: pg_config.c:98 +#, c-format +msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr " --ldflags ukáže hodnotu LDFLAGS použitou při buildu PostgreSQL\n" + +#: pg_config.c:99 +#, c-format +msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" +msgstr " --ldflags_ex ukáže hodnotu LDFLAGS_EX použitou při buildu PostgreSQL\n" + +#: pg_config.c:100 +#, c-format +msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" +msgstr " --ldflags_sl ukáže hodnotu LDFLAGS_SL použitou při buildu PostgreSQL\n" + +#: pg_config.c:101 +#, c-format +msgid " --libs show LIBS value used when PostgreSQL was built\n" +msgstr " --libs ukáže hodnotu LIBS použitou při buildu PostgreSQL\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version ukáže verzi PostgreSQL\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ukáže tuto nápovědu, a skončí\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"Bez argumentů jsou vypsány všechny známé položky.\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Chyby hlašte na <%s>.\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: nelze najít vlastní spustitelný soubor\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: neplatný parametr: %s\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "nelze číst symbolický link \"%s\"" + +#~ msgid "child process exited with exit code %d" +#~ msgstr "potomek skončil s návratovým kódem %d" + +#~ msgid "child process was terminated by exception 0x%X" +#~ msgstr "potomek byl ukončen vyjímkou 0x%X" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "potomek byl ukončen signálem %s" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "potomek byl ukončen signálem %d" + +#~ msgid "child process exited with unrecognized status %d" +#~ msgstr "potomek skončil s nerozponaným stavem %d" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Oznámení o chybách zasílejte na .\n" diff --git a/src/bin/pg_config/po/de.po b/src/bin/pg_config/po/de.po new file mode 100644 index 000000000000..93c9088186ee --- /dev/null +++ b/src/bin/pg_config/po/de.po @@ -0,0 +1,265 @@ +# German message translation file for pg_config +# Peter Eisentraut , 2004 - 2021. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-29 03:16+0000\n" +"PO-Revision-Date: 2021-04-29 06:58+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "nicht aufgezeichnet" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ungültige Programmdatei »%s«" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "konnte Programmdatei »%s« nicht lesen" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "konnte kein »%s« zum Ausführen finden" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() fehlgeschlagen: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s gibt Informationen über die installierte Version von PostgreSQL.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [OPTION]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "Optionen:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr " --bindir zeige Installationsverzeichnis der Benutzerprogramme\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir zeige Installationsverzeichnis der Dokumentation\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr " --htmldir zeige Installationsverzeichnis der HTML-Dokumentation\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" --includedir zeige Installationsverzeichnis der Headerdateien der\n" +" Client-Schnittstellen\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr " --pkgincludedir zeige Installationsverzeichnis von weiteren Headerdateien\n" + +#: pg_config.c:84 +#, c-format +msgid " --includedir-server show location of C header files for the server\n" +msgstr "" +" --includedir-server zeige Installationsverzeichnis der Headerdateien des\n" +" Servers\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr " --libdir zeige Installationsverzeichnis der Objektbibliotheken\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr "" +" --pkglibdir zeige Installationsverzeichnis der dynamisch\n" +" ladbaren Module\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr " --localedir zeige Installationsverzeichnis der Locale-Dateien\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir zeige Installationsverzeichnis der Manpages\n" + +#: pg_config.c:89 +#, c-format +msgid " --sharedir show location of architecture-independent support files\n" +msgstr "" +" --sharedir zeige Installationsverzeichnis der architektur-\n" +" unabhängigen Datendateien\n" + +#: pg_config.c:90 +#, c-format +msgid " --sysconfdir show location of system-wide configuration files\n" +msgstr "" +" --sysconfdir zeige Installationsverzeichnis der systemweiten\n" +" Konfigurationsdateien\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr " --pgxs zeige Ort der Erweiterungs-Makefile\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure zeige Optionen des »configure«-Skriptes beim Bauen\n" +" von PostgreSQL\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr " --cc zeige CC-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:95 +#, c-format +msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr " --cppflags zeige CPPFLAGS-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:96 +#, c-format +msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr " --cflags zeige CFLAGS-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:97 +#, c-format +msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr " --cflags_sl zeige CFLAGS_SL-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:98 +#, c-format +msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr " --ldflags zeige LDFLAGS-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:99 +#, c-format +msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" +msgstr " --ldflags_ex zeige LDFLAGS_EX-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:100 +#, c-format +msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" +msgstr " --ldflags_sl zeige LDFLAGS_SL-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:101 +#, c-format +msgid " --libs show LIBS value used when PostgreSQL was built\n" +msgstr " --libs zeige LIBS-Wert, mit dem PostgreSQL gebaut wurde\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version zeige PostgreSQL-Version\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"Ohne Argumente werden alle bekannten Informationen angezeigt.\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Berichten Sie Fehler an <%s>.\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: konnte eigene Programmdatei nicht finden\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: ungültiges Argument: %s\n" diff --git a/src/bin/pg_config/po/el.po b/src/bin/pg_config/po/el.po new file mode 100644 index 000000000000..d17d2b999b77 --- /dev/null +++ b/src/bin/pg_config/po/el.po @@ -0,0 +1,260 @@ +# Greek message translation file for pg_config +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_config (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_config (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:46+0000\n" +"PO-Revision-Date: 2021-05-04 14:33+0200\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "δεν έχει καταγραφεί" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "δεν ήταν δυνατή η αναγνώριση του τρέχοντος καταλόγου: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "μη έγκυρο δυαδικό αρχείο “%s”" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "δεν ήταν δυνατή η ανάγνωση του δυαδικού αρχείου “%s”" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "δεν βρέθηκε το αρχείο “%s” για να εκτελεστεί" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "δεν ήταν δυνατή η μετάβαση στον κατάλογο “%s”: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του συμβολικού συνδέσμου “%s”: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s () απέτυχε: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "έλλειψη μνήμης" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s παρέχει πληροφορίες σχετικά με την εγκατεστημένη έκδοση της PostgreSQL.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [ΕΠΙΛΟΓΗ]…\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "Επιλογές:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr " —bindir εμφάνισε τη τοποθεσία των εκτελέσιμων αρχείων του χρήστη\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " —docdir εμφάνισε τη τοποθεσία των αρχείων τεκμηρίωσης\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr " —htmldir εμφάνισε τη τοποθεσία των αρχείων τεκμηρίωσης HTML\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" —includedir εμφάνισε τη τοποθεσία των αρχείων κεφαλίδας C\n" +" των διεπαφών πελάτη\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr " —pkgincludedir εμφάνισε τη τοποθεσία άλλων αρχείων κεφαλίδας C\n" + +#: pg_config.c:84 +#, c-format +msgid " --includedir-server show location of C header files for the server\n" +msgstr " —includedir-server εμφάνισε τη τοποθεσία των αρχείων κεφαλίδας C για τον διακομιστή\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr " —libdir εμφάνισε τη τοποθεσία των βιβλιοθηκών κώδικα αντικειμένων\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr " —pkglibdir εμφάνισε τη τοποθεσία των δυναμικά φορτώσιμων ενοτήτων\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr " —localedir εμφάνισε τη τοποθεσία των αρχείων υποστήριξης εντοπιότητας\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " —mandir εμφάνισε τη τοποθεσία των σελίδων τεκμηρίωσης\n" + +#: pg_config.c:89 +#, c-format +msgid " --sharedir show location of architecture-independent support files\n" +msgstr " —sharedir εμφάνισε τη τοποθεσία των ανεξάρτητων από την αρχιτεκτονική αρχείων υποστήριξης\n" + +#: pg_config.c:90 +#, c-format +msgid " --sysconfdir show location of system-wide configuration files\n" +msgstr " —sysconfdir εμφάνισε την τοποθεσία των αρχείων ρύθμισης παραμέτρων όλου του συστήματος\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr " —pgxs εμφάνισε τη τοποθεσία του makefile επέκτασης\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" —configure εμφάνισε τις παραμέτρους που δόθηκαν ώστε να “ρυθμιστεί” το σενάριο\n" +" κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr " —cc εμφάνισε την τιμή CC που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:95 +#, c-format +msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr " —cppflags εμφάνισε την τιμή CPPFLAGS που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:96 +#, c-format +msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr "" +" —cflags εμφάνισε την τιμή CFLAGS που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" +"\n" + +#: pg_config.c:97 +#, c-format +msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr " —cflags_sl εμφάνισε την τιμή CFLAGS_SL που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:98 +#, c-format +msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr " —ldflags εμφάνισε την τιμή LDFLAGS που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:99 +#, c-format +msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" +msgstr " —ldflags_ex εμφάνισε την τιμή LDFLAGS_EX που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:100 +#, c-format +msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" +msgstr " —ldflags_sl εμφάνισε την τιμή LDFLAGS_SL που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:101 +#, c-format +msgid " --libs show LIBS value used when PostgreSQL was built\n" +msgstr " —libs εμφάνισε την τιμή LIBS που χρησιμοποιήθηκε κατά την κατασκευή της PostgreSQL\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " —version εμφάνισε την έκδοση PostgreSQL\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, στη συνέχεια έξοδος\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"Χωρίς παραμέτρους, εμφανίζονται όλα τα γνωστά στοιχεία.\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: δεν ήταν δυνατή η εύρεση του ιδίου εκτελέσιμου προγράμματος\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: μη έγκυρη παράμετρος: %s\n" diff --git a/src/bin/pg_config/po/es.po b/src/bin/pg_config/po/es.po new file mode 100644 index 000000000000..d5aa1cf07d34 --- /dev/null +++ b/src/bin/pg_config/po/es.po @@ -0,0 +1,292 @@ +# pg_config spanish translation +# +# Copyright (c) 2004-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Alvaro Herrera , 2004-2013 +# Carlos Chapi , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_config (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:46+0000\n" +"PO-Revision-Date: 2021-05-20 23:11-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "no registrado" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "el binario «%s» no es válido" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "no se pudo leer el binario «%s»" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "no se pudo encontrar un «%s» para ejecutar" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() falló: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "memoria agotada" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s provee información sobre la versión instalada de PostgreSQL.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [OPCIÓN]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "Opciones:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr " --bindir muestra la ubicación de ejecutables de usuario\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir muestra la ubicación de archivos de documentación\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr " --htmldir muestra la ubicación de archivos de documentación HTML\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" --includedir muestra la ubicación de archivos de encabezados C\n" +" de las interfaces cliente\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr "" +" --pkgincludedir muestra la ubicación de otros archivos de\n" +" encabezados C\n" + +#: pg_config.c:84 +#, c-format +msgid " --includedir-server show location of C header files for the server\n" +msgstr "" +" --includedir-server muestra la ubicación de archivos de encabezados C\n" +" del servidor\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr "" +" --libdir muestra la ubicación de bibliotecas\n" +" de código objeto\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr " --pkglibdir muestra la ubicación de módulos para carga dinámica\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr "" +" --localedir muestra la ubicación de archivos de soporte de\n" +" configuraciones locales\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir muestra la ubicación de páginas de manual\n" + +#: pg_config.c:89 +#, c-format +msgid " --sharedir show location of architecture-independent support files\n" +msgstr "" +" --sharedir muestra la ubicación de archivos de soporte\n" +" independientes de arquitectura\n" + +#: pg_config.c:90 +#, c-format +msgid " --sysconfdir show location of system-wide configuration files\n" +msgstr "" +" --sysconfdir muestra la ubicación de archivos de configuración\n" +" global del sistema\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr "" +" --pgxs muestra la ubicación del archivo makefile\n" +" para extensiones\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure muestra las opciones que se dieron a «configure»\n" +" cuando PostgreSQL fue construido\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr " --cc muestra el valor de CC cuando PostgreSQL fue construido\n" + +#: pg_config.c:95 +#, c-format +msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cppflags muestra el valor de CPPFLAGS cuando PostgreSQL fue\n" +" construido\n" + +#: pg_config.c:96 +#, c-format +msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cflags muestra el valor de CFLAGS cuando PostgreSQL fue\n" +" construido\n" + +#: pg_config.c:97 +#, c-format +msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr "" +" --cflags_sl muestra el valor de CFLAGS_SL cuando PostgreSQL fue\n" +" construido\n" + +#: pg_config.c:98 +#, c-format +msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --ldflags muestra el valor de LDFLAGS cuando PostgreSQL fue\n" +" construido\n" + +#: pg_config.c:99 +#, c-format +msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" +msgstr "" +" --ldflags_ex muestra el valor de LDFLAGS_EX cuando PostgreSQL fue\n" +" construido\n" + +#: pg_config.c:100 +#, c-format +msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" +msgstr "" +" --ldflags_sl muestra el valor de LDFLAGS_SL cuando PostgreSQL fue\n" +" construido\n" + +#: pg_config.c:101 +#, c-format +msgid " --libs show LIBS value used when PostgreSQL was built\n" +msgstr "" +" --libs muestra el valor de LIBS cuando PostgreSQL fue\n" +" construido\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version muestra la versión de PostgreSQL\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help muestra esta ayuda, luego sale\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"Si no se pasa ningún argumento, se muestra toda la información conocida\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Reporte errores a <%s>.\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Use «%s --help» para mayor información.\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: no se pudo encontrar el ejecutable propio\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: el argumento no es válido: %s\n" + +#~ msgid "pclose failed: %m" +#~ msgstr "pclose falló: %m" diff --git a/src/bin/pg_config/po/fr.po b/src/bin/pg_config/po/fr.po new file mode 100644 index 000000000000..aa7b5e0806a3 --- /dev/null +++ b/src/bin/pg_config/po/fr.po @@ -0,0 +1,323 @@ +# translation of pg_config.po to fr_fr +# french message translation file for pg_config +# +# Use these quotes: « %s » +# +# Guillaume Lelarge , 2004-2009. +# Stéphane Schildknecht , 2009. +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-26 06:46+0000\n" +"PO-Revision-Date: 2021-04-26 11:37+0200\n" +"Last-Translator: Guillaume Lelarge \n" +"Language-Team: PostgreSQLfr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "non enregistré" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "binaire « %s » invalide" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "n'a pas pu lire le binaire « %s »" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "n'a pas pu trouver un « %s » à exécuter" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "échec de %s() : %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "mémoire épuisée" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s fournit des informations sur la version installée de PostgreSQL.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [OPTION]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "Options :\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr " --bindir affiche l'emplacement des exécutables utilisateur\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir affiche l'emplacement des fichiers de documentation\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr "" +" --htmldir affiche l'emplacement des fichiers de documentation\n" +" HTML\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" --includedir affiche l'emplacement des fichiers d'en-tête C\n" +" des interfaces client\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr "" +" --pkgincludedir affiche l'emplacement des autres fichiers d'en-tête\n" +" C\n" + +#: pg_config.c:84 +#, c-format +msgid " --includedir-server show location of C header files for the server\n" +msgstr "" +" --includedir-server affiche l'emplacement des fichiers d'en-tête C du\n" +" serveur\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr " --libdir affiche l'emplacement des bibliothèques\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr "" +" --pkglibdir affiche l'emplacement des modules chargeables\n" +" dynamiquement\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr "" +" --localedir affiche l'emplacement des fichiers de support de la\n" +" locale\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir affiche l'emplacement des pages man\n" + +#: pg_config.c:89 +#, c-format +msgid " --sharedir show location of architecture-independent support files\n" +msgstr "" +" --sharedir affiche l'emplacement des fichiers de support\n" +" indépendants de l'architecture\n" + +#: pg_config.c:90 +#, c-format +msgid " --sysconfdir show location of system-wide configuration files\n" +msgstr "" +" --sysconfdir affiche l'emplacement des fichiers de configuration\n" +" globaux du système\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr " --pgxs affiche l'emplacement du makefile des extensions\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure affiche les options passées au script « configure »\n" +" à la construction de PostgreSQL\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr "" +" --cc affiche la valeur de CC utilisée lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:95 +#, c-format +msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cppflags affiche la valeur de CPPFLAGS utilisée lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:96 +#, c-format +msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cflags affiche la valeur de CFLAGS utilisée lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:97 +#, c-format +msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr "" +" --cflags_sl affiche la valeur de CFLAGS_SL utilisée lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:98 +#, c-format +msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --ldflags affiche la valeur de LDFLAGS utilisée à lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:99 +#, c-format +msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" +msgstr "" +" --ldflags_ex affiche la valeur de LDFLAGS_EX utilisée lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:100 +#, c-format +msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" +msgstr "" +" --ldflags_sl affiche la valeur de LDFLAGS_SL utilisée lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:101 +#, c-format +msgid " --libs show LIBS value used when PostgreSQL was built\n" +msgstr "" +" --libs affiche la valeur de LIBS utilisée lors de la\n" +" construction de PostgreSQL\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version affiche la version de PostgreSQL\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"Sans argument, tous les éléments connus sont affichés.\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Rapporter les bogues à <%s>.\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil %s : %s\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayer « %s --help » pour plus d'informations.\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s : n'a pas pu trouver son propre exécutable\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s : argument invalide : %s\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapporter les bogues à .\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide puis quitte\n" + +#~ msgid "child process exited with unrecognized status %d" +#~ msgstr "le processus fils a quitté avec un statut %d non reconnu" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "le processus fils a été terminé par le signal %d" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "child process was terminated by exception 0x%X" +#~ msgstr "le processus fils a été terminé par l'exception 0x%X" + +#~ msgid "child process exited with exit code %d" +#~ msgstr "le processus fils a quitté avec le code de sortie %d" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu changer le répertoire par « %s » : %s" + +#~ msgid "pclose failed: %m" +#~ msgstr "échec de pclose : %m" diff --git a/src/bin/pg_config/po/ja.po b/src/bin/pg_config/po/ja.po new file mode 100644 index 000000000000..0252ccfac054 --- /dev/null +++ b/src/bin/pg_config/po/ja.po @@ -0,0 +1,290 @@ +# Japanese message translation file for pg_config +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# Shigehiro Honda , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_config (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:54+0900\n" +"PO-Revision-Date: 2020-09-13 08:56+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "記録されていません" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "カレントディレクトリを識別できませんでした: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "バイナリ\"%s\"は無効です" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "バイナリ\"%s\"を読み取れませんでした" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "実行する\"%s\"がありませんでした" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "ディレクトリ\"%s\"に移動できませんでした: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pcloseが失敗しました: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "メモリ不足です" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%sはインストールされたバージョンのPostgreSQLに関する情報を提供します。\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [オプション]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "オプション:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr " --bindir ユーザ実行ファイルの場所を表示\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir 文書ファイルの場所を表示\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr " --htmldir html文書ファイルの場所を表示\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr " --includedir クライアントインタフェースのCヘッダファイルの場所を表示\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr " --pkgincludedir その他のCヘッダファイルの場所を表示\n" + +#: pg_config.c:84 +#, c-format +msgid " --includedir-server show location of C header files for the server\n" +msgstr " --includedir-server サーバ用Cヘッダファイルの場所を表示\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr " --libdir オブジェクトコードライブラリの場所を表示\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr " --pkglibdir 動的ロード可能モジュールの場所を表示\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr " --localedir ロケールサポートファイルの場所を表示\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir マニュアルページの場所を表示\n" + +#: pg_config.c:89 +#, c-format +msgid " --sharedir show location of architecture-independent support files\n" +msgstr " --sharedir アーキテクチャ非依存のサポートファイルの場所を表示\n" + +#: pg_config.c:90 +#, c-format +msgid " --sysconfdir show location of system-wide configuration files\n" +msgstr " --sysconfdir システム全体の設定ファイルの場所を表示\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr " --pgxs 機能拡張のmakefileの場所を表示\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure PostgreSQL構築時に\"configure\"スクリプトに与えた\n" +" オプションを表示\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr " --cc PostgreSQL構築時に使用したCCの値を表示\n" + +#: pg_config.c:95 +#, c-format +msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr " --cppflags PostgreSQL構築時に使用したCPPFLAGSの値を表示\n" + +#: pg_config.c:96 +#, c-format +msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr " --cflags PostgreSQL構築時に使用したCFLAGSの値を表示\n" + +#: pg_config.c:97 +#, c-format +msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr " --cflags_sl PostgreSQL構築時に使用したCFLAGS_SLの値を表示\n" + +#: pg_config.c:98 +#, c-format +msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr " --ldflags PostgreSQL構築時に使用したLDFLAGSの値を表示\n" + +#: pg_config.c:99 +#, c-format +msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" +msgstr " --ldflags_ex PostgreSQL構築時に使用したLDFLAGS_EXの値を表示\n" + +#: pg_config.c:100 +#, c-format +msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" +msgstr " --ldflags_sl PostgreSQL構築時に使用したLDFLAGS_SLの値を表示\n" + +#: pg_config.c:101 +#, c-format +msgid " --libs show LIBS value used when PostgreSQL was built\n" +msgstr " --libs PostgreSQL構築時に使用したLIBSの値を表示\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version PostgreSQLのバージョンを表示\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"引数がない場合、既知の項目をすべて表示します。\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "バグは<%s>に報告してください。\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"を行ってください\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 実行ファイル自体がありませんでした\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: 無効な引数です: %s\n" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "現在のディレクトリを認識できませんでした: %s" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "ディレクトリ\"%s\"に移動できませんでした: %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "シンボリックリンク\"%s\"を読み取ることができませんでした" + +#~ msgid "pclose failed: %s" +#~ msgstr "pcloseが失敗しました: %s" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "子プロセスがシグナル%dで終了しました" + +#~ msgid "child process exited with unrecognized status %d" +#~ msgstr "子プロセスが未知のステータス%dで終了しました" + +#~ msgid "child process exited with exit code %d" +#~ msgstr "子プロセスが終了コード%dで終了しました" + +#~ msgid "child process was terminated by exception 0x%X" +#~ msgstr "子プロセスが例外0x%Xで終了しました" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "子プロセスがシグナル%sで終了しました" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "ディレクトリ\"%s\"に移動できませんでした" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help ヘルプを表示し、終了します\n" diff --git a/src/bin/pg_config/po/ko.po b/src/bin/pg_config/po/ko.po new file mode 100644 index 000000000000..2d44f89e7312 --- /dev/null +++ b/src/bin/pg_config/po/ko.po @@ -0,0 +1,275 @@ +# Korean message translation file for PostgreSQL pg_config +# Ioseph Kim , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_config (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:44+0000\n" +"PO-Revision-Date: 2020-10-06 11:15+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean team \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "기록되어 있지 않음" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "현재 디렉터리를 알 수 없음: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "잘못된 바이너리 파일: \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" 바이너리 파일을 읽을 수 없음" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "실행할 \"%s\" 파일 찾을 수 없음" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" 디렉터리로 바꿀 수 없음: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "\"%s\" 심벌릭 링크를 읽을 수 없음: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose 실패: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "메모리 부족" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s 프로그램은 설치된 PostgreSQL 버전에 대한 정보를 제공합니다.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [OPTION]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "옵션들:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr "" +" --bindir 사용자가 실행할 수 있는 응용프로그램들이 있는\n" +" 경로를 보여줌\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir 문서 파일들이 있는 위치를 보여줌\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr " --htmldir HTML 문서 파일의 위치를 보여줌\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" --includedir 클라이언트 인터페이스의 C 헤더 파일이 있는 경로를\n" +" 보여줌\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr " --pkgincludedir 기타 C 헤더 파일 위치를 보여줌\n" + +#: pg_config.c:84 +#, c-format +msgid "" +" --includedir-server show location of C header files for the server\n" +msgstr " --includedir-server 서버용 C 헤더 파일 경로를 보여줌\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr " --libdir 라이브러리 경로를 보여줌\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr " --pkglibdir 동적 호출 가능 모듈의 경로를 보여줌\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr " --localedir 로케인 지원 파일들의 위치를 보여줌\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir 맨페이지 위치를 보여줌\n" + +#: pg_config.c:89 +#, c-format +msgid "" +" --sharedir show location of architecture-independent support " +"files\n" +msgstr "" +" --sharedir 각종 공용으로 사용되는 share 파일들의 위치를 보여줌\n" + +#: pg_config.c:90 +#, c-format +msgid "" +" --sysconfdir show location of system-wide configuration files\n" +msgstr " --sysconfdir 시스템 전역 환경 설정 파일의 위치를 보여줌\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr " --pgxs 확장 makefile 경로를 보여줌\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure PostgreSQL 만들 때 사용한 \"configure\" 스크립트의\n" +" 옵션들을 보여줌\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr " --cc PostgreSQL 만들 때 사용된 CC 값을 보여줌\n" + +#: pg_config.c:95 +#, c-format +msgid "" +" --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr " --cppflags PostgreSQL 만들 때 지정한 CPPFLAGS 값\n" + +#: pg_config.c:96 +#, c-format +msgid "" +" --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cflags PostgreSQL 만들 때, 사용한 CFLAGS 값을 보여줌\n" + +#: pg_config.c:97 +#, c-format +msgid "" +" --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr " --cflags_sl PostgreSQL 만들 때 지정한 CFLAGS_SL 값\n" + +#: pg_config.c:98 +#, c-format +msgid "" +" --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --ldflags PostgreSQL 만들 때, 사용한 LDFLAGS 값을 보여줌\n" + +#: pg_config.c:99 +#, c-format +msgid "" +" --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was " +"built\n" +msgstr "" +" --ldflags_ex PostgreSQL 만들 때, 사용한 LDFLAGS_EX 값을 보여줌\n" + +#: pg_config.c:100 +#, c-format +msgid "" +" --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was " +"built\n" +msgstr " --ldflags_sl PostgreSQL 만들 때 지정한 LDFLAGS_SL 값\n" + +#: pg_config.c:101 +#, c-format +msgid "" +" --libs show LIBS value used when PostgreSQL was built\n" +msgstr " --libs PostgreSQL 만들 때, 사용한 LIBS 값을 보여줌\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version PostgreSQL 버전을 보여줌\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"명령행 인수가 없으면 모든 항목에 대한 정보를 보여 줌\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "문제점 보고 주소: <%s>\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 자세한 정보가 필요하면, \"%s --help\"\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 실행 가능한 프로그램을 찾을 수 없습니다\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: 잘못된 인수: %s\n" diff --git a/src/bin/pg_config/po/ru.po b/src/bin/pg_config/po/ru.po new file mode 100644 index 000000000000..75c7f8959949 --- /dev/null +++ b/src/bin/pg_config/po/ru.po @@ -0,0 +1,320 @@ +# Russian message translation file for pg_config +# Copyright (C) 2004-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Oleg Bartunov , 2004. +# Serguei A. Mokhov , 2004-2005. +# Sergey Burladyan , 2009, 2012. +# Andrey Sudnik , 2010. +# Alexander Lakhin , 2012-2016, 2017, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_config (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2020-09-03 13:28+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 +msgid "not recorded" +msgstr "не записано" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не удалось определить текущий каталог: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "неверный исполняемый файл \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "не удалось прочитать исполняемый файл \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "не удалось найти запускаемый файл \"%s\"" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не удалось перейти в каталог \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не удалось прочитать символическую ссылку \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "ошибка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "нехватка памяти" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s предоставляет информацию об установленной версии PostgreSQL.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [ПАРАМЕТР]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "Параметры:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr " --bindir показать расположение исполняемых файлов\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir показать расположение файлов документации\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr "" +" --htmldir показать расположение HTML-файлов документации\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" --includedir показать расположение файлов-заголовков (.h) для\n" +" клиентских интерфейсов на языке C\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr "" +" --pkgincludedir показать расположение других файлов-заголовков (.h)\n" + +#: pg_config.c:84 +#, c-format +msgid "" +" --includedir-server show location of C header files for the server\n" +msgstr "" +" --includedir-server показать расположение файлов-заголовков (.h) для " +"сервера\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr "" +" --libdir показать расположение библиотек объектного кода\n" + +#: pg_config.c:86 +#, c-format +msgid " --pkglibdir show location of dynamically loadable modules\n" +msgstr "" +" --pkglibdir показать расположение динамически загружаемых " +"модулей\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr "" +" --localedir показать расположение файлов описания локалей\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir показать расположение справочных страниц\n" + +#: pg_config.c:89 +#, c-format +msgid "" +" --sharedir show location of architecture-independent support " +"files\n" +msgstr "" +" --sharedir показать расположение платформенно-независимых " +"файлов\n" + +#: pg_config.c:90 +#, c-format +msgid "" +" --sysconfdir show location of system-wide configuration files\n" +msgstr "" +" --sysconfdir показать расположение общесистемных файлов " +"конфигурации\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr "" +" --pgxs показать расположение makefile для расширений\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure показать параметры скрипта \"configure\", с " +"которыми\n" +" был собран PostgreSQL\n" + +#: pg_config.c:94 +#, c-format +msgid " --cc show CC value used when PostgreSQL was built\n" +msgstr "" +" --cc показать, с каким значением CC собран PostgreSQL\n" + +#: pg_config.c:95 +#, c-format +msgid "" +" --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cppflags показать, с каким значением CPPFLAGS собран " +"PostgreSQL\n" + +#: pg_config.c:96 +#, c-format +msgid "" +" --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cflags показать, с какими флагами C собран PostgreSQL\n" + +#: pg_config.c:97 +#, c-format +msgid "" +" --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgstr "" +" --cflags_sl показать, с каким значением CFLAGS_SL собран " +"PostgreSQL\n" + +#: pg_config.c:98 +#, c-format +msgid "" +" --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --ldflags показать, с каким значением LDFLAGS собран " +"PostgreSQL\n" + +#: pg_config.c:99 +#, c-format +msgid "" +" --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was " +"built\n" +msgstr "" +" --ldflags_ex показать, с каким значением LDFLAGS_EX собран " +"PostgreSQL\n" + +#: pg_config.c:100 +#, c-format +msgid "" +" --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was " +"built\n" +msgstr "" +" --ldflags_sl показать, с каким значением LDFLAGS_SL собран " +"PostgreSQL\n" + +#: pg_config.c:101 +#, c-format +msgid "" +" --libs show LIBS value used when PostgreSQL was built\n" +msgstr "" +" --libs показать, с каким значением LIBS собран PostgreSQL\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version показать версию PostgreSQL\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"При запуске без аргументов выводятся все известные значения.\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_config.c:112 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_config.c:154 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: не удалось найти свой исполняемый файл\n" + +#: pg_config.c:181 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: неверный аргумент: %s\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Об ошибках сообщайте по адресу .\n" + +#~ msgid "child process exited with unrecognized status %d" +#~ msgstr "дочерний процесс завершился с нераспознанным состоянием %d" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "дочерний процесс завершён по сигналу %d" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "дочерний процесс завершён по сигналу %s" + +#~ msgid "child process was terminated by exception 0x%X" +#~ msgstr "дочерний процесс прерван исключением 0x%X" + +#~ msgid "child process exited with exit code %d" +#~ msgstr "дочерний процесс завершился с кодом возврата %d" diff --git a/src/bin/pg_config/po/uk.po b/src/bin/pg_config/po/uk.po index 8a332b740b58..407ef9fc1b87 100644 --- a/src/bin/pg_config/po/uk.po +++ b/src/bin/pg_config/po/uk.po @@ -1,63 +1,67 @@ msgid "" msgstr "" "Project-Id-Version: postgresql\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2018-12-04 20:35+0100\n" -"PO-Revision-Date: 2019-05-07 12:57\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:14+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" "Last-Translator: pasha_golub\n" "Language-Team: Ukrainian\n" -"Language: uk_UA\n" +"Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" -"X-Generator: crowdin.com\n" "X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" "X-Crowdin-Language: uk\n" -"X-Crowdin-File: /REL_11_STABLE/src/bin/pg_config/po/pg_config.pot\n" +"X-Crowdin-File: /DEV_13/pg_config.pot\n" +"X-Crowdin-File-ID: 494\n" -#: ../../common/config_info.c:130 ../../common/config_info.c:138 -#: ../../common/config_info.c:146 ../../common/config_info.c:154 -#: ../../common/config_info.c:162 ../../common/config_info.c:170 -#: ../../common/config_info.c:178 ../../common/config_info.c:186 -#: ../../common/config_info.c:194 +#: ../../common/config_info.c:134 ../../common/config_info.c:142 +#: ../../common/config_info.c:150 ../../common/config_info.c:158 +#: ../../common/config_info.c:166 ../../common/config_info.c:174 +#: ../../common/config_info.c:182 ../../common/config_info.c:190 msgid "not recorded" msgstr "не записано" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 #, c-format -msgid "could not identify current directory: %s" -msgstr "не вдалося визначити поточний каталог: %s" +msgid "could not identify current directory: %m" +msgstr "не вдалося визначити поточний каталог: %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:156 #, c-format msgid "invalid binary \"%s\"" msgstr "невірний бінарний файл \"%s\"" -#: ../../common/exec.c:195 +#: ../../common/exec.c:206 #, c-format msgid "could not read binary \"%s\"" msgstr "неможливо прочитати бінарний файл \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:214 #, c-format msgid "could not find a \"%s\" to execute" msgstr "неможливо знайти \"%s\" для виконання" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:270 ../../common/exec.c:309 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "неможливо змінити директорію на \"%s\": %s" +msgid "could not change directory to \"%s\": %m" +msgstr "не вдалося змінити каталог на \"%s\": %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:287 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "неможливо прочитати символічне посилання \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "не можливо прочитати символічне послання \"%s\": %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:410 #, c-format -msgid "pclose failed: %s" -msgstr "помилка pclose: %s" +msgid "pclose failed: %m" +msgstr "помилка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "недостатньо пам'яті" #: pg_config.c:74 #, c-format @@ -212,21 +216,29 @@ msgstr "\n" #: pg_config.c:105 #, c-format -msgid "Report bugs to .\n" -msgstr "Про помилки повідомляйте .\n" +msgid "Report bugs to <%s>.\n" +msgstr "Повідомляти про помилки на <%s>.\n" + +#: pg_config.c:106 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" -#: pg_config.c:111 +#: pg_config.c:112 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" -#: pg_config.c:153 +#: pg_config.c:154 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: не вдалося знайти ехе файл власної програми\n" -#: pg_config.c:180 +#: pg_config.c:181 #, c-format msgid "%s: invalid argument: %s\n" msgstr "%s: недопустимий аргумент: %s\n" +#~ msgid "Report bugs to .\n" +#~ msgstr "Про помилки повідомляйте на .\n" + diff --git a/src/bin/pg_config/t/001_pg_config.pl b/src/bin/pg_config/t/001_pg_config.pl index ccca190bb19b..d8829faea6c9 100644 --- a/src/bin/pg_config/t/001_pg_config.pl +++ b/src/bin/pg_config/t/001_pg_config.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pg_controldata/Makefile b/src/bin/pg_controldata/Makefile index 76b330dc1f9e..c5405b8a080d 100644 --- a/src/bin/pg_controldata/Makefile +++ b/src/bin/pg_controldata/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_controldata # -# Copyright (c) 1998-2020, PostgreSQL Global Development Group +# Copyright (c) 1998-2021, PostgreSQL Global Development Group # # src/bin/pg_controldata/Makefile # diff --git a/src/bin/pg_controldata/nls.mk b/src/bin/pg_controldata/nls.mk index 8f6b6757b74e..5c0e33e91a1d 100644 --- a/src/bin/pg_controldata/nls.mk +++ b/src/bin/pg_controldata/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_controldata/nls.mk CATALOG_NAME = pg_controldata -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr uk vi zh_CN +AVAIL_LANGUAGES = cs de el es fr it ja ko pl pt_BR ru sv tr uk vi zh_CN GETTEXT_FILES = pg_controldata.c ../../common/controldata_utils.c GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index 93bd51aa6dec..c4a8cddba6b7 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -243,11 +243,9 @@ main(int argc, char *argv[]) printf(_("pg_control last modified: %s\n"), pgctime_str); printf(_("Latest checkpoint location: %X/%X\n"), - (uint32) (ControlFile->checkPoint >> 32), - (uint32) ControlFile->checkPoint); + LSN_FORMAT_ARGS(ControlFile->checkPoint)); printf(_("Latest checkpoint's REDO location: %X/%X\n"), - (uint32) (ControlFile->checkPointCopy.redo >> 32), - (uint32) ControlFile->checkPointCopy.redo); + LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo)); printf(_("Latest checkpoint's REDO WAL file: %s\n"), xlogfilename); printf(_("Latest checkpoint's TimeLineID: %u\n"), @@ -286,19 +284,15 @@ main(int argc, char *argv[]) printf(_("Time of latest checkpoint: %s\n"), ckpttime_str); printf(_("Fake LSN counter for unlogged rels: %X/%X\n"), - (uint32) (ControlFile->unloggedLSN >> 32), - (uint32) ControlFile->unloggedLSN); + LSN_FORMAT_ARGS(ControlFile->unloggedLSN)); printf(_("Minimum recovery ending location: %X/%X\n"), - (uint32) (ControlFile->minRecoveryPoint >> 32), - (uint32) ControlFile->minRecoveryPoint); + LSN_FORMAT_ARGS(ControlFile->minRecoveryPoint)); printf(_("Min recovery ending loc's timeline: %u\n"), ControlFile->minRecoveryPointTLI); printf(_("Backup start location: %X/%X\n"), - (uint32) (ControlFile->backupStartPoint >> 32), - (uint32) ControlFile->backupStartPoint); + LSN_FORMAT_ARGS(ControlFile->backupStartPoint)); printf(_("Backup end location: %X/%X\n"), - (uint32) (ControlFile->backupEndPoint >> 32), - (uint32) ControlFile->backupEndPoint); + LSN_FORMAT_ARGS(ControlFile->backupEndPoint)); printf(_("End-of-backup record required: %s\n"), ControlFile->backupEndRequired ? _("yes") : _("no")); printf(_("wal_level setting: %s\n"), diff --git a/src/bin/pg_controldata/po/cs.po b/src/bin/pg_controldata/po/cs.po new file mode 100644 index 000000000000..4774832b805e --- /dev/null +++ b/src/bin/pg_controldata/po/cs.po @@ -0,0 +1,561 @@ +# Czech message translation file for pg_controldata +# Copyright (C) 2012 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Tomas Vondra , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata-cs (PostgreSQL 9.3)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:17+0000\n" +"PO-Revision-Date: 2020-10-31 20:50+0100\n" +"Last-Translator: Tomas Vondra \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.4.1\n" + +#: ../../common/controldata_utils.c:73 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "nelze otevřít soubor \"%s\" pro čtení: %m" + +#: ../../common/controldata_utils.c:89 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "nelze číst soubor \"%s\": %m" + +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "nelze číst soubor \"%s\": načteno %d z %zu" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "nelze uzavřít soubor \"%s\": %m" + +#: ../../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "pořadí bytů nesouhlasí" + +#: ../../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the " +"one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"možný nesoulad v pořadí bytů\n" +"Pořadí bytů používané pro uložení pg_control souboru nemusí odpovídat " +"tomu\n" +"používanému tímto programem. V tom případě by výsledky uvedené níže byly " +"chybné, a\n" +"PostgreSQL instalace by byla nekompatibilní s tímto datovým adresářem." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "nelze otevřít soubor \"%s\": %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "nelze zapsat soubor \"%s\": %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "nelze provést fsync souboru \"%s\": %m" + +#: pg_controldata.c:35 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s vypíše kontrolní informace o PostgreSQL databázi.\n" +"\n" + +#: pg_controldata.c:36 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: pg_controldata.c:37 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [VOLBY] [DATOVÝ-ADRESÁŘ]\n" + +#: pg_controldata.c:38 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Volby:\n" + +#: pg_controldata.c:39 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR datový adresář\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version vypiš informaci o verzi, potom skonči\n" + +#: pg_controldata.c:41 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help vypiš tuto nápovědu, potom skonči\n" + +#: pg_controldata.c:42 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable " +"PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Není-li specifikován datový adresář, je použita proměnná prostředí\n" +"PGDATA.\n" +"\n" + +#: pg_controldata.c:44 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Chyby hlašte na <%s>.\n" + +#: pg_controldata.c:45 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domovská stránka: <%s>\n" + +#: pg_controldata.c:55 +msgid "starting up" +msgstr "startování" + +#: pg_controldata.c:57 +msgid "shut down" +msgstr "ukončení" + +#: pg_controldata.c:59 +msgid "shut down in recovery" +msgstr "ukončení (shut down) během obnovy" + +#: pg_controldata.c:61 +msgid "shutting down" +msgstr "ukončování" + +#: pg_controldata.c:63 +msgid "in crash recovery" +msgstr "probíhá zotavení z pádu" + +#: pg_controldata.c:65 +msgid "in archive recovery" +msgstr "probíhá obnova z archivu" + +#: pg_controldata.c:67 +msgid "in production" +msgstr "v provozu" + +#: pg_controldata.c:69 +msgid "unrecognized status code" +msgstr "neznámý stavový kód" + +#: pg_controldata.c:84 +msgid "unrecognized wal_level" +msgstr "neznámý wal_level" + +#: pg_controldata.c:137 pg_controldata.c:155 pg_controldata.c:163 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: pg_controldata.c:153 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "příliš mnoho argumentů v příkazové řádce (první je \"%s\")" + +#: pg_controldata.c:162 +#, c-format +msgid "no data directory specified" +msgstr "není specifikován datový adresář" + +#: pg_controldata.c:170 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this " +"program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"UPOZORNĚNÍ: Spočítaný CRC kontrolní součet nesouhlasí s hodnotou uloženou\n" +"v souboru. Buď je soubor poškozen nebo má jinou strukturu než tento " +"program\n" +"očekává. Níže uvedené výsledky jsou nedůvěryhodné.\n" +"\n" + +#: pg_controldata.c:179 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "WARNING: neplatná velikost WAL segmentu\n" + +#: pg_controldata.c:180 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"Velikost WAL segmentu uloženého v souboru, %d byte, není mocnina dvou\n" +"mezi 1 MB a 1 GB. Soubor je poškozený a výsledky uvedené níže jsou\n" +"nedůvěryhodné.\n" +"\n" +msgstr[1] "" +"Velikost WAL segmentu uloženého v souboru, %d bytů, není mocnina dvou\n" +"mezi 1 MB a 1 GB. Soubor je poškozený a výsledky uvedené níže jsou\n" +"nedůvěryhodné.\n" +"\n" +msgstr[2] "" +"Velikost WAL segmentu uloženého v souboru, %d bytů, není mocnina dvou\n" +"mezi 1 MB a 1 GB. Soubor je poškozený a výsledky uvedené níže jsou\n" +"nedůvěryhodné.\n" +"\n" + +#: pg_controldata.c:222 +msgid "???" +msgstr "???" + +#: pg_controldata.c:228 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "Číslo verze pg_controlu: %u\n" + +#: pg_controldata.c:230 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Číslo verze katalogu: %u\n" + +#: pg_controldata.c:232 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "" +"Identifikátor databázového systému: %llu\n" +"\n" + +#: pg_controldata.c:234 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "Status databázového klastru: %s\n" + +#: pg_controldata.c:236 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "Poslední modifikace pg_control: %s\n" + +#: pg_controldata.c:238 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "Poslední umístění checkpointu: %X/%X\n" + +#: pg_controldata.c:241 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "Poslední umístění REDO checkpointu: %X/%X\n" + +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "REDO WAL file posledního checkpointu: %s\n" + +#: pg_controldata.c:246 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "TimeLineID posledního checkpointu: %u\n" + +#: pg_controldata.c:248 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "PrevTimeLineID posledního checkpointu: %u\n" + +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Poslední full_page_writes checkpointu: %s\n" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "off" +msgstr "vypnuto" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "on" +msgstr "zapnuto" + +#: pg_controldata.c:252 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID posledního checkpointu: %u:%u\n" + +#: pg_controldata.c:255 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "Poslední umístění NextOID checkpointu: %u\n" + +#: pg_controldata.c:257 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "NextMultiXactId posledního checkpointu: %u\n" + +#: pg_controldata.c:259 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "NextMultiOffset posledního checkpointu: %u\n" + +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "oldestXID posledního checkpointu: %u\n" + +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "DB k oldestXID posledního checkpointu: %u\n" + +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "oldestActiveXID posledního checkpointu: %u\n" + +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "oldestMultiXid posledního checkpointu: %u\n" + +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "DB k oldestMulti posledního checkpointu: %u\n" + +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "oldestCommitTsXid posledního checkpointu: %u\n" + +#: pg_controldata.c:273 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "newestCommitTsXid posledního checkpointu: %u\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "Čas posledního checkpointu: %s\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "Falešné LSN počítadlo pro unlogged relace: %X/%X\n" + +#: pg_controldata.c:280 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "Minimální pozice ukončení obnovy: %X/%X\n" + +#: pg_controldata.c:283 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "Timeline minimální pozice ukončení obnovy: %u\n" + +#: pg_controldata.c:285 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "Pozice počátku backupu: %X/%X\n" + +#: pg_controldata.c:288 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "Koncová pozice zálohy: %X/%X\n" + +#: pg_controldata.c:291 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "Vyžadován záznam konce backupu: %s\n" + +#: pg_controldata.c:292 +msgid "no" +msgstr "ne" + +#: pg_controldata.c:292 +msgid "yes" +msgstr "ano" + +#: pg_controldata.c:293 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "wal_level hodnota: %s\n" + +#: pg_controldata.c:295 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "wal_log_hints hodnota: %s\n" + +#: pg_controldata.c:297 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "max_connections hodnota: %d\n" + +#: pg_controldata.c:299 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "max_worker_processes hodnota: %d\n" + +#: pg_controldata.c:301 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "max_wal_senders setting: %d\n" + +#: pg_controldata.c:303 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "max_prepared_xacts hodnota: %d\n" + +#: pg_controldata.c:305 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "max_locks_per_xact hodnota: %d\n" + +#: pg_controldata.c:307 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "track_commit_timestamp hodnota: %s\n" + +#: pg_controldata.c:309 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Maximální zarovnání dat: %u\n" + +#: pg_controldata.c:312 +#, c-format +msgid "Database block size: %u\n" +msgstr "Velikost databázového bloku: %u\n" + +#: pg_controldata.c:314 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Bloků v segmentu velké relace: %u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Velikost WAL bloku: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Bytů ve WAL segmentu: %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Maximální délka identifikátorů: %u\n" + +#: pg_controldata.c:322 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Maximální počet sloupců v indexu: %u\n" + +#: pg_controldata.c:324 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Maximální velikost úseku TOAST: %u\n" + +#: pg_controldata.c:326 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Velikost large-object chunku: %u\n" + +#: pg_controldata.c:329 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Způsob uložení typu date/time: %s\n" + +#: pg_controldata.c:330 +msgid "64-bit integers" +msgstr "64-bitová čísla" + +#: pg_controldata.c:331 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Způsob předávání float8 hodnot: %s\n" + +#: pg_controldata.c:332 +msgid "by reference" +msgstr "odkazem" + +#: pg_controldata.c:332 +msgid "by value" +msgstr "hodnotou" + +#: pg_controldata.c:333 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Verze kontrolních součtů datových stránek: %u\n" + +#: pg_controldata.c:335 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "Zkušební authentizační nonce: %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: nelze otevřít soubor \"%s\" pro čtení: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: nelze číst soubor \"%s\": %s\n" + +#~ msgid "" +#~ "Usage:\n" +#~ " %s [OPTION] [DATADIR]\n" +#~ "\n" +#~ "Options:\n" +#~ " --help show this help, then exit\n" +#~ " --version output version information, then exit\n" +#~ msgstr "" +#~ "Použití:\n" +#~ " %s [PŘEPÍNAČ] [ADRESÁŘ]\n" +#~ "\n" +#~ "Přepínače:\n" +#~ " --help ukáže tuto nápovědu a skončí\n" +#~ " --version ukáže verzi tohoto programu a skončí\n" + +#~ msgid "floating-point numbers" +#~ msgstr "čísla s plovoucí řádovou čárkou" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help ukáže tuto nápovědu, a skončí\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version vypíše informaci o verzi, pak skončí\n" + +#~ msgid "Float4 argument passing: %s\n" +#~ msgstr "Způsob předávání float4 hodnot: %s\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Oznámení o chybách zasílejte na .\n" diff --git a/src/bin/pg_controldata/po/el.po b/src/bin/pg_controldata/po/el.po new file mode 100644 index 000000000000..12bbb0556b49 --- /dev/null +++ b/src/bin/pg_controldata/po/el.po @@ -0,0 +1,521 @@ +# Greek message translation file for pg_controldata +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_controldata (PostgreSQL) package. +# Georgios Kokolatos , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-26 00:19+0000\n" +"PO-Revision-Date: 2021-05-31 11:02+0200\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../common/controldata_utils.c:73 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου “%s” για ανάγνωση: %m" + +#: ../../common/controldata_utils.c:89 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του αρχείου \"%s\": %m" + +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "δεν ήταν δυνατή η ανάγνωση του αρχείου \"%s\": ανέγνωσε %d από %zu" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο του αρχείου “%s”: %m" + +#: ../../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "αναντιστοιχία διάταξης byte" + +#: ../../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"πιθανή αναντιστοιχία διάταξης byte\n" +"Η διάταξη byte που χρησιμοποιείται για την αποθήκευση του αρχείου pg_control " +"ενδέχεται να μην ταιριάζει με αυτήν\n" +"που χρησιμοποιείται από αυτό το πρόγραμμα. Στην περίπτωση αυτή, τα παρακάτω " +"αποτελέσματα θα ήταν εσφαλμένα, και\n" +"η εγκατάσταση PostgreSQL θα ήταν ασύμβατη με αυτόν τον κατάλογο δεδομένων." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου “%s”: %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εγγραφή αρχείου “%s”: %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση της εντολής fsync στο αρχείο “%s”: %m" + +#: pg_controldata.c:35 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s εμφανίζει πληροφορίες ελέγχου μίας συστάδας βάσεων δεδομένων PostgreSQL.\n" +"\n" + +#: pg_controldata.c:36 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_controldata.c:37 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [OPTION] [DATADIR]\n" + +#: pg_controldata.c:38 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Επιλογές:\n" + +#: pg_controldata.c:39 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, —pgdata=]DATADIR κατάλογος δεδομένων\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης, στη συνέχεια έξοδος\n" + +#: pg_controldata.c:41 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, μετά έξοδος\n" + +#: pg_controldata.c:42 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Εάν δεν έχει καθοριστεί κατάλογος δεδομένων (DATADIR), χρησιμοποιείται η\n" +"μεταβλητή περιβάλλοντος PGDATA.\n" +"\n" + +#: pg_controldata.c:44 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_controldata.c:45 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_controldata.c:55 +msgid "starting up" +msgstr "εκκίνηση" + +#: pg_controldata.c:57 +msgid "shut down" +msgstr "τερματισμός" + +#: pg_controldata.c:59 +msgid "shut down in recovery" +msgstr "τερματισμός σε αποκατάσταση" + +#: pg_controldata.c:61 +msgid "shutting down" +msgstr "τερματίζει" + +#: pg_controldata.c:63 +msgid "in crash recovery" +msgstr "σε αποκατάσταση από κρασάρισμα" + +#: pg_controldata.c:65 +msgid "in archive recovery" +msgstr "σε αποκατάσταση αρχειοθήκης" + +#: pg_controldata.c:67 +msgid "in production" +msgstr "στην παραγωγή" + +#: pg_controldata.c:69 +msgid "unrecognized status code" +msgstr "μη αναγνωρίσιμος κωδικός κατάστασης" + +#: pg_controldata.c:84 +msgid "unrecognized wal_level" +msgstr "μη αναγνωρίσιμο wal_level" + +#: pg_controldata.c:137 pg_controldata.c:155 pg_controldata.c:163 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_controldata.c:153 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (ο πρώτη είναι η “%s”)" + +#: pg_controldata.c:162 +#, c-format +msgid "no data directory specified" +msgstr "δεν ορίστηκε κατάλογος δεδομένων" + +#: pg_controldata.c:170 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το υπολογιζόμενο άθροισμα ελέγχου CRC δεν συμφωνεί με την τιμή που " +"είναι αποθηκευμένη στο αρχείο.\n" +"Είτε το αρχείο είναι αλλοιωμένο είτε έχει διαφορετική διάταξη από αυτή που " +"περιμένει\n" +"αυτό το πρόγραμμα. Τα παρακάτω αποτελέσματα είναι αναξιόπιστα.\n" +"\n" + +#: pg_controldata.c:179 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "ΠΡΟΕΙΔΟΠΟΙΗΣΗ: μη έγκυρο μέγεθος τμήματος WAL\n" + +#: pg_controldata.c:180 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"Το μέγεθος τμήματος WAL που είναι αποθηκευμένο στο αρχείο, %d byte, δεν είναι " +"δύναμη\n" +"του δύο μεταξύ 1 MB και 1 GB. Το αρχείο είναι αλλοιωμένο και τα παρακάτω " +"αποτελέσματα\n" +"είναι αναξιόπιστα.\n" +"\n" +msgstr[1] "" +"Το μέγεθος τμήματος WAL που είναι αποθηκευμένο στο αρχείο, %d bytes, δεν είναι " +"δύναμη\n" +"του δύο μεταξύ 1 MB και 1 GB. Το αρχείο είναι αλλοιωμένο και τα παρακάτω " +"αποτελέσματα\n" +"είναι αναξιόπιστα.\n" +"\n" + +#: pg_controldata.c:222 +msgid "???" +msgstr "???" + +#: pg_controldata.c:228 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "" +"pg_control αριθμός έκδοσης: %u\n" +"\n" + +#: pg_controldata.c:230 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Αριθμός έκδοσης καταλόγου: %u\n" + +#: pg_controldata.c:232 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "Αναγνωριστικό συστήματος βάσης δεδομένων: %llu\n" + +#: pg_controldata.c:234 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "Κατάσταση συστάδας βάσης δεδομένων: %s\n" + +#: pg_controldata.c:236 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "πιο πρόσφατη μετατροπή pg_control: %s\n" + +#: pg_controldata.c:238 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "Πιο πρόσφατη τοποθεσία σημείου ελέγχου: %X/%X\n" + +#: pg_controldata.c:240 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "Πιο πρόσφατη τοποθεσία REDO του σημείου ελέγχου: %X/%X\n" + +#: pg_controldata.c:242 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "Πιο πρόσφατο αρχείο REDO WAL του σημείου ελέγχου: %s\n" + +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "Πιο πρόσφατο TimeLineID του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:246 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "Πιο πρόσφατο PrevTimeLineID του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:248 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Πιο πρόσφατο full_page_writes του σημείου ελέγχου: %s\n" + +#: pg_controldata.c:249 pg_controldata.c:290 pg_controldata.c:302 +msgid "off" +msgstr "κλειστό" + +#: pg_controldata.c:249 pg_controldata.c:290 pg_controldata.c:302 +msgid "on" +msgstr "ανοικτό" + +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "Πιο πρόσφατο NextXID του σημείου ελέγχου: %u:%u\n" + +#: pg_controldata.c:253 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "Πιο πρόσφατο NextOID του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:255 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "Πιο πρόσφατο NextMultiXactId του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:257 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "Πιο πρόσφατο NextMultiOffset του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:259 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "Πιο πρόσφατο oldestXID του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "Πιο πρόσφατο oldestXID’s DB του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "Πιο πρόσφατο oldestActiveXID του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "Πιο πρόσφατο oldestMultiXid του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "Πιο πρόσφατο oldestMulti’s DB του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "Πιο πρόσφατο oldestCommitTsXid του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "Πιο πρόσφατο newestCommitTsXid του σημείου ελέγχου: %u\n" + +#: pg_controldata.c:273 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "Ώρα του πιο πρόσφατου σημείου ελέγχου: %s\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "Ψεύτικος μετρητής LSN για μη κενές rels: %X/%X\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "Ελάχιστη τοποθεσία τερματισμού ανάκαμψης: %X/%X\n" + +#: pg_controldata.c:279 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "Χρονογραμμή ελάχιστης τοποθεσίας τερματισμού ανάκαμψης: %u\n" + +#: pg_controldata.c:281 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "Τοποθεσία εκκίνησης Backup: %X/%X\n" + +#: pg_controldata.c:283 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "Τοποθεσία τερματισμου Backup: %X/%X\n" + +#: pg_controldata.c:285 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "Απαιτείται εγγραφή end-of-backup: %s\n" + +#: pg_controldata.c:286 +msgid "no" +msgstr "όχι" + +#: pg_controldata.c:286 +msgid "yes" +msgstr "ναι" + +#: pg_controldata.c:287 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "ρύθμιση wal_level: %s\n" + +#: pg_controldata.c:289 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "ρύθμιση wal_log_hints: %s\n" + +#: pg_controldata.c:291 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "ρύθμιση max_connections: %d\n" + +#: pg_controldata.c:293 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "ρύθμιση max_worker_processes: %d\n" + +#: pg_controldata.c:295 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "ρύθμιση max_wal_senders: %d\n" + +#: pg_controldata.c:297 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "ρύθμιση max_prepared_xacts: %d\n" + +#: pg_controldata.c:299 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "ρύθμιση max_locks_per_xact: %d\n" + +#: pg_controldata.c:301 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "ρύθμιση track_commit_timestamp: %s\n" + +#: pg_controldata.c:303 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Μέγιστη στοίχιση δεδομένων: %u\n" + +#: pg_controldata.c:306 +#, c-format +msgid "Database block size: %u\n" +msgstr "Μέγεθος μπλοκ βάσης δεδομένων: %u\n" + +#: pg_controldata.c:308 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Μπλοκ ανά τμήμα μεγάλης σχέσης: %u\n" + +#: pg_controldata.c:310 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Μέγεθος μπλοκ WAL: %u\n" + +#: pg_controldata.c:312 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Bytes ανά τμήμα WAL: %u\n" + +#: pg_controldata.c:314 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Μέγιστο μήκος αναγνωριστικών: %u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Μέγιστες στήλες σε ένα ευρετήριο: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Μέγιστο μέγεθος ενός τμήματος TOAST: %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Μέγεθος τμήματος μεγάλου αντικειμένου: %u\n" + +#: pg_controldata.c:323 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Τύπος αποθήκευσης ημερομηνίας/ώρας: %s\n" + +#: pg_controldata.c:324 +msgid "64-bit integers" +msgstr "Ακέραιοι 64-bit" + +#: pg_controldata.c:325 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Μεταβλητή Float8 τέθηκε: %s\n" + +#: pg_controldata.c:326 +msgid "by reference" +msgstr "με αναφορά" + +#: pg_controldata.c:326 +msgid "by value" +msgstr "με τιμή" + +#: pg_controldata.c:327 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Έκδοση αθροίσματος ελέγχου σελίδας δεδομένων: %u\n" + +#: pg_controldata.c:329 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "Μακέτα (mock) nonce ταυτοποίησης: %s\n" diff --git a/src/bin/pg_controldata/po/es.po b/src/bin/pg_controldata/po/es.po new file mode 100644 index 000000000000..2764c38466f4 --- /dev/null +++ b/src/bin/pg_controldata/po/es.po @@ -0,0 +1,515 @@ +# Spanish message translation file for pg_controldata +# +# Copyright (c) 2002-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Karim Mribti , 2002. +# Alvaro Herrera , 2003-2014 +# Martín Marqués , 2013 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-13 10:47+0000\n" +"PO-Revision-Date: 2020-09-12 22:55-0300\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../common/controldata_utils.c:73 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" + +#: ../../common/controldata_utils.c:89 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" + +#: ../../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "discordancia en orden de bytes" + +#: ../../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"posible discordancia en orden de bytes\n" +"El ordenamiento de bytes usado para almacenar el archivo pg_control puede no\n" +"coincidir con el usado por este programa. En tal caso los resultados de abajo\n" +"serían erróneos, y la instalación de PostgreSQL sería incompatible con este\n" +"directorio de datos." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" + +#: pg_controldata.c:35 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s muestra información de control del cluster de PostgreSQL.\n" +"\n" + +#: pg_controldata.c:36 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_controldata.c:37 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [OPCIÓN] [DATADIR]\n" + +#: pg_controldata.c:38 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Opciones:\n" + +#: pg_controldata.c:39 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR directorio de datos\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión, luego salir\n" + +#: pg_controldata.c:41 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda, luego salir\n" + +#: pg_controldata.c:42 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Si no se especifica un directorio de datos (DATADIR), se utilizará\n" +"la variable de entorno PGDATA.\n" +"\n" + +#: pg_controldata.c:44 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Reporte errores a <%s>.\n" + +#: pg_controldata.c:45 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_controldata.c:55 +msgid "starting up" +msgstr "iniciando" + +#: pg_controldata.c:57 +msgid "shut down" +msgstr "apagado" + +#: pg_controldata.c:59 +msgid "shut down in recovery" +msgstr "apagado durante recuperación" + +#: pg_controldata.c:61 +msgid "shutting down" +msgstr "apagándose" + +#: pg_controldata.c:63 +msgid "in crash recovery" +msgstr "en recuperación" + +#: pg_controldata.c:65 +msgid "in archive recovery" +msgstr "en recuperación desde archivo" + +#: pg_controldata.c:67 +msgid "in production" +msgstr "en producción" + +#: pg_controldata.c:69 +msgid "unrecognized status code" +msgstr "código de estado no reconocido" + +#: pg_controldata.c:84 +msgid "unrecognized wal_level" +msgstr "wal_level no reconocido" + +#: pg_controldata.c:137 pg_controldata.c:155 pg_controldata.c:163 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Intente «%s --help» para mayor información.\n" + +#: pg_controldata.c:153 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_controldata.c:162 +#, c-format +msgid "no data directory specified" +msgstr "no se especificó el directorio de datos" + +#: pg_controldata.c:170 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"ATENCIÓN: La suma de verificación calculada no coincide con el valor\n" +"almacenado en el archivo. Puede ser que el archivo esté corrupto, o\n" +"bien tiene una estructura diferente de la que este programa está\n" +"esperando. Los resultados presentados a continuación no son confiables.\n" +"\n" + +#: pg_controldata.c:179 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "PRECAUCIÓN: tamaño de segmento de WAL no válido\n" + +#: pg_controldata.c:180 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"El tamaño de segmento de WAL almacenado en el archivo, %d byte,\n" +"no es una potencia de dos entre 1 MB y 1 GB. El archivo está corrupto y los\n" +"resultados de abajo no son confiables.\n" +msgstr[1] "" +"El tamaño de segmento de WAL almacenado en el archivo, %d bytes,\n" +"no es una potencia de dos entre 1 MB y 1 GB. El archivo está corrupto y los\n" +"resultados de abajo no son confiables.\n" + +#: pg_controldata.c:222 +msgid "???" +msgstr "???" + +#: pg_controldata.c:228 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "Número de versión de pg_control: %u\n" + +#: pg_controldata.c:230 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Número de versión del catálogo: %u\n" + +#: pg_controldata.c:232 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "Identificador de sistema: %llu\n" + +#: pg_controldata.c:234 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "Estado del sistema de base de datos: %s\n" + +#: pg_controldata.c:236 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "Última modificación de pg_control: %s\n" + +#: pg_controldata.c:238 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "Ubicación del último checkpoint: %X/%X\n" + +#: pg_controldata.c:241 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "Ubicación de REDO de último checkpoint: %X/%X\n" + +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "Ubicación de REDO de último checkpoint: %s\n" + +#: pg_controldata.c:246 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "TimeLineID del último checkpoint: %u\n" + +#: pg_controldata.c:248 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "PrevTimeLineID del último checkpoint: %u\n" + +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "full_page_writes del último checkpoint: %s\n" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "off" +msgstr "desactivado" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "on" +msgstr "activado" + +#: pg_controldata.c:252 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID de último checkpoint: %u/%u\n" + +#: pg_controldata.c:255 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "NextOID de último checkpoint: %u\n" + +#: pg_controldata.c:257 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "NextMultiXactId de último checkpoint: %u\n" + +#: pg_controldata.c:259 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "NextMultiOffset de último checkpoint: %u\n" + +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "oldestXID del último checkpoint: %u\n" + +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "DB del oldestXID del último checkpoint: %u\n" + +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "oldestActiveXID del último checkpoint: %u\n" + +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "oldestMultiXid del último checkpoint: %u\n" + +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "DB del oldestMultiXid del últ. checkpoint: %u\n" + +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "oldestCommitTsXid del último checkpoint: %u\n" + +#: pg_controldata.c:273 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "newestCommitTsXid del último checkpoint: %u\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "Instante de último checkpoint: %s\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "Contador de LSN falsas para rels. unlogged: %X/%X\n" + +#: pg_controldata.c:280 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "Punto final mínimo de recuperación: %X/%X\n" + +#: pg_controldata.c:283 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "Timeline de dicho punto final mínimo: %u\n" + +#: pg_controldata.c:285 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "Ubicación del inicio de backup: %X/%X\n" + +#: pg_controldata.c:288 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "Ubicación del fin de backup: %X/%X\n" + +#: pg_controldata.c:291 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "Registro fin-de-backup requerido: %s\n" + +#: pg_controldata.c:292 +msgid "no" +msgstr "no" + +#: pg_controldata.c:292 +msgid "yes" +msgstr "sí" + +#: pg_controldata.c:293 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "Parámetro wal_level: %s\n" + +#: pg_controldata.c:295 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "Parámetro wal_log_hings: %s\n" + +#: pg_controldata.c:297 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "Parámetro max_connections: %d\n" + +#: pg_controldata.c:299 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "Parámetro max_worker_processes: %d\n" + +#: pg_controldata.c:301 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "Parámetro max_wal_senders: %d\n" + +#: pg_controldata.c:303 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "Parámetro max_prepared_xacts: %d\n" + +#: pg_controldata.c:305 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "Parámetro max_locks_per_xact: %d\n" + +#: pg_controldata.c:307 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "Parámetro track_commit_timestamp: %s\n" + +#: pg_controldata.c:309 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Alineamiento máximo de datos: %u\n" + +#: pg_controldata.c:312 +#, c-format +msgid "Database block size: %u\n" +msgstr "Tamaño de bloque de la base de datos: %u\n" + +#: pg_controldata.c:314 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Bloques por segmento en relación grande: %u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Tamaño del bloque de WAL: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Bytes por segmento WAL: %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Máxima longitud de identificadores: %u\n" + +#: pg_controldata.c:322 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Máximo número de columnas de un índice: %u\n" + +#: pg_controldata.c:324 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Longitud máxima de un trozo TOAST: %u\n" + +#: pg_controldata.c:326 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Longitud máx. de un trozo de objeto grande: %u\n" + +#: pg_controldata.c:329 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Tipo de almacenamiento de horas y fechas: %s\n" + +#: pg_controldata.c:330 +msgid "64-bit integers" +msgstr "enteros de 64 bits" + +#: pg_controldata.c:331 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Paso de parámetros float8: %s\n" + +#: pg_controldata.c:332 +msgid "by reference" +msgstr "por referencia" + +#: pg_controldata.c:332 +msgid "by value" +msgstr "por valor" + +#: pg_controldata.c:333 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Versión de sumas de verificación de datos: %u\n" + +#: pg_controldata.c:335 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "Nonce para autentificación simulada: %s\n" diff --git a/src/bin/pg_controldata/po/ja.po b/src/bin/pg_controldata/po/ja.po new file mode 100644 index 000000000000..a98a05fbf1b6 --- /dev/null +++ b/src/bin/pg_controldata/po/ja.po @@ -0,0 +1,538 @@ +# Japanese message translation file for pg_controldata +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# Shigehiro Honda , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:54+0900\n" +"PO-Revision-Date: 2020-09-13 08:56+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../common/controldata_utils.c:73 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "ファイル\"%s\"を読み取り用にオープンできませんでした: %m" + +#: ../../common/controldata_utils.c:89 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "ファイル\"%s\"の読み取りに失敗しました: %m" + +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "" +"ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$dバイトを読み込" +"みました" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "ファイル\"%s\"をクローズできませんでした: %m" + +#: ../../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "バイトオーダの不整合" + +#: ../../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the " +"one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"バイトオーダが異なる可能性があります。\n" +"pg_controlファイルを格納するために使用するバイトオーダが本プログラムで使" +"用\n" +"されるものと一致しないようです。この場合以下の結果は不正確になります。ま" +"た、\n" +"PostgreSQLインストレーションはこのデータディレクトリと互換性がなくなりま" +"す。" + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "ファイル\"%s\"を書き出せませんでした: %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "ファイル\"%s\"をfsyncできませんでした: %m" + +#: pg_controldata.c:35 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s はPostgreSQLデータベースクラスタの制御情報を表示します。\n" +"\n" + +#: pg_controldata.c:36 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_controldata.c:37 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [OPTION] [DATADIR]\n" + +#: pg_controldata.c:38 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: pg_controldata.c:39 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR データディレクトリ\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_controldata.c:41 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_controldata.c:42 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable " +"PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"データディレクトリ(DATADIR)が指定されない場合、PGDATA環境変数が使用されま" +"す。\n" +"\n" + +#: pg_controldata.c:44 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "バグは<%s>に報告してください。\n" + +#: pg_controldata.c:45 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_controldata.c:55 +msgid "starting up" +msgstr "起動処理中" + +#: pg_controldata.c:57 +msgid "shut down" +msgstr "シャットダウン" + +#: pg_controldata.c:59 +msgid "shut down in recovery" +msgstr "リカバリ中にシャットダウンされている" + +#: pg_controldata.c:61 +msgid "shutting down" +msgstr "シャットダウン処理中" + +#: pg_controldata.c:63 +msgid "in crash recovery" +msgstr "クラッシュリカバリ中" + +#: pg_controldata.c:65 +msgid "in archive recovery" +msgstr "アーカイブリカバリ中" + +#: pg_controldata.c:67 +msgid "in production" +msgstr "運用中" + +#: pg_controldata.c:69 +msgid "unrecognized status code" +msgstr "未知のステータスコード" + +#: pg_controldata.c:84 +msgid "unrecognized wal_level" +msgstr "wal_level を認識できません" + +#: pg_controldata.c:137 pg_controldata.c:155 pg_controldata.c:163 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"を実行してください\n" + +#: pg_controldata.c:153 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "コマンドライン引数が多すぎます。(先頭は\"%s\")" + +#: pg_controldata.c:162 +#, c-format +msgid "no data directory specified" +msgstr "データディレクトリが指定されていません" + +#: pg_controldata.c:170 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this " +"program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"警告: CRCチェックサムの計算結果がファイル内の値と一致しません。\n" +"ファイルの破損、あるいは、本プログラムが想定するレイアウトと異なる\n" +"可能性があります。以下の結果は信頼できません。\n" +"\n" + +#: pg_controldata.c:179 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "警告: 不正なWALセグメントサイズ\n" + +#: pg_controldata.c:180 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"ファイル中のWALセグメントサイズは %d バイトとなっていますが、これは\n" +"1MBから1GBまでの2の累乗ではありません。このファイルは壊れており、\n" +"以下の情報は信頼できません。\n" +"\n" + +#: pg_controldata.c:222 +msgid "???" +msgstr "???" + +#: pg_controldata.c:228 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_controlバージョン番号: %u\n" + +#: pg_controldata.c:230 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "カタログバージョン番号: %u\n" + +#: pg_controldata.c:232 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "データベースシステム識別子: %llu\n" + +#: pg_controldata.c:234 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "データベースクラスタの状態: %s\n" + +#: pg_controldata.c:236 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "pg_control最終更新: %s\n" + +#: pg_controldata.c:238 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "最終チェックポイント位置: %X/%X\n" + +#: pg_controldata.c:241 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "最終チェックポイントのREDO位置: %X/%X\n" + +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "最終チェックポイントのREDO WALファイル: %s\n" + +#: pg_controldata.c:246 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "最終チェックポイントの時系列ID: %u\n" + +#: pg_controldata.c:248 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "最終チェックポイントのPrevTimeLineID: %u\n" + +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "最終チェックポイントのfull_page_writes: %s\n" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "off" +msgstr "オフ" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "on" +msgstr "オン" + +#: pg_controldata.c:252 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "最終チェックポイントのNextXID: %u:%u\n" + +#: pg_controldata.c:255 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "最終チェックポイントのNextOID: %u\n" + +#: pg_controldata.c:257 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "最終チェックポイントのNextMultiXactId: %u\n" + +#: pg_controldata.c:259 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "最終チェックポイントのNextMultiOffset: %u\n" + +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "最終チェックポイントのoldestXID: %u\n" + +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "最終チェックポイントのoldestXIDのDB: %u\n" + +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "最終チェックポイントのoldestActiveXID: %u\n" + +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "最終チェックポイントのoldestMultiXid: %u\n" + +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "最終チェックポイントのoldestMultiのDB: %u\n" + +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "最終チェックポイントのoldestCommitTsXid: %u\n" + +#: pg_controldata.c:273 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "最終チェックポイントのnewestCommitTsXid: %u\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "最終チェックポイント時刻: %s\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "UNLOGGEDリレーションの偽のLSNカウンタ: %X/%X\n" + +#: pg_controldata.c:280 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "最小リカバリ終了位置: %X/%X\n" + +#: pg_controldata.c:283 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "最小リカバリ終了位置のタイムライン: %u\n" + +#: pg_controldata.c:285 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "バックアップ開始位置: %X/%X\n" + +#: pg_controldata.c:288 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "バックアップ終了位置: %X/%X\n" + +#: pg_controldata.c:291 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "必要なバックアップ最終レコード: %s\n" + +#: pg_controldata.c:292 +msgid "no" +msgstr "いいえ" + +#: pg_controldata.c:292 +msgid "yes" +msgstr "はい" + +#: pg_controldata.c:293 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "wal_levelの設定: %s\n" + +#: pg_controldata.c:295 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "wal_log_hintsの設定: %s\n" + +#: pg_controldata.c:297 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "max_connectionsの設定: %d\n" + +#: pg_controldata.c:299 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "max_worker_processesの設定: %d\n" + +#: pg_controldata.c:301 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "max_wal_sendersの設定: %d\n" + +#: pg_controldata.c:303 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "max_prepared_xactsの設定: %d\n" + +#: pg_controldata.c:305 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "max_locks_per_xactの設定: %d\n" + +#: pg_controldata.c:307 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "track_commit_timestampの設定: %s\n" + +#: pg_controldata.c:309 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "最大データアラインメント: %u\n" + +#: pg_controldata.c:312 +#, c-format +msgid "Database block size: %u\n" +msgstr "データベースのブロックサイズ: %u\n" + +#: pg_controldata.c:314 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "大きなリレーションのセグメント毎のブロック数:%u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "WAL block size: %u\n" +msgstr "WALのブロックサイズ: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "WALセグメント当たりのバイト数: %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "識別子の最大長: %u\n" + +#: pg_controldata.c:322 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "インデックス内の最大列数: %u\n" + +#: pg_controldata.c:324 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "TOASTチャンクの最大サイズ: %u\n" + +#: pg_controldata.c:326 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "ラージオブジェクトチャンクのサイズ: %u\n" + +#: pg_controldata.c:329 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "日付/時刻型の格納方式: %s\n" + +#: pg_controldata.c:330 +msgid "64-bit integers" +msgstr "64ビット整数" + +#: pg_controldata.c:331 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Float8引数の渡し方: %s\n" + +#: pg_controldata.c:332 +msgid "by reference" +msgstr "参照渡し" + +#: pg_controldata.c:332 +msgid "by value" +msgstr "値渡し" + +#: pg_controldata.c:333 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "データベージチェックサムのバージョン: %u\n" + +#: pg_controldata.c:335 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "認証用の疑似nonce: %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: 読み取り用の\"%s\"ファイルのオープンに失敗しました: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: \"%s\"ファイルの読み取りに失敗しました: %s\n" + +#~ msgid "%s: could not read file \"%s\": read %d of %d\n" +#~ msgstr "" +#~ "%1$s: ファイル\"%2$s\"を読み込めませんでした: %4$dバイトのうち%3$dバイト" +#~ "を読み込みました\n" + +#~ msgid "Prior checkpoint location: %X/%X\n" +#~ msgstr "前回のチェックポイント位置: %X/%X\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help このヘルプを表示して、終了します\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version バージョン情報を表示して、終了します\n" + +#~ msgid "Float4 argument passing: %s\n" +#~ msgstr "Float4引数の渡し方: %s\n" diff --git a/src/bin/pg_controldata/po/ko.po b/src/bin/pg_controldata/po/ko.po new file mode 100644 index 000000000000..962b36ece728 --- /dev/null +++ b/src/bin/pg_controldata/po/ko.po @@ -0,0 +1,504 @@ +# Korean message translation file for PostgreSQL pg_controldata +# Ioseph Kim , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:46+0000\n" +"PO-Revision-Date: 2020-10-06 11:18+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean Team \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../common/controldata_utils.c:73 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" 파일을 읽기 모드로 열 수 없습니다: %m" + +#: ../../common/controldata_utils.c:89 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "\"%s\" 파일을 읽을 수 없습니다: %m" + +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "\"%s\" 파일을 읽을 수 없음: %d 읽음, 전체 %zu" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "\"%s\" 파일을 닫을 수 없습니다: %m" + +#: ../../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "바이트 순서 불일치" + +#: ../../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"바이트 순서가 일치하지 않습니다.\n" +"pg_control 파일을 저장하는 데 사용된 바이트 순서는 \n" +"이 프로그램에서 사용하는 순서와 일치해야 합니다. 이 경우 아래 결과는\n" +"올바르지 않으며 이 데이터 디렉터리에 PostgreSQL을 설치할 수 없습니다." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" 파일을 읽을 수 없습니다: %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" 파일을 쓸 수 없습니다: %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "\"%s\" 파일을 fsync 할 수 없습니다: %m" + +#: pg_controldata.c:35 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s 프로그램은 PostgreSQL 데이터베이스 클러스터의 제어정보를 보여줌.\n" +"\n" + +#: pg_controldata.c:36 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_controldata.c:37 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [옵션] [DATADIR]\n" + +#: pg_controldata.c:38 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"옵션들:\n" + +#: pg_controldata.c:39 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR 데이터 디렉터리\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보 보여주고 마침\n" + +#: pg_controldata.c:41 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_controldata.c:42 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable " +"PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"DATADIR인 데이터 디렉터리를 지정하지 않으며, PGDATA 환경 변수값을\n" +"사용합니다.\n" +"\n" + +#: pg_controldata.c:44 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "문제점 보고 주소: <%s>\n" + +#: pg_controldata.c:45 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: pg_controldata.c:55 +msgid "starting up" +msgstr "시작 중" + +#: pg_controldata.c:57 +msgid "shut down" +msgstr "중지됨" + +#: pg_controldata.c:59 +msgid "shut down in recovery" +msgstr "복구 작업 중 중지됨" + +#: pg_controldata.c:61 +msgid "shutting down" +msgstr "중지 중" + +#: pg_controldata.c:63 +msgid "in crash recovery" +msgstr "비정상 종료 복구 중" + +#: pg_controldata.c:65 +msgid "in archive recovery" +msgstr "자료 복구 중" + +#: pg_controldata.c:67 +msgid "in production" +msgstr "정상가동중" + +#: pg_controldata.c:69 +msgid "unrecognized status code" +msgstr "알수 없는 상태 코드" + +#: pg_controldata.c:84 +msgid "unrecognized wal_level" +msgstr "알 수 없는 wal_level" + +#: pg_controldata.c:137 pg_controldata.c:155 pg_controldata.c:163 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 자세한 정보는 \"%s --help\"\n" + +#: pg_controldata.c:153 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "너무 많은 명령행 인수를 지정했습니다. (처음 \"%s\")" + +#: pg_controldata.c:162 +#, c-format +msgid "no data directory specified" +msgstr "데이터 디렉터리를 지정하지 않았습니다" + +#: pg_controldata.c:170 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"경고: 계산된 CRC 체크섬값이 파일에 있는 값과 틀립니다.\n" +"이 경우는 파일이 손상되었거나, 이 프로그램과 컨트롤 파일의 버전이 틀린\n" +"경우입니다. 결과값들은 믿지 못할 값들이 출력될 수 있습니다.\n" +"\n" + +#: pg_controldata.c:179 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "경고: 잘못된 WAL 조각 크기\n" + +#: pg_controldata.c:180 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"저장된 WAL 조각 파일의 크기는 %d 바이트입니다. 이 값은 1MB부터 1GB사이\n" +"2^n 값이 아닙니다. 파일이 손상되었으며, 결과 또한 믿을 수 없습니다.\n" +"\n" + +#: pg_controldata.c:222 +msgid "???" +msgstr "???" + +#: pg_controldata.c:228 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_control 버전 번호: %u\n" + +#: pg_controldata.c:230 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "카탈로그 버전 번호: %u\n" + +#: pg_controldata.c:232 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "데이터베이스 시스템 식별자: %llu\n" + +#: pg_controldata.c:234 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "데이터베이스 클러스터 상태: %s\n" + +#: pg_controldata.c:236 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "pg_control 마지막 변경시간: %s\n" + +#: pg_controldata.c:238 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "마지막 체크포인트 위치: %X/%X\n" + +#: pg_controldata.c:241 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "마지막 체크포인트 REDO 위치: %X/%X\n" + +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "마지막 체크포인트 REDO WAL 파일: %s\n" + +#: pg_controldata.c:246 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "마지막 체크포인트 TimeLineID: %u\n" + +#: pg_controldata.c:248 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "마지막 체크포인트 PrevTimeLineID: %u\n" + +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "마지막 체크포인트 full_page_writes: %s\n" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "off" +msgstr "off" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "on" +msgstr "on" + +#: pg_controldata.c:252 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "마지막 체크포인트 NextXID: %u:%u\n" + +#: pg_controldata.c:255 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "마지막 체크포인트 NextOID: %u\n" + +#: pg_controldata.c:257 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "마지막 체크포인트 NextMultiXactId: %u\n" + +#: pg_controldata.c:259 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "마지막 체크포인트 NextMultiOffset: %u\n" + +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "마지막 체크포인트 제일오래된XID: %u\n" + +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "마지막 체크포인트 제일오래된XID의 DB: %u\n" + +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "마지막 체크포인트 제일오래된ActiveXID:%u\n" + +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "마지막 체크포인트 제일오래된MultiXid: %u\n" + +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "마지막 체크포인트 제일오래된멀티Xid DB:%u\n" + +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "마지막 체크포인트 제일오래된CommitTsXid:%u\n" + +#: pg_controldata.c:273 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "마지막 체크포인트 최신CommitTsXid: %u\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "마지막 체크포인트 시간: %s\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "언로그 릴레이션의 가짜 LSN 카운터: %X/%X\n" + +#: pg_controldata.c:280 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "최소 복구 마지막 위치: %X/%X\n" + +#: pg_controldata.c:283 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "최소 복구 종료 위치의 타임라인: %u\n" + +#: pg_controldata.c:285 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "백업 시작 위치: %X/%X\n" + +#: pg_controldata.c:288 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "백업 종료 위치: %X/%X\n" + +#: pg_controldata.c:291 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "백업 종료 레코드 필요 여부: %s\n" + +#: pg_controldata.c:292 +msgid "no" +msgstr "아니오" + +#: pg_controldata.c:292 +msgid "yes" +msgstr "예" + +#: pg_controldata.c:293 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "wal_level 설정값: %s\n" + +#: pg_controldata.c:295 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "wal_log_hints 설정값: %s\n" + +#: pg_controldata.c:297 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "max_connections 설정값: %d\n" + +#: pg_controldata.c:299 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "max_worker_processes 설정값: %d\n" + +#: pg_controldata.c:301 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "max_wal_senders 설정값: %d\n" + +#: pg_controldata.c:303 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "max_prepared_xacts 설정값: %d\n" + +#: pg_controldata.c:305 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "max_locks_per_xact 설정값: %d\n" + +#: pg_controldata.c:307 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "track_commit_timestamp 설정값: %s\n" + +#: pg_controldata.c:309 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "최대 자료 정렬: %u\n" + +#: pg_controldata.c:312 +#, c-format +msgid "Database block size: %u\n" +msgstr "데이터베이스 블록 크기: %u\n" + +#: pg_controldata.c:314 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "대형 릴레이션의 세그먼트당 블럭 개수: %u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "WAL block size: %u\n" +msgstr "WAL 블록 크기: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "WAL 세그먼트의 크기(byte): %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "식별자 최대 길이: %u\n" + +#: pg_controldata.c:322 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "인덱스에서 사용하는 최대 열 수: %u\n" + +#: pg_controldata.c:324 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "TOAST 청크 최대 크기: %u\n" + +#: pg_controldata.c:326 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "대형 객체 청크 크기: %u\n" + +#: pg_controldata.c:329 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "날짜/시간형 자료의 저장방식: %s\n" + +#: pg_controldata.c:330 +msgid "64-bit integers" +msgstr "64-비트 정수" + +#: pg_controldata.c:331 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Float8 인수 전달: %s\n" + +#: pg_controldata.c:332 +msgid "by reference" +msgstr "참조별" + +#: pg_controldata.c:332 +msgid "by value" +msgstr "값별" + +#: pg_controldata.c:333 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "데이터 페이지 체크섬 버전: %u\n" + +#: pg_controldata.c:335 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "임시 모의 인증: %s\n" diff --git a/src/bin/pg_controldata/po/ru.po b/src/bin/pg_controldata/po/ru.po new file mode 100644 index 000000000000..39343c05a1aa --- /dev/null +++ b/src/bin/pg_controldata/po/ru.po @@ -0,0 +1,585 @@ +# Russian message translation file for pg_controldata +# Copyright (C) 2002-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Serguei A. Mokhov , 2002-2004. +# Oleg Bartunov , 2004. +# Andrey Sudnik , 2011. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2020-09-03 13:28+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../common/controldata_utils.c:73 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не удалось открыть файл \"%s\" для чтения: %m" + +#: ../../common/controldata_utils.c:89 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %zu)" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: ../../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "несоответствие порядка байт" + +#: ../../common/controldata_utils.c:137 +#, c-format +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"возможно несоответствие порядка байт\n" +"Порядок байт в файле pg_control может не соответствовать используемому\n" +"этой программой. В этом случае результаты будут неверными и\n" +"установленный PostgreSQL будет несовместим с этим каталогом данных." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не удалось записать файл \"%s\": %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: pg_controldata.c:35 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s показывает информацию о работе кластера баз PostgreSQL.\n" +"\n" + +#: pg_controldata.c:36 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: pg_controldata.c:37 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [ПАРАМЕТР] [КАТ_ДАННЫХ]\n" + +#: pg_controldata.c:38 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Параметры:\n" + +#: pg_controldata.c:39 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]КАТ_ДАННЫХ каталог данных\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_controldata.c:41 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_controldata.c:42 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable " +"PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Если каталог данных не задан, используется значение переменной окружения " +"PGDATA.\n" +"\n" + +#: pg_controldata.c:44 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_controldata.c:45 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_controldata.c:55 +msgid "starting up" +msgstr "запускается" + +#: pg_controldata.c:57 +msgid "shut down" +msgstr "выключен" + +#: pg_controldata.c:59 +msgid "shut down in recovery" +msgstr "выключен при восстановлении" + +#: pg_controldata.c:61 +msgid "shutting down" +msgstr "выключение" + +#: pg_controldata.c:63 +msgid "in crash recovery" +msgstr "восстановление после сбоя" + +#: pg_controldata.c:65 +msgid "in archive recovery" +msgstr "восстановление из архива" + +#: pg_controldata.c:67 +msgid "in production" +msgstr "в работе" + +#: pg_controldata.c:69 +msgid "unrecognized status code" +msgstr "нераспознанный код состояния" + +#: pg_controldata.c:84 +msgid "unrecognized wal_level" +msgstr "нераспознанный уровень WAL" + +#: pg_controldata.c:137 pg_controldata.c:155 pg_controldata.c:163 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_controldata.c:153 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: pg_controldata.c:162 +#, c-format +msgid "no data directory specified" +msgstr "каталог данных не указан" + +#: pg_controldata.c:170 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"ПРЕДУПРЕЖДЕНИЕ: Вычисленная контрольная сумма не совпадает со значением в " +"файле.\n" +"Либо файл повреждён, либо его формат отличается от ожидаемого.\n" +"Следующая информация может быть недостоверной.\n" +"\n" + +#: pg_controldata.c:179 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "ПРЕДУПРЕЖДЕНИЕ: неверный размер сегмента WAL\n" + +#: pg_controldata.c:180 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"Сохранённый в этом файле размер сегмента WAL (байт: %d) не является " +"степенью\n" +"двух между 1 МБ и 1 ГБ. Файл испорчен, выводимая ниже информация\n" +"подлежит сомнению.\n" +"\n" +msgstr[1] "" +"Сохранённый в этом файле размер сегмента WAL (байт: %d) не является " +"степенью\n" +"двух между 1 МБ и 1 ГБ. Файл испорчен, выводимая ниже информация\n" +"подлежит сомнению.\n" +"\n" +msgstr[2] "" +"Сохранённый в этом файле размер сегмента WAL (байт: %d) не является " +"степенью\n" +"двух между 1 МБ и 1 ГБ. Файл испорчен, выводимая ниже информация\n" +"подлежит сомнению.\n" +"\n" + +#: pg_controldata.c:222 +msgid "???" +msgstr "???" + +#: pg_controldata.c:228 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "Номер версии pg_control: %u\n" + +#: pg_controldata.c:230 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Номер версии каталога: %u\n" + +#: pg_controldata.c:232 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "Идентификатор системы баз данных: %llu\n" + +#: pg_controldata.c:234 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "Состояние кластера БД: %s\n" + +#: pg_controldata.c:236 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "Последнее обновление pg_control: %s\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:238 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "Положение последней конт. точки: %X/%X\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:241 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "Положение REDO последней конт. точки: %X/%X\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "Файл WAL c REDO последней к. т.: %s\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:246 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "Линия времени последней конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:248 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "Пред. линия времени последней к. т.: %u\n" + +# skip-rule: no-space-after-period +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Режим full_page_writes последней к.т: %s\n" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "off" +msgstr "выкл." + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 +msgid "on" +msgstr "вкл." + +# skip-rule: capital-letter-first +#: pg_controldata.c:252 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID последней конт. точки: %u:%u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:255 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "NextOID последней конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:257 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "NextMultiXactId послед. конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:259 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "NextMultiOffset послед. конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "oldestXID последней конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "БД с oldestXID последней конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "oldestActiveXID последней к. т.: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "oldestMultiXid последней конт. точки: %u\n" + +# skip-rule: double-space, capital-letter-first +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "БД с oldestMulti последней к. т.: %u\n" + +# skip-rule: double-space, capital-letter-first +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "oldestCommitTsXid последней к. т.: %u\n" + +# skip-rule: capital-letter-first, double-space +#: pg_controldata.c:273 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "newestCommitTsXid последней к. т.: %u\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "Время последней контрольной точки: %s\n" + +# skip-rule: capital-letter-first +# well-spelled: нежурналир +#: pg_controldata.c:277 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "Фиктивный LSN для нежурналир. таблиц: %X/%X\n" + +#: pg_controldata.c:280 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "Мин. положение конца восстановления: %X/%X\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:283 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "Линия времени мин. положения к. в.: %u\n" + +#: pg_controldata.c:285 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "Положение начала копии: %X/%X\n" + +#: pg_controldata.c:288 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "Положение конца копии: %X/%X\n" + +#: pg_controldata.c:291 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "Требуется запись конец-копии: %s\n" + +#: pg_controldata.c:292 +msgid "no" +msgstr "нет" + +#: pg_controldata.c:292 +msgid "yes" +msgstr "да" + +#: pg_controldata.c:293 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "Значение wal_level: %s\n" + +#: pg_controldata.c:295 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "Значение wal_log_hints: %s\n" + +#: pg_controldata.c:297 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "Значение max_connections: %d\n" + +#: pg_controldata.c:299 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "Значение max_worker_processes: %d\n" + +#: pg_controldata.c:301 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "Значение max_wal_senders: %d\n" + +#: pg_controldata.c:303 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "Значение max_prepared_xacts: %d\n" + +#: pg_controldata.c:305 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "Значение max_locks_per_xact: %d\n" + +#: pg_controldata.c:307 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "Значение track_commit_timestamp: %s\n" + +#: pg_controldata.c:309 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Макс. предел выравнивания данных: %u\n" + +#: pg_controldata.c:312 +#, c-format +msgid "Database block size: %u\n" +msgstr "Размер блока БД: %u\n" + +# skip-rule: double-space +#: pg_controldata.c:314 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Блоков в макс. сегменте отношений: %u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Размер блока WAL: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Байт в сегменте WAL: %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Максимальная длина идентификаторов: %u\n" + +#: pg_controldata.c:322 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Макс. число столбцов в индексе: %u\n" + +#: pg_controldata.c:324 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Максимальный размер порции TOAST: %u\n" + +#: pg_controldata.c:326 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Размер порции большого объекта: %u\n" + +#: pg_controldata.c:329 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Формат хранения даты/времени: %s\n" + +#: pg_controldata.c:330 +msgid "64-bit integers" +msgstr "64-битные целые" + +#: pg_controldata.c:331 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Передача аргумента float8: %s\n" + +#: pg_controldata.c:332 +msgid "by reference" +msgstr "по ссылке" + +#: pg_controldata.c:332 +msgid "by value" +msgstr "по значению" + +#: pg_controldata.c:333 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Версия контрольных сумм страниц: %u\n" + +# skip-rule: capital-letter-first +#: pg_controldata.c:335 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "Случ. число для псевдоаутентификации: %s\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Об ошибках сообщайте по адресу .\n" + +#~ msgid "Float4 argument passing: %s\n" +#~ msgstr "Передача аргумента Float4: %s\n" + +# skip-rule: capital-letter-first +#~ msgid "Prior checkpoint location: %X/%X\n" +#~ msgstr "Положение предыдущей конт. точки: %X/%X\n" + +#~ msgid "calculated CRC checksum does not match value stored in file" +#~ msgstr "" +#~ "вычисленная контрольная сумма (CRC) не соответствует значению, " +#~ "сохранённому в файле" + +#~ msgid "floating-point numbers" +#~ msgstr "числа с плавающей точкой" + +#~ msgid "" +#~ "Usage:\n" +#~ " %s [OPTION] [DATADIR]\n" +#~ "\n" +#~ "Options:\n" +#~ " --help show this help, then exit\n" +#~ " --version output version information, then exit\n" +#~ msgstr "" +#~ "Использование:\n" +#~ " %s [ПАРАМЕТР] [КАТАЛОГ_ДАННЫХ]\n" +#~ "\n" +#~ "Параметры:\n" +#~ " --help показать эту справку и выйти\n" +#~ " --version показать версию и выйти\n" + +#~ msgid "enabled" +#~ msgstr "включен" + +#~ msgid "disabled" +#~ msgstr "отключен" diff --git a/src/bin/pg_controldata/po/uk.po b/src/bin/pg_controldata/po/uk.po index 345263acd788..23c5dfb71482 100644 --- a/src/bin/pg_controldata/po/uk.po +++ b/src/bin/pg_controldata/po/uk.po @@ -1,87 +1,108 @@ msgid "" msgstr "" "Project-Id-Version: postgresql\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2018-12-04 20:35+0100\n" -"PO-Revision-Date: 2019-07-11 16:20\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:17+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" "Last-Translator: pasha_golub\n" "Language-Team: Ukrainian\n" -"Language: uk_UA\n" +"Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" -"X-Generator: crowdin.com\n" "X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" "X-Crowdin-Language: uk\n" -"X-Crowdin-File: /REL_11_STABLE/src/bin/pg_controldata/po/pg_controldata.pot\n" +"X-Crowdin-File: /DEV_13/pg_controldata.pot\n" +"X-Crowdin-File-ID: 496\n" -#: ../../common/controldata_utils.c:62 +#: ../../common/controldata_utils.c:73 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: не вдалося відкрити файл \"%s\" для читання: %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "не вдалося відкрити файл \"%s\" для читання: %m" -#: ../../common/controldata_utils.c:78 +#: ../../common/controldata_utils.c:89 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: не вдалося прочитати файл \"%s\": %s\n" +msgid "could not read file \"%s\": %m" +msgstr "не вдалося прочитати файл \"%s\": %m" -#: ../../common/controldata_utils.c:90 +#: ../../common/controldata_utils.c:101 #, c-format -msgid "%s: could not read file \"%s\": read %d of %d\n" -msgstr "%s: не вдалося прочитати файл \"%s\": прочитано %d з %d\n" +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не вдалося прочитати файл \"%s\": прочитано %d з %zu" -#: ../../common/controldata_utils.c:112 +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "неможливо закрити файл \"%s\": %m" + +#: ../../common/controldata_utils.c:135 msgid "byte ordering mismatch" msgstr "неправильний порядок байтів" -#: ../../common/controldata_utils.c:114 +#: ../../common/controldata_utils.c:137 #, c-format -msgid "WARNING: possible byte ordering mismatch\n" +msgid "possible byte ordering mismatch\n" "The byte ordering used to store the pg_control file might not match the one\n" "used by this program. In that case the results below would be incorrect, and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" -msgstr "УВАГА: можлива помилка у послідовності байтів \n" -"Порядок байтів, що використовують для зберігання файлу pg_control може не відповідати тому, який використовується цією програмою. У такому випадку результати нижче будуть неправильним, і інсталяція PostgreSQL буде несумісною з цим каталогом даних.\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "можлива помилка у послідовності байтів.\n" +"Порядок байтів, що використовують для зберігання файлу pg_control, може не відповідати тому, який використовується цією програмою. У такому випадку результати нижче будуть неправильним, і інсталяція PostgreSQL буде несумісною з цим каталогом даних." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" -#: pg_controldata.c:34 +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не вдалося записати файл \"%s\": %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "не вдалося fsync файл \"%s\": %m" + +#: pg_controldata.c:35 #, c-format msgid "%s displays control information of a PostgreSQL database cluster.\n\n" msgstr "%s відображає контрольну інформацію щодо кластеру PostgreSQL.\n\n" -#: pg_controldata.c:35 +#: pg_controldata.c:36 #, c-format msgid "Usage:\n" msgstr "Використання:\n" -#: pg_controldata.c:36 +#: pg_controldata.c:37 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [OPTION] [DATADIR]\n" -#: pg_controldata.c:37 +#: pg_controldata.c:38 #, c-format msgid "\n" "Options:\n" msgstr "\n" "Параметри:\n" -#: pg_controldata.c:38 +#: pg_controldata.c:39 #, c-format msgid " [-D, --pgdata=]DATADIR data directory\n" msgstr " [-D, --pgdata=]DATADIR каталог з даними\n" -#: pg_controldata.c:39 +#: pg_controldata.c:40 #, c-format msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version вивести інформацію про версію і вийти\n" +msgstr " -V, --version вивести інформацію про версію і вийти\n" -#: pg_controldata.c:40 +#: pg_controldata.c:41 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показати цю довідку потім вийти\n" -#: pg_controldata.c:41 +#: pg_controldata.c:42 #, c-format msgid "\n" "If no data directory (DATADIR) is specified, the environment variable PGDATA\n" @@ -89,75 +110,80 @@ msgid "\n" msgstr "\n" "Якщо каталог даних не вказано (DATADIR), використовується змінна середовища PGDATA.\n\n" -#: pg_controldata.c:43 +#: pg_controldata.c:44 #, c-format -msgid "Report bugs to .\n" -msgstr "Про помилки повідомляйте .\n" +msgid "Report bugs to <%s>.\n" +msgstr "Повідомляти про помилки на <%s>.\n" -#: pg_controldata.c:53 +#: pg_controldata.c:45 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: pg_controldata.c:55 msgid "starting up" msgstr "запуск" -#: pg_controldata.c:55 +#: pg_controldata.c:57 msgid "shut down" msgstr "завершення роботи" -#: pg_controldata.c:57 +#: pg_controldata.c:59 msgid "shut down in recovery" msgstr "завершення роботи у відновленні" -#: pg_controldata.c:59 +#: pg_controldata.c:61 msgid "shutting down" msgstr "завершення роботи" -#: pg_controldata.c:61 +#: pg_controldata.c:63 msgid "in crash recovery" msgstr "відновлення при збої" -#: pg_controldata.c:63 +#: pg_controldata.c:65 msgid "in archive recovery" msgstr "відновлення в архіві" -#: pg_controldata.c:65 +#: pg_controldata.c:67 msgid "in production" msgstr "у виробництві" -#: pg_controldata.c:67 +#: pg_controldata.c:69 msgid "unrecognized status code" msgstr "невизнаний код статусу" -#: pg_controldata.c:82 +#: pg_controldata.c:84 msgid "unrecognized wal_level" msgstr "невизнаний wal_рівень" -#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 +#: pg_controldata.c:137 pg_controldata.c:155 pg_controldata.c:163 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" -#: pg_controldata.c:152 +#: pg_controldata.c:153 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: забагато аргументів у командному рядку (перший \"%s\")\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" -#: pg_controldata.c:161 +#: pg_controldata.c:162 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: каталог даних не вказано\n" +msgid "no data directory specified" +msgstr "каталог даних не вказано" -#: pg_controldata.c:169 +#: pg_controldata.c:170 #, c-format msgid "WARNING: Calculated CRC checksum does not match value stored in file.\n" "Either the file is corrupt, or it has a different layout than this program\n" "is expecting. The results below are untrustworthy.\n\n" msgstr "ПОПЕРЕДЖЕННЯ: Контрольна сума CRC не відповідає збереженому значенню у файлі. Або файл пошкоджено, або він містить іншу структуру, ніж очікує ця програма. Результати нижче є недостовірними.\n\n" -#: pg_controldata.c:178 +#: pg_controldata.c:179 #, c-format msgid "WARNING: invalid WAL segment size\n" msgstr "ПОПЕРЕДЖЕННЯ: неправильний розмір WAL сегменту \n" -#: pg_controldata.c:179 +#: pg_controldata.c:180 #, c-format msgid "The WAL segment size stored in the file, %d byte, is not a power of two\n" "between 1 MB and 1 GB. The file is corrupt and the results below are\n" @@ -170,284 +196,284 @@ msgstr[1] "Розмір WAL сегменту збережений у файлі, msgstr[2] "Розмір WAL сегменту збережений у файлі, %d байтів, не є степенем двійки між 1 MB та 1 GB. Файл пошкоджено та результати нижче є недостовірними.\n\n" msgstr[3] "Розмір WAL сегменту збережений у файлі, %d байта, не є степенем двійки між 1 MB та 1 GB. Файл пошкоджено та результати нижче є недостовірними.\n\n" -#: pg_controldata.c:221 +#: pg_controldata.c:222 msgid "???" msgstr "???" -#: pg_controldata.c:234 +#: pg_controldata.c:228 #, c-format msgid "pg_control version number: %u\n" msgstr "pg_control номер версії: %u\n" -#: pg_controldata.c:236 +#: pg_controldata.c:230 #, c-format msgid "Catalog version number: %u\n" msgstr "Номер версії каталогу: %u\n" -#: pg_controldata.c:238 +#: pg_controldata.c:232 #, c-format -msgid "Database system identifier: %s\n" -msgstr "Системний ідентифікатор бази даних: %s\n" +msgid "Database system identifier: %llu\n" +msgstr "Системний ідентифікатор бази даних: %llu\n" -#: pg_controldata.c:240 +#: pg_controldata.c:234 #, c-format msgid "Database cluster state: %s\n" msgstr "Стан кластеру бази даних: %s\n" -#: pg_controldata.c:242 +#: pg_controldata.c:236 #, c-format msgid "pg_control last modified: %s\n" msgstr "pg_control був модифікований востаннє: %s\n" -#: pg_controldata.c:244 +#: pg_controldata.c:238 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "Останнє місце знаходження контрольної точки: %X/%X\n" -#: pg_controldata.c:247 +#: pg_controldata.c:241 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "Розташування останньої контрольної точки: %X%X\n" -#: pg_controldata.c:250 +#: pg_controldata.c:244 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "Останній файл контрольної точки REDO WAL: %s\n" -#: pg_controldata.c:252 +#: pg_controldata.c:246 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "Останній TimeLineID контрольної точки: %u\n" -#: pg_controldata.c:254 +#: pg_controldata.c:248 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "Останній PrevTimeLineID контрольної точки: %u\n" -#: pg_controldata.c:256 +#: pg_controldata.c:250 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "Останній full_page_writes контрольної точки: %s\n" -#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 msgid "off" -msgstr "вимк." +msgstr "вимк" -#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:308 msgid "on" -msgstr "увімк." +msgstr "увімк" -#: pg_controldata.c:258 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "Останній NextXID контрольної точки: %u%u\n" -#: pg_controldata.c:261 +#: pg_controldata.c:255 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "Останній NextOID контрольної точки: %u\n" -#: pg_controldata.c:263 +#: pg_controldata.c:257 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "Останній NextMultiXactId контрольної точки: %u\n" -#: pg_controldata.c:265 +#: pg_controldata.c:259 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "Останній NextMultiOffset контрольної точки: %u\n" -#: pg_controldata.c:267 +#: pg_controldata.c:261 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "Останній oldestXID контрольної точки: %u\n" -#: pg_controldata.c:269 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "Остання DB останнього oldestXID контрольної точки: %u\n" -#: pg_controldata.c:271 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "Останній oldestActiveXID контрольної точки: %u\n" -#: pg_controldata.c:273 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "Останній oldestMultiXid контрольної точки: %u \n" -#: pg_controldata.c:275 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "Остання DB останньої oldestMulti контрольної точки: %u\n" -#: pg_controldata.c:277 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "Останній oldestCommitTsXid контрольної точки:%u\n" -#: pg_controldata.c:279 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "Останній newestCommitTsXid контрольної точки: %u\n" -#: pg_controldata.c:281 +#: pg_controldata.c:275 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "Час останньої контрольної точки: %s\n" -#: pg_controldata.c:283 +#: pg_controldata.c:277 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "Фіктивний LSN для таблиць без журналювання: %X/%X\n" -#: pg_controldata.c:286 +#: pg_controldata.c:280 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "Мінімальне розташування кінця відновлення: %X/%X\n" -#: pg_controldata.c:289 +#: pg_controldata.c:283 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "Мінімальна позиція історії часу завершення відновлення: %u\n" -#: pg_controldata.c:291 +#: pg_controldata.c:285 #, c-format msgid "Backup start location: %X/%X\n" msgstr "Початкове розташування резервного копіювання: %X/%X\n" -#: pg_controldata.c:294 +#: pg_controldata.c:288 #, c-format msgid "Backup end location: %X/%X\n" msgstr "Кінцеве розташування резервного копіювання: %X/%X\n" -#: pg_controldata.c:297 +#: pg_controldata.c:291 #, c-format msgid "End-of-backup record required: %s\n" msgstr "Вимагається запис кінця резервного копіювання: %s\n" -#: pg_controldata.c:298 +#: pg_controldata.c:292 msgid "no" msgstr "ні" -#: pg_controldata.c:298 +#: pg_controldata.c:292 msgid "yes" msgstr "так" -#: pg_controldata.c:299 +#: pg_controldata.c:293 #, c-format msgid "wal_level setting: %s\n" msgstr "налаштування wal_рівня: %s\n" -#: pg_controldata.c:301 +#: pg_controldata.c:295 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "налаштування wal_log_hints: %s\n" -#: pg_controldata.c:303 +#: pg_controldata.c:297 #, c-format msgid "max_connections setting: %d\n" msgstr "налаштування max_connections: %d\n" -#: pg_controldata.c:305 +#: pg_controldata.c:299 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "налаштування max_worker_processes: %d\n" -#: pg_controldata.c:307 +#: pg_controldata.c:301 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "налаштування max_wal_senders: %d\n" + +#: pg_controldata.c:303 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "налаштування max_prepared_xacts: %d\n" -#: pg_controldata.c:309 +#: pg_controldata.c:305 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "налаштування max_locks_per_xact: %d\n" -#: pg_controldata.c:311 +#: pg_controldata.c:307 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "налаштування track_commit_timestamp: %s\n" -#: pg_controldata.c:313 +#: pg_controldata.c:309 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Максимальне вирівнювання даних: %u\n" -#: pg_controldata.c:316 +#: pg_controldata.c:312 #, c-format msgid "Database block size: %u\n" msgstr "Розмір блоку бази даних: %u\n" -#: pg_controldata.c:318 +#: pg_controldata.c:314 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Блоків на сегмент великого відношення: %u\n" -#: pg_controldata.c:320 +#: pg_controldata.c:316 #, c-format msgid "WAL block size: %u\n" msgstr "Pозмір блоку WAL: %u\n" -#: pg_controldata.c:322 +#: pg_controldata.c:318 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Байтів на сегмент WAL: %u\n" -#: pg_controldata.c:324 +#: pg_controldata.c:320 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Максимальна довжина ідентифікаторів: %u\n" -#: pg_controldata.c:326 +#: pg_controldata.c:322 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Максимальна кількість стовпців в індексі: %u\n" -#: pg_controldata.c:328 +#: pg_controldata.c:324 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Максимальний розмір сегменту TOAST: %u\n" -#: pg_controldata.c:330 +#: pg_controldata.c:326 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Розмір сегменту великих обїєктів: %u\n" -#: pg_controldata.c:333 +#: pg_controldata.c:329 #, c-format msgid "Date/time type storage: %s\n" msgstr "Дата/час типу сховища: %s\n" -#: pg_controldata.c:334 +#: pg_controldata.c:330 msgid "64-bit integers" msgstr "64-бітні цілі" -#: pg_controldata.c:335 +#: pg_controldata.c:331 #, c-format -msgid "Float4 argument passing: %s\n" -msgstr "Передача аргументу Float4: %s\n" +msgid "Float8 argument passing: %s\n" +msgstr "Передача аргументу Float8: %s\n" -#: pg_controldata.c:336 pg_controldata.c:338 +#: pg_controldata.c:332 msgid "by reference" msgstr "за посиланням" -#: pg_controldata.c:336 pg_controldata.c:338 +#: pg_controldata.c:332 msgid "by value" msgstr "за значенням" -#: pg_controldata.c:337 -#, c-format -msgid "Float8 argument passing: %s\n" -msgstr "Передача аргументу Float8: %s\n" - -#: pg_controldata.c:339 +#: pg_controldata.c:333 #, c-format msgid "Data page checksum version: %u\n" msgstr "Версія контрольних сум сторінок даних: %u\n" -#: pg_controldata.c:341 +#: pg_controldata.c:335 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "Імітувати нонс для аутентифікації: %s\n" diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl index 3b63ad230fc3..c3f3aca095c8 100644 --- a/src/bin/pg_controldata/t/001_pg_controldata.pl +++ b/src/bin/pg_controldata/t/001_pg_controldata.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use PostgresNode; diff --git a/src/bin/pg_ctl/Makefile b/src/bin/pg_ctl/Makefile index 14602c118512..5d5f5372a3f0 100644 --- a/src/bin/pg_ctl/Makefile +++ b/src/bin/pg_ctl/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_ctl # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/pg_ctl/Makefile diff --git a/src/bin/pg_ctl/nls.mk b/src/bin/pg_ctl/nls.mk index 1a8a4bafe123..15b5b4851a20 100644 --- a/src/bin/pg_ctl/nls.mk +++ b/src/bin/pg_ctl/nls.mk @@ -1,4 +1,4 @@ # src/bin/pg_ctl/nls.mk CATALOG_NAME = pg_ctl -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr uk zh_CN +AVAIL_LANGUAGES = cs de el es fr he it ja ko pl pt_BR ru sv tr uk zh_CN GETTEXT_FILES = pg_ctl.c ../../common/exec.c ../../common/fe_memutils.c ../../common/wait_error.c ../../port/path.c diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index c676d8236e98..fbcbda975cac 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -2,7 +2,7 @@ * * pg_ctl --- start/stops/restarts the PostgreSQL server * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * * src/bin/pg_ctl/pg_ctl.c * @@ -932,11 +932,10 @@ do_start(void) */ #ifndef WIN32 { - static char env_var[32]; + char env_var[32]; - snprintf(env_var, sizeof(env_var), "PG_GRANDPARENT_PID=%d", - (int) getppid()); - putenv(env_var); + snprintf(env_var, sizeof(env_var), "%d", (int) getppid()); + setenv("PG_GRANDPARENT_PID", env_var, 1); } #endif @@ -1975,7 +1974,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser Advapi32Handle = LoadLibrary("ADVAPI32.DLL"); if (Advapi32Handle != NULL) { - _CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken"); + _CreateRestrictedToken = (__CreateRestrictedToken) (pg_funcptr_t) GetProcAddress(Advapi32Handle, "CreateRestrictedToken"); } if (_CreateRestrictedToken == NULL) @@ -2049,11 +2048,11 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser Kernel32Handle = LoadLibrary("KERNEL32.DLL"); if (Kernel32Handle != NULL) { - _IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob"); - _CreateJobObject = (__CreateJobObject) GetProcAddress(Kernel32Handle, "CreateJobObjectA"); - _SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject"); - _AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject"); - _QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject"); + _IsProcessInJob = (__IsProcessInJob) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "IsProcessInJob"); + _CreateJobObject = (__CreateJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "CreateJobObjectA"); + _SetInformationJobObject = (__SetInformationJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "SetInformationJobObject"); + _AssignProcessToJobObject = (__AssignProcessToJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject"); + _QueryInformationJobObject = (__QueryInformationJobObject) (pg_funcptr_t) GetProcAddress(Kernel32Handle, "QueryInformationJobObject"); } /* Verify that we found all functions */ @@ -2547,12 +2546,10 @@ main(int argc, char **argv) case 'D': { char *pgdata_D; - char *env_var; pgdata_D = pg_strdup(optarg); canonicalize_path(pgdata_D); - env_var = psprintf("PGDATA=%s", pgdata_D); - putenv(env_var); + setenv("PGDATA", pgdata_D, 1); /* * We could pass PGDATA just in an environment @@ -2560,6 +2557,7 @@ main(int argc, char **argv) * 'ps' display */ pgdata_opt = psprintf("-D \"%s\" ", pgdata_D); + free(pgdata_D); break; } case 'e': diff --git a/src/bin/pg_ctl/po/cs.po b/src/bin/pg_ctl/po/cs.po new file mode 100644 index 000000000000..c7b3237b8c2c --- /dev/null +++ b/src/bin/pg_ctl/po/cs.po @@ -0,0 +1,945 @@ +# Czech message translation file for pg_ctl +# Copyright (C) 2012 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Tomas Vondra , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: pg_ctl-cs (PostgreSQL 9.3)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:14+0000\n" +"PO-Revision-Date: 2020-10-31 21:30+0100\n" +"Last-Translator: Tomas Vondra \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.4.1\n" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "nelze identifikovat aktuální adresář: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "neplatný binární soubor\"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "nelze číst binární soubor \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "nelze najít soubor \"%s\" ke spuštění" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "nelze změnit adresář na \"%s\" : %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "nelze přečíst symbolický odkaz \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "volání pclose selhalo: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "nedostatek paměti" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek paměti\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nelze duplikovat null pointer (interní chyba)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "příkaz není spustitelný" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "příkaz nenalezen" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "potomek skončil s návratovým kódem %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "potomek byl ukončen vyjímkou 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "potomek byl ukončen signálem %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "potomek skončil s nerozponaným stavem %d" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "nelze získat aktuální pracovní adresář: %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: adresář \"%s\" neexistuje\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: nelze otevřít adresář \"%s\": %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: adresář \"%s\" není datový adresář databázového clusteru\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: nelze otevřít PID soubor \"%s\": %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: PID soubor \"%s\" je prázdný\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: neplatná data v PID souboru \"%s\"\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: nelze nastartovat server: %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: nelze nastartovat server kvůli selhání setsid(): %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: nelze otevřít logovací soubor \"%s\": %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: nelze nastartovat server: chybový kód %lu\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "%s: nelze nastavit limit pro core soubor; zakázáno hard limitem\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: nelze číst soubor \"%s\"\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: soubor s volbami \"%s\" musí mít přesně jednu řádku\n" + +#: pg_ctl.c:785 pg_ctl.c:975 pg_ctl.c:1071 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: nelze poslat stop signál (PID: %ld): %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"Program \"%s\" je vyžadován aplikací %s, ale nebyl nalezen ve stejném\n" +"adresáři jako \"%s\".\n" +"Zkontrolujte vaši instalaci.\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"Program \"%s\" byl nalezen pomocí \"%s\",\n" +"ale nebyl ve stejné verzi jako %s.\n" +"Zkontrolujte vaši instalaci.\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: inicializace databáze selhala\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "%s: další server možná běží; i tak zkouším start\n" + +#: pg_ctl.c:915 +msgid "waiting for server to start..." +msgstr "čekám na start serveru ..." + +#: pg_ctl.c:920 pg_ctl.c:1025 pg_ctl.c:1117 pg_ctl.c:1247 +msgid " done\n" +msgstr " hotovo\n" + +#: pg_ctl.c:921 +msgid "server started\n" +msgstr "server spuštěn\n" + +#: pg_ctl.c:924 pg_ctl.c:930 pg_ctl.c:1252 +msgid " stopped waiting\n" +msgstr " přestávám čekat\n" + +#: pg_ctl.c:925 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: server nenastartoval v časovém limitu\n" + +#: pg_ctl.c:931 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: nelze spustit server\n" +"Zkontrolujte záznam v logu.\n" + +#: pg_ctl.c:939 +msgid "server starting\n" +msgstr "server startuje\n" + +#: pg_ctl.c:960 pg_ctl.c:1047 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1276 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: PID soubor \"%s\" neexistuje\n" + +#: pg_ctl.c:961 pg_ctl.c:1049 pg_ctl.c:1139 pg_ctl.c:1178 pg_ctl.c:1277 +msgid "Is server running?\n" +msgstr "Běží server?\n" + +#: pg_ctl.c:967 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "%s: nemohu zastavit server; postgres běží v single-user módu (PID: %ld)\n" + +#: pg_ctl.c:982 +msgid "server shutting down\n" +msgstr "server se ukončuje\n" + +#: pg_ctl.c:997 pg_ctl.c:1086 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"VAROVÁNÍ: online backup mód je aktivní\n" +"Shutdown nebude ukončen dokud nebude zavolán pg_stop_backup().\n" +"\n" + +#: pg_ctl.c:1001 pg_ctl.c:1090 +msgid "waiting for server to shut down..." +msgstr "čekám na ukončení serveru ..." + +#: pg_ctl.c:1017 pg_ctl.c:1108 +msgid " failed\n" +msgstr " selhalo\n" + +#: pg_ctl.c:1019 pg_ctl.c:1110 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: server se neukončuje\n" + +#: pg_ctl.c:1021 pg_ctl.c:1112 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"TIP: Volba \"-m fast\" okamžitě ukončí sezení namísto aby čekala\n" +"na odpojení iniciované přímo session.\n" + +#: pg_ctl.c:1027 pg_ctl.c:1118 +msgid "server stopped\n" +msgstr "server zastaven\n" + +#: pg_ctl.c:1050 +msgid "trying to start server anyway\n" +msgstr "přesto zkouším server spustit\n" + +#: pg_ctl.c:1059 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "%s: nemohu restartovat server; postgres běží v single-user módu (PID: %ld)\n" + +#: pg_ctl.c:1062 pg_ctl.c:1148 +msgid "Please terminate the single-user server and try again.\n" +msgstr "Prosím ukončete single-user postgres a zkuste to znovu.\n" + +#: pg_ctl.c:1122 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: starý proces serveru (PID: %ld) zřejmě skončil\n" + +#: pg_ctl.c:1124 +msgid "starting server anyway\n" +msgstr "přesto server spouštím\n" + +#: pg_ctl.c:1145 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "%s: nemohu znovunačíst server; server běží v single-user módu (PID: %ld)\n" + +#: pg_ctl.c:1154 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: nelze poslat signál pro reload (PID: %ld): %s\n" + +#: pg_ctl.c:1159 +msgid "server signaled\n" +msgstr "server obdržel signál\n" + +#: pg_ctl.c:1184 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "%s: nelze povýšit (promote) server; server běží v single-user módu (PID: %ld)\n" + +#: pg_ctl.c:1192 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s: nelze povýšit (promote) server; server není ve standby módu\n" + +#: pg_ctl.c:1207 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: nelze vytvořit signální soubor pro povýšení (promote) \"%s\": %s\n" + +#: pg_ctl.c:1213 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: nelze zapsat do signálního souboru pro povýšení (promote) \"%s\": %s\n" + +#: pg_ctl.c:1221 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: nelze poslat signál pro povýšení (promote, PID: %ld): %s\n" + +#: pg_ctl.c:1224 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: nelze odstranit signální soubor pro povýšení (promote) \"%s\": %s\n" + +#: pg_ctl.c:1234 +msgid "waiting for server to promote..." +msgstr "čekám na promote serveru ..." + +#: pg_ctl.c:1248 +msgid "server promoted\n" +msgstr "server je povyšován (promote)\n" + +#: pg_ctl.c:1253 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: server neprovedl promote v časovém intervalu\n" + +#: pg_ctl.c:1259 +msgid "server promoting\n" +msgstr "server je povyšován (promote)\n" + +#: pg_ctl.c:1283 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: nemohu odrotovat log soubor; server běží v single-user módu (PID: %ld)\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: nelze vytvořit signální soubor pro odrotování logu \"%s\": %s\n" + +#: pg_ctl.c:1299 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: nelze zapsat do signálního souboru pro odrotování logu \"%s\": %s\n" + +#: pg_ctl.c:1307 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: nelze poslat signál pro odrotování logu (PID: %ld): %s\n" + +#: pg_ctl.c:1310 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: nelze odstranit signální soubor pro odrotování logu \"%s\": %s\n" + +#: pg_ctl.c:1315 +msgid "server signaled to rotate log file\n" +msgstr "server obdržel signál pro odrotování logu\n" + +#: pg_ctl.c:1362 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: server běží v single-user módu (PID: %ld)\n" + +#: pg_ctl.c:1376 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: server běží (PID: %ld)\n" + +#: pg_ctl.c:1392 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: žádný server neběží\n" + +#: pg_ctl.c:1409 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: nelze poslat signál pro reload %d (PID: %ld): %s\n" + +#: pg_ctl.c:1440 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: nelze najít vlastní spustitelný soubor\n" + +#: pg_ctl.c:1450 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: nelze najít spustitelný program postgres\n" + +#: pg_ctl.c:1520 pg_ctl.c:1554 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: nelze otevřít manažera služeb\n" + +#: pg_ctl.c:1526 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: služba \"%s\" je již registrována\n" + +#: pg_ctl.c:1537 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: nelze zaregistrovat službu \"%s\": chybový kód %lu\n" + +#: pg_ctl.c:1560 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: služba \"%s\" není registrována\n" + +#: pg_ctl.c:1567 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: nelze otevřít službu \"%s\": chybový kód %lu\n" + +#: pg_ctl.c:1576 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: nelze odregistrovat službu \"%s\": chybový kód %lu\n" + +#: pg_ctl.c:1663 +msgid "Waiting for server startup...\n" +msgstr "Čekám na start serveru ...\n" + +#: pg_ctl.c:1666 +msgid "Timed out waiting for server startup\n" +msgstr "Časový limit pro čekání na start serveru vypršel\n" + +#: pg_ctl.c:1670 +msgid "Server started and accepting connections\n" +msgstr "Server nastartoval a přijímá spojení\n" + +#: pg_ctl.c:1725 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: nelze nastartovat službu \"%s\": chybový kód %lu\n" + +#: pg_ctl.c:1795 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: VAROVÁNÍ: na této platformě nelze vytvořit tajné tokeny\n" + +#: pg_ctl.c:1808 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: nelze otevřít token procesu: chybový kód %lu\n" + +#: pg_ctl.c:1822 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: nelze alokovat SIDs: chybový kód %lu\n" + +#: pg_ctl.c:1849 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: nelze vytvořit vyhrazený token: chybový kód %lu\n" + +#: pg_ctl.c:1880 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s: VAROVÁNÍ: v systémovém API nelze najít všechny \"job object\" funkce\n" + +#: pg_ctl.c:1977 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: nelze získat seznam LUID pro privilegia: chybový kód %lu\n" + +#: pg_ctl.c:1985 pg_ctl.c:2000 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: nelze získat informace o tokenu: chybový kód %lu\n" + +#: pg_ctl.c:1994 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: nedostatek paměti\n" + +#: pg_ctl.c:2024 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: pg_ctl.c:2032 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s je nástroj pro inicializaci, spuštění, zastavení, nebo ovládání PostgreSQL serveru.\n" +"\n" + +#: pg_ctl.c:2033 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: pg_ctl.c:2034 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr "" +" %s init[db] [-D ADRESÁŘ] [-s] [-o PŘEPÍNAČE]\n" +"\n" + +#: pg_ctl.c:2035 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D ADRESÁŘ] [-l SOUBOR] [-W] [-t SECS] [-s]\n" +" [-o VOLBY] [-p CESTA] [-c]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr "" +" %s stop [-D ADRESÁŘ] [-m MÓD-UKONČENÍ] [-W] [-t SECS] [-s]\n" +"\n" + +#: pg_ctl.c:2038 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D ADRESÁŘ] [-m MÓD-UKONČENÍ] [-W] [-t SECS] [-s]\n" +" [-o VOLBY] [-c]\n" + +#: pg_ctl.c:2040 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D ADRESÁŘ] [-s]\n" + +#: pg_ctl.c:2041 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D ADRESÁŘ]\n" + +#: pg_ctl.c:2042 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D ADRESÁŘ] [-W] [-t SECS] [-s]\n" + +#: pg_ctl.c:2043 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s reload [-D ADRESÁŘ] [-s]\n" + +#: pg_ctl.c:2044 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill NAZEVSIGNALU PID\n" + +#: pg_ctl.c:2046 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgstr "" +" %s register [-D ADRESÁŘ] [-N NÁZEVSLUŽBY] [-U UŽIVATEL] [-P HESLO]\n" +" [-S MÓD-STARTU] [-e ZDROJ] [-W] [-t SECS] [-s] [-o VOLBY]\n" + +#: pg_ctl.c:2048 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N SERVICENAME]\n" + +#: pg_ctl.c:2051 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"Společné přepínače:\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " -D, --pgdata=ADRESÁŘ umístění úložiště databáze\n" + +#: pg_ctl.c:2054 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr " -e SOURCE název zdroje pro logování při běhu jako služba\n" + +#: pg_ctl.c:2056 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr " -s, --silent vypisuj jen chyby, žádné informativní zprávy\n" + +#: pg_ctl.c:2057 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr " -t, --timeout=SECS počet vteřin pro čekání při využití volby -w\n" + +#: pg_ctl.c:2058 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version vypsat informace o verzi, potom skončit\n" + +#: pg_ctl.c:2059 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait čekat na dokončení operace (výchozí)\n" + +#: pg_ctl.c:2060 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait nečekat na dokončení operace\n" + +#: pg_ctl.c:2061 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help vypsat tuto nápovědu, potom skončit\n" + +#: pg_ctl.c:2062 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "Pokud je vynechán parametr -D, použije se proměnná prostředí PGDATA.\n" + +#: pg_ctl.c:2064 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"Přepínače pro start nebo restart:\n" + +#: pg_ctl.c:2066 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, --core-files povolit postgresu vytvářet core soubory\n" + +#: pg_ctl.c:2068 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files nepoužitelné pro tuto platformu\n" + +#: pg_ctl.c:2070 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr " -l, --log=SOUBOR zapisuj (nebo připoj na konec) log serveru do SOUBORU.\n" + +#: pg_ctl.c:2071 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=VOLBY přepínače, které budou předány postgresu\n" +" (spustitelnému souboru PostgreSQL) či initdb\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p CESTA-K-POSTGRESU za normálních okolností není potřeba\n" + +#: pg_ctl.c:2074 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"Přepínače pro start nebo restart:\n" + +#: pg_ctl.c:2075 +#, c-format +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, --mode=MODE může být \"smart\", \"fast\", or \"immediate\"\n" + +#: pg_ctl.c:2077 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"Módy ukončení jsou:\n" + +#: pg_ctl.c:2078 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart skonči potom, co se odpojí všichni klienti\n" + +#: pg_ctl.c:2079 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast skonči okamžitě, s korektním zastavením serveru (výchozí)\n" + +#: pg_ctl.c:2080 +#, c-format +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr "" +" immediate skonči bez kompletního zastavení; po restartu se provede\n" +" obnova po pádu (crash recovery)\n" + +#: pg_ctl.c:2082 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"Povolené signály pro \"kill\":\n" + +#: pg_ctl.c:2086 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"Přepínače pro register nebo unregister:\n" + +#: pg_ctl.c:2087 +#, c-format +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr " -N SERVICENAME jméno služby, pod kterým registrovat PostgreSQL server\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr " -P PASSWORD heslo k účtu pro registraci PostgreSQL serveru\n" + +#: pg_ctl.c:2089 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr " -U USERNAME uživatelské jméno pro registraci PostgreSQL server\n" + +#: pg_ctl.c:2090 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr " -S TYP-STARTU typ spuštění služby pro registraci PostgreSQL serveru\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"Módy spuštění jsou:\n" + +#: pg_ctl.c:2093 +#, c-format +msgid " auto start service automatically during system startup (default)\n" +msgstr " auto spusť službu automaticky během startu systému (implicitní)\n" + +#: pg_ctl.c:2094 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand spusť službu na vyžádání\n" + +#: pg_ctl.c:2097 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Chyby hlašte na <%s>.\n" + +#: pg_ctl.c:2098 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#: pg_ctl.c:2123 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: neplatný mód ukončení mode \"%s\"\n" + +#: pg_ctl.c:2152 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: neplatné jméno signálu \"%s\"\n" + +#: pg_ctl.c:2169 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: neplatný typ spuštění \"%s\"\n" + +#: pg_ctl.c:2224 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: nelze najít datový adresář pomocí příkazu \"%s\"\n" + +#: pg_ctl.c:2248 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: control file se zdá být poškozený\n" + +#: pg_ctl.c:2316 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: nemůže běžet pod uživatelem root\n" +"Prosím přihlaste se jako (neprivilegovaný) uživatel, který bude vlastníkem\n" +"serverového procesu (například pomocí příkazu \"su\").\n" + +#: pg_ctl.c:2400 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: -S nepoužitelné pro tuto platformu\n" + +#: pg_ctl.c:2437 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: příliš mnoho argumentů v příkazové řádce (první je \"%s\")\n" + +#: pg_ctl.c:2463 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: chýbějící parametr pro \"kill\" mód\n" + +#: pg_ctl.c:2481 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: neplatný mód operace \"%s\"\n" + +#: pg_ctl.c:2491 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: není specifikována operace\n" + +#: pg_ctl.c:2512 +#, c-format +msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "%s: není zadán datový adresář a ani není nastavena proměnná prostředí PGDATA\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "nelze číst symbolický link \"%s\"" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "potomek byl ukončen signálem %s" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option is not supported when starting a pre-9.1 server\n" +#~ msgstr "" +#~ "\n" +#~ "%s: -w volba není podporována při startu pre-9.1 serveru\n" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option cannot use a relative socket directory specification\n" +#~ msgstr "" +#~ "\n" +#~ "%s: -w volba nemůže používat relativně zadaný adresář socketu\n" + +#~ msgid "" +#~ "\n" +#~ "%s: this data directory appears to be running a pre-existing postmaster\n" +#~ msgstr "" +#~ "\n" +#~ "%s: zdá se že v tomto datovém adresáři již běží existující postmaster\n" + +#~ msgid "server is still starting up\n" +#~ msgstr "server stále startuje\n" + +#~ msgid "%s: could not wait for server because of misconfiguration\n" +#~ msgstr "%s: nelze čekat na server kvůli chybné konfiguraci\n" + +#~ msgid " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n" +#~ msgstr " %s start [-w] [-t SECS] [-D ADRESÁŘ] [-s] [-l SOUBOR] [-o \"PŘEPÍNAČE\"]\n" + +#~ msgid "" +#~ "(The default is to wait for shutdown, but not for start or restart.)\n" +#~ "\n" +#~ msgstr "" +#~ "(Implicitní chování je čekat na ukončení, ale ne při startu nebo restartu.)\n" +#~ "\n" + +#~ msgid "" +#~ "\n" +#~ "Options for stop, restart, or promote:\n" +#~ msgstr "" +#~ "\n" +#~ "Přepínače pro zastavení, restart a promote:\n" + +#~ msgid " smart promote after performing a checkpoint\n" +#~ msgstr " smart promote po provedení checkpointu\n" + +#~ msgid " fast promote quickly without waiting for checkpoint completion\n" +#~ msgstr " fast promote rychlé bez čekání na dokončení checkpointu\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" diff --git a/src/bin/pg_ctl/po/de.po b/src/bin/pg_ctl/po/de.po new file mode 100644 index 000000000000..61afaf1f248e --- /dev/null +++ b/src/bin/pg_ctl/po/de.po @@ -0,0 +1,885 @@ +# German message translation file for pg_ctl +# Peter Eisentraut , 2004 - 2021. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-24 06:46+0000\n" +"PO-Revision-Date: 2021-04-24 09:40+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ungültige Programmdatei »%s«" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "konnte Programmdatei »%s« nicht lesen" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "konnte kein »%s« zum Ausführen finden" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() fehlgeschlagen: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "Befehl ist nicht ausführbar" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "Befehl nicht gefunden" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "Kindprozess hat mit Code %d beendet" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "Kindprozess wurde durch Ausnahme 0x%X beendet" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "Kindprozess wurde von Signal %d beendet: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "Kindprozess hat mit unbekanntem Status %d beendet" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "konnte aktuelles Arbeitsverzeichnis nicht ermitteln: %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: Verzeichnis »%s« existiert nicht\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: konnte nicht auf Verzeichnis »%s« zugreifen: %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: Verzeichnis »%s« ist kein Datenbankclusterverzeichnis\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: konnte PID-Datei »%s« nicht öffnen: %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: die PID-Datei »%s« ist leer\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: ungültige Daten in PID-Datei »%s«\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: konnte Server nicht starten: %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: konnte Server wegen setsid()-Fehler nicht starten: %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: konnte Logdatei »%s« nicht öffnen: %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: konnte Server nicht starten: Fehlercode %lu\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "%s: kann Grenzwert für Core-Datei-Größe nicht setzen; durch harten Grenzwert verboten\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: konnte Datei »%s« nicht lesen\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: Optionsdatei »%s« muss genau eine Zeile haben\n" + +#: pg_ctl.c:785 pg_ctl.c:974 pg_ctl.c:1070 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: konnte Stopp-Signal nicht senden (PID: %ld): %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"Das Programm »%s« wird von %s benötigt, aber wurde nicht im\n" +"selben Verzeichnis wie »%s« gefunden.\n" +"Prüfen Sie Ihre Installation.\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"Das Programm »%s« wurde von %s gefunden,\n" +"aber es hatte nicht die gleiche Version wie %s.\n" +"Prüfen Sie Ihre Installation.\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: Initialisierung des Datenbanksystems fehlgeschlagen\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "%s: ein anderer Server läuft möglicherweise; versuche trotzdem zu starten\n" + +#: pg_ctl.c:914 +msgid "waiting for server to start..." +msgstr "warte auf Start des Servers..." + +#: pg_ctl.c:919 pg_ctl.c:1024 pg_ctl.c:1116 pg_ctl.c:1241 +msgid " done\n" +msgstr " fertig\n" + +#: pg_ctl.c:920 +msgid "server started\n" +msgstr "Server gestartet\n" + +#: pg_ctl.c:923 pg_ctl.c:929 pg_ctl.c:1246 +msgid " stopped waiting\n" +msgstr " Warten beendet\n" + +#: pg_ctl.c:924 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: Starten des Servers hat nicht rechtzeitig abgeschlossen\n" + +#: pg_ctl.c:930 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: konnte Server nicht starten\n" +"Prüfen Sie die Logausgabe.\n" + +#: pg_ctl.c:938 +msgid "server starting\n" +msgstr "Server startet\n" + +#: pg_ctl.c:959 pg_ctl.c:1046 pg_ctl.c:1137 pg_ctl.c:1176 pg_ctl.c:1270 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: PID-Datei »%s« existiert nicht\n" + +#: pg_ctl.c:960 pg_ctl.c:1048 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1271 +msgid "Is server running?\n" +msgstr "Läuft der Server?\n" + +#: pg_ctl.c:966 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "%s: kann Server nicht anhalten; Einzelbenutzerserver läuft (PID: %ld)\n" + +#: pg_ctl.c:981 +msgid "server shutting down\n" +msgstr "Server fährt herunter\n" + +#: pg_ctl.c:996 pg_ctl.c:1085 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"WARNUNG: Online-Backup-Modus ist aktiv\n" +"Herunterfahren wird erst abgeschlossen werden, wenn pg_stop_backup() aufgerufen wird.\n" +"\n" + +#: pg_ctl.c:1000 pg_ctl.c:1089 +msgid "waiting for server to shut down..." +msgstr "warte auf Herunterfahren des Servers..." + +#: pg_ctl.c:1016 pg_ctl.c:1107 +msgid " failed\n" +msgstr " Fehler\n" + +#: pg_ctl.c:1018 pg_ctl.c:1109 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: Server fährt nicht herunter\n" + +#: pg_ctl.c:1020 pg_ctl.c:1111 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"TIPP: Die Option »-m fast« beendet Sitzungen sofort, statt auf das Beenden\n" +"durch die Sitzungen selbst zu warten.\n" + +#: pg_ctl.c:1026 pg_ctl.c:1117 +msgid "server stopped\n" +msgstr "Server angehalten\n" + +#: pg_ctl.c:1049 +msgid "trying to start server anyway\n" +msgstr "versuche Server trotzdem zu starten\n" + +#: pg_ctl.c:1058 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "%s: kann Server nicht neu starten; Einzelbenutzerserver läuft (PID: %ld)\n" + +#: pg_ctl.c:1061 pg_ctl.c:1147 +msgid "Please terminate the single-user server and try again.\n" +msgstr "Bitte beenden Sie den Einzelbenutzerserver und versuchen Sie es noch einmal.\n" + +#: pg_ctl.c:1121 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: alter Serverprozess (PID: %ld) scheint verschwunden zu sein\n" + +#: pg_ctl.c:1123 +msgid "starting server anyway\n" +msgstr "starte Server trotzdem\n" + +#: pg_ctl.c:1144 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "%s: kann Server nicht neu laden; Einzelbenutzerserver läuft (PID: %ld)\n" + +#: pg_ctl.c:1153 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: konnte Signal zum Neuladen nicht senden (PID: %ld): %s\n" + +#: pg_ctl.c:1158 +msgid "server signaled\n" +msgstr "Signal an Server gesendet\n" + +#: pg_ctl.c:1183 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "%s: kann Server nicht befördern; Einzelbenutzerserver läuft (PID: %ld)\n" + +#: pg_ctl.c:1191 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s: kann Server nicht befördern; Server ist nicht im Standby-Modus\n" + +#: pg_ctl.c:1201 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: konnte Signaldatei zum Befördern »%s« nicht erzeugen: %s\n" + +#: pg_ctl.c:1207 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: konnte Signaldatei zum Befördern »%s« nicht schreiben: %s\n" + +#: pg_ctl.c:1215 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: konnte Signal zum Befördern nicht senden (PID: %ld): %s\n" + +#: pg_ctl.c:1218 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: konnte Signaldatei zum Befördern »%s« nicht entfernen: %s\n" + +#: pg_ctl.c:1228 +msgid "waiting for server to promote..." +msgstr "warte auf Befördern des Servers..." + +#: pg_ctl.c:1242 +msgid "server promoted\n" +msgstr "Server wurde befördert\n" + +#: pg_ctl.c:1247 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: Befördern des Servers hat nicht rechtzeitig abgeschlossen\n" + +#: pg_ctl.c:1253 +msgid "server promoting\n" +msgstr "Server wird befördert\n" + +#: pg_ctl.c:1277 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: kann Logdatei nicht rotieren; Einzelbenutzerserver läuft (PID: %ld)\n" + +#: pg_ctl.c:1287 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: konnte Signaldatei zum Logrotieren »%s« nicht erzeugen: %s\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: konnte Signaldatei zum Logrotieren »%s« nicht schreiben: %s\n" + +#: pg_ctl.c:1301 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: konnte Signal zum Logrotieren nicht senden (PID: %ld): %s\n" + +#: pg_ctl.c:1304 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: konnte Signaldatei zum Logrotieren »%s« nicht entfernen: %s\n" + +#: pg_ctl.c:1309 +msgid "server signaled to rotate log file\n" +msgstr "Signal zum Logrotieren an Server gesendet\n" + +#: pg_ctl.c:1356 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: Einzelbenutzerserver läuft (PID: %ld)\n" + +#: pg_ctl.c:1370 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: Server läuft (PID: %ld)\n" + +#: pg_ctl.c:1386 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: kein Server läuft\n" + +#: pg_ctl.c:1403 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: konnte Signal %d nicht senden (PID: %ld): %s\n" + +#: pg_ctl.c:1434 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: konnte eigene Programmdatei nicht finden\n" + +#: pg_ctl.c:1444 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: konnte »postgres« Programmdatei nicht finden\n" + +#: pg_ctl.c:1514 pg_ctl.c:1548 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: konnte Servicemanager nicht öffnen\n" + +#: pg_ctl.c:1520 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: Systemdienst »%s« ist bereits registriert\n" + +#: pg_ctl.c:1531 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: konnte Systemdienst »%s« nicht registrieren: Fehlercode %lu\n" + +#: pg_ctl.c:1554 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: Systemdienst »%s« ist nicht registriert\n" + +#: pg_ctl.c:1561 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: konnte Systemdienst »%s« nicht öffnen: Fehlercode %lu\n" + +#: pg_ctl.c:1570 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: konnte Systemdienst »%s« nicht deregistrieren: Fehlercode %lu\n" + +#: pg_ctl.c:1657 +msgid "Waiting for server startup...\n" +msgstr "Warte auf Start des Servers...\n" + +#: pg_ctl.c:1660 +msgid "Timed out waiting for server startup\n" +msgstr "Zeitüberschreitung beim Warten auf Start des Servers\n" + +#: pg_ctl.c:1664 +msgid "Server started and accepting connections\n" +msgstr "Server wurde gestartet und nimmt Verbindungen an\n" + +#: pg_ctl.c:1719 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: konnte Systemdienst »%s« nicht starten: Fehlercode %lu\n" + +#: pg_ctl.c:1789 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: WARNUNG: auf dieser Plattform können keine beschränkten Token erzeugt werden\n" + +#: pg_ctl.c:1802 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: konnte Prozess-Token nicht öffnen: Fehlercode %lu\n" + +#: pg_ctl.c:1816 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: konnte SIDs nicht erzeugen: Fehlercode %lu\n" + +#: pg_ctl.c:1843 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: konnte beschränktes Token nicht erzeugen: Fehlercode %lu\n" + +#: pg_ctl.c:1874 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s: WARNUNG: konnte nicht alle Job-Objekt-Funtionen in der System-API finden\n" + +#: pg_ctl.c:1971 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: konnte LUIDs für Privilegien nicht ermitteln: Fehlercode %lu\n" + +#: pg_ctl.c:1979 pg_ctl.c:1994 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: konnte Token-Informationen nicht ermitteln: Fehlercode %lu\n" + +#: pg_ctl.c:1988 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: Speicher aufgebraucht\n" + +#: pg_ctl.c:2018 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_ctl.c:2026 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s ist ein Hilfsprogramm, um einen PostgreSQL-Server zu initialisieren, zu\n" +"starten, anzuhalten oder zu steuern.\n" +"\n" + +#: pg_ctl.c:2027 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_ctl.c:2028 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D DATENVERZ] [-s] [-o OPTIONEN]\n" + +#: pg_ctl.c:2029 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D DATENVERZ] [-l DATEINAME] [-W] [-t SEK] [-s]\n" +" [-o OPTIONEN] [-p PFAD] [-c]\n" + +#: pg_ctl.c:2031 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D DATENVERZ] [-m SHUTDOWN-MODUS] [-W] [-t SEK] [-s]\n" + +#: pg_ctl.c:2032 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D DATENVERZ] [-m SHUTDOWN-MODUS] [-W] [-t SEK] [-s]\n" +" [-o OPTIONEN] [-c]\n" + +#: pg_ctl.c:2034 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D DATENVERZ] [-s]\n" + +#: pg_ctl.c:2035 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATENVERZ]\n" + +#: pg_ctl.c:2036 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D DATENVERZ] [-W] [-t SEK] [-s]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D DATENVERZ] [-s]\n" + +#: pg_ctl.c:2038 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill SIGNALNAME PID\n" + +#: pg_ctl.c:2040 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgstr "" +" %s register [-D DATENVERZ] [-N DIENSTNAME] [-U BENUTZERNAME] [-P PASSWORT]\n" +" [-S STARTTYP] [-e QUELLE] [-W] [-t SEK] [-s] [-o OPTIONEN]\n" + +#: pg_ctl.c:2042 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N DIENSTNAME]\n" + +#: pg_ctl.c:2045 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"Optionen für alle Modi:\n" + +#: pg_ctl.c:2046 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " -D, --pgdata=DATENVERZ Datenbankverzeichnis\n" + +#: pg_ctl.c:2048 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr "" +" -e QUELLE Ereignisquelle fürs Loggen, wenn als Systemdienst\n" +" gestartet\n" + +#: pg_ctl.c:2050 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr " -s, --silent nur Fehler zeigen, keine Informationsmeldungen\n" + +#: pg_ctl.c:2051 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr " -t, --timeout=SEK Sekunden zu warten bei Option -w\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_ctl.c:2053 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait warten bis Operation abgeschlossen ist (Voreinstellung)\n" + +#: pg_ctl.c:2054 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait nicht warten bis Operation abgeschlossen ist\n" + +#: pg_ctl.c:2055 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_ctl.c:2056 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "" +"Wenn die Option -D weggelassen wird, dann wird die Umgebungsvariable\n" +"PGDATA verwendet.\n" + +#: pg_ctl.c:2058 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"Optionen für Start oder Neustart:\n" + +#: pg_ctl.c:2060 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, --core-files erlaubt postgres Core-Dateien zu erzeugen\n" + +#: pg_ctl.c:2062 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files betrifft diese Plattform nicht\n" + +#: pg_ctl.c:2064 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr "" +" -l, --log=DATEINAME Serverlog in DATEINAME schreiben (wird an bestehende\n" +" Datei angehängt)\n" + +#: pg_ctl.c:2065 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=OPTIONEN Kommandozeilenoptionen für postgres (PostgreSQL-\n" +" Serverprogramm) oder initdb\n" + +#: pg_ctl.c:2067 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p PFAD-ZU-POSTGRES normalerweise nicht notwendig\n" + +#: pg_ctl.c:2068 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"Optionen für Anhalten oder Neustart:\n" + +#: pg_ctl.c:2069 +#, c-format +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, --mode=MODUS MODUS kann »smart«, »fast« oder »immediate« sein\n" + +#: pg_ctl.c:2071 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"Shutdown-Modi sind:\n" + +#: pg_ctl.c:2072 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart beenden nachdem alle Clientverbindungen geschlossen sind\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast sofort beenden, mit richtigem Shutdown (Voreinstellung)\n" + +#: pg_ctl.c:2074 +#, c-format +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr "" +" immediate beenden ohne vollständigen Shutdown; führt zu Recovery-Lauf\n" +" beim Neustart\n" + +#: pg_ctl.c:2076 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"Erlaubte Signalnamen für »kill«:\n" + +#: pg_ctl.c:2080 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"Optionen für »register« und »unregister«:\n" + +#: pg_ctl.c:2081 +#, c-format +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr " -N DIENSTNAME Systemdienstname für Registrierung des PostgreSQL-Servers\n" + +#: pg_ctl.c:2082 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr " -P PASSWORD Passwort des Benutzers für Registrierung des PostgreSQL-Servers\n" + +#: pg_ctl.c:2083 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr " -U USERNAME Benutzername für Registrierung des PostgreSQL-Servers\n" + +#: pg_ctl.c:2084 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr " -S STARTTYP Systemdienst-Starttyp für PostgreSQL-Server\n" + +#: pg_ctl.c:2086 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"Starttypen sind:\n" + +#: pg_ctl.c:2087 +#, c-format +msgid " auto start service automatically during system startup (default)\n" +msgstr "" +" auto Dienst automatisch starten beim Start des Betriebssystems\n" +" (Voreinstellung)\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand Dienst bei Bedarf starten\n" + +#: pg_ctl.c:2091 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: pg_ctl.c:2117 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: unbekannter Shutdown-Modus »%s«\n" + +#: pg_ctl.c:2146 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: unbekannter Signalname »%s«\n" + +#: pg_ctl.c:2163 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: unbekannter Starttyp »%s«\n" + +#: pg_ctl.c:2218 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: konnte das Datenverzeichnis mit Befehl »%s« nicht ermitteln\n" + +#: pg_ctl.c:2242 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: Kontrolldatei scheint kaputt zu sein\n" + +#: pg_ctl.c:2310 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: kann nicht als root ausgeführt werden\n" +"Bitte loggen Sie sich (z.B. mit »su«) als der (unprivilegierte) Benutzer\n" +"ein, der Eigentümer des Serverprozesses sein soll.\n" + +#: pg_ctl.c:2393 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: Option -S wird auf dieser Plattform nicht unterstützt\n" + +#: pg_ctl.c:2430 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" + +#: pg_ctl.c:2456 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: fehlende Argumente für »kill«-Modus\n" + +#: pg_ctl.c:2474 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: unbekannter Operationsmodus »%s«\n" + +#: pg_ctl.c:2484 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: keine Operation angegeben\n" + +#: pg_ctl.c:2505 +#, c-format +msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "%s: kein Datenbankverzeichnis angegeben und Umgebungsvariable PGDATA nicht gesetzt\n" diff --git a/src/bin/pg_ctl/po/el.po b/src/bin/pg_ctl/po/el.po new file mode 100644 index 000000000000..b34c73ae7a55 --- /dev/null +++ b/src/bin/pg_ctl/po/el.po @@ -0,0 +1,882 @@ +# Greek message translation file for pg_ctl +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_ctl (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_ctl (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:46+0000\n" +"PO-Revision-Date: 2021-03-30 10:28+0200\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "δεν ήταν δυνατή η αναγνώριση του τρέχοντος καταλόγου: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "μη έγκυρο δυαδικό αρχείο “%s”" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "δεν ήταν δυνατή η ανάγνωση του δυαδικού αρχείου “%s”" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "δεν βρέθηκε το αρχείο “%s” για να εκτελεστεί" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "δεν ήταν δυνατή η μετάβαση στον κατάλογο “%s”: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του συμβολικού συνδέσμου “%s”: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s () απέτυχε: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "έλλειψη μνήμης" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "έλλειψη μνήμης\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "δεν ήταν δυνατή η αντιγραφή δείκτη null (εσωτερικό σφάλμα)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "εντολή μη εκτελέσιμη" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "εντολή δεν βρέθηκε" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "απόγονος διεργασίας τερμάτισε με κωδικό εξόδου %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "απόγονος διεργασίας τερματίστηκε με εξαίρεση 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "απόγονος διεργασίας τερματίστηκε με σήμα %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "απόγονος διεργασίας τερμάτισε με μη αναγνωρίσιμη κατάσταση %d" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "δεν ήταν δυνατή η επεξεργασία του τρέχοντος καταλόγου εργασίας: %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: ο κατάλογος \"%s\" δεν υπάρχει\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατή η πρόσβαση στον κατάλογο \"%s\": %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: ο κατάλογος \"%s\" δεν είναι κατάλογος συστάδας βάσης δεδομένων\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατό το άνοιγμα αρχείου PID “%s”: %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: το αρχείο PID “%s” είναι άδειο\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: μη έγκυρα δεδομένα στο αρχείο PID “%s”\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: δεν μπόρεσε να εκκινήσει τον διακομιστή: %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: δεν ήταν δυνατή η εκκίνηση του διακομιστή λόγω αποτυχίας του setsid(): %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατό το άνοιγμα του αρχείου καταγραφής “%s”: %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η εκκίνηση διακομιστή: κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "%s: δεν είναι δυνατός ο ορισμός ορίου μεγέθους αρχείου πυρήνα· απαγορεύεται από το σκληρό όριο\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: δεν ήταν δυνατή η ανάγνωση αρχείου “%s”\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: το αρχείο επιλογής \"%s\" πρέπει να έχει ακριβώς μία γραμμή\n" + +#: pg_ctl.c:785 pg_ctl.c:974 pg_ctl.c:1070 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: δεν ήταν δυνατή η αποστολή σήματος διακοπής (PID: %ld): %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"Το πρόγραμμα \"%s\" απαιτείται από %s αλλά δεν βρέθηκε στον\n" +"ίδιο κατάλογο με το \"%s\".\n" +"Ελέγξτε την εγκατάστασή σας.\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"Το πρόγραμμα \"%s\" βρέθηκε από το \"%s\"\n" +"αλλά δεν ήταν στην ίδια έκδοση με %s.\n" +"Ελέγξτε την εγκατάστασή σας.\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: αρχικοποίηση του συστήματος βάσης δεδομένων απέτυχε\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "%s: ενδέχεται να εκτελείται ένας άλλος διακομιστής· γίνεται προσπάθεια εκκίνησης του διακομιστή ούτως ή άλλως\n" + +#: pg_ctl.c:914 +msgid "waiting for server to start..." +msgstr "αναμονή για την εκκίνηση του διακομιστή..." + +#: pg_ctl.c:919 pg_ctl.c:1024 pg_ctl.c:1116 pg_ctl.c:1241 +msgid " done\n" +msgstr " ολοκλήρωση\n" + +#: pg_ctl.c:920 +msgid "server started\n" +msgstr "ο διακομιστής ξεκίνησε\n" + +#: pg_ctl.c:923 pg_ctl.c:929 pg_ctl.c:1246 +msgid " stopped waiting\n" +msgstr " διακοπή αναμονής\n" + +#: pg_ctl.c:924 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: ο διακομιστής δεν ξεκίνησε εγκαίρως\n" + +#: pg_ctl.c:930 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: δεν ήταν δυνατή η εκκίνηση του διακομιστή\n" +"Εξετάστε την έξοδο του αρχείου καταγραφής.\n" + +#: pg_ctl.c:938 +msgid "server starting\n" +msgstr "εκκίνηση διακομιστή\n" + +#: pg_ctl.c:959 pg_ctl.c:1046 pg_ctl.c:1137 pg_ctl.c:1176 pg_ctl.c:1270 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: το αρχείο PID “%s” δεν υπάρχει\n" + +#: pg_ctl.c:960 pg_ctl.c:1048 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1271 +msgid "Is server running?\n" +msgstr "Εκτελείται ο διακομιστής;\n" + +#: pg_ctl.c:966 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "%s: δεν είναι δυνατή η διακοπή του διακομιστή· εκτελείται διακομιστής μοναδικού-χρήστη (PID: %ld)\n" + +#: pg_ctl.c:981 +msgid "server shutting down\n" +msgstr "τερματισμός λειτουργίας διακομιστή\n" + +#: pg_ctl.c:996 pg_ctl.c:1085 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"WARNING: Η λειτουργία δημιουργίας αντιγράφων ασφαλείας σε απευθείας σύνδεση είναι ενεργή\n" +"Ο τερματισμός λειτουργίας δεν θα ολοκληρωθεί μέχρι να κληθεί pg_stop_backup().\n" +"\n" + +#: pg_ctl.c:1000 pg_ctl.c:1089 +msgid "waiting for server to shut down..." +msgstr "αναμονή για τερματισμό λειτουργίας του διακομιστή..." + +#: pg_ctl.c:1016 pg_ctl.c:1107 +msgid " failed\n" +msgstr " απέτυχε.\n" + +#: pg_ctl.c:1018 pg_ctl.c:1109 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: ο διακομιστής δεν τερματίζεται\n" + +#: pg_ctl.c:1020 pg_ctl.c:1111 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"HINT: Η επιλογή \"-m fast\" αποσυνδέει αμέσως τις συνεδρίες αντί\n" +"να αναμένει για εκ’ συνεδρίας εκκινούμενη αποσύνδεση.\n" + +#: pg_ctl.c:1026 pg_ctl.c:1117 +msgid "server stopped\n" +msgstr "ο διακομιστής διακόπηκε\n" + +#: pg_ctl.c:1049 +msgid "trying to start server anyway\n" +msgstr "προσπάθεια εκκίνησης του διακομιστή ούτως ή άλλως\n" + +#: pg_ctl.c:1058 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "%s: δεν είναι δυνατή η επανεκκίνηση του διακομιστή· εκτελείται διακομιστής μοναδικού-χρήστη (PID: %ld)\n" + +#: pg_ctl.c:1061 pg_ctl.c:1147 +msgid "Please terminate the single-user server and try again.\n" +msgstr "Τερματίστε το διακομιστή μοναδικού-χρήστη και προσπαθήστε ξανά.\n" + +#: pg_ctl.c:1121 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: παλεά διαδικασία διακομιστή (PID: %ld) φαίνεται να έχει χαθεί\n" + +#: pg_ctl.c:1123 +msgid "starting server anyway\n" +msgstr "εκκίνηση του διακομιστή ούτως ή άλλως\n" + +#: pg_ctl.c:1144 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "%s: δεν είναι δυνατή η επαναφόρτωση του διακομιστή· εκτελείται διακομιστής μοναδικού-χρήστη (PID: %ld)\n" + +#: pg_ctl.c:1153 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: δεν ήταν δυνατή η αποστολή σήματος επαναφόρτωσης (PID: %ld): %s\n" + +#: pg_ctl.c:1158 +msgid "server signaled\n" +msgstr "στάλθηκε σήμα στον διακομιστή\n" + +#: pg_ctl.c:1183 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "%s: δεν είναι δυνατή η προβίβαση του διακομιστή· εκτελείται διακομιστής μοναδικού-χρήστη (PID: %ld)\n" + +#: pg_ctl.c:1191 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s: δεν είναι δυνατή η προβίβαση του διακομιστή· ο διακομιστής δεν βρίσκεται σε κατάσταση αναμονής\n" + +#: pg_ctl.c:1201 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατή η δημιουργία του αρχείου σήματος προβιβασμού \"%s\": %s\n" + +#: pg_ctl.c:1207 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατή η εγγραφή του αρχείου σήματος προβιβασμού \"%s\": %s\n" + +#: pg_ctl.c:1215 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: δεν ήταν δυνατή η αποστολή σήματος προβιβασμού (PID: %ld): %s\n" + +#: pg_ctl.c:1218 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατή η κατάργηση του αρχείου σήματος προβιβασμού \"%s\": %s\n" + +#: pg_ctl.c:1228 +msgid "waiting for server to promote..." +msgstr "αναμονή για την προβίβαση του διακομιστή..." + +#: pg_ctl.c:1242 +msgid "server promoted\n" +msgstr "ο διακομιστής προβιβάστηκε\n" + +#: pg_ctl.c:1247 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: ο διακομιστής δεν προβιβάστηκε εγκαίρως\n" + +#: pg_ctl.c:1253 +msgid "server promoting\n" +msgstr "προβίβαση διακομιστή\n" + +#: pg_ctl.c:1277 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: δεν είναι δυνατή η περιστροφή του αρχείου καταγραφής· εκτελείται διακομιστής μοναδικού-χρήστη (PID: %ld)\n" + +#: pg_ctl.c:1287 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατή η δημιουργία αρχείου σήματος περιστροφής αρχείου καταγραφής \"%s\": %s\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατή η εγγραφή του αρχείου σήματος περιστροφής αρχείου καταγραφής \"%s\": %s\n" + +#: pg_ctl.c:1301 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: δεν ήταν δυνατή η αποστολή σήματος περιστροφής αρχείου καταγραφής (PID: %ld): %s\n" + +#: pg_ctl.c:1304 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: δεν ήταν δυνατή η κατάργηση του αρχείου σήματος περιστροφής αρχείου καταγραφής \"%s\": %s\n" + +#: pg_ctl.c:1309 +msgid "server signaled to rotate log file\n" +msgstr "ο διακομιστής έλαβε σήμα για την περιστροφή του αρχείου καταγραφής\n" + +#: pg_ctl.c:1356 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: εκτελείται διακομιστής μοναδικού-χρήστη (PID: %ld)\n" + +#: pg_ctl.c:1370 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: εκτελείται διακομιστής (PID: %ld)\n" + +#: pg_ctl.c:1386 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: δεν εκτελείται κανένας διακομιστής\n" + +#: pg_ctl.c:1403 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: δεν ήταν δυνατή η αποστολή %d σήματος (PID: %ld): %s\n" + +#: pg_ctl.c:1434 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: δεν ήταν δυνατή η εύρεση του ιδίου εκτελέσιμου προγράμματος\n" + +#: pg_ctl.c:1444 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: δεν ήταν δυνατή η εύρεση του εκτελέσιμου προγράμματος postgres\n" + +#: pg_ctl.c:1514 pg_ctl.c:1548 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: δεν ήταν δυνατό το άνοιγμα του διαχειριστή υπηρεσιών\n" + +#: pg_ctl.c:1520 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: η υπηρεσία \"%s\" έχει ήδη καταχωρηθεί\n" + +#: pg_ctl.c:1531 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η καταχώρηση της υπηρεσίας \"%s\": κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1554 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: η υπηρεσία \"%s\" δεν έχει καταχωρηθεί\n" + +#: pg_ctl.c:1561 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: δεν ήταν δυνατό το άνοιγμα της υπηρεσίας \"%s\": κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1570 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η διαγραφή καταχώρησης της υπηρεσίας \"%s\": κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1657 +msgid "Waiting for server startup...\n" +msgstr "Αναμονή για εκκίνηση διακομιστή...\n" + +#: pg_ctl.c:1660 +msgid "Timed out waiting for server startup\n" +msgstr "Λήξη χρονικού ορίου αναμονής για εκκίνηση διακομιστή\n" + +#: pg_ctl.c:1664 +msgid "Server started and accepting connections\n" +msgstr "Ο διακομιστής ξεκίνησε και αποδέχτηκε συνδέσεις\n" + +#: pg_ctl.c:1719 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η εκκίνηση της υπηρεσίας \"%s\": κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1789 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: WARNING: δεν είναι δυνατή η δημιουργία περιορισμένων διακριτικών σε αυτήν την πλατφόρμα\n" + +#: pg_ctl.c:1802 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: δεν ήταν δυνατό το άνοιγμα διακριτικού διεργασίας: κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1816 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η εκχώρηση SIDs: κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1843 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η δημιουργία περιορισμένου διακριτικού: κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1874 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s: WARNING: δεν ήταν δυνατός ο εντοπισμός όλων των λειτουργιών αντικειμένου εργασίας στο API συστήματος\n" + +#: pg_ctl.c:1971 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η ανάκτηση LUIDs για δικαιώματα: κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1979 pg_ctl.c:1994 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: δεν ήταν δυνατή η ανάκτηση πληροφοριών διακριτικού: κωδικός σφάλματος %lu\n" + +#: pg_ctl.c:1988 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: έλλειψη μνήμης\n" + +#: pg_ctl.c:2018 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_ctl.c:2026 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s είναι ένα βοηθητικό πρόγραμμα για την αρχικοποίηση, την εκκίνηση, τη διακοπή ή τον έλεγχο ενός διακομιστή PostgreSQL.\n" +"\n" + +#: pg_ctl.c:2027 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_ctl.c:2028 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" + +#: pg_ctl.c:2029 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +"\n" + +#: pg_ctl.c:2031 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr "" +" %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +"\n" + +#: pg_ctl.c:2032 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" + +#: pg_ctl.c:2034 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D DATADIR] [-s]\n" + +#: pg_ctl.c:2035 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATADIR]\n" + +#: pg_ctl.c:2036 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D DATADIR] [-s]\n" + +#: pg_ctl.c:2038 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill SIGNALNAME PID\n" + +#: pg_ctl.c:2040 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgstr "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" + +#: pg_ctl.c:2042 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N SERVICENAME]\n" + +#: pg_ctl.c:2045 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"Κοινές επιλογές:\n" + +#: pg_ctl.c:2046 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " [-D, —pgdata=]DATADIR τοποθεσία για τη περιοχή αποθήκευσης της βάσης δεδομένων\n" + +#: pg_ctl.c:2048 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr " -e SOURCE πηγή προέλευσης συμβάντων για καταγραφή κατά την εκτέλεση ως υπηρεσία\n" + +#: pg_ctl.c:2050 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr " -s, —silent εκτύπωση μόνο σφαλμάτων, χωρίς ενημερωτικά μηνύματα\n" + +#: pg_ctl.c:2051 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr " -t, —timeout=SECS δευτερόλεπτα αναμονής κατά τη χρήση της επιλογής -w\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης και, στη συνέχεια, έξοδος\n" + +#: pg_ctl.c:2053 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, —wait περίμενε μέχρι να ολοκληρωθεί η λειτουργία (προεπιλογή)\n" + +#: pg_ctl.c:2054 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, —no-wait να μην περιμένει μέχρι να ολοκληρωθεί η λειτουργία\n" + +#: pg_ctl.c:2055 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, και μετά έξοδος\n" + +#: pg_ctl.c:2056 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "Εάν παραλειφθεί η επιλογή -D, χρησιμοποιείται η μεταβλητή περιβάλλοντος PGDATA.\n" + +#: pg_ctl.c:2058 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"Επιλογές για έναρξη ή επανεκκίνηση:\n" + +#: pg_ctl.c:2060 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, —core-files επίτρεψε στην postgres να παράγει αρχεία αποτύπωσης μνήμης\n" + +#: pg_ctl.c:2062 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, —core-files ανεφάρμοστο σε αυτήν την πλατφόρμα\n" + +#: pg_ctl.c:2064 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr " -l, --log=FILENAME ενέγραψε (ή προσάρτησε) το αρχείο καταγραφής διακομιστή στο FILENAME\n" + +#: pg_ctl.c:2065 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, —options=OPTIONS επιλογές γραμμής εντολών που θα διαβιστούν στη postgres\n" +" (εκτελέσιμο αρχείο διακομιστή PostgreSQL) ή initdb\n" + +#: pg_ctl.c:2067 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p ΤΟ PATH-TO-POSTGRES κανονικά δεν είναι απαραίτητο\n" + +#: pg_ctl.c:2068 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"Επιλογές διακοπής ή επανεκκίνησης:\n" + +#: pg_ctl.c:2069 +#, c-format +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, —mode=MODE MODE μπορεί να είνα “smart”, “fast”, ή “immediate”\n" + +#: pg_ctl.c:2071 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"Οι λειτουργίες τερματισμού λειτουργίας είναι:\n" + +#: pg_ctl.c:2072 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart διάκοψε μετά την αποσύνδεση όλων των πελατών\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast διάκοψε απευθείας, με σωστό τερματισμό (προεπιλογή)\n" + +#: pg_ctl.c:2074 +#, c-format +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr " immediate διάκοψε άμεσα χωρίς πλήρη τερματισμό· Θα οδηγήσει σε αποκατάσταση κατά την επανεκκίνηση\n" + +#: pg_ctl.c:2076 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"Επιτρεπόμενα ονόματα σημάτων για θανάτωση:\n" + +#: pg_ctl.c:2080 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"Επιλογές καταχώρησης και διαγραφής καταχώρησης:\n" + +#: pg_ctl.c:2081 +#, c-format +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr " -N SERVICENAME όνομα υπηρεσίας με το οποίο θα καταχωρηθεί ο διακομιστής PostgreSQL\n" + +#: pg_ctl.c:2082 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr " -P PASSWORD κωδικός πρόσβασης του λογαριασμού για την καταγραφή του διακομιστή PostgreSQL\n" + +#: pg_ctl.c:2083 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr " -U USERNAME όνομα χρήστη του λογαριασμού για την καταγραφή του διακομιστή PostgreSQL\n" + +#: pg_ctl.c:2084 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr " -S START-TYPE τύπος έναρξης υπηρεσίας για την καταχώρηση διακομιστή PostgreSQL\n" + +#: pg_ctl.c:2086 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"Οι τύποι έναρξης είναι:\n" + +#: pg_ctl.c:2087 +#, c-format +msgid " auto start service automatically during system startup (default)\n" +msgstr " auto αυτόματη εκκίνηση της υπηρεσίας κατά την εκκίνηση του συστήματος (προεπιλογή)\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand έναρξη υπηρεσίας κατ' απαίτηση\n" + +#: pg_ctl.c:2091 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_ctl.c:2117 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: μη αναγνωρισμένη λειτουργία τερματισμού λειτουργίας \"%s\"\n" + +#: pg_ctl.c:2146 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: μη αναγνωρισμένο όνομα σήματος \"%s\"\n" + +#: pg_ctl.c:2163 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: μη αναγνωρίσιμος τύπος έναρξης \"%s\"\n" + +#: pg_ctl.c:2218 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: δεν ήταν δυνατός ο προσδιορισμός του καταλόγου δεδομένων με χρήση της εντολής \"%s\"\n" + +#: pg_ctl.c:2242 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: το αρχείο ελέγχου φαίνεται να είναι αλλοιωμένο\n" + +#: pg_ctl.c:2310 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: δεν είναι δυνατή η εκτέλεση ως υπερχρήστης\n" +"Συνδεθείτε (χρησιμοποιώντας, π.χ. \"su\") ως (μη προνομιούχο) χρήστη που θα\n" +"να είναι στην κατοχή της η διαδικασία διακομιστή.\n" + +#: pg_ctl.c:2393 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: επιλογή -S δεν υποστηρίζεται σε αυτήν την πλατφόρμα\n" + +#: pg_ctl.c:2430 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (πρώτη είναι η “%s”)\n" + +#: pg_ctl.c:2456 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: λείπουν παράμετροι για τη λειτουργία kill\n" + +#: pg_ctl.c:2474 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: μη αναγνωρισμένη λειτουργία \"%s\"\n" + +#: pg_ctl.c:2484 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: δεν καθορίστηκε καμία λειτουργία\n" + +#: pg_ctl.c:2505 +#, c-format +msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "%s: δεν έχει καθοριστεί κατάλογος βάσης δεδομένων και δεν έχει καθοριστεί μεταβλητή περιβάλλοντος PGDATA\n" + +#~ msgid "pclose failed: %m" +#~ msgstr "απέτυχε η εντολή pclose: %m" diff --git a/src/bin/pg_ctl/po/es.po b/src/bin/pg_ctl/po/es.po new file mode 100644 index 000000000000..b3be2080a607 --- /dev/null +++ b/src/bin/pg_ctl/po/es.po @@ -0,0 +1,907 @@ +# Spanish translation of pg_ctl. +# +# Copyright (c) 2004-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Alvaro Herrera , 2004-2013 +# Martín Marqués , 2013 +# Carlos Chapi , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_ctl (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:46+0000\n" +"PO-Revision-Date: 2021-05-20 23:12-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "el binario «%s» no es válido" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "no se pudo leer el binario «%s»" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "no se pudo encontrar un «%s» para ejecutar" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() falló: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "memoria agotada" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "la orden no es ejecutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "orden no encontrada" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "el proceso hijo terminó con código de salida %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "el proceso hijo fue terminado por una excepción 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "el proceso hijo terminó con código no reconocido %d" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "no se pudo obtener el directorio de trabajo actual: %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: el directorio «%s» no existe\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: no se pudo acceder al directorio «%s»: %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: el directorio «%s» no es un directorio de base de datos\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: no se pudo abrir el archivo de PID «%s»: %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: el archivo de PID «%s» está vacío\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: datos no válidos en archivo de PID «%s»\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: no se pudo iniciar el servidor: %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: no se pudo iniciar el servidor debido a falla en setsid(): %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: no se pudo abrir el archivo de log «%s»: %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: no se pudo iniciar el servidor: código de error %lu\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "" +"%s: no se puede establecer el límite de archivos de volcado;\n" +"impedido por un límite duro\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: no se pudo leer el archivo «%s»\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: archivo de opciones «%s» debe tener exactamente una línea\n" + +#: pg_ctl.c:785 pg_ctl.c:974 pg_ctl.c:1070 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: falló la señal de detención (PID: %ld): %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"%s necesita el programa «%s», pero no pudo encontrarlo en el mismo\n" +"directorio que «%s».\n" +"Verifique su instalación.\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"El programa «%s» fue encontrado por «%s», pero no es\n" +"de la misma versión que «%s».\n" +"Verifique su instalación.\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: falló la creación de la base de datos\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "%s: otro servidor puede estar en ejecución; tratando de iniciarlo de todas formas.\n" + +#: pg_ctl.c:914 +msgid "waiting for server to start..." +msgstr "esperando que el servidor se inicie..." + +#: pg_ctl.c:919 pg_ctl.c:1024 pg_ctl.c:1116 pg_ctl.c:1241 +msgid " done\n" +msgstr " listo\n" + +#: pg_ctl.c:920 +msgid "server started\n" +msgstr "servidor iniciado\n" + +#: pg_ctl.c:923 pg_ctl.c:929 pg_ctl.c:1246 +msgid " stopped waiting\n" +msgstr " abandonando la espera\n" + +#: pg_ctl.c:924 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: el servidor no inició a tiempo\n" + +#: pg_ctl.c:930 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: no se pudo iniciar el servidor.\n" +"Examine el registro del servidor.\n" + +#: pg_ctl.c:938 +msgid "server starting\n" +msgstr "servidor iniciándose\n" + +#: pg_ctl.c:959 pg_ctl.c:1046 pg_ctl.c:1137 pg_ctl.c:1176 pg_ctl.c:1270 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: el archivo de PID «%s» no existe\n" + +#: pg_ctl.c:960 pg_ctl.c:1048 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1271 +msgid "Is server running?\n" +msgstr "¿Está el servidor en ejecución?\n" + +#: pg_ctl.c:966 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: no se puede detener el servidor;\n" +"un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:981 +msgid "server shutting down\n" +msgstr "servidor deteniéndose\n" + +#: pg_ctl.c:996 pg_ctl.c:1085 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"ATENCIÓN: el modo de respaldo en línea está activo\n" +"El apagado no se completará hasta que se invoque la función pg_stop_backup().\n" +"\n" + +#: pg_ctl.c:1000 pg_ctl.c:1089 +msgid "waiting for server to shut down..." +msgstr "esperando que el servidor se detenga..." + +#: pg_ctl.c:1016 pg_ctl.c:1107 +msgid " failed\n" +msgstr " falló\n" + +#: pg_ctl.c:1018 pg_ctl.c:1109 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: el servidor no se detiene\n" + +#: pg_ctl.c:1020 pg_ctl.c:1111 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"SUGERENCIA: La opción «-m fast» desconecta las sesiones inmediatamente\n" +"en lugar de esperar que cada sesión finalice por sí misma.\n" + +#: pg_ctl.c:1026 pg_ctl.c:1117 +msgid "server stopped\n" +msgstr "servidor detenido\n" + +#: pg_ctl.c:1049 +msgid "trying to start server anyway\n" +msgstr "intentando iniciae el servidor de todas maneras\n" + +#: pg_ctl.c:1058 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: no se puede reiniciar el servidor;\n" +"un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:1061 pg_ctl.c:1147 +msgid "Please terminate the single-user server and try again.\n" +msgstr "Por favor termine el servidor mono-usuario e intente nuevamente.\n" + +#: pg_ctl.c:1121 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: el proceso servidor antiguo (PID: %ld) parece no estar\n" + +#: pg_ctl.c:1123 +msgid "starting server anyway\n" +msgstr "iniciando el servidor de todas maneras\n" + +#: pg_ctl.c:1144 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: no se puede recargar el servidor;\n" +"un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:1153 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: la señal de recarga falló (PID: %ld): %s\n" + +#: pg_ctl.c:1158 +msgid "server signaled\n" +msgstr "se ha enviado una señal al servidor\n" + +#: pg_ctl.c:1183 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: no se puede promover el servidor;\n" +"un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:1191 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "" +"%s: no se puede promover el servidor;\n" +"el servidor no está en modo «standby»\n" + +#: pg_ctl.c:1201 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: no se pudo crear el archivo de señal de promoción «%s»: %s\n" + +#: pg_ctl.c:1207 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: no se pudo escribir al archivo de señal de promoción «%s»: %s\n" + +#: pg_ctl.c:1215 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: no se pudo enviar la señal de promoción (PID: %ld): %s\n" + +#: pg_ctl.c:1218 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: no se pudo eliminar el archivo de señal de promoción «%s»: %s\n" + +#: pg_ctl.c:1228 +msgid "waiting for server to promote..." +msgstr "esperando que el servidor se promueva..." + +#: pg_ctl.c:1242 +msgid "server promoted\n" +msgstr "servidor promovido\n" + +#: pg_ctl.c:1247 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: el servidor no se promovió a tiempo\n" + +#: pg_ctl.c:1253 +msgid "server promoting\n" +msgstr "servidor promoviendo\n" + +#: pg_ctl.c:1277 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: no se puede rotar el archivo de log; un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:1287 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: no se pudo crear el archivo de señal de rotación de log «%s»: %s\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: no se pudo escribir al archivo de señal de rotación de log «%s»: %s\n" + +#: pg_ctl.c:1301 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: no se pudo enviar la señal de rotación de log (PID: %ld): %s\n" + +#: pg_ctl.c:1304 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: no se pudo eliminar el archivo de señal de rotación de log «%s»: %s\n" + +#: pg_ctl.c:1309 +msgid "server signaled to rotate log file\n" +msgstr "se ha enviado una señal de rotación de log al servidor\n" + +#: pg_ctl.c:1356 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:1370 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: el servidor está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:1386 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: no hay servidor en ejecución\n" + +#: pg_ctl.c:1403 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: no se pudo enviar la señal %d (PID: %ld): %s\n" + +#: pg_ctl.c:1434 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: no se pudo encontrar el ejecutable propio\n" + +#: pg_ctl.c:1444 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: no se pudo encontrar el ejecutable postgres\n" + +#: pg_ctl.c:1514 pg_ctl.c:1548 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: no se pudo abrir el gestor de servicios\n" + +#: pg_ctl.c:1520 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: el servicio «%s» ya está registrado\n" + +#: pg_ctl.c:1531 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: no se pudo registrar el servicio «%s»: código de error %lu\n" + +#: pg_ctl.c:1554 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: el servicio «%s» no ha sido registrado\n" + +#: pg_ctl.c:1561 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: no se pudo abrir el servicio «%s»: código de error %lu\n" + +#: pg_ctl.c:1570 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: no se pudo dar de baja el servicio «%s»: código de error %lu\n" + +#: pg_ctl.c:1657 +msgid "Waiting for server startup...\n" +msgstr "Esperando que el servidor se inicie...\n" + +#: pg_ctl.c:1660 +msgid "Timed out waiting for server startup\n" +msgstr "Se agotó el tiempo de espera al inicio del servidor\n" + +#: pg_ctl.c:1664 +msgid "Server started and accepting connections\n" +msgstr "Servidor iniciado y aceptando conexiones\n" + +#: pg_ctl.c:1719 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: no se pudo iniciar el servicio «%s»: código de error %lu\n" + +#: pg_ctl.c:1789 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: ATENCIÓN: no se pueden crear tokens restrigidos en esta plataforma\n" + +#: pg_ctl.c:1802 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: no se pudo abrir el token de proceso: código de error %lu\n" + +#: pg_ctl.c:1816 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: no se pudo emplazar los SIDs: código de error %lu\n" + +#: pg_ctl.c:1843 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: no se pudo crear el token restringido: código de error %lu\n" + +#: pg_ctl.c:1874 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s: ATENCIÓN: no fue posible encontrar todas las funciones de gestión de tareas en la API del sistema\n" + +#: pg_ctl.c:1971 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: no se pudo obtener LUIDs para privilegios: código de error %lu\n" + +#: pg_ctl.c:1979 pg_ctl.c:1994 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: no se pudo obtener información de token: código de error %lu\n" + +#: pg_ctl.c:1988 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: memoria agotada\n" + +#: pg_ctl.c:2018 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Use «%s --help» para obtener más información.\n" + +#: pg_ctl.c:2026 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s es un programa para inicializar, iniciar, detener o controlar\n" +"un servidor PostgreSQL.\n" +"\n" + +#: pg_ctl.c:2027 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_ctl.c:2028 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D DATADIR] [-s] [-o OPCIONES]\n" + +#: pg_ctl.c:2029 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D DATADIR] [-l ARCHIVO] [-W] [-t SEGS] [-s]\n" +" [-o OPCIONES] [-p RUTA] [-c]\n" + +#: pg_ctl.c:2031 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D DATADIR] [-m MODO-DETENCIÓN] [-W] [-t SEGS] [-s]\n" + +#: pg_ctl.c:2032 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D DATADIR] [-m MODO-DETENCIÓN] [-W] [-t SEGS] [-s]\n" +" [-o OPCIONES]\n" + +#: pg_ctl.c:2034 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D DATADIR] [-s]\n" + +#: pg_ctl.c:2035 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATADIR]\n" + +#: pg_ctl.c:2036 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D DATADIR] [-W] [-t SEGS] [-s]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D DATADIR] [-s]\n" + +#: pg_ctl.c:2038 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill NOMBRE-SEÑAL ID-DE-PROCESO\n" + +#: pg_ctl.c:2040 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgstr "" +" %s register [-D DATADIR] [-N SERVICIO] [-U USUARIO] [-P PASSWORD]\n" +" [-S TIPO-INICIO] [-e ORIGEN] [-W] [-t SEGS] [-o OPCIONES]\n" + +#: pg_ctl.c:2042 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N SERVICIO]\n" + +#: pg_ctl.c:2045 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"Opciones comunes:\n" + +#: pg_ctl.c:2046 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " -D, --pgdata DATADIR ubicación del área de almacenamiento de datos\n" + +#: pg_ctl.c:2048 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr " -e ORIGEN origen para el log de eventos cuando se ejecuta como servicio\n" + +#: pg_ctl.c:2050 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr " -s, --silent mostrar sólo errores, no mensajes de información\n" + +#: pg_ctl.c:2051 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr " -t, --timeout=SEGS segundos a esperar cuando se use la opción -w\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión, luego salir\n" + +#: pg_ctl.c:2053 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait esperar hasta que la operación se haya completado (por omisión)\n" + +#: pg_ctl.c:2054 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait no esperar hasta que la operación se haya completado\n" + +#: pg_ctl.c:2055 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda, luego salir\n" + +#: pg_ctl.c:2056 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "Si la opción -D es omitida, se usa la variable de ambiente PGDATA.\n" + +#: pg_ctl.c:2058 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"Opciones para inicio y reinicio:\n" + +#: pg_ctl.c:2060 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr "" +" -c, --core-files permite que postgres produzca archivos\n" +" de volcado (core)\n" + +#: pg_ctl.c:2062 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files no aplicable en esta plataforma\n" + +#: pg_ctl.c:2064 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr " -l --log=ARCHIVO guardar el registro del servidor en ARCHIVO.\n" + +#: pg_ctl.c:2065 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=OPCIONES parámetros de línea de órdenes a pasar a postgres\n" +" (ejecutable del servidor de PostgreSQL) o initdb\n" + +#: pg_ctl.c:2067 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p RUTA-A-POSTGRES normalmente no es necesario\n" + +#: pg_ctl.c:2068 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"Opciones para detener o reiniciar:\n" + +#: pg_ctl.c:2069 +#, c-format +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, --mode=MODO puede ser «smart», «fast» o «immediate»\n" + +#: pg_ctl.c:2071 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"Modos de detención son:\n" + +#: pg_ctl.c:2072 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart salir después que todos los clientes se hayan desconectado\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast salir directamente, con apagado apropiado (por omisión)\n" + +#: pg_ctl.c:2074 +#, c-format +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr "" +" immediate salir sin apagado completo; se ejecutará recuperación\n" +" en el próximo inicio\n" + +#: pg_ctl.c:2076 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"Nombres de señales permitidos para kill:\n" + +#: pg_ctl.c:2080 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"Opciones para registrar y dar de baja:\n" + +#: pg_ctl.c:2081 +#, c-format +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr "" +" -N SERVICIO nombre de servicio con el cual registrar\n" +" el servidor PostgreSQL\n" + +#: pg_ctl.c:2082 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr "" +" -P CONTRASEÑA contraseña de la cuenta con la cual registrar\n" +" el servidor PostgreSQL\n" + +#: pg_ctl.c:2083 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr "" +" -U USUARIO nombre de usuario de la cuenta con la cual\n" +" registrar el servidor PostgreSQL\n" + +#: pg_ctl.c:2084 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr "" +" -S TIPO-INICIO tipo de inicio de servicio con que registrar\n" +" el servidor PostgreSQL\n" + +#: pg_ctl.c:2086 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"Tipos de inicio del servicio son:\n" + +#: pg_ctl.c:2087 +#, c-format +msgid " auto start service automatically during system startup (default)\n" +msgstr " auto iniciar automáticamente al inicio del sistema (por omisión)\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand iniciar el servicio en demanda\n" + +#: pg_ctl.c:2091 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_ctl.c:2117 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: modo de apagado «%s» no reconocido\n" + +#: pg_ctl.c:2146 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: nombre de señal «%s» no reconocido\n" + +#: pg_ctl.c:2163 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: tipo de inicio «%s» no reconocido\n" + +#: pg_ctl.c:2218 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: no se pudo determinar el directorio de datos usando la orden «%s»\n" + +#: pg_ctl.c:2242 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: el archivo de control parece estar corrupto\n" + +#: pg_ctl.c:2310 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: no puede ser ejecutado como «root»\n" +"Por favor conéctese (usando, por ejemplo, «su») con un usuario no privilegiado,\n" +"quien ejecutará el proceso servidor.\n" + +#: pg_ctl.c:2393 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: la opción -S no está soportada en esta plataforma\n" + +#: pg_ctl.c:2430 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" + +#: pg_ctl.c:2456 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: argumentos faltantes para envío de señal\n" + +#: pg_ctl.c:2474 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: modo de operación «%s» no reconocido\n" + +#: pg_ctl.c:2484 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: no se especificó operación\n" + +#: pg_ctl.c:2505 +#, c-format +msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "%s: no se especificó directorio de datos y la variable PGDATA no está definida\n" + +#~ msgid "pclose failed: %m" +#~ msgstr "pclose falló: %m" diff --git a/src/bin/pg_ctl/po/fr.po b/src/bin/pg_ctl/po/fr.po new file mode 100644 index 000000000000..3c72fe5f6084 --- /dev/null +++ b/src/bin/pg_ctl/po/fr.po @@ -0,0 +1,1012 @@ +# translation of pg_ctl.po to fr_fr +# french message translation file for pg_ctl +# +# Use these quotes: « %s » +# +# Guillaume Lelarge , 2003-2009. +# Stéphane Schildknecht , 2009. +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-26 06:46+0000\n" +"PO-Revision-Date: 2021-04-26 11:37+0200\n" +"Last-Translator: Guillaume Lelarge \n" +"Language-Team: PostgreSQLfr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "binaire « %s » invalide" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "n'a pas pu lire le binaire « %s »" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "n'a pas pu trouver un « %s » à exécuter" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "échec de %s() : %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "mémoire épuisée" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "commande non exécutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "commande introuvable" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "le processus fils a quitté avec le code de sortie %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "le processus fils a été terminé par l'exception 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "le processus fils a été terminé par le signal %d : %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "le processus fils a quitté avec un statut %d non reconnu" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "n'a pas pu obtenir le répertoire de travail : %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s : le répertoire « %s » n'existe pas\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s : le répertoire « %s » n'est pas un répertoire d'instance\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s : n'a pas pu ouvrir le fichier de PID « %s » : %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s : le fichier PID « %s » est vide\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s : données invalides dans le fichier de PID « %s »\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s : n'a pas pu démarrer le serveur : %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s : n'a pas pu démarrer le serveur à cause d'un échec de setsid() : %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s : n'a pas pu ouvrir le journal applicatif « %s » : %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s : n'a pas pu démarrer le serveur : code d'erreur %lu\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "" +"%s : n'a pas pu initialiser la taille des fichiers core, ceci est interdit\n" +"par une limite dure\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s : n'a pas pu lire le fichier « %s »\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s : le fichier d'options « %s » ne doit comporter qu'une seule ligne\n" + +#: pg_ctl.c:785 pg_ctl.c:974 pg_ctl.c:1070 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s : n'a pas pu envoyer le signal d'arrêt (PID : %ld) : %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"Le programme « %s » est nécessaire pour %s, mais n'a pas été trouvé\n" +"dans le même répertoire que « %s ».\n" +"Vérifiez votre installation.\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"Le programme « %s », trouvé par « %s », n'est pas de la même version\n" +"que %s.\n" +"Vérifiez votre installation.\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s : l'initialisation du système a échoué\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "" +"%s : un autre serveur semble en cours d'exécution ; le démarrage du serveur\n" +"va toutefois être tenté\n" + +#: pg_ctl.c:914 +msgid "waiting for server to start..." +msgstr "en attente du démarrage du serveur..." + +#: pg_ctl.c:919 pg_ctl.c:1024 pg_ctl.c:1116 pg_ctl.c:1241 +msgid " done\n" +msgstr " effectué\n" + +#: pg_ctl.c:920 +msgid "server started\n" +msgstr "serveur démarré\n" + +#: pg_ctl.c:923 pg_ctl.c:929 pg_ctl.c:1246 +msgid " stopped waiting\n" +msgstr " attente arrêtée\n" + +#: pg_ctl.c:924 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s : le serveur ne s'est pas lancé à temps\n" + +#: pg_ctl.c:930 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s : n'a pas pu démarrer le serveur\n" +"Examinez le journal applicatif.\n" + +#: pg_ctl.c:938 +msgid "server starting\n" +msgstr "serveur en cours de démarrage\n" + +#: pg_ctl.c:959 pg_ctl.c:1046 pg_ctl.c:1137 pg_ctl.c:1176 pg_ctl.c:1270 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s : le fichier de PID « %s » n'existe pas\n" + +#: pg_ctl.c:960 pg_ctl.c:1048 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1271 +msgid "Is server running?\n" +msgstr "Le serveur est-il en cours d'exécution ?\n" + +#: pg_ctl.c:966 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s : ne peut pas arrêter le serveur ; le serveur mono-utilisateur est en\n" +"cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:981 +msgid "server shutting down\n" +msgstr "serveur en cours d'arrêt\n" + +#: pg_ctl.c:996 pg_ctl.c:1085 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"ATTENTION : le mode de sauvegarde en ligne est activé.\n" +"L'arrêt ne surviendra qu'au moment où pg_stop_backup() sera appelé.\n" +"\n" + +#: pg_ctl.c:1000 pg_ctl.c:1089 +msgid "waiting for server to shut down..." +msgstr "en attente de l'arrêt du serveur..." + +#: pg_ctl.c:1016 pg_ctl.c:1107 +msgid " failed\n" +msgstr " a échoué\n" + +#: pg_ctl.c:1018 pg_ctl.c:1109 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s : le serveur ne s'est pas arrêté\n" + +#: pg_ctl.c:1020 pg_ctl.c:1111 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"ASTUCE : l'option « -m fast » déconnecte immédiatement les sessions plutôt que\n" +"d'attendre la déconnexion des sessions déjà présentes.\n" + +#: pg_ctl.c:1026 pg_ctl.c:1117 +msgid "server stopped\n" +msgstr "serveur arrêté\n" + +#: pg_ctl.c:1049 +msgid "trying to start server anyway\n" +msgstr "tentative de lancement du serveur malgré tout\n" + +#: pg_ctl.c:1058 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s : ne peut pas relancer le serveur ; le serveur mono-utilisateur est en\n" +"cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:1061 pg_ctl.c:1147 +msgid "Please terminate the single-user server and try again.\n" +msgstr "Merci d'arrêter le serveur mono-utilisateur et de réessayer.\n" + +#: pg_ctl.c:1121 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s : l'ancien processus serveur (PID : %ld) semble être parti\n" + +#: pg_ctl.c:1123 +msgid "starting server anyway\n" +msgstr "lancement du serveur malgré tout\n" + +#: pg_ctl.c:1144 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s : ne peut pas recharger le serveur ; le serveur mono-utilisateur est en\n" +"cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:1153 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s : n'a pas pu envoyer le signal de rechargement (PID : %ld) : %s\n" + +#: pg_ctl.c:1158 +msgid "server signaled\n" +msgstr "envoi d'un signal au serveur\n" + +#: pg_ctl.c:1183 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s : ne peut pas promouvoir le serveur ; le serveur mono-utilisateur est en\n" +"cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:1191 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s : ne peut pas promouvoir le serveur ; le serveur n'est pas en standby\n" + +#: pg_ctl.c:1201 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s : n'a pas pu créer le fichier « %s » signalant la promotion : %s\n" + +#: pg_ctl.c:1207 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s : n'a pas pu écrire le fichier « %s » signalant la promotion : %s\n" + +#: pg_ctl.c:1215 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s : n'a pas pu envoyer le signal de promotion (PID : %ld) : %s\n" + +#: pg_ctl.c:1218 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s : n'a pas pu supprimer le fichier « %s » signalant la promotion : %s\n" + +#: pg_ctl.c:1228 +msgid "waiting for server to promote..." +msgstr "en attente du serveur à promouvoir..." + +#: pg_ctl.c:1242 +msgid "server promoted\n" +msgstr "serveur promu\n" + +#: pg_ctl.c:1247 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s : le serveur ne s'est pas promu à temps\n" + +#: pg_ctl.c:1253 +msgid "server promoting\n" +msgstr "serveur en cours de promotion\n" + +#: pg_ctl.c:1277 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "" +"%s : ne peut pas faire une rotation de fichier de traces ; le serveur mono-utilisateur est en\n" +"cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:1287 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s : n'a pas pu créer le fichier « %s » de demande de rotation des fichiers de trace : %s\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s : n'a pas pu écrire le fichier « %s » de demande de rotation des fichiers de trace : %s\n" + +#: pg_ctl.c:1301 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s : n'a pas pu envoyer le signal de rotation des fichiers de trace (PID : %ld) : %s\n" + +#: pg_ctl.c:1304 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s : n'a pas pu supprimer le fichier « %s » signalant la demande de rotation des fichiers de trace : %s\n" + +#: pg_ctl.c:1309 +msgid "server signaled to rotate log file\n" +msgstr "envoi d'un signal au serveur pour faire une rotation des traces\n" + +#: pg_ctl.c:1356 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s : le serveur mono-utilisateur est en cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:1370 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s : le serveur est en cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:1386 +#, c-format +msgid "%s: no server running\n" +msgstr "%s : aucun serveur en cours d'exécution\n" + +#: pg_ctl.c:1403 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s : n'a pas pu envoyer le signal %d (PID : %ld) : %s\n" + +#: pg_ctl.c:1434 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s : n'a pas pu trouver l'exécutable du programme\n" + +#: pg_ctl.c:1444 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s : n'a pas pu trouver l'exécutable postgres\n" + +#: pg_ctl.c:1514 pg_ctl.c:1548 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s : n'a pas pu ouvrir le gestionnaire de services\n" + +#: pg_ctl.c:1520 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s : le service « %s » est déjà enregistré\n" + +#: pg_ctl.c:1531 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s : n'a pas pu enregistrer le service « %s » : code d'erreur %lu\n" + +#: pg_ctl.c:1554 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s : le service « %s » n'est pas enregistré\n" + +#: pg_ctl.c:1561 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s : n'a pas pu ouvrir le service « %s » : code d'erreur %lu\n" + +#: pg_ctl.c:1570 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s : n'a pas pu supprimer le service « %s » : code d'erreur %lu\n" + +#: pg_ctl.c:1657 +msgid "Waiting for server startup...\n" +msgstr "En attente du démarrage du serveur...\n" + +#: pg_ctl.c:1660 +msgid "Timed out waiting for server startup\n" +msgstr "Dépassement du délai pour le démarrage du serveur\n" + +#: pg_ctl.c:1664 +msgid "Server started and accepting connections\n" +msgstr "Serveur lancé et acceptant les connexions\n" + +#: pg_ctl.c:1719 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s : n'a pas pu démarrer le service « %s » : code d'erreur %lu\n" + +#: pg_ctl.c:1789 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s : ATTENTION : ne peut pas créer les jetons restreints sur cette plateforme\n" + +#: pg_ctl.c:1802 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s : n'a pas pu ouvrir le jeton du processus : code d'erreur %lu\n" + +#: pg_ctl.c:1816 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s : n'a pas pu allouer les SID : code d'erreur %lu\n" + +#: pg_ctl.c:1843 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s : n'a pas pu créer le jeton restreint : code d'erreur %lu\n" + +#: pg_ctl.c:1874 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s : ATTENTION : n'a pas pu localiser toutes les fonctions objet de job dans l'API système\n" + +#: pg_ctl.c:1971 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s : n'a pas pu obtenir les LUID pour les droits : code d'erreur %lu\n" + +#: pg_ctl.c:1979 pg_ctl.c:1994 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s : n'a pas pu obtenir l'information sur le jeton : code d'erreur %lu\n" + +#: pg_ctl.c:1988 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s : mémoire épuisée\n" + +#: pg_ctl.c:2018 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayer « %s --help » pour plus d'informations.\n" + +#: pg_ctl.c:2026 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s est un outil pour initialiser, démarrer, arrêter et contrôler un serveur\n" +"PostgreSQL.\n" +"\n" + +#: pg_ctl.c:2027 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: pg_ctl.c:2028 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D RÉP_DONNÉES] [-s] [-o OPTIONS]\n" + +#: pg_ctl.c:2029 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D RÉP_DONNÉES] [-l NOM_FICHIER] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p CHEMIN] [-c]\n" + +#: pg_ctl.c:2031 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D RÉP_DONNÉES] [-m MODE_ARRÊT] [-W] [-t SECS] [-s]\n" + +#: pg_ctl.c:2032 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D RÉP_DONNÉES] [-m MODE_ARRÊT] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" + +#: pg_ctl.c:2034 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D RÉP_DONNÉES] [-s]\n" + +#: pg_ctl.c:2035 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D RÉP_DONNÉES]\n" + +#: pg_ctl.c:2036 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D RÉP_DONNÉES] [-W] [-t SECS] [-s]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s reload [-D RÉP_DONNÉES] [-s]\n" + +#: pg_ctl.c:2038 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill NOM_SIGNAL PID\n" + +#: pg_ctl.c:2040 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgstr "" +" %s register [-D RÉP_DONNÉES] [-N NOM_SERVICE] [-U NOM_UTILISATEUR] [-P MOT_DE_PASSE]\n" +" [-S TYPE_DÉMARRAGE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" + +#: pg_ctl.c:2042 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N NOM_SERVICE]\n" + +#: pg_ctl.c:2045 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"Options générales :\n" + +#: pg_ctl.c:2046 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " -D, --pgdata=RÉP_DONNÉES emplacement de stockage du cluster\n" + +#: pg_ctl.c:2048 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr "" +" -e SOURCE source de l'événement pour la trace lors de\n" +" l'exécution en tant que service\n" + +#: pg_ctl.c:2050 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr "" +" -s, --silent affiche uniquement les erreurs, aucun message\n" +" d'informations\n" + +#: pg_ctl.c:2051 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr "" +" -t, --timeout=SECS durée en secondes à attendre lors de\n" +" l'utilisation de l'option -w\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" + +#: pg_ctl.c:2053 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait attend la fin de l'opération (par défaut)\n" + +#: pg_ctl.c:2054 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait n'attend pas la fin de l'opération\n" + +#: pg_ctl.c:2055 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" + +#: pg_ctl.c:2056 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "Si l'option -D est omise, la variable d'environnement PGDATA est utilisée.\n" + +#: pg_ctl.c:2058 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"Options pour le démarrage ou le redémarrage :\n" + +#: pg_ctl.c:2060 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, --core-files autorise postgres à produire des fichiers core\n" + +#: pg_ctl.c:2062 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files non applicable à cette plateforme\n" + +#: pg_ctl.c:2064 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr "" +" -l, --log=NOM_FICHIER écrit (ou ajoute) le journal du serveur dans\n" +" NOM_FICHIER\n" + +#: pg_ctl.c:2065 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=OPTIONS options de la ligne de commande à passer à\n" +" postgres (exécutable du serveur PostgreSQL)\n" +" ou à initdb\n" + +#: pg_ctl.c:2067 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p CHEMIN_POSTGRES normalement pas nécessaire\n" + +#: pg_ctl.c:2068 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"Options pour l'arrêt ou le redémarrage :\n" + +#: pg_ctl.c:2069 +#, c-format +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr "" +" -m, --mode=MODE MODE peut valoir « smart », « fast » ou\n" +" « immediate »\n" + +#: pg_ctl.c:2071 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"Les modes d'arrêt sont :\n" + +#: pg_ctl.c:2072 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart quitte après déconnexion de tous les clients\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast quitte directement, et arrête correctement (par défaut)\n" + +#: pg_ctl.c:2074 +#, c-format +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr "" +" immediate quitte sans arrêt complet ; entraîne une\n" +" restauration au démarrage suivant\n" + +#: pg_ctl.c:2076 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"Signaux autorisés pour kill :\n" + +#: pg_ctl.c:2080 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"Options d'enregistrement ou de dés-enregistrement :\n" + +#: pg_ctl.c:2081 +#, c-format +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr "" +" -N NOM_SERVICE nom du service utilisé pour l'enregistrement du\n" +" serveur PostgreSQL\n" + +#: pg_ctl.c:2082 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr "" +" -P MOT_DE_PASSE mot de passe du compte utilisé pour\n" +" l'enregistrement du serveur PostgreSQL\n" + +#: pg_ctl.c:2083 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr "" +" -U NOM_UTILISATEUR nom de l'utilisateur du compte utilisé pour\n" +" l'enregistrement du serveur PostgreSQL\n" + +#: pg_ctl.c:2084 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr "" +" -S TYPE_DÉMARRAGE type de démarrage du service pour enregistrer le\n" +" serveur PostgreSQL\n" + +#: pg_ctl.c:2086 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"Les types de démarrage sont :\n" + +#: pg_ctl.c:2087 +#, c-format +msgid " auto start service automatically during system startup (default)\n" +msgstr "" +" auto démarre le service automatiquement lors du démarrage du système\n" +" (par défaut)\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand démarre le service à la demande\n" + +#: pg_ctl.c:2091 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapporter les bogues à <%s>.\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil %s : %s\n" + +#: pg_ctl.c:2117 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s : mode d'arrêt non reconnu « %s »\n" + +#: pg_ctl.c:2146 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s : signal non reconnu « %s »\n" + +#: pg_ctl.c:2163 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s : type de redémarrage « %s » non reconnu\n" + +#: pg_ctl.c:2218 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s : n'a pas déterminer le répertoire des données en utilisant la commande « %s »\n" + +#: pg_ctl.c:2242 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s : le fichier de contrôle semble corrompu\n" + +#: pg_ctl.c:2310 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s : ne peut pas être exécuté en tant qu'utilisateur root\n" +"Connectez-vous (par exemple en utilisant « su ») sous l'utilisateur (non\n" +" privilégié) qui sera propriétaire du processus serveur.\n" + +#: pg_ctl.c:2393 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s : option -S non supportée sur cette plateforme\n" + +#: pg_ctl.c:2430 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" + +#: pg_ctl.c:2456 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s : arguments manquant pour le mode kill\n" + +#: pg_ctl.c:2474 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s : mode d'opération « %s » non reconnu\n" + +#: pg_ctl.c:2484 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s : aucune opération indiquée\n" + +#: pg_ctl.c:2505 +#, c-format +msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "" +"%s : aucun répertoire de bases de données indiqué et variable\n" +"d'environnement PGDATA non initialisée\n" + +#~ msgid "%s: could not create log file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le fichier de traces « %s » : %s\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapporter les bogues à .\n" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu modifier le répertoire par « %s » : %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "server is still starting up\n" +#~ msgstr "le serveur est toujours en cours de démarrage\n" + +#~ msgid "" +#~ "\n" +#~ "%s: this data directory appears to be running a pre-existing postmaster\n" +#~ msgstr "" +#~ "\n" +#~ "%s : ce répertoire des données semble être utilisé par un postmaster déjà existant\n" + +#~ msgid "%s: could not start server: exit code was %d\n" +#~ msgstr "%s : n'a pas pu démarrer le serveur : le code de sortie est %d\n" + +#~ msgid "%s: could not open process token: %lu\n" +#~ msgstr "%s : n'a pas pu ouvrir le jeton du processus : %lu\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide et quitte\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version et quitte\n" + +#~ msgid "" +#~ "%s is a utility to start, stop, restart, reload configuration files,\n" +#~ "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n" +#~ "\n" +#~ msgstr "" +#~ "%s est un outil qui permet de démarrer, arrêter, redémarrer, recharger les\n" +#~ "les fichiers de configuration, rapporter le statut d'un serveur PostgreSQL\n" +#~ "ou d'envoyer un signal à un processus PostgreSQL\n" +#~ "\n" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" + +#~ msgid "" +#~ "\n" +#~ "Options for stop, restart, or promote:\n" +#~ msgstr "" +#~ "\n" +#~ "Options pour l'arrêt, le redémarrage ou la promotion :\n" + +#~ msgid "" +#~ "(The default is to wait for shutdown, but not for start or restart.)\n" +#~ "\n" +#~ msgstr "" +#~ "(Le comportement par défaut attend l'arrêt, pas le démarrage ou le\n" +#~ "redémarrage.)\n" +#~ "\n" + +#~ msgid " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n" +#~ msgstr "" +#~ " %s start [-w] [-t SECS] [-D RÉP_DONNÉES] [-s] [-l NOM_FICHIER]\n" +#~ " [-o \"OPTIONS\"]\n" + +#~ msgid "%s: could not wait for server because of misconfiguration\n" +#~ msgstr "%s : n'a pas pu attendre le serveur à cause d'une mauvaise configuration\n" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option cannot use a relative socket directory specification\n" +#~ msgstr "" +#~ "\n" +#~ "%s : l'option -w ne peut pas utiliser un chemin relatif vers le répertoire de\n" +#~ "la socket\n" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option is not supported when starting a pre-9.1 server\n" +#~ msgstr "" +#~ "\n" +#~ "%s : l'option -w n'est pas supportée lors du démarrage d'un serveur pré-9.1\n" + +#~ msgid "pclose failed: %m" +#~ msgstr "échec de pclose : %m" diff --git a/src/bin/pg_ctl/po/ja.po b/src/bin/pg_ctl/po/ja.po new file mode 100644 index 000000000000..b16284c3e596 --- /dev/null +++ b/src/bin/pg_ctl/po/ja.po @@ -0,0 +1,899 @@ +# Japanese message translation file for pg_ctl +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# Shigehiro Honda , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_ctl (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:54+0900\n" +"PO-Revision-Date: 2020-08-21 23:23+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "カレントディレクトリを識別できませんでした: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "バイナリ\"%s\"は無効です" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "バイナリ\"%s\"を読み取れませんでした" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "実行する\"%s\"がありませんでした" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "ディレクトリ\"%s\"に移動できませんでした: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pcloseが失敗しました: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "メモリ不足です" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ポインタを複製できません(内部エラー)。\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "コマンドは実行形式ではありません" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "コマンドが見つかりません" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "子プロセスが終了コード%dで終了しました" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "子プロセスが例外0x%Xで終了しました" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "子プロセスはシグナル%dにより終了しました: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "子プロセスが未知のステータス%dで終了しました" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "現在の作業ディレクトリを取得できませんでした: %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: ディレクトリ \"%s\" は存在しません\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"にアクセスできませんでした: %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: ディレクトリ\"%s\"はデータベースクラスタディレクトリではありません\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: PIDファイル\"%s\"をオープンできませんでした: %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: PIDファイル\"%s\"が空です\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: PIDファイル\"%s\"内に無効なデータがあります\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: サーバに接続できませんでした: %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: setsid()に失敗したためサーバに接続できませんでした: %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: ログファイル \"%s\" をオープンできませんでした: %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: サーバの起動に失敗しました: エラーコード %lu\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "%s: コアファイルのサイズ制限を設定できません:固定の制限により許されていません\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: ファイル\"%s\"を読み取ることに失敗しました\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: オプションファイル\"%s\"は1行のみでなければなりません\n" + +#: pg_ctl.c:785 pg_ctl.c:975 pg_ctl.c:1071 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: 停止シグナルを送信できませんでした。(PID: %ld): %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"%2$sには\"%1$s\"プログラムが必要ですが、\"%3$s\"と同じディレクトリ\n" +"にありませんでした。\n" +"インストール状況を確認してください。\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じ\n" +"バージョンではありませんでした。\n" +"インストレーションを検査してください。\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: データベースシステムが初期化に失敗しました\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "%s: 他のサーバが動作中の可能性がありますが、とにかくpostmasterの起動を試みます。\n" + +#: pg_ctl.c:915 +msgid "waiting for server to start..." +msgstr "サーバの起動完了を待っています..." + +#: pg_ctl.c:920 pg_ctl.c:1025 pg_ctl.c:1117 pg_ctl.c:1242 +msgid " done\n" +msgstr "完了\n" + +#: pg_ctl.c:921 +msgid "server started\n" +msgstr "サーバ起動完了\n" + +#: pg_ctl.c:924 pg_ctl.c:930 pg_ctl.c:1247 +msgid " stopped waiting\n" +msgstr " 待機処理が停止されました\n" + +#: pg_ctl.c:925 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: サーバは時間内に停止しませんでした\n" + +#: pg_ctl.c:931 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: サーバを起動できませんでした。\n" +"ログ出力を確認してください。\n" + +#: pg_ctl.c:939 +msgid "server starting\n" +msgstr "サーバは起動中です。\n" + +#: pg_ctl.c:960 pg_ctl.c:1047 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1271 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: PIDファイル\"%s\"がありません\n" + +#: pg_ctl.c:961 pg_ctl.c:1049 pg_ctl.c:1139 pg_ctl.c:1178 pg_ctl.c:1272 +msgid "Is server running?\n" +msgstr "サーバが動作していますか?\n" + +#: pg_ctl.c:967 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "%s: サーバを停止できません。シングルユーザサーバ(PID: %ld)が動作しています。\n" + +#: pg_ctl.c:982 +msgid "server shutting down\n" +msgstr "サーバの停止中です\n" + +#: pg_ctl.c:997 pg_ctl.c:1086 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"警告: オンラインバックアップモードが実行中です。\n" +"pg_stop_backup()が呼び出されるまでシャットダウンは完了しません\n" +"\n" + +#: pg_ctl.c:1001 pg_ctl.c:1090 +msgid "waiting for server to shut down..." +msgstr "サーバ停止処理の完了を待っています..." + +#: pg_ctl.c:1017 pg_ctl.c:1108 +msgid " failed\n" +msgstr "失敗しました\n" + +#: pg_ctl.c:1019 pg_ctl.c:1110 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: サーバは停止していません\n" + +#: pg_ctl.c:1021 pg_ctl.c:1112 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"ヒント: \"-m fast\"オプションは、セッション切断が始まるまで待機するのではなく\n" +"即座にセッションを切断します。\n" + +#: pg_ctl.c:1027 pg_ctl.c:1118 +msgid "server stopped\n" +msgstr "サーバは停止しました\n" + +#: pg_ctl.c:1050 +msgid "trying to start server anyway\n" +msgstr "とにかくサーバの起動を試みます\n" + +#: pg_ctl.c:1059 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "%s: サーバを再起動できません。シングルユーザサーバ(PID: %ld)が動作中です。\n" + +#: pg_ctl.c:1062 pg_ctl.c:1148 +msgid "Please terminate the single-user server and try again.\n" +msgstr "シングルユーザサーバを終了させてから、再度実行してください\n" + +#: pg_ctl.c:1122 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: 古いサーバプロセス(PID: %ld)が動作していないようです\n" + +#: pg_ctl.c:1124 +msgid "starting server anyway\n" +msgstr "とにかくサーバを起動しています\n" + +#: pg_ctl.c:1145 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "%s: サーバをリロードできません。シングルユーザサーバ(PID: %ld)が動作中です\n" + +#: pg_ctl.c:1154 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: リロードシグナルを送信できませんでした。(PID: %ld): %s\n" + +#: pg_ctl.c:1159 +msgid "server signaled\n" +msgstr "サーバにシグナルを送信しました\n" + +#: pg_ctl.c:1184 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "%s: サーバを昇格できません; シングルユーザサーバ(PID: %ld)が動作中です\n" + +#: pg_ctl.c:1192 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s: サーバを昇格できません; サーバはスタンバイモードではありません\n" + +#: pg_ctl.c:1202 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: 昇格指示ファイル\"%s\"を作成することができませんでした: %s\n" + +#: pg_ctl.c:1208 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: 昇格指示ファイル\"%s\"に書き出すことができませんでした: %s\n" + +#: pg_ctl.c:1216 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: 昇格シグナルを送信できませんでした (PID: %ld): %s\n" + +#: pg_ctl.c:1219 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: 昇格指示ファイル\"%s\"の削除に失敗しました: %s\n" + +#: pg_ctl.c:1229 +msgid "waiting for server to promote..." +msgstr "サーバの昇格を待っています..." + +#: pg_ctl.c:1243 +msgid "server promoted\n" +msgstr "サーバは昇格しました\n" + +#: pg_ctl.c:1248 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: サーバは時間内に昇格しませんでした\n" + +#: pg_ctl.c:1254 +msgid "server promoting\n" +msgstr "サーバを昇格中です\n" + +#: pg_ctl.c:1278 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: ログをローテートできません; シングルユーザサーバが動作中です (PID: %ld)\n" + +#: pg_ctl.c:1288 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: ログローテート指示ファイル\"%s\"を作成することができませんでした: %s\n" + +#: pg_ctl.c:1294 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: ログローテート指示ファイル\"%s\"に書き出すことができませんでした: %s\n" + +#: pg_ctl.c:1302 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: ログローテートシグナルを送信できませんでした (PID: %ld): %s\n" + +#: pg_ctl.c:1305 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: ログローテーション指示ファイル\"%s\"の削除に失敗しました: %s\n" + +#: pg_ctl.c:1310 +msgid "server signaled to rotate log file\n" +msgstr "サーバがログローテートをシグナルされました\n" + +#: pg_ctl.c:1357 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: シングルユーザサーバが動作中です(PID: %ld)\n" + +#: pg_ctl.c:1371 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: サーバが動作中です(PID: %ld)\n" + +#: pg_ctl.c:1387 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: サーバが動作していません\n" + +#: pg_ctl.c:1404 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: シグナル%dを送信できませんでした(PID: %ld): %s\n" + +#: pg_ctl.c:1435 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 本プログラムの実行ファイルの検索に失敗しました\n" + +#: pg_ctl.c:1445 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: postgres の実行ファイルが見つかりません\n" + +#: pg_ctl.c:1515 pg_ctl.c:1549 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: サービスマネージャのオープンに失敗しました\n" + +#: pg_ctl.c:1521 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: サービス\\\"%s\\\"は登録済みです\n" + +#: pg_ctl.c:1532 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: サービス\"%s\"の登録に失敗しました: エラーコード %lu\n" + +#: pg_ctl.c:1555 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: サービス\"%s\"は登録されていません\n" + +#: pg_ctl.c:1562 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: サービス\"%s\"のオープンに失敗しました: エラーコード %lu\n" + +#: pg_ctl.c:1571 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: サービス\"%s\"の登録削除に失敗しました: エラーコード %lu\n" + +#: pg_ctl.c:1658 +msgid "Waiting for server startup...\n" +msgstr "サーバの起動完了を待っています...\n" + +#: pg_ctl.c:1661 +msgid "Timed out waiting for server startup\n" +msgstr "サーバの起動待機がタイムアウトしました\n" + +#: pg_ctl.c:1665 +msgid "Server started and accepting connections\n" +msgstr "サーバは起動し、接続を受け付けています\n" + +#: pg_ctl.c:1720 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: サービス\"%s\"の起動に失敗しました: エラーコード %lu\n" + +#: pg_ctl.c:1790 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: 警告: このプラットフォームでは制限付きトークンを作成できません\n" + +#: pg_ctl.c:1803 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: プロセストークンをオープンできませんでした: エラーコード %lu\n" + +#: pg_ctl.c:1817 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: SIDを割り当てられませんでした: エラーコード %lu\n" + +#: pg_ctl.c:1844 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: 制限付きトークンを作成できませんでした: エラーコード %lu\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s: 警告: システムAPI内にすべてのジョブオブジェクト関数を格納できませんでした\n" + +#: pg_ctl.c:1972 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: 権限の LUID を取得できません: エラーコード %lu\n" + +#: pg_ctl.c:1980 pg_ctl.c:1995 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: トークン情報を取得できませんでした: エラーコード %lu\n" + +#: pg_ctl.c:1989 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: メモリ不足です\n" + +#: pg_ctl.c:2019 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"を実行してください。\n" + +#: pg_ctl.c:2027 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "%sはPostgreSQLサーバの初期化、起動、停止、制御を行うユーティリティです。\n" + +#: pg_ctl.c:2028 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_ctl.c:2029 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" + +#: pg_ctl.c:2030 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" + +#: pg_ctl.c:2032 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" + +#: pg_ctl.c:2033 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" + +#: pg_ctl.c:2035 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D DATADIR] [-s]\n" + +#: pg_ctl.c:2036 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATADIR]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" + +#: pg_ctl.c:2038 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D DATADIR] [-s]\n" + +#: pg_ctl.c:2039 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill SIGNALNAME PID\n" + +#: pg_ctl.c:2041 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgstr "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" + +#: pg_ctl.c:2043 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N SERVICENAME]\n" + +#: pg_ctl.c:2046 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"共通のオプション:\n" + +#: pg_ctl.c:2047 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " -D, --pgdata=DATADIR データベース格納領域の場所\n" + +#: pg_ctl.c:2049 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr " -e SOURCE サービスとして起動させたときのログのイベントソース\n" + +#: pg_ctl.c:2051 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr " -s, --silent エラーメッセージのみを表示、情報メッセージは表示しない\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr " -t, --timeout=SECS -wオプションを使用する時に待機する秒数\n" + +#: pg_ctl.c:2053 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_ctl.c:2054 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait 操作が完了するまで待機 (デフォルト)\n" + +#: pg_ctl.c:2055 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait 作業の完了を待たない\n" + +#: pg_ctl.c:2056 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_ctl.c:2057 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "-Dオプションの省略時はPGDATA環境変数が使用されます。\n" + +#: pg_ctl.c:2059 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"起動、再起動のオプション\n" + +#: pg_ctl.c:2061 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, --core-files postgresのコアファイル生成を許可\n" + +#: pg_ctl.c:2063 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files このプラットフォームでは適用されない\n" + +#: pg_ctl.c:2065 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr " -l, --log FILENAME サーバログをFILENAMEへ書き込む(または追加する)\n" + +#: pg_ctl.c:2066 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=OPTIONS postgres(PostgreSQLサーバ実行ファイル)または\n" +" initdb に渡すコマンドラインオプション\n" + +#: pg_ctl.c:2068 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p PATH-TO-POSTGRES 通常は不要\n" + +#: pg_ctl.c:2069 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"停止、再起動のオプション\n" + +#: pg_ctl.c:2070 +#, c-format +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, --mode=MODE MODEは\"smart\"、\"fast\"、\"immediate\"のいずれか\n" + +#: pg_ctl.c:2072 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"シャットダウンモードは以下の通り:\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart 全クライアントの接続切断後に停止\n" + +#: pg_ctl.c:2074 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast 適切な手続きで直ちに停止(デフォルト)\n" + +#: pg_ctl.c:2075 +#, c-format +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr " immediate 適切な手続き抜きで停止; 再起動時にはリカバリが実行される\n" + +#: pg_ctl.c:2077 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"killモードで利用できるシグナル名:\n" + +#: pg_ctl.c:2081 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"登録、登録解除のオプション:\n" + +#: pg_ctl.c:2082 +#, c-format +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr " -N SERVICENAME PostgreSQLサーバを登録する際のサービス名\n" + +#: pg_ctl.c:2083 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr " -P PASSWORD PostgreSQLサーバを登録するためのアカウントのパスワード\n" + +#: pg_ctl.c:2084 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr " -U USERNAME PostgreSQLサーバを登録するためのアカウント名\n" + +#: pg_ctl.c:2085 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr " -S START-TYPE PostgreSQLサーバを登録する際のサービス起動タイプ\n" + +#: pg_ctl.c:2087 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"起動タイプは以下の通り:\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " auto start service automatically during system startup (default)\n" +msgstr " auto システムの起動時にサービスを自動的に開始(デフォルト)\n" + +#: pg_ctl.c:2089 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand 要求に応じてサービスを開始\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: pg_ctl.c:2093 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_ctl.c:2118 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: 不正なシャットダウンモード\"%s\"\n" + +#: pg_ctl.c:2147 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: 不正なシグナル名\"%s\"\n" + +#: pg_ctl.c:2164 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: 不正な起動タイプ\"%s\"\n" + +#: pg_ctl.c:2219 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: コマンド\"%s\"を使用するデータディレクトリを決定できませんでした\n" + +#: pg_ctl.c:2243 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: 制御ファイルが壊れているようです\n" + +#: pg_ctl.c:2311 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: rootでは実行できません\n" +"サーバプロセスの所有者となる(非特権)ユーザとして(\"su\"などを使用して)\n" +"ログインしてください。\n" + +#: pg_ctl.c:2395 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: -Sオプションはこのプラットフォームでサポートされていません\n" + +#: pg_ctl.c:2432 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: コマンドライン引数が多すぎます(先頭は\"%s\")\n" + +#: pg_ctl.c:2458 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: killモード用の引数がありません\n" + +#: pg_ctl.c:2476 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: 操作モード\"%s\"は不明です\n" + +#: pg_ctl.c:2486 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: 操作モードが指定されていません\n" + +#: pg_ctl.c:2507 +#, c-format +msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "%s: データベースの指定も、PGDATA環境変数の設定もありません\n" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "子プロセスがシグナル%dで終了しました" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "子プロセスがシグナル%sで終了しました" + +#~ msgid "pclose failed: %s" +#~ msgstr "pcloseが失敗しました: %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "シンボリックリンク\"%s\"の読み取りに失敗しました" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "ディレクトリ\"%s\"に移動できませんでした: %s" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "現在のディレクトリを特定できませんでした: %s" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "不具合はまで報告してください。\n" diff --git a/src/bin/pg_ctl/po/ko.po b/src/bin/pg_ctl/po/ko.po new file mode 100644 index 000000000000..8ba592369b3a --- /dev/null +++ b/src/bin/pg_ctl/po/ko.po @@ -0,0 +1,894 @@ +# Korean message translation file for PostgreSQL pg_ctl +# Ioseph Kim , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_ctl (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:44+0000\n" +"PO-Revision-Date: 2020-10-06 11:22+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean Team \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "현재 디렉터리를 알 수 없음: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "잘못된 바이너리 파일 \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" 바이너리 파일을 읽을 수 없음" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "실행할 \"%s\" 파일을 찾을 수 없음" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" 이름의 디렉터리로 이동할 수 없습니다: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "\"%s\" 심벌릭 링크를 읽을 수 없음: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose 실패: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "메모리 부족" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null 포인터를 복제할 수 없음(내부 오류)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "명령을 실행할 수 없음" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "명령어를 찾을 수 없음" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "하위 프로세스가 종료되었음, 종료 코드 %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "0x%X 예외처리로 하위 프로세스가 종료되었음" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "하위 프로세스가 종료되었음, 시그널 %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "하위 프로세스가 종료되었음, 알수 없는 상태 %d" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "현재 작업 디렉터리를 알 수 없음: %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: \"%s\" 디렉터리 없음\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리에 액세스할 수 없음: %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: 지정한 \"%s\" 디렉터리는 데이터베이스 클러스트 디렉터리가 아님\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: \"%s\" PID 파일을 열 수 없음: %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: \"%s\" PID 파일에 내용이 없습니다\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: \"%s\" PID 파일이 비었음\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: 서버를 시작 할 수 없음: %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: setsid() 실패로 서버를 시작 할 수 없음: %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: \"%s\" 로그 파일을 열 수 없음: %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: 서버를 시작할 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "" +"%s: 코어 파일 크기 한도를 설정할 수 없음, 하드 디스크 용량 초과로 허용되지 않" +"음\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: \"%s\" 파일을 읽을 수 없음\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: \"%s\" 환경설정파일은 반드시 한 줄을 가져야한다?\n" + +#: pg_ctl.c:785 pg_ctl.c:975 pg_ctl.c:1071 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: stop 시그널을 보낼 수 없음 (PID: %ld): %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"\"%s\" 프로그램은 %s 에서 필요로 합니다. 그런데, 이 파일이\n" +"\"%s\" 디렉터리 안에 없습니다.\n" +"설치 상태를 확인해 주십시오.\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"\"%s\" 프로그램을 \"%s\" 에서 필요해서 찾았지만 이 파일은\n" +"%s 버전과 같지 않습니다.\n" +"설치 상태를 확인해 주십시오.\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: 데이터베이스 초기화 실패\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "%s: 다른 서버가 가동 중인 것 같음; 어째든 서버 가동을 시도함\n" + +#: pg_ctl.c:915 +msgid "waiting for server to start..." +msgstr "서버를 시작하기 위해 기다리는 중..." + +#: pg_ctl.c:920 pg_ctl.c:1025 pg_ctl.c:1117 pg_ctl.c:1247 +msgid " done\n" +msgstr " 완료\n" + +#: pg_ctl.c:921 +msgid "server started\n" +msgstr "서버 시작됨\n" + +#: pg_ctl.c:924 pg_ctl.c:930 pg_ctl.c:1252 +msgid " stopped waiting\n" +msgstr " 중지 기다리는 중\n" + +#: pg_ctl.c:925 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: 서버가 제 시간에 시작되지 못했음\n" + +#: pg_ctl.c:931 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: 서버를 시작 할 수 없음\n" +"로그 출력을 살펴보십시오.\n" + +#: pg_ctl.c:939 +msgid "server starting\n" +msgstr "서버를 시작합니다\n" + +#: pg_ctl.c:960 pg_ctl.c:1047 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1276 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: \"%s\" PID 파일이 없습니다\n" + +#: pg_ctl.c:961 pg_ctl.c:1049 pg_ctl.c:1139 pg_ctl.c:1178 pg_ctl.c:1277 +msgid "Is server running?\n" +msgstr "서버가 실행 중입니까?\n" + +#: pg_ctl.c:967 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "%s: 서버 중지 실패; 단일 사용자 서버가 실행 중 (PID: %ld)\n" + +#: pg_ctl.c:982 +msgid "server shutting down\n" +msgstr "서버를 멈춥니다\n" + +#: pg_ctl.c:997 pg_ctl.c:1086 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"경고: 온라인 백업 모드가 활성 상태입니다.\n" +"pg_stop_backup()이 호출될 때까지 종료가 완료되지 않습니다.\n" +"\n" + +#: pg_ctl.c:1001 pg_ctl.c:1090 +msgid "waiting for server to shut down..." +msgstr "서버를 멈추기 위해 기다리는 중..." + +#: pg_ctl.c:1017 pg_ctl.c:1108 +msgid " failed\n" +msgstr " 실패\n" + +#: pg_ctl.c:1019 pg_ctl.c:1110 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: 서버를 멈추지 못했음\n" + +#: pg_ctl.c:1021 pg_ctl.c:1112 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"힌트: \"-m fast\" 옵션을 사용하면 접속한 세션들을 즉시 정리합니다.\n" +"이 옵션을 사용하지 않으면 접속한 세션들 스스로 끊을 때까지 기다립니다.\n" + +#: pg_ctl.c:1027 pg_ctl.c:1118 +msgid "server stopped\n" +msgstr "서버 멈추었음\n" + +#: pg_ctl.c:1050 +msgid "trying to start server anyway\n" +msgstr "어째든 서버를 시작해 봅니다\n" + +#: pg_ctl.c:1059 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: 서버를 다시 시작 할 수 없음; 단일사용자 서버가 실행 중임 (PID: %ld)\n" + +#: pg_ctl.c:1062 pg_ctl.c:1148 +msgid "Please terminate the single-user server and try again.\n" +msgstr "단일 사용자 서버를 멈추고 다시 시도하십시오.\n" + +#: pg_ctl.c:1122 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: 이전 서버 프로세스(PID: %ld)가 없어졌습니다\n" + +#: pg_ctl.c:1124 +msgid "starting server anyway\n" +msgstr "어째든 서버를 시작합니다\n" + +#: pg_ctl.c:1145 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: 서버 환경설정을 다시 불러올 수 없음; 단일 사용자 서버가 실행 중임 (PID: " +"%ld)\n" + +#: pg_ctl.c:1154 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: reload 시그널을 보낼 수 없음 (PID: %ld): %s\n" + +#: pg_ctl.c:1159 +msgid "server signaled\n" +msgstr "서버가 시스템 시그널을 받았음\n" + +#: pg_ctl.c:1184 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "%s: 운영서버 전환 실패; 단일사용자 서버가 실행 중(PID: %ld)\n" + +#: pg_ctl.c:1192 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s: 운영서버 전환 실패; 서버가 대기 모드로 상태가 아님\n" + +#: pg_ctl.c:1207 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: 운영전환 시그널 파일인 \"%s\" 파일을 만들 수 없음: %s\n" + +#: pg_ctl.c:1213 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: 운영전환 시그널 파일인 \"%s\" 파일에 쓰기 실패: %s\n" + +#: pg_ctl.c:1221 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: 운영전환 시그널을 서버(PID: %ld)로 보낼 수 없음: %s\n" + +#: pg_ctl.c:1224 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: 운영전환 시그널 파일인 \"%s\" 파일을 지울 수 없음: %s\n" + +#: pg_ctl.c:1234 +msgid "waiting for server to promote..." +msgstr "서버를 운영 모드로 전환하는 중 ..." + +#: pg_ctl.c:1248 +msgid "server promoted\n" +msgstr "운영 모드 전환 완료\n" + +#: pg_ctl.c:1253 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: 서버를 제 시간에 운영 모드로 전환하지 못했음\n" + +#: pg_ctl.c:1259 +msgid "server promoting\n" +msgstr "서버를 운영 모드로 전환합니다\n" + +#: pg_ctl.c:1283 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: 서버 로그 파일을 바꿀 수 없음; 단일 사용자 서버가 실행 중임 (PID: %ld)\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: 로그 전환 시그널 파일인 \"%s\" 파일을 만들 수 없음: %s\n" + +#: pg_ctl.c:1299 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: 로그 전환 시그널 파일인 \"%s\" 파일에 쓰기 실패: %s\n" + +#: pg_ctl.c:1307 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: 로그 전환 시그널을 보낼 수 없음 (PID: %ld): %s\n" + +#: pg_ctl.c:1310 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: 로그 전환 시그널 파일인 \"%s\" 파일을 지울 수 없음: %s\n" + +#: pg_ctl.c:1315 +msgid "server signaled to rotate log file\n" +msgstr "서버가 로그 전환 시그널을 받았음\n" + +#: pg_ctl.c:1362 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: 단일사용자 서버가 실행 중임 (PID: %ld)\n" + +#: pg_ctl.c:1376 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: 서버가 실행 중임 (PID: %ld)\n" + +#: pg_ctl.c:1392 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: 가동 중인 서버가 없음\n" + +#: pg_ctl.c:1409 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: %d 시그널을 보낼 수 없음 (PID: %ld): %s\n" + +#: pg_ctl.c:1440 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 실행 가능한 프로그램을 찾을 수 없습니다\n" + +#: pg_ctl.c:1450 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: 실행 가능한 postgres 프로그램을 찾을 수 없음\n" + +#: pg_ctl.c:1520 pg_ctl.c:1554 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: 서비스 관리자를 열 수 없음\n" + +#: pg_ctl.c:1526 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: \"%s\" 서비스가 이미 등록 되어 있음\n" + +#: pg_ctl.c:1537 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" 서비스를 등록할 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1560 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: \"%s\" 서비스가 등록되어 있지 않음\n" + +#: pg_ctl.c:1567 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" 서비스를 열 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1576 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" 서비스를 서비스 목록에서 뺄 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1663 +msgid "Waiting for server startup...\n" +msgstr "서버를 시작하기 위해 기다리는 중...\n" + +#: pg_ctl.c:1666 +msgid "Timed out waiting for server startup\n" +msgstr "서버 시작을 기다리는 동안 시간 초과됨\n" + +#: pg_ctl.c:1670 +msgid "Server started and accepting connections\n" +msgstr "서버가 시작되었으며 연결을 허용함\n" + +#: pg_ctl.c:1725 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" 서비스를 시작할 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1795 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: 경고: 이 운영체제에서 restricted token을 만들 수 없음\n" + +#: pg_ctl.c:1808 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: 프로세스 토큰을 열 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1822 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: SID를 할당할 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1849 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: restricted token을 만들 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1880 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s: 경고: 시스템 API에서 모든 job 객체 함수를 찾을 수 없음\n" + +#: pg_ctl.c:1977 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: 접근 권한용 LUID를 구할 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1985 pg_ctl.c:2000 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: 토큰 정보를 구할 수 없음: 오류 코드 %lu\n" + +#: pg_ctl.c:1994 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: 메모리 부족\n" + +#: pg_ctl.c:2024 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 자세한 사용법은 \"%s --help\"\n" + +#: pg_ctl.c:2032 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s 프로그램은 PostgreSQL 서버를 초기화, 시작, 중지, 제어하는 도구입니다.\n" +"\n" + +#: pg_ctl.c:2033 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_ctl.c:2034 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D 데이터디렉터리] [-s] [-o 옵션]\n" + +#: pg_ctl.c:2035 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D 데이터디렉터리] [-l 파일이름] [-W] [-t 초] [-s]\n" +" [-o 옵션] [-p 경로] [-c]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D 데이터디렉터리] [-m 중지방법] [-W] [-t 초] [-s]\n" + +#: pg_ctl.c:2038 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D 데이터디렉터리] [-m 중지방법] [-W] [-t 초] [-s]\n" +" [-o 옵션] [-c]\n" + +#: pg_ctl.c:2040 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D 데이터디렉터리] [-s]\n" + +#: pg_ctl.c:2041 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D 데이터디렉터리]\n" + +#: pg_ctl.c:2042 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D 데이터디렉터리] [-W] [-t 초] [-s]\n" + +#: pg_ctl.c:2043 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D 데이터디렉터리] [-s]\n" + +#: pg_ctl.c:2044 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill 시그널이름 PID\n" + +#: pg_ctl.c:2046 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o " +"OPTIONS]\n" +msgstr "" +" %s register [-D 데이터디렉터리] [-N 서비스이름] [-U 사용자이름] [-P 암" +"호]\n" +" [-S 시작형태] [-e SOURCE] [-w] [-t 초] [-o 옵션]\n" + +#: pg_ctl.c:2048 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N 서비스이름]\n" + +#: pg_ctl.c:2051 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"일반 옵션들:\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr "" +" -D, --pgdata=데이터디렉터리 데이터베이스 자료가 저장되어있는 디렉터리\n" + +#: pg_ctl.c:2054 +#, c-format +msgid "" +" -e SOURCE event source for logging when running as a service\n" +msgstr "" +" -e SOURCE 서비스가 실행 중일때 쌓을 로그를 위한 이벤트 소스\n" + +#: pg_ctl.c:2056 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr "" +" -s, --silent 일반적인 메시지는 보이지 않고, 오류만 보여줌\n" + +#: pg_ctl.c:2057 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr " -t, --timeout=초 -w 옵션 사용 시 대기 시간(초)\n" + +#: pg_ctl.c:2058 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: pg_ctl.c:2059 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait 작업이 끝날 때까지 기다림 (기본값)\n" + +#: pg_ctl.c:2060 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait 작업이 끝날 때까지 기다리지 않음\n" + +#: pg_ctl.c:2061 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_ctl.c:2062 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "-D 옵션을 사용하지 않으면, PGDATA 환경변수값을 사용함.\n" + +#: pg_ctl.c:2064 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"start, restart 때 사용할 수 있는 옵션들:\n" + +#: pg_ctl.c:2066 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, --core-files 코어 덤프 파일을 만듬\n" + +#: pg_ctl.c:2068 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files 이 플랫폼에서는 사용할 수 없음\n" + +#: pg_ctl.c:2070 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr " -l, --log=로그파일 서버 로그를 이 로그파일에 기록함\n" + +#: pg_ctl.c:2071 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=옵션들 PostgreSQL 서버프로그램인 postgres나 initdb\n" +" 명령에서 사용할 명령행 옵션들\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p PATH-TO-POSTGRES 보통은 필요치 않음\n" + +#: pg_ctl.c:2074 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"stop, restart 때 사용 할 수 있는 옵션들:\n" + +#: pg_ctl.c:2075 +#, c-format +msgid "" +" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr "" +" -m, --mode=모드 모드는 \"smart\", \"fast\", \"immediate\" 중 하나\n" + +#: pg_ctl.c:2077 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"중지방법 설명:\n" + +#: pg_ctl.c:2078 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart 모든 클라이언트의 연결이 끊기게 되면 중지 됨\n" + +#: pg_ctl.c:2079 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr "" +" fast 클라이언트의 연결을 강제로 끊고 정상적으로 중지 됨 (기본값)\n" + +#: pg_ctl.c:2080 +#, c-format +msgid "" +" immediate quit without complete shutdown; will lead to recovery on " +"restart\n" +msgstr "" +" immediate 그냥 무조건 중지함; 다시 시작할 때 복구 작업을 할 수도 있음\n" + +#: pg_ctl.c:2082 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"사용할 수 있는 중지용(for kill) 시그널 이름:\n" + +#: pg_ctl.c:2086 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"서비스 등록/제거용 옵션들:\n" + +#: pg_ctl.c:2087 +#, c-format +msgid "" +" -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr " -N SERVICENAME 서비스 목록에 등록될 PostgreSQL 서비스 이름\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr " -P PASSWORD 이 서비스를 실행할 사용자의 암호\n" + +#: pg_ctl.c:2089 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr " -U USERNAME 이 서비스를 실행할 사용자 이름\n" + +#: pg_ctl.c:2090 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr " -S 시작형태 서비스로 등록된 PostgreSQL 서버 시작 방법\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"시작형태 설명:\n" + +#: pg_ctl.c:2093 +#, c-format +msgid "" +" auto start service automatically during system startup (default)\n" +msgstr " auto 시스템이 시작되면 자동으로 서비스가 시작됨 (초기값)\n" + +#: pg_ctl.c:2094 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand 수동 시작\n" + +#: pg_ctl.c:2097 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"문제점 보고 주소: <%s>\n" + +#: pg_ctl.c:2098 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: pg_ctl.c:2123 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: 잘못된 중지 방법 \"%s\"\n" + +#: pg_ctl.c:2152 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: 잘못된 시그널 이름 \"%s\"\n" + +#: pg_ctl.c:2169 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: 알 수 없는 시작형태 \"%s\"\n" + +#: pg_ctl.c:2224 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: \"%s\" 명령에서 사용할 데이터 디렉터리를 알 수 없음\n" + +#: pg_ctl.c:2248 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: 컨트롤 파일이 깨졌음\n" + +#: pg_ctl.c:2316 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: root로 이 프로그램을 실행하지 마십시오\n" +"시스템관리자 권한이 없는, 서버프로세스의 소유주가 될 일반 사용자로\n" +"로그인 해서(\"su\", \"runas\" 같은 명령 이용) 실행하십시오.\n" + +#: pg_ctl.c:2400 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: -S 옵션은 이 운영체제에서는 지원하지 않음\n" + +#: pg_ctl.c:2437 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: 너무 많은 명령행 인수들 (시작 \"%s\")\n" + +#: pg_ctl.c:2463 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: kill 작업에 필요한 인수가 빠졌습니다\n" + +#: pg_ctl.c:2481 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: 알 수 없는 작업 모드 \"%s\"\n" + +#: pg_ctl.c:2491 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: 수행할 작업을 지정하지 않았습니다\n" + +#: pg_ctl.c:2512 +#, c-format +msgid "" +"%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "%s: -D 옵션도 없고, PGDATA 환경변수값도 지정되어 있지 않습니다.\n" diff --git a/src/bin/pg_ctl/po/ru.po b/src/bin/pg_ctl/po/ru.po new file mode 100644 index 000000000000..86fa24b9e03a --- /dev/null +++ b/src/bin/pg_ctl/po/ru.po @@ -0,0 +1,1032 @@ +# Russian message translation file for pg_ctl +# Copyright (C) 2004-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Oleg Bartunov , 2004. +# Serguei A. Mokhov , 2004-2005. +# Sergey Burladyan , 2009, 2012. +# Andrey Sudnik , 2010. +# Dmitriy Olshevskiy , 2014. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_ctl (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2020-10-29 15:01+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не удалось определить текущий каталог: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "неверный исполняемый файл \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "не удалось прочитать исполняемый файл \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "не удалось найти запускаемый файл \"%s\"" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не удалось перейти в каталог \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не удалось прочитать символическую ссылку \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "ошибка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "нехватка памяти" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "неисполняемая команда" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "команда не найдена" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "дочерний процесс завершился с кодом возврата %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "дочерний процесс прерван исключением 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "дочерний процесс завершён по сигналу %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "дочерний процесс завершился с нераспознанным состоянием %d" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "не удалось определить текущий рабочий каталог: %s\n" + +#: pg_ctl.c:258 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: каталог \"%s\" не существует\n" + +#: pg_ctl.c:261 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: нет доступа к каталогу \"%s\": %s\n" + +#: pg_ctl.c:274 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: каталог \"%s\" не содержит структуры кластера баз данных\n" + +#: pg_ctl.c:287 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: не удалось открыть файл PID \"%s\": %s\n" + +#: pg_ctl.c:296 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: файл PID \"%s\" пуст\n" + +#: pg_ctl.c:299 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: неверные данные в файле PID \"%s\"\n" + +#: pg_ctl.c:458 pg_ctl.c:500 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: не удалось запустить сервер: %s\n" + +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: не удалось запустить сервер из-за ошибки в setsid(): %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: не удалось открыть файл журнала \"%s\": %s\n" + +#: pg_ctl.c:565 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: не удалось запустить сервер (код ошибки: %lu)\n" + +#: pg_ctl.c:712 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "" +"%s: не удалось ограничить размер дампа памяти; запрещено жёстким " +"ограничением\n" + +#: pg_ctl.c:738 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: не удалось прочитать файл \"%s\"\n" + +#: pg_ctl.c:743 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: в файле параметров \"%s\" должна быть ровно одна строка\n" + +#: pg_ctl.c:785 pg_ctl.c:975 pg_ctl.c:1071 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: не удалось отправить сигнал остановки (PID: %ld): %s\n" + +#: pg_ctl.c:813 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"Программа \"%s\" необходима для %s, но не найдена\n" +"в каталоге \"%s\".\n" +"Проверьте правильность установки СУБД.\n" + +#: pg_ctl.c:818 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"Программа \"%s\" найдена программой \"%s\",\n" +"но её версия отличается от версии %s.\n" +"Проверьте правильность установки СУБД.\n" + +#: pg_ctl.c:851 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: сбой при инициализации системы баз данных\n" + +#: pg_ctl.c:866 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "" +"%s: возможно, уже работает другой сервер; всё же пробуем запустить этот " +"сервер\n" + +#: pg_ctl.c:915 +msgid "waiting for server to start..." +msgstr "ожидание запуска сервера..." + +#: pg_ctl.c:920 pg_ctl.c:1025 pg_ctl.c:1117 pg_ctl.c:1247 +msgid " done\n" +msgstr " готово\n" + +#: pg_ctl.c:921 +msgid "server started\n" +msgstr "сервер запущен\n" + +#: pg_ctl.c:924 pg_ctl.c:930 pg_ctl.c:1252 +msgid " stopped waiting\n" +msgstr " прекращение ожидания\n" + +#: pg_ctl.c:925 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: сервер не запустился за отведённое время\n" + +#: pg_ctl.c:931 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: не удалось запустить сервер\n" +"Изучите протокол выполнения.\n" + +#: pg_ctl.c:939 +msgid "server starting\n" +msgstr "сервер запускается\n" + +#: pg_ctl.c:960 pg_ctl.c:1047 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1276 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: файл PID \"%s\" не существует\n" + +#: pg_ctl.c:961 pg_ctl.c:1049 pg_ctl.c:1139 pg_ctl.c:1178 pg_ctl.c:1277 +msgid "Is server running?\n" +msgstr "Запущен ли сервер?\n" + +#: pg_ctl.c:967 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: остановить сервер с PID %ld нельзя - он запущен в монопольном режиме\n" + +#: pg_ctl.c:982 +msgid "server shutting down\n" +msgstr "сервер останавливается\n" + +#: pg_ctl.c:997 pg_ctl.c:1086 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"ПРЕДУПРЕЖДЕНИЕ: активен режим копирования \"на ходу\"\n" +"Выключение произойдёт только при вызове pg_stop_backup().\n" +"\n" + +#: pg_ctl.c:1001 pg_ctl.c:1090 +msgid "waiting for server to shut down..." +msgstr "ожидание завершения работы сервера..." + +#: pg_ctl.c:1017 pg_ctl.c:1108 +msgid " failed\n" +msgstr " ошибка\n" + +#: pg_ctl.c:1019 pg_ctl.c:1110 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: сервер не останавливается\n" + +#: pg_ctl.c:1021 pg_ctl.c:1112 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"ПОДСКАЗКА: Параметр \"-m fast\" может сбросить сеансы принудительно,\n" +"не дожидаясь, пока они завершатся сами.\n" + +#: pg_ctl.c:1027 pg_ctl.c:1118 +msgid "server stopped\n" +msgstr "сервер остановлен\n" + +#: pg_ctl.c:1050 +msgid "trying to start server anyway\n" +msgstr "производится попытка запуска сервера в любом случае\n" + +#: pg_ctl.c:1059 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: перезапустить сервер с PID %ld нельзя - он запущен в монопольном режиме\n" + +#: pg_ctl.c:1062 pg_ctl.c:1148 +msgid "Please terminate the single-user server and try again.\n" +msgstr "Пожалуйста, остановите его и повторите попытку.\n" + +#: pg_ctl.c:1122 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: похоже, что старый серверный процесс (PID: %ld) исчез\n" + +#: pg_ctl.c:1124 +msgid "starting server anyway\n" +msgstr "сервер запускается, несмотря на это\n" + +#: pg_ctl.c:1145 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: перезагрузить сервер с PID %ld нельзя - он запущен в монопольном режиме\n" + +#: pg_ctl.c:1154 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: не удалось отправить сигнал перезагрузки (PID: %ld): %s\n" + +#: pg_ctl.c:1159 +msgid "server signaled\n" +msgstr "сигнал отправлен серверу\n" + +#: pg_ctl.c:1184 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: повысить сервер с PID %ld нельзя - он выполняется в монопольном режиме\n" + +#: pg_ctl.c:1192 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s: повысить сервер нельзя - он работает не в режиме резерва\n" + +#: pg_ctl.c:1207 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: не удалось создать файл \"%s\" с сигналом к повышению: %s\n" + +#: pg_ctl.c:1213 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: не удалось записать файл \"%s\" с сигналом к повышению: %s\n" + +#: pg_ctl.c:1221 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: не удалось отправить сигнал к повышению (PID: %ld): %s\n" + +#: pg_ctl.c:1224 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: ошибка при удалении файла \"%s\" с сигналом к повышению: %s\n" + +#: pg_ctl.c:1234 +msgid "waiting for server to promote..." +msgstr "ожидание повышения сервера..." + +#: pg_ctl.c:1248 +msgid "server promoted\n" +msgstr "сервер повышен\n" + +#: pg_ctl.c:1253 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: повышение сервера не завершилось за отведённое время\n" + +#: pg_ctl.c:1259 +msgid "server promoting\n" +msgstr "сервер повышается\n" + +#: pg_ctl.c:1283 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "" +"%s: не удалось прокрутить файл журнала; сервер работает в монопольном режиме " +"(PID: %ld)\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "" +"%s: не удалось создать файл \"%s\" с сигналом к прокрутке журнала: %s\n" + +#: pg_ctl.c:1299 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "" +"%s: не удалось записать файл \"%s\" с сигналом к прокрутке журнала: %s\n" + +#: pg_ctl.c:1307 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: не удалось отправить сигнал к прокрутке журнала (PID: %ld): %s\n" + +#: pg_ctl.c:1310 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "" +"%s: ошибка при удалении файла \"%s\" с сигналом к прокрутке журнала: %s\n" + +#: pg_ctl.c:1315 +msgid "server signaled to rotate log file\n" +msgstr "сигнал для прокрутки файла журнала отправлен серверу\n" + +#: pg_ctl.c:1362 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: сервер работает в монопольном режиме (PID: %ld)\n" + +#: pg_ctl.c:1376 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: сервер работает (PID: %ld)\n" + +#: pg_ctl.c:1392 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: сервер не работает\n" + +#: pg_ctl.c:1409 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: не удалось отправить сигнал %d (PID: %ld): %s\n" + +#: pg_ctl.c:1440 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: не удалось найти свой исполняемый файл\n" + +#: pg_ctl.c:1450 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: не удалось найти исполняемый файл postgres\n" + +#: pg_ctl.c:1520 pg_ctl.c:1554 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: не удалось открыть менеджер служб\n" + +#: pg_ctl.c:1526 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: служба \"%s\" уже зарегистрирована\n" + +#: pg_ctl.c:1537 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: не удалось зарегистрировать службу \"%s\" (код ошибки: %lu)\n" + +#: pg_ctl.c:1560 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: служба \"%s\" не зарегистрирована\n" + +#: pg_ctl.c:1567 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: не удалось открыть службу \"%s\" (код ошибки: %lu)\n" + +#: pg_ctl.c:1576 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: ошибка при удалении службы \"%s\" (код ошибки: %lu)\n" + +#: pg_ctl.c:1663 +msgid "Waiting for server startup...\n" +msgstr "Ожидание запуска сервера...\n" + +#: pg_ctl.c:1666 +msgid "Timed out waiting for server startup\n" +msgstr "Превышено время ожидания запуска сервера\n" + +#: pg_ctl.c:1670 +msgid "Server started and accepting connections\n" +msgstr "Сервер запущен и принимает подключения\n" + +#: pg_ctl.c:1725 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: не удалось запустить службу \"%s\" (код ошибки: %lu)\n" + +#: pg_ctl.c:1795 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: ПРЕДУПРЕЖДЕНИЕ: в этой ОС нельзя создавать ограниченные маркеры\n" + +#: pg_ctl.c:1808 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: не удалось открыть маркер процесса (код ошибки: %lu)\n" + +#: pg_ctl.c:1822 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: не удалось подготовить структуры SID (код ошибки: %lu)\n" + +#: pg_ctl.c:1849 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: не удалось создать ограниченный маркер (код ошибки: %lu)\n" + +#: pg_ctl.c:1880 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "" +"%s: ПРЕДУПРЕЖДЕНИЕ: не удалось найти все функции для работы с задачами в " +"системном API\n" + +#: pg_ctl.c:1977 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: не удалось получить LUID для привилегий (код ошибки: %lu)\n" + +#: pg_ctl.c:1985 pg_ctl.c:2000 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: не удалось получить информацию о маркере (код ошибки: %lu)\n" + +#: pg_ctl.c:1994 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: нехватка памяти\n" + +#: pg_ctl.c:2024 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_ctl.c:2032 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s - это утилита для инициализации, запуска, остановки и управления сервером " +"PostgreSQL.\n" +"\n" + +#: pg_ctl.c:2033 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: pg_ctl.c:2034 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D КАТАЛОГ-ДАННЫХ] [-s] [-o ПАРАМЕТРЫ]\n" + +#: pg_ctl.c:2035 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D КАТАЛОГ-ДАННЫХ] [-l ИМЯ-ФАЙЛА] [-W] [-t СЕК] [-s]\n" +" [-o ПАРАМЕТРЫ] [-p ПУТЬ] [-c]\n" + +#: pg_ctl.c:2037 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr "" +" %s stop [-D КАТАЛОГ-ДАННЫХ] [-m РЕЖИМ-ОСТАНОВКИ] [-W] [-t СЕК] [-s]\n" + +#: pg_ctl.c:2038 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D КАТАЛОГ-ДАННЫХ] [-m РЕЖИМ-ОСТАНОВКИ] [-W] [-t СЕК] [-s]\n" +" [-o ПАРАМЕТРЫ] [-c]\n" + +#: pg_ctl.c:2040 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D КАТАЛОГ-ДАННЫХ] [-s]\n" + +#: pg_ctl.c:2041 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D КАТАЛОГ-ДАННЫХ]\n" + +#: pg_ctl.c:2042 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D КАТАЛОГ-ДАННЫХ] [-W] [-t СЕК] [-s]\n" + +#: pg_ctl.c:2043 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D КАТАЛОГ-ДАННЫХ] [-s]\n" + +#: pg_ctl.c:2044 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill СИГНАЛ PID\n" + +#: pg_ctl.c:2046 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o " +"OPTIONS]\n" +msgstr "" +" %s register [-D КАТАЛОГ-ДАННЫХ] [-N ИМЯ-СЛУЖБЫ] [-U ПОЛЬЗОВАТЕЛЬ] [-P " +"ПАРОЛЬ]\n" +" [-S ТИП-ЗАПУСКА] [-e ИСТОЧНИК] [-W] [-t СЕК] [-s] [-o " +"ПАРАМЕТРЫ]\n" + +#: pg_ctl.c:2048 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N ИМЯ-СЛУЖБЫ]\n" + +#: pg_ctl.c:2051 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"Общие параметры:\n" + +#: pg_ctl.c:2052 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " -D, --pgdata=КАТАЛОГ расположение хранилища баз данных\n" + +#: pg_ctl.c:2054 +#, c-format +msgid "" +" -e SOURCE event source for logging when running as a service\n" +msgstr "" +" -e ИСТОЧНИК источник событий, устанавливаемый при записи в " +"журнал,\n" +" когда сервер работает в виде службы\n" + +#: pg_ctl.c:2056 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr "" +" -s, --silent выводить только ошибки, без информационных " +"сообщений\n" + +#: pg_ctl.c:2057 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr "" +" -t, --timeout=СЕК время ожидания при использовании параметра -w\n" + +#: pg_ctl.c:2058 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_ctl.c:2059 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait ждать завершения операции (по умолчанию)\n" + +#: pg_ctl.c:2060 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait не ждать завершения операции\n" + +#: pg_ctl.c:2061 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_ctl.c:2062 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "Если параметр -D опущен, используется переменная окружения PGDATA.\n" + +#: pg_ctl.c:2064 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"Параметры запуска и перезапуска:\n" + +#: pg_ctl.c:2066 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, --core-files указать postgres создавать дампы памяти\n" + +#: pg_ctl.c:2068 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files неприменимо на этой платформе\n" + +#: pg_ctl.c:2070 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr "" +" -l, --log=ФАЙЛ записывать (или добавлять) протокол сервера в " +"ФАЙЛ.\n" + +#: pg_ctl.c:2071 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=ПАРАМЕТРЫ передаваемые postgres (исполняемому файлу " +"PostgreSQL)\n" +" или initdb параметры командной строки\n" + +#: pg_ctl.c:2073 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p ПУТЬ-К-POSTGRES обычно не требуется\n" + +#: pg_ctl.c:2074 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"Параметры остановки и перезапуска:\n" + +#: pg_ctl.c:2075 +#, c-format +msgid "" +" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr "" +" -m, --mode=РЕЖИМ может быть \"smart\", \"fast\" или \"immediate\"\n" + +#: pg_ctl.c:2077 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"Режимы остановки:\n" + +#: pg_ctl.c:2078 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart закончить работу после отключения всех клиентов\n" + +#: pg_ctl.c:2079 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast закончить сразу, в штатном режиме (по умолчанию)\n" + +#: pg_ctl.c:2080 +#, c-format +msgid "" +" immediate quit without complete shutdown; will lead to recovery on " +"restart\n" +msgstr "" +" immediate закончить немедленно, в экстренном режиме; влечёт за собой\n" +" восстановление при перезапуске\n" + +#: pg_ctl.c:2082 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"Разрешённые сигналы для команды kill:\n" + +#: pg_ctl.c:2086 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"Параметры для регистрации и удаления:\n" + +#: pg_ctl.c:2087 +#, c-format +msgid "" +" -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr " -N ИМЯ-СЛУЖБЫ имя службы для регистрации сервера PostgreSQL\n" + +#: pg_ctl.c:2088 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr "" +" -P ПАРОЛЬ пароль учётной записи для регистрации сервера PostgreSQL\n" + +#: pg_ctl.c:2089 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr "" +" -U ПОЛЬЗОВАТЕЛЬ имя пользователя для регистрации сервера PostgreSQL\n" + +#: pg_ctl.c:2090 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr " -S ТИП-ЗАПУСКА тип запуска службы сервера PostgreSQL\n" + +#: pg_ctl.c:2092 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"Типы запуска:\n" + +#: pg_ctl.c:2093 +#, c-format +msgid "" +" auto start service automatically during system startup (default)\n" +msgstr "" +" auto запускать службу автоматически при старте системы (по " +"умолчанию)\n" + +#: pg_ctl.c:2094 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand запускать службу по требованию\n" + +#: pg_ctl.c:2097 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_ctl.c:2098 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_ctl.c:2123 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: неизвестный режим остановки \"%s\"\n" + +#: pg_ctl.c:2152 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: нераспознанное имя сигнала \"%s\"\n" + +#: pg_ctl.c:2169 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: нераспознанный тип запуска \"%s\"\n" + +#: pg_ctl.c:2224 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: не удалось определить каталог данных с помощью команды \"%s\"\n" + +#: pg_ctl.c:2248 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: управляющий файл, по-видимому, испорчен\n" + +#: pg_ctl.c:2316 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Запускать %s от имени root нельзя.\n" +"Пожалуйста, переключитесь на обычного пользователя (например,\n" +"используя \"su\"), который будет запускать серверный процесс.\n" + +#: pg_ctl.c:2400 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: параметр -S не поддерживается в этой ОС\n" + +#: pg_ctl.c:2437 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: слишком много аргументов командной строки (первый: \"%s\")\n" + +#: pg_ctl.c:2463 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: отсутствуют аргументы для режима kill\n" + +#: pg_ctl.c:2481 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: нераспознанный режим работы \"%s\"\n" + +#: pg_ctl.c:2491 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: команда не указана\n" + +#: pg_ctl.c:2512 +#, c-format +msgid "" +"%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "" +"%s: каталог баз данных не указан и переменная окружения PGDATA не " +"установлена\n" + +#~ msgid "%s: could not create log file \"%s\": %s\n" +#~ msgstr "%s: не удалось создать файл журнала \"%s\": %s\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "дочерний процесс завершён по сигналу %s" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option is not supported when starting a pre-9.1 server\n" +#~ msgstr "" +#~ "\n" +#~ "%s: параметр -w не поддерживается при запуске сервера до версии 9.1\n" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option cannot use a relative socket directory specification\n" +#~ msgstr "" +#~ "\n" +#~ "%s: в параметре -w нельзя указывать относительный путь к каталогу " +#~ "сокетов\n" + +#~ msgid "server is still starting up\n" +#~ msgstr "сервер всё ещё запускается\n" + +#~ msgid "%s: could not wait for server because of misconfiguration\n" +#~ msgstr "%s: не удалось дождаться сервера вследствие ошибки конфигурации\n" + +#~ msgid "" +#~ " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS" +#~ "\"]\n" +#~ msgstr "" +#~ " %s start [-w] [-t СЕК] [-D КАТАЛОГ-ДАННЫХ] [-s] [-l ИМЯ-ФАЙЛА]\n" +#~ " [-o \"ПАРАМЕТРЫ\"]\n" + +#~ msgid " %s promote [-w] [-t SECS] [-D DATADIR] [-s]\n" +#~ msgstr " %s promote [-w] [-t СЕК] [-D КАТАЛОГ-ДАННЫХ] [-s]\n" + +#~ msgid "" +#~ "(The default is to wait for shutdown, but not for start or restart.)\n" +#~ "\n" +#~ msgstr "" +#~ "(По умолчанию ожидание имеет место при остановке, но не при " +#~ "(пере)запуске.)\n" +#~ "\n" + +#~ msgid "" +#~ "\n" +#~ "%s: could not stat file \"%s\": %s\n" +#~ msgstr "" +#~ "\n" +#~ "%s: не удалось получить информацию о файле \"%s\": %s\n" + +#~ msgid "" +#~ "\n" +#~ "%s: this data directory appears to be running a pre-existing postmaster\n" +#~ msgstr "" +#~ "\n" +#~ "%s: похоже, что с этим каталогом уже работает управляющий процесс " +#~ "postmaster\n" + +#~ msgid "" +#~ "\n" +#~ "Options for stop, restart, or promote:\n" +#~ msgstr "" +#~ "\n" +#~ "Параметры остановки, перезапуска и повышения:\n" + +#~ msgid "%s: another server might be running\n" +#~ msgstr "%s: возможно, работает другой сервер\n" + +#~ msgid "" +#~ "\n" +#~ "Options for start or stop:\n" +#~ msgstr "" +#~ "\n" +#~ "Параметры запуска и остановки сервера:\n" + +#~ msgid "" +#~ " -I, --idempotent don't error if server already running or " +#~ "stopped\n" +#~ msgstr "" +#~ " -I, --idempotent не считать ошибкой, если он уже запущен или " +#~ "остановлен\n" + +#~ msgid "" +#~ "\n" +#~ "Promotion modes are:\n" +#~ msgstr "" +#~ "\n" +#~ "Режимы повышения:\n" + +#~ msgid " smart promote after performing a checkpoint\n" +#~ msgstr " smart повышение после выполнения контрольной точки\n" + +#~ msgid "" +#~ " fast promote quickly without waiting for checkpoint completion\n" +#~ msgstr "" +#~ " fast быстрое повышение, без ожидания завершения контрольной " +#~ "точки\n" diff --git a/src/bin/pg_ctl/po/uk.po b/src/bin/pg_ctl/po/uk.po index a12f7e88d2fb..34c19e3a2882 100644 --- a/src/bin/pg_ctl/po/uk.po +++ b/src/bin/pg_ctl/po/uk.po @@ -1,64 +1,69 @@ msgid "" msgstr "" "Project-Id-Version: postgresql\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2018-12-04 20:35+0100\n" -"PO-Revision-Date: 2019-05-12 22:09\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:15+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" "Last-Translator: pasha_golub\n" "Language-Team: Ukrainian\n" -"Language: uk_UA\n" +"Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" -"X-Generator: crowdin.com\n" "X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" "X-Crowdin-Language: uk\n" -"X-Crowdin-File: /REL_11_STABLE/src/bin/pg_ctl/po/pg_ctl.pot\n" +"X-Crowdin-File: /DEV_13/pg_ctl.pot\n" +"X-Crowdin-File-ID: 498\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 #, c-format -msgid "could not identify current directory: %s" -msgstr "не вдалося визначити поточний каталог: %s" +msgid "could not identify current directory: %m" +msgstr "не вдалося визначити поточний каталог: %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:156 #, c-format msgid "invalid binary \"%s\"" msgstr "невірний бінарний файл \"%s\"" -#: ../../common/exec.c:195 +#: ../../common/exec.c:206 #, c-format msgid "could not read binary \"%s\"" msgstr "неможливо прочитати бінарний файл \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:214 #, c-format msgid "could not find a \"%s\" to execute" msgstr "неможливо знайти \"%s\" для виконання" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:270 ../../common/exec.c:309 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "неможливо змінити директорію на \"%s\": %s" +msgid "could not change directory to \"%s\": %m" +msgstr "не вдалося змінити каталог на \"%s\": %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:287 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "неможливо прочитати символічне посилання \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "не можливо прочитати символічне послання \"%s\": %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:410 #, c-format -msgid "pclose failed: %s" -msgstr "помилка pclose: %s" +msgid "pclose failed: %m" +msgstr "помилка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "недостатньо пам'яті" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 -#: ../../port/path.c:687 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#: ../../port/path.c:632 ../../port/path.c:670 ../../port/path.c:687 #, c-format msgid "out of memory\n" msgstr "недостатньо пам'яті\n" -#: ../../common/fe_memutils.c:92 +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" @@ -78,22 +83,17 @@ msgstr "команду не знайдено" msgid "child process exited with exit code %d" msgstr "дочірній процес завершився з кодом виходу %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "дочірній процес перервано через помилку 0х%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "дочірній процес перервано через сигнал %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "дочірній процес перервано через сигнал %d" +msgid "child process was terminated by signal %d: %s" +msgstr "дочірній процес перервано через сигнал %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "дочірній процес завершився з невизнаним статусом %d" @@ -103,62 +103,77 @@ msgstr "дочірній процес завершився з невизнани msgid "could not get current working directory: %s\n" msgstr "не вдалося отримати поточний робочий каталог: %s\n" -#: pg_ctl.c:257 +#: pg_ctl.c:258 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: директорія \"%s\" не існує\n" -#: pg_ctl.c:260 +#: pg_ctl.c:261 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: немає доступу до каталогу \"%s\": %s\n" -#: pg_ctl.c:273 +#: pg_ctl.c:274 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: каталог \"%s\" не є каталогом кластера бази даних\n" -#: pg_ctl.c:286 +#: pg_ctl.c:287 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: не вдалося відкрити файл PID \"%s\": %s\n" -#: pg_ctl.c:295 +#: pg_ctl.c:296 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: файл PID \"%s\" пустий\n" -#: pg_ctl.c:298 +#: pg_ctl.c:299 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: невірні дані у файлі PID \"%s\"\n" -#: pg_ctl.c:459 pg_ctl.c:487 +#: pg_ctl.c:458 pg_ctl.c:500 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s: не вдалося запустити сервер: %s\n" -#: pg_ctl.c:511 +#: pg_ctl.c:478 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: не вдалося запустити сервер через помилку setsid(): %s\n" + +#: pg_ctl.c:548 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: не вдалося відкрити файл журналу \"%s\": %s\n" + +#: pg_ctl.c:565 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s: не вдалося запустити сервер: код помилки %lu\n" -#: pg_ctl.c:658 +#: pg_ctl.c:712 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "%s: не вдалося встановити обмеження на розмір файлу; заборонено жорстким лімітом\n" -#: pg_ctl.c:684 +#: pg_ctl.c:738 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: не вдалося прочитати файл \"%s\"\n" -#: pg_ctl.c:689 +#: pg_ctl.c:743 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: файл параметрів \"%s\" повинен містити рівно один рядок\n" -#: pg_ctl.c:735 +#: pg_ctl.c:785 pg_ctl.c:975 pg_ctl.c:1071 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: не вдалося надіслати стоп-сигнал (PID: %ld): %s\n" + +#: pg_ctl.c:813 #, c-format msgid "The program \"%s\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" @@ -166,7 +181,7 @@ msgid "The program \"%s\" is needed by %s but was not found in the\n" msgstr "Програма \"%s\" потрібна для %s, але не знайдена в тому ж каталозі, що й \"%s\".\n" "Перевірте вашу установку.\n" -#: pg_ctl.c:741 +#: pg_ctl.c:818 #, c-format msgid "The program \"%s\" was found by \"%s\"\n" "but was not the same version as %s.\n" @@ -174,573 +189,607 @@ msgid "The program \"%s\" was found by \"%s\"\n" msgstr "Програма \"%s\" була знайдена \"%s\", але не була тієї ж версії, що %s.\n" "Перевірте вашу установку.\n" -#: pg_ctl.c:774 +#: pg_ctl.c:851 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: не вдалося виконати ініціалізацію системи бази даних\n" -#: pg_ctl.c:789 +#: pg_ctl.c:866 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: мабуть, інший сервер вже працює; у будь-якому разі спробуємо запустити сервер\n" -#: pg_ctl.c:827 +#: pg_ctl.c:915 msgid "waiting for server to start..." msgstr "очікується запуск серверу..." -#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 +#: pg_ctl.c:920 pg_ctl.c:1025 pg_ctl.c:1117 pg_ctl.c:1247 msgid " done\n" msgstr " готово\n" -#: pg_ctl.c:833 +#: pg_ctl.c:921 msgid "server started\n" msgstr "сервер запущено\n" -#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 +#: pg_ctl.c:924 pg_ctl.c:930 pg_ctl.c:1252 msgid " stopped waiting\n" msgstr " очікування припинено\n" -#: pg_ctl.c:837 +#: pg_ctl.c:925 #, c-format msgid "%s: server did not start in time\n" msgstr "%s: сервер не було запущено вчасно\n" -#: pg_ctl.c:843 +#: pg_ctl.c:931 #, c-format msgid "%s: could not start server\n" "Examine the log output.\n" msgstr "%s: неможливо запустити сервер\n" "Передивіться протокол виконання.\n" -#: pg_ctl.c:851 +#: pg_ctl.c:939 msgid "server starting\n" msgstr "запуск серверу\n" -#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 +#: pg_ctl.c:960 pg_ctl.c:1047 pg_ctl.c:1138 pg_ctl.c:1177 pg_ctl.c:1276 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: файл PID \"%s\" не існує\n" -#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 +#: pg_ctl.c:961 pg_ctl.c:1049 pg_ctl.c:1139 pg_ctl.c:1178 pg_ctl.c:1277 msgid "Is server running?\n" msgstr "Сервер працює?\n" -#: pg_ctl.c:879 +#: pg_ctl.c:967 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "%s: не можливо зупинити сервер; сервер запущений в режимі single-user (PID: %ld)\n" -#: pg_ctl.c:887 pg_ctl.c:983 -#, c-format -msgid "%s: could not send stop signal (PID: %ld): %s\n" -msgstr "%s: не вдалося надіслати стоп-сигнал (PID: %ld): %s\n" - -#: pg_ctl.c:894 +#: pg_ctl.c:982 msgid "server shutting down\n" msgstr "сервер зупиняється\n" -#: pg_ctl.c:909 pg_ctl.c:998 +#: pg_ctl.c:997 pg_ctl.c:1086 msgid "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n\n" msgstr "ПОПЕРЕДЖЕННЯ: режим онлайн копіювання активний\n" "Зупинку не буде завершено поки не буде викликано pg_stop_backup().\n\n" -#: pg_ctl.c:913 pg_ctl.c:1002 +#: pg_ctl.c:1001 pg_ctl.c:1090 msgid "waiting for server to shut down..." msgstr "очікується зупинка серверу..." -#: pg_ctl.c:929 pg_ctl.c:1020 +#: pg_ctl.c:1017 pg_ctl.c:1108 msgid " failed\n" msgstr " помилка\n" -#: pg_ctl.c:931 pg_ctl.c:1022 +#: pg_ctl.c:1019 pg_ctl.c:1110 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: сервер не зупинено\n" -#: pg_ctl.c:933 pg_ctl.c:1024 +#: pg_ctl.c:1021 pg_ctl.c:1112 msgid "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" msgstr "ПІДКАЗКА: Режим \"-m fast\" закриває сесії відразу, не чекаючи на відключення ініційовані сесіями.\n" -#: pg_ctl.c:939 pg_ctl.c:1030 +#: pg_ctl.c:1027 pg_ctl.c:1118 msgid "server stopped\n" msgstr "сервер зупинено\n" -#: pg_ctl.c:962 +#: pg_ctl.c:1050 msgid "trying to start server anyway\n" msgstr "спроба запуску серверу в будь-якому разі\n" -#: pg_ctl.c:971 +#: pg_ctl.c:1059 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "%s: не можливо перезапустити сервер; сервер запущений в режимі single-user (PID: %ld)\n" -#: pg_ctl.c:974 pg_ctl.c:1060 +#: pg_ctl.c:1062 pg_ctl.c:1148 msgid "Please terminate the single-user server and try again.\n" msgstr "Будь ласка, припиніть однокористувацький сервер та спробуйте ще раз.\n" -#: pg_ctl.c:1034 +#: pg_ctl.c:1122 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: старий серверний процес (PID: %ld), здається, зник\n" -#: pg_ctl.c:1036 +#: pg_ctl.c:1124 msgid "starting server anyway\n" msgstr "запуск серверу в будь-якому разі\n" -#: pg_ctl.c:1057 +#: pg_ctl.c:1145 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "%s: неможливо перезавантажити сервер; сервер запущено в однокористувацькому режимі (PID: %ld)\n" -#: pg_ctl.c:1066 +#: pg_ctl.c:1154 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: не можливо надіслати сигнал перезавантаження (PID: %ld): %s\n" -#: pg_ctl.c:1071 +#: pg_ctl.c:1159 msgid "server signaled\n" msgstr "серверу надіслано сигнал\n" -#: pg_ctl.c:1096 +#: pg_ctl.c:1184 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "%s: неможливо підвищити сервер; сервер запущено в режимі single-user (PID: %ld)\n" -#: pg_ctl.c:1104 +#: pg_ctl.c:1192 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: неможливо підвищити сервер; сервер запущено не в режимі резерву\n" -#: pg_ctl.c:1119 +#: pg_ctl.c:1207 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: неможливо створити файл \"%s\" із сигналом для підвищення: %s\n" -#: pg_ctl.c:1125 +#: pg_ctl.c:1213 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: неможливо записати файл \"%s\" із сигналом для підвищення: %s\n" -#: pg_ctl.c:1133 +#: pg_ctl.c:1221 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: неможливо надіслати сигнал підвищення (PID: %ld): %s\n" -#: pg_ctl.c:1136 +#: pg_ctl.c:1224 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: неможливо видалити файл \"%s\" із сигналом для підвищення: %s\n" -#: pg_ctl.c:1146 +#: pg_ctl.c:1234 msgid "waiting for server to promote..." msgstr "очікується підвищення серверу..." -#: pg_ctl.c:1160 +#: pg_ctl.c:1248 msgid "server promoted\n" msgstr "сервер підвищено\n" -#: pg_ctl.c:1165 +#: pg_ctl.c:1253 #, c-format msgid "%s: server did not promote in time\n" msgstr "%s: сервер не було підвищено вчасно\n" -#: pg_ctl.c:1171 +#: pg_ctl.c:1259 msgid "server promoting\n" msgstr "сервер підвищується\n" -#: pg_ctl.c:1218 +#: pg_ctl.c:1283 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: не можливо розвернути файл журналу; сервер працює в режимі одного користувача (PID: %ld)\n" + +#: pg_ctl.c:1293 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: не вдалося створити файл сигналу розвороту журналу \"%s\": %s\n" + +#: pg_ctl.c:1299 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: не вдалося записати у файл сигналу розвороту журналу \"%s\": %s\n" + +#: pg_ctl.c:1307 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: не вдалося надіслати сигнал розвороту журналу (PID: %ld): %s\n" + +#: pg_ctl.c:1310 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: не вдалося видалити файл сигналу розвороту журналу \"%s\": %s\n" + +#: pg_ctl.c:1315 +msgid "server signaled to rotate log file\n" +msgstr "серверу надіслано сигнал для розворот файлу журналу\n" + +#: pg_ctl.c:1362 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: однокористувацький сервер працює (PID: %ld)\n" -#: pg_ctl.c:1232 +#: pg_ctl.c:1376 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: сервер працює (PID: %ld)\n" -#: pg_ctl.c:1248 +#: pg_ctl.c:1392 #, c-format msgid "%s: no server running\n" msgstr "%s: сервер не працює \n" -#: pg_ctl.c:1265 +#: pg_ctl.c:1409 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: не вдалося надіслати сигнал %d (PID: %ld): %s\n" -#: pg_ctl.c:1322 +#: pg_ctl.c:1440 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: не вдалося знайти ехе файл власної програми\n" -#: pg_ctl.c:1332 +#: pg_ctl.c:1450 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: не вдалося знайти виконану програму postgres\n" -#: pg_ctl.c:1402 pg_ctl.c:1436 +#: pg_ctl.c:1520 pg_ctl.c:1554 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: не вдалося відкрити менеджер служб\n" -#: pg_ctl.c:1408 +#: pg_ctl.c:1526 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: служба \"%s\" вже зареєстрована \n" -#: pg_ctl.c:1419 +#: pg_ctl.c:1537 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: не вдалося зареєструвати службу \"%s\": код помилки %lu\n" -#: pg_ctl.c:1442 +#: pg_ctl.c:1560 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: служба \"%s\" не зареєстрована \n" -#: pg_ctl.c:1449 +#: pg_ctl.c:1567 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: не вдалося відкрити службу \"%s\": код помилки %lu\n" -#: pg_ctl.c:1458 +#: pg_ctl.c:1576 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: не вдалося видалити службу \"%s\": код помилки %lu\n" -#: pg_ctl.c:1545 +#: pg_ctl.c:1663 msgid "Waiting for server startup...\n" msgstr "Очікування запуску сервера...\n" -#: pg_ctl.c:1548 +#: pg_ctl.c:1666 msgid "Timed out waiting for server startup\n" msgstr "Перевищено час очікування запуску сервера\n" -#: pg_ctl.c:1552 +#: pg_ctl.c:1670 msgid "Server started and accepting connections\n" msgstr "Сервер запущений і приймає з'єднання\n" -#: pg_ctl.c:1607 +#: pg_ctl.c:1725 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: не вдалося почати службу \"%s\": код помилки %lu\n" -#: pg_ctl.c:1677 +#: pg_ctl.c:1795 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: УВАГА: не вдалося створити обмежені токени на цій платформі\n" -#: pg_ctl.c:1690 +#: pg_ctl.c:1808 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: не вдалося відкрити токен процесу: код помилки %lu\n" -#: pg_ctl.c:1704 +#: pg_ctl.c:1822 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: не вдалося виділити SID: код помилки %lu\n" -#: pg_ctl.c:1731 +#: pg_ctl.c:1849 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: не вдалося створити обмежений токен: код помилки %lu\n" -#: pg_ctl.c:1762 +#: pg_ctl.c:1880 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: ПОПЕРЕДЖЕННЯ: не вдалося знайти усі робочі функції у системному API для завдань\n" -#: pg_ctl.c:1859 +#: pg_ctl.c:1977 #, c-format msgid "%s: could not get LUIDs for privileges: error code %lu\n" msgstr "%s: не вдалося отримати LUIDs для прав: код помилки %lu\n" -#: pg_ctl.c:1867 pg_ctl.c:1881 +#: pg_ctl.c:1985 pg_ctl.c:2000 #, c-format msgid "%s: could not get token information: error code %lu\n" msgstr "%s: не вдалося отримати інформацію токену: код помилки %lu\n" -#: pg_ctl.c:1875 +#: pg_ctl.c:1994 #, c-format msgid "%s: out of memory\n" msgstr "%s: бракує пам'яті\n" -#: pg_ctl.c:1905 +#: pg_ctl.c:2024 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" -#: pg_ctl.c:1913 +#: pg_ctl.c:2032 #, c-format msgid "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n\n" msgstr "%s - це утиліта для ініціалізації, запуску, зупинки і контролю серверу PostgreSQL.\n\n" -#: pg_ctl.c:1914 +#: pg_ctl.c:2033 #, c-format msgid "Usage:\n" msgstr "Використання:\n" -#: pg_ctl.c:1915 +#: pg_ctl.c:2034 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" -msgstr " %s init[db] [-D КАТАЛОГ-ДАНИХ] [-s] [-o ПАРАМЕТРИ]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D КАТАЛОГ-ДАНИХ] [-s] [-o ПАРАМЕТРИ]\n" -#: pg_ctl.c:1916 +#: pg_ctl.c:2035 #, c-format -msgid " %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-p PATH] [-c]\n" -msgstr " %s start [-D КАТАЛОГ-ДАНИХ] [-l ІМ'Я-ФАЙЛУ] [-W] [-t СЕК] [-s]\n" -" [-o ПАРАМЕТРИ] [-p ШЛЯХ] [-c]\n" +msgid " %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr " %s start [-D КАТАЛОГ-ДАНИХ] [-l ІМ'Я-ФАЙЛ] [-W] [-t СЕК] [-s]\n" +" [-o ПАРАМЕТРИ] [-p ШЛЯХ] [-c]\n" -#: pg_ctl.c:1918 +#: pg_ctl.c:2037 #, c-format -msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -msgstr " %s stop [-D КАТАЛОГ-ДАНИХ] [-m РЕЖИМ-ЗУПИНКИ] [-W] [-t СЕК] [-s]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D КАТАЛОГ-ДАНИХ] [-m РЕЖИМ-ЗУПИНКИ] [-W] [-t СЕК] [-s]\n" -#: pg_ctl.c:1919 +#: pg_ctl.c:2038 #, c-format -msgid " %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-c]\n" -msgstr " %s restart [-D КАТАЛОГ-ДАНИХ] [-m -РЕЖИМ-ЗУПИНКИ] [-W] [-t СЕК] [-s]\n" -" [-o ПАРАМЕТРИ] [-c]\n" +msgid " %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr " %s restart [-D КАТАЛОГ-ДАНИХ] [-m РЕЖИМ-ЗУПИНКИ] [-W] [-t СЕК] [-s]\n" +" [-o ПАРАМЕТРИ] [-c]\n" -#: pg_ctl.c:1921 +#: pg_ctl.c:2040 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" +msgid " %s reload [-D DATADIR] [-s]\n" msgstr " %s reload [-D КАТАЛОГ-ДАНИХ] [-s]\n" -#: pg_ctl.c:1922 +#: pg_ctl.c:2041 #, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D КАТАЛОГ-ДАНИХ]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATADIR]\n" -#: pg_ctl.c:1923 +#: pg_ctl.c:2042 #, c-format -msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" msgstr " %s promote [-D КАТАЛОГ-ДАНИХ] [-W] [-t СЕК] [-s]\n" -#: pg_ctl.c:1924 +#: pg_ctl.c:2043 +#, c-format +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D DATADIR] [-s]\n" + +#: pg_ctl.c:2044 #, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill ІМ'Я-СИГНАЛУ PID\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill ІМ'Я-СИГНАЛУ PID\n" -#: pg_ctl.c:1926 +#: pg_ctl.c:2046 #, c-format -msgid " %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" -" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgid " %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" msgstr " %s register [-D КАТАЛОГ-ДАНИХ] [-N ІМ'Я-СЛУЖБИ] [-U ІМ'Я-КОРИСТУВАЧА] [-P ПАРОЛЬ]\n" -" [-S ТИП-ЗАПУСКУ] [-e ДЖЕРЕЛО] [-W] [-t СЕК][-s] [-o ПАРАМЕТРИ]\n" +" [-S ТИП-ЗАПУСКУ] [-e ДЖЕРЕЛО] [-W] [-t СЕК] [-s] [-o ПАРАМЕТРИ]\n" -#: pg_ctl.c:1928 +#: pg_ctl.c:2048 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N ІМ'Я-СЛУЖБИ]\n" -#: pg_ctl.c:1931 +#: pg_ctl.c:2051 #, c-format msgid "\n" "Common options:\n" msgstr "\n" "Загальні параметри:\n" -#: pg_ctl.c:1932 +#: pg_ctl.c:2052 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata=КАТАЛОГ-ДАНИХ розташування простору зберігання бази даних\n" -#: pg_ctl.c:1934 +#: pg_ctl.c:2054 #, c-format msgid " -e SOURCE event source for logging when running as a service\n" msgstr " -e ДЖЕРЕЛО джерело подій для протоколу при запуску в якості послуги\n" -#: pg_ctl.c:1936 +#: pg_ctl.c:2056 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr " -s, --silent виводити лише помилки, без інформаційних повідомлень\n" -#: pg_ctl.c:1937 +#: pg_ctl.c:2057 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=СЕК час очікування при використанні -w параметра\n" -#: pg_ctl.c:1938 +#: pg_ctl.c:2058 #, c-format msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version вивести інформацію про версію і вийти\n" +msgstr " -V, --version вивести інформацію про версію і вийти\n" -#: pg_ctl.c:1939 +#: pg_ctl.c:2059 #, c-format msgid " -w, --wait wait until operation completes (default)\n" msgstr " -w, --wait чекати завершення операції (за замовчуванням)\n" -#: pg_ctl.c:1940 +#: pg_ctl.c:2060 #, c-format msgid " -W, --no-wait do not wait until operation completes\n" msgstr " -W, --no-wait не чекати завершення операції\n" -#: pg_ctl.c:1941 +#: pg_ctl.c:2061 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показати цю довідку потім вийти\n" -#: pg_ctl.c:1942 +#: pg_ctl.c:2062 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "Якщо -D параметр пропущено, використовувати змінну середовища PGDATA.\n" -#: pg_ctl.c:1944 +#: pg_ctl.c:2064 #, c-format msgid "\n" "Options for start or restart:\n" msgstr "\n" "Параметри запуску або перезапуску:\n" -#: pg_ctl.c:1946 +#: pg_ctl.c:2066 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files дозволяти postgres створювати дампи пам'яті\n" -#: pg_ctl.c:1948 +#: pg_ctl.c:2068 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files недопустимо цією платформою\n" -#: pg_ctl.c:1950 +#: pg_ctl.c:2070 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr " -l, --log=ФАЙЛ записувати (або додавати) протокол служби до ФАЙЛ\n" -#: pg_ctl.c:1951 +#: pg_ctl.c:2071 #, c-format msgid " -o, --options=OPTIONS command line options to pass to postgres\n" " (PostgreSQL server executable) or initdb\n" msgstr " -o, --options=ПАРАМЕТРИ параметри командного рядку для PostgreSQL або initdb\n" -#: pg_ctl.c:1953 +#: pg_ctl.c:2073 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p ШЛЯХ-ДО-СЕРВЕРУ зазвичай зайвий\n" -#: pg_ctl.c:1954 +#: pg_ctl.c:2074 #, c-format msgid "\n" "Options for stop or restart:\n" msgstr "\n" "Параметри припинення або перезапуску:\n" -#: pg_ctl.c:1955 +#: pg_ctl.c:2075 #, c-format msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr " -m, --mode=РЕЖИМ РЕЖИМ може бути \"smart\", \"fast\", або \"immediate\"\n" -#: pg_ctl.c:1957 +#: pg_ctl.c:2077 #, c-format msgid "\n" "Shutdown modes are:\n" msgstr "\n" "Режими зупинки:\n" -#: pg_ctl.c:1958 +#: pg_ctl.c:2078 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart вийти після від'єднання усіх клієнтів\n" -#: pg_ctl.c:1959 +#: pg_ctl.c:2079 #, c-format msgid " fast quit directly, with proper shutdown (default)\n" msgstr " fast вийти негайно з коректним вимкненням (за замовченням)\n" -#: pg_ctl.c:1960 +#: pg_ctl.c:2080 #, c-format msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" msgstr " immediate вийти негайно без повної процедури. Приведе до відновлення під час перезапуску\n" -#: pg_ctl.c:1962 +#: pg_ctl.c:2082 #, c-format msgid "\n" "Allowed signal names for kill:\n" msgstr "\n" "Дозволенні сигнали для команди kill:\n" -#: pg_ctl.c:1966 +#: pg_ctl.c:2086 #, c-format msgid "\n" "Options for register and unregister:\n" msgstr "\n" "Параметри для реєстрації і видалення: \n" -#: pg_ctl.c:1967 +#: pg_ctl.c:2087 #, c-format msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr " -N ІМ'Я-СЛУЖБИ ім'я служби під яким зареєструвати сервер PostgreSQL\n" -#: pg_ctl.c:1968 +#: pg_ctl.c:2088 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr " -P ПАРОЛЬ пароль облікового запису для реєстрації серверу PostgreSQL\n" -#: pg_ctl.c:1969 +#: pg_ctl.c:2089 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr " -U КОРИСТУВАЧ ім'я користувача під яким зареєструвати сервер PostgreSQL\n" -#: pg_ctl.c:1970 +#: pg_ctl.c:2090 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr " -S ТИП-ЗАПУСКУ тип запуску служби для реєстрації серверу PostgreSQL\n" -#: pg_ctl.c:1972 +#: pg_ctl.c:2092 #, c-format msgid "\n" "Start types are:\n" msgstr "\n" "Типи запуску:\n" -#: pg_ctl.c:1973 +#: pg_ctl.c:2093 #, c-format msgid " auto start service automatically during system startup (default)\n" msgstr " auto запускати сервер автоматично під час запуску системи (за замовчуванням)\n" -#: pg_ctl.c:1974 +#: pg_ctl.c:2094 #, c-format msgid " demand start service on demand\n" msgstr " demand запускати сервер за потреби\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:2097 #, c-format msgid "\n" -"Report bugs to .\n" +"Report bugs to <%s>.\n" msgstr "\n" -"Про помилки повідомляйте .\n" +"Повідомляти про помилки на <%s>.\n" -#: pg_ctl.c:2002 +#: pg_ctl.c:2098 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: pg_ctl.c:2123 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: невідомий режим завершення \"%s\"\n" -#: pg_ctl.c:2031 +#: pg_ctl.c:2152 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: невідомий сигнал \"%s\"\n" -#: pg_ctl.c:2048 +#: pg_ctl.c:2169 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: невідомий тип запуску \"%s\"\n" -#: pg_ctl.c:2103 +#: pg_ctl.c:2224 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: неможливо визначити каталог даних за допомогою команди \"%s\"\n" -#: pg_ctl.c:2128 +#: pg_ctl.c:2248 #, c-format msgid "%s: control file appears to be corrupt\n" msgstr "%s: контрольний файл видається пошкодженим\n" -#: pg_ctl.c:2199 +#: pg_ctl.c:2316 #, c-format msgid "%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" @@ -749,33 +798,40 @@ msgstr "%s: не може бути запущеним від ім'я супер- " Будь ласка увійдіть (використовуючи наприклад, \"su\") як (непривілейований) користувач який буде мати\n" "свій серверний процес. \n" -#: pg_ctl.c:2283 +#: pg_ctl.c:2400 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: параметр -S не підтримується цією платформою\n" -#: pg_ctl.c:2320 +#: pg_ctl.c:2437 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: забагато аргументів у командному рядку (перший \"%s\")\n" -#: pg_ctl.c:2344 +#: pg_ctl.c:2463 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: відсутні аргументи для режиму kill\n" -#: pg_ctl.c:2362 +#: pg_ctl.c:2481 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: невідомий режим роботи \"%s\"\n" -#: pg_ctl.c:2372 +#: pg_ctl.c:2491 #, c-format msgid "%s: no operation specified\n" msgstr "%s: команда не вказана\n" -#: pg_ctl.c:2393 +#: pg_ctl.c:2512 #, c-format msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: не вказано каталог даних і змінна середовища PGDATA не встановлена\n" +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Про помилки повідомляйте на .\n" + diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl index e27bbb592bef..a50726f1b48b 100644 --- a/src/bin/pg_ctl/t/001_start_stop.pl +++ b/src/bin/pg_ctl/t/001_start_stop.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/src/bin/pg_ctl/t/002_status.pl b/src/bin/pg_ctl/t/002_status.pl index 7864062dc5e5..8b005f30f928 100644 --- a/src/bin/pg_ctl/t/002_status.pl +++ b/src/bin/pg_ctl/t/002_status.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/src/bin/pg_ctl/t/003_promote.pl b/src/bin/pg_ctl/t/003_promote.pl index ecb294b4906a..2d7e2fd5f3d3 100644 --- a/src/bin/pg_ctl/t/003_promote.pl +++ b/src/bin/pg_ctl/t/003_promote.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/src/bin/pg_ctl/t/004_logrotate.pl b/src/bin/pg_ctl/t/004_logrotate.pl index f04638643604..ffc82d91615d 100644 --- a/src/bin/pg_ctl/t/004_logrotate.pl +++ b/src/bin/pg_ctl/t/004_logrotate.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; @@ -12,6 +15,8 @@ $node->append_conf( 'postgresql.conf', qq( logging_collector = on +# these ensure stability of test results: +log_rotation_age = 0 lc_messages = 'C' )); @@ -21,7 +26,19 @@ $node->psql('postgres', 'SELECT 1/0'); -my $current_logfiles = slurp_file($node->data_dir . '/current_logfiles'); +# might need to retry if logging collector process is slow... +my $max_attempts = 180 * 10; + +my $current_logfiles; +for (my $attempts = 0; $attempts < $max_attempts; $attempts++) +{ + eval { + $current_logfiles = slurp_file($node->data_dir . '/current_logfiles'); + }; + last unless $@; + usleep(100_000); +} +die $@ if $@; note "current_logfiles = $current_logfiles"; @@ -34,9 +51,6 @@ $lfname =~ s/^stderr //; chomp $lfname; -# might need to retry if logging collector process is slow... -my $max_attempts = 180 * 10; - my $first_logfile; for (my $attempts = 0; $attempts < $max_attempts; $attempts++) { diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile index ea7ff42e580a..2248ee43290d 100644 --- a/src/bin/pg_dump/Makefile +++ b/src/bin/pg_dump/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_dump # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/pg_dump/Makefile diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index ec5f9755d998..a1d10d91433a 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -4,7 +4,7 @@ * Catalog routines used by pg_dump; long ago these were shared * by another dump tool, but not anymore. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -31,6 +31,9 @@ #include "pg_backup_utils.h" #include "pg_dump.h" +static DumpableObject **buildIndexArray(void *objArray, int numObjs, Size objSize); +static int DOCatalogIdCompare(const void *p1, const void *p2); + /* * Variables for mapping DumpId to DumpableObject */ @@ -74,6 +77,30 @@ typedef struct _catalogIdMapEntry #define SH_DECLARE #define SH_DEFINE #include "lib/simplehash.h" +/* + * These variables are static to avoid the notational cruft of having to pass + * them into findTableByOid() and friends. For each of these arrays, we build + * a sorted-by-OID index array immediately after the objects are fetched, + * and then we use binary search in findTableByOid() and friends. (qsort'ing + * the object arrays themselves would be simpler, but it doesn't work because + * pg_dump.c may have already established pointers between items.) + */ +static DumpableObject **tblinfoindex; +static DumpableObject **typinfoindex; +static DumpableObject **funinfoindex; +static DumpableObject **oprinfoindex; +static DumpableObject **collinfoindex; +static DumpableObject **nspinfoindex; +static DumpableObject **extinfoindex; +static DumpableObject **pubinfoindex; +static int numTables; +static int numTypes; +static int numFuncs; +static int numOperators; +static int numCollations; +static int numNamespaces; +static int numExtensions; +static int numPublications; #define CATALOGIDHASH_INITIAL_SIZE 10000 @@ -96,6 +123,7 @@ getSchemaData(Archive *fout, int *numTablesPtr) { TableInfo *tblinfo; ExtensionInfo *extinfo; + PublicationInfo *pubinfo; InhInfo *inhinfo; int numTables; int numTypes; @@ -272,7 +300,9 @@ getSchemaData(Archive *fout, int *numTablesPtr) getPolicies(fout, tblinfo, numTables); pg_log_info("reading publications"); - (void) getPublications(fout, &numPublications); + pubinfo = getPublications(fout, &numPublications); + pubinfoindex = buildIndexArray(pubinfo, numPublications, + sizeof(PublicationInfo)); pg_log_info("reading publication membership"); getPublicationTables(fout, tblinfo, numTables); @@ -480,9 +510,11 @@ flagInhIndexes(Archive *fout, TableInfo tblinfo[], int numTables) * - Detect child columns that have a generation expression when their parents * also have one. Generation expressions are always inherited, so there is * no need to set them again in child tables, and there is no syntax for it - * either. (Exception: In binary upgrade mode we dump them because - * inherited tables are recreated standalone first and then reattached to - * the parent.) + * either. Exceptions: If it's a partition or we are in binary upgrade + * mode, we dump them because in those cases inherited tables are recreated + * standalone first and then reattached to the parent. (See also the logic + * in dumpTableSchema().) In that situation, the generation expressions + * must match the parent, enforced by ALTER TABLE. * * modifies tblinfo */ @@ -528,7 +560,7 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables) { bool foundNotNull; /* Attr was NOT NULL in a parent */ bool foundDefault; /* Found a default in a parent */ - bool foundGenerated; /* Found a generated in a parent */ + bool foundGenerated; /* Found a generated in a parent */ /* no point in examining dropped columns */ if (tbinfo->attisdropped[j]) @@ -593,7 +625,7 @@ flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables) } /* Remove generation expression from child */ - if (foundGenerated && !dopt->binary_upgrade) + if (foundGenerated && !tbinfo->ispartition && !dopt->binary_upgrade) tbinfo->attrdefs[j] = NULL; } } @@ -720,6 +752,90 @@ findObjectByCatalogId(CatalogId catalogId) return entry->dobj; } +/* + * Find a DumpableObject by OID, in a pre-sorted array of one type of object + * + * Returns NULL for unknown OID + */ +static DumpableObject * +findObjectByOid(Oid oid, DumpableObject **indexArray, int numObjs) +{ + DumpableObject **low; + DumpableObject **high; + + /* + * This is the same as findObjectByCatalogId except we assume we need not + * look at table OID because the objects are all the same type. + * + * We could use bsearch() here, but the notational cruft of calling + * bsearch is nearly as bad as doing it ourselves; and the generalized + * bsearch function is noticeably slower as well. + */ + if (numObjs <= 0) + return NULL; + low = indexArray; + high = indexArray + (numObjs - 1); + while (low <= high) + { + DumpableObject **middle; + int difference; + + middle = low + (high - low) / 2; + difference = oidcmp((*middle)->catId.oid, oid); + if (difference == 0) + return *middle; + else if (difference < 0) + low = middle + 1; + else + high = middle - 1; + } + return NULL; +} + +/* + * Build an index array of DumpableObject pointers, sorted by OID + */ +static DumpableObject ** +buildIndexArray(void *objArray, int numObjs, Size objSize) +{ + DumpableObject **ptrs; + int i; + + if (numObjs <= 0) + return NULL; + + ptrs = (DumpableObject **) pg_malloc(numObjs * sizeof(DumpableObject *)); + for (i = 0; i < numObjs; i++) + ptrs[i] = (DumpableObject *) ((char *) objArray + i * objSize); + + /* We can use DOCatalogIdCompare to sort since its first key is OID */ + if (numObjs > 1) + qsort((void *) ptrs, numObjs, sizeof(DumpableObject *), + DOCatalogIdCompare); + + return ptrs; +} + +/* + * qsort comparator for pointers to DumpableObjects + */ +static int +DOCatalogIdCompare(const void *p1, const void *p2) +{ + const DumpableObject *obj1 = *(DumpableObject *const *) p1; + const DumpableObject *obj2 = *(DumpableObject *const *) p2; + int cmpval; + + /* + * Compare OID first since it's usually unique, whereas there will only be + * a few distinct values of tableoid. + */ + cmpval = oidcmp(obj1->catId.oid, obj2->catId.oid); + if (cmpval == 0) + cmpval = oidcmp(obj1->catId.tableoid, obj2->catId.tableoid); + return cmpval; +} + /* * Build an array of pointers to all known dumpable objects * @@ -936,7 +1052,7 @@ findExtensionByOid(Oid oid) /* * findPublicationByOid - * finds the DumpableObject for the publication with the given oid + * finds the entry (in pubinfo) of the publication with the given oid * returns NULL if not found */ PublicationInfo * diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c index 1417401086a6..808df1949554 100644 --- a/src/bin/pg_dump/compress_io.c +++ b/src/bin/pg_dump/compress_io.c @@ -4,7 +4,7 @@ * Routines for archivers to write an uncompressed or compressed data * stream. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * This file includes two APIs for dealing with compressed data. The first diff --git a/src/bin/pg_dump/compress_io.h b/src/bin/pg_dump/compress_io.h index d2e6e1b85480..1eafbd845668 100644 --- a/src/bin/pg_dump/compress_io.h +++ b/src/bin/pg_dump/compress_io.h @@ -3,7 +3,7 @@ * compress_io.h * Interface to compress_io.c routines * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index b65a86d86068..a8a8cb5cdd76 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -5,7 +5,7 @@ * Basically this is stuff that is useful in both pg_dump and pg_dumpall. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/dumputils.c @@ -210,50 +210,29 @@ buildACLCommands(const char *name, const char *subname, const char *nspname, /* Scan individual REVOKE ACL items */ for (i = 0; i < nrevokeitems; i++) { - if (!parseAclItem(revokeitems[i], - type, name, subname, remoteVersion, - grantee, grantor, privs, privswgo)) + if (!parseAclItem(revokeitems[i], type, name, subname, remoteVersion, + grantee, grantor, privs, NULL)) { ok = false; break; } - if (privs->len > 0 || privswgo->len > 0) + if (privs->len > 0) { - if (privs->len > 0) - { - appendPQExpBuffer(firstsql, "%sREVOKE %s ON %s ", - prefix, privs->data, type); - if (nspname && *nspname) - appendPQExpBuffer(firstsql, "%s.", fmtId(nspname)); - appendPQExpBuffer(firstsql, "%s FROM ", name); - if (grantee->len == 0) - appendPQExpBufferStr(firstsql, "PUBLIC;\n"); - else if (strncmp(grantee->data, "group ", - strlen("group ")) == 0) - appendPQExpBuffer(firstsql, "GROUP %s;\n", - fmtId(grantee->data + strlen("group "))); - else - appendPQExpBuffer(firstsql, "%s;\n", - fmtId(grantee->data)); - } - if (privswgo->len > 0) - { - appendPQExpBuffer(firstsql, - "%sREVOKE GRANT OPTION FOR %s ON %s ", - prefix, privswgo->data, type); - if (nspname && *nspname) - appendPQExpBuffer(firstsql, "%s.", fmtId(nspname)); - appendPQExpBuffer(firstsql, "%s FROM ", name); - if (grantee->len == 0) - appendPQExpBufferStr(firstsql, "PUBLIC"); - else if (strncmp(grantee->data, "group ", - strlen("group ")) == 0) - appendPQExpBuffer(firstsql, "GROUP %s", - fmtId(grantee->data + strlen("group "))); - else - appendPQExpBufferStr(firstsql, fmtId(grantee->data)); - } + appendPQExpBuffer(firstsql, "%sREVOKE %s ON %s ", + prefix, privs->data, type); + if (nspname && *nspname) + appendPQExpBuffer(firstsql, "%s.", fmtId(nspname)); + appendPQExpBuffer(firstsql, "%s FROM ", name); + if (grantee->len == 0) + appendPQExpBufferStr(firstsql, "PUBLIC;\n"); + else if (strncmp(grantee->data, "group ", + strlen("group ")) == 0) + appendPQExpBuffer(firstsql, "GROUP %s;\n", + fmtId(grantee->data + strlen("group "))); + else + appendPQExpBuffer(firstsql, "%s;\n", + fmtId(grantee->data)); } } } @@ -432,8 +411,11 @@ buildDefaultACLCommands(const char *type, const char *nspname, * The returned grantee string will be the dequoted username or groupname * (preceded with "group " in the latter case). Note that a grant to PUBLIC * is represented by an empty grantee string. The returned grantor is the - * dequoted grantor name. Privilege characters are decoded and split between - * privileges with grant option (privswgo) and without (privs). + * dequoted grantor name. Privilege characters are translated to GRANT/REVOKE + * comma-separated privileges lists. If "privswgo" is non-NULL, the result is + * separate lists for privileges with grant option ("privswgo") and without + * ("privs"). Otherwise, "privs" bears every relevant privilege, ignoring the + * grant option distinction. * * Note: for cross-version compatibility, it's important to use ALL to * represent the privilege sets whenever appropriate. @@ -484,7 +466,7 @@ parseAclItem(const char *item, const char *type, do { \ if ((pos = strchr(eqpos + 1, code))) \ { \ - if (*(pos + 1) == '*') \ + if (*(pos + 1) == '*' && privswgo != NULL) \ { \ AddAcl(privswgo, keywd, subname); \ all_without_go = false; \ @@ -747,11 +729,12 @@ emitShSecLabels(PGconn *conn, PGresult *res, PQExpBuffer buffer, bool variable_is_guc_list_quote(const char *name) { - if (pg_strcasecmp(name, "temp_tablespaces") == 0 || + if (pg_strcasecmp(name, "local_preload_libraries") == 0 || + pg_strcasecmp(name, "search_path") == 0 || pg_strcasecmp(name, "session_preload_libraries") == 0 || pg_strcasecmp(name, "shared_preload_libraries") == 0 || - pg_strcasecmp(name, "local_preload_libraries") == 0 || - pg_strcasecmp(name, "search_path") == 0) + pg_strcasecmp(name, "temp_tablespaces") == 0 || + pg_strcasecmp(name, "unix_socket_directories") == 0) return true; else return false; diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h index c5c0c0e2daae..43832d99466b 100644 --- a/src/bin/pg_dump/dumputils.h +++ b/src/bin/pg_dump/dumputils.h @@ -5,7 +5,7 @@ * Basically this is stuff that is useful in both pg_dump and pg_dumpall. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/dumputils.h diff --git a/src/bin/pg_dump/nls.mk b/src/bin/pg_dump/nls.mk index 2a6fd597cb13..6276fd443b17 100644 --- a/src/bin/pg_dump/nls.mk +++ b/src/bin/pg_dump/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_dump/nls.mk CATALOG_NAME = pg_dump -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr zh_CN +AVAIL_LANGUAGES = cs de el es fr he it ja ko pl pt_BR ru sv tr uk zh_CN GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ pg_backup_archiver.c pg_backup_db.c pg_backup_custom.c \ pg_backup_null.c pg_backup_tar.c \ diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c index f0587f41e492..f1577e785faf 100644 --- a/src/bin/pg_dump/parallel.c +++ b/src/bin/pg_dump/parallel.c @@ -4,7 +4,7 @@ * * Parallel support for pg_dump and pg_restore * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -130,7 +130,7 @@ typedef struct /* Windows implementation of pipe access */ static int pgpipe(int handles[2]); -static int piperead(int s, char *buf, int len); +#define piperead(a,b,c) recv(a,b,c,0) #define pipewrite(a,b,c) send(a,b,c,0) #else /* !WIN32 */ @@ -229,19 +229,6 @@ static char *readMessageFromPipe(int fd); (strncmp(msg, prefix, strlen(prefix)) == 0) -/* - * Shutdown callback to clean up socket access - */ -#ifdef WIN32 -static void -shutdown_parallel_dump_utils(int code, void *unused) -{ - /* Call the cleanup function only from the main thread */ - if (mainThreadId == GetCurrentThreadId()) - WSACleanup(); -} -#endif - /* * Initialize parallel dump support --- should be called early in process * startup. (Currently, this is called whether or not we intend parallel @@ -264,11 +251,10 @@ init_parallel_dump_utils(void) err = WSAStartup(MAKEWORD(2, 2), &wsaData); if (err != 0) { - pg_log_error("WSAStartup failed: %d", err); + pg_log_error("%s() failed: error code %d", "WSAStartup", err); exit_nicely(1); } - /* ... and arrange to shut it down at exit */ - on_exit_nicely(shutdown_parallel_dump_utils, NULL); + parallel_init_done = true; } #endif @@ -1625,7 +1611,7 @@ getMessageFromWorker(ParallelState *pstate, bool do_wait, int *worker) } if (i < 0) - fatal("select() failed: %m"); + fatal("%s() failed: %m", "select"); for (i = 0; i < pstate->numWorkers; i++) { @@ -1775,7 +1761,7 @@ pgpipe(int handles[2]) } if (getsockname(s, (SOCKADDR *) &serv_addr, &len) == SOCKET_ERROR) { - pg_log_error("pgpipe: getsockname() failed: error code %d", + pg_log_error("pgpipe: %s() failed: error code %d", "getsockname", WSAGetLastError()); closesocket(s); return -1; @@ -1817,20 +1803,4 @@ pgpipe(int handles[2]) return 0; } -/* - * Windows implementation of reading from a pipe. - */ -static int -piperead(int s, char *buf, int len) -{ - int ret = recv(s, buf, len, 0); - - if (ret < 0 && WSAGetLastError() == WSAECONNRESET) - { - /* EOF on the pipe! */ - ret = 0; - } - return ret; -} - #endif /* WIN32 */ diff --git a/src/bin/pg_dump/parallel.h b/src/bin/pg_dump/parallel.h index a2e98cb87bf0..0fbf736c811c 100644 --- a/src/bin/pg_dump/parallel.h +++ b/src/bin/pg_dump/parallel.h @@ -4,7 +4,7 @@ * * Parallel support for pg_dump and pg_restore * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index 18968684e322..433b7e7c417d 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -142,12 +142,9 @@ typedef struct _restoreOptions SimpleStringList tableNames; int useDB; - char *dbname; /* subject to expand_dbname */ - char *pgport; - char *pghost; - char *username; + ConnParams cparams; /* parameters to use if useDB */ + int noDataForFailedTables; - trivalue promptPassword; int exit_on_error; int compression; int suppressDumpWarnings; /* Suppress output of WARNING entries @@ -163,10 +160,7 @@ typedef struct _restoreOptions typedef struct _dumpOptions { - const char *dbname; /* subject to expand_dbname */ - const char *pghost; - const char *pgport; - const char *username; + ConnParams cparams; int binary_upgrade; @@ -187,6 +181,7 @@ typedef struct _dumpOptions int no_publications; int no_subscriptions; int no_synchronized_snapshots; + int no_toast_compression; int no_unlogged_table_data; int serializable_deferrable; int disable_triggers; @@ -291,13 +286,9 @@ typedef void (*SetupWorkerPtrType) (Archive *AH); * Main archiver interface. */ -extern void ConnectDatabase(Archive *AH, - const char *dbname, - const char *pghost, - const char *pgport, - const char *username, - trivalue prompt_password, - bool binary_upgrade); +extern void ConnectDatabase(Archive *AHX, + const ConnParams *cparams, + bool isReconnect); extern void DisconnectDatabase(Archive *AHX); extern PGconn *GetConnection(Archive *AHX); diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index d38aafbbfb98..69cd192ff909 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -30,8 +30,10 @@ #include #endif +#include "common/string.h" #include "dumputils.h" #include "fe_utils/string_utils.h" +#include "lib/stringinfo.h" #include "libpq/libpq-fs.h" #include "parallel.h" #include "pg_backup_archiver.h" @@ -84,7 +86,7 @@ static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam); static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te); static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te); static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te); -static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH); +static int _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH); static RestorePass _tocEntryRestorePass(TocEntry *te); static bool _tocEntryIsACL(TocEntry *te); static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te); @@ -163,6 +165,7 @@ InitDumpOptions(DumpOptions *opts) memset(opts, 0, sizeof(DumpOptions)); /* set any fields that shouldn't default to zeroes */ opts->include_everything = true; + opts->cparams.promptPassword = TRI_DEFAULT; opts->dumpSections = DUMP_UNSECTIONED; } @@ -176,6 +179,11 @@ dumpOptionsFromRestoreOptions(RestoreOptions *ropt) DumpOptions *dopt = NewDumpOptions(); /* this is the inverse of what's at the end of pg_dump.c's main() */ + dopt->cparams.dbname = ropt->cparams.dbname ? pg_strdup(ropt->cparams.dbname) : NULL; + dopt->cparams.pgport = ropt->cparams.pgport ? pg_strdup(ropt->cparams.pgport) : NULL; + dopt->cparams.pghost = ropt->cparams.pghost ? pg_strdup(ropt->cparams.pghost) : NULL; + dopt->cparams.username = ropt->cparams.username ? pg_strdup(ropt->cparams.username) : NULL; + dopt->cparams.promptPassword = ropt->cparams.promptPassword; dopt->outputClean = ropt->dropSchema; dopt->dataOnly = ropt->dataOnly; dopt->schemaOnly = ropt->schemaOnly; @@ -408,10 +416,7 @@ RestoreArchive(Archive *AHX) AHX->minRemoteVersion = 0; AHX->maxRemoteVersion = 9999999; - ConnectDatabase(AHX, ropt->dbname, - ropt->pghost, ropt->pgport, ropt->username, - ropt->promptPassword, - false); + ConnectDatabase(AHX, &ropt->cparams, false); /* * If we're talking to the DB directly, don't send comments since they @@ -762,7 +767,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) { RestoreOptions *ropt = AH->public.ropt; int status = WORKER_OK; - teReqs reqs; + int reqs; bool defnDumped; AH->currentTE = te; @@ -843,16 +848,8 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) if (strcmp(te->desc, "DATABASE") == 0 || strcmp(te->desc, "DATABASE PROPERTIES") == 0) { - PQExpBufferData connstr; - - initPQExpBuffer(&connstr); - appendPQExpBufferStr(&connstr, "dbname="); - appendConnStrVal(&connstr, te->tag); - /* Abandon struct, but keep its buffer until process exit. */ - pg_log_info("connecting to new database \"%s\"", te->tag); _reconnectToDB(AH, te->tag); - ropt->dbname = connstr.data; } } @@ -984,7 +981,7 @@ NewRestoreOptions(void) /* set any fields that shouldn't default to zeroes */ opts->format = archUnknown; - opts->promptPassword = TRI_DEFAULT; + opts->cparams.promptPassword = TRI_DEFAULT; opts->dumpSections = DUMP_UNSECTIONED; /* GPDB_92_MERGE_FIXEME: do we need the following two lines? */ @@ -1417,8 +1414,7 @@ SortTocFromFile(Archive *AHX) ArchiveHandle *AH = (ArchiveHandle *) AHX; RestoreOptions *ropt = AH->public.ropt; FILE *fh; - char buf[100]; - bool incomplete_line; + StringInfoData linebuf; /* Allocate space for the 'wanted' array, and init it */ ropt->idWanted = (bool *) pg_malloc0(sizeof(bool) * AH->maxDumpId); @@ -1428,45 +1424,33 @@ SortTocFromFile(Archive *AHX) if (!fh) fatal("could not open TOC file \"%s\": %m", ropt->tocFile); - incomplete_line = false; - while (fgets(buf, sizeof(buf), fh) != NULL) + initStringInfo(&linebuf); + + while (pg_get_line_buf(fh, &linebuf)) { - bool prev_incomplete_line = incomplete_line; - int buflen; char *cmnt; char *endptr; DumpId id; TocEntry *te; - /* - * Some lines in the file might be longer than sizeof(buf). This is - * no problem, since we only care about the leading numeric ID which - * can be at most a few characters; but we have to skip continuation - * bufferloads when processing a long line. - */ - buflen = strlen(buf); - if (buflen > 0 && buf[buflen - 1] == '\n') - incomplete_line = false; - else - incomplete_line = true; - if (prev_incomplete_line) - continue; - /* Truncate line at comment, if any */ - cmnt = strchr(buf, ';'); + cmnt = strchr(linebuf.data, ';'); if (cmnt != NULL) + { cmnt[0] = '\0'; + linebuf.len = cmnt - linebuf.data; + } /* Ignore if all blank */ - if (strspn(buf, " \t\r\n") == strlen(buf)) + if (strspn(linebuf.data, " \t\r\n") == linebuf.len) continue; /* Get an ID, check it's valid and not already seen */ - id = strtol(buf, &endptr, 10); - if (endptr == buf || id <= 0 || id > AH->maxDumpId || + id = strtol(linebuf.data, &endptr, 10); + if (endptr == linebuf.data || id <= 0 || id > AH->maxDumpId || ropt->idWanted[id - 1]) { - pg_log_warning("line ignored: %s", buf); + pg_log_warning("line ignored: %s", linebuf.data); continue; } @@ -1493,6 +1477,8 @@ SortTocFromFile(Archive *AHX) _moveBefore(AH->toc, te); } + pg_free(linebuf.data); + if (fclose(fh) != 0) fatal("could not close TOC file: %m"); } @@ -1700,16 +1686,17 @@ dump_lo_buf(ArchiveHandle *AH) { if (AH->connection) { - size_t res; + int res; res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used); - pg_log_debug(ngettext("wrote %lu byte of large object data (result = %lu)", - "wrote %lu bytes of large object data (result = %lu)", + pg_log_debug(ngettext("wrote %zu byte of large object data (result = %d)", + "wrote %zu bytes of large object data (result = %d)", AH->lo_buf_used), - (unsigned long) AH->lo_buf_used, (unsigned long) res); + AH->lo_buf_used, res); + /* We assume there are no short writes, only errors */ if (res != AH->lo_buf_used) - fatal("could not write to large object (result: %lu, expected: %lu)", - (unsigned long) res, (unsigned long) AH->lo_buf_used); + warn_or_exit_horribly(AH, "could not write to large object: %s", + PQerrorMessage(AH->connection)); } else { @@ -1930,7 +1917,7 @@ getTocEntryByDumpId(ArchiveHandle *AH, DumpId id) return NULL; } -teReqs +int TocIDRequired(ArchiveHandle *AH, DumpId id) { TocEntry *te = getTocEntryByDumpId(AH, id); @@ -2132,6 +2119,7 @@ _discoverArchiveFormat(ArchiveHandle *AH) if (AH->lookahead) free(AH->lookahead); + AH->readHeader = 0; AH->lookaheadSize = 512; AH->lookahead = pg_malloc0(512); AH->lookaheadLen = 0; @@ -2203,62 +2191,9 @@ _discoverArchiveFormat(ArchiveHandle *AH) if (strncmp(sig, "PGDMP", 5) == 0) { - int byteread; - char vmaj, - vmin, - vrev; - - /* - * Finish reading (most of) a custom-format header. - * - * NB: this code must agree with ReadHead(). - */ - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - vmaj = byteread; - - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - vmin = byteread; - - /* Save these too... */ - AH->lookahead[AH->lookaheadLen++] = vmaj; - AH->lookahead[AH->lookaheadLen++] = vmin; - - /* Check header version; varies from V1.0 */ - if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */ - { - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - vrev = byteread; - AH->lookahead[AH->lookaheadLen++] = vrev; - } - else - vrev = 0; - - AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev); - - if ((AH->intSize = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - AH->lookahead[AH->lookaheadLen++] = AH->intSize; - - if (AH->version >= K_VERS_1_7) - { - if ((AH->offSize = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - AH->lookahead[AH->lookaheadLen++] = AH->offSize; - } - else - AH->offSize = AH->intSize; - - if ((byteread = fgetc(fh)) == EOF) - READ_ERROR_EXIT(fh); - - AH->format = byteread; - AH->lookahead[AH->lookaheadLen++] = AH->format; + /* It's custom format, stop here */ + AH->format = archCustom; + AH->readHeader = 1; } else { @@ -2295,22 +2230,15 @@ _discoverArchiveFormat(ArchiveHandle *AH) AH->format = archTar; } - /* If we can't seek, then mark the header as read */ - if (fseeko(fh, 0, SEEK_SET) != 0) - { - /* - * NOTE: Formats that use the lookahead buffer can unset this in their - * Init routine. - */ - AH->readHeader = 1; - } - else - AH->lookaheadLen = 0; /* Don't bother since we've reset the file */ - - /* Close the file */ + /* Close the file if we opened it */ if (wantClose) + { if (fclose(fh) != 0) fatal("could not close input file: %m"); + /* Forget lookahead, since we'll re-read header after re-opening */ + AH->readHeader = 0; + AH->lookaheadLen = 0; + } return AH->format; } @@ -2326,7 +2254,8 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt, { ArchiveHandle *AH; - pg_log_debug("allocating AH for %s, format %d", FileSpec, fmt); + pg_log_debug("allocating AH for %s, format %d", + FileSpec ? FileSpec : "(stdio)", fmt); AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle)); @@ -2403,8 +2332,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt, else AH->format = fmt; - AH->promptPassword = TRI_DEFAULT; - switch (AH->format) { case archCustom: @@ -2866,10 +2793,10 @@ StrictNamesCheck(RestoreOptions *ropt) * REQ_SCHEMA and REQ_DATA bits if we want to restore schema and/or data * portions of this TOC entry, or REQ_SPECIAL if it's a special entry. */ -static teReqs +static int _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH) { - teReqs res = REQ_SCHEMA | REQ_DATA; + int res = REQ_SCHEMA | REQ_DATA; RestoreOptions *ropt = AH->public.ropt; /* These items are treated specially */ @@ -3277,27 +3204,20 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user) * If we're currently restoring right into a database, this will * actually establish a connection. Otherwise it puts a \connect into * the script output. - * - * NULL dbname implies reconnecting to the current DB (pretty useless). */ static void _reconnectToDB(ArchiveHandle *AH, const char *dbname) { if (RestoringToDB(AH)) - ReconnectToServer(AH, dbname, NULL); + ReconnectToServer(AH, dbname); else { - if (dbname) - { - PQExpBufferData connectbuf; + PQExpBufferData connectbuf; - initPQExpBuffer(&connectbuf); - appendPsqlMetaConnect(&connectbuf, dbname); - ahprintf(AH, "%s\n", connectbuf.data); - termPQExpBuffer(&connectbuf); - } - else - ahprintf(AH, "%s\n", "\\connect -\n"); + initPQExpBuffer(&connectbuf); + appendPsqlMetaConnect(&connectbuf, dbname); + ahprintf(AH, "%s\n", connectbuf.data); + termPQExpBuffer(&connectbuf); } /* @@ -3850,9 +3770,10 @@ WriteHead(ArchiveHandle *AH) void ReadHead(ArchiveHandle *AH) { - char tmpMag[7]; + char vmaj, + vmin, + vrev; int fmt; - struct tm crtm; /* * If we haven't already read the header, do so. @@ -3862,48 +3783,46 @@ ReadHead(ArchiveHandle *AH) */ if (!AH->readHeader) { - char vmaj, - vmin, - vrev; + char tmpMag[7]; AH->ReadBufPtr(AH, tmpMag, 5); if (strncmp(tmpMag, "PGDMP", 5) != 0) fatal("did not find magic string in file header"); + } - vmaj = AH->ReadBytePtr(AH); - vmin = AH->ReadBytePtr(AH); + vmaj = AH->ReadBytePtr(AH); + vmin = AH->ReadBytePtr(AH); - if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */ - vrev = AH->ReadBytePtr(AH); - else - vrev = 0; + if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */ + vrev = AH->ReadBytePtr(AH); + else + vrev = 0; - AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev); + AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev); - if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX) - fatal("unsupported version (%d.%d) in file header", - vmaj, vmin); + if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX) + fatal("unsupported version (%d.%d) in file header", + vmaj, vmin); - AH->intSize = AH->ReadBytePtr(AH); - if (AH->intSize > 32) - fatal("sanity check on integer size (%lu) failed", - (unsigned long) AH->intSize); + AH->intSize = AH->ReadBytePtr(AH); + if (AH->intSize > 32) + fatal("sanity check on integer size (%lu) failed", + (unsigned long) AH->intSize); - if (AH->intSize > sizeof(int)) - pg_log_warning("archive was made on a machine with larger integers, some operations might fail"); + if (AH->intSize > sizeof(int)) + pg_log_warning("archive was made on a machine with larger integers, some operations might fail"); - if (AH->version >= K_VERS_1_7) - AH->offSize = AH->ReadBytePtr(AH); - else - AH->offSize = AH->intSize; + if (AH->version >= K_VERS_1_7) + AH->offSize = AH->ReadBytePtr(AH); + else + AH->offSize = AH->intSize; - fmt = AH->ReadBytePtr(AH); + fmt = AH->ReadBytePtr(AH); - if (AH->format != fmt) - fatal("expected format (%d) differs from format found in file (%d)", - AH->format, fmt); - } + if (AH->format != fmt) + fatal("expected format (%d) differs from format found in file (%d)", + AH->format, fmt); if (AH->version >= K_VERS_1_2) { @@ -3922,6 +3841,8 @@ ReadHead(ArchiveHandle *AH) if (AH->version >= K_VERS_1_4) { + struct tm crtm; + crtm.tm_sec = ReadInt(AH); crtm.tm_min = ReadInt(AH); crtm.tm_hour = ReadInt(AH); @@ -3930,12 +3851,32 @@ ReadHead(ArchiveHandle *AH) crtm.tm_year = ReadInt(AH); crtm.tm_isdst = ReadInt(AH); - AH->archdbname = ReadStr(AH); - + /* + * Newer versions of glibc have mktime() report failure if tm_isdst is + * inconsistent with the prevailing timezone, e.g. tm_isdst = 1 when + * TZ=UTC. This is problematic when restoring an archive under a + * different timezone setting. If we get a failure, try again with + * tm_isdst set to -1 ("don't know"). + * + * XXX with or without this hack, we reconstruct createDate + * incorrectly when the prevailing timezone is different from + * pg_dump's. Next time we bump the archive version, we should flush + * this representation and store a plain seconds-since-the-Epoch + * timestamp instead. + */ AH->createDate = mktime(&crtm); - if (AH->createDate == (time_t) -1) - pg_log_warning("invalid creation date in header"); + { + crtm.tm_isdst = -1; + AH->createDate = mktime(&crtm); + if (AH->createDate == (time_t) -1) + pg_log_warning("invalid creation date in header"); + } + } + + if (AH->version >= K_VERS_1_4) + { + AH->archdbname = ReadStr(AH); } if (AH->version >= K_VERS_1_10) @@ -4255,10 +4196,7 @@ restore_toc_entries_postfork(ArchiveHandle *AH, TocEntry *pending_list) /* * Now reconnect the single parent connection. */ - ConnectDatabase((Archive *) AH, ropt->dbname, - ropt->pghost, ropt->pgport, ropt->username, - ropt->promptPassword, - false); + ConnectDatabase((Archive *) AH, &ropt->cparams, true); /* re-establish fixed state */ _doSetFixedOutputState(AH); @@ -4920,55 +4858,15 @@ CloneArchive(ArchiveHandle *AH) clone->public.n_errors = 0; /* - * Connect our new clone object to the database: In parallel restore the - * parent is already disconnected, because we can connect the worker - * processes independently to the database (no snapshot sync required). In - * parallel backup we clone the parent's existing connection. + * Connect our new clone object to the database, using the same connection + * parameters used for the original connection. */ - if (AH->mode == archModeRead) - { - RestoreOptions *ropt = AH->public.ropt; - - Assert(AH->connection == NULL); + ConnectDatabase((Archive *) clone, &clone->public.ropt->cparams, true); - /* this also sets clone->connection */ - ConnectDatabase((Archive *) clone, ropt->dbname, - ropt->pghost, ropt->pgport, ropt->username, - ropt->promptPassword, false); - - /* re-establish fixed state */ + /* re-establish fixed state */ + if (AH->mode == archModeRead) _doSetFixedOutputState(clone); - } - else - { - PQExpBufferData connstr; - char *pghost; - char *pgport; - char *username; - - Assert(AH->connection != NULL); - - /* - * Even though we are technically accessing the parent's database - * object here, these functions are fine to be called like that - * because all just return a pointer and do not actually send/receive - * any data to/from the database. - */ - initPQExpBuffer(&connstr); - appendPQExpBufferStr(&connstr, "dbname="); - appendConnStrVal(&connstr, PQdb(AH->connection)); - pghost = PQhost(AH->connection); - pgport = PQport(AH->connection); - username = PQuser(AH->connection); - - /* this also sets clone->connection */ - ConnectDatabase((Archive *) clone, connstr.data, - pghost, pgport, username, TRI_NO, false); - - termPQExpBuffer(&connstr); - /* setupDumpWorker will fix up connection state */ - } - + /* in write case, setupDumpWorker will fix up connection state */ /* Let the format-specific code have a chance too */ clone->ClonePtr(clone); diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index f50973de9323..91060944f1fa 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -229,12 +229,9 @@ typedef enum #define RESTORE_PASS_LAST RESTORE_PASS_POST_ACL } RestorePass; -typedef enum -{ - REQ_SCHEMA = 0x01, /* want schema */ - REQ_DATA = 0x02, /* want data */ - REQ_SPECIAL = 0x04 /* for special TOC entries */ -} teReqs; +#define REQ_SCHEMA 0x01 /* want schema */ +#define REQ_DATA 0x02 /* want data */ +#define REQ_SPECIAL 0x04 /* for special TOC entries */ struct _archiveHandle { @@ -256,15 +253,21 @@ struct _archiveHandle time_t createDate; /* Date archive created */ /* - * Fields used when discovering header. A format can always get the - * previous read bytes from here... + * Fields used when discovering archive format. For tar format, we load + * the first block into the lookahead buffer, and verify that it looks + * like a tar header. The tar module must then consume bytes from the + * lookahead buffer before reading any more from the file. For custom + * format, we load only the "PGDMP" marker into the buffer, and then set + * readHeader after confirming it matches. The buffer is vestigial in + * this case, as the subsequent code just checks readHeader and doesn't + * examine the buffer. */ - int readHeader; /* Used if file header has been read already */ + int readHeader; /* Set if we already read "PGDMP" marker */ char *lookahead; /* Buffer used when reading header to discover * format */ - size_t lookaheadSize; /* Size of allocated buffer */ - size_t lookaheadLen; /* Length of data in lookahead */ - pgoff_t lookaheadPos; /* Current read position in lookahead buffer */ + size_t lookaheadSize; /* Allocated size of buffer */ + size_t lookaheadLen; /* Length of valid data in lookahead */ + size_t lookaheadPos; /* Current read position in lookahead buffer */ ArchiveEntryPtrType ArchiveEntryPtr; /* Called for each metadata object */ StartDataPtrType StartDataPtr; /* Called when table data is about to be @@ -303,7 +306,6 @@ struct _archiveHandle /* Stuff for direct DB connection */ char *archdbname; /* DB name *read* from archive */ - trivalue promptPassword; char *savedPassword; /* password for ropt->username, if known */ char *use_role; PGconn *connection; @@ -333,10 +335,14 @@ struct _archiveHandle DumpId *tableDataId; /* TABLE DATA ids, indexed by table dumpId */ struct _tocEntry *currToc; /* Used when dumping data */ - int compression; /* Compression requested on open Possible - * values for compression: -1 - * Z_DEFAULT_COMPRESSION 0 COMPRESSION_NONE - * 1-9 levels for gzip compression */ + int compression; /*--------- + * Compression requested on open(). + * Possible values for compression: + * -1 Z_DEFAULT_COMPRESSION + * 0 COMPRESSION_NONE + * 1-9 levels for gzip compression + *--------- + */ bool dosync; /* data requested to be synced on sight */ ArchiveMode mode; /* File mode - r or w */ void *formatData; /* Header data specific to file format */ @@ -387,7 +393,8 @@ struct _tocEntry /* working state while dumping/restoring */ pgoff_t dataLength; /* item's data size; 0 if none or unknown */ - teReqs reqs; /* do we need schema and/or data of object */ + int reqs; /* do we need schema and/or data of object + * (REQ_* bit mask) */ bool created; /* set for DATA member if TABLE was created */ /* working state (needed only for parallel restore) */ @@ -437,7 +444,7 @@ extern void WriteDataChunksForTocEntry(ArchiveHandle *AH, TocEntry *te); extern ArchiveHandle *CloneArchive(ArchiveHandle *AH); extern void DeCloneArchive(ArchiveHandle *AH); -extern teReqs TocIDRequired(ArchiveHandle *AH, DumpId id); +extern int TocIDRequired(ArchiveHandle *AH, DumpId id); TocEntry *getTocEntryByDumpId(ArchiveHandle *AH, DumpId id); extern bool checkSeek(FILE *fp); @@ -471,7 +478,7 @@ extern void InitArchiveFmt_Tar(ArchiveHandle *AH); extern bool isValidTarHeader(char *header); -extern void ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser); +extern void ReconnectToServer(ArchiveHandle *AH, const char *dbname); extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid); void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH); diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c index 971e6adf4875..77d402c323e9 100644 --- a/src/bin/pg_dump/pg_backup_custom.c +++ b/src/bin/pg_dump/pg_backup_custom.c @@ -619,7 +619,6 @@ _skipData(ArchiveHandle *AH) size_t blkLen; char *buf = NULL; int buflen = 0; - size_t cnt; blkLen = ReadInt(AH); while (blkLen != 0) @@ -638,7 +637,7 @@ _skipData(ArchiveHandle *AH) buf = (char *) pg_malloc(blkLen); buflen = blkLen; } - if ((cnt = fread(buf, 1, blkLen, AH->FH)) != blkLen) + if (fread(buf, 1, blkLen, AH->FH) != blkLen) { if (feof(AH->FH)) fatal("could not read from input file: end of file"); @@ -664,9 +663,7 @@ _skipData(ArchiveHandle *AH) static int _WriteByte(ArchiveHandle *AH, const int i) { - int res; - - if ((res = fputc(i, AH->FH)) == EOF) + if (fputc(i, AH->FH) == EOF) WRITE_ERROR_EXIT; return 1; diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index e249177298c7..9fe9c4aaa6e3 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -18,6 +18,7 @@ #endif #include "common/connect.h" +#include "common/string.h" #include "dumputils.h" #include "fe_utils/string_utils.h" #include "parallel.h" @@ -28,6 +29,7 @@ static void _check_database_version(ArchiveHandle *AH); static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser); static void notice_processor(void *arg pg_attribute_unused(), const char *message); +static void notice_processor(void *arg, const char *message); static void _check_database_version(ArchiveHandle *AH) @@ -72,191 +74,64 @@ _check_database_version(ArchiveHandle *AH) /* * Reconnect to the server. If dbname is not NULL, use that database, - * else the one associated with the archive handle. If username is - * not NULL, use that user name, else the one from the handle. + * else the one associated with the archive handle. */ void -ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *username) +ReconnectToServer(ArchiveHandle *AH, const char *dbname) { - PGconn *newConn; - const char *newdbname; - const char *newusername; - - if (!dbname) - newdbname = PQdb(AH->connection); - else - newdbname = dbname; - - if (!username) - newusername = PQuser(AH->connection); - else - newusername = username; - - newConn = _connectDB(AH, newdbname, newusername); - - /* Update ArchiveHandle's connCancel before closing old connection */ - set_archive_cancel_info(AH, newConn); - - PQfinish(AH->connection); - AH->connection = newConn; - - /* Start strict; later phases may override this. */ - PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH, - ALWAYS_SECURE_SEARCH_PATH_SQL)); -} - -/* - * Connect to the db again. - * - * Note: it's not really all that sensible to use a single-entry password - * cache if the username keeps changing. In current usage, however, the - * username never does change, so one savedPassword is sufficient. We do - * update the cache on the off chance that the password has changed since the - * start of the run. - */ -static PGconn * -_connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) -{ - PQExpBufferData connstr; - PGconn *newConn; - const char *newdb; - const char *newuser; - char *password; - char passbuf[100]; - bool new_pass; - - if (!reqdb) - newdb = PQdb(AH->connection); - else - newdb = reqdb; - - if (!requser || strlen(requser) == 0) - newuser = PQuser(AH->connection); - else - newuser = requser; - - pg_log_info("connecting to database \"%s\" as user \"%s\"", - newdb, newuser); - - password = AH->savedPassword; - - if (AH->promptPassword == TRI_YES && password == NULL) - { - simple_prompt("Password: ", passbuf, sizeof(passbuf), false); - password = passbuf; - } - - initPQExpBuffer(&connstr); - appendPQExpBufferStr(&connstr, "dbname="); - appendConnStrVal(&connstr, newdb); - - do - { - const char *keywords[7]; - const char *values[7]; - - keywords[0] = "host"; - values[0] = PQhost(AH->connection); - keywords[1] = "port"; - values[1] = PQport(AH->connection); - keywords[2] = "user"; - values[2] = newuser; - keywords[3] = "password"; - values[3] = password; - keywords[4] = "dbname"; - values[4] = connstr.data; - keywords[5] = "fallback_application_name"; - values[5] = progname; - keywords[6] = NULL; - values[6] = NULL; - - new_pass = false; - newConn = PQconnectdbParams(keywords, values, true); - - if (!newConn) - fatal("could not reconnect to database"); - - if (PQstatus(newConn) == CONNECTION_BAD) - { - if (!PQconnectionNeedsPassword(newConn)) - fatal("could not reconnect to database: %s", - PQerrorMessage(newConn)); - PQfinish(newConn); - - if (password) - fprintf(stderr, "Password incorrect\n"); - - fprintf(stderr, "Connecting to %s as %s\n", - newdb, newuser); - - if (AH->promptPassword != TRI_NO) - { - simple_prompt("Password: ", passbuf, sizeof(passbuf), false); - password = passbuf; - } - else - fatal("connection needs password"); - - new_pass = true; - } - } while (new_pass); + PGconn *oldConn = AH->connection; + RestoreOptions *ropt = AH->public.ropt; /* - * We want to remember connection's actual password, whether or not we got - * it by prompting. So we don't just store the password variable. + * Save the dbname, if given, in override_dbname so that it will also + * affect any later reconnection attempt. */ - if (PQconnectionUsedPassword(newConn)) - { - if (AH->savedPassword) - free(AH->savedPassword); - AH->savedPassword = pg_strdup(PQpass(newConn)); - } + if (dbname) + ropt->cparams.override_dbname = pg_strdup(dbname); - termPQExpBuffer(&connstr); - - /* check for version mismatch */ - _check_database_version(AH); + /* + * Note: we want to establish the new connection, and in particular update + * ArchiveHandle's connCancel, before closing old connection. Otherwise + * an ill-timed SIGINT could try to access a dead connection. + */ + AH->connection = NULL; /* dodge error check in ConnectDatabase */ - PQsetNoticeProcessor(newConn, notice_processor, NULL); + ConnectDatabase((Archive *) AH, &ropt->cparams, true); - return newConn; + PQfinish(oldConn); } - /* - * Make a database connection with the given parameters. The - * connection handle is returned, the parameters are stored in AHX. - * An interactive password prompt is automatically issued if required. + * Make, or remake, a database connection with the given parameters. * + * The resulting connection handle is stored in AHX->connection. + * + * An interactive password prompt is automatically issued if required. + * We store the results of that in AHX->savedPassword. * Note: it's not really all that sensible to use a single-entry password * cache if the username keeps changing. In current usage, however, the * username never does change, so one savedPassword is sufficient. */ void ConnectDatabase(Archive *AHX, - const char *dbname, - const char *pghost, - const char *pgport, - const char *username, - trivalue prompt_password, - bool binary_upgrade) + const ConnParams *cparams, + bool isReconnect) { ArchiveHandle *AH = (ArchiveHandle *) AHX; + trivalue prompt_password; char *password; - char passbuf[100]; bool new_pass; if (AH->connection) fatal("already connected to a database"); + /* Never prompt for a password during a reconnection */ + prompt_password = isReconnect ? TRI_NO : cparams->promptPassword; + password = AH->savedPassword; if (prompt_password == TRI_YES && password == NULL) - { - simple_prompt("Password: ", passbuf, sizeof(passbuf), false); - password = passbuf; - } - AH->promptPassword = prompt_password; + password = simple_prompt("Password: ", false); /* * Start the connection. Loop until we have a password if requested by @@ -266,20 +141,35 @@ ConnectDatabase(Archive *AHX, const char *values[8]; do { - keywords[0] = "host"; - values[0] = pghost; - keywords[1] = "port"; - values[1] = pgport; - keywords[2] = "user"; - values[2] = username; - keywords[3] = "password"; - values[3] = password; - keywords[4] = "dbname"; - values[4] = dbname; - keywords[5] = "fallback_application_name"; - values[5] = progname; - keywords[6] = NULL; - values[6] = NULL; + const char *keywords[8]; + const char *values[8]; + int i = 0; + + /* + * If dbname is a connstring, its entries can override the other + * values obtained from cparams; but in turn, override_dbname can + * override the dbname component of it. + */ + keywords[i] = "host"; + values[i++] = cparams->pghost; + keywords[i] = "port"; + values[i++] = cparams->pgport; + keywords[i] = "user"; + values[i++] = cparams->username; + keywords[i] = "password"; + values[i++] = password; + keywords[i] = "dbname"; + values[i++] = cparams->dbname; + if (cparams->override_dbname) + { + keywords[i] = "dbname"; + values[i++] = cparams->override_dbname; + } + keywords[i] = "fallback_application_name"; + values[i++] = progname; + keywords[i] = NULL; + values[i++] = NULL; + Assert(i <= lengthof(keywords)); new_pass = false; AH->connection = PQconnectdbParams(keywords, values, true); @@ -293,22 +183,29 @@ ConnectDatabase(Archive *AHX, prompt_password != TRI_NO) { PQfinish(AH->connection); - simple_prompt("Password: ", passbuf, sizeof(passbuf), false); - password = passbuf; + password = simple_prompt("Password: ", false); new_pass = true; } } while (new_pass); /* check to see that the backend connection was successfully made */ if (PQstatus(AH->connection) == CONNECTION_BAD) - fatal("connection to database \"%s\" failed: %s", - PQdb(AH->connection) ? PQdb(AH->connection) : "", - PQerrorMessage(AH->connection)); + { + if (isReconnect) + fatal("reconnection failed: %s", + PQerrorMessage(AH->connection)); + else + fatal("%s", + PQerrorMessage(AH->connection)); + } /* Start strict; later phases may override this. */ PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH, ALWAYS_SECURE_SEARCH_PATH_SQL)); + if (password && password != AH->savedPassword) + free(password); + /* * We want to remember connection's actual password, whether or not we got * it by prompting. So we don't just store the password variable. @@ -329,7 +226,7 @@ ConnectDatabase(Archive *AHX, * we connect for the first time, so set the correct GUC and * reconnect. */ - if (binary_upgrade) + if (AH->public.ropt && AH->public.ropt->binary_upgrade) { keywords[6] = "options"; values[6] = AH->public.remoteVersion < GPDB7_MAJOR_PGVERSION ? diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c index 48fa7cb1a38c..fb8c7713a508 100644 --- a/src/bin/pg_dump/pg_backup_directory.c +++ b/src/bin/pg_dump/pg_backup_directory.c @@ -4,7 +4,7 @@ * * A directory format dump is a directory, which contains a "toc.dat" file * for the TOC, and a separate file for each data entry, named ".dat". - * Large objects (BLOBs) are stored in separate files named "blob_.dat", + * Large objects (BLOBs) are stored in separate files named "blob_.dat", * and there's a plain-text TOC file for them called "blobs.toc". If * compression is used, each data file is individually compressed and the * ".gz" suffix is added to the filenames. The TOC files are never @@ -17,7 +17,7 @@ * sync. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2000, Philip Warner * diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index 9bc3184102fb..e41c3a5f0c12 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -231,12 +231,6 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) ctx->hasSeek = checkSeek(ctx->tarFH); - /* - * Forcibly unmark the header as read since we use the lookahead - * buffer - */ - AH->readHeader = 0; - ctx->FH = (void *) tarOpen(AH, "toc.dat", 'r'); ReadHead(AH); ReadToc(AH); @@ -1270,7 +1264,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) /* Header doesn't match, so read to next header */ len = th->fileLen; len += tarPaddingBytesRequired(th->fileLen); - blks = len / TAR_BLOCK_SIZE; /* # of tar blocks */ + blks = len / TAR_BLOCK_SIZE; /* # of tar blocks */ for (i = 0; i < blks; i++) _tarReadRaw(AH, &header[0], TAR_BLOCK_SIZE, NULL, ctx->tarFH); diff --git a/src/bin/pg_dump/pg_backup_utils.c b/src/bin/pg_dump/pg_backup_utils.c index 5729a20a84af..c709a40e06d5 100644 --- a/src/bin/pg_dump/pg_backup_utils.c +++ b/src/bin/pg_dump/pg_backup_utils.c @@ -4,7 +4,7 @@ * Utility routines shared by pg_dump and pg_restore * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/pg_backup_utils.c diff --git a/src/bin/pg_dump/pg_backup_utils.h b/src/bin/pg_dump/pg_backup_utils.h index ca51e2596655..306798f9ac97 100644 --- a/src/bin/pg_dump/pg_backup_utils.h +++ b/src/bin/pg_dump/pg_backup_utils.h @@ -4,7 +4,7 @@ * Utility routines shared by pg_dump and pg_restore. * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/pg_backup_utils.h @@ -17,13 +17,11 @@ #include "common/logging.h" -typedef enum /* bits returned by set_dump_section */ -{ - DUMP_PRE_DATA = 0x01, - DUMP_DATA = 0x02, - DUMP_POST_DATA = 0x04, - DUMP_UNSECTIONED = 0xff -} DumpSections; +/* bits returned by set_dump_section */ +#define DUMP_PRE_DATA 0x01 +#define DUMP_DATA 0x02 +#define DUMP_POST_DATA 0x04 +#define DUMP_UNSECTIONED 0xff typedef void (*on_exit_nicely_callback) (int code, void *arg); diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index ffe3f97d7944..09b70c45b9a5 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -6,7 +6,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * pg_dump will read the system catalogs in a database and dump out a @@ -138,6 +138,8 @@ static SimpleStringList funcid_string_list = {NULL, NULL}; static SimpleOidList function_include_oids = {NULL, NULL}; static SimpleOidList preassigned_oids = {NULL, NULL}; +static SimpleStringList extension_include_patterns = {NULL, NULL}; +static SimpleOidList extension_include_oids = {NULL, NULL}; static const CatalogId nilCatalogId = {0, 0}; @@ -184,6 +186,10 @@ static void expand_schema_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids, bool strict_names); +static void expand_extension_name_patterns(Archive *fout, + SimpleStringList *patterns, + SimpleOidList *oids, + bool strict_names); static void expand_foreign_server_name_patterns(Archive *fout, SimpleStringList *patterns, SimpleOidList *oids); @@ -209,7 +215,7 @@ static void dumpSecLabel(Archive *fout, const char *type, const char *name, CatalogId catalogId, int subid, DumpId dumpId); static int findSecLabels(Archive *fout, Oid classoid, Oid objoid, SecLabelItem **items); -static void collectSecLabels(Archive *fout); +static int collectSecLabels(Archive *fout, SecLabelItem **items); static void dumpDumpableObject(Archive *fout, DumpableObject *dobj); static void dumpNamespace(Archive *fout, const NamespaceInfo *nspinfo); static void dumpExtension(Archive *fout, const ExtensionInfo *extinfo); @@ -280,6 +286,11 @@ static void buildMatViewRefreshDependencies(Archive *fout); static void getTableDataFKConstraints(void); static char *format_function_arguments(const FuncInfo *finfo, const char *funcargs, bool is_agg); +static char *format_function_arguments_old(Archive *fout, + const FuncInfo *finfo, int nallargs, + char **allargtypes, + char **argmodes, + char **argnames); static char *format_function_signature(Archive *fout, const FuncInfo *finfo, bool honor_quotes); static char *convertRegProcReference(const char *proc); @@ -304,11 +315,14 @@ static void binary_upgrade_set_namespace_oid(Archive *fout, static void dumpSearchPath(Archive *AH); static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout, PQExpBuffer upgrade_buffer, - const TypeInfo *tyinfo, - bool force_array_type); + Oid pg_type_oid, + bool force_array_type, + bool include_multirange_type); static void binary_upgrade_set_type_oids_by_rel(Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tblinfo); +static void binary_upgrade_set_type_oids_by_rel_oid(Archive *fout, + PQExpBuffer upgrade_buffer, Oid pg_rel_oid); static void binary_upgrade_set_pg_class_oids(Archive *fout, PQExpBuffer upgrade_buffer, Oid pg_class_oid, bool is_index); @@ -380,7 +394,6 @@ main(int argc, char **argv) char *use_role = NULL; long rowsPerInsert; int numWorkers = 1; - trivalue prompt_password = TRI_DEFAULT; int compressLevel = -1; int plainText = 0; ArchiveFormat archiveFormat = archUnknown; @@ -404,6 +417,7 @@ main(int argc, char **argv) {"clean", no_argument, NULL, 'c'}, {"create", no_argument, NULL, 'C'}, {"dbname", required_argument, NULL, 'd'}, + {"extension", required_argument, NULL, 'e'}, {"file", required_argument, NULL, 'f'}, {"format", required_argument, NULL, 'F'}, {"host", required_argument, NULL, 'h'}, @@ -454,9 +468,10 @@ main(int argc, char **argv) {"no-comments", no_argument, &dopt.no_comments, 1}, {"no-publications", no_argument, &dopt.no_publications, 1}, {"no-security-labels", no_argument, &dopt.no_security_labels, 1}, + {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1}, {"no-synchronized-snapshots", no_argument, &dopt.no_synchronized_snapshots, 1}, + {"no-toast-compression", no_argument, &dopt.no_toast_compression, 1}, {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1}, - {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1}, {"no-sync", no_argument, NULL, 7}, {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1}, {"rows-per-insert", required_argument, NULL, 10}, @@ -504,7 +519,7 @@ main(int argc, char **argv) InitDumpOptions(&dopt); - while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:oOp:RsS:t:T:U:vwWxZ:", + while ((c = getopt_long(argc, argv, "abBcCd:e:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:", long_options, &optindex)) != -1) { switch (c) @@ -530,7 +545,12 @@ main(int argc, char **argv) break; case 'd': /* database name */ - dopt.dbname = pg_strdup(optarg); + dopt.cparams.dbname = pg_strdup(optarg); + break; + + case 'e': /* include extension(s) */ + simple_string_list_append(&extension_include_patterns, optarg); + dopt.include_everything = false; break; case 'E': /* Dump encoding */ @@ -546,7 +566,7 @@ main(int argc, char **argv) break; case 'h': /* server host */ - dopt.pghost = pg_strdup(optarg); + dopt.cparams.pghost = pg_strdup(optarg); break; case 'j': /* number of dump jobs */ @@ -567,7 +587,7 @@ main(int argc, char **argv) break; case 'p': /* server port */ - dopt.pgport = pg_strdup(optarg); + dopt.cparams.pgport = pg_strdup(optarg); break; case 'R': @@ -592,20 +612,20 @@ main(int argc, char **argv) break; case 'U': - dopt.username = pg_strdup(optarg); + dopt.cparams.username = pg_strdup(optarg); break; case 'v': /* verbose */ g_verbose = true; - pg_logging_set_level(PG_LOG_INFO); + pg_logging_increase_verbosity(); break; case 'w': - prompt_password = TRI_NO; + dopt.cparams.promptPassword = TRI_NO; break; case 'W': - prompt_password = TRI_YES; + dopt.cparams.promptPassword = TRI_YES; break; case 'x': /* skip ACL dump */ @@ -727,8 +747,8 @@ main(int argc, char **argv) * Non-option argument specifies database name as long as it wasn't * already specified with -d / --dbname */ - if (optind < argc && dopt.dbname == NULL) - dopt.dbname = argv[optind++]; + if (optind < argc && dopt.cparams.dbname == NULL) + dopt.cparams.dbname = argv[optind++]; /* Complain if any arguments remain */ if (optind < argc) @@ -854,7 +874,7 @@ main(int argc, char **argv) * Open the database using the Archiver, so it knows about it. Errors mean * death. */ - ConnectDatabase(fout, dopt.dbname, dopt.pghost, dopt.pgport, dopt.username, prompt_password, dopt.binary_upgrade); + ConnectDatabase(fout, &dopt.cparams, false); setup_connection(fout, dumpencoding, dumpsnapshot, use_role); /* @@ -949,6 +969,15 @@ main(int argc, char **argv) expand_oid_patterns(&relid_string_list, &table_include_oids); expand_oid_patterns(&funcid_string_list, &function_include_oids); + /* Expand extension selection patterns into OID lists */ + if (extension_include_patterns.head != NULL) + { + expand_extension_name_patterns(fout, &extension_include_patterns, + &extension_include_oids, + strict_names); + if (extension_include_oids.head == NULL) + fatal("no matching extensions were found"); + } /* * Dumping blobs is the default for dumps where an inclusion switch is not @@ -1012,8 +1041,7 @@ main(int argc, char **argv) getAdditionalACLs(fout); if (!dopt.no_comments) collectComments(fout); - if (!dopt.no_security_labels) - collectSecLabels(fout); + /* Security labels are collected on-demand in findSecLabels() */ /* Lastly, create dummy objects to represent the section boundaries */ boundaryObjs = createBoundaryObjects(); @@ -1043,7 +1071,9 @@ main(int argc, char **argv) * order. */ - /* First the special ENCODING, STDSTRINGS, and SEARCHPATH entries. */ + /* + * First the special entries for ENCODING, STDSTRINGS, and SEARCHPATH. + */ dumpEncoding(fout); dumpStdStrings(fout); dumpSearchPath(fout); @@ -1072,6 +1102,11 @@ main(int argc, char **argv) ropt->filename = filename; /* if you change this list, see dumpOptionsFromRestoreOptions */ + ropt->cparams.dbname = dopt.cparams.dbname ? pg_strdup(dopt.cparams.dbname) : NULL; + ropt->cparams.pgport = dopt.cparams.pgport ? pg_strdup(dopt.cparams.pgport) : NULL; + ropt->cparams.pghost = dopt.cparams.pghost ? pg_strdup(dopt.cparams.pghost) : NULL; + ropt->cparams.username = dopt.cparams.username ? pg_strdup(dopt.cparams.username) : NULL; + ropt->cparams.promptPassword = dopt.cparams.promptPassword; ropt->dropSchema = dopt.outputClean; ropt->dataOnly = dopt.dataOnly; ropt->schemaOnly = dopt.schemaOnly; @@ -1158,6 +1193,7 @@ help(const char *progname) printf(_(" -B, --no-blobs exclude large objects in dump\n")); printf(_(" -c, --clean clean (drop) database objects before recreating\n")); printf(_(" -C, --create include commands to create database in dump\n")); + printf(_(" -e, --extension=PATTERN dump the specified extension(s) only\n")); printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n")); printf(_(" -n, --schema=PATTERN dump the specified schema(s) only\n")); printf(_(" -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n")); @@ -1188,6 +1224,7 @@ help(const char *progname) printf(_(" --no-subscriptions do not dump subscriptions\n")); printf(_(" --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n")); printf(_(" --no-tablespaces do not dump tablespace assignments\n")); + printf(_(" --no-toast-compression do not dump TOAST compression methods\n")); printf(_(" --no-unlogged-table-data do not dump unlogged table data\n")); printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n")); printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n")); @@ -1517,6 +1554,53 @@ expand_schema_name_patterns(Archive *fout, destroyPQExpBuffer(query); } +/* + * Find the OIDs of all extensions matching the given list of patterns, + * and append them to the given OID list. + */ +static void +expand_extension_name_patterns(Archive *fout, + SimpleStringList *patterns, + SimpleOidList *oids, + bool strict_names) +{ + PQExpBuffer query; + PGresult *res; + SimpleStringListCell *cell; + int i; + + if (patterns->head == NULL) + return; /* nothing to do */ + + query = createPQExpBuffer(); + + /* + * The loop below runs multiple SELECTs might sometimes result in + * duplicate entries in the OID list, but we don't care. + */ + for (cell = patterns->head; cell; cell = cell->next) + { + appendPQExpBufferStr(query, + "SELECT oid FROM pg_catalog.pg_extension e\n"); + processSQLNamePattern(GetConnection(fout), query, cell->val, false, + false, NULL, "e.extname", NULL, NULL); + + res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); + if (strict_names && PQntuples(res) == 0) + fatal("no matching extensions were found for pattern \"%s\"", cell->val); + + for (i = 0; i < PQntuples(res); i++) + { + simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); + } + + PQclear(res); + resetPQExpBuffer(query); + } + + destroyPQExpBuffer(query); +} + /* * Find the OIDs of all foreign servers matching the given list of patterns, * and append them to the given OID list. @@ -1543,8 +1627,8 @@ expand_foreign_server_name_patterns(Archive *fout, for (cell = patterns->head; cell; cell = cell->next) { - appendPQExpBuffer(query, - "SELECT oid FROM pg_catalog.pg_foreign_server s\n"); + appendPQExpBufferStr(query, + "SELECT oid FROM pg_catalog.pg_foreign_server s\n"); processSQLNamePattern(GetConnection(fout), query, cell->val, false, false, NULL, "s.srvname", NULL, NULL); @@ -1863,7 +1947,7 @@ selectDumpableType(TypeInfo *tyinfo, Archive *fout) } /* skip auto-generated array types */ - if (tyinfo->isArray) + if (tyinfo->isArray || tyinfo->isMultirange) { tyinfo->dobj.objType = DO_DUMMY_TYPE; @@ -2015,8 +2099,9 @@ selectDumpableAccessMethod(AccessMethodInfo *method, Archive *fout) * Built-in extensions should be skipped except for checking ACLs, since we * assume those will already be installed in the target database. We identify * such extensions by their having OIDs in the range reserved for initdb. - * We dump all user-added extensions by default, or none of them if - * include_everything is false (i.e., a --schema or --table switch was given). + * We dump all user-added extensions by default. No extensions are dumped + * if include_everything is false (i.e., a --schema or --table switch was + * given), except if --extension specifies a list of extensions to dump. */ static void selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt) @@ -2029,9 +2114,18 @@ selectDumpableExtension(ExtensionInfo *extinfo, DumpOptions *dopt) if (extinfo->dobj.catId.oid <= (Oid) g_last_builtin_oid) extinfo->dobj.dump = extinfo->dobj.dump_contains = DUMP_COMPONENT_ACL; else - extinfo->dobj.dump = extinfo->dobj.dump_contains = - dopt->include_everything ? DUMP_COMPONENT_ALL : - DUMP_COMPONENT_NONE; + { + /* check if there is a list of extensions to dump */ + if (extension_include_oids.head != NULL) + extinfo->dobj.dump = extinfo->dobj.dump_contains = + simple_oid_list_member(&extension_include_oids, + extinfo->dobj.catId.oid) ? + DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; + else + extinfo->dobj.dump = extinfo->dobj.dump_contains = + dopt->include_everything ? + DUMP_COMPONENT_ALL : DUMP_COMPONENT_NONE; + } } /* @@ -4367,6 +4461,9 @@ dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo) PQExpBuffer query; char *tag; + if (!(pubrinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)) + return; + tag = psprintf("%s %s", pubinfo->dobj.name, tbinfo->dobj.name); query = createPQExpBuffer(); @@ -4391,6 +4488,13 @@ dumpPublicationTable(Archive *fout, const PublicationRelInfo *pubrinfo) .description = "PUBLICATION TABLE", .section = SECTION_POST_DATA, .createStmt = query->data)); + ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId, + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = pubinfo->rolname, + .description = "PUBLICATION TABLE", + .section = SECTION_POST_DATA, + .createStmt = query->data)); free(tag); destroyPQExpBuffer(query); @@ -4428,6 +4532,7 @@ getSubscriptions(Archive *fout) int i_oid; int i_subname; int i_subowner; + int i_substream; int i_subconninfo; int i_subslotname; int i_subsynccommit; @@ -4465,16 +4570,19 @@ getSubscriptions(Archive *fout) "s.subpublications,\n"); if (fout->remoteVersion >= 140000) - appendPQExpBuffer(query, - " s.subbinary\n"); + appendPQExpBufferStr(query, " s.subbinary,\n"); else - appendPQExpBuffer(query, - " false AS subbinary\n"); + appendPQExpBufferStr(query, " false AS subbinary,\n"); - appendPQExpBuffer(query, - "FROM pg_subscription s\n" - "WHERE s.subdbid = (SELECT oid FROM pg_database\n" - " WHERE datname = current_database())"); + if (fout->remoteVersion >= 140000) + appendPQExpBufferStr(query, " s.substream\n"); + else + appendPQExpBufferStr(query, " false AS substream\n"); + + appendPQExpBufferStr(query, + "FROM pg_subscription s\n" + "WHERE s.subdbid = (SELECT oid FROM pg_database\n" + " WHERE datname = current_database())"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -4489,6 +4597,7 @@ getSubscriptions(Archive *fout) i_subsynccommit = PQfnumber(res, "subsynccommit"); i_subpublications = PQfnumber(res, "subpublications"); i_subbinary = PQfnumber(res, "subbinary"); + i_substream = PQfnumber(res, "substream"); subinfo = pg_malloc(ntups * sizeof(SubscriptionInfo)); @@ -4512,6 +4621,8 @@ getSubscriptions(Archive *fout) pg_strdup(PQgetvalue(res, i, i_subpublications)); subinfo[i].subbinary = pg_strdup(PQgetvalue(res, i, i_subbinary)); + subinfo[i].substream = + pg_strdup(PQgetvalue(res, i, i_substream)); /* Decide whether we want to dump it */ selectDumpableObject(&(subinfo[i].dobj), fout); @@ -4550,13 +4661,7 @@ dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo) /* Build list of quoted publications and append them to query. */ if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames)) - { - pg_log_warning("could not parse subpublications array"); - if (pubnames) - free(pubnames); - pubnames = NULL; - npubnames = 0; - } + fatal("could not parse subpublications array"); publications = createPQExpBuffer(); for (i = 0; i < npubnames; i++) @@ -4574,7 +4679,10 @@ dumpSubscription(Archive *fout, const SubscriptionInfo *subinfo) appendPQExpBufferStr(query, "NONE"); if (strcmp(subinfo->subbinary, "t") == 0) - appendPQExpBuffer(query, ", binary = true"); + appendPQExpBufferStr(query, ", binary = true"); + + if (strcmp(subinfo->substream, "f") != 0) + appendPQExpBufferStr(query, ", streaming = on"); if (strcmp(subinfo->subsynccommit, "off") != 0) appendPQExpBuffer(query, ", synchronous_commit = %s", fmtId(subinfo->subsynccommit)); @@ -4658,6 +4766,36 @@ append_depends_on_extension(Archive *fout, } } +static Oid +get_next_possible_free_pg_type_oid(Archive *fout, PQExpBuffer upgrade_query) +{ + /* + * If the old version didn't assign an array type, but the new version + * does, we must select an unused type OID to assign. This currently only + * happens for domains, when upgrading pre-v11 to v11 and up. + * + * Note: local state here is kind of ugly, but we must have some, since we + * mustn't choose the same unused OID more than once. + */ + static Oid next_possible_free_oid = FirstNormalObjectId; + PGresult *res; + bool is_dup; + + do + { + ++next_possible_free_oid; + printfPQExpBuffer(upgrade_query, + "SELECT EXISTS(SELECT 1 " + "FROM pg_catalog.pg_type " + "WHERE oid = '%u'::pg_catalog.oid);", + next_possible_free_oid); + res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data); + is_dup = (PQgetvalue(res, 0, 0)[0] == 't'); + PQclear(res); + } while (is_dup); + + return next_possible_free_oid; +} static void binary_upgrade_set_namespace_oid(Archive *fout, PQExpBuffer upgrade_buffer, @@ -4702,22 +4840,41 @@ binary_upgrade_set_namespace_oid(Archive *fout, PQExpBuffer upgrade_buffer, static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout, PQExpBuffer upgrade_buffer, - const TypeInfo *tyinfo, - bool force_array_type) + Oid pg_type_oid, + bool force_array_type, + bool include_multirange_type) { PQExpBuffer upgrade_query = createPQExpBuffer(); PGresult *res; - Oid pg_type_array_oid = tyinfo->typarrayoid; - Oid pg_type_array_ns_oid = tyinfo->typarrayns; - char *pg_type_array_name = tyinfo->typarrayname; + TypeInfo *tyinfo = findTypeByOid(pg_type_oid); + Oid pg_type_array_oid; + Oid pg_type_array_ns_oid; + char *pg_type_array_name; + Oid pg_type_multirange_oid; + Oid pg_type_multirange_array_oid; + + /* + * GPDB: the binary-upgrade preassignment functions take the namespace + * and object name in addition to the OID, so that the QD can dispatch + * the preassigned OIDs to the QEs; we also track every preassigned OID + * in preassigned_oids. Take them from the TypeInfo gathered by + * getTypes() (which also covers table rowtypes). + */ + if (tyinfo == NULL) + fatal("could not find type with OID %u for binary upgrade", pg_type_oid); + pg_type_array_oid = tyinfo->typarrayoid; + pg_type_array_ns_oid = tyinfo->typarrayns; + pg_type_array_name = tyinfo->typarrayname; simple_oid_list_append(&preassigned_oids, tyinfo->dobj.catId.oid); appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, must preserve pg_type oid\n"); appendPQExpBuffer(upgrade_buffer, - "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid, " - "'%u'::pg_catalog.oid, $$%s$$::text);\n\n", - tyinfo->dobj.catId.oid, tyinfo->dobj.namespace->dobj.catId.oid, tyinfo->dobj.name); + "SELECT pg_catalog.binary_upgrade_set_next_pg_type_oid('%u'::pg_catalog.oid, " + "'%u'::pg_catalog.oid, $$%s$$::text);\n\n", + tyinfo->dobj.catId.oid, + tyinfo->dobj.namespace->dobj.catId.oid, + tyinfo->dobj.name); if (!OidIsValid(pg_type_array_oid) && force_array_type) { @@ -4762,6 +4919,46 @@ binary_upgrade_set_type_oids_by_type_oid(Archive *fout, pg_type_array_name); } + /* + * Pre-set the multirange type oid and its own array type oid. + */ + if (include_multirange_type) + { + if (fout->remoteVersion >= 140000) + { + appendPQExpBuffer(upgrade_query, + "SELECT t.oid, t.typarray " + "FROM pg_catalog.pg_type t " + "JOIN pg_catalog.pg_range r " + "ON t.oid = r.rngmultitypid " + "WHERE r.rngtypid = '%u'::pg_catalog.oid;", + pg_type_oid); + + res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data); + + pg_type_multirange_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "oid"))); + pg_type_multirange_array_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typarray"))); + + PQclear(res); + } + else + { + pg_type_multirange_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query); + pg_type_multirange_array_oid = get_next_possible_free_pg_type_oid(fout, upgrade_query); + } + + appendPQExpBufferStr(upgrade_buffer, + "\n-- For binary upgrade, must preserve multirange pg_type oid\n"); + appendPQExpBuffer(upgrade_buffer, + "SELECT pg_catalog.binary_upgrade_set_next_multirange_pg_type_oid('%u'::pg_catalog.oid);\n\n", + pg_type_multirange_oid); + appendPQExpBufferStr(upgrade_buffer, + "\n-- For binary upgrade, must preserve multirange pg_type array oid\n"); + appendPQExpBuffer(upgrade_buffer, + "SELECT pg_catalog.binary_upgrade_set_next_multirange_array_pg_type_oid('%u'::pg_catalog.oid);\n\n", + pg_type_multirange_array_oid); + } + destroyPQExpBuffer(upgrade_query); } @@ -4770,9 +4967,26 @@ binary_upgrade_set_type_oids_by_rel(Archive *fout, PQExpBuffer upgrade_buffer, const TableInfo *tblinfo) { - TypeInfo *typinfo = findTypeByOid(tblinfo->reltype); - binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer, - typinfo, false); + PQExpBuffer upgrade_query = createPQExpBuffer(); + PGresult *upgrade_res; + Oid pg_type_oid; + + appendPQExpBuffer(upgrade_query, + "SELECT c.reltype AS crel " + "FROM pg_catalog.pg_class c " + "WHERE c.oid = '%u'::pg_catalog.oid;", + tblinfo->dobj.catId.oid); + + upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data); + + pg_type_oid = atooid(PQgetvalue(upgrade_res, 0, PQfnumber(upgrade_res, "crel"))); + + if (OidIsValid(pg_type_oid)) + binary_upgrade_set_type_oids_by_type_oid(fout, upgrade_buffer, + pg_type_oid, false, false); + + PQclear(upgrade_res); + destroyPQExpBuffer(upgrade_query); } static void @@ -5351,6 +5565,7 @@ getTypes(Archive *fout, int *numTypes) tyinfo[i].dacl.initprivs = NULL; tyinfo[i].ftypname = NULL; /* may get filled later */ tyinfo[i].rolname = getRoleName(PQgetvalue(res, i, i_typowner)); + tyinfo[i].typacl = pg_strdup(PQgetvalue(res, i, i_typacl)); tyinfo[i].typelem = atooid(PQgetvalue(res, i, i_typelem)); tyinfo[i].typrelid = atooid(PQgetvalue(res, i, i_typrelid)); tyinfo[i].typrelkind = *PQgetvalue(res, i, i_typrelkind); @@ -5375,6 +5590,10 @@ getTypes(Archive *fout, int *numTypes) tyinfo[i].typarrayname = pg_strdup(PQgetvalue(res, i, i_typarrayname)); tyinfo[i].typarrayns = atooid(PQgetvalue(res, i, i_typarrayns)); } + if (tyinfo[i].typtype == 'm') + tyinfo[i].isMultirange = true; + else + tyinfo[i].isMultirange = false; /* Decide whether we want to dump it */ selectDumpableType(&tyinfo[i], fout); @@ -5995,6 +6214,9 @@ getAggregates(Archive *fout, int *numAggs) agginfo[i].aggfn.dacl.privtype = 0; agginfo[i].aggfn.dacl.initprivs = NULL; agginfo[i].aggfn.rolname = getRoleName(PQgetvalue(res, i, i_proowner)); + if (strlen(agginfo[i].aggfn.rolname) == 0) + pg_log_warning("owner of aggregate function \"%s\" appears to be invalid", + agginfo[i].aggfn.dobj.name); agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */ agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */ agginfo[i].aggfn.nargs = atoi(PQgetvalue(res, i, i_pronargs)); @@ -7180,10 +7402,7 @@ getInherits(Archive *fout, int *numInherits) int i_inhrelid; int i_inhparent; - /* - * Find all the inheritance information, excluding implicit inheritance - * via partitioning. - */ + /* find all the inheritance information */ appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -8416,9 +8635,12 @@ getProcLangs(Archive *fout, int *numProcLangs) /* * getCasts - * get basic information about every cast in the system + * get basic information about most casts in the system * * numCasts is set to the number of casts read in + * + * Skip casts from a range to its multirange, since we'll create those + * automatically. */ CastInfo * getCasts(Archive *fout, int *numCasts) @@ -8436,7 +8658,20 @@ getCasts(Archive *fout, int *numCasts) int i_castcontext; int i_castmethod; - if (fout->remoteVersion >= 80400) + if (fout->remoteVersion >= 140000) + { + appendPQExpBufferStr(query, "SELECT tableoid, oid, " + "castsource, casttarget, castfunc, castcontext, " + "castmethod " + "FROM pg_cast c " + "WHERE NOT EXISTS ( " + "SELECT 1 FROM pg_range r " + "WHERE c.castsource = r.rngtypid " + "AND c.casttarget = r.rngmultitypid " + ") " + "ORDER BY 3,4"); + } + else if (fout->remoteVersion >= 80400) { appendPQExpBufferStr(query, "SELECT tableoid, oid, " "castsource, casttarget, castfunc, castcontext, " @@ -8626,45 +8861,9 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) { DumpOptions *dopt = fout->dopt; PQExpBuffer q = createPQExpBuffer(); - PQExpBuffer tbloids = createPQExpBuffer(); - PQExpBuffer checkoids = createPQExpBuffer(); - PGresult *res; - int ntups; - int curtblindx; - int i_attrelid; - int i_attnum; - int i_attname; - int i_atttypname; - int i_atttypmod; - int i_attstattarget; - int i_attstorage; - int i_typstorage; - int i_attidentity; - int i_attgenerated; - int i_attisdropped; - int i_attlen; - int i_attalign; - int i_attislocal; - int i_attnotnull; - int i_attoptions; - int i_attcollation; - int i_attfdwoptions; - int i_attmissingval; - int i_atthasdef; - int i_attencoding; - /* - * We want to perform just one query against pg_attribute, and then just - * one against pg_attrdef (for DEFAULTs) and one against pg_constraint - * (for CHECK constraints). However, we mustn't try to select every row - * of those catalogs and then sort it out on the client side, because some - * of the server-side functions we need would be unsafe to apply to tables - * we don't have lock on. Hence, we build an array of the OIDs of tables - * we care about (and now have lock on!), and use a WHERE clause to - * constrain which rows are selected. - */ - appendPQExpBufferChar(tbloids, '{'); - appendPQExpBufferChar(checkoids, '{'); + /* GPDB_14_MERGE_FIXME: GPDB specific column, need to keep this for easy to use*/ + int i_attencoding; for (int i = 0; i < numTables; i++) { @@ -8681,500 +8880,382 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) if (!tbinfo->interesting) continue; - /* OK, we need info for this table */ - if (tbloids->len > 1) /* do we have more than the '{'? */ - appendPQExpBufferChar(tbloids, ','); - appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid); - - if (tbinfo->ncheck > 0) - { - /* Also make a list of the ones with check constraints */ - if (checkoids->len > 1) /* do we have more than the '{'? */ - appendPQExpBufferChar(checkoids, ','); - appendPQExpBuffer(checkoids, "%u", tbinfo->dobj.catId.oid); - } - } - appendPQExpBufferChar(tbloids, '}'); - appendPQExpBufferChar(checkoids, '}'); - - /* find all the user attributes and their types */ - appendPQExpBufferStr(q, - "SELECT\n" - "a.attrelid,\n" - "a.attnum,\n" - "a.attname,\n" - "a.atttypmod,\n" - "a.attstattarget,\n" - "a.attstorage,\n" - "t.typstorage,\n" - "a.attnotnull,\n" - "a.atthasdef,\n" - "a.attisdropped,\n" - "a.attlen,\n" - "a.attalign,\n" - "a.attislocal,\n" - "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n" - "pg_catalog.array_to_string(e.attoptions, ',') AS attencoding,\n"); + /* find all the user attributes and their types */ - if (fout->remoteVersion >= 90000) - appendPQExpBufferStr(q, - "array_to_string(a.attoptions, ', ') AS attoptions,\n"); - else - appendPQExpBufferStr(q, - "'' AS attoptions,\n"); - - if (fout->remoteVersion >= 90100) - { /* - * Since we only want to dump COLLATE clauses for attributes whose - * collation is different from their type's default, we use a CASE - * here to suppress uninteresting attcollations cheaply. + * we must read the attribute names in attribute number order! because + * we will use the attnum to index into the attnames array later. */ - appendPQExpBufferStr(q, - "CASE WHEN a.attcollation <> t.typcollation " - "THEN a.attcollation ELSE 0 END AS attcollation,\n"); - } - else - appendPQExpBufferStr(q, - "0 AS attcollation,\n"); + pg_log_info("finding the columns and types of table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); - if (fout->remoteVersion >= 90200) - appendPQExpBufferStr(q, - "pg_catalog.array_to_string(ARRAY(" - "SELECT pg_catalog.quote_ident(option_name) || " - "' ' || pg_catalog.quote_literal(option_value) " - "FROM pg_catalog.pg_options_to_table(attfdwoptions) " - "ORDER BY option_name" - "), E',\n ') AS attfdwoptions,\n"); - else - appendPQExpBufferStr(q, - "'' AS attfdwoptions,\n"); + resetPQExpBuffer(q); - if (fout->remoteVersion >= 100000) - appendPQExpBufferStr(q, - "a.attidentity,\n"); - else appendPQExpBufferStr(q, - "'' AS attidentity,\n"); + "SELECT\n" + "a.attnum,\n" + "a.attname,\n" + "a.atttypmod,\n" + "a.attstattarget,\n" + "a.attstorage,\n" + "t.typstorage,\n" + "a.attnotnull,\n" + "a.atthasdef,\n" + "a.attisdropped,\n" + "a.attlen,\n" + "a.attalign,\n" + "a.attislocal,\n" + "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"); + + if (fout->remoteVersion >= 90000) + appendPQExpBufferStr(q, + "array_to_string(a.attoptions, ', ') AS attoptions,\n"); + else + appendPQExpBufferStr(q, + "'' AS attoptions,\n"); - if (fout->remoteVersion >= 110000) - appendPQExpBufferStr(q, - "CASE WHEN a.atthasmissing AND NOT a.attisdropped " - "THEN a.attmissingval ELSE null END AS attmissingval,\n"); - else - appendPQExpBufferStr(q, - "NULL AS attmissingval,\n"); + if (fout->remoteVersion >= 90100) + { + /* + * Since we only want to dump COLLATE clauses for attributes whose + * collation is different from their type's default, we use a CASE + * here to suppress uninteresting attcollations cheaply. + */ + appendPQExpBufferStr(q, + "CASE WHEN a.attcollation <> t.typcollation " + "THEN a.attcollation ELSE 0 END AS attcollation,\n"); + } + else + appendPQExpBufferStr(q, + "0 AS attcollation,\n"); - if (fout->remoteVersion >= 120000) - appendPQExpBufferStr(q, - "a.attgenerated\n"); - else - appendPQExpBufferStr(q, - "'' AS attgenerated\n"); + if (fout->remoteVersion >= 140000) + appendPQExpBuffer(q, + "a.attcompression AS attcompression,\n"); + else + appendPQExpBuffer(q, + "'' AS attcompression,\n"); - /* need left join to pg_type to not fail on dropped columns ... */ - appendPQExpBuffer(q, - "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n" - "JOIN pg_catalog.pg_attribute a ON (src.tbloid = a.attrelid) " - "LEFT JOIN pg_catalog.pg_type t " - "ON (a.atttypid = t.oid)\n" - "LEFT OUTER JOIN pg_catalog.pg_attribute_encoding e " - "ON e.attrelid = a.attrelid AND e.attnum = a.attnum \n" - "WHERE a.attnum > 0::pg_catalog.int2\n" - "ORDER BY a.attrelid, a.attnum", - tbloids->data); + appendPQExpBuffer(q, + "pg_catalog.array_to_string(e.attoptions, ',') AS attencoding,\n"); - res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK); + if (fout->remoteVersion >= 90200) + appendPQExpBufferStr(q, + "pg_catalog.array_to_string(ARRAY(" + "SELECT pg_catalog.quote_ident(option_name) || " + "' ' || pg_catalog.quote_literal(option_value) " + "FROM pg_catalog.pg_options_to_table(attfdwoptions) " + "ORDER BY option_name" + "), E',\n ') AS attfdwoptions,\n"); + else + appendPQExpBufferStr(q, + "'' AS attfdwoptions,\n"); - ntups = PQntuples(res); + if (fout->remoteVersion >= 100000) + appendPQExpBufferStr(q, + "a.attidentity,\n"); + else + appendPQExpBufferStr(q, + "'' AS attidentity,\n"); - i_attrelid = PQfnumber(res, "attrelid"); - i_attnum = PQfnumber(res, "attnum"); - i_attname = PQfnumber(res, "attname"); - i_atttypname = PQfnumber(res, "atttypname"); - i_atttypmod = PQfnumber(res, "atttypmod"); - i_attstattarget = PQfnumber(res, "attstattarget"); - i_attstorage = PQfnumber(res, "attstorage"); - i_typstorage = PQfnumber(res, "typstorage"); - i_attidentity = PQfnumber(res, "attidentity"); - i_attgenerated = PQfnumber(res, "attgenerated"); - i_attisdropped = PQfnumber(res, "attisdropped"); - i_attlen = PQfnumber(res, "attlen"); - i_attalign = PQfnumber(res, "attalign"); - i_attislocal = PQfnumber(res, "attislocal"); - i_attnotnull = PQfnumber(res, "attnotnull"); - i_attoptions = PQfnumber(res, "attoptions"); - i_attcollation = PQfnumber(res, "attcollation"); - i_attfdwoptions = PQfnumber(res, "attfdwoptions"); - i_attmissingval = PQfnumber(res, "attmissingval"); - i_atthasdef = PQfnumber(res, "atthasdef"); - i_attencoding = PQfnumber(res, "attencoding"); + if (fout->remoteVersion >= 110000) + appendPQExpBufferStr(q, + "CASE WHEN a.atthasmissing AND NOT a.attisdropped " + "THEN a.attmissingval ELSE null END AS attmissingval,\n"); + else + appendPQExpBufferStr(q, + "NULL AS attmissingval,\n"); - /* Within the next loop, we'll accumulate OIDs of tables with defaults */ - resetPQExpBuffer(tbloids); - appendPQExpBufferChar(tbloids, '{'); + if (fout->remoteVersion >= 120000) + appendPQExpBufferStr(q, + "a.attgenerated\n"); + else + appendPQExpBufferStr(q, + "'' AS attgenerated\n"); - /* - * Outer loop iterates once per table, not once per row. Incrementing of - * r is handled by the inner loop. - */ - curtblindx = -1; - for (int r = 0; r < ntups;) - { - Oid attrelid = atooid(PQgetvalue(res, r, i_attrelid)); - TableInfo *tbinfo = NULL; - int numatts; - bool hasdefaults; + /* need left join here to not fail on dropped columns ... */ + appendPQExpBuffer(q, + "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t " + "ON a.atttypid = t.oid\n" + "LEFT OUTER JOIN pg_catalog.pg_attribute_encoding e ON e.attrelid = a.attrelid AND e.attnum = a.attnum \n" + "WHERE a.attrelid = '%u'::pg_catalog.oid " + "AND a.attnum > 0::pg_catalog.int2\n" + "ORDER BY a.attnum", + tbinfo->dobj.catId.oid); - /* Count rows for this table */ - for (numatts = 1; numatts < ntups - r; numatts++) - if (atooid(PQgetvalue(res, r + numatts, i_attrelid)) != attrelid) - break; + res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK); - /* - * Locate the associated TableInfo; we rely on tblinfo[] being in OID - * order. - */ - while (++curtblindx < numTables) - { - tbinfo = &tblinfo[curtblindx]; - if (tbinfo->dobj.catId.oid == attrelid) - break; - } - if (curtblindx >= numTables) - fatal("unrecognized table OID %u", attrelid); - /* cross-check that we only got requested tables */ - if (tbinfo->relkind == RELKIND_SEQUENCE || - !tbinfo->interesting) - fatal("unexpected column data for table \"%s\"", - tbinfo->dobj.name); + ntups = PQntuples(res); - /* Save data for this table */ - tbinfo->numatts = numatts; - tbinfo->attnames = (char **) pg_malloc(numatts * sizeof(char *)); - tbinfo->atttypnames = (char **) pg_malloc(numatts * sizeof(char *)); - tbinfo->atttypmod = (int *) pg_malloc(numatts * sizeof(int)); - tbinfo->attstattarget = (int *) pg_malloc(numatts * sizeof(int)); - tbinfo->attstorage = (char *) pg_malloc(numatts * sizeof(char)); - tbinfo->typstorage = (char *) pg_malloc(numatts * sizeof(char)); - tbinfo->attidentity = (char *) pg_malloc(numatts * sizeof(char)); - tbinfo->attgenerated = (char *) pg_malloc(numatts * sizeof(char)); - tbinfo->attisdropped = (bool *) pg_malloc(numatts * sizeof(bool)); - tbinfo->attlen = (int *) pg_malloc(numatts * sizeof(int)); - tbinfo->attalign = (char *) pg_malloc(numatts * sizeof(char)); - tbinfo->attislocal = (bool *) pg_malloc(numatts * sizeof(bool)); - tbinfo->attoptions = (char **) pg_malloc(numatts * sizeof(char *)); - tbinfo->attcollation = (Oid *) pg_malloc(numatts * sizeof(Oid)); - tbinfo->attfdwoptions = (char **) pg_malloc(numatts * sizeof(char *)); - tbinfo->attmissingval = (char **) pg_malloc(numatts * sizeof(char *)); - tbinfo->notnull = (bool *) pg_malloc(numatts * sizeof(bool)); - tbinfo->inhNotNull = (bool *) pg_malloc(numatts * sizeof(bool)); - tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(numatts * sizeof(AttrDefInfo *)); - tbinfo->attencoding = (char **) pg_malloc(numatts * sizeof(char*)); + i_attencoding = PQfnumber(res, "attencoding"); + + tbinfo->numatts = ntups; + tbinfo->attnames = (char **) pg_malloc(ntups * sizeof(char *)); + tbinfo->atttypnames = (char **) pg_malloc(ntups * sizeof(char *)); + tbinfo->atttypmod = (int *) pg_malloc(ntups * sizeof(int)); + tbinfo->attstattarget = (int *) pg_malloc(ntups * sizeof(int)); + tbinfo->attstorage = (char *) pg_malloc(ntups * sizeof(char)); + tbinfo->typstorage = (char *) pg_malloc(ntups * sizeof(char)); + tbinfo->attidentity = (char *) pg_malloc(ntups * sizeof(char)); + tbinfo->attgenerated = (char *) pg_malloc(ntups * sizeof(char)); + tbinfo->attisdropped = (bool *) pg_malloc(ntups * sizeof(bool)); + tbinfo->attlen = (int *) pg_malloc(ntups * sizeof(int)); + tbinfo->attalign = (char *) pg_malloc(ntups * sizeof(char)); + tbinfo->attislocal = (bool *) pg_malloc(ntups * sizeof(bool)); + tbinfo->attoptions = (char **) pg_malloc(ntups * sizeof(char *)); + tbinfo->attcollation = (Oid *) pg_malloc(ntups * sizeof(Oid)); + tbinfo->attcompression = (char *) pg_malloc(ntups * sizeof(char)); + tbinfo->attfdwoptions = (char **) pg_malloc(ntups * sizeof(char *)); + tbinfo->attmissingval = (char **) pg_malloc(ntups * sizeof(char *)); + tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool)); + tbinfo->inhNotNull = (bool *) pg_malloc(ntups * sizeof(bool)); + tbinfo->attencoding = (char **) pg_malloc(ntups * sizeof(char *)); + tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *)); hasdefaults = false; - for (int j = 0; j < numatts; j++, r++) + for (int j = 0; j < ntups; j++) { - if (j + 1 != atoi(PQgetvalue(res, r, i_attnum))) + if (j + 1 != atoi(PQgetvalue(res, j, PQfnumber(res, "attnum")))) fatal("invalid column numbering in table \"%s\"", tbinfo->dobj.name); - tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, r, i_attname)); - tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, r, i_atttypname)); - tbinfo->atttypmod[j] = atoi(PQgetvalue(res, r, i_atttypmod)); - tbinfo->attstattarget[j] = atoi(PQgetvalue(res, r, i_attstattarget)); - tbinfo->attstorage[j] = *(PQgetvalue(res, r, i_attstorage)); - tbinfo->typstorage[j] = *(PQgetvalue(res, r, i_typstorage)); - tbinfo->attidentity[j] = *(PQgetvalue(res, r, i_attidentity)); - tbinfo->attgenerated[j] = *(PQgetvalue(res, r, i_attgenerated)); + tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attname"))); + tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "atttypname"))); + tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, PQfnumber(res, "atttypmod"))); + tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, PQfnumber(res, "attstattarget"))); + tbinfo->attstorage[j] = *(PQgetvalue(res, j, PQfnumber(res, "attstorage"))); + tbinfo->typstorage[j] = *(PQgetvalue(res, j, PQfnumber(res, "typstorage"))); + tbinfo->attidentity[j] = *(PQgetvalue(res, j, PQfnumber(res, "attidentity"))); + tbinfo->attgenerated[j] = *(PQgetvalue(res, j, PQfnumber(res, "attgenerated"))); tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS); - tbinfo->attisdropped[j] = (PQgetvalue(res, r, i_attisdropped)[0] == 't'); - tbinfo->attlen[j] = atoi(PQgetvalue(res, r, i_attlen)); - tbinfo->attalign[j] = *(PQgetvalue(res, r, i_attalign)); - tbinfo->attislocal[j] = (PQgetvalue(res, r, i_attislocal)[0] == 't'); - tbinfo->notnull[j] = (PQgetvalue(res, r, i_attnotnull)[0] == 't'); - tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, r, i_attoptions)); - tbinfo->attcollation[j] = atooid(PQgetvalue(res, r, i_attcollation)); - tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, r, i_attfdwoptions)); - tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, r, i_attmissingval)); + tbinfo->attisdropped[j] = (PQgetvalue(res, j, PQfnumber(res, "attisdropped"))[0] == 't'); + tbinfo->attlen[j] = atoi(PQgetvalue(res, j, PQfnumber(res, "attlen"))); + tbinfo->attalign[j] = *(PQgetvalue(res, j, PQfnumber(res, "attalign"))); + tbinfo->attislocal[j] = (PQgetvalue(res, j, PQfnumber(res, "attislocal"))[0] == 't'); + tbinfo->notnull[j] = (PQgetvalue(res, j, PQfnumber(res, "attnotnull"))[0] == 't'); + tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attoptions"))); + tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, PQfnumber(res, "attcollation"))); + tbinfo->attcompression[j] = *(PQgetvalue(res, j, PQfnumber(res, "attcompression"))); + tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attfdwoptions"))); + tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, j, PQfnumber(res, "attmissingval"))); tbinfo->attrdefs[j] = NULL; /* fix below */ - if (PQgetvalue(res, r, i_atthasdef)[0] == 't') + if (PQgetvalue(res, j, PQfnumber(res, "atthasdef"))[0] == 't') hasdefaults = true; /* these flags will be set in flagInhAttrs() */ tbinfo->inhNotNull[j] = false; /* column storage attributes */ - if (!PQgetisnull(res, r, PQfnumber(res, "attencoding"))) - tbinfo->attencoding[j] = pg_strdup(PQgetvalue(res, r, PQfnumber(res, "attencoding"))); + if (!PQgetisnull(res, j, i_attencoding)) + tbinfo->attencoding[j] = pg_strdup(PQgetvalue(res, j, i_attencoding)); else tbinfo->attencoding[j] = NULL; } - if (hasdefaults) + PQclear(res); + + /* + * Get info about column defaults. This is skipped for a data-only + * dump, as it is only needed for table schemas. + */ + if (!dopt->dataOnly && hasdefaults) { - /* Collect OIDs of interesting tables that have defaults */ - if (tbloids->len > 1) /* do we have more than the '{'? */ - appendPQExpBufferChar(tbloids, ','); - appendPQExpBuffer(tbloids, "%u", tbinfo->dobj.catId.oid); - } - } + AttrDefInfo *attrdefs; + int numDefaults; - PQclear(res); + pg_log_info("finding default expressions of table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); - /* - * Now get info about column defaults. This is skipped for a data-only - * dump, as it is only needed for table schemas. - */ - if (!dopt->dataOnly && tbloids->len > 1) - { - AttrDefInfo *attrdefs; - int numDefaults; - TableInfo *tbinfo = NULL; + printfPQExpBuffer(q, "SELECT tableoid, oid, adnum, " + "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc " + "FROM pg_catalog.pg_attrdef " + "WHERE adrelid = '%u'::pg_catalog.oid", + tbinfo->dobj.catId.oid); - pg_log_info("finding table default expressions"); + res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK); - appendPQExpBufferChar(tbloids, '}'); + numDefaults = PQntuples(res); + attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo)); - printfPQExpBuffer(q, "SELECT a.tableoid, a.oid, adrelid, adnum, " - "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc\n" - "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n" - "JOIN pg_catalog.pg_attrdef a ON (src.tbloid = a.adrelid)\n" - "ORDER BY a.adrelid, a.adnum", - tbloids->data); + for (int j = 0; j < numDefaults; j++) + { + int adnum; - res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK); + adnum = atoi(PQgetvalue(res, j, 2)); - numDefaults = PQntuples(res); - attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo)); + if (adnum <= 0 || adnum > ntups) + fatal("invalid adnum value %d for table \"%s\"", + adnum, tbinfo->dobj.name); - curtblindx = -1; - for (int j = 0; j < numDefaults; j++) - { - Oid adtableoid = atooid(PQgetvalue(res, j, 0)); - Oid adoid = atooid(PQgetvalue(res, j, 1)); - Oid adrelid = atooid(PQgetvalue(res, j, 2)); - int adnum = atoi(PQgetvalue(res, j, 3)); - char *adsrc = PQgetvalue(res, j, 4); + /* + * dropped columns shouldn't have defaults, but just in case, + * ignore 'em + */ + if (tbinfo->attisdropped[adnum - 1]) + continue; - /* - * Locate the associated TableInfo; we rely on tblinfo[] being in - * OID order. - */ - if (tbinfo == NULL || tbinfo->dobj.catId.oid != adrelid) - { - while (++curtblindx < numTables) + attrdefs[j].dobj.objType = DO_ATTRDEF; + attrdefs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0)); + attrdefs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1)); + AssignDumpId(&attrdefs[j].dobj); + attrdefs[j].adtable = tbinfo; + attrdefs[j].adnum = adnum; + attrdefs[j].adef_expr = pg_strdup(PQgetvalue(res, j, 3)); + + attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name); + attrdefs[j].dobj.namespace = tbinfo->dobj.namespace; + + attrdefs[j].dobj.dump = tbinfo->dobj.dump; + + /* + * Figure out whether the default/generation expression should + * be dumped as part of the main CREATE TABLE (or similar) + * command or as a separate ALTER TABLE (or similar) command. + * The preference is to put it into the CREATE command, but in + * some cases that's not possible. + */ + if (tbinfo->attgenerated[adnum - 1]) { - tbinfo = &tblinfo[curtblindx]; - if (tbinfo->dobj.catId.oid == adrelid) - break; + /* + * Column generation expressions cannot be dumped + * separately, because there is no syntax for it. The + * !shouldPrintColumn case below will be tempted to set + * them to separate if they are attached to an inherited + * column without a local definition, but that would be + * wrong and unnecessary, because generation expressions + * are always inherited, so there is no need to set them + * again in child tables, and there is no syntax for it + * either. By setting separate to false here we prevent + * the "default" from being processed as its own dumpable + * object, and flagInhAttrs() will remove it from the + * table when it detects that it belongs to an inherited + * column. + */ + attrdefs[j].separate = false; + } + else if (tbinfo->relkind == RELKIND_VIEW) + { + /* + * Defaults on a VIEW must always be dumped as separate + * ALTER TABLE commands. + */ + attrdefs[j].separate = true; + } + else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1)) + { + /* column will be suppressed, print default separately */ + attrdefs[j].separate = true; + } + else + { + attrdefs[j].separate = false; } - if (curtblindx >= numTables) - fatal("unrecognized table OID %u", adrelid); - } - - if (adnum <= 0 || adnum > tbinfo->numatts) - fatal("invalid adnum value %d for table \"%s\"", - adnum, tbinfo->dobj.name); - /* - * dropped columns shouldn't have defaults, but just in case, - * ignore 'em - */ - if (tbinfo->attisdropped[adnum - 1]) - continue; + if (!attrdefs[j].separate) + { + /* + * Mark the default as needing to appear before the table, + * so that any dependencies it has must be emitted before + * the CREATE TABLE. If this is not possible, we'll + * change to "separate" mode while sorting dependencies. + */ + addObjectDependency(&tbinfo->dobj, + attrdefs[j].dobj.dumpId); + } - attrdefs[j].dobj.objType = DO_ATTRDEF; - attrdefs[j].dobj.catId.tableoid = adtableoid; - attrdefs[j].dobj.catId.oid = adoid; - AssignDumpId(&attrdefs[j].dobj); - attrdefs[j].adtable = tbinfo; - attrdefs[j].adnum = adnum; - attrdefs[j].adef_expr = pg_strdup(adsrc); + tbinfo->attrdefs[adnum - 1] = &attrdefs[j]; + } + PQclear(res); + } - attrdefs[j].dobj.name = pg_strdup(tbinfo->dobj.name); - attrdefs[j].dobj.namespace = tbinfo->dobj.namespace; + /* + * Get info about table CHECK constraints. This is skipped for a + * data-only dump, as it is only needed for table schemas. + */ + if (tbinfo->ncheck > 0 && !dopt->dataOnly) + { + ConstraintInfo *constrs; + int numConstrs; - attrdefs[j].dobj.dump = tbinfo->dobj.dump; + pg_log_info("finding check constraints for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); - /* - * Figure out whether the default/generation expression should be - * dumped as part of the main CREATE TABLE (or similar) command or - * as a separate ALTER TABLE (or similar) command. The preference - * is to put it into the CREATE command, but in some cases that's - * not possible. - */ - if (tbinfo->attgenerated[adnum - 1]) + resetPQExpBuffer(q); + if (fout->remoteVersion >= 90200) { /* - * Column generation expressions cannot be dumped separately, - * because there is no syntax for it. The !shouldPrintColumn - * case below will be tempted to set them to separate if they - * are attached to an inherited column without a local - * definition, but that would be wrong and unnecessary, - * because generation expressions are always inherited, so - * there is no need to set them again in child tables, and - * there is no syntax for it either. By setting separate to - * false here we prevent the "default" from being processed as - * its own dumpable object, and flagInhAttrs() will remove it - * from the table when it detects that it belongs to an - * inherited column. + * convalidated is new in 9.2 (actually, it is there in 9.1, + * but it wasn't ever false for check constraints until 9.2). */ - attrdefs[j].separate = false; + appendPQExpBuffer(q, "SELECT tableoid, oid, conname, " + "pg_catalog.pg_get_constraintdef(oid) AS consrc, " + "conislocal, convalidated " + "FROM pg_catalog.pg_constraint " + "WHERE conrelid = '%u'::pg_catalog.oid " + " AND contype = 'c' " + "ORDER BY conname", + tbinfo->dobj.catId.oid); } - else if (tbinfo->relkind == RELKIND_VIEW) + else if (fout->remoteVersion >= 80400) { - /* - * Defaults on a VIEW must always be dumped as separate ALTER - * TABLE commands. - */ - attrdefs[j].separate = true; - } - else if (!shouldPrintColumn(dopt, tbinfo, adnum - 1)) - { - /* column will be suppressed, print default separately */ - attrdefs[j].separate = true; + /* conislocal is new in 8.4 */ + appendPQExpBuffer(q, "SELECT tableoid, oid, conname, " + "pg_catalog.pg_get_constraintdef(oid) AS consrc, " + "conislocal, true AS convalidated " + "FROM pg_catalog.pg_constraint " + "WHERE conrelid = '%u'::pg_catalog.oid " + " AND contype = 'c' " + "ORDER BY conname", + tbinfo->dobj.catId.oid); } else { - attrdefs[j].separate = false; - } - - if (!attrdefs[j].separate) - { - /* - * Mark the default as needing to appear before the table, so - * that any dependencies it has must be emitted before the - * CREATE TABLE. If this is not possible, we'll change to - * "separate" mode while sorting dependencies. - */ - addObjectDependency(&tbinfo->dobj, - attrdefs[j].dobj.dumpId); + appendPQExpBuffer(q, "SELECT tableoid, oid, conname, " + "pg_catalog.pg_get_constraintdef(oid) AS consrc, " + "true AS conislocal, true AS convalidated " + "FROM pg_catalog.pg_constraint " + "WHERE conrelid = '%u'::pg_catalog.oid " + " AND contype = 'c' " + "ORDER BY conname", + tbinfo->dobj.catId.oid); } - tbinfo->attrdefs[adnum - 1] = &attrdefs[j]; - } - - PQclear(res); - } + res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK); - /* - * Get info about table CHECK constraints. This is skipped for a - * data-only dump, as it is only needed for table schemas. - */ - if (!dopt->dataOnly && checkoids->len > 2) - { - ConstraintInfo *constrs; - int numConstrs; - int i_tableoid; - int i_oid; - int i_conrelid; - int i_conname; - int i_consrc; - int i_conislocal; - int i_convalidated; - - pg_log_info("finding table check constraints"); - - resetPQExpBuffer(q); - appendPQExpBufferStr(q, - "SELECT c.tableoid, c.oid, conrelid, conname, " - "pg_catalog.pg_get_constraintdef(c.oid) AS consrc, "); - if (fout->remoteVersion >= 90200) - { - /* - * convalidated is new in 9.2 (actually, it is there in 9.1, but - * it wasn't ever false for check constraints until 9.2). - */ - appendPQExpBufferStr(q, - "conislocal, convalidated "); - } - else if (fout->remoteVersion >= 80400) - { - /* conislocal is new in 8.4 */ - appendPQExpBufferStr(q, - "conislocal, true AS convalidated "); - } - else - { - appendPQExpBufferStr(q, - "true AS conislocal, true AS convalidated "); - } - appendPQExpBuffer(q, - "FROM unnest('%s'::pg_catalog.oid[]) AS src(tbloid)\n" - "JOIN pg_catalog.pg_constraint c ON (src.tbloid = c.conrelid)\n" - "WHERE contype = 'c' " - "ORDER BY c.conrelid, c.conname", - checkoids->data); - - res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK); - - numConstrs = PQntuples(res); - constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo)); - - i_tableoid = PQfnumber(res, "tableoid"); - i_oid = PQfnumber(res, "oid"); - i_conrelid = PQfnumber(res, "conrelid"); - i_conname = PQfnumber(res, "conname"); - i_consrc = PQfnumber(res, "consrc"); - i_conislocal = PQfnumber(res, "conislocal"); - i_convalidated = PQfnumber(res, "convalidated"); - - /* As above, this loop iterates once per table, not once per row */ - curtblindx = -1; - for (int j = 0; j < numConstrs;) - { - Oid conrelid = atooid(PQgetvalue(res, j, i_conrelid)); - TableInfo *tbinfo = NULL; - int numcons; - - /* Count rows for this table */ - for (numcons = 1; numcons < numConstrs - j; numcons++) - if (atooid(PQgetvalue(res, j + numcons, i_conrelid)) != conrelid) - break; - - /* - * Locate the associated TableInfo; we rely on tblinfo[] being in - * OID order. - */ - while (++curtblindx < numTables) - { - tbinfo = &tblinfo[curtblindx]; - if (tbinfo->dobj.catId.oid == conrelid) - break; - } - if (curtblindx >= numTables) - fatal("unrecognized table OID %u", conrelid); - - if (numcons != tbinfo->ncheck) + numConstrs = PQntuples(res); + if (numConstrs != tbinfo->ncheck) { pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d", "expected %d check constraints on table \"%s\" but found %d", tbinfo->ncheck), - tbinfo->ncheck, tbinfo->dobj.name, numcons); + tbinfo->ncheck, tbinfo->dobj.name, numConstrs); pg_log_error("(The system catalogs might be corrupted.)"); exit_nicely(1); } - tbinfo->checkexprs = constrs + j; + constrs = (ConstraintInfo *) pg_malloc(numConstrs * sizeof(ConstraintInfo)); + tbinfo->checkexprs = constrs; - for (int c = 0; c < numcons; c++, j++) + for (int j = 0; j < numConstrs; j++) { - bool validated = PQgetvalue(res, j, i_convalidated)[0] == 't'; + bool validated = PQgetvalue(res, j, 5)[0] == 't'; constrs[j].dobj.objType = DO_CONSTRAINT; - constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid)); - constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, i_oid)); + constrs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0)); + constrs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1)); AssignDumpId(&constrs[j].dobj); - constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, i_conname)); + constrs[j].dobj.name = pg_strdup(PQgetvalue(res, j, 2)); constrs[j].dobj.namespace = tbinfo->dobj.namespace; constrs[j].contable = tbinfo; constrs[j].condomain = NULL; constrs[j].contype = 'c'; - constrs[j].condef = pg_strdup(PQgetvalue(res, j, i_consrc)); + constrs[j].condef = pg_strdup(PQgetvalue(res, j, 3)); constrs[j].confrelid = InvalidOid; constrs[j].conindex = 0; constrs[j].condeferrable = false; constrs[j].condeferred = false; - constrs[j].conislocal = (PQgetvalue(res, j, i_conislocal)[0] == 't'); + constrs[j].conislocal = (PQgetvalue(res, j, 4)[0] == 't'); /* * An unvalidated constraint needs to be dumped separately, so @@ -9204,33 +9285,14 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) * constraint must be split out from the table definition. */ } + PQclear(res); } - - PQclear(res); } destroyPQExpBuffer(q); - destroyPQExpBuffer(tbloids); - destroyPQExpBuffer(checkoids); } -/* - * Test whether a column should be printed as part of table's CREATE TABLE. - * Column number is zero-based. - * - * Normally this is always true, but it's false for dropped columns, as well - * as those that were inherited without any local definition. (If we print - * such a column it will mistakenly get pg_attribute.attislocal set to true.) - * For partitions, it's always true, because we want the partitions to be - * created independently and ATTACH PARTITION used afterwards. - * - * In binary_upgrade mode, we must print all columns and fix the attislocal/ - * attisdropped state later, so as to keep control of the physical column - * order. - * - * This function exists because there are scattered nonobvious places that - * must be kept in sync with this decision. - */ + bool shouldPrintColumn(const DumpOptions *dopt, const TableInfo *tbinfo, int colno) { @@ -10914,7 +10976,9 @@ dumpEnumType(Archive *fout, const TypeInfo *tyinfo) appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname); if (dopt->binary_upgrade) - binary_upgrade_set_type_oids_by_type_oid(fout, q, tyinfo, false); + binary_upgrade_set_type_oids_by_type_oid(fout, q, + tyinfo->dobj.catId.oid, + false, false); appendPQExpBuffer(q, "CREATE TYPE %s AS ENUM (", qualtypname); @@ -11024,6 +11088,13 @@ dumpRangeType(Archive *fout, const TypeInfo *tyinfo) appendPQExpBufferStr(query, "SELECT "); + if (fout->remoteVersion >= 140000) + appendPQExpBufferStr(query, + "pg_catalog.format_type(rngmultitypid, NULL) AS rngmultitype, "); + else + appendPQExpBufferStr(query, + "NULL AS rngmultitype, "); + appendPQExpBufferStr(query, "pg_catalog.format_type(rngsubtype, NULL) AS rngsubtype, " "opc.opcname AS opcname, " @@ -11060,8 +11131,8 @@ dumpRangeType(Archive *fout, const TypeInfo *tyinfo) if (dopt->binary_upgrade) binary_upgrade_set_type_oids_by_type_oid(fout, q, - tyinfo, - false); + tyinfo->dobj.catId.oid, + false, true); appendPQExpBuffer(q, "CREATE TYPE %s AS RANGE (", qualtypname); @@ -11069,6 +11140,10 @@ dumpRangeType(Archive *fout, const TypeInfo *tyinfo) appendPQExpBuffer(q, "\n subtype = %s", PQgetvalue(res, 0, PQfnumber(res, "rngsubtype"))); + if (!PQgetisnull(res, 0, PQfnumber(res, "rngmultitype"))) + appendPQExpBuffer(q, ",\n multirange_type_name = %s", + PQgetvalue(res, 0, PQfnumber(res, "rngmultitype"))); + /* print subtype_opclass only if not default for subtype */ if (PQgetvalue(res, 0, PQfnumber(res, "opcdefault"))[0] != 't') { @@ -11164,9 +11239,9 @@ dumpUndefinedType(Archive *fout, const TypeInfo *tyinfo) appendPQExpBuffer(delq, "DROP TYPE %s;\n", qualtypname); if (dopt->binary_upgrade) - binary_upgrade_set_type_oids_by_type_oid(fout, - q, tyinfo, - false); + binary_upgrade_set_type_oids_by_type_oid(fout, q, + tyinfo->dobj.catId.oid, + false, false); appendPQExpBuffer(q, "CREATE TYPE %s;\n", qualtypname); @@ -11231,11 +11306,13 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo) char *typmodin; char *typmodout; char *typanalyze; + char *typsubscript; Oid typreceiveoid; Oid typsendoid; Oid typmodinoid; Oid typmodoutoid; Oid typanalyzeoid; + Oid typsubscriptoid; char *typcategory; char *typispreferred; char *typdelim; @@ -11275,6 +11352,14 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo) else appendPQExpBufferStr(query, "false AS typcollatable, "); + if (fout->remoteVersion >= 140000) + appendPQExpBufferStr(query, + "typsubscript, " + "typsubscript::pg_catalog.oid AS typsubscriptoid, "); + else + appendPQExpBufferStr(query, + "'-' AS typsubscript, 0 AS typsubscriptoid, "); + /* Before 8.4, pg_get_expr does not allow 0 for its second arg */ if (fout->remoteVersion >= 80400) appendPQExpBufferStr(query, @@ -11290,7 +11375,7 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo) fout->is_prepared[PREPQUERY_DUMPBASETYPE] = true; } - + /* Fetch type-specific details */ printfPQExpBuffer(query, "EXECUTE dumpBaseType('%u')", tyinfo->dobj.catId.oid); @@ -11305,11 +11390,13 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo) typmodin = PQgetvalue(res, 0, PQfnumber(res, "typmodin")); typmodout = PQgetvalue(res, 0, PQfnumber(res, "typmodout")); typanalyze = PQgetvalue(res, 0, PQfnumber(res, "typanalyze")); + typsubscript = PQgetvalue(res, 0, PQfnumber(res, "typsubscript")); typreceiveoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typreceiveoid"))); typsendoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsendoid"))); typmodinoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodinoid"))); typmodoutoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typmodoutoid"))); typanalyzeoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typanalyzeoid"))); + typsubscriptoid = atooid(PQgetvalue(res, 0, PQfnumber(res, "typsubscriptoid"))); typcategory = PQgetvalue(res, 0, PQfnumber(res, "typcategory")); typispreferred = PQgetvalue(res, 0, PQfnumber(res, "typispreferred")); typdelim = PQgetvalue(res, 0, PQfnumber(res, "typdelim")); @@ -11343,8 +11430,8 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo) */ if (dopt->binary_upgrade) binary_upgrade_set_type_oids_by_type_oid(fout, q, - tyinfo, - false); + tyinfo->dobj.catId.oid, + false, false); appendPQExpBuffer(q, "CREATE TYPE %s (\n" @@ -11378,6 +11465,9 @@ dumpBaseType(Archive *fout, const TypeInfo *tyinfo) appendPQExpBufferStr(q, typdefault); } + if (OidIsValid(typsubscriptoid)) + appendPQExpBuffer(q, ",\n SUBSCRIPT = %s", typsubscript); + if (OidIsValid(tyinfo->typelem)) { char *elemType; @@ -11570,8 +11660,9 @@ dumpDomain(Archive *fout, const TypeInfo *tyinfo) if (dopt->binary_upgrade) binary_upgrade_set_type_oids_by_type_oid(fout, q, - tyinfo, - true); /* force array type */ + tyinfo->dobj.catId.oid, + true, /* force array type */ + false); /* force multirange type */ qtypname = pg_strdup(fmtId(tyinfo->dobj.name)); qualtypname = pg_strdup(fmtQualifiedDumpable(tyinfo)); @@ -11769,8 +11860,8 @@ dumpCompositeType(Archive *fout, const TypeInfo *tyinfo) if (dopt->binary_upgrade) { binary_upgrade_set_type_oids_by_type_oid(fout, q, - tyinfo, - false); + tyinfo->dobj.catId.oid, + false, false); binary_upgrade_set_pg_class_oids(fout, q, tyinfo->typrelid, false); } @@ -12044,8 +12135,8 @@ dumpShellType(Archive *fout, const ShellTypeInfo *stinfo) if (dopt->binary_upgrade) binary_upgrade_set_type_oids_by_type_oid(fout, q, - stinfo->baseType, - false); + stinfo->baseType->dobj.catId.oid, + false, false); appendPQExpBuffer(q, "CREATE TYPE %s;\n", fmtQualifiedDumpable(stinfo)); @@ -12334,6 +12425,7 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) char *proretset; char *prosrc; char *probin; + char *prosqlbody; char *funcargs; char *funciargs; char *funcresult; @@ -12432,10 +12524,17 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) if (fout->remoteVersion >= 120000) appendPQExpBuffer(query, - "prosupport\n"); + "prosupport,\n"); else appendPQExpBuffer(query, - "'-' AS prosupport\n"); + "'-' AS prosupport,\n"); + + if (fout->remoteVersion >= 140000) + appendPQExpBuffer(query, + "pg_get_function_sqlbody(p.oid) AS prosqlbody\n"); + else + appendPQExpBuffer(query, + "NULL AS prosqlbody\n"); appendPQExpBuffer(query, "FROM pg_catalog.pg_proc p, pg_catalog.pg_language l\n" @@ -12448,6 +12547,7 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) } + /* Fetch function-specific details */ printfPQExpBuffer(query, "EXECUTE dumpFunc('%u')", finfo->dobj.catId.oid); @@ -12461,6 +12561,32 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs")); funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult")); + if (PQgetisnull(res, 0, PQfnumber(res, "prosqlbody"))) + { + prosrc = PQgetvalue(res, 0, PQfnumber(res, "prosrc")); + probin = PQgetvalue(res, 0, PQfnumber(res, "probin")); + prosqlbody = NULL; + } + else + { + prosrc = NULL; + probin = NULL; + prosqlbody = PQgetvalue(res, 0, PQfnumber(res, "prosqlbody")); + } + if (fout->remoteVersion >= 80400) + { + funcargs = PQgetvalue(res, 0, PQfnumber(res, "funcargs")); + funciargs = PQgetvalue(res, 0, PQfnumber(res, "funciargs")); + funcresult = PQgetvalue(res, 0, PQfnumber(res, "funcresult")); + allargtypes = argmodes = argnames = NULL; + } + else + { + allargtypes = PQgetvalue(res, 0, PQfnumber(res, "allargtypes")); + argmodes = PQgetvalue(res, 0, PQfnumber(res, "argmodes")); + argnames = PQgetvalue(res, 0, PQfnumber(res, "argnames")); + funcargs = funciargs = funcresult = NULL; + } if (PQfnumber(res, "protrftypes") != -1) protrftypes = PQgetvalue(res, 0, PQfnumber(res, "protrftypes")); else @@ -12486,7 +12612,11 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) * versions would set it to "-". There are no known cases in which prosrc * is unused, so the tests below for "-" are probably useless. */ - if (probin[0] != '\0' && strcmp(probin, "-") != 0) + if (prosqlbody) + { + appendPQExpBufferStr(asPart, prosqlbody); + } + else if (probin[0] != '\0' && strcmp(probin, "-") != 0) { appendPQExpBufferStr(asPart, "AS "); appendStringLiteralAH(asPart, probin, fout); @@ -12527,13 +12657,12 @@ dumpFunc(Archive *fout, const FuncInfo *finfo) if (proconfig && *proconfig) { if (!parsePGArray(proconfig, &configitems, &nconfigitems)) - { - pg_log_warning("could not parse proconfig array"); - if (configitems) - free(configitems); - configitems = NULL; - nconfigitems = 0; - } + fatal("could not parse proconfig array"); + } + else + { + configitems = NULL; + nconfigitems = 0; } funcsig_tag = format_function_signature(fout, finfo, false); @@ -13169,6 +13298,11 @@ dumpOpr(Archive *fout, const OprInfo *oprinfo) oprcanmerge = PQgetvalue(res, 0, i_oprcanmerge); oprcanhash = PQgetvalue(res, 0, i_oprcanhash); + /* In PG14 upwards postfix operator support does not exist anymore. */ + if (strcmp(oprkind, "r") == 0) + pg_log_warning("postfix operators are not supported anymore (operator \"%s\")", + oprcode); + oprregproc = convertRegProcReference(oprcode); if (oprregproc) { @@ -13181,7 +13315,8 @@ dumpOpr(Archive *fout, const OprInfo *oprinfo) /* * right unary means there's a left arg and left unary means there's a - * right arg + * right arg. (Although the "r" case is dead code for PG14 and later, + * continue to support it in case we're dumping from an old server.) */ if (strcmp(oprkind, "r") == 0 || strcmp(oprkind, "b") == 0) @@ -14428,7 +14563,6 @@ dumpAgg(Archive *fout, const AggInfo *agginfo) "'-' AS aggserialfn,\n" "'-' AS aggdeserialfn,\n" "'u' AS proparallel,\n"); - if (fout->remoteVersion >= 110000) appendPQExpBufferStr(query, "aggfinalmodify,\n" @@ -15954,8 +16088,8 @@ findSecLabels(Archive *fout, Oid classoid, Oid objoid, SecLabelItem **items) * * The table is sorted by classoid/objid/objsubid for speed in lookup. */ -static void -collectSecLabels(Archive *fout) +static int +collectSecLabels(Archive *fout, SecLabelItem **items) { PGresult *res; PQExpBuffer query; @@ -16600,6 +16734,9 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo) /* We had better have loaded per-column details about this table */ Assert(tbinfo->interesting); + /* We had better have loaded per-column details about this table */ + Assert(tbinfo->interesting); + qrelname = pg_strdup(fmtId(tbinfo->dobj.name)); qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo)); @@ -17457,6 +17594,33 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo) storage); } + /* + * Dump per-column compression, if it's been set. + */ + if (!dopt->no_toast_compression) + { + const char *cmname; + + switch (tbinfo->attcompression[j]) + { + case 'p': + cmname = "pglz"; + break; + case 'l': + cmname = "lz4"; + break; + default: + cmname = NULL; + break; + } + + if (cmname != NULL) + appendPQExpBuffer(q, "ALTER %sTABLE ONLY %s ALTER COLUMN %s SET COMPRESSION %s;\n", + foreign, qualrelname, + fmtId(tbinfo->attnames[j]), + cmname); + } + /* * Dump per-column attributes. */ @@ -17478,7 +17642,7 @@ dumpTableSchema(Archive *fout, const TableInfo *tbinfo) qualrelname, fmtId(tbinfo->attnames[j]), tbinfo->attfdwoptions[j]); - } + } /* end loop over columns */ if (ftoptions) free(ftoptions); @@ -17760,8 +17924,8 @@ dumpIndex(Archive *fout, const IndxInfo *indxinfo) char *indstatvals = indxinfo->indstatvals; char **indstatcolsarray = NULL; char **indstatvalsarray = NULL; - int nstatcols; - int nstatvals; + int nstatcols = 0; + int nstatvals = 0; if (dopt->binary_upgrade) binary_upgrade_set_pg_class_oids(fout, q, indxinfo->dobj.catId.oid, true); @@ -17789,12 +17953,17 @@ dumpIndex(Archive *fout, const IndxInfo *indxinfo) * If the index has any statistics on some of its columns, generate * the associated ALTER INDEX queries. */ - if (parsePGArray(indstatcols, &indstatcolsarray, &nstatcols) && - parsePGArray(indstatvals, &indstatvalsarray, &nstatvals) && - nstatcols == nstatvals) + if (strlen(indstatcols) != 0 || strlen(indstatvals) != 0) { int j; + if (!parsePGArray(indstatcols, &indstatcolsarray, &nstatcols)) + fatal("could not parse index statistic columns"); + if (!parsePGArray(indstatvals, &indstatvalsarray, &nstatvals)) + fatal("could not parse index statistic values"); + if (nstatcols != nstatvals) + fatal("mismatched number of columns and values for index statistics"); + for (j = 0; j < nstatcols; j++) { appendPQExpBuffer(q, "ALTER INDEX %s ", qqindxname); @@ -19186,7 +19355,8 @@ processExtensionTables(Archive *fout, ExtensionInfo extinfo[], * Note that we create TableDataInfo objects even in schemaOnly mode, ie, * user data in a configuration table is treated like schema data. This * seems appropriate since system data in a config table would get - * reloaded by CREATE EXTENSION. + * reloaded by CREATE EXTENSION. If the extension is not listed in the + * list of extensions to be included, none of its data is dumped. */ for (i = 0; i < numExtensions; i++) { @@ -19195,15 +19365,29 @@ processExtensionTables(Archive *fout, ExtensionInfo extinfo[], char *extcondition = curext->extcondition; char **extconfigarray = NULL; char **extconditionarray = NULL; - int nconfigitems; - int nconditionitems; + int nconfigitems = 0; + int nconditionitems = 0; + + /* + * Check if this extension is listed as to include in the dump. If + * not, any table data associated with it is discarded. + */ + if (extension_include_oids.head != NULL && + !simple_oid_list_member(&extension_include_oids, + curext->dobj.catId.oid)) + continue; - if (parsePGArray(extconfig, &extconfigarray, &nconfigitems) && - parsePGArray(extcondition, &extconditionarray, &nconditionitems) && - nconfigitems == nconditionitems) + if (strlen(extconfig) != 0 || strlen(extcondition) != 0) { int j; + if (!parsePGArray(extconfig, &extconfigarray, &nconfigitems)) + fatal("could not parse extension configuration array"); + if (!parsePGArray(extcondition, &extconditionarray, &nconditionitems)) + fatal("could not parse extension condition array"); + if (nconfigitems != nconditionitems) + fatal("mismatched number of configurations and conditions for extension"); + for (j = 0; j < nconfigitems; j++) { TableInfo *configtbl; diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index a912e27ac743..8bbe87c50965 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -5,7 +5,7 @@ * * Portions Copyright (c) 2005-2010, Greenplum inc * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/pg_dump.h @@ -212,6 +212,7 @@ typedef struct _typeInfo char typrelkind; /* 'r', 'v', 'c', etc */ char typtype; /* 'b', 'c', etc */ bool isArray; /* true if auto-generated array type */ + bool isMultirange; /* true if auto-generated multirange type */ bool isDefined; /* true if typisdefined */ /* If needed, we'll create a "shell type" entry for it; link that here: */ struct _shellTypeInfo *shellType; /* shell-type entry, or NULL */ @@ -366,6 +367,7 @@ typedef struct _tableInfo bool *attislocal; /* true if attr has local definition */ char **attoptions; /* per-attribute options */ Oid *attcollation; /* per-attribute collation selection */ + char *attcompression; /* per-attribute compression method */ char **attfdwoptions; /* per-attribute fdw options */ char **attmissingval; /* per attribute missing value */ bool *notnull; /* NOT NULL constraints on attributes */ @@ -452,7 +454,7 @@ typedef struct _indxInfo * contains both key and nonkey attributes */ bool indisclustered; bool indisreplident; - Oid parentidx; /* if partitioned, parent index OID */ + Oid parentidx; /* if a partition, parent index OID */ SimplePtrList partattaches; /* if partitioned, partition attach objects */ /* if there is an associated constraint object, its dumpId: */ @@ -704,6 +706,7 @@ typedef struct _SubscriptionInfo char *subconninfo; char *subslotname; char *subbinary; + char *substream; char *subsynccommit; char *subpublications; } SubscriptionInfo; diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c index 7d23b56b6285..acc87499485e 100644 --- a/src/bin/pg_dump/pg_dump_sort.c +++ b/src/bin/pg_dump/pg_dump_sort.c @@ -4,7 +4,7 @@ * Sort the items of a dump into a safe order for dumping * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 4b4d8204c310..4fa4e2b0f592 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -4,7 +4,7 @@ * * Portions Copyright (c) 2006-2010, Greenplum inc. * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates. - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * pg_dumpall forces all pg_dump output to be text, since it also outputs @@ -23,6 +23,7 @@ #include "common/connect.h" #include "common/file_utils.h" #include "common/logging.h" +#include "common/string.h" #include "dumputils.h" #include "fe_utils/string_utils.h" #include "getopt_long.h" @@ -84,6 +85,7 @@ static int no_comments = 0; static int no_publications = 0; static int no_security_labels = 0; static int no_subscriptions = 0; +static int no_toast_compression = 0; static int no_unlogged_table_data = 0; static int no_role_passwords = 0; static int server_version; @@ -153,6 +155,7 @@ main(int argc, char *argv[]) {"no-security-labels", no_argument, &no_security_labels, 1}, {"no-subscriptions", no_argument, &no_subscriptions, 1}, {"no-sync", no_argument, NULL, 4}, + {"no-toast-compression", no_argument, &no_toast_compression, 1}, {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1}, {"on-conflict-do-nothing", no_argument, &on_conflict_do_nothing, 1}, {"rows-per-insert", required_argument, NULL, 7}, @@ -309,7 +312,7 @@ main(int argc, char *argv[]) case 'v': verbose = true; - pg_logging_set_level(PG_LOG_INFO); + pg_logging_increase_verbosity(); appendPQExpBufferStr(pgdumpopts, " -v"); break; @@ -478,6 +481,8 @@ main(int argc, char *argv[]) appendPQExpBufferStr(pgdumpopts, " --no-security-labels"); if (no_subscriptions) appendPQExpBufferStr(pgdumpopts, " --no-subscriptions"); + if (no_toast_compression) + appendPQExpBufferStr(pgdumpopts, " --no-toast-compression"); if (no_unlogged_table_data) appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data"); if (on_conflict_do_nothing) @@ -724,6 +729,7 @@ help(void) printf(_(" --no-subscriptions do not dump subscriptions\n")); printf(_(" --no-sync do not wait for changes to be written safely to disk\n")); printf(_(" --no-tablespaces do not dump tablespace assignments\n")); + printf(_(" --no-toast-compression do not dump TOAST compression methods\n")); printf(_(" --no-unlogged-table-data do not dump unlogged table data\n")); printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n")); printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n")); @@ -2031,14 +2037,10 @@ connectDatabase(const char *dbname, const char *connection_string, const char **keywords = NULL; const char **values = NULL; PQconninfoOption *conn_opts = NULL; - static bool have_password = false; - static char password[100]; + static char *password = NULL; - if (prompt_password == TRI_YES && !have_password) - { - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; - } + if (prompt_password == TRI_YES && !password) + password = simple_prompt("Password: ", false); /* * Start the connection. Loop until we have a password if requested by @@ -2118,7 +2120,7 @@ connectDatabase(const char *dbname, const char *connection_string, values[i] = pguser; i++; } - if (have_password) + if (password) { keywords[i] = "password"; values[i] = password; @@ -2145,12 +2147,11 @@ connectDatabase(const char *dbname, const char *connection_string, if (PQstatus(conn) == CONNECTION_BAD && PQconnectionNeedsPassword(conn) && - !have_password && + !password && prompt_password != TRI_NO) { PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; + password = simple_prompt("Password: ", false); new_pass = true; } } while (new_pass); @@ -2160,8 +2161,7 @@ connectDatabase(const char *dbname, const char *connection_string, { if (fail_on_error) { - pg_log_error("could not connect to database \"%s\": %s", - dbname, PQerrorMessage(conn)); + pg_log_error("%s", PQerrorMessage(conn)); exit_nicely(1); } else diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 4531c42656ab..b4c26f0dd08d 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -168,7 +168,7 @@ main(int argc, char **argv) opts->createDB = 1; break; case 'd': - opts->dbname = pg_strdup(optarg); + opts->cparams.dbname = pg_strdup(optarg); break; case 'e': opts->exit_on_error = true; @@ -182,7 +182,7 @@ main(int argc, char **argv) break; case 'h': if (strlen(optarg) != 0) - opts->pghost = pg_strdup(optarg); + opts->cparams.pghost = pg_strdup(optarg); break; case 'j': /* number of restore jobs */ @@ -211,7 +211,7 @@ main(int argc, char **argv) case 'p': if (strlen(optarg) != 0) - opts->pgport = pg_strdup(optarg); + opts->cparams.pgport = pg_strdup(optarg); break; case 'R': /* no-op, still accepted for backwards compatibility */ @@ -245,20 +245,20 @@ main(int argc, char **argv) break; case 'U': - opts->username = pg_strdup(optarg); + opts->cparams.username = pg_strdup(optarg); break; case 'v': /* verbose */ opts->verbose = 1; - pg_logging_set_level(PG_LOG_INFO); + pg_logging_increase_verbosity(); break; case 'w': - opts->promptPassword = TRI_NO; + opts->cparams.promptPassword = TRI_NO; break; case 'W': - opts->promptPassword = TRI_YES; + opts->cparams.promptPassword = TRI_YES; break; case 'x': /* skip ACL dump */ @@ -308,14 +308,14 @@ main(int argc, char **argv) } /* Complain if neither -f nor -d was specified (except if dumping TOC) */ - if (!opts->dbname && !opts->filename && !opts->tocSummary) + if (!opts->cparams.dbname && !opts->filename && !opts->tocSummary) { pg_log_error("one of -d/--dbname and -f/--file must be specified"); exit_nicely(1); } /* Should get at most one of -d and -f, else user is confused */ - if (opts->dbname) + if (opts->cparams.dbname) { if (opts->filename) { diff --git a/src/bin/pg_dump/po/cs.po b/src/bin/pg_dump/po/cs.po new file mode 100644 index 000000000000..ca7d2b84f15c --- /dev/null +++ b/src/bin/pg_dump/po/cs.po @@ -0,0 +1,2969 @@ +# Czech message translation file for pg_dump +# Copyright (C) 2012 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Tomas Vondra , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: pg_dump-cs (PostgreSQL 9.3)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:16+0000\n" +"PO-Revision-Date: 2020-11-01 01:00+0100\n" +"Last-Translator: Tomas Vondra \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.4.1\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "chyba " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "varování: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "nelze získat aktuální adresář: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "neplatný binární soubor\"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "nelze číst binární soubor \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "nelze najít soubor \"%s\" ke spuštění" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "nelze změnit adresář na \"%s\" : %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "nelze přečíst symbolický odkaz \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "volání pclose selhalo: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "nedostatek paměti" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek paměti\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nelze duplikovat null pointer (interní chyba)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "příkaz není spustitelný" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "příkaz nenalezen" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "potomek skončil s návratovým kódem %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "potomek byl ukončen vyjímkou 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "potomek byl ukončen signálem %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "potomek skončil s nerozponaným stavem %d" + +#: common.c:121 +#, c-format +msgid "reading extensions" +msgstr "čtu rozšíření" + +#: common.c:125 +#, c-format +msgid "identifying extension members" +msgstr "hledám položky rozšíření (extenze)" + +#: common.c:128 +#, c-format +msgid "reading schemas" +msgstr "čtu schémata" + +#: common.c:138 +#, c-format +msgid "reading user-defined tables" +msgstr "čtu uživatelem definované tabulky" + +#: common.c:145 +#, c-format +msgid "reading user-defined functions" +msgstr "čtu uživatelem definované funkce" + +#: common.c:150 +#, c-format +msgid "reading user-defined types" +msgstr "čtu uživatelem definované typy" + +#: common.c:155 +#, c-format +msgid "reading procedural languages" +msgstr "čtu procedurální jazyky" + +#: common.c:158 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "čtu uživatelem definované agregátní funkce" + +#: common.c:161 +#, c-format +msgid "reading user-defined operators" +msgstr "čtu uživatelem definované operátory" + +#: common.c:165 +#, c-format +msgid "reading user-defined access methods" +msgstr "čtu uživatelem definované přístupové metody" + +#: common.c:168 +#, c-format +msgid "reading user-defined operator classes" +msgstr "čtu uživatelem definované třídy operátorů" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator families" +msgstr "čtu uživatelem definované rodiny operátorů" + +#: common.c:174 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "čtu uživatelem definované fulltextové parsery" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search templates" +msgstr "čtu uživatelem definované fulltextové šablony" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "čtu uživatelem definované fulltextové slovníky" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "čtu uživatelské fulltextového konfigurace" + +#: common.c:186 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "čtu uživatelem definované foreign-data wrappery" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "čtu uživatelem definované foreign servery" + +#: common.c:192 +#, c-format +msgid "reading default privileges" +msgstr "čtu implicitní přístupová práva" + +#: common.c:195 +#, c-format +msgid "reading user-defined collations" +msgstr "čtu uživatelem definované collations" + +#: common.c:199 +#, c-format +msgid "reading user-defined conversions" +msgstr "čtu uživatelem definované konverze" + +#: common.c:202 +#, c-format +msgid "reading type casts" +msgstr "čtu přetypování" + +#: common.c:205 +#, c-format +msgid "reading transforms" +msgstr "čtu transformace" + +#: common.c:208 +#, c-format +msgid "reading table inheritance information" +msgstr "čtu informace dědičnosti tabulky" + +#: common.c:211 +#, c-format +msgid "reading event triggers" +msgstr "čtu event triggery" + +#: common.c:215 +#, c-format +msgid "finding extension tables" +msgstr "hledám tabulky pro rozšíření" + +#: common.c:219 +#, c-format +msgid "finding inheritance relationships" +msgstr "hledám informace o dědičnosti" + +#: common.c:222 +#, c-format +msgid "reading column info for interesting tables" +msgstr "čtu informace o sloupcích pro tabulky" + +#: common.c:225 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "označuji zděděné sloupce v pod-tabulkách" + +#: common.c:228 +#, c-format +msgid "reading indexes" +msgstr "čtu indexy" + +#: common.c:231 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "označuji indexy na partitionovaných tabulkách" + +#: common.c:234 +#, c-format +msgid "reading extended statistics" +msgstr "čtu rozšířené statistiky" + +#: common.c:237 +#, c-format +msgid "reading constraints" +msgstr "čtu omezení" + +#: common.c:240 +#, c-format +msgid "reading triggers" +msgstr "čtu triggery" + +#: common.c:243 +#, c-format +msgid "reading rewrite rules" +msgstr "čtu přepisovací pravidla" + +#: common.c:246 +#, c-format +msgid "reading policies" +msgstr "čtu přístupové politiky" + +#: common.c:249 +#, c-format +msgid "reading publications" +msgstr "čtu publikace" + +#: common.c:252 +#, c-format +msgid "reading publication membership" +msgstr "čtu členství v publikacích" + +#: common.c:255 +#, c-format +msgid "reading subscriptions" +msgstr "čtu subskripce" + +#: common.c:1025 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "selhala kontrola, rodičovské OID %u tabulky \"%s\" (OID %u) nenalez" + +#: common.c:1067 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "nemohu zpracovat numerické pole \"%s\": příliš mnoho čísel" + +#: common.c:1082 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "nemohu zpracovat numerické pole \"%s\": neplatný znak v čísle" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "neplatný kompresní kód: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "nezkompilováno s podporou zlib" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "nelze inicializovat kompresní knihovnu: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "nelze uzavřít kompresní stream: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "nelze komprimovat data: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "nelze dekomprimovat data: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "nelze uzavřít kompresní knihovnu: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:557 pg_backup_tar.c:560 +#, c-format +msgid "could not read from input file: %s" +msgstr "nelze číst vstupní soubor: %s" + +#: compress_io.c:623 pg_backup_custom.c:646 pg_backup_directory.c:552 +#: pg_backup_tar.c:793 pg_backup_tar.c:816 +#, c-format +msgid "could not read from input file: end of file" +msgstr "nelze číst vstupní soubor: end of file" + +#: parallel.c:254 +#, c-format +msgid "WSAStartup failed: %d" +msgstr "WSAStartup selhal: %d" + +#: parallel.c:964 +#, c-format +msgid "could not create communication channels: %m" +msgstr "nelze vytvořit komunikační kanály: %m" + +#: parallel.c:1021 +#, c-format +msgid "could not create worker process: %m" +msgstr "nelze vytvořit pracovní proces: %m" + +#: parallel.c:1151 +#, c-format +msgid "unrecognized command received from master: \"%s\"" +msgstr "nerozpoznaný příkaz obdržen od mastera: %s" + +#: parallel.c:1194 parallel.c:1432 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "z pracovního procesu dorazila neplatná zpráva: \"%s\"" + +#: parallel.c:1326 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"nelze získat zámek na relaci \"%s\"\n" +"Toto obvykle znamená že někdo si vyžádal ACCESS EXCLUSIVE zámek na tabulce poté co rodičovský pg_dump proces získal výchozí ACCESS SHARE zámek na dané tabulce." + +#: parallel.c:1415 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "pracovní proces neočekávaně selhal" + +#: parallel.c:1537 parallel.c:1655 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "nelze zapsat do komunikačního kanálu: %m" + +#: parallel.c:1614 +#, c-format +msgid "select() failed: %m" +msgstr "select() selhalo: %m" + +#: parallel.c:1739 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: nelze vytvořit soket: chybový kód %d" + +#: parallel.c:1750 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: nelze provést bind: chybový kód %d" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: nelze poslouchat: chybový kód %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname() selhal: chybový kód %d" + +#: parallel.c:1775 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: nelze vytvořit druhý soket: chybový kód %d" + +#: parallel.c:1784 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: nelze se připojit k soketu: chybový kód %d" + +#: parallel.c:1793 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: nelze přijmout spojení: chybový kód %d" + +#: pg_backup_archiver.c:277 pg_backup_archiver.c:1587 +#, c-format +msgid "could not close output file: %m" +msgstr "nelze zavřít výstupní soubor: %m" + +#: pg_backup_archiver.c:321 pg_backup_archiver.c:325 +#, c-format +msgid "archive items not in correct section order" +msgstr "archivované položky v nesprávném pořadí sekcí" + +#: pg_backup_archiver.c:331 +#, c-format +msgid "unexpected section code %d" +msgstr "neočekávaný kód sekce %d" + +#: pg_backup_archiver.c:368 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "paralelní obnova není pro tento formát archivu podporována" + +#: pg_backup_archiver.c:372 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "paralelní obnova není podporována s archivy z pre-8.0 verzí pg_dump" + +#: pg_backup_archiver.c:390 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "nelze obnovit z komprimovaného archivu (není nastavena podpora komprese)" + +#: pg_backup_archiver.c:407 +#, c-format +msgid "connecting to database for restore" +msgstr "navazováno spojení s databází pro obnovu" + +#: pg_backup_archiver.c:409 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "přímé spojení s databází nejsou podporovány v archivech před verzí 1.3" + +#: pg_backup_archiver.c:452 +#, c-format +msgid "implied data-only restore" +msgstr "předpokládána pouze obnova dat" + +#: pg_backup_archiver.c:518 +#, c-format +msgid "dropping %s %s" +msgstr "odstraňuji %s %s" + +#: pg_backup_archiver.c:613 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "nelze zjistit kam přidat IF EXISTS v příkazu \"%s\"" + +#: pg_backup_archiver.c:769 pg_backup_archiver.c:771 +#, c-format +msgid "warning from original dump file: %s" +msgstr "varování z originálního dump souboru: %s" + +#: pg_backup_archiver.c:786 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "vytvářím %s \"%s.%s\"" + +#: pg_backup_archiver.c:789 +#, c-format +msgid "creating %s \"%s\"" +msgstr "vytvářím %s \"%s\"" + +#: pg_backup_archiver.c:839 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "připojuji se k nové databázi \"%s\"" + +#: pg_backup_archiver.c:866 +#, c-format +msgid "processing %s" +msgstr "zpracovávám %s" + +#: pg_backup_archiver.c:886 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "zpracovávám data pro tabulku \"%s.%s\"" + +#: pg_backup_archiver.c:948 +#, c-format +msgid "executing %s %s" +msgstr "vykonávám %s %s" + +#: pg_backup_archiver.c:987 +#, c-format +msgid "disabling triggers for %s" +msgstr "vypínám triggery pro %s" + +#: pg_backup_archiver.c:1013 +#, c-format +msgid "enabling triggers for %s" +msgstr "zapínám triggery pro %s" + +#: pg_backup_archiver.c:1041 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "interní chyba -- WriteData není možno volat mimo kontext rutiny DataDumper" + +#: pg_backup_archiver.c:1224 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "\"large object\" výstup není podporován ve vybraném formátu" + +#: pg_backup_archiver.c:1282 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "obnoven %d large objekt" +msgstr[1] "obnoveny %d large objekty" +msgstr[2] "obnoveny %d large objektů" + +#: pg_backup_archiver.c:1303 pg_backup_tar.c:736 +#, c-format +msgid "restoring large object with OID %u" +msgstr "obnovován \"large object\" s OID %u" + +#: pg_backup_archiver.c:1315 +#, c-format +msgid "could not create large object %u: %s" +msgstr "nelze vytvořit \"large object\" %u: %s" + +#: pg_backup_archiver.c:1320 pg_dump.c:3555 +#, c-format +msgid "could not open large object %u: %s" +msgstr "nelze otevřít \"large object\" %u:%s" + +#: pg_backup_archiver.c:1377 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "nelze otevřít TOC soubor \"%s\": %m" + +#: pg_backup_archiver.c:1417 +#, c-format +msgid "line ignored: %s" +msgstr "řádka ignorována: %s" + +#: pg_backup_archiver.c:1424 +#, c-format +msgid "could not find entry for ID %d" +msgstr "nelze najít záznam ID %d" + +#: pg_backup_archiver.c:1445 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "nelze zavřít TOC soubor: %m" + +#: pg_backup_archiver.c:1559 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:484 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "nelze otevřít výstupní soubor \"%s\": %m" + +#: pg_backup_archiver.c:1561 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "nelze otevřít výstupní soubor: %m" + +#: pg_backup_archiver.c:1654 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "zapsán %lu byte dat large objektů (result = %lu)" +msgstr[1] "zapsán %lu byty dat large objektů (result = %lu)" +msgstr[2] "zapsán %lu bytů dat large objektů (result = %lu)" + +#: pg_backup_archiver.c:1659 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "nelze zapsat \"large object\" (výsledek = %lu, očekáváno: %lu)" + +#: pg_backup_archiver.c:1749 +#, c-format +msgid "while INITIALIZING:" +msgstr "během INICIALIZACE:" + +#: pg_backup_archiver.c:1754 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "během ZPRACOVÁNÍ TOC:" + +#: pg_backup_archiver.c:1759 +#, c-format +msgid "while FINALIZING:" +msgstr "během FINALIZACE:" + +#: pg_backup_archiver.c:1764 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "z TOC záznamu %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1840 +#, c-format +msgid "bad dumpId" +msgstr "neplatné dumpId" + +#: pg_backup_archiver.c:1861 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "špatné dumpId tabulky pro TABLE DATA položku" + +#: pg_backup_archiver.c:1953 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "neočekávaný příznak datového offsetu %d" + +#: pg_backup_archiver.c:1966 +#, c-format +msgid "file offset in dump file is too large" +msgstr "offset souboru v dumpu je příliš velký" + +#: pg_backup_archiver.c:2103 pg_backup_archiver.c:2113 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "jméno adresáře je příliš dlouhé: \"%s\"" + +#: pg_backup_archiver.c:2121 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "adresář \"%s\" zřejmě není platným archivem (\"toc.dat\" neexistuje)" + +#: pg_backup_archiver.c:2129 pg_backup_custom.c:173 pg_backup_custom.c:812 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "nelze otevřít vstupní soubor \"%s\": %m" + +#: pg_backup_archiver.c:2136 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "nelze otevřít vstupní soubor: %m" + +#: pg_backup_archiver.c:2142 +#, c-format +msgid "could not read input file: %m" +msgstr "nelze číst vstupní soubor: %m" + +#: pg_backup_archiver.c:2144 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "vstupní soubor je příliš krátký (čteno %lu, očekáváno 5)" + +#: pg_backup_archiver.c:2229 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "vstupní soubor se zdá být dump v textovém formátu. Použijte prosím psql." + +#: pg_backup_archiver.c:2235 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "vstupní soubor se nezdá být korektním archivem (příliš krátký?)" + +#: pg_backup_archiver.c:2241 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "vstupní soubor se nezdá být korektním archivem" + +#: pg_backup_archiver.c:2261 +#, c-format +msgid "could not close input file: %m" +msgstr "nelze zavřít výstupní soubor: %m" + +#: pg_backup_archiver.c:2373 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "neznámý formát souboru \"%d\"" + +#: pg_backup_archiver.c:2455 pg_backup_archiver.c:4458 +#, c-format +msgid "finished item %d %s %s" +msgstr "dokončena položka %d %s %s" + +#: pg_backup_archiver.c:2459 pg_backup_archiver.c:4471 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "worker proces selhal: exit kód %d" + +#: pg_backup_archiver.c:2579 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "ID záznamu %d je mimo rozsah -- možná je poškozena TOC" + +#: pg_backup_archiver.c:2646 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "obnova tabulek s volbou WITH OIDS již není podporována" + +#: pg_backup_archiver.c:2728 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "neplatné kódování \"%s\"" + +#: pg_backup_archiver.c:2733 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "chybná položka ENCODING: %s" + +#: pg_backup_archiver.c:2751 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "chybná položka STDSTRINGS: %s" + +#: pg_backup_archiver.c:2776 +#, c-format +msgid "schema \"%s\" not found" +msgstr "schéma \"%s\" nenalezeno" + +#: pg_backup_archiver.c:2783 +#, c-format +msgid "table \"%s\" not found" +msgstr "tabulka \"%s\" nenalezena" + +#: pg_backup_archiver.c:2790 +#, c-format +msgid "index \"%s\" not found" +msgstr "index \"%s\" nenalezen" + +#: pg_backup_archiver.c:2797 +#, c-format +msgid "function \"%s\" not found" +msgstr "funkce \"%s\" nenalezena" + +#: pg_backup_archiver.c:2804 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "trigger \"%s\" nenalezen" + +#: pg_backup_archiver.c:3196 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "nelze nastavit uživatele session na \"%s\": %s" + +#: pg_backup_archiver.c:3328 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "nelze nastavit search_path na \"%s\": %s" + +#: pg_backup_archiver.c:3390 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "nelze nastavit default_tablespace na %s: %s" + +#: pg_backup_archiver.c:3435 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "nelze nastavit default_table_access_method na: %s" + +#: pg_backup_archiver.c:3527 pg_backup_archiver.c:3685 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "nevím jak nastavit vlastníka pro typ objektu \"%s\"" + +#: pg_backup_archiver.c:3789 +#, c-format +msgid "did not find magic string in file header" +msgstr "nelze najít identifikační řetězec v hlavičce souboru" + +#: pg_backup_archiver.c:3802 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "nepodporovaná verze (%d.%d) v hlavičce souboru" + +#: pg_backup_archiver.c:3807 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "kontrola velikosti integeru (%lu) selhala" + +#: pg_backup_archiver.c:3811 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "archiv byl vytvořen na stroji s většími celými čísly (integer), některé operace mohou selhat" + +#: pg_backup_archiver.c:3821 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "očekávaný formát (%d) se liší se od formátu nalezeného v souboru (%d)" + +#: pg_backup_archiver.c:3837 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "archiv je komprimován, ale tato instalace nepodporuje kompresi -- data nebudou dostupná" + +#: pg_backup_archiver.c:3855 +#, c-format +msgid "invalid creation date in header" +msgstr "v hlavičce je neplatné datum vytvoření" + +#: pg_backup_archiver.c:3983 +#, c-format +msgid "processing item %d %s %s" +msgstr "zpracovávám položku %d %s %s" + +#: pg_backup_archiver.c:4062 +#, c-format +msgid "entering main parallel loop" +msgstr "vstupuji do hlavní paralelní smyčky" + +#: pg_backup_archiver.c:4073 +#, c-format +msgid "skipping item %d %s %s" +msgstr "přeskakuji položku %d %s %s" + +#: pg_backup_archiver.c:4082 +#, c-format +msgid "launching item %d %s %s" +msgstr "spouštím položku %d %s %s" + +#: pg_backup_archiver.c:4136 +#, c-format +msgid "finished main parallel loop" +msgstr "ukončuji hlavní paralelní smyčku" + +#: pg_backup_archiver.c:4172 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "zpracování vynechalo položku %d %s %s" + +#: pg_backup_archiver.c:4777 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "tabulku \"%s\" nelze vytvořit, její data nebudou obnovena" + +#: pg_backup_custom.c:378 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "neplatné OID pro \"large object\"" + +#: pg_backup_custom.c:441 pg_backup_custom.c:507 pg_backup_custom.c:632 +#: pg_backup_custom.c:870 pg_backup_tar.c:1086 pg_backup_tar.c:1091 +#, c-format +msgid "error during file seek: %m" +msgstr "chyba během posunu v souboru: %m" + +#: pg_backup_custom.c:480 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "datový blok %d má chybnou seek pozici" + +#: pg_backup_custom.c:497 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "nepřípustný typ datového bloku (%d) během prohledávání archivu" + +#: pg_backup_custom.c:519 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "v archivu nelze najít blok ID %d -- možná kvůli out-of-order restore požadavku, který nemohl být vyřízen kvůli non-seekable vstupnímu souboru" + +#: pg_backup_custom.c:524 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "v archivu nelze najít blok ID %d -- archiv může být poškozen" + +#: pg_backup_custom.c:531 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "nalezeno neočekávané ID bloku (%d) při čtení dat - očekáváno %d" + +#: pg_backup_custom.c:545 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "nepřípustný typ datového bloku %d během obnovení archivu" + +#: pg_backup_custom.c:648 +#, c-format +msgid "could not read from input file: %m" +msgstr "nelze číst vstupní soubor: %m" + +#: pg_backup_custom.c:751 pg_backup_custom.c:803 pg_backup_custom.c:948 +#: pg_backup_tar.c:1089 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "nelze určit seek pozici v archivním souboru: %m" + +#: pg_backup_custom.c:767 pg_backup_custom.c:807 +#, c-format +msgid "could not close archive file: %m" +msgstr "nelze uzavřít archivní soubor: %m" + +#: pg_backup_custom.c:790 +#, c-format +msgid "can only reopen input archives" +msgstr "vstupní archivy lze pouze znovu otevřít" + +#: pg_backup_custom.c:797 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "paralelní obnova ze standardního vstupnu není podporována" + +#: pg_backup_custom.c:799 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "paralelní obnova z neseekovatelného souboru není podporována" + +#: pg_backup_custom.c:815 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "nelze nastavit seek pozici v archivním souboru: %m" + +#: pg_backup_custom.c:894 +#, c-format +msgid "compressor active" +msgstr "compressor aktivní" + +#: pg_backup_db.c:41 +#, c-format +msgid "could not get server_version from libpq" +msgstr "nelze získat server_version z libpq" + +#: pg_backup_db.c:52 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "verze serveru: %s; %s verze: %s" + +#: pg_backup_db.c:54 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "končím kvůli rozdílnosti verzí serverů" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "spojení s databází již existuje" + +#: pg_backup_db.c:133 pg_backup_db.c:185 pg_dumpall.c:1651 pg_dumpall.c:1764 +msgid "Password: " +msgstr "Heslo: " + +#: pg_backup_db.c:177 +#, c-format +msgid "could not connect to database" +msgstr "nelze znovu navázat spojení s databází" + +#: pg_backup_db.c:195 +#, c-format +msgid "reconnection to database \"%s\" failed: %s" +msgstr "připojení k databázi \"%s\" selhalo: %s" + +#: pg_backup_db.c:199 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "spojení s databází \"%s\" selhalo: %s" + +#: pg_backup_db.c:272 pg_dumpall.c:1684 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:279 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "dotaz selhal: %s" + +#: pg_backup_db.c:281 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "dotaz byl: %s" + +#: pg_backup_db.c:322 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "dotaz vrátil %d řádku namísto jedné: %s" +msgstr[1] "dotaz vrátil %d řádky namísto jedné: %s" +msgstr[2] "dotaz vrátil %d řádek namísto jedné: %s" + +#: pg_backup_db.c:358 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %sPříkaz byl: %s" + +#: pg_backup_db.c:414 pg_backup_db.c:488 pg_backup_db.c:495 +msgid "could not execute query" +msgstr "nelze provést dotaz" + +#: pg_backup_db.c:467 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "chyba vrácená voláním PQputCopyData: %s" + +#: pg_backup_db.c:516 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "chyba vrícená voláním PQputCopyEnd: %s" + +#: pg_backup_db.c:522 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "COPY selhal pro tabulku \"%s\": %s" + +#: pg_backup_db.c:528 pg_dump.c:1991 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "neočekávané další výsledky během COPY tabulky \"%s\"" + +#: pg_backup_db.c:586 +#, c-format +msgid "LOCK TABLE failed for \"%s\": %s" +msgstr "LOCK TABLE selhal pro \"%s\": %s" + +#: pg_backup_db.c:604 +msgid "could not start database transaction" +msgstr "nelze spustit databázovou transakci" + +#: pg_backup_db.c:612 +msgid "could not commit database transaction" +msgstr "nelze provést commit transakce" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "nezadán žádný výstupní adresář" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "nelze načíst adresář \"%s\": %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "nelze zavřít adresář \"%s\": %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "nelze vytvořit adresář \"%s\": %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "nelze zapsat do výstupního souboru: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "nelze uzavřít datový soubor \"%s\": %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "nelze otevřít TOC soubor pro large objekty \"%s\" pro vstup: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "neplatný řádek v TOC souboru pro large objekty \"%s\" : \"%s\"" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "chyba při čtení TOC souboru pro large objekty \"%s\"" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "nelze uzavřít TOC soubor pro large objekty \"%s\": %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "nelze zapsat do TOC souboru pro bloby" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "jméno souboru je příliš dlouhé: \"%s\"" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "tento formát nelze číst" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "nelze otevřít TOC soubor \"%s\" pro výstup: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "nelze otevřít TOC soubor pro výstup: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:358 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "komprese není podporována v archivním formátu tar" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "nelze otevřít TOC soubor \"%s\" pro vstup: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "nelze otevřít TOC soubor pro vstup: %m" + +#: pg_backup_tar.c:344 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "v archivu nelze najít soubor \"%s\"" + +#: pg_backup_tar.c:410 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "nelze vygenerovat jméno dočasného souboru: %m" + +#: pg_backup_tar.c:421 +#, c-format +msgid "could not open temporary file" +msgstr "nelze otevřít dočasný soubor" + +#: pg_backup_tar.c:448 +#, c-format +msgid "could not close tar member" +msgstr "nelze zavřít tar položku" + +#: pg_backup_tar.c:691 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "neočekávaná syntaxe příkazu COPY: \"%s\"" + +#: pg_backup_tar.c:958 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "neplatné OID pro \"large object\" (%u)" + +#: pg_backup_tar.c:1105 +#, c-format +msgid "could not close temporary file: %m" +msgstr "nelze otevřít dočasný soubor: %m" + +#: pg_backup_tar.c:1114 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "skutečná délka souboru (%s) neodpovídá očekávané (%s)" + +#: pg_backup_tar.c:1171 pg_backup_tar.c:1201 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "nelze najít hlavičku pro soubor %s v tar archivu" + +#: pg_backup_tar.c:1189 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "obnova dat mimo pořadí není podporována v tomto formátu archivu: \"%s\" je vyžadován, ale v archivu předchází \"%s\"." + +#: pg_backup_tar.c:1234 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "nalezena nekompletní tar hlavička (%lu byte)" +msgstr[1] "nalezena nekompletní tar hlavička (%lu byty)" +msgstr[2] "nalezena nekompletní tar hlavička (%lu bytů)" + +#: pg_backup_tar.c:1285 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "nalezena poškozená tar hlavička v %s (očekáváno %d, vypočteno %d) pozice souboru %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "neznámý název sekce \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:607 pg_dump.c:624 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "vyčerpány dostupné on_exit_nicely sloty" + +#: pg_dump.c:533 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "úroveň komprese musí být v rozsahu 0..9" + +#: pg_dump.c:571 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits musí být v intervalu -15..3" + +#: pg_dump.c:594 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "počet řádek na insert musí být v rozsahu %d..%d" + +#: pg_dump.c:622 pg_dumpall.c:346 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "příliš mnoho argumentů v příkazové řádce (první je \"%s\")" + +#: pg_dump.c:643 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "volby -s/--schema-only a -a/--data-only nelze používat společně" + +#: pg_dump.c:648 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "volby -s/--schema-only a --include-foreign-data nelze používat společně" + +#: pg_dump.c:651 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "volba --include-foreign-data není podporována pro paralelní backupy" + +#: pg_dump.c:655 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "volby -c/--clean a -a/--data-only nelze používat společně" + +#: pg_dump.c:660 pg_dumpall.c:381 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "volba --if-exists vyžaduje volbu -c/--clean" + +#: pg_dump.c:667 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "volba --on-conflict-do-nothing vyžaduje volbu --inserts, --rows-per-insert, nebo --column-inserts" + +#: pg_dump.c:689 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "požadovaná komprese není v této instalaci dostupná -- archiv bude nekomprimovaný" + +#: pg_dump.c:710 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "neplatný počet paralelních jobů" + +#: pg_dump.c:714 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "paralelní záloha je podporována pouze directory formátem" + +#: pg_dump.c:769 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Synchronizované snapshoty nejsou na této verzi serveru podporovány.\n" +"Pokud nepotřebujete synchronizované snapshoty, použijte přepínač\n" +"--no-synchronized-snapshots." + +#: pg_dump.c:775 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Exportované snapshoty nejsou touto verzí serveru podporovány." + +#: pg_dump.c:787 +#, c-format +msgid "last built-in OID is %u" +msgstr "poslední vestavěné OID je %u" + +#: pg_dump.c:796 +#, c-format +msgid "no matching schemas were found" +msgstr "nebyla nalezena žádná odovídající schémata" + +#: pg_dump.c:810 +#, c-format +msgid "no matching tables were found" +msgstr "nebyla nalezena žádná odpovídající tabulka" + +#: pg_dump.c:990 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s vytvoří dump databáze jako textový soubor nebo v jiném formátu.\n" +"\n" + +#: pg_dump.c:991 pg_dumpall.c:617 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: pg_dump.c:992 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [PŘEPÍNAČ]... [DATABÁZE]\n" + +#: pg_dump.c:994 pg_dumpall.c:620 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Obecné volby:\n" + +#: pg_dump.c:995 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=SOUBOR výstupní soubor nebo adresář\n" + +#: pg_dump.c:996 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p formát výstupního soubor (custom, directory, tar,\n" +" plain text (výchozí))\n" + +#: pg_dump.c:998 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=NUM použij tento počet paralelních jobů pro zálohu\n" + +#: pg_dump.c:999 pg_dumpall.c:622 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose vypisovat více informací\n" + +#: pg_dump.c:1000 pg_dumpall.c:623 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version zobraz informaci o verzi, poté skonči\n" + +#: pg_dump.c:1001 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 úroveň komprese při použití komprimovaného formátu\n" + +#: pg_dump.c:1002 pg_dumpall.c:624 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " --lock-wait-timeout=TIMEOUT selže po uplynutí TIMEOUT čekáním na zámek tabulky\n" + +#: pg_dump.c:1003 pg_dumpall.c:651 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync nečekat než budou změny bezpečně zapsány na disk\n" + +#: pg_dump.c:1004 pg_dumpall.c:625 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help zobraz tuto nápovědu, poté skonči\n" + +#: pg_dump.c:1006 pg_dumpall.c:626 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Přepínače ovlivňující výstup:\n" + +#: pg_dump.c:1007 pg_dumpall.c:627 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only dump pouze dat bez definic databázových objektů\n" + +#: pg_dump.c:1008 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs zahrnout \"large objects\" do dumpu\n" + +#: pg_dump.c:1009 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs nezahrnovat \"large objects\" do dumpu\n" + +#: pg_dump.c:1010 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, --clean odstranit (drop) databázi před jejím vytvořením\n" + +#: pg_dump.c:1011 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr " -C, --create zahrnout příkazy pro vytvoření databáze do dumpu\n" + +#: pg_dump.c:1012 pg_dumpall.c:629 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=KÓDOVÁNÍ kódování znaků databáze\n" + +#: pg_dump.c:1013 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr "" +" -n, --schema=PATTERN vytvořit dump pouze specifikovaného schématu\n" +"\n" + +#: pg_dump.c:1014 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr "" +" -N, --exclude-schema=PATTERN nedumpuj uvedená schéma(ta)\n" +"\n" + +#: pg_dump.c:1015 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner nevypisovat příkazy pro nastavení vlastníka objektu\n" +" v čistě textovém formátu\n" + +#: pg_dump.c:1017 pg_dumpall.c:633 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr "" +" -s, --schema-only dump pouze definic databázových objektů\n" +" (tabulek apod.) bez dat\n" + +#: pg_dump.c:1018 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, --superuser=JMÉNO uživatelské jméno superuživatele použité při dumpu\n" + +#: pg_dump.c:1019 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr "" +" -t, --table=PATTERN provést dump pouze uvedené tabulky\n" +"\n" + +#: pg_dump.c:1020 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr "" +" -T, --exclude-table=PATTERN neprováděj dump uvedených tabulek\n" +"\n" + +#: pg_dump.c:1021 pg_dumpall.c:636 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges neprovádět dump přístupových práv (grant/revoke)\n" + +#: pg_dump.c:1022 pg_dumpall.c:637 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade pouze pro použití upgradovacími nástroji\n" + +#: pg_dump.c:1023 pg_dumpall.c:638 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr " --column-inserts použije pro dump dat příkaz INSERT se jmény sloupců\n" + +#: pg_dump.c:1024 pg_dumpall.c:639 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr "" +" --disable-dollar-quoting nepoužívat znak dolaru místo uvozovek, používat\n" +" standardní SQL uvozování\n" + +#: pg_dump.c:1025 pg_dumpall.c:640 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr " --disable-triggers zakázat volání triggerů během obnovy dat\n" + +#: pg_dump.c:1026 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security povolit row security (vypíše pouze data ke kterým má\n" +" uživatel přístup)\n" + +#: pg_dump.c:1028 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr "" +" --exclude-table-data=VZOR nedumpuj data pro zadané tabulky\n" +"\n" + +#: pg_dump.c:1029 pg_dumpall.c:642 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM přenastav výchozí nastavení pro extra_float_digits\n" + +#: pg_dump.c:1030 pg_dumpall.c:643 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists použít IF EXISTS při mazání objektů\n" + +#: pg_dump.c:1031 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=PATTERN\n" +" zahrne data z foreign tabulek náležících k foreign\n" +" serverům odpovídajícím PATTERN\n" + +#: pg_dump.c:1034 pg_dumpall.c:644 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr " --inserts použít pro dump dat příkazy INSERT místo COPY\n" + +#: pg_dump.c:1035 pg_dumpall.c:645 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root data do partition tabulek načítat přes root tabulku\n" + +#: pg_dump.c:1036 pg_dumpall.c:646 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments neprovádět dump komentářů\n" + +#: pg_dump.c:1037 pg_dumpall.c:647 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications neprovádět dump publikací\n" + +#: pg_dump.c:1038 pg_dumpall.c:649 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels neprovádět dump bezpečnostních štítků\n" + +#: pg_dump.c:1039 pg_dumpall.c:650 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions neprovádět dump subsckripcí\n" + +#: pg_dump.c:1040 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr " --no-synchronized-snapshots nepoužívat synchronizované snapshoty v paralelních jobech\n" + +#: pg_dump.c:1041 pg_dumpall.c:652 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces neprovádět dump přiřazení tablespaces\n" + +#: pg_dump.c:1042 pg_dumpall.c:653 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data nedumpuj data unlogged tabulek\n" + +#: pg_dump.c:1043 pg_dumpall.c:654 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing přidej ON CONFLICT DO NOTHING do INSERT příkazů\n" + +#: pg_dump.c:1044 pg_dumpall.c:655 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr " --quote-all-identifiers všechny identifikátory uveď v uvozovkách, i když se nejedná o klíčová slova\n" + +#: pg_dump.c:1045 pg_dumpall.c:656 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NROWS počet řádek per INSERT; implikuje --inserts\n" + +#: pg_dump.c:1046 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr " --section=SECTION dump pojmenované sekce (pre-data, data, nebo post-data)\n" + +#: pg_dump.c:1047 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr " --serializable-deferrable počkej než bude možné provést dump bez anomálií\n" + +#: pg_dump.c:1048 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT pro dump použít zadaný snapshot\n" + +#: pg_dump.c:1049 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names vyžadovat aby každý vzor pro zahrnutí tabulek a/nebo schémat\n" +" odpovídal alespoň jednomu objektu\n" + +#: pg_dump.c:1051 pg_dumpall.c:657 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" používat příkaz SET SESSION AUTHORIZATION namísto\n" +" příkazu ALTER OWNER pro nastavení vlastníka\n" + +#: pg_dump.c:1055 pg_dumpall.c:661 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Volby spojení:\n" + +#: pg_dump.c:1056 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=JMÉNO jméno zdrojové databáze\n" + +#: pg_dump.c:1057 pg_dumpall.c:663 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME host databázového serveru nebo adresář se sockety\n" + +#: pg_dump.c:1058 pg_dumpall.c:665 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT port databázového serveru\n" + +#: pg_dump.c:1059 pg_dumpall.c:666 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=JMÉNO připoj se jako uvedený uživatel\n" + +#: pg_dump.c:1060 pg_dumpall.c:667 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password nikdy se neptej na heslo\n" + +#: pg_dump.c:1061 pg_dumpall.c:668 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password zeptej se na heslo (mělo by se dít automaticky)\n" + +#: pg_dump.c:1062 pg_dumpall.c:669 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROLENAME před dumpem proveď SET ROLE\n" + +#: pg_dump.c:1064 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Není-li specifikováno jméno databáze, použije se proměnná prostředí\n" +"PGDATABASE.\n" +"\n" + +#: pg_dump.c:1066 pg_dumpall.c:673 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Chyby hlašte na <%s>.\n" + +#: pg_dump.c:1067 pg_dumpall.c:674 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#: pg_dump.c:1086 pg_dumpall.c:499 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "specifikováno neplatné klientské kódování \"%s\"" + +#: pg_dump.c:1235 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Synchronizované snapshoty nejsou na této verzi serveru podporovány.\n" +"Pokud nepotřebujete synchronizované snapshoty, použijte přepínač\n" +"--no-synchronized-snapshots." + +#: pg_dump.c:1304 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "specifikován neplatný formát \"%s\" výstupu" + +#: pg_dump.c:1342 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "nebyla nalezena žádná schémata odpovídající vzoru \"%s\"" + +#: pg_dump.c:1389 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "nebyly nalezeny žádné foreign servery odpovídající vzoru \"%s\"" + +#: pg_dump.c:1452 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "nebyla nalezena žádná tabulka odpovídající vzoru \"%s\"" + +#: pg_dump.c:1865 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "dumpuji obsah tabulky \"%s.%s\"" + +#: pg_dump.c:1972 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Dumpování obsahu tabulky \"%s\" selhalo: volání PQgetCopyData() selhalo." + +#: pg_dump.c:1973 pg_dump.c:1983 +#, c-format +msgid "Error message from server: %s" +msgstr "Chybová zpráva ze serveru: %s" + +#: pg_dump.c:1974 pg_dump.c:1984 +#, c-format +msgid "The command was: %s" +msgstr "Příkaz byl: %s" + +#: pg_dump.c:1982 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Dumpování obsahu tabulky \"%s\" selhalo: volání PQgetResult() selhalo." + +#: pg_dump.c:2742 +#, c-format +msgid "saving database definition" +msgstr "ukládám definice databáze" + +#: pg_dump.c:3214 +#, c-format +msgid "saving encoding = %s" +msgstr "ukládám kódování znaků = %s" + +#: pg_dump.c:3239 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "ukládám standard_conforming_strings = %s" + +#: pg_dump.c:3278 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "nelze zpracovat výsledek current_schemas()" + +#: pg_dump.c:3297 +#, c-format +msgid "saving search_path = %s" +msgstr "ukládám search_path = %s" + +#: pg_dump.c:3337 +#, c-format +msgid "reading large objects" +msgstr "čtu \"large objects\"" + +#: pg_dump.c:3519 +#, c-format +msgid "saving large objects" +msgstr "ukládám \"large objects\"" + +#: pg_dump.c:3565 +#, c-format +msgid "error reading large object %u: %s" +msgstr "chyba při čtení large objektu %u: %s" + +#: pg_dump.c:3617 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "čtu row security enabled pro tabulku \"%s.%s\"" + +#: pg_dump.c:3648 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "čtu policies pro tablku \"%s.%s\"" + +#: pg_dump.c:3800 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "neočekáváný typ policy příkazu: %c" + +#: pg_dump.c:3951 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "vlastník publikace \"%s\" se zdá být neplatný" + +#: pg_dump.c:4096 +#, c-format +msgid "reading publication membership for table \"%s.%s\"" +msgstr "čtu členství v publikacích pro tabulku \"%s.%s\"" + +#: pg_dump.c:4239 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "subscriptions nejsou zahrnuty do dumpu protože aktuální uživatel není superuživatl" + +#: pg_dump.c:4293 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "vlastník subskripce \"%s\" se zdá být neplatný" + +#: pg_dump.c:4337 +#, c-format +msgid "could not parse subpublications array" +msgstr "nelze naparsovat pole \"subpublications\"" + +#: pg_dump.c:4659 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "nelze najít nadřízené rozšíření pro %s %s" + +#: pg_dump.c:4791 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "vlastník schématu \"%s\" se zdá být neplatný" + +#: pg_dump.c:4814 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "schéma s OID %u neexistuje" + +#: pg_dump.c:5139 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "vlastník datového typu \"%s\" se zdá být neplatný" + +#: pg_dump.c:5224 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "vlastník operátoru \"%s\" se zdá být neplatný" + +#: pg_dump.c:5526 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "vlastník třídy operátorů \"%s\" se zdá být neplatný" + +#: pg_dump.c:5610 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "vlastník rodiny operátorů \"%s\" se zdá být neplatný" + +#: pg_dump.c:5779 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "vlastník agregační funkce \"%s\" se zdá být neplatný" + +#: pg_dump.c:6039 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "vlastník funkce \"%s\" se zdá být neplatný" + +#: pg_dump.c:6867 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "vlastník tabulky \"%s\" se zdá být neplatný" + +#: pg_dump.c:6909 pg_dump.c:17389 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "selhala kontrola, OID %u rodičovské tabulky u sekvence s OID %u nelze najít" + +#: pg_dump.c:7051 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "čtu indexy pro tabulku \"%s.%s\"" + +#: pg_dump.c:7466 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "čtu cizí klíče pro tabulku \"%s.%s\"" + +#: pg_dump.c:7747 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "selhala kontrola, OID %u rodičovské tabulky u pg_rewrite položky OID %u nelze najít" + +#: pg_dump.c:7830 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "čtu triggery pro tabulku \"%s.%s\"" + +#: pg_dump.c:7963 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "dotaz vrátil prázdné jméno referencované tabulky pro trigger \"%s\" cizího klíče pro tabulku \"%s\" (OID tabulky: %u)" + +#: pg_dump.c:8518 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "hledám sloupce a typy pro tabulku \"%s.%s\"" + +#: pg_dump.c:8654 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "neplatné číslování sloupců v tabulce \"%s\"" + +#: pg_dump.c:8691 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "hledám DEFAULT výrazy pro tabulku \"%s.%s\"" + +#: pg_dump.c:8713 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "neplatná \"adnum\" hodnota %d pro tabulku \"%s\"" + +#: pg_dump.c:8778 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "hledám CHECK omezení pro tabulku \"%s.%s\"" + +#: pg_dump.c:8827 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "očekáván %d check constraint na tabulce \"%s\" nalezeno %d" +msgstr[1] "očekávány %d check constrainty na tabulce \"%s\" nalezeno %d" +msgstr[2] "očekáváno %d check constraintů na tabulce \"%s\" nalezeno %d" + +#: pg_dump.c:8831 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Systémové katalogy mohou být poškozeny.)" + +#: pg_dump.c:10417 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "typtype datového typu \"%s\" se zdá být neplatný" + +#: pg_dump.c:11771 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "nesmyslná hodnota v \"proargmodes\" poli" + +#: pg_dump.c:12143 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "nelze naparsovat pole \"proallargtypes\"" + +#: pg_dump.c:12159 +#, c-format +msgid "could not parse proargmodes array" +msgstr "nelze naparsovat pole \"proargmodes\"" + +#: pg_dump.c:12173 +#, c-format +msgid "could not parse proargnames array" +msgstr "nelze naparsovat pole \"proargnames\"" + +#: pg_dump.c:12184 +#, c-format +msgid "could not parse proconfig array" +msgstr "nelze naparsovat pole \"proconfig\"" + +#: pg_dump.c:12264 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "nerozpoznaná \"provolatile\" hodnota pro funkci \"%s\"" + +#: pg_dump.c:12314 pg_dump.c:14372 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "nerozpoznaná proparallel\" hodnota pro funkci \"%s\"" + +#: pg_dump.c:12453 pg_dump.c:12562 pg_dump.c:12569 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "nelze najít definici pro funkci ID %u" + +#: pg_dump.c:12492 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "chybná hodnota v položce pg_cast.castfunc nebo pg_cast.castmethod" + +#: pg_dump.c:12495 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "nesmyslná hodnota v položce \"pg_cast.castmethod\"" + +#: pg_dump.c:12588 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "chybná definice transformace, alespoň jedno z trffromsql a trftosql by mělo být nenulové" + +#: pg_dump.c:12605 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "nesmyslná hodnota v položce pg_transform.trffromsql" + +#: pg_dump.c:12626 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "nesmyslná hodnota v položce pg_transform.trftosql" + +#: pg_dump.c:12942 +#, c-format +msgid "could not find operator with OID %s" +msgstr "nelze najít operátor s OID %s" + +#: pg_dump.c:13010 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "neplatný typ \"%c\" access metody \"%s\"" + +#: pg_dump.c:13764 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "neočekávaný poskytovatel collation: %s" + +#: pg_dump.c:14236 +#, c-format +msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +msgstr "agregační funkci %s nelze dumpovat korektně pro tuto verzi databáze; ignorováno" + +#: pg_dump.c:14291 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "neznámá aggfinalmodify hodnota for agregační funkci \"%s\"" + +#: pg_dump.c:14347 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "neznámá aggmfinalmodify hodnota for agregační funkci \"%s\"" + +#: pg_dump.c:15069 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "neznámý typ objektu (%d) ve výchozích privilegiích" + +#: pg_dump.c:15087 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "nelze zpracovat seznam oprávnění ACL (%s)" + +#: pg_dump.c:15172 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "nelze zpracovat výchozí GRANT ACL seznam (%s) nebo výchozí REVOKE ACL seznam (%s) pro objekt \"%s\" (%s)" + +#: pg_dump.c:15180 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "nelze zpracovat GRANT ACL seznam (%s) nebo REVOKE ACL seznam (%s) pro objekt \"%s\" (%s)" + +#: pg_dump.c:15695 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "dotaz na získání definice view \"%s\" nevrátil žádná data" + +#: pg_dump.c:15698 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "dotaz na získání definice view \"%s\" vrátil více jak jednu definici" + +#: pg_dump.c:15705 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "definice view \"%s\" se zdá být prázdná (nulová délka)" + +#: pg_dump.c:15789 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS již není podporováno (tabulka \"%s\")" + +#: pg_dump.c:16269 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "neplatný počet rodičů %d pro tabulku \"%s\"" + +#: pg_dump.c:16592 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "neplatné číslo sloupce %d pro tabulku \"%s\"" + +#: pg_dump.c:16877 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "chybí index pro omezení \"%s\"" + +#: pg_dump.c:17102 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "neočekávaný typ omezení: %c" + +#: pg_dump.c:17234 pg_dump.c:17454 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "dotaz pro načtení dat sekvence \"%s\" vrátil %d řádek (expected 1)" +msgstr[1] "dotaz pro načtení dat sekvence \"%s\" vrátil %d řádky (expected 1)" +msgstr[2] "dotaz pro načtení dat sekvence \"%s\" vrátil %d řádek (expected 1)" + +#: pg_dump.c:17268 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "neočekávaný typ sekvence: %s" + +#: pg_dump.c:17552 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "neočekávaná hodnota tgtype: %d" + +#: pg_dump.c:17626 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "neplatný řetězec argumentů (%s) pro trigger \"%s\" tabulky \"%s\"" + +#: pg_dump.c:17862 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "dotaz k získání pravidla (RULE) \"%s\" pro tabulku \"%s\" selhal: vrácen chybný počet řádků" + +#: pg_dump.c:18024 +#, c-format +msgid "could not find referenced extension %u" +msgstr "nelze najít odkazované rozšíření %u" + +#: pg_dump.c:18236 +#, c-format +msgid "reading dependency data" +msgstr "čtu data o závislostech" + +#: pg_dump.c:18329 +#, c-format +msgid "no referencing object %u %u" +msgstr "žádný odkazující objekt %u: %u" + +#: pg_dump.c:18340 +#, c-format +msgid "no referenced object %u %u" +msgstr "žádný odkazovaný objekt %u: %u" + +#: pg_dump.c:18713 +#, c-format +msgid "could not parse reloptions array" +msgstr "nelze naparsovat pole \"reloptions\"" + +#: pg_dump_sort.c:360 +#, c-format +msgid "invalid dumpId %d" +msgstr "neplatné dumpId %d" + +#: pg_dump_sort.c:366 +#, c-format +msgid "invalid dependency %d" +msgstr "neplatná závislost %d" + +#: pg_dump_sort.c:599 +#, c-format +msgid "could not identify dependency loop" +msgstr "nelze identifikovat smyčku závislostí" + +#: pg_dump_sort.c:1170 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "na této tabulce existuje cyklus cizích klíčů:" +msgstr[1] "mezi těmito tabulkami existuje cyklus cizích klíčů:" +msgstr[2] "mezi těmito tabulkami existuje cyklus cizích klíčů:" + +#: pg_dump_sort.c:1174 pg_dump_sort.c:1194 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1175 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Bez zadání volby --disable-triggers nebo dočasného vypnutí constraintů zřejmě nebudete schopni tento dump obnovit." + +#: pg_dump_sort.c:1176 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Zvažte použití kompletního (full) dumpu namísto --data-only dumpu pro odstranění tohoto problému." + +#: pg_dump_sort.c:1188 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "nelze vyřešit smyčku závislostí mezi těmito položkami:" + +#: pg_dumpall.c:199 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Program \"%s\" je vyžadován aplikací %s, ale nebyl nalezen ve stejném\n" +"adresáři jako \"%s\".\n" +"Zkontrolujte vaši instalaci." + +#: pg_dumpall.c:204 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Program \"%s\" byl nalezen pomocí \"%s\",\n" +"ale nebyl ve stejné verzi jako %s.\n" +"Zkontrolujte vaši instalaci." + +#: pg_dumpall.c:356 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "volba --exclude-database nemůže být použita společně s -g/--globals-only, -r/--roles-only, nebo -t/--tablespaces-only" + +#: pg_dumpall.c:365 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "volby -g/--globals-only a -r/--roles-only nelze používat společně" + +#: pg_dumpall.c:373 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "volby -g/--globals-only a -t/--tablespaces-only nelze používat společně" + +#: pg_dumpall.c:387 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "volby -r/--roles-only a -t/--tablespaces-only nelze používat společně" + +#: pg_dumpall.c:448 pg_dumpall.c:1754 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "nelze navázat spojení s databází \"%s\"" + +#: pg_dumpall.c:462 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"nelze navázat spojení s databází \"postgres\" nebo \"template1\"\n" +"Zadejte prosím alternativní databázi." + +#: pg_dumpall.c:616 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s extrahuje PostgreSQL databázi do souboru s SQL skriptem.\n" +"\n" + +#: pg_dumpall.c:618 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [VOLBA]...\n" + +#: pg_dumpall.c:621 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=SOUBOR výstupní soubor\n" + +#: pg_dumpall.c:628 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, --clean odstranit (drop) databázi před jejím vytvořením\n" + +#: pg_dumpall.c:630 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, --globals-only dump pouze globálních objektů, ne databáze\n" + +#: pg_dumpall.c:631 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner nevypisuje příkazy k nastavení vlastníka objektů\n" + +#: pg_dumpall.c:632 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr " -r, --roles-only dump pouze rolí, ne databází nebo tablespaců\n" + +#: pg_dumpall.c:634 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, --superuser=JMÉNO uživatelské jméno superuživatele použité při dumpu\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr " -t, --tablespaces-only dump pouze tablespaců, ne databází nebo rolí\n" + +#: pg_dumpall.c:641 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=VZOR nedumpuj databáze jejichž jména odpovídají VZORu\n" + +#: pg_dumpall.c:648 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords hesla pro role nezahrnovat do dumpu\n" + +#: pg_dumpall.c:662 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=CONNSTR specifikace připojení do databáze\n" + +#: pg_dumpall.c:664 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=DBNAME alternativní výchozí databáze\n" + +#: pg_dumpall.c:671 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"Pokud není použito -f/--file, potom SQL skript bude vypsán přímo na standardní\n" +"výstup.\n" +"\n" + +#: pg_dumpall.c:877 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "název role začínající s \"pg_\" přeskočen (%s)" + +#: pg_dumpall.c:1278 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "nelze zpracovat ACL seznam (%s) pro prostor tabulek \"%s\"" + +#: pg_dumpall.c:1495 +#, c-format +msgid "excluding database \"%s\"" +msgstr "nedumpuji databázi \"%s\"" + +#: pg_dumpall.c:1499 +#, c-format +msgid "dumping database \"%s\"" +msgstr "dumpuji databázi \"%s\"" + +#: pg_dumpall.c:1531 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump selhal při zpracovávání databáze \"%s\", ukončuji se" + +#: pg_dumpall.c:1540 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "nelze otevřít logovací soubor \"%s\": %m" + +#: pg_dumpall.c:1584 +#, c-format +msgid "running \"%s\"" +msgstr "běží \"%s\"" + +#: pg_dumpall.c:1775 +#, c-format +msgid "could not connect to database \"%s\": %s" +msgstr "nelze navázat spojení s databází \"%s\": %s" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "nelze získat verzi serveru" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "nelze zpracovat verzi serveru \"%s\"" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "spouštím: %s" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "musí být specifikována jedna z voleb -d/--dbname a -f/--file" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "volby -d/--dbname a -f/--file nelze používat společně" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "volby -C/--create a -1/--single-transaction nelze používat společně" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "maximální počet paralelních jobů je %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "nelze zadat --single-transaction a několik úloh" + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "neznámý formát archivu \"%s\"; zadejte prosím \"c\", \"d\" nebo \"t\"" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "chyby ignorovány při obnovení: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s obnovuje PostgreSQL databázi z archivu vytvořeného pomocí pg_dump.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [PŘEPÍNAČ]... [SOUBOR]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=JMÉNO jméno cílové databáze\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=SOUBOR výstupní soubor (- pro stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, --format=c|d|t formát záložního souboru (měl by být automatický)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list zobrazit sumarizovaný obsah (TOC) archivu\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose vypisovat více informací\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version zobraz informaci o verzi, poté skonči\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help zobraz tuto nápovědu, poté skonči\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Přepínače ovlivňující obnovu:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only obnovit pouze data, ne definice databázových objektů\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create vypíše příkazy pro vytvoření databáze\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, --exit-on-error ukončit při chybě, implicitně pokračuje\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=JMÉNO obnovit jmenovaný index\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, --jobs=NUM použij pro obnovu daný počet paralelních jobů\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=SOUBOR použít specifikovaný obsah (TOC) pro řazení\n" +" výstupu z tohoto souboru\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NAME obnovit pouze objekty v tomto schématu\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NAME neobnovovat objekty v tomto schématu\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr "" +" -P, --function=JMÉNO(args)\n" +" obnovit funkci daného jména\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only obnovit pouze definice objektů, bez dat\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr "" +" -S, --superuser=JMÉNO jméno superuživatele použité pro\n" +" zakázaní triggerů\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=JMÉNO obnovit pouze jmenovanou relaci (tabulka, pohled, etc.)\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=JMÉNO obnovit pouze jmenovaný trigger\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, --no-privileges přeskočit obnovu přístupových práv (grant/revoke)\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr "" +" -1, --single-transaction\n" +" zpracuj soubor v rámci jedné transakce\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security povolit row security\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments neobnovovat komentáře\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables\n" +" neobnovuj data tabulek které nemohly být vytvořeny\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications do not restore publications\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels neobnovuj bezpečnostní štítky\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions neobnovovat subskripce\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces neobnovuj přiřazení tablespaces\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr " --section=SECTION obnov pojmenovanou sekci (pre-data, data, nebo post-data)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROLENAME před obnovou proveď SET ROLE\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"Volby -I, -n, -N, -P, -t, -T, a --section mohou být kombinovány a zadány několikrát\n" +"pro výběr více objektů.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"Není-li definován vstupní soubor, je použit standardní vstup.\n" +"\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "nelze číst symbolický link \"%s\"" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "potomek byl ukončen signálem %s" + +#~ msgid "compress_io" +#~ msgstr "compress_io" + +#~ msgid "parallel archiver" +#~ msgstr "paralelní archivář" + +#~ msgid "archiver" +#~ msgstr "archivář" + +#~ msgid "-C and -1 are incompatible options\n" +#~ msgstr "-C a -1 jsou nekompatibilní přepínače\n" + +#~ msgid "attempting to ascertain archive format\n" +#~ msgstr "pokouším se zjistit formát archivu\n" + +#~ msgid "allocating AH for %s, format %d\n" +#~ msgstr "alokován AH pro %s, formát %d\n" + +#~ msgid "read TOC entry %d (ID %d) for %s %s\n" +#~ msgstr "přečetl jsem TOC záznam %d (ID %d) pro %s %s\n" + +#~ msgid "could not set default_with_oids: %s" +#~ msgstr "nelze nastavit default_with_oids: %s" + +#~ msgid "entering restore_toc_entries_prefork\n" +#~ msgstr "vstupuji do restore_toc_entries_prefork\n" + +#~ msgid "entering restore_toc_entries_parallel\n" +#~ msgstr "vstupuji do restore_toc_entries_parallel\n" + +#~ msgid "entering restore_toc_entries_postfork\n" +#~ msgstr "vstupuji do restore_toc_entries_postfork\n" + +#~ msgid "no item ready\n" +#~ msgstr "žádná položka není připravena\n" + +#~ msgid "transferring dependency %d -> %d to %d\n" +#~ msgstr "přenáším závislost %d -> %d to %d\n" + +#~ msgid "reducing dependencies for %d\n" +#~ msgstr "redukuji závislosti pro %d\n" + +#~ msgid "custom archiver" +#~ msgstr "vlastní archivář" + +#~ msgid "archiver (db)" +#~ msgstr "archivář (db)" + +#~ msgid "failed to reconnect to database\n" +#~ msgstr "selhalo znovunavázání spojení s databází\n" + +#~ msgid "failed to connect to database\n" +#~ msgstr "selhalo spojení s databází\n" + +#~ msgid "directory archiver" +#~ msgstr "directory archiver" + +#~ msgid "tar archiver" +#~ msgstr "tar archivář" + +#~ msgid "moving from position %s to next member at file position %s\n" +#~ msgstr "přecházím z pozice %s na následujícího položky na pozici souboru %s\n" + +#~ msgid "now at file position %s\n" +#~ msgstr "nyní na pozici souboru %s\n" + +#~ msgid "skipping tar member %s\n" +#~ msgstr "přeskakován tar člen %s\n" + +#~ msgid "TOC Entry %s at %s (length %s, checksum %d)\n" +#~ msgstr "TOC položka %s na %s (délka %s, kontrolní součet %d)\n" + +#~ msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" +#~ msgstr "volby --inserts/--column-inserts a -o/--oids nelze používat společně\n" + +#~ msgid "(The INSERT command cannot set OIDs.)\n" +#~ msgstr "(Příkaz INSERT nemůže nastavovat OID.)\n" + +#~ msgid " -o, --oids include OIDs in dump\n" +#~ msgstr " -o, --oids zahrnout OID do dumpu\n" + +#~ msgid "WARNING: could not parse reloptions array\n" +#~ msgstr "VAROVÁNÍ: nelze naparsovat pole reloptions\n" + +#~ msgid "sorter" +#~ msgstr "sorter" + +#~ msgid " %s\n" +#~ msgstr " %s\n" + +#~ msgid "%s: option --if-exists requires option -c/--clean\n" +#~ msgstr "%s: volba --if-exists vyžaduje volbu -c/--clean\n" + +#~ msgid "%s: could not open the output file \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít výstupní soubor \"%s\": %s\n" + +#~ msgid "%s: invalid client encoding \"%s\" specified\n" +#~ msgstr "%s: specifikováno neplatné klientské kódování \"%s\"\n" + +#~ msgid "%s: executing %s\n" +#~ msgstr "%s: vykonávám %s\n" + +#~ msgid "%s: query failed: %s" +#~ msgstr "%s: dotaz selhal: %s" + +#~ msgid "%s: query was: %s\n" +#~ msgstr "%s: dotaz byl: %s\n" + +#~ msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" +#~ msgstr "%s: volby -s/--schema-only a -a/--data-only nelze použít najednou\n" + +#~ msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" +#~ msgstr "%s: volby -c/--clean a -a/--data-only nelze používat společně\n" + +#~ msgid "%s: invalid number of parallel jobs\n" +#~ msgstr "%s: neplatný počet paralelních jobů\n" + +#~ msgid "worker is terminating\n" +#~ msgstr "worker končí\n" + +#~ msgid "error processing a parallel work item\n" +#~ msgstr "chyba při paralelním zpracovávání položky\n" + +#~ msgid "terminated by user\n" +#~ msgstr "ukončeno uživatelem\n" + +#~ msgid "setting owner and privileges for %s %s\n" +#~ msgstr "nastavuji vlastníka a přístupová práva pro %s %s\n" + +#~ msgid "could not write to custom output routine\n" +#~ msgstr "nelze zapsat do vlastní výstupní rutiny\n" + +#~ msgid "unexpected end of file\n" +#~ msgstr "neočekávaný konec souboru\n" + +#~ msgid "could not find slot of finished worker\n" +#~ msgstr "nelze najít slot ukončeného workera\n" + +#~ msgid "could not write byte: %s\n" +#~ msgstr "nelze zapsat byte: %s\n" + +#~ msgid "could not write byte\n" +#~ msgstr "nelze zapsat byte\n" + +#~ msgid "could not write null block at end of tar archive\n" +#~ msgstr "nelze zapsat null blok na konec tar archivu\n" + +#~ msgid "archive member too large for tar format\n" +#~ msgstr "položka archivu je příliš velká pro formát tar\n" + +#~ msgid "could not output padding at end of tar member\n" +#~ msgstr "nelze zapsat vycpávku (padding) na konec položky taru\n" + +#~ msgid "mismatch in actual vs. predicted file position (%s vs. %s)\n" +#~ msgstr "aktuální a předpokládaná pozice souboru se neshodují (%s vs. %s)\n" + +#~ msgid "could not open output file \"%s\" for writing\n" +#~ msgstr "nelze otevřít výstupní soubor \"%s\" pro zápis\n" + +#~ msgid "server version must be at least 7.3 to use schema selection switches\n" +#~ msgstr "verze serveru musí být alespoň 7.3 pro použití přepínačů prů výběr schématu\n" + +#~ msgid "query to get data of sequence \"%s\" returned name \"%s\"\n" +#~ msgstr "dotaz na získání dat sekvence \"%s\" vrátil jméno \"%s\"\n" + +#~ msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" +#~ msgstr "%s: nelze zpracovat ACL seznam (%s) pro databázi \"%s\"\n" + +#~ msgid "worker process crashed: status %d\n" +#~ msgstr "worker proces selhal: status %d\n" + +#~ msgid "parallel_restore should not return\n" +#~ msgstr "parallel_restore by neměl skončit\n" + +#~ msgid "could not create worker thread: %s\n" +#~ msgstr "nelze vytvořit worker thread: %s\n" + +#~ msgid "could not parse version string \"%s\"\n" +#~ msgstr "neplatný formát řetězce s verzí \"%s\"\n" + +#~ msgid "%s: could not parse version \"%s\"\n" +#~ msgstr "%s: nelze zpracovat verzi serveru \"%s\"\n" + +#~ msgid "-C and -c are incompatible options\n" +#~ msgstr "-C a -c jsou nekompatibilní přepínače\n" + +#~ msgid "invalid COPY statement -- could not find \"copy\" in string \"%s\"\n" +#~ msgstr "neplatný COPY příkaz -- nelze najít \"copy\" v řetězci \"%s\"\n" + +#~ msgid "invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n" +#~ msgstr "neplatný COPY příkaz -- nelze najít \"from stdin\" v řetězci \"%s\" začínající na pozici %lu\n" + +#~ msgid "cannot create directory %s, it exists already\n" +#~ msgstr "nelze vytvořit adresář %s, již existuje\n" + +#~ msgid "cannot create directory %s, a file with this name exists already\n" +#~ msgstr "nelze vytvořit adresář %s, soubor s tímto jménem již existuje\n" + +#~ msgid "path name too long: %s" +#~ msgstr "cesta příliš dlouhá: %s" + +#~ msgid "restoring large object OID %u\n" +#~ msgstr "obnovuji \"large object\" s OID %u\n" + +#~ msgid "options -s/--schema-only and -a/--data-only cannot be used with --section\n" +#~ msgstr "volby -s/--schema-only a -a/--data-only nelze použít s --section\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help ukáže tento text a skončí\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version ukáže informace o verzi a skončí\n" + +#~ msgid "%s: options -s/--schema-only and -a/--data-only cannot be used with --section\n" +#~ msgstr "%s: volby -s/--schema-only a -a/--data-only nelze použít s --section\n" + +#~ msgid " -c, --clean clean (drop) database objects before recreating\n" +#~ msgstr " -c, --clean odstranit (drop) databázi před jejím vytvořením\n" + +#~ msgid " -O, --no-owner skip restoration of object ownership\n" +#~ msgstr " -O, --no-owner přeskoč nastavení vlastníka objektů\n" + +#~ msgid " --disable-triggers disable triggers during data-only restore\n" +#~ msgstr " --disable-triggers zakázat volání triggerů během obnovy dat\n" + +#~ msgid "" +#~ " --use-set-session-authorization\n" +#~ " use SET SESSION AUTHORIZATION commands instead of\n" +#~ " ALTER OWNER commands to set ownership\n" +#~ msgstr "" +#~ " --use-set-session-authorization\n" +#~ " používat příkaz SET SESSION AUTHORIZATION namísto\n" +#~ " příkazu ALTER OWNER pro nastavení vlastníka\n" + +#~ msgid "" +#~ "The program \"pg_dump\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Program \"pg_dump\" byl nalezen \"%s\",\n" +#~ "který ale není stejné verze jako %s.\n" +#~ "Zkontrolujte vaši instalaci." + +#~ msgid "" +#~ "The program \"pg_dump\" is needed by %s but was not found in the\n" +#~ "same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Program \"pg_dump\" je potřebný pro %s, ale nebyl nalezen ve stejném\n" +#~ "adresáři jako \"%s\".\n" +#~ "Zkontrolujte vaši instalaci." + +#~ msgid "Report bugs to .\n" +#~ msgstr "Oznámení o chybách zasílejte na .\n" + +#~ msgid "internal error -- neither th nor fh specified in tarReadRaw()" +#~ msgstr "interní chyba -- ani th ani fh nespecifikován v tarReadRaw()" + +#~ msgid "connection needs password" +#~ msgstr "spojení vyžaduje heslo" + +#~ msgid "could not reconnect to database: %s" +#~ msgstr "nelze znovu navázat spojení s databází: %s" + +#~ msgid "could not reconnect to database" +#~ msgstr "nelze znovu navázat spojení s databází" + +#~ msgid "connecting to database \"%s\" as user \"%s\"" +#~ msgstr "připojuji se k databázi \"%s\" jako uživatel \"%s\"" + +#~ msgid "ftell mismatch with expected position -- ftell used" +#~ msgstr "ftell neodpovídá očekávané pozici -- použit ftell" + +#~ msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +#~ msgstr "v archivu nelze najít blok ID %d -- možná kvůli out-of-order restore požadavku, který nemohl být vyřízen kvůli chybějícím datovým offsetům v archivu" diff --git a/src/bin/pg_dump/po/de.po b/src/bin/pg_dump/po/de.po new file mode 100644 index 000000000000..a0fb38612e03 --- /dev/null +++ b/src/bin/pg_dump/po/de.po @@ -0,0 +1,2727 @@ +# German message translation file for pg_dump and friends +# Peter Eisentraut , 2001 - 2021. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 08:48+0000\n" +"PO-Revision-Date: 2021-05-14 14:38+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ungültige Programmdatei »%s«" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "konnte Programmdatei »%s« nicht lesen" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "konnte kein »%s« zum Ausführen finden" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" + +#: ../../common/exec.c:409 parallel.c:1614 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() fehlgeschlagen: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "Befehl ist nicht ausführbar" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "Befehl nicht gefunden" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "Kindprozess hat mit Code %d beendet" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "Kindprozess wurde durch Ausnahme 0x%X beendet" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "Kindprozess wurde von Signal %d beendet: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "Kindprozess hat mit unbekanntem Status %d beendet" + +#: common.c:124 +#, c-format +msgid "reading extensions" +msgstr "lese Erweiterungen" + +#: common.c:128 +#, c-format +msgid "identifying extension members" +msgstr "identifiziere Erweiterungselemente" + +#: common.c:131 +#, c-format +msgid "reading schemas" +msgstr "lese Schemas" + +#: common.c:141 +#, c-format +msgid "reading user-defined tables" +msgstr "lese benutzerdefinierte Tabellen" + +#: common.c:148 +#, c-format +msgid "reading user-defined functions" +msgstr "lese benutzerdefinierte Funktionen" + +#: common.c:153 +#, c-format +msgid "reading user-defined types" +msgstr "lese benutzerdefinierte Typen" + +#: common.c:158 +#, c-format +msgid "reading procedural languages" +msgstr "lese prozedurale Sprachen" + +#: common.c:161 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "lese benutzerdefinierte Aggregatfunktionen" + +#: common.c:164 +#, c-format +msgid "reading user-defined operators" +msgstr "lese benutzerdefinierte Operatoren" + +#: common.c:168 +#, c-format +msgid "reading user-defined access methods" +msgstr "lese benutzerdefinierte Zugriffsmethoden" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator classes" +msgstr "lese benutzerdefinierte Operatorklassen" + +#: common.c:174 +#, c-format +msgid "reading user-defined operator families" +msgstr "lese benutzerdefinierte Operatorfamilien" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "lese benutzerdefinierte Textsuche-Parser" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search templates" +msgstr "lese benutzerdefinierte Textsuche-Templates" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "lese benutzerdefinierte Textsuchewörterbücher" + +#: common.c:186 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "lese benutzerdefinierte Textsuchekonfigurationen" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "lese benutzerdefinierte Fremddaten-Wrapper" + +#: common.c:192 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "lese benutzerdefinierte Fremdserver" + +#: common.c:195 +#, c-format +msgid "reading default privileges" +msgstr "lese Vorgabeprivilegien" + +#: common.c:198 +#, c-format +msgid "reading user-defined collations" +msgstr "lese benutzerdefinierte Sortierfolgen" + +#: common.c:202 +#, c-format +msgid "reading user-defined conversions" +msgstr "lese benutzerdefinierte Konversionen" + +#: common.c:205 +#, c-format +msgid "reading type casts" +msgstr "lese Typumwandlungen" + +#: common.c:208 +#, c-format +msgid "reading transforms" +msgstr "lese Transformationen" + +#: common.c:211 +#, c-format +msgid "reading table inheritance information" +msgstr "lese Tabellenvererbungsinformationen" + +#: common.c:214 +#, c-format +msgid "reading event triggers" +msgstr "lese Ereignistrigger" + +#: common.c:218 +#, c-format +msgid "finding extension tables" +msgstr "finde Erweiterungstabellen" + +#: common.c:222 +#, c-format +msgid "finding inheritance relationships" +msgstr "fine Vererbungsbeziehungen" + +#: common.c:225 +#, c-format +msgid "reading column info for interesting tables" +msgstr "lese Spalteninfo für interessante Tabellen" + +#: common.c:228 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "markiere vererbte Spalten in abgeleiteten Tabellen" + +#: common.c:231 +#, c-format +msgid "reading indexes" +msgstr "lese Indexe" + +#: common.c:234 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "markiere Indexe in partitionierten Tabellen" + +#: common.c:237 +#, c-format +msgid "reading extended statistics" +msgstr "lese erweiterte Statistiken" + +#: common.c:240 +#, c-format +msgid "reading constraints" +msgstr "lese Constraints" + +#: common.c:243 +#, c-format +msgid "reading triggers" +msgstr "lese Trigger" + +#: common.c:246 +#, c-format +msgid "reading rewrite rules" +msgstr "lese Umschreiberegeln" + +#: common.c:249 +#, c-format +msgid "reading policies" +msgstr "lese Policies" + +#: common.c:252 +#, c-format +msgid "reading publications" +msgstr "lese Publikationen" + +#: common.c:257 +#, c-format +msgid "reading publication membership" +msgstr "lese Publikationsmitgliedschaft" + +#: common.c:260 +#, c-format +msgid "reading subscriptions" +msgstr "lese Subskriptionen" + +#: common.c:338 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "ungültige Anzahl Eltern %d für Tabelle »%s«" + +#: common.c:1100 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "Sanity-Check fehlgeschlagen, Eltern-OID %u von Tabelle »%s« (OID %u) nicht gefunden" + +#: common.c:1142 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "konnte numerisches Array »%s« nicht parsen: zu viele Zahlen" + +#: common.c:1157 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "ungültiger Komprimierungscode: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "nicht mit zlib-Unterstützung gebaut" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "konnte Komprimierungsbibliothek nicht initialisieren: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "konnte Komprimierungsstrom nicht schließen: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "konnte Daten nicht komprimieren: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "konnte Daten nicht dekomprimieren: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "konnte Komprimierungsbibliothek nicht schließen: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:551 pg_backup_tar.c:554 +#, c-format +msgid "could not read from input file: %s" +msgstr "konnte nicht aus Eingabedatei lesen: %s" + +#: compress_io.c:623 pg_backup_custom.c:643 pg_backup_directory.c:552 +#: pg_backup_tar.c:787 pg_backup_tar.c:810 +#, c-format +msgid "could not read from input file: end of file" +msgstr "konnte nicht aus Eingabedatei lesen: Dateiende" + +#: parallel.c:254 +#, c-format +msgid "%s() failed: error code %d" +msgstr "%s() fehlgeschlagen: Fehlercode %d" + +#: parallel.c:964 +#, c-format +msgid "could not create communication channels: %m" +msgstr "konnte Kommunikationskanäle nicht erzeugen: %m" + +#: parallel.c:1021 +#, c-format +msgid "could not create worker process: %m" +msgstr "konnte Arbeitsprozess nicht erzeugen: %m" + +#: parallel.c:1151 +#, c-format +msgid "unrecognized command received from leader: \"%s\"" +msgstr "unbekannter Befehl vom Leader-Prozess empfangen: »%s«" + +#: parallel.c:1194 parallel.c:1432 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "ungültige Nachricht vom Arbeitsprozess empfangen: »%s«" + +#: parallel.c:1326 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"konnte Sperre für Relation »%s« nicht setzen\n" +"Das bedeutet meistens, dass jemand eine ACCESS-EXCLUSIVE-Sperre auf die Tabelle gesetzt hat, nachdem der pg-dump-Elternprozess die anfängliche ACCESS-SHARE-Sperre gesetzt hatte." + +#: parallel.c:1415 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "ein Arbeitsprozess endete unerwartet" + +#: parallel.c:1537 parallel.c:1655 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "konnte nicht in den Kommunikationskanal schreiben: %m" + +#: parallel.c:1739 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: konnte Socket nicht erzeugen: Fehlercode %d" + +#: parallel.c:1750 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: konnte nicht binden: Fehlercode %d" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: konnte nicht auf Socket hören: Fehlercode %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: %s() failed: error code %d" +msgstr "pgpipe: %s() fehlgeschlagen: Fehlercode %d" + +#: parallel.c:1775 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: konnte zweites Socket nicht erzeugen: Fehlercode %d" + +#: parallel.c:1784 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: konnte Socket nicht verbinden: Fehlercode %d" + +#: parallel.c:1793 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: konnte Verbindung nicht annehmen: Fehlercode %d" + +#: pg_backup_archiver.c:278 pg_backup_archiver.c:1577 +#, c-format +msgid "could not close output file: %m" +msgstr "konnte Ausgabedatei nicht schließen: %m" + +#: pg_backup_archiver.c:322 pg_backup_archiver.c:326 +#, c-format +msgid "archive items not in correct section order" +msgstr "Archivelemente nicht in richtiger Abschnittsreihenfolge" + +#: pg_backup_archiver.c:332 +#, c-format +msgid "unexpected section code %d" +msgstr "unerwarteter Abschnittscode %d" + +#: pg_backup_archiver.c:369 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "parallele Wiederherstellung wird von diesem Archivdateiformat nicht unterstützt" + +#: pg_backup_archiver.c:373 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "parallele Wiederherstellung wird mit Archiven, die mit pg_dump vor 8.0 erstellt worden sind, nicht unterstützt" + +#: pg_backup_archiver.c:391 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "kann komprimiertes Archiv nicht wiederherstellen (Komprimierung in dieser Installation nicht unterstützt)" + +#: pg_backup_archiver.c:408 +#, c-format +msgid "connecting to database for restore" +msgstr "verbinde mit der Datenbank zur Wiederherstellung" + +#: pg_backup_archiver.c:410 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "direkte Datenbankverbindungen sind in Archiven vor Version 1.3 nicht unterstützt" + +#: pg_backup_archiver.c:453 +#, c-format +msgid "implied data-only restore" +msgstr "implizit werden nur Daten wiederhergestellt" + +#: pg_backup_archiver.c:519 +#, c-format +msgid "dropping %s %s" +msgstr "entferne %s %s" + +#: pg_backup_archiver.c:614 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "konnte nicht bestimmen, wo IF EXISTS in die Anweisung »%s« eingefügt werden soll" + +#: pg_backup_archiver.c:770 pg_backup_archiver.c:772 +#, c-format +msgid "warning from original dump file: %s" +msgstr "Warnung aus der ursprünglichen Ausgabedatei: %s" + +#: pg_backup_archiver.c:787 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "erstelle %s »%s.%s«" + +#: pg_backup_archiver.c:790 +#, c-format +msgid "creating %s \"%s\"" +msgstr "erstelle %s »%s«" + +#: pg_backup_archiver.c:840 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "verbinde mit neuer Datenbank »%s«" + +#: pg_backup_archiver.c:867 +#, c-format +msgid "processing %s" +msgstr "verarbeite %s" + +#: pg_backup_archiver.c:887 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "verarbeite Daten für Tabelle »%s.%s«" + +#: pg_backup_archiver.c:949 +#, c-format +msgid "executing %s %s" +msgstr "führe %s %s aus" + +#: pg_backup_archiver.c:988 +#, c-format +msgid "disabling triggers for %s" +msgstr "schalte Trigger für %s aus" + +#: pg_backup_archiver.c:1014 +#, c-format +msgid "enabling triggers for %s" +msgstr "schalte Trigger für %s ein" + +#: pg_backup_archiver.c:1042 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "interner Fehler -- WriteData kann nicht außerhalb des Kontexts einer DataDumper-Routine aufgerufen werden" + +#: pg_backup_archiver.c:1225 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "Large-Object-Ausgabe im gewählten Format nicht unterstützt" + +#: pg_backup_archiver.c:1283 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "%d Large Object wiederhergestellt" +msgstr[1] "%d Large Objects wiederhergestellt" + +#: pg_backup_archiver.c:1304 pg_backup_tar.c:730 +#, c-format +msgid "restoring large object with OID %u" +msgstr "Wiederherstellung von Large Object mit OID %u" + +#: pg_backup_archiver.c:1316 +#, c-format +msgid "could not create large object %u: %s" +msgstr "konnte Large Object %u nicht erstellen: %s" + +#: pg_backup_archiver.c:1321 pg_dump.c:3693 +#, c-format +msgid "could not open large object %u: %s" +msgstr "konnte Large Object %u nicht öffnen: %s" + +#: pg_backup_archiver.c:1377 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht öffnen: %m" + +#: pg_backup_archiver.c:1405 +#, c-format +msgid "line ignored: %s" +msgstr "Zeile ignoriert: %s" + +#: pg_backup_archiver.c:1412 +#, c-format +msgid "could not find entry for ID %d" +msgstr "konnte Eintrag für ID %d nicht finden" + +#: pg_backup_archiver.c:1435 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "konnte Inhaltsverzeichnisdatei nicht schließen: %m" + +#: pg_backup_archiver.c:1549 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:485 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "konnte Ausgabedatei »%s« nicht öffnen: %m" + +#: pg_backup_archiver.c:1551 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "konnte Ausgabedatei nicht öffnen: %m" + +#: pg_backup_archiver.c:1644 +#, c-format +msgid "wrote %zu byte of large object data (result = %d)" +msgid_plural "wrote %zu bytes of large object data (result = %d)" +msgstr[0] "%zu Byte Large-Object-Daten geschrieben (Ergebnis = %d)" +msgstr[1] "%zu Bytes Large-Object-Daten geschrieben (Ergebnis = %d)" + +#: pg_backup_archiver.c:1650 +#, c-format +msgid "could not write to large object: %s" +msgstr "konnte Large Object nicht schreiben: %s" + +#: pg_backup_archiver.c:1740 +#, c-format +msgid "while INITIALIZING:" +msgstr "in Phase INITIALIZING:" + +#: pg_backup_archiver.c:1745 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "in Phase PROCESSING TOC:" + +#: pg_backup_archiver.c:1750 +#, c-format +msgid "while FINALIZING:" +msgstr "in Phase FINALIZING:" + +#: pg_backup_archiver.c:1755 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "in Inhaltsverzeichniseintrag %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1831 +#, c-format +msgid "bad dumpId" +msgstr "ungültige DumpId" + +#: pg_backup_archiver.c:1852 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "ungültige Tabellen-DumpId für »TABLE DATA«-Eintrag" + +#: pg_backup_archiver.c:1944 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "unerwartete Datenoffsetmarkierung %d" + +#: pg_backup_archiver.c:1957 +#, c-format +msgid "file offset in dump file is too large" +msgstr "Dateioffset in Dumpdatei ist zu groß" + +#: pg_backup_archiver.c:2095 pg_backup_archiver.c:2105 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "Verzeichnisname zu lang: »%s«" + +#: pg_backup_archiver.c:2113 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "Verzeichnis »%s« scheint kein gültiges Archiv zu sein (»toc.dat« existiert nicht)" + +#: pg_backup_archiver.c:2121 pg_backup_custom.c:173 pg_backup_custom.c:807 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "konnte Eingabedatei »%s« nicht öffnen: %m" + +#: pg_backup_archiver.c:2128 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "konnte Eingabedatei nicht öffnen: %m" + +#: pg_backup_archiver.c:2134 +#, c-format +msgid "could not read input file: %m" +msgstr "konnte Eingabedatei nicht lesen: %m" + +#: pg_backup_archiver.c:2136 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "Eingabedatei ist zu kurz (gelesen: %lu, erwartet: 5)" + +#: pg_backup_archiver.c:2168 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "Eingabedatei ist anscheinend ein Dump im Textformat. Bitte verwenden Sie psql." + +#: pg_backup_archiver.c:2174 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "Eingabedatei scheint kein gültiges Archiv zu sein (zu kurz?)" + +#: pg_backup_archiver.c:2180 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "Eingabedatei scheint kein gültiges Archiv zu sein" + +#: pg_backup_archiver.c:2189 +#, c-format +msgid "could not close input file: %m" +msgstr "konnte Eingabedatei nicht schließen: %m" + +#: pg_backup_archiver.c:2306 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "nicht erkanntes Dateiformat »%d«" + +#: pg_backup_archiver.c:2388 pg_backup_archiver.c:4422 +#, c-format +msgid "finished item %d %s %s" +msgstr "Element %d %s %s abgeschlossen" + +#: pg_backup_archiver.c:2392 pg_backup_archiver.c:4435 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "Arbeitsprozess fehlgeschlagen: Code %d" + +#: pg_backup_archiver.c:2512 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "ID %d des Eintrags außerhalb des gültigen Bereichs -- vielleicht ein verfälschtes Inhaltsverzeichnis" + +#: pg_backup_archiver.c:2579 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "Wiederherstellung von Tabellen mit WITH OIDS wird nicht mehr unterstützt" + +#: pg_backup_archiver.c:2663 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "nicht erkannte Kodierung »%s«" + +#: pg_backup_archiver.c:2668 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "ungültiger ENCODING-Eintrag: %s" + +#: pg_backup_archiver.c:2686 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "ungültiger STDSTRINGS-Eintrag: %s" + +#: pg_backup_archiver.c:2717 +#, c-format +msgid "invalid TOASTCOMPRESSION item: %s" +msgstr "ungültiger TOASTCOMPRESSION-Eintrag: %s" + +#: pg_backup_archiver.c:2734 +#, c-format +msgid "schema \"%s\" not found" +msgstr "Schema »%s« nicht gefunden" + +#: pg_backup_archiver.c:2741 +#, c-format +msgid "table \"%s\" not found" +msgstr "Tabelle »%s« nicht gefunden" + +#: pg_backup_archiver.c:2748 +#, c-format +msgid "index \"%s\" not found" +msgstr "Index »%s« nicht gefunden" + +#: pg_backup_archiver.c:2755 +#, c-format +msgid "function \"%s\" not found" +msgstr "Funktion »%s« nicht gefunden" + +#: pg_backup_archiver.c:2762 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "Trigger »%s« nicht gefunden" + +#: pg_backup_archiver.c:3160 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "konnte Sitzungsbenutzer nicht auf »%s« setzen: %s" + +#: pg_backup_archiver.c:3292 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "konnte search_path nicht auf »%s« setzen: %s" + +#: pg_backup_archiver.c:3354 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "konnte default_tablespace nicht auf »%s« setzen: %s" + +#: pg_backup_archiver.c:3399 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "konnte default_table_access_method nicht setzen: %s" + +#: pg_backup_archiver.c:3491 pg_backup_archiver.c:3649 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "kann Eigentümer für Objekttyp »%s« nicht setzen" + +#: pg_backup_archiver.c:3753 +#, c-format +msgid "did not find magic string in file header" +msgstr "magische Zeichenkette im Dateikopf nicht gefunden" + +#: pg_backup_archiver.c:3767 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "nicht unterstützte Version (%d.%d) im Dateikopf" + +#: pg_backup_archiver.c:3772 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "Prüfung der Integer-Größe (%lu) fehlgeschlagen" + +#: pg_backup_archiver.c:3776 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "Archiv wurde auf einer Maschine mit größeren Integers erstellt; einige Operationen könnten fehlschlagen" + +#: pg_backup_archiver.c:3786 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "erwartetes Format (%d) ist nicht das gleiche wie das in der Datei gefundene (%d)" + +#: pg_backup_archiver.c:3801 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "Archiv ist komprimiert, aber diese Installation unterstützt keine Komprimierung -- keine Daten verfügbar" + +#: pg_backup_archiver.c:3819 +#, c-format +msgid "invalid creation date in header" +msgstr "ungültiges Erstellungsdatum im Kopf" + +#: pg_backup_archiver.c:3947 +#, c-format +msgid "processing item %d %s %s" +msgstr "verarbeite Element %d %s %s" + +#: pg_backup_archiver.c:4026 +#, c-format +msgid "entering main parallel loop" +msgstr "Eintritt in Hauptparallelschleife" + +#: pg_backup_archiver.c:4037 +#, c-format +msgid "skipping item %d %s %s" +msgstr "Element %d %s %s wird übersprungen" + +#: pg_backup_archiver.c:4046 +#, c-format +msgid "launching item %d %s %s" +msgstr "starte Element %d %s %s" + +#: pg_backup_archiver.c:4100 +#, c-format +msgid "finished main parallel loop" +msgstr "Hauptparallelschleife beendet" + +#: pg_backup_archiver.c:4136 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "verarbeite verpasstes Element %d %s %s" + +#: pg_backup_archiver.c:4741 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "Tabelle »%s« konnte nicht erzeugt werden, ihre Daten werden nicht wiederhergestellt werden" + +#: pg_backup_custom.c:376 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "ungültige OID für Large Object" + +#: pg_backup_custom.c:439 pg_backup_custom.c:505 pg_backup_custom.c:629 +#: pg_backup_custom.c:865 pg_backup_tar.c:1080 pg_backup_tar.c:1085 +#, c-format +msgid "error during file seek: %m" +msgstr "Fehler beim Suchen in Datei: %m" + +#: pg_backup_custom.c:478 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "Datenblock %d hat falsche Seek-Position" + +#: pg_backup_custom.c:495 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "unerkannter Datenblocktyp (%d) beim Suchen im Archiv gefunden" + +#: pg_backup_custom.c:517 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise wegen Wiederherstellung außer der Reihe, was nicht möglich ist, weil die Eingabedatei kein Suchen unterstützt" + +#: pg_backup_custom.c:522 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise beschädigtes Archiv" + +#: pg_backup_custom.c:529 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "unerwartete Block-ID (%d) beim Lesen der Daten gefunden -- erwartet wurde %d" + +#: pg_backup_custom.c:543 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "unerkannter Datenblocktyp %d beim Wiederherstellen des Archivs gefunden" + +#: pg_backup_custom.c:645 +#, c-format +msgid "could not read from input file: %m" +msgstr "konnte nicht aus Eingabedatei lesen: %m" + +#: pg_backup_custom.c:746 pg_backup_custom.c:798 pg_backup_custom.c:943 +#: pg_backup_tar.c:1083 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "konnte Positionszeiger in Archivdatei nicht ermitteln: %m" + +#: pg_backup_custom.c:762 pg_backup_custom.c:802 +#, c-format +msgid "could not close archive file: %m" +msgstr "konnte Archivdatei nicht schließen: %m" + +#: pg_backup_custom.c:785 +#, c-format +msgid "can only reopen input archives" +msgstr "nur Eingabearchive können neu geöffnet werden" + +#: pg_backup_custom.c:792 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "parallele Wiederherstellung aus der Standardeingabe wird nicht unterstützt" + +#: pg_backup_custom.c:794 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "parallele Wiederherstellung aus einer Datei, die kein Suchen ermöglicht, wird nicht unterstützt" + +#: pg_backup_custom.c:810 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "konnte Positionszeiger in Archivdatei nicht setzen: %m" + +#: pg_backup_custom.c:889 +#, c-format +msgid "compressor active" +msgstr "Kompressor ist aktiv" + +#: pg_backup_db.c:42 +#, c-format +msgid "could not get server_version from libpq" +msgstr "konnte server_version nicht von libpq ermitteln" + +#: pg_backup_db.c:53 pg_dumpall.c:1821 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "Version des Servers: %s; Version von %s: %s" + +#: pg_backup_db.c:55 pg_dumpall.c:1823 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "Abbruch wegen unpassender Serverversion" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "bereits mit einer Datenbank verbunden" + +#: pg_backup_db.c:132 pg_backup_db.c:182 pg_dumpall.c:1650 pg_dumpall.c:1761 +msgid "Password: " +msgstr "Passwort: " + +#: pg_backup_db.c:174 +#, c-format +msgid "could not connect to database" +msgstr "konnte nicht mit der Datenbank verbinden" + +#: pg_backup_db.c:191 +#, c-format +msgid "reconnection failed: %s" +msgstr "Wiederverbindung fehlgeschlagen: %s" + +#: pg_backup_db.c:194 pg_backup_db.c:269 pg_dumpall.c:1681 pg_dumpall.c:1771 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:276 pg_dumpall.c:1884 pg_dumpall.c:1907 +#, c-format +msgid "query failed: %s" +msgstr "Anfrage fehlgeschlagen: %s" + +#: pg_backup_db.c:278 pg_dumpall.c:1885 pg_dumpall.c:1908 +#, c-format +msgid "query was: %s" +msgstr "Anfrage war: %s" + +#: pg_backup_db.c:319 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "Anfrage ergab %d Zeile anstatt einer: %s" +msgstr[1] "Anfrage ergab %d Zeilen anstatt einer: %s" + +#: pg_backup_db.c:355 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %sDie Anweisung war: %s" + +#: pg_backup_db.c:411 pg_backup_db.c:485 pg_backup_db.c:492 +msgid "could not execute query" +msgstr "konnte Anfrage nicht ausführen" + +#: pg_backup_db.c:464 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "Fehler in PQputCopyData: %s" + +#: pg_backup_db.c:513 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "Fehler in PQputCopyEnd: %s" + +#: pg_backup_db.c:519 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "COPY fehlgeschlagen für Tabelle »%s«: %s" + +#: pg_backup_db.c:525 pg_dump.c:2077 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "unerwartete zusätzliche Ergebnisse während COPY von Tabelle »%s«" + +#: pg_backup_db.c:537 +msgid "could not start database transaction" +msgstr "konnte Datenbanktransaktion nicht starten" + +#: pg_backup_db.c:545 +msgid "could not commit database transaction" +msgstr "konnte Datenbanktransaktion nicht beenden" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "kein Ausgabeverzeichnis angegeben" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "konnte nicht in Ausgabedatei schreiben: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "konnte Datendatei »%s« nicht schließen: %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "konnte Large-Object-Inhaltsverzeichnisdatei »%s« nicht zur Eingabe öffnen: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "ungültige Zeile in Large-Object-Inhaltsverzeichnisdatei »%s«: %s" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "Fehler beim Lesen von Large-Object-Inhaltsverzeichnisdatei »%s«" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "konnte Large-Object-Inhaltsverzeichnisdatei »%s« nicht schließen: %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "konnte nicht in Blobs-Inhaltsverzeichnisdatei schreiben" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "Dateiname zu lang: »%s«" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "dieses Format kann nicht gelesen werden" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht zur Ausgabe öffnen: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "konnte Inhaltsverzeichnisdatei nicht zur Ausgabe öffnen: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:352 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "Komprimierung ist im Tar-Format nicht unterstützt" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht zur Eingabe öffnen: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "konnte Inhaltsverzeichnisdatei nicht zur Eingabe öffnen: %m" + +#: pg_backup_tar.c:338 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "konnte Datei »%s« nicht im Archiv finden" + +#: pg_backup_tar.c:404 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "konnte keine temporären Dateinamen erzeugen: %m" + +#: pg_backup_tar.c:415 +#, c-format +msgid "could not open temporary file" +msgstr "konnte temporäre Datei nicht öffnen" + +#: pg_backup_tar.c:442 +#, c-format +msgid "could not close tar member" +msgstr "konnte Tar-Mitglied nicht schließen" + +#: pg_backup_tar.c:685 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "unerwartete Syntax der COPY-Anweisung: »%s«" + +#: pg_backup_tar.c:952 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "Large Object hat ungültige OID (%u)" + +#: pg_backup_tar.c:1099 +#, c-format +msgid "could not close temporary file: %m" +msgstr "konnte temporäre Datei nicht schließen: %m" + +#: pg_backup_tar.c:1108 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "tatsächliche Dateilänge (%s) stimmt nicht mit erwarteter Länge (%s) überein" + +#: pg_backup_tar.c:1165 pg_backup_tar.c:1196 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "konnte Kopf für Datei »%s« im Tar-Archiv nicht finden" + +#: pg_backup_tar.c:1183 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "Ausgabe der Daten in anderer Reihenfolge wird in diesem Archivformat nicht unterstützt: »%s« wird benötigt, aber es kommt vor »%s« in der Archivdatei." + +#: pg_backup_tar.c:1230 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "unvollständiger Tar-Dateikopf gefunden (%lu Byte)" +msgstr[1] "unvollständiger Tar-Dateikopf gefunden (%lu Bytes)" + +#: pg_backup_tar.c:1281 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "beschädigter Tar-Kopf in %s gefunden (%d erwartet, %d berechnet), Dateiposition %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "unbekannter Abschnittsname: »%s«" + +#: pg_backup_utils.c:55 pg_dump.c:623 pg_dump.c:640 pg_dumpall.c:339 +#: pg_dumpall.c:349 pg_dumpall.c:358 pg_dumpall.c:367 pg_dumpall.c:375 +#: pg_dumpall.c:389 pg_dumpall.c:465 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "on_exit_nicely-Slots aufgebraucht" + +#: pg_dump.c:549 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "Komprimierungsniveau muss im Bereich 0..9 sein" + +#: pg_dump.c:587 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits muss im Bereich -15..3 sein" + +#: pg_dump.c:610 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "Zeilen-pro-Insert muss im Bereich %d..%d sein" + +#: pg_dump.c:638 pg_dumpall.c:347 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_dump.c:659 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "Optionen -s/--schema-only und -a/--data-only können nicht zusammen verwendet werden" + +#: pg_dump.c:664 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "Optionen -s/--schema-only und --include-foreign-data können nicht zusammen verwendet werden" + +#: pg_dump.c:667 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "Option --include-foreign-data wird nicht mit paralleler Sicherung unterstützt" + +#: pg_dump.c:671 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "Optionen -c/--clean und -a/--data-only können nicht zusammen verwendet werden" + +#: pg_dump.c:676 pg_dumpall.c:382 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "Option --if-exists benötigt Option -c/--clean" + +#: pg_dump.c:683 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "Option --on-conflict-do-nothing benötigt Option --inserts, --rows-per-insert oder --column-inserts" + +#: pg_dump.c:705 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "Komprimierung ist in dieser Installation nicht verfügbar -- Archiv wird nicht komprimiert" + +#: pg_dump.c:726 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "ungültige Anzahl paralleler Jobs" + +#: pg_dump.c:730 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "parallele Sicherung wird nur vom Ausgabeformat »Verzeichnis« unterstützt" + +#: pg_dump.c:785 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Synchronisierte Snapshots werden von dieser Serverversion nicht unterstützt.\n" +"Verwenden Sie --no-synchronized-snapshots, wenn Sie keine synchronisierten\n" +"Snapshots benötigen." + +#: pg_dump.c:791 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Exportierte Snapshots werden in dieser Serverversion nicht unterstützt." + +#: pg_dump.c:803 +#, c-format +msgid "last built-in OID is %u" +msgstr "letzte eingebaute OID ist %u" + +#: pg_dump.c:812 +#, c-format +msgid "no matching schemas were found" +msgstr "keine passenden Schemas gefunden" + +#: pg_dump.c:826 +#, c-format +msgid "no matching tables were found" +msgstr "keine passenden Tabellen gefunden" + +#: pg_dump.c:848 +#, c-format +msgid "no matching extensions were found" +msgstr "keine passenden Erweiterungen gefunden" + +#: pg_dump.c:1020 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s gibt eine Datenbank als Textdatei oder in anderen Formaten aus.\n" +"\n" + +#: pg_dump.c:1021 pg_dumpall.c:618 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_dump.c:1022 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]... [DBNAME]\n" + +#: pg_dump.c:1024 pg_dumpall.c:621 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Allgemeine Optionen:\n" + +#: pg_dump.c:1025 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=DATEINAME Name der Ausgabedatei oder des -verzeichnisses\n" + +#: pg_dump.c:1026 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p Ausgabeformat (custom, d=Verzeichnis, tar,\n" +" plain text)\n" + +#: pg_dump.c:1028 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=NUM so viele parallele Jobs zur Sicherung verwenden\n" + +#: pg_dump.c:1029 pg_dumpall.c:623 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose »Verbose«-Modus\n" + +#: pg_dump.c:1030 pg_dumpall.c:624 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_dump.c:1031 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 Komprimierungsniveau für komprimierte Formate\n" + +#: pg_dump.c:1032 pg_dumpall.c:625 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " --lock-wait-timeout=ZEIT Abbruch nach ZEIT Warten auf Tabellensperre\n" + +#: pg_dump.c:1033 pg_dumpall.c:652 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_dump.c:1034 pg_dumpall.c:626 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_dump.c:1036 pg_dumpall.c:627 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Optionen die den Inhalt der Ausgabe kontrollieren:\n" + +#: pg_dump.c:1037 pg_dumpall.c:628 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only nur Daten ausgeben, nicht das Schema\n" + +#: pg_dump.c:1038 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs Large Objects mit ausgeben\n" + +#: pg_dump.c:1039 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs Large Objects nicht mit ausgeben\n" + +#: pg_dump.c:1040 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, --clean Datenbankobjekte vor der Wiedererstellung löschen\n" + +#: pg_dump.c:1041 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr "" +" -C, --create Anweisungen zum Erstellen der Datenbank in\n" +" Ausgabe einfügen\n" + +#: pg_dump.c:1042 +#, c-format +msgid " -e, --extension=PATTERN dump the specified extension(s) only\n" +msgstr " -e, --extension=MUSTER nur die angegebene(n) Erweiterung(en) ausgeben\n" + +#: pg_dump.c:1043 pg_dumpall.c:630 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=KODIERUNG Daten in Kodierung KODIERUNG ausgeben\n" + +#: pg_dump.c:1044 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=MUSTER nur das/die angegebene(n) Schema(s) ausgeben\n" + +#: pg_dump.c:1045 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=MUSTER das/die angegebene(n) Schema(s) NICHT ausgeben\n" + +#: pg_dump.c:1046 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner Wiederherstellung der Objekteigentümerschaft im\n" +" »plain text«-Format auslassen\n" + +#: pg_dump.c:1048 pg_dumpall.c:634 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only nur das Schema, nicht die Daten, ausgeben\n" + +#: pg_dump.c:1049 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, --superuser=NAME Superusername für »plain text«-Format\n" + +#: pg_dump.c:1050 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=MUSTER nur die angegebene(n) Tabelle(n) ausgeben\n" + +#: pg_dump.c:1051 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=MUSTER die angegebene(n) Tabelle(n) NICHT ausgeben\n" + +#: pg_dump.c:1052 pg_dumpall.c:637 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges Zugriffsprivilegien (grant/revoke) nicht ausgeben\n" + +#: pg_dump.c:1053 pg_dumpall.c:638 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade wird nur von Upgrade-Programmen verwendet\n" + +#: pg_dump.c:1054 pg_dumpall.c:639 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr "" +" --column-inserts Daten als INSERT-Anweisungen mit Spaltennamen\n" +" ausgeben\n" + +#: pg_dump.c:1055 pg_dumpall.c:640 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr "" +" --disable-dollar-quoting Dollar-Quoting abschalten, normales SQL-Quoting\n" +" verwenden\n" + +#: pg_dump.c:1056 pg_dumpall.c:641 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr "" +" --disable-triggers Trigger während der Datenwiederherstellung\n" +" abschalten\n" + +#: pg_dump.c:1057 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security Sicherheit auf Zeilenebene einschalten (nur Daten\n" +" ausgeben, auf die der Benutzer Zugriff hat)\n" + +#: pg_dump.c:1059 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " --exclude-table-data=MUSTER Daten der angegebenen Tabelle(n) NICHT ausgeben\n" + +#: pg_dump.c:1060 pg_dumpall.c:643 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=ZAHL Einstellung für extra_float_digits\n" + +#: pg_dump.c:1061 pg_dumpall.c:644 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists IF EXISTS verwenden, wenn Objekte gelöscht werden\n" + +#: pg_dump.c:1062 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=MUSTER\n" +" Daten von Fremdtabellen auf Fremdservern, die\n" +" mit MUSTER übereinstimmen, mit sichern\n" + +#: pg_dump.c:1065 pg_dumpall.c:645 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr " --inserts Daten als INSERT-Anweisungen statt COPY ausgeben\n" + +#: pg_dump.c:1066 pg_dumpall.c:646 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root Partitionen über die Wurzeltabelle laden\n" + +#: pg_dump.c:1067 pg_dumpall.c:647 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments Kommentare nicht ausgeben\n" + +#: pg_dump.c:1068 pg_dumpall.c:648 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications Publikationen nicht ausgeben\n" + +#: pg_dump.c:1069 pg_dumpall.c:650 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels Security-Label-Zuweisungen nicht ausgeben\n" + +#: pg_dump.c:1070 pg_dumpall.c:651 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions Subskriptionen nicht ausgeben\n" + +#: pg_dump.c:1071 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr "" +" --no-synchronized-snapshots keine synchronisierten Snapshots in parallelen\n" +" Jobs verwenden\n" + +#: pg_dump.c:1072 pg_dumpall.c:653 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces Tablespace-Zuordnungen nicht ausgeben\n" + +#: pg_dump.c:1073 +#, c-format +msgid " --no-toast-compression do not dump TOAST compression methods\n" +msgstr " --no-toast-compression TOAST-Komprimierungsmethoden nicht ausgeben\n" + +#: pg_dump.c:1074 pg_dumpall.c:654 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data Daten in ungeloggten Tabellen nicht ausgeben\n" + +#: pg_dump.c:1075 pg_dumpall.c:655 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing INSERT-Befehle mit ON CONFLICT DO NOTHING ausgeben\n" + +#: pg_dump.c:1076 pg_dumpall.c:656 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr "" +" --quote-all-identifiers alle Bezeichner in Anführungszeichen, selbst wenn\n" +" kein Schlüsselwort\n" + +#: pg_dump.c:1077 pg_dumpall.c:657 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=ANZAHL Anzahl Zeilen pro INSERT; impliziert --inserts\n" + +#: pg_dump.c:1078 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=ABSCHNITT angegebenen Abschnitt ausgeben (pre-data, data\n" +" oder post-data)\n" + +#: pg_dump.c:1079 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr " --serializable-deferrable warten bis der Dump ohne Anomalien laufen kann\n" + +#: pg_dump.c:1080 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT angegebenen Snapshot für den Dump verwenden\n" + +#: pg_dump.c:1081 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names Tabellen- oder Schemamuster müssen auf mindestens\n" +" je ein Objekt passen\n" + +#: pg_dump.c:1083 pg_dumpall.c:658 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" SET SESSION AUTHORIZATION Befehle statt ALTER\n" +" OWNER Befehle verwenden, um Eigentümerschaft zu\n" +" setzen\n" + +#: pg_dump.c:1087 pg_dumpall.c:662 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Verbindungsoptionen:\n" + +#: pg_dump.c:1088 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=DBNAME auszugebende Datenbank\n" + +#: pg_dump.c:1089 pg_dumpall.c:664 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" + +#: pg_dump.c:1090 pg_dumpall.c:666 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT Portnummer des Datenbankservers\n" + +#: pg_dump.c:1091 pg_dumpall.c:667 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME Datenbankbenutzername\n" + +#: pg_dump.c:1092 pg_dumpall.c:668 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password niemals nach Passwort fragen\n" + +#: pg_dump.c:1093 pg_dumpall.c:669 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password nach Passwort fragen (sollte automatisch geschehen)\n" + +#: pg_dump.c:1094 pg_dumpall.c:670 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROLLENNAME vor der Ausgabe SET ROLE ausführen\n" + +#: pg_dump.c:1096 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Wenn kein Datenbankname angegeben wird, dann wird die Umgebungsvariable\n" +"PGDATABASE verwendet.\n" +"\n" + +#: pg_dump.c:1098 pg_dumpall.c:674 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Berichten Sie Fehler an <%s>.\n" + +#: pg_dump.c:1099 pg_dumpall.c:675 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: pg_dump.c:1118 pg_dumpall.c:500 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "ungültige Clientkodierung »%s« angegeben" + +#: pg_dump.c:1264 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Synchronisierte Snapshots auf Standby-Servern werden von dieser Serverversion nicht unterstützt.\n" +"Verwenden Sie --no-synchronized-snapshots, wenn Sie keine synchronisierten\n" +"Snapshots benötigen." + +#: pg_dump.c:1333 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "ungültiges Ausgabeformat »%s« angegeben" + +#: pg_dump.c:1371 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "keine passenden Schemas für Muster »%s« gefunden" + +#: pg_dump.c:1418 +#, c-format +msgid "no matching extensions were found for pattern \"%s\"" +msgstr "keine passenden Erweiterungen für Muster »%s« gefunden" + +#: pg_dump.c:1465 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "keine passenden Fremdserver für Muster »%s« gefunden" + +#: pg_dump.c:1528 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "keine passenden Tabellen für Muster »%s« gefunden" + +#: pg_dump.c:1951 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "gebe Inhalt der Tabelle »%s.%s« aus" + +#: pg_dump.c:2058 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Ausgabe des Inhalts der Tabelle »%s« fehlgeschlagen: PQgetCopyData() fehlgeschlagen." + +#: pg_dump.c:2059 pg_dump.c:2069 +#, c-format +msgid "Error message from server: %s" +msgstr "Fehlermeldung vom Server: %s" + +#: pg_dump.c:2060 pg_dump.c:2070 +#, c-format +msgid "The command was: %s" +msgstr "Die Anweisung war: %s" + +#: pg_dump.c:2068 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Ausgabe des Inhalts der Tabelle »%s« fehlgeschlagen: PQgetResult() fehlgeschlagen." + +#: pg_dump.c:2828 +#, c-format +msgid "saving database definition" +msgstr "sichere Datenbankdefinition" + +#: pg_dump.c:3300 +#, c-format +msgid "saving encoding = %s" +msgstr "sichere Kodierung = %s" + +#: pg_dump.c:3325 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "sichere standard_conforming_strings = %s" + +#: pg_dump.c:3364 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "konnte Ergebnis von current_schemas() nicht interpretieren" + +#: pg_dump.c:3383 +#, c-format +msgid "saving search_path = %s" +msgstr "sichere search_path = %s" + +#: pg_dump.c:3436 +#, c-format +msgid "saving default_toast_compression = %s" +msgstr "sichere default_toast_compression = %s" + +#: pg_dump.c:3475 +#, c-format +msgid "reading large objects" +msgstr "lese Large Objects" + +#: pg_dump.c:3657 +#, c-format +msgid "saving large objects" +msgstr "sichere Large Objects" + +#: pg_dump.c:3703 +#, c-format +msgid "error reading large object %u: %s" +msgstr "Fehler beim Lesen von Large Object %u: %s" + +#: pg_dump.c:3755 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "lese Einstellung von Sicherheit auf Zeilenebene für Tabelle »%s.%s«" + +#: pg_dump.c:3786 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "lese Policys von Tabelle »%s.%s«" + +#: pg_dump.c:3938 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "unerwarteter Policy-Befehlstyp: %c" + +#: pg_dump.c:4092 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "Eigentümer der Publikation »%s« scheint ungültig zu sein" + +#: pg_dump.c:4384 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "Subskriptionen werden nicht ausgegeben, weil der aktuelle Benutzer kein Superuser ist" + +#: pg_dump.c:4455 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "Eigentümer der Subskription »%s« scheint ungültig zu sein" + +#: pg_dump.c:4498 +#, c-format +msgid "could not parse subpublications array" +msgstr "konnte subpublications-Array nicht interpretieren" + +#: pg_dump.c:4856 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "konnte Erweiterung, zu der %s %s gehört, nicht finden" + +#: pg_dump.c:4988 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "Eigentümer des Schemas »%s« scheint ungültig zu sein" + +#: pg_dump.c:5011 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "Schema mit OID %u existiert nicht" + +#: pg_dump.c:5340 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "Eigentümer des Datentypen »%s« scheint ungültig zu sein" + +#: pg_dump.c:5424 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "Eigentümer des Operatoren »%s« scheint ungültig zu sein" + +#: pg_dump.c:5723 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "Eigentümer der Operatorklasse »%s« scheint ungültig zu sein" + +#: pg_dump.c:5806 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "Eigentümer der Operatorfamilie »%s« scheint ungültig zu sein" + +#: pg_dump.c:5974 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "Eigentümer der Aggregatfunktion »%s« scheint ungültig zu sein" + +#: pg_dump.c:6233 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "Eigentümer der Funktion »%s« scheint ungültig zu sein" + +#: pg_dump.c:7060 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "Eigentümer der Tabelle »%s« scheint ungültig zu sein" + +#: pg_dump.c:7102 pg_dump.c:17493 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von Sequenz mit OID %u nicht gefunden" + +#: pg_dump.c:7241 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "lese Indexe von Tabelle »%s.%s«" + +#: pg_dump.c:7655 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "lese Fremdschlüssel-Constraints von Tabelle »%s.%s«" + +#: pg_dump.c:7934 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von pg_rewrite-Eintrag mit OID %u nicht gefunden" + +#: pg_dump.c:8017 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "lese Trigger von Tabelle »%s.%s«" + +#: pg_dump.c:8150 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "Anfrage ergab NULL als Name der Tabelle auf die sich Fremdschlüssel-Trigger »%s« von Tabelle »%s« bezieht (OID der Tabelle: %u)" + +#: pg_dump.c:8700 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "finde Spalten und Typen von Tabelle »%s.%s«" + +#: pg_dump.c:8824 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "ungültige Spaltennummerierung in Tabelle »%s«" + +#: pg_dump.c:8863 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "finde DEFAULT-Ausdrücke von Tabelle »%s.%s«" + +#: pg_dump.c:8885 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "ungültiger adnum-Wert %d für Tabelle »%s«" + +#: pg_dump.c:8978 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "finde Check-Constraints für Tabelle »%s.%s«" + +#: pg_dump.c:9027 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "%d Check-Constraint für Tabelle %s erwartet, aber %d gefunden" +msgstr[1] "%d Check-Constraints für Tabelle %s erwartet, aber %d gefunden" + +#: pg_dump.c:9031 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Die Systemkataloge sind wahrscheinlich verfälscht.)" + +#: pg_dump.c:10616 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "typtype des Datentypen »%s« scheint ungültig zu sein" + +#: pg_dump.c:11968 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "unsinniger Wert in proargmodes-Array" + +#: pg_dump.c:12275 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "konnte proallargtypes-Array nicht interpretieren" + +#: pg_dump.c:12291 +#, c-format +msgid "could not parse proargmodes array" +msgstr "konnte proargmodes-Array nicht interpretieren" + +#: pg_dump.c:12305 +#, c-format +msgid "could not parse proargnames array" +msgstr "konnte proargnames-Array nicht interpretieren" + +#: pg_dump.c:12315 +#, c-format +msgid "could not parse proconfig array" +msgstr "konnte proconfig-Array nicht interpretieren" + +#: pg_dump.c:12395 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "ungültiger provolatile-Wert für Funktion »%s«" + +#: pg_dump.c:12445 pg_dump.c:14396 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "ungültiger proparallel-Wert für Funktion »%s«" + +#: pg_dump.c:12584 pg_dump.c:12693 pg_dump.c:12700 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "konnte Funktionsdefinition für Funktion mit OID %u nicht finden" + +#: pg_dump.c:12623 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "unsinniger Wert in Feld pg_cast.castfunc oder pg_cast.castmethod" + +#: pg_dump.c:12626 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "unsinniger Wert in Feld pg_cast.castmethod" + +#: pg_dump.c:12719 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "unsinnige Transformationsdefinition, mindestens eins von trffromsql und trftosql sollte nicht null sein" + +#: pg_dump.c:12736 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "unsinniger Wert in Feld pg_transform.trffromsql" + +#: pg_dump.c:12757 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "unsinniger Wert in Feld pg_transform.trftosql" + +#: pg_dump.c:12909 +#, c-format +msgid "postfix operators are not supported anymore (operator \"%s\")" +msgstr "Postfix-Operatoren werden nicht mehr unterstützt (Operator »%s«)" + +#: pg_dump.c:13079 +#, c-format +msgid "could not find operator with OID %s" +msgstr "konnte Operator mit OID %s nicht finden" + +#: pg_dump.c:13147 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "ungültiger Typ »%c« für Zugriffsmethode »%s«" + +#: pg_dump.c:13901 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "unbekannter Sortierfolgen-Provider: %s" + +#: pg_dump.c:14315 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "unbekannter aggfinalmodify-Wert für Aggregat »%s«" + +#: pg_dump.c:14371 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "unbekannter aggmfinalmodify-Wert für Aggregat »%s«" + +#: pg_dump.c:15093 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "unbekannter Objekttyp in den Vorgabeprivilegien: %d" + +#: pg_dump.c:15111 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "konnte Vorgabe-ACL-Liste (%s) nicht interpretieren" + +#: pg_dump.c:15196 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "konnte initiale GRANT-ACL-Liste (%s) oder initiale REVOKE-ACL-Liste (%s) für Objekt »%s« (%s) nicht interpretieren" + +#: pg_dump.c:15204 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "konnte GRANT-ACL-Liste (%s) oder REVOKE-ACL-Liste (%s) für Objekt »%s« (%s) nicht interpretieren" + +#: pg_dump.c:15719 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte keine Daten" + +#: pg_dump.c:15722 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte mehr als eine Definition" + +#: pg_dump.c:15729 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "Definition der Sicht »%s« scheint leer zu sein (Länge null)" + +#: pg_dump.c:15813 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS wird nicht mehr unterstützt (Tabelle »%s«)" + +#: pg_dump.c:16680 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "ungültige Spaltennummer %d in Tabelle »%s«" + +#: pg_dump.c:16757 +#, c-format +msgid "could not parse index statistic columns" +msgstr "konnte Indexstatistikspalten nicht interpretieren" + +#: pg_dump.c:16759 +#, c-format +msgid "could not parse index statistic values" +msgstr "konnte Indexstatistikwerte nicht interpretieren" + +#: pg_dump.c:16761 +#, c-format +msgid "mismatched number of columns and values for index statistics" +msgstr "Anzahl Spalten und Werte für Indexstatistiken stimmt nicht überein" + +#: pg_dump.c:16978 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "fehlender Index für Constraint »%s«" + +#: pg_dump.c:17203 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "unbekannter Constraint-Typ: %c" + +#: pg_dump.c:17335 pg_dump.c:17558 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "Anfrage nach Daten der Sequenz %s ergab %d Zeile (erwartete 1)" +msgstr[1] "Anfrage nach Daten der Sequenz %s ergab %d Zeilen (erwartete 1)" + +#: pg_dump.c:17369 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "unbekannter Sequenztyp: %s" + +#: pg_dump.c:17656 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "unerwarteter tgtype-Wert: %d" + +#: pg_dump.c:17730 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "fehlerhafte Argumentzeichenkette (%s) für Trigger »%s« von Tabelle »%s«" + +#: pg_dump.c:17966 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "Anfrage nach Regel »%s« der Tabelle »%s« fehlgeschlagen: falsche Anzahl Zeilen zurückgegeben" + +#: pg_dump.c:18128 +#, c-format +msgid "could not find referenced extension %u" +msgstr "konnte referenzierte Erweiterung %u nicht finden" + +#: pg_dump.c:18219 +#, c-format +msgid "could not parse extension configuration array" +msgstr "konnte Erweiterungskonfigurations-Array nicht interpretieren" + +#: pg_dump.c:18221 +#, c-format +msgid "could not parse extension condition array" +msgstr "konnte Erweiterungsbedingungs-Array nicht interpretieren" + +#: pg_dump.c:18223 +#, c-format +msgid "mismatched number of configurations and conditions for extension" +msgstr "Anzahl Konfigurationen und Bedingungen für Erweiterung stimmt nicht überein" + +#: pg_dump.c:18355 +#, c-format +msgid "reading dependency data" +msgstr "lese Abhängigkeitsdaten" + +#: pg_dump.c:18448 +#, c-format +msgid "no referencing object %u %u" +msgstr "kein referenzierendes Objekt %u %u" + +#: pg_dump.c:18459 +#, c-format +msgid "no referenced object %u %u" +msgstr "kein referenziertes Objekt %u %u" + +#: pg_dump.c:18833 +#, c-format +msgid "could not parse reloptions array" +msgstr "konnte reloptions-Array nicht interpretieren" + +#: pg_dump_sort.c:411 +#, c-format +msgid "invalid dumpId %d" +msgstr "ungültige dumpId %d" + +#: pg_dump_sort.c:417 +#, c-format +msgid "invalid dependency %d" +msgstr "ungültige Abhängigkeit %d" + +#: pg_dump_sort.c:650 +#, c-format +msgid "could not identify dependency loop" +msgstr "konnte Abhängigkeitsschleife nicht bestimmen" + +#: pg_dump_sort.c:1221 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "Es gibt zirkuläre Fremdschlüssel-Constraints für diese Tabelle:" +msgstr[1] "Es gibt zirkuläre Fremdschlüssel-Constraints zwischen diesen Tabellen:" + +#: pg_dump_sort.c:1225 pg_dump_sort.c:1245 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1226 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Möglicherweise kann der Dump nur wiederhergestellt werden, wenn --disable-triggers verwendet wird oder die Constraints vorübergehend entfernt werden." + +#: pg_dump_sort.c:1227 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Führen Sie einen vollen Dump statt eines Dumps mit --data-only durch, um dieses Problem zu vermeiden." + +#: pg_dump_sort.c:1239 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "konnte Abhängigkeitsschleife zwischen diesen Elementen nicht auflösen:" + +#: pg_dumpall.c:200 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wird von %s benötigt, aber wurde nicht im\n" +"selben Verzeichnis wie »%s« gefunden.\n" +"Prüfen Sie Ihre Installation." + +#: pg_dumpall.c:205 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wurde von %s gefunden,\n" +"aber es hatte nicht die gleiche Version wie %s.\n" +"Prüfen Sie Ihre Installation." + +#: pg_dumpall.c:357 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "Option --exclude-database kann nicht zusammen mit -g/--globals-only, -r/--roles-only oder -t/--tablesspaces-only verwendet werden" + +#: pg_dumpall.c:366 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "Optionen -g/--globals-only und -r/--roles-only können nicht zusammen verwendet werden" + +#: pg_dumpall.c:374 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "Optionen -g/--globals-only und -t/--tablespaces-only können nicht zusammen verwendet werden" + +#: pg_dumpall.c:388 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "Optionen -r/--roles-only und -t/--tablespaces-only können nicht zusammen verwendet werden" + +#: pg_dumpall.c:449 pg_dumpall.c:1751 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "konnte nicht mit der Datenbank »%s« verbinden" + +#: pg_dumpall.c:463 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"konnte nicht mit Datenbank »postgres« oder »template1« verbinden\n" +"Bitte geben Sie eine alternative Datenbank an." + +#: pg_dumpall.c:617 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s gibt einen PostgreSQL-Datenbankcluster in eine SQL-Skriptdatei aus.\n" +"\n" + +#: pg_dumpall.c:619 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPTION]...\n" + +#: pg_dumpall.c:622 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=DATEINAME Name der Ausgabedatei\n" + +#: pg_dumpall.c:629 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, --clean Datenbanken vor der Wiedererstellung löschen\n" + +#: pg_dumpall.c:631 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, --globals-only nur globale Objekte ausgeben, keine Datenbanken\n" + +#: pg_dumpall.c:632 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr "" +" -O, --no-owner Wiederherstellung der Objekteigentümerschaft\n" +" auslassen\n" + +#: pg_dumpall.c:633 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr "" +" -r, --roles-only nur Rollen ausgeben, keine Datenbanken oder\n" +" Tablespaces\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, --superuser=NAME Superusername für den Dump\n" + +#: pg_dumpall.c:636 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr "" +" -t, --tablespaces-only nur Tablespaces ausgeben, keine Datenbanken oder\n" +" Rollen\n" + +#: pg_dumpall.c:642 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr "" +" --exclude-database=MUSTER Datenbanken deren Name mit MUSTER übereinstimmt\n" +" überspringen\n" + +#: pg_dumpall.c:649 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords Rollenpasswörter nicht mit ausgeben\n" + +#: pg_dumpall.c:663 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=VERBDG mit angegebenen Verbindungsparametern verbinden\n" + +#: pg_dumpall.c:665 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=DBNAME alternative Standarddatenbank\n" + +#: pg_dumpall.c:672 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"Wenn -f/--file nicht verwendet wird, dann wird das SQL-Skript auf die\n" +"Standardausgabe geschrieben.\n" +"\n" + +#: pg_dumpall.c:878 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "mit »pg_« anfangender Rollenname übersprungen (%s)" + +#: pg_dumpall.c:1279 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "konnte ACL-Zeichenkette (%s) für Tablespace »%s« nicht interpretieren" + +#: pg_dumpall.c:1496 +#, c-format +msgid "excluding database \"%s\"" +msgstr "Datenbank »%s« übersprungen" + +#: pg_dumpall.c:1500 +#, c-format +msgid "dumping database \"%s\"" +msgstr "Ausgabe der Datenbank »%s«" + +#: pg_dumpall.c:1532 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump für Datenbank »%s« fehlgeschlagen; beende" + +#: pg_dumpall.c:1541 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "konnte die Ausgabedatei »%s« nicht neu öffnen: %m" + +#: pg_dumpall.c:1585 +#, c-format +msgid "running \"%s\"" +msgstr "führe »%s« aus" + +#: pg_dumpall.c:1800 +#, c-format +msgid "could not get server version" +msgstr "konnte Version des Servers nicht ermitteln" + +#: pg_dumpall.c:1806 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "konnte Versionszeichenkette »%s« nicht entziffern" + +#: pg_dumpall.c:1878 pg_dumpall.c:1901 +#, c-format +msgid "executing %s" +msgstr "führe %s aus" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "entweder -d/--dbname oder -f/--file muss angegeben werden" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "Optionen -d/--dbname und -f/--file können nicht zusammen verwendet werden" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "Optionen -C/--create und -1/--single-transaction können nicht zusammen verwendet werden" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "maximale Anzahl paralleler Jobs ist %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "--single-transaction und mehrere Jobs können nicht zusammen verwendet werden" + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "unbekanntes Archivformat »%s«; bitte »c«, »d« oder »t« angeben" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "bei Wiederherstellung ignorierte Fehler: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s stellt eine PostgreSQL-Datenbank wieder her, die mit pg_dump\n" +"gesichert wurde.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [OPTION]... [DATEI]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=NAME mit angegebener Datenbank verbinden\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=DATEINAME Name der Ausgabedatei (- für stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, --format=c|d|t Format der Backup-Datei (sollte automatisch gehen)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list Inhaltsverzeichnis für dieses Archiv anzeigen\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose »Verbose«-Modus\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Optionen die die Wiederherstellung kontrollieren:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only nur Daten, nicht das Schema, wiederherstellen\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create Zieldatenbank erzeugen\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, --exit-on-error bei Fehler beenden, Voreinstellung ist fortsetzen\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=NAME benannten Index wiederherstellen\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr "" +" -j, --jobs=NUM so viele parallele Jobs zur Wiederherstellung\n" +" verwenden\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=DATEINAME\n" +" Inhaltsverzeichnis aus dieser Datei zur Auswahl oder\n" +" Sortierung der Ausgabe verwenden\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NAME nur Objekte in diesem Schema wiederherstellen\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, ---exclude-schema=NAME Objekte in diesem Schema nicht wiederherstellen\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NAME(args) benannte Funktion wiederherstellen\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only nur das Schema, nicht die Daten, wiederherstellen\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr " -S, --superuser=NAME Name des Superusers, um Trigger auszuschalten\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr "" +" -t, --table=NAME benannte Relation (Tabelle, Sicht, usw.)\n" +" wiederherstellen\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=NAME benannten Trigger wiederherstellen\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, --no-privileges Wiederherstellung der Zugriffsprivilegien auslassen\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction Wiederherstellung als eine einzige Transaktion\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security Sicherheit auf Zeilenebene einschalten\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments Kommentare nicht wiederherstellen\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables Daten für Tabellen, die nicht erzeugt werden\n" +" konnten, nicht wiederherstellen\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications Publikationen nicht wiederherstellen\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels Security-Labels nicht wiederherstellen\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions Subskriptionen nicht wiederherstellen\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces Tablespace-Zuordnungen nicht wiederherstellen\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=ABSCHNITT angegebenen Abschnitt wiederherstellen (pre-data,\n" +" data oder post-data)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROLLENNAME vor der Wiederherstellung SET ROLE ausführen\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"Die Optionen -I, -n, -N, -P, -t, -T und --section können kombiniert und mehrfach\n" +"angegeben werden, um mehrere Objekte auszuwählen.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"Wenn keine Eingabedatei angegeben ist, wird die Standardeingabe verwendet.\n" +"\n" diff --git a/src/bin/pg_dump/po/el.po b/src/bin/pg_dump/po/el.po new file mode 100644 index 000000000000..b4cd226dadf2 --- /dev/null +++ b/src/bin/pg_dump/po/el.po @@ -0,0 +1,2737 @@ +# Greek message translation file for pg_dump +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_dump (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_dump (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:48+0000\n" +"PO-Revision-Date: 2021-04-26 09:13+0200\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο:" + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα:" + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση:" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "δεν ήταν δυνατή η αναγνώριση του τρέχοντος καταλόγου: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "μη έγκυρο δυαδικό αρχείο “%s”" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "δεν ήταν δυνατή η ανάγνωση του δυαδικού αρχείου “%s”" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "δεν βρέθηκε το αρχείο “%s” για να εκτελεστεί" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "δεν ήταν δυνατή η μετάβαση στον κατάλογο “%s”: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του συμβολικού συνδέσμου “%s”: %m" + +#: ../../common/exec.c:409 parallel.c:1614 +#, c-format +msgid "%s() failed: %m" +msgstr "%s () απέτυχε: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "έλλειψη μνήμης" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "έλλειψη μνήμης\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "δεν ήταν δυνατή η αντιγραφή δείκτη null (εσωτερικό σφάλμα)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "εντολή μη εκτελέσιμη" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "εντολή δεν βρέθηκε" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "απόγονος διεργασίας τερμάτισε με κωδικό εξόδου %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "απόγονος διεργασίας τερματίστηκε με εξαίρεση 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "απόγονος διεργασίας τερματίστηκε με σήμα %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "απόγονος διεργασίας τερμάτισε με μη αναγνωρίσιμη κατάσταση %d" + +#: common.c:124 +#, c-format +msgid "reading extensions" +msgstr "ανάγνωση επεκτάσεων" + +#: common.c:128 +#, c-format +msgid "identifying extension members" +msgstr "προσδιορισμός μελών επέκτασεων" + +#: common.c:131 +#, c-format +msgid "reading schemas" +msgstr "ανάγνωση σχημάτων" + +#: common.c:141 +#, c-format +msgid "reading user-defined tables" +msgstr "ανάγνωση πινάκων ορισμένων από το χρήστη" + +#: common.c:148 +#, c-format +msgid "reading user-defined functions" +msgstr "ανάγνωση συναρτήσεων ορισμένων από το χρήστη" + +#: common.c:153 +#, c-format +msgid "reading user-defined types" +msgstr "ανάγνωση τύπων ορισμένων από το χρήστη" + +#: common.c:158 +#, c-format +msgid "reading procedural languages" +msgstr "ανάγνωση δομημένων γλωσσών" + +#: common.c:161 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "ανάγνωση συναρτήσεων συγκεντρωτικών αποτελεσμάτων ορισμένων από το χρήστη" + +#: common.c:164 +#, c-format +msgid "reading user-defined operators" +msgstr "ανάγνωση χειριστών ορισμένων από το χρήστη" + +#: common.c:168 +#, c-format +msgid "reading user-defined access methods" +msgstr "ανάγνωση μεθόδων πρόσβασης ορισμένων από το χρήστη" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator classes" +msgstr "ανάγνωση κλάσεων χειριστών ορισμένων από το χρήστη" + +#: common.c:174 +#, c-format +msgid "reading user-defined operator families" +msgstr "ανάγνωση οικογενειών χειριστών ορισμένων από το χρήστη" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "ανάγνωση αναλυτών αναζήτησης κειμένου ορισμένων από το χρήστη" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search templates" +msgstr "ανάγνωση προτύπων αναζήτησης κειμένου ορισμένων από το χρήστη" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "ανάγνωση λεξικών αναζήτησης κειμένου ορισμένων από το χρήστη" + +#: common.c:186 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "ανάγνωση ρυθμίσεων παραμέτρων αναζήτησης κειμένου ορισμένων από το χρήστη" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "ανάγνωση περιτυλίξεων ξενικών δεδομένων ορισμένων από το χρήστη" + +#: common.c:192 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "ανάγνωση ξενικών διακομιστών ορισμένων από το χρήστη" + +#: common.c:195 +#, c-format +msgid "reading default privileges" +msgstr "ανάγνωση προεπιλεγμένων δικαιωμάτων" + +#: common.c:198 +#, c-format +msgid "reading user-defined collations" +msgstr "ανάγνωση συρραφών ορισμένων από το χρήστη" + +#: common.c:202 +#, c-format +msgid "reading user-defined conversions" +msgstr "ανάγνωση μετατροπών ορισμένων από το χρήστη" + +#: common.c:205 +#, c-format +msgid "reading type casts" +msgstr "ανάγνωση τύπων καστ" + +#: common.c:208 +#, c-format +msgid "reading transforms" +msgstr "ανάγωση μετατροπών" + +#: common.c:211 +#, c-format +msgid "reading table inheritance information" +msgstr "ανάγωση πληροφοριών κληρονομιάς πινάκων" + +#: common.c:214 +#, c-format +msgid "reading event triggers" +msgstr "ανάγνωση ενεργοποιήσεων συμβάντων" + +#: common.c:218 +#, c-format +msgid "finding extension tables" +msgstr "εύρεση πινάκων επέκτασης" + +#: common.c:222 +#, c-format +msgid "finding inheritance relationships" +msgstr "εύρεση σχέσεων κληρονιμιά" + +#: common.c:225 +#, c-format +msgid "reading column info for interesting tables" +msgstr "ανάγνωση πληροφοριών στήλης για ενδιαφέροντες πίνακες" + +#: common.c:228 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "επισήμανση κληρονομούμενων στηλών σε υποπίνακες" + +#: common.c:231 +#, c-format +msgid "reading indexes" +msgstr "ανάγνωση ευρετηρίων" + +#: common.c:234 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "επισήμανση ευρετηρίων σε κατατμημένους πινάκες" + +#: common.c:237 +#, c-format +msgid "reading extended statistics" +msgstr "ανάγνωση εκτεταμένων στατιστικών στοιχείων" + +#: common.c:240 +#, c-format +msgid "reading constraints" +msgstr "ανάγνωση περιορισμών" + +#: common.c:243 +#, c-format +msgid "reading triggers" +msgstr "ανάγνωση ενεργοποιήσεων συμβάντων" + +#: common.c:246 +#, c-format +msgid "reading rewrite rules" +msgstr "ανάγνωση κανόνων επανεγγραφής" + +#: common.c:249 +#, c-format +msgid "reading policies" +msgstr "ανάγνωση πολιτικών" + +#: common.c:252 +#, c-format +msgid "reading publications" +msgstr "ανάγνωση δημοσιεύσεων" + +#: common.c:257 +#, c-format +msgid "reading publication membership" +msgstr "ανάγνωση ιδιοτήτων μελών δημοσίευσεων" + +#: common.c:260 +#, c-format +msgid "reading subscriptions" +msgstr "ανάγνωση συνδρομών" + +#: common.c:338 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "μη έγκυρος αριθμός γονέων %d για τον πίνακα \"%s\"" + +#: common.c:1100 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "απέτυχε ο έλεγχος ακεραιότητας, το γονικό OID %u του πίνακα \"%s\" (OID %u) δεν βρέθηκε" + +#: common.c:1142 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "δεν ήταν δυνατή η ανάλυση της αριθμητικής συστυχίας \"%s\": πάρα πολλοί αριθμοί" + +#: common.c:1157 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "δεν ήταν δυνατή η ανάλυση της αριθμητικής συστυχίας \"%s\": μη έγκυρος χαρακτήρας σε αριθμό" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "μη έγκυρος κωδικός συμπίεσης: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "δεν έχει κατασκευαστεί με υποστήριξη zlib" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "δεν ήταν δυνατή η αρχικοποίηση της βιβλιοθήκης συμπίεσης: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "δεν ήταν δυνατό το κλείσιμο της ροής συμπίεσης: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "δεν ήταν δυνατή η συμπίεση δεδομένων: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "δεν ήταν δυνατή η αποσυμπίεση δεδομένων: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "δεν ήταν δυνατό το κλείσιμο της βιβλιοθήκης συμπίεσης: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:551 pg_backup_tar.c:554 +#, c-format +msgid "could not read from input file: %s" +msgstr "δεν ήταν δυνατή η ανάγνωση από το αρχείο εισόδου: %s" + +#: compress_io.c:623 pg_backup_custom.c:643 pg_backup_directory.c:552 +#: pg_backup_tar.c:787 pg_backup_tar.c:810 +#, c-format +msgid "could not read from input file: end of file" +msgstr "δεν ήταν δυνατή η ανάγνωση από το αρχείο εισόδου: τέλος αρχείου" + +#: parallel.c:254 +#, fuzzy, c-format +#| msgid "pgpipe: getsockname() failed: error code %d" +msgid "%s() failed: error code %d" +msgstr "pgpipe: getsockname() απέτυχε: κωδικός σφάλματος %d" + +#: parallel.c:964 +#, c-format +msgid "could not create communication channels: %m" +msgstr "δεν ήταν δυνατή η δημιουργία καναλιών επικοινωνίας: %m" + +#: parallel.c:1021 +#, c-format +msgid "could not create worker process: %m" +msgstr "δεν ήταν δυνατή η δημιουργία διεργασίας εργάτη: %m" + +#: parallel.c:1151 +#, fuzzy, c-format +#| msgid "unrecognized command received from master: \"%s\"" +msgid "unrecognized command received from leader: \"%s\"" +msgstr "μη αναγνωρίσιμη εντολή που ελήφθη από τον μάστερ: “%s”" + +#: parallel.c:1194 parallel.c:1432 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "άκυρο μήνυμα που ελήφθη από εργάτη: “%s”" + +#: parallel.c:1326 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"δεν ήταν δυνατή η απόκτηση κλειδιού για τη σχέση \"%s\"\n" +"Αυτό συνήθως σημαίνει ότι κάποιος ζήτησε ένα κλειδί ACCESS EXCLUSIVE στον πίνακα αφού η γονική διεργασία pg_dump είχε ήδη αποκτήσει το αρχικό κλειδί ACCESS SHARE στον πίνακα." + +#: parallel.c:1415 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "μία διεργασία εργάτη τερματίστηκε απρόσμενα" + +#: parallel.c:1537 parallel.c:1655 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "δεν ήταν δυνατή η εγγραφή στο κανάλι επικοινωνίας: %m" + +#: parallel.c:1739 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: δεν ήταν δυνατή η δημιουργία υποδοχέα: κωδικός σφάλματος %d" + +#: parallel.c:1750 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: δεν ήταν δυνατή η δέσμευση: κωδικός σφάλματος %d" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: δεν ήταν δυνατή η ακρόαση: κωδικός σφάλματος %d" + +#: parallel.c:1764 +#, fuzzy, c-format +#| msgid "pgpipe: getsockname() failed: error code %d" +msgid "pgpipe: %s() failed: error code %d" +msgstr "pgpipe: getsockname() απέτυχε: κωδικός σφάλματος %d" + +#: parallel.c:1775 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: δεν ήταν δυνατή η δημιουργία δεύτερης υποδοχής: κωδικός σφάλματος %d" + +#: parallel.c:1784 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: δεν ήταν δυνατή η σύνδεση της υποδοχής: κωδικός σφάλματος %d" + +#: parallel.c:1793 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: δεν ήταν δυνατή η αποδοχή σύνδεσης: κωδικός σφάλματος %d" + +#: pg_backup_archiver.c:278 pg_backup_archiver.c:1577 +#, c-format +msgid "could not close output file: %m" +msgstr "δεν ήταν δυνατό το κλείσιμο αρχείου εξόδου: %m" + +#: pg_backup_archiver.c:322 pg_backup_archiver.c:326 +#, c-format +msgid "archive items not in correct section order" +msgstr "αρχειοθέτηση στοιχείων που δεν βρίσκονται σε σωστή σειρά ενότητας" + +#: pg_backup_archiver.c:332 +#, c-format +msgid "unexpected section code %d" +msgstr "μη αναμενόμενος κώδικας ενότητας %d" + +#: pg_backup_archiver.c:369 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "η παράλληλη επαναφορά δεν υποστηρίζεται από αυτήν τη μορφή αρχείου αρχειοθέτησης" + +#: pg_backup_archiver.c:373 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "η παράλληλη επαναφορά δεν υποστηρίζεται με αρχεία που έγιναν από pg_dump προ έκδοσης 8.0" + +#: pg_backup_archiver.c:391 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "δεν είναι δυνατή η επαναφορά από συμπιεσμένη αρχειοθήκη (η συμπίεση δεν υποστηρίζεται σε αυτήν την εγκατάσταση)" + +#: pg_backup_archiver.c:408 +#, c-format +msgid "connecting to database for restore" +msgstr "σύνδεση με βάση δεδομένων για επαναφορά" + +#: pg_backup_archiver.c:410 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "οι απευθείας συνδέσεις βάσεων δεδομένων δεν υποστηρίζονται σε προ-1.3 αρχεία" + +#: pg_backup_archiver.c:453 +#, c-format +msgid "implied data-only restore" +msgstr "υποδηλούμενη επαναφορά μόνο δεδομένων" + +#: pg_backup_archiver.c:519 +#, c-format +msgid "dropping %s %s" +msgstr "εγκαταλείπει %s: %s" + +#: pg_backup_archiver.c:614 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "δεν ήταν δυνατή η εύρεση του σημείου εισαγωγής IF EXISTS στη δήλωση \"%s\"" + +#: pg_backup_archiver.c:770 pg_backup_archiver.c:772 +#, c-format +msgid "warning from original dump file: %s" +msgstr "προειδοποίηση από το αρχικό αρχείο απόθεσης: %s" + +#: pg_backup_archiver.c:787 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "δημιουργία %s “%s.%s”" + +#: pg_backup_archiver.c:790 +#, c-format +msgid "creating %s \"%s\"" +msgstr "δημιουργία %s “%s”" + +#: pg_backup_archiver.c:840 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "σύνδεση με νέα βάση δεδομένων \"%s\"" + +#: pg_backup_archiver.c:867 +#, c-format +msgid "processing %s" +msgstr "επεξεργασία %s" + +#: pg_backup_archiver.c:887 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "επεξεργασία δεδομένων για τον πίνακα “%s.%s”" + +#: pg_backup_archiver.c:949 +#, c-format +msgid "executing %s %s" +msgstr "εκτέλεση %s %s" + +#: pg_backup_archiver.c:988 +#, c-format +msgid "disabling triggers for %s" +msgstr "απενεργοποίηση ενεργοποιήσεων για %s" + +#: pg_backup_archiver.c:1014 +#, c-format +msgid "enabling triggers for %s" +msgstr "ενεργοποίηση ενεργοποιήσεων για %s" + +#: pg_backup_archiver.c:1042 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "εσωτερικό σφάλμα -- Δεν είναι δυνατή η κλήση του WriteData εκτός του περιβάλλοντος μιας ρουτίνας DataDumper" + +#: pg_backup_archiver.c:1225 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "η έξοδος μεγάλου αντικειμένου δεν υποστηρίζεται στην επιλεγμένη μορφή" + +#: pg_backup_archiver.c:1283 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "επανέφερε %d μεγάλο αντικείμενο" +msgstr[1] "επανέφερε %d μεγάλα αντικείμενα" + +#: pg_backup_archiver.c:1304 pg_backup_tar.c:730 +#, c-format +msgid "restoring large object with OID %u" +msgstr "επαναφορά μεγάλου αντικειμένου με OID %u" + +#: pg_backup_archiver.c:1316 +#, c-format +msgid "could not create large object %u: %s" +msgstr "δεν ήταν δυνατή η δημιουργία μεγάλου αντικειμένου %u: %s" + +#: pg_backup_archiver.c:1321 pg_dump.c:3693 +#, c-format +msgid "could not open large object %u: %s" +msgstr "δεν ήταν δυνατό το άνοιγμα μεγάλου αντικειμένου %u: %s" + +#: pg_backup_archiver.c:1377 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου TOC “%s”: %m" + +#: pg_backup_archiver.c:1405 +#, c-format +msgid "line ignored: %s" +msgstr "παραβλέπεται γραμμή: %s" + +#: pg_backup_archiver.c:1412 +#, c-format +msgid "could not find entry for ID %d" +msgstr "δεν ήταν δυνατή η εύρεση καταχώρησης για ID %d" + +#: pg_backup_archiver.c:1435 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "δεν ήταν δυνατό το κλείσιμο του αρχείου TOC %m" + +#: pg_backup_archiver.c:1549 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:489 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου εξόδου “%s”: %m" + +#: pg_backup_archiver.c:1551 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου εξόδου %m" + +#: pg_backup_archiver.c:1644 +#, fuzzy, c-format +#| msgid "wrote %lu byte of large object data (result = %lu)" +#| msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgid "wrote %zu byte of large object data (result = %d)" +msgid_plural "wrote %zu bytes of large object data (result = %d)" +msgstr[0] "έγραψε %lu byte δεδομένων μεγάλου αντικειμένου (αποτέλεσμα = %lu)" +msgstr[1] "έγραψε %lu bytes δεδομένων μεγάλου αντικειμένου (αποτέλεσμα = %lu)" + +#: pg_backup_archiver.c:1650 +#, fuzzy, c-format +#| msgid "could not create large object %u: %s" +msgid "could not write to large object: %s" +msgstr "δεν ήταν δυνατή η δημιουργία μεγάλου αντικειμένου %u: %s" + +#: pg_backup_archiver.c:1740 +#, c-format +msgid "while INITIALIZING:" +msgstr "ενόσω INITIALIZING:" + +#: pg_backup_archiver.c:1745 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "ενόσω PROCESSING TOC:" + +#: pg_backup_archiver.c:1750 +#, c-format +msgid "while FINALIZING:" +msgstr "ενόσω FINALIZING:" + +#: pg_backup_archiver.c:1755 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "από καταχώρηση TOC %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1831 +#, c-format +msgid "bad dumpId" +msgstr "εσφαλμένο dumpId" + +#: pg_backup_archiver.c:1852 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "εσφαλμένος πίνακας dumpId για στοιχείο TABLE DATA" + +#: pg_backup_archiver.c:1944 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "μη αναμενόμενη σημαία όφσετ δεδομένων %d" + +#: pg_backup_archiver.c:1957 +#, c-format +msgid "file offset in dump file is too large" +msgstr "το όφσετ αρχείου στο αρχείο απόθεσης είναι πολύ μεγάλο" + +#: pg_backup_archiver.c:2095 pg_backup_archiver.c:2105 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "πολύ μακρύ όνομα καταλόγου: “%s”" + +#: pg_backup_archiver.c:2113 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "ο κατάλογος \"%s\" δεν φαίνεται να είναι έγκυρη αρχειοθήκη (το \"toc.dat\" δεν υπάρχει)" + +#: pg_backup_archiver.c:2121 pg_backup_custom.c:173 pg_backup_custom.c:807 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου εισόδου “%s”: %m" + +#: pg_backup_archiver.c:2128 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου εισόδου %m" + +#: pg_backup_archiver.c:2134 +#, c-format +msgid "could not read input file: %m" +msgstr "δεν ήταν δυνατή η ανάγνωση αρχείου εισόδου: %m" + +#: pg_backup_archiver.c:2136 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "το αρχείο εισόδου είναι πολύ σύντομο (διάβασε %lu, ανάμενε 5)" + +#: pg_backup_archiver.c:2168 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "το αρχείο εισαγωγής φαίνεται να είναι απόθεση μορφής κειμένου. Παρακαλώ χρησιμοποιήστε το psql." + +#: pg_backup_archiver.c:2174 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "το αρχείο εισόδου δεν φαίνεται να είναι έγκυρη αρχειοθήκη (πολύ σύντομο;)" + +#: pg_backup_archiver.c:2180 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "το αρχείο εισόδου δεν φαίνεται να είναι έγκυρη αρχειοθήκη" + +#: pg_backup_archiver.c:2189 +#, c-format +msgid "could not close input file: %m" +msgstr "δεν ήταν δυνατό το κλείσιμο αρχείου εισόδου: %m" + +#: pg_backup_archiver.c:2306 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "μη αναγνωρίσιμη μορφή αρχείου \"%d\"" + +#: pg_backup_archiver.c:2388 pg_backup_archiver.c:4422 +#, c-format +msgid "finished item %d %s %s" +msgstr "τερματισμός στοιχείου %d %s %s" + +#: pg_backup_archiver.c:2392 pg_backup_archiver.c:4435 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "διεργασία εργάτη απέτυχε: κωδικός εξόδου %d" + +#: pg_backup_archiver.c:2512 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "καταχώρηση με ID %d εκτός εύρους τιμών — ίσως αλλοιωμένο TOC" + +#: pg_backup_archiver.c:2579 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "η επαναφορά πινάκων WITH OIDS δεν υποστηρίζεται πλέον" + +#: pg_backup_archiver.c:2663 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "μη αναγνωρίσιμη κωδικοποίηση “%s”" + +#: pg_backup_archiver.c:2668 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "μη έγκυρο στοιχείο ENCODING: %s" + +#: pg_backup_archiver.c:2686 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "μη έγκυρο στοιχείο STDSTRINGS: %s" + +#: pg_backup_archiver.c:2717 +#, fuzzy, c-format +#| msgid "invalid STDSTRINGS item: %s" +msgid "invalid TOASTCOMPRESSION item: %s" +msgstr "μη έγκυρο στοιχείο STDSTRINGS: %s" + +#: pg_backup_archiver.c:2734 +#, c-format +msgid "schema \"%s\" not found" +msgstr "το σχήμα \"%s\" δεν βρέθηκε" + +#: pg_backup_archiver.c:2741 +#, c-format +msgid "table \"%s\" not found" +msgstr "ο πίνακας “%s” δεν βρέθηκε" + +#: pg_backup_archiver.c:2748 +#, c-format +msgid "index \"%s\" not found" +msgstr "το ευρετήριο “%s” δεν βρέθηκε" + +#: pg_backup_archiver.c:2755 +#, c-format +msgid "function \"%s\" not found" +msgstr "η συνάρτηση “%s” δεν βρέθηκε" + +#: pg_backup_archiver.c:2762 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "η ενεργοποίηση \"%s\" δεν βρέθηκε" + +#: pg_backup_archiver.c:3160 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "δεν ήταν δυνατός ο ορισμός του χρήστη συνεδρίας σε \"%s\": %s" + +#: pg_backup_archiver.c:3292 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "δεν ήταν δυνατός ο ορισμός του search_path σε “%s”: %s" + +#: pg_backup_archiver.c:3354 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "δεν ήταν δυνατός ο ορισμός του default_tablespace σε “%s”: %s" + +#: pg_backup_archiver.c:3399 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "δεν ήταν δυνατός ο ορισμός του default_table_access_method: %s" + +#: pg_backup_archiver.c:3491 pg_backup_archiver.c:3649 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "δεν γνωρίζω πώς να οριστεί κάτοχος για τύπο αντικειμένου \"%s\"" + +#: pg_backup_archiver.c:3753 +#, c-format +msgid "did not find magic string in file header" +msgstr "δεν βρέθηκε μαγική συμβολοσειρά στην κεφαλίδα αρχείου" + +#: pg_backup_archiver.c:3767 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "μη υποστηριζόμενη έκδοση (%d.%d) στην κεφαλίδα αρχείου" + +#: pg_backup_archiver.c:3772 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "απέτυχε έλεγχος ακεραιότητας για μέγεθος ακεραίου (%lu)" + +#: pg_backup_archiver.c:3776 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "το αρχείο δημιουργήθηκε σε έναν υπολογιστή με μεγαλύτερους ακέραιους, ορισμένες λειτουργίες ενδέχεται να αποτύχουν" + +#: pg_backup_archiver.c:3786 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "η αναμενόμενη μορφή (%d) διαφέρει από τη μορφή που βρίσκεται στο αρχείο (%d)" + +#: pg_backup_archiver.c:3801 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "το αρχείο είναι συμπιεσμένο, αλλά αυτή η εγκατάσταση δεν υποστηρίζει συμπίεση -- δεν θα υπάρχουν διαθέσιμα δεδομένα" + +#: pg_backup_archiver.c:3819 +#, c-format +msgid "invalid creation date in header" +msgstr "μη έγκυρη ημερομηνία δημιουργίας στην κεφαλίδα" + +#: pg_backup_archiver.c:3947 +#, c-format +msgid "processing item %d %s %s" +msgstr "επεξεργασία στοιχείου %d %s %s" + +#: pg_backup_archiver.c:4026 +#, c-format +msgid "entering main parallel loop" +msgstr "εισέρχεται στο κύριο παράλληλο βρόχο" + +#: pg_backup_archiver.c:4037 +#, c-format +msgid "skipping item %d %s %s" +msgstr "παράβλεψη στοιχείου %d %s %s" + +#: pg_backup_archiver.c:4046 +#, c-format +msgid "launching item %d %s %s" +msgstr "εκκίνηση στοιχείου %d %s %s" + +#: pg_backup_archiver.c:4100 +#, c-format +msgid "finished main parallel loop" +msgstr "εξέρχεται από το κύριο παράλληλο βρόχο" + +#: pg_backup_archiver.c:4136 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "επεξεργασία παραβλεπόμενου στοιχείου %d %s %s" + +#: pg_backup_archiver.c:4741 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "δεν ήταν δυνατή η δημιουργία του πίνακα \"%s\", δεν θα επαναφερθούν τα δεδομένα του" + +#: pg_backup_custom.c:376 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "μη έγκυρο OID για μεγάλο αντικειμένο" + +#: pg_backup_custom.c:439 pg_backup_custom.c:505 pg_backup_custom.c:629 +#: pg_backup_custom.c:865 pg_backup_tar.c:1080 pg_backup_tar.c:1085 +#, c-format +msgid "error during file seek: %m" +msgstr "σφάλμα κατά τη διάρκεια αναζήτησης σε αρχείο: %m" + +#: pg_backup_custom.c:478 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "%d μπλοκ δεδομένων έχει εσφαλμένη θέση αναζήτησης" + +#: pg_backup_custom.c:495 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "τύπος μπλοκ δεδομένων (%d) που δεν αναγνωρίζεται κατά την αναζήτηση αρχειοθέτησης" + +#: pg_backup_custom.c:517 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "δεν ήταν δυνατή η εύρεση μπλοκ ID %d στο αρχείο -- πιθανώς λόγω αίτησης επαναφοράς εκτός σειράς, η οποία δεν είναι δυνατό να αντιμετωπιστεί λόγω μη αναζητήσιμου αρχείου εισόδου" + +#: pg_backup_custom.c:522 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "δεν ήταν δυνατή η εύρεση μπλοκ ID %d στην αρχειοθήκη -- πιθανώς αλλοιωμένη αρχειοθήκη" + +#: pg_backup_custom.c:529 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "βρέθηκε μη αναμενόμενο μπλοκ ID (%d) κατά την ανάγνωση δεδομένων -- αναμενόμενο %d" + +#: pg_backup_custom.c:543 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "μη αναγνωρίσιμος τύπος μπλοκ δεδομένων %d κατά την επαναφορά της αρχειοθήκης" + +#: pg_backup_custom.c:645 +#, c-format +msgid "could not read from input file: %m" +msgstr "δεν ήταν δυνατή η ανάγνωση από αρχείο: %m" + +#: pg_backup_custom.c:746 pg_backup_custom.c:798 pg_backup_custom.c:943 +#: pg_backup_tar.c:1083 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "δεν ήταν δυνατός ο προσδιορισμός της θέσης αναζήτησης στην αρχειοθήκη: %m" + +#: pg_backup_custom.c:762 pg_backup_custom.c:802 +#, c-format +msgid "could not close archive file: %m" +msgstr "δεν ήταν δυνατό το κλείσιμο της αρχειοθήκης: %m" + +#: pg_backup_custom.c:785 +#, c-format +msgid "can only reopen input archives" +msgstr "μπορεί να επα-ανοίξει μόνο αρχειοθήκες εισόδου" + +#: pg_backup_custom.c:792 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "η επαναφορά από τυπική είσοδο δεν υποστηρίζεται" + +#: pg_backup_custom.c:794 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "η παράλληλη επαναφορά από μη αναζητήσιμο αρχείο δεν υποστηρίζεται" + +#: pg_backup_custom.c:810 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "δεν ήταν δυνατή η αναζήτηση θέσης στο αρχείο αρχειοθέτησης: %m" + +#: pg_backup_custom.c:889 +#, c-format +msgid "compressor active" +msgstr "συμπιεστής ενεργός" + +#: pg_backup_db.c:42 +#, c-format +msgid "could not get server_version from libpq" +msgstr "δεν ήταν δυνατή η απόκτηση server_version από libpq" + +#: pg_backup_db.c:53 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "έκδοση διακομιστή: %s; %s έκδοση: %s" + +#: pg_backup_db.c:55 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "ματαίωση λόγω ασυμφωνίας έκδοσης διακομιστή" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "ήδη συνδεδεμένος σε βάση δεδομένων" + +#: pg_backup_db.c:132 pg_backup_db.c:182 pg_dumpall.c:1655 pg_dumpall.c:1766 +msgid "Password: " +msgstr "Κωδικός πρόσβασης: " + +#: pg_backup_db.c:174 +#, c-format +msgid "could not connect to database" +msgstr "δεν ήταν δυνατή η σύνδεση σε βάση δεδομένων" + +#: pg_backup_db.c:191 +#, fuzzy, c-format +#| msgid "reconnection to database \"%s\" failed: %s" +msgid "reconnection failed: %s" +msgstr "επανασύνδεση στη βάση δεδομένων “%s” απέτυχε: %s" + +#: pg_backup_db.c:194 pg_backup_db.c:269 pg_dumpall.c:1686 pg_dumpall.c:1776 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:276 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "το ερώτημα απέτυχε: %s" + +#: pg_backup_db.c:278 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "το ερώτημα ήταν: %s" + +#: pg_backup_db.c:319 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "το ερώτημα επέστρεψε %d σειρά αντί μίας: %s" +msgstr[1] "το ερώτημα επέστρεψε %d σειρές αντί μίας: %s" + +#: pg_backup_db.c:355 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %s η εντολή ήταν: %s" + +#: pg_backup_db.c:411 pg_backup_db.c:485 pg_backup_db.c:492 +msgid "could not execute query" +msgstr "δεν ήταν δυνατή η εκτέλεση ερωτήματος" + +#: pg_backup_db.c:464 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "επιστράφηκε σφάλμα από PQputCopyData: %s" + +#: pg_backup_db.c:513 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "επιστράφηκε σφάλμα από PQputCopyEnd: %s" + +#: pg_backup_db.c:519 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "COPY απέτυχε για πίνακα “%s”: %s" + +#: pg_backup_db.c:525 pg_dump.c:2077 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "μη αναμενόμενα αποτελέσματα κατά τη διάρκεια COPY του πίνακα “%s”" + +#: pg_backup_db.c:537 +msgid "could not start database transaction" +msgstr "δεν ήταν δυνατή η εκκίνηση συναλλαγής βάσης δεδομένων" + +#: pg_backup_db.c:545 +msgid "could not commit database transaction" +msgstr "δεν ήταν δυνατή η ολοκλήρωση της συναλλαγής βάσης δεδομένων" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "δεν ορίστηκε κατάλογος δεδομένων εξόδου" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του καταλόγου “%s”: %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο του καταλόγου “%s”: %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η δημιουργία του καταλόγου “%s”: %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "δεν ήταν δυνατή η εγγραφή εξόδου στο αρχείο: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο του αρχείου δεδομένων “%s”: %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου TOC μεγάλου αντικειμένου \"%s\" για είσοδο: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "μη έγκυρη γραμμή σε αρχείο TOC μεγάλου αντικειμένου “%s”: “%s”" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "σφάλμα κατά την ανάγνωση αρχείου TOC μεγάλου αντικειμένου “%s”" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο αρχείου TOC μεγάλου αντικειμένου “%s”: %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "δεν ήταν δυνατή η εγγραφή σε αρχείο TOC blobs" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "πολύ μακρύ όνομα αρχείου: \"%s\"" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "δεν είναι δυνατή η ανάγνωση αυτής της μορφής" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου TOC “%s” για έξοδο: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου TOC για έξοδο: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:352 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "δεν υποστηρίζεται συμπίεση από τη μορφή αρχειοθέτησης tar" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου TOC “%s” για είσοδο: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου TOC για είσοδο: %m" + +#: pg_backup_tar.c:338 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "δεν ήταν δυνατή η εύρεση του αρχείου \"%s\" στην αρχειοθήκη" + +#: pg_backup_tar.c:404 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "δεν ήταν δυνατή η δημιουργία ονόματος προσωρινού αρχείου: %m" + +#: pg_backup_tar.c:415 +#, c-format +msgid "could not open temporary file" +msgstr "δεν ήταν δυνατό το άνοιγμα του προσωρινού αρχείου" + +#: pg_backup_tar.c:442 +#, c-format +msgid "could not close tar member" +msgstr "δεν ήταν δυνατό το κλείσιμο μέλους tar" + +#: pg_backup_tar.c:685 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "μη αναμενόμενη σύνταξη πρότασης COPY: \"%s\"" + +#: pg_backup_tar.c:952 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "μη έγκυρο OID για μεγάλο αντικείμενο (%u)" + +#: pg_backup_tar.c:1099 +#, c-format +msgid "could not close temporary file: %m" +msgstr "δεν ήταν δυνατό το κλείσιμο προσωρινού αρχείου: %m" + +#: pg_backup_tar.c:1108 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "πραγματικό μήκος αρχείου (%s) δεν συμφωνεί με το αναμενόμενο (%s)" + +#: pg_backup_tar.c:1165 pg_backup_tar.c:1196 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "δεν ήταν δυνατή η εύρεση κεφαλίδας για το αρχείο \"%s\" στο αρχείο tar" + +#: pg_backup_tar.c:1183 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "η επαναφορά δεδομένων εκτός σειράς δεν υποστηρίζεται σε αυτήν τη μορφή αρχειοθέτησης: απαιτείται \"%s\", αλλά προηγείται της \"%s\" στο αρχείο αρχειοθέτησης." + +#: pg_backup_tar.c:1230 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "βρέθηκε ατελής κεφαλίδα tar (%lu byte)" +msgstr[1] "βρέθηκε ατελής κεφαλίδα tar (%lu bytes)" + +#: pg_backup_tar.c:1281 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "αλλοιωμένη κεφαλίδα tar βρέθηκε σε %s (αναμενόμενη %d, υπολογισμένη %d) θέση αρχείου %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "μη αναγνωρισμένο όνομα τμήματος: \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:623 pg_dump.c:640 pg_dumpall.c:341 +#: pg_dumpall.c:351 pg_dumpall.c:360 pg_dumpall.c:369 pg_dumpall.c:377 +#: pg_dumpall.c:391 pg_dumpall.c:469 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "έλλειψη υποδοχών on_exit_nicely" + +#: pg_dump.c:549 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "το επίπεδο συμπίεσης πρέπει να βρίσκεται στο εύρος 0..9" + +#: pg_dump.c:587 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits πρέπει να βρίσκονται στο εύρος -15..3" + +#: pg_dump.c:610 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insert πρέπει να βρίσκονται στο εύρος %d..%d" + +#: pg_dump.c:638 pg_dumpall.c:349 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (η πρώτη είναι η “%s”)" + +#: pg_dump.c:659 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "οι επιλογές -s/—schema-only και -a/--data-only δεν είναι δυνατό να χρησιμοποιηθούν μαζί" + +#: pg_dump.c:664 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "οι επιλογές -s/—schema-only και —include-foreign-data δεν είναι δυνατό να χρησιμοποιηθούν μαζί" + +#: pg_dump.c:667 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "η επιλογή —include-foreign-data δεν υποστηρίζεται με παράλληλη δημιουργία αντιγράφων ασφαλείας" + +#: pg_dump.c:671 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "οι επιλογές -c/—clean και -a/—data-only δεν είναι δυνατό να χρησιμοποιηθούν μαζί" + +#: pg_dump.c:676 pg_dumpall.c:384 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "η επιλογή —if-exists απαιτεί την επιλογή -c/—clean" + +#: pg_dump.c:683 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "η επιλογή —on-conflict-do-nothing απαιτεί την επιλογή —inserts, —rows-per-insert, ή —column-inserts" + +#: pg_dump.c:705 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "η συμπίεση που ζητήθηκε δεν είναι διαθέσιμη σε αυτήν την εγκατάσταση -- η αρχειοθήκη θα είναι ασυμπίεστη" + +#: pg_dump.c:726 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "μη έγκυρος αριθμός παράλληλων εργασιών" + +#: pg_dump.c:730 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "παράλληλο αντίγραφο ασφαλείας υποστηρίζεται μόνο από μορφή καταλόγου" + +#: pg_dump.c:785 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Τα συγχρονισμένα στιγμιότυπα δεν υποστηρίζονται από αυτήν την έκδοση διακομιστή.\n" +"Εκτελέστε με —no-synchronized-snapshots, εάν δεν χρειάζεστε\n" +"συγχρονισμένα στιγμιότυπα." + +#: pg_dump.c:791 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Τα εξαγόμενα στιγμιότυπα δεν υποστηρίζονται από αυτήν την έκδοση διακομιστή." + +#: pg_dump.c:803 +#, c-format +msgid "last built-in OID is %u" +msgstr "το τελευταίο ενσωματωμένο OID είναι %u" + +#: pg_dump.c:812 +#, c-format +msgid "no matching schemas were found" +msgstr "δεν βρέθηκαν σχήματα που να ταιριάζουν" + +#: pg_dump.c:826 +#, c-format +msgid "no matching tables were found" +msgstr "δεν βρέθηκαν πίνακες που να ταιριάζουν" + +#: pg_dump.c:848 +#, fuzzy, c-format +#| msgid "no matching tables were found" +msgid "no matching extensions were found" +msgstr "δεν βρέθηκαν πίνακες που να ταιριάζουν" + +#: pg_dump.c:1020 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s αποθέτει μια βάση δεδομένων ως αρχείο κειμένου ή σε άλλες μορφές.\n" +"\n" + +#: pg_dump.c:1021 pg_dumpall.c:622 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_dump.c:1022 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]… [DBNAME]\n" + +#: pg_dump.c:1024 pg_dumpall.c:625 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Γενικές επιλογές:\n" + +#: pg_dump.c:1025 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, —file=FILENAME αρχείο εξόδου ή όνομα καταλόγου\n" + +#: pg_dump.c:1026 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, —format=c|d|t|p μορφή αρχείου εξόδου (προσαρμοσμένη, κατάλογος, tar,\n" +" απλό κείμενο (προεπιλογή))\n" + +#: pg_dump.c:1028 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, —jobs=NUM χρησιμοποιήστε τόσες πολλές παράλληλες εργασίες για απόθεση\n" + +#: pg_dump.c:1029 pg_dumpall.c:627 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, —verbose περιφραστική λειτουργία\n" + +#: pg_dump.c:1030 pg_dumpall.c:628 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης και, στη συνέχεια, έξοδος\n" + +#: pg_dump.c:1031 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, —compress=0-9 επίπεδο συμπίεσης για συμπιεσμένες μορφές\n" + +#: pg_dump.c:1032 pg_dumpall.c:629 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " —lock-wait-timeout=TIMEOUT αποτυγχάνει μετά την αναμονή TIMEOUT για το κλείδωμα πίνακα\n" + +#: pg_dump.c:1033 pg_dumpall.c:656 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " —no-sync να μην αναμένει την ασφαλή εγγραφή αλλαγών στον δίσκο\n" + +#: pg_dump.c:1034 pg_dumpall.c:630 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, και μετά έξοδος\n" + +#: pg_dump.c:1036 pg_dumpall.c:631 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Επιλογές που ελέγχουν το περιεχόμενο εξόδου:\n" + +#: pg_dump.c:1037 pg_dumpall.c:632 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, —data-only αποθέτει μόνο τα δεδομένα, όχι το σχήμα\n" + +#: pg_dump.c:1038 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, —blobs περιέλαβε μεγάλα αντικείμενα στην απόθεση\n" + +#: pg_dump.c:1039 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, —no-blobs εξαίρεσε μεγάλα αντικείμενα στην απόθεση\n" + +#: pg_dump.c:1040 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, —clean καθάρισε (εγκατάληψε) αντικείμενα βάσης δεδομένων πριν από την αναδημιουργία\n" + +#: pg_dump.c:1041 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr " -C, —create συμπεριέλαβε εντολές για τη δημιουργία βάσης δεδομένων στην απόθεση\n" + +#: pg_dump.c:1042 +#, fuzzy, c-format +#| msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgid " -e, --extension=PATTERN dump the specified extension(s) only\n" +msgstr " -t, —table=PATTERN απόθεση μόνο των καθορισμένων πινάκων\n" + +#: pg_dump.c:1043 pg_dumpall.c:634 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, —encoding=ENCODING απόθεσε τα δεδομένα στην κωδικοποίηση ENCODING\n" + +#: pg_dump.c:1044 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, —schema=PATTERN απόθεση μόνο για τα καθορισμένα σχήματα\n" + +#: pg_dump.c:1045 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, —exclude-schema=PATTERN να ΜΗΝ αποθέσει τα καθορισμένα σχήματα\n" + +#: pg_dump.c:1046 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, —no-owner παράλειπε την αποκατάσταση της κυριότητας των αντικειμένων στη\n" +" μορφή απλού κειμένου\n" + +#: pg_dump.c:1048 pg_dumpall.c:638 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, —schema-only απόθεση μόνο το σχήμα, χωρίς δεδομένα\n" + +#: pg_dump.c:1049 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, —superuser=NAME όνομα χρήστη υπερ-χρήστη που θα χρησιμοποιηθεί σε μορφή απλού κειμένου\n" + +#: pg_dump.c:1050 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, —table=PATTERN απόθεση μόνο των καθορισμένων πινάκων\n" + +#: pg_dump.c:1051 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, —exclude-table=PATTERN να ΜΗΝ αποθέτει τους καθορισμένους πίνακες\n" + +#: pg_dump.c:1052 pg_dumpall.c:641 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, —no-privileges να ΜΗΝ αποθέτει δικαιώματα (εκχώρηση/ανάκληση)\n" + +#: pg_dump.c:1053 pg_dumpall.c:642 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " —binary-upgrade μόνο για χρήση μόνο από βοηθητικά προγράμματα αναβάθμισης\n" + +#: pg_dump.c:1054 pg_dumpall.c:643 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr " —column-inserts αποθέτει δεδομένα ως εντολές INSERT με ονόματα στηλών\n" + +#: pg_dump.c:1055 pg_dumpall.c:644 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr " —disable-dollar-quoting απενεργοποίησε την παράθεση δολαρίου, χρήση τυποποιημένης παράθεσης SQL\n" + +#: pg_dump.c:1056 pg_dumpall.c:645 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr " —disable-triggers απενεργοποίησε τα εναύσματα κατά την επαναφορά δεδομένων-μόνο\n" + +#: pg_dump.c:1057 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" —enable-row-security ενεργοποιήστε την ασφάλεια σειρών (απόθεση μόνο του περιεχομένου που ο χρήστης έχει\n" +" πρόσβαση)\n" + +#: pg_dump.c:1059 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " —exclude-table-data=PATTERN να ΜΗΝ αποθέσει δεδομένα για τους καθορισμένους πίνακες\n" + +#: pg_dump.c:1060 pg_dumpall.c:647 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM παράκαμψε την προεπιλεγμένη ρύθμιση για extra_float_digits\n" + +#: pg_dump.c:1061 pg_dumpall.c:648 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " —if-exists χρησιμοποίησε το IF EXISTS κατά την εγκαταλήψη αντικειμένων\n" + +#: pg_dump.c:1062 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" —include-foreign-data=PATTERN\n" +" περιέλαβε δεδομένα ξένων πινάκων για\n" +" διακομιστές που ταιριάζουν με PATTERN\n" + +#: pg_dump.c:1065 pg_dumpall.c:649 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr " —inserts απόθεσε δεδομένα ως εντολές INSERT, αντί για COPY\n" + +#: pg_dump.c:1066 pg_dumpall.c:650 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " —load-via-partition-root φόρτωσε διαχωρίσματα μέσω του βασικού πίνακα\n" + +#: pg_dump.c:1067 pg_dumpall.c:651 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " —no-comments να μην αποθέσεις σχόλια\n" + +#: pg_dump.c:1068 pg_dumpall.c:652 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " —no-publications να μην αποθέσεις δημοσιεύσεις\n" + +#: pg_dump.c:1069 pg_dumpall.c:654 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " —no-security-labels να μην αποθέσεις αντιστοιχίσεις ετικετών ασφαλείας\n" + +#: pg_dump.c:1070 pg_dumpall.c:655 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " —no-publications να μην αποθέσεις συνδρομές\n" + +#: pg_dump.c:1071 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr " —no-synchronized-snapshots να μην χρησιμοποιήσει συγχρονισμένα στιγμιότυπα σε παράλληλες εργασίες\n" + +#: pg_dump.c:1072 pg_dumpall.c:657 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " —no-tablespaces να μην αποθέσει αναθέσεις πινακοχώρος\n" + +#: pg_dump.c:1073 pg_dumpall.c:658 +#, fuzzy, c-format +#| msgid " --no-comments do not dump comments\n" +msgid " --no-toast-compression do not dump TOAST compression methods\n" +msgstr " —no-comments να μην αποθέσεις σχόλια\n" + +#: pg_dump.c:1074 pg_dumpall.c:659 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " —no-unlogged-table-data να μην αποθέσει μη δεδομένα μη-καταγραμένου πίνακα\n" + +#: pg_dump.c:1075 pg_dumpall.c:660 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " —on-conflict-do-nothing προσθέστε ON CONFLICT DO NOTHING στις εντολές INSERT\n" + +#: pg_dump.c:1076 pg_dumpall.c:661 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr " —quote-all-identifiers παράθεσε όλα τα αναγνωριστικά, ακόμα και αν δεν είναι λέξεις κλειδιά\n" + +#: pg_dump.c:1077 pg_dumpall.c:662 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " —rows-per-insert=NROWS αριθμός γραμμών ανά INSERT; υπονοεί —inserts\n" + +#: pg_dump.c:1078 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr " —section=SECTION απόθεσε ονομασμένες ενότητες (προ-δεδομένα, δεδομένα, ή μετα-δεδομένα)\n" + +#: pg_dump.c:1079 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr " —serializable-deferrable ανάμενε έως ότου η απόθεση να μπορεί να τρέξει χωρίς ανωμαλίες\n" + +#: pg_dump.c:1080 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " —snapshot=SNAPSHOT χρησιμοποίησε το δοσμένο στιγμιότυπο για την απόθεση\n" + +#: pg_dump.c:1081 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" —strict-names απαίτησε τα μοτίβα περίληψης πίνακα ή/και σχήματος να\n" +" αντιστοιχήσουν τουλάχιστον μία οντότητα το καθένα\n" + +#: pg_dump.c:1083 pg_dumpall.c:663 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" —use-set-session-authorization\n" +" χρησιμοποιήσε τις εντολές SET SESSION AUTHORIZATION αντί των\n" +" ALTER OWNER για τον ορισμό ιδιοκτησίας\n" + +#: pg_dump.c:1087 pg_dumpall.c:667 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Επιλογές σύνδεσης:\n" + +#: pg_dump.c:1088 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, —dbname=DBNAME βάση δεδομένων για απόθεση\n" + +#: pg_dump.c:1089 pg_dumpall.c:669 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, —host=HOSTNAME διακομιστής βάσης δεδομένων ή κατάλογος υποδοχών\n" + +#: pg_dump.c:1090 pg_dumpall.c:671 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, —port=PORT θύρα διακομιστή βάσης δεδομένων\n" + +#: pg_dump.c:1091 pg_dumpall.c:672 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, —username=USERNAME σύνδεση ως ο ορισμένος χρήστης βάσης δεδομένων\n" + +#: pg_dump.c:1092 pg_dumpall.c:673 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, —no-password να μην ζητείται ποτέ κωδικός πρόσβασης\n" + +#: pg_dump.c:1093 pg_dumpall.c:674 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, —password αναγκαστική προτροπή κωδικού πρόσβασης (πρέπει να συμβεί αυτόματα)\n" + +#: pg_dump.c:1094 pg_dumpall.c:675 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " —role=ROLENAME κάνε SET ROLE πριν την απόθεση\n" + +#: pg_dump.c:1096 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Εάν δεν παρέχεται όνομα βάσης δεδομένων, τότε χρησιμοποιείται η μεταβλητή\n" +"περιβάλλοντος PGDATABASE .\n" +"\n" + +#: pg_dump.c:1098 pg_dumpall.c:679 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_dump.c:1099 pg_dumpall.c:680 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_dump.c:1118 pg_dumpall.c:504 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "καθορίστηκε μη έγκυρη κωδικοποίηση προγράμματος-πελάτη \"%s\"" + +#: pg_dump.c:1264 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Τα συγχρονισμένα στιγμιότυπα σε διακομιστές αναμονής δεν υποστηρίζονται από αυτήν την έκδοση διακομιστή.\n" +"Εκτελέστε με —no-synchronized-snapshots, εάν δεν χρειάζεστε\n" +"συγχρονισμένα στιγμιότυπα." + +#: pg_dump.c:1333 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "ορίστηκε μη έγκυρη μορφή εξόδου “%s”" + +#: pg_dump.c:1371 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "δεν βρέθηκαν σχήματα που να ταιριάζουν με το μοτίβο \"%s\"" + +#: pg_dump.c:1418 +#, fuzzy, c-format +#| msgid "no matching tables were found for pattern \"%s\"" +msgid "no matching extensions were found for pattern \"%s\"" +msgstr "δεν βρέθηκαν πίνακες που να ταιριάζουν για το μοτίβο \"%s\"" + +#: pg_dump.c:1465 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "δεν βρέθηκαν ξένοι διακομιστές που να ταιριάζουν με το μοτίβο \"%s\"" + +#: pg_dump.c:1528 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "δεν βρέθηκαν πίνακες που να ταιριάζουν για το μοτίβο \"%s\"" + +#: pg_dump.c:1951 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "αποθέτει τα δεδομένα του πίνακα “%s.%s”" + +#: pg_dump.c:2058 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Η απόθεση των περιεχομένων του πίνακα \"%s\" απέτυχε: PQgetCopyData() απέτυχε." + +#: pg_dump.c:2059 pg_dump.c:2069 +#, c-format +msgid "Error message from server: %s" +msgstr "Μήνυμα σφάλματος από διακομιστή: %s" + +#: pg_dump.c:2060 pg_dump.c:2070 +#, c-format +msgid "The command was: %s" +msgstr "Η εντολή ήταν: %s" + +#: pg_dump.c:2068 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Η απόθεση των περιεχομένων του πίνακα \"%s\" απέτυχε: PQgetResult() απέτυχε." + +#: pg_dump.c:2828 +#, c-format +msgid "saving database definition" +msgstr "αποθήκευση ορισμού βάσης δεδομένων" + +#: pg_dump.c:3300 +#, c-format +msgid "saving encoding = %s" +msgstr "αποθηκεύει encoding = %s" + +#: pg_dump.c:3325 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "αποθηκεύει standard_conforming_strings = %s" + +#: pg_dump.c:3364 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "δεν ήταν δυνατή η ανάλυση του αποτελέσματος της current_schemas()" + +#: pg_dump.c:3383 +#, c-format +msgid "saving search_path = %s" +msgstr "αποθηκεύει search_path = %s" + +#: pg_dump.c:3436 +#, c-format +msgid "saving default_toast_compression = %s" +msgstr "" + +#: pg_dump.c:3475 +#, c-format +msgid "reading large objects" +msgstr "ανάγνωση μεγάλων αντικειμένων" + +#: pg_dump.c:3657 +#, c-format +msgid "saving large objects" +msgstr "αποθηκεύει μεγάλων αντικειμένων" + +#: pg_dump.c:3703 +#, c-format +msgid "error reading large object %u: %s" +msgstr "σφάλμα κατά την ανάγνωση %u μεγάλου αντικειμένου: %s" + +#: pg_dump.c:3755 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "ανάγνωση ενεργοποιημένης ασφάλειας γραμμής για τον πίνακα \"%s.%s\"" + +#: pg_dump.c:3786 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "ανάγνωση πολιτικών για τον πίνακα \"%s.%s\"" + +#: pg_dump.c:3938 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "μη αναμενόμενος τύπος εντολής πολιτικής: %c" + +#: pg_dump.c:4092 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "ο κάτοχος της δημοσίευσης \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:4384 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "οι συνδρομές δεν απορρίπτονται, επειδή ο τρέχων χρήστης δεν είναι υπερχρήστης" + +#: pg_dump.c:4455 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "ο κάτοχος της συνδρομής \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:4498 +#, c-format +msgid "could not parse subpublications array" +msgstr "δεν ήταν δυνατή η ανάλυση της συστυχίας υποδημοσιεύσεων" + +#: pg_dump.c:4856 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "δεν ήταν δυνατή η εύρεση γονικής επέκτασης για %s %s" + +#: pg_dump.c:4988 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "ο κάτοχος του σχήματος \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:5011 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "το σχήμα με %u OID δεν υπάρχει" + +#: pg_dump.c:5340 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "ο κάτοχος του τύπου δεδομένων \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:5424 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "ο κάτοχος του χειριστή “%s” φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:5723 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "ο κάτοχος της κλάσης χειριστή \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:5806 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "ο κάτοχος της οικογένειας χειριστών \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:5974 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "ο κάτοχος της συνάρτησης συγκεντρωτικών αποτελεσμάτων \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:6233 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "ο κάτοχος της συνάρτησης \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:7060 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "ο κάτοχος του πίνακα \"%s\" φαίνεται να μην είναι έγκυρος" + +#: pg_dump.c:7102 pg_dump.c:17493 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "απέτυχε ο έλεγχος ακεραιότητας, ο γονικός πίνακας με OID %u της ακολουθίας με OID %u δεν βρέθηκε" + +#: pg_dump.c:7241 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "ανάγνωση ευρετηρίων για τον πίνακα \"%s.%s\"" + +#: pg_dump.c:7655 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "ανάγνωση περιορισμών ξένου κλειδιού για τον πίνακα \"%s.%s\"" + +#: pg_dump.c:7934 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "απέτυχε ο έλεγχος ακεραιότητας, ο γονικός πίνακας με OID %u της καταχώρησης pg_rewrite με OID %u δεν βρέθηκε" + +#: pg_dump.c:8017 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "ανάγνωση εναυσμάτων για τον πίνακα “%s.%s”" + +#: pg_dump.c:8150 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "το ερώτημα παρήγαγε null πίνακα αναφοράς για το έναυσμα ξένου κλειδιού \"%s\" στον πίνακα \"%s\" (OID του πίνακα: %u)" + +#: pg_dump.c:8700 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "εύρεση των στηλών και των τύπων του πίνακα “%s.%s”" + +#: pg_dump.c:8824 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "μη έγκυρη αρίθμηση στηλών στον πίνακα \"%s\"" + +#: pg_dump.c:8863 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "εύρεση προεπιλεγμένων εκφράσεων για τον πίνακα \"%s.%s\"" + +#: pg_dump.c:8885 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "μη έγκυρη τιμή adnum %d για τον πίνακα \"%s\"" + +#: pg_dump.c:8978 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "εύρεση περιορισμών ελέγχου για τον πίνακα \"%s.%s\"" + +#: pg_dump.c:9027 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "αναμενόμενος %d περιορισμός ελέγχου στον πίνακα \"%s\", αλλά βρήκε %d" +msgstr[1] "αναμενόμενοι %d περιορισμοί ελέγχου στον πίνακα “%s”, αλλά βρήκε %d" + +#: pg_dump.c:9031 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Οι κατάλογοι συστήματος ενδέχεται να είναι αλλοιωμένοι.)" + +#: pg_dump.c:10616 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "typtype του τύπου δεδομένων \"%s\" φαίνεται να μην είναι έγκυρο" + +#: pg_dump.c:11968 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "πλαστή τιμή στη συστυχία proargmodes" + +#: pg_dump.c:12275 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας proallargtypes" + +#: pg_dump.c:12291 +#, c-format +msgid "could not parse proargmodes array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας proargmodes" + +#: pg_dump.c:12305 +#, c-format +msgid "could not parse proargnames array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας proargnames" + +#: pg_dump.c:12315 +#, c-format +msgid "could not parse proconfig array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας proconfig" + +#: pg_dump.c:12395 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "μη αναγνωρίσιμη τιμή provolatile για τη συνάρτηση \"%s\"" + +#: pg_dump.c:12445 pg_dump.c:14396 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "μη αναγνωρίσιμη τιμή proparallel για τη συνάρτηση “%s”" + +#: pg_dump.c:12584 pg_dump.c:12693 pg_dump.c:12700 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "δεν ήταν δυνατή η εύρεση ορισμού συνάντησης για την συνάρτηση με OID %u" + +#: pg_dump.c:12623 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "πλαστή τιμή στο πεδίο pg_cast.castfunc ή pg_cast.castmethod" + +#: pg_dump.c:12626 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "πλαστή τιμή στο πεδίο pg_cast.castmethod" + +#: pg_dump.c:12719 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "πλαστός ορισμός μετασχηματισμού, τουλάχιστον μία από trffromsql και trftosql θα πρέπει να είναι μη μηδενική" + +#: pg_dump.c:12736 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "πλαστή τιμή στο πεδίο pg_transform.trffromsql" + +#: pg_dump.c:12757 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "πλαστή τιμή στο πεδίοpg_transform.trftosql" + +#: pg_dump.c:12909 +#, fuzzy, c-format +#| msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgid "postfix operators are not supported anymore (operator \"%s\")" +msgstr "WITH OIDS δεν υποστηρίζεται πλέον (πίνακας \"%s\")" + +#: pg_dump.c:13079 +#, c-format +msgid "could not find operator with OID %s" +msgstr "δεν ήταν δυνατή η εύρεση χειριστή με OID %s" + +#: pg_dump.c:13147 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "μη έγκυρος τύπος \"%c\" για την μεθόδο πρόσβασης \"%s\"" + +#: pg_dump.c:13901 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "μη αναγνωρίσιμος πάροχος συρραφής: %s" + +#: pg_dump.c:14315 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "μη αναγνωρίσιμη τιμή aggfinalmodify για το συγκεντρωτικό \"%s\"" + +#: pg_dump.c:14371 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "μη αναγνωρίσιμη τιμή aggmfinalmodify για το συγκεντρωτικό “%s”" + +#: pg_dump.c:15093 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "μη αναγνωρίσιμος τύπος αντικειμένου σε προεπιλεγμένα δικαιώματα: %d" + +#: pg_dump.c:15111 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "δεν ήταν δυνατή η ανάλυση της προεπιλεγμένης λίστας ACL (%s)" + +#: pg_dump.c:15196 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "δεν ήταν δυνατή η ανάλυση της αρχικής λίστας ACL GRANT (%s) ή της αρχικής λίστας REVOKE ACL (%s) για το αντικείμενο \"%s\" (%s)" + +#: pg_dump.c:15204 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "δεν ήταν δυνατή η ανάλυση της λίστας GRANT ACL (%s) ή της λίστας REVOKE ACL (%s) για το αντικείμενο \"%s\" (%s)" + +#: pg_dump.c:15719 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "το ερώτημα για τη λήψη ορισμού της όψης \"%s\" δεν επέστρεψε δεδομένα" + +#: pg_dump.c:15722 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "το ερώτημα για τη λήψη ορισμού της όψης \"%s\" επέστρεψε περισσότερους από έναν ορισμούς" + +#: pg_dump.c:15729 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "ο ορισμός της όψης \"%s\" φαίνεται να είναι κενός (μηδενικό μήκος)" + +#: pg_dump.c:15813 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS δεν υποστηρίζεται πλέον (πίνακας \"%s\")" + +#: pg_dump.c:16680 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "μη έγκυρος αριθμός στήλης %d για τον πίνακα \"%s\"" + +#: pg_dump.c:16757 +#, fuzzy, c-format +#| msgid "could not parse default ACL list (%s)" +msgid "could not parse index statistic columns" +msgstr "δεν ήταν δυνατή η ανάλυση της προεπιλεγμένης λίστας ACL (%s)" + +#: pg_dump.c:16759 +#, fuzzy, c-format +#| msgid "could not parse default ACL list (%s)" +msgid "could not parse index statistic values" +msgstr "δεν ήταν δυνατή η ανάλυση της προεπιλεγμένης λίστας ACL (%s)" + +#: pg_dump.c:16761 +#, c-format +msgid "mismatched number of columns and values for index statistics" +msgstr "" + +#: pg_dump.c:16978 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "λείπει ευρετήριο για τον περιορισμό \"%s\"" + +#: pg_dump.c:17203 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "μη αναγνωρίσιμος τύπος περιορισμού: %c" + +#: pg_dump.c:17335 pg_dump.c:17558 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "ερώτημα για τη λήψη δεδομένων ακολουθίας \"%s\" επέστρεψε %d γραμμή (αναμένεται 1)" +msgstr[1] "ερώτημα για τη λήψη δεδομένων ακολουθίας “%s” επέστρεψε %d γραμμές (αναμένεται 1)" + +#: pg_dump.c:17369 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "μη αναγνωρίσιμος τύπος ακολουθίας: %s" + +#: pg_dump.c:17656 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "μη αναγνωρίσιμος τύπος tgtype: %d" + +#: pg_dump.c:17730 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "μη έγκυρη συμβολοσειρά παραμέτρου (%s) για το έναυσμα \"%s\" στον πίνακα \"%s\"" + +#: pg_dump.c:17966 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "ερώτημα για τη λήψη κανόνα \"%s\" για τον πίνακα \"%s\" απέτυχε: επιστράφηκε εσφαλμένος αριθμός γραμμών" + +#: pg_dump.c:18128 +#, c-format +msgid "could not find referenced extension %u" +msgstr "δεν ήταν δυνατή η εύρεση της αναφερόμενης επέκτασης %u" + +#: pg_dump.c:18219 +#, fuzzy, c-format +#| msgid "could not parse proconfig array" +msgid "could not parse extension configuration array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας proconfig" + +#: pg_dump.c:18221 +#, fuzzy, c-format +#| msgid "could not parse reloptions array" +msgid "could not parse extension condition array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας reloptions" + +#: pg_dump.c:18223 +#, c-format +msgid "mismatched number of configurations and conditions for extension" +msgstr "" + +#: pg_dump.c:18355 +#, c-format +msgid "reading dependency data" +msgstr "ανάγνωση δεδομένων εξάρτησης" + +#: pg_dump.c:18448 +#, c-format +msgid "no referencing object %u %u" +msgstr "δεν αναφέρεται αντικείμενο %u %u" + +#: pg_dump.c:18459 +#, c-format +msgid "no referenced object %u %u" +msgstr "μη αναφερόμενο αντικείμενο %u %u" + +#: pg_dump.c:18833 +#, c-format +msgid "could not parse reloptions array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας reloptions" + +#: pg_dump_sort.c:411 +#, c-format +msgid "invalid dumpId %d" +msgstr "μη έγκυρο dumpId %d" + +#: pg_dump_sort.c:417 +#, c-format +msgid "invalid dependency %d" +msgstr "μη έγκυρη εξάρτηση %d" + +#: pg_dump_sort.c:650 +#, c-format +msgid "could not identify dependency loop" +msgstr "δεν ήταν δυνατός ο προσδιορισμός βρόχου εξάρτησης" + +#: pg_dump_sort.c:1221 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "υπάρχουν κυκλικοί περιορισμοί ξένου κλειδιού σε αυτόν τον πίνακα:" +msgstr[1] "υπάρχουν κυκλικοί περιορισμοί ξένου κλειδιού σε αυτούς τους πίνακες:" + +#: pg_dump_sort.c:1225 pg_dump_sort.c:1245 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1226 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Ενδέχεται να μην μπορείτε να επαναφέρετε την ένδειξη χωρίς να χρησιμοποιήσετε --disable-triggers ή να εγκαταλήψετε προσωρινά τους περιορισμούς." + +#: pg_dump_sort.c:1227 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Εξετάστε το ενδεχόμενο να χρησιμοποιήσετε μια πλήρη απόθεση αντί για μια —data-only απόθεση για να αποφύγετε αυτό το πρόβλημα." + +#: pg_dump_sort.c:1239 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "δεν ήταν δυνατή η επίλυση του βρόχου εξάρτησης μεταξύ αυτών των στοιχείων:" + +#: pg_dumpall.c:202 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Το πρόγραμμα \"%s\" απαιτείται από %s αλλά δεν βρέθηκε στο\n" +"ίδιος κατάλογος με το \"%s\".\n" +"Ελέγξτε την εγκατάστασή σας." + +#: pg_dumpall.c:207 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Το πρόγραμμα \"%s\" βρέθηκε από το \"%s\"\n" +"αλλά δεν ήταν η ίδια εκδοχή με %s.\n" +"Ελέγξτε την εγκατάστασή σας." + +#: pg_dumpall.c:359 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "επιλογή —exclude-database δεν μπορεί να χρησιμοποιηθεί μαζί με -g/—globals-only, -r/—roles-only, ή -t/—tablespaces-only" + +#: pg_dumpall.c:368 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "οι επιλογές -g/—globals-only και -r/—roles-only δεν μπορούν να χρησιμοποιηθούν μαζί" + +#: pg_dumpall.c:376 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "Οι επιλογές -g/--καθολικές μόνο και -t/--επιτραπέζιοι χώροι δεν μπορούν να χρησιμοποιηθούν μαζί" + +#: pg_dumpall.c:390 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "οι επιλογές -r/—roles-only και -t/—tablespaces-only δεν μπορούν να χρησιμοποιηθούν μαζί" + +#: pg_dumpall.c:453 pg_dumpall.c:1756 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "δεν ήταν δυνατή η σύνδεση στη βάση δεδομένων “%s”" + +#: pg_dumpall.c:467 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"δεν ήταν δυνατή η σύνδεση με τις βάσεις δεδομένων \"postgres\" ή \"Template1\"\n" +"Παρακαλώ καθορίστε μία εναλλακτική βάση δεδομένων." + +#: pg_dumpall.c:621 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s εξάγει μία συστάδα βάσεων δεδομένων PostgreSQL σε ένα αρχείο σεναρίου SQL.\n" +"\n" + +#: pg_dumpall.c:623 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [ΕΠΙΛΟΓΗ]…\n" + +#: pg_dumpall.c:626 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, —file=FILENAME όνομα αρχείου εξόδου\n" + +#: pg_dumpall.c:633 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, —clean καθάρισε (εγκατάληψε) βάσεις δεδομένων πριν από την αναδημιουργία\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, —globals-only απόθεσε μόνο καθολικά αντικείμενα, όχι βάσεις δεδομένων\n" + +#: pg_dumpall.c:636 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, —no-owner παράλειψε την αποκατάσταση της κυριότητας αντικειμένων\n" + +#: pg_dumpall.c:637 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr " -r, —roles-only απόθεσε μόνο ρόλους, όχι βάσεις δεδομένων ή πινακοχώρους\n" + +#: pg_dumpall.c:639 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, —superuser=NAME όνομα υπερχρήστη για να χρησιμοποιηθεί στην απόθεση\n" + +#: pg_dumpall.c:640 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr " -t, —tablespaces-only απόθεσε μόνο πινακοχώρους, όχι βάσεις δεδομένων ή ρόλους\n" + +#: pg_dumpall.c:646 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " —exclude-database=PATTERN εξαίρεσε βάσεις δεδομένων των οποίων το όνομα ταιριάζει με PATTERN\n" + +#: pg_dumpall.c:653 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " —no-role-passwords να μην αποθέσει κωδικούς πρόσβασης για ρόλους\n" + +#: pg_dumpall.c:668 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, —dbname=CONNSTR σύνδεση με χρήση συμβολοσειράς σύνδεσης\n" + +#: pg_dumpall.c:670 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr "" +" -l, —database=DBNAME εναλλακτική προεπιλεγμένη βάση δεδομένων\n" +"\n" + +#: pg_dumpall.c:677 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"Εάν δεν χρησιμοποιηθεί -f/—file , τότε η δέσμη ενεργειών SQL θα εγγραφεί στη τυπική\n" +"έξοδο.\n" +"\n" + +#: pg_dumpall.c:883 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "όνομα ρόλου που αρχίζει \"pg_\" παραλείπεται (%s)" + +#: pg_dumpall.c:1284 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "δεν ήταν δυνατή η ανάλυση της λίστας ACL (%s) για τον πινακοχώρο \"%s\"" + +#: pg_dumpall.c:1501 +#, c-format +msgid "excluding database \"%s\"" +msgstr "εξαιρεί τη βάση δεδομένων \"%s\"" + +#: pg_dumpall.c:1505 +#, c-format +msgid "dumping database \"%s\"" +msgstr "αποθέτει τη βάση δεδομένων “%s”" + +#: pg_dumpall.c:1537 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump απέτυχε στη βάση δεδομένων \"%s\", εξέρχεται" + +#: pg_dumpall.c:1546 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "δεν ήταν δυνατό το εκ νέου άνοιγμα του αρχείου εξόδου \"%s\": %m" + +#: pg_dumpall.c:1590 +#, c-format +msgid "running \"%s\"" +msgstr "εκτελείται “%s”" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "δεν ήταν δυνατή η απόκτηση έκδοσης διακομιστή" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "δεν ήταν δυνατή η ανάλυση έκδοσης διακομιστή “%s”" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "εκτελείται %s" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "ένα από τα -d/--dbname και -f/--file πρέπει να καθοριστεί" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "οι επιλογές -d/—dbname και -f/—file δεν μπορούν να χρησιμοποιηθούν μαζί" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "οι επιλογές -C/--create και -1/--single-transaction δεν μπορούν να χρησιμοποιηθούν μαζί" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "ο μέγιστος αριθμός παράλληλων εργασιών είναι %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "δεν είναι δυνατό να οριστούν —single-transaction και multiple jobs και τα δύο μαζί " + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "μη αναγνωρισμένη μορφή αρχειοθέτησης “%s”· παρακαλώ καθορίστε \"c\", \"d\" ή \"t\"" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "σφάλματα που παραβλέφθηκαν κατά την επαναφορά: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s επαναφέρει μια βάση δεδομένων PostgreSQL από μια αρχειοθήκη που δημιουργήθηκε από τη pg_dump.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [OPTION]… [FILE]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, —dbname=NAME σύνδεση με τη βάσης δεδομένων με όνομα\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, —file=FILENAME όνομα αρχείου εξόδου (- για stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, —format=c|d|t μορφή αρχείου αντιγράφου ασφαλείας (θα πρέπει να είναι αυτόματη)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, —list εκτύπωσε συνοπτικό TOC της αρχειοθήκης\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, —verbose περιφραστική λειτουργία\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης και, στη συνέχεια, έξοδος\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, και μετά έξοδος\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Επιλογές που ελέγχουν την επαναφορά:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, —data-only επαναφέρε μόνο τα δεδομένα, όχι το σχήμα\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, —create δημιούργησε τη βάσης δεδομένων προορισμού\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, —exit-on-error να εξέλθει σε σφάλμα, η προεπιλογή είναι να συνεχίσει\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, —index=NAME επανάφερε το ευρετήριο με όνομα\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, —jobs=NUM χρησιμοποίησε τόσες πολλές παράλληλες εργασίες για την επαναφορά\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, —use-list=FILENAME χρησιμοποίησε τον πίνακα περιεχομένων από αυτό το αρχείο για\n" +" επιλογή/ταξινόμηση εξόδου\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, —schema=NAME επανάφερε μόνο αντικείμενα σε αυτό το σχήμα\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, —exclude-schema=NAME να μην επαναφέρει αντικείμενα από αυτό το σχήμα\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr "P, —function=NAME(args) επανάφερε την καθορισμένη συνάρτηση\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, —schema-only επανάφερε μόνο το σχήμα, χωρίς δεδομένα\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr " -S, —superuser=NAME όνομα υπερχρήστη για χρήση κατά την απενεργοποίηση εναυσμάτων\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, —table=NAME επανάφερε την καθορισμένη σχέση (πίνακας, προβολή κ.λπ.)\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr "" +" -T, —trigger=NAME επανάφερε το καθορισμένο έναυσμα\n" +"\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, —no-privileges παράλειπε την επαναφορά των δικαιωμάτων πρόσβασης (εκχώρηση/ανάκληση)\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, —single-transaction επανάφερε ως μεμονωμένη συναλλαγή\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " —enable-row-security ενεργοποίησε ασφαλεία σειράς\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " —no-comments να μην επαναφέρεις σχόλια\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" —no-data-for-failed-tables να μην επαναφέρεις δεδομένα πινάκων που δεν ήταν\n" +" δυνατό να δημιουργήθουν\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " —no-publications να μην επαναφέρεις δημοσιεύσεις\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " —no-security-labels να μην επαναφέρεις ετικέτες ασφαλείας\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " —no-publications να μην επαναφέρεις συνδρομές\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " —no-tablespaces να μην επαναφέρεις αναθέσεις πινακοχώρων\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr " —section=SECTION επανάφερε ονομασμένες ενότητες (προ-δεδομένα, δεδομένα, ή μετα-δεδομένα)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " —role=ROLENAME κάνε SET ROLE πριν την επαναφορά\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"Οι επιλογές -I, -n, -N, -P, -t, -T και —section μπορούν να συνδυαστούν και να καθοριστούν\n" +"πολλές φορές για την επιλογή πολλών αντικειμένων.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"Εάν δεν παρέχεται όνομα αρχείου εισόδου, τότε χρησιμοποιείται η τυπική είσοδος.\n" +"\n" + +#~ msgid "could not connect to database \"%s\": %s" +#~ msgstr "δεν ήταν δυνατή η σύνδεση στη βάση δεδομένων “%s”: %s" + +#~ msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +#~ msgstr "δεν ήταν δυνατή η σωστή απόθεση της συνάρτησης συγκεντρωτικών αποτελεσμάτων %s για αυτήν την έκδοση της βάσης δεδομένων· παραβλέπεται" + +#~ msgid "connection to database \"%s\" failed: %s" +#~ msgstr "σύνδεση στη βάση δεδομένων “%s” απέτυχε: %s" + +#~ msgid "could not write to large object (result: %lu, expected: %lu)" +#~ msgstr "δεν ήταν δυνατή η εγγραφή σε μεγάλο αντικείμενο (αποτέλεσμα: %lu, αναμένεται: %lu)" + +#~ msgid "select() failed: %m" +#~ msgstr "απέτυχε το select(): %m" + +#~ msgid "WSAStartup failed: %d" +#~ msgstr "WSAStartup απέτυχε: %d" + +#~ msgid "pclose failed: %m" +#~ msgstr "απέτυχε η εντολή pclose: %m" diff --git a/src/bin/pg_dump/po/es.po b/src/bin/pg_dump/po/es.po new file mode 100644 index 000000000000..b7d603e7aa16 --- /dev/null +++ b/src/bin/pg_dump/po/es.po @@ -0,0 +1,2768 @@ +# Spanish message translation file for pg_dump +# +# Copyright (c) 2003-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Manuel Sugawara , 2003. +# Alvaro Herrera , 2004-2007, 2009-2013 +# Carlos Chapi , 2014, 2017, 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_dump (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:48+0000\n" +"PO-Revision-Date: 2021-05-20 23:35-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "el binario «%s» no es válido" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "no se pudo leer el binario «%s»" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "no se pudo encontrar un «%s» para ejecutar" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" + +#: ../../common/exec.c:409 parallel.c:1614 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() falló: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "memoria agotada" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "la orden no es ejecutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "orden no encontrada" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "el proceso hijo terminó con código de salida %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "el proceso hijo fue terminado por una excepción 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "el proceso hijo terminó con código no reconocido %d" + +#: common.c:124 +#, c-format +msgid "reading extensions" +msgstr "leyendo las extensiones" + +#: common.c:128 +#, c-format +msgid "identifying extension members" +msgstr "identificando miembros de extensión" + +#: common.c:131 +#, c-format +msgid "reading schemas" +msgstr "leyendo esquemas" + +#: common.c:141 +#, c-format +msgid "reading user-defined tables" +msgstr "leyendo las tablas definidas por el usuario" + +#: common.c:148 +#, c-format +msgid "reading user-defined functions" +msgstr "leyendo las funciones definidas por el usuario" + +#: common.c:153 +#, c-format +msgid "reading user-defined types" +msgstr "leyendo los tipos definidos por el usuario" + +#: common.c:158 +#, c-format +msgid "reading procedural languages" +msgstr "leyendo los lenguajes procedurales" + +#: common.c:161 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "leyendo las funciones de agregación definidas por el usuario" + +#: common.c:164 +#, c-format +msgid "reading user-defined operators" +msgstr "leyendo los operadores definidos por el usuario" + +#: common.c:168 +#, c-format +msgid "reading user-defined access methods" +msgstr "leyendo los métodos de acceso definidos por el usuario" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator classes" +msgstr "leyendo las clases de operadores definidos por el usuario" + +#: common.c:174 +#, c-format +msgid "reading user-defined operator families" +msgstr "leyendo las familias de operadores definidas por el usuario" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "leyendo los procesadores (parsers) de búsqueda en texto definidos por el usuario" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search templates" +msgstr "leyendo las plantillas de búsqueda en texto definidas por el usuario" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "leyendo los diccionarios de búsqueda en texto definidos por el usuario" + +#: common.c:186 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "leyendo las configuraciones de búsqueda en texto definidas por el usuario" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "leyendo los conectores de datos externos definidos por el usuario" + +#: common.c:192 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "leyendo los servidores foráneos definidas por el usuario" + +#: common.c:195 +#, c-format +msgid "reading default privileges" +msgstr "leyendo los privilegios por omisión" + +#: common.c:198 +#, c-format +msgid "reading user-defined collations" +msgstr "leyendo los ordenamientos definidos por el usuario" + +#: common.c:202 +#, c-format +msgid "reading user-defined conversions" +msgstr "leyendo las conversiones definidas por el usuario" + +#: common.c:205 +#, c-format +msgid "reading type casts" +msgstr "leyendo conversiones de tipo" + +#: common.c:208 +#, c-format +msgid "reading transforms" +msgstr "leyendo las transformaciones" + +#: common.c:211 +#, c-format +msgid "reading table inheritance information" +msgstr "leyendo la información de herencia de las tablas" + +#: common.c:214 +#, c-format +msgid "reading event triggers" +msgstr "leyendo los disparadores por eventos" + +#: common.c:218 +#, c-format +msgid "finding extension tables" +msgstr "buscando tablas de extensión" + +#: common.c:222 +#, c-format +msgid "finding inheritance relationships" +msgstr "buscando relaciones de herencia" + +#: common.c:225 +#, c-format +msgid "reading column info for interesting tables" +msgstr "leyendo la información de columnas para las tablas interesantes" + +#: common.c:228 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "marcando las columnas heredadas en las subtablas" + +#: common.c:231 +#, c-format +msgid "reading indexes" +msgstr "leyendo los índices" + +#: common.c:234 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "marcando índices en las tablas particionadas" + +#: common.c:237 +#, c-format +msgid "reading extended statistics" +msgstr "leyendo estadísticas extendidas" + +#: common.c:240 +#, c-format +msgid "reading constraints" +msgstr "leyendo las restricciones" + +#: common.c:243 +#, c-format +msgid "reading triggers" +msgstr "leyendo los disparadores (triggers)" + +#: common.c:246 +#, c-format +msgid "reading rewrite rules" +msgstr "leyendo las reglas de reescritura" + +#: common.c:249 +#, c-format +msgid "reading policies" +msgstr "leyendo políticas" + +#: common.c:252 +#, c-format +msgid "reading publications" +msgstr "leyendo publicaciones" + +#: common.c:257 +#, c-format +msgid "reading publication membership" +msgstr "leyendo membresía en publicaciones" + +#: common.c:260 +#, c-format +msgid "reading subscriptions" +msgstr "leyendo las suscripciones" + +#: common.c:338 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "número de padres %d para la tabla «%s» no es válido" + +#: common.c:1100 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "falló la revisión de integridad, el OID %u del padre de la tabla «%s» (OID %u) no se encontró" + +#: common.c:1142 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "no se pudo interpretar el arreglo numérico «%s»: demasiados números" + +#: common.c:1157 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "no se pudo interpretar el arreglo numérico «%s»: carácter no válido en número" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "código de compresión no válido: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "no contiene soporte zlib" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "no se pudo inicializar la biblioteca de compresión: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "no se pudo cerrar el flujo comprimido: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "no se pudo comprimir datos: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "no se pudo descomprimir datos: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "no se pudo cerrar la biblioteca de compresión: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:551 pg_backup_tar.c:554 +#, c-format +msgid "could not read from input file: %s" +msgstr "no se pudo leer el archivo de entrada: %s" + +#: compress_io.c:623 pg_backup_custom.c:643 pg_backup_directory.c:552 +#: pg_backup_tar.c:787 pg_backup_tar.c:810 +#, c-format +msgid "could not read from input file: end of file" +msgstr "no se pudo leer desde el archivo de entrada: fin de archivo" + +#: parallel.c:254 +#, c-format +msgid "%s() failed: error code %d" +msgstr "%s() falló: código de error %d" + +#: parallel.c:964 +#, c-format +msgid "could not create communication channels: %m" +msgstr "no se pudo crear los canales de comunicación: %m" + +#: parallel.c:1021 +#, c-format +msgid "could not create worker process: %m" +msgstr "no se pudo crear el proceso hijo: %m" + +#: parallel.c:1151 +#, c-format +msgid "unrecognized command received from leader: \"%s\"" +msgstr "orden no reconocida recibida del servidor principal: «%s»" + +#: parallel.c:1194 parallel.c:1432 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "mensaje no válido recibido del proceso hijo: «%s»" + +#: parallel.c:1326 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"no se pudo obtener un lock en la relación «%s»\n" +"Esto normalmente significa que alguien solicitó un lock ACCESS EXCLUSIVE en la tabla después de que el proceso pg_dump padre había obtenido el lock ACCESS SHARE en la tabla." + +#: parallel.c:1415 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "un proceso hijo murió inesperadamente" + +#: parallel.c:1537 parallel.c:1655 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "no se pudo escribir al canal de comunicación: %m" + +#: parallel.c:1739 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: no se pudo crear el socket: código de error %d" + +#: parallel.c:1750 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: no se pudo enlazar: código de error %d" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: no se pudo escuchar: código de error %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: %s() failed: error code %d" +msgstr "pgpipe: %s() falló: código de error %d" + +#: parallel.c:1775 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: no se pudo crear el segundo socket: código de error %d" + +#: parallel.c:1784 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: no se pudo conectar el socket: código de error %d" + +#: parallel.c:1793 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: no se pudo aceptar la conexión: código de error %d" + +#: pg_backup_archiver.c:278 pg_backup_archiver.c:1577 +#, c-format +msgid "could not close output file: %m" +msgstr "no se pudo cerrar el archivo de salida: %m" + +#: pg_backup_archiver.c:322 pg_backup_archiver.c:326 +#, c-format +msgid "archive items not in correct section order" +msgstr "elementos del archivo no están en el orden correcto de secciones" + +#: pg_backup_archiver.c:332 +#, c-format +msgid "unexpected section code %d" +msgstr "código de sección %d inesperado" + +#: pg_backup_archiver.c:369 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "la restauración en paralelo no está soportada con este formato de archivo" + +#: pg_backup_archiver.c:373 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "la restauración en paralelo no está soportada con archivos construidos con pg_dump anterior a 8.0" + +#: pg_backup_archiver.c:391 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "no se puede reestablecer desde un archivo comprimido (la compresión no está soportada en esta instalación)" + +#: pg_backup_archiver.c:408 +#, c-format +msgid "connecting to database for restore" +msgstr "conectando a la base de datos para reestablecimiento" + +#: pg_backup_archiver.c:410 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "las conexiones directas a la base de datos no están soportadas en archivadores pre-1.3" + +#: pg_backup_archiver.c:453 +#, c-format +msgid "implied data-only restore" +msgstr "asumiendo reestablecimiento de sólo datos" + +#: pg_backup_archiver.c:519 +#, c-format +msgid "dropping %s %s" +msgstr "eliminando %s %s" + +#: pg_backup_archiver.c:614 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "no se pudo encontrar dónde insertar IF EXISTS en la sentencia «%s»" + +#: pg_backup_archiver.c:770 pg_backup_archiver.c:772 +#, c-format +msgid "warning from original dump file: %s" +msgstr "precaución desde el archivo original: %s" + +#: pg_backup_archiver.c:787 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "creando %s «%s.%s»" + +#: pg_backup_archiver.c:790 +#, c-format +msgid "creating %s \"%s\"" +msgstr "creando %s «%s»" + +#: pg_backup_archiver.c:840 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "conectando a nueva base de datos «%s»" + +#: pg_backup_archiver.c:867 +#, c-format +msgid "processing %s" +msgstr "procesando %s" + +#: pg_backup_archiver.c:887 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "procesando datos de la tabla «%s.%s»" + +#: pg_backup_archiver.c:949 +#, c-format +msgid "executing %s %s" +msgstr "ejecutando %s %s" + +#: pg_backup_archiver.c:988 +#, c-format +msgid "disabling triggers for %s" +msgstr "deshabilitando disparadores (triggers) para %s" + +#: pg_backup_archiver.c:1014 +#, c-format +msgid "enabling triggers for %s" +msgstr "habilitando disparadores (triggers) para %s" + +#: pg_backup_archiver.c:1042 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "error interno -- WriteData no puede ser llamada fuera del contexto de una rutina DataDumper" + +#: pg_backup_archiver.c:1225 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "la extracción de objetos grandes no está soportada en el formato seleccionado" + +#: pg_backup_archiver.c:1283 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "se reestableció %d objeto grande" +msgstr[1] "se reestablecieron %d objetos grandes" + +#: pg_backup_archiver.c:1304 pg_backup_tar.c:730 +#, c-format +msgid "restoring large object with OID %u" +msgstr "reestableciendo objeto grande con OID %u" + +#: pg_backup_archiver.c:1316 +#, c-format +msgid "could not create large object %u: %s" +msgstr "no se pudo crear el objeto grande %u: %s" + +#: pg_backup_archiver.c:1321 pg_dump.c:3693 +#, c-format +msgid "could not open large object %u: %s" +msgstr "no se pudo abrir el objeto grande %u: %s" + +#: pg_backup_archiver.c:1377 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "no se pudo abrir el archivo TOC «%s»: %m" + +#: pg_backup_archiver.c:1405 +#, c-format +msgid "line ignored: %s" +msgstr "línea ignorada: %s" + +#: pg_backup_archiver.c:1412 +#, c-format +msgid "could not find entry for ID %d" +msgstr "no se pudo encontrar una entrada para el ID %d" + +#: pg_backup_archiver.c:1435 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "no se pudo cerrar el archivo TOC: %m" + +#: pg_backup_archiver.c:1549 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:485 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "no se pudo abrir el archivo de salida «%s»: %m" + +#: pg_backup_archiver.c:1551 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "no se pudo abrir el archivo de salida: %m" + +#: pg_backup_archiver.c:1644 +#, c-format +msgid "wrote %zu byte of large object data (result = %d)" +msgid_plural "wrote %zu bytes of large object data (result = %d)" +msgstr[0] "se escribió %zu byte de los datos del objeto grande (resultado = %d)" +msgstr[1] "se escribieron %zu bytes de los datos del objeto grande (resultado = %d)" + +#: pg_backup_archiver.c:1650 +#, c-format +msgid "could not write to large object: %s" +msgstr "no se pudo escribir en objeto grande: %s" + +#: pg_backup_archiver.c:1740 +#, c-format +msgid "while INITIALIZING:" +msgstr "durante INICIALIZACIÓN:" + +#: pg_backup_archiver.c:1745 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "durante PROCESAMIENTO DE TABLA DE CONTENIDOS:" + +#: pg_backup_archiver.c:1750 +#, c-format +msgid "while FINALIZING:" +msgstr "durante FINALIZACIÓN:" + +#: pg_backup_archiver.c:1755 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "en entrada de la tabla de contenidos %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1831 +#, c-format +msgid "bad dumpId" +msgstr "dumpId incorrecto" + +#: pg_backup_archiver.c:1852 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "dumpId de tabla incorrecto para elemento TABLE DATA" + +#: pg_backup_archiver.c:1944 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "bandera de posición inesperada %d" + +#: pg_backup_archiver.c:1957 +#, c-format +msgid "file offset in dump file is too large" +msgstr "el posición en el archivo es demasiado grande" + +#: pg_backup_archiver.c:2095 pg_backup_archiver.c:2105 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "nombre de directorio demasiado largo: «%s»" + +#: pg_backup_archiver.c:2113 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "el directorio «%s» no parece ser un archivador válido (no existe «toc.dat»)" + +#: pg_backup_archiver.c:2121 pg_backup_custom.c:173 pg_backup_custom.c:807 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "no se pudo abrir el archivo de entrada «%s»: %m" + +#: pg_backup_archiver.c:2128 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "no se pudo abrir el archivo de entrada: %m" + +#: pg_backup_archiver.c:2134 +#, c-format +msgid "could not read input file: %m" +msgstr "no se pudo leer el archivo de entrada: %m" + +#: pg_backup_archiver.c:2136 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "el archivo de entrada es demasiado corto (leidos %lu, esperados 5)" + +#: pg_backup_archiver.c:2168 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "el archivo de entrada parece ser un volcado de texto. Por favor use psql." + +#: pg_backup_archiver.c:2174 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "el archivo de entrada no parece ser un archivador válido (¿demasiado corto?)" + +#: pg_backup_archiver.c:2180 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "el archivo de entrada no parece ser un archivador válido" + +#: pg_backup_archiver.c:2189 +#, c-format +msgid "could not close input file: %m" +msgstr "no se pudo cerrar el archivo de entrada: %m" + +#: pg_backup_archiver.c:2306 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "formato de archivo no reconocido «%d»" + +#: pg_backup_archiver.c:2388 pg_backup_archiver.c:4422 +#, c-format +msgid "finished item %d %s %s" +msgstr "terminó el elemento %d %s %s" + +#: pg_backup_archiver.c:2392 pg_backup_archiver.c:4435 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "el proceso hijo falló: código de salida %d" + +#: pg_backup_archiver.c:2512 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "la entrada con ID %d está fuera de rango -- tal vez la tabla de contenido está corrupta" + +#: pg_backup_archiver.c:2579 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "restaurar tablas WITH OIDS ya no está soportado" + +#: pg_backup_archiver.c:2663 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "no se reconoce la codificación: «%s»" + +#: pg_backup_archiver.c:2668 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "elemento ENCODING no válido: %s" + +#: pg_backup_archiver.c:2686 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "elemento STDSTRINGS no válido: %s" + +#: pg_backup_archiver.c:2717 +#, c-format +msgid "invalid TOASTCOMPRESSION item: %s" +msgstr "elemento TOASTCOMPRESSION no válido: %s" + +#: pg_backup_archiver.c:2734 +#, c-format +msgid "schema \"%s\" not found" +msgstr "esquema «%s» no encontrado" + +#: pg_backup_archiver.c:2741 +#, c-format +msgid "table \"%s\" not found" +msgstr "tabla «%s» no encontrada" + +#: pg_backup_archiver.c:2748 +#, c-format +msgid "index \"%s\" not found" +msgstr "índice «%s» no encontrado" + +#: pg_backup_archiver.c:2755 +#, c-format +msgid "function \"%s\" not found" +msgstr "función «%s» no encontrada" + +#: pg_backup_archiver.c:2762 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "disparador «%s» no encontrado" + +#: pg_backup_archiver.c:3160 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "no se pudo establecer el usuario de sesión a «%s»: %s" + +#: pg_backup_archiver.c:3292 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "no se pudo definir search_path a «%s»: %s" + +#: pg_backup_archiver.c:3354 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "no se pudo definir default_tablespace a %s: %s" + +#: pg_backup_archiver.c:3399 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "no se pudo definir default_table_access_method: %s" + +#: pg_backup_archiver.c:3491 pg_backup_archiver.c:3649 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "no se sabe cómo establecer el dueño para el objeto de tipo «%s»" + +#: pg_backup_archiver.c:3753 +#, c-format +msgid "did not find magic string in file header" +msgstr "no se encontró la cadena mágica en el encabezado del archivo" + +#: pg_backup_archiver.c:3767 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "versión no soportada (%d.%d) en el encabezado del archivo" + +#: pg_backup_archiver.c:3772 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "revisión de integridad en el tamaño del entero (%lu) falló" + +#: pg_backup_archiver.c:3776 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "el archivador fue hecho en una máquina con enteros más grandes, algunas operaciones podrían fallar" + +#: pg_backup_archiver.c:3786 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "el formato esperado (%d) difiere del formato encontrado en el archivo (%d)" + +#: pg_backup_archiver.c:3801 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "el archivador está comprimido, pero esta instalación no soporta compresión -- no habrá datos disponibles" + +#: pg_backup_archiver.c:3819 +#, c-format +msgid "invalid creation date in header" +msgstr "la fecha de creación en el encabezado no es válida" + +#: pg_backup_archiver.c:3947 +#, c-format +msgid "processing item %d %s %s" +msgstr "procesando el elemento %d %s %s" + +#: pg_backup_archiver.c:4026 +#, c-format +msgid "entering main parallel loop" +msgstr "ingresando al bucle paralelo principal" + +#: pg_backup_archiver.c:4037 +#, c-format +msgid "skipping item %d %s %s" +msgstr "saltando el elemento %d %s %s" + +#: pg_backup_archiver.c:4046 +#, c-format +msgid "launching item %d %s %s" +msgstr "lanzando el elemento %d %s %s" + +#: pg_backup_archiver.c:4100 +#, c-format +msgid "finished main parallel loop" +msgstr "terminó el bucle paralelo principal" + +#: pg_backup_archiver.c:4136 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "procesando el elemento saltado %d %s %s" + +#: pg_backup_archiver.c:4741 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "la tabla «%s» no pudo ser creada, no se recuperarán sus datos" + +#: pg_backup_custom.c:376 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "OID no válido para objeto grande" + +#: pg_backup_custom.c:439 pg_backup_custom.c:505 pg_backup_custom.c:629 +#: pg_backup_custom.c:865 pg_backup_tar.c:1080 pg_backup_tar.c:1085 +#, c-format +msgid "error during file seek: %m" +msgstr "error durante el posicionamiento (seek) en el archivo: %m" + +#: pg_backup_custom.c:478 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "el bloque de datos %d tiene una posición de búsqueda incorrecta" + +#: pg_backup_custom.c:495 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "tipo de bloque de datos (%d) no conocido al buscar en el archivador" + +#: pg_backup_custom.c:517 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente debido a una petición de restauración fuera de orden, la que no puede ser completada debido a que en el archivo de entrada no es reposicionable (seekable)" + +#: pg_backup_custom.c:522 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente el archivo está corrupto" + +#: pg_backup_custom.c:529 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "se encontró un bloque no esperado ID (%d) mientras se leían los datos -- se esperaba %d" + +#: pg_backup_custom.c:543 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "se encontró un bloque tipo %d no reconocido al restablecer el archivador" + +#: pg_backup_custom.c:645 +#, c-format +msgid "could not read from input file: %m" +msgstr "no se pudo leer el archivo de entrada: %m" + +#: pg_backup_custom.c:746 pg_backup_custom.c:798 pg_backup_custom.c:943 +#: pg_backup_tar.c:1083 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "no se pudo determinar la posición (seek) en el archivo del archivador: %m" + +#: pg_backup_custom.c:762 pg_backup_custom.c:802 +#, c-format +msgid "could not close archive file: %m" +msgstr "no se pudo cerrar el archivo del archivador: %m" + +#: pg_backup_custom.c:785 +#, c-format +msgid "can only reopen input archives" +msgstr "sólo se pueden reabrir archivos de entrada" + +#: pg_backup_custom.c:792 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "la restauración en paralelo desde entrada estándar (stdin) no está soportada" + +#: pg_backup_custom.c:794 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "la restauración en paralelo desde un archivo no posicionable no está soportada" + +#: pg_backup_custom.c:810 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "no se pudo posicionar (seek) en el archivo del archivador: %m" + +#: pg_backup_custom.c:889 +#, c-format +msgid "compressor active" +msgstr "compresor activo" + +#: pg_backup_db.c:42 +#, c-format +msgid "could not get server_version from libpq" +msgstr "no se pudo obtener server_version desde libpq" + +#: pg_backup_db.c:53 pg_dumpall.c:1821 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "versión del servidor: %s; versión de %s: %s" + +#: pg_backup_db.c:55 pg_dumpall.c:1823 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "abortando debido a que no coincide la versión del servidor" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "ya está conectado a una base de datos" + +#: pg_backup_db.c:132 pg_backup_db.c:182 pg_dumpall.c:1650 pg_dumpall.c:1761 +msgid "Password: " +msgstr "Contraseña: " + +#: pg_backup_db.c:174 +#, c-format +msgid "could not connect to database" +msgstr "no se pudo hacer la conexión a la base de datos" + +#: pg_backup_db.c:191 +#, c-format +msgid "reconnection failed: %s" +msgstr "falló la reconexión: %s" + +#: pg_backup_db.c:194 pg_backup_db.c:269 pg_dumpall.c:1681 pg_dumpall.c:1771 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:276 pg_dumpall.c:1884 pg_dumpall.c:1907 +#, c-format +msgid "query failed: %s" +msgstr "la consulta falló: %s" + +#: pg_backup_db.c:278 pg_dumpall.c:1885 pg_dumpall.c:1908 +#, c-format +msgid "query was: %s" +msgstr "la consulta era: %s" + +#: pg_backup_db.c:319 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "la consulta regresó %d fila en lugar de una: %s" +msgstr[1] "la consulta regresó %d filas en lugar de una: %s" + +#: pg_backup_db.c:355 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %sLa orden era: %s" + +#: pg_backup_db.c:411 pg_backup_db.c:485 pg_backup_db.c:492 +msgid "could not execute query" +msgstr "no se pudo ejecutar la consulta" + +#: pg_backup_db.c:464 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "PQputCopyData regresó un error: %s" + +#: pg_backup_db.c:513 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "PQputCopyEnd regresó un error: %s" + +#: pg_backup_db.c:519 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "COPY falló para la tabla «%s»: %s" + +#: pg_backup_db.c:525 pg_dump.c:2077 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "resultados extra inesperados durante el COPY de la tabla «%s»" + +#: pg_backup_db.c:537 +msgid "could not start database transaction" +msgstr "no se pudo iniciar la transacción en la base de datos" + +#: pg_backup_db.c:545 +msgid "could not commit database transaction" +msgstr "no se pudo terminar la transacción a la base de datos" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "no se especificó un directorio de salida" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "no se pudo escribir al archivo de salida: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "no se pudo cerrar el archivo de datos «%s»: %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "no se pudo abrir el archivo de la tabla de contenidos de objetos grandes «%s» para su lectura: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "línea no válida en el archivo de la tabla de contenido de objetos grandes «%s»: «%s»" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "error al leer el archivo de la tabla de contenidos de objetos grandes «%s»" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "no se pudo cerrar el archivo de la tabla de contenido de los objetos grandes «%s»: %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "no se pudo escribir al archivo de la tabla de contenidos de objetos grandes" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "nombre de archivo demasiado largo: «%s»" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "no se puede leer este formato" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "no se pudo abrir el archivo de tabla de contenido «%s» para escribir: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "no se pudo abrir la tabla de contenido para escribir: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:352 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "la compresión no está soportada por el formato de salida tar" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "no se pudo abrir el archivo de tabla de contenido «%s» para leer: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "no se pudo abrir la tabla de contenido para leer: %m" + +#: pg_backup_tar.c:338 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "no se pudo encontrar el archivo «%s» en el archivador" + +#: pg_backup_tar.c:404 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "no se pudo generar el nombre de archivo temporal: %m" + +#: pg_backup_tar.c:415 +#, c-format +msgid "could not open temporary file" +msgstr "no se pudo abrir archivo temporal" + +#: pg_backup_tar.c:442 +#, c-format +msgid "could not close tar member" +msgstr "no se pudo cerrar miembro del archivo tar" + +#: pg_backup_tar.c:685 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "sintaxis de sentencia COPY inesperada: «%s»" + +#: pg_backup_tar.c:952 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "el OID del objeto grande no es válido (%u)" + +#: pg_backup_tar.c:1099 +#, c-format +msgid "could not close temporary file: %m" +msgstr "no se pudo abrir archivo temporal: %m" + +#: pg_backup_tar.c:1108 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "el tamaño real del archivo (%s) no coincide con el esperado (%s)" + +#: pg_backup_tar.c:1165 pg_backup_tar.c:1196 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "no se pudo encontrar el encabezado para el archivo «%s» en el archivo tar" + +#: pg_backup_tar.c:1183 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "la extracción de datos fuera de orden no está soportada en este formato: se requiere «%s», pero viene antes de «%s» en el archivador." + +#: pg_backup_tar.c:1230 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "se encontró un encabezado incompleto (%lu byte)" +msgstr[1] "se encontró un encabezado incompleto (%lu bytes)" + +#: pg_backup_tar.c:1281 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "se encontró un encabezado corrupto en %s (esperado %d, calculado %d) en la posición %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "nombre de sección «%s» no reconocido" + +#: pg_backup_utils.c:55 pg_dump.c:623 pg_dump.c:640 pg_dumpall.c:339 +#: pg_dumpall.c:349 pg_dumpall.c:358 pg_dumpall.c:367 pg_dumpall.c:375 +#: pg_dumpall.c:389 pg_dumpall.c:465 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Prueba «%s --help» para más información.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "elementos on_exit_nicely agotados" + +#: pg_dump.c:549 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "nivel de compresión debe estar en el rango 0..9" + +#: pg_dump.c:587 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_floats_digits debe estar en el rango -15..3" + +#: pg_dump.c:610 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insert debe estar en el rango %d..%d" + +#: pg_dump.c:638 pg_dumpall.c:347 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_dump.c:659 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "las opciones -s/--schema-only y -a/--data-only no pueden usarse juntas" + +#: pg_dump.c:664 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "las opciones -s/--schema-only y --include-foreign-data no pueden usarse juntas" + +#: pg_dump.c:667 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "la opción --include-foreign-data no está soportado con respaldo en paralelo" + +#: pg_dump.c:671 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "las opciones -c/--clean y -a/--data-only no pueden usarse juntas" + +#: pg_dump.c:676 pg_dumpall.c:382 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "la opción --if-exists requiere la opción -c/--clean" + +#: pg_dump.c:683 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "la opción --on-conflict-do-nothing requiere la opción --inserts, --rows-per-insert o --column-inserts" + +#: pg_dump.c:705 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "la compresión solicitada no está soportada en esta instalación -- el archivador será sin compresión" + +#: pg_dump.c:726 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "número no válido de trabajos paralelos" + +#: pg_dump.c:730 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "el volcado en paralelo sólo está soportado por el formato «directory»" + +#: pg_dump.c:785 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Los snapshots sincronizados no están soportados por esta versión del servidor.\n" +"Ejecute con --no-synchronized-snapshots si no los necesita." + +#: pg_dump.c:791 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Los snapshot exportados no están soportados por esta versión de servidor." + +#: pg_dump.c:803 +#, c-format +msgid "last built-in OID is %u" +msgstr "el último OID interno es %u" + +#: pg_dump.c:812 +#, c-format +msgid "no matching schemas were found" +msgstr "no se encontraron esquemas coincidentes" + +#: pg_dump.c:826 +#, c-format +msgid "no matching tables were found" +msgstr "no se encontraron tablas coincidentes" + +#: pg_dump.c:848 +#, c-format +msgid "no matching extensions were found" +msgstr "no se encontraron extensiones coincidentes" + +#: pg_dump.c:1020 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s extrae una base de datos en formato de texto o en otros formatos.\n" +"\n" + +#: pg_dump.c:1021 pg_dumpall.c:618 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_dump.c:1022 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPCIÓN]... [NOMBREDB]\n" + +#: pg_dump.c:1024 pg_dumpall.c:621 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Opciones generales:\n" + +#: pg_dump.c:1025 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=ARCHIVO nombre del archivo o directorio de salida\n" + +#: pg_dump.c:1026 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p Formato del archivo de salida (c=personalizado, \n" +" d=directorio, t=tar, p=texto (por omisión))\n" + +#: pg_dump.c:1028 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=NUM máximo de procesos paralelos para volcar\n" + +#: pg_dump.c:1029 pg_dumpall.c:623 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose modo verboso\n" + +#: pg_dump.c:1030 pg_dumpall.c:624 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de version y salir\n" + +#: pg_dump.c:1031 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 nivel de compresión para formatos comprimidos\n" + +#: pg_dump.c:1032 pg_dumpall.c:625 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " --lock-wait-timeout=SEGS espera a lo más SEGS segundos obtener un lock\n" + +#: pg_dump.c:1033 pg_dumpall.c:652 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_dump.c:1034 pg_dumpall.c:626 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: pg_dump.c:1036 pg_dumpall.c:627 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Opciones que controlan el contenido de la salida:\n" + +#: pg_dump.c:1037 pg_dumpall.c:628 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only extrae sólo los datos, no el esquema\n" + +#: pg_dump.c:1038 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs incluye objetos grandes en la extracción\n" + +#: pg_dump.c:1039 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs excluye objetos grandes en la extracción\n" + +#: pg_dump.c:1040 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, --clean tira (drop) la base de datos antes de crearla\n" + +#: pg_dump.c:1041 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr "" +" -C, --create incluye órdenes para crear la base de datos\n" +" en la extracción\n" + +#: pg_dump.c:1042 +#, c-format +msgid " -e, --extension=PATTERN dump the specified extension(s) only\n" +msgstr " -e, --extension=PATRÓN extrae sólo la o las extensiones nombradas\n" + +#: pg_dump.c:1043 pg_dumpall.c:630 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=CODIF extrae los datos con la codificación CODIF\n" + +#: pg_dump.c:1044 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=PATRÓN extrae sólo el o los esquemas nombrados\n" + +#: pg_dump.c:1045 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=PATRÓN NO extrae el o los esquemas nombrados\n" + +#: pg_dump.c:1046 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner en formato de sólo texto, no reestablece\n" +" los dueños de los objetos\n" + +#: pg_dump.c:1048 pg_dumpall.c:634 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only extrae sólo el esquema, no los datos\n" + +#: pg_dump.c:1049 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, --superuser=NAME superusuario a utilizar en el volcado de texto\n" + +#: pg_dump.c:1050 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=PATRÓN extrae sólo la o las tablas nombradas\n" + +#: pg_dump.c:1051 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=PATRÓN NO extrae la o las tablas nombradas\n" + +#: pg_dump.c:1052 pg_dumpall.c:637 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges no extrae los privilegios (grant/revoke)\n" + +#: pg_dump.c:1053 pg_dumpall.c:638 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade sólo para uso de utilidades de upgrade\n" + +#: pg_dump.c:1054 pg_dumpall.c:639 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr "" +" --column-inserts extrae los datos usando INSERT con nombres\n" +" de columnas\n" + +#: pg_dump.c:1055 pg_dumpall.c:640 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr "" +" --disable-dollar-quoting deshabilita el uso de «delimitadores de dólar»,\n" +" usa delimitadores de cadena estándares\n" + +#: pg_dump.c:1056 pg_dumpall.c:641 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr "" +" --disable-triggers deshabilita los disparadores (triggers) durante el\n" +" restablecimiento de la extracción de sólo-datos\n" + +#: pg_dump.c:1057 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security activa seguridad de filas (volcar sólo el\n" +" contenido al que el usuario tiene acceso)\n" + +#: pg_dump.c:1059 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " --exclude-table-data=PATRÓN NO extrae los datos de la(s) tablas nombradas\n" + +#: pg_dump.c:1060 pg_dumpall.c:643 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM usa este valor para extra_float_digits\n" + +#: pg_dump.c:1061 pg_dumpall.c:644 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists usa IF EXISTS al eliminar objetos\n" + +#: pg_dump.c:1062 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=PATRÓN\n" +" incluye datos de tablas foráneas en servidores\n" +" que coinciden con PATRÓN\n" + +#: pg_dump.c:1065 pg_dumpall.c:645 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr " --inserts extrae los datos usando INSERT, en vez de COPY\n" + +#: pg_dump.c:1066 pg_dumpall.c:646 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root cargar particiones a través de tabla raíz\n" + +#: pg_dump.c:1067 pg_dumpall.c:647 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments no volcar los comentarios\n" + +#: pg_dump.c:1068 pg_dumpall.c:648 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications no volcar las publicaciones\n" + +#: pg_dump.c:1069 pg_dumpall.c:650 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels no volcar asignaciones de etiquetas de seguridad\n" + +#: pg_dump.c:1070 pg_dumpall.c:651 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions no volcar las suscripciones\n" + +#: pg_dump.c:1071 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr "" +" --no-synchronized-snapshots no usar snapshots sincronizados en trabajos\n" +" en paralelo\n" + +#: pg_dump.c:1072 pg_dumpall.c:653 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces no volcar asignaciones de tablespace\n" + +#: pg_dump.c:1073 +#, c-format +msgid " --no-toast-compression do not dump TOAST compression methods\n" +msgstr " --no-toast-compression no volcar métodos de compresión TOAST\n" + +#: pg_dump.c:1074 pg_dumpall.c:654 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data no volcar datos de tablas unlogged\n" + +#: pg_dump.c:1075 pg_dumpall.c:655 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing agregar ON CONFLICT DO NOTHING a órdenes INSERT\n" + +#: pg_dump.c:1076 pg_dumpall.c:656 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr "" +" --quote-all-identifiers entrecomilla todos los identificadores, incluso\n" +" si no son palabras clave\n" + +#: pg_dump.c:1077 pg_dumpall.c:657 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NUMFILAS número de filas por INSERT; implica --inserts\n" + +#: pg_dump.c:1078 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=SECCIÓN volcar la sección nombrada (pre-data, data,\n" +" post-data)\n" + +#: pg_dump.c:1079 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr "" +" --serializable-deferrable espera hasta que el respaldo pueda completarse\n" +" sin anomalías\n" + +#: pg_dump.c:1080 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT use el snapshot dado para la extracción\n" + +#: pg_dump.c:1081 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names requerir al menos una coincidencia para cada patrón\n" +" de nombre de tablas y esquemas\n" + +#: pg_dump.c:1083 pg_dumpall.c:658 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" usa órdenes SESSION AUTHORIZATION en lugar de\n" +" ALTER OWNER para cambiar los dueño de los objetos\n" + +#: pg_dump.c:1087 pg_dumpall.c:662 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Opciones de conexión:\n" + +#: pg_dump.c:1088 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=NOMBRE nombre de la base de datos que volcar\n" + +#: pg_dump.c:1089 pg_dumpall.c:664 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr "" +" -h, --host=ANFITRIÓN anfitrión de la base de datos o\n" +" directorio del enchufe (socket)\n" + +#: pg_dump.c:1090 pg_dumpall.c:666 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PUERTO número del puerto de la base de datos\n" + +#: pg_dump.c:1091 pg_dumpall.c:667 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=USUARIO nombre de usuario con el cual conectarse\n" + +#: pg_dump.c:1092 pg_dumpall.c:668 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password nunca pedir una contraseña\n" + +#: pg_dump.c:1093 pg_dumpall.c:669 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr "" +" -W, --password fuerza un prompt para la contraseña\n" +" (debería ser automático)\n" + +#: pg_dump.c:1094 pg_dumpall.c:670 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROL ejecuta SET ROLE antes del volcado\n" + +#: pg_dump.c:1096 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Si no se especifica un nombre de base de datos, se utiliza el valor\n" +"de la variable de ambiente PGDATABASE.\n" +"\n" + +#: pg_dump.c:1098 pg_dumpall.c:674 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Reporte errores a <%s>.\n" + +#: pg_dump.c:1099 pg_dumpall.c:675 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_dump.c:1118 pg_dumpall.c:500 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "la codificación de cliente especificada «%s» no es válida" + +#: pg_dump.c:1264 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Los snapshots sincronizados en servidores standby no están soportados por esta versión del servidor.\n" +"Ejecute con --no-synchronized-snapshots si no los necesita." + +#: pg_dump.c:1333 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "el formato de salida especificado «%s» no es válido" + +#: pg_dump.c:1371 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "no se encontraron esquemas coincidentes para el patrón «%s»" + +#: pg_dump.c:1418 +#, c-format +msgid "no matching extensions were found for pattern \"%s\"" +msgstr "no se encontraron extensiones coincidentes para el patrón «%s»" + +#: pg_dump.c:1465 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "no se encontraron servidores foráneos coincidentes para el patrón «%s»" + +#: pg_dump.c:1528 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "no se encontraron tablas coincidentes para el patrón «%s»" + +#: pg_dump.c:1951 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "extrayendo el contenido de la tabla «%s.%s»" + +#: pg_dump.c:2058 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Falló la extracción del contenido de la tabla «%s»: PQgetCopyData() falló." + +#: pg_dump.c:2059 pg_dump.c:2069 +#, c-format +msgid "Error message from server: %s" +msgstr "Mensaje de error del servidor: %s" + +#: pg_dump.c:2060 pg_dump.c:2070 +#, c-format +msgid "The command was: %s" +msgstr "La orden era: %s" + +#: pg_dump.c:2068 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Falló la extracción del contenido de la tabla «%s»: PQgetResult() falló." + +#: pg_dump.c:2828 +#, c-format +msgid "saving database definition" +msgstr "salvando las definiciones de la base de datos" + +#: pg_dump.c:3300 +#, c-format +msgid "saving encoding = %s" +msgstr "salvando codificaciones = %s" + +#: pg_dump.c:3325 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "salvando standard_conforming_strings = %s" + +#: pg_dump.c:3364 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "no se pudo interpretar la salida de current_schemas()" + +#: pg_dump.c:3383 +#, c-format +msgid "saving search_path = %s" +msgstr "salvando search_path = %s" + +#: pg_dump.c:3436 +#, c-format +msgid "saving default_toast_compression = %s" +msgstr "salvando default_toast_compression = %s" + +#: pg_dump.c:3475 +#, c-format +msgid "reading large objects" +msgstr "leyendo objetos grandes" + +#: pg_dump.c:3657 +#, c-format +msgid "saving large objects" +msgstr "salvando objetos grandes" + +#: pg_dump.c:3703 +#, c-format +msgid "error reading large object %u: %s" +msgstr "error al leer el objeto grande %u: %s" + +#: pg_dump.c:3755 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "leyendo si seguridad de filas está activa para la tabla «%s.%s»" + +#: pg_dump.c:3786 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "extrayendo las políticas para la tabla «%s.%s»" + +#: pg_dump.c:3938 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "tipo de orden inesperada en política: %c" + +#: pg_dump.c:4092 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "el dueño de la publicación «%s» parece no ser válido" + +#: pg_dump.c:4384 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "no se volcaron las suscripciones porque el usuario actual no es un superusuario" + +#: pg_dump.c:4455 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "el dueño de la suscripción «%s» parece no ser válido" + +#: pg_dump.c:4498 +#, c-format +msgid "could not parse subpublications array" +msgstr "no se pudo interpretar el arreglo subpublications" + +#: pg_dump.c:4856 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "no se pudo encontrar la extensión padre para %s %s" + +#: pg_dump.c:4988 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "el dueño del esquema «%s» parece no ser válido" + +#: pg_dump.c:5011 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "no existe el esquema con OID %u" + +#: pg_dump.c:5340 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "el dueño del tipo «%s» parece no ser válido" + +#: pg_dump.c:5424 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "el dueño del operador «%s» parece no ser válido" + +#: pg_dump.c:5723 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "el dueño de la clase de operadores «%s» parece no ser válido" + +#: pg_dump.c:5806 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "el dueño de la familia de operadores «%s» parece no ser válido" + +#: pg_dump.c:5974 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "el dueño de la función de agregación «%s» parece no ser válido" + +#: pg_dump.c:6233 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "el dueño de la función «%s» parece no ser válido" + +#: pg_dump.c:7060 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "el dueño de la tabla «%s» parece no ser válido" + +#: pg_dump.c:7102 pg_dump.c:17493 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "falló la revisión de integridad, no se encontró la tabla padre con OID %u de la secuencia con OID %u" + +#: pg_dump.c:7241 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "extrayendo los índices para la tabla «%s.%s»" + +#: pg_dump.c:7655 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "extrayendo restricciones de llave foránea para la tabla «%s.%s»" + +#: pg_dump.c:7934 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "falló la revisión de integridad, no se encontró la tabla padre con OID %u del elemento con OID %u de pg_rewrite" + +#: pg_dump.c:8017 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "extrayendo los disparadores (triggers) para la tabla «%s.%s»" + +#: pg_dump.c:8150 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "la consulta produjo un nombre de tabla nulo para la llave foránea del disparador \"%s\" en la tabla «%s» (OID de la tabla: %u)" + +#: pg_dump.c:8700 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "buscando las columnas y tipos de la tabla «%s.%s»" + +#: pg_dump.c:8824 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "numeración de columnas no válida en la tabla «%s»" + +#: pg_dump.c:8863 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "buscando expresiones por omisión de la tabla «%s.%s»" + +#: pg_dump.c:8885 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "el valor de adnum %d para la tabla «%s» no es válido" + +#: pg_dump.c:8978 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "buscando restricciones de revisión (check) para la tabla «%s.%s»" + +#: pg_dump.c:9027 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "se esperaban %d restricciones CHECK en la tabla «%s» pero se encontraron %d" +msgstr[1] "se esperaban %d restricciones CHECK en la tabla «%s» pero se encontraron %d" + +#: pg_dump.c:9031 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Los catálogos del sistema podrían estar corruptos)" + +#: pg_dump.c:10616 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "el typtype del tipo «%s» parece no ser válido" + +#: pg_dump.c:11968 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "valor no válido en el arreglo proargmodes" + +#: pg_dump.c:12275 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "no se pudo interpretar el arreglo proallargtypes" + +#: pg_dump.c:12291 +#, c-format +msgid "could not parse proargmodes array" +msgstr "no se pudo interpretar el arreglo proargmodes" + +#: pg_dump.c:12305 +#, c-format +msgid "could not parse proargnames array" +msgstr "no se pudo interpretar el arreglo proargnames" + +#: pg_dump.c:12315 +#, c-format +msgid "could not parse proconfig array" +msgstr "no se pudo interpretar el arreglo proconfig" + +#: pg_dump.c:12395 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "el valor del atributo «provolatile» para la función «%s» es desconocido" + +#: pg_dump.c:12445 pg_dump.c:14396 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "el valor del atributo «proparallel» para la función «%s» es desconocido" + +#: pg_dump.c:12584 pg_dump.c:12693 pg_dump.c:12700 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "no se encontró la definición de la función con OID %u" + +#: pg_dump.c:12623 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "valor no válido en los campos pg_cast.castfunc o pg_cast.castmethod" + +#: pg_dump.c:12626 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "valor no válido en el campo pg_cast.castmethod" + +#: pg_dump.c:12719 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "definición errónea de transformación; al menos uno de trffromsql and trftosql debe ser distinto de cero" + +#: pg_dump.c:12736 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "valor erróneo en el campo pg_transform.trffromsql" + +#: pg_dump.c:12757 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "valor erróneo en el campo pg_transform.trftosql" + +#: pg_dump.c:12909 +#, c-format +msgid "postfix operators are not supported anymore (operator \"%s\")" +msgstr "los operadores postfix ya no están soportados (operador «%s»)" + +#: pg_dump.c:13079 +#, c-format +msgid "could not find operator with OID %s" +msgstr "no se pudo encontrar el operador con OID %s" + +#: pg_dump.c:13147 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "el tipo «%c» para el método de acceso «%s» no es válido" + +#: pg_dump.c:13901 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "proveedor de ordenamiento no reconocido: %s" + +#: pg_dump.c:14315 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "valor de aggfinalmodify no reconocido para la agregación «%s»" + +#: pg_dump.c:14371 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "valor de aggmfinalmodify no reconocido para la agregación «%s»" + +#: pg_dump.c:15093 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "tipo de objeto desconocido en privilegios por omisión: %d" + +#: pg_dump.c:15111 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "no se pudo interpretar la lista de ACL (%s)" + +#: pg_dump.c:15196 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "no se pudo interpretar la lista inicial de GRANT ACL (%s) o la lista inicial de REVOKE ACL (%s) para el objeto «%s» (%s)" + +#: pg_dump.c:15204 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "no se pudo interpretar la lista de GRANT ACL (%s) o la lista de REVOKE ACL (%s) para el objeto «%s» (%s)" + +#: pg_dump.c:15719 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "la consulta para obtener la definición de la vista «%s» no regresó datos" + +#: pg_dump.c:15722 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "la consulta para obtener la definición de la vista «%s» regresó más de una definición" + +#: pg_dump.c:15729 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "la definición de la vista «%s» parece estar vacía (tamaño cero)" + +#: pg_dump.c:15813 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS ya no está soportado (tabla «%s»)" + +#: pg_dump.c:16680 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "el número de columna %d no es válido para la tabla «%s»" + +#: pg_dump.c:16757 +#, c-format +msgid "could not parse index statistic columns" +msgstr "no se pudieron interpretar columnas de estadísticas de índices" + +#: pg_dump.c:16759 +#, c-format +msgid "could not parse index statistic values" +msgstr "no se pudieron interpretar valores de estadísticas de índices" + +#: pg_dump.c:16761 +#, c-format +msgid "mismatched number of columns and values for index statistics" +msgstr "no coincide el número de columnas con el de valores para estadísticas de índices" + +#: pg_dump.c:16978 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "falta un índice para restricción «%s»" + +#: pg_dump.c:17203 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "tipo de restricción inesperado: %c" + +#: pg_dump.c:17335 pg_dump.c:17558 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "la consulta para obtener los datos de la secuencia «%s» regresó %d entrada, pero se esperaba 1" +msgstr[1] "la consulta para obtener los datos de la secuencia «%s» regresó %d entradas, pero se esperaba 1" + +#: pg_dump.c:17369 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "tipo no reconocido de secuencia: %s" + +#: pg_dump.c:17656 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "tgtype no esperado: %d" + +#: pg_dump.c:17730 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "argumento de cadena (%s) no válido para el disparador (trigger) «%s» en la tabla «%s»" + +#: pg_dump.c:17966 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "la consulta para obtener la regla «%s» asociada con la tabla «%s» falló: retornó un número incorrecto de renglones" + +#: pg_dump.c:18128 +#, c-format +msgid "could not find referenced extension %u" +msgstr "no se pudo encontrar la extensión referenciada %u" + +#: pg_dump.c:18219 +#, c-format +msgid "could not parse extension configuration array" +msgstr "no se pudo interpretar el arreglo de configuración de extensión" + +#: pg_dump.c:18221 +#, c-format +msgid "could not parse extension condition array" +msgstr "no se pudo interpretar el arreglo de condición de extensión" + +#: pg_dump.c:18223 +#, c-format +msgid "mismatched number of configurations and conditions for extension" +msgstr "no coincide el número de configuraciones con el de condiciones para extensión" + +#: pg_dump.c:18355 +#, c-format +msgid "reading dependency data" +msgstr "obteniendo datos de dependencias" + +#: pg_dump.c:18448 +#, c-format +msgid "no referencing object %u %u" +msgstr "no existe el objeto referenciante %u %u" + +#: pg_dump.c:18459 +#, c-format +msgid "no referenced object %u %u" +msgstr "no existe el objeto referenciado %u %u" + +#: pg_dump.c:18833 +#, c-format +msgid "could not parse reloptions array" +msgstr "no se pudo interpretar el arreglo reloptions" + +#: pg_dump_sort.c:411 +#, c-format +msgid "invalid dumpId %d" +msgstr "dumpId %d no válido" + +#: pg_dump_sort.c:417 +#, c-format +msgid "invalid dependency %d" +msgstr "dependencia %d no válida" + +#: pg_dump_sort.c:650 +#, c-format +msgid "could not identify dependency loop" +msgstr "no se pudo identificar bucle de dependencia" + +#: pg_dump_sort.c:1221 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "hay restricciones de llave foránea circulares en la siguiente tabla:" +msgstr[1] "hay restricciones de llave foránea circulares entre las siguientes tablas:" + +#: pg_dump_sort.c:1225 pg_dump_sort.c:1245 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1226 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Puede no ser capaz de restaurar el respaldo sin usar --disable-triggers o temporalmente eliminar las restricciones." + +#: pg_dump_sort.c:1227 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Considere usar un volcado completo en lugar de --data-only para evitar este problema." + +#: pg_dump_sort.c:1239 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "no se pudo resolver el bucle de dependencias entre los siguientes elementos:" + +#: pg_dumpall.c:200 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%s necesita el programa «%s» pero no fue encontrado en el\n" +"mismo directorio que «%s».\n" +"Verifique su instalación." + +#: pg_dumpall.c:205 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"El programa «%s» fue encontrado por «%s»\n" +"but no era de la misma versión que %s.\n" +"Verifique su instalación." + +#: pg_dumpall.c:357 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "la opción --exclude-database no puede ser usada junto con -g/--globals-only, -r/--roles-only o -t/--tablespaces-only" + +#: pg_dumpall.c:366 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "las opciones -g/--globals-only y -r/--roles-only no pueden usarse juntas" + +#: pg_dumpall.c:374 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "las opciones -g/--globals-only y -t/--tablespaces-only no pueden usarse juntas" + +#: pg_dumpall.c:388 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "las opciones -r/--roles-only y -t/--tablespaces-only no pueden usarse juntas" + +#: pg_dumpall.c:449 pg_dumpall.c:1751 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "no se pudo establecer la conexión a la base de datos «%s»" + +#: pg_dumpall.c:463 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"no se pudo establecer la conexión a las bases de datos «postgres» o\n" +"«template1». Por favor especifique una base de datos para conectarse." + +#: pg_dumpall.c:617 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s extrae un cluster de bases de datos de PostgreSQL en un archivo\n" +"guión (script) SQL.\n" +"\n" + +#: pg_dumpall.c:619 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPCIÓN]...\n" + +#: pg_dumpall.c:622 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=ARCHIVO nombre del archivo de salida\n" + +#: pg_dumpall.c:629 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, --clean tira (drop) la base de datos antes de crearla\n" + +#: pg_dumpall.c:631 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, --globals-only extrae sólo los objetos globales, no bases de datos\n" + +#: pg_dumpall.c:632 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner no reestablece los dueños de los objetos\n" + +#: pg_dumpall.c:633 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr "" +" -r, --roles-only extrae sólo los roles, no bases de datos\n" +" ni tablespaces\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr "" +" -S, --superuser=NAME especifica el nombre del superusuario a usar en\n" +" el volcado\n" + +#: pg_dumpall.c:636 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr "" +" -t, --tablespaces-only extrae sólo los tablespaces, no bases de datos\n" +" ni roles\n" + +#: pg_dumpall.c:642 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=PATRÓN excluir bases de datos cuyos nombres coinciden con el patrón\n" + +#: pg_dumpall.c:649 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords no extraer contraseñas para roles\n" + +#: pg_dumpall.c:663 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=CONNSTR conectar usando la cadena de conexión\n" + +#: pg_dumpall.c:665 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=NOMBRE especifica la base de datos a la cual conectarse\n" + +#: pg_dumpall.c:672 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"Si no se usa -f/--file, el volcado de SQL será escrito a la salida estándar.\n" +"\n" + +#: pg_dumpall.c:878 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "omitido nombre de rol que empieza con «pg_» (%s)" + +#: pg_dumpall.c:1279 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "no se pudo interpretar la lista de control de acceso (%s) del tablespace «%s»" + +#: pg_dumpall.c:1496 +#, c-format +msgid "excluding database \"%s\"" +msgstr "excluyendo base de datos «%s»" + +#: pg_dumpall.c:1500 +#, c-format +msgid "dumping database \"%s\"" +msgstr "extrayendo base de datos «%s»" + +#: pg_dumpall.c:1532 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump falló en la base de datos «%s», saliendo" + +#: pg_dumpall.c:1541 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "no se pudo reabrir el archivo de salida «%s»: %m" + +#: pg_dumpall.c:1585 +#, c-format +msgid "running \"%s\"" +msgstr "ejecutando «%s»" + +#: pg_dumpall.c:1800 +#, c-format +msgid "could not get server version" +msgstr "no se pudo obtener la versión del servidor" + +#: pg_dumpall.c:1806 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "no se pudo interpretar la versión del servidor «%s»" + +#: pg_dumpall.c:1878 pg_dumpall.c:1901 +#, c-format +msgid "executing %s" +msgstr "ejecutando %s" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "una de las opciones -d/--dbname y -f/--file debe especificarse" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "las opciones -d/--dbname y -f/--file no pueden usarse juntas" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "las opciones -c/--clean y -1/--single-transaction no pueden usarse juntas" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "el número máximo de trabajos en paralelo es %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "no se puede especificar --single-transaction junto con múltiples tareas" + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "formato de archivo «%s» no reconocido; por favor especifique «c», «d» o «t»" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "errores ignorados durante la recuperación: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s reestablece una base de datos de PostgreSQL usando un archivo\n" +"creado por pg_dump.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [OPCIÓN]... [ARCHIVO]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=NOMBRE nombre de la base de datos a la que conectarse\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=ARCHIVO nombre del archivo de salida (- para stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, --format=c|d|t formato del volcado (debería ser automático)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr "" +" -l, --list imprime una tabla resumida de contenidos\n" +" del archivador\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose modo verboso\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Opciones que controlan la recuperación:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only reestablece sólo los datos, no el esquema\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create crea la base de datos de destino\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr "" +" -e, --exit-on-error abandonar al encontrar un error\n" +" por omisión, se continúa la restauración\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=NOMBRE reestablece el índice nombrado\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, --jobs=NUM máximo de procesos paralelos para restaurar\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=ARCHIVO usa la tabla de contenido especificada para ordenar\n" +" la salida de este archivo\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NAME reestablece sólo los objetos en este esquema\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NAME no reestablecer los objetos en este esquema\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NOMBRE(args) reestablece la función nombrada\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only reestablece el esquema únicamente, no los datos\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr "" +" -S, --superuser=NOMBRE especifica el nombre del superusuario que se usa\n" +" para deshabilitar los disparadores (triggers)\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=NOMBRE reestablece la relación (tabla, vista, etc.) nombrada\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=NOMBRE reestablece el disparador (trigger) nombrado\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, --no-privileges no reestablece los privilegios (grant/revoke)\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction reestablece en una única transacción\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security activa seguridad de filas\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments no restaurar comentarios\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables no reestablece datos de tablas que no pudieron\n" +" ser creadas\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications no restaurar publicaciones\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels no restaura etiquetas de seguridad\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions no restaurar suscripciones\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces no vuelca asignaciones de tablespace\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=SECCIÓN reestablece la sección nombrada (pre-data, data\n" +" post-data)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROLENAME hace SET ROLE antes de restaurar\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"Las opciones -I, -n, -N, -P, -t, -T, y --section pueden ser combinadas y especificadas\n" +"varias veces para seleccionar varios objetos.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"Si no se especifica un archivo de entrada, se usa la entrada estándar.\n" +"\n" + +#~ msgid "could not connect to database \"%s\": %s" +#~ msgstr "no se pudo conectar a la base de datos «%s»: %s" + +#~ msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +#~ msgstr "la función de agregación «%s» no se pudo extraer correctamente para esta versión de la base de datos; ignorada" + +#~ msgid "reading publication membership for table \"%s.%s\"" +#~ msgstr "extrayendo la membresía en publicaciones para la tabla «%s.%s»" + +#~ msgid "connection to database \"%s\" failed: %s" +#~ msgstr "falló la conexión a la base de datos «%s»: %s" + +#~ msgid "connection needs password" +#~ msgstr "la conexión necesita contraseña" + +#~ msgid "could not reconnect to database: %s" +#~ msgstr "no se pudo hacer la reconexión a la base de datos: %s" + +#~ msgid "could not reconnect to database" +#~ msgstr "no se pudo hacer la reconexión a la base de datos" + +#~ msgid "connecting to database \"%s\" as user \"%s\"" +#~ msgstr "conectandose a la base de datos \"%s\" como el usuario «%s»" + +#~ msgid "could not write to large object (result: %lu, expected: %lu)" +#~ msgstr "no se pudo escribir al objecto grande (resultado: %lu, esperado: %lu)" + +#~ msgid "select() failed: %m" +#~ msgstr "select() fallida: %m" + +#~ msgid "WSAStartup failed: %d" +#~ msgstr "WSAStartup falló: %d" + +#~ msgid "pclose failed: %m" +#~ msgstr "pclose falló: %m" diff --git a/src/bin/pg_dump/po/fr.po b/src/bin/pg_dump/po/fr.po new file mode 100644 index 000000000000..cb3002ecca3d --- /dev/null +++ b/src/bin/pg_dump/po/fr.po @@ -0,0 +1,3312 @@ +# translation of pg_dump.po to fr_fr +# french message translation file for pg_dump +# +# Use these quotes: « %s » +# +# Guillaume Lelarge , 2004-2009. +# Stéphane Schildknecht , 2009. +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-28 00:48+0000\n" +"PO-Revision-Date: 2021-05-28 15:23+0200\n" +"Last-Translator: Guillaume Lelarge \n" +"Language-Team: PostgreSQLfr \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "binaire « %s » invalide" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "n'a pas pu lire le binaire « %s »" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "n'a pas pu trouver un « %s » à exécuter" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" + +#: ../../common/exec.c:409 parallel.c:1614 +#, c-format +msgid "%s() failed: %m" +msgstr "échec de %s() : %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +msgid "out of memory" +msgstr "mémoire épuisée" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "commande non exécutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "commande introuvable" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "le processus fils a quitté avec le code de sortie %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "le processus fils a été terminé par l'exception 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "le processus fils a été terminé par le signal %d : %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "le processus fils a quitté avec un statut %d non reconnu" + +#: common.c:124 +#, c-format +msgid "reading extensions" +msgstr "lecture des extensions" + +#: common.c:128 +#, c-format +msgid "identifying extension members" +msgstr "identification des membres d'extension" + +#: common.c:131 +#, c-format +msgid "reading schemas" +msgstr "lecture des schémas" + +#: common.c:141 +#, c-format +msgid "reading user-defined tables" +msgstr "lecture des tables utilisateur" + +#: common.c:148 +#, c-format +msgid "reading user-defined functions" +msgstr "lecture des fonctions utilisateur" + +#: common.c:153 +#, c-format +msgid "reading user-defined types" +msgstr "lecture des types utilisateur" + +#: common.c:158 +#, c-format +msgid "reading procedural languages" +msgstr "lecture des langages procéduraux" + +#: common.c:161 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "lecture des fonctions d'agrégats utilisateur" + +#: common.c:164 +#, c-format +msgid "reading user-defined operators" +msgstr "lecture des opérateurs utilisateur" + +#: common.c:168 +#, c-format +msgid "reading user-defined access methods" +msgstr "lecture des méthodes d'accès définis par les utilisateurs" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator classes" +msgstr "lecture des classes d'opérateurs utilisateur" + +#: common.c:174 +#, c-format +msgid "reading user-defined operator families" +msgstr "lecture des familles d'opérateurs utilisateur" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "lecture des analyseurs utilisateur pour la recherche plein texte" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search templates" +msgstr "lecture des modèles utilisateur pour la recherche plein texte" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "lecture des dictionnaires utilisateur pour la recherche plein texte" + +#: common.c:186 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "lecture des configurations utilisateur pour la recherche plein texte" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "lecture des wrappers de données distantes utilisateur" + +#: common.c:192 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "lecture des serveurs distants utilisateur" + +#: common.c:195 +#, c-format +msgid "reading default privileges" +msgstr "lecture des droits par défaut" + +#: common.c:198 +#, c-format +msgid "reading user-defined collations" +msgstr "lecture des collationnements utilisateurs" + +#: common.c:202 +#, c-format +msgid "reading user-defined conversions" +msgstr "lecture des conversions utilisateur" + +#: common.c:205 +#, c-format +msgid "reading type casts" +msgstr "lecture des conversions de type" + +#: common.c:208 +#, c-format +msgid "reading transforms" +msgstr "lecture des transformations" + +#: common.c:211 +#, c-format +msgid "reading table inheritance information" +msgstr "lecture des informations d'héritage des tables" + +#: common.c:214 +#, c-format +msgid "reading event triggers" +msgstr "lecture des triggers sur évènement" + +#: common.c:218 +#, c-format +msgid "finding extension tables" +msgstr "recherche des tables d'extension" + +#: common.c:222 +#, c-format +msgid "finding inheritance relationships" +msgstr "recherche des relations d'héritage" + +#: common.c:225 +#, c-format +msgid "reading column info for interesting tables" +msgstr "lecture des informations de colonnes des tables intéressantes" + +#: common.c:228 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "marquage des colonnes héritées dans les sous-tables" + +#: common.c:231 +#, c-format +msgid "reading indexes" +msgstr "lecture des index" + +#: common.c:234 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "décrit les index des tables partitionnées" + +#: common.c:237 +#, c-format +msgid "reading extended statistics" +msgstr "lecture des statistiques étendues" + +#: common.c:240 +#, c-format +msgid "reading constraints" +msgstr "lecture des contraintes" + +#: common.c:243 +#, c-format +msgid "reading triggers" +msgstr "lecture des triggers" + +#: common.c:246 +#, c-format +msgid "reading rewrite rules" +msgstr "lecture des règles de réécriture" + +#: common.c:249 +#, c-format +msgid "reading policies" +msgstr "lecture des politiques" + +#: common.c:252 +#, c-format +msgid "reading publications" +msgstr "lecture des publications" + +#: common.c:257 +#, c-format +msgid "reading publication membership" +msgstr "lecture des appartenances aux publications" + +#: common.c:260 +#, c-format +msgid "reading subscriptions" +msgstr "lecture des souscriptions" + +#: common.c:338 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "nombre de parents invalide (%d) pour la table « %s »" + +#: common.c:1100 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "vérification échouée, OID %u parent de la table « %s » (OID %u) introuvable" + +#: common.c:1142 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "n'a pas pu analyser le tableau numérique « %s » : trop de nombres" + +#: common.c:1157 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "n'a pas pu analyser le tableau numérique « %s » : caractère invalide dans le nombre" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "code de compression invalide : %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "pas construit avec le support de zlib" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "n'a pas pu initialiser la bibliothèque de compression : %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "n'a pas pu fermer le flux de compression : %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "n'a pas pu compresser les données : %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "n'a pas pu décompresser les données : %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "n'a pas pu fermer la bibliothèque de compression : %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:551 pg_backup_tar.c:554 +#, c-format +msgid "could not read from input file: %s" +msgstr "n'a pas pu lire à partir du fichier en entrée : %s" + +#: compress_io.c:623 pg_backup_custom.c:643 pg_backup_directory.c:552 +#: pg_backup_tar.c:787 pg_backup_tar.c:810 +#, c-format +msgid "could not read from input file: end of file" +msgstr "n'a pas pu lire à partir du fichier en entrée : fin du fichier" + +#: parallel.c:254 +#, c-format +msgid "%s() failed: error code %d" +msgstr "échec de %s() : code d'erreur %d" + +#: parallel.c:964 +#, c-format +msgid "could not create communication channels: %m" +msgstr "n'a pas pu créer le canal de communication : %m" + +#: parallel.c:1021 +#, c-format +msgid "could not create worker process: %m" +msgstr "n'a pas pu créer le processus worker : %m" + +#: parallel.c:1151 +#, c-format +msgid "unrecognized command received from leader: \"%s\"" +msgstr "commande non reconnue reçue du leader : « %s »" + +#: parallel.c:1194 parallel.c:1432 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "message invalide reçu du worker: « %s »" + +#: parallel.c:1326 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"impossible d'obtenir un verrou sur la relation « %s »\n" +"Cela signifie en général que quelqu'un a demandé un verrou ACCESS EXCLUSIVE sur la table après que pg_dump ait obtenu son verrou ACCESS SHARE initial sur la table." + +#: parallel.c:1415 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "un processus worker a subi un arrêt brutal inattendu" + +#: parallel.c:1537 parallel.c:1655 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "n'a pas pu écrire dans le canal de communication: %m" + +#: parallel.c:1739 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: n'a pas pu créer le socket: code d'erreur %d" + +#: parallel.c:1750 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: n'a pas pu se lier: code d'erreur %d" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe : n'a pas pu se mettre en écoute: code d'erreur %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: %s() failed: error code %d" +msgstr "pgpipe: échec de %s() : code d'erreur %d" + +#: parallel.c:1775 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: n'a pas pu créer un deuxième socket: code d'erreur %d" + +#: parallel.c:1784 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: n'a pas pu se connecter au socket: code d'erreur %d" + +#: parallel.c:1793 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: n'a pas pu accepter de connexion: code d'erreur %d" + +#: pg_backup_archiver.c:277 pg_backup_archiver.c:1576 +#, c-format +msgid "could not close output file: %m" +msgstr "n'a pas pu fermer le fichier en sortie : %m" + +#: pg_backup_archiver.c:321 pg_backup_archiver.c:325 +#, c-format +msgid "archive items not in correct section order" +msgstr "les éléments de l'archive ne sont pas dans l'ordre correct de la section" + +#: pg_backup_archiver.c:331 +#, c-format +msgid "unexpected section code %d" +msgstr "code de section inattendu %d" + +#: pg_backup_archiver.c:368 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "la restauration parallélisée n'est pas supportée avec ce format de fichier d'archive" + +#: pg_backup_archiver.c:372 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "la restauration parallélisée n'est pas supportée avec les archives réalisées par un pg_dump antérieur à la 8.0" + +#: pg_backup_archiver.c:390 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "ne peut pas restaurer à partir de l'archive compressée (compression indisponible dans cette installation)" + +#: pg_backup_archiver.c:407 +#, c-format +msgid "connecting to database for restore" +msgstr "connexion à la base de données pour la restauration" + +#: pg_backup_archiver.c:409 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "les connexions directes à la base de données ne sont pas supportées dans les archives pre-1.3" + +#: pg_backup_archiver.c:452 +#, c-format +msgid "implied data-only restore" +msgstr "a impliqué une restauration des données uniquement" + +#: pg_backup_archiver.c:518 +#, c-format +msgid "dropping %s %s" +msgstr "suppression de %s %s" + +#: pg_backup_archiver.c:613 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "n'a pas pu trouver où insérer IF EXISTS dans l'instruction « %s »" + +#: pg_backup_archiver.c:769 pg_backup_archiver.c:771 +#, c-format +msgid "warning from original dump file: %s" +msgstr "message d'avertissement du fichier de sauvegarde original : %s" + +#: pg_backup_archiver.c:786 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "création de %s « %s.%s »" + +#: pg_backup_archiver.c:789 +#, c-format +msgid "creating %s \"%s\"" +msgstr "création de %s « %s »" + +#: pg_backup_archiver.c:839 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "connexion à la nouvelle base de données « %s »" + +#: pg_backup_archiver.c:866 +#, c-format +msgid "processing %s" +msgstr "traitement de %s" + +#: pg_backup_archiver.c:886 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "traitement des données de la table « %s.%s »" + +#: pg_backup_archiver.c:948 +#, c-format +msgid "executing %s %s" +msgstr "exécution de %s %s" + +#: pg_backup_archiver.c:987 +#, c-format +msgid "disabling triggers for %s" +msgstr "désactivation des triggers pour %s" + +#: pg_backup_archiver.c:1013 +#, c-format +msgid "enabling triggers for %s" +msgstr "activation des triggers pour %s" + +#: pg_backup_archiver.c:1041 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "erreur interne -- WriteData ne peut pas être appelé en dehors du contexte de la routine DataDumper" + +#: pg_backup_archiver.c:1224 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "la sauvegarde des « Large Objects » n'est pas supportée dans le format choisi" + +#: pg_backup_archiver.c:1282 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "restauration de %d « Large Object »" +msgstr[1] "restauration de %d « Large Objects »" + +#: pg_backup_archiver.c:1303 pg_backup_tar.c:730 +#, c-format +msgid "restoring large object with OID %u" +msgstr "restauration du « Large Object » d'OID %u" + +#: pg_backup_archiver.c:1315 +#, c-format +msgid "could not create large object %u: %s" +msgstr "n'a pas pu créer le « Large Object » %u : %s" + +#: pg_backup_archiver.c:1320 pg_dump.c:3638 +#, c-format +msgid "could not open large object %u: %s" +msgstr "n'a pas pu ouvrir le « Large Object » %u : %s" + +#: pg_backup_archiver.c:1376 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier TOC « %s » : %m" + +#: pg_backup_archiver.c:1404 +#, c-format +msgid "line ignored: %s" +msgstr "ligne ignorée : %s" + +#: pg_backup_archiver.c:1411 +#, c-format +msgid "could not find entry for ID %d" +msgstr "n'a pas pu trouver l'entrée pour l'ID %d" + +#: pg_backup_archiver.c:1434 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "n'a pas pu fermer le fichier TOC : %m" + +#: pg_backup_archiver.c:1548 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:489 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier de sauvegarde « %s » : %m" + +#: pg_backup_archiver.c:1550 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "n'a pas pu ouvrir le fichier de sauvegarde : %m" + +#: pg_backup_archiver.c:1643 +#, c-format +msgid "wrote %zu byte of large object data (result = %d)" +msgid_plural "wrote %zu bytes of large object data (result = %d)" +msgstr[0] "a écrit %zu octet de données d'un « Large Object » (résultat = %d)" +msgstr[1] "a écrit %zu octets de données d'un « Large Object » (résultat = %d)" + +#: pg_backup_archiver.c:1649 +#, c-format +msgid "could not write to large object: %s" +msgstr "n'a pas pu écrire dans le « Large Object » : %s" + +#: pg_backup_archiver.c:1739 +#, c-format +msgid "while INITIALIZING:" +msgstr "pendant l'initialisation (« INITIALIZING ») :" + +#: pg_backup_archiver.c:1744 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "pendant le traitement de la TOC (« PROCESSING TOC ») :" + +#: pg_backup_archiver.c:1749 +#, c-format +msgid "while FINALIZING:" +msgstr "pendant la finalisation (« FINALIZING ») :" + +#: pg_backup_archiver.c:1754 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "de l'entrée TOC %d ; %u %u %s %s %s" + +#: pg_backup_archiver.c:1830 +#, c-format +msgid "bad dumpId" +msgstr "mauvais dumpId" + +#: pg_backup_archiver.c:1851 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "mauvais dumpId de table pour l'élément TABLE DATA" + +#: pg_backup_archiver.c:1943 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "drapeau de décalage de données inattendu %d" + +#: pg_backup_archiver.c:1956 +#, c-format +msgid "file offset in dump file is too large" +msgstr "le décalage dans le fichier de sauvegarde est trop important" + +#: pg_backup_archiver.c:2094 pg_backup_archiver.c:2104 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "nom du répertoire trop long : « %s »" + +#: pg_backup_archiver.c:2112 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "le répertoire « %s » ne semble pas être une archive valide (« toc.dat » n'existe pas)" + +#: pg_backup_archiver.c:2120 pg_backup_custom.c:173 pg_backup_custom.c:807 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier en entrée « %s » : %m" + +#: pg_backup_archiver.c:2127 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "n'a pas pu ouvrir le fichier en entrée : %m" + +#: pg_backup_archiver.c:2133 +#, c-format +msgid "could not read input file: %m" +msgstr "n'a pas pu lire le fichier en entrée : %m" + +#: pg_backup_archiver.c:2135 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "le fichier en entrée est trop petit (%lu lus, 5 attendus)" + +#: pg_backup_archiver.c:2167 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "Le fichier en entrée semble être une sauvegarde au format texte. Merci d'utiliser psql." + +#: pg_backup_archiver.c:2173 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "le fichier en entrée ne semble pas être une archive valide (trop petit ?)" + +#: pg_backup_archiver.c:2179 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "le fichier en entrée ne semble pas être une archive valide" + +#: pg_backup_archiver.c:2188 +#, c-format +msgid "could not close input file: %m" +msgstr "n'a pas pu fermer le fichier en entrée : %m" + +#: pg_backup_archiver.c:2305 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "format de fichier « %d » non reconnu" + +#: pg_backup_archiver.c:2387 pg_backup_archiver.c:4390 +#, c-format +msgid "finished item %d %s %s" +msgstr "élément terminé %d %s %s" + +#: pg_backup_archiver.c:2391 pg_backup_archiver.c:4403 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "échec du processus worker : code de sortie %d" + +#: pg_backup_archiver.c:2511 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "ID %d de l'entrée en dehors de la plage -- peut-être un TOC corrompu" + +#: pg_backup_archiver.c:2578 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "la restauration des tables avec WITH OIDS n'est plus supportée" + +#: pg_backup_archiver.c:2660 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "encodage « %s » non reconnu" + +#: pg_backup_archiver.c:2665 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "élément ENCODING invalide : %s" + +#: pg_backup_archiver.c:2683 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "élément STDSTRINGS invalide : %s" + +#: pg_backup_archiver.c:2708 +#, c-format +msgid "schema \"%s\" not found" +msgstr "schéma « %s » non trouvé" + +#: pg_backup_archiver.c:2715 +#, c-format +msgid "table \"%s\" not found" +msgstr "table « %s » non trouvée" + +#: pg_backup_archiver.c:2722 +#, c-format +msgid "index \"%s\" not found" +msgstr "index « %s » non trouvé" + +#: pg_backup_archiver.c:2729 +#, c-format +msgid "function \"%s\" not found" +msgstr "fonction « %s » non trouvée" + +#: pg_backup_archiver.c:2736 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "trigger « %s » non trouvé" + +#: pg_backup_archiver.c:3128 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "n'a pas pu initialiser la session utilisateur à « %s »: %s" + +#: pg_backup_archiver.c:3260 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "n'a pas pu configurer search_path à « %s » : %s" + +#: pg_backup_archiver.c:3322 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "n'a pas pu configurer default_tablespace à %s : %s" + +#: pg_backup_archiver.c:3367 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "n'a pas pu configurer la méthode default_table_access_method à %s" + +#: pg_backup_archiver.c:3459 pg_backup_archiver.c:3617 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "ne sait pas comment initialiser le propriétaire du type d'objet « %s »" + +#: pg_backup_archiver.c:3721 +#, c-format +msgid "did not find magic string in file header" +msgstr "n'a pas trouver la chaîne magique dans le fichier d'en-tête" + +#: pg_backup_archiver.c:3735 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "version non supportée (%d.%d) dans le fichier d'en-tête" + +#: pg_backup_archiver.c:3740 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "échec de la vérification sur la taille de l'entier (%lu)" + +#: pg_backup_archiver.c:3744 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "l'archive a été créée sur une machine disposant d'entiers plus larges, certaines opérations peuvent échouer" + +#: pg_backup_archiver.c:3754 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "le format attendu (%d) diffère du format du fichier (%d)" + +#: pg_backup_archiver.c:3769 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "l'archive est compressée mais cette installation ne supporte pas la compression -- aucune donnée ne sera disponible" + +#: pg_backup_archiver.c:3787 +#, c-format +msgid "invalid creation date in header" +msgstr "date de création invalide dans l'en-tête" + +#: pg_backup_archiver.c:3915 +#, c-format +msgid "processing item %d %s %s" +msgstr "traitement de l'élément %d %s %s" + +#: pg_backup_archiver.c:3994 +#, c-format +msgid "entering main parallel loop" +msgstr "entrée dans la boucle parallèle principale" + +#: pg_backup_archiver.c:4005 +#, c-format +msgid "skipping item %d %s %s" +msgstr "omission de l'élément %d %s %s" + +#: pg_backup_archiver.c:4014 +#, c-format +msgid "launching item %d %s %s" +msgstr "lancement de l'élément %d %s %s" + +#: pg_backup_archiver.c:4068 +#, c-format +msgid "finished main parallel loop" +msgstr "fin de la boucle parallèle principale" + +#: pg_backup_archiver.c:4104 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "traitement de l'élément manquant %d %s %s" + +#: pg_backup_archiver.c:4709 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "la table « %s » n'a pas pu être créée, ses données ne seront pas restaurées" + +#: pg_backup_custom.c:376 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "OID invalide pour le « Large Object »" + +#: pg_backup_custom.c:439 pg_backup_custom.c:505 pg_backup_custom.c:629 +#: pg_backup_custom.c:865 pg_backup_tar.c:1080 pg_backup_tar.c:1085 +#, c-format +msgid "error during file seek: %m" +msgstr "erreur lors de la recherche dans le fichier : %m" + +#: pg_backup_custom.c:478 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "le bloc de données %d a une mauvaise position de recherche" + +#: pg_backup_custom.c:495 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "type de bloc de données non reconnu (%d) lors de la recherche dans l'archive" + +#: pg_backup_custom.c:517 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "" +"n'a pas pu trouver l'identifiant de bloc %d dans l'archive --\n" +"il est possible que cela soit dû à une demande de restauration dans un ordre\n" +"différent, ce qui ne peut pas être géré à cause d'un fichier non gérable en\n" +"recherche" + +#: pg_backup_custom.c:522 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "n'a pas pu trouver l'identifiant de bloc %d dans l'archive -- possible corruption de l'archive" + +#: pg_backup_custom.c:529 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "ID de bloc inattendu (%d) lors de la lecture des données -- %d attendu" + +#: pg_backup_custom.c:543 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "type de bloc de données %d non reconnu lors de la restauration de l'archive" + +#: pg_backup_custom.c:645 +#, c-format +msgid "could not read from input file: %m" +msgstr "n'a pas pu lire à partir du fichier en entrée : %m" + +#: pg_backup_custom.c:746 pg_backup_custom.c:798 pg_backup_custom.c:943 +#: pg_backup_tar.c:1083 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "n'a pas pu déterminer la position de recherche dans le fichier d'archive : %m" + +#: pg_backup_custom.c:762 pg_backup_custom.c:802 +#, c-format +msgid "could not close archive file: %m" +msgstr "n'a pas pu fermer le fichier d'archive : %m" + +#: pg_backup_custom.c:785 +#, c-format +msgid "can only reopen input archives" +msgstr "peut seulement rouvrir l'archive en entrée" + +#: pg_backup_custom.c:792 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "la restauration parallélisée n'est pas supportée à partir de stdin" + +#: pg_backup_custom.c:794 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "la restauration parallélisée n'est pas supportée à partir de fichiers sans table de matière" + +#: pg_backup_custom.c:810 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "n'a pas pu initialiser la recherche de position dans le fichier d'archive : %m" + +#: pg_backup_custom.c:889 +#, c-format +msgid "compressor active" +msgstr "compression activée" + +#: pg_backup_db.c:42 +#, c-format +msgid "could not get server_version from libpq" +msgstr "n'a pas pu obtenir server_version de libpq" + +#: pg_backup_db.c:53 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "version du serveur : %s ; %s version : %s" + +#: pg_backup_db.c:55 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "annulation à cause de la différence des versions" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "déjà connecté à une base de données" + +#: pg_backup_db.c:132 pg_backup_db.c:182 pg_dumpall.c:1655 pg_dumpall.c:1766 +msgid "Password: " +msgstr "Mot de passe : " + +#: pg_backup_db.c:174 +#, c-format +msgid "could not connect to database" +msgstr "n'a pas pu se connecter à la base de données" + +#: pg_backup_db.c:191 +#, c-format +msgid "reconnection failed: %s" +msgstr "échec de la reconnexion : %s" + +#: pg_backup_db.c:194 pg_backup_db.c:269 pg_dumpall.c:1686 pg_dumpall.c:1776 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:276 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "échec de la requête : %s" + +#: pg_backup_db.c:278 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "la requête était : %s" + +#: pg_backup_db.c:319 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "la requête a renvoyé %d ligne au lieu d'une seule : %s" +msgstr[1] "la requête a renvoyé %d lignes au lieu d'une seule : %s" + +#: pg_backup_db.c:355 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %sLa commande était : %s" + +#: pg_backup_db.c:411 pg_backup_db.c:485 pg_backup_db.c:492 +msgid "could not execute query" +msgstr "n'a pas pu exécuter la requête" + +#: pg_backup_db.c:464 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "erreur renvoyée par PQputCopyData : %s" + +#: pg_backup_db.c:513 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "erreur renvoyée par PQputCopyEnd : %s" + +#: pg_backup_db.c:519 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "COPY échoué pour la table « %s » : %s" + +#: pg_backup_db.c:525 pg_dump.c:2074 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "résultats supplémentaires non attendus durant l'exécution de COPY sur la table « %s »" + +#: pg_backup_db.c:537 +msgid "could not start database transaction" +msgstr "n'a pas pu démarrer la transaction de la base de données" + +#: pg_backup_db.c:545 +msgid "could not commit database transaction" +msgstr "n'a pas pu valider la transaction de la base de données" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "aucun répertoire cible indiqué" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "n'a pas pu lire le répertoire « %s » : %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "n'a pas pu fermer le répertoire « %s » : %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "n'a pas pu créer le répertoire « %s » : %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "n'a pas pu écrire dans le fichier en sortie : %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "n'a pas pu fermer le fichier de données « %s » : %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "n'a pas pu ouvrir le fichier TOC « %s » du Large Object en entrée : %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "ligne invalide dans le fichier TOC du Large Object « %s » : « %s »" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "erreur lors de la lecture du TOC du fichier Large Object « %s »" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "n'a pas pu fermer le TOC du Large Object « %s » : %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "n'a pas pu écrire dans le fichier TOC des Large Objects" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "nom du fichier trop long : « %s »" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "ce format ne peut pas être lu" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "n'a pas pu ouvrir le fichier TOC « %s » en sortie : %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "n'a pas pu ouvrir le fichier TOC en sortie : %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:352 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "compression non supportée par le format des archives tar" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "n'a pas pu ouvrir le fichier TOC « %s » en entrée : %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "n'a pas pu ouvrir le fichier TOC en entrée : %m" + +#: pg_backup_tar.c:338 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "n'a pas pu trouver le fichier « %s » dans l'archive" + +#: pg_backup_tar.c:404 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "impossible de créer le nom du fichier temporaire : %m" + +#: pg_backup_tar.c:415 +#, c-format +msgid "could not open temporary file" +msgstr "n'a pas pu ouvrir le fichier temporaire" + +#: pg_backup_tar.c:442 +#, c-format +msgid "could not close tar member" +msgstr "n'a pas pu fermer le membre de tar" + +#: pg_backup_tar.c:685 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "syntaxe inattendue de l'instruction COPY : « %s »" + +#: pg_backup_tar.c:952 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "OID invalide pour le « Large Object » (%u)" + +#: pg_backup_tar.c:1099 +#, c-format +msgid "could not close temporary file: %m" +msgstr "n'a pas pu fermer le fichier temporaire : m" + +#: pg_backup_tar.c:1108 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "la longueur réelle du fichier (%s) ne correspond pas à ce qui était attendu (%s)" + +#: pg_backup_tar.c:1165 pg_backup_tar.c:1196 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "n'a pas pu trouver l'en-tête du fichier « %s » dans l'archive tar" + +#: pg_backup_tar.c:1183 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "la restauration désordonnée de données n'est pas supportée avec ce format d'archive : « %s » est requis mais vient avant « %s » dans le fichier d'archive." + +#: pg_backup_tar.c:1230 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "en-tête incomplet du fichier tar (%lu octet)" +msgstr[1] "en-tête incomplet du fichier tar (%lu octets)" + +#: pg_backup_tar.c:1281 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "en-tête tar corrompu trouvé dans %s (%d attendu, %d calculé ) à la position %s du fichier" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "nom de section non reconnu : « %s »" + +#: pg_backup_utils.c:55 pg_dump.c:622 pg_dump.c:639 pg_dumpall.c:341 +#: pg_dumpall.c:351 pg_dumpall.c:360 pg_dumpall.c:369 pg_dumpall.c:377 +#: pg_dumpall.c:391 pg_dumpall.c:469 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayer « %s --help » pour plus d'informations.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "plus d'emplacements on_exit_nicely" + +#: pg_dump.c:548 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "le niveau de compression doit être compris entre 0 et 9" + +#: pg_dump.c:586 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits doit être dans l'intervalle -15 à 3" + +#: pg_dump.c:609 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "le nombre de lignes par insertion doit être compris entre %d et %d" + +#: pg_dump.c:637 pg_dumpall.c:349 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" + +#: pg_dump.c:658 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "les options « -s/--schema-only » et « -a/--data-only » ne peuvent pas être utilisées ensemble" + +#: pg_dump.c:663 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "les options « -s/--schema-only » et « --include-foreign-data » ne peuvent pas être utilisées ensemble" + +#: pg_dump.c:666 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "l'option --include-foreign-data n'est pas supportée avec une sauvegarde parallélisée" + +#: pg_dump.c:670 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "les options « -c/--clean » et « -a/--data-only » ne peuvent pas être utilisées ensemble" + +#: pg_dump.c:675 pg_dumpall.c:384 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "l'option --if-exists nécessite l'option -c/--clean" + +#: pg_dump.c:682 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "l'option --on-conflict-do-nothing requiert l'option --inserts, --rows-per-insert, ou --column-inserts" + +#: pg_dump.c:704 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "la compression requise n'est pas disponible avec cette installation -- l'archive ne sera pas compressée" + +#: pg_dump.c:725 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "nombre de jobs parallèles invalide" + +#: pg_dump.c:729 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "la sauvegarde parallélisée n'est supportée qu'avec le format directory" + +#: pg_dump.c:784 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Les snapshots synchronisés ne sont pas supportés par cette version serveur.\n" +"Lancez avec --no-synchronized-snapshots à la place si vous n'avez pas besoin\n" +"de snapshots synchronisés." + +#: pg_dump.c:790 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Les images exportées de la base ne sont pas supportées par cette version du serveur." + +#: pg_dump.c:802 +#, c-format +msgid "last built-in OID is %u" +msgstr "le dernier OID interne est %u" + +#: pg_dump.c:811 +#, c-format +msgid "no matching schemas were found" +msgstr "aucun schéma correspondant n'a été trouvé" + +#: pg_dump.c:825 +#, c-format +msgid "no matching tables were found" +msgstr "aucune table correspondante n'a été trouvée" + +#: pg_dump.c:847 +#, c-format +msgid "no matching extensions were found" +msgstr "aucune extension correspondante n'a été trouvée" + +#: pg_dump.c:1017 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s exporte une base de données dans un fichier texte ou dans d'autres\n" +"formats.\n" +"\n" + +#: pg_dump.c:1018 pg_dumpall.c:622 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: pg_dump.c:1019 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]... [NOMBASE]\n" + +#: pg_dump.c:1021 pg_dumpall.c:625 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Options générales :\n" + +#: pg_dump.c:1022 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=NOMFICHIER nom du fichier ou du répertoire en sortie\n" + +#: pg_dump.c:1023 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p format du fichier de sortie (personnalisé,\n" +" répertoire, tar, texte (par défaut))\n" + +#: pg_dump.c:1025 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr "" +" -j, --jobs=NUMERO utilise ce nombre de jobs en parallèle pour\n" +" la sauvegarde\n" + +#: pg_dump.c:1026 pg_dumpall.c:627 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose mode verbeux\n" + +#: pg_dump.c:1027 pg_dumpall.c:628 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" + +#: pg_dump.c:1028 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr "" +" -Z, --compress=0-9 niveau de compression pour les formats\n" +" compressés\n" + +#: pg_dump.c:1029 pg_dumpall.c:629 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr "" +" --lock-wait-timeout=DÉLAI échec après l'attente du DÉLAI pour un verrou\n" +" de table\n" + +#: pg_dump.c:1030 pg_dumpall.c:656 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync n'attend pas que les modifications soient proprement écrites sur disque\n" + +#: pg_dump.c:1031 pg_dumpall.c:630 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" + +#: pg_dump.c:1033 pg_dumpall.c:631 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Options contrôlant le contenu en sortie :\n" + +#: pg_dump.c:1034 pg_dumpall.c:632 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr "" +" -a, --data-only sauvegarde uniquement les données, pas le\n" +" schéma\n" + +#: pg_dump.c:1035 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr "" +" -b, --blobs inclut les « Large Objects » dans la\n" +" sauvegarde\n" + +#: pg_dump.c:1036 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr "" +" -B, --no-blobs exclut les « Large Objects » dans la\n" +" sauvegarde\n" + +#: pg_dump.c:1037 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr "" +" -c, --clean nettoie/supprime les objets de la base de\n" +" données avant de les créer\n" + +#: pg_dump.c:1038 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr "" +" -C, --create inclut les commandes de création de la base\n" +" dans la sauvegarde\n" + +#: pg_dump.c:1039 +#, c-format +msgid " -e, --extension=PATTERN dump the specified extension(s) only\n" +msgstr " -e, --extension=MOTIF sauvegarde uniquement les extensions indiquées\n" + +#: pg_dump.c:1040 pg_dumpall.c:634 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr "" +" -E, --encoding=ENCODAGE sauvegarde les données dans l'encodage\n" +" ENCODAGE\n" + +#: pg_dump.c:1041 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=MOTIF sauvegarde uniquement les schémas indiqués\n" + +#: pg_dump.c:1042 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=MOTIF ne sauvegarde pas les schémas indiqués\n" + +#: pg_dump.c:1043 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner ne sauvegarde pas les propriétaires des\n" +" objets lors de l'utilisation du format texte\n" + +#: pg_dump.c:1045 pg_dumpall.c:638 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr "" +" -s, --schema-only sauvegarde uniquement la structure, pas les\n" +" données\n" + +#: pg_dump.c:1046 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr "" +" -S, --superuser=NOM indique le nom du super-utilisateur à\n" +" utiliser avec le format texte\n" + +#: pg_dump.c:1047 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=MOTIF sauvegarde uniquement les tables indiquées\n" + +#: pg_dump.c:1048 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=MOTIF ne sauvegarde pas les tables indiquées\n" + +#: pg_dump.c:1049 pg_dumpall.c:641 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges ne sauvegarde pas les droits sur les objets\n" + +#: pg_dump.c:1050 pg_dumpall.c:642 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr "" +" --binary-upgrade à n'utiliser que par les outils de mise à\n" +" jour seulement\n" + +#: pg_dump.c:1051 pg_dumpall.c:643 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr "" +" --column-inserts sauvegarde les données avec des commandes\n" +" INSERT en précisant les noms des colonnes\n" + +#: pg_dump.c:1052 pg_dumpall.c:644 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr "" +" --disable-dollar-quoting désactive l'utilisation des guillemets\n" +" dollar dans le but de respecter le standard\n" +" SQL en matière de guillemets\n" + +#: pg_dump.c:1053 pg_dumpall.c:645 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr "" +" --disable-triggers désactive les triggers en mode de restauration\n" +" des données seules\n" + +#: pg_dump.c:1054 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security active la sécurité niveau ligne (et donc\\n\n" +" sauvegarde uniquement le contenu visible par\\n\n" +" cet utilisateur)\n" + +#: pg_dump.c:1056 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " --exclude-table-data=MOTIF ne sauvegarde pas les tables indiquées\n" + +#: pg_dump.c:1057 pg_dumpall.c:647 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM surcharge la configuration par défaut de extra_float_digits\n" + +#: pg_dump.c:1058 pg_dumpall.c:648 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists utilise IF EXISTS lors de la suppression des objets\n" + +#: pg_dump.c:1059 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=MOTIF\n" +" inclut les données des tables externes pour les\n" +" serveurs distants correspondant au motif MOTIF\n" + +#: pg_dump.c:1062 pg_dumpall.c:649 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr "" +" --inserts sauvegarde les données avec des instructions\n" +" INSERT plutôt que COPY\n" + +#: pg_dump.c:1063 pg_dumpall.c:650 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root charger les partitions via la table racine\n" + +#: pg_dump.c:1064 pg_dumpall.c:651 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments ne sauvegarde pas les commentaires\n" + +#: pg_dump.c:1065 pg_dumpall.c:652 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications ne sauvegarde pas les publications\n" + +#: pg_dump.c:1066 pg_dumpall.c:654 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr "" +" --no-security-labels ne sauvegarde pas les affectations de labels de\n" +" sécurité\n" + +#: pg_dump.c:1067 pg_dumpall.c:655 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions ne sauvegarde pas les souscriptions\n" + +#: pg_dump.c:1068 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr " --no-synchronized-snapshots n'utilise pas de snapshots synchronisés pour les jobs en parallèle\n" + +#: pg_dump.c:1069 pg_dumpall.c:657 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr "" +" --no-tablespaces ne sauvegarde pas les affectations de\n" +" tablespaces\n" + +#: pg_dump.c:1070 pg_dumpall.c:658 +#, c-format +msgid " --no-toast-compression do not dump TOAST compression methods\n" +msgstr " --no-toast-compression ne sauvegarde pas les méthodes de compression de TOAST\n" + +#: pg_dump.c:1071 pg_dumpall.c:659 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr "" +" --no-unlogged-table-data ne sauvegarde pas les données des tables non\n" +" journalisées\n" + +#: pg_dump.c:1072 pg_dumpall.c:660 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing ajoute ON CONFLICT DO NOTHING aux commandes INSERT\n" + +#: pg_dump.c:1073 pg_dumpall.c:661 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr "" +" --quote-all-identifiers met entre guillemets tous les identifiants\n" +" même s'il ne s'agit pas de mots clés\n" + +#: pg_dump.c:1074 pg_dumpall.c:662 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NROWS nombre de lignes par INSERT ; implique --inserts\n" + +#: pg_dump.c:1075 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=SECTION sauvegarde la section indiquée (pre-data, data\n" +" ou post-data)\n" + +#: pg_dump.c:1076 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr "" +" --serializable-deferrable attend jusqu'à ce que la sauvegarde puisse\n" +" s'exécuter sans anomalies\n" + +#: pg_dump.c:1077 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT utilise l'image donnée pour la sauvegarde\n" + +#: pg_dump.c:1078 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names requiert que le motifs de table et/ou schéma\n" +" correspondent à au moins une entité de chaque\n" + +#: pg_dump.c:1080 pg_dumpall.c:663 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" utilise les commandes SET SESSION AUTHORIZATION\n" +" au lieu des commandes ALTER OWNER pour\n" +" modifier les propriétaires\n" + +#: pg_dump.c:1084 pg_dumpall.c:667 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Options de connexion :\n" + +#: pg_dump.c:1085 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=NOMBASE base de données à sauvegarder\n" + +#: pg_dump.c:1086 pg_dumpall.c:669 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr "" +" -h, --host=NOMHÔTE hôte du serveur de bases de données ou\n" +" répertoire des sockets\n" + +#: pg_dump.c:1087 pg_dumpall.c:671 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr "" +" -p, --port=PORT numéro de port du serveur de bases de\n" +" données\n" + +#: pg_dump.c:1088 pg_dumpall.c:672 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NOM se connecter avec cet utilisateur\n" + +#: pg_dump.c:1089 pg_dumpall.c:673 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password ne demande jamais le mot de passe\n" + +#: pg_dump.c:1090 pg_dumpall.c:674 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr "" +" -W, --password force la demande du mot de passe (par\n" +" défaut)\n" + +#: pg_dump.c:1091 pg_dumpall.c:675 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=NOMROLE exécute SET ROLE avant la sauvegarde\n" + +#: pg_dump.c:1093 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Si aucune base de données n'est indiquée, la valeur de la variable\n" +"d'environnement PGDATABASE est alors utilisée.\n" +"\n" + +#: pg_dump.c:1095 pg_dumpall.c:679 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Rapporter les bogues à <%s>.\n" + +#: pg_dump.c:1096 pg_dumpall.c:680 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil de %s : <%s>\n" + +#: pg_dump.c:1115 pg_dumpall.c:504 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "encodage client indiqué (« %s ») invalide" + +#: pg_dump.c:1261 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Les snapshots synchronisés sur les serveurs standbys ne sont pas supportés par cette version serveur.\n" +"Lancez avec --no-synchronized-snapshots à la place si vous n'avez pas besoin\n" +"de snapshots synchronisés." + +#: pg_dump.c:1330 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "format de sortie « %s » invalide" + +#: pg_dump.c:1368 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "aucun schéma correspondant n'a été trouvé avec le motif « %s »" + +#: pg_dump.c:1415 +#, c-format +msgid "no matching extensions were found for pattern \"%s\"" +msgstr "aucune extension correspondante n'a été trouvée avec le motif « %s »" + +#: pg_dump.c:1462 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "aucun serveur distant correspondant n'a été trouvé avec le motif « %s »" + +#: pg_dump.c:1525 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "aucune table correspondante n'a été trouvée avec le motif « %s »" + +#: pg_dump.c:1948 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "sauvegarde du contenu de la table « %s.%s »" + +#: pg_dump.c:2055 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Sauvegarde du contenu de la table « %s » échouée : échec de PQgetCopyData()." + +#: pg_dump.c:2056 pg_dump.c:2066 +#, c-format +msgid "Error message from server: %s" +msgstr "Message d'erreur du serveur : %s" + +#: pg_dump.c:2057 pg_dump.c:2067 +#, c-format +msgid "The command was: %s" +msgstr "La commande était : %s" + +#: pg_dump.c:2065 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Sauvegarde du contenu de la table « %s » échouée : échec de PQgetResult()." + +#: pg_dump.c:2825 +#, c-format +msgid "saving database definition" +msgstr "sauvegarde de la définition de la base de données" + +#: pg_dump.c:3297 +#, c-format +msgid "saving encoding = %s" +msgstr "encodage de la sauvegarde = %s" + +#: pg_dump.c:3322 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "sauvegarde de standard_conforming_strings = %s" + +#: pg_dump.c:3361 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "n'a pas pu analyser le résultat de current_schema()" + +#: pg_dump.c:3380 +#, c-format +msgid "saving search_path = %s" +msgstr "sauvegarde de search_path = %s" + +#: pg_dump.c:3420 +#, c-format +msgid "reading large objects" +msgstr "lecture des « Large Objects »" + +#: pg_dump.c:3602 +#, c-format +msgid "saving large objects" +msgstr "sauvegarde des « Large Objects »" + +#: pg_dump.c:3648 +#, c-format +msgid "error reading large object %u: %s" +msgstr "erreur lors de la lecture du « Large Object » %u : %s" + +#: pg_dump.c:3700 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "lecture de l'activation de la sécurité niveau ligne pour la table « %s.%s »" + +#: pg_dump.c:3731 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "lecture des politiques pour la table « %s.%s »" + +#: pg_dump.c:3883 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "type de commande inattendu pour la politique : %c" + +#: pg_dump.c:4037 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "le propriétaire de la publication « %s » semble être invalide" + +#: pg_dump.c:4329 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "les souscriptions ne sont pas sauvegardées parce que l'utilisateur courant n'est pas un superutilisateur" + +#: pg_dump.c:4400 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "le propriétaire de la souscription « %s » semble être invalide" + +#: pg_dump.c:4443 +#, c-format +msgid "could not parse subpublications array" +msgstr "n'a pas pu analyser le tableau de sous-publications" + +#: pg_dump.c:4801 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "n'a pas pu trouver l'extension parent pour %s %s" + +#: pg_dump.c:4933 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "le propriétaire du schéma « %s » semble être invalide" + +#: pg_dump.c:4956 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "le schéma d'OID %u n'existe pas" + +#: pg_dump.c:5285 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "le propriétaire du type de données « %s » semble être invalide" + +#: pg_dump.c:5369 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "le propriétaire de l'opérateur « %s » semble être invalide" + +#: pg_dump.c:5668 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "le propriétaire de la classe d'opérateur « %s » semble être invalide" + +#: pg_dump.c:5751 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "le propriétaire de la famille d'opérateur « %s » semble être invalide" + +#: pg_dump.c:5919 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "le propriétaire de la fonction d'agrégat « %s » semble être invalide" + +#: pg_dump.c:6178 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "le propriétaire de la fonction « %s » semble être invalide" + +#: pg_dump.c:7005 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "le propriétaire de la table « %s » semble être invalide" + +#: pg_dump.c:7047 pg_dump.c:17436 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "vérification échouée, OID %u de la table parent de l'OID %u de la séquence introuvable" + +#: pg_dump.c:7186 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "lecture des index de la table « %s.%s »" + +#: pg_dump.c:7600 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "lecture des contraintes de clés étrangères pour la table « %s.%s »" + +#: pg_dump.c:7879 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "vérification échouée, OID %u de la table parent de l'OID %u de l'entrée de pg_rewrite introuvable" + +#: pg_dump.c:7962 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "lecture des triggers pour la table « %s.%s »" + +#: pg_dump.c:8095 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "la requête a produit une réference de nom de table null pour le trigger de la clé étrangère « %s » sur la table « %s » (OID de la table : %u)" + +#: pg_dump.c:8645 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "recherche des colonnes et types de la table « %s.%s »" + +#: pg_dump.c:8769 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "numérotation des colonnes invalide pour la table « %s »" + +#: pg_dump.c:8808 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "recherche des expressions par défaut de la table « %s.%s »" + +#: pg_dump.c:8830 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "valeur adnum %d invalide pour la table « %s »" + +#: pg_dump.c:8923 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "recherche des contraintes de vérification pour la table « %s.%s »" + +#: pg_dump.c:8972 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "%d contrainte de vérification attendue pour la table « %s » mais %d trouvée" +msgstr[1] "%d contraintes de vérification attendues pour la table « %s » mais %d trouvée" + +#: pg_dump.c:8976 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Les catalogues système sont peut-être corrompus.)" + +#: pg_dump.c:10561 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "la colonne typtype du type de données « %s » semble être invalide" + +#: pg_dump.c:11913 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "valeur erronée dans le tableau proargmodes" + +#: pg_dump.c:12220 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "n'a pas pu analyser le tableau proallargtypes" + +#: pg_dump.c:12236 +#, c-format +msgid "could not parse proargmodes array" +msgstr "n'a pas pu analyser le tableau proargmodes" + +#: pg_dump.c:12250 +#, c-format +msgid "could not parse proargnames array" +msgstr "n'a pas pu analyser le tableau proargnames" + +#: pg_dump.c:12260 +#, c-format +msgid "could not parse proconfig array" +msgstr "n'a pas pu analyser le tableau proconfig" + +#: pg_dump.c:12340 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "valeur provolatile non reconnue pour la fonction « %s »" + +#: pg_dump.c:12390 pg_dump.c:14341 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "valeur proparallel non reconnue pour la fonction « %s »" + +#: pg_dump.c:12529 pg_dump.c:12638 pg_dump.c:12645 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "n'a pas pu trouver la définition de la fonction d'OID %u" + +#: pg_dump.c:12568 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "valeur erronée dans le champ pg_cast.castfunc ou pg_cast.castmethod" + +#: pg_dump.c:12571 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "valeur erronée dans pg_cast.castmethod" + +#: pg_dump.c:12664 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "définition de transformation invalide, au moins un de trffromsql et trftosql ne doit pas valoir 0" + +#: pg_dump.c:12681 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "valeur erronée dans pg_transform.trffromsql" + +#: pg_dump.c:12702 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "valeur erronée dans pg_transform.trftosql" + +#: pg_dump.c:12854 +#, c-format +msgid "postfix operators are not supported anymore (operator \"%s\")" +msgstr "les opérateurs postfixes ne sont plus supportés (opérateur « %s »)" + +#: pg_dump.c:13024 +#, c-format +msgid "could not find operator with OID %s" +msgstr "n'a pas pu trouver l'opérateur d'OID %s" + +#: pg_dump.c:13092 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "type « %c » invalide de la méthode d'accès « %s »" + +#: pg_dump.c:13846 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "fournisseur de collationnement non reconnu : %s" + +#: pg_dump.c:14260 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "valeur non reconnue de aggfinalmodify pour l'agrégat « %s »" + +#: pg_dump.c:14316 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "valeur non reconnue de aggmfinalmodify pour l'agrégat « %s »" + +#: pg_dump.c:15038 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "type d'objet inconnu dans les droits par défaut : %d" + +#: pg_dump.c:15056 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "n'a pas pu analyser la liste ACL par défaut (%s)" + +#: pg_dump.c:15141 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "n'a pas pu analyser la liste ACL GRANT initiale (%s) ou la liste ACL REVOKE initiale (%s) de l'objet « %s » (%s)" + +#: pg_dump.c:15149 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "n'a pas pu analyser la liste ACL GRANT (%s) ou REVOKE (%s) de l'objet « %s » (%s)" + +#: pg_dump.c:15664 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "la requête permettant d'obtenir la définition de la vue « %s » n'a renvoyé aucune donnée" + +#: pg_dump.c:15667 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "la requête permettant d'obtenir la définition de la vue « %s » a renvoyé plusieurs définitions" + +#: pg_dump.c:15674 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "la définition de la vue « %s » semble être vide (longueur nulle)" + +#: pg_dump.c:15758 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS n'est plus supporté (table « %s »)" + +#: pg_dump.c:16623 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "numéro de colonne %d invalide pour la table « %s »" + +#: pg_dump.c:16700 +#, c-format +msgid "could not parse index statistic columns" +msgstr "n'a pas pu analyser les colonnes statistiques de l'index" + +#: pg_dump.c:16702 +#, c-format +msgid "could not parse index statistic values" +msgstr "n'a pas pu analyser les valeurs statistiques de l'index" + +#: pg_dump.c:16704 +#, c-format +msgid "mismatched number of columns and values for index statistics" +msgstr "nombre de colonnes et de valeurs différentes pour les statistiques des index" + +#: pg_dump.c:16921 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "index manquant pour la contrainte « %s »" + +#: pg_dump.c:17146 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "type de contrainte inconnu : %c" + +#: pg_dump.c:17278 pg_dump.c:17501 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "la requête permettant d'obtenir les données de la séquence « %s » a renvoyé %d ligne (une seule attendue)" +msgstr[1] "la requête permettant d'obtenir les données de la séquence « %s » a renvoyé %d ligne (une seule attendue)" + +#: pg_dump.c:17312 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "type de séquence non reconnu : « %s »" + +#: pg_dump.c:17599 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "valeur tgtype inattendue : %d" + +#: pg_dump.c:17673 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "chaîne argument invalide (%s) pour le trigger « %s » sur la table « %s »" + +#: pg_dump.c:17909 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "la requête permettant d'obtenir la règle « %s » associée à la table « %s » a échoué : mauvais nombre de lignes renvoyées" + +#: pg_dump.c:18071 +#, c-format +msgid "could not find referenced extension %u" +msgstr "n'a pas pu trouver l'extension référencée %u" + +#: pg_dump.c:18162 +#, c-format +msgid "could not parse extension configuration array" +msgstr "n'a pas pu analyser le tableau de configuration des extensions" + +#: pg_dump.c:18164 +#, c-format +msgid "could not parse extension condition array" +msgstr "n'a pas pu analyser le tableau de condition de l'extension" + +#: pg_dump.c:18166 +#, c-format +msgid "mismatched number of configurations and conditions for extension" +msgstr "nombre différent de configurations et de conditions pour l'extension" + +#: pg_dump.c:18298 +#, c-format +msgid "reading dependency data" +msgstr "lecture des données de dépendance" + +#: pg_dump.c:18391 +#, c-format +msgid "no referencing object %u %u" +msgstr "pas d'objet référant %u %u" + +#: pg_dump.c:18402 +#, c-format +msgid "no referenced object %u %u" +msgstr "pas d'objet référencé %u %u" + +#: pg_dump.c:18776 +#, c-format +msgid "could not parse reloptions array" +msgstr "n'a pas pu analyser le tableau reloptions" + +#: pg_dump_sort.c:411 +#, c-format +msgid "invalid dumpId %d" +msgstr "dumpId %d invalide" + +#: pg_dump_sort.c:417 +#, c-format +msgid "invalid dependency %d" +msgstr "dépendance invalide %d" + +#: pg_dump_sort.c:650 +#, c-format +msgid "could not identify dependency loop" +msgstr "n'a pas pu identifier la boucle de dépendance" + +#: pg_dump_sort.c:1221 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "NOTE : il existe des constraintes de clés étrangères circulaires sur cette table :" +msgstr[1] "NOTE : il existe des constraintes de clés étrangères circulaires sur ces tables :" + +#: pg_dump_sort.c:1225 pg_dump_sort.c:1245 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1226 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Il est possible de restaurer la sauvegarde sans utiliser --disable-triggers ou sans supprimer temporairement les constraintes." + +#: pg_dump_sort.c:1227 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Considérez l'utilisation d'une sauvegarde complète au lieu d'une sauvegarde des données seulement pour éviter ce problème." + +#: pg_dump_sort.c:1239 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "n'a pas pu résoudre la boucle de dépendances parmi ces éléments :" + +#: pg_dumpall.c:202 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Le programme « %s » est nécessaire pour %s, mais n'a pas été trouvé\n" +"dans le même répertoire que « %s ».\n" +"Vérifiez votre installation." + +#: pg_dumpall.c:207 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Le programme « %s » a été trouvé par « %s »\n" +"mais n'est pas de la même version que %s.\n" +"Vérifiez votre installation." + +#: pg_dumpall.c:359 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "l'option --exclude-database ne peut pas être utilisée avec -g/--globals-only, -r/--roles-only ou -t/--tablespaces-only" + +#: pg_dumpall.c:368 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "les options « -g/--globals-only » et « -r/--roles-only » ne peuvent pas être utilisées ensemble" + +#: pg_dumpall.c:376 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "les options « -g/--globals-only » et « -t/--tablespaces-only » ne peuvent pas être utilisées ensemble" + +#: pg_dumpall.c:390 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "les options « -r/--roles-only » et « -t/--tablespaces-only » ne peuvent pas être utilisées ensemble" + +#: pg_dumpall.c:453 pg_dumpall.c:1756 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "n'a pas pu se connecter à la base de données « %s »" + +#: pg_dumpall.c:467 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"n'a pas pu se connecter aux bases « postgres » et « template1 ».\n" +"Merci de préciser une autre base de données." + +#: pg_dumpall.c:621 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s extrait un cluster de bases de données PostgreSQL dans un fichier de\n" +"commandes SQL.\n" +"\n" + +#: pg_dumpall.c:623 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPTION]...\n" + +#: pg_dumpall.c:626 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=NOMFICHIER nom du fichier de sortie\n" + +#: pg_dumpall.c:633 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr "" +" -c, --clean nettoie (supprime) les bases de données avant de\n" +" les créer\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr "" +" -g, --globals-only sauvegarde uniquement les objets système, pas\n" +" le contenu des bases de données\n" + +#: pg_dumpall.c:636 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr "" +" -O, --no-owner omet la restauration des propriétaires des\n" +" objets\n" + +#: pg_dumpall.c:637 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr "" +" -r, --roles-only sauvegarde uniquement les rôles, pas les bases\n" +" de données ni les tablespaces\n" + +#: pg_dumpall.c:639 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr "" +" -S, --superuser=NOM indique le nom du super-utilisateur à utiliser\n" +" avec le format texte\n" + +#: pg_dumpall.c:640 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr "" +" -t, --tablespaces-only sauvegarde uniquement les tablespaces, pas les\n" +" bases de données ni les rôles\n" + +#: pg_dumpall.c:646 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=MOTIF exclut les bases de données dont le nom correspond au motif\n" + +#: pg_dumpall.c:653 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords ne sauvegarde pas les mots de passe des rôles\n" + +#: pg_dumpall.c:668 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=CHAINE_CONN connexion à l'aide de la chaîne de connexion\n" + +#: pg_dumpall.c:670 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=NOM_BASE indique une autre base par défaut\n" + +#: pg_dumpall.c:677 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"Si -f/--file n'est pas utilisé, le script SQL sera envoyé sur la sortie\n" +"standard.\n" +"\n" + +#: pg_dumpall.c:883 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "nom de rôle commençant par « pg_ » ignoré (« %s »)" + +#: pg_dumpall.c:1284 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "n'a pas pu analyser la liste d'ACL (%s) pour le tablespace « %s »" + +#: pg_dumpall.c:1501 +#, c-format +msgid "excluding database \"%s\"" +msgstr "exclusion de la base de données « %s »" + +#: pg_dumpall.c:1505 +#, c-format +msgid "dumping database \"%s\"" +msgstr "sauvegarde de la base de données « %s »" + +#: pg_dumpall.c:1537 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "échec de pg_dump sur la base de données « %s », quitte" + +#: pg_dumpall.c:1546 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "n'a pas pu ré-ouvrir le fichier de sortie « %s » : %m" + +#: pg_dumpall.c:1590 +#, c-format +msgid "running \"%s\"" +msgstr "exécute « %s »" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "n'a pas pu obtenir la version du serveur" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "n'a pas pu analyser la version du serveur « %s »" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "exécution %s" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "une seule des options -d/--dbname and -f/--file peut être indiquée" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "les options « -d/--dbname » et « -f/--file » ne peuvent pas être utilisées ensemble" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "les options « -c/--clean » et « -a/--data-only » ne peuvent pas être utilisées ensemble" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "le nombre maximum de jobs en parallèle est %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "ne peut pas spécifier à la fois l'option --single-transaction et demander plusieurs jobs" + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "format d'archive « %s » non reconnu ; merci d'indiquer « c », « d » ou « t »" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "erreurs ignorées lors de la restauration : %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s restaure une base de données PostgreSQL à partir d'une archive créée par\n" +"pg_dump.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [OPTION]... [FICHIER]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr "" +" -d, --dbname=NOM nom de la base de données utilisée pour la\n" +" connexion\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=NOMFICHIER nom du fichier de sortie (- pour stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr "" +" -F, --format=c|d|t format du fichier de sauvegarde (devrait être\n" +" automatique)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list affiche la table des matières de l'archive (TOC)\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose mode verbeux\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Options contrôlant la restauration :\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr "" +" -a, --data-only restaure uniquement les données, pas la\n" +" structure\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create crée la base de données cible\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, --exit-on-error quitte en cas d'erreur, continue par défaut\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=NOM restaure l'index indiqué\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr "" +" -j, --jobs=NUMERO utilise ce nombre de jobs en parallèle pour\n" +" la restauration\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=NOMFICHIER utilise la table des matières à partir\n" +" de ce fichier pour sélectionner/trier\n" +" la sortie\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NOM restaure uniquement les objets de ce schéma\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NOM ne restaure pas les objets de ce schéma\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NOM(args) restaure la fonction indiquée\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr "" +" -s, --schema-only restaure uniquement la structure, pas les\n" +" données\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr "" +" -S, --superuser=NOM indique le nom du super-utilisateur à\n" +" utiliser pour désactiver les triggers\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=NOM restaure la relation indiquée (table, vue, etc)\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=NOM restaure le trigger indiqué\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr "" +" -x, --no-privileges omet la restauration des droits sur les objets\n" +" (grant/revoke)\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction restaure dans une seule transaction\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security active la sécurité niveau ligne\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments ne restaure pas les commentaires\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables ne restaure pas les données des tables qui\n" +" n'ont pas pu être créées\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications ne restaure pas les publications\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels ne restaure pas les labels de sécurité\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions ne restaure pas les souscriptions\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr "" +" --no-tablespaces ne restaure pas les affectations de\n" +" tablespaces\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=SECTION restaure la section indiquée (pre-data, data\n" +" ou post-data)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=NOMROLE exécute SET ROLE avant la restauration\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"Les options -I, -n, -N, -P, -t, -T et --section peuvent être combinées et indiquées\n" +"plusieurs fois pour sélectionner plusieurs objets.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"Si aucun nom de fichier n'est fourni en entrée, alors l'entrée standard est\n" +"utilisée.\n" +"\n" + +#~ msgid "pclose failed: %m" +#~ msgstr "échec de pclose : %m" + +#~ msgid "WSAStartup failed: %d" +#~ msgstr "WSAStartup a échoué : %d" + +#~ msgid "select() failed: %m" +#~ msgstr "échec de select() : %m" + +#~ msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +#~ msgstr "" +#~ "n'a pas pu trouver l'identifiant de bloc %d dans l'archive --\n" +#~ "il est possible que cela soit dû à une demande de restauration dans un ordre\n" +#~ "différent, qui n'a pas pu être géré à cause d'un manque d'information de\n" +#~ "position dans l'archive" + +#~ msgid "ftell mismatch with expected position -- ftell used" +#~ msgstr "ftell ne correspond pas à la position attendue -- ftell utilisé" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapporter les bogues à .\n" + +#~ msgid "reading extended statistics for table \"%s.%s\"\n" +#~ msgstr "lecture des statistiques étendues pour la table « %s.%s »\n" + +#~ msgid "worker is terminating\n" +#~ msgstr "le worker est en cours d'arrêt\n" + +#~ msgid "could not get relation name for OID %u: %s\n" +#~ msgstr "n'a pas pu obtenir le nom de la relation pour l'OID %u: %s\n" + +#~ msgid "unrecognized command on communication channel: %s\n" +#~ msgstr "commande inconnue sur le canal de communucation: %s\n" + +#~ msgid "terminated by user\n" +#~ msgstr "terminé par l'utilisateur\n" + +#~ msgid "error in ListenToWorkers(): %s\n" +#~ msgstr "erreur dans ListenToWorkers(): %s\n" + +#~ msgid "archive member too large for tar format\n" +#~ msgstr "membre de l'archive trop volumineux pour le format tar\n" + +#~ msgid "could not open output file \"%s\" for writing\n" +#~ msgstr "n'a pas pu ouvrir le fichier de sauvegarde « %s » en écriture\n" + +#~ msgid "could not write to custom output routine\n" +#~ msgstr "n'a pas pu écrire vers la routine de sauvegarde personnalisée\n" + +#~ msgid "unexpected end of file\n" +#~ msgstr "fin de fichier inattendu\n" + +#~ msgid "could not write byte: %s\n" +#~ msgstr "n'a pas pu écrire un octet : %s\n" + +#~ msgid "could not write byte\n" +#~ msgstr "n'a pas pu écrire l'octet\n" + +#~ msgid "could not write null block at end of tar archive\n" +#~ msgstr "n'a pas pu écrire le bloc nul à la fin de l'archive tar\n" + +#~ msgid "could not output padding at end of tar member\n" +#~ msgstr "n'a pas pu remplir la fin du membre de tar\n" + +#~ msgid "mismatch in actual vs. predicted file position (%s vs. %s)\n" +#~ msgstr "" +#~ "pas de correspondance entre la position réelle et celle prévue du fichier\n" +#~ "(%s vs. %s)\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide puis quitte\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version puis quitte\n" + +#~ msgid "*** aborted because of error\n" +#~ msgstr "*** interrompu du fait d'erreurs\n" + +#~ msgid "missing pg_database entry for database \"%s\"\n" +#~ msgstr "entrée manquante dans pg_database pour la base de données « %s »\n" + +#~ msgid "query returned more than one (%d) pg_database entry for database \"%s\"\n" +#~ msgstr "" +#~ "la requête a renvoyé plusieurs (%d) entrées pg_database pour la base de\n" +#~ "données « %s »\n" + +#~ msgid "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n" +#~ msgstr "dumpDatabase() : n'a pas pu trouver pg_largeobject.relfrozenxid\n" + +#~ msgid "dumpDatabase(): could not find pg_largeobject_metadata.relfrozenxid\n" +#~ msgstr "dumpDatabase() : n'a pas pu trouver pg_largeobject_metadata.relfrozenxid\n" + +#~ msgid "query returned %d foreign server entry for foreign table \"%s\"\n" +#~ msgid_plural "query returned %d foreign server entries for foreign table \"%s\"\n" +#~ msgstr[0] "la requête a renvoyé %d entrée de serveur distant pour la table distante « %s »\n" +#~ msgstr[1] "la requête a renvoyé %d entrées de serveurs distants pour la table distante « %s »\n" + +#~ msgid "missing pg_database entry for this database\n" +#~ msgstr "entrée pg_database manquante pour cette base de données\n" + +#~ msgid "found more than one pg_database entry for this database\n" +#~ msgstr "a trouvé plusieurs entrées dans pg_database pour cette base de données\n" + +#~ msgid "could not find entry for pg_indexes in pg_class\n" +#~ msgstr "n'a pas pu trouver l'entrée de pg_indexes dans pg_class\n" + +#~ msgid "found more than one entry for pg_indexes in pg_class\n" +#~ msgstr "a trouvé plusieurs entrées pour pg_indexes dans la table pg_class\n" + +#~ msgid "SQL command failed\n" +#~ msgstr "la commande SQL a échoué\n" + +#~ msgid "file archiver" +#~ msgstr "programme d'archivage de fichiers" + +#~ msgid "" +#~ "WARNING:\n" +#~ " This format is for demonstration purposes; it is not intended for\n" +#~ " normal use. Files will be written in the current working directory.\n" +#~ msgstr "" +#~ "ATTENTION :\n" +#~ " Ce format est présent dans un but de démonstration ; il n'est pas prévu\n" +#~ " pour une utilisation normale. Les fichiers seront écrits dans le\n" +#~ " répertoire actuel.\n" + +#~ msgid "could not close data file after reading\n" +#~ msgstr "n'a pas pu fermer le fichier de données après lecture\n" + +#~ msgid "could not open large object TOC for input: %s\n" +#~ msgstr "n'a pas pu ouvrir la TOC du « Large Object » en entrée : %s\n" + +#~ msgid "could not open large object TOC for output: %s\n" +#~ msgstr "n'a pas pu ouvrir la TOC du « Large Object » en sortie : %s\n" + +#~ msgid "could not close large object file\n" +#~ msgstr "n'a pas pu fermer le fichier du « Large Object »\n" + +#~ msgid "restoring large object OID %u\n" +#~ msgstr "restauration du « Large Object » d'OID %u\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide et quitte\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version et quitte\n" + +#~ msgid " -c, --clean clean (drop) database objects before recreating\n" +#~ msgstr "" +#~ " -c, --clean nettoie/supprime les bases de données avant de\n" +#~ " les créer\n" + +#~ msgid " -O, --no-owner skip restoration of object ownership\n" +#~ msgstr "" +#~ " -O, --no-owner omettre la restauration des possessions des\n" +#~ " objets\n" + +#~ msgid " --disable-triggers disable triggers during data-only restore\n" +#~ msgstr "" +#~ " --disable-triggers désactiver les déclencheurs lors de la\n" +#~ " restauration des données seules\n" + +#~ msgid "" +#~ " --use-set-session-authorization\n" +#~ " use SET SESSION AUTHORIZATION commands instead of\n" +#~ " ALTER OWNER commands to set ownership\n" +#~ msgstr "" +#~ " --use-set-session-authorization\n" +#~ " utilise les commandes SET SESSION AUTHORIZATION\n" +#~ " au lieu des commandes ALTER OWNER pour les\n" +#~ " modifier les propriétaires\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s : mémoire épuisée\n" + +#~ msgid "cannot reopen stdin\n" +#~ msgstr "ne peut pas rouvrir stdin\n" + +#~ msgid "cannot reopen non-seekable file\n" +#~ msgstr "ne peut pas rouvrir le fichier non cherchable\n" + +#~ msgid "%s: invalid -X option -- %s\n" +#~ msgstr "%s : option -X invalide -- %s\n" + +#~ msgid "query returned no rows: %s\n" +#~ msgstr "la requête n'a renvoyé aucune ligne : %s\n" + +#~ msgid "dumping a specific TOC data block out of order is not supported without ID on this input stream (fseek required)\n" +#~ msgstr "" +#~ "la sauvegarde d'un bloc de données spécifique du TOC dans le désordre n'est\n" +#~ "pas supporté sans identifiant sur ce flux d'entrée (fseek requis)\n" + +#~ msgid "dumpBlobs(): could not open large object %u: %s" +#~ msgstr "dumpBlobs() : n'a pas pu ouvrir le « Large Object » %u : %s" + +#~ msgid "saving large object properties\n" +#~ msgstr "sauvegarde des propriétés des « Large Objects »\n" + +#~ msgid "could not parse ACL (%s) for large object %u" +#~ msgstr "n'a pas pu analyser la liste ACL (%s) du « Large Object » %u" + +#~ msgid "compression support is disabled in this format\n" +#~ msgstr "le support de la compression est désactivé avec ce format\n" + +#~ msgid "no label definitions found for enum ID %u\n" +#~ msgstr "aucune définition de label trouvée pour l'ID enum %u\n" + +#~ msgid "query returned %d rows instead of one: %s\n" +#~ msgstr "la requête a renvoyé %d lignes au lieu d'une seule : %s\n" + +#~ msgid "read %lu byte into lookahead buffer\n" +#~ msgid_plural "read %lu bytes into lookahead buffer\n" +#~ msgstr[0] "lecture de %lu octet dans le tampon prévisionnel\n" +#~ msgstr[1] "lecture de %lu octets dans le tampon prévisionnel\n" + +#~ msgid "requested %d byte, got %d from lookahead and %d from file\n" +#~ msgid_plural "requested %d bytes, got %d from lookahead and %d from file\n" +#~ msgstr[0] "%d octet requis, %d obtenu de « lookahead » et %d du fichier\n" +#~ msgstr[1] "%d octets requis, %d obtenus de « lookahead » et %d du fichier\n" + +#~ msgid "invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n" +#~ msgstr "" +#~ "instruction COPY invalide -- n'a pas pu trouver « from stdin » dans la\n" +#~ "chaîne « %s » à partir de la position %lu\n" + +#~ msgid "invalid COPY statement -- could not find \"copy\" in string \"%s\"\n" +#~ msgstr "instruction COPY invalide -- n'a pas pu trouver « copy » dans la chaîne « %s »\n" + +#~ msgid "-C and -c are incompatible options\n" +#~ msgstr "-C et -c sont des options incompatibles\n" + +#~ msgid "%s: could not parse version \"%s\"\n" +#~ msgstr "%s : n'a pas pu analyser la version « %s »\n" + +#~ msgid "could not parse version string \"%s\"\n" +#~ msgstr "n'a pas pu analyser la chaîne de version « %s »\n" + +#~ msgid "could not create worker thread: %s\n" +#~ msgstr "n'a pas pu créer le fil de travail: %s\n" + +#~ msgid "parallel_restore should not return\n" +#~ msgstr "parallel_restore ne devrait pas retourner\n" + +#~ msgid "worker process crashed: status %d\n" +#~ msgstr "crash du processus worker : statut %d\n" + +#~ msgid "cannot duplicate null pointer\n" +#~ msgstr "ne peut pas dupliquer un pointeur nul\n" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" + +#~ msgid "query to get data of sequence \"%s\" returned name \"%s\"\n" +#~ msgstr "" +#~ "la requête permettant d'obtenir les données de la séquence « %s » a renvoyé\n" +#~ "le nom « %s »\n" + +#~ msgid "server version must be at least 7.3 to use schema selection switches\n" +#~ msgstr "" +#~ "le serveur doit être de version 7.3 ou supérieure pour utiliser les options\n" +#~ "de sélection du schéma\n" + +#~ msgid "error during backup\n" +#~ msgstr "erreur lors de la sauvegarde\n" + +#~ msgid "could not find slot of finished worker\n" +#~ msgstr "n'a pas pu trouver l'emplacement du worker qui vient de terminer\n" + +#~ msgid "error processing a parallel work item\n" +#~ msgstr "erreur durant le traitement en parallèle d'un item\n" + +#~ msgid "" +#~ "Synchronized snapshots are not supported on standby servers.\n" +#~ "Run with --no-synchronized-snapshots instead if you do not need\n" +#~ "synchronized snapshots.\n" +#~ msgstr "" +#~ "Les snapshots synchronisés ne sont pas supportés sur les serveurs de stadby.\n" +#~ "Lancez avec --no-synchronized-snapshots à la place si vous n'avez pas besoin\n" +#~ "de snapshots synchronisés.\n" + +#~ msgid "setting owner and privileges for %s \"%s\"\n" +#~ msgstr "réglage du propriétaire et des droits pour %s « %s »\n" + +#~ msgid "setting owner and privileges for %s \"%s.%s\"\n" +#~ msgstr "réglage du propriétaire et des droits pour %s « %s.%s»\n" + +#~ msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" +#~ msgstr "%s : n'a pas pu analyser la liste d'ACL (%s) pour la base de données « %s »\n" + +#~ msgid "%s: invalid number of parallel jobs\n" +#~ msgstr "%s : nombre de jobs en parallèle invalide\n" + +#~ msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" +#~ msgstr "" +#~ "%s : les options « -c/--clean » et « -a/--data-only » ne peuvent pas être\n" +#~ "utilisées conjointement\n" + +#~ msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" +#~ msgstr "" +#~ "%s : les options « -s/--schema-only » et « -a/--data-only » ne peuvent pas être\n" +#~ "utilisées conjointement\n" + +#~ msgid "%s: query was: %s\n" +#~ msgstr "%s : la requête était : %s\n" + +#~ msgid "%s: query failed: %s" +#~ msgstr "%s : échec de la requête : %s" + +#~ msgid "%s: executing %s\n" +#~ msgstr "%s : exécute %s\n" + +#~ msgid "%s: could not connect to database \"%s\": %s" +#~ msgstr "%s : n'a pas pu se connecter à la base de données « %s » : %s" + +#~ msgid "%s: invalid client encoding \"%s\" specified\n" +#~ msgstr "%s : encodage client indiqué (« %s ») invalide\n" + +#~ msgid "%s: could not open the output file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier de sauvegarde « %s » : %s\n" + +#~ msgid "%s: option --if-exists requires option -c/--clean\n" +#~ msgstr "%s : l'option --if-exists nécessite l'option -c/--clean\n" + +#~ msgid "sorter" +#~ msgstr "tri" + +#~ msgid "WARNING: could not parse reloptions array\n" +#~ msgstr "ATTENTION : n'a pas pu analyser le tableau reloptions\n" + +#~ msgid "unrecognized collation provider: %s\n" +#~ msgstr "fournisseur de collationnement non reconnu : %s\n" + +#~ msgid "schema with OID %u does not exist\n" +#~ msgstr "le schéma d'OID %u n'existe pas\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapporter les bogues à .\n" + +#~ msgid " -o, --oids include OIDs in dump\n" +#~ msgstr " -o, --oids inclut les OID dans la sauvegarde\n" + +#~ msgid "(The INSERT command cannot set OIDs.)\n" +#~ msgstr "(La commande INSERT ne peut pas positionner les OID.)\n" + +#~ msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" +#~ msgstr "" +#~ "les options « --inserts/--column-inserts » et « -o/--oids » ne\n" +#~ "peuvent pas être utilisées conjointement\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" + +#~ msgid "TOC Entry %s at %s (length %s, checksum %d)\n" +#~ msgstr "entrée TOC %s à %s (longueur %s, somme de contrôle %d)\n" + +#~ msgid "skipping tar member %s\n" +#~ msgstr "omission du membre %s du tar\n" + +#~ msgid "now at file position %s\n" +#~ msgstr "maintenant en position %s du fichier\n" + +#~ msgid "moving from position %s to next member at file position %s\n" +#~ msgstr "déplacement de la position %s vers le prochain membre à la position %s du fichier\n" + +#~ msgid "tar archiver" +#~ msgstr "archiveur tar" + +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "n'a pas pu créer le répertoire « %s » : %s\n" + +#~ msgid "could not close directory \"%s\": %s\n" +#~ msgstr "n'a pas pu fermer le répertoire « %s » : %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "directory archiver" +#~ msgstr "archiveur répertoire" + +#~ msgid "query returned %d row instead of one: %s\n" +#~ msgid_plural "query returned %d rows instead of one: %s\n" +#~ msgstr[0] "la requête a renvoyé %d ligne au lieu d'une seule : %s\n" +#~ msgstr[1] "la requête a renvoyé %d lignes au lieu d'une seule : %s\n" + +#~ msgid "query was: %s\n" +#~ msgstr "la requête était : %s\n" + +#~ msgid "failed to connect to database\n" +#~ msgstr "n'a pas pu se connecter à la base de données\n" + +#~ msgid "failed to reconnect to database\n" +#~ msgstr "la reconnexion à la base de données a échoué\n" + +#~ msgid "archiver (db)" +#~ msgstr "programme d'archivage (db)" + +#~ msgid "custom archiver" +#~ msgstr "programme d'archivage personnalisé" + +#~ msgid "reducing dependencies for %d\n" +#~ msgstr "réduction des dépendances pour %d\n" + +#~ msgid "transferring dependency %d -> %d to %d\n" +#~ msgstr "transfert de la dépendance %d -> %d vers %d\n" + +#~ msgid "no item ready\n" +#~ msgstr "aucun élément prêt\n" + +#~ msgid "entering restore_toc_entries_postfork\n" +#~ msgstr "entrée dans restore_toc_entries_prefork\n" + +#~ msgid "entering restore_toc_entries_parallel\n" +#~ msgstr "entrée dans restore_toc_entries_parallel\n" + +#~ msgid "entering restore_toc_entries_prefork\n" +#~ msgstr "entrée dans restore_toc_entries_prefork\n" + +#~ msgid "could not set default_with_oids: %s" +#~ msgstr "n'a pas pu configurer default_with_oids : %s" + +#~ msgid "read TOC entry %d (ID %d) for %s %s\n" +#~ msgstr "lecture de l'entrée %d de la TOC (ID %d) pour %s %s\n" + +#~ msgid "allocating AH for %s, format %d\n" +#~ msgstr "allocation d'AH pour %s, format %d\n" + +#~ msgid "attempting to ascertain archive format\n" +#~ msgstr "tentative d'identification du format de l'archive\n" + +#~ msgid "-C and -1 are incompatible options\n" +#~ msgstr "-C et -1 sont des options incompatibles\n" + +#~ msgid "archiver" +#~ msgstr "archiveur" + +#~ msgid "select() failed: %s\n" +#~ msgstr "échec de select() : %s\n" + +#~ msgid "parallel archiver" +#~ msgstr "archiveur en parallèle" + +#~ msgid "compress_io" +#~ msgstr "compression_io" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "le processus fils a été terminé par le signal %d" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "pclose failed: %s" +#~ msgstr "échec de pclose : %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu changer le répertoire par « %s » : %s" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "n'a pas pu identifier le répertoire courant : %s" + +#~ msgid "" +#~ "The program \"pg_dump\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « pg_dump » a été trouvé par « %s »\n" +#~ "mais n'a pas la même version que %s.\n" +#~ "Vérifiez votre installation." + +#~ msgid "" +#~ "The program \"pg_dump\" is needed by %s but was not found in the\n" +#~ "same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « pg_dump » est nécessaire à %s mais n'a pas été trouvé dans le\n" +#~ "même répertoire que « %s ».\n" +#~ "Vérifiez votre installation." + +#~ msgid "internal error -- neither th nor fh specified in _tarReadRaw()" +#~ msgstr "erreur interne -- ni th ni fh ne sont précisés dans _tarReadRaw()" + +#~ msgid "connection needs password" +#~ msgstr "la connexion nécessite un mot de passe" + +#~ msgid "could not reconnect to database: %s" +#~ msgstr "n'a pas pu se reconnecter à la base de données : %s" + +#~ msgid "could not reconnect to database" +#~ msgstr "n'a pas pu se reconnecter à la base de données" + +#~ msgid "connecting to database \"%s\" as user \"%s\"" +#~ msgstr "connexion à la base de données « %s » en tant qu'utilisateur « %s »" + +#~ msgid "could not connect to database \"%s\": %s" +#~ msgstr "n'a pas pu se connecter à la base de données « %s » : %s" + +#~ msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +#~ msgstr "la fonction d'aggrégat %s n'a pas pu être sauvegardée correctement avec cette version de la base de données ; ignorée" + +#~ msgid "reading publication membership for table \"%s.%s\"" +#~ msgstr "lecture des appartenances aux publications pour la table « %s.%s »" + +#~ msgid "LOCK TABLE failed for \"%s\": %s" +#~ msgstr "LOCK TABLE échoué pour la table « %s » : %s" + +#~ msgid "connection to database \"%s\" failed: %s" +#~ msgstr "la connexion à la base de données « %s » a échoué : %s" + +#~ msgid "reconnection to database \"%s\" failed: %s" +#~ msgstr "reconnexion à la base de données « %s » échouée : %s" + +#~ msgid "could not write to large object (result: %lu, expected: %lu)" +#~ msgstr "n'a pas pu écrire le « Large Object » (résultat : %lu, attendu : %lu)" + +#~ msgid "mismatched number of collation names and versions for index" +#~ msgstr "nombre différent de noms et versions de collation pour l'index" + +#~ msgid "could not parse index collation version array" +#~ msgstr "n'a pas pu analyser le tableau des versions de collation de l'index" + +#~ msgid "could not parse index collation name array" +#~ msgstr "n'a pas pu analyser le tableau des noms de collation de l'index" + +#~ msgid "saving default_toast_compression = %s" +#~ msgstr "sauvegarde de default_toast_compression = %s" + +#~ msgid "option --index-collation-versions-unknown only works in binary upgrade mode" +#~ msgstr "l'option --index-collation-versions-unknown fonctionne seulement dans le mode de mise à jour binaire" + +#~ msgid "invalid TOASTCOMPRESSION item: %s" +#~ msgstr "élément TOASTCOMPRESSION invalide : %s" diff --git a/src/bin/pg_dump/po/ja.po b/src/bin/pg_dump/po/ja.po new file mode 100644 index 000000000000..721a1487044e --- /dev/null +++ b/src/bin/pg_dump/po/ja.po @@ -0,0 +1,2819 @@ +# Japanese message translation file for pg_dump +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# Shigehiro Honda , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_dump (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:55+0900\n" +"PO-Revision-Date: 2020-09-13 08:56+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "カレントディレクトリを識別できませんでした: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "不正なバイナリ\"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "バイナリ\"%s\"を読み取れませんでした" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "実行する\"%s\"がありませんでした" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "ディレクトリ\"%s\"に移動できませんでした: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pcloseが失敗しました: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "メモリ不足です" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ポインタを複製できません(内部エラー)。\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "コマンドは実行可能形式ではありません" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "コマンドが見つかりません" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "子プロセスが終了コード%dで終了しました" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "子プロセスが例外0x%Xで終了しました" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "子プロセスはシグナル%dにより終了しました: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "子プロセスが未知のステータス%dで終了しました" + +#: common.c:121 +#, c-format +msgid "reading extensions" +msgstr "機能拡張を読み込んでいます" + +#: common.c:125 +#, c-format +msgid "identifying extension members" +msgstr "機能拡張の構成要素を特定しています" + +#: common.c:128 +#, c-format +msgid "reading schemas" +msgstr "スキーマを読み込んでいます" + +#: common.c:138 +#, c-format +msgid "reading user-defined tables" +msgstr "ユーザ定義テーブルを読み込んでいます" + +#: common.c:145 +#, c-format +msgid "reading user-defined functions" +msgstr "ユーザ定義関数を読み込んでいます" + +#: common.c:150 +#, c-format +msgid "reading user-defined types" +msgstr "ユーザ定義型を読み込んでいます" + +#: common.c:155 +#, c-format +msgid "reading procedural languages" +msgstr "手続き言語を読み込んでいます" + +#: common.c:158 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "ユーザ定義集約関数を読み込んでいます" + +#: common.c:161 +#, c-format +msgid "reading user-defined operators" +msgstr "ユーザ定義演算子を読み込んでいます" + +#: common.c:165 +#, c-format +msgid "reading user-defined access methods" +msgstr "ユーザ定義アクセスメソッドを読み込んでいます" + +#: common.c:168 +#, c-format +msgid "reading user-defined operator classes" +msgstr "ユーザ定義演算子クラスを読み込んでいます" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator families" +msgstr "ユーザ定義演算子族を読み込んでいます" + +#: common.c:174 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "ユーザ定義のテキスト検索パーサを読み込んでいます" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search templates" +msgstr "ユーザ定義のテキスト検索テンプレートを読み込んでいます" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "ユーザ定義のテキスト検索辞書を読み込んでいます" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "ユーザ定義のテキスト検索設定を読み込んでいます" + +#: common.c:186 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "ユーザ定義の外部データラッパーを読み込んでいます" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "ユーザ定義の外部サーバーを読み込んでいます" + +#: common.c:192 +#, c-format +msgid "reading default privileges" +msgstr "デフォルト権限設定を読み込んでいます" + +#: common.c:195 +#, c-format +msgid "reading user-defined collations" +msgstr "ユーザ定義の照合順序を読み込んでいます" + +#: common.c:199 +#, c-format +msgid "reading user-defined conversions" +msgstr "ユーザ定義の変換を読み込んでいます" + +#: common.c:202 +#, c-format +msgid "reading type casts" +msgstr "型キャストを読み込んでいます" + +#: common.c:205 +#, c-format +msgid "reading transforms" +msgstr "変換を読み込んでいます" + +#: common.c:208 +#, c-format +msgid "reading table inheritance information" +msgstr "テーブル継承情報を読み込んでいます" + +#: common.c:211 +#, c-format +msgid "reading event triggers" +msgstr "イベントトリガを読み込んでいます" + +#: common.c:215 +#, c-format +msgid "finding extension tables" +msgstr "機能拡張構成テーブルを探しています" + +#: common.c:219 +#, c-format +msgid "finding inheritance relationships" +msgstr "継承関係を検索しています" + +#: common.c:222 +#, c-format +msgid "reading column info for interesting tables" +msgstr "対象テーブルの列情報を読み込んでいます" + +#: common.c:225 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "子テーブルの継承列にフラグを設定しています" + +#: common.c:228 +#, c-format +msgid "reading indexes" +msgstr "インデックスを読み込んでいます" + +#: common.c:231 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "パーティション親テーブルのインデックスにフラグを設定しています" + +#: common.c:234 +#, c-format +msgid "reading extended statistics" +msgstr "拡張統計情報を読み込んでいます" + +#: common.c:237 +#, c-format +msgid "reading constraints" +msgstr "制約を読み込んでいます" + +#: common.c:240 +#, c-format +msgid "reading triggers" +msgstr "トリガを読み込んでいます" + +#: common.c:243 +#, c-format +msgid "reading rewrite rules" +msgstr "書き換えルールを読み込んでいます" + +#: common.c:246 +#, c-format +msgid "reading policies" +msgstr "ポリシを読み込んでいます" + +#: common.c:249 +#, c-format +msgid "reading publications" +msgstr "パブリケーションを読み込んでいます" + +#: common.c:252 +#, c-format +msgid "reading publication membership" +msgstr "パブリケーションの構成要素を読み込んでいます" + +#: common.c:255 +#, c-format +msgid "reading subscriptions" +msgstr "サブスクリプションを読み込んでいます" + +#: common.c:1025 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "健全性検査に失敗しました、テーブル\"%2$s\"(OID %3$u)の親のOID %1$uがありません" + +#: common.c:1067 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "数値配列\"%s\"のパースに失敗しました: 要素が多すぎます" + +#: common.c:1082 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "数値配列\"%s\"のパースに失敗しました: 数値に不正な文字が含まれています" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "不正な圧縮コード: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "zlibサポートなしでビルドされています" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "圧縮ライブラリを初期化できませんでした: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "圧縮ストリームをクローズできませんでした: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "データを圧縮できませんでした: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "データを伸長できませんでした: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "圧縮ライブラリをクローズできませんでした: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:557 pg_backup_tar.c:560 +#, c-format +msgid "could not read from input file: %s" +msgstr "入力ファイルから読み込めませんでした: %s" + +#: compress_io.c:623 pg_backup_custom.c:644 pg_backup_directory.c:552 +#: pg_backup_tar.c:793 pg_backup_tar.c:816 +#, c-format +msgid "could not read from input file: end of file" +msgstr "入力ファイルから読み込めませんでした: ファイルの終端" + +#: parallel.c:267 +#, c-format +msgid "WSAStartup failed: %d" +msgstr "WSAStartupが失敗しました: %d" + +#: parallel.c:978 +#, c-format +msgid "could not create communication channels: %m" +msgstr "通信チャンネルを作成できませんでした: %m" + +#: parallel.c:1035 +#, c-format +msgid "could not create worker process: %m" +msgstr "ワーカプロセスを作成できませんでした: %m" + +#: parallel.c:1165 +#, c-format +msgid "unrecognized command received from leader: \"%s\"" +msgstr "リーダーから認識不能のコマンドを受信しました: \"%s\"" + +#: parallel.c:1208 parallel.c:1446 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "ワーカから不正なメッセージを受信しました: \"%s\"" + +#: parallel.c:1340 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"リレーション\"%s\"のロックを獲得できませんでした。\n" +"通常これは、pg_dumpの親プロセスが初期のACCESS SHAREロックを獲得した後にだれかがテーブルに対してACCESS EXCLUSIVEロックを要求したことを意味しています。" + +#: parallel.c:1429 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "ワーカプロセスが突然終了しました" + +#: parallel.c:1551 parallel.c:1669 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "通信チャンネルに書き込めませんでした: %m" + +#: parallel.c:1628 +#, c-format +msgid "select() failed: %m" +msgstr "select()が失敗しました: %m" + +#: parallel.c:1753 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: ソケットを作成できませんでした: エラーコード %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: バインドできませんでした: エラーコード %d" + +#: parallel.c:1771 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: リッスンできませんでした: エラーコード %d" + +#: parallel.c:1778 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname()が失敗しました: エラーコード %d" + +#: parallel.c:1789 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: 第二ソケットを作成できませんでした: エラーコード %d" + +#: parallel.c:1798 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: ソケットを接続できませんでした: エラーコード %d" + +#: parallel.c:1807 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: 接続を受け付けられませんでした: エラーコード %d" + +#: pg_backup_archiver.c:271 pg_backup_archiver.c:1591 +#, c-format +msgid "could not close output file: %m" +msgstr "出力ファイルをクローズできませんでした: %m" + +#: pg_backup_archiver.c:315 pg_backup_archiver.c:319 +#, c-format +msgid "archive items not in correct section order" +msgstr "アーカイブ項目が正しいセクション順ではありません" + +#: pg_backup_archiver.c:325 +#, c-format +msgid "unexpected section code %d" +msgstr "想定外のセクションコード %d" + +#: pg_backup_archiver.c:362 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "このアーカイブファイル形式での並列リストアはサポートしていません" + +#: pg_backup_archiver.c:366 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "8.0 より古い pg_dump で作られたアーカイブでの並列リストアはサポートしていません" + +#: pg_backup_archiver.c:384 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "圧縮アーカイブからのリストアができません(このインストールは圧縮をサポートしていません)" + +#: pg_backup_archiver.c:401 +#, c-format +msgid "connecting to database for restore" +msgstr "リストアのためデータベースに接続しています" + +#: pg_backup_archiver.c:403 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "1.3より古いアーカイブではデータベースへの直接接続はサポートされていません" + +#: pg_backup_archiver.c:448 +#, c-format +msgid "implied data-only restore" +msgstr "暗黙的にデータのみのリストアを行います" + +#: pg_backup_archiver.c:514 +#, c-format +msgid "dropping %s %s" +msgstr "%s %sを削除しています" + +#: pg_backup_archiver.c:609 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "文\"%s\"中に IF EXISTS を挿入すべき場所が見つかりませでした" + +#: pg_backup_archiver.c:765 pg_backup_archiver.c:767 +#, c-format +msgid "warning from original dump file: %s" +msgstr "オリジナルのダンプファイルからの警告: %s" + +#: pg_backup_archiver.c:782 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "%s \"%s.%s\"を作成しています" + +#: pg_backup_archiver.c:785 +#, c-format +msgid "creating %s \"%s\"" +msgstr "%s \"%s\"を作成しています" + +#: pg_backup_archiver.c:842 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "新しいデータベース\"%s\"に接続しています" + +#: pg_backup_archiver.c:870 +#, c-format +msgid "processing %s" +msgstr "%sを処理しています" + +#: pg_backup_archiver.c:890 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"のデータを処理しています" + +#: pg_backup_archiver.c:952 +#, c-format +msgid "executing %s %s" +msgstr "%s %sを実行しています" + +#: pg_backup_archiver.c:991 +#, c-format +msgid "disabling triggers for %s" +msgstr "%sのトリガを無効にしています" + +#: pg_backup_archiver.c:1017 +#, c-format +msgid "enabling triggers for %s" +msgstr "%sのトリガを有効にしています" + +#: pg_backup_archiver.c:1045 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "内部エラー -- WriteDataはDataDumperルーチンのコンテクスト外では呼び出せません" + +#: pg_backup_archiver.c:1228 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "選択した形式ではラージオブジェクト出力をサポートしていません" + +#: pg_backup_archiver.c:1286 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "%d個のラージオブジェクトをリストアしました" +msgstr[1] "%d個のラージオブジェクトをリストアしました" + +#: pg_backup_archiver.c:1307 pg_backup_tar.c:736 +#, c-format +msgid "restoring large object with OID %u" +msgstr "OID %uのラージオブジェクトをリストアしています" + +#: pg_backup_archiver.c:1319 +#, c-format +msgid "could not create large object %u: %s" +msgstr "ラージオブジェクト %u を作成できませんでした: %s" + +#: pg_backup_archiver.c:1324 pg_dump.c:3542 +#, c-format +msgid "could not open large object %u: %s" +msgstr "ラージオブジェクト %u をオープンできませんでした: %s" + +#: pg_backup_archiver.c:1381 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "TOCファイル\"%s\"をオープンできませんでした: %m" + +#: pg_backup_archiver.c:1421 +#, c-format +msgid "line ignored: %s" +msgstr "行を無視しました: %s" + +#: pg_backup_archiver.c:1428 +#, c-format +msgid "could not find entry for ID %d" +msgstr "ID %dのエントリがありませんでした" + +#: pg_backup_archiver.c:1449 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "TOCファイルをクローズできませんでした: %m" + +#: pg_backup_archiver.c:1563 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:484 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "出力ファイル\"%s\"をオープンできませんでした: %m" + +#: pg_backup_archiver.c:1565 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "出力ファイルをオープンできませんでした: %m" + +#: pg_backup_archiver.c:1658 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "ラージオブジェクトデータを%luバイト書き出しました(結果は%lu)" +msgstr[1] "ラージオブジェクトデータを%luバイト書き出しました(結果は%lu)" + +#: pg_backup_archiver.c:1663 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "ラージオブジェクトを書き出すことができませんでした(結果は%lu、想定は%lu)" + +#: pg_backup_archiver.c:1753 +#, c-format +msgid "while INITIALIZING:" +msgstr "初期化中:" + +#: pg_backup_archiver.c:1758 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "TOC処理中:" + +#: pg_backup_archiver.c:1763 +#, c-format +msgid "while FINALIZING:" +msgstr "終了処理中:" + +#: pg_backup_archiver.c:1768 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "TOCエントリ%d; %u %u %s %s %s から" + +#: pg_backup_archiver.c:1844 +#, c-format +msgid "bad dumpId" +msgstr "不正なdumpId" + +#: pg_backup_archiver.c:1865 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "TABLE DATA項目に対する不正なテーブルdumpId" + +#: pg_backup_archiver.c:1957 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "想定外のデータオフセットフラグ %d" + +#: pg_backup_archiver.c:1970 +#, c-format +msgid "file offset in dump file is too large" +msgstr "ダンプファイルのファイルオフセットが大きすぎます" + +#: pg_backup_archiver.c:2107 pg_backup_archiver.c:2117 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "ディレクトリ名が長すぎます: \"%s\"" + +#: pg_backup_archiver.c:2125 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "ディレクトリ\"%s\"は有効なアーカイブではないようです(\"toc.dat\"がありません)" + +#: pg_backup_archiver.c:2133 pg_backup_custom.c:173 pg_backup_custom.c:810 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "入力ファイル\"%s\"をオープンできませんでした: %m" + +#: pg_backup_archiver.c:2140 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "入力ファイルをオープンできませんでした: %m" + +#: pg_backup_archiver.c:2146 +#, c-format +msgid "could not read input file: %m" +msgstr "入力ファイルを読み込めませんでした: %m" + +#: pg_backup_archiver.c:2148 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "入力ファイルが小さすぎます(読み取り%lu、想定は 5)" + +#: pg_backup_archiver.c:2233 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "入力ファイルがテキスト形式のダンプのようです。psqlを使用してください。" + +#: pg_backup_archiver.c:2239 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "入力ファイルが有効なアーカイブではないようです(小さすぎる?)" + +#: pg_backup_archiver.c:2245 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "入力ファイルが有効なアーカイブではないようです" + +#: pg_backup_archiver.c:2265 +#, c-format +msgid "could not close input file: %m" +msgstr "入力ファイルをクローズできませんでした: %m" + +#: pg_backup_archiver.c:2379 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "認識不能のファイル形式\"%d\"" + +#: pg_backup_archiver.c:2461 pg_backup_archiver.c:4473 +#, c-format +msgid "finished item %d %s %s" +msgstr "項目 %d %s %s の処理が完了" + +#: pg_backup_archiver.c:2465 pg_backup_archiver.c:4486 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "ワーカープロセスの処理失敗: 終了コード %d" + +#: pg_backup_archiver.c:2585 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "エントリID%dは範囲外です -- おそらくTOCの破損です" + +#: pg_backup_archiver.c:2652 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "WITH OIDSと定義されたテーブルのリストアは今後サポートされません" + +#: pg_backup_archiver.c:2734 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "認識不能のエンコーディング\"%s\"" + +#: pg_backup_archiver.c:2739 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "不正なENCODING項目: %s" + +#: pg_backup_archiver.c:2757 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "不正なSTDSTRINGS項目: %s" + +#: pg_backup_archiver.c:2782 +#, c-format +msgid "schema \"%s\" not found" +msgstr "スキーマ \"%s\"が見つかりません" + +#: pg_backup_archiver.c:2789 +#, c-format +msgid "table \"%s\" not found" +msgstr "テーブル\"%s\"が見つかりません" + +#: pg_backup_archiver.c:2796 +#, c-format +msgid "index \"%s\" not found" +msgstr "インデックス\"%s\"が見つかりません" + +#: pg_backup_archiver.c:2803 +#, c-format +msgid "function \"%s\" not found" +msgstr "関数\"%s\"が見つかりません" + +#: pg_backup_archiver.c:2810 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "トリガ\"%s\"が見つかりません" + +#: pg_backup_archiver.c:3202 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "セッションユーザを\"%s\"に設定できませんでした: %s" + +#: pg_backup_archiver.c:3341 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "search_pathを\"%s\"に設定できませんでした: %s" + +#: pg_backup_archiver.c:3403 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "default_tablespaceを\"%s\"に設定できませんでした: %s" + +#: pg_backup_archiver.c:3448 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "default_table_access_methodを設定できませんでした: %s" + +#: pg_backup_archiver.c:3540 pg_backup_archiver.c:3698 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "オブジェクトタイプ%sに対する所有者の設定方法がわかりません" + +#: pg_backup_archiver.c:3802 +#, c-format +msgid "did not find magic string in file header" +msgstr "ファイルヘッダにマジック文字列がありませんでした" + +#: pg_backup_archiver.c:3815 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "ファイルヘッダ内のバージョン(%d.%d)はサポートされていません" + +#: pg_backup_archiver.c:3820 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "整数のサイズ(%lu)に関する健全性検査が失敗しました" + +#: pg_backup_archiver.c:3824 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "アーカイブはより大きなサイズの整数を持つマシンで作成されました、一部の操作が失敗する可能性があります" + +#: pg_backup_archiver.c:3834 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "想定した形式(%d)はファイル内にある形式(%d)と異なります" + +#: pg_backup_archiver.c:3850 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "アーカイブは圧縮されていますが、このインストールでは圧縮をサポートしていません -- 利用できるデータはありません" + +#: pg_backup_archiver.c:3868 +#, c-format +msgid "invalid creation date in header" +msgstr "ヘッダ内の作成日付が不正です" + +#: pg_backup_archiver.c:3996 +#, c-format +msgid "processing item %d %s %s" +msgstr "項目 %d %s %s を処理しています" + +#: pg_backup_archiver.c:4075 +#, c-format +msgid "entering main parallel loop" +msgstr "メインの並列ループに入ります" + +#: pg_backup_archiver.c:4086 +#, c-format +msgid "skipping item %d %s %s" +msgstr "項目 %d %s %s をスキップしています" + +#: pg_backup_archiver.c:4095 +#, c-format +msgid "launching item %d %s %s" +msgstr "項目 %d %s %s に着手します" + +#: pg_backup_archiver.c:4149 +#, c-format +msgid "finished main parallel loop" +msgstr "メインの並列ループが終了しました" + +#: pg_backup_archiver.c:4187 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "やり残し項目 %d %s %s を処理しています" + +#: pg_backup_archiver.c:4792 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "テーブル\"%s\"を作成できませんでした、このテーブルのデータは復元されません" + +#: pg_backup_custom.c:376 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "ラージオブジェクトのOIDが不正です" + +#: pg_backup_custom.c:439 pg_backup_custom.c:505 pg_backup_custom.c:630 +#: pg_backup_custom.c:868 pg_backup_tar.c:1086 pg_backup_tar.c:1091 +#, c-format +msgid "error during file seek: %m" +msgstr "ファイルシーク中にエラーがありました: %m" + +#: pg_backup_custom.c:478 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "データブロック%dのシーク位置が間違っています" + +#: pg_backup_custom.c:495 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "アーカイブの探索中に認識不能のデータブロックタイプ(%d)がありました" + +#: pg_backup_custom.c:517 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "アーカイブ中にブロックID %d がありません -- おそらくリストア要求が順不同だったためですが、入力ファイルがシーク不可なため処理できません" + +#: pg_backup_custom.c:522 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "アーカイブ内にブロック ID %d がありませんでした -- おそらくアーカイブが壊れています" + +#: pg_backup_custom.c:529 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "データ読み込み時に想定外のブロックID(%d)がありました --想定は%d" + +#: pg_backup_custom.c:543 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "アーカイブのりストア中に認識不可のデータブロックタイプ%dがありました" + +#: pg_backup_custom.c:646 +#, c-format +msgid "could not read from input file: %m" +msgstr "入力ファイルから読み込めませんでした: %m" + +#: pg_backup_custom.c:749 pg_backup_custom.c:801 pg_backup_custom.c:946 +#: pg_backup_tar.c:1089 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "アーカイブファイルのシーク位置を決定できませんでした: %m" + +#: pg_backup_custom.c:765 pg_backup_custom.c:805 +#, c-format +msgid "could not close archive file: %m" +msgstr "アーカイブファイルをクローズできませんでした: %m" + +#: pg_backup_custom.c:788 +#, c-format +msgid "can only reopen input archives" +msgstr "入力アーカイブだけが再オープン可能です" + +#: pg_backup_custom.c:795 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "標準入力からの並列リストアはサポートされていません" + +#: pg_backup_custom.c:797 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "シーク不可のファイルからの並列リストアはサポートされていません" + +#: pg_backup_custom.c:813 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "アーカイブファイルのシークができませんでした: %m" + +#: pg_backup_custom.c:892 +#, c-format +msgid "compressor active" +msgstr "圧縮処理が有効です" + +#: pg_backup_db.c:42 +#, c-format +msgid "could not get server_version from libpq" +msgstr "libpqからserver_versionを取得できませんでした" + +#: pg_backup_db.c:53 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "サーババージョン: %s、%s バージョン: %s" + +#: pg_backup_db.c:55 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "サーババージョンの不一致のため処理を中断します" + +#: pg_backup_db.c:138 +#, c-format +msgid "connecting to database \"%s\" as user \"%s\"" +msgstr "データベース\"%s\"にユーザ\"%s\"で接続しています" + +#: pg_backup_db.c:145 pg_backup_db.c:194 pg_backup_db.c:255 pg_backup_db.c:296 +#: pg_dumpall.c:1651 pg_dumpall.c:1764 +msgid "Password: " +msgstr "パスワード: " + +#: pg_backup_db.c:177 +#, c-format +msgid "could not reconnect to database" +msgstr "データベースへの再接続ができませんでした" + +#: pg_backup_db.c:182 +#, c-format +msgid "could not reconnect to database: %s" +msgstr "データベース%sへの再接続ができませんでした" + +#: pg_backup_db.c:198 +#, c-format +msgid "connection needs password" +msgstr "接続にパスワードが必要です" + +#: pg_backup_db.c:249 +#, c-format +msgid "already connected to a database" +msgstr "データベースはすでに接続済みです" + +#: pg_backup_db.c:288 +#, c-format +msgid "could not connect to database" +msgstr "データベースへの接続ができませんでした" + +#: pg_backup_db.c:304 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "データベース\"%s\"への接続が失敗しました: %s" + +#: pg_backup_db.c:376 pg_dumpall.c:1684 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:383 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "問い合わせが失敗しました: %s" + +#: pg_backup_db.c:385 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "問い合わせ: %s" + +#: pg_backup_db.c:426 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "問い合わせが1行ではなく%d行返しました: %s" +msgstr[1] "問い合わせが1行ではなく%d行返しました: %s" + +#: pg_backup_db.c:462 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %sコマンド: %s" + +#: pg_backup_db.c:518 pg_backup_db.c:592 pg_backup_db.c:599 +msgid "could not execute query" +msgstr "問い合わせを実行できませんでした" + +#: pg_backup_db.c:571 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "PQputCopyData からエラーが返されました: %s" + +#: pg_backup_db.c:620 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "PQputCopyEnd からエラーが返されました: %s" + +#: pg_backup_db.c:626 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "テーブル\"%s\"へのコピーに失敗しました: %s" + +#: pg_backup_db.c:632 pg_dump.c:1984 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "ファイル\"%s\"をCOPY中に想定していない余分な結果がありました" + +#: pg_backup_db.c:644 +msgid "could not start database transaction" +msgstr "データベーストランザクションを開始できませんでした" + +#: pg_backup_db.c:652 +msgid "could not commit database transaction" +msgstr "データベーストランザクションをコミットできませんでした" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "出力ディレクトリが指定されていません" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "出力ファイルに書き込めませんでした: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "データファイル\"%s\"をクローズできませんでした: %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "ラージオブジェクトTOCファイル\"%s\"を入力用としてオープンできませんでした: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "ラージオブジェクトTOCファイル\"%s\"の中に不正な行がありました: \"%s\"" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "ラージオブジェクトTOCファイル\"%s\"の読み取り中にエラーがありました" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "ラージオブジェクトTOCファイル\"%s\"をクローズできませんでした: %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "blobs TOCファイルに書き出せませんでした" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "ファイル名が長すぎます: \"%s\"" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "この形式は読み込めません" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "TOCファイル\"%s\"を出力用にオープンできませんでした: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "TOCファイルを出力用にオープンできませんでした: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:358 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "tar アーカイブ形式では圧縮をサポートしていません" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "TOCファイル\"%s\"を入力用にオープンできませんでした: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "TOCファイルを入力用にオープンできませんでした: %m" + +#: pg_backup_tar.c:344 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "アーカイブ内にファイル\"%s\"がありませんでした" + +#: pg_backup_tar.c:410 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "一時ファイル名を生成できませんでした: %m" + +#: pg_backup_tar.c:421 +#, c-format +msgid "could not open temporary file" +msgstr "一時ファイルをオープンできませんでした" + +#: pg_backup_tar.c:448 +#, c-format +msgid "could not close tar member" +msgstr "tarメンバをクローズできませんでした" + +#: pg_backup_tar.c:691 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "想定外のCOPY文の構文: \"%s\"" + +#: pg_backup_tar.c:958 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "ラージオブジェクトの不正なOID(%u)" + +#: pg_backup_tar.c:1105 +#, c-format +msgid "could not close temporary file: %m" +msgstr "一時ファイルを開けませんでした: %m" + +#: pg_backup_tar.c:1114 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "実際の長さ(%s)が想定(%s)と一致しません" + +#: pg_backup_tar.c:1171 pg_backup_tar.c:1202 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "tar アーカイブ内でファイル\"%s\"のヘッダがありませんでした" + +#: pg_backup_tar.c:1189 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "このアーカイブ形式では、順不同でのデータのリストアはサポートされていません: \"%s\"は必要ですが、アーカイブファイル内で\"%s\"より前に来ました。" + +#: pg_backup_tar.c:1236 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "不完全なtarヘッダがありました(%luバイト)" +msgstr[1] "不完全なtarヘッダがありました(%luバイト)" + +#: pg_backup_tar.c:1287 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "破損したtarヘッダが%sにありました(想定 %d、算出結果 %d) ファイル位置 %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "認識不可のセクション名: \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:608 pg_dump.c:625 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は \"%s --help\" を実行してください\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "on_exit_nicelyスロットが足りません" + +#: pg_dump.c:534 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "圧縮レベルは 0..9 の範囲でなければなりません" + +#: pg_dump.c:572 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digitsは -15..3 の範囲でなければなりません" + +#: pg_dump.c:595 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insertは%d..%dの範囲でなければなりません" + +#: pg_dump.c:623 pg_dumpall.c:346 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "コマンドライン引数が多すぎます(先頭は\"%s\")" + +#: pg_dump.c:644 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "-s/--schema-only と -a/--data-only オプションは同時には使用できません" + +#: pg_dump.c:649 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "-s/--schema-only と --include-foreign-data オプションは同時には使用できません" + +#: pg_dump.c:652 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "オプション --include-foreign-data はパラレルバックアップではサポートされません" + +#: pg_dump.c:656 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "-c/--clean と -a/--data-only オプションは同時には使用できません" + +#: pg_dump.c:661 pg_dumpall.c:381 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "--if-existsは -c/--clean の指定が必要です" + +#: pg_dump.c:668 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "--on-conflict-do-nothingオプションは--inserts、--rows-per-insert または --column-insertsを必要とします" + +#: pg_dump.c:690 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "圧縮が要求されましたがこのインストールでは利用できません -- アーカイブは圧縮されません" + +#: pg_dump.c:711 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "不正な並列ジョブ数" + +#: pg_dump.c:715 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "並列バックアップはディレクトリ形式でのみサポートされます" + +#: pg_dump.c:770 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"同期スナップショットはこのサーババージョンではサポートされていません。\n" +"同期スナップショットが不要ならば--no-synchronized-snapshotsを付けて\n" +"実行してください。" + +#: pg_dump.c:776 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "スナップショットのエクスポートはこのサーババージョンではサポートされません" + +#: pg_dump.c:788 +#, c-format +msgid "last built-in OID is %u" +msgstr "最後の組み込みOIDは%u" + +#: pg_dump.c:797 +#, c-format +msgid "no matching schemas were found" +msgstr "マッチするスキーマが見つかりません" + +#: pg_dump.c:811 +#, c-format +msgid "no matching tables were found" +msgstr "マッチするテーブルが見つかりません" + +#: pg_dump.c:986 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%sはデータベースをテキストファイルまたはその他の形式でダンプします。\n" +"\n" + +#: pg_dump.c:987 pg_dumpall.c:617 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_dump.c:988 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]... [DBNAME]\n" + +#: pg_dump.c:990 pg_dumpall.c:620 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"一般的なオプション;\n" + +#: pg_dump.c:991 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=ファイル名 出力ファイルまたはディレクトリの名前\n" + +#: pg_dump.c:992 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p 出力ファイルの形式(custom, directory, tar, \n" +" plain text(デフォルト))\n" + +#: pg_dump.c:994 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=NUM ダンプ時に指定した数の並列ジョブを使用\n" + +#: pg_dump.c:995 pg_dumpall.c:622 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose 冗長モード\n" + +#: pg_dump.c:996 pg_dumpall.c:623 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_dump.c:997 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 圧縮形式における圧縮レベル\n" + +#: pg_dump.c:998 pg_dumpall.c:624 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " --lock-wait-timeout=TIMEOUT テーブルロックをTIMEOUT待ってから失敗\n" + +#: pg_dump.c:999 pg_dumpall.c:651 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync 変更のディスクへの安全な書き出しを待機しない\n" + +#: pg_dump.c:1000 pg_dumpall.c:625 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_dump.c:1002 pg_dumpall.c:626 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"出力内容を制御するためのオプション:\n" + +#: pg_dump.c:1003 pg_dumpall.c:627 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only データのみをダンプし、スキーマをダンプしない\n" + +#: pg_dump.c:1004 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs ダンプにラージオブジェクトを含める\n" + +#: pg_dump.c:1005 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs ダンプにラージオブジェクトを含めない\n" + +#: pg_dump.c:1006 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, --clean 再作成前にデータベースオブジェクトを整理(削除)\n" + +#: pg_dump.c:1007 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr " -C, --create ダンプにデータベース生成用コマンドを含める\n" + +#: pg_dump.c:1008 pg_dumpall.c:629 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=ENCODING ENCODING符号化方式でデータをダンプ\n" + +#: pg_dump.c:1009 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=SCHEMA 指定したスキーマのみをダンプ\n" + +#: pg_dump.c:1010 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=SCHEMA 指定したスキーマをダンプしない\n" + +#: pg_dump.c:1011 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner プレインテキスト形式で、オブジェクト所有権の\n" +" 復元を行わない\n" + +#: pg_dump.c:1013 pg_dumpall.c:633 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only スキーマのみをダンプし、データはダンプしない\n" + +#: pg_dump.c:1014 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, --superuser=NAME プレインテキスト形式で使用するスーパユーザの名前\n" + +#: pg_dump.c:1015 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=PATTERN 指定したテーブルのみをダンプ\n" + +#: pg_dump.c:1016 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=PATTERN 指定したテーブルをダンプしない\n" + +#: pg_dump.c:1017 pg_dumpall.c:636 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges 権限(grant/revoke)をダンプしない\n" + +#: pg_dump.c:1018 pg_dumpall.c:637 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade アップグレードユーティリティ専用\n" + +#: pg_dump.c:1019 pg_dumpall.c:638 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr " --column-inserts 列名指定のINSERTコマンドでデータをダンプ\n" + +#: pg_dump.c:1020 pg_dumpall.c:639 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr "" +" --disable-dollar-quoting ドル記号による引用符付けを禁止、SQL標準の引用符\n" +" 付けを使用\n" + +#: pg_dump.c:1021 pg_dumpall.c:640 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr " --disable-triggers データのみのリストアの際にトリガを無効化\n" + +#: pg_dump.c:1022 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security 行セキュリティを有効化(ユーザがアクセス可能な\n" +" 内容のみをダンプ)\n" + +#: pg_dump.c:1024 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " --exclude-table-data=PATTERN 指定したテーブルのデータをダンプしない\n" + +#: pg_dump.c:1025 pg_dumpall.c:642 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM extra_float_digitsの設定を上書きする\n" + +#: pg_dump.c:1026 pg_dumpall.c:643 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists オブジェクト削除の際に IF EXISTS を使用\n" + +#: pg_dump.c:1027 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=PATTERN\n" +" PATTERNに合致する外部サーバ上の外部テーブルの\n" +" データを含める\n" + +#: pg_dump.c:1030 pg_dumpall.c:644 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr " --inserts COPYではなくINSERTコマンドでデータをダンプ\n" + +#: pg_dump.c:1031 pg_dumpall.c:645 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root 子テーブルをルートテーブル経由でロードする\n" + +#: pg_dump.c:1032 pg_dumpall.c:646 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments コメントをダンプしない\n" + +#: pg_dump.c:1033 pg_dumpall.c:647 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications パブリケーションをダンプしない\n" + +#: pg_dump.c:1034 pg_dumpall.c:649 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels セキュリティラベルの割り当てをダンプしない\n" + +#: pg_dump.c:1035 pg_dumpall.c:650 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions サブスクリプションをダンプしない\n" + +#: pg_dump.c:1036 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr " --no-synchronized-snapshots 並列ジョブにおいて同期スナップショットを使用しない\n" + +#: pg_dump.c:1037 pg_dumpall.c:652 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces テーブルスペースの割り当てをダンプしない\n" + +#: pg_dump.c:1038 pg_dumpall.c:653 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data 非ログテーブルのデータをダンプしない\n" + +#: pg_dump.c:1039 pg_dumpall.c:654 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing INSERTコマンドにON CONFLICT DO NOTHINGを付加する\n" + +#: pg_dump.c:1040 pg_dumpall.c:655 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr "" +" --quote-all-identifiers すべての識別子をキーワードでなかったとしても\n" +" 引用符でくくる\n" + +#: pg_dump.c:1041 pg_dumpall.c:656 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NROWS INSERT毎の行数; --insertsを暗黙的に指定する\n" + +#: pg_dump.c:1042 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=SECTION 指定したセクション(データ前、データ、データ後)を\n" +" ダンプする\n" + +#: pg_dump.c:1043 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr " --serializable-deferrable ダンプを異常なく実行できるようになるまで待機\n" + +#: pg_dump.c:1044 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT ダンプに指定のスナップショットを使用する\n" + +#: pg_dump.c:1045 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names テーブル/スキーマの対象パターンが最低でも\n" +" 一つの実体にマッチすることを必須とする\n" + +#: pg_dump.c:1047 pg_dumpall.c:657 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" 所有者をセットする際、ALTER OWNER コマンドの代わり\n" +" に SET SESSION AUTHORIZATION コマンドを使用する\n" + +#: pg_dump.c:1051 pg_dumpall.c:661 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"接続オプション:\n" + +#: pg_dump.c:1052 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=DBNAME ダンプするデータベース\n" + +#: pg_dump.c:1053 pg_dumpall.c:663 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME データベースサーバのホストまたはソケットディレクトリ\n" + +#: pg_dump.c:1054 pg_dumpall.c:665 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT データベースサーバのポート番号\n" + +#: pg_dump.c:1055 pg_dumpall.c:666 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME 指定したデータベースユーザで接続\n" + +#: pg_dump.c:1056 pg_dumpall.c:667 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password パスワード入力を要求しない\n" + +#: pg_dump.c:1057 pg_dumpall.c:668 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr "" +" -W, --password パスワードプロンプトを強制表示します\n" +" (自動的に表示されるはず)\n" + +#: pg_dump.c:1058 pg_dumpall.c:669 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROLENAME ダンプの前に SET ROLE を行う\n" + +#: pg_dump.c:1060 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"データベース名が指定されなかった場合、環境変数PGDATABASEが使用されます\n" +"\n" + +#: pg_dump.c:1062 pg_dumpall.c:673 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "バグは<%s>に報告してください。\n" + +#: pg_dump.c:1063 pg_dumpall.c:674 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_dump.c:1082 pg_dumpall.c:499 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "不正なクライアントエンコーディング\"%s\"が指定されました" + +#: pg_dump.c:1228 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"同期スナップショットはこのサーババージョンではサポートされていません。\n" +"同期スナップショットが不要ならば--no-synchronized-snapshotsを付けて\n" +"実行してください。" + +#: pg_dump.c:1297 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "不正な出力形式\"%s\"が指定されました" + +#: pg_dump.c:1335 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "パターン\"%s\"にマッチするスキーマが見つかりません" + +#: pg_dump.c:1382 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "パターン\"%s\"にマッチする外部サーバーが見つかりません" + +#: pg_dump.c:1445 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "パターン \"%s\"にマッチするテーブルが見つかりません" + +#: pg_dump.c:1858 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "テーブル \"%s.%s\"の内容をダンプしています" + +#: pg_dump.c:1965 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "テーブル\"%s\"の内容のダンプに失敗: PQgetCopyData()が失敗しました。" + +#: pg_dump.c:1966 pg_dump.c:1976 +#, c-format +msgid "Error message from server: %s" +msgstr "サーバのエラーメッセージ: %s" + +#: pg_dump.c:1967 pg_dump.c:1977 +#, c-format +msgid "The command was: %s" +msgstr "コマンド: %s" + +#: pg_dump.c:1975 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "テーブル\"%s\"の内容のダンプに失敗: PQgetResult()が失敗しました。" + +#: pg_dump.c:2729 +#, c-format +msgid "saving database definition" +msgstr "データベース定義を保存しています" + +#: pg_dump.c:3201 +#, c-format +msgid "saving encoding = %s" +msgstr "encoding = %s を保存しています" + +#: pg_dump.c:3226 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "standard_conforming_strings = %s を保存しています" + +#: pg_dump.c:3265 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "current_schemas()の結果をパースできませんでした" + +#: pg_dump.c:3284 +#, c-format +msgid "saving search_path = %s" +msgstr "search_path = %s を保存しています" + +#: pg_dump.c:3324 +#, c-format +msgid "reading large objects" +msgstr "ラージオブジェクトを読み込んでいます" + +#: pg_dump.c:3506 +#, c-format +msgid "saving large objects" +msgstr "ラージオブジェクトを保存しています" + +#: pg_dump.c:3552 +#, c-format +msgid "error reading large object %u: %s" +msgstr "ラージオブジェクト %u を読み取り中にエラーがありました: %s" + +#: pg_dump.c:3604 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"で有効な行セキュリティ設定を読み込んでいます" + +#: pg_dump.c:3635 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"のポリシを読み込んでいます" + +#: pg_dump.c:3787 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "想定外のポリシコマンドタイプ: \"%c\"" + +#: pg_dump.c:3938 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "パブリケーション\"%s\"の所有者が不正なようです" + +#: pg_dump.c:4083 +#, c-format +msgid "reading publication membership for table \"%s.%s\"" +msgstr "パブリケーション\"%s.%s\"の構成要素を読み込んでいます" + +#: pg_dump.c:4227 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "現在のユーザがスーパユーザではないため、サブスクリプションはダンプされません" + +#: pg_dump.c:4292 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "サブスクリプション\"%s\"の所有者が無効なようです" + +#: pg_dump.c:4336 +#, c-format +msgid "could not parse subpublications array" +msgstr "subpublications配列をパースできませんでした" + +#: pg_dump.c:4649 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "%s %sの親となる機能拡張がありませんでした" + +#: pg_dump.c:4781 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "スキーマ\"%s\"の所有者が無効なようです" + +#: pg_dump.c:4804 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "OID %uのスキーマは存在しません" + +#: pg_dump.c:5129 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "データ型\"%s\"の所有者が無効なようです" + +#: pg_dump.c:5214 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "演算子\"%s\"の所有者が無効なようです" + +#: pg_dump.c:5516 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "演算子クラス\"%s\"の所有者が無効なようです" + +#: pg_dump.c:5600 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "演算子族\"%s\"の所有者が無効なようです" + +#: pg_dump.c:5769 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "集約関数\"%s\"の所有者が無効なようです" + +#: pg_dump.c:6029 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "関数\"%s\"の所有者が無効なようです" + +#: pg_dump.c:6857 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "テーブル\"%s\"の所有者が無効なようです" + +#: pg_dump.c:6899 pg_dump.c:17136 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "健全性検査に失敗しました、OID %2$u であるシーケンスの OID %1$u である親テーブルがありません" + +#: pg_dump.c:7041 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"のインデックスを読み込んでいます" + +#: pg_dump.c:7456 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"の外部キー制約を読み込んでいます" + +#: pg_dump.c:7735 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "健全性検査に失敗しました、OID %2$u であるpg_rewriteエントリのOID %1$u である親テーブルが見つかりません" + +#: pg_dump.c:7818 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"のトリガを読み込んでいます" + +#: pg_dump.c:7951 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "問い合わせがテーブル\"%2$s\"上の外部キートリガ\"%1$s\"の参照テーブル名としてNULLを返しました(テーブルのOID: %3$u)" + +#: pg_dump.c:8485 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"の列と型を探しています" + +#: pg_dump.c:8601 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "テーブル\"%s\"の列番号が不正です" + +#: pg_dump.c:8638 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"のデフォルト式を探しています" + +#: pg_dump.c:8660 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "テーブル\"%2$s\"用のadnumの値%1$dが不正です" + +#: pg_dump.c:8725 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"の検査制約を探しています" + +#: pg_dump.c:8774 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "テーブル\"%2$s\"で想定する検査制約は%1$d個でしたが、%3$dありました" +msgstr[1] "テーブル\"%2$s\"で想定する検査制約は%1$d個でしたが、%3$dありました" + +#: pg_dump.c:8778 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(システムカタログが破損している可能性があります)" + +#: pg_dump.c:10364 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "データ型\"%s\"のtyptypeが不正なようです" + +#: pg_dump.c:11718 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "proargmodes配列内におかしな値があります" + +#: pg_dump.c:12002 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "proallargtypes配列のパースができませんでした" + +#: pg_dump.c:12018 +#, c-format +msgid "could not parse proargmodes array" +msgstr "proargmodes配列のパースができませんでした" + +#: pg_dump.c:12032 +#, c-format +msgid "could not parse proargnames array" +msgstr "proargnames配列のパースができませんでした" + +#: pg_dump.c:12043 +#, c-format +msgid "could not parse proconfig array" +msgstr "proconfig配列のパースができませんでした" + +#: pg_dump.c:12123 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "関数\"%s\"のprovolatileの値が認識できません" + +#: pg_dump.c:12173 pg_dump.c:14118 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "関数\"%s\"のproparallel値が認識できません" + +#: pg_dump.c:12312 pg_dump.c:12421 pg_dump.c:12428 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "OID %uの関数の関数定義が見つかりませんでした" + +#: pg_dump.c:12351 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "pg_cast.castfuncまたはpg_cast.castmethodフィールドの値がおかしいです" + +#: pg_dump.c:12354 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "pg_cast.castmethod フィールドの値がおかしいです" + +#: pg_dump.c:12447 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "おかしな変換定義、trffromsql か trftosql の少なくとも一方は非ゼロであるはずです" + +#: pg_dump.c:12464 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "pg_cast.castmethod フィールドの値がおかしいです" + +#: pg_dump.c:12485 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "pg_cast.castmethod フィールドの値がおかしいです" + +#: pg_dump.c:12801 +#, c-format +msgid "could not find operator with OID %s" +msgstr "OID %sの演算子がありませんでした" + +#: pg_dump.c:12869 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "アクセスメソッド\"%2$s\"の不正なタイプ\"%1$c\"" + +#: pg_dump.c:13623 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "認識できないの照合順序プロバイダ: %s" + +#: pg_dump.c:14037 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "集約\"%s\"のaggfinalmodifyの値が識別できません" + +#: pg_dump.c:14093 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "集約\"%s\"のaggmfinalmodifyの値が識別できません" + +#: pg_dump.c:14815 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "デフォルト権限設定中の認識できないオブジェクト型: %d" + +#: pg_dump.c:14833 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "デフォルトの ACL リスト(%s)をパースできませんでした" + +#: pg_dump.c:14918 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "オブジェクト\"%3$s\"(%4$s)の初期GRANT ACLリスト(%1$s)または初期REVOKE ACLリスト(%2$s)をパースできませんでした" + +#: pg_dump.c:14926 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "オブジェクト\"%3$s\"(%4$s)のGRANT ACLリスト(%1$s)またはREVOKE ACLリスト(%2$s)をパースできませんでした" + +#: pg_dump.c:15441 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "ビュー\"%s\"の定義を取り出すための問い合わせがデータを返却しませんでした" + +#: pg_dump.c:15444 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "ビュー\"%s\"の定義を取り出すための問い合わせが2つ以上の定義を返却しました" + +#: pg_dump.c:15451 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "ビュー\"%s\"の定義が空のようです(長さが0)" + +#: pg_dump.c:15533 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDSは今後サポートされません(テーブル\"%s\")" + +#: pg_dump.c:16013 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "テーブル\"%2$s\"用の親テーブルの数%1$dが不正です" + +#: pg_dump.c:16336 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "テーブル\"%2$s\"の列番号%1$dは不正です" + +#: pg_dump.c:16621 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "制約\"%s\"のインデックスが見つかりません" + +#: pg_dump.c:16846 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "制約のタイプが識別できません: %c" + +#: pg_dump.c:16978 pg_dump.c:17201 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "シーケンス\"%s\"のデータを得るための問い合わせが%d行返却しました(想定は1)" +msgstr[1] "シーケンス\"%s\"のデータを得るための問い合わせが%d行返却しました(想定は1)" + +#: pg_dump.c:17012 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "認識されないシーケンスの型\"%s\"" + +#: pg_dump.c:17299 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "想定外のtgtype値: %d" + +#: pg_dump.c:17373 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "テーブル\"%3$s\"上のトリガ\"%2$s\"の引数文字列(%1$s)が不正です" + +#: pg_dump.c:17609 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "テーブル\"%2$s\"のルール\"%1$s\"を得るための問い合わせが失敗しました: 間違った行数が返却されました" + +#: pg_dump.c:17771 +#, c-format +msgid "could not find referenced extension %u" +msgstr "親の機能拡張%uが見つかりません" + +#: pg_dump.c:17983 +#, c-format +msgid "reading dependency data" +msgstr "データの依存データを読み込んでいます" + +#: pg_dump.c:18076 +#, c-format +msgid "no referencing object %u %u" +msgstr "参照元オブジェクト%u %uがありません" + +#: pg_dump.c:18087 +#, c-format +msgid "no referenced object %u %u" +msgstr "参照先オブジェクト%u %uがありません" + +#: pg_dump.c:18460 +#, c-format +msgid "could not parse reloptions array" +msgstr "reloptions 配列をパースできませんでした" + +#: pg_dump_sort.c:360 +#, c-format +msgid "invalid dumpId %d" +msgstr "不正なdumpId %d" + +#: pg_dump_sort.c:366 +#, c-format +msgid "invalid dependency %d" +msgstr "不正な依存関係 %d" + +#: pg_dump_sort.c:599 +#, c-format +msgid "could not identify dependency loop" +msgstr "依存関係のループが見つかりませんでした" + +#: pg_dump_sort.c:1170 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "次のテーブルの中で外部キー制約の循環があります: " +msgstr[1] "次のテーブルの中で外部キー制約の循環があります: " + +#: pg_dump_sort.c:1174 pg_dump_sort.c:1194 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1175 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "--disable-triggersの使用または一時的な制約の削除を行わずにこのダンプをリストアすることはできないかもしれません。" + +#: pg_dump_sort.c:1176 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "この問題を回避するために--data-onlyダンプの代わりに完全なダンプを使用することを検討してください。" + +#: pg_dump_sort.c:1188 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "以下の項目の間の依存関係のループを解決できませんでした:" + +#: pg_dumpall.c:199 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%2$sには\"%1$s\"プログラムが必要ですが、\"%3$s\"と同じディレクトリ\n" +"にありませんでした。\n" +"インストール状況を確認してください。" + +#: pg_dumpall.c:204 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じ\n" +"バージョンではありませんでした。\n" +"インストール状況を確認してください。" + +#: pg_dumpall.c:356 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "--exclude-database オプションは -g/--globals-only、-r/--roles-only もしくは -t/--tablespaces-only と一緒には使用できません" + +#: pg_dumpall.c:365 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "-g/--globals-onlyと-r/--roles-onlyオプションは同時に使用できません" + +#: pg_dumpall.c:373 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "-g/--globals-onlyと-t/--tablespaces-onlyオプションは同時に使用できません" + +#: pg_dumpall.c:387 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "-r/--roles-onlyと-t/--tablespaces-onlyオプションは同時に使用できません" + +#: pg_dumpall.c:448 pg_dumpall.c:1754 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "データベース\"%s\"へ接続できませんでした" + +#: pg_dumpall.c:462 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"\"postgres\"または\"template1\"データベースに接続できませんでした\n" +"代わりのデータベースを指定してください。" + +#: pg_dumpall.c:616 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%sはPostgreSQLデータベースクラスタをSQLスクリプトファイルに展開します。\n" +"\n" + +#: pg_dumpall.c:618 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPTION]...\n" + +#: pg_dumpall.c:621 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=ファイル名 出力ファイル名\n" + +#: pg_dumpall.c:628 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, --clean 再作成前にデータベースを整理(削除)\n" + +#: pg_dumpall.c:630 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, --globals-only グローバルオブジェクトのみをダンプし、データベースをダンプしません\n" + +#: pg_dumpall.c:631 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner オブジェクトの所有権の復元を省略\n" + +#: pg_dumpall.c:632 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr "" +" -r, --roles-only ロールのみをダンプ。\n" +" データベースとテーブル空間をダンプしません\n" + +#: pg_dumpall.c:634 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, --superuser=NAME ダンプで使用するスーパユーザのユーザ名を指定\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr " -t, --tablespaces-only テーブル空間のみをダンプ。データベースとロールをダンプしません\n" + +#: pg_dumpall.c:641 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=PATTERN PATTERNに合致する名前のデータベースを除外\n" + +#: pg_dumpall.c:648 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords ロールのパスワードをダンプしない\n" + +#: pg_dumpall.c:662 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=CONSTR 接続文字列を用いた接続\n" + +#: pg_dumpall.c:664 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=DBNAME 代替のデフォルトデータベースを指定\n" + +#: pg_dumpall.c:671 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"-f/--file が指定されない場合、SQLスクリプトは標準出力に書き出されます。\n" +"\n" + +#: pg_dumpall.c:877 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "\"pg_\"で始まるロール名はスキップされました(%s)" + +#: pg_dumpall.c:1278 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "テーブル空間\"%2$s\"のACLリスト(%1$s)をパースできませんでした" + +#: pg_dumpall.c:1495 +#, c-format +msgid "excluding database \"%s\"" +msgstr "データベース\"%s\"除外します" + +#: pg_dumpall.c:1499 +#, c-format +msgid "dumping database \"%s\"" +msgstr "データベース\"%s\"をダンプしています" + +#: pg_dumpall.c:1531 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "データベース\"%s\"のダンプが失敗しました、終了します" + +#: pg_dumpall.c:1540 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "出力ファイル\"%s\"を再オープンできませんでした: %m" + +#: pg_dumpall.c:1584 +#, c-format +msgid "running \"%s\"" +msgstr "\"%s\"を実行しています" + +#: pg_dumpall.c:1775 +#, c-format +msgid "could not connect to database \"%s\": %s" +msgstr "データベース\"%s\"へ接続できませんでした: %s" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "サーババージョンを取得できませんでした" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "サーババージョン\"%s\"をパースできませんでした" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "%s を実行しています" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "-d/--dbnameと-f/--fileのどちらか一方が指定されていなければなりません" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "オプション-d/--dbnameと-f/--fileは同時に使用できません" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "オプション-C/--createと-1/--single-transactionとは同時には使用できません" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "並列ジョブ数の最大値は%dです" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "--single-transaction と複数ジョブは同時には指定できません" + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "アーカイブ形式\"%s\"が認識できません; \"c\"、\"d\"または\"t\"を指定してください" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "リストア中に無視されたエラー数: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%sはpg_dumpで作成したアーカイブからPostgreSQLデータベースをリストアします。\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [OPTION]... [FILE]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=NAME 接続するデータベース名\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=FILENAME 出力ファイル名(- で標準出力)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr "" +" -F, --format=c|d|t バックアップファイルの形式\n" +" (自動的に設定されるはずです)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list アーカイブのTOCの要約を表示\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose 冗長モードです\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示し、終了します\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示し、終了します\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"リストア制御用のオプション:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only データのみをリストア。スキーマをリストアしません\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create 対象のデータベースを作成\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, --exit-on-error エラー時に終了。デフォルトは継続\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=NAME 指名したインデックスをリストア\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, --jobs=NUM リストア時に指定した数の並列ジョブを使用\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=FILENAME このファイルの内容に従って SELECT や\n" +" 出力のソートを行います\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NAME 指定したスキーマのオブジェクトのみをリストア\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NAME 指定したスキーマのオブジェクトはリストアしない\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NAME(args) 指名された関数をリストア\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only スキーマのみをリストア。データをリストアしません\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr " -S, --superuser=NAME トリガを無効にするためのスーパユーザの名前\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=NAME 指名したリレーション(テーブル、ビューなど)をリストア\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=NAME 指名したトリガをリストア\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, --no-privileges アクセス権限(grant/revoke)の復元を省略\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction 単一のトランザクションとしてリストア\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security 行セキュリティを有効にします\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments コメントをリストアしない\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables 作成できなかったテーッブルのデータはリストア\n" +" しません\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications パブリケーションをリストアしない\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels セキュリティラベルをリストアしません\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions サブスクリプションをリストアしない\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces テーブル空間の割り当てをリストアしません\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr " --section=SECTION 指定されたセクション(データ前部、データ、データ後部)をリストア\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROLENAME リストアに先立って SET ROLE します\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +" -I, -n, -N, -P, -t, -T および --section オプションは組み合わせて複数回\n" +"指定することで複数のオブジェクトを指定できます。\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"入力ファイル名が指定されない場合、標準入力が使用されます。\n" +"\n" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "子プロセスがシグナル%dで終了しました" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "ディレクトリを\"%s\"に変更できませんでした" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version バージョン情報を表示し、終了します\n" + +#~ msgid "file archiver" +#~ msgstr "ファイルアーカイバ" + +#~ msgid "could not create worker thread: %s\n" +#~ msgstr "ワーカースレッドを作成できませんでした: %s\n" + +#~ msgid "*** aborted because of error\n" +#~ msgstr "*** エラーのため中断\n" + +#~ msgid "found more than one entry for pg_indexes in pg_class\n" +#~ msgstr "pg_class内にpg_indexes用のエントリが複数ありました\n" + +#~ msgid "cannot reopen non-seekable file\n" +#~ msgstr "シークできないファイルを再オープンできません\n" + +#~ msgid "restoring large object OID %u\n" +#~ msgstr "OID %uのラージオブジェクトをリストアしています\n" + +#~ msgid "cannot reopen stdin\n" +#~ msgstr "標準入力を再オープンできません\n" + +#~ msgid "could not find entry for pg_indexes in pg_class\n" +#~ msgstr "pg_class内にpg_indexes用のエントリがありませんでした\n" + +#~ msgid "could not open large object TOC for output: %s\n" +#~ msgstr "出力用のラージオブジェクトTOCをオープンできませんでした: %s\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help ヘルプを表示し、終了します\n" + +#~ msgid "invalid COPY statement -- could not find \"copy\" in string \"%s\"\n" +#~ msgstr "COPY文が無効です -- 文字列\"%s\"に\"copy\"がありませんでした\n" + +#~ msgid "could not open large object TOC for input: %s\n" +#~ msgstr "入力用のラージオブジェクトTOCをオープンできませんでした: %s\n" + +#~ msgid "query returned no rows: %s\n" +#~ msgstr "問い合わせの結果行がありませんでした: %s\n" + +#~ msgid "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n" +#~ msgstr "dumpDatabase(): pg_largeobject.relfrozenxid が見つかりません\n" + +#~ msgid "missing pg_database entry for database \"%s\"\n" +#~ msgstr "データベース\"%s\"用のエントリがpg_databaseにありません\n" + +#~ msgid "%s: invalid -X option -- %s\n" +#~ msgstr "%s: 無効な -X オプション -- %s\n" + +#~ msgid "" +#~ "WARNING:\n" +#~ " This format is for demonstration purposes; it is not intended for\n" +#~ " normal use. Files will be written in the current working directory.\n" +#~ msgstr "" +#~ "警告:\n" +#~ "この書式はデモを目的としたものです。通常の使用を意図したものではありま\n" +#~ "せん。ファイルは現在の作業ディレクトリに書き出されます\n" + +#~ msgid "%s: could not parse version \"%s\"\n" +#~ msgstr "%s: バージョン\"%s\"を解析できませんでした\n" + +#~ msgid "could not close large object file\n" +#~ msgstr "ラージオブジェクトファイルをクローズできませんでした\n" + +#~ msgid " -O, --no-owner skip restoration of object ownership\n" +#~ msgstr " -O, --no-owner オブジェクトの所有権の復元を省略\n" + +#~ msgid "cannot duplicate null pointer\n" +#~ msgstr "null ポインタを複製できません\n" + +#~ msgid "" +#~ " --use-set-session-authorization\n" +#~ " use SET SESSION AUTHORIZATION commands instead of\n" +#~ " ALTER OWNER commands to set ownership\n" +#~ msgstr "" +#~ " --use-set-session-authorization\n" +#~ " 所有者をセットする際、ALTER OWNER コマンドの代り\n" +#~ " に SET SESSION AUTHORIZATION コマンドを使用する\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: メモリ不足です\n" + +#~ msgid " -c, --clean clean (drop) database objects before recreating\n" +#~ msgstr " -c, --clean 再作成前にデータベースを削除します\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help ヘルプを表示して終了\n" + +#~ msgid "SQL command failed\n" +#~ msgstr "SQLコマンドが失敗しました\n" + +#~ msgid " --disable-triggers disable triggers during data-only restore\n" +#~ msgstr "" +#~ " --disable-triggers \n" +#~ " データのみの復元中にトリガを無効にします\n" + +#~ msgid "query returned more than one (%d) pg_database entry for database \"%s\"\n" +#~ msgstr "問い合わせにより、データベース\"%2$s\"用のエントリがpg_databaseから複数(%1$d)返されました\n" + +#~ msgid "invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n" +#~ msgstr "COPY文が無効です -- 文字列\"%s\"の%lu位置から\"from stdin\"がありませんでした\n" + +#~ msgid "found more than one pg_database entry for this database\n" +#~ msgstr "このデータベース用のpg_databaseエントリが複数ありました\n" + +#~ msgid "could not parse version string \"%s\"\n" +#~ msgstr "バージョン文字列\"%s\"を解析できませんでした\n" + +#~ msgid "dumpDatabase(): could not find pg_largeobject_metadata.relfrozenxid\n" +#~ msgstr "dumpDatabase(): pg_largeobject_metadata.relfrozenxidが見つかりません\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "子プロセスがシグナル%sで終了しました" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version バージョン情報を表示して終了\n" + +#~ msgid "could not close data file after reading\n" +#~ msgstr "読み込んだ後データファイルをクローズできませんでした\n" + +#~ msgid "-C and -c are incompatible options\n" +#~ msgstr "オプション-Cと-cは互換性がありません\n" + +#~ msgid "missing pg_database entry for this database\n" +#~ msgstr "このデータベース用のpg_databaseエントリが見つかりません\n" + +#~ msgid "parallel_restore should not return\n" +#~ msgstr "parallel_restore は return しません\n" + +#~ msgid "worker process crashed: status %d\n" +#~ msgstr "ワーカープロセスがクラッシュしました:ステータス %d\n" + +#~ msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" +#~ msgstr "内部エラー -- tarReadRaw()にてthもfhも指定されていませんでした\n" diff --git a/src/bin/pg_dump/po/ko.po b/src/bin/pg_dump/po/ko.po new file mode 100644 index 000000000000..f533f7e4729d --- /dev/null +++ b/src/bin/pg_dump/po/ko.po @@ -0,0 +1,2821 @@ +# Korean message translation file for PostgreSQL pg_dump +# Ioseph Kim , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_dump (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:46+0000\n" +"PO-Revision-Date: 2020-10-06 13:40+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean Team \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "현재 디렉터리를 알 수 없음: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "잘못된 바이너리 파일 \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" 바이너리 파일을 읽을 수 없음" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "실행 할 \"%s\" 파일을 찾을 수 없음" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" 이름의 디렉터리로 이동할 수 없습니다: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "\"%s\" 심볼릭 링크 파일을 읽을 수 없음: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose 실패: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "메모리 부족" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null 포인터를 중복할 수 없음 (내부 오류)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "명령을 실행할 수 없음" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "해당 명령어 없음" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "하위 프로세스가 종료되었음, 종료 코드 %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "0x%X 예외처리로 하위 프로세스가 종료되었음" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "하위 프로세스가 종료되었음, 시그널 %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "하위 프로세스가 종료되었음, 알수 없는 상태 %d" + +#: common.c:121 +#, c-format +msgid "reading extensions" +msgstr "확장 기능 읽는 중" + +#: common.c:125 +#, c-format +msgid "identifying extension members" +msgstr "확장 멤버를 식별 중" + +#: common.c:128 +#, c-format +msgid "reading schemas" +msgstr "스키마들을 읽는 중" + +#: common.c:138 +#, c-format +msgid "reading user-defined tables" +msgstr "사용자 정의 테이블들을 읽는 중" + +#: common.c:145 +#, c-format +msgid "reading user-defined functions" +msgstr "사용자 정의 함수들 읽는 중" + +#: common.c:150 +#, c-format +msgid "reading user-defined types" +msgstr "사용자 정의 자료형을 읽는 중" + +#: common.c:155 +#, c-format +msgid "reading procedural languages" +msgstr "프로시쥬얼 언어를 읽는 중" + +#: common.c:158 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "사용자 정의 집계 함수를 읽는 중" + +#: common.c:161 +#, c-format +msgid "reading user-defined operators" +msgstr "사용자 정의 연산자를 읽는 중" + +#: common.c:165 +#, c-format +msgid "reading user-defined access methods" +msgstr "사용자 정의 접근 방법을 읽는 중" + +#: common.c:168 +#, c-format +msgid "reading user-defined operator classes" +msgstr "사용자 정의 연산자 클래스를 읽는 중" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator families" +msgstr "사용자 정의 연산자 부류들 읽는 중" + +#: common.c:174 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "사용자 정의 텍스트 검색 파서를 읽는 중" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search templates" +msgstr "사용자 정의 텍스트 검색 템플릿을 읽는 중" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "사용자 정의 텍스트 검색 사전을 읽는 중" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "사용자 정의 텍스트 검색 구성을 읽는 중" + +#: common.c:186 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "사용자 정의 외부 데이터 래퍼를 읽는 중" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "사용자 정의 외부 서버를 읽는 중" + +#: common.c:192 +#, c-format +msgid "reading default privileges" +msgstr "기본 접근 권한 읽는 중" + +#: common.c:195 +#, c-format +msgid "reading user-defined collations" +msgstr "사용자 정의 글자 정렬(collation) 읽는 중" + +#: common.c:199 +#, c-format +msgid "reading user-defined conversions" +msgstr "사용자 정의 인코딩 변환규칙을 읽는 중" + +#: common.c:202 +#, c-format +msgid "reading type casts" +msgstr "형변환자(type cast)들을 읽는 중" + +#: common.c:205 +#, c-format +msgid "reading transforms" +msgstr "변환자(transform) 읽는 중" + +#: common.c:208 +#, c-format +msgid "reading table inheritance information" +msgstr "테이블 상속 정보를 읽는 중" + +#: common.c:211 +#, c-format +msgid "reading event triggers" +msgstr "이벤트 트리거들을 읽는 중" + +#: common.c:215 +#, c-format +msgid "finding extension tables" +msgstr "확장 테이블을 찾는 중" + +#: common.c:219 +#, c-format +msgid "finding inheritance relationships" +msgstr "상속 관계를 조사중" + +#: common.c:222 +#, c-format +msgid "reading column info for interesting tables" +msgstr "재미난 테이블들(interesting tables)을 위해 열 정보를 읽는 중" + +#: common.c:225 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "하위 테이블에서 상속된 열 구분중" + +#: common.c:228 +#, c-format +msgid "reading indexes" +msgstr "인덱스들을 읽는 중" + +#: common.c:231 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "하위 파티션 테이블에서 인덱스를 플래그 처리하는 중" + +#: common.c:234 +#, c-format +msgid "reading extended statistics" +msgstr "확장 통계들을 읽는 중" + +#: common.c:237 +#, c-format +msgid "reading constraints" +msgstr "제약 조건들을 읽는 중" + +#: common.c:240 +#, c-format +msgid "reading triggers" +msgstr "트리거들을 읽는 중" + +#: common.c:243 +#, c-format +msgid "reading rewrite rules" +msgstr "룰(rule) 읽는 중" + +#: common.c:246 +#, c-format +msgid "reading policies" +msgstr "정책 읽는 중" + +#: common.c:249 +#, c-format +msgid "reading publications" +msgstr "발행 정보를 읽는 중" + +#: common.c:252 +#, c-format +msgid "reading publication membership" +msgstr "발행 맵버쉽을 읽을 중" + +#: common.c:255 +#, c-format +msgid "reading subscriptions" +msgstr "구독정보를 읽는 중" + +#: common.c:1025 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "안전 검사 실패, OID %u인 부모 개체가 없음. 해당 테이블 \"%s\" (OID %u)" + +#: common.c:1067 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "\"%s\" 숫자 배열을 분석할 수 없음: 너무 많은 숫자들이 있음" + +#: common.c:1082 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "\"%s\" 숫자 배열을 분석할 수 없음: 숫자안에 이상한 글자가 있음" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "잘못된 압축 수위: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "zlib 지원 기능이 없음" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "압축 라이브러리를 초기화 할 수 없음: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "압축 스트림을 닫을 수 없음: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "자료를 압축할 수 없음: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "자료 압축을 풀 수 없습니다: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "압축 라이브러리를 닫을 수 없음: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:557 pg_backup_tar.c:560 +#, c-format +msgid "could not read from input file: %s" +msgstr "입력 파일을 읽을 수 없음: %s" + +#: compress_io.c:623 pg_backup_custom.c:646 pg_backup_directory.c:552 +#: pg_backup_tar.c:793 pg_backup_tar.c:816 +#, c-format +msgid "could not read from input file: end of file" +msgstr "입력 파일을 읽을 수 없음: 파일 끝" + +# # search5 끝 +# # advance 부분 +#: parallel.c:267 +#, c-format +msgid "WSAStartup failed: %d" +msgstr "WSAStartup 작업 실패: %d" + +#: parallel.c:978 +#, c-format +msgid "could not create communication channels: %m" +msgstr "통신 체널을 만들 수 없음: %m" + +#: parallel.c:1035 +#, c-format +msgid "could not create worker process: %m" +msgstr "작업자 프로세스를 만들 수 없음: %m" + +#: parallel.c:1165 +#, c-format +msgid "unrecognized command received from master: \"%s\"" +msgstr "마스터에서 알 수 없는 명령을 받음: \"%s\"" + +#: parallel.c:1208 parallel.c:1446 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "작업 프로세스로부터 잘못된 메시지를 받음: \"%s\"" + +#: parallel.c:1340 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the " +"table after the pg_dump parent process had gotten the initial ACCESS SHARE " +"lock on the table." +msgstr "" +"\"%s\" 릴레이션을 선점할 수 없음\n" +"이 상황은 일반적으로 다른 세션에서 해당 테이블을 이미 덤프하고 있거나 기타 다" +"른 이유로 다른 세션에 의해서 선점 된 경우입니다." + +#: parallel.c:1429 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "작업 프로세스가 예상치 않게 종료됨" + +#: parallel.c:1551 parallel.c:1669 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "통신 체널에에 쓸 수 없음: %m" + +#: parallel.c:1628 +#, c-format +msgid "select() failed: %m" +msgstr "select() 실패: %m" + +#: parallel.c:1753 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: 소켓을 만들 수 없음: 오류 코드 %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: 바인딩 할 수 없음: 오류 코드 %d" + +#: parallel.c:1771 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: 리슨 할 수 없음: 오류 코드 %d" + +#: parallel.c:1778 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname() 실패: 오류 코드 %d" + +#: parallel.c:1789 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: 두번째 소켓을 만들 수 없음: 오류 코드 %d" + +#: parallel.c:1798 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: 소켓 접속 실패: 오류 코드 %d" + +#: parallel.c:1807 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: 접속을 승인할 수 없음: 오류 코드 %d" + +#: pg_backup_archiver.c:277 pg_backup_archiver.c:1587 +#, c-format +msgid "could not close output file: %m" +msgstr "출력 파일을 닫을 수 없음: %m" + +#: pg_backup_archiver.c:321 pg_backup_archiver.c:325 +#, c-format +msgid "archive items not in correct section order" +msgstr "아카이브 아이템의 순서가 섹션에서 비정상적임" + +#: pg_backup_archiver.c:331 +#, c-format +msgid "unexpected section code %d" +msgstr "예상치 못한 섹션 코드 %d" + +#: pg_backup_archiver.c:368 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "이 아카이브 파일 형식에서는 병렬 복원이 지원되지 않음" + +#: pg_backup_archiver.c:372 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "8.0 이전 pg_dump로 만든 아카이브에서는 병렬 복원이 지원되지 않음" + +#: pg_backup_archiver.c:390 +#, c-format +msgid "" +"cannot restore from compressed archive (compression not supported in this " +"installation)" +msgstr "" +"압축된 자료파일을 복원용으로 사용할 수 없습니다(압축기능을 지원하지 않고 컴파" +"일되었음)" + +#: pg_backup_archiver.c:407 +#, c-format +msgid "connecting to database for restore" +msgstr "복원 작업을 위해 데이터베이스에 접속 중" + +#: pg_backup_archiver.c:409 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "pre-1.3 archive에서 직통 데이터베이스 접속은 지원되지 않음" + +#: pg_backup_archiver.c:452 +#, c-format +msgid "implied data-only restore" +msgstr "암묵적으로 자료만 복원" + +#: pg_backup_archiver.c:518 +#, c-format +msgid "dropping %s %s" +msgstr "%s %s 삭제 중" + +#: pg_backup_archiver.c:613 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "\"%s\" 구문에서 insert IF EXISTS 부분을 찾을 수 없음" + +#: pg_backup_archiver.c:769 pg_backup_archiver.c:771 +#, c-format +msgid "warning from original dump file: %s" +msgstr "원본 덤프 파일에서 발생한 경고: %s" + +#: pg_backup_archiver.c:786 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "%s \"%s.%s\" 만드는 중" + +#: pg_backup_archiver.c:789 +#, c-format +msgid "creating %s \"%s\"" +msgstr "%s \"%s\" 만드는 중" + +#: pg_backup_archiver.c:839 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "\"%s\" 새 데이터베이스에 접속중" + +#: pg_backup_archiver.c:866 +#, c-format +msgid "processing %s" +msgstr "%s 처리 중" + +#: pg_backup_archiver.c:886 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블의 자료를 처리 중" + +#: pg_backup_archiver.c:948 +#, c-format +msgid "executing %s %s" +msgstr "실행중: %s %s" + +#: pg_backup_archiver.c:987 +#, c-format +msgid "disabling triggers for %s" +msgstr "%s 트리거 작동을 비활성화 하는 중" + +#: pg_backup_archiver.c:1013 +#, c-format +msgid "enabling triggers for %s" +msgstr "%s 트리거 작동을 활성화 하는 중" + +#: pg_backup_archiver.c:1041 +#, c-format +msgid "" +"internal error -- WriteData cannot be called outside the context of a " +"DataDumper routine" +msgstr "내부 오류 -- WriteData는 DataDumper 루틴 영역 밖에서 호출 될 수 없음" + +#: pg_backup_archiver.c:1224 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "선택한 파일 양식으로는 large-object를 덤프할 수 없음" + +#: pg_backup_archiver.c:1282 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "%d개의 큰 개체가 복원됨" + +#: pg_backup_archiver.c:1303 pg_backup_tar.c:736 +#, c-format +msgid "restoring large object with OID %u" +msgstr "%u OID large object를 복원중" + +#: pg_backup_archiver.c:1315 +#, c-format +msgid "could not create large object %u: %s" +msgstr "%u large object를 만들 수 없음: %s" + +#: pg_backup_archiver.c:1320 pg_dump.c:3548 +#, c-format +msgid "could not open large object %u: %s" +msgstr "%u large object를 열 수 없음: %s" + +#: pg_backup_archiver.c:1377 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "TOC 파일 \"%s\"을(를) 열 수 없음: %m" + +#: pg_backup_archiver.c:1417 +#, c-format +msgid "line ignored: %s" +msgstr "줄 무시됨: %s" + +#: pg_backup_archiver.c:1424 +#, c-format +msgid "could not find entry for ID %d" +msgstr "%d ID에 대한 항목을 찾지 못했음" + +#: pg_backup_archiver.c:1445 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "TOC 파일을 닫을 수 없음: %m" + +#: pg_backup_archiver.c:1559 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:484 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "\"%s\" 출력 파일을 열 수 없음: %m" + +#: pg_backup_archiver.c:1561 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "출력 파일을 열 수 없음: %m" + +#: pg_backup_archiver.c:1654 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "%lu바이트의 큰 개체 데이터를 씀(결과 = %lu)" + +#: pg_backup_archiver.c:1659 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "large object를 쓸 수 없음 (결과값: %lu, 예상값: %lu)" + +#: pg_backup_archiver.c:1749 +#, c-format +msgid "while INITIALIZING:" +msgstr "초기화 작업 중:" + +#: pg_backup_archiver.c:1754 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "TOC 처리하는 중:" + +#: pg_backup_archiver.c:1759 +#, c-format +msgid "while FINALIZING:" +msgstr "뒷 마무리 작업 중:" + +#: pg_backup_archiver.c:1764 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "%d TOC 항목에서; %u %u %s %s %s" + +#: pg_backup_archiver.c:1840 +#, c-format +msgid "bad dumpId" +msgstr "잘못된 dumpID" + +#: pg_backup_archiver.c:1861 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "TABLE DATA 아이템에 대한 잘못된 테이블 dumpId" + +#: pg_backup_archiver.c:1953 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "예상치 못한 자료 옵셋 플래그 %d" + +#: pg_backup_archiver.c:1966 +#, c-format +msgid "file offset in dump file is too large" +msgstr "덤프 파일에서 파일 옵셋 값이 너무 큽니다" + +#: pg_backup_archiver.c:2103 pg_backup_archiver.c:2113 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "디렉터리 이름이 너무 긺: \"%s\"" + +#: pg_backup_archiver.c:2121 +#, c-format +msgid "" +"directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not " +"exist)" +msgstr "\"%s\" 디렉터리가 알맞은 아카이브용이 아님 (\"toc.dat\" 파일이 없음)" + +#: pg_backup_archiver.c:2129 pg_backup_custom.c:173 pg_backup_custom.c:812 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "\"%s\" 입력 파일을 열 수 없음: %m" + +#: pg_backup_archiver.c:2136 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "입력 파일을 열 수 없음: %m" + +#: pg_backup_archiver.c:2142 +#, c-format +msgid "could not read input file: %m" +msgstr "입력 파일을 읽을 수 없음: %m" + +#: pg_backup_archiver.c:2144 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "입력 파일이 너무 짧습니다 (%lu 읽었음, 예상치 5)" + +#: pg_backup_archiver.c:2229 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "입력 파일은 일반 텍스트 덤프 파일입니다. psql 명령을 사용하세요." + +#: pg_backup_archiver.c:2235 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "입력 파일에서 타당한 아카이브를 찾을 수 없습니다(너무 짧은지?)" + +#: pg_backup_archiver.c:2241 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "입력 파일에서 타당한 아카이브를 찾을 수 없음" + +#: pg_backup_archiver.c:2261 +#, c-format +msgid "could not close input file: %m" +msgstr "입력 파일을 닫을 수 없음: %m" + +#: pg_backup_archiver.c:2373 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "알 수 없는 파일 포멧: \"%d\"" + +#: pg_backup_archiver.c:2455 pg_backup_archiver.c:4458 +#, c-format +msgid "finished item %d %s %s" +msgstr "%d %s %s 항목 마침" + +#: pg_backup_archiver.c:2459 pg_backup_archiver.c:4471 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "작업자 프로세스 실패: 종료 코드 %d" + +#: pg_backup_archiver.c:2579 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "%d ID 항목은 범위를 벗어났음 -- TOC 정보가 손상된 듯 합니다" + +#: pg_backup_archiver.c:2646 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "WITH OIDS 옵션이 있는 테이블의 복원은 이제 지원하지 않습니다" + +#: pg_backup_archiver.c:2728 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "알 수 없는 인코딩: \"%s\"" + +#: pg_backup_archiver.c:2733 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "잘못된 ENCODING 항목: %s" + +#: pg_backup_archiver.c:2751 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "잘못된 STDSTRINGS 항목: %s" + +#: pg_backup_archiver.c:2776 +#, c-format +msgid "schema \"%s\" not found" +msgstr "\"%s\" 스키마를 찾을 수 없음" + +#: pg_backup_archiver.c:2783 +#, c-format +msgid "table \"%s\" not found" +msgstr "\"%s\" 테이블을 찾을 수 없음" + +#: pg_backup_archiver.c:2790 +#, c-format +msgid "index \"%s\" not found" +msgstr "\"%s\" 인덱스를 찾을 수 없음" + +#: pg_backup_archiver.c:2797 +#, c-format +msgid "function \"%s\" not found" +msgstr "\"%s\" 함수를 찾을 수 없음" + +#: pg_backup_archiver.c:2804 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "\"%s\" 트리거를 찾을 수 없음" + +#: pg_backup_archiver.c:3196 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "\"%s\" 사용자로 세션 사용자를 지정할 수 없음: %s" + +#: pg_backup_archiver.c:3328 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "search_path를 \"%s\"(으)로 지정할 수 없음: %s" + +#: pg_backup_archiver.c:3390 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "default_tablespace로 %s(으)로 지정할 수 없음: %s" + +#: pg_backup_archiver.c:3435 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "default_table_access_method를 지정할 수 없음: %s" + +#: pg_backup_archiver.c:3527 pg_backup_archiver.c:3685 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "\"%s\" 개체의 소유주를 지정할 수 없습니다" + +#: pg_backup_archiver.c:3789 +#, c-format +msgid "did not find magic string in file header" +msgstr "파일 헤더에서 매직 문자열을 찾지 못했습니다" + +#: pg_backup_archiver.c:3802 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "파일 헤더에 있는 %d.%d 버전은 지원되지 않습니다" + +#: pg_backup_archiver.c:3807 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "정수 크기 (%lu) 안전성 검사 실패" + +#: pg_backup_archiver.c:3811 +#, c-format +msgid "" +"archive was made on a machine with larger integers, some operations might " +"fail" +msgstr "" +"이 아카이브는 큰 정수를 지원하는 시스템에서 만들어졌습니다. 그래서 몇 동작이 " +"실패할 수도 있습니다." + +#: pg_backup_archiver.c:3821 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "예상되는 포멧 (%d)와 발견된 파일 포멧 (%d)이 서로 다름" + +#: pg_backup_archiver.c:3837 +#, c-format +msgid "" +"archive is compressed, but this installation does not support compression -- " +"no data will be available" +msgstr "" +"아카이브는 압축되어있지만, 이 프로그램에서는 압축기능을 지원하지 못합니다 -- " +"이 안에 있는 자료를 모두 사용할 수 없습니다." + +#: pg_backup_archiver.c:3855 +#, c-format +msgid "invalid creation date in header" +msgstr "헤더에 잘못된 생성 날짜가 있음" + +#: pg_backup_archiver.c:3983 +#, c-format +msgid "processing item %d %s %s" +msgstr "%d %s %s 항목을 처리하는 중" + +#: pg_backup_archiver.c:4062 +#, c-format +msgid "entering main parallel loop" +msgstr "기본 병렬 루프로 시작 중" + +#: pg_backup_archiver.c:4073 +#, c-format +msgid "skipping item %d %s %s" +msgstr "%d %s %s 항목을 건너뛰는 중" + +#: pg_backup_archiver.c:4082 +#, c-format +msgid "launching item %d %s %s" +msgstr "%d %s %s 항목을 시작하는 중" + +#: pg_backup_archiver.c:4136 +#, c-format +msgid "finished main parallel loop" +msgstr "기본 병렬 루프 마침" + +#: pg_backup_archiver.c:4172 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "누락된 %d %s %s 항목 처리 중" + +#: pg_backup_archiver.c:4777 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "\"%s\" 테이블을 만들 수 없어, 해당 자료는 복원되지 않을 것입니다." + +#: pg_backup_custom.c:378 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "잘못된 large object용 OID" + +#: pg_backup_custom.c:441 pg_backup_custom.c:507 pg_backup_custom.c:632 +#: pg_backup_custom.c:870 pg_backup_tar.c:1086 pg_backup_tar.c:1091 +#, c-format +msgid "error during file seek: %m" +msgstr "파일 seek 작업하는 도중 오류가 발생했습니다: %m" + +#: pg_backup_custom.c:480 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "%d 자료 블록에 잘못된 접근 위치가 있음" + +#: pg_backup_custom.c:497 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "아카이브 검색하는 동안 알 수 없는 자료 블럭 형태(%d)를 발견함" + +#: pg_backup_custom.c:519 +#, c-format +msgid "" +"could not find block ID %d in archive -- possibly due to out-of-order " +"restore request, which cannot be handled due to non-seekable input file" +msgstr "" +"아카이브에서 블록 ID %d을(를) 찾지 못했습니다. 복원 요청이 잘못된 것 같습니" +"다. 입력 파일을 검색할 수 없으므로 요청을 처리할 수 없습니다." + +#: pg_backup_custom.c:524 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "" +"아카이브에서 블록 ID %d을(를) 찾을 수 없습니다. 아카이브가 손상된 것 같습니" +"다." + +#: pg_backup_custom.c:531 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "자료를 읽는 동안 예상치 못한 ID (%d) 발견됨 -- 예상값 %d" + +#: pg_backup_custom.c:545 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "아카이브 복원하는 중에, 알 수 없는 자료 블럭 형태 %d 를 발견함" + +#: pg_backup_custom.c:648 +#, c-format +msgid "could not read from input file: %m" +msgstr "입력 파일을 읽을 수 없음: %m" + +#: pg_backup_custom.c:751 pg_backup_custom.c:803 pg_backup_custom.c:948 +#: pg_backup_tar.c:1089 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "아카이브 파일에서 검색 위치를 확인할 수 없음: %m" + +#: pg_backup_custom.c:767 pg_backup_custom.c:807 +#, c-format +msgid "could not close archive file: %m" +msgstr "자료 파일을 닫을 수 없음: %m" + +#: pg_backup_custom.c:790 +#, c-format +msgid "can only reopen input archives" +msgstr "입력 아카이브만 다시 열 수 있음" + +#: pg_backup_custom.c:797 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "표준 입력을 이용한 병렬 복원 작업은 지원하지 않습니다" + +#: pg_backup_custom.c:799 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "" +"시작 위치를 임의로 지정할 수 없는 파일로는 병렬 복원 작업을 할 수 없습니다." + +#: pg_backup_custom.c:815 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "아카이브 파일에서 검색 위치를 설정할 수 없음: %m" + +#: pg_backup_custom.c:894 +#, c-format +msgid "compressor active" +msgstr "압축기 사용" + +#: pg_backup_db.c:41 +#, c-format +msgid "could not get server_version from libpq" +msgstr "libpq에서 server_verion 값을 구할 수 없음" + +#: pg_backup_db.c:52 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "서버 버전: %s; %s 버전: %s" + +#: pg_backup_db.c:54 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "서버 버전이 일치하지 않아 중단하는 중" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "데이터베이스에 이미 접속해 있음" + +#: pg_backup_db.c:133 pg_backup_db.c:185 pg_dumpall.c:1651 pg_dumpall.c:1764 +msgid "Password: " +msgstr "암호: " + +#: pg_backup_db.c:177 +#, c-format +msgid "could not connect to database" +msgstr "데이터베이스 접속을 할 수 없음" + +#: pg_backup_db.c:195 +#, c-format +msgid "reconnection to database \"%s\" failed: %s" +msgstr "\"%s\" 데이터베이스 재접속 실패: %s" + +#: pg_backup_db.c:199 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "\"%s\" 데이터베이스에 접속 할 수 없음: %s" + +#: pg_backup_db.c:272 pg_dumpall.c:1684 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:279 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "쿼리 실패: %s" + +#: pg_backup_db.c:281 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "사용한 쿼리: %s" + +#: pg_backup_db.c:322 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "쿼리에서 한 개가 아닌 %d개의 행을 반환: %s" + +#: pg_backup_db.c:358 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %s사용된 명령: %s" + +#: pg_backup_db.c:414 pg_backup_db.c:488 pg_backup_db.c:495 +msgid "could not execute query" +msgstr "쿼리를 실행 할 수 없음" + +#: pg_backup_db.c:467 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "PQputCopyData에 의해서 오류가 반환되었음: %s" + +#: pg_backup_db.c:516 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "PQputCopyEnd에 의해서 오류가 반환되었음: %s" + +#: pg_backup_db.c:522 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "\"%s\" 테이블을 위한 COPY 실패: %s" + +#: pg_backup_db.c:528 pg_dump.c:1988 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "\"%s\" 테이블 COPY 작업 중 잘못된 부가 결과가 있음" + +#: pg_backup_db.c:540 +msgid "could not start database transaction" +msgstr "데이터베이스 트랜잭션을 시작할 수 없음" + +#: pg_backup_db.c:548 +msgid "could not commit database transaction" +msgstr "데이터베이스 트랜잭션을 commit 할 수 없음" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "자료가 저장될 디렉터리를 지정하지 않았음" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 읽을 수 없음: %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 닫을 수 없음: %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 만들 수 없음: %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "출력 파일을 쓸 수 없음: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "\"%s\" 자료 파일을 닫을 수 없음: %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "입력용 large object TOC 파일(\"%s\")을 열 수 없음: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "large object TOC 파일(\"%s\")을 닫을 수 없음: \"%s\"" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "large object TOC 파일(\"%s\")을 닫을 수 없음" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "large object TOC 파일(\"%s\")을 닫을 수 없음: %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "blob TOC 파일에 쓸 수 없음" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "파일 이름이 너무 긺: \"%s\"" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "이 파일 형태는 읽을 수 없음" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "출력용 TOC 파일 \"%s\"을(를) 열 수 없음: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "출력용 TOC 파일을 열 수 없음: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:358 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "tar 출력 포멧에서 압축 기능을 지원하지 않음" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "입력용 TOC 파일(\"%s\")을 열 수 없음: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "입력용 TOC 파일을 열 수 없음: %m" + +#: pg_backup_tar.c:344 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "아카이브에서 \"%s\" 파일을 찾을 수 없음" + +#: pg_backup_tar.c:410 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "임시 파일 이름을 짓지 못했습니다: %m" + +#: pg_backup_tar.c:421 +#, c-format +msgid "could not open temporary file" +msgstr "임시 파일을 열 수 없음" + +#: pg_backup_tar.c:448 +#, c-format +msgid "could not close tar member" +msgstr "tar 맴버를 닫지 못했습니다" + +#: pg_backup_tar.c:691 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "COPY 구문 오류: \"%s\"" + +#: pg_backup_tar.c:958 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "잘못된 large object OID: %u" + +#: pg_backup_tar.c:1105 +#, c-format +msgid "could not close temporary file: %m" +msgstr "임시 파일을 열 수 없음: %m" + +#: pg_backup_tar.c:1114 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "실재 파일 길이(%s)와 예상되는 값(%s)이 다릅니다" + +#: pg_backup_tar.c:1171 pg_backup_tar.c:1201 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "tar 아카이브에서 \"%s\" 파일을 위한 헤더를 찾을 수 없음" + +#: pg_backup_tar.c:1189 +#, c-format +msgid "" +"restoring data out of order is not supported in this archive format: \"%s\" " +"is required, but comes before \"%s\" in the archive file." +msgstr "" +"순서를 넘어서는 자료 덤프 작업은 이 아카이브 포멧에서는 지원하지 않습니다: " +"\"%s\" 요구되었지만, 이 아카이브 파일에서는 \"%s\" 전에 옵니다." + +#: pg_backup_tar.c:1234 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "불완전한 tar 헤더가 있음(%lu 바이트)" + +#: pg_backup_tar.c:1285 +#, c-format +msgid "" +"corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "%s 안에 손상된 tar 헤더 발견 (예상치 %d, 계산된 값 %d), 파일 위치 %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "알 수 없는 섹션 이름: \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:607 pg_dump.c:624 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 자세한 사용법은 \"%s --help\"\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "on_exit_nicely 슬롯 범위 벗어남" + +#: pg_dump.c:533 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "압축 수위는 0부터 9까지 지정할 수 있음" + +#: pg_dump.c:571 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits 값은 -15..3 사이값이어야 함" + +#: pg_dump.c:594 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insert 값은 %d부터 %d까지 지정할 수 있습니다." + +#: pg_dump.c:622 pg_dumpall.c:346 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "너무 많은 명령행 인자를 지정했음 (시작: \"%s\")" + +#: pg_dump.c:643 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "-s/--schema-only 옵션과 -a/--data-only 옵션은 함께 사용할 수 없음" + +#: pg_dump.c:648 +#, c-format +msgid "" +"options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "" +"-s/--schema-only 옵션과 --include-foreign-data 옵션은 함께 사용할 수 없음" + +#: pg_dump.c:651 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "--include-foreign-data 옵션은 병렬 백업 작업에서 지원하지 않음" + +#: pg_dump.c:655 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "-c/--clean 옵션과 -a/--data-only 옵션은 함께 사용할 수 없음" + +#: pg_dump.c:660 pg_dumpall.c:381 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "--if-exists 옵션은 -c/--clean 옵션과 함께 사용해야 함" + +#: pg_dump.c:667 +#, c-format +msgid "" +"option --on-conflict-do-nothing requires option --inserts, --rows-per-" +"insert, or --column-inserts" +msgstr "" +"--on-conflict-do-nothing 옵션은 --inserts, --rows-per-insert 또는 --column-" +"inserts 옵션과 함께 사용해야 함" + +#: pg_dump.c:689 +#, c-format +msgid "" +"requested compression not available in this installation -- archive will be " +"uncompressed" +msgstr "" +"요청한 압축 기능은 이 설치판에서는 사용할 수 없습니다 -- 자료 파일은 압축 없" +"이 만들어질 것입니다" + +#: pg_dump.c:710 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "잘못된 병렬 작업 수" + +#: pg_dump.c:714 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "병렬 백업은 디렉터리 기반 출력일 때만 사용할 수 있습니다." + +#: pg_dump.c:769 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"이 서버 버전에서는 동기화된 스냅샷 기능을 사용할 수 없음.\n" +"동기화된 스냅샷 기능이 필요 없다면, --no-synchronized-snapshots\n" +"옵션을 지정해서 덤프할 수 있습니다." + +#: pg_dump.c:775 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "이 서버는 exported snapshot을 지원하지 않음." + +#: pg_dump.c:787 +#, c-format +msgid "last built-in OID is %u" +msgstr "마지막 내장 OID는 %u" + +#: pg_dump.c:796 +#, c-format +msgid "no matching schemas were found" +msgstr "조건에 맞는 스키마가 없습니다" + +#: pg_dump.c:810 +#, c-format +msgid "no matching tables were found" +msgstr "조건에 맞는 테이블이 없습니다" + +#: pg_dump.c:990 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s 프로그램은 데이터베이스를 텍스트 파일 또는 기타\n" +"다른 형태의 파일로 덤프합니다.\n" +"\n" + +#: pg_dump.c:991 pg_dumpall.c:617 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_dump.c:992 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [옵션]... [DB이름]\n" + +#: pg_dump.c:994 pg_dumpall.c:620 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"일반 옵션들:\n" + +#: pg_dump.c:995 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=파일이름 출력 파일 또는 디렉터리 이름\n" + +#: pg_dump.c:996 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p 출력 파일 형식(사용자 지정, 디렉터리, tar,\n" +" 일반 텍스트(초기값))\n" + +#: pg_dump.c:998 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=개수 덤프 작업을 병렬 처리 함\n" + +#: pg_dump.c:999 pg_dumpall.c:622 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose 작업 내역을 자세히 봄\n" + +#: pg_dump.c:1000 pg_dumpall.c:623 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: pg_dump.c:1001 +#, c-format +msgid "" +" -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 출력 자료 압축 수위\n" + +#: pg_dump.c:1002 pg_dumpall.c:624 +#, c-format +msgid "" +" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr "" +" --lock-wait-timeout=초 테이블 잠금 시 지정한 초만큼 기다린 후 실패\n" + +#: pg_dump.c:1003 pg_dumpall.c:651 +#, c-format +msgid "" +" --no-sync do not wait for changes to be written safely " +"to disk\n" +msgstr " --no-sync fsync 작업 생략\n" + +#: pg_dump.c:1004 pg_dumpall.c:625 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_dump.c:1006 pg_dumpall.c:626 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"출력 내용을 다루는 옵션들:\n" + +#: pg_dump.c:1007 pg_dumpall.c:627 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only 스키마 빼고 자료만 덤프\n" + +#: pg_dump.c:1008 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs Large Object들도 함께 덤프함\n" + +#: pg_dump.c:1009 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs Large Object들을 제외하고 덤프함\n" + +#: pg_dump.c:1010 pg_restore.c:476 +#, c-format +msgid "" +" -c, --clean clean (drop) database objects before " +"recreating\n" +msgstr "" +" -c, --clean 다시 만들기 전에 데이터베이스 개체 지우기(삭" +"제)\n" + +#: pg_dump.c:1011 +#, c-format +msgid "" +" -C, --create include commands to create database in dump\n" +msgstr "" +" -C, --create 데이터베이스 만드는 명령구문도 포함시킴\n" + +#: pg_dump.c:1012 pg_dumpall.c:629 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=인코딩 지정한 인코딩으로 자료를 덤프 함\n" + +#: pg_dump.c:1013 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=PATTERN 지정한 SCHEMA들 자료만 덤프\n" + +#: pg_dump.c:1014 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=PATTERN 지정한 SCHEMA들만 빼고 모두 덤프\n" + +#: pg_dump.c:1015 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner 일반 텍스트 형식에서\n" +" 개체 소유권 복원 건너뛰기\n" + +#: pg_dump.c:1017 pg_dumpall.c:633 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only 자료구조(스키마)만 덤프\n" + +#: pg_dump.c:1018 +#, c-format +msgid "" +" -S, --superuser=NAME superuser user name to use in plain-text " +"format\n" +msgstr "" +" -S, --superuser=NAME 일반 텍스트 형식에서 사용할 슈퍼유저 사용자 이" +"름\n" + +#: pg_dump.c:1019 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=PATTERN 지정한 이름의 테이블들만 덤프\n" + +#: pg_dump.c:1020 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=PATTERN 지정한 테이블들만 빼고 덤프\n" + +#: pg_dump.c:1021 pg_dumpall.c:636 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr "" +" -x, --no-privileges 접근 권한 (grant/revoke) 정보는 덤프 안 함\n" + +#: pg_dump.c:1022 pg_dumpall.c:637 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade 업그레이드 유틸리티 전용\n" + +#: pg_dump.c:1023 pg_dumpall.c:638 +#, c-format +msgid "" +" --column-inserts dump data as INSERT commands with column " +"names\n" +msgstr "" +" --column-inserts 칼럼 이름과 함께 INSERT 명령으로 자료 덤프\n" + +#: pg_dump.c:1024 pg_dumpall.c:639 +#, c-format +msgid "" +" --disable-dollar-quoting disable dollar quoting, use SQL standard " +"quoting\n" +msgstr "" +" --disable-dollar-quoting $ 인용 구문 사용안함, SQL 표준 따옴표 사용\n" + +#: pg_dump.c:1025 pg_dumpall.c:640 pg_restore.c:493 +#, c-format +msgid "" +" --disable-triggers disable triggers during data-only restore\n" +msgstr " --disable-triggers 자료만 복원할 때 트리거 사용을 안함\n" + +#: pg_dump.c:1026 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user " +"has\n" +" access to)\n" +msgstr "" +" --enable-row-security 로우 보안 활성화 (현재 작업자가 접근할 수\n" +" 있는 자료만 덤프 함)\n" + +#: pg_dump.c:1028 +#, c-format +msgid "" +" --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " --exclude-table-data=PATTERN 해당 테이블 자료는 덤프 안함\n" + +#: pg_dump.c:1029 pg_dumpall.c:642 +#, c-format +msgid "" +" --extra-float-digits=NUM override default setting for " +"extra_float_digits\n" +msgstr " --extra-float-digits=NUM 기본 extra_float_digits 값 바꿈\n" + +#: pg_dump.c:1030 pg_dumpall.c:643 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists 객체 삭제 시 IF EXISTS 구문 사용\n" + +#: pg_dump.c:1031 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=패턴\n" +" 지정한 패턴과 일치하는 외부 서버의 외부\n" +" 테이블 자료를 포함\n" + +#: pg_dump.c:1034 pg_dumpall.c:644 +#, c-format +msgid "" +" --inserts dump data as INSERT commands, rather than " +"COPY\n" +msgstr " --inserts COPY 대신 INSERT 명령으로 자료 덤프\n" + +#: pg_dump.c:1035 pg_dumpall.c:645 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr "" +" --load-via-partition-root 상위 테이블을 통해 하위 테이블을 로드함\n" + +#: pg_dump.c:1036 pg_dumpall.c:646 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments 코멘트는 덤프 안함\n" + +#: pg_dump.c:1037 pg_dumpall.c:647 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications 발행 정보는 덤프하지 않음\n" + +#: pg_dump.c:1038 pg_dumpall.c:649 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels 보안 라벨 할당을 덤프 하지 않음\n" + +#: pg_dump.c:1039 pg_dumpall.c:650 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions 구독 정보는 덤프하지 않음\n" + +#: pg_dump.c:1040 +#, c-format +msgid "" +" --no-synchronized-snapshots do not use synchronized snapshots in parallel " +"jobs\n" +msgstr "" +" --no-synchronized-snapshots 병렬 작업에서 스냅샷 일관성을 맞추지 않음\n" + +#: pg_dump.c:1041 pg_dumpall.c:652 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces 테이블스페이스 할당을 덤프하지 않음\n" + +#: pg_dump.c:1042 pg_dumpall.c:653 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data 언로그드 테이블 자료는 덤프하지 않음\n" + +#: pg_dump.c:1043 pg_dumpall.c:654 +#, c-format +msgid "" +" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT " +"commands\n" +msgstr "" +" --on-conflict-do-nothing INSERT 구문에 ON CONFLICT DO NOTHING 옵션 추" +"가\n" + +#: pg_dump.c:1044 pg_dumpall.c:655 +#, c-format +msgid "" +" --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr "" +" --quote-all-identifiers 예약어가 아니여도 모든 식별자는 따옴표를 씀\n" + +#: pg_dump.c:1045 pg_dumpall.c:656 +#, c-format +msgid "" +" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr "" +" --rows-per-insert=NROWS 한 INSERT 명령으로 입력할 로우 수; --inserts\n" +" 옵션을 사용한 것으로 가정 함\n" + +#: pg_dump.c:1046 +#, c-format +msgid "" +" --section=SECTION dump named section (pre-data, data, or post-" +"data)\n" +msgstr "" +" --section=SECTION 해당 섹션(pre-data, data, post-data)만 덤프\n" + +#: pg_dump.c:1047 +#, c-format +msgid "" +" --serializable-deferrable wait until the dump can run without " +"anomalies\n" +msgstr "" +" --serializable-deferrable 자료 정합성을 보장하기 위해 덤프 작업을\n" +" 직렬화 가능한 트랜잭션으로 처리 함\n" + +#: pg_dump.c:1048 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT 지정한 스냅샷을 덤프 함\n" + +#: pg_dump.c:1049 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns " +"to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names 테이블이나 스키마를 지정했을 때 그 패턴에 맞" +"는\n" +" 객체가 적어도 하나 이상 있어야 함\n" + +#: pg_dump.c:1051 pg_dumpall.c:657 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands " +"instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" SET SESSION AUTHORIZATION 명령을 ALTER OWNER " +"명령\n" +" 대신 사용하여 소유권 설정\n" + +#: pg_dump.c:1055 pg_dumpall.c:661 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"연결 옵션들:\n" + +#: pg_dump.c:1056 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=DBNAME 덤프할 데이터베이스\n" + +#: pg_dump.c:1057 pg_dumpall.c:663 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr "" +" -h, --host=HOSTNAME 접속할 데이터베이스 서버 또는 소켓 디렉터리\n" + +#: pg_dump.c:1058 pg_dumpall.c:665 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT 데이터베이스 서버의 포트 번호\n" + +#: pg_dump.c:1059 pg_dumpall.c:666 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME 연결할 데이터베이스 사용자\n" + +#: pg_dump.c:1060 pg_dumpall.c:667 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password 암호 프롬프트 표시 안 함\n" + +#: pg_dump.c:1061 pg_dumpall.c:668 pg_restore.c:515 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr " -W, --password 암호 입력 프롬프트 보임(자동으로 처리함)\n" + +#: pg_dump.c:1062 pg_dumpall.c:669 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROLENAME 덤프 전에 SET ROLE 수행\n" + +#: pg_dump.c:1064 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"데이터베이스 이름을 지정하지 않았다면, PGDATABASE 환경변수값을\n" +"사용합니다.\n" +"\n" + +#: pg_dump.c:1066 pg_dumpall.c:673 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "문제점 보고 주소 <%s>\n" + +#: pg_dump.c:1067 pg_dumpall.c:674 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: pg_dump.c:1086 pg_dumpall.c:499 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "클라이언트 인코딩 값이 잘못되었습니다: \"%s\"" + +#: pg_dump.c:1232 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server " +"version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"이 서버 버전에서는 대기 서버에서 동기화된 스냅샷 기능을 사용할 수 없음.\n" +"동기화된 스냅샷 기능이 필요 없다면, --no-synchronized-snapshots\n" +"옵션을 지정해서 덤프할 수 있습니다." + +#: pg_dump.c:1301 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "\"%s\" 값은 잘못된 출력 파일 형태입니다." + +#: pg_dump.c:1339 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "\"%s\" 검색 조건에 만족하는 스키마가 없습니다" + +#: pg_dump.c:1386 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "\"%s\" 검색 조건에 만족하는 외부 서버가 없습니다" + +#: pg_dump.c:1449 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "\"%s\" 검색 조건에 만족하는 테이블이 없습니다" + +#: pg_dump.c:1862 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블의 내용 덤프 중" + +#: pg_dump.c:1969 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "\"%s\" 테이블 내용을 덤프하면서 오류 발생: PQgetCopyData() 실패." + +#: pg_dump.c:1970 pg_dump.c:1980 +#, c-format +msgid "Error message from server: %s" +msgstr "서버에서 보낸 오류 메시지: %s" + +#: pg_dump.c:1971 pg_dump.c:1981 +#, c-format +msgid "The command was: %s" +msgstr "사용된 명령: %s" + +#: pg_dump.c:1979 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "\"%s\" 테이블 내용을 덤프하면서 오류 발생: PQgetResult() 실패." + +#: pg_dump.c:2735 +#, c-format +msgid "saving database definition" +msgstr "데이터베이스 구성정보를 저장 중" + +#: pg_dump.c:3207 +#, c-format +msgid "saving encoding = %s" +msgstr "인코딩 = %s 저장 중" + +#: pg_dump.c:3232 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "standard_conforming_strings = %s 저장 중" + +#: pg_dump.c:3271 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "current_schemas() 결과를 분석할 수 없음" + +#: pg_dump.c:3290 +#, c-format +msgid "saving search_path = %s" +msgstr "search_path = %s 저장 중" + +#: pg_dump.c:3330 +#, c-format +msgid "reading large objects" +msgstr "large object 읽는 중" + +#: pg_dump.c:3512 +#, c-format +msgid "saving large objects" +msgstr "large object들을 저장 중" + +#: pg_dump.c:3558 +#, c-format +msgid "error reading large object %u: %s" +msgstr "%u large object 읽는 중 오류: %s" + +#: pg_dump.c:3610 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블을 위한 로우 보안 활성화를 읽는 중" + +#: pg_dump.c:3641 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블을 위한 정책 읽는 중" + +#: pg_dump.c:3793 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "예상치 못한 정책 명령 형태: %c" + +#: pg_dump.c:3944 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "\"%s\" 구독의 소유주가 적당하지 않습니다." + +#: pg_dump.c:4089 +#, c-format +msgid "reading publication membership for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블을 위한 발행 맵버쉽을 읽는 중" + +#: pg_dump.c:4232 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "" +"현재 사용자가 슈퍼유저가 아니기 때문에 서브스크립션들은 덤프하지 못했음" + +#: pg_dump.c:4286 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "\"%s\" 구독의 소유주가 적당하지 않습니다." + +#: pg_dump.c:4330 +#, c-format +msgid "could not parse subpublications array" +msgstr "구독 배열을 분석할 수 없음" + +#: pg_dump.c:4652 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "%s %s 객체와 관련된 상위 확장 기능을 찾을 수 없음" + +#: pg_dump.c:4784 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "\"%s\" 스키마의 소유주가 바르지 않습니다" + +#: pg_dump.c:4807 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "OID %u 스키마 없음" + +#: pg_dump.c:5132 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "\"%s\" 자료형의 소유주가 적당하지 않습니다." + +#: pg_dump.c:5217 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "\"%s\" 연산자의 소유주가 적당하지 않습니다." + +#: pg_dump.c:5519 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "\"%s\" 연산자 클래스의 소유주가 적당하지 않습니다." + +#: pg_dump.c:5603 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "\"%s\" 연산자 부류의 소유주가 적당하지 않습니다." + +#: pg_dump.c:5772 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "\"%s\" 집계 함수의 소유주가 적당하지 않습니다." + +#: pg_dump.c:6032 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "\"%s\" 함수의 소유주가 적당하지 않습니다." + +#: pg_dump.c:6860 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "\"%s\" 테이블의 소유주가 적당하지 않습니다." + +#: pg_dump.c:6902 pg_dump.c:17380 +#, c-format +msgid "" +"failed sanity check, parent table with OID %u of sequence with OID %u not " +"found" +msgstr "의존성 검사 실패, 부모 테이블 OID %u 없음. 해당 시퀀스 개체 OID %u" + +#: pg_dump.c:7044 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블에서 사용하는 인덱스들을 읽는 중" + +#: pg_dump.c:7459 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블에서 사용하는 참조키 제약조건을 읽는 중" + +#: pg_dump.c:7740 +#, c-format +msgid "" +"failed sanity check, parent table with OID %u of pg_rewrite entry with OID " +"%u not found" +msgstr "의존성 검사 실패, 부모 테이블 OID %u 없음. 해당 pg_rewrite 개체 OID %u" + +#: pg_dump.c:7823 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블에서 사용하는 트리거들을 읽는 중" + +#: pg_dump.c:7956 +#, c-format +msgid "" +"query produced null referenced table name for foreign key trigger \"%s\" on " +"table \"%s\" (OID of table: %u)" +msgstr "" +"쿼리가 참조테이블 정보가 없는 \"%s\" 참조키 트리거를 \"%s\" (해당 OID: %u) 테" +"이블에서 만들었습니다." + +#: pg_dump.c:8511 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블의 칼럼과 자료형을 찾는 중" + +#: pg_dump.c:8647 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "\"%s\" 테이블에 매겨져 있는 열 번호가 잘못되었습니다" + +#: pg_dump.c:8684 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블에서 default 표현들 찾는 중" + +#: pg_dump.c:8706 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "적당하지 않는 adnum 값: %d, 해당 테이블 \"%s\"" + +#: pg_dump.c:8771 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블에서 사용하는 체크 제약 조건을 찾는 중" + +#: pg_dump.c:8820 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "" +"%d개의 제약 조건이 \"%s\" 테이블에 있을 것으로 예상했으나 %d개를 찾음" + +#: pg_dump.c:8824 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(시스템 카탈로그가 손상되었는 것 같습니다)" + +#: pg_dump.c:10410 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "\"%s\" 자료형의 typtype가 잘못 되어 있음" + +#: pg_dump.c:11764 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "proargmodes 배열에 잘못된 값이 있음" + +#: pg_dump.c:12136 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "proallargtypes 배열을 분석할 수 없습니다" + +#: pg_dump.c:12152 +#, c-format +msgid "could not parse proargmodes array" +msgstr "proargmodes 배열을 분석할 수 없습니다" + +#: pg_dump.c:12166 +#, c-format +msgid "could not parse proargnames array" +msgstr "proargnames 배열을 분석할 수 없습니다" + +#: pg_dump.c:12177 +#, c-format +msgid "could not parse proconfig array" +msgstr "proconfig 배열을 구문 분석할 수 없음" + +#: pg_dump.c:12257 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "\"%s\" 함수의 provolatile 값이 잘못 되었습니다" + +#: pg_dump.c:12307 pg_dump.c:14365 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "\"%s\" 함수의 proparallel 값이 잘못 되었습니다" + +#: pg_dump.c:12446 pg_dump.c:12555 pg_dump.c:12562 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "%u OID 함수에 대한 함수 정의를 찾을 수 없음" + +#: pg_dump.c:12485 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "pg_cast.castfunc 또는 pg_cast.castmethod 필드에 잘못된 값이 있음" + +#: pg_dump.c:12488 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "pg_cast.castmethod 필드에 잘못된 값이 있음" + +#: pg_dump.c:12581 +#, c-format +msgid "" +"bogus transform definition, at least one of trffromsql and trftosql should " +"be nonzero" +msgstr "잘못된 전송 정의, trffromsql 또는 trftosql 중 하나는 비어 있으면 안됨" + +#: pg_dump.c:12598 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "pg_transform.trffromsql 필드에 잘못된 값이 있음" + +#: pg_dump.c:12619 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "pg_transform.trftosql 필드에 잘못된 값이 있음" + +#: pg_dump.c:12935 +#, c-format +msgid "could not find operator with OID %s" +msgstr "%s OID의 연산자를 찾을 수 없음" + +#: pg_dump.c:13003 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "\"%c\" 잘못된 자료형, 해당 접근 방법: \"%s\"" + +#: pg_dump.c:13757 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "알 수 없는 정렬규칙 제공자 이름: %s" + +#: pg_dump.c:14229 +#, c-format +msgid "" +"aggregate function %s could not be dumped correctly for this database " +"version; ignored" +msgstr "" +"%s 집계 함수는 이 데이터베이스 버전에서는 바르게 덤프되질 못했습니다; 무시함" + +#: pg_dump.c:14284 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "\"%s\" 집계 함수용 aggfinalmodify 값이 이상함" + +#: pg_dump.c:14340 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "\"%s\" 집계 함수용 aggmfinalmodify 값이 이상함" + +#: pg_dump.c:15062 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "기본 접근 권한에서 알 수 없는 객체형이 있음: %d" + +#: pg_dump.c:15080 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "기본 ACL 목록 (%s)을 분석할 수 없음" + +#: pg_dump.c:15165 +#, c-format +msgid "" +"could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) " +"for object \"%s\" (%s)" +msgstr "" +"GRANT ACL 목록 초기값 (%s) 또는 REVOKE ACL 목록 초기값 (%s) 분석할 수 없음, " +"해당 객체: \"%s\" (%s)" + +#: pg_dump.c:15173 +#, c-format +msgid "" +"could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s" +"\" (%s)" +msgstr "" +"GRANT ACL 목록 (%s) 또는 REVOKE ACL 목록 (%s) 분석할 수 없음, 해당 객체: \"%s" +"\" (%s)" + +#: pg_dump.c:15688 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "\"%s\" 뷰 정의 정보가 없습니다." + +#: pg_dump.c:15691 +#, c-format +msgid "" +"query to obtain definition of view \"%s\" returned more than one definition" +msgstr "\"%s\" 뷰 정의 정보가 하나 이상 있습니다." + +#: pg_dump.c:15698 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "\"%s\" 뷰의 정의 내용이 비어있습니다." + +#: pg_dump.c:15780 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS 옵션은 더이상 지원하지 않음 (\"%s\" 테이블)" + +#: pg_dump.c:16260 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "잘못된 부모 수: %d, 해당 테이블 \"%s\"" + +#: pg_dump.c:16583 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "잘못된 열 번호 %d, 해당 테이블 \"%s\"" + +#: pg_dump.c:16868 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "\"%s\" 제약 조건을 위한 인덱스가 빠졌습니다" + +#: pg_dump.c:17093 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "알 수 없는 제약 조건 종류: %c" + +#: pg_dump.c:17225 pg_dump.c:17445 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "" +"query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "" +"\"%s\" 시퀀스의 데이터를 가져오기 위한 쿼리에서 %d개의 행 반환(1개 필요)" + +#: pg_dump.c:17259 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "알 수 없는 시퀀스 형태: %s" + +#: pg_dump.c:17543 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "기대되지 않은 tgtype 값: %d" + +#: pg_dump.c:17617 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "잘못된 인수 문자열 (%s), 해당 트리거 \"%s\", 사용되는 테이블 \"%s\"" + +#: pg_dump.c:17853 +#, c-format +msgid "" +"query to get rule \"%s\" for table \"%s\" failed: wrong number of rows " +"returned" +msgstr "" +"\"%s\" 규칙(\"%s\" 테이블)을 가져오기 위한 쿼리 실패: 잘못된 행 수 반환" + +#: pg_dump.c:18015 +#, c-format +msgid "could not find referenced extension %u" +msgstr "%u 확장기능과 관련된 상위 확장 기능을 찾을 수 없음" + +#: pg_dump.c:18229 +#, c-format +msgid "reading dependency data" +msgstr "의존 관계 자료 읽는 중" + +#: pg_dump.c:18322 +#, c-format +msgid "no referencing object %u %u" +msgstr "%u %u 개체의 하위 관련 개체가 없음" + +#: pg_dump.c:18333 +#, c-format +msgid "no referenced object %u %u" +msgstr "%u %u 개체의 상위 관련 개체가 없음" + +#: pg_dump.c:18706 +#, c-format +msgid "could not parse reloptions array" +msgstr "reloptions 배열을 분석할 수 없음" + +#: pg_dump_sort.c:360 +#, c-format +msgid "invalid dumpId %d" +msgstr "잘못된 dumpId %d" + +#: pg_dump_sort.c:366 +#, c-format +msgid "invalid dependency %d" +msgstr "잘못된 의존성 %d" + +#: pg_dump_sort.c:599 +#, c-format +msgid "could not identify dependency loop" +msgstr "의존 관계를 식별 할 수 없음" + +#: pg_dump_sort.c:1170 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "다음 데이블 간 참조키가 서로 교차하고 있음:" + +#: pg_dump_sort.c:1174 pg_dump_sort.c:1194 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1175 +#, c-format +msgid "" +"You might not be able to restore the dump without using --disable-triggers " +"or temporarily dropping the constraints." +msgstr "" +"--disable-triggers 옵션으로 복원할 수 있습니다. 또는 임시로 제약 조건을 삭제" +"하고 복원하세요." + +#: pg_dump_sort.c:1176 +#, c-format +msgid "" +"Consider using a full dump instead of a --data-only dump to avoid this " +"problem." +msgstr "" +"이 문제를 피하려면, --data-only 덤프 대신에 모든 덤프를 사용하길 권합니다." + +#: pg_dump_sort.c:1188 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "다음 항목 간 의존 관계를 분석할 수 없음:" + +#: pg_dumpall.c:199 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"\"%s\" 프로그램이 %s 작업에서 필요로 하지만, \"%s\" 프로그램이\n" +"있는 같은 디렉터리에서 찾을 수 없습니다.\n" +"설치 상태를 살펴 보십시오." + +#: pg_dumpall.c:204 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"%s\" 프로그램이 \"%s\" 작업 때문에 찾았지만, \n" +"%s 버전과 같지 않습니다.\n" +"설치 상태를 살펴 보십시오." + +#: pg_dumpall.c:356 +#, c-format +msgid "" +"option --exclude-database cannot be used together with -g/--globals-only, -" +"r/--roles-only, or -t/--tablespaces-only" +msgstr "" +"--exclude-database 옵션은 -g/--globals-only, -r/--roles-only, 또는 -t/--" +"tablespaces-only 옵션과 함께 쓸 수 없음" + +#: pg_dumpall.c:365 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "-g/--globals-only 옵션과 -r/--roles-only 옵션은 함께 사용할 수 없음" + +#: pg_dumpall.c:373 +#, c-format +msgid "" +"options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "" +"-g/--globals-only 옵션과 -t/--tablespaces-only 옵션은 함께 사용할 수 없음" + +#: pg_dumpall.c:387 +#, c-format +msgid "" +"options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "" +"-r/--roles-only 옵션과 -t/--tablespaces-only 옵션은 함께 사용할 수 없음" + +#: pg_dumpall.c:448 pg_dumpall.c:1754 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "\"%s\" 데이터베이스에 접속할 수 없음" + +#: pg_dumpall.c:462 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"\"postgres\" 또는 \"template1\" 데이터베이스에 연결할 수 없습니다.\n" +"다른 데이터베이스를 지정하십시오." + +#: pg_dumpall.c:616 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s 프로그램은 PostgreSQL 데이터베이스 클러스터를 SQL 스크립트 파일로\n" +"추출하는 프로그램입니다.\n" +"\n" + +#: pg_dumpall.c:618 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [옵션]...\n" + +#: pg_dumpall.c:621 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=파일이름 출력 파일 이름\n" + +#: pg_dumpall.c:628 +#, c-format +msgid "" +" -c, --clean clean (drop) databases before recreating\n" +msgstr "" +" -c, --clean 다시 만들기 전에 데이터베이스 지우기(삭제)\n" + +#: pg_dumpall.c:630 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr "" +" -g, --globals-only 데이터베이스는 제외하고 글로벌 개체만 덤프\n" + +#: pg_dumpall.c:631 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner 개체 소유권 복원 건너뛰기\n" + +#: pg_dumpall.c:632 +#, c-format +msgid "" +" -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr "" +" -r, --roles-only 데이터베이스나 테이블스페이스는 제외하고 역할" +"만 덤프\n" + +#: pg_dumpall.c:634 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, --superuser=NAME 덤프에 사용할 슈퍼유저 사용자 이름\n" + +#: pg_dumpall.c:635 +#, c-format +msgid "" +" -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr "" +" -t, --tablespaces-only 데이터베이스나 역할은 제외하고 테이블스페이스" +"만 덤프\n" + +#: pg_dumpall.c:641 +#, c-format +msgid "" +" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr "" +" --exclude-database=PATTERN 해당 PATTERN에 일치하는 데이터베이스 제외\n" + +#: pg_dumpall.c:648 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords 롤용 비밀번호를 덤프하지 않음\n" + +#: pg_dumpall.c:662 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=접속문자열 서버 접속 문자열\n" + +#: pg_dumpall.c:664 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=DBNAME 대체용 기본 데이터베이스\n" + +#: pg_dumpall.c:671 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the " +"standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"-f/--file을 사용하지 않으면 SQL 스크립트가 표준\n" +"출력에 쓰여집니다.\n" +"\n" + +#: pg_dumpall.c:877 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "롤 이름이 \"pg_\"로 시작함, 무시함: (%s)" + +#: pg_dumpall.c:1278 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "테이블스페이스 용 ACL 목록 (%s)을 분석할 수 없음, 해당개체 \"%s\"" + +#: pg_dumpall.c:1495 +#, c-format +msgid "excluding database \"%s\"" +msgstr "\"%s\" 데이터베이스를 제외하는 중" + +#: pg_dumpall.c:1499 +#, c-format +msgid "dumping database \"%s\"" +msgstr "\"%s\" 데이터베이스 덤프 중" + +#: pg_dumpall.c:1531 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "\"%s\" 데이터베이스에서 pg_dump 작업 중에 오류가 발생, 끝냅니다." + +#: pg_dumpall.c:1540 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "\"%s\" 출력 파일을 다시 열 수 없음: %m" + +#: pg_dumpall.c:1584 +#, c-format +msgid "running \"%s\"" +msgstr "\"%s\" 가동중" + +#: pg_dumpall.c:1775 +#, c-format +msgid "could not connect to database \"%s\": %s" +msgstr "\"%s\" 데이터베이스에 접속할 수 없음: %s" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "서버 버전을 알 수 없음" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "\"%s\" 서버 버전을 분석할 수 없음" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "실행중: %s" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "-d/--dbname 옵션 또는 -f/--file 옵션 중 하나를 지정해야 함" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "-d/--dbname 옵션과 -f/--file 옵션은 함께 사용할 수 없음" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "-C/--clean 옵션과 -1/--single-transaction 옵션은 함께 사용할 수 없음" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "병렬 작업 최대수는 %d 입니다." + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "--single-transaction 및 병렬 작업을 함께 지정할 수는 없음" + +#: pg_restore.c:408 +#, c-format +msgid "" +"unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "" +"알 수 없는 아카이브 형식: \"%s\"; 사용할 수 있는 값: \"c\", \"d\", \"t\"" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "복원작업에서의 오류들이 무시되었음: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s 프로그램은 pg_dump로 만들어진 자료파일로 PostgreSQL 데이터베이스에\n" +"그 자료를 일괄 입력합니다.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [옵션]... [파일]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=NAME 접속할 데이터베이스 이름\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=FILENAME 출력 파일 이름 (표준 출력: -)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, --format=c|d|t 백업 파일 형식 (지정하지 않으면 자동분석)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list 자료의 요약된 목차를 보여줌\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose 자세한 정보 보여줌\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"리스토어 처리를 위한 옵션들:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only 스키마는 빼고 자료만 입력함\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create 작업 대상 데이터베이스를 만듦\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr "" +" -e, --exit-on-error 오류가 생기면 끝냄, 기본은 계속 진행함\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=NAME 지정한 인덱스 만듦\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, --jobs=NUM 여러 병렬 작업을 사용하여 복원\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=FILENAME 출력을 선택하고 해당 순서를 지정하기 위해\n" +" 이 파일의 목차 사용\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NAME 해당 스키마의 개체들만 복원함\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NAME 해당 스키마의 개체들은 복원 안함\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NAME(args) 지정한 함수 만듦\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only 자료구조(스키마)만 만듦\n" + +#: pg_restore.c:488 +#, c-format +msgid "" +" -S, --superuser=NAME superuser user name to use for disabling " +"triggers\n" +msgstr "" +" -S, --superuser=NAME 트리거를 사용하지 않기 위해 사용할 슈퍼유저\n" +" 사용자 이름\n" + +#: pg_restore.c:489 +#, c-format +msgid "" +" -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=NAME 복원할 객체 이름 (테이블, 뷰, 기타)\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=NAME 지정한 트리거 만듦\n" + +#: pg_restore.c:491 +#, c-format +msgid "" +" -x, --no-privileges skip restoration of access privileges (grant/" +"revoke)\n" +msgstr " -x, --no-privileges 접근 권한(grant/revoke) 지정 안함\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction 하나의 트랜잭션 작업으로 복원함\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security 로우 보안 활성화\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments 코멘트는 복원하지 않음\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not " +"be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables 만들 수 없는 테이블에 대해서는 자료를 덤프하" +"지 않음\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications 발행 정보는 복원 안함\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels 보안 라벨을 복원하지 않음\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions 구독 정보는 복원 안함\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces 테이블스페이스 할당을 복원하지 않음\n" + +#: pg_restore.c:503 +#, c-format +msgid "" +" --section=SECTION restore named section (pre-data, data, or " +"post-data)\n" +msgstr "" +" --section=SECTION 지정한 섹션만 복원함\n" +" 섹션 종류: pre-data, data, post-data\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROLENAME 복원 전에 SET ROLE 수행\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and " +"specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"-I, -n, -N, -P, -t, -T, --section 옵션은 그 대상이 되는 객체를 복수로 지정하" +"기\n" +"위해서 여러번 사용할 수 있습니다.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"사용할 입력 파일을 지정하지 않았다면, 표준 입력(stdin)을 사용합니다.\n" +"\n" diff --git a/src/bin/pg_dump/po/ru.po b/src/bin/pg_dump/po/ru.po new file mode 100644 index 000000000000..7235c01df17f --- /dev/null +++ b/src/bin/pg_dump/po/ru.po @@ -0,0 +1,3338 @@ +# Russian message translation file for pg_dump +# Copyright (C) 2001-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Serguei A. Mokhov , 2001-2005. +# Oleg Bartunov , 2004. +# Sergey Burladyan , 2012. +# Dmitriy Olshevskiy , 2014. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_dump (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-02-08 07:28+0300\n" +"PO-Revision-Date: 2020-11-09 08:28+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не удалось определить текущий каталог: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "неверный исполняемый файл \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "не удалось прочитать исполняемый файл \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "не удалось найти запускаемый файл \"%s\"" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не удалось перейти в каталог \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не удалось прочитать символическую ссылку \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "ошибка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "нехватка памяти" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "неисполняемая команда" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "команда не найдена" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "дочерний процесс завершился с кодом возврата %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "дочерний процесс прерван исключением 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "дочерний процесс завершён по сигналу %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "дочерний процесс завершился с нераспознанным состоянием %d" + +#: common.c:124 +#, c-format +msgid "reading extensions" +msgstr "чтение расширений" + +#: common.c:128 +#, c-format +msgid "identifying extension members" +msgstr "выявление членов расширений" + +#: common.c:131 +#, c-format +msgid "reading schemas" +msgstr "чтение схем" + +#: common.c:141 +#, c-format +msgid "reading user-defined tables" +msgstr "чтение пользовательских таблиц" + +#: common.c:148 +#, c-format +msgid "reading user-defined functions" +msgstr "чтение пользовательских функций" + +#: common.c:153 +#, c-format +msgid "reading user-defined types" +msgstr "чтение пользовательских типов" + +#: common.c:158 +#, c-format +msgid "reading procedural languages" +msgstr "чтение процедурных языков" + +#: common.c:161 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "чтение пользовательских агрегатных функций" + +#: common.c:164 +#, c-format +msgid "reading user-defined operators" +msgstr "чтение пользовательских операторов" + +#: common.c:168 +#, c-format +msgid "reading user-defined access methods" +msgstr "чтение пользовательских методов доступа" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator classes" +msgstr "чтение пользовательских классов операторов" + +#: common.c:174 +#, c-format +msgid "reading user-defined operator families" +msgstr "чтение пользовательских семейств операторов" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "чтение пользовательских анализаторов текстового поиска" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search templates" +msgstr "чтение пользовательских шаблонов текстового поиска" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "чтение пользовательских словарей текстового поиска" + +#: common.c:186 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "чтение пользовательских конфигураций текстового поиска" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "чтение пользовательских оболочек сторонних данных" + +#: common.c:192 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "чтение пользовательских сторонних серверов" + +#: common.c:195 +#, c-format +msgid "reading default privileges" +msgstr "чтение прав по умолчанию" + +#: common.c:198 +#, c-format +msgid "reading user-defined collations" +msgstr "чтение пользовательских правил сортировки" + +#: common.c:202 +#, c-format +msgid "reading user-defined conversions" +msgstr "чтение пользовательских преобразований" + +#: common.c:205 +#, c-format +msgid "reading type casts" +msgstr "чтение приведений типов" + +#: common.c:208 +#, c-format +msgid "reading transforms" +msgstr "чтение преобразований" + +#: common.c:211 +#, c-format +msgid "reading table inheritance information" +msgstr "чтение информации о наследовании таблиц" + +#: common.c:214 +#, c-format +msgid "reading event triggers" +msgstr "чтение событийных триггеров" + +#: common.c:218 +#, c-format +msgid "finding extension tables" +msgstr "поиск таблиц расширений" + +#: common.c:222 +#, c-format +msgid "finding inheritance relationships" +msgstr "поиск связей наследования" + +#: common.c:225 +#, c-format +msgid "reading column info for interesting tables" +msgstr "чтение информации о столбцах интересующих таблиц" + +#: common.c:228 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "пометка наследованных столбцов в подтаблицах" + +#: common.c:231 +#, c-format +msgid "reading indexes" +msgstr "чтение индексов" + +#: common.c:234 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "пометка индексов в секционированных таблицах" + +#: common.c:237 +#, c-format +msgid "reading extended statistics" +msgstr "чтение расширенной статистики" + +#: common.c:240 +#, c-format +msgid "reading constraints" +msgstr "чтение ограничений" + +#: common.c:243 +#, c-format +msgid "reading triggers" +msgstr "чтение триггеров" + +#: common.c:246 +#, c-format +msgid "reading rewrite rules" +msgstr "чтение правил перезаписи" + +#: common.c:249 +#, c-format +msgid "reading policies" +msgstr "чтение политик" + +#: common.c:252 +#, c-format +msgid "reading publications" +msgstr "чтение публикаций" + +#: common.c:257 +#, c-format +msgid "reading publication membership" +msgstr "чтение участников публикаций" + +#: common.c:260 +#, c-format +msgid "reading subscriptions" +msgstr "чтение подписок" + +#: common.c:1058 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "" +"нарушение целостности: родительская таблица с OID %u для таблицы \"%s\" (OID " +"%u) не найдена" + +#: common.c:1100 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "не удалось разобрать числовой массив \"%s\": слишком много чисел" + +#: common.c:1115 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "не удалось разобрать числовой массив \"%s\": неверный символ в числе" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "неверный код сжатия: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "программа собрана без поддержки zlib" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "не удалось инициализировать библиотеку сжатия: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "не удалось закрыть поток сжатых данных: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "не удалось сжать данные: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "не удалось распаковать данные: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "не удалось закрыть библиотеку сжатия: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:557 pg_backup_tar.c:560 +#, c-format +msgid "could not read from input file: %s" +msgstr "не удалось прочитать входной файл: %s" + +#: compress_io.c:623 pg_backup_custom.c:646 pg_backup_directory.c:552 +#: pg_backup_tar.c:793 pg_backup_tar.c:816 +#, c-format +msgid "could not read from input file: end of file" +msgstr "не удалось прочитать входной файл: конец файла" + +#: parallel.c:254 +#, c-format +msgid "WSAStartup failed: %d" +msgstr "ошибка WSAStartup: %d" + +#: parallel.c:964 +#, c-format +msgid "could not create communication channels: %m" +msgstr "не удалось создать каналы межпроцессного взаимодействия: %m" + +#: parallel.c:1021 +#, c-format +msgid "could not create worker process: %m" +msgstr "не удалось создать рабочий процесс: %m" + +#: parallel.c:1151 +#, c-format +msgid "unrecognized command received from master: \"%s\"" +msgstr "от ведущего получена нераспознанная команда: \"%s\"" + +#: parallel.c:1194 parallel.c:1432 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "от рабочего процесса получено ошибочное сообщение: \"%s\"" + +#: parallel.c:1326 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the " +"table after the pg_dump parent process had gotten the initial ACCESS SHARE " +"lock on the table." +msgstr "" +"не удалось получить блокировку отношения \"%s\".\n" +"Обычно это означает, что кто-то запросил блокировку ACCESS EXCLUSIVE для " +"этой таблицы после того, как родительский процесс pg_dump получил для неё " +"начальную блокировку ACCESS SHARE." + +#: parallel.c:1415 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "рабочий процесс неожиданно завершился" + +#: parallel.c:1537 parallel.c:1655 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "не удалось записать в канал взаимодействия: %m" + +#: parallel.c:1614 +#, c-format +msgid "select() failed: %m" +msgstr "ошибка в select(): %m" + +#: parallel.c:1739 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: не удалось создать сокет (код ошибки: %d)" + +#: parallel.c:1750 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: не удалось привязаться к сокету (код ошибки: %d)" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: не удалось начать приём (код ошибки: %d)" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: ошибка в getsockname() (код ошибки: %d)" + +#: parallel.c:1775 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: не удалось создать второй сокет (код ошибки: %d)" + +#: parallel.c:1784 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: не удалось подключить сокет (код ошибки: %d)" + +#: parallel.c:1793 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: не удалось принять соединение (код ошибки: %d)" + +#: pg_backup_archiver.c:277 pg_backup_archiver.c:1587 +#, c-format +msgid "could not close output file: %m" +msgstr "не удалось закрыть выходной файл: %m" + +#: pg_backup_archiver.c:321 pg_backup_archiver.c:325 +#, c-format +msgid "archive items not in correct section order" +msgstr "в последовательности элементов архива нарушен порядок разделов" + +#: pg_backup_archiver.c:331 +#, c-format +msgid "unexpected section code %d" +msgstr "неожиданный код раздела %d" + +#: pg_backup_archiver.c:368 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "" +"параллельное восстановление не поддерживается с выбранным форматом архивного " +"файла" + +#: pg_backup_archiver.c:372 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "" +"параллельное восстановление возможно только для архивов, созданных pg_dump " +"версии 8.0 и новее" + +#: pg_backup_archiver.c:390 +#, c-format +msgid "" +"cannot restore from compressed archive (compression not supported in this " +"installation)" +msgstr "" +"восстановить данные из сжатого архива нельзя (установленная версия не " +"поддерживает сжатие)" + +#: pg_backup_archiver.c:407 +#, c-format +msgid "connecting to database for restore" +msgstr "подключение к базе данных для восстановления" + +#: pg_backup_archiver.c:409 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "" +"прямые подключения к базе данных не поддерживаются в архивах до версии 1.3" + +#: pg_backup_archiver.c:452 +#, c-format +msgid "implied data-only restore" +msgstr "подразумевается восстановление только данных" + +#: pg_backup_archiver.c:518 +#, c-format +msgid "dropping %s %s" +msgstr "удаляется %s %s" + +#: pg_backup_archiver.c:613 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "не удалось определить, куда добавить IF EXISTS в оператор \"%s\"" + +#: pg_backup_archiver.c:769 pg_backup_archiver.c:771 +#, c-format +msgid "warning from original dump file: %s" +msgstr "предупреждение из исходного файла: %s" + +#: pg_backup_archiver.c:786 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "создаётся %s \"%s.%s\"" + +#: pg_backup_archiver.c:789 +#, c-format +msgid "creating %s \"%s\"" +msgstr "создаётся %s \"%s\"" + +#: pg_backup_archiver.c:839 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "подключение к новой базе данных \"%s\"" + +#: pg_backup_archiver.c:866 +#, c-format +msgid "processing %s" +msgstr "обрабатывается %s" + +#: pg_backup_archiver.c:886 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "обрабатываются данные таблицы \"%s.%s\"" + +#: pg_backup_archiver.c:948 +#, c-format +msgid "executing %s %s" +msgstr "выполняется %s %s" + +#: pg_backup_archiver.c:987 +#, c-format +msgid "disabling triggers for %s" +msgstr "отключаются триггеры таблицы %s" + +#: pg_backup_archiver.c:1013 +#, c-format +msgid "enabling triggers for %s" +msgstr "включаются триггеры таблицы %s" + +#: pg_backup_archiver.c:1041 +#, c-format +msgid "" +"internal error -- WriteData cannot be called outside the context of a " +"DataDumper routine" +msgstr "" +"внутренняя ошибка -- WriteData нельзя вызывать вне контекста процедуры " +"DataDumper" + +#: pg_backup_archiver.c:1224 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "выбранный формат не поддерживает выгрузку больших объектов" + +#: pg_backup_archiver.c:1282 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "восстановлен %d большой объект" +msgstr[1] "восстановлено %d больших объекта" +msgstr[2] "восстановлено %d больших объектов" + +#: pg_backup_archiver.c:1303 pg_backup_tar.c:736 +#, c-format +msgid "restoring large object with OID %u" +msgstr "восстановление большого объекта с OID %u" + +#: pg_backup_archiver.c:1315 +#, c-format +msgid "could not create large object %u: %s" +msgstr "не удалось создать большой объект %u: %s" + +#: pg_backup_archiver.c:1320 pg_dump.c:3552 +#, c-format +msgid "could not open large object %u: %s" +msgstr "не удалось открыть большой объект %u: %s" + +#: pg_backup_archiver.c:1377 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "не удалось открыть файл оглавления \"%s\": %m" + +#: pg_backup_archiver.c:1417 +#, c-format +msgid "line ignored: %s" +msgstr "строка проигнорирована: %s" + +#: pg_backup_archiver.c:1424 +#, c-format +msgid "could not find entry for ID %d" +msgstr "не найдена запись для ID %d" + +#: pg_backup_archiver.c:1445 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "не удалось закрыть файл оглавления: %m" + +#: pg_backup_archiver.c:1559 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:484 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "не удалось открыть выходной файл \"%s\": %m" + +#: pg_backup_archiver.c:1561 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "не удалось открыть выходной файл: %m" + +#: pg_backup_archiver.c:1654 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "записан %lu байт данных большого объекта (результат = %lu)" +msgstr[1] "записано %lu байта данных большого объекта (результат = %lu)" +msgstr[2] "записано %lu байт данных большого объекта (результат = %lu)" + +#: pg_backup_archiver.c:1659 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "не удалось записать большой объект (результат: %lu, ожидалось: %lu)" + +#: pg_backup_archiver.c:1749 +#, c-format +msgid "while INITIALIZING:" +msgstr "при инициализации:" + +#: pg_backup_archiver.c:1754 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "при обработке оглавления:" + +#: pg_backup_archiver.c:1759 +#, c-format +msgid "while FINALIZING:" +msgstr "при завершении:" + +#: pg_backup_archiver.c:1764 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "из записи оглавления %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1840 +#, c-format +msgid "bad dumpId" +msgstr "неверный dumpId" + +#: pg_backup_archiver.c:1861 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "неверный dumpId таблицы в элементе TABLE DATA" + +#: pg_backup_archiver.c:1953 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "неожиданный флаг смещения данных: %d" + +#: pg_backup_archiver.c:1966 +#, c-format +msgid "file offset in dump file is too large" +msgstr "слишком большое смещение в файле выгрузки" + +#: pg_backup_archiver.c:2103 pg_backup_archiver.c:2113 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "слишком длинное имя каталога: \"%s\"" + +#: pg_backup_archiver.c:2121 +#, c-format +msgid "" +"directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not " +"exist)" +msgstr "каталог \"%s\" не похож на архивный (в нём отсутствует \"toc.dat\")" + +#: pg_backup_archiver.c:2129 pg_backup_custom.c:173 pg_backup_custom.c:812 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "не удалось открыть входной файл \"%s\": %m" + +#: pg_backup_archiver.c:2136 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "не удалось открыть входной файл: %m" + +#: pg_backup_archiver.c:2142 +#, c-format +msgid "could not read input file: %m" +msgstr "не удалось прочитать входной файл: %m" + +#: pg_backup_archiver.c:2144 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "входной файл слишком короткий (прочитано байт: %lu, ожидалось: 5)" + +#: pg_backup_archiver.c:2229 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "" +"входной файл, видимо, имеет текстовый формат. Загрузите его с помощью psql." + +#: pg_backup_archiver.c:2235 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "входной файл не похож на архив (возможно, слишком мал?)" + +#: pg_backup_archiver.c:2241 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "входной файл не похож на архив" + +#: pg_backup_archiver.c:2261 +#, c-format +msgid "could not close input file: %m" +msgstr "не удалось закрыть входной файл: %m" + +#: pg_backup_archiver.c:2373 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "неопознанный формат файла: \"%d\"" + +#: pg_backup_archiver.c:2455 pg_backup_archiver.c:4458 +#, c-format +msgid "finished item %d %s %s" +msgstr "закончен объект %d %s %s" + +#: pg_backup_archiver.c:2459 pg_backup_archiver.c:4471 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "рабочий процесс завершился с кодом возврата %d" + +#: pg_backup_archiver.c:2579 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "ID записи %d вне диапазона - возможно повреждено оглавление" + +#: pg_backup_archiver.c:2646 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "восстановление таблиц со свойством WITH OIDS больше не поддерживается" + +#: pg_backup_archiver.c:2728 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "нераспознанная кодировка \"%s\"" + +#: pg_backup_archiver.c:2733 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "неверный элемент ENCODING: %s" + +#: pg_backup_archiver.c:2751 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "неверный элемент STDSTRINGS: %s" + +#: pg_backup_archiver.c:2776 +#, c-format +msgid "schema \"%s\" not found" +msgstr "схема \"%s\" не найдена" + +#: pg_backup_archiver.c:2783 +#, c-format +msgid "table \"%s\" not found" +msgstr "таблица \"%s\" не найдена" + +#: pg_backup_archiver.c:2790 +#, c-format +msgid "index \"%s\" not found" +msgstr "индекс \"%s\" не найден" + +#: pg_backup_archiver.c:2797 +#, c-format +msgid "function \"%s\" not found" +msgstr "функция \"%s\" не найдена" + +#: pg_backup_archiver.c:2804 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "триггер \"%s\" не найден" + +#: pg_backup_archiver.c:3196 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "не удалось переключить пользователя сессии на \"%s\": %s" + +#: pg_backup_archiver.c:3328 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "не удалось присвоить search_path значение \"%s\": %s" + +#: pg_backup_archiver.c:3390 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "не удалось задать для default_tablespace значение %s: %s" + +#: pg_backup_archiver.c:3435 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "не удалось задать default_table_access_method: %s" + +#: pg_backup_archiver.c:3527 pg_backup_archiver.c:3685 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "неизвестно, как назначить владельца для объекта типа \"%s\"" + +#: pg_backup_archiver.c:3789 +#, c-format +msgid "did not find magic string in file header" +msgstr "в заголовке файла не найдена нужная сигнатура" + +#: pg_backup_archiver.c:3802 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "неподдерживаемая версия (%d.%d) в заголовке файла" + +#: pg_backup_archiver.c:3807 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "несоответствие размера integer (%lu)" + +#: pg_backup_archiver.c:3811 +#, c-format +msgid "" +"archive was made on a machine with larger integers, some operations might " +"fail" +msgstr "" +"архив был сделан на компьютере большей разрядности -- возможен сбой " +"некоторых операций" + +#: pg_backup_archiver.c:3821 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "ожидаемый формат (%d) отличается от формата, указанного в файле (%d)" + +#: pg_backup_archiver.c:3837 +#, c-format +msgid "" +"archive is compressed, but this installation does not support compression -- " +"no data will be available" +msgstr "" +"архив сжат, но установленная версия не поддерживает сжатие -- данные " +"недоступны" + +#: pg_backup_archiver.c:3855 +#, c-format +msgid "invalid creation date in header" +msgstr "неверная дата создания в заголовке" + +#: pg_backup_archiver.c:3983 +#, c-format +msgid "processing item %d %s %s" +msgstr "обработка объекта %d %s %s" + +#: pg_backup_archiver.c:4062 +#, c-format +msgid "entering main parallel loop" +msgstr "вход в основной параллельный цикл" + +#: pg_backup_archiver.c:4073 +#, c-format +msgid "skipping item %d %s %s" +msgstr "объект %d %s %s пропускается" + +#: pg_backup_archiver.c:4082 +#, c-format +msgid "launching item %d %s %s" +msgstr "объект %d %s %s запускается" + +#: pg_backup_archiver.c:4136 +#, c-format +msgid "finished main parallel loop" +msgstr "основной параллельный цикл закончен" + +#: pg_backup_archiver.c:4172 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "обработка пропущенного объекта %d %s %s" + +#: pg_backup_archiver.c:4777 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "создать таблицу \"%s\" не удалось, её данные не будут восстановлены" + +#: pg_backup_custom.c:378 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "неверный OID большого объекта" + +#: pg_backup_custom.c:441 pg_backup_custom.c:507 pg_backup_custom.c:632 +#: pg_backup_custom.c:870 pg_backup_tar.c:1086 pg_backup_tar.c:1091 +#, c-format +msgid "error during file seek: %m" +msgstr "ошибка при перемещении в файле: %m" + +#: pg_backup_custom.c:480 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "в блоке данных %d задана неверная позиция" + +#: pg_backup_custom.c:497 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "нераспознанный тип блока данных (%d) при поиске архива" + +#: pg_backup_custom.c:519 +#, c-format +msgid "" +"could not find block ID %d in archive -- possibly due to out-of-order " +"restore request, which cannot be handled due to non-seekable input file" +msgstr "" +"не удалось найти в архиве блок с ID %d -- возможно, по причине не " +"последовательного запроса восстановления, который нельзя обработать с " +"файлом, не допускающим произвольный доступ" + +#: pg_backup_custom.c:524 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "не удалось найти в архиве блок с ID %d -- возможно, архив испорчен" + +#: pg_backup_custom.c:531 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "при чтении данных получен неожиданный ID блока (%d) -- ожидался: %d" + +#: pg_backup_custom.c:545 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "нераспознанный тип блока данных %d при восстановлении архива" + +#: pg_backup_custom.c:648 +#, c-format +msgid "could not read from input file: %m" +msgstr "не удалось прочитать входной файл: %m" + +#: pg_backup_custom.c:751 pg_backup_custom.c:803 pg_backup_custom.c:948 +#: pg_backup_tar.c:1089 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "не удалось определить позицию в файле архива: %m" + +#: pg_backup_custom.c:767 pg_backup_custom.c:807 +#, c-format +msgid "could not close archive file: %m" +msgstr "не удалось закрыть файл архива: %m" + +#: pg_backup_custom.c:790 +#, c-format +msgid "can only reopen input archives" +msgstr "повторно открыть можно только входные файлы" + +#: pg_backup_custom.c:797 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "параллельное восстановление из стандартного ввода не поддерживается" + +#: pg_backup_custom.c:799 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "" +"параллельное восстановление возможно только с файлом произвольного доступа" + +#: pg_backup_custom.c:815 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "не удалось задать текущую позицию в файле архива: %m" + +#: pg_backup_custom.c:894 +#, c-format +msgid "compressor active" +msgstr "сжатие активно" + +#: pg_backup_db.c:41 +#, c-format +msgid "could not get server_version from libpq" +msgstr "не удалось получить версию сервера из libpq" + +#: pg_backup_db.c:52 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "версия сервера: %s; версия %s: %s" + +#: pg_backup_db.c:54 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "продолжение работы с другой версией сервера невозможно" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "подключение к базе данных уже установлено" + +#: pg_backup_db.c:133 pg_backup_db.c:185 pg_dumpall.c:1651 pg_dumpall.c:1764 +msgid "Password: " +msgstr "Пароль: " + +#: pg_backup_db.c:177 +#, c-format +msgid "could not connect to database" +msgstr "не удалось переподключиться к базе" + +#: pg_backup_db.c:195 +#, c-format +msgid "reconnection to database \"%s\" failed: %s" +msgstr "не удалось переподключиться к базе \"%s\": %s" + +#: pg_backup_db.c:199 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "не удалось подключиться к базе \"%s\": %s" + +#: pg_backup_db.c:272 pg_dumpall.c:1684 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:279 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "ошибка при выполнении запроса: %s" + +#: pg_backup_db.c:281 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "запрос: %s" + +#: pg_backup_db.c:322 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "запрос вернул %d строку вместо одной: %s" +msgstr[1] "запрос вернул %d строки вместо одной: %s" +msgstr[2] "запрос вернул %d строк вместо одной: %s" + +# skip-rule: language-mix +#: pg_backup_db.c:358 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %sВыполнялась команда: %s" + +#: pg_backup_db.c:414 pg_backup_db.c:488 pg_backup_db.c:495 +msgid "could not execute query" +msgstr "не удалось выполнить запрос" + +#: pg_backup_db.c:467 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "ошибка в PQputCopyData: %s" + +#: pg_backup_db.c:516 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "ошибка в PQputCopyEnd: %s" + +#: pg_backup_db.c:522 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "сбой команды COPY для таблицы \"%s\": %s" + +#: pg_backup_db.c:528 pg_dump.c:1988 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "неожиданные лишние результаты получены при COPY для таблицы \"%s\"" + +#: pg_backup_db.c:540 +msgid "could not start database transaction" +msgstr "не удаётся начать транзакцию" + +#: pg_backup_db.c:548 +msgid "could not commit database transaction" +msgstr "не удалось зафиксировать транзакцию" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "выходной каталог не указан" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не удалось прочитать каталог \"%s\": %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не удалось закрыть каталог \"%s\": %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "создать каталог \"%s\" не удалось: %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "не удалось записать в выходной файл: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "не удалось закрыть файл данных \"%s\": %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "" +"не удалось открыть для чтения файл оглавления больших объектов \"%s\": %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "неверная строка в файле оглавления больших объектов \"%s\": \"%s\"" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "ошибка чтения файла оглавления больших объектов \"%s\"" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "не удалось закрыть файл оглавления больших объектов \"%s\": %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "не удалось записать в файл оглавления больших объектов" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "слишком длинное имя файла: \"%s\"" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "этот формат нельзя прочитать" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "не удалось открыть для записи файл оглавления \"%s\": %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "не удалось открыть для записи файл оглавления: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:358 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "формат архива tar не поддерживает сжатие" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "не удалось открыть для чтения файл оглавления \"%s\": %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "не удалось открыть для чтения файл оглавления: %m" + +#: pg_backup_tar.c:344 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "не удалось найти файл \"%s\" в архиве" + +#: pg_backup_tar.c:410 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "не удалось получить имя для временного файла: %m" + +#: pg_backup_tar.c:421 +#, c-format +msgid "could not open temporary file" +msgstr "не удалось открыть временный файл" + +#: pg_backup_tar.c:448 +#, c-format +msgid "could not close tar member" +msgstr "не удалось закрыть компонент tar-архива" + +#: pg_backup_tar.c:691 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "недопустимый синтаксис оператора COPY: \"%s\"" + +#: pg_backup_tar.c:958 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "неверный OID для большого объекта (%u)" + +#: pg_backup_tar.c:1105 +#, c-format +msgid "could not close temporary file: %m" +msgstr "не удалось закрыть временный файл: %m" + +#: pg_backup_tar.c:1114 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "действительная длина файла (%s) не равна ожидаемой (%s)" + +#: pg_backup_tar.c:1171 pg_backup_tar.c:1201 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "в архиве tar не найден заголовок для файла \"%s\"" + +#: pg_backup_tar.c:1189 +#, c-format +msgid "" +"restoring data out of order is not supported in this archive format: \"%s\" " +"is required, but comes before \"%s\" in the archive file." +msgstr "" +"непоследовательное восстановление данных для данного формата архива не " +"поддерживается: требуется компонент \"%s\", но в файле архива прежде идёт " +"\"%s\"." + +#: pg_backup_tar.c:1234 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "найден неполный заголовок tar (размер %lu байт)" +msgstr[1] "найден неполный заголовок tar (размер %lu байта)" +msgstr[2] "найден неполный заголовок tar (размер %lu байт)" + +#: pg_backup_tar.c:1285 +#, c-format +msgid "" +"corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "" +"заголовок tar в %s повреждён (ожидалось: %d, получено: %d), позиция в файле: " +"%s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "нераспознанное имя раздела: \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:607 pg_dump.c:624 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "превышен предел обработчиков штатного выхода" + +#: pg_dump.c:533 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "уровень сжатия должен быть в диапазоне 0..9" + +#: pg_dump.c:571 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "значение extra_float_digits должно быть в диапазоне -15..3" + +#: pg_dump.c:594 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "значение rows-per-insert должно быть в диапазоне %d..%d" + +#: pg_dump.c:622 pg_dumpall.c:346 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: pg_dump.c:643 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "параметры -s/--schema-only и -a/--data-only исключают друг друга" + +#: pg_dump.c:648 +#, c-format +msgid "" +"options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "" +"параметры -s/--schema-only и --include-foreign-data исключают друг друга" + +#: pg_dump.c:651 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "" +"параметр --include-foreign-data не поддерживается при копировании в " +"параллельном режиме" + +#: pg_dump.c:655 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "параметры -c/--clean и -a/--data-only исключают друг друга" + +#: pg_dump.c:660 pg_dumpall.c:381 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "параметр --if-exists требует указания -c/--clean" + +#: pg_dump.c:667 +#, c-format +msgid "" +"option --on-conflict-do-nothing requires option --inserts, --rows-per-" +"insert, or --column-inserts" +msgstr "" +"параметр --on-conflict-do-nothing требует указания --inserts, --rows-per-" +"insert или --column-inserts" + +#: pg_dump.c:689 +#, c-format +msgid "" +"requested compression not available in this installation -- archive will be " +"uncompressed" +msgstr "" +"установленная версия программы не поддерживает сжатие -- архив не будет " +"сжиматься" + +#: pg_dump.c:710 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "неверное число параллельных заданий" + +#: pg_dump.c:714 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "" +"параллельное резервное копирование поддерживается только с форматом \"каталог" +"\"" + +#: pg_dump.c:769 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"В этой версии сервера синхронизированные снимки не поддерживаются.\n" +"Если они вам не нужны, укажите при запуске ключ\n" +"--no-synchronized-snapshots." + +#: pg_dump.c:775 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Экспортированные снимки не поддерживаются этой версией сервера." + +#: pg_dump.c:787 +#, c-format +msgid "last built-in OID is %u" +msgstr "последний системный OID: %u" + +#: pg_dump.c:796 +#, c-format +msgid "no matching schemas were found" +msgstr "соответствующие схемы не найдены" + +#: pg_dump.c:810 +#, c-format +msgid "no matching tables were found" +msgstr "соответствующие таблицы не найдены" + +#: pg_dump.c:990 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s сохраняет резервную копию БД в текстовом файле или другом виде.\n" +"\n" + +#: pg_dump.c:991 pg_dumpall.c:617 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: pg_dump.c:992 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [ПАРАМЕТР]... [ИМЯ_БД]\n" + +#: pg_dump.c:994 pg_dumpall.c:620 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Общие параметры:\n" + +#: pg_dump.c:995 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=ИМЯ имя выходного файла или каталога\n" + +#: pg_dump.c:996 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p формат выводимых данных\n" +" (пользовательский | каталог | tar |\n" +" текстовый (по умолчанию))\n" + +#: pg_dump.c:998 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr "" +" -j, --jobs=ЧИСЛО распараллелить копирование на указанное " +"число\n" +" заданий\n" + +#: pg_dump.c:999 pg_dumpall.c:622 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose режим подробных сообщений\n" + +#: pg_dump.c:1000 pg_dumpall.c:623 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_dump.c:1001 +#, c-format +msgid "" +" -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 уровень сжатия при архивации\n" + +#: pg_dump.c:1002 pg_dumpall.c:624 +#, c-format +msgid "" +" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr "" +" --lock-wait-timeout=ТАЙМ-АУТ прервать операцию при тайм-ауте блокировки " +"таблицы\n" + +#: pg_dump.c:1003 pg_dumpall.c:651 +#, c-format +msgid "" +" --no-sync do not wait for changes to be written safely " +"to disk\n" +msgstr "" +" --no-sync не ждать надёжного сохранения изменений на " +"диске\n" + +#: pg_dump.c:1004 pg_dumpall.c:625 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_dump.c:1006 pg_dumpall.c:626 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Параметры, управляющие выводом:\n" + +#: pg_dump.c:1007 pg_dumpall.c:627 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only выгрузить только данные, без схемы\n" + +#: pg_dump.c:1008 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs выгрузить также большие объекты\n" + +#: pg_dump.c:1009 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs исключить из выгрузки большие объекты\n" + +#: pg_dump.c:1010 pg_restore.c:476 +#, c-format +msgid "" +" -c, --clean clean (drop) database objects before " +"recreating\n" +msgstr "" +" -c, --clean очистить (удалить) объекты БД при " +"восстановлении\n" + +#: pg_dump.c:1011 +#, c-format +msgid "" +" -C, --create include commands to create database in dump\n" +msgstr "" +" -C, --create добавить в копию команды создания базы " +"данных\n" + +#: pg_dump.c:1012 pg_dumpall.c:629 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=КОДИРОВКА выгружать данные в заданной кодировке\n" + +#: pg_dump.c:1013 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=ШАБЛОН выгрузить только указанную схему(ы)\n" + +#: pg_dump.c:1014 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=ШАБЛОН НЕ выгружать указанную схему(ы)\n" + +#: pg_dump.c:1015 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner не восстанавливать владение объектами\n" +" при использовании текстового формата\n" + +#: pg_dump.c:1017 pg_dumpall.c:633 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only выгрузить только схему, без данных\n" + +#: pg_dump.c:1018 +#, c-format +msgid "" +" -S, --superuser=NAME superuser user name to use in plain-text " +"format\n" +msgstr "" +" -S, --superuser=ИМЯ имя пользователя, который будет задействован\n" +" при восстановлении из текстового формата\n" + +#: pg_dump.c:1019 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=ШАБЛОН выгрузить только указанную таблицу(ы)\n" + +#: pg_dump.c:1020 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=ШАБЛОН НЕ выгружать указанную таблицу(ы)\n" + +#: pg_dump.c:1021 pg_dumpall.c:636 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges не выгружать права (назначение/отзыв)\n" + +#: pg_dump.c:1022 pg_dumpall.c:637 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade только для утилит обновления БД\n" + +#: pg_dump.c:1023 pg_dumpall.c:638 +#, c-format +msgid "" +" --column-inserts dump data as INSERT commands with column " +"names\n" +msgstr "" +" --column-inserts выгружать данные в виде INSERT с именами " +"столбцов\n" + +#: pg_dump.c:1024 pg_dumpall.c:639 +#, c-format +msgid "" +" --disable-dollar-quoting disable dollar quoting, use SQL standard " +"quoting\n" +msgstr "" +" --disable-dollar-quoting отключить спецстроки с $, выводить строки\n" +" по стандарту SQL\n" + +#: pg_dump.c:1025 pg_dumpall.c:640 pg_restore.c:493 +#, c-format +msgid "" +" --disable-triggers disable triggers during data-only restore\n" +msgstr "" +" --disable-triggers отключить триггеры при восстановлении\n" +" только данных, без схемы\n" + +#: pg_dump.c:1026 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user " +"has\n" +" access to)\n" +msgstr "" +" --enable-row-security включить защиту на уровне строк (выгружать " +"только\n" +" те данные, которые доступны пользователю)\n" + +#: pg_dump.c:1028 +#, c-format +msgid "" +" --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr "" +" --exclude-table-data=ШАБЛОН НЕ выгружать данные указанной таблицы " +"(таблиц)\n" + +#: pg_dump.c:1029 pg_dumpall.c:642 +#, c-format +msgid "" +" --extra-float-digits=NUM override default setting for " +"extra_float_digits\n" +msgstr "" +" --extra-float-digits=ЧИСЛО переопределить значение extra_float_digits\n" + +#: pg_dump.c:1030 pg_dumpall.c:643 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr "" +" --if-exists применять IF EXISTS при удалении объектов\n" + +#: pg_dump.c:1031 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=ШАБЛОН\n" +" включать в копию данные сторонних таблиц с\n" +" серверов с именами, подпадающими под ШАБЛОН\n" + +#: pg_dump.c:1034 pg_dumpall.c:644 +#, c-format +msgid "" +" --inserts dump data as INSERT commands, rather than " +"COPY\n" +msgstr "" +" --inserts выгрузить данные в виде команд INSERT, не " +"COPY\n" + +#: pg_dump.c:1035 pg_dumpall.c:645 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr "" +" --load-via-partition-root загружать секции через главную таблицу\n" + +#: pg_dump.c:1036 pg_dumpall.c:646 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments не выгружать комментарии\n" + +#: pg_dump.c:1037 pg_dumpall.c:647 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications не выгружать публикации\n" + +#: pg_dump.c:1038 pg_dumpall.c:649 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr "" +" --no-security-labels не выгружать назначения меток безопасности\n" + +#: pg_dump.c:1039 pg_dumpall.c:650 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions не выгружать подписки\n" + +#: pg_dump.c:1040 +#, c-format +msgid "" +" --no-synchronized-snapshots do not use synchronized snapshots in parallel " +"jobs\n" +msgstr "" +" --no-synchronized-snapshots не использовать синхронизированные снимки\n" +" в параллельных заданиях\n" + +#: pg_dump.c:1041 pg_dumpall.c:652 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr "" +" --no-tablespaces не выгружать назначения табличных " +"пространств\n" + +#: pg_dump.c:1042 pg_dumpall.c:653 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr "" +" --no-unlogged-table-data не выгружать данные нежурналируемых таблиц\n" + +#: pg_dump.c:1043 pg_dumpall.c:654 +#, c-format +msgid "" +" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT " +"commands\n" +msgstr "" +" --on-conflict-do-nothing добавлять ON CONFLICT DO NOTHING в команды " +"INSERT\n" + +#: pg_dump.c:1044 pg_dumpall.c:655 +#, c-format +msgid "" +" --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr "" +" --quote-all-identifiers заключать в кавычки все идентификаторы,\n" +" а не только ключевые слова\n" + +#: pg_dump.c:1045 pg_dumpall.c:656 +#, c-format +msgid "" +" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr "" +" --rows-per-insert=ЧИСЛО число строк в одном INSERT; подразумевает --" +"inserts\n" + +#: pg_dump.c:1046 +#, c-format +msgid "" +" --section=SECTION dump named section (pre-data, data, or post-" +"data)\n" +msgstr "" +" --section=РАЗДЕЛ выгрузить заданный раздел\n" +" (pre-data, data или post-data)\n" + +#: pg_dump.c:1047 +#, c-format +msgid "" +" --serializable-deferrable wait until the dump can run without " +"anomalies\n" +msgstr "" +" --serializable-deferrable дождаться момента для выгрузки данных без " +"аномалий\n" + +#: pg_dump.c:1048 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr "" +" --snapshot=СНИМОК использовать при выгрузке заданный снимок\n" + +#: pg_dump.c:1049 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns " +"to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names требовать, чтобы при указании шаблона " +"включения\n" +" таблицы и/или схемы ему соответствовал " +"минимум\n" +" один объект\n" + +#: pg_dump.c:1051 pg_dumpall.c:657 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands " +"instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" устанавливать владельца, используя команды\n" +" SET SESSION AUTHORIZATION вместо ALTER OWNER\n" + +#: pg_dump.c:1055 pg_dumpall.c:661 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Параметры подключения:\n" + +#: pg_dump.c:1056 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=БД имя базы данных для выгрузки\n" + +#: pg_dump.c:1057 pg_dumpall.c:663 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr "" +" -h, --host=ИМЯ имя сервера баз данных или каталог сокетов\n" + +#: pg_dump.c:1058 pg_dumpall.c:665 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=ПОРТ номер порта сервера БД\n" + +#: pg_dump.c:1059 pg_dumpall.c:666 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=ИМЯ имя пользователя баз данных\n" + +#: pg_dump.c:1060 pg_dumpall.c:667 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password не запрашивать пароль\n" + +#: pg_dump.c:1061 pg_dumpall.c:668 pg_restore.c:515 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr "" +" -W, --password запрашивать пароль всегда (обычно не требуется)\n" + +#: pg_dump.c:1062 pg_dumpall.c:669 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ИМЯ_РОЛИ выполнить SET ROLE перед выгрузкой\n" + +#: pg_dump.c:1064 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Если имя базы данных не указано, используется переменная окружения " +"PGDATABASE.\n" +"\n" + +#: pg_dump.c:1066 pg_dumpall.c:673 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_dump.c:1067 pg_dumpall.c:674 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_dump.c:1086 pg_dumpall.c:499 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "указана неверная клиентская кодировка \"%s\"" + +#: pg_dump.c:1232 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server " +"version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"В этой версии сервера синхронизированные снимки на ведомых серверах не " +"поддерживаются.\n" +"Если они вам не нужны, укажите при запуске ключ\n" +"--no-synchronized-snapshots." + +#: pg_dump.c:1301 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "указан неверный формат вывода: \"%s\"" + +#: pg_dump.c:1339 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "схемы, соответствующие шаблону \"%s\", не найдены" + +#: pg_dump.c:1386 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "сторонние серверы, соответствующие шаблону \"%s\", не найдены" + +#: pg_dump.c:1449 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "таблицы, соответствующие шаблону \"%s\", не найдены" + +#: pg_dump.c:1862 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "выгрузка содержимого таблицы \"%s.%s\"" + +#: pg_dump.c:1969 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Ошибка выгрузки таблицы \"%s\": сбой в PQgetCopyData()." + +#: pg_dump.c:1970 pg_dump.c:1980 +#, c-format +msgid "Error message from server: %s" +msgstr "Сообщение об ошибке с сервера: %s" + +#: pg_dump.c:1971 pg_dump.c:1981 +#, c-format +msgid "The command was: %s" +msgstr "Выполнялась команда: %s" + +#: pg_dump.c:1979 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Ошибка выгрузки таблицы \"%s\": сбой в PQgetResult()." + +#: pg_dump.c:2739 +#, c-format +msgid "saving database definition" +msgstr "сохранение определения базы данных" + +#: pg_dump.c:3211 +#, c-format +msgid "saving encoding = %s" +msgstr "сохранение кодировки (%s)" + +#: pg_dump.c:3236 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "сохранение standard_conforming_strings (%s)" + +#: pg_dump.c:3275 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "не удалось разобрать результат current_schemas()" + +#: pg_dump.c:3294 +#, c-format +msgid "saving search_path = %s" +msgstr "сохранение search_path (%s)" + +#: pg_dump.c:3334 +#, c-format +msgid "reading large objects" +msgstr "чтение больших объектов" + +#: pg_dump.c:3516 +#, c-format +msgid "saving large objects" +msgstr "сохранение больших объектов" + +#: pg_dump.c:3562 +#, c-format +msgid "error reading large object %u: %s" +msgstr "ошибка чтения большого объекта %u: %s" + +#: pg_dump.c:3614 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "чтение информации о защите строк для таблицы \"%s.%s\"" + +#: pg_dump.c:3645 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "чтение политик таблицы \"%s.%s\"" + +#: pg_dump.c:3797 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "нераспознанный тип команды в политике: %c" + +#: pg_dump.c:3951 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "у публикации \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:4241 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "" +"подписки не выгружены, так как текущий пользователь не суперпользователь" + +#: pg_dump.c:4295 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "у подписки \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:4339 +#, c-format +msgid "could not parse subpublications array" +msgstr "не удалось разобрать массив subpublications" + +#: pg_dump.c:4661 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "не удалось найти родительское расширение для %s %s" + +# TO REVIEW +#: pg_dump.c:4793 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "у схемы \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:4816 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "схема с OID %u не существует" + +#: pg_dump.c:5141 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "у типа данных \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:5226 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "у оператора \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:5528 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "у класса операторов \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:5612 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "у семейства операторов \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:5781 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "у агрегатной функции \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:6041 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "у функции \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:6869 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "у таблицы \"%s\" по-видимому неправильный владелец" + +#: pg_dump.c:6911 pg_dump.c:17426 +#, c-format +msgid "" +"failed sanity check, parent table with OID %u of sequence with OID %u not " +"found" +msgstr "" +"нарушение целостности: по OID %u не удалось найти родительскую таблицу " +"последовательности с OID %u" + +#: pg_dump.c:7053 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "чтение индексов таблицы \"%s.%s\"" + +#: pg_dump.c:7468 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "чтение ограничений внешних ключей таблицы \"%s.%s\"" + +#: pg_dump.c:7749 +#, c-format +msgid "" +"failed sanity check, parent table with OID %u of pg_rewrite entry with OID " +"%u not found" +msgstr "" +"нарушение целостности: по OID %u не удалось найти родительскую таблицу для " +"записи pg_rewrite с OID %u" + +#: pg_dump.c:7832 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "чтение триггеров таблицы \"%s.%s\"" + +#: pg_dump.c:7965 +#, c-format +msgid "" +"query produced null referenced table name for foreign key trigger \"%s\" on " +"table \"%s\" (OID of table: %u)" +msgstr "" +"запрос вернул NULL вместо имени целевой таблицы для триггера внешнего ключа " +"\"%s\" в таблице \"%s\" (OID таблицы: %u)" + +#: pg_dump.c:8520 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "поиск столбцов и типов таблицы \"%s.%s\"" + +#: pg_dump.c:8656 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "неверная нумерация столбцов в таблице \"%s\"" + +#: pg_dump.c:8693 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "поиск выражений по умолчанию для таблицы \"%s.%s\"" + +#: pg_dump.c:8715 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "неверное значение adnum (%d) в таблице \"%s\"" + +#: pg_dump.c:8807 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "поиск ограничений-проверок для таблицы \"%s.%s\"" + +#: pg_dump.c:8856 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "" +"ожидалось %d ограничение-проверка для таблицы \"%s\", но найдено: %d" +msgstr[1] "" +"ожидалось %d ограничения-проверки для таблицы \"%s\", но найдено: %d" +msgstr[2] "" +"ожидалось %d ограничений-проверок для таблицы \"%s\", но найдено: %d" + +#: pg_dump.c:8860 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Возможно, повреждены системные каталоги.)" + +#: pg_dump.c:10446 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "у типа данных \"%s\" по-видимому неправильный тип типа" + +#: pg_dump.c:11800 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "неприемлемое значение в массиве proargmodes" + +#: pg_dump.c:12172 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "не удалось разобрать массив proallargtypes" + +#: pg_dump.c:12188 +#, c-format +msgid "could not parse proargmodes array" +msgstr "не удалось разобрать массив proargmodes" + +#: pg_dump.c:12202 +#, c-format +msgid "could not parse proargnames array" +msgstr "не удалось разобрать массив proargnames" + +#: pg_dump.c:12213 +#, c-format +msgid "could not parse proconfig array" +msgstr "не удалось разобрать массив proconfig" + +# TO REVEIW +#: pg_dump.c:12293 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "недопустимое значение provolatile для функции \"%s\"" + +# TO REVEIW +#: pg_dump.c:12343 pg_dump.c:14401 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "недопустимое значение proparallel для функции \"%s\"" + +#: pg_dump.c:12482 pg_dump.c:12591 pg_dump.c:12598 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "не удалось найти определение функции для функции с OID %u" + +#: pg_dump.c:12521 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "неприемлемое значение в поле pg_cast.castfunc или pg_cast.castmethod" + +#: pg_dump.c:12524 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "неприемлемое значение в поле pg_cast.castmethod" + +#: pg_dump.c:12617 +#, c-format +msgid "" +"bogus transform definition, at least one of trffromsql and trftosql should " +"be nonzero" +msgstr "" +"неприемлемое определение преобразования (trffromsql или trftosql должно быть " +"ненулевым)" + +#: pg_dump.c:12634 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "неприемлемое значение в поле pg_transform.trffromsql" + +#: pg_dump.c:12655 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "неприемлемое значение в поле pg_transform.trftosql" + +#: pg_dump.c:12971 +#, c-format +msgid "could not find operator with OID %s" +msgstr "оператор с OID %s не найден" + +#: pg_dump.c:13039 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "неверный тип \"%c\" метода доступа \"%s\"" + +#: pg_dump.c:13793 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "нераспознанный поставщик правил сортировки: %s" + +#: pg_dump.c:14265 +#, c-format +msgid "" +"aggregate function %s could not be dumped correctly for this database " +"version; ignored" +msgstr "" +"агрегатная функция %s не может быть правильно выгружена для этой версии базы " +"данных; функция проигнорирована" + +#: pg_dump.c:14320 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "нераспознанное значение aggfinalmodify для агрегата \"%s\"" + +#: pg_dump.c:14376 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "нераспознанное значение aggmfinalmodify для агрегата \"%s\"" + +#: pg_dump.c:15098 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "нераспознанный тип объекта в определении прав по умолчанию: %d" + +#: pg_dump.c:15116 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "не удалось разобрать список прав по умолчанию (%s)" + +#: pg_dump.c:15201 +#, c-format +msgid "" +"could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) " +"for object \"%s\" (%s)" +msgstr "" +"не удалось разобрать изначальный список GRANT ACL (%s) или изначальный " +"список REVOKE ACL (%s) для объекта \"%s\" (%s)" + +#: pg_dump.c:15209 +#, c-format +msgid "" +"could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s" +"\" (%s)" +msgstr "" +"не удалось разобрать список GRANT ACL (%s) или список REVOKE ACL (%s) для " +"объекта \"%s\" (%s)" + +#: pg_dump.c:15724 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "" +"запрос на получение определения представления \"%s\" не возвратил данные" + +#: pg_dump.c:15727 +#, c-format +msgid "" +"query to obtain definition of view \"%s\" returned more than one definition" +msgstr "" +"запрос на получение определения представления \"%s\" возвратил несколько " +"определений" + +#: pg_dump.c:15734 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "определение представления \"%s\" пустое (длина равна нулю)" + +#: pg_dump.c:15818 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "свойство WITH OIDS больше не поддерживается (таблица \"%s\")" + +#: pg_dump.c:16298 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "неверное число родителей (%d) для таблицы \"%s\"" + +#: pg_dump.c:16621 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "неверный номер столбца %d для таблицы \"%s\"" + +#: pg_dump.c:16914 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "отсутствует индекс для ограничения \"%s\"" + +#: pg_dump.c:17139 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "нераспознанный тип ограничения: %c" + +#: pg_dump.c:17271 pg_dump.c:17491 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "" +"query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "" +"запрос на получение данных последовательности \"%s\" вернул %d строку " +"(ожидалась 1)" +msgstr[1] "" +"запрос на получение данных последовательности \"%s\" вернул %d строки " +"(ожидалась 1)" +msgstr[2] "" +"запрос на получение данных последовательности \"%s\" вернул %d строк " +"(ожидалась 1)" + +#: pg_dump.c:17305 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "нераспознанный тип последовательности: %s" + +#: pg_dump.c:17589 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "неожиданное значение tgtype: %d" + +#: pg_dump.c:17663 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "неверная строка аргументов (%s) для триггера \"%s\" таблицы \"%s\"" + +#: pg_dump.c:17899 +#, c-format +msgid "" +"query to get rule \"%s\" for table \"%s\" failed: wrong number of rows " +"returned" +msgstr "" +"запрос на получение правила \"%s\" для таблицы \"%s\" возвратил неверное " +"число строк" + +#: pg_dump.c:18061 +#, c-format +msgid "could not find referenced extension %u" +msgstr "не удалось найти упомянутое расширение %u" + +#: pg_dump.c:18273 +#, c-format +msgid "reading dependency data" +msgstr "чтение информации о зависимостях" + +#: pg_dump.c:18366 +#, c-format +msgid "no referencing object %u %u" +msgstr "нет подчинённого объекта %u %u" + +#: pg_dump.c:18377 +#, c-format +msgid "no referenced object %u %u" +msgstr "нет вышестоящего объекта %u %u" + +#: pg_dump.c:18750 +#, c-format +msgid "could not parse reloptions array" +msgstr "не удалось разобрать массив reloptions" + +#: pg_dump_sort.c:360 +#, c-format +msgid "invalid dumpId %d" +msgstr "неверный dumpId %d" + +#: pg_dump_sort.c:366 +#, c-format +msgid "invalid dependency %d" +msgstr "неверная зависимость %d" + +#: pg_dump_sort.c:599 +#, c-format +msgid "could not identify dependency loop" +msgstr "не удалось определить цикл зависимостей" + +#: pg_dump_sort.c:1170 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "в следующей таблице зациклены ограничения внешних ключей:" +msgstr[1] "в следующих таблицах зациклены ограничения внешних ключей:" +msgstr[2] "в следующих таблицах зациклены ограничения внешних ключей:" + +#: pg_dump_sort.c:1174 pg_dump_sort.c:1194 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1175 +#, c-format +msgid "" +"You might not be able to restore the dump without using --disable-triggers " +"or temporarily dropping the constraints." +msgstr "" +"Возможно, для восстановления базы потребуется использовать --disable-" +"triggers или временно удалить ограничения." + +#: pg_dump_sort.c:1176 +#, c-format +msgid "" +"Consider using a full dump instead of a --data-only dump to avoid this " +"problem." +msgstr "" +"Во избежание этой проблемы, вероятно, стоит выгружать всю базу данных, а не " +"только данные (--data-only)." + +#: pg_dump_sort.c:1188 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "не удалось разрешить цикл зависимостей для следующих объектов:" + +#: pg_dumpall.c:199 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Программа \"%s\" нужна для %s, но она не найдена\n" +"в каталоге \"%s\".\n" +"Проверьте правильность установки СУБД." + +#: pg_dumpall.c:204 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Программа \"%s\" найдена программой \"%s\",\n" +"но её версия отличается от версии %s.\n" +"Проверьте правильность установки СУБД." + +#: pg_dumpall.c:356 +#, c-format +msgid "" +"option --exclude-database cannot be used together with -g/--globals-only, -" +"r/--roles-only, or -t/--tablespaces-only" +msgstr "" +"параметр --exclude-database несовместим с -g/--globals-only, -r/--roles-only " +"и -t/--tablespaces-only" + +#: pg_dumpall.c:365 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "параметры -g/--globals-only и -r/--roles-only исключают друг друга" + +#: pg_dumpall.c:373 +#, c-format +msgid "" +"options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "" +"параметры -g/--globals-only и -t/--tablespaces-only исключают друг друга" + +#: pg_dumpall.c:387 +#, c-format +msgid "" +"options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "параметры -r/--roles-only и -t/--tablespaces-only исключают друг друга" + +#: pg_dumpall.c:448 pg_dumpall.c:1754 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "не удалось подключиться к базе данных: \"%s\"" + +#: pg_dumpall.c:462 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"не удалось подключиться к базе данных \"postgres\" или \"template1\"\n" +"Укажите другую базу данных." + +#: pg_dumpall.c:616 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s экспортирует всё содержимое кластера баз данных PostgreSQL в SQL-скрипт.\n" +"\n" + +#: pg_dumpall.c:618 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [ПАРАМЕТР]...\n" + +#: pg_dumpall.c:621 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=ИМЯ_ФАЙЛА имя выходного файла\n" + +#: pg_dumpall.c:628 +#, c-format +msgid "" +" -c, --clean clean (drop) databases before recreating\n" +msgstr "" +" -c, --clean очистить (удалить) базы данных перед\n" +" восстановлением\n" + +#: pg_dumpall.c:630 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr "" +" -g, --globals-only выгрузить только глобальные объекты, без баз\n" + +#: pg_dumpall.c:631 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner не восстанавливать владение объектами\n" + +#: pg_dumpall.c:632 +#, c-format +msgid "" +" -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr "" +" -r, --roles-only выгрузить только роли, без баз данных\n" +" и табличных пространств\n" + +#: pg_dumpall.c:634 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr "" +" -S, --superuser=ИМЯ имя пользователя для выполнения выгрузки\n" + +#: pg_dumpall.c:635 +#, c-format +msgid "" +" -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr "" +" -t, --tablespaces-only выгружать только табличные пространства,\n" +" без баз данных и ролей\n" + +#: pg_dumpall.c:641 +#, c-format +msgid "" +" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr "" +" --exclude-database=ШАБЛОН исключить базы с именами, подпадающими под " +"шаблон\n" + +#: pg_dumpall.c:648 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords не выгружать пароли ролей\n" + +#: pg_dumpall.c:662 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=СТРОКА подключиться с данной строкой подключения\n" + +#: pg_dumpall.c:664 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=ИМЯ_БД выбор другой базы данных по умолчанию\n" + +#: pg_dumpall.c:671 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the " +"standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"Если не указан параметр -f/--file, SQL-скрипт записывается в стандартный " +"вывод.\n" +"\n" + +#: pg_dumpall.c:877 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "имя роли, начинающееся с \"pg_\", пропущено (%s)" + +#: pg_dumpall.c:1278 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "" +"не удалось разобрать список управления доступом (%s) для табл. пространства " +"\"%s\"" + +#: pg_dumpall.c:1495 +#, c-format +msgid "excluding database \"%s\"" +msgstr "база данных \"%s\" исключается" + +#: pg_dumpall.c:1499 +#, c-format +msgid "dumping database \"%s\"" +msgstr "выгрузка базы данных \"%s\"" + +#: pg_dumpall.c:1531 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "ошибка при обработке базы \"%s\", pg_dump завершается" + +#: pg_dumpall.c:1540 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "не удалось повторно открыть выходной файл \"%s\": %m" + +#: pg_dumpall.c:1584 +#, c-format +msgid "running \"%s\"" +msgstr "выполняется \"%s\"" + +#: pg_dumpall.c:1775 +#, c-format +msgid "could not connect to database \"%s\": %s" +msgstr "не удалось подключиться к базе \"%s\": %s" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "не удалось узнать версию сервера" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "не удалось разобрать строку версии сервера \"%s\"" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "выполняется %s" + +# TO REVEIW +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "необходимо указать -d/--dbname или -f/--file" + +# TO REVEIW +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "параметры -d/--dbname и -f/--file исключают друг друга" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "параметры -C/--create и -1/--single-transaction исключают друг друга" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "максимальное число параллельных заданий равно %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "параметр --single-transaction допускается только с одним заданием" + +#: pg_restore.c:408 +#, c-format +msgid "" +"unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "нераспознанный формат архива \"%s\"; укажите \"c\", \"d\" или \"t\"" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "при восстановлении проигнорировано ошибок: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s восстанавливает базу данных PostgreSQL из архива, созданного командой " +"pg_dump.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [ПАРАМЕТР]... [ФАЙЛ]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=БД подключиться к указанной базе данных\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr "" +" -f, --file=ИМЯ_ФАЙЛА имя выходного файла (или - для вывода в stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr "" +" -F, --format=c|d|t формат файла (должен определяться автоматически)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list вывести краткое оглавление архива\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose выводить подробные сообщения\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Параметры, управляющие восстановлением:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only восстановить только данные, без схемы\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create создать целевую базу данных\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr "" +" -e, --exit-on-error выйти при ошибке (по умолчанию - продолжать)\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=ИМЯ восстановить указанный индекс\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr "" +" -j, --jobs=ЧИСЛО распараллелить восстановление на указанное " +"число заданий\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=ИМЯ_ФАЙЛА использовать оглавление из этого файла для\n" +" чтения/упорядочивания данных\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr "" +" -n, --schema=ИМЯ восстановить объекты только в этой схеме\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr "" +" -N, --exclude-schema=ИМЯ не восстанавливать объекты в этой схеме\n" + +# skip-rule: no-space-before-parentheses +# well-spelled: арг +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=ИМЯ(арг-ты) восстановить заданную функцию\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only восстановить только схему, без данных\n" + +#: pg_restore.c:488 +#, c-format +msgid "" +" -S, --superuser=NAME superuser user name to use for disabling " +"triggers\n" +msgstr "" +" -S, --superuser=ИМЯ имя суперпользователя для отключения " +"триггеров\n" + +#: pg_restore.c:489 +#, c-format +msgid "" +" -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr "" +" -t, --table=ИМЯ восстановить заданное отношение (таблицу, " +"представление и т. п.)\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=ИМЯ восстановить заданный триггер\n" + +#: pg_restore.c:491 +#, c-format +msgid "" +" -x, --no-privileges skip restoration of access privileges (grant/" +"revoke)\n" +msgstr "" +" -x, --no-privileges не восстанавливать права доступа\n" +" (назначение/отзыв)\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr "" +" -1, --single-transaction выполнить восстановление в одной транзакции\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security включить защиту на уровне строк\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments не восстанавливать комментарии\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not " +"be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables не восстанавливать данные таблиц, которые\n" +" не удалось создать\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications не восстанавливать публикации\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels не восстанавливать метки безопасности\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions не восстанавливать подписки\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr "" +" --no-tablespaces не восстанавливать назначения табл. " +"пространств\n" + +#: pg_restore.c:503 +#, c-format +msgid "" +" --section=SECTION restore named section (pre-data, data, or " +"post-data)\n" +msgstr "" +" --section=РАЗДЕЛ восстановить заданный раздел\n" +" (pre-data, data или post-data)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ИМЯ_РОЛИ выполнить SET ROLE перед восстановлением\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and " +"specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"Параметры -I, -n, -N, -P, -t, -T и --section можно комбинировать и " +"указывать\n" +"несколько раз для выбора нескольких объектов.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"Если имя входного файла не указано, используется стандартное устройство " +"ввода.\n" +"\n" + +#~ msgid "reading publication membership for table \"%s.%s\"" +#~ msgstr "чтение информации об участии в репликации таблицы \"%s.%s\"" + +#~ msgid "connecting to database \"%s\" as user \"%s\"" +#~ msgstr "подключение к базе \"%s\" с именем пользователя \"%s\"" + +#~ msgid "could not reconnect to database" +#~ msgstr "не удалось переподключиться к базе" + +#~ msgid "could not reconnect to database: %s" +#~ msgstr "не удалось переподключиться к базе: %s" + +#~ msgid "connection needs password" +#~ msgstr "для подключения необходим пароль" + +#~ msgid "" +#~ "could not find block ID %d in archive -- possibly due to out-of-order " +#~ "restore request, which cannot be handled due to lack of data offsets in " +#~ "archive" +#~ msgstr "" +#~ "не удалось найти в архиве блок с ID %d -- возможно, по причине не " +#~ "последовательного запроса восстановления, который нельзя обработать из-за " +#~ "отсутствия смещений данных в архиве" + +#~ msgid "ftell mismatch with expected position -- ftell used" +#~ msgstr "позиция ftell не соответствует ожидаемой -- используется ftell" + +#~ msgid "internal error -- neither th nor fh specified in tarReadRaw()" +#~ msgstr "внутренняя ошибка -- в tarReadRaw() не указан ни th, ни fh" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Об ошибках сообщайте по адресу .\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "дочерний процесс завершён по сигналу %s" + +#~ msgid "compress_io" +#~ msgstr "compress_io" + +#~ msgid "parallel archiver" +#~ msgstr "параллельный архиватор" + +#~ msgid "archiver" +#~ msgstr "архиватор" + +#~ msgid "-C and -1 are incompatible options\n" +#~ msgstr "Параметры -C и -1 несовместимы\n" + +#~ msgid "attempting to ascertain archive format\n" +#~ msgstr "попытка выяснить формат архива\n" + +#~ msgid "allocating AH for %s, format %d\n" +#~ msgstr "выделение структуры AH для %s, формат %d\n" + +#~ msgid "read TOC entry %d (ID %d) for %s %s\n" +#~ msgstr "прочитана запись оглавления %d (ID %d): %s %s\n" + +#~ msgid "could not set default_with_oids: %s" +#~ msgstr "не удалось установить параметр default_with_oids: %s" + +#~ msgid "entering restore_toc_entries_prefork\n" +#~ msgstr "вход в restore_toc_entries_prefork\n" + +#~ msgid "entering restore_toc_entries_parallel\n" +#~ msgstr "вход в restore_toc_entries_parallel\n" + +#~ msgid "entering restore_toc_entries_postfork\n" +#~ msgstr "вход в restore_toc_entries_postfork\n" + +#~ msgid "no item ready\n" +#~ msgstr "элемент не готов\n" + +#~ msgid "transferring dependency %d -> %d to %d\n" +#~ msgstr "переключение зависимости %d -> %d на %d\n" + +#~ msgid "reducing dependencies for %d\n" +#~ msgstr "уменьшение зависимостей для %d\n" + +#~ msgid "custom archiver" +#~ msgstr "внешний архиватор" + +#~ msgid "archiver (db)" +#~ msgstr "архиватор (БД)" + +#~ msgid "failed to reconnect to database\n" +#~ msgstr "ошибка переподключения к базе данных\n" + +#~ msgid "failed to connect to database\n" +#~ msgstr "ошибка подключения к базе данных\n" + +#~ msgid "directory archiver" +#~ msgstr "каталоговый архиватор" + +#~ msgid "tar archiver" +#~ msgstr "архиватор tar" + +#~ msgid "moving from position %s to next member at file position %s\n" +#~ msgstr "переход от позиции %s к следующему компоненту в позиции %s\n" + +#~ msgid "now at file position %s\n" +#~ msgstr "текущая позиция в файле %s\n" + +#~ msgid "skipping tar member %s\n" +#~ msgstr "пропускается компонент tar %s\n" + +# skip-rule: capital-letter-first +#~ msgid "TOC Entry %s at %s (length %s, checksum %d)\n" +#~ msgstr "Запись оглавления %s в %s (длина: %s, контр. сумма: %d)\n" + +#~ msgid "" +#~ "options --inserts/--column-inserts and -o/--oids cannot be used together\n" +#~ msgstr "" +#~ "параметры --inserts/--column-inserts и -o/--oids исключают друг друга\n" + +#~ msgid "(The INSERT command cannot set OIDs.)\n" +#~ msgstr "(В INSERT нельзя определять OID.)\n" + +#~ msgid " -o, --oids include OIDs in dump\n" +#~ msgstr " -o, --oids выгружать данные с OID\n" + +#~ msgid "sorter" +#~ msgstr "sorter" + +#~ msgid "%s: option --if-exists requires option -c/--clean\n" +#~ msgstr "%s: параметр --if-exists требует указания -c/--clean\n" + +#~ msgid "%s: could not open the output file \"%s\": %s\n" +#~ msgstr "%s: не удалось открыть выходной файл \"%s\": %s\n" + +#~ msgid "%s: invalid client encoding \"%s\" specified\n" +#~ msgstr "%s: указана неверная клиентская кодировка \"%s\"\n" + +#~ msgid "%s: executing %s\n" +#~ msgstr "%s: выполняется %s\n" + +#~ msgid "%s: query failed: %s" +#~ msgstr "%s: ошибка при выполнении запроса: %s" + +#~ msgid "%s: query was: %s\n" +#~ msgstr "%s: запрос: %s\n" + +#~ msgid "" +#~ "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" +#~ msgstr "" +#~ "%s: параметры -s/--schema-only и -a/--data-only исключают друг друга\n" + +#~ msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" +#~ msgstr "%s: параметры -c/--clean and -a/--data-only исключают друг друга\n" + +#~ msgid "%s: invalid number of parallel jobs\n" +#~ msgstr "%s: неверное число параллельных заданий\n" + +#~ msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" +#~ msgstr "" +#~ "%s: не удалось разобрать список управления доступом (%s) для базы данных " +#~ "\"%s\"\n" + +#~ msgid "reading extended statistics for table \"%s.%s\"\n" +#~ msgstr "чтение расширенной статистики для таблицы \"%s.%s\"\n" + +#~ msgid "setting owner and privileges for %s \"%s.%s\"\n" +#~ msgstr "установка владельца и прав: %s \"%s.%s\"\n" + +#~ msgid "setting owner and privileges for %s \"%s\"\n" +#~ msgstr "установка владельца и прав: %s \"%s\"\n" + +#~ msgid "" +#~ "Synchronized snapshots are not supported on standby servers.\n" +#~ "Run with --no-synchronized-snapshots instead if you do not need\n" +#~ "synchronized snapshots.\n" +#~ msgstr "" +#~ "На резервных серверах синхронизированные снимки не поддерживаются.\n" +#~ "Если они вам не нужны, укажите при запуске ключ\n" +#~ "--no-synchronized-snapshots.\n" + +#~ msgid "reading partition information\n" +#~ msgstr "чтение информации о секциях\n" + +#~ msgid "finding partition relationships\n" +#~ msgstr "обнаружение взаимосвязей секций\n" + +#~ msgid "reading partition key information for interesting tables\n" +#~ msgstr "чтение информации о ключах разбиения для интересующих таблиц\n" + +#~ msgid "" +#~ " --no-subscription-connect dump subscriptions so they don't connect " +#~ "on restore\n" +#~ msgstr "" +#~ " --no-subscription-connect выгружать подписки так, чтобы они не " +#~ "подключались\n" +#~ " при восстановлении\n" + +#~ msgid "" +#~ "%s: options --no-role-passwords and --binary-upgrade cannot be used " +#~ "together\n" +#~ msgstr "" +#~ "%s: параметры --no-role-passwords и --binary-upgrade исключают друг " +#~ "друга\n" + +#~ msgid "error processing a parallel work item\n" +#~ msgstr "ошибка выполнения части параллельной работы\n" + +#~ msgid "could not find slot of finished worker\n" +#~ msgstr "не удалось найти слот законченного рабочего объекта\n" + +#~ msgid "error during backup\n" +#~ msgstr "ошибка в процессе резервного копирования\n" + +#~ msgid "" +#~ "server version must be at least 7.3 to use schema selection switches\n" +#~ msgstr "" +#~ "для использования параметров выбора схемы нужен сервер версии 7.3 или " +#~ "новее\n" + +#~ msgid "query to get data of sequence \"%s\" returned name \"%s\"\n" +#~ msgstr "" +#~ "запрос на получение данных последовательности \"%s\" вернул имя \"%s\"\n" + +#~ msgid "could not get relation name for OID %u: %s\n" +#~ msgstr "не удалось получить имя отношения с OID %u: %s\n" + +#~ msgid "terminated by user\n" +#~ msgstr "прервано пользователем\n" + +#~ msgid "error in ListenToWorkers(): %s\n" +#~ msgstr "ошибка в ListenToWorkers(): %s\n" + +#~ msgid "worker is terminating\n" +#~ msgstr "рабочий процесс прерывается\n" + +#~ msgid "could not open output file \"%s\" for writing\n" +#~ msgstr "не удалось открыть выходной файл \"%s\" для записи\n" + +#~ msgid " -t, --table=NAME restore named table\n" +#~ msgstr " -t, --table=ИМЯ восстановить заданную таблицу\n" + +#~ msgid "archive member too large for tar format\n" +#~ msgstr "компонент архива слишком велик для формата tar\n" + +#~ msgid "could not write to custom output routine\n" +#~ msgstr "не удалось вывести данную в пользовательскую процедуру\n" + +#~ msgid "unexpected end of file\n" +#~ msgstr "неожиданный конец файла\n" + +#~ msgid "could not write byte: %s\n" +#~ msgstr "не удалось записать байт: %s\n" + +#~ msgid "could not write byte\n" +#~ msgstr "не удалось записать байт\n" + +#~ msgid "could not write null block at end of tar archive\n" +#~ msgstr "не удалось записать нулевой блок в конец tar-архива\n" + +#~ msgid "could not output padding at end of tar member\n" +#~ msgstr "не удалось записать выравнивание для компонента tar\n" + +#~ msgid "mismatch in actual vs. predicted file position (%s vs. %s)\n" +#~ msgstr "реальная позиция в файле отличается от предсказанной (%s и %s)\n" + +#~ msgid "could not determine seek position in file: %s\n" +#~ msgstr "не удалось определить позицию в файле: %s\n" + +#~ msgid "Error processing a parallel work item.\n" +#~ msgstr "Ошибка выполнения части параллельной работы.\n" + +#~ msgid "pgpipe could not getsockname: %ui" +#~ msgstr "функция pgpipe не смогла получить имя сокета: %ui" + +#~ msgid "pgpipe could not create socket 2: %ui" +#~ msgstr "функция pgpipe не смогла создать сокет 2: %ui" + +#~ msgid "worker process crashed: status %d\n" +#~ msgstr "крах рабочего процесса: состояние %d\n" + +#~ msgid "parallel_restore should not return\n" +#~ msgstr "неожиданный выход из parallel_restore\n" + +#~ msgid "could not parse version string \"%s\"\n" +#~ msgstr "не удалось разобрать строку версии \"%s\"\n" + +#~ msgid "%s: could not parse version \"%s\"\n" +#~ msgstr "%s: не удалось разобрать строку версии \"%s\"\n" + +#~ msgid "-C and -c are incompatible options\n" +#~ msgstr "Параметры -C и -c несовместимы\n" + +#~ msgid "invalid COPY statement -- could not find \"copy\" in string \"%s\"\n" +#~ msgstr "" +#~ "неверный оператор COPY -- слово \"copy\" не найдено в строке \"%s\"\n" + +#~ msgid "" +#~ "invalid COPY statement -- could not find \"from stdin\" in string \"%s\" " +#~ "starting at position %lu\n" +#~ msgstr "" +#~ "неверный оператор COPY -- указание \"from stdin\" не найдено в строке \"%s" +#~ "\", начиная с позиции %lu\n" + +#~ msgid "cannot create directory %s, it exists already\n" +#~ msgstr "создать каталог %s не удалось, он уже существует\n" + +#~ msgid "cannot create directory %s, a file with this name exists already\n" +#~ msgstr "создать каталог %s не удалось, так как есть файл с таким именем\n" + +#~ msgid "restoring large object OID %u\n" +#~ msgstr "восстановление большого объекта с OID %u\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help показать эту справку и выйти\n" + +#~ msgid "" +#~ " --version output version information, then exit\n" +#~ msgstr " --version показать версию и выйти\n" + +#~ msgid "*** aborted because of error\n" +#~ msgstr "*** аварийное завершение из-за ошибки\n" + +#~ msgid "missing pg_database entry for database \"%s\"\n" +#~ msgstr "для базы данных \"%s\" отсутствует запись в pg_database\n" + +#~ msgid "" +#~ "query returned more than one (%d) pg_database entry for database \"%s\"\n" +#~ msgstr "" +#~ "в pg_database нашлось несколько записей (%d) для базы данных \"%s\"\n" + +#~ msgid "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n" +#~ msgstr "dumpDatabase(): не удалось найти pg_largeobject.relfrozenxid\n" + +#~ msgid "" +#~ "dumpDatabase(): could not find pg_largeobject_metadata.relfrozenxid\n" +#~ msgstr "" +#~ "dumpDatabase(): не удалось найти pg_largeobject_metadata.relfrozenxid\n" + +#~ msgid "query returned %d foreign server entry for foreign table \"%s\"\n" +#~ msgid_plural "" +#~ "query returned %d foreign server entries for foreign table \"%s\"\n" +#~ msgstr[0] "" +#~ "запрос вернул %d запись о стороннем сервере для сторонней таблицы \"%s\"\n" +#~ msgstr[1] "" +#~ "запрос вернул %d записи о стороннем сервере для сторонней таблицы \"%s\"\n" +#~ msgstr[2] "" +#~ "запрос вернул %d записей о стороннем сервере для сторонней таблицы \"%s" +#~ "\"\n" + +#~ msgid "missing pg_database entry for this database\n" +#~ msgstr "для этой базы данных отсутствует запись в pg_database\n" + +#~ msgid "found more than one pg_database entry for this database\n" +#~ msgstr "для этой базы данных найдено несколько записей в pg_database\n" + +#~ msgid "could not find entry for pg_indexes in pg_class\n" +#~ msgstr "для pg_indexes не найдена запись в pg_class\n" + +#~ msgid "found more than one entry for pg_indexes in pg_class\n" +#~ msgstr "для pg_indexes найдено несколько записей в pg_class\n" + +#~ msgid "SQL command failed\n" +#~ msgstr "ошибка SQL-команды\n" + +#~ msgid "file archiver" +#~ msgstr "файловый архиватор" + +#~ msgid "" +#~ "WARNING:\n" +#~ " This format is for demonstration purposes; it is not intended for\n" +#~ " normal use. Files will be written in the current working directory.\n" +#~ msgstr "" +#~ "ПРЕДУПРЖДЕНИЕ:\n" +#~ " Этот формат предназначен только для целей демонстрации, но не для\n" +#~ " повседневного использования. Файлы сохраняются в текущий рабочий " +#~ "каталог.\n" + +#~ msgid "could not close data file after reading\n" +#~ msgstr "не удалось закрыть файл данных после чтения\n" + +#~ msgid "could not open large object TOC for input: %s\n" +#~ msgstr "" +#~ "не удалось открыть для чтения файл оглавления больших объектов: %s\n" + +#~ msgid "could not open large object TOC for output: %s\n" +#~ msgstr "" +#~ "не удалось открыть для записи файл оглавления больших объектов: %s\n" + +#~ msgid "could not close large object file\n" +#~ msgstr "не удалось закрыть файл большого объекта\n" + +#~ msgid "" +#~ " -c, --clean clean (drop) database objects before " +#~ "recreating\n" +#~ msgstr "" +#~ " -c, --clean очистить (удалить) объекты БД при " +#~ "восстановлении\n" + +#~ msgid " -O, --no-owner skip restoration of object ownership\n" +#~ msgstr " -O, --no-owner не восстанавливать владение объектами\n" + +#~ msgid "" +#~ " --disable-triggers disable triggers during data-only restore\n" +#~ msgstr "" +#~ " --disable-triggers отключить триггеры при восстановлении только " +#~ "данных\n" + +#~ msgid "" +#~ " --use-set-session-authorization\n" +#~ " use SET SESSION AUTHORIZATION commands instead " +#~ "of\n" +#~ " ALTER OWNER commands to set ownership\n" +#~ msgstr "" +#~ " --use-set-session-authorization\n" +#~ " устанавливать владельца, используя команды\n" +#~ " SET SESSION AUTHORIZATION вместо ALTER OWNER\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: нехватка памяти\n" diff --git a/src/bin/pg_dump/po/sv.po b/src/bin/pg_dump/po/sv.po new file mode 100644 index 000000000000..45090f6a7881 --- /dev/null +++ b/src/bin/pg_dump/po/sv.po @@ -0,0 +1,2692 @@ +# Swedish message translation file for pg_dump +# Peter Eisentraut , 2001, 2009, 2010. +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-20 16:46+0000\n" +"PO-Revision-Date: 2020-10-20 20:32+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ogiltig binär \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "kunde inte läsa binär \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "kunde inte hitta en \"%s\" att köra" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "slut på minne" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "slut på minne\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kan inte duplicera null-pekare (internt fel)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "kommandot är inte körbart" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "kommandot kan ej hittas" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "barnprocess avslutade med kod %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "barnprocess terminerades med avbrott 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "barnprocess avslutade med okänd statuskod %d" + +#: common.c:121 +#, c-format +msgid "reading extensions" +msgstr "läser utökningar" + +#: common.c:125 +#, c-format +msgid "identifying extension members" +msgstr "identifierar utökningsmedlemmar" + +#: common.c:128 +#, c-format +msgid "reading schemas" +msgstr "läser scheman" + +#: common.c:138 +#, c-format +msgid "reading user-defined tables" +msgstr "läser användardefinierade tabeller" + +#: common.c:145 +#, c-format +msgid "reading user-defined functions" +msgstr "läser användardefinierade funktioner" + +#: common.c:150 +#, c-format +msgid "reading user-defined types" +msgstr "läser användardefinierade typer" + +#: common.c:155 +#, c-format +msgid "reading procedural languages" +msgstr "läser procedurspråk" + +#: common.c:158 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "läser användardefinierade aggregatfunktioner" + +#: common.c:161 +#, c-format +msgid "reading user-defined operators" +msgstr "läser användardefinierade operatorer" + +#: common.c:165 +#, c-format +msgid "reading user-defined access methods" +msgstr "läser användardefinierade accessmetoder" + +#: common.c:168 +#, c-format +msgid "reading user-defined operator classes" +msgstr "läser användardefinierade operatorklasser" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator families" +msgstr "läser användardefinierade operator-familjer" + +#: common.c:174 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "läser användardefinierade textsöktolkare" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search templates" +msgstr "läser användardefinierade textsökmallar" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "läser användardefinierade textsökordlistor" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "läser användardefinierade textsökkonfigurationer" + +#: common.c:186 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "läser användardefinierade främmande data-omvandlare" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "läser användardefinierade främmande servrar" + +#: common.c:192 +#, c-format +msgid "reading default privileges" +msgstr "läser standardrättigheter" + +#: common.c:195 +#, c-format +msgid "reading user-defined collations" +msgstr "läser användardefinierade jämförelser" + +#: common.c:199 +#, c-format +msgid "reading user-defined conversions" +msgstr "läser användardefinierade konverteringar" + +#: common.c:202 +#, c-format +msgid "reading type casts" +msgstr "läser typomvandlingar" + +#: common.c:205 +#, c-format +msgid "reading transforms" +msgstr "läser transformer" + +#: common.c:208 +#, c-format +msgid "reading table inheritance information" +msgstr "läser information om arv av tabeller" + +#: common.c:211 +#, c-format +msgid "reading event triggers" +msgstr "läser händelseutlösare" + +#: common.c:215 +#, c-format +msgid "finding extension tables" +msgstr "hittar utökningstabeller" + +#: common.c:219 +#, c-format +msgid "finding inheritance relationships" +msgstr "hittar arvrelationer" + +#: common.c:222 +#, c-format +msgid "reading column info for interesting tables" +msgstr "läser kolumninfo flr intressanta tabeller" + +#: common.c:225 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "markerar ärvda kolumner i undertabeller" + +#: common.c:228 +#, c-format +msgid "reading indexes" +msgstr "läser index" + +#: common.c:231 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "flaggar index i partitionerade tabeller" + +#: common.c:234 +#, c-format +msgid "reading extended statistics" +msgstr "läser utökad statistik" + +#: common.c:237 +#, c-format +msgid "reading constraints" +msgstr "läser integritetsvillkor" + +#: common.c:240 +#, c-format +msgid "reading triggers" +msgstr "läser utlösare" + +#: common.c:243 +#, c-format +msgid "reading rewrite rules" +msgstr "läser omskrivningsregler" + +#: common.c:246 +#, c-format +msgid "reading policies" +msgstr "läser policys" + +#: common.c:249 +#, c-format +msgid "reading publications" +msgstr "läser publiceringar" + +#: common.c:252 +#, c-format +msgid "reading publication membership" +msgstr "läser publiceringsmedlemskap" + +#: common.c:255 +#, c-format +msgid "reading subscriptions" +msgstr "läser prenumerationer" + +#: common.c:1025 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "misslyckades med riktighetskontroll, hittade inte förälder-OID %u för tabell \"%s\" (OID %u)" + +#: common.c:1067 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "kunde inte tolka numerisk array \"%s\": för många nummer" + +#: common.c:1082 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "kunde inte tolka numerisk array \"%s\": ogiltigt tecken i nummer" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "ogiltig komprimeringskod: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "ej byggt med zlib-stöd" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "kunde inte initiera komprimeringsbibliotek: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "kunde inte stänga komprimeringsströmmen: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "kunde inte komprimera data: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "kunde inte packa upp data: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "kunde inte stänga komprimeringsbiblioteket: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:557 pg_backup_tar.c:560 +#, c-format +msgid "could not read from input file: %s" +msgstr "kunde inte läsa från infilen: %s" + +#: compress_io.c:623 pg_backup_custom.c:646 pg_backup_directory.c:552 +#: pg_backup_tar.c:793 pg_backup_tar.c:816 +#, c-format +msgid "could not read from input file: end of file" +msgstr "kunde inte läsa från infilen: slut på filen" + +#: parallel.c:254 +#, c-format +msgid "WSAStartup failed: %d" +msgstr "WSAStartup misslyckades: %d" + +#: parallel.c:964 +#, c-format +msgid "could not create communication channels: %m" +msgstr "kunde inte skapa kommunikationskanaler: %m" + +#: parallel.c:1021 +#, c-format +msgid "could not create worker process: %m" +msgstr "kunde inte skapa arbetsprocess: %m" + +#: parallel.c:1151 +#, c-format +msgid "unrecognized command received from master: \"%s\"" +msgstr "okänt kommando mottaget från master: \"%s\"" + +#: parallel.c:1194 parallel.c:1432 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "ogiltigt meddelande mottaget från arbetare: \"%s\"" + +#: parallel.c:1326 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"kunde inte låsa relationen \"%s\"\n" +"Dette beror oftast på att någon tagit ett ACCESS EXCLUSIVE-lås på tabellen\n" +"efter att pg_dumps föräldraprocess tagit ett ACCESS SHARE-lås på tabellen." + +#: parallel.c:1415 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "en arbetsprocess dog oväntat" + +#: parallel.c:1537 parallel.c:1655 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "kunde inte skriva till kommunikationskanal: %m" + +#: parallel.c:1614 +#, c-format +msgid "select() failed: %m" +msgstr "select() misslyckades: %m" + +#: parallel.c:1739 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: kunde inte skapa uttag (socket): felkod %d" + +#: parallel.c:1750 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: kunde inte göra \"bind\": felkod %d" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: kunde inte göra \"listen\": felkod %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname() misslyckades: felkod %d" + +#: parallel.c:1775 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: kunde inte skapa ett andra uttag (socket): felkod %d" + +#: parallel.c:1784 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: kunde itne ansluta till uttag (socket): felkod %d" + +#: parallel.c:1793 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: kunde inte acceptera anslutning: felkod %d" + +#: pg_backup_archiver.c:277 pg_backup_archiver.c:1587 +#, c-format +msgid "could not close output file: %m" +msgstr "kunde inte stänga utdatafilen: %m" + +#: pg_backup_archiver.c:321 pg_backup_archiver.c:325 +#, c-format +msgid "archive items not in correct section order" +msgstr "arkivobjekten är inte i korrekt sektionsordning" + +#: pg_backup_archiver.c:331 +#, c-format +msgid "unexpected section code %d" +msgstr "oväntad sektionskod %d" + +#: pg_backup_archiver.c:368 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "parallell återställning stöds inte med detta arkivformat" + +#: pg_backup_archiver.c:372 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "parallell återställning stöds inte med arkiv som skapats av en pre-8.0 pg_dump" + +#: pg_backup_archiver.c:390 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "kan inte återställa från komprimerat arkiv (inte konfigurerad med stöd för komprimering)" + +#: pg_backup_archiver.c:407 +#, c-format +msgid "connecting to database for restore" +msgstr "kopplar upp mot databas för återställning" + +#: pg_backup_archiver.c:409 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "direkta databasuppkopplingar stöds inte i arkiv från före version 1.3" + +#: pg_backup_archiver.c:452 +#, c-format +msgid "implied data-only restore" +msgstr "implicerad återställning av enbart data" + +#: pg_backup_archiver.c:518 +#, c-format +msgid "dropping %s %s" +msgstr "tar bort %s %s" + +#: pg_backup_archiver.c:613 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "kunde inte hitta var IF EXISTS skulle stoppas in i sats \"%s\"" + +#: pg_backup_archiver.c:769 pg_backup_archiver.c:771 +#, c-format +msgid "warning from original dump file: %s" +msgstr "varning från orginaldumpfilen: %s" + +#: pg_backup_archiver.c:786 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "skapar %s \"%s.%s\"" + +#: pg_backup_archiver.c:789 +#, c-format +msgid "creating %s \"%s\"" +msgstr "skapar %s \"%s\"" + +#: pg_backup_archiver.c:839 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "kopplar upp mot ny databas \"%s\"" + +#: pg_backup_archiver.c:866 +#, c-format +msgid "processing %s" +msgstr "processar %s" + +#: pg_backup_archiver.c:886 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "processar data för tabell \"%s.%s\"" + +#: pg_backup_archiver.c:948 +#, c-format +msgid "executing %s %s" +msgstr "kör %s %s" + +#: pg_backup_archiver.c:987 +#, c-format +msgid "disabling triggers for %s" +msgstr "stänger av utlösare för %s" + +#: pg_backup_archiver.c:1013 +#, c-format +msgid "enabling triggers for %s" +msgstr "slår på utlösare för %s" + +#: pg_backup_archiver.c:1041 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "internt fel -- WriteData kan inte anropas utanför kontexten av en DataDumper-rutin" + +#: pg_backup_archiver.c:1224 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "utmatning av stora objekt stöds inte i det valda formatet" + +#: pg_backup_archiver.c:1282 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "återställde %d stor objekt" +msgstr[1] "återställde %d stora objekt" + +#: pg_backup_archiver.c:1303 pg_backup_tar.c:736 +#, c-format +msgid "restoring large object with OID %u" +msgstr "återställer stort objekt med OID %u" + +#: pg_backup_archiver.c:1315 +#, c-format +msgid "could not create large object %u: %s" +msgstr "kunde inte skapa stort objekt %u: %s" + +#: pg_backup_archiver.c:1320 pg_dump.c:3552 +#, c-format +msgid "could not open large object %u: %s" +msgstr "kunde inte öppna stort objekt %u: %s" + +#: pg_backup_archiver.c:1377 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "kunde inte öppna TOC-filen \"%s\": %m" + +#: pg_backup_archiver.c:1417 +#, c-format +msgid "line ignored: %s" +msgstr "rad ignorerad: %s" + +#: pg_backup_archiver.c:1424 +#, c-format +msgid "could not find entry for ID %d" +msgstr "kunde inte hitta en post för ID %d" + +#: pg_backup_archiver.c:1445 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "kunde inte stänga TOC-filen: %m" + +#: pg_backup_archiver.c:1559 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:484 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "kunde inte öppna utdatafilen \"%s\": %m" + +#: pg_backup_archiver.c:1561 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "kunde inte öppna utdatafilen: %m" + +#: pg_backup_archiver.c:1654 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "skrev %lu byte av stort objekt-data (resultat = %lu)" +msgstr[1] "skrev %lu bytes av stort objekt-data (resultat = %lu)" + +#: pg_backup_archiver.c:1659 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "kunde inte skriva till stort objekt (resultat: %lu, förväntat: %lu)" + +#: pg_backup_archiver.c:1749 +#, c-format +msgid "while INITIALIZING:" +msgstr "vid INITIERING:" + +#: pg_backup_archiver.c:1754 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "vid HANTERING AV TOC:" + +#: pg_backup_archiver.c:1759 +#, c-format +msgid "while FINALIZING:" +msgstr "vid SLUTFÖRANDE:" + +#: pg_backup_archiver.c:1764 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "från TOC-post %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1840 +#, c-format +msgid "bad dumpId" +msgstr "felaktigt dumpId" + +#: pg_backup_archiver.c:1861 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "felaktig tabell-dumpId för TABLE DATA-objekt" + +#: pg_backup_archiver.c:1953 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "oväntad data-offset-flagga %d" + +#: pg_backup_archiver.c:1966 +#, c-format +msgid "file offset in dump file is too large" +msgstr "fil-offset i dumpfilen är för stort" + +#: pg_backup_archiver.c:2103 pg_backup_archiver.c:2113 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "katalognamn för långt: \"%s\"" + +#: pg_backup_archiver.c:2121 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "katalogen \"%s\" verkar inte vara ett giltigt arkiv (\"toc.dat\" finns inte)" + +#: pg_backup_archiver.c:2129 pg_backup_custom.c:173 pg_backup_custom.c:812 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "kunde inte öppna indatafilen \"%s\": %m" + +#: pg_backup_archiver.c:2136 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "kan inte öppna infil: %m" + +#: pg_backup_archiver.c:2142 +#, c-format +msgid "could not read input file: %m" +msgstr "kan inte läsa infilen: %m" + +#: pg_backup_archiver.c:2144 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "indatafilen är för kort (läste %lu, förväntade 5)" + +#: pg_backup_archiver.c:2229 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "indatafilen verkar vara en dump i textformat. Använd psql." + +#: pg_backup_archiver.c:2235 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "indatafilen verkar inte vara ett korrekt arkiv (för kort?)" + +#: pg_backup_archiver.c:2241 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "indatafilen verkar inte vara ett korrekt arkiv" + +#: pg_backup_archiver.c:2261 +#, c-format +msgid "could not close input file: %m" +msgstr "kunde inte stänga indatafilen: %m" + +#: pg_backup_archiver.c:2373 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "känner inte igen filformat \"%d\"" + +#: pg_backup_archiver.c:2455 pg_backup_archiver.c:4458 +#, c-format +msgid "finished item %d %s %s" +msgstr "klar med objekt %d %s %s" + +#: pg_backup_archiver.c:2459 pg_backup_archiver.c:4471 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "arbetsprocess misslyckades: felkod %d" + +#: pg_backup_archiver.c:2579 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "post-ID %d utanför sitt intervall -- kanske en trasig TOC" + +#: pg_backup_archiver.c:2646 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "återeställa tabeller med WITH OIDS stöds inte längre" + +#: pg_backup_archiver.c:2728 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "okänd teckenkodning \"%s\"" + +#: pg_backup_archiver.c:2733 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "ogiltigt ENCODING-val: %s" + +#: pg_backup_archiver.c:2751 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "ogiltigt STDSTRINGS-val: %s" + +#: pg_backup_archiver.c:2776 +#, c-format +msgid "schema \"%s\" not found" +msgstr "schema \"%s\" hittades inte" + +#: pg_backup_archiver.c:2783 +#, c-format +msgid "table \"%s\" not found" +msgstr "tabell \"%s\" hittades inte" + +#: pg_backup_archiver.c:2790 +#, c-format +msgid "index \"%s\" not found" +msgstr "index \"%s\" hittades inte" + +#: pg_backup_archiver.c:2797 +#, c-format +msgid "function \"%s\" not found" +msgstr "funktion \"%s\" hittades inte" + +#: pg_backup_archiver.c:2804 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "utlösare \"%s\" hittades inte" + +#: pg_backup_archiver.c:3196 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "kunde inte sätta sessionsanvändare till \"%s\": %s" + +#: pg_backup_archiver.c:3328 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "kunde inte sätta search_path till \"%s\": %s" + +#: pg_backup_archiver.c:3390 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "kunde inte sätta default_tablespace till %s: %s" + +#: pg_backup_archiver.c:3435 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "kunde inte sätta default_table_access_method: %s" + +#: pg_backup_archiver.c:3527 pg_backup_archiver.c:3685 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "vet inte hur man sätter ägare för objekttyp \"%s\"" + +#: pg_backup_archiver.c:3789 +#, c-format +msgid "did not find magic string in file header" +msgstr "kunde inte hitta den magiska strängen i filhuvudet" + +#: pg_backup_archiver.c:3802 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "ej supportad version (%d.%d) i filhuvudet" + +#: pg_backup_archiver.c:3807 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "riktighetskontroll på heltalsstorlek (%lu) misslyckades" + +#: pg_backup_archiver.c:3811 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "arkivet skapades på en maskin med större heltal, en del operationer kan misslyckas" + +#: pg_backup_archiver.c:3821 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "förväntat format (%d) skiljer sig från formatet som fanns i filen (%d)" + +#: pg_backup_archiver.c:3837 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "arkivet är komprimerat, men denna installation stödjer inte komprimering -- ingen data kommer kunna läsas" + +#: pg_backup_archiver.c:3855 +#, c-format +msgid "invalid creation date in header" +msgstr "ogiltig skapandedatum i huvud" + +#: pg_backup_archiver.c:3983 +#, c-format +msgid "processing item %d %s %s" +msgstr "processar objekt %d %s %s" + +#: pg_backup_archiver.c:4062 +#, c-format +msgid "entering main parallel loop" +msgstr "går in i parallella huvudloopen" + +#: pg_backup_archiver.c:4073 +#, c-format +msgid "skipping item %d %s %s" +msgstr "hoppar över objekt %d %s %s" + +#: pg_backup_archiver.c:4082 +#, c-format +msgid "launching item %d %s %s" +msgstr "startar objekt %d %s %s" + +#: pg_backup_archiver.c:4136 +#, c-format +msgid "finished main parallel loop" +msgstr "klar med parallella huvudloopen" + +#: pg_backup_archiver.c:4172 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "processar saknat objekt %d %s %s" + +#: pg_backup_archiver.c:4777 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "tabell \"%s\" kunde inte skapas, dess data kommer ej återställas" + +#: pg_backup_custom.c:378 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "ogiltig OID för stort objekt" + +#: pg_backup_custom.c:441 pg_backup_custom.c:507 pg_backup_custom.c:632 +#: pg_backup_custom.c:870 pg_backup_tar.c:1086 pg_backup_tar.c:1091 +#, c-format +msgid "error during file seek: %m" +msgstr "fel vid sökning: %m" + +#: pg_backup_custom.c:480 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "datablock %d har fel sökposition" + +#: pg_backup_custom.c:497 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "känner inte igen datablocktyp (%d) vid genomsökning av arkiv" + +#: pg_backup_custom.c:519 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "kunde inte hitta block ID %d i arkiv -- kanske på grund av en återställningbegäran i oordning vilket inte kan hanteras då inputfilen inte är sökbar" + +#: pg_backup_custom.c:524 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "kunde inte hitta block ID %d i arkiv -- möjligen ett trasigt arkiv" + +#: pg_backup_custom.c:531 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "hittade oväntat block-ID (%d) vid läsning av data -- förväntade %d" + +#: pg_backup_custom.c:545 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "ej igenkänd datablockstyp %d vid återställande av arkiv" + +#: pg_backup_custom.c:648 +#, c-format +msgid "could not read from input file: %m" +msgstr "kunde inte läsa från infilen: %m" + +#: pg_backup_custom.c:751 pg_backup_custom.c:803 pg_backup_custom.c:948 +#: pg_backup_tar.c:1089 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "kunde inte bestämma sökposition i arkivfil: %m" + +#: pg_backup_custom.c:767 pg_backup_custom.c:807 +#, c-format +msgid "could not close archive file: %m" +msgstr "kan inte stänga arkivfilen: %m" + +#: pg_backup_custom.c:790 +#, c-format +msgid "can only reopen input archives" +msgstr "kan inte återöppna indataarkiven" + +#: pg_backup_custom.c:797 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "parallell återställning från standard in stöds inte" + +#: pg_backup_custom.c:799 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "parallell återställning för en icke sökbar fil stöds inte" + +#: pg_backup_custom.c:815 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "kunde inte söka till rätt position i arkivfilen: %m" + +#: pg_backup_custom.c:894 +#, c-format +msgid "compressor active" +msgstr "komprimerare aktiv" + +#: pg_backup_db.c:41 +#, c-format +msgid "could not get server_version from libpq" +msgstr "kunde inte hämta serverversionen från libpq" + +#: pg_backup_db.c:52 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "server version: %s; %s version: %s" + +#: pg_backup_db.c:54 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "avbryter då serverversionerna i matchar" + +#: pg_backup_db.c:124 +#, c-format +msgid "already connected to a database" +msgstr "är redan uppkopplad mot en databas" + +#: pg_backup_db.c:133 pg_backup_db.c:185 pg_dumpall.c:1651 pg_dumpall.c:1764 +msgid "Password: " +msgstr "Lösenord: " + +#: pg_backup_db.c:177 +#, c-format +msgid "could not connect to database" +msgstr "kunde inte ansluta till databasen" + +#: pg_backup_db.c:195 +#, c-format +msgid "reconnection to database \"%s\" failed: %s" +msgstr "återuppkoppling mot databas \"%s\" misslyckades: %s" + +#: pg_backup_db.c:199 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "uppkoppling mot databas \"%s\" misslyckades: %s" + +#: pg_backup_db.c:272 pg_dumpall.c:1684 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:279 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "fråga misslyckades: %s" + +#: pg_backup_db.c:281 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "frågan var: %s" + +#: pg_backup_db.c:322 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "fråga gav %d rad istället för en: %s" +msgstr[1] "fråga gav %d rader istället för en: %s" + +#: pg_backup_db.c:358 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s: %sKommandot var: %s" + +#: pg_backup_db.c:414 pg_backup_db.c:488 pg_backup_db.c:495 +msgid "could not execute query" +msgstr "kunde inte utföra fråga" + +#: pg_backup_db.c:467 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "fel returnerat av PQputCopyData: %s" + +#: pg_backup_db.c:516 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "fel returnerat av PQputCopyEnd: %s" + +#: pg_backup_db.c:522 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "COPY misslyckades för tabell \"%s\": %s" + +#: pg_backup_db.c:528 pg_dump.c:1988 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "oväntade extraresultat under kopiering (COPY) av tabell \"%s\"" + +#: pg_backup_db.c:540 +msgid "could not start database transaction" +msgstr "kunde inte starta databastransaktionen" + +#: pg_backup_db.c:548 +msgid "could not commit database transaction" +msgstr "kunde inte genomföra databastransaktionen" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "ingen utdatakatalog angiven" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "kunde inte skapa katalog \"%s\": %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "kunde inte skriva till utdatafil: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "kan inte stänga datafil \"%s\": %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "kunde inte öppna stora objekts TOC-fil \"%s\" för läsning: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "ogiltig rad i stora objekts TOC-fil \"%s\": \"%s\"" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "fel vid lösning av stora objekts TOC-fil \"%s\"" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "kunde inte stänga stora objekts TOC-fil \"%s\": %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "kunde inte skriva till blobbars TOC-fil" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "filnamnet är för långt: \"%s\"" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "detta format kan inte läsas" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "kunde inte öppna TOC-filen \"%s\" för utmatning: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "kunde inte öppna TOC-filen för utmatning: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:358 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "komprimering är stödjs inte av arkivformatet tar" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "kunde inte öppna TOC-fil \"%s\" för läsning: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "kunde inte öppna TOC-fil för läsning: %m" + +#: pg_backup_tar.c:344 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "kunde inte hitta fil \"%s\" i arkiv" + +#: pg_backup_tar.c:410 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "kunde inte generera temporärt filnamn: %m" + +#: pg_backup_tar.c:421 +#, c-format +msgid "could not open temporary file" +msgstr "kunde inte öppna temporär fil" + +#: pg_backup_tar.c:448 +#, c-format +msgid "could not close tar member" +msgstr "kunde inte stänga tar-medlem" + +#: pg_backup_tar.c:691 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "oväntad COPY-satssyntax: \"%s\"" + +#: pg_backup_tar.c:958 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "ogiltig OID för stort objekt (%u)" + +#: pg_backup_tar.c:1105 +#, c-format +msgid "could not close temporary file: %m" +msgstr "kunde inte stänga temporär fil: %m" + +#: pg_backup_tar.c:1114 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "verklig fillängd (%s) matchar inte det förväntade (%s)" + +#: pg_backup_tar.c:1171 pg_backup_tar.c:1201 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "kunde inte hitta filhuvud för fil \"%s\" i tar-arkiv" + +#: pg_backup_tar.c:1189 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "dumpa data i oordning stöds inte av detta arkivformat: \"%s\" krävs, men kommer före \"%s\" i denna arkivfil." + +#: pg_backup_tar.c:1234 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "inkomplett tar-huvud hittat (%lu byte)" +msgstr[1] "inkomplett tar-huvud hittat (%lu bytes)" + +#: pg_backup_tar.c:1285 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "trasigt tar-huvud hittat i %s (förväntade %d, beräknad %d) filposition %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "okänt sektionsnamn: \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:607 pg_dump.c:624 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "slut på on_exit_nicely-slottar" + +#: pg_dump.c:533 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "komprimeringsnivå måste vara i intervallet 0..9" + +#: pg_dump.c:571 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits måste vara i intervallet -15..3" + +#: pg_dump.c:594 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insert måste vara i intervallet %d..%d" + +#: pg_dump.c:622 pg_dumpall.c:346 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för många kommandoradsargument (första är \"%s\")" + +#: pg_dump.c:643 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "flaggorna \"bara schema\" (-s) och \"bara data\" (-a) kan inte användas tillsammans" + +#: pg_dump.c:648 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "flaggorna -s/--schema-only och --include-foreign-data kan inte användas tillsammans" + +#: pg_dump.c:651 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "flaggan --include-foreign-data stöds inte med parallell backup" + +#: pg_dump.c:655 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "flaggorna \"nollställ\" (-c) och \"bara data\" (-a) kan inte användas tillsammans" + +#: pg_dump.c:660 pg_dumpall.c:381 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "flaggan --if-exists kräver flaggan -c/--clean" + +#: pg_dump.c:667 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "flagga --on-conflict-do-nothing kräver --inserts, --rows-per-insert eller --column-inserts" + +#: pg_dump.c:689 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "efterfrågad komprimering finns inte i denna installation -- arkivet kommer sparas okomprimerat" + +#: pg_dump.c:710 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "felaktigt antal parallella job" + +#: pg_dump.c:714 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "parallell backup stöds bara med katalogformat" + +#: pg_dump.c:769 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Synkroniseringssnapshots stöds inte av denna serverversion.\n" +"Kör med --no-synchronized-snapshots istället om du inte kräver\n" +"synkroniserade snapshots." + +#: pg_dump.c:775 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Exporterade snapshots stöds inte i denna serverversion." + +#: pg_dump.c:787 +#, c-format +msgid "last built-in OID is %u" +msgstr "sista inbyggda OID är %u" + +#: pg_dump.c:796 +#, c-format +msgid "no matching schemas were found" +msgstr "hittade inga matchande scheman" + +#: pg_dump.c:810 +#, c-format +msgid "no matching tables were found" +msgstr "hittade inga matchande tabeller" + +#: pg_dump.c:990 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s dumpar en databas som en textfil eller i andra format.\n" +"\n" + +#: pg_dump.c:991 pg_dumpall.c:617 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Användning:\n" + +#: pg_dump.c:992 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [FLAGGA]... [DBNAMN]\n" + +#: pg_dump.c:994 pg_dumpall.c:620 pg_restore.c:465 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Allmänna flaggor:\n" + +#: pg_dump.c:995 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=FILENAME fil eller katalognamn för utdata\n" + +#: pg_dump.c:996 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p utdatans filformat (egen (c), katalog (d), tar (t),\n" +" ren text (p) (standard))\n" + +#: pg_dump.c:998 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=NUM använd så här många parellella job för att dumpa\n" + +#: pg_dump.c:999 pg_dumpall.c:622 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose visa mer information\n" + +#: pg_dump.c:1000 pg_dumpall.c:623 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: pg_dump.c:1001 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 komprimeringsnivå för komprimerade format\n" + +#: pg_dump.c:1002 pg_dumpall.c:624 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " --lock-wait-timeout=TIMEOUT misslyckas efter att ha väntat i TIMEOUT på tabellås\n" + +#: pg_dump.c:1003 pg_dumpall.c:651 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync vänta inte på att ändingar säkert skrivits till disk\n" + +#: pg_dump.c:1004 pg_dumpall.c:625 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denna hjälp, avsluta sedan\n" + +#: pg_dump.c:1006 pg_dumpall.c:626 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Flaggor som styr utmatning:\n" + +#: pg_dump.c:1007 pg_dumpall.c:627 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only dumpa bara data, inte schema\n" + +#: pg_dump.c:1008 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs inkludera stora objekt i dumpen\n" + +#: pg_dump.c:1009 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs exkludera stora objekt i dumpen\n" + +#: pg_dump.c:1010 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, --clean nollställ (drop) databasobjekt innan återskapande\n" + +#: pg_dump.c:1011 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr " -C, --create inkludera kommandon för att skapa databasen i dumpen\n" + +#: pg_dump.c:1012 pg_dumpall.c:629 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=KODNING dumpa data i teckenkodning KODNING\n" + +#: pg_dump.c:1013 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=MALL dumpa bara de angivna scheman\n" + +#: pg_dump.c:1014 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=MALL dumpa INTE de angivna scheman\n" + +#: pg_dump.c:1015 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner hoppa över återställande av objektägare i\n" +" textformatdumpar\n" + +#: pg_dump.c:1017 pg_dumpall.c:633 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only dumpa bara scheman, inte data\n" + +#: pg_dump.c:1018 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, --superuser=NAME superanvändarens namn för textformatdumpar\n" + +#: pg_dump.c:1019 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=MALL dumpa bara de angivna tabellerna\n" + +#: pg_dump.c:1020 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=MALL dumpa INTE de angivna tabellerna\n" + +#: pg_dump.c:1021 pg_dumpall.c:636 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges dumpa inte rättigheter (grant/revoke)\n" + +#: pg_dump.c:1022 pg_dumpall.c:637 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade används bara av uppgraderingsverktyg\n" + +#: pg_dump.c:1023 pg_dumpall.c:638 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr " --column-inserts dumpa data som INSERT med kolumnnamn\n" + +#: pg_dump.c:1024 pg_dumpall.c:639 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr " --disable-dollar-quoting slå av dollar-citering, använd standard SQL-citering\n" + +#: pg_dump.c:1025 pg_dumpall.c:640 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr " --disable-triggers slå av utlösare vid återställning av enbart data\n" + +#: pg_dump.c:1026 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security slå på radsäkerhet (dumpa bara data användaren\n" +" har rätt till)\n" + +#: pg_dump.c:1028 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " --exclude-table-data=MALL dumpa INTE data för de angivna tabellerna\n" + +#: pg_dump.c:1029 pg_dumpall.c:642 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM övertrumfa standardinställningen för extra_float_digits\n" + +#: pg_dump.c:1030 pg_dumpall.c:643 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists använd IF EXISTS när objekt droppas\n" + +#: pg_dump.c:1031 +#, c-format +msgid "" +" --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr "" +" --include-foreign-data=MALL\n" +" inkludera data i främmande tabeller från\n" +" främmande servrar som matchar MALL\n" + +#: pg_dump.c:1034 pg_dumpall.c:644 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr " --inserts dumpa data som INSERT, istället för COPY\n" + +#: pg_dump.c:1035 pg_dumpall.c:645 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root ladda partitioner via root-tabellen\n" + +#: pg_dump.c:1036 pg_dumpall.c:646 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments dumpa inte kommentarer\n" + +#: pg_dump.c:1037 pg_dumpall.c:647 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications dumpa inte publiceringar\n" + +#: pg_dump.c:1038 pg_dumpall.c:649 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels dumpa inte tilldelning av säkerhetsetiketter\n" + +#: pg_dump.c:1039 pg_dumpall.c:650 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions dumpa inte prenumereringar\n" + +#: pg_dump.c:1040 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr " --no-synchronized-snapshots använd inte synkroniserade snapshots i parallella job\n" + +#: pg_dump.c:1041 pg_dumpall.c:652 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces dumpa inte användning av tabellutymmen\n" + +#: pg_dump.c:1042 pg_dumpall.c:653 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data dumpa inte ologgad tabelldata\n" + +#: pg_dump.c:1043 pg_dumpall.c:654 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing addera ON CONFLICT DO NOTHING till INSERT-kommandon\n" + +#: pg_dump.c:1044 pg_dumpall.c:655 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr " --quote-all-identifiers citera alla identifierar, även om de inte är nyckelord\n" + +#: pg_dump.c:1045 pg_dumpall.c:656 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NRADER antal rader per INSERT; implicerar --inserts\n" + +#: pg_dump.c:1046 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr " --section=SEKTION dumpa namngiven sektion (pre-data, data eller post-data)\n" + +#: pg_dump.c:1047 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr " --serializable-deferrable wait until the dump can run without anomalies\n" + +#: pg_dump.c:1048 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT använda namngivet snapshot för att dumpa\n" + +#: pg_dump.c:1049 pg_restore.c:504 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names kräv att mallar för tabeller och/eller scheman matchar\n" +" minst en sak var\n" + +#: pg_dump.c:1051 pg_dumpall.c:657 pg_restore.c:506 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" använd kommandot SET SESSION AUTHORIZATION istället för\n" +" kommandot ALTER OWNER för att sätta ägare\n" + +#: pg_dump.c:1055 pg_dumpall.c:661 pg_restore.c:510 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Flaggor för anslutning:\n" + +#: pg_dump.c:1056 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=DBNAMN databasens som skall dumpas\n" + +#: pg_dump.c:1057 pg_dumpall.c:663 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=VÄRDNAMN databasens värdnamn eller socketkatalog\n" + +#: pg_dump.c:1058 pg_dumpall.c:665 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT databasens värdport\n" + +#: pg_dump.c:1059 pg_dumpall.c:666 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAMN anslut med datta användarnamn mot databasen\n" + +#: pg_dump.c:1060 pg_dumpall.c:667 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password fråga aldrig efter lösenord\n" + +#: pg_dump.c:1061 pg_dumpall.c:668 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password fråga om lösenord (borde ske automatiskt)\n" + +#: pg_dump.c:1062 pg_dumpall.c:669 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROLLNAMN gör SET ROLE innan dumpen\n" + +#: pg_dump.c:1064 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Om inget databasnamn anges, då kommer värdet i omgivningsvariabel\n" +"PGDATABASE att användas.\n" +"\n" + +#: pg_dump.c:1066 pg_dumpall.c:673 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Rapportera fel till <%s>.\n" + +#: pg_dump.c:1067 pg_dumpall.c:674 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "hemsida för %s: <%s>\n" + +#: pg_dump.c:1086 pg_dumpall.c:499 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "ogiltig klientteckenkodning \"%s\" angiven" + +#: pg_dump.c:1232 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Synkroniserade snapshots på standby-servrar stöds inte av denna serverversion.\n" +"Kör med --no-synchronized-snapshots istället om du inte behöver\n" +"synkroniserade snapshots." + +#: pg_dump.c:1301 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "ogiltigt utdataformat \"%s\" angivet" + +#: pg_dump.c:1339 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "hittade inga matchande scheman för mallen \"%s\"" + +#: pg_dump.c:1386 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "hittade inga matchande främmande servrar för mallen \"%s\"" + +#: pg_dump.c:1449 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "hittade inga matchande tabeller för mallen \"%s\"" + +#: pg_dump.c:1862 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "dumpar innehållet i tabell \"%s.%s\"" + +#: pg_dump.c:1969 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Dumpning av innehållet i tabellen \"%s\" misslyckades: PQendcopy() misslyckades." + +#: pg_dump.c:1970 pg_dump.c:1980 +#, c-format +msgid "Error message from server: %s" +msgstr "Felmeddelandet från servern: %s" + +#: pg_dump.c:1971 pg_dump.c:1981 +#, c-format +msgid "The command was: %s" +msgstr "Kommandot var: %s" + +#: pg_dump.c:1979 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Dumpning av innehållet i tabellen \"%s\" misslyckades: PQgetResult() misslyckades." + +#: pg_dump.c:2739 +#, c-format +msgid "saving database definition" +msgstr "sparar databasdefinition" + +#: pg_dump.c:3211 +#, c-format +msgid "saving encoding = %s" +msgstr "sparar kodning = %s" + +#: pg_dump.c:3236 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "sparar standard_conforming_strings = %s" + +#: pg_dump.c:3275 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "kunde inte parsa resultat från current_schemas()" + +#: pg_dump.c:3294 +#, c-format +msgid "saving search_path = %s" +msgstr "sparar search_path = %s" + +#: pg_dump.c:3334 +#, c-format +msgid "reading large objects" +msgstr "läser stora objekt" + +#: pg_dump.c:3516 +#, c-format +msgid "saving large objects" +msgstr "sparar stora objekt" + +#: pg_dump.c:3562 +#, c-format +msgid "error reading large object %u: %s" +msgstr "fel vid läsning av stort objekt %u: %s" + +#: pg_dump.c:3614 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "läser aktiverad radsäkerhet för tabell \"%s.%s\"" + +#: pg_dump.c:3645 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "läser policys för tabell \"%s.%s\"" + +#: pg_dump.c:3797 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "oväntad kommandotyp för policy: %c" + +#: pg_dump.c:3948 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "ägare av publicering \"%s\" verkar vara ogiltig" + +#: pg_dump.c:4093 +#, c-format +msgid "reading publication membership for table \"%s.%s\"" +msgstr "läser publiceringsmedlemskap för tabell \"%s.%s\"" + +#: pg_dump.c:4236 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "prenumerationer har inte dumpats få aktuell användare inte är en superanvändare" + +#: pg_dump.c:4290 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "ägare av prenumeration \"%s\" verkar vara ogiltig" + +#: pg_dump.c:4334 +#, c-format +msgid "could not parse subpublications array" +msgstr "kunde inte parsa arrayen för subpubliceringar" + +#: pg_dump.c:4656 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "kunde inte hitta föräldrautökning för %s %s" + +#: pg_dump.c:4788 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "ägare av schema \"%s\" verkar vara ogiltig" + +#: pg_dump.c:4811 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "schema med OID %u existerar inte" + +#: pg_dump.c:5136 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "ägare av datatyp \"%s\" verkar vara ogiltig" + +#: pg_dump.c:5221 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "ägare av operator \"%s\" verkar vara ogiltig" + +#: pg_dump.c:5523 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "ägare av operatorklass \"%s\" verkar vara ogiltig" + +#: pg_dump.c:5607 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "ägare av operator-familj \"%s\" verkar vara ogiltig" + +#: pg_dump.c:5776 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "ägare av aggregatfunktion \"%s\" verkar vara ogiltig" + +#: pg_dump.c:6036 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "ägare av funktion \"%s\" verkar vara ogiltig" + +#: pg_dump.c:6864 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "ägare av tabell \"%s\" verkar vara ogiltig" + +#: pg_dump.c:6906 pg_dump.c:17386 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "misslyckades med riktighetskontroll, föräldratabell med OID %u för sekvens med OID %u hittas inte" + +#: pg_dump.c:7048 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "läser index för tabell \"%s.%s\"" + +#: pg_dump.c:7463 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "läser främmande nyckel-villkor för tabell \"%s.%s\"" + +#: pg_dump.c:7744 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "misslyckades med riktighetskontroll, föräldratabell med OID %u för pg_rewrite-rad med OID %u hittades inte" + +#: pg_dump.c:7827 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "läser utlösare för tabell \"%s.%s\"" + +#: pg_dump.c:7960 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "fråga producerade null som refererad tabell för främmande nyckel-utlösare \"%s\" i tabell \"%s\" (OID för tabell : %u)" + +#: pg_dump.c:8515 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "hittar kolumner och typer för tabell \"%s.%s\"" + +#: pg_dump.c:8651 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "ogiltigt kolumnnumrering i tabell \"%s\"" + +#: pg_dump.c:8688 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "hittar default-uttryck för tabell \"%s.%s\"" + +#: pg_dump.c:8710 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "felaktigt adnum-värde %d för tabell \"%s\"" + +#: pg_dump.c:8775 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "hittar check-villkor för tabell \"%s.%s\"" + +#: pg_dump.c:8824 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "förväntade %d check-villkor för tabell \"%s\" men hittade %d" +msgstr[1] "förväntade %d check-villkor för tabell \"%s\" men hittade %d" + +#: pg_dump.c:8828 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(systemkatalogerna kan vara trasiga.)" + +#: pg_dump.c:10414 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "typtype för datatyp \"%s\" verkar vara ogiltig" + +#: pg_dump.c:11768 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "felaktigt värde i arrayen proargmodes" + +#: pg_dump.c:12140 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "kunde inte tolka arrayen proallargtypes" + +#: pg_dump.c:12156 +#, c-format +msgid "could not parse proargmodes array" +msgstr "kunde inte tolka arrayen proargmodes" + +#: pg_dump.c:12170 +#, c-format +msgid "could not parse proargnames array" +msgstr "kunde inte tolka arrayen proargnames" + +#: pg_dump.c:12181 +#, c-format +msgid "could not parse proconfig array" +msgstr "kunde inte tolka arrayen proconfig" + +#: pg_dump.c:12261 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "okänt provolatile-värde för funktion \"%s\"" + +#: pg_dump.c:12311 pg_dump.c:14369 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "okänt proparallel-värde för funktion \"%s\"" + +#: pg_dump.c:12450 pg_dump.c:12559 pg_dump.c:12566 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "kunde inte hitta funktionsdefinitionen för funktion med OID %u" + +#: pg_dump.c:12489 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "felaktigt värde i fältet pg_cast.castfunc eller pg_cast.castmethod" + +#: pg_dump.c:12492 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "felaktigt värde i fältet pg_cast.castmethod" + +#: pg_dump.c:12585 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "felaktig transform-definition, minst en av trffromsql och trftosql måste vara ickenoll" + +#: pg_dump.c:12602 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "felaktigt värde i fältet pg_transform.trffromsql" + +#: pg_dump.c:12623 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "felaktigt värde i fältet pg_transform.trftosql" + +#: pg_dump.c:12939 +#, c-format +msgid "could not find operator with OID %s" +msgstr "kunde inte hitta en operator med OID %s." + +#: pg_dump.c:13007 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "ogiltig typ \"%c\" för accessmetod \"%s\"" + +#: pg_dump.c:13761 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "okänd jämförelseleverantör: %s" + +#: pg_dump.c:14233 +#, c-format +msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +msgstr "aggregatfunktion %s kunde inte dumpas korrekt för denna databasversion; ignorerad" + +#: pg_dump.c:14288 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "okänt aggfinalmodify-värde för aggregat \"%s\"" + +#: pg_dump.c:14344 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "okänt aggmfinalmodify-värde för aggregat \"%s\"" + +#: pg_dump.c:15066 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "okänd objekttyp i standardrättigheter: %d" + +#: pg_dump.c:15084 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "kunde inte parsa standard-ACL-lista (%s)" + +#: pg_dump.c:15169 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "kunde inte parsa initial GRANT ACL-lista (%s) eller initial REVOKE ACL-lista (%s) för objekt \"%s\" (%s)" + +#: pg_dump.c:15177 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "kunde inte parsa GRANT ACL-lista (%s) eller REVOKE ACL-lista (%s) för objekt \"%s\" (%s)" + +#: pg_dump.c:15692 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "fråga för att hämta definition av vy \"%s\" returnerade ingen data" + +#: pg_dump.c:15695 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "fråga för att hämta definition av vy \"%s\" returnerade mer än en definition" + +#: pg_dump.c:15702 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "definition av vy \"%s\" verkar vara tom (längd noll)" + +#: pg_dump.c:15786 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS stöds inte längre (tabell \"%s\")" + +#: pg_dump.c:16266 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "ogiltigt antal (%d) föräldrar för tabell \"%s\"" + +#: pg_dump.c:16589 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "ogiltigt kolumnnummer %d för tabell \"%s\"" + +#: pg_dump.c:16874 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "saknar index för integritetsvillkor \"%s\"" + +#: pg_dump.c:17099 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "oväntad integritetsvillkorstyp: %c" + +#: pg_dump.c:17231 pg_dump.c:17451 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "fråga för att hämta data för sekvens \"%s\" returnerade %d rad (förväntade 1)" +msgstr[1] "fråga för att hämta data för sekvens \"%s\" returnerade %d rader (förväntade 1)" + +#: pg_dump.c:17265 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "okänd sekvenstyp: %s" + +#: pg_dump.c:17549 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "oväntat tgtype-värde: %d" + +#: pg_dump.c:17623 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "felaktig argumentsträng (%s) för utlösare \"%s\" i tabell \"%s\"" + +#: pg_dump.c:17859 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "fråga för att hämta regel \"%s\" för tabell \"%s\" misslyckades: fel antal rader returnerades" + +#: pg_dump.c:18021 +#, c-format +msgid "could not find referenced extension %u" +msgstr "kunde inte hitta refererad utökning %u" + +#: pg_dump.c:18233 +#, c-format +msgid "reading dependency data" +msgstr "läser beroendedata" + +#: pg_dump.c:18326 +#, c-format +msgid "no referencing object %u %u" +msgstr "inget refererande objekt %u %u" + +#: pg_dump.c:18337 +#, c-format +msgid "no referenced object %u %u" +msgstr "inget refererat objekt %u %u" + +#: pg_dump.c:18710 +#, c-format +msgid "could not parse reloptions array" +msgstr "kunde inte parsa arrayen reloptions" + +#: pg_dump_sort.c:360 +#, c-format +msgid "invalid dumpId %d" +msgstr "ogiltigt dumpId %d" + +#: pg_dump_sort.c:366 +#, c-format +msgid "invalid dependency %d" +msgstr "ogiltigt beroende %d" + +#: pg_dump_sort.c:599 +#, c-format +msgid "could not identify dependency loop" +msgstr "kunde inte fastställa beroendeloop" + +#: pg_dump_sort.c:1170 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "det finns cirkulära främmande nyckelberoenden för denna tabell:" +msgstr[1] "det finns cirkulära främmande nyckelberoenden för dessa tabeller:" + +#: pg_dump_sort.c:1174 pg_dump_sort.c:1194 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1175 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Du kan eventiellt inte återställa dumpen utan att använda --disable-triggers eller temporärt droppa vilkoren." + +#: pg_dump_sort.c:1176 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Överväg att göra en full dump istället för --data-only för att undvika detta problem." + +#: pg_dump_sort.c:1188 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "kunde inte räta ut beroendeloopen för dessa saker:" + +#: pg_dumpall.c:199 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Programmet \"%s\" behövs av %s men hittades inte i samma\n" +"katalog som \"%s\".\n" +"Kontrollera din installation." + +#: pg_dumpall.c:204 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Programmet \"%s\" hittades av \"%s\"\n" +"men är inte av samma version som %s.\n" +"Kontrollera din installation." + +#: pg_dumpall.c:356 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "flaggan --exclude-database kan inte användas tillsammans med -g/--globals-only, -r/--roles-only eller -t/--tablespaces-only" + +#: pg_dumpall.c:365 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "flaggorna \"bara gobala\" (-g) och \"bara roller\" (-r) kan inte användas tillsammans" + +#: pg_dumpall.c:373 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "flaggorna \"bara globala\" (-g) och \"bara tabellutrymmen\" (-t) kan inte användas tillsammans" + +#: pg_dumpall.c:387 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "flaggorna \"bara roller\" (-r) och \"bara tabellutrymmen\" (-t) kan inte användas tillsammans" + +#: pg_dumpall.c:448 pg_dumpall.c:1754 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "kunde inte ansluta till databasen \"%s\"" + +#: pg_dumpall.c:462 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"kunde inte ansluta till databasen \"postgres\" eller \"template1\"\n" +"Ange en annan databas." + +#: pg_dumpall.c:616 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s extraherar ett PostgreSQL databaskluster till en SQL-scriptfil.\n" +"\n" + +#: pg_dumpall.c:618 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [FLAGGA]...\n" + +#: pg_dumpall.c:621 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=FILENAME utdatafilnamn\n" + +#: pg_dumpall.c:628 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, --clean nollställ (drop) databaser innan återskapning\n" + +#: pg_dumpall.c:630 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, --globals-only dumpa bara globala objekt, inte databaser\n" + +#: pg_dumpall.c:631 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner återställ inte objektägare\n" + +#: pg_dumpall.c:632 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr " -r, --roles-only dumpa endast roller, inte databaser eller tabellutrymmen\n" + +#: pg_dumpall.c:634 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, --superuser=NAMN superanvändarens namn för användning i dumpen\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr " -t, --tablespaces-only dumpa endasdt tabellutrymmen, inte databaser eller roller\n" + +#: pg_dumpall.c:641 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=MALL uteslut databaser vars namn matchar MALL\n" + +#: pg_dumpall.c:648 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords dumpa inte lösenord för roller\n" + +#: pg_dumpall.c:662 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=ANSLSTR anslut med anslutningssträng\n" + +#: pg_dumpall.c:664 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=DBNAMN alternativ standarddatabas\n" + +#: pg_dumpall.c:671 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"Om -f/--file inte används så kommer SQL-skriptet skriva till standard ut.\n" +"\n" + +#: pg_dumpall.c:877 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "rollnamn som startar med \"pg_\" hoppas över (%s)" + +#: pg_dumpall.c:1278 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "kunde inte tolka ACL-listan (%s) för tabellutrymme \"%s\"" + +#: pg_dumpall.c:1495 +#, c-format +msgid "excluding database \"%s\"" +msgstr "utesluter databas \"%s\"" + +#: pg_dumpall.c:1499 +#, c-format +msgid "dumping database \"%s\"" +msgstr "dumpar databas \"%s\"" + +#: pg_dumpall.c:1531 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump misslyckades med databas \"%s\", avslutar" + +#: pg_dumpall.c:1540 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "kunde inte öppna om utdatafilen \"%s\": %m" + +#: pg_dumpall.c:1584 +#, c-format +msgid "running \"%s\"" +msgstr "kör \"%s\"" + +#: pg_dumpall.c:1775 +#, c-format +msgid "could not connect to database \"%s\": %s" +msgstr "kunde inte ansluta till databasen \"%s\": %s" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "kunde inte hämta serverversionen" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "kunde inte tolka versionsträngen \"%s\"" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "kör: %s" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "en av flaggorna -d/--dbname och -f/--file måste anges" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "flaggorna -d/--dbname och -f/--file kan inte användas ihop" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "flaggorna -C/--create och -1/--single-transaction kan inte användas tillsammans" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "maximalt antal parallella job är %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "kan inte ange både --single-transaction och multipla job" + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "okänt arkivformat \"%s\"; vänligen ange \"c\", \"d\" eller \"t\"" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "fel ignorerade vid återställande: %d" + +#: pg_restore.c:461 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s återställer en PostgreSQL-databas från ett arkiv skapat av pg_dump.\n" +"\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [FLAGGA]... [FIL]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=NAMN koppla upp med databasnamn\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=FILNAMN utdatafilnamn (- för stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, --format=c|d|t backupens filformat (bör ske automatiskt)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list skriv ut summerad TOC för arkivet\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose visa mer information\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denna hjälp, avsluta sedan\n" + +#: pg_restore.c:474 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Flaggor som styr återställning:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only återställ bara data, inte scheman\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create skapa måldatabasen\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, --exit-on-error avsluta vid fel, standard är att fortsätta\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=NAMN återställ namngivet index\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, --jobs=NUM använda så här många parallella job för återställning\n" + +#: pg_restore.c:481 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=FILNAMN använd innehållsförteckning från denna fil för\n" +" att välja/sortera utdata\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NAMN återställ enbart objekt i detta schema\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NAMN återställ inte objekt i detta schema\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NAMN(arg) återställ namngiven funktion\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only återställ bara scheman, inte data\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr " -S, --superuser=NAMN superanvändarens namn för att slå av utlösare\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=NAMN återställ namngiven relation (tabell, vy, osv.)\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=NAMN återställ namngiven utlösare\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, --no-privileges återställ inte åtkomsträttigheter (grant/revoke)\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction återställ i en enda transaktion\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security aktivera radsäkerhet\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments återställ inte kommentarer\n" + +#: pg_restore.c:497 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables återställ inte data för tabeller som\n" +" inte kunde skapas\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications återställ inte publiceringar\n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels återställ inte säkerhetsetiketter\n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions återställ inte prenumerationer\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces återställ inte användning av tabellutymmen\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr " --section=SEKTION återställ namngiven sektion (pre-data, data eller post-data)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROLENAME gör SET ROLE innan återställning\n" + +#: pg_restore.c:518 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"Flaggorna -I, -n, -N, -P, -t, -T och --section kan kombineras och anges\n" +"många gånger för att välja flera objekt.\n" + +#: pg_restore.c:521 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"Om inget indatafilnamn är angivet, så kommer standard in att användas.\n" +"\n" + +#~ msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +#~ msgstr "kunde inte hitta block ID %d i arkiv -- kanske på grund av en återställningbegäran i oordning vilket inte kan hanteras då det saknas dataoffsets i arkivet" + +#~ msgid "ftell mismatch with expected position -- ftell used" +#~ msgstr "ftell stämmer inte med förväntad position -- ftell använd" + +#~ msgid "" +#~ "The program \"pg_dump\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Programmet \"pg_dump\" hittades av \"%s\"\n" +#~ "men hade inte samma version som \"%s\".\n" +#~ "Kontrollera din installation." + +#~ msgid "" +#~ "The program \"pg_dump\" is needed by %s but was not found in the\n" +#~ "same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Programmet \"pg_dump\" behövs av %s men kunde inte hittas i samma katalog\n" +#~ "som \"%s\".\n" +#~ "Kontrollera din installation." + +#~ msgid "internal error -- neither th nor fh specified in _tarReadRaw()" +#~ msgstr "internt fel -- varken th eller fh angiven i _tarReadRaw()" + +#~ msgid "connection needs password" +#~ msgstr "anslutningen kräver lösenord" + +#~ msgid "could not reconnect to database: %s" +#~ msgstr "kunde inte återuppkoppla mot databasen: %s" + +#~ msgid "could not reconnect to database" +#~ msgstr "kunde inte återuppkoppla mot databasen" + +#~ msgid "connecting to database \"%s\" as user \"%s\"" +#~ msgstr "kopplar upp mot databas \"%s\" som användare \"%s\"" diff --git a/src/bin/pg_dump/po/uk.po b/src/bin/pg_dump/po/uk.po new file mode 100644 index 000000000000..a774aa116c89 --- /dev/null +++ b/src/bin/pg_dump/po/uk.po @@ -0,0 +1,2622 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:16+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: pasha_golub\n" +"Language-Team: Ukrainian\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_dump.pot\n" +"X-Crowdin-File-ID: 500\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не вдалося визначити поточний каталог: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "невірний бінарний файл \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "неможливо прочитати бінарний файл \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "неможливо знайти \"%s\" для виконання" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не вдалося змінити каталог на \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не можливо прочитати символічне послання \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "помилка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +msgid "out of memory" +msgstr "недостатньо пам'яті" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "недостатньо пам'яті\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "неможливо виконати команду" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "команду не знайдено" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "дочірній процес завершився з кодом виходу %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "дочірній процес перервано через помилку 0х%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "дочірній процес перервано через сигнал %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "дочірній процес завершився з невизнаним статусом %d" + +#: common.c:121 +#, c-format +msgid "reading extensions" +msgstr "читання розширень" + +#: common.c:125 +#, c-format +msgid "identifying extension members" +msgstr "ідентифікація членів розширення" + +#: common.c:128 +#, c-format +msgid "reading schemas" +msgstr "читання схемів" + +#: common.c:138 +#, c-format +msgid "reading user-defined tables" +msgstr "читання користувацьких таблиць" + +#: common.c:145 +#, c-format +msgid "reading user-defined functions" +msgstr "читання користувацьких функцій" + +#: common.c:150 +#, c-format +msgid "reading user-defined types" +msgstr "читання користувацьких типів" + +#: common.c:155 +#, c-format +msgid "reading procedural languages" +msgstr "читання процедурних мов" + +#: common.c:158 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "читання користувацьких агрегатних функцій" + +#: common.c:161 +#, c-format +msgid "reading user-defined operators" +msgstr "читання користувацьких операторів" + +#: common.c:165 +#, c-format +msgid "reading user-defined access methods" +msgstr "читання користувацьких методів доступу" + +#: common.c:168 +#, c-format +msgid "reading user-defined operator classes" +msgstr "читання користувацьких класів операторів" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator families" +msgstr "читання користувацьких сімейств операторів" + +#: common.c:174 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "читання користувацьких парсерів текстового пошуку" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search templates" +msgstr "читання користувацьких шаблонів текстового пошуку" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "читання користувацьких словників текстового пошуку" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "читання користувацьких конфігурацій текстового пошуку" + +#: common.c:186 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "читання користувацьких джерел сторонніх даних" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "читання користувацьких сторонніх серверів" + +#: common.c:192 +#, c-format +msgid "reading default privileges" +msgstr "читання прав за замовчуванням" + +#: common.c:195 +#, c-format +msgid "reading user-defined collations" +msgstr "читання користувацьких сортувань" + +#: common.c:199 +#, c-format +msgid "reading user-defined conversions" +msgstr "читання користувацьких перетворень" + +#: common.c:202 +#, c-format +msgid "reading type casts" +msgstr "читання типу приведення" + +#: common.c:205 +#, c-format +msgid "reading transforms" +msgstr "читання перетворень" + +#: common.c:208 +#, c-format +msgid "reading table inheritance information" +msgstr "читання інформації про успадкування таблиці" + +#: common.c:211 +#, c-format +msgid "reading event triggers" +msgstr "читання тригерів подій" + +#: common.c:215 +#, c-format +msgid "finding extension tables" +msgstr "пошук таблиць розширень" + +#: common.c:219 +#, c-format +msgid "finding inheritance relationships" +msgstr "пошук відносин успадкування" + +#: common.c:222 +#, c-format +msgid "reading column info for interesting tables" +msgstr "читання інформації про стовпці цікавлячої таблиці" + +#: common.c:225 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "помітка успадкованих стовпців в підтаблицях" + +#: common.c:228 +#, c-format +msgid "reading indexes" +msgstr "читання індексів" + +#: common.c:231 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "помітка індексів в секційних таблицях" + +#: common.c:234 +#, c-format +msgid "reading extended statistics" +msgstr "читання розширеної статистики" + +#: common.c:237 +#, c-format +msgid "reading constraints" +msgstr "читання обмежень" + +#: common.c:240 +#, c-format +msgid "reading triggers" +msgstr "читання тригерів" + +#: common.c:243 +#, c-format +msgid "reading rewrite rules" +msgstr "читання правил перезаписування" + +#: common.c:246 +#, c-format +msgid "reading policies" +msgstr "читання політик" + +#: common.c:249 +#, c-format +msgid "reading publications" +msgstr "читання публікацій" + +#: common.c:252 +#, c-format +msgid "reading publication membership" +msgstr "читання публікацій учасників" + +#: common.c:255 +#, c-format +msgid "reading subscriptions" +msgstr "читання підписок" + +#: common.c:1025 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "помилка перевірки, батьківський елемент ідентифікатора OID %u для таблиці \"%s\" (ідентифікатор OID %u) не знайдено" + +#: common.c:1067 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "не вдалося проаналізувати числовий масив \"%s\": забагато чисел" + +#: common.c:1082 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "не вдалося проаналізувати числовий масив \"%s\": неприпустимий характер числа" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "невірний код стиснення: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:504 +#: compress_io.c:547 +#, c-format +msgid "not built with zlib support" +msgstr "зібрано без підтримки zlib" + +#: compress_io.c:236 compress_io.c:333 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "не вдалося ініціалізувати бібліотеку стиснення: %s" + +#: compress_io.c:256 +#, c-format +msgid "could not close compression stream: %s" +msgstr "не вдалося закрити потік стиснення: %s" + +#: compress_io.c:273 +#, c-format +msgid "could not compress data: %s" +msgstr "не вдалося стиснути дані: %s" + +#: compress_io.c:349 compress_io.c:364 +#, c-format +msgid "could not uncompress data: %s" +msgstr "не вдалося розпакувати дані: %s" + +#: compress_io.c:371 +#, c-format +msgid "could not close compression library: %s" +msgstr "не вдалося закрити бібліотеку стиснення: %s" + +#: compress_io.c:584 compress_io.c:621 pg_backup_tar.c:557 pg_backup_tar.c:560 +#, c-format +msgid "could not read from input file: %s" +msgstr "не вдалося прочитати з вхідного файлу: %s" + +#: compress_io.c:623 pg_backup_custom.c:646 pg_backup_directory.c:552 +#: pg_backup_tar.c:793 pg_backup_tar.c:816 +#, c-format +msgid "could not read from input file: end of file" +msgstr "не вдалося прочитати з вхідного файлу: кінець файлу" + +#: parallel.c:267 +#, c-format +msgid "WSAStartup failed: %d" +msgstr "Помилка WSAStartup: %d" + +#: parallel.c:978 +#, c-format +msgid "could not create communication channels: %m" +msgstr "не вдалося створити канали зв'язку: %m" + +#: parallel.c:1035 +#, c-format +msgid "could not create worker process: %m" +msgstr "не вдалося створити робочий процес: %m" + +#: parallel.c:1165 +#, c-format +msgid "unrecognized command received from master: \"%s\"" +msgstr "отримана нерозпізнана команда від майстра: \"%s\"" + +#: parallel.c:1208 parallel.c:1446 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "отримане невірне повідомлення від робочого процесу: \"%s\"" + +#: parallel.c:1340 +#, c-format +msgid "could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "не вдалося отримати блокування відношення \"%s\"\n" +"Це, зазвичай, означає, що хтось зробив запит на монопольне блокування таблиці після того, як батьківський процес pg_dump отримав початкове блокування спільного доступу для таблиці." + +#: parallel.c:1429 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "робочий процес завершився несподівано" + +#: parallel.c:1551 parallel.c:1669 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "не вдалося записати до каналу зв'язку: %m" + +#: parallel.c:1628 +#, c-format +msgid "select() failed: %m" +msgstr "помилка в select(): %m" + +#: parallel.c:1753 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: не вдалося створити сокет: код помилки %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: не вдалося прив'язати: код помилки %d" + +#: parallel.c:1771 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: не вдалося прослухати: код помилки %d" + +#: parallel.c:1778 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: помилка в getsockname(): код помилки %d" + +#: parallel.c:1789 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: не вдалося створити другий сокет: код помилки %d" + +#: parallel.c:1798 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: не вдалося зв'язатися з сокетом: код помилки %d" + +#: parallel.c:1807 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: не вдалося прийняти зв'язок: код помилки %d" + +#: pg_backup_archiver.c:271 pg_backup_archiver.c:1591 +#, c-format +msgid "could not close output file: %m" +msgstr "не вдалося закрити вихідний файл: %m" + +#: pg_backup_archiver.c:315 pg_backup_archiver.c:319 +#, c-format +msgid "archive items not in correct section order" +msgstr "елементи архіву в неправильному порядку" + +#: pg_backup_archiver.c:325 +#, c-format +msgid "unexpected section code %d" +msgstr "неочікуваний код розділу %d" + +#: pg_backup_archiver.c:362 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "паралельне відновлення не підтримується з цим файлом архівного формату" + +#: pg_backup_archiver.c:366 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "паралельне відновлення не підтримується з архівами, зробленими pre-8.0 pg_dump" + +#: pg_backup_archiver.c:384 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "не вдалося відновити зі стиснутого архіву (встановлена версія не підтримує стискання)" + +#: pg_backup_archiver.c:401 +#, c-format +msgid "connecting to database for restore" +msgstr "підключення до бази даних для відновлення" + +#: pg_backup_archiver.c:403 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "прямі з'днання з базою даних не підтримуються в архівах у версіях до 1.3" + +#: pg_backup_archiver.c:448 +#, c-format +msgid "implied data-only restore" +msgstr "мається на увазі відновлення лише даних" + +#: pg_backup_archiver.c:514 +#, c-format +msgid "dropping %s %s" +msgstr "видалення %s %s" + +#: pg_backup_archiver.c:609 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "не вдалося знайти, куди вставити IF EXISTS в інструкції \"%s\"" + +#: pg_backup_archiver.c:765 pg_backup_archiver.c:767 +#, c-format +msgid "warning from original dump file: %s" +msgstr "попередження з оригінального файлу дамп: %s" + +#: pg_backup_archiver.c:782 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "створення %s \"%s.%s\"" + +#: pg_backup_archiver.c:785 +#, c-format +msgid "creating %s \"%s\"" +msgstr "створення %s \" \"%s\"" + +#: pg_backup_archiver.c:842 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "підключення до нової бази даних \"%s\"" + +#: pg_backup_archiver.c:870 +#, c-format +msgid "processing %s" +msgstr "обробка %s" + +#: pg_backup_archiver.c:890 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "обробка даних для таблиці \"%s.%s\"" + +#: pg_backup_archiver.c:952 +#, c-format +msgid "executing %s %s" +msgstr "виконання %s %s" + +#: pg_backup_archiver.c:991 +#, c-format +msgid "disabling triggers for %s" +msgstr "вимкнення тригерів для %s" + +#: pg_backup_archiver.c:1017 +#, c-format +msgid "enabling triggers for %s" +msgstr "увімкнення тригерів для %s" + +#: pg_backup_archiver.c:1045 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "внутрішня помилка - WriteData не може бути викликана поза контекстом підпрограми DataDumper " + +#: pg_backup_archiver.c:1228 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "вивід великих об'єктів не підтримується у вибраному форматі" + +#: pg_backup_archiver.c:1286 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "відновлено %d великий об'єкт" +msgstr[1] "відновлено %d великих об'єкти" +msgstr[2] "відновлено %d великих об'єктів" +msgstr[3] "відновлено %d великих об'єктів" + +#: pg_backup_archiver.c:1307 pg_backup_tar.c:736 +#, c-format +msgid "restoring large object with OID %u" +msgstr "відновлення великого об'єкту з OID %u" + +#: pg_backup_archiver.c:1319 +#, c-format +msgid "could not create large object %u: %s" +msgstr "не вдалося створити великий об'єкт %u: %s" + +#: pg_backup_archiver.c:1324 pg_dump.c:3544 +#, c-format +msgid "could not open large object %u: %s" +msgstr "не вдалося відкрити великий об'єкт %u: %s" + +#: pg_backup_archiver.c:1381 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "не вдалося відкрити файл TOC \"%s\": %m" + +#: pg_backup_archiver.c:1421 +#, c-format +msgid "line ignored: %s" +msgstr "рядок проігноровано: %s" + +#: pg_backup_archiver.c:1428 +#, c-format +msgid "could not find entry for ID %d" +msgstr "не вдалося знайти введення для ID %d" + +#: pg_backup_archiver.c:1449 pg_backup_directory.c:222 +#: pg_backup_directory.c:598 +#, c-format +msgid "could not close TOC file: %m" +msgstr "не вдалося закрити файл TOC: %m" + +#: pg_backup_archiver.c:1563 pg_backup_custom.c:156 pg_backup_directory.c:332 +#: pg_backup_directory.c:585 pg_backup_directory.c:648 +#: pg_backup_directory.c:667 pg_dumpall.c:484 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "не вдалося відкрити вихідний файл \"%s\": %m" + +#: pg_backup_archiver.c:1565 pg_backup_custom.c:162 +#, c-format +msgid "could not open output file: %m" +msgstr "не вдалося відкрити вихідний файл: %m" + +#: pg_backup_archiver.c:1658 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "записано %lu байт даних великого об'єкта (результат = %lu)" +msgstr[1] "записано %lu байти даних великого об'єкта (результат = %lu)" +msgstr[2] "записано %lu байтів даних великого об'єкта (результат = %lu)" +msgstr[3] "записано %lu байтів даних великого об'єкта (результат = %lu)" + +#: pg_backup_archiver.c:1663 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "не вдалося записати великий об'єкт (результат: %lu, очікувано: %lu)" + +#: pg_backup_archiver.c:1753 +#, c-format +msgid "while INITIALIZING:" +msgstr "при ІНІЦІАЛІЗАЦІЇ:" + +#: pg_backup_archiver.c:1758 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "при ОБРОБЦІ TOC:" + +#: pg_backup_archiver.c:1763 +#, c-format +msgid "while FINALIZING:" +msgstr "при ЗАВЕРШЕННІ:" + +#: pg_backup_archiver.c:1768 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "зі входження до TOC %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1844 +#, c-format +msgid "bad dumpId" +msgstr "невірний dumpId" + +#: pg_backup_archiver.c:1865 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "невірна таблиця dumpId для елементу даних таблиці" + +#: pg_backup_archiver.c:1957 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "неочікувана позначка зсуву даних %d" + +#: pg_backup_archiver.c:1970 +#, c-format +msgid "file offset in dump file is too large" +msgstr "зсув файлу у файлі дампу завеликий" + +#: pg_backup_archiver.c:2107 pg_backup_archiver.c:2117 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "ім'я каталогу задовге: \"%s\"" + +#: pg_backup_archiver.c:2125 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "каталог \"%s\" не схожий на архівний (\"toc.dat\" не існує)" + +#: pg_backup_archiver.c:2133 pg_backup_custom.c:173 pg_backup_custom.c:812 +#: pg_backup_directory.c:207 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "не вдалося відкрити вхідний файл \"%s\": %m" + +#: pg_backup_archiver.c:2140 pg_backup_custom.c:179 +#, c-format +msgid "could not open input file: %m" +msgstr "не вдалося відкрити вхідний файл: %m" + +#: pg_backup_archiver.c:2146 +#, c-format +msgid "could not read input file: %m" +msgstr "не вдалося прочитати вхідний файл: %m" + +#: pg_backup_archiver.c:2148 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "вхідний файл закороткий (прочитано %lu, очікувалось 5)" + +#: pg_backup_archiver.c:2233 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "вхідний файл схожий на дамп текстового формату. Будь ласка, використайте psql." + +#: pg_backup_archiver.c:2239 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "вхідний файл не схожий на архівний (закороткий?)" + +#: pg_backup_archiver.c:2245 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "вхідний файл не схожий на архівний" + +#: pg_backup_archiver.c:2265 +#, c-format +msgid "could not close input file: %m" +msgstr "не вдалося закрити вхідний файл: %m" + +#: pg_backup_archiver.c:2379 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "нерозпізнаний формат файлу \"%d\"" + +#: pg_backup_archiver.c:2461 pg_backup_archiver.c:4473 +#, c-format +msgid "finished item %d %s %s" +msgstr "завершений об'єкт %d %s %s" + +#: pg_backup_archiver.c:2465 pg_backup_archiver.c:4486 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "помилка при робочому процесі: код виходу %d" + +#: pg_backup_archiver.c:2585 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "введення ідентифікатора %d поза діапазоном -- можливо, зміст пошкоджений" + +#: pg_backup_archiver.c:2652 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "відновлення таблиць WITH OIDS більше не підтримується" + +#: pg_backup_archiver.c:2734 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "нерозпізнане кодування \"%s\"" + +#: pg_backup_archiver.c:2739 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "невірний об'єкт КОДУВАННЯ: %s" + +#: pg_backup_archiver.c:2757 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "невірний об'єкт STDSTRINGS: %s" + +#: pg_backup_archiver.c:2782 +#, c-format +msgid "schema \"%s\" not found" +msgstr "схему \"%s\" не знайдено" + +#: pg_backup_archiver.c:2789 +#, c-format +msgid "table \"%s\" not found" +msgstr "таблицю \"%s\" не знайдено" + +#: pg_backup_archiver.c:2796 +#, c-format +msgid "index \"%s\" not found" +msgstr "індекс \"%s\" не знайдено" + +#: pg_backup_archiver.c:2803 +#, c-format +msgid "function \"%s\" not found" +msgstr "функцію \"%s\" не знайдено" + +#: pg_backup_archiver.c:2810 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "тригер \"%s\" не знайдено" + +#: pg_backup_archiver.c:3202 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "не вдалося встановити користувача сеансу для \"%s\": %s" + +#: pg_backup_archiver.c:3341 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "не вдалося встановити search_path для \"%s\": %s" + +#: pg_backup_archiver.c:3403 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "не вдалося встановити default_tablespace для %s: %s" + +#: pg_backup_archiver.c:3448 +#, c-format +msgid "could not set default_table_access_method: %s" +msgstr "не вдалося встановити default_table_access_method для : %s" + +#: pg_backup_archiver.c:3540 pg_backup_archiver.c:3698 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "невідомо, як встановити власника об'єкту типу \"%s\"" + +#: pg_backup_archiver.c:3802 +#, c-format +msgid "did not find magic string in file header" +msgstr "в заголовку файлу не знайдено магічного рядка" + +#: pg_backup_archiver.c:3815 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "в заголовку непідтримувана версія (%d.%d)" + +#: pg_backup_archiver.c:3820 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "перевірка на розмір цілого числа (%lu) не вдалася" + +#: pg_backup_archiver.c:3824 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "архів зроблено на архітектурі з більшими цілими числами, деякі операції можуть не виконуватися" + +#: pg_backup_archiver.c:3834 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "очікуваний формат (%d) відрізняється від знайденого формату у файлі (%d)" + +#: pg_backup_archiver.c:3850 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "архів стиснено, але ця інсталяція не підтримує стискання -- дані не будуть доступними " + +#: pg_backup_archiver.c:3868 +#, c-format +msgid "invalid creation date in header" +msgstr "неприпустима дата створення у заголовку" + +#: pg_backup_archiver.c:3996 +#, c-format +msgid "processing item %d %s %s" +msgstr "обробка елементу %d %s %s" + +#: pg_backup_archiver.c:4075 +#, c-format +msgid "entering main parallel loop" +msgstr "введення головного паралельного циклу" + +#: pg_backup_archiver.c:4086 +#, c-format +msgid "skipping item %d %s %s" +msgstr "пропускається елемент %d %s %s " + +#: pg_backup_archiver.c:4095 +#, c-format +msgid "launching item %d %s %s" +msgstr "запуск елементу %d %s %s " + +#: pg_backup_archiver.c:4149 +#, c-format +msgid "finished main parallel loop" +msgstr "головний паралельний цикл завершився" + +#: pg_backup_archiver.c:4187 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "обробка втраченого елементу %d %s %s" + +#: pg_backup_archiver.c:4792 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "не вдалося створити таблицю \"%s\", дані не будуть відновлені" + +#: pg_backup_custom.c:378 pg_backup_null.c:147 +#, c-format +msgid "invalid OID for large object" +msgstr "неприпустимий ідентифікатор OID для великого об’єкту" + +#: pg_backup_custom.c:441 pg_backup_custom.c:507 pg_backup_custom.c:632 +#: pg_backup_custom.c:870 pg_backup_tar.c:1086 pg_backup_tar.c:1091 +#, c-format +msgid "error during file seek: %m" +msgstr "помилка під час пошуку файлу oobe. xml: %m" + +#: pg_backup_custom.c:480 +#, c-format +msgid "data block %d has wrong seek position" +msgstr "блок даних %d має неправильну позицію пошуку" + +#: pg_backup_custom.c:497 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "нерозпізнаний тип блоку даних (%d) під час пошуку архіву" + +#: pg_backup_custom.c:519 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "не вдалося зайти в архіві блок з ідентифікатором %d -- можливо, через непослідовність запиту відновлення, який не можна обробити через файл, що не допускає довільний вхід" + +#: pg_backup_custom.c:524 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "не вдалося знайти в архіві блок з ідентифікатором %d -- можливо, архів пошкоджений" + +#: pg_backup_custom.c:531 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "знайдено неочікуваний блок з ідентифікатором (%d) під час читання даних -- очікувалося %d" + +#: pg_backup_custom.c:545 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "нерозпізнаний тип блоку даних %d при відновленні архіву" + +#: pg_backup_custom.c:648 +#, c-format +msgid "could not read from input file: %m" +msgstr "не вдалося прочитати з вхідного файлу: %m" + +#: pg_backup_custom.c:751 pg_backup_custom.c:803 pg_backup_custom.c:948 +#: pg_backup_tar.c:1089 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "не вдалося визначити позицію пошуку у файлі архіву: %m" + +#: pg_backup_custom.c:767 pg_backup_custom.c:807 +#, c-format +msgid "could not close archive file: %m" +msgstr "не вдалося закрити архівний файл: %m" + +#: pg_backup_custom.c:790 +#, c-format +msgid "can only reopen input archives" +msgstr "можливо повторно відкрити лише вхідні архіви" + +#: pg_backup_custom.c:797 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "паралельне відновлення зі стандартного вводу не підтримується" + +#: pg_backup_custom.c:799 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "паралельне відновлення з файлу без вільного доступу не підтримується" + +#: pg_backup_custom.c:815 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "не вдалося набрати позицію пошуку у файлі архіву: %m" + +#: pg_backup_custom.c:894 +#, c-format +msgid "compressor active" +msgstr "ущільнювач активний" + +#: pg_backup_db.c:42 +#, c-format +msgid "could not get server_version from libpq" +msgstr "не вдалося отримати версію серверу з libpq" + +#: pg_backup_db.c:53 pg_dumpall.c:1826 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "версія серверу: %s; версія %s: %s" + +#: pg_backup_db.c:55 pg_dumpall.c:1828 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "переривання через невідповідність версії серверу" + +#: pg_backup_db.c:138 +#, c-format +msgid "connecting to database \"%s\" as user \"%s\"" +msgstr "підключення до бази даних \"%s\" як користувача \"%s\"" + +#: pg_backup_db.c:145 pg_backup_db.c:194 pg_backup_db.c:255 pg_backup_db.c:296 +#: pg_dumpall.c:1651 pg_dumpall.c:1764 +msgid "Password: " +msgstr "Пароль: " + +#: pg_backup_db.c:177 +#, c-format +msgid "could not reconnect to database" +msgstr "неможливо заново під'єднатися до бази даних" + +#: pg_backup_db.c:182 +#, c-format +msgid "could not reconnect to database: %s" +msgstr "неможливо заново під'єднатися до бази даних: %s" + +#: pg_backup_db.c:198 +#, c-format +msgid "connection needs password" +msgstr "для з'єднання потрібен пароль" + +#: pg_backup_db.c:249 +#, c-format +msgid "already connected to a database" +msgstr "вже під'єднано до бази даних" + +#: pg_backup_db.c:288 +#, c-format +msgid "could not connect to database" +msgstr "не вдалося зв'язатися з базою даних" + +#: pg_backup_db.c:304 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "підключення до бази даних \"%s\" не вдалося: %s" + +#: pg_backup_db.c:376 pg_dumpall.c:1684 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:383 pg_dumpall.c:1889 pg_dumpall.c:1912 +#, c-format +msgid "query failed: %s" +msgstr "запит не вдався: %s" + +#: pg_backup_db.c:385 pg_dumpall.c:1890 pg_dumpall.c:1913 +#, c-format +msgid "query was: %s" +msgstr "запит був: %s" + +#: pg_backup_db.c:426 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "запит повернув %d рядок замість одного: %s" +msgstr[1] "запит повернув %d рядки замість одного: %s" +msgstr[2] "запит повернув %d рядків замість одного: %s" +msgstr[3] "запит повернув %d рядків замість одного: %s" + +#: pg_backup_db.c:462 +#, c-format +msgid "%s: %sCommand was: %s" +msgstr "%s:%sКоманда була: %s" + +#: pg_backup_db.c:518 pg_backup_db.c:592 pg_backup_db.c:599 +msgid "could not execute query" +msgstr "не вдалося виконати запит" + +#: pg_backup_db.c:571 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "помилка повернулася від PQputCopyData: %s" + +#: pg_backup_db.c:620 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "помилка повернулася від PQputCopyEnd: %s" + +#: pg_backup_db.c:626 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "КОПІЮВАННЯ для таблиці \"%s\" не вдалося: %s" + +#: pg_backup_db.c:632 pg_dump.c:1984 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "неочікувані зайві результати під час копіювання таблиці \"%s\"" + +#: pg_backup_db.c:644 +msgid "could not start database transaction" +msgstr "не вдалося почати транзакцію бази даних" + +#: pg_backup_db.c:652 +msgid "could not commit database transaction" +msgstr "не вдалося затвердити транзакцію бази даних" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "вихідний каталог не вказано" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не вдалося прочитати каталог \"%s\": %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не вдалося закрити каталог \"%s\": %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не вдалося створити каталог \"%s\": %m" + +#: pg_backup_directory.c:355 pg_backup_directory.c:496 +#: pg_backup_directory.c:532 +#, c-format +msgid "could not write to output file: %s" +msgstr "не можливо записати у вихідний файл: %s" + +#: pg_backup_directory.c:406 +#, c-format +msgid "could not close data file \"%s\": %m" +msgstr "не вдалося закрити файл даних \"%s\": %m" + +#: pg_backup_directory.c:446 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "не вдалося відкрити великий об'єкт файлу TOC \"%s\" для вводу: %m" + +#: pg_backup_directory.c:457 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "невірна лінія у великому об'єкті файлу TOC \"%s\": \"%s\"" + +#: pg_backup_directory.c:466 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "помилка читання великого об'єкту файлу TOC \"%s\"" + +#: pg_backup_directory.c:470 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "не вдалося закрити великий об'єкт файлу TOC \"%s\" %m" + +#: pg_backup_directory.c:689 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "не вдалося записати зміст у файл oobe. xml" + +#: pg_backup_directory.c:721 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "ім'я файлу задовге: \"%s\"" + +#: pg_backup_null.c:74 +#, c-format +msgid "this format cannot be read" +msgstr "цей формат не може бути прочитаним" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "не вдалося відкрити файл TOC \"%s\" для виводу: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "не вдалося відкрити файл TOC для виводу: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:358 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "стиснення не підтримується форматом архіватора tar" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "не вдалося відкрити файл TOC \"%s\" для вводу: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "не вдалося відкрити файл TOC для вводу: %m" + +#: pg_backup_tar.c:344 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "не вдалося знайти файл \"%s\" в архіві" + +#: pg_backup_tar.c:410 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "не вдалося згенерувати тимчасове ім'я файлу: %m" + +#: pg_backup_tar.c:421 +#, c-format +msgid "could not open temporary file" +msgstr "неможливо відкрити тимчасовий файл" + +#: pg_backup_tar.c:448 +#, c-format +msgid "could not close tar member" +msgstr "не вдалося закрити tar-елемент" + +#: pg_backup_tar.c:691 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "неочікуваний синтаксис інструкції копіювання: \"%s\"" + +#: pg_backup_tar.c:958 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "неприпустимий ідентифікатор OID для великих об’єктів (%u)" + +#: pg_backup_tar.c:1105 +#, c-format +msgid "could not close temporary file: %m" +msgstr "не вдалося закрити тимчасовий файл oobe. xml: %m" + +#: pg_backup_tar.c:1114 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "фактична довжина файлу (%s) не відповідає очікуваному (%s)" + +#: pg_backup_tar.c:1171 pg_backup_tar.c:1201 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "не вдалося знайти верхній колонтитул для файлу oobe. xml \"%s\" в архіві tar" + +#: pg_backup_tar.c:1189 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "відновлення даних поза замовленням не підтримується у цьому форматі архіву: вимагаєтсья \"%s\", але перед цим іде \"%s\" у файлі архіву." + +#: pg_backup_tar.c:1234 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "знайдено незавершений tar-заголовок (%lu байт)" +msgstr[1] "знайдено незавершений tar-заголовок (%lu байт)" +msgstr[2] "знайдено незавершений tar-заголовок (%lu байт)" +msgstr[3] "знайдено незавершений tar-заголовок (%lu байт)" + +#: pg_backup_tar.c:1285 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "знайдено пошкоджений tar-верхній колонтитул у %s(очікувалося %d, обчислюється %d) позиція файлу oobe. xml %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "нерозпізнане ім’я розділу: \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:608 pg_dump.c:625 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:284 pg_restore.c:300 +#: pg_restore.c:318 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "перевищено межу on_exit_nicely слотів" + +#: pg_dump.c:534 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "рівень стискання має бути у діапазоні 0..9" + +#: pg_dump.c:572 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits повинні бути у діапазоні -15..3" + +#: pg_dump.c:595 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "рядків-на-вставку має бути у діапазоні %d..%d" + +#: pg_dump.c:623 pg_dumpall.c:346 pg_restore.c:298 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" + +#: pg_dump.c:644 pg_restore.c:327 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "параметри -s/--schema-only і -a/--data-only не можуть використовуватись разом" + +#: pg_dump.c:649 +#, c-format +msgid "options -s/--schema-only and --include-foreign-data cannot be used together" +msgstr "параметри -s/--schema-only і --include-foreign-data не можуть використовуватись разом" + +#: pg_dump.c:652 +#, c-format +msgid "option --include-foreign-data is not supported with parallel backup" +msgstr "параметр --include-foreign-data не підтримується з паралельним резервним копіюванням" + +#: pg_dump.c:656 pg_restore.c:333 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "параметри -c/--clean і -a/--data-only не можна використовувати разом" + +#: pg_dump.c:661 pg_dumpall.c:381 pg_restore.c:382 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "параметр --if-exists потребує параметр -c/--clean" + +#: pg_dump.c:668 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts" +msgstr "параметр --on-conflict-do-nothing вимагає опції --inserts, --rows-per-insert або --column-inserts" + +#: pg_dump.c:690 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "затребуване стискання недоступне на цій системі -- архів не буде стискатися" + +#: pg_dump.c:711 pg_restore.c:349 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "неприпустима кількість паралельних завдань" + +#: pg_dump.c:715 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "паралельне резервне копіювання підтримується лише з форматом \"каталог\"" + +#: pg_dump.c:770 +#, c-format +msgid "Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "У цій версії серверу синхронізовані знімки не підтримуються.\n" +"Якщо вам не потрібні синхронізовані знімки, виконайте \n" +" --no-synchronized-snapshots." + +#: pg_dump.c:776 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Експортовані знімки не підтримуються цією версією серверу." + +#: pg_dump.c:788 +#, c-format +msgid "last built-in OID is %u" +msgstr "останній вбудований OID %u" + +#: pg_dump.c:797 +#, c-format +msgid "no matching schemas were found" +msgstr "відповідних схем не знайдено" + +#: pg_dump.c:811 +#, c-format +msgid "no matching tables were found" +msgstr "відповідних таблиць не знайдено" + +#: pg_dump.c:986 +#, c-format +msgid "%s dumps a database as a text file or to other formats.\n\n" +msgstr "%s зберігає резервну копію бази даних в текстовому файлі або в інших форматах.\n\n" + +#: pg_dump.c:987 pg_dumpall.c:617 pg_restore.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Використання:\n" + +#: pg_dump.c:988 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]... [DBNAME]\n" + +#: pg_dump.c:990 pg_dumpall.c:620 pg_restore.c:465 +#, c-format +msgid "\n" +"General options:\n" +msgstr "\n" +"Основні налаштування:\n" + +#: pg_dump.c:991 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=FILENAME ім'я файлу виводу або каталогу\n" + +#: pg_dump.c:992 +#, c-format +msgid " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr " -F, --format=c|d|t|p формат файлу виводу (спеціальний, каталог, tar,\n" +" звичайний текст (за замовчуванням))\n" + +#: pg_dump.c:994 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=NUM використовувати ці паралельні завдання для вивантаження\n" + +#: pg_dump.c:995 pg_dumpall.c:622 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose детальний режим\n" + +#: pg_dump.c:996 pg_dumpall.c:623 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію, потім вийти\n" + +#: pg_dump.c:997 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 рівень стискання для стиснутих форматів\n" + +#: pg_dump.c:998 pg_dumpall.c:624 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " --lock-wait-timeout=TIMEOUT помилка після очікування TIMEOUT для блокування таблиці\n" + +#: pg_dump.c:999 pg_dumpall.c:651 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync не чекати безпечного збереження змін на диск\n" + +#: pg_dump.c:1000 pg_dumpall.c:625 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати цю довідку, потім вийти\n" + +#: pg_dump.c:1002 pg_dumpall.c:626 +#, c-format +msgid "\n" +"Options controlling the output content:\n" +msgstr "\n" +"Параметри, що керують вихідним вмістом:\n" + +#: pg_dump.c:1003 pg_dumpall.c:627 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only вивантажити лише дані, без схеми\n" + +#: pg_dump.c:1004 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs включити у вивантаження великі об'єкти\n" + +#: pg_dump.c:1005 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs виключити з вивантаження великі об'єкти\n" + +#: pg_dump.c:1006 pg_restore.c:476 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, --clean видалити об'єкти бази даних перед перед повторним створенням\n" + +#: pg_dump.c:1007 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr " -C, --create включити у вивантаження команди для створення бази даних\n" + +#: pg_dump.c:1008 pg_dumpall.c:629 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=ENCODING вивантажити дані в кодуванні ENCODING\n" + +#: pg_dump.c:1009 +#, c-format +msgid " -n, --schema=PATTERN dump the specified schema(s) only\n" +msgstr " -n, --schema=PATTERN вивантажити лише вказану схему(и)\n" + +#: pg_dump.c:1010 +#, c-format +msgid " -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n" +msgstr " -N, --exclude-schema=PATTERN НЕ вивантажувати вказану схему(и)\n" + +#: pg_dump.c:1011 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr " -O, --no-owner пропускати відновлення володіння об'єктами\n" +" при використанні текстового формату\n" + +#: pg_dump.c:1013 pg_dumpall.c:633 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only вивантажити лише схему, без даних\n" + +#: pg_dump.c:1014 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, --superuser=NAME ім'я користувача, яке буде використовуватись у звичайних текстових форматах\n" + +#: pg_dump.c:1015 +#, c-format +msgid " -t, --table=PATTERN dump the specified table(s) only\n" +msgstr " -t, --table=PATTERN вивантажити лише вказані таблиці\n" + +#: pg_dump.c:1016 +#, c-format +msgid " -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n" +msgstr " -T, --exclude-table=PATTERN НЕ вивантажувати вказані таблиці\n" + +#: pg_dump.c:1017 pg_dumpall.c:636 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges не вивантажувати права (надання/відкликання)\n" + +#: pg_dump.c:1018 pg_dumpall.c:637 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade для використання лише утилітами оновлення\n" + +#: pg_dump.c:1019 pg_dumpall.c:638 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr " --column-inserts вивантажити дані у вигляді команд INSERT з іменами стовпців\n" + +#: pg_dump.c:1020 pg_dumpall.c:639 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr " --disable-dollar-quoting вимкнути цінову пропозицію $, використовувати SQL стандартну цінову пропозицію\n" + +#: pg_dump.c:1021 pg_dumpall.c:640 pg_restore.c:493 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr " --disable-triggers вимкнути тригери лише під час відновлення даних\n" + +#: pg_dump.c:1022 +#, c-format +msgid " --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr " --enable-row-security активувати захист на рівні рядків (вивантажити лише той вміст, до якого\n" +" користувач має доступ)\n" + +#: pg_dump.c:1024 +#, c-format +msgid " --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n" +msgstr " --exclude-table-data=PATTERN НЕ вивантажувати дані вказаних таблиць\n" + +#: pg_dump.c:1025 pg_dumpall.c:642 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM змінити параметр за замовчуванням для extra_float_digits\n" + +#: pg_dump.c:1026 pg_dumpall.c:643 pg_restore.c:495 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists використовувати IF EXISTS під час видалення об'єктів\n" + +#: pg_dump.c:1027 +#, c-format +msgid " --include-foreign-data=PATTERN\n" +" include data of foreign tables on foreign\n" +" servers matching PATTERN\n" +msgstr " --include-foreign-data=ШАБЛОН\n" +" включають дані підлеглих таблиць на підлеглих\n" +" сервери, що відповідають ШАБЛОНУ\n" + +#: pg_dump.c:1030 pg_dumpall.c:644 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr " --inserts вивантажити дані у вигляді команд INSERT, не COPY\n" + +#: pg_dump.c:1031 pg_dumpall.c:645 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root завантажувати секції через головну таблицю\n" + +#: pg_dump.c:1032 pg_dumpall.c:646 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments не вивантажувати коментарі\n" + +#: pg_dump.c:1033 pg_dumpall.c:647 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications не вивантажувати публікації\n" + +#: pg_dump.c:1034 pg_dumpall.c:649 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels не вивантажувати завдання міток безпеки\n" + +#: pg_dump.c:1035 pg_dumpall.c:650 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions не вивантажувати підписки\n" + +#: pg_dump.c:1036 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr " --no-synchronized-snapshots не використовувати синхронізовані знімки в паралельних завданнях\n" + +#: pg_dump.c:1037 pg_dumpall.c:652 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces не вивантажувати призначення табличних просторів\n" + +#: pg_dump.c:1038 pg_dumpall.c:653 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data не вивантажувати дані таблиць, які не журналюються\n" + +#: pg_dump.c:1039 pg_dumpall.c:654 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing додавати ON CONFLICT DO NOTHING до команди INSERT\n" + +#: pg_dump.c:1040 pg_dumpall.c:655 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr " --quote-all-identifiers укладати в лапки всі ідентифікатори, а не тільки ключові слова\n" + +#: pg_dump.c:1041 pg_dumpall.c:656 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NROWS кількість рядків для INSERT; вимагає параметру --inserts\n" + +#: pg_dump.c:1042 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr " --section=SECTION вивантажити вказану секцію (pre-data, data або post-data)\n" + +#: pg_dump.c:1043 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr " --serializable-deferrable чекати коли вивантаження можна буде виконати без аномалій\n" + +#: pg_dump.c:1044 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT використовувати під час вивантаження вказаний знімок\n" + +#: pg_dump.c:1045 pg_restore.c:504 +#, c-format +msgid " --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr " --strict-names потребувати, щоб при вказівці шаблону включення\n" +" таблиці і/або схеми йому відповідав мінімум один об'єкт\n" + +#: pg_dump.c:1047 pg_dumpall.c:657 pg_restore.c:506 +#, c-format +msgid " --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr " --use-set-session-authorization\n" +" щоб встановити власника, використати команди SET SESSION AUTHORIZATION,\n" +" замість команд ALTER OWNER\n" + +#: pg_dump.c:1051 pg_dumpall.c:661 pg_restore.c:510 +#, c-format +msgid "\n" +"Connection options:\n" +msgstr "\n" +"Налаштування з'єднання:\n" + +#: pg_dump.c:1052 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=DBNAME ім'я бази даних для вивантаження\n" + +#: pg_dump.c:1053 pg_dumpall.c:663 pg_restore.c:511 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME хост серверу баз даних або каталог сокетів\n" + +#: pg_dump.c:1054 pg_dumpall.c:665 pg_restore.c:512 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT номер порту сервера бази даних\n" + +#: pg_dump.c:1055 pg_dumpall.c:666 pg_restore.c:513 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME підключатись як вказаний користувач бази даних\n" + +#: pg_dump.c:1056 pg_dumpall.c:667 pg_restore.c:514 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password ніколи не запитувати пароль\n" + +#: pg_dump.c:1057 pg_dumpall.c:668 pg_restore.c:515 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password запитувати пароль завжди (повинно траплятись автоматично)\n" + +#: pg_dump.c:1058 pg_dumpall.c:669 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROLENAME виконати SET ROLE до вивантаження\n" + +#: pg_dump.c:1060 +#, c-format +msgid "\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n\n" +msgstr "\n" +"Якщо ім'я бази даних не вказано, тоді використовується значення змінної середовища PGDATABASE.\n\n" + +#: pg_dump.c:1062 pg_dumpall.c:673 pg_restore.c:522 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Повідомляти про помилки на <%s>.\n" + +#: pg_dump.c:1063 pg_dumpall.c:674 pg_restore.c:523 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: pg_dump.c:1082 pg_dumpall.c:499 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "вказано неприпустиме клієнтське кодування \"%s\"" + +#: pg_dump.c:1228 +#, c-format +msgid "Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "Синхронізовані знімки на резервному сервері не підтримуються цією версією сервера. Запустіть із параметром --no-synchronized-snapshots, якщо вам не потрібні синхронізовані знімки." + +#: pg_dump.c:1297 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "вказано неприпустимий формат виводу \"%s\"" + +#: pg_dump.c:1335 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "не знайдено відповідних схем для візерунку \"%s\"" + +#: pg_dump.c:1382 +#, c-format +msgid "no matching foreign servers were found for pattern \"%s\"" +msgstr "не знайдено відповідних підлеглих серверів для шаблону \"%s\"" + +#: pg_dump.c:1445 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "не знайдено відповідних таблиць для візерунку\"%s\"" + +#: pg_dump.c:1858 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "вивантажування змісту таблиці \"%s.%s\"" + +#: pg_dump.c:1965 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Помилка вивантажування змісту таблиці \"%s\": помилка в PQgetCopyData()." + +#: pg_dump.c:1966 pg_dump.c:1976 +#, c-format +msgid "Error message from server: %s" +msgstr "Повідомлення про помилку від сервера: %s" + +#: pg_dump.c:1967 pg_dump.c:1977 +#, c-format +msgid "The command was: %s" +msgstr "Команда була: %s" + +#: pg_dump.c:1975 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Помилка вивантажування змісту таблиці \"%s\": помилка в PQgetResult(). " + +#: pg_dump.c:2731 +#, c-format +msgid "saving database definition" +msgstr "збереження визначення бази даних" + +#: pg_dump.c:3203 +#, c-format +msgid "saving encoding = %s" +msgstr "збереження кодування = %s" + +#: pg_dump.c:3228 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "збереження standard_conforming_strings = %s" + +#: pg_dump.c:3267 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "не вдалося проаналізувати результат current_schemas()" + +#: pg_dump.c:3286 +#, c-format +msgid "saving search_path = %s" +msgstr "збереження search_path = %s" + +#: pg_dump.c:3326 +#, c-format +msgid "reading large objects" +msgstr "читання великих об’єктів" + +#: pg_dump.c:3508 +#, c-format +msgid "saving large objects" +msgstr "збереження великих об’єктів" + +#: pg_dump.c:3554 +#, c-format +msgid "error reading large object %u: %s" +msgstr "помилка читання великих об’єктів %u: %s" + +#: pg_dump.c:3606 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "читання рядка безпеки активовано для таблиці \"%s.%s\"" + +#: pg_dump.c:3637 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "читання політики для таблиці \"%s.%s\"" + +#: pg_dump.c:3789 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "неочікуваний тип команди в політиці: %c" + +#: pg_dump.c:3940 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "власник публікації \"%s\" здається недійсним" + +#: pg_dump.c:4085 +#, c-format +msgid "reading publication membership for table \"%s.%s\"" +msgstr "читання членства публікації для таблиці \"%s.%s\"" + +#: pg_dump.c:4228 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "підписки не вивантажені через те, що чинний користувач не є суперкористувачем" + +#: pg_dump.c:4282 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "власник підписки \"%s\" є недійсним" + +#: pg_dump.c:4326 +#, c-format +msgid "could not parse subpublications array" +msgstr "не вдалося аналізувати масив підпублікацій" + +#: pg_dump.c:4648 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "не вдалося знайти батьківський елемент для %s %s" + +#: pg_dump.c:4780 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "власник схеми \"%s\" виглядає недійсним" + +#: pg_dump.c:4803 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "схема з OID %u не існує" + +#: pg_dump.c:5128 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "власник типу даних \"%s\" здається недійсним" + +#: pg_dump.c:5213 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "власник оператора \"%s\" здається недійсним" + +#: pg_dump.c:5515 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "власник класу операторів \"%s\" здається недійсним" + +#: pg_dump.c:5599 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "власник сімейства операторів \"%s\" здається недійсним" + +#: pg_dump.c:5768 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "власник агрегатної функції \"%s\" є недійсним" + +#: pg_dump.c:6028 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "власник функції \"%s\" здається недійсним" + +#: pg_dump.c:6856 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "власник таблиці \"%s\" здається недійсним" + +#: pg_dump.c:6898 pg_dump.c:17376 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "помилка цілісності, за OID %u не вдалося знайти батьківську таблицю послідовності з OID %u" + +#: pg_dump.c:7040 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "читання індексів таблиці \"%s.%s\"" + +#: pg_dump.c:7455 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "читання обмежень зовнішніх ключів таблиці \"%s.%s\"" + +#: pg_dump.c:7736 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "помилка цілісності, за OID %u не вдалося знайти батьківську таблицю для запису pg_rewrite з OID %u" + +#: pg_dump.c:7819 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "читання тригерів таблиці \"%s.%s\"" + +#: pg_dump.c:7952 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "запит не повернув ім'я цільової таблиці для тригера зовнішнього ключа \"%s\" в таблиці \"%s\" (OID цільової таблиці: %u)" + +#: pg_dump.c:8507 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "пошук стовпців і типів таблиці \"%s.%s\"" + +#: pg_dump.c:8643 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "неприпустима нумерація стовпців у таблиці \"%s\"" + +#: pg_dump.c:8680 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "пошук виразів за замовчуванням для таблиці \"%s.%s\"" + +#: pg_dump.c:8702 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "неприпустиме значення adnum %d для таблиці \"%s\"" + +#: pg_dump.c:8767 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "пошук обмежень-перевірок для таблиці \"%s.%s\"" + +#: pg_dump.c:8816 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "очікувалось %d обмеження-перевірка для таблиці \"%s\", але знайдено %d" +msgstr[1] "очікувалось %d обмеження-перевірки для таблиці \"%s\", але знайдено %d" +msgstr[2] "очікувалось %d обмежень-перевірок для таблиці \"%s\", але знайдено %d" +msgstr[3] "очікувалось %d обмежень-перевірок для таблиці \"%s\", але знайдено %d" + +#: pg_dump.c:8820 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Можливо, системні каталоги пошкоджені.)" + +#: pg_dump.c:10406 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "typtype типу даних \"%s\" має неприпустимий вигляд" + +#: pg_dump.c:11760 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "неприпустиме значення в масиві proargmodes" + +#: pg_dump.c:12132 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "не вдалося аналізувати масив proallargtypes" + +#: pg_dump.c:12148 +#, c-format +msgid "could not parse proargmodes array" +msgstr "не вдалося аналізувати масив proargmodes" + +#: pg_dump.c:12162 +#, c-format +msgid "could not parse proargnames array" +msgstr "не вдалося аналізувати масив proargnames" + +#: pg_dump.c:12173 +#, c-format +msgid "could not parse proconfig array" +msgstr "не вдалося аналізувати масив proconfig" + +#: pg_dump.c:12253 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "нерозпізнане значення provolatile для функції \"%s\"" + +#: pg_dump.c:12303 pg_dump.c:14361 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "нерозпізнане значення proparallel для функції \"%s\"" + +#: pg_dump.c:12442 pg_dump.c:12551 pg_dump.c:12558 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "не вдалося знайти визначення функції для функції з OID %u" + +#: pg_dump.c:12481 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "неприпустиме значення в полі pg_cast.castfunc або pg_cast.castmethod" + +#: pg_dump.c:12484 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "неприпустиме значення в полі pg_cast.castmethod" + +#: pg_dump.c:12577 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "неприпустиме визначення перетворення, як мінімум одне з trffromsql і trftosql повинно бути ненульовим" + +#: pg_dump.c:12594 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "неприпустиме значення в полі pg_transform.trffromsql" + +#: pg_dump.c:12615 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "неприпустиме значення в полі pg_transform.trftosql" + +#: pg_dump.c:12931 +#, c-format +msgid "could not find operator with OID %s" +msgstr "не вдалося знайти оператора з OID %s" + +#: pg_dump.c:12999 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "неприпустимий тип \"%c\" методу доступу \"%s\"" + +#: pg_dump.c:13753 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "нерозпізнаний постачальник правил сортування: %s" + +#: pg_dump.c:14225 +#, c-format +msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +msgstr "агрегатна функція %s не може бути вивантажена правильно для цієї версії бази даних; пропускається" + +#: pg_dump.c:14280 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "нерозпізнане значення aggfinalmodify для агрегату \"%s\"" + +#: pg_dump.c:14336 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "нерозпізнане значення aggmfinalmodify для агрегату \"%s\"" + +#: pg_dump.c:15058 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "нерозпізнаний тип об’єкта у стандартному праві: %d" + +#: pg_dump.c:15076 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "не вдалося проаналізувати стандартний ACL список (%s)" + +#: pg_dump.c:15161 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "не вдалося аналізувати початковий список GRANT ACL (%s) або початковий список REVOKE ACL (%s) для об'єкта \"%s\" (%s)" + +#: pg_dump.c:15169 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "не вдалося аналізувати список GRANT ACL (%s) або список REVOKE ACL (%s) для об'єкта \"%s\" (%s)" + +#: pg_dump.c:15684 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "запит на отримання визначення перегляду \"%s\" не повернув дані" + +#: pg_dump.c:15687 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "запит на отримання визначення перегляду \"%s\" повернув більше, ніж одне визначення" + +#: pg_dump.c:15694 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "визначення перегляду \"%s\" пусте (довжина нуль)" + +#: pg_dump.c:15776 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS більше не підтримується (таблиця\"%s\")" + +#: pg_dump.c:16256 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "неприпустиме число батьківських елементів %d для таблиці \"%s\"" + +#: pg_dump.c:16579 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "неприпустиме число стовпців %d для таблиці \"%s\"" + +#: pg_dump.c:16864 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "пропущено індекс для обмеження \"%s\"" + +#: pg_dump.c:17089 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "нерозпізнаний тип обмеження: %c" + +#: pg_dump.c:17221 pg_dump.c:17441 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "запит на отримання даних послідовності \"%s\" повернув %d рядки (очікувалося 1)" +msgstr[1] "запит на отримання даних послідовності \"%s\" повернув %d рядки (очікувалося 1)" +msgstr[2] "запит на отримання даних послідовності \"%s\" повернув %d рядків (очікувалося 1)" +msgstr[3] "запит на отримання даних послідовності \"%s\" повернув %d рядків (очікувалося 1)" + +#: pg_dump.c:17255 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "нерозпізнаний тип послідовності: %s" + +#: pg_dump.c:17539 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "неочікуване значення tgtype: %d" + +#: pg_dump.c:17613 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "неприпустимий рядок аргументу (%s) для тригера \"%s\" у таблиці \"%s\"" + +#: pg_dump.c:17849 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "помилка запиту на отримання правила \"%s\" для таблиці \"%s\": повернено неправильне число рядків " + +#: pg_dump.c:18011 +#, c-format +msgid "could not find referenced extension %u" +msgstr "не вдалося знайти згадане розширення %u" + +#: pg_dump.c:18225 +#, c-format +msgid "reading dependency data" +msgstr "читання даних залежності" + +#: pg_dump.c:18318 +#, c-format +msgid "no referencing object %u %u" +msgstr "немає об’єкту посилання %u %u" + +#: pg_dump.c:18329 +#, c-format +msgid "no referenced object %u %u" +msgstr "немає посилання на об'єкт %u %u" + +#: pg_dump.c:18702 +#, c-format +msgid "could not parse reloptions array" +msgstr "неможливо розібрати масив reloptions" + +#: pg_dump_sort.c:360 +#, c-format +msgid "invalid dumpId %d" +msgstr "неприпустимий dumpId %d" + +#: pg_dump_sort.c:366 +#, c-format +msgid "invalid dependency %d" +msgstr "неприпустима залежність %d" + +#: pg_dump_sort.c:599 +#, c-format +msgid "could not identify dependency loop" +msgstr "не вдалося ідентифікувати цикл залежності" + +#: pg_dump_sort.c:1170 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "у наступній таблиці зациклені зовнішні ключі:" +msgstr[1] "у наступних таблицях зациклені зовнішні ключі:" +msgstr[2] "у наступних таблицях зациклені зовнішні ключі:" +msgstr[3] "у наступних таблицях зациклені зовнішні ключі:" + +#: pg_dump_sort.c:1174 pg_dump_sort.c:1194 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1175 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Ви не зможете відновити дамп без використання --disable-triggers або тимчасово розірвати обмеження." + +#: pg_dump_sort.c:1176 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Можливо, використання повного вивантажування замість --data-only вивантажування допоможе уникнути цієї проблеми." + +#: pg_dump_sort.c:1188 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "не вдалося вирішити цикл залежності серед цих елементів:" + +#: pg_dumpall.c:199 +#, c-format +msgid "The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "Програма \"%s\" потрібна для %s, але не знайдена в тому ж каталозі, що й \"%s\".\n" +"Перевірте вашу установку." + +#: pg_dumpall.c:204 +#, c-format +msgid "The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "Програма \"%s\" була знайдена \"%s\", але не була тієї ж версії, що %s.\n" +"Перевірте вашу установку." + +#: pg_dumpall.c:356 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only" +msgstr "параметр --exclude-database не можна використовувати разом з -g/--globals-only, -r/--roles-only або -t/--tablespaces-only" + +#: pg_dumpall.c:365 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "параметри -g/--globals-only і -r/--roles-only не можна використовувати разом" + +#: pg_dumpall.c:373 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "параметри -g/--globals-only і -t/--tablespaces-only не можна використовувати разом" + +#: pg_dumpall.c:387 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "параметри -r/--roles-only і -t/--tablespaces-only не можна використовувати разом" + +#: pg_dumpall.c:448 pg_dumpall.c:1754 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "не вдалося зв'язатися з базою даних \"%s\"" + +#: pg_dumpall.c:462 +#, c-format +msgid "could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "не вдалося зв'язатися з базами даних \"postgres\" або \"template1\"\n" +"Будь ласка, вкажіть альтернативну базу даних." + +#: pg_dumpall.c:616 +#, c-format +msgid "%s extracts a PostgreSQL database cluster into an SQL script file.\n\n" +msgstr "%s експортує кластер баз даних PostgreSQL до SQL-скрипту.\n\n" + +#: pg_dumpall.c:618 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s: [OPTION]...\n" + +#: pg_dumpall.c:621 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=FILENAME ім'я вихідного файлу\n" + +#: pg_dumpall.c:628 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, --clean очистити (видалити) бази даних перед відтворенням\n" + +#: pg_dumpall.c:630 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, --globals-only вивантажувати лише глобальні об’єкти, не бази даних\n" + +#: pg_dumpall.c:631 pg_restore.c:485 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner пропускається відновлення форми власності об’єктом\n" + +#: pg_dumpall.c:632 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr " -r, --roles-only вивантажувати лише ролі, не бази даних або табличні простори\n" + +#: pg_dumpall.c:634 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, --superuser=NAME ім'я суперкористувача для використання при вивантажуванні\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr " -t, --tablespaces-only вивантажувати лише табличні простори, не бази даних або ролі\n" + +#: pg_dumpall.c:641 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=PATTERN виключити бази даних, ім'я яких відповідає PATTERN\n" + +#: pg_dumpall.c:648 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords не вивантажувати паролі для ролей\n" + +#: pg_dumpall.c:662 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=CONNSTR підключення з використанням рядку підключення \n" + +#: pg_dumpall.c:664 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=DBNAME альтернативна база даних за замовчуванням\n" + +#: pg_dumpall.c:671 +#, c-format +msgid "\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n\n" +msgstr "\n" +"Якщо -f/--file не використовується, тоді SQL- сценарій буде записаний до стандартного виводу.\n\n" + +#: pg_dumpall.c:877 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "пропущено ім’я ролі, що починається з \"pg_\" (%s)" + +#: pg_dumpall.c:1278 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "не вдалося аналізувати список ACL (%s) для табличного простору \"%s\"" + +#: pg_dumpall.c:1495 +#, c-format +msgid "excluding database \"%s\"" +msgstr "виключаємо базу даних \"%s\"" + +#: pg_dumpall.c:1499 +#, c-format +msgid "dumping database \"%s\"" +msgstr "вивантажуємо базу даних \"%s\"" + +#: pg_dumpall.c:1531 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "помилка pg_dump для бази даних \"%s\", завершення роботи" + +#: pg_dumpall.c:1540 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "не вдалося повторно відкрити файл виводу \"%s\": %m" + +#: pg_dumpall.c:1584 +#, c-format +msgid "running \"%s\"" +msgstr "виконується \"%s\"" + +#: pg_dumpall.c:1775 +#, c-format +msgid "could not connect to database \"%s\": %s" +msgstr "не вдалося підключитись до бази даних \"%s\": %s" + +#: pg_dumpall.c:1805 +#, c-format +msgid "could not get server version" +msgstr "не вдалося отримати версію серверу" + +#: pg_dumpall.c:1811 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "не вдалося аналізувати версію серверу \"%s\"" + +#: pg_dumpall.c:1883 pg_dumpall.c:1906 +#, c-format +msgid "executing %s" +msgstr "виконується %s" + +#: pg_restore.c:308 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "необхідно вказати один з -d/--dbname або -f/--file" + +#: pg_restore.c:317 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "параметри -d/--dbname і -f/--file не можуть використовуватись разом" + +#: pg_restore.c:343 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "параметри -C/--create і -1/--single-transaction не можуть використовуватись разом" + +#: pg_restore.c:357 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "максимальна кількість паралельних завдань: %d" + +#: pg_restore.c:366 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "параметр --single-transaction допускається лише з одним завданням" + +#: pg_restore.c:408 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "нерозпізнаний формат архіву \"%s\"; будь ласка, вкажіть \"c\", \"d\" або \"t\"" + +#: pg_restore.c:448 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "при відновленні проігноровано помилок: %d" + +#: pg_restore.c:461 +#, c-format +msgid "%s restores a PostgreSQL database from an archive created by pg_dump.\n\n" +msgstr "%s відновлює базу даних PostgreSQL з архіву, створеного командою pg_dump.\n\n" + +#: pg_restore.c:463 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [OPTION]... [FILE]\n" + +#: pg_restore.c:466 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=NAME підключитись до вказаної бази даних\n" + +#: pg_restore.c:467 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=FILENAME ім'я файлу виводу (- для stdout)\n" + +#: pg_restore.c:468 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, --format=c|d|t формат файлу резервної копії (розпізнається автоматично)\n" + +#: pg_restore.c:469 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list вивести короткий зміст архіву\n" + +#: pg_restore.c:470 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose детальний режим\n" + +#: pg_restore.c:471 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію, потім вийти\n" + +#: pg_restore.c:472 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати цю довідку, потім вийти\n" + +#: pg_restore.c:474 +#, c-format +msgid "\n" +"Options controlling the restore:\n" +msgstr "\n" +"Параметри, що керують відновленням:\n" + +#: pg_restore.c:475 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only відновити лише дані, без схеми\n" + +#: pg_restore.c:477 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create створити цільову базу даних\n" + +#: pg_restore.c:478 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, --exit-on-error вийти при помилці, продовжувати за замовчуванням\n" + +#: pg_restore.c:479 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=NAME відновити вказаний індекс\n" + +#: pg_restore.c:480 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, --jobs=NUM щоб виконати відновлення, використайте ці паралельні завдання\n" + +#: pg_restore.c:481 +#, c-format +msgid " -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr " -L, --use-list=FILENAME використовувати зміст з цього файлу для \n" +" вибору/упорядкування даних\n" + +#: pg_restore.c:483 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=NAME відновити об'єкти лише в цій схемі\n" + +#: pg_restore.c:484 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NAME не відновлювати об'єкти в цій схемі\n" + +#: pg_restore.c:486 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NAME(args) відновити вказану функцію\n" + +#: pg_restore.c:487 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only відновити лише схему, без даних\n" + +#: pg_restore.c:488 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr " -S, --superuser=NAME ім'я суперкористувача для вимкнення тригерів\n" + +#: pg_restore.c:489 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=NAME відновити вказане відношення (таблицю, подання і т. д.)\n" + +#: pg_restore.c:490 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=NAME відновити вказаний тригер\n" + +#: pg_restore.c:491 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, --no-privileges пропустити відновлення прав доступу (grant/revoke)\n" + +#: pg_restore.c:492 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction відновити в одній транзакції\n" + +#: pg_restore.c:494 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security активувати захист на рівні рядків\n" + +#: pg_restore.c:496 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments не відновлювати коментарі\n" + +#: pg_restore.c:497 +#, c-format +msgid " --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr " --no-data-for-failed-tables не відновлювати дані таблиць, які не вдалося створити\n" + +#: pg_restore.c:499 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications не відновлювати публікації \n" + +#: pg_restore.c:500 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels не відновлювати мітки безпеки \n" + +#: pg_restore.c:501 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions не відновлювати підписки\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces не відновлювати завдання табличного простору\n" + +#: pg_restore.c:503 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr " --section=SECTION відновлювати названий розділ (pre-data, data або post-data)\n" + +#: pg_restore.c:516 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROLENAME виконати SET ROLE перед відновленням\n" + +#: pg_restore.c:518 +#, c-format +msgid "\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "\n" +"Параметри -I, -n, -N, -P, -t, -T, і --section можна групувати і вказувати\n" +"декілька разів для вибору декількох об'єктів.\n" + +#: pg_restore.c:521 +#, c-format +msgid "\n" +"If no input file name is supplied, then standard input is used.\n\n" +msgstr "\n" +"Якщо ім'я файлу введеня не вказано, тоді використовується стандартне введення.\n\n" + +#~ msgid "ftell mismatch with expected position -- ftell used" +#~ msgstr "невідповідність позиції ftell з очікуваною -- використовується ftell" + +#~ msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +#~ msgstr "не вдалося знайти в архіві блок з ідентифікатором %d -- можливо, через непослідовність запиту відновлення, який не можна обробити через нестачу зсувів даних в архіві" + diff --git a/src/bin/pg_dump/t/001_basic.pl b/src/bin/pg_dump/t/001_basic.pl index cea1d2db5625..9388d64c5a94 100644 --- a/src/bin/pg_dump/t/001_basic.pl +++ b/src/bin/pg_dump/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/src/bin/pg_dump/t/003_pg_dump_with_server.pl b/src/bin/pg_dump/t/003_pg_dump_with_server.pl index dd9a60a2c9f1..f9fea9ddcfe7 100644 --- a/src/bin/pg_dump/t/003_pg_dump_with_server.pl +++ b/src/bin/pg_dump/t/003_pg_dump_with_server.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/src/bin/pg_dump/t/010_dump_connstr.pl b/src/bin/pg_dump/t/010_dump_connstr.pl index 617d153e3eaf..76be7870eea8 100644 --- a/src/bin/pg_dump/t/010_dump_connstr.pl +++ b/src/bin/pg_dump/t/010_dump_connstr.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; @@ -27,7 +30,7 @@ # The odds of finding something interesting by testing all ASCII letters # seem too small to justify the cycles of testing a fifth name. my $dbname1 = - 'regression' + 'regression' . generate_ascii_string(1, 9) . generate_ascii_string(11, 12) . generate_ascii_string(14, 33) diff --git a/src/bin/pg_resetwal/Makefile b/src/bin/pg_resetwal/Makefile index 464268e9788a..7dfa80c5e51f 100644 --- a/src/bin/pg_resetwal/Makefile +++ b/src/bin/pg_resetwal/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_resetwal # -# Copyright (c) 1998-2020, PostgreSQL Global Development Group +# Copyright (c) 1998-2021, PostgreSQL Global Development Group # # src/bin/pg_resetwal/Makefile # diff --git a/src/bin/pg_resetwal/nls.mk b/src/bin/pg_resetwal/nls.mk index cc40875b482b..5b54c18a3c9d 100644 --- a/src/bin/pg_resetwal/nls.mk +++ b/src/bin/pg_resetwal/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_resetwal/nls.mk CATALOG_NAME = pg_resetwal -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr zh_CN +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr uk zh_CN GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_resetwal.c ../../common/restricted_token.c GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index d82dd19ca659..fafa4e0db043 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -20,7 +20,7 @@ * step 2 ... * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_resetwal/pg_resetwal.c diff --git a/src/bin/pg_resetwal/po/cs.po b/src/bin/pg_resetwal/po/cs.po new file mode 100644 index 000000000000..f1ec4d9da15c --- /dev/null +++ b/src/bin/pg_resetwal/po/cs.po @@ -0,0 +1,721 @@ +# Czech message translation file for pg_resetxlog +# Copyright (C) 2012 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Tomas Vondra , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: pg_resetxlog-cs (PostgreSQL 9.3)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:15+0000\n" +"PO-Revision-Date: 2020-10-31 21:25+0100\n" +"Last-Translator: Tomas Vondra \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.4.1\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "warning: " + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "nelze načíst knihovnu \"%s\": kód chyby %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "na této platformě nelze vytvářet vyhrazené tokeny: kód chyby %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "nelze otevřít process token: chybový kód %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "nelze alokovat SIDs: chybový kód %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "nelze vytvořit vyhrazený token: chybový kód %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "nelze spustit proces pro příkaz \"%s\": chybový kód %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "nelze znovu spustit s vyhrazeným tokenem: chybový kód %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "nelze získat návratový kód ze subprocesu: chybový kód %lu" + +#. translator: the second %s is a command line argument (-e, etc) +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 +#, c-format +msgid "invalid argument for option %s" +msgstr "neplatný argument pro volbu %s" + +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: pg_resetwal.c:166 +#, c-format +msgid "transaction ID epoch (-e) must not be -1" +msgstr "epocha ID transakce (-e) nesmí být -1" + +#: pg_resetwal.c:181 +#, c-format +msgid "transaction ID (-x) must not be 0" +msgstr "ID transakce (-x) nesmí být 0" + +#: pg_resetwal.c:205 pg_resetwal.c:212 +#, c-format +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "ID transakce (-c) musí být buď 0 nebo větší než nebo rovno 2" + +#: pg_resetwal.c:227 +#, c-format +msgid "OID (-o) must not be 0" +msgstr "OID (-o) nesmí být 0" + +#: pg_resetwal.c:250 +#, c-format +msgid "multitransaction ID (-m) must not be 0" +msgstr "ID multitransakce (-m) nesmí být 0" + +#: pg_resetwal.c:260 +#, c-format +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "ID nejstarší multitransakce (-m) nesmí být 0" + +#: pg_resetwal.c:275 +#, c-format +msgid "multitransaction offset (-O) must not be -1" +msgstr "offset multitransakce (-O) nesmí být -1" + +#: pg_resetwal.c:299 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "argument pro --wal-segsize musí být číslo" + +#: pg_resetwal.c:304 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "argument pro --wal-segsize musí být mocnina 2 mezi 1 a 1024" + +#: pg_resetwal.c:321 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "příliš mnoho parametrů na příkazové řádce (první je \"%s\")" + +#: pg_resetwal.c:330 +#, c-format +msgid "no data directory specified" +msgstr "není specifikován datový adresář" + +#: pg_resetwal.c:344 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "nelze spouštět jako \"root\"" + +#: pg_resetwal.c:345 +#, c-format +msgid "You must run %s as the PostgreSQL superuser." +msgstr "Musíte spustit %s jako PostgreSQL superuživatel." + +#: pg_resetwal.c:356 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "nelze zjistit přístupová práva adresáře \"%s\": %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "nelze změnit adresář na \"%s\" : %m" + +#: pg_resetwal.c:381 pg_resetwal.c:544 pg_resetwal.c:595 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "nelze otevřít soubor \"%s\" pro čtení: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "soubor se zámkem \"%s\" existuje" + +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "Neběží již server? Jestliže ne, smažte soubor se zámkem a zkuste to znova." + +#: pg_resetwal.c:492 +#, c-format +msgid "" +"\n" +"If these values seem acceptable, use -f to force reset.\n" +msgstr "" +"\n" +"Jestliže tyto hodnoty vypadají akceptovatelně, použijte -f pro vynucený reset.\n" + +#: pg_resetwal.c:504 +#, c-format +msgid "" +"The database server was not shut down cleanly.\n" +"Resetting the write-ahead log might cause data to be lost.\n" +"If you want to proceed anyway, use -f to force reset.\n" +msgstr "" +"Databázový server nebyl ukončen čistě.\n" +"Resetování transakčního logu může způsobit ztrátu dat.\n" +"Jestliže i přesto chcete pokračovat, použijte -f pro vynucený reset.\n" + +#: pg_resetwal.c:518 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "Transakční log resetován\n" + +#: pg_resetwal.c:553 +#, c-format +msgid "unexpected empty file \"%s\"" +msgstr "neočekávaný prázdný soubor \"%s\"" + +#: pg_resetwal.c:555 pg_resetwal.c:611 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "nelze číst soubor \"%s\": %m" + +#: pg_resetwal.c:564 +#, c-format +msgid "data directory is of wrong version" +msgstr "datový adresář pochází z nesprávné verze" + +#: pg_resetwal.c:565 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "Soubor \"%s\" obsahuje \"%s\", což je nekompatibilní s verzí \"%s\" tohoto programu." + +#: pg_resetwal.c:598 +#, c-format +msgid "" +"If you are sure the data directory path is correct, execute\n" +" touch %s\n" +"and try again." +msgstr "" +"Máte-li jistotu, že je cesta k datovému adresáři správná, proveďte\n" +" touch %s\n" +"a zkuste to znovu." + +#: pg_resetwal.c:629 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "pg_control existuje, ale s neplatným kontrolním součtem CRC; postupujte opatrně" + +#: pg_resetwal.c:638 +#, c-format +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_control obsahuje neplatnou velikost WAL segmentu (%d byte); pokračujte obezřetně" +msgstr[1] "pg_control obsahuje neplatnou velikost WAL segmentu (%d bytů); pokračujte obezřetně" +msgstr[2] "pg_control obsahuje neplatnou velikost WAL segmentu (%d bytů); pokračujte obezřetně" + +#: pg_resetwal.c:649 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "pg_control existuje, ale je poškozen nebo neznámé verze; ignoruji to" + +#: pg_resetwal.c:744 +#, c-format +msgid "" +"Guessed pg_control values:\n" +"\n" +msgstr "" +"Odhadnuté hodnoty pg_controlu:\n" +"\n" + +#: pg_resetwal.c:746 +#, c-format +msgid "" +"Current pg_control values:\n" +"\n" +msgstr "" +"Současné pg_control hodnoty:\n" +"\n" + +#: pg_resetwal.c:748 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "Číslo verze pg_controlu: %u\n" + +#: pg_resetwal.c:750 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Číslo verze katalogu: %u\n" + +#: pg_resetwal.c:752 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "" +"Identifikátor databázového systému: %llu\n" +"\n" + +#: pg_resetwal.c:754 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "TimeLineID posledního checkpointu: %u\n" + +#: pg_resetwal.c:756 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Poslední full_page_writes checkpointu: %s\n" + +#: pg_resetwal.c:757 +msgid "off" +msgstr "vypnuto" + +#: pg_resetwal.c:757 +msgid "on" +msgstr "zapnuto" + +#: pg_resetwal.c:758 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID posledního checkpointu: %u:%u\n" + +#: pg_resetwal.c:761 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "Poslední umístění NextOID checkpointu: %u\n" + +#: pg_resetwal.c:763 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "NextMultiXactId posledního checkpointu: %u\n" + +#: pg_resetwal.c:765 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "NextMultiOffset posledního checkpointu: %u\n" + +#: pg_resetwal.c:767 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "oldestXID posledního checkpointu: %u\n" + +#: pg_resetwal.c:769 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "DB k oldestXID posledního checkpointu: %u\n" + +#: pg_resetwal.c:771 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "oldestActiveXID posledního checkpointu: %u\n" + +#: pg_resetwal.c:773 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "oldestMultiXid posledního checkpointu: %u\n" + +#: pg_resetwal.c:775 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "DB k oldestMulti posledního checkpointu: %u\n" + +#: pg_resetwal.c:777 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "oldestCommitTsXid posledního checkpointu: %u\n" + +#: pg_resetwal.c:779 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "newestCommitTsXid posledního checkpointu: %u\n" + +#: pg_resetwal.c:781 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Maximální zarovnání dat: %u\n" + +#: pg_resetwal.c:784 +#, c-format +msgid "Database block size: %u\n" +msgstr "Velikost databázového bloku: %u\n" + +#: pg_resetwal.c:786 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Bloků v segmentu velké relace: %u\n" + +#: pg_resetwal.c:788 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Velikost WAL bloku: %u\n" + +#: pg_resetwal.c:790 pg_resetwal.c:876 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Bytů ve WAL segmentu: %u\n" + +#: pg_resetwal.c:792 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Maximální délka identifikátorů: %u\n" + +#: pg_resetwal.c:794 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Maximální počet sloupců v indexu: %u\n" + +#: pg_resetwal.c:796 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Maximální velikost úseku TOAST: %u\n" + +#: pg_resetwal.c:798 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Velikost large-object chunku: %u\n" + +#: pg_resetwal.c:801 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Způsob uložení typu date/time: %s\n" + +#: pg_resetwal.c:802 +msgid "64-bit integers" +msgstr "64-bitová čísla" + +#: pg_resetwal.c:803 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Způsob předávání float8 hodnot: %s\n" + +#: pg_resetwal.c:804 +msgid "by reference" +msgstr "odkazem" + +#: pg_resetwal.c:804 +msgid "by value" +msgstr "hodnotou" + +#: pg_resetwal.c:805 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Verze kontrolních součtů datových stránek: %u\n" + +#: pg_resetwal.c:819 +#, c-format +msgid "" +"\n" +"\n" +"Values to be changed:\n" +"\n" +msgstr "" +"\n" +"\n" +"Hodnoty které se změní:\n" +"\n" + +#: pg_resetwal.c:823 +#, c-format +msgid "First log segment after reset: %s\n" +msgstr "První log segment po resetu: %s\n" + +#: pg_resetwal.c:827 +#, c-format +msgid "NextMultiXactId: %u\n" +msgstr "NextMultiXactId: %u\n" + +#: pg_resetwal.c:829 +#, c-format +msgid "OldestMultiXid: %u\n" +msgstr "OldestMultiXid: %u\n" + +#: pg_resetwal.c:831 +#, c-format +msgid "OldestMulti's DB: %u\n" +msgstr "DB k OldestMulti: %u\n" + +#: pg_resetwal.c:837 +#, c-format +msgid "NextMultiOffset: %u\n" +msgstr "NextMultiOffset: %u\n" + +#: pg_resetwal.c:843 +#, c-format +msgid "NextOID: %u\n" +msgstr "NextOID: %u\n" + +#: pg_resetwal.c:849 +#, c-format +msgid "NextXID: %u\n" +msgstr "NextXID: %u\n" + +#: pg_resetwal.c:851 +#, c-format +msgid "OldestXID: %u\n" +msgstr "OldestXID: %u\n" + +#: pg_resetwal.c:853 +#, c-format +msgid "OldestXID's DB: %u\n" +msgstr "DB k OldestXID: %u\n" + +#: pg_resetwal.c:859 +#, c-format +msgid "NextXID epoch: %u\n" +msgstr "NextXID epoch: %u\n" + +#: pg_resetwal.c:865 +#, c-format +msgid "oldestCommitTsXid: %u\n" +msgstr "oldestCommitTsXid: %u\n" + +#: pg_resetwal.c:870 +#, c-format +msgid "newestCommitTsXid: %u\n" +msgstr "newestCommitTsXid: %u\n" + +#: pg_resetwal.c:956 pg_resetwal.c:1024 pg_resetwal.c:1071 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "nelze otevřít adresář \"%s\": %m" + +#: pg_resetwal.c:991 pg_resetwal.c:1044 pg_resetwal.c:1094 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "nelze číst z adresáře \"%s\": %m" + +#: pg_resetwal.c:997 pg_resetwal.c:1050 pg_resetwal.c:1100 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "nelze zavřít adresář \"%s\": %m" + +#: pg_resetwal.c:1036 pg_resetwal.c:1086 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "nelze smazat soubor \"%s\": %m" + +#: pg_resetwal.c:1167 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "nelze otevřít soubor \"%s\": %m" + +#: pg_resetwal.c:1177 pg_resetwal.c:1190 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "nelze zapsat soubor \"%s\": %m" + +#: pg_resetwal.c:1197 +#, c-format +msgid "fsync error: %m" +msgstr "fsync error: %m" + +#: pg_resetwal.c:1208 +#, c-format +msgid "" +"%s resets the PostgreSQL write-ahead log.\n" +"\n" +msgstr "" +"%s resetuje PostgreSQL transakční log.\n" +"\n" + +#: pg_resetwal.c:1209 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... DATADIR\n" +"\n" +msgstr "" +"Použití:\n" +" %s [VOLBA]... ADRESÁŘ\n" +"\n" + +#: pg_resetwal.c:1210 +#, c-format +msgid "Options:\n" +msgstr "Přepínače:\n" + +#: pg_resetwal.c:1211 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" nastaví nejstarší a nejnovější s nastaveným\n" +" commit timestamp (nula znamená beze změny)\n" + +#: pg_resetwal.c:1214 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]ADRESÁŘ datový adresář\n" + +#: pg_resetwal.c:1215 +#, c-format +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH nastaví epochu následujícího ID transakce\n" + +#: pg_resetwal.c:1216 +#, c-format +msgid " -f, --force force update to be done\n" +msgstr " -f, --force vynutí provedení update\n" + +#: pg_resetwal.c:1217 +#, c-format +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr " -l, --next-wal-file=WALFILE vynutí minimální počáteční WAL pozici pro nový transakční log\n" + +#: pg_resetwal.c:1218 +#, c-format +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr " -m, --multixact-ids=MXID,MXID nastav další a nejstarší ID multitransakce\n" + +#: pg_resetwal.c:1219 +#, c-format +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr " -n, --dry-run bez update, pouze ukáže co by bylo provedeno\n" + +#: pg_resetwal.c:1220 +#, c-format +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID nastaví následující OID\n" + +#: pg_resetwal.c:1221 +#, c-format +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr " -O, --multixact-offset=OFFSET nastaví offset následující multitransakce\n" + +#: pg_resetwal.c:1222 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version ukáže informace o verzi a skončí\n" + +#: pg_resetwal.c:1223 +#, c-format +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID nastaví ID následující transakce\n" + +#: pg_resetwal.c:1224 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=VELIKOST velikost WAL segmentů, v megabytech\n" + +#: pg_resetwal.c:1225 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ukáže tuto nápovědu a skončí\n" + +#: pg_resetwal.c:1226 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Chyby hlašte na <%s>.\n" + +#: pg_resetwal.c:1227 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#~ msgid "%s: cannot be executed by \"root\"\n" +#~ msgstr "%s: nemůže být spuštěn uživatelem \"root\"\n" + +#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" +#~ msgstr "%s: nelze načíst přístupová práva pro adresář \"%s\": %s\n" + +#~ msgid "%s: could not change directory to \"%s\": %s\n" +#~ msgstr "%s: nelze změnit adresář na \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: nelze otevřít soubor \"%s\" pro čtení: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: nelze číst soubor \"%s\": %s\n" + +#~ msgid "%s: could not create pg_control file: %s\n" +#~ msgstr "%s: nelze vytvořit pg_control soubor: %s\n" + +#~ msgid "%s: could not write pg_control file: %s\n" +#~ msgstr "%s: nelze zapsat pg_control soubor: %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít adresář \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: nelze číst z adresáře \"%s\": %s\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: nelze zavřít adresář \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít soubor \"%s\": %s\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s: nelze zapsat do souboru \"%s\": %s\n" + +#~ msgid "%s: invalid argument for option -x\n" +#~ msgstr "%s: neplatný argument pro volbu -x\n" + +#~ msgid "%s: invalid argument for option -o\n" +#~ msgstr "%s: neplatný argument pro volbu -o\n" + +#~ msgid "%s: invalid argument for option -m\n" +#~ msgstr "%s: neplatný argument pro volbu -m\n" + +#~ msgid "%s: invalid argument for option -O\n" +#~ msgstr "%s: neplatný argument pro volbu -O\n" + +#~ msgid "%s: invalid argument for option -l\n" +#~ msgstr "%s: neplatný argument pro volbu -l\n" + +#~ msgid "floating-point numbers" +#~ msgstr "čísla s plovoucí řádovou čárkou" + +#~ msgid "%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n" +#~ msgstr "%s: interní chyba -- sizeof(ControlFileData) je příliš velký ... opravte PG_CONTROL_SIZE\n" + +#~ msgid "First log file ID after reset: %u\n" +#~ msgstr "První ID log souboru po resetu: %u\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" + +#~ msgid "Float4 argument passing: %s\n" +#~ msgstr "Způsob předávání float4 hodnot: %s\n" diff --git a/src/bin/pg_resetwal/po/es.po b/src/bin/pg_resetwal/po/es.po new file mode 100644 index 000000000000..4403bc0908c8 --- /dev/null +++ b/src/bin/pg_resetwal/po/es.po @@ -0,0 +1,663 @@ +# Spanish message translation file for pg_resetwal +# +# Copyright (c) 2003-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Ivan Hernandez , 2003. +# Alvaro Herrera , 2004-2014 +# Jaime Casanova , 2005 +# Martín Marqués , 2013-2014 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_resetwal (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-13 10:46+0000\n" +"PO-Revision-Date: 2019-06-06 17:24-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "no se pudo cargar la biblioteca «%s»: código de error %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "no se pueden crear tokens restrigidos en esta plataforma: código de error %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "no se pudo abrir el token de proceso: código de error %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "no se pudo emplazar los SIDs: código de error %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "no se pudo crear el token restringido: código de error %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "no se pudo iniciar el proceso para la orden «%s»: código de error %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "no se pudo re-ejecutar con el token restringido: código de error %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "no se pudo obtener el código de salida del subproceso»: código de error %lu" + +#. translator: the second %s is a command line argument (-e, etc) +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 +#, c-format +msgid "invalid argument for option %s" +msgstr "argumento no válido para la opción %s" + +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Prueba con «%s --help» para más información\n" + +#: pg_resetwal.c:166 +#, c-format +msgid "transaction ID epoch (-e) must not be -1" +msgstr "el «epoch» de ID de transacción (-e) no debe ser -1" + +#: pg_resetwal.c:181 +#, c-format +msgid "transaction ID (-x) must not be 0" +msgstr "el ID de transacción (-x) no debe ser 0" + +#: pg_resetwal.c:205 pg_resetwal.c:212 +#, c-format +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "el ID de transacción (-c) debe ser 0 o bien mayor o igual a 2" + +#: pg_resetwal.c:227 +#, c-format +msgid "OID (-o) must not be 0" +msgstr "OID (-o) no debe ser cero" + +#: pg_resetwal.c:250 +#, c-format +msgid "multitransaction ID (-m) must not be 0" +msgstr "el ID de multitransacción (-m) no debe ser 0" + +#: pg_resetwal.c:260 +#, c-format +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "el ID de multitransacción más antiguo (-m) no debe ser 0" + +#: pg_resetwal.c:275 +#, c-format +msgid "multitransaction offset (-O) must not be -1" +msgstr "la posición de multitransacción (-O) no debe ser -1" + +#: pg_resetwal.c:299 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "el argumento de --wal-segsize debe ser un número" + +#: pg_resetwal.c:304 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "el argumento de --wal-segsize debe ser una potencia de 2 entre 1 y 1024" + +#: pg_resetwal.c:321 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_resetwal.c:330 +#, c-format +msgid "no data directory specified" +msgstr "directorio de datos no especificado" + +#: pg_resetwal.c:344 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "no puede ser ejecutado con el usuario «root»" + +#: pg_resetwal.c:345 +#, c-format +msgid "You must run %s as the PostgreSQL superuser." +msgstr "Debe ejecutar %s con el superusuario de PostgreSQL." + +#: pg_resetwal.c:356 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "no se pudo obtener los permisos del directorio «%s»: %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: pg_resetwal.c:381 pg_resetwal.c:544 pg_resetwal.c:595 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "el archivo candado «%s» existe" + +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "¿Hay un servidor corriendo? Si no, borre el archivo candado e inténtelo de nuevo." + +#: pg_resetwal.c:492 +#, c-format +msgid "" +"\n" +"If these values seem acceptable, use -f to force reset.\n" +msgstr "" +"\n" +"Si estos valores parecen aceptables, use -f para forzar reinicio.\n" + +#: pg_resetwal.c:504 +#, c-format +msgid "" +"The database server was not shut down cleanly.\n" +"Resetting the write-ahead log might cause data to be lost.\n" +"If you want to proceed anyway, use -f to force reset.\n" +msgstr "" +"El servidor de bases de datos no se apagó limpiamente.\n" +"Restablecer el WAL puede causar pérdida de datos.\n" +"Si quiere continuar de todas formas, use -f para forzar el restablecimiento.\n" + +#: pg_resetwal.c:518 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "«Write-ahead log» restablecido\n" + +#: pg_resetwal.c:553 +#, c-format +msgid "unexpected empty file \"%s\"" +msgstr "archivo vacío inesperado «%s»" + +#: pg_resetwal.c:555 pg_resetwal.c:611 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: pg_resetwal.c:564 +#, c-format +msgid "data directory is of wrong version" +msgstr "el directorio de datos tiene la versión equivocada" + +#: pg_resetwal.c:565 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "El archivo «%s» contiene «%s», que no es compatible con la versión «%s» de este programa." + +#: pg_resetwal.c:598 +#, c-format +msgid "" +"If you are sure the data directory path is correct, execute\n" +" touch %s\n" +"and try again." +msgstr "" +"Si está seguro que la ruta al directorio de datos es correcta, ejecute\n" +" touch %s\n" +"y pruebe de nuevo." + +#: pg_resetwal.c:629 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "existe pg_control pero tiene un CRC no válido, proceda con precaución" + +#: pg_resetwal.c:638 +#, c-format +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_control especifica un tamaño de segmento de WAL no válido (%d byte), proceda con precaución" +msgstr[1] "pg_control especifica un tamaño de segmento de WAL no válido (%d bytes), proceda con precaución" + +#: pg_resetwal.c:649 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "existe pg_control pero está roto o tiene la versión equivocada; ignorándolo" + +#: pg_resetwal.c:744 +#, c-format +msgid "" +"Guessed pg_control values:\n" +"\n" +msgstr "" +"Valores de pg_control asumidos:\n" +"\n" + +#: pg_resetwal.c:746 +#, c-format +msgid "" +"Current pg_control values:\n" +"\n" +msgstr "" +"Valores actuales de pg_control:\n" +"\n" + +#: pg_resetwal.c:748 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "Número de versión de pg_control: %u\n" + +#: pg_resetwal.c:750 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Número de versión de catálogo: %u\n" + +#: pg_resetwal.c:752 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "Identificador de sistema: %llu\n" + +#: pg_resetwal.c:754 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "TimeLineID del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:756 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "full_page_writes del checkpoint más reciente: %s\n" + +#: pg_resetwal.c:757 +msgid "off" +msgstr "desactivado" + +#: pg_resetwal.c:757 +msgid "on" +msgstr "activado" + +#: pg_resetwal.c:758 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID del checkpoint más reciente: %u:%u\n" + +#: pg_resetwal.c:761 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "NextOID del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:763 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "NextMultiXactId del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:765 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "NextMultiOffset del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:767 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "oldestXID del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:769 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "BD del oldestXID del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:771 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "oldestActiveXID del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:773 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "oldestMultiXid del checkpoint más reciente: %u\n" + +#: pg_resetwal.c:775 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "BD del oldestMultiXid del checkpt. más reciente: %u\n" + +#: pg_resetwal.c:777 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "oldestCommitTsXid del último checkpoint: %u\n" + +#: pg_resetwal.c:779 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "newestCommitTsXid del último checkpoint: %u\n" + +#: pg_resetwal.c:781 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Máximo alineamiento de datos: %u\n" + +#: pg_resetwal.c:784 +#, c-format +msgid "Database block size: %u\n" +msgstr "Tamaño del bloque de la base de datos: %u\n" + +#: pg_resetwal.c:786 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Bloques por segmento de relación grande: %u\n" + +#: pg_resetwal.c:788 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Tamaño del bloque de WAL: %u\n" + +#: pg_resetwal.c:790 pg_resetwal.c:876 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Bytes por segmento WAL: %u\n" + +#: pg_resetwal.c:792 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Longitud máxima de identificadores: %u\n" + +#: pg_resetwal.c:794 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Máximo número de columnas en un índice: %u\n" + +#: pg_resetwal.c:796 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Longitud máxima de un trozo TOAST: %u\n" + +#: pg_resetwal.c:798 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Longitud máxima de un trozo de objeto grande: %u\n" + +#: pg_resetwal.c:801 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Tipo de almacenamiento hora/fecha: %s\n" + +#: pg_resetwal.c:802 +msgid "64-bit integers" +msgstr "enteros de 64 bits" + +#: pg_resetwal.c:803 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Paso de parámetros float8: %s\n" + +#: pg_resetwal.c:804 +msgid "by reference" +msgstr "por referencia" + +#: pg_resetwal.c:804 +msgid "by value" +msgstr "por valor" + +#: pg_resetwal.c:805 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Versión de suma de verificación de datos: %u\n" + +#: pg_resetwal.c:819 +#, c-format +msgid "" +"\n" +"\n" +"Values to be changed:\n" +"\n" +msgstr "" +"\n" +"\n" +"Valores a cambiar:\n" +"\n" + +#: pg_resetwal.c:823 +#, c-format +msgid "First log segment after reset: %s\n" +msgstr "Primer segmento de log después de reiniciar: %s\n" + +#: pg_resetwal.c:827 +#, c-format +msgid "NextMultiXactId: %u\n" +msgstr "NextMultiXactId: %u\n" + +#: pg_resetwal.c:829 +#, c-format +msgid "OldestMultiXid: %u\n" +msgstr "OldestMultiXid: %u\n" + +#: pg_resetwal.c:831 +#, c-format +msgid "OldestMulti's DB: %u\n" +msgstr "Base de datos del OldestMulti: %u\n" + +#: pg_resetwal.c:837 +#, c-format +msgid "NextMultiOffset: %u\n" +msgstr "NextMultiOffset: %u\n" + +#: pg_resetwal.c:843 +#, c-format +msgid "NextOID: %u\n" +msgstr "NextOID: %u\n" + +#: pg_resetwal.c:849 +#, c-format +msgid "NextXID: %u\n" +msgstr "NextXID: %u\n" + +#: pg_resetwal.c:851 +#, c-format +msgid "OldestXID: %u\n" +msgstr "OldestXID: %u\n" + +#: pg_resetwal.c:853 +#, c-format +msgid "OldestXID's DB: %u\n" +msgstr "Base de datos del OldestXID: %u\n" + +#: pg_resetwal.c:859 +#, c-format +msgid "NextXID epoch: %u\n" +msgstr "Epoch del NextXID: %u\n" + +#: pg_resetwal.c:865 +#, c-format +msgid "oldestCommitTsXid: %u\n" +msgstr "oldestCommitTsXid: %u\n" + +#: pg_resetwal.c:870 +#, c-format +msgid "newestCommitTsXid: %u\n" +msgstr "newestCommitTsXid: %u\n" + +#: pg_resetwal.c:956 pg_resetwal.c:1024 pg_resetwal.c:1071 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_resetwal.c:991 pg_resetwal.c:1044 pg_resetwal.c:1094 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" + +#: pg_resetwal.c:997 pg_resetwal.c:1050 pg_resetwal.c:1100 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_resetwal.c:1036 pg_resetwal.c:1086 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "no se pudo borrar el archivo «%s»: %m" + +#: pg_resetwal.c:1167 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: pg_resetwal.c:1177 pg_resetwal.c:1190 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" + +#: pg_resetwal.c:1197 +#, c-format +msgid "fsync error: %m" +msgstr "error de fsync: %m" + +#: pg_resetwal.c:1208 +#, c-format +msgid "" +"%s resets the PostgreSQL write-ahead log.\n" +"\n" +msgstr "" +"%s restablece el WAL («write-ahead log») de PostgreSQL.\n" +"\n" + +#: pg_resetwal.c:1209 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... DATADIR\n" +"\n" +msgstr "" +"Uso:\n" +" %s [OPCIÓN]... DATADIR\n" +"\n" + +#: pg_resetwal.c:1210 +#, c-format +msgid "Options:\n" +msgstr "Opciones:\n" + +#: pg_resetwal.c:1211 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" definir la más antigua y la más nueva transacciones\n" +" que llevan timestamp de commit (cero significa no\n" +" cambiar)\n" + +#: pg_resetwal.c:1214 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR directorio de datos\n" + +#: pg_resetwal.c:1215 +#, c-format +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH asigna el siguiente «epoch» de ID de transacción\n" + +#: pg_resetwal.c:1216 +#, c-format +msgid " -f, --force force update to be done\n" +msgstr " -f, --force fuerza que la actualización sea hecha\n" + +#: pg_resetwal.c:1217 +#, c-format +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr "" +" -l, --next-wal-file=ARCHIVOWAL\n" +" fuerza una ubicación inicial mínima para nuevo WAL\n" + +#: pg_resetwal.c:1218 +#, c-format +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr "" +" -m, --multixact-ids=MXID,MXID\n" +" asigna el siguiente ID de multitransacción y\n" +" el más antiguo\n" + +#: pg_resetwal.c:1219 +#, c-format +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr " -n, --dry-run no actualiza, sólo muestra lo que se haría\n" + +#: pg_resetwal.c:1220 +#, c-format +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID asigna el siguiente OID\n" + +#: pg_resetwal.c:1221 +#, c-format +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr "" +" -O, --multixact-offset=OFFSET\n" +" asigna la siguiente posición de multitransacción\n" + +#: pg_resetwal.c:1222 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: pg_resetwal.c:1223 +#, c-format +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr "" +" -x, --next-transaction-id=XID\n" +" asigna el siguiente ID de transacción\n" + +#: pg_resetwal.c:1224 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=TAMAÑO tamaño de segmentos de WAL, en megabytes\n" + +#: pg_resetwal.c:1225 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: pg_resetwal.c:1226 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_resetwal.c:1227 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" diff --git a/src/bin/pg_resetwal/po/ja.po b/src/bin/pg_resetwal/po/ja.po new file mode 100644 index 000000000000..b14af6e21dd0 --- /dev/null +++ b/src/bin/pg_resetwal/po/ja.po @@ -0,0 +1,740 @@ +# Japanese message translation file for pg_resetwal +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# Shigehiro Honda , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_resetwal (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:55+0900\n" +"PO-Revision-Date: 2020-09-13 08:56+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "ライブラリ\"%s\"をロードできませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "このプラットフォームでは制限付きトークンを生成できません: エラーコード %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "プロセストークンをオープンできませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SIDを割り当てられませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "制限付きトークンを作成できませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\"コマンドのプロセスを起動できませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "制限付きトークンで再実行できませんでした: %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "サブプロセスの終了コードを入手できませんでした。: エラーコード %lu" + +#. translator: the second %s is a command line argument (-e, etc) +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 +#, c-format +msgid "invalid argument for option %s" +msgstr "オプション%sの引数が不正です" + +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"を実行してください。\n" + +#: pg_resetwal.c:166 +#, c-format +msgid "transaction ID epoch (-e) must not be -1" +msgstr "トランザクションIDの基点(-e)は-1にはできません" + +#: pg_resetwal.c:181 +#, c-format +msgid "transaction ID (-x) must not be 0" +msgstr "トランザクションID(-x)は0にはできません" + +#: pg_resetwal.c:205 pg_resetwal.c:212 +#, c-format +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "トランザクションID(-c)は0もしくは2以上でなければなりません" + +#: pg_resetwal.c:227 +#, c-format +msgid "OID (-o) must not be 0" +msgstr "OID(-o)は0にはできません" + +#: pg_resetwal.c:250 +#, c-format +msgid "multitransaction ID (-m) must not be 0" +msgstr "マルチトランザクションID(-m)は0にはできません" + +#: pg_resetwal.c:260 +#, c-format +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "最古のマルチトランザクションID(-m)は0にはできません" + +#: pg_resetwal.c:275 +#, c-format +msgid "multitransaction offset (-O) must not be -1" +msgstr "マルチトランザクションオフセット(-O)は-1にはできません" + +#: pg_resetwal.c:299 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "--wal-segsizの引数は数値でなければなりません" + +#: pg_resetwal.c:304 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "--wal-segsizeの引数は1から1024の間の2のべき乗でなければなりません" + +#: pg_resetwal.c:321 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "コマンドライン引数が多すぎます。(先頭は\"%s\")" + +#: pg_resetwal.c:330 +#, c-format +msgid "no data directory specified" +msgstr "データディレクトリが指定されていません" + +#: pg_resetwal.c:344 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "\"root\"では実行できません" + +#: pg_resetwal.c:345 +#, c-format +msgid "You must run %s as the PostgreSQL superuser." +msgstr "PostgreSQLのスーパユーザで%sを実行しなければなりません" + +#: pg_resetwal.c:356 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"の権限を読み取れませんでした: %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "ディレクトリ\"%s\"に移動できませんでした: %m" + +#: pg_resetwal.c:381 pg_resetwal.c:544 pg_resetwal.c:595 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "ファイル\"%s\"を読み取り用にオープンできませんでした: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "ロックファイル\"%s\"が存在します" + +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "サーバが稼動していませんか? そうでなければロックファイルを削除し再実行してください。" + +#: pg_resetwal.c:492 +#, c-format +msgid "" +"\n" +"If these values seem acceptable, use -f to force reset.\n" +msgstr "" +"\n" +"この値が適切だと思われるのであれば、-fを使用して強制リセットしてください。\n" + +#: pg_resetwal.c:504 +#, c-format +msgid "" +"The database server was not shut down cleanly.\n" +"Resetting the write-ahead log might cause data to be lost.\n" +"If you want to proceed anyway, use -f to force reset.\n" +msgstr "" +"データベースサーバが正しくシャットダウンされていませんでした。\n" +"先行書き込みログのリセットにはデータ損失の恐れがあります。\n" +"とにかく処理したいのであれば、-fでリセットを強制してください。\n" + +#: pg_resetwal.c:518 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "先行書き込みログがリセットされました\n" + +#: pg_resetwal.c:553 +#, c-format +msgid "unexpected empty file \"%s\"" +msgstr "想定外の空のファイル\"%s\"" + +#: pg_resetwal.c:555 pg_resetwal.c:611 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "ファイル\"%s\"の読み取りに失敗しました: %m" + +#: pg_resetwal.c:564 +#, c-format +msgid "data directory is of wrong version" +msgstr "データディレクトリのバージョンが違います" + +#: pg_resetwal.c:565 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "ファイル\"%s\"では\"%s\"となっています、これはこのプログラムのバージョン\"%s\"と互換性がありません" + +#: pg_resetwal.c:598 +#, c-format +msgid "" +"If you are sure the data directory path is correct, execute\n" +" touch %s\n" +"and try again." +msgstr "" +"確実にデータディレクトリのパスが正しければ、\n" +" touch %s\n" +"の後に再実行してください。" + +#: pg_resetwal.c:629 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "pg_controlがありましたが、CRCが不正でした; 注意して進めてください" + +#: pg_resetwal.c:638 +#, c-format +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_controlにあるWALセグメントサイズ(%dバイト)は不正です; 注意して進めてください" + +#: pg_resetwal.c:649 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "pg_controlがありましたが、破損あるいは間違ったバージョンです; 無視します" + +#: pg_resetwal.c:744 +#, c-format +msgid "" +"Guessed pg_control values:\n" +"\n" +msgstr "" +"pg_controlの推測値:\n" +"\n" + +#: pg_resetwal.c:746 +#, c-format +msgid "" +"Current pg_control values:\n" +"\n" +msgstr "" +"現在のpg_controlの値:\n" +"\n" + +#: pg_resetwal.c:748 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_controlバージョン番号: %u\n" + +#: pg_resetwal.c:750 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "カタログバージョン番号: %u\n" + +#: pg_resetwal.c:752 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "データベースシステム識別子: %llu\n" + +#: pg_resetwal.c:754 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "最終チェックポイントの時系列ID: %u\n" + +#: pg_resetwal.c:756 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "最終チェックポイントのfull_page_writes: %s\n" + +#: pg_resetwal.c:757 +msgid "off" +msgstr "オフ" + +#: pg_resetwal.c:757 +msgid "on" +msgstr "オン" + +#: pg_resetwal.c:758 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "最終チェックポイントのNextXID: %u:%u\n" + +#: pg_resetwal.c:761 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "最終チェックポイントのNextOID: %u\n" + +#: pg_resetwal.c:763 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "最終チェックポイントのNextMultiXactId: %u\n" + +#: pg_resetwal.c:765 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "最終チェックポイントのNextMultiOffset: %u\n" + +#: pg_resetwal.c:767 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "最終チェックポイントのoldestXID: %u\n" + +#: pg_resetwal.c:769 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "最終チェックポイントのoldestXIDのDB: %u\n" + +#: pg_resetwal.c:771 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "最終チェックポイントのoldestActiveXID: %u\n" + +#: pg_resetwal.c:773 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "最終チェックポイントのoldestMultiXid: %u\n" + +#: pg_resetwal.c:775 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "最終チェックポイントのoldestMultiのDB: %u\n" + +#: pg_resetwal.c:777 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "最終チェックポイントのoldestCommitTsXid: %u\n" + +#: pg_resetwal.c:779 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "最終チェックポイントのnewestCommitTsXid: %u\n" + +#: pg_resetwal.c:781 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "最大データアラインメント: %u\n" + +#: pg_resetwal.c:784 +#, c-format +msgid "Database block size: %u\n" +msgstr "データベースのブロックサイズ: %u\n" + +#: pg_resetwal.c:786 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "大きなリレーションのセグメント毎のブロック数:%u\n" + +#: pg_resetwal.c:788 +#, c-format +msgid "WAL block size: %u\n" +msgstr "WALのブロックサイズ: %u\n" + +#: pg_resetwal.c:790 pg_resetwal.c:876 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "WALセグメント当たりのバイト数: %u\n" + +#: pg_resetwal.c:792 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "識別子の最大長: %u\n" + +#: pg_resetwal.c:794 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "インデックス内の最大列数: %u\n" + +#: pg_resetwal.c:796 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "TOASTチャンクの最大サイズ: %u\n" + +#: pg_resetwal.c:798 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "ラージオブジェクトチャンクのサイズ: %u\n" + +#: pg_resetwal.c:801 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "日付/時刻型の格納方式: %s\n" + +#: pg_resetwal.c:802 +msgid "64-bit integers" +msgstr "64ビット整数" + +#: pg_resetwal.c:803 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Float8引数の渡し方: %s\n" + +#: pg_resetwal.c:804 +msgid "by reference" +msgstr "参照渡し" + +#: pg_resetwal.c:804 +msgid "by value" +msgstr "値渡し" + +#: pg_resetwal.c:805 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "データベージチェックサムのバージョン: %u\n" + +#: pg_resetwal.c:819 +#, c-format +msgid "" +"\n" +"\n" +"Values to be changed:\n" +"\n" +msgstr "" +"\n" +"\n" +"変更される値:\n" +"\n" + +#: pg_resetwal.c:823 +#, c-format +msgid "First log segment after reset: %s\n" +msgstr "リセット後最初のログセグメント: %s\n" + +#: pg_resetwal.c:827 +#, c-format +msgid "NextMultiXactId: %u\n" +msgstr "NextMultiXactId: %u\n" + +#: pg_resetwal.c:829 +#, c-format +msgid "OldestMultiXid: %u\n" +msgstr "OldestMultiXid: %u\n" + +#: pg_resetwal.c:831 +#, c-format +msgid "OldestMulti's DB: %u\n" +msgstr "OldestMultiのDB: %u\n" + +#: pg_resetwal.c:837 +#, c-format +msgid "NextMultiOffset: %u\n" +msgstr "NextMultiOffset: %u\n" + +#: pg_resetwal.c:843 +#, c-format +msgid "NextOID: %u\n" +msgstr "NextOID: %u\n" + +#: pg_resetwal.c:849 +#, c-format +msgid "NextXID: %u\n" +msgstr "NextXID: %u\n" + +#: pg_resetwal.c:851 +#, c-format +msgid "OldestXID: %u\n" +msgstr "OldestXID: %u\n" + +#: pg_resetwal.c:853 +#, c-format +msgid "OldestXID's DB: %u\n" +msgstr "OldestXIDのDB: %u\n" + +#: pg_resetwal.c:859 +#, c-format +msgid "NextXID epoch: %u\n" +msgstr "NextXID基点: %u\n" + +#: pg_resetwal.c:865 +#, c-format +msgid "oldestCommitTsXid: %u\n" +msgstr "oldestCommitTsXid: %u\n" + +#: pg_resetwal.c:870 +#, c-format +msgid "newestCommitTsXid: %u\n" +msgstr "newestCommitTsXid: %u\n" + +#: pg_resetwal.c:956 pg_resetwal.c:1024 pg_resetwal.c:1071 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: pg_resetwal.c:991 pg_resetwal.c:1044 pg_resetwal.c:1094 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m" + +#: pg_resetwal.c:997 pg_resetwal.c:1050 pg_resetwal.c:1100 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" + +#: pg_resetwal.c:1036 pg_resetwal.c:1086 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "ファイル\"%s\"を削除できませんでした: %m" + +#: pg_resetwal.c:1167 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: pg_resetwal.c:1177 pg_resetwal.c:1190 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "ファイル\"%s\"を書き出せませんでした: %m" + +#: pg_resetwal.c:1197 +#, c-format +msgid "fsync error: %m" +msgstr "fsyncエラー: %m" + +#: pg_resetwal.c:1208 +#, c-format +msgid "" +"%s resets the PostgreSQL write-ahead log.\n" +"\n" +msgstr "" +"%sはPostgreSQLの先行書き込みログをリセットします。\n" +"\n" + +#: pg_resetwal.c:1209 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... DATADIR\n" +"\n" +msgstr "" +"使用方法:\n" +" %s [OPTION]... DATADIR\n" +"\n" + +#: pg_resetwal.c:1210 +#, c-format +msgid "Options:\n" +msgstr "オプション:\n" + +#: pg_resetwal.c:1211 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" コミットタイムスタンプを持つ最古と最新の\n" +" トランザクション(0は変更しないことを意味する)\n" + +#: pg_resetwal.c:1214 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR データディレクトリ\n" + +#: pg_resetwal.c:1215 +#, c-format +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH 次のトランザクションIDの基点を設定\n" + +#: pg_resetwal.c:1216 +#, c-format +msgid " -f, --force force update to be done\n" +msgstr " -f, --force 強制的に更新を実施\n" + +#: pg_resetwal.c:1217 +#, c-format +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr " -l, --next-wal-file=WALFILE 新しいWALの最小開始ポイントを設定\n" + +#: pg_resetwal.c:1218 +#, c-format +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr " -m, --multixact-ids=MXID,MXID 次および最古のマルチトランザクションIDを設定\n" + +#: pg_resetwal.c:1219 +#, c-format +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr " -n, --dry-run 更新をせず、単に何が行なわれるかを表示\n" + +#: pg_resetwal.c:1220 +#, c-format +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID 次のOIDを設定\n" + +#: pg_resetwal.c:1221 +#, c-format +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr " -O, --multixact-offset=OFFSET 次のマルチトランザクションオフセットを設定\n" + +#: pg_resetwal.c:1222 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_resetwal.c:1223 +#, c-format +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID 次のトランザクションIDを設定\n" + +#: pg_resetwal.c:1224 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE WALセグメントのサイズ、単位はメガバイト\n" + +#: pg_resetwal.c:1225 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_resetwal.c:1226 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: pg_resetwal.c:1227 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#~ msgid "%s: cannot be executed by \"root\"\n" +#~ msgstr "%s: \"root\"では実行できません\n" + +#~ msgid "%s: could not change directory to \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"に移動できませんでした: %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: 読み取り用のファイル\"%s\"をオープンできませんでした: %s\n" + +#~ msgid "Transaction log reset\n" +#~ msgstr "トランザクションログをリセットします。\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"を読み込めませんでした: %s\n" + +#~ msgid "floating-point numbers" +#~ msgstr "浮動小数点数" + +#~ msgid "%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n" +#~ msgstr "%s: 内部エラー -- sizeof(ControlFileData)が大きすぎます ... PG_CONTROL_SIZEを修正してください\n" + +#~ msgid "%s: could not create pg_control file: %s\n" +#~ msgstr "%s: pg_controlファイルを作成できませんでした: %s\n" + +#~ msgid "%s: could not write pg_control file: %s\n" +#~ msgstr "%s: pg_controlファイルを書き込めませんでした: %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"をオープンできませんでした: %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"を読み取ることができませんでした。: %s\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ \"%s\" をクローズできませんでした: %s\n" + +#~ msgid "%s: could not delete file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"を削除できませんでした: %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"をオープンできませんでした: %s\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s: ファイル\"%s\"を書き込めませんでした: %s\n" + +#~ msgid " -c XID,XID set oldest and newest transactions bearing commit timestamp\n" +#~ msgstr " -c XID,XID コミットタイムスタンプを作成する最も古いトランザクションと最も新しいトランザクションを設定します\n" + +#~ msgid " (zero in either value means no change)\n" +#~ msgstr " (いずれかの値での0は変更がないことを意味します)\n" + +#~ msgid " [-D] DATADIR data directory\n" +#~ msgstr " [-D] DATADIR データベースディレクトリ\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version バージョン情報を出力、終了します\n" + +#~ msgid " -x XID set next transaction ID\n" +#~ msgstr " -x XID 次のトランザクションIDを設定します\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help このヘルプを表示し、終了します\n" + +#~ msgid "First log file ID after reset: %u\n" +#~ msgstr "リセット後、現在のログファイルID: %u\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help ヘルプを表示し、終了します\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version バージョン情報を表示し、終了します\n" + +#~ msgid "%s: could not read from directory \"%s\": %s\n" +#~ msgstr "%s: ディレクトリ\"%s\"から読み込めませんでした: %s\n" + +#~ msgid "%s: invalid argument for option -l\n" +#~ msgstr "%s: オプション-lの引数が無効です\n" + +#~ msgid "%s: invalid argument for option -O\n" +#~ msgstr "%s: オプション-Oの引数が無効です\n" + +#~ msgid "%s: invalid argument for option -m\n" +#~ msgstr "%s: オプション-mの引数が無効です\n" + +#~ msgid "%s: invalid argument for option -o\n" +#~ msgstr "%s: オプション-oの引数が無効です\n" + +#~ msgid "%s: invalid argument for option -x\n" +#~ msgstr "%s: オプション-xの引数が無効です\n" + +#~ msgid "Float4 argument passing: %s\n" +#~ msgstr "Float4引数の渡し方: %s\n" diff --git a/src/bin/pg_resetwal/po/ko.po b/src/bin/pg_resetwal/po/ko.po new file mode 100644 index 000000000000..03e30bc6d88c --- /dev/null +++ b/src/bin/pg_resetwal/po/ko.po @@ -0,0 +1,662 @@ +# Korean message translation file for PostgreSQL pg_resetxlog +# Ioseph Kim , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_resetwal (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:45+0000\n" +"PO-Revision-Date: 2020-10-06 13:44+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean Team \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "\"%s\" 라이브러리를 로드할 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "이 운영체제에서 restricted token을 만들 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "프로세스 토큰을 열 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SID를 할당할 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "상속된 토큰을 만들 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\" 명령용 프로세스를 시작할 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "상속된 토큰으로 재실행할 수 없음: 오류 코드 %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "하위 프로세스의 종료 코드를 구할 수 없음: 오류 코드 %lu" + +#. translator: the second %s is a command line argument (-e, etc) +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 +#, c-format +msgid "invalid argument for option %s" +msgstr "%s 옵션의 잘못된 인자" + +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "자세한 사용법은 \"%s --help\"\n" + +#: pg_resetwal.c:166 +#, c-format +msgid "transaction ID epoch (-e) must not be -1" +msgstr "트랜잭션 ID epoch (-e) 값은 -1이 아니여야함" + +#: pg_resetwal.c:181 +#, c-format +msgid "transaction ID (-x) must not be 0" +msgstr "트랜잭션 ID (-x) 값은 0이 아니여야함" + +#: pg_resetwal.c:205 pg_resetwal.c:212 +#, c-format +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "-c 옵션으로 지정한 트랜잭션 ID는 0이거나 2이상이어야 함" + +#: pg_resetwal.c:227 +#, c-format +msgid "OID (-o) must not be 0" +msgstr "OID (-o) 값은 0이 아니여야함" + +#: pg_resetwal.c:250 +#, c-format +msgid "multitransaction ID (-m) must not be 0" +msgstr "멀티트랜잭션 ID (-m) 값은 0이 아니여야함" + +#: pg_resetwal.c:260 +#, c-format +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "제일 오래된 멀티트랜잭션 ID (-m) 값은 0이 아니여야함" + +#: pg_resetwal.c:275 +#, c-format +msgid "multitransaction offset (-O) must not be -1" +msgstr "멀티트랜잭션 옵셋 (-O) 값은 -1이 아니여야함" + +#: pg_resetwal.c:299 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "--wal-segsize 값은 숫자여야 합니다" + +#: pg_resetwal.c:304 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "--wal-segsize 값은 1부터 1024사이 2^n 값이어야 합니다" + +#: pg_resetwal.c:321 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "너무 많은 명령행 인수를 지정했습니다. (처음 \"%s\")" + +#: pg_resetwal.c:330 +#, c-format +msgid "no data directory specified" +msgstr "데이터 디렉터리를 지정하지 않았음" + +#: pg_resetwal.c:344 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "\"root\" 계정으로는 실행 할 수 없음" + +#: pg_resetwal.c:345 +#, c-format +msgid "You must run %s as the PostgreSQL superuser." +msgstr "PostgreSQL superuser로 %s 프로그램을 실행하십시오." + +#: pg_resetwal.c:356 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 읽기 권한 없음: %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" 이름의 디렉터리로 이동할 수 없습니다: %m" + +#: pg_resetwal.c:381 pg_resetwal.c:544 pg_resetwal.c:595 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" 파일 일기 모드로 열기 실패: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "\"%s\" 잠금 파일이 있음" + +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "" +"서버가 가동중인가요? 그렇지 않다면, 이 파일을 지우고 다시 시도하십시오." + +#: pg_resetwal.c:492 +#, c-format +msgid "" +"\n" +"If these values seem acceptable, use -f to force reset.\n" +msgstr "" +"\n" +"이 설정값들이 타당하다고 판단되면, 강제로 갱신하려면, -f 옵션을 쓰세요.\n" + +#: pg_resetwal.c:504 +#, c-format +msgid "" +"The database server was not shut down cleanly.\n" +"Resetting the write-ahead log might cause data to be lost.\n" +"If you want to proceed anyway, use -f to force reset.\n" +msgstr "" +"이 데이터베이스 서버는 정상적으로 중지되지 못했습니다.\n" +"트랜잭션 로그를 다시 설정하는 것은 자료 손실을 야기할 수 있습니다.\n" +"그럼에도 불구하고 진행하려면, -f 옵션을 사용해서 강제 설정을 하십시오.\n" + +#: pg_resetwal.c:518 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "트랜잭션 로그 재설정\n" + +#: pg_resetwal.c:553 +#, c-format +msgid "unexpected empty file \"%s\"" +msgstr "\"%s\" 파일은 예상치 않게 비었음" + +#: pg_resetwal.c:555 pg_resetwal.c:611 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "\"%s\" 파일을 읽을 수 없음: %m" + +#: pg_resetwal.c:564 +#, c-format +msgid "data directory is of wrong version" +msgstr "잘못된 버전의 데이터 디렉터리입니다." + +#: pg_resetwal.c:565 +#, c-format +msgid "" +"File \"%s\" contains \"%s\", which is not compatible with this program's " +"version \"%s\"." +msgstr "\"%s\" 파일 버전은 \"%s\", 이 프로그램 버전은 \"%s\"." + +#: pg_resetwal.c:598 +#, c-format +msgid "" +"If you are sure the data directory path is correct, execute\n" +" touch %s\n" +"and try again." +msgstr "" +"지정한 데이터 디렉터리가 맞다면, 다음 명령을 실행하고, 다시 시도해\n" +"보십시오.\n" +" touch %s" + +#: pg_resetwal.c:629 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "pg_control 파일이 있지만, CRC값이 잘못되었습니다; 경고와 함께 진행함" + +#: pg_resetwal.c:638 +#, c-format +msgid "" +"pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "" +"pg_control specifies invalid WAL segment size (%d bytes); proceed with " +"caution" +msgstr[0] "" +"pg_control 파일에 잘못된 WAL 조각 파일 크기(%d 바이트)가 지정됨; 경고와 함께 " +"진행함" + +#: pg_resetwal.c:649 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "pg_control 파일이 있지만, 손상되었거나 버전을 알 수 없음; 무시함" + +#: pg_resetwal.c:744 +#, c-format +msgid "" +"Guessed pg_control values:\n" +"\n" +msgstr "" +"추측된 pg_control 설정값들:\n" +"\n" + +#: pg_resetwal.c:746 +#, c-format +msgid "" +"Current pg_control values:\n" +"\n" +msgstr "" +"현재 pg_control 설정값들:\n" +"\n" + +#: pg_resetwal.c:748 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_control 버전 번호: %u\n" + +#: pg_resetwal.c:750 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "카탈로그 버전 번호: %u\n" + +#: pg_resetwal.c:752 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "데이터베이스 시스템 식별자: %llu\n" + +#: pg_resetwal.c:754 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "마지막 체크포인트 TimeLineID: %u\n" + +#: pg_resetwal.c:756 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "마지막 체크포인트 full_page_writes: %s\n" + +#: pg_resetwal.c:757 +msgid "off" +msgstr "off" + +#: pg_resetwal.c:757 +msgid "on" +msgstr "on" + +#: pg_resetwal.c:758 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "마지막 체크포인트 NextXID: %u:%u\n" + +#: pg_resetwal.c:761 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "마지막 체크포인트 NextOID: %u\n" + +#: pg_resetwal.c:763 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "마지막 체크포인트 NextMultiXactId: %u\n" + +#: pg_resetwal.c:765 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "마지막 체크포인트 NextMultiOffset: %u\n" + +#: pg_resetwal.c:767 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "마지막 체크포인트 제일 오래된 XID: %u\n" + +#: pg_resetwal.c:769 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "마지막 체크포인트 제일 오래된 XID의 DB:%u\n" + +#: pg_resetwal.c:771 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "마지막 체크포인트 제일 오래된 ActiveXID:%u\n" + +#: pg_resetwal.c:773 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "마지막 체크포인트 제일 오래된 MultiXid:%u\n" + +#: pg_resetwal.c:775 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "마지막 체크포인트 제일 오래된 MultiXid의 DB:%u\n" + +#: pg_resetwal.c:777 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "마지막 체크포인트 제일 오래된 CommitTsXid:%u\n" + +#: pg_resetwal.c:779 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "마지막 체크포인트 최신 CommitTsXid: %u\n" + +#: pg_resetwal.c:781 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "최대 자료 정렬: %u\n" + +#: pg_resetwal.c:784 +#, c-format +msgid "Database block size: %u\n" +msgstr "데이터베이스 블록 크기: %u\n" + +#: pg_resetwal.c:786 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "대형 릴레이션의 세그먼트당 블럭 갯수: %u\n" + +#: pg_resetwal.c:788 +#, c-format +msgid "WAL block size: %u\n" +msgstr "WAL 블록 크기: %u\n" + +#: pg_resetwal.c:790 pg_resetwal.c:876 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "WAL 세그먼트의 크기(byte): %u\n" + +#: pg_resetwal.c:792 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "식별자 최대 길이: %u\n" + +#: pg_resetwal.c:794 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "인덱스에서 사용하는 최대 열 수: %u\n" + +#: pg_resetwal.c:796 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "TOAST 청크의 최대 크기: %u\n" + +#: pg_resetwal.c:798 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "대형객체 청크의 최대 크기: %u\n" + +#: pg_resetwal.c:801 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "날짜/시간형 자료의 저장방식: %s\n" + +#: pg_resetwal.c:802 +msgid "64-bit integers" +msgstr "64-비트 정수" + +#: pg_resetwal.c:803 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Float8 인수 전달: %s\n" + +#: pg_resetwal.c:804 +msgid "by reference" +msgstr "참조별" + +#: pg_resetwal.c:804 +msgid "by value" +msgstr "값별" + +#: pg_resetwal.c:805 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "데이터 페이지 체크섬 버전: %u\n" + +#: pg_resetwal.c:819 +#, c-format +msgid "" +"\n" +"\n" +"Values to be changed:\n" +"\n" +msgstr "" +"\n" +"\n" +"변경될 값:\n" +"\n" + +#: pg_resetwal.c:823 +#, c-format +msgid "First log segment after reset: %s\n" +msgstr "리셋 뒤 첫 로그 세그먼트: %s\n" + +#: pg_resetwal.c:827 +#, c-format +msgid "NextMultiXactId: %u\n" +msgstr "NextMultiXactId: %u\n" + +#: pg_resetwal.c:829 +#, c-format +msgid "OldestMultiXid: %u\n" +msgstr "OldestMultiXid: %u\n" + +#: pg_resetwal.c:831 +#, c-format +msgid "OldestMulti's DB: %u\n" +msgstr "OldestMultiXid의 DB: %u\n" + +#: pg_resetwal.c:837 +#, c-format +msgid "NextMultiOffset: %u\n" +msgstr "NextMultiOffset: %u\n" + +#: pg_resetwal.c:843 +#, c-format +msgid "NextOID: %u\n" +msgstr "NextOID: %u\n" + +#: pg_resetwal.c:849 +#, c-format +msgid "NextXID: %u\n" +msgstr "NextXID: %u\n" + +#: pg_resetwal.c:851 +#, c-format +msgid "OldestXID: %u\n" +msgstr "OldestXID: %u\n" + +#: pg_resetwal.c:853 +#, c-format +msgid "OldestXID's DB: %u\n" +msgstr "OldestXID의 DB: %u\n" + +#: pg_resetwal.c:859 +#, c-format +msgid "NextXID epoch: %u\n" +msgstr "NextXID epoch: %u\n" + +#: pg_resetwal.c:865 +#, c-format +msgid "oldestCommitTsXid: %u\n" +msgstr "제일 오래된 CommitTsXid: %u\n" + +#: pg_resetwal.c:870 +#, c-format +msgid "newestCommitTsXid: %u\n" +msgstr "최근 CommitTsXid: %u\n" + +#: pg_resetwal.c:956 pg_resetwal.c:1024 pg_resetwal.c:1071 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 열 수 없음: %m" + +#: pg_resetwal.c:991 pg_resetwal.c:1044 pg_resetwal.c:1094 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 읽을 수 없음: %m" + +#: pg_resetwal.c:997 pg_resetwal.c:1050 pg_resetwal.c:1100 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 닫을 수 없음: %m" + +#: pg_resetwal.c:1036 pg_resetwal.c:1086 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "\"%s\" 파일을 지울 수 없음: %m" + +#: pg_resetwal.c:1167 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" 파일을 열 수 없음: %m" + +#: pg_resetwal.c:1177 pg_resetwal.c:1190 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" 파일 쓰기 실패: %m" + +#: pg_resetwal.c:1197 +#, c-format +msgid "fsync error: %m" +msgstr "fsync 오류: %m" + +#: pg_resetwal.c:1208 +#, c-format +msgid "" +"%s resets the PostgreSQL write-ahead log.\n" +"\n" +msgstr "" +"%s 프로그램은 PostgreSQL 트랜잭션 로그를 다시 설정합니다.\n" +"\n" + +#: pg_resetwal.c:1209 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... DATADIR\n" +"\n" +msgstr "" +"사용법:\n" +" %s [옵션]... DATADIR\n" +"\n" + +#: pg_resetwal.c:1210 +#, c-format +msgid "Options:\n" +msgstr "옵션들:\n" + +#: pg_resetwal.c:1211 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" 커밋 타임스탬프를 사용할 최소,최대 트랜잭" +"션\n" +" ID 값 (0이면 바꾸지 않음)\n" + +#: pg_resetwal.c:1214 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR 데이터 디렉터리\n" + +#: pg_resetwal.c:1215 +#, c-format +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH 다음 트랙잭션 ID epoch 지정\n" + +#: pg_resetwal.c:1216 +#, c-format +msgid " -f, --force force update to be done\n" +msgstr " -f, --force 강제로 갱신함\n" + +#: pg_resetwal.c:1217 +#, c-format +msgid "" +" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr "" +" -l, --next-wal-file=WALFILE 새 트랜잭션 로그를 위한 WAL 최소 시작 위치" +"를 강제로 지정\n" + +#: pg_resetwal.c:1218 +#, c-format +msgid "" +" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr "" +" -m, --multixact-ids=MXID,MXID 다음 제일 오래된 멀티트랜잭션 ID 지정\n" + +#: pg_resetwal.c:1219 +#, c-format +msgid "" +" -n, --dry-run no update, just show what would be done\n" +msgstr "" +" -n, --dry-run 갱신하지 않음, 컨트롤 값들을 보여주기만 함" +"(테스트용)\n" + +#: pg_resetwal.c:1220 +#, c-format +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID 다음 OID 지정\n" + +#: pg_resetwal.c:1221 +#, c-format +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr " -O, --multixact-offset=OFFSET 다음 멀티트랜잭션 옵셋 지정\n" + +#: pg_resetwal.c:1222 +#, c-format +msgid "" +" -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: pg_resetwal.c:1223 +#, c-format +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID 다음 트랜잭션 ID 지정\n" + +#: pg_resetwal.c:1224 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE WAL 조각 파일 크기, MB 단위\n" + +#: pg_resetwal.c:1225 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_resetwal.c:1226 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"문제점 보고 주소: <%s>\n" + +#: pg_resetwal.c:1227 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" diff --git a/src/bin/pg_resetwal/po/ru.po b/src/bin/pg_resetwal/po/ru.po new file mode 100644 index 000000000000..d0f196d80756 --- /dev/null +++ b/src/bin/pg_resetwal/po/ru.po @@ -0,0 +1,761 @@ +# Russian message translation file for pg_resetxlog +# Copyright (C) 2002-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Serguei A. Mokhov , 2002-2005. +# Oleg Bartunov , 2004. +# Sergey Burladyan , 2009. +# Dmitriy Olshevskiy , 2014. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_resetxlog (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2020-09-03 13:37+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "не удалось загрузить библиотеку \"%s\" (код ошибки: %lu)" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "в этой ОС нельзя создавать ограниченные маркеры (код ошибки: %lu)" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "не удалось открыть маркер процесса (код ошибки: %lu)" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "не удалось подготовить структуры SID (код ошибки: %lu)" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "не удалось создать ограниченный маркер (код ошибки: %lu)" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "не удалось запустить процесс для команды \"%s\" (код ошибки: %lu)" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "не удалось перезапуститься с ограниченным маркером (код ошибки: %lu)" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "не удалось получить код выхода от подпроцесса (код ошибки: %lu)" + +#. translator: the second %s is a command line argument (-e, etc) +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 +#, c-format +msgid "invalid argument for option %s" +msgstr "недопустимый аргумент параметра %s" + +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_resetwal.c:166 +#, c-format +msgid "transaction ID epoch (-e) must not be -1" +msgstr "эпоха ID транзакции (-e) не должна быть равна -1" + +#: pg_resetwal.c:181 +#, c-format +msgid "transaction ID (-x) must not be 0" +msgstr "ID транзакции (-x) не должен быть равен 0" + +#: pg_resetwal.c:205 pg_resetwal.c:212 +#, c-format +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "ID транзакции (-c) должен быть равен 0, либо больше или равен 2" + +#: pg_resetwal.c:227 +#, c-format +msgid "OID (-o) must not be 0" +msgstr "OID (-o) не должен быть равен 0" + +#: pg_resetwal.c:250 +#, c-format +msgid "multitransaction ID (-m) must not be 0" +msgstr "ID мультитранзакции (-m) не должен быть равен 0" + +#: pg_resetwal.c:260 +#, c-format +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "ID старейшей мультитранзакции (-m) не должен быть равен 0" + +#: pg_resetwal.c:275 +#, c-format +msgid "multitransaction offset (-O) must not be -1" +msgstr "смещение мультитранзакции (-O) не должно быть равно -1" + +#: pg_resetwal.c:299 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "аргументом --wal-segsize должно быть число" + +#: pg_resetwal.c:304 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "аргументом --wal-segsize должна быть степень 2 от 1 до 1024" + +#: pg_resetwal.c:321 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: pg_resetwal.c:330 +#, c-format +msgid "no data directory specified" +msgstr "каталог данных не указан" + +#: pg_resetwal.c:344 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "программу не должен запускать root" + +#: pg_resetwal.c:345 +#, c-format +msgid "You must run %s as the PostgreSQL superuser." +msgstr "Запускать %s нужно от имени суперпользователя PostgreSQL." + +#: pg_resetwal.c:356 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "не удалось считать права на каталог \"%s\": %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не удалось перейти в каталог \"%s\": %m" + +#: pg_resetwal.c:381 pg_resetwal.c:544 pg_resetwal.c:595 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не удалось открыть файл \"%s\" для чтения: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "файл блокировки \"%s\" существует" + +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "" +"Возможно, сервер запущен? Если нет, удалите этот файл и попробуйте снова." + +#: pg_resetwal.c:492 +#, c-format +msgid "" +"\n" +"If these values seem acceptable, use -f to force reset.\n" +msgstr "" +"\n" +"Если эти значения приемлемы, выполните сброс принудительно, добавив ключ -" +"f.\n" + +#: pg_resetwal.c:504 +#, c-format +msgid "" +"The database server was not shut down cleanly.\n" +"Resetting the write-ahead log might cause data to be lost.\n" +"If you want to proceed anyway, use -f to force reset.\n" +msgstr "" +"Сервер баз данных был остановлен некорректно.\n" +"Сброс журнала предзаписи может привести к потере данных.\n" +"Если вы хотите сбросить его, несмотря на это, добавьте ключ -f.\n" + +#: pg_resetwal.c:518 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "Журнал предзаписи сброшен\n" + +#: pg_resetwal.c:553 +#, c-format +msgid "unexpected empty file \"%s\"" +msgstr "файл \"%s\" оказался пустым" + +#: pg_resetwal.c:555 pg_resetwal.c:611 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: pg_resetwal.c:564 +#, c-format +msgid "data directory is of wrong version" +msgstr "каталог данных имеет неверную версию" + +#: pg_resetwal.c:565 +#, c-format +msgid "" +"File \"%s\" contains \"%s\", which is not compatible with this program's " +"version \"%s\"." +msgstr "" +"Файл \"%s\" содержит строку \"%s\", а ожидается версия программы \"%s\"." + +#: pg_resetwal.c:598 +#, c-format +msgid "" +"If you are sure the data directory path is correct, execute\n" +" touch %s\n" +"and try again." +msgstr "" +"Если вы уверены, что путь к каталогу данных правильный, выполните\n" +" touch %s\n" +"и повторите попытку." + +#: pg_resetwal.c:629 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "" +"pg_control существует, но его контрольная сумма неверна; продолжайте с " +"осторожностью" + +#: pg_resetwal.c:638 +#, c-format +msgid "" +"pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "" +"pg_control specifies invalid WAL segment size (%d bytes); proceed with " +"caution" +msgstr[0] "" +"в pg_control указан некорректный размер сегмента WAL (%d Б); продолжайте с " +"осторожностью" +msgstr[1] "" +"в pg_control указан некорректный размер сегмента WAL (%d Б); продолжайте с " +"осторожностью" +msgstr[2] "" +"в pg_control указан некорректный размер сегмента WAL (%d Б); продолжайте с " +"осторожностью" + +#: pg_resetwal.c:649 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "" +"pg_control испорчен или имеет неизвестную либо недопустимую версию; " +"игнорируется..." + +#: pg_resetwal.c:744 +#, c-format +msgid "" +"Guessed pg_control values:\n" +"\n" +msgstr "" +"Предполагаемые значения pg_control:\n" +"\n" + +#: pg_resetwal.c:746 +#, c-format +msgid "" +"Current pg_control values:\n" +"\n" +msgstr "" +"Текущие значения pg_control:\n" +"\n" + +#: pg_resetwal.c:748 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "Номер версии pg_control: %u\n" + +#: pg_resetwal.c:750 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Номер версии каталога: %u\n" + +#: pg_resetwal.c:752 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "Идентификатор системы баз данных: %llu\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:754 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "Линия времени последней конт. точки: %u\n" + +# skip-rule: no-space-after-period +#: pg_resetwal.c:756 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Режим full_page_writes последней к.т: %s\n" + +#: pg_resetwal.c:757 +msgid "off" +msgstr "выкл." + +#: pg_resetwal.c:757 +msgid "on" +msgstr "вкл." + +# skip-rule: capital-letter-first +#: pg_resetwal.c:758 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID последней конт. точки: %u:%u\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:761 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "NextOID последней конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:763 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "NextMultiXactId послед. конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:765 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "NextMultiOffset послед. конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:767 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "oldestXID последней конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:769 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "БД с oldestXID последней конт. точки: %u\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:771 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "oldestActiveXID последней к. т.: %u\n" + +# skip-rule: capital-letter-first +#: pg_resetwal.c:773 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "oldestMultiXid последней конт. точки: %u\n" + +# skip-rule: capital-letter-first, double-space +#: pg_resetwal.c:775 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "БД с oldestMulti последней к. т.: %u\n" + +# skip-rule: capital-letter-first, double-space +#: pg_resetwal.c:777 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "oldestCommitTsXid последней к. т.: %u\n" + +# skip-rule: capital-letter-first, double-space +#: pg_resetwal.c:779 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "newestCommitTsXid последней к. т.: %u\n" + +#: pg_resetwal.c:781 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Макс. предел выравнивания данных: %u\n" + +#: pg_resetwal.c:784 +#, c-format +msgid "Database block size: %u\n" +msgstr "Размер блока БД: %u\n" + +# skip-rule: double-space +#: pg_resetwal.c:786 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Блоков в макс. сегменте отношений: %u\n" + +#: pg_resetwal.c:788 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Размер блока WAL: %u\n" + +#: pg_resetwal.c:790 pg_resetwal.c:876 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Байт в сегменте WAL: %u\n" + +#: pg_resetwal.c:792 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Максимальная длина идентификаторов: %u\n" + +#: pg_resetwal.c:794 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Максимальное число столбцов в индексе: %u\n" + +#: pg_resetwal.c:796 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Максимальный размер порции TOAST: %u\n" + +#: pg_resetwal.c:798 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Размер порции большого объекта: %u\n" + +#: pg_resetwal.c:801 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Формат хранения даты/времени: %s\n" + +#: pg_resetwal.c:802 +msgid "64-bit integers" +msgstr "64-битные целые" + +#: pg_resetwal.c:803 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Передача аргумента Float8: %s\n" + +#: pg_resetwal.c:804 +msgid "by reference" +msgstr "по ссылке" + +#: pg_resetwal.c:804 +msgid "by value" +msgstr "по значению" + +#: pg_resetwal.c:805 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Версия контрольных сумм страниц: %u\n" + +#: pg_resetwal.c:819 +#, c-format +msgid "" +"\n" +"\n" +"Values to be changed:\n" +"\n" +msgstr "" +"\n" +"\n" +"Значения, которые будут изменены:\n" +"\n" + +#: pg_resetwal.c:823 +#, c-format +msgid "First log segment after reset: %s\n" +msgstr "Первый сегмент журнала после сброса: %s\n" + +#: pg_resetwal.c:827 +#, c-format +msgid "NextMultiXactId: %u\n" +msgstr "NextMultiXactId: %u\n" + +#: pg_resetwal.c:829 +#, c-format +msgid "OldestMultiXid: %u\n" +msgstr "OldestMultiXid: %u\n" + +#: pg_resetwal.c:831 +#, c-format +msgid "OldestMulti's DB: %u\n" +msgstr "БД с oldestMultiXid: %u\n" + +#: pg_resetwal.c:837 +#, c-format +msgid "NextMultiOffset: %u\n" +msgstr "NextMultiOffset: %u\n" + +#: pg_resetwal.c:843 +#, c-format +msgid "NextOID: %u\n" +msgstr "NextOID: %u\n" + +#: pg_resetwal.c:849 +#, c-format +msgid "NextXID: %u\n" +msgstr "NextXID: %u\n" + +#: pg_resetwal.c:851 +#, c-format +msgid "OldestXID: %u\n" +msgstr "OldestXID: %u\n" + +#: pg_resetwal.c:853 +#, c-format +msgid "OldestXID's DB: %u\n" +msgstr "БД с oldestXID: %u\n" + +#: pg_resetwal.c:859 +#, c-format +msgid "NextXID epoch: %u\n" +msgstr "Эпоха NextXID: %u\n" + +#: pg_resetwal.c:865 +#, c-format +msgid "oldestCommitTsXid: %u\n" +msgstr "oldestCommitTsXid: %u\n" + +#: pg_resetwal.c:870 +#, c-format +msgid "newestCommitTsXid: %u\n" +msgstr "newestCommitTsXid: %u\n" + +#: pg_resetwal.c:956 pg_resetwal.c:1024 pg_resetwal.c:1071 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалось открыть каталог \"%s\": %m" + +#: pg_resetwal.c:991 pg_resetwal.c:1044 pg_resetwal.c:1094 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не удалось прочитать каталог \"%s\": %m" + +#: pg_resetwal.c:997 pg_resetwal.c:1050 pg_resetwal.c:1100 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не удалось закрыть каталог \"%s\": %m" + +#: pg_resetwal.c:1036 pg_resetwal.c:1086 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "ошибка при удалении файла \"%s\": %m" + +#: pg_resetwal.c:1167 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: pg_resetwal.c:1177 pg_resetwal.c:1190 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не удалось записать файл \"%s\": %m" + +#: pg_resetwal.c:1197 +#, c-format +msgid "fsync error: %m" +msgstr "ошибка синхронизации с ФС: %m" + +#: pg_resetwal.c:1208 +#, c-format +msgid "" +"%s resets the PostgreSQL write-ahead log.\n" +"\n" +msgstr "" +"%s сбрасывает журнал предзаписи PostgreSQL.\n" +"\n" + +#: pg_resetwal.c:1209 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... DATADIR\n" +"\n" +msgstr "" +"Использование:\n" +" %s [ПАРАМЕТР]... КАТ_ДАННЫХ\n" +"\n" + +#: pg_resetwal.c:1210 +#, c-format +msgid "Options:\n" +msgstr "Параметры:\n" + +#: pg_resetwal.c:1211 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" задать старейшую и новейшую транзакции,\n" +" несущие метки времени (0 — не менять)\n" + +#: pg_resetwal.c:1214 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]КАТ_ДАННЫХ каталог данных\n" + +#: pg_resetwal.c:1215 +#, c-format +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr "" +" -e, --epoch=XIDEPOCH задать эпоху для ID следующей транзакции\n" + +#: pg_resetwal.c:1216 +#, c-format +msgid " -f, --force force update to be done\n" +msgstr " -f, --force принудительное выполнение операции\n" + +#: pg_resetwal.c:1217 +#, c-format +msgid "" +" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr "" +" -l, --next-wal-file=ФАЙЛ_WAL задать минимальное начальное положение\n" +" для нового WAL\n" + +#: pg_resetwal.c:1218 +#, c-format +msgid "" +" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr "" +" -m, --multixact-ids=MXID,MXID задать ID следующей и старейшей " +"мультитранзакции\n" + +#: pg_resetwal.c:1219 +#, c-format +msgid "" +" -n, --dry-run no update, just show what would be done\n" +msgstr "" +" -n, --dry-run показать, какие действия будут выполнены,\n" +" но не выполнять их\n" + +#: pg_resetwal.c:1220 +#, c-format +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID задать следующий OID\n" + +#: pg_resetwal.c:1221 +#, c-format +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr "" +" -O, --multixact-offset=СМЕЩЕНИЕ задать смещение следующей " +"мультитранзакции\n" + +#: pg_resetwal.c:1222 +#, c-format +msgid "" +" -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_resetwal.c:1223 +#, c-format +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID задать ID следующей транзакции\n" + +#: pg_resetwal.c:1224 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=РАЗМЕР размер сегментов WAL (в мегабайтах)\n" + +#: pg_resetwal.c:1225 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_resetwal.c:1226 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_resetwal.c:1227 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#~ msgid "Float4 argument passing: %s\n" +#~ msgstr "Передача аргумента Float4: %s\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid "%s: could not create pg_control file: %s\n" +#~ msgstr "%s: не удалось создать файл pg_control: %s\n" + +#~ msgid "%s: could not write pg_control file: %s\n" +#~ msgstr "%s: не удалось записать файл pg_control: %s\n" + +#~ msgid "" +#~ " -c XID,XID set oldest and newest transactions bearing commit " +#~ "timestamp\n" +#~ msgstr "" +#~ " -c XID,XID задать старейшую и новейшую транзакции, несущие метку " +#~ "времени фиксации\n" + +#~ msgid " (zero in either value means no change)\n" +#~ msgstr " (0 в любом из аргументов игнорируется)\n" + +#~ msgid "" +#~ "%s: internal error -- sizeof(ControlFileData) is too large ... fix " +#~ "PG_CONTROL_SIZE\n" +#~ msgstr "" +#~ "%s: внутренняя ошибка -- размер ControlFileData слишком велик -- " +#~ "исправьте PG_CONTROL_SIZE\n" + +#~ msgid "floating-point numbers" +#~ msgstr "числа с плавающей точкой" + +#~ msgid "%s: invalid argument for option -x\n" +#~ msgstr "%s: недопустимый аргумент параметра -x\n" + +#~ msgid "%s: invalid argument for option -o\n" +#~ msgstr "%s: недопустимый аргумент параметра -o\n" + +#~ msgid "%s: invalid argument for option -m\n" +#~ msgstr "%s: недопустимый аргумент параметра -m\n" + +#~ msgid "%s: invalid argument for option -O\n" +#~ msgstr "%s: недопустимый аргумент параметра -O\n" + +#~ msgid "%s: invalid argument for option -l\n" +#~ msgstr "%s: недопустимый аргумент параметра -l\n" + +#~ msgid " -m XID,OLDEST set next multitransaction ID and oldest value\n" +#~ msgstr "" +#~ " -m XID,СТАРЕЙШАЯ задать ID следующей мультитранзакции и ID старейшей\n" + +#~ msgid "disabled" +#~ msgstr "отключен" + +#~ msgid "enabled" +#~ msgstr "включен" + +#~ msgid "First log file ID after reset: %u\n" +#~ msgstr "ID первого журнала после сброса: %u\n" diff --git a/src/bin/pg_resetwal/po/uk.po b/src/bin/pg_resetwal/po/uk.po new file mode 100644 index 000000000000..b6c024e7aa02 --- /dev/null +++ b/src/bin/pg_resetwal/po/uk.po @@ -0,0 +1,618 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:16+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: \n" +"Language-Team: Ukrainian\n" +"Language: uk_UA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_resetwal.pot\n" +"X-Crowdin-File-ID: 502\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "не вдалося завантажити бібліотеку \"%s\": код помилки %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "не вдалося створити обмежені токени на цій платформі: код помилки %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "не вдалося відкрити токен процесу: код помилки %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "не вдалося виділити SID: код помилки %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "не вдалося створити обмежений токен: код помилки %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "не вдалося запустити процес для команди \"%s\": код помилки %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "не вдалося перезапустити з обмеженим токеном: код помилки %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "не вдалося отримати код завершення підпроцесу: код помилки %lu" + +#. translator: the second %s is a command line argument (-e, etc) +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 +#, c-format +msgid "invalid argument for option %s" +msgstr "неприпустимий аргумент для параметру %s" + +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: pg_resetwal.c:166 +#, c-format +msgid "transaction ID epoch (-e) must not be -1" +msgstr "епоха ID транзакції (-e) не повинна бути -1" + +#: pg_resetwal.c:181 +#, c-format +msgid "transaction ID (-x) must not be 0" +msgstr "ID транзакції (-x) не повинна бути 0" + +#: pg_resetwal.c:205 pg_resetwal.c:212 +#, c-format +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "ID транзакції (-c) повинен дорівнювати 0, бути більшим за або дорівнювати 2" + +#: pg_resetwal.c:227 +#, c-format +msgid "OID (-o) must not be 0" +msgstr "OID (-o) не може бути 0" + +#: pg_resetwal.c:250 +#, c-format +msgid "multitransaction ID (-m) must not be 0" +msgstr "ID мультитранзакції (-m) не повинен бути 0" + +#: pg_resetwal.c:260 +#, c-format +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "найстарший ID мультитранзакції (-m) не повинен бути 0" + +#: pg_resetwal.c:275 +#, c-format +msgid "multitransaction offset (-O) must not be -1" +msgstr "зсув мультитранзакції (-O) не повинен бути -1" + +#: pg_resetwal.c:299 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "аргумент --wal-segsize повинен бути числом" + +#: pg_resetwal.c:304 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "аргумент --wal-segsize повинен бути ступенем 2 між 1 і 1024" + +#: pg_resetwal.c:321 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" + +#: pg_resetwal.c:330 +#, c-format +msgid "no data directory specified" +msgstr "каталог даних не вказано" + +#: pg_resetwal.c:344 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "\"root\" не може це виконувати" + +#: pg_resetwal.c:345 +#, c-format +msgid "You must run %s as the PostgreSQL superuser." +msgstr "Запускати %s треба від суперкористувача PostgreSQL." + +#: pg_resetwal.c:356 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "не вдалося прочитати дозволи на каталог \"%s\": %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не вдалося змінити каталог на \"%s\": %m" + +#: pg_resetwal.c:381 pg_resetwal.c:544 pg_resetwal.c:595 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не вдалося відкрити файл \"%s\" для читання: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "файл блокування \"%s\" вже існує" + +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "Чи запущений сервер? Якщо ні, видаліть файл блокування і спробуйте знову." + +#: pg_resetwal.c:492 +#, c-format +msgid "\n" +"If these values seem acceptable, use -f to force reset.\n" +msgstr "\n" +"Якщо ці значення виглядають допустимими, використайте -f, щоб провести перевстановлення.\n" + +#: pg_resetwal.c:504 +#, c-format +msgid "The database server was not shut down cleanly.\n" +"Resetting the write-ahead log might cause data to be lost.\n" +"If you want to proceed anyway, use -f to force reset.\n" +msgstr "Сервер баз даних був зупинений некоректно.\n" +"Очищення журналу передзапису може привести до втрати даних.\n" +"Якщо ви все одно хочете продовжити, використайте параметр -f.\n" + +#: pg_resetwal.c:518 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "Журнал передзапису скинуто\n" + +#: pg_resetwal.c:553 +#, c-format +msgid "unexpected empty file \"%s\"" +msgstr "неочікуваний порожній файл \"%s\"" + +#: pg_resetwal.c:555 pg_resetwal.c:611 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не вдалося прочитати файл \"%s\": %m" + +#: pg_resetwal.c:564 +#, c-format +msgid "data directory is of wrong version" +msgstr "каталог даних неправильної версії" + +#: pg_resetwal.c:565 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "Файл \"%s\" містить \"%s\", який не сумісний з версією цієї програми \"%s\"." + +#: pg_resetwal.c:598 +#, c-format +msgid "If you are sure the data directory path is correct, execute\n" +" touch %s\n" +"and try again." +msgstr "Якщо Ви впевнені, що шлях каталогу даних є правильним, виконайте \n" +" touch %s\n" +"і спробуйте знову." + +#: pg_resetwal.c:629 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "pg_control існує, але має недопустимий CRC; продовжуйте з обережністю" + +#: pg_resetwal.c:638 +#, c-format +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_control вказує неприпустимий розмір сегмента WAL (%d байт); продовжуйте з обережністю" +msgstr[1] "pg_control вказує неприпустимий розмір сегмента WAL (%d байти); продовжуйте з обережністю" +msgstr[2] "pg_control вказує неприпустимий розмір сегмента WAL (%d байтів); продовжуйте з обережністю" +msgstr[3] "pg_control вказує неприпустимий розмір сегмента WAL (%d байтів); продовжуйте з обережністю" + +#: pg_resetwal.c:649 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "pg_control існує, але зламаний або неправильної версії; ігнорується" + +#: pg_resetwal.c:744 +#, c-format +msgid "Guessed pg_control values:\n\n" +msgstr "Припустимі значення pg_control:\n\n" + +#: pg_resetwal.c:746 +#, c-format +msgid "Current pg_control values:\n\n" +msgstr "Поточні значення pg_control:\n\n" + +#: pg_resetwal.c:748 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_control номер версії: %u\n" + +#: pg_resetwal.c:750 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Номер версії каталогу: %u\n" + +#: pg_resetwal.c:752 +#, c-format +msgid "Database system identifier: %llu\n" +msgstr "Системний ідентифікатор бази даних: %llu\n" + +#: pg_resetwal.c:754 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "Останній TimeLineID контрольної точки: %u\n" + +#: pg_resetwal.c:756 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Останній full_page_writes контрольної точки: %s\n" + +#: pg_resetwal.c:757 +msgid "off" +msgstr "вимк" + +#: pg_resetwal.c:757 +msgid "on" +msgstr "увімк" + +#: pg_resetwal.c:758 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "Останній NextXID контрольної точки: %u%u\n" + +#: pg_resetwal.c:761 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "Останній NextOID контрольної точки: %u\n" + +#: pg_resetwal.c:763 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "Останній NextMultiXactId контрольної точки: %u\n" + +#: pg_resetwal.c:765 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "Останній NextMultiOffset контрольної точки: %u\n" + +#: pg_resetwal.c:767 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "Останній oldestXID контрольної точки: %u\n" + +#: pg_resetwal.c:769 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "Остання DB останнього oldestXID контрольної точки: %u\n" + +#: pg_resetwal.c:771 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "Останній oldestActiveXID контрольної точки: %u\n" + +#: pg_resetwal.c:773 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "Останній oldestMultiXid контрольної точки: %u \n" + +#: pg_resetwal.c:775 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "Остання DB останньої oldestMulti контрольної точки: %u\n" + +#: pg_resetwal.c:777 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "Останній oldestCommitTsXid контрольної точки:%u\n" + +#: pg_resetwal.c:779 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "Останній newestCommitTsXid контрольної точки: %u\n" + +#: pg_resetwal.c:781 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Максимальне вирівнювання даних: %u\n" + +#: pg_resetwal.c:784 +#, c-format +msgid "Database block size: %u\n" +msgstr "Розмір блоку бази даних: %u\n" + +#: pg_resetwal.c:786 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Блоків на сегмент великого відношення: %u\n" + +#: pg_resetwal.c:788 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Pозмір блоку WAL: %u\n" + +#: pg_resetwal.c:790 pg_resetwal.c:876 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Байтів на сегмент WAL: %u\n" + +#: pg_resetwal.c:792 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Максимальна довжина ідентифікаторів: %u\n" + +#: pg_resetwal.c:794 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Максимальна кількість стовпців в індексі: %u\n" + +#: pg_resetwal.c:796 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Максимальний розмір сегменту TOAST: %u\n" + +#: pg_resetwal.c:798 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Розмір сегменту великих обїєктів: %u\n" + +#: pg_resetwal.c:801 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Дата/час типу сховища: %s\n" + +#: pg_resetwal.c:802 +msgid "64-bit integers" +msgstr "64-бітні цілі" + +#: pg_resetwal.c:803 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Передача аргументу Float8: %s\n" + +#: pg_resetwal.c:804 +msgid "by reference" +msgstr "за посиланням" + +#: pg_resetwal.c:804 +msgid "by value" +msgstr "за значенням" + +#: pg_resetwal.c:805 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Версія контрольних сум сторінок даних: %u\n" + +#: pg_resetwal.c:819 +#, c-format +msgid "\n\n" +"Values to be changed:\n\n" +msgstr "\n\n" +"Значення, що потребують зміни:\n\n" + +#: pg_resetwal.c:823 +#, c-format +msgid "First log segment after reset: %s\n" +msgstr "Перший сегмент журналу після скидання: %s\n" + +#: pg_resetwal.c:827 +#, c-format +msgid "NextMultiXactId: %u\n" +msgstr "NextMultiXactId: %u\n" + +#: pg_resetwal.c:829 +#, c-format +msgid "OldestMultiXid: %u\n" +msgstr "OldestMultiXid: %u\n" + +#: pg_resetwal.c:831 +#, c-format +msgid "OldestMulti's DB: %u\n" +msgstr "OldestMulti's DB: %u\n" + +#: pg_resetwal.c:837 +#, c-format +msgid "NextMultiOffset: %u\n" +msgstr "NextMultiOffset: %u\n" + +#: pg_resetwal.c:843 +#, c-format +msgid "NextOID: %u\n" +msgstr "NextOID: %u\n" + +#: pg_resetwal.c:849 +#, c-format +msgid "NextXID: %u\n" +msgstr "NextXID: %u\n" + +#: pg_resetwal.c:851 +#, c-format +msgid "OldestXID: %u\n" +msgstr "OldestXID: %u\n" + +#: pg_resetwal.c:853 +#, c-format +msgid "OldestXID's DB: %u\n" +msgstr "OldestXID's DB: %u\n" + +#: pg_resetwal.c:859 +#, c-format +msgid "NextXID epoch: %u\n" +msgstr "Епоха NextXID: %u\n" + +#: pg_resetwal.c:865 +#, c-format +msgid "oldestCommitTsXid: %u\n" +msgstr "oldestCommitTsXid: %u\n" + +#: pg_resetwal.c:870 +#, c-format +msgid "newestCommitTsXid: %u\n" +msgstr "newestCommitTsXid: %u\n" + +#: pg_resetwal.c:956 pg_resetwal.c:1024 pg_resetwal.c:1071 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не вдалося відкрити каталог \"%s\": %m" + +#: pg_resetwal.c:991 pg_resetwal.c:1044 pg_resetwal.c:1094 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не вдалося прочитати каталог \"%s\": %m" + +#: pg_resetwal.c:997 pg_resetwal.c:1050 pg_resetwal.c:1100 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не вдалося закрити каталог \"%s\": %m" + +#: pg_resetwal.c:1036 pg_resetwal.c:1086 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "не вдалося видалити файл \"%s\": %m" + +#: pg_resetwal.c:1167 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" + +#: pg_resetwal.c:1177 pg_resetwal.c:1190 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не вдалося записати файл \"%s\": %m" + +#: pg_resetwal.c:1197 +#, c-format +msgid "fsync error: %m" +msgstr "помилка fsync: %m" + +#: pg_resetwal.c:1208 +#, c-format +msgid "%s resets the PostgreSQL write-ahead log.\n\n" +msgstr "%s скидає журнал передзапису PostgreSQL.\n\n" + +#: pg_resetwal.c:1209 +#, c-format +msgid "Usage:\n" +" %s [OPTION]... DATADIR\n\n" +msgstr "Використання:\n" +" %s [OPTION]... КАТАЛОГ_ДАНИХ\n\n" + +#: pg_resetwal.c:1210 +#, c-format +msgid "Options:\n" +msgstr "Параметри:\n" + +#: pg_resetwal.c:1211 +#, c-format +msgid " -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr " -c, --commit-timestamp-ids=XID,XID \n" +" встановити найстарішу та найновішу транзакції\n" +" затвердити позначку часу (0 -- не змінювати)\n" + +#: pg_resetwal.c:1214 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR каталог даних\n" + +#: pg_resetwal.c:1215 +#, c-format +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH встановити наступну епоху ID транзакцій\n" + +#: pg_resetwal.c:1216 +#, c-format +msgid " -f, --force force update to be done\n" +msgstr " -f, --force потрібно виконати оновлення\n" + +#: pg_resetwal.c:1217 +#, c-format +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr " -l, --next-wal-file=WALFILE задати мінімальне початкове розташування для нового WAL\n" + +#: pg_resetwal.c:1218 +#, c-format +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr " -m, --multixact-ids=MXID,MXID задати ідентифікатор наступної і найстарішої мультитранзакції\n" + +#: pg_resetwal.c:1219 +#, c-format +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr " -n, --dry-run не оновлювати, лише показати, що буде зроблено\n" + +#: pg_resetwal.c:1220 +#, c-format +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID задати наступний OID\n" + +#: pg_resetwal.c:1221 +#, c-format +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr " -O, --multixact-offset=OFFSET задати зсув наступної мультітранзакції\n" + +#: pg_resetwal.c:1222 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію і вийти\n" + +#: pg_resetwal.c:1223 +#, c-format +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID задати ідентифікатор наступної транзакції\n" + +#: pg_resetwal.c:1224 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE розміри сегментів WAL у мегабайтах\n" + +#: pg_resetwal.c:1225 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати довідку, потім вийти\n" + +#: pg_resetwal.c:1226 +#, c-format +msgid "\n" +"Report bugs to <%s>.\n" +msgstr "\n" +"Повідомляти про помилки на <%s>.\n" + +#: pg_resetwal.c:1227 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + diff --git a/src/bin/pg_resetwal/t/001_basic.pl b/src/bin/pg_resetwal/t/001_basic.pl index ca93ddbda050..9c08ade79fcd 100644 --- a/src/bin/pg_resetwal/t/001_basic.pl +++ b/src/bin/pg_resetwal/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/src/bin/pg_resetwal/t/002_corrupted.pl b/src/bin/pg_resetwal/t/002_corrupted.pl index f9940d7fc5d6..954790c28cce 100644 --- a/src/bin/pg_resetwal/t/002_corrupted.pl +++ b/src/bin/pg_resetwal/t/002_corrupted.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Tests for handling a corrupted pg_control use strict; diff --git a/src/bin/pg_rewind/Makefile b/src/bin/pg_rewind/Makefile index f398c3d84881..5514b95e6c1e 100644 --- a/src/bin/pg_rewind/Makefile +++ b/src/bin/pg_rewind/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_rewind # -# Portions Copyright (c) 2013-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 2013-2021, PostgreSQL Global Development Group # # src/bin/pg_rewind/Makefile # @@ -20,12 +20,11 @@ LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) OBJS = \ $(WIN32RES) \ - copy_fetch.o \ datapagemap.o \ - fetch.o \ file_ops.o \ filemap.o \ - libpq_fetch.o \ + libpq_source.o \ + local_source.o \ parsexlog.o \ pg_rewind.o \ timeline.o \ diff --git a/src/bin/pg_rewind/datapagemap.c b/src/bin/pg_rewind/datapagemap.c index 16fa89da943e..3f8952b8f3be 100644 --- a/src/bin/pg_rewind/datapagemap.c +++ b/src/bin/pg_rewind/datapagemap.c @@ -5,7 +5,7 @@ * * This is a fairly simple bitmap. * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Copyright (c) 2013-2021, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/bin/pg_rewind/datapagemap.h b/src/bin/pg_rewind/datapagemap.h index b5fac09ea6b2..76e9f20c9412 100644 --- a/src/bin/pg_rewind/datapagemap.h +++ b/src/bin/pg_rewind/datapagemap.h @@ -2,7 +2,7 @@ * * datapagemap.h * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Copyright (c) 2013-2021, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/bin/pg_rewind/fetch.c b/src/bin/pg_rewind/fetch.c deleted file mode 100644 index f18fe5386ed4..000000000000 --- a/src/bin/pg_rewind/fetch.c +++ /dev/null @@ -1,60 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fetch.c - * Functions for fetching files from a local or remote data dir - * - * This file forms an abstraction of getting files from the "source". - * There are two implementations of this interface: one for copying files - * from a data directory via normal filesystem operations (copy_fetch.c), - * and another for fetching files from a remote server via a libpq - * connection (libpq_fetch.c) - * - * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group - * - *------------------------------------------------------------------------- - */ -#include "postgres_fe.h" - -#include -#include - -#include "fetch.h" -#include "file_ops.h" -#include "filemap.h" -#include "pg_rewind.h" - -void -fetchSourceFileList(void) -{ - if (datadir_source) - traverse_datadir(datadir_source, &process_source_file); - else - libpqProcessFileList(); -} - -/* - * Fetch all relation data files that are marked in the given data page map. - */ -void -executeFileMap(void) -{ - if (datadir_source) - copy_executeFileMap(filemap); - else - libpq_executeFileMap(filemap); -} - -/* - * Fetch a single file into a malloc'd buffer. The file size is returned - * in *filesize. The returned buffer is always zero-terminated, which is - * handy for text files. - */ -char * -fetchFile(const char *filename, size_t *filesize) -{ - if (datadir_source) - return slurpFile(datadir_source, filename, filesize); - else - return libpqGetFile(filename, filesize); -} diff --git a/src/bin/pg_rewind/fetch.h b/src/bin/pg_rewind/fetch.h deleted file mode 100644 index 7cf8b6ea090d..000000000000 --- a/src/bin/pg_rewind/fetch.h +++ /dev/null @@ -1,44 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fetch.h - * Fetching data from a local or remote data directory. - * - * This file includes the prototypes for functions used to copy files from - * one data directory to another. The source to copy from can be a local - * directory (copy method), or a remote PostgreSQL server (libpq fetch - * method). - * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group - * - *------------------------------------------------------------------------- - */ -#ifndef FETCH_H -#define FETCH_H - -#include "access/xlogdefs.h" - -#include "filemap.h" - -/* - * Common interface. Calls the copy or libpq method depending on global - * config options. - */ -extern void fetchSourceFileList(void); -extern char *fetchFile(const char *filename, size_t *filesize); -extern void executeFileMap(void); - -/* in libpq_fetch.c */ -extern void libpqProcessFileList(void); -extern char *libpqGetFile(const char *filename, size_t *filesize); -extern void libpq_executeFileMap(filemap_t *map); - -extern void libpqConnect(const char *connstr); -extern XLogRecPtr libpqGetCurrentXlogInsertLocation(void); - -/* in copy_fetch.c */ -extern void copy_executeFileMap(filemap_t *map); - -typedef void (*process_file_callback_t) (const char *path, file_type_t type, size_t size, const char *link_target); -extern void traverse_datadir(const char *datadir, process_file_callback_t callback); - -#endif /* FETCH_H */ diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c index ed5b8c9a3e35..c50f283ede41 100644 --- a/src/bin/pg_rewind/file_ops.c +++ b/src/bin/pg_rewind/file_ops.c @@ -8,17 +8,19 @@ * do nothing if it's enabled. You should avoid accessing the target files * directly but if you do, make sure you honor the --dry-run mode! * - * Portions Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2021, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ #include "postgres_fe.h" #include +#include #include #include #include "common/file_perm.h" +#include "common/file_utils.h" #include "file_ops.h" #include "filemap.h" #include "pg_rewind.h" @@ -33,7 +35,10 @@ static void create_target_dir(const char *path); static void remove_target_dir(const char *path); static void create_target_symlink(const char *path, const char *link); static void remove_target_symlink(const char *path); -static void create_target_tablespace_layout(const char *path, const char *link); + +static void recurse_dir(const char *datadir, const char *parentpath, + process_file_callback_t callback); + /* * Open a target file for writing. If 'trunc' is true and the file already * exists, it will be truncated. @@ -82,7 +87,7 @@ close_target_file(void) void write_target_range(char *buf, off_t begin, size_t size) { - int writeleft; + size_t writeleft; char *p; /* update progress report */ @@ -100,7 +105,7 @@ write_target_range(char *buf, off_t begin, size_t size) p = buf; while (writeleft > 0) { - int writelen; + ssize_t writelen; errno = 0; writelen = write(dstfd, p, writeleft); @@ -137,10 +142,6 @@ remove_target(file_entry_t *entry) remove_target_file(entry->path, false); break; - case FILE_TYPE_FIFO: - remove_target_file(entry->path, false); - break; - case FILE_TYPE_SYMLINK: remove_target_symlink(entry->path); break; @@ -164,10 +165,7 @@ create_target(file_entry_t *entry) break; case FILE_TYPE_SYMLINK: - if (entry->is_gp_tablespace) - create_target_tablespace_layout(entry->path, entry->source_link_target); - else - create_target_symlink(entry->path, entry->source_link_target); + create_target_symlink(entry->path, entry->source_link_target); break; case FILE_TYPE_REGULAR: @@ -175,11 +173,6 @@ create_target(file_entry_t *entry) pg_fatal("invalid action (CREATE) for regular file"); break; - case FILE_TYPE_FIFO: - /* Only pgsql_tmp files are FIFO and they are ignored from source target. */ - pg_fatal("invalid action (CREATE) for fifo file"); - break; - case FILE_TYPE_UNDEFINED: pg_fatal("undefined file type for \"%s\"", entry->path); break; @@ -288,32 +281,25 @@ remove_target_symlink(const char *path) dstpath); } -/* Create symlink for tablespace, create tablespace target dir */ -static void -create_target_tablespace_layout(const char *path, const char *link) +/* + * Sync target data directory to ensure that modifications are safely on disk. + * + * We do this once, for the whole data directory, for performance reasons. At + * the end of pg_rewind's run, the kernel is likely to already have flushed + * most dirty buffers to disk. Additionally fsync_pgdata uses a two-pass + * approach (only initiating writeback in the first pass), which often reduces + * the overall amount of IO noticeably. + */ +void +sync_target_dir(void) { - char dstpath[MAXPGPATH]; - char *newlink; - - if (dry_run) + if (!do_sync || dry_run) return; - /* Append the target dbid to the symlink target. */ - newlink = psprintf("%s/%d", link, dbid_target); - - snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path); - if (symlink(newlink, dstpath) != 0) - pg_fatal("could not create symbolic link at \"%s\": %m", - dstpath); - - /* We need to create the directory at the symlink target. */ - if (mkdir(newlink, S_IRWXU) != 0) - pg_fatal("could not create directory \"%s\": %m", - newlink); - - pfree(newlink); + fsync_pgdata(datadir_target, PG_VERSION_NUM); } + /* * Read a file into memory. The file to be read is /. * The file contents are returned in a malloc'd buffer, and *filesize @@ -323,9 +309,6 @@ create_target_tablespace_layout(const char *path, const char *link) * buffer is actually *filesize + 1. That's handy when reading a text file. * This function can be used to read binary files as well, you can just * ignore the zero-terminator in that case. - * - * This function is used to implement the fetchFile function in the "fetch" - * interface (see fetch.c), but is also called directly. */ char * slurpFile(const char *datadir, const char *path, size_t *filesize) @@ -370,3 +353,125 @@ slurpFile(const char *datadir, const char *path, size_t *filesize) *filesize = len; return buffer; } + +/* + * Traverse through all files in a data directory, calling 'callback' + * for each file. + */ +void +traverse_datadir(const char *datadir, process_file_callback_t callback) +{ + recurse_dir(datadir, NULL, callback); +} + +/* + * recursive part of traverse_datadir + * + * parentpath is the current subdirectory's path relative to datadir, + * or NULL at the top level. + */ +static void +recurse_dir(const char *datadir, const char *parentpath, + process_file_callback_t callback) +{ + DIR *xldir; + struct dirent *xlde; + char fullparentpath[MAXPGPATH]; + + if (parentpath) + snprintf(fullparentpath, MAXPGPATH, "%s/%s", datadir, parentpath); + else + snprintf(fullparentpath, MAXPGPATH, "%s", datadir); + + xldir = opendir(fullparentpath); + if (xldir == NULL) + pg_fatal("could not open directory \"%s\": %m", + fullparentpath); + + while (errno = 0, (xlde = readdir(xldir)) != NULL) + { + struct stat fst; + char fullpath[MAXPGPATH * 2]; + char path[MAXPGPATH * 2]; + + if (strcmp(xlde->d_name, ".") == 0 || + strcmp(xlde->d_name, "..") == 0) + continue; + + snprintf(fullpath, sizeof(fullpath), "%s/%s", fullparentpath, xlde->d_name); + + if (lstat(fullpath, &fst) < 0) + { + if (errno == ENOENT) + { + /* + * File doesn't exist anymore. This is ok, if the new primary + * is running and the file was just removed. If it was a data + * file, there should be a WAL record of the removal. If it + * was something else, it couldn't have been anyway. + * + * TODO: But complain if we're processing the target dir! + */ + } + else + pg_fatal("could not stat file \"%s\": %m", + fullpath); + } + + if (parentpath) + snprintf(path, sizeof(path), "%s/%s", parentpath, xlde->d_name); + else + snprintf(path, sizeof(path), "%s", xlde->d_name); + + if (S_ISREG(fst.st_mode)) + callback(path, FILE_TYPE_REGULAR, fst.st_size, NULL); + else if (S_ISDIR(fst.st_mode)) + { + callback(path, FILE_TYPE_DIRECTORY, 0, NULL); + /* recurse to handle subdirectories */ + recurse_dir(datadir, path, callback); + } +#ifndef WIN32 + else if (S_ISLNK(fst.st_mode)) +#else + else if (pgwin32_is_junction(fullpath)) +#endif + { +#if defined(HAVE_READLINK) || defined(WIN32) + char link_target[MAXPGPATH]; + int len; + + len = readlink(fullpath, link_target, sizeof(link_target)); + if (len < 0) + pg_fatal("could not read symbolic link \"%s\": %m", + fullpath); + if (len >= sizeof(link_target)) + pg_fatal("symbolic link \"%s\" target is too long", + fullpath); + link_target[len] = '\0'; + + callback(path, FILE_TYPE_SYMLINK, 0, link_target); + + /* + * If it's a symlink within pg_tblspc, we need to recurse into it, + * to process all the tablespaces. We also follow a symlink if + * it's for pg_wal. Symlinks elsewhere are ignored. + */ + if ((parentpath && strcmp(parentpath, "pg_tblspc") == 0) || + strcmp(path, "pg_wal") == 0) + recurse_dir(datadir, path, callback); +#else + pg_fatal("\"%s\" is a symbolic link, but symbolic links are not supported on this platform", + fullpath); +#endif /* HAVE_READLINK */ + } + } + + if (errno) + pg_fatal("could not read directory \"%s\": %m", + fullparentpath); + + if (closedir(xldir)) + pg_fatal("could not close directory \"%s\": %m", + fullparentpath); +} diff --git a/src/bin/pg_rewind/file_ops.h b/src/bin/pg_rewind/file_ops.h index 025f24141c98..611981f293a1 100644 --- a/src/bin/pg_rewind/file_ops.h +++ b/src/bin/pg_rewind/file_ops.h @@ -3,7 +3,7 @@ * file_ops.h * Helper functions for operating on files * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Copyright (c) 2013-2021, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -19,7 +19,11 @@ extern void remove_target_file(const char *path, bool missing_ok); extern void truncate_target_file(const char *path, off_t newsize); extern void create_target(file_entry_t *t); extern void remove_target(file_entry_t *t); +extern void sync_target_dir(void); extern char *slurpFile(const char *datadir, const char *path, size_t *filesize); +typedef void (*process_file_callback_t) (const char *path, file_type_t type, size_t size, const char *link_target); +extern void traverse_datadir(const char *datadir, process_file_callback_t callback); + #endif /* FILE_OPS_H */ diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c index b4e9289eeef8..a1f07f2f4e12 100644 --- a/src/bin/pg_rewind/filemap.c +++ b/src/bin/pg_rewind/filemap.c @@ -3,7 +3,20 @@ * filemap.c * A data structure for keeping track of files that have changed. * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group + * This source file contains the logic to decide what to do with different + * kinds of files, and the data structure to support it. Before modifying + * anything, pg_rewind collects information about all the files and their + * attributes in the target and source data directories. It also scans the + * WAL log in the target, and collects information about data blocks that + * were changed. All this information is stored in a hash table, using the + * file path relative to the root of the data directory as the key. + * + * After collecting all the information required, the decide_file_actions() + * function scans the hash table and decides what action needs to be taken + * for each file. Finally, it sorts the array to the final order that the + * actions should be executed in. + * + * Copyright (c) 2013-2021, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -13,24 +26,43 @@ #include #include -#include "catalog/catalog.h" #include "catalog/pg_tablespace_d.h" +#include "common/hashfn.h" +#include "common/relpath.h" #include "common/string.h" #include "datapagemap.h" #include "filemap.h" #include "pg_rewind.h" #include "storage/fd.h" -filemap_t *filemap = NULL; +/* + * Define a hash table which we can use to store information about the files + * appearing in source and target systems. + */ +static uint32 hash_string_pointer(const char *s); +#define SH_PREFIX filehash +#define SH_ELEMENT_TYPE file_entry_t +#define SH_KEY_TYPE const char * +#define SH_KEY path +#define SH_HASH_KEY(tb, key) hash_string_pointer(key) +#define SH_EQUAL(tb, a, b) (strcmp(a, b) == 0) +#define SH_SCOPE static inline +#define SH_RAW_ALLOCATOR pg_malloc0 +#define SH_DECLARE +#define SH_DEFINE +#include "lib/simplehash.h" + +#define FILEHASH_INITIAL_SIZE 1000 + +static filehash_hash *filehash; static bool isRelDataFile(const char *path); static char *datasegpath(RelFileNode rnode, ForkNumber forknum, BlockNumber segno); -static int path_cmp(const void *a, const void *b); -static file_entry_t *get_filemap_entry(const char *path, bool create); +static file_entry_t *insert_filehash_entry(const char *path); +static file_entry_t *lookup_filehash_entry(const char *path); static int final_filemap_cmp(const void *a, const void *b); -static void filemap_list_to_array(filemap_t *map); static bool check_file_excluded(const char *path, bool is_source); /* @@ -88,12 +120,6 @@ static const char *excludeDirContents[] = /* Contents zeroed on startup, see StartupSUBTRANS(). */ "pg_subtrans", - /* GPDB: Contents unique to each segment instance. */ - "log", - - /* GPDB: Default gpbackup directory (backup contents) */ - "backups", - /* end of list */ NULL }; @@ -133,64 +159,31 @@ static const struct exclude_list_item excludeFiles[] = {"postmaster.pid", false}, {"postmaster.opts", false}, - {GP_INTERNAL_AUTO_CONF_FILE_NAME, false}, - - /* GPDB: Default gpbackup directory (top-level directory) */ - {"backups", false}, - /* end of list */ {NULL, false} }; /* - * Create a new file map (stored in the global pointer "filemap"). + * Initialize the hash table for the file map. */ void -filemap_create(void) +filehash_init(void) { - filemap_t *map; - - map = pg_malloc(sizeof(filemap_t)); - map->first = map->last = NULL; - map->nlist = 0; - map->array = NULL; - map->narray = 0; - - Assert(filemap == NULL); - filemap = map; + filehash = filehash_create(FILEHASH_INITIAL_SIZE, NULL); } -/* Look up or create entry for 'path' */ +/* Look up entry for 'path', creating a new one if it doesn't exist */ static file_entry_t * -get_filemap_entry(const char *path, bool create) +insert_filehash_entry(const char *path) { - filemap_t *map = filemap; file_entry_t *entry; - file_entry_t **e; - file_entry_t key; - file_entry_t *key_ptr; - - if (map->array) - { - key.path = (char *) path; - key_ptr = &key; - e = bsearch(&key_ptr, map->array, map->narray, sizeof(file_entry_t *), - path_cmp); - } - else - e = NULL; + bool found; - if (e) - entry = *e; - else if (!create) - entry = NULL; - else + entry = filehash_insert(filehash, path, &found); + if (!found) { - /* Create a new entry for this file */ - entry = pg_malloc(sizeof(file_entry_t)); entry->path = pg_strdup(path); entry->isrelfile = isRelDataFile(path); - entry->action = FILE_ACTION_UNDECIDED; entry->target_exists = false; entry->target_type = FILE_TYPE_UNDEFINED; @@ -204,23 +197,18 @@ get_filemap_entry(const char *path, bool create) entry->source_size = 0; entry->source_link_target = NULL; - entry->is_gp_tablespace = false; - - entry->next = NULL; - - if (map->last) - { - map->last->next = entry; - map->last = entry; - } - else - map->first = map->last = entry; - map->nlist++; + entry->action = FILE_ACTION_UNDECIDED; } return entry; } +static file_entry_t * +lookup_filehash_entry(const char *path) +{ + return filehash_lookup(filehash, path); +} + /* * Callback for processing source file list. * @@ -234,8 +222,6 @@ process_source_file(const char *path, file_type_t type, size_t size, { file_entry_t *entry; - Assert(filemap->array == NULL); - /* * Pretend that pg_wal is a directory, even if it's really a symlink. We * don't want to mess with the symlink itself, nor complain if it's a @@ -252,7 +238,9 @@ process_source_file(const char *path, file_type_t type, size_t size, pg_fatal("data file \"%s\" in source is not a regular file", path); /* Remember this source file */ - entry = get_filemap_entry(path, true); + entry = insert_filehash_entry(path); + if (entry->source_exists) + pg_fatal("duplicate source file \"%s\"", path); entry->source_exists = true; entry->source_type = type; entry->source_size = size; @@ -262,58 +250,19 @@ process_source_file(const char *path, file_type_t type, size_t size, /* * Callback for processing target file list. * - * All source files must be already processed before calling this. We record - * the type and size of file, so that decide_file_action() can later decide - * what to do with it. + * Record the type and size of the file, like process_source_file() does. */ void process_target_file(const char *path, file_type_t type, size_t size, const char *link_target) { - filemap_t *map = filemap; file_entry_t *entry; /* * Do not apply any exclusion filters here. This has advantage to remove * from the target data folder all paths which have been filtered out from * the source data folder when processing the source files. - * - * GPDB: GP_INTERNAL_AUTO_CONF_FILE_NAME, "log", and "backups" are in the - * excluded dir/file list. These should not be copied but also should not - * be removed. In the future, if there are more files or directories that - * should not be copied but also should not be removed, then a separate - * function for those would be better. */ - { - const char *filename = last_dir_separator(path); - if (filename == NULL) - filename = path; - else - filename++; - if (strcmp(filename, GP_INTERNAL_AUTO_CONF_FILE_NAME) == 0) - return; - if (strstr(path, "log/") == path) - return; - if (strstr(path, "backups/") == path || - strcmp(path, "backups") == 0) - return; - } - - if (map->array == NULL) - { - /* on first call, initialize lookup array */ - if (map->nlist == 0) - { - /* should not happen */ - pg_fatal("source file list is empty"); - } - - filemap_list_to_array(map); - - Assert(map->array != NULL); - - qsort(map->array, map->narray, sizeof(file_entry_t *), path_cmp); - } /* * Like in process_source_file, pretend that pg_wal is always a directory. @@ -322,7 +271,9 @@ process_target_file(const char *path, file_type_t type, size_t size, type = FILE_TYPE_DIRECTORY; /* Remember this target file */ - entry = get_filemap_entry(path, true); + entry = insert_filehash_entry(path); + if (entry->target_exists) + pg_fatal("duplicate source file \"%s\"", path); entry->target_exists = true; entry->target_type = type; entry->target_size = size; @@ -336,7 +287,7 @@ process_target_file(const char *path, file_type_t type, size_t size, * if so, records it in 'target_pages_to_overwrite' bitmap. * * NOTE: All the files on both systems must have already been added to the - * file map! + * hash table! */ void process_target_wal_block_change(ForkNumber forknum, RelFileNode rnode, @@ -347,97 +298,48 @@ process_target_wal_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno_inseg; int segno; - Assert(filemap->array); - segno = blkno / RELSEG_SIZE; blkno_inseg = blkno % RELSEG_SIZE; path = datasegpath(rnode, forknum, segno); - entry = get_filemap_entry(path, false); + entry = lookup_filehash_entry(path); pfree(path); - if (entry && entry->target_exists) + /* + * If the block still exists in both systems, remember it. Otherwise we + * can safely ignore it. + * + * If the block is beyond the EOF in the source system, or the file + * doesn't exist in the source at all, we're going to truncate/remove it + * away from the target anyway. Likewise, if it doesn't exist in the + * target anymore, we will copy it over with the "tail" from the source + * system, anyway. + * + * It is possible to find WAL for a file that doesn't exist on either + * system anymore. It means that the relation was dropped later in the + * target system, and independently on the source system too, or that it + * was created and dropped in the target system and it never existed in + * the source. Either way, we can safely ignore it. + */ + if (entry) { - int64 end_offset; - Assert(entry->isrelfile); - if (entry->target_type != FILE_TYPE_REGULAR) - pg_fatal("unexpected page modification for non-regular file \"%s\"", - entry->path); - - /* - * If the block beyond the EOF in the source system, no need to - * remember it now, because we're going to truncate it away from the - * target anyway. Also no need to remember the block if it's beyond - * the current EOF in the target system; we will copy it over with the - * "tail" from the source system, anyway. - */ - end_offset = (blkno_inseg + 1) * BLCKSZ; - if (end_offset <= entry->source_size && - end_offset <= entry->target_size) - datapagemap_add(&entry->target_pages_to_overwrite, blkno_inseg); - } - else - { - /* - * If we don't have any record of this file in the file map, it means - * that it's a relation that doesn't exist in the source system. It - * could exist in the target system; we haven't moved the target-only - * entries from the linked list to the array yet! But in any case, if - * it doesn't exist in the source it will be removed from the target - * too, and we can safely ignore it. - */ - } -} - -void -process_target_wal_aofile_change(RelFileNode rnode, int segno, int64 offset) -{ - char *path; - file_entry_t *entry; - - Assert(filemap->array); - - path = datasegpath(rnode, MAIN_FORKNUM, segno); - entry = get_filemap_entry(path, false); - pfree(path); + if (entry->target_exists) + { + if (entry->target_type != FILE_TYPE_REGULAR) + pg_fatal("unexpected page modification for non-regular file \"%s\"", + entry->path); - if (entry && entry->target_exists) - { - if (entry->target_size < entry->source_size) - { - /* - * if the insertion happened in the area between target_size - * and source_size, no change in action needed. But if insert - * was performed at offset lower than the starting point, which - * is target_size, reset the starting point to lower value from - * xlog record. - */ - if (offset < entry->target_size) - entry->target_size = offset; - } - else + if (entry->source_exists) { - /* - * if the insertion happened after the point we plan to - * truncate, don't bother copying. - */ - if (offset < entry->source_size) - { - /* - * since target_size must be either equal or greater than - * source_size, so we can safely assign offset to - * target_size. - */ - Assert(offset <= entry->target_size); - entry->target_size = offset; - } + off_t end_offset; + + end_offset = (blkno_inseg + 1) * BLCKSZ; + if (end_offset <= entry->source_size && end_offset <= entry->target_size) + datapagemap_add(&entry->target_pages_to_overwrite, blkno_inseg); } - } - else - { - /* Similar to process_target_wal_block_change(), the absence of the file entry is not an error */ + } } } @@ -508,34 +410,6 @@ check_file_excluded(const char *path, bool is_source) return false; } -/* - * Convert the linked list of entries in map->first/last to the array, - * map->array. - */ -static void -filemap_list_to_array(filemap_t *map) -{ - int narray; - file_entry_t *entry, - *next; - - map->array = (file_entry_t **) - pg_realloc(map->array, - (map->nlist + map->narray) * sizeof(file_entry_t *)); - - narray = map->narray; - for (entry = map->first; entry != NULL; entry = next) - { - map->array[narray++] = entry; - next = entry->next; - entry->next = NULL; - } - Assert(narray == map->nlist + map->narray); - map->narray = narray; - map->nlist = 0; - map->first = map->last = NULL; -} - static const char * action_to_str(file_action_t action) { @@ -563,32 +437,31 @@ action_to_str(file_action_t action) * Calculate the totals needed for progress reports. */ void -calculate_totals(void) +calculate_totals(filemap_t *filemap) { file_entry_t *entry; int i; - filemap_t *map = filemap; - map->total_size = 0; - map->fetch_size = 0; + filemap->total_size = 0; + filemap->fetch_size = 0; - for (i = 0; i < map->narray; i++) + for (i = 0; i < filemap->nentries; i++) { - entry = map->array[i]; + entry = filemap->entries[i]; if (entry->source_type != FILE_TYPE_REGULAR) continue; - map->total_size += entry->source_size; + filemap->total_size += entry->source_size; if (entry->action == FILE_ACTION_COPY) { - map->fetch_size += entry->source_size; + filemap->fetch_size += entry->source_size; continue; } if (entry->action == FILE_ACTION_COPY_TAIL) - map->fetch_size += (entry->source_size - entry->target_size); + filemap->fetch_size += (entry->source_size - entry->target_size); if (entry->target_pages_to_overwrite.bitmapsize > 0) { @@ -597,7 +470,7 @@ calculate_totals(void) iter = datapagemap_iterate(&entry->target_pages_to_overwrite); while (datapagemap_next(iter, &blk)) - map->fetch_size += BLCKSZ; + filemap->fetch_size += BLCKSZ; pg_free(iter); } @@ -605,15 +478,14 @@ calculate_totals(void) } void -print_filemap(void) +print_filemap(filemap_t *filemap) { - filemap_t *map = filemap; file_entry_t *entry; int i; - for (i = 0; i < map->narray; i++) + for (i = 0; i < filemap->nentries; i++) { - entry = map->array[i]; + entry = filemap->entries[i]; if (entry->action != FILE_ACTION_NONE || entry->target_pages_to_overwrite.bitmapsize > 0) { @@ -735,15 +607,6 @@ datasegpath(RelFileNode rnode, ForkNumber forknum, BlockNumber segno) return path; } -static int -path_cmp(const void *a, const void *b) -{ - file_entry_t *fa = *((file_entry_t **) a); - file_entry_t *fb = *((file_entry_t **) b); - - return strcmp(fa->path, fb->path); -} - /* * In the final stage, the filemap is sorted so that removals come last. * From disk space usage point of view, it would be better to do removals @@ -811,12 +674,9 @@ decide_file_action(file_entry_t *entry) { case FILE_TYPE_DIRECTORY: case FILE_TYPE_SYMLINK: - entry->is_gp_tablespace = strncmp(entry->path, "pg_tblspc/", strlen("pg_tblspc/")) == 0; return FILE_ACTION_CREATE; case FILE_TYPE_REGULAR: return FILE_ACTION_COPY; - case FILE_TYPE_FIFO: - return FILE_ACTION_NONE; case FILE_TYPE_UNDEFINED: pg_fatal("unknown file type for \"%s\"", entry->path); break; @@ -911,9 +771,6 @@ decide_file_action(file_entry_t *entry) } break; - case FILE_TYPE_FIFO: - return FILE_ACTION_NONE; - case FILE_TYPE_UNDEFINED: pg_fatal("unknown file type for \"%s\"", path); break; @@ -925,22 +782,62 @@ decide_file_action(file_entry_t *entry) /* * Decide what to do with each file. + * + * Returns a 'filemap' with the entries in the order that their actions + * should be executed. */ -void +filemap_t * decide_file_actions(void) { int i; + filehash_iterator it; + file_entry_t *entry; + filemap_t *filemap; - filemap_list_to_array(filemap); - - for (i = 0; i < filemap->narray; i++) + filehash_start_iterate(filehash, &it); + while ((entry = filehash_iterate(filehash, &it)) != NULL) { - file_entry_t *entry = filemap->array[i]; - entry->action = decide_file_action(entry); } - /* Sort the actions to the order that they should be performed */ - qsort(filemap->array, filemap->narray, sizeof(file_entry_t *), + /* + * Turn the hash table into an array, and sort in the order that the + * actions should be performed. + */ + filemap = pg_malloc(offsetof(filemap_t, entries) + + filehash->members * sizeof(file_entry_t *)); + filemap->nentries = filehash->members; + filehash_start_iterate(filehash, &it); + i = 0; + while ((entry = filehash_iterate(filehash, &it)) != NULL) + { + filemap->entries[i++] = entry; + } + + qsort(&filemap->entries, filemap->nentries, sizeof(file_entry_t *), final_filemap_cmp); + + return filemap; +} + + +/* + * Helper function for filemap hash table. + */ +static uint32 +hash_string_pointer(const char *s) +{ + unsigned char *ss = (unsigned char *) s; + + return hash_bytes(ss, strlen(s)); +} + +/* + * GPDB: Track AO file changes from WAL. + * TODO: Adapt for PG14 filemap hash table API. + */ +void +process_target_wal_aofile_change(RelFileNode rnode, int segno, int64 offset) +{ + /* No-op until adapted for PG14 filemap */ } diff --git a/src/bin/pg_rewind/filemap.h b/src/bin/pg_rewind/filemap.h index a2954f54b293..42e76dc5c7d8 100644 --- a/src/bin/pg_rewind/filemap.h +++ b/src/bin/pg_rewind/filemap.h @@ -2,7 +2,7 @@ * * filemap.h * - * Copyright (c) 2013-2020, PostgreSQL Global Development Group + * Copyright (c) 2013-2021, PostgreSQL Global Development Group *------------------------------------------------------------------------- */ #ifndef FILEMAP_H @@ -12,15 +12,6 @@ #include "storage/block.h" #include "storage/relfilenode.h" -/* - * For every file found in the local or remote system, we have a file entry - * that contains information about the file on both systems. For relation - * files, there is also a page map that marks pages in the file that were - * changed in the target after the last common checkpoint. Each entry also - * contains an 'action' field, which says what we are going to do with the - * file. - */ - /* these enum values are sorted in the order we want actions to be processed */ typedef enum { @@ -41,14 +32,25 @@ typedef enum FILE_TYPE_UNDEFINED = 0, FILE_TYPE_REGULAR, - FILE_TYPE_FIFO, FILE_TYPE_DIRECTORY, FILE_TYPE_SYMLINK } file_type_t; +/* + * For every file found in the local or remote system, we have a file entry + * that contains information about the file on both systems. For relation + * files, there is also a page map that marks pages in the file that were + * changed in the target after the last common checkpoint. + * + * When gathering information, these are kept in a hash table, private to + * filemap.c. decide_file_actions() fills in the 'action' field, sorts all + * the entries, and returns them in an array, ready for executing the actions. + */ typedef struct file_entry_t { - char *path; + uint32 status; /* hash status */ + + const char *path; bool isrelfile; /* is it a relation data file? */ /* @@ -73,60 +75,43 @@ typedef struct file_entry_t size_t source_size; char *source_link_target; /* for a symlink */ - bool is_gp_tablespace; - /* * What will we do to the file? */ file_action_t action; - - struct file_entry_t *next; } file_entry_t; +/* + * This contains the final decisions on what to do with each file. + * 'entries' array contains an entry for each file, sorted in the order + * that their actions should executed. + */ typedef struct filemap_t { - /* - * New entries are accumulated to a linked list, in process_source_file - * and process_target_file. - */ - file_entry_t *first; - file_entry_t *last; - int nlist; /* number of entries currently in list */ - - /* - * After processing all the remote files, the entries in the linked list - * are moved to this array. After processing local files, too, all the - * local entries are added to the array by decide_file_actions(), and - * sorted in the final order. After decide_file_actions(), all the entries - * are in the array, and the linked list is empty. - */ - file_entry_t **array; - int narray; /* current length of array */ - - /* - * Summary information. - */ + /* Summary information, filled by calculate_totals() */ uint64 total_size; /* total size of the source cluster */ uint64 fetch_size; /* number of bytes that needs to be copied */ -} filemap_t; -extern filemap_t *filemap; - -extern void filemap_create(void); -extern void calculate_totals(void); -extern void print_filemap(void); + int nentries; /* size of 'entries' array */ + file_entry_t *entries[FLEXIBLE_ARRAY_MEMBER]; +} filemap_t; /* Functions for populating the filemap */ +extern void filehash_init(void); extern void process_source_file(const char *path, file_type_t type, size_t size, const char *link_target); extern void process_target_file(const char *path, file_type_t type, size_t size, const char *link_target); -extern void process_target_wal_aofile_change(RelFileNode rnode, - int segno, - int64 offset); extern void process_target_wal_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno); -extern void decide_file_actions(void); + +extern filemap_t *decide_file_actions(void); +extern void calculate_totals(filemap_t *filemap); +extern void print_filemap(filemap_t *filemap); + +/* GPDB: AO file WAL tracking - needs adaptation for PG14 filemap */ +extern void process_target_wal_aofile_change(RelFileNode rnode, + int segno, int64 offset); #endif /* FILEMAP_H */ diff --git a/src/bin/pg_rewind/libpq_source.c b/src/bin/pg_rewind/libpq_source.c new file mode 100644 index 000000000000..8e0783fcef3d --- /dev/null +++ b/src/bin/pg_rewind/libpq_source.c @@ -0,0 +1,643 @@ +/*------------------------------------------------------------------------- + * + * libpq_source.c + * Functions for fetching files from a remote server via libpq. + * + * Copyright (c) 2013-2021, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#include "postgres_fe.h" + +#include "catalog/pg_type_d.h" +#include "common/connect.h" +#include "datapagemap.h" +#include "file_ops.h" +#include "filemap.h" +#include "lib/stringinfo.h" +#include "pg_rewind.h" +#include "port/pg_bswap.h" +#include "rewind_source.h" + +/* + * Files are fetched MAX_CHUNK_SIZE bytes at a time, and with a + * maximum of MAX_CHUNKS_PER_QUERY chunks in a single query. + */ +#define MAX_CHUNK_SIZE (1024 * 1024) +#define MAX_CHUNKS_PER_QUERY 1000 + +/* represents a request to fetch a piece of a file from the source */ +typedef struct +{ + const char *path; /* path relative to data directory root */ + off_t offset; + size_t length; +} fetch_range_request; + +typedef struct +{ + rewind_source common; /* common interface functions */ + + PGconn *conn; + + /* + * Queue of chunks that have been requested with the queue_fetch_range() + * function, but have not been fetched from the remote server yet. + */ + int num_requests; + fetch_range_request request_queue[MAX_CHUNKS_PER_QUERY]; + + /* temporary space for process_queued_fetch_requests() */ + StringInfoData paths; + StringInfoData offsets; + StringInfoData lengths; +} libpq_source; + +static void init_libpq_conn(PGconn *conn); +static char *run_simple_query(PGconn *conn, const char *sql); +static void run_simple_command(PGconn *conn, const char *sql); +static void appendArrayEscapedString(StringInfo buf, const char *str); + +static void process_queued_fetch_requests(libpq_source *src); + +/* public interface functions */ +static void libpq_traverse_files(rewind_source *source, + process_file_callback_t callback); +static void libpq_queue_fetch_range(rewind_source *source, const char *path, + off_t off, size_t len); +static void libpq_finish_fetch(rewind_source *source); +static char *libpq_fetch_file(rewind_source *source, const char *path, + size_t *filesize); +static XLogRecPtr libpq_get_current_wal_insert_lsn(rewind_source *source); +static void libpq_destroy(rewind_source *source); + +/* + * Create a new libpq source. + * + * The caller has already established the connection, but should not try + * to use it while the source is active. + */ +rewind_source * +init_libpq_source(PGconn *conn) +{ + libpq_source *src; + + init_libpq_conn(conn); + + src = pg_malloc0(sizeof(libpq_source)); + + src->common.traverse_files = libpq_traverse_files; + src->common.fetch_file = libpq_fetch_file; + src->common.queue_fetch_range = libpq_queue_fetch_range; + src->common.finish_fetch = libpq_finish_fetch; + src->common.get_current_wal_insert_lsn = libpq_get_current_wal_insert_lsn; + src->common.destroy = libpq_destroy; + + src->conn = conn; + + initStringInfo(&src->paths); + initStringInfo(&src->offsets); + initStringInfo(&src->lengths); + + return &src->common; +} + +/* + * Initialize a libpq connection for use. + */ +static void +init_libpq_conn(PGconn *conn) +{ + PGresult *res; + char *str; + + /* disable all types of timeouts */ + run_simple_command(conn, "SET statement_timeout = 0"); + run_simple_command(conn, "SET lock_timeout = 0"); + run_simple_command(conn, "SET idle_in_transaction_session_timeout = 0"); + + /* + * we don't intend to do any updates, put the connection in read-only mode + * to keep us honest + */ + run_simple_command(conn, "SET default_transaction_read_only = on"); + + /* secure search_path */ + res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + pg_fatal("could not clear search_path: %s", + PQresultErrorMessage(res)); + PQclear(res); + + /* + * Also check that full_page_writes is enabled. We can get torn pages if + * a page is modified while we read it with pg_read_binary_file(), and we + * rely on full page images to fix them. + */ + str = run_simple_query(conn, "SHOW full_page_writes"); + if (strcmp(str, "on") != 0) + pg_fatal("full_page_writes must be enabled in the source server"); + pg_free(str); + + /* Prepare a statement we'll use to fetch files */ + res = PQprepare(conn, "fetch_chunks_stmt", + "SELECT path, begin,\n" + " pg_read_binary_file(path, begin, len, true) AS chunk\n" + "FROM unnest ($1::text[], $2::int8[], $3::int4[]) as x(path, begin, len)", + 3, NULL); + + if (PQresultStatus(res) != PGRES_COMMAND_OK) + pg_fatal("could not prepare statement to fetch file contents: %s", + PQresultErrorMessage(res)); + PQclear(res); +} + +/* + * Run a query that returns a single value. + * + * The result should be pg_free'd after use. + */ +static char * +run_simple_query(PGconn *conn, const char *sql) +{ + PGresult *res; + char *result; + + res = PQexec(conn, sql); + + if (PQresultStatus(res) != PGRES_TUPLES_OK) + pg_fatal("error running query (%s) on source server: %s", + sql, PQresultErrorMessage(res)); + + /* sanity check the result set */ + if (PQnfields(res) != 1 || PQntuples(res) != 1 || PQgetisnull(res, 0, 0)) + pg_fatal("unexpected result set from query"); + + result = pg_strdup(PQgetvalue(res, 0, 0)); + + PQclear(res); + + return result; +} + +/* + * Run a command. + * + * In the event of a failure, exit immediately. + */ +static void +run_simple_command(PGconn *conn, const char *sql) +{ + PGresult *res; + + res = PQexec(conn, sql); + + if (PQresultStatus(res) != PGRES_COMMAND_OK) + pg_fatal("error running query (%s) in source server: %s", + sql, PQresultErrorMessage(res)); + + PQclear(res); +} + +/* + * Call the pg_current_wal_insert_lsn() function in the remote system. + */ +static XLogRecPtr +libpq_get_current_wal_insert_lsn(rewind_source *source) +{ + PGconn *conn = ((libpq_source *) source)->conn; + XLogRecPtr result; + uint32 hi; + uint32 lo; + char *val; + + val = run_simple_query(conn, "SELECT pg_current_wal_insert_lsn()"); + + if (sscanf(val, "%X/%X", &hi, &lo) != 2) + pg_fatal("unrecognized result \"%s\" for current WAL insert location", val); + + result = ((uint64) hi) << 32 | lo; + + pg_free(val); + + return result; +} + +/* + * Get a list of all files in the data directory. + */ +static void +libpq_traverse_files(rewind_source *source, process_file_callback_t callback) +{ + PGconn *conn = ((libpq_source *) source)->conn; + PGresult *res; + const char *sql; + int i; + + /* + * Create a recursive directory listing of the whole data directory. + * + * The WITH RECURSIVE part does most of the work. The second part gets the + * targets of the symlinks in pg_tblspc directory. + * + * XXX: There is no backend function to get a symbolic link's target in + * general, so if the admin has put any custom symbolic links in the data + * directory, they won't be copied correctly. + */ + sql = + "WITH RECURSIVE files (path, filename, size, isdir) AS (\n" + " SELECT '' AS path, filename, size, isdir FROM\n" + " (SELECT pg_ls_dir('.', true, false) AS filename) AS fn,\n" + " pg_stat_file(fn.filename, true) AS this\n" + " UNION ALL\n" + " SELECT parent.path || parent.filename || '/' AS path,\n" + " fn, this.size, this.isdir\n" + " FROM files AS parent,\n" + " pg_ls_dir(parent.path || parent.filename, true, false) AS fn,\n" + " pg_stat_file(parent.path || parent.filename || '/' || fn, true) AS this\n" + " WHERE parent.isdir = 't'\n" + ")\n" + "SELECT path || filename, size, isdir,\n" + " pg_tablespace_location(pg_tablespace.oid) AS link_target\n" + "FROM files\n" + "LEFT OUTER JOIN pg_tablespace ON files.path = 'pg_tblspc/'\n" + " AND oid::text = files.filename\n"; + res = PQexec(conn, sql); + + if (PQresultStatus(res) != PGRES_TUPLES_OK) + pg_fatal("could not fetch file list: %s", + PQresultErrorMessage(res)); + + /* sanity check the result set */ + if (PQnfields(res) != 4) + pg_fatal("unexpected result set while fetching file list"); + + /* Read result to local variables */ + for (i = 0; i < PQntuples(res); i++) + { + char *path; + int64 filesize; + bool isdir; + char *link_target; + file_type_t type; + + if (PQgetisnull(res, i, 1)) + { + /* + * The file was removed from the server while the query was + * running. Ignore it. + */ + continue; + } + + path = PQgetvalue(res, i, 0); + filesize = atol(PQgetvalue(res, i, 1)); + isdir = (strcmp(PQgetvalue(res, i, 2), "t") == 0); + link_target = PQgetvalue(res, i, 3); + + if (link_target[0]) + type = FILE_TYPE_SYMLINK; + else if (isdir) + type = FILE_TYPE_DIRECTORY; + else + type = FILE_TYPE_REGULAR; + + process_source_file(path, type, filesize, link_target); + } + PQclear(res); +} + +/* + * Queue up a request to fetch a piece of a file from remote system. + */ +static void +libpq_queue_fetch_range(rewind_source *source, const char *path, off_t off, + size_t len) +{ + libpq_source *src = (libpq_source *) source; + + /* + * Does this request happen to be a continuation of the previous chunk? If + * so, merge it with the previous one. + * + * XXX: We use pointer equality to compare the path. That's good enough + * for our purposes; the caller always passes the same pointer for the + * same filename. If it didn't, we would fail to merge requests, but it + * wouldn't affect correctness. + */ + if (src->num_requests > 0) + { + fetch_range_request *prev = &src->request_queue[src->num_requests - 1]; + + if (prev->offset + prev->length == off && + prev->length < MAX_CHUNK_SIZE && + prev->path == path) + { + /* + * Extend the previous request to cover as much of this new + * request as possible, without exceeding MAX_CHUNK_SIZE. + */ + size_t thislen; + + thislen = Min(len, MAX_CHUNK_SIZE - prev->length); + prev->length += thislen; + + off += thislen; + len -= thislen; + + /* + * Fall through to create new requests for any remaining 'len' + * that didn't fit in the previous chunk. + */ + } + } + + /* Divide the request into pieces of MAX_CHUNK_SIZE bytes each */ + while (len > 0) + { + int32 thislen; + + /* if the queue is full, perform all the work queued up so far */ + if (src->num_requests == MAX_CHUNKS_PER_QUERY) + process_queued_fetch_requests(src); + + thislen = Min(len, MAX_CHUNK_SIZE); + src->request_queue[src->num_requests].path = path; + src->request_queue[src->num_requests].offset = off; + src->request_queue[src->num_requests].length = thislen; + src->num_requests++; + + off += thislen; + len -= thislen; + } +} + +/* + * Fetch all the queued chunks and write them to the target data directory. + */ +static void +libpq_finish_fetch(rewind_source *source) +{ + process_queued_fetch_requests((libpq_source *) source); +} + +static void +process_queued_fetch_requests(libpq_source *src) +{ + const char *params[3]; + PGresult *res; + int chunkno; + + if (src->num_requests == 0) + return; + + pg_log_debug("getting %d file chunks", src->num_requests); + + /* + * The prepared statement, 'fetch_chunks_stmt', takes three arrays with + * the same length as parameters: paths, offsets and lengths. Construct + * the string representations of them. + */ + resetStringInfo(&src->paths); + resetStringInfo(&src->offsets); + resetStringInfo(&src->lengths); + + appendStringInfoChar(&src->paths, '{'); + appendStringInfoChar(&src->offsets, '{'); + appendStringInfoChar(&src->lengths, '{'); + for (int i = 0; i < src->num_requests; i++) + { + fetch_range_request *rq = &src->request_queue[i]; + + if (i > 0) + { + appendStringInfoChar(&src->paths, ','); + appendStringInfoChar(&src->offsets, ','); + appendStringInfoChar(&src->lengths, ','); + } + + appendArrayEscapedString(&src->paths, rq->path); + appendStringInfo(&src->offsets, INT64_FORMAT, (int64) rq->offset); + appendStringInfo(&src->lengths, INT64_FORMAT, (int64) rq->length); + } + appendStringInfoChar(&src->paths, '}'); + appendStringInfoChar(&src->offsets, '}'); + appendStringInfoChar(&src->lengths, '}'); + + /* + * Execute the prepared statement. + */ + params[0] = src->paths.data; + params[1] = src->offsets.data; + params[2] = src->lengths.data; + + if (PQsendQueryPrepared(src->conn, "fetch_chunks_stmt", 3, params, NULL, NULL, 1) != 1) + pg_fatal("could not send query: %s", PQerrorMessage(src->conn)); + + if (PQsetSingleRowMode(src->conn) != 1) + pg_fatal("could not set libpq connection to single row mode"); + + /*---- + * The result set is of format: + * + * path text -- path in the data directory, e.g "base/1/123" + * begin int8 -- offset within the file + * chunk bytea -- file content + *---- + */ + chunkno = 0; + while ((res = PQgetResult(src->conn)) != NULL) + { + fetch_range_request *rq = &src->request_queue[chunkno]; + char *filename; + int filenamelen; + int64 chunkoff; + int chunksize; + char *chunk; + + switch (PQresultStatus(res)) + { + case PGRES_SINGLE_TUPLE: + break; + + case PGRES_TUPLES_OK: + PQclear(res); + continue; /* final zero-row result */ + + default: + pg_fatal("unexpected result while fetching remote files: %s", + PQresultErrorMessage(res)); + } + + if (chunkno > src->num_requests) + pg_fatal("received more data chunks than requested"); + + /* sanity check the result set */ + if (PQnfields(res) != 3 || PQntuples(res) != 1) + pg_fatal("unexpected result set size while fetching remote files"); + + if (PQftype(res, 0) != TEXTOID || + PQftype(res, 1) != INT8OID || + PQftype(res, 2) != BYTEAOID) + { + pg_fatal("unexpected data types in result set while fetching remote files: %u %u %u", + PQftype(res, 0), PQftype(res, 1), PQftype(res, 2)); + } + + if (PQfformat(res, 0) != 1 && + PQfformat(res, 1) != 1 && + PQfformat(res, 2) != 1) + { + pg_fatal("unexpected result format while fetching remote files"); + } + + if (PQgetisnull(res, 0, 0) || + PQgetisnull(res, 0, 1)) + { + pg_fatal("unexpected null values in result while fetching remote files"); + } + + if (PQgetlength(res, 0, 1) != sizeof(int64)) + pg_fatal("unexpected result length while fetching remote files"); + + /* Read result set to local variables */ + memcpy(&chunkoff, PQgetvalue(res, 0, 1), sizeof(int64)); + chunkoff = pg_ntoh64(chunkoff); + chunksize = PQgetlength(res, 0, 2); + + filenamelen = PQgetlength(res, 0, 0); + filename = pg_malloc(filenamelen + 1); + memcpy(filename, PQgetvalue(res, 0, 0), filenamelen); + filename[filenamelen] = '\0'; + + chunk = PQgetvalue(res, 0, 2); + + /* + * If a file has been deleted on the source, remove it on the target + * as well. Note that multiple unlink() calls may happen on the same + * file if multiple data chunks are associated with it, hence ignore + * unconditionally anything missing. + */ + if (PQgetisnull(res, 0, 2)) + { + pg_log_debug("received null value for chunk for file \"%s\", file has been deleted", + filename); + remove_target_file(filename, true); + } + else + { + pg_log_debug("received chunk for file \"%s\", offset %lld, size %d", + filename, (long long int) chunkoff, chunksize); + + if (strcmp(filename, rq->path) != 0) + { + pg_fatal("received data for file \"%s\", when requested for \"%s\"", + filename, rq->path); + } + if (chunkoff != rq->offset) + pg_fatal("received data at offset %lld of file \"%s\", when requested for offset %lld", + (long long int) chunkoff, rq->path, (long long int) rq->offset); + + /* + * We should not receive more data than we requested, or + * pg_read_binary_file() messed up. We could receive less, + * though, if the file was truncated in the source after we + * checked its size. That's OK, there should be a WAL record of + * the truncation, which will get replayed when you start the + * target system for the first time after pg_rewind has completed. + */ + if (chunksize > rq->length) + pg_fatal("received more than requested for file \"%s\"", rq->path); + + open_target_file(filename, false); + + write_target_range(chunk, chunkoff, chunksize); + } + + pg_free(filename); + + PQclear(res); + chunkno++; + } + if (chunkno != src->num_requests) + pg_fatal("unexpected number of data chunks received"); + + src->num_requests = 0; +} + +/* + * Escape a string to be used as element in a text array constant + */ +static void +appendArrayEscapedString(StringInfo buf, const char *str) +{ + appendStringInfoCharMacro(buf, '\"'); + while (*str) + { + char ch = *str; + + if (ch == '"' || ch == '\\') + appendStringInfoCharMacro(buf, '\\'); + + appendStringInfoCharMacro(buf, ch); + + str++; + } + appendStringInfoCharMacro(buf, '\"'); +} + +/* + * Fetch a single file as a malloc'd buffer. + */ +static char * +libpq_fetch_file(rewind_source *source, const char *path, size_t *filesize) +{ + PGconn *conn = ((libpq_source *) source)->conn; + PGresult *res; + char *result; + int len; + const char *paramValues[1]; + + paramValues[0] = path; + res = PQexecParams(conn, "SELECT pg_read_binary_file($1)", + 1, NULL, paramValues, NULL, NULL, 1); + + if (PQresultStatus(res) != PGRES_TUPLES_OK) + pg_fatal("could not fetch remote file \"%s\": %s", + path, PQresultErrorMessage(res)); + + /* sanity check the result set */ + if (PQntuples(res) != 1 || PQgetisnull(res, 0, 0)) + pg_fatal("unexpected result set while fetching remote file \"%s\"", + path); + + /* Read result to local variables */ + len = PQgetlength(res, 0, 0); + result = pg_malloc(len + 1); + memcpy(result, PQgetvalue(res, 0, 0), len); + result[len] = '\0'; + + PQclear(res); + + pg_log_debug("fetched file \"%s\", length %d", path, len); + + if (filesize) + *filesize = len; + return result; +} + +/* + * Close a libpq source. + */ +static void +libpq_destroy(rewind_source *source) +{ + libpq_source *src = (libpq_source *) source; + + pfree(src->paths.data); + pfree(src->offsets.data); + pfree(src->lengths.data); + pfree(src); + + /* NOTE: we don't close the connection here, as it was not opened by us. */ +} diff --git a/src/bin/pg_rewind/local_source.c b/src/bin/pg_rewind/local_source.c new file mode 100644 index 000000000000..9c3491c3fba1 --- /dev/null +++ b/src/bin/pg_rewind/local_source.c @@ -0,0 +1,131 @@ +/*------------------------------------------------------------------------- + * + * local_source.c + * Functions for using a local data directory as the source. + * + * Portions Copyright (c) 2013-2021, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#include "postgres_fe.h" + +#include +#include + +#include "datapagemap.h" +#include "file_ops.h" +#include "filemap.h" +#include "pg_rewind.h" +#include "rewind_source.h" + +typedef struct +{ + rewind_source common; /* common interface functions */ + + const char *datadir; /* path to the source data directory */ +} local_source; + +static void local_traverse_files(rewind_source *source, + process_file_callback_t callback); +static char *local_fetch_file(rewind_source *source, const char *path, + size_t *filesize); +static void local_fetch_file_range(rewind_source *source, const char *path, + off_t off, size_t len); +static void local_finish_fetch(rewind_source *source); +static void local_destroy(rewind_source *source); + +rewind_source * +init_local_source(const char *datadir) +{ + local_source *src; + + src = pg_malloc0(sizeof(local_source)); + + src->common.traverse_files = local_traverse_files; + src->common.fetch_file = local_fetch_file; + src->common.queue_fetch_range = local_fetch_file_range; + src->common.finish_fetch = local_finish_fetch; + src->common.get_current_wal_insert_lsn = NULL; + src->common.destroy = local_destroy; + + src->datadir = datadir; + + return &src->common; +} + +static void +local_traverse_files(rewind_source *source, process_file_callback_t callback) +{ + traverse_datadir(((local_source *) source)->datadir, &process_source_file); +} + +static char * +local_fetch_file(rewind_source *source, const char *path, size_t *filesize) +{ + return slurpFile(((local_source *) source)->datadir, path, filesize); +} + +/* + * Copy a file from source to target, starting at 'off', for 'len' bytes. + */ +static void +local_fetch_file_range(rewind_source *source, const char *path, off_t off, + size_t len) +{ + const char *datadir = ((local_source *) source)->datadir; + PGAlignedBlock buf; + char srcpath[MAXPGPATH]; + int srcfd; + off_t begin = off; + off_t end = off + len; + + snprintf(srcpath, sizeof(srcpath), "%s/%s", datadir, path); + + srcfd = open(srcpath, O_RDONLY | PG_BINARY, 0); + if (srcfd < 0) + pg_fatal("could not open source file \"%s\": %m", + srcpath); + + if (lseek(srcfd, begin, SEEK_SET) == -1) + pg_fatal("could not seek in source file: %m"); + + open_target_file(path, false); + + while (end - begin > 0) + { + ssize_t readlen; + size_t len; + + if (end - begin > sizeof(buf)) + len = sizeof(buf); + else + len = end - begin; + + readlen = read(srcfd, buf.data, len); + + if (readlen < 0) + pg_fatal("could not read file \"%s\": %m", srcpath); + else if (readlen == 0) + pg_fatal("unexpected EOF while reading file \"%s\"", srcpath); + + write_target_range(buf.data, begin, readlen); + begin += readlen; + } + + if (close(srcfd) != 0) + pg_fatal("could not close file \"%s\": %m", srcpath); +} + +static void +local_finish_fetch(rewind_source *source) +{ + /* + * Nothing to do, local_fetch_file_range() copies the ranges immediately. + */ +} + +static void +local_destroy(rewind_source *source) +{ + pfree(source); +} diff --git a/src/bin/pg_rewind/nls.mk b/src/bin/pg_rewind/nls.mk index 732d2bc23233..a561f965df7c 100644 --- a/src/bin/pg_rewind/nls.mk +++ b/src/bin/pg_rewind/nls.mk @@ -1,7 +1,7 @@ # src/bin/pg_rewind/nls.mk CATALOG_NAME = pg_rewind -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr zh_CN -GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) copy_fetch.c datapagemap.c fetch.c file_ops.c filemap.c libpq_fetch.c parsexlog.c pg_rewind.c timeline.c xlogreader.c ../../common/fe_memutils.c ../../common/restricted_token.c ../../fe_utils/archive.c ../../fe_utils/recovery_gen.c +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr uk zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) datapagemap.c file_ops.c filemap.c libpq_source.c local_source.c parsexlog.c pg_rewind.c timeline.c xlogreader.c ../../common/fe_memutils.c ../../common/restricted_token.c ../../fe_utils/archive.c ../../fe_utils/recovery_gen.c GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) pg_fatal report_invalid_record:2 GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) \ pg_fatal:1:c-format \ diff --git a/src/bin/pg_rewind/parsexlog.c b/src/bin/pg_rewind/parsexlog.c index 1549cda6601e..0ae2b20bc371 100644 --- a/src/bin/pg_rewind/parsexlog.c +++ b/src/bin/pg_rewind/parsexlog.c @@ -3,7 +3,7 @@ * parsexlog.c * Functions for reading Write-Ahead-Log * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- @@ -58,6 +58,9 @@ static int SimpleXLogPageRead(XLogReaderState *xlogreader, * Read WAL from the datadir/pg_wal, starting from 'startpoint' on timeline * index 'tliIndex' in target timeline history, until 'endpoint'. Make note of * the data blocks touched by the WAL records, and return them in a page map. + * + * 'endpoint' is the end of the last record to read. The record starting at + * 'endpoint' is the first one that is not read. */ void extractPageMap(const char *datadir, XLogRecPtr startpoint, int tliIndex, @@ -87,16 +90,22 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, int tliIndex, if (errormsg) pg_fatal("could not read WAL record at %X/%X: %s", - (uint32) (errptr >> 32), (uint32) (errptr), + LSN_FORMAT_ARGS(errptr), errormsg); else pg_fatal("could not read WAL record at %X/%X", - (uint32) (errptr >> 32), (uint32) (errptr)); + LSN_FORMAT_ARGS(errptr)); } extractPageInfo(xlogreader); - } while (xlogreader->ReadRecPtr != endpoint); + } while (xlogreader->EndRecPtr < endpoint); + + /* + * If 'endpoint' didn't point exactly at a record boundary, the caller + * messed up. + */ + Assert(xlogreader->EndRecPtr == endpoint); XLogReaderFree(xlogreader); if (xlogreadfd != -1) @@ -134,10 +143,10 @@ readOneRecord(const char *datadir, XLogRecPtr ptr, int tliIndex, { if (errormsg) pg_fatal("could not read WAL record at %X/%X: %s", - (uint32) (ptr >> 32), (uint32) (ptr), errormsg); + LSN_FORMAT_ARGS(ptr), errormsg); else pg_fatal("could not read WAL record at %X/%X", - (uint32) (ptr >> 32), (uint32) (ptr)); + LSN_FORMAT_ARGS(ptr)); } endptr = xlogreader->EndRecPtr; @@ -200,17 +209,17 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex, { if (errormsg) pg_fatal("could not find previous WAL record at %X/%X: %s", - (uint32) (searchptr >> 32), (uint32) (searchptr), + LSN_FORMAT_ARGS(searchptr), errormsg); else pg_fatal("could not find previous WAL record at %X/%X", - (uint32) (searchptr >> 32), (uint32) (searchptr)); + LSN_FORMAT_ARGS(searchptr)); } /* * Check if it is a checkpoint record. This checkpoint record needs to * be the latest checkpoint before WAL forked and not the checkpoint - * where the primary has been stopped to be rewinded. + * where the primary has been stopped to be rewound. */ info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK; if (searchptr < forkptr && @@ -422,7 +431,7 @@ extractPageInfo(XLogReaderState *record) */ pg_fatal("WAL record modifies a relation, but record type is not recognized: " "lsn: %X/%X, rmgr: %s, info: %02X", - (uint32) (record->ReadRecPtr >> 32), (uint32) (record->ReadRecPtr), + LSN_FORMAT_ARGS(record->ReadRecPtr), RmgrNames[rmid], info); } else if (rmid == RM_APPEND_ONLY_ID) diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c index 8af5968a56d2..e411bc4f08f9 100644 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@ -3,11 +3,12 @@ * pg_rewind.c * Synchronizes a PostgreSQL data directory to a new timeline * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ #include "postgres_fe.h" + #include #include #include @@ -19,37 +20,39 @@ #include "catalog/pg_control.h" #include "common/controldata_utils.h" #include "common/file_perm.h" -#include "common/file_utils.h" #include "common/restricted_token.h" #include "common/string.h" #include "fe_utils/recovery_gen.h" -#include "fetch.h" #include "file_ops.h" #include "filemap.h" #include "getopt_long.h" +#include "miscadmin.h" #include "pg_rewind.h" +#include "rewind_source.h" #include "storage/bufpage.h" -#include "utils/palloc.h" static void usage(const char *progname); +static void perform_rewind(filemap_t *filemap, rewind_source *source, + XLogRecPtr chkptrec, + TimeLineID chkpttli, + XLogRecPtr chkptredo); + static void createBackupLabel(XLogRecPtr startpoint, TimeLineID starttli, XLogRecPtr checkpointloc); -static void digestControlFile(ControlFileData *ControlFile, char *source, - size_t size); -static void syncTargetDirectory(void); +static void digestControlFile(ControlFileData *ControlFile, + const char *content, size_t size); static void getRestoreCommand(const char *argv0); static void sanityChecks(void); static void findCommonAncestorTimeline(XLogRecPtr *recptr, int *tliIndex); static void ensureCleanShutdown(const char *argv0); static void disconnect_atexit(void); -static int32 get_target_dbid(const char *argv0); static ControlFileData ControlFile_target; static ControlFileData ControlFile_source; +static ControlFileData ControlFile_source_after; -int32 dbid_target; const char *progname; int WalSegSz; @@ -73,6 +76,8 @@ int targetNentries; uint64 fetch_size; uint64 fetch_done; +static PGconn *conn; +static rewind_source *source; static void usage(const char *progname) @@ -91,7 +96,8 @@ usage(const char *progname) printf(_(" -P, --progress write progress messages\n")); printf(_(" -R, --write-recovery-conf write configuration for replication\n" " (requires --source-server)\n")); - printf(_(" -S, --slot=SLOTNAME replication slot to use\n")); + printf(_(" -S, --slot=SLOTNAME set primary_slot_name when writing the\n" + " replication configuration\n")); printf(_(" --debug write a lot of debug messages\n")); printf(_(" --no-ensure-shutdown do not automatically fix unclean shutdown\n")); printf(_(" -V, --version output version information, then exit\n")); @@ -127,15 +133,14 @@ main(int argc, char **argv) XLogRecPtr chkptrec; TimeLineID chkpttli; XLogRecPtr chkptredo; + XLogRecPtr target_wal_endrec; size_t size; char *buffer; bool no_ensure_shutdown = false; bool rewind_needed; - XLogRecPtr endrec; - TimeLineID endtli; - ControlFileData ControlFile_new; bool writerecoveryconf = false; - char *replication_slot = NULL; + char *replication_slot = NULL; + filemap_t *filemap; pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_rewind")); @@ -151,7 +156,7 @@ main(int argc, char **argv) } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { - puts("pg_rewind (Greenplum Database) " PG_VERSION); + puts("pg_rewind (PostgreSQL) " PG_VERSION); exit(0); } } @@ -176,10 +181,6 @@ main(int argc, char **argv) dry_run = true; break; - case 'S': - replication_slot = pg_strdup(optarg); - break; - case 'N': do_sync = false; break; @@ -188,9 +189,13 @@ main(int argc, char **argv) writerecoveryconf = true; break; + case 'S': /* GPDB: slot for primary_slot_name in -R output */ + replication_slot = pg_strdup(optarg); + break; + case 3: debug = true; - pg_logging_set_level(PG_LOG_DEBUG); + pg_logging_increase_verbosity(); break; case 'D': /* -D or --target-pgdata */ @@ -225,13 +230,6 @@ main(int argc, char **argv) exit(1); } - if (datadir_source != NULL && connstr_source != NULL) - { - fprintf(stderr, _("%s: only one of --source-pgdata or --source-server can be specified\n"), progname); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); - } - if (datadir_target == NULL) { pg_log_error("no target data directory specified (--target-pgdata)"); @@ -246,17 +244,17 @@ main(int argc, char **argv) exit(1); } - if (optind < argc) + if (replication_slot != NULL && !writerecoveryconf) { - pg_log_error("too many command-line arguments (first is \"%s\")", - argv[optind]); + pg_log_error("--slot can be specified only with --write-recovery-conf"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } - if (!writerecoveryconf && replication_slot != NULL) + if (optind < argc) { - fprintf(stderr, _("%s: --slot can be specified only if --write-recovery-conf is specified\n"), progname); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -293,19 +291,28 @@ main(int argc, char **argv) atexit(disconnect_atexit); - /* Connect to remote server */ - if (connstr_source) - libpqConnect(connstr_source); - /* - * Ok, we have all the options and we're ready to start. Read in all the - * information we need from both clusters. + * Ok, we have all the options and we're ready to start. First, connect to + * remote server. */ - buffer = slurpFile(datadir_target, "global/pg_control", &size); - digestControlFile(&ControlFile_target, buffer, size); - pg_free(buffer); + if (connstr_source) + { + conn = PQconnectdb(connstr_source); + + if (PQstatus(conn) == CONNECTION_BAD) + pg_fatal("%s", PQerrorMessage(conn)); + + if (showprogress) + pg_log_info("connected to server"); + + source = init_libpq_source(conn); + } + else + source = init_local_source(datadir_source); /* + * Check the status of the target instance. + * * If the target instance was not cleanly shut down, start and stop the * target cluster once in single-user mode to enforce recovery to finish, * ensuring that the cluster can be used by pg_rewind. Note that if @@ -313,6 +320,10 @@ main(int argc, char **argv) * need to make sure by themselves that the target cluster is in a clean * state. */ + buffer = slurpFile(datadir_target, "global/pg_control", &size); + digestControlFile(&ControlFile_target, buffer, size); + pg_free(buffer); + if (!no_ensure_shutdown && ControlFile_target.state != DB_SHUTDOWNED && ControlFile_target.state != DB_SHUTDOWNED_IN_RECOVERY) @@ -324,60 +335,73 @@ main(int argc, char **argv) pg_free(buffer); } - buffer = fetchFile("global/pg_control", &size); + buffer = source->fetch_file(source, "global/pg_control", &size); digestControlFile(&ControlFile_source, buffer, size); pg_free(buffer); - dbid_target = get_target_dbid(argv[0]); - sanityChecks(); /* + * Find the common ancestor timeline between the clusters. + * * If both clusters are already on the same timeline, there's nothing to * do. */ - if (ControlFile_target.checkPointCopy.ThisTimeLineID == ControlFile_source.checkPointCopy.ThisTimeLineID) + if (ControlFile_target.checkPointCopy.ThisTimeLineID == + ControlFile_source.checkPointCopy.ThisTimeLineID) { - pg_log_info("source and target cluster are on the same timeline: %u", - ControlFile_source.checkPointCopy.ThisTimeLineID); + pg_log_info("source and target cluster are on the same timeline"); rewind_needed = false; + target_wal_endrec = 0; } else { + XLogRecPtr chkptendrec; + findCommonAncestorTimeline(&divergerec, &lastcommontliIndex); pg_log_info("servers diverged at WAL location %X/%X on timeline %u", - (uint32) (divergerec >> 32), (uint32) divergerec, + LSN_FORMAT_ARGS(divergerec), targetHistory[lastcommontliIndex].tli); + /* + * Determine the end-of-WAL on the target. + * + * The WAL ends at the last shutdown checkpoint, or at + * minRecoveryPoint if it was a standby. (If we supported rewinding a + * server that was not shut down cleanly, we would need to replay + * until we reach the first invalid record, like crash recovery does.) + */ + + /* read the checkpoint record on the target to see where it ends. */ + chkptendrec = readOneRecord(datadir_target, + ControlFile_target.checkPoint, + targetNentries - 1, + restore_command); + + if (ControlFile_target.minRecoveryPoint > chkptendrec) + { + target_wal_endrec = ControlFile_target.minRecoveryPoint; + } + else + { + target_wal_endrec = chkptendrec; + } + /* * Check for the possibility that the target is in fact a direct * ancestor of the source. In that case, there is no divergent history * in the target that needs rewinding. */ - if (ControlFile_target.checkPoint >= divergerec) + if (target_wal_endrec > divergerec) { rewind_needed = true; } else { - XLogRecPtr chkptendrec; - - /* Read the checkpoint record on the target to see where it ends. */ - chkptendrec = readOneRecord(datadir_target, - ControlFile_target.checkPoint, - targetNentries - 1, - restore_command); + /* the last common checkpoint record must be part of target WAL */ + Assert(target_wal_endrec == divergerec); - /* - * If the histories diverged exactly at the end of the shutdown - * checkpoint record on the target, there are no WAL records in - * the target that don't belong in the source's history, and no - * rewind is needed. - */ - if (chkptendrec == divergerec) - rewind_needed = false; - else - rewind_needed = true; + rewind_needed = false; } } @@ -393,16 +417,18 @@ main(int argc, char **argv) findLastCheckpoint(datadir_target, divergerec, lastcommontliIndex, &chkptrec, &chkpttli, &chkptredo, restore_command); pg_log_info("rewinding from last common checkpoint at %X/%X on timeline %u", - (uint32) (chkptrec >> 32), (uint32) chkptrec, - chkpttli); + LSN_FORMAT_ARGS(chkptrec), chkpttli); + + /* Initialize the hash table to track the status of each file */ + filehash_init(); /* - * Collect information about all files in the target and source systems. + * Collect information about all files in the both data directories. */ - filemap_create(); if (showprogress) pg_log_info("reading source file list"); - fetchSourceFileList(); + source->traverse_files(source, &process_source_file); + if (showprogress) pg_log_info("reading target file list"); traverse_datadir(datadir_target, &process_target_file); @@ -410,26 +436,24 @@ main(int argc, char **argv) /* * Read the target WAL from last checkpoint before the point of fork, to * extract all the pages that were modified on the target cluster after - * the fork. We can stop reading after reaching the final shutdown record. - * XXX: If we supported rewinding a server that was not shut down cleanly, - * we would need to replay until the end of WAL here. + * the fork. */ if (showprogress) pg_log_info("reading WAL in target"); extractPageMap(datadir_target, chkptrec, lastcommontliIndex, - ControlFile_target.checkPoint, restore_command); + target_wal_endrec, restore_command); /* * We have collected all information we need from both systems. Decide * what to do with each file. */ - decide_file_actions(); + filemap = decide_file_actions(); if (showprogress) - calculate_totals(); + calculate_totals(filemap); /* this is too verbose even for verbose mode */ if (debug) - print_filemap(); + print_filemap(filemap); /* * Ok, we're ready to start copying things over. @@ -445,59 +469,222 @@ main(int argc, char **argv) } /* - * This is the point of no return. Once we start copying things, we have - * modified the target directory and there is no turning back! + * We have now collected all the information we need from both systems, + * and we are ready to start modifying the target directory. + * + * This is the point of no return. Once we start copying things, there is + * no turning back! + */ + perform_rewind(filemap, source, chkptrec, chkpttli, chkptredo); + + if (showprogress) + pg_log_info("syncing target data directory"); + sync_target_dir(); + + /* Also update the standby configuration, if requested. */ + if (writerecoveryconf && !dry_run) + WriteRecoveryConfig(conn, datadir_target, + GenerateRecoveryConfig(conn, replication_slot)); + + /* don't need the source connection anymore */ + source->destroy(source); + if (conn) + { + PQfinish(conn); + conn = NULL; + } + + pg_log_info("Done!"); + + return 0; +} + +/* + * Perform the rewind. + * + * We have already collected all the information we need from the + * target and the source. + */ +static void +perform_rewind(filemap_t *filemap, rewind_source *source, + XLogRecPtr chkptrec, + TimeLineID chkpttli, + XLogRecPtr chkptredo) +{ + XLogRecPtr endrec; + TimeLineID endtli; + ControlFileData ControlFile_new; + size_t size; + char *buffer; + + /* + * Execute the actions in the file map, fetching data from the source + * system as needed. */ + for (int i = 0; i < filemap->nentries; i++) + { + file_entry_t *entry = filemap->entries[i]; - executeFileMap(); + /* + * If this is a relation file, copy the modified blocks. + * + * This is in addition to any other changes. + */ + if (entry->target_pages_to_overwrite.bitmapsize > 0) + { + datapagemap_iterator_t *iter; + BlockNumber blkno; + off_t offset; + + iter = datapagemap_iterate(&entry->target_pages_to_overwrite); + while (datapagemap_next(iter, &blkno)) + { + offset = blkno * BLCKSZ; + source->queue_fetch_range(source, entry->path, offset, BLCKSZ); + } + pg_free(iter); + } + + switch (entry->action) + { + case FILE_ACTION_NONE: + /* nothing else to do */ + break; + + case FILE_ACTION_COPY: + /* Truncate the old file out of the way, if any */ + open_target_file(entry->path, true); + source->queue_fetch_range(source, entry->path, + 0, entry->source_size); + break; + + case FILE_ACTION_TRUNCATE: + truncate_target_file(entry->path, entry->source_size); + break; + + case FILE_ACTION_COPY_TAIL: + source->queue_fetch_range(source, entry->path, + entry->target_size, + entry->source_size - entry->target_size); + break; + + case FILE_ACTION_REMOVE: + remove_target(entry); + break; + + case FILE_ACTION_CREATE: + create_target(entry); + break; + + case FILE_ACTION_UNDECIDED: + pg_fatal("no action decided for file \"%s\"", entry->path); + break; + } + } + + /* Complete any remaining range-fetches that we queued up above. */ + source->finish_fetch(source); + + close_target_file(); progress_report(true); + /* + * Fetch the control file from the source last. This ensures that the + * minRecoveryPoint is up-to-date. + */ + buffer = source->fetch_file(source, "global/pg_control", &size); + digestControlFile(&ControlFile_source_after, buffer, size); + pg_free(buffer); + + /* + * Sanity check: If the source is a local system, the control file should + * not have changed since we started. + * + * XXX: We assume it hasn't been modified, but actually, what could go + * wrong? The logic handles a libpq source that's modified concurrently, + * why not a local datadir? + */ + if (datadir_source && + memcmp(&ControlFile_source, &ControlFile_source_after, + sizeof(ControlFileData)) != 0) + { + pg_fatal("source system was modified while pg_rewind was running"); + } + if (showprogress) pg_log_info("creating backup label and updating control file"); - createBackupLabel(chkptredo, chkpttli, chkptrec); /* - * Update control file of target. Make it ready to perform archive - * recovery when restarting. + * Create a backup label file, to tell the target where to begin the WAL + * replay. Normally, from the last common checkpoint between the source + * and the target. But if the source is a standby server, it's possible + * that the last common checkpoint is *after* the standby's restartpoint. + * That implies that the source server has applied the checkpoint record, + * but hasn't performed a corresponding restartpoint yet. Make sure we + * start at the restartpoint's redo point in that case. * - * minRecoveryPoint is set to the current WAL insert location in the - * source server. Like in an online backup, it's important that we recover - * all the WAL that was generated while we copied the files over. + * Use the old version of the source's control file for this. The server + * might have finished the restartpoint after we started copying files, + * but we must begin from the redo point at the time that started copying. */ - memcpy(&ControlFile_new, &ControlFile_source, sizeof(ControlFileData)); + if (ControlFile_source.checkPointCopy.redo < chkptredo) + { + chkptredo = ControlFile_source.checkPointCopy.redo; + chkpttli = ControlFile_source.checkPointCopy.ThisTimeLineID; + chkptrec = ControlFile_source.checkPoint; + } + createBackupLabel(chkptredo, chkpttli, chkptrec); + /* + * Update control file of target, to tell the target how far it must + * replay the WAL (minRecoveryPoint). + */ if (connstr_source) { - endrec = libpqGetCurrentXlogInsertLocation(); - endtli = ControlFile_source.checkPointCopy.ThisTimeLineID; + /* + * The source is a live server. Like in an online backup, it's + * important that we recover all the WAL that was generated while we + * were copying files. + */ + if (ControlFile_source_after.state == DB_IN_ARCHIVE_RECOVERY) + { + /* + * Source is a standby server. We must replay to its + * minRecoveryPoint. + */ + endrec = ControlFile_source_after.minRecoveryPoint; + endtli = ControlFile_source_after.minRecoveryPointTLI; + } + else + { + /* + * Source is a production, non-standby, server. We must replay to + * the last WAL insert location. + */ + if (ControlFile_source_after.state != DB_IN_PRODUCTION) + pg_fatal("source system was in unexpected state at end of rewind"); + + endrec = source->get_current_wal_insert_lsn(source); + endtli = ControlFile_source_after.checkPointCopy.ThisTimeLineID; + } } else { - endrec = ControlFile_source.checkPoint; - endtli = ControlFile_source.checkPointCopy.ThisTimeLineID; + /* + * Source is a local data directory. It should've shut down cleanly, + * and we must replay to the latest shutdown checkpoint. + */ + endrec = ControlFile_source_after.checkPoint; + endtli = ControlFile_source_after.checkPointCopy.ThisTimeLineID; } + + memcpy(&ControlFile_new, &ControlFile_source_after, sizeof(ControlFileData)); ControlFile_new.minRecoveryPoint = endrec; ControlFile_new.minRecoveryPointTLI = endtli; ControlFile_new.state = DB_IN_ARCHIVE_RECOVERY; if (!dry_run) update_controlfile(datadir_target, &ControlFile_new, do_sync); - - if (writerecoveryconf) - WriteRecoveryConfig(conn, datadir_target, - GenerateRecoveryConfig(conn, replication_slot)); - - if (showprogress) - pg_log_info("syncing target data directory"); - syncTargetDirectory(); - - if (writerecoveryconf && !dry_run) - WriteRecoveryConfig(conn, datadir_target, - GenerateRecoveryConfig(conn, NULL)); - - pg_log_info("Done!"); - - return 0; } static void @@ -657,7 +844,7 @@ getTimelineHistory(ControlFileData *controlFile, int *nentries) /* Get history file from appropriate source */ if (controlFile == &ControlFile_source) - histfile = fetchFile(path, NULL); + histfile = source->fetch_file(source, path, NULL); else if (controlFile == &ControlFile_target) histfile = slurpFile(datadir_target, path, NULL); else @@ -686,9 +873,9 @@ getTimelineHistory(ControlFileData *controlFile, int *nentries) TimeLineHistoryEntry *entry; entry = &history[i]; - pg_log_debug("%d: %X/%X - %X/%X", entry->tli, - (uint32) (entry->begin >> 32), (uint32) (entry->begin), - (uint32) (entry->end >> 32), (uint32) (entry->end)); + pg_log_debug("%u: %X/%X - %X/%X", entry->tli, + LSN_FORMAT_ARGS(entry->begin), + LSN_FORMAT_ARGS(entry->end)); } } @@ -782,8 +969,8 @@ createBackupLabel(XLogRecPtr startpoint, TimeLineID starttli, XLogRecPtr checkpo "BACKUP FROM: standby\n" "START TIME: %s\n", /* omit LABEL: line */ - (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename, - (uint32) (checkpointloc >> 32), (uint32) checkpointloc, + LSN_FORMAT_ARGS(startpoint), xlogfilename, + LSN_FORMAT_ARGS(checkpointloc), strfbuf); if (len >= sizeof(buf)) pg_fatal("backup label buffer too small"); /* shouldn't happen */ @@ -813,16 +1000,18 @@ checkControlFile(ControlFileData *ControlFile) } /* - * Verify control file contents in the buffer src, and copy it to *ControlFile. + * Verify control file contents in the buffer 'content', and copy it to + * *ControlFile. */ static void -digestControlFile(ControlFileData *ControlFile, char *src, size_t size) +digestControlFile(ControlFileData *ControlFile, const char *content, + size_t size) { if (size != PG_CONTROL_FILE_SIZE) pg_fatal("unexpected control file size %d, expected %d", (int) size, PG_CONTROL_FILE_SIZE); - memcpy(ControlFile, src, sizeof(ControlFileData)); + memcpy(ControlFile, content, sizeof(ControlFileData)); /* set and validate WalSegSz */ WalSegSz = ControlFile->xlog_seg_size; @@ -837,141 +1026,6 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size) checkControlFile(ControlFile); } -/* - * Sync target data directory to ensure that modifications are safely on disk. - * - * We do this once, for the whole data directory, for performance reasons. At - * the end of pg_rewind's run, the kernel is likely to already have flushed - * most dirty buffers to disk. Additionally fsync_pgdata uses a two-pass - * approach (only initiating writeback in the first pass), which often reduces - * the overall amount of IO noticeably. - * - * gpdb: We assume that all files are synchronized before rewinding and thus we - * just need to synchronize those affected files. This is a resonable - * assumption for gpdb since we've ensured that the db state is clean shutdown - * in pg_rewind by running single mode postgres if needed and also we do not - * copy an unsynchronized dababase without sync as the target base. - */ -static void -syncTargetDirectory(void) -{ - if (!do_sync || dry_run) - return; - - file_entry_t *entry; - int i; - - if (chdir(datadir_target) < 0) - { - pg_log_error("could not change directory to \"%s\": %m", datadir_target); - exit(1); - } - - for (i = 0; i < filemap->narray; i++) - { - entry = filemap->array[i]; - - if (entry->target_pages_to_overwrite.bitmapsize > 0) - fsync_fname(entry->path, false); - else - { - switch (entry->action) - { - case FILE_ACTION_COPY: - case FILE_ACTION_TRUNCATE: - case FILE_ACTION_COPY_TAIL: - fsync_fname(entry->path, false); - break; - - case FILE_ACTION_CREATE: - fsync_fname(entry->path, - entry->source_type == FILE_TYPE_DIRECTORY); - /* FALLTHROUGH */ - case FILE_ACTION_REMOVE: - /* - * Fsync the parent directory if we either create or delete - * files/directories in the parent directory. The parent - * directory might be missing as expected, so fsync it could - * fail but we ignore that error. - */ - fsync_parent_path(entry->path); - break; - - case FILE_ACTION_NONE: - break; - - default: - pg_fatal("no action decided for \"%s\"", entry->path); - break; - } - } - } - - /* fsync some files that are (possibly) written by pg_rewind. */ - fsync_fname("global/pg_control", false); - fsync_fname("backup_label", false); - fsync_fname("postgresql.auto.conf", false); - fsync_fname(".", true); /* due to new file backup_label. */ -} - -static int32 -get_target_dbid(const char *argv0) -{ - char cmd_output[1024]; - FILE *output; - int32 dbid; - - int ret; -#define MAXCMDLEN (2 * MAXPGPATH) - char exec_path[MAXPGPATH]; - char cmd[MAXCMDLEN]; - long parsed_dbid; - - /* locate postgres binary */ - if ((ret = find_other_exec(argv0, "postgres", - "postgres (Greenplum Database) " PG_VERSION "\n", - exec_path)) < 0) - { - char full_path[MAXPGPATH]; - - if (find_my_exec(argv0, full_path) < 0) - strlcpy(full_path, progname, sizeof(full_path)); - - if (ret == -1) - pg_fatal("The program \"postgres\" is needed by %s but was \n" - "not found in the same directory as \"%s\".\n" - "Check your installation.\n", progname, full_path); - else - pg_fatal("The program \"postgres\" was found by \"%s\"\n" - "but was not the same version as %s.\n" - "Check your installation.\n", full_path, progname); - } - - snprintf(cmd, MAXCMDLEN, "\"%s\" -D \"%s\" -C gp_dbid", - exec_path, datadir_target); - - if ((output = popen(cmd, "r")) == NULL || - fgets(cmd_output, sizeof(cmd_output), output) == NULL) - pg_fatal("Could not get dbid using %s: %m\n", - cmd); - - pclose(output); - - /* Remove trailing newline */ - if (strchr(cmd_output, '\n') != NULL) - *strchr(cmd_output, '\n') = '\0'; - - errno = 0; - parsed_dbid = strtol(cmd_output, NULL, 10); - if (errno) - pg_fatal("could not parse valid dbid from %s\n with cmd_output %s\n", cmd, cmd_output); - if(parsed_dbid > INT16_MAX || parsed_dbid <= -1) - pg_fatal("parsed dbid (%ld) is out of valid range: [1, INT16_MAX]", parsed_dbid); - dbid = (int32) parsed_dbid; - - return dbid; -} - /* * Get value of GUC parameter restore_command from the target cluster. * @@ -1085,19 +1139,18 @@ ensureCleanShutdown(const char *argv0) * Finally run postgres in single-user mode. There is no need to use * fsync here. This makes the recovery faster, and the target data folder * is synced at the end anyway. - */ - /* - * gpdb: use postgres instead of template1, else the below postgres - * instance might hang in the below scenario: * - * 1. There was a prepared but not finished "create database " dtx + * gpdb: use DB_FOR_COMMON_ACCESS (postgres) instead of template1, else + * the postgres instance might hang in the below scenario: + * + * 1. There was a prepared but not finished "create database" dtx * transaction which was recovered during crash recovery in the startup * process and thus it holds the lock of database template1 since * by default template1 is the template for database creation. * - * 2. Single mode postgres process will execute the below code in - * InitPostgres() after finishing crash recovery (i.e. calling - * startupXLOG()) and then hang due to lock conflict. + * 2. The single mode postgres process will execute the below code in + * InitPostgres() after finishing crash recovery (i.e. calling + * StartupXLOG()) and then hang due to lock conflict. * * LockSharedObject(DatabaseRelationId, ...); * @@ -1106,7 +1159,7 @@ ensureCleanShutdown(const char *argv0) * since the commands (e.g. create database with template * DB_FOR_COMMON_ACCESS) would fail. */ - snprintf(cmd, MAXCMDLEN, "\"%s\" --single -D \"%s\" %s < %s", + snprintf(cmd, MAXCMDLEN, "\"%s\" --single -F -D \"%s\" %s < \"%s\"", exec_path, datadir_target, DB_FOR_COMMON_ACCESS, DEVNULL); if (system(cmd) != 0) diff --git a/src/bin/pg_rewind/pg_rewind.h b/src/bin/pg_rewind/pg_rewind.h index 8c443f0ebcef..e819db4a876b 100644 --- a/src/bin/pg_rewind/pg_rewind.h +++ b/src/bin/pg_rewind/pg_rewind.h @@ -3,7 +3,7 @@ * pg_rewind.h * * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- @@ -20,10 +20,9 @@ /* Configuration options */ extern char *datadir_target; -extern char *datadir_source; -extern char *connstr_source; extern bool showprogress; extern bool dry_run; +extern bool do_sync; extern int WalSegSz; extern int32 dbid_target; @@ -34,9 +33,6 @@ extern const char *progname; extern TimeLineHistoryEntry *targetHistory; extern int targetNentries; -/* general state */ -extern PGconn *conn; - /* Progress counters */ extern uint64 fetch_size; extern uint64 fetch_done; diff --git a/src/bin/pg_rewind/po/cs.po b/src/bin/pg_rewind/po/cs.po index 1f1db7d52488..1f4a8ebce199 100644 --- a/src/bin/pg_rewind/po/cs.po +++ b/src/bin/pg_rewind/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-27 08:15+0000\n" -"PO-Revision-Date: 2019-09-27 20:08+0200\n" +"POT-Creation-Date: 2020-10-31 16:16+0000\n" +"PO-Revision-Date: 2020-10-31 21:24+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: cs\n" @@ -16,82 +16,133 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 2.4.1\n" "X-Poedit-Bookmarks: -1,-1,-1,-1,-1,-1,-1,-1,-1,17\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "fatal: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format -#| msgid "SQL error: %s\n" msgid "error: " msgstr "error: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format -#| msgid "warning" msgid "warning: " msgstr "warning: " #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 #, c-format msgid "out of memory\n" msgstr "nedostatek paměti\n" -#: ../../common/fe_memutils.c:92 +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "nelze duplikovat null pointer (interní chyba)\n" -#: ../../common/restricted_token.c:69 +#: ../../common/restricted_token.c:64 #, c-format -msgid "cannot create restricted tokens on this platform" -msgstr "na této platformě nelze vytvářet vyhrazené tokeny" +msgid "could not load library \"%s\": error code %lu" +msgstr "nelze načíst knihovnu \"%s\": kód chyby %lu" -#: ../../common/restricted_token.c:78 +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "na této platformě nelze vytvářet vyhrazené tokeny: kód chyby %lu" + +#: ../../common/restricted_token.c:82 #, c-format msgid "could not open process token: error code %lu" msgstr "nelze otevřít token procesu: chybový kód %lu" -#: ../../common/restricted_token.c:91 +#: ../../common/restricted_token.c:97 #, c-format msgid "could not allocate SIDs: error code %lu" msgstr "nelze alokovat SIDs: chybový kód %lu" -#: ../../common/restricted_token.c:110 +#: ../../common/restricted_token.c:119 #, c-format msgid "could not create restricted token: error code %lu" msgstr "nelze vytvořit vyhrazený token: chybový kód %lu" -#: ../../common/restricted_token.c:131 +#: ../../common/restricted_token.c:140 #, c-format msgid "could not start process for command \"%s\": error code %lu" msgstr "nelze nastartovat proces pro příkaz \"%s\": chybový kód %lu" -#: ../../common/restricted_token.c:169 +#: ../../common/restricted_token.c:178 #, c-format msgid "could not re-execute with restricted token: error code %lu" msgstr "nelze znovu spustit s vyhrazeným tokenem: chybový kód %lu" -#: ../../common/restricted_token.c:185 +#: ../../common/restricted_token.c:194 #, c-format msgid "could not get exit code from subprocess: error code %lu" msgstr "nelze získat návratový kód z podprovesu: chybový kód %lu" -#: copy_fetch.c:59 +#: ../../fe_utils/archive.c:53 #, c-format -msgid "could not open directory \"%s\": %m" -msgstr "nelze otevřít adresář \"%s\": %m" +msgid "cannot use restore_command with %%r placeholder" +msgstr "nelze použít restore_command se zástupnou hodnotou %%r" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lu instead of %lu" +msgstr "neočekávaná velikost souboru \"%s\": %lu namísto %lu" -#: copy_fetch.c:88 filemap.c:187 filemap.c:348 +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "nelze otevřít soubor \"%s\" obnovený z archivu: %m" + +#: ../../fe_utils/archive.c:97 copy_fetch.c:88 filemap.c:208 #, c-format msgid "could not stat file \"%s\": %m" msgstr "nelze přistoupit k souboru \"%s\": %m" +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed: %s" +msgstr "restore_command selhal: %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "nelze obnovit soubor\"%s\" z archivu" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:73 parsexlog.c:125 +#: parsexlog.c:185 +#, c-format +msgid "out of memory" +msgstr "nedostatek paměti" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:298 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "nelze otevřít soubor \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "nelze zapsat do souboru \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "nelze vytvořit soubor \"%s\": %m" + +#: copy_fetch.c:59 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "nelze otevřít adresář \"%s\": %m" + #: copy_fetch.c:117 #, c-format msgid "could not read symbolic link \"%s\": %m" @@ -127,7 +178,7 @@ msgstr "nelze otevřít zdrojový soubor \"%s\": %m" msgid "could not seek in source file: %m" msgstr "nelze změnit pozici (seek) ve zdrojovém souboru: %m" -#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:314 +#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:336 #, c-format msgid "could not read file \"%s\": %m" msgstr "nelze číst soubor \"%s\": %m" @@ -207,202 +258,197 @@ msgstr "nelze odstranit symbolický odkaz \"%s\": %m" msgid "could not open file \"%s\" for reading: %m" msgstr "nelze otevřít soubor \"%s\" pro čtení: %m" -#: file_ops.c:314 parsexlog.c:316 +#: file_ops.c:314 parsexlog.c:338 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "nelze číst soubor \"%s\": načteno %d z %zu" -#: filemap.c:179 +#: filemap.c:200 #, c-format msgid "data file \"%s\" in source is not a regular file" msgstr "datový soubor \"%s\" ve zdroji není obyčejný soubor" -#: filemap.c:201 +#: filemap.c:222 #, c-format msgid "\"%s\" is not a directory" msgstr "\"%s\" není adresář" -#: filemap.c:224 +#: filemap.c:245 #, c-format msgid "\"%s\" is not a symbolic link" msgstr "\"%s\" není symbolický odkaz" -#: filemap.c:236 +#: filemap.c:257 #, c-format msgid "\"%s\" is not a regular file" msgstr "\"%s\" není obyčejný soubor" -#: filemap.c:360 +#: filemap.c:369 #, c-format msgid "source file list is empty" msgstr "seznam zdrojových souborů je prázdný" -#: filemap.c:475 +#: filemap.c:484 #, c-format msgid "unexpected page modification for directory or symbolic link \"%s\"" msgstr "neočekávaná modifikace stránky pro adresář nebo symbolický odkaz \"%s\"" -#: libpq_fetch.c:52 +#: libpq_fetch.c:50 #, c-format msgid "could not connect to server: %s" msgstr "nelze se připojit k serveru: %s" -#: libpq_fetch.c:56 +#: libpq_fetch.c:54 #, c-format msgid "connected to server" msgstr "připojen k serveru" -#: libpq_fetch.c:65 +#: libpq_fetch.c:63 #, c-format msgid "could not clear search_path: %s" msgstr "nelze vyčistit search_path: %s" -#: libpq_fetch.c:77 +#: libpq_fetch.c:75 #, c-format msgid "source server must not be in recovery mode" msgstr "zdrojový server musí být v recovery módu" -#: libpq_fetch.c:87 +#: libpq_fetch.c:85 #, c-format msgid "full_page_writes must be enabled in the source server" msgstr "full_page_writes musí být zapnuty na zdrojovém serveru" -#: libpq_fetch.c:113 libpq_fetch.c:139 +#: libpq_fetch.c:111 #, c-format -msgid "error running query (%s) in source server: %s" +msgid "error running query (%s) on source server: %s" msgstr "chyba při spuštění dotazu (%s) na zdrojovém serveru: %s" -#: libpq_fetch.c:118 +#: libpq_fetch.c:116 #, c-format msgid "unexpected result set from query" msgstr "neočekávaný výsledek dotazu" -#: libpq_fetch.c:159 +#: libpq_fetch.c:137 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "chyba při spuštění dotazu (%s) na zdrojovém serveru: %s" + +#: libpq_fetch.c:157 #, c-format msgid "unrecognized result \"%s\" for current WAL insert location" msgstr "nerozpoznaný výsledek \"%s\" pro aktuální WAL insert pozici" -#: libpq_fetch.c:209 +#: libpq_fetch.c:207 #, c-format msgid "could not fetch file list: %s" msgstr "nelze načíst seznam souborů: %s" -#: libpq_fetch.c:214 +#: libpq_fetch.c:212 #, c-format msgid "unexpected result set while fetching file list" msgstr "neočekávaný výsledek při načítání seznamu souborů" -#: libpq_fetch.c:262 +#: libpq_fetch.c:265 #, c-format msgid "could not send query: %s" msgstr "nelze zaslat dotaz: %s" -#: libpq_fetch.c:267 +#: libpq_fetch.c:270 #, c-format msgid "could not set libpq connection to single row mode" msgstr "nelze nastavit libpq spojení na single row mód" -#: libpq_fetch.c:288 +#: libpq_fetch.c:290 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "neočekávaný výsledek při načítání vzdálených souborů: %s" -#: libpq_fetch.c:294 +#: libpq_fetch.c:296 #, c-format msgid "unexpected result set size while fetching remote files" msgstr "neočekávaná velikost výsledku při načítání vzdálených souborů" -#: libpq_fetch.c:300 +#: libpq_fetch.c:302 #, c-format msgid "unexpected data types in result set while fetching remote files: %u %u %u" msgstr "neočekávané datové typy ve vysledku při načítání vzdálených souborů: %u %u %u" -#: libpq_fetch.c:308 +#: libpq_fetch.c:310 #, c-format msgid "unexpected result format while fetching remote files" msgstr "neočekávaný formát výsledku při načítání vzdálených souborů" -#: libpq_fetch.c:314 +#: libpq_fetch.c:316 #, c-format msgid "unexpected null values in result while fetching remote files" msgstr "neočekávané null hodnoty ve výsledku při načítání vzdálených souborů" -#: libpq_fetch.c:318 +#: libpq_fetch.c:320 #, c-format msgid "unexpected result length while fetching remote files" msgstr "neočekávaná délka výsledku při načítání vzdálených souborů" -#: libpq_fetch.c:384 +#: libpq_fetch.c:381 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "nelze načíst vzdálený soubor \"%s\": %s" -#: libpq_fetch.c:389 +#: libpq_fetch.c:386 #, c-format msgid "unexpected result set while fetching remote file \"%s\"" msgstr "neočekávaný výsledek při načítání vzdáleného souboru \"%s\"" -#: libpq_fetch.c:433 +#: libpq_fetch.c:430 #, c-format msgid "could not send COPY data: %s" msgstr "nelze poslat COPY data: %s" -#: libpq_fetch.c:462 +#: libpq_fetch.c:459 #, c-format msgid "could not send file list: %s" msgstr "nelze poslat seznam souborů: %s" -#: libpq_fetch.c:504 +#: libpq_fetch.c:501 #, c-format msgid "could not send end-of-COPY: %s" msgstr "nelze poslat end-of-COPY: %s" -#: libpq_fetch.c:510 +#: libpq_fetch.c:507 #, c-format msgid "unexpected result while sending file list: %s" msgstr "neočekávaný výsledek při posílání seznamu souborů: %s" -#: parsexlog.c:74 parsexlog.c:127 parsexlog.c:185 -#, c-format -msgid "out of memory" -msgstr "nedostatek paměti" - -#: parsexlog.c:87 parsexlog.c:133 +#: parsexlog.c:85 parsexlog.c:132 #, c-format msgid "could not read WAL record at %X/%X: %s" msgstr "nelze načíst WAL záznam na %X/%X: %s" -#: parsexlog.c:91 parsexlog.c:136 +#: parsexlog.c:89 parsexlog.c:135 #, c-format msgid "could not read WAL record at %X/%X" msgstr "nelze načíst WAL záznam na %X/%X" -#: parsexlog.c:197 +#: parsexlog.c:198 #, c-format msgid "could not find previous WAL record at %X/%X: %s" msgstr "nelze nalézt předchozí WAL záznam na %X/%X: %s" -#: parsexlog.c:201 +#: parsexlog.c:202 #, c-format msgid "could not find previous WAL record at %X/%X" msgstr "nelze načíst předchozí WAL záznam na %X/%X" -#: parsexlog.c:292 -#, c-format -msgid "could not open file \"%s\": %m" -msgstr "nelze otevřít soubor \"%s\": %m" - -#: parsexlog.c:305 +#: parsexlog.c:327 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "nelze nastavit pozici (seek) v souboru \"%s\": %m" -#: parsexlog.c:385 +#: parsexlog.c:407 #, c-format msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" msgstr "WAL záznam modifikuje relaci, ale typ záznamu není rozpoznán: lsn: %X/%X, rmgr: %s, info: %02X" -#: pg_rewind.c:72 +#: pg_rewind.c:78 #, c-format msgid "" "%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" @@ -411,7 +457,7 @@ msgstr "" "%s resynchronizuje PostgreSQL cluster s jinou kopií daného clusteru.\n" "\n" -#: pg_rewind.c:73 +#: pg_rewind.c:79 #, c-format msgid "" "Usage:\n" @@ -422,34 +468,42 @@ msgstr "" " %s [OPTION]...\n" "\n" -#: pg_rewind.c:74 +#: pg_rewind.c:80 #, c-format msgid "Options:\n" msgstr "Přepínače:\n" -#: pg_rewind.c:75 +#: pg_rewind.c:81 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal použij restore_command v cílové konfiguraci pro\n" +" získání WAL souborů z archivu\n" + +#: pg_rewind.c:83 #, c-format msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" msgstr " -D, --target-pgdata=ADRESÁŘ existující datový adresář pro modifikaci\n" -#: pg_rewind.c:76 +#: pg_rewind.c:84 #, c-format msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" msgstr " --source-pgdata=ADRESÁŘ zdrojový datový adresář proti kterému se synchronizovat\n" -#: pg_rewind.c:77 +#: pg_rewind.c:85 #, c-format msgid " --source-server=CONNSTR source server to synchronize with\n" msgstr " --source-server=CONNSTR zdrojový server se kterým se synchronizovat\n" -#: pg_rewind.c:78 +#: pg_rewind.c:86 #, c-format msgid " -n, --dry-run stop before modifying anything\n" msgstr " -n, --dry-run zastavit před modifikací čehokoliv\n" -#: pg_rewind.c:79 +#: pg_rewind.c:87 #, c-format -#| msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgid "" " -N, --no-sync do not wait for changes to be written\n" " safely to disk\n" @@ -457,187 +511,212 @@ msgstr "" " -N, --no-sync nečekat na bezpečné zapsání změn na disk\n" "\n" -#: pg_rewind.c:81 +#: pg_rewind.c:89 #, c-format msgid " -P, --progress write progress messages\n" msgstr " -P, --progress průběžně vypisovat zprávy o postupu\n" -#: pg_rewind.c:82 +#: pg_rewind.c:90 +#, c-format +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf zapíše konfiguraci pro replikaci\n" +" (vyžaduje zadání --source-server)\n" +"\n" + +#: pg_rewind.c:92 #, c-format msgid " --debug write a lot of debug messages\n" msgstr " --debug vypisovat mnoho zpráv s debug informacemi\n" -#: pg_rewind.c:83 +#: pg_rewind.c:93 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr " --no-ensure-shutdown neopravuj automaticky nečisté vypnutí databáze\n" + +#: pg_rewind.c:94 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version vypíše informaci o verzi, poté skončí\n" -#: pg_rewind.c:84 +#: pg_rewind.c:95 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help vypíše tuto nápovědu, poté skončí\n" -#: pg_rewind.c:85 +#: pg_rewind.c:96 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to <%s>.\n" msgstr "" "\n" -"Chyby hlaste na adresu .\n" +"Chyby oznamujte na <%s>.\n" + +#: pg_rewind.c:97 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" -#: pg_rewind.c:142 pg_rewind.c:178 pg_rewind.c:185 pg_rewind.c:192 -#: pg_rewind.c:200 +#: pg_rewind.c:159 pg_rewind.c:208 pg_rewind.c:215 pg_rewind.c:222 +#: pg_rewind.c:229 pg_rewind.c:237 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: pg_rewind.c:177 +#: pg_rewind.c:207 #, c-format msgid "no source specified (--source-pgdata or --source-server)" msgstr "nespecifikován žádný zdroj (--source-pgdata nebo --source-server)" -#: pg_rewind.c:184 +#: pg_rewind.c:214 #, c-format msgid "only one of --source-pgdata or --source-server can be specified" msgstr "pouze jedna z voleb --source-pgdata nebo --source-server může být zadána" -#: pg_rewind.c:191 +#: pg_rewind.c:221 #, c-format msgid "no target data directory specified (--target-pgdata)" msgstr "cílový datový adresář nespecifikován (--target-pgdata)" -#: pg_rewind.c:198 +#: pg_rewind.c:228 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "" + +#: pg_rewind.c:235 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "příliš mnoho argumentů v příkazové řádce (první je \"%s\")" -#: pg_rewind.c:213 +#: pg_rewind.c:250 #, c-format msgid "cannot be executed by \"root\"" msgstr "nelze spouštět jako \"root\"" -#: pg_rewind.c:214 +#: pg_rewind.c:251 #, c-format msgid "You must run %s as the PostgreSQL superuser.\n" msgstr "Musíte spustit %s jako PostgreSQL superuživatel.\n" -#: pg_rewind.c:225 +#: pg_rewind.c:262 #, c-format msgid "could not read permissions of directory \"%s\": %m" msgstr "nelze zjistit přístupová práva adresáře \"%s\": %m" -#: pg_rewind.c:256 +#: pg_rewind.c:316 #, c-format msgid "source and target cluster are on the same timeline" msgstr "zdrojový a cílový cluster jsou na stejné timeline" -#: pg_rewind.c:262 +#: pg_rewind.c:322 #, c-format msgid "servers diverged at WAL location %X/%X on timeline %u" msgstr "servery se rozešly na WAL pozici %X/%X na timeline %u" -#: pg_rewind.c:299 +#: pg_rewind.c:360 #, c-format msgid "no rewind required" msgstr "rewind není potřeba" -#: pg_rewind.c:306 +#: pg_rewind.c:369 #, c-format msgid "rewinding from last common checkpoint at %X/%X on timeline %u" msgstr "provádím rewind z posledního společného checkpointu na %X/%X na timeline %u" -#: pg_rewind.c:315 +#: pg_rewind.c:378 #, c-format msgid "reading source file list" msgstr "načítám seznam zdrojových souborů" -#: pg_rewind.c:318 +#: pg_rewind.c:381 #, c-format msgid "reading target file list" msgstr "načítám seznam cílových souborů" -#: pg_rewind.c:329 +#: pg_rewind.c:392 #, c-format msgid "reading WAL in target" msgstr "čtu WAL na cílovém clusteru" -#: pg_rewind.c:346 +#: pg_rewind.c:409 #, c-format msgid "need to copy %lu MB (total source directory size is %lu MB)" msgstr "je třeba zkopírovat %lu MB (celková velikost zdrojového adresáře je %lu MB)" -#: pg_rewind.c:365 +#: pg_rewind.c:427 #, c-format msgid "creating backup label and updating control file" msgstr "vytvářím backup label a aktualizuji control file" -#: pg_rewind.c:394 +#: pg_rewind.c:457 #, c-format msgid "syncing target data directory" msgstr "provádím sync cílového datového adresáře" -#: pg_rewind.c:397 +#: pg_rewind.c:464 #, c-format msgid "Done!" msgstr "Hotovo!" -#: pg_rewind.c:409 +#: pg_rewind.c:476 #, c-format msgid "source and target clusters are from different systems" msgstr "zdrojový a cílový cluster jsou z různých systémů" -#: pg_rewind.c:417 +#: pg_rewind.c:484 #, c-format msgid "clusters are not compatible with this version of pg_rewind" msgstr "clustery nejsou kompatibilní s touto verzí pg_rewind" -#: pg_rewind.c:427 +#: pg_rewind.c:494 #, c-format msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" msgstr "cílový server musí používat buď data checksums nebo \"wal_log_hints = on\"" -#: pg_rewind.c:438 +#: pg_rewind.c:505 #, c-format msgid "target server must be shut down cleanly" msgstr "cílový server musí být zastaven čistě" -#: pg_rewind.c:448 +#: pg_rewind.c:515 #, c-format msgid "source data directory must be shut down cleanly" msgstr "zdrojový datový adresář musí být zastaven čistě" -#: pg_rewind.c:497 +#: pg_rewind.c:567 #, c-format msgid "%*s/%s kB (%d%%) copied" msgstr "%*s/%s kB (%d%%) zkopírováno" -#: pg_rewind.c:558 +#: pg_rewind.c:630 #, c-format msgid "invalid control file" msgstr "neplatný control file" -#: pg_rewind.c:642 +#: pg_rewind.c:714 #, c-format msgid "could not find common ancestor of the source and target cluster's timelines" msgstr "nelze najít společného předka pro timeline ze zdrojového a cílového clusteru" -#: pg_rewind.c:683 +#: pg_rewind.c:755 #, c-format msgid "backup label buffer too small" msgstr "backup label buffer je příliš malý" -#: pg_rewind.c:706 +#: pg_rewind.c:778 #, c-format msgid "unexpected control file CRC" msgstr "neočekávaná CRC hodnota control file" -#: pg_rewind.c:716 +#: pg_rewind.c:788 #, c-format msgid "unexpected control file size %d, expected %d" msgstr "neočekávaná velikost control file %d, očekáváno %d" -#: pg_rewind.c:725 +#: pg_rewind.c:797 #, c-format msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" @@ -645,247 +724,296 @@ msgstr[0] "Velikost WAL segmentu musí být mocnina dvou mezi 1 MB a 1 GB, ale c msgstr[1] "Velikost WAL segmentu musí být mocnina dvou mezi 1 MB a 1 GB, ale control file udává %d bytů" msgstr[2] "Velikost WAL segmentu musí být mocnina dvou mezi 1 MB a 1 GB, ale control file udává %d bytů" -#: timeline.c:76 timeline.c:82 +#: pg_rewind.c:854 pg_rewind.c:912 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Program \"%s\" je vyžadován aplikací %s, ale nebyl nalezen ve stejném\n" +"adresáři jako \"%s\".\n" +"Zkontrolujte vaši instalaci." + +#: pg_rewind.c:859 pg_rewind.c:917 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Program \"%s\" byl nalezen pomocí \"%s\",\n" +"ale nebyl ve stejné verzi jako %s.\n" +"Zkontrolujte vaši instalaci." + +#: pg_rewind.c:880 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "restore_command není nastaven pro cílový cluster" + +#: pg_rewind.c:923 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "spouštím \"%s\" na cílovém serveru pro dokončení crash recovery" + +#: pg_rewind.c:943 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "postgres single-user mód v cílovém clusteru selhal" + +#: pg_rewind.c:944 +#, c-format +msgid "Command was: %s" +msgstr "Příkaz byl: %s" + +#: timeline.c:75 timeline.c:81 #, c-format msgid "syntax error in history file: %s" msgstr "syntaktická chyba v souboru s historií: %s" -#: timeline.c:77 +#: timeline.c:76 #, c-format msgid "Expected a numeric timeline ID." msgstr "Očekávána číselná hodnota timeline ID." -#: timeline.c:83 +#: timeline.c:82 #, c-format msgid "Expected a write-ahead log switchpoint location." msgstr "Očekávána pozice pro switchpoint write-ahead logu." -#: timeline.c:88 +#: timeline.c:87 #, c-format msgid "invalid data in history file: %s" msgstr "chybná data v souboru s historií: %s" -#: timeline.c:89 +#: timeline.c:88 #, c-format msgid "Timeline IDs must be in increasing sequence." msgstr "Timeline IDs musí být rostoucí posloupnost." -#: timeline.c:109 +#: timeline.c:108 #, c-format msgid "invalid data in history file" msgstr "chybná data v souboru s historií" -#: timeline.c:110 +#: timeline.c:109 #, c-format msgid "Timeline IDs must be less than child timeline's ID." msgstr "Timeline IDs musí být nižší než timeline ID potomka." -#: xlogreader.c:299 +#: xlogreader.c:349 #, c-format msgid "invalid record offset at %X/%X" msgstr "neplatný offset záznamu na %X/%X" -#: xlogreader.c:307 +#: xlogreader.c:357 #, c-format msgid "contrecord is requested by %X/%X" msgstr "contrecord je vyžadován %X/%X" -#: xlogreader.c:348 xlogreader.c:645 +#: xlogreader.c:398 xlogreader.c:695 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "neplatná délka záznamu na %X/%X: potřeba %u, získáno %u" -#: xlogreader.c:372 +#: xlogreader.c:422 #, c-format msgid "record length %u at %X/%X too long" msgstr "délka záznamu %u na %X/%X je příliš vysoká" -#: xlogreader.c:404 +#: xlogreader.c:454 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "na %X/%X není nastaven contrecord flag" -#: xlogreader.c:417 +#: xlogreader.c:467 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "chybná contrecord délka %u na %X/%X" -#: xlogreader.c:653 +#: xlogreader.c:703 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "chybný ID resource managera %u na %X/%X" -#: xlogreader.c:667 xlogreader.c:684 +#: xlogreader.c:717 xlogreader.c:734 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "záznam s neplatnou hodnotou prev-link %X/%X na %X/%X" -#: xlogreader.c:721 +#: xlogreader.c:771 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "neplatný data checksum resource managera v záznamu na %X/%X" -#: xlogreader.c:758 +#: xlogreader.c:808 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "neplatné magické číslo %04X v log segmentu %s, offset %u" -#: xlogreader.c:772 xlogreader.c:823 +#: xlogreader.c:822 xlogreader.c:863 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "neplatné info bity %04X v log segmentu %s, offset %u" -#: xlogreader.c:798 +#: xlogreader.c:837 #, c-format -msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" -msgstr "WAL soubor je z jiného databázového systému: systémový identifikátor z WAL souboru je %s, systémový identifikátor z pg_control je %s" +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL soubor je z jiného databázového systému: systémový identifikátor z WAL souboru je %llu, systémový identifikátor z pg_control je %llu" -#: xlogreader.c:805 +#: xlogreader.c:845 #, c-format msgid "WAL file is from different database system: incorrect segment size in page header" msgstr "WAL soubor je z jiného databázového systému: neplatná velikost segmentu v hlavičce stránky" -#: xlogreader.c:811 +#: xlogreader.c:851 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "WAL soubor je z jiného databázového systému: neplatná hodnota XLOG_BLCKSZ v hlavičce stránky" -#: xlogreader.c:842 +#: xlogreader.c:882 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "neočekávaná pageaddr hodnota %X/%X v log segmentu %s, offset %u" -#: xlogreader.c:867 +#: xlogreader.c:907 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "timeline ID %u mimo pořadí (po %u) v log segmentu %s, offset %u" -#: xlogreader.c:1112 +#: xlogreader.c:1247 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "block_id %u mimo pořadí na %X/%X" -#: xlogreader.c:1135 +#: xlogreader.c:1270 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA flag nastaven, ale žádná data nejsou přiložena na %X/%X" -#: xlogreader.c:1142 +#: xlogreader.c:1277 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA flag nenastaven, ale délka dat je %u na %X/%X" -#: xlogreader.c:1178 +#: xlogreader.c:1313 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE flag nastaven, ale hole offset %u length %u block image length %u na %X/%X" -#: xlogreader.c:1194 +#: xlogreader.c:1329 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE flag nenastaven, ale hole offset %u length %u na %X/%X" -#: xlogreader.c:1209 +#: xlogreader.c:1344 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED flag nastaven, ale block image length %u na %X/%X" -#: xlogreader.c:1224 +#: xlogreader.c:1359 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE ani BKPIMAGE_IS_COMPRESSED flag nenastaven, ale block image length je %u na %X/%X" -#: xlogreader.c:1240 +#: xlogreader.c:1375 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL flag nastaven, ale žádná předchozí rel hodnota na %X/%X" -#: xlogreader.c:1252 +#: xlogreader.c:1387 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "neplatné block_id %u na %X/%X" -#: xlogreader.c:1341 +#: xlogreader.c:1476 #, c-format msgid "record with invalid length at %X/%X" msgstr "záznam s neplatnou délkou na %X/%X" -#: xlogreader.c:1430 +#: xlogreader.c:1565 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "neplatný komprimovaný image na %X/%X, block %d" -#~ msgid "sync of target directory failed\n" -#~ msgstr "sync na cílovém adresáři selhal\n" +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "nelze otevřít adresář \"%s\": %s\n" -#~ msgid "" -#~ "The program \"initdb\" was found by \"%s\"\n" -#~ "but was not the same version as %s.\n" -#~ "Check your installation.\n" -#~ msgstr "" -#~ "Program \"initdb\" byl nalezen \"%s\"\n" -#~ "ale nemá stejnou verzi jako \"%s\".\n" -#~ "Zkontrolujte svou instalaci.\n" +#~ msgid "could not read file \"%s\": %s\n" +#~ msgstr "nelze číst soubor \"%s\": %s\n" -#~ msgid "" -#~ "The program \"initdb\" is needed by %s but was\n" -#~ "not found in the same directory as \"%s\".\n" -#~ "Check your installation.\n" -#~ msgstr "" -#~ "Program \"initdb\" je vyžadován %s ale nebyl\n" -#~ "nalezen ve stejném adresáři jako \"%s\".\n" -#~ "Zkontrolujte svou instalaci.\n" +#~ msgid " block %u\n" +#~ msgstr " blok %u\n" -#~ msgid "%d: %X/%X - %X/%X\n" -#~ msgstr "%d: %X/%X - %X/%X\n" +#~ msgid "entry \"%s\" excluded from %s file list\n" +#~ msgstr "položka \"%s\" vyloučena ze %s seznamu souborů\n" -#~ msgid "Target timeline history:\n" -#~ msgstr "Cílová timeline history:\n" +#~ msgid "%s (%s)\n" +#~ msgstr "%s (%s)\n" -#~ msgid "Source timeline history:\n" -#~ msgstr "Zdrojová timeline history:\n" +#~ msgid "could not set up connection context: %s" +#~ msgstr "nelze nastavit kontext spojení: %s" -#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" -#~ msgstr "%s: nelze načíst práva adresáře \"%s\": %s\n" +#~ msgid "getting file chunks\n" +#~ msgstr "načítám části souborů\n" -#~ msgid "could not read from file \"%s\": %s\n" -#~ msgstr "nelze číst ze souboru \"%s\": %s\n" +#~ msgid "received null value for chunk for file \"%s\", file has been deleted\n" +#~ msgstr "přijata null hodnota pro chunk souboru \"%s\", soubor byl smazán\n" -#~ msgid "could not open file \"%s\": %s\n" -#~ msgstr "nelze otevřít soubor \"%s\": %s\n" +#~ msgid "received chunk for file \"%s\", offset %s, size %d\n" +#~ msgstr "přijat chunk souboru \"%s\", offset %s, délka %d\n" -#~ msgid "Failure, exiting\n" -#~ msgstr "Chyba, končím\n" +#~ msgid "fetched file \"%s\", length %d\n" +#~ msgstr "načten soubor \"%s\", délka %d\n" #~ msgid "could not create temporary table: %s" #~ msgstr "nelze vytvořit temporary tabulku: %s" -#~ msgid "fetched file \"%s\", length %d\n" -#~ msgstr "načten soubor \"%s\", délka %d\n" +#~ msgid "Failure, exiting\n" +#~ msgstr "Chyba, končím\n" -#~ msgid "received chunk for file \"%s\", offset %s, size %d\n" -#~ msgstr "přijat chunk souboru \"%s\", offset %s, délka %d\n" +#~ msgid "could not open file \"%s\": %s\n" +#~ msgstr "nelze otevřít soubor \"%s\": %s\n" -#~ msgid "received null value for chunk for file \"%s\", file has been deleted\n" -#~ msgstr "přijata null hodnota pro chunk souboru \"%s\", soubor byl smazán\n" +#~ msgid "could not read from file \"%s\": %s\n" +#~ msgstr "nelze číst ze souboru \"%s\": %s\n" -#~ msgid "getting file chunks\n" -#~ msgstr "načítám části souborů\n" +#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" +#~ msgstr "%s: nelze načíst práva adresáře \"%s\": %s\n" -#~ msgid "could not set up connection context: %s" -#~ msgstr "nelze nastavit kontext spojení: %s" +#~ msgid "Source timeline history:\n" +#~ msgstr "Zdrojová timeline history:\n" -#~ msgid "%s (%s)\n" -#~ msgstr "%s (%s)\n" +#~ msgid "Target timeline history:\n" +#~ msgstr "Cílová timeline history:\n" -#~ msgid "entry \"%s\" excluded from %s file list\n" -#~ msgstr "položka \"%s\" vyloučena ze %s seznamu souborů\n" +#~ msgid "%d: %X/%X - %X/%X\n" +#~ msgstr "%d: %X/%X - %X/%X\n" -#~ msgid " block %u\n" -#~ msgstr " blok %u\n" +#~ msgid "" +#~ "The program \"initdb\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "Program \"initdb\" je vyžadován %s ale nebyl\n" +#~ "nalezen ve stejném adresáři jako \"%s\".\n" +#~ "Zkontrolujte svou instalaci.\n" -#~ msgid "could not read file \"%s\": %s\n" -#~ msgstr "nelze číst soubor \"%s\": %s\n" +#~ msgid "" +#~ "The program \"initdb\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "Program \"initdb\" byl nalezen \"%s\"\n" +#~ "ale nemá stejnou verzi jako \"%s\".\n" +#~ "Zkontrolujte svou instalaci.\n" -#~ msgid "could not open directory \"%s\": %s\n" -#~ msgstr "nelze otevřít adresář \"%s\": %s\n" +#~ msgid "sync of target directory failed\n" +#~ msgstr "sync na cílovém adresáři selhal\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" diff --git a/src/bin/pg_rewind/po/de.po b/src/bin/pg_rewind/po/de.po new file mode 100644 index 000000000000..e3b922f2d9da --- /dev/null +++ b/src/bin/pg_rewind/po/de.po @@ -0,0 +1,959 @@ +# German message translation file for pg_rewind +# Copyright (C) 2015-2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_rewind (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 08:49+0000\n" +"PO-Revision-Date: 2021-05-14 14:40+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "konnte Bibliothek »%s« nicht laden: Fehlercode %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "auf dieser Plattform können keine beschränkten Token erzeugt werden: Fehlercode %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "konnte Prozess-Token nicht öffnen: Fehlercode %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "konnte SIDs nicht erzeugen: Fehlercode %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "konnte beschränktes Token nicht erzeugen: Fehlercode %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "cannot use restore_command with %%r placeholder" +msgstr "kann restore_command mit Platzhalter %%r nicht verwenden" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lld instead of %lld" +msgstr "unerwartete Dateigröße für »%s«: %lld statt %lld" + +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "konnte aus dem Archiv wiederhergestellte Datei »%s« nicht öffnen: %m" + +#: ../../fe_utils/archive.c:97 file_ops.c:417 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed: %s" +msgstr "restore_command fehlgeschlagen: %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "konnte Datei »%s« nicht aus Archiv wiederherstellen" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:77 parsexlog.c:135 +#: parsexlog.c:195 +#, c-format +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:308 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "konnte nicht in Datei »%s« schreiben: %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "konnte Datei »%s« nicht erstellen: %m" + +#: file_ops.c:67 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "konnte Zieldatei »%s« nicht öffnen: %m" + +#: file_ops.c:81 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "konnte Zieldatei »%s« nicht schließen: %m" + +#: file_ops.c:101 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "konnte Positionszeiger in Zieldatei »%s« nicht setzen: %m" + +#: file_ops.c:117 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schreiben: %m" + +#: file_ops.c:150 file_ops.c:177 +#, c-format +msgid "undefined file type for \"%s\"" +msgstr "undefinierter Dateityp für »%s«" + +#: file_ops.c:173 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "ungültige Aktion (CREATE) für normale Datei" + +#: file_ops.c:200 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "konnte Datei »%s« nicht löschen: %m" + +#: file_ops.c:218 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "konnte Datei »%s« nicht zum Kürzen öffnen: %m" + +#: file_ops.c:222 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" + +#: file_ops.c:238 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" + +#: file_ops.c:252 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht löschen: %m" + +#: file_ops.c:266 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" + +#: file_ops.c:280 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht löschen: %m" + +#: file_ops.c:326 file_ops.c:330 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" + +#: file_ops.c:341 local_source.c:107 parsexlog.c:346 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "konnte Datei »%s« nicht lesen: %m" + +#: file_ops.c:344 parsexlog.c:348 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" + +#: file_ops.c:388 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: file_ops.c:446 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" + +#: file_ops.c:449 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "Ziel für symbolische Verknüpfung »%s« ist zu lang" + +#: file_ops.c:464 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "»%s« ist eine symbolische Verknüpfung, aber symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt" + +#: file_ops.c:471 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" + +#: file_ops.c:475 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" + +#: filemap.c:237 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "Datendatei »%s« in der Quelle ist keine normale Datei" + +#: filemap.c:242 filemap.c:275 +#, c-format +msgid "duplicate source file \"%s\"" +msgstr "doppelte Quelldatei »%s«" + +#: filemap.c:330 +#, c-format +msgid "unexpected page modification for non-regular file \"%s\"" +msgstr "unerwartete Seitenänderung für nicht normale Datei »%s«" + +#: filemap.c:680 filemap.c:774 +#, c-format +msgid "unknown file type for \"%s\"" +msgstr "unbekannter Dateityp für »%s«" + +#: filemap.c:707 +#, c-format +msgid "file \"%s\" is of different type in source and target" +msgstr "Datei »%s« hat unterschiedlichen Typ in Quelle und Ziel" + +#: filemap.c:779 +#, c-format +msgid "could not decide what to do with file \"%s\"" +msgstr "konnte nicht entscheiden, was mit Datei »%s« zu tun ist" + +#: libpq_source.c:128 +#, c-format +msgid "could not clear search_path: %s" +msgstr "konnte search_path nicht auf leer setzen: %s" + +#: libpq_source.c:139 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "full_page_writes muss im Quell-Server eingeschaltet sein" + +#: libpq_source.c:150 +#, c-format +msgid "could not prepare statement to fetch file contents: %s" +msgstr "konnte Anfrage zum Holen des Dateiinhalts nicht vorbereiten: %s" + +#: libpq_source.c:169 +#, c-format +msgid "error running query (%s) on source server: %s" +msgstr "Fehler beim Ausführen einer Anfrage (%s) auf dem Quellserver: %s" + +#: libpq_source.c:174 +#, c-format +msgid "unexpected result set from query" +msgstr "Anfrage ergab unerwartete Ergebnismenge" + +#: libpq_source.c:196 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "Fehler beim Ausführen einer Anfrage (%s) im Quellserver: %s" + +#: libpq_source.c:217 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "unbekanntes Ergebnis »%s« für aktuelle WAL-Einfügeposition" + +#: libpq_source.c:268 +#, c-format +msgid "could not fetch file list: %s" +msgstr "konnte Dateiliste nicht holen: %s" + +#: libpq_source.c:273 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "unerwartete Ergebnismenge beim Holen der Dateiliste" + +#: libpq_source.c:435 +#, c-format +msgid "could not send query: %s" +msgstr "konnte Anfrage nicht senden: %s" + +#: libpq_source.c:438 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "konnte libpq-Verbindung nicht in den Einzelzeilenmodus setzen" + +#: libpq_source.c:468 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "unerwartetes Ergebnis beim Holen von fernen Dateien: %s" + +#: libpq_source.c:473 +#, c-format +msgid "received more data chunks than requested" +msgstr "mehr Daten-Chunks erhalten als verlangt" + +#: libpq_source.c:477 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "unerwartete Ergebnismengengröße beim Holen von fernen Dateien" + +#: libpq_source.c:483 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "unerwartete Datentypen in Ergebnismenge beim Holen von fernen Dateien: %u %u %u" + +#: libpq_source.c:491 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "unerwartetes Ergebnisformat beim Holen von fernen Dateien" + +#: libpq_source.c:497 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "unerwartete NULL-Werte im Ergebnis beim Holen von fernen Dateien" + +#: libpq_source.c:501 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "unerwartete Ergebnislänge beim Holen von fernen Dateien" + +#: libpq_source.c:534 +#, c-format +msgid "received data for file \"%s\", when requested for \"%s\"" +msgstr "Daten für Datei »%s« erhalten, aber »%s« wurde verlangt" + +#: libpq_source.c:538 +#, c-format +msgid "received data at offset %lld of file \"%s\", when requested for offset %lld" +msgstr "Daten für Offset %lld von Datei »%s« erhalten, aber Offset %lld wurde verlangt" + +#: libpq_source.c:550 +#, c-format +msgid "received more than requested for file \"%s\"" +msgstr "mehr als verlangt erhalten für Datei »%s«" + +#: libpq_source.c:563 +#, c-format +msgid "unexpected number of data chunks received" +msgstr "unerwartete Anzahl Daten-Chunks erhalten" + +#: libpq_source.c:606 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "konnte ferne Datei »%s« nicht holen: %s" + +#: libpq_source.c:611 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "unerwartete Ergebnismenge beim Holen der fernen Datei »%s«" + +#: local_source.c:86 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "konnte Quelldatei »%s« nicht öffnen: %m" + +#: local_source.c:90 +#, c-format +msgid "could not seek in source file: %m" +msgstr "konnte Positionszeiger in Quelldatei nicht setzen: %m" + +#: local_source.c:109 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "unerwartetes EOF beim Lesen der Datei »%s«" + +#: local_source.c:116 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schließen: %m" + +#: parsexlog.c:89 parsexlog.c:142 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "konnte WAL-Eintrag bei %X/%X nicht lesen: %s" + +#: parsexlog.c:93 parsexlog.c:145 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "konnte WAL-Eintrag bei %X/%X nicht lesen" + +#: parsexlog.c:208 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "konnte vorangegangenen WAL-Eintrag bei %X/%X nicht finden: %s" + +#: parsexlog.c:212 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "konnte vorangegangenen WAL-Eintrag bei %X/%X nicht finden" + +#: parsexlog.c:337 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %m" + +#: parsexlog.c:429 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WAL-Eintrag modifiziert eine Relation, aber Typ des Eintrags wurde nicht erkannt: lsn: %X/%X, rmgr: %s, info: %02X" + +#: pg_rewind.c:84 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s resynchronisiert einen PostgreSQL-Cluster mit einer Kopie des Clusters.\n" +"\n" + +#: pg_rewind.c:85 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Aufruf:\n" +" %s [OPTION]...\n" +"\n" + +#: pg_rewind.c:86 +#, c-format +msgid "Options:\n" +msgstr "Optionen:\n" + +#: pg_rewind.c:87 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal restore_command in der Zielkonfiguration zum\n" +" Laden von WAL-Dateien aus Archiv verwenden\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=VERZ bestehendes zu modifizierendes Datenverzeichnis\n" + +#: pg_rewind.c:90 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr "" +" --source-pgdata=VERZ Quelldatenverzeichnis, mit dem synchronisiert\n" +" werden soll\n" + +#: pg_rewind.c:91 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=VERB Quellserver, mit dem synchronisiert werden soll\n" + +#: pg_rewind.c:92 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run anhalten, bevor etwas geändert wird\n" + +#: pg_rewind.c:93 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr "" +" -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress Fortschrittsmeldungen ausgeben\n" + +#: pg_rewind.c:96 +#, c-format +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf Konfiguration für Replikation schreiben\n" +" (benötigt --source-server)\n" + +#: pg_rewind.c:98 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug viele Debug-Meldungen ausgeben\n" + +#: pg_rewind.c:99 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr " --no-ensure-shutdown unsauberen Shutdown nicht automatisch reparieren\n" + +#: pg_rewind.c:100 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_rewind.c:101 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_rewind.c:102 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: pg_rewind.c:103 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: pg_rewind.c:164 pg_rewind.c:213 pg_rewind.c:220 pg_rewind.c:227 +#: pg_rewind.c:234 pg_rewind.c:242 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_rewind.c:212 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "keine Quelle angegeben (--source-pgdata oder --source-server)" + +#: pg_rewind.c:219 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "--source-pgdata und --source-server können nicht zusammen angegeben werden" + +#: pg_rewind.c:226 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "kein Zielverzeichnis angegeben (--target-pgdata)" + +#: pg_rewind.c:233 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "kein Quellserver (--source-server) angegeben für --write-recovery-conf" + +#: pg_rewind.c:240 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_rewind.c:255 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "kann nicht von »root« ausgeführt werden" + +#: pg_rewind.c:256 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "Sie müssen %s als PostgreSQL-Superuser ausführen.\n" + +#: pg_rewind.c:267 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" + +#: pg_rewind.c:287 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_rewind.c:290 +#, c-format +msgid "connected to server" +msgstr "mit Server verbunden" + +#: pg_rewind.c:337 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "Quell- und Ziel-Cluster sind auf der gleichen Zeitleiste" + +#: pg_rewind.c:346 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "Server divergierten bei WAL-Position %X/%X auf Zeitleiste %u" + +#: pg_rewind.c:394 +#, c-format +msgid "no rewind required" +msgstr "kein Rückspulen nötig" + +#: pg_rewind.c:403 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "Rückspulen ab letztem gemeinsamen Checkpoint bei %X/%X auf Zeitleiste %u" + +#: pg_rewind.c:413 +#, c-format +msgid "reading source file list" +msgstr "lese Quelldateiliste" + +#: pg_rewind.c:417 +#, c-format +msgid "reading target file list" +msgstr "lese Zieldateiliste" + +#: pg_rewind.c:426 +#, c-format +msgid "reading WAL in target" +msgstr "lese WAL im Ziel-Cluster" + +#: pg_rewind.c:447 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "%lu MB müssen kopiert werden (Gesamtgröße des Quellverzeichnisses ist %lu MB)" + +#: pg_rewind.c:465 +#, c-format +msgid "syncing target data directory" +msgstr "synchronisiere Zieldatenverzeichnis" + +#: pg_rewind.c:481 +#, c-format +msgid "Done!" +msgstr "Fertig!" + +#: pg_rewind.c:564 +#, c-format +msgid "no action decided for file \"%s\"" +msgstr "keine Aktion bestimmt für Datei »%s«" + +#: pg_rewind.c:596 +#, c-format +msgid "source system was modified while pg_rewind was running" +msgstr "Quellsystem wurde verändert, während pg_rewind lief" + +#: pg_rewind.c:600 +#, c-format +msgid "creating backup label and updating control file" +msgstr "erzeuge Backup-Label und aktualisiere Kontrolldatei" + +#: pg_rewind.c:650 +#, c-format +msgid "source system was in unexpected state at end of rewind" +msgstr "Quellsystem war in einem unerwarteten Zustand am Ende des Rückspulens" + +#: pg_rewind.c:681 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "Quell- und Ziel-Cluster sind von verschiedenen Systemen" + +#: pg_rewind.c:689 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "die Cluster sind nicht mit dieser Version von pg_rewind kompatibel" + +#: pg_rewind.c:699 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "Zielserver muss entweder Datenprüfsummen oder »wal_log_hints = on« verwenden" + +#: pg_rewind.c:710 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "Zielserver muss sauber heruntergefahren worden sein" + +#: pg_rewind.c:720 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "Quelldatenverzeichnis muss sauber heruntergefahren worden sein" + +#: pg_rewind.c:772 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s kB (%d%%) kopiert" + +#: pg_rewind.c:835 +#, c-format +msgid "invalid control file" +msgstr "ungültige Kontrolldatei" + +#: pg_rewind.c:919 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "konnte keinen gemeinsamen Anfangspunkt in den Zeitleisten von Quell- und Ziel-Cluster finden" + +#: pg_rewind.c:960 +#, c-format +msgid "backup label buffer too small" +msgstr "Puffer für Backup-Label ist zu klein" + +#: pg_rewind.c:983 +#, c-format +msgid "unexpected control file CRC" +msgstr "unerwartete CRC in Kontrolldatei" + +#: pg_rewind.c:995 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "unerwartete Kontrolldateigröße %d, erwartet wurde %d" + +#: pg_rewind.c:1004 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Byte an" +msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Bytes an" + +#: pg_rewind.c:1043 pg_rewind.c:1101 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wird von %s benötigt, aber wurde nicht im\n" +"selben Verzeichnis wie »%s« gefunden.\n" +"Prüfen Sie Ihre Installation." + +#: pg_rewind.c:1048 pg_rewind.c:1106 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wurde von %s gefunden,\n" +"aber es hatte nicht die gleiche Version wie %s.\n" +"Prüfen Sie Ihre Installation." + +#: pg_rewind.c:1069 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "restore_command ist im Ziel-Cluster nicht gesetzt" + +#: pg_rewind.c:1112 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "führe »%s« für Zielserver aus, um Wiederherstellung abzuschließen" + +#: pg_rewind.c:1132 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "postgres im Einzelbenutzermodus im Ziel-Cluster fehlgeschlagen" + +#: pg_rewind.c:1133 +#, c-format +msgid "Command was: %s" +msgstr "Die Anweisung war: %s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "Syntaxfehler in History-Datei: %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Eine numerische Zeitleisten-ID wurde erwartet." + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Eine Write-Ahead-Log-Switchpoint-Position wurde erwartet." + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "ungültige Daten in History-Datei: %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Zeitleisten-IDs müssen in aufsteigender Folge sein." + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "ungültige Daten in History-Datei" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Zeitleisten-IDs müssen kleiner als die Zeitleisten-ID des Kindes sein." + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "ungültiger Datensatz-Offset bei %X/%X" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "Contrecord angefordert von %X/%X" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "ungültige Datensatzlänge bei %X/%X: %u erwartet, %u erhalten" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "Datensatzlänge %u bei %X/%X ist zu lang" + +#: xlogreader.c:453 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "keine Contrecord-Flag bei %X/%X" + +#: xlogreader.c:466 +#, c-format +msgid "invalid contrecord length %u (expected %lld) at %X/%X" +msgstr "ungültige Contrecord-Länge %u (erwartet %lld) bei %X/%X" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "ungültige Resource-Manager-ID %u bei %X/%X" + +#: xlogreader.c:716 xlogreader.c:732 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "Datensatz mit falschem Prev-Link %X/%X bei %X/%X" + +#: xlogreader.c:768 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "ungültige Resource-Manager-Datenprüfsumme in Datensatz bei %X/%X" + +#: xlogreader.c:805 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "ungültige magische Zahl %04X in Logsegment %s, Offset %u" + +#: xlogreader.c:819 xlogreader.c:860 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ungültige Info-Bits %04X in Logsegment %s, Offset %u" + +#: xlogreader.c:834 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Datenbanksystemidentifikator in WAL-Datei ist %llu, Datenbanksystemidentifikator in pg_control ist %llu" + +#: xlogreader.c:842 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche Segmentgröße im Seitenkopf" + +#: xlogreader.c:848 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche XLOG_BLCKSZ im Seitenkopf" + +#: xlogreader.c:879 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "unerwartete Pageaddr %X/%X in Logsegment %s, Offset %u" + +#: xlogreader.c:904 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "Zeitleisten-ID %u außer der Reihe (nach %u) in Logsegment %s, Offset %u" + +#: xlogreader.c:1249 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %u außer der Reihe bei %X/%X" + +#: xlogreader.c:1271 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA gesetzt, aber keine Daten enthalten bei %X/%X" + +#: xlogreader.c:1278 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA nicht gesetzt, aber Datenlänge ist %u bei %X/%X" + +#: xlogreader.c:1314 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE gesetzt, aber Loch Offset %u Länge %u Block-Abbild-Länge %u bei %X/%X" + +#: xlogreader.c:1330 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE nicht gesetzt, aber Loch Offset %u Länge %u bei %X/%X" + +#: xlogreader.c:1345 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge %u bei %X/%X" + +#: xlogreader.c:1360 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "weder BKPIMAGE_HAS_HOLE noch BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge ist %u bei %X/%X" + +#: xlogreader.c:1376 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL gesetzt, aber keine vorangehende Relation bei %X/%X" + +#: xlogreader.c:1388 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "ungültige block_id %u bei %X/%X" + +#: xlogreader.c:1475 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "Datensatz mit ungültiger Länge bei %X/%X" + +#: xlogreader.c:1564 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "ungültiges komprimiertes Abbild bei %X/%X, Block %d" diff --git a/src/bin/pg_rewind/po/es.po b/src/bin/pg_rewind/po/es.po new file mode 100644 index 000000000000..fe5a6d529698 --- /dev/null +++ b/src/bin/pg_rewind/po/es.po @@ -0,0 +1,992 @@ +# Spanish message translation file for pg_rewind +# +# Copyright (c) 2015-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Álvaro Herrera , 2015. +# Carlos Chapi , 2017, 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_rewind (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:49+0000\n" +"PO-Revision-Date: 2021-05-21 23:23-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "no se pudo cargar la biblioteca «%s»: código de error %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "no se pueden crear tokens restrigidos en esta plataforma: código de error %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "no se pudo abrir el token de proceso: código de error %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "no se pudo emplazar los SIDs: código de error %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "no se pudo crear el token restringido: código de error %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "no se pudo iniciar el proceso para la orden «%s»: código de error %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "no se pudo re-ejecutar con el token restringido: código de error %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "no se pudo obtener el código de salida del subproceso»: código de error %lu" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "cannot use restore_command with %%r placeholder" +msgstr "no se puede usar restore_command con el marcador %%r" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lld instead of %lld" +msgstr "el archivo «%s» tiene tamaño inesperado: %lld en lugar de %lld" + +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "no se pudo abrir el archivo «%s» restaurado del archivo: %m" + +#: ../../fe_utils/archive.c:97 file_ops.c:417 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed: %s" +msgstr "restore_command falló: %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "no se pudo recuperar el archivo «%s» del archivo" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:77 parsexlog.c:135 +#: parsexlog.c:195 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:308 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "no se pudo escribir a archivo «%s»: %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "no se pudo crear archivo «%s»: %m" + +#: file_ops.c:67 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "no se pudo abrir el archivo de destino «%s»: %m" + +#: file_ops.c:81 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "no se pudo cerrar el archivo de destino «%s»: %m" + +#: file_ops.c:101 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "no se pudo posicionar en archivo de destino «%s»: %m" + +#: file_ops.c:117 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" + +#: file_ops.c:150 file_ops.c:177 +#, c-format +msgid "undefined file type for \"%s\"" +msgstr "tipo de archivo no definido para «%s»" + +#: file_ops.c:173 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "acción no válida (CREATE) para archivo regular" + +#: file_ops.c:200 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "no se pudo eliminar el archivo «%s»: %m" + +#: file_ops.c:218 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "no se pudo abrir el archivo «%s» para truncarlo: %m" + +#: file_ops.c:222 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "no se pudo truncar el archivo «%s» a %u: %m" + +#: file_ops.c:238 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" + +#: file_ops.c:252 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "no se pudo eliminar el directorio «%s»: %m" + +#: file_ops.c:266 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "no se pudo crear el link simbólico en «%s»: %m" + +#: file_ops.c:280 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "no se pudo eliminar el enlace simbólico «%s»: %m" + +#: file_ops.c:326 file_ops.c:330 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" + +#: file_ops.c:341 local_source.c:107 parsexlog.c:346 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: file_ops.c:344 parsexlog.c:348 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" + +#: file_ops.c:388 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: file_ops.c:446 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" + +#: file_ops.c:449 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "la ruta «%s» del enlace simbólico es demasiado larga" + +#: file_ops.c:464 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "«%s» es un link simbólico, pero los links simbólicos no están soportados en esta plataforma" + +#: file_ops.c:471 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" + +#: file_ops.c:475 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: filemap.c:237 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "el archivo de datos «%s» en el origen no es un archivo regular" + +#: filemap.c:242 filemap.c:275 +#, c-format +msgid "duplicate source file \"%s\"" +msgstr "archivo origen duplicado «%s»" + +#: filemap.c:330 +#, c-format +msgid "unexpected page modification for non-regular file \"%s\"" +msgstr "modificación de página inesperada para el archivo no regular «%s»" + +#: filemap.c:680 filemap.c:774 +#, c-format +msgid "unknown file type for \"%s\"" +msgstr "tipo de archivo desconocido para «%s»" + +#: filemap.c:707 +#, c-format +msgid "file \"%s\" is of different type in source and target" +msgstr "el archivo «%s» tiene un tipo diferente en el origen y en el destino" + +#: filemap.c:779 +#, c-format +msgid "could not decide what to do with file \"%s\"" +msgstr "no se pudo decidir qué hacer con el archivo «%s»" + +#: libpq_source.c:128 +#, c-format +msgid "could not clear search_path: %s" +msgstr "no se pudo limpiar search_path: %s" + +#: libpq_source.c:139 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "full_page_writes debe estar activado en el servidor de origen" + +#: libpq_source.c:150 +#, c-format +msgid "could not prepare statement to fetch file contents: %s" +msgstr "no se pudo preparar sentencia para obtener el contenido del archivo: %s" + +#: libpq_source.c:169 +#, c-format +msgid "error running query (%s) on source server: %s" +msgstr "error ejecutando consulta (%s) en el servidor de origen: %s" + +#: libpq_source.c:174 +#, c-format +msgid "unexpected result set from query" +msgstr "conjunto de resultados inesperados de la consulta" + +#: libpq_source.c:196 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "error ejecutando consulta (%s) en el servidor de origen: %s" + +#: libpq_source.c:217 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "resultado «%s» no reconocido para la ubicación de inserción WAL actual" + +#: libpq_source.c:268 +#, c-format +msgid "could not fetch file list: %s" +msgstr "no se pudo obtener el listado de archivos: %s" + +#: libpq_source.c:273 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "conjunto de resultados inesperado mientras se obtenía el listado de archivos" + +#: libpq_source.c:435 +#, c-format +msgid "could not send query: %s" +msgstr "no se pudo enviar la consulta: %s" + +#: libpq_source.c:438 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "no se pudo establecer la coneción libpq a modo «single row»" + +#: libpq_source.c:468 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "resultados inesperados mientras se obtenían archivos remotos: %s" + +#: libpq_source.c:473 +#, c-format +msgid "received more data chunks than requested" +msgstr "se recibieron más trozos de datos que los solicitados" + +#: libpq_source.c:477 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "tamaño del conjunto de resultados inesperado mientras se obtenían archivos remotos" + +#: libpq_source.c:483 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "tipos de dato inesperados en el conjunto de resultados mientras se obtenían archivos remotos: %u %u %u" + +#: libpq_source.c:491 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "formato de resultados inesperado mientras se obtenían archivos remotos" + +#: libpq_source.c:497 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "valores nulos inesperados en el resultado mientras se obtenían archivos remotos" + +#: libpq_source.c:501 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "largo del resultado inesperado mientras se obtenían los archivos remotos" + +#: libpq_source.c:534 +#, c-format +msgid "received data for file \"%s\", when requested for \"%s\"" +msgstr "se recibieron datos para el archivo «%s», cuando se solicitó para «%s»" + +#: libpq_source.c:538 +#, c-format +msgid "received data at offset %lld of file \"%s\", when requested for offset %lld" +msgstr "se recibieron datos en la posición %lld del archivo «%s», cuando se solicitó para la posición %lld" + +#: libpq_source.c:550 +#, c-format +msgid "received more than requested for file \"%s\"" +msgstr "se recibió más de lo solicitado para el archivo «%s»" + +#: libpq_source.c:563 +#, c-format +msgid "unexpected number of data chunks received" +msgstr "se recibió un número inesperado de trozos de datos" + +#: libpq_source.c:606 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "no se pudo obtener el archivo remoto «%s»: %s" + +#: libpq_source.c:611 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "conjunto de resultados inesperado mientras se obtenía el archivo remoto «%s»" + +#: local_source.c:86 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "no se pudo abrir el archivo de origen «%s»: %m" + +#: local_source.c:90 +#, c-format +msgid "could not seek in source file: %m" +msgstr "no se pudo posicionar en archivo de origen: %m" + +#: local_source.c:109 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "EOF inesperado mientras se leía el archivo «%s»" + +#: local_source.c:116 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" + +#: parsexlog.c:89 parsexlog.c:142 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "no se pudo leer el registro WAL en %X/%X: %s" + +#: parsexlog.c:93 parsexlog.c:145 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "no se pudo leer el registro WAL en %X/%X" + +#: parsexlog.c:208 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "no se pudo encontrar el registro WAL anterior en %X/%X: %s" + +#: parsexlog.c:212 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "no se pudo encontrar el registro WAL anterior en %X/%X" + +#: parsexlog.c:337 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "no se pudo posicionar (seek) el archivo «%s»: %m" + +#: parsexlog.c:429 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "el registro WAL modifica una relación, pero el tipo de registro no es reconocido lsn: %X/%X, rmgr: %s, info: %02X" + +#: pg_rewind.c:84 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s resincroniza un cluster PostgreSQL con otra copia del cluster.\n" +"\n" + +#: pg_rewind.c:85 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Empleo:\n" +" %s [OPCION]...\n" +"\n" + +#: pg_rewind.c:86 +#, c-format +msgid "Options:\n" +msgstr "Opciones:\n" + +#: pg_rewind.c:87 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal utilizar restore_command de la configuración\n" +" de destino para obtener archivos WAL\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=DIRECTORIO directorio de datos existente a modificar\n" + +#: pg_rewind.c:90 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr " --source-pgdata=DIRECTORIO directorio de datos de origen a sincronizar\n" + +#: pg_rewind.c:91 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=CONN servidor de origen a sincronizar\n" + +#: pg_rewind.c:92 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run detener antes de modificar nada\n" + +#: pg_rewind.c:93 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress escribir mensajes de progreso\n" + +#: pg_rewind.c:96 +#, c-format +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf escribe configuración para replicación\n" +" (requiere --source-server)\n" + +#: pg_rewind.c:98 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug escribir muchos mensajes de depuración\n" + +#: pg_rewind.c:99 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr "" +" --no-ensure-shutdown no corregir automáticamente un apagado\n" +" no-limpio\n" + +#: pg_rewind.c:100 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: pg_rewind.c:101 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: pg_rewind.c:102 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_rewind.c:103 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_rewind.c:164 pg_rewind.c:213 pg_rewind.c:220 pg_rewind.c:227 +#: pg_rewind.c:234 pg_rewind.c:242 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_rewind.c:212 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "no se especificó origen (--source-pgdata o --source-server)" + +#: pg_rewind.c:219 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "sólo uno de --source-pgdata o --source-server puede ser especificado" + +#: pg_rewind.c:226 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "no se especificó directorio de datos de destino (--target-pgdata)" + +#: pg_rewind.c:233 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "no se especificó información de servidor de origen (--source-server) para --write-recovery-conf" + +#: pg_rewind.c:240 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_rewind.c:255 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "no puede ser ejecutado por «root»" + +#: pg_rewind.c:256 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "Debe ejecutar %s con el superusuario de PostgreSQL.\n" + +#: pg_rewind.c:267 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "no se pudo obtener los permisos del directorio «%s»: %m" + +#: pg_rewind.c:287 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_rewind.c:290 +#, c-format +msgid "connected to server" +msgstr "conectado al servidor" + +#: pg_rewind.c:337 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "el cluster de origen y destino están en el mismo timeline" + +#: pg_rewind.c:346 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "servidores divergieron en la posición de WAL %X/%X en el timeline %u" + +#: pg_rewind.c:394 +#, c-format +msgid "no rewind required" +msgstr "no se requiere rebobinar" + +#: pg_rewind.c:403 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "rebobinando desde el último checkpoint común en %X/%X en el timeline %u" + +#: pg_rewind.c:413 +#, c-format +msgid "reading source file list" +msgstr "leyendo la lista de archivos de origen" + +#: pg_rewind.c:417 +#, c-format +msgid "reading target file list" +msgstr "leyendo la lista de archivos de destino" + +#: pg_rewind.c:426 +#, c-format +msgid "reading WAL in target" +msgstr "leyendo WAL en destino" + +#: pg_rewind.c:447 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "se necesitan copiar %lu MB (tamaño total de directorio de origen es %lu MB)" + +#: pg_rewind.c:465 +#, c-format +msgid "syncing target data directory" +msgstr "sincronizando directorio de datos de destino" + +#: pg_rewind.c:481 +#, c-format +msgid "Done!" +msgstr "¡Listo!" + +#: pg_rewind.c:564 +#, c-format +msgid "no action decided for file \"%s\"" +msgstr "no se decidió una acción para el archivo «%s»" + +#: pg_rewind.c:596 +#, c-format +msgid "source system was modified while pg_rewind was running" +msgstr "el sistema origen fue modificado mientras pg_rewind estaba en ejecución" + +#: pg_rewind.c:600 +#, c-format +msgid "creating backup label and updating control file" +msgstr "creando etiqueta de respaldo y actualizando archivo de control" + +#: pg_rewind.c:650 +#, c-format +msgid "source system was in unexpected state at end of rewind" +msgstr "el sistema origen estaba en un estado inesperado al final del rebobinado" + +#: pg_rewind.c:681 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "clusters de origen y destino son de sistemas diferentes" + +#: pg_rewind.c:689 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "los clusters no son compatibles con esta versión de pg_rewind" + +#: pg_rewind.c:699 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "el servidor de destino necesita tener sumas de verificación de datos o «wal_log_hints» activados" + +#: pg_rewind.c:710 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "el directorio de destino debe estar apagado limpiamente" + +#: pg_rewind.c:720 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "el directorio de origen debe estar apagado limpiamente" + +#: pg_rewind.c:772 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s kB (%d%%) copiados" + +#: pg_rewind.c:835 +#, c-format +msgid "invalid control file" +msgstr "archivo de control no válido" + +#: pg_rewind.c:919 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "no se pudo encontrar un ancestro común en el timeline de los clusters de origen y destino" + +#: pg_rewind.c:960 +#, c-format +msgid "backup label buffer too small" +msgstr "el búfer del backup label es demasiado pequeño" + +#: pg_rewind.c:983 +#, c-format +msgid "unexpected control file CRC" +msgstr "CRC de archivo de control inesperado" + +#: pg_rewind.c:995 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "tamaño del archivo de control %d inesperado, se esperaba %d" + +#: pg_rewind.c:1004 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d byte" +msgstr[1] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d bytes" + +#: pg_rewind.c:1043 pg_rewind.c:1101 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%s necesita el programa «%s», pero no pudo encontrarlo en el mismo\n" +"directorio que «%s».\n" +"Verifique su instalación." + +#: pg_rewind.c:1048 pg_rewind.c:1106 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"El programa «%s» fue encontrado por «%s»,\n" +"pero no es de la misma versión que %s.\n" +"Verifique su instalación." + +#: pg_rewind.c:1069 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "restore_command no está definido en el clúster de destino" + +#: pg_rewind.c:1112 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "ejecutando «%s» en el servidor de destino para completar la recuperación de caídas" + +#: pg_rewind.c:1132 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "el modo «single-user» en el servidor de destino falló" + +#: pg_rewind.c:1133 +#, c-format +msgid "Command was: %s" +msgstr "La orden era: % s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "error de sintaxis en archivo de historia: %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Se esperaba un ID numérico de timeline." + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Se esperaba una ubicación de punto de cambio del «write-ahead log»." + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "datos no válidos en archivo de historia: %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "IDs de timeline deben ser una secuencia creciente." + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "datos no válidos en archivo de historia" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "IDs de timeline deben ser menores que el ID de timeline del hijo." + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "posición de registro no válida en %X/%X" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "contrecord solicitado por %X/%X" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "largo de registro no válido en %X/%X: se esperaba %u, se obtuvo %u" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "largo de registro %u en %X/%X demasiado largo" + +#: xlogreader.c:453 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "no hay bandera de contrecord en %X/%X" + +#: xlogreader.c:466 +#, c-format +msgid "invalid contrecord length %u (expected %lld) at %X/%X" +msgstr "largo de contrecord %u no válido (se esperaba %lld) en %X/%X" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "ID de gestor de recursos %u no válido en %X/%X" + +#: xlogreader.c:716 xlogreader.c:732 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "registro con prev-link %X/%X incorrecto en %X/%X" + +#: xlogreader.c:768 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "suma de verificación de los datos del gestor de recursos incorrecta en el registro en %X/%X" + +#: xlogreader.c:805 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "número mágico %04X no válido en archivo %s, posición %u" + +#: xlogreader.c:819 xlogreader.c:860 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "info bits %04X no válidos en archivo %s, posición %u" + +#: xlogreader.c:834 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "archivo WAL es de un sistema de bases de datos distinto: identificador de sistema en archivo WAL es %llu, identificador en pg_control es %llu" + +#: xlogreader.c:842 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "archivo WAL es de un sistema de bases de datos distinto: tamaño de segmento incorrecto en cabecera de paǵina" + +#: xlogreader.c:848 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "archivo WAL es de un sistema de bases de datos distinto: XLOG_BLCKSZ incorrecto en cabecera de paǵina" + +#: xlogreader.c:879 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "pageaddr %X/%X inesperado en archivo %s, posición %u" + +#: xlogreader.c:904 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "ID de timeline %u fuera de secuencia (después de %u) en archivo %s, posición %u" + +#: xlogreader.c:1249 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %u fuera de orden en %X/%X" + +#: xlogreader.c:1271 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA está definido, pero no hay datos en %X/%X" + +#: xlogreader.c:1278 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA no está definido, pero el largo de los datos es %u en %X/%X" + +#: xlogreader.c:1314 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE está definido, pero posición del agujero es %u largo %u largo de imagen %u en %X/%X" + +#: xlogreader.c:1330 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE no está definido, pero posición del agujero es %u largo %u en %X/%X" + +#: xlogreader.c:1345 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED definido, pero largo de imagen de bloque es %u en %X/%X" + +#: xlogreader.c:1360 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "ni BKPIMAGE_HAS_HOLE ni BKPIMAGE_IS_COMPRESSED está definido, pero largo de imagen de bloque es %u en %X/%X" + +#: xlogreader.c:1376 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL está definido, pero no hay «rel» anterior en %X/%X " + +#: xlogreader.c:1388 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "block_id %u no válido en %X/%X" + +#: xlogreader.c:1475 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "registro con largo no válido en %X/%X" + +#: xlogreader.c:1564 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "imagen comprimida no válida en %X/%X, bloque %d" + +#~ msgid "unexpected result while sending file list: %s" +#~ msgstr "resultados inesperados mientras se enviaba el listado de archivos: %s" + +#~ msgid "could not send end-of-COPY: %s" +#~ msgstr "no se pudo enviar fin-de-COPY: %s" + +#~ msgid "could not send file list: %s" +#~ msgstr "no se pudo enviar el listado de archivos: %s" + +#~ msgid "could not send COPY data: %s" +#~ msgstr "no se pudo enviar datos COPY: %s" + +#~ msgid "source server must not be in recovery mode" +#~ msgstr "el servidor de origen no debe estar en modo de recuperación" + +#~ msgid "could not connect to server: %s" +#~ msgstr "no se pudo conectar al servidor: %s" + +#~ msgid "source file list is empty" +#~ msgstr "el listado de archivos de origen está vacío" + +#~ msgid "\"%s\" is not a regular file" +#~ msgstr "«%s» no es un archivo regular" + +#~ msgid "\"%s\" is not a symbolic link" +#~ msgstr "«%s» no es un link simbólico" + +#~ msgid "\"%s\" is not a directory" +#~ msgstr "«%s» no es un directorio" diff --git a/src/bin/pg_rewind/po/fr.po b/src/bin/pg_rewind/po/fr.po new file mode 100644 index 000000000000..492eacca9ccd --- /dev/null +++ b/src/bin/pg_rewind/po/fr.po @@ -0,0 +1,1211 @@ +# LANGUAGE message translation file for pg_rewind +# Copyright (C) 2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_rewind (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-28 00:49+0000\n" +"PO-Revision-Date: 2021-05-28 15:23+0200\n" +"Last-Translator: Guillaume Lelarge \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.3\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "n'a pas pu charger la bibliothèque « %s » : code d'erreur %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "ne peut pas créer les jetons restreints sur cette plateforme : code d'erreur %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "n'a pas pu ouvrir le jeton du processus : code d'erreur %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "n'a pas pu allouer les SID : code d'erreur %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "n'a pas pu créer le jeton restreint : code d'erreur %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "n'a pas pu démarrer le processus pour la commande « %s » : code d'erreur %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "n'a pas pu ré-exécuter le jeton restreint : code d'erreur %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "n'a pas pu récupérer le code de statut du sous-processus : code d'erreur %lu" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "cannot use restore_command with %%r placeholder" +msgstr "ne peut pas utiliser restore_command avec le joker %%r" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lld instead of %lld" +msgstr "taille de fichier inattendu pour « %s » : %lld au lieu de %lld" + +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » à partir de l'archive : %m" + +#: ../../fe_utils/archive.c:97 file_ops.c:417 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "n'a pas pu tester le fichier « %s » : %m" + +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed: %s" +msgstr "échec de la restore_command : %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "n'a pas pu restaurer le fichier « %s » à partir de l'archive" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:77 parsexlog.c:135 +#: parsexlog.c:195 +#, c-format +msgid "out of memory" +msgstr "mémoire épuisée" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:308 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier « %s » : %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "n'a pas pu écrire dans le fichier « %s » : %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "n'a pas pu créer le fichier « %s » : %m" + +#: file_ops.c:67 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier cible « %s » : %m" + +#: file_ops.c:81 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "n'a pas pu fermer le fichier cible « %s » : %m" + +#: file_ops.c:101 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "n'a pas pu chercher dans le fichier cible « %s » : %m" + +#: file_ops.c:117 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "impossible d'écrire le fichier « %s » : %m" + +#: file_ops.c:150 file_ops.c:177 +#, c-format +msgid "undefined file type for \"%s\"" +msgstr "type de fichier non défini pour « %s »" + +#: file_ops.c:173 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "action (CREATE) invalide pour le fichier régulier" + +#: file_ops.c:200 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier « %s » : %m" + +#: file_ops.c:218 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » pour le troncage : %m" + +#: file_ops.c:222 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "n'a pas pu tronquer le fichier « %s » en %u : %m" + +#: file_ops.c:238 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "n'a pas pu créer le répertoire « %s » : %m" + +#: file_ops.c:252 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "n'a pas pu supprimer le répertoire « %s » : %m" + +#: file_ops.c:266 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "n'a pas pu créer le lien symbolique à « %s » : %m" + +#: file_ops.c:280 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "n'a pas pu supprimer le lien symbolique « %s » : %m" + +#: file_ops.c:326 file_ops.c:330 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %m" + +#: file_ops.c:341 local_source.c:107 parsexlog.c:346 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "n'a pas pu lire le fichier « %s » : %m" + +#: file_ops.c:344 parsexlog.c:348 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %zu" + +#: file_ops.c:388 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" + +#: file_ops.c:446 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" + +#: file_ops.c:449 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "la cible du lien symbolique « %s » est trop long" + +#: file_ops.c:464 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "« %s » est un lien symbolique mais les liens symboliques ne sont pas supportés sur cette plateforme" + +#: file_ops.c:471 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "n'a pas pu lire le répertoire « %s » : %m" + +#: file_ops.c:475 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "n'a pas pu fermer le répertoire « %s » : %m" + +#: filemap.c:237 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "le fichier de données « %s » en source n'est pas un fichier standard" + +#: filemap.c:242 filemap.c:275 +#, c-format +msgid "duplicate source file \"%s\"" +msgstr "fichier source « %s » dupliqué" + +#: filemap.c:330 +#, c-format +msgid "unexpected page modification for non-regular file \"%s\"" +msgstr "modification inattendue de page pour le fichier non standard « %s »" + +#: filemap.c:680 filemap.c:774 +#, c-format +msgid "unknown file type for \"%s\"" +msgstr "type de fichier inconnu pour « %s »" + +#: filemap.c:707 +#, c-format +msgid "file \"%s\" is of different type in source and target" +msgstr "le fichier « %s » a un type différent pour la source et la cible" + +#: filemap.c:779 +#, c-format +msgid "could not decide what to do with file \"%s\"" +msgstr "n'a pas pu décider que faire avec le fichier « %s » : %m" + +#: libpq_source.c:128 +#, c-format +msgid "could not clear search_path: %s" +msgstr "n'a pas pu effacer search_path : %s" + +#: libpq_source.c:139 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "full_page_writes doit être activé sur le serveur source" + +#: libpq_source.c:150 +#, c-format +msgid "could not prepare statement to fetch file contents: %s" +msgstr "n'a pas pu préparer l'instruction pour récupérer le contenu du fichier : %s" + +#: libpq_source.c:169 +#, c-format +msgid "error running query (%s) on source server: %s" +msgstr "erreur lors de l'exécution de la requête (%s) sur le serveur source : %s" + +#: libpq_source.c:174 +#, c-format +msgid "unexpected result set from query" +msgstr "ensemble de résultats inattendu provenant de la requête" + +#: libpq_source.c:196 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "erreur lors de l'exécution de la requête (%s) dans le serveur source : %s" + +#: libpq_source.c:217 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "résultat non reconnu « %s » pour l'emplacement d'insertion actuel dans les WAL" + +#: libpq_source.c:268 +#, c-format +msgid "could not fetch file list: %s" +msgstr "n'a pas pu récupérer la liste des fichiers : %s" + +#: libpq_source.c:273 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "ensemble de résultats inattendu lors de la récupération de la liste des fichiers" + +#: libpq_source.c:435 +#, c-format +msgid "could not send query: %s" +msgstr "n'a pas pu envoyer la requête : %s" + +#: libpq_source.c:438 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "n'a pas pu configurer la connexion libpq en mode ligne seule" + +#: libpq_source.c:468 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "résultat inattendu lors de la récupération des fichiers cibles : %s" + +#: libpq_source.c:473 +#, c-format +msgid "received more data chunks than requested" +msgstr "a reçu plus de morceaux de données que demandé" + +#: libpq_source.c:477 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "taille inattendue de l'ensemble de résultats lors de la récupération des fichiers distants" + +#: libpq_source.c:483 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "types de données inattendus dans l'ensemble de résultats lors de la récupération des fichiers distants : %u %u %u" + +#: libpq_source.c:491 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "format de résultat inattendu lors de la récupération des fichiers distants" + +#: libpq_source.c:497 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "valeurs NULL inattendues dans le résultat lors de la récupération des fichiers distants" + +#: libpq_source.c:501 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "longueur de résultats inattendu lors de la récupération des fichiers distants" + +#: libpq_source.c:534 +#, c-format +msgid "received data for file \"%s\", when requested for \"%s\"" +msgstr "a reçu des données du fichier « %s » alors que « %s » était demandé" + +#: libpq_source.c:538 +#, c-format +msgid "received data at offset %lld of file \"%s\", when requested for offset %lld" +msgstr "a reçu des données au décalage %lld du fichier « %s » alors que le décalage %lld était demandé" + +#: libpq_source.c:550 +#, c-format +msgid "received more than requested for file \"%s\"" +msgstr "a reçu plus que demandé pour le fichier « %s »" + +#: libpq_source.c:563 +#, c-format +msgid "unexpected number of data chunks received" +msgstr "nombre de morceaux de données reçus inattendu" + +#: libpq_source.c:606 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "n'a pas pu récupérer le fichier distant « %s » : %s" + +#: libpq_source.c:611 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "ensemble de résultats inattendu lors de la récupération du fichier distant « %s »" + +#: local_source.c:86 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier source « %s » : %m" + +#: local_source.c:90 +#, c-format +msgid "could not seek in source file: %m" +msgstr "n'a pas pu chercher dans le fichier source : %m" + +#: local_source.c:109 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "EOF inattendu lors de la lecture du fichier « %s »" + +#: local_source.c:116 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "n'a pas pu fermer le fichier « %s » : %m" + +#: parsexlog.c:89 parsexlog.c:142 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "n'a pas pu lire l'enregistrement WAL précédent à %X/%X : %s" + +#: parsexlog.c:93 parsexlog.c:145 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "n'a pas pu lire l'enregistrement WAL précédent à %X/%X" + +#: parsexlog.c:208 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "n'a pas pu trouver l'enregistrement WAL précédent à %X/%X : %s" + +#: parsexlog.c:212 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "n'a pas pu trouver l'enregistrement WAL précédent à %X/%X" + +#: parsexlog.c:337 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "n'a pas pu parcourir le fichier « %s » : %m" + +#: parsexlog.c:429 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "l'enregistrement WAL modifie une relation mais le type d'enregistrement n'est pas reconnu: lsn : %X/%X, rmgr : %s, info : %02X" + +#: pg_rewind.c:84 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s resynchronise une instance PostgreSQL avec une autre copie de l'instance.\n" +"\n" + +#: pg_rewind.c:85 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Usage :\n" +" %s [OPTION]...\n" +"\n" + +#: pg_rewind.c:86 +#, c-format +msgid "Options:\n" +msgstr "Options :\n" + +#: pg_rewind.c:87 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal utilise restore_command pour la configuration cible\n" +" de récupération des fichiers WAL des archives\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=RÉPERTOIRE répertoire de données existant à modifier\n" + +#: pg_rewind.c:90 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr " --source-pgdata=RÉPERTOIRE répertoire des données source pour la synchronisation\n" + +#: pg_rewind.c:91 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=CONNSTR serveur source pour la synchronisation\n" + +#: pg_rewind.c:92 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run arrête avant de modifier quoi que ce soit\n" + +#: pg_rewind.c:93 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr " -N, --nosync n'attend pas que les modifications soient proprement écrites sur disque\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress écrit les messages de progression\n" + +#: pg_rewind.c:96 +#, c-format +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf écrit la configuration pour la réplication\n" +" (requiert --source-server)\n" +"\n" + +#: pg_rewind.c:98 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug écrit beaucoup de messages de débogage\n" + +#: pg_rewind.c:99 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr " --no-ensure-shutdown ne corrige pas automatiquement l'arrêt non propre\n" + +#: pg_rewind.c:100 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version, puis quitte\n" + +#: pg_rewind.c:101 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide, puis quitte\n" + +#: pg_rewind.c:102 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapporter les bogues à <%s>.\n" + +#: pg_rewind.c:103 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil %s : <%s>\n" + +#: pg_rewind.c:164 pg_rewind.c:213 pg_rewind.c:220 pg_rewind.c:227 +#: pg_rewind.c:234 pg_rewind.c:242 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: pg_rewind.c:212 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "aucune source indiquée (--source-pgdata ou --source-server)" + +#: pg_rewind.c:219 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "une seule des options --source-pgdata et --source-server peut être indiquée" + +#: pg_rewind.c:226 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "aucun répertoire de données cible indiqué (--target-pgdata)" + +#: pg_rewind.c:233 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "aucune information sur le serveur source (--source-server) indiquée pour --write-recovery-conf" + +#: pg_rewind.c:240 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" + +#: pg_rewind.c:255 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "ne peut pas être exécuté par « root »" + +#: pg_rewind.c:256 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "Vous devez exécuter %s en tant que super-utilisateur PostgreSQL.\n" + +#: pg_rewind.c:267 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "n'a pas pu lire les droits du répertoire « %s » : %m" + +#: pg_rewind.c:287 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_rewind.c:290 +#, c-format +msgid "connected to server" +msgstr "connecté au serveur" + +#: pg_rewind.c:337 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "les instances source et cible sont sur la même ligne de temps" + +#: pg_rewind.c:346 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "les serveurs ont divergé à la position %X/%X des WAL sur la timeline %u" + +#: pg_rewind.c:394 +#, c-format +msgid "no rewind required" +msgstr "pas de retour en arrière requis" + +#: pg_rewind.c:403 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "retour en arrière depuis le dernier checkpoint commun à %X/%X sur la ligne de temps %u" + +#: pg_rewind.c:413 +#, c-format +msgid "reading source file list" +msgstr "lecture de la liste des fichiers sources" + +#: pg_rewind.c:417 +#, c-format +msgid "reading target file list" +msgstr "lecture de la liste des fichiers cibles" + +#: pg_rewind.c:426 +#, c-format +msgid "reading WAL in target" +msgstr "lecture du WAL dans la cible" + +#: pg_rewind.c:447 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "a besoin de copier %lu Mo (la taille totale du répertoire source est %lu Mo)" + +#: pg_rewind.c:465 +#, c-format +msgid "syncing target data directory" +msgstr "synchronisation du répertoire des données cible" + +#: pg_rewind.c:481 +#, c-format +msgid "Done!" +msgstr "Terminé !" + +#: pg_rewind.c:564 +#, c-format +msgid "no action decided for file \"%s\"" +msgstr "aucune action décidée pour le fichier « %s »" + +#: pg_rewind.c:596 +#, c-format +msgid "source system was modified while pg_rewind was running" +msgstr "le système source a été modifié alors que pg_rewind était en cours d'exécution" + +#: pg_rewind.c:600 +#, c-format +msgid "creating backup label and updating control file" +msgstr "création du fichier backup_label et mise à jour du fichier contrôle" + +#: pg_rewind.c:650 +#, c-format +msgid "source system was in unexpected state at end of rewind" +msgstr "le système source était dans un état inattendu en fin de rewind" + +#: pg_rewind.c:681 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "les instances source et cible proviennent de systèmes différents" + +#: pg_rewind.c:689 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "les instances ne sont pas compatibles avec cette version de pg_rewind" + +#: pg_rewind.c:699 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "le serveur cible doit soit utiliser les sommes de contrôle sur les données soit avoir wal_log_hints configuré à on" + +#: pg_rewind.c:710 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "le serveur cible doit être arrêté proprement" + +#: pg_rewind.c:720 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "le répertoire de données source doit être arrêté proprement" + +#: pg_rewind.c:772 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s Ko (%d%%) copiés" + +#: pg_rewind.c:835 +#, c-format +msgid "invalid control file" +msgstr "fichier de contrôle invalide" + +#: pg_rewind.c:919 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "n'a pas pu trouver l'ancêtre commun des lignes de temps des instances source et cible" + +#: pg_rewind.c:960 +#, c-format +msgid "backup label buffer too small" +msgstr "tampon du label de sauvegarde trop petit" + +#: pg_rewind.c:983 +#, c-format +msgid "unexpected control file CRC" +msgstr "CRC inattendu pour le fichier de contrôle" + +#: pg_rewind.c:995 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "taille %d inattendue du fichier de contrôle, %d attendu" + +#: pg_rewind.c:1004 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octet" +msgstr[1] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octets" + +#: pg_rewind.c:1043 pg_rewind.c:1101 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Le programme « %s » est nécessaire pour %s, mais n'a pas été trouvé\n" +"dans le même répertoire que « %s ».\n" +"Vérifiez votre installation." + +#: pg_rewind.c:1048 pg_rewind.c:1106 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Le programme « %s » a été trouvé par « %s »\n" +"mais n'est pas de la même version que %s.\n" +"Vérifiez votre installation." + +#: pg_rewind.c:1069 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "restore_command n'est pas configuré sur l'instance cible" + +#: pg_rewind.c:1112 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "exécution de « %s » pour terminer la restauration après crash du serveur cible" + +#: pg_rewind.c:1132 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "le mot simple-utilisateur de postgres a échoué pour l'instance cible" + +#: pg_rewind.c:1133 +#, c-format +msgid "Command was: %s" +msgstr "La commande était : %s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "erreur de syntaxe dans le fichier historique : %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Attendait un identifiant timeline numérique." + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Attendait un emplacement de bascule de journal de transactions." + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "données invalides dans le fichier historique : %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Les identifiants timeline doivent être en ordre croissant." + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "données invalides dans le fichier historique" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "" +"Les identifiants timeline doivent être plus petits que les enfants des\n" +"identifiants timeline." + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "décalage invalide de l'enregistrement %X/%X" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "« contrecord » est requis par %X/%X" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "longueur invalide de l'enregistrement à %X/%X : voulait %u, a eu %u" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "longueur trop importante de l'enregistrement %u à %X/%X" + +#: xlogreader.c:453 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "il n'existe pas de drapeau contrecord à %X/%X" + +#: xlogreader.c:466 +#, c-format +msgid "invalid contrecord length %u (expected %lld) at %X/%X" +msgstr "longueur %u invalide du contrecord (%lld attendu) à %X/%X" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "identifiant du gestionnaire de ressources invalide %u à %X/%X" + +#: xlogreader.c:716 xlogreader.c:732 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "enregistrement avec prev-link %X/%X incorrect à %X/%X" + +#: xlogreader.c:768 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "" +"somme de contrôle des données du gestionnaire de ressources incorrecte à\n" +"l'enregistrement %X/%X" + +#: xlogreader.c:805 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "numéro magique invalide %04X dans le segment %s, décalage %u" + +#: xlogreader.c:819 xlogreader.c:860 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "bits d'information %04X invalides dans le segment %s, décalage %u" + +#: xlogreader.c:834 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "le fichier WAL provient d'un système différent : l'identifiant système de la base dans le fichier WAL est %llu, alors que l'identifiant système de la base dans pg_control est %llu" + +#: xlogreader.c:842 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "Le fichier WAL provient d'un système différent : taille invalide du segment dans l'en-tête de page" + +#: xlogreader.c:848 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "Le fichier WAL provient d'un système différent : XLOG_BLCKSZ invalide dans l'en-tête de page" + +#: xlogreader.c:879 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "pageaddr %X/%X inattendue dans le journal de transactions %s, segment %u" + +#: xlogreader.c:904 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "identifiant timeline %u hors de la séquence (après %u) dans le segment %s, décalage %u" + +#: xlogreader.c:1249 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %u désordonné à %X/%X" + +#: xlogreader.c:1271 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA configuré, mais aucune donnée inclus à %X/%X" + +#: xlogreader.c:1278 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA non configuré, mais la longueur des données est %u à %X/%X" + +#: xlogreader.c:1314 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE activé, mais décalage trou %u longueur %u longueur image bloc %u à %X/%X" + +#: xlogreader.c:1330 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE désactivé, mais décalage trou %u longueur %u à %X/%X" + +#: xlogreader.c:1345 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED configuré, mais la longueur de l'image du bloc est %u à %X/%X" + +#: xlogreader.c:1360 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "ni BKPIMAGE_HAS_HOLE ni BKPIMAGE_IS_COMPRESSED configuré, mais la longueur de l'image du bloc est %u à %X/%X" + +#: xlogreader.c:1376 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL configuré, mais pas de relation précédente à %X/%X" + +#: xlogreader.c:1388 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "block_id %u invalide à %X/%X" + +#: xlogreader.c:1475 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "enregistrement de longueur invalide à %X/%X" + +#: xlogreader.c:1564 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "image compressée invalide à %X/%X, bloc %d" + +#~ msgid "there is no contrecord flag at %X/%X reading %X/%X" +#~ msgstr "il n'existe pas de drapeau contrecord à %X/%X en lisant %X/%X" + +#~ msgid "invalid contrecord length %u at %X/%X reading %X/%X, expected %u" +#~ msgstr "longueur %u invalide du contrecord à %X/%X en lisant %X/%X, attendait %u" + +#~ msgid "\"%s\" is not a directory" +#~ msgstr "« %s » n'est pas un répertoire" + +#~ msgid "\"%s\" is not a symbolic link" +#~ msgstr "« %s » n'est pas un lien symbolique" + +#~ msgid "\"%s\" is not a regular file" +#~ msgstr "« %s » n'est pas un fichier standard" + +#~ msgid "source file list is empty" +#~ msgstr "la liste de fichiers sources est vide" + +#~ msgid "source server must not be in recovery mode" +#~ msgstr "le serveur source ne doit pas être en mode restauration" + +#~ msgid "could not send COPY data: %s" +#~ msgstr "n'a pas pu envoyer les données COPY : %s" + +#~ msgid "could not send file list: %s" +#~ msgstr "n'a pas pu envoyer la liste de fichiers : %s" + +#~ msgid "could not send end-of-COPY: %s" +#~ msgstr "n'a pas pu envoyer end-of-COPY : %s" + +#~ msgid "unexpected result while sending file list: %s" +#~ msgstr "résultat inattendu lors de l'envoi de la liste de fichiers : %s" + +#~ msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +#~ msgstr "%s : ATTENTION : ne peut pas créer les jetons restreints sur cette plateforme\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s : n'a pas pu ouvrir le jeton du processus : code d'erreur %lu\n" + +#~ msgid "%s: could not allocate SIDs: error code %lu\n" +#~ msgstr "%s : n'a pas pu allouer les SID : code d'erreur %lu\n" + +#~ msgid "%s: could not create restricted token: error code %lu\n" +#~ msgstr "%s : n'a pas pu créer le jeton restreint : code d'erreur %lu\n" + +#~ msgid "%s: could not start process for command \"%s\": error code %lu\n" +#~ msgstr "%s : n'a pas pu démarrer le processus pour la commande « %s » : code d'erreur %lu\n" + +#~ msgid "%s: could not re-execute with restricted token: error code %lu\n" +#~ msgstr "%s : n'a pas pu ré-exécuter le jeton restreint : code d'erreur %lu\n" + +#~ msgid "%s: could not get exit code from subprocess: error code %lu\n" +#~ msgstr "%s : n'a pas pu récupérer le code de statut du sous-processus : code d'erreur %lu\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "n'a pas pu ouvrir le répertoire « %s » : %s\n" + +#~ msgid "could not stat file \"%s\": %s\n" +#~ msgstr "n'a pas pu tester le fichier « %s » : %s\n" + +#~ msgid "could not read symbolic link \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le lien symbolique « %s » : %s\n" + +#~ msgid "symbolic link \"%s\" target is too long\n" +#~ msgstr "la cible du lien symbolique « %s » est trop long\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "could not close directory \"%s\": %s\n" +#~ msgstr "n'a pas pu fermer le répertoire « %s » : %s\n" + +#~ msgid "could not read file \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le fichier « %s » : %s\n" + +#~ msgid "could not close file \"%s\": %s\n" +#~ msgstr "n'a pas pu fermer le fichier « %s » : %s\n" + +#~ msgid " block %u\n" +#~ msgstr " bloc %u\n" + +#~ msgid "could not write file \"%s\": %s\n" +#~ msgstr "n'a pas pu écrire le fichier « %s » : %s\n" + +#~ msgid "could not remove file \"%s\": %s\n" +#~ msgstr "n'a pas pu supprimer le fichier « %s » : %s\n" + +#~ msgid "could not truncate file \"%s\" to %u: %s\n" +#~ msgstr "n'a pas pu tronquer le fichier « %s » à %u : %s\n" + +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "n'a pas pu créer le répertoire « %s » : %s\n" + +#~ msgid "could not remove directory \"%s\": %s\n" +#~ msgstr "n'a pas pu supprimer le répertoire « %s » : %s\n" + +#~ msgid "could not remove symbolic link \"%s\": %s\n" +#~ msgstr "n'a pas pu supprimer le lien symbolique « %s » : %s\n" + +#~ msgid "could not open file \"%s\" for reading: %s\n" +#~ msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %s\n" + +#~ msgid "entry \"%s\" excluded from source file list\n" +#~ msgstr "enregistrement « %s » exclus de la liste des fichiers sources\n" + +#~ msgid "entry \"%s\" excluded from target file list\n" +#~ msgstr "enregistrement « %s » exclus de la liste des fichiers cibles\n" + +#~ msgid "%s (%s)\n" +#~ msgstr "%s (%s)\n" + +#~ msgid "could not set up connection context: %s" +#~ msgstr "n'a pas pu initialiser le contexte de connexion : « %s »" + +#~ msgid "getting file chunks\n" +#~ msgstr "récupération des parties de fichier\n" + +#~ msgid "received null value for chunk for file \"%s\", file has been deleted\n" +#~ msgstr "a reçu une valeur NULL pour une partie du fichier « %s », le fichier a été supprimé\n" + +#~ msgid "fetched file \"%s\", length %d\n" +#~ msgstr "fichier récupéré « %s », longueur %d\n" + +#~ msgid "could not create temporary table: %s" +#~ msgstr "n'a pas pu créer la table temporaire : %s" + +#~ msgid "Failure, exiting\n" +#~ msgstr "Échec, sortie\n" + +#~ msgid "could not open file \"%s\": %s\n" +#~ msgstr "n'a pas pu ouvrir le fichier « %s » : %s\n" + +#~ msgid "could not seek in file \"%s\": %s\n" +#~ msgstr "n'a pas pu chercher dans le fichier « %s » : %s\n" + +#~ msgid "could not read from file \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le fichier « %s » : %s\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" + +#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu lire les droits sur le répertoire « %s » : %s\n" + +#~ msgid "Source timeline history:\n" +#~ msgstr "Historique de la ligne de temps source :\n" + +#~ msgid "Target timeline history:\n" +#~ msgstr "Historique de la ligne de temps cible :\n" + +#~ msgid "%d: %X/%X - %X/%X\n" +#~ msgstr "%d : %X/%X - %X/%X\n" + +#~ msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte\n" +#~ msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes\n" +#~ msgstr[0] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octet\n" +#~ msgstr[1] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octets\n" + +#~ msgid "" +#~ "The program \"initdb\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "Le programme « initdb » est nécessaire pour %s, mais n'a pas été trouvé\n" +#~ "dans le même répertoire que « %s ».\n" +#~ "Vérifiez votre installation.\n" + +#~ msgid "" +#~ "The program \"initdb\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "Le programme « initdb » a été trouvé par « %s », mais n'est pas de la même version\n" +#~ "que %s.\n" +#~ "Vérifiez votre installation.\n" + +#~ msgid "sync of target directory failed\n" +#~ msgstr "échec de la synchronisation du répertoire cible\n" + +#~ msgid "syntax error in history file: %s\n" +#~ msgstr "erreur de syntaxe dans le fichier historique : %s\n" + +#~ msgid "Expected a numeric timeline ID.\n" +#~ msgstr "Attendait un identifiant numérique de ligne de temps.\n" + +#~ msgid "Expected a write-ahead log switchpoint location.\n" +#~ msgstr "Attendait un emplacement de bascule de journal de transactions.\n" + +#~ msgid "invalid data in history file: %s\n" +#~ msgstr "données invalides dans le fichier historique : %s\n" + +#~ msgid "Timeline IDs must be in increasing sequence.\n" +#~ msgstr "Les identifiants de ligne de temps doivent être dans une séquence croissante.\n" + +#~ msgid "Timeline IDs must be less than child timeline's ID.\n" +#~ msgstr "Les identifiants de ligne de temps doivent être inférieurs à l'identifiant de la ligne de temps enfant.\n" + +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "le fichier WAL provient d'un système différent : XLOG_SEG_SIZE invalide dans l'en-tête de page" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapporter les bogues à .\n" + +#~ msgid "" +#~ "The program \"%s\" was found by \"%s\" but was\n" +#~ "not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « %s » a été trouvé par « %s » mais n'était pas de la même version\n" +#~ "que %s.\n" +#~ "Vérifiez votre installation." + +#~ msgid "" +#~ "The program \"%s\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « %s » est nécessaire pour %s, mais n'a pas été trouvé\n" +#~ "dans le même répertoire que « %s ».\n" +#~ "Vérifiez votre installation." + +#~ msgid "" +#~ "The program \"postgres\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « postgres » a été trouvé par « %s » mais n'est pas de la même\n" +#~ "version que « %s ».\n" +#~ "Vérifiez votre installation." + +#~ msgid "" +#~ "The program \"postgres\" is needed by %s but was not found in the\n" +#~ "same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Le programme « postgres » est nécessaire à %s mais n'a pas été trouvé dans\n" +#~ "le même répertoire que « %s ».\n" +#~ "Vérifiez votre installation." + +#~ msgid "could not connect to server: %s" +#~ msgstr "n'a pas pu se connecter au serveur : %s" + +#~ msgid "received data at offset " +#~ msgstr "a reçu des données au décalage " diff --git a/src/bin/pg_rewind/po/ja.po b/src/bin/pg_rewind/po/ja.po new file mode 100644 index 000000000000..bfaea375ec53 --- /dev/null +++ b/src/bin/pg_rewind/po/ja.po @@ -0,0 +1,1070 @@ +# Japanese message translation file for pg_rewind +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_rewind (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:55+0900\n" +"PO-Revision-Date: 2020-08-21 23:25+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.13\n" +"Plural-Forms: nplurals=2; plural=n!=1;\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ポインタを複製できません(内部エラー)\n" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "ライブラリ\"%s\"をロードできませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "このプラットフォームでは制限付きトークンを生成できません: エラーコード %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "プロセストークンをオープンできませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SIDを割り当てられませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "制限付きトークンを作成できませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\"コマンドのプロセスを起動できませんでした: エラーコード %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "制限付きトークンで再実行できませんでした: %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "サブプロセスの終了コードを取得できませんでした。: エラーコード %lu" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "could not use restore_command with %%r alias" +msgstr "%%rエイリアスを含むrestore_commandは使用できません" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lu instead of %lu" +msgstr "予期しない\"%1$s\"のサイズ: %3$lu ではなく %2$lu" + +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "アーカイブからリストアされたファイル\"%s\"のオープンに失敗しました: %m" + +#: ../../fe_utils/archive.c:97 copy_fetch.c:88 filemap.c:208 filemap.c:369 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "ファイル\"%s\"のstatに失敗しました: %m" + +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed due to the signal: %s" +msgstr "restore_commandがシグナルにより失敗しました: %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "ファイル\"%s\"をアーカイブからリストアできませんでした" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:74 parsexlog.c:126 +#: parsexlog.c:186 +#, c-format +msgid "out of memory" +msgstr "メモリ不足です" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:299 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "ファイル\"%s\"を書き出せませんでした: %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "ファイル\"%s\"を作成できませんでした: %m" + +#: copy_fetch.c:59 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: copy_fetch.c:117 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" + +#: copy_fetch.c:120 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "シンボリックリンク\"%s\"の参照先が長すぎます" + +#: copy_fetch.c:135 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "\"%s\"はシンボリックリンクですが、このプラットフォームではシンボリックリンクをサポートしていません" + +#: copy_fetch.c:142 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m" + +#: copy_fetch.c:146 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" + +#: copy_fetch.c:166 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "ソースファイル\"%s\"をオープンすることができませんでした: %m" + +#: copy_fetch.c:170 +#, c-format +msgid "could not seek in source file: %m" +msgstr "ソースファイルをシークすることができませんでした: %m" + +#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:337 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "ファイル\"%s\"の読み取りに失敗しました: %m" + +#: copy_fetch.c:190 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "ファイル\"%s\"を読み込み中に想定外のEOF" + +#: copy_fetch.c:197 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "ファイル\"%s\"をクローズできませんでした: %m" + +#: file_ops.c:62 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "ターゲットファイル\"%s\"をオープンできませんでした: %m" + +#: file_ops.c:76 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "ターゲットファイル\"%s\"をクローズできませんでした: %m" + +#: file_ops.c:96 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "ターゲットファイル\"%s\"をシークできませんでした: %m" + +#: file_ops.c:112 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "ファイル\"%s\"を書き出せませんでした: %m" + +#: file_ops.c:162 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "通常のファイルに対する不正なアクション(CREATE)です" + +#: file_ops.c:185 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "ファイル\"%s\"を削除できませんでした: %m" + +#: file_ops.c:203 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "ファイル\"%s\"を切り詰めのためにオープンできませんでした: %m" + +#: file_ops.c:207 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "ファイル\"%s\"を%uバイトに切り詰められませんでした: %m" + +#: file_ops.c:223 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を作成できませんでした: %m" + +#: file_ops.c:237 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"を削除できませんでした: %m" + +#: file_ops.c:251 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "\"%s\"にシンボリックリンクを作成できませんでした: %m" + +#: file_ops.c:265 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を削除できませんでした: %m" + +#: file_ops.c:296 file_ops.c:300 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "ファイル\"%s\"を読み取り用にオープンできませんでした: %m" + +#: file_ops.c:314 parsexlog.c:339 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$dバイトを読み込みました" + +#: filemap.c:200 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "ソースのデータファイル\"%s\"は通常のファイルではありません" + +#: filemap.c:222 +#, c-format +msgid "\"%s\" is not a directory" +msgstr "\"%s\"はディレクトリではありません" + +#: filemap.c:245 +#, c-format +msgid "\"%s\" is not a symbolic link" +msgstr "\"%s\"はシンボリックリンクではありません" + +#: filemap.c:257 +#, c-format +msgid "\"%s\" is not a regular file" +msgstr "\"%s\" は通常のファイルではありません" + +#: filemap.c:381 +#, c-format +msgid "source file list is empty" +msgstr "ソースファイルリストが空です" + +#: filemap.c:496 +#, c-format +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "ディレクトリまたはシンボリックリンク\"%s\"に対する想定外のページの書き換えです" + +#: libpq_fetch.c:50 +#, c-format +msgid "could not connect to server: %s" +msgstr "サーバに接続できませんでした: %s" + +#: libpq_fetch.c:54 +#, c-format +msgid "connected to server" +msgstr "サーバへ接続しました" + +#: libpq_fetch.c:63 +#, c-format +msgid "could not clear search_path: %s" +msgstr "search_pathを消去できませんでした: %s" + +#: libpq_fetch.c:75 +#, c-format +msgid "source server must not be in recovery mode" +msgstr "ソースサーバはリカバリモードであってはなりません" + +#: libpq_fetch.c:85 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "ソースサーバではfull_pate_writesは有効でなければなりません" + +#: libpq_fetch.c:111 +#, c-format +msgid "error running query (%s) on source server: %s" +msgstr "ソースサーバで実行中のクエリ(%s)でエラー: %s" + +#: libpq_fetch.c:116 +#, c-format +msgid "unexpected result set from query" +msgstr "クエリから想定外の結果セット" + +#: libpq_fetch.c:137 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "ソースサーバの実行中のクエリ(%s)でエラー: %s" + +#: libpq_fetch.c:157 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "現在のWAL挿入位置として認識不可の結果\"%s\"" + +#: libpq_fetch.c:207 +#, c-format +msgid "could not fetch file list: %s" +msgstr "ファイルリストをフェッチできませんでした: %s" + +#: libpq_fetch.c:212 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "ファイルリストのフェッチ中に想定外の結果セット" + +#: libpq_fetch.c:265 +#, c-format +msgid "could not send query: %s" +msgstr "クエリを送信できませんでした: %s" + +#: libpq_fetch.c:270 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "libpq接続を単一行モードに設定できませんでした" + +#: libpq_fetch.c:290 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "リモートファイルをフェッチ中に想定外の結果: %s" + +#: libpq_fetch.c:296 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "リモートファイルのフェッチ中に想定外の結果セットサイズ" + +#: libpq_fetch.c:302 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "リモートファイルのフェッチ中の結果セットに想定外のデータ型: %u %u %u" + +#: libpq_fetch.c:310 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "リモートファイルのフェッチ中に想定外の結果形式" + +#: libpq_fetch.c:316 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "リモートファイルのフェッチ中の結果に想定外のNULL値" + +#: libpq_fetch.c:320 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "リモートファイルのフェッチ中に想定外の結果の長さ" + +#: libpq_fetch.c:381 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "リモートファイル\"%s\"をフェッチできませんでした: %s" + +#: libpq_fetch.c:386 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "リモートファイル\"%s\"のフェッチ中に想定外の結果セット" + +#: libpq_fetch.c:430 +#, c-format +msgid "could not send COPY data: %s" +msgstr "COPY 対象データを送信できませんでした: %s" + +#: libpq_fetch.c:459 +#, c-format +msgid "could not send file list: %s" +msgstr "ファイルリストを送信できませんでした: %s" + +#: libpq_fetch.c:501 +#, c-format +msgid "could not send end-of-COPY: %s" +msgstr "コピー終端を送信できませんでした: %s" + +#: libpq_fetch.c:507 +#, c-format +msgid "unexpected result while sending file list: %s" +msgstr "ファイルリストを送信中に想定外の結果: %s" + +#: parsexlog.c:86 parsexlog.c:133 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "%X/%XのWALレコードを読み取れませんでした: %s" + +#: parsexlog.c:90 parsexlog.c:136 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "%X/%XのWALレコードを読み取れませんでした" + +#: parsexlog.c:199 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "%X/%Xの前のWALレコードが見つかりませんでした: %s" + +#: parsexlog.c:203 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "%X/%Xの前のWALレコードが見つかりませんでした" + +#: parsexlog.c:328 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "ファイル\"%s\"をシークできませんでした: %m" + +#: parsexlog.c:420 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WALレコードはリレーションを修正しますが、レコードの型を認識できません: lsn: %X/%X、rmgr: %s、info: %02X" + +#: pg_rewind.c:78 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s はPostgreSQLクラスタをそのクラスタのコピーで再同期します。\n" +"\n" + +#: pg_rewind.c:79 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"使用方法:\n" +" %s [オプション]...\n" +"\n" + +#: pg_rewind.c:80 +#, c-format +msgid "Options:\n" +msgstr "オプション:\n" + +#: pg_rewind.c:81 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal ターゲットの設定の中のrestore_commandを使用して\n" +" アーカイブからWALファイルを取得する\n" + +#: pg_rewind.c:83 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=DIRECTORY 修正を行う既存データディレクトリ\n" + +#: pg_rewind.c:84 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr " --source-pgdata=DIRECTORY 同期元とするデータディレクトリ\n" + +#: pg_rewind.c:85 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=CONNSTR 同期元とするサーバ\n" + +#: pg_rewind.c:86 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run 修正を始める前に停止する\n" + +#: pg_rewind.c:87 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr " -N, --no-sync 変更のディスクへの安全な書き出しを待機しない\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress 進捗メッセージを出力\n" + +#: pg_rewind.c:90 +#, c-format +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf レプリケーションのための設定を書き込む\n" +" (--source-server が必要となります)\n" + +#: pg_rewind.c:92 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug 多量のデバッグメッセージを出力\n" + +#: pg_rewind.c:93 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr " --no-ensure-shutdown 非クリーンシャットダウン後の修正を自動で行わない\n" + +#: pg_rewind.c:94 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_rewind.c:96 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: pg_rewind.c:97 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_rewind.c:159 pg_rewind.c:208 pg_rewind.c:215 pg_rewind.c:222 +#: pg_rewind.c:229 pg_rewind.c:237 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"を実行してください。\n" + +#: pg_rewind.c:207 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "ソースが指定されていません(--source-pgdata または --source-server)" + +#: pg_rewind.c:214 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "--source-pgdataか--source-server はいずれか一方のみ指定可能です" + +#: pg_rewind.c:221 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "ターゲットデータディレクトリが指定されていません(--target-pgdata)" + +#: pg_rewind.c:228 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "--write-recovery-confにソースサーバ情報(--source-server)が指定されていません" + +#: pg_rewind.c:235 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr " コマンドライン引数が多すぎます(先頭は\"%s\")" + +#: pg_rewind.c:250 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "\"root\"では実行できません" + +#: pg_rewind.c:251 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "PostgreSQLのスーパユーザで%sを実行しなければなりません\n" + +#: pg_rewind.c:262 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"の権限を読み取れませんでした: %m" + +#: pg_rewind.c:316 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "ソースとターゲットのクラスタが同一タイムライン上にあります" + +#: pg_rewind.c:322 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "タイムライン%3$uのWAL位置%1$X/%2$Xで両サーバが分岐しています" + +#: pg_rewind.c:360 +#, c-format +msgid "no rewind required" +msgstr "巻き戻しは必要ありません" + +#: pg_rewind.c:369 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "タイムライン%3$uの%1$X/%2$Xにある最新の共通チェックポイントから巻き戻しています" + +#: pg_rewind.c:378 +#, c-format +msgid "reading source file list" +msgstr "ソースファイルリストを読み込んでいます" + +#: pg_rewind.c:381 +#, c-format +msgid "reading target file list" +msgstr "ターゲットファイルリストを読み込んでいます" + +#: pg_rewind.c:392 +#, c-format +msgid "reading WAL in target" +msgstr "ターゲットでWALを読み込んでいます" + +#: pg_rewind.c:409 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "%lu MBコピーする必要があります(ソースディレクトリの合計サイズは%lu MBです)" + +#: pg_rewind.c:427 +#, c-format +msgid "creating backup label and updating control file" +msgstr "backup labelを作成して制御ファイルを更新しています" + +#: pg_rewind.c:457 +#, c-format +msgid "syncing target data directory" +msgstr "ターゲットデータディレクトリを同期しています" + +#: pg_rewind.c:464 +#, c-format +msgid "Done!" +msgstr "完了!" + +#: pg_rewind.c:476 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "ソースクラスタとターゲットクラスタは異なるシステムのものです" + +#: pg_rewind.c:484 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "クラスタは、このバージョンのpg_rewindとの互換性がありません" + +#: pg_rewind.c:494 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "ターゲットサーバはデータチェックサムを利用している、または\"wal_log_hints = on\"である必要があります" + +#: pg_rewind.c:505 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "ターゲットサーバはきれいにシャットダウンされていなければなりません" + +#: pg_rewind.c:515 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "ソースデータディレクトリはきれいにシャットダウンされていなければなりません" + +#: pg_rewind.c:567 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s kB (%d%%) コピーしました" + +#: pg_rewind.c:630 +#, c-format +msgid "invalid control file" +msgstr "不正な制御ファイル" + +#: pg_rewind.c:714 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "ソースクラスタとターゲットクラスタのタイムラインの共通の祖先を見つけられません" + +#: pg_rewind.c:755 +#, c-format +msgid "backup label buffer too small" +msgstr "バックアップラベルのバッファが小さすぎます" + +#: pg_rewind.c:778 +#, c-format +msgid "unexpected control file CRC" +msgstr "想定外の制御ファイルCRCです" + +#: pg_rewind.c:788 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "想定外の制御ファイルのサイズ%d、想定は%d" + +#: pg_rewind.c:797 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WALセグメントのサイズ指定は1MBと1GBの間の2の累乗でなければなりません、しかしコントロールファイルでは%dバイトとなっています" +msgstr[1] "WALセグメントのサイズ指定は1MBと1GBの間の2の累乗でなければなりません、しかしコントロールファイルでは%dバイトとなっています" + +#: pg_rewind.c:854 pg_rewind.c:912 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%2$sには\"%1$s\"プログラムが必要ですが、\"%3$s\"と同じディレクトリ\n" +"にありませんでした。\n" +"インストール状況を確認してください。" + +#: pg_rewind.c:859 pg_rewind.c:917 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じ\n" +"バージョンではありませんでした。\n" +"インストール状況を確認してください。" + +#: pg_rewind.c:880 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "ターゲットクラスタでrestore_commandが設定されていません" + +#: pg_rewind.c:923 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "ターゲットサーバに対して\"%s\"を実行してクラッシュリカバリを完了させます" + +#: pg_rewind.c:943 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "ターゲットクラスタでのpostgresコマンドのシングルユーザモード実行に失敗しました" + +#: pg_rewind.c:944 +#, c-format +msgid "Command was: %s" +msgstr "コマンド: %s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "履歴ファイル内の構文エラー: %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "数字のタイムラインIDを想定しました。" + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "先行書き込みログの切り替え点の場所があるはずでした。" + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "履歴ファイル内の不正なデータ: %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "タイムラインIDは昇順でなければなりません" + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "履歴ファイル内の無効なデータ" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "タイムラインIDは子のタイムラインIDより小さくなければなりません。" + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "%X/%Xのレコードオフセットが無効です" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "%X/%Xではcontrecordが必要です" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "%X/%Xのレコード長が無効です:長さは%uである必要がありますが、長さは%uでした" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "%2$X/%3$Xのレコード長%1$uが大きすぎます" + +#: xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "%X/%Xで contrecord フラグがありません" + +#: xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "%2$X/%3$Xのcontrecordの長さ %1$u が無効です" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "%2$X/%3$XのリソースマネージャID %1$uが無効です" + +#: xlogreader.c:717 xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "直前のリンク%1$X/%2$Xが不正なレコードが%3$X/%4$Xにあります" + +#: xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "%X/%Xのレコード内のリソースマネージャデータのチェックサムが不正です" + +#: xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "ログセグメント%2$s、オフセット%3$uのマジックナンバー%1$04Xは無効です" + +#: xlogreader.c:822 xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ログセグメント %2$s、オフセット %3$u の情報ビット %1$04X は無効です" + +#: xlogreader.c:837 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WALファイルは異なるデータベースシステム由来のものです: WALファイルのデータベースシステム識別子は %lluで、pg_control におけるデータベースシステム識別子は %lluです" + +#: xlogreader.c:845 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL ファイルは異なるデータベースシステム由来のものです: ページヘッダーのセグメントサイズが正しくありません" + +#: xlogreader.c:851 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL ファイルは異なるデータベースシステム由来のものです: ページヘッダーのXLOG_BLCKSZが正しくありません" + +#: xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "ログセグメント%3$s、オフセット%4$uのページアドレス%1$X/%2$Xは想定外です" + +#: xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "ログセグメント%3$s、オフセット%4$uの時系列ID %1$u(%2$uの後)は順序に従っていません" + +#: xlogreader.c:1252 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %uが%X/%Xで無効です" + +#: xlogreader.c:1275 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATAが設定されていますが、%X/%Xにデータがありません" + +#: xlogreader.c:1282 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATAが設定されていませんが、%2$X/%3$Xのデータ長は%1$u" + +#: xlogreader.c:1318 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEが設定されていますが、%4$X/%5$Xでホールオフセット%1$u、長さ%2$u、ブロックイメージ長%3$u" + +#: xlogreader.c:1334 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEが設定されていませんが、%3$X/%4$Xにホールオフセット%1$u、長さ%2$u" + +#: xlogreader.c:1349 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSEDが設定されていますが、%2$X/%3$Xにおいてブロックイメージ長が%1$u" + +#: xlogreader.c:1364 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEもBKPIMAGE_IS_COMPRESSEDも設定されていませんが、%2$X/%3$Xにおいてブロックイメージ長が%1$u" + +#: xlogreader.c:1380 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_RELが設定されていますが、%X/%Xにおいて以前のリレーションがありません" + +#: xlogreader.c:1392 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "%2$X/%3$Xにおけるblock_id %1$uが無効です" + +#: xlogreader.c:1481 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "%X/%Xのレコードのサイズが無効です" + +#: xlogreader.c:1570 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "%X/%X、ブロック %d での圧縮イメージが無効です" + +#~ msgid "could not create temporary table: %s" +#~ msgstr "一時テーブルを作成できませんでした: %s" + +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "WAL ファイルは異なるデータベースシステム由来のものです: ページヘッダーのXLOG_SEG_SIZEが正しくありません" + +#~ msgid "Timeline IDs must be less than child timeline's ID.\n" +#~ msgstr "時系列IDは副時系列IDより小さくなければなりません。\n" + +#~ msgid "Timeline IDs must be in increasing sequence.\n" +#~ msgstr "時系列IDは昇順の並びでなければなりません\n" + +#~ msgid "invalid data in history file: %s\n" +#~ msgstr "履歴ファイル内の無効なデータ: %s\n" + +#~ msgid "Expected a transaction log switchpoint location.\n" +#~ msgstr "トランザクションログの切替えポイントを想定しています。\n" + +#~ msgid "Expected a numeric timeline ID.\n" +#~ msgstr "数字の時系列IDを想定しました。\n" + +#~ msgid "syntax error in history file: %s\n" +#~ msgstr "履歴ファイル内の構文エラー: %s\n" + +#~ msgid "sync of target directory failed\n" +#~ msgstr "ターゲットディレクトリの同期が失敗しました\n" + +#~ msgid "" +#~ "The program \"initdb\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "\"%s\"がプログラム \"initdb\" を見つけましたが、これは%sと同じ\n" +#~ "バージョンではありませんでした。\n" +#~ "インストレーションを検査してください。\n" + +#~ msgid "" +#~ "The program \"initdb\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "%sには \"initdb\" プログラムが必要ですが、\"%s\"と同じディレクトリ\n" +#~ "にありませんでした。\n" +#~ "インストール状況を確認してください。\n" + +#~ msgid "%d: %X/%X - %X/%X\n" +#~ msgstr "%d: %X/%X - %X/%X\n" + +#~ msgid "Target timeline history:\n" +#~ msgstr "ターゲットタイムラインの履歴:\n" + +#~ msgid "Source timeline history:\n" +#~ msgstr "ソースタイムラインの履歴\n" + +#~ msgid "could not read from file \"%s\": %s\n" +#~ msgstr "ファイル\"%s\"を読み込めませんでした: %s\n" + +#~ msgid "could not seek in file \"%s\": %s\n" +#~ msgstr "ファイル\"%s\"をシークできませんでした: %s\n" + +#~ msgid "could not open file \"%s\": %s\n" +#~ msgstr "ファイル \"%s\" をオープンできませんでした: %s\n" + +#~ msgid "Failure, exiting\n" +#~ msgstr "失敗しました、終了します\n" + +#~ msgid "fetched file \"%s\", length %d\n" +#~ msgstr "フェッチしたファイル \"%s\",長さ %d\n" + +#~ msgid "received chunk for file \"%s\", offset %d, size %d\n" +#~ msgstr "ファイル \"%s\",オフセット %d, サイズ %dのチャンクを受け取りました\n" + +#~ msgid "received null value for chunk for file \"%s\", file has been deleted\n" +#~ msgstr "ファイル\"%s\"のNULL値のチャンクを受け取りました。ファイルは削除されました。\n" + +#~ msgid "getting file chunks\n" +#~ msgstr "ファイルチャンクの取得\n" + +#~ msgid "%s (%s)\n" +#~ msgstr "%s (%s)\n" + +#~ msgid "could not open file \"%s\" for reading: %s\n" +#~ msgstr "読み取り用のファイル\"%s\"をオープンできませんでした:%s\n" + +#~ msgid "could not remove symbolic link \"%s\": %s\n" +#~ msgstr "シンボリックリンク \"%s\" を削除できませんでした: %s\n" + +#~ msgid "could not remove directory \"%s\": %s\n" +#~ msgstr "ディレクトリ\"%s\"を削除できませんでした: %s\n" + +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "ディレクトリ\"%s\"を作成できませんでした: %s\n" + +#~ msgid "could not truncate file \"%s\" to %u: %s\n" +#~ msgstr "ファイル \"%s\" を%uに切り詰められませんでした: %s\n" + +#~ msgid "could not remove file \"%s\": %s\n" +#~ msgstr "ファイル\"%s\"を削除できませんでした: %s\n" + +#~ msgid "could not write file \"%s\": %s\n" +#~ msgstr "ファイル\"%s\"に書き込めませんでした: %s\n" + +#~ msgid " block %u\n" +#~ msgstr "ブロック数 %u\n" + +#~ msgid "could not close file \"%s\": %s\n" +#~ msgstr "ファイル \"%s\" をクローズできませんでした: %s\n" + +#~ msgid "could not read file \"%s\": %s\n" +#~ msgstr "ファイル \"%s\" を読み込めませんでした: %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "ディレクトリ\"%s\"を読み取れませんでした: %s\n" + +#~ msgid "symbolic link \"%s\" target is too long\n" +#~ msgstr "シンボリックリンク\"%s\"の参照先は長すぎます\n" + +#~ msgid "could not read symbolic link \"%s\": %s\n" +#~ msgstr "シンボリックリンク \"%s\" を読み込めませんでした: %s\n" + +#~ msgid "could not stat file \"%s\": %s\n" +#~ msgstr "ファイル\"%s\"のstatができませんでした: %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "ディレクトリ\"%s\"をオープンできませんでした: %s\n" + +#~ msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +#~ msgstr "WAL ファイルは異なるデータベースシステム由来ものです: WAL ファイルにおけるデータベースシステムの識別子は %s で、pg_control におけるデータベースシステムの識別子は %s です。" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "不具合はまで報告してください。\n" + +#~ msgid "cannot create restricted tokens on this platform" +#~ msgstr "このプラットフォームでは制限付きトークンを作成できません" diff --git a/src/bin/pg_rewind/po/ru.po b/src/bin/pg_rewind/po/ru.po new file mode 100644 index 000000000000..88f1f4cc9c07 --- /dev/null +++ b/src/bin/pg_rewind/po/ru.po @@ -0,0 +1,1089 @@ +# Russian message translation file for pg_rewind +# Copyright (C) 2015-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Alexander Lakhin , 2015-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_rewind (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-12-11 07:48+0300\n" +"PO-Revision-Date: 2020-11-09 08:33+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "не удалось загрузить библиотеку \"%s\" (код ошибки: %lu)" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "в этой ОС нельзя создавать ограниченные маркеры (код ошибки: %lu)" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "не удалось открыть маркер процесса (код ошибки: %lu)" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "не удалось подготовить структуры SID (код ошибки: %lu)" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "не удалось создать ограниченный маркер (код ошибки: %lu)" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "не удалось запустить процесс для команды \"%s\" (код ошибки: %lu)" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "не удалось перезапуститься с ограниченным маркером (код ошибки: %lu)" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "не удалось получить код выхода от подпроцесса (код ошибки: %lu)" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "cannot use restore_command with %%r placeholder" +msgstr "нельзя использовать restore_command со знаком подстановки %%r" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lu instead of %lu" +msgstr "неподходящий размер файла \"%s\": %lu вместо %lu байт" + +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "не удалось открыть файл \"%s\", восстановленный из архива: %m" + +#: ../../fe_utils/archive.c:97 copy_fetch.c:88 filemap.c:208 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не удалось получить информацию о файле \"%s\": %m" + +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed: %s" +msgstr "ошибка при выполнении restore_command: %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "восстановить файл \"%s\" из архива не удалось" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:76 parsexlog.c:134 +#: parsexlog.c:194 +#, c-format +msgid "out of memory" +msgstr "нехватка памяти" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:307 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "не удалось записать в файл \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "не удалось создать файл \"%s\": %m" + +#: copy_fetch.c:59 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалось открыть каталог \"%s\": %m" + +#: copy_fetch.c:117 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не удалось прочитать символическую ссылку \"%s\": %m" + +#: copy_fetch.c:120 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "целевой путь символической ссылки \"%s\" слишком длинный" + +#: copy_fetch.c:135 +#, c-format +msgid "" +"\"%s\" is a symbolic link, but symbolic links are not supported on this " +"platform" +msgstr "" +"\"%s\" — символическая ссылка, но в этой ОС символические ссылки не " +"поддерживаются" + +#: copy_fetch.c:142 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не удалось прочитать каталог \"%s\": %m" + +#: copy_fetch.c:146 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не удалось закрыть каталог \"%s\": %m" + +#: copy_fetch.c:166 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "не удалось открыть исходный файл \"%s\": %m" + +#: copy_fetch.c:170 +#, c-format +msgid "could not seek in source file: %m" +msgstr "не удалось переместиться в исходном файле: %m" + +#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:345 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: copy_fetch.c:190 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "неожиданный конец файла при чтении \"%s\"" + +#: copy_fetch.c:197 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "не удалось закрыть файл \"%s\": %m" + +#: file_ops.c:62 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "не удалось открыть целевой файл \"%s\": %m" + +#: file_ops.c:76 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "не удалось закрыть целевой файл \"%s\": %m" + +#: file_ops.c:96 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "не удалось переместиться в целевом файле \"%s\": %m" + +#: file_ops.c:112 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не удалось записать файл \"%s\": %m" + +#: file_ops.c:162 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "неверное действие (CREATE) для обычного файла" + +#: file_ops.c:185 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "не удалось стереть файл \"%s\": %m" + +#: file_ops.c:203 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "не удалось открыть файл \"%s\" для усечения: %m" + +#: file_ops.c:207 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "не удалось обрезать файл \"%s\" до нужного размера (%u): %m" + +#: file_ops.c:223 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не удалось создать каталог \"%s\": %m" + +#: file_ops.c:237 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "ошибка при удалении каталога \"%s\": %m" + +#: file_ops.c:251 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "не удалось создать символическую ссылку \"%s\": %m" + +#: file_ops.c:265 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "ошибка при удалении символической ссылки \"%s\": %m" + +#: file_ops.c:296 file_ops.c:300 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не удалось открыть файл \"%s\" для чтения: %m" + +#: file_ops.c:314 parsexlog.c:347 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %zu)" + +#: filemap.c:200 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "файл данных \"%s\" в источнике не является обычным файлом" + +#: filemap.c:222 +#, c-format +msgid "\"%s\" is not a directory" +msgstr "\"%s\" не является каталогом" + +#: filemap.c:245 +#, c-format +msgid "\"%s\" is not a symbolic link" +msgstr "\"%s\" не является символической ссылкой" + +#: filemap.c:257 +#, c-format +msgid "\"%s\" is not a regular file" +msgstr "\"%s\" не является обычным файлом" + +#: filemap.c:369 +#, c-format +msgid "source file list is empty" +msgstr "список файлов в источнике пуст" + +#: filemap.c:484 +#, c-format +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "" +"неожиданная модификация страницы для каталога или символической ссылки \"%s\"" + +#: libpq_fetch.c:50 +#, c-format +msgid "%s" +msgstr "%s" + +#: libpq_fetch.c:53 +#, c-format +msgid "connected to server" +msgstr "подключение к серверу установлено" + +#: libpq_fetch.c:62 +#, c-format +msgid "could not clear search_path: %s" +msgstr "не удалось очистить search_path: %s" + +#: libpq_fetch.c:74 +#, c-format +msgid "source server must not be in recovery mode" +msgstr "исходный сервер должен выйти из режима восстановления" + +#: libpq_fetch.c:84 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "на исходном сервере должен быть включён режим full_page_writes" + +#: libpq_fetch.c:110 +#, c-format +msgid "error running query (%s) on source server: %s" +msgstr "ошибка выполнения запроса (%s) на исходном сервере: %s" + +#: libpq_fetch.c:115 +#, c-format +msgid "unexpected result set from query" +msgstr "неожиданный результат запроса" + +#: libpq_fetch.c:136 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "ошибка выполнения запроса (%s) на исходном сервере: %s" + +#: libpq_fetch.c:156 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "" +"нераспознанный результат \"%s\" вместо текущей позиции добавления в WAL" + +#: libpq_fetch.c:206 +#, c-format +msgid "could not fetch file list: %s" +msgstr "не удалось получить список файлов: %s" + +#: libpq_fetch.c:211 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "неожиданный результат при получении списка файлов" + +#: libpq_fetch.c:264 +#, c-format +msgid "could not send query: %s" +msgstr "не удалось отправить запрос: %s" + +#: libpq_fetch.c:269 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "не удалось перевести подключение libpq в однострочный режим" + +#: libpq_fetch.c:289 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "неожиданный результат при получении файлов с сервера: %s" + +#: libpq_fetch.c:295 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "неожиданный размер набора результатов при получении файлов с сервера" + +#: libpq_fetch.c:301 +#, c-format +msgid "" +"unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "" +"неожиданные типы данных в наборе результатов при получении файлов с сервера: " +"%u %u %u" + +#: libpq_fetch.c:309 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "неожиданный формат результата при получении файлов с сервера" + +#: libpq_fetch.c:315 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "неожиданные значения NULL в результате при получении файлов с сервера" + +#: libpq_fetch.c:319 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "неожиданная длина результата при получении файлов с сервера" + +#: libpq_fetch.c:380 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "не удалось получить с сервера файл \"%s\": %s" + +#: libpq_fetch.c:385 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "неожиданный набор результатов при получении файла \"%s\" с сервера" + +#: libpq_fetch.c:429 +#, c-format +msgid "could not send COPY data: %s" +msgstr "не удалось отправить данные COPY: %s" + +#: libpq_fetch.c:458 +#, c-format +msgid "could not send file list: %s" +msgstr "не удалось отправить список файлов: %s" + +#: libpq_fetch.c:500 +#, c-format +msgid "could not send end-of-COPY: %s" +msgstr "не удалось отправить сообщение о завершении копирования: %s" + +#: libpq_fetch.c:506 +#, c-format +msgid "unexpected result while sending file list: %s" +msgstr "неожиданный результат при передаче списка: %s" + +#: parsexlog.c:88 parsexlog.c:141 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "не удалось прочитать запись WAL в позиции %X/%X: %s" + +#: parsexlog.c:92 parsexlog.c:144 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "не удалось прочитать запись WAL в позиции %X/%X" + +#: parsexlog.c:207 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "не удалось найти предыдущую запись WAL в позиции %X/%X: %s" + +#: parsexlog.c:211 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "не удалось найти предыдущую запись WAL в позиции %X/%X" + +#: parsexlog.c:336 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "не удалось переместиться в файле \"%s\": %m" + +#: parsexlog.c:416 +#, c-format +msgid "" +"WAL record modifies a relation, but record type is not recognized: lsn: %X/" +"%X, rmgr: %s, info: %02X" +msgstr "" +"Запись WAL модифицирует отношение, но тип записи не распознан: lsn: %X/%X, " +"rmgr: %s, info: %02X" + +#: pg_rewind.c:78 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s синхронизирует кластер PostgreSQL с другой копией кластера.\n" +"\n" + +#: pg_rewind.c:79 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Использование:\n" +" %s [ПАРАМЕТР]...\n" +"\n" + +#: pg_rewind.c:80 +#, c-format +msgid "Options:\n" +msgstr "Параметры:\n" + +#: pg_rewind.c:81 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration " +"to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal использовать для получения файлов WAL из\n" +" архива команду restore_command из целевой\n" +" конфигурации\n" + +#: pg_rewind.c:83 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr "" +" -D, --target-pgdata=КАТАЛОГ существующий каталог, куда будут записаны " +"данные\n" + +#: pg_rewind.c:84 +#, c-format +msgid "" +" --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr "" +" --source-pgdata=КАТАЛОГ исходный каталог, с которым будет проведена " +"синхронизация\n" + +# well-spelled: ПОДКЛ +#: pg_rewind.c:85 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr "" +" --source-server=СТР_ПОДКЛ сервер, с которым будет проведена " +"синхронизация\n" + +#: pg_rewind.c:86 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr "" +" -n, --dry-run остановиться до внесения каких-либо " +"изменений\n" + +#: pg_rewind.c:87 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr "" +" -N, --no-sync не ждать завершения сохранения данных на " +"диске\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress выводить сообщения о ходе процесса\n" + +#: pg_rewind.c:90 +#, c-format +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf записать конфигурацию для репликации\n" +" (требуется указание --source-server)\n" + +#: pg_rewind.c:92 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr "" +" --debug выдавать множество отладочных сообщений\n" + +#: pg_rewind.c:93 +#, c-format +msgid "" +" --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr "" +" --no-ensure-shutdown не исправлять автоматически состояние,\n" +" возникающее при нештатном отключении\n" + +#: pg_rewind.c:94 +#, c-format +msgid "" +" -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_rewind.c:96 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_rewind.c:97 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_rewind.c:160 pg_rewind.c:209 pg_rewind.c:216 pg_rewind.c:223 +#: pg_rewind.c:230 pg_rewind.c:238 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_rewind.c:208 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "источник не указан (требуется --source-pgdata или --source-server)" + +#: pg_rewind.c:215 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "указать можно только --source-pgdata либо --source-server" + +#: pg_rewind.c:222 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "целевой каталог данных не указан (--target-pgdata)" + +#: pg_rewind.c:229 +#, c-format +msgid "" +"no source server information (--source-server) specified for --write-" +"recovery-conf" +msgstr "" +"отсутствует информация об исходном сервере (--source-server) для --write-" +"recovery-conf" + +#: pg_rewind.c:236 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: pg_rewind.c:251 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "программу не должен запускать root" + +#: pg_rewind.c:252 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "Запускать %s нужно от имени суперпользователя PostgreSQL.\n" + +#: pg_rewind.c:263 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "не удалось считать права на каталог \"%s\": %m" + +#: pg_rewind.c:317 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "исходный и целевой кластер уже на одной линии времени" + +#: pg_rewind.c:326 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "серверы разошлись в позиции WAL %X/%X на линии времени %u" + +#: pg_rewind.c:374 +#, c-format +msgid "no rewind required" +msgstr "перемотка не требуется" + +#: pg_rewind.c:383 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "" +"перемотка от последней общей контрольной точки в позиции %X/%X на линии " +"времени %u" + +#: pg_rewind.c:392 +#, c-format +msgid "reading source file list" +msgstr "чтение списка исходных файлов" + +#: pg_rewind.c:395 +#, c-format +msgid "reading target file list" +msgstr "чтение списка целевых файлов" + +#: pg_rewind.c:404 +#, c-format +msgid "reading WAL in target" +msgstr "чтение WAL в целевом кластере" + +#: pg_rewind.c:421 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "требуется скопировать %lu МБ (общий размер исходного каталога: %lu МБ)" + +#: pg_rewind.c:439 +#, c-format +msgid "creating backup label and updating control file" +msgstr "создание метки копии и модификация управляющего файла" + +#: pg_rewind.c:469 +#, c-format +msgid "syncing target data directory" +msgstr "синхронизация целевого каталога данных" + +#: pg_rewind.c:476 +#, c-format +msgid "Done!" +msgstr "Готово!" + +#: pg_rewind.c:488 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "исходный и целевой кластеры относятся к разным системам" + +#: pg_rewind.c:496 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "кластеры несовместимы с этой версией pg_rewind" + +#: pg_rewind.c:506 +#, c-format +msgid "" +"target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "" +"на целевом сервере должны быть контрольные суммы данных или \"wal_log_hints " +"= on\"" + +#: pg_rewind.c:517 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "целевой сервер должен быть выключен штатно" + +#: pg_rewind.c:527 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "работа с исходным каталогом данных должна быть завершена штатно" + +#: pg_rewind.c:579 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s КБ (%d%%) скопировано" + +#: pg_rewind.c:642 +#, c-format +msgid "invalid control file" +msgstr "неверный управляющий файл" + +#: pg_rewind.c:726 +#, c-format +msgid "" +"could not find common ancestor of the source and target cluster's timelines" +msgstr "" +"не удалось найти общего предка линий времени исходного и целевого кластеров" + +#: pg_rewind.c:767 +#, c-format +msgid "backup label buffer too small" +msgstr "буфер для метки копии слишком мал" + +#: pg_rewind.c:790 +#, c-format +msgid "unexpected control file CRC" +msgstr "неверная контрольная сумма управляющего файла" + +#: pg_rewind.c:800 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "неверный размер управляющего файла (%d), ожидалось: %d" + +#: pg_rewind.c:809 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d bytes" +msgstr[0] "" +"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управляющем файле указано значение: %d" +msgstr[1] "" +"Размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управляющем файле указано значение: %d" +msgstr[2] "" +"Размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управляющем файле указано значение: %d" + +#: pg_rewind.c:866 pg_rewind.c:924 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Программа \"%s\" нужна для %s, но она не найдена\n" +"в каталоге \"%s\".\n" +"Проверьте правильность установки СУБД." + +#: pg_rewind.c:871 pg_rewind.c:929 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Программа \"%s\" найдена программой \"%s\",\n" +"но её версия отличается от версии %s.\n" +"Проверьте правильность установки СУБД." + +#: pg_rewind.c:892 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "команда restore_command в целевом кластере не определена" + +#: pg_rewind.c:935 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "" +"выполнение \"%s\" для восстановления согласованности на целевом сервере" + +#: pg_rewind.c:955 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "" +"не удалось запустить postgres в целевом кластере в однопользовательском " +"режиме" + +#: pg_rewind.c:956 +#, c-format +msgid "Command was: %s" +msgstr "Выполнялась команда: %s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "синтаксическая ошибка в файле истории: %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Ожидается числовой идентификатор линии времени." + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Ожидается положение точки переключения журнала предзаписи." + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "неверные данные в файле истории: %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Идентификаторы линий времени должны возрастать." + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "неверные данные в файле истории" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "" +"Идентификаторы линий времени должны быть меньше идентификатора линии-потомка." + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "неверное смещение записи: %X/%X" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "по смещению %X/%X запрошено продолжение записи" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "неверная длина записи по смещению %X/%X: ожидалось %u, получено %u" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "длина записи %u по смещению %X/%X слишком велика" + +#: xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "нет флага contrecord в позиции %X/%X" + +#: xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "неверная длина contrecord (%u) в позиции %X/%X" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "неверный ID менеджера ресурсов %u по смещению %X/%X" + +#: xlogreader.c:717 xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "запись с неверной ссылкой назад %X/%X по смещению %X/%X" + +#: xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "" +"некорректная контрольная сумма данных менеджера ресурсов в записи по " +"смещению %X/%X" + +#: xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "неверное магическое число %04X в сегменте журнала %s, смещение %u" + +#: xlogreader.c:822 xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "неверные информационные биты %04X в сегменте журнала %s, смещение %u" + +#: xlogreader.c:837 +#, c-format +msgid "" +"WAL file is from different database system: WAL file database system " +"identifier is %llu, pg_control database system identifier is %llu" +msgstr "" +"файл WAL принадлежит другой СУБД: в нём указан идентификатор системы БД " +"%llu, а идентификатор системы pg_control: %llu" + +#: xlogreader.c:845 +#, c-format +msgid "" +"WAL file is from different database system: incorrect segment size in page " +"header" +msgstr "" +"файл WAL принадлежит другой СУБД: некорректный размер сегмента в заголовке " +"страницы" + +#: xlogreader.c:851 +#, c-format +msgid "" +"WAL file is from different database system: incorrect XLOG_BLCKSZ in page " +"header" +msgstr "" +"файл WAL принадлежит другой СУБД: некорректный XLOG_BLCKSZ в заголовке " +"страницы" + +#: xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "неожиданный pageaddr %X/%X в сегменте журнала %s, смещение %u" + +#: xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "" +"нарушение последовательности ID линии времени %u (после %u) в сегменте " +"журнала %s, смещение %u" + +#: xlogreader.c:1247 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "идентификатор блока %u идёт не по порядку в позиции %X/%X" + +#: xlogreader.c:1270 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA установлен, но данных в позиции %X/%X нет" + +#: xlogreader.c:1277 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "" +"BKPBLOCK_HAS_DATA не установлен, но длина данных равна %u в позиции %X/%X" + +#: xlogreader.c:1313 +#, c-format +msgid "" +"BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " +"%X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE установлен, но для пропуска заданы смещение %u и длина %u " +"при длине образа блока %u в позиции %X/%X" + +#: xlogreader.c:1329 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE не установлен, но для пропуска заданы смещение %u и длина " +"%u в позиции %X/%X" + +#: xlogreader.c:1344 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "" +"BKPIMAGE_IS_COMPRESSED установлен, но длина образа блока равна %u в позиции " +"%X/%X" + +#: xlogreader.c:1359 +#, c-format +msgid "" +"neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " +"length is %u at %X/%X" +msgstr "" +"ни BKPIMAGE_HAS_HOLE, ни BKPIMAGE_IS_COMPRESSED не установлены, но длина " +"образа блока равна %u в позиции %X/%X" + +#: xlogreader.c:1375 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "" +"BKPBLOCK_SAME_REL установлен, но предыдущее значение не задано в позиции %X/" +"%X" + +#: xlogreader.c:1387 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "неверный идентификатор блока %u в позиции %X/%X" + +#: xlogreader.c:1476 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "запись с неверной длиной в позиции %X/%X" + +#: xlogreader.c:1565 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "неверный сжатый образ в позиции %X/%X, блок %d" + +#~ msgid "could not connect to server: %s" +#~ msgstr "не удалось подключиться к серверу: %s" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid " block %u\n" +#~ msgstr " блок %u\n" + +#~ msgid "entry \"%s\" excluded from source file list\n" +#~ msgstr "\"%s\" исключён из списка исходных файлов\n" + +#~ msgid "entry \"%s\" excluded from target file list\n" +#~ msgstr "\"%s\" исключён из списка целевых файлов\n" + +#~ msgid "%s (%s)\n" +#~ msgstr "%s (%s)\n" + +#, fuzzy +#~ msgid "could not set up connection context: %s" +#~ msgstr "не удалось настроить контекст подключения: %s" + +#~ msgid "getting file chunks\n" +#~ msgstr "получение сегментов файлов\n" + +#~ msgid "" +#~ "received null value for chunk for file \"%s\", file has been deleted\n" +#~ msgstr "" +#~ "для файла \"%s\" вместо сегмента получено NULL-значение, файл удалён\n" + +#~ msgid "received chunk for file \"%s\", offset %s, size %d\n" +#~ msgstr "получен сегмент файла \"%s\": смещение %s, размер %d\n" + +#~ msgid "fetched file \"%s\", length %d\n" +#~ msgstr "получен файл \"%s\", длина %d\n" + +#, fuzzy +#~ msgid "could not create temporary table: %s" +#~ msgstr "не удалось создать временную таблицу: %s" + +#~ msgid "Failure, exiting\n" +#~ msgstr "Ошибка, выполняется выход\n" + +#~ msgid "could not read from file \"%s\": %s\n" +#~ msgstr "не удалось прочитать файл \"%s\": %s\n" + +#~ msgid "Source timeline history:\n" +#~ msgstr "История линии времени источника:\n" + +#~ msgid "Target timeline history:\n" +#~ msgstr "История линии времени получателя:\n" + +#~ msgid "%d: %X/%X - %X/%X\n" +#~ msgstr "%d: %X/%X - %X/%X\n" + +#~ msgid "sync of target directory failed\n" +#~ msgstr "сбой синхронизации целевого каталога\n" + +#~ msgid "" +#~ "WAL file is from different database system: incorrect XLOG_SEG_SIZE in " +#~ "page header" +#~ msgstr "" +#~ "файл WAL принадлежит другой СУБД: некорректный XLOG_SEG_SIZE в заголовке " +#~ "страницы" diff --git a/src/bin/pg_rewind/po/sv.po b/src/bin/pg_rewind/po/sv.po new file mode 100644 index 000000000000..0df9e35b8604 --- /dev/null +++ b/src/bin/pg_rewind/po/sv.po @@ -0,0 +1,973 @@ +# Swedish message translation file for pg_rewind +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Dennis Björklund , 2017, 2018, 2019, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-16 05:17+0000\n" +"PO-Revision-Date: 2020-09-16 07:53+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "slut på minne\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kan inte duplicera null-pekare (internt fel)\n" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "kunde inte ladda länkbibliotek \"%s\": felkod %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "kan inte skapa token för begränsad åtkomst på denna plattorm: felkod %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "kunde inte öppna process-token: felkod %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "kunde inte allokera SID: felkod %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "kunde inte skapa token för begränsad åtkomst: felkod %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "kunde inte starta process för kommando \"%s\": felkod %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "kunde inte köra igen med token för begränsad åtkomst: felkod %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "kunde inte hämta statuskod för underprocess: felkod %lu" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "cannot use restore_command with %%r placeholder" +msgstr "kan inte använda restore_command med %%r-platshållare" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lu instead of %lu" +msgstr "oväntad filstorlek på \"%s\": %lu istället för %lu" + +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "kunde inte öppna fil \"%s\" återställd från arkiv: %m" + +#: ../../fe_utils/archive.c:97 copy_fetch.c:88 filemap.c:208 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() på fil \"%s\": %m" + +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed: %s" +msgstr "restore_command misslyckades: %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "kunde inte återställa fil \"%s\" från arkiv" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:73 parsexlog.c:125 +#: parsexlog.c:185 +#, c-format +msgid "out of memory" +msgstr "slut på minne" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:298 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "kunde inte skriva till fil \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "kan inte skapa fil \"%s\": %m" + +#: copy_fetch.c:59 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "kunde inte öppna katalog \"%s\": %m" + +#: copy_fetch.c:117 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" + +#: copy_fetch.c:120 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "mål för symbolisk länk \"%s\" är för lång" + +#: copy_fetch.c:135 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "\"%s\" är en symbolisk länk men symboliska länkar stöds inte på denna plattform" + +#: copy_fetch.c:142 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" + +#: copy_fetch.c:146 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" + +#: copy_fetch.c:166 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "kunde inte öppna källfil \"%s\": %m" + +#: copy_fetch.c:170 +#, c-format +msgid "could not seek in source file: %m" +msgstr "kunde inte söka i källfil: %m" + +#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:336 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "kunde inte läsa fil \"%s\": %m" + +#: copy_fetch.c:190 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "oväntad EOF under läsning av fil \"%s\"" + +#: copy_fetch.c:197 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "kunde inte stänga fil \"%s\": %m" + +#: file_ops.c:62 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "kunde inte öppna målfil \"%s\": %m" + +#: file_ops.c:76 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "kunde inte stänga målfil \"%s\": %m" + +#: file_ops.c:96 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "kunde inte söka i målfil \"%s\": %m" + +#: file_ops.c:112 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "kunde inte skriva fil \"%s\": %m" + +#: file_ops.c:162 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "ogiltig aktion (CREATE) för vanlig fil" + +#: file_ops.c:185 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "kunde inte ta bort fil \"%s\": %m" + +#: file_ops.c:203 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "kunde inte öppna fil \"%s\" för trunkering: %m" + +#: file_ops.c:207 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "kunde inte trunkera fil \"%s\" till %u: %m" + +#: file_ops.c:223 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "kunde inte skapa katalog \"%s\": %m" + +#: file_ops.c:237 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "kunde inte ta bort katalog \"%s\": %m" + +#: file_ops.c:251 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "kunde inte skapa en symnbolisk länk vid \"%s\": %m" + +#: file_ops.c:265 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "kan inte ta bort symbolisk länk \"%s\": %m" + +#: file_ops.c:296 file_ops.c:300 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "kunde inte öppna filen \"%s\" för läsning: %m" + +#: file_ops.c:314 parsexlog.c:338 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" + +#: filemap.c:200 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "datafil \"%s\" i källan är inte en vanlig fil" + +#: filemap.c:222 +#, c-format +msgid "\"%s\" is not a directory" +msgstr "\"%s\" är inte en katalog" + +#: filemap.c:245 +#, c-format +msgid "\"%s\" is not a symbolic link" +msgstr "\"%s\" är inte en symbolisk länk" + +#: filemap.c:257 +#, c-format +msgid "\"%s\" is not a regular file" +msgstr "\"%s\" är inte en vanlig fil" + +#: filemap.c:369 +#, c-format +msgid "source file list is empty" +msgstr "källfillistan är tom" + +#: filemap.c:484 +#, c-format +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "oväntad sidmodifiering för katalog eller symbolisk länk \"%s\"" + +#: libpq_fetch.c:50 +#, c-format +msgid "could not connect to server: %s" +msgstr "kunde inte ansluta till server: %s" + +#: libpq_fetch.c:54 +#, c-format +msgid "connected to server" +msgstr "ansluten till server" + +#: libpq_fetch.c:63 +#, c-format +msgid "could not clear search_path: %s" +msgstr "kunde inte nollställa search_path: %s" + +#: libpq_fetch.c:75 +#, c-format +msgid "source server must not be in recovery mode" +msgstr "källserver får inte vara i återställningsläge" + +#: libpq_fetch.c:85 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "full_page_writes måste vara påslagen i källservern" + +#: libpq_fetch.c:111 +#, c-format +msgid "error running query (%s) on source server: %s" +msgstr "fel vid körande av fråga (%s) på källserver: %s" + +#: libpq_fetch.c:116 +#, c-format +msgid "unexpected result set from query" +msgstr "oväntad resultatmängd från fråga" + +#: libpq_fetch.c:137 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "fel vid körande av fråga (%s) i källserver: %s" + +#: libpq_fetch.c:157 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "oväntat resultat \"%s\" för nuvarande WAL-insättningsposition" + +#: libpq_fetch.c:207 +#, c-format +msgid "could not fetch file list: %s" +msgstr "kunde inte hämta fillista: %s" + +#: libpq_fetch.c:212 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "oväntad resultatmängd vid hämtning av fillista" + +#: libpq_fetch.c:265 +#, c-format +msgid "could not send query: %s" +msgstr "kunde inte skicka fråga: %s" + +#: libpq_fetch.c:270 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "kunde inte sätta libpq-anslutning till enradsläge" + +#: libpq_fetch.c:290 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "oväntat resultat vid hämtning av extern fil: %s" + +#: libpq_fetch.c:296 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "oväntad resultatmängdstorlek vid hämtning av externa filer" + +#: libpq_fetch.c:302 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "oväntade datayper i resultatmängd vid hämtning av externa filer: %u %u %u" + +#: libpq_fetch.c:310 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "oväntat resultatformat vid hämtning av externa filer" + +#: libpq_fetch.c:316 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "oväntade null-värden i resultat vid hämtning av externa filer" + +#: libpq_fetch.c:320 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "oväntad resultatlängd vid hämtning av externa filer" + +#: libpq_fetch.c:381 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "kunde inte hämta extern fil \"%s\": %s" + +#: libpq_fetch.c:386 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "oväntat resultatmängd vid hämtning av extern fil \"%s\"" + +#: libpq_fetch.c:430 +#, c-format +msgid "could not send COPY data: %s" +msgstr "kunde inte skicka COPY-data: %s" + +#: libpq_fetch.c:459 +#, c-format +msgid "could not send file list: %s" +msgstr "kunde inte skicka fillista: %s" + +#: libpq_fetch.c:501 +#, c-format +msgid "could not send end-of-COPY: %s" +msgstr "kunde inte skicka slut-på-COPY: %s" + +#: libpq_fetch.c:507 +#, c-format +msgid "unexpected result while sending file list: %s" +msgstr "oväntat resultat vid skickande av fillista: %s" + +#: parsexlog.c:85 parsexlog.c:132 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "kunde inte läsa WAL-post vid %X/%X: %s" + +#: parsexlog.c:89 parsexlog.c:135 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "kunde inte läsa WAL-post vid %X/%X" + +#: parsexlog.c:198 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "kunde inte hitta föregående WAL-post vid %X/%X: %s" + +#: parsexlog.c:202 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "kunde inte hitta förgående WAL-post vid %X/%X" + +#: parsexlog.c:327 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "kunde inte söka (seek) i fil \"%s\": %m" + +#: parsexlog.c:407 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WAL-post modifierar en relation, men posttypen känns inte igen: lsn: %X/%X, rmgr: %s, info: %02X" + +#: pg_rewind.c:78 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s resynkroniserar ett PostgreSQL-kluster med en annan kopia av klustret.\n" +"\n" + +#: pg_rewind.c:79 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"Användning:\n" +" %s [FLAGGA]...\n" +"\n" + +#: pg_rewind.c:80 +#, c-format +msgid "Options:\n" +msgstr "Flaggor:\n" + +#: pg_rewind.c:81 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal använd restore_command i målkonfigurationen\n" +" för att hämta WAL-filer från arkiv\n" + +#: pg_rewind.c:83 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=KATALOG existerande datakatalog att modifiera\n" + +#: pg_rewind.c:84 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr " --source-pgdata=KATALOG källdatakatalog att synkronisera med\n" + +#: pg_rewind.c:85 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=ANSLSTR källserver att synkronisera med\n" + +#: pg_rewind.c:86 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run stoppa innan något modifieras\n" + +#: pg_rewind.c:87 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr "" +" -N, --no-sync vänta inte på att ändingar säkert\n" +" skrivits till disk\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress skriv ut förloppmeddelanden\n" + +#: pg_rewind.c:90 +#, c-format +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf\n" +" skriv konfiguration för replikering\n" +" (kräver --source-server)\n" + +#: pg_rewind.c:92 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug skriv ut en massa debugmeddelanden\n" + +#: pg_rewind.c:93 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr " --no-ensure-shutdown ingen automatisk hantering av trasig nedstängning\n" + +#: pg_rewind.c:94 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version skriv ut versioninformation och avsluta sedan\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denna hjälp och avsluta sedan\n" + +#: pg_rewind.c:96 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapportera fel till <%s>.\n" + +#: pg_rewind.c:97 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "hemsida för %s: <%s>\n" + +#: pg_rewind.c:159 pg_rewind.c:208 pg_rewind.c:215 pg_rewind.c:222 +#: pg_rewind.c:229 pg_rewind.c:237 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: pg_rewind.c:207 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "ingen källa angavs (--source-pgdata eller --source-server)" + +#: pg_rewind.c:214 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "bara en av --source-pgdata och --source-server får anges" + +#: pg_rewind.c:221 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "ingen måldatakatalog angiven (--target-pgdata)" + +#: pg_rewind.c:228 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "ingen källserverinformation (--source-server) angiven för --write-recovery-conf" + +#: pg_rewind.c:235 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för många kommandoradsargument (första är \"%s\")" + +#: pg_rewind.c:250 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "kan inte köras av \"root\"" + +#: pg_rewind.c:251 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "Du måste köra %s som PostgreSQL:s superanvändare.\n" + +#: pg_rewind.c:262 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "kunde inte läsa rättigheter på katalog \"%s\": %m" + +#: pg_rewind.c:316 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "källa och målkluster är på samma tidslinje" + +#: pg_rewind.c:322 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "servrarna divergerade vid WAL-position %X/%X på tidslinje %u" + +#: pg_rewind.c:360 +#, c-format +msgid "no rewind required" +msgstr "ingen rewind krävs" + +#: pg_rewind.c:369 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "rewind från senaste gemensamma checkpoint vid %X/%X på tidslinje %u" + +#: pg_rewind.c:378 +#, c-format +msgid "reading source file list" +msgstr "läser källfillista" + +#: pg_rewind.c:381 +#, c-format +msgid "reading target file list" +msgstr "läser målfillista" + +#: pg_rewind.c:392 +#, c-format +msgid "reading WAL in target" +msgstr "läser WAL i målet" + +#: pg_rewind.c:409 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "behöver kopiera %lu MB (total källkatalogstorlek är %lu MB)" + +#: pg_rewind.c:427 +#, c-format +msgid "creating backup label and updating control file" +msgstr "skapar backupetikett och uppdaterar kontrollfil" + +#: pg_rewind.c:457 +#, c-format +msgid "syncing target data directory" +msgstr "synkar måldatakatalog" + +#: pg_rewind.c:464 +#, c-format +msgid "Done!" +msgstr "Klar!" + +#: pg_rewind.c:476 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "källa och målkluster är från olika system" + +#: pg_rewind.c:484 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "klustren är inte kompatibla med denna version av pg_rewind" + +#: pg_rewind.c:494 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "målservern behöver använda antingen datachecksums eller \"wal_log_hints = on\"" + +#: pg_rewind.c:505 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "målserver måste stängas ner utan fel" + +#: pg_rewind.c:515 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "måldatakatalog måste stängas ner utan fel" + +#: pg_rewind.c:567 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s kB (%d%%) kopierad" + +#: pg_rewind.c:630 +#, c-format +msgid "invalid control file" +msgstr "ogiltig kontrollfil" + +#: pg_rewind.c:714 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "kunde inte finna en gemensam anfader av källa och målklusterets tidslinjer" + +#: pg_rewind.c:755 +#, c-format +msgid "backup label buffer too small" +msgstr "backupetikett-buffer för liten" + +#: pg_rewind.c:778 +#, c-format +msgid "unexpected control file CRC" +msgstr "oväntad kontrollfil-CRC" + +#: pg_rewind.c:788 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "oväntad kontrollfilstorlek %d, förväntade %d" + +#: pg_rewind.c:797 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-segmentstorlek måste vara en tvåpotens mellan 1MB och 1GB men kontrollfilen anger %d byte" +msgstr[1] "WAL-segmentstorlek måste vara en tvåpotens mellan 1MB och 1GB men kontrollfilen anger %d byte" + +#: pg_rewind.c:854 pg_rewind.c:912 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Programmet \"%s\" behövs av %s men hittades inte i samma\n" +"katalog som \"%s\".\n" +"Kontrollera din installation." + +#: pg_rewind.c:859 pg_rewind.c:917 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Programmet \"%s\" hittades av \"%s\"\n" +"men är inte av samma version som %s.\n" +"Kontrollera din installation." + +#: pg_rewind.c:880 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "restore_command är inte satt i målklustret" + +#: pg_rewind.c:923 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "kör \"%s\" för målservern för att slutföra krashåterställning" + +#: pg_rewind.c:943 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "postgres enanvändarläge misslyckades i målklustret" + +#: pg_rewind.c:944 +#, c-format +msgid "Command was: %s" +msgstr "Kommandot var: %s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "syntaxfel i history-fil: %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Förväntade ett numeriskt tidslinje-ID." + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Förväntade en write-ahead-logg:s switchpoint-position." + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "felaktig data i history-fil: %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Tidslinje-ID måste komma i en stigande sekvens." + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "ogiltig data i historikfil" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Tidslinje-ID:er måste vara mindre än barnens tidslinje-ID:er." + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "ogiltig postoffset vid %X/%X" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "contrecord är begärd vid %X/%X" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "ogiltig postlängd vid %X/%X: förväntade %u, fick %u" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "postlängd %u vid %X/%X är för lång" + +#: xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "det finns ingen contrecord-flagga vid %X/%X" + +#: xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "ogiltig contrecord-längd %u vid %X/%X" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "ogiltigt resurshanterar-ID %u vid %X/%X" + +#: xlogreader.c:717 xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "post med inkorrekt prev-link %X/%X vid %X/%X" + +#: xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%X" + +#: xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "felaktigt magiskt nummer %04X i loggsegment %s, offset %u" + +#: xlogreader.c:822 xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ogiltiga infobitar %04X i loggsegment %s, offset %u" + +#: xlogreader.c:837 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL-fil är från ett annat databassystem: WAL-filens databassystemidentifierare är %llu, pg_control databassystemidentifierare är %llu" + +#: xlogreader.c:845 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-fil är från ett annat databassystem: inkorrekt segmentstorlek i sidhuvud" + +#: xlogreader.c:851 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL-fil är från ett annat databassystem: inkorrekt XLOG_BLCKSZ i sidhuvud" + +#: xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "oväntad sidadress %X/%X i loggsegment %s, offset %u" + +#: xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "ej-i-sekvens för tidslinje-ID %u (efter %u) i loggsegment %s, offset %u" + +#: xlogreader.c:1247 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "ej-i-sekvens block_id %u vid %X/%X" + +#: xlogreader.c:1270 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA satt, men ingen data inkluderad vid %X/%X" + +#: xlogreader.c:1277 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA ej satt, men datalängd är %u vid %X/%X" + +#: xlogreader.c:1313 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE satt, men håloffset %u längd %u block-image-längd %u vid %X/%X" + +#: xlogreader.c:1329 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ej satt, men håloffset %u längd %u vid %X/%X" + +#: xlogreader.c:1344 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED satt, men block-image-längd %u vid %X/%X" + +#: xlogreader.c:1359 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_IS_COMPRESSED satt, men block-image-längd är %u vid %X/%X" + +#: xlogreader.c:1375 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL satt men ingen tidigare rel vid %X/%X" + +#: xlogreader.c:1387 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "ogiltig block_id %u vid %X/%X" + +#: xlogreader.c:1476 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "post med ogiltig längd vid %X/%X" + +#: xlogreader.c:1565 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "ogiltig komprimerad image vid %X/%X, block %d" + +#~ msgid "could not load advapi32.dll: error code %lu" +#~ msgstr "kunde inte ladda advapi32.dll: felkod %lu" + +#~ msgid "" +#~ "The program \"%s\" was found by \"%s\" but was\n" +#~ "not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Programmet \"%s\" hittades av \"%s\"\n" +#~ "men är inte av samma version som %s.\n" +#~ "Kontrollera din installation." + +#~ msgid "" +#~ "The program \"%s\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Programmet \"%s\" behövs av %s men hittades inte i samma\n" +#~ "katalog som \"%s\".\n" +#~ "Kontrollera din installation." + +#~ msgid "" +#~ "The program \"postgres\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Programmet \"postgres\" hittades av \"%s\",\n" +#~ "men det är inte byggt i samma version som %s.\n" +#~ "Kontrollera din installation." + +#~ msgid "" +#~ "The program \"postgres\" is needed by %s but was not found in the\n" +#~ "same directory as \"%s\".\n" +#~ "Check your installation." +#~ msgstr "" +#~ "Programmet \"postgres\" behövs av %s men kunde inte hittas\n" +#~ "i samma katalog som \"%s\".\n" +#~ "Kontrollera din installation." diff --git a/src/bin/pg_rewind/po/uk.po b/src/bin/pg_rewind/po/uk.po new file mode 100644 index 000000000000..841576cec1b0 --- /dev/null +++ b/src/bin/pg_rewind/po/uk.po @@ -0,0 +1,913 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:17+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: \n" +"Language-Team: Ukrainian\n" +"Language: uk_UA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_rewind.pot\n" +"X-Crowdin-File-ID: 504\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "недостатньо пам'яті\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" + +#: ../../common/restricted_token.c:64 +#, c-format +msgid "could not load library \"%s\": error code %lu" +msgstr "не вдалося завантажити бібліотеку \"%s\": код помилки %lu" + +#: ../../common/restricted_token.c:73 +#, c-format +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "не вдалося створити обмежені токени на цій платформі: код помилки %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "не вдалося відкрити токен процесу: код помилки %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "не вдалося виділити SID: код помилки %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "не вдалося створити обмежений токен: код помилки %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "не вдалося запустити процес для команди \"%s\": код помилки %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "не вдалося перезапустити з обмеженим токеном: код помилки %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "не вдалося отримати код завершення підпроцесу: код помилки %lu" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "cannot use restore_command with %%r placeholder" +msgstr "не вдалося використати restore_command із заповнювачем %%r" + +#: ../../fe_utils/archive.c:74 +#, c-format +msgid "unexpected file size for \"%s\": %lu instead of %lu" +msgstr "неочікуваний розмір файлу для \"%s\": %lu замість %lu" + +#: ../../fe_utils/archive.c:85 +#, c-format +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "не вдалося відкрити файл \"%s\" відновлений з архіву: %m" + +#: ../../fe_utils/archive.c:97 copy_fetch.c:88 filemap.c:208 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не вдалося отримати інформацію від файлу \"%s\": %m" + +#: ../../fe_utils/archive.c:112 +#, c-format +msgid "restore_command failed: %s" +msgstr "помилка restore_command: %s" + +#: ../../fe_utils/archive.c:121 +#, c-format +msgid "could not restore file \"%s\" from archive" +msgstr "не вдалося відновити файл \"%s\" з архіву" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:73 parsexlog.c:125 +#: parsexlog.c:185 +#, c-format +msgid "out of memory" +msgstr "недостатньо пам'яті" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:298 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "неможливо записати до файлу \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "неможливо створити файл \"%s\": %m" + +#: copy_fetch.c:59 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не вдалося відкрити каталог \"%s\": %m" + +#: copy_fetch.c:117 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не можливо прочитати символічне послання \"%s\": %m" + +#: copy_fetch.c:120 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "таргет символічного посилання \"%s\" задовгий" + +#: copy_fetch.c:135 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "\"%s\"є символічним посиланням, але символічні посилання не підтримуються на даній платформі" + +#: copy_fetch.c:142 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "не вдалося прочитати каталог \"%s\": %m" + +#: copy_fetch.c:146 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не вдалося закрити каталог \"%s\": %m" + +#: copy_fetch.c:166 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "не вдалося відкрити вихідний файл \"%s\": %m" + +#: copy_fetch.c:170 +#, c-format +msgid "could not seek in source file: %m" +msgstr "не вдалося знайти у вихідному файлі: %m" + +#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:336 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не вдалося прочитати файл \"%s\": %m" + +#: copy_fetch.c:190 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "неочікуваний кінець при читанні файлу \"%s\"" + +#: copy_fetch.c:197 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "неможливо закрити файл \"%s\": %m" + +#: file_ops.c:62 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "не вдалося відкрити цільовий файл \"%s\": %m" + +#: file_ops.c:76 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "не вдалося закрити цільовий файл \"%s\": %m" + +#: file_ops.c:96 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "не вдалося знайти в цільовому файлі \"%s\": %m" + +#: file_ops.c:112 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "не вдалося записати файл \"%s\": %m" + +#: file_ops.c:162 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "неприпустима дія (CREATE) для звичайного файлу" + +#: file_ops.c:185 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "не можливо видалити файл \"%s\": %m" + +#: file_ops.c:203 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "не вдалося відкрити файл \"%s\" для скорочення: %m" + +#: file_ops.c:207 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "не вдалося скоротити файл \"%s\" до потрібного розміру %u: %m" + +#: file_ops.c:223 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "не вдалося створити каталог \"%s\": %m" + +#: file_ops.c:237 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "не вдалося видалити каталог \"%s\": %m" + +#: file_ops.c:251 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "неможливо створити символічне послання на \"%s\": %m" + +#: file_ops.c:265 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "не вдалося видалити символьне посилання \"%s\": %m" + +#: file_ops.c:296 file_ops.c:300 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "не вдалося відкрити файл \"%s\" для читання: %m" + +#: file_ops.c:314 parsexlog.c:338 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не вдалося прочитати файл \"%s\": прочитано %d з %zu" + +#: filemap.c:200 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "файл даних \"%s\" в джерелі не є регулярним файлом" + +#: filemap.c:222 +#, c-format +msgid "\"%s\" is not a directory" +msgstr "\"%s\" не є каталогом" + +#: filemap.c:245 +#, c-format +msgid "\"%s\" is not a symbolic link" +msgstr "\"%s\" не є символічним посиланням" + +#: filemap.c:257 +#, c-format +msgid "\"%s\" is not a regular file" +msgstr "\"%s\" не є регулярним файлом" + +#: filemap.c:369 +#, c-format +msgid "source file list is empty" +msgstr "список файлів в джерелі порожній" + +#: filemap.c:484 +#, c-format +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "неочікувана модифікація сторінки для каталогу або символічного посилання \"%s\"" + +#: libpq_fetch.c:50 +#, c-format +msgid "could not connect to server: %s" +msgstr "не вдалося підключитися до сервера: %s" + +#: libpq_fetch.c:54 +#, c-format +msgid "connected to server" +msgstr "під'єднано до серверу" + +#: libpq_fetch.c:63 +#, c-format +msgid "could not clear search_path: %s" +msgstr "не вдалося очистити search_path: %s" + +#: libpq_fetch.c:75 +#, c-format +msgid "source server must not be in recovery mode" +msgstr "початковий сервер не повинен бути у стані відновлення" + +#: libpq_fetch.c:85 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "на початковому сервері повинно бути увімкнено full_page_writes" + +#: libpq_fetch.c:111 +#, c-format +msgid "error running query (%s) on source server: %s" +msgstr "помилка при виконанні запиту (%s) на вихідному сервері: %s" + +#: libpq_fetch.c:116 +#, c-format +msgid "unexpected result set from query" +msgstr "неочікуваний результат запиту" + +#: libpq_fetch.c:137 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "помилка при виконанні запиту (%s) на початковому сервері: %s" + +#: libpq_fetch.c:157 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "нерозпізнаний результат \"%s\" замість поточної добавленої позиції WAL" + +#: libpq_fetch.c:207 +#, c-format +msgid "could not fetch file list: %s" +msgstr "не вдалося отримати список файлів: %s" + +#: libpq_fetch.c:212 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "неочікуваний результат при отриманні списку файлів" + +#: libpq_fetch.c:265 +#, c-format +msgid "could not send query: %s" +msgstr "не вдалося надіслати запит: %s" + +#: libpq_fetch.c:270 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "не вдалося встановити libpq з'єднання для однорядкового режиму" + +#: libpq_fetch.c:290 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "неочікуваний результат при отриманні віддалених файлів: %s" + +#: libpq_fetch.c:296 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "неочікуваний розмір набору результатів при отриманні віддалених файлів" + +#: libpq_fetch.c:302 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "неочікувані типи даних в результаті при отриманні віддалених файлів: %u %u %u" + +#: libpq_fetch.c:310 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "неочікуваний формат результату при отриманні віддалених файлів" + +#: libpq_fetch.c:316 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "неочікувані нульові значення в результаті при отриманні віддалених файлів" + +#: libpq_fetch.c:320 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "неочікувана довжина результату при отриманні віддалених файлів" + +#: libpq_fetch.c:381 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "не вдалося отримати віддалений файл \"%s\": %s" + +#: libpq_fetch.c:386 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "неочікуваний набір результатів при отриманні віддаленого файлу \"%s\"" + +#: libpq_fetch.c:430 +#, c-format +msgid "could not send COPY data: %s" +msgstr "не вдалося надіслати дані COPY: %s" + +#: libpq_fetch.c:459 +#, c-format +msgid "could not send file list: %s" +msgstr "не вдалося надіслати список файлів: %s" + +#: libpq_fetch.c:501 +#, c-format +msgid "could not send end-of-COPY: %s" +msgstr "не вдалося надіслати сповіщення про закінчення копіювання: %s" + +#: libpq_fetch.c:507 +#, c-format +msgid "unexpected result while sending file list: %s" +msgstr "неочікуваний результат при надсиланні списку файлів: %s" + +#: parsexlog.c:85 parsexlog.c:132 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "не вдалося прочитати запис WAL на %X/%X: %s" + +#: parsexlog.c:89 parsexlog.c:135 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "не вдалося прочитати запис WAL на %X/%X" + +#: parsexlog.c:198 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "не вдалося знайти попередній запис WAL на %X/%X: %s" + +#: parsexlog.c:202 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "не вдалося знайти попередній запис WAL на %X/%X" + +#: parsexlog.c:327 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "не вдалося знайти в файлі \"%s\": %m" + +#: parsexlog.c:407 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WAL модифікує відношення, але тип запису не розпізнано: lsn: %X/%X, rmgr: %s, info: %02X" + +#: pg_rewind.c:78 +#, c-format +msgid "%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n\n" +msgstr "%s синхронізує кластер PostgreSQL з іншою копією кластеру.\n\n" + +#: pg_rewind.c:79 +#, c-format +msgid "Usage:\n" +" %s [OPTION]...\n\n" +msgstr "Використання:\n" +" %s [OPTION]...\n\n" + +#: pg_rewind.c:80 +#, c-format +msgid "Options:\n" +msgstr "Параметри:\n" + +#: pg_rewind.c:81 +#, c-format +msgid " -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr " -c, --restore-target-wal використовує restore_command в цільовій конфігурації, щоб\n" +" отримати файли WAL з архівів\n" + +#: pg_rewind.c:83 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=DIRECTORY існуючий каталог для змін\n" + +#: pg_rewind.c:84 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr " --source-pgdata=DIRECTORY початковий каталог даних для синхронізації\n" + +#: pg_rewind.c:85 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=CONNSTR початковий сервер для синхронізації\n" + +#: pg_rewind.c:86 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run зупинитися до внесення будь-яких змін\n" + +#: pg_rewind.c:87 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr " -N, --no-sync не чекати поки зміни будуть записані на диск\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress повідомляти про хід процесу\n" + +#: pg_rewind.c:90 +#, c-format +msgid " -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr " -R, --write-recovery-conf записує конфігурацію для реплікації \n" +" (потребує --source-server)\n" + +#: pg_rewind.c:92 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug виводити багато налагоджувальних повідомлень\n" + +#: pg_rewind.c:93 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr " --no-ensure-shutdown не виправляти автоматично неочищене завершення роботи\n" + +#: pg_rewind.c:94 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію і вийти\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати довідку, потім вийти\n" + +#: pg_rewind.c:96 +#, c-format +msgid "\n" +"Report bugs to <%s>.\n" +msgstr "\n" +"Повідомляти про помилки на <%s>.\n" + +#: pg_rewind.c:97 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: pg_rewind.c:159 pg_rewind.c:208 pg_rewind.c:215 pg_rewind.c:222 +#: pg_rewind.c:229 pg_rewind.c:237 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: pg_rewind.c:207 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "джерело не вказано (--source-pgdata чи --source-server)" + +#: pg_rewind.c:214 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "може бути вказано лише --source-pgdata чи --source-server" + +#: pg_rewind.c:221 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "не вказано жодного каталогу цільових даних (--target-pgdata)" + +#: pg_rewind.c:228 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "немає інформації про вихідний сервер (--source-server) вказаної для --write-recovery-conf" + +#: pg_rewind.c:235 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" + +#: pg_rewind.c:250 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "\"root\" не може це виконувати" + +#: pg_rewind.c:251 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "Запускати %s треба від суперкористувача PostgreSQL.\n" + +#: pg_rewind.c:262 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "не вдалося прочитати дозволи на каталог \"%s\": %m" + +#: pg_rewind.c:316 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "початковий і цільовий кластери знаходяться на одній лінії часу" + +#: pg_rewind.c:322 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "сервери розійшлись в позиції WAL %X/%X на лінії часу %u" + +#: pg_rewind.c:360 +#, c-format +msgid "no rewind required" +msgstr "перемотування не потрібне" + +#: pg_rewind.c:369 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "перемотування від останньої спільної контрольної точки на %X/%X на лінії часу %u" + +#: pg_rewind.c:378 +#, c-format +msgid "reading source file list" +msgstr "читання списку файлів із джерела" + +#: pg_rewind.c:381 +#, c-format +msgid "reading target file list" +msgstr "читання списку цільових файлів" + +#: pg_rewind.c:392 +#, c-format +msgid "reading WAL in target" +msgstr "читання WAL у цілі" + +#: pg_rewind.c:409 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "треба скопіювати %lu МБ (загальний розмір каталогу джерела становить %lu МБ)" + +#: pg_rewind.c:427 +#, c-format +msgid "creating backup label and updating control file" +msgstr "створення мітки резервного копіювання і оновлення контрольного файлу" + +#: pg_rewind.c:457 +#, c-format +msgid "syncing target data directory" +msgstr "синхронізація цільового каталогу даних" + +#: pg_rewind.c:464 +#, c-format +msgid "Done!" +msgstr "Готово!" + +#: pg_rewind.c:476 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "початковий і цільовий кластер належать до різних систем" + +#: pg_rewind.c:484 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "кластери не сумісні з даною версією pg_rewind" + +#: pg_rewind.c:494 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "цільовий сервер потребує використання контрольної суми даних або \"wal_log_hints = on\"" + +#: pg_rewind.c:505 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "цільовий сервер повинен бути вимкненим штатно" + +#: pg_rewind.c:515 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "робота з початковим каталогом даних повинна бути завершена штатно" + +#: pg_rewind.c:567 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "скопійовано %*s/%s кБ (%d%%)" + +#: pg_rewind.c:630 +#, c-format +msgid "invalid control file" +msgstr "неприпустимий контрольний файл" + +#: pg_rewind.c:714 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "не вдалося знайти спільного предка ліній часу початкового та цільового кластерів" + +#: pg_rewind.c:755 +#, c-format +msgid "backup label buffer too small" +msgstr "буфер для мітки резервного копіювання замалий" + +#: pg_rewind.c:778 +#, c-format +msgid "unexpected control file CRC" +msgstr "неочікуваний контрольний файл CRC" + +#: pg_rewind.c:788 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "неочікуваний розмір контрольного файлу %d, очікувалося %d" + +#: pg_rewind.c:797 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" +msgstr[1] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" +msgstr[2] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" +msgstr[3] "Розмір сегменту WAL повинен задаватись ступенем 2 в інтервалі від 1 МБ до 1 ГБ, але в керуючому файлі вказано значення %d" + +#: pg_rewind.c:854 pg_rewind.c:912 +#, c-format +msgid "The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "Програма \"%s\" потрібна для %s, але не знайдена в тому ж каталозі, що й \"%s\".\n" +"Перевірте вашу установку." + +#: pg_rewind.c:859 pg_rewind.c:917 +#, c-format +msgid "The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "Програма \"%s\" була знайдена \"%s\", але не була тієї ж версії, що %s.\n" +"Перевірте вашу установку." + +#: pg_rewind.c:880 +#, c-format +msgid "restore_command is not set in the target cluster" +msgstr "команда restore_command не встановлена в цільовому кластері" + +#: pg_rewind.c:923 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "виконання \"%s\" для цільового серверу, щоб завершити відновлення після аварійного завершення роботи" + +#: pg_rewind.c:943 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "не вдалося ввімкнути однокористувацький режим postgres в цільовому кластері" + +#: pg_rewind.c:944 +#, c-format +msgid "Command was: %s" +msgstr "Команда була: %s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "синтаксична помилка у файлі історії: %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Очікується числовий ідентифікатор лінії часу." + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Очікується положення точки випереджувального журналювання." + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "неприпустимі дані у файлу історії: %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Ідентифікатори ліній часу повинні збільшуватись." + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "неприпустимі дані у файлі історії" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Ідентифікатори ліній часу повинні бути меншими від ідентифікатора дочірньої лінії." + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "невірний зсув запису: %X/%X" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "по зсуву %X/%X запитано продовження запису" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "невірна довжина запису по зсуву %X/%X: очікувалось %u, отримано %u" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "довжина запису %u на %X/%X є задовгою" + +#: xlogreader.c:454 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "немає флага contrecord в позиції %X/%X" + +#: xlogreader.c:467 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "невірна довижна contrecord (%u) в позиції %X/%X" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "невірний ID менеджера ресурсів %u в %X/%X" + +#: xlogreader.c:717 xlogreader.c:734 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "запис з неправильним попереднім посиланням %X/%X на %X/%X" + +#: xlogreader.c:771 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "некоректна контрольна сума даних менеджера ресурсів у запису по зсуву %X/%X" + +#: xlogreader.c:808 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "невірне магічне число %04X в сегменті журналу %s, зсув %u" + +#: xlogreader.c:822 xlogreader.c:863 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "невірні інформаційні біти %04X в сегменті журналу %s, зсув %u" + +#: xlogreader.c:837 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL файл належить іншій системі баз даних: ідентифікатор системи баз даних де міститься WAL файл - %llu, а ідентифікатор системи баз даних pg_control - %llu" + +#: xlogreader.c:845 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "Файл WAL належить іншій системі баз даних: некоректний розмір сегменту в заголовку сторінки" + +#: xlogreader.c:851 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "Файл WAL належить іншій системі баз даних: некоректний XLOG_BLCKSZ в заголовку сторінки" + +#: xlogreader.c:882 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "неочікуваний pageaddr %X/%X в сегменті журналу %s, зсув %u" + +#: xlogreader.c:907 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "порушення послідовності ID лінії часу %u (після %u) в сегменті журналу %s, зсув %u" + +#: xlogreader.c:1247 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "ідентифікатор блока %u out-of-order в позиції %X/%X" + +#: xlogreader.c:1270 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA встановлений, але немає даних в позиції %X/%X" + +#: xlogreader.c:1277 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA встановлений, але довжина даних дорівнює %u в позиції %X/%X" + +#: xlogreader.c:1313 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE встановлений, але для пропуску задані: зсув %u, довжина %u, при довжині образу блока %u в позиції %X/%X" + +#: xlogreader.c:1329 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE не встановлений, але для пропуску задані: зсув %u, довжина %u в позиції %X/%X" + +#: xlogreader.c:1344 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED встановлений, але довжина образу блока дорівнює %u в позиції %X/%X" + +#: xlogreader.c:1359 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "ні BKPIMAGE_HAS_HOLE, ні BKPIMAGE_IS_COMPRESSED не встановлені, але довжина образу блока дорвінює %u в позиції %X/%X" + +#: xlogreader.c:1375 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL встановлений, але попереднє значення не задано в позиції %X/%X" + +#: xlogreader.c:1387 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "невірний ідентифікатор блоку %u в позиції %X/%X" + +#: xlogreader.c:1476 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "запис з невірною довжиною на %X/%X" + +#: xlogreader.c:1565 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "невірно стиснутий образ в позиції %X/%X, блок %d" + diff --git a/src/bin/pg_rewind/po/zh_CN.po b/src/bin/pg_rewind/po/zh_CN.po new file mode 100644 index 000000000000..65db1ffb03fb --- /dev/null +++ b/src/bin/pg_rewind/po/zh_CN.po @@ -0,0 +1,935 @@ +# LANGUAGE message translation file for pg_rewind +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_rewind (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-09 21:19+0000\n" +"PO-Revision-Date: 2021-06-09 10:00+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.5.7\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "致命的: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "错误: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "内存溢出\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "无法复制空指针 (内部错误)\n" + +#: ../../common/restricted_token.c:64 +msgid "could not load library \"%s\": error code %lu" +msgstr "无法加载库 \"%s\": 错误码 %lu" + +#: ../../common/restricted_token.c:73 +msgid "cannot create restricted tokens on this platform: error code %lu" +msgstr "无法为该平台创建受限制的令牌:错误码 %lu" + +#: ../../common/restricted_token.c:82 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "无法打开进程令牌 (token): 错误码 %lu" + +#: ../../common/restricted_token.c:97 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "无法分配SID: 错误码 %lu" + +#: ../../common/restricted_token.c:119 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "无法创建受限令牌: 错误码为 %lu" + +#: ../../common/restricted_token.c:140 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "无法为命令 \"%s\"创建进程: 错误码 %lu" + +#: ../../common/restricted_token.c:178 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "无法使用受限令牌再次执行: 错误码 %lu" + +#: ../../common/restricted_token.c:194 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "无法从子进程得到退出码: 错误码 %lu" + +#: ../../fe_utils/archive.c:53 +#, c-format +msgid "cannot use restore_command with %%r placeholder" +msgstr "无法对%%r占位符使用restore_command" + +#: ../../fe_utils/archive.c:74 +msgid "unexpected file size for \"%s\": %lld instead of %lld" +msgstr "\"%s\"的意外文件大小:%lld而不是%lld" + +#: ../../fe_utils/archive.c:85 +msgid "could not open file \"%s\" restored from archive: %m" +msgstr "无法打开从存档还原的文件\"%s\": %m" + +#: ../../fe_utils/archive.c:97 file_ops.c:417 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "无法取文件 \"%s\" 的状态: %m" + +#: ../../fe_utils/archive.c:112 +msgid "restore_command failed: %s" +msgstr "restore_command失败: %s" + +#: ../../fe_utils/archive.c:121 +msgid "could not restore file \"%s\" from archive" +msgstr "无法从存档还原文件\"%s\"" + +#: ../../fe_utils/recovery_gen.c:35 ../../fe_utils/recovery_gen.c:49 +#: ../../fe_utils/recovery_gen.c:77 ../../fe_utils/recovery_gen.c:100 +#: ../../fe_utils/recovery_gen.c:171 parsexlog.c:77 parsexlog.c:135 +#: parsexlog.c:195 +#, c-format +msgid "out of memory" +msgstr "内存用尽" + +#: ../../fe_utils/recovery_gen.c:134 parsexlog.c:308 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "无法打开文件 \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:140 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "无法写入文件 \"%s\": %m" + +#: ../../fe_utils/recovery_gen.c:152 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "无法创建文件 \"%s\": %m" + +#: file_ops.c:67 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "无法打开目标文件\"%s\": %m" + +#: file_ops.c:81 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "无法关闭目标文件\"%s\": %m" + +#: file_ops.c:101 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "无法在目标文件\"%s\"中定位(seek): %m" + +#: file_ops.c:117 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "无法写入文件 \"%s\": %m" + +#: file_ops.c:150 file_ops.c:177 +msgid "undefined file type for \"%s\"" +msgstr "不可识别的文件格式 \"%s\"" + +#: file_ops.c:173 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "对常规文件无效的动作(CREATE)" + +#: file_ops.c:200 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "无法删除文件 \"%s\": %m" + +#: file_ops.c:218 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "无法打开文件\"%s\"用于截断:%m" + +#: file_ops.c:222 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "无法将文件\"%s\"截断为%u:%m" + +#: file_ops.c:238 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "无法创建目录 \"%s\": %m" + +#: file_ops.c:252 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "无法删除目录 \"%s\": %m" + +#: file_ops.c:266 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "无法在\"%s\"创建符号链接: %m" + +#: file_ops.c:280 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "无法删除符号链接 \"%s\": %m" + +#: file_ops.c:326 file_ops.c:330 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "为了读取, 无法打开文件 \"%s\": %m" + +#: file_ops.c:341 local_source.c:107 parsexlog.c:346 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "无法读取文件 \"%s\": %m" + +#: file_ops.c:344 parsexlog.c:348 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "无法读取文件\"%1$s\":读取了%3$zu中的%2$d" + +#: file_ops.c:388 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "无法打开目录 \"%s\": %m" + +#: file_ops.c:446 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "无法读取符号链接 \"%s\": %m" + +#: file_ops.c:449 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "符号链接 \"%s\" 目标超长" + +#: file_ops.c:464 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "\"%s\"是一个符号链接,但是这个平台上不支持平台链接" + +#: file_ops.c:471 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "无法读取目录 \"%s\": %m" + +#: file_ops.c:475 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "无法关闭目录 \"%s\": %m" + +#: filemap.c:237 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "源头的数据文件\"%s\"不是一个常规文件" + +#: filemap.c:242 filemap.c:275 +msgid "duplicate source file \"%s\"" +msgstr "复制源文件\"%s\"" + +#: filemap.c:330 +msgid "unexpected page modification for non-regular file \"%s\"" +msgstr "非常规文件\"%s\"的意外页面修改" + +#: filemap.c:680 filemap.c:774 +msgid "unknown file type for \"%s\"" +msgstr "\"%s\"的未知文件类型" + +#: filemap.c:707 +msgid "file \"%s\" is of different type in source and target" +msgstr "文件 \"%s\"在源和目标中的类型不同" + +#: filemap.c:779 +msgid "could not decide what to do with file \"%s\"" +msgstr "无法决定如何处理文件\"%s\"" + +#: libpq_source.c:128 +#, c-format +msgid "could not clear search_path: %s" +msgstr "无法清除search_path: %s" + +#: libpq_source.c:139 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "源服务器中的full_page_writes必须被启用" + +#: libpq_source.c:150 +msgid "could not prepare statement to fetch file contents: %s" +msgstr "无法准备语句以获取文件内容: %s" + +#: libpq_source.c:169 +msgid "error running query (%s) on source server: %s" +msgstr "源服务器中有错误运行的查询(%s):%s" + +#: libpq_source.c:174 +#, c-format +msgid "unexpected result set from query" +msgstr "从查询得到意料之外的结果集" + +#: libpq_source.c:196 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "源服务器中有错误运行的查询(%s):%s" + +#: libpq_source.c:217 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "当前WAL插入位置的未识别结果\"%s\"" + +#: libpq_source.c:268 +#, c-format +msgid "could not fetch file list: %s" +msgstr "无法取得文件列表:%s" + +#: libpq_source.c:273 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "在取得文件列表时得到意料之外的结果集" + +#: libpq_source.c:435 +#, c-format +msgid "could not send query: %s" +msgstr "无法发送查询:%s" + +#: libpq_source.c:438 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "无法设置libpq连接为单行模式" + +#: libpq_source.c:468 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "在取得远程文件时得到意料之外的结果:%s" + +#: libpq_source.c:473 +msgid "received more data chunks than requested" +msgstr "收到的数据块比请求的多" + +#: libpq_source.c:477 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "在取得远程文件时得到意料之外的结果集大小" + +#: libpq_source.c:483 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "在取得远程文件时结果集中有意料之外的数据类型:%u %u %u" + +#: libpq_source.c:491 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "在取得远程文件时得到意料之外的结果格式" + +#: libpq_source.c:497 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "在取得远程文件时结果中有意料之外的空值" + +#: libpq_source.c:501 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "在取得远程文件时得到意料之外的结果长度" + +#: libpq_source.c:534 +#, c-format +msgid "received data for file \"%s\", when requested for \"%s\"" +msgstr "当为文件\"%2$s\"请求时,接收到文件\"%1$s\"的数据" + +#: libpq_source.c:538 +#, c-format +msgid "received data at offset %lld of file \"%s\", when requested for offset %lld" +msgstr "当请求偏移量%3$lld时,在文件\"%2$s\"的偏移量%1$lld处接收到数据" + +#: libpq_source.c:550 +msgid "received more than requested for file \"%s\"" +msgstr "收到的文件\"%s\"比要求的多" + +#: libpq_source.c:563 +msgid "unexpected number of data chunks received" +msgstr "接收到意外的数据块数" + +#: libpq_source.c:606 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "无法取得远程文件\"%s\": %s" + +#: libpq_source.c:611 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "在取得远程文件\"%s\"时得到意料之外的结果集" + +#: local_source.c:86 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "无法打开源文件\"%s\": %m" + +#: local_source.c:90 +#, c-format +msgid "could not seek in source file: %m" +msgstr "无法在源文件中定位(seek):%m" + +#: local_source.c:109 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "读取文件\"%s\"时遇到意料之外的EOF" + +#: local_source.c:116 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "无法关闭文件 \"%s\": %m" + +#: parsexlog.c:89 parsexlog.c:142 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "无法读取%X/%X处的WAL记录:%s" + +#: parsexlog.c:93 parsexlog.c:145 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "无法读取%X/%X处的WAL记录" + +#: parsexlog.c:208 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "无法在%X/%X找到前一个WAL记录:%s" + +#: parsexlog.c:212 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "无法在%X/%X找到前一个WAL记录" + +#: parsexlog.c:337 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "无法在文件\"%s\"进行查找: %m" + +#: parsexlog.c:429 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WAL记录修改了一个关系,但是记录类型无法识别: lsn: %X/%X, rmgr: %s, info: %02X" + +#: pg_rewind.c:84 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s用一个PostgreSQL集簇的另一个拷贝重新同步了该集簇。\n" +"\n" + +#: pg_rewind.c:85 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"用法:\n" +" %s [选项]...\n" +"\n" + +#: pg_rewind.c:86 +#, c-format +msgid "Options:\n" +msgstr "选项:\n" + +#: pg_rewind.c:87 +#, c-format +msgid "" +" -c, --restore-target-wal use restore_command in target configuration to\n" +" retrieve WAL files from archives\n" +msgstr "" +" -c, --restore-target-wal 在目标配置中使用restore_command\n" +" 从存档中检索WAL文件\n" + +#: pg_rewind.c:89 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=DIRECTORY 已有的要修改的数据目录\n" + +#: pg_rewind.c:90 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr " --source-pgdata=DIRECTORY 要与之同步的源数据目录\n" + +#: pg_rewind.c:91 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=CONNSTR 要与之同步的源服务器\n" + +#: pg_rewind.c:92 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run 在修改任何东西之前停止\n" + +#: pg_rewind.c:93 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr "" +" -N, --no-sync 不用等待变化安全\n" +" 写入磁盘\n" + +#: pg_rewind.c:95 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress 写出进度消息\n" + +#: pg_rewind.c:96 +msgid "" +" -R, --write-recovery-conf write configuration for replication\n" +" (requires --source-server)\n" +msgstr "" +" -R, --write-recovery-conf 为复制写配置文\n" +" (requires --source-server)\n" + +#: pg_rewind.c:98 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug 写出很多调试消息\n" + +#: pg_rewind.c:99 +#, c-format +msgid " --no-ensure-shutdown do not automatically fix unclean shutdown\n" +msgstr " --no-ensure-shutdown 不要自动修复不干净的关机\n" + +#: pg_rewind.c:100 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 输出版本信息,然后退出\n" + +#: pg_rewind.c:101 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 显示本帮助,然后退出\n" + +#: pg_rewind.c:102 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"臭虫报告至<%s>.\n" + +#: pg_rewind.c:103 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 主页: <%s>\n" + +#: pg_rewind.c:164 pg_rewind.c:213 pg_rewind.c:220 pg_rewind.c:227 +#: pg_rewind.c:234 pg_rewind.c:242 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "请用 \"%s --help\" 获取更多的信息.\n" + +#: pg_rewind.c:212 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "没有指定源 (--source-pgdata 或者 --source-server)" + +#: pg_rewind.c:219 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "只能指定--source-pgdata和--source-server这两个选项之一" + +#: pg_rewind.c:226 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "没有指定目标数据目录 (--target-pgdata)" + +#: pg_rewind.c:233 +#, c-format +msgid "no source server information (--source-server) specified for --write-recovery-conf" +msgstr "没有为--write-recovery-conf指定源服务器信息(--source-server)" + +#: pg_rewind.c:240 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "命令行参数太多 (第一个是 \"%s\")" + +#: pg_rewind.c:255 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "不能由\"root\"执行" + +#: pg_rewind.c:256 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "您现在作为PostgreSQL超级用户运行%s.\n" + +#: pg_rewind.c:267 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "没有读取目录 \"%s\" 的权限: %m" + +#: pg_rewind.c:287 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_rewind.c:290 +#, c-format +msgid "connected to server" +msgstr "已连接服务器" + +#: pg_rewind.c:337 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "源集簇和目标集簇处于同一时间线" + +#: pg_rewind.c:346 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "服务器在时间线%3$u上的WAL位置%1$X/%2$X处发生了分歧" + +#: pg_rewind.c:394 +#, c-format +msgid "no rewind required" +msgstr "不需要倒带(rewind)" + +#: pg_rewind.c:403 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "从时间线%3$u上%1$X/%2$X处的最后一个普通检查点倒带" + +#: pg_rewind.c:413 +#, c-format +msgid "reading source file list" +msgstr "读取源文件列表" + +#: pg_rewind.c:417 +#, c-format +msgid "reading target file list" +msgstr "读取目标文件列表" + +#: pg_rewind.c:426 +#, c-format +msgid "reading WAL in target" +msgstr "读取目标中的WAL" + +#: pg_rewind.c:447 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "需要复制 %lu MB(整个源目录的大小是 %lu MB)" + +#: pg_rewind.c:465 +#, c-format +msgid "syncing target data directory" +msgstr "正在同步目标数据目录" + +#: pg_rewind.c:481 +#, c-format +msgid "Done!" +msgstr "完成!" + +#: pg_rewind.c:564 +msgid "no action decided for file \"%s\"" +msgstr "未决定对文件\"%s\"执行任何操作" + +#: pg_rewind.c:596 +#, c-format +msgid "source system was modified while pg_rewind was running" +msgstr "pg_rewind运行时修改了源系统" + +#: pg_rewind.c:600 +#, c-format +msgid "creating backup label and updating control file" +msgstr "正在创建备份标签并且更新控制文件" + +#: pg_rewind.c:650 +#, c-format +msgid "source system was in unexpected state at end of rewind" +msgstr "源系统在rewind结束时处于意外状态" + +#: pg_rewind.c:681 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "源集簇和目标集簇来自不同的系统" + +#: pg_rewind.c:689 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "集簇与这个pg_rewind的版本不兼容" + +#: pg_rewind.c:699 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "目标服务器需要使用数据校验和或者让\"wal_log_hints = on\"" + +#: pg_rewind.c:710 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "目标服务器必须被干净地关闭" + +#: pg_rewind.c:720 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "源数据目录必须被干净地关闭" + +#: pg_rewind.c:772 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "已复制%*s/%s kB (%d%%)" + +#: pg_rewind.c:835 +msgid "invalid control file" +msgstr "无效的控制文件" + +#: pg_rewind.c:919 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "无法找到源集簇和目标集簇的时间线的共同祖先" + +#: pg_rewind.c:960 +#, c-format +msgid "backup label buffer too small" +msgstr "备份标签缓冲太小" + +#: pg_rewind.c:983 +#, c-format +msgid "unexpected control file CRC" +msgstr "意料之外的控制文件CRC" + +#: pg_rewind.c:995 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "意料之外的控制文件大小%d,应该是%d" + +#: pg_rewind.c:1004 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL段大小必须是1 MB到1 GB之间的2的幂,但控制文件指定了%d字节" +msgstr[1] "WAL段大小必须是1 MB到1 GB之间的2的幂,但控制文件指定了%d字节" + +#: pg_rewind.c:1043 pg_rewind.c:1101 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%2$s需要程序\"%1$s\"\n" +"但在与\"%3$s\"相同的目录中找不到该程序.\n" +"检查您的安装." + +#: pg_rewind.c:1048 pg_rewind.c:1106 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"程序\"%s\"是由\"%s\"找到的\n" +"但与%s的版本不同.\n" +"检查您的安装." + +#: pg_rewind.c:1069 +msgid "restore_command is not set in the target cluster" +msgstr "目标群集中未设置restore_command" + +#: pg_rewind.c:1112 +#, c-format +msgid "executing \"%s\" for target server to complete crash recovery" +msgstr "对目标服务器执行\"%s\"以完成崩溃恢复" + +#: pg_rewind.c:1132 +#, c-format +msgid "postgres single-user mode in target cluster failed" +msgstr "目标群集中的postgres单用户模式失败" + +#: pg_rewind.c:1133 +msgid "Command was: %s" +msgstr "命令是: %s" + +#: timeline.c:75 timeline.c:81 +#, c-format +msgid "syntax error in history file: %s" +msgstr "历史文件中的语法错误: %s" + +#: timeline.c:76 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "期望一个数字 timeline ID." + +#: timeline.c:82 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "期望一个预写日志切换点位置." + +#: timeline.c:87 +#, c-format +msgid "invalid data in history file: %s" +msgstr "历史文件中的无效数据: %s" + +#: timeline.c:88 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "TimeLine ID 必须为递增序列." + +#: timeline.c:108 +#, c-format +msgid "invalid data in history file" +msgstr "历史文件中有无效数据" + +#: timeline.c:109 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Timeline ID 必须小于子 timeline 的 ID." + +#: xlogreader.c:349 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "%X/%X处有无效的记录偏移量" + +#: xlogreader.c:357 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "%X/%X请求继续记录(contrecord)" + +#: xlogreader.c:398 xlogreader.c:695 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "%X/%X处有无效记录长度: 应该是%u, 但实际是%u" + +#: xlogreader.c:422 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "%2$X/%3$X处有的记录长度%1$u过长" + +#: xlogreader.c:453 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "%X/%X处没有继续记录标志" + +#: xlogreader.c:466 +msgid "invalid contrecord length %u (expected %lld) at %X/%X" +msgstr "%3$X/%4$X处有无效的继续记录长度%1$u(应为 %2$lld)" + +#: xlogreader.c:703 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "%2$X/%3$X处有无效的资源管理器 ID %1$u" + +#: xlogreader.c:716 xlogreader.c:732 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "%3$X/%4$X处的记录有不正确的prev-link %1$X/%2$X" + +#: xlogreader.c:768 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "%X/%X处的记录中有不正确的资源管理器数据校验和" + +#: xlogreader.c:805 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "在日志段%2$s的偏移量%3$u处有无效的magic号%1$04X" + +#: xlogreader.c:819 xlogreader.c:860 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "在日志段%2$s的偏移量%3$u处有无效的info位%1$04X" + +#: xlogreader.c:834 +msgid "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu" +msgstr "WAL文件来自于不同的数据库系统:WAL文件数据库系统标识符是%llu,pg_control数据库系统标识符是%llu" + +#: xlogreader.c:842 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL文件来自于不同的数据库系统:页头部中有不正确的段大小" + +#: xlogreader.c:848 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL文件来自于不同的数据库系统:页头部中有不正确的XLOG_BLCKSZ" + +#: xlogreader.c:879 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "在日志段%3$s的偏移量%4$u处有意料之外的pageaddr %1$X/%2$X" + +#: xlogreader.c:904 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "在日志段%3$s的偏移量%4$u处有失序的时间线 ID %1$u(在%2$u之后)" + +#: xlogreader.c:1249 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "在%2$X/%3$X处有无序的block_id %1$u" + +#: xlogreader.c:1271 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA已被设置,但是在%X/%X处没有包括数据" + +#: xlogreader.c:1278 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA没有被设置,但是在%2$X/%3$X处的数据长度为%1$u" + +#: xlogreader.c:1314 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE已被设置,但是%4$X/%5$X处记录了洞偏移量为%1$u、长度为%2$u、块映像长度为%3$u" + +#: xlogreader.c:1330 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE没有被设置,但是%3$X/%4$X处记录了洞偏移量为%1$u、长度为%2$u" + +#: xlogreader.c:1345 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED已被设置,但是%2$X/%3$X处记录的块映像长度为%1$u" + +#: xlogreader.c:1360 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE和BKPIMAGE_IS_COMPRESSED都没有被设置,但是%2$X/%3$X处记录的块映像长度为%1$u" + +#: xlogreader.c:1376 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL已被设置,但是在%X/%X没有前一个关系" + +#: xlogreader.c:1388 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "%2$X/%3$X处有无效block_id %1$u" + +#: xlogreader.c:1475 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "%X/%X处的记录的长度无效" + +#: xlogreader.c:1564 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "%X/%X处是块%d的无效压缩映像" diff --git a/src/bin/pg_rewind/rewind_source.h b/src/bin/pg_rewind/rewind_source.h new file mode 100644 index 000000000000..2da92dbff948 --- /dev/null +++ b/src/bin/pg_rewind/rewind_source.h @@ -0,0 +1,73 @@ +/*------------------------------------------------------------------------- + * + * rewind_source.h + * Abstraction for fetching from source server. + * + * The source server can be either a libpq connection to a live system, + * or a local data directory. The 'rewind_source' struct abstracts the + * operations to fetch data from the source system, so that the rest of + * the code doesn't need to care what kind of a source its dealing with. + * + * Copyright (c) 2013-2021, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef REWIND_SOURCE_H +#define REWIND_SOURCE_H + +#include "access/xlogdefs.h" +#include "file_ops.h" +#include "filemap.h" +#include "libpq-fe.h" + +typedef struct rewind_source +{ + /* + * Traverse all files in the source data directory, and call 'callback' on + * each file. + */ + void (*traverse_files) (struct rewind_source *, + process_file_callback_t callback); + + /* + * Fetch a single file into a malloc'd buffer. The file size is returned + * in *filesize. The returned buffer is always zero-terminated, which is + * handy for text files. + */ + char *(*fetch_file) (struct rewind_source *, const char *path, + size_t *filesize); + + /* + * Request to fetch (part of) a file in the source system, specified by an + * offset and length, and write it to the same offset in the corresponding + * target file. The source implementation may queue up the request and + * execute it later when convenient. Call finish_fetch() to flush the + * queue and execute all requests. + */ + void (*queue_fetch_range) (struct rewind_source *, const char *path, + off_t offset, size_t len); + + /* + * Execute all requests queued up with queue_fetch_range(). + */ + void (*finish_fetch) (struct rewind_source *); + + /* + * Get the current WAL insert position in the source system. + */ + XLogRecPtr (*get_current_wal_insert_lsn) (struct rewind_source *); + + /* + * Free this rewind_source object. + */ + void (*destroy) (struct rewind_source *); + +} rewind_source; + +/* in libpq_source.c */ +extern rewind_source *init_libpq_source(PGconn *conn); + +/* in local_source.c */ +extern rewind_source *init_local_source(const char *datadir); + +#endif /* FETCH_H */ diff --git a/src/bin/pg_rewind/t/001_basic.pl b/src/bin/pg_rewind/t/001_basic.pl index ba528e262f32..d636f35f5e5e 100644 --- a/src/bin/pg_rewind/t/001_basic.pl +++ b/src/bin/pg_rewind/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; @@ -71,6 +74,8 @@ sub run_test primary_psql("VACUUM tail_tbl"); # Drop drop_tbl. pg_rewind should copy it back. + primary_psql( + "insert into drop_tbl values ('in primary, after promotion')"); primary_psql("DROP TABLE drop_tbl"); # Before running pg_rewind, do a couple of extra tests with several @@ -79,7 +84,7 @@ sub run_test # in "local" mode for simplicity's sake. if ($test_mode eq 'local') { - my $primary_pgdata = $node_primary->data_dir; + my $primary_pgdata = $node_primary->data_dir; my $standby_pgdata = $node_standby->data_dir; # First check that pg_rewind fails if the target cluster is diff --git a/src/bin/pg_rewind/t/002_databases.pl b/src/bin/pg_rewind/t/002_databases.pl index 5506fe425bca..72c4b225a7f1 100644 --- a/src/bin/pg_rewind/t/002_databases.pl +++ b/src/bin/pg_rewind/t/002_databases.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pg_rewind/t/003_extrafiles.pl b/src/bin/pg_rewind/t/003_extrafiles.pl index f53369d97c8d..8a087f0219eb 100644 --- a/src/bin/pg_rewind/t/003_extrafiles.pl +++ b/src/bin/pg_rewind/t/003_extrafiles.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Test how pg_rewind reacts to extra files and directories in the data dirs. use strict; @@ -24,10 +27,13 @@ sub run_test # Create a subdir and files that will be present in both mkdir "$test_primary_datadir/tst_both_dir"; - append_to_file "$test_primary_datadir/tst_both_dir/both_file1", "in both1"; - append_to_file "$test_primary_datadir/tst_both_dir/both_file2", "in both2"; + append_to_file "$test_primary_datadir/tst_both_dir/both_file1", + "in both1"; + append_to_file "$test_primary_datadir/tst_both_dir/both_file2", + "in both2"; mkdir "$test_primary_datadir/tst_both_dir/both_subdir/"; - append_to_file "$test_primary_datadir/tst_both_dir/both_subdir/both_file3", + append_to_file + "$test_primary_datadir/tst_both_dir/both_subdir/both_file3", "in both3"; RewindTest::create_standby($test_mode); @@ -40,10 +46,13 @@ sub run_test "in standby1"; append_to_file "$test_standby_datadir/tst_standby_dir/standby_file2", "in standby2"; - mkdir "$test_standby_datadir/tst_standby_dir/standby_subdir/"; append_to_file - "$test_standby_datadir/tst_standby_dir/standby_subdir/standby_file3", + "$test_standby_datadir/tst_standby_dir/standby_file3 with 'quotes'", "in standby3"; + mkdir "$test_standby_datadir/tst_standby_dir/standby_subdir/"; + append_to_file + "$test_standby_datadir/tst_standby_dir/standby_subdir/standby_file4", + "in standby4"; mkdir "$test_primary_datadir/tst_primary_dir"; append_to_file "$test_primary_datadir/tst_primary_dir/primary_file1", @@ -63,7 +72,9 @@ sub run_test RewindTest::promote_standby(); RewindTest::run_pg_rewind($test_mode); - # List files in the data directory after rewind. + # List files in the data directory after rewind. All the files that + # were present in the standby should be present after rewind, and + # all the files that were added on the primary should be removed. my @paths; find( sub { @@ -85,8 +96,9 @@ sub run_test "$test_primary_datadir/tst_standby_dir", "$test_primary_datadir/tst_standby_dir/standby_file1", "$test_primary_datadir/tst_standby_dir/standby_file2", + "$test_primary_datadir/tst_standby_dir/standby_file3 with 'quotes'", "$test_primary_datadir/tst_standby_dir/standby_subdir", - "$test_primary_datadir/tst_standby_dir/standby_subdir/standby_file3" + "$test_primary_datadir/tst_standby_dir/standby_subdir/standby_file4" ], "file lists match"); diff --git a/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl b/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl index fff475850834..8fb0ab3eadd0 100644 --- a/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl +++ b/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # # Test pg_rewind when the target's pg_wal directory is a symlink. # diff --git a/src/bin/pg_rewind/t/005_same_timeline.pl b/src/bin/pg_rewind/t/005_same_timeline.pl index 8706d5aed5c4..efe1d4c77f5a 100644 --- a/src/bin/pg_rewind/t/005_same_timeline.pl +++ b/src/bin/pg_rewind/t/005_same_timeline.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # # Test that running pg_rewind with the source and target clusters # on the same timeline runs successfully. diff --git a/src/bin/pg_rewind/t/006_options.pl b/src/bin/pg_rewind/t/006_options.pl index 1515696e6635..81793899e59d 100644 --- a/src/bin/pg_rewind/t/006_options.pl +++ b/src/bin/pg_rewind/t/006_options.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # # Test checking options of pg_rewind. # diff --git a/src/bin/pg_rewind/t/007_standby_source.pl b/src/bin/pg_rewind/t/007_standby_source.pl new file mode 100644 index 000000000000..44319a8204eb --- /dev/null +++ b/src/bin/pg_rewind/t/007_standby_source.pl @@ -0,0 +1,181 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +# +# Test using a standby server as the source. +# +# This sets up three nodes: A, B and C. First, A is the primary, +# B follows A, and C follows B: +# +# A (primary) <--- B (standby) <--- C (standby) +# +# +# Then we promote C, and insert some divergent rows in A and C: +# +# A (primary) <--- B (standby) C (primary) +# +# +# Finally, we run pg_rewind on C, to re-point it at B again: +# +# A (primary) <--- B (standby) <--- C (standby) +# +# +# The test is similar to the basic tests, but since we're dealing with +# three nodes, not two, we cannot use most of the RewindTest functions +# as is. + +use strict; +use warnings; +use TestLib; +use Test::More tests => 3; + +use FindBin; +use lib $FindBin::RealBin; +use File::Copy; +use PostgresNode; +use RewindTest; + +my $tmp_folder = TestLib::tempdir; + +my $node_a; +my $node_b; +my $node_c; + +# Set up node A, as primary +# +# A (primary) + +setup_cluster('a'); +start_primary(); +$node_a = $node_primary; + +# Create a test table and insert a row in primary. +$node_a->safe_psql('postgres', "CREATE TABLE tbl1 (d text)"); +$node_a->safe_psql('postgres', "INSERT INTO tbl1 VALUES ('in A')"); +primary_psql("CHECKPOINT"); + +# Set up node B and C, as cascaded standbys +# +# A (primary) <--- B (standby) <--- C (standby) +$node_a->backup('my_backup'); +$node_b = get_new_node('node_b'); +$node_b->init_from_backup($node_a, 'my_backup', has_streaming => 1); +$node_b->set_standby_mode(); +$node_b->start; + +$node_b->backup('my_backup'); +$node_c = get_new_node('node_c'); +$node_c->init_from_backup($node_b, 'my_backup', has_streaming => 1); +$node_c->set_standby_mode(); +$node_c->start; + +# Insert additional data on A, and wait for both standbys to catch up. +$node_a->safe_psql('postgres', + "INSERT INTO tbl1 values ('in A, before promotion')"); +$node_a->safe_psql('postgres', 'CHECKPOINT'); + +my $lsn = $node_a->lsn('insert'); +$node_a->wait_for_catchup('node_b', 'write', $lsn); +$node_b->wait_for_catchup('node_c', 'write', $lsn); + +# Promote C +# +# A (primary) <--- B (standby) C (primary) + +$node_c->promote; +$node_c->safe_psql('postgres', "checkpoint"); + + +# Insert a row in A. This causes A/B and C to have "diverged", so that it's +# no longer possible to just apply the standy's logs over primary directory +# - you need to rewind. +$node_a->safe_psql('postgres', + "INSERT INTO tbl1 VALUES ('in A, after C was promoted')"); + +# make sure it's replicated to B before we continue +$lsn = $node_a->lsn('insert'); +$node_a->wait_for_catchup('node_b', 'replay', $lsn); + +# Also insert a new row in the standby, which won't be present in the +# old primary. +$node_c->safe_psql('postgres', + "INSERT INTO tbl1 VALUES ('in C, after C was promoted')"); + + +# +# All set up. We're ready to run pg_rewind. +# +my $node_c_pgdata = $node_c->data_dir; + +# Stop the node and be ready to perform the rewind. +$node_c->stop('fast'); + +# Keep a temporary postgresql.conf or it would be overwritten during the rewind. +copy( + "$node_c_pgdata/postgresql.conf", + "$tmp_folder/node_c-postgresql.conf.tmp"); + +{ + # Temporarily unset PGAPPNAME so that the server doesn't + # inherit it. Otherwise this could affect libpqwalreceiver + # connections in confusing ways. + local %ENV = %ENV; + delete $ENV{PGAPPNAME}; + + # Do rewind using a remote connection as source, generating + # recovery configuration automatically. + command_ok( + [ + 'pg_rewind', "--debug", + "--source-server", $node_b->connstr('postgres'), + "--target-pgdata=$node_c_pgdata", "--no-sync", + "--write-recovery-conf" + ], + 'pg_rewind remote'); +} + +# Now move back postgresql.conf with old settings +move( + "$tmp_folder/node_c-postgresql.conf.tmp", + "$node_c_pgdata/postgresql.conf"); + +# Restart the node. +$node_c->start; + +# set RewindTest::node_primary to point to the rewinded node, so that we can +# use check_query() +$node_primary = $node_c; + +# Run some checks to verify that C has been successfully rewound, +# and connected back to follow B. + +check_query( + 'SELECT * FROM tbl1', + qq(in A +in A, before promotion +in A, after C was promoted +), + 'table content after rewind'); + +# Insert another row, and observe that it's cascaded from A to B to C. +$node_a->safe_psql('postgres', + "INSERT INTO tbl1 values ('in A, after rewind')"); + +$lsn = $node_a->lsn('insert'); +$node_b->wait_for_catchup('node_c', 'replay', $lsn); + +check_query( + 'SELECT * FROM tbl1', + qq(in A +in A, before promotion +in A, after C was promoted +in A, after rewind +), + 'table content after rewind and insert'); + +# clean up +$node_a->teardown_node; +$node_b->teardown_node; +$node_c->teardown_node; + +exit(0); diff --git a/src/bin/pg_rewind/t/008_min_recovery_point.pl b/src/bin/pg_rewind/t/008_min_recovery_point.pl new file mode 100644 index 000000000000..9ebcbad0d266 --- /dev/null +++ b/src/bin/pg_rewind/t/008_min_recovery_point.pl @@ -0,0 +1,177 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +# +# Test situation where a target data directory contains +# WAL records beyond both the last checkpoint and the divergence +# point: +# +# Target WAL (TLI 2): +# +# backup ... Checkpoint A ... INSERT 'rewind this' +# (TLI 1 -> 2) +# +# ^ last common ^ minRecoveryPoint +# checkpoint +# +# Source WAL (TLI 3): +# +# backup ... Checkpoint A ... Checkpoint B ... INSERT 'keep this' +# (TLI 1 -> 2) (TLI 2 -> 3) +# +# +# The last common checkpoint is Checkpoint A. But there is WAL on TLI 2 +# after the last common checkpoint that needs to be rewound. We used to +# have a bug where minRecoveryPoint was ignored, and pg_rewind concluded +# that the target doesn't need rewinding in this scenario, because the +# last checkpoint on the target TLI was an ancestor of the source TLI. +# +# +# This test does not make use of RewindTest as it requires three +# nodes. + +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 3; + +use File::Copy; + +my $tmp_folder = TestLib::tempdir; + +my $node_1 = get_new_node('node_1'); +$node_1->init(allows_streaming => 1); +$node_1->append_conf( + 'postgresql.conf', qq( +wal_keep_size='100 MB' +)); + +$node_1->start; + +# Create a couple of test tables +$node_1->safe_psql('postgres', 'CREATE TABLE public.foo (t TEXT)'); +$node_1->safe_psql('postgres', 'CREATE TABLE public.bar (t TEXT)'); +$node_1->safe_psql('postgres', "INSERT INTO public.bar VALUES ('in both')"); + +# +# Create node_2 and node_3 as standbys following node_1 +# +my $backup_name = 'my_backup'; +$node_1->backup($backup_name); + +my $node_2 = get_new_node('node_2'); +$node_2->init_from_backup($node_1, $backup_name, has_streaming => 1); +$node_2->start; + +my $node_3 = get_new_node('node_3'); +$node_3->init_from_backup($node_1, $backup_name, has_streaming => 1); +$node_3->start; + +# Wait until node 3 has connected and caught up +my $lsn = $node_1->lsn('insert'); +$node_1->wait_for_catchup('node_3', 'replay', $lsn); + +# +# Swap the roles of node_1 and node_3, so that node_1 follows node_3. +# +$node_1->stop('fast'); +$node_3->promote; +# Force a checkpoint after the promotion. pg_rewind looks at the control +# file to determine what timeline the server is on, and that isn't updated +# immediately at promotion, but only at the next checkpoint. When running +# pg_rewind in remote mode, it's possible that we complete the test steps +# after promotion so quickly that when pg_rewind runs, the standby has not +# performed a checkpoint after promotion yet. +$node_3->safe_psql('postgres', "checkpoint"); + +# reconfigure node_1 as a standby following node_3 +my $node_3_connstr = $node_3->connstr; +$node_1->append_conf( + 'postgresql.conf', qq( +primary_conninfo='$node_3_connstr' +)); +$node_1->set_standby_mode(); +$node_1->start(); + +# also reconfigure node_2 to follow node_3 +$node_2->append_conf( + 'postgresql.conf', qq( +primary_conninfo='$node_3_connstr' +)); +$node_2->restart(); + +# +# Promote node_1, to create a split-brain scenario. +# + +# make sure node_1 is full caught up with node_3 first +$lsn = $node_3->lsn('insert'); +$node_3->wait_for_catchup('node_1', 'replay', $lsn); + +$node_1->promote; +# Force a checkpoint after promotion, like earlier. +$node_1->safe_psql('postgres', "checkpoint"); + +# +# We now have a split-brain with two primaries. Insert a row on both to +# demonstratively create a split brain. After the rewind, we should only +# see the insert on 1, as the insert on node 3 is rewound away. +# +$node_1->safe_psql('postgres', + "INSERT INTO public.foo (t) VALUES ('keep this')"); +# 'bar' is unmodified in node 1, so it won't be overwritten by replaying the +# WAL from node 1. +$node_3->safe_psql('postgres', + "INSERT INTO public.bar (t) VALUES ('rewind this')"); + +# Insert more rows in node 1, to bump up the XID counter. Otherwise, if +# rewind doesn't correctly rewind the changes made on the other node, +# we might fail to notice if the inserts are invisible because the XIDs +# are not marked as committed. +$node_1->safe_psql('postgres', + "INSERT INTO public.foo (t) VALUES ('and this')"); +$node_1->safe_psql('postgres', + "INSERT INTO public.foo (t) VALUES ('and this too')"); + +# Wait for node 2 to catch up +$node_2->poll_query_until('postgres', + q|SELECT COUNT(*) > 1 FROM public.bar|, 't'); + +# At this point node_2 will shut down without a shutdown checkpoint, +# but with WAL entries beyond the preceding shutdown checkpoint. +$node_2->stop('fast'); +$node_3->stop('fast'); + +my $node_2_pgdata = $node_2->data_dir; +my $node_1_connstr = $node_1->connstr; + +# Keep a temporary postgresql.conf or it would be overwritten during the rewind. +copy( + "$node_2_pgdata/postgresql.conf", + "$tmp_folder/node_2-postgresql.conf.tmp"); + +command_ok( + [ + 'pg_rewind', "--source-server=$node_1_connstr", + "--target-pgdata=$node_2_pgdata", "--debug" + ], + 'run pg_rewind'); + +# Now move back postgresql.conf with old settings +move( + "$tmp_folder/node_2-postgresql.conf.tmp", + "$node_2_pgdata/postgresql.conf"); + +$node_2->start; + +# Check contents of the test tables after rewind. The rows inserted in node 3 +# before rewind should've been overwritten with the data from node 1. +my $result; +$result = $node_2->safe_psql('postgres', 'SELECT * FROM public.foo'); +is( $result, qq(keep this +and this +and this too), 'table foo after rewind'); + +$result = $node_2->safe_psql('postgres', 'SELECT * FROM public.bar'); +is($result, qq(in both), 'table bar after rewind'); diff --git a/src/bin/pg_rewind/timeline.c b/src/bin/pg_rewind/timeline.c index 1ea660718938..6756c5ddbf79 100644 --- a/src/bin/pg_rewind/timeline.c +++ b/src/bin/pg_rewind/timeline.c @@ -3,7 +3,7 @@ * timeline.c * timeline-related functions. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/bin/pg_test_fsync/.gitignore b/src/bin/pg_test_fsync/.gitignore index f3b593249859..5eb5085f4524 100644 --- a/src/bin/pg_test_fsync/.gitignore +++ b/src/bin/pg_test_fsync/.gitignore @@ -1 +1,3 @@ /pg_test_fsync + +/tmp_check/ diff --git a/src/bin/pg_test_fsync/Makefile b/src/bin/pg_test_fsync/Makefile index 7632c94eb7f6..631d0f38a8e0 100644 --- a/src/bin/pg_test_fsync/Makefile +++ b/src/bin/pg_test_fsync/Makefile @@ -22,8 +22,15 @@ install: all installdirs installdirs: $(MKDIR_P) '$(DESTDIR)$(bindir)' +check: + $(prove_check) + +installcheck: + $(prove_installcheck) + uninstall: rm -f '$(DESTDIR)$(bindir)/pg_test_fsync$(X)' clean distclean maintainer-clean: rm -f pg_test_fsync$(X) $(OBJS) + rm -rf tmp_check diff --git a/src/bin/pg_test_fsync/nls.mk b/src/bin/pg_test_fsync/nls.mk index 15b35ddc3e06..3449f1b7affe 100644 --- a/src/bin/pg_test_fsync/nls.mk +++ b/src/bin/pg_test_fsync/nls.mk @@ -1,5 +1,5 @@ # src/bin/pg_test_fsync/nls.mk CATALOG_NAME = pg_test_fsync -AVAIL_LANGUAGES = cs de es fr ja ko pl ru sv tr uk vi zh_CN +AVAIL_LANGUAGES = cs de el es fr ja ko pl ru sv tr uk vi zh_CN GETTEXT_FILES = pg_test_fsync.c GETTEXT_TRIGGERS = die diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c index 6e4729312331..78dab5096c6e 100644 --- a/src/bin/pg_test_fsync/pg_test_fsync.c +++ b/src/bin/pg_test_fsync/pg_test_fsync.c @@ -5,6 +5,7 @@ #include "postgres_fe.h" +#include #include #include #include @@ -62,7 +63,7 @@ do { \ static const char *progname; -static int secs_per_test = 5; +static unsigned int secs_per_test = 5; static int needs_unlink = 0; static char full_buf[DEFAULT_XLOG_SEG_SIZE], *buf, @@ -148,6 +149,8 @@ handle_args(int argc, char *argv[]) int option; /* Command line option */ int optindex = 0; /* used by getopt_long */ + unsigned long optval; /* used for option parsing */ + char *endptr; if (argc > 1) { @@ -173,7 +176,24 @@ handle_args(int argc, char *argv[]) break; case 's': - secs_per_test = atoi(optarg); + errno = 0; + optval = strtoul(optarg, &endptr, 10); + + if (endptr == optarg || *endptr != '\0' || + errno != 0 || optval != (unsigned int) optval) + { + pg_log_error("invalid argument for option %s", "--secs-per-test"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + + secs_per_test = (unsigned int) optval; + if (secs_per_test == 0) + { + pg_log_error("%s must be in range %u..%u", + "--secs-per-test", 1, UINT_MAX); + exit(1); + } break; default: @@ -193,8 +213,8 @@ handle_args(int argc, char *argv[]) exit(1); } - printf(ngettext("%d second per test\n", - "%d seconds per test\n", + printf(ngettext("%u second per test\n", + "%u seconds per test\n", secs_per_test), secs_per_test); #if PG_O_DIRECT != 0 @@ -270,10 +290,11 @@ test_sync(int writes_per_op) for (ops = 0; alarm_triggered == false; ops++) { for (writes = 0; writes < writes_per_op; writes++) - if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (pg_pwrite(tmpfile, + buf, + XLOG_BLCKSZ, + writes * XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); - if (lseek(tmpfile, 0, SEEK_SET) == -1) - die("seek failed"); } STOP_TIMER; close(tmpfile); @@ -295,11 +316,12 @@ test_sync(int writes_per_op) for (ops = 0; alarm_triggered == false; ops++) { for (writes = 0; writes < writes_per_op; writes++) - if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (pg_pwrite(tmpfile, + buf, + XLOG_BLCKSZ, + writes * XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); fdatasync(tmpfile); - if (lseek(tmpfile, 0, SEEK_SET) == -1) - die("seek failed"); } STOP_TIMER; close(tmpfile); @@ -319,12 +341,13 @@ test_sync(int writes_per_op) for (ops = 0; alarm_triggered == false; ops++) { for (writes = 0; writes < writes_per_op; writes++) - if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (pg_pwrite(tmpfile, + buf, + XLOG_BLCKSZ, + writes * XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); if (fsync(tmpfile) != 0) die("fsync failed"); - if (lseek(tmpfile, 0, SEEK_SET) == -1) - die("seek failed"); } STOP_TIMER; close(tmpfile); @@ -342,12 +365,13 @@ test_sync(int writes_per_op) for (ops = 0; alarm_triggered == false; ops++) { for (writes = 0; writes < writes_per_op; writes++) - if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (pg_pwrite(tmpfile, + buf, + XLOG_BLCKSZ, + writes * XLOG_BLCKSZ) != XLOG_BLCKSZ) die("write failed"); if (pg_fsync_writethrough(tmpfile) != 0) die("fsync failed"); - if (lseek(tmpfile, 0, SEEK_SET) == -1) - die("seek failed"); } STOP_TIMER; close(tmpfile); @@ -373,7 +397,10 @@ test_sync(int writes_per_op) for (ops = 0; alarm_triggered == false; ops++) { for (writes = 0; writes < writes_per_op; writes++) - if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (pg_pwrite(tmpfile, + buf, + XLOG_BLCKSZ, + writes * XLOG_BLCKSZ) != XLOG_BLCKSZ) /* * This can generate write failures if the filesystem has @@ -382,8 +409,6 @@ test_sync(int writes_per_op) * size, e.g. XFS. */ die("write failed"); - if (lseek(tmpfile, 0, SEEK_SET) == -1) - die("seek failed"); } STOP_TIMER; close(tmpfile); @@ -437,11 +462,12 @@ test_open_sync(const char *msg, int writes_size) for (ops = 0; alarm_triggered == false; ops++) { for (writes = 0; writes < 16 / writes_size; writes++) - if (write(tmpfile, buf, writes_size * 1024) != + if (pg_pwrite(tmpfile, + buf, + writes_size * 1024, + writes * writes_size * 1024) != writes_size * 1024) die("write failed"); - if (lseek(tmpfile, 0, SEEK_SET) == -1) - die("seek failed"); } STOP_TIMER; close(tmpfile); @@ -533,16 +559,16 @@ test_non_sync(void) printf(LABEL_FORMAT, "write"); fflush(stdout); + if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1) + die("could not open output file"); START_TIMER; for (ops = 0; alarm_triggered == false; ops++) { - if ((tmpfile = open(filename, O_RDWR | PG_BINARY, 0)) == -1) - die("could not open output file"); - if (write(tmpfile, buf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (pg_pwrite(tmpfile, buf, XLOG_BLCKSZ, 0) != XLOG_BLCKSZ) die("write failed"); - close(tmpfile); } STOP_TIMER; + close(tmpfile); } static void diff --git a/src/bin/pg_test_fsync/po/de.po b/src/bin/pg_test_fsync/po/de.po new file mode 100644 index 000000000000..290551e16edb --- /dev/null +++ b/src/bin/pg_test_fsync/po/de.po @@ -0,0 +1,174 @@ +# German message translation file for pg_test_fsync +# Copyright (C) 2017-2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-13 21:19+0000\n" +"PO-Revision-Date: 2021-04-14 00:04+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:31 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr " %13.3f Op./s %6.0f µs/Op.\n" + +#: pg_test_fsync.c:159 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Aufruf: %s [-f DATEINAME] [-s SEK-PRO-TEST]\n" + +#: pg_test_fsync.c:186 pg_test_fsync.c:200 pg_test_fsync.c:211 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_test_fsync.c:216 +#, c-format +msgid "%u second per test\n" +msgid_plural "%u seconds per test\n" +msgstr[0] "%u Sekunde pro Test\n" +msgstr[1] "%u Sekunden pro Test\n" + +#: pg_test_fsync.c:221 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "O_DIRECT wird auf dieser Plattform für open_datasync und open_sync unterstützt.\n" + +#: pg_test_fsync.c:223 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "Direct-I/O wird auf dieser Plattform nicht unterstützt.\n" + +#: pg_test_fsync.c:248 pg_test_fsync.c:314 pg_test_fsync.c:339 +#: pg_test_fsync.c:363 pg_test_fsync.c:506 pg_test_fsync.c:518 +#: pg_test_fsync.c:534 pg_test_fsync.c:540 pg_test_fsync.c:562 +msgid "could not open output file" +msgstr "konnte Ausgabedatei nicht öffnen" + +#: pg_test_fsync.c:252 pg_test_fsync.c:297 pg_test_fsync.c:323 +#: pg_test_fsync.c:348 pg_test_fsync.c:372 pg_test_fsync.c:410 +#: pg_test_fsync.c:469 pg_test_fsync.c:508 pg_test_fsync.c:536 +#: pg_test_fsync.c:567 +msgid "write failed" +msgstr "Schreiben fehlgeschlagen" + +#: pg_test_fsync.c:256 pg_test_fsync.c:350 pg_test_fsync.c:374 +#: pg_test_fsync.c:510 pg_test_fsync.c:542 +msgid "fsync failed" +msgstr "fsync fehlgeschlagen" + +#: pg_test_fsync.c:270 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Vergleich von Datei-Sync-Methoden bei einem Schreibvorgang aus %dkB:\n" + +#: pg_test_fsync.c:272 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Vergleich von Datei-Sync-Methoden bei zwei Schreibvorgängen aus je %dkB:\n" + +#: pg_test_fsync.c:273 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(in Rangordnung von wal_sync_method, außer dass fdatasync auf Linux Standard ist)\n" + +#: pg_test_fsync.c:284 pg_test_fsync.c:391 pg_test_fsync.c:457 +msgid "n/a*" +msgstr "entf.*" + +#: pg_test_fsync.c:303 pg_test_fsync.c:329 pg_test_fsync.c:379 +#: pg_test_fsync.c:416 pg_test_fsync.c:475 +msgid "n/a" +msgstr "entf." + +#: pg_test_fsync.c:421 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Dieses Dateisystem und die Mount-Optionen unterstützen kein Direct-I/O,\n" +" z.B. ext4 im Journaled-Modus.\n" + +#: pg_test_fsync.c:429 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"Vergleich von open_sync mit verschiedenen Schreibgrößen:\n" + +#: pg_test_fsync.c:430 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Damit werden die Kosten für das Schreiben von 16kB in verschieden Größen mit\n" +"open_sync verglichen.)\n" + +#: pg_test_fsync.c:433 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync schreiben" + +#: pg_test_fsync.c:434 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync schreiben" + +#: pg_test_fsync.c:435 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync schreiben" + +#: pg_test_fsync.c:436 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync schreiben" + +#: pg_test_fsync.c:437 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync schreiben" + +#: pg_test_fsync.c:491 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Probe ob fsync auf einem anderen Dateideskriptor funktioniert:\n" + +#: pg_test_fsync.c:492 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Wenn die Zeiten ähnlich sind, dann kann fsync() auf einem anderen Deskriptor\n" +"geschriebene Daten syncen.)\n" + +#: pg_test_fsync.c:557 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Nicht gesynctes Schreiben von %dkB:\n" diff --git a/src/bin/pg_test_fsync/po/el.po b/src/bin/pg_test_fsync/po/el.po new file mode 100644 index 000000000000..8382e61b9079 --- /dev/null +++ b/src/bin/pg_test_fsync/po/el.po @@ -0,0 +1,176 @@ +# Greek message translation file for pg_test_fsync +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_fsync (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:49+0000\n" +"PO-Revision-Date: 2021-05-05 10:54+0200\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.4.3\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:31 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/sec %6.0f usecs/op\n" + +#: pg_test_fsync.c:159 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Χρήση: %s [-f FILENAME] [-s SECS-PER-TEST]\n" + +#: pg_test_fsync.c:186 pg_test_fsync.c:200 pg_test_fsync.c:211 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_test_fsync.c:216 +#, c-format +msgid "%u second per test\n" +msgid_plural "%u seconds per test\n" +msgstr[0] "%u δευτερόλεπτο ανά τεστ\n" +msgstr[1] "%u δευτερόλεπτα ανά τεστ\n" + +#: pg_test_fsync.c:221 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "O_DIRECT υποστηρίζεται σε αυτήν την πλατφόρμα για open_datasync και open_sync.\n" + +#: pg_test_fsync.c:223 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "Άμεσο I/O δεν υποστηρίζεται σε αυτήν την πλατφόρμα.\n" + +#: pg_test_fsync.c:248 pg_test_fsync.c:314 pg_test_fsync.c:339 +#: pg_test_fsync.c:363 pg_test_fsync.c:507 pg_test_fsync.c:519 +#: pg_test_fsync.c:535 pg_test_fsync.c:541 pg_test_fsync.c:563 +msgid "could not open output file" +msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου εξόδου" + +#: pg_test_fsync.c:252 pg_test_fsync.c:297 pg_test_fsync.c:323 +#: pg_test_fsync.c:348 pg_test_fsync.c:372 pg_test_fsync.c:411 +#: pg_test_fsync.c:470 pg_test_fsync.c:509 pg_test_fsync.c:537 +#: pg_test_fsync.c:568 +msgid "write failed" +msgstr "απέτυχε η εγγραφή" + +#: pg_test_fsync.c:256 pg_test_fsync.c:350 pg_test_fsync.c:374 +#: pg_test_fsync.c:511 pg_test_fsync.c:543 +msgid "fsync failed" +msgstr "fsync απέτυχε" + +#: pg_test_fsync.c:270 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Συγκρίνετε τις μεθόδους συγχρονισμού αρχείων χρησιμοποιώντας μία εγγραφή %dkB:\n" + +#: pg_test_fsync.c:272 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Συγκρίνετε τις μεθόδους συγχρονισμού αρχείων χρησιμοποιώντας δύο εγγραφές %dkB:\n" + +#: pg_test_fsync.c:273 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(με wal_sync_method σειρά προτίμησης, εκτός από fdatasync είναι η προεπιλογή σε Linux)\n" + +#: pg_test_fsync.c:284 pg_test_fsync.c:391 pg_test_fsync.c:458 +msgid "n/a*" +msgstr "n/a*" + +#: pg_test_fsync.c:303 pg_test_fsync.c:329 pg_test_fsync.c:379 +#: pg_test_fsync.c:417 pg_test_fsync.c:476 +msgid "n/a" +msgstr "n/a" + +#: pg_test_fsync.c:422 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Αυτό το σύστημα αρχείων και οι επιλογές προσάρτησής του δεν υποστηρίζουν\n" +" άμεσο I/O, π.χ. ext4 σε λειτουργία journal.\n" + +#: pg_test_fsync.c:430 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"Συγκρίνετε open_sync με διαφορετικά μεγέθη εγγραφής:\n" + +#: pg_test_fsync.c:431 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Αυτό έχει σχεδιαστεί για να συγκρίνει το κόστος της γραφής 16kB σε διαφορετικά\n" +"μεγέθη open_sync.)\n" + +#: pg_test_fsync.c:434 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync εγγραφή" + +#: pg_test_fsync.c:435 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync εγγραφές" + +#: pg_test_fsync.c:436 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync εγγραφές" + +#: pg_test_fsync.c:437 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync εγγραφές" + +#: pg_test_fsync.c:438 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync εγγραφές" + +#: pg_test_fsync.c:492 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Ελέγξτε εάν τηρείται το fsync σε μη-εγγράψιμο περιγραφέα αρχείων:\n" + +#: pg_test_fsync.c:493 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Εάν οι χρόνοι είναι παρόμοιοι, το fsync() μπορεί να συγχρονίσει δεδομένα εγγεγραμμένα\n" +"σε διαφορετικό περιγραφέα.)\n" + +#: pg_test_fsync.c:558 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Μη-συγχρονισμένες %dkB εγγραφές:\n" diff --git a/src/bin/pg_test_fsync/po/es.po b/src/bin/pg_test_fsync/po/es.po new file mode 100644 index 000000000000..544cc892f720 --- /dev/null +++ b/src/bin/pg_test_fsync/po/es.po @@ -0,0 +1,181 @@ +# Spanish message translation file for pg_test_fsync +# +# Copyright (c) 2017-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Carlos Chapi , 2017, 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:49+0000\n" +"PO-Revision-Date: 2021-05-21 23:25-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.4.3\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:31 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/seg %6.0f usegs/op\n" + +#: pg_test_fsync.c:159 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Empleo: %s [-f ARCHIVO] [-s SEG-POR-PRUEBA]\n" + +#: pg_test_fsync.c:186 pg_test_fsync.c:200 pg_test_fsync.c:211 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_test_fsync.c:216 +#, c-format +msgid "%u second per test\n" +msgid_plural "%u seconds per test\n" +msgstr[0] "%u segundo por prueba\n" +msgstr[1] "%u segundos por prueba\n" + +#: pg_test_fsync.c:221 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "O_DIRECT tiene soporte en esta plataforma para open_datasync y open_sync.\n" + +#: pg_test_fsync.c:223 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "Direct I/O no está soportado en esta plataforma.\n" + +#: pg_test_fsync.c:248 pg_test_fsync.c:314 pg_test_fsync.c:339 +#: pg_test_fsync.c:363 pg_test_fsync.c:507 pg_test_fsync.c:519 +#: pg_test_fsync.c:535 pg_test_fsync.c:541 pg_test_fsync.c:563 +msgid "could not open output file" +msgstr "no se pudo abrir el archivo de salida" + +#: pg_test_fsync.c:252 pg_test_fsync.c:297 pg_test_fsync.c:323 +#: pg_test_fsync.c:348 pg_test_fsync.c:372 pg_test_fsync.c:411 +#: pg_test_fsync.c:470 pg_test_fsync.c:509 pg_test_fsync.c:537 +#: pg_test_fsync.c:568 +msgid "write failed" +msgstr "escritura falló" + +#: pg_test_fsync.c:256 pg_test_fsync.c:350 pg_test_fsync.c:374 +#: pg_test_fsync.c:511 pg_test_fsync.c:543 +msgid "fsync failed" +msgstr "fsync falló" + +#: pg_test_fsync.c:270 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Comparar métodos de sincronización de archivos usando una escritura de %dkB:\n" + +#: pg_test_fsync.c:272 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Comparar métodos de sincronización de archivos usando dos escrituras de %dkB:\n" + +#: pg_test_fsync.c:273 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(en orden de preferencia de wal_sync_method, excepto en Linux donde fdatasync es el predeterminado)\n" + +#: pg_test_fsync.c:284 pg_test_fsync.c:391 pg_test_fsync.c:458 +msgid "n/a*" +msgstr "n/a*" + +#: pg_test_fsync.c:303 pg_test_fsync.c:329 pg_test_fsync.c:379 +#: pg_test_fsync.c:417 pg_test_fsync.c:476 +msgid "n/a" +msgstr "n/a" + +#: pg_test_fsync.c:422 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Este sistema de archivos con sus opciones de montaje no soportan\n" +" Direct I/O, e.g. ext4 en modo journal.\n" + +#: pg_test_fsync.c:430 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"Comparar open_sync con diferentes tamaños de escritura:\n" + +#: pg_test_fsync.c:431 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Esto está diseñado para comparar el costo de escribir 16kB en diferentes\n" +"tamaños de escrituras open_sync.)\n" + +#: pg_test_fsync.c:434 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB escritura open_sync" + +#: pg_test_fsync.c:435 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB escrituras open_sync" + +#: pg_test_fsync.c:436 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB escrituras open_sync" + +#: pg_test_fsync.c:437 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB escrituras open_sync" + +#: pg_test_fsync.c:438 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB escrituras open_sync" + +#: pg_test_fsync.c:492 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Probar si se respeta fsync en un descriptor de archivo que no es de escritura:\n" + +#: pg_test_fsync.c:493 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Si los tiempos son similares, fsync() puede sincronizar datos escritos\n" +"en un descriptor diferente.)\n" + +#: pg_test_fsync.c:558 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Escrituras de %dkB no sincronizadas:\n" + +#~ msgid "seek failed" +#~ msgstr "búsqueda falló" diff --git a/src/bin/pg_test_fsync/po/fr.po b/src/bin/pg_test_fsync/po/fr.po new file mode 100644 index 000000000000..cc9800aa24ad --- /dev/null +++ b/src/bin/pg_test_fsync/po/fr.po @@ -0,0 +1,188 @@ +# LANGUAGE message translation file for pg_test_fsync +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-15 01:49+0000\n" +"PO-Revision-Date: 2021-04-15 08:43+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.2\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:31 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/sec %6.0f usecs/op\n" + +#: pg_test_fsync.c:159 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Usage: %s [-f NOMFICHIER] [-s SECS-PAR-TEST]\n" + +#: pg_test_fsync.c:186 pg_test_fsync.c:200 pg_test_fsync.c:211 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: pg_test_fsync.c:216 +#, c-format +msgid "%u second per test\n" +msgid_plural "%u seconds per test\n" +msgstr[0] "%u seconde par test\n" +msgstr[1] "%u secondes par test\n" + +#: pg_test_fsync.c:221 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "O_DIRECT supporté sur cette plateforme pour open_datasync et open_sync.\n" + +#: pg_test_fsync.c:223 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "Direct I/O n'est pas supporté sur cette plateforme.\n" + +#: pg_test_fsync.c:248 pg_test_fsync.c:314 pg_test_fsync.c:339 +#: pg_test_fsync.c:363 pg_test_fsync.c:506 pg_test_fsync.c:518 +#: pg_test_fsync.c:534 pg_test_fsync.c:540 pg_test_fsync.c:562 +msgid "could not open output file" +msgstr "n'a pas pu ouvrir le fichier en sortie" + +#: pg_test_fsync.c:252 pg_test_fsync.c:297 pg_test_fsync.c:323 +#: pg_test_fsync.c:348 pg_test_fsync.c:372 pg_test_fsync.c:410 +#: pg_test_fsync.c:469 pg_test_fsync.c:508 pg_test_fsync.c:536 +#: pg_test_fsync.c:567 +msgid "write failed" +msgstr "échec en écriture" + +#: pg_test_fsync.c:256 pg_test_fsync.c:350 pg_test_fsync.c:374 +#: pg_test_fsync.c:510 pg_test_fsync.c:542 +msgid "fsync failed" +msgstr "échec de la synchronisation (fsync)" + +#: pg_test_fsync.c:270 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Comparer les méthodes de synchronisation de fichier en utilisant une écriture de %d Ko :\n" + +#: pg_test_fsync.c:272 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Comparer les méthodes de synchronisation de fichier sur disque en utilisant deux écritures de %d Ko :\n" + +#: pg_test_fsync.c:273 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(dans l'ordre de préférence de wal_sync_method, sauf fdatasync qui est la valeur par défaut sous Linux)\n" + +#: pg_test_fsync.c:284 pg_test_fsync.c:391 pg_test_fsync.c:457 +msgid "n/a*" +msgstr "n/a*" + +#: pg_test_fsync.c:303 pg_test_fsync.c:329 pg_test_fsync.c:379 +#: pg_test_fsync.c:416 pg_test_fsync.c:475 +msgid "n/a" +msgstr "n/a" + +#: pg_test_fsync.c:421 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Ce système de fichiers et ses options de montage ne supportent pas les\n" +" I/O directes, par exemple ext4 en journalisé.\n" + +#: pg_test_fsync.c:429 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"Comparer open_sync avec différentes tailles d'écriture :\n" + +#: pg_test_fsync.c:430 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Ceci est conçu pour comparer le coût d'écriture de 16 Ko dans différentes tailles\n" +"d'écritures open_sync.)\n" + +#: pg_test_fsync.c:433 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16 Ko, écriture avec open_sync" + +#: pg_test_fsync.c:434 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8 Ko, écriture avec open_sync" + +#: pg_test_fsync.c:435 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4 Ko, écriture avec open_sync" + +#: pg_test_fsync.c:436 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2 Ko, écriture avec open_sync" + +#: pg_test_fsync.c:437 +msgid "16 * 1kB open_sync writes" +msgstr " 16 * 1 Ko, écriture avec open_sync" + +#: pg_test_fsync.c:491 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Teste si fsync est honoré sur un descripteur de fichiers sans écriture :\n" + +#: pg_test_fsync.c:492 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Si les temps sont similaires, fsync() peut synchroniser sur disque les données écrites sur\n" +"un descripteur différent.)\n" + +#: pg_test_fsync.c:557 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"%d Ko d'écritures non synchronisées :\n" + +#~ msgid "%s: %s\n" +#~ msgstr "%s : %s\n" + +#~ msgid "seek failed" +#~ msgstr "seek échoué" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" + +#~ msgid "Could not create thread for alarm\n" +#~ msgstr "N'a pas pu créer un thread pour l'alarme\n" diff --git a/src/bin/pg_test_fsync/po/ru.po b/src/bin/pg_test_fsync/po/ru.po new file mode 100644 index 000000000000..a73b146ade17 --- /dev/null +++ b/src/bin/pg_test_fsync/po/ru.po @@ -0,0 +1,198 @@ +# Russian message translation file for pg_test_fsync +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Alexander Lakhin , 2017. +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2017-09-21 14:03+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f оп/с %6.0f мкс/оп\n" + +#: pg_test_fsync.c:156 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Использование: %s [-f ИМЯ_ФАЙЛА ] [-s ТЕСТ_СЕК]\n" + +#: pg_test_fsync.c:180 pg_test_fsync.c:191 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_test_fsync.c:196 +#, c-format +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "на тест отводится %d сек.\n" +msgstr[1] "на тест отводится %d сек.\n" +msgstr[2] "на тест отводится %d сек.\n" + +#: pg_test_fsync.c:201 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "" +"O_DIRECT на этой платформе не поддерживается для open_datasync и open_sync.\n" + +#: pg_test_fsync.c:203 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "Прямой ввод/вывод не поддерживается на этой платформе.\n" + +#: pg_test_fsync.c:228 pg_test_fsync.c:293 pg_test_fsync.c:317 +#: pg_test_fsync.c:340 pg_test_fsync.c:481 pg_test_fsync.c:493 +#: pg_test_fsync.c:509 pg_test_fsync.c:515 pg_test_fsync.c:540 +msgid "could not open output file" +msgstr "не удалось открыть выходной файл" + +#: pg_test_fsync.c:232 pg_test_fsync.c:274 pg_test_fsync.c:299 +#: pg_test_fsync.c:323 pg_test_fsync.c:346 pg_test_fsync.c:384 +#: pg_test_fsync.c:442 pg_test_fsync.c:483 pg_test_fsync.c:511 +#: pg_test_fsync.c:542 +msgid "write failed" +msgstr "ошибка записи" + +#: pg_test_fsync.c:236 pg_test_fsync.c:325 pg_test_fsync.c:348 +#: pg_test_fsync.c:485 pg_test_fsync.c:517 +msgid "fsync failed" +msgstr "ошибка синхронизации с ФС" + +#: pg_test_fsync.c:250 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Сравнение методов синхронизации файлов при однократной записи %d КБ:\n" + +#: pg_test_fsync.c:252 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Сравнение методов синхронизации файлов при двухкратной записи %d КБ:\n" + +#: pg_test_fsync.c:253 +#, c-format +msgid "" +"(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "" +"(в порядке предпочтения для wal_sync_method, без учёта наибольшего " +"предпочтения fdatasync в Linux)\n" + +#: pg_test_fsync.c:264 pg_test_fsync.c:367 pg_test_fsync.c:433 +msgid "n/a*" +msgstr "н/д*" + +#: pg_test_fsync.c:276 pg_test_fsync.c:302 pg_test_fsync.c:327 +#: pg_test_fsync.c:350 pg_test_fsync.c:386 pg_test_fsync.c:444 +msgid "seek failed" +msgstr "ошибка позиционирования" + +#: pg_test_fsync.c:282 pg_test_fsync.c:307 pg_test_fsync.c:355 +#: pg_test_fsync.c:392 pg_test_fsync.c:450 +msgid "n/a" +msgstr "н/д" + +#: pg_test_fsync.c:397 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Эта файловая система с текущими параметрами монтирования не поддерживает\n" +" прямой ввод/вывод, как например, ext4 в режиме журналирования.\n" + +#: pg_test_fsync.c:405 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"Сравнение open_sync при различных объёмах записываемых данных:\n" + +#: pg_test_fsync.c:406 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Этот тест предназначен для сравнения стоимости записи 16 КБ при разных " +"размерах\n" +"записи с open_sync.)\n" + +# skip-rule: double-space +#: pg_test_fsync.c:409 +msgid " 1 * 16kB open_sync write" +msgstr "запись с open_sync 1 * 16 КБ" + +#: pg_test_fsync.c:410 +msgid " 2 * 8kB open_sync writes" +msgstr "запись с open_sync 2 * 8 КБ" + +#: pg_test_fsync.c:411 +msgid " 4 * 4kB open_sync writes" +msgstr "запись с open_sync 4 * 4 КБ" + +#: pg_test_fsync.c:412 +msgid " 8 * 2kB open_sync writes" +msgstr "запись с open_sync 8 * 2 КБ" + +#: pg_test_fsync.c:413 +msgid "16 * 1kB open_sync writes" +msgstr "запись с open_sync 16 * 1 КБ" + +#: pg_test_fsync.c:466 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Проверка, производится ли fsync с указателем файла, открытого не для " +"записи:\n" + +#: pg_test_fsync.c:467 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Если длительность примерно одинаковая, fsync() может синхронизировать " +"данные,\n" +"записанные через другой дескриптор.)\n" + +#: pg_test_fsync.c:532 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Несинхронизированная запись %d КБ:\n" + +#~ msgid "Could not create thread for alarm\n" +#~ msgstr "Не удалось создать поток для обработки сигналов\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: слишком много аргументов командной строки (первый: \"%s\")\n" + +#~ msgid "%s: %s\n" +#~ msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/uk.po b/src/bin/pg_test_fsync/po/uk.po index 35b02906e7f7..e12dba9aaea2 100644 --- a/src/bin/pg_test_fsync/po/uk.po +++ b/src/bin/pg_test_fsync/po/uk.po @@ -1,20 +1,21 @@ msgid "" msgstr "" "Project-Id-Version: postgresql\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2018-12-04 20:35+0100\n" -"PO-Revision-Date: 2019-08-10 13:19\n" -"Last-Translator: pasha_golub\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:17+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" -"X-Generator: crowdin.com\n" "X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" "X-Crowdin-Language: uk\n" -"X-Crowdin-File: /REL_11_STABLE/src/bin/pg_test_fsync/po/pg_test_fsync.pot\n" +"X-Crowdin-File: /DEV_13/pg_test_fsync.pot\n" +"X-Crowdin-File-ID: 506\n" #. translator: maintain alignment with NA_FORMAT #: pg_test_fsync.c:30 @@ -22,27 +23,17 @@ msgstr "" msgid "%13.3f ops/sec %6.0f usecs/op\n" msgstr "%13.3f оп/с %6.0f мкс/оп\n" -#: pg_test_fsync.c:49 -#, c-format -msgid "Could not create thread for alarm\n" -msgstr "Не вдалося створити потік для обробки сигналів\n" - -#: pg_test_fsync.c:154 +#: pg_test_fsync.c:156 #, c-format msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" msgstr "Використання: %s [-f FILENAME] [-s SECS-PER-TEST]\n" -#: pg_test_fsync.c:178 pg_test_fsync.c:190 +#: pg_test_fsync.c:180 pg_test_fsync.c:191 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" -#: pg_test_fsync.c:188 -#, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: забагато аргументів у командному рядку (перший \"%s\")\n" - -#: pg_test_fsync.c:195 +#: pg_test_fsync.c:196 #, c-format msgid "%d second per test\n" msgid_plural "%d seconds per test\n" @@ -51,130 +42,125 @@ msgstr[1] "%d секунди для тесту\n" msgstr[2] "%d секунд для тесту\n" msgstr[3] "%d секунда для тесту\n" -#: pg_test_fsync.c:200 +#: pg_test_fsync.c:201 #, c-format msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" msgstr "O_DIRECT на цій платформі підтримується для open_datasync і open_sync.\n" -#: pg_test_fsync.c:202 +#: pg_test_fsync.c:203 #, c-format msgid "Direct I/O is not supported on this platform.\n" msgstr "Пряме введення/виведення не підтримується на цій платформі.\n" -#: pg_test_fsync.c:227 pg_test_fsync.c:292 pg_test_fsync.c:316 -#: pg_test_fsync.c:339 pg_test_fsync.c:480 pg_test_fsync.c:492 -#: pg_test_fsync.c:508 pg_test_fsync.c:514 pg_test_fsync.c:539 +#: pg_test_fsync.c:228 pg_test_fsync.c:293 pg_test_fsync.c:317 +#: pg_test_fsync.c:340 pg_test_fsync.c:481 pg_test_fsync.c:493 +#: pg_test_fsync.c:509 pg_test_fsync.c:515 pg_test_fsync.c:540 msgid "could not open output file" msgstr "неможливо відкрити файл виводу" -#: pg_test_fsync.c:231 pg_test_fsync.c:273 pg_test_fsync.c:298 -#: pg_test_fsync.c:322 pg_test_fsync.c:345 pg_test_fsync.c:383 -#: pg_test_fsync.c:441 pg_test_fsync.c:482 pg_test_fsync.c:510 -#: pg_test_fsync.c:541 +#: pg_test_fsync.c:232 pg_test_fsync.c:274 pg_test_fsync.c:299 +#: pg_test_fsync.c:323 pg_test_fsync.c:346 pg_test_fsync.c:384 +#: pg_test_fsync.c:442 pg_test_fsync.c:483 pg_test_fsync.c:511 +#: pg_test_fsync.c:542 msgid "write failed" msgstr "записування не вдалося" -#: pg_test_fsync.c:235 pg_test_fsync.c:324 pg_test_fsync.c:347 -#: pg_test_fsync.c:484 pg_test_fsync.c:516 +#: pg_test_fsync.c:236 pg_test_fsync.c:325 pg_test_fsync.c:348 +#: pg_test_fsync.c:485 pg_test_fsync.c:517 msgid "fsync failed" msgstr "помилка fsync" -#: pg_test_fsync.c:249 +#: pg_test_fsync.c:250 #, c-format msgid "\n" "Compare file sync methods using one %dkB write:\n" msgstr "\n" "Порівнювання методів синхронізації файлу, використовуючи один запис %dkB:\n" -#: pg_test_fsync.c:251 +#: pg_test_fsync.c:252 #, c-format msgid "\n" "Compare file sync methods using two %dkB writes:\n" msgstr "\n" "Порівнювання методів синхронізації файлу, використовуючи два записи %dkB: \n" -#: pg_test_fsync.c:252 +#: pg_test_fsync.c:253 #, c-format msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" msgstr "(в порядку переваги для wal_sync_method, окрім переваги fdatasync в Linux)\n" -#: pg_test_fsync.c:263 pg_test_fsync.c:366 pg_test_fsync.c:432 +#: pg_test_fsync.c:264 pg_test_fsync.c:367 pg_test_fsync.c:433 msgid "n/a*" msgstr "н/д*" -#: pg_test_fsync.c:275 pg_test_fsync.c:301 pg_test_fsync.c:326 -#: pg_test_fsync.c:349 pg_test_fsync.c:385 pg_test_fsync.c:443 +#: pg_test_fsync.c:276 pg_test_fsync.c:302 pg_test_fsync.c:327 +#: pg_test_fsync.c:350 pg_test_fsync.c:386 pg_test_fsync.c:444 msgid "seek failed" msgstr "помилка пошуку" -#: pg_test_fsync.c:281 pg_test_fsync.c:306 pg_test_fsync.c:354 -#: pg_test_fsync.c:391 pg_test_fsync.c:449 +#: pg_test_fsync.c:282 pg_test_fsync.c:307 pg_test_fsync.c:355 +#: pg_test_fsync.c:392 pg_test_fsync.c:450 msgid "n/a" msgstr "н/д" -#: pg_test_fsync.c:396 +#: pg_test_fsync.c:397 #, c-format msgid "* This file system and its mount options do not support direct\n" " I/O, e.g. ext4 in journaled mode.\n" msgstr "* Ця файлова система з поточними параметрами монтування не підтримує\n" " пряме введення/виведення, наприклад, ext4 в режимі журналювання.\n" -#: pg_test_fsync.c:404 +#: pg_test_fsync.c:405 #, c-format msgid "\n" "Compare open_sync with different write sizes:\n" msgstr "\n" "Порівняння open_sync з різними розмірами записування:\n" -#: pg_test_fsync.c:405 +#: pg_test_fsync.c:406 #, c-format msgid "(This is designed to compare the cost of writing 16kB in different write\n" "open_sync sizes.)\n" msgstr "(Це створено для порівняння вартості запису 16 КБ з різними розмірами\n" "записування open_sync.)\n" -#: pg_test_fsync.c:408 +#: pg_test_fsync.c:409 msgid " 1 * 16kB open_sync write" msgstr " запис з open_sync 1 * 16 КБ" -#: pg_test_fsync.c:409 +#: pg_test_fsync.c:410 msgid " 2 * 8kB open_sync writes" msgstr " запис з open_sync 2 * 8 КБ" -#: pg_test_fsync.c:410 +#: pg_test_fsync.c:411 msgid " 4 * 4kB open_sync writes" msgstr " запис з open_sync 4 * 4 КБ" -#: pg_test_fsync.c:411 +#: pg_test_fsync.c:412 msgid " 8 * 2kB open_sync writes" msgstr " запис з open_sync 8 * 2 КБ" -#: pg_test_fsync.c:412 +#: pg_test_fsync.c:413 msgid "16 * 1kB open_sync writes" msgstr "запис з open_sync 16 * 1 КБ" -#: pg_test_fsync.c:465 +#: pg_test_fsync.c:466 #, c-format msgid "\n" "Test if fsync on non-write file descriptor is honored:\n" msgstr "\n" "Перевірка, чи здійснюється fsync з дескриптором файлу, відкритого не для запису:\n" -#: pg_test_fsync.c:466 +#: pg_test_fsync.c:467 #, c-format msgid "(If the times are similar, fsync() can sync data written on a different\n" "descriptor.)\n" msgstr "(Якщо час однаковий, fsync() може синхронізувати дані, записані іншим дескриптором.)\n" -#: pg_test_fsync.c:531 +#: pg_test_fsync.c:532 #, c-format msgid "\n" "Non-sync'ed %dkB writes:\n" msgstr "\n" "Несинхронізований запис %d КБ:\n" -#: pg_test_fsync.c:608 -#, c-format -msgid "%s: %s\n" -msgstr "%s: %s\n" - diff --git a/src/bin/pg_test_fsync/t/001_basic.pl b/src/bin/pg_test_fsync/t/001_basic.pl new file mode 100644 index 000000000000..c0d0effd92de --- /dev/null +++ b/src/bin/pg_test_fsync/t/001_basic.pl @@ -0,0 +1,28 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use Config; +use TestLib; +use Test::More tests => 12; + +######################################### +# Basic checks + +program_help_ok('pg_test_fsync'); +program_version_ok('pg_test_fsync'); +program_options_handling_ok('pg_test_fsync'); + +######################################### +# Test invalid option combinations + +command_fails_like( + [ 'pg_test_fsync', '--secs-per-test', 'a' ], + qr/\Qpg_test_fsync: error: invalid argument for option --secs-per-test\E/, + 'pg_test_fsync: invalid argument for option --secs-per-test'); +command_fails_like( + [ 'pg_test_fsync', '--secs-per-test', '0' ], + qr/\Qpg_test_fsync: error: --secs-per-test must be in range 1..4294967295\E/, + 'pg_test_fsync: --secs-per-test must be in range'); diff --git a/src/bin/pg_test_timing/.gitignore b/src/bin/pg_test_timing/.gitignore index f6c664c76576..e5aac2ab120f 100644 --- a/src/bin/pg_test_timing/.gitignore +++ b/src/bin/pg_test_timing/.gitignore @@ -1 +1,3 @@ /pg_test_timing + +/tmp_check/ diff --git a/src/bin/pg_test_timing/Makefile b/src/bin/pg_test_timing/Makefile index 334d6ff5c00d..84d84c38aa86 100644 --- a/src/bin/pg_test_timing/Makefile +++ b/src/bin/pg_test_timing/Makefile @@ -22,8 +22,15 @@ install: all installdirs installdirs: $(MKDIR_P) '$(DESTDIR)$(bindir)' +check: + $(prove_check) + +installcheck: + $(prove_installcheck) + uninstall: rm -f '$(DESTDIR)$(bindir)/pg_test_timing$(X)' clean distclean maintainer-clean: rm -f pg_test_timing$(X) $(OBJS) + rm -rf tmp_check diff --git a/src/bin/pg_test_timing/nls.mk b/src/bin/pg_test_timing/nls.mk index 91dedb15410e..126f45e2cb42 100644 --- a/src/bin/pg_test_timing/nls.mk +++ b/src/bin/pg_test_timing/nls.mk @@ -1,4 +1,4 @@ # src/bin/pg_test_timing/nls.mk CATALOG_NAME = pg_test_timing -AVAIL_LANGUAGES = cs de es fr ja ko pl ru sv tr uk vi zh_CN +AVAIL_LANGUAGES = cs de el es fr ja ko pl ru sv tr uk vi zh_CN GETTEXT_FILES = pg_test_timing.c diff --git a/src/bin/pg_test_timing/pg_test_timing.c b/src/bin/pg_test_timing/pg_test_timing.c index e14802372bd6..c29d6f876294 100644 --- a/src/bin/pg_test_timing/pg_test_timing.c +++ b/src/bin/pg_test_timing/pg_test_timing.c @@ -6,15 +6,17 @@ #include "postgres_fe.h" +#include + #include "getopt_long.h" #include "portability/instr_time.h" static const char *progname; -static int32 test_duration = 3; +static unsigned int test_duration = 3; static void handle_args(int argc, char *argv[]); -static uint64 test_timing(int32); +static uint64 test_timing(unsigned int duration); static void output(uint64 loop_count); /* record duration in powers of 2 microseconds */ @@ -47,6 +49,8 @@ handle_args(int argc, char *argv[]) int option; /* Command line option */ int optindex = 0; /* used by getopt_long */ + unsigned long optval; /* used for option parsing */ + char *endptr; if (argc > 1) { @@ -68,7 +72,25 @@ handle_args(int argc, char *argv[]) switch (option) { case 'd': - test_duration = atoi(optarg); + errno = 0; + optval = strtoul(optarg, &endptr, 10); + + if (endptr == optarg || *endptr != '\0' || + errno != 0 || optval != (unsigned int) optval) + { + fprintf(stderr, _("%s: invalid argument for option %s\n"), + progname, "--duration"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + + test_duration = (unsigned int) optval; + if (test_duration == 0) + { + fprintf(stderr, _("%s: %s must be in range %u..%u\n"), + progname, "--duration", 1, UINT_MAX); + exit(1); + } break; default: @@ -89,26 +111,15 @@ handle_args(int argc, char *argv[]) exit(1); } - if (test_duration > 0) - { - printf(ngettext("Testing timing overhead for %d second.\n", - "Testing timing overhead for %d seconds.\n", - test_duration), - test_duration); - } - else - { - fprintf(stderr, - _("%s: duration must be a positive integer (duration is \"%d\")\n"), - progname, test_duration); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), - progname); - exit(1); - } + + printf(ngettext("Testing timing overhead for %u second.\n", + "Testing timing overhead for %u seconds.\n", + test_duration), + test_duration); } static uint64 -test_timing(int32 duration) +test_timing(unsigned int duration) { uint64 total_time; int64 time_elapsed = 0; diff --git a/src/bin/pg_test_timing/po/de.po b/src/bin/pg_test_timing/po/de.po new file mode 100644 index 000000000000..6bcbc73064ca --- /dev/null +++ b/src/bin/pg_test_timing/po/de.po @@ -0,0 +1,84 @@ +# German message translation file for pg_test_timing +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-12 14:17+0000\n" +"PO-Revision-Date: 2021-04-12 16:37+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: pg_test_timing.c:59 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "Aufruf: %s [-d DAUER]\n" + +#: pg_test_timing.c:81 +#, c-format +msgid "%s: invalid argument for option %s\n" +msgstr "%s: ungültiges Argument für Option %s\n" + +#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_test_timing.c:90 +#, c-format +msgid "%s: %s must be in range %u..%u\n" +msgstr "%s: %s muss im Bereich %u..%u sein\n" + +#: pg_test_timing.c:107 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" + +#: pg_test_timing.c:115 +#, c-format +msgid "Testing timing overhead for %u second.\n" +msgid_plural "Testing timing overhead for %u seconds.\n" +msgstr[0] "Testen des Overheads der Zeitmessung für %u Sekunde\n" +msgstr[1] "Testen des Overheads der Zeitmessung für %u Sekunden\n" + +#: pg_test_timing.c:151 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "Rückwärts gehende Uhr festgestellt.\n" + +#: pg_test_timing.c:152 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "Zeitdifferenz: %d ms\n" + +#: pg_test_timing.c:175 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "Zeit pro Durchlauf einschließlich Overhead: %0.2f ns\n" + +#: pg_test_timing.c:186 +msgid "< us" +msgstr "< µs" + +#: pg_test_timing.c:187 +#, no-c-format +msgid "% of total" +msgstr "% von gesamt" + +#: pg_test_timing.c:188 +msgid "count" +msgstr "Anzahl" + +#: pg_test_timing.c:197 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Histogramm der Dauern der Zeitmessungen:\n" diff --git a/src/bin/pg_test_timing/po/el.po b/src/bin/pg_test_timing/po/el.po new file mode 100644 index 000000000000..5375540b1eed --- /dev/null +++ b/src/bin/pg_test_timing/po/el.po @@ -0,0 +1,84 @@ +# Greek message translation file for pg_test_timing +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package. +# Georgios Kokolatos , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:47+0000\n" +"PO-Revision-Date: 2021-04-28 10:43+0200\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.4.2\n" + +#: pg_test_timing.c:59 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "Χρήση: %s [-d DURATION]\n" + +#: pg_test_timing.c:81 +#, c-format +msgid "%s: invalid argument for option %s\n" +msgstr "%s: μη έγκυρη παράμετρος για την επιλογή %s\n" + +#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_test_timing.c:90 +#, c-format +msgid "%s: %s must be in range %u..%u\n" +msgstr "%s: %s πρέπει να βρίσκεται εντός εύρους %u..%u\n" + +#: pg_test_timing.c:107 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (πρώτη είναι η “%s”)\n" + +#: pg_test_timing.c:115 +#, c-format +msgid "Testing timing overhead for %u second.\n" +msgid_plural "Testing timing overhead for %u seconds.\n" +msgstr[0] "Έλεγχος επίφορτου χρονισμού για %u δευτερόλεπτο.\n" +msgstr[1] "Έλεγχος επίφορτου χρονισμού για %u δευτερόλεπτα.\n" + +#: pg_test_timing.c:151 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "Εντοπίστηκε ρολόι που πηγαίνει προς τα πίσω στο χρόνο.\n" + +#: pg_test_timing.c:152 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "Χρονική στρέβλωση: %d ms\n" + +#: pg_test_timing.c:175 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "Χρόνος ανά βρόχο συμπεριλαμβανομένου επίφορτου: %0.2f ns\n" + +#: pg_test_timing.c:186 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:187 +#, no-c-format +msgid "% of total" +msgstr "% of συνολικά" + +#: pg_test_timing.c:188 +msgid "count" +msgstr "count" + +#: pg_test_timing.c:197 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Ιστόγραμμα διαρκειών χρονισμού\n" diff --git a/src/bin/pg_test_timing/po/es.po b/src/bin/pg_test_timing/po/es.po new file mode 100644 index 000000000000..3ca19778d1aa --- /dev/null +++ b/src/bin/pg_test_timing/po/es.po @@ -0,0 +1,89 @@ +# Spanish message translation file for pg_test_timing +# +# Copyright (c) 2017-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Carlos Chapi , 2017-2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:47+0000\n" +"PO-Revision-Date: 2021-05-19 22:07-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 2.4.2\n" + +#: pg_test_timing.c:59 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "Empleo: %s [-d DURACIÓN]\n" + +#: pg_test_timing.c:81 +#, c-format +msgid "%s: invalid argument for option %s\n" +msgstr "%s: argumento no válido para la opción %s\n" + +#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_test_timing.c:90 +#, c-format +msgid "%s: %s must be in range %u..%u\n" +msgstr "%s: %s debe estar en el rango %u..%u\n" + +#: pg_test_timing.c:107 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" + +#: pg_test_timing.c:115 +#, c-format +msgid "Testing timing overhead for %u second.\n" +msgid_plural "Testing timing overhead for %u seconds.\n" +msgstr[0] "Midiendo sobrecosto de lectura de reloj durante %u segundo.\n" +msgstr[1] "Midiendo sobrecosto de lectura de reloj durante %u segundos.\n" + +#: pg_test_timing.c:151 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "Se detectó que el reloj retrocede en el tiempo.\n" + +#: pg_test_timing.c:152 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "Desfase de tiempo: %d ms\n" + +#: pg_test_timing.c:175 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "Tiempo por lectura incluyendo sobrecosto: %0.2f ns\n" + +#: pg_test_timing.c:186 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:187 +#, no-c-format +msgid "% of total" +msgstr "% del total" + +#: pg_test_timing.c:188 +msgid "count" +msgstr "cantidad" + +#: pg_test_timing.c:197 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Histograma de duraciones de lectura de reloj:\n" + +#~ msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +#~ msgstr "%s: la duración debe ser un número entero positivo (la duración es \"%d\")\n" diff --git a/src/bin/pg_test_timing/po/fr.po b/src/bin/pg_test_timing/po/fr.po new file mode 100644 index 000000000000..17d321c60d90 --- /dev/null +++ b/src/bin/pg_test_timing/po/fr.po @@ -0,0 +1,87 @@ +# LANGUAGE message translation file for pg_test_timing +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-22 04:17+0000\n" +"PO-Revision-Date: 2021-04-22 10:10+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n>1;\n" +"X-Generator: Poedit 2.4.2\n" + +#: pg_test_timing.c:59 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "Usage: %s [-d DURÉE]\n" + +#: pg_test_timing.c:81 +#, c-format +msgid "%s: invalid argument for option %s\n" +msgstr "%s : argument invalide pour l'option %s\n" + +#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: pg_test_timing.c:90 +#, c-format +msgid "%s: %s must be in range %u..%u\n" +msgstr "%s : %s doit être compris entre %u et %u\n" + +#: pg_test_timing.c:107 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" + +#: pg_test_timing.c:115 +#, c-format +msgid "Testing timing overhead for %u second.\n" +msgid_plural "Testing timing overhead for %u seconds.\n" +msgstr[0] "Test du coût du chronométrage pour %u seconde.\n" +msgstr[1] "Test du coût du chronométrage pour %u secondes.\n" + +#: pg_test_timing.c:151 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "Détection d'une horloge partant à rebours.\n" + +#: pg_test_timing.c:152 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "Décalage de temps : %d ms\n" + +#: pg_test_timing.c:175 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "Durée par boucle incluant le coût : %0.2f ns\n" + +#: pg_test_timing.c:186 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:187 +#, no-c-format +msgid "% of total" +msgstr "% du total" + +#: pg_test_timing.c:188 +msgid "count" +msgstr "nombre" + +#: pg_test_timing.c:197 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Histogramme des durées de chronométrage\n" + +#~ msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +#~ msgstr "%s : la durée doit être un entier positif (la durée est « %d »)\n" diff --git a/src/bin/pg_test_timing/po/zh_CN.po b/src/bin/pg_test_timing/po/zh_CN.po index 9edb500df90f..9259fcd7d7f4 100644 --- a/src/bin/pg_test_timing/po/zh_CN.po +++ b/src/bin/pg_test_timing/po/zh_CN.po @@ -5,74 +5,76 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_test_timing (PostgreSQL) 12\n" +"Project-Id-Version: pg_test_timing (PostgreSQL) 14\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-05-22 17:56+0800\n" -"PO-Revision-Date: 2019-05-31 18:50+0800\n" -"Last-Translator: Jie Zhang \n" -"Language-Team: Chinese (Simplified) \n" +"POT-Creation-Date: 2021-06-09 21:17+0000\n" +"PO-Revision-Date: 2021-06-10 10:50+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: zh_CN\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: pg_test_timing.c:55 +#: pg_test_timing.c:59 #, c-format msgid "Usage: %s [-d DURATION]\n" msgstr "用法: %s [-d 持续时间]\n" -#: pg_test_timing.c:75 pg_test_timing.c:87 pg_test_timing.c:104 +#: pg_test_timing.c:81 +msgid "%s: invalid argument for option %s\n" +msgstr "%s: 选项%s的参数无效\n" + +#: pg_test_timing.c:83 pg_test_timing.c:97 pg_test_timing.c:109 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "请用 \"%s --help\" 获取更多的信息.\n" -#: pg_test_timing.c:85 +#: pg_test_timing.c:90 +msgid "%s: %s must be in range %u..%u\n" +msgstr "%s: %s必须位于%u..%u的范围内\n" + +#: pg_test_timing.c:107 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 命令行参数太多 (第一个是 \"%s\")\n" -#: pg_test_timing.c:94 -#, c-format -msgid "Testing timing overhead for %d second.\n" -msgid_plural "Testing timing overhead for %d seconds.\n" -msgstr[0] "测试%d秒的计时开销.\n" -msgstr[1] "测试%d秒的计时开销.\n" +#: pg_test_timing.c:115 +msgid "Testing timing overhead for %u second.\n" +msgid_plural "Testing timing overhead for %u seconds.\n" +msgstr[0] "测试%u秒的计时开销.\n" +msgstr[1] "测试%u秒的计时开销.\n" -#: pg_test_timing.c:102 -#, c-format -msgid "%s: duration must be a positive integer (duration is \"%d\")\n" -msgstr "%s: 持续时间必须是正整数(持续时间是 \"%d\")\n" - -#: pg_test_timing.c:140 +#: pg_test_timing.c:151 #, c-format msgid "Detected clock going backwards in time.\n" msgstr "检测到时钟时间倒转.\n" -#: pg_test_timing.c:141 +#: pg_test_timing.c:152 #, c-format msgid "Time warp: %d ms\n" msgstr "时间错位: %d 毫秒\n" -#: pg_test_timing.c:164 +#: pg_test_timing.c:175 #, c-format msgid "Per loop time including overhead: %0.2f ns\n" msgstr "每次循环的平均开销: %0.2f 纳秒\n" -#: pg_test_timing.c:175 +#: pg_test_timing.c:186 msgid "< us" msgstr "< 微秒" -#: pg_test_timing.c:176 +#: pg_test_timing.c:187 #, no-c-format msgid "% of total" msgstr "总计的 %" -#: pg_test_timing.c:177 +#: pg_test_timing.c:188 msgid "count" msgstr "计数" -#: pg_test_timing.c:186 +#: pg_test_timing.c:197 #, c-format msgid "Histogram of timing durations:\n" msgstr "持续时间的柱状图:\n" diff --git a/src/bin/pg_test_timing/t/001_basic.pl b/src/bin/pg_test_timing/t/001_basic.pl new file mode 100644 index 000000000000..72e5a42b6f2e --- /dev/null +++ b/src/bin/pg_test_timing/t/001_basic.pl @@ -0,0 +1,28 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + +use strict; +use warnings; + +use Config; +use TestLib; +use Test::More tests => 12; + +######################################### +# Basic checks + +program_help_ok('pg_test_timing'); +program_version_ok('pg_test_timing'); +program_options_handling_ok('pg_test_timing'); + +######################################### +# Test invalid option combinations + +command_fails_like( + [ 'pg_test_timing', '--duration', 'a' ], + qr/\Qpg_test_timing: invalid argument for option --duration\E/, + 'pg_test_timing: invalid argument for option --duration'); +command_fails_like( + [ 'pg_test_timing', '--duration', '0' ], + qr/\Qpg_test_timing: --duration must be in range 1..4294967295\E/, + 'pg_test_timing: --duration must be in range'); diff --git a/src/bin/pg_upgrade/.gitignore b/src/bin/pg_upgrade/.gitignore index 707442aad5b9..bbae6abf9c56 100644 --- a/src/bin/pg_upgrade/.gitignore +++ b/src/bin/pg_upgrade/.gitignore @@ -1,9 +1,7 @@ /pg_upgrade # Generated by test suite /pg_upgrade_internal.log -/analyze_new_cluster.sh /delete_old_cluster.sh -/analyze_new_cluster.bat /delete_old_cluster.bat /reindex_hash.sql /loadable_libraries.txt diff --git a/src/bin/pg_upgrade/Makefile b/src/bin/pg_upgrade/Makefile index f6fa161b0bfa..b742374c7e62 100644 --- a/src/bin/pg_upgrade/Makefile +++ b/src/bin/pg_upgrade/Makefile @@ -50,7 +50,7 @@ uninstall: clean distclean maintainer-clean: rm -f pg_upgrade$(X) $(OBJS) - rm -rf analyze_new_cluster.sh delete_old_cluster.sh log/ tmp_check/ \ + rm -rf delete_old_cluster.sh log/ tmp_check/ \ loadable_libraries.txt reindex_hash.sql \ pg_upgrade_dump_globals.sql \ pg_upgrade_dump_*.custom pg_upgrade_*.log \ diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index d81fbc4c5828..f2259a39f3d5 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -258,20 +258,12 @@ issue_warnings_and_set_wal_level(char *sequence_script_file_name) void -output_completion_banner(char *analyze_script_file_name, - char *deletion_script_file_name) +output_completion_banner(char *deletion_script_file_name) { - /* Did we copy the free space files? */ - if (GET_MAJOR_VERSION(old_cluster.major_version) >= 804) - pg_log(PG_REPORT, - "Optimizer statistics are not transferred by pg_upgrade so,\n" - "once you start the new server, consider running:\n" - " %s\n\n", analyze_script_file_name); - else - pg_log(PG_REPORT, - "Optimizer statistics and free space information are not transferred\n" - "by pg_upgrade so, once you start the new server, consider running:\n" - " %s\n\n", analyze_script_file_name); + pg_log(PG_REPORT, + "Optimizer statistics are not transferred by pg_upgrade so,\n" + "once you start the new server, consider running:\n" + " vacuumdb --all --analyze-in-stages\n\n"); if (deletion_script_file_name) diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c index 359ddc4aaec3..cabfa363a638 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -3,7 +3,7 @@ * * controldata functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/controldata.c */ @@ -100,20 +100,20 @@ get_control_data(ClusterInfo *cluster, bool live_check) if (getenv("LC_MESSAGES")) lc_messages = pg_strdup(getenv("LC_MESSAGES")); - pg_putenv("LC_COLLATE", NULL); - pg_putenv("LC_CTYPE", NULL); - pg_putenv("LC_MONETARY", NULL); - pg_putenv("LC_NUMERIC", NULL); - pg_putenv("LC_TIME", NULL); + unsetenv("LC_COLLATE"); + unsetenv("LC_CTYPE"); + unsetenv("LC_MONETARY"); + unsetenv("LC_NUMERIC"); + unsetenv("LC_TIME"); #ifndef WIN32 - pg_putenv("LANG", NULL); + unsetenv("LANG"); #else /* On Windows the default locale may not be English, so force it */ - pg_putenv("LANG", "en"); + setenv("LANG", "en", 1); #endif - pg_putenv("LANGUAGE", NULL); - pg_putenv("LC_ALL", NULL); - pg_putenv("LC_MESSAGES", "C"); + unsetenv("LANGUAGE"); + unsetenv("LC_ALL"); + setenv("LC_MESSAGES", "C", 1); /* * Check for clean shutdown @@ -183,7 +183,7 @@ get_control_data(ClusterInfo *cluster, bool live_check) } /* pg_resetxlog has been renamed to pg_resetwal in version 10 */ - if (GET_MAJOR_VERSION(cluster->bin_version) < 1000) + if (GET_MAJOR_VERSION(cluster->bin_version) <= 906) resetwal_bin = "pg_resetxlog\" -n"; else resetwal_bin = "pg_resetwal\" -n"; @@ -554,17 +554,31 @@ get_control_data(ClusterInfo *cluster, bool live_check) pclose(output); /* - * Restore environment variables + * Restore environment variables. Note all but LANG and LC_MESSAGES were + * unset above. */ - pg_putenv("LC_COLLATE", lc_collate); - pg_putenv("LC_CTYPE", lc_ctype); - pg_putenv("LC_MONETARY", lc_monetary); - pg_putenv("LC_NUMERIC", lc_numeric); - pg_putenv("LC_TIME", lc_time); - pg_putenv("LANG", lang); - pg_putenv("LANGUAGE", language); - pg_putenv("LC_ALL", lc_all); - pg_putenv("LC_MESSAGES", lc_messages); + if (lc_collate) + setenv("LC_COLLATE", lc_collate, 1); + if (lc_ctype) + setenv("LC_CTYPE", lc_ctype, 1); + if (lc_monetary) + setenv("LC_MONETARY", lc_monetary, 1); + if (lc_numeric) + setenv("LC_NUMERIC", lc_numeric, 1); + if (lc_time) + setenv("LC_TIME", lc_time, 1); + if (lang) + setenv("LANG", lang, 1); + else + unsetenv("LANG"); + if (language) + setenv("LANGUAGE", language, 1); + if (lc_all) + setenv("LC_ALL", lc_all, 1); + if (lc_messages) + setenv("LC_MESSAGES", lc_messages, 1); + else + unsetenv("LC_MESSAGES"); pg_free(lc_collate); pg_free(lc_ctype); diff --git a/src/bin/pg_upgrade/dump.c b/src/bin/pg_upgrade/dump.c index 0b53f775af9e..845899af42cf 100644 --- a/src/bin/pg_upgrade/dump.c +++ b/src/bin/pg_upgrade/dump.c @@ -3,7 +3,7 @@ * * dump functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/dump.c */ diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c index 565a46c30035..2889ee47a39e 100644 --- a/src/bin/pg_upgrade/exec.c +++ b/src/bin/pg_upgrade/exec.c @@ -18,7 +18,7 @@ static void check_data_dir(ClusterInfo *cluster); static void check_bin_dir(ClusterInfo *cluster); static void get_bin_version(ClusterInfo *cluster); -static void validate_exec(const char *dir, const char *cmdName); +static void gpdb_validate_exec(const char *dir, const char *cmdName); #ifdef WIN32 static int win32_check_directory_write_permissions(void); @@ -379,9 +379,9 @@ check_bin_dir(ClusterInfo *cluster) report_status(PG_FATAL, "\"%s\" is not a directory\n", cluster->bindir); - validate_exec(cluster->bindir, "postgres"); - validate_exec(cluster->bindir, "pg_controldata"); - validate_exec(cluster->bindir, "pg_ctl"); + gpdb_validate_exec(cluster->bindir, "postgres"); + gpdb_validate_exec(cluster->bindir, "pg_controldata"); + gpdb_validate_exec(cluster->bindir, "pg_ctl"); /* * Fetch the binary version after checking for the existence of pg_ctl. @@ -392,9 +392,9 @@ check_bin_dir(ClusterInfo *cluster) /* pg_resetxlog has been renamed to pg_resetwal in version 10 */ if (GET_MAJOR_VERSION(cluster->bin_version) < 1000) - validate_exec(cluster->bindir, "pg_resetxlog"); + gpdb_validate_exec(cluster->bindir, "pg_resetxlog"); else - validate_exec(cluster->bindir, "pg_resetwal"); + gpdb_validate_exec(cluster->bindir, "pg_resetwal"); if (cluster == &new_cluster) { @@ -403,23 +403,23 @@ check_bin_dir(ClusterInfo *cluster) * pg_dumpall are used to dump the old cluster, but must be of the * target version. */ - validate_exec(cluster->bindir, "initdb"); - validate_exec(cluster->bindir, "pg_dump"); - validate_exec(cluster->bindir, "pg_dumpall"); - validate_exec(cluster->bindir, "pg_restore"); - validate_exec(cluster->bindir, "psql"); - validate_exec(cluster->bindir, "vacuumdb"); + gpdb_validate_exec(cluster->bindir, "initdb"); + gpdb_validate_exec(cluster->bindir, "pg_dump"); + gpdb_validate_exec(cluster->bindir, "pg_dumpall"); + gpdb_validate_exec(cluster->bindir, "pg_restore"); + gpdb_validate_exec(cluster->bindir, "psql"); + gpdb_validate_exec(cluster->bindir, "vacuumdb"); } } /* - * validate_exec() + * gpdb_validate_exec() * * validate "path" as an executable file */ static void -validate_exec(const char *dir, const char *cmdName) +gpdb_validate_exec(const char *dir, const char *cmdName) { char path[MAXPGPATH]; struct stat buf; diff --git a/src/bin/pg_upgrade/file.c b/src/bin/pg_upgrade/file.c index 46f173533ccf..ebbd80fe131b 100644 --- a/src/bin/pg_upgrade/file.c +++ b/src/bin/pg_upgrade/file.c @@ -3,7 +3,7 @@ * * file system operations * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/file.c */ diff --git a/src/bin/pg_upgrade/function.c b/src/bin/pg_upgrade/function.c index 4750dfe1ca4d..572164005b7c 100644 --- a/src/bin/pg_upgrade/function.c +++ b/src/bin/pg_upgrade/function.c @@ -3,7 +3,7 @@ * * server-side function support * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/function.c */ @@ -89,7 +89,7 @@ get_loadable_libraries(void) * http://archives.postgresql.org/pgsql-hackers/2012-03/msg01101.php * http://archives.postgresql.org/pgsql-bugs/2012-05/msg00206.php */ - if (GET_MAJOR_VERSION(old_cluster.major_version) < 901) + if (GET_MAJOR_VERSION(old_cluster.major_version) <= 900) { PGresult *res; @@ -217,7 +217,7 @@ check_loadable_libraries(void) * library name "plpython" in an old PG <= 9.1 cluster must look * for "plpython2" in the new cluster. */ - if (GET_MAJOR_VERSION(old_cluster.major_version) < 901 && + if (GET_MAJOR_VERSION(old_cluster.major_version) <= 900 && strcmp(lib, "$libdir/plpython") == 0) { lib = "$libdir/plpython2"; diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c index b5459bfcaa8b..a4e711374f79 100644 --- a/src/bin/pg_upgrade/info.c +++ b/src/bin/pg_upgrade/info.c @@ -3,7 +3,7 @@ * * information support functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/info.c */ diff --git a/src/bin/pg_upgrade/nls.mk b/src/bin/pg_upgrade/nls.mk index fa05b3292b14..06308bdf7888 100644 --- a/src/bin/pg_upgrade/nls.mk +++ b/src/bin/pg_upgrade/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_upgrade/nls.mk CATALOG_NAME = pg_upgrade -AVAIL_LANGUAGES = cs de es fr ja ko ru sv tr zh_CN +AVAIL_LANGUAGES = cs de es fr ja ko ru sv tr uk zh_CN GETTEXT_FILES = check.c controldata.c dump.c exec.c file.c function.c \ info.c option.c parallel.c pg_upgrade.c relfilenode.c \ server.c tablespace.c util.c version.c diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c index e072b55c3d4a..bb6203ca1a69 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -3,7 +3,7 @@ * * options functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/option.c */ @@ -199,7 +199,7 @@ parseCommandLine(int argc, char *argv[]) * Push the user name into the environment so pre-9.1 * pg_ctl/libpq uses it. */ - pg_putenv("PGUSER", os_info.user); + setenv("PGUSER", os_info.user, 1); break; case 'v': @@ -251,11 +251,11 @@ parseCommandLine(int argc, char *argv[]) char *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY, getenv("PGOPTIONS")); - pg_putenv("PGOPTIONS", pgoptions); + setenv("PGOPTIONS", pgoptions, 1); pfree(pgoptions); } else - pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY); + setenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY, 1); /* Get values from env if not already set */ check_required_directory(&old_cluster.bindir, "PGBINOLD", false, diff --git a/src/bin/pg_upgrade/parallel.c b/src/bin/pg_upgrade/parallel.c index 5e8cfbbec909..ee7364da3bb0 100644 --- a/src/bin/pg_upgrade/parallel.c +++ b/src/bin/pg_upgrade/parallel.c @@ -3,7 +3,7 @@ * * multi-process support * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/parallel.c */ @@ -297,7 +297,7 @@ reap_child(bool wait_for_child) #ifndef WIN32 child = waitpid(-1, &work_status, wait_for_child ? 0 : WNOHANG); if (child == (pid_t) -1) - pg_fatal("waitpid() failed: %s\n", strerror(errno)); + pg_fatal("%s() failed: %s\n", "waitpid", strerror(errno)); if (child == 0) return false; /* no children, or no dead children */ if (work_status != 0) diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c index 0e173388b9f9..4bd54423fe24 100644 --- a/src/bin/pg_upgrade/pg_upgrade.c +++ b/src/bin/pg_upgrade/pg_upgrade.c @@ -4,7 +4,7 @@ * main source file * * Portions Copyright (c) 2016-Present, VMware, Inc. or its affiliates - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/pg_upgrade.c */ @@ -240,7 +240,6 @@ main(int argc, char **argv) new_cluster.pgdata); check_ok(); - create_script_for_cluster_analyze(&analyze_script_file_name); create_script_for_old_cluster_deletion(&deletion_script_file_name); issue_warnings_and_set_wal_level(sequence_script_file_name); @@ -253,10 +252,8 @@ main(int argc, char **argv) report_progress(NULL, DONE, "Upgrade complete"); close_progress(); - output_completion_banner(analyze_script_file_name, - deletion_script_file_name); + output_completion_banner(deletion_script_file_name); - pg_free(analyze_script_file_name); pg_free(deletion_script_file_name); cleanup(); @@ -598,7 +595,7 @@ create_new_objects(void) * We don't have minmxids for databases or relations in pre-9.3 clusters, * so set those after we have restored the schema. */ - if (GET_MAJOR_VERSION(old_cluster.major_version) < 903) + if (GET_MAJOR_VERSION(old_cluster.major_version) <= 902) set_frozenxids(true); /* update new_cluster info now that we have objects in the databases */ @@ -673,9 +670,9 @@ copy_xact_xlog_xid(void) * Copy old commit logs to new data dir. pg_clog has been renamed to * pg_xact in post-10 clusters. */ - copy_subdir_files(GET_MAJOR_VERSION(old_cluster.major_version) < 1000 ? + copy_subdir_files(GET_MAJOR_VERSION(old_cluster.major_version) <= 906 ? "pg_clog" : "pg_xact", - GET_MAJOR_VERSION(new_cluster.major_version) < 1000 ? + GET_MAJOR_VERSION(new_cluster.major_version) <= 906 ? "pg_clog" : "pg_xact"); /* diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h index 237a0650c2c8..3c4dd2d9c011 100644 --- a/src/bin/pg_upgrade/pg_upgrade.h +++ b/src/bin/pg_upgrade/pg_upgrade.h @@ -439,8 +439,7 @@ void check_and_dump_old_cluster(bool live_check, char **sequence_script_file_na void check_new_cluster(void); void report_clusters_compatible(void); void issue_warnings_and_set_wal_level(char *sequence_script_file_name); -void output_completion_banner(char *analyze_script_file_name, - char *deletion_script_file_name); +void output_completion_banner(char *deletion_script_file_name); void check_cluster_versions(void); void check_cluster_compatibility(bool live_check); void create_script_for_old_cluster_deletion(char **deletion_script_file_name); diff --git a/src/bin/pg_upgrade/po/cs.po b/src/bin/pg_upgrade/po/cs.po new file mode 100644 index 000000000000..9ffcaca49fd6 --- /dev/null +++ b/src/bin/pg_upgrade/po/cs.po @@ -0,0 +1,1804 @@ +# LANGUAGE message translation file for pg_upgrade +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_upgrade (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:15+0000\n" +"PO-Revision-Date: 2020-10-31 21:14+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.1\n" + +#: check.c:67 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Provádím Kontrolu Konzistence na Starém Live Serveru\n" +"----------------------------------------------------\n" + +#: check.c:73 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Provádím Kontrolu Konzistence\n" +"-----------------------------\n" + +#: check.c:193 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Clustery jsou kompatibilní*\n" + +#: check.c:199 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Pokud pg_upgrade selže po tomto místě, musíte reinicializovat\n" +"(initdb) nový cluster než budete pokračovat.\n" + +#: check.c:233 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Statistiky optimalizéru nejsou zachovány při pg_upgrade,\n" +"takže po nastartování nového serveru zvažte spuštění:\n" +" %s\n" +"\n" + +#: check.c:239 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"Spuštění tohoto skriptu smaže datové soubory starého clusteru:\n" +" %s\n" + +#: check.c:244 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Nelze vytvořit skript pro smazání datových souborů starého cluster\n" +"protože uživatelem definované tablespaces nebo datový adresář nového\n" +"clusteru jsou v adresáři starého clusteru. Obsah starého clusteru musí\n" +"být smazán manuálně.\n" + +#: check.c:254 +#, c-format +msgid "Checking cluster versions" +msgstr "Kontroluji verze clusterů" + +#: check.c:266 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Tato utilita může upgradovat pouze z PostgreSQL verze 8.4 a novějších.\n" + +#: check.c:270 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Tato utilita může upgradovat pouze na PostgreSQL verze %s.\n" + +#: check.c:279 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Tato utilita nemůže být použita pro downgrade na starší major PostgreSQL verze.\n" + +#: check.c:284 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Data a binární adresáře starého clusteru jsou z jiných major verzí.\n" + +#: check.c:287 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Data a binární adresáře nového clusteru jsou z různých minárních verzí.\n" + +#: check.c:304 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Při kontrole pre-PG 9.1 živého starého serveru, musíte zadat číslo portu starého serveru.\n" + +#: check.c:308 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Při kontrole živého serveru, staré a nové číslo portu musí být různá.\n" + +#: check.c:323 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "kódování databáze \"%s\" neodpovídají: stará \"%s\", nová \"%s\"\n" + +#: check.c:328 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_collate hodnoty pro databázi \"%s\" neodpovídají: stará \"%s\", nová \"%s\"\n" + +#: check.c:331 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_ctype hodnoty pro databázi \"%s\" neodpovídají: stará \"%s\", nová \"%s\"\n" + +#: check.c:404 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "Databáze \"%s\" na novém clusteru není prázdná: nalezena relace \"%s.%s\"\n" + +#: check.c:453 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Vytvářím skript pro analyze nového clusteru" + +#: check.c:467 check.c:626 check.c:890 check.c:969 check.c:1079 check.c:1170 +#: file.c:336 function.c:240 option.c:497 version.c:54 version.c:199 +#: version.c:341 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "nelze otevřít soubor \"%s\": %s\n" + +#: check.c:515 check.c:682 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "nelze přidat právo na spuštění pro soubor \"%s\": %s\n" + +#: check.c:545 +#, c-format +msgid "Checking for new cluster tablespace directories" +msgstr "Kontroluji tablespace adresáře v novém clusteru" + +#: check.c:556 +#, c-format +msgid "new cluster tablespace directory already exists: \"%s\"\n" +msgstr "tablespace adresář v novém clusteru již existuje \"%s\"\n" + +#: check.c:589 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"VAROVÁNÍ: nový datový adresář by neměl být ve starém datovém adresáři, e.g. %s\n" + +#: check.c:613 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"VAROVÁNÍ: umístění uživatelem definovaných tablespaces by neměly být v datovém adresáři, e.g. %s\n" + +#: check.c:623 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Vytvářím skript pro smazání starého clusteru" + +#: check.c:702 +#, c-format +msgid "Checking database user is the install user" +msgstr "Kontroluji že databázový uživatel je použit pro instalaci" + +#: check.c:718 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "databázový uživatel \"%s\" nebyl použit pro instalaci\n" + +#: check.c:729 +#, c-format +msgid "could not determine the number of users\n" +msgstr "nelže určit počet uživatelů\n" + +#: check.c:737 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Pouze instalační uživatel může být definován pro nový cluster.\n" + +#: check.c:757 +#, c-format +msgid "Checking database connection settings" +msgstr "Kontroluji nastavení databázového spojení" + +#: check.c:779 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 nesmí povolovat spojení, i.e. příslušná hodnota pg_database.datallowconn musí být false\n" + +#: check.c:789 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Všechny non-template0 databáze musí povolovat spojení, i.e. jejich pg_database.datallowconn musí být true\n" + +#: check.c:814 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Kontroluji prepared transakce" + +#: check.c:823 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Zdrojový cluster obsahuje prepared transakce\n" + +#: check.c:825 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Cílový cluster obsahuje prepared transakce\n" + +#: check.c:851 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Kontroluji contrib/isn s bigint-passing rozdílem" + +#: check.c:912 check.c:991 check.c:1102 check.c:1193 function.c:262 +#: version.c:245 version.c:282 version.c:425 +#, c-format +msgid "fatal\n" +msgstr "fatal\n" + +#: check.c:913 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace obsahuje \"contrib/isn\" funkce které spoléhají na\n" +"bigint datový typ. Váš starý a nový cluster předávají bigint hodnoty\n" +"rozdílně takže tento cluster aktuálně nelze upgradovat. Můžete manuálně\n" +"upgradovat databáze které používají \"contrib/isn\" prostředky a odstranit\n" +"\"contrib/isn\" ze starého clusteru a znovu spustit upgrade. Seznam\n" +"problematických funkcí je v souboru:\n" +" %s\n" +"\n" + +#: check.c:937 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Kontrola tabulek s WITH OIDS" + +#: check.c:992 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace obsahuje tabulky deklarované s WITH OIDS, což již nadále není podporováno.\n" +"Zvažte odstranění oid sloupce pomocí\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Seznam tabulek s tímto problémem je v souboru:\n" +" %s\n" +"\n" + +#: check.c:1022 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Kontroluji reg* datové typy v uživatelských tabulkách" + +#: check.c:1103 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the\n" +"problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace obsahuje některý z reg* datových typů v uživatelských\n" +"tabulkách. Tyto datové typy odkazují na systémové OID hodnoty které\n" +"nejsou zachovány při pg_upgrade, takže tento cluster aktuálně nelze\n" +"upgradovat. Můžete odstranit problematické tabulky a znovu spustit\n" +"upgrade. Seznam problematických sloupců je v souboru:\n" +" %s\n" +"\n" + +#: check.c:1128 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Kontroluji nekompatibilní \"jsonb\" datový typ" + +#: check.c:1194 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can remove the problem\n" +"tables and restart the upgrade. A list of the problem columns is\n" +"in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace obsahuje \"jsonb\" datový typ v uživatelských tabulkách.\n" +"Interní formát \"jsonb\" se změnil v 9.4 beta takže tento cluster aktuálně nelze\n" +"upgradovat. Můžete odstranit problematické tabulky a znovu spustit upgrade.\n" +"Seznam problematických sloupců je v souboru:\n" +" %s\n" +"\n" + +#: check.c:1216 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Kontroluji existenci rolí začínajících na \"pg_\"" + +#: check.c:1226 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Zdrojový cluster obsahuje role začínající na \"pg_\"\n" + +#: check.c:1228 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Cílový cluster obsahuje role začínající na \"pg_\"\n" + +#: check.c:1254 +#, c-format +msgid "failed to get the current locale\n" +msgstr "selhalo získání aktuální hodnoty locale\n" + +#: check.c:1263 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "selhalo získání jména systémové locale pro \"%s\"\n" + +#: check.c:1269 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "selhala obnova staré locale \"%s\"\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "nelze získat control data pomocí %s: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: problém se stavem databázového clusteru\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Zdrojový cluster byl vypnut v recovery módu. Pro upgrade použijte \"rsync\" jak je uvedeno v dokumentaci nebo ho vypněte jako primary.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Cílový cluster byl vypnut v recovery módu. Pro upgrade použijte \"rsync\" jak je uvedeno v dokumentaci nebo ho vypněte jako primary.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Zdrojový cluster nebyl zastaven čistě.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Cílový cluster nebyl zastaven čistě.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Zdrojový cluster postrádá některé nutné informace o stavu:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Cílový cluster postrádá některé nutné informace o stavu:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:339 pg_upgrade.c:375 +#: relfilenode.c:243 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal problem\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: controldata retrieval problem\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Zdrojový cluster postrádá některé nutné control informace:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Cílový cluster postrádá některé nutné control informace:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " další XID checkpointu\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " další OID posledního checkpointu\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " další MultiXactId posledního checkpointu\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " nejstarší MultiXactId posledního checkpointu\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " MultiXactOffset posledního checkpointu\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " první WAL segment po resets\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " metoda předávání float8 argumentů\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " maximální alignment\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " velikost bloku\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " velikost segmentu velkých relací\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " velikost WAL bloku\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " velikost WAL segmentu\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " maximální délka identifikátoru\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " maximální počet indexovaných sloupců\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " maximální velikost TOAST chunku\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " velikost large-object chunku\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " datum/čas jsou integery?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " verze datových kontrolních součtů\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Nelze pokračovat bez kontrolních informací, končím\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"stará a nová hodnota pg_controldata alignmentu jsou neplatné nebo se neshodují\n" +"Pravděpodobně jeden z clusterů je 32-bitový a druhý je 64-bitový\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata velikosti bloku jsou neplatné nebo se neshodují\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata maximální velikosti segmentu relace jsou neplatné nebo se neshodují\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata velikost WAL bloku jsou neplatné nebo se neshodují\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata velikost WAL segmentu jsou neplatné nebo se neshodují\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata maximální délky identifikátoru jsou neplatné nebo se neshodují\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata maximálního počtu indexovaných sloupců jsou neplatné nebo se neshodují\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata maximální velikosti TOAST chunku jsou neplatné nebo se neshodují\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "stará a nová hodnota pg_controldata velikosti large-object chunku jsou neplatné nebo se neshodují\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "stará a nová hodnota pg_controldata typu pro datum/čas jsou neplatné nebo se neshodují\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "starý cluster nepoužívá data chechsums ale nový ano\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "starý cluster používá data chechsums ale nový nikoliv\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "verze kontrolních součtů na starém a novém clusteru se neshodují\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Přidávám \".old\" příponu ke starému global/pg_control souboru" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Nelze přejmenovat %s na %s.\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Pokud budete chtít nastartovat starý cluster, budete muset odstranit\n" +"příponu \".old\" z %s/global/pg_control.old.\n" +"Protože byl použit \"link\" mód, starý cluster nemůže být bezpečně\n" +"spuštěn jakmile bude nastartován nový cluster.\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "Vytvářím dump globálních objektů" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Vytvářím dump databázových schémat\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "nelze získat verzi pg_ctl pomocí %s: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "nelze získat výstup s pg_ctl verzí z %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "příkaz je příliš dlouhý\n" + +#: exec.c:110 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "nelze otevřít logovací soubor \"%s\": %m\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*failure*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Došlo k problémům při spuštění \"%s\"\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Pro pravděpodobnou příčinu selhání prozkoumejte posledních pár\n" +"řádek z \"%s\" nebo \"%s\".\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Pro pravděpodobnou příčinu selhání prozkoumejte posledních pár\n" +"řádek z \"%s\".\n" + +#: exec.c:204 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "nelze zapsat do log souboru \"%s\": %m\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "nelze otevřít soubor \"%s\" pro čtení: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Musíte mít práva na čtení a zápis v aktuálním adresáři.\n" + +#: exec.c:310 exec.c:372 exec.c:436 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "kontrola pro \"%s\" selhala: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" není adresář\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "check for \"%s\" failed: not a regular file\n" + +#: exec.c:451 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "kontrola \"%s\" selhala: nelze číst soubor (přístup odepřen)\n" + +#: exec.c:459 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "kontrola \"%s\" selhala: nelze spustit soubor (přístup odepřen)\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "chyba při klonování relace \"%s.%s\" (\"%s\" na \"%s\"): %s\n" + +#: file.c:50 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "chyba při klonování relace \"%s.%s\": nelze otevřít soubor \"%s\": %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "chyba při klonování relace \"%s.%s\": nelze vytvořit soubor \"%s\": %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "chyba při kopírování relace \"%s.%s\": nelze otevřít soubor \"%s\": %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "chyba při kopírování relace \"%s.%s\": nelze vytvořit soubor \"%s\": %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "chyba při kopírování relace \"%s.%s\": nelze číst ze souboru \"%s\": %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "chyba při kopírování relace \"%s.%s\": nelze zapsat do souboru \"%s\": %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "chyba při kopírování relace \"%s.%s\" (\"%s\" na \"%s\"): %s\n" + +#: file.c:151 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "chyba při vytváření odkazů pro relaci \"%s.%s\" (\"%s\" na \"%s\"): %s\n" + +#: file.c:194 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "chyba při kopírování relace \"%s.%s\": nelze získat informace o souboru \"%s\": %s\n" + +#: file.c:226 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "chyba při kopírování relace \"%s.%s\": částečně zapsaná stránka nalezena v souboru \"%s\"\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "nelze klonovat soubory mezi starým a novým datovým adresářem: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "nelze vytvořit soubor \"%s\": %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "klonování souborů na této platformě není podporováno\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"nelze vytvořit hard link mezi starým a novým datovým adresářem: %s\n" +"V link módu musí být starý a nový datový adresář na stejném souborovém systému.\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"Starý cluster má \"plpython_call_handler\" funkci definovanou\n" +"v \"public\" schématu což je duplicitní s tou definovanou v \"pg_catalog\"\n" +"schématu. Ověřit to můžete spuštěním tohoto v psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"Veze z \"public\" schématu byla vytvořena instalací plpython před 8.1,\n" +"a musí být odstraněna aby pg_upgrade mohlo fungovat protože\n" +"odkazuje na nyní zastaralý \"plpython\" sdílený objekt. Verzi z \"public\"\n" +"schématu můžete odstranit spuštěním následujícího příkazu:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"v každé postižené databázi:\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Pro pokračování ze starého clusteru odstraňte problematické funkce.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Kontroluji dostupnost potřebných knihoven" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "nelze načíst knihovnu \"%s\": %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "Databáze: %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace odkazuje na knihovny které chybí v nové instalaci. Můtete\n" +"je buď přidat do nové instalace, nebo odstranit funkce které je vyžadují ze\n" +"staré instalace. Seznam problematických knihoven je v souboru:\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Názvy relace pro OID %u v databázi \"%s\" neodpovídají: staré jméno \"%s.%s\", nové jméno \"%s.%s\"\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Chyba při párování starých a nových tabulek v databázi \"%s\"\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " což je index na \"%s.%s\"" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " což je index na OID %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " což je TOAST tabulka pro \"%s.%s\"" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " což je TOAST tabulka pro OID %u" + +#: info.c:274 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "Ve starém clusteru nebyl nalezen odpovídající záznam pro novou relaci s OID %u v databázi \"%s\": %s\n" + +#: info.c:277 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "V novém clusteru nebyl nalezen odpovídající záznam pro relaci s OID %u v databázi \"%s\": %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "mapování pro databázi \"%s\":\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u na %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"zdrojové databáze:\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"cílové databáze:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "Databáze: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: nelze spouštět jako root\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "neplatné staré číslo portu\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "neplatné nové číslo portu\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "příliš mnoho argumentů v příkazové řádce (první je \"%s\")\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Běží v módu s detailním (verbose) logováním.\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "binárky starého clusteru jsou umístěny" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "binárky nového clusteru jsou umístěny" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "data starého clusteru jsou umístěna" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "data nového clusteru jsou umístěna" + +#: option.c:259 +msgid "sockets will be created" +msgstr "sockety budou vytvořeny" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "nelze určit aktuální adresář\n" + +#: option.c:279 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "na Windows nelze spouštět pg_upgrade z datového adresáře nového clusteru\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade upgraduje PostgreSQL cluster na jinou major verzi.\n" +"\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [VOLBA]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "Přepínače:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR adresář se spustitelnými soubory starého clusteru\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=BINDIR adresář se spustitelnými soubory nového clusteru\n" +" (výchozí hodnota je stejný adresář jako pg_upgrade)\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check pouze kontroluje clustery, nemění žádná data\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR datový adresář starého clusteru\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR datový adresář nového clusteru\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs=NUM number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs=NUM počet paralelních procesů nebo threadů\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link vytváří odkazy namísto kopírování souborů do nového clusteru\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=VOLBY volby pro starý cluster které se mají předat serveru\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=VOLBY volby pro nový cluster které se mají předat serveru\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT číslo portu pro starý cluster (implicitně %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT číslo portu pro nový cluster (implicitně %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain v případě úspěchu zachovat SQL a log soubory\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" +msgstr "" +" -s, --socketdir=DIR adresář pro sockety (implicitně současný adresář)\n" +"\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=JMÉNO superuživatel pro cluster (implicitně \"%s\")\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose zapné podrobné interní logování\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version zobrazí informaci o verzi, poté skončí\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr "" +" --clone klonuje namísto kopírování souborů do nového clusteru\n" +"\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help zobrazí tuto nápovědu, poté skončí\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Před spuštěním pg_upgrade musíte:\n" +" vytvořit nový databázový cluster (pomocí nové verze initdb)\n" +" zastavit postmaster proces běžící nad starým clusterem\n" +" zastavit postmaster proces běžízí nad novým clusterem\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"Při spuštění pg_upgrade musíte zadat následující informace:\n" +" datový adresář pro starý cluster (-d DATADIR)\n" +" datový adresář pro nový cluster (-D DATADIR)\n" +" \"bin\" adresář pro starou verzi (-b BINDIR)\n" +" \"bin\" adresář pro novou verzi (-B BINDIR)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Například:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"nebo\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Chyby hlašte na <%s>.\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Musíte zadat adresář kde %s.\n" +"Použijte prosím volbu %s na příkazové řádce nebo proměnnou prostředí %s.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Vyhledávám skutečný datový adresář pro zdrojový cluster" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Vyhledávám skutečný datový adresář pro cílový cluster" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "nelze získat datový adresář pomocí %s: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "nelze načíst řádek %d ze souboru \"%s\": %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "uživatelem-zadané číslo starého portu %hu opraveno na %hu\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "nelze vytvořit worker proces: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "nelze vytvořit worker thread: %s\n" + +#: parallel.c:300 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "volání waitpid() selhalo: %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "podřízený proces abnormálně skončil: status %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "podřízený proces neočekávaně skončil: %s\n" + +#: pg_upgrade.c:108 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "nelze zjistit přístupová práva adresáře \"%s\": %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Provádím Upgrade\n" +"----------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Nastavuji další OID pro nový cluster" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "Synchronizuji datový adresář na disk" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Upgrade Dokončen\n" +"----------------\n" + +#: pg_upgrade.c:220 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: nelze najít vlastní spustitelný soubor\n" + +#: pg_upgrade.c:246 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Zdá se že postmaster nad starým clusterem stále běží.\n" +"Prosím zastavte příslušný postmaster proces a zkuste to znovu.\n" + +#: pg_upgrade.c:259 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Zdá se že postmaster nad novým clusterem stále běží.\n" +"Prosím zastavte příslušný postmaster proces a zkuste to znovu.\n" + +#: pg_upgrade.c:273 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analyzuji všechny řádky v novém clusteru" + +#: pg_upgrade.c:286 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Provádím freeze na všech řádcích v novém clusteru" + +#: pg_upgrade.c:306 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Obnovuji globální objekty v novém clusteru" + +#: pg_upgrade.c:321 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Obnovuji databázová schémata v novém clusteru\n" + +#: pg_upgrade.c:425 +#, c-format +msgid "Deleting files from new %s" +msgstr "Mažu soubory z nového %s" + +#: pg_upgrade.c:429 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "nelze smazat adresář \"%s\"\n" + +#: pg_upgrade.c:448 +#, c-format +msgid "Copying old %s to new server" +msgstr "Kopíruji starý %s do nového serveru" + +#: pg_upgrade.c:475 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Nastavuij následující transaction ID a epochu pro nový cluster" + +#: pg_upgrade.c:505 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Nastavuji následující multixact ID a offset pro nový cluster" + +#: pg_upgrade.c:529 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Nastavuji nejstarší multixact ID v novém clusteru" + +#: pg_upgrade.c:549 +#, c-format +msgid "Resetting WAL archives" +msgstr "Resetuji WAL archivy" + +#: pg_upgrade.c:592 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Nastavuji frozenxid a minmxid v novém clusteru" + +#: pg_upgrade.c:594 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Nastavuji minmxid v novém clustreru" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Klonuji soubory pro uživatelské relace\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "Kopíruji soubory pro uživatelské relace\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "Linkuji soubory pro uživatelské relace\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "stará databáze \"%s\" nenalezena v novém clusteru\n" + +#: relfilenode.c:230 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "chyba při kontrole existence souboru \"%s.%s\" (\"%s\" na \"%s\"): %s\n" + +#: relfilenode.c:248 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "přepisuji \"%s\" na \"%s\"\n" + +#: relfilenode.c:256 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "klonuji \"%s\" do \"%s\"\n" + +#: relfilenode.c:261 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "kopíruji \"%s\" do \"%s\"\n" + +#: relfilenode.c:266 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "linkuji \"%s\" na \"%s\"\n" + +#: server.c:33 +#, c-format +msgid "connection to database failed: %s" +msgstr "spojení do databáze selhalo: %s" + +#: server.c:39 server.c:141 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "Chyba, končím\n" + +#: server.c:131 +#, c-format +msgid "executing: %s\n" +msgstr "spouštím: %s\n" + +#: server.c:137 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL příkaz selhal\n" +"%s\n" +"%s" + +#: server.c:167 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "nelze otevřít soubor s verzí: \"%s\": %m\n" + +#: server.c:171 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "neplatný formát řetězce s verzí \"%s\"\n" + +#: server.c:297 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"spojení na databázi selhalo: %s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"nelze se připojit ke zdrojovému postmaster procesu příkazem:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"nelze se připojit k cílovému postmaster procesu příkazem:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl selhal při pokusu nastartovat zdrojový server, nebo selhal pokus o spojení\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl selhal při pokusu nastartovat cílový server, nebo selhal pokus o spojení\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek paměti\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "libpq proměnná prostředí %s má hodnotu odkazující na nelokální server: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"Při použití tablespaces nelze provádět upgrade na/ze stejné verze\n" +"systémových katalogů.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "adresář pro tablespace \"%s\" neexistuje\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "nelze přistoupit k tablespace adresáři \"%s\": %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "cesta k tabespace \"%s\" není adresář\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "Kontrola velkých objektů" + +#: version.c:77 version.c:384 +#, c-format +msgid "warning" +msgstr "varování" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Vaše instalace obsahuje velké objekty. Nová databáze má další tabulku\n" +"s právy k velkým objektům. Po upgrade vám bude poskytnut příkaz pro\n" +"naplnění tabulky pg_largeobject_metadata s výchozími právy.\n" +"\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Vaše instalace obsahuje velké objekty. Nová databáze má další tabulku\n" +"s právy k velkým objektům, takže pro všechny velké objekty musí být\n" +"definována výchozí práva. Soubor\n" +" %s\n" +"po spuštění z psql pod superuživatelským účtem tato výchozí práva nastaví.\n" +"\n" + +#: version.c:239 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Kontrola nekompatibilního \"line\" datového typu" + +#: version.c:246 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace obsahuje datový typ \"line\" v uživatelských tabulkách. Tento\n" +"datový typ změnil interní a vstupní/výstupní formát mezi vaším starým a novým\n" +"clusterem takže tento cluster nemůže být aktuálně upgradován. Můžete odstranit\n" +"problematické tabulky a znovu spustit upgrade. Seznam problematických sloupců\n" +"je v souboru:\n" +" %s\n" +"\n" + +#: version.c:276 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Kontrola pro neplatné \"unknown\" uživatelské sloupce" + +#: version.c:283 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace obsahuje \"unknown\" datový typ v uživatelských tabulkách. Tento\n" +"datový typ není v uživatelských tabulkách nadále povolen, takže tento cluster nelze\n" +"aktuálně upgradovat. Můžete problematické tabulky odstranit a znovu spustit upgrade.\n" +"Seznam problematických sloupců je v souboru:\n" +" %s\n" +"\n" + +#: version.c:306 +#, c-format +msgid "Checking for hash indexes" +msgstr "Kontrola hash indexů" + +#: version.c:386 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Vaše instalace obsahuje hash indexy. Tyto indexy mají rozdílný interní\n" +"formát mezi vaším starým a novým clusterem, takže musí být reindexovány\n" +"příkazem REINDEX. Po skončení upgrade vám budou poskytnuty instrukce\n" +"jak REINDEX provést.\n" +"\n" + +#: version.c:392 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Vaše instalace obsahuje hash indexy. Tyto indexy mají rozdílný interní\n" +"formát mezi vaším starým a novým clusterem, takže musí být reindexovány\n" +"příkazem REINDEX. Soubor\n" +" %s\n" +"po spuštění z psql pod superuživatelským účtem znovu vytvoří všechny\n" +"neplatné indexy; dokud k tomu nedojde tyto indexy nebudou používány.\n" +"\n" + +#: version.c:418 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "Kontrola pro neplatné \"sql_identifier\" uživatelské sloupce" + +#: version.c:426 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables\n" +"and/or indexes. The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can remove the problem tables or\n" +"change the data type to \"name\" and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Vaše instalace obsahuje \"sql_identifier\" datový typ v uživatelských tabulkách\n" +"a/nebo indexech. Formát uložení na disku pro tento datový typ se změnil, takže\n" +"tento cluster nelze aktuálně upgradovat. Můžete problematické tabulky\n" +"odstranit nebo datový typ změnit na \"name\" a znovu spustit upgrade.\n" +"Seznam problematických sloupců je v souboru:\n" +" %s\n" +"\n" + +#~ msgid "could not parse PG_VERSION file from %s\n" +#~ msgstr "nelze naparsovat PG_VERSION soubor z %s\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" + +#~ msgid "" +#~ "Optimizer statistics and free space information are not transferred\n" +#~ "by pg_upgrade so, once you start the new server, consider running:\n" +#~ " %s\n" +#~ "\n" +#~ msgstr "" +#~ "Statistiky optimalizéru a informace o volném místě nejsou zachovány\n" +#~ "při pg_upgrade, takže po nastartování nového serveru zvažte spuštění:\n" +#~ " %s\n" +#~ "\n" diff --git a/src/bin/pg_upgrade/po/de.po b/src/bin/pg_upgrade/po/de.po new file mode 100644 index 000000000000..dda800b88c76 --- /dev/null +++ b/src/bin/pg_upgrade/po/de.po @@ -0,0 +1,1858 @@ +# German message translation file for pg_upgrade +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-12 17:47+0000\n" +"PO-Revision-Date: 2021-05-13 00:10+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: check.c:70 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Führe Konsistenzprüfungen am alten laufenden Server durch\n" +"---------------------------------------------------------\n" + +#: check.c:76 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Führe Konsistenzprüfungen durch\n" +"-------------------------------\n" + +#: check.c:213 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Cluster sind kompatibel*\n" + +#: check.c:219 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Wenn pg_upgrade ab diesem Punkt fehlschlägt, dann müssen Sie den\n" +"neuen Cluster neu mit initdb initialisieren, bevor fortgesetzt\n" +"werden kann.\n" + +#: check.c:262 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade.\n" +"Once you start the new server, consider running:\n" +" %s/vacuumdb %s--all --analyze-in-stages\n" +"\n" +msgstr "" +"Optimizer-Statistiken werden von pg_upgrade nicht übertragen. Wenn Sie\n" +"den neuen Server starten, sollte Sie diesen Befehl ausführen:\n" +" %s/vacuumdb %s--all --analyze-in-stages\n" +"\n" + +#: check.c:268 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"Mit diesem Skript können die Dateien des alten Clusters gelöscht werden:\n" +" %s\n" + +#: check.c:273 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Ein Skript zum Löschen der Dateien des alten Clusters konnte nicht\n" +"erzeugt werden, weil benutzerdefinierte Tablespaces oder das\n" +"Datenverzeichnis des neuen Clusters im alten Cluster-Verzeichnis\n" +"liegen. Der Inhalt des alten Clusters muss von Hand gelöscht werden.\n" + +#: check.c:285 +#, c-format +msgid "Checking cluster versions" +msgstr "Prüfe Cluster-Versionen" + +#: check.c:297 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Dieses Programm kann nur Upgrades von PostgreSQL Version 8.4 oder später durchführen.\n" + +#: check.c:301 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Dieses Programm kann nur Upgrades auf PostgreSQL Version %s durchführen.\n" + +#: check.c:310 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Dieses Programm kann keine Downgrades auf ältere Hauptversionen von PostgreSQL durchführen.\n" + +#: check.c:315 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Die Daten- und Programmverzeichnisse des alten Clusters stammen von verschiedenen Hauptversionen.\n" + +#: check.c:318 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Die Daten- und Programmverzeichnisse des neuen Clusters stammen von verschiedenen Hauptversionen.\n" + +#: check.c:335 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Wenn ein laufender alter Server vor Version 9.1 geprüft wird, muss die Portnummer des alten Servers angegeben werden.\n" + +#: check.c:339 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Wenn ein laufender Server geprüft wird, müssen die alte und die neue Portnummer verschieden sein.\n" + +#: check.c:354 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "Kodierungen für Datenbank »%s« stimmen nicht überein: alt »%s«, neu »%s«\n" + +#: check.c:359 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_collate-Werte für Datenbank »%s« stimmen nicht überein: alt »%s«, neu »%s«\n" + +#: check.c:362 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_ctype-Werte für Datenbank »%s« stimmen nicht überein: alt »%s«, neu »%s«\n" + +#: check.c:435 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "Datenbank »%s« im neuen Cluster ist nicht leer: Relation »%s.%s« gefunden\n" + +#: check.c:492 +#, c-format +msgid "Checking for new cluster tablespace directories" +msgstr "Prüfe Tablespace-Verzeichnisse des neuen Clusters" + +#: check.c:503 +#, c-format +msgid "new cluster tablespace directory already exists: \"%s\"\n" +msgstr "Tablespace-Verzeichnis für neuen Cluster existiert bereits: »%s«\n" + +#: check.c:536 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"WARNUNG: das neue Datenverzeichnis sollte nicht im alten Datenverzeichnis liegen, z.B. %s\n" + +#: check.c:560 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"WARNUNG: benutzerdefinierte Tablespace-Pfade sollten nicht im Datenverzeichnis liegen, z.B. %s\n" + +#: check.c:570 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Erzeuge Skript zum Löschen des alten Clusters" + +#: check.c:573 check.c:837 check.c:935 check.c:1014 check.c:1276 file.c:336 +#: function.c:240 option.c:497 version.c:54 version.c:204 version.c:376 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "konnte Datei »%s« nicht öffnen: %s\n" + +#: check.c:629 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "konnte Datei »%s« nicht ausführbar machen: %s\n" + +#: check.c:649 +#, c-format +msgid "Checking database user is the install user" +msgstr "Prüfe ob der Datenbankbenutzer der Installationsbenutzer ist" + +#: check.c:665 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "Datenbankbenutzer »%s« ist nicht der Installationsbenutzer\n" + +#: check.c:676 +#, c-format +msgid "could not determine the number of users\n" +msgstr "konnte die Anzahl der Benutzer nicht ermitteln\n" + +#: check.c:684 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Nur der Installationsbenutzer darf im neuen Cluster definiert sein.\n" + +#: check.c:704 +#, c-format +msgid "Checking database connection settings" +msgstr "Prüfe Verbindungseinstellungen der Datenbank" + +#: check.c:726 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 darf keine Verbindungen erlauben, d.h. ihr pg_database.datallowconn muss falsch sein\n" + +#: check.c:736 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Alle Datenbanken außer template0 müssen Verbindungen erlauben, d.h. ihr pg_database.datallowconn muss wahr sein\n" + +#: check.c:761 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Prüfe auf vorbereitete Transaktionen" + +#: check.c:770 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Der alte Cluster enthält vorbereitete Transaktionen\n" + +#: check.c:772 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Der neue Cluster enthält vorbereitete Transaktionen\n" + +#: check.c:798 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Prüfe auf contrib/isn mit unpassender bigint-Übergabe" + +#: check.c:859 check.c:960 check.c:1036 check.c:1093 check.c:1152 check.c:1181 +#: check.c:1299 function.c:262 version.c:278 version.c:316 version.c:460 +#, c-format +msgid "fatal\n" +msgstr "fatal\n" + +#: check.c:860 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält Funktionen aus »contrib/isn«, welche den\n" +"Datentyp bigint verwenden. Der alte und der neue Cluster übergeben\n" +"bigint auf andere Weise und daher kann dieser Cluster gegenwärtig\n" +"nicht aktualisiert werden. Sie können Datenbanken im alten Cluster,\n" +"die »contrib/isn« verwenden, manuell dumpen, löschen, dann das\n" +"Upgrade durchführen und sie dann wiederherstellen. Eine Liste\n" +"der problematischen Funktionen ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:883 +#, c-format +msgid "Checking for user-defined postfix operators" +msgstr "Prüfe auf benutzerdefinierte Postfix-Operatoren" + +#: check.c:961 +#, c-format +msgid "" +"Your installation contains user-defined postfix operators, which are not\n" +"supported anymore. Consider dropping the postfix operators and replacing\n" +"them with prefix operators or function calls.\n" +"A list of user-defined postfix operators is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält benutzerdefinierte Postfixoperatoren, was\n" +"nicht mehr unterstützt wird. Entfernen Sie die Postfixoperatoren und\n" +"ersetzten Sie sie durch Präfixoperatoren oder Funktionsaufrufe. Eine\n" +"Liste der benutzerdefinierten Postfixoperatoren ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:982 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Prüfe auf Tabellen mit WITH OIDS" + +#: check.c:1037 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält Tabellen, die mit WITH OIDS deklariert sind,\n" +"was nicht mehr unterstützt wird. Entfernen Sie die oid-Spalte mit\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Eine Liste der Tabellen mit dem Problem ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:1065 +#, c-format +msgid "Checking for system-defined composite types in user tables" +msgstr "Prüfe auf systemdefinierte zusammengesetzte Typen in Benutzertabellen" + +#: check.c:1094 +#, c-format +msgid "" +"Your installation contains system-defined composite type(s) in user tables.\n" +"These type OIDs are not stable across PostgreSQL versions,\n" +"so this cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält systemdefinierte zusammengesetzte Typen in\n" +"Benutzertabellen. Die OIDs dieser Typen sind nicht über\n" +"PostgreSQL-Versionen stabil und daher kann dieser Cluster gegenwärtig\n" +"nicht aktualisiert werden. Sie können die Problemspalten löschen\n" +"und das Upgrade neu starten. Eine Liste der Problemspalten ist in der\n" +"Datei:\n" +" %s\n" +"\n" + +#: check.c:1122 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Prüfe auf reg*-Datentypen in Benutzertabellen" + +#: check.c:1153 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält einen der reg*-Datentypen in\n" +"Benutzertabellen. Diese Datentypen verweisen auf System-OIDs, die von\n" +"pg_upgrade nicht erhalten werden. Daher kann dieser Cluster\n" +"gegenwärtig nicht aktualiert werden. Sie können die Problemspalten\n" +"löschen und das Upgrade neu starten. Eine Liste der Problemspalten\n" +"ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:1175 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Prüfe auf inkompatiblen Datentyp »jsonb«" + +#: check.c:1182 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält den Datentyp »jsonb« in\n" +"Benutzertabellen. Das interne Format von »jsonb« wurde während 9.4\n" +"Beta geändert. Daher kann dieser Cluster gegenwärtig nicht\n" +"aktualisiert werden. Sie können die Problemspalten löschen und das\n" +"Upgrade neu starten. Eine Liste der Problemspalten ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:1204 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Prüfe auf Rollen, die mit »pg_« anfangen" + +#: check.c:1214 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Der alte Cluster enthält Rollen, die mit »pg_« anfangen\n" + +#: check.c:1216 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Der neue Cluster enthält Rollen, die mit »pg_« anfangen\n" + +#: check.c:1237 +#, c-format +msgid "Checking for user-defined encoding conversions" +msgstr "Prüfe auf benutzerdefinierte Kodierungsumwandlungen" + +#: check.c:1300 +#, c-format +msgid "" +"Your installation contains user-defined encoding conversions.\n" +"The conversion function parameters changed in PostgreSQL version 14\n" +"so this cluster cannot currently be upgraded. You can remove the\n" +"encoding conversions in the old cluster and restart the upgrade.\n" +"A list of user-defined encoding conversions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält benutzerdefinierte\n" +"Kodierungsumwandlungen. Die Parameter von Umwandlungsfunktionen wurden\n" +"in PostgreSQL Version 14 geändert. Daher kann dieser Cluster\n" +"gegenwärtig nicht aktualisiert werden. Sie können die\n" +"Kodierungsumwandlungen im alten Cluster entfernen und das Upgrade neu\n" +"starten. Eine Liste der benutzerdefinierten Kodierungsumwandlungen ist\n" +"in der Datei:\n" +" %s\n" +"\n" + +#: check.c:1327 +#, c-format +msgid "failed to get the current locale\n" +msgstr "konnte aktuelle Locale nicht ermitteln\n" + +#: check.c:1336 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "konnte System-Locale-Namen für »%s« nicht ermitteln\n" + +#: check.c:1342 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "konnte alte Locale »%s« nicht wiederherstellen\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "konnte Kontrolldaten mit %s nicht ermitteln: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: Problem mit dem Zustand des Clusters\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Der alte Cluster wurde im Wiederherstellungsmodus heruntergefahren. Um ihn zu aktualisieren, verwenden Sie »rsync« wie in der Dokumentation beschrieben oder fahren Sie ihn im Primärmodus herunter.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Der neue Cluster wurde im Wiederherstellungsmodus heruntergefahren. Um ihn zu aktualisieren, verwenden Sie »rsync« wie in der Dokumentation beschrieben oder fahren Sie ihn im Primärmodus herunter.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Der alte Cluster wurde nicht sauber heruntergefahren.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Der neue Cluster wurde nicht sauber heruntergefahren.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Im alten Cluster fehlen Cluster-Zustandsinformationen:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Im neuen Cluster fehlen Cluster-Zustandsinformationen:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:335 pg_upgrade.c:371 +#: relfilenode.c:243 server.c:33 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: Problem mit pg_resetwal\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: Problem beim Ermitteln der Kontrolldaten\n" + +#: controldata.c:560 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Im alten Cluster fehlen einige notwendige Kontrollinformationen:\n" + +#: controldata.c:563 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Im neuen Cluster fehlen einige notwendige Kontrollinformationen:\n" + +#: controldata.c:566 +#, c-format +msgid " checkpoint next XID\n" +msgstr " Checkpoint nächste XID\n" + +#: controldata.c:569 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " NextOID des letzten Checkpoints\n" + +#: controldata.c:572 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " NextMultiXactId des letzten Checkpoints\n" + +#: controldata.c:576 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " oldestMultiXid des letzten Checkpoints\n" + +#: controldata.c:579 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " NextMultiOffset des letzten Checkpoints\n" + +#: controldata.c:582 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " erstes WAL-Segment nach dem Reset\n" + +#: controldata.c:585 +#, c-format +msgid " float8 argument passing method\n" +msgstr " Übergabe von Float8-Argumenten\n" + +#: controldata.c:588 +#, c-format +msgid " maximum alignment\n" +msgstr " maximale Ausrichtung (Alignment)\n" + +#: controldata.c:591 +#, c-format +msgid " block size\n" +msgstr " Blockgröße\n" + +#: controldata.c:594 +#, c-format +msgid " large relation segment size\n" +msgstr " Segmentgröße für große Relationen\n" + +#: controldata.c:597 +#, c-format +msgid " WAL block size\n" +msgstr " WAL-Blockgröße\n" + +#: controldata.c:600 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL-Segmentgröße\n" + +#: controldata.c:603 +#, c-format +msgid " maximum identifier length\n" +msgstr " maximale Bezeichnerlänge\n" + +#: controldata.c:606 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " maximale Anzahl indizierter Spalten\n" + +#: controldata.c:609 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " maximale TOAST-Chunk-Größe\n" + +#: controldata.c:613 +#, c-format +msgid " large-object chunk size\n" +msgstr " Large-Object-Chunk-Größe\n" + +#: controldata.c:616 +#, c-format +msgid " dates/times are integers?\n" +msgstr " Datum/Zeit sind Ganzzahlen?\n" + +#: controldata.c:620 +#, c-format +msgid " data checksum version\n" +msgstr " Datenprüfsummenversion\n" + +#: controldata.c:622 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Kann ohne die benötigten Kontrollinformationen nicht fortsetzen, Programm wird beendet\n" + +#: controldata.c:637 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"altes und neues Alignment in pg_controldata ist ungültig oder stimmt nicht überein\n" +"Wahrscheinlich ist ein Cluster eine 32-Bit-Installation und der andere 64-Bit\n" + +#: controldata.c:641 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "alte und neue Blockgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:644 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "alte und neue maximale Relationssegmentgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:647 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "alte und neue WAL-Blockgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "alte und neue WAL-Segmentgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "alte und neue maximale Bezeichnerlängen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:656 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "alte und neue Maximalzahlen indizierter Spalten von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:659 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "alte und neue maximale TOAST-Chunk-Größen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:664 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "alte und neue Large-Object-Chunk-Größen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:667 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "alte und neue Speicherung von Datums- und Zeittypen von pg_controldata ist ungültig oder stimmt nicht überein\n" + +#: controldata.c:680 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "der alte Cluster verwendet keine Datenprüfsummen, aber der neue verwendet sie\n" + +#: controldata.c:683 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "die alte Cluster verwendet Datenprüfsummen, aber der neue nicht\n" + +#: controldata.c:685 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "Prüfsummenversionen im alten und neuen Cluster stimmen nicht überein\n" + +#: controldata.c:696 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Füge Endung ».old« an altes global/pg_control an" + +#: controldata.c:701 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Konnte %s nicht in %s umbenennen.\n" + +#: controldata.c:704 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Wenn Sie den alten Cluster starten wollen, müssen Sie die Endung\n" +"».old« von %s/global/pg_control.old entfernen. Da der »link«-Modus\n" +"verwendet wurde, kann der alte Cluster nicht gefahrlos gestartet\n" +"werden, nachdem der neue Cluster gestartet worden ist.\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "Erzeuge Dump der globalen Objekte" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Erzeuge Dump der Datenbankschemas\n" + +#: exec.c:45 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "konnte pg_ctl-Versionsdaten mit %s nicht ermitteln: %s\n" + +#: exec.c:51 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "konnte pg_ctl-Version nicht ermitteln von %s\n" + +#: exec.c:105 exec.c:109 +#, c-format +msgid "command too long\n" +msgstr "Befehl zu lang\n" + +#: exec.c:111 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:150 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "konnte Logdatei »%s« nicht öffnen: %m\n" + +#: exec.c:179 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*fehlgeschlagen*" + +#: exec.c:182 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Probleme beim Ausführen von »%s«\n" + +#: exec.c:185 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Prüfen Sie die letzten Zeilen von »%s« oder »%s« für den\n" +"wahrscheinlichen Grund für das Scheitern.\n" + +#: exec.c:190 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Prüfen Sie die letzten Zeilen von »%s« für den\n" +"wahrscheinlichen Grund für das Scheitern.\n" + +#: exec.c:205 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "konnte nicht in Logdatei »%s «schreiben: %m\n" + +#: exec.c:231 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %s\n" + +#: exec.c:258 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Sie müssen Lese- und Schreibzugriff im aktuellen Verzeichnis haben.\n" + +#: exec.c:311 exec.c:377 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "Prüfen von »%s« fehlgeschlagen: %s\n" + +#: exec.c:314 exec.c:380 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "»%s« ist kein Verzeichnis\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "Prüfen von »%s« fehlgeschlagen: keine reguläre Datei\n" + +#: exec.c:433 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "Prüfen von »%s« fehlgeschlagen: kann nicht ausgeführt werden (keine Berechtigung)\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: cannot execute\n" +msgstr "Prüfen von »%s« fehlgeschlagen: kann nicht ausgeführt werden\n" + +#: exec.c:449 +#, c-format +msgid "check for \"%s\" failed: incorrect version: found \"%s\", expected \"%s\"\n" +msgstr "Prüfen von »%s« fehlgeschlagen: falsche Version: gefunden »%s«, erwartet »%s«\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Klonen von Relation »%s.%s« (»%s« nach »%s«): %s\n" + +#: file.c:50 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "Fehler beim Klonen von Relation »%s.%s«: konnte Datei »%s« nicht öffnen: %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "Fehler beim Klonen von Relation »%s.%s«: konnte Datei »%s« nicht erzeugen: %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht öffnen: %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht erzeugen: %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht lesen: %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht schreiben: %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s« (»%s« nach »%s«): %s\n" + +#: file.c:151 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Erzeugen einer Verknüpfung für Relation »%s.%s« (»%s« nach »%s«): %s\n" + +#: file.c:194 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte »stat« für Datei »%s« nicht ausführen: %s\n" + +#: file.c:226 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: unvollständige Seite gefunden in Datei »%s«\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "konnte Datei nicht vom alten in das neue Datenverzeichnis klonen: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "konnte Datei »%s« nicht erstellen: %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "Klonen von Dateien wird auf dieser Plattform nicht unterstützt\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"konnte Hard-Link-Verknüpfung zwischen altem und neuen Datenverzeichnis nicht erzeugen: %s\n" +"Im Link-Modus müssen das alte und das neue Datenverzeichnis im selben Dateisystem liegen.\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"Der alte Cluster hat eine Funktion »plpython_call_handler« definiert\n" +"im Schema »public«, die eine Duplikat der im Schema »pg_catalog«\n" +"definierten ist. Sie können das bestätigen, indem Sie dies in psql\n" +"ausführen:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"Die Version im Schema »public« wurde von einer Installation von\n" +"plpython vor Version 8.1 erzeugt und muss entfernt werden, damit\n" +"pg_upgrade fortsetzen kann, weil sie auf die mittlerweile obsolete\n" +"Shared-Object-Datei »plpython« verweist. Sie können die Version dieser\n" +"Funktion im Schema »public« entfernen, indem Sie den Befehl\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in jeder betroffenen Datenbank ausführen:\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Entfernen Sie die problematischen Funktionen aus dem alten Cluster um fortzufahren.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Prüfe das Vorhandensein benötigter Bibliotheken" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "konnte Bibliothek »%s« nicht laden: %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "In Datenbank: %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation verweist auf ladbare Bibliotheken, die in der neuen\n" +"Installation fehlen. Sie können diese Bibliotheken zur neuen\n" +"Installation hinzufügen oder die Funktionen in der alten Installation\n" +"entfernen. Eine Liste der problematischen Bibliotheken ist in der\n" +"Datei:\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Relationsnamen für OID %u in Datenbank »%s« stimmen nicht überein: alten Name »%s.%s«, neuer Name »%s.%s«\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Alte und neue Tabellen in Datenbank »%s« konnten nicht gepaart werden\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr ", ein Index für »%s.%s«" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr ", ein Index für OID %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr ", eine TOAST-Tabelle für »%s.%s«" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr ", eine TOAST-Tabelle für OID %u" + +#: info.c:274 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "Keine Übereinstimmung gefunden im alten Cluster für neue Relation mit OID %u in Datenbank »%s«: %s\n" + +#: info.c:277 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "Keine Übereinstimmung gefunden im neuen Cluster für alte Relation mit OID %u in Datenbank »%s«: %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "Paarungen für Datenbank »%s«:\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u nach %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"Quelldatenbanken:\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"Zieldatenbanken:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "Datenbank: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: kann nicht als root ausgeführt werden\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "ungültige alte Portnummer\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "ungültige neue Portnummer\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Ausführung im Verbose-Modus\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "die Programmdateien des alten Clusters liegen" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "die Programmdateien des neuen Clusters liegen" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "die Daten das alten Clusters liegen" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "die Daten des neuen Clusters liegen" + +#: option.c:259 +msgid "sockets will be created" +msgstr "die Sockets erzeugt werden sollen" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln\n" + +#: option.c:279 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "auf Windows kann pg_upgrade nicht von innerhalb des Cluster-Datenverzeichnisses ausgeführt werden\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade aktualisiert einen PostgreSQL-Cluster auf eine neue Hauptversion.\n" +"\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [OPTION]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "Optionen:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINVERZ Programmverzeichnis des alten Clusters\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=BINVERZ Programmverzeichnis des neuen Clusters\n" +" (Standard: gleiches Verzeichnis wie pg_upgrade)\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check nur Cluster prüfen, keine Daten ändern\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATENVERZ Datenverzeichnis des alten Clusters\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATENVERZ Datenverzeichnis des neuen Clusters\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs=NUM number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs=NUM Anzahl paralleler Prozesse oder Threads\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link Dateien in den neuen Cluster verknüpfen statt kopieren\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPTIONEN Serveroptionen für den alten Cluster\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPTIONEN Serveroptionen für den neuen Cluster\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT Portnummer für den alten Cluster (Standard: %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT Portnummer für den neuen Cluster (Standard: %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain SQL- und Logdateien bei Erfolg aufheben\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" +msgstr " -s, --socketdir=VERZ Verzeichnis für Socket (Standard: aktuelles Verz.)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NAME Cluster-Superuser (Standard: »%s«)\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose »Verbose«-Modus einschalten\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " --clone Dateien in den neuen Cluster klonen statt kopieren\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Vor dem Aufruf von pg_upgrade müssen Sie:\n" +" den neuen Datenbankcluster anlegen (mit der neuen Version von initdb)\n" +" den Postmaster für den alten Cluster anhalten\n" +" den Postmaster für den neuen Cluster anhalten\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"Beim Aufruf von pg_upgrade müssen die folgenden Informationen angegeben werden:\n" +" das Datenverzeichnis des alten Clusters (-d DATENVERZ)\n" +" das Datenverzeichnis des neuen Clusters (-D DATENVERZ)\n" +" das »bin«-Verzeichnis der alten Version (-b BINVERZ)\n" +" das »bin«-Verzeichnis der neuen Version (-B BINVERZ)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Zum Beispiel:\n" +" pg_upgrade -d alterCluster/data -D neuerCluster/data -b alterCluster/bin -B neuerCluster/bin\n" +"oder\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=alterCluster/data\n" +" $ export PGDATANEW=neuerCluster/data\n" +" $ export PGBINOLD=alterCluster/bin\n" +" $ export PGBINNEW=neuerCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=alterCluster/data\n" +" C:\\> set PGDATANEW=neuerCluster/data\n" +" C:\\> set PGBINOLD=alterCluster/bin\n" +" C:\\> set PGBINNEW=neuerCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Sie müssen das Verzeichnis angeben, wo %s.\n" +"Bitte verwenden Sie die Kommandzeilenoption %s oder die Umgebungsvariable %s.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Suche das tatsächliche Datenverzeichnis des alten Clusters" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Suche das tatsächliche Datenverzeichnis des neuen Clusters" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "konnte Datenverzeichnis mit %s nicht ermitteln: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "konnte Zeile %d aus Datei »%s« nicht lesen: %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "vom Benutzer angegebene Portnummer %hu wurde auf %hu korrigiert\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "konnte Arbeitsprozess nicht erzeugen: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "konnte Arbeits-Thread nicht erzeugen: %s\n" + +#: parallel.c:300 +#, c-format +msgid "%s() failed: %s\n" +msgstr "%s() fehlgeschlagen: %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "Kindprozess wurde abnormal beendet: Status %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "Kindprozess wurde abnormal beendet: %s\n" + +#: pg_upgrade.c:107 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %s\n" + +#: pg_upgrade.c:122 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Führe Upgrade durch\n" +"-------------------\n" + +#: pg_upgrade.c:165 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Setze nächste OID im neuen Cluster" + +#: pg_upgrade.c:172 +#, c-format +msgid "Sync data directory to disk" +msgstr "Synchronisiere Datenverzeichnis auf Festplatte" + +#: pg_upgrade.c:183 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Upgrade abgeschlossen\n" +"---------------------\n" + +#: pg_upgrade.c:216 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: konnte eigene Programmdatei nicht finden\n" + +#: pg_upgrade.c:242 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Es läuft scheinbar ein Postmaster für den alten Cluster.\n" +"Bitte beenden Sie diesen Postmaster und versuchen Sie es erneut.\n" + +#: pg_upgrade.c:255 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Es läuft scheinbar ein Postmaster für den neuen Cluster.\n" +"Bitte beenden Sie diesen Postmaster und versuchen Sie es erneut.\n" + +#: pg_upgrade.c:269 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analysiere alle Zeilen im neuen Cluster" + +#: pg_upgrade.c:282 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Friere alle Zeilen im neuen Cluster ein" + +#: pg_upgrade.c:302 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Stelle globale Objekte im neuen Cluster wieder her" + +#: pg_upgrade.c:317 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Stelle Datenbankschemas im neuen Cluster wieder her\n" + +#: pg_upgrade.c:421 +#, c-format +msgid "Deleting files from new %s" +msgstr "Lösche Dateien aus neuem %s" + +#: pg_upgrade.c:425 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "konnte Verzeichnis »%s« nicht löschen\n" + +#: pg_upgrade.c:444 +#, c-format +msgid "Copying old %s to new server" +msgstr "Kopiere altes %s zum neuen Server" + +#: pg_upgrade.c:471 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Setze nächste Transaktions-ID und -epoche im neuen Cluster" + +#: pg_upgrade.c:501 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Setze nächste Multixact-ID und nächstes Offset im neuen Cluster" + +#: pg_upgrade.c:525 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Setze älteste Multixact-ID im neuen Cluster" + +#: pg_upgrade.c:545 +#, c-format +msgid "Resetting WAL archives" +msgstr "Setze WAL-Archive zurück" + +#: pg_upgrade.c:588 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Setze frozenxid und minmxid im neuen Cluster" + +#: pg_upgrade.c:590 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Setze minmxid im neuen Cluster" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Klonen Benutzertabellendateien\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "Kopiere Benutzertabellendateien\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "Verknüpfe Benutzertabellendateien\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "alte Datenbank »%s« nicht im neuen Cluster gefunden\n" + +#: relfilenode.c:230 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Prüfen auf Existenz der Datei für »%s.%s« (»%s« nach »%s«): %s\n" + +#: relfilenode.c:248 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "konvertiere »%s« nach »%s«\n" + +#: relfilenode.c:256 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "klone »%s« nach »%s«\n" + +#: relfilenode.c:261 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "kopiere »%s« nach »%s«\n" + +#: relfilenode.c:266 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "verknüpfe »%s« nach »%s«\n" + +#: server.c:38 server.c:142 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "Fehlgeschlagen, Programm wird beendet\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "führe aus: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL-Befehl fehlgeschlagen\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "konnte Versionsdatei »%s« nicht öffnen: %m\n" + +#: server.c:172 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "konnte Versionsdatei »%s« nicht interpretieren\n" + +#: server.c:298 +#, c-format +msgid "" +"\n" +"%s" +msgstr "" +"\n" +"%s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"konnte nicht mit dem Postmaster für den alten Cluster verbinden, gestartet mit dem Befehl:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"konnte nicht mit dem Postmaster für den neuen Cluster verbinden, gestartet mit dem Befehl:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl konnte den Quellserver nicht starten, oder Verbindung fehlgeschlagen\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl konnte den Zielserver nicht starten, oder Verbindung fehlgeschlagen\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "libpq-Umgebungsvariable %s hat einen nicht lokalen Serverwert: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"Kann nicht auf gleiche Systemkatalogversion aktualisieren, wenn\n" +"Tablespaces verwendet werden.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "Tablespace-Verzeichnis »%s« existiert nicht\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "konnte »stat« für Tablespace-Verzeichnis »%s« nicht ausführen: %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "Tablespace-Pfad »%s« ist kein Verzeichnis\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "Prüfe auf Large Objects" + +#: version.c:77 version.c:419 +#, c-format +msgid "warning" +msgstr "Warnung" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Large Objects. Die neue Datenbank hat eine\n" +"zusätzliche Tabelle mit den Zugriffsrechten für Large Objects. Nach\n" +"dem Upgrade wird Ihnen ein Befehl gegeben werden, mit dem die Tabelle\n" +"pg_largeobject_metadata mit den Standardrechten gefüllt wird.\n" +"\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Large Objects. Die neue Datenbank hat eine\n" +"zusätzliche Tabelle mit den Zugriffsrechten für Large Objects, sodass\n" +"Standardrechte für alle Large Objects gesetzt werden müssen. Die Datei\n" +" %s\n" +"kann mit psql als Datenbank-Superuser ausgeführt werden, um die\n" +"Standardrechte zu setzen.\n" +"\n" + +#: version.c:272 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Prüfe auf inkompatiblen Datentyp »line«" + +#: version.c:279 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables.\n" +"This data type changed its internal and input/output format\n" +"between your old and new versions so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält den Datentyp »line« in Benutzertabellen. Das\n" +"interne Format und das Eingabe-/Ausgabeformat dieses Datentyps wurden\n" +"zwischen Ihrem alten und neuen Cluster geändert und daher kann dieser\n" +"Cluster gegenwärtig nicht aktualisiert werden. Sie können die\n" +"Problemspalten löschen und das Upgrade neu starten. Eine Liste der\n" +"Problemspalten ist in der Datei:\n" +" %s\n" +"\n" + +#: version.c:310 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Prüfe auf ungültige Benutzerspalten mit Typ »unknown«" + +#: version.c:317 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables.\n" +"This data type is no longer allowed in tables, so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält den Datentyp »unknown« in\n" +"Benutzertabellen. Dieser Datentyp ist nicht mehr in Tabellen erlaubt\n" +"und daher kann dieser Cluster gegenwärtig nicht aktualisiert\n" +"werden. Sie können die Problemspalten löschen und das Upgrade neu\n" +"starten. Eine Liste der Problemspalten ist in der Datei:\n" +" %s\n" +"\n" + +#: version.c:341 +#, c-format +msgid "Checking for hash indexes" +msgstr "Prüfe auf Hash-Indexe" + +#: version.c:421 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Hash-Indexe. Diese Indexe haben\n" +"unterschiedliche interne Formate im alten und neuen Cluster und müssen\n" +"daher mit dem Befehl REINDEX reindiziert werden. Nach dem Upgrade\n" +"werden Sie Anweisungen zum REINDEX erhalten.\n" +"\n" + +#: version.c:427 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Hash-Indexe. Diese Indexe haben\n" +"unterschiedliche interne Formate im alten und neuen Cluster und müssen\n" +"daher mit dem Befehl REINDEX reindiziert werden. Die Datei\n" +" %s\n" +"kann mit psql als Datenbank-Superuser ausgeführt werden, um alle\n" +"ungültigen Indexe neu zu erzeugen. Bis dahin werden diese Indexe nicht\n" +"verwendet werden.\n" +"\n" + +#: version.c:453 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "Prüfe auf ungültige Benutzerspalten mit Typ »sql_identifier«" + +#: version.c:461 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables.\n" +"The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält den Datentyp »sql_identifier« in\n" +"Benutzertabellen. Das Speicherformat dieses Datentyps wurde geändert\n" +"und daher kann dieser Cluster gegenwärtig nicht aktualisiert\n" +"werden. Sie können die Problemspalten löschen und das Upgrade neu\n" +"starten. Eine Liste der Problemspalten ist in der Datei: %s\n" +"\n" diff --git a/src/bin/pg_upgrade/po/es.po b/src/bin/pg_upgrade/po/es.po new file mode 100644 index 000000000000..8525e77810f0 --- /dev/null +++ b/src/bin/pg_upgrade/po/es.po @@ -0,0 +1,1897 @@ +# spanish message translation file for pg_upgrade +# +# Copyright (c) 2017-2019, PostgreSQL Global Development Group +# +# This file is distributed under the same license as the PostgreSQL package. +# Álvaro Herrera , 2017. +# Carlos Chapi , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:47+0000\n" +"PO-Revision-Date: 2021-05-24 16:35-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.3\n" + +#: check.c:70 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Verificando Consistencia en Vivo en el Servidor Antiguo\n" +"-------------------------------------------------------\n" + +#: check.c:76 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Verificando Consistencia\n" +"------------------------\n" + +#: check.c:213 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Los clústers son compatibles*\n" + +#: check.c:219 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Si pg_upgrade falla a partir de este punto, deberá re-ejecutar initdb\n" +"en el clúster nuevo antes de continuar.\n" + +#: check.c:262 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade.\n" +"Once you start the new server, consider running:\n" +" %s/vacuumdb %s--all --analyze-in-stages\n" +"\n" +msgstr "" +"Las estadísticas para el optimizador no son transferidas por pg_upgrade.\n" +"Una vez que inicie el servidor nuevo, considere ejecutar:\n" +" %s/vacuumdb %s--all --analyze-in-stages\n" +"\n" + +#: check.c:268 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"Ejecutando este script se borrarán los archivos de datos del servidor antiguo:\n" +" %s\n" + +#: check.c:273 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"No se pudo crear un script para borrar los archivos de datos del servidor\n" +"antiguo, porque el directorio del clúster antiguo contiene tablespaces\n" +"o el directorio de datos del servidor nuevo. El contenido del servidor\n" +"antiguo debe ser borrado manualmente.\n" + +#: check.c:285 +#, c-format +msgid "Checking cluster versions" +msgstr "Verificando las versiones de los clústers" + +#: check.c:297 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Este programa sólo puede actualizar desde PostgreSQL versión 8.4 y posterior.\n" + +#: check.c:301 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Este programa sólo puede actualizar a PostgreSQL versión %s.\n" + +#: check.c:310 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Este programa no puede usarse para volver a versiones anteriores de PostgreSQL.\n" + +#: check.c:315 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "" +"El directorio de datos antiguo y el directorio de binarios antiguo son de\n" +"versiones diferentes.\n" + +#: check.c:318 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "" +"El directorio de datos nuevo y el directorio de binarios nuevo son de\n" +"versiones diferentes.\n" + +#: check.c:335 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Al verificar un servidor antiguo anterior a 9.1, debe especificar el port de éste.\n" + +#: check.c:339 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Al verificar servidores en caliente, los números de port antiguo y nuevo deben ser diferentes.\n" + +#: check.c:354 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "las codificaciones de la base de datos «%s» no coinciden: antigua «%s», nueva «%s»\n" + +#: check.c:359 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "valores lc_collate de la base de datos «%s» no coinciden: antigua «%s», nueva «%s»\n" + +#: check.c:362 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "valores lc_ctype de la base de datos «%s» no coinciden: antigua «%s», nueva «%s»\n" + +#: check.c:435 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "La base de datos «%s» del clúster nuevo no está vacía: se encontró la relación «%s.%s»\n" + +#: check.c:492 +#, c-format +msgid "Checking for new cluster tablespace directories" +msgstr "Verificando los directorios de tablespaces para el nuevo clúster" + +#: check.c:503 +#, c-format +msgid "new cluster tablespace directory already exists: \"%s\"\n" +msgstr "directorio de tablespace para el nuevo clúster ya existe: «%s»\n" + +#: check.c:536 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"ADVERTENCIA: el directorio de datos nuevo no debería estar dentro del directorio antiguo,\n" +"por ej. %s\n" + +#: check.c:560 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"ADVERTENCIA: las ubicaciones de tablespaces definidos por el usuario\n" +"no deberían estar dentro del directorio de datos,\n" +"por ej. %s\n" + +#: check.c:570 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Creando un script para borrar el clúster antiguo" + +#: check.c:573 check.c:837 check.c:935 check.c:1014 check.c:1276 file.c:336 +#: function.c:240 option.c:497 version.c:54 version.c:204 version.c:376 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "no se pudo abrir el archivo «%s»: %s\n" + +#: check.c:629 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "no se pudo agregar permisos de ejecución al archivo «%s»: %s\n" + +#: check.c:649 +#, c-format +msgid "Checking database user is the install user" +msgstr "Verificando que el usuario de base de datos es el usuario de instalación" + +#: check.c:665 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "el usuario de base de datos «%s» no es el usuario de instalación\n" + +#: check.c:676 +#, c-format +msgid "could not determine the number of users\n" +msgstr "no se pudo determinar el número de usuarios\n" + +#: check.c:684 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Sólo el usuario de instalación puede estar definido en el nuevo clúster.\n" + +#: check.c:704 +#, c-format +msgid "Checking database connection settings" +msgstr "Verificando los parámetros de conexión de bases de datos" + +#: check.c:726 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 no debe permitir conexiones, es decir su pg_database.datallowconn debe ser «false»\n" + +#: check.c:736 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Todas las bases de datos no-template0 deben permitir conexiones, es decir su pg_database.datallowconn debe ser «true»\n" + +#: check.c:761 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Verificando transacciones preparadas" + +#: check.c:770 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "El clúster de origen contiene transacciones preparadas\n" + +#: check.c:772 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "El clúster de destino contiene transacciones preparadas\n" + +#: check.c:798 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Verificando contrib/isn con discordancia en mecanismo de paso de bigint" + +#: check.c:859 check.c:960 check.c:1036 check.c:1093 check.c:1152 check.c:1181 +#: check.c:1299 function.c:262 version.c:278 version.c:316 version.c:460 +#, c-format +msgid "fatal\n" +msgstr "fatal\n" + +#: check.c:860 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene funciones de «contrib/isn» que usan el tip de dato\n" +"bigint. Sus clústers nuevo y antiguo pasar el tipo bigint de distinta forma,\n" +"por lo que este clúster no puede ser actualizado.\n" +"Puede hacer un volcado (dump) de las bases de datos que usan «contrib/isn»,\n" +"eliminarlas, hacer el upgrade, y luego restaurarlas.\n" +"Un listado de funciones problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: check.c:883 +#, c-format +msgid "Checking for user-defined postfix operators" +msgstr "Verificando operadores postfix definidos por el usuario" + +#: check.c:961 +#, c-format +msgid "" +"Your installation contains user-defined postfix operators, which are not\n" +"supported anymore. Consider dropping the postfix operators and replacing\n" +"them with prefix operators or function calls.\n" +"A list of user-defined postfix operators is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene operadores postfix definidos por el usuario, los\n" +"cuales ya no están soportados. Considere eliminar los operadores postfix\n" +"y reemplazarlos con operadores de prefijo o llamadas a funciones.\n" +"Una lista de operadores postfix definidos por el usuario aparece en el archivo:\n" +" %s\n" +"\n" + +#: check.c:982 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Verificando tablas WITH OIDS" + +#: check.c:1037 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene tablas declaradas WITH OIDS, que ya no está\n" +"soportado. Considere eliminar la columna oid usando\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Una lista de tablas con este problema aparece en el archivo:\n" +" %s\n" +"\n" + +#: check.c:1065 +#, c-format +msgid "Checking for system-defined composite types in user tables" +msgstr "Verificando tipos compuestos definidos por el sistema en tablas de usuario" + +#: check.c:1094 +#, c-format +msgid "" +"Your installation contains system-defined composite type(s) in user tables.\n" +"These type OIDs are not stable across PostgreSQL versions,\n" +"so this cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene uno o varios tipos compuestos definidos por el sistema en\n" +"tablas de usuario. Los OIDs de estos tipos no son estables entre diferentes\n" +"versiones de PostgreSQL, por lo que este clúster no puede ser actualizado.\n" +"Puede eliminar las columnas problemáticas y reiniciar la actualización.\n" +"Un listado de las columnas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: check.c:1122 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Verificando tipos de datos reg* en datos de usuario" + +#: check.c:1153 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene uno de los tipos reg* en tablas de usuario. Estos tipos\n" +"de dato hacen referencia a OIDs de sistema que no son preservados por pg_upgrade,\n" +"por lo que este clúster no puede ser actualizado.\n" +"Puede eliminar las columnas problemáticas y reiniciar la actualización.\n" +"Un listado de las columnas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: check.c:1175 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Verificando datos de usuario en tipo «jsonb» incompatible" + +#: check.c:1182 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene el tipo «jsonb» en tablas de usuario.\n" +"El formato interno de «jsonb» cambió durante 9.4 beta,\n" +"por lo que este clúster no puede ser actualizado.\n" +"Puede eliminar las columnas problemáticas y reiniciar la actualización.\n" +"Un listado de las columnas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: check.c:1204 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Verificando roles que empiecen con «pg_»" + +#: check.c:1214 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "El clúster de origen contiene roles que empiezan con «pg_»\n" + +#: check.c:1216 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "El clúster de destino contiene roles que empiezan con «pg_»\n" + +#: check.c:1237 +#, c-format +msgid "Checking for user-defined encoding conversions" +msgstr "Verificando conversiones de codificación definidas por el usuario" + +#: check.c:1300 +#, c-format +msgid "" +"Your installation contains user-defined encoding conversions.\n" +"The conversion function parameters changed in PostgreSQL version 14\n" +"so this cluster cannot currently be upgraded. You can remove the\n" +"encoding conversions in the old cluster and restart the upgrade.\n" +"A list of user-defined encoding conversions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene conversiones de codificación definidas por el usuario.\n" +"Los parámetros de la función de conversión cambiaron en PostgreSQL 14\n" +"por lo que este clúster no puede ser actualizado. Puede eliminar\n" +"las conversiones de codificación en el clúster antiguo y reiniciar la actualización.\n" +"Un listado de las conversiones de codificación definidas por el usuario está en el archivo:\n" +" %s\n" +"\n" + +#: check.c:1327 +#, c-format +msgid "failed to get the current locale\n" +msgstr "no se pudo obtener el «locale» actual\n" + +#: check.c:1336 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "no se pudo obtener el nombre del «locale» para «%s»\n" + +#: check.c:1342 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "no se pudo restaurar el locale antiguo «%s»\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "no se pudo obtener datos de control usando %s: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: problema de estado del clúster\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "El clúster de origen fue apagado mientras estaba en modo de recuperación. Para actualizarlo, use «rsync» como está documentado, o apáguelo siendo primario.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "El clúster de destino fue apagado mientras estaba en modo de recuperación. Para actualizarlo, use «rsync» como está documentado, o apáguelo siendo primario.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "El clúster de origen no fue apagado limpiamente.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "El clúster de destino no fue apagado limpiamente.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Al clúster de origen le falta información de estado:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Al cluster de destino le falta información de estado:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:335 pg_upgrade.c:371 +#: relfilenode.c:243 server.c:33 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: problema en pg_resetwal\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: problema de extracción de controldata\n" + +#: controldata.c:560 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Al clúster de origen le falta información de control requerida:\n" + +#: controldata.c:563 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Al clúster de destino le falta información de control requerida:\n" + +#: controldata.c:566 +#, c-format +msgid " checkpoint next XID\n" +msgstr " siguiente XID del último checkpoint\n" + +#: controldata.c:569 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " siguiente OID del último checkpoint\n" + +#: controldata.c:572 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " siguiente MultiXactId del último checkpoint\n" + +#: controldata.c:576 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " MultiXactId más antiguo del último checkpoint\n" + +#: controldata.c:579 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " siguiente MultiXactOffset del siguiente checkpoint\n" + +#: controldata.c:582 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " primer segmento de WAL después del reinicio\n" + +#: controldata.c:585 +#, c-format +msgid " float8 argument passing method\n" +msgstr " método de paso de argumentos float8\n" + +#: controldata.c:588 +#, c-format +msgid " maximum alignment\n" +msgstr " alineamiento máximo\n" + +#: controldata.c:591 +#, c-format +msgid " block size\n" +msgstr " tamaño de bloques\n" + +#: controldata.c:594 +#, c-format +msgid " large relation segment size\n" +msgstr " tamaño de segmento de relación grande\n" + +#: controldata.c:597 +#, c-format +msgid " WAL block size\n" +msgstr " tamaño de bloque de WAL\n" + +#: controldata.c:600 +#, c-format +msgid " WAL segment size\n" +msgstr " tamaño de segmento de WAL\n" + +#: controldata.c:603 +#, c-format +msgid " maximum identifier length\n" +msgstr " máximo largo de identificadores\n" + +#: controldata.c:606 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " máximo número de columnas indexadas\n" + +#: controldata.c:609 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " tamaño máximo de trozos TOAST\n" + +#: controldata.c:613 +#, c-format +msgid " large-object chunk size\n" +msgstr " tamaño de trozos de objetos grandes\n" + +#: controldata.c:616 +#, c-format +msgid " dates/times are integers?\n" +msgstr " fechas/horas son enteros?\n" + +#: controldata.c:620 +#, c-format +msgid " data checksum version\n" +msgstr " versión del checksum de datos\n" + +#: controldata.c:622 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "No se puede continuar sin la información de control requerida. Terminando\n" + +#: controldata.c:637 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"Alineamientos de pg_controldata antiguo y nuevo no son válidos o no coinciden\n" +"Seguramente un clúster es 32-bit y el otro es 64-bit\n" + +#: controldata.c:641 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "Los tamaños de bloque antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:644 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "El tamaño máximo de segmento de relación antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:647 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "El tamaño de bloques de WAL antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "El tamaño de segmentos de WAL antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "Los máximos largos de identificador antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:656 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "La cantidad máxima de columnas indexadas antigua y nueva no son válidos o no coinciden\n" + +#: controldata.c:659 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "Los máximos de trozos TOAST antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:664 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "Los tamaños de trozos de objetos grandes antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:667 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "Los tipos de almacenamiento de fecha/hora antiguo y nuevo no coinciden\n" + +#: controldata.c:680 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "El clúster antiguo no usa checksums de datos pero el nuevo sí\n" + +#: controldata.c:683 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "El clúster antiguo usa checksums de datos pero el nuevo no\n" + +#: controldata.c:685 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "Las versiones de checksum de datos antigua y nueva no coinciden\n" + +#: controldata.c:696 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Agregando el sufijo «.old» a global/pg_control" + +#: controldata.c:701 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "No se pudo renombrar %s a %s.\n" + +#: controldata.c:704 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Si desea iniciar el clúster antiguo, necesitará eliminar el sufijo\n" +"«.old» de %s/global/pg_control.old.\n" +"Puesto que se usó el modo «link», el clúster antiguo no puede usarse\n" +"en forma segura después de que el clúster nuevo haya sido iniciado.\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "Creando el volcado de objetos globales" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Creando el volcado de esquemas de bases de datos\n" + +#: exec.c:45 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "no se pudo obtener datos de versión de pg_ctl usando %s: %s\n" + +#: exec.c:51 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "no se pudo obtener la salida de versión de pg_ctl de %s\n" + +#: exec.c:105 exec.c:109 +#, c-format +msgid "command too long\n" +msgstr "orden demasiado larga\n" + +#: exec.c:111 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:150 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "no se pudo abrir el archivo de registro «%s»: %m\n" + +#: exec.c:179 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*falló*" + +#: exec.c:182 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Hubo problemas ejecutando «%s»\n" + +#: exec.c:185 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Consulte las últimas línea de «%s» o «%s» para\n" +"saber la causa probable de la falla.\n" + +#: exec.c:190 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Consulte las últimas líneas de «%s» para saber\n" +"la causa probable de la falla.\n" + +#: exec.c:205 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "no se pudo escribir al archivo de log «%s»\n" + +#: exec.c:231 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "no se pudo abrir el archivo «%s» para lectura: %s\n" + +#: exec.c:258 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Debe tener privilegios de lectura y escritura en el directorio actual.\n" + +#: exec.c:311 exec.c:377 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "la comprobación de «%s» falló: %s\n" + +#: exec.c:314 exec.c:380 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "«%s» no es un directorio\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "La comprobación de «%s» falló: no es un archivo regular\n" + +#: exec.c:433 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "La comprobación de «%s» falló: no se puede ejecutar (permiso denegado)\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: cannot execute\n" +msgstr "La comprobación de «%s» falló: no se puede ejecutar\n" + +#: exec.c:449 +#, c-format +msgid "check for \"%s\" failed: incorrect version: found \"%s\", expected \"%s\"\n" +msgstr "La comprobación de «%s» falló: versión incorrecta: se encontró «%s», se esperaba «%s»\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se clonaba la relación «%s.%s» («%s» a «%s»): %s\n" + +#: file.c:50 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "error mientras se clonaba la relación «%s.%s»: no se pudo abrir el archivo «%s»: %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "error mientras se clonaba la relación «%s.%s»: no se pudo crear el archivo «%s»: %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo leer el archivo «%s»: %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo crear el archivo «%s»: %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo leer el archivo «%s»: %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo escribir el archivo «%s»: %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se copiaba la relación «%s.%s» («%s» a «%s»): %s\n" + +#: file.c:151 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se creaba el link para la relación «%s.%s» («%s» a «%s»): %s\n" + +#: file.c:194 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo hacer stat a «%s»: %s\n" + +#: file.c:226 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "error mientras se copiaba la relación «%s.%s»: se encontró una página parcial en el archivo «%s»\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "no se pudo clonar el archivo entre los directorios viejo y nuevo: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "no se pudo crear el archivo «%s»: %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "el clonado de archivos no está soportado en esta plataforma\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"No se pudo crear un link duro entre los directorios de datos nuevo y antiguo: %s\n" +"En modo link los directorios de dato nuevo y antiguo deben estar en el mismo sistema de archivos.\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"El clúster antiguo tiene la función «plpython_call_handler» definida\n" +"en el esquema «public» que es un duplicado de la que está definida en\n" +"el esquema «pg_catalog». Puede confirmar esto ejecutando lo siguiente\n" +"en psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"La versión del esquema «public» de esta función fue creada por una\n" +"instalación pre-8.1 de plpython, y debe eliminarse para que pg_upgrade\n" +"pueda completar puesto que hace referencia a un archivo objeto compartido\n" +"«plpython» ahora obsoleto.\n" +"Puede eliminar la versión del esquema «public» de esta función ejecutando\n" +"la siguiente orden:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"en cada base de datos afectada:\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Elimine las funciones problemáticas del clúster antiguo para continuar.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Verificando la presencia de las bibliotecas requeridas" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "no se pudo cargar la biblioteca «%s»: %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "En la base de datos: %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación hace referencia a bibliotecas que no están en la nueva\n" +"instalación. Puede agregar estar bibliotecas la instalación nueva, o\n" +"eliminar las funciones que las utilizan de la versión antigua. Un listado\n" +"de las bibliotecas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Los nombres de relación para OID %u en la base de datos «%s» no coinciden: nombre antiguo «%s.%s», nombre nuevo «%s.%s»\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "No hubo coincidencia en las tablas nueva y antigua en la base de datos «%s»\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " que es un índice en «%s.%s»" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " que es un índice en el OID %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " que es la tabla TOAST para «%s.%s»" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " que es la tabla TOAST para el OID %u" + +#: info.c:274 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "" +"No se encontró equivalente en el clúster antiguo para la relación con OID %u\n" +"en la base de datos «%s» en el clúster nuevo: %s\n" + +#: info.c:277 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "" +"No se encontró equivalente en el clúster nuevo para la relación con OID %u\n" +"en la base de datos «%s» en el clúster antiguo: %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "mapeos para la base de datos «%s»:\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u a %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"bases de datos de origen:\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"bases de datos de destino:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "Base de datos: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: no puede ejecutarse como root\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "número de puerto antiguo no válido\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "número de puerto nuevo no válido\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Ejecutando en modo verboso\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "residen los binarios del clúster antiguo" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "residen los binarios del clúster nuevo" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "residen los datos del clúster antiguo" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "residen los datos del clúster nuevo" + +#: option.c:259 +msgid "sockets will be created" +msgstr "se crearán los sockets" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "no se pudo identificar el directorio actual\n" + +#: option.c:279 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "" +"no se puede ejecutar pg_upgrade desde dentro del directorio de datos\n" +"del clúster nuevo en Windows\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "pg_upgrado actualiza un clúster PostgreSQL a una versión «mayor» diferente.\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [OPCIÓN]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "Opciones:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR directorio de ejecutables del clúster antiguo\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=BINDIR directorio de ejecutables del clúster nuevo\n" +" (por omisión el mismo directorio que pg_upgrade)\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check sólo verificar clústers, no cambiar datos\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR directorio de datos del clúster antiguo\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR directorio de datos del clúster nuevo\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs=NUM number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs=NUM máximo de procesos paralelos para restaurar\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link enlazar (link) archivos en vez de copiarlos\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPCIONES opciones a pasar al servidor antiguo\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPCIONES opciones a pasar al servidor nuevo\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PUERTO número de puerto del clúster antiguo (def. %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PUERTO número de puerto del clúster nuevo (def. %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain preservar archivos SQL y logs en caso de éxito\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" +msgstr " -s, --socketdir=DIR directorio de sockets a usar (omisión: dir. actual)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NOMBRE superusuario del clúster (def. «%s»)\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose activar registro interno verboso\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " --clone clonar los archivos en vez de copiarlos\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Antes de ejecutar pg_upgrade, debe:\n" +" crear el nuevo clúster de la base de datos (usando la nueva versión de initdb)\n" +" apagar el postmaster que atiende al clúster antiguo\n" +" apagar el postmaster que atiende al clúster nuevo\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"Cuando ejecute pg_ugpade, debe proveer la siguiente información:\n" +" el directorio de datos del clúster antiguo (-d DATADIR)\n" +" el directorio de datos del clúster nuevo (-D DATADIR)\n" +" el directorio «bin» para la versión antigua (-b BINDIR)\n" +" el directorio «bin» para la versión nueva (-B BINDIR)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Por ejemplo:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"o\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=clusterAntiguo/data\n" +" $ export PGDATANEW=clusterNuevo/data\n" +" $ export PGBINOLD=clusterAntiguo/bin\n" +" $ export PGBINNEW=clusterNuevo/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=clusterAntiguo/data\n" +" C:\\> set PGDATANEW=clusterNuevo/data\n" +" C:\\> set PGBINOLD=clusterAntiguo/bin\n" +" C:\\> set PGBINNEW=clusterNuevo/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Debe identificar el directorio donde %s.\n" +"Por favor use la opción %s o la variable de ambiente %s.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Buscando el directorio de datos real para el clúster de origen" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Buscando el directorio de datos real para el clúster de destino" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "no se pudo obtener el directorio de datos usando %s: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "no se pudo leer la línea %d del archivo «%s»: %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "número de port entregado por el usuario %hu corregido a %hu\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "no se pudo crear el proceso hijo: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "no se pudo crear el thread: %s\n" + +#: parallel.c:300 +#, c-format +msgid "%s() failed: %s\n" +msgstr "%s() falló: %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "el proceso hijo terminó anormalmente: estado %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "el thread terminó anormalmente: %s\n" + +#: pg_upgrade.c:107 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "no se pudo obtener los permisos del directorio «%s»: %s\n" + +#: pg_upgrade.c:122 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Llevando a cabo el Upgrade\n" +"--------------------------\n" + +#: pg_upgrade.c:165 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Seteando siguiente OID para el nuevo clúster" + +#: pg_upgrade.c:172 +#, c-format +msgid "Sync data directory to disk" +msgstr "Sincronizando directorio de datos a disco" + +#: pg_upgrade.c:183 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Actualización Completa\n" +"----------------------\n" + +#: pg_upgrade.c:216 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: no se pudo encontrar el ejecutable propio\n" + +#: pg_upgrade.c:242 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Parece haber un postmaster sirviendo el clúster antiguo.\n" +"Por favor detenga ese postmaster e inténtelo nuevamente.\n" + +#: pg_upgrade.c:255 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Parece haber un postmaster sirviendo el clúster nuevo.\n" +"Por favor detenga ese postmaster e inténtelo nuevamente.\n" + +#: pg_upgrade.c:269 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analizando todas las filas en el clúster nuevo" + +#: pg_upgrade.c:282 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Congelando todas las filas en el nuevo clúster" + +#: pg_upgrade.c:302 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Restaurando objetos globales en el nuevo clúster" + +#: pg_upgrade.c:317 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Restaurando esquemas de bases de datos en el clúster nuevo\n" + +#: pg_upgrade.c:421 +#, c-format +msgid "Deleting files from new %s" +msgstr "Eliminando archivos del nuevo %s" + +#: pg_upgrade.c:425 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "no se pudo eliminar directorio «%s»\n" + +#: pg_upgrade.c:444 +#, c-format +msgid "Copying old %s to new server" +msgstr "Copiando el %s antiguo al nuevo servidor" + +#: pg_upgrade.c:471 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Seteando el ID de transacción y «época» siguientes en el nuevo clúster" + +#: pg_upgrade.c:501 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Seteando el multixact ID y offset siguientes en el nuevo clúster" + +#: pg_upgrade.c:525 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Seteando el multixact ID más antiguo en el nuevo clúster" + +#: pg_upgrade.c:545 +#, c-format +msgid "Resetting WAL archives" +msgstr "Reseteando los archivos de WAL" + +#: pg_upgrade.c:588 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Seteando contadores frozenxid y minmxid en el clúster nuevo" + +#: pg_upgrade.c:590 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Seteando contador minmxid en el clúster nuevo" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Clonando archivos de relaciones de usuario\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "Copiando archivos de relaciones de usuario\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "Enlazando archivos de relaciones de usuario\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "la base de datos «%s» no se encontró en el clúster nuevo\n" + +#: relfilenode.c:230 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se comprobaba la existencia del archivo «%s.%s» («%s» a «%s»); %s\n" + +#: relfilenode.c:248 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "reescribiendo «%s» a «%s»\n" + +#: relfilenode.c:256 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "clonando «%s» a «%s»\n" + +#: relfilenode.c:261 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "copiando «%s» a «%s»\n" + +#: relfilenode.c:266 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "enlazando «%s» a «%s»\n" + +#: server.c:38 server.c:142 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "Falló, saliendo\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "ejecutando: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"Orden SQL falló\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "no se pudo abrir el archivo de versión «%s»: %m\n" + +#: server.c:172 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "no se pudo interpretar el archivo de versión «%s»\n" + +#: server.c:298 +#, c-format +msgid "" +"\n" +"%s" +msgstr "" +"\n" +"%s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"no se pudo conectar al postmaster de origen iniciado con la orden:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"no se pudo conectar al postmaster de destino iniciado con la orden:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl no pudo iniciar el servidor de origen, o la conexión falló\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl no pudo iniciar el servidor de destino, o la conexión falló\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "la variable de ambiente libpq %s tiene un valor de servidor no-local: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"No se puede actualizar desde el mismo número de versión del catálogo\n" +"cuando se están usando tablespaces.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "el directorio de tablespace «%s» no existe\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "no se pudo hace stat al directorio de tablespace «%s»: %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "la ruta de tablespace «%s» no es un directorio\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "éxito" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "Buscando objetos grandes" + +#: version.c:77 version.c:419 +#, c-format +msgid "warning" +msgstr "atención" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene objetos grandes. La base de datos nueva\n" +"tiene una tabla adicional de permisos de objetos grandes. Después de\n" +"actualizar, se le dará una instrucción para poblar la tabla\n" +"pg_largeobject_metadata con privilegios por omisión.\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene objetos grandes. La base de datos nueva tiene\n" +"una tabla adicional de permisos de objetos grandes, por lo que deben ser\n" +"definidos permisos por omisión para todos los objetos grandes. El archivo\n" +" %s\n" +"cuando se ejecute en psql con el superusuario de la base de datos\n" +"establecerá los privilegios por omisión.\n" + +#: version.c:272 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Verificando datos de usuario de tipo «line» incompatible" + +#: version.c:279 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables.\n" +"This data type changed its internal and input/output format\n" +"between your old and new versions so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene el tipo de dato «line» en tablas de usuario. Este\n" +"tipo de dato cambió su formato interno y de entrada/salida entre las\n" +"versiones de sus clústers antiguo y nuevo, por lo que este clúster no puede\n" +"actualmente ser actualizado. Puede eliminar las columnas problemáticas y\n" +"reiniciar la actualización. Un listado de las columnas problemáticas está\n" +"en el archivo:\n" +" %s\n" +"\n" + +#: version.c:310 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Verificando columnas de usuario del tipo no válido «unknown»" + +#: version.c:317 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables.\n" +"This data type is no longer allowed in tables, so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene el tipo «unknown» en tablas de usuario.\n" +"Este tipo ya no es permitido en tablas,\n" +"por lo que este clúster no puede ser actualizado. Puede\n" +"eliminar las columnas problemáticas y reiniciar la actualización.\n" +"Un listado de las columnas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: version.c:341 +#, c-format +msgid "Checking for hash indexes" +msgstr "Verificando índices hash" + +#: version.c:421 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene índices hash. Estos índices tienen formato interno\n" +"distinto entre su versión nueva y antigua, por lo que deben ser reindexados\n" +"con la orden REINDEX. Después de la actualización, se le entregarán\n" +"instrucciones de REINDEX.\n" +"\n" + +#: version.c:427 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene índices hash. Estos índices tienen formato interno\n" +"distinto entre su versión nueva y antigua, por lo que deben ser reindexados\n" +"con la orden REINDEX. El archivo\n" +" %s\n" +"cuando se ejecute en psql con el superusuario de la base de datos recreará\n" +"los índices no válidos; hasta entonces, ninguno de esos índices será usado.\n" +"\n" + +#: version.c:453 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "Verificando columnas de usuario del tipo «sql_identifier»" + +#: version.c:461 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables.\n" +"The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene el tipo de dato «sql_identifier» en tablas de usuario.\n" +"El formato en disco para este tipo de dato ha cambiado, por lo que\n" +"este clúster no puede ser actualizado.\n" +"Puede eliminar las columnas problemáticas y reiniciar la actualización\n" +"Un listado de las columnas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#~ msgid "" +#~ "\n" +#~ "connection to database failed: %s" +#~ msgstr "" +#~ "\n" +#~ "falló la conexión a la base de datos: %s" + +#~ msgid "connection to database failed: %s" +#~ msgstr "falló la conexión a la base de datos: %s" + +#~ msgid "waitpid() failed: %s\n" +#~ msgstr "waitpid() fallida: %s\n" + +#~ msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +#~ msgstr "La comprobación de «%s» falló: no se puede leer el archivo (permiso denegado)\n" + +#~ msgid "Creating script to analyze new cluster" +#~ msgstr "Creando un script para analizar el clúster nuevo" + +#~ msgid "" +#~ "Optimizer statistics and free space information are not transferred\n" +#~ "by pg_upgrade so, once you start the new server, consider running:\n" +#~ " %s\n" +#~ "\n" +#~ msgstr "" +#~ "Las estadísticas para el optimizador y la información de espacio libre\n" +#~ "no son transferidas por pg_upgrade, de manera que una vez que inicie\n" +#~ "el servidor nuevo considere ejecutar:\n" +#~ " %s\n" +#~ "\n" diff --git a/src/bin/pg_upgrade/po/fr.po b/src/bin/pg_upgrade/po/fr.po new file mode 100644 index 000000000000..54d8b76333e0 --- /dev/null +++ b/src/bin/pg_upgrade/po/fr.po @@ -0,0 +1,1941 @@ +# LANGUAGE message translation file for pg_upgrade +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-11 07:47+0000\n" +"PO-Revision-Date: 2021-05-11 10:39+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.3\n" + +#: check.c:70 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Exécution de tests de cohérence sur l'ancien serveur\n" +"----------------------------------------------------\n" + +#: check.c:76 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Exécution de tests de cohérence\n" +"-------------------------------\n" + +#: check.c:213 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Les instances sont compatibles*\n" + +#: check.c:219 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Si pg_upgrade échoue après cela, vous devez ré-exécuter initdb\n" +"sur la nouvelle instance avant de continuer.\n" + +#: check.c:262 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade.\n" +"Once you start the new server, consider running:\n" +" %s/vacuumdb %s--all --analyze-in-stages\n" +"\n" +msgstr "" +"Les statistiques de l'optimiseur ne sont pas transférées par pg_upgrade.\n" +"Une fois le nouveau serveur démarré, pensez à exécuter :\n" +" %s/vacuumdb %s--all --analyze-in-stages\n" +"\n" + +#: check.c:268 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"Exécuter ce script supprimera les fichiers de données de l'ancienne\n" +"instance :\n" +" %s\n" + +#: check.c:273 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"N'a pas pu créer un script pour supprimer les fichiers de données\n" +"de l'ancienne instance parce que les tablespaces définis par l'utilisateur\n" +"ou le répertoire de données de la nouvelle instance existent dans le répertoire\n" +"de l'ancienne instance. Le contenu de l'ancienne instance doit être supprimé\n" +"manuellement.\n" + +#: check.c:285 +#, c-format +msgid "Checking cluster versions" +msgstr "Vérification des versions des instances" + +#: check.c:297 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Cet outil peut seulement mettre à jour les versions 8.4 et ultérieures de PostgreSQL.\n" + +#: check.c:301 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Cet outil peut seulement mettre à jour vers la version %s de PostgreSQL.\n" + +#: check.c:310 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Cet outil ne peut pas être utilisé pour mettre à jour vers des versions majeures plus anciennes de PostgreSQL.\n" + +#: check.c:315 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Les répertoires des données de l'ancienne instance et des binaires sont de versions majeures différentes.\n" + +#: check.c:318 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Les répertoires des données de la nouvelle instance et des binaires sont de versions majeures différentes.\n" + +#: check.c:335 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Lors de la vérification d'un serveur antérieur à la 9.1, vous devez spécifier le numéro de port de l'ancien serveur.\n" + +#: check.c:339 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Lors de la vérification d'un serveur en production, l'ancien numéro de port doit être différent du nouveau.\n" + +#: check.c:354 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "les encodages de la base de données « %s » ne correspondent pas : ancien « %s », nouveau « %s »\n" + +#: check.c:359 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "les valeurs de lc_collate de la base de données « %s » ne correspondent pas : ancien « %s », nouveau « %s »\n" + +#: check.c:362 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "les valeurs de lc_ctype de la base de données « %s » ne correspondent pas : ancien « %s », nouveau « %s »\n" + +#: check.c:435 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "La nouvelle instance « %s » n'est pas vide : relation « %s.%s » trouvée\n" + +#: check.c:492 +#, c-format +msgid "Checking for new cluster tablespace directories" +msgstr "Vérification des répertoires de tablespace de la nouvelle instance" + +#: check.c:503 +#, c-format +msgid "new cluster tablespace directory already exists: \"%s\"\n" +msgstr "le répertoire du tablespace de la nouvelle instance existe déjà : « %s »\n" + +#: check.c:536 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"AVERTISSEMENT : le nouveau répertoire de données ne doit pas être à l'intérieur de l'ancien répertoire de données, %s\n" + +#: check.c:560 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"AVERTISSEMENT : les emplacements de tablespaces utilisateurs ne doivent pas être à l'intérieur du répertoire de données, %s\n" + +#: check.c:570 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Création du script pour supprimer l'ancienne instance" + +#: check.c:573 check.c:837 check.c:935 check.c:1014 check.c:1276 file.c:336 +#: function.c:240 option.c:497 version.c:54 version.c:204 version.c:376 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "n'a pas pu ouvrir le fichier « %s » : %s\n" + +#: check.c:629 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "n'a pas pu ajouter les droits d'exécution pour le fichier « %s » : %s\n" + +#: check.c:649 +#, c-format +msgid "Checking database user is the install user" +msgstr "Vérification que l'utilisateur de la base de données est l'utilisateur d'installation" + +#: check.c:665 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "l'utilisateur de la base de données « %s » n'est pas l'utilisateur d'installation\n" + +#: check.c:676 +#, c-format +msgid "could not determine the number of users\n" +msgstr "n'a pas pu déterminer le nombre d'utilisateurs\n" + +#: check.c:684 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Seul l'utilisateur d'installation peut être défini dans la nouvelle instance.\n" + +#: check.c:704 +#, c-format +msgid "Checking database connection settings" +msgstr "Vérification des paramètres de connexion de la base de données" + +#: check.c:726 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 ne doit pas autoriser les connexions, ie pg_database.datallowconn doit valoir false\n" + +#: check.c:736 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Toutes les bases de données, autre que template0, doivent autoriser les connexions, ie pg_database.datallowconn doit valoir true\n" + +#: check.c:761 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Vérification des transactions préparées" + +#: check.c:770 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "L'instance source contient des transactions préparées\n" + +#: check.c:772 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "L'instance cible contient des transactions préparées\n" + +#: check.c:798 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Vérification de contrib/isn avec une différence sur le passage des bigint" + +#: check.c:859 check.c:960 check.c:1036 check.c:1093 check.c:1152 check.c:1181 +#: check.c:1299 function.c:262 version.c:278 version.c:316 version.c:460 +#, c-format +msgid "fatal\n" +msgstr "fatal\n" + +#: check.c:860 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient les fonctions « contrib/isn » qui se basent sur le\n" +"type de données bigint. Vos ancienne et nouvelle instances passent les valeurs\n" +"bigint différemment, donc cette instance ne peut pas être mise à jour\n" +"actuellement. Vous pouvez mettre à jour manuellement vos bases de données\n" +"qui utilisent « contrib/isn », les supprimer de l'ancienne instance,\n" +"relancer la mise à jour, puis les restaurer. Une liste des fonctions\n" +"problématiques est disponible\n" +"dans le fichier :\n" +" %s\n" +"\n" + +#: check.c:883 +#, c-format +msgid "Checking for user-defined postfix operators" +msgstr "Vérification des opérateurs postfixes définis par les utilisateurs" + +#: check.c:961 +#, c-format +msgid "" +"Your installation contains user-defined postfix operators, which are not\n" +"supported anymore. Consider dropping the postfix operators and replacing\n" +"them with prefix operators or function calls.\n" +"A list of user-defined postfix operators is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient des opérateurs postfixes définis par des utilisateurs,\n" +"qui ne sont plus supportés. Supprimez les opérateurs postfixes et remplacez-les\n" +"avec des opérateurs préfixes ou des appels de fonctions.\n" +"Une liste des opérateurs postfixes définis par les utilisateurs se trouve dans le fichier :\n" +" %s\n" + +#: check.c:982 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Vérification des tables WITH OIDS" + +#: check.c:1037 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient des tables déclarées avec WITH OIDS, ce qui n'est plus supporté.\n" +"Pensez à supprimer la colonne oid en utilisant\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Une liste des tables ayant ce problème se trouve dans le fichier :\n" +" %s\n" + +#: check.c:1065 +#, c-format +msgid "Checking for system-defined composite types in user tables" +msgstr "Vérification des types composites définis par le système dans les tables utilisateurs" + +#: check.c:1094 +#, c-format +msgid "" +"Your installation contains system-defined composite type(s) in user tables.\n" +"These type OIDs are not stable across PostgreSQL versions,\n" +"so this cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient des types composites définis par le système dans vos tables\n" +"utilisateurs. Les OID de ces types ne sont pas stables entre différentes versions majeures\n" +"de PostgreSQL, donc cette instance ne peut pas être mise à jour actuellement. Vous pouvez\n" +"supprimer les colonnes problématiques, puis relancer la mise à jour. Vous trouverez\n" +"une liste des colonnes problématiques dans le fichier :\n" +" %s\n" +"\n" + +#: check.c:1122 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Vérification des types de données reg* dans les tables utilisateurs" + +#: check.c:1153 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient un des types de données reg* dans vos tables\n" +"utilisateurs. Ces types de données référencent des OID système qui ne sont\n" +"pas préservés par pg_upgrade, donc cette instance ne peut pas être mise à\n" +"jour actuellement. Vous pouvez supprimer les colonnes problématiques et relancer\n" +"la mise à jour. Une liste des colonnes problématiques est disponible dans le\n" +"fichier :\n" +" %s\n" +"\n" + +#: check.c:1175 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Vérification des types de données « jsonb » incompatibles" + +#: check.c:1182 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient un type de données « jsonb » dans vos tables utilisateurs.\n" +"Le format interne de « jsonb » a changé lors du développement de la version 9.4 beta, donc\n" +"cette instance ne peut pas être mise à jour actuellement. Vous pouvez supprimer les\n" +"colonnes problématiques et relancer la mise à jour. Une liste des colonnes problématiques\n" +"est disponible dans le fichier :\n" +" %s\n" +"\n" + +#: check.c:1204 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Vérification des rôles commençant avec « pg_ »" + +#: check.c:1214 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "L'instance source contient des rôles commençant avec « pg_ »\n" + +#: check.c:1216 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "L'instance cible contient des rôles commençant avec « pg_ »\n" + +#: check.c:1237 +#, c-format +msgid "Checking for user-defined encoding conversions" +msgstr "Vérification des conversions d'encodage définies par les utilisateurs" + +#: check.c:1300 +#, c-format +msgid "" +"Your installation contains user-defined encoding conversions.\n" +"The conversion function parameters changed in PostgreSQL version 14\n" +"so this cluster cannot currently be upgraded. You can remove the\n" +"encoding conversions in the old cluster and restart the upgrade.\n" +"A list of user-defined encoding conversions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient des conversions définies par un utilisateur.\n" +"Les paramètres des fonctions de conversion ont changé dans PostgreSQL version 14\n" +"donc cette instance ne peut pas être mise à jour actuellement. Vous devez supprimer\n" +"les conversions d'encodage de l'ancienne instance puis relancer la mise à jour.\n" +"Une liste des conversions d'encodage définies par l'utilisateur se trouve dans le fichier :\n" +" %s\n" +"\n" + +#: check.c:1327 +#, c-format +msgid "failed to get the current locale\n" +msgstr "a échoué pour obtenir la locale courante\n" + +#: check.c:1336 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "a échoué pour obtenir le nom de la locale système « %s »\n" + +#: check.c:1342 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "a échoué pour restaurer l'ancienne locale « %s »\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "" +"n'a pas pu obtenir les données de contrôle en utilisant %s : %s\n" +"\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d : problème sur l'état de l'instance de la base de données\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "L'instance source a été arrêté alors qu'elle était en mode restauration. Pour mettre à jour, utilisez « rsync » comme documenté ou arrêtez-la en tant que serveur primaire.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "L'instance cible a été arrêté alors qu'elle était en mode restauration. Pour mettre à jour, utilisez « rsync » comme documenté ou arrêtez-la en tant que serveur primaire.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "L'instance source n'a pas été arrêtée proprement.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "L'instance cible n'a pas été arrêtée proprement.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Il manque certaines informations d'état requises sur l'instance source :\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Il manque certaines informations d'état requises sur l'instance cible :\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:335 pg_upgrade.c:371 +#: relfilenode.c:243 server.c:33 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d : problème avec pg_resetwal\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d : problème de récupération des controldata\n" + +#: controldata.c:560 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Il manque certaines informations de contrôle requises sur l'instance source :\n" + +#: controldata.c:563 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Il manque certaines informations de contrôle requises sur l'instance cible :\n" + +#: controldata.c:566 +#, c-format +msgid " checkpoint next XID\n" +msgstr " XID du prochain checkpoint\n" + +#: controldata.c:569 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " prochain OID du dernier checkpoint\n" + +#: controldata.c:572 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " prochain MultiXactId du dernier checkpoint\n" + +#: controldata.c:576 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " plus ancien MultiXactId du dernier checkpoint\n" + +#: controldata.c:579 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " prochain MultiXactOffset du dernier checkpoint\n" + +#: controldata.c:582 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " premier segment WAL après réinitialisation\n" + +#: controldata.c:585 +#, c-format +msgid " float8 argument passing method\n" +msgstr " méthode de passage de arguments float8\n" + +#: controldata.c:588 +#, c-format +msgid " maximum alignment\n" +msgstr " alignement maximale\n" + +#: controldata.c:591 +#, c-format +msgid " block size\n" +msgstr " taille de bloc\n" + +#: controldata.c:594 +#, c-format +msgid " large relation segment size\n" +msgstr " taille de segment des relations\n" + +#: controldata.c:597 +#, c-format +msgid " WAL block size\n" +msgstr " taille de bloc d'un WAL\n" + +#: controldata.c:600 +#, c-format +msgid " WAL segment size\n" +msgstr " taille d'un segment WAL\n" + +#: controldata.c:603 +#, c-format +msgid " maximum identifier length\n" +msgstr " longueur maximum d'un identifiant\n" + +#: controldata.c:606 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " nombre maximum de colonnes indexées\n" + +#: controldata.c:609 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " taille maximale d'un morceau de TOAST\n" + +#: controldata.c:613 +#, c-format +msgid " large-object chunk size\n" +msgstr " taille d'un morceau Large-Object\n" + +#: controldata.c:616 +#, c-format +msgid " dates/times are integers?\n" +msgstr " les dates/heures sont-ils des integers?\n" + +#: controldata.c:620 +#, c-format +msgid " data checksum version\n" +msgstr " version des sommes de contrôle des données\n" + +#: controldata.c:622 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Ne peut pas continuer sans les informations de contrôle requises, en arrêt\n" + +#: controldata.c:637 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"les alignements sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +"Il est probable qu'une installation soit en 32 bits et l'autre en 64 bits.\n" + +#: controldata.c:641 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "les tailles de bloc sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:644 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "les tailles maximales de segment de relation sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:647 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "les tailles de bloc des WAL sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "les tailles de segment de WAL sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "les longueurs maximales des identifiants sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:656 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "les nombres maximums de colonnes indexées sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:659 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "les tailles maximales de morceaux des TOAST sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:664 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "les tailles des morceaux de Large Objects sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:667 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "les types de stockage date/heure ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:680 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "l'ancienne instance n'utilise pas les sommes de contrôle alors que la nouvelle les utilise\n" + +#: controldata.c:683 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "l'ancienne instance utilise les sommes de contrôle alors que la nouvelle ne les utilise pas\n" + +#: controldata.c:685 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "les versions des sommes de contrôle ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" + +#: controldata.c:696 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Ajout du suffixe « .old » à l'ancien global/pg_control" + +#: controldata.c:701 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Incapable de renommer %s à %s.\n" + +#: controldata.c:704 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Si vous voulez démarrer l'ancienne instance, vous devez supprimer le suffixe « .old » du fichier %s/global/pg_control.old.\n" +"\n" +"Comme le mode lien était utilisé, l'ancienne instance ne peut pas être démarré proprement une fois que la nouvelle instance a été démarrée.\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "Création de la sauvegarde des objets globaux" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Création de la sauvegarde des schémas des bases\n" + +#: exec.c:45 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "n'a pas pu obtenir la version de pg_ctl en utilisant %s : %s\n" + +#: exec.c:51 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "n'a pas pu obtenir la version de pg_ctl à partir de %s\n" + +#: exec.c:105 exec.c:109 +#, c-format +msgid "command too long\n" +msgstr "commande trop longue\n" + +#: exec.c:111 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:150 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "n'a pas pu ouvrir le fichier de traces « %s » : %m\n" + +#: exec.c:179 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*échec*" + +#: exec.c:182 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Il y a eu des problèmes lors de l'exécution de « %s »\n" + +#: exec.c:185 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "Consultez les dernières lignes de « %s » ou « %s » pour trouver la cause probable de l'échec.\n" + +#: exec.c:190 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "Consultez les dernières lignes de « %s » pour trouver la cause probable de l'échec.\n" + +#: exec.c:205 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "n'a pas pu écrire dans le fichier de traces « %s »\n" + +#: exec.c:231 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %s\n" + +#: exec.c:258 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Vous devez avoir les droits de lecture et d'écriture dans le répertoire actuel.\n" + +#: exec.c:311 exec.c:377 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "échec de la vérification de « %s » : %s\n" + +#: exec.c:314 exec.c:380 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "« %s » n'est pas un répertoire\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "échec de la vérification de « %s » : pas un fichier régulier\n" + +#: exec.c:433 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "échec de la vérification de « %s » : ne peut pas exécuter (droit refusé)\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: cannot execute\n" +msgstr "échec de la vérification de « %s » : ne peut pas exécuter\n" + +#: exec.c:449 +#, c-format +msgid "check for \"%s\" failed: incorrect version: found \"%s\", expected \"%s\"\n" +msgstr "" +"échec de la vérification de « %s » : version incorrect : « %s » trouvée, « %s » attendue\n" +"\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "erreur lors du clonage de la relation « %s.%s » (« %s » à « %s ») : %s\n" + +#: file.c:50 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "erreur lors du clonage de la relation « %s.%s » : n'a pas pu ouvrir le fichier « %s » : %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "erreur lors du clonage de la relation « %s.%s » : n'a pas pu créer le fichier « %s » : %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu ouvrir le fichier « %s » : %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu créer le fichier « %s » : %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu lire le fichier « %s » : %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu écrire le fichier « %s » : %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "erreur lors de la copie de la relation « %s.%s » (« %s » à « %s ») : %s\n" + +#: file.c:151 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "erreur lors de la création du lien pour la relation « %s.%s » (« %s » à « %s ») : %s\n" + +#: file.c:194 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu tester le fichier « %s » : %s\n" + +#: file.c:226 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "erreur lors de la copie de la relation « %s.%s » : page partielle trouvée dans le fichier « %s »\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "n'a pas pu cloner le fichier entre l'ancien et le nouveau répertoires : %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "n'a pas pu créer le fichier « %s » : %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "clonage de fichiers non supporté sur cette plateforme\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"n'a pas pu créer le lien physique entre l'ancien et le nouveau répertoires de données : %s\n" +"Dans le mode lien, les ancien et nouveau répertoires de données doivent être sur le même système de fichiers.\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"L'ancienne instance comprend une fonction « plpython_call_handler »\n" +"définie dans le schéma « public » qui est un duplicat de celle définie\n" +"dans le schéma « pg_catalog ». Vous pouvez confirmer cela en\n" +"exécutant dans psql :\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"La version de cette fonction dans le schéma « public » a été créée\n" +"par une installation de plpython antérieure à la version 8.1 et doit\n" +"être supprimée pour que pg_upgrade puisse termine parce qu'elle\n" +"référence un fichier objet partagé « plpython » maintenant obsolète.\n" +"Vous pouvez supprimer la version de cette fonction dans le schéma\n" +"« public » en exécutant la commande suivante :\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"dans chaque base de données affectée :\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Supprimez les fonctions problématiques de l'ancienne instance pour continuer.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Vérification de la présence des bibliothèques requises" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "n'a pas pu charger la bibliothèque « %s » : %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "Dans la base de données : %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation référence des bibliothèques chargeables, mais manquantes sur\n" +"la nouvelle installation. Vous pouvez ajouter ces bibliothèques à la nouvelle\n" +"installation ou supprimer les fonctions les utilisant dans l'ancienne installation.\n" +"Une liste des biblioth_ques problématiques est disponible dans le fichier :\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Les noms de relation pour l'OID %u dans la base de données « %s » ne correspondent pas : ancien nom « %s.%s », nouveau nom « %s.%s »\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Échec de correspondance des anciennes et nouvelles tables dans la base de données « %s »\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " qui est un index sur \"%s.%s\"" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " qui est un index sur l'OID %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " qui est la table TOAST pour « %s.%s »" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " qui est la table TOAST pour l'OID %u" + +#: info.c:274 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "Aucune correspondance trouvée dans l'ancienne instance pour la nouvelle relation d'OID %u dans la base de données « %s » : %s\n" + +#: info.c:277 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "Aucune correspondance trouvée dans la nouvelle instance pour la nouvelle relation d'OID %u dans la base de données « %s » : %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "correspondances pour la base de données « %s » :\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s : %u vers %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"bases de données sources :\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"bases de données cibles :\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "Base de données : %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname : %s.%s : reloid : %u reltblspace : %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s : ne peut pas être exécuté en tant que root\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "ancien numéro de port invalide\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "nouveau numéro de port invalide\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Exécution en mode verbeux\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "les binaires de l'ancienne instance résident" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "les binaires de la nouvelle instance résident" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "les données de l'ancienne instance résident" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "les données de la nouvelle instance résident" + +#: option.c:259 +msgid "sockets will be created" +msgstr "les sockets seront créés" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "n'a pas pu déterminer le répertoire courant\n" + +#: option.c:279 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "ne peut pas exécuter pg_upgrade depuis le répertoire de données de la nouvelle instance sur Windows\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "pg_upgrade met à jour une instance PostgreSQL vers une version majeure différente.\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [OPTION]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "Options :\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=DIRBIN répertoire des exécutables de l'ancienne instance\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=DIRBIN répertoire des exécutables de la nouvelle instance (par défaut,\n" +" le même répertoire que pg_upgrade)\n" +"\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check vérifie seulement les instances, pas de modifications\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DIRDONNEES répertoire des données de l'ancienne instance\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DIRDONNEES répertoire des données de la nouvelle instance\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs=NUM number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs=NUM nombre de processus ou threads simultanés à utiliser\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link lie les fichiers au lieu de les copier vers la nouvelle instance\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPTIONS options à passer au serveur de l'ancienne instance\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPTIONS options à passer au serveur de la nouvelle instance\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT numéro de port de l'ancienne instance (par défaut %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT numéro de port de la nouvelle instance (par défaut %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain conserve les fichiers SQL et de traces en cas de succès\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" +msgstr " -s, --socketdir=DIR répertoire de la socket à utiliser (par défaut le répertoire courant)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NOM superutilisateur de l'instance (par défaut « %s »)\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose active des traces internes verbeuses\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version affiche la version, puis quitte\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " --clone clone au lieu de copier les fichiers vers la nouvelle instance\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide, puis quitte\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Avant d'exécuter pg_upgrade, vous devez :\n" +" créer une nouvelle instance (en utilisant la nouvelle version d'initdb)\n" +" arrêter le postmaster de l'ancienne instance\n" +" arrêter le postmaster de la nouvelle instance\n" +"\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"Quand vous exécutez pg_upgrade, vous devez fournir les informations suivantes :\n" +" le répertoire de données pour l'ancienne instance (-d DIRDONNÉES)\n" +" le répertoire de données pour la nouvelle instance (-D DIRDONNÉES)\n" +" le répertoire « bin » pour l'ancienne version (-b DIRBIN)\n" +" le répertoire « bin » pour la nouvelle version (-B DIRBIN)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Par exemple :\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"ou\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapporter les bogues à <%s>.\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil %s : <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Vous devez identifier le répertoire où le %s.\n" +"Merci d'utiliser l'option en ligne de commande %s ou la variable d'environnement %s.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Recherche du vrai répertoire des données pour l'instance source" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Recherche du vrai répertoire des données pour l'instance cible" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "n'a pas pu obtenir le répertoire des données en utilisant %s : %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "n'a pas pu lire la ligne %d du fichier « %s » : %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "ancien numéro de port %hu fourni par l'utilisateur corrigé en %hu\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "n'a pas pu créer le processus de travail : %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "n'a pas pu créer le fil de travail: %s\n" + +#: parallel.c:300 +#, c-format +msgid "%s() failed: %s\n" +msgstr "échec de %s() : %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "le processus fils a quitté anormalement : statut %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "le processus fils a quitté anormalement : %s\n" + +#: pg_upgrade.c:107 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "n'a pas pu lire les droits du répertoire « %s » : %s\n" + +#: pg_upgrade.c:122 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Réalisation de la mise à jour\n" +"-----------------------------\n" + +#: pg_upgrade.c:165 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Configuration du prochain OID sur la nouvelle instance" + +#: pg_upgrade.c:172 +#, c-format +msgid "Sync data directory to disk" +msgstr "Synchronisation du répertoire des données sur disque" + +#: pg_upgrade.c:183 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Mise à jour terminée\n" +"--------------------\n" + +#: pg_upgrade.c:216 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s : n'a pas pu trouver son propre exécutable\n" + +#: pg_upgrade.c:242 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Il semble qu'un postmaster est démarré sur l'ancienne instance.\n" +"Merci d'arrêter ce postmaster et d'essayer de nouveau.\n" + +#: pg_upgrade.c:255 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Il semble qu'un postmaster est démarré sur la nouvelle instance.\n" +"Merci d'arrêter ce postmaster et d'essayer de nouveau.\n" + +#: pg_upgrade.c:269 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analyse de toutes les lignes dans la nouvelle instance" + +#: pg_upgrade.c:282 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Gel de toutes les lignes dans la nouvelle instance" + +#: pg_upgrade.c:302 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Restauration des objets globaux dans la nouvelle instance" + +#: pg_upgrade.c:317 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Restauration des schémas des bases de données dans la nouvelle instance\n" + +#: pg_upgrade.c:421 +#, c-format +msgid "Deleting files from new %s" +msgstr "Suppression des fichiers à partir du nouveau %s" + +#: pg_upgrade.c:425 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "n'a pas pu supprimer le répertoire « %s »\n" + +#: pg_upgrade.c:444 +#, c-format +msgid "Copying old %s to new server" +msgstr "Copie de l'ancien %s vers le nouveau serveur" + +#: pg_upgrade.c:471 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Configuration du prochain identifiant de transaction et de l'epoch pour la nouvelle instance" + +#: pg_upgrade.c:501 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Configuration du prochain MultiXactId et décalage pour la nouvelle instance" + +#: pg_upgrade.c:525 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Configuration du plus ancien identifiant multixact sur la nouvelle instance" + +#: pg_upgrade.c:545 +#, c-format +msgid "Resetting WAL archives" +msgstr "Réinitialisation des archives WAL" + +#: pg_upgrade.c:588 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Configuration des compteurs frozenxid et minmxid dans la nouvelle instance" + +#: pg_upgrade.c:590 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Configuration du compteur minmxid dans la nouvelle instance" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Clonage des fichiers des relations utilisateurs\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "Copie des fichiers des relations utilisateurs\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "Création des liens pour les fichiers des relations utilisateurs\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "ancienne base de données « %s » introuvable dans la nouvelle instance\n" + +#: relfilenode.c:230 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "erreur lors de la vérification de l'existence du fichier « %s.%s » (« %s » vers « %s ») : %s\n" + +#: relfilenode.c:248 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "réécriture de « %s » en « %s »\n" + +#: relfilenode.c:256 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "clonage de « %s » en « %s »\n" + +#: relfilenode.c:261 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "copie de « %s » en « %s »\n" + +#: relfilenode.c:266 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "lien de « %s » vers « %s »\n" + +#: server.c:38 server.c:142 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "Échec, sortie\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "exécution : %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"La commande SQL a échoué\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "n'a pas pu ouvrir le fichier de version « %s » : %m\n" + +#: server.c:172 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "n'a pas pu analyser le fichier de version « %s »\n" + +#: server.c:298 +#, c-format +msgid "" +"\n" +"%s" +msgstr "" +"\n" +"%s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"n'a pas pu se connecter au postmaster source lancé avec la commande :\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"n'a pas pu se connecter au postmaster cible lancé avec la commande :\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl a échoué à démarrer le serveur source ou connexion échouée\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl a échoué à démarrer le serveur cible ou connexion échouée\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "la variable d'environnement libpq %s a une valeur serveur non locale : %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "Ne peut pas mettre à jour vers ou à partir de la même version de catalogue système quand des tablespaces sont utilisés.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "le répertoire « %s » du tablespace n'existe pas\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "n'a pas pu tester le répertoire « %s » du tablespace : %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "le chemin « %s » du tablespace n'est pas un répertoire\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "Vérification des Large Objects" + +#: version.c:77 version.c:419 +#, c-format +msgid "warning" +msgstr "attention" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Votre installation contient des Large Objects. La nouvelle base de données a une table de droit supplémentaire sur les Large Objects.\n" +"Après la mise à jour, vous disposerez d'une commande pour peupler la table pg_largeobject_metadata avec les droits par défaut.\n" +"\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Votre installation contient des Large Objects. La nouvelle base de données\n" +"a une table de droit supplémentaire pour les Large Objects, donc les droits\n" +"par défaut doivent être définies pour tous les Large Objects. Le fichier\n" +" %s\n" +"une fois exécuté par psql avec un superutilisateur définira les droits par\n" +"défaut.\n" +"\n" + +#: version.c:272 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Vérification des types de données line incompatibles" + +#: version.c:279 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables.\n" +"This data type changed its internal and input/output format\n" +"between your old and new versions so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient le type de données « line » dans vos tables utilisateurs.\n" +"Ce type de données a changé de format interne et en entrée/sortie entre vos ancienne\n" +"et nouvelle versions, donc cette instance ne peut pas être mise à jour\n" +"actuellement. Vous pouvez supprimer les colonnes problématiques et relancer la mise à jour.\n" +"Une liste des colonnes problématiques se trouve dans le fichier :\n" +" %s\n" +"\n" + +#: version.c:310 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Vérification des colonnes utilisateurs « unknown » invalides" + +#: version.c:317 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables.\n" +"This data type is no longer allowed in tables, so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient le type de données « unknown » dans vos tables\n" +"utilisateurs. Ce type de données n'est plus autorisé dans les tables, donc\n" +"cette instance ne peut pas être mise à jour pour l'instant. Vous pouvez\n" +"supprimer les colonnes problématiques, puis relancer la mise à jour. Vous trouverez\n" +"une liste des colonnes problématiques dans le fichier :\n" +" %s\n" +"\n" + +#: version.c:341 +#, c-format +msgid "Checking for hash indexes" +msgstr "Vérification des index hash" + +#: version.c:421 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Votre installation contient des index hashs. Ces index ont des formats\n" +"internes différents entre l'ancienne et la nouvelle instance, dont ils doivent\n" +"être recréés avec la commande REINDEX. Après la mise à jour, les instructions\n" +"REINDEX vous seront données.\n" +"\n" + +#: version.c:427 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Votre installation contient des index hashs. Ces index ont des formats\n" +"internes différents entre l'ancienne et la nouvelle instance, donc ils doivent\n" +"être recréés avec la commande REINDEX. Le fichier :\n" +" %s\n" +"une fois exécuté par psql en tant que superutilisateur va recréer tous les\n" +"index invalides. Avant cela, aucun de ces index ne sera utilisé.\n" +"\n" + +#: version.c:453 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "Vérification des colonnes utilisateurs « sql_identifier » invalides" + +#: version.c:461 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables.\n" +"The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can\n" +"drop the problem columns and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient le type de données « sql_identifier » dans les tables\n" +"utilisateurs. Le format sur disque pour ce type de données a changé,\n" +"donc cette instance ne peut pas être mise à jour actuellement. Vous pouvez supprimer\n" +"les colonnes problématiques, puis relancer la mise à jour.\n" +"\n" +"Une liste des colonnes problématiques se trouve dans le fichier :\n" +" %s\n" +"\n" + +#~ msgid "waitpid() failed: %s\n" +#~ msgstr "échec de waitpid() : %s\n" + +#~ msgid "" +#~ "Optimizer statistics and free space information are not transferred\n" +#~ "by pg_upgrade so, once you start the new server, consider running:\n" +#~ " %s\n" +#~ "\n" +#~ msgstr "" +#~ "Les statistiques de l'optimiseur et les informations sur l'espace libre\n" +#~ "ne sont pas transférées par pg_upgrade, donc une fois le nouveau\n" +#~ "serveur démarré, pensez à exécuter :\n" +#~ " %s\n" +#~ "\n" + +#~ msgid "cannot write to log file %s\n" +#~ msgstr "ne peut pas écrire dans le fichier de traces %s\n" + +#~ msgid "cannot find current directory\n" +#~ msgstr "ne peut pas trouver le répertoire courant\n" + +#~ msgid "Cannot open file %s: %m\n" +#~ msgstr "Ne peut pas ouvrir le fichier %s : %m\n" + +#~ msgid "Cannot read line %d from %s: %m\n" +#~ msgstr "Ne peut pas lire la ligne %d à partir de %s : %m\n" + +#~ msgid "----------------\n" +#~ msgstr "----------------\n" + +#~ msgid "------------------\n" +#~ msgstr "------------------\n" + +#~ msgid "" +#~ "could not load library \"%s\":\n" +#~ "%s\n" +#~ msgstr "" +#~ "n'a pas pu charger la biblothèque « %s »:\n" +#~ "%s\n" + +#~ msgid "%s is not a directory\n" +#~ msgstr "%s n'est pas un répertoire\n" + +#~ msgid "" +#~ "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n" +#~ "because of backend API changes made during development.\n" +#~ msgstr "" +#~ "Cet outil peut seulement mettre à jour à partir de la version 9.0 de PostgreSQL (après le 11 janvier 2010)\n" +#~ "à cause de changements dans l'API du moteur fait lors du développement.\n" + +#~ msgid "-----------------------------\n" +#~ msgstr "-----------------------------\n" + +#~ msgid "------------------------------------------------\n" +#~ msgstr "------------------------------------------------\n" + +#~ msgid "could not parse PG_VERSION file from %s\n" +#~ msgstr "n'a pas pu analyser le fichier PG_VERSION à partir de %s\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapporter les bogues à .\n" + +#~ msgid "" +#~ "\n" +#~ "connection to database failed: %s" +#~ msgstr "" +#~ "\n" +#~ "échec de la connexion à la base de données : %s" + +#~ msgid "connection to database failed: %s" +#~ msgstr "échec de la connexion à la base de données : %s" + +#~ msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +#~ msgstr "échec de la vérification de « %s » : ne peut pas lire le fichier (droit refusé)\n" + +#~ msgid "Creating script to analyze new cluster" +#~ msgstr "Création d'un script pour analyser la nouvelle instance" + +#~ msgid "" +#~ " --index-collation-versions-unknown\n" +#~ " mark text indexes as needing to be rebuilt\n" +#~ msgstr "" +#~ " --index-collation-versions-unknown\n" +#~ " marque les index de colonnes de type text comme nécessitant une reconstruction\n" diff --git a/src/bin/pg_upgrade/po/ja.po b/src/bin/pg_upgrade/po/ja.po new file mode 100644 index 000000000000..17aae06271c7 --- /dev/null +++ b/src/bin/pg_upgrade/po/ja.po @@ -0,0 +1,1803 @@ +# Japanese message translation file for pg_upgrade +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:55+0900\n" +"PO-Revision-Date: 2020-08-21 18:53+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.13\n" +"Plural-Forms: nplural=1; plural=0;\n" + +#: check.c:66 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"元の実行中サーバーの一貫性チェックを実行しています。\n" +"--------------------------------------------------\n" + +#: check.c:72 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"整合性チェックを実行しています。\n" +"-----------------------------\n" + +#: check.c:190 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"* クラスタは互換性があります *\n" + +#: check.c:196 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"この後pg_upgradeが失敗した場合は、続ける前に新しいクラスタを\n" +"initdbで再作成する必要があります。\n" + +#: check.c:232 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"オプティマイザーの統計は、pg_upgrade では転送されません。そのため\n" +"新サーバーを起動した後、%s を動かすことを検討してください。\n" +"\n" +"\n" + +#: check.c:237 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"オプティマイザーの統計情報と空き容量の情報は pg_upgrade では転送されません。\n" +"そのため新サーバーを起動した後、%s の実行を検討してください。\n" +"\n" +"\n" + +#: check.c:244 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"このスクリプトを実行すると、旧クラスタのデータファイル %sが削除されます:\n" +"\n" + +#: check.c:249 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"ユーザー定義のテーブル空間もしくは新クラスタのデータディレクトリが\n" +"旧クラスタのディレクトリ内に存在するため、旧クラスタのデータ\n" +"ファイルを削除するためのスクリプトを作成できませんでした。 古い\n" +"クラスタの内容は手動で削除する必要があります。\n" + +#: check.c:259 +#, c-format +msgid "Checking cluster versions" +msgstr "クラスタのバージョンを確認しています" + +#: check.c:271 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "このユーティリティでは PostgreSQL 8.4 以降のバージョンからのみアップグレードできます。\n" + +#: check.c:275 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "このユーティリティは、PostgreSQL バージョン %s にのみアップグレードできます。\n" + +#: check.c:284 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "このユーティリティは PostgreSQL の過去のメジャーバージョンにダウングレードする用途では使用できません。\n" + +#: check.c:289 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "旧クラスタのデータとバイナリのディレクトリは異なるメジャーバージョンのものです。\n" + +#: check.c:292 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "新クラスタのデータとバイナリのディレクトリは異なるメジャーバージョンのものです。\n" + +#: check.c:309 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "現在動作中の PG 9.1 以前の旧サーバをチェックする場合、旧サーバのポート番号を指定する必要があります。\n" + +#: check.c:313 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "稼働中のサーバをチェックする場合、新旧のポート番号が異なっている必要があります。\n" + +#: check.c:328 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "データベース\"%s\"のエンコーディングが一致しません: 旧 \"%s\"、新 \"%s\"\n" + +#: check.c:333 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "データベース\"%s\"の lc_collate 値が一致しません:旧 \"%s\"、新 \"%s\"\n" + +#: check.c:336 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "データベース\"%s\"の lc_ctype 値が一致しません:旧 \"%s\"、新 \"%s\"\n" + +#: check.c:409 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "新クラスタのデータベース\"%s\"が空ではありません: リレーション\"%s.%s\"が見つかりました\n" + +#: check.c:458 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "新クラスタをANALYZEするためのスクリプトを作成しています" + +#: check.c:472 check.c:600 check.c:864 check.c:943 check.c:1053 check.c:1144 +#: file.c:336 function.c:240 option.c:497 version.c:54 version.c:199 +#: version.c:341 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "ファイル \"%s\" をオープンできませんでした: %s\n" + +#: check.c:527 check.c:656 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "ファイル\"%s\"に実行権限を追加できませんでした: %s\n" + +#: check.c:563 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"警告: 新データディレクトリが旧データディレクトリの中にあってはなりません、例えば%s\n" + +#: check.c:587 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"警告: ユーザー定義テーブル空間の場所がデータディレクトリ、例えば %s の中にあってはなりません。\n" + +#: check.c:597 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "旧クラスタを削除するスクリプトを作成しています" + +#: check.c:676 +#, c-format +msgid "Checking database user is the install user" +msgstr "データベースユーザーがインストールユーザーかどうかをチェックしています" + +#: check.c:692 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "データベースユーザー\"%s\"がインストールユーザーではありません\n" + +#: check.c:703 +#, c-format +msgid "could not determine the number of users\n" +msgstr "ユーザー数を特定できませんでした\n" + +#: check.c:711 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "新クラスタ内で定義できるのはインストールユーザーのみです。\n" + +#: check.c:731 +#, c-format +msgid "Checking database connection settings" +msgstr "データベース接続の設定を確認しています" + +#: check.c:753 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 には接続を許可してはなりません。すなわち、pg_database.datallowconn は false である必要があります。\n" + +#: check.c:763 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "template0 以外のすべてのデータベースは接続を許可する必要があります。すなわち pg_database.datallowconn が true でなければなりません。\n" + +#: check.c:788 +#, c-format +msgid "Checking for prepared transactions" +msgstr "準備済みトランザクションをチェックしています" + +#: check.c:797 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "移行元クラスタに準備済みトランザクションがあります\n" + +#: check.c:799 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "移行先クラスタに準備済みトランザクションがあります\n" + +#: check.c:825 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "bigint を渡す際にミスマッチが発生する contrib/isn をチェックしています" + +#: check.c:886 check.c:965 check.c:1076 check.c:1167 function.c:262 +#: version.c:245 version.c:282 version.c:425 +#, c-format +msgid "fatal\n" +msgstr "致命的\n" + +#: check.c:887 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"移行元インストールに、bigint データ型に依存する「contrib/isn」の関数が\n" +"含まれています。新旧のクラスタ間でのbigint値の受け渡し方法が異なるため、\n" +"現時点ではこのクラスタをアップグレードすることはできません。\n" +"旧クラスタ中の「contrib/isn」の関数等を使うデータベースを手動でダンプして、\n" +"それらを削除してからアップグレードを実行し、その後削除したデータベースを\n" +"リストアすることができます。 \n" +"問題のある関数の一覧は以下のファイルにあります:\n" +" %s\n" +"\n" + +#: check.c:911 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "WITH OIDS宣言されたテーブルをチェックしています" + +#: check.c:966 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"このインストールではWITH OIDS宣言されたテーブルが存在しますが、これは今後\n" +"サポートされません。以下のコマンドでoidカラムを削除することを検討してください:\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"以下のファイルにこの問題を抱えるテーブルの一覧があります:\n" +" %s\n" +"\n" + +#: check.c:996 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "ユーザーテーブル内の reg * データ型をチェックしています" + +#: check.c:1077 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the\n" +"problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"あなたのインストールではユーザテーブルにreg*データ型のひとつが含まれています。\n" +"これらのデータ型はシステムOIDを参照しますが、これは pg_upgradeでは\n" +"保存されないため、現時点ではこのクラスタをアップグレードすることはできません。\n" +"問題のテーブルを削除したのち、アップグレードを再実行できます。\n" +"問題になる列の一覧は以下のファイルにあります:\n" +" %s\n" +"\n" + +#: check.c:1102 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "互換性のない\"jsonb\"データ型をチェックしています" + +#: check.c:1168 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can remove the problem\n" +"tables and restart the upgrade. A list of the problem columns is\n" +"in the file:\n" +" %s\n" +"\n" +msgstr "" +"あなたのインストールではユーザテーブルに\"jsonb\"データ型が含まれています。\n" +"この型の内部フォーマットは9.4ベータの間に変更されているため、現時点ではこの\n" +"クラスタをアップグレードすることはできません。\n" +"問題のテーブルを削除したのち、アップグレードを再実行できます。\n" +"問題になる列の一覧は以下のファイルにあります:\n" +" %s\n" +"\n" + +#: check.c:1190 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "'pg_' で始まるロールをチェックしています" + +#: check.c:1200 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "移行元クラスタに 'pg_' で始まるロールが含まれています\n" + +#: check.c:1202 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "移行先クラスタに \"pg_\" で始まるロールが含まれています\n" + +#: check.c:1228 +#, c-format +msgid "failed to get the current locale\n" +msgstr "現在のロケールを取得できませんでした。\n" + +#: check.c:1237 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "\"%s\"のシステムロケール名を取得できませんでした。\n" + +#: check.c:1243 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "古いロケール\"%s\"を復元できませんでした。\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "%s を使った制御情報が取得できませんでした。: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: データベースクラスタの状態異常\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "ソースクラスタはリカバリモード中にシャットダウンされています。アップグレードをするにはドキュメントの通りに \"rsync\" を実行するか、プライマリとしてシャットダウンしてください。\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "ターゲットクラスタはリカバリモード中にシャットダウンされています。アップグレードをするにはドキュメントの通りに \"rsync\" を実行するか、プライマリとしてシャットダウンしてください。\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "移行元クラスタはクリーンにシャットダウンされていません。\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "移行先クラスタはクリーンにシャットダウンされていません。\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "移行元クラスタにクラスタ状態情報がありません:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "移行先クラスタにクラスタ状態情報がありません:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:339 pg_upgrade.c:375 +#: relfilenode.c:247 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal で問題発生\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: 制御情報の取得で問題発生\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "移行元クラスタに必要な制御情報の一部がありません:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "移行先クラスタに必要な制御情報の一部がありません:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " チェックポイントにおける次の XID\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " 最新のチェックポイントにおける次の OID\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " 最新のチェックポイントにおける次の MultiXactId\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " 最新のチェックポイントにおける最古の MultiXactId\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " 最新のチェックポイントにおける次の MultiXactOffset\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " リセット後の最初の WAL セグメント\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " float8 引数がメソッドを渡しています\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " 最大アラインメント\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " ブロックサイズ\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " リレーションセグメントのサイズ\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " WAL のブロックサイズ\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL のセグメント サイズ\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " 識別子の最大長\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " インデックス対象カラムの最大数\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " 最大の TOAST チャンクサイズ\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " ラージオブジェクトのチャンクサイズ\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " 日付/時間が整数?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " データチェックサムのバージョン\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "必要な制御情報がないので続行できません。終了しています\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"新旧のpg_controldataのアラインメントが不正であるかかまたは一致しません\n" +"一方のクラスタが32ビットで、他方が64ビットである可能性が高いです\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "新旧の pg_controldata におけるブロックサイズが有効でないかまたは一致しません。\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "新旧の pg_controldata におけるリレーションの最大セグメントサイズが有効でないか一致しません。\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "新旧の pg_controldata における WAL ブロックサイズが有効でないか一致しません。\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "新旧の pg_controldata における WAL セグメントサイズが有効でないか一致しません。\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "新旧の pg_controldata における識別子の最大長が有効でないか一致しません。\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "新旧の pg_controldata におけるインデックス付き列の最大数が有効でないか一致しません。\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "新旧の pg_controldata における TOAST チャンクサイズの最大値が有効でないか一致しません。\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "新旧の pg_controldata におけるラージオブジェクトのチャンクサイズが有効でないかまたは一致しません。\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "新旧の pg_controldata における日付/時刻型データの保存バイト数が一致しません\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "旧クラスタではデータチェックサムを使用していませんが、新クラスタでは使用しています\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "旧クラスタではデータチェックサムを使用していますが、新クラスタでは使用していません\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "新旧の pg_controldata 間でチェックサムのバージョンが一致しません。\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "旧の global/pg_control に \".old\" サフィックスを追加しています" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "%s の名前を %s に変更できません。\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"旧クラスタを起動する場合、%s/global/pg_control.oldから\n" +"\".old\"拡張子を削除する必要があります。「リンク」モードが使われて\n" +"いるため、一度新クラスタを起動してしまうと旧クラスタは安全に起動\n" +"することができなくなります。\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "グローバルオブジェクトのダンプを作成しています" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "データベーススキーマのダンプを作成しています。\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "%s を使って pg_ctl のバージョンデータを取得できませんでした。: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "pg_ctl のバージョン出力を %s から取得できませんでした。\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "コマンドが長すぎます\n" + +#: exec.c:110 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "ログファイル\"%s\"をオープンできませんでした: %m\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*失敗*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "\"%s\"を実行していて問題が発生しました\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"失敗の原因については\"%s\"または\"%s\"の最後の数行を参照してください。\n" +"\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"失敗の原因については、\"%s\"の最後の数行を参照してください。\n" +"\n" + +#: exec.c:204 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "ログファイル\"%s\"に書き込めませんでした。\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "ファイル\"%s\"を読み取り用としてオープンできませんでした:%s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "カレントディレクトリに対して読み書き可能なアクセス権が必要です。\n" + +#: exec.c:310 exec.c:372 exec.c:436 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "\"%s\"のチェックに失敗しました: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\"はディレクトリではありません\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "\"%s\"のチェックに失敗しました:通常ファイルではありません\n" + +#: exec.c:451 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "\"%s\"のチェックに失敗しました:ファイルが読めません(権限が拒否されました)\n" + +#: exec.c:459 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "\"%s\"のチェックに失敗しました:実行できません(権限が拒否されました)\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "リレーション\"%s.%s\"の(\"%s\"から\"%s\"への)クローン中にエラー: %s\n" + +#: file.c:50 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"のクローン中にエラー: ファイル\"%s\"を開けませんでした: %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"のクローン中にエラー: ファイル\"%s\"を作成できませんでした: %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"を開けませんでした: %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"を作成できませんでした: %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"を読めませんでした: %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"に書けませんでした: %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "リレーション\"%s.%s\"のコピー(\"%s\" -> \"%s\")中にエラー:%s\n" + +#: file.c:151 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "リレーション\"%s.%s\"へのリンク(\"%s\" -> \"%s\")作成中にエラー:%s\n" + +#: file.c:194 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"を stat できませんでした: %s\n" + +#: file.c:226 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "リレーション\"%s.%s\"のコピー中にエラー: ファイル\"%s\"中に不完全なページがありました\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "新旧ディレクトリ間のファイルのクローンができませんでした: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "ファイル\"%s\"を作成できませんでした: %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "このプラットフォームではファイルのクローニングはサポートされません\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"新旧のデータディレクトリ間でハードリンクを作成できませんでした: %s\n" +"リンクモードでは、新旧のデータディレクトリが同じファイルシステム上に存在しなければなりません。\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"旧クラスタで\"plpython_call_handler\"関数が\"public\"スキーマ内に\n" +"定義されていますが、これは\"pg_catalog\"スキーマで定義されている\n" +"ものと重複しています。このことは以下のコマンドをpsqlで実行して確認\n" +"できます:\n" +"\n" +" \\\\df *.plpython_call_handler\n" +"\n" +"\"public\"スキーマの方の関数は8.1以前の環境のplpythonが作成したもので、\n" +"すでに廃止済みの \"plpython\" 共有オブジェクトファイルを参照している\n" +"ため、pg_upgrade を完了させるには削除する必要があります。以下のコマンドを\n" +"影響のあるデータベースで個別に実行することにより\"public\"スキーマの方の\n" +"関数の削除ができます: \n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "継続するには、旧クラスタから問題となっている関数を削除してください。\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "必要なライブラリの有無を確認しています" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "ライブラリ\"%s\"をロードできませんでした: %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "データベース: %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"旧の環境で、新の環境にはないローダブルライブラリを参照しています。\n" +"これらのライブラリを新の環境に追加するか、もしくは旧の環境から\n" +"それらを使っている関数を削除してください。 問題のライブラリの一覧は、\n" +"以下のファイルに入っています:\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "データベース\"%2$s\"で OID %1$u のリレーション名が一致しません: 元の名前 \"%3$s.%4$s\"、新しい名前 \"%5$s.%6$s\"\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "データベース\"%s\"で新旧のテーブルの照合に失敗しました。\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " これは \"%s.%s\" 上のインデックスです" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " これは OID %u 上のインデックスです" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " これは \"%s.%s\" の TOAST テーブルです" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " これは OID %u の TOAST テーブルです" + +#: info.c:274 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "データベース\"%2$s\"でOID%1$uを持つ新リレーションに対応するものが旧クラスタ内にありません: %3$s\n" + +#: info.c:277 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "データベース\"%2$s\"でOID %1$uを持つ旧リレーションに対応するものが新クラスタ内にありません: %3$s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "データベース\"%s\"のマッピング:\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u -> %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"移行元データベース:\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"移行先データベース:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "データベース: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: root では実行できません\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "旧ポート番号が無効です\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "新ポート番号が無効です\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"を参照してください。\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "コマンドライン引数が多すぎます。(先頭は\"%s\")\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "冗長モードで実行しています\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "旧クラスタのバイナリが置かれている" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "新クラスタのバイナリが置かれている" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "旧クラスタのデータが置かれている" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "新クラスタのデータが置かれている" + +#: option.c:259 +msgid "sockets will be created" +msgstr "ソケットが作成される" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "カレントディレクトリを特定できませんでした。\n" + +#: option.c:279 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "Windowsでは、新クラスタのデータディレクトリの中でpg_upgradeを実行することはできません\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgradeは、PostgreSQLのクラスタを別のメジャーバージョンにアップグレードします。\n" +"\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "使い方:\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [オプション]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "オプション:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR 旧クラスタの実行ファイルディレクトリ\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=BINDIR 新クラスタの実行ファイルディレクトリ(デフォルト\n" +" はpg_upgradeと同じディレクトリ)\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check クラスタのチェックのみ、データを一切変更しない\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR 旧クラスタのデータディレクトリ\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR 新クラスタのデータディレクトリ\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs=NUM number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs 使用する同時実行プロセスまたはスレッドの数\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr "" +" -k, --link 新クラスタにファイルをコピーする代わりに\n" +" リンクする\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPTIONS サーバに渡す旧クラスタのオプション\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPTIONS サーバに渡す新クラスタのオプション\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT 旧クラスタのポート番号(デフォルト %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT 新クラスタのポート番号(デフォルト %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain SQLとログファイルを、成功後も消さずに残す\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" +msgstr "" +" -s, --socketdir=DIR 使用するソケットディレクトリ(デフォルトは\n" +" カレントディレクトリ)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NAME クラスタのスーパユーザ(デフォルト\"%s\")\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose 詳細な内部ログを有効化\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr "" +" --clone 新クラスタにファイルをコピーする代わりに\n" +" クローンする\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"pg_upgrade を実行する前に、以下のことを行ってください:\n" +" (新バージョンのinitdbを使って)新しいデータベースクラスタを作成する\n" +" 旧クラスタのpostmasterをシャットダウンする\n" +" 新クラスタのpostmasterをシャットダウンする\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"pg_upgrade を動かす場合、次の情報を指定する必要があります: \n" +" 旧クラスタのデータディレクトリ (-d DATADIR)\n" +" 新クラスタのデータディレクトリ (-D DATADIR) \n" +" 旧バージョンの\"bin\"ディレクトリ (-b BINDIR)\n" +" 新バージョンの\"bin\"ディレクトリ(-B BINDIR)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"実行例:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"または\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"%sディレクトリを指定する必要があります。\n" +"コマンドラインオプション %s または環境変数 %s を使用してください。\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "移行元クラスタの実際のデータディレクトリを探しています" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "移行先クラスタの実際のデータディレクトリを探しています" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "%s を使ってデータディレクトリを取得できませんでした。: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "ファイル\"%2$s\"の%1$d行目を読み取れませんでした: %3$s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "ユーザー指定の旧ポート番号 %hu は %hu に訂正されました\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "ワーカープロセスを作成できませんでした: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "ワーカースレッドを作成できませんでした: %s\n" + +#: parallel.c:300 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "waitpid()が失敗しました: %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "子プロセスが異常終了しました: ステータス %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "子ワーカーが異常終了しました: %s\n" + +#: pg_upgrade.c:108 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "ディレクトリ\"%s\"の権限を読み取れませんでした: %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"アップグレードを実行しています。\n" +"------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "新クラスタの、次の OID を設定しています" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "データディレクトリをディスクに同期します" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"アップグレードが完了しました\n" +"----------------\n" + +#: pg_upgrade.c:220 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 自身のための実行ファイルが見つかりませんでした\n" + +#: pg_upgrade.c:246 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"旧クラスタで稼働中のpostmasterがあるようです。\n" +"そのpostmasterをシャットダウンしたのちにやり直してください。\n" + +#: pg_upgrade.c:259 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"新クラスタで稼働中のpostmasterがあるようです。\n" +"そのpostmasterをシャットダウンしたのちやり直してください。\n" + +#: pg_upgrade.c:273 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "新クラスタ内のすべての行を分析しています" + +#: pg_upgrade.c:286 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "新クラスタ内のすべての行を凍結しています" + +#: pg_upgrade.c:306 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "新クラスタ内のグローバルオブジェクトを復元しています" + +#: pg_upgrade.c:321 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "新クラスタ内のデータベーススキーマを復元しています\n" + +#: pg_upgrade.c:425 +#, c-format +msgid "Deleting files from new %s" +msgstr "新しい %s からファイルを削除しています" + +#: pg_upgrade.c:429 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "ディレクトリ\"%s\"を削除できませんでした。\n" + +#: pg_upgrade.c:448 +#, c-format +msgid "Copying old %s to new server" +msgstr "旧の %s を新サーバーにコピーしています" + +#: pg_upgrade.c:475 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "新クラスタの、次のトランザクションIDと基点を設定しています" + +#: pg_upgrade.c:505 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "新クラスタの、次のmultixact IDとオフセットを設定しています" + +#: pg_upgrade.c:529 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "新クラスタの最古のmultixact IDを設定しています" + +#: pg_upgrade.c:549 +#, c-format +msgid "Resetting WAL archives" +msgstr "WAL アーカイブをリセットしています" + +#: pg_upgrade.c:592 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "新クラスタのfrozenxidとminmxidカウンタを設定しています" + +#: pg_upgrade.c:594 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "新クラスタのminmxidカウンタを設定しています" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "ユーザリレーションをクローニングしています\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "ユーザリレーションのファイルをコピーしています\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "ユーザリレーションのファイルをリンクしています\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "新クラスタ内に旧データベース\"%s\"が見つかりません\n" + +#: relfilenode.c:234 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\"ファイル (\"%s\" -> \"%s\")の存在を確認中にエラー: %s\n" + +#: relfilenode.c:252 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "\"%s\"を\"%s\"に書き換えています\n" + +#: relfilenode.c:260 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "\"%s\"から\"%s\"へクローニングしています\n" + +#: relfilenode.c:265 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "\"%s\"を\"%s\"にコピーしています\n" + +#: relfilenode.c:270 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "\"%s\"から\"%s\"へリンクを作成しています\n" + +#: server.c:33 +#, c-format +msgid "connection to database failed: %s" +msgstr "データベースへの接続に失敗しました: %s" + +#: server.c:39 server.c:141 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "失敗しました、終了しています\n" + +#: server.c:131 +#, c-format +msgid "executing: %s\n" +msgstr "実行中: %s\n" + +#: server.c:137 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL コマンドが失敗しました\n" +"%s\n" +"%s" + +#: server.c:167 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "バージョンファイル\"%s\"をオープンできませんでした: %m\n" + +#: server.c:171 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "バージョンファイル\"%s\"をパースできませんでした\n" + +#: server.c:297 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"データベースへの接続に失敗しました: %s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"以下のコマンドで起動した移行元postmasterに接続できませんでした:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"以下のコマンドで起動した移行先postmasterに接続できませんでした:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl が移行元サーバの起動に失敗した、あるいは接続に失敗しました\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl が移行先サーバの起動に失敗した、あるいは接続に失敗しました\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "libpq の環境変数 %s で、ローカルでないサーバ値が設定されています: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"テーブル空間を使用する場合、\n" +"同一のバージョンのシステムカタログ同士でアップグレードすることができません。\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "テーブル空間のディレクトリ\"%s\"が存在しません\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "テーブル空間のディレクトリ\"%s\"を stat できませんでした: %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "テーブル空間のパス\"%s\"がディレクトリではありません。\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "ラージオブジェクトをチェックしています" + +#: version.c:77 version.c:384 +#, c-format +msgid "warning" +msgstr "警告" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"環境にラージオブジェクトが含まれています。新しいデータベースでは\n" +"ラージオブジェクトのパーミッションテーブルが追加されています。\n" +"アップグレードが終わったら、 pg_largeobject_metadata テーブルに\n" +"デフォルトのパーミッションを投入するためのコマンドが案内されます。\n" +"\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"環境にラージオブジェクトが含まれています。新しいデータベースでは\n" +"ラージオブジェクトのパーミッションテーブルが追加されており、すべてのラージ\n" +"オブジェクトについて、デフォルトのパーミッションを定義する必要があります。\n" +"以下のファイルをpsqlでデータベースのスーパユーザとして実行することで\n" +"デフォルトパーミッションを設定します。\n" +" %s\n" +"\n" + +#: version.c:239 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "非互換の \"line\" データ型を確認しています" + +#: version.c:246 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"移行元の環境のユーザテーブルに\"line\"データ型が含まれています。\n" +"このデータ型は新旧のクラスタ間で内部形式や入出力フォーマットが\n" +"変更されているため、このクラスタは現時点ではアップグレードできません。\n" +"問題のテーブルを削除してから、再度アップグレードを実行してください。\n" +"問題のある列の一覧は、以下のファイルにあります: \n" +" %s\n" +"\n" + +#: version.c:276 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "無効な \"unknown\" ユーザ列をチェックしています" + +#: version.c:283 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"環境のユーザテーブルに \"unknown\" データ型が含まれています。\n" +"このデータ型はもはやテーブル内では利用できないため、このクラスタは現時点\n" +"ではアップグレードできません。問題のテーブルを削除したのち、アップグレードを\n" +"再実行できます。\n" +"問題のある列の一覧は、以下のファイルにあります: \n" +" %s\n" +"\n" + +#: version.c:306 +#, c-format +msgid "Checking for hash indexes" +msgstr "ハッシュインデックスをチェックしています" + +#: version.c:386 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"環境にハッシュインデックスがあります。このインデックスは新旧のクラスタ間で\n" +"フォーマットが異なるため、REINDEX コマンドを使って再構築する必要があります。\n" +"アップグレードが終わったら、REINDEX を使った操作方法が表示されます。\n" +"\n" + +#: version.c:392 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"環境にハッシュインデックスがあります。このインデックスは新旧のクラスタ間でフォーマットが\n" +"異なるため、REINDEX コマンドを使って再構築する必要があります。以下のファイル\n" +" %s\n" +"を、psqlを使用してデータベースのスーパユーザとして実行することで、無効になった\n" +"インデックスを再構築できます。\n" +"それまでは、これらのインデックスは使用されません。\n" +"\n" + +#: version.c:418 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "無効な \"sql_identifier\" ユーザ列を確認しています" + +#: version.c:426 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables\n" +"and/or indexes. The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can remove the problem tables or\n" +"change the data type to \"name\" and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"あなたのインストールでは”sql_identifier”データ型がユーザテーブルまたは/および\n" +"インデックスに含まれています。このデータ型のディスク上での形式は変更されてい\n" +"ます。問題のあるテーブルを削除するか、データ型を\"name\"に変更してからアップ\n" +"グレードを再実行することができます。\n" +"問題のある列の一覧は、以下のファイルにあります: \n" +" %s\n" +"\n" + +#~ msgid "could not parse PG_VERSION file from %s\n" +#~ msgstr "%s から PG_VERSION ファイルを読み取れませんでした。\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "不具合は まで報告してください。\n" diff --git a/src/bin/pg_upgrade/po/ko.po b/src/bin/pg_upgrade/po/ko.po new file mode 100644 index 000000000000..5fa498a22035 --- /dev/null +++ b/src/bin/pg_upgrade/po/ko.po @@ -0,0 +1,1889 @@ +# LANGUAGE message translation file for pg_upgrade +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:45+0000\n" +"PO-Revision-Date: 2020-10-06 14:02+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: check.c:66 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"옛 운영 서버에서 일관성 검사를 진행합니다.\n" +"------------------------------------------\n" + +#: check.c:72 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"일관성 검사 수행중\n" +"------------------\n" + +#: check.c:190 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*클러스터 호환성*\n" + +#: check.c:196 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"여기서 pg_upgrade 작업을 실패한다면, 재시도 하기 전에 먼저\n" +"새 클러스터를 처음부터 다시 만들어 진행해야 합니다.\n" + +#: check.c:232 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"pg_upgrade 작업에서는 최적화기를 위한 통계 정보까지 업그레이드\n" +"하지는 않습니다. 새 서버가 실행 될 때, 다음 명령을 수행하길 권합니다:\n" +" %s\n" +"\n" + +#: check.c:237 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"pg_upgrade 작업으로는 통계 정보와 빈 공간 정보는 업그레이드 되지\n" +"않습니다. 새 서버가 실행 될 때, 다음 명령을 수행하길 권합니다:\n" +" %s\n" +"\n" + +#: check.c:244 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"아래 스크립트를 실행하면, 옛 클러스터 자료를 지울 것입니다:\n" +" %s\n" + +#: check.c:249 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"옛 클러스터 자료 파일을 지우는 스크립트를 만들지 못했습니다.\n" +"사용자 정의 테이블스페이스나, 새 클러스터가 옛 클러스터 안에\n" +"있기 때문입니다. 옛 클러스터 자료는 직접 찾아서 지우세요.\n" + +#: check.c:259 +#, c-format +msgid "Checking cluster versions" +msgstr "클러스터 버전 검사 중" + +#: check.c:271 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "이 도구는 PostgreSQL 8.4 이상 버전에서 사용할 수 있습니다.\n" + +#: check.c:275 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "이 도구는 PostgreSQL %s 버전으로만 업그레이드 할 수 있습니다.\n" + +#: check.c:284 +#, c-format +msgid "" +"This utility cannot be used to downgrade to older major PostgreSQL " +"versions.\n" +msgstr "" +"이 도구는 더 낮은 메이져 PostgreSQL 버전으로 다운그레이드하는데 사용할 수 없" +"습니다.\n" + +#: check.c:289 +#, c-format +msgid "" +"Old cluster data and binary directories are from different major versions.\n" +msgstr "옛 클러스터 자료와 실행파일 디렉터리가 서로 메이져 버전이 다릅니다.\n" + +#: check.c:292 +#, c-format +msgid "" +"New cluster data and binary directories are from different major versions.\n" +msgstr "새 클러스터 자료와 실행파일 디렉터리가 서로 메이져 버전이 다릅니다.\n" + +#: check.c:309 +#, c-format +msgid "" +"When checking a pre-PG 9.1 live old server, you must specify the old " +"server's port number.\n" +msgstr "" +"옛 서버가 9.1 버전 이전 이라면 옛 서버의 포트를 반드시 지정해야 합니다.\n" + +#: check.c:313 +#, c-format +msgid "" +"When checking a live server, the old and new port numbers must be " +"different.\n" +msgstr "" +"운영 서버 검사를 할 때는, 옛 서버, 새 서버의 포트를 다르게 지정해야 합니다.\n" + +#: check.c:328 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"\"%s\" 데이터베이스의 인코딩이 서로 다릅니다: 옛 서버 \"%s\", 새 서버 \"%s" +"\"\n" + +#: check.c:333 +#, c-format +msgid "" +"lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"\"%s\" 데이터베이스의 lc_collate 값이 서로 다릅니다: 옛 서버 \"%s\", 새 서버 " +"\"%s\"\n" + +#: check.c:336 +#, c-format +msgid "" +"lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"\"%s\" 데이터베이스의 lc_ctype 값이 서로 다릅니다: 옛 서버 \"%s\", 새 서버 " +"\"%s\"\n" + +#: check.c:409 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "" +"\"%s\" 새 데이터베이스 클러스터가 비어있지 않습니다.\n" +" -- \"%s.%s\" 릴레이션을 찾았음\n" + +#: check.c:458 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "새 클러스터 통계정보 수집 스크립트를 만듭니다" + +#: check.c:472 check.c:600 check.c:864 check.c:943 check.c:1053 check.c:1144 +#: file.c:336 function.c:240 option.c:497 version.c:54 version.c:199 +#: version.c:341 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "\"%s\" 파일을 열 수 없음: %s\n" + +#: check.c:527 check.c:656 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "\"%s\" 파일에 실행 권한을 추가 할 수 없음: %s\n" + +#: check.c:563 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e." +"g. %s\n" +msgstr "" +"\n" +"경고: 새 데이터 디렉터리는 옛 데이터 디렉터리 안에 둘 수 없습니다, 예: %s\n" + +#: check.c:587 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data " +"directory, e.g. %s\n" +msgstr "" +"\n" +"경고: 사용자 정의 테이블스페이스 위치를 데이터 디렉터리 안에 둘 수 없습니다, " +"예: %s\n" + +#: check.c:597 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "옛 클러스터를 지우는 스크립트를 만듭니다" + +#: check.c:676 +#, c-format +msgid "Checking database user is the install user" +msgstr "데이터베이스 사용자가 설치 작업을 한 사용자인지 확인합니다" + +#: check.c:692 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "\"%s\" 데이터베이스 사용자는 설치 작업을 한 사용자가 아닙니다\n" + +#: check.c:703 +#, c-format +msgid "could not determine the number of users\n" +msgstr "사용자 수를 확인할 수 없음\n" + +#: check.c:711 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "새 클러스터에서만 설치 사용 사용자가 정의될 수 있음\n" + +#: check.c:731 +#, c-format +msgid "Checking database connection settings" +msgstr "데이터베이스 연결 설정을 확인 중" + +#: check.c:753 +#, c-format +msgid "" +"template0 must not allow connections, i.e. its pg_database.datallowconn must " +"be false\n" +msgstr "" +"template0 데이터베이스 접속을 금지해야 합니다. 예: 해당 데이터베이스의 " +"pg_database.datallowconn 값이 false여야 합니다.\n" + +#: check.c:763 +#, c-format +msgid "" +"All non-template0 databases must allow connections, i.e. their pg_database." +"datallowconn must be true\n" +msgstr "" +"template0 데이터베이스를 제외한 다른 모든 데이터베이스는 접속이 가능해야합니" +"다. 예: 그들의 pg_database.datallowconn 값은 true여야 합니다.\n" + +#: check.c:788 +#, c-format +msgid "Checking for prepared transactions" +msgstr "미리 준비된 트랜잭션을 확인 중" + +#: check.c:797 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "옛 클러스터에 미리 준비된 트랜잭션이 있음\n" + +#: check.c:799 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "새 클러스터에 미리 준비된 트랜잭션이 있음\n" + +#: check.c:825 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "contrib/isn 모듈의 bigint 처리가 서로 같은지 확인 중" + +#: check.c:886 check.c:965 check.c:1076 check.c:1167 function.c:262 +#: version.c:245 version.c:282 version.c:425 +#, c-format +msgid "fatal\n" +msgstr "치명적 오류\n" + +#: check.c:887 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"설치되어 있는 \"contrib/isn\" 모듈은 bigint 자료형을 사용합니다.\n" +"이 bigint 자료형의 처리 방식이 새 버전과 옛 버전 사이 호환성이 없어,\n" +"이 클러스터 업그레이드를 할 수 없습니다. 먼저 수동으로 데이터베이스를 \n" +"덤프하고, 해당 모듈을 삭제하고, 업그레이드 한 뒤 다시 덤프 파일을 이용해\n" +"복원할 수 있습니다. 문제가 있는 함수는 아래 파일 안에 있습니다:\n" +" %s\n" +"\n" + +#: check.c:911 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "WITH OIDS 옵션 있는 테이블 확인 중" + +#: check.c:966 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"더 이상 WITH OIDS 옵션을 사용하는 테이블을 지원하지 않습니다.\n" +"먼저 oid 칼럼이 있는 기존 테이블을 대상으로 다음 명령을 실행해서\n" +"이 옵션을 뺄 것을 고려해 보십시오.\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"관련 테이블 목록은 아래 파일 안에 있습니다:\n" +" %s\n" +"\n" + +#: check.c:996 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "사용자가 만든 테이블에 reg* 자료형을 쓰는지 확인 중" + +#: check.c:1077 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the\n" +"problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"옛 서버에서 사용자가 만든 테이블에서 reg* 자료형을 사용하고 있습니다.\n" +"이 자료형들은 pg_upgrade 명령으로 내정된 시스템 OID를 사용하지 못할 수\n" +"있습니다. 그래서 업그레이드 작업을 진행할 수 없습니다.\n" +"사용하고 있는 테이블들을 지우고 업그레이드 작업을 다시 시도하세요.\n" +"이런 자료형을 사용하는 칼럼들은 아래 파일 안에 있습니다:\n" +" %s\n" +"\n" + +#: check.c:1102 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "\"jsonb\" 자료형 호환성 확인 중" + +#: check.c:1168 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can remove the problem\n" +"tables and restart the upgrade. A list of the problem columns is\n" +"in the file:\n" +" %s\n" +"\n" +msgstr "" +"사용자 테이블에서 \"jsonb\" 자료형을 사용하고 있습니다.\n" +"9.4 베타 비전 이후 JSONB 내부 자료 구조가 바뀌었습니다.\n" +"그래서, 업그레이드 작업이 불가능합니다.\n" +"해당 테이블들을 지우고 업그레이드 작업을 진행하세요\n" +"해당 자료형을 칼럼들은 아래 파일 안에 있습니다:\n" +" %s\n" +"\n" + +#: check.c:1190 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "\"pg_\"로 시작하는 롤 확인 중" + +#: check.c:1200 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "옛 클러스터에 \"pg_\" 시작하는 롤이 있습니다.\n" + +#: check.c:1202 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "새 클러스터에 \"pg_\"로 시작하는 롤이 있습니다.\n" + +#: check.c:1228 +#, c-format +msgid "failed to get the current locale\n" +msgstr "현재 로케일을 확인 할 수 없음\n" + +#: check.c:1237 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "\"%s\"용 시스템 로케일 이름을 알 수 없음\n" + +#: check.c:1243 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "\"%s\" 옛 로케일을 복원할 수 없음\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "%s 사용하는 컨트롤 자료를 구할 수 없음: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: 데이터베이스 클러스터 상태 문제\n" + +#: controldata.c:156 +#, c-format +msgid "" +"The source cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"원본 클러스터는 복구 모드(대기 서버 모드나, 복구 중) 상태에서 중지 되었습니" +"다. 업그레이드 하려면, 문서에 언급한 것 처럼 \"rsync\"를 사용하든가, 그 서버" +"를 운영 서버 모드로 바꾼 뒤 중지하고 작업하십시오.\n" + +#: controldata.c:158 +#, c-format +msgid "" +"The target cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"대상 클러스터는 복구 모드(대기 서버 모드나, 복구 중) 상태에서 중지 되었습니" +"다. 업그레이드 하려면, 문서에 언급한 것 처럼 \"rsync\"를 사용하든가, 그 서버" +"를 운영 서버 모드로 바꾼 뒤 중지하고 작업하십시오.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "원본 클러스터는 정상적으로 종료되어야 함\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "대상 클러스터는 정상 종료되어야 함\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "원본 클러스터에 클러스터 상태 정보가 없음:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "대상 클러스터에 클러스터 상태 정보가 없음:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:339 pg_upgrade.c:375 +#: relfilenode.c:247 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal 문제\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: controldata 복원 문제\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "옛 클러스터에 필요한 컨트롤 정보가 몇몇 빠져있음:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "새 클러스터에 필요한 컨트롤 정보가 몇몇 빠져있음:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " 체크포인트 다음 XID\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " 마지막 체크포인트 다음 OID\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " 마지막 체크포인트 다음 MultiXactId\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " 마지막 체크포인트 제일 오래된 MultiXactId\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " 마지막 체크포인트 다음 MultiXactOffset\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " 리셋 뒤 첫 WAL 조각\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " float8 인자 처리 방식\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " 최대 정렬\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " 블록 크기\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " 대형 릴레이션 조각 크기\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " WAL 블록 크기\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL 조각 크기\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " 최대 식별자 길이\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " 최대 인덱스 칼럼 수\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " 최대 토스트 조각 크기\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " 대형 객체 조각 크기\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " date/time 자료형을 정수로?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " 자료 체크섬 버전\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "필요한 컨트롤 정보 없이는 진행할 수 없음, 중지 함\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"클러스터간 pg_controldata 정렬이 서로 다릅니다.\n" +"하나는 32비트고, 하나는 64비트인 경우 같습니다\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "클러스터간 pg_controldata 블록 크기가 서로 다릅니다.\n" + +#: controldata.c:630 +#, c-format +msgid "" +"old and new pg_controldata maximum relation segment sizes are invalid or do " +"not match\n" +msgstr "클러스터간 pg_controldata 최대 릴레이션 조각 크가가 서로 다릅니다.\n" + +#: controldata.c:633 +#, c-format +msgid "" +"old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "클러스터간 pg_controldata WAL 블록 크기가 서로 다릅니다.\n" + +#: controldata.c:636 +#, c-format +msgid "" +"old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "클러스터간 pg_controldata WAL 조각 크기가 서로 다릅니다.\n" + +#: controldata.c:639 +#, c-format +msgid "" +"old and new pg_controldata maximum identifier lengths are invalid or do not " +"match\n" +msgstr "클러스터간 pg_controldata 최대 식별자 길이가 서로 다릅니다.\n" + +#: controldata.c:642 +#, c-format +msgid "" +"old and new pg_controldata maximum indexed columns are invalid or do not " +"match\n" +msgstr "클러스터간 pg_controldata 최대 인덱스 칼럼수가 서로 다릅니다.\n" + +#: controldata.c:645 +#, c-format +msgid "" +"old and new pg_controldata maximum TOAST chunk sizes are invalid or do not " +"match\n" +msgstr "클러스터간 pg_controldata 최대 토스트 조각 크기가 서로 다릅니다.\n" + +#: controldata.c:650 +#, c-format +msgid "" +"old and new pg_controldata large-object chunk sizes are invalid or do not " +"match\n" +msgstr "클러스터간 pg_controldata 대형 객체 조각 크기가 서로 다릅니다.\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "클러스터간 pg_controldata date/time 저장 크기가 서로 다릅니다.\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "" +"옛 클러스터는 데이터 체크섬 기능을 사용하지 않고, 새 클러스터는 사용하고 있습" +"니다.\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "" +"옛 클러스터는 데이터 체크섬 기능을 사용하고, 새 클러스터는 사용하고 있지 않습" +"니다.\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "클러스터간 pg_controldata 체크섬 버전이 서로 다릅니다.\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "옛 global/pg_control 파일에 \".old\" 이름을 덧붙입니다." + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "%s 이름을 %s 이름으로 바꿀 수 없음.\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"옛 버전으로 옛 클러스터를 사용해서 서버를 실행하려면,\n" +"%s/global/pg_control.old 파일의 이름을 \".old\" 빼고 바꾸어\n" +"사용해야합니다. 업그레이드를 \"link\" 모드로 했기 때문에,\n" +"한번이라도 새 버전의 서버가 이 클러스터를 이용해서 실행되었다면,\n" +"이 파일이 더 이상 안전하지 않기 때문입니다.\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "전역 객체 덤프를 만듭니다" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "데이터베이스 스키마 덤프를 만듭니다\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "%s 명령을 사용해서 pg_ctl 버전 자료를 구할 수 없음: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "%s에서 pg_ctl 버전을 알 수 없음\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "명령이 너무 긺\n" + +#: exec.c:110 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "\"%s\" 로그 파일을 열 수 없음: %m\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*실패*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "\"%s\" 실행에서 문제 발생\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"\"%s\" 또는 \"%s\" 파일의 마지막 부분을 살펴보면\n" +"이 문제를 풀 실마리가 보일 것입니다.\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"\"%s\" 파일의 마지막 부분을 살펴보면\n" +"이 문제를 풀 실마리가 보일 것입니다.\n" + +#: exec.c:204 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "\"%s\" 로그 파일을 쓸 수 없음: %m\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "\"%s\" 파일을 읽기 위해 열 수 없습니다: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "현재 디렉터리의 읽기 쓰기 권한을 부여하세요.\n" + +#: exec.c:310 exec.c:372 exec.c:436 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "\"%s\" 검사 실패: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" 파일은 디렉터리가 아닙니다.\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "\"%s\" 검사 실패: 일반 파일이 아닙니다\n" + +#: exec.c:451 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "\"%s\" 검사 실패: 해당 파일을 읽을 수 없음 (접근 권한 없음)\n" + +#: exec.c:459 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "\"%s\" 검사 실패: 실행할 수 없음 (접근 권한 없음)\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" (\"%s\" / \"%s\") 릴레이션 클론 중 오류: %s\n" + +#: file.c:50 +#, c-format +msgid "" +"error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레이션 클론 중 오류: \"%s\" 파일을 열 수 없음: %s\n" + +#: file.c:55 +#, c-format +msgid "" +"error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레이션 클론 중 오류: \"%s\" 파일을 만들 수 없음: %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레이션 복사 중 오류: \"%s\" 파일을 열 수 없음: %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레이션 복사 중 오류: \"%s\" 파일을 만들 수 없음: %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레이션 복사 중 오류: \"%s\" 파일을 읽을 수 없음: %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레이션 복사 중 오류: \"%s\" 파일을 쓸 수 없음: %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" (\"%s\" / \"%s\") 릴레이션 복사 중 오류: %s\n" + +#: file.c:151 +#, c-format +msgid "" +"error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" (\"%s\" / \"%s\") 릴레이션 링크 만드는 중 오류: %s\n" + +#: file.c:194 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "" +"\"%s.%s\" 릴레이션 복사 중 오류: \"%s\" 파일 상태 정보를 알 수 없음: %s\n" + +#: file.c:226 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "\"%s.%s\" 릴레이션 복사 중 오류: \"%s\" 파일에 페이지가 손상되었음\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "옛 데이터 디렉터리와 새 데이터 디렉터리 사이 파일 클론 실패: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "\"%s\" 파일을 만들 수 없음: %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "이 운영체제는 파일 클론 기능을 제공하지 않습니다.\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file " +"system.\n" +msgstr "" +"데이터 디렉터리간 하드 링크를 만들 수 없음: %s\n" +"하드 링크를 사용하려면, 두 디렉터리가 같은 시스템 볼륨 안에 있어야 합니다.\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"옛 클러스터는 \"plpython_call_handler\" 함수가 \"public\" 스키마 안에\n" +"정의 되어있습니다. 이 함수는 \"pg_catalog\" 스키마 안에 있어야합니다.\n" +"psql에서 다음 명령으로 이 함수의 위치를 살펴 볼 수 있습니다:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"\"public\" 스키마 안에 이 함수가 있는 경우는 8.1 버전 이전 버전이었습니다.\n" +"업그레이드 작업을 정상적으로 마치려면, 먼저 \"plpython\" 관련 객체들을 먼저\n" +"모두 지우고, 새 버전용 모듈을 설치해서 사용해야 합니다.\n" +"이 삭제 작업은 다음과 같이 진행합니다:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"이 작업은 관련 모든 데이터베이스 단위로 진행되어야 합니다.\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "옛 클러스터에서 문제가 있는 함수들을 삭제하고 진행하세요.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "필요한 라이브러리 확인 중" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "\"%s\" 라이브러리 로드 실패: %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "데이터베이스: %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"옛 버전에는 있고, 새 버전에는 없는 라이브러리들이 있습니다. 새 버전에\n" +"해당 라이브러리들을 설치하거나, 옛 버전에서 해당 라이브러리를 삭제하고,\n" +"업그레이드 작업을 해야합니다. 문제가 있는 라이브러리들은 다음과 같습니다:\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "" +"Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s" +"\", new name \"%s.%s\"\n" +msgstr "" +"%u OID에 대한 \"%s\" 데이터베이스 이름이 서로 다릅니다: 옛 이름: \"%s.%s\", " +"새 이름: \"%s.%s\"\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "\"%s\" 데이터베이스 내 테이블 이름이 서로 다릅니다:\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " 해당 인덱스: \"%s.%s\"" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " 해당 인덱스의 OID: %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " \"%s.%s\" 객체의 토스트 테이블" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " 해당 토스트 베이블의 OID: %u" + +#: info.c:274 +#, c-format +msgid "" +"No match found in old cluster for new relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"새 클러스터의 %u OID (해당 데이터베이스: \"%s\")가 옛 클러스터에 없음: %s\n" + +#: info.c:277 +#, c-format +msgid "" +"No match found in new cluster for old relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"옛 클러스터의 %u OID (해당 데이터베이스: \"%s\")가 새 클러스터에 없음: %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "\"%s\" 데이터베이스 맵핑 중:\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u / %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"원본 데이터베이스:\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"대상 데이터베이스:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "데이터베이스: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: root 권한으로 실행할 수 없음\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "잘못된 옛 포트 번호\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "잘못된 새 포트 번호\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 자세한 사용법은 \"%s --help\" 명령을 이용하세요.\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "너무 많은 명령행 인자를 지정 했음 (시작: \"%s\")\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "작업 내역을 자세히 봄\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "옛 클러스터 실행파일 위치" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "새 클러스터 실팽파일 위치" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "옛 클러스터 자료 위치" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "새 클러스터 자료 위치" + +#: option.c:259 +msgid "sockets will be created" +msgstr "소켓 파일 만들 위치" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "현재 디렉터리 위치를 알 수 없음\n" + +#: option.c:279 +#, c-format +msgid "" +"cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "" +"윈도우즈 환경에서는 pg_upgrade 명령은 새 클러스터 데이터 디렉터리 안에서는 실" +"행할 수 없음\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"새 데이터 클러스터 버전과 pg_upgrade 버전의 메이저 버전이 서로 다릅니다.\n" +"\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [옵션]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "옵션:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR 옛 클러스터 실행 파일의 디렉터리\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=BINDIR 새 클러스터 실행 파일의 디렉터리 (기본값:\n" +" pg_upgrade가 있는 디렉터리)\n" + +#: option.c:295 +#, c-format +msgid "" +" -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check 실 작업 없이, 그냥 검사만\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR 옛 클러스터 데이터 디렉터리\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR 새 클러스터 데이터 디렉터리\n" + +#: option.c:298 +#, c-format +msgid "" +" -j, --jobs=NUM number of simultaneous processes or threads " +"to use\n" +msgstr "" +" -j, --jobs=NUM 동시에 작업할 프로세스 또는 쓰레드 수\n" + +#: option.c:299 +#, c-format +msgid "" +" -k, --link link instead of copying files to new " +"cluster\n" +msgstr "" +" -k, --link 새 클러스터 구축을 복사 대신 링크 사용\n" + +#: option.c:300 +#, c-format +msgid "" +" -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=옵션 옛 서버에서 사용할 서버 옵션들\n" + +#: option.c:301 +#, c-format +msgid "" +" -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=옵션 새 서버에서 사용할 서버 옵션들\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT 옛 클러스터 포트 번호 (기본값 %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT 새 클러스터 포트 번호 (기본값 %d)\n" + +#: option.c:304 +#, c-format +msgid "" +" -r, --retain retain SQL and log files after success\n" +msgstr "" +" -r, --retain 작업 완료 후 사용했던 SQL과 로그 파일 남김\n" + +#: option.c:305 +#, c-format +msgid "" +" -s, --socketdir=DIR socket directory to use (default current " +"dir.)\n" +msgstr "" +" -s, --socketdir=DIR 사용할 소켓 디렉터리 (기본값: 현재 디렉터" +"리)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=이름 클러스터 슈퍼유저 (기본값 \"%s\")\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose 작업 내역을 자세히 남김\n" + +#: option.c:308 +#, c-format +msgid "" +" -V, --version display version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: option.c:309 +#, c-format +msgid "" +" --clone clone instead of copying files to new " +"cluster\n" +msgstr "" +" --clone 새 클러스터 구축을 복사 대신 클론 사용\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"pg_upgrade 작업 전에 먼저 해야 할 것들:\n" +" 새 버전의 initdb 명령으로 새 데이터베이스 클러스터를 만들고\n" +" 옛 서버를 중지하고\n" +" 새 서버도 중지하세요.\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"pg_upgrade 작업은 다음 네개의 옵션 값은 반드시 지정해야 함:\n" +" 옛 데이터 클러스터 디렉터리 (-d DATADIR)\n" +" 새 데이터 클러스터 디렉터리 (-D DATADIR)\n" +" 옛 버전의 \"bin\" 디렉터리 (-b BINDIR)\n" +" 새 버전의 \"bin\" 디렉터리 (-B BINDIR)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B " +"newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"사용예:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B " +"newCluster/bin\n" +"or\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"문제점 보고 주소: <%s>\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"%s 위치의 디렉터리를 알고 있어야 함.\n" +"%s 명령행 옵션이나, %s 환경 변수를 사용하세요.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "원본 클러스터용 실 데이터 디렉터리를 찾는 중" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "대상 클러스터용 실 데이터 디렉터리를 찾는 중" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "%s 지정한 데이터 디렉터리를 찾을 수 없음: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "%d 번째 줄을 \"%s\" 파일에서 읽을 수 없음: %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "지정한 %hu 옛 포트 번호를 %hu 번호로 바꿈\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "작업용 프로세스를 만들 수 없음: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "작업용 쓰레드를 만들 수 없음: %s\n" + +#: parallel.c:300 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "waitpid() 실패: %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "하위 작업자가 비정상 종료됨: 상태값 %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "하위 작업자가 비정상 종료됨: %s\n" + +#: pg_upgrade.c:108 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "\"%s\" 디렉터리 읽기 권한 없음: %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"업그레이드 진행 중\n" +"------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "새 클러스터용 다음 OID 설정 중" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "데이터 디렉터리 fsync 작업 중" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"업그레이드 완료\n" +"---------------\n" + +#: pg_upgrade.c:220 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 실행할 프로그램을 찾을 수 없습니다.\n" + +#: pg_upgrade.c:246 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"옛 서버가 현재 운영 되고 있습니다.\n" +"먼저 서버를 중지하고 진행하세요.\n" + +#: pg_upgrade.c:259 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"새 서버가 현재 운영 되고 있습니다.\n" +"먼저 서버를 중지하고 진행하세요.\n" + +#: pg_upgrade.c:273 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "새 클러스터의 모든 로우에 대해서 통계 정보 수집 중" + +#: pg_upgrade.c:286 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "새 클러스터의 모든 로우에 대해서 영구 격리(freeze) 중" + +#: pg_upgrade.c:306 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "새 클러스터에 전역 객체를 복원 중" + +#: pg_upgrade.c:321 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "새 클러스터에 데이터베이스 스키마 복원 중\n" + +#: pg_upgrade.c:425 +#, c-format +msgid "Deleting files from new %s" +msgstr "새 %s에서 파일 지우는 중" + +#: pg_upgrade.c:429 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "\"%s\" 디렉터리를 삭제 할 수 없음\n" + +#: pg_upgrade.c:448 +#, c-format +msgid "Copying old %s to new server" +msgstr "옛 %s 객체를 새 서버로 복사 중" + +#: pg_upgrade.c:475 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "새 클러스터용 다음 트랜잭션 ID와 epoch 값 설정 중" + +#: pg_upgrade.c:505 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "새 클러스터용 다음 멀티 트랜잭션 ID와 위치 값 설정 중" + +#: pg_upgrade.c:529 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "새 클러스터용 제일 오래된 멀티 트랜잭션 ID 설정 중" + +#: pg_upgrade.c:549 +#, c-format +msgid "Resetting WAL archives" +msgstr "WAL 아카이브 재설정 중" + +#: pg_upgrade.c:592 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "새 클러스터에서 frozenxid, minmxid 값 설정 중" + +#: pg_upgrade.c:594 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "새 클러스터에서 minmxid 값 설정 중" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "사용자 릴레이션 파일 클론 중\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "사용자 릴레이션 파일 복사 중\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "사용자 릴레이션 파일 링크 중\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "\"%s\" 이름의 옛 데이터베이스를 새 클러스터에서 찾을 수 없음\n" + +#: relfilenode.c:234 +#, c-format +msgid "" +"error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" (\"%s\" / \"%s\") 파일이 있는지 확인 도중 오류 발생: %s\n" + +#: relfilenode.c:252 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "\"%s\" 객체를 \"%s\" 객체로 다시 쓰는 중\n" + +#: relfilenode.c:260 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "\"%s\" 객체를 \"%s\" 객체로 클론 중\n" + +#: relfilenode.c:265 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "\"%s\" 객체를 \"%s\" 객체로 복사 중\n" + +#: relfilenode.c:270 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "\"%s\" 객체를 \"%s\" 객체로 링크 중\n" + +#: server.c:33 +#, c-format +msgid "connection to database failed: %s" +msgstr "데이터베이스 연결 실패: %s" + +#: server.c:39 server.c:141 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "실패, 종료함\n" + +#: server.c:131 +#, c-format +msgid "executing: %s\n" +msgstr "실행중: %s\n" + +#: server.c:137 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL 명령 실패\n" +"%s\n" +"%s" + +#: server.c:167 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "\"%s\" 버전 파일 열기 실패: %m\n" + +#: server.c:171 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "\"%s\" 버전 파일 구문 분석 실패\n" + +#: server.c:297 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"데이터베이스 연결 실패: %s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"다음 명령으로 실행된 원본 서버로 접속할 수 없음:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"다음 명령으로 실행된 대상 서버로 접속할 수 없음:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "원본 서버를 실행하는 pg_ctl 작업 실패, 또는 연결 실패\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "대상 서버를 실행하는 pg_ctl 작업 실패, 또는 연결 실패\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "%s libpq 환경 변수가 로컬 서버 값이 아님: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"사용자 정의 테이블스페이스를 사용하는 경우 같은 시스템 카탈로그 버전으로\n" +"업그레이드 작업을 진행할 수 없습니다.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "\"%s\" 이름의 테이블스페이스 디렉터리가 없음\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "\"%s\" 테이블스페이스 디렉터리의 상태 정보를 구할 수 없음: %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "\"%s\" 테이블스페이스 경로는 디렉터리가 아님\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "대형 객체 확인 중" + +#: version.c:77 version.c:384 +#, c-format +msgid "warning" +msgstr "경고" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"이 데이터베이스는 대형 객체를 사용하고 있습니다. 새 데이터베이스에서는\n" +"이들의 접근 권한 제어를 위해 추가적인 테이블을 사용합니다. 업그레이드 후\n" +"이 객체들의 접근 권한은 pg_largeobject_metadata 테이블에 기본값으로 지정됩니" +"다.\n" +"\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"이 데이터베이스는 대형 객체를 사용하고 있습니다. 새 데이터베이스에서는\n" +"이들의 접근 권한 제어를 위해 추가적인 테이블을 사용합니다. 그래서\n" +"이들의 접근 권한을 기본값으로 설정하려면,\n" +" %s\n" +"파일을 새 서버가 실행 되었을 때 슈퍼유저 권한으로 psql 명령으로\n" +"실행 하세요.\n" +"\n" + +#: version.c:239 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "\"line\" 자료형 호환성 확인 중" + +#: version.c:246 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"해당 데이터베이스에서 \"line\" 자료형을 사용하는 칼럼이 있습니다.\n" +"이 자료형의 입출력 방식이 옛 버전과 새 버전에서 서로 호환하지 않습니다.\n" +"먼저 이 자료형을 사용하는 테이블을 삭제 후 업그레이드 작업을 하고,\n" +"수동으로 복원 작업을 해야 합니다. 해당 파일들은 다음과 같습니다:\n" +" %s\n" +"\n" + +#: version.c:276 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "잘못된 \"unknown\" 사용자 칼럼을 확인 중" + +#: version.c:283 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"해당 데이터베이스에서 사용자 테이블에서 \"unknown\" 자료형을 사용하고 있습니" +"다.\n" +"이 자료형은 더 이상 사용할 수 없습니다. 이 문제를 옛 버전에서 먼저 정리하고\n" +"업그레이드 작업을 진행하세요. 해당 파일은 다음과 같습니다:\n" +" %s\n" +"\n" + +#: version.c:306 +#, c-format +msgid "Checking for hash indexes" +msgstr "해쉬 인덱스 확인 중" + +#: version.c:386 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"해당 데이터베이스에서 해쉬 인덱스를 사용하고 있습니다. 해쉬 인덱스 자료구조" +"가\n" +"새 버전에서 호환되지 않습니다. 업그레이드 후에 해당 인덱스들을\n" +"REINDEX 명령으로 다시 만들어야 합니다.\n" +"\n" + +#: version.c:392 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"해당 데이터베이스에서 해쉬 인덱스를 사용하고 있습니다. 해쉬 인덱스 자료구조" +"가\n" +"새 버전에서 호환되지 않습니다. 업그레이드 후 다음 파일을\n" +"슈퍼유저 권한으로 실행한 psql에서 실행해서, REINDEX 작업을 진행하세요:\n" +" %s\n" +"이 작업이 있기 전까지는 해당 인덱스는 invalid 상태로 사용할 수 없게 됩니다.\n" +"\n" + +#: version.c:418 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "잘못된 \"sql_identifier\" 사용자 칼럼을 확인 중" + +#: version.c:426 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables\n" +"and/or indexes. The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can remove the problem tables or\n" +"change the data type to \"name\" and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"사용자 테이블 또는/이나 인덱스에 \"sql_identifier\" 자료형을 사용하고\n" +"있습니다. 이 자료형의 저장 양식이 바뀌었기에, 이 클러스터는 업그레이드\n" +"되어야합니다. 해당 테이블을 지우거나, 해당 칼럼의 자료형을 \"name\" 형으로\n" +"바꾸고, 서버를 재실행 한 뒤 업그레이드 하십시오.\n" +"문제의 칼럼이 있는 파일들은 다음과 같습니다:\n" +" %s\n" +"\n" diff --git a/src/bin/pg_upgrade/po/ru.po b/src/bin/pg_upgrade/po/ru.po new file mode 100644 index 000000000000..fbb84a3b3759 --- /dev/null +++ b/src/bin/pg_upgrade/po/ru.po @@ -0,0 +1,2040 @@ +# Russian message translation file for pg_upgrade +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Alexander Lakhin , 2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-11-09 07:34+0300\n" +"PO-Revision-Date: 2020-11-09 08:34+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: check.c:67 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Проверка целостности на старом работающем сервере\n" +"-------------------------------------------------\n" + +#: check.c:73 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Проведение проверок целостности\n" +"-------------------------------\n" + +#: check.c:193 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Кластеры совместимы*\n" + +#: check.c:199 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Если работа pg_upgrade после этого прервётся, вы должны заново выполнить " +"initdb\n" +"для нового кластера, чтобы продолжить.\n" + +#: check.c:233 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Статистика оптимизатора утилитой pg_upgrade не переносится, поэтому\n" +"запустив новый сервер, имеет смысл выполнить:\n" +" %s\n" +"\n" + +#: check.c:239 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"При запуске этого скрипта будут удалены файлы данных старого кластера:\n" +" %s\n" + +#: check.c:244 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Не удалось создать скрипт для удаления файлов данных старого кластера,\n" +"так как каталог старого кластера содержит пользовательские табличные\n" +"пространства или каталог данных нового кластера.\n" +"Содержимое старого кластера нужно будет удалить вручную.\n" + +#: check.c:254 +#, c-format +msgid "Checking cluster versions" +msgstr "Проверка версий кластеров" + +#: check.c:266 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "" +"Эта утилита может производить обновление только с версии PostgreSQL 8.4 и " +"новее.\n" + +#: check.c:270 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Эта утилита может только повышать версию PostgreSQL до %s.\n" + +#: check.c:279 +#, c-format +msgid "" +"This utility cannot be used to downgrade to older major PostgreSQL " +"versions.\n" +msgstr "" +"Эта утилита не может понижать версию до более старой основной версии " +"PostgreSQL.\n" + +#: check.c:284 +#, c-format +msgid "" +"Old cluster data and binary directories are from different major versions.\n" +msgstr "" +"Каталоги данных и исполняемых файлов старого кластера относятся к разным " +"основным версиям.\n" + +#: check.c:287 +#, c-format +msgid "" +"New cluster data and binary directories are from different major versions.\n" +msgstr "" +"Каталоги данных и исполняемых файлов нового кластера относятся к разным " +"основным версиям.\n" + +#: check.c:304 +#, c-format +msgid "" +"When checking a pre-PG 9.1 live old server, you must specify the old " +"server's port number.\n" +msgstr "" +"Для проверки старого работающего сервера версии до 9.1 необходимо указать " +"номер порта этого сервера.\n" + +#: check.c:308 +#, c-format +msgid "" +"When checking a live server, the old and new port numbers must be " +"different.\n" +msgstr "" +"Для проверки работающего сервера новый номер порта должен отличаться от " +"старого.\n" + +#: check.c:323 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"кодировки в базе данных \"%s\" различаются: старая - \"%s\", новая - \"%s" +"\"\n" + +#: check.c:328 +#, c-format +msgid "" +"lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"значения lc_collate в базе данных \"%s\" различаются: старое - \"%s\", " +"новое - \"%s\"\n" + +#: check.c:331 +#, c-format +msgid "" +"lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"значения lc_ctype в базе данных \"%s\" различаются: старое - \"%s\", новое " +"- \"%s\"\n" + +#: check.c:404 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "" +"Новая база данных кластера \"%s\" не пустая: найдено отношение \"%s.%s\"\n" + +#: check.c:453 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Создание скрипта для анализа нового кластера" + +#: check.c:467 check.c:626 check.c:890 check.c:969 check.c:1079 check.c:1170 +#: file.c:336 function.c:240 option.c:497 version.c:54 version.c:199 +#: version.c:341 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "не удалось открыть файл \"%s\": %s\n" + +#: check.c:515 check.c:682 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "не удалось добавить право выполнения для файла \"%s\": %s\n" + +#: check.c:545 +#, c-format +msgid "Checking for new cluster tablespace directories" +msgstr "Проверка каталогов табличных пространств в новом кластере" + +#: check.c:556 +#, c-format +msgid "new cluster tablespace directory already exists: \"%s\"\n" +msgstr "" +"каталог табличного пространства в новом кластере уже существует: \"%s\"\n" + +#: check.c:589 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e." +"g. %s\n" +msgstr "" +"\n" +"ПРЕДУПРЕЖДЕНИЕ: новый каталог данных не должен располагаться внутри старого " +"каталога данных, то есть, в %s\n" + +#: check.c:613 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data " +"directory, e.g. %s\n" +msgstr "" +"\n" +"ПРЕДУПРЕЖДЕНИЕ: пользовательские табличные пространства не должны " +"располагаться внутри каталога данных, то есть, в %s\n" + +#: check.c:623 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Создание скрипта для удаления старого кластера" + +#: check.c:702 +#, c-format +msgid "Checking database user is the install user" +msgstr "Проверка, является ли пользователь БД стартовым пользователем" + +#: check.c:718 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "пользователь БД \"%s\" не является стартовым пользователем\n" + +#: check.c:729 +#, c-format +msgid "could not determine the number of users\n" +msgstr "не удалось определить количество пользователей\n" + +#: check.c:737 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "В новом кластере может быть определён только стартовый пользователь.\n" + +#: check.c:757 +#, c-format +msgid "Checking database connection settings" +msgstr "Проверка параметров подключения к базе данных" + +#: check.c:779 +#, c-format +msgid "" +"template0 must not allow connections, i.e. its pg_database.datallowconn must " +"be false\n" +msgstr "" +"База template0 не должна допускать подключения, то есть её свойство " +"pg_database.datallowconn должно быть false\n" + +#: check.c:789 +#, c-format +msgid "" +"All non-template0 databases must allow connections, i.e. their pg_database." +"datallowconn must be true\n" +msgstr "" +"Все базы, кроме template0, должны допускать подключения, то есть их свойство " +"pg_database.datallowconn должно быть true\n" + +#: check.c:814 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Проверка наличия подготовленных транзакций" + +#: check.c:823 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Исходный кластер содержит подготовленные транзакции\n" + +#: check.c:825 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Целевой кластер содержит подготовленные транзакции\n" + +#: check.c:851 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Проверка несоответствия при передаче bigint в contrib/isn" + +#: check.c:912 check.c:991 check.c:1102 check.c:1193 function.c:262 +#: version.c:245 version.c:282 version.c:425 +#, c-format +msgid "fatal\n" +msgstr "сбой\n" + +#: check.c:913 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции имеются функции \"contrib/isn\", задействующие тип " +"biging.\n" +"Однако в новом кластере значения bigint передаётся не так, как в старом,\n" +"так что обновление кластера в текущем состоянии невозможно. Вы можете\n" +"вручную выгрузить базы данных, где используется функциональность \"contrib/" +"isn\",\n" +"или удалить \"contrib/isn\" из старого кластера и перезапустить обновление. " +"Список\n" +"проблемных функций приведён в файле:\n" +" %s\n" +"\n" + +#: check.c:937 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Проверка таблиц со свойством WITH OIDS" + +#: check.c:992 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции содержатся таблицы со свойством WITH OIDS, которое " +"теперь\n" +"не поддерживается. Отказаться от использования столбцов oid можно так:\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Список проблемных таблиц приведён в файле:\n" +" %s\n" +"\n" + +#: check.c:1022 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Проверка типов данных reg* в пользовательских таблицах" + +#: check.c:1103 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the\n" +"problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции пользовательские таблицы содержат один из типов reg*.\n" +"Эти типы данных ссылаются на системные OID, которые не сохраняются утилитой\n" +"pg_upgrade, так что обновление кластера в текущем состоянии невозможно. Вы\n" +"можете удалить проблемные таблицы и перезапустить обновление. Список " +"проблемных\n" +"столбцов приведён в файле:\n" +" %s\n" +"\n" + +#: check.c:1128 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Проверка несовместимого типа данных \"jsonb\"" + +#: check.c:1194 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can remove the problem\n" +"tables and restart the upgrade. A list of the problem columns is\n" +"in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции таблицы используют тип данных jsonb.\n" +"Внутренний формат \"jsonb\" изменился в версии 9.4 beta, поэтому обновить " +"кластер\n" +"в текущем состоянии невозможно. Вы можете удалить проблемные таблицы и\n" +"перезапустить обновление. Список проблемных столбцов приведён в файле:\n" +" %s\n" +"\n" + +#: check.c:1216 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Проверка ролей с именами, начинающимися с \"pg_\"" + +#: check.c:1226 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "В исходном кластере есть роли, имена которых начинаются с \"pg_\"\n" + +#: check.c:1228 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "В целевом кластере есть роли, имена которых начинаются с \"pg_\"\n" + +#: check.c:1254 +#, c-format +msgid "failed to get the current locale\n" +msgstr "не удалось получить текущую локаль\n" + +#: check.c:1263 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "не удалось получить системное имя локали для \"%s\"\n" + +#: check.c:1269 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "не удалось восстановить старую локаль \"%s\"\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "не удалось получить управляющие данные, выполнив %s: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: недопустимое состояние кластера баз данных\n" + +#: controldata.c:156 +#, c-format +msgid "" +"The source cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"Исходный кластер был отключён в режиме восстановления. Чтобы произвести " +"обновление, используйте документированный способ с rsync или отключите его в " +"режиме главного сервера.\n" + +#: controldata.c:158 +#, c-format +msgid "" +"The target cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"Целевой кластер был отключён в режиме восстановления. Чтобы произвести " +"обновление, используйте документированный способ с rsync или отключите его в " +"режиме главного сервера.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Исходный кластер не был отключён штатным образом.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Целевой кластер не был отключён штатным образом.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "В исходном кластере не хватает информации о состоянии кластера:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "В целевом кластере не хватает информации о состоянии кластера:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:339 pg_upgrade.c:375 +#: relfilenode.c:243 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: проблема с выводом pg_resetwal\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: проблема с получением управляющих данных\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "В исходном кластере не хватает необходимой управляющей информации:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "В целевом кластере не хватает необходимой управляющей информации:\n" + +# skip-rule: capital-letter-first +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " следующий XID последней конт. точки\n" + +# skip-rule: capital-letter-first +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " следующий OID последней конт. точки\n" + +# skip-rule: capital-letter-first +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " следующий MultiXactId последней конт. точки\n" + +# skip-rule: capital-letter-first +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " старейший MultiXactId последней конт. точки\n" + +# skip-rule: capital-letter-first +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " следующий MultiXactOffset последней конт. точки\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " первый сегмент WAL после сброса\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " метод передачи аргумента float8\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " максимальное выравнивание\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " размер блока\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " размер сегмента большого отношения\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " размер блока WAL\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " размер сегмента WAL\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " максимальная длина идентификатора\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " максимальное число столбцов в индексе\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " максимальный размер порции TOAST\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " размер порции большого объекта\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " дата/время представлены целыми числами?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " версия контрольных сумм данных\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "" +"Нет необходимой управляющей информации для продолжения, работа прерывается\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"старое и новое выравнивание в pg_controldata различаются или некорректны\n" +"Вероятно, один кластер установлен в 32-битной системе, а другой ~ в 64-" +"битной\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "" +"старый и новый размер блоков в pg_controldata различаются или некорректны\n" + +#: controldata.c:630 +#, c-format +msgid "" +"old and new pg_controldata maximum relation segment sizes are invalid or do " +"not match\n" +msgstr "" +"старый и новый максимальный размер сегментов отношений в pg_controldata " +"различаются или некорректны\n" + +#: controldata.c:633 +#, c-format +msgid "" +"old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "" +"старый и новый размер блоков WAL в pg_controldata различаются или " +"некорректны\n" + +#: controldata.c:636 +#, c-format +msgid "" +"old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "" +"старый и новый размер сегментов WAL в pg_controldata различаются или " +"некорректны\n" + +#: controldata.c:639 +#, c-format +msgid "" +"old and new pg_controldata maximum identifier lengths are invalid or do not " +"match\n" +msgstr "" +"старая и новая максимальная длина идентификаторов в pg_controldata " +"различаются или некорректны\n" + +#: controldata.c:642 +#, c-format +msgid "" +"old and new pg_controldata maximum indexed columns are invalid or do not " +"match\n" +msgstr "" +"старый и новый максимум числа столбцов, составляющих индексы, в " +"pg_controldata различаются или некорректны\n" + +#: controldata.c:645 +#, c-format +msgid "" +"old and new pg_controldata maximum TOAST chunk sizes are invalid or do not " +"match\n" +msgstr "" +"старый и новый максимальный размер порции TOAST в pg_controldata различаются " +"или некорректны\n" + +#: controldata.c:650 +#, c-format +msgid "" +"old and new pg_controldata large-object chunk sizes are invalid or do not " +"match\n" +msgstr "" +"старый и новый размер порции большого объекта различаются или некорректны\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "" +"старый и новый тип хранения даты/времени в pg_controldata различаются или " +"некорректны\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "" +"в старом кластере не применялись контрольные суммы данных, но в новом они " +"есть\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "" +"в старом кластере применялись контрольные суммы данных, но в новом их нет\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "" +"старая и новая версия контрольных сумм кластера в pg_controldata " +"различаются\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Добавление расширения \".old\" к старому файлу global/pg_control" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Не удалось переименовать %s в %s.\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Если вы захотите запустить старый кластер, вам нужно будет убрать\n" +"расширение \".old\" у файла %s/global/pg_control.old.\n" +"Так как применялся режим \"ссылок\", работа старого кластера\n" +"после того, как будет запущен новый, не гарантируется.\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "Формирование выгрузки глобальных объектов" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Формирование выгрузки схем базы данных\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "не удалось получить данные версии pg_ctl, выполнив %s: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "не удалось получить версию pg_ctl из результата %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "команда слишком длинная\n" + +#: exec.c:110 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "не удалось открыть файл протокола \"%s\": %m\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*ошибка*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "При выполнении \"%s\" возникли проблемы\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Чтобы понять причину ошибки, просмотрите последние несколько строк\n" +"файла \"%s\" или \"%s\".\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Чтобы понять причину ошибки, просмотрите последние несколько строк\n" +"файла \"%s\".\n" + +#: exec.c:204 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "не удалось записать в файл протокола \"%s\": %m\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "не удалось открыть файл \"%s\" для чтения: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "У вас должны быть права на чтение и запись в текущем каталоге.\n" + +#: exec.c:310 exec.c:372 exec.c:436 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "проверка существования \"%s\" не пройдена: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" не является каталогом\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "проверка файла \"%s\" не пройдена: это не обычный файл\n" + +#: exec.c:451 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "" +"проверка файла \"%s\" не пройдена: не удаётся прочитать файл (нет доступа)\n" + +#: exec.c:459 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "" +"проверка файла \"%s\" не пройдена: выполнение невозможно (нет доступа)\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "ошибка при клонировании отношения \"%s.%s\" (из \"%s\" в \"%s\"): %s\n" + +#: file.c:50 +#, c-format +msgid "" +"error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "" +"ошибка при клонировании отношения \"%s.%s\": не удалось открыть файл \"%s\": " +"%s\n" + +#: file.c:55 +#, c-format +msgid "" +"error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "" +"ошибка при клонировании отношения \"%s.%s\": не удалось создать файл \"%s\": " +"%s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "" +"ошибка при копировании отношения \"%s.%s\": не удалось открыть файл \"%s\": " +"%s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "" +"ошибка при копировании отношения \"%s.%s\": не удалось создать файл \"%s\": " +"%s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "" +"ошибка при копировании отношения \"%s.%s\": не удалось прочитать файл \"%s" +"\": %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "" +"ошибка при копировании отношения \"%s.%s\": не удалось записать в файл \"%s" +"\": %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "ошибка при копировании отношения \"%s.%s\" (из \"%s\" в \"%s\"): %s\n" + +#: file.c:151 +#, c-format +msgid "" +"error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "" +"ошибка при создании ссылки для отношения \"%s.%s\" (из \"%s\" в \"%s\"): %s\n" + +#: file.c:194 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "" +"ошибка при копировании отношения \"%s.%s\": не удалось получить информацию о " +"файле \"%s\": %s\n" + +#: file.c:226 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "" +"ошибка при копировании отношения \"%s.%s\": в файле \"%s\" обнаружена " +"неполная страница\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "не удалось клонировать файл из старого каталога данных в новый: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "не удалось создать файл \"%s\": %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "клонирование файлов не поддерживается в этой ОС\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file " +"system.\n" +msgstr "" +"не удалось создать жёсткую ссылку между старым и новым каталогами данных: " +"%s\n" +"В режиме \"ссылок\" старый и новый каталоги данных должны находиться в одной " +"файловой системе.\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"В старом кластере имеется функция \"plpython_call_handler\",\n" +"определённая в схеме \"public\", представляющая собой копию функции,\n" +"определённой в схеме \"pg_catalog\". Вы можете убедиться в этом,\n" +"выполнив в psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"Версия этой функции в схеме \"public\" была создана инсталляцией\n" +"plpython версии до 8.1 и должна быть удалена для завершения процедуры\n" +"pg_upgrade, так как она ссылается на ставший устаревшим\n" +"разделяемый объектный файл \"plpython\". Вы можете удалить версию этой " +"функции\n" +"из схемы \"public\", выполнив следующую команду:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"в каждой затронутой базе данных:\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Удалите проблемные функции из старого кластера для продолжения.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Проверка наличия требуемых библиотек" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "загрузить библиотеку \"%s\" не удалось: %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "В базе данных: %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции есть ссылки на загружаемые библиотеки, отсутствующие\n" +"в новой инсталляции. Вы можете добавить эти библиотеки в новую инсталляцию\n" +"или удалить функции, использующие их, из старой. Список проблемных\n" +"библиотек приведён в файле:\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "" +"Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s" +"\", new name \"%s.%s\"\n" +msgstr "" +"Имена отношения с OID %u в базе данных \"%s\" различаются: старое имя - \"%s." +"%s\", новое - \"%s.%s\"\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Не удалось сопоставить старые таблицы с новыми в базе данных \"%s\"\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " это индекс в \"%s.%s\"" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " это индекс в отношении с OID %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " это TOAST-таблица для \"%s.%s\"" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " это TOAST-таблица для отношения с OID %u" + +#: info.c:274 +#, c-format +msgid "" +"No match found in old cluster for new relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"В старом кластере не нашлось соответствия для нового отношения с OID %u в " +"базе данных \"%s\": %s\n" + +#: info.c:277 +#, c-format +msgid "" +"No match found in new cluster for old relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"В новом кластере не нашлось соответствия для старого отношения с OID %u в " +"базе данных \"%s\": %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "отображения для базы данных \"%s\":\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u в %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"исходные базы данных:\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"целевые базы данных:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "База данных: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "имя_отношения: %s.%s: oid_отношения: %u табл_пространство: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: программу не должен запускать root\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "неверный старый номер порта\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "неверный новый номер порта\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "слишком много аргументов командной строки (первый: \"%s\")\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Программа запущена в режиме подробных сообщений\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "расположение исполняемых файлов старого кластера" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "расположение исполняемых файлов нового кластера" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "расположение данных старого кластера" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "расположение данных нового кластера" + +#: option.c:259 +msgid "sockets will be created" +msgstr "расположение сокетов" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "не удалось определить текущий каталог\n" + +#: option.c:279 +#, c-format +msgid "" +"cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "" +"в Windows нельзя запустить pg_upgrade внутри каталога данных нового " +"кластера\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade обновляет кластер PostgreSQL до другой основной версии.\n" +"\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [ПАРАМЕТР]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "Параметры:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr "" +" -b, --old-bindir=КАТ_BIN каталог исполняемых файлов старого кластера\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=КАТ_BIN каталог исполняемых файлов нового кластера\n" +" (по умолчанию каталог программы pg_upgrade)\n" + +#: option.c:295 +#, c-format +msgid "" +" -c, --check check clusters only, don't change any data\n" +msgstr "" +" -c, --check только проверить кластеры, не меняя никакие " +"данные\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=КАТ_DATA каталог данных старого кластера\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=КАТ_DATA каталог данных нового кластера\n" + +#: option.c:298 +#, c-format +msgid "" +" -j, --jobs=NUM number of simultaneous processes or threads " +"to use\n" +msgstr "" +" -j, --jobs=ЧИСЛО число одновременно используемых процессов " +"или\n" +" потоков\n" + +#: option.c:299 +#, c-format +msgid "" +" -k, --link link instead of copying files to new " +"cluster\n" +msgstr "" +" -k, --link устанавливать ссылки вместо копирования " +"файлов\n" +" в новый кластер\n" + +#: option.c:300 +#, c-format +msgid "" +" -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr "" +" -o, --old-options=ПАРАМЕТРЫ параметры старого кластера, передаваемые " +"серверу\n" + +#: option.c:301 +#, c-format +msgid "" +" -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr "" +" -O, --new-options=ПАРАМЕТРЫ параметры нового кластера, передаваемые " +"серверу\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr "" +" -p, --old-port=ПОРТ номер порта старого кластера (по умолчанию " +"%d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr "" +" -P, --new-port=ПОРТ номер порта нового кластера (по умолчанию " +"%d)\n" + +#: option.c:304 +#, c-format +msgid "" +" -r, --retain retain SQL and log files after success\n" +msgstr "" +" -r, --retain сохранить файлы журналов и SQL в случае " +"успеха\n" + +#: option.c:305 +#, c-format +msgid "" +" -s, --socketdir=DIR socket directory to use (default current " +"dir.)\n" +msgstr "" +" -s, --socketdir=КАТАЛОГ каталог сокетов (по умолчанию текущий)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr "" +" -U, --username=ИМЯ суперпользователь кластера (по умолчанию \"%s" +"\")\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr "" +" -v, --verbose включить вывод подробных внутренних " +"сообщений\n" + +#: option.c:308 +#, c-format +msgid "" +" -V, --version display version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: option.c:309 +#, c-format +msgid "" +" --clone clone instead of copying files to new " +"cluster\n" +msgstr "" +" --clone клонировать, а не копировать файлы в новый " +"кластер\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"До запуска pg_upgrade вы должны:\n" +" создать новый кластер баз данных (используя новую версию initdb)\n" +" остановить процесс postmaster, обслуживающий старый кластер\n" +" остановить процесс postmaster, обслуживающий новый кластер\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"Запуская pg_upgrade, вы должны указать:\n" +" путь к каталогу данных старого кластера (-d КАТ_ДАННЫХ)\n" +" путь к каталогу данных нового кластера (-D КАТ_ДАННЫХ)\n" +" путь к каталогу \"bin\" старой версии (-b КАТ_BIN)\n" +" путь к каталогу \"bin\" новой версии (-B КАТ_BIN)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B " +"newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Например:\n" +" pg_upgrade -d старый_кластер/data -D новый_кластер/data -b старый_кластер/" +"bin -B новый_кластер/bin\n" +"или\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=старый_кластер/data\n" +" $ export PGDATANEW=новый_кластер/data\n" +" $ export PGBINOLD=старый_кластер/bin\n" +" $ export PGBINNEW=новый_кластер/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=старый_кластер/data\n" +" C:\\> set PGDATANEW=новый_кластер/data\n" +" C:\\> set PGBINOLD=старый_кластер/bin\n" +" C:\\> set PGBINNEW=новый_кластер/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Вы должны указать каталог, где находится %s.\n" +"Воспользуйтесь для этого ключом командной строки %s или переменной окружения " +"%s.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Поиск фактического каталога данных для исходного кластера" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Поиск фактического каталога данных для целевого кластера" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "не удалось получить каталог данных, выполнив %s: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "не удалось прочитать строку %d из файла \"%s\": %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "заданный пользователем старый номер порта %hu изменён на %hu\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "не удалось создать рабочий процесс: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "не удалось создать рабочий поток: %s\n" + +#: parallel.c:300 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "сбой waitpid(): %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "дочерний процесс завершился нештатно с ошибкой %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "дочерний процесс завершился аварийно: %s\n" + +#: pg_upgrade.c:108 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "не удалось считать права на каталог \"%s\": %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Выполнение обновления\n" +"---------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Установка следующего OID для нового кластера" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "Синхронизация каталога данных с ФС" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Обновление завершено\n" +"--------------------\n" + +#: pg_upgrade.c:220 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: не удалось найти свой исполняемый файл\n" + +#: pg_upgrade.c:246 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Видимо, запущен процесс postmaster, обслуживающий старый кластер.\n" +"Остановите его и попробуйте ещё раз.\n" + +#: pg_upgrade.c:259 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Видимо, запущен процесс postmaster, обслуживающий новый кластер.\n" +"Остановите его и попробуйте ещё раз.\n" + +#: pg_upgrade.c:273 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Анализ всех строк в новом кластере" + +#: pg_upgrade.c:286 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Замораживание всех строк в новом кластере" + +#: pg_upgrade.c:306 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Восстановление глобальных объектов в новом кластере" + +#: pg_upgrade.c:321 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Восстановление схем баз данных в новом кластере\n" + +#: pg_upgrade.c:425 +#, c-format +msgid "Deleting files from new %s" +msgstr "Удаление файлов из нового каталога %s" + +#: pg_upgrade.c:429 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "ошибка при удалении каталога \"%s\"\n" + +#: pg_upgrade.c:448 +#, c-format +msgid "Copying old %s to new server" +msgstr "Копирование старого каталога %s на новый сервер" + +#: pg_upgrade.c:475 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "" +"Установка следующего идентификатора транзакции и эпохи для нового кластера" + +#: pg_upgrade.c:505 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "" +"Установка следующего идентификатора и смещения мультитранзакции для нового " +"кластера" + +#: pg_upgrade.c:529 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Установка старейшего идентификатора мультитранзакции в новом кластере" + +#: pg_upgrade.c:549 +#, c-format +msgid "Resetting WAL archives" +msgstr "Сброс архивов WAL" + +#: pg_upgrade.c:592 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Установка счётчиков frozenxid и minmxid в новом кластере" + +#: pg_upgrade.c:594 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Установка счётчика minmxid в новом кластере" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Клонирование файлов пользовательских отношений\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "Копирование файлов пользовательских отношений\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "Подключение файлов пользовательских отношений ссылками\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "старая база данных \"%s\" не найдена в новом кластере\n" + +#: relfilenode.c:230 +#, c-format +msgid "" +"error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "" +"ошибка при проверке существования файла отношения \"%s.%s\" (перенос \"%s\" " +"в \"%s\"): %s\n" + +#: relfilenode.c:248 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "переписывание \"%s\" в \"%s\"\n" + +#: relfilenode.c:256 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "клонирование \"%s\" в \"%s\"\n" + +#: relfilenode.c:261 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "копирование \"%s\" в \"%s\"\n" + +#: relfilenode.c:266 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "создание ссылки на \"%s\" в \"%s\"\n" + +#: server.c:33 +#, c-format +msgid "connection to database failed: %s" +msgstr "не удалось подключиться к базе: %s" + +#: server.c:39 server.c:141 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "Ошибка, выполняется выход\n" + +#: server.c:131 +#, c-format +msgid "executing: %s\n" +msgstr "выполняется: %s\n" + +#: server.c:137 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"Ошибка SQL-команды\n" +"%s\n" +"%s" + +#: server.c:167 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "не удалось открыть файл с версией \"%s\": %m\n" + +#: server.c:171 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "не удалось разобрать файл с версией \"%s\"\n" + +#: server.c:297 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"не удалось подключиться к базе: %s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"не удалось подключиться к главному процессу исходного сервера, запущенному " +"командой:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"не удалось подключиться к главному процессу целевого сервера, запущенному " +"командой:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "" +"программа pg_ctl не смогла запустить исходный сервер, либо к нему не удалось " +"подключиться\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "" +"программа pg_ctl не смогла запустить целевой сервер, либо к нему не удалось " +"подключиться\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "в переменной окружения для libpq %s задано не локальное значение: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"Обновление в рамках одной версии системного каталога невозможно,\n" +"если используются табличные пространства.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "каталог табличного пространства \"%s\" не существует\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "" +"не удалось получить информацию о каталоге табличного пространства \"%s\": " +"%s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "путь табличного пространства \"%s\" не указывает на каталог\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "Проверка больших объектов" + +#: version.c:77 version.c:384 +#, c-format +msgid "warning" +msgstr "предупреждение" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"В вашей инсталляции используются большие объекты. В новой базе данных\n" +"имеется дополнительная таблица с правами для больших объектов. После " +"обновления\n" +"вам будет представлена команда для наполнения таблицы прав\n" +"pg_largeobject_metadata правами по умолчанию.\n" +"\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"В вашей инсталляции используются большие объекты. В новой базе данных\n" +"имеется дополнительная таблица с правами для больших объектов, поэтому\n" +"для всех больших объектов должны определяться права по умолчанию. Скрипт\n" +" %s\n" +"позволяет установить такие права (он предназначен для выполнения в psql\n" +"суперпользователем базы данных).\n" +"\n" + +#: version.c:239 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Проверка несовместимого типа данных \"line\"" + +#: version.c:246 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции пользовательские таблицы используют тип данных \"line" +"\".\n" +"В старом кластере внутренний формат и формат ввода/вывода этого типа " +"отличается\n" +"от нового, поэтому в настоящем состоянии обновить кластер невозможно. Вы " +"можете\n" +"удалить проблемные таблицы и перезапустить обновление. Список проблемных\n" +"столбцов приведён в файле:\n" +" %s\n" +"\n" + +#: version.c:276 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Проверка неправильных пользовательских столбцов типа \"unknown\"" + +#: version.c:283 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции пользовательские таблицы используют тип данных \"unknown" +"\".\n" +"Теперь использование этого типа данных не допускается, поэтому в настоящем\n" +"состоянии обновить кластер невозможно. Вы можете удалить проблемные таблицы\n" +"и перезапустить обновления. Список проблемных столбцов приведён в файле:\n" +" %s\n" +"\n" + +#: version.c:306 +#, c-format +msgid "Checking for hash indexes" +msgstr "Проверка хеш-индексов" + +#: version.c:386 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"В вашей инсталляции используются хеш-индексы. Эти индексы имеют разные\n" +"внутренние форматы в старом и новом кластерах, поэтому их необходимо\n" +"перестроить с помощью команды REINDEX. По завершении обновления вы получите\n" +"инструкции по выполнению REINDEX.\n" +"\n" + +#: version.c:392 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"В вашей инсталляции используются хеш-индексы. Эти индексы имеют разные\n" +"внутренние форматы в старом и новом кластерах, поэтому их необходимо\n" +"перестроить с помощью команды REINDEX. Скрипт\n" +" %s\n" +"будучи выполненным администратором БД в psql, пересоздаст все неправильные\n" +"индексы; до этого никакие хеш-индексы не будут использоваться.\n" +"\n" + +#: version.c:418 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "" +"Проверка неправильных пользовательских столбцов типа \"sql_identifier\"" + +#: version.c:426 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables\n" +"and/or indexes. The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can remove the problem tables or\n" +"change the data type to \"name\" and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"В вашей инсталляции пользовательские таблицы и/или индексы используют тип\n" +"данных \"sql_identifier\". Формат хранения таких данных на диске поменялся,\n" +"поэтому обновить данный кластер невозможно. Вы можете удалить проблемные " +"таблицы\n" +"или поменять тип данных на \"name\" и перезапустить обновления.\n" +"Список проблемных столбцов приведён в файле:\n" +" %s\n" +"\n" + +#~ msgid "" +#~ "Optimizer statistics and free space information are not transferred\n" +#~ "by pg_upgrade so, once you start the new server, consider running:\n" +#~ " %s\n" +#~ "\n" +#~ msgstr "" +#~ "Статистика оптимизатора и сведения о свободном месте утилитой pg_upgrade\n" +#~ "не переносятся, поэтому, запустив новый сервер, имеет смысл выполнить:\n" +#~ " %s\n" +#~ "\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid "could not parse PG_VERSION file from %s\n" +#~ msgstr "не удалось разобрать файл PG_VERSION из %s\n" + +#~ msgid "" +#~ "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n" +#~ "because of backend API changes made during development.\n" +#~ msgstr "" +#~ "Эта утилита поддерживает обновление только до версии 9.0 после " +#~ "2010-01-11,\n" +#~ "так как в API серверной части были внесены изменения.\n" + +#~ msgid "Cannot open file %s: %m\n" +#~ msgstr "Не удаётся открыть файл %s: %m\n" + +#~ msgid "Cannot read line %d from %s: %m\n" +#~ msgstr "Не удалось прочитать строку %d из %s: %m\n" + +#~ msgid "------------------------------------------------\n" +#~ msgstr "------------------------------------------------\n" + +#~ msgid "-----------------------------\n" +#~ msgstr "-----------------------------\n" + +#~ msgid "------------------\n" +#~ msgstr "------------------\n" + +#~ msgid "----------------\n" +#~ msgstr "----------------\n" diff --git a/src/bin/pg_upgrade/po/sv.po b/src/bin/pg_upgrade/po/sv.po new file mode 100644 index 000000000000..92678bbe1b42 --- /dev/null +++ b/src/bin/pg_upgrade/po/sv.po @@ -0,0 +1,1799 @@ +# Swedish message translation file for pg_upgrade +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Dennis Björklund , 2017, 2018, 2019, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-20 16:45+0000\n" +"PO-Revision-Date: 2020-10-20 20:29+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: check.c:67 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Utför konsistenskontroller på gamla live-servern\n" +"------------------------------------------------\n" + +#: check.c:73 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Utför konsistenskontroller\n" +"--------------------------\n" + +#: check.c:193 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Klustren är kompatibla*\n" + +#: check.c:199 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Om pg_upgrade misslyckas efter denna punkt så måste du\n" +"köra om initdb på nya klustret innan du fortsätter.\n" + +#: check.c:233 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Optimeringsstatistik överförs inte av pg_upgrade så\n" +"när du startar nya servern så vill du nog köra:\n" +" %s\n" +"\n" + +#: check.c:239 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"När detta skript körs så raderas gamla klustrets datafiler:\n" +" %s\n" + +#: check.c:244 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Kunde inte skapa ett script som raderar gamla klustrets datafiler\n" +"då användardefinierade tabellutrymmen eller nya klustrets datakatalog\n" +"ligger i gamla klusterkatalogen. Det gamla klustrets innehåll\n" +"måste raderas för hand.\n" + +#: check.c:254 +#, c-format +msgid "Checking cluster versions" +msgstr "Kontrollerar klustrets versioner" + +#: check.c:266 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Detta verktyg kan bara uppgradera från PostgreSQL version 8.4 eller nyare.\n" + +#: check.c:270 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Detta verktyg kan bara uppgradera till PostgreSQL version %s.\n" + +#: check.c:279 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Detta verktyg kan inte användas för att nergradera till äldre major-versioner av PostgreSQL.\n" + +#: check.c:284 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Gammal klusterdata och binära kataloger är från olika major-versioner.\n" + +#: check.c:287 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Nya klusterdata och binära kataloger är från olika major-versioner.\n" + +#: check.c:304 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Vid kontroll av en gammal live-server före PG 9.1 så måste den gamla serverns portnummer anges.\n" + +#: check.c:308 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Vid kontroll av en live-server så måste gamla och nya portnumren vara olika.\n" + +#: check.c:323 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "kodning för databasen \"%s\" matchar inte: gammal \"%s\", ny \"%s\"\n" + +#: check.c:328 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_collate-värden för databasen \"%s\" matchar inte: gammal \"%s\", ny \"%s\"\n" + +#: check.c:331 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_ctype-värden för databasen \"%s\" matchar inte: gammal \"%s\", ny \"%s\"\n" + +#: check.c:404 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "Nya databasklustret \"%s\" är inte tomt: hittade relation \"%s.%s\"\n" + +#: check.c:453 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Skapar skript för att analysera nya klustret" + +#: check.c:467 check.c:626 check.c:890 check.c:969 check.c:1079 check.c:1170 +#: file.c:336 function.c:240 option.c:497 version.c:54 version.c:199 +#: version.c:341 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "kan inte öppna fil \"%s\": %s\n" + +#: check.c:515 check.c:682 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "kan inte sätta rättigheten \"körbar\" på filen \"%s\": %s\n" + +#: check.c:545 +#, c-format +msgid "Checking for new cluster tablespace directories" +msgstr "Letar efter nya tablespace-kataloger i klustret" + +#: check.c:556 +#, c-format +msgid "new cluster tablespace directory already exists: \"%s\"\n" +msgstr "i klustret finns redan ny tablespace-katalog: \"%s\"\n" + +#: check.c:589 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"VARNING: nya datakatalogen skall inte ligga inuti den gamla datakatalogen, dvs. %s\n" + +#: check.c:613 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"VARNING: användardefinierade tabellutrymmens position skall inte vara i datakatalogen, dvs. %s\n" + +#: check.c:623 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Skapar skript för att radera gamla klustret" + +#: check.c:702 +#, c-format +msgid "Checking database user is the install user" +msgstr "Kontrollerar att databasanvändaren är installationsanvändaren" + +#: check.c:718 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "databasanvändare \"%s\" är inte installationsanvändaren\n" + +#: check.c:729 +#, c-format +msgid "could not determine the number of users\n" +msgstr "kunde inte bestämma antalet användare\n" + +#: check.c:737 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Bara installationsanvändaren får finnas i nya klustret.\n" + +#: check.c:757 +#, c-format +msgid "Checking database connection settings" +msgstr "Kontrollerar databasens anslutningsinställningar" + +#: check.c:779 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 får inte tillåta anslutningar, dvs dess pg_database.datallowconn måste vara false\n" + +#: check.c:789 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Alla icke-template0-databaser måste tillåta anslutningar, dvs. deras pg_database.datallowconn måste vara true\n" + +#: check.c:814 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Letar efter förberedda transaktioner" + +#: check.c:823 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Källklustret innehåller förberedda transaktioner\n" + +#: check.c:825 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Målklustret innehåller förberedda transaktioner\n" + +#: check.c:851 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Letar efter contrib/isn med bigint-anropsfel" + +#: check.c:912 check.c:991 check.c:1102 check.c:1193 function.c:262 +#: version.c:245 version.c:282 version.c:425 +#, c-format +msgid "fatal\n" +msgstr "fatalt\n" + +#: check.c:913 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehåller \"contrib/isn\"-funktioner son beror på\n" +"datatypen bigint. Ditt gamla och nya kluster skickar bigint-värden\n" +"på olika sätt så detta kluster kan för närvarande inte uppgraderas. Du\n" +"kan manuellt dumpa databaser i gamla klustret som använder \"contrib/isn\"-finesser,\n" +"radera dessa databaser, utföra uppgraderingen och sedan återställa databaserna.\n" +"En lista med problemfunktionerna finns i filen:\n" +" %s\n" +"\n" + +#: check.c:937 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Letar efter tabeller med WITH OIDS" + +#: check.c:992 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehåller tabeller deklarerade med WITH OIDS som inte\n" +"stöds längre. Överväg att ta bort oid-kolumnen med\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"En lista över tabeller med detta problem finns i filen:\n" +" %s\n" +"\n" + +# FIXME: is this msgid correct? +#: check.c:1022 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Letar efter reg*-datatyper i användartabeller" + +#: check.c:1103 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the\n" +"problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation använder en av reg*-datatyperna i en användartabell.\n" +"Dessa datatyper refererar system-OID:er som inte bevaras av pg_upgrade\n" +"så detta kluster kan för närvarande inte uppgraderas. Du kan ta bort\n" +"problemtabellerna och starta om uppgraderingen. En lista med\n" +"problemkolumnerna finns i filen:\n" +" %s\n" +"\n" + +# FIXME: is this msgid correct? +#: check.c:1128 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Letar efter inkompatibel \"jsonb\"-datatyp" + +#: check.c:1194 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can remove the problem\n" +"tables and restart the upgrade. A list of the problem columns is\n" +"in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehåller \"jsonb\"-datatypen i användartabeller.\n" +"Interna formatet för \"jsonb\" ändrades under 9.4-betan så detta kluster kan\n" +"för närvarande inte uppgraderas. Du kan ta bort problemtabellerna och\n" +"starta om uppgraderingen. En lista med problemkolumnerna finns i filen:\n" +" %s\n" +"\n" + +#: check.c:1216 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Letar efter roller som startar med \"pg_\"" + +#: check.c:1226 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Källklustret innehåller roller som startar med \"pg_\"\n" + +#: check.c:1228 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Målklustret innehåller roller som startar med \"pg_\"\n" + +#: check.c:1254 +#, c-format +msgid "failed to get the current locale\n" +msgstr "misslyckades med att hämta aktuell lokal\n" + +#: check.c:1263 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "misslyckades med att hämta systemlokalnamn för \"%s\"\n" + +#: check.c:1269 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "misslyckades med att återställa gamla lokalen \"%s\"\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "kunde inte hämta kontrolldata med %s: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: state-problem för databaskluster\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Källklustret stängdes ner när det var i återställningsläge. För att uppgradera så använd \"rsync\" enligt dokumentation eller stäng ner den som en primär.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Målklustret stängdes ner när det var i återställningsläge. För att uppgradera så använd \"rsync\" enligt dokumentation eller stäng ner den som en primär.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Källklustret har inte stängts ner på ett korrekt sätt.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Målklustret har inte stängts ner på ett korrekt sätt.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Källklustret saknar information om kluster-state:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Målklustret saknar information om kluster-state:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:339 pg_upgrade.c:375 +#: relfilenode.c:243 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal-problem\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: problem vid hämtning av kontrolldata\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Källklustret saknar lite kontrolldata som krävs:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Målklustret saknar lite kontrolldata som krävs:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " checkpoint nästa-XID\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " senaste checkpoint nästa-OID\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " senaster checkpoint nästa-MultiXactId\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " senaste checkpoint äldsta-MultiXactId\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " senaste checkpoint nästa-MultiXactOffset\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " första WAL-segmentet efter reset\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " float8 argumentöverföringsmetod\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " maximal alignment\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " blockstorlek\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " stora relationers segmentstorlek\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " WAL-blockstorlek\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL-segmentstorlek\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " maximal identifierarlängd\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " maximalt antal indexerade kolumner\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " maximal TOAST-chunkstorlek\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " stora-objekt chunkstorlek\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " datum/tid är heltal?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " datachecksumversion\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Kan inte fortsätta utan kontrollinformation som krävs, avslutar\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"gamla och nya pg_controldata-alignments är ogiltiga eller matchar inte.\n" +"Troligen är ett kluster en 32-bitars-installation och den andra 64-bitars\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata-blockstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maximala relationssegmentstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata WAL-blockstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata WAL-segmentstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maximal identifierarlängder är ogiltiga eller matchar inte\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maxilmalt indexerade kolumner ogiltiga eller matchar inte\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maximal TOAST-chunkstorlek ogiltiga eller matchar inte\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata stora-objekt-chunkstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "gamla och nya pg_controldata datum/tid-lagringstyper matchar inte\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "gamla klustret använder inte datachecksummor men nya gör det\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "gamla klustret använder datachecksummor men nya gör inte det\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "gamla och nya klustrets pg_controldata checksumversioner matchar inte\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Lägger till \".old\"-suffix till gamla global/pg_control" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Kan inte byta namn på %s till %s.\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Om du vill starta gamla klustret så måste du ta bort\n" +"\".old\"-suffixet från %s/global/pg_control.old.\n" +"Detta då \"link\"-läge användes och gamla klustret kan inte\n" +"startas på ett säkert sätt efter att nya klustret startats.\n" +"\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "Skapar dump med globala objekt" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Skapar dump med databasscheman\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "kunde inte hämta pg_ctl versionsdata med %s: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "kunde inte läsa versionutdata för pg_ctl från %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "kommandot för långt\n" + +#: exec.c:110 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "kunde inte öppna loggfil \"%s\": %m\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*misslyckande*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Det var problem med att köra \"%s\"\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Se de sista raderna i \"%s\" eller \"%s\" för\n" +"en trolig orsak till misslyckandet.\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Se de sista raderna i \"%s\" för\n" +"en trolig orsak till misslyckandet.\n" + +#: exec.c:204 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "kunde inte skriva till loggfil \"%s\": %m\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "kunde inte öppna fil \"%s\" för läsning: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Du måste ha läs och skrivrättigheter till den aktuella katalogen.\n" + +#: exec.c:310 exec.c:372 exec.c:436 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "kontroll av \"%s\" misslyckades: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" är inte en katalog\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "kontroll av \"%s\" misslyckades: inte en vanlig fil\n" + +#: exec.c:451 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "kontroll av \"%s\" misslyckades: kan inte läsa filen (rättighet saknas)\n" + +#: exec.c:459 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "kontroll av \"%s\" misslyckades: kan inte exekvera (rättighet saknas)\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid kloning av relation \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: file.c:50 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "fel vid kloning av relation \"%s.%s\": kunde inte öppna filen \"%s\": %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "fel vid kloning av relation \"%s.%s\": kunde inte skapa filen \"%s\": %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte öppna filen \"%s\": %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte skapa filen \"%s\": %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte läsa filen \"%s\": %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte skriva filen \"%s\": %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: file.c:151 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid skapande av länk för relation \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: file.c:194 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte göra stat på file \"%s\": %s\n" + +#: file.c:226 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "fel vid kopiering av relation \"%s.%s\": partiell sida hittad i fil \"%s\"\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "kunde inte klona fil mellan gamla och nya datakatalogen: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "kan inte skapa fil \"%s\": %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "filkloning stöds inte på denna plattform\n" + +#: file.c:369 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"kunde inte skapa hård länk mellan gamla och nya datakatalogerna: %s\n" +"I länk-läge måste gamla och nya datakatalogerna vara i samma filsystem.\n" + +#: function.c:114 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"Det gamla klustret har en \"plpython_call_handler\"-funktion definierad\n" +"i \"public\"-schemat vilket är en kopia på den som definierats\n" +"i \"pg_catalog\"-schemat. Du kan verifiera detta genom att i\n" +"psql köra:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"\"public\"-schema-versionen av denna funktion har skapats av en\n" +"pre-8.1-installation av plpython och måste raderas för att pg_upgrade\n" +"skall kunna gå klart då den referar till en nu föråldrad\n" +"\"plpython\" delad objektfil. Du kan ta bort \"public\"-schemaversionen\n" +"av denna funktion genom att köra följande kommando:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"i varje inblandad databas:\n" +"\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Ta bort problemfunktionerna från gamla klustret för att fortsätta.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Kontrollerar att krävda länkbibliotek finns" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "kunde inte ladda länkbibliotek \"%s\": %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "I databas: %s\n" + +#: function.c:263 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation refererar till laddbara bibliotek som saknas i nya\n" +"installationen. Du kan lägga till dessa itll nya installationen eller\n" +"ta bort funktionerna som använder dem i gamla installationen. En lista\n" +"med problembiblioteken finns i filen:\n" +" %s\n" +"\n" + +#: info.c:131 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Relationsname för OID %u i databas \"%s\" matchar inte: gammalt namn \"%s.%s\", nytt namn \"%s.%s\"\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Misslyckades med att matcha ihop gamla och nya tabeller i databas \"%s\"\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " vilket är ett index för \"%s.%s\"" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " vilket är ett index för OID %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " vilket är TOAST-tabellen för \"%s.%s\"" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " vilket är TOAST-tabellen för OID %u" + +#: info.c:274 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "Ingen träff hittad i gamla klustret för ny relation med OID %u i databas \"%s\": %s\n" + +#: info.c:277 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "Ingen träff hittad i nya klustret för gammal relation med OID %u i databas \"%s\": %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "avbildningar för databasen \"%s\":\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u till %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:322 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"källdatabaser:\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"måldatabaser:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "Databas: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relnamn: %s.%s: reloid: %u reltblutrymme: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: kan inte köras som root\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "ogiltigt gammalt portnummer\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "ogiltigt nytt portnummer\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "för många kommandoradsargument (första är \"%s\")\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Kör i utförligt läge\n" + +# FIXME: the source code need to be fixed here. it paste words together +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "gamla klusterbinärer är i" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "nya klusterbinärer är i" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "gamla klusterdatan är i" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "nya klusterdatan är i" + +#: option.c:259 +msgid "sockets will be created" +msgstr "uttag kommer skapas" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "kunde inte bestämma aktuell katalog\n" + +#: option.c:279 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "kan inte köra pg_upgrade inifrån nya klusterdatakatalogen i Windows\n" + +#: option.c:288 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade uppgraderar ett PostgreSQL-kluster till en annan major-version.\n" +"\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "Användning:\n" + +#: option.c:290 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [FLAGGA]...\n" +"\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "Flaggor:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINKAT gamla klustrets katalog för körbara filer\n" + +#: option.c:293 +#, c-format +msgid "" +" -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr "" +" -B, --new-bindir=BINKAT nya klustrets katalog för körbara filer\n" +" (standard är samma som för pg_upgrade)\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check testa klustren bara, ändra ingen data\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATAKAT gamla klustrets datakatalog\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATAKAT nya klustrets datakatalog\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs=NUM number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs=NUM antal samtidiga processer eller trådar att använda\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link länka istället för att kopiera filer till nya klustret\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=FLAGGOR serverflaggor för gamla klustret\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=FLAGGOR serverflaggor för nya klustret\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT gamla klustrets portnummer (standard %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT nya klustrets portnummer (standard %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain behåll SQL och loggfiler efter lyckad uppgradering\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" +msgstr " -s, --socketdir=KAT uttagskatalog (standard är aktuell katalog.)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NAMN klustrets superanvändare (standard \"%s\")\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose slå på utförligt intern loggning\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " -clone klona istället för att kopiera filer till nya klustret\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denns hjälp, avsluta sedan\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Innan du kör pg_upgrade måste du:\n" +" skapa ett nytt databaskluster (med nya versionens initdb)\n" +" stänga ner den postmaster som hanterar gamla klustret\n" +" stänga ner den postmaster som hanterar nya klustret\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"När du kör pg_upgrade måste du ange följande information:\n" +" datakatalogen för gamla klustret (-d DATAKAT)\n" +" datakatalogen för nya klustret (-D DATAKAT)\n" +" \"bin\"-katalogen för gamla versionen (-b BINKAT)\n" +" \"bin\"-katalogen för nya versionen (-B BINKAT)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Till exempel:\n" +" pg_upgrade -d gammaltKluster/data -D nyttKluster/data -b gammaltKluster/bin -B nyttKluster/bin\n" +"eller\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=gammaltKluster/data\n" +" $ export PGDATANEW=nyttKluster/data\n" +" $ export PGBINOLD=gammaltKluster/bin\n" +" $ export PGBINNEW=nyttKluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=gammaltKluster/data\n" +" C:\\> set PGDATANEW=nyttKluster/data\n" +" C:\\> set PGBINOLD=gammaltKluster/bin\n" +" C:\\> set PGBINNEW=nyttKluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Rapportera fel till <%s>.\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "hemsida för %s: <%s>\n" + +#: option.c:380 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Du måste identifiera katalogen där %s.\n" +"Använd kommandoradsflaggan %s eller omgivningsvariabeln %s.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Letar efter den riktiga datakatalogen i källklustret" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Letar efter den riktiga datakatalogen för målklustret" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "kunde inte hämta datakatalogen med %s: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "kunde inte läsa rad %d från fil \"%s\": %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "användarangivet gammalt portnummer %hu korrigerat till %hu\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "kunde inte skapa arbetsprocess: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "kunde inte skapa arbetstråd: %s\n" + +#: parallel.c:300 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "waitpid() misslyckades: %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "barnprocess avslutade felaktigt: status %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "barnprocess avslutade felaktigt: %s\n" + +#: pg_upgrade.c:108 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "kunde inte läsa rättigheter på katalog \"%s\": %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Utför uppgradering\n" +"------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Sätter nästa OID för nya klustret" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "Synkar datakatalog till disk" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Uppgradering klar\n" +"-----------------\n" + +#: pg_upgrade.c:220 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: kunde inte hitta det egna programmets körbara fil\n" + +#: pg_upgrade.c:246 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Det verkar vara en postmaster igång som hanterar gamla klustret.\n" +"Stänga ner den postmastern och försök igen.\n" + +#: pg_upgrade.c:259 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Det verkar vara en postmaster igång som hanterar nya klustret.\n" +"Stänga ner den postmastern och försök igen.\n" + +#: pg_upgrade.c:273 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analyserar alla rader i nya klustret" + +#: pg_upgrade.c:286 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Fryser alla rader i nya klustret" + +#: pg_upgrade.c:306 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Återställer globala objekt i nya klustret" + +#: pg_upgrade.c:321 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Återställer databasscheman i nya klustret\n" + +#: pg_upgrade.c:425 +#, c-format +msgid "Deleting files from new %s" +msgstr "Raderar filer från ny %s" + +#: pg_upgrade.c:429 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "kunde inte ta bort katalog \"%s\"\n" + +#: pg_upgrade.c:448 +#, c-format +msgid "Copying old %s to new server" +msgstr "Kopierar gammal %s till ny server" + +#: pg_upgrade.c:475 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Sätter nästa transaktions-ID och epoch för nytt kluster" + +#: pg_upgrade.c:505 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Sätter nästa multixact-ID och offset för nytt kluster" + +#: pg_upgrade.c:529 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Sätter äldsta multixact-ID i nytt kluster" + +#: pg_upgrade.c:549 +#, c-format +msgid "Resetting WAL archives" +msgstr "Resettar WAL-arkiv" + +#: pg_upgrade.c:592 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Sätter räknarna frozenxid och minmxid för nytt kluster" + +#: pg_upgrade.c:594 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Sätter räknarenm minmxid för nytt kluster" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Klonar användares relationsfiler\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "Kopierar användares relationsfiler\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "Länkar användares relationsfiler\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "gamla databasen \"%s\" kan inte hittas i nya klustret\n" + +#: relfilenode.c:230 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid kontroll av filexistens \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: relfilenode.c:248 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "skriver om \"%s\" till \"%s\"\n" + +#: relfilenode.c:256 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "klonar \"%s\" till \"%s\"\n" + +#: relfilenode.c:261 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "kopierar \"%s\" till \"%s\"\n" + +#: relfilenode.c:266 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "länkar \"%s\" till \"%s\"\n" + +#: server.c:33 +#, c-format +msgid "connection to database failed: %s" +msgstr "anslutning till databas misslyckades: %s" + +#: server.c:39 server.c:141 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "Misslyckades, avslutar\n" + +#: server.c:131 +#, c-format +msgid "executing: %s\n" +msgstr "kör: %s\n" + +#: server.c:137 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL-kommando misslyckades\n" +"%s\n" +"%s" + +#: server.c:167 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "kunde inte öppna versionsfil \"%s\": %m\n" + +#: server.c:171 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "kunde inte tolka versionsfil \"%s\"\n" + +#: server.c:297 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"anslutning till databas misslyckades: %s" + +#: server.c:302 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"kunde inte ansluta till käll-postmaster som startats med kommandot:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"kunde inte ansluta till mål-postmaster som startats med kommandot:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl misslyckades att start källservern eller så misslyckades anslutningen\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl misslyckades att start målservern eller så misslyckades anslutningen\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "slut på minne\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "libpq:s omgivningsvariabel %s har ett icke-lokalt servervärde: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"Kan inte uppgradera till/från samma systemkatalogversion när\n" +"man använder tablespace.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "tablespace-katalogen \"%s\" finns inte\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "kunde inte göra stat på tablespace-katalog \"%s\": %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "tablespace-sökväg \"%s\" är inte en katalog\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "Letar efter stora objekt" + +#: version.c:77 version.c:384 +#, c-format +msgid "warning" +msgstr "varning" + +#: version.c:79 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Din installation innehåller stora objekt. Den nya databasen\n" +"har en extra rättighetstabell för stora objekt. Efter uppgradering\n" +"kommer du ges ett kommando för att populera rättighetstabellen\n" +"pg_largeobject_metadata med standardrättigheter.\n" +"\n" + +#: version.c:85 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Din installation innehåller stora objekt. Den nya databasen har en extra\n" +"rättighetstabell för stora onbjekt så standardrättigheter måste ges för\n" +"alla stora objekt. Filen\n" +" %s\n" +"kan köras med psql av databasens superanvändare för att sätta\n" +"standardrättigheter.\n" +"\n" + +# FIXME: is this msgid correct? +#: version.c:239 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Letar efter inkompatibel \"line\"-datatyp" + +#: version.c:246 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehåller datatypen \"line\" i användartabeller. Denna\n" +"datatype har ändrat sitt interna format samt sitt in/ut-format mellan ditt\n" +"gamla och nya kluster så detta kluster kan för närvarande inte uppgraderas.\n" +"Du kan radera problemtabellerna och återstarta uppgraderingen. En lista\n" +"med problemkolumner finns i filen:\n" +" %s\n" +"\n" + +#: version.c:276 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Letar efter ogiltiga användarkolumner av typen \"unknown\"" + +#: version.c:283 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehåller användartabeller med datatypen \"unknown\".\n" +"Denna typ tillåts inte längre i tabeller så detta kluster kan\n" +"för närvarande inte uppgraderas. Du kan radera problemtabellerna och\n" +"återstarta uppgraderingen. En lista med problemkolumnerna finns i filen:\n" +" %s\n" +"\n" + +#: version.c:306 +#, c-format +msgid "Checking for hash indexes" +msgstr "Letar efter hash-index" + +#: version.c:386 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Din installation innehåller hash-index. Dessa index har olika internt\n" +"format i ditt gamla och nya kluster så de måste omindexeras med\n" +"kommandot REINDEX. Efter uppgraderingen så kommer du få\n" +"REINDEX-instruktioner.\n" +"\n" + +#: version.c:392 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Din installation innehåller hash-index. Dessa index har olika internt\n" +"format i ditt gamla och nya kluster så de måste omindexeras med\n" +"kommandot REINDEX. Filen\n" +" %s\n" +"kan köras med psql av databasens superanvändare och kommer återskapa\n" +"alla ogiltiga index; innan dess så kommer inget av dess index användas.\n" +"\n" + +#: version.c:418 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "Letar efter ogiltiga användarkolumner av typen \"sql_identifier\"" + +#: version.c:426 +#, c-format +msgid "" +"Your installation contains the \"sql_identifier\" data type in user tables\n" +"and/or indexes. The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can remove the problem tables or\n" +"change the data type to \"name\" and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehåller användartabeller och/eller index med\n" +"med datatypen \"sql_identifier\". Formatet på disk för denna datatyp\n" +"har ändrats så detta kluster kan för närvarande inte uppgraderas.\n" +"Du kan radera problemtabellerna eller ändra datatypen till \"name\"\n" +"och återstarta uppgraderingen. En lista med problemkolumnerna finns\n" +"i filen:\n" +" %s\n" +"\n" + +#~ msgid "" +#~ "Optimizer statistics and free space information are not transferred\n" +#~ "by pg_upgrade so, once you start the new server, consider running:\n" +#~ " %s\n" +#~ "\n" +#~ msgstr "" +#~ "Optimeringsstatistik och information om ledigt utrymme överförs\n" +#~ "inte av pg_upgrade så när du startar nya servern så vill du nog köra:\n" +#~ " %s\n" diff --git a/src/bin/pg_upgrade/po/uk.po b/src/bin/pg_upgrade/po/uk.po new file mode 100644 index 000000000000..75d7600ccf7c --- /dev/null +++ b/src/bin/pg_upgrade/po/uk.po @@ -0,0 +1,1623 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:15+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: \n" +"Language-Team: Ukrainian\n" +"Language: uk_UA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_upgrade.pot\n" +"X-Crowdin-File-ID: 510\n" + +#: check.c:66 +#, c-format +msgid "Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "Перевірка цілістності на старому працюючому сервері\n" +"------------------------------------------------\n" + +#: check.c:72 +#, c-format +msgid "Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "Проведення перевірок цілістності\n" +"-----------------------------\n" + +#: check.c:190 +#, c-format +msgid "\n" +"*Clusters are compatible*\n" +msgstr "\n" +"*Кластери сумісні*\n" + +#: check.c:196 +#, c-format +msgid "\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "\n" +"Якщо робота pg_upgrade після цієї точки перерветься, вам потрібно буде заново виконати initdb \n" +"для нового кластера, перед продовженням.\n" + +#: check.c:232 +#, c-format +msgid "Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n\n" +msgstr "Статистика оптимізатора не переноситься за допомогою pg_upgrade, тож\n" +"запустивши новий сервер, має сенс виконати:\n" +" %s\n\n" + +#: check.c:237 +#, c-format +msgid "Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n\n" +msgstr "Статистика оптимізатора і інформація про вільне місце не переноситься за допомогою pg_upgrade, тож\n" +"запустивши новий сервер, має сенс виконати:\n" +" %s\n\n" + +#: check.c:244 +#, c-format +msgid "Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "При запуску цього скрипту файли даних старого кластера будуть видалені:\n" +" %s\n" + +#: check.c:249 +#, c-format +msgid "Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "Не вдалося створити скрипт для видалення файлів даних старого кластеру,\n" +"тому що каталог даних старого кластера містить користувацькі табличні\n" +"простори або каталог даних нового кластера. Вміст старого кластера\n" +"треба буде видалити вручну.\n" + +#: check.c:259 +#, c-format +msgid "Checking cluster versions" +msgstr "Перевірка версій кластерів" + +#: check.c:271 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Ця утиліта може виконувати оновлення тільки з версії PostgreSQL 8.4 і новіше.\n" + +#: check.c:275 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Ця утиліта може тільки підвищувати версію PostgreSQL до %s.\n" + +#: check.c:284 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Ця утиліта не може не може використовуватись щоб понижувати версію до більш старих основних версій PostgreSQL.\n" + +#: check.c:289 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Каталог даних і двійковий каталог старого кластера з різних основних версій.\n" + +#: check.c:292 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Каталог даних і двійковий каталог нового кластера з різних основних версій.\n" + +#: check.c:309 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Для перевірки старого працюючого сервера до версії 9.1, вам необхідно вказати номер порта цього сервера.\n" + +#: check.c:313 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Для перевірки працюючого сервера, старий і новий номер порта повинні бути різними.\n" + +#: check.c:328 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "кодування для бази даних \"%s\" не збігаються: старе \"%s\", нове \"%s\"\n" + +#: check.c:333 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "значення lc_collate для бази даних \"%s\" не збігаються: старе \"%s\", нове \"%s\"\n" + +#: check.c:336 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "значення lc_ctype для бази даних \"%s\" не збігаються: старе \"%s\", нове \"%s\"\n" + +#: check.c:409 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "Новий кластер бази даних \"%s\" не порожній: знайдено відношення \"%s.%s\"\n" + +#: check.c:458 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Створення скрипту для аналізу нового кластеру" + +#: check.c:472 check.c:600 check.c:864 check.c:943 check.c:1053 check.c:1144 +#: file.c:336 function.c:240 option.c:497 version.c:54 version.c:199 +#: version.c:341 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "не вдалося відкрити файл \"%s\": %s\n" + +#: check.c:527 check.c:656 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "не вдалося додати право виконання для файлу \"%s\": %s\n" + +#: check.c:563 +#, c-format +msgid "\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "\n" +"ПОПЕРЕДЖЕННЯ: новий каталог даних не повинен бути всередині старого каталогу даних, наприклад %s\n" + +#: check.c:587 +#, c-format +msgid "\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "\n" +"ПОПЕРЕДЖЕННЯ: користувацькі розташування табличних просторів не повинні бути всередині каталогу даних, наприклад %s\n" + +#: check.c:597 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Створення скрипту для видалення старого кластеру" + +#: check.c:676 +#, c-format +msgid "Checking database user is the install user" +msgstr "Перевірка, чи є користувач бази даних стартовим користувачем" + +#: check.c:692 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "користувач бази даних \"%s\" не є стартовим користувачем\n" + +#: check.c:703 +#, c-format +msgid "could not determine the number of users\n" +msgstr "не вдалося визначити кількість користувачів\n" + +#: check.c:711 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "В новому кластері може бути визначеним тільки стартовий користувач.\n" + +#: check.c:731 +#, c-format +msgid "Checking database connection settings" +msgstr "Перевірка параметрів підключення до бази даних" + +#: check.c:753 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 не повинна дозволяти підключення, тобто pg_database.datallowconn повинно бути false\n" + +#: check.c:763 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Всі бази даних, окрім template0, повинні дозволяти підключення, тобто pg_database.datallowconn повинно бути true\n" + +#: check.c:788 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Перевірка підготовлених транзакцій" + +#: check.c:797 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Початковий кластер містить підготовлені транзакції\n" + +#: check.c:799 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Цільовий кластер містить підготовлені транзакції\n" + +#: check.c:825 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Перевірка невідповідності при передаванні bigint в contrib/isn" + +#: check.c:886 check.c:965 check.c:1076 check.c:1167 function.c:262 +#: version.c:245 version.c:282 version.c:425 +#, c-format +msgid "fatal\n" +msgstr "збій\n" + +#: check.c:887 +#, c-format +msgid "Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually dump databases in the old cluster that use \"contrib/isn\"\n" +"facilities, drop them, perform the upgrade, and then restore them. A\n" +"list of the problem functions is in the file:\n" +" %s\n\n" +msgstr "Ваша інсталяція містить функції \"contrib/isn\", що використовують тип даних bigint. Старі та нові кластери передають значення bigint по-різному, тому цей кластер наразі неможливо оновити. Ви можете вручну вивантажити бази даних зі старого кластеру, що використовує засоби \"contrib/isn\", видалити їх, виконати оновлення, а потім відновити їх. Список проблемних функцій подано у файлі:\n" +" %s\n\n" + +#: check.c:911 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Перевірка таблиць WITH OIDS" + +#: check.c:966 +#, c-format +msgid "Your installation contains tables declared WITH OIDS, which is not\n" +"supported anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n\n" +msgstr "Ваша інсталяція містить таблиці, створені як WITH OIDS, що більше не підтримуються. Розгляньте видалення стовпців, що містять oid за допомогою\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Список проблемних таблиць подано у файлі:\n" +" %s\n\n" + +#: check.c:996 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Перевірка типів даних reg* в користувацьких таблицях" + +#: check.c:1077 +#, c-format +msgid "Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the\n" +"problem columns is in the file:\n" +" %s\n\n" +msgstr "Користувацькі таблиці у вашій інсталяції містять один з типів даних reg*. Ці типи даних посилаються на системні OIDs, що не зберігаються за допомогою pg_upgrade, тому цей кластер наразі неможливо оновити. Ви можете видалити проблемні таблиці і перезавантажити оновлення. Список проблемних стовпців подано у файлі:\n" +" %s\n\n" + +#: check.c:1102 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Перевірка несумісного типу даних \"jsonb\"" + +#: check.c:1168 +#, c-format +msgid "Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this\n" +"cluster cannot currently be upgraded. You can remove the problem\n" +"tables and restart the upgrade. A list of the problem columns is\n" +"in the file:\n" +" %s\n\n" +msgstr "Користувацькі таблиці у вашій інсталяції містять тип даних \"jsonb\". Внутрішній формат \"jsonb\" змінено під час версії 9.4 beta, тому цей кластер наразі неможливо оновити. Ви можете видалити проблемні таблиці та перезавантажити оновлення. Список проблемних таблиць подано у файлі:\n" +" %s\n\n" + +#: check.c:1190 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Перевірка ролей, які починаються з \"pg_\"" + +#: check.c:1200 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Початковий кластер містить ролі, які починаються з \"pg_\"\n" + +#: check.c:1202 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Цільовий кластер містить ролі, які починаються з \"pg_\"\n" + +#: check.c:1228 +#, c-format +msgid "failed to get the current locale\n" +msgstr "не вдалося отримати поточну локаль\n" + +#: check.c:1237 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "не вдалося отримати системне ім'я локалі для \"%s\"\n" + +#: check.c:1243 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "не вдалося відновити стару локаль \"%s\"\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "не вдалося отримати контрольні дані за допомогою %s: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: неприпустимий стан кластера баз даних\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Початковий кластер завершив роботу в режимі відновлення. Щоб виконати оновлення, використайте документований спосіб з \"rsync\" або вимкніть його в режимі головного сервера.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Цільовий кластер завершив роботу в режимі відновлення. Щоб виконати оновлення, використайте документований спосіб з \"rsync\" або вимкніть його в режимі головного сервера.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Початковий кластер завершив роботу некоректно.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Цільовий кластер завершив роботу некоректно.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "В початковому кластері відсутня інформація про стан кластеру:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "В цільовому кластері відсутня інформація про стан кластеру:\n" + +#: controldata.c:208 dump.c:49 pg_upgrade.c:339 pg_upgrade.c:375 +#: relfilenode.c:247 util.c:79 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: проблема pg_resetwal\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: проблема з отриманням контрольних даних\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "У початковому кластері відсутня необхідна контрольна інформація:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "У цільовому кластері відсутня необхідна контрольна інформація:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " наступний XID контрольної точки\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " наступний OID останньої контрольної точки\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " наступний MultiXactId останньої контрольної точки\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " найстарший MultiXactId останньої контрольної точки\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " наступний MultiXactOffset останньої контрольної точки\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " перший сегмет WAL після скидання\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " метод передачі аргументу float8\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " максимальне вирівнювання\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " розмір блоку\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " розмір сегменту великого відношення\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " розмір блоку WAL\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " розмір сегменту WAL\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " максимальна довжина ідентифікатора\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " максимальна кількість індексованих стовпців\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " максимальний розмір порції TOAST\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " розмір порції великого об'єкту\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " дата/час представлені цілими числами?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " версія контрольних сум даних\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Не можна продовжити без необхідної контрольної інформації, завершення\n" + +#: controldata.c:623 +#, c-format +msgid "old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "старе і нове вирівнювання в pg_controldata неприпустимі або не збігаються\n" +"Ймовірно, один кластер встановлений у 32-бітній системі, а інший - у 64-бітній\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "старий і новий розмір блоків в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "старий і новий максимальний розмір сегментів відношень в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "старий і новий розмір блоків WAL в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "старий і новий розмір сегментів WAL в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "стара і нова максимальна довжина ідентифікаторів в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "стара і нова максимальна кількість індексованих стовпців в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "старий і новий максимальний розмір порції TOAST в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "старий і новий розмір порції великого об'єкту в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "старий і новий тип сховища дати/часу в pg_controldata неприпустимі або не збігаються\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "старий кластер не використовує контрольні суми даних, але новий використовує\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "старий кластер використовує контрольні суми даних, але новий не використовує\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "стара і нова версія контрольних сум кластера в pg_controldata не збігаються\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Додавання суфікса \".old\" до старого файла global/pg_control" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Не вдалося перейменувати %s на %s.\n" + +#: controldata.c:690 +#, c-format +msgid "\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n\n" +msgstr "\n" +"Якщо ви хочете запустити старий кластер, вам необхідно видалити\n" +"суфікс \".old\" з файлу %s/global/pg_control.old. Через використання\n" +"режиму \"link\" робота старого кластера після запуску нового може бути\n" +"небезпечна.\n\n" + +#: dump.c:20 +#, c-format +msgid "Creating dump of global objects" +msgstr "Створення вивантаження глобальних об'єктів" + +#: dump.c:31 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Створення вивантаження схем бази даних\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "не вдалося отримати дані версії pg_ctl, виконавши %s: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "не вдалося отримати версію pg_ctl з результату %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "команда занадто довга\n" + +#: exec.c:110 util.c:37 util.c:225 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 option.c:217 +#, c-format +msgid "could not open log file \"%s\": %m\n" +msgstr "не вдалося відкрити файл журналу \"%s\": %m\n" + +#: exec.c:178 +#, c-format +msgid "\n" +"*failure*" +msgstr "\n" +"*неполадка*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Під час виконання \"%s\" виникли проблеми\n" + +#: exec.c:184 +#, c-format +msgid "Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "Щоб зрозуміти причину неполадки, зверніться до декількох останніх рядків\n" +"файлу \"%s\" або \"%s\".\n" + +#: exec.c:189 +#, c-format +msgid "Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "Щоб зрозуміти причину неполадки, зверніться до декількох останніх рядків\n" +"файлу \"%s\".\n" + +#: exec.c:204 option.c:226 +#, c-format +msgid "could not write to log file \"%s\": %m\n" +msgstr "не вдалося записати до файлу журналу \"%s\": %m\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "не вдалося відкрити файл \"%s\" для читання: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Ви повинні мати права на читання і запис в поточному каталозі.\n" + +#: exec.c:310 exec.c:372 exec.c:436 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "перевірка \"%s\" провалена: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" не є каталогом\n" + +#: exec.c:439 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "перевірка \"%s\" провалена: це не звичайний файл\n" + +#: exec.c:451 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "перевірка \"%s\" провалена: не можна прочитати файл (немає доступу)\n" + +#: exec.c:459 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "перевірка \"%s\" провалена: виконання неможливе (немає доступу)\n" + +#: file.c:43 file.c:61 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "помилка при клонуванні відношення \"%s.%s\" (\"%s\" до \"%s\"): %s\n" + +#: file.c:50 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "помилка при клонуванні відношення \"%s.%s\": не вдалося відкрити файл \"%s\": %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "помилка при клонуванні відношення \"%s.%s\": не вдалося створити файл \"%s\": %s\n" + +#: file.c:87 file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "помилка під час копіювання відношення \"%s.%s\": не вдалося відкрити файл \"%s\": %s\n" + +#: file.c:92 file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "помилка під час копіювання відношення \"%s.%s\": не вдалося створити файл \"%s\": %s\n" + +#: file.c:106 file.c:223 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "помилка під час копіювання відношення \"%s.%s\": не вдалося прочитати файл \"%s\": %s\n" + +#: file.c:118 file.c:301 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "помилка під час копіювання відношення \"%s.%s\": не вдалося записати до файлу \"%s\": %s\n" + +#: file.c:132 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "помилка під час копіювання відношення \"%s.%s\" ( з \"%s\" в \"%s\"): %s\n" + +#: file.c:151 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "помилка під час створення посилання для відношення \"%s.%s\" ( з \"%s\" в \"%s\"): %s\n" + +#: file.c:194 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "помилка під час копіювання відношення \"%s.%s\": не вдалося отримати стан файлу \"%s\": %s\n" + +#: file.c:226 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "помилка під час копіювання відношення \"%s.%s\": у файлі \"%s\" знайдена часткова сторінка\n" + +#: file.c:328 file.c:345 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "не вдалося клонувати файл між старим і новим каталогами даних: %s\n" + +#: file.c:341 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "не можливо створити файл \"%s\": %s\n" + +#: file.c:352 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "клонування файлів не підтримується на цій платформі\n" + +#: file.c:369 +#, c-format +msgid "could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "не вдалося створити жорстке посилання між старим і новим каталогами даних: %s\n" +"В режимі посилань старий і новий каталоги даних повинні знаходитись в одній файловій системі.\n" + +#: function.c:114 +#, c-format +msgid "\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n\n" +" \\df *.plpython_call_handler\n\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n\n" +" DROP FUNCTION public.plpython_call_handler()\n\n" +"in each affected database:\n\n" +msgstr "\n" +"Старий кластер має функцію \"plpython_call_handler\", визначену в схемі\n" +"\"public\", яка є дублікатом функції, визначеної в схемі \"pg_catalog\". Ви\n" +"можете переконатися в цьому, виконавши в psql:\n\n" +" \\df *.plpython_call_handler\n\n" +"Версія цієї функції в схемі \"public\" була створена встановленням plpython \n" +"версії до 8.1 і повинна бути видалена до завершення процедури pg_upgrade,\n" +"адже вона посилається на застарілий спільний об'єктний файл \"plpython\". Ви\n" +"можете видалити версію цієї функції зі схеми \"public\", виконавши наступну\n" +"команду:\n\n" +" DROP FUNCTION public.plpython_call_handler()\n\n" +"у кожній базі даних, якої це стосується:\n\n" + +#: function.c:132 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:142 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Видаліть проблемні функції старого кластера для продовження.\n" + +#: function.c:189 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Перевірка наявності необхідних бібліотек" + +#: function.c:242 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "не вдалося завантажити бібліотеку \"%s\": %s" + +#: function.c:253 +#, c-format +msgid "In database: %s\n" +msgstr "У базі даних: %s\n" + +#: function.c:263 +#, c-format +msgid "Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n\n" +msgstr "У вашій інсталяції є посилання на завантажувані бібліотеки, що \n" +"відсутні в новій інсталяції. Ви можете додати ці бібліотеки до нової інсталяції\n" +"або видалити функції, які використовують їх зі старої інсталяції. Список\n" +"проблемних бібліотек подано у файлі:\n" +" %s\n\n" + +#: info.c:131 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Імена відношень з OID %u в базі даних \"%s\" не збігаються: старе ім'я \"%s.%s\", нове ім'я \"%s.%s\"\n" + +#: info.c:151 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Не вдалося зіставити старі таблиці з новими в базі даних \"%s\"\n" + +#: info.c:240 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " це індекс в \"%s.%s\"" + +#: info.c:250 +#, c-format +msgid " which is an index on OID %u" +msgstr " це індекс у відношенні з OID %u" + +#: info.c:262 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " це TOAST-таблиця для \"%s.%s\"" + +#: info.c:270 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " це TOAST-таблиця для відношення з OID %u" + +#: info.c:274 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "У старому кластері не знайдено відповідності для нового відношення з OID %u в базі даних %s\": %s\n" + +#: info.c:277 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "У новому кластері не знайдено відповідності для старого відношення з OID %u в базі даних \"%s\": %s\n" + +#: info.c:289 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "відображення для бази даних \"%s\":\n" + +#: info.c:292 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u в %u\n" + +#: info.c:297 info.c:633 +#, c-format +msgid "\n\n" +msgstr "\n\n" + +#: info.c:322 +#, c-format +msgid "\n" +"source databases:\n" +msgstr "\n" +"вихідні бази даних:\n" + +#: info.c:324 +#, c-format +msgid "\n" +"target databases:\n" +msgstr "\n" +"цільові бази даних:\n" + +#: info.c:631 +#, c-format +msgid "Database: %s\n" +msgstr "База даних: %s\n" + +#: info.c:644 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "ім'я_відношення: %s.%s: oid_відношення: %u табл_простір: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: не може виконуватись як root\n" + +#: option.c:170 +#, c-format +msgid "invalid old port number\n" +msgstr "неприпустимий старий номер порту\n" + +#: option.c:175 +#, c-format +msgid "invalid new port number\n" +msgstr "неприпустимий новий номер порту\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: option.c:214 +#, c-format +msgid "too many command-line arguments (first is \"%s\")\n" +msgstr "забагато аргументів у командному рядку (перший \"%s\")\n" + +#: option.c:220 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Виконується в детальному режимі\n" + +#: option.c:251 +msgid "old cluster binaries reside" +msgstr "розташування двійкових даних старого кластера" + +#: option.c:253 +msgid "new cluster binaries reside" +msgstr "розташування двійкових даних нового кластера" + +#: option.c:255 +msgid "old cluster data resides" +msgstr "розташування даних старого кластера" + +#: option.c:257 +msgid "new cluster data resides" +msgstr "розташування даних нового кластера" + +#: option.c:259 +msgid "sockets will be created" +msgstr "сокети будуть створені" + +#: option.c:276 option.c:374 +#, c-format +msgid "could not determine current directory\n" +msgstr "не вдалося визначити поточний каталог\n" + +#: option.c:279 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "у Windows не можна виконати pg_upgrade всередині каталогу даних нового кластера\n" + +#: option.c:288 +#, c-format +msgid "pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n\n" +msgstr "pg_upgrade оновлює кластер PostgreSQL до іншої основної версії.\n\n" + +#: option.c:289 +#, c-format +msgid "Usage:\n" +msgstr "Використання:\n" + +#: option.c:290 +#, c-format +msgid " pg_upgrade [OPTION]...\n\n" +msgstr " pg_upgrade [OPTION]...\n\n" + +#: option.c:291 +#, c-format +msgid "Options:\n" +msgstr "Параметри:\n" + +#: option.c:292 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR каталог виконуваних файлів старого кластера\n" + +#: option.c:293 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory (default\n" +" same directory as pg_upgrade)\n" +msgstr " -B, --new-bindir=BINDIR каталог виконуваних файлів нового кластера (за замовчуванням\n" +" той самий каталог, що і pg_upgrade)\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check тільки перевірити кластери, не змінювати ніякі дані\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR каталог даних старого кластера\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR каталог даних нового кластера\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs=NUM number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs=NUM число одночасних процесів або потоків для використання\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link встановлювати посилання замість копіювання файлів до нового кластера\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPTIONS параметри старого кластера, які передаються серверу\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPTIONS параметри нового кластера, які передаються серверу\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT номер порту старого кластера (за замовчуванням %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT номер порту нового кластера (за замовчуванням %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain зберегти файли журналів і SQL після успішного завершення\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default current dir.)\n" +msgstr " -s, --socketdir=DIR директорія сокету для використання (за замовчування поточна директорія)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NAME суперкористувач кластера (за замовчуванням \"%s\")\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose активувати виведення детальних внутрішніх повідомлень\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version відобразити інформацію про версію, потім вийти\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " --clone клонувати замість копіювання файлів до нового кластера\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати цю довідку, потім вийти\n" + +#: option.c:311 +#, c-format +msgid "\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "\n" +"До виконання pg_upgrade ви повинні:\n" +" створити новий кластер баз даних (використовуючи нову версію initdb)\n" +" завершити процес postmaster, який обслуговує старий кластер\n" +" завершити процес postmaster, який обслуговує новий кластер\n" + +#: option.c:316 +#, c-format +msgid "\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "\n" +"Коли ви виконуєте pg_upgrade, ви повинні надати наступну інформацію:\n" +" каталог даних старого кластера (-d DATADIR)\n" +" каталог даних нового кластера (-D DATADIR)\n" +" каталог \"bin\" старого кластера (-b BINDIR)\n" +" каталог \"bin\" нового кластера (-B BINDIR)\n" + +#: option.c:322 +#, c-format +msgid "\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "\n" +"Наприклад:\n" +" pg_upgrade -d старий_кластер/data -D новий_кластер/data -b старий_кластер/bin -B новий_кластер/bin\n" +"або\n" + +#: option.c:327 +#, c-format +msgid " $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr " $ export PGDATAOLD=старий_кластер/data\n" +" $ export PGDATANEW=новий_кластер/data\n" +" $ export PGBINOLD=старий_кластер/bin\n" +" $ export PGBINNEW=новий_кластер/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid " C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr " C:\\> set PGDATAOLD=старий_кластер/data\n" +" C:\\> set PGDATANEW=новий_кластер/data\n" +" C:\\> set PGBINOLD=старий_кластер/bin\n" +" C:\\> set PGBINNEW=новий_кластер/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "\n" +"Report bugs to <%s>.\n" +msgstr "\n" +"Повідомляти про помилки на <%s>.\n" + +#: option.c:340 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: option.c:380 +#, c-format +msgid "You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "Ви повинні визначити каталог, де знаходиться %s.\n" +"Будь ласка, використайте параметр командного рядка %s або змінну середовища %s.\n" + +#: option.c:432 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Пошук дійсного каталогу даних для початкового кластера" + +#: option.c:434 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Пошук дійсного каталогу даних для цільового кластера" + +#: option.c:446 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "не вдалося отримати каталог даних, виконавши %s: %s\n" + +#: option.c:505 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "не вдалося прочитати рядок %d з файлу \"%s\": %s\n" + +#: option.c:522 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "вказаний користувачем старий номер порту %hu змінений на %hu\n" + +#: parallel.c:127 parallel.c:238 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "не вдалося створити робочий процес: %s\n" + +#: parallel.c:146 parallel.c:259 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "не вдалося створити робочий потік: %s\n" + +#: parallel.c:300 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "помилка waitpid(): %s\n" + +#: parallel.c:304 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "дочірній процес завершився ненормально: статус %d\n" + +#: parallel.c:319 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "дочірній процес завершився аварійно: %s\n" + +#: pg_upgrade.c:108 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "не вдалося прочитати права на каталог \"%s\": %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "\n" +"Виконання оновлення\n" +"------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Встановлення наступного OID для нового кластера" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "Синхронізація каталогу даних на диск" + +#: pg_upgrade.c:185 +#, c-format +msgid "\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "\n" +"Оновлення завершено\n" +"----------------\n" + +#: pg_upgrade.c:220 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: не вдалося знайти ехе файл власної програми\n" + +#: pg_upgrade.c:246 +#, c-format +msgid "There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "Мабуть, запущений процес postmaster, який обслуговує старий кластер.\n" +"Будь ласка, завершіть роботу процесу і спробуйте знову.\n" + +#: pg_upgrade.c:259 +#, c-format +msgid "There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "Мабуть, запущений процес postmaster, який обслуговує новий кластер.\n" +"Будь ласка, завершіть роботу процесу і спробуйте знову.\n" + +#: pg_upgrade.c:273 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Аналіз всіх рядків у новому кластері" + +#: pg_upgrade.c:286 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Закріплення всіх рядків у новому кластері" + +#: pg_upgrade.c:306 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Відновлення глобальних об'єктів у новому кластері" + +#: pg_upgrade.c:321 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Відновлення схем баз даних у новому кластері\n" + +#: pg_upgrade.c:425 +#, c-format +msgid "Deleting files from new %s" +msgstr "Видалення файлів з нового %s" + +#: pg_upgrade.c:429 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "не вдалося видалити каталог \"%s\"\n" + +#: pg_upgrade.c:448 +#, c-format +msgid "Copying old %s to new server" +msgstr "Копіювання старого %s до нового серверу" + +#: pg_upgrade.c:475 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Установка наступного ID транзакції й епохи для нового кластера" + +#: pg_upgrade.c:505 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Установка наступного ID і зсуву мультитранзакції для нового кластера" + +#: pg_upgrade.c:529 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Установка найстаршого ID мультитранзакції в новому кластері" + +#: pg_upgrade.c:549 +#, c-format +msgid "Resetting WAL archives" +msgstr "Скидання архівів WAL" + +#: pg_upgrade.c:592 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Установка лічильників frozenxid і minmxid у новому кластері" + +#: pg_upgrade.c:594 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Установка лічильника minmxid у новому кластері" + +#: relfilenode.c:35 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Клонування файлів користувацьких відношень\n" + +#: relfilenode.c:38 +#, c-format +msgid "Copying user relation files\n" +msgstr "Копіювання файлів користувацьких відношень\n" + +#: relfilenode.c:41 +#, c-format +msgid "Linking user relation files\n" +msgstr "Підключення файлів користувацьких відношень посиланнями\n" + +#: relfilenode.c:115 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "стара база даних \"%s\" не знайдена в новому кластері\n" + +#: relfilenode.c:234 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "помилка під час перевірки існування файлу \"%s.%s\" (з \"%s\" в \"%s\"): %s\n" + +#: relfilenode.c:252 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "перезаписування \"%s\" в \"%s\"\n" + +#: relfilenode.c:260 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "клонування \"%s\" до \"%s\"\n" + +#: relfilenode.c:265 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "копіювання \"%s\" в \"%s\"\n" + +#: relfilenode.c:270 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "створення посилання на \"%s\" в \"%s\"\n" + +#: server.c:33 +#, c-format +msgid "connection to database failed: %s" +msgstr "помилка підключення до бази даних: %s" + +#: server.c:39 server.c:141 util.c:135 util.c:165 +#, c-format +msgid "Failure, exiting\n" +msgstr "Помилка, вихід\n" + +#: server.c:131 +#, c-format +msgid "executing: %s\n" +msgstr "виконується: %s\n" + +#: server.c:137 +#, c-format +msgid "SQL command failed\n" +"%s\n" +"%s" +msgstr "Помилка SQL-команди\n" +"%s\n" +"%s" + +#: server.c:167 +#, c-format +msgid "could not open version file \"%s\": %m\n" +msgstr "не вдалося відкрити файл версії \"%s\": %m\n" + +#: server.c:171 +#, c-format +msgid "could not parse version file \"%s\"\n" +msgstr "не вдалося проаналізувати файл версії \"%s\"\n" + +#: server.c:297 +#, c-format +msgid "\n" +"connection to database failed: %s" +msgstr "\n" +"помилка підключення до бази даних: %s" + +#: server.c:302 +#, c-format +msgid "could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "не вдалося підключитися до початкового процесу postmaster, запущеного командою:\n" +"%s\n" + +#: server.c:306 +#, c-format +msgid "could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "не вдалося підключитися до цільового процесу postmaster, запущеного командою:\n" +"%s\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl не зміг запустити початковий сервер або сталася помилка підключення\n" + +#: server.c:322 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl не зміг запустити цільовий сервер або сталася помилка підключення\n" + +#: server.c:367 +#, c-format +msgid "out of memory\n" +msgstr "недостатньо пам'яті\n" + +#: server.c:380 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "у змінній середовища для libpq %s задано не локальне значення: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "Оновлення в межах однієї версії системного каталогу неможливе,\n" +"якщо використовуються табличні простори.\n" + +#: tablespace.c:86 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "каталог табличного простору \"%s\" не існує\n" + +#: tablespace.c:90 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "не вдалося отримати стан каталогу табличного простору \"%s\": %s\n" + +#: tablespace.c:95 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "шлях табличного простору \"%s\" не вказує на каталог\n" + +#: util.c:49 +#, c-format +msgid " " +msgstr " " + +#: util.c:82 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:174 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:29 +#, c-format +msgid "Checking for large objects" +msgstr "Перевірка великих об'єктів" + +#: version.c:77 version.c:384 +#, c-format +msgid "warning" +msgstr "попередження" + +#: version.c:79 +#, c-format +msgid "\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n\n" +msgstr "\n" +"Ваша інсталяція містить великі об'єкти. Нова база даних має\n" +"додаткову таблицю з правами для великих об'єктів. Після оновлення ви отримаєте команду для заповнення таблиці pg_largeobject_metadata \n" +"з правами за замовчуванням.\n\n" + +#: version.c:85 +#, c-format +msgid "\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n\n" +msgstr "\n" +"Ваша інсталяція містить великі об'єкти. Нова база даних має\n" +"додаткову таблицю з правами для великих об'єктів, тож для всіх\n" +"великих об'єктів повинні визначатись права за замовчуванням. Файл\n" +" %s\n" +"дозволяє встановити такі права (він призначений для виконання в psql\n" +"суперкористувачем бази даних).\n\n" + +#: version.c:239 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Перевірка несумісного типу даних \"line\"" + +#: version.c:246 +#, c-format +msgid "Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n\n" +msgstr "Користувацькі таблиці у вашій інсталяції містять тип даних \"line\". У\n" +"старому кластері внутрішній формат введення/виведення цього типу\n" +"відрізняється від нового, тож в поточному стані оновити кластер неможливо. Ви\n" +"можете видалити проблемні таблиці і перезавантажити оновлення. Список\n" +"проблемних стовпців подано у файлі:\n" +" %s\n\n" + +#: version.c:276 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Перевірка неприпустимих користувацьких стовпців \"unknown\"" + +#: version.c:283 +#, c-format +msgid "Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n\n" +msgstr "Користувацькі таблиці у вашій інсталяції містять тип даних \"unknown\". Цей тип даних\n" +"більше не допускається в таблицях, тож в поточному стані оновити кластер неможливо. Ви\n" +"можете видалити проблемні таблиці і перезавантажити оновлення. Список проблемних стовпців\n" +"подано у файлі:\n" +" %s\n\n" + +#: version.c:306 +#, c-format +msgid "Checking for hash indexes" +msgstr "Перевірка геш-індексів" + +#: version.c:386 +#, c-format +msgid "\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n\n" +msgstr "\n" +"Ваша інсталяція містить геш-індекси. Ці індекси мають різні внутрішні\n" +"формати в старому і новому кластерах, тож їх потрібно повторно індексувати\n" +"за допомогою команди REINDEX. Після оновлення вам буде надано інструкції REINDEX.\n\n" + +#: version.c:392 +#, c-format +msgid "\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n\n" +msgstr "\n" +"Ваша інсталяція містить геш-індекси. Ці індекси мають різні внутрішні\n" +"формати в старому і новому кластерах, тож їх потрібно повторно індексувати\n" +"за допомогою команди REINDEX. Файл\n" +" %s\n" +"після виконання суперкористувачем бази даних в psql, повторно створить\n" +"всі неприпустимі індекси; до цього ніякі геш-індекси не будуть використовуватись.\n\n" + +#: version.c:418 +#, c-format +msgid "Checking for invalid \"sql_identifier\" user columns" +msgstr "Перевірка неприпустимих користувацьких стовпців \"sql_identifier\"" + +#: version.c:426 +#, c-format +msgid "Your installation contains the \"sql_identifier\" data type in user tables\n" +"and/or indexes. The on-disk format for this data type has changed, so this\n" +"cluster cannot currently be upgraded. You can remove the problem tables or\n" +"change the data type to \"name\" and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n\n" +msgstr "Користувацькі таблиці або індекси у вашій інсталяції містять тип даних \"sql_identifier\". \n" +"Формат зберігання цього типу на диску змінився, тож в поточному стані оновити \n" +"кластер неможливо. Ви можете видалити проблемні таблиці або змінити тип даних \n" +"на \"name\" і спробувати знову. Список проблемних стовпців подано у файлі:\n" +" %s\n\n" + diff --git a/src/bin/pg_upgrade/relfilenode.c b/src/bin/pg_upgrade/relfilenode.c index e8485e0444bb..eded1fa8e4c7 100644 --- a/src/bin/pg_upgrade/relfilenode.c +++ b/src/bin/pg_upgrade/relfilenode.c @@ -3,7 +3,7 @@ * * relfilenode functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/relfilenode.c */ @@ -189,6 +189,12 @@ transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace) transfer_relfile(&maps[mapnum], "_vm", vm_must_add_frozenbit); } } + /* + * Copy/link any fsm and vm files, if they exist + */ + transfer_relfile(&maps[mapnum], "_fsm", vm_must_add_frozenbit); + if (vm_crashsafe_match) + transfer_relfile(&maps[mapnum], "_vm", vm_must_add_frozenbit); } } } diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c index 8a41bab8597a..3eef89439181 100644 --- a/src/bin/pg_upgrade/server.c +++ b/src/bin/pg_upgrade/server.c @@ -3,7 +3,7 @@ * * database server functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/server.c */ @@ -31,8 +31,7 @@ connectToServer(ClusterInfo *cluster, const char *db_name) if (conn == NULL || PQstatus(conn) != CONNECTION_OK) { - pg_log(PG_REPORT, "connection to database failed: %s", - PQerrorMessage(conn)); + pg_log(PG_REPORT, "%s", PQerrorMessage(conn)); if (conn) PQfinish(conn); @@ -51,6 +50,8 @@ connectToServer(ClusterInfo *cluster, const char *db_name) * get_db_conn() * * get database connection, using named database + standard params for cluster + * + * Caller must check for connection failure! */ static PGconn * get_db_conn(ClusterInfo *cluster, const char *db_name) @@ -228,7 +229,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error) snprintf(socket_string + strlen(socket_string), sizeof(socket_string) - strlen(socket_string), " -c %s='%s'", - (GET_MAJOR_VERSION(cluster->major_version) < 903) ? + (GET_MAJOR_VERSION(cluster->major_version) <= 902) ? "unix_socket_directory" : "unix_socket_directories", cluster->sockdir); #endif @@ -318,8 +319,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error) if ((conn = get_db_conn(cluster, "template1")) == NULL || PQstatus(conn) != CONNECTION_OK) { - pg_log(PG_REPORT, "\nconnection to database failed: %s", - PQerrorMessage(conn)); + pg_log(PG_REPORT, "\n%s", PQerrorMessage(conn)); if (conn) PQfinish(conn); if (cluster == &old_cluster) diff --git a/src/bin/pg_upgrade/tablespace.c b/src/bin/pg_upgrade/tablespace.c index 0001ec5cbaf3..bdf4aa57b8a2 100644 --- a/src/bin/pg_upgrade/tablespace.c +++ b/src/bin/pg_upgrade/tablespace.c @@ -3,7 +3,7 @@ * * tablespace functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/tablespace.c */ diff --git a/src/bin/pg_upgrade/test.sh b/src/bin/pg_upgrade/test.sh index 7ff06de6d182..1ba326decdd0 100644 --- a/src/bin/pg_upgrade/test.sh +++ b/src/bin/pg_upgrade/test.sh @@ -6,7 +6,7 @@ # runs the regression tests (to put in some data), runs pg_dumpall, # runs pg_upgrade, runs pg_dumpall again, compares the dumps. # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California set -e @@ -106,7 +106,6 @@ outputdir="$temp_root/regress" EXTRA_REGRESS_OPTS="$EXTRA_REGRESS_OPTS --outputdir=$outputdir" export EXTRA_REGRESS_OPTS mkdir "$outputdir" -mkdir "$outputdir"/testtablespace logdir=`pwd`/log rm -rf "$logdir" @@ -167,17 +166,24 @@ createdb "regression$dbname3" || createdb_status=$? if "$MAKE" -C "$oldsrc" installcheck-parallel; then oldpgversion=`psql -X -A -t -d regression -c "SHOW server_version_num"` - # before dumping, get rid of objects not existing in later versions + # before dumping, get rid of objects not feasible in later versions if [ "$newsrc" != "$oldsrc" ]; then fix_sql="" case $oldpgversion in 804??) - fix_sql="DROP FUNCTION public.myfunc(integer); DROP FUNCTION public.oldstyle_length(integer, text);" - ;; - *) - fix_sql="DROP FUNCTION public.oldstyle_length(integer, text);" + fix_sql="DROP FUNCTION public.myfunc(integer);" ;; esac + fix_sql="$fix_sql + DROP FUNCTION IF EXISTS + public.oldstyle_length(integer, text); -- last in 9.6 + DROP FUNCTION IF EXISTS + public.putenv(text); -- last in v13 + DROP OPERATOR IF EXISTS -- last in v13 + public.#@# (pg_catalog.int8, NONE), + public.#%# (pg_catalog.int8, NONE), + public.!=- (pg_catalog.int8, NONE), + public.#@%# (pg_catalog.int8, NONE);" psql -X -d regression -c "$fix_sql;" || psql_fix_sql_status=$? fi @@ -226,7 +232,7 @@ pg_upgrade $PG_UPGRADE_OPTS -d "${PGDATA}.old" -D "$PGDATA" -b "$oldbindir" -p " # make sure all directories and files have group permissions, on Unix hosts # Windows hosts don't support Unix-y permissions. case $testhost in - MINGW*) ;; + MINGW*|CYGWIN*) ;; *) if [ `find "$PGDATA" -type f ! -perm 640 | wc -l` -ne 0 ]; then echo "files in PGDATA with permission != 640"; exit 1; @@ -234,7 +240,7 @@ case $testhost in esac case $testhost in - MINGW*) ;; + MINGW*|CYGWIN*) ;; *) if [ `find "$PGDATA" -type d ! -perm 750 | wc -l` -ne 0 ]; then echo "directories in PGDATA with permission != 750"; exit 1; @@ -243,14 +249,6 @@ esac pg_ctl start -l "$logdir/postmaster2.log" -o "$POSTMASTER_OPTS" -w -# In the commands below we inhibit msys2 from converting the "/c" switch -# in "cmd /c" to a file system path. - -case $testhost in - MINGW*) MSYS2_ARG_CONV_EXCL=/c cmd /c analyze_new_cluster.bat ;; - *) sh ./analyze_new_cluster.sh ;; -esac - pg_dumpall --no-sync -f "$temp_root"/dump2.sql || pg_dumpall2_status=$? pg_ctl -m fast stop diff --git a/src/bin/pg_upgrade/test_gpdb.sh b/src/bin/pg_upgrade/test_gpdb.sh index b2d1dcf34716..cd0679059732 100755 --- a/src/bin/pg_upgrade/test_gpdb.sh +++ b/src/bin/pg_upgrade/test_gpdb.sh @@ -429,7 +429,12 @@ main() { export COORDINATOR_DATADIR=${temp_root} cp ${OLD_DATADIR}/../lalshell . - LANG=en_US.utf8 BLDWRAP_POSTGRES_CONF_ADDONS=fsync=off ${temp_root}/../../../../gpAux/gpdemo/demo_cluster.sh ${DEMOCLUSTER_OPTS} + # Note: do not force a locale (the upstream script pinned LANG=en_US.utf8 + # here): the new cluster must be created with the same locale as the old + # one, or pg_upgrade aborts with "lc_collate values for database ... do + # not match". Inheriting the environment guarantees that, since the old + # cluster was created in this same environment. + BLDWRAP_POSTGRES_CONF_ADDONS=fsync=off ${temp_root}/../../../../gpAux/gpdemo/demo_cluster.sh ${DEMOCLUSTER_OPTS} export COORDINATOR_DATA_DIRECTORY="${NEW_DATADIR}/qddir/demoDataDir-1" export PGPORT=17432 diff --git a/src/bin/pg_upgrade/util.c b/src/bin/pg_upgrade/util.c index ba921a2a8bbc..36b0565f1ad7 100644 --- a/src/bin/pg_upgrade/util.c +++ b/src/bin/pg_upgrade/util.c @@ -3,7 +3,7 @@ * * utility functions * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/util.c */ diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c index 4e5d27f76eb2..a3c193316d0f 100644 --- a/src/bin/pg_upgrade/version.c +++ b/src/bin/pg_upgrade/version.c @@ -3,7 +3,7 @@ * * Postgres-version-specific routines * - * Copyright (c) 2010-2020, PostgreSQL Global Development Group + * Copyright (c) 2010-2021, PostgreSQL Global Development Group * src/bin/pg_upgrade/version.c */ @@ -97,17 +97,22 @@ new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode) /* - * check_for_data_type_usage - * Detect whether there are any stored columns depending on the given type + * check_for_data_types_usage() + * Detect whether there are any stored columns depending on given type(s) * * If so, write a report to the given file name, and return true. * - * We check for the type in tables, matviews, and indexes, but not views; + * base_query should be a SELECT yielding a single column named "oid", + * containing the pg_type OIDs of one or more types that are known to have + * inconsistent on-disk representations across server versions. + * + * We check for the type(s) in tables, matviews, and indexes, but not views; * there's no storage involved in a view. */ -static bool -check_for_data_type_usage(ClusterInfo *cluster, const char *typename, - char *output_path) +bool +check_for_data_types_usage(ClusterInfo *cluster, + const char *base_query, + const char *output_path) { bool found = false; FILE *script = NULL; @@ -127,7 +132,7 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename, i_attname; /* - * The type of interest might be wrapped in a domain, array, + * The type(s) of interest might be wrapped in a domain, array, * composite, or range, and these container types can be nested (to * varying extents depending on server version, but that's not of * concern here). To handle all these cases we need a recursive CTE. @@ -135,8 +140,8 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename, initPQExpBuffer(&querybuf); appendPQExpBuffer(&querybuf, "WITH RECURSIVE oids AS ( " - /* the target type itself */ - " SELECT '%s'::pg_catalog.regtype AS oid " + /* start with the type(s) returned by base_query */ + " %s " " UNION ALL " " SELECT * FROM ( " /* inner WITH because we can only reference the CTE once */ @@ -154,37 +159,37 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename, " c.oid = a.attrelid AND " " NOT a.attisdropped AND " " a.atttypid = x.oid ", - typename); + base_query); /* Ranges were introduced in 9.2 */ if (GET_MAJOR_VERSION(cluster->major_version) >= 902) - appendPQExpBuffer(&querybuf, - " UNION ALL " + appendPQExpBufferStr(&querybuf, + " UNION ALL " /* ranges containing any type selected so far */ - " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x " - " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid"); + " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x " + " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid"); - appendPQExpBuffer(&querybuf, - " ) foo " - ") " + appendPQExpBufferStr(&querybuf, + " ) foo " + ") " /* now look for stored columns of any such type */ - "SELECT n.nspname, c.relname, a.attname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n, " - " pg_catalog.pg_attribute a " - "WHERE c.oid = a.attrelid AND " - " NOT a.attisdropped AND " - " a.atttypid IN (SELECT oid FROM oids) AND " - " c.relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_INDEX) ") AND " - " c.relnamespace = n.oid AND " + "SELECT n.nspname, c.relname, a.attname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_namespace n, " + " pg_catalog.pg_attribute a " + "WHERE c.oid = a.attrelid AND " + " NOT a.attisdropped AND " + " a.atttypid IN (SELECT oid FROM oids) AND " + " c.relkind IN (" + CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_MATVIEW) ", " + CppAsString2(RELKIND_INDEX) ") AND " + " c.relnamespace = n.oid AND " /* exclude possible orphaned temp tables */ - " n.nspname !~ '^pg_temp_' AND " - " n.nspname !~ '^pg_toast_temp_' AND " + " n.nspname !~ '^pg_temp_' AND " + " n.nspname !~ '^pg_toast_temp_' AND " /* exclude system catalogs, too */ - " n.nspname NOT IN ('pg_catalog', 'information_schema')"); + " n.nspname NOT IN ('pg_catalog', 'information_schema')"); res = executeQueryOrDie(conn, "%s", querybuf.data); @@ -222,6 +227,34 @@ check_for_data_type_usage(ClusterInfo *cluster, const char *typename, return found; } +/* + * check_for_data_type_usage() + * Detect whether there are any stored columns depending on the given type + * + * If so, write a report to the given file name, and return true. + * + * type_name should be a fully qualified type name. This is just a + * trivial wrapper around check_for_data_types_usage() to convert a + * type name into a base query. + */ +bool +check_for_data_type_usage(ClusterInfo *cluster, + const char *type_name, + const char *output_path) +{ + bool found; + char *base_query; + + base_query = psprintf("SELECT '%s'::pg_catalog.regtype AS oid", + type_name); + + found = check_for_data_types_usage(cluster, base_query, output_path); + + free(base_query); + + return found; +} + /* * old_9_3_check_for_line_data_type_usage() @@ -243,11 +276,12 @@ old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster) if (check_for_data_type_usage(cluster, "pg_catalog.line", output_path)) { pg_log(PG_REPORT, "fatal\n"); - pg_fatal("Your installation contains the \"line\" data type in user tables. This\n" - "data type changed its internal and input/output format between your old\n" - "and new clusters so this cluster cannot currently be upgraded. You can\n" - "remove the problem tables and restart the upgrade. A list of the problem\n" - "columns is in the file:\n" + pg_fatal("Your installation contains the \"line\" data type in user tables.\n" + "This data type changed its internal and input/output format\n" + "between your old and new versions so this\n" + "cluster cannot currently be upgraded. You can\n" + "drop the problem columns and restart the upgrade.\n" + "A list of the problem columns is in the file:\n" " %s\n\n", output_path); } else @@ -280,9 +314,10 @@ old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster) if (check_for_data_type_usage(cluster, "pg_catalog.unknown", output_path)) { pg_log(PG_REPORT, "fatal\n"); - pg_fatal("Your installation contains the \"unknown\" data type in user tables. This\n" - "data type is no longer allowed in tables, so this cluster cannot currently\n" - "be upgraded. You can remove the problem tables and restart the upgrade.\n" + pg_fatal("Your installation contains the \"unknown\" data type in user tables.\n" + "This data type is no longer allowed in tables, so this\n" + "cluster cannot currently be upgraded. You can\n" + "drop the problem columns and restart the upgrade.\n" "A list of the problem columns is in the file:\n" " %s\n\n", output_path); } @@ -423,10 +458,10 @@ old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster) output_path)) { pg_log(PG_REPORT, "fatal\n"); - pg_fatal("Your installation contains the \"sql_identifier\" data type in user tables\n" - "and/or indexes. The on-disk format for this data type has changed, so this\n" - "cluster cannot currently be upgraded. You can remove the problem tables or\n" - "change the data type to \"name\" and restart the upgrade.\n" + pg_fatal("Your installation contains the \"sql_identifier\" data type in user tables.\n" + "The on-disk format for this data type has changed, so this\n" + "cluster cannot currently be upgraded. You can\n" + "drop the problem columns and restart the upgrade.\n" "A list of the problem columns is in the file:\n" " %s\n\n", output_path); } diff --git a/src/bin/pg_verifybackup/nls.mk b/src/bin/pg_verifybackup/nls.mk index 8c4e5ee031d7..81b96356da6a 100644 --- a/src/bin/pg_verifybackup/nls.mk +++ b/src/bin/pg_verifybackup/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_verifybackup/nls.mk CATALOG_NAME = pg_verifybackup -AVAIL_LANGUAGES = fr sv +AVAIL_LANGUAGES = de el es fr ja ko ru sv uk zh_CN GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ parse_manifest.c \ pg_verifybackup.c \ diff --git a/src/bin/pg_verifybackup/parse_manifest.c b/src/bin/pg_verifybackup/parse_manifest.c index faee423c7ece..3b13ae5b8464 100644 --- a/src/bin/pg_verifybackup/parse_manifest.c +++ b/src/bin/pg_verifybackup/parse_manifest.c @@ -3,7 +3,7 @@ * parse_manifest.c * Parse a backup manifest in JSON format. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_verifybackup/parse_manifest.c @@ -325,7 +325,7 @@ json_manifest_object_field_start(void *state, char *fname, bool isnull) /* It's not a field we recognize. */ json_manifest_parse_failure(parse->context, - "unknown toplevel field"); + "unrecognized top-level field"); break; case JM_EXPECT_THIS_FILE_FIELD: @@ -358,7 +358,7 @@ json_manifest_object_field_start(void *state, char *fname, bool isnull) parse->wal_range_field = JMWRF_END_LSN; else json_manifest_parse_failure(parse->context, - "unexpected wal range field"); + "unexpected WAL range field"); parse->state = JM_EXPECT_THIS_WAL_RANGE_VALUE; break; @@ -469,10 +469,10 @@ json_manifest_finalize_file(JsonManifestParseState *parse) /* Pathname and size are required. */ if (parse->pathname == NULL && parse->encoded_pathname == NULL) - json_manifest_parse_failure(parse->context, "missing pathname"); + json_manifest_parse_failure(parse->context, "missing path name"); if (parse->pathname != NULL && parse->encoded_pathname != NULL) json_manifest_parse_failure(parse->context, - "both pathname and encoded pathname"); + "both path name and encoded path name"); if (parse->size == NULL) json_manifest_parse_failure(parse->context, "missing size"); if (parse->algorithm == NULL && parse->checksum != NULL) @@ -491,7 +491,7 @@ json_manifest_finalize_file(JsonManifestParseState *parse) parse->encoded_pathname, raw_length)) json_manifest_parse_failure(parse->context, - "unable to decode filename"); + "could not decode file name"); parse->pathname[raw_length] = '\0'; pfree(parse->encoded_pathname); parse->encoded_pathname = NULL; @@ -582,10 +582,10 @@ json_manifest_finalize_wal_range(JsonManifestParseState *parse) "timeline is not an integer"); if (!parse_xlogrecptr(&start_lsn, parse->start_lsn)) json_manifest_parse_failure(parse->context, - "unable to parse start LSN"); + "could not parse start LSN"); if (!parse_xlogrecptr(&end_lsn, parse->end_lsn)) json_manifest_parse_failure(parse->context, - "unable to parse end LSN"); + "could not parse end LSN"); /* Invoke the callback with the details we've gathered. */ context->perwalrange_cb(context, tli, start_lsn, end_lsn); @@ -624,7 +624,7 @@ verify_manifest_checksum(JsonManifestParseState *parse, char *buffer, size_t number_of_newlines = 0; size_t ultimate_newline = 0; size_t penultimate_newline = 0; - pg_sha256_ctx manifest_ctx; + pg_cryptohash_ctx *manifest_ctx; uint8 manifest_checksum_actual[PG_SHA256_DIGEST_LENGTH]; uint8 manifest_checksum_expected[PG_SHA256_DIGEST_LENGTH]; @@ -652,9 +652,16 @@ verify_manifest_checksum(JsonManifestParseState *parse, char *buffer, "last line not newline-terminated"); /* Checksum the rest. */ - pg_sha256_init(&manifest_ctx); - pg_sha256_update(&manifest_ctx, (uint8 *) buffer, penultimate_newline + 1); - pg_sha256_final(&manifest_ctx, manifest_checksum_actual); + manifest_ctx = pg_cryptohash_create(PG_SHA256); + if (manifest_ctx == NULL) + context->error_cb(context, "out of memory"); + if (pg_cryptohash_init(manifest_ctx) < 0) + context->error_cb(context, "could not initialize checksum of manifest"); + if (pg_cryptohash_update(manifest_ctx, (uint8 *) buffer, penultimate_newline + 1) < 0) + context->error_cb(context, "could not update checksum of manifest"); + if (pg_cryptohash_final(manifest_ctx, manifest_checksum_actual, + sizeof(manifest_checksum_actual)) < 0) + context->error_cb(context, "could not finalize checksum of manifest"); /* Now verify it. */ if (parse->manifest_checksum == NULL) @@ -667,6 +674,7 @@ verify_manifest_checksum(JsonManifestParseState *parse, char *buffer, if (memcmp(manifest_checksum_actual, manifest_checksum_expected, PG_SHA256_DIGEST_LENGTH) != 0) context->error_cb(context, "manifest checksum mismatch"); + pg_cryptohash_free(manifest_ctx); } /* diff --git a/src/bin/pg_verifybackup/parse_manifest.h b/src/bin/pg_verifybackup/parse_manifest.h index cbb7ca1397e6..b0745a0a5928 100644 --- a/src/bin/pg_verifybackup/parse_manifest.h +++ b/src/bin/pg_verifybackup/parse_manifest.h @@ -3,7 +3,7 @@ * parse_manifest.h * Parse a backup manifest in JSON format. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_verifybackup/parse_manifest.h diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c b/src/bin/pg_verifybackup/pg_verifybackup.c index 70b6ffdec00b..f5ebd57a47fc 100644 --- a/src/bin/pg_verifybackup/pg_verifybackup.c +++ b/src/bin/pg_verifybackup/pg_verifybackup.c @@ -3,7 +3,7 @@ * pg_verifybackup.c * Verify a backup against a backup manifest. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_verifybackup/pg_verifybackup.c @@ -411,8 +411,8 @@ parse_manifest_file(char *manifest_path, manifest_files_hash **ht_p, report_fatal_error("could not read file \"%s\": %m", manifest_path); else - report_fatal_error("could not read file \"%s\": read %d of %zu", - manifest_path, rc, (size_t) statbuf.st_size); + report_fatal_error("could not read file \"%s\": read %d of %lld", + manifest_path, rc, (long long int) statbuf.st_size); } /* Close the manifest file. */ @@ -471,7 +471,7 @@ record_manifest_details_for_file(JsonManifestParseContext *context, /* Make a new entry in the hash table for this file. */ m = manifest_files_insert(ht, pathname, &found); if (found) - report_fatal_error("duplicate pathname in backup manifest: \"%s\"", + report_fatal_error("duplicate path name in backup manifest: \"%s\"", pathname); /* Initialize the entry. */ @@ -638,8 +638,8 @@ verify_backup_file(verifier_context *context, char *relpath, char *fullpath) if (m->size != sb.st_size) { report_backup_error(context, - "\"%s\" has size %zu on disk but size %zu in the manifest", - relpath, (size_t) sb.st_size, m->size); + "\"%s\" has size %lld on disk but size %zu in the manifest", + relpath, (long long int) sb.st_size, m->size); m->bad = true; } @@ -726,13 +726,27 @@ verify_file_checksum(verifier_context *context, manifest_file *m, } /* Initialize checksum context. */ - pg_checksum_init(&checksum_ctx, m->checksum_type); + if (pg_checksum_init(&checksum_ctx, m->checksum_type) < 0) + { + report_backup_error(context, "could not initialize checksum of file \"%s\"", + relpath); + close(fd); + return; + } /* Read the file chunk by chunk, updating the checksum as we go. */ while ((rc = read(fd, buffer, READ_CHUNK_SIZE)) > 0) { bytes_read += rc; - pg_checksum_update(&checksum_ctx, buffer, rc); + if (pg_checksum_update(&checksum_ctx, buffer, rc) < 0) + { + report_backup_error(context, "could not update checksum of file \"%s\"", + relpath); + close(fd); + return; + } + + } if (rc < 0) report_backup_error(context, "could not read file \"%s\": %m", @@ -767,6 +781,13 @@ verify_file_checksum(verifier_context *context, manifest_file *m, /* Get the final checksum. */ checksumlen = pg_checksum_final(&checksum_ctx, checksumbuf); + if (checksumlen < 0) + { + report_backup_error(context, + "could not finalize checksum of file \"%s\"", + relpath); + return; + } /* And check it against the manifest. */ if (checksumlen != m->checksum_length) @@ -795,10 +816,8 @@ parse_required_wal(verifier_context *context, char *pg_waldump_path, pg_waldump_cmd = psprintf("\"%s\" --quiet --path=\"%s\" --timeline=%u --start=%X/%X --end=%X/%X\n", pg_waldump_path, wal_directory, this_wal_range->tli, - (uint32) (this_wal_range->start_lsn >> 32), - (uint32) this_wal_range->start_lsn, - (uint32) (this_wal_range->end_lsn >> 32), - (uint32) this_wal_range->end_lsn); + LSN_FORMAT_ARGS(this_wal_range->start_lsn), + LSN_FORMAT_ARGS(this_wal_range->end_lsn)); if (system(pg_waldump_cmd) != 0) report_backup_error(context, "WAL parsing failed for timeline %u", diff --git a/src/bin/pg_verifybackup/po/de.po b/src/bin/pg_verifybackup/po/de.po new file mode 100644 index 000000000000..6cf9d8fee17b --- /dev/null +++ b/src/bin/pg_verifybackup/po/de.po @@ -0,0 +1,501 @@ +# German message translation file for pg_verifybackup +# Copyright (C) 2020-2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_verifybackup (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_verifybackup (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-04-17 02:45+0000\n" +"PO-Revision-Date: 2021-04-17 09:54+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../../common/jsonapi.c:1066 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Escape-Sequenz »\\%s« ist nicht gültig." + +#: ../../common/jsonapi.c:1069 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Zeichen mit Wert 0x%02x muss escapt werden." + +#: ../../common/jsonapi.c:1072 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Ende der Eingabe erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1075 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Array-Element oder »]« erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1078 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "»,« oder »]« erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1081 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "»:« erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1084 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "JSON-Wert erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1087 +msgid "The input string ended unexpectedly." +msgstr "Die Eingabezeichenkette endete unerwartet." + +#: ../../common/jsonapi.c:1089 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Zeichenkette oder »}« erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1092 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "»,« oder »}« erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1095 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Zeichenkette erwartet, aber »%s« gefunden." + +#: ../../common/jsonapi.c:1098 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Token »%s« ist ungültig." + +#: ../../common/jsonapi.c:1101 +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 kann nicht in »text« umgewandelt werden." + +#: ../../common/jsonapi.c:1103 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "Nach »\\u« müssen vier Hexadezimalziffern folgen." + +#: ../../common/jsonapi.c:1106 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Unicode-Escape-Werte können nicht für Code-Punkt-Werte über 007F verwendet werden, wenn die Kodierung nicht UTF8 ist." + +#: ../../common/jsonapi.c:1108 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Unicode-High-Surrogate darf nicht auf ein High-Surrogate folgen." + +#: ../../common/jsonapi.c:1110 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Unicode-Low-Surrogate muss auf ein High-Surrogate folgen." + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "Manifest endete unerwartet" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "unerwarteter Objektstart" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "unerwartetes Objektende" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "unerwarteter Array-Start" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "unerwartetes Array-Ende" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "unerwartete Versionskennzeichnung" + +#: parse_manifest.c:328 +msgid "unrecognized top-level field" +msgstr "unbekanntes Feld auf oberster Ebene" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "unerwartetes Feld für Datei" + +#: parse_manifest.c:361 +msgid "unexpected WAL range field" +msgstr "unerwartetes Feld für WAL-Bereich" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "unbekanntes Feld für Objekt" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "unerwartete Manifestversion" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "unerwarteter Skalar" + +#: parse_manifest.c:472 +msgid "missing path name" +msgstr "fehlender Pfadname" + +#: parse_manifest.c:475 +msgid "both path name and encoded path name" +msgstr "sowohl Pfadname als auch kodierter Pfadname angegeben" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "Größenangabe fehlt" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "Prüfsumme ohne Algorithmus" + +#: parse_manifest.c:494 +msgid "could not decode file name" +msgstr "konnte Dateinamen nicht dekodieren" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "Dateigröße ist keine ganze Zahl" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "unbekannter Prüfsummenalgorithmus: »%s«" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "ungültige Prüfsumme für Datei »%s«: »%s«" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "Zeitleiste fehlt" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "Start-LSN fehlt" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "End-LSN fehlt" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "Zeitleiste ist keine ganze Zahl" + +#: parse_manifest.c:585 +msgid "could not parse start LSN" +msgstr "konnte Start-LSN nicht parsen" + +#: parse_manifest.c:588 +msgid "could not parse end LSN" +msgstr "konnte End-LSN nicht parsen" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "mindestens 2 Zeilen erwartet" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "letzte Zeile nicht durch Newline abgeschlossen" + +#: parse_manifest.c:657 +#, c-format +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: parse_manifest.c:659 +#, c-format +msgid "could not initialize checksum of manifest" +msgstr "konnte Prüfsumme des Manifests nicht initialisieren" + +#: parse_manifest.c:661 +#, c-format +msgid "could not update checksum of manifest" +msgstr "konnte Prüfsumme des Manifests nicht aktualisieren" + +#: parse_manifest.c:664 +#, c-format +msgid "could not finalize checksum of manifest" +msgstr "konnte Prüfsumme des Manifests nicht abschließen" + +#: parse_manifest.c:668 +#, c-format +msgid "manifest has no checksum" +msgstr "Manifest hat keine Prüfsumme" + +#: parse_manifest.c:672 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "ungültige Manifestprüfsumme: »%s«" + +#: parse_manifest.c:676 +#, c-format +msgid "manifest checksum mismatch" +msgstr "Manifestprüfsumme stimmt nicht überein" + +#: parse_manifest.c:691 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "konnte Backup-Manifest nicht parsen: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "kein Backup-Verzeichnis angegeben" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_verifybackup.c:298 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wird von %s benötigt, aber wurde nicht im\n" +"selben Verzeichnis wie »%s« gefunden.\n" +"Prüfen Sie Ihre Installation." + +#: pg_verifybackup.c:303 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Das Programm »%s« wurde von %s gefunden,\n" +"aber es hatte nicht die gleiche Version wie %s.\n" +"Prüfen Sie Ihre Installation." + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "Backup erfolgreich überprüft\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:752 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "konnte Datei »%s« nicht lesen: %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %lld" +msgstr "konnte Datei »%s« nicht lesen: %d von %lld gelesen" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "doppelter Pfadname im Backup-Manifest: »%s«" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "»%s« ist keine Datei und kein Verzeichnis" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "»%s« ist auf der Festplatte vorhanden, aber nicht im Manifest" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %lld on disk but size %zu in the manifest" +msgstr "»%s« hat Größe %lld auf Festplatte aber Größe %zu im Manifest" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "»%s« steht im Manifest, ist aber nicht auf der Festplatte vorhanden" + +#: pg_verifybackup.c:731 +#, c-format +msgid "could not initialize checksum of file \"%s\"" +msgstr "konnte Prüfsumme der Datei »%s« nicht initialisieren" + +#: pg_verifybackup.c:743 +#, c-format +msgid "could not update checksum of file \"%s\"" +msgstr "konnte Prüfsumme der Datei »%s« nicht aktualisieren" + +#: pg_verifybackup.c:758 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schließen: %m" + +#: pg_verifybackup.c:777 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "Datei »%s« sollte %zu Bytes enthalten, aber %zu Bytes wurden gelesen" + +#: pg_verifybackup.c:787 +#, c-format +msgid "could not finalize checksum of file \"%s\"" +msgstr "konnte Prüfsumme der Datei »%s« nicht abschließen" + +#: pg_verifybackup.c:795 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "Datei »%s« hat Prüfsumme mit Länge %d, aber %d wurde erwartet" + +#: pg_verifybackup.c:799 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "Prüfsumme stimmt nicht überein für Datei »%s«" + +#: pg_verifybackup.c:823 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "Parsen des WAL fehlgeschlagen für Zeitleiste %u" + +#: pg_verifybackup.c:909 +#, c-format +msgid "" +"%s verifies a backup against the backup manifest.\n" +"\n" +msgstr "" +"%s überprüft ein Backup anhand eines Backup-Manifests.\n" +"\n" + +#: pg_verifybackup.c:910 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... BACKUPDIR\n" +"\n" +msgstr "" +"Aufruf:\n" +" %s [OPTION]... BACKUPVERZ\n" +"\n" + +#: pg_verifybackup.c:911 +#, c-format +msgid "Options:\n" +msgstr "Optionen:\n" + +#: pg_verifybackup.c:912 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, --exit-on-error bei Fehler sofort beenden\n" + +#: pg_verifybackup.c:913 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr " -i, --ignore=REL-PFAD angegebenen Pfad ignorieren\n" + +#: pg_verifybackup.c:914 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, --manifest-path=PFAD angegebenen Pfad für Manifest verwenden\n" + +#: pg_verifybackup.c:915 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, --no-parse-wal nicht versuchen WAL-Dateien zu parsen\n" + +#: pg_verifybackup.c:916 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet keine Ausgabe, außer Fehler\n" + +#: pg_verifybackup.c:917 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, --skip-checksums Überprüfung der Prüfsummen überspringen\n" + +#: pg_verifybackup.c:918 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr " -w, --wal-directory=PFAD angegebenen Pfad für WAL-Dateien verwenden\n" + +#: pg_verifybackup.c:919 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_verifybackup.c:920 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_verifybackup.c:921 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Berichten Sie Fehler an <%s>.\n" + +#: pg_verifybackup.c:922 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" diff --git a/src/bin/pg_verifybackup/po/el.po b/src/bin/pg_verifybackup/po/el.po new file mode 100644 index 000000000000..ce869d591d23 --- /dev/null +++ b/src/bin/pg_verifybackup/po/el.po @@ -0,0 +1,503 @@ +# Greek message translation file for pg_verifybackup +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_verifybackup (PostgreSQL) package. +# Georgios Kokolatos , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_verifybackup (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-31 23:45+0000\n" +"PO-Revision-Date: 2021-06-04 09:16+0200\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "έλλειψη μνήμης\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "δεν ήταν δυνατή η αντιγραφή δείκτη null (εσωτερικό σφάλμα)\n" + +#: ../../common/jsonapi.c:1066 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Η ακολουθία διαφυγής \"\\%s\" δεν είναι έγκυρη." + +#: ../../common/jsonapi.c:1069 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Ο χαρακτήρας με τιμή 0x%02x πρέπει να διαφύγει." + +#: ../../common/jsonapi.c:1072 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Ανέμενε τέλος εισόδου, αλλά βρήκε “%s”." + +#: ../../common/jsonapi.c:1075 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Ανέμενε στοιχείο συστυχίας ή \"]\", αλλά βρέθηκε \"%s\"." + +#: ../../common/jsonapi.c:1078 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Ανέμενε “,” ή “]”, αλλά βρήκε “%s”." + +#: ../../common/jsonapi.c:1081 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Ανέμενε \":\", αλλά βρήκε \"%s\"." + +#: ../../common/jsonapi.c:1084 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Ανέμενε τιμή JSON, αλλά βρήκε \"%s\"." + +#: ../../common/jsonapi.c:1087 +msgid "The input string ended unexpectedly." +msgstr "Η συμβολοσειρά εισόδου τερματίστηκε αναπάντεχα." + +#: ../../common/jsonapi.c:1089 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Ανέμενε συμβολοσειρά ή “}”, αλλά βρήκε “%s”." + +#: ../../common/jsonapi.c:1092 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Ανέμενε “,” ή “}”, αλλά βρήκε “%s”." + +#: ../../common/jsonapi.c:1095 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Ανέμενε συμβολοσειρά, αλλά βρήκε “%s”." + +#: ../../common/jsonapi.c:1098 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Το διακριτικό \"%s\" δεν είναι έγκυρο." + +#: ../../common/jsonapi.c:1101 +msgid "\\u0000 cannot be converted to text." +msgstr "Δεν είναι δυνατή η μετατροπή του \\u0000 σε κείμενο." + +#: ../../common/jsonapi.c:1103 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "Το \"\\u\" πρέπει να ακολουθείται από τέσσερα δεκαεξαδικά ψηφία." + +#: ../../common/jsonapi.c:1106 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Δεν μπορούν να χρησιμοποιηθούν τιμές διαφυγής Unicode για τιμές σημείου κώδικα άνω του 007F όταν η κωδικοποίηση δεν είναι UTF8." + +#: ../../common/jsonapi.c:1108 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Υψηλό διακριτικό Unicode δεν πρέπει να ακολουθεί υψηλό διακριτικό." + +#: ../../common/jsonapi.c:1110 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Χαμηλό διακριτικό Unicode πρέπει να ακολουθεί υψηλό διακριτικό." + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "η διακήρυξη έληξε απροσδόκητα" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "μη αναμενόμενη αρχή αντικειμένου" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "μη αναμενόμενο τέλος αντικειμένου" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "μη αναμενόμενη αρχή συστοιχίας" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "μη αναμενόμενο τέλος συστοιχίας" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "ανέμενε ένδειξη έκδοσης" + +#: parse_manifest.c:328 +msgid "unrecognized top-level field" +msgstr "μη αναγνωρίσιμο πεδίο ανώτατου επιπέδου" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "μη αναμενόμενο πεδίο αρχείου" + +#: parse_manifest.c:361 +msgid "unexpected WAL range field" +msgstr "μη αναμενόμενο πεδίο περιοχής WAL" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "μη αναμενόμενο πεδίο αντικειμένου" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "μη αναμενόμενη έκδοση διακήρυξης" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "μη αναμενόμενο scalar" + +#: parse_manifest.c:472 +msgid "missing path name" +msgstr "λείπει όνομα διαδρομής" + +#: parse_manifest.c:475 +msgid "both path name and encoded path name" +msgstr "και όνομα διαδρομής και κωδικοποιημένο όνομα διαδρομής" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "λείπει το μέγεθος" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "άθροισμα ελέγχου χωρίς αλγόριθμο" + +#: parse_manifest.c:494 +msgid "could not decode file name" +msgstr "δεν ήταν δυνατή η αποκωδικοποίηση του ονόματος αρχείου" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "το μέγεθος αρχείου δεν είναι ακέραιος" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "μη αναγνωρίσιμος αλγόριθμος αθροίσματος ελέγχου: \"%s\"" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "μη έγκυρο άθροισμα ελέγχου για το αρχείο \"%s\": \"%s\"" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "λείπει η χρονογραμμή" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "λείπει αρχικό LSN" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "λείπει τελικό LSN" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "η χρονογραμμή δεν είναι ακέραιος" + +#: parse_manifest.c:585 +msgid "could not parse start LSN" +msgstr "δεν ήταν δυνατή η ανάλυση του αρχικού LSN" + +#: parse_manifest.c:588 +msgid "could not parse end LSN" +msgstr "δεν ήταν δυνατή η ανάλυση του τελικού LSN" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "αναμένονταν τουλάχιστον 2 γραμμές" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "η τελευταία γραμμή δεν τερματίστηκε με newline" + +#: parse_manifest.c:657 +#, c-format +msgid "out of memory" +msgstr "έλλειψη μνήμης" + +#: parse_manifest.c:659 +#, c-format +msgid "could not initialize checksum of manifest" +msgstr "δεν ήταν δυνατή η αρχικοποίηση του αθροίσματος ελέγχου της διακήρυξης" + +#: parse_manifest.c:661 +#, c-format +msgid "could not update checksum of manifest" +msgstr "δεν ήταν δυνατή η ενημέρωση του αθροίσματος ελέγχου της διακήρυξης" + +#: parse_manifest.c:664 +#, c-format +msgid "could not finalize checksum of manifest" +msgstr "δεν ήταν δυνατή η ολοκλήρωση του αθροίσματος ελέγχου της διακήρυξης" + +#: parse_manifest.c:668 +#, c-format +msgid "manifest has no checksum" +msgstr "η διακήρυξη δεν έχει άθροισμα ελέγχου" + +#: parse_manifest.c:672 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "μη έγκυρο άθροισμα ελέγχου διακήρυξης: \"%s\"" + +#: parse_manifest.c:676 +#, c-format +msgid "manifest checksum mismatch" +msgstr "αναντιστοιχία ελέγχου αθροίσματος διακήρυξης" + +#: parse_manifest.c:691 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "δεν ήταν δυνατή η ανάλυση του αντιγράφου ασφαλείας της διακήρυξης: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "δεν ορίστηκε κατάλογος αντιγράφου ασφαλείας" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (ο πρώτη είναι η “%s”)" + +#: pg_verifybackup.c:298 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Το πρόγραμμα \"%s\" απαιτείται από %s αλλά δεν βρέθηκε στο\n" +"ίδιος κατάλογος με το \"%s\".\n" +"Ελέγξτε την εγκατάστασή σας." + +#: pg_verifybackup.c:303 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Το πρόγραμμα \"%s\" βρέθηκε από το \"%s\"\n" +"αλλά δεν ήταν η ίδια εκδοχή με %s.\n" +"Ελέγξτε την εγκατάστασή σας." + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "το αντίγραφο ασφαλείας επαληθεύτηκε με επιτυχία\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου “%s”: %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση stat στο αρχείο “%s”: %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:752 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του αρχείου \"%s\": %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %lld" +msgstr "δεν ήταν δυνατή η ανάγνωση του αρχείου \"%s\": ανέγνωσε %d από %lld" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "διπλότυπο όνομα διαδρομής στη διακήρυξη αντιγράφου ασφαλείας: \"%s\"" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του καταλόγου “%s”: %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο του καταλόγου “%s”: %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση stat στο αρχείο ή κατάλογο “%s”: %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "“%s” δεν είναι αρχείο ή κατάλογος" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "\"%s\" βρίσκεται στο δίσκο, αλλά όχι στη διακήρυξη" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %lld on disk but size %zu in the manifest" +msgstr "\"%s\" έχει μέγεθος %lld στο δίσκο, αλλά μέγεθος %zu στη διακήρυξη" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "\"%s\" βρίσκεται στη διακήρυξη αλλά όχι στο δίσκο" + +#: pg_verifybackup.c:731 +#, c-format +msgid "could not initialize checksum of file \"%s\"" +msgstr "δεν ήταν δυνατή η αρχικοποίηση του αθροίσματος ελέγχου του αρχείου \"%s\"" + +#: pg_verifybackup.c:743 +#, c-format +msgid "could not update checksum of file \"%s\"" +msgstr "δεν ήταν δυνατή η ενημέρωση αθροίσματος ελέγχου του αρχείου “%s”" + +#: pg_verifybackup.c:758 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "δεν ήταν δυνατό το κλείσιμο του αρχείου “%s”: %m" + +#: pg_verifybackup.c:777 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "το αρχείο \"%s\" έπρεπε να περιέχει %zu bytes, αλλά να αναγνώστηκαν %zu bytes" + +#: pg_verifybackup.c:787 +#, c-format +msgid "could not finalize checksum of file \"%s\"" +msgstr "δεν ήταν δυνατή η ολοκλήρωση του αθροίσματος ελέγχου του αρχείου \"%s\"" + +#: pg_verifybackup.c:795 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "το αρχείο \"%s\" έχει άθροισμα ελέγχου μήκους %d, αλλά αναμένεται %d" + +#: pg_verifybackup.c:799 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "αναντιστοιχία αθροίσματος ελέγχου για το αρχείο \"%s\"" + +#: pg_verifybackup.c:823 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "απέτυχε η ανάλυση WAL για την χρονογραμμή %u" + +#: pg_verifybackup.c:909 +#, c-format +msgid "" +"%s verifies a backup against the backup manifest.\n" +"\n" +msgstr "" +"%s επαληθεύει ένα αντίγραφο ασφαλείας έναντι της διακήρυξης αντιγράφων ασφαλείας.\n" +"\n" + +#: pg_verifybackup.c:910 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... BACKUPDIR\n" +"\n" +msgstr "" +"Χρήση:\n" +" %s [ΕΠΙΛΟΓΗ]… BACKUPDIR\n" +"\n" + +#: pg_verifybackup.c:911 +#, c-format +msgid "Options:\n" +msgstr "Επιλογές:\n" + +#: pg_verifybackup.c:912 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, —exit-on-error να εξέλθει άμεσα σε σφάλμα\n" + +#: pg_verifybackup.c:913 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr " -i, —ignore=RELATIVE_PATH αγνόησε την υποδεικνυόμενη διαδρομή\n" + +#: pg_verifybackup.c:914 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, —manifest-path=PATH χρησιμοποίησε την καθορισμένη διαδρομή για την διακήρυξη\n" + +#: pg_verifybackup.c:915 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, —no-parse-wal μην δοκιμάσεις να αναλύσεις αρχεία WAL\n" + +#: pg_verifybackup.c:916 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, —quiet να μην εκτυπώσεις καμία έξοδο, εκτός από σφάλματα\n" + +#: pg_verifybackup.c:917 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, —skip-checksums παράκαμψε την επαλήθευση αθροισμάτων ελέγχου\n" + +#: pg_verifybackup.c:918 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr " -w, —wal-directory=PATH χρησιμοποίησε την καθορισμένη διαδρομή για αρχεία WAL\n" + +#: pg_verifybackup.c:919 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης, στη συνέχεια έξοδος\n" + +#: pg_verifybackup.c:920 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, μετά έξοδος\n" + +#: pg_verifybackup.c:921 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_verifybackup.c:922 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" diff --git a/src/bin/pg_verifybackup/po/es.po b/src/bin/pg_verifybackup/po/es.po new file mode 100644 index 000000000000..c2c79108a2c4 --- /dev/null +++ b/src/bin/pg_verifybackup/po/es.po @@ -0,0 +1,505 @@ +# Spanish message translation file for pg_verifybackup +# Copyright (C) 2020 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_verifybackup (PostgreSQL) package. +# Álvaro Herrera , 2020. +# Carlos Chapi , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-14 19:45+0000\n" +"PO-Revision-Date: 2021-05-24 16:53-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../../common/jsonapi.c:1066 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "La secuencia de escape «%s» no es válida." + +#: ../../common/jsonapi.c:1069 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Los caracteres con valor 0x%02x deben ser escapados." + +#: ../../common/jsonapi.c:1072 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Se esperaba el fin de la entrada, se encontró «%s»." + +#: ../../common/jsonapi.c:1075 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Se esperaba un elemento de array o «]», se encontró «%s»." + +#: ../../common/jsonapi.c:1078 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Se esperaba «,» o «]», se encontró «%s»." + +#: ../../common/jsonapi.c:1081 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Se esperaba «:», se encontró «%s»." + +#: ../../common/jsonapi.c:1084 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Se esperaba un valor JSON, se encontró «%s»." + +#: ../../common/jsonapi.c:1087 +msgid "The input string ended unexpectedly." +msgstr "La cadena de entrada terminó inesperadamente." + +#: ../../common/jsonapi.c:1089 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Se esperaba una cadena o «}», se encontró «%s»." + +#: ../../common/jsonapi.c:1092 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Se esperaba «,» o «}», se encontró «%s»." + +#: ../../common/jsonapi.c:1095 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Se esperaba una cadena, se encontró «%s»." + +#: ../../common/jsonapi.c:1098 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "El elemento «%s» no es válido." + +#: ../../common/jsonapi.c:1101 +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 no puede ser convertido a text." + +#: ../../common/jsonapi.c:1103 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "«\\u» debe ser seguido por cuatro dígitos hexadecimales." + +#: ../../common/jsonapi.c:1106 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Los valores de escape Unicode no se pueden utilizar para valores de código superiores a 007F cuando la codificación no es UTF8." + +#: ../../common/jsonapi.c:1108 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Un «high-surrogate» Unicode no puede venir después de un «high-surrogate»." + +#: ../../common/jsonapi.c:1110 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Un «low-surrogate» Unicode debe seguir a un «high-surrogate»." + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "el manifiesto terminó inesperadamente" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "inicio de objeto inesperado" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "fin de objeto inesperado" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "inicio de array inesperado" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "fin de array inesperado" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "se esperaba indicador de versión" + +#: parse_manifest.c:328 +msgid "unrecognized top-level field" +msgstr "campo de nivel superior no reconocido" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "campo de archivo inesperado" + +#: parse_manifest.c:361 +msgid "unexpected WAL range field" +msgstr "campo de rango de WAL inesperado" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "campo de objeto inesperado" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "versión de manifiesto inesperada" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "escalar inesperado" + +#: parse_manifest.c:472 +msgid "missing path name" +msgstr "ruta de archivo faltante" + +#: parse_manifest.c:475 +msgid "both path name and encoded path name" +msgstr "hay ambos ruta de archivo (path name) y ruta codificada (encoded path name)" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "tamaño faltante" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "suma de comprobación sin algoritmo" + +#: parse_manifest.c:494 +msgid "could not decode file name" +msgstr "no se pudo decodificar el nombre del archivo" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "el tamaño del archivo no es un número entero" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "algoritmo de suma de comprobación no reconocido: \"%s\"" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "suma de comprobación no válida para el archivo \"%s\": \"%s\"" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "falta el timeline" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "falta el LSN de inicio" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "falta el LSN de término" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "el timeline no es un número entero" + +#: parse_manifest.c:585 +msgid "could not parse start LSN" +msgstr "no se pudo interpretar el LSN de inicio" + +#: parse_manifest.c:588 +msgid "could not parse end LSN" +msgstr "no se pudo interpretar el LSN de término" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "esperado al menos 2 líneas" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "última línea no termina en nueva línea" + +#: parse_manifest.c:657 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" + +#: parse_manifest.c:659 +#, c-format +msgid "could not initialize checksum of manifest" +msgstr "no se pudo inicializar la suma de verificación del manifiesto" + +#: parse_manifest.c:661 +#, c-format +msgid "could not update checksum of manifest" +msgstr "no se pudo actualizar la suma de verificación del manifiesto" + +#: parse_manifest.c:664 +#, c-format +msgid "could not finalize checksum of manifest" +msgstr "no se pudo finalizar la suma de verificación del manifiesto" + +#: parse_manifest.c:668 +#, c-format +msgid "manifest has no checksum" +msgstr "el manifiesto no tiene suma de comprobación" + +#: parse_manifest.c:672 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "suma de comprobación de manifiesto no válida: \"%s\"" + +#: parse_manifest.c:676 +#, c-format +msgid "manifest checksum mismatch" +msgstr "discordancia en la suma de comprobación del manifiesto" + +#: parse_manifest.c:691 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "no se pudo analizar el manifiesto de la copia de seguridad: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "no fue especificado el directorio de respaldo" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_verifybackup.c:298 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%s necesita el programa «%s», pero no pudo encontrarlo en el mismo\n" +"directorio que «%s».\n" +"Verifique su instalación." + +#: pg_verifybackup.c:303 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"El programa «%s» fue encontrado por «%s»,\n" +"pero no es de la misma versión que %s.\n" +"Verifique su instalación." + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "copia de seguridad verificada correctamente\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:752 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %lld" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %lld" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "nombre de ruta duplicado en el manifiesto de la copia de seguridad: \"%s\"" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "no se pudo hacer stat al archivo o directorio «%s»: %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "\"%s\" no es un archivo o directorio" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "\"%s\" está presente en el disco pero no en el manifiesto" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %lld on disk but size %zu in the manifest" +msgstr "\"%s\" tiene un tamaño %lld en el disco pero un tamaño %zu en el manifiesto" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "\"%s\" está presente en el manifiesto pero no en el disco" + +#: pg_verifybackup.c:731 +#, c-format +msgid "could not initialize checksum of file \"%s\"" +msgstr "no se pudo inicializar la suma de verificación para el archivo «%s»" + +#: pg_verifybackup.c:743 +#, c-format +msgid "could not update checksum of file \"%s\"" +msgstr "no se pudo actualizar la suma de verificación para el archivo «%s»" + +#: pg_verifybackup.c:758 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" + +#: pg_verifybackup.c:777 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "el archivo \"%s\" debe contener %zu bytes, pero se leyeron %zu bytes" + +#: pg_verifybackup.c:787 +#, c-format +msgid "could not finalize checksum of file \"%s\"" +msgstr "no se pudo finalizar la suma de verificación para el archivo «%s»" + +#: pg_verifybackup.c:795 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "el archivo \"%s\" tiene una suma de comprobación de longitud %d, pero se esperaba %d" + +#: pg_verifybackup.c:799 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "no coincide la suma de comprobación para el archivo \"%s\"" + +#: pg_verifybackup.c:823 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "Error al analizar el WAL para el timeline %u" + +#: pg_verifybackup.c:909 +#, c-format +msgid "" +"%s verifies a backup against the backup manifest.\n" +"\n" +msgstr "" +"%s verifica una copia de seguridad con el fichero de manifiesto de la copia de seguridad.\n" +"\n" + +#: pg_verifybackup.c:910 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... BACKUPDIR\n" +"\n" +msgstr "" +"Uso:\n" +" %s [OPCIÓN]... BACKUPDIR\n" +"\n" + +#: pg_verifybackup.c:911 +#, c-format +msgid "Options:\n" +msgstr "Opciones:\n" + +#: pg_verifybackup.c:912 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, --exit-on-error salir inmediatamente en caso de error\n" + +#: pg_verifybackup.c:913 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr " -i, --ignore=RELATIVE_PATH ignorar la ruta indicada\n" + +#: pg_verifybackup.c:914 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, --manifest-path=PATH usar la ruta especificada para el manifiesto\n" + +#: pg_verifybackup.c:915 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, --no-parse-wal no intentar analizar archivos WAL\n" + +#: pg_verifybackup.c:916 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet no escribir ningún mensaje, excepto errores\n" + +#: pg_verifybackup.c:917 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, --skip-checksums omitir la verificación de la suma de comprobación\n" + +#: pg_verifybackup.c:918 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr " -w, --wal-directory=PATH utilizar la ruta especificada para los archivos WAL\n" + +#: pg_verifybackup.c:919 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar la información de la versión, luego salir\n" + +#: pg_verifybackup.c:920 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help muestra esta ayuda, luego salir\n" + +#: pg_verifybackup.c:921 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_verifybackup.c:922 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" diff --git a/src/bin/pg_verifybackup/po/fr.po b/src/bin/pg_verifybackup/po/fr.po index 4d55e05f053f..9ad27058e328 100644 --- a/src/bin/pg_verifybackup/po/fr.po +++ b/src/bin/pg_verifybackup/po/fr.po @@ -7,27 +7,27 @@ msgid "" msgstr "" "Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2020-05-11 07:44+0000\n" -"PO-Revision-Date: 2020-05-11 10:14+0200\n" +"POT-Creation-Date: 2021-04-15 01:45+0000\n" +"PO-Revision-Date: 2021-04-15 08:45+0200\n" +"Last-Translator: \n" +"Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: \n" -"Language-Team: \n" -"X-Generator: Poedit 2.3\n" +"X-Generator: Poedit 2.4.2\n" -#: ../../../src/common/logging.c:236 +#: ../../../src/common/logging.c:259 #, c-format msgid "fatal: " msgstr "fatal : " -#: ../../../src/common/logging.c:243 +#: ../../../src/common/logging.c:266 #, c-format msgid "error: " msgstr "erreur : " -#: ../../../src/common/logging.c:250 +#: ../../../src/common/logging.c:273 #, c-format msgid "warning: " msgstr "attention : " @@ -43,82 +43,82 @@ msgstr "mémoire épuisée\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" -#: ../../common/jsonapi.c:1064 +#: ../../common/jsonapi.c:1066 #, c-format msgid "Escape sequence \"\\%s\" is invalid." msgstr "La séquence d'échappement « \\%s » est invalide." -#: ../../common/jsonapi.c:1067 +#: ../../common/jsonapi.c:1069 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "Le caractère de valeur 0x%02x doit être échappé." -#: ../../common/jsonapi.c:1070 +#: ../../common/jsonapi.c:1072 #, c-format msgid "Expected end of input, but found \"%s\"." msgstr "Attendait une fin de l'entrée, mais a trouvé « %s »." -#: ../../common/jsonapi.c:1073 +#: ../../common/jsonapi.c:1075 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." msgstr "Élément de tableau ou « ] » attendu, mais trouvé « %s »." -#: ../../common/jsonapi.c:1076 +#: ../../common/jsonapi.c:1078 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." msgstr "« , » ou « ] » attendu, mais trouvé « %s »." -#: ../../common/jsonapi.c:1079 +#: ../../common/jsonapi.c:1081 #, c-format msgid "Expected \":\", but found \"%s\"." msgstr "« : » attendu, mais trouvé « %s »." -#: ../../common/jsonapi.c:1082 +#: ../../common/jsonapi.c:1084 #, c-format msgid "Expected JSON value, but found \"%s\"." msgstr "Valeur JSON attendue, mais « %s » trouvé." -#: ../../common/jsonapi.c:1085 +#: ../../common/jsonapi.c:1087 msgid "The input string ended unexpectedly." msgstr "La chaîne en entrée se ferme de manière inattendue." -#: ../../common/jsonapi.c:1087 +#: ../../common/jsonapi.c:1089 #, c-format msgid "Expected string or \"}\", but found \"%s\"." msgstr "Chaîne ou « } » attendu, mais « %s » trouvé" -#: ../../common/jsonapi.c:1090 +#: ../../common/jsonapi.c:1092 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." msgstr "« , » ou « } » attendu, mais trouvé « %s »." -#: ../../common/jsonapi.c:1093 +#: ../../common/jsonapi.c:1095 #, c-format msgid "Expected string, but found \"%s\"." msgstr "Chaîne attendue, mais « %s » trouvé." -#: ../../common/jsonapi.c:1096 +#: ../../common/jsonapi.c:1098 #, c-format msgid "Token \"%s\" is invalid." msgstr "Le jeton « %s » n'est pas valide." -#: ../../common/jsonapi.c:1099 +#: ../../common/jsonapi.c:1101 msgid "\\u0000 cannot be converted to text." msgstr "\\u0000 ne peut pas être converti en texte." -#: ../../common/jsonapi.c:1101 +#: ../../common/jsonapi.c:1103 msgid "\"\\u\" must be followed by four hexadecimal digits." msgstr "« \\u » doit être suivi par quatre chiffres hexadécimaux." -#: ../../common/jsonapi.c:1104 +#: ../../common/jsonapi.c:1106 msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." msgstr "les valeurs d'échappement Unicode ne peuvent pas être utilisées pour des valeurs de point code au-dessus de 007F quand l'encodage n'est pas UTF8." -#: ../../common/jsonapi.c:1106 +#: ../../common/jsonapi.c:1108 msgid "Unicode high surrogate must not follow a high surrogate." msgstr "Une substitution unicode haute ne doit pas suivre une substitution haute." -#: ../../common/jsonapi.c:1108 +#: ../../common/jsonapi.c:1110 msgid "Unicode low surrogate must follow a high surrogate." msgstr "Une substitution unicode basse ne doit pas suivre une substitution haute." @@ -147,7 +147,7 @@ msgid "expected version indicator" msgstr "indicateur de version inattendu" #: parse_manifest.c:328 -msgid "unknown toplevel field" +msgid "unrecognized top-level field" msgstr "champ haut niveau inconnu" #: parse_manifest.c:347 @@ -155,7 +155,7 @@ msgid "unexpected file field" msgstr "champ de fichier inattendu" #: parse_manifest.c:361 -msgid "unexpected wal range field" +msgid "unexpected WAL range field" msgstr "champ d'intervalle de WAL inattendu" #: parse_manifest.c:367 @@ -171,12 +171,12 @@ msgid "unexpected scalar" msgstr "scalaire inattendu" #: parse_manifest.c:472 -msgid "missing pathname" -msgstr "chemin manquant" +msgid "missing path name" +msgstr "nom de chemin manquant" #: parse_manifest.c:475 -msgid "both pathname and encoded pathname" -msgstr "le chemin et le chemin encodé" +msgid "both path name and encoded path name" +msgstr "le nom du chemin et le nom du chemin encodé" #: parse_manifest.c:477 msgid "missing size" @@ -187,8 +187,8 @@ msgid "checksum without algorithm" msgstr "somme de contrôle sans algorithme" #: parse_manifest.c:494 -msgid "unable to decode filename" -msgstr "incapable de décoder le nom du fichier" +msgid "could not decode file name" +msgstr "n'a pas pu décoder le nom du fichier" #: parse_manifest.c:504 msgid "file size is not an integer" @@ -221,12 +221,12 @@ msgid "timeline is not an integer" msgstr "la timeline n'est pas un entier" #: parse_manifest.c:585 -msgid "unable to parse start LSN" -msgstr "incapable d'analyser le LSN de début" +msgid "could not parse start LSN" +msgstr "n'a pas pu analyser le LSN de début" #: parse_manifest.c:588 -msgid "unable to parse end LSN" -msgstr "incapable d'analyser le LSN de fin" +msgid "could not parse end LSN" +msgstr "n'a pas pu analyser le LSN de fin" #: parse_manifest.c:649 msgid "expected at least 2 lines" @@ -236,22 +236,42 @@ msgstr "attendait au moins deux lignes" msgid "last line not newline-terminated" msgstr "dernière ligne non terminée avec un caractère newline" +#: parse_manifest.c:657 +#, c-format +msgid "out of memory" +msgstr "mémoire épuisée" + +#: parse_manifest.c:659 +#, c-format +msgid "could not initialize checksum of manifest" +msgstr "n'a pas pu initialiser la somme de contrôle du manifeste" + #: parse_manifest.c:661 #, c-format +msgid "could not update checksum of manifest" +msgstr "n'a pas pu mettre à jour la somme de contrôle du manifeste" + +#: parse_manifest.c:664 +#, c-format +msgid "could not finalize checksum of manifest" +msgstr "n'a pas pu finaliser la somme de contrôle du manifeste" + +#: parse_manifest.c:668 +#, c-format msgid "manifest has no checksum" msgstr "le manifeste n'a pas de somme de contrôle" -#: parse_manifest.c:665 +#: parse_manifest.c:672 #, c-format msgid "invalid manifest checksum: \"%s\"" msgstr "somme de contrôle du manifeste invalide : « %s »" -#: parse_manifest.c:669 +#: parse_manifest.c:676 #, c-format msgid "manifest checksum mismatch" msgstr "différence de somme de contrôle pour le manifeste" -#: parse_manifest.c:683 +#: parse_manifest.c:691 #, c-format msgid "could not parse backup manifest: %s" msgstr "n'a pas pu analyser le manifeste de sauvegarde : %s" @@ -298,7 +318,7 @@ msgstr "" msgid "backup successfully verified\n" msgstr "sauvegarde vérifiée avec succès\n" -#: pg_verifybackup.c:387 pg_verifybackup.c:724 +#: pg_verifybackup.c:387 pg_verifybackup.c:723 #, c-format msgid "could not open file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier « %s » : %m" @@ -308,20 +328,20 @@ msgstr "n'a pas pu ouvrir le fichier « %s » : %m" msgid "could not stat file \"%s\": %m" msgstr "n'a pas pu tester le fichier « %s » : %m" -#: pg_verifybackup.c:411 pg_verifybackup.c:739 +#: pg_verifybackup.c:411 pg_verifybackup.c:752 #, c-format msgid "could not read file \"%s\": %m" msgstr "n'a pas pu lire le fichier « %s » : %m" #: pg_verifybackup.c:414 #, c-format -msgid "could not read file \"%s\": read %d of %zu" -msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %zu" +msgid "could not read file \"%s\": read %d of %lld" +msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %lld" #: pg_verifybackup.c:474 #, c-format -msgid "duplicate pathname in backup manifest: \"%s\"" -msgstr "chemin dupliqué dans le manifeste de sauvegarde : « %s »" +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "nom de chemin dupliqué dans le manifeste de sauvegarde : « %s »" #: pg_verifybackup.c:537 pg_verifybackup.c:544 #, c-format @@ -352,40 +372,55 @@ msgstr "« %s » est présent sur disque mais pas dans le manifeste" #: pg_verifybackup.c:641 #, c-format -msgid "\"%s\" has size %zu on disk but size %zu in the manifest" -msgstr "« %s » a une taille de %zu sur disque mais de %zu dans le manifeste" +msgid "\"%s\" has size %lld on disk but size %zu in the manifest" +msgstr "« %s » a une taille de %lld sur disque mais de %zu dans le manifeste" -#: pg_verifybackup.c:669 +#: pg_verifybackup.c:668 #, c-format msgid "\"%s\" is present in the manifest but not on disk" msgstr "« %s » est présent dans le manifeste mais pas sur disque" -#: pg_verifybackup.c:745 +#: pg_verifybackup.c:731 +#, c-format +msgid "could not initialize checksum of file \"%s\"" +msgstr "n'a pas pu initialiser la somme de contrôle du fichier « %s »" + +#: pg_verifybackup.c:743 +#, c-format +msgid "could not update checksum of file \"%s\"" +msgstr "n'a pas pu mettre à jour la somme de contrôle du fichier « %s »" + +#: pg_verifybackup.c:758 #, c-format msgid "could not close file \"%s\": %m" msgstr "n'a pas pu fermer le fichier « %s » : %m" -#: pg_verifybackup.c:764 +#: pg_verifybackup.c:777 #, c-format msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" msgstr "le fichier « %s » devrait contenir %zu octets, mais la lecture produit %zu octets" -#: pg_verifybackup.c:775 +#: pg_verifybackup.c:787 +#, c-format +msgid "could not finalize checksum of file \"%s\"" +msgstr "n'a pas pu finaliser la somme de contrôle du fichier « %s »" + +#: pg_verifybackup.c:795 #, c-format msgid "file \"%s\" has checksum of length %d, but expected %d" msgstr "le fichier « %s » a une somme de contrôle de taille %d, alors que %d était attendu" -#: pg_verifybackup.c:779 +#: pg_verifybackup.c:799 #, c-format msgid "checksum mismatch for file \"%s\"" msgstr "différence de somme de contrôle pour le fichier « %s »" -#: pg_verifybackup.c:805 +#: pg_verifybackup.c:823 #, c-format msgid "WAL parsing failed for timeline %u" msgstr "analyse du WAL échouée pour la timeline %u" -#: pg_verifybackup.c:891 +#: pg_verifybackup.c:909 #, c-format msgid "" "%s verifies a backup against the backup manifest.\n" @@ -394,7 +429,7 @@ msgstr "" "%s vérifie une sauvegarde à partir du manifeste de sauvegarde.\n" "\n" -#: pg_verifybackup.c:892 +#: pg_verifybackup.c:910 #, c-format msgid "" "Usage:\n" @@ -405,57 +440,57 @@ msgstr "" " %s [OPTION]... REPSAUVEGARDE\n" "\n" -#: pg_verifybackup.c:893 +#: pg_verifybackup.c:911 #, c-format msgid "Options:\n" msgstr "Options :\n" -#: pg_verifybackup.c:894 +#: pg_verifybackup.c:912 #, c-format msgid " -e, --exit-on-error exit immediately on error\n" msgstr " -e, --exit-on-error quitte immédiatement en cas d'erreur\n" -#: pg_verifybackup.c:895 +#: pg_verifybackup.c:913 #, c-format msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" msgstr " -i, --ignore=CHEMIN_RELATIF ignore le chemin indiqué\n" -#: pg_verifybackup.c:896 +#: pg_verifybackup.c:914 #, c-format msgid " -m, --manifest-path=PATH use specified path for manifest\n" msgstr " -m, --manifest-path=CHEMIN utilise le chemin spécifié pour le manifeste\n" -#: pg_verifybackup.c:897 +#: pg_verifybackup.c:915 #, c-format msgid " -n, --no-parse-wal do not try to parse WAL files\n" msgstr " -n, --no-parse-wal n'essaie pas d'analyse les fichiers WAL\n" -#: pg_verifybackup.c:898 +#: pg_verifybackup.c:916 #, c-format msgid " -q, --quiet do not print any output, except for errors\n" msgstr " -q, --quiet n'affiche aucun message sauf pour les erreurs\n" -#: pg_verifybackup.c:899 +#: pg_verifybackup.c:917 #, c-format msgid " -s, --skip-checksums skip checksum verification\n" msgstr " -s, --skip-checksums ignore la vérification des sommes de contrôle\n" -#: pg_verifybackup.c:900 +#: pg_verifybackup.c:918 #, c-format msgid " -w, --wal-directory=PATH use specified path for WAL files\n" msgstr " -w, --wal-directory=CHEMIN utilise le chemin spécifié pour les fichiers WAL\n" -#: pg_verifybackup.c:901 +#: pg_verifybackup.c:919 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version affiche la version, puis quitte\n" -#: pg_verifybackup.c:902 +#: pg_verifybackup.c:920 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help affiche cette aide, puis quitte\n" -#: pg_verifybackup.c:903 +#: pg_verifybackup.c:921 #, c-format msgid "" "\n" @@ -464,7 +499,10 @@ msgstr "" "\n" "Rapporter les bogues à <%s>.\n" -#: pg_verifybackup.c:904 +#: pg_verifybackup.c:922 #, c-format msgid "%s home page: <%s>\n" msgstr "page d'accueil de %s : <%s>\n" + +#~ msgid "could not read file \"%s\": read %d of %zu" +#~ msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %zu" diff --git a/src/bin/pg_verifybackup/po/ja.po b/src/bin/pg_verifybackup/po/ja.po new file mode 100644 index 000000000000..402694dbda21 --- /dev/null +++ b/src/bin/pg_verifybackup/po/ja.po @@ -0,0 +1,469 @@ +# Japanese message translation file for pg_verifybackup +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_verifybackup (PostgreSQL) package. +# Haiying Tang , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-01-06 20:06+0900\n" +"PO-Revision-Date: 2021-02-05 08:11+0100\n" +"Last-Translator: Haiying Tang \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ポインタを複製できません (内部エラー)\n" + +#: ../../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "エスケープシーケンス\"\\%s\"は不正です。" + +#: ../../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "0x%02x値を持つ文字はエスケープしなければなりません" + +#: ../../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "入力の終端を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "配列要素または\"]\"を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "\",\"または\"]\"を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "\":\"を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "JSON値を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "入力文字列が予期せず終了しました。" + +#: ../../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "文字列または\"}\"を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "\",\"または\"}\"を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "文字列を想定していましたが、\"%s\"でした。" + +#: ../../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "トークン\"%s\"は不正です。" + +#: ../../common/jsonapi.c:1099 +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 はテキストに変換できません。" + +#: ../../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\"の後には16進数の4桁が続かなければなりません。" + +#: ../../common/jsonapi.c:1104 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "エンコーディングがUTF-8ではない場合、コードポイントの値が 007F 以上についてはUnicodeエスケープの値は使用できません。" + +#: ../../common/jsonapi.c:1106 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Unicodeのハイサロゲートはハイサロゲートに続いてはいけません。" + +#: ../../common/jsonapi.c:1108 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Unicodeのローサロゲートはハイサロゲートに続かなければなりません。" + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "マニフェストが予期せず終了しました。" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "予期しないオブジェクトの開始" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "予期しないオブジェクトの終わり" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "予期しない配列の開始" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "予期しない配列の終わり" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "バージョン指示子を想定していました" + +#: parse_manifest.c:328 +msgid "unrecognized top-level field" +msgstr "認識できないトップレベルフィールド" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "予期しないファイルフィールド" + +#: parse_manifest.c:361 +msgid "unexpected WAL range field" +msgstr "予期しないWAL範囲フィールド" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "予期しないオブジェクトフィールド" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "予期しないマニフェストバージョン" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "予期しないスカラー" + +#: parse_manifest.c:472 +msgid "missing path name" +msgstr "パス名がありません" + +#: parse_manifest.c:475 +msgid "both path name and encoded path name" +msgstr "パス名とエンコードされたパス名の両方" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "サイズがありません" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "アルゴリズムなしのチェックサム" + +#: parse_manifest.c:494 +msgid "could not decode file name" +msgstr "ファイル名をデコードできませんでした" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "ファイルサイズが整数ではありません" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "認識できないチェックサムアルゴリズム: \"%s\"" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "\"%s\" ファイルのチェックサムが無効: \"%s\"" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "タイムラインがありません" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "開始LSNがありません" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "終了LSNがありません" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "タイムラインが整数ではありません" + +#: parse_manifest.c:585 +msgid "could not parse start LSN" +msgstr "開始LSNを解析できませんでした" + +#: parse_manifest.c:588 +msgid "could not parse end LSN" +msgstr "終了LSNを解析できませんでした" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "少なくとも2行が必要です" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "最後の行が改行で終わっていません" + +#: parse_manifest.c:661 +#, c-format +msgid "manifest has no checksum" +msgstr "マニフェストにチェックサムがありません" + +#: parse_manifest.c:665 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "無効なマニフェストチェックサム: \"%s\"" + +#: parse_manifest.c:669 +#, c-format +msgid "manifest checksum mismatch" +msgstr "マニフェストチェックサムが合っていません" + +#: parse_manifest.c:683 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "バックアップマニフェストを解析できませんでした: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"で確認してください。\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "バックアップディレクトリが指定されていません" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "コマンドライン引数が多すぎます。(先頭は\"%s\")" + +#: pg_verifybackup.c:298 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%2$sにはプログラム\"%1$s\"が必要ですが、\"%3$s\"と同じディレクトリ\n" +"にありませんでした。\n" +"インストール状況を確認してください。" + +#: pg_verifybackup.c:303 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"%2$s\"がプログラム\"%1$s\"を見つけましたが、これは%3$sと同じ\n" +"バージョンではありませんでした。\n" +"インストール状況を確認してください。" + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "バックアップが正常に検証されました\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "ファイル\"%s\"のstatに失敗しました: %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:738 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "ファイル\"%s\"の読み取りに失敗しました: %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "" +"ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$dバイトを読み込" +"みました" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "バックアップマニフェスト内の重複パス名: \"%s\"" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "\"%s\"というファイルまたはディレクトリの情報を取得できませんでした: %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "\"%s\"はファイルまたはディレクトリではありません" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "\"%s\"はディスクに存在しますが、マニフェストには存在しません" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %zu on disk but size %zu in the manifest" +msgstr "\"%s\"はディスクに%zuがありますが、マニフェストに%zuがあります" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "\"%s\"マニフェストには存在しますが、ディスクには存在しません" + +#: pg_verifybackup.c:744 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "ファイル\"%s\"をクローズできませんでした: %m" + +#: pg_verifybackup.c:763 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "file\"%s\"は%zuバイトを含む必要がありますが、%zuバイトが読み込まれました" + +#: pg_verifybackup.c:774 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "ファイル\"%s\"のチェックサムの長さは%dですが、予期されるのは%dです" + +#: pg_verifybackup.c:778 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "ファイル\"%s\"のチェックサムが一致しません" + +#: pg_verifybackup.c:804 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "タイムライン%uのWAL解析に失敗しました" + +#: pg_verifybackup.c:890 +#, c-format +msgid "" +"%s verifies a backup against the backup manifest.\n" +"\n" +msgstr "" +"%sはバックアップマニフェストに対してバックアップを検証します。\n" +"\n" + +#: pg_verifybackup.c:891 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... BACKUPDIR\n" +"\n" +msgstr "" +"使用方法:\n" +" %s [オプション]... BACKUPDIR\n" +"\n" + +#: pg_verifybackup.c:892 +#, c-format +msgid "Options:\n" +msgstr "オプション:\n" + +#: pg_verifybackup.c:893 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, --exit-on-error エラー時に直ちに終了する\n" + +#: pg_verifybackup.c:894 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr " -i, --ignore=RELATIVE_PATH 指示されたパスを無視\n" + +#: pg_verifybackup.c:895 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, --manifest-path=PATH マニフェストの指定されたパスを使用する\n" + +#: pg_verifybackup.c:896 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, --no-parse-wal WALファイルをパースしようとしない\n" + +#: pg_verifybackup.c:897 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet エラー以外何も出力しない\n" + +#: pg_verifybackup.c:898 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, --skip-checksums スキップチェックサム検証\n" + +#: pg_verifybackup.c:899 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr " -w, --wal-directory=PATH 指定したWALファイルのパスを使用する\n" + +#: pg_verifybackup.c:900 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_verifybackup.c:901 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_verifybackup.c:902 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: pg_verifybackup.c:903 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" diff --git a/src/bin/pg_verifybackup/po/ko.po b/src/bin/pg_verifybackup/po/ko.po new file mode 100644 index 000000000000..06d9ce2844d6 --- /dev/null +++ b/src/bin/pg_verifybackup/po/ko.po @@ -0,0 +1,467 @@ +# LANGUAGE message translation file for pg_verifybackup +# Copyright (C) 2020 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_verifybackup (PostgreSQL) package. +# Ioseph Kim , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-05 20:43+0000\n" +"PO-Revision-Date: 2020-10-06 14:45+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: PostgreSQL Korea \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null 포인터를 중복할 수 없음 (내부 오류)\n" + +#: ../../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "잘못된 이스케이프 조합: \"\\%s\"" + +#: ../../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "0x%02x 값의 문자는 이스케이프 되어야함." + +#: ../../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "입력 자료의 끝을 기대했는데, \"%s\" 값이 더 있음." + +#: ../../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "\"]\" 가 필요한데 \"%s\"이(가) 있음" + +#: ../../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "\",\" 또는 \"]\"가 필요한데 \"%s\"이(가) 있음" + +#: ../../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "\":\"가 필요한데 \"%s\"이(가) 있음" + +#: ../../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "JSON 값을 기대했는데, \"%s\" 값임" + +#: ../../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "입력 문자열이 예상치 않게 끝났음." + +#: ../../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "\"}\"가 필요한데 \"%s\"이(가) 있음" + +#: ../../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "\",\" 또는 \"}\"가 필요한데 \"%s\"이(가) 있음" + +#: ../../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "문자열 값을 기대했는데, \"%s\" 값임" + +#: ../../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "잘못된 토큰: \"%s\"" + +#: ../../common/jsonapi.c:1099 +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 값은 text 형으로 변환할 수 없음." + +#: ../../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\" 표기법은 뒤에 4개의 16진수가 와야합니다." + +#: ../../common/jsonapi.c:1104 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "인코딩은 UTF8이 아닐 때 유니코드 이스케이프 값은 007F 이상 코드 포인트 값으로 사용할 수 없음." + +#: ../../common/jsonapi.c:1106 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "유니코드 상위 surrogate(딸림 코드)는 상위 딸림 코드 뒤에 오면 안됨." + +#: ../../common/jsonapi.c:1108 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "유니코드 상위 surrogate(딸림 코드) 뒤에는 하위 딸림 코드가 있어야 함." + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "메니페스트가 비정상적으로 끝났음" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "비정상적인 개체 시작" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "비정상적인 개체 끝" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "비정상적인 배열 시작" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "비정상적인 배열 끝" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "버전 지시자가 있어야 함" + +#: parse_manifest.c:328 +msgid "unrecognized top-level field" +msgstr "최상위 필드를 알 수 없음" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "예상치 못한 파일 필드" + +#: parse_manifest.c:361 +msgid "unexpected WAL range field" +msgstr "예상치 못한 WAL 범위 필드" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "예상치 못한 개체 필드" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "예상치 못한 메니페스트 버전" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "예상치 못한 스칼라" + +#: parse_manifest.c:472 +msgid "missing path name" +msgstr "패스 이름 빠짐" + +#: parse_manifest.c:475 +msgid "both path name and encoded path name" +msgstr "패스 이름과 인코딩 된 패스 이름이 함께 있음" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "크기 빠짐" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "알고리즘 없는 체크섬" + +#: parse_manifest.c:494 +msgid "could not decode file name" +msgstr "파일 이름을 디코딩할 수 없음" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "파일 크기가 정수가 아님" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "알 수 없는 체크섬 알고리즘: \"%s\"" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "\"%s\" 파일의 체크섬이 잘못됨: \"%s\"" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "타임라인 빠짐" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "시작 LSN 빠짐" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "끝 LSN 빠짐" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "타임라인이 정수가 아님" + +#: parse_manifest.c:585 +msgid "could not parse start LSN" +msgstr "시작 LSN 값을 분석할 수 없음" + +#: parse_manifest.c:588 +msgid "could not parse end LSN" +msgstr "끝 LSN 값을 분석할 수 없음" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "적어도 2줄이 더 있어야 함" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "마지막 줄에 줄바꿈 문자가 없음" + +#: parse_manifest.c:661 +#, c-format +msgid "manifest has no checksum" +msgstr "메니페스트에 체크섬 없음" + +#: parse_manifest.c:665 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "잘못된 메니페스트 체크섬: \"%s\"" + +#: parse_manifest.c:669 +#, c-format +msgid "manifest checksum mismatch" +msgstr "메니페스트 체크섬 불일치" + +#: parse_manifest.c:683 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "백업 메니페스트 구문 분석 실패: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "자제한 사항은 \"%s --help\" 명령으로 살펴보십시오.\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "백업 디렉터리를 지정하지 않았음" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "너무 많은 명령행 인자를 지정했습니다. (처음 \"%s\")" + +#: pg_verifybackup.c:298 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"\"%s\" 프로그램이 %s 작업에서 필요하지만 \"%s\" 프로그램이\n" +"있는 디렉터리 내에 없습니다.\n" +"설치 상태를 확인해 보세요." + +#: pg_verifybackup.c:303 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"%s\" 프로그램을 \"%s\" 작업을 위해 찾았지만\n" +"%s 버전과 같지 않습니다.\n" +"설치 상태를 확인해 보세요." + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "백업 검사 완료\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" 파일을 열 수 없음: %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" 파일의 상태값을 알 수 없음: %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:738 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "\"%s\" 파일을 읽을 수 없음: %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "\"%s\" 파일을 읽을 수 없음: %d 읽음, 전체 %zu" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "백업 메니페스트 안에 경로 이름이 중복됨: \"%s\"" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 열 수 없음: %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 닫을 수 없음: %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "파일 또는 디렉터리 \"%s\"의 상태를 확인할 수 없음: %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "\"%s\" 이름은 파일이나 디렉터리가 아님" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "디스크에는 \"%s\" 개체가 있으나, 메니페스트 안에는 없음" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %zu on disk but size %zu in the manifest" +msgstr "\"%s\" 의 디스크 크기는 %zu 이나 메니페스트 안에는 %zu 입니다" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "메니페스트 안에는 \"%s\" 개체가 있으나 디스크에는 없음" + +#: pg_verifybackup.c:744 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "\"%s\" 파일을 닫을 수 없음: %m" + +#: pg_verifybackup.c:763 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "\"%s\" 파일은 %zu 바이트이나 %zu 바이트를 읽음" + +#: pg_verifybackup.c:774 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "\"%s\" 파일 체크섬 %d, 예상되는 값: %d" + +#: pg_verifybackup.c:778 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "\"%s\" 파일의 체크섬이 맞지 않음" + +#: pg_verifybackup.c:804 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "타임라인 %u번의 WAL 분석 오류" + +#: pg_verifybackup.c:890 +#, c-format +msgid "" +"%s verifies a backup against the backup manifest.\n" +"\n" +msgstr "" +"%s 프로그램은 백업 메니페스트로 백업을 검사합니다.\n" +"\n" + +#: pg_verifybackup.c:891 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... BACKUPDIR\n" +"\n" +msgstr "" +"사용법:\n" +" %s [옵션]... 백업디렉터리\n" +"\n" + +#: pg_verifybackup.c:892 +#, c-format +msgid "Options:\n" +msgstr "옵션들:\n" + +#: pg_verifybackup.c:893 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, --exit-on-error 오류가 있으면 작업 중지\n" + +#: pg_verifybackup.c:894 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr " -i, --ignore=상대경로 지정한 경로 건너뜀\n" + +#: pg_verifybackup.c:895 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, --manifest-path=경로 메니페스트 파일 경로 지정\n" + +#: pg_verifybackup.c:896 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, --no-parse-wal WAL 파일 검사 건너뜀\n" + +#: pg_verifybackup.c:897 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet 오류를 빼고 나머지는 아무 것도 안 보여줌\n" + +#: pg_verifybackup.c:898 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, --skip-checksums 체크섬 검사 건너뜀\n" + +#: pg_verifybackup.c:899 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr " -w, --wal-directory=경로 WAL 파일이 있는 경로 지정\n" + +#: pg_verifybackup.c:900 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: pg_verifybackup.c:901 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 이 도움말을 보여주고 마침\n" + +#: pg_verifybackup.c:902 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"문제점 보고 주소: <%s>\n" + +#: pg_verifybackup.c:903 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" diff --git a/src/bin/pg_verifybackup/po/ru.po b/src/bin/pg_verifybackup/po/ru.po new file mode 100644 index 000000000000..35ed42ce007b --- /dev/null +++ b/src/bin/pg_verifybackup/po/ru.po @@ -0,0 +1,479 @@ +# Alexander Lakhin , 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-15 18:25+0300\n" +"PO-Revision-Date: 2020-10-29 15:03+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 19.12.3\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Неверная спецпоследовательность: \"\\%s\"." + +#: ../../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Символ с кодом 0x%02x необходимо экранировать." + +#: ../../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Ожидался конец текста, но обнаружено продолжение \"%s\"." + +#: ../../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Ожидался элемент массива или \"]\", но обнаружено \"%s\"." + +#: ../../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Ожидалась \",\" или \"]\", но обнаружено \"%s\"." + +#: ../../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Ожидалось \":\", но обнаружено \"%s\"." + +#: ../../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Ожидалось значение JSON, но обнаружено \"%s\"." + +#: ../../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "Неожиданный конец входной строки." + +#: ../../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Ожидалась строка или \"}\", но обнаружено \"%s\"." + +#: ../../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Ожидалась \",\" или \"}\", но обнаружено \"%s\"." + +#: ../../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Ожидалась строка, но обнаружено \"%s\"." + +#: ../../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Ошибочный элемент текста \"%s\"." + +#: ../../common/jsonapi.c:1099 +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 нельзя преобразовать в текст." + +#: ../../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "За \"\\u\" должны следовать четыре шестнадцатеричные цифры." + +#: ../../common/jsonapi.c:1104 +msgid "" +"Unicode escape values cannot be used for code point values above 007F when " +"the encoding is not UTF8." +msgstr "" +"Спецкоды Unicode для значений выше 007F можно использовать только с " +"кодировкой UTF8." + +#: ../../common/jsonapi.c:1106 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "" +"Старшее слово суррогата Unicode не может следовать за другим старшим словом." + +#: ../../common/jsonapi.c:1108 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Младшее слово суррогата Unicode должно следовать за старшим словом." + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "неожиданный конец манифеста" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "неожиданное начало объекта" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "неожиданный конец объекта" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "неожиданное начало массива" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "неожиданный конец массива" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "ожидалось указание версии" + +#: parse_manifest.c:328 +msgid "unrecognized top-level field" +msgstr "нераспознанное поле на верхнем уровне" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "неизвестное поле для файла" + +#: parse_manifest.c:361 +msgid "unexpected WAL range field" +msgstr "неизвестное поле в указании диапазона WAL" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "неожиданное поле объекта" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "неожиданная версия манифеста" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "неожиданное скалярное значение" + +#: parse_manifest.c:472 +msgid "missing path name" +msgstr "отсутствует указание пути" + +#: parse_manifest.c:475 +msgid "both path name and encoded path name" +msgstr "указание пути задано в обычном виде и в закодированном" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "отсутствует указание размера" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "не задан алгоритм расчёта контрольной суммы" + +#: parse_manifest.c:494 +msgid "could not decode file name" +msgstr "не удалось декодировать имя файла" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "размер файла не является целочисленным" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "нераспознанный алгоритм расчёта контрольных сумм: \"%s\"" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "неверная контрольная сумма для файла \"%s\": \"%s\"" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "отсутствует линия времени" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "отсутствует начальный LSN" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "отсутствует конечный LSN" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "линия времени задаётся не целым числом" + +#: parse_manifest.c:585 +msgid "could not parse start LSN" +msgstr "не удалось разобрать начальный LSN" + +#: parse_manifest.c:588 +msgid "could not parse end LSN" +msgstr "не удалось разобрать конечный LSN" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "ожидалось как минимум 2 строки" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "последняя строка не оканчивается символом новой строки" + +#: parse_manifest.c:661 +#, c-format +msgid "manifest has no checksum" +msgstr "в манифесте нет контрольной суммы" + +#: parse_manifest.c:665 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "неверная контрольная сумма в манифесте: \"%s\"" + +#: parse_manifest.c:669 +#, c-format +msgid "manifest checksum mismatch" +msgstr "ошибка контрольной суммы манифеста" + +#: parse_manifest.c:683 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "не удалось разобрать манифест копии: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "каталог копии не указан" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: pg_verifybackup.c:298 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"Программа \"%s\" нужна для %s, но она не найдена\n" +"в каталоге \"%s\".\n" +"Проверьте правильность установки СУБД." + +#: pg_verifybackup.c:303 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"Программа \"%s\" найдена программой \"%s\",\n" +"но её версия отличается от версии %s.\n" +"Проверьте правильность установки СУБД." + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "копия проверена успешно\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не удалось получить информацию о файле \"%s\": %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:738 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %zu)" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "дублирующийся путь в манифесте копии: \"%s\"" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалось открыть каталог \"%s\": %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не удалось закрыть каталог \"%s\": %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "не удалось получить информацию о файле или каталоге \"%s\": %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "\"%s\" не указывает на файл или каталог" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "файл \"%s\" присутствует на диске, но отсутствует в манифесте" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %zu on disk but size %zu in the manifest" +msgstr "" +"файл \"%s\" имеет размер на диске: %zu, тогда как размер в манифесте: %zu" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "файл \"%s\" присутствует в манифесте, но отсутствует на диске" + +#: pg_verifybackup.c:744 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "не удалось закрыть файл \"%s\": %m" + +#: pg_verifybackup.c:763 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "файл \"%s\" должен содержать байт: %zu, но фактически прочитано: %zu" + +#: pg_verifybackup.c:774 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "" +"для файла \"%s\" задана контрольная сумма размером %d, но ожидаемый размер: " +"%d" + +#: pg_verifybackup.c:778 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "ошибка контрольной суммы для файла \"%s\"" + +#: pg_verifybackup.c:804 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "не удалось разобрать WAL для линии времени %u" + +#: pg_verifybackup.c:890 +#, c-format +msgid "" +"%s verifies a backup against the backup manifest.\n" +"\n" +msgstr "" +"%s проверяет резервную копию, используя манифест копии.\n" +"\n" + +#: pg_verifybackup.c:891 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... BACKUPDIR\n" +"\n" +msgstr "" +"Использование:\n" +" %s [ПАРАМЕТР]... КАТАЛОГ_КОПИИ\n" +"\n" + +#: pg_verifybackup.c:892 +#, c-format +msgid "Options:\n" +msgstr "Параметры:\n" + +#: pg_verifybackup.c:893 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, --exit-on-error немедленный выход при ошибке\n" + +#: pg_verifybackup.c:894 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr "" +" -i, --ignore=ОТНОСИТЕЛЬНЫЙ_ПУТЬ\n" +" игнорировать заданный путь\n" + +#: pg_verifybackup.c:895 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, --manifest-path=ПУТЬ использовать заданный файл манифеста\n" + +#: pg_verifybackup.c:896 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, --no-parse-wal не пытаться разбирать файлы WAL\n" + +#: pg_verifybackup.c:897 +#, c-format +msgid "" +" -q, --quiet do not print any output, except for errors\n" +msgstr "" +" -q, --quiet не выводить никаких сообщений, кроме ошибок\n" + +#: pg_verifybackup.c:898 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, --skip-checksums пропустить проверку контрольных сумм\n" + +#: pg_verifybackup.c:899 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr "" +" -w, --wal-directory=ПУТЬ использовать заданный путь к файлам WAL\n" + +#: pg_verifybackup.c:900 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_verifybackup.c:901 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_verifybackup.c:902 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_verifybackup.c:903 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" diff --git a/src/bin/pg_verifybackup/po/sv.po b/src/bin/pg_verifybackup/po/sv.po index bf5bda88fa87..8a984d3cc2ee 100644 --- a/src/bin/pg_verifybackup/po/sv.po +++ b/src/bin/pg_verifybackup/po/sv.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2020-05-09 08:44+0000\n" -"PO-Revision-Date: 2020-05-09 13:50+0200\n" +"POT-Creation-Date: 2020-09-16 05:14+0000\n" +"PO-Revision-Date: 2020-09-16 07:55+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -147,7 +147,7 @@ msgid "expected version indicator" msgstr "förväntade en versionsindikator" #: parse_manifest.c:328 -msgid "unknown toplevel field" +msgid "unrecognized top-level field" msgstr "okänt toppnivåfält" #: parse_manifest.c:347 @@ -155,8 +155,8 @@ msgid "unexpected file field" msgstr "oväntat filfält" #: parse_manifest.c:361 -msgid "unexpected wal range field" -msgstr "oväntat wal-intervall-fält" +msgid "unexpected WAL range field" +msgstr "oväntat WAL-intervall-fält" #: parse_manifest.c:367 msgid "unexpected object field" @@ -171,11 +171,11 @@ msgid "unexpected scalar" msgstr "oväntad skalar" #: parse_manifest.c:472 -msgid "missing pathname" +msgid "missing path name" msgstr "saknas sökväg" #: parse_manifest.c:475 -msgid "both pathname and encoded pathname" +msgid "both path name and encoded path name" msgstr "både sökväg och kodad sökväg" #: parse_manifest.c:477 @@ -187,8 +187,8 @@ msgid "checksum without algorithm" msgstr "checksumma utan algoritm" #: parse_manifest.c:494 -msgid "unable to decode filename" -msgstr "kan inte avkoda filnamn" +msgid "could not decode file name" +msgstr "kunde inte avkoda filnamn" #: parse_manifest.c:504 msgid "file size is not an integer" @@ -221,12 +221,12 @@ msgid "timeline is not an integer" msgstr "tidslinje är inte ett heltal" #: parse_manifest.c:585 -msgid "unable to parse start LSN" -msgstr "kan inte parsa start-LSN" +msgid "could not parse start LSN" +msgstr "kunde inte parsa start-LSN" #: parse_manifest.c:588 -msgid "unable to parse end LSN" -msgstr "kan inte parsa slut-LSN" +msgid "could not parse end LSN" +msgstr "kunde inte parsa slut-LSN" #: parse_manifest.c:649 msgid "expected at least 2 lines" @@ -298,7 +298,7 @@ msgstr "" msgid "backup successfully verified\n" msgstr "korrekt verifierad backup\n" -#: pg_verifybackup.c:387 pg_verifybackup.c:724 +#: pg_verifybackup.c:387 pg_verifybackup.c:723 #, c-format msgid "could not open file \"%s\": %m" msgstr "kunde inte öppna fil \"%s\": %m" @@ -308,7 +308,7 @@ msgstr "kunde inte öppna fil \"%s\": %m" msgid "could not stat file \"%s\": %m" msgstr "kunde inte göra stat() på fil \"%s\": %m" -#: pg_verifybackup.c:411 pg_verifybackup.c:739 +#: pg_verifybackup.c:411 pg_verifybackup.c:738 #, c-format msgid "could not read file \"%s\": %m" msgstr "kunde inte läsa fil \"%s\": %m" @@ -320,7 +320,7 @@ msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" #: pg_verifybackup.c:474 #, c-format -msgid "duplicate pathname in backup manifest: \"%s\"" +msgid "duplicate path name in backup manifest: \"%s\"" msgstr "duplicerad sökväg i backup-manifest: \"%s\"" #: pg_verifybackup.c:537 pg_verifybackup.c:544 @@ -353,37 +353,37 @@ msgstr "\"%s\" finns på disk men är inte i manifestet" msgid "\"%s\" has size %zu on disk but size %zu in the manifest" msgstr "\"%s\" har storlek %zu på disk men storlek %zu i manifestet" -#: pg_verifybackup.c:669 +#: pg_verifybackup.c:668 #, c-format msgid "\"%s\" is present in the manifest but not on disk" msgstr "\"%s\" finns i manifestet men inte på disk" -#: pg_verifybackup.c:745 +#: pg_verifybackup.c:744 #, c-format msgid "could not close file \"%s\": %m" msgstr "kunde inte stänga fil \"%s\": %m" -#: pg_verifybackup.c:764 +#: pg_verifybackup.c:763 #, c-format msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" msgstr "filen \"%s\" skall innehålla %zu byte men vi läste %zu byte" -#: pg_verifybackup.c:775 +#: pg_verifybackup.c:774 #, c-format msgid "file \"%s\" has checksum of length %d, but expected %d" msgstr "filen \"%s\" har checksumma med längd %d men förväntade %d" -#: pg_verifybackup.c:779 +#: pg_verifybackup.c:778 #, c-format msgid "checksum mismatch for file \"%s\"" msgstr "checksumman matchar inte för fil \"%s\"" -#: pg_verifybackup.c:805 +#: pg_verifybackup.c:804 #, c-format msgid "WAL parsing failed for timeline %u" msgstr "WAL-parsning misslyckades för tidslinje %u" -#: pg_verifybackup.c:891 +#: pg_verifybackup.c:890 #, c-format msgid "" "%s verifies a backup against the backup manifest.\n" @@ -392,7 +392,7 @@ msgstr "" "%s verifierar en backup gentemot backup-manifestet.\n" "\n" -#: pg_verifybackup.c:892 +#: pg_verifybackup.c:891 #, c-format msgid "" "Usage:\n" @@ -403,57 +403,57 @@ msgstr "" " %s [FLAGGOR]... BACKUPKAT\n" "\n" -#: pg_verifybackup.c:893 +#: pg_verifybackup.c:892 #, c-format msgid "Options:\n" msgstr "Flaggor:\n" -#: pg_verifybackup.c:894 +#: pg_verifybackup.c:893 #, c-format msgid " -e, --exit-on-error exit immediately on error\n" msgstr " -e, --exit-on-error avsluta direkt vid fel\n" -#: pg_verifybackup.c:895 +#: pg_verifybackup.c:894 #, c-format msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" msgstr " -i, --ignore=RELATIV_SÖKVÄG hoppa över angiven sökväg\n" -#: pg_verifybackup.c:896 +#: pg_verifybackup.c:895 #, c-format msgid " -m, --manifest-path=PATH use specified path for manifest\n" msgstr " -m, --manifest-path=SÖKVÄG använd denna sökväg till manifestet\n" -#: pg_verifybackup.c:897 +#: pg_verifybackup.c:896 #, c-format msgid " -n, --no-parse-wal do not try to parse WAL files\n" msgstr " -n, --no-parse-wal försök inte parsa WAL-filer\n" -#: pg_verifybackup.c:898 +#: pg_verifybackup.c:897 #, c-format msgid " -q, --quiet do not print any output, except for errors\n" msgstr " -q, --quiet skriv inte ut några meddelanden förutom fel\n" -#: pg_verifybackup.c:899 +#: pg_verifybackup.c:898 #, c-format msgid " -s, --skip-checksums skip checksum verification\n" msgstr " -s, --skip-checksums hoppa över verifiering av checksummor\n" -#: pg_verifybackup.c:900 +#: pg_verifybackup.c:899 #, c-format msgid " -w, --wal-directory=PATH use specified path for WAL files\n" msgstr " -w, --wal-directory=SÖKVÄG använd denna sökväg till WAL-filer\n" -#: pg_verifybackup.c:901 +#: pg_verifybackup.c:900 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_verifybackup.c:902 +#: pg_verifybackup.c:901 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: pg_verifybackup.c:903 +#: pg_verifybackup.c:902 #, c-format msgid "" "\n" @@ -462,25 +462,25 @@ msgstr "" "\n" "Rapportera fel till <%s>.\n" -#: pg_verifybackup.c:904 +#: pg_verifybackup.c:903 #, c-format msgid "%s home page: <%s>\n" msgstr "hemsida för %s: <%s>\n" #~ msgid "" -#~ "The program \"%s\" was found by \"%s\" but was\n" -#~ "not the same version as %s.\n" +#~ "The program \"%s\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" #~ "Check your installation." #~ msgstr "" -#~ "Programmet \"%s\" hittades av \"%s\"\n" -#~ "men är inte av samma version som %s.\n" +#~ "Programmet \"%s\" behövs av %s men hittades inte i samma\n" +#~ "katalog som \"%s\".\n" #~ "Kontrollera din installation." #~ msgid "" -#~ "The program \"%s\" is needed by %s but was\n" -#~ "not found in the same directory as \"%s\".\n" +#~ "The program \"%s\" was found by \"%s\" but was\n" +#~ "not the same version as %s.\n" #~ "Check your installation." #~ msgstr "" -#~ "Programmet \"%s\" behövs av %s men hittades inte i samma\n" -#~ "katalog som \"%s\".\n" +#~ "Programmet \"%s\" hittades av \"%s\"\n" +#~ "men är inte av samma version som %s.\n" #~ "Kontrollera din installation." diff --git a/src/bin/pg_verifybackup/po/uk.po b/src/bin/pg_verifybackup/po/uk.po new file mode 100644 index 000000000000..f8bb42a2d429 --- /dev/null +++ b/src/bin/pg_verifybackup/po/uk.po @@ -0,0 +1,453 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:14+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: \n" +"Language-Team: Ukrainian\n" +"Language: uk_UA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_verifybackup.pot\n" +"X-Crowdin-File-ID: 528\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "недостатньо пам'яті\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" + +#: ../../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Неприпустима спеціальна послідовність \"\\%s\"." + +#: ../../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Символ зі значенням 0x%02x повинен бути пропущений." + +#: ../../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Очікувався кінець введення, але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Очікувався елемент масиву або \"]\", але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Очікувалось \",\" або \"]\", але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Очікувалось \":\", але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Очікувалось значення JSON, але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "Несподіваний кінець вхідного рядка." + +#: ../../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Очікувався рядок або \"}\", але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Очікувалось \",\" або \"}\", але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Очікувався рядок, але знайдено \"%s\"." + +#: ../../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Неприпустимий маркер \"%s\"." + +#: ../../common/jsonapi.c:1099 +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 не можна перетворити в текст." + +#: ../../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "За \"\\u\" повинні прямувати чотири шістнадцяткових числа." + +#: ../../common/jsonapi.c:1104 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "Значення виходу Unicode не можна використовувати для значень кодових точок більше 007F, якщо кодування не UTF8." + +#: ../../common/jsonapi.c:1106 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Старший сурогат Unicode не повинен прямувати за іншим старшим сурогатом." + +#: ../../common/jsonapi.c:1108 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Молодший сурогат Unicode не повинен прямувати за іншим молодшим сурогатом." + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "маніфест закінчився несподівано" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "неочікуваний початок об'єкта" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "неочікуваний кінець об'єкта" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "неочікуваний початок масиву" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "неочікуваний кінець масиву" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "індикатор очікуваної версії" + +#: parse_manifest.c:328 +msgid "unrecognized top-level field" +msgstr "нерозпізнане поле верхнього рівня" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "неочікуване поле файлу" + +#: parse_manifest.c:361 +msgid "unexpected WAL range field" +msgstr "неочікуване поле діапазону WAL" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "неочікуване поле об'єкта" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "неочікувана версія маніфесту" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "неочікуваний скаляр" + +#: parse_manifest.c:472 +msgid "missing path name" +msgstr "пропущено шлях" + +#: parse_manifest.c:475 +msgid "both path name and encoded path name" +msgstr "і ім'я шляху, і закодований шлях" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "відсутній розмір" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "контрольна сума без алгоритму" + +#: parse_manifest.c:494 +msgid "could not decode file name" +msgstr "не вдалося декодувати ім'я файлу" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "розмір файлу не є цілим числом" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "нерозпізнаний алгоритм контрольної суми: \"%s\"" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "неприпустима контрольна сума для файлу \"%s\": \"%s\"" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "відсутня часова шкала" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "відсутній LSN початку" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "відсутній LSN кінця" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "часова лінія не є цілим числом" + +#: parse_manifest.c:585 +msgid "could not parse start LSN" +msgstr "не вдалося проаналізувати початковий LSN" + +#: parse_manifest.c:588 +msgid "could not parse end LSN" +msgstr "не вдалося проаналізувати кінцевий LSN" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "очікувалося принаймні 2 рядки" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "останній рядок не завершений новим рядком" + +#: parse_manifest.c:661 +#, c-format +msgid "manifest has no checksum" +msgstr "у маніфесті немає контрольної суми" + +#: parse_manifest.c:665 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "неприпустима контрольна сума маніфесту: \"%s\"" + +#: parse_manifest.c:669 +#, c-format +msgid "manifest checksum mismatch" +msgstr "невідповідність контрольної суми маніфесту" + +#: parse_manifest.c:683 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "не вдалося проаналізувати маніфест резервної копії: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "не вказано папку резервної копії" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" + +#: pg_verifybackup.c:298 +#, c-format +msgid "The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "Програма \"%s\" потрібна для %s, але не знайдена в тому ж каталозі, що й \"%s\".\n" +"Перевірте вашу установку." + +#: pg_verifybackup.c:303 +#, c-format +msgid "The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "Програма \"%s\" була знайдена \"%s\", але не була тієї ж версії, що %s.\n" +"Перевірте вашу установку." + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "резервну копію успішно перевірено\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не вдалося отримати інформацію від файлу \"%s\": %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:738 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не вдалося прочитати файл \"%s\": %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не вдалося прочитати файл \"%s\": прочитано %d з %zu" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate path name in backup manifest: \"%s\"" +msgstr "дубльований шлях у маніфесті резервного копіювання: \"%s\"" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не вдалося відкрити каталог \"%s\": %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "не вдалося закрити каталог \"%s\": %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "не вдалося отримати інформацію про файл або каталог \"%s\": %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "\"%s\" не є файлом або каталогом" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "\"%s\" присутній на диску, але не у маніфесті" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %zu on disk but size %zu in the manifest" +msgstr "\"%s\" має розмір %zu на диску, але розмір %zu у маніфесті" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "\"%s\" присутній у маніфесті, але не на диску" + +#: pg_verifybackup.c:744 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "неможливо закрити файл \"%s\": %m" + +#: pg_verifybackup.c:763 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "файл \"%s\" мусить містити %zu байтів, але прочитано %zu байтів" + +#: pg_verifybackup.c:774 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "файл \"%s\" має контрольну суму довжини %d, але очікувалось %d" + +#: pg_verifybackup.c:778 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "невідповідність контрольної суми для файлу \"%s\"" + +#: pg_verifybackup.c:804 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "не вдалося проаналізувати WAL для часової шкали %u" + +#: pg_verifybackup.c:890 +#, c-format +msgid "%s verifies a backup against the backup manifest.\n\n" +msgstr "%s перевіряє резервну копію відповідно до маніфесту резервного копіювання.\n\n" + +#: pg_verifybackup.c:891 +#, c-format +msgid "Usage:\n" +" %s [OPTION]... BACKUPDIR\n\n" +msgstr "Використання:\n" +" %s [OPTION]... КАТАЛОГ_КОПІЮВАННЯ\n\n" + +#: pg_verifybackup.c:892 +#, c-format +msgid "Options:\n" +msgstr "Параметри:\n" + +#: pg_verifybackup.c:893 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, --exit-on-error вийти при помилці\n" + +#: pg_verifybackup.c:894 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr " -i, --ignore=RELATIVE_PATH ігнорувати вказаний шлях\n" + +#: pg_verifybackup.c:895 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, --manifest-path=PATH використовувати вказаний шлях для маніфесту\n" + +#: pg_verifybackup.c:896 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, --no-parse-wal не намагатися аналізувати файли WAL\n" + +#: pg_verifybackup.c:897 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet не друкувати жодного виводу, окрім помилок\n" + +#: pg_verifybackup.c:898 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, --skip-checksums не перевіряти контрольні суми\n" + +#: pg_verifybackup.c:899 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr " -w, --wal-directory=PATH використовувати вказаний шлях для файлів WAL\n" + +#: pg_verifybackup.c:900 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію, потім вийти\n" + +#: pg_verifybackup.c:901 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати цю довідку, потім вийти\n" + +#: pg_verifybackup.c:902 +#, c-format +msgid "\n" +"Report bugs to <%s>.\n" +msgstr "\n" +"Повідомляти про помилки на <%s>.\n" + +#: pg_verifybackup.c:903 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + diff --git a/src/bin/pg_verifybackup/po/zh_CN.po b/src/bin/pg_verifybackup/po/zh_CN.po new file mode 100644 index 000000000000..9dd2291ee4aa --- /dev/null +++ b/src/bin/pg_verifybackup/po/zh_CN.po @@ -0,0 +1,467 @@ +# LANGUAGE message translation file for pg_verifybackup +# Copyright (C) 2020 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_verifybackup (PostgreSQL) package. +# FIRST AUTHOR , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_verifybackup (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-05-17 02:44+0000\n" +"PO-Revision-Date: 2020-06-22 16:00+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "致命的:" + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "错误: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "内存溢出\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "无法复制空指针 (内部错误)\n" + +#: ../../common/jsonapi.c:1064 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "转义序列 \"\\%s\" 无效." + +#: ../../common/jsonapi.c:1067 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "值为 0x%02x 的字符必须进行转义处理." + +#: ../../common/jsonapi.c:1070 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "期望输入结束,结果发现是\"%s\"." + +#: ../../common/jsonapi.c:1073 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "期望为数组元素或者\"]\",但发现结果是\"%s\"." + +#: ../../common/jsonapi.c:1076 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "期望是\",\" 或 \"]\",但发现结果是\"%s\"." + +#: ../../common/jsonapi.c:1079 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "期望得到 \":\",但发现结果是\"%s\"." + +#: ../../common/jsonapi.c:1082 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "期望是JSON值, 但结果发现是\"%s\"." + +#: ../../common/jsonapi.c:1085 +msgid "The input string ended unexpectedly." +msgstr "输入字符串意外终止." + +#: ../../common/jsonapi.c:1087 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "期望是字符串或\"}\",但发现结果是\"%s\"." + +#: ../../common/jsonapi.c:1090 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "期望是 \",\" 或 \"}\",但发现结果是\"%s\"." + +#: ../../common/jsonapi.c:1093 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "期望是字符串, 但发现结果是\"%s\"." + +#: ../../common/jsonapi.c:1096 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "令牌 \"%s\" 无效." + +#: ../../common/jsonapi.c:1099 +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000不能被转换为文本。" + +#: ../../common/jsonapi.c:1101 +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\" 后必须紧跟有效的十六进制数数字" + +#: ../../common/jsonapi.c:1104 +msgid "Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8." +msgstr "当编码不是UTF8时,大于007F的码位值不能使用Unicode转义值." + +#: ../../common/jsonapi.c:1106 +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "Unicode 的高位代理项不能紧随另一个高位代理项." + +#: ../../common/jsonapi.c:1108 +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "Unicode 代位代理项必须紧随一个高位代理项." + +#: parse_manifest.c:152 +msgid "manifest ended unexpectedly" +msgstr "清单意外结束" + +#: parse_manifest.c:191 +msgid "unexpected object start" +msgstr "意外的对象开始" + +#: parse_manifest.c:224 +msgid "unexpected object end" +msgstr "意外的对象结束" + +#: parse_manifest.c:251 +msgid "unexpected array start" +msgstr "意外的数组开始" + +#: parse_manifest.c:274 +msgid "unexpected array end" +msgstr "意外的数组结束" + +#: parse_manifest.c:299 +msgid "expected version indicator" +msgstr "预期的版本指示器" + +#: parse_manifest.c:328 +msgid "unknown toplevel field" +msgstr "未知的顶层字段" + +#: parse_manifest.c:347 +msgid "unexpected file field" +msgstr "意外的文件字段" + +#: parse_manifest.c:361 +msgid "unexpected wal range field" +msgstr "意外的wal范围字段" + +#: parse_manifest.c:367 +msgid "unexpected object field" +msgstr "意外的对象字段" + +#: parse_manifest.c:397 +msgid "unexpected manifest version" +msgstr "意外的清单版本" + +#: parse_manifest.c:448 +msgid "unexpected scalar" +msgstr "意外的标量" + +#: parse_manifest.c:472 +msgid "missing pathname" +msgstr "缺少路径名" + +#: parse_manifest.c:475 +msgid "both pathname and encoded pathname" +msgstr "路径名和编码路径名" + +#: parse_manifest.c:477 +msgid "missing size" +msgstr "缺少大小" + +#: parse_manifest.c:480 +msgid "checksum without algorithm" +msgstr "校验和没有算法" + +#: parse_manifest.c:494 +msgid "unable to decode filename" +msgstr "无法解码文件名" + +#: parse_manifest.c:504 +msgid "file size is not an integer" +msgstr "文件大小不是整数" + +#: parse_manifest.c:510 +#, c-format +msgid "unrecognized checksum algorithm: \"%s\"" +msgstr "无法识别的校验和算法: \"%s\"" + +#: parse_manifest.c:529 +#, c-format +msgid "invalid checksum for file \"%s\": \"%s\"" +msgstr "文件\"%s\"的校验和无效: \"%s\"" + +#: parse_manifest.c:572 +msgid "missing timeline" +msgstr "缺少时间线" + +#: parse_manifest.c:574 +msgid "missing start LSN" +msgstr "缺少起始LSN" + +#: parse_manifest.c:576 +msgid "missing end LSN" +msgstr "缺少结束LSN" + +#: parse_manifest.c:582 +msgid "timeline is not an integer" +msgstr "时间线不是整数" + +#: parse_manifest.c:585 +msgid "unable to parse start LSN" +msgstr "无法解析起始LSN" + +#: parse_manifest.c:588 +msgid "unable to parse end LSN" +msgstr "无法解析结束LSN" + +#: parse_manifest.c:649 +msgid "expected at least 2 lines" +msgstr "至少需要2行" + +#: parse_manifest.c:652 +msgid "last line not newline-terminated" +msgstr "最后一行未以换行符结尾" + +#: parse_manifest.c:661 +#, c-format +msgid "manifest has no checksum" +msgstr "清单没有校验和" + +#: parse_manifest.c:665 +#, c-format +msgid "invalid manifest checksum: \"%s\"" +msgstr "清单校验和无效: \"%s\"" + +#: parse_manifest.c:669 +#, c-format +msgid "manifest checksum mismatch" +msgstr "清单校验和不匹配" + +#: parse_manifest.c:683 +#, c-format +msgid "could not parse backup manifest: %s" +msgstr "清单校验和不匹配: %s" + +#: pg_verifybackup.c:255 pg_verifybackup.c:265 pg_verifybackup.c:277 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "请用 \"%s --help\" 获取更多的信息.\n" + +#: pg_verifybackup.c:264 +#, c-format +msgid "no backup directory specified" +msgstr "未指定备份目录" + +#: pg_verifybackup.c:275 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "命令行参数太多 (第一个是 \"%s\")" + +#: pg_verifybackup.c:298 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%2$s需要程序\"%1$s\"\n" +"但在与\"%3$s\"相同的目录中找不到该程序.\n" +"检查您的安装." + +#: pg_verifybackup.c:303 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"程序\"%s\"是由\"%s\"找到的\n" +"但与%s的版本不同.\n" +"检查您的安装." + +#: pg_verifybackup.c:361 +#, c-format +msgid "backup successfully verified\n" +msgstr "备份已成功验证\n" + +#: pg_verifybackup.c:387 pg_verifybackup.c:723 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "无法打开文件 \"%s\": %m" + +#: pg_verifybackup.c:391 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "无法取文件 \"%s\" 的状态: %m" + +#: pg_verifybackup.c:411 pg_verifybackup.c:738 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "无法读取文件 \"%s\": %m" + +#: pg_verifybackup.c:414 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "无法读取文件\"%1$s\":读取了%3$zu中的%2$d" + +#: pg_verifybackup.c:474 +#, c-format +msgid "duplicate pathname in backup manifest: \"%s\"" +msgstr "备份清单中的路径名重复: \"%s\"" + +#: pg_verifybackup.c:537 pg_verifybackup.c:544 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "无法打开目录 \"%s\": %m" + +#: pg_verifybackup.c:576 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "无法关闭目录 \"%s\": %m" + +#: pg_verifybackup.c:596 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "无法统计文件或目录\"%s\": %m" + +#: pg_verifybackup.c:619 +#, c-format +msgid "\"%s\" is not a file or directory" +msgstr "\"%s\"不是文件或目录" + +#: pg_verifybackup.c:629 +#, c-format +msgid "\"%s\" is present on disk but not in the manifest" +msgstr "磁盘上有\"%s\",但清单中没有" + +#: pg_verifybackup.c:641 +#, c-format +msgid "\"%s\" has size %zu on disk but size %zu in the manifest" +msgstr "\"%s\"在磁盘上有大小%zu,但在清单中有大小%zu" + +#: pg_verifybackup.c:668 +#, c-format +msgid "\"%s\" is present in the manifest but not on disk" +msgstr "清单中有\"%s\",但磁盘上没有" + +#: pg_verifybackup.c:744 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "无法关闭文件 \"%s\": %m" + +#: pg_verifybackup.c:763 +#, c-format +msgid "file \"%s\" should contain %zu bytes, but read %zu bytes" +msgstr "文件\"%s\"应包含%zu到字节,但读取到%zu字节" + +#: pg_verifybackup.c:774 +#, c-format +msgid "file \"%s\" has checksum of length %d, but expected %d" +msgstr "文件\"%s\"的校验和长度为%d,但应为%d" + +#: pg_verifybackup.c:778 +#, c-format +msgid "checksum mismatch for file \"%s\"" +msgstr "文件\"%s\"的校验和不匹配" + +#: pg_verifybackup.c:804 +#, c-format +msgid "WAL parsing failed for timeline %u" +msgstr "时间线%u的WAL解析失败" + +#: pg_verifybackup.c:890 +#, c-format +msgid "" +"%s verifies a backup against the backup manifest.\n" +"\n" +msgstr "" +"%s 根据备份清单验证备份.\n" +"\n" + +#: pg_verifybackup.c:891 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... BACKUPDIR\n" +"\n" +msgstr "" +"用法:\n" +" %s [选项]... BACKUPDIR\n" +"\n" + +#: pg_verifybackup.c:892 +#, c-format +msgid "Options:\n" +msgstr "选项:\n" + +#: pg_verifybackup.c:893 +#, c-format +msgid " -e, --exit-on-error exit immediately on error\n" +msgstr " -e, --exit-on-error 出错时立即退出\n" + +#: pg_verifybackup.c:894 +#, c-format +msgid " -i, --ignore=RELATIVE_PATH ignore indicated path\n" +msgstr " -i, --ignore=RELATIVE_PATH 忽略指定的路径\n" + +#: pg_verifybackup.c:895 +#, c-format +msgid " -m, --manifest-path=PATH use specified path for manifest\n" +msgstr " -m, --manifest-path=PATH 使用清单的指定路径\n" + +#: pg_verifybackup.c:896 +#, c-format +msgid " -n, --no-parse-wal do not try to parse WAL files\n" +msgstr " -n, --no-parse-wal 不试图解析WAL文件\n" + +#: pg_verifybackup.c:897 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet 不打印任何输出,错误除外\n" + +#: pg_verifybackup.c:898 +#, c-format +msgid " -s, --skip-checksums skip checksum verification\n" +msgstr " -s, --skip-checksums 跳过校验和验证\n" + +#: pg_verifybackup.c:899 +#, c-format +msgid " -w, --wal-directory=PATH use specified path for WAL files\n" +msgstr " -w, --wal-directory=PATH 对WAL文件使用指定路径\n" + +#: pg_verifybackup.c:900 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 输出版本信息,然后退出\n" + +#: pg_verifybackup.c:901 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 显示此帮助,然后退出\n" + +#: pg_verifybackup.c:902 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"臭虫报告至<%s>.\n" + +#: pg_verifybackup.c:903 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 主页: <%s>\n" diff --git a/src/bin/pg_verifybackup/t/001_basic.pl b/src/bin/pg_verifybackup/t/001_basic.pl index 0c35062dc0a1..4ad1c3f0a995 100644 --- a/src/bin/pg_verifybackup/t/001_basic.pl +++ b/src/bin/pg_verifybackup/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pg_verifybackup/t/002_algorithm.pl b/src/bin/pg_verifybackup/t/002_algorithm.pl index f0e3b93eee1e..fd40527858d9 100644 --- a/src/bin/pg_verifybackup/t/002_algorithm.pl +++ b/src/bin/pg_verifybackup/t/002_algorithm.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Verify that we can take and verify backups with various checksum types. use strict; diff --git a/src/bin/pg_verifybackup/t/003_corruption.pl b/src/bin/pg_verifybackup/t/003_corruption.pl index d54f74ff9f23..8ef95aefe273 100644 --- a/src/bin/pg_verifybackup/t/003_corruption.pl +++ b/src/bin/pg_verifybackup/t/003_corruption.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Verify that various forms of corruption are detected by pg_verifybackup. use strict; diff --git a/src/bin/pg_verifybackup/t/004_options.pl b/src/bin/pg_verifybackup/t/004_options.pl index e803fa1fe423..212028505a0c 100644 --- a/src/bin/pg_verifybackup/t/004_options.pl +++ b/src/bin/pg_verifybackup/t/004_options.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Verify the behavior of assorted pg_verifybackup options. use strict; diff --git a/src/bin/pg_verifybackup/t/005_bad_manifest.pl b/src/bin/pg_verifybackup/t/005_bad_manifest.pl index afd64d1a96b0..9f8a100a716b 100644 --- a/src/bin/pg_verifybackup/t/005_bad_manifest.pl +++ b/src/bin/pg_verifybackup/t/005_bad_manifest.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # Test the behavior of pg_verifybackup when the backup manifest has # problems. @@ -38,7 +41,7 @@ {"PostgreSQL-Backup-Manifest-Version": 1, "Files": true} EOM -test_parse_error('unknown toplevel field', <> 4; + /* + * XACT records need to be handled differently. Those records use the + * first bit of those four bits for an optional flag variable and the + * following three bits for the opcode. We filter opcode out of xl_info + * and use it as the identifier of the record. + */ + if (rmid == RM_XACT_ID) + recid &= 0x07; + stats->record_stats[rmid][recid].count++; stats->record_stats[rmid][recid].rec_len += rec_len; stats->record_stats[rmid][recid].fpi_len += fpi_len; @@ -467,8 +476,8 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record) desc->rm_name, rec_len, XLogRecGetTotalLen(record), XLogRecGetXid(record), - (uint32) (record->ReadRecPtr >> 32), (uint32) record->ReadRecPtr, - (uint32) (xl_prev >> 32), (uint32) xl_prev); + LSN_FORMAT_ARGS(record->ReadRecPtr), + LSN_FORMAT_ARGS(xl_prev)); id = desc->rm_identify(info); if (id == NULL) @@ -972,8 +981,7 @@ main(int argc, char **argv) else if (!XLByteInSeg(private.startptr, segno, WalSegSz)) { pg_log_error("start WAL location %X/%X is not inside file \"%s\"", - (uint32) (private.startptr >> 32), - (uint32) private.startptr, + LSN_FORMAT_ARGS(private.startptr), fname); goto bad_argument; } @@ -1015,8 +1023,7 @@ main(int argc, char **argv) private.endptr != (segno + 1) * WalSegSz) { pg_log_error("end WAL location %X/%X is not inside file \"%s\"", - (uint32) (private.endptr >> 32), - (uint32) private.endptr, + LSN_FORMAT_ARGS(private.endptr), argv[argc - 1]); goto bad_argument; } @@ -1048,8 +1055,7 @@ main(int argc, char **argv) if (first_record == InvalidXLogRecPtr) fatal_error("could not find a valid record after %X/%X", - (uint32) (private.startptr >> 32), - (uint32) private.startptr); + LSN_FORMAT_ARGS(private.startptr)); /* * Display a message that we're skipping data if `from` wasn't a pointer @@ -1061,8 +1067,8 @@ main(int argc, char **argv) printf(ngettext("first record is after %X/%X, at %X/%X, skipping over %u byte\n", "first record is after %X/%X, at %X/%X, skipping over %u bytes\n", (first_record - private.startptr)), - (uint32) (private.startptr >> 32), (uint32) private.startptr, - (uint32) (first_record >> 32), (uint32) first_record, + LSN_FORMAT_ARGS(private.startptr), + LSN_FORMAT_ARGS(first_record), (uint32) (first_record - private.startptr)); for (;;) @@ -1110,8 +1116,7 @@ main(int argc, char **argv) if (errormsg) fatal_error("error in WAL record at %X/%X: %s", - (uint32) (xlogreader_state->ReadRecPtr >> 32), - (uint32) xlogreader_state->ReadRecPtr, + LSN_FORMAT_ARGS(xlogreader_state->ReadRecPtr), errormsg); XLogReaderFree(xlogreader_state); diff --git a/src/bin/pg_waldump/po/cs.po b/src/bin/pg_waldump/po/cs.po index 2b8ab21a6ffd..b8b1278500b0 100644 --- a/src/bin/pg_waldump/po/cs.po +++ b/src/bin/pg_waldump/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_waldump (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-27 08:13+0000\n" -"PO-Revision-Date: 2019-09-27 20:46+0200\n" +"POT-Creation-Date: 2020-10-31 16:14+0000\n" +"PO-Revision-Date: 2020-10-31 21:06+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: cs\n" @@ -16,31 +16,29 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Poedit 2.2.3\n" +"X-Generator: Poedit 2.4.1\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format -#| msgid "fatal\n" msgid "fatal: " msgstr "fatal: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "error: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format -#| msgid "warning" msgid "warning: " msgstr "warning: " -#: pg_waldump.c:148 +#: pg_waldump.c:146 #, c-format -msgid "could not open file \"%s\": %s" -msgstr "nelze otevřít soubor \"%s\": %s" +msgid "could not open file \"%s\": %m" +msgstr "nelze otevřít soubor \"%s\": %m" -#: pg_waldump.c:205 +#: pg_waldump.c:202 #, c-format msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" @@ -48,47 +46,42 @@ msgstr[0] "velikost WAL segmentu musí být mocnina dvou mezi 1 MB a 1 GB, ale h msgstr[1] "velikost WAL segmentu musí být mocnina dvou mezi 1 MB a 1 GB, ale hlavička WAL souboru \"%s\" udává %d byty" msgstr[2] "velikost WAL segmentu musí být mocnina dvou mezi 1 MB a 1 GB, ale hlavička WAL souboru \"%s\" udává %d bytů" -#: pg_waldump.c:213 +#: pg_waldump.c:210 #, c-format -msgid "could not read file \"%s\": %s" -msgstr "nelze číst soubor \"%s\": %s" +msgid "could not read file \"%s\": %m" +msgstr "nelze číst soubor \"%s\": %m" -#: pg_waldump.c:216 +#: pg_waldump.c:213 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "nelze číst soubor \"%s\": načteno %d z %zu" -#: pg_waldump.c:294 +#: pg_waldump.c:275 #, c-format msgid "could not locate WAL file \"%s\"" msgstr "nelze najít WAL soubor \"%s\"" -#: pg_waldump.c:296 +#: pg_waldump.c:277 #, c-format msgid "could not find any WAL file" msgstr "nelze najít žádný WAL soubor" -#: pg_waldump.c:367 +#: pg_waldump.c:318 #, c-format -msgid "could not find file \"%s\": %s" -msgstr "nelze najít soubor \"%s\": %s" +msgid "could not find file \"%s\": %m" +msgstr "nelze najít soubor \"%s\": %m" -#: pg_waldump.c:382 -#, c-format -msgid "could not seek in log file %s to offset %u: %s" -msgstr "nelze nastavit pozici (seek) v log souboru %s na offset %u: %s" - -#: pg_waldump.c:405 +#: pg_waldump.c:367 #, c-format -msgid "could not read from log file %s, offset %u, length %d: %s" -msgstr "nelze číst z log souboru %s, offset %u, délka %d: %s" +msgid "could not read from file %s, offset %u: %m" +msgstr "nelze číst ze souboru %s, offset %u : %m" -#: pg_waldump.c:408 +#: pg_waldump.c:371 #, c-format -msgid "could not read from log file %s, offset %u: read %d of %zu" -msgstr "nelze číst z log souboru %s, offset %u, načteno %d z %zu" +msgid "could not read from file %s, offset %u: read %d of %zu" +msgstr "nelze číst ze souboru %s, offset %u, načteno %d z %zu" -#: pg_waldump.c:787 +#: pg_waldump.c:720 #, c-format msgid "" "%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" @@ -97,17 +90,17 @@ msgstr "" "%s dekóduje a zobrazuje PostgreSQL write-ahead logy pro účely debugování.\n" "\n" -#: pg_waldump.c:789 +#: pg_waldump.c:722 #, c-format msgid "Usage:\n" msgstr "Použití:\n" -#: pg_waldump.c:790 +#: pg_waldump.c:723 #, c-format msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" msgstr " %s [OPTION]... [STARTSEG [ENDSEG]]\n" -#: pg_waldump.c:791 +#: pg_waldump.c:724 #, c-format msgid "" "\n" @@ -116,27 +109,27 @@ msgstr "" "\n" "Přepínače:\n" -#: pg_waldump.c:792 +#: pg_waldump.c:725 #, c-format msgid " -b, --bkp-details output detailed information about backup blocks\n" msgstr " -b, --bkp-details output detailed information about backup blocks\n" -#: pg_waldump.c:793 +#: pg_waldump.c:726 #, c-format msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" msgstr " -e, --end=RECPTR přestane číst WAL na pozici RECPTR\n" -#: pg_waldump.c:794 +#: pg_waldump.c:727 #, c-format msgid " -f, --follow keep retrying after reaching end of WAL\n" msgstr " -f, --follow dále to zkoušet po dosažení konce WAL\n" -#: pg_waldump.c:795 +#: pg_waldump.c:728 #, c-format msgid " -n, --limit=N number of records to display\n" msgstr " -n, --limit=N počet záznamů pro zobrazení\n" -#: pg_waldump.c:796 +#: pg_waldump.c:729 #, c-format msgid "" " -p, --path=PATH directory in which to find log segment files or a\n" @@ -147,7 +140,12 @@ msgstr "" " adresář s ./pg_wal který tyto soubory obsahuje\n" " (implicitní: aktuální adresář, ./pg_wal, $PGDATA/pg_wal)\n" -#: pg_waldump.c:799 +#: pg_waldump.c:732 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet nevypisovat žádné zprávy, s výjimkou chyb\n" + +#: pg_waldump.c:733 #, c-format msgid "" " -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" @@ -156,12 +154,12 @@ msgstr "" " -r, --rmgr=RMGR zobrazí pouze záznamy generované resource managerem RMGR;\n" " použijte --rmgr=list pro seznam platných jmen resource managerů\n" -#: pg_waldump.c:801 +#: pg_waldump.c:735 #, c-format msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" msgstr " -s, --start=RECPTR začne číst WAL na pozici RECPTR\n" -#: pg_waldump.c:802 +#: pg_waldump.c:736 #, c-format msgid "" " -t, --timeline=TLI timeline from which to read log records\n" @@ -170,17 +168,17 @@ msgstr "" " -t, --timeline=TLI timeline ze které číst log záznamy\n" " (implicitní: 1 nebo hodnota v STARTSEG)\n" -#: pg_waldump.c:804 +#: pg_waldump.c:738 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version vypiš informace o verzi, potom skonči\n" -#: pg_waldump.c:805 +#: pg_waldump.c:739 #, c-format msgid " -x, --xid=XID only show records with transaction ID XID\n" msgstr " -x, --xid=XID zobrazí pouze záznamy pro transakci s ID XID\n" -#: pg_waldump.c:806 +#: pg_waldump.c:740 #, c-format msgid "" " -z, --stats[=record] show statistics instead of records\n" @@ -189,111 +187,111 @@ msgstr "" " -z, --stats[=record] zobrazí statistiky namísto záznamů\n" " (volitelně, zobrazí per-record statistiky)\n" -#: pg_waldump.c:808 +#: pg_waldump.c:742 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ukaž tuto nápovědu, potom skonči\n" -#: pg_waldump.c:809 +#: pg_waldump.c:743 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to <%s>.\n" msgstr "" "\n" -"Chyby hlaste na adresu .\n" +"Chyby hlašte na <%s>.\n" + +#: pg_waldump.c:744 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" -#: pg_waldump.c:883 +#: pg_waldump.c:821 #, c-format msgid "no arguments specified" msgstr "nezadán žádný argument" -#: pg_waldump.c:898 +#: pg_waldump.c:836 #, c-format msgid "could not parse end WAL location \"%s\"" msgstr "nelze naparsovat koncovou WAL pozici \"%s\"" -#: pg_waldump.c:910 +#: pg_waldump.c:848 #, c-format msgid "could not parse limit \"%s\"" msgstr "nelze naparsovat limit \"%s\"" -#: pg_waldump.c:938 +#: pg_waldump.c:879 #, c-format msgid "resource manager \"%s\" does not exist" msgstr "resource manager \"%s\" neexistuje" -#: pg_waldump.c:947 +#: pg_waldump.c:888 #, c-format msgid "could not parse start WAL location \"%s\"" msgstr "nelze naparsovat počáteční WAL pozici \"%s\"" -#: pg_waldump.c:957 +#: pg_waldump.c:898 #, c-format msgid "could not parse timeline \"%s\"" msgstr "nelze naparsovat timeline \"%s\"" -#: pg_waldump.c:964 +#: pg_waldump.c:905 #, c-format msgid "could not parse \"%s\" as a transaction ID" msgstr "nelze naparsovat \"%s\" jako ID transakce" -#: pg_waldump.c:979 +#: pg_waldump.c:920 #, c-format msgid "unrecognized argument to --stats: %s" msgstr "nerozpoznaný argument pro --stats: %s" -#: pg_waldump.c:992 +#: pg_waldump.c:933 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "příliš mnoho argumentů v příkazové řádce (první je \"%s\")" -#: pg_waldump.c:1002 +#: pg_waldump.c:943 pg_waldump.c:963 #, c-format -msgid "path \"%s\" could not be opened: %s" -msgstr "cestu \"%s\" nelze otevřít: %s" +msgid "could not open directory \"%s\": %m" +msgstr "nelze otevřít adresář \"%s\": %m" -#: pg_waldump.c:1023 -#, c-format -msgid "could not open directory \"%s\": %s" -msgstr "nelze otevřít adresář \"%s\": %s" - -#: pg_waldump.c:1030 pg_waldump.c:1061 +#: pg_waldump.c:969 pg_waldump.c:1000 #, c-format msgid "could not open file \"%s\"" msgstr "nelze otevřít soubor \"%s\"" -#: pg_waldump.c:1040 +#: pg_waldump.c:979 #, c-format msgid "start WAL location %X/%X is not inside file \"%s\"" msgstr "počátační WAL pozice %X/%X není v souboru \"%s\"" -#: pg_waldump.c:1068 +#: pg_waldump.c:1007 #, c-format msgid "ENDSEG %s is before STARTSEG %s" msgstr "ENDSEG %s je před STARTSEG %s" -#: pg_waldump.c:1083 +#: pg_waldump.c:1022 #, c-format msgid "end WAL location %X/%X is not inside file \"%s\"" msgstr "koncová WAL pozice %X/%X není v souboru \"%s\"" -#: pg_waldump.c:1096 +#: pg_waldump.c:1035 #, c-format msgid "no start WAL location given" msgstr "není zadána žádná WAL pozice" -#: pg_waldump.c:1106 +#: pg_waldump.c:1049 #, c-format msgid "out of memory" msgstr "nedostatek paměti" -#: pg_waldump.c:1112 +#: pg_waldump.c:1055 #, c-format msgid "could not find a valid record after %X/%X" msgstr "nelze najít platný záznam po %X/%X" -#: pg_waldump.c:1123 +#: pg_waldump.c:1066 #, c-format msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" @@ -301,18 +299,40 @@ msgstr[0] "první záznam po %X/%X, na %X/%X, přeskakuji %u bytů\n" msgstr[1] "první záznam po %X/%X, na %X/%X, přeskakuji %u byty\n" msgstr[2] "první záznam po %X/%X, na %X/%X, přeskakuji %u bytů\n" -#: pg_waldump.c:1174 +#: pg_waldump.c:1117 #, c-format msgid "error in WAL record at %X/%X: %s" msgstr "chyba ve WAL záznamu na %X/%X: %s" -#: pg_waldump.c:1184 +#: pg_waldump.c:1127 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" +#~ msgid "%s: FATAL: " +#~ msgstr "%s: FATAL: " + #~ msgid "not enough data in file \"%s\"" #~ msgstr "nedostatek dat v souboru \"%s\"" -#~ msgid "%s: FATAL: " -#~ msgstr "%s: FATAL: " +#~ msgid "could not open directory \"%s\": %s" +#~ msgstr "nelze otevřít adresář \"%s\": %s" + +#~ msgid "path \"%s\" could not be opened: %s" +#~ msgstr "cestu \"%s\" nelze otevřít: %s" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Chyby hlaste na adresu .\n" + +#~ msgid "could not seek in log file %s to offset %u: %s" +#~ msgstr "nelze nastavit pozici (seek) v log souboru %s na offset %u: %s" + +#~ msgid "could not read file \"%s\": %s" +#~ msgstr "nelze číst soubor \"%s\": %s" + +#~ msgid "could not open file \"%s\": %s" +#~ msgstr "nelze otevřít soubor \"%s\": %s" diff --git a/src/bin/pg_waldump/po/el.po b/src/bin/pg_waldump/po/el.po new file mode 100644 index 000000000000..50ef93deae0c --- /dev/null +++ b/src/bin/pg_waldump/po/el.po @@ -0,0 +1,308 @@ +# Greek message translation file for pg_waldump +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_waldump (PostgreSQL) package. +# Georgios Kokolatos , 2021. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-12 06:16+0000\n" +"PO-Revision-Date: 2021-05-17 10:40+0200\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο:" + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα:" + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση:" + +#: pg_waldump.c:146 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου “%s”: %m" + +#: pg_waldump.c:202 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "η τιμή του μεγέθους τμήματος WAL πρέπει να ανήκει σε δύναμη του δύο μεταξύ 1 MB και 1 GB, αλλά η κεφαλίδα \"%s\" του αρχείου WAL καθορίζει %d byte" +msgstr[1] "η τιμή του μεγέθους τμήματος WAL πρέπει να ανήκει σε δύναμη του δύο μεταξύ 1 MB και 1 GB, αλλά η κεφαλίδα “%s” του αρχείου WAL καθορίζει %d bytes" + +#: pg_waldump.c:210 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του αρχείου \"%s\": %m" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "δεν ήταν δυνατή η ανάγνωση του αρχείου \"%s\": ανέγνωσε %d από %zu" + +#: pg_waldump.c:275 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "δεν ήταν δυνατός ο εντοπισμός του αρχείου WAL \"%s\"" + +#: pg_waldump.c:277 +#, c-format +msgid "could not find any WAL file" +msgstr "δεν ήταν δυνατή η εύρεση οποιουδήποτε αρχείου WAL" + +#: pg_waldump.c:318 +#, c-format +msgid "could not find file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εύρεση του αρχείου \"%s\": %m" + +#: pg_waldump.c:367 +#, c-format +msgid "could not read from file %s, offset %u: %m" +msgstr "δεν ήταν δυνατή η ανάγνωση από αρχείο %s, μετατόπιση %u: %m" + +#: pg_waldump.c:371 +#, c-format +msgid "could not read from file %s, offset %u: read %d of %zu" +msgstr "δεν ήταν δυνατή η ανάγνωση από αρχείο %s, μετατόπιση %u: ανέγνωσε %d από %zu" + +#: pg_waldump.c:724 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s αποκωδικοποιεί και εμφανίζει αρχεία καταγραφής εμπρόσθιας-εγγραφής PostgreSQL για αποσφαλμάτωση.\n" +"\n" + +#: pg_waldump.c:726 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: pg_waldump.c:727 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [ΕΠΙΛΟΓΗ]… [STARTSEG [ENDSEG]]\n" + +#: pg_waldump.c:728 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Επιλογές:\n" + +#: pg_waldump.c:729 +#, c-format +msgid " -b, --bkp-details output detailed information about backup blocks\n" +msgstr " -b, —bkp-details πάραγε λεπτομερείς πληροφορίες σχετικά με τα μπλοκ αντιγράφων ασφαλείας\n" + +#: pg_waldump.c:730 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, —end=RECPTR σταμάτησε την ανάγνωση στη τοποθεσία WAL RECPTR\n" + +#: pg_waldump.c:731 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr " -f, —follow εξακολούθησε την προσπάθεια μετά την επίτευξη του τέλους του WAL\n" + +#: pg_waldump.c:732 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, —limit=N αριθμός των εγγραφών για εμφάνιση\n" + +#: pg_waldump.c:733 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" +msgstr "" +" -p, —path=PATH κατάλογος στον οποίο βρίσκονται αρχεία τμήματος καταγραφής ή\n" +" ένα κατάλογο με ./pg_wal που περιέχει τέτοια αρχεία\n" +" (προεπιλογή: τρέχων κατάλογος, ./pg_wal, $PGDATA/pg_wal)\n" + +#: pg_waldump.c:736 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, —quiet να μην εκτυπωθεί καμία έξοδος, εκτός από σφάλματα\n" + +#: pg_waldump.c:737 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" +" use --rmgr=list to list valid resource manager names\n" +msgstr "" +" -r, —rmgr=RMGR εμφάνισε μόνο εγγραφές που δημιουργούνται από τον διαχειριστή πόρων RMGR·\n" +" χρησιμοποίησε --rmgr=list για την παράθεση έγκυρων ονομάτων διαχειριστών πόρων\n" + +#: pg_waldump.c:739 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, —start=RECPTR άρχισε την ανάγνωση WAL από την τοποθεσία RECPTR\n" + +#: pg_waldump.c:740 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, —timeline=TLI χρονογραμή από την οποία να αναγνωστούν εγγραφές καταγραφής\n" +" (προεπιλογή: 1 ή η τιμή που χρησιμοποιήθηκε στο STARTSEG)\n" + +#: pg_waldump.c:742 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης και, στη συνέχεια, έξοδος\n" + +#: pg_waldump.c:743 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, —xid=XID εμφάνισε μόνο εγγραφές με ID συναλλαγής XID\n" + +#: pg_waldump.c:744 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, —stats[=record] εμφάνισε στατιστικά στοιχεία αντί για εγγραφές\n" +" (προαιρετικά, εμφάνισε στατιστικά στοιχεία ανά εγγραφή)\n" + +#: pg_waldump.c:746 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, —help εμφάνισε αυτό το μήνυμα βοήθειας, και μετά έξοδος\n" + +#: pg_waldump.c:747 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: pg_waldump.c:748 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: pg_waldump.c:825 +#, c-format +msgid "no arguments specified" +msgstr "δεν καθορίστηκαν παράμετροι" + +#: pg_waldump.c:840 +#, c-format +msgid "could not parse end WAL location \"%s\"" +msgstr "δεν ήταν δυνατή η ανάλυση της τελικής τοποθεσίας WAL \"%s\"" + +#: pg_waldump.c:852 +#, c-format +msgid "could not parse limit \"%s\"" +msgstr "δεν ήταν δυνατή η ανάλυση του ορίου \"%s\"" + +#: pg_waldump.c:883 +#, c-format +msgid "resource manager \"%s\" does not exist" +msgstr "ο διαχειριστής πόρων \"%s\" δεν υπάρχει" + +#: pg_waldump.c:892 +#, c-format +msgid "could not parse start WAL location \"%s\"" +msgstr "δεν ήταν δυνατή η ανάλυση της αρχικής τοποθεσίας WAL “%s”" + +#: pg_waldump.c:902 +#, c-format +msgid "could not parse timeline \"%s\"" +msgstr "δεν ήταν δυνατή η ανάλυση της χρονογραμμής “%s”" + +#: pg_waldump.c:909 +#, c-format +msgid "could not parse \"%s\" as a transaction ID" +msgstr "δεν ήταν δυνατή η ανάλυση του \"%s\" ως ID συναλλαγής" + +#: pg_waldump.c:924 +#, c-format +msgid "unrecognized argument to --stats: %s" +msgstr "μη αναγνωρισμένη παράμετρος για —stats: %s" + +#: pg_waldump.c:937 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "πάρα πολλοί παραμέτροι εισόδου από την γραμμή εντολών (ο πρώτη είναι η “%s”)" + +#: pg_waldump.c:947 pg_waldump.c:967 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του καταλόγου “%s”: %m" + +#: pg_waldump.c:973 pg_waldump.c:1003 +#, c-format +msgid "could not open file \"%s\"" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου \"%s\"" + +#: pg_waldump.c:983 +#, c-format +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "τοποθεσία εκκίνησης WAL %X/%X δεν βρίσκεται μέσα στο αρχείο \"%s\"" + +#: pg_waldump.c:1010 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "ENDSEG %s βρίσκεται πριν από STARTSEG %s" + +#: pg_waldump.c:1025 +#, c-format +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "η τελική τοποθεσία WAL %X/%X δεν βρίσκεται μέσα στο αρχείο \"%s\"" + +#: pg_waldump.c:1037 +#, c-format +msgid "no start WAL location given" +msgstr "δεν δόθηκε καμία τοποθεσία έναρξης WAL" + +#: pg_waldump.c:1051 +#, c-format +msgid "out of memory" +msgstr "έλλειψη μνήμης" + +#: pg_waldump.c:1057 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "δεν ήταν δυνατή η εύρεση έγκυρης εγγραφής μετά %X/%X" + +#: pg_waldump.c:1067 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "πρώτη εγγραφή βρίσκεται μετά από %X/%X, σε %X/%X, παρακάμπτοντας %u byte\n" +msgstr[1] "πρώτη εγγραφή βρίσκεται μετά από %X/%X, σε %X/%X, παρακάμπτοντας %u bytes\n" + +#: pg_waldump.c:1118 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "σφάλμα στην εγγραφή WAL στο %X/%X: %s" + +#: pg_waldump.c:1127 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" diff --git a/src/bin/pg_waldump/po/es.po b/src/bin/pg_waldump/po/es.po new file mode 100644 index 000000000000..c4001027e0d7 --- /dev/null +++ b/src/bin/pg_waldump/po/es.po @@ -0,0 +1,311 @@ +# Spanish message translation file for pg_waldump +# +# Copyright (c) 2017-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Carlos Chapi , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-13 10:45+0000\n" +"PO-Revision-Date: 2020-09-18 18:35-0300\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: pg_waldump.c:146 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: pg_waldump.c:202 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "el tamaño de segmento WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero la cabecera del archivo WAL «%s» especifica %d byte" +msgstr[1] "el tamaño de segmento WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero la cabecera del archivo WAL «%s» especifica %d bytes" + +#: pg_waldump.c:210 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" + +#: pg_waldump.c:275 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "no se pudo ubicar el archivo WAL «%s»" + +#: pg_waldump.c:277 +#, c-format +msgid "could not find any WAL file" +msgstr "no se pudo encontrar ningún archivo WAL" + +#: pg_waldump.c:318 +#, c-format +msgid "could not find file \"%s\": %m" +msgstr "no se pudo encontrar el archivo «%s»: %m" + +#: pg_waldump.c:367 +#, c-format +msgid "could not read from file %s, offset %u: %m" +msgstr "no se pudo leer desde el archivo «%s» en la posición %u: %m" + +# XXX why talk about "log segment" instead of "file"? +#: pg_waldump.c:371 +#, c-format +msgid "could not read from file %s, offset %u: read %d of %zu" +msgstr "no se pudo leer del archivo %s, posición %u: leídos %d de %zu" + +#: pg_waldump.c:720 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s decodifica y muestra segmentos de WAL de PostgreSQL para depuración.\n" +"\n" + +#: pg_waldump.c:722 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_waldump.c:723 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [OPCIÓN]... [SEGINICIAL [SEGFINAL]]\n" + +#: pg_waldump.c:724 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Opciones:\n" + +#: pg_waldump.c:725 +#, c-format +msgid " -b, --bkp-details output detailed information about backup blocks\n" +msgstr " -b, --bkp-details mostrar información detallada sobre bloques de respaldo\n" + +#: pg_waldump.c:726 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, --end=RECPTR detener la lectura del WAL en la posición RECPTR\n" + +#: pg_waldump.c:727 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr " -f, --follow seguir reintentando después de alcanzar el final del WAL\n" + +#: pg_waldump.c:728 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N número de registros a mostrar\n" + +#: pg_waldump.c:729 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" +msgstr "" +" -p, --path=RUTA directorio donde buscar los archivos de segmento de WAL\n" +" o un directorio con un ./pg_wal que contenga tales archivos\n" +" (por omisión: directorio actual, ./pg_wal, $PGDATA/pg_wal)\n" + +#: pg_waldump.c:732 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet no escribir ningún mensaje, excepto errores\n" + +#: pg_waldump.c:733 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" +" use --rmgr=list to list valid resource manager names\n" +msgstr "" +" -r, --rmgr=GREC sólo mostrar registros generados por el gestor de\n" +" recursos GREC; use --rmgr=list para listar nombres válidos\n" + +#: pg_waldump.c:735 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, --start=RECPTR empezar a leer el WAL en la posición RECPTR\n" + +#: pg_waldump.c:736 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=TLI timeline del cual leer los registros de WAL\n" +" (por omisión: 1 o el valor usado en SEGINICIAL)\n" + +#: pg_waldump.c:738 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión, luego salir\n" + +#: pg_waldump.c:739 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID sólo mostrar registros con el id de transacción XID\n" + +#: pg_waldump.c:740 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=registro] mostrar estadísticas en lugar de registros\n" +" (opcionalmente, mostrar estadísticas por registro)\n" + +#: pg_waldump.c:742 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda, luego salir\n" + +#: pg_waldump.c:743 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Reporte errores a <%s>.\n" + +#: pg_waldump.c:744 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: pg_waldump.c:821 +#, c-format +msgid "no arguments specified" +msgstr "no se especificó ningún argumento" + +#: pg_waldump.c:836 +#, c-format +msgid "could not parse end WAL location \"%s\"" +msgstr "no se pudo interpretar la posición final de WAL «%s»" + +#: pg_waldump.c:848 +#, c-format +msgid "could not parse limit \"%s\"" +msgstr "no se pudo interpretar el límite «%s»" + +#: pg_waldump.c:879 +#, c-format +msgid "resource manager \"%s\" does not exist" +msgstr "el gestor de recursos «%s» no existe" + +#: pg_waldump.c:888 +#, c-format +msgid "could not parse start WAL location \"%s\"" +msgstr "no se pudo interpretar la posición inicial de WAL «%s»" + +#: pg_waldump.c:898 +#, c-format +msgid "could not parse timeline \"%s\"" +msgstr "no se pudo interpretar el timeline «%s»" + +#: pg_waldump.c:905 +#, c-format +msgid "could not parse \"%s\" as a transaction ID" +msgstr "no se pudo interpretar «%s» como un id de transacción" + +#: pg_waldump.c:920 +#, c-format +msgid "unrecognized argument to --stats: %s" +msgstr "parámetro no reconocido para --stats: %s" + +#: pg_waldump.c:933 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_waldump.c:943 pg_waldump.c:963 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_waldump.c:969 pg_waldump.c:1000 +#, c-format +msgid "could not open file \"%s\"" +msgstr "no se pudo abrir el archivo «%s»" + +#: pg_waldump.c:979 +#, c-format +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "la posición inicial de WAL %X/%X no está en el archivo «%s»" + +#: pg_waldump.c:1007 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "SEGFINAL %s está antes del SEGINICIAL %s" + +#: pg_waldump.c:1022 +#, c-format +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "la posición final de WAL %X/%X no está en el archivo «%s»" + +#: pg_waldump.c:1035 +#, c-format +msgid "no start WAL location given" +msgstr "no se especificó posición inicial de WAL" + +#: pg_waldump.c:1049 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" + +#: pg_waldump.c:1055 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "no se pudo encontrar un registro válido después de %X/%X" + +#: pg_waldump.c:1066 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "el primer registro está ubicado después de %X/%X, en %X/%X, saltándose %u byte\n" +msgstr[1] "el primer registro está ubicado después de %X/%X, en %X/%X, saltándose %u bytes\n" + +#: pg_waldump.c:1117 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "error en registro de WAL en %X/%X: %s" + +#: pg_waldump.c:1127 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" diff --git a/src/bin/pg_waldump/po/ja.po b/src/bin/pg_waldump/po/ja.po new file mode 100644 index 000000000000..5e5a631d5c88 --- /dev/null +++ b/src/bin/pg_waldump/po/ja.po @@ -0,0 +1,323 @@ +# Japanese message translation file for pg_waldump +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:55+0900\n" +"PO-Revision-Date: 2020-09-13 08:57+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n!=1;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: pg_waldump.c:146 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンできませんでした: %m" + +#: pg_waldump.c:202 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "WALセグメントのサイズは1MBと1GBの間の2の累乗でなければなりません、しかしWALファイル\"%s\"のヘッダでは%dバイトとなっています" +msgstr[1] "WALセグメントのサイズは1MBと1GBの間の2の累乗でなければなりません、しかしWALファイル\"%s\"のヘッダでは%dバイトとなっています" + +#: pg_waldump.c:210 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "ファイル\"%s\"の読み取りに失敗しました: %m" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "ファイル\"%1$s\"を読み込めませんでした: %3$zuバイトのうち%2$dバイトを読み込みました" + +#: pg_waldump.c:275 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "WALファイル\"%s\"がありませんでした" + +#: pg_waldump.c:277 +#, c-format +msgid "could not find any WAL file" +msgstr "WALファイルが全くありません" + +#: pg_waldump.c:318 +#, c-format +msgid "could not find file \"%s\": %m" +msgstr "ファイル\"%s\"が見つかりませんでした: %m" + +#: pg_waldump.c:367 +#, c-format +msgid "could not read from file %s, offset %u: %m" +msgstr "ファイル\"%s\"のオフセット%uを読み取れませんでした: %m" + +#: pg_waldump.c:371 +#, c-format +msgid "could not read from file %s, offset %u: read %d of %zu" +msgstr "ファイル%1$s、オフセット%2$uから読み取れませんでした: %4$zu中%3$d" + +#: pg_waldump.c:715 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%sはデバッグのためにPostgreSQLの先行書き込みログをデコードして表示します。\n" +"\n" + +#: pg_waldump.c:717 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_waldump.c:718 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [オプション] ... [開始セグメント [終了セグメント]]\n" + +#: pg_waldump.c:719 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: pg_waldump.c:720 +#, c-format +msgid " -b, --bkp-details output detailed information about backup blocks\n" +msgstr " -b, --bkp-details バックアップブロックに関する詳細情報を出力\n" + +#: pg_waldump.c:721 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, --end=RECPTR WAL位置RECPTRで読み込みを停止\n" + +#: pg_waldump.c:722 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr " -f, --follow WALの終端に達してからもリトライを続ける\n" + +#: pg_waldump.c:723 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N 表示するレコード数\n" + +#: pg_waldump.c:724 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" +msgstr "" +" -p, --path=PATH ログセグメントファイルを探すディレクトリ、または\n" +" そのようなファイルを格納している ./pg_walディレクトリ\n" +" (デフォルト: カレントディレクトリ, ./pg_wal,\n" +" $PGDATA/pg_wal)\n" + +#: pg_waldump.c:727 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet エラー以外何も出力しない\n" + +#: pg_waldump.c:728 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" +" use --rmgr=list to list valid resource manager names\n" +msgstr "" +" -r, --rmgr=RMGR リソースマネージャーRMGRで生成されたレコードのみを表示\n" +" --rmgr=list で有効なリソースマネージャーの一覧を表示\n" + +#: pg_waldump.c:730 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, --start=RECPTR WAL位置RECPTRから読み込みを開始\n" + +#: pg_waldump.c:731 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=TLI ログレコードを読むべきタイムライン\n" +" (デフォルト: 1 またはSTARTSEGで使われた値)\n" + +#: pg_waldump.c:733 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: pg_waldump.c:734 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID トランザクションIDがXIDのレコードのみを表示する\n" + +#: pg_waldump.c:735 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=レコード] レコードの代わりに統計情報を表示する\n" +" (オプションで、レコードごとの統計を表示する)\n" + +#: pg_waldump.c:737 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help このヘルプを表示して終了\n" + +#: pg_waldump.c:738 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"バグは<%s>に報告してください。\n" + +#: pg_waldump.c:739 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: pg_waldump.c:816 +#, c-format +msgid "no arguments specified" +msgstr "引数が指定されていません" + +#: pg_waldump.c:831 +#, c-format +msgid "could not parse end WAL location \"%s\"" +msgstr "WALの終了位置\"%s\"をパースできませんでした" + +#: pg_waldump.c:843 +#, c-format +msgid "could not parse limit \"%s\"" +msgstr "表示レコード数の制限値\"%s\"をパースできませんでした" + +#: pg_waldump.c:874 +#, c-format +msgid "resource manager \"%s\" does not exist" +msgstr "リソースマネージャー\"%s\"は存在しません" + +#: pg_waldump.c:883 +#, c-format +msgid "could not parse start WAL location \"%s\"" +msgstr "WALの開始位置\"%s\"をパースできませんでした" + +#: pg_waldump.c:893 +#, c-format +msgid "could not parse timeline \"%s\"" +msgstr "タイムライン\"%s\"をパースできませんでした" + +#: pg_waldump.c:900 +#, c-format +msgid "could not parse \"%s\" as a transaction ID" +msgstr "\"%s\"をトランザクションIDとしてパースできませんでした" + +#: pg_waldump.c:915 +#, c-format +msgid "unrecognized argument to --stats: %s" +msgstr "--statsの引数が認識できません: %s" + +#: pg_waldump.c:928 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "コマンドライン引数が多すぎます(先頭は\"%s\")" + +#: pg_waldump.c:938 pg_waldump.c:958 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m" + +#: pg_waldump.c:964 pg_waldump.c:995 +#, c-format +msgid "could not open file \"%s\"" +msgstr "ファイル\"%s\"を開くことができませんでした" + +#: pg_waldump.c:974 +#, c-format +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "WALの開始位置%X/%Xはファイル\"%s\"の中ではありません" + +#: pg_waldump.c:1002 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "ENDSEG%sがSTARTSEG %sより前に現れました" + +#: pg_waldump.c:1017 +#, c-format +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "WALの終了位置%X/%Xはファイル\"%s\"の中ではありません" + +#: pg_waldump.c:1030 +#, c-format +msgid "no start WAL location given" +msgstr "WALの開始位置が指定されていません" + +#: pg_waldump.c:1044 +#, c-format +msgid "out of memory" +msgstr "メモリ不足です" + +#: pg_waldump.c:1050 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "%X/%Xの後に有効なレコードが見つかりませんでした" + +#: pg_waldump.c:1061 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "先頭レコードが%X/%Xの後の%X/%Xの位置にありました。%uバイト分をスキップしています\n" +msgstr[1] "先頭レコードが%X/%Xの後の%X/%Xの位置にありました。%uバイト分をスキップしています\n" + +#: pg_waldump.c:1112 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "WALレコードの%X/%Xでエラー: %s" + +#: pg_waldump.c:1122 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "\"%s --help\"で詳細を確認してください。\n" + +#~ msgid "%s: FATAL: " +#~ msgstr "%s: 致命的なエラー: " + +#~ msgid "could not open directory \"%s\": %s" +#~ msgstr "ディレクトリ\"%s\"を開くことができませんでした: %s" + +#~ msgid "could not read from log file %s, offset %u, length %d: %s" +#~ msgstr "ログファイル%sのオフセット%uから長さ%d分を読み取れませんでした: %s" + +#~ msgid "could not seek in log file %s to offset %u: %s" +#~ msgstr "ログファイル%sでオフセット%uにシークできませんでした: %s" + +#~ msgid "could not open file \"%s\": %s" +#~ msgstr "ファイル\"%s\"をオープンできませんでした: %s" diff --git a/src/bin/pg_waldump/po/ru.po b/src/bin/pg_waldump/po/ru.po new file mode 100644 index 000000000000..352c8370ef0d --- /dev/null +++ b/src/bin/pg_waldump/po/ru.po @@ -0,0 +1,363 @@ +# Russian message translation file for pg_waldump +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Alexander Lakhin , 2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-03 11:22+0300\n" +"PO-Revision-Date: 2020-09-03 15:07+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: pg_waldump.c:146 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не удалось открыть файл \"%s\": %m" + +#: pg_waldump.c:202 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL " +"file \"%s\" header specifies %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL " +"file \"%s\" header specifies %d bytes" +msgstr[0] "" +"Размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в заголовке файла WAL \"%s\" указано значение: %d" +msgstr[1] "" +"Размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в заголовке файла WAL \"%s\" указано значение: %d" +msgstr[2] "" +"Размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в заголовке файла WAL \"%s\" указано значение: %d" + +#: pg_waldump.c:210 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не удалось прочитать файл \"%s\": %m" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не удалось прочитать файл \"%s\" (прочитано байт: %d из %zu)" + +#: pg_waldump.c:275 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "не удалось найти файл WAL \"%s\"" + +#: pg_waldump.c:277 +#, c-format +msgid "could not find any WAL file" +msgstr "не удалось найти ни одного файла WAL" + +#: pg_waldump.c:318 +#, c-format +msgid "could not find file \"%s\": %m" +msgstr "не удалось найти файл \"%s\": %m" + +#: pg_waldump.c:367 +#, c-format +msgid "could not read from file %s, offset %u: %m" +msgstr "не удалось прочитать из файла \"%s\" по смещению %u: %m" + +#: pg_waldump.c:371 +#, c-format +msgid "could not read from file %s, offset %u: read %d of %zu" +msgstr "" +"не удалось прочитать из файла %s по смещению %u (прочитано байт: %d из %zu)" + +#: pg_waldump.c:720 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s декодирует и показывает журналы предзаписи PostgreSQL для целей отладки.\n" +"\n" + +#: pg_waldump.c:722 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: pg_waldump.c:723 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [ПАРАМЕТР]... [НАЧАЛЬНЫЙ_СЕГМЕНТ [КОНЕЧНЫЙ_СЕГМЕНТ]]\n" + +#: pg_waldump.c:724 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Параметры:\n" + +#: pg_waldump.c:725 +#, c-format +msgid "" +" -b, --bkp-details output detailed information about backup blocks\n" +msgstr "" +" -b, --bkp-details вывести подробную информацию о копиях страниц\n" + +# well-spelled: ПОЗЗАП +#: pg_waldump.c:726 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr "" +" -e, --end=ПОЗЗАП прекратить чтение в заданной позиции записи в WAL\n" + +#: pg_waldump.c:727 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr "" +" -f, --follow повторять попытки чтения по достижении конца WAL\n" + +#: pg_waldump.c:728 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N число выводимых записей\n" + +# skip-rule: space-before-period +#: pg_waldump.c:729 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/" +"pg_wal)\n" +msgstr "" +" -p, --path=ПУТЬ каталог, где нужно искать файлы сегментов журнала, " +"или\n" +" каталог с подкаталогом ./pg_wal, содержащим такие " +"файлы\n" +" (по умолчанию: текущий каталог,\n" +" ./pg_wal, $PGDATA/pg_wal)\n" + +#: pg_waldump.c:732 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet не выводить никаких сообщений, кроме ошибок\n" + +# well-spelled: МНГР +#: pg_waldump.c:733 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager " +"RMGR;\n" +" use --rmgr=list to list valid resource manager " +"names\n" +msgstr "" +" -r, --rmgr=МНГР выводить записи только менеджера ресурсов МНГР;\n" +" для просмотра списка доступных менеджеров ресурсов\n" +" укажите --rmgr=list\n" + +# well-spelled: ПОЗЗАП +#: pg_waldump.c:735 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr "" +" -s, --start=ПОЗЗАП начать чтение с заданной позиции записи в WAL\n" + +# well-spelled: ЛВР +#: pg_waldump.c:736 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=ЛВР линия времени, записи которой будут прочитаны\n" +" (по умолчанию: 1 или линия, определяемая " +"аргументом\n" +" НАЧАЛЬНЫЙ_СЕГМЕНТ)\n" + +#: pg_waldump.c:738 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: pg_waldump.c:739 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr "" +" -x, --xid=XID выводить только записи с заданным\n" +" идентификатором транзакции\n" + +#: pg_waldump.c:740 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=record] показывать статистику вместо записей\n" +" (также возможно получить статистику по записям)\n" + +#: pg_waldump.c:742 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать эту справку и выйти\n" + +#: pg_waldump.c:743 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"Об ошибках сообщайте по адресу <%s>.\n" + +#: pg_waldump.c:744 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: pg_waldump.c:821 +#, c-format +msgid "no arguments specified" +msgstr "аргументы не указаны" + +#: pg_waldump.c:836 +#, c-format +msgid "could not parse end WAL location \"%s\"" +msgstr "не удалось разобрать конечную позицию в WAL \"%s\"" + +#: pg_waldump.c:848 +#, c-format +msgid "could not parse limit \"%s\"" +msgstr "не удалось разобрать предел в \"%s\"" + +#: pg_waldump.c:879 +#, c-format +msgid "resource manager \"%s\" does not exist" +msgstr "менеджер ресурсов \"%s\" не существует" + +#: pg_waldump.c:888 +#, c-format +msgid "could not parse start WAL location \"%s\"" +msgstr "не удалось разобрать начальную позицию в WAL \"%s\"" + +#: pg_waldump.c:898 +#, c-format +msgid "could not parse timeline \"%s\"" +msgstr "не удалось разобрать линию времени в \"%s\"" + +#: pg_waldump.c:905 +#, c-format +msgid "could not parse \"%s\" as a transaction ID" +msgstr "не удалось разобрать в \"%s\" идентификатор транзакции" + +#: pg_waldump.c:920 +#, c-format +msgid "unrecognized argument to --stats: %s" +msgstr "нераспознанный аргумент ключа --stats: %s" + +#: pg_waldump.c:933 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "слишком много аргументов командной строки (первый: \"%s\")" + +#: pg_waldump.c:943 pg_waldump.c:963 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалось открыть каталог \"%s\": %m" + +#: pg_waldump.c:969 pg_waldump.c:1000 +#, c-format +msgid "could not open file \"%s\"" +msgstr "не удалось открыть файл \"%s\"" + +#: pg_waldump.c:979 +#, c-format +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "начальная позиция в WAL %X/%X находится не в файле \"%s\"" + +#: pg_waldump.c:1007 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "КОНЕЧНЫЙ_СЕГМЕНТ %s меньше, чем НАЧАЛЬНЫЙ_СЕГМЕНТ %s" + +#: pg_waldump.c:1022 +#, c-format +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "конечная позиция в WAL %X/%X находится не в файле \"%s\"" + +#: pg_waldump.c:1035 +#, c-format +msgid "no start WAL location given" +msgstr "начальная позиция в WAL не задана" + +#: pg_waldump.c:1049 +#, c-format +msgid "out of memory" +msgstr "нехватка памяти" + +#: pg_waldump.c:1055 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "не удалось найти действительную запись после позиции %X/%X" + +#: pg_waldump.c:1066 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "" +"первая запись обнаружена после %X/%X, в позиции %X/%X, пропускается %u Б\n" +msgstr[1] "" +"первая запись обнаружена после %X/%X, в позиции %X/%X, пропускается %u Б\n" +msgstr[2] "" +"первая запись обнаружена после %X/%X, в позиции %X/%X, пропускается %u Б\n" + +#: pg_waldump.c:1117 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "ошибка в записи WAL в позиции %X/%X: %s" + +#: pg_waldump.c:1127 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#~ msgid "could not seek in log file %s to offset %u: %s" +#~ msgstr "не удалось переместиться в файле журнала %s к смещению %u: %s" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Об ошибках сообщайте по адресу .\n" + +#~ msgid "path \"%s\" could not be opened: %s" +#~ msgstr "не удалось открыть путь \"%s\": %s" + +#~ msgid "%s: FATAL: " +#~ msgstr "%s: СБОЙ: " + +#~ msgid "not enough data in file \"%s\"" +#~ msgstr "недостаточно данных в файле \"%s\"" diff --git a/src/bin/pg_waldump/po/uk.po b/src/bin/pg_waldump/po/uk.po new file mode 100644 index 000000000000..71312d16ec34 --- /dev/null +++ b/src/bin/pg_waldump/po/uk.po @@ -0,0 +1,293 @@ +msgid "" +msgstr "" +"Project-Id-Version: postgresql\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-09-21 21:15+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: \n" +"Language-Team: Ukrainian\n" +"Language: uk_UA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: /DEV_13/pg_waldump.pot\n" +"X-Crowdin-File-ID: 512\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "збій: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "помилка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "попередження: " + +#: pg_waldump.c:146 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "не можливо відкрити файл \"%s\": %m" + +#: pg_waldump.c:202 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "Розмір сегмента WAL повинен задаватись ступенем двійки в інтервалі між 1 MB і 1 GB, але у заголовку файлу WAL \"%s\" вказано %d байт" +msgstr[1] "Розмір сегмента WAL повинен задаватись ступенем двійки в інтервалі між 1 MB і 1 GB, але у заголовку файлу WAL \"%s\" вказано %d байти" +msgstr[2] "Розмір сегмента WAL повинен задаватись ступенем двійки в інтервалі між 1 MB і 1 GB, але у заголовку файлу WAL \"%s\" вказано %d байтів" +msgstr[3] "Розмір сегмента WAL повинен задаватись ступенем двійки в інтервалі між 1 MB і 1 GB, але у заголовку файлу WAL \"%s\" вказано %d байтів" + +#: pg_waldump.c:210 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "не вдалося прочитати файл \"%s\": %m" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "не вдалося прочитати файл \"%s\": прочитано %d з %zu" + +#: pg_waldump.c:275 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "не вдалося знайти WAL файл \"%s\"" + +#: pg_waldump.c:277 +#, c-format +msgid "could not find any WAL file" +msgstr "не вдалося знайти жодного WAL файлу" + +#: pg_waldump.c:318 +#, c-format +msgid "could not find file \"%s\": %m" +msgstr "не вдалося знайти файл \"%s\": %m" + +#: pg_waldump.c:367 +#, c-format +msgid "could not read from file %s, offset %u: %m" +msgstr "не вдалося прочитати з файлу %s, зсув %u: %m" + +#: pg_waldump.c:371 +#, c-format +msgid "could not read from file %s, offset %u: read %d of %zu" +msgstr "не вдалося прочитати з файлу %s, зсув %u: прочитано %d з %zu" + +#: pg_waldump.c:720 +#, c-format +msgid "%s decodes and displays PostgreSQL write-ahead logs for debugging.\n\n" +msgstr "%s декодує і відображає журнали попереднього запису PostgreSQL для налагодження.\n\n" + +#: pg_waldump.c:722 +#, c-format +msgid "Usage:\n" +msgstr "Використання:\n" + +#: pg_waldump.c:723 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [OPTION]...[STARTSEG [ENDSEG]]\n" + +#: pg_waldump.c:724 +#, c-format +msgid "\n" +"Options:\n" +msgstr "\n" +"Параметри:\n" + +#: pg_waldump.c:725 +#, c-format +msgid " -b, --bkp-details output detailed information about backup blocks\n" +msgstr " -b, --bkp-details виводити детальну інформацію про блоки резервних копій\n" + +#: pg_waldump.c:726 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, --end=RECPTR зупинити читання WAL з місця RECPTR\n" + +#: pg_waldump.c:727 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr " -f, --follow повторювати спроби після досягнення кінця WAL\n" + +#: pg_waldump.c:728 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N число записів для відображення\n" + +#: pg_waldump.c:729 +#, c-format +msgid " -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" +msgstr " -p, --path=PATH каталог, у якому шукати файли сегментів журналу \n" +"або каталог з ./pg_wal, що містить такі файли (за замовчуванням: чинний каталог, ./pg_wal, $PGDATA/pg_wal)\n" + +#: pg_waldump.c:732 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet не друкувати жодного виводу, окрім помилок\n" + +#: pg_waldump.c:733 +#, c-format +msgid " -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" +" use --rmgr=list to list valid resource manager names\n" +msgstr " -r, --rmgr=RMGR відображати записи, згенеровані лише ресурсним менеджером RMGR;\n" +" використовувати --rmgr=list для перегляду списку припустимих імен ресурсного менеджера\n" + +#: pg_waldump.c:735 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, --start=RECPTR почати читання WAL з місця RECPTR\n" + +#: pg_waldump.c:736 +#, c-format +msgid " -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr " -t, --timeline=TLI часова шкала, записи якої будуть прочитані (за замовчуванням: 1 або значення, що використовується у STARTSEG)\n" + +#: pg_waldump.c:738 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version вивести інформацію про версію і вийти\n" + +#: pg_waldump.c:739 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID показати записи лише з ідентифікатором транзакцій XID\n" + +#: pg_waldump.c:740 +#, c-format +msgid " -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr " -z, --stats[=record] показати статистику замість записів (необов'язково, відобразити щорядкову статистику)\n" + +#: pg_waldump.c:742 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показати цю довідку потім вийти\n" + +#: pg_waldump.c:743 +#, c-format +msgid "\n" +"Report bugs to <%s>.\n" +msgstr "\n" +"Повідомляти про помилки на <%s>.\n" + +#: pg_waldump.c:744 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" + +#: pg_waldump.c:821 +#, c-format +msgid "no arguments specified" +msgstr "не вказано аргументів" + +#: pg_waldump.c:836 +#, c-format +msgid "could not parse end WAL location \"%s\"" +msgstr "не вдалося проаналізувати кінцеве розташування WAL \"%s\"" + +#: pg_waldump.c:848 +#, c-format +msgid "could not parse limit \"%s\"" +msgstr "не вдалося проаналізувати ліміт \"%s\"" + +#: pg_waldump.c:879 +#, c-format +msgid "resource manager \"%s\" does not exist" +msgstr "менеджер ресурсів \"%s\" не існує" + +#: pg_waldump.c:888 +#, c-format +msgid "could not parse start WAL location \"%s\"" +msgstr "не вдалося проаналізувати початкове розташування WAL \"%s\"" + +#: pg_waldump.c:898 +#, c-format +msgid "could not parse timeline \"%s\"" +msgstr "не вдалося проаналізувати часову шкалу \"%s\"" + +#: pg_waldump.c:905 +#, c-format +msgid "could not parse \"%s\" as a transaction ID" +msgstr "не вдалося прочитати \"%s\" як ідентифікатор транзакції" + +#: pg_waldump.c:920 +#, c-format +msgid "unrecognized argument to --stats: %s" +msgstr "нерозпізнаний аргумент для --stats: %s" + +#: pg_waldump.c:933 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "забагато аргументів у командному рядку (перший \"%s\")" + +#: pg_waldump.c:943 pg_waldump.c:963 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не вдалося відкрити каталог \"%s\": %m" + +#: pg_waldump.c:969 pg_waldump.c:1000 +#, c-format +msgid "could not open file \"%s\"" +msgstr "не вдалося відкрити файл \"%s\"" + +#: pg_waldump.c:979 +#, c-format +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "початкове розташування WAL %X/%X не всередині файлу \"%s\"" + +#: pg_waldump.c:1007 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "ENDSEG %s перед STARTSEG %s" + +#: pg_waldump.c:1022 +#, c-format +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "кінцеве розташування WAL %X/%X не всередині файлу \"%s\"" + +#: pg_waldump.c:1035 +#, c-format +msgid "no start WAL location given" +msgstr "не задано початкове розташування WAL" + +#: pg_waldump.c:1049 +#, c-format +msgid "out of memory" +msgstr "недостатньо пам'яті" + +#: pg_waldump.c:1055 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "не вдалося знайти припустимий запис після %X/%X" + +#: pg_waldump.c:1066 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "перший запис після %X/%X, у %X/%X, пропускається %u байт\n" +msgstr[1] "перший запис після %X/%X, у %X/%X, пропускається %u байти\n" +msgstr[2] "перший запис після %X/%X, у %X/%X, пропускається %u байтів\n" +msgstr[3] "перший запис після %X/%X, у %X/%X, пропускається %u байти\n" + +#: pg_waldump.c:1117 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "помилка у записі WAL у %X/%X: %s" + +#: pg_waldump.c:1127 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" + diff --git a/src/bin/pg_waldump/po/zh_CN.po b/src/bin/pg_waldump/po/zh_CN.po index 906a545dc48d..5aeb92882f7a 100644 --- a/src/bin/pg_waldump/po/zh_CN.po +++ b/src/bin/pg_waldump/po/zh_CN.po @@ -5,86 +5,81 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_waldump (PostgreSQL) 12\n" +"Project-Id-Version: pg_waldump (PostgreSQL) 13\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-05-22 17:56+0800\n" -"PO-Revision-Date: 2019-06-03 18:12+0800\n" +"POT-Creation-Date: 2020-06-05 01:45+0000\n" +"PO-Revision-Date: 2020-06-23 18:00+0800\n" "Last-Translator: Jie Zhang \n" "Language-Team: Chinese (Simplified) \n" +"Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: zh_CN\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "致命的: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "错误: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "警告: " -#: pg_waldump.c:148 +#: pg_waldump.c:146 #, c-format -msgid "could not open file \"%s\": %s" -msgstr "无法打开文件 \"%s\": %s" +msgid "could not open file \"%s\": %m" +msgstr "无法打开文件 \"%s\": %m" -#: pg_waldump.c:205 +#: pg_waldump.c:202 #, c-format msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" msgstr[0] "WAL段大小必须是1MB到1GB之间的2次幂,但WAL文件\"%s\"头指定了%d个字节" msgstr[1] "WAL段大小必须是1MB到1GB之间的2次幂,但WAL文件\"%s\"头指定了%d个字节" -#: pg_waldump.c:213 +#: pg_waldump.c:210 #, c-format -msgid "could not read file \"%s\": %s" -msgstr "无法读取文件 \"%s\": %s" +msgid "could not read file \"%s\": %m" +msgstr "无法读取文件 \"%s\": %m" -#: pg_waldump.c:216 +#: pg_waldump.c:213 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "无法读取文件\"%1$s\":读取了%3$zu中的%2$d" -#: pg_waldump.c:294 +#: pg_waldump.c:275 #, c-format msgid "could not locate WAL file \"%s\"" msgstr "找不到WAL文件\"%s\"" -#: pg_waldump.c:296 +#: pg_waldump.c:277 #, c-format msgid "could not find any WAL file" msgstr "找不到任何WAL文件" -#: pg_waldump.c:367 +#: pg_waldump.c:318 #, c-format -msgid "could not find file \"%s\": %s" -msgstr "找不到文件\"%s\": %s" +msgid "could not find file \"%s\": %m" +msgstr "找不到文件\"%s\": %m" -#: pg_waldump.c:382 -#, c-format -msgid "could not seek in log file %s to offset %u: %s" -msgstr "无法在日志文件%s中查找到偏移量%u: %s" - -#: pg_waldump.c:405 +#: pg_waldump.c:367 #, c-format -msgid "could not read from log file %s, offset %u, length %d: %s" -msgstr "无法读取日志文件%s,偏移量%u,长度%d: %s" +msgid "could not read from file %s, offset %u: %m" +msgstr "无法从文件 %s读取,偏移量 %u: %m" -#: pg_waldump.c:408 +#: pg_waldump.c:371 #, c-format -msgid "could not read from log file %s, offset %u: read %d of %zu" -msgstr "无法读取日志文件%1$s,偏移量%2$u,读取%4$zu中的%3$d" +msgid "could not read from file %s, offset %u: read %d of %zu" +msgstr "无法从文件%1$s读取,偏移量%2$u,读取%4$zu中的%3$d" -#: pg_waldump.c:787 +#: pg_waldump.c:720 #, c-format msgid "" "%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" @@ -93,17 +88,17 @@ msgstr "" "%s 为了调试,解码并显示PostgreSQL预写日志.\n" "\n" -#: pg_waldump.c:789 +#: pg_waldump.c:722 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_waldump.c:790 +#: pg_waldump.c:723 #, c-format msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" msgstr " %s [选项]... [STARTSEG [ENDSEG]]\n" -#: pg_waldump.c:791 +#: pg_waldump.c:724 #, c-format msgid "" "\n" @@ -112,27 +107,27 @@ msgstr "" "\n" "选项:\n" -#: pg_waldump.c:792 +#: pg_waldump.c:725 #, c-format msgid " -b, --bkp-details output detailed information about backup blocks\n" msgstr " -b, --bkp-details 输出有关备份块的详细信息\n" -#: pg_waldump.c:793 +#: pg_waldump.c:726 #, c-format msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" msgstr " -e, --end=RECPTR 在指定的WAL位置停止读取\n" -#: pg_waldump.c:794 +#: pg_waldump.c:727 #, c-format msgid " -f, --follow keep retrying after reaching end of WAL\n" msgstr " -f, --follow 在到达可用WAL的末尾之后,继续重试\n" -#: pg_waldump.c:795 +#: pg_waldump.c:728 #, c-format msgid " -n, --limit=N number of records to display\n" msgstr " -n, --limit=N 要显示的记录数\n" -#: pg_waldump.c:796 +#: pg_waldump.c:729 #, c-format msgid "" " -p, --path=PATH directory in which to find log segment files or a\n" @@ -143,7 +138,12 @@ msgstr "" " 或包含此类文件的./pg_wal目录\n" " (默认值: 当前的目录, ./pg_wal, $PGDATA/pg_wal)\n" -#: pg_waldump.c:799 +#: pg_waldump.c:732 +#, c-format +msgid " -q, --quiet do not print any output, except for errors\n" +msgstr " -q, --quiet 不打印任何输出,错误除外\n" + +#: pg_waldump.c:733 #, c-format msgid "" " -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" @@ -152,12 +152,12 @@ msgstr "" " -r, --rmgr=RMGR 只显示由RMGR资源管理器生成的记录\n" " 使用--rmgr=list列出有效的资源管理器名称\n" -#: pg_waldump.c:801 +#: pg_waldump.c:735 #, c-format msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" msgstr " -s, --start=RECPTR 在WAL中位于RECPTR处开始阅读\n" -#: pg_waldump.c:802 +#: pg_waldump.c:736 #, c-format msgid "" " -t, --timeline=TLI timeline from which to read log records\n" @@ -166,17 +166,17 @@ msgstr "" " -t, --timeline=TLI 要从哪个时间线读取日志记录\n" " (默认值:1或者是使用STARTSEG中的值)\n" -#: pg_waldump.c:804 +#: pg_waldump.c:738 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 输出版本信息, 然后退出\n" -#: pg_waldump.c:805 +#: pg_waldump.c:739 #, c-format msgid " -x, --xid=XID only show records with transaction ID XID\n" msgstr " -x, --xid=XID 只显示用给定事务ID标记的记录\n" -#: pg_waldump.c:806 +#: pg_waldump.c:740 #, c-format msgid "" " -z, --stats[=record] show statistics instead of records\n" @@ -185,115 +185,123 @@ msgstr "" " -z, --stats[=record] 显示统计信息而不是记录\n" " (或者,显示每个记录的统计信息)\n" -#: pg_waldump.c:808 +#: pg_waldump.c:742 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help 显示此帮助, 然后退出\n" -#: pg_waldump.c:868 +#: pg_waldump.c:743 +#, c-format +msgid "" +"\n" +"Report bugs to <%s>.\n" +msgstr "" +"\n" +"臭虫报告至 <%s>.\n" + +#: pg_waldump.c:744 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 主页: <%s>\n" + +#: pg_waldump.c:821 #, c-format msgid "no arguments specified" msgstr "未指定参数" -#: pg_waldump.c:883 +#: pg_waldump.c:836 #, c-format msgid "could not parse end WAL location \"%s\"" msgstr "无法解析WAL结束位置\"%s\"" -#: pg_waldump.c:899 +#: pg_waldump.c:848 #, c-format msgid "could not parse limit \"%s\"" msgstr "无法解析限制\"%s\"" -#: pg_waldump.c:927 +#: pg_waldump.c:879 #, c-format msgid "resource manager \"%s\" does not exist" msgstr "资源管理器\"%s\"不存在" -#: pg_waldump.c:936 +#: pg_waldump.c:888 #, c-format msgid "could not parse start WAL location \"%s\"" msgstr "无法解析WAL起始位置\"%s\"" -#: pg_waldump.c:946 +#: pg_waldump.c:898 #, c-format msgid "could not parse timeline \"%s\"" msgstr "无法解析时间线\"%s\"" -#: pg_waldump.c:957 +#: pg_waldump.c:905 #, c-format msgid "could not parse \"%s\" as a transaction ID" msgstr "无法将\"%s\"解析为事务ID" -#: pg_waldump.c:972 +#: pg_waldump.c:920 #, c-format msgid "unrecognized argument to --stats: %s" msgstr "无法识别的参数--stats: %s" -#: pg_waldump.c:985 +#: pg_waldump.c:933 #, c-format msgid "too many command-line arguments (first is \"%s\")" msgstr "命令行参数太多 (第一个是 \"%s\")" -#: pg_waldump.c:995 +#: pg_waldump.c:943 pg_waldump.c:963 #, c-format -msgid "path \"%s\" could not be opened: %s" -msgstr "无法打开路径\"%s\": %s" +msgid "could not open directory \"%s\": %m" +msgstr "无法打开目录 \"%s\": %m" -#: pg_waldump.c:1016 -#, c-format -msgid "could not open directory \"%s\": %s" -msgstr "无法打开目录\"%s\": %s" - -#: pg_waldump.c:1023 pg_waldump.c:1054 +#: pg_waldump.c:969 pg_waldump.c:1000 #, c-format msgid "could not open file \"%s\"" msgstr "could not open file\"%s\"" -#: pg_waldump.c:1033 +#: pg_waldump.c:979 #, c-format msgid "start WAL location %X/%X is not inside file \"%s\"" msgstr "WAL开始位置%X/%X不在文件\"%s\"中" -#: pg_waldump.c:1061 +#: pg_waldump.c:1007 #, c-format msgid "ENDSEG %s is before STARTSEG %s" msgstr "ENDSEG %s在STARTSEG %s之前" -#: pg_waldump.c:1076 +#: pg_waldump.c:1022 #, c-format msgid "end WAL location %X/%X is not inside file \"%s\"" msgstr "WAL结束位置%X/%X不在文件\"%s\"中" -#: pg_waldump.c:1089 +#: pg_waldump.c:1035 #, c-format msgid "no start WAL location given" msgstr "未给出WAL起始位置" -#: pg_waldump.c:1099 +#: pg_waldump.c:1049 #, c-format msgid "out of memory" msgstr "内存用尽" -#: pg_waldump.c:1105 +#: pg_waldump.c:1055 #, c-format msgid "could not find a valid record after %X/%X" msgstr "在%X/%X之后找不到有效记录" -#: pg_waldump.c:1116 +#: pg_waldump.c:1066 #, c-format msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" msgstr[0] "第一条记录在%X/%X之后,位于%X/%X,跳过了%u个字节\n" msgstr[1] "第一条记录在%X/%X之后,位于%X/%X,跳过了%u个字节\n" -#: pg_waldump.c:1167 +#: pg_waldump.c:1117 #, c-format msgid "error in WAL record at %X/%X: %s" msgstr "在WAL记录中的%X/%X处错误为: %s" -#: pg_waldump.c:1177 +#: pg_waldump.c:1127 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "请用 \"%s --help\" 获取更多的信息.\n" - +msgstr "请用 \"%s --help\" 获取更多的信息.\n" \ No newline at end of file diff --git a/src/bin/pg_waldump/t/001_basic.pl b/src/bin/pg_waldump/t/001_basic.pl index 5af0ce94fb80..fb2f807dc3bc 100644 --- a/src/bin/pg_waldump/t/001_basic.pl +++ b/src/bin/pg_waldump/t/001_basic.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use TestLib; diff --git a/src/bin/pgbench/exprparse.y b/src/bin/pgbench/exprparse.y index 85d61caa9f10..56f75ccd253e 100644 --- a/src/bin/pgbench/exprparse.y +++ b/src/bin/pgbench/exprparse.y @@ -4,7 +4,7 @@ * exprparse.y * bison grammar for a simple expression syntax * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pgbench/exprparse.y @@ -19,6 +19,7 @@ #define PGBENCH_NARGS_VARIABLE (-1) #define PGBENCH_NARGS_CASE (-2) #define PGBENCH_NARGS_HASH (-3) +#define PGBENCH_NARGS_PERMUTE (-4) PgBenchExpr *expr_parse_result; @@ -370,6 +371,9 @@ static const struct { "hash_fnv1a", PGBENCH_NARGS_HASH, PGBENCH_HASH_FNV1A }, + { + "permute", PGBENCH_NARGS_PERMUTE, PGBENCH_PERMUTE + }, /* keep as last array element */ { NULL, 0, 0 @@ -482,6 +486,19 @@ make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *args) } break; + /* pseudorandom permutation function with optional seed argument */ + case PGBENCH_NARGS_PERMUTE: + if (len < 2 || len > 3) + expr_yyerror_more(yyscanner, "unexpected number of arguments", + PGBENCH_FUNCTIONS[fnumber].fname); + + if (len == 2) + { + PgBenchExpr *var = make_variable("default_seed"); + args = make_elist(var, args); + } + break; + /* common case: positive arguments number */ default: Assert(PGBENCH_FUNCTIONS[fnumber].nargs >= 0); diff --git a/src/bin/pgbench/exprscan.l b/src/bin/pgbench/exprscan.l index 430bff38a617..75432cedc653 100644 --- a/src/bin/pgbench/exprscan.l +++ b/src/bin/pgbench/exprscan.l @@ -15,7 +15,7 @@ * * Note that this lexer operates within the framework created by psqlscan.l, * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pgbench/exprscan.l diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index cc142c4a8d78..cddd8fa0e4c1 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -59,6 +59,7 @@ #include "common/int.h" #include "common/logging.h" +#include "common/string.h" #include "fe_utils/cancel.h" #include "fe_utils/conditional.h" #include "getopt_long.h" @@ -1224,7 +1225,11 @@ doConnect(void) !have_password) { PQfinish(conn); - simple_prompt("Password: ", password, sizeof(password), false); + { + char *p = simple_prompt("Password: ", false); + strlcpy(password, p, sizeof(password)); + free(p); + } have_password = true; new_pass = true; } diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h index fb2c34f512fb..6ce1c98649ad 100644 --- a/src/bin/pgbench/pgbench.h +++ b/src/bin/pgbench/pgbench.h @@ -2,7 +2,7 @@ * * pgbench.h * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- @@ -99,7 +99,8 @@ typedef enum PgBenchFunction PGBENCH_IS, PGBENCH_CASE, PGBENCH_HASH_FNV1A, - PGBENCH_HASH_MURMUR2 + PGBENCH_HASH_MURMUR2, + PGBENCH_PERMUTE } PgBenchFunction; typedef struct PgBenchExpr PgBenchExpr; diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl index 52009c352429..3aa9d5d75309 100644 --- a/src/bin/pgbench/t/001_pgbench_with_server.pl +++ b/src/bin/pgbench/t/001_pgbench_with_server.pl @@ -1,9 +1,13 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; use PostgresNode; use TestLib; use Test::More; +use Config; # start a pgbench specific server my $node = get_new_node('main'); @@ -41,7 +45,7 @@ sub pgbench # filenames are expected to be unique on a test if (-e $filename) { - ok(0, "$filename must not already exists"); + ok(0, "$filename must not already exist"); unlink $filename or die "cannot unlink $filename: $!"; } append_to_file($filename, $$files{$fn}); @@ -90,13 +94,13 @@ sub pgbench 1, [qr{^$}], [ - qr{connection to database "no-such-database" failed}, + qr{connection to server .* failed}, qr{FATAL: database "no-such-database" does not exist} ], 'no such database'); pgbench( - '-S -t 1', 1, [qr{^$}], + '-S -t 1', 1, [], [qr{Perhaps you need to do initialization}], 'run without init'); @@ -287,7 +291,7 @@ sub pgbench [], [ qr{ERROR: invalid input syntax for type json}, - qr{(?!extended query with parameters)} + qr{(?!unnamed portal with parameters)} ], 'server parameter logging', { @@ -314,7 +318,7 @@ sub pgbench [], [ qr{ERROR: division by zero}, - qr{CONTEXT: extended query with parameters: \$1 = '1', \$2 = NULL} + qr{CONTEXT: unnamed portal with parameters: \$1 = '1', \$2 = NULL} ], 'server parameter logging', { @@ -328,7 +332,7 @@ sub pgbench [], [ qr{ERROR: invalid input syntax for type json}, - qr[CONTEXT: JSON data, line 1: \{ invalid\.\.\.[\r\n]+extended query with parameters: \$1 = '\{ invalid ', \$2 = '''Valame Dios!'' dijo Sancho; ''no le dije yo a vuestra merced que \.\.\.']m + qr[CONTEXT: JSON data, line 1: \{ invalid\.\.\.[\r\n]+unnamed portal with parameters: \$1 = '\{ invalid ', \$2 = '''Valame Dios!'' dijo Sancho; ''no le dije yo a vuestra merced que \.\.\.']m ], 'server parameter logging', { @@ -356,7 +360,7 @@ sub pgbench [], [ qr{ERROR: division by zero}, - qr{CONTEXT: extended query with parameters: \$1 = '1', \$2 = NULL} + qr{CONTEXT: unnamed portal with parameters: \$1 = '1', \$2 = NULL} ], 'server parameter logging', { @@ -373,7 +377,7 @@ sub pgbench [], [ qr{ERROR: invalid input syntax for type json}, - qr[CONTEXT: JSON data, line 1: \{ invalid\.\.\.[\r\n]+extended query with parameters: \$1 = '\{ invalid ', \$2 = '''Valame Dios!'' dijo Sancho; ''no le dije yo a vuestra merced que mirase bien lo que hacia\?']m + qr[CONTEXT: JSON data, line 1: \{ invalid\.\.\.[\r\n]+unnamed portal with parameters: \$1 = '\{ invalid ', \$2 = '''Valame Dios!'' dijo Sancho; ''no le dije yo a vuestra merced que mirase bien lo que hacia\?']m ], 'server parameter logging', { @@ -389,6 +393,22 @@ sub pgbench "parameter report truncates"); $log = undef; +# Check that bad parameters are reported during typinput phase of BIND +pgbench( + '-n -t1 -c1 -M prepared', + 2, + [], + [ + qr{ERROR: invalid input syntax for type smallint: "1a"}, + qr{CONTEXT: unnamed portal parameter \$2 = '1a'} + ], + 'server parameter logging', + { + '001_param_6' => q{select 42 as value1, '1a' as value2 \gset +select :value1::smallint, :value2::smallint; +} + }); + # Restore default logging config $node->append_conf('postgresql.conf', "log_min_duration_statement = -1\n" @@ -467,6 +487,15 @@ sub pgbench qr{command=98.: int 5432\b}, # :random_seed qr{command=99.: int -9223372036854775808\b}, # min int qr{command=100.: int 9223372036854775807\b}, # max int + # pseudorandom permutation tests + qr{command=101.: boolean true\b}, + qr{command=102.: boolean true\b}, + qr{command=103.: boolean true\b}, + qr{command=104.: boolean true\b}, + qr{command=105.: boolean true\b}, + qr{command=109.: boolean true\b}, + qr{command=110.: boolean true\b}, + qr{command=111.: boolean true\b}, ], 'pgbench expressions', { @@ -594,6 +623,24 @@ sub pgbench -- minint constant parsing \set min debug(-9223372036854775808) \set max debug(-(:min + 1)) +-- parametric pseudorandom permutation function +\set t debug(permute(0, 2) + permute(1, 2) = 1) +\set t debug(permute(0, 3) + permute(1, 3) + permute(2, 3) = 3) +\set t debug(permute(0, 4) + permute(1, 4) + permute(2, 4) + permute(3, 4) = 6) +\set t debug(permute(0, 5) + permute(1, 5) + permute(2, 5) + permute(3, 5) + permute(4, 5) = 10) +\set t debug(permute(0, 16) + permute(1, 16) + permute(2, 16) + permute(3, 16) + \ + permute(4, 16) + permute(5, 16) + permute(6, 16) + permute(7, 16) + \ + permute(8, 16) + permute(9, 16) + permute(10, 16) + permute(11, 16) + \ + permute(12, 16) + permute(13, 16) + permute(14, 16) + permute(15, 16) = 120) +-- random sanity checks +\set size random(2, 1000) +\set v random(0, :size - 1) +\set p permute(:v, :size) +\set t debug(0 <= :p and :p < :size and :p = permute(:v + :size, :size) and :p <> permute(:v + 1, :size)) +-- actual values +\set t debug(permute(:v, 1) = 0) +\set t debug(permute(0, 2, 5432) = 0 and permute(1, 2, 5432) = 1 and \ + permute(0, 2, 5435) = 1 and permute(1, 2, 5435) = 0) } }); @@ -755,6 +802,83 @@ sub pgbench } }); +# Working \startpipeline +pgbench( + '-t 1 -n -M extended', + 0, + [ qr{type: .*/001_pgbench_pipeline}, qr{actually processed: 1/1} ], + [], + 'working \startpipeline', + { + '001_pgbench_pipeline' => q{ +-- test startpipeline +\startpipeline +} . "select 1;\n" x 10 . q{ +\endpipeline +} + }); + +# Working \startpipeline in prepared query mode +pgbench( + '-t 1 -n -M prepared', + 0, + [ qr{type: .*/001_pgbench_pipeline_prep}, qr{actually processed: 1/1} ], + [], + 'working \startpipeline', + { + '001_pgbench_pipeline_prep' => q{ +-- test startpipeline +\startpipeline +} . "select 1;\n" x 10 . q{ +\endpipeline +} + }); + +# Try \startpipeline twice +pgbench( + '-t 1 -n -M extended', + 2, + [], + [qr{already in pipeline mode}], + 'error: call \startpipeline twice', + { + '001_pgbench_pipeline_2' => q{ +-- startpipeline twice +\startpipeline +\startpipeline +} + }); + +# Try to end a pipeline that hasn't started +pgbench( + '-t 1 -n -M extended', + 2, + [], + [qr{not in pipeline mode}], + 'error: \endpipeline with no start', + { + '001_pgbench_pipeline_3' => q{ +-- pipeline not started +\endpipeline +} + }); + +# Try \gset in pipeline mode +pgbench( + '-t 1 -n -M extended', + 2, + [], + [qr{gset is not allowed in pipeline mode}], + 'error: \gset not allowed in pipeline mode', + { + '001_pgbench_pipeline_4' => q{ +\startpipeline +select 1 \gset f +\endpipeline +} + }); + + # trigger many expression errors my @errors = ( @@ -955,16 +1079,22 @@ sub pgbench 'bad boolean', 2, [qr{malformed variable.*trueXXX}], q{\set b :badtrue or true} ], + [ + 'invalid permute size', + 2, + [qr{permute size parameter must be greater than zero}], + q{\set i permute(0, 0)} + ], # GSET [ 'gset no row', 2, [qr{expected one row, got 0\b}], q{SELECT WHERE FALSE \gset} ], - [ 'gset alone', 1, [qr{gset must follow a SQL command}], q{\gset} ], + [ 'gset alone', 1, [qr{gset must follow an SQL command}], q{\gset} ], [ - 'gset no SQL', 1, - [qr{gset must follow a SQL command}], q{\set i +1 + 'gset no SQL', 1, + [qr{gset must follow an SQL command}], q{\set i +1 \gset} ], [ @@ -972,8 +1102,8 @@ sub pgbench [qr{too many arguments}], q{SELECT 1 \gset a b} ], [ - 'gset after gset', 1, - [qr{gset must follow a SQL command}], q{SELECT 1 AS i \gset + 'gset after gset', 1, + [qr{gset must follow an SQL command}], q{SELECT 1 AS i \gset \gset} ], [ @@ -1043,7 +1173,12 @@ sub list_files return map { $dir . '/' . $_ } @files; } -# check log contents and cleanup +# Check log contents and clean them up: +# $dir: directory holding logs +# $prefix: file prefix for per-thread logs +# $nb: number of expected files +# $min/$max: minimum and maximum number of lines in log files +# $re: regular expression each log line has to match sub check_pgbench_logs { local $Test::Builder::Level = $Test::Builder::Level + 1; @@ -1058,42 +1193,51 @@ sub check_pgbench_logs my $log_number = 0; for my $log (sort @logs) { - eval { - open my $fh, '<', $log or die "$@"; - my @contents = <$fh>; - my $clen = @contents; - ok( $min <= $clen && $clen <= $max, - "transaction count for $log ($clen)"); - ok( grep($re, @contents) == $clen, - "transaction format for $prefix"); - close $fh or die "$@"; - }; + # Check the contents of each log file. + my $contents_raw = slurp_file($log); + + my @contents = split(/\n/, $contents_raw); + my $clen = @contents; + ok( $min <= $clen && $clen <= $max, + "transaction count for $log ($clen)"); + my $clen_match = grep(/$re/, @contents); + ok($clen_match == $clen, "transaction format for $prefix"); + + # Show more information if some logs don't match + # to help with debugging. + if ($clen_match != $clen) + { + foreach my $log (@contents) + { + print "# Log entry not matching: $log\n" + unless $log =~ /$re/; + } + } } - ok(unlink(@logs), "remove log files"); return; } my $bdir = $node->basedir; -# with sampling rate +# Run with sampling rate, 2 clients with 50 transactions each. pgbench( "-n -S -t 50 -c 2 --log --sampling-rate=0.5", 0, [ qr{select only}, qr{processed: 100/100} ], [qr{^$}], 'pgbench logs', undef, "--log-prefix=$bdir/001_pgbench_log_2"); - +# The IDs of the clients (1st field) in the logs should be either 0 or 1. check_pgbench_logs($bdir, '001_pgbench_log_2', 1, 8, 92, - qr{^0 \d{1,2} \d+ \d \d+ \d+$}); + qr{^[01] \d{1,2} \d+ \d \d+ \d+$}); -# check log file in some detail +# Run with different read-only option pattern, 1 client with 10 transactions. pgbench( - "-n -b se -t 10 -l", 0, + "-n -b select-only -t 10 -l", 0, [ qr{select only}, qr{processed: 10/10} ], [qr{^$}], 'pgbench logs contents', undef, "--log-prefix=$bdir/001_pgbench_log_3"); - +# The ID of a single client (1st field) should match 0. check_pgbench_logs($bdir, '001_pgbench_log_3', 1, 10, 10, - qr{^\d \d{1,2} \d+ \d \d+ \d+$}); + qr{^0 \d{1,2} \d+ \d \d+ \d+$}); # done $node->safe_psql('postgres', 'DROP TABLESPACE regress_pgbench_tap_1_ts'); diff --git a/src/bin/pgbench/t/002_pgbench_no_server.pl b/src/bin/pgbench/t/002_pgbench_no_server.pl index e38c7d77d1c0..346a2667fcac 100644 --- a/src/bin/pgbench/t/002_pgbench_no_server.pl +++ b/src/bin/pgbench/t/002_pgbench_no_server.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + # # pgbench tests which do not need a server # @@ -23,7 +26,6 @@ sub pgbench local $Test::Builder::Level = $Test::Builder::Level + 1; my ($opts, $stat, $out, $err, $name) = @_; - print STDERR "opts=$opts, stat=$stat, out=$out, err=$err, name=$name"; command_checks_all([ 'pgbench', split(/\s+/, $opts) ], $stat, $out, $err, $name); return; @@ -341,6 +343,16 @@ sub pgbench_scripts 'set i', [ qr{set i 1 }, qr{\^ error found here} ], { 'set_i_op' => "\\set i 1 +\n" } + ], + [ + 'not enough arguments to permute', + [qr{unexpected number of arguments \(permute\)}], + { 'bad-permute-1.sql' => "\\set i permute(1)\n" } + ], + [ + 'too many arguments to permute', + [qr{unexpected number of arguments \(permute\)}], + { 'bad-permute-2.sql' => "\\set i permute(1, 2, 3, 4)\n" } ],); for my $t (@script_tests) diff --git a/src/bin/pgevent/Makefile b/src/bin/pgevent/Makefile index 28c3078b01c0..da69e91839d5 100644 --- a/src/bin/pgevent/Makefile +++ b/src/bin/pgevent/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pgevent # -# Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Copyright (c) 1996-2021, PostgreSQL Global Development Group # #------------------------------------------------------------------------- diff --git a/src/bin/psql/Makefile b/src/bin/psql/Makefile index 2305d93e39cf..d00881163c02 100644 --- a/src/bin/psql/Makefile +++ b/src/bin/psql/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/psql # -# Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/psql/Makefile diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 79ed39e81720..7913712cbced 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/command.c */ @@ -10,6 +10,7 @@ #include #include #include +#include #ifndef WIN32 #include /* for stat() */ #include /* open() flags */ @@ -26,6 +27,7 @@ #include "command.h" #include "common.h" #include "common/logging.h" +#include "common/string.h" #include "copy.h" #include "crosstabview.h" #include "describe.h" @@ -36,6 +38,7 @@ #include "input.h" #include "large_obj.h" #include "libpq-fe.h" +#include "libpq/pqcomm.h" #include "mainloop.h" #include "portability/instr_time.h" #include "pqexpbuffer.h" @@ -69,6 +72,9 @@ static backslashResult exec_command_copyright(PsqlScanState scan_state, bool act static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd); +static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd, + const char *pattern, + bool show_verbose, bool show_system); static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, @@ -145,11 +151,11 @@ static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cst PQExpBuffer query_buf); static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, PQExpBuffer query_buf); -static void copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf); +static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf); static bool do_connect(enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port); static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, - int lineno, bool *edited); + int lineno, bool discard_on_quit, bool *edited); static bool do_shell(const char *command); static bool do_watch(PQExpBuffer query_buf, double sleep); static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, @@ -415,7 +421,7 @@ exec_command(const char *cmd, * the individual command subroutines. */ if (status == PSQL_CMD_SEND) - copy_previous_query(query_buf, previous_buf); + (void) copy_previous_query(query_buf, previous_buf); return status; } @@ -603,12 +609,9 @@ exec_command_conninfo(PsqlScanState scan_state, bool active_branch) char *host = PQhost(pset.db); char *hostaddr = PQhostaddr(pset.db); - /* - * If the host is an absolute path, the connection is via socket - * unless overridden by hostaddr - */ - if (is_absolute_path(host)) + if (is_unixsock_path(host)) { + /* hostaddr overrides host */ if (hostaddr && *hostaddr) printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"), db, PQuser(pset.db), hostaddr, PQport(pset.db)); @@ -790,7 +793,8 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 'p': case 't': case 'w': - success = describeFunctions(&cmd[2], pattern, show_verbose, show_system); + success = exec_command_dfo(scan_state, cmd, pattern, + show_verbose, show_system); break; default: status = PSQL_CMD_UNKNOWN; @@ -811,7 +815,8 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) success = listSchemas(pattern, show_verbose, show_system); break; case 'o': - success = describeOperators(pattern, show_verbose, show_system); + success = exec_command_dfo(scan_state, cmd, pattern, + show_verbose, show_system); break; case 'O': success = listCollations(pattern, show_verbose, show_system); @@ -929,6 +934,9 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) else success = listExtensions(pattern); break; + case 'X': /* Extended Statistics */ + success = listExtendedStats(pattern); + break; case 'y': /* Event Triggers */ success = listEventTriggers(pattern, show_verbose); break; @@ -948,6 +956,45 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) return status; } +/* \df and \do; messy enough to split out of exec_command_d */ +static bool +exec_command_dfo(PsqlScanState scan_state, const char *cmd, + const char *pattern, + bool show_verbose, bool show_system) +{ + bool success; + char *arg_patterns[FUNC_MAX_ARGS]; + int num_arg_patterns = 0; + + /* Collect argument-type patterns too */ + if (pattern) /* otherwise it was just \df or \do */ + { + char *ap; + + while ((ap = psql_scan_slash_option(scan_state, + OT_NORMAL, NULL, true)) != NULL) + { + arg_patterns[num_arg_patterns++] = ap; + if (num_arg_patterns >= FUNC_MAX_ARGS) + break; /* protect limited-size array */ + } + } + + if (cmd[1] == 'f') + success = describeFunctions(&cmd[2], pattern, + arg_patterns, num_arg_patterns, + show_verbose, show_system); + else + success = describeOperators(pattern, + arg_patterns, num_arg_patterns, + show_verbose, show_system); + + while (--num_arg_patterns >= 0) + free(arg_patterns[num_arg_patterns]); + + return success; +} + /* * \e or \edit -- edit the current query buffer, or edit a file and * make it the query buffer @@ -1001,14 +1048,27 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch, } if (status != PSQL_CMD_ERROR) { + bool discard_on_quit; + expand_tilde(&fname); if (fname) + { canonicalize_path(fname); + /* Always clear buffer if the file isn't modified */ + discard_on_quit = true; + } + else + { + /* + * If query_buf is empty, recall previous query for + * editing. But in that case, the query buffer should be + * emptied if editing doesn't modify the file. + */ + discard_on_quit = copy_previous_query(query_buf, + previous_buf); + } - /* If query_buf is empty, recall previous query for editing */ - copy_previous_query(query_buf, previous_buf); - - if (do_edit(fname, query_buf, lineno, NULL)) + if (do_edit(fname, query_buf, lineno, discard_on_quit, NULL)) status = PSQL_CMD_NEWEDIT; else status = PSQL_CMD_ERROR; @@ -1131,7 +1191,7 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, { bool edited = false; - if (!do_edit(NULL, query_buf, lineno, &edited)) + if (!do_edit(NULL, query_buf, lineno, true, &edited)) status = PSQL_CMD_ERROR; else if (!edited) puts(_("No changes")); @@ -1964,11 +2024,11 @@ exec_command_password(PsqlScanState scan_state, bool active_branch) { char *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true); - char pw1[100]; - char pw2[100]; + char *pw1; + char *pw2; - simple_prompt("Enter new password: ", pw1, sizeof(pw1), false); - simple_prompt("Enter it again: ", pw2, sizeof(pw2), false); + pw1 = simple_prompt("Enter new password: ", false); + pw2 = simple_prompt("Enter it again: ", false); if (strcmp(pw1, pw2) != 0) { @@ -2013,6 +2073,8 @@ exec_command_password(PsqlScanState scan_state, bool active_branch) if (opt0) free(opt0); + free(pw1); + free(pw2); } else ignore_slash_options(scan_state); @@ -2058,8 +2120,7 @@ exec_command_prompt(PsqlScanState scan_state, bool active_branch, if (!pset.inputfile) { - result = (char *) pg_malloc(4096); - simple_prompt(prompt_text, result, 4096, true); + result = simple_prompt(prompt_text, true); } else { @@ -2296,17 +2357,8 @@ exec_command_setenv(PsqlScanState scan_state, bool active_branch, else { /* Set variable to the value of the next argument */ - char *newval; - - newval = psprintf("%s=%s", envvar, envval); - putenv(newval); + setenv(envvar, envval, 1); success = true; - - /* - * Do not free newval here, it will screw up the environment if - * you do. See putenv man page for details. That means we leak a - * bit of memory here, but not enough to worry about. - */ } free(envvar); free(envval); @@ -2642,7 +2694,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch, } /* If query_buf is empty, recall and execute previous query */ - copy_previous_query(query_buf, previous_buf); + (void) copy_previous_query(query_buf, previous_buf); success = do_watch(query_buf, sleep); @@ -2966,12 +3018,19 @@ discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, * This is used by various slash commands for which re-execution of a * previous query is a common usage. For convenience, we allow the * case of query_buf == NULL (and do nothing). + * + * Returns "true" if the previous query was copied into the query + * buffer, else "false". */ -static void +static bool copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf) { if (query_buf && query_buf->len == 0) + { appendPQExpBufferStr(query_buf, previous_buf->data); + return true; + } + return false; } /* @@ -2982,19 +3041,19 @@ copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf) static char * prompt_for_password(const char *username) { - char buf[100]; + char *result; if (username == NULL || username[0] == '\0') - simple_prompt("Password: ", buf, sizeof(buf), false); + result = simple_prompt("Password: ", false); else { char *prompt_text; prompt_text = psprintf(_("Password for user %s: "), username); - simple_prompt(prompt_text, buf, sizeof(buf), false); + result = simple_prompt(prompt_text, false); free(prompt_text); } - return pg_strdup(buf); + return result; } static bool @@ -3009,34 +3068,13 @@ param_is_newly_set(const char *old_val, const char *new_val) return false; } -/* return whether the connection has 'hostaddr' in its conninfo */ -static bool -has_hostaddr(PGconn *conn) -{ - bool used = false; - PQconninfoOption *ciopt = PQconninfo(conn); - - for (PQconninfoOption *p = ciopt; p->keyword != NULL; p++) - { - if (strcmp(p->keyword, "hostaddr") == 0 && p->val != NULL) - { - used = true; - break; - } - } - - PQconninfoFree(ciopt); - return used; -} - /* * do_connect -- handler for \connect * - * Connects to a database with given parameters. Absent an established - * connection, all parameters are required. Given -reuse-previous=off or a - * connection string without -reuse-previous=on, NULL values will pass through - * to PQconnectdbParams(), so the libpq defaults will be used. Otherwise, NULL - * values will be replaced with the ones in the current connection. + * Connects to a database with given parameters. If we are told to re-use + * parameters, parameters from the previous connection are used where the + * command's own options do not supply a value. Otherwise, libpq defaults + * are used. * * In interactive mode, if connection fails with the given parameters, * the old connection will be kept. @@ -3046,28 +3084,27 @@ do_connect(enum trivalue reuse_previous_specification, char *dbname, char *user, char *host, char *port) { PGconn *o_conn = pset.db, - *n_conn; + *n_conn = NULL; + PQconninfoOption *cinfo; + int nconnopts = 0; + bool same_host = false; char *password = NULL; - char *hostaddr = NULL; - bool keep_password; + char *client_encoding; + bool success = true; + bool keep_password = true; bool has_connection_string; bool reuse_previous; - PQExpBufferData connstr; - if (!o_conn && (!dbname || !user || !host || !port)) + has_connection_string = dbname ? + recognized_connection_string(dbname) : false; + + /* Complain if we have additional arguments after a connection string. */ + if (has_connection_string && (user || host || port)) { - /* - * We don't know the supplied connection parameters and don't want to - * connect to the wrong database by using defaults, so require all - * parameters to be specified. - */ - pg_log_error("All connection parameters must be supplied because no " - "database connection exists"); + pg_log_error("Do not give user, host, or port separately when using a connection string"); return false; } - has_connection_string = dbname ? - recognized_connection_string(dbname) : false; switch (reuse_previous_specification) { case TRI_YES: @@ -3081,68 +3118,183 @@ do_connect(enum trivalue reuse_previous_specification, break; } - /* If the old connection does not exist, there is nothing to reuse. */ - if (!o_conn) - reuse_previous = false; - - /* Silently ignore arguments subsequent to a connection string. */ - if (has_connection_string) - { - user = NULL; - host = NULL; - port = NULL; - } - /* - * Grab missing values from the old connection. If we grab host (or host - * is the same as before) and hostaddr was set, grab that too. + * If we intend to re-use connection parameters, collect them out of the + * old connection, then replace individual values as necessary. (We may + * need to resort to looking at pset.dead_conn, if the connection died + * previously.) Otherwise, obtain a PQconninfoOption array containing + * libpq's defaults, and modify that. Note this function assumes that + * PQconninfo, PQconndefaults, and PQconninfoParse will all produce arrays + * containing the same options in the same order. */ if (reuse_previous) { - if (!user) - user = PQuser(o_conn); - if (host && strcmp(host, PQhost(o_conn)) == 0 && - has_hostaddr(o_conn)) - { - hostaddr = PQhostaddr(o_conn); - } - if (!host) + if (o_conn) + cinfo = PQconninfo(o_conn); + else if (pset.dead_conn) + cinfo = PQconninfo(pset.dead_conn); + else { - host = PQhost(o_conn); - if (has_hostaddr(o_conn)) - hostaddr = PQhostaddr(o_conn); + /* This is reachable after a non-interactive \connect failure */ + pg_log_error("No database connection exists to re-use parameters from"); + return false; } - if (!port) - port = PQport(o_conn); } - - /* - * Any change in the parameters read above makes us discard the password. - * We also discard it if we're to use a conninfo rather than the - * positional syntax. - */ - if (has_connection_string) - keep_password = false; else - keep_password = - (user && PQuser(o_conn) && strcmp(user, PQuser(o_conn)) == 0) && - (host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) && - (port && PQport(o_conn) && strcmp(port, PQport(o_conn)) == 0); + cinfo = PQconndefaults(); - /* - * Grab missing dbname from old connection. No password discard if this - * changes: passwords aren't (usually) database-specific. - */ - if (!dbname && reuse_previous) + if (cinfo) { - initPQExpBuffer(&connstr); - appendPQExpBufferStr(&connstr, "dbname="); - appendConnStrVal(&connstr, PQdb(o_conn)); - dbname = connstr.data; - /* has_connection_string=true would be a dead store */ + if (has_connection_string) + { + /* Parse the connstring and insert values into cinfo */ + PQconninfoOption *replcinfo; + char *errmsg; + + replcinfo = PQconninfoParse(dbname, &errmsg); + if (replcinfo) + { + PQconninfoOption *ci; + PQconninfoOption *replci; + bool have_password = false; + + for (ci = cinfo, replci = replcinfo; + ci->keyword && replci->keyword; + ci++, replci++) + { + Assert(strcmp(ci->keyword, replci->keyword) == 0); + /* Insert value from connstring if one was provided */ + if (replci->val) + { + /* + * We know that both val strings were allocated by + * libpq, so the least messy way to avoid memory leaks + * is to swap them. + */ + char *swap = replci->val; + + replci->val = ci->val; + ci->val = swap; + + /* + * Check whether connstring provides options affecting + * password re-use. While any change in user, host, + * hostaddr, or port causes us to ignore the old + * connection's password, we don't force that for + * dbname, since passwords aren't database-specific. + */ + if (replci->val == NULL || + strcmp(ci->val, replci->val) != 0) + { + if (strcmp(replci->keyword, "user") == 0 || + strcmp(replci->keyword, "host") == 0 || + strcmp(replci->keyword, "hostaddr") == 0 || + strcmp(replci->keyword, "port") == 0) + keep_password = false; + } + /* Also note whether connstring contains a password. */ + if (strcmp(replci->keyword, "password") == 0) + have_password = true; + } + else if (!reuse_previous) + { + /* + * When we have a connstring and are not re-using + * parameters, swap *all* entries, even those not set + * by the connstring. This avoids absorbing + * environment-dependent defaults from the result of + * PQconndefaults(). We don't want to do that because + * they'd override service-file entries if the + * connstring specifies a service parameter, whereas + * the priority should be the other way around. libpq + * can certainly recompute any defaults we don't pass + * here. (In this situation, it's a bit wasteful to + * have called PQconndefaults() at all, but not doing + * so would require yet another major code path here.) + */ + replci->val = ci->val; + ci->val = NULL; + } + } + Assert(ci->keyword == NULL && replci->keyword == NULL); + + /* While here, determine how many option slots there are */ + nconnopts = ci - cinfo; + + PQconninfoFree(replcinfo); + + /* + * If the connstring contains a password, tell the loop below + * that we may use it, regardless of other settings (i.e., + * cinfo's password is no longer an "old" password). + */ + if (have_password) + keep_password = true; + + /* Don't let code below try to inject dbname into params. */ + dbname = NULL; + } + else + { + /* PQconninfoParse failed */ + if (errmsg) + { + pg_log_error("%s", errmsg); + PQfreemem(errmsg); + } + else + pg_log_error("out of memory"); + success = false; + } + } + else + { + /* + * If dbname isn't a connection string, then we'll inject it and + * the other parameters into the keyword array below. (We can't + * easily insert them into the cinfo array because of memory + * management issues: PQconninfoFree would misbehave on Windows.) + * However, to avoid dependencies on the order in which parameters + * appear in the array, make a preliminary scan to set + * keep_password and same_host correctly. + * + * While any change in user, host, or port causes us to ignore the + * old connection's password, we don't force that for dbname, + * since passwords aren't database-specific. + */ + PQconninfoOption *ci; + + for (ci = cinfo; ci->keyword; ci++) + { + if (user && strcmp(ci->keyword, "user") == 0) + { + if (!(ci->val && strcmp(user, ci->val) == 0)) + keep_password = false; + } + else if (host && strcmp(ci->keyword, "host") == 0) + { + if (ci->val && strcmp(host, ci->val) == 0) + same_host = true; + else + keep_password = false; + } + else if (port && strcmp(ci->keyword, "port") == 0) + { + if (!(ci->val && strcmp(port, ci->val) == 0)) + keep_password = false; + } + } + + /* While here, determine how many option slots there are */ + nconnopts = ci - cinfo; + } } else - connstr.data = NULL; + { + /* We failed to create the cinfo structure */ + pg_log_error("out of memory"); + success = false; + } /* * If the user asked to be prompted for a password, ask for one now. If @@ -3154,77 +3306,85 @@ do_connect(enum trivalue reuse_previous_specification, * the postmaster's log. But libpq offers no API that would let us obtain * a password and then continue with the first connection attempt. */ - if (pset.getPassword == TRI_YES) + if (pset.getPassword == TRI_YES && success) { /* - * If a connstring or URI is provided, we can't be sure we know which - * username will be used, since we haven't parsed that argument yet. + * If a connstring or URI is provided, we don't know which username + * will be used, since we haven't dug that out of the connstring. * Don't risk issuing a misleading prompt. As in startup.c, it does - * not seem worth working harder, since this getPassword option is + * not seem worth working harder, since this getPassword setting is * normally only used in noninteractive cases. */ password = prompt_for_password(has_connection_string ? NULL : user); } - else if (o_conn && keep_password) - { - password = PQpass(o_conn); - if (password && *password) - password = pg_strdup(password); - else - password = NULL; - } - while (true) - { -#define PARAMS_ARRAY_SIZE 9 - const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); - const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); - int paramnum = -1; + /* + * Consider whether to force client_encoding to "auto" (overriding + * anything in the connection string). We do so if we have a terminal + * connection and there is no PGCLIENTENCODING environment setting. + */ + if (pset.notty || getenv("PGCLIENTENCODING")) + client_encoding = NULL; + else + client_encoding = "auto"; - keywords[++paramnum] = "host"; - values[paramnum] = host; - if (hostaddr && *hostaddr) - { - keywords[++paramnum] = "hostaddr"; - values[paramnum] = hostaddr; - } - keywords[++paramnum] = "port"; - values[paramnum] = port; - keywords[++paramnum] = "user"; - values[paramnum] = user; + /* Loop till we have a connection or fail, which we might've already */ + while (success) + { + const char **keywords = pg_malloc((nconnopts + 1) * sizeof(*keywords)); + const char **values = pg_malloc((nconnopts + 1) * sizeof(*values)); + int paramnum = 0; + PQconninfoOption *ci; /* - * Position in the array matters when the dbname is a connection - * string, because settings in a connection string override earlier - * array entries only. Thus, user= in the connection string always - * takes effect, but client_encoding= often will not. + * Copy non-default settings into the PQconnectdbParams parameter + * arrays; but inject any values specified old-style, as well as any + * interactively-obtained password, and a couple of fields we want to + * set forcibly. * - * If you change this code, also change the initial-connection code in - * main(). For no good reason, a connection string password= takes - * precedence in main() but not here. + * If you change this code, see also the initial-connection code in + * main(). */ - keywords[++paramnum] = "dbname"; - values[paramnum] = dbname; - keywords[++paramnum] = "password"; - values[paramnum] = password; - keywords[++paramnum] = "fallback_application_name"; - values[paramnum] = pset.progname; - keywords[++paramnum] = "client_encoding"; - values[paramnum] = (pset.notty || getenv("PGCLIENTENCODING")) ? NULL : "auto"; - + for (ci = cinfo; ci->keyword; ci++) + { + keywords[paramnum] = ci->keyword; + + if (dbname && strcmp(ci->keyword, "dbname") == 0) + values[paramnum++] = dbname; + else if (user && strcmp(ci->keyword, "user") == 0) + values[paramnum++] = user; + else if (host && strcmp(ci->keyword, "host") == 0) + values[paramnum++] = host; + else if (host && !same_host && strcmp(ci->keyword, "hostaddr") == 0) + { + /* If we're changing the host value, drop any old hostaddr */ + values[paramnum++] = NULL; + } + else if (port && strcmp(ci->keyword, "port") == 0) + values[paramnum++] = port; + /* If !keep_password, we unconditionally drop old password */ + else if ((password || !keep_password) && + strcmp(ci->keyword, "password") == 0) + values[paramnum++] = password; + else if (strcmp(ci->keyword, "fallback_application_name") == 0) + values[paramnum++] = pset.progname; + else if (client_encoding && + strcmp(ci->keyword, "client_encoding") == 0) + values[paramnum++] = client_encoding; + else if (ci->val) + values[paramnum++] = ci->val; + /* else, don't bother making libpq parse this keyword */ + } /* add array terminator */ - keywords[++paramnum] = NULL; + keywords[paramnum] = NULL; values[paramnum] = NULL; - n_conn = PQconnectdbParams(keywords, values, true); + /* Note we do not want libpq to re-expand the dbname parameter */ + n_conn = PQconnectdbParams(keywords, values, false); pg_free(keywords); pg_free(values); - /* We can immediately discard the password -- no longer needed */ - if (password) - pg_free(password); - if (PQstatus(n_conn) == CONNECTION_OK) break; @@ -3240,9 +3400,28 @@ do_connect(enum trivalue reuse_previous_specification, */ password = prompt_for_password(PQuser(n_conn)); PQfinish(n_conn); + n_conn = NULL; continue; } + /* + * We'll report the error below ... unless n_conn is NULL, indicating + * that libpq didn't have enough memory to make a PGconn. + */ + if (n_conn == NULL) + pg_log_error("out of memory"); + + success = false; + } /* end retry loop */ + + /* Release locally allocated data, whether we succeeded or not */ + if (password) + pg_free(password); + if (cinfo) + PQconninfoFree(cinfo); + + if (!success) + { /* * Failed to connect to the database. In interactive mode, keep the * previous connection to the DB; in scripting mode, close our @@ -3250,7 +3429,11 @@ do_connect(enum trivalue reuse_previous_specification, */ if (pset.cur_cmd_interactive) { - pg_log_info("%s", PQerrorMessage(n_conn)); + if (n_conn) + { + pg_log_info("%s", PQerrorMessage(n_conn)); + PQfinish(n_conn); + } /* pset.db is left unmodified */ if (o_conn) @@ -3258,27 +3441,39 @@ do_connect(enum trivalue reuse_previous_specification, } else { - pg_log_error("\\connect: %s", PQerrorMessage(n_conn)); + if (n_conn) + { + pg_log_error("\\connect: %s", PQerrorMessage(n_conn)); + PQfinish(n_conn); + } + if (o_conn) { /* - * Transition to having no connection. Keep this bit in sync - * with CheckConnection(). + * Transition to having no connection. + * + * Unlike CheckConnection(), we close the old connection + * immediately to prevent its parameters from being re-used. + * This is so that a script cannot accidentally reuse + * parameters it did not expect to. Otherwise, the state + * cleanup should be the same as in CheckConnection(). */ PQfinish(o_conn); pset.db = NULL; ResetCancelConn(); UnsyncVariables(); } + + /* On the same reasoning, release any dead_conn to prevent reuse */ + if (pset.dead_conn) + { + PQfinish(pset.dead_conn); + pset.dead_conn = NULL; + } } - PQfinish(n_conn); - if (connstr.data) - termPQExpBuffer(&connstr); return false; } - if (connstr.data) - termPQExpBuffer(&connstr); /* * Replace the old connection with the new one, and update @@ -3300,12 +3495,9 @@ do_connect(enum trivalue reuse_previous_specification, char *host = PQhost(pset.db); char *hostaddr = PQhostaddr(pset.db); - /* - * If the host is an absolute path, the connection is via socket - * unless overridden by hostaddr - */ - if (is_absolute_path(host)) + if (is_unixsock_path(host)) { + /* hostaddr overrides host */ if (hostaddr && *hostaddr) printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"), PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db)); @@ -3328,8 +3520,15 @@ do_connect(enum trivalue reuse_previous_specification, PQdb(pset.db), PQuser(pset.db)); } + /* Drop no-longer-needed connection(s) */ if (o_conn) PQfinish(o_conn); + if (pset.dead_conn) + { + PQfinish(pset.dead_conn); + pset.dead_conn = NULL; + } + return true; } @@ -3512,10 +3711,11 @@ UnsyncVariables(void) /* - * do_edit -- handler for \e + * helper for do_edit(): actually invoke the editor * - * If you do not specify a filename, the current query buffer will be copied - * into a temporary one. + * Returns true on success, false if we failed to invoke the editor or + * it returned nonzero status. (An error message is printed for failed- + * to-invoke cases, but not if the editor returns nonzero status.) */ static bool editFile(const char *fname, int lineno) @@ -3584,17 +3784,29 @@ editFile(const char *fname, int lineno) } -/* call this one */ +/* + * do_edit -- handler for \e + * + * If you do not specify a filename, the current query buffer will be copied + * into a temporary file. + * + * After this function is done, the resulting file will be copied back into the + * query buffer. As an exception to this, the query buffer will be emptied + * if the file was not modified (or the editor failed) and the caller passes + * "discard_on_quit" = true. + * + * If "edited" isn't NULL, *edited will be set to true if the query buffer + * is successfully replaced. + */ static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, - int lineno, bool *edited) + int lineno, bool discard_on_quit, bool *edited) { char fnametmp[MAXPGPATH]; FILE *stream = NULL; const char *fname; bool error = false; int fd; - struct stat before, after; @@ -3619,13 +3831,13 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, !ret ? strerror(errno) : ""); return false; } +#endif /* * No canonicalize_path() here. EDIT.EXE run from CMD.EXE prepends the * current directory to the supplied path unless we use only * backslashes, so we do that. */ -#endif #ifndef WIN32 snprintf(fnametmp, sizeof(fnametmp), "%s%spsql.edit.%d.sql", tmpdir, "/", (int) getpid()); @@ -3675,6 +3887,24 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, pg_log_error("%s: %m", fname); error = true; } + else + { + struct utimbuf ut; + + /* + * Try to set the file modification time of the temporary file + * a few seconds in the past. Otherwise, the low granularity + * (one second, or even worse on some filesystems) that we can + * portably measure with stat(2) could lead us to not + * recognize a modification, if the user typed very quickly. + * + * This is a rather unlikely race condition, so don't error + * out if the utime(2) call fails --- that would make the cure + * worse than the disease. + */ + ut.modtime = ut.actime = time(NULL) - 2; + (void) utime(fname, &ut); + } } } @@ -3694,7 +3924,10 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, error = true; } - if (!error && before.st_mtime != after.st_mtime) + /* file was edited if the size or modification time has changed */ + if (!error && + (before.st_size != after.st_size || + before.st_mtime != after.st_mtime)) { stream = fopen(fname, PG_BINARY_R); if (!stream) @@ -3715,6 +3948,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, { pg_log_error("%s: %m", fname); error = true; + resetPQExpBuffer(query_buf); } else if (edited) { @@ -3724,6 +3958,15 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, fclose(stream); } } + else + { + /* + * If the file was not modified, and the caller requested it, discard + * the query buffer. + */ + if (discard_on_quit) + resetPQExpBuffer(query_buf); + } /* remove temp file */ if (!filename_arg) diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h index 006832f1022a..0ff5b768db1a 100644 --- a/src/bin/psql/command.h +++ b/src/bin/psql/command.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/command.h */ diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 6323a35c91ca..9a0049951092 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/common.c */ @@ -313,10 +313,14 @@ CheckConnection(void) fprintf(stderr, _("Failed.\n")); /* - * Transition to having no connection. Keep this bit in sync with - * do_connect(). + * Transition to having no connection; but stash away the failed + * connection so that we can still refer to its parameters in a + * later \connect attempt. Keep the state cleanup here in sync + * with do_connect(). */ - PQfinish(pset.db); + if (pset.dead_conn) + PQfinish(pset.dead_conn); + pset.dead_conn = pset.db; pset.db = NULL; ResetCancelConn(); UnsyncVariables(); @@ -782,6 +786,13 @@ StoreQueryTuple(const PGresult *result) /* concatenate prefix and column name */ varname = psprintf("%s%s", pset.gset_prefix, colname); + if (VariableHasHook(pset.vars, varname)) + { + pg_log_warning("attempt to \\gset into specially treated variable \"%s\" ignored", + varname); + continue; + } + if (!PQgetisnull(result, 0, i)) value = PQgetvalue(result, 0, i); else @@ -1339,12 +1350,13 @@ SendQuery(const char *query) /* * Do nothing if they are messing with savepoints themselves: - * If the user did RELEASE or ROLLBACK, our savepoint is gone. - * If they issued a SAVEPOINT, releasing ours would remove - * theirs. + * If the user did COMMIT AND CHAIN, RELEASE or ROLLBACK, our + * savepoint is gone. If they issued a SAVEPOINT, releasing + * ours would remove theirs. */ if (results && - (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 || + (strcmp(PQcmdStatus(results), "COMMIT") == 0 || + strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 || strcmp(PQcmdStatus(results), "RELEASE") == 0 || strcmp(PQcmdStatus(results), "ROLLBACK") == 0)) svptcmd = NULL; @@ -1834,7 +1846,7 @@ skip_white_space(const char *query) while (*query) { - int mblen = PQmblen(query, pset.encoding); + int mblen = PQmblenBounded(query, pset.encoding); /* * Note: we assume the encoding is a superset of ASCII, so that for @@ -1871,7 +1883,7 @@ skip_white_space(const char *query) query++; break; } - query += PQmblen(query, pset.encoding); + query += PQmblenBounded(query, pset.encoding); } } else if (cnestlevel > 0) @@ -1906,7 +1918,7 @@ command_no_begin(const char *query) */ wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); /* * Transaction control commands. These should include every keyword that @@ -1937,7 +1949,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); if (wordlen == 11 && pg_strncasecmp(query, "transaction", 11) == 0) return true; @@ -1971,7 +1983,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0) return true; @@ -1987,7 +1999,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); } if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0) @@ -1998,7 +2010,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0) return true; @@ -2015,7 +2027,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); /* ALTER SYSTEM isn't allowed in xacts */ if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0) @@ -2038,7 +2050,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0) return true; @@ -2053,7 +2065,7 @@ command_no_begin(const char *query) query = skip_white_space(query); wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); /* * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in @@ -2072,7 +2084,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0) return true; @@ -2092,7 +2104,7 @@ command_no_begin(const char *query) wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); if (wordlen == 3 && pg_strncasecmp(query, "all", 3) == 0) return true; @@ -2128,7 +2140,7 @@ is_select_command(const char *query) */ wordlen = 0; while (isalpha((unsigned char) query[wordlen])) - wordlen += PQmblen(&query[wordlen], pset.encoding); + wordlen += PQmblenBounded(&query[wordlen], pset.encoding); if (wordlen == 6 && pg_strncasecmp(query, "select", 6) == 0) return true; @@ -2142,9 +2154,6 @@ is_select_command(const char *query) /* * Test if the current user is a database superuser. - * - * Note: this will correctly detect superuserness only with a protocol-3.0 - * or newer backend; otherwise it will always say "false". */ bool is_superuser(void) @@ -2165,9 +2174,6 @@ is_superuser(void) /* * Test if the current session uses standard string literals. - * - * Note: With a pre-protocol-3.0 connection this will always say "false", - * which should be the right answer. */ bool standard_strings(void) @@ -2188,10 +2194,6 @@ standard_strings(void) /* * Return the session user of the current connection. - * - * Note: this will correctly detect the session user only with a - * protocol-3.0 or newer backend; otherwise it will return the - * connection user. */ const char * session_username(void) diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index ec4e83c9fdf8..041b2ac068a7 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/common.h */ diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index 8749f946dfa5..50a48a972595 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/copy.c */ @@ -717,7 +717,9 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) /* * Terminate data transfer. We can't send an error message if we're using - * protocol version 2. + * protocol version 2. (libpq no longer supports protocol version 2, but + * keep the version checks just in case you're using a pre-v14 libpq.so at + * runtime) */ if (PQputCopyEnd(conn, (OK || PQprotocolVersion(conn) < 3) ? NULL : diff --git a/src/bin/psql/copy.h b/src/bin/psql/copy.h index b2daf9185128..5923da869843 100644 --- a/src/bin/psql/copy.h +++ b/src/bin/psql/copy.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/copy.h */ diff --git a/src/bin/psql/create_help.pl b/src/bin/psql/create_help.pl index ee82e645832e..83324239740b 100644 --- a/src/bin/psql/create_help.pl +++ b/src/bin/psql/create_help.pl @@ -3,7 +3,7 @@ ################################################################# # create_help.pl -- converts SGML docs to internal psql help # -# Copyright (c) 2000-2020, PostgreSQL Global Development Group +# Copyright (c) 2000-2021, PostgreSQL Global Development Group # # src/bin/psql/create_help.pl ################################################################# @@ -63,11 +63,12 @@ struct _helpStruct { - const char *cmd; /* the command name */ - const char *help; /* the help associated with it */ - const char *docbook_id; /* DocBook XML id (for generating URL) */ - void (*syntaxfunc)(PQExpBuffer); /* function that prints the syntax associated with it */ - int nl_count; /* number of newlines in syntax (for pager) */ + const char *cmd; /* the command name */ + const char *help; /* the help associated with it */ + const char *docbook_id; /* DocBook XML id (for generating URL) */ + void (*syntaxfunc) (PQExpBuffer); /* function that prints the + * syntax associated with it */ + int nl_count; /* number of newlines in syntax (for pager) */ }; extern const struct _helpStruct QL_HELP[]; @@ -190,17 +191,17 @@ { my $id = $_; $id =~ s/ /_/g; - print $cfile_handle " { \"$_\", - N_(\"$entries{$_}{cmddesc}\"), - \"$entries{$_}{cmdid}\", - sql_help_$id, - $entries{$_}{nl_count} }, + print $cfile_handle "\t{\"$_\", +\t\tN_(\"$entries{$_}{cmddesc}\"), +\t\t\"$entries{$_}{cmdid}\", +\t\tsql_help_$id, +\t$entries{$_}{nl_count}}, "; } print $cfile_handle " - { NULL, NULL, NULL } /* End of list marker */ +\t{NULL, NULL, NULL}\t\t\t/* End of list marker */ }; "; @@ -210,7 +211,7 @@ #define QL_MAX_CMD_LEN $maxlen /* largest strlen(cmd) */ -#endif /* $define */ +#endif /* $define */ "; close $cfile_handle; diff --git a/src/bin/psql/crosstabview.c b/src/bin/psql/crosstabview.c index f06cb068c90b..97515f0d4a0b 100644 --- a/src/bin/psql/crosstabview.c +++ b/src/bin/psql/crosstabview.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/crosstabview.c */ diff --git a/src/bin/psql/crosstabview.h b/src/bin/psql/crosstabview.h index 096e76b62249..53d0e4182ba9 100644 --- a/src/bin/psql/crosstabview.h +++ b/src/bin/psql/crosstabview.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/crosstabview.h */ diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 104c820d6997..69a13830e9a0 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -6,7 +6,7 @@ * with servers of versions 7.4 and up. It's okay to omit irrelevant * information for an old server, but not to fail outright. * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/describe.c */ @@ -31,6 +31,7 @@ #include "catalog/gp_distribution_policy.h" #include "catalog/pg_foreign_server.h" +static const char *map_typename_pattern(const char *pattern); static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, @@ -456,7 +457,9 @@ describeTablespaces(const char *pattern, bool verbose) * and you can mix and match these in any order. */ bool -describeFunctions(const char *functypes, const char *pattern, bool verbose, bool showSystem) +describeFunctions(const char *functypes, const char *func_pattern, + char **arg_patterns, int num_arg_patterns, + bool verbose, bool showSystem) { bool showAggregate = strchr(functypes, 'a') != NULL; bool showNormal = strchr(functypes, 'n') != NULL; @@ -693,11 +696,18 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool appendPQExpBufferStr(&buf, ",\n "); printACLColumn(&buf, "p.proacl"); appendPQExpBuffer(&buf, - ",\n l.lanname as \"%s\"" - ",\n p.prosrc as \"%s\"" + ",\n l.lanname as \"%s\"", + gettext_noop("Language")); + if (pset.sversion >= 140000) + appendPQExpBuffer(&buf, + ",\n COALESCE(pg_catalog.pg_get_function_sqlbody(p.oid), p.prosrc) as \"%s\"", + gettext_noop("Source code")); + else + appendPQExpBuffer(&buf, + ",\n p.prosrc as \"%s\"", + gettext_noop("Source code")); + appendPQExpBuffer(&buf, ",\n pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"", - gettext_noop("Language"), - gettext_noop("Source code"), gettext_noop("Description")); } @@ -705,6 +715,14 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool "\nFROM pg_catalog.pg_proc p" "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"); + for (int i = 0; i < num_arg_patterns; i++) + { + appendPQExpBuffer(&buf, + " LEFT JOIN pg_catalog.pg_type t%d ON t%d.oid = p.proargtypes[%d]\n" + " LEFT JOIN pg_catalog.pg_namespace nt%d ON nt%d.oid = t%d.typnamespace\n", + i, i, i, i, i, i); + } + if (verbose) appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n"); @@ -810,11 +828,43 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool appendPQExpBufferStr(&buf, " )\n"); } - processSQLNamePattern(pset.db, &buf, pattern, have_where, false, + processSQLNamePattern(pset.db, &buf, func_pattern, have_where, false, "n.nspname", "p.proname", NULL, "pg_catalog.pg_function_is_visible(p.oid)"); - if (!showSystem && !pattern) + for (int i = 0; i < num_arg_patterns; i++) + { + if (strcmp(arg_patterns[i], "-") != 0) + { + /* + * Match type-name patterns against either internal or external + * name, like \dT. Unlike \dT, there seems no reason to + * discriminate against arrays or composite types. + */ + char nspname[64]; + char typname[64]; + char ft[64]; + char tiv[64]; + + snprintf(nspname, sizeof(nspname), "nt%d.nspname", i); + snprintf(typname, sizeof(typname), "t%d.typname", i); + snprintf(ft, sizeof(ft), + "pg_catalog.format_type(t%d.oid, NULL)", i); + snprintf(tiv, sizeof(tiv), + "pg_catalog.pg_type_is_visible(t%d.oid)", i); + processSQLNamePattern(pset.db, &buf, + map_typename_pattern(arg_patterns[i]), + true, false, + nspname, typname, ft, tiv); + } + else + { + /* "-" pattern specifies no such parameter */ + appendPQExpBuffer(&buf, " AND t%d.typname IS NULL\n", i); + } + } + + if (!showSystem && !func_pattern) appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n"); @@ -934,20 +984,24 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) "WHERE c.oid = t.typrelid))\n"); /* - * do not include array types (before 8.3 we have to use the assumption - * that their names start with underscore) + * do not include array types unless the pattern contains [] (before 8.3 + * we have to use the assumption that their names start with underscore) */ - if (pset.sversion >= 80300) - appendPQExpBufferStr(&buf, " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n"); - else - appendPQExpBufferStr(&buf, " AND t.typname !~ '^_'\n"); + if (pattern == NULL || strstr(pattern, "[]") == NULL) + { + if (pset.sversion >= 80300) + appendPQExpBufferStr(&buf, " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n"); + else + appendPQExpBufferStr(&buf, " AND t.typname !~ '^_'\n"); + } if (!showSystem && !pattern) appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n"); /* Match name pattern against either internal or external name */ - processSQLNamePattern(pset.db, &buf, pattern, true, false, + processSQLNamePattern(pset.db, &buf, map_typename_pattern(pattern), + true, false, "n.nspname", "t.typname", "pg_catalog.format_type(t.oid, NULL)", "pg_catalog.pg_type_is_visible(t.oid)"); @@ -969,13 +1023,69 @@ describeTypes(const char *pattern, bool verbose, bool showSystem) return true; } +/* + * Map some variant type names accepted by the backend grammar into + * canonical type names. + * + * Helper for \dT and other functions that take typename patterns. + * This doesn't completely mask the fact that these names are special; + * for example, a pattern of "dec*" won't magically match "numeric". + * But it goes a long way to reduce the surprise factor. + */ +static const char * +map_typename_pattern(const char *pattern) +{ + static const char *const typename_map[] = { + /* + * These names are accepted by gram.y, although they are neither the + * "real" name seen in pg_type nor the canonical name printed by + * format_type(). + */ + "decimal", "numeric", + "float", "double precision", + "int", "integer", + + /* + * We also have to map the array names for cases where the canonical + * name is different from what pg_type says. + */ + "bool[]", "boolean[]", + "decimal[]", "numeric[]", + "float[]", "double precision[]", + "float4[]", "real[]", + "float8[]", "double precision[]", + "int[]", "integer[]", + "int2[]", "smallint[]", + "int4[]", "integer[]", + "int8[]", "bigint[]", + "time[]", "time without time zone[]", + "timetz[]", "time with time zone[]", + "timestamp[]", "timestamp without time zone[]", + "timestamptz[]", "timestamp with time zone[]", + "varbit[]", "bit varying[]", + "varchar[]", "character varying[]", + NULL + }; + + if (pattern == NULL) + return NULL; + for (int i = 0; typename_map[i] != NULL; i += 2) + { + if (pg_strcasecmp(pattern, typename_map[i]) == 0) + return typename_map[i + 1]; + } + return pattern; +} + /* * \do * Describe operators */ bool -describeOperators(const char *pattern, bool verbose, bool showSystem) +describeOperators(const char *oper_pattern, + char **arg_patterns, int num_arg_patterns, + bool verbose, bool showSystem) { PQExpBufferData buf; PGresult *res; @@ -994,6 +1104,10 @@ describeOperators(const char *pattern, bool verbose, bool showSystem) * anyway, for now, because (1) third-party modules may still be following * the old convention, and (2) we'd need to do it anyway when talking to a * pre-9.1 server. + * + * The support for postfix operators in this query is dead code as of + * Postgres 14, but we need to keep it for as long as we support talking + * to pre-v14 servers. */ printfPQExpBuffer(&buf, @@ -1020,14 +1134,66 @@ describeOperators(const char *pattern, bool verbose, bool showSystem) " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = o.oprnamespace\n", gettext_noop("Description")); - if (!showSystem && !pattern) + if (num_arg_patterns >= 2) + { + num_arg_patterns = 2; /* ignore any additional arguments */ + appendPQExpBufferStr(&buf, + " LEFT JOIN pg_catalog.pg_type t0 ON t0.oid = o.oprleft\n" + " LEFT JOIN pg_catalog.pg_namespace nt0 ON nt0.oid = t0.typnamespace\n" + " LEFT JOIN pg_catalog.pg_type t1 ON t1.oid = o.oprright\n" + " LEFT JOIN pg_catalog.pg_namespace nt1 ON nt1.oid = t1.typnamespace\n"); + } + else if (num_arg_patterns == 1) + { + appendPQExpBufferStr(&buf, + " LEFT JOIN pg_catalog.pg_type t0 ON t0.oid = o.oprright\n" + " LEFT JOIN pg_catalog.pg_namespace nt0 ON nt0.oid = t0.typnamespace\n"); + } + + if (!showSystem && !oper_pattern) appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n"); - processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern, true, + processSQLNamePattern(pset.db, &buf, oper_pattern, + !showSystem && !oper_pattern, true, "n.nspname", "o.oprname", NULL, "pg_catalog.pg_operator_is_visible(o.oid)"); + if (num_arg_patterns == 1) + appendPQExpBufferStr(&buf, " AND o.oprleft = 0\n"); + + for (int i = 0; i < num_arg_patterns; i++) + { + if (strcmp(arg_patterns[i], "-") != 0) + { + /* + * Match type-name patterns against either internal or external + * name, like \dT. Unlike \dT, there seems no reason to + * discriminate against arrays or composite types. + */ + char nspname[64]; + char typname[64]; + char ft[64]; + char tiv[64]; + + snprintf(nspname, sizeof(nspname), "nt%d.nspname", i); + snprintf(typname, sizeof(typname), "t%d.typname", i); + snprintf(ft, sizeof(ft), + "pg_catalog.format_type(t%d.oid, NULL)", i); + snprintf(tiv, sizeof(tiv), + "pg_catalog.pg_type_is_visible(t%d.oid)", i); + processSQLNamePattern(pset.db, &buf, + map_typename_pattern(arg_patterns[i]), + true, false, + nspname, typname, ft, tiv); + } + else + { + /* "-" pattern specifies no such parameter */ + appendPQExpBuffer(&buf, " AND t%d.typname IS NULL\n", i); + } + } + appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3, 4;"); res = PSQLexec(buf.data); @@ -1675,7 +1841,7 @@ describeOneTableDetails(const char *schemaname, bool printTableInitialized = false; int i; char *view_def = NULL; - char *headers[11]; + char *headers[12]; PQExpBufferData title; PQExpBufferData tmpbuf; int cols; @@ -1690,6 +1856,7 @@ describeOneTableDetails(const char *schemaname, indexdef_col = -1, fdwopts_col = -1, attstorage_col = -1, + attcompression_col = -1, attstattarget_col = -1, attdescr_col = -1; int attoptions_col = -1; @@ -2127,7 +2294,7 @@ describeOneTableDetails(const char *schemaname, { /* use "pretty" mode for expression to avoid excessive parentheses */ appendPQExpBufferStr(&buf, - ",\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) for 128)" + ",\n (SELECT pg_catalog.pg_get_expr(d.adbin, d.adrelid, true)" "\n FROM pg_catalog.pg_attrdef d" "\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)" ",\n a.attnotnull"); @@ -2177,6 +2344,17 @@ describeOneTableDetails(const char *schemaname, appendPQExpBufferStr(&buf, ",\n a.attstorage"); attstorage_col = cols++; + /* compression info, if relevant to relkind */ + if (pset.sversion >= 140000 && + !pset.hide_compression && + (tableinfo.relkind == RELKIND_RELATION || + tableinfo.relkind == RELKIND_PARTITIONED_TABLE || + tableinfo.relkind == RELKIND_MATVIEW)) + { + appendPQExpBufferStr(&buf, ",\n a.attcompression AS attcompression"); + attcompression_col = cols++; + } + /* stats target, if relevant to relkind */ if (tableinfo.relkind == RELKIND_RELATION || tableinfo.relkind == RELKIND_INDEX || @@ -2329,6 +2507,8 @@ describeOneTableDetails(const char *schemaname, headers[cols++] = gettext_noop("FDW options"); if (attstorage_col >= 0) headers[cols++] = gettext_noop("Storage"); + if (attcompression_col >= 0) + headers[cols++] = gettext_noop("Compression"); if (attstattarget_col >= 0) headers[cols++] = gettext_noop("Stats target"); @@ -2364,7 +2544,8 @@ describeOneTableDetails(const char *schemaname, { char *identity; char *generated; - char *default_str = ""; + char *default_str; + bool mustfree = false; printTableAddCell(&cont, PQgetvalue(res, i, attcoll_col), false, false); @@ -2380,12 +2561,15 @@ describeOneTableDetails(const char *schemaname, else if (identity[0] == ATTRIBUTE_IDENTITY_BY_DEFAULT) default_str = "generated by default as identity"; else if (generated[0] == ATTRIBUTE_GENERATED_STORED) - default_str = psprintf("generated always as (%s) stored", PQgetvalue(res, i, attrdef_col)); + { + default_str = psprintf("generated always as (%s) stored", + PQgetvalue(res, i, attrdef_col)); + mustfree = true; + } else - /* (note: above we cut off the 'default' string at 128) */ default_str = PQgetvalue(res, i, attrdef_col); - printTableAddCell(&cont, default_str, false, generated[0] ? true : false); + printTableAddCell(&cont, default_str, false, mustfree); } /* Info for index columns */ @@ -2398,7 +2582,7 @@ describeOneTableDetails(const char *schemaname, if (fdwopts_col >= 0) printTableAddCell(&cont, PQgetvalue(res, i, fdwopts_col), false, false); - /* Storage and Description */ + /* Storage mode, if relevant */ if (attstorage_col >= 0) { char *storage = PQgetvalue(res, i, attstorage_col); @@ -2413,6 +2597,19 @@ describeOneTableDetails(const char *schemaname, false, false); } + /* Column compression, if relevant */ + if (attcompression_col >= 0) + { + char *compression = PQgetvalue(res, i, attcompression_col); + + /* these strings are literal in our syntax, so not translated. */ + printTableAddCell(&cont, (compression[0] == 'p' ? "pglz" : + (compression[0] == 'l' ? "lz4" : + (compression[0] == '\0' ? "" : + "???"))), + false, false); + } + /* Statistics target, if the relkind supports this feature */ if (attstattarget_col >= 0) printTableAddCell(&cont, PQgetvalue(res, i, attstattarget_col), @@ -2482,7 +2679,12 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT inhparent::pg_catalog.regclass,\n" - " pg_catalog.pg_get_expr(c.relpartbound, c.oid)"); + " pg_catalog.pg_get_expr(c.relpartbound, c.oid),\n "); + + appendPQExpBuffer(&buf, + pset.sversion >= 140000 ? "inhdetachpending" : + "false as inhdetachpending"); + /* If verbose, also request the partition constraint definition */ if (verbose) appendPQExpBufferStr(&buf, @@ -2500,17 +2702,19 @@ describeOneTableDetails(const char *schemaname, { char *parent_name = PQgetvalue(result, 0, 0); char *partdef = PQgetvalue(result, 0, 1); + char *detached = PQgetvalue(result, 0, 2); - printfPQExpBuffer(&tmpbuf, _("Partition of: %s %s"), parent_name, - partdef); + printfPQExpBuffer(&tmpbuf, _("Partition of: %s %s%s"), parent_name, + partdef, + strcmp(detached, "t") == 0 ? " DETACH PENDING" : ""); printTableAddFooter(&cont, tmpbuf.data); if (verbose) { char *partconstraintdef = NULL; - if (!PQgetisnull(result, 0, 2)) - partconstraintdef = PQgetvalue(result, 0, 2); + if (!PQgetisnull(result, 0, 3)) + partconstraintdef = PQgetvalue(result, 0, 3); /* If there isn't any constraint, show that explicitly */ if (partconstraintdef == NULL || partconstraintdef[0] == '\0') printfPQExpBuffer(&tmpbuf, _("No partition constraint")); @@ -3068,7 +3272,104 @@ describeOneTableDetails(const char *schemaname, } /* print any extended statistics */ - if (pset.sversion >= 100000) + if (pset.sversion >= 140000) + { + printfPQExpBuffer(&buf, + "SELECT oid, " + "stxrelid::pg_catalog.regclass, " + "stxnamespace::pg_catalog.regnamespace AS nsp, " + "stxname,\n" + "pg_get_statisticsobjdef_columns(oid) AS columns,\n" + " 'd' = any(stxkind) AS ndist_enabled,\n" + " 'f' = any(stxkind) AS deps_enabled,\n" + " 'm' = any(stxkind) AS mcv_enabled,\n" + "stxstattarget\n" + "FROM pg_catalog.pg_statistic_ext stat\n" + "WHERE stxrelid = '%s'\n" + "ORDER BY 1;", + oid); + + result = PSQLexec(buf.data); + if (!result) + goto error_return; + else + tuples = PQntuples(result); + + if (tuples > 0) + { + printTableAddFooter(&cont, _("Statistics objects:")); + + for (i = 0; i < tuples; i++) + { + bool gotone = false; + bool has_ndistinct; + bool has_dependencies; + bool has_mcv; + bool has_all; + bool has_some; + + has_ndistinct = (strcmp(PQgetvalue(result, i, 5), "t") == 0); + has_dependencies = (strcmp(PQgetvalue(result, i, 6), "t") == 0); + has_mcv = (strcmp(PQgetvalue(result, i, 7), "t") == 0); + + printfPQExpBuffer(&buf, " "); + + /* statistics object name (qualified with namespace) */ + appendPQExpBuffer(&buf, "\"%s\".\"%s\"", + PQgetvalue(result, i, 2), + PQgetvalue(result, i, 3)); + + /* + * When printing kinds we ignore expression statistics, + * which is used only internally and can't be specified by + * user. We don't print the kinds when either none are + * specified (in which case it has to be statistics on a + * single expr) or when all are specified (in which case + * we assume it's expanded by CREATE STATISTICS). + */ + has_all = (has_ndistinct && has_dependencies && has_mcv); + has_some = (has_ndistinct || has_dependencies || has_mcv); + + if (has_some && !has_all) + { + appendPQExpBufferStr(&buf, " ("); + + /* options */ + if (has_ndistinct) + { + appendPQExpBufferStr(&buf, "ndistinct"); + gotone = true; + } + + if (has_dependencies) + { + appendPQExpBuffer(&buf, "%sdependencies", gotone ? ", " : ""); + gotone = true; + } + + if (has_mcv) + { + appendPQExpBuffer(&buf, "%smcv", gotone ? ", " : ""); + } + + appendPQExpBufferChar(&buf, ')'); + } + + appendPQExpBuffer(&buf, " ON %s FROM %s", + PQgetvalue(result, i, 4), + PQgetvalue(result, i, 1)); + + /* Show the stats target if it's not default */ + if (strcmp(PQgetvalue(result, i, 8), "-1") != 0) + appendPQExpBuffer(&buf, "; STATISTICS %s", + PQgetvalue(result, i, 8)); + + printTableAddFooter(&cont, buf.data); + } + } + PQclear(result); + } + else if (pset.sversion >= 100000) { printfPQExpBuffer(&buf, "SELECT oid, " @@ -3081,8 +3382,13 @@ describeOneTableDetails(const char *schemaname, " a.attnum = s.attnum AND NOT attisdropped)) AS columns,\n" " 'd' = any(stxkind) AS ndist_enabled,\n" " 'f' = any(stxkind) AS deps_enabled,\n" - " 'm' = any(stxkind) AS mcv_enabled\n" - "FROM pg_catalog.pg_statistic_ext stat " + " 'm' = any(stxkind) AS mcv_enabled,\n"); + + if (pset.sversion >= 130000) + appendPQExpBufferStr(&buf, " stxstattarget\n"); + else + appendPQExpBufferStr(&buf, " -1 AS stxstattarget\n"); + appendPQExpBuffer(&buf, "FROM pg_catalog.pg_statistic_ext stat\n" "WHERE stxrelid = '%s'\n" "ORDER BY 1;", oid); @@ -3130,6 +3436,11 @@ describeOneTableDetails(const char *schemaname, PQgetvalue(result, i, 4), PQgetvalue(result, i, 1)); + /* Show the stats target if it's not default */ + if (strcmp(PQgetvalue(result, i, 8), "-1") != 0) + appendPQExpBuffer(&buf, "; STATISTICS %s", + PQgetvalue(result, i, 8)); + printTableAddFooter(&cont, buf.data); } } @@ -3590,9 +3901,20 @@ describeOneTableDetails(const char *schemaname, } /* print child tables (with additional info if partitions) */ - if (pset.sversion >= 100000) + if (pset.sversion >= 140000) printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass, c.relkind," + " inhdetachpending," + " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n" + "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" + "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" + "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT'," + " c.oid::pg_catalog.regclass::pg_catalog.text;", + oid); + else if (pset.sversion >= 100000) + printfPQExpBuffer(&buf, + "SELECT c.oid::pg_catalog.regclass, c.relkind," + " false AS inhdetachpending," " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" @@ -3601,14 +3923,16 @@ describeOneTableDetails(const char *schemaname, oid); else if (pset.sversion >= 80300) printfPQExpBuffer(&buf, - "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n" + "SELECT c.oid::pg_catalog.regclass, c.relkind," + " false AS inhdetachpending, NULL\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", oid); else printfPQExpBuffer(&buf, - "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n" + "SELECT c.oid::pg_catalog.regclass, c.relkind," + " false AS inhdetachpending, NULL\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" "ORDER BY c.relname;", @@ -3658,11 +3982,13 @@ describeOneTableDetails(const char *schemaname, else printfPQExpBuffer(&buf, "%*s %s", ctw, "", PQgetvalue(result, i, 0)); - if (!PQgetisnull(result, i, 2)) - appendPQExpBuffer(&buf, " %s", PQgetvalue(result, i, 2)); + if (!PQgetisnull(result, i, 3)) + appendPQExpBuffer(&buf, " %s", PQgetvalue(result, i, 3)); if (child_relkind == RELKIND_PARTITIONED_TABLE || child_relkind == RELKIND_PARTITIONED_INDEX) appendPQExpBufferStr(&buf, ", PARTITIONED"); + if (strcmp(PQgetvalue(result, i, 2), "t") == 0) + appendPQExpBufferStr(&buf, " (DETACH PENDING)"); if (i < tuples - 1) appendPQExpBufferChar(&buf, ','); @@ -4433,6 +4759,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem) printTableAddHeader(&cont, gettext_noop("Role name"), true, align); printTableAddHeader(&cont, gettext_noop("Attributes"), true, align); + /* ignores implicit memberships from superuser & pg_database_owner */ printTableAddHeader(&cont, gettext_noop("Member of"), true, align); if (verbose && pset.sversion >= 80200) @@ -4636,7 +4963,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys PGresult *res; printQueryOpt myopt = pset.popt; int cols_so_far; - bool translate_columns[] = {false, false, true, false, false /* Storage */, false, false, false, false, false}; + bool translate_columns[] = {false, false, true, false, false, false, false, false, false}; /* If tabtypes is empty, we default to \dtvmsE (but see also command.c) */ if (!(showTables || showIndexes || showViews || showMatViews || showSeq || showForeign)) @@ -4666,6 +4993,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys " WHEN " CppAsString2(RELKIND_INDEX) " THEN '%s'" " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'" " WHEN 's' THEN '%s'" + " WHEN " CppAsString2(RELKIND_TOASTVALUE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'" @@ -4679,6 +5007,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys gettext_noop("index"), gettext_noop("sequence"), gettext_noop("special"), + gettext_noop("TOAST table"), gettext_noop("foreign table"), gettext_noop("partitioned table"), gettext_noop("partitioned index"), @@ -4739,6 +5068,16 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys * to; this might change with future additions to the output columns. */ + /* + * Access methods exist for tables, materialized views and indexes. + * This has been introduced in PostgreSQL 12 for tables. + */ + if (pset.sversion >= 120000 && !pset.hide_tableam && + (showTables || showMatViews || showIndexes)) + appendPQExpBuffer(&buf, + ",\n am.amname as \"%s\"", + gettext_noop("Access method")); + /* * As of PostgreSQL 9.0, use pg_table_size() to show a more accurate * size of a table, including FSM, VM and TOAST tables. @@ -4763,6 +5102,12 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys if (showTables && isGPDB7000OrLater()) appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_am a ON a.oid = c.relam"); + + if (pset.sversion >= 120000 && !pset.hide_tableam && + (showTables || showMatViews || showIndexes)) + appendPQExpBufferStr(&buf, + "\n LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam"); + if (showIndexes) appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid" @@ -4771,8 +5116,14 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN ("); if (showTables || (showExternal && isGPDB6000OrBelow())) + if (showTables) + { appendPQExpBufferStr(&buf, CppAsString2(RELKIND_RELATION) "," CppAsString2(RELKIND_PARTITIONED_TABLE) ","); + /* with 'S' or a pattern, allow 't' to match TOAST tables too */ + if (showSystem || pattern) + appendPQExpBufferStr(&buf, CppAsString2(RELKIND_TOASTVALUE) ","); + } if (showViews) appendPQExpBufferStr(&buf, CppAsString2(RELKIND_VIEW) ","); if (showMatViews) @@ -4812,6 +5163,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys if (!showSystem && !pattern) appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" + " AND n.nspname !~ '^pg_toast'\n" " AND n.nspname <> 'information_schema'\n"); /* @@ -5038,17 +5390,9 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) if (!pattern) appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" + " AND n.nspname !~ '^pg_toast'\n" " AND n.nspname <> 'information_schema'\n"); - /* - * TOAST objects are suppressed unconditionally. Since we don't provide - * any way to select RELKIND_TOASTVALUE above, we would never show toast - * tables in any case; it seems a bit confusing to allow their indexes to - * be shown. Use plain \d if you really need to look at a TOAST - * table/index. - */ - appendPQExpBufferStr(&buf, " AND n.nspname !~ '^pg_toast'\n"); - processSQLNamePattern(pset.db, &buf, pattern, true, false, "n.nspname", "c.relname", NULL, "pg_catalog.pg_table_is_visible(c.oid)"); @@ -5382,6 +5726,98 @@ listEventTriggers(const char *pattern, bool verbose) return true; } +/* + * \dX + * + * Describes extended statistics. + */ +bool +listExtendedStats(const char *pattern) +{ + PQExpBufferData buf; + PGresult *res; + printQueryOpt myopt = pset.popt; + + if (pset.sversion < 100000) + { + char sverbuf[32]; + + pg_log_error("The server (version %s) does not support extended statistics.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); + return true; + } + + initPQExpBuffer(&buf); + printfPQExpBuffer(&buf, + "SELECT \n" + "es.stxnamespace::pg_catalog.regnamespace::text AS \"%s\", \n" + "es.stxname AS \"%s\", \n", + gettext_noop("Schema"), + gettext_noop("Name")); + + if (pset.sversion >= 140000) + appendPQExpBuffer(&buf, + "pg_catalog.format('%%s FROM %%s', \n" + " pg_get_statisticsobjdef_columns(es.oid), \n" + " es.stxrelid::regclass) AS \"%s\"", + gettext_noop("Definition")); + else + appendPQExpBuffer(&buf, + "pg_catalog.format('%%s FROM %%s', \n" + " (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(a.attname),', ') \n" + " FROM pg_catalog.unnest(es.stxkeys) s(attnum) \n" + " JOIN pg_catalog.pg_attribute a \n" + " ON (es.stxrelid = a.attrelid \n" + " AND a.attnum = s.attnum \n" + " AND NOT a.attisdropped)), \n" + "es.stxrelid::regclass) AS \"%s\"", + gettext_noop("Definition")); + + appendPQExpBuffer(&buf, + ",\nCASE WHEN 'd' = any(es.stxkind) THEN 'defined' \n" + "END AS \"%s\", \n" + "CASE WHEN 'f' = any(es.stxkind) THEN 'defined' \n" + "END AS \"%s\"", + gettext_noop("Ndistinct"), + gettext_noop("Dependencies")); + + /* + * Include the MCV statistics kind. + */ + if (pset.sversion >= 120000) + { + appendPQExpBuffer(&buf, + ",\nCASE WHEN 'm' = any(es.stxkind) THEN 'defined' \n" + "END AS \"%s\" ", + gettext_noop("MCV")); + } + + appendPQExpBufferStr(&buf, + " \nFROM pg_catalog.pg_statistic_ext es \n"); + + processSQLNamePattern(pset.db, &buf, pattern, + false, false, + "es.stxnamespace::pg_catalog.regnamespace::text", "es.stxname", + NULL, NULL); + + appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); + + res = PSQLexec(buf.data); + termPQExpBuffer(&buf); + if (!res) + return false; + + myopt.nullPrint = NULL; + myopt.title = _("List of extended statistics"); + myopt.translate_header = true; + + printQuery(res, &myopt, pset.queryFout, false, pset.logfile); + + PQclear(res); + return true; +} + /* * \dC * @@ -6993,7 +7429,7 @@ describeSubscriptions(const char *pattern, bool verbose) PGresult *res; printQueryOpt myopt = pset.popt; static const bool translate_columns[] = {false, false, false, false, - false, false, false}; + false, false, false, false}; if (pset.sversion < 100000) { @@ -7019,11 +7455,13 @@ describeSubscriptions(const char *pattern, bool verbose) if (verbose) { - /* Binary mode is only supported in v14 and higher */ + /* Binary mode and streaming are only supported in v14 and higher */ if (pset.sversion >= 140000) appendPQExpBuffer(&buf, - ", subbinary AS \"%s\"\n", - gettext_noop("Binary")); + ", subbinary AS \"%s\"\n" + ", substream AS \"%s\"\n", + gettext_noop("Binary"), + gettext_noop("Streaming")); appendPQExpBuffer(&buf, ", subsynccommit AS \"%s\"\n" @@ -7135,17 +7573,16 @@ listOperatorClasses(const char *access_method_pattern, " pg_catalog.pg_get_userbyid(c.opcowner) AS \"%s\"\n", gettext_noop("Operator family"), gettext_noop("Owner")); - appendPQExpBuffer(&buf, - "\nFROM pg_catalog.pg_opclass c\n" - " LEFT JOIN pg_catalog.pg_am am on am.oid = c.opcmethod\n" - " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n" - " LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n" - " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n" - ); + appendPQExpBufferStr(&buf, + "\nFROM pg_catalog.pg_opclass c\n" + " LEFT JOIN pg_catalog.pg_am am on am.oid = c.opcmethod\n" + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n" + " LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n" + " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n"); if (verbose) - appendPQExpBuffer(&buf, - " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n" - " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n"); + appendPQExpBufferStr(&buf, + " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n" + " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n"); if (access_method_pattern) have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, @@ -7214,11 +7651,10 @@ listOperatorFamilies(const char *access_method_pattern, appendPQExpBuffer(&buf, ",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n", gettext_noop("Owner")); - appendPQExpBuffer(&buf, - "\nFROM pg_catalog.pg_opfamily f\n" - " LEFT JOIN pg_catalog.pg_am am on am.oid = f.opfmethod\n" - " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n" - ); + appendPQExpBufferStr(&buf, + "\nFROM pg_catalog.pg_opfamily f\n" + " LEFT JOIN pg_catalog.pg_am am on am.oid = f.opfmethod\n" + " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n"); if (access_method_pattern) have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, @@ -7238,7 +7674,7 @@ listOperatorFamilies(const char *access_method_pattern, "tn.nspname", "t.typname", "pg_catalog.format_type(t.oid, NULL)", "pg_catalog.pg_type_is_visible(t.oid)"); - appendPQExpBuffer(&buf, " )\n"); + appendPQExpBufferStr(&buf, " )\n"); } appendPQExpBufferStr(&buf, "ORDER BY 1, 2;"); @@ -7305,14 +7741,14 @@ listOpFamilyOperators(const char *access_method_pattern, appendPQExpBuffer(&buf, ", ofs.opfname AS \"%s\"\n", gettext_noop("Sort opfamily")); - appendPQExpBuffer(&buf, - "FROM pg_catalog.pg_amop o\n" - " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n" - " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n" - " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n"); + appendPQExpBufferStr(&buf, + "FROM pg_catalog.pg_amop o\n" + " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n" + " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n" + " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n"); if (verbose) - appendPQExpBuffer(&buf, - " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n"); + appendPQExpBufferStr(&buf, + " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n"); if (access_method_pattern) have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, @@ -7391,12 +7827,12 @@ listOpFamilyFunctions(const char *access_method_pattern, ", ap.amproc::pg_catalog.regprocedure AS \"%s\"\n", gettext_noop("Function")); - appendPQExpBuffer(&buf, - "FROM pg_catalog.pg_amproc ap\n" - " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n" - " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n" - " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n" - " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n"); + appendPQExpBufferStr(&buf, + "FROM pg_catalog.pg_amproc ap\n" + " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n" + " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n" + " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n" + " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n"); if (access_method_pattern) have_where = processSQLNamePattern(pset.db, &buf, access_method_pattern, diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index 1d216319d7e9..a8fb280cb50b 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/describe.h */ @@ -19,13 +19,17 @@ extern bool describeAccessMethods(const char *pattern, bool verbose); extern bool describeTablespaces(const char *pattern, bool verbose); /* \df, \dfa, \dfn, \dft, \dfw, etc. */ -extern bool describeFunctions(const char *functypes, const char *pattern, bool verbose, bool showSystem); +extern bool describeFunctions(const char *functypes, const char *func_pattern, + char **arg_patterns, int num_arg_patterns, + bool verbose, bool showSystem); /* \dT */ extern bool describeTypes(const char *pattern, bool verbose, bool showSystem); /* \do */ -extern bool describeOperators(const char *pattern, bool verbose, bool showSystem); +extern bool describeOperators(const char *oper_pattern, + char **arg_patterns, int num_arg_patterns, + bool verbose, bool showSystem); /* \du, \dg */ extern bool describeRoles(const char *pattern, bool verbose, bool showSystem); @@ -114,6 +118,9 @@ extern bool listExtensions(const char *pattern); /* \dx+ */ extern bool listExtensionContents(const char *pattern); +/* \dX */ +extern bool listExtendedStats(const char *pattern); + /* \dy */ extern bool listEventTriggers(const char *pattern, bool verbose); diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 9b237d9d64c1..efa2f256c058 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/help.c */ @@ -134,10 +134,7 @@ usage(unsigned short int pager) fprintf(output, _(" -p, --port=PORT database server port (default: \"%s\")\n"), env ? env : DEF_PGPORT_STR); /* Display default user */ - env = getenv("PGUSER"); - if (!env) - env = user; - fprintf(output, _(" -U, --username=USERNAME database user name (default: \"%s\")\n"), env); + fprintf(output, _(" -U, --username=USERNAME database user name (default: \"%s\")\n"), user); fprintf(output, _(" -w, --no-password never prompt for password\n")); fprintf(output, _(" -W, --password force password prompt (should happen automatically)\n")); @@ -171,7 +168,7 @@ slashUsage(unsigned short int pager) * Use "psql --help=commands | wc" to count correctly. It's okay to count * the USE_READLINE line even in builds without that. */ - output = PageOutput(133, pager ? &(pset.popt.topt) : NULL); + output = PageOutput(135, pager ? &(pset.popt.topt) : NULL); fprintf(output, _("General\n")); fprintf(output, _(" \\copyright show PostgreSQL usage and distribution terms\n")); @@ -233,7 +230,7 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n")); fprintf(output, _(" \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n")); fprintf(output, _(" \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n")); - fprintf(output, _(" \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n")); + fprintf(output, _(" \\dAp[+] [AMPTRN [OPFPTRN]] list support functions of operator families\n")); fprintf(output, _(" \\db[+] [PATTERN] list tablespaces\n")); fprintf(output, _(" \\dc[S+] [PATTERN] list conversions\n")); fprintf(output, _(" \\dC[+] [PATTERN] list casts\n")); @@ -245,7 +242,8 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\des[+] [PATTERN] list foreign servers\n")); fprintf(output, _(" \\deu[+] [PATTERN] list user mappings\n")); fprintf(output, _(" \\dew[+] [PATTERN] list foreign-data wrappers\n")); - fprintf(output, _(" \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n")); + fprintf(output, _(" \\df[anptw][S+] [FUNCPTRN [TYPEPTRN ...]]\n" + " list [only agg/normal/procedure/trigger/window] functions\n")); fprintf(output, _(" \\dF[+] [PATTERN] list text search configurations\n")); fprintf(output, _(" \\dFd[+] [PATTERN] list text search dictionaries\n")); fprintf(output, _(" \\dFp[+] [PATTERN] list text search parsers\n")); @@ -256,7 +254,8 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\dL[S+] [PATTERN] list procedural languages\n")); fprintf(output, _(" \\dm[S+] [PATTERN] list materialized views\n")); fprintf(output, _(" \\dn[S+] [PATTERN] list schemas\n")); - fprintf(output, _(" \\do[S] [PATTERN] list operators\n")); + fprintf(output, _(" \\do[S+] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" + " list operators\n")); fprintf(output, _(" \\dO[S+] [PATTERN] list collations\n")); fprintf(output, _(" \\dp [PATTERN] list table, view, and sequence access privileges\n")); fprintf(output, _(" \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n")); @@ -271,7 +270,8 @@ slashUsage(unsigned short int pager) /* In GPDB, we use \dE for both external and foreign tables. */ fprintf(output, _(" \\dE[S+] [PATTERN] list foreign and external tables\n")); fprintf(output, _(" \\dx[+] [PATTERN] list extensions\n")); - fprintf(output, _(" \\dy [PATTERN] list event triggers\n")); + fprintf(output, _(" \\dX [PATTERN] list extended statistics\n")); + fprintf(output, _(" \\dy[+] [PATTERN] list event triggers\n")); fprintf(output, _(" \\l[+] [PATTERN] list databases\n")); fprintf(output, _(" \\sf[+] FUNCNAME show a function's definition\n")); fprintf(output, _(" \\sv[+] VIEWNAME show a view's definition\n")); @@ -380,6 +380,8 @@ helpVariables(unsigned short int pager) " the number of result rows to fetch and display at a time (0 = unlimited)\n")); fprintf(output, _(" HIDE_TABLEAM\n" " if set, table access methods are not displayed\n")); + fprintf(output, _(" HIDE_TOAST_COMPRESSION\n" + " if set, compression methods are not displayed\n")); fprintf(output, _(" HISTCONTROL\n" " controls command history [ignorespace, ignoredups, ignoreboth]\n")); fprintf(output, _(" HISTFILE\n" @@ -491,10 +493,10 @@ helpVariables(unsigned short int pager) " same as the dbname connection parameter\n")); fprintf(output, _(" PGHOST\n" " same as the host connection parameter\n")); - fprintf(output, _(" PGPASSWORD\n" - " connection password (not recommended)\n")); fprintf(output, _(" PGPASSFILE\n" " password file name\n")); + fprintf(output, _(" PGPASSWORD\n" + " connection password (not recommended)\n")); fprintf(output, _(" PGPORT\n" " same as the port connection parameter\n")); fprintf(output, _(" PGUSER\n" @@ -538,6 +540,7 @@ helpSQL(const char *topic, unsigned short int pager) int i; int j; + /* Find screen width to determine how many columns will fit */ #ifdef TIOCGWINSZ struct winsize screen_size; @@ -575,56 +578,63 @@ helpSQL(const char *topic, unsigned short int pager) else { int i, - j, - x = 0; - bool help_found = false; + pass; FILE *output = NULL; size_t len, - wordlen; - int nl_count = 0; + wordlen, + j; + int nl_count; /* + * len is the amount of the input to compare to the help topic names. * We first try exact match, then first + second words, then first * word only. */ len = strlen(topic); - for (x = 1; x <= 3; x++) + for (pass = 1; pass <= 3; pass++) { - if (x > 1) /* Nothing on first pass - try the opening + if (pass > 1) /* Nothing on first pass - try the opening * word(s) */ { wordlen = j = 1; - while (topic[j] != ' ' && j++ < len) + while (j < len && topic[j++] != ' ') wordlen++; - if (x == 2) + if (pass == 2 && j < len) { - j++; - while (topic[j] != ' ' && j++ <= len) + wordlen++; + while (j < len && topic[j++] != ' ') wordlen++; } - if (wordlen >= len) /* Don't try again if the same word */ + if (wordlen >= len) { - if (!output) - output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL); - break; + /* Failed to shorten input, so try next pass if any */ + continue; } len = wordlen; } - /* Count newlines for pager */ + /* + * Count newlines for pager. This logic must agree with what the + * following loop will do! + */ + nl_count = 0; for (i = 0; QL_HELP[i].cmd; i++) { if (pg_strncasecmp(topic, QL_HELP[i].cmd, len) == 0 || strcmp(topic, "*") == 0) { - nl_count += 5 + QL_HELP[i].nl_count; + /* magic constant here must match format below! */ + nl_count += 7 + QL_HELP[i].nl_count; /* If we have an exact match, exit. Fixes \h SELECT */ if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0) break; } } + /* If no matches, don't open the output yet */ + if (nl_count == 0) + continue; if (!output) output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL); @@ -639,10 +649,10 @@ helpSQL(const char *topic, unsigned short int pager) initPQExpBuffer(&buffer); QL_HELP[i].syntaxfunc(&buffer); - help_found = true; url = psprintf("https://www.postgresql.org/docs/%s/%s.html", strstr(PG_VERSION, "devel") ? "devel" : PG_MAJORVERSION, QL_HELP[i].docbook_id); + /* # of newlines in format must match constant above! */ fprintf(output, _("Command: %s\n" "Description: %s\n" "Syntax:\n%s\n\n" @@ -652,17 +662,24 @@ helpSQL(const char *topic, unsigned short int pager) buffer.data, url); free(url); + termPQExpBuffer(&buffer); + /* If we have an exact match, exit. Fixes \h SELECT */ if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0) break; } } - if (help_found) /* Don't keep trying if we got a match */ - break; + break; } - if (!help_found) - fprintf(output, _("No help available for \"%s\".\nTry \\h with no arguments to see available help.\n"), topic); + /* If we never found anything, report that */ + if (!output) + { + output = PageOutput(2, pager ? &(pset.popt.topt) : NULL); + fprintf(output, _("No help available for \"%s\".\n" + "Try \\h with no arguments to see available help.\n"), + topic); + } ClosePager(output); } diff --git a/src/bin/psql/help.h b/src/bin/psql/help.h index 2e2666d3d0e8..d4f91e0be2bf 100644 --- a/src/bin/psql/help.h +++ b/src/bin/psql/help.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/help.h */ diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index ba469798be30..88c28b5a8b91 100644 --- a/src/bin/psql/input.c +++ b/src/bin/psql/input.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/input.c */ diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h index cfa03f59ea73..1a5a1be999e1 100644 --- a/src/bin/psql/input.h +++ b/src/bin/psql/input.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/input.h */ diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c index cae81c0f1522..c15fcc08851d 100644 --- a/src/bin/psql/large_obj.c +++ b/src/bin/psql/large_obj.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/large_obj.c */ diff --git a/src/bin/psql/large_obj.h b/src/bin/psql/large_obj.h index 755b9e70f0df..003acbf52c9d 100644 --- a/src/bin/psql/large_obj.h +++ b/src/bin/psql/large_obj.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/large_obj.h */ diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index 7abe016e4038..e49ed022938b 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/mainloop.c */ diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h index d9680d45b18d..dd7a1889dee4 100644 --- a/src/bin/psql/mainloop.h +++ b/src/bin/psql/mainloop.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/mainloop.h */ diff --git a/src/bin/psql/nls.mk b/src/bin/psql/nls.mk index dd4d482590fa..5da216f8f6d5 100644 --- a/src/bin/psql/nls.mk +++ b/src/bin/psql/nls.mk @@ -1,6 +1,6 @@ # src/bin/psql/nls.mk CATALOG_NAME = psql -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr uk zh_CN zh_TW +AVAIL_LANGUAGES = cs de el es fr he it ja ko pl pt_BR ru sv tr uk zh_CN zh_TW GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ command.c common.c copy.c crosstabview.c help.c input.c large_obj.c \ mainloop.c psqlscanslash.c startup.c \ diff --git a/src/bin/psql/po/cs.po b/src/bin/psql/po/cs.po new file mode 100644 index 000000000000..45771e129d9b --- /dev/null +++ b/src/bin/psql/po/cs.po @@ -0,0 +1,6603 @@ +# Czech translation of psql +# +# pgtranslation Id: psql.po,v 1.6 2011/09/08 18:23:06 petere Exp $ +# Karel Žák, 2001-2003, 2004. +# Zdeněk Kotala, 2009, 2011, 2012, 2013. +# Tomáš Vondra , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: psql-cs (PostgreSQL 9.3)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-31 16:14+0000\n" +"PO-Revision-Date: 2020-11-01 00:59+0100\n" +"Last-Translator: Tomas Vondra \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.4.1\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "warning: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "nelze získat aktuální adresář: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "neplatný binární soubor\"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "nelze číst binární soubor \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "nelze najít příkaz \"%s\" ke spuštění" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "nelze změnit adresář na \"%s\" : %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "nelze přečíst symbolický odkaz \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "volání pclose selhalo: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: command.c:1255 command.c:3146 command.c:3195 command.c:3307 input.c:227 +#: mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "nedostatek paměti" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek paměti\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nelze duplikovat null pointer (interní chyba)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "nelze načíst efektivní user ID \"%ld\": %s" + +#: ../../common/username.c:45 command.c:559 +msgid "user does not exist" +msgstr "uživatel neexistuje" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "vyhledávání uživatele selhalo: chybový kód %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "příkaz není spustitelný" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "příkaz nenalezen" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "potomek skončil s návratovým kódem %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "potomek byl ukončen výjimkou 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "potomek byl ukončen signálem %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "potomek skončil s nerozponaným stavem %d" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Požadavek na zrušení byl poslán\n" + +#: ../../fe_utils/cancel.c:165 +msgid "Could not send cancel request: " +msgstr "Nelze poslat požadavek na zrušení: " + +#: ../../fe_utils/cancel.c:210 +#, c-format +msgid "Could not send cancel request: %s" +msgstr "Nelze poslat požadavek na zrušení: %s" + +#: ../../fe_utils/print.c:350 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu řádka)" +msgstr[1] "(%lu řádky)" +msgstr[2] "(%lu řádek)" + +#: ../../fe_utils/print.c:3055 +#, c-format +msgid "Interrupted\n" +msgstr "Přerušeno\n" + +#: ../../fe_utils/print.c:3119 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "Nelze přidat hlavičku k obsahu tabulky: překročen počet sloupců %d.\n" + +#: ../../fe_utils/print.c:3159 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "Nelze přidat buňku do obsahu tabulky: překročen celkový počet buněk %d.\n" + +#: ../../fe_utils/print.c:3414 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "specifikován neplatný formát výstupu (interní chyba): %d" + +#: ../../fe_utils/psqlscan.l:694 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "přeskakuji rekursivní expanzi proměnné \"%s\"" + +#: command.c:224 +#, c-format +msgid "invalid command \\%s" +msgstr "neplatný příkaz \\%s" + +#: command.c:226 +#, c-format +msgid "Try \\? for help." +msgstr "Zkuste \\? pro zobrazení nápovědy." + +#: command.c:244 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: nadbytečný argument \"%s\" ignorován" + +#: command.c:296 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "\\%s příkaz ignorován; použijte \\endif nebo Ctrl-C pro ukončení aktuálního \\if bloku" + +#: command.c:557 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "nelze získat domácí adresář pro uživatele ID %ld: %s" + +#: command.c:575 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: nelze změnit adresář na \"%s\": %m" + +#: command.c:600 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "Aktuálně nejste připojeni k databázi.\n" + +#: command.c:613 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Nyní jste připojeni k databázi \"%s\" jako uživatel \"%s\" na adrese \"%s\" na portu\"%s\".\n" + +#: command.c:616 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Jste připojeni k databázi \"%s\" jako uživatel \"%s\" přes socket v \"%s\" naportu \"%s\".\n" + +#: command.c:622 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Nyní jste připojeni k databázi \"%s\" jako uživatel \"%s\" na serveru \"%s\" (adresa \"%s\") na portu\"%s\".\n" + +#: command.c:625 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Nyní jste připojeni k databázi \"%s\" jako uživatel \"%s\" na serveru \"%s\" na portu\"%s\".\n" + +#: command.c:965 command.c:1061 command.c:2550 +#, c-format +msgid "no query buffer" +msgstr "v historii není žádný dotaz" + +#: command.c:998 command.c:5139 +#, c-format +msgid "invalid line number: %s" +msgstr "neplatné číslo řádky: %s" + +#: command.c:1052 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "Server (verze %s) nepodporuje editaci zdrojového kódu funkce." + +#: command.c:1055 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "Server (verze %s) nepodporuje editaci definice pohledu." + +#: command.c:1137 +msgid "No changes" +msgstr "Žádné změny" + +#: command.c:1216 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: neplatné jméno kódování nebo nenalezena konverzní funkce" + +#: command.c:1251 command.c:1992 command.c:3142 command.c:3329 command.c:5241 +#: common.c:174 common.c:223 common.c:388 common.c:1237 common.c:1265 +#: common.c:1373 common.c:1480 common.c:1518 copy.c:488 copy.c:707 help.c:62 +#: large_obj.c:157 large_obj.c:192 large_obj.c:254 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1258 +msgid "There is no previous error." +msgstr "Žádná předchozí chyba." + +#: command.c:1371 +#, c-format +#| msgid "Missing left parenthesis." +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: chybějící pravá závorka" + +#: command.c:1548 command.c:1853 command.c:1867 command.c:1884 command.c:2044 +#: command.c:2281 command.c:2517 command.c:2557 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s: chybí požadovaný argument" + +#: command.c:1679 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: nemůže být zadáno po \\else" + +#: command.c:1684 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif: žádné odpovídající \\if" + +#: command.c:1748 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else: nemůže být zadáno po \\else" + +#: command.c:1753 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else: žádné odpovídající \\if" + +#: command.c:1793 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif: žádné odpovídající \\if" + +#: command.c:1948 +msgid "Query buffer is empty." +msgstr "Buffer dotazů je prázdný." + +#: command.c:1970 +msgid "Enter new password: " +msgstr "Zadejte nové heslo: " + +#: command.c:1971 +msgid "Enter it again: " +msgstr "Zadejte znova: " + +#: command.c:1975 +#, c-format +msgid "Passwords didn't match." +msgstr "Hesla se neshodují." + +#: command.c:2074 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s: nelze načíst hodnotu proměnné" + +#: command.c:2177 +msgid "Query buffer reset (cleared)." +msgstr "Buffer dotazů vyprázdněn." + +#: command.c:2199 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "Historie zapsána do souboru: \"%s\".\n" + +#: command.c:2286 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: název proměnné prostředí nesmí obsahovat \"=\"" + +#: command.c:2347 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "Server (verze %s) nepodporuje zobrazování zdrojového kódu funkce." + +#: command.c:2350 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "Server (verze %s) nepodporuje zobrazování definice pohledu." + +#: command.c:2357 +#, c-format +msgid "function name is required" +msgstr "function name is required" + +#: command.c:2359 +#, c-format +msgid "view name is required" +msgstr "je vyžadováno jméno pohledu" + +#: command.c:2489 +msgid "Timing is on." +msgstr "Sledování času je zapnuto." + +#: command.c:2491 +msgid "Timing is off." +msgstr "Sledování času je vypnuto." + +#: command.c:2576 command.c:2604 command.c:3739 command.c:3742 command.c:3745 +#: command.c:3751 command.c:3753 command.c:3761 command.c:3771 command.c:3780 +#: command.c:3794 command.c:3811 command.c:3869 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:2988 startup.c:236 startup.c:287 +msgid "Password: " +msgstr "Heslo: " + +#: command.c:2993 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "Heslo pro uživatele %s: " + +#: command.c:3046 +#, c-format +msgid "All connection parameters must be supplied because no database connection exists" +msgstr "Všechny parametry musí být zadány protože žádné připojení k databázi neexistuje" + +#: command.c:3335 +#, c-format +msgid "Previous connection kept" +msgstr "Předchozí spojení zachováno" + +#: command.c:3341 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3388 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Nyní jste připojeni k databázi \"%s\" jako uživatel \"%s\" na adrese \"%s\" na portu\"%s\".\n" + +#: command.c:3391 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" + +#: command.c:3397 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Nyní jste připojeni k databázi \"%s\" jako uživatel \"%s\" na serveru \"%s\" (adresa \"%s\") na portu\"%s\".\n" + +#: command.c:3400 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Nyní jste připojeni k databázi \"%s\" jako uživatel \"%s\" na serveru \"%s\" na portu\"%s\".\n" + +#: command.c:3405 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Nyní jste připojeni k databázi \"%s\" jako uživatel \"%s\".\n" + +#: command.c:3438 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, server %s)\n" + +#: command.c:3446 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"VAROVÁNÍ: %s major verze %s, major verze serveru %s.\n" +" Některé vlastnosti psql nemusí fungovat.\n" + +#: command.c:3485 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL spojení (protokol: %s, šifra: %s, bitů: %s, komprese: %s)\n" + +#: command.c:3486 command.c:3487 command.c:3488 +msgid "unknown" +msgstr "neznámé" + +#: command.c:3489 help.c:45 +msgid "off" +msgstr "vypnuto" + +#: command.c:3489 help.c:45 +msgid "on" +msgstr "zapnuto" + +#: command.c:3503 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "GSSAPI-šifrované spojení\n" + +#: command.c:3523 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"VAROVÁNÍ: Kódová stránka konzole (%u) není shodná s kódovou stránkou\n" +" Windows (%u) 8-bitové znaky nemusí fungovat správně. Další\n" +" informace najdete v manuálu k psql na stránce \"Poznámky pro\n" +" uživatele Windows.\"\n" + +#: command.c:3627 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "proměnná prostředí PSQL_EDITOR_LINENUMBER_ARG musí být nastavena pro zadáníčísla řádky" + +#: command.c:3656 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "nelze spustit editor \"%s\"" + +#: command.c:3658 +#, c-format +msgid "could not start /bin/sh" +msgstr "nelze spustit /bin/sh" + +#: command.c:3696 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "nelze najít dočasný adresář: %s" + +#: command.c:3723 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "nelze otevřít dočasný soubor \"%s\": %m" + +#: command.c:4028 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: nejednoznačná zkratka \"%s\" odpovídá \"%s\" a \"%s\"" + +#: command.c:4048 +#, c-format +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: dovolené formáty jsou aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" + +#: command.c:4067 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: povolené styly řádek jsou ascii, old-ascii, unicode" + +#: command.c:4082 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: povolené styly Unicode rámečků jsou single, double" + +#: command.c:4097 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: povolené styly Unicode sloupců jsou single, double" + +#: command.c:4112 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: povolené styly Unicode rámečků záhlaví single, double" + +#: command.c:4155 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep musí být jediný jedno-bytový znak" + +#: command.c:4160 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldsep nemůže být dvojitá uvozovka, nový řádek, nebo konec řádky" + +#: command.c:4297 command.c:4485 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset: neznámá volba: %s" + +#: command.c:4317 +#, c-format +msgid "Border style is %d.\n" +msgstr "Styl rámečků je %d.\n" + +#: command.c:4323 +#, c-format +msgid "Target width is unset.\n" +msgstr "Cílová šířka není nastavena.\n" + +#: command.c:4325 +#, c-format +msgid "Target width is %d.\n" +msgstr "Cílová šířka je %d.\n" + +#: command.c:4332 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Rozšířené zobrazení zapnuto.\n" + +#: command.c:4334 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "Rozšířené zobrazení je zapnuto automaticky.\n" + +#: command.c:4336 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Rozšířené zobrazení vypnuto.\n" + +#: command.c:4342 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "Oddělovač polí pro CSV je '\"%s\"'.\n" + +#: command.c:4350 command.c:4358 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "Oddělovač polí je nulový byte.\n" + +#: command.c:4352 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "Oddělovač polí je '\"%s\"'.\n" + +#: command.c:4365 +#, c-format +msgid "Default footer is on.\n" +msgstr "Implicitní zápatí je zapnuto.\n" + +#: command.c:4367 +#, c-format +msgid "Default footer is off.\n" +msgstr "Implicitní zápatí je vypnuto.\n" + +#: command.c:4373 +#, c-format +msgid "Output format is %s.\n" +msgstr "Výstupní formát je %s.\n" + +#: command.c:4379 +#, c-format +msgid "Line style is %s.\n" +msgstr "Styl čar je %s.\n" + +#: command.c:4386 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Null je zobrazován jako '\"%s\"'.\n" + +#: command.c:4394 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "Zobrazení číselného výstupu dle národního nastavení je vypnuto.\n" + +#: command.c:4396 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "Zobrazení číselného výstupu dle národního nastavení je vypnuto.\n" + +#: command.c:4403 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Stránkování je zapnuto pro dlouhé výstupy.\n" + +#: command.c:4405 +#, c-format +msgid "Pager is always used.\n" +msgstr "Stránkování je vždy použito.\n" + +#: command.c:4407 +#, c-format +msgid "Pager usage is off.\n" +msgstr "Stránkování je vypnuto.\n" + +#: command.c:4413 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "Pager nebude použit pro méně než %d řáden.\n" +msgstr[1] "Pager won't be used for less than %d lines.\n" +msgstr[2] "Pager won't be used for less than %d lines.\n" + +#: command.c:4423 command.c:4433 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "Oddělovač záznamů je nulový byte.\n" + +#: command.c:4425 +#, c-format +msgid "Record separator is .\n" +msgstr "Oddělovač záznamů je .\n" + +#: command.c:4427 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "Oddělovač záznamů je '\"%s\"'.\n" + +#: command.c:4440 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Atributy tabulky jsou \"%s\".\n" + +#: command.c:4443 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Atributy tabulky nejsou nastaveny.\n" + +#: command.c:4450 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "Nadpis je \"%s\".\n" + +#: command.c:4452 +#, c-format +msgid "Title is unset.\n" +msgstr "Nadpis není nastaven.\n" + +#: command.c:4459 +#, c-format +msgid "Tuples only is on.\n" +msgstr "Zobrazování pouze záznamů je vypnuto.\n" + +#: command.c:4461 +#, c-format +msgid "Tuples only is off.\n" +msgstr "Zobrazování pouze záznamů je vypnuto.\n" + +#: command.c:4467 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Styl Unicode rámečků je \"%s\".\n" + +#: command.c:4473 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Styl Unicode sloupců je \"%s\".\n" + +#: command.c:4479 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Styl Unicode rámečků záhlaví je \"%s\".\n" + +#: command.c:4712 +#, c-format +msgid "\\!: failed" +msgstr "\\!: selhal" + +#: command.c:4737 common.c:648 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch neze použít s prázdným dotazem" + +#: command.c:4778 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (každé %gs)\n" + +#: command.c:4781 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (každé %gs)\n" + +#: command.c:4835 command.c:4842 common.c:548 common.c:555 common.c:1220 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********* DOTAZ **********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:5034 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "\"%s.%s\" není pohled" + +#: command.c:5050 +#, c-format +msgid "could not parse reloptions array" +msgstr "nelze naparsovat pole reloptions" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "nelze escapovat bez aktivního spojení" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "argument shell příkazu obsahuje přechod na nový řádek nebo návrat na začátek (carriage return): \"%s\"" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "spojení na server bylo ztraceno" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "Spojení na server bylo ztraceno. Zkoušen restart: " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "Nepodařilo se.\n" + +#: common.c:326 +#, c-format +msgid "Succeeded.\n" +msgstr "Podařilo se.\n" + +#: common.c:378 common.c:938 common.c:1155 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "neočekávaný PQresultStatus: %d" + +#: common.c:487 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Čas: %.3f ms\n" + +#: common.c:502 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Čas: %.3f ms (%02d:%06.3f)\n" + +#: common.c:511 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Čas: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:518 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Čas: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:542 common.c:600 common.c:1191 +#, c-format +msgid "You are currently not connected to a database." +msgstr "Aktuálně nejste připojeni k databázi." + +#: common.c:655 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watch nelze použít s COPY" + +#: common.c:660 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "neočekávaný stav výsledku pro \\watch" + +#: common.c:690 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "Asynchronní upozornění \"%s\" s obsahem \"%s\" obdrženo ze serverového procesu s PID %d.\n" + +#: common.c:693 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "Asynchronní upozornění \"%s\" obdrženo z procesu serveru s PID %d.\n" + +#: common.c:726 common.c:743 +#, c-format +msgid "could not print result table: %m" +msgstr "nelze číst vypsat tabulku: %m" + +#: common.c:764 +#, c-format +msgid "no rows returned for \\gset" +msgstr "žádné řádky nevráceny pro \\gset" + +#: common.c:769 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "více než jedna řádka vrácena pro \\gset" + +#: common.c:1200 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(Krokovací mód: potvrďte příkaz)*******************************************\n" +"%s\n" +"***(stiskněte return pro zpracování nebo x a return pro zrušení)********************\n" + +#: common.c:1255 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "Server (verze %s) nepodporuje savepoints pro ON_ERROR_ROLLBACK." + +#: common.c:1318 +#, c-format +msgid "STATEMENT: %s" +msgstr "PŘÍKAZ: %s" + +#: common.c:1361 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "neočekávaný stav transakce: (%d)" + +#: common.c:1502 describe.c:2001 +msgid "Column" +msgstr "Sloupec" + +#: common.c:1503 describe.c:177 describe.c:393 describe.c:411 describe.c:456 +#: describe.c:473 describe.c:962 describe.c:1126 describe.c:1711 +#: describe.c:1735 describe.c:2002 describe.c:3729 describe.c:3939 +#: describe.c:4172 describe.c:5378 +msgid "Type" +msgstr "Typ" + +#: common.c:1552 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Příkaz nevrátil žádný výsledek, nebo výsledek nemá žádné sloupce.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy: argumenty jsou povinné" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: chyba na \"%s\"" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: chyba na konci řádku" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "nelze spustit příkaz \"%s\": %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "nelze provést stat souboru \"%s\": %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s: nelze kopírovat z/do adresáře" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "nelze zavřít rouru (pipe) pro externí příkaz: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "nelze zapsat data příkazu COPY: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "přenos dat příkazu COPY selhal: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "zrušeno na žádost uživatele" + +# common.c:485 +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Zadejte data pro kopírování následovaná novým řádkem.\n" +"Ukončete zpětným lomítkem a tečkou na samostatném řádku." + +#: copy.c:669 +msgid "aborted because of read failure" +msgstr "přerušeno z důvodu chyby čtení" + +#: copy.c:703 +msgid "trying to exit copy mode" +msgstr "pokouším se opustit copy mód" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: příkaz nevrátil žádný výsledek" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: dotaz musí vracet alespoň tři sloupce" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: vertikální a horozintální záklaví musí být různé sloupce" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: datový sloupec musí být specifikován pokud má dotaz více než tři sloupce" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: maximální počet sloupců (%d) překročen" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: výsledek dotazu obsahuje několik hodnot pro řádek \"%s\", sloupec \"%s\"" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: číslo sloupce %d je mimo rozsah 1..%d" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: nejednoznačný název sloupce: \"%s\"" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: sloupec nenaleze: \"%s\"" + +#: describe.c:75 describe.c:373 describe.c:678 describe.c:810 describe.c:954 +#: describe.c:1115 describe.c:1187 describe.c:3718 describe.c:3926 +#: describe.c:4170 describe.c:4261 describe.c:4528 describe.c:4688 +#: describe.c:4929 describe.c:5004 describe.c:5015 describe.c:5077 +#: describe.c:5502 describe.c:5585 +msgid "Schema" +msgstr "Schéma" + +#: describe.c:76 describe.c:174 describe.c:242 describe.c:250 describe.c:374 +#: describe.c:679 describe.c:811 describe.c:872 describe.c:955 describe.c:1188 +#: describe.c:3719 describe.c:3927 describe.c:4093 describe.c:4171 +#: describe.c:4262 describe.c:4341 describe.c:4529 describe.c:4613 +#: describe.c:4689 describe.c:4930 describe.c:5005 describe.c:5016 +#: describe.c:5078 describe.c:5275 describe.c:5359 describe.c:5583 +#: describe.c:5755 describe.c:5995 +msgid "Name" +msgstr "Jméno" + +#: describe.c:77 describe.c:386 describe.c:404 describe.c:450 describe.c:467 +msgid "Result data type" +msgstr "Datový typ výsledku" + +#: describe.c:85 describe.c:98 describe.c:102 describe.c:387 describe.c:405 +#: describe.c:451 describe.c:468 +msgid "Argument data types" +msgstr "Datový typ parametru" + +#: describe.c:110 describe.c:117 describe.c:185 describe.c:273 describe.c:513 +#: describe.c:727 describe.c:826 describe.c:897 describe.c:1190 describe.c:2020 +#: describe.c:3506 describe.c:3779 describe.c:3973 describe.c:4124 +#: describe.c:4198 describe.c:4271 describe.c:4354 describe.c:4437 +#: describe.c:4556 describe.c:4622 describe.c:4690 describe.c:4831 +#: describe.c:4873 describe.c:4946 describe.c:5008 describe.c:5017 +#: describe.c:5079 describe.c:5301 describe.c:5381 describe.c:5516 +#: describe.c:5586 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "Popis" + +#: describe.c:135 +msgid "List of aggregate functions" +msgstr "Seznam agregačních funkcí" + +#: describe.c:160 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "Server (verze %s) nepodporuje přístupové metody (access methods)." + +#: describe.c:175 +msgid "Index" +msgstr "Index" + +#: describe.c:176 describe.c:3737 describe.c:3952 describe.c:5503 +msgid "Table" +msgstr "Tabulka" + +#: describe.c:184 describe.c:5280 +msgid "Handler" +msgstr "Handler" + +#: describe.c:203 +msgid "List of access methods" +msgstr "Seznam přístupových metod" + +#: describe.c:229 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "Server (verze %s) nepodporuje tablespaces." + +#: describe.c:243 describe.c:251 describe.c:501 describe.c:717 describe.c:873 +#: describe.c:1114 describe.c:3730 describe.c:3928 describe.c:4097 +#: describe.c:4343 describe.c:4614 describe.c:5276 describe.c:5360 +#: describe.c:5756 describe.c:5893 describe.c:5996 describe.c:6111 +#: describe.c:6190 large_obj.c:289 +msgid "Owner" +msgstr "Vlastník" + +#: describe.c:244 describe.c:252 +msgid "Location" +msgstr "Umístění" + +#: describe.c:263 describe.c:3323 +msgid "Options" +msgstr "Volby" + +#: describe.c:268 describe.c:690 describe.c:889 describe.c:3771 describe.c:3775 +msgid "Size" +msgstr "Velikost" + +#: describe.c:290 +msgid "List of tablespaces" +msgstr "Seznam tablespaces" + +#: describe.c:333 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "pro \\df můžete použít pouze přepínače [anptwS+]" + +#: describe.c:341 describe.c:352 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "pro \\df nelze použít volbu \"%c\" ve verzi serveru %s" + +#. translator: "agg" is short for "aggregate" +#: describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "agg" +msgstr "agg" + +#: describe.c:390 describe.c:408 +msgid "window" +msgstr "window" + +#: describe.c:391 +msgid "proc" +msgstr "proc" + +#: describe.c:392 describe.c:410 describe.c:455 describe.c:472 +msgid "func" +msgstr "func" + +#: describe.c:409 describe.c:454 describe.c:471 describe.c:1324 +msgid "trigger" +msgstr "trigger" + +#: describe.c:483 +msgid "immutable" +msgstr "immutable" + +#: describe.c:484 +msgid "stable" +msgstr "stable" + +#: describe.c:485 +msgid "volatile" +msgstr "volatile" + +#: describe.c:486 +msgid "Volatility" +msgstr "Volatilita" + +#: describe.c:494 +msgid "restricted" +msgstr "restricted" + +#: describe.c:495 +msgid "safe" +msgstr "safe" + +#: describe.c:496 +msgid "unsafe" +msgstr "unsafe" + +#: describe.c:497 +msgid "Parallel" +msgstr "Parallel" + +#: describe.c:502 +msgid "definer" +msgstr "definer" + +#: describe.c:503 +msgid "invoker" +msgstr "invoker" + +#: describe.c:504 +msgid "Security" +msgstr "Bezpečnost" + +#: describe.c:511 +msgid "Language" +msgstr "Jazyk" + +#: describe.c:512 +msgid "Source code" +msgstr "Zdrojový kód" + +#: describe.c:641 +msgid "List of functions" +msgstr "Seznam funkcí" + +#: describe.c:689 +msgid "Internal name" +msgstr "Interní jméno" + +#: describe.c:711 +msgid "Elements" +msgstr "Složky" + +#: describe.c:768 +msgid "List of data types" +msgstr "Seznam datových typů" + +#: describe.c:812 +msgid "Left arg type" +msgstr "Typ levého argumentu" + +#: describe.c:813 +msgid "Right arg type" +msgstr "Typ pravého argumentu" + +#: describe.c:814 +msgid "Result type" +msgstr "Typ výsledku" + +#: describe.c:819 describe.c:4349 describe.c:4414 describe.c:4420 +#: describe.c:4830 describe.c:6362 describe.c:6366 +msgid "Function" +msgstr "Funkce" + +#: describe.c:844 +msgid "List of operators" +msgstr "Seznam operátorů" + +#: describe.c:874 +msgid "Encoding" +msgstr "Kódování" + +#: describe.c:879 describe.c:4530 +msgid "Collate" +msgstr "Collation" + +#: describe.c:880 describe.c:4531 +msgid "Ctype" +msgstr "CType" + +#: describe.c:893 +msgid "Tablespace" +msgstr "Tablespace" + +#: describe.c:915 +msgid "List of databases" +msgstr "Seznam databází" + +#: describe.c:956 describe.c:1117 describe.c:3720 +msgid "table" +msgstr "tabulka" + +#: describe.c:957 describe.c:3721 +msgid "view" +msgstr "pohled" + +#: describe.c:958 describe.c:3722 +msgid "materialized view" +msgstr "materializovaný pohled" + +#: describe.c:959 describe.c:1119 describe.c:3724 +msgid "sequence" +msgstr "sekvence" + +#: describe.c:960 describe.c:3726 +msgid "foreign table" +msgstr "foreign_tabulka" + +#: describe.c:961 describe.c:3727 describe.c:3937 +msgid "partitioned table" +msgstr "partitioned tabulka" + +# +#: describe.c:973 +msgid "Column privileges" +msgstr "Přístupová práva k atributům" + +#: describe.c:1004 describe.c:1038 +msgid "Policies" +msgstr "Politiky" + +#: describe.c:1070 describe.c:6052 describe.c:6056 +msgid "Access privileges" +msgstr "Přístupová práva" + +#: describe.c:1101 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "Server (verze %s) nepodporuje změny výchozích privilegií." + +#: describe.c:1121 +msgid "function" +msgstr "funkce" + +#: describe.c:1123 +msgid "type" +msgstr "typ" + +#: describe.c:1125 +msgid "schema" +msgstr "schéma" + +#: describe.c:1149 +msgid "Default access privileges" +msgstr "Implicitní přístupová práva" + +#: describe.c:1189 +msgid "Object" +msgstr "Objekt" + +#: describe.c:1203 +msgid "table constraint" +msgstr "omezení tabulky" + +#: describe.c:1225 +msgid "domain constraint" +msgstr "omezení domény" + +#: describe.c:1253 +msgid "operator class" +msgstr "třída operátorů" + +#: describe.c:1282 +msgid "operator family" +msgstr "rodina operátorů" + +#: describe.c:1304 +msgid "rule" +msgstr "rule" + +#: describe.c:1346 +msgid "Object descriptions" +msgstr "Popis objektu" + +#: describe.c:1402 describe.c:3843 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "Nelze nalézt relaci se jménem \"%s\"." + +#: describe.c:1405 describe.c:3846 +#, c-format +msgid "Did not find any relations." +msgstr "Nelze nalézt žádnou relaci." + +#: describe.c:1660 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "Nelze nalézt relaci se OID %s." + +#: describe.c:1712 describe.c:1736 +msgid "Start" +msgstr "Start" + +#: describe.c:1713 describe.c:1737 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1714 describe.c:1738 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1715 describe.c:1739 +msgid "Increment" +msgstr "Inkrement" + +#: describe.c:1716 describe.c:1740 describe.c:1871 describe.c:4265 +#: describe.c:4431 describe.c:4545 describe.c:4550 describe.c:6099 +msgid "yes" +msgstr "ano" + +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4265 +#: describe.c:4428 describe.c:4545 describe.c:6100 +msgid "no" +msgstr "ne" + +#: describe.c:1718 describe.c:1742 +msgid "Cycles?" +msgstr "Cycles?" + +#: describe.c:1719 describe.c:1743 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1786 +#, c-format +msgid "Owned by: %s" +msgstr "Vlastník: %s" + +#: describe.c:1790 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Sekvence pro identity sloupec: %s" + +#: describe.c:1797 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Sekvence \"%s.%s\"" + +#: describe.c:1933 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Unlogged tabulka \"%s.%s\"" + +#: describe.c:1936 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Tabulka \"%s.%s\"" + +#: describe.c:1940 +#, c-format +msgid "View \"%s.%s\"" +msgstr "Pohled \"%s.%s\"" + +#: describe.c:1945 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Unlogged materializovaný pohled \"%s.%s\"" + +#: describe.c:1948 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Materializovaný pohled \"%s.%s\"" + +#: describe.c:1953 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Unlogged index \"%s.%s\"" + +#: describe.c:1956 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "Index \"%s.%s\"" + +#: describe.c:1961 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Unlogged partitioned index \"%s.%s\"" + +#: describe.c:1964 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Partitioned index \"%s.%s\"" + +#: describe.c:1969 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Speciální relace \"%s.%s\"" + +#: describe.c:1973 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "TOAST tabulka \"%s.%s\"" + +#: describe.c:1977 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Složený typ \"%s.%s\"" + +#: describe.c:1981 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "Foreign tabulka \"%s.%s\"" + +#: describe.c:1986 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Unlogged partitioned tabulka \"%s.%s\"" + +#: describe.c:1989 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Partitioned tabulka \"%s.%s\"" + +#: describe.c:2005 describe.c:4178 +msgid "Collation" +msgstr "Collation" + +#: describe.c:2006 describe.c:4185 +msgid "Nullable" +msgstr "Nullable" + +#: describe.c:2007 describe.c:4186 +msgid "Default" +msgstr "Implicitně" + +#: describe.c:2010 +msgid "Key?" +msgstr "Klíč?" + +#: describe.c:2012 +msgid "Definition" +msgstr "Definice" + +#: describe.c:2014 describe.c:5296 describe.c:5380 describe.c:5451 +#: describe.c:5515 +msgid "FDW options" +msgstr "FDW volby" + +#: describe.c:2016 +msgid "Storage" +msgstr "Uložení" + +#: describe.c:2018 +msgid "Stats target" +msgstr "Stats target" + +#: describe.c:2131 +#, c-format +msgid "Partition of: %s %s" +msgstr "Partition pro: %s %s" + +#: describe.c:2143 +msgid "No partition constraint" +msgstr "Žádné omezení partition" + +#: describe.c:2145 +#, c-format +msgid "Partition constraint: %s" +msgstr "Omezení partition: %s" + +#: describe.c:2169 +#, c-format +msgid "Partition key: %s" +msgstr "Partition klíč: %s" + +#: describe.c:2195 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Owning table: \"%s.%s\"" + +#: describe.c:2266 +msgid "primary key, " +msgstr "primární klíč, " + +#: describe.c:2268 +msgid "unique, " +msgstr "unikátní, " + +#: describe.c:2274 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "pro tabulku \"%s.%s\"" + +#: describe.c:2278 +#, c-format +msgid ", predicate (%s)" +msgstr ", predikát (%s)" + +#: describe.c:2281 +msgid ", clustered" +msgstr ", clusterován" + +#: describe.c:2284 +msgid ", invalid" +msgstr ", neplatný" + +#: describe.c:2287 +msgid ", deferrable" +msgstr ", odložitelný" + +#: describe.c:2290 +msgid ", initially deferred" +msgstr ", iniciálně odložený" + +#: describe.c:2293 +msgid ", replica identity" +msgstr ", replica identity" + +#: describe.c:2360 +msgid "Indexes:" +msgstr "Indexy:" + +#: describe.c:2444 +msgid "Check constraints:" +msgstr "Kontrolní pravidla:" + +#: describe.c:2512 +msgid "Foreign-key constraints:" +msgstr "Podmínky cizího klíče:" + +#: describe.c:2575 +msgid "Referenced by:" +msgstr "Odkazovaný:" + +#: describe.c:2625 +msgid "Policies:" +msgstr "Politiky:" + +#: describe.c:2628 +msgid "Policies (forced row security enabled):" +msgstr "Poitiky (forced row security zapnuta):" + +#: describe.c:2631 +msgid "Policies (row security enabled): (none)" +msgstr "Politiky (row security zapnuta): (žádné)" + +#: describe.c:2634 +msgid "Policies (forced row security enabled): (none)" +msgstr "Politiky (forced row security zapnuta): (žádné)" + +#: describe.c:2637 +msgid "Policies (row security disabled):" +msgstr "Politiky (row security vypnuta):" + +#: describe.c:2705 +msgid "Statistics objects:" +msgstr "Statistické objekty:" + +#: describe.c:2819 describe.c:2923 +msgid "Rules:" +msgstr "Rules:" + +#: describe.c:2822 +msgid "Disabled rules:" +msgstr "Vypnutá pravidla (rules):" + +#: describe.c:2825 +msgid "Rules firing always:" +msgstr "Vždy spouštěná pravidla:" + +#: describe.c:2828 +msgid "Rules firing on replica only:" +msgstr "Pravidla spouštěná jen na replice:" + +#: describe.c:2868 +msgid "Publications:" +msgstr "Publikace:" + +#: describe.c:2906 +msgid "View definition:" +msgstr "Definice pohledu:" + +#: describe.c:3053 +msgid "Triggers:" +msgstr "Triggery:" + +#: describe.c:3057 +msgid "Disabled user triggers:" +msgstr "Vypnuté uživatelské triggery:" + +#: describe.c:3059 +msgid "Disabled triggers:" +msgstr "Vypnuté triggery:" + +#: describe.c:3062 +msgid "Disabled internal triggers:" +msgstr "Vypnuté interní triggery:" + +#: describe.c:3065 +msgid "Triggers firing always:" +msgstr "Vždy spouštěné triggery:" + +#: describe.c:3068 +msgid "Triggers firing on replica only:" +msgstr "Triggery spouštěné jen na replice:" + +#: describe.c:3140 +#, c-format +msgid "Server: %s" +msgstr "Server: %s" + +#: describe.c:3148 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW volby: (%s)" + +#: describe.c:3169 +msgid "Inherits" +msgstr "Dědí" + +#: describe.c:3229 +#, c-format +msgid "Number of partitions: %d" +msgstr "Počet partition: %d" + +#: describe.c:3238 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Počet partitions: %d (Použijte \\d+ pro jejich seznam.)" + +#: describe.c:3240 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Počet podřízených tabulek: %d (Použijte \\d+ pro jejich seznam.)" + +#: describe.c:3247 +msgid "Child tables" +msgstr "Podřízené tabulky" + +#: describe.c:3247 +msgid "Partitions" +msgstr "Partitions" + +#: describe.c:3276 +#, c-format +msgid "Typed table of type: %s" +msgstr "Typovaná tabulka typu: %s" + +#: describe.c:3292 +msgid "Replica Identity" +msgstr "Replica Identity" + +#: describe.c:3305 +msgid "Has OIDs: yes" +msgstr "Má OID: ano" + +#: describe.c:3314 +#, c-format +msgid "Access method: %s" +msgstr "Přístupová metoda: %s" + +#: describe.c:3394 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Tablespace: \"%s\"" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3406 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", tablespace: \"%s\"" + +#: describe.c:3499 +msgid "List of roles" +msgstr "Seznam rolí" + +#: describe.c:3501 +msgid "Role name" +msgstr "Jméno role" + +#: describe.c:3502 +msgid "Attributes" +msgstr "Atributy" + +#: describe.c:3503 +msgid "Member of" +msgstr "Je členem" + +#: describe.c:3514 +msgid "Superuser" +msgstr "Super-uživatel" + +#: describe.c:3517 +msgid "No inheritance" +msgstr "Bez dědičnosti" + +#: describe.c:3520 +msgid "Create role" +msgstr "Vytvoř roli" + +#: describe.c:3523 +msgid "Create DB" +msgstr "Vytvoř DB" + +#: describe.c:3526 +msgid "Cannot login" +msgstr "Nemohu se přihlásit" + +#: describe.c:3530 +msgid "Replication" +msgstr "Replikace" + +#: describe.c:3534 +msgid "Bypass RLS" +msgstr "Obejít RLS" + +#: describe.c:3543 +msgid "No connections" +msgstr "Není spojení" + +#: describe.c:3545 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d spojení" +msgstr[1] "%d spojení" +msgstr[2] "%d spojení" + +#: describe.c:3555 +msgid "Password valid until " +msgstr "Heslo platné do " + +#: describe.c:3605 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "Server (verze %s) nepodporuje nastavení rolí pro jednotlivé databáze." + +#: describe.c:3618 +msgid "Role" +msgstr "Role" + +#: describe.c:3619 +msgid "Database" +msgstr "Databáze" + +#: describe.c:3620 +msgid "Settings" +msgstr "Nastavení" + +#: describe.c:3641 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "Nelze nalézt žádné nastavení pro roli \"%s\" a databázi \"%s\"." + +#: describe.c:3644 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "Nelze nalézt žádné nastavení pro roli \"%s\"." + +#: describe.c:3647 +#, c-format +msgid "Did not find any settings." +msgstr "Žádná nastavení nenalezena." + +#: describe.c:3652 +msgid "List of settings" +msgstr "Seznam nastavení" + +#: describe.c:3723 +msgid "index" +msgstr "index" + +#: describe.c:3725 +msgid "special" +msgstr "speciální" + +#: describe.c:3728 describe.c:3938 +msgid "partitioned index" +msgstr "partitioned index" + +#: describe.c:3752 +msgid "permanent" +msgstr "permanent" + +#: describe.c:3753 +msgid "temporary" +msgstr "temporary" + +#: describe.c:3754 +msgid "unlogged" +msgstr "unlogged" + +#: describe.c:3755 +msgid "Persistence" +msgstr "Persistence" + +#: describe.c:3851 +msgid "List of relations" +msgstr "Seznam relací" + +#: describe.c:3899 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "Server (verze %s) nepodporuje deklarativní partitioning." + +#: describe.c:3910 +msgid "List of partitioned indexes" +msgstr "Seznam partitioned indexů" + +#: describe.c:3912 +msgid "List of partitioned tables" +msgstr "Seznam partitioned tabulek" + +#: describe.c:3916 +msgid "List of partitioned relations" +msgstr "Seznam partitioned relací" + +#: describe.c:3947 +msgid "Parent name" +msgstr "Jméno předka" + +#: describe.c:3960 +msgid "Leaf partition size" +msgstr "Leaf partition size" + +#: describe.c:3963 describe.c:3969 +msgid "Total size" +msgstr "Celková velikost" + +#: describe.c:4101 +msgid "Trusted" +msgstr "Důvěryhodný" + +#: describe.c:4109 +msgid "Internal language" +msgstr "Interní jazyk" + +#: describe.c:4110 +msgid "Call handler" +msgstr "Call handler" + +#: describe.c:4111 describe.c:5283 +msgid "Validator" +msgstr "Validátor" + +#: describe.c:4114 +msgid "Inline handler" +msgstr "Inline handler" + +#: describe.c:4142 +msgid "List of languages" +msgstr "Seznam jazyků" + +#: describe.c:4187 +msgid "Check" +msgstr "Kontrola" + +#: describe.c:4229 +msgid "List of domains" +msgstr "Seznam domén" + +#: describe.c:4263 +msgid "Source" +msgstr "Zdroj" + +#: describe.c:4264 +msgid "Destination" +msgstr "Cíl" + +#: describe.c:4266 describe.c:6101 +msgid "Default?" +msgstr "Implicitně?" + +#: describe.c:4303 +msgid "List of conversions" +msgstr "Seznam konverzí" + +#: describe.c:4342 +msgid "Event" +msgstr "Událost" + +#: describe.c:4344 +msgid "enabled" +msgstr "povoleno" + +#: describe.c:4345 +msgid "replica" +msgstr "replica" + +#: describe.c:4346 +msgid "always" +msgstr "vždy" + +#: describe.c:4347 +msgid "disabled" +msgstr "disabled" + +#: describe.c:4348 describe.c:5997 +msgid "Enabled" +msgstr "Povoleno" + +#: describe.c:4350 +msgid "Tags" +msgstr "Tagy" + +#: describe.c:4369 +msgid "List of event triggers" +msgstr "Seznam event triggerů" + +#: describe.c:4398 +msgid "Source type" +msgstr "Zdrojový typ" + +#: describe.c:4399 +msgid "Target type" +msgstr "Cílový typ" + +#: describe.c:4430 +msgid "in assignment" +msgstr "v přiřazení" + +#: describe.c:4432 +msgid "Implicit?" +msgstr "Implicitně?" + +#: describe.c:4487 +msgid "List of casts" +msgstr "Seznam přetypování" + +#: describe.c:4515 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "Server (verze %s) nepodporuje collations." + +#: describe.c:4536 describe.c:4540 +msgid "Provider" +msgstr "Provider" + +#: describe.c:4546 describe.c:4551 +msgid "Deterministic?" +msgstr "Deterministická?" + +#: describe.c:4586 +msgid "List of collations" +msgstr "Seznam collations" + +#: describe.c:4645 +msgid "List of schemas" +msgstr "Seznam schémat" + +#: describe.c:4670 describe.c:4917 describe.c:4988 describe.c:5059 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "Server (verze %s) nepodporuje fulltextové vyhledávání." + +#: describe.c:4705 +msgid "List of text search parsers" +msgstr "Seznam fulltextových parserů" + +#: describe.c:4750 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "Nelze nalézt fulltextový parser se jménem \"%s\"." + +#: describe.c:4753 +#, c-format +msgid "Did not find any text search parsers." +msgstr "Nelze nalézt žádný fulltextový parser." + +#: describe.c:4828 +msgid "Start parse" +msgstr "Začátek parsování" + +#: describe.c:4829 +msgid "Method" +msgstr "Metoda" + +#: describe.c:4833 +msgid "Get next token" +msgstr "Získej další token" + +#: describe.c:4835 +msgid "End parse" +msgstr "Konec parsování" + +#: describe.c:4837 +msgid "Get headline" +msgstr "Získej záhlaví" + +#: describe.c:4839 +msgid "Get token types" +msgstr "Získej typy tokenu" + +#: describe.c:4850 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Fulltextový parser \"%s.%s\"" + +#: describe.c:4853 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "Fulltextový parser \"%s\"" + +#: describe.c:4872 +msgid "Token name" +msgstr "Jméno tokenu" + +#: describe.c:4883 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "Jméno tokenu pro parser \"%s.%s\"" + +#: describe.c:4886 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "Typ tokenu pro parser \"%s\"" + +#: describe.c:4940 +msgid "Template" +msgstr "Šablona" + +#: describe.c:4941 +msgid "Init options" +msgstr "Init options" + +#: describe.c:4963 +msgid "List of text search dictionaries" +msgstr "Seznam fulltextových slovníků" + +#: describe.c:5006 +msgid "Init" +msgstr "Init" + +#: describe.c:5007 +msgid "Lexize" +msgstr "Lexize" + +#: describe.c:5034 +msgid "List of text search templates" +msgstr "Seznam fulltextových šablon" + +#: describe.c:5094 +msgid "List of text search configurations" +msgstr "Seznam fulltextových konfigurací" + +#: describe.c:5140 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "Nelze nalézt fulltextovou konfiguraci se jménem \"%s\"." + +#: describe.c:5143 +#, c-format +msgid "Did not find any text search configurations." +msgstr "Nelze nalézt žádnou fulltextovou konfiguraci." + +#: describe.c:5209 +msgid "Token" +msgstr "Token" + +#: describe.c:5210 +msgid "Dictionaries" +msgstr "Slovníky" + +#: describe.c:5221 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Fulltextová konfigurace \"%s.%s\"" + +#: describe.c:5224 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Fulltextová konfigurace \"%s\"" + +#: describe.c:5228 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Parser: \"%s.%s\"" + +#: describe.c:5231 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Parser: \"%s\"" + +#: describe.c:5265 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "Server (verze %s) nepodporuje foreign-data wrappery." + +#: describe.c:5323 +msgid "List of foreign-data wrappers" +msgstr "Seznam foreign-data wrapperů" + +#: describe.c:5348 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "Server (verze %s) nepodporuje foreign servery." + +#: describe.c:5361 +msgid "Foreign-data wrapper" +msgstr "Foreign-data wrapper" + +#: describe.c:5379 describe.c:5584 +msgid "Version" +msgstr "Verze" + +#: describe.c:5405 +msgid "List of foreign servers" +msgstr "Seznam foreign serverů" + +#: describe.c:5430 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "Server (verze %s) nepodporuje mapování uživatelů." + +#: describe.c:5440 describe.c:5504 +msgid "Server" +msgstr "Server" + +#: describe.c:5441 +msgid "User name" +msgstr "Uživatelské jméno" + +#: describe.c:5466 +msgid "List of user mappings" +msgstr "Seznam mapování uživatelů" + +#: describe.c:5491 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "Server (verze %s) nepodporuje foreign tabulky." + +#: describe.c:5544 +msgid "List of foreign tables" +msgstr "Seznam foreign tabulek" + +#: describe.c:5569 describe.c:5626 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "Server (verze %s) nepodporuje extensions." + +#: describe.c:5601 +msgid "List of installed extensions" +msgstr "Seznam instalovaných extensions" + +#: describe.c:5654 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "Nelze nalézt extension se jménem \"%s\"." + +#: describe.c:5657 +#, c-format +msgid "Did not find any extensions." +msgstr "Nelze nalézt žádnou extension." + +#: describe.c:5701 +msgid "Object description" +msgstr "Popis objektu" + +#: describe.c:5711 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "Objekty v rozšíření \"%s\"" + +#: describe.c:5740 describe.c:5816 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "Server (verze %s) nepodporuje publikace." + +#: describe.c:5757 describe.c:5894 +msgid "All tables" +msgstr "Všechny tabulky" + +#: describe.c:5758 describe.c:5895 +msgid "Inserts" +msgstr "Insert" + +#: describe.c:5759 describe.c:5896 +msgid "Updates" +msgstr "Update" + +#: describe.c:5760 describe.c:5897 +msgid "Deletes" +msgstr "Delete" + +#: describe.c:5764 describe.c:5899 +msgid "Truncates" +msgstr "Truncates" + +#: describe.c:5768 describe.c:5901 +msgid "Via root" +msgstr "Via root" + +#: describe.c:5785 +msgid "List of publications" +msgstr "Seznam publikací" + +#: describe.c:5858 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "Nelze nalézt publikaci se jménem \"%s\"." + +#: describe.c:5861 +#, c-format +msgid "Did not find any publications." +msgstr "Nelze nalézt žádnou publikaci." + +#: describe.c:5890 +#, c-format +msgid "Publication %s" +msgstr "Publikace %s" + +#: describe.c:5938 +msgid "Tables:" +msgstr "Tabulky:" + +#: describe.c:5982 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "Server (verze %s) nepodporuje subskripce." + +#: describe.c:5998 +msgid "Publication" +msgstr "Publikace" + +#: describe.c:6005 +msgid "Synchronous commit" +msgstr "Synchronní commit" + +#: describe.c:6006 +msgid "Conninfo" +msgstr "Spojení" + +#: describe.c:6028 +msgid "List of subscriptions" +msgstr "Seznam subskripcí" + +#: describe.c:6095 describe.c:6184 describe.c:6270 describe.c:6353 +msgid "AM" +msgstr "AM" + +#: describe.c:6096 +msgid "Input type" +msgstr "Vstupní typ" + +#: describe.c:6097 +msgid "Storage type" +msgstr "Typ uložení" + +#: describe.c:6098 +msgid "Operator class" +msgstr "Třída operátorů" + +#: describe.c:6110 describe.c:6185 describe.c:6271 describe.c:6354 +msgid "Operator family" +msgstr "Rodina operátorů" + +#: describe.c:6143 +msgid "List of operator classes" +msgstr "Seznam tříd operátorů" + +#: describe.c:6186 +msgid "Applicable types" +msgstr "Aplikovatelné typy" + +#: describe.c:6225 +msgid "List of operator families" +msgstr "Seznam rodin operátorů" + +#: describe.c:6272 +msgid "Operator" +msgstr "Operátor" + +#: describe.c:6273 +msgid "Strategy" +msgstr "Strategie" + +#: describe.c:6274 +msgid "ordering" +msgstr "řazení" + +#: describe.c:6275 +msgid "search" +msgstr "hledání" + +#: describe.c:6276 +msgid "Purpose" +msgstr "Účel" + +#: describe.c:6281 +msgid "Sort opfamily" +msgstr "Rodina operátorů" + +#: describe.c:6312 +msgid "List of operators of operator families" +msgstr "List operátorů v rodinách operátorů" + +#: describe.c:6355 +msgid "Registered left type" +msgstr "Typ levého argumentu" + +#: describe.c:6356 +msgid "Registered right type" +msgstr "Typ pravého argumentu" + +#: describe.c:6357 +msgid "Number" +msgstr "Číslo" + +#: describe.c:6393 +msgid "List of support functions of operator families" +msgstr "Seznam support funkcí pro rodiny operátorů" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql je PostgreSQL interaktivní terminál.\n" +"\n" + +#: help.c:74 help.c:355 help.c:431 help.c:474 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [PŘEPÍNAČE]... [DATABÁZE [UŽIVATEL]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Základní volby:\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr " -c, --command=PŘÍKAZ provede pouze jeden příkaz (SQL nebo interní) a skončí\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr " -d, --dbname=DATABÁZE jméno databáze pro spojení (implicitně: \"%s\")\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=SOUBOR provede příkazy ze souboru a skončí\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, --list vypíše seznam dostupných databází a skončí\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=JMÉNO=HODNOTA\n" +" nastaví psql proměnnou JMÉNO na HODNOTA\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +"\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version ukáže informace o verzi a skončí\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc nečíst inicializační soubor (~/.psqlrc)\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 (\"jedna\"), --single-transaction\n" +" proveď operaci v rámci jedné transakce\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] ukáže tuto nápovědu, a skončí\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands vypíše interní příkazy, poté skončí\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables vypíše speciální proměnné, poté skončí\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Vstupní a výstupní přepínače:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all ukáže všechny vstupy ze skriptu\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors vypíše příkazy které selhaly\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e --echo-queries ukáže všechny příkazy poslané na server\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden ukáže dotazy generované interními příkazy\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, --log-file=SOUBOR uloží záznam sezení do souboru\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, --no-readline vypne pokročilé editační možnosti příkazové řádky (podpora readline)\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, --output=SOUBOR zapíše výsledek dotazu do souboru (nebo |roury)\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, --quiet tichý chod (bez hlášek, pouze výstupy dotazů)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, --single-step krokovací mód (nutné potvrzení každého dotazu)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr " -S, --single-line jednořádkový mód (konec řádky ukončuje SQL příkaz)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Výstupní formát je:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align mód nezarovnaného formátu tabulky\n" + +#: help.c:111 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv CSV (Comma-Separated Values) mód výstupu tabulek\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, --field-separator=ŘETĚZEC\n" +" oddělovač polí pro nezarovnaný výstup (implicitně: \"%s\")\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html mód HTML formátu tabulky\n" + +#: help.c:116 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr " -P, --pset=VAR[=ARG] nastaví zobrazovací parametr VAR na hodnotu ARG (viz. příkaz \\pset)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, --record-separator=ŘETĚZEC\n" +" oddělovač záznamů pro nezarovnaný výstup (implicitně: newline)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only tiskni pouze řádky\n" + +#: help.c:120 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr " -T, --table-attr=TEXT nastaví atributy HTML tabulky (např. width, border)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded zapne rozšířený tabulkový výstup\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" nastaví oddělovač polí pro nezarovnaný výstup na nulový byte\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" nastaví oddělovač záznamů pro nezarovnaný výstup na nulový byte\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Parametry spojení:\n" + +#: help.c:130 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr " -h, --host=HOSTNAME jméno databázového serveru nebo adresář se soketem (implicitně: \"%s\")\n" + +#: help.c:131 +msgid "local socket" +msgstr "lokální soket" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, --port=PORT port databázového serveru (implicitně: \"%s\")\n" + +#: help.c:140 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, --username=JMÉNO jméno databázového uživatele (implicitně: \"%s\")\n" + +#: help.c:141 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password neptá se na heslo\n" + +#: help.c:142 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password vynucený dotaz na heslo (měl by být proveden automaticky)\n" + +#: help.c:144 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"Pro více informací použijte \"\\?\" (pro interní příkazy) nebo \"\\help\"\n" +"(pro SQL příkazy), nebo se podívejte do dokumentace PostgreSQL a\n" +"části věnované psql.\n" +"\n" + +#: help.c:147 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Chyby hlašte na <%s>.\n" + +#: help.c:148 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s domácí stránka: <%s>\n" + +#: help.c:174 +#, c-format +msgid "General\n" +msgstr "Hlavní\n" + +#: help.c:175 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright zobrazí podmínky použití a distribuce PostgreSQL\n" + +#: help.c:176 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [SLOUPCE] spustí dotaz a zobrazí výsledek přes crosstab\n" + +#: help.c:177 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose zobrazí polední chybovou hlášku s maximem podrobností\n" + +#: help.c:178 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" + +#: help.c:180 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc popíše výsledek dotazu, bez spuštění\n" + +#: help.c:181 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr " \\gexec spustí dotaz, poté spustí každou hodnotu z jeho výsledku\n" + +#: help.c:182 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PREFIX] spustí dotaz a uloží výsledky v psql proměnných\n" + +#: help.c:183 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [(VOLBY)] [SOUBOR] jako \\g, ale vynucuje rozšířený mód výstupu\n" + +#: help.c:184 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q ukončení psql\n" + +#: help.c:185 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SEC] každých SEC vteřin spusť dotaz\n" + +#: help.c:188 +#, c-format +msgid "Help\n" +msgstr "Nápověda\n" + +#: help.c:190 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commands] zobrazí nápovědu k interním příkazům\n" + +#: help.c:191 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? options zobrazí nápovědu k psql parametrům psql pro příkazovou řádku\n" + +#: help.c:192 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables zobrazí nápovědu ke speciálním proměnným\n" + +#: help.c:193 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr " \\h [JMÉNO] nápověda syntaxe SQL příkazů, * pro všechny příkazy\n" + +#: help.c:196 +#, c-format +msgid "Query Buffer\n" +msgstr "Paměť dotazu\n" + +#: help.c:197 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr " \\e [SOUBOR] [ŘÁDEK] editace aktuálního dotazu (nebo souboru) v externím editoru\n" + +#: help.c:198 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [JMENOFUNKCE [ŘÁDEK]] editace definice funkce v externím editoru\n" + +#: help.c:199 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr "" +" \\ev [VIEWNAME [LINE]] editace definice pohledu v externím editoru\n" +"\n" + +#: help.c:200 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p ukázat současný obsah paměti s dotazem\n" + +#: help.c:201 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r vyprázdnění paměti s dotazy\n" + +#: help.c:203 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [SOUBOR] vytiskne historii nebo ji uloží do souboru\n" + +#: help.c:205 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w SOUBOR zapsání paměti s dotazem do souboru\n" + +#: help.c:208 +#, c-format +msgid "Input/Output\n" +msgstr "Vstup/Výstup\n" + +#: help.c:209 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr " \\copy ... provede SQL COPY s tokem dat na klienta\n" + +#: help.c:210 +#, c-format +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr "" +" \\echo [-n] [ŘETĚZEC] vypsání textu na standardní výstup (-n pro potlačení\n" +" nového řádku)\n" + +#: help.c:211 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i SOUBOR provedení příkazů ze souboru\n" + +#: help.c:212 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr " \\ir FILE jako \\i, ale relativně k pozici v aktuálním skriptu\n" + +#: help.c:213 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [SOUBOR] přesměrování výsledků dotazu do souboru nebo |roury\n" + +#: help.c:214 +#, c-format +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr "" +" \\qecho [ŘETĚZEC] vypsání textu na \\o výstup dotazů (-n pro potlačení\n" +" nového řádku)\n" + +#: help.c:215 +#, c-format +#| msgid " \\echo [STRING] write string to standard output\n" +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr "" +" \\warn [-n] [TEXT] vypsání textu na standardní výstup (-n pro potlačení\n" +" nového řádku)\n" + +#: help.c:218 +#, c-format +msgid "Conditional\n" +msgstr "Podmínka\n" + +#: help.c:219 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR začne podmíněný blok\n" + +#: help.c:220 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR alternativa v současném podmíněném bloku\n" + +#: help.c:221 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else poslední alternativa v současném podmíněném bloku\n" + +#: help.c:222 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif ukončí podmíněný blok\n" + +#: help.c:225 +#, c-format +msgid "Informational\n" +msgstr "Informační\n" + +#: help.c:226 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (volby: S = zobraz systémové objekty, + = další detaily)\n" + +#: help.c:227 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] seznam tabulek, pohledů a sekvencí\n" + +#: help.c:228 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+] JMÉNO popis tabulky, pohledů, sekvence nebo indexu\n" + +#: help.c:229 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [VZOR] seznam agregačních funkcí\n" + +#: help.c:230 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [PATTERN] seznam přístupových metod\n" + +#: help.c:231 +#, c-format +#| msgid " \\do[S] [PATTERN] list operators\n" +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] vypíše třídy operátorů\n" + +#: help.c:232 +#, c-format +#| msgid " \\do[S] [PATTERN] list operators\n" +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] vypíše rodiny operátorů\n" + +#: help.c:233 +#, c-format +#| msgid " \\do[S] [PATTERN] list operators\n" +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] vypíše operátory pro rodiny operátorů\n" + +#: help.c:234 +#, c-format +msgid " \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp [AMPTRN [OPFPTRN]] vypíše support funkce rodin operátorů\n" + +#: help.c:235 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [VZOR] seznam tablespaces\n" + +#: help.c:236 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [PATTERN] seznam konverzí\n" + +#: help.c:237 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [PATTERN] seznam přetypování\n" + +#: help.c:238 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr " \\dd[S] [PATTERN] zobrazí popis objektů nezobrazených jinde\n" + +#: help.c:239 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [PATTERN] seznam domén\n" + +#: help.c:240 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [VZOR] seznam implicitních privilegií\n" + +#: help.c:241 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [VZOR] seznam foreign tabulek\n" + +#: help.c:242 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [VZOR] seznam foreign tabulek\n" + +#: help.c:243 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [VZOR] seznam foreign serverů\n" + +#: help.c:244 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [VZOR] seznam mapování uživatelů\n" + +#: help.c:245 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [VZOR] seznam foreign-data wrapperů\n" + +#: help.c:246 +#, c-format +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [VZOR] seznam [pouze agg/normal/procedures/trigger/window] funkcí\n" + +#: help.c:247 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [VZOR] seznam konfigurací fulltextového vyhledávání\n" + +#: help.c:248 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [VZOR] seznam slovníků fulltextového vyhledávání\n" + +#: help.c:249 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [VZOR] seznam parserů fulltextového vyhledávání\n" + +#: help.c:250 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [VZOR] seznam šablon fulltextového vyhledávání\n" + +#: help.c:251 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [PATTERN] seznam rolí\n" + +#: help.c:252 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [VZOR] seznam indexů\n" + +#: help.c:253 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl seznam \"large object\" stejné jako \\lo_list\n" + +#: help.c:254 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [VZOR] seznam procedurálních jazyků\n" + +#: help.c:255 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [PATTERN] seznam materializovaných pohledů\n" + +#: help.c:256 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [VZOR] seznam schémat\n" + +#: help.c:257 +#, c-format +msgid " \\do[S] [PATTERN] list operators\n" +msgstr " \\do[S] [VZOR] seznam operátorů\n" + +#: help.c:258 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [VZOR] seznam collations\n" + +#: help.c:259 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [VZOR] seznam přístupových práv tabulek, pohledů a sekvencí\n" + +#: help.c:260 +#, c-format +msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" +msgstr " \\dP[itn+] [PATTERN] seznam [pouze index/table] partitioned relations [n=nested]\n" + +#: help.c:261 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [VZOR1 [VZOR2]] seznam nastavení rolí pro jednotlivé databáze\n" + +#: help.c:262 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [PATTERN] seznam replikačních publikací\n" + +#: help.c:263 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [PATTERN] seznam replikačních subskripcí\n" + +#: help.c:264 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [VZOR] seznam sekvencí\n" + +#: help.c:265 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [VZOR] seznam tabulek\n" + +#: help.c:266 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [VZOR] seznam datových typů\n" + +#: help.c:267 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [PATTERN] seznam rolí\n" + +#: help.c:268 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [VZOR] seznam pohledů\n" + +#: help.c:269 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [VZOR] seznam rozšíření\n" + +#: help.c:270 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [PATTERN] seznam event triggerů\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [PATTERN] seznam databází\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] FUNCNAME zobrazí definici funkce\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] VIEWNAME zobrazí definici pohledu\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [VZOR] stejné jako \\dp\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "Formátování\n" + +#: help.c:278 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr " \\a přepíná mezi 'unaligned' a 'aligned' modem výstupu\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr " \\C [ŘETĚZEC] nastaví titulek tabulky nebo odnastaví pokud není definován řetězec\n" + +#: help.c:280 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr " \\f [ŘETĚZEC] nastaví nebo zobrazí oddělovače polí pro nezarovnaný výstup dotazů\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H zapne HTML mód výstupu (nyní %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] ukazovat pouze řádky (nyní %s)\n" + +#: help.c:292 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr " \\T [ŘETĚZEC] nastavení atributů HTML tagu
\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] zapne rozšířený mód výstupu (nyní %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "Spojení\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] [DATABÁZE|- UŽIVATEL|- HOST|- PORT|-] | conninfo]\n" +" připojí se do nové databáze (současná \"%s\")\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] [DATABÁZE|- UŽIVATEL|- HOST|- PORT|-] | conninfo]\n" +" připojí se do nové databáze (současně žádné spojení)\n" + +#: help.c:305 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo zobrazí informace o aktuálním spojení\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [KÓDOVÁNÍ] zobrazení nebo nastavení kódování klienta\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr " \\password [UŽIVATEL] bezpečná změna hesla uživatele\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "Operační systém\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [ADRESÁŘ] změna aktuálního pracovního adresář\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv NAME [VALUE] nastaví nebo zruší proměnnou prostředí\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] použít sledování času u příkazů (nyní %s)\n" + +#: help.c:315 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr " \\! [PŘÍKAZ] provedení příkazu v shellu nebo nastartuje interaktivní shell\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "Proměnné\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr " \\prompt [TEXT] PROMĚNÁ vyzve uživatele, aby zadal hodnotu proměnné\n" + +#: help.c:320 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr "" +" \\set [PROMĚNÁ [HODNOTA]]\n" +" nastavení interní proměnné nebo bez parametrů zobrazí\n" +" seznam všech proměnných\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset JMÉNO zrušení interní proměnné\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "Velké objekty (LO)\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID SOUBOR\n" +" \\lo_import SOUBOR [KOMENTÁŘ]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID operace s \"large\" objekty\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"Seznam proměnných se zvláštním významem\n" +"\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "psql proměnné:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=NAME=VALUE\n" +" nebo \\set NAME VALUE v psql\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" pokud nastaveno, úspěšně dokončené SQL příkazy jsou automaticky commitovány\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" určuje velikost písmen pro dokončování SQL klíčových slov\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" název aktuálně připojené databáze\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" určuje jaký vstup je zapisován na standardní výstup\n" +" [all, errors, none, queries]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" pokud je nastaveno, zobrazuje dotazy spouštěné interními (backslash) příkazy;\n" +" při nastavení na \"noexec\", pouze zobrazí bez spuštění\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" aktuální kódování znakové sady klienta\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" nastaveno na true pokud poslední dotaz selhal, jinak false\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" počet řádek výsledku pro načtení a zobrazení nanjednou (0 = unlimited)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" pokud nastaveno, informace o table access methods nejsou zobrazovány\n" + +#: help.c:379 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" nastavuje chování historie příkazů [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" název souboru pro uložení historie příkazů\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" maximální počet položek uložených v historii přkazů\n" +"\n" + +#: help.c:385 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" databázový server ke kterému jste aktuálně připojeni\n" + +#: help.c:387 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" počet EOF znaků potřebných pro ukončení interaktivníhi sezení\n" + +#: help.c:389 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" hodnota posledního změněného OID\n" + +#: help.c:391 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" zpráva a SQLSTATE poslední chyby, nebo prázdný řetězec a \"00000\" pokud se chyba nevyskytla\n" + +#: help.c:394 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" pokud nastaveno, chyba nepřeruší transakci (používá implicitní savepointy)\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" zastaví dávkové spouštění v případě výskytu chyby\n" + +#: help.c:398 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" port na serveru používaný aktuálním spojením\n" + +#: help.c:400 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" specifikuje standardní psql prompt\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" specifikuje prompt používaný pokud příkaz pokračuje z předchozí řádky\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" specifikuje prompt používaný během COPY ... FROM STDIN\n" + +#: help.c:406 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" tichý běh (stejné jako volba -q)\n" + +#: help.c:408 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" počet řádek vrácených nebo ovlivněných předchozím dotazem, nebo 0\n" + +#: help.c:410 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" verze serveru (v krátkém textovém nebo numerickém formátu)\n" + +#: help.c:413 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" určuje zobrazení informací o kontextu zpráv [never, errors, always]\n" + +#: help.c:415 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" pokud nastaveno, konec řádky ukončuje SQL příkazy (stejné jako volba -S)\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" single-step mód (stejné jako volba -s)\n" + +#: help.c:419 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE posledního dotazu, nebo \"00000\" pokud skončil bez chyby\n" + +#: help.c:421 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" uživatelský účet ke kterému jste aktuálně připojeni\n" + +#: help.c:423 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" určuje podrobnost chybových hlášení [default, verbose, terse, sqlstate]\n" +"\n" + +#: help.c:425 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" verze psql (v podropbném řetězci, krátkém řetězci, nebo numerickém formátu)\n" + +#: help.c:430 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Nastavení zobrazení:\n" + +#: help.c:432 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NAME[=VALUE]\n" +" nebo \\pset NAME [VALUE] v psql\n" +"\n" + +#: help.c:434 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" styl rámečků (číslo)\n" + +#: help.c:436 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" cílová šířka pro zalomený formát\n" + +#: help.c:438 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (nebo x)\n" +" rozšířený výstup [on, off, auto]\n" + +#: help.c:440 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" oddělovač položek pro nezarovnaný výstup (výchozí \"%s\")\n" + +#: help.c:443 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" nastaví oddělovač polí pro nezarovnaný výstup na nulový byte\n" + +#: help.c:445 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" zapne nebo vypne zobrazení zápatí tabulky [on, off]\n" + +#: help.c:447 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" nastaví formát výstupu [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:449 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestype\n" +" nastaví styl vykreslování rámečků [ascii, old-ascii, unicode]\n" + +#: help.c:451 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" nastaví řetězec vypisovaný místo null hodnoty\n" + +#: help.c:453 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +" numericlocale\n" +" zapne zobrazení lokalizovaného znaku pro oddělení skupin číslic\n" + +#: help.c:455 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" určuje kdy se použije externí pager [yes, no, always]\n" + +#: help.c:457 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" oddělovač záznamů (řádek) pro nezarovnaný výstup\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" nastaví oddělovač záznamů pro nezarovnaný výstup na nulový byte\n" + +#: help.c:461 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (or T)\n" +" specifikuje attributy pro table tag v html formátu, nebo proporcionální\n" +" šířky sloupců pro datové typy zarovnávané doleva v latex-longtable formátu\n" + +#: help.c:464 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" nastavuje titulek tabulky pro následně vypisované tabulky\n" + +#: help.c:466 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" pokud nastaveno, jsou vypsána pouze data z tabulky\n" + +#: help.c:468 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" nastaví styl Unicode rámečků [single, double]\n" + +#: help.c:473 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Proměnné prostředí:\n" + +#: help.c:477 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" nebo \\setenv NAME [VALUE] v rámci psql\n" +"\n" + +#: help.c:479 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NAME=VALUE\n" +" psql ...\n" +" nebo \\setenv NAME [VALUE] v rámci psql\n" +"\n" + +#: help.c:482 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" počet sloupců pro zalamovaný formát\n" + +#: help.c:484 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" stejné jako application_name v parametrech spojení\n" + +#: help.c:486 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" stejné jako dbname v parametrech spojení\n" + +#: help.c:488 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" stejné jako host v parametrech spojení\n" + +#: help.c:490 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" heslo pro spojení (nedoporučuje se)\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" jméno souboru s hesly\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" stejné jako port v parametrech spojení\n" + +#: help.c:496 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" stejné jako user v parametrech spojení\n" + +#: help.c:498 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor používaný příkazy \\e, \\ef, a \\ev\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" jak specifikovat číslo řádky při spouštění editoru\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" alternativní umístění pro soubor s historií příkazů\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" jméno externího stránkovacího programu (pageru)\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" alternativní umístění uživatelova .psqlrc souboru\n" + +#: help.c:508 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" shell používaný \\! příkazem\n" + +#: help.c:510 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" adresář pro dočasné soubory\n" + +#: help.c:554 +msgid "Available help:\n" +msgstr "Dostupná nápověda:\n" + +#: help.c:642 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"Příkaz: %s\n" +"Popis: %s\n" +"Syntaxe:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" + +#: help.c:661 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"Nápověda pro \"%s\" je nedostupná.\n" +"Pomocí \\h bez parametrů lze získat seznam dostupných nápověd.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "nelze číst vstupní soubor: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "nelze uložit historii do souboru \"%s\": %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "historie není podporována pro tuto instalaci" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: není spojení s databází" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: současná transakce je přerušena (abort)" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: neznámý status transakce" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "Velké objekty (LO)" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if: escapované" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "Použijte \"\\q\" pro odchod z %s.\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Na vstupu je dump v PostgreSQL \"custom\" formátu.\n" +"Pro obnovení této zálohy použijte klienta pg_restore pro příkazovou řádku.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Použijte \\? pro nápovědu nebo stiskněte control-C pro vymazání vstupního bufferu." + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "Pro zobrazení nápovědy použijte \"\\?\"." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "Používáte psql, řádkový nástroj pro připojení k PostgreSQL." + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Pište: \\copyright pro podmínky distribuce\n" +" \\h pro nápovědu k SQL příkazům\n" +" \\? pro nápovědu k psql příkazům\n" +" \\g nebo středník pro ukončení SQL příkazů\n" +" \\q pro ukončení programu\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "Použijte \\q pro ukončení." + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "Použijte control-D pro ukončení." + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "Použijte control-C pro ukončení." + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "dotaz ignorován; použijte \\endif nebo Ctrl-C pro ukončení aktuálního \\if bloku" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "dosažen EOF bez nalezení ukončujícího \\endif(s)" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "neukončený řetězec v uvozovkách" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: nedostatek paměti" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1090 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 +#: sql_help.c:1112 sql_help.c:1114 sql_help.c:1118 sql_help.c:1121 +#: sql_help.c:1122 sql_help.c:1123 sql_help.c:1126 sql_help.c:1128 +#: sql_help.c:1262 sql_help.c:1264 sql_help.c:1267 sql_help.c:1270 +#: sql_help.c:1272 sql_help.c:1274 sql_help.c:1277 sql_help.c:1280 +#: sql_help.c:1391 sql_help.c:1393 sql_help.c:1395 sql_help.c:1398 +#: sql_help.c:1419 sql_help.c:1422 sql_help.c:1425 sql_help.c:1428 +#: sql_help.c:1432 sql_help.c:1434 sql_help.c:1436 sql_help.c:1438 +#: sql_help.c:1452 sql_help.c:1455 sql_help.c:1457 sql_help.c:1459 +#: sql_help.c:1469 sql_help.c:1471 sql_help.c:1481 sql_help.c:1483 +#: sql_help.c:1493 sql_help.c:1496 sql_help.c:1519 sql_help.c:1521 +#: sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 sql_help.c:1530 +#: sql_help.c:1533 sql_help.c:1536 sql_help.c:1586 sql_help.c:1629 +#: sql_help.c:1632 sql_help.c:1634 sql_help.c:1636 sql_help.c:1639 +#: sql_help.c:1641 sql_help.c:1643 sql_help.c:1646 sql_help.c:1696 +#: sql_help.c:1712 sql_help.c:1933 sql_help.c:2002 sql_help.c:2021 +#: sql_help.c:2034 sql_help.c:2091 sql_help.c:2098 sql_help.c:2108 +#: sql_help.c:2129 sql_help.c:2155 sql_help.c:2173 sql_help.c:2200 +#: sql_help.c:2295 sql_help.c:2340 sql_help.c:2364 sql_help.c:2387 +#: sql_help.c:2391 sql_help.c:2425 sql_help.c:2445 sql_help.c:2467 +#: sql_help.c:2481 sql_help.c:2501 sql_help.c:2524 sql_help.c:2554 +#: sql_help.c:2579 sql_help.c:2625 sql_help.c:2903 sql_help.c:2916 +#: sql_help.c:2933 sql_help.c:2949 sql_help.c:2989 sql_help.c:3041 +#: sql_help.c:3045 sql_help.c:3047 sql_help.c:3053 sql_help.c:3071 +#: sql_help.c:3098 sql_help.c:3133 sql_help.c:3145 sql_help.c:3154 +#: sql_help.c:3198 sql_help.c:3212 sql_help.c:3240 sql_help.c:3248 +#: sql_help.c:3260 sql_help.c:3270 sql_help.c:3278 sql_help.c:3286 +#: sql_help.c:3294 sql_help.c:3302 sql_help.c:3311 sql_help.c:3322 +#: sql_help.c:3330 sql_help.c:3338 sql_help.c:3346 sql_help.c:3354 +#: sql_help.c:3364 sql_help.c:3373 sql_help.c:3382 sql_help.c:3390 +#: sql_help.c:3400 sql_help.c:3411 sql_help.c:3419 sql_help.c:3428 +#: sql_help.c:3439 sql_help.c:3448 sql_help.c:3456 sql_help.c:3464 +#: sql_help.c:3472 sql_help.c:3480 sql_help.c:3488 sql_help.c:3496 +#: sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 sql_help.c:3528 +#: sql_help.c:3545 sql_help.c:3554 sql_help.c:3562 sql_help.c:3579 +#: sql_help.c:3594 sql_help.c:3869 sql_help.c:3920 sql_help.c:3949 +#: sql_help.c:3962 sql_help.c:4407 sql_help.c:4455 sql_help.c:4596 +msgid "name" +msgstr "jméno" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1783 +#: sql_help.c:3213 sql_help.c:4193 +msgid "aggregate_signature" +msgstr "aggregate_signature" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1093 sql_help.c:1129 sql_help.c:1271 sql_help.c:1392 +#: sql_help.c:1435 sql_help.c:1456 sql_help.c:1470 sql_help.c:1482 +#: sql_help.c:1495 sql_help.c:1522 sql_help.c:1587 sql_help.c:1640 +msgid "new_name" +msgstr "nové_jméno" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1091 sql_help.c:1127 sql_help.c:1332 +#: sql_help.c:1394 sql_help.c:1437 sql_help.c:1458 sql_help.c:1520 +#: sql_help.c:1635 sql_help.c:2889 +msgid "new_owner" +msgstr "nový_vlastník" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1095 +#: sql_help.c:1273 sql_help.c:1439 sql_help.c:1460 sql_help.c:1472 +#: sql_help.c:1484 sql_help.c:1524 sql_help.c:1642 +msgid "new_schema" +msgstr "nové_schéma" + +#: sql_help.c:44 sql_help.c:1847 sql_help.c:3214 sql_help.c:4222 +msgid "where aggregate_signature is:" +msgstr "kde aggregate_signature je:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1801 +#: sql_help.c:1818 sql_help.c:1824 sql_help.c:1848 sql_help.c:1851 +#: sql_help.c:1854 sql_help.c:2003 sql_help.c:2022 sql_help.c:2025 +#: sql_help.c:2296 sql_help.c:2502 sql_help.c:3215 sql_help.c:3218 +#: sql_help.c:3221 sql_help.c:3312 sql_help.c:3401 sql_help.c:3429 +#: sql_help.c:3753 sql_help.c:4101 sql_help.c:4199 sql_help.c:4206 +#: sql_help.c:4212 sql_help.c:4223 sql_help.c:4226 sql_help.c:4229 +msgid "argmode" +msgstr "mód_argumentu" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1802 +#: sql_help.c:1819 sql_help.c:1825 sql_help.c:1849 sql_help.c:1852 +#: sql_help.c:1855 sql_help.c:2004 sql_help.c:2023 sql_help.c:2026 +#: sql_help.c:2297 sql_help.c:2503 sql_help.c:3216 sql_help.c:3219 +#: sql_help.c:3222 sql_help.c:3313 sql_help.c:3402 sql_help.c:3430 +#: sql_help.c:4200 sql_help.c:4207 sql_help.c:4213 sql_help.c:4224 +#: sql_help.c:4227 sql_help.c:4230 +msgid "argname" +msgstr "jméno_argumentu" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1803 +#: sql_help.c:1820 sql_help.c:1826 sql_help.c:1850 sql_help.c:1853 +#: sql_help.c:1856 sql_help.c:2298 sql_help.c:2504 sql_help.c:3217 +#: sql_help.c:3220 sql_help.c:3223 sql_help.c:3314 sql_help.c:3403 +#: sql_help.c:3431 sql_help.c:4201 sql_help.c:4208 sql_help.c:4214 +#: sql_help.c:4225 sql_help.c:4228 sql_help.c:4231 +msgid "argtype" +msgstr "typ_argumentu" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1453 sql_help.c:1581 sql_help.c:1613 +#: sql_help.c:1665 sql_help.c:1904 sql_help.c:1911 sql_help.c:2203 +#: sql_help.c:2245 sql_help.c:2252 sql_help.c:2261 sql_help.c:2341 +#: sql_help.c:2555 sql_help.c:2647 sql_help.c:2918 sql_help.c:3099 +#: sql_help.c:3121 sql_help.c:3261 sql_help.c:3616 sql_help.c:3788 +#: sql_help.c:3961 sql_help.c:4658 +msgid "option" +msgstr "volba" + +#: sql_help.c:113 sql_help.c:927 sql_help.c:1582 sql_help.c:2342 +#: sql_help.c:2556 sql_help.c:3100 sql_help.c:3262 +msgid "where option can be:" +msgstr "kde volba může být:" + +#: sql_help.c:114 sql_help.c:2137 +msgid "allowconn" +msgstr "allowconn" + +#: sql_help.c:115 sql_help.c:928 sql_help.c:1583 sql_help.c:2138 +#: sql_help.c:2343 sql_help.c:2557 sql_help.c:3101 +msgid "connlimit" +msgstr "connlimit" + +#: sql_help.c:116 sql_help.c:2139 +msgid "istemplate" +msgstr "istemplate" + +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1276 sql_help.c:1325 +msgid "new_tablespace" +msgstr "nový_tablespace" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1140 sql_help.c:1143 sql_help.c:1590 +#: sql_help.c:1594 sql_help.c:1597 sql_help.c:2308 sql_help.c:2508 +#: sql_help.c:3980 sql_help.c:4396 +msgid "configuration_parameter" +msgstr "konfigurační_parametr" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1117 sql_help.c:1120 sql_help.c:1125 sql_help.c:1141 +#: sql_help.c:1142 sql_help.c:1307 sql_help.c:1327 sql_help.c:1375 +#: sql_help.c:1397 sql_help.c:1454 sql_help.c:1538 sql_help.c:1591 +#: sql_help.c:1614 sql_help.c:2204 sql_help.c:2246 sql_help.c:2253 +#: sql_help.c:2262 sql_help.c:2309 sql_help.c:2310 sql_help.c:2372 +#: sql_help.c:2375 sql_help.c:2409 sql_help.c:2509 sql_help.c:2510 +#: sql_help.c:2527 sql_help.c:2648 sql_help.c:2678 sql_help.c:2783 +#: sql_help.c:2796 sql_help.c:2810 sql_help.c:2851 sql_help.c:2875 +#: sql_help.c:2892 sql_help.c:2919 sql_help.c:3122 sql_help.c:3789 +#: sql_help.c:4397 sql_help.c:4398 +msgid "value" +msgstr "hodnota" + +#: sql_help.c:197 +msgid "target_role" +msgstr "cílová_role" + +#: sql_help.c:198 sql_help.c:2188 sql_help.c:2603 sql_help.c:2608 +#: sql_help.c:3735 sql_help.c:3742 sql_help.c:3756 sql_help.c:3762 +#: sql_help.c:4083 sql_help.c:4090 sql_help.c:4104 sql_help.c:4110 +msgid "schema_name" +msgstr "jméno_schématu" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "zkrácený_grant_nebo_revoke" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "kde zkrácený_grant_nebo_revoke je jedno z:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1275 sql_help.c:1601 sql_help.c:2346 sql_help.c:2347 +#: sql_help.c:2348 sql_help.c:2349 sql_help.c:2350 sql_help.c:2483 +#: sql_help.c:2560 sql_help.c:2561 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 sql_help.c:3104 sql_help.c:3105 sql_help.c:3106 +#: sql_help.c:3107 sql_help.c:3108 sql_help.c:3768 sql_help.c:3772 +#: sql_help.c:4116 sql_help.c:4120 sql_help.c:4417 +msgid "role_name" +msgstr "jméno_role" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1342 sql_help.c:1354 sql_help.c:1379 sql_help.c:1631 +#: sql_help.c:2158 sql_help.c:2162 sql_help.c:2265 sql_help.c:2270 +#: sql_help.c:2368 sql_help.c:2778 sql_help.c:2791 sql_help.c:2805 +#: sql_help.c:2814 sql_help.c:2826 sql_help.c:2855 sql_help.c:3820 +#: sql_help.c:3835 sql_help.c:3837 sql_help.c:4282 sql_help.c:4283 +#: sql_help.c:4292 sql_help.c:4333 sql_help.c:4334 sql_help.c:4335 +#: sql_help.c:4336 sql_help.c:4337 sql_help.c:4338 sql_help.c:4371 +#: sql_help.c:4372 sql_help.c:4377 sql_help.c:4382 sql_help.c:4521 +#: sql_help.c:4522 sql_help.c:4531 sql_help.c:4572 sql_help.c:4573 +#: sql_help.c:4574 sql_help.c:4575 sql_help.c:4576 sql_help.c:4577 +#: sql_help.c:4624 sql_help.c:4626 sql_help.c:4685 sql_help.c:4741 +#: sql_help.c:4742 sql_help.c:4751 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +msgid "expression" +msgstr "výraz" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "omezení_domény" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1268 sql_help.c:1313 sql_help.c:1314 sql_help.c:1315 +#: sql_help.c:1341 sql_help.c:1353 sql_help.c:1370 sql_help.c:1789 +#: sql_help.c:1791 sql_help.c:2161 sql_help.c:2264 sql_help.c:2269 +#: sql_help.c:2813 sql_help.c:2825 sql_help.c:3832 +msgid "constraint_name" +msgstr "jméno_omezení" + +#: sql_help.c:244 sql_help.c:1269 +msgid "new_constraint_name" +msgstr "jméno_nového_omezení" + +#: sql_help.c:317 sql_help.c:1073 +msgid "new_version" +msgstr "nová_verze" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "členský_objekt" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "kde členský_objekt je:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1781 sql_help.c:1786 sql_help.c:1793 +#: sql_help.c:1794 sql_help.c:1795 sql_help.c:1796 sql_help.c:1797 +#: sql_help.c:1798 sql_help.c:1799 sql_help.c:1804 sql_help.c:1806 +#: sql_help.c:1810 sql_help.c:1812 sql_help.c:1816 sql_help.c:1821 +#: sql_help.c:1822 sql_help.c:1829 sql_help.c:1830 sql_help.c:1831 +#: sql_help.c:1832 sql_help.c:1833 sql_help.c:1834 sql_help.c:1835 +#: sql_help.c:1836 sql_help.c:1837 sql_help.c:1838 sql_help.c:1839 +#: sql_help.c:1844 sql_help.c:1845 sql_help.c:4189 sql_help.c:4194 +#: sql_help.c:4195 sql_help.c:4196 sql_help.c:4197 sql_help.c:4203 +#: sql_help.c:4204 sql_help.c:4209 sql_help.c:4210 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4217 sql_help.c:4218 sql_help.c:4219 +#: sql_help.c:4220 +msgid "object_name" +msgstr "jméno_objektu" + +#: sql_help.c:326 sql_help.c:1782 sql_help.c:4192 +msgid "aggregate_name" +msgstr "aggregate_name" + +#: sql_help.c:328 sql_help.c:1784 sql_help.c:2068 sql_help.c:2072 +#: sql_help.c:2074 sql_help.c:3231 +msgid "source_type" +msgstr "zdrojový_typ" + +#: sql_help.c:329 sql_help.c:1785 sql_help.c:2069 sql_help.c:2073 +#: sql_help.c:2075 sql_help.c:3232 +msgid "target_type" +msgstr "cílový_typ" + +#: sql_help.c:336 sql_help.c:774 sql_help.c:1800 sql_help.c:2070 +#: sql_help.c:2111 sql_help.c:2176 sql_help.c:2426 sql_help.c:2457 +#: sql_help.c:2995 sql_help.c:4100 sql_help.c:4198 sql_help.c:4311 +#: sql_help.c:4315 sql_help.c:4319 sql_help.c:4322 sql_help.c:4550 +#: sql_help.c:4554 sql_help.c:4558 sql_help.c:4561 sql_help.c:4770 +#: sql_help.c:4774 sql_help.c:4778 sql_help.c:4781 +msgid "function_name" +msgstr "jméno_funkce" + +#: sql_help.c:341 sql_help.c:767 sql_help.c:1807 sql_help.c:2450 +msgid "operator_name" +msgstr "jméno_operátoru" + +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1808 +#: sql_help.c:2427 sql_help.c:3355 +msgid "left_type" +msgstr "levý_typ" + +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1809 +#: sql_help.c:2428 sql_help.c:3356 +msgid "right_type" +msgstr "pravý_typ" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1359 sql_help.c:1811 sql_help.c:1813 sql_help.c:2447 +#: sql_help.c:2468 sql_help.c:2831 sql_help.c:3365 sql_help.c:3374 +msgid "index_method" +msgstr "metoda_indexování" + +#: sql_help.c:349 sql_help.c:1817 sql_help.c:4205 +msgid "procedure_name" +msgstr "procedure_name" + +#: sql_help.c:353 sql_help.c:1823 sql_help.c:3752 sql_help.c:4211 +msgid "routine_name" +msgstr "routine_name" + +#: sql_help.c:365 sql_help.c:1331 sql_help.c:1840 sql_help.c:2304 +#: sql_help.c:2507 sql_help.c:2786 sql_help.c:2962 sql_help.c:3536 +#: sql_help.c:3766 sql_help.c:4114 +msgid "type_name" +msgstr "jméno_typu" + +#: sql_help.c:366 sql_help.c:1841 sql_help.c:2303 sql_help.c:2506 +#: sql_help.c:2963 sql_help.c:3189 sql_help.c:3537 sql_help.c:3758 +#: sql_help.c:4106 +msgid "lang_name" +msgstr "jméno_jazyka" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "a aggregate_signature je:" + +#: sql_help.c:392 sql_help.c:1935 sql_help.c:2201 +msgid "handler_function" +msgstr "handler_function" + +#: sql_help.c:393 sql_help.c:2202 +msgid "validator_function" +msgstr "validator_function" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1263 sql_help.c:1529 +msgid "action" +msgstr "akce" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1265 +#: sql_help.c:1283 sql_help.c:1287 sql_help.c:1288 sql_help.c:1292 +#: sql_help.c:1294 sql_help.c:1295 sql_help.c:1296 sql_help.c:1297 +#: sql_help.c:1299 sql_help.c:1302 sql_help.c:1303 sql_help.c:1305 +#: sql_help.c:1308 sql_help.c:1310 sql_help.c:1355 sql_help.c:1357 +#: sql_help.c:1364 sql_help.c:1373 sql_help.c:1378 sql_help.c:1630 +#: sql_help.c:1633 sql_help.c:1637 sql_help.c:1673 sql_help.c:1788 +#: sql_help.c:1901 sql_help.c:1907 sql_help.c:1920 sql_help.c:1921 +#: sql_help.c:1922 sql_help.c:2243 sql_help.c:2256 sql_help.c:2301 +#: sql_help.c:2367 sql_help.c:2373 sql_help.c:2406 sql_help.c:2633 +#: sql_help.c:2661 sql_help.c:2662 sql_help.c:2769 sql_help.c:2777 +#: sql_help.c:2787 sql_help.c:2790 sql_help.c:2800 sql_help.c:2804 +#: sql_help.c:2827 sql_help.c:2829 sql_help.c:2836 sql_help.c:2849 +#: sql_help.c:2854 sql_help.c:2872 sql_help.c:2998 sql_help.c:3134 +#: sql_help.c:3737 sql_help.c:3738 sql_help.c:3819 sql_help.c:3834 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:4085 sql_help.c:4086 +#: sql_help.c:4191 sql_help.c:4342 sql_help.c:4581 sql_help.c:4623 +#: sql_help.c:4625 sql_help.c:4627 sql_help.c:4673 sql_help.c:4801 +msgid "column_name" +msgstr "jméno_sloupce" + +#: sql_help.c:444 sql_help.c:664 sql_help.c:1266 sql_help.c:1638 +msgid "new_column_name" +msgstr "nové_jméno_sloupce" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1282 sql_help.c:1539 +msgid "where action is one of:" +msgstr "kde akce je jedno z:" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1284 +#: sql_help.c:1289 sql_help.c:1541 sql_help.c:1545 sql_help.c:2156 +#: sql_help.c:2244 sql_help.c:2446 sql_help.c:2626 sql_help.c:2770 +#: sql_help.c:3043 sql_help.c:3921 +msgid "data_type" +msgstr "datový_typ" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1285 sql_help.c:1290 +#: sql_help.c:1542 sql_help.c:1546 sql_help.c:2157 sql_help.c:2247 +#: sql_help.c:2369 sql_help.c:2771 sql_help.c:2779 sql_help.c:2792 +#: sql_help.c:2806 sql_help.c:3044 sql_help.c:3050 sql_help.c:3829 +msgid "collation" +msgstr "collation" + +#: sql_help.c:453 sql_help.c:1286 sql_help.c:2248 sql_help.c:2257 +#: sql_help.c:2772 sql_help.c:2788 sql_help.c:2801 +msgid "column_constraint" +msgstr "omezení_sloupce" + +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1304 sql_help.c:4670 +msgid "integer" +msgstr "integer" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1306 +#: sql_help.c:1309 +msgid "attribute_option" +msgstr "volba_atributu" + +#: sql_help.c:473 sql_help.c:1311 sql_help.c:2249 sql_help.c:2258 +#: sql_help.c:2773 sql_help.c:2789 sql_help.c:2802 +msgid "table_constraint" +msgstr "omezení_tabulky" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1316 +#: sql_help.c:1317 sql_help.c:1318 sql_help.c:1319 sql_help.c:1842 +msgid "trigger_name" +msgstr "jméno_triggeru" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1329 sql_help.c:1330 +#: sql_help.c:2250 sql_help.c:2255 sql_help.c:2776 sql_help.c:2799 +msgid "parent_table" +msgstr "nadřízená_tabulka" + +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1498 sql_help.c:2187 +msgid "extension_name" +msgstr "název_extension" + +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2305 +msgid "execution_cost" +msgstr "execution_cost" + +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2306 +msgid "result_rows" +msgstr "výsledné_řádky" + +#: sql_help.c:543 sql_help.c:2307 +msgid "support_function" +msgstr "support_funkce" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1580 sql_help.c:1588 +#: sql_help.c:1592 sql_help.c:1595 sql_help.c:1598 sql_help.c:2604 +#: sql_help.c:2606 sql_help.c:2609 sql_help.c:2610 sql_help.c:3736 +#: sql_help.c:3740 sql_help.c:3743 sql_help.c:3745 sql_help.c:3747 +#: sql_help.c:3749 sql_help.c:3751 sql_help.c:3757 sql_help.c:3759 +#: sql_help.c:3761 sql_help.c:3763 sql_help.c:3765 sql_help.c:3767 +#: sql_help.c:3769 sql_help.c:3770 sql_help.c:4084 sql_help.c:4088 +#: sql_help.c:4091 sql_help.c:4093 sql_help.c:4095 sql_help.c:4097 +#: sql_help.c:4099 sql_help.c:4105 sql_help.c:4107 sql_help.c:4109 +#: sql_help.c:4111 sql_help.c:4113 sql_help.c:4115 sql_help.c:4117 +#: sql_help.c:4118 +msgid "role_specification" +msgstr "role_specification" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:1611 sql_help.c:2130 +#: sql_help.c:2612 sql_help.c:3119 sql_help.c:3570 sql_help.c:4427 +msgid "user_name" +msgstr "uživatel" + +#: sql_help.c:568 sql_help.c:945 sql_help.c:1600 sql_help.c:2611 +#: sql_help.c:3771 sql_help.c:4119 +msgid "where role_specification can be:" +msgstr "kde role_specification může být:" + +#: sql_help.c:570 +msgid "group_name" +msgstr "group_name" + +#: sql_help.c:591 sql_help.c:1376 sql_help.c:2136 sql_help.c:2376 +#: sql_help.c:2410 sql_help.c:2784 sql_help.c:2797 sql_help.c:2811 +#: sql_help.c:2852 sql_help.c:2876 sql_help.c:2888 sql_help.c:3764 +#: sql_help.c:4112 +msgid "tablespace_name" +msgstr "jméno_tablespace" + +#: sql_help.c:593 sql_help.c:681 sql_help.c:1324 sql_help.c:1333 +#: sql_help.c:1371 sql_help.c:1722 +msgid "index_name" +msgstr "jméno_indexu" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1326 +#: sql_help.c:1328 sql_help.c:1374 sql_help.c:2374 sql_help.c:2408 +#: sql_help.c:2782 sql_help.c:2795 sql_help.c:2809 sql_help.c:2850 +#: sql_help.c:2874 +msgid "storage_parameter" +msgstr "parametr_uložení" + +#: sql_help.c:602 +msgid "column_number" +msgstr "column_number" + +#: sql_help.c:626 sql_help.c:1805 sql_help.c:4202 +msgid "large_object_oid" +msgstr "oid_large_objektu" + +#: sql_help.c:713 sql_help.c:2431 +msgid "res_proc" +msgstr "res_proc" + +#: sql_help.c:714 sql_help.c:2432 +msgid "join_proc" +msgstr "join_proc" + +#: sql_help.c:766 sql_help.c:778 sql_help.c:2449 +msgid "strategy_number" +msgstr "číslo_strategie" + +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2451 sql_help.c:2452 +#: sql_help.c:2455 sql_help.c:2456 +msgid "op_type" +msgstr "typ_operátoru" + +#: sql_help.c:770 sql_help.c:2453 +msgid "sort_family_name" +msgstr "sort_family_name" + +#: sql_help.c:771 sql_help.c:781 sql_help.c:2454 +msgid "support_number" +msgstr "support_number" + +#: sql_help.c:775 sql_help.c:2071 sql_help.c:2458 sql_help.c:2965 +#: sql_help.c:2967 +msgid "argument_type" +msgstr "typ_argumentu" + +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1494 sql_help.c:1497 +#: sql_help.c:1672 sql_help.c:1721 sql_help.c:1790 sql_help.c:1815 +#: sql_help.c:1828 sql_help.c:1843 sql_help.c:1900 sql_help.c:1906 +#: sql_help.c:2242 sql_help.c:2254 sql_help.c:2365 sql_help.c:2405 +#: sql_help.c:2482 sql_help.c:2525 sql_help.c:2581 sql_help.c:2632 +#: sql_help.c:2663 sql_help.c:2768 sql_help.c:2785 sql_help.c:2798 +#: sql_help.c:2871 sql_help.c:2991 sql_help.c:3168 sql_help.c:3391 +#: sql_help.c:3440 sql_help.c:3546 sql_help.c:3734 sql_help.c:3739 +#: sql_help.c:3785 sql_help.c:3817 sql_help.c:4082 sql_help.c:4087 +#: sql_help.c:4190 sql_help.c:4297 sql_help.c:4299 sql_help.c:4348 +#: sql_help.c:4387 sql_help.c:4536 sql_help.c:4538 sql_help.c:4587 +#: sql_help.c:4621 sql_help.c:4672 sql_help.c:4756 sql_help.c:4758 +#: sql_help.c:4807 +msgid "table_name" +msgstr "jméno_tabulky" + +#: sql_help.c:811 sql_help.c:2484 +msgid "using_expression" +msgstr "using_expression" + +#: sql_help.c:812 sql_help.c:2485 +msgid "check_expression" +msgstr "check_expression" + +#: sql_help.c:886 sql_help.c:2526 +msgid "publication_parameter" +msgstr "publication_parameter" + +#: sql_help.c:929 sql_help.c:1584 sql_help.c:2344 sql_help.c:2558 +#: sql_help.c:3102 +msgid "password" +msgstr "heslo" + +#: sql_help.c:930 sql_help.c:1585 sql_help.c:2345 sql_help.c:2559 +#: sql_help.c:3103 +msgid "timestamp" +msgstr "timestamp" + +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1589 +#: sql_help.c:1593 sql_help.c:1596 sql_help.c:1599 sql_help.c:3744 +#: sql_help.c:4092 +msgid "database_name" +msgstr "jméno_databáze" + +#: sql_help.c:1048 sql_help.c:2627 +msgid "increment" +msgstr "inkrement" + +#: sql_help.c:1049 sql_help.c:2628 +msgid "minvalue" +msgstr "min_hodnota" + +#: sql_help.c:1050 sql_help.c:2629 +msgid "maxvalue" +msgstr "max_hodnota" + +#: sql_help.c:1051 sql_help.c:2630 sql_help.c:4295 sql_help.c:4385 +#: sql_help.c:4534 sql_help.c:4689 sql_help.c:4754 +msgid "start" +msgstr "start" + +#: sql_help.c:1052 sql_help.c:1301 +msgid "restart" +msgstr "restart" + +#: sql_help.c:1053 sql_help.c:2631 +msgid "cache" +msgstr "cache" + +#: sql_help.c:1097 +#| msgid "new_table" +msgid "new_target" +msgstr "nový_cíl" + +#: sql_help.c:1113 sql_help.c:2675 +msgid "conninfo" +msgstr "conninfo" + +#: sql_help.c:1115 sql_help.c:2676 +msgid "publication_name" +msgstr "publication_name" + +#: sql_help.c:1116 +msgid "set_publication_option" +msgstr "set_publication_option" + +#: sql_help.c:1119 +msgid "refresh_option" +msgstr "refresh_option" + +#: sql_help.c:1124 sql_help.c:2677 +msgid "subscription_parameter" +msgstr "subscription_parameter" + +#: sql_help.c:1278 sql_help.c:1281 +msgid "partition_name" +msgstr "partition_name" + +#: sql_help.c:1279 sql_help.c:2259 sql_help.c:2803 +msgid "partition_bound_spec" +msgstr "partition_bound_spec" + +#: sql_help.c:1298 sql_help.c:1345 sql_help.c:2817 +msgid "sequence_options" +msgstr "sequence_options" + +#: sql_help.c:1300 +msgid "sequence_option" +msgstr "sequence_option" + +#: sql_help.c:1312 +msgid "table_constraint_using_index" +msgstr "omezení_tabulky_s_využitím_indexu" + +#: sql_help.c:1320 sql_help.c:1321 sql_help.c:1322 sql_help.c:1323 +msgid "rewrite_rule_name" +msgstr "přepisovací_pravidlo" + +#: sql_help.c:1334 sql_help.c:2842 +msgid "and partition_bound_spec is:" +msgstr "a partition_bound_spec je:" + +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:2843 +#: sql_help.c:2844 sql_help.c:2845 +msgid "partition_bound_expr" +msgstr "partition_bound_expr" + +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:2846 sql_help.c:2847 +msgid "numeric_literal" +msgstr "numeric_literal" + +#: sql_help.c:1340 +msgid "and column_constraint is:" +msgstr "a column_constraint je:" + +#: sql_help.c:1343 sql_help.c:2266 sql_help.c:2299 sql_help.c:2505 +#: sql_help.c:2815 +msgid "default_expr" +msgstr "implicitní_výraz" + +#: sql_help.c:1344 sql_help.c:2267 sql_help.c:2816 +msgid "generation_expr" +msgstr "generation_expr" + +#: sql_help.c:1346 sql_help.c:1347 sql_help.c:1356 sql_help.c:1358 +#: sql_help.c:1362 sql_help.c:2818 sql_help.c:2819 sql_help.c:2828 +#: sql_help.c:2830 sql_help.c:2834 +msgid "index_parameters" +msgstr "parametry_indexu" + +#: sql_help.c:1348 sql_help.c:1365 sql_help.c:2820 sql_help.c:2837 +msgid "reftable" +msgstr "odkazovaná_tabulka" + +#: sql_help.c:1349 sql_help.c:1366 sql_help.c:2821 sql_help.c:2838 +msgid "refcolumn" +msgstr "odkazovaný_sloupec" + +#: sql_help.c:1350 sql_help.c:1351 sql_help.c:1367 sql_help.c:1368 +#: sql_help.c:2822 sql_help.c:2823 sql_help.c:2839 sql_help.c:2840 +msgid "referential_action" +msgstr "referential_action" + +#: sql_help.c:1352 sql_help.c:2268 sql_help.c:2824 +msgid "and table_constraint is:" +msgstr "a omezení_tabulky je:" + +#: sql_help.c:1360 sql_help.c:2832 +msgid "exclude_element" +msgstr "exclude_element" + +#: sql_help.c:1361 sql_help.c:2833 sql_help.c:4293 sql_help.c:4383 +#: sql_help.c:4532 sql_help.c:4687 sql_help.c:4752 +msgid "operator" +msgstr "operátor" + +#: sql_help.c:1363 sql_help.c:2377 sql_help.c:2835 +msgid "predicate" +msgstr "predikát" + +#: sql_help.c:1369 +msgid "and table_constraint_using_index is:" +msgstr "a omezení_tabulky_s_využitím_indexu je:" + +#: sql_help.c:1372 sql_help.c:2848 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "parametry_indexu v UNIQUE, PRIMARY KEY, a EXCLUDE omezeních jsou:" + +#: sql_help.c:1377 sql_help.c:2853 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "exclude_element v EXCLUDE omezení je:" + +#: sql_help.c:1380 sql_help.c:2370 sql_help.c:2780 sql_help.c:2793 +#: sql_help.c:2807 sql_help.c:2856 sql_help.c:3830 +msgid "opclass" +msgstr "třída_operátoru" + +#: sql_help.c:1396 sql_help.c:1399 sql_help.c:2891 +msgid "tablespace_option" +msgstr "volba_tablespace" + +#: sql_help.c:1420 sql_help.c:1423 sql_help.c:1429 sql_help.c:1433 +msgid "token_type" +msgstr "typ_tokenu" + +#: sql_help.c:1421 sql_help.c:1424 +msgid "dictionary_name" +msgstr "jméno_slovníku" + +#: sql_help.c:1426 sql_help.c:1430 +msgid "old_dictionary" +msgstr "starý_slovník" + +#: sql_help.c:1427 sql_help.c:1431 +msgid "new_dictionary" +msgstr "nový_slovník" + +#: sql_help.c:1526 sql_help.c:1540 sql_help.c:1543 sql_help.c:1544 +#: sql_help.c:3042 +msgid "attribute_name" +msgstr "jméno_atributu" + +#: sql_help.c:1527 +msgid "new_attribute_name" +msgstr "nové_jméno_atributu" + +#: sql_help.c:1531 sql_help.c:1535 +msgid "new_enum_value" +msgstr "nová_enum_hodnota" + +#: sql_help.c:1532 +msgid "neighbor_enum_value" +msgstr "neighbor_enum_value" + +#: sql_help.c:1534 +msgid "existing_enum_value" +msgstr "existing_enum_value" + +#: sql_help.c:1537 +#| msgid "operator" +msgid "property" +msgstr "vlastnost" + +#: sql_help.c:1612 sql_help.c:2251 sql_help.c:2260 sql_help.c:2643 +#: sql_help.c:3120 sql_help.c:3571 sql_help.c:3750 sql_help.c:3786 +#: sql_help.c:4098 +msgid "server_name" +msgstr "jméno_serveru" + +#: sql_help.c:1644 sql_help.c:1647 sql_help.c:3135 +msgid "view_option_name" +msgstr "název_volby_pohledu" + +#: sql_help.c:1645 sql_help.c:3136 +msgid "view_option_value" +msgstr "hodnota_volby_pohledu" + +#: sql_help.c:1666 sql_help.c:1667 sql_help.c:4659 sql_help.c:4660 +msgid "table_and_columns" +msgstr "table_and_columns" + +#: sql_help.c:1668 sql_help.c:1912 sql_help.c:3619 sql_help.c:3963 +#: sql_help.c:4661 +msgid "where option can be one of:" +msgstr "kde volba je jedno z:" + +#: sql_help.c:1669 sql_help.c:1670 sql_help.c:1914 sql_help.c:1917 +#: sql_help.c:2096 sql_help.c:3620 sql_help.c:3621 sql_help.c:3622 +#: sql_help.c:3623 sql_help.c:3624 sql_help.c:3625 sql_help.c:3626 +#: sql_help.c:3627 sql_help.c:4662 sql_help.c:4663 sql_help.c:4664 +#: sql_help.c:4665 sql_help.c:4666 sql_help.c:4667 sql_help.c:4668 +#: sql_help.c:4669 +msgid "boolean" +msgstr "boolean" + +#: sql_help.c:1671 sql_help.c:4671 +msgid "and table_and_columns is:" +msgstr "a table_and_columns je:" + +#: sql_help.c:1687 sql_help.c:4443 sql_help.c:4445 sql_help.c:4469 +msgid "transaction_mode" +msgstr "transakční_mód" + +#: sql_help.c:1688 sql_help.c:4446 sql_help.c:4470 +msgid "where transaction_mode is one of:" +msgstr "kde transakční_mód je jedno z:" + +#: sql_help.c:1697 sql_help.c:4303 sql_help.c:4312 sql_help.c:4316 +#: sql_help.c:4320 sql_help.c:4323 sql_help.c:4542 sql_help.c:4551 +#: sql_help.c:4555 sql_help.c:4559 sql_help.c:4562 sql_help.c:4762 +#: sql_help.c:4771 sql_help.c:4775 sql_help.c:4779 sql_help.c:4782 +msgid "argument" +msgstr "argument" + +#: sql_help.c:1787 +msgid "relation_name" +msgstr "název_relace" + +#: sql_help.c:1792 sql_help.c:3746 sql_help.c:4094 +msgid "domain_name" +msgstr "jméno_domény" + +#: sql_help.c:1814 +msgid "policy_name" +msgstr "policy_name" + +#: sql_help.c:1827 +msgid "rule_name" +msgstr "jméno_pravidla" + +#: sql_help.c:1846 +msgid "text" +msgstr "text" + +#: sql_help.c:1871 sql_help.c:3930 sql_help.c:4135 +msgid "transaction_id" +msgstr "id_transakce" + +#: sql_help.c:1902 sql_help.c:1909 sql_help.c:3856 +msgid "filename" +msgstr "jméno_souboru" + +#: sql_help.c:1903 sql_help.c:1910 sql_help.c:2583 sql_help.c:2584 +#: sql_help.c:2585 +msgid "command" +msgstr "příkaz" + +#: sql_help.c:1905 sql_help.c:2582 sql_help.c:2994 sql_help.c:3171 +#: sql_help.c:3840 sql_help.c:4286 sql_help.c:4288 sql_help.c:4376 +#: sql_help.c:4378 sql_help.c:4525 sql_help.c:4527 sql_help.c:4630 +#: sql_help.c:4745 sql_help.c:4747 +msgid "condition" +msgstr "podmínka" + +#: sql_help.c:1908 sql_help.c:2411 sql_help.c:2877 sql_help.c:3137 +#: sql_help.c:3155 sql_help.c:3821 +msgid "query" +msgstr "dotaz" + +#: sql_help.c:1913 +msgid "format_name" +msgstr "jméno_formátu" + +#: sql_help.c:1915 +msgid "delimiter_character" +msgstr "oddělovací_znak" + +#: sql_help.c:1916 +msgid "null_string" +msgstr "null_string" + +#: sql_help.c:1918 +msgid "quote_character" +msgstr "quote_character" + +#: sql_help.c:1919 +msgid "escape_character" +msgstr "escape_character" + +#: sql_help.c:1923 +msgid "encoding_name" +msgstr "název_kódování" + +#: sql_help.c:1934 +msgid "access_method_type" +msgstr "access_method_type" + +#: sql_help.c:2005 sql_help.c:2024 sql_help.c:2027 +msgid "arg_data_type" +msgstr "arg_data_type" + +#: sql_help.c:2006 sql_help.c:2028 sql_help.c:2036 +msgid "sfunc" +msgstr "sfunc" + +#: sql_help.c:2007 sql_help.c:2029 sql_help.c:2037 +msgid "state_data_type" +msgstr "datový_typ_stavu" + +#: sql_help.c:2008 sql_help.c:2030 sql_help.c:2038 +msgid "state_data_size" +msgstr "state_data_size" + +#: sql_help.c:2009 sql_help.c:2031 sql_help.c:2039 +msgid "ffunc" +msgstr "ffunc" + +#: sql_help.c:2010 sql_help.c:2040 +msgid "combinefunc" +msgstr "combinefunc" + +#: sql_help.c:2011 sql_help.c:2041 +msgid "serialfunc" +msgstr "serialfunc" + +#: sql_help.c:2012 sql_help.c:2042 +msgid "deserialfunc" +msgstr "deserialfunc" + +#: sql_help.c:2013 sql_help.c:2032 sql_help.c:2043 +msgid "initial_condition" +msgstr "výchozí_podmínka" + +#: sql_help.c:2014 sql_help.c:2044 +msgid "msfunc" +msgstr "msfunc" + +#: sql_help.c:2015 sql_help.c:2045 +msgid "minvfunc" +msgstr "minvfunc" + +#: sql_help.c:2016 sql_help.c:2046 +msgid "mstate_data_type" +msgstr "mstate_data_type" + +#: sql_help.c:2017 sql_help.c:2047 +msgid "mstate_data_size" +msgstr "mstate_data_size" + +#: sql_help.c:2018 sql_help.c:2048 +msgid "mffunc" +msgstr "mffunc" + +#: sql_help.c:2019 sql_help.c:2049 +msgid "minitial_condition" +msgstr "minitial_condition" + +#: sql_help.c:2020 sql_help.c:2050 +msgid "sort_operator" +msgstr "operátor_třídění" + +#: sql_help.c:2033 +msgid "or the old syntax" +msgstr "nebo stará syntaxe" + +#: sql_help.c:2035 +msgid "base_type" +msgstr "základní_typ" + +#: sql_help.c:2092 sql_help.c:2133 +msgid "locale" +msgstr "locale" + +#: sql_help.c:2093 sql_help.c:2134 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2094 sql_help.c:2135 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2095 sql_help.c:4188 +msgid "provider" +msgstr "provider" + +#: sql_help.c:2097 sql_help.c:2189 +msgid "version" +msgstr "verze" + +#: sql_help.c:2099 +msgid "existing_collation" +msgstr "existující_collation" + +#: sql_help.c:2109 +msgid "source_encoding" +msgstr "kódování_zdroje" + +#: sql_help.c:2110 +msgid "dest_encoding" +msgstr "kódování_cíle" + +#: sql_help.c:2131 sql_help.c:2917 +msgid "template" +msgstr "šablona" + +#: sql_help.c:2132 +msgid "encoding" +msgstr "kódování" + +#: sql_help.c:2159 +msgid "constraint" +msgstr "omezení" + +#: sql_help.c:2160 +msgid "where constraint is:" +msgstr "kde omezení je:" + +#: sql_help.c:2174 sql_help.c:2580 sql_help.c:2990 +msgid "event" +msgstr "událost" + +#: sql_help.c:2175 +msgid "filter_variable" +msgstr "filter_variable" + +#: sql_help.c:2263 sql_help.c:2812 +msgid "where column_constraint is:" +msgstr "kde omezení_sloupce je:" + +#: sql_help.c:2300 +msgid "rettype" +msgstr "návratový_typ" + +#: sql_help.c:2302 +msgid "column_type" +msgstr "typ_sloupce" + +#: sql_help.c:2311 sql_help.c:2511 +msgid "definition" +msgstr "definice" + +#: sql_help.c:2312 sql_help.c:2512 +msgid "obj_file" +msgstr "obj_file" + +#: sql_help.c:2313 sql_help.c:2513 +msgid "link_symbol" +msgstr "link_symbol" + +#: sql_help.c:2351 sql_help.c:2565 sql_help.c:3109 +msgid "uid" +msgstr "uid" + +#: sql_help.c:2366 sql_help.c:2407 sql_help.c:2781 sql_help.c:2794 +#: sql_help.c:2808 sql_help.c:2873 +msgid "method" +msgstr "metoda" + +#: sql_help.c:2371 +#| msgid "storage_parameter" +msgid "opclass_parameter" +msgstr "opclass_parametr" + +#: sql_help.c:2388 +msgid "call_handler" +msgstr "call_handler" + +#: sql_help.c:2389 +msgid "inline_handler" +msgstr "inline_handler" + +#: sql_help.c:2390 +msgid "valfunction" +msgstr "valfunction" + +#: sql_help.c:2429 +msgid "com_op" +msgstr "com_op" + +#: sql_help.c:2430 +msgid "neg_op" +msgstr "neg_op" + +#: sql_help.c:2448 +msgid "family_name" +msgstr "family_name" + +#: sql_help.c:2459 +msgid "storage_type" +msgstr "typ_uložení" + +#: sql_help.c:2586 sql_help.c:2997 +msgid "where event can be one of:" +msgstr "kde událost může být jedno z:" + +#: sql_help.c:2605 sql_help.c:2607 +msgid "schema_element" +msgstr "prvek_schématu" + +#: sql_help.c:2644 +msgid "server_type" +msgstr "typ_serveru" + +#: sql_help.c:2645 +msgid "server_version" +msgstr "verze_serveru" + +#: sql_help.c:2646 sql_help.c:3748 sql_help.c:4096 +msgid "fdw_name" +msgstr "fdw_jméno" + +#: sql_help.c:2659 +msgid "statistics_name" +msgstr "statistics_name" + +#: sql_help.c:2660 +msgid "statistics_kind" +msgstr "statistics_kind" + +#: sql_help.c:2674 +msgid "subscription_name" +msgstr "subscription_name" + +#: sql_help.c:2774 +msgid "source_table" +msgstr "zdrojová_tabulka" + +#: sql_help.c:2775 +msgid "like_option" +msgstr "like_volba" + +#: sql_help.c:2841 +msgid "and like_option is:" +msgstr "a like_volba je:" + +#: sql_help.c:2890 +msgid "directory" +msgstr "adresář" + +#: sql_help.c:2904 +msgid "parser_name" +msgstr "jméno_parseru" + +#: sql_help.c:2905 +msgid "source_config" +msgstr "source_config" + +#: sql_help.c:2934 +msgid "start_function" +msgstr "start_funkce" + +#: sql_help.c:2935 +msgid "gettoken_function" +msgstr "gettoken_funkce" + +#: sql_help.c:2936 +msgid "end_function" +msgstr "end_function" + +#: sql_help.c:2937 +msgid "lextypes_function" +msgstr "lextypes_funkce" + +#: sql_help.c:2938 +msgid "headline_function" +msgstr "headline_funkce" + +#: sql_help.c:2950 +msgid "init_function" +msgstr "init_funkce" + +#: sql_help.c:2951 +msgid "lexize_function" +msgstr "lexize_funkce" + +#: sql_help.c:2964 +msgid "from_sql_function_name" +msgstr "from_sql_function_name" + +#: sql_help.c:2966 +msgid "to_sql_function_name" +msgstr "to_sql_function_name" + +#: sql_help.c:2992 +msgid "referenced_table_name" +msgstr "jméno_odkazované_tabulky" + +#: sql_help.c:2993 +msgid "transition_relation_name" +msgstr "transition_relation_name" + +#: sql_help.c:2996 +msgid "arguments" +msgstr "argumenty" + +#: sql_help.c:3046 sql_help.c:4221 +msgid "label" +msgstr "popisek" + +#: sql_help.c:3048 +msgid "subtype" +msgstr "subtyp" + +#: sql_help.c:3049 +msgid "subtype_operator_class" +msgstr "třída_operátorů_subtypu" + +#: sql_help.c:3051 +msgid "canonical_function" +msgstr "kanonická_funkce" + +#: sql_help.c:3052 +msgid "subtype_diff_function" +msgstr "diff_funkce_subtypu" + +#: sql_help.c:3054 +msgid "input_function" +msgstr "vstupní_funkce" + +#: sql_help.c:3055 +msgid "output_function" +msgstr "výstupní_funkce" + +#: sql_help.c:3056 +msgid "receive_function" +msgstr "receive_funkce" + +#: sql_help.c:3057 +msgid "send_function" +msgstr "send_funkce" + +#: sql_help.c:3058 +msgid "type_modifier_input_function" +msgstr "type_modifier_input_function" + +#: sql_help.c:3059 +msgid "type_modifier_output_function" +msgstr "type_modifier_output_function" + +#: sql_help.c:3060 +msgid "analyze_function" +msgstr "analyze_funkce" + +#: sql_help.c:3061 +msgid "internallength" +msgstr "interní_délka" + +#: sql_help.c:3062 +msgid "alignment" +msgstr "zarovnání" + +#: sql_help.c:3063 +msgid "storage" +msgstr "uložení" + +#: sql_help.c:3064 +msgid "like_type" +msgstr "like_typ" + +#: sql_help.c:3065 +msgid "category" +msgstr "kategorie" + +#: sql_help.c:3066 +msgid "preferred" +msgstr "preferovaný" + +#: sql_help.c:3067 +msgid "default" +msgstr "implicitní" + +#: sql_help.c:3068 +msgid "element" +msgstr "prvek" + +#: sql_help.c:3069 +msgid "delimiter" +msgstr "oddělovač" + +#: sql_help.c:3070 +msgid "collatable" +msgstr "collatable" + +#: sql_help.c:3167 sql_help.c:3816 sql_help.c:4281 sql_help.c:4370 +#: sql_help.c:4520 sql_help.c:4620 sql_help.c:4740 +msgid "with_query" +msgstr "with_dotaz" + +#: sql_help.c:3169 sql_help.c:3818 sql_help.c:4300 sql_help.c:4306 +#: sql_help.c:4309 sql_help.c:4313 sql_help.c:4317 sql_help.c:4325 +#: sql_help.c:4539 sql_help.c:4545 sql_help.c:4548 sql_help.c:4552 +#: sql_help.c:4556 sql_help.c:4564 sql_help.c:4622 sql_help.c:4759 +#: sql_help.c:4765 sql_help.c:4768 sql_help.c:4772 sql_help.c:4776 +#: sql_help.c:4784 +msgid "alias" +msgstr "alias" + +#: sql_help.c:3170 sql_help.c:4285 sql_help.c:4327 sql_help.c:4329 +#: sql_help.c:4375 sql_help.c:4524 sql_help.c:4566 sql_help.c:4568 +#: sql_help.c:4629 sql_help.c:4744 sql_help.c:4786 sql_help.c:4788 +msgid "from_item" +msgstr "z_položky" + +#: sql_help.c:3172 sql_help.c:3653 sql_help.c:3897 sql_help.c:4631 +msgid "cursor_name" +msgstr "jméno_kurzoru" + +#: sql_help.c:3173 sql_help.c:3824 sql_help.c:4632 +msgid "output_expression" +msgstr "výstupní_výraz" + +#: sql_help.c:3174 sql_help.c:3825 sql_help.c:4284 sql_help.c:4373 +#: sql_help.c:4523 sql_help.c:4633 sql_help.c:4743 +msgid "output_name" +msgstr "výstupní_jméno" + +#: sql_help.c:3190 +msgid "code" +msgstr "kód" + +#: sql_help.c:3595 +msgid "parameter" +msgstr "parametr" + +#: sql_help.c:3617 sql_help.c:3618 sql_help.c:3922 +msgid "statement" +msgstr "příkaz" + +#: sql_help.c:3652 sql_help.c:3896 +msgid "direction" +msgstr "směr" + +#: sql_help.c:3654 sql_help.c:3898 +msgid "where direction can be empty or one of:" +msgstr "kde směr může být prázdný nebo jedno z:" + +#: sql_help.c:3655 sql_help.c:3656 sql_help.c:3657 sql_help.c:3658 +#: sql_help.c:3659 sql_help.c:3899 sql_help.c:3900 sql_help.c:3901 +#: sql_help.c:3902 sql_help.c:3903 sql_help.c:4294 sql_help.c:4296 +#: sql_help.c:4384 sql_help.c:4386 sql_help.c:4533 sql_help.c:4535 +#: sql_help.c:4688 sql_help.c:4690 sql_help.c:4753 sql_help.c:4755 +msgid "count" +msgstr "počet" + +#: sql_help.c:3741 sql_help.c:4089 +msgid "sequence_name" +msgstr "sekvence" + +#: sql_help.c:3754 sql_help.c:4102 +msgid "arg_name" +msgstr "jméno_argumentu" + +#: sql_help.c:3755 sql_help.c:4103 +msgid "arg_type" +msgstr "typ_argumentu" + +#: sql_help.c:3760 sql_help.c:4108 +msgid "loid" +msgstr "loid" + +#: sql_help.c:3784 +msgid "remote_schema" +msgstr "remote_schema" + +#: sql_help.c:3787 +msgid "local_schema" +msgstr "local_schema" + +#: sql_help.c:3822 +msgid "conflict_target" +msgstr "conflict_target" + +#: sql_help.c:3823 +msgid "conflict_action" +msgstr "conflict_action" + +#: sql_help.c:3826 +msgid "where conflict_target can be one of:" +msgstr "where conflict_target can be one of:" + +#: sql_help.c:3827 +msgid "index_column_name" +msgstr "index_column_name" + +#: sql_help.c:3828 +msgid "index_expression" +msgstr "index_expression" + +#: sql_help.c:3831 +msgid "index_predicate" +msgstr "index_predicate" + +#: sql_help.c:3833 +msgid "and conflict_action is one of:" +msgstr "a conflict_action je jedno z:" + +#: sql_help.c:3839 sql_help.c:4628 +msgid "sub-SELECT" +msgstr "sub-SELECT" + +#: sql_help.c:3848 sql_help.c:3911 sql_help.c:4604 +msgid "channel" +msgstr "kanál" + +#: sql_help.c:3870 +msgid "lockmode" +msgstr "mód_zámku" + +#: sql_help.c:3871 +msgid "where lockmode is one of:" +msgstr "kde mód_zámku je jedno z:" + +#: sql_help.c:3912 +msgid "payload" +msgstr "náklad" + +#: sql_help.c:3939 +msgid "old_role" +msgstr "stará_role" + +#: sql_help.c:3940 +msgid "new_role" +msgstr "nová_role" + +#: sql_help.c:3971 sql_help.c:4143 sql_help.c:4151 +msgid "savepoint_name" +msgstr "jméno_savepointu" + +#: sql_help.c:4287 sql_help.c:4339 sql_help.c:4526 sql_help.c:4578 +#: sql_help.c:4746 sql_help.c:4798 +msgid "grouping_element" +msgstr "grouping_element" + +#: sql_help.c:4289 sql_help.c:4379 sql_help.c:4528 sql_help.c:4748 +msgid "window_name" +msgstr "jméno_okna" + +#: sql_help.c:4290 sql_help.c:4380 sql_help.c:4529 sql_help.c:4749 +msgid "window_definition" +msgstr "definice_okna" + +#: sql_help.c:4291 sql_help.c:4305 sql_help.c:4343 sql_help.c:4381 +#: sql_help.c:4530 sql_help.c:4544 sql_help.c:4582 sql_help.c:4750 +#: sql_help.c:4764 sql_help.c:4802 +msgid "select" +msgstr "select" + +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4757 +msgid "where from_item can be one of:" +msgstr "kde z_položky může být jedno z:" + +#: sql_help.c:4301 sql_help.c:4307 sql_help.c:4310 sql_help.c:4314 +#: sql_help.c:4326 sql_help.c:4540 sql_help.c:4546 sql_help.c:4549 +#: sql_help.c:4553 sql_help.c:4565 sql_help.c:4760 sql_help.c:4766 +#: sql_help.c:4769 sql_help.c:4773 sql_help.c:4785 +msgid "column_alias" +msgstr "alias_sloupce" + +#: sql_help.c:4302 sql_help.c:4541 sql_help.c:4761 +msgid "sampling_method" +msgstr "sampling_method" + +#: sql_help.c:4304 sql_help.c:4543 sql_help.c:4763 +msgid "seed" +msgstr "seed" + +#: sql_help.c:4308 sql_help.c:4341 sql_help.c:4547 sql_help.c:4580 +#: sql_help.c:4767 sql_help.c:4800 +msgid "with_query_name" +msgstr "jméno_with_dotazu" + +#: sql_help.c:4318 sql_help.c:4321 sql_help.c:4324 sql_help.c:4557 +#: sql_help.c:4560 sql_help.c:4563 sql_help.c:4777 sql_help.c:4780 +#: sql_help.c:4783 +msgid "column_definition" +msgstr "definice_sloupce" + +#: sql_help.c:4328 sql_help.c:4567 sql_help.c:4787 +msgid "join_type" +msgstr "typ_joinu" + +#: sql_help.c:4330 sql_help.c:4569 sql_help.c:4789 +msgid "join_condition" +msgstr "joinovací_podmínka" + +#: sql_help.c:4331 sql_help.c:4570 sql_help.c:4790 +msgid "join_column" +msgstr "joinovací_sloupec" + +#: sql_help.c:4332 sql_help.c:4571 sql_help.c:4791 +msgid "and grouping_element can be one of:" +msgstr "a grouping_element může být jedno z:" + +#: sql_help.c:4340 sql_help.c:4579 sql_help.c:4799 +msgid "and with_query is:" +msgstr "a with_dotaz je:" + +#: sql_help.c:4344 sql_help.c:4583 sql_help.c:4803 +msgid "values" +msgstr "hodnoty" + +#: sql_help.c:4345 sql_help.c:4584 sql_help.c:4804 +msgid "insert" +msgstr "insert" + +#: sql_help.c:4346 sql_help.c:4585 sql_help.c:4805 +msgid "update" +msgstr "update" + +#: sql_help.c:4347 sql_help.c:4586 sql_help.c:4806 +msgid "delete" +msgstr "delete" + +#: sql_help.c:4374 +msgid "new_table" +msgstr "nová_tabulka" + +#: sql_help.c:4399 +msgid "timezone" +msgstr "časová_zóna" + +#: sql_help.c:4444 +msgid "snapshot_id" +msgstr "snapshot_id" + +#: sql_help.c:4686 +msgid "sort_expression" +msgstr "sort_expression" + +#: sql_help.c:4813 sql_help.c:5791 +msgid "abort the current transaction" +msgstr "nestandardní ukončení (abort) současné transakce" + +#: sql_help.c:4819 +msgid "change the definition of an aggregate function" +msgstr "změna definice agregátní funkce" + +#: sql_help.c:4825 +msgid "change the definition of a collation" +msgstr "změní definici collation" + +#: sql_help.c:4831 +msgid "change the definition of a conversion" +msgstr "změna definice konverze" + +#: sql_help.c:4837 +msgid "change a database" +msgstr "změní databázi" + +#: sql_help.c:4843 +msgid "define default access privileges" +msgstr "definuje výchozí přístupová práva" + +#: sql_help.c:4849 +msgid "change the definition of a domain" +msgstr "změní definici domény" + +#: sql_help.c:4855 +msgid "change the definition of an event trigger" +msgstr "změní definici event triggeru" + +#: sql_help.c:4861 +msgid "change the definition of an extension" +msgstr "změna definice extension" + +#: sql_help.c:4867 +msgid "change the definition of a foreign-data wrapper" +msgstr "změní definici foreign-data wrapperu" + +#: sql_help.c:4873 +msgid "change the definition of a foreign table" +msgstr "změní definici foreign tabulky" + +#: sql_help.c:4879 +msgid "change the definition of a function" +msgstr "změní definici funkce" + +#: sql_help.c:4885 +msgid "change role name or membership" +msgstr "změní jméno role nebo členství" + +#: sql_help.c:4891 +msgid "change the definition of an index" +msgstr "změní definici indexu" + +#: sql_help.c:4897 +msgid "change the definition of a procedural language" +msgstr "změní definici procedurálního jazyka" + +#: sql_help.c:4903 +msgid "change the definition of a large object" +msgstr "změní definici large objektu" + +#: sql_help.c:4909 +msgid "change the definition of a materialized view" +msgstr "změní definici materializovaného pohledu" + +#: sql_help.c:4915 +msgid "change the definition of an operator" +msgstr "změní definici operátoru" + +#: sql_help.c:4921 +msgid "change the definition of an operator class" +msgstr "změní definici třídy operátorů" + +#: sql_help.c:4927 +msgid "change the definition of an operator family" +msgstr "změní definici rodiny operátorů" + +#: sql_help.c:4933 +msgid "change the definition of a row level security policy" +msgstr "změní definici row level security politiky" + +#: sql_help.c:4939 +msgid "change the definition of a procedure" +msgstr "změní definici procedury" + +#: sql_help.c:4945 +msgid "change the definition of a publication" +msgstr "změní definici publikace" + +#: sql_help.c:4951 sql_help.c:5053 +msgid "change a database role" +msgstr "změní databázovou roli" + +#: sql_help.c:4957 +msgid "change the definition of a routine" +msgstr "změní definici rutiny" + +#: sql_help.c:4963 +msgid "change the definition of a rule" +msgstr "změní definici pravidla" + +#: sql_help.c:4969 +msgid "change the definition of a schema" +msgstr "změní definici schématu" + +#: sql_help.c:4975 +msgid "change the definition of a sequence generator" +msgstr "změní definici generátoru sekvencí" + +#: sql_help.c:4981 +msgid "change the definition of a foreign server" +msgstr "změní definici foreign serveru" + +#: sql_help.c:4987 +msgid "change the definition of an extended statistics object" +msgstr "změna definice rozšířené statistiky" + +#: sql_help.c:4993 +msgid "change the definition of a subscription" +msgstr "změní definici subskripce" + +#: sql_help.c:4999 +msgid "change a server configuration parameter" +msgstr "změní serverový konfigurační parametr" + +#: sql_help.c:5005 +msgid "change the definition of a table" +msgstr "změní definici tabulky" + +#: sql_help.c:5011 +msgid "change the definition of a tablespace" +msgstr "změní definici tablespace" + +#: sql_help.c:5017 +msgid "change the definition of a text search configuration" +msgstr "změní definici konfigurace fulltextového vyhledávání" + +#: sql_help.c:5023 +msgid "change the definition of a text search dictionary" +msgstr "změní definici slovníku pro fulltextové vyhledávání" + +#: sql_help.c:5029 +msgid "change the definition of a text search parser" +msgstr "změní definici parseru pro fulltextové vyhledávání" + +#: sql_help.c:5035 +msgid "change the definition of a text search template" +msgstr "změní definici šablony pro fulltextové vyhledávání" + +#: sql_help.c:5041 +msgid "change the definition of a trigger" +msgstr "změní definici triggeru" + +#: sql_help.c:5047 +msgid "change the definition of a type" +msgstr "změní definici datového typu" + +#: sql_help.c:5059 +msgid "change the definition of a user mapping" +msgstr "změní definici mapování uživatelů" + +#: sql_help.c:5065 +msgid "change the definition of a view" +msgstr "změní definici pohledu" + +#: sql_help.c:5071 +msgid "collect statistics about a database" +msgstr "shromáždí statistické informace o databázi" + +#: sql_help.c:5077 sql_help.c:5869 +msgid "start a transaction block" +msgstr "nastartuje nový transakční blok" + +#: sql_help.c:5083 +msgid "invoke a procedure" +msgstr "spustí proceduru" + +#: sql_help.c:5089 +msgid "force a write-ahead log checkpoint" +msgstr "vynutí checkpoint transakčního logu" + +#: sql_help.c:5095 +msgid "close a cursor" +msgstr "uzavře kursor" + +#: sql_help.c:5101 +msgid "cluster a table according to an index" +msgstr "přerovná obsah tabulky dle indexu" + +#: sql_help.c:5107 +msgid "define or change the comment of an object" +msgstr "definuje nebo změní komentář objektu" + +#: sql_help.c:5113 sql_help.c:5671 +msgid "commit the current transaction" +msgstr "potvrzení aktuální transakce" + +#: sql_help.c:5119 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "potvrzení aktuální transakce, která byla již dříve připravena pro dvoufázový commit" + +#: sql_help.c:5125 +msgid "copy data between a file and a table" +msgstr "kopíruje data mezi souborem a tabulkou" + +#: sql_help.c:5131 +msgid "define a new access method" +msgstr "definuje novou přístupovou metodu" + +#: sql_help.c:5137 +msgid "define a new aggregate function" +msgstr "definuje novou agrefunkci" + +#: sql_help.c:5143 +msgid "define a new cast" +msgstr "definuje nové přetypování" + +#: sql_help.c:5149 +msgid "define a new collation" +msgstr "definuje novou collation" + +#: sql_help.c:5155 +msgid "define a new encoding conversion" +msgstr "definuje novou konverzi kódování" + +#: sql_help.c:5161 +msgid "create a new database" +msgstr "vytvoří novou databázi" + +#: sql_help.c:5167 +msgid "define a new domain" +msgstr "definuje novou atributovou doménu" + +#: sql_help.c:5173 +msgid "define a new event trigger" +msgstr "definuje nový event trigger" + +#: sql_help.c:5179 +msgid "install an extension" +msgstr "instaluje rozšíření" + +#: sql_help.c:5185 +msgid "define a new foreign-data wrapper" +msgstr "definuje nový foreign-data wrapper" + +#: sql_help.c:5191 +msgid "define a new foreign table" +msgstr "definuje nový foreign tabulku" + +#: sql_help.c:5197 +msgid "define a new function" +msgstr "definuje novou funkci" + +#: sql_help.c:5203 sql_help.c:5263 sql_help.c:5365 +msgid "define a new database role" +msgstr "definuje novou databázovou roli" + +#: sql_help.c:5209 +msgid "define a new index" +msgstr "definuje nový index" + +#: sql_help.c:5215 +msgid "define a new procedural language" +msgstr "definuje nový procedurální jazyk" + +#: sql_help.c:5221 +msgid "define a new materialized view" +msgstr "definuje nový materializovaný pohled" + +#: sql_help.c:5227 +msgid "define a new operator" +msgstr "definuje nový operátor" + +#: sql_help.c:5233 +msgid "define a new operator class" +msgstr "definuje novou třídu operátorů" + +#: sql_help.c:5239 +msgid "define a new operator family" +msgstr "definuje novou rodinu operátorů" + +#: sql_help.c:5245 +msgid "define a new row level security policy for a table" +msgstr "definute novou row level security politiku pro tabulku" + +#: sql_help.c:5251 +msgid "define a new procedure" +msgstr "definuje novou proceduru" + +#: sql_help.c:5257 +msgid "define a new publication" +msgstr "definuje novou publikaci" + +#: sql_help.c:5269 +msgid "define a new rewrite rule" +msgstr "definuje nové přepisovací pravidlo (rule)" + +#: sql_help.c:5275 +msgid "define a new schema" +msgstr "definuje nové schéma" + +#: sql_help.c:5281 +msgid "define a new sequence generator" +msgstr "definuje nový generátor sekvencí" + +#: sql_help.c:5287 +msgid "define a new foreign server" +msgstr "definuje nový foreign server" + +#: sql_help.c:5293 +msgid "define extended statistics" +msgstr "definuje nové rozšířené statistiky" + +#: sql_help.c:5299 +msgid "define a new subscription" +msgstr "definuje novou subskripci" + +#: sql_help.c:5305 +msgid "define a new table" +msgstr "definuje novou tabulku" + +#: sql_help.c:5311 sql_help.c:5827 +msgid "define a new table from the results of a query" +msgstr "definuje novou tabulku dle výsledku dotazu" + +#: sql_help.c:5317 +msgid "define a new tablespace" +msgstr "definuje nový tablespace" + +#: sql_help.c:5323 +msgid "define a new text search configuration" +msgstr "definuje novou konfiguraci fulltextového vyhledávání" + +#: sql_help.c:5329 +msgid "define a new text search dictionary" +msgstr "definuje nový slovník pro fulltextové vyhledávání" + +#: sql_help.c:5335 +msgid "define a new text search parser" +msgstr "definuje nový parser pro fulltextové vyhledávání" + +#: sql_help.c:5341 +msgid "define a new text search template" +msgstr "definuje novou šablonu pro fulltextové vyhledávání" + +#: sql_help.c:5347 +msgid "define a new transform" +msgstr "definuje novou transformaci" + +#: sql_help.c:5353 +msgid "define a new trigger" +msgstr "definuje nový trigger" + +#: sql_help.c:5359 +msgid "define a new data type" +msgstr "definuje nový datový typ" + +#: sql_help.c:5371 +msgid "define a new mapping of a user to a foreign server" +msgstr "definuje nové mapování uživatele na vzdálený server" + +#: sql_help.c:5377 +msgid "define a new view" +msgstr "definuje nový pohled" + +#: sql_help.c:5383 +msgid "deallocate a prepared statement" +msgstr "dealokuje připravený dotaz (prepared statement)" + +#: sql_help.c:5389 +msgid "define a cursor" +msgstr "definuje kursor" + +#: sql_help.c:5395 +msgid "delete rows of a table" +msgstr "smaže řádky z takulky" + +#: sql_help.c:5401 +msgid "discard session state" +msgstr "zahodí stav session" + +#: sql_help.c:5407 +msgid "execute an anonymous code block" +msgstr "spustí anonymní blok kódu" + +#: sql_help.c:5413 +msgid "remove an access method" +msgstr "odstraní definici přístupové metody" + +#: sql_help.c:5419 +msgid "remove an aggregate function" +msgstr "odstraní agregační funkci" + +#: sql_help.c:5425 +msgid "remove a cast" +msgstr "odstraní definici přetypování" + +#: sql_help.c:5431 +msgid "remove a collation" +msgstr "odstraní collation" + +#: sql_help.c:5437 +msgid "remove a conversion" +msgstr "odstraní konverzi" + +#: sql_help.c:5443 +msgid "remove a database" +msgstr "odstraní databázi" + +#: sql_help.c:5449 +msgid "remove a domain" +msgstr "odstraní doménu" + +#: sql_help.c:5455 +msgid "remove an event trigger" +msgstr "odstraní event trigger" + +#: sql_help.c:5461 +msgid "remove an extension" +msgstr "odstraní extension" + +#: sql_help.c:5467 +msgid "remove a foreign-data wrapper" +msgstr "odstraní foreign-data wrapper" + +#: sql_help.c:5473 +msgid "remove a foreign table" +msgstr "odstraní foreign tabulku" + +#: sql_help.c:5479 +msgid "remove a function" +msgstr "odstraní funkci" + +#: sql_help.c:5485 sql_help.c:5551 sql_help.c:5653 +msgid "remove a database role" +msgstr "odstraní databázovou roli" + +#: sql_help.c:5491 +msgid "remove an index" +msgstr "odstraní index" + +#: sql_help.c:5497 +msgid "remove a procedural language" +msgstr "odstraní procedurální jazyk" + +#: sql_help.c:5503 +msgid "remove a materialized view" +msgstr "odstraní materializovaný pohled" + +#: sql_help.c:5509 +msgid "remove an operator" +msgstr "odstraní operátor" + +#: sql_help.c:5515 +msgid "remove an operator class" +msgstr "odstraní třídu operátorů" + +#: sql_help.c:5521 +msgid "remove an operator family" +msgstr "odstraní rodinu operátorů" + +#: sql_help.c:5527 +msgid "remove database objects owned by a database role" +msgstr "odstraní objekty vlastněné databázovou rolí" + +#: sql_help.c:5533 +msgid "remove a row level security policy from a table" +msgstr "odstraní row level security politiku z tabulky" + +#: sql_help.c:5539 +msgid "remove a procedure" +msgstr "odstraní proceduru" + +#: sql_help.c:5545 +msgid "remove a publication" +msgstr "odstraní publikaci" + +#: sql_help.c:5557 +msgid "remove a routine" +msgstr "odstraní rutinu" + +#: sql_help.c:5563 +msgid "remove a rewrite rule" +msgstr "odstraní přepisovací pravidlo (rule)" + +#: sql_help.c:5569 +msgid "remove a schema" +msgstr "odstraní schéma" + +#: sql_help.c:5575 +msgid "remove a sequence" +msgstr "odstraní sekvenci" + +#: sql_help.c:5581 +msgid "remove a foreign server descriptor" +msgstr "odstraní deskriptor foreign serveru" + +#: sql_help.c:5587 +msgid "remove extended statistics" +msgstr "odstraní rozšířené statistiky" + +#: sql_help.c:5593 +msgid "remove a subscription" +msgstr "odstraní subskripci" + +#: sql_help.c:5599 +msgid "remove a table" +msgstr "odstraní tabulku" + +#: sql_help.c:5605 +msgid "remove a tablespace" +msgstr "odstraní tablespace" + +#: sql_help.c:5611 +msgid "remove a text search configuration" +msgstr "odstraní konfiguraci fulltextového vyhledávání" + +#: sql_help.c:5617 +msgid "remove a text search dictionary" +msgstr "odstraní slovn?ik pro fulltextové vyhledávání" + +#: sql_help.c:5623 +msgid "remove a text search parser" +msgstr "odstraní parser pro fulltextové vyhledávání" + +#: sql_help.c:5629 +msgid "remove a text search template" +msgstr "odstraní Šablonu fulltextového vyhledávání" + +#: sql_help.c:5635 +msgid "remove a transform" +msgstr "odstraní transformaci" + +#: sql_help.c:5641 +msgid "remove a trigger" +msgstr "odstraní trigger" + +#: sql_help.c:5647 +msgid "remove a data type" +msgstr "odstraní datový typ" + +#: sql_help.c:5659 +msgid "remove a user mapping for a foreign server" +msgstr "odstraní mapování uživatele z foreign serveru" + +#: sql_help.c:5665 +msgid "remove a view" +msgstr "odstraní náhled" + +#: sql_help.c:5677 +msgid "execute a prepared statement" +msgstr "provede připravený dotaz (prepared statement)" + +#: sql_help.c:5683 +msgid "show the execution plan of a statement" +msgstr "ukáže prováděcí plán dotazu" + +#: sql_help.c:5689 +msgid "retrieve rows from a query using a cursor" +msgstr "načte řádky z výsledku dotazu pomocí kursoru" + +#: sql_help.c:5695 +msgid "define access privileges" +msgstr "definuje přístupová práva" + +#: sql_help.c:5701 +msgid "import table definitions from a foreign server" +msgstr "importuje definice tabulek z foreign serveru" + +#: sql_help.c:5707 +msgid "create new rows in a table" +msgstr "přidá nové řádky do tabulky" + +#: sql_help.c:5713 +msgid "listen for a notification" +msgstr "naslouchá upozorněním" + +#: sql_help.c:5719 +msgid "load a shared library file" +msgstr "načte sdílenou knihovnu" + +#: sql_help.c:5725 +msgid "lock a named relation (table, etc)" +msgstr "zamkne uvedenou relaci (tabulku, etc)" + +#: sql_help.c:5731 +msgid "position a cursor" +msgstr "přemístí kursor" + +#: sql_help.c:5737 +msgid "generate a notification" +msgstr "generuje upozornění" + +#: sql_help.c:5743 +msgid "prepare a statement for execution" +msgstr "připraví a uloží dotaz pro provedení" + +#: sql_help.c:5749 +msgid "prepare the current transaction for two-phase commit" +msgstr "přípraví aktuální transakci pro dvoufázoví commit" + +#: sql_help.c:5755 +msgid "change the ownership of database objects owned by a database role" +msgstr "změní vlastníka databázových objektů vlastněných databázovou rolí" + +#: sql_help.c:5761 +msgid "replace the contents of a materialized view" +msgstr "nahraď obsah materializovaného pohledu" + +#: sql_help.c:5767 +msgid "rebuild indexes" +msgstr "znovuvytvoří indexy" + +#: sql_help.c:5773 +msgid "destroy a previously defined savepoint" +msgstr "odstraní dříve vytvořený savepoint" + +#: sql_help.c:5779 +msgid "restore the value of a run-time parameter to the default value" +msgstr "přenastaví parametr běhu na implicitní hodnotu" + +#: sql_help.c:5785 +msgid "remove access privileges" +msgstr "odstraní přístupová práva" + +#: sql_help.c:5797 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "zruší transakci, která byla připravena pro dvoufázový commit" + +#: sql_help.c:5803 +msgid "roll back to a savepoint" +msgstr "vrátí se na savepoint" + +#: sql_help.c:5809 +msgid "define a new savepoint within the current transaction" +msgstr "definuje nový savepoint uvnitř aktuální transakce" + +#: sql_help.c:5815 +msgid "define or change a security label applied to an object" +msgstr "definuje nebo změní bezpečnostní štítek aplikovaný na objekt" + +#: sql_help.c:5821 sql_help.c:5875 sql_help.c:5911 +msgid "retrieve rows from a table or view" +msgstr "vybere řádky z tabulky nebo náhledu" + +#: sql_help.c:5833 +msgid "change a run-time parameter" +msgstr "změní parametry běhu" + +#: sql_help.c:5839 +msgid "set constraint check timing for the current transaction" +msgstr "nastaví mód kontroly omezení (constraints) pro aktuální transakci" + +#: sql_help.c:5845 +msgid "set the current user identifier of the current session" +msgstr "nastaví uživatelský identifikátor aktuální session" + +#: sql_help.c:5851 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "nastaví uživatelský identifikátor session a identifikátor aktuálníhouživatele pro aktuální session" + +#: sql_help.c:5857 +msgid "set the characteristics of the current transaction" +msgstr "nastaví charakteristiku pro aktualní trasakci" + +#: sql_help.c:5863 +msgid "show the value of a run-time parameter" +msgstr "zobrazí hodnoty run-time parametrů" + +#: sql_help.c:5881 +msgid "empty a table or set of tables" +msgstr "zruší obsah tabulky nebo skupiny tabulek" + +#: sql_help.c:5887 +msgid "stop listening for a notification" +msgstr "ukončí naslouchání připomínkám" + +#: sql_help.c:5893 +msgid "update rows of a table" +msgstr "aktualizuje řádky tabulky" + +#: sql_help.c:5899 +msgid "garbage-collect and optionally analyze a database" +msgstr "provede úklid a případně analýzu databáze" + +#: sql_help.c:5905 +msgid "compute a set of rows" +msgstr "spočítá množinu řádek" + +#: startup.c:212 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 může být použito pouze pro neinteraktivní módy" + +#: startup.c:299 +#, c-format +msgid "could not connect to server: %s" +msgstr "nelze se připojit k serveru: %s" + +#: startup.c:327 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "nelze otevřít soubor \"%s\": %m" + +#: startup.c:439 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Pro získání nápovědy napište \"help\".\n" +"\n" + +#: startup.c:589 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "nelze nastavit parametr zobrazení \"%s\"" + +#: startup.c:697 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: startup.c:714 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "varování: nadbytečný parametr příkazové řádky \"%s\" ignorován" + +#: startup.c:763 +#, c-format +msgid "could not find own program executable" +msgstr "nelze najít vlastní spustitelný soubor" + +#: tab-complete.c:4640 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"tab completion dotaz selhal: %s\n" +"Dotaz byl:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "nerozpoznaná hodnota \"%s\" pro \"%s\": očekáván Boolean výraz" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "neplatná hodnota \"%s\" pro \"%s\": očekáváno celé číslo" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "neplatný název proměnné: \"%s\"" + +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"nerozpoznaná hodnota \"%s\" pro \"%s\"\n" +"Možné hodnoty jsou: %s." + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "nelze číst symbolický link \"%s\"" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "potomek byl ukončen signálem %s" + +#~ msgid "Invalid command \\%s. Try \\? for help.\n" +#~ msgstr "Neplatný příkaz \\%s. Použijte \\? pro nápovědu.\n" + +#~ msgid "%s: %s\n" +#~ msgstr "%s: %s\n" + +#~ msgid "Procedure" +#~ msgstr "Procedura" + +#~ msgid "%s\n" +#~ msgstr "%s\n" + +#~ msgid "unterminated quoted string\n" +#~ msgstr "neukončený řetězec v uvozovkách\n" + +#~ msgid "string_literal" +#~ msgstr "string_literal" + +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s: nelze otevřít logovací soubor \"%s\": %s\n" + +#~ msgid "\\%s: error\n" +#~ msgstr "\\%s: chyba\n" + +#~ msgid "\\copy: %s" +#~ msgstr "\\copy: %s" + +#~ msgid "\\copy: unexpected response (%d)\n" +#~ msgstr "\\copy: neočekávaná odezva (%d)\n" + +#~ msgid "data type" +#~ msgstr "datový typ" + +#~ msgid " on host \"%s\"" +#~ msgstr " na počítač \"%s\"" + +#~ msgid " at port \"%s\"" +#~ msgstr " na port \"%s\"" + +#~ msgid " as user \"%s\"" +#~ msgstr " jako uživatel \"%s\"" + +#~ msgid "define a new constraint trigger" +#~ msgstr "defunuje nový constraint trigger" + +#~ msgid " \"%s\" IN %s %s" +#~ msgstr " \"%s\" IN %s %s" + +#~ msgid "ABORT [ WORK | TRANSACTION ]" +#~ msgstr "ABORT [ WORK | TRANSACTION ]" + +#~ msgid "contains support for command-line editing" +#~ msgstr "obsahuje podporu pro editaci příkazové řádky " + +#~ msgid "tablespace" +#~ msgstr "tablespace" + +#~ msgid "new_column" +#~ msgstr "nový_sloupec" + +#~ msgid "column" +#~ msgstr "sloupec" + +#~ msgid " \\l[+] list all databases\n" +#~ msgstr " \\l[+] seznam databází\n" + +#~ msgid "%s: -1 is incompatible with -c and -l\n" +#~ msgstr "%s: -1 je nekompatibilní s -c a -l\n" + +#~ msgid "unrecognized Boolean value; assuming \"on\"\n" +#~ msgstr "nerozpoznaná boolean hodnota; předpokládám \"on\".\n" + +#~ msgid "%s: could not set variable \"%s\"\n" +#~ msgstr "%s: nelze nastavit proměnnou \"%s\"\n" + +#~ msgid "attribute" +#~ msgstr "atribut" + +#~ msgid "input_data_type" +#~ msgstr "vstupní_datový_typ" + +#~ msgid "agg_type" +#~ msgstr "typ_agregace" + +#~ msgid "agg_name" +#~ msgstr "jméno_agregace" + +#~ msgid "(No rows)\n" +#~ msgstr "(Žádné řádky)\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help ukáže tuto nápovědu a skončí\n" + +#~ msgid "could not get current user name: %s\n" +#~ msgstr "nelze získat aktuální uživatelské jméno: %s\n" + +#~ msgid "Object Description" +#~ msgstr "Popis objektu" + +#~ msgid "Modifier" +#~ msgstr "Modifikátor" + +#~ msgid "No relations found.\n" +#~ msgstr "Žádné relace nenalezeny.\n" + +#~ msgid "No matching relations found.\n" +#~ msgstr "Odpovídající relace nebyla nalezena.\n" + +#~ msgid "No settings found.\n" +#~ msgstr "Žádné nastavení nenalezeno.\n" + +#~ msgid "No matching settings found.\n" +#~ msgstr "Odpovídající relace nebyla nalezena.\n" + +#~ msgid "No per-database role settings support in this server version.\n" +#~ msgstr "Tato verze serveru nepodporuje nastavení rolí dle databáze.\n" + +#~ msgid "default %s" +#~ msgstr "implicitně %s" + +#~ msgid "not null" +#~ msgstr "not null" + +#~ msgid "collate %s" +#~ msgstr "collate %s" + +#~ msgid "Value" +#~ msgstr "Hodnota" + +#~ msgid "Modifiers" +#~ msgstr "Modifikátory" + +#~ msgid "normal" +#~ msgstr "normal" + +#~ msgid "could not set variable \"%s\"\n" +#~ msgstr "nelze nastavit proměnnou \"%s\"\n" + +#~ msgid "Watch every %lds\t%s" +#~ msgstr "Zkontroluj každých %lds\t%s" + +#~ msgid "Showing only tuples." +#~ msgstr "Zobrazovány jsou pouze záznamy." + +#~ msgid "Showing locale-adjusted numeric output." +#~ msgstr "Zobrazí číselný výstup dle národního nastavení." + +#~ msgid "SSL connection (unknown cipher)\n" +#~ msgstr "SSL spojení (neznámá šifra)\n" + +#~ msgid "+ opt(%d) = |%s|\n" +#~ msgstr "+ opt(%d) = |%s|\n" + +#~ msgid "\\%s: error while setting variable\n" +#~ msgstr "\\%s: chyba při nastavování proměnné\n" + +#~ msgid "Password encryption failed.\n" +#~ msgstr "Zašifrování hesla selhalo.\n" + +#~ msgid "lock a table" +#~ msgstr "uzamkne tabulku" + +#~ msgid "from_list" +#~ msgstr "from_seznam" + +#~ msgid "using_list" +#~ msgstr "using_seznam" + +#~ msgid "old_version" +#~ msgstr "stará_verze" + +#~ msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" +#~ msgstr " \\g [SOUBOR] nebo ; pošle SQL dotaz na server (a zapíše výsledek do souboru nebo |roury)\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Chyby posílejte na adresu .\n" diff --git a/src/bin/psql/po/de.po b/src/bin/psql/po/de.po new file mode 100644 index 000000000000..dd6f7b3ddd0d --- /dev/null +++ b/src/bin/psql/po/de.po @@ -0,0 +1,6552 @@ +# German message translation file for psql +# Peter Eisentraut , 2001 - 2021. +# +# Use these quotes: »%s« +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-06 22:45+0000\n" +"PO-Revision-Date: 2021-05-07 08:12+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ungültige Programmdatei »%s«" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "konnte Programmdatei »%s« nicht lesen" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "konnte kein »%s« zum Ausführen finden" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() fehlgeschlagen: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: command.c:1315 command.c:3246 command.c:3295 command.c:3412 input.c:227 +#: mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "konnte effektive Benutzer-ID %ld nicht nachschlagen: %s" + +#: ../../common/username.c:45 command.c:565 +msgid "user does not exist" +msgstr "Benutzer existiert nicht" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "Fehler beim Nachschlagen des Benutzernamens: Fehlercode %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "Befehl ist nicht ausführbar" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "Befehl nicht gefunden" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "Kindprozess hat mit Code %d beendet" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "Kindprozess wurde durch Ausnahme 0x%X beendet" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "Kindprozess wurde von Signal %d beendet: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "Kindprozess hat mit unbekanntem Status %d beendet" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Abbruchsanforderung gesendet\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "Konnte Abbruchsanforderung nicht senden: " + +#: ../../fe_utils/print.c:336 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu Zeile)" +msgstr[1] "(%lu Zeilen)" + +#: ../../fe_utils/print.c:3039 +#, c-format +msgid "Interrupted\n" +msgstr "Unterbrochen\n" + +#: ../../fe_utils/print.c:3103 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "Kann keinen weiteren Spaltenkopf zur Tabelle hinzufügen: Spaltenzahl %d überschritten.\n" + +#: ../../fe_utils/print.c:3143 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "Cann keine weitere Zelle zur Tabelle hinzufügen: Zellengesamtzahl %d überschritten.\n" + +#: ../../fe_utils/print.c:3401 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "ungültiges Ausgabeformat (interner Fehler): %d" + +#: ../../fe_utils/psqlscan.l:697 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "rekursive Auswertung der Variable »%s« wird ausgelassen" + +#: command.c:230 +#, c-format +msgid "invalid command \\%s" +msgstr "ungültige Anweisung \\%s" + +#: command.c:232 +#, c-format +msgid "Try \\? for help." +msgstr "Versuchen Sie \\? für Hilfe." + +#: command.c:250 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: überflüssiges Argument »%s« ignoriert" + +#: command.c:302 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "Befehl \\%s ignoriert; verwenden Sie \\endif oder Strg-C um den aktuellen \\if-Block zu beenden" + +#: command.c:563 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "konnte Home-Verzeichnis für Benutzer-ID %ld nicht ermitteln: %s" + +#: command.c:581 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: konnte nicht in das Verzeichnis »%s« wechseln: %m" + +#: command.c:606 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "Sie sind gegenwärtig nicht mit einer Datenbank verbunden.\n" + +#: command.c:616 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Sie sind verbunden mit der Datenbank »%s« als Benutzer »%s« auf Adresse »%s« auf Port »%s«.\n" + +#: command.c:619 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Sie sind verbunden mit der Datenbank »%s« als Benutzer »%s« via Socket in »%s« auf Port »%s«.\n" + +#: command.c:625 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Sie sind verbunden mit der Datenbank »%s« als Benutzer »%s« auf Host »%s« (Adresse »%s«) auf Port »%s«.\n" + +#: command.c:628 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Sie sind verbunden mit der Datenbank »%s« als Benutzer »%s« auf Host »%s« auf Port »%s«.\n" + +#: command.c:1012 command.c:1121 command.c:2602 +#, c-format +msgid "no query buffer" +msgstr "kein Anfragepuffer" + +#: command.c:1045 command.c:5304 +#, c-format +msgid "invalid line number: %s" +msgstr "ungültige Zeilennummer: %s" + +#: command.c:1112 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "Der Server (Version %s) unterstützt das Bearbeiten des Funktionsquelltextes nicht." + +#: command.c:1115 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "Der Server (Version %s) unterstützt das Bearbeiten von Sichtdefinitionen nicht." + +#: command.c:1197 +msgid "No changes" +msgstr "keine Änderungen" + +#: command.c:1276 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: ungültiger Kodierungsname oder Umwandlungsprozedur nicht gefunden" + +#: command.c:1311 command.c:2052 command.c:3242 command.c:3434 command.c:5406 +#: common.c:174 common.c:223 common.c:392 common.c:1248 common.c:1276 +#: common.c:1385 common.c:1492 common.c:1530 copy.c:488 copy.c:709 help.c:62 +#: large_obj.c:157 large_obj.c:192 large_obj.c:254 startup.c:298 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1318 +msgid "There is no previous error." +msgstr "Es gibt keinen vorangegangenen Fehler." + +#: command.c:1431 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: rechte Klammer fehlt" + +#: command.c:1608 command.c:1913 command.c:1927 command.c:1944 command.c:2106 +#: command.c:2342 command.c:2569 command.c:2609 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s: notwendiges Argument fehlt" + +#: command.c:1739 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: kann nicht nach \\else kommen" + +#: command.c:1744 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif: kein passendes \\if" + +#: command.c:1808 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else: kann nicht nach \\else kommen" + +#: command.c:1813 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else: kein passendes \\if" + +#: command.c:1853 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif: kein passendes \\if" + +#: command.c:2008 +msgid "Query buffer is empty." +msgstr "Anfragepuffer ist leer." + +#: command.c:2030 +msgid "Enter new password: " +msgstr "Neues Passwort eingeben: " + +#: command.c:2031 +msgid "Enter it again: " +msgstr "Geben Sie es noch einmal ein: " + +#: command.c:2035 +#, c-format +msgid "Passwords didn't match." +msgstr "Passwörter stimmten nicht überein." + +#: command.c:2135 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s: konnte Wert für Variable nicht lesen" + +#: command.c:2238 +msgid "Query buffer reset (cleared)." +msgstr "Anfragepuffer wurde gelöscht." + +#: command.c:2260 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "Befehlsgeschichte in Datei »%s« geschrieben.\n" + +#: command.c:2347 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: Name der Umgebungsvariable darf kein »=« enthalten" + +#: command.c:2399 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "Der Server (Version %s) unterstützt das Anzeigen des Funktionsquelltextes nicht." + +#: command.c:2402 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "Der Server (Version %s) unterstützt das Anzeigen von Sichtdefinitionen nicht." + +#: command.c:2409 +#, c-format +msgid "function name is required" +msgstr "Funktionsname wird benötigt" + +#: command.c:2411 +#, c-format +msgid "view name is required" +msgstr "Sichtname wird benötigt" + +#: command.c:2541 +msgid "Timing is on." +msgstr "Zeitmessung ist an." + +#: command.c:2543 +msgid "Timing is off." +msgstr "Zeitmessung ist aus." + +#: command.c:2628 command.c:2656 command.c:3873 command.c:3876 command.c:3879 +#: command.c:3885 command.c:3887 command.c:3913 command.c:3923 command.c:3935 +#: command.c:3949 command.c:3976 command.c:4034 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:3047 startup.c:237 startup.c:287 +msgid "Password: " +msgstr "Passwort: " + +#: command.c:3052 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "Passwort für Benutzer %s: " + +#: command.c:3104 +#, c-format +msgid "Do not give user, host, or port separately when using a connection string" +msgstr "Geben Sie Benutzer, Host oder Port nicht separat an, wenn eine Verbindungsangabe verwendet wird" + +#: command.c:3139 +#, c-format +msgid "No database connection exists to re-use parameters from" +msgstr "Es gibt keine Verbindung, von der die Parameter verwendet werden können" + +#: command.c:3440 +#, c-format +msgid "Previous connection kept" +msgstr "Vorherige Verbindung wurde behalten" + +#: command.c:3446 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3502 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s« auf Adresse »%s« auf Port »%s«.\n" + +#: command.c:3505 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s« via Socket in »%s« auf Port »%s«.\n" + +#: command.c:3511 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s« auf Host »%s« (Adresse »%s«) auf Port »%s«.\n" + +#: command.c:3514 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s« auf Host »%s« auf Port »%s«.\n" + +#: command.c:3519 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s«.\n" + +#: command.c:3559 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, Server %s)\n" + +#: command.c:3567 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"WARNUNG: %s-Hauptversion %s, Server-Hauptversion %s.\n" +" Einige Features von psql werden eventuell nicht funktionieren.\n" + +#: command.c:3606 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL-Verbindung (Protokoll: %s, Verschlüsselungsmethode: %s, Bits: %s, Komprimierung: %s)\n" + +#: command.c:3607 command.c:3608 command.c:3609 +msgid "unknown" +msgstr "unbekannt" + +#: command.c:3610 help.c:45 +msgid "off" +msgstr "aus" + +#: command.c:3610 help.c:45 +msgid "on" +msgstr "an" + +#: command.c:3624 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "GSSAPI-verschlüsselte Verbindung\n" + +#: command.c:3644 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"Warnung: Konsolencodeseite (%u) unterscheidet sich von der Windows-\n" +" Codeseite (%u). 8-Bit-Zeichen funktionieren möglicherweise nicht\n" +" richtig. Einzelheiten finden Sie auf der psql-Handbuchseite unter\n" +" »Notes for Windows users«.\n" + +#: command.c:3749 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "Umgebungsvariable PSQL_EDITOR_LINENUMBER_ARG muss gesetzt werden, um eine Zeilennummer angeben zu können" + +#: command.c:3778 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "konnte Editor »%s« nicht starten" + +#: command.c:3780 +#, c-format +msgid "could not start /bin/sh" +msgstr "konnte /bin/sh nicht starten" + +#: command.c:3830 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "konnte temporäres Verzeichnis nicht finden: %s" + +#: command.c:3857 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht öffnen: %m" + +#: command.c:4193 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: Abkürzung »%s« ist nicht eindeutig, passt auf »%s« und »%s«" + +#: command.c:4213 +#, c-format +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: zulässige Formate sind aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" + +#: command.c:4232 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: zulässige Linienstile sind ascii, old-ascii, unicode" + +#: command.c:4247 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: zulässige Unicode-Rahmnenlinienstile sind single, double" + +#: command.c:4262 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: zulässige Unicode-Spaltenlinienstile sind single, double" + +#: command.c:4277 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: zulässige Unicode-Kopflinienstile sind single, double" + +#: command.c:4320 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep muss ein einzelnes Ein-Byte-Zeichen sein" + +#: command.c:4325 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldsep kann nicht doppeltes Anführungszeichen, Newline oder Carriage Return sein" + +#: command.c:4462 command.c:4650 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset: unbekannte Option: %s" + +#: command.c:4482 +#, c-format +msgid "Border style is %d.\n" +msgstr "Rahmenstil ist %d.\n" + +#: command.c:4488 +#, c-format +msgid "Target width is unset.\n" +msgstr "Zielbreite ist nicht gesetzt.\n" + +#: command.c:4490 +#, c-format +msgid "Target width is %d.\n" +msgstr "Zielbreite ist %d.\n" + +#: command.c:4497 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Erweiterte Anzeige ist an.\n" + +#: command.c:4499 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "Erweiterte Anzeige wird automatisch verwendet.\n" + +#: command.c:4501 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Erweiterte Anzeige ist aus.\n" + +#: command.c:4507 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "Feldtrennzeichen für CSV ist »%s«.\n" + +#: command.c:4515 command.c:4523 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "Feldtrennzeichen ist ein Null-Byte.\n" + +#: command.c:4517 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "Feldtrennzeichen ist »%s«.\n" + +#: command.c:4530 +#, c-format +msgid "Default footer is on.\n" +msgstr "Standardfußzeile ist an.\n" + +#: command.c:4532 +#, c-format +msgid "Default footer is off.\n" +msgstr "Standardfußzeile ist aus.\n" + +#: command.c:4538 +#, c-format +msgid "Output format is %s.\n" +msgstr "Ausgabeformat ist »%s«.\n" + +#: command.c:4544 +#, c-format +msgid "Line style is %s.\n" +msgstr "Linienstil ist %s.\n" + +#: command.c:4551 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Null-Anzeige ist »%s«.\n" + +#: command.c:4559 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "Lokalisiertes Format für numerische Daten ist an.\n" + +#: command.c:4561 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "Lokalisiertes Format für numerische Daten ist aus.\n" + +#: command.c:4568 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Pager wird für lange Ausgaben verwendet.\n" + +#: command.c:4570 +#, c-format +msgid "Pager is always used.\n" +msgstr "Pager wird immer verwendet.\n" + +#: command.c:4572 +#, c-format +msgid "Pager usage is off.\n" +msgstr "Pager-Verwendung ist aus.\n" + +#: command.c:4578 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "Pager wird nicht für weniger als %d Zeile verwendet werden.\n" +msgstr[1] "Pager wird nicht für weniger als %d Zeilen verwendet werden.\n" + +#: command.c:4588 command.c:4598 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "Satztrennzeichen ist ein Null-Byte.\n" + +#: command.c:4590 +#, c-format +msgid "Record separator is .\n" +msgstr "Satztrennzeichen ist .\n" + +#: command.c:4592 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "Satztrennzeichen ist »%s«.\n" + +#: command.c:4605 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Tabellenattribute sind »%s«.\n" + +#: command.c:4608 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Tabellenattribute sind nicht gesetzt.\n" + +#: command.c:4615 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "Titel ist »%s«.\n" + +#: command.c:4617 +#, c-format +msgid "Title is unset.\n" +msgstr "Titel ist nicht gesetzt.\n" + +#: command.c:4624 +#, c-format +msgid "Tuples only is on.\n" +msgstr "Nur Datenzeilen ist an.\n" + +#: command.c:4626 +#, c-format +msgid "Tuples only is off.\n" +msgstr "Nur Datenzeilen ist aus.\n" + +#: command.c:4632 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Unicode-Rahmenlinienstil ist »%s«.\n" + +#: command.c:4638 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Unicode-Spaltenlinienstil ist »%s«.\n" + +#: command.c:4644 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Unicode-Kopflinienstil ist »%s«.\n" + +#: command.c:4877 +#, c-format +msgid "\\!: failed" +msgstr "\\!: fehlgeschlagen" + +#: command.c:4902 common.c:652 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch kann nicht mit einer leeren Anfrage verwendet werden" + +#: command.c:4943 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (alle %gs)\n" + +#: command.c:4946 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (alle %gs)\n" + +#: command.c:5000 command.c:5007 common.c:552 common.c:559 common.c:1231 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"******** ANFRAGE *********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:5199 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "»%s.%s« ist keine Sicht" + +#: command.c:5215 +#, c-format +msgid "could not parse reloptions array" +msgstr "konnte reloptions-Array nicht interpretieren" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "Escape kann nicht ohne aktive Verbindung ausgeführt werden" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "Verbindung zum Server wurde verloren" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "Die Verbindung zum Server wurde verloren. Versuche Reset: " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "Fehlgeschlagen.\n" + +#: common.c:330 +#, c-format +msgid "Succeeded.\n" +msgstr "Erfolgreich.\n" + +#: common.c:382 common.c:949 common.c:1166 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "unerwarteter PQresultStatus: %d" + +#: common.c:491 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Zeit: %.3f ms\n" + +#: common.c:506 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Zeit: %.3f ms (%02d:%06.3f)\n" + +#: common.c:515 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Zeit: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:522 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Zeit: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:546 common.c:604 common.c:1202 +#, c-format +msgid "You are currently not connected to a database." +msgstr "Sie sind gegenwärtig nicht mit einer Datenbank verbunden." + +#: common.c:659 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watch kann nicht mit COPY verwendet werden" + +#: common.c:664 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "unerwarteter Ergebnisstatus für \\watch" + +#: common.c:694 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "Asynchrone Benachrichtigung »%s« mit Daten »%s« vom Serverprozess mit PID %d empfangen.\n" + +#: common.c:697 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "Asynchrone Benachrichtigung »%s« vom Serverprozess mit PID %d empfangen.\n" + +#: common.c:730 common.c:747 +#, c-format +msgid "could not print result table: %m" +msgstr "konnte Ergebnistabelle nicht ausgeben: %m" + +#: common.c:768 +#, c-format +msgid "no rows returned for \\gset" +msgstr "keine Zeilen für \\gset zurückgegeben" + +#: common.c:773 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "mehr als eine Zeile für \\gset zurückgegeben" + +#: common.c:791 +#, c-format +msgid "attempt to \\gset into specially treated variable \"%s\" ignored" +msgstr "Versuch von \\gset in besonders behandelte Variable »%s« ignoriert" + +#: common.c:1211 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(Einzelschrittmodus: Anfrage bestätigen)*************************************\n" +"%s\n" +"***(Drücken Sie die Eingabetaste um fortzufahren oder »x« um abzubrechen)*******\n" + +#: common.c:1266 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "Der Server (Version %s) unterstützt keine Sicherungspunkte für ON_ERROR_ROLLBACK." + +#: common.c:1329 +#, c-format +msgid "STATEMENT: %s" +msgstr "ANWEISUNG: %s" + +#: common.c:1373 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "unerwarteter Transaktionsstatus (%d)" + +#: common.c:1514 describe.c:2179 +msgid "Column" +msgstr "Spalte" + +#: common.c:1515 describe.c:178 describe.c:396 describe.c:414 describe.c:459 +#: describe.c:476 describe.c:1128 describe.c:1292 describe.c:1878 +#: describe.c:1902 describe.c:2180 describe.c:4048 describe.c:4271 +#: describe.c:4496 describe.c:5794 +msgid "Type" +msgstr "Typ" + +#: common.c:1564 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Der Befehl hat kein Ergebnis oder das Ergebnis hat keine Spalten.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy: benötigt Argumente" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: Parse-Fehler bei »%s«" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: Parse-Fehler am Zeilenende" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "konnte Befehl »%s« nicht ausführen: %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s: ein Verzeichnis kann nicht kopiert werden" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "konnte Pipe zu externem Programm nicht schließen: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "konnte COPY-Daten nicht schreiben: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "Datentransfer mit COPY fehlgeschlagen: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "vom Benutzer abgebrochen" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Geben Sie die zu kopierenden Daten ein, gefolgt von einem Zeilenende.\n" +"Beenden Sie mit einem Backslash und einem Punkt alleine auf einer Zeile, oder einem EOF-Signal." + +#: copy.c:671 +msgid "aborted because of read failure" +msgstr "abgebrochen wegen Lesenfehlers" + +#: copy.c:705 +msgid "trying to exit copy mode" +msgstr "versuche, den COPY-Modus zu verlassen" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: Anweisung hat keine Ergebnismenge zurückgegeben" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: Anfrage muss mindestens drei Spalten zurückgeben" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: die vertikalen und horizontalen Kopffelder müssen verschiedene Spalten sein" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: Datenspalte muss angegeben werden, wenn die Anfrage mehr als drei Spalten zurückgibt" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: maximale Anzahl Spalten (%d) überschritten" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: Anfrageergebnis enthält mehrfache Datenwerte für Zeile »%s«, Spalte »%s«" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: Spaltennummer %d ist außerhalb des zulässigen Bereichs 1..%d" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: zweideutiger Spaltenname: »%s«" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: Spaltenname nicht gefunden: »%s«" + +#: describe.c:76 describe.c:376 describe.c:728 describe.c:924 describe.c:1120 +#: describe.c:1281 describe.c:1353 describe.c:4036 describe.c:4258 +#: describe.c:4494 describe.c:4585 describe.c:4731 describe.c:4944 +#: describe.c:5104 describe.c:5345 describe.c:5420 describe.c:5431 +#: describe.c:5493 describe.c:5918 describe.c:6001 +msgid "Schema" +msgstr "Schema" + +#: describe.c:77 describe.c:175 describe.c:243 describe.c:251 describe.c:377 +#: describe.c:729 describe.c:925 describe.c:1038 describe.c:1121 +#: describe.c:1354 describe.c:4037 describe.c:4259 describe.c:4417 +#: describe.c:4495 describe.c:4586 describe.c:4665 describe.c:4732 +#: describe.c:4945 describe.c:5029 describe.c:5105 describe.c:5346 +#: describe.c:5421 describe.c:5432 describe.c:5494 describe.c:5691 +#: describe.c:5775 describe.c:5999 describe.c:6171 describe.c:6411 +msgid "Name" +msgstr "Name" + +#: describe.c:78 describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "Result data type" +msgstr "Ergebnisdatentyp" + +#: describe.c:86 describe.c:99 describe.c:103 describe.c:390 describe.c:408 +#: describe.c:454 describe.c:471 +msgid "Argument data types" +msgstr "Argumentdatentypen" + +#: describe.c:111 describe.c:118 describe.c:186 describe.c:274 describe.c:523 +#: describe.c:777 describe.c:940 describe.c:1063 describe.c:1356 +#: describe.c:2200 describe.c:3823 describe.c:4108 describe.c:4305 +#: describe.c:4448 describe.c:4522 describe.c:4595 describe.c:4678 +#: describe.c:4853 describe.c:4972 describe.c:5038 describe.c:5106 +#: describe.c:5247 describe.c:5289 describe.c:5362 describe.c:5424 +#: describe.c:5433 describe.c:5495 describe.c:5717 describe.c:5797 +#: describe.c:5932 describe.c:6002 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "Beschreibung" + +#: describe.c:136 +msgid "List of aggregate functions" +msgstr "Liste der Aggregatfunktionen" + +#: describe.c:161 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "Der Server (Version %s) unterstützt keine Zugriffsmethoden." + +#: describe.c:176 +msgid "Index" +msgstr "Index" + +#: describe.c:177 describe.c:4056 describe.c:4284 describe.c:5919 +msgid "Table" +msgstr "Tabelle" + +#: describe.c:185 describe.c:5696 +msgid "Handler" +msgstr "Handler" + +#: describe.c:204 +msgid "List of access methods" +msgstr "Liste der Zugriffsmethoden" + +#: describe.c:230 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "Der Server (Version %s) unterstützt keine Tablespaces." + +#: describe.c:244 describe.c:252 describe.c:504 describe.c:767 describe.c:1039 +#: describe.c:1280 describe.c:4049 describe.c:4260 describe.c:4421 +#: describe.c:4667 describe.c:5030 describe.c:5692 describe.c:5776 +#: describe.c:6172 describe.c:6309 describe.c:6412 describe.c:6535 +#: describe.c:6613 large_obj.c:289 +msgid "Owner" +msgstr "Eigentümer" + +#: describe.c:245 describe.c:253 +msgid "Location" +msgstr "Pfad" + +#: describe.c:264 describe.c:3639 +msgid "Options" +msgstr "Optionen" + +#: describe.c:269 describe.c:740 describe.c:1055 describe.c:4100 +#: describe.c:4104 +msgid "Size" +msgstr "Größe" + +#: describe.c:291 +msgid "List of tablespaces" +msgstr "Liste der Tablespaces" + +#: describe.c:336 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df akzeptiert nur [anptwS+] als Optionen" + +#: describe.c:344 describe.c:355 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df akzeptiert die Option »%c« nicht mit Serverversion %s" + +#. translator: "agg" is short for "aggregate" +#: describe.c:392 describe.c:410 describe.c:456 describe.c:473 +msgid "agg" +msgstr "Agg" + +#: describe.c:393 describe.c:411 +msgid "window" +msgstr "Fenster" + +#: describe.c:394 +msgid "proc" +msgstr "Proz" + +#: describe.c:395 describe.c:413 describe.c:458 describe.c:475 +msgid "func" +msgstr "Funk" + +#: describe.c:412 describe.c:457 describe.c:474 describe.c:1490 +msgid "trigger" +msgstr "Trigger" + +#: describe.c:486 +msgid "immutable" +msgstr "unveränderlich" + +#: describe.c:487 +msgid "stable" +msgstr "stabil" + +#: describe.c:488 +msgid "volatile" +msgstr "volatil" + +#: describe.c:489 +msgid "Volatility" +msgstr "Volatilität" + +#: describe.c:497 +msgid "restricted" +msgstr "beschränkt" + +#: describe.c:498 +msgid "safe" +msgstr "sicher" + +#: describe.c:499 +msgid "unsafe" +msgstr "unsicher" + +#: describe.c:500 +msgid "Parallel" +msgstr "Parallel" + +#: describe.c:505 +msgid "definer" +msgstr "definer" + +#: describe.c:506 +msgid "invoker" +msgstr "invoker" + +#: describe.c:507 +msgid "Security" +msgstr "Sicherheit" + +#: describe.c:512 +msgid "Language" +msgstr "Sprache" + +#: describe.c:516 describe.c:520 +msgid "Source code" +msgstr "Quelltext" + +#: describe.c:691 +msgid "List of functions" +msgstr "Liste der Funktionen" + +#: describe.c:739 +msgid "Internal name" +msgstr "Interner Name" + +#: describe.c:761 +msgid "Elements" +msgstr "Elemente" + +#: describe.c:822 +msgid "List of data types" +msgstr "Liste der Datentypen" + +#: describe.c:926 +msgid "Left arg type" +msgstr "Linker Typ" + +#: describe.c:927 +msgid "Right arg type" +msgstr "Rechter Typ" + +#: describe.c:928 +msgid "Result type" +msgstr "Ergebnistyp" + +#: describe.c:933 describe.c:4673 describe.c:4830 describe.c:4836 +#: describe.c:5246 describe.c:6784 describe.c:6788 +msgid "Function" +msgstr "Funktion" + +#: describe.c:1010 +msgid "List of operators" +msgstr "Liste der Operatoren" + +#: describe.c:1040 +msgid "Encoding" +msgstr "Kodierung" + +#: describe.c:1045 describe.c:4946 +msgid "Collate" +msgstr "Sortierfolge" + +#: describe.c:1046 describe.c:4947 +msgid "Ctype" +msgstr "Zeichentyp" + +#: describe.c:1059 +msgid "Tablespace" +msgstr "Tablespace" + +#: describe.c:1081 +msgid "List of databases" +msgstr "Liste der Datenbanken" + +#: describe.c:1122 describe.c:1283 describe.c:4038 +msgid "table" +msgstr "Tabelle" + +#: describe.c:1123 describe.c:4039 +msgid "view" +msgstr "Sicht" + +#: describe.c:1124 describe.c:4040 +msgid "materialized view" +msgstr "materialisierte Sicht" + +#: describe.c:1125 describe.c:1285 describe.c:4042 +msgid "sequence" +msgstr "Sequenz" + +#: describe.c:1126 describe.c:4045 +msgid "foreign table" +msgstr "Fremdtabelle" + +#: describe.c:1127 describe.c:4046 describe.c:4269 +msgid "partitioned table" +msgstr "partitionierte Tabelle" + +#: describe.c:1139 +msgid "Column privileges" +msgstr "Spaltenprivilegien" + +#: describe.c:1170 describe.c:1204 +msgid "Policies" +msgstr "Policys" + +#: describe.c:1236 describe.c:6476 describe.c:6480 +msgid "Access privileges" +msgstr "Zugriffsprivilegien" + +#: describe.c:1267 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "Der Server (Version %s) unterstützt kein Ändern der Vorgabeprivilegien." + +#: describe.c:1287 +msgid "function" +msgstr "Funktion" + +#: describe.c:1289 +msgid "type" +msgstr "Typ" + +#: describe.c:1291 +msgid "schema" +msgstr "Schema" + +#: describe.c:1315 +msgid "Default access privileges" +msgstr "Vorgegebene Zugriffsprivilegien" + +#: describe.c:1355 +msgid "Object" +msgstr "Objekt" + +#: describe.c:1369 +msgid "table constraint" +msgstr "Tabellen-Constraint" + +#: describe.c:1391 +msgid "domain constraint" +msgstr "Domänen-Constraint" + +#: describe.c:1419 +msgid "operator class" +msgstr "Operatorklasse" + +#: describe.c:1448 +msgid "operator family" +msgstr "Operatorfamilie" + +#: describe.c:1470 +msgid "rule" +msgstr "Rule" + +#: describe.c:1512 +msgid "Object descriptions" +msgstr "Objektbeschreibungen" + +#: describe.c:1568 describe.c:4175 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "Keine Relation namens »%s« gefunden" + +#: describe.c:1571 describe.c:4178 +#, c-format +msgid "Did not find any relations." +msgstr "Keine Relationen gefunden" + +#: describe.c:1827 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "Keine Relation mit OID %s gefunden" + +#: describe.c:1879 describe.c:1903 +msgid "Start" +msgstr "Start" + +#: describe.c:1880 describe.c:1904 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1881 describe.c:1905 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1882 describe.c:1906 +msgid "Increment" +msgstr "Inkrement" + +#: describe.c:1883 describe.c:1907 describe.c:2038 describe.c:4589 +#: describe.c:4847 describe.c:4961 describe.c:4966 describe.c:6523 +msgid "yes" +msgstr "ja" + +#: describe.c:1884 describe.c:1908 describe.c:2039 describe.c:4589 +#: describe.c:4844 describe.c:4961 describe.c:6524 +msgid "no" +msgstr "nein" + +#: describe.c:1885 describe.c:1909 +msgid "Cycles?" +msgstr "Zyklisch?" + +#: describe.c:1886 describe.c:1910 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1953 +#, c-format +msgid "Owned by: %s" +msgstr "Eigentümer: %s" + +#: describe.c:1957 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Sequenz für Identitätsspalte: %s" + +#: describe.c:1964 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Sequenz »%s.%s«" + +#: describe.c:2111 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Ungeloggte Tabelle »%s.%s«" + +#: describe.c:2114 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Tabelle »%s.%s«" + +#: describe.c:2118 +#, c-format +msgid "View \"%s.%s\"" +msgstr "Sicht »%s.%s«" + +#: describe.c:2123 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Ungeloggte materialisierte Sicht »%s.%s«" + +#: describe.c:2126 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Materialisierte Sicht »%s.%s«" + +#: describe.c:2131 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Ungeloggter Index »%s.%s«" + +#: describe.c:2134 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "Index »%s.%s«" + +#: describe.c:2139 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Ungeloggter partitionierter Index »%s.%s«" + +#: describe.c:2142 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Partitionierter Index »%s.%s«" + +#: describe.c:2147 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Spezielle Relation »%s.%s«" + +#: describe.c:2151 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "TOAST-Tabelle »%s.%s«" + +#: describe.c:2155 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Zusammengesetzter Typ »%s.%s«" + +#: describe.c:2159 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "Fremdtabelle »%s.%s«" + +#: describe.c:2164 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Ungeloggte partitionierte Tabelle »%s.%s«" + +#: describe.c:2167 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Partitionierte Tabelle »%s.%s«" + +#: describe.c:2183 describe.c:4502 +msgid "Collation" +msgstr "Sortierfolge" + +#: describe.c:2184 describe.c:4509 +msgid "Nullable" +msgstr "NULL erlaubt?" + +#: describe.c:2185 describe.c:4510 +msgid "Default" +msgstr "Vorgabewert" + +#: describe.c:2188 +msgid "Key?" +msgstr "Schlüssel?" + +#: describe.c:2190 describe.c:4739 describe.c:4750 +msgid "Definition" +msgstr "Definition" + +#: describe.c:2192 describe.c:5712 describe.c:5796 describe.c:5867 +#: describe.c:5931 +msgid "FDW options" +msgstr "FDW-Optionen" + +#: describe.c:2194 +msgid "Storage" +msgstr "Speicherung" + +#: describe.c:2196 +msgid "Compression" +msgstr "Kompression" + +#: describe.c:2198 +msgid "Stats target" +msgstr "Statistikziel" + +#: describe.c:2334 +#, c-format +msgid "Partition of: %s %s%s" +msgstr "Partition von: %s %s%s" + +#: describe.c:2347 +msgid "No partition constraint" +msgstr "Kein Partitions-Constraint" + +#: describe.c:2349 +#, c-format +msgid "Partition constraint: %s" +msgstr "Partitions-Constraint: %s" + +#: describe.c:2373 +#, c-format +msgid "Partition key: %s" +msgstr "Partitionsschlüssel: %s" + +#: describe.c:2399 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Gehört zu Tabelle: »%s.%s«" + +#: describe.c:2470 +msgid "primary key, " +msgstr "Primärschlüssel, " + +#: describe.c:2472 +msgid "unique, " +msgstr "eindeutig, " + +#: describe.c:2478 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "für Tabelle »%s.%s«" + +#: describe.c:2482 +#, c-format +msgid ", predicate (%s)" +msgstr ", Prädikat (%s)" + +#: describe.c:2485 +msgid ", clustered" +msgstr ", geclustert" + +#: describe.c:2488 +msgid ", invalid" +msgstr ", ungültig" + +#: describe.c:2491 +msgid ", deferrable" +msgstr ", DEFERRABLE" + +#: describe.c:2494 +msgid ", initially deferred" +msgstr ", INITIALLY DEFERRED" + +#: describe.c:2497 +msgid ", replica identity" +msgstr ", Replika-Identität" + +#: describe.c:2564 +msgid "Indexes:" +msgstr "Indexe:" + +#: describe.c:2648 +msgid "Check constraints:" +msgstr "Check-Constraints:" + +#: describe.c:2716 +msgid "Foreign-key constraints:" +msgstr "Fremdschlüssel-Constraints:" + +#: describe.c:2779 +msgid "Referenced by:" +msgstr "Fremdschlüsselverweise von:" + +#: describe.c:2829 +msgid "Policies:" +msgstr "Policys:" + +#: describe.c:2832 +msgid "Policies (forced row security enabled):" +msgstr "Policys (Sicherheit auf Zeilenebene erzwungen):" + +#: describe.c:2835 +msgid "Policies (row security enabled): (none)" +msgstr "Policys (Sicherheit auf Zeilenebene eingeschaltet): (keine)" + +#: describe.c:2838 +msgid "Policies (forced row security enabled): (none)" +msgstr "Policys (Sicherheit auf Zeilenebene erzwungen): (keine)" + +#: describe.c:2841 +msgid "Policies (row security disabled):" +msgstr "Policys (Sicherheit auf Zeilenebene ausgeschaltet):" + +#: describe.c:2902 describe.c:3006 +msgid "Statistics objects:" +msgstr "Statistikobjekte:" + +#: describe.c:3120 describe.c:3224 +msgid "Rules:" +msgstr "Regeln:" + +#: describe.c:3123 +msgid "Disabled rules:" +msgstr "Abgeschaltete Regeln:" + +#: describe.c:3126 +msgid "Rules firing always:" +msgstr "Regeln, die immer aktiv werden:" + +#: describe.c:3129 +msgid "Rules firing on replica only:" +msgstr "Regeln, die nur im Replikat aktiv werden:" + +#: describe.c:3169 +msgid "Publications:" +msgstr "Publikationen:" + +#: describe.c:3207 +msgid "View definition:" +msgstr "Sichtdefinition:" + +#: describe.c:3354 +msgid "Triggers:" +msgstr "Trigger:" + +#: describe.c:3358 +msgid "Disabled user triggers:" +msgstr "Abgeschaltete Benutzer-Trigger:" + +#: describe.c:3360 +msgid "Disabled triggers:" +msgstr "Abgeschaltete Trigger:" + +#: describe.c:3363 +msgid "Disabled internal triggers:" +msgstr "Abgeschaltete interne Trigger:" + +#: describe.c:3366 +msgid "Triggers firing always:" +msgstr "Trigger, die immer aktiv werden:" + +#: describe.c:3369 +msgid "Triggers firing on replica only:" +msgstr "Trigger, die nur im Replikat aktiv werden:" + +#: describe.c:3441 +#, c-format +msgid "Server: %s" +msgstr "Server: %s" + +#: describe.c:3449 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW-Optionen: (%s)" + +#: describe.c:3470 +msgid "Inherits" +msgstr "Erbt von" + +#: describe.c:3543 +#, c-format +msgid "Number of partitions: %d" +msgstr "Anzahl Partitionen: %d" + +#: describe.c:3552 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Anzahl Partitionen: %d (Mit \\d+ alle anzeigen.)" + +#: describe.c:3554 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Anzahl Kindtabellen: %d (Mit \\d+ alle anzeigen.)" + +#: describe.c:3561 +msgid "Child tables" +msgstr "Kindtabellen" + +#: describe.c:3561 +msgid "Partitions" +msgstr "Partitionen" + +#: describe.c:3592 +#, c-format +msgid "Typed table of type: %s" +msgstr "Getypte Tabelle vom Typ: %s" + +#: describe.c:3608 +msgid "Replica Identity" +msgstr "Replika-Identität" + +#: describe.c:3621 +msgid "Has OIDs: yes" +msgstr "Hat OIDs: ja" + +#: describe.c:3630 +#, c-format +msgid "Access method: %s" +msgstr "Zugriffsmethode: %s" + +#: describe.c:3710 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Tablespace: »%s«" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3722 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", Tablespace »%s«" + +#: describe.c:3815 +msgid "List of roles" +msgstr "Liste der Rollen" + +#: describe.c:3817 +msgid "Role name" +msgstr "Rollenname" + +#: describe.c:3818 +msgid "Attributes" +msgstr "Attribute" + +#: describe.c:3820 +msgid "Member of" +msgstr "Mitglied von" + +#: describe.c:3831 +msgid "Superuser" +msgstr "Superuser" + +#: describe.c:3834 +msgid "No inheritance" +msgstr "keine Vererbung" + +#: describe.c:3837 +msgid "Create role" +msgstr "Rolle erzeugen" + +#: describe.c:3840 +msgid "Create DB" +msgstr "DB erzeugen" + +#: describe.c:3843 +msgid "Cannot login" +msgstr "kann nicht einloggen" + +#: describe.c:3847 +msgid "Replication" +msgstr "Replikation" + +#: describe.c:3851 +msgid "Bypass RLS" +msgstr "Bypass RLS" + +#: describe.c:3860 +msgid "No connections" +msgstr "keine Verbindungen" + +#: describe.c:3862 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d Verbindung" +msgstr[1] "%d Verbindungen" + +#: describe.c:3872 +msgid "Password valid until " +msgstr "Passwort gültig bis " + +#: describe.c:3922 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "Der Server (Version %s) unterstützt keine Rolleneinstellungen pro Datenbank." + +#: describe.c:3935 +msgid "Role" +msgstr "Rolle" + +#: describe.c:3936 +msgid "Database" +msgstr "Datenbank" + +#: describe.c:3937 +msgid "Settings" +msgstr "Einstellung" + +#: describe.c:3958 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "Keine Einstellungen für Rolle »%s« und Datenbank »%s« gefunden" + +#: describe.c:3961 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "Keine Einstellungen für Rolle »%s« gefunden" + +#: describe.c:3964 +#, c-format +msgid "Did not find any settings." +msgstr "Keine Einstellungen gefunden" + +#: describe.c:3969 +msgid "List of settings" +msgstr "Liste der Einstellungen" + +#: describe.c:4041 +msgid "index" +msgstr "Index" + +#: describe.c:4043 +msgid "special" +msgstr "speziell" + +#: describe.c:4044 +msgid "TOAST table" +msgstr "TOAST-Tabelle" + +#: describe.c:4047 describe.c:4270 +msgid "partitioned index" +msgstr "partitionierter Index" + +#: describe.c:4071 +msgid "permanent" +msgstr "permanent" + +#: describe.c:4072 +msgid "temporary" +msgstr "temporär" + +#: describe.c:4073 +msgid "unlogged" +msgstr "ungeloggt" + +#: describe.c:4074 +msgid "Persistence" +msgstr "Persistenz" + +#: describe.c:4091 +msgid "Access method" +msgstr "Zugriffsmethode" + +#: describe.c:4183 +msgid "List of relations" +msgstr "Liste der Relationen" + +#: describe.c:4231 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "Der Server (Version %s) unterstützt keine deklarative Tabellenpartitionierung." + +#: describe.c:4242 +msgid "List of partitioned indexes" +msgstr "Liste partitionierter Indexe" + +#: describe.c:4244 +msgid "List of partitioned tables" +msgstr "Liste partitionierte Tabellen" + +#: describe.c:4248 +msgid "List of partitioned relations" +msgstr "Liste partitionierter Relationen" + +#: describe.c:4279 +msgid "Parent name" +msgstr "Elternname" + +#: describe.c:4292 +msgid "Leaf partition size" +msgstr "Größe Leaf-Partition" + +#: describe.c:4295 describe.c:4301 +msgid "Total size" +msgstr "Gesamtgröße" + +#: describe.c:4425 +msgid "Trusted" +msgstr "Vertraut" + +#: describe.c:4433 +msgid "Internal language" +msgstr "Interne Sprache" + +#: describe.c:4434 +msgid "Call handler" +msgstr "Call-Handler" + +#: describe.c:4435 describe.c:5699 +msgid "Validator" +msgstr "Validator" + +#: describe.c:4438 +msgid "Inline handler" +msgstr "Inline-Handler" + +#: describe.c:4466 +msgid "List of languages" +msgstr "Liste der Sprachen" + +#: describe.c:4511 +msgid "Check" +msgstr "Check" + +#: describe.c:4553 +msgid "List of domains" +msgstr "Liste der Domänen" + +#: describe.c:4587 +msgid "Source" +msgstr "Quelle" + +#: describe.c:4588 +msgid "Destination" +msgstr "Ziel" + +#: describe.c:4590 describe.c:6525 +msgid "Default?" +msgstr "Standard?" + +#: describe.c:4627 +msgid "List of conversions" +msgstr "Liste der Konversionen" + +#: describe.c:4666 +msgid "Event" +msgstr "Ereignis" + +#: describe.c:4668 +msgid "enabled" +msgstr "eingeschaltet" + +#: describe.c:4669 +msgid "replica" +msgstr "Replika" + +#: describe.c:4670 +msgid "always" +msgstr "immer" + +#: describe.c:4671 +msgid "disabled" +msgstr "ausgeschaltet" + +#: describe.c:4672 describe.c:6413 +msgid "Enabled" +msgstr "Eingeschaltet" + +#: describe.c:4674 +msgid "Tags" +msgstr "Tags" + +#: describe.c:4693 +msgid "List of event triggers" +msgstr "Liste der Ereignistrigger" + +#: describe.c:4720 +#, c-format +msgid "The server (version %s) does not support extended statistics." +msgstr "Der Server (Version %s) unterstützt keine erweiterten Statistiken." + +#: describe.c:4757 +msgid "Ndistinct" +msgstr "Ndistinct" + +#: describe.c:4758 +msgid "Dependencies" +msgstr "Abhängigkeiten" + +#: describe.c:4768 +msgid "MCV" +msgstr "MCV" + +#: describe.c:4787 +msgid "List of extended statistics" +msgstr "Liste der erweiterten Statistiken" + +#: describe.c:4814 +msgid "Source type" +msgstr "Quelltyp" + +#: describe.c:4815 +msgid "Target type" +msgstr "Zieltyp" + +#: describe.c:4846 +msgid "in assignment" +msgstr "in Zuweisung" + +#: describe.c:4848 +msgid "Implicit?" +msgstr "Implizit?" + +#: describe.c:4903 +msgid "List of casts" +msgstr "Liste der Typumwandlungen" + +#: describe.c:4931 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "Der Server (Version %s) unterstützt keine Sortierfolgen." + +#: describe.c:4952 describe.c:4956 +msgid "Provider" +msgstr "Provider" + +#: describe.c:4962 describe.c:4967 +msgid "Deterministic?" +msgstr "Deterministisch?" + +#: describe.c:5002 +msgid "List of collations" +msgstr "Liste der Sortierfolgen" + +#: describe.c:5061 +msgid "List of schemas" +msgstr "Liste der Schemas" + +#: describe.c:5086 describe.c:5333 describe.c:5404 describe.c:5475 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "Der Server (Version %s) unterstützt keine Volltextsuche." + +#: describe.c:5121 +msgid "List of text search parsers" +msgstr "Liste der Textsucheparser" + +#: describe.c:5166 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "Kein Textsucheparser namens »%s« gefunden" + +#: describe.c:5169 +#, c-format +msgid "Did not find any text search parsers." +msgstr "Keine Textsucheparser gefunden" + +#: describe.c:5244 +msgid "Start parse" +msgstr "Parsen starten" + +#: describe.c:5245 +msgid "Method" +msgstr "Methode" + +#: describe.c:5249 +msgid "Get next token" +msgstr "Nächstes Token lesen" + +#: describe.c:5251 +msgid "End parse" +msgstr "Parsen beenden" + +#: describe.c:5253 +msgid "Get headline" +msgstr "Überschrift ermitteln" + +#: describe.c:5255 +msgid "Get token types" +msgstr "Tokentypen ermitteln" + +#: describe.c:5266 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Textsucheparser »%s.%s«" + +#: describe.c:5269 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "Textsucheparser »%s«" + +#: describe.c:5288 +msgid "Token name" +msgstr "Tokenname" + +#: describe.c:5299 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "Tokentypen für Parser »%s.%s«" + +#: describe.c:5302 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "Tokentypen für Parser »%s«" + +#: describe.c:5356 +msgid "Template" +msgstr "Vorlage" + +#: describe.c:5357 +msgid "Init options" +msgstr "Initialisierungsoptionen" + +#: describe.c:5379 +msgid "List of text search dictionaries" +msgstr "Liste der Textsuchewörterbücher" + +#: describe.c:5422 +msgid "Init" +msgstr "Init" + +#: describe.c:5423 +msgid "Lexize" +msgstr "Lexize" + +#: describe.c:5450 +msgid "List of text search templates" +msgstr "Liste der Textsuchevorlagen" + +#: describe.c:5510 +msgid "List of text search configurations" +msgstr "Liste der Textsuchekonfigurationen" + +#: describe.c:5556 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "Keine Textsuchekonfiguration namens »%s« gefunden" + +#: describe.c:5559 +#, c-format +msgid "Did not find any text search configurations." +msgstr "Keine Textsuchekonfigurationen gefunden" + +#: describe.c:5625 +msgid "Token" +msgstr "Token" + +#: describe.c:5626 +msgid "Dictionaries" +msgstr "Wörterbücher" + +#: describe.c:5637 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Textsuchekonfiguration »%s.%s«" + +#: describe.c:5640 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Textsuchekonfiguration »%s«" + +#: describe.c:5644 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Parser: »%s.%s«" + +#: describe.c:5647 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Parser: »%s«" + +#: describe.c:5681 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "Der Server (Version %s) unterstützt keine Fremddaten-Wrapper." + +#: describe.c:5739 +msgid "List of foreign-data wrappers" +msgstr "Liste der Fremddaten-Wrapper" + +#: describe.c:5764 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "Der Server (Version %s) unterstützt keine Fremdserver." + +#: describe.c:5777 +msgid "Foreign-data wrapper" +msgstr "Fremddaten-Wrapper" + +#: describe.c:5795 describe.c:6000 +msgid "Version" +msgstr "Version" + +#: describe.c:5821 +msgid "List of foreign servers" +msgstr "Liste der Fremdserver" + +#: describe.c:5846 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "Der Server (Version %s) unterstützt keine Benutzerabbildungen." + +#: describe.c:5856 describe.c:5920 +msgid "Server" +msgstr "Server" + +#: describe.c:5857 +msgid "User name" +msgstr "Benutzername" + +#: describe.c:5882 +msgid "List of user mappings" +msgstr "Liste der Benutzerabbildungen" + +#: describe.c:5907 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "Der Server (Version %s) unterstützt keine Fremdtabellen." + +#: describe.c:5960 +msgid "List of foreign tables" +msgstr "Liste der Fremdtabellen" + +#: describe.c:5985 describe.c:6042 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "Der Server (Version %s) unterstützt keine Erweiterungen." + +#: describe.c:6017 +msgid "List of installed extensions" +msgstr "Liste der installierten Erweiterungen" + +#: describe.c:6070 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "Keine Erweiterung namens »%s« gefunden" + +#: describe.c:6073 +#, c-format +msgid "Did not find any extensions." +msgstr "Keine Erweiterungen gefunden" + +#: describe.c:6117 +msgid "Object description" +msgstr "Objektbeschreibung" + +#: describe.c:6127 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "Objekte in Erweiterung »%s«" + +#: describe.c:6156 describe.c:6232 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "Der Server (Version %s) unterstützt keine Publikationen." + +#: describe.c:6173 describe.c:6310 +msgid "All tables" +msgstr "Alle Tabellen" + +#: describe.c:6174 describe.c:6311 +msgid "Inserts" +msgstr "Inserts" + +#: describe.c:6175 describe.c:6312 +msgid "Updates" +msgstr "Updates" + +#: describe.c:6176 describe.c:6313 +msgid "Deletes" +msgstr "Deletes" + +#: describe.c:6180 describe.c:6315 +msgid "Truncates" +msgstr "Truncates" + +#: describe.c:6184 describe.c:6317 +msgid "Via root" +msgstr "Über Wurzel" + +#: describe.c:6201 +msgid "List of publications" +msgstr "Liste der Publikationen" + +#: describe.c:6274 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "Keine Publikation namens »%s« gefunden" + +#: describe.c:6277 +#, c-format +msgid "Did not find any publications." +msgstr "Keine Publikationen gefunden" + +#: describe.c:6306 +#, c-format +msgid "Publication %s" +msgstr "Publikation %s" + +#: describe.c:6354 +msgid "Tables:" +msgstr "Tabellen:" + +#: describe.c:6398 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "Der Server (Version %s) unterstützt keine Subskriptionen." + +#: describe.c:6414 +msgid "Publication" +msgstr "Publikation" + +#: describe.c:6423 +msgid "Binary" +msgstr "Binär" + +#: describe.c:6424 +msgid "Streaming" +msgstr "Streaming" + +#: describe.c:6429 +msgid "Synchronous commit" +msgstr "Synchroner Commit" + +#: describe.c:6430 +msgid "Conninfo" +msgstr "Verbindungsinfo" + +#: describe.c:6452 +msgid "List of subscriptions" +msgstr "Liste der Subskriptionen" + +#: describe.c:6519 describe.c:6607 describe.c:6692 describe.c:6775 +msgid "AM" +msgstr "AM" + +#: describe.c:6520 +msgid "Input type" +msgstr "Eingabetyp" + +#: describe.c:6521 +msgid "Storage type" +msgstr "Storage-Typ" + +#: describe.c:6522 +msgid "Operator class" +msgstr "Operatorklasse" + +#: describe.c:6534 describe.c:6608 describe.c:6693 describe.c:6776 +msgid "Operator family" +msgstr "Operatorfamilie" + +#: describe.c:6566 +msgid "List of operator classes" +msgstr "Liste der Operatorklassen" + +#: describe.c:6609 +msgid "Applicable types" +msgstr "Passende Typen" + +#: describe.c:6647 +msgid "List of operator families" +msgstr "Liste der Operatorfamilien" + +#: describe.c:6694 +msgid "Operator" +msgstr "Operator" + +#: describe.c:6695 +msgid "Strategy" +msgstr "Strategie" + +#: describe.c:6696 +msgid "ordering" +msgstr "Sortieren" + +#: describe.c:6697 +msgid "search" +msgstr "Suchen" + +#: describe.c:6698 +msgid "Purpose" +msgstr "Zweck" + +#: describe.c:6703 +msgid "Sort opfamily" +msgstr "Sortier-Opfamilie" + +#: describe.c:6734 +msgid "List of operators of operator families" +msgstr "Liste der Operatoren in Operatorfamilien" + +#: describe.c:6777 +msgid "Registered left type" +msgstr "Registrierter linker Typ" + +#: describe.c:6778 +msgid "Registered right type" +msgstr "Registrierter rechter Typ" + +#: describe.c:6779 +msgid "Number" +msgstr "Nummer" + +#: describe.c:6815 +msgid "List of support functions of operator families" +msgstr "Liste der Unterstützungsfunktionen in Operatorfamilien" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql ist das interaktive PostgreSQL-Terminal.\n" +"\n" + +#: help.c:74 help.c:355 help.c:433 help.c:476 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [OPTION]... [DBNAME [BENUTZERNAME]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Allgemeine Optionen:\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr " -c, --command=ANWEISUNG einzelne Anweisung ausführen und beenden\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr "" +" -d, --dbname=DBNAME Datenbank, zu der verbunden werden soll\n" +" (Standard: »%s«)\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=DATEINAME Anweisungen aus Datei ausführen und danach beenden\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, --list verfügbare Datenbanken auflisten und beenden\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=NAME=WERT\n" +" psql-Variable NAME auf WERT setzen\n" +" (z.B. -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc Startdatei (~/.psqlrc) nicht lesen\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 (»eins«), --single-transaction\n" +" als eine einzige Transaktion ausführen (wenn nicht\n" +" interaktiv)\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] diese Hilfe anzeigen, dann beenden\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands Backslash-Befehle auflisten, dann beenden\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables besondere Variablen auflisten, dann beenden\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Eingabe- und Ausgabeoptionen:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all Skript-Inhalt wiedergeben\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors fehlgeschlagene Anweisungen wiedergeben\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, --echo-queries an den Server geschickte Anweisungen zeigen\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden von internen Anweisungen erzeugte Anfragen zeigen\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr "" +" -L, --log-file=DATEINAME\n" +" Sitzungslog in Datei senden\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, --no-readline erweiterte Zeilenbearbeitung (Readline) ausschalten\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, --output=DATEINAME Anfrageergebnisse in Datei (oder |Pipe) senden\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr "" +" -q, --quiet stille Ausführung (keine Mitteilungen, nur\n" +" Anfrageergebnisse)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, --single-step Einzelschrittmodus (jede Anfrage bestätigen)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr " -S, --single-line Einzelzeilenmodus (Zeilenende beendet SQL-Anweisung)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Ausgabeformatoptionen:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align unausgerichteter Tabellenausgabemodus\n" + +#: help.c:111 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv Tabellenausgabemodus CSV (Comma-Separated Values)\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, --field-separator=ZEICHEN\n" +" Feldtrennzeichen für unausgerichteten Ausgabemodus\n" +" (Standard: »%s«)\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html HTML-Tabellenausgabemodus\n" + +#: help.c:116 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr "" +" -P, --pset=VAR[=ARG] Ausgabeoption VAR auf ARG setzen (siehe\n" +" \\pset-Anweisung)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, --record-separator=ZEICHEN\n" +" Satztrennzeichen für unausgerichteten Ausgabemodus\n" +" (Standard: Newline)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only nur Datenzeilen ausgeben\n" + +#: help.c:120 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr " -T, --table-attr=TEXT HTML »table«-Tag-Attribute setzen (z.B. width, border)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded erweiterte Tabellenausgabe einschalten\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" Feldtrennzeichen für unausgerichteten Ausgabemodus auf\n" +" Null-Byte setzen\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" Satztrennzeichen für unausgerichteten Ausgabemodus auf\n" +" Null-Byte setzen\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Verbindungsoptionen:\n" + +#: help.c:130 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr "" +" -h, --host=HOSTNAME Hostname des Datenbankservers oder\n" +" Socket-Verzeichnis (Standard: »%s«)\n" + +#: help.c:131 +msgid "local socket" +msgstr "lokales Socket" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, --port=PORT Port des Datenbankservers (Standard: »%s«)\n" + +#: help.c:137 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, --username=NAME Datenbank-Benutzername (Standard: »%s«)\n" + +#: help.c:138 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password niemals nach Passwort fragen\n" + +#: help.c:139 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password nach Passwort fragen (sollte automatisch geschehen)\n" + +#: help.c:141 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"Für mehr Informationen, geben Sie »\\?« (für interne Anweisungen) oder\n" +"»\\help« (für SQL-Anweisungen) in psql ein oder schauen Sie in den psql-\n" +"Abschnitt der PostgreSQL-Dokumentation.\n" +"\n" + +#: help.c:144 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Berichten Sie Fehler an <%s>.\n" + +#: help.c:145 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s Homepage: <%s>\n" + +#: help.c:171 +#, c-format +msgid "General\n" +msgstr "Allgemein\n" + +#: help.c:172 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright PostgreSQL-Urheberrechtsinformationen zeigen\n" + +#: help.c:173 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr "" +" \\crosstabview [SPALTEN] Anfrage ausführen und Ergebnisse als Kreuztabelle\n" +" anzeigen\n" + +#: help.c:174 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose letzte Fehlermeldung mit vollen Details anzeigen\n" + +#: help.c:175 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(OPT)] [DATEI] SQL-Anweisung ausführen (und Ergebnis in Datei oder\n" +" |Pipe schreiben); \\g ohne Argumente entspricht Semikolon\n" + +#: help.c:177 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc Ergebnis der Anfrage beschreiben ohne sie auszuführen\n" + +#: help.c:178 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr "" +" \\gexec Anfrage ausführen, dann jeden Ergebniswert als\n" +" Anweisung ausführen\n" + +#: help.c:179 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr "" +" \\gset [PREFIX] SQL-Anweisung ausführen und Ergebnis in psql-Variablen\n" +" ablegen\n" + +#: help.c:180 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [(OPT)] [DATEI] wie \\g, aber mit erweitertem Ausgabemodus\n" + +#: help.c:181 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q psql beenden\n" + +#: help.c:182 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SEK] Anfrage alle SEK Sekunden ausführen\n" + +#: help.c:185 +#, c-format +msgid "Help\n" +msgstr "Hilfe\n" + +#: help.c:187 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commands] Hilfe über Backslash-Befehle anzeigen\n" + +#: help.c:188 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? options Hilfe über psql-Kommandozeilenoptionen anzeigen\n" + +#: help.c:189 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables Hilfe über besondere Variablen anzeigen\n" + +#: help.c:190 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr " \\h [NAME] Syntaxhilfe über SQL-Anweisung, * für alle Anweisungen\n" + +#: help.c:193 +#, c-format +msgid "Query Buffer\n" +msgstr "Anfragepuffer\n" + +#: help.c:194 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr " \\e [DATEI] [ZEILE] Anfragepuffer (oder Datei) mit externem Editor bearbeiten\n" + +#: help.c:195 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [FUNKNAME [ZEILE]] Funktionsdefinition mit externem Editor bearbeiten\n" + +#: help.c:196 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr " \\ev [SICHTNAME [ZEILE]] Sichtdefinition mit externem Editor bearbeiten\n" + +#: help.c:197 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p aktuellen Inhalt der Anfragepuffers zeigen\n" + +#: help.c:198 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r Anfragepuffer löschen\n" + +#: help.c:200 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [DATEI] Befehlsgeschichte ausgeben oder in Datei schreiben\n" + +#: help.c:202 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w DATEI Anfragepuffer in Datei schreiben\n" + +#: help.c:205 +#, c-format +msgid "Input/Output\n" +msgstr "Eingabe/Ausgabe\n" + +#: help.c:206 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr " \\copy ... SQL COPY mit Datenstrom auf Client-Host ausführen\n" + +#: help.c:207 +#, c-format +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr " \\echo [-n] [TEXT] Text auf Standardausgabe schreiben (-n für ohne Newline)\n" + +#: help.c:208 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i DATEI Befehle aus Datei ausführen\n" + +#: help.c:209 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr " \\ir DATEI wie \\i, aber relativ zum Ort des aktuellen Skripts\n" + +#: help.c:210 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [DATEI] alle Anfrageergebnisse in Datei oder |Pipe schreiben\n" + +#: help.c:211 +#, c-format +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr "" +" \\qecho [-n] [TEXT] Text auf Ausgabestrom für \\o schreiben (-n für ohne\n" +" Newline)\n" + +#: help.c:212 +#, c-format +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr "" +" \\warn [-n] [TEXT] Text auf Standardfehlerausgabe schreiben (-n für ohne\n" +" Newline)\n" + +#: help.c:215 +#, c-format +msgid "Conditional\n" +msgstr "Bedingte Anweisungen\n" + +#: help.c:216 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if AUSDRUCK Beginn einer bedingten Anweisung\n" + +#: help.c:217 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif AUSDRUCK Alternative in aktueller bedingter Anweisung\n" + +#: help.c:218 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else letzte Alternative in aktueller bedingter Anweisung\n" + +#: help.c:219 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif Ende einer bedingten Anweisung\n" + +#: help.c:222 +#, c-format +msgid "Informational\n" +msgstr "Informationen\n" + +#: help.c:223 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (Optionen: S = Systemobjekte zeigen, + = zusätzliche Details zeigen)\n" + +#: help.c:224 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] Tabellen, Sichten und Sequenzen auflisten\n" + +#: help.c:225 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+] NAME Tabelle, Sicht, Sequenz oder Index beschreiben\n" + +#: help.c:226 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [MUSTER] Aggregatfunktionen auflisten\n" + +#: help.c:227 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [MUSTER] Zugriffsmethoden auflisten\n" + +#: help.c:228 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMMUST [TYPMUST]] Operatorklassen auflisten\n" + +#: help.c:229 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMMUST [TYPMUST]] Operatorfamilien auflisten\n" + +#: help.c:230 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMMUST [OPFMUST]] Operatoren in Operatorfamilien auflisten\n" + +#: help.c:231 +#, c-format +msgid " \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp [AMMUST [OPFMUST]] Unterst.funktionen in Operatorfamilien auflisten\n" + +#: help.c:232 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [MUSTER] Tablespaces auflisten\n" + +#: help.c:233 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [MUSTER] Konversionen auflisten\n" + +#: help.c:234 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [MUSTER] Typumwandlungen (Casts) auflisten\n" + +#: help.c:235 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr "" +" \\dd[S] [MUSTER] Objektbeschreibungen zeigen, die nirgendwo anders\n" +" erscheinen\n" + +#: help.c:236 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [MUSTER] Domänen auflisten\n" + +#: help.c:237 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [MUSTER] Vorgabeprivilegien auflisten\n" + +#: help.c:238 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [MUSTER] Fremdtabellen auflisten\n" + +#: help.c:239 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [MUSTER] Fremdtabellen auflisten\n" + +#: help.c:240 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [MUSTER] Fremdserver auflisten\n" + +#: help.c:241 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [MUSTER] Benutzerabbildungen auflisten\n" + +#: help.c:242 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [MUSTER] Fremddaten-Wrapper auflisten\n" + +#: help.c:243 +#, c-format +msgid "" +" \\df[anptw][S+] [FUNCPTRN [TYPEPTRN ...]]\n" +" list [only agg/normal/procedure/trigger/window] functions\n" +msgstr "" +" \\df[anptw][S+] [FUNKMUSTR [TYPMUSTR ...]]\n" +" Funktionen [nur Agg/normale/Proz/Trigger/Fenster] auflisten\n" + +#: help.c:245 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [MUSTER] Textsuchekonfigurationen auflisten\n" + +#: help.c:246 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [MUSTER] Textsuchewörterbücher auflisten\n" + +#: help.c:247 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [MUSTER] Textsucheparser auflisten\n" + +#: help.c:248 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [MUSTER] Textsuchevorlagen auflisten\n" + +#: help.c:249 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [MUSTER] Rollen auflisten\n" + +#: help.c:250 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [MUSTER] Indexe auflisten\n" + +#: help.c:251 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl Large Objects auflisten, wie \\lo_list\n" + +#: help.c:252 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [MUSTER] prozedurale Sprachen auflisten\n" + +#: help.c:253 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [MUSTER] materialisierte Sichten auflisten\n" + +#: help.c:254 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [MUSTER] Schemas auflisten\n" + +#: help.c:255 +#, c-format +msgid "" +" \\do[S] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" +" list operators\n" +msgstr "" +" \\do[S] [OPMUST [TYPMUST [TYPMUST]]]\n" +" Operatoren auflisten\n" + +#: help.c:257 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [MUSTER] Sortierfolgen auflisten\n" + +#: help.c:258 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr "" +" \\dp [MUSTER] Zugriffsprivilegien für Tabellen, Sichten und\n" +" Sequenzen auflisten\n" + +#: help.c:259 +#, c-format +msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" +msgstr "" +" \\dP[itn+] [MUSTER] partitionierte Relationen [nur Indexe/Tabellen]\n" +" auflisten [n=geschachtelt]\n" + +#: help.c:260 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [MUSTER1 [MUSTER2]] datenbankspezifische Rolleneinstellungen auflisten\n" + +#: help.c:261 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [MUSTER] Replikationspublikationen auflisten\n" + +#: help.c:262 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [MUSTER] Replikationssubskriptionen auflisten\n" + +#: help.c:263 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [MUSTER] Sequenzen auflisten\n" + +#: help.c:264 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [MUSTER] Tabellen auflisten\n" + +#: help.c:265 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [MUSTER] Datentypen auflisten\n" + +#: help.c:266 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [MUSTER] Rollen auflisten\n" + +#: help.c:267 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [MUSTER] Sichten auflisten\n" + +#: help.c:268 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [MUSTER] Erweiterungen auflisten\n" + +#: help.c:269 +#, c-format +msgid " \\dX [PATTERN] list extended statistics\n" +msgstr " \\dX [MUSTER] erweiterte Statistiken auflisten\n" + +#: help.c:270 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [MUSTER] Ereignistrigger auflisten\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [MUSTER] Datenbanken auflisten\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] FUNKNAME Funktionsdefinition zeigen\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] SICHTNAME Sichtdefinition zeigen\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [MUSTER] äquivalent zu \\dp\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "Formatierung\n" + +#: help.c:278 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr "" +" \\a zwischen unausgerichtetem und ausgerichtetem Ausgabemodus\n" +" umschalten\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr " \\C [TEXT] Tabellentitel setzen oder löschen\n" + +#: help.c:280 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr " \\f [ZEICHEN] Feldtrennzeichen zeigen oder setzen\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H HTML-Ausgabemodus umschalten (gegenwärtig %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [NAME [WERT]] Tabellenausgabeoption setzen\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] nur Datenzeilen zeigen (gegenwärtig %s)\n" + +#: help.c:292 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr " \\T [TEXT] HTML
-Tag-Attribute setzen oder löschen\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] erweiterte Ausgabe umschalten (gegenwärtig %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "Verbindung\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[DBNAME|- BENUTZER|- HOST|- PORT|-] | conninfo}\n" +" mit neuer Datenbank verbinden (aktuell »%s«)\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[DBNAME|- BENUTZER|- HOST|- PORT|-] | conninfo}\n" +" mit neuer Datenbank verbinden (aktuell keine Verbindung)\n" + +#: help.c:305 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo Informationen über aktuelle Verbindung anzeigen\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [KODIERUNG] Client-Kodierung zeigen oder setzen\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr "" +" \\password [BENUTZERNAME]\n" +" sicheres Ändern eines Benutzerpasswortes\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "Betriebssystem\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [VERZ] Arbeitsverzeichnis wechseln\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv NAME [WERT] Umgebungsvariable setzen oder löschen\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] Zeitmessung umschalten (gegenwärtig %s)\n" + +#: help.c:315 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr " \\! [BEFEHL] Befehl in Shell ausführen oder interaktive Shell starten\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "Variablen\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr " \\prompt [TEXT] NAME interne Variable vom Benutzer abfragen\n" + +#: help.c:320 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr " \\set [NAME [WERT]] interne Variable setzen, oder alle anzeigen\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset NAME interne Variable löschen\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "Large Objects\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID DATEI\n" +" \\lo_import DATEI [KOMMENTAR]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID Large-Object-Operationen\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"Liste besonderer Variablen\n" +"\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "psql-Variablen:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=NAME=WERT\n" +" oder \\set NAME WERT innerhalb von psql\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" wenn gesetzt werden alle erfolgreichen SQL-Befehle automatisch committet\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" bestimmt, ob SQL-Schlüsselwörter in Groß- oder Kleinschreibung\n" +" vervollständigt werden [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" Name der aktuellen Datenbank\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" kontrolliert, welche Eingaben auf die Standardausgabe geschrieben werden\n" +" [all, errors, none, queries]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" wenn gesetzt, interne Anfragen, die von Backslash-Befehlen ausgeführt werden,\n" +" anzeigen; wenn auf »noexec« gesetzt, nur anzeigen, nicht ausführen\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" aktuelle Zeichensatzkodierung des Clients\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" »true« wenn die letzte Anfrage fehlgeschlagen ist, sonst »false«\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" Anzahl auf einmal zu holender und anzuzeigender Zeilen (0 = unbegrenzt)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TOAST_COMPRESSION\n" +" if set, compression methods are not displayed\n" +msgstr "" +" HIDE_TOAST_COMPRESSION\n" +" wenn gesetzt werden Kompressionsmethoden nicht angezeigt\n" + +#: help.c:379 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" wenn gesetzt werden Tabellenzugriffsmethoden nicht angezeigt\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" kontrolliert Befehlsgeschichte [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" Dateiname für die Befehlsgeschichte\n" + +#: help.c:385 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" maximale Anzahl der in der Befehlsgeschichte zu speichernden Befehle\n" + +#: help.c:387 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" der aktuell verbundene Datenbankserverhost\n" + +#: help.c:389 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" Anzahl benötigter EOFs um eine interaktive Sitzung zu beenden\n" + +#: help.c:391 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" Wert der zuletzt beinträchtigten OID\n" + +#: help.c:393 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" Fehlermeldung und SQLSTATE des letzten Fehlers, oder leer und »000000« wenn\n" +" kein Fehler\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" wenn gesetzt beendet ein Fehler die Transaktion nicht (verwendet implizite\n" +" Sicherungspunkte)\n" + +#: help.c:398 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" Skriptausführung bei Fehler beenden\n" + +#: help.c:400 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" Serverport der aktuellen Verbindung\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" der normale psql-Prompt\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" der Prompt, wenn eine Anweisung von der vorherigen Zeile fortgesetzt wird\n" + +#: help.c:406 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" der Prompt während COPY ... FROM STDIN\n" + +#: help.c:408 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" stille Ausführung (wie Option -q)\n" + +#: help.c:410 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" Anzahl der von der letzten Anfrage beeinträchtigten Zeilen, oder 0\n" + +#: help.c:412 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" Serverversion (kurze Zeichenkette oder numerisches Format)\n" + +#: help.c:415 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" kontrolliert die Anzeige von Kontextinformationen in Meldungen\n" +" [never, errors, always]\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" wenn gesetzt beendet Zeilenende die SQL-Anweisung (wie Option -S)\n" + +#: help.c:419 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" Einzelschrittmodus (wie Option -s)\n" + +#: help.c:421 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE der letzten Anfrage, oder »00000« wenn kein Fehler\n" + +#: help.c:423 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" der aktuell verbundene Datenbankbenutzer\n" + +#: help.c:425 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" kontrolliert wieviele Details in Fehlermeldungen enthalten sind\n" +" [default, verbose, terse, sqlstate]\n" + +#: help.c:427 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" Version von psql (lange Zeichenkette, kurze Zeichenkette oder numerisch)\n" + +#: help.c:432 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Anzeigeeinstellungen:\n" + +#: help.c:434 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NAME[=WERT]\n" +" oder \\pset NAME [WERT] innerhalb von psql\n" +"\n" + +#: help.c:436 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" Rahmenstil (Zahl)\n" + +#: help.c:438 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" Zielbreite für das Format »wrapped«\n" + +#: help.c:440 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (oder x)\n" +" erweiterte Ausgabe [on, off, auto]\n" + +#: help.c:442 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" Feldtrennzeichen für unausgerichteten Ausgabemodus (Standard »%s«)\n" + +#: help.c:445 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" Feldtrennzeichen für unausgerichteten Ausgabemodus auf Null-Byte setzen\n" + +#: help.c:447 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" Tabellenfußzeile ein- oder auschalten [on, off]\n" + +#: help.c:449 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" Ausgabeformat setzen [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:451 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" Rahmenlinienstil setzen [ascii, old-ascii, unicode]\n" + +#: help.c:453 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" setzt die Zeichenkette, die anstelle eines NULL-Wertes ausgegeben wird\n" + +#: help.c:455 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +" numericlocale\n" +" Verwendung eines Locale-spezifischen Zeichens zur Trennung von Zifferngruppen\n" +" einschalten [on, off]\n" + +#: help.c:457 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" kontrolliert Verwendung eines externen Pager-Programms [yes, no, always]\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" Satztrennzeichen für unausgerichteten Ausgabemodus\n" + +#: help.c:461 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" Satztrennzeichen für unausgerichteten Ausgabemodus auf Null-Byte setzen\n" + +#: help.c:463 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (or T)\n" +" Attribute für das »table«-Tag im Format »html« oder proportionale\n" +" Spaltenbreite für links ausgerichtete Datentypen im Format »latex-longtable«\n" + +#: help.c:466 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" setzt den Titel darauffolgend ausgegebener Tabellen\n" + +#: help.c:468 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" wenn gesetzt werden nur die eigentlichen Tabellendaten gezeigt\n" + +#: help.c:470 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" setzt den Stil für Unicode-Linien [single, double]\n" + +#: help.c:475 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Umgebungsvariablen:\n" + +#: help.c:479 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NAME=WERT [NAME=WERT] psql ...\n" +" oder \\setenv NAME [WERT] innerhalb von psql\n" +"\n" + +#: help.c:481 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NAME=WERT\n" +" psql ...\n" +" oder \\setenv NAME [WERT] innerhalb von psql\n" +"\n" + +#: help.c:484 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" Anzahl Spalten im Format »wrapped«\n" + +#: help.c:486 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" wie Verbindungsparameter »application_name«\n" + +#: help.c:488 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" wie Verbindungsparameter »dbname«\n" + +#: help.c:490 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" wie Verbindungsparameter »host«\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" Verbindungspasswort (nicht empfohlen)\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" Name der Passwortdatei\n" + +#: help.c:496 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" wie Verbindungsparameter »port«\n" + +#: help.c:498 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" wie Verbindungsparameter »user«\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" Editor für Befehle \\e, \\ef und \\ev\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" wie die Zeilennummer beim Aufruf des Editors angegeben wird\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" alternativer Pfad für History-Datei\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" Name des externen Pager-Programms\n" + +#: help.c:508 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" alternativer Pfad für .psqlrc-Datei des Benutzers\n" + +#: help.c:510 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" Shell für den Befehl \\!\n" + +#: help.c:512 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" Verzeichnis für temporäre Dateien\n" + +#: help.c:557 +msgid "Available help:\n" +msgstr "Verfügbare Hilfe:\n" + +#: help.c:652 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"Anweisung: %s\n" +"Beschreibung: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" + +#: help.c:675 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"Keine Hilfe verfügbar für »%s«.\n" +"Versuchen Sie \\h ohne Argumente, um die verfügbare Hilfe zu sehen.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "konnte nicht aus Eingabedatei lesen: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "konnte Befehlsgeschichte nicht in Datei »%s« speichern: %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "Befehlsgeschichte wird von dieser Installation nicht unterstützt" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: nicht mit einer Datenbank verbunden" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: aktuelle Transaktion ist abgebrochen" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: unbekannter Transaktionsstatus" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "Large Objects" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if: abgebrochen" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "Verwenden Sie »\\q«, um %s zu verlassen.\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Die Eingabe ist ein PostgreSQL-Dump im Custom-Format.\n" +"Verwenden Sie den Kommandozeilen-Client pg_restore, um diesen Dump in die\n" +"Datenbank zurückzuspielen.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Verwenden Sie \\? für Hilfe oder drücken Sie Strg-C um den Eingabepuffer zu löschen." + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "Verwenden Sie \\? für Hilfe." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "Dies ist psql, die Kommandozeilenschnittstelle für PostgreSQL." + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Geben Sie ein: \\copyright für Urheberrechtsinformationen\n" +" \\h für Hilfe über SQL-Anweisungen\n" +" \\? für Hilfe über interne Anweisungen\n" +" \\g oder Semikolon, um eine Anfrage auszuführen\n" +" \\q um zu beenden\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "Verwenden Sie \\q zum beenden." + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "Verwenden Sie Strg-D zum beenden." + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "Verwenden Sie Strg-C zum beenden." + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "Anfrage ignoriert; verwenden Sie \\endif oder Strg-C um den aktuellen \\if-Block zu beenden" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "Dateiende erreicht, aber schließendes \\endif fehlt" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "Zeichenkette in Anführungszeichen nicht abgeschlossen" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: Speicher aufgebraucht" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:63 sql_help.c:65 +#: sql_help.c:67 sql_help.c:78 sql_help.c:80 sql_help.c:82 sql_help.c:108 +#: sql_help.c:114 sql_help.c:116 sql_help.c:118 sql_help.c:120 sql_help.c:123 +#: sql_help.c:125 sql_help.c:127 sql_help.c:232 sql_help.c:234 sql_help.c:235 +#: sql_help.c:237 sql_help.c:239 sql_help.c:242 sql_help.c:244 sql_help.c:246 +#: sql_help.c:248 sql_help.c:260 sql_help.c:261 sql_help.c:262 sql_help.c:264 +#: sql_help.c:313 sql_help.c:315 sql_help.c:317 sql_help.c:319 sql_help.c:388 +#: sql_help.c:393 sql_help.c:395 sql_help.c:437 sql_help.c:439 sql_help.c:442 +#: sql_help.c:444 sql_help.c:512 sql_help.c:517 sql_help.c:522 sql_help.c:527 +#: sql_help.c:532 sql_help.c:587 sql_help.c:589 sql_help.c:591 sql_help.c:593 +#: sql_help.c:595 sql_help.c:597 sql_help.c:600 sql_help.c:602 sql_help.c:605 +#: sql_help.c:616 sql_help.c:618 sql_help.c:660 sql_help.c:662 sql_help.c:664 +#: sql_help.c:667 sql_help.c:669 sql_help.c:671 sql_help.c:706 sql_help.c:710 +#: sql_help.c:714 sql_help.c:733 sql_help.c:736 sql_help.c:739 sql_help.c:768 +#: sql_help.c:780 sql_help.c:788 sql_help.c:791 sql_help.c:794 sql_help.c:809 +#: sql_help.c:812 sql_help.c:841 sql_help.c:846 sql_help.c:851 sql_help.c:856 +#: sql_help.c:861 sql_help.c:883 sql_help.c:885 sql_help.c:887 sql_help.c:889 +#: sql_help.c:892 sql_help.c:894 sql_help.c:936 sql_help.c:980 sql_help.c:985 +#: sql_help.c:990 sql_help.c:995 sql_help.c:1000 sql_help.c:1019 +#: sql_help.c:1030 sql_help.c:1032 sql_help.c:1051 sql_help.c:1061 +#: sql_help.c:1063 sql_help.c:1065 sql_help.c:1077 sql_help.c:1081 +#: sql_help.c:1083 sql_help.c:1095 sql_help.c:1097 sql_help.c:1099 +#: sql_help.c:1101 sql_help.c:1119 sql_help.c:1121 sql_help.c:1125 +#: sql_help.c:1129 sql_help.c:1133 sql_help.c:1136 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1141 sql_help.c:1143 sql_help.c:1279 +#: sql_help.c:1281 sql_help.c:1284 sql_help.c:1287 sql_help.c:1289 +#: sql_help.c:1291 sql_help.c:1294 sql_help.c:1297 sql_help.c:1411 +#: sql_help.c:1413 sql_help.c:1415 sql_help.c:1418 sql_help.c:1439 +#: sql_help.c:1442 sql_help.c:1445 sql_help.c:1448 sql_help.c:1452 +#: sql_help.c:1454 sql_help.c:1456 sql_help.c:1458 sql_help.c:1472 +#: sql_help.c:1475 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1491 sql_help.c:1501 sql_help.c:1503 sql_help.c:1513 +#: sql_help.c:1516 sql_help.c:1539 sql_help.c:1541 sql_help.c:1543 +#: sql_help.c:1545 sql_help.c:1548 sql_help.c:1550 sql_help.c:1553 +#: sql_help.c:1556 sql_help.c:1607 sql_help.c:1650 sql_help.c:1653 +#: sql_help.c:1655 sql_help.c:1657 sql_help.c:1660 sql_help.c:1662 +#: sql_help.c:1664 sql_help.c:1667 sql_help.c:1717 sql_help.c:1733 +#: sql_help.c:1964 sql_help.c:2033 sql_help.c:2052 sql_help.c:2065 +#: sql_help.c:2121 sql_help.c:2127 sql_help.c:2137 sql_help.c:2158 +#: sql_help.c:2184 sql_help.c:2202 sql_help.c:2229 sql_help.c:2325 +#: sql_help.c:2371 sql_help.c:2395 sql_help.c:2418 sql_help.c:2422 +#: sql_help.c:2456 sql_help.c:2476 sql_help.c:2498 sql_help.c:2512 +#: sql_help.c:2533 sql_help.c:2557 sql_help.c:2587 sql_help.c:2612 +#: sql_help.c:2659 sql_help.c:2947 sql_help.c:2960 sql_help.c:2977 +#: sql_help.c:2993 sql_help.c:3033 sql_help.c:3087 sql_help.c:3091 +#: sql_help.c:3093 sql_help.c:3100 sql_help.c:3119 sql_help.c:3146 +#: sql_help.c:3181 sql_help.c:3193 sql_help.c:3202 sql_help.c:3246 +#: sql_help.c:3260 sql_help.c:3288 sql_help.c:3296 sql_help.c:3308 +#: sql_help.c:3318 sql_help.c:3326 sql_help.c:3334 sql_help.c:3342 +#: sql_help.c:3350 sql_help.c:3359 sql_help.c:3370 sql_help.c:3378 +#: sql_help.c:3386 sql_help.c:3394 sql_help.c:3402 sql_help.c:3412 +#: sql_help.c:3421 sql_help.c:3430 sql_help.c:3438 sql_help.c:3448 +#: sql_help.c:3459 sql_help.c:3467 sql_help.c:3476 sql_help.c:3487 +#: sql_help.c:3496 sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3528 sql_help.c:3536 sql_help.c:3544 sql_help.c:3552 +#: sql_help.c:3560 sql_help.c:3568 sql_help.c:3576 sql_help.c:3593 +#: sql_help.c:3602 sql_help.c:3610 sql_help.c:3627 sql_help.c:3642 +#: sql_help.c:3944 sql_help.c:3995 sql_help.c:4024 sql_help.c:4039 +#: sql_help.c:4524 sql_help.c:4572 sql_help.c:4723 +msgid "name" +msgstr "Name" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:324 sql_help.c:1814 +#: sql_help.c:3261 sql_help.c:4300 +msgid "aggregate_signature" +msgstr "Aggregatsignatur" + +#: sql_help.c:37 sql_help.c:64 sql_help.c:79 sql_help.c:115 sql_help.c:247 +#: sql_help.c:265 sql_help.c:396 sql_help.c:443 sql_help.c:521 sql_help.c:569 +#: sql_help.c:588 sql_help.c:617 sql_help.c:668 sql_help.c:735 sql_help.c:790 +#: sql_help.c:811 sql_help.c:850 sql_help.c:895 sql_help.c:937 sql_help.c:989 +#: sql_help.c:1021 sql_help.c:1031 sql_help.c:1064 sql_help.c:1084 +#: sql_help.c:1098 sql_help.c:1144 sql_help.c:1288 sql_help.c:1412 +#: sql_help.c:1455 sql_help.c:1476 sql_help.c:1490 sql_help.c:1502 +#: sql_help.c:1515 sql_help.c:1542 sql_help.c:1608 sql_help.c:1661 +msgid "new_name" +msgstr "neuer_Name" + +#: sql_help.c:40 sql_help.c:66 sql_help.c:81 sql_help.c:117 sql_help.c:245 +#: sql_help.c:263 sql_help.c:394 sql_help.c:479 sql_help.c:526 sql_help.c:619 +#: sql_help.c:628 sql_help.c:689 sql_help.c:709 sql_help.c:738 sql_help.c:793 +#: sql_help.c:855 sql_help.c:893 sql_help.c:994 sql_help.c:1033 sql_help.c:1062 +#: sql_help.c:1082 sql_help.c:1096 sql_help.c:1142 sql_help.c:1351 +#: sql_help.c:1414 sql_help.c:1457 sql_help.c:1478 sql_help.c:1540 +#: sql_help.c:1656 sql_help.c:2933 +msgid "new_owner" +msgstr "neuer_Eigentümer" + +#: sql_help.c:43 sql_help.c:68 sql_help.c:83 sql_help.c:249 sql_help.c:316 +#: sql_help.c:445 sql_help.c:531 sql_help.c:670 sql_help.c:713 sql_help.c:741 +#: sql_help.c:796 sql_help.c:860 sql_help.c:999 sql_help.c:1066 sql_help.c:1100 +#: sql_help.c:1290 sql_help.c:1459 sql_help.c:1480 sql_help.c:1492 +#: sql_help.c:1504 sql_help.c:1544 sql_help.c:1663 +msgid "new_schema" +msgstr "neues_Schema" + +#: sql_help.c:44 sql_help.c:1878 sql_help.c:3262 sql_help.c:4329 +msgid "where aggregate_signature is:" +msgstr "wobei Aggregatsignatur Folgendes ist:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:334 sql_help.c:347 +#: sql_help.c:351 sql_help.c:367 sql_help.c:370 sql_help.c:373 sql_help.c:513 +#: sql_help.c:518 sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:842 +#: sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:862 sql_help.c:981 +#: sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1001 sql_help.c:1832 +#: sql_help.c:1849 sql_help.c:1855 sql_help.c:1879 sql_help.c:1882 +#: sql_help.c:1885 sql_help.c:2034 sql_help.c:2053 sql_help.c:2056 +#: sql_help.c:2326 sql_help.c:2534 sql_help.c:3263 sql_help.c:3266 +#: sql_help.c:3269 sql_help.c:3360 sql_help.c:3449 sql_help.c:3477 +#: sql_help.c:3822 sql_help.c:4202 sql_help.c:4306 sql_help.c:4313 +#: sql_help.c:4319 sql_help.c:4330 sql_help.c:4333 sql_help.c:4336 +msgid "argmode" +msgstr "Argmodus" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:335 sql_help.c:348 +#: sql_help.c:352 sql_help.c:368 sql_help.c:371 sql_help.c:374 sql_help.c:514 +#: sql_help.c:519 sql_help.c:524 sql_help.c:529 sql_help.c:534 sql_help.c:843 +#: sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:863 sql_help.c:982 +#: sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1002 sql_help.c:1833 +#: sql_help.c:1850 sql_help.c:1856 sql_help.c:1880 sql_help.c:1883 +#: sql_help.c:1886 sql_help.c:2035 sql_help.c:2054 sql_help.c:2057 +#: sql_help.c:2327 sql_help.c:2535 sql_help.c:3264 sql_help.c:3267 +#: sql_help.c:3270 sql_help.c:3361 sql_help.c:3450 sql_help.c:3478 +#: sql_help.c:4307 sql_help.c:4314 sql_help.c:4320 sql_help.c:4331 +#: sql_help.c:4334 sql_help.c:4337 +msgid "argname" +msgstr "Argname" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:336 sql_help.c:349 +#: sql_help.c:353 sql_help.c:369 sql_help.c:372 sql_help.c:375 sql_help.c:515 +#: sql_help.c:520 sql_help.c:525 sql_help.c:530 sql_help.c:535 sql_help.c:844 +#: sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:864 sql_help.c:983 +#: sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1003 sql_help.c:1834 +#: sql_help.c:1851 sql_help.c:1857 sql_help.c:1881 sql_help.c:1884 +#: sql_help.c:1887 sql_help.c:2328 sql_help.c:2536 sql_help.c:3265 +#: sql_help.c:3268 sql_help.c:3271 sql_help.c:3362 sql_help.c:3451 +#: sql_help.c:3479 sql_help.c:4308 sql_help.c:4315 sql_help.c:4321 +#: sql_help.c:4332 sql_help.c:4335 sql_help.c:4338 +msgid "argtype" +msgstr "Argtyp" + +#: sql_help.c:109 sql_help.c:391 sql_help.c:468 sql_help.c:480 sql_help.c:931 +#: sql_help.c:1079 sql_help.c:1473 sql_help.c:1602 sql_help.c:1634 +#: sql_help.c:1686 sql_help.c:1749 sql_help.c:1935 sql_help.c:1942 +#: sql_help.c:2232 sql_help.c:2274 sql_help.c:2281 sql_help.c:2290 +#: sql_help.c:2372 sql_help.c:2588 sql_help.c:2681 sql_help.c:2962 +#: sql_help.c:3147 sql_help.c:3169 sql_help.c:3309 sql_help.c:3664 +#: sql_help.c:3863 sql_help.c:4038 sql_help.c:4786 +msgid "option" +msgstr "Option" + +#: sql_help.c:110 sql_help.c:932 sql_help.c:1603 sql_help.c:2373 +#: sql_help.c:2589 sql_help.c:3148 sql_help.c:3310 +msgid "where option can be:" +msgstr "wobei Option Folgendes sein kann:" + +#: sql_help.c:111 sql_help.c:2166 +msgid "allowconn" +msgstr "allowconn" + +#: sql_help.c:112 sql_help.c:933 sql_help.c:1604 sql_help.c:2167 +#: sql_help.c:2374 sql_help.c:2590 sql_help.c:3149 +msgid "connlimit" +msgstr "Verbindungslimit" + +#: sql_help.c:113 sql_help.c:2168 +msgid "istemplate" +msgstr "istemplate" + +#: sql_help.c:119 sql_help.c:607 sql_help.c:673 sql_help.c:1293 sql_help.c:1344 +#: sql_help.c:4042 +msgid "new_tablespace" +msgstr "neuer_Tablespace" + +#: sql_help.c:121 sql_help.c:124 sql_help.c:126 sql_help.c:541 sql_help.c:543 +#: sql_help.c:544 sql_help.c:867 sql_help.c:869 sql_help.c:870 sql_help.c:940 +#: sql_help.c:944 sql_help.c:947 sql_help.c:1008 sql_help.c:1010 +#: sql_help.c:1011 sql_help.c:1155 sql_help.c:1158 sql_help.c:1611 +#: sql_help.c:1615 sql_help.c:1618 sql_help.c:2338 sql_help.c:2540 +#: sql_help.c:4060 sql_help.c:4513 +msgid "configuration_parameter" +msgstr "Konfigurationsparameter" + +#: sql_help.c:122 sql_help.c:392 sql_help.c:463 sql_help.c:469 sql_help.c:481 +#: sql_help.c:542 sql_help.c:599 sql_help.c:679 sql_help.c:687 sql_help.c:868 +#: sql_help.c:891 sql_help.c:941 sql_help.c:1009 sql_help.c:1080 +#: sql_help.c:1124 sql_help.c:1128 sql_help.c:1132 sql_help.c:1135 +#: sql_help.c:1140 sql_help.c:1156 sql_help.c:1157 sql_help.c:1324 +#: sql_help.c:1346 sql_help.c:1395 sql_help.c:1417 sql_help.c:1474 +#: sql_help.c:1558 sql_help.c:1612 sql_help.c:1635 sql_help.c:2233 +#: sql_help.c:2275 sql_help.c:2282 sql_help.c:2291 sql_help.c:2339 +#: sql_help.c:2340 sql_help.c:2403 sql_help.c:2406 sql_help.c:2440 +#: sql_help.c:2541 sql_help.c:2542 sql_help.c:2560 sql_help.c:2682 +#: sql_help.c:2721 sql_help.c:2827 sql_help.c:2840 sql_help.c:2854 +#: sql_help.c:2895 sql_help.c:2919 sql_help.c:2936 sql_help.c:2963 +#: sql_help.c:3170 sql_help.c:3864 sql_help.c:4514 sql_help.c:4515 +msgid "value" +msgstr "Wert" + +#: sql_help.c:194 +msgid "target_role" +msgstr "Zielrolle" + +#: sql_help.c:195 sql_help.c:2217 sql_help.c:2637 sql_help.c:2642 +#: sql_help.c:3797 sql_help.c:3806 sql_help.c:3825 sql_help.c:3834 +#: sql_help.c:4177 sql_help.c:4186 sql_help.c:4205 sql_help.c:4214 +msgid "schema_name" +msgstr "Schemaname" + +#: sql_help.c:196 +msgid "abbreviated_grant_or_revoke" +msgstr "abgekürztes_Grant_oder_Revoke" + +#: sql_help.c:197 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "wobei abgekürztes_Grant_oder_Revoke Folgendes sein kann:" + +#: sql_help.c:198 sql_help.c:199 sql_help.c:200 sql_help.c:201 sql_help.c:202 +#: sql_help.c:203 sql_help.c:204 sql_help.c:205 sql_help.c:206 sql_help.c:207 +#: sql_help.c:567 sql_help.c:606 sql_help.c:672 sql_help.c:814 sql_help.c:951 +#: sql_help.c:1292 sql_help.c:1622 sql_help.c:2377 sql_help.c:2378 +#: sql_help.c:2379 sql_help.c:2380 sql_help.c:2381 sql_help.c:2514 +#: sql_help.c:2593 sql_help.c:2594 sql_help.c:2595 sql_help.c:2596 +#: sql_help.c:2597 sql_help.c:3152 sql_help.c:3153 sql_help.c:3154 +#: sql_help.c:3155 sql_help.c:3156 sql_help.c:3843 sql_help.c:3847 +#: sql_help.c:4223 sql_help.c:4227 sql_help.c:4534 +msgid "role_name" +msgstr "Rollenname" + +#: sql_help.c:233 sql_help.c:456 sql_help.c:1308 sql_help.c:1310 +#: sql_help.c:1361 sql_help.c:1374 sql_help.c:1399 sql_help.c:1652 +#: sql_help.c:2187 sql_help.c:2191 sql_help.c:2294 sql_help.c:2299 +#: sql_help.c:2399 sql_help.c:2698 sql_help.c:2703 sql_help.c:2705 +#: sql_help.c:2822 sql_help.c:2835 sql_help.c:2849 sql_help.c:2858 +#: sql_help.c:2870 sql_help.c:2899 sql_help.c:3895 sql_help.c:3910 +#: sql_help.c:3912 sql_help.c:4391 sql_help.c:4392 sql_help.c:4401 +#: sql_help.c:4443 sql_help.c:4444 sql_help.c:4445 sql_help.c:4446 +#: sql_help.c:4447 sql_help.c:4448 sql_help.c:4488 sql_help.c:4489 +#: sql_help.c:4494 sql_help.c:4499 sql_help.c:4640 sql_help.c:4641 +#: sql_help.c:4650 sql_help.c:4692 sql_help.c:4693 sql_help.c:4694 +#: sql_help.c:4695 sql_help.c:4696 sql_help.c:4697 sql_help.c:4751 +#: sql_help.c:4753 sql_help.c:4814 sql_help.c:4872 sql_help.c:4873 +#: sql_help.c:4882 sql_help.c:4924 sql_help.c:4925 sql_help.c:4926 +#: sql_help.c:4927 sql_help.c:4928 sql_help.c:4929 +msgid "expression" +msgstr "Ausdruck" + +#: sql_help.c:236 +msgid "domain_constraint" +msgstr "Domänen-Constraint" + +#: sql_help.c:238 sql_help.c:240 sql_help.c:243 sql_help.c:471 sql_help.c:472 +#: sql_help.c:1285 sql_help.c:1332 sql_help.c:1333 sql_help.c:1334 +#: sql_help.c:1360 sql_help.c:1373 sql_help.c:1390 sql_help.c:1820 +#: sql_help.c:1822 sql_help.c:2190 sql_help.c:2293 sql_help.c:2298 +#: sql_help.c:2857 sql_help.c:2869 sql_help.c:3907 +msgid "constraint_name" +msgstr "Constraint-Name" + +#: sql_help.c:241 sql_help.c:1286 +msgid "new_constraint_name" +msgstr "neuer_Constraint-Name" + +#: sql_help.c:314 sql_help.c:1078 +msgid "new_version" +msgstr "neue_Version" + +#: sql_help.c:318 sql_help.c:320 +msgid "member_object" +msgstr "Elementobjekt" + +#: sql_help.c:321 +msgid "where member_object is:" +msgstr "wobei Elementobjekt Folgendes ist:" + +#: sql_help.c:322 sql_help.c:327 sql_help.c:328 sql_help.c:329 sql_help.c:330 +#: sql_help.c:331 sql_help.c:332 sql_help.c:337 sql_help.c:341 sql_help.c:343 +#: sql_help.c:345 sql_help.c:354 sql_help.c:355 sql_help.c:356 sql_help.c:357 +#: sql_help.c:358 sql_help.c:359 sql_help.c:360 sql_help.c:361 sql_help.c:364 +#: sql_help.c:365 sql_help.c:1812 sql_help.c:1817 sql_help.c:1824 +#: sql_help.c:1825 sql_help.c:1826 sql_help.c:1827 sql_help.c:1828 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:1835 sql_help.c:1837 +#: sql_help.c:1841 sql_help.c:1843 sql_help.c:1847 sql_help.c:1852 +#: sql_help.c:1853 sql_help.c:1860 sql_help.c:1861 sql_help.c:1862 +#: sql_help.c:1863 sql_help.c:1864 sql_help.c:1865 sql_help.c:1866 +#: sql_help.c:1867 sql_help.c:1868 sql_help.c:1869 sql_help.c:1870 +#: sql_help.c:1875 sql_help.c:1876 sql_help.c:4296 sql_help.c:4301 +#: sql_help.c:4302 sql_help.c:4303 sql_help.c:4304 sql_help.c:4310 +#: sql_help.c:4311 sql_help.c:4316 sql_help.c:4317 sql_help.c:4322 +#: sql_help.c:4323 sql_help.c:4324 sql_help.c:4325 sql_help.c:4326 +#: sql_help.c:4327 +msgid "object_name" +msgstr "Objektname" + +#: sql_help.c:323 sql_help.c:1813 sql_help.c:4299 +msgid "aggregate_name" +msgstr "Aggregatname" + +#: sql_help.c:325 sql_help.c:1815 sql_help.c:2099 sql_help.c:2103 +#: sql_help.c:2105 sql_help.c:3279 +msgid "source_type" +msgstr "Quelltyp" + +#: sql_help.c:326 sql_help.c:1816 sql_help.c:2100 sql_help.c:2104 +#: sql_help.c:2106 sql_help.c:3280 +msgid "target_type" +msgstr "Zieltyp" + +#: sql_help.c:333 sql_help.c:778 sql_help.c:1831 sql_help.c:2101 +#: sql_help.c:2140 sql_help.c:2205 sql_help.c:2457 sql_help.c:2488 +#: sql_help.c:3039 sql_help.c:4201 sql_help.c:4305 sql_help.c:4420 +#: sql_help.c:4424 sql_help.c:4428 sql_help.c:4431 sql_help.c:4669 +#: sql_help.c:4673 sql_help.c:4677 sql_help.c:4680 sql_help.c:4901 +#: sql_help.c:4905 sql_help.c:4909 sql_help.c:4912 +msgid "function_name" +msgstr "Funktionsname" + +#: sql_help.c:338 sql_help.c:771 sql_help.c:1838 sql_help.c:2481 +msgid "operator_name" +msgstr "Operatorname" + +#: sql_help.c:339 sql_help.c:707 sql_help.c:711 sql_help.c:715 sql_help.c:1839 +#: sql_help.c:2458 sql_help.c:3403 +msgid "left_type" +msgstr "linker_Typ" + +#: sql_help.c:340 sql_help.c:708 sql_help.c:712 sql_help.c:716 sql_help.c:1840 +#: sql_help.c:2459 sql_help.c:3404 +msgid "right_type" +msgstr "rechter_Typ" + +#: sql_help.c:342 sql_help.c:344 sql_help.c:734 sql_help.c:737 sql_help.c:740 +#: sql_help.c:769 sql_help.c:781 sql_help.c:789 sql_help.c:792 sql_help.c:795 +#: sql_help.c:1379 sql_help.c:1842 sql_help.c:1844 sql_help.c:2478 +#: sql_help.c:2499 sql_help.c:2875 sql_help.c:3413 sql_help.c:3422 +msgid "index_method" +msgstr "Indexmethode" + +#: sql_help.c:346 sql_help.c:1848 sql_help.c:4312 +msgid "procedure_name" +msgstr "Prozedurname" + +#: sql_help.c:350 sql_help.c:1854 sql_help.c:3821 sql_help.c:4318 +msgid "routine_name" +msgstr "Routinenname" + +#: sql_help.c:362 sql_help.c:1350 sql_help.c:1871 sql_help.c:2334 +#: sql_help.c:2539 sql_help.c:2830 sql_help.c:3006 sql_help.c:3584 +#: sql_help.c:3840 sql_help.c:4220 +msgid "type_name" +msgstr "Typname" + +#: sql_help.c:363 sql_help.c:1872 sql_help.c:2333 sql_help.c:2538 +#: sql_help.c:3007 sql_help.c:3237 sql_help.c:3585 sql_help.c:3828 +#: sql_help.c:4208 +msgid "lang_name" +msgstr "Sprachname" + +#: sql_help.c:366 +msgid "and aggregate_signature is:" +msgstr "und Aggregatsignatur Folgendes ist:" + +#: sql_help.c:389 sql_help.c:1966 sql_help.c:2230 +msgid "handler_function" +msgstr "Handler-Funktion" + +#: sql_help.c:390 sql_help.c:2231 +msgid "validator_function" +msgstr "Validator-Funktion" + +#: sql_help.c:438 sql_help.c:516 sql_help.c:661 sql_help.c:845 sql_help.c:984 +#: sql_help.c:1280 sql_help.c:1549 +msgid "action" +msgstr "Aktion" + +#: sql_help.c:440 sql_help.c:447 sql_help.c:451 sql_help.c:452 sql_help.c:455 +#: sql_help.c:457 sql_help.c:458 sql_help.c:459 sql_help.c:461 sql_help.c:464 +#: sql_help.c:466 sql_help.c:467 sql_help.c:665 sql_help.c:675 sql_help.c:677 +#: sql_help.c:680 sql_help.c:682 sql_help.c:683 sql_help.c:1060 sql_help.c:1282 +#: sql_help.c:1300 sql_help.c:1304 sql_help.c:1305 sql_help.c:1309 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1314 +#: sql_help.c:1316 sql_help.c:1319 sql_help.c:1320 sql_help.c:1322 +#: sql_help.c:1325 sql_help.c:1327 sql_help.c:1328 sql_help.c:1375 +#: sql_help.c:1377 sql_help.c:1384 sql_help.c:1393 sql_help.c:1398 +#: sql_help.c:1651 sql_help.c:1654 sql_help.c:1658 sql_help.c:1694 +#: sql_help.c:1819 sql_help.c:1932 sql_help.c:1938 sql_help.c:1951 +#: sql_help.c:1952 sql_help.c:1953 sql_help.c:2272 sql_help.c:2285 +#: sql_help.c:2331 sql_help.c:2398 sql_help.c:2404 sql_help.c:2437 +#: sql_help.c:2667 sql_help.c:2702 sql_help.c:2704 sql_help.c:2812 +#: sql_help.c:2821 sql_help.c:2831 sql_help.c:2834 sql_help.c:2844 +#: sql_help.c:2848 sql_help.c:2871 sql_help.c:2873 sql_help.c:2880 +#: sql_help.c:2893 sql_help.c:2898 sql_help.c:2916 sql_help.c:3042 +#: sql_help.c:3182 sql_help.c:3800 sql_help.c:3801 sql_help.c:3894 +#: sql_help.c:3909 sql_help.c:3911 sql_help.c:3913 sql_help.c:4180 +#: sql_help.c:4181 sql_help.c:4298 sql_help.c:4452 sql_help.c:4458 +#: sql_help.c:4460 sql_help.c:4701 sql_help.c:4707 sql_help.c:4709 +#: sql_help.c:4750 sql_help.c:4752 sql_help.c:4754 sql_help.c:4802 +#: sql_help.c:4933 sql_help.c:4939 sql_help.c:4941 +msgid "column_name" +msgstr "Spaltenname" + +#: sql_help.c:441 sql_help.c:666 sql_help.c:1283 sql_help.c:1659 +msgid "new_column_name" +msgstr "neuer_Spaltenname" + +#: sql_help.c:446 sql_help.c:537 sql_help.c:674 sql_help.c:866 sql_help.c:1005 +#: sql_help.c:1299 sql_help.c:1559 +msgid "where action is one of:" +msgstr "wobei Aktion Folgendes sein kann:" + +#: sql_help.c:448 sql_help.c:453 sql_help.c:1052 sql_help.c:1301 +#: sql_help.c:1306 sql_help.c:1561 sql_help.c:1565 sql_help.c:2185 +#: sql_help.c:2273 sql_help.c:2477 sql_help.c:2660 sql_help.c:2813 +#: sql_help.c:3089 sql_help.c:3996 +msgid "data_type" +msgstr "Datentyp" + +#: sql_help.c:449 sql_help.c:454 sql_help.c:1302 sql_help.c:1307 +#: sql_help.c:1562 sql_help.c:1566 sql_help.c:2186 sql_help.c:2276 +#: sql_help.c:2400 sql_help.c:2814 sql_help.c:2823 sql_help.c:2836 +#: sql_help.c:2850 sql_help.c:3090 sql_help.c:3096 sql_help.c:3904 +msgid "collation" +msgstr "Sortierfolge" + +#: sql_help.c:450 sql_help.c:1303 sql_help.c:2277 sql_help.c:2286 +#: sql_help.c:2816 sql_help.c:2832 sql_help.c:2845 +msgid "column_constraint" +msgstr "Spalten-Constraint" + +#: sql_help.c:460 sql_help.c:604 sql_help.c:676 sql_help.c:1321 sql_help.c:4799 +msgid "integer" +msgstr "ganze_Zahl" + +#: sql_help.c:462 sql_help.c:465 sql_help.c:678 sql_help.c:681 sql_help.c:1323 +#: sql_help.c:1326 +msgid "attribute_option" +msgstr "Attributoption" + +#: sql_help.c:470 sql_help.c:1330 sql_help.c:2278 sql_help.c:2287 +#: sql_help.c:2817 sql_help.c:2833 sql_help.c:2846 +msgid "table_constraint" +msgstr "Tabellen-Constraint" + +#: sql_help.c:473 sql_help.c:474 sql_help.c:475 sql_help.c:476 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:1337 sql_help.c:1338 sql_help.c:1873 +msgid "trigger_name" +msgstr "Triggername" + +#: sql_help.c:477 sql_help.c:478 sql_help.c:1348 sql_help.c:1349 +#: sql_help.c:2279 sql_help.c:2284 sql_help.c:2820 sql_help.c:2843 +msgid "parent_table" +msgstr "Elterntabelle" + +#: sql_help.c:536 sql_help.c:594 sql_help.c:663 sql_help.c:865 sql_help.c:1004 +#: sql_help.c:1518 sql_help.c:2216 +msgid "extension_name" +msgstr "Erweiterungsname" + +#: sql_help.c:538 sql_help.c:1006 sql_help.c:2335 +msgid "execution_cost" +msgstr "Ausführungskosten" + +#: sql_help.c:539 sql_help.c:1007 sql_help.c:2336 +msgid "result_rows" +msgstr "Ergebniszeilen" + +#: sql_help.c:540 sql_help.c:2337 +msgid "support_function" +msgstr "Support-Funktion" + +#: sql_help.c:562 sql_help.c:564 sql_help.c:930 sql_help.c:938 sql_help.c:942 +#: sql_help.c:945 sql_help.c:948 sql_help.c:1601 sql_help.c:1609 +#: sql_help.c:1613 sql_help.c:1616 sql_help.c:1619 sql_help.c:2638 +#: sql_help.c:2640 sql_help.c:2643 sql_help.c:2644 sql_help.c:3798 +#: sql_help.c:3799 sql_help.c:3803 sql_help.c:3804 sql_help.c:3807 +#: sql_help.c:3808 sql_help.c:3810 sql_help.c:3811 sql_help.c:3813 +#: sql_help.c:3814 sql_help.c:3816 sql_help.c:3817 sql_help.c:3819 +#: sql_help.c:3820 sql_help.c:3826 sql_help.c:3827 sql_help.c:3829 +#: sql_help.c:3830 sql_help.c:3832 sql_help.c:3833 sql_help.c:3835 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:3839 sql_help.c:3841 +#: sql_help.c:3842 sql_help.c:3844 sql_help.c:3845 sql_help.c:4178 +#: sql_help.c:4179 sql_help.c:4183 sql_help.c:4184 sql_help.c:4187 +#: sql_help.c:4188 sql_help.c:4190 sql_help.c:4191 sql_help.c:4193 +#: sql_help.c:4194 sql_help.c:4196 sql_help.c:4197 sql_help.c:4199 +#: sql_help.c:4200 sql_help.c:4206 sql_help.c:4207 sql_help.c:4209 +#: sql_help.c:4210 sql_help.c:4212 sql_help.c:4213 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4218 sql_help.c:4219 sql_help.c:4221 +#: sql_help.c:4222 sql_help.c:4224 sql_help.c:4225 +msgid "role_specification" +msgstr "Rollenangabe" + +#: sql_help.c:563 sql_help.c:565 sql_help.c:1632 sql_help.c:2159 +#: sql_help.c:2646 sql_help.c:3167 sql_help.c:3618 sql_help.c:4544 +msgid "user_name" +msgstr "Benutzername" + +#: sql_help.c:566 sql_help.c:950 sql_help.c:1621 sql_help.c:2645 +#: sql_help.c:3846 sql_help.c:4226 +msgid "where role_specification can be:" +msgstr "wobei Rollenangabe Folgendes sein kann:" + +#: sql_help.c:568 +msgid "group_name" +msgstr "Gruppenname" + +#: sql_help.c:590 sql_help.c:1396 sql_help.c:2165 sql_help.c:2407 +#: sql_help.c:2441 sql_help.c:2828 sql_help.c:2841 sql_help.c:2855 +#: sql_help.c:2896 sql_help.c:2920 sql_help.c:2932 sql_help.c:3837 +#: sql_help.c:4217 +msgid "tablespace_name" +msgstr "Tablespace-Name" + +#: sql_help.c:592 sql_help.c:685 sql_help.c:1343 sql_help.c:1352 +#: sql_help.c:1391 sql_help.c:1748 sql_help.c:1751 +msgid "index_name" +msgstr "Indexname" + +#: sql_help.c:596 +msgid "collation_name" +msgstr "Sortierfolgenname" + +#: sql_help.c:598 sql_help.c:601 sql_help.c:686 sql_help.c:688 sql_help.c:1345 +#: sql_help.c:1347 sql_help.c:1394 sql_help.c:2405 sql_help.c:2439 +#: sql_help.c:2826 sql_help.c:2839 sql_help.c:2853 sql_help.c:2894 +#: sql_help.c:2918 +msgid "storage_parameter" +msgstr "Storage-Parameter" + +#: sql_help.c:603 +msgid "column_number" +msgstr "Spaltennummer" + +#: sql_help.c:627 sql_help.c:1836 sql_help.c:4309 +msgid "large_object_oid" +msgstr "Large-Object-OID" + +#: sql_help.c:684 sql_help.c:1329 sql_help.c:1367 sql_help.c:2815 +msgid "compression_method" +msgstr "Kompressionsmethode" + +#: sql_help.c:717 sql_help.c:2462 +msgid "res_proc" +msgstr "Res-Funktion" + +#: sql_help.c:718 sql_help.c:2463 +msgid "join_proc" +msgstr "Join-Funktion" + +#: sql_help.c:770 sql_help.c:782 sql_help.c:2480 +msgid "strategy_number" +msgstr "Strategienummer" + +#: sql_help.c:772 sql_help.c:773 sql_help.c:776 sql_help.c:777 sql_help.c:783 +#: sql_help.c:784 sql_help.c:786 sql_help.c:787 sql_help.c:2482 sql_help.c:2483 +#: sql_help.c:2486 sql_help.c:2487 +msgid "op_type" +msgstr "Optyp" + +#: sql_help.c:774 sql_help.c:2484 +msgid "sort_family_name" +msgstr "Sortierfamilienname" + +#: sql_help.c:775 sql_help.c:785 sql_help.c:2485 +msgid "support_number" +msgstr "Unterst-Nummer" + +#: sql_help.c:779 sql_help.c:2102 sql_help.c:2489 sql_help.c:3009 +#: sql_help.c:3011 +msgid "argument_type" +msgstr "Argumenttyp" + +#: sql_help.c:810 sql_help.c:813 sql_help.c:884 sql_help.c:886 sql_help.c:888 +#: sql_help.c:1020 sql_help.c:1059 sql_help.c:1514 sql_help.c:1517 +#: sql_help.c:1693 sql_help.c:1747 sql_help.c:1750 sql_help.c:1821 +#: sql_help.c:1846 sql_help.c:1859 sql_help.c:1874 sql_help.c:1931 +#: sql_help.c:1937 sql_help.c:2271 sql_help.c:2283 sql_help.c:2396 +#: sql_help.c:2436 sql_help.c:2513 sql_help.c:2558 sql_help.c:2614 +#: sql_help.c:2666 sql_help.c:2699 sql_help.c:2706 sql_help.c:2811 +#: sql_help.c:2829 sql_help.c:2842 sql_help.c:2915 sql_help.c:3035 +#: sql_help.c:3216 sql_help.c:3439 sql_help.c:3488 sql_help.c:3594 +#: sql_help.c:3796 sql_help.c:3802 sql_help.c:3860 sql_help.c:3892 +#: sql_help.c:4176 sql_help.c:4182 sql_help.c:4297 sql_help.c:4406 +#: sql_help.c:4408 sql_help.c:4465 sql_help.c:4504 sql_help.c:4655 +#: sql_help.c:4657 sql_help.c:4714 sql_help.c:4748 sql_help.c:4801 +#: sql_help.c:4887 sql_help.c:4889 sql_help.c:4946 +msgid "table_name" +msgstr "Tabellenname" + +#: sql_help.c:815 sql_help.c:2515 +msgid "using_expression" +msgstr "Using-Ausdruck" + +#: sql_help.c:816 sql_help.c:2516 +msgid "check_expression" +msgstr "Check-Ausdruck" + +#: sql_help.c:890 sql_help.c:2559 +msgid "publication_parameter" +msgstr "Publikationsparameter" + +#: sql_help.c:934 sql_help.c:1605 sql_help.c:2375 sql_help.c:2591 +#: sql_help.c:3150 +msgid "password" +msgstr "Passwort" + +#: sql_help.c:935 sql_help.c:1606 sql_help.c:2376 sql_help.c:2592 +#: sql_help.c:3151 +msgid "timestamp" +msgstr "Zeit" + +#: sql_help.c:939 sql_help.c:943 sql_help.c:946 sql_help.c:949 sql_help.c:1610 +#: sql_help.c:1614 sql_help.c:1617 sql_help.c:1620 sql_help.c:3809 +#: sql_help.c:4189 +msgid "database_name" +msgstr "Datenbankname" + +#: sql_help.c:1053 sql_help.c:2661 +msgid "increment" +msgstr "Inkrement" + +#: sql_help.c:1054 sql_help.c:2662 +msgid "minvalue" +msgstr "Minwert" + +#: sql_help.c:1055 sql_help.c:2663 +msgid "maxvalue" +msgstr "Maxwert" + +#: sql_help.c:1056 sql_help.c:2664 sql_help.c:4404 sql_help.c:4502 +#: sql_help.c:4653 sql_help.c:4818 sql_help.c:4885 +msgid "start" +msgstr "Start" + +#: sql_help.c:1057 sql_help.c:1318 +msgid "restart" +msgstr "Restart" + +#: sql_help.c:1058 sql_help.c:2665 +msgid "cache" +msgstr "Cache" + +#: sql_help.c:1102 +msgid "new_target" +msgstr "neues_Ziel" + +#: sql_help.c:1120 sql_help.c:2718 +msgid "conninfo" +msgstr "Verbindungsinfo" + +#: sql_help.c:1122 sql_help.c:1126 sql_help.c:1130 sql_help.c:2719 +msgid "publication_name" +msgstr "Publikationsname" + +#: sql_help.c:1123 sql_help.c:1127 sql_help.c:1131 +msgid "set_publication_option" +msgstr "SET-Publikationsoption" + +#: sql_help.c:1134 +msgid "refresh_option" +msgstr "Refresh-Option" + +#: sql_help.c:1139 sql_help.c:2720 +msgid "subscription_parameter" +msgstr "Subskriptionsparameter" + +#: sql_help.c:1295 sql_help.c:1298 +msgid "partition_name" +msgstr "Partitionsname" + +#: sql_help.c:1296 sql_help.c:2288 sql_help.c:2847 +msgid "partition_bound_spec" +msgstr "Partitionsbegrenzungsangabe" + +#: sql_help.c:1315 sql_help.c:1364 sql_help.c:2861 +msgid "sequence_options" +msgstr "Sequenzoptionen" + +#: sql_help.c:1317 +msgid "sequence_option" +msgstr "Sequenzoption" + +#: sql_help.c:1331 +msgid "table_constraint_using_index" +msgstr "Tabellen-Constraint-für-Index" + +#: sql_help.c:1339 sql_help.c:1340 sql_help.c:1341 sql_help.c:1342 +msgid "rewrite_rule_name" +msgstr "Regelname" + +#: sql_help.c:1353 sql_help.c:2886 +msgid "and partition_bound_spec is:" +msgstr "und Partitionsbegrenzungsangabe Folgendes ist:" + +#: sql_help.c:1354 sql_help.c:1355 sql_help.c:1356 sql_help.c:2887 +#: sql_help.c:2888 sql_help.c:2889 +msgid "partition_bound_expr" +msgstr "Partitionsbegrenzungsausdruck" + +#: sql_help.c:1357 sql_help.c:1358 sql_help.c:2890 sql_help.c:2891 +msgid "numeric_literal" +msgstr "numerische_Konstante" + +#: sql_help.c:1359 +msgid "and column_constraint is:" +msgstr "und Spalten-Constraint Folgendes ist:" + +#: sql_help.c:1362 sql_help.c:2295 sql_help.c:2329 sql_help.c:2537 +#: sql_help.c:2859 +msgid "default_expr" +msgstr "Vorgabeausdruck" + +#: sql_help.c:1363 sql_help.c:2296 sql_help.c:2860 +msgid "generation_expr" +msgstr "Generierungsausdruck" + +#: sql_help.c:1365 sql_help.c:1366 sql_help.c:1376 sql_help.c:1378 +#: sql_help.c:1382 sql_help.c:2862 sql_help.c:2863 sql_help.c:2872 +#: sql_help.c:2874 sql_help.c:2878 +msgid "index_parameters" +msgstr "Indexparameter" + +#: sql_help.c:1368 sql_help.c:1385 sql_help.c:2864 sql_help.c:2881 +msgid "reftable" +msgstr "Reftabelle" + +#: sql_help.c:1369 sql_help.c:1386 sql_help.c:2865 sql_help.c:2882 +msgid "refcolumn" +msgstr "Refspalte" + +#: sql_help.c:1370 sql_help.c:1371 sql_help.c:1387 sql_help.c:1388 +#: sql_help.c:2866 sql_help.c:2867 sql_help.c:2883 sql_help.c:2884 +msgid "referential_action" +msgstr "Fremdschlüsselaktion" + +#: sql_help.c:1372 sql_help.c:2297 sql_help.c:2868 +msgid "and table_constraint is:" +msgstr "und Tabellen-Constraint Folgendes ist:" + +#: sql_help.c:1380 sql_help.c:2876 +msgid "exclude_element" +msgstr "Exclude-Element" + +#: sql_help.c:1381 sql_help.c:2877 sql_help.c:4402 sql_help.c:4500 +#: sql_help.c:4651 sql_help.c:4816 sql_help.c:4883 +msgid "operator" +msgstr "Operator" + +#: sql_help.c:1383 sql_help.c:2408 sql_help.c:2879 +msgid "predicate" +msgstr "Prädikat" + +#: sql_help.c:1389 +msgid "and table_constraint_using_index is:" +msgstr "und Tabellen-Constraint-für-Index Folgendes ist:" + +#: sql_help.c:1392 sql_help.c:2892 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "Indexparameter bei UNIQUE-, PRIMARY KEY- und EXCLUDE-Constraints sind:" + +#: sql_help.c:1397 sql_help.c:2897 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "Exclude-Element in einem EXCLUDE-Constraint ist:" + +#: sql_help.c:1400 sql_help.c:2401 sql_help.c:2824 sql_help.c:2837 +#: sql_help.c:2851 sql_help.c:2900 sql_help.c:3905 +msgid "opclass" +msgstr "Opklasse" + +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:2935 +msgid "tablespace_option" +msgstr "Tablespace-Option" + +#: sql_help.c:1440 sql_help.c:1443 sql_help.c:1449 sql_help.c:1453 +msgid "token_type" +msgstr "Tokentyp" + +#: sql_help.c:1441 sql_help.c:1444 +msgid "dictionary_name" +msgstr "Wörterbuchname" + +#: sql_help.c:1446 sql_help.c:1450 +msgid "old_dictionary" +msgstr "altes_Wörterbuch" + +#: sql_help.c:1447 sql_help.c:1451 +msgid "new_dictionary" +msgstr "neues_Wörterbuch" + +#: sql_help.c:1546 sql_help.c:1560 sql_help.c:1563 sql_help.c:1564 +#: sql_help.c:3088 +msgid "attribute_name" +msgstr "Attributname" + +#: sql_help.c:1547 +msgid "new_attribute_name" +msgstr "neuer_Attributname" + +#: sql_help.c:1551 sql_help.c:1555 +msgid "new_enum_value" +msgstr "neuer_Enum-Wert" + +#: sql_help.c:1552 +msgid "neighbor_enum_value" +msgstr "Nachbar-Enum-Wert" + +#: sql_help.c:1554 +msgid "existing_enum_value" +msgstr "existierender_Enum-Wert" + +#: sql_help.c:1557 +msgid "property" +msgstr "Eigenschaft" + +#: sql_help.c:1633 sql_help.c:2280 sql_help.c:2289 sql_help.c:2677 +#: sql_help.c:3168 sql_help.c:3619 sql_help.c:3818 sql_help.c:3861 +#: sql_help.c:4198 +msgid "server_name" +msgstr "Servername" + +#: sql_help.c:1665 sql_help.c:1668 sql_help.c:3183 +msgid "view_option_name" +msgstr "Sichtoptionsname" + +#: sql_help.c:1666 sql_help.c:3184 +msgid "view_option_value" +msgstr "Sichtoptionswert" + +#: sql_help.c:1687 sql_help.c:1688 sql_help.c:4787 sql_help.c:4788 +msgid "table_and_columns" +msgstr "Tabelle-und-Spalten" + +#: sql_help.c:1689 sql_help.c:1752 sql_help.c:1943 sql_help.c:3667 +#: sql_help.c:4040 sql_help.c:4789 +msgid "where option can be one of:" +msgstr "wobei Option eine der folgenden sein kann:" + +#: sql_help.c:1690 sql_help.c:1691 sql_help.c:1753 sql_help.c:1945 +#: sql_help.c:1948 sql_help.c:2126 sql_help.c:3668 sql_help.c:3669 +#: sql_help.c:3670 sql_help.c:3671 sql_help.c:3672 sql_help.c:3673 +#: sql_help.c:3674 sql_help.c:3675 sql_help.c:4041 sql_help.c:4043 +#: sql_help.c:4790 sql_help.c:4791 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +#: sql_help.c:4798 +msgid "boolean" +msgstr "boolean" + +#: sql_help.c:1692 sql_help.c:4800 +msgid "and table_and_columns is:" +msgstr "und Tabelle-und-Spalten Folgendes ist:" + +#: sql_help.c:1708 sql_help.c:4560 sql_help.c:4562 sql_help.c:4586 +msgid "transaction_mode" +msgstr "Transaktionsmodus" + +#: sql_help.c:1709 sql_help.c:4563 sql_help.c:4587 +msgid "where transaction_mode is one of:" +msgstr "wobei Transaktionsmodus Folgendes sein kann:" + +#: sql_help.c:1718 sql_help.c:4412 sql_help.c:4421 sql_help.c:4425 +#: sql_help.c:4429 sql_help.c:4432 sql_help.c:4661 sql_help.c:4670 +#: sql_help.c:4674 sql_help.c:4678 sql_help.c:4681 sql_help.c:4893 +#: sql_help.c:4902 sql_help.c:4906 sql_help.c:4910 sql_help.c:4913 +msgid "argument" +msgstr "Argument" + +#: sql_help.c:1818 +msgid "relation_name" +msgstr "Relationsname" + +#: sql_help.c:1823 sql_help.c:3812 sql_help.c:4192 +msgid "domain_name" +msgstr "Domänenname" + +#: sql_help.c:1845 +msgid "policy_name" +msgstr "Policy-Name" + +#: sql_help.c:1858 +msgid "rule_name" +msgstr "Regelname" + +#: sql_help.c:1877 +msgid "text" +msgstr "Text" + +#: sql_help.c:1902 sql_help.c:4005 sql_help.c:4242 +msgid "transaction_id" +msgstr "Transaktions-ID" + +#: sql_help.c:1933 sql_help.c:1940 sql_help.c:3931 +msgid "filename" +msgstr "Dateiname" + +#: sql_help.c:1934 sql_help.c:1941 sql_help.c:2616 sql_help.c:2617 +#: sql_help.c:2618 +msgid "command" +msgstr "Befehl" + +#: sql_help.c:1936 sql_help.c:2615 sql_help.c:3038 sql_help.c:3219 +#: sql_help.c:3915 sql_help.c:4395 sql_help.c:4397 sql_help.c:4493 +#: sql_help.c:4495 sql_help.c:4644 sql_help.c:4646 sql_help.c:4757 +#: sql_help.c:4876 sql_help.c:4878 +msgid "condition" +msgstr "Bedingung" + +#: sql_help.c:1939 sql_help.c:2442 sql_help.c:2921 sql_help.c:3185 +#: sql_help.c:3203 sql_help.c:3896 +msgid "query" +msgstr "Anfrage" + +#: sql_help.c:1944 +msgid "format_name" +msgstr "Formatname" + +#: sql_help.c:1946 +msgid "delimiter_character" +msgstr "Trennzeichen" + +#: sql_help.c:1947 +msgid "null_string" +msgstr "Null-Zeichenkette" + +#: sql_help.c:1949 +msgid "quote_character" +msgstr "Quote-Zeichen" + +#: sql_help.c:1950 +msgid "escape_character" +msgstr "Escape-Zeichen" + +#: sql_help.c:1954 +msgid "encoding_name" +msgstr "Kodierungsname" + +#: sql_help.c:1965 +msgid "access_method_type" +msgstr "Zugriffsmethodentyp" + +#: sql_help.c:2036 sql_help.c:2055 sql_help.c:2058 +msgid "arg_data_type" +msgstr "Arg-Datentyp" + +#: sql_help.c:2037 sql_help.c:2059 sql_help.c:2067 +msgid "sfunc" +msgstr "Übergangsfunktion" + +#: sql_help.c:2038 sql_help.c:2060 sql_help.c:2068 +msgid "state_data_type" +msgstr "Zustandsdatentyp" + +#: sql_help.c:2039 sql_help.c:2061 sql_help.c:2069 +msgid "state_data_size" +msgstr "Zustandsdatengröße" + +#: sql_help.c:2040 sql_help.c:2062 sql_help.c:2070 +msgid "ffunc" +msgstr "Abschlussfunktion" + +#: sql_help.c:2041 sql_help.c:2071 +msgid "combinefunc" +msgstr "Combine-Funktion" + +#: sql_help.c:2042 sql_help.c:2072 +msgid "serialfunc" +msgstr "Serialisierungsfunktion" + +#: sql_help.c:2043 sql_help.c:2073 +msgid "deserialfunc" +msgstr "Deserialisierungsfunktion" + +#: sql_help.c:2044 sql_help.c:2063 sql_help.c:2074 +msgid "initial_condition" +msgstr "Anfangswert" + +#: sql_help.c:2045 sql_help.c:2075 +msgid "msfunc" +msgstr "Moving-Übergangsfunktion" + +#: sql_help.c:2046 sql_help.c:2076 +msgid "minvfunc" +msgstr "Moving-Inversfunktion" + +#: sql_help.c:2047 sql_help.c:2077 +msgid "mstate_data_type" +msgstr "Moving-Zustandsdatentyp" + +#: sql_help.c:2048 sql_help.c:2078 +msgid "mstate_data_size" +msgstr "Moving-Zustandsdatengröße" + +#: sql_help.c:2049 sql_help.c:2079 +msgid "mffunc" +msgstr "Moving-Abschlussfunktion" + +#: sql_help.c:2050 sql_help.c:2080 +msgid "minitial_condition" +msgstr "Moving-Anfangswert" + +#: sql_help.c:2051 sql_help.c:2081 +msgid "sort_operator" +msgstr "Sortieroperator" + +#: sql_help.c:2064 +msgid "or the old syntax" +msgstr "oder die alte Syntax" + +#: sql_help.c:2066 +msgid "base_type" +msgstr "Basistyp" + +#: sql_help.c:2122 sql_help.c:2162 +msgid "locale" +msgstr "Locale" + +#: sql_help.c:2123 sql_help.c:2163 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2124 sql_help.c:2164 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2125 sql_help.c:4295 +msgid "provider" +msgstr "Provider" + +#: sql_help.c:2128 +msgid "existing_collation" +msgstr "existierende_Sortierfolge" + +#: sql_help.c:2138 +msgid "source_encoding" +msgstr "Quellkodierung" + +#: sql_help.c:2139 +msgid "dest_encoding" +msgstr "Zielkodierung" + +#: sql_help.c:2160 sql_help.c:2961 +msgid "template" +msgstr "Vorlage" + +#: sql_help.c:2161 +msgid "encoding" +msgstr "Kodierung" + +#: sql_help.c:2188 +msgid "constraint" +msgstr "Constraint" + +#: sql_help.c:2189 +msgid "where constraint is:" +msgstr "wobei Constraint Folgendes ist:" + +#: sql_help.c:2203 sql_help.c:2613 sql_help.c:3034 +msgid "event" +msgstr "Ereignis" + +#: sql_help.c:2204 +msgid "filter_variable" +msgstr "Filtervariable" + +#: sql_help.c:2218 +msgid "version" +msgstr "Version" + +#: sql_help.c:2292 sql_help.c:2856 +msgid "where column_constraint is:" +msgstr "wobei Spalten-Constraint Folgendes ist:" + +#: sql_help.c:2330 +msgid "rettype" +msgstr "Rückgabetyp" + +#: sql_help.c:2332 +msgid "column_type" +msgstr "Spaltentyp" + +#: sql_help.c:2341 sql_help.c:2543 +msgid "definition" +msgstr "Definition" + +#: sql_help.c:2342 sql_help.c:2544 +msgid "obj_file" +msgstr "Objektdatei" + +#: sql_help.c:2343 sql_help.c:2545 +msgid "link_symbol" +msgstr "Linksymbol" + +#: sql_help.c:2344 sql_help.c:2546 +msgid "sql_body" +msgstr "SQL-Rumpf" + +#: sql_help.c:2382 sql_help.c:2598 sql_help.c:3157 +msgid "uid" +msgstr "Uid" + +#: sql_help.c:2397 sql_help.c:2438 sql_help.c:2825 sql_help.c:2838 +#: sql_help.c:2852 sql_help.c:2917 +msgid "method" +msgstr "Methode" + +#: sql_help.c:2402 +msgid "opclass_parameter" +msgstr "Opklassen-Parameter" + +#: sql_help.c:2419 +msgid "call_handler" +msgstr "Handler" + +#: sql_help.c:2420 +msgid "inline_handler" +msgstr "Inline-Handler" + +#: sql_help.c:2421 +msgid "valfunction" +msgstr "Valfunktion" + +#: sql_help.c:2460 +msgid "com_op" +msgstr "Kommutator-Op" + +#: sql_help.c:2461 +msgid "neg_op" +msgstr "Umkehrungs-Op" + +#: sql_help.c:2479 +msgid "family_name" +msgstr "Familienname" + +#: sql_help.c:2490 +msgid "storage_type" +msgstr "Storage-Typ" + +#: sql_help.c:2619 sql_help.c:3041 +msgid "where event can be one of:" +msgstr "wobei Ereignis eins der folgenden sein kann:" + +#: sql_help.c:2639 sql_help.c:2641 +msgid "schema_element" +msgstr "Schemaelement" + +#: sql_help.c:2678 +msgid "server_type" +msgstr "Servertyp" + +#: sql_help.c:2679 +msgid "server_version" +msgstr "Serverversion" + +#: sql_help.c:2680 sql_help.c:3815 sql_help.c:4195 +msgid "fdw_name" +msgstr "FDW-Name" + +#: sql_help.c:2697 sql_help.c:2700 +msgid "statistics_name" +msgstr "Statistikname" + +#: sql_help.c:2701 +msgid "statistics_kind" +msgstr "Statistikart" + +#: sql_help.c:2717 +msgid "subscription_name" +msgstr "Subskriptionsname" + +#: sql_help.c:2818 +msgid "source_table" +msgstr "Quelltabelle" + +#: sql_help.c:2819 +msgid "like_option" +msgstr "Like-Option" + +#: sql_help.c:2885 +msgid "and like_option is:" +msgstr "und Like-Option Folgendes ist:" + +#: sql_help.c:2934 +msgid "directory" +msgstr "Verzeichnis" + +#: sql_help.c:2948 +msgid "parser_name" +msgstr "Parser-Name" + +#: sql_help.c:2949 +msgid "source_config" +msgstr "Quellkonfig" + +#: sql_help.c:2978 +msgid "start_function" +msgstr "Startfunktion" + +#: sql_help.c:2979 +msgid "gettoken_function" +msgstr "Gettext-Funktion" + +#: sql_help.c:2980 +msgid "end_function" +msgstr "Endfunktion" + +#: sql_help.c:2981 +msgid "lextypes_function" +msgstr "Lextypenfunktion" + +#: sql_help.c:2982 +msgid "headline_function" +msgstr "Headline-Funktion" + +#: sql_help.c:2994 +msgid "init_function" +msgstr "Init-Funktion" + +#: sql_help.c:2995 +msgid "lexize_function" +msgstr "Lexize-Funktion" + +#: sql_help.c:3008 +msgid "from_sql_function_name" +msgstr "From-SQL-Funktionsname" + +#: sql_help.c:3010 +msgid "to_sql_function_name" +msgstr "To-SQL-Funktionsname" + +#: sql_help.c:3036 +msgid "referenced_table_name" +msgstr "verwiesener_Tabellenname" + +#: sql_help.c:3037 +msgid "transition_relation_name" +msgstr "Übergangsrelationsname" + +#: sql_help.c:3040 +msgid "arguments" +msgstr "Argumente" + +#: sql_help.c:3092 sql_help.c:4328 +msgid "label" +msgstr "Label" + +#: sql_help.c:3094 +msgid "subtype" +msgstr "Untertyp" + +#: sql_help.c:3095 +msgid "subtype_operator_class" +msgstr "Untertyp-Operatorklasse" + +#: sql_help.c:3097 +msgid "canonical_function" +msgstr "Canonical-Funktion" + +#: sql_help.c:3098 +msgid "subtype_diff_function" +msgstr "Untertyp-Diff-Funktion" + +#: sql_help.c:3099 +msgid "multirange_type_name" +msgstr "Multirange-Typname" + +#: sql_help.c:3101 +msgid "input_function" +msgstr "Eingabefunktion" + +#: sql_help.c:3102 +msgid "output_function" +msgstr "Ausgabefunktion" + +#: sql_help.c:3103 +msgid "receive_function" +msgstr "Empfangsfunktion" + +#: sql_help.c:3104 +msgid "send_function" +msgstr "Sendefunktion" + +#: sql_help.c:3105 +msgid "type_modifier_input_function" +msgstr "Typmod-Eingabefunktion" + +#: sql_help.c:3106 +msgid "type_modifier_output_function" +msgstr "Typmod-Ausgabefunktion" + +#: sql_help.c:3107 +msgid "analyze_function" +msgstr "Analyze-Funktion" + +#: sql_help.c:3108 +msgid "subscript_function" +msgstr "Subscript-Funktion" + +#: sql_help.c:3109 +msgid "internallength" +msgstr "interne_Länge" + +#: sql_help.c:3110 +msgid "alignment" +msgstr "Ausrichtung" + +#: sql_help.c:3111 +msgid "storage" +msgstr "Speicherung" + +#: sql_help.c:3112 +msgid "like_type" +msgstr "wie_Typ" + +#: sql_help.c:3113 +msgid "category" +msgstr "Kategorie" + +#: sql_help.c:3114 +msgid "preferred" +msgstr "bevorzugt" + +#: sql_help.c:3115 +msgid "default" +msgstr "Vorgabewert" + +#: sql_help.c:3116 +msgid "element" +msgstr "Element" + +#: sql_help.c:3117 +msgid "delimiter" +msgstr "Trennzeichen" + +#: sql_help.c:3118 +msgid "collatable" +msgstr "sortierbar" + +#: sql_help.c:3215 sql_help.c:3891 sql_help.c:4390 sql_help.c:4487 +#: sql_help.c:4639 sql_help.c:4747 sql_help.c:4871 +msgid "with_query" +msgstr "With-Anfrage" + +#: sql_help.c:3217 sql_help.c:3893 sql_help.c:4409 sql_help.c:4415 +#: sql_help.c:4418 sql_help.c:4422 sql_help.c:4426 sql_help.c:4434 +#: sql_help.c:4658 sql_help.c:4664 sql_help.c:4667 sql_help.c:4671 +#: sql_help.c:4675 sql_help.c:4683 sql_help.c:4749 sql_help.c:4890 +#: sql_help.c:4896 sql_help.c:4899 sql_help.c:4903 sql_help.c:4907 +#: sql_help.c:4915 +msgid "alias" +msgstr "Alias" + +#: sql_help.c:3218 sql_help.c:4394 sql_help.c:4436 sql_help.c:4438 +#: sql_help.c:4492 sql_help.c:4643 sql_help.c:4685 sql_help.c:4687 +#: sql_help.c:4756 sql_help.c:4875 sql_help.c:4917 sql_help.c:4919 +msgid "from_item" +msgstr "From-Element" + +#: sql_help.c:3220 sql_help.c:3701 sql_help.c:3972 sql_help.c:4758 +msgid "cursor_name" +msgstr "Cursor-Name" + +#: sql_help.c:3221 sql_help.c:3899 sql_help.c:4759 +msgid "output_expression" +msgstr "Ausgabeausdruck" + +#: sql_help.c:3222 sql_help.c:3900 sql_help.c:4393 sql_help.c:4490 +#: sql_help.c:4642 sql_help.c:4760 sql_help.c:4874 +msgid "output_name" +msgstr "Ausgabename" + +#: sql_help.c:3238 +msgid "code" +msgstr "Code" + +#: sql_help.c:3643 +msgid "parameter" +msgstr "Parameter" + +#: sql_help.c:3665 sql_help.c:3666 sql_help.c:3997 +msgid "statement" +msgstr "Anweisung" + +#: sql_help.c:3700 sql_help.c:3971 +msgid "direction" +msgstr "Richtung" + +#: sql_help.c:3702 sql_help.c:3973 +msgid "where direction can be empty or one of:" +msgstr "wobei Richtung leer sein kann oder Folgendes:" + +#: sql_help.c:3703 sql_help.c:3704 sql_help.c:3705 sql_help.c:3706 +#: sql_help.c:3707 sql_help.c:3974 sql_help.c:3975 sql_help.c:3976 +#: sql_help.c:3977 sql_help.c:3978 sql_help.c:4403 sql_help.c:4405 +#: sql_help.c:4501 sql_help.c:4503 sql_help.c:4652 sql_help.c:4654 +#: sql_help.c:4817 sql_help.c:4819 sql_help.c:4884 sql_help.c:4886 +msgid "count" +msgstr "Anzahl" + +#: sql_help.c:3805 sql_help.c:4185 +msgid "sequence_name" +msgstr "Sequenzname" + +#: sql_help.c:3823 sql_help.c:4203 +msgid "arg_name" +msgstr "Argname" + +#: sql_help.c:3824 sql_help.c:4204 +msgid "arg_type" +msgstr "Argtyp" + +#: sql_help.c:3831 sql_help.c:4211 +msgid "loid" +msgstr "Large-Object-OID" + +#: sql_help.c:3859 +msgid "remote_schema" +msgstr "fernes_Schema" + +#: sql_help.c:3862 +msgid "local_schema" +msgstr "lokales_Schema" + +#: sql_help.c:3897 +msgid "conflict_target" +msgstr "Konfliktziel" + +#: sql_help.c:3898 +msgid "conflict_action" +msgstr "Konfliktaktion" + +#: sql_help.c:3901 +msgid "where conflict_target can be one of:" +msgstr "wobei Konfliktziel Folgendes sein kann:" + +#: sql_help.c:3902 +msgid "index_column_name" +msgstr "Indexspaltenname" + +#: sql_help.c:3903 +msgid "index_expression" +msgstr "Indexausdruck" + +#: sql_help.c:3906 +msgid "index_predicate" +msgstr "Indexprädikat" + +#: sql_help.c:3908 +msgid "and conflict_action is one of:" +msgstr "und Konfliktaktion Folgendes sein kann:" + +#: sql_help.c:3914 sql_help.c:4755 +msgid "sub-SELECT" +msgstr "Sub-SELECT" + +#: sql_help.c:3923 sql_help.c:3986 sql_help.c:4731 +msgid "channel" +msgstr "Kanal" + +#: sql_help.c:3945 +msgid "lockmode" +msgstr "Sperrmodus" + +#: sql_help.c:3946 +msgid "where lockmode is one of:" +msgstr "wobei Sperrmodus Folgendes sein kann:" + +#: sql_help.c:3987 +msgid "payload" +msgstr "Payload" + +#: sql_help.c:4014 +msgid "old_role" +msgstr "alte_Rolle" + +#: sql_help.c:4015 +msgid "new_role" +msgstr "neue_Rolle" + +#: sql_help.c:4051 sql_help.c:4250 sql_help.c:4258 +msgid "savepoint_name" +msgstr "Sicherungspunktsname" + +#: sql_help.c:4396 sql_help.c:4449 sql_help.c:4645 sql_help.c:4698 +#: sql_help.c:4877 sql_help.c:4930 +msgid "grouping_element" +msgstr "Gruppierelement" + +#: sql_help.c:4398 sql_help.c:4496 sql_help.c:4647 sql_help.c:4879 +msgid "window_name" +msgstr "Fenstername" + +#: sql_help.c:4399 sql_help.c:4497 sql_help.c:4648 sql_help.c:4880 +msgid "window_definition" +msgstr "Fensterdefinition" + +#: sql_help.c:4400 sql_help.c:4414 sql_help.c:4453 sql_help.c:4498 +#: sql_help.c:4649 sql_help.c:4663 sql_help.c:4702 sql_help.c:4881 +#: sql_help.c:4895 sql_help.c:4934 +msgid "select" +msgstr "Select" + +#: sql_help.c:4407 sql_help.c:4656 sql_help.c:4888 +msgid "where from_item can be one of:" +msgstr "wobei From-Element Folgendes sein kann:" + +#: sql_help.c:4410 sql_help.c:4416 sql_help.c:4419 sql_help.c:4423 +#: sql_help.c:4435 sql_help.c:4659 sql_help.c:4665 sql_help.c:4668 +#: sql_help.c:4672 sql_help.c:4684 sql_help.c:4891 sql_help.c:4897 +#: sql_help.c:4900 sql_help.c:4904 sql_help.c:4916 +msgid "column_alias" +msgstr "Spaltenalias" + +#: sql_help.c:4411 sql_help.c:4660 sql_help.c:4892 +msgid "sampling_method" +msgstr "Stichprobenmethode" + +#: sql_help.c:4413 sql_help.c:4662 sql_help.c:4894 +msgid "seed" +msgstr "Startwert" + +#: sql_help.c:4417 sql_help.c:4451 sql_help.c:4666 sql_help.c:4700 +#: sql_help.c:4898 sql_help.c:4932 +msgid "with_query_name" +msgstr "With-Anfragename" + +#: sql_help.c:4427 sql_help.c:4430 sql_help.c:4433 sql_help.c:4676 +#: sql_help.c:4679 sql_help.c:4682 sql_help.c:4908 sql_help.c:4911 +#: sql_help.c:4914 +msgid "column_definition" +msgstr "Spaltendefinition" + +#: sql_help.c:4437 sql_help.c:4686 sql_help.c:4918 +msgid "join_type" +msgstr "Verbundtyp" + +#: sql_help.c:4439 sql_help.c:4688 sql_help.c:4920 +msgid "join_condition" +msgstr "Verbundbedingung" + +#: sql_help.c:4440 sql_help.c:4689 sql_help.c:4921 +msgid "join_column" +msgstr "Verbundspalte" + +#: sql_help.c:4441 sql_help.c:4690 sql_help.c:4922 +msgid "join_using_alias" +msgstr "Join-Using-Alias" + +#: sql_help.c:4442 sql_help.c:4691 sql_help.c:4923 +msgid "and grouping_element can be one of:" +msgstr "und Gruppierelement eins der folgenden sein kann:" + +#: sql_help.c:4450 sql_help.c:4699 sql_help.c:4931 +msgid "and with_query is:" +msgstr "und With-Anfrage ist:" + +#: sql_help.c:4454 sql_help.c:4703 sql_help.c:4935 +msgid "values" +msgstr "values" + +#: sql_help.c:4455 sql_help.c:4704 sql_help.c:4936 +msgid "insert" +msgstr "insert" + +#: sql_help.c:4456 sql_help.c:4705 sql_help.c:4937 +msgid "update" +msgstr "update" + +#: sql_help.c:4457 sql_help.c:4706 sql_help.c:4938 +msgid "delete" +msgstr "delete" + +#: sql_help.c:4459 sql_help.c:4708 sql_help.c:4940 +msgid "search_seq_col_name" +msgstr "Search-Seq-Spaltenname" + +#: sql_help.c:4461 sql_help.c:4710 sql_help.c:4942 +msgid "cycle_mark_col_name" +msgstr "Cycle-Mark-Spaltenname" + +#: sql_help.c:4462 sql_help.c:4711 sql_help.c:4943 +msgid "cycle_mark_value" +msgstr "Cycle-Mark-Wert" + +#: sql_help.c:4463 sql_help.c:4712 sql_help.c:4944 +msgid "cycle_mark_default" +msgstr "Cycle-Mark-Standard" + +#: sql_help.c:4464 sql_help.c:4713 sql_help.c:4945 +msgid "cycle_path_col_name" +msgstr "Cycle-Pfad-Spaltenname" + +#: sql_help.c:4491 +msgid "new_table" +msgstr "neue_Tabelle" + +#: sql_help.c:4516 +msgid "timezone" +msgstr "Zeitzone" + +#: sql_help.c:4561 +msgid "snapshot_id" +msgstr "Snapshot-ID" + +#: sql_help.c:4815 +msgid "sort_expression" +msgstr "Sortierausdruck" + +#: sql_help.c:4952 sql_help.c:5930 +msgid "abort the current transaction" +msgstr "bricht die aktuelle Transaktion ab" + +#: sql_help.c:4958 +msgid "change the definition of an aggregate function" +msgstr "ändert die Definition einer Aggregatfunktion" + +#: sql_help.c:4964 +msgid "change the definition of a collation" +msgstr "ändert die Definition einer Sortierfolge" + +#: sql_help.c:4970 +msgid "change the definition of a conversion" +msgstr "ändert die Definition einer Zeichensatzkonversion" + +#: sql_help.c:4976 +msgid "change a database" +msgstr "ändert eine Datenbank" + +#: sql_help.c:4982 +msgid "define default access privileges" +msgstr "definiert vorgegebene Zugriffsprivilegien" + +#: sql_help.c:4988 +msgid "change the definition of a domain" +msgstr "ändert die Definition einer Domäne" + +#: sql_help.c:4994 +msgid "change the definition of an event trigger" +msgstr "ändert die Definition eines Ereignistriggers" + +#: sql_help.c:5000 +msgid "change the definition of an extension" +msgstr "ändert die Definition einer Erweiterung" + +#: sql_help.c:5006 +msgid "change the definition of a foreign-data wrapper" +msgstr "ändert die Definition eines Fremddaten-Wrappers" + +#: sql_help.c:5012 +msgid "change the definition of a foreign table" +msgstr "ändert die Definition einer Fremdtabelle" + +#: sql_help.c:5018 +msgid "change the definition of a function" +msgstr "ändert die Definition einer Funktion" + +#: sql_help.c:5024 +msgid "change role name or membership" +msgstr "ändert Rollenname oder -mitglieder" + +#: sql_help.c:5030 +msgid "change the definition of an index" +msgstr "ändert die Definition eines Index" + +#: sql_help.c:5036 +msgid "change the definition of a procedural language" +msgstr "ändert die Definition einer prozeduralen Sprache" + +#: sql_help.c:5042 +msgid "change the definition of a large object" +msgstr "ändert die Definition eines Large Object" + +#: sql_help.c:5048 +msgid "change the definition of a materialized view" +msgstr "ändert die Definition einer materialisierten Sicht" + +#: sql_help.c:5054 +msgid "change the definition of an operator" +msgstr "ändert die Definition eines Operators" + +#: sql_help.c:5060 +msgid "change the definition of an operator class" +msgstr "ändert die Definition einer Operatorklasse" + +#: sql_help.c:5066 +msgid "change the definition of an operator family" +msgstr "ändert die Definition einer Operatorfamilie" + +#: sql_help.c:5072 +msgid "change the definition of a row-level security policy" +msgstr "ändert die Definition einer Policy für Sicherheit auf Zeilenebene" + +#: sql_help.c:5078 +msgid "change the definition of a procedure" +msgstr "ändert die Definition einer Prozedur" + +#: sql_help.c:5084 +msgid "change the definition of a publication" +msgstr "ändert die Definition einer Publikation" + +#: sql_help.c:5090 sql_help.c:5192 +msgid "change a database role" +msgstr "ändert eine Datenbankrolle" + +#: sql_help.c:5096 +msgid "change the definition of a routine" +msgstr "ändert die Definition einer Routine" + +#: sql_help.c:5102 +msgid "change the definition of a rule" +msgstr "ändert die Definition einer Regel" + +#: sql_help.c:5108 +msgid "change the definition of a schema" +msgstr "ändert die Definition eines Schemas" + +#: sql_help.c:5114 +msgid "change the definition of a sequence generator" +msgstr "ändert die Definition eines Sequenzgenerators" + +#: sql_help.c:5120 +msgid "change the definition of a foreign server" +msgstr "ändert die Definition eines Fremdservers" + +#: sql_help.c:5126 +msgid "change the definition of an extended statistics object" +msgstr "ändert die Definition eines erweiterten Statistikobjekts" + +#: sql_help.c:5132 +msgid "change the definition of a subscription" +msgstr "ändert die Definition einer Subskription" + +#: sql_help.c:5138 +msgid "change a server configuration parameter" +msgstr "ändert einen Server-Konfigurationsparameter" + +#: sql_help.c:5144 +msgid "change the definition of a table" +msgstr "ändert die Definition einer Tabelle" + +#: sql_help.c:5150 +msgid "change the definition of a tablespace" +msgstr "ändert die Definition eines Tablespace" + +#: sql_help.c:5156 +msgid "change the definition of a text search configuration" +msgstr "ändert die Definition einer Textsuchekonfiguration" + +#: sql_help.c:5162 +msgid "change the definition of a text search dictionary" +msgstr "ändert die Definition eines Textsuchewörterbuchs" + +#: sql_help.c:5168 +msgid "change the definition of a text search parser" +msgstr "ändert die Definition eines Textsucheparsers" + +#: sql_help.c:5174 +msgid "change the definition of a text search template" +msgstr "ändert die Definition einer Textsuchevorlage" + +#: sql_help.c:5180 +msgid "change the definition of a trigger" +msgstr "ändert die Definition eines Triggers" + +#: sql_help.c:5186 +msgid "change the definition of a type" +msgstr "ändert die Definition eines Typs" + +#: sql_help.c:5198 +msgid "change the definition of a user mapping" +msgstr "ändert die Definition einer Benutzerabbildung" + +#: sql_help.c:5204 +msgid "change the definition of a view" +msgstr "ändert die Definition einer Sicht" + +#: sql_help.c:5210 +msgid "collect statistics about a database" +msgstr "sammelt Statistiken über eine Datenbank" + +#: sql_help.c:5216 sql_help.c:6008 +msgid "start a transaction block" +msgstr "startet einen Transaktionsblock" + +#: sql_help.c:5222 +msgid "invoke a procedure" +msgstr "ruft eine Prozedur auf" + +#: sql_help.c:5228 +msgid "force a write-ahead log checkpoint" +msgstr "erzwingt einen Checkpoint im Write-Ahead-Log" + +#: sql_help.c:5234 +msgid "close a cursor" +msgstr "schließt einen Cursor" + +#: sql_help.c:5240 +msgid "cluster a table according to an index" +msgstr "clustert eine Tabelle nach einem Index" + +#: sql_help.c:5246 +msgid "define or change the comment of an object" +msgstr "definiert oder ändert den Kommentar eines Objektes" + +#: sql_help.c:5252 sql_help.c:5810 +msgid "commit the current transaction" +msgstr "schließt die aktuelle Transaktion ab" + +#: sql_help.c:5258 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "schließt eine Transaktion ab, die vorher für Two-Phase-Commit vorbereitet worden war" + +#: sql_help.c:5264 +msgid "copy data between a file and a table" +msgstr "kopiert Daten zwischen einer Datei und einer Tabelle" + +#: sql_help.c:5270 +msgid "define a new access method" +msgstr "definiert eine neue Zugriffsmethode" + +#: sql_help.c:5276 +msgid "define a new aggregate function" +msgstr "definiert eine neue Aggregatfunktion" + +#: sql_help.c:5282 +msgid "define a new cast" +msgstr "definiert eine neue Typumwandlung" + +#: sql_help.c:5288 +msgid "define a new collation" +msgstr "definiert eine neue Sortierfolge" + +#: sql_help.c:5294 +msgid "define a new encoding conversion" +msgstr "definiert eine neue Kodierungskonversion" + +#: sql_help.c:5300 +msgid "create a new database" +msgstr "erzeugt eine neue Datenbank" + +#: sql_help.c:5306 +msgid "define a new domain" +msgstr "definiert eine neue Domäne" + +#: sql_help.c:5312 +msgid "define a new event trigger" +msgstr "definiert einen neuen Ereignistrigger" + +#: sql_help.c:5318 +msgid "install an extension" +msgstr "installiert eine Erweiterung" + +#: sql_help.c:5324 +msgid "define a new foreign-data wrapper" +msgstr "definiert einen neuen Fremddaten-Wrapper" + +#: sql_help.c:5330 +msgid "define a new foreign table" +msgstr "definiert eine neue Fremdtabelle" + +#: sql_help.c:5336 +msgid "define a new function" +msgstr "definiert eine neue Funktion" + +#: sql_help.c:5342 sql_help.c:5402 sql_help.c:5504 +msgid "define a new database role" +msgstr "definiert eine neue Datenbankrolle" + +#: sql_help.c:5348 +msgid "define a new index" +msgstr "definiert einen neuen Index" + +#: sql_help.c:5354 +msgid "define a new procedural language" +msgstr "definiert eine neue prozedurale Sprache" + +#: sql_help.c:5360 +msgid "define a new materialized view" +msgstr "definiert eine neue materialisierte Sicht" + +#: sql_help.c:5366 +msgid "define a new operator" +msgstr "definiert einen neuen Operator" + +#: sql_help.c:5372 +msgid "define a new operator class" +msgstr "definiert eine neue Operatorklasse" + +#: sql_help.c:5378 +msgid "define a new operator family" +msgstr "definiert eine neue Operatorfamilie" + +#: sql_help.c:5384 +msgid "define a new row-level security policy for a table" +msgstr "definiert eine neue Policy für Sicherheit auf Zeilenebene für eine Tabelle" + +#: sql_help.c:5390 +msgid "define a new procedure" +msgstr "definiert eine neue Prozedur" + +#: sql_help.c:5396 +msgid "define a new publication" +msgstr "definiert eine neue Publikation" + +#: sql_help.c:5408 +msgid "define a new rewrite rule" +msgstr "definiert eine neue Umschreiberegel" + +#: sql_help.c:5414 +msgid "define a new schema" +msgstr "definiert ein neues Schema" + +#: sql_help.c:5420 +msgid "define a new sequence generator" +msgstr "definiert einen neuen Sequenzgenerator" + +#: sql_help.c:5426 +msgid "define a new foreign server" +msgstr "definiert einen neuen Fremdserver" + +#: sql_help.c:5432 +msgid "define extended statistics" +msgstr "definiert erweiterte Statistiken" + +#: sql_help.c:5438 +msgid "define a new subscription" +msgstr "definiert eine neue Subskription" + +#: sql_help.c:5444 +msgid "define a new table" +msgstr "definiert eine neue Tabelle" + +#: sql_help.c:5450 sql_help.c:5966 +msgid "define a new table from the results of a query" +msgstr "definiert eine neue Tabelle aus den Ergebnissen einer Anfrage" + +#: sql_help.c:5456 +msgid "define a new tablespace" +msgstr "definiert einen neuen Tablespace" + +#: sql_help.c:5462 +msgid "define a new text search configuration" +msgstr "definiert eine neue Textsuchekonfiguration" + +#: sql_help.c:5468 +msgid "define a new text search dictionary" +msgstr "definiert ein neues Textsuchewörterbuch" + +#: sql_help.c:5474 +msgid "define a new text search parser" +msgstr "definiert einen neuen Textsucheparser" + +#: sql_help.c:5480 +msgid "define a new text search template" +msgstr "definiert eine neue Textsuchevorlage" + +#: sql_help.c:5486 +msgid "define a new transform" +msgstr "definiert eine neue Transformation" + +#: sql_help.c:5492 +msgid "define a new trigger" +msgstr "definiert einen neuen Trigger" + +#: sql_help.c:5498 +msgid "define a new data type" +msgstr "definiert einen neuen Datentyp" + +#: sql_help.c:5510 +msgid "define a new mapping of a user to a foreign server" +msgstr "definiert eine neue Abbildung eines Benutzers auf einen Fremdserver" + +#: sql_help.c:5516 +msgid "define a new view" +msgstr "definiert eine neue Sicht" + +#: sql_help.c:5522 +msgid "deallocate a prepared statement" +msgstr "gibt einen vorbereiteten Befehl frei" + +#: sql_help.c:5528 +msgid "define a cursor" +msgstr "definiert einen Cursor" + +#: sql_help.c:5534 +msgid "delete rows of a table" +msgstr "löscht Zeilen einer Tabelle" + +#: sql_help.c:5540 +msgid "discard session state" +msgstr "verwirft den Sitzungszustand" + +#: sql_help.c:5546 +msgid "execute an anonymous code block" +msgstr "führt einen anonymen Codeblock aus" + +#: sql_help.c:5552 +msgid "remove an access method" +msgstr "entfernt eine Zugriffsmethode" + +#: sql_help.c:5558 +msgid "remove an aggregate function" +msgstr "entfernt eine Aggregatfunktion" + +#: sql_help.c:5564 +msgid "remove a cast" +msgstr "entfernt eine Typumwandlung" + +#: sql_help.c:5570 +msgid "remove a collation" +msgstr "entfernt eine Sortierfolge" + +#: sql_help.c:5576 +msgid "remove a conversion" +msgstr "entfernt eine Zeichensatzkonversion" + +#: sql_help.c:5582 +msgid "remove a database" +msgstr "entfernt eine Datenbank" + +#: sql_help.c:5588 +msgid "remove a domain" +msgstr "entfernt eine Domäne" + +#: sql_help.c:5594 +msgid "remove an event trigger" +msgstr "entfernt einen Ereignistrigger" + +#: sql_help.c:5600 +msgid "remove an extension" +msgstr "entfernt eine Erweiterung" + +#: sql_help.c:5606 +msgid "remove a foreign-data wrapper" +msgstr "entfernt einen Fremddaten-Wrapper" + +#: sql_help.c:5612 +msgid "remove a foreign table" +msgstr "entfernt eine Fremdtabelle" + +#: sql_help.c:5618 +msgid "remove a function" +msgstr "entfernt eine Funktion" + +#: sql_help.c:5624 sql_help.c:5690 sql_help.c:5792 +msgid "remove a database role" +msgstr "entfernt eine Datenbankrolle" + +#: sql_help.c:5630 +msgid "remove an index" +msgstr "entfernt einen Index" + +#: sql_help.c:5636 +msgid "remove a procedural language" +msgstr "entfernt eine prozedurale Sprache" + +#: sql_help.c:5642 +msgid "remove a materialized view" +msgstr "entfernt eine materialisierte Sicht" + +#: sql_help.c:5648 +msgid "remove an operator" +msgstr "entfernt einen Operator" + +#: sql_help.c:5654 +msgid "remove an operator class" +msgstr "entfernt eine Operatorklasse" + +#: sql_help.c:5660 +msgid "remove an operator family" +msgstr "entfernt eine Operatorfamilie" + +#: sql_help.c:5666 +msgid "remove database objects owned by a database role" +msgstr "entfernt die einer Datenbankrolle gehörenden Datenbankobjekte" + +#: sql_help.c:5672 +msgid "remove a row-level security policy from a table" +msgstr "entfernt eine Policy für Sicherheit auf Zeilenebene von einer Tabelle" + +#: sql_help.c:5678 +msgid "remove a procedure" +msgstr "entfernt eine Prozedur" + +#: sql_help.c:5684 +msgid "remove a publication" +msgstr "entfernt eine Publikation" + +#: sql_help.c:5696 +msgid "remove a routine" +msgstr "entfernt eine Routine" + +#: sql_help.c:5702 +msgid "remove a rewrite rule" +msgstr "entfernt eine Umschreiberegel" + +#: sql_help.c:5708 +msgid "remove a schema" +msgstr "entfernt ein Schema" + +#: sql_help.c:5714 +msgid "remove a sequence" +msgstr "entfernt eine Sequenz" + +#: sql_help.c:5720 +msgid "remove a foreign server descriptor" +msgstr "entfernt einen Fremdserverdeskriptor" + +#: sql_help.c:5726 +msgid "remove extended statistics" +msgstr "entfernt erweiterte Statistiken" + +#: sql_help.c:5732 +msgid "remove a subscription" +msgstr "entfernt eine Subskription" + +#: sql_help.c:5738 +msgid "remove a table" +msgstr "entfernt eine Tabelle" + +#: sql_help.c:5744 +msgid "remove a tablespace" +msgstr "entfernt einen Tablespace" + +#: sql_help.c:5750 +msgid "remove a text search configuration" +msgstr "entfernt eine Textsuchekonfiguration" + +#: sql_help.c:5756 +msgid "remove a text search dictionary" +msgstr "entfernt ein Textsuchewörterbuch" + +#: sql_help.c:5762 +msgid "remove a text search parser" +msgstr "entfernt einen Textsucheparser" + +#: sql_help.c:5768 +msgid "remove a text search template" +msgstr "entfernt eine Textsuchevorlage" + +#: sql_help.c:5774 +msgid "remove a transform" +msgstr "entfernt eine Transformation" + +#: sql_help.c:5780 +msgid "remove a trigger" +msgstr "entfernt einen Trigger" + +#: sql_help.c:5786 +msgid "remove a data type" +msgstr "entfernt einen Datentyp" + +#: sql_help.c:5798 +msgid "remove a user mapping for a foreign server" +msgstr "entfernt eine Benutzerabbildung für einen Fremdserver" + +#: sql_help.c:5804 +msgid "remove a view" +msgstr "entfernt eine Sicht" + +#: sql_help.c:5816 +msgid "execute a prepared statement" +msgstr "führt einen vorbereiteten Befehl aus" + +#: sql_help.c:5822 +msgid "show the execution plan of a statement" +msgstr "zeigt den Ausführungsplan eines Befehls" + +#: sql_help.c:5828 +msgid "retrieve rows from a query using a cursor" +msgstr "liest Zeilen aus einer Anfrage mit einem Cursor" + +#: sql_help.c:5834 +msgid "define access privileges" +msgstr "definiert Zugriffsprivilegien" + +#: sql_help.c:5840 +msgid "import table definitions from a foreign server" +msgstr "importiert Tabellendefinitionen von einem Fremdserver" + +#: sql_help.c:5846 +msgid "create new rows in a table" +msgstr "erzeugt neue Zeilen in einer Tabelle" + +#: sql_help.c:5852 +msgid "listen for a notification" +msgstr "hört auf eine Benachrichtigung" + +#: sql_help.c:5858 +msgid "load a shared library file" +msgstr "lädt eine dynamische Bibliotheksdatei" + +#: sql_help.c:5864 +msgid "lock a table" +msgstr "sperrt eine Tabelle" + +#: sql_help.c:5870 +msgid "position a cursor" +msgstr "positioniert einen Cursor" + +#: sql_help.c:5876 +msgid "generate a notification" +msgstr "erzeugt eine Benachrichtigung" + +#: sql_help.c:5882 +msgid "prepare a statement for execution" +msgstr "bereitet einen Befehl zur Ausführung vor" + +#: sql_help.c:5888 +msgid "prepare the current transaction for two-phase commit" +msgstr "bereitet die aktuelle Transaktion für Two-Phase-Commit vor" + +#: sql_help.c:5894 +msgid "change the ownership of database objects owned by a database role" +msgstr "ändert den Eigentümer der der Rolle gehörenden Datenbankobjekte" + +#: sql_help.c:5900 +msgid "replace the contents of a materialized view" +msgstr "ersetzt den Inhalt einer materialisierten Sicht" + +#: sql_help.c:5906 +msgid "rebuild indexes" +msgstr "baut Indexe neu" + +#: sql_help.c:5912 +msgid "destroy a previously defined savepoint" +msgstr "gibt einen zuvor definierten Sicherungspunkt frei" + +#: sql_help.c:5918 +msgid "restore the value of a run-time parameter to the default value" +msgstr "setzt einen Konfigurationsparameter auf die Voreinstellung zurück" + +#: sql_help.c:5924 +msgid "remove access privileges" +msgstr "entfernt Zugriffsprivilegien" + +#: sql_help.c:5936 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "storniert eine Transaktion, die vorher für Two-Phase-Commit vorbereitet worden war" + +#: sql_help.c:5942 +msgid "roll back to a savepoint" +msgstr "rollt eine Transaktion bis zu einem Sicherungspunkt zurück" + +#: sql_help.c:5948 +msgid "define a new savepoint within the current transaction" +msgstr "definiert einen neuen Sicherungspunkt in der aktuellen Transaktion" + +#: sql_help.c:5954 +msgid "define or change a security label applied to an object" +msgstr "definiert oder ändert ein Security-Label eines Objektes" + +#: sql_help.c:5960 sql_help.c:6014 sql_help.c:6050 +msgid "retrieve rows from a table or view" +msgstr "liest Zeilen aus einer Tabelle oder Sicht" + +#: sql_help.c:5972 +msgid "change a run-time parameter" +msgstr "ändert einen Konfigurationsparameter" + +#: sql_help.c:5978 +msgid "set constraint check timing for the current transaction" +msgstr "setzt die Zeitsteuerung für Check-Constraints in der aktuellen Transaktion" + +#: sql_help.c:5984 +msgid "set the current user identifier of the current session" +msgstr "setzt den aktuellen Benutzernamen der aktuellen Sitzung" + +#: sql_help.c:5990 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "setzt den Sitzungsbenutzernamen und den aktuellen Benutzernamen der aktuellen Sitzung" + +#: sql_help.c:5996 +msgid "set the characteristics of the current transaction" +msgstr "setzt die Charakteristika der aktuellen Transaktion" + +#: sql_help.c:6002 +msgid "show the value of a run-time parameter" +msgstr "zeigt den Wert eines Konfigurationsparameters" + +#: sql_help.c:6020 +msgid "empty a table or set of tables" +msgstr "leert eine oder mehrere Tabellen" + +#: sql_help.c:6026 +msgid "stop listening for a notification" +msgstr "beendet das Hören auf eine Benachrichtigung" + +#: sql_help.c:6032 +msgid "update rows of a table" +msgstr "aktualisiert Zeilen einer Tabelle" + +#: sql_help.c:6038 +msgid "garbage-collect and optionally analyze a database" +msgstr "säubert und analysiert eine Datenbank" + +#: sql_help.c:6044 +msgid "compute a set of rows" +msgstr "berechnet eine Zeilenmenge" + +#: startup.c:213 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 kann nur im nicht interaktiven Modus verwendet werden" + +#: startup.c:326 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "konnte Logdatei »%s« nicht öffnen: %m" + +#: startup.c:438 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Geben Sie »help« für Hilfe ein.\n" +"\n" + +#: startup.c:591 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "konnte Ausgabeparameter »%s« nicht setzen" + +#: startup.c:699 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: startup.c:716 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "überflüssiges Kommandozeilenargument »%s« ignoriert" + +#: startup.c:765 +#, c-format +msgid "could not find own program executable" +msgstr "konnte eigene Programmdatei nicht finden" + +#: tab-complete.c:4917 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"Anfrage zur Tab-Vervollständigung fehlgeschlagen: %s\n" +"Anfrage war:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "unbekannter Wert »%s« für »%s«: Boole'scher Wert erwartet" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "ungültiger Wert »%s« für »%s«: ganze Zahl erwartet" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "ungültiger Variablenname: »%s«" + +#: variables.c:419 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"unbekannter Wert »%s« für »%s«\n" +"Verfügbare Werte sind: %s." diff --git a/src/bin/psql/po/el.po b/src/bin/psql/po/el.po new file mode 100644 index 000000000000..b2cac84aed49 --- /dev/null +++ b/src/bin/psql/po/el.po @@ -0,0 +1,6548 @@ +# Greek message translation file for psql +# Copyright (C) 2021 PostgreSQL Global Development Group +# This file is distributed under the same license as the psql (PostgreSQL) package. +# +msgid "" +msgstr "" +"Project-Id-Version: psql (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-05-25 05:45+0000\n" +"PO-Revision-Date: 2021-03-11 10:07+0100\n" +"Last-Translator: Georgios Kokolatos \n" +"Language-Team: \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.4.2\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "κρίσιμο:" + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "σφάλμα:" + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "προειδοποίηση:" + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "δεν ήταν δυνατή η αναγνώριση του τρέχοντος καταλόγου: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "μη έγκυρο δυαδικό αρχείο “%s”" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "δεν ήταν δυνατή η ανάγνωση του δυαδικού αρχείου “%s”" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "δεν βρέθηκε το αρχείο “%s” για να εκτελεστεί" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "δεν ήταν δυνατή η μετάβαση στον κατάλογο “%s”: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "δεν ήταν δυνατή η ανάγνωση του συμβολικού συνδέσμου “%s”: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s () απέτυχε: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: command.c:1315 command.c:3246 command.c:3295 command.c:3412 input.c:227 +#: mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "έλλειψη μνήμης" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "έλλειψη μνήμης\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "δεν ήταν δυνατή η αντιγραφή δείκτη null (εσωτερικό σφάλμα)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "δεν ήταν δυνατή η αναζήτηση ενεργής ταυτότητας χρήστη %ld: %s" + +#: ../../common/username.c:45 command.c:565 +msgid "user does not exist" +msgstr "ο χρήστης δεν υπάρχει" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "αποτυχία αναζήτησης ονόματος χρήστη: κωδικός σφάλματος % lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "εντολή μη εκτελέσιμη" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "εντολή δεν βρέθηκε" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "απόγονος διεργασίας τερμάτισε με κωδικό εξόδου %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "απόγονος διεργασίας τερματίστηκε με εξαίρεση 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "απόγονος διεργασίας τερματίστηκε με σήμα %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "απόγονος διεργασίας τερμάτισε με μη αναγνωρίσιμη κατάσταση %d" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Αίτηση ακύρωσης εστάλη\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "Δεν ήταν δυνατή η αποστολή αίτησης ακύρωσης" + +#: ../../fe_utils/print.c:336 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu σειρά)" +msgstr[1] "(%lu σειρές)" + +#: ../../fe_utils/print.c:3039 +#, c-format +msgid "Interrupted\n" +msgstr "Διακόπηκε\n" + +#: ../../fe_utils/print.c:3103 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "Δεν είναι δυνατή η προσθήκη κεφαλίδας σε περιεχόμενο πίνακα: υπέρβαση του πλήθους στηλών %d.\n" + +#: ../../fe_utils/print.c:3143 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "Δεν είναι δυνατή η προσθήκη κελιού σε περιεχόμενο πίνακα: υπέρβαση του συνολικού αριθμού κελιών %d.\n" + +#: ../../fe_utils/print.c:3401 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "μη έγκυρη μορφή εξόδου (εσωτερικό σφάλμα): %d" + +#: ../../fe_utils/psqlscan.l:697 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "Παραλείπεται η αναδρομική επέκταση της μεταβλητής “%s”" + +#: command.c:230 +#, c-format +msgid "invalid command \\%s" +msgstr "μη έγκυρη εντολή “%s”" + +#: command.c:232 +#, c-format +msgid "Try \\? for help." +msgstr "Δοκιμάστε \\? για βοήθεια." + +#: command.c:250 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: επιπλέον παράμετρος “%s” αγνοείται" + +#: command.c:302 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "\\%s εντολή αγνοείται, χρησιμοποιείστε \\endif ή Ctrl-C για να εξέλθετε από το παρόν μπλοκ \\if" + +#: command.c:563 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "δεν ήταν δυνατή η ανάλληψη προσωπικού καταλόγου για τον χρήστη με ID %ld: %s" + +#: command.c:581 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: δεν ήταν δυνατή η μετάβαση στον κατάλογο “%s”: %m" + +#: command.c:606 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "Αυτή τη στιγμή δεν είστε συνδεδεμένοι σε μία βάση δεδομένων.\n" + +#: command.c:616 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Είστε συνδεδεμένοι στη βάση δεδομένων “%s” ως χρήστης “%s” στην διεύθυνση “%s” στη θύρα “%s”.\n" + +#: command.c:619 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Είστε συνδεδεμένοι στη βάση δεδομένων “%s” ως χρήστης “%s” μέσω του υποδεχέα “%s” στη θύρα “%s”.\n" + +#: command.c:625 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Είστε συνδεδεμένοι στη βάση δεδομένων \"%s\" ως χρήστης \"%s\" στον κεντρικό υπολογιστή \"%s\" (διεύθυνση \"%s\") στη θύρα \"%s\".\n" + +#: command.c:628 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Είστε συνδεδεμένοι στη βάση δεδομένων “%s” ως χρήστης “%s” στον κεντρικό υπολογιστή “%s” στη θύρα “%s”.\n" + +#: command.c:1012 command.c:1121 command.c:2602 +#, c-format +msgid "no query buffer" +msgstr "μη ενδιάμεση μνήμη ερώτησης" + +#: command.c:1045 command.c:5304 +#, c-format +msgid "invalid line number: %s" +msgstr "μη έγκυρος αριθμός γραμμής “%s”" + +#: command.c:1112 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει την επεξεργασία πηγών συναρτήσεων." + +#: command.c:1115 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει την επεξεργασία ορισμών προβολής." + +#: command.c:1197 +msgid "No changes" +msgstr "Καθόλου αλλάγες" + +#: command.c:1276 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: μη έγκυρη ονομασία κωδικοποίησης ή δεν βρέθηκε η διεργασία μετατροπής" + +#: command.c:1311 command.c:2052 command.c:3242 command.c:3434 command.c:5406 +#: common.c:174 common.c:223 common.c:392 common.c:1248 common.c:1276 +#: common.c:1385 common.c:1492 common.c:1530 copy.c:488 copy.c:709 help.c:62 +#: large_obj.c:157 large_obj.c:192 large_obj.c:254 startup.c:298 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1318 +msgid "There is no previous error." +msgstr "Δεν υπάρχει προηγούμενο σφάλμα." + +#: command.c:1431 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: λείπει δεξιά παρένθεση" + +#: command.c:1608 command.c:1913 command.c:1927 command.c:1944 command.c:2106 +#: command.c:2342 command.c:2569 command.c:2609 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s: λείπει αναγκαία παράμετρος" + +#: command.c:1739 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: δεν δύναται να προκύψει μετά \\else" + +#: command.c:1744 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif: δεν υπάρχει αντίστοιχο \\if" + +#: command.c:1808 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else: δεν δύναται να προκύψει μετά \\else" + +#: command.c:1813 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else: δεν υπάρχει αντίστοιχο \\if" + +#: command.c:1853 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif: δεν υπάρχει αντίστοιχο \\if" + +#: command.c:2008 +msgid "Query buffer is empty." +msgstr "Άδεια ενδιάμεση μνήμη ερώτησης." + +#: command.c:2030 +msgid "Enter new password: " +msgstr "Εισάγετε νέο κωδικό πρόσβασης: " + +#: command.c:2031 +msgid "Enter it again: " +msgstr "Εισάγετε ξανά: " + +#: command.c:2035 +#, c-format +msgid "Passwords didn't match." +msgstr "Οι κωδικοί πρόσβασης δεν είναι ίδιοι." + +#: command.c:2135 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s: δεν ήταν δυνατή η ανάγνωση τιμής για την μεταβλητή" + +#: command.c:2238 +msgid "Query buffer reset (cleared)." +msgstr "Μηδενισμός ενδιάμεσης μνήμη ερώτησης (καθάρισμα)." + +#: command.c:2260 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "‘Εγραψε την ιστορία στο αρχείο “%s”.\n" + +#: command.c:2347 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: η ονομασία μεταβλητή περιβάλλοντος environment δεν δύναται να εμπεριέχει “=“" + +#: command.c:2399 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει την εμφάνιση του κώδικα της συνάρτησης." + +#: command.c:2402 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει την επεξεργασία ορισμών προβολής." + +#: command.c:2409 +#, c-format +msgid "function name is required" +msgstr "η ονομασία συνάρτησης είναι αναγκαία" + +#: command.c:2411 +#, c-format +msgid "view name is required" +msgstr "η ονομασία ορισμού είναι αναγκαία" + +#: command.c:2541 +msgid "Timing is on." +msgstr "Η χρονομέτρηση είναι ενεργή." + +#: command.c:2543 +msgid "Timing is off." +msgstr "Η χρονομέτρηση είναι ανενεργή." + +#: command.c:2628 command.c:2656 command.c:3873 command.c:3876 command.c:3879 +#: command.c:3885 command.c:3887 command.c:3913 command.c:3923 command.c:3935 +#: command.c:3949 command.c:3976 command.c:4034 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:3047 startup.c:237 startup.c:287 +msgid "Password: " +msgstr "Κωδικός πρόσβασης: " + +#: command.c:3052 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "Κωδικός πρόσβασης για τον χρήστη %s: " + +#: command.c:3104 +#, c-format +msgid "Do not give user, host, or port separately when using a connection string" +msgstr "" + +#: command.c:3139 +#, c-format +msgid "No database connection exists to re-use parameters from" +msgstr "" + +#: command.c:3440 +#, c-format +msgid "Previous connection kept" +msgstr "Κρατήθηκε η προηγούμενη σύνδεση" + +#: command.c:3446 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3502 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "" +"Τώρα είστε συνδεδεμένοι στη βάση δεδομένων “%s” ως χρήστης “%s” στη διεύθυνση “%s” στη θύρα “%s”.\n" +"=\n" + +#: command.c:3505 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Τώρα είστε συνδεδεμένοι στη βάση δεδομένων “%s” ως χρήστης “%s” μέσω του υποδεχέα “%s” στη θύρα “%s”.\n" + +#: command.c:3511 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Τώρα είστε συνδεδεμένοι στη βάση δεδομένων \"%s\" ως χρήστης \"%s\" στον κεντρικό υπολογιστή \"%s\" (διεύθυνση \"%s\") στη θύρα \"%s\".\n" + +#: command.c:3514 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Τώρα είστε συνδεδεμένοι στη βάση δεδομένων “%s” ως χρήστης “%s” στον κεντρικό υπολογιστή “%s” στη θύρα “%s”.\n" + +#: command.c:3519 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Τώρα είστε συνδεδεμένοι στη βάση δεδομένων “%s” ως χρήστης “%s”.\n" + +#: command.c:3559 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, διακομιστής %s)\n" + +#: command.c:3567 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"ΠΡΟΕΙΔΟΠΟΙΗΣΗ: %s κύρια έκδοση %s, %s κύρια έκδοση διακομιστή.\n" +" Ορισμένες δυνατότητες psql ενδέχεται να μην λειτουργούν.\n" + +#: command.c:3606 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL σύνδεση (πρωτόκολλο: %s, cipher: %s, bits: %s, συμπίεση: %s)\n" + +#: command.c:3607 command.c:3608 command.c:3609 +msgid "unknown" +msgstr "άγνωστο" + +#: command.c:3610 help.c:45 +msgid "off" +msgstr "κλειστό" + +#: command.c:3610 help.c:45 +msgid "on" +msgstr "ανοικτό" + +#: command.c:3624 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "GSSAPI-κρυπτογραφημένη σύνδεση\n" + +#: command.c:3644 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Ο πηγαίος κώδικας της κονσόλας (%u) διαφέρει από τον πηγαίο κώδικα των Windows(%u)\n" +" Χαρακτήρες 8-bit δύναται να μην λειτουργούν ορθά. Δείτε την αναφορά στη σελίδα\n" +" psql με τίτλο “Σημειώσεις για χρήστες Windows” για πληροφορίες.\n" + +#: command.c:3749 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "η μεταβλητή περιβάλλοντος PSQL_EDITOR_LINENUMBER_ARG πρέπει να έχει οριστεί για να ορίσετε αριθμό σειράς" + +#: command.c:3778 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "δεν μπόρεσε να εκκινήσει τον editor “%s”" + +#: command.c:3780 +#, c-format +msgid "could not start /bin/sh" +msgstr "δεν μπόρεσε να εκκινήσει το /bin/sh" + +#: command.c:3830 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "δεν ήταν δυνατός ο εντοπισμός του προσωρινού καταλόγου %s" + +#: command.c:3857 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του προσωρινού αρχείου “%s”: %m" + +#: command.c:4193 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: διφορούμενης συντόμευση “%s” ταιριάζει τόσο “%s” όσο “%s”" + +#: command.c:4213 +#, c-format +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: επιτρεπόμενες μορφές είναι aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" + +#: command.c:4232 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: επιτρεπόμενες μορφές γραμμών είναι ascii, old-ascii, unicode" + +#: command.c:4247 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: επιτρεπόμενες μορφές Unicode border line είναι single, double" + +#: command.c:4262 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: επιτρεπόμενες μορφές Unicode column line είναι single, double" + +#: command.c:4277 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: επιτρεπόμενες μορφές Unicode header line είναι single, double" + +#: command.c:4320 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep πρέπει να είναι ένας χαρακτήρας ενός-byte" + +#: command.c:4325 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldsep δεν μπορεί να είναι διπλά εισαγωγικά, νέα γραμμή, ή carriage return" + +#: command.c:4462 command.c:4650 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset: άγνωστη επιλογή: %s" + +#: command.c:4482 +#, c-format +msgid "Border style is %d.\n" +msgstr "Border style είναι %d.\n" + +#: command.c:4488 +#, c-format +msgid "Target width is unset.\n" +msgstr "Target width δεν είναι ορισμένο.\n" + +#: command.c:4490 +#, c-format +msgid "Target width is %d.\n" +msgstr "Target width είναι %d.\n" + +#: command.c:4497 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Εκτεταμένη οθόνη είναι ενεργή.\n" + +#: command.c:4499 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "Εκτεταμένη οθόνη χρησιμοποιείται αυτόματα.\n" + +#: command.c:4501 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Εκτεταμένη οθόνη είναι ανενεργή.\n" + +#: command.c:4507 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "Διαχωριστής πεδίων CSV είναι ο “%s”.\n" + +#: command.c:4515 command.c:4523 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "Διαχωριστής πεδίων είναι το μηδενικό byte\n" + +#: command.c:4517 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "Διαχωριστής πεδίων είναι ο “%s”.\n" + +#: command.c:4530 +#, c-format +msgid "Default footer is on.\n" +msgstr "Προκαθορισμένο υποσέλιδο είναι ενεργό.\n" + +#: command.c:4532 +#, c-format +msgid "Default footer is off.\n" +msgstr "Προκαθορισμένο υποσέλιδο είναι ανενεργό.\n" + +#: command.c:4538 +#, c-format +msgid "Output format is %s.\n" +msgstr "Η μορφή εξόδου είναι %s.\n" + +#: command.c:4544 +#, c-format +msgid "Line style is %s.\n" +msgstr "Η μορφή γραμμής είναι %s.\n" + +#: command.c:4551 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Εμφάνιση Null είναι “%s”.\n" + +#: command.c:4559 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "Η κατά εντοπιότητα διορθωμένη μορφή αριθμητικής εξόδου είναι ενεργή.\n" + +#: command.c:4561 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "Η κατά εντοπιότητα διορθωμένη μορφή αριθμητικής εξόδου είναι ανενεργή.\n" + +#: command.c:4568 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Χρησιμοποιείται Pager για μεγάλη έξοδο.\n" + +#: command.c:4570 +#, c-format +msgid "Pager is always used.\n" +msgstr "Χρησιμοποιείται Pager συνέχεια.\n" + +#: command.c:4572 +#, c-format +msgid "Pager usage is off.\n" +msgstr "Η χρήση Pager είναι ανενεργή.\n" + +#: command.c:4578 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "Ο Pager δεν θα χρησιμοποιηθεί για λιγότερο από %d γραμμή.\n" +msgstr[1] "Ο Pager δεν θα χρησιμοποιηθεί για λιγότερες από %d γραμμές.\n" + +#: command.c:4588 command.c:4598 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "Διαχωριστής εγγραφών είναι το μηδενικό byte\n" + +#: command.c:4590 +#, c-format +msgid "Record separator is .\n" +msgstr "Διαχωριστής εγγραφών είναι ο .\n" + +#: command.c:4592 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "Διαχωριστής εγγραφών είναι ο/η “%s”.\n" + +#: command.c:4605 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Τα χαρακτηριστικά του πίνακα είναι “%s”.\n" + +#: command.c:4608 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Χαρακτηριστικά πίνακα μη ορισμένα.\n" + +#: command.c:4615 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "Ο τίτλος είναι “%s”.\n" + +#: command.c:4617 +#, c-format +msgid "Title is unset.\n" +msgstr "Ο τίτλος δεν είναι ορισμένος.\n" + +#: command.c:4624 +#, c-format +msgid "Tuples only is on.\n" +msgstr "Ενεργή όψη μόνο πλειάδων.\n" + +#: command.c:4626 +#, c-format +msgid "Tuples only is off.\n" +msgstr "Ανενεργή όψη μόνο πλειάδων.\n" + +#: command.c:4632 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Το στυλ περιγράμματος γραμμής Unicode είναι \"%s\".\n" + +#: command.c:4638 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Το στυλ περιγράμματος στήλης Unicode είναι “%s”.\n" + +#: command.c:4644 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Το στυλ περιγράμματος γραμμής κεφαλίδας Unicode είναι “%s”.\n" + +#: command.c:4877 +#, c-format +msgid "\\!: failed" +msgstr "\\!: απέτυχε" + +#: command.c:4902 common.c:652 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch δεν μπορεί να χρησιμοποιηθεί με κενή ερώτηση" + +#: command.c:4943 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (κάθε %gs)\n" + +#: command.c:4946 +#, c-format +msgid "%s (every %gs)\n" +msgstr "" +"%s (κάθε %gs)\n" +"\n" + +#: command.c:5000 command.c:5007 common.c:552 common.c:559 common.c:1231 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********* ΕΡΩΤΗΣΗ **********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:5199 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "“%s.%s” δεν είναι μία όψη" + +#: command.c:5215 +#, c-format +msgid "could not parse reloptions array" +msgstr "δεν ήταν δυνατή η ανάλυση συστυχίας reloptions" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "δεν είναι δυνατή η διαφυγή χωρίς ενεργή σύνδεση" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "παράμετρος της εντολής κελύφους περιέχει μια νέα γραμμή ή μια επιστροφή μεταφοράς: \"%s\"" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "χάθηκε η σύνδεση στον διακομιστή" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "Χάθηκε η σύνδεση στον διακομιστή. Προσπάθεια επαναφοράς: " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "Απέτυχε.\n" + +#: common.c:330 +#, c-format +msgid "Succeeded.\n" +msgstr "Πέτυχε.\n" + +#: common.c:382 common.c:949 common.c:1166 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "μη αναμενόμενο PQresultStatus: %d" + +#: common.c:491 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Χρόνος: %.3f ms\n" + +#: common.c:506 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Χρόνος: %.3f ms (%02d:%06.3f)\n" + +#: common.c:515 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Χρόνος: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:522 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Χρόνος: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:546 common.c:604 common.c:1202 +#, c-format +msgid "You are currently not connected to a database." +msgstr "Αυτή τη στιγμή δεν είστε συνδεδεμένοι σε μία βάση δεδομένων." + +#: common.c:659 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watch δεν μπορεί να χρησιμοποιηθεί μαζί με COPY" + +#: common.c:664 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "μη αναμενόμενη κατάσταση αποτελέσματος για \\watch" + +#: common.c:694 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "Ελήφθει ασύγχρονη ειδοποίηση \"%s\" με ωφέλιμο φορτίο \"%s\" από τη διαδικασία διακομιστή με %d PID.\n" + +#: common.c:697 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "Ελήφθει ασύγχρονη ειδοποίηση “%s” από τη διαδικασία διακομιστή με %d PID.\n" + +#: common.c:730 common.c:747 +#, c-format +msgid "could not print result table: %m" +msgstr "δεν μπόρεσε να εκτυπώσει τον πίνακα αποτελέσματος: %m" + +#: common.c:768 +#, c-format +msgid "no rows returned for \\gset" +msgstr "δεν επιστράφηκαν σειρές για \\gset" + +#: common.c:773 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "περισσότερες από μία γραμμές επιστράφηκαν για \\gset" + +#: common.c:791 +#, c-format +msgid "attempt to \\gset into specially treated variable \"%s\" ignored" +msgstr "αγνοείται η προσπάθεια να τεθεί \\gset στην ειδικά διαμορφωμένη μεταβλητή “%s”" + +#: common.c:1211 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(Λειτουργία μονού βήματος: επιβεβαιώστε την εντολή)*******************************************\n" +"%s\n" +"***(πατήστε return για να συνεχίσετε ή εισάγετε x και return για να ακυρώσετε)********************\n" + +#: common.c:1266 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει savepoints για ON_ERROR_ROLLBACK." + +#: common.c:1329 +#, c-format +msgid "STATEMENT: %s" +msgstr "ΔΗΛΩΣΗ: %s" + +#: common.c:1373 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "μη αναμενόμενη κατάσταση συναλλαγής: %d" + +#: common.c:1514 describe.c:2179 +msgid "Column" +msgstr "Στήλη" + +#: common.c:1515 describe.c:178 describe.c:396 describe.c:414 describe.c:459 +#: describe.c:476 describe.c:1128 describe.c:1292 describe.c:1878 +#: describe.c:1902 describe.c:2180 describe.c:4048 describe.c:4271 +#: describe.c:4496 describe.c:5794 +msgid "Type" +msgstr "Τύπος" + +#: common.c:1564 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Η εντολή δεν έχει αποτέλεσμα, η το αποτέλεσμα δεν έχει στήλες.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy: παράμετροι επιβάλλονται" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: σφάλμα ανάλυσης σε “%s”" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: σφάλμα ανάλυσης στο τέλος γραμμής" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση της εντολής “%s”: %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "δεν ήταν δυνατή η εκτέλεση stat στο αρχείο “%s”: %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s: δεν μπορεί να αντιγράψει από/προς κατάλογο" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "δεν ήταν δυνατό το κλείσιμο της διοχέτευσης σε εξωτερική εντολή: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "δεν ήταν δυνατή η εγγραφή δεδομένων COPY: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "Μεταφορά δεδομένων μέσω COPY απέτυχε: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "ακυρώθηκε από τον χρήστη" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Εισαγάγετε τα δεδομένα που θα αντιγραφούν ακολουθούμενα από νέα γραμμή.\n" +"Τερματίστε με μια ανάστροφη κάθετο και μια τελεία σε μια ξεχωριστή γραμμή, ή ένα σήμα EOF." + +#: copy.c:671 +msgid "aborted because of read failure" +msgstr "ματαιώθηκε λόγω σφάλματος κατά την ανάγνωση" + +#: copy.c:705 +msgid "trying to exit copy mode" +msgstr "προσπαθεί να τερματίσει τη λειτουργία αντιγραφής" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: η δήλωση δεν επέστρεψε σετ αποτελεσμάτων" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: η ερώτηση πρέπει να επιστρέψει τουλάχιστον τρεις στήλες" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: κάθετες και οριζόντιες κεφαλίδες πρέπει να βρίσκονται σε διαφορετικές στήλες" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: επιβάλλεται να έχει οριστεί στήλη δεδομένων όταν η ερώτηση επιστρέφει περισσότερες από τρεις στήλες" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: υπερβλήθηκε ο μέγιστος αριθμός στηλών (%d)" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: το αποτέλεσμα της ερώτησης περιλαμβάνει πολλαπλές τιμές δεδομένων για την σειρά “%s”, στήλη “%s”" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: αριθμός στήλης %d βρίσκεται εκτός διαστήματος 1..%d" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: αμφίσημο όνομα στήλης: “%s”" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: όνομα στήλης δεν βρέθηκε: “%s”" + +#: describe.c:76 describe.c:376 describe.c:728 describe.c:924 describe.c:1120 +#: describe.c:1281 describe.c:1353 describe.c:4036 describe.c:4258 +#: describe.c:4494 describe.c:4585 describe.c:4731 describe.c:4944 +#: describe.c:5104 describe.c:5345 describe.c:5420 describe.c:5431 +#: describe.c:5493 describe.c:5918 describe.c:6001 +msgid "Schema" +msgstr "Σχήμα" + +#: describe.c:77 describe.c:175 describe.c:243 describe.c:251 describe.c:377 +#: describe.c:729 describe.c:925 describe.c:1038 describe.c:1121 +#: describe.c:1354 describe.c:4037 describe.c:4259 describe.c:4417 +#: describe.c:4495 describe.c:4586 describe.c:4665 describe.c:4732 +#: describe.c:4945 describe.c:5029 describe.c:5105 describe.c:5346 +#: describe.c:5421 describe.c:5432 describe.c:5494 describe.c:5691 +#: describe.c:5775 describe.c:5999 describe.c:6171 describe.c:6411 +msgid "Name" +msgstr "Όνομα" + +#: describe.c:78 describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "Result data type" +msgstr "Τύπος δεδομένων αποτελεσμάτων" + +#: describe.c:86 describe.c:99 describe.c:103 describe.c:390 describe.c:408 +#: describe.c:454 describe.c:471 +msgid "Argument data types" +msgstr "Τύπος δεδομένων παραμέτρων" + +#: describe.c:111 describe.c:118 describe.c:186 describe.c:274 describe.c:523 +#: describe.c:777 describe.c:940 describe.c:1063 describe.c:1356 +#: describe.c:2200 describe.c:3823 describe.c:4108 describe.c:4305 +#: describe.c:4448 describe.c:4522 describe.c:4595 describe.c:4678 +#: describe.c:4853 describe.c:4972 describe.c:5038 describe.c:5106 +#: describe.c:5247 describe.c:5289 describe.c:5362 describe.c:5424 +#: describe.c:5433 describe.c:5495 describe.c:5717 describe.c:5797 +#: describe.c:5932 describe.c:6002 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "Περιγραφή" + +#: describe.c:136 +msgid "List of aggregate functions" +msgstr "Λίστα των συγκεντρωτικών συναρτήσεων" + +#: describe.c:161 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει μεθόδους πρόσβασης." + +#: describe.c:176 +msgid "Index" +msgstr "Ευρετήριο" + +#: describe.c:177 describe.c:4056 describe.c:4284 describe.c:5919 +msgid "Table" +msgstr "Πίνακας" + +#: describe.c:185 describe.c:5696 +msgid "Handler" +msgstr "Διαχειριστής" + +#: describe.c:204 +msgid "List of access methods" +msgstr "Λίστα μεθόδων πρόσβασης" + +#: describe.c:230 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει tablespaces." + +#: describe.c:244 describe.c:252 describe.c:504 describe.c:767 describe.c:1039 +#: describe.c:1280 describe.c:4049 describe.c:4260 describe.c:4421 +#: describe.c:4667 describe.c:5030 describe.c:5692 describe.c:5776 +#: describe.c:6172 describe.c:6309 describe.c:6412 describe.c:6535 +#: describe.c:6613 large_obj.c:289 +msgid "Owner" +msgstr "Ιδιοκτήτης" + +#: describe.c:245 describe.c:253 +msgid "Location" +msgstr "Τοποθεσία" + +#: describe.c:264 describe.c:3639 +msgid "Options" +msgstr "Επιλογές" + +#: describe.c:269 describe.c:740 describe.c:1055 describe.c:4100 +#: describe.c:4104 +msgid "Size" +msgstr "Μέγεθος" + +#: describe.c:291 +msgid "List of tablespaces" +msgstr "Λίστα tablespaces" + +#: describe.c:336 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df λαμβάνει μόνο [anptwS+] ως επιλογές" + +#: describe.c:344 describe.c:355 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df δεν λαμβάνει την επιλογή “%c” στην έκδοση διακομιστή %s" + +#. translator: "agg" is short for "aggregate" +#: describe.c:392 describe.c:410 describe.c:456 describe.c:473 +msgid "agg" +msgstr "agg" + +#: describe.c:393 describe.c:411 +msgid "window" +msgstr "window" + +#: describe.c:394 +msgid "proc" +msgstr "proc" + +#: describe.c:395 describe.c:413 describe.c:458 describe.c:475 +msgid "func" +msgstr "func" + +#: describe.c:412 describe.c:457 describe.c:474 describe.c:1490 +msgid "trigger" +msgstr "trigger" + +#: describe.c:486 +msgid "immutable" +msgstr "immutable" + +#: describe.c:487 +msgid "stable" +msgstr "stable" + +#: describe.c:488 +msgid "volatile" +msgstr "volatile" + +#: describe.c:489 +msgid "Volatility" +msgstr "Προσωρινή" + +#: describe.c:497 +msgid "restricted" +msgstr "περιορισμένη" + +#: describe.c:498 +msgid "safe" +msgstr "ασφαλής" + +#: describe.c:499 +msgid "unsafe" +msgstr "ανασφαλής" + +#: describe.c:500 +msgid "Parallel" +msgstr "Παράλληλη" + +#: describe.c:505 +msgid "definer" +msgstr "definer" + +#: describe.c:506 +msgid "invoker" +msgstr "invoker" + +#: describe.c:507 +msgid "Security" +msgstr "Ασφάλεια" + +#: describe.c:512 +msgid "Language" +msgstr "Γλώσσα" + +#: describe.c:516 describe.c:520 +msgid "Source code" +msgstr "Πηγαίος κώδικας" + +#: describe.c:691 +msgid "List of functions" +msgstr "Λίστα συναρτήσεων" + +#: describe.c:739 +msgid "Internal name" +msgstr "Εσωτερική ονομασία" + +#: describe.c:761 +msgid "Elements" +msgstr "Στοιχεία" + +#: describe.c:822 +msgid "List of data types" +msgstr "Λίστα τύπων δεδομένων" + +#: describe.c:926 +msgid "Left arg type" +msgstr "Τύπος αριστερής παραμέτρου" + +#: describe.c:927 +msgid "Right arg type" +msgstr "Τύπος δεξιάς παραμέτρου" + +#: describe.c:928 +msgid "Result type" +msgstr "Τύπος αποτελέσματος" + +#: describe.c:933 describe.c:4673 describe.c:4830 describe.c:4836 +#: describe.c:5246 describe.c:6784 describe.c:6788 +msgid "Function" +msgstr "Συνάρτηση" + +#: describe.c:1010 +msgid "List of operators" +msgstr "Λίστα operators" + +#: describe.c:1040 +msgid "Encoding" +msgstr "Κωδικοποίηση" + +#: describe.c:1045 describe.c:4946 +msgid "Collate" +msgstr "Σύνθεση" + +#: describe.c:1046 describe.c:4947 +msgid "Ctype" +msgstr "Ctype" + +#: describe.c:1059 +msgid "Tablespace" +msgstr "Tablespace" + +#: describe.c:1081 +msgid "List of databases" +msgstr "Λίστα βάσεων δεδομένων" + +#: describe.c:1122 describe.c:1283 describe.c:4038 +msgid "table" +msgstr "πίνακας" + +#: describe.c:1123 describe.c:4039 +msgid "view" +msgstr "όψη" + +#: describe.c:1124 describe.c:4040 +msgid "materialized view" +msgstr "υλοποιημένη όψη" + +#: describe.c:1125 describe.c:1285 describe.c:4042 +msgid "sequence" +msgstr "ακολουθία" + +#: describe.c:1126 describe.c:4045 +msgid "foreign table" +msgstr "ξένος πίνακας" + +#: describe.c:1127 describe.c:4046 describe.c:4269 +msgid "partitioned table" +msgstr "κατατμημένος πίνακας" + +#: describe.c:1139 +msgid "Column privileges" +msgstr "Προνόμια στήλης" + +#: describe.c:1170 describe.c:1204 +msgid "Policies" +msgstr "Πολιτικές" + +#: describe.c:1236 describe.c:6476 describe.c:6480 +msgid "Access privileges" +msgstr "Προνόμια πρόσβασης" + +#: describe.c:1267 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει την τροποποίηση προεπιλεγμένων δικαιωμάτων." + +#: describe.c:1287 +msgid "function" +msgstr "συνάρτηση" + +#: describe.c:1289 +msgid "type" +msgstr "τύπος" + +#: describe.c:1291 +msgid "schema" +msgstr "σχήμα" + +#: describe.c:1315 +msgid "Default access privileges" +msgstr "Προεπιλεγμένες επιλογές δικαιωμάτων" + +#: describe.c:1355 +msgid "Object" +msgstr "Ατνικείμενο" + +#: describe.c:1369 +msgid "table constraint" +msgstr "περιορισμός πίνακα" + +#: describe.c:1391 +msgid "domain constraint" +msgstr "περιορισμός πεδίου" + +#: describe.c:1419 +msgid "operator class" +msgstr "κλάση χειριστή" + +#: describe.c:1448 +msgid "operator family" +msgstr "οικογένεια χειριστή" + +#: describe.c:1470 +msgid "rule" +msgstr "περιγραφή" + +#: describe.c:1512 +msgid "Object descriptions" +msgstr "Περιγραφές αντικειμένου" + +#: describe.c:1568 describe.c:4175 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "Δεν βρέθηκε καμία σχέση με όνομα “%s”." + +#: describe.c:1571 describe.c:4178 +#, c-format +msgid "Did not find any relations." +msgstr "Δεν βρέθηκαν καθόλου σχέσεις." + +#: describe.c:1827 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "Δεν βρέθηκαν καθόλου σχέσεις με OID %s." + +#: describe.c:1879 describe.c:1903 +msgid "Start" +msgstr "Εκκίνηση" + +#: describe.c:1880 describe.c:1904 +msgid "Minimum" +msgstr "Ελάχιστο" + +#: describe.c:1881 describe.c:1905 +msgid "Maximum" +msgstr "Μέγιστο" + +#: describe.c:1882 describe.c:1906 +msgid "Increment" +msgstr "Επαύξηση" + +#: describe.c:1883 describe.c:1907 describe.c:2038 describe.c:4589 +#: describe.c:4847 describe.c:4961 describe.c:4966 describe.c:6523 +msgid "yes" +msgstr "ναι" + +#: describe.c:1884 describe.c:1908 describe.c:2039 describe.c:4589 +#: describe.c:4844 describe.c:4961 describe.c:6524 +msgid "no" +msgstr "όχι" + +#: describe.c:1885 describe.c:1909 +msgid "Cycles?" +msgstr "Κύκλοι;" + +#: describe.c:1886 describe.c:1910 +msgid "Cache" +msgstr "Προσωρινή μνήμη" + +#: describe.c:1953 +#, c-format +msgid "Owned by: %s" +msgstr "Ανήκει σε: %s" + +#: describe.c:1957 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Ακολουθία για τη στήλη ταυτότητας: %s" + +#: describe.c:1964 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Ακολουθία “%s.%s”" + +#: describe.c:2111 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Ακαταχώρητος πίνακας “%s.%s”" + +#: describe.c:2114 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Πίνακας “%s.%s”" + +#: describe.c:2118 +#, c-format +msgid "View \"%s.%s\"" +msgstr "Όψη “%s.%s”" + +#: describe.c:2123 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Ακαταχώρητη υλοποιημένη όψη “%s.%s”" + +#: describe.c:2126 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Υλοποιημένη όψη “%s.%s”" + +#: describe.c:2131 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Ακαταχώρητο ευρετήριο “%s.%s”" + +#: describe.c:2134 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "Ευρετήριο “%s.%s”" + +#: describe.c:2139 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Ακαταχώρητο κατατετμημένο ευρετήριο “%s.%s”" + +#: describe.c:2142 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Κατατετμημένο ευρετήριο “%s.%s”" + +#: describe.c:2147 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Ειδική σχέση “%s.%s”" + +#: describe.c:2151 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "TOAST πίνακας “%s.%s”" + +#: describe.c:2155 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Συνθετικός τύπος “%s.%s”" + +#: describe.c:2159 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "Ξενικός πίνακας “%s.%s”" + +#: describe.c:2164 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Ακαταχώρητος κατατετμημένος πίνακας “%s.%s”" + +#: describe.c:2167 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Κατατετμημένος πίνακας “%s.%s”" + +#: describe.c:2183 describe.c:4502 +msgid "Collation" +msgstr "Σύνθεση" + +#: describe.c:2184 describe.c:4509 +msgid "Nullable" +msgstr "Nullable" + +#: describe.c:2185 describe.c:4510 +msgid "Default" +msgstr "Προκαθορισμένο" + +#: describe.c:2188 +msgid "Key?" +msgstr "Κλειδί;" + +#: describe.c:2190 describe.c:4739 describe.c:4750 +msgid "Definition" +msgstr "Ορισμός" + +#: describe.c:2192 describe.c:5712 describe.c:5796 describe.c:5867 +#: describe.c:5931 +msgid "FDW options" +msgstr "Επιλογές FDW" + +#: describe.c:2194 +msgid "Storage" +msgstr "Αποθήκευση" + +#: describe.c:2196 +#, fuzzy +#| msgid "expression" +msgid "Compression" +msgstr "expression" + +#: describe.c:2198 +msgid "Stats target" +msgstr "Στόχος στατιστικών" + +#: describe.c:2334 +#, fuzzy, c-format +#| msgid "Partition of: %s %s" +msgid "Partition of: %s %s%s" +msgstr "Κατάτμηση του: %s %s" + +#: describe.c:2347 +msgid "No partition constraint" +msgstr "Κανένας περιορισμός κατάτμησης" + +#: describe.c:2349 +#, c-format +msgid "Partition constraint: %s" +msgstr "Περιορισμός κατάτμησης: %s" + +#: describe.c:2373 +#, c-format +msgid "Partition key: %s" +msgstr "Κλειδί κατάτμησης: %s" + +#: describe.c:2399 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Ιδιοκτήτης πίνακα “%s.%s”" + +#: describe.c:2470 +msgid "primary key, " +msgstr "Κύριο κλειδί, " + +#: describe.c:2472 +msgid "unique, " +msgstr "μοναδικό, " + +#: describe.c:2478 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "για πίνακα “%s.%s”" + +#: describe.c:2482 +#, c-format +msgid ", predicate (%s)" +msgstr ", πρόβλεψη (%s)" + +#: describe.c:2485 +msgid ", clustered" +msgstr ", συσταδοποιημένο" + +#: describe.c:2488 +msgid ", invalid" +msgstr ", άκυρο" + +#: describe.c:2491 +msgid ", deferrable" +msgstr ", αναβαλλόμενο" + +#: describe.c:2494 +msgid ", initially deferred" +msgstr ", αρχικά αναβαλλόμενο" + +#: describe.c:2497 +msgid ", replica identity" +msgstr ", ταυτότητα πανομοιόματος" + +#: describe.c:2564 +msgid "Indexes:" +msgstr "Ευρετήρια:" + +#: describe.c:2648 +msgid "Check constraints:" +msgstr "Περιορισμοί ελέγχου:" + +#: describe.c:2716 +msgid "Foreign-key constraints:" +msgstr "Περιορισμοί ξενικών κλειδιών:" + +#: describe.c:2779 +msgid "Referenced by:" +msgstr "Αναφέρεται από:" + +#: describe.c:2829 +msgid "Policies:" +msgstr "Πολιτικές:" + +#: describe.c:2832 +msgid "Policies (forced row security enabled):" +msgstr "Πολιτικές (ενεργοποιημένη επιβολή ασφάλειας γραμμών):" + +#: describe.c:2835 +msgid "Policies (row security enabled): (none)" +msgstr "Πολιτικές (ενεργοποιημένη ασφάλεια γραμμών): (καμία)" + +#: describe.c:2838 +msgid "Policies (forced row security enabled): (none)" +msgstr "Πολιτικές (ενεργοποιημένη επιβολή ασφάλειας γραμμών): (καμία)" + +#: describe.c:2841 +msgid "Policies (row security disabled):" +msgstr "Πολιτικές (απενεργοποιημένη ασφάλεια γραμμών):" + +#: describe.c:2902 describe.c:3006 +msgid "Statistics objects:" +msgstr "Αντικείμενα στατιστικών:" + +#: describe.c:3120 describe.c:3224 +msgid "Rules:" +msgstr "Κανόνες" + +#: describe.c:3123 +msgid "Disabled rules:" +msgstr "Απενεργοποιημένοι κανόνες:" + +#: describe.c:3126 +msgid "Rules firing always:" +msgstr "Κανόνες πάντα σε χρήση:" + +#: describe.c:3129 +msgid "Rules firing on replica only:" +msgstr "Κανόνες σε χρήση μόνο στο ομοίωμα:" + +#: describe.c:3169 +msgid "Publications:" +msgstr "Δημοσιεύσεις:" + +#: describe.c:3207 +msgid "View definition:" +msgstr "Ορισμός όψης:" + +#: describe.c:3354 +msgid "Triggers:" +msgstr "Triggers:" + +#: describe.c:3358 +msgid "Disabled user triggers:" +msgstr "Απενεργοποιημένες triggers χρήστη:" + +#: describe.c:3360 +msgid "Disabled triggers:" +msgstr "Απενεργοποιημένες triggers:" + +#: describe.c:3363 +msgid "Disabled internal triggers:" +msgstr "Απενεργοποιημένες εσωτερικές triggers:" + +#: describe.c:3366 +msgid "Triggers firing always:" +msgstr "Triggers πάντα σε χρήση:" + +#: describe.c:3369 +msgid "Triggers firing on replica only:" +msgstr "Triggers σε χρήση μόνο στο ομοίωμα:" + +#: describe.c:3441 +#, c-format +msgid "Server: %s" +msgstr "Διακομιστής: %s" + +#: describe.c:3449 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW επιλογές: (%s)" + +#: describe.c:3470 +msgid "Inherits" +msgstr "Κληρονομεί" + +#: describe.c:3543 +#, c-format +msgid "Number of partitions: %d" +msgstr "Αριθμός κατατμήσεων: %d" + +#: describe.c:3552 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Αριθμός κατατμήσεων: %d (Χρησιμοποιείστε \\d+ για να τους απαριθμήσετε.)" + +#: describe.c:3554 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Αριθμός απογονικών πινάκων: %d (Χρησιμοποιείστε \\d+ για να τους απαριθμήσετε.)" + +#: describe.c:3561 +msgid "Child tables" +msgstr "Απογονικοί πίνακες" + +#: describe.c:3561 +msgid "Partitions" +msgstr "Κατατμήσεις" + +#: describe.c:3592 +#, c-format +msgid "Typed table of type: %s" +msgstr "Τυποποιημένος πίνακας τύπου: %s" + +#: describe.c:3608 +msgid "Replica Identity" +msgstr "Ταυτότητα Ομοιόματος" + +#: describe.c:3621 +msgid "Has OIDs: yes" +msgstr "Έχει OIDs: ναι" + +#: describe.c:3630 +#, c-format +msgid "Access method: %s" +msgstr "Μέθοδος πρόσβασης: %s" + +#: describe.c:3710 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Χώρος πινάκα: “%s”" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3722 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", χώρος πίνακα “%s”" + +#: describe.c:3815 +msgid "List of roles" +msgstr "Λίστα ρόλων" + +#: describe.c:3817 +msgid "Role name" +msgstr "Όνομα ρόλου" + +#: describe.c:3818 +msgid "Attributes" +msgstr "Χαρακτηριστικά" + +#: describe.c:3820 +msgid "Member of" +msgstr "Μέλος του" + +#: describe.c:3831 +msgid "Superuser" +msgstr "Υπερχρήστης" + +#: describe.c:3834 +msgid "No inheritance" +msgstr "Καμία κληρονιμιά" + +#: describe.c:3837 +msgid "Create role" +msgstr "Δημιουργήστε ρόλο" + +#: describe.c:3840 +msgid "Create DB" +msgstr "Δημιουργήστε βάση δεδομένων" + +#: describe.c:3843 +msgid "Cannot login" +msgstr "Δεν δύναται σύνδεση" + +#: describe.c:3847 +msgid "Replication" +msgstr "Αντιγραφή" + +#: describe.c:3851 +msgid "Bypass RLS" +msgstr "Παράκαμψη RLS" + +#: describe.c:3860 +msgid "No connections" +msgstr "Καθόλου συνδέσεις" + +#: describe.c:3862 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d σύνδεση" +msgstr[1] "%d συνδέσεις" + +#: describe.c:3872 +msgid "Password valid until " +msgstr "Κωδικός πρόσβασης ενεργός μέχρι " + +#: describe.c:3922 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει ρυθμίσεις ρόλων ανά βάση δεδομένων." + +#: describe.c:3935 +msgid "Role" +msgstr "Ρόλος" + +#: describe.c:3936 +msgid "Database" +msgstr "Βάση δεδομένων" + +#: describe.c:3937 +msgid "Settings" +msgstr "Ρυθμίσεις" + +#: describe.c:3958 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "Δεν βρέθηκαν ρυθμίσεις για το ρόλο \"%s\" και τη βάση δεδομένων \"%s\"." + +#: describe.c:3961 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "Δεν βρέθηκαν ρυθμίσεις για το ρόλο “%s”." + +#: describe.c:3964 +#, c-format +msgid "Did not find any settings." +msgstr "Δεν βρέθηκαν ρυθμίσεις." + +#: describe.c:3969 +msgid "List of settings" +msgstr "Λίστα ρυθμίσεων" + +#: describe.c:4041 +msgid "index" +msgstr "ευρετήριο" + +#: describe.c:4043 +msgid "special" +msgstr "ειδικό" + +#: describe.c:4044 +#, fuzzy +#| msgid "TOAST table \"%s.%s\"" +msgid "TOAST table" +msgstr "TOAST πίνακας “%s.%s”" + +#: describe.c:4047 describe.c:4270 +msgid "partitioned index" +msgstr "κατατετμημένο ευρετήριο" + +#: describe.c:4071 +msgid "permanent" +msgstr "μόνιμο" + +#: describe.c:4072 +msgid "temporary" +msgstr "προσωρινό" + +#: describe.c:4073 +msgid "unlogged" +msgstr "ακαταχώρητο" + +#: describe.c:4074 +msgid "Persistence" +msgstr "Διάρκεια" + +#: describe.c:4091 +#, fuzzy +#| msgid "Access method: %s" +msgid "Access method" +msgstr "Μέθοδος πρόσβασης: %s" + +#: describe.c:4183 +msgid "List of relations" +msgstr "Λίστα σχέσεων" + +#: describe.c:4231 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει την δηλωτική δημιουργία κατατμήσεων πίνακα." + +#: describe.c:4242 +msgid "List of partitioned indexes" +msgstr "Λίστα κατατμημένων ευρετηρίων" + +#: describe.c:4244 +msgid "List of partitioned tables" +msgstr "Λίστα κατατμημένων πινάκων" + +#: describe.c:4248 +msgid "List of partitioned relations" +msgstr "Λίστα κατατμημένων σχέσεων" + +#: describe.c:4279 +msgid "Parent name" +msgstr "Γονικό όνομα" + +#: describe.c:4292 +msgid "Leaf partition size" +msgstr "Μέγεθος φύλλου κατάτμησης" + +#: describe.c:4295 describe.c:4301 +msgid "Total size" +msgstr "Συνολικό μέγεθος" + +#: describe.c:4425 +msgid "Trusted" +msgstr "Εμπιστευόμενο" + +#: describe.c:4433 +msgid "Internal language" +msgstr "Εσωτερική γλώσσα" + +#: describe.c:4434 +msgid "Call handler" +msgstr "Πρόγραμμα χειρισμού κλήσεων" + +#: describe.c:4435 describe.c:5699 +msgid "Validator" +msgstr "Ελεκτής" + +#: describe.c:4438 +msgid "Inline handler" +msgstr "Ενσωματωμένος χειριστής" + +#: describe.c:4466 +msgid "List of languages" +msgstr "Λίστα γλωσσών" + +#: describe.c:4511 +msgid "Check" +msgstr "Έλεγχος" + +#: describe.c:4553 +msgid "List of domains" +msgstr "Λίστα πεδίων" + +#: describe.c:4587 +msgid "Source" +msgstr "Πηγή" + +#: describe.c:4588 +msgid "Destination" +msgstr "Προορισμός" + +#: describe.c:4590 describe.c:6525 +msgid "Default?" +msgstr "Προεπιλογή;" + +#: describe.c:4627 +msgid "List of conversions" +msgstr "Λίστα μετατροπών" + +#: describe.c:4666 +msgid "Event" +msgstr "Συμβάν" + +#: describe.c:4668 +msgid "enabled" +msgstr "ενεγροποιημένο" + +#: describe.c:4669 +msgid "replica" +msgstr "ομοίωμα" + +#: describe.c:4670 +msgid "always" +msgstr "πάντα" + +#: describe.c:4671 +msgid "disabled" +msgstr "απενεργοποιημένο" + +#: describe.c:4672 describe.c:6413 +msgid "Enabled" +msgstr "Ενεργοποιημένο" + +#: describe.c:4674 +msgid "Tags" +msgstr "Ετικέτες" + +#: describe.c:4693 +msgid "List of event triggers" +msgstr "Λίστα ενεργοποιήσεων συμβάντων" + +#: describe.c:4720 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support extensions." +msgid "The server (version %s) does not support extended statistics." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει επεκτάσεις." + +#: describe.c:4757 +msgid "Ndistinct" +msgstr "" + +#: describe.c:4758 +msgid "Dependencies" +msgstr "" + +#: describe.c:4768 +msgid "MCV" +msgstr "" + +#: describe.c:4787 +#, fuzzy +#| msgid "define extended statistics" +msgid "List of extended statistics" +msgstr "ορίστε εκτεταμένα στατιστικά στοιχεία" + +#: describe.c:4814 +msgid "Source type" +msgstr "Τύπος πηγής" + +#: describe.c:4815 +msgid "Target type" +msgstr "Τύπος προοριστμού" + +#: describe.c:4846 +msgid "in assignment" +msgstr "σε ανάθεση" + +#: describe.c:4848 +msgid "Implicit?" +msgstr "Έμμεσα;" + +#: describe.c:4903 +msgid "List of casts" +msgstr "Λίστα casts" + +#: describe.c:4931 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει συρραφές." + +#: describe.c:4952 describe.c:4956 +msgid "Provider" +msgstr "Πάροχος" + +#: describe.c:4962 describe.c:4967 +msgid "Deterministic?" +msgstr "Ντετερμινιστικό;" + +#: describe.c:5002 +msgid "List of collations" +msgstr "Λίστα συρραφών" + +#: describe.c:5061 +msgid "List of schemas" +msgstr "Λίστα σχημάτων" + +#: describe.c:5086 describe.c:5333 describe.c:5404 describe.c:5475 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει αναζήτηση πλήρους κειμένου." + +#: describe.c:5121 +msgid "List of text search parsers" +msgstr "Λίστα αναλυτών αναζήτησης κειμένου" + +#: describe.c:5166 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "Δεν βρήκε ανάλυση αναζήτησης κειμένου με το όνομα \"%s\"." + +#: describe.c:5169 +#, c-format +msgid "Did not find any text search parsers." +msgstr "Δεν βρήκε ανάλυση αναζήτησης κειμένου." + +#: describe.c:5244 +msgid "Start parse" +msgstr "Εκκίνηση ανάλυσης" + +#: describe.c:5245 +msgid "Method" +msgstr "Μέθοδος" + +#: describe.c:5249 +msgid "Get next token" +msgstr "Λήψη επόμενου ενδεικτικού" + +#: describe.c:5251 +msgid "End parse" +msgstr "Τέλος ανάλυσης" + +#: describe.c:5253 +msgid "Get headline" +msgstr "Λήψη επικεφαλίδας" + +#: describe.c:5255 +msgid "Get token types" +msgstr "Λήψη τύπων ενδεικτικών" + +#: describe.c:5266 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Αναλυτής αναζήτης κειμένου “%s.%s”" + +#: describe.c:5269 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "Αναλυτής αναζήτης κειμένου “%s”" + +#: describe.c:5288 +msgid "Token name" +msgstr "Ονομασία ενδεικτικού" + +#: describe.c:5299 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "Τύποι ενδεικτικών αναλυτή “%s.%s”" + +#: describe.c:5302 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "Τύποι ενδεικτικών αναλυτή “%s”" + +#: describe.c:5356 +msgid "Template" +msgstr "Πρότυπο" + +#: describe.c:5357 +msgid "Init options" +msgstr "Επιλογές εκκίνησης" + +#: describe.c:5379 +msgid "List of text search dictionaries" +msgstr "Λίστα λεξικών αναζήτησης κειμένου" + +#: describe.c:5422 +msgid "Init" +msgstr "Εκκίνηση" + +#: describe.c:5423 +msgid "Lexize" +msgstr "Lexize" + +#: describe.c:5450 +msgid "List of text search templates" +msgstr "Λίστα προτύπων αναζήτησης κειμένου" + +#: describe.c:5510 +msgid "List of text search configurations" +msgstr "Λίστα ρυθμίσεων αναζήτησης κειμένου" + +#: describe.c:5556 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "Δεν βρέθηκαν ρυθμίσεις αναζήτησης κειμένου με όνομα “%s”." + +#: describe.c:5559 +#, c-format +msgid "Did not find any text search configurations." +msgstr "Δεν βρέθηκαν ρυθμίσεις αναζήτησης κειμένου." + +#: describe.c:5625 +msgid "Token" +msgstr "Ενδεικτικό" + +#: describe.c:5626 +msgid "Dictionaries" +msgstr "Λεξικά" + +#: describe.c:5637 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Ρύθμιση αναζήτησης κειμένου “%s.%s”" + +#: describe.c:5640 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Ρύθμιση αναζήτησης κειμένου “%s”" + +#: describe.c:5644 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Αναλυτής: “%s.%s”" + +#: describe.c:5647 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Αναλυτής: “%s”" + +#: describe.c:5681 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει περιτύλιξη ξένων δεδομένων." + +#: describe.c:5739 +msgid "List of foreign-data wrappers" +msgstr "Λίστα περιτύλιξης ξένων δεδομένων" + +#: describe.c:5764 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "Ο διακομιστής (έκδοση %s) δεν ξενικούς διακομιστές." + +#: describe.c:5777 +msgid "Foreign-data wrapper" +msgstr "Περιτύλιξη ξένων δεδομένων" + +#: describe.c:5795 describe.c:6000 +msgid "Version" +msgstr "Έκδοση" + +#: describe.c:5821 +msgid "List of foreign servers" +msgstr "Λίστα ξενικών διακομιστών" + +#: describe.c:5846 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει αντιστοιχίσεις χρηστών." + +#: describe.c:5856 describe.c:5920 +msgid "Server" +msgstr "Διακομιστής" + +#: describe.c:5857 +msgid "User name" +msgstr "Όνομα χρήστη" + +#: describe.c:5882 +msgid "List of user mappings" +msgstr "Λίστα αντιστοιχιών χρηστών" + +#: describe.c:5907 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "Ο διακομιστής (έκδοση %s) δεν ξενικούς πίνακες." + +#: describe.c:5960 +msgid "List of foreign tables" +msgstr "Λίστα ξενικών πινάκων" + +#: describe.c:5985 describe.c:6042 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει επεκτάσεις." + +#: describe.c:6017 +msgid "List of installed extensions" +msgstr "Λίστα εγκατεστημένων επεκτάσεων" + +#: describe.c:6070 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "Δεν βρέθηκε καμία επέκταση με το όνομα \"%s\"." + +#: describe.c:6073 +#, c-format +msgid "Did not find any extensions." +msgstr "Δεν βρέθηκαν επεκτάσεις." + +#: describe.c:6117 +msgid "Object description" +msgstr "Περιγραφή αντικειμένου" + +#: describe.c:6127 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "Αντικείμενα στην επέκταση \"%s\"" + +#: describe.c:6156 describe.c:6232 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει δημοσιεύσεις." + +#: describe.c:6173 describe.c:6310 +msgid "All tables" +msgstr "Όλοι οι πίνακες" + +#: describe.c:6174 describe.c:6311 +msgid "Inserts" +msgstr "Εισαγωγές" + +#: describe.c:6175 describe.c:6312 +msgid "Updates" +msgstr "Ενημερώσεις" + +#: describe.c:6176 describe.c:6313 +msgid "Deletes" +msgstr "Διαγραφές" + +#: describe.c:6180 describe.c:6315 +msgid "Truncates" +msgstr "Περικοπές" + +#: describe.c:6184 describe.c:6317 +msgid "Via root" +msgstr "Διαμέσου υπερχρήστη" + +#: describe.c:6201 +msgid "List of publications" +msgstr "Λίστα δημοσιεύσεων" + +#: describe.c:6274 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "Δεν βρέθηκε καμία δημοσίευση με όνομα \"%s\"." + +#: describe.c:6277 +#, c-format +msgid "Did not find any publications." +msgstr "Δεν βρέθηκε καμία δημοσίευση." + +#: describe.c:6306 +#, c-format +msgid "Publication %s" +msgstr "Δημοσίευση %s" + +#: describe.c:6354 +msgid "Tables:" +msgstr "Πίνακες:" + +#: describe.c:6398 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "Ο διακομιστής (έκδοση %s) δεν υποστηρίζει συνδρομές." + +#: describe.c:6414 +msgid "Publication" +msgstr "Δημοσίευση" + +#: describe.c:6423 +msgid "Binary" +msgstr "" + +#: describe.c:6424 +msgid "Streaming" +msgstr "" + +#: describe.c:6429 +msgid "Synchronous commit" +msgstr "Σύγχρονη δέσμευση" + +#: describe.c:6430 +msgid "Conninfo" +msgstr "Conninfo" + +#: describe.c:6452 +msgid "List of subscriptions" +msgstr "Λίστα συνδρομών" + +#: describe.c:6519 describe.c:6607 describe.c:6692 describe.c:6775 +msgid "AM" +msgstr "ΑΜ" + +#: describe.c:6520 +msgid "Input type" +msgstr "Τύπος εισόδου" + +#: describe.c:6521 +msgid "Storage type" +msgstr "Τύπος αποθήκευσης" + +#: describe.c:6522 +msgid "Operator class" +msgstr "Κλάση χειριστή" + +#: describe.c:6534 describe.c:6608 describe.c:6693 describe.c:6776 +msgid "Operator family" +msgstr "Οικογένεια χειριστή" + +#: describe.c:6566 +msgid "List of operator classes" +msgstr "Λίστα οικογένειας κλάσεων" + +#: describe.c:6609 +msgid "Applicable types" +msgstr "Εφαρμόσιμοι τύποι" + +#: describe.c:6647 +msgid "List of operator families" +msgstr "Λίστα οικογενειών χειριστών" + +#: describe.c:6694 +msgid "Operator" +msgstr "Χειριστής" + +#: describe.c:6695 +msgid "Strategy" +msgstr "Στρατηγική" + +#: describe.c:6696 +msgid "ordering" +msgstr "Διάταξη" + +#: describe.c:6697 +msgid "search" +msgstr "αναζήτηση" + +#: describe.c:6698 +msgid "Purpose" +msgstr "Στόχος" + +#: describe.c:6703 +msgid "Sort opfamily" +msgstr "Διάταξη opfamily" + +#: describe.c:6734 +msgid "List of operators of operator families" +msgstr "Λίστα χειριστών των οικογενειών χειριστών" + +#: describe.c:6777 +msgid "Registered left type" +msgstr "Καταχωρημένος αριστερός τύπος" + +#: describe.c:6778 +msgid "Registered right type" +msgstr "Καταχωρημένος δεξιός τύπος" + +#: describe.c:6779 +msgid "Number" +msgstr "Αριθμός" + +#: describe.c:6815 +msgid "List of support functions of operator families" +msgstr "Λίστα συναρτήσεων υποστήριξης των οικογενειών χειριστών" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql είναι το διαδραστικό τερματικό της PostgreSQL.\n" +"\n" + +#: help.c:74 help.c:355 help.c:433 help.c:476 +#, c-format +msgid "Usage:\n" +msgstr "Χρήση:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [OPTION]… [DBNAME [USERNAME]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Γενικές επιλογές:\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr " -c, —command=COMMAND εκτέλεσε μόνο μία μονή εντολή (SQL ή εσωτερική) και, στη συνέχεια, εξέλθετε\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr " -d, —dbname=DBNAME ονομασία βάσης δεδομένων στην οποία θα συνδεθείτε (προεπιλογή: “%s”)\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, —file=FILENAME εκτέλεσε εντολές από αρχείο και, στη συνέχεια, έξοδος\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, —list απαρίθμησε τις διαθέσιμες βάσεις δεδομένων και, στη συνέχεια, έξοδος\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, —set=, —variable=NAME=VALUE\n" +" όρισε την μεταβλητή της psql NAME στην τιμή VALUE\n" +" (π.χ., -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, —version εμφάνισε πληροφορίες έκδοσης και, στη συνέχεια, έξοδος\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc να μην διαβαστεί το αρχείο εκκίνησης (~/.psqlrc)\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 (“one”), —single-transaction\n" +" εκτέλεσε ως μεμονωμένη συναλλαγή (εάν δεν είναι διαδραστική)\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, —help[=options] εμφάνισε αυτής της βοήθειας και, στη συνέχεια, έξοδος\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " —help=commands απαρίθμησε τις εντολές ανάποδης καθέτου και, στη συνέχεια, έξοδος\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " —help=variables απαρίθμησε τις ειδικές μεταβλητές και, στη συνέχεια, έξοδος\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Επιλογές εισόδου και εξόδου:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, —echo-all echo όλη την είσοδο από σενάριο\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, —echo-errors echo όλες τις αποτυχημένες εντολές\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, —echo-queries echo τις εντολές που αποστέλλονται στο διακομιστή\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, —echo-hidden εμφάνισε ερωτήματα που δημιουργούνται από εσωτερικές εντολές\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, —log-file=FILENAME στείλε την καταγραφή της συνεδρίας στο αρχείο\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, —no-readline απενεργοποιήσε την βελτιωμένη επεξεργασία γραμμής εντολών (readline)\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, —output=FILENAME στείλε τα αποτελέσματα ερωτημάτων σε αρχείο (ή |pipe)\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, —quiet εκτέλεσε σιωπηλά (καθόλου μηνύματα, μόνο έξοδος ερωτημάτων)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, —single-step λειτουργία μονού βήματος (επιβεβαίωσε κάθε ερώτημα)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr " -S, —single-line λειτουργία μονής γραμμής (το τέλος της γραμμής τερματίζει την εντολή SQL)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Επιλογές μορφής εξόδου:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, —no-align λειτουργία εξόδου πίνακα μη ευθυγραμμισμένη λειτουργία εξόδου πίνακα\n" + +#: help.c:111 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " —csv λειτουργία εξόδου πίνακα CSV (τιμές διαχωρισμένες με κόμματα)\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, —field-separator=STRING\n" +" διαχωριστικό πεδίου για μη ευθυγραμμισμένη έξοδο (προεπιλογή: \"%s\")\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, —html λειτουργία εξόδου πίνακα HTML\n" + +#: help.c:116 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr " -P, --pset=VAR[=ARG] όρισε την επιλογή εκτύπωσης VAR σε ARG (δείτε την εντολή \\pset)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, —record-separator=STRING\n" +" διαχωριστικό εγγραφών για μη ευθυγραμμισμένη έξοδο (προεπιλογή: νέα γραμμή)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, —tuples-only εκτύπωσε μόνο γραμμές\n" + +#: help.c:120 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr " -T, —table-attr=TEXT όρισε τα χαρακτηριστικά ετικετών πίνακα HTML (π.χ. πλάτος, περίγραμμα)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, —expanded ενεργοποίησε λειτουργία εκτεταμένης εξόδου πίνακα\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, —field-separator-zero\n" +" όρισε το διαχωριστικό πεδίου για μη ευθυγραμμισμένη έξοδο στο μηδενικό byte\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, —record-separator-zero\n" +" όρισε το διαχωριστικό εγγραφών για μη ευθυγραμμισμένη έξοδο στο μηδενικό byte\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Επιλογές σύνδεσης:\n" + +#: help.c:130 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr " -h, —host=HOSTNAME κεντρικός υπολογιστής διακομιστή βάσης δεδομένων ή κατάλογος υποδοχών (προεπιλογή: \"%s\")\n" + +#: help.c:131 +msgid "local socket" +msgstr "τοπική υποδοχή" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, —port=PORT θύρα διακομιστή βάσης δεδομένων (προεπιλογή: \"%s\")\n" + +#: help.c:137 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, —username=USERNAME όνομα χρήστη βάσης δεδομένων (προεπιλογή: \"%s\")\n" + +#: help.c:138 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, —no-password να μην ζητείται ποτέ κωδικός πρόσβασης\n" + +#: help.c:139 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, —password αναγκαστική προτροπή κωδικού πρόσβασης (πρέπει να συμβεί αυτόματα)\n" + +#: help.c:141 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"Για περισσότερες πληροφορίες, πληκτρολογήστε \"\\?\" (για εσωτερικές εντολές) ή “\\help” (για SQL\n" +"εντολές) μέσα από το psql, ή συμβουλευτείτε την ενότητα psql στην τεκμηρίωση της PostgreSQL\n" +"\n" + +#: help.c:144 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Υποβάλετε αναφορές σφάλματων σε <%s>.\n" + +#: help.c:145 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s αρχική σελίδα: <%s>\n" + +#: help.c:171 +#, c-format +msgid "General\n" +msgstr "Γενικά\n" + +#: help.c:172 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright εμφάνισε τους όρους χρήσης και διανομής της PostgreSQL\n" + +#: help.c:173 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [COLUMNS] εκτέλεσε την ερώτηση και execute query and εμφάνισε τα αποτελέσματα σε μορφή crosstab\n" + +#: help.c:174 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose εμφάνισε το πιο πρόσφατο μήνυμα σφάλματος στη μέγιστη λεπτομέρεια\n" + +#: help.c:175 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(OPTIONS)] [FILE] εκτέλεσε το ερώτημα (και στείλτε αποτελέσματα σε αρχείο ή |pipe).\n" +" \\g χωρίς επιλογές ισοδυναμεί με το ερωματικό\n" + +#: help.c:177 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc περίγραψε το αποτέλεσμα του ερωτήματος, χωρίς να εκτελεστεί\n" + +#: help.c:178 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr " \\gexec εκτέλεσε το ερώτημα και, στη συνέχεια, εκτέλεσε κάθε τιμή του αποτελέσματός της\n" + +#: help.c:179 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PREFIX] εκτέλεσε το ερώτημα και αποθήκευσε τα αποτελέσματα σε μεταβλητές της psql\n" + +#: help.c:180 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [(OPTIONS)] [FILE] όμοια με \\g, αλλά επιβάλλει λειτουργία εκτεταμένης εξόδου\n" + +#: help.c:181 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q τερμάτισε psql\n" + +#: help.c:182 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SEC] εκτέλεση του ερωτήματος κάθε SEC δευτερόλεπτα\n" + +#: help.c:185 +#, c-format +msgid "Help\n" +msgstr "Βοήθεια\n" + +#: help.c:187 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commands] εμφάνισε την βοήθεια για τις εντολές ανάποδης καθέτου\n" + +#: help.c:188 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? options εμφάνισε την βοήθεια για τις επιλογές εντολών γραμμής της psql\n" + +#: help.c:189 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables εμφάνισε την βοήθεια για τις ειδικές μεταβλητές\n" + +#: help.c:190 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr " \\h [NAME] βοήθεια για την σύνταξη των εντολών SQL, * για όλες τις εντολών\n" + +#: help.c:193 +#, c-format +msgid "Query Buffer\n" +msgstr "Ενδιάμεση μνήμη Ερωτήματος\n" + +#: help.c:194 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr " \\e [FILE] [LINE] επεξεργάσου την ενδιάμεση μνήμη (ή αρχείο) ερωτήματος με εξωτερικό επεξεργαστή κειμένου\n" + +#: help.c:195 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [FUNCNAME [LINE]] επεξεργάσου τον ορισμό της συνάρτησης με εξωτερικό επεξεργαστή κειμένου\n" + +#: help.c:196 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr " \\ef [FUNCNAME [LINE]] επεξεργάσου τον ορισμό της όψης με εξωτερικό επεξεργαστή κειμένου\n" + +#: help.c:197 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p εμφάνισε τα περιοχόμενα της ενδιάμεσης μνήμης ερωτήματος\n" + +#: help.c:198 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r επαναφορά (αρχικοποίηση) της ενδιάμεσης μνήμης ερωτήματος\n" + +#: help.c:200 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [FILE] εμφάνισε το ιστορικό η αποθήκευσε το σε αρχείο\n" + +#: help.c:202 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w FILE γράψε την ενδιάμεση μνήμη ερωτήματος σε αρχείο\n" + +#: help.c:205 +#, c-format +msgid "Input/Output\n" +msgstr "Είσοδος/Έξοδος\n" + +#: help.c:206 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr " \\copy … εκτέλεσε SQL COPY με ροή δεδομένων σε διακομιστή πελάτη\n" + +#: help.c:207 +#, c-format +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr " \\echo [-n] [STRING] γράψε την στοιχειοσειρά στην τυπική έξοδο (-n για παράληψη νέας γραμμής)\n" + +#: help.c:208 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i FILE εκτέλεσε εντολές από αρχείο\n" + +#: help.c:209 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr " \\ir FILE όπως \\i, αλλά σε σχέση με την τοποθεσία του τρέχοντος σεναρίου\n" + +#: help.c:210 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [FILE] στείλε όλα τα αποτελέσματα ερωτημάτων σε αρχείο ή |pipe\n" + +#: help.c:211 +#, c-format +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr " \\qecho [-n] [STRING] γράψε την στοιχειοσειρά στην ροή εξόδου \\o (-n για παράληψη νέας γραμμής)\n" + +#: help.c:212 +#, c-format +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr " \\warn [-n] [STRING] γράψε την στοιχειοσειρά στο τυπικό σφάλμα (-n για παράληψη νέας γραμμής)\n" + +#: help.c:215 +#, c-format +msgid "Conditional\n" +msgstr "Υπό συνθήκη\n" + +#: help.c:216 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR έναρξη υπό συνθήκης μπλοκ\n" + +#: help.c:217 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR εναλλακτική λύση εντός του τρέχοντος μπλοκ υπό όρους\n" + +#: help.c:218 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else τελική εναλλακτική λύση εντός του τρέχοντος μπλοκ υπό όρους\n" + +#: help.c:219 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif τερματισμός μπλοκ υπό όρους\n" + +#: help.c:222 +#, c-format +msgid "Informational\n" +msgstr "Πληροφοριακά\n" + +#: help.c:223 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (επιλογές: S = εμφάνισε αντικείμενα συστήματος, + = επιπλέον λεπτομέριες)\n" + +#: help.c:224 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] εμφάνισε πίνακες, όψεις και σειρές\n" + +#: help.c:225 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+] NAME περιέγραψε πίνακα, όψη, σειρά, ή ευρετήριο\n" + +#: help.c:226 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [PATTERN] απαρίθμησε συγκεντρωτικά\n" + +#: help.c:227 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [PATTERN] απαρίθμησε μεθόδους πρόσβασης\n" + +#: help.c:228 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] απαρίθμησε κλάσεις χειριστή\n" + +#: help.c:229 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] απαρίθμησε οικογένειες χειριστών\n" + +#: help.c:230 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] απαρίθμησε χειριστές των οικογενειών χειριστών\n" + +#: help.c:231 +#, c-format +msgid " \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp [AMPTRN [OPFPTRN]] απαρίθμησε συναρτήσεις των οικογενειών χειριστών\n" + +#: help.c:232 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [PATTERN] απαρίθμησε πινακοχώρους\n" + +#: help.c:233 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [PATTERN] απαρίθμησε μετατροπές\n" + +#: help.c:234 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [PATTERN] απαρίθμησε casts\n" + +#: help.c:235 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr " \\dd[S] [PATTERN] εμφάνισε περιγραφές αντικειμένων που δεν φαίνονται πουθενά αλλού\n" + +#: help.c:236 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [PATTERN] απαρίθμησε πεδία\n" + +#: help.c:237 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [PATTERN] απαρίθμησε προεπιλεγμένα προνόμια\n" + +#: help.c:238 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [PATTERN] απαρίθμησε ξενικούς πίνακες\n" + +#: help.c:239 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [PATTERN] απαρίθμησε ξενικούς πίνακες\n" + +#: help.c:240 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [PATTERN] απαρίθμησε ξενικούς διακομιστές\n" + +#: help.c:241 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [PATTERN] απαρίθμησε αντιστοιχίες χρηστών\n" + +#: help.c:242 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [PATTERN] απαρίθμησε περιτυλίξεις ξένων δεδομένων\n" + +#: help.c:243 +#, fuzzy, c-format +#| msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgid "" +" \\df[anptw][S+] [FUNCPTRN [TYPEPTRN ...]]\n" +" list [only agg/normal/procedure/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [PATRN] απαρίθμησε συναρτήσεις [μόνο agg/normal/procedures/trigger/window]\n" + +#: help.c:245 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [PATTERN] απαρίθμησε ρυθμίσεις αναζήτησης κειμένου\n" + +#: help.c:246 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [PATTERN] απαρίθμησε λεξικά αναζήτησης κειμένου\n" + +#: help.c:247 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [PATTERN] απαρίθμησε αναλυτές αναζήτησης κειμένου\n" + +#: help.c:248 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [PATTERN] απαρίθμησε πρότυπα αναζήτησης κειμένου\n" + +#: help.c:249 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [PATTERN] απαρίθμησε ρόλους\n" + +#: help.c:250 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [PATTERN] απαρίθμησε ευρετήρια\n" + +#: help.c:251 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl απαρίθμησε μεγάλα αντικείμενα, όπως \\lo_list\n" + +#: help.c:252 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [PATTERN] απαρίθμησε διαδικαστικές γλώσσες\n" + +#: help.c:253 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [PATTERN] απαρίθμησε υλοποιημένες όψεις\n" + +#: help.c:254 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [PATTERN] απαρίθμησε σχήματα\n" + +#: help.c:255 +#, fuzzy, c-format +#| msgid " \\do[S] [PATTERN] list operators\n" +msgid "" +" \\do[S] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" +" list operators\n" +msgstr " \\do[S] [PATTERN] απαρίθμησε χειριστές\n" + +#: help.c:257 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [PATTERN] απαρίθμησε συρραφές\n" + +#: help.c:258 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [PATTERN] απαρίθμησε προνόμια πρόσβασης πίνακα, όψης και σειράς\n" + +#: help.c:259 +#, c-format +msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" +msgstr " \\dP[itn+] [PATTERN] απαρίθμησε διαχωρισμένες σχέσεις [μόνο ευρετήριο/πίνακα] [n=nested]\n" + +#: help.c:260 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [PATRN1 [PATRN2]] απαρίθμησε ρυθμίσεις ρόλου ανά βάση δεδομένων\n" + +#: help.c:261 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [PATTERN] απαρίθμησε δημοσιεύσεις αναπαραγωγής\n" + +#: help.c:262 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [PATTERN] απαρίθμησε συνδρομές αναπαραγωγής\n" + +#: help.c:263 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [PATTERN] απαρίθμησε ακολουθίες\n" + +#: help.c:264 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [PATTERN] απαρίθμησε πίνακες\n" + +#: help.c:265 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [PATTERN] απαρίθμησε τύπους δεδομένων\n" + +#: help.c:266 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [PATTERN] απαρίθμησε ρόλους\n" + +#: help.c:267 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [PATTERN] απαρίθμησε όψεις\n" + +#: help.c:268 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [PATTERN] απαρίθμησε προεκτάσεις\n" + +#: help.c:269 +#, fuzzy, c-format +#| msgid " \\dy [PATTERN] list event triggers\n" +msgid " \\dX [PATTERN] list extended statistics\n" +msgstr " \\dy [PATTERN] απαρίθμησε εναύσματα συμβάντων\n" + +#: help.c:270 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [PATTERN] απαρίθμησε εναύσματα συμβάντων\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [PATTERN] απαρίθμησε βάσεις δεδομένων\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] FUNCNAME εμφάνισε τον ορισμό μίας συνάρτησης\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] VIEWNAME εμφάνισε τον ορισμό μίας όψης\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [PATTERN] όπως \\dp\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "Μορφοποίηση\n" + +#: help.c:278 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr " \\a εναλλαγή μεταξύ μη ευθυγραμμισμένης και ευθυγραμμισμένης μορφής εξόδου\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr " \\C [STRING] όρισε τίτλο πίνακα, ή αναίρεσε εάν κενό\n" + +#: help.c:280 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr " \\f [STRING] εμφάνισε ή όρισε τον διαχωριστή πεδίου για μη ευθυγραμμισμένη έξοδο ερωτήματος\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H εναλλαγή λειτουργίας εξόδου HTML (επί του παρόντος% s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [NAME [VALUE]] όρισε την επιλογή εξόδου πίνακα\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] εμφάνισε μόνο γραμμές (επί του παρόντος %s)\n" + +#: help.c:292 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr "\\T [STRING] ορίστε χαρακτηριστικά ετικέτας πίνακα HTML, ή αναίρεσε εάν δεν υπάρχουν\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] εναλλαγή τιμής διευρυμένης εξόδου (επί του παρόντος %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "Σύνδεση\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" σύνδεση σε νέα βάση δεδομένων (επί του παρόντος “%s”)\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" σύνδεση σε νέα βάση δεδομένων (επί του παρόντος καμία σύνδεση)\n" + +#: help.c:305 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo εμφάνιση πληροφοριών σχετικά με την παρούσα σύνδεση\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " -E, —encoding=ENCODING εμφάνισε ή όρισε την κωδικοποίηση του πελάτη\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr " \\password [USERNAME] άλλαξε με ασφάλεια τον κωδικό πρόσβασης ενός χρήστη\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "Λειτουργικό σύστημα\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [DIR] άλλαξε τον παρόν κατάλογο εργασίας\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv NAME [VALUE] όρισε ή αναίρεσε μεταβλητή περιβάλλοντος\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] εναλλαγή χρονισμού των εντολών (επί του παρόντος %s)\n" + +#: help.c:315 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr " \\! [COMMAND] εκτέλεσε εντολή σε κέλυφος ή ξεκίνησε διαδραστικό κέλυφος\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "Μεταβλητές\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr " \\prompt [TEXT] NAME προέτρεψε τον χρήστη να ορίσει εσωτερική μεταβλητή\n" + +#: help.c:320 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr " \\set [NAME [VALUE]] όρισε εσωτερική μεταβλητή, ή απαρίθμησέ τες όλες εάν δεν υπάρχουν παράμετροι\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset NAME αναίρεσε (διέγραψε) εσωτερική μεταβλητή\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "Μεγάλα αντικείμενα\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID λειτουργίες μεγάλου αντικειμένου\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"Απαρίθμηση των ειδικά επεξεργασμένων μεταβλητών\n" +"\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "psql μεταβλητές:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql —set=NAME=VALUE\n" +" ή \\set NAME VALUE μέσα σε psql\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" εφόσον ορισμένο, επιτυχημένες εντολές SQL ολοκληρώνονται αυτόματα\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" καθορίζει τον τύπο (πεζά, κεφαλαία) για την ολοκλήρωση όρων SQL\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" ονομασία της συνδεδεμένης βάσης δεδομένων\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" ελέγχει ποία είσοδος γράφεται στην τυπική έξοδο\n" +" [all, errors, none, queries]\n" +"\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" εάν έχει οριστεί, εμφανίστε εσωτερικά ερωτήματα που εκτελούνται από εντολές ανάστρωσής τους.\n" +" εάν οριστεί σε \"noexec\", απλά δείξτε τους χωρίς εκτέλεση\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" τρέχουσα κωδικοποίηση χαρακτήρων του προγράμματος-πελάτη\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" αληθές εάν το τελευταίο ερώτημα απέτυχε, διαφορετικά ψευδές\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" αριθμός των σειρών αποτελεσμάτων για λήψη και εμφάνιση ανά επανάλληψη (0 = απεριόριστος)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" εάν έχει οριστεί, δεν εμφανίζονται μέθοδοι πρόσβασης πίνακα\n" + +#: help.c:379 +#, fuzzy, c-format +#| msgid "" +#| " HIDE_TABLEAM\n" +#| " if set, table access methods are not displayed\n" +msgid "" +" HIDE_TOAST_COMPRESSION\n" +" if set, compression methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" εάν έχει οριστεί, δεν εμφανίζονται μέθοδοι πρόσβασης πίνακα\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" ελέγχει το ιστορικό εντολών [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" όνομα αρχείου που χρησιμοποιείται για την αποθήκευση του ιστορικού εντολών\n" + +#: help.c:385 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" μέγιστος αριθμός εντολών που θα αποθηκευτούν στο ιστορικό εντολών\n" + +#: help.c:387 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" ο συνδεδεμένος κεντρικός υπολογιστής διακομιστή βάσης δεδομένων\n" + +#: help.c:389 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" αριθμός των EOF που απαιτούνται για τον τερματισμό μιας διαδραστικής συνεδρίας\n" + +#: help.c:391 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" τιμή του τελευταίου επηρεασμένου OID\n" + +#: help.c:393 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" μήνυμα και SQLSTATE του τελευταίου σφάλματος, ή κενή συμβολοσειρά και \"00000\" εάν δεν\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" εάν έχει οριστεί, ένα σφάλμα δεν διακόπτει μια συναλλαγή (χρησιμοποιεί έμμεσα σημεία αποθήκευσης)\n" + +#: help.c:398 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" σταμάτησε την ομαδική εκτέλεση μετά από σφάλμα\n" + +#: help.c:400 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" θύρα διακομιστή της τρέχουσας σύνδεσης\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" ορίζει την τυπική προτροπή psql\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" καθορίζει την προτροπή που χρησιμοποιείται όταν μια πρόταση συνεχίζεται από προηγούμενη γραμμή\n" + +#: help.c:406 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" καθορίζει την προτροπή που χρησιμοποιείται κατά την διάρκεια COPY … FROM STDIN\n" + +#: help.c:408 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" σιωπηλή εκτέλεση(όμοια με την επιλογή -q)\n" + +#: help.c:410 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" αριθμός των επηρεασμένων ή επιστρεφομένων σειρών του τελευταίου ερωτήματος, ή 0\n" + +#: help.c:412 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" έκδοση διακομιστή (σε σύντομη συμβολοσειρά ή αριθμητική μορφή)\n" + +#: help.c:415 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" ελέγχει την εμφάνιση των πεδίων του περιεχομένου μηνύματος [never, errors, always]\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" εάν έχει οριστεί, το τέλος γραμμής ολοκληρώνει τα ερωτήματα SQL (όμοια με την επιλογή -S)\n" + +#: help.c:419 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" λειτουργία μονού-βήματος(όμοια με την επιλογή -s)\n" + +#: help.c:421 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE του τελευταίου ερωτήματος, ή “00000” εάν δεν υπήρξαν σφάλματα\n" + +#: help.c:423 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" ο τρέχων συνδεδεμένος χρήστης βάσης δεδομένων\n" + +#: help.c:425 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" ελέγχει την περιφραστικότητα των αναφορών σφαλμάτων [default, verbose, terse, sqlstate]\n" + +#: help.c:427 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" η έκδοση της psql (σε περιγραφική συμβολοσειρά, σύντομη συμβολοσειρά, ή αριθμητική μορφή)\n" + +#: help.c:432 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Ρυθμίσεις εμφάνισης:\n" + +#: help.c:434 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql —set=NAME=VALUE\n" +" ή \\set NAME VALUE μέσα σε συνεδρία psql\n" +"\n" + +#: help.c:436 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" στυλ περιγράμματος (αριθμός)\n" + +#: help.c:438 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" πλάτος προορισμού κατά την εμφάνιση αναδιπλωμένης μορφής\n" + +#: help.c:440 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (ή x)\n" +" διευρυμένη έξοδος [on, off, auto]\n" + +#: help.c:442 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" διαχωριστικό πεδίου σε μορφή μή ευθυγραμισμένης εξόδου (προκαθοριμένο “%s”)\n" + +#: help.c:445 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" ορίζει το διαχωριστικό πεδίου για τη μορφή μη ευθυγραμμισμένης εξόδου στο μηδενικό byte\n" + +#: help.c:447 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" ενεργοποιεί ή απενεργοποιεί την εμφάνιση του υποσέλιδου σε πίνακα [on, off]\n" + +#: help.c:449 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" ορίζει τη μορφή εξόδου [unaligned, aligned, wrapped, html, asciidoc, …]\n" + +#: help.c:451 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" ορίζει τη μορφή περιγράμματος [ascii, old-ascii, unicode]\n" + +#: help.c:453 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" ορίζει τη συμβολοσειρά που θα εκτυπωθεί στη θέση κενής τιμής\n" + +#: help.c:455 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +"numericlocale\n" +" ενεργοποίηση εμφάνισης ενός χαρακτήρα εντοπιότητας για το διαχωρισμό ομάδων ψηφίων\n" + +#: help.c:457 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" Pager\n" +" ελέγχει πότε χρησιμοποιείται εξωτερικός σελιδοποιητής [yes, no, always]\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" διαχωριστικό εγγραφών (σειράς) κατά την έξοδο μη ευθυγραμμισμένης μορφής\n" + +#: help.c:461 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" ορίζει το διαχωριστικό εγγραφών στο μηδενικό byte κατά την έξοδο μη ευθυγραμμισμένης μορφής\n" + +#: help.c:463 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (ή T)\n" +" καθορίζει τα χαρακτηριστικά ενός πίνακα tag σε μορφή HTML, ή καθορίζει\n" +" αναλογικό πλάτος στηλών για τύπους δεδομένων με αριστερή στοίχιση σε μορφή latex-longtable\n" + +#: help.c:466 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" ορίζει τον τίτλο πίνακα για χρήση στους επόμενα εκτυπωμένους πίνακες\n" + +#: help.c:468 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" εάν έχει ορισθεί, τότε εμφανίζονται μόνο τα δεδομένα πίνακα\n" + +#: help.c:470 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" ορισμός του στυλ γραμμής Unicode [single, double]\n" + +#: help.c:475 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Μεταβλητές περιβάλλοντος:\n" + +#: help.c:479 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NAME=VALUE [NAME=VALUE] psql …\n" +" ή \\setenv ΟΝΟΜΑ [ΤΙΜΗ] μέσα σε συνεδρία psql\n" +"\n" + +#: help.c:481 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" ορίστε NAME=VALUE\n" +" psql ...\n" +" ή \\setenv NAME [VALUE] μέσα σε συνεδρία psql\n" +"\n" + +#: help.c:484 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" αριθμός στηλών για αναδιπλωμένη μορφή\n" + +#: help.c:486 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" όμοια με την παράμετρο σύνδεσης application_name\n" + +#: help.c:488 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" όμοια με την παράμετρο σύνδεσης dbname\n" + +#: help.c:490 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" όμοια με την παράμετρο της σύνδεσης κεντρικού υπολογιστή\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" αρχείο κωδικών πρόσβασης\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" κωδικός πρόσβασης σύνδεσης (δεν συνιστάται)\n" + +#: help.c:496 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" όμοια με την παράμετρο σύνδεσης θύρας\n" + +#: help.c:498 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" όμοια με την παράμετρο σύνδεσης χρήστη\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" πρόγραμμα επεξεργασίας κειμένου που χρησιμοποιείται από τις εντολές \\e, \\ef και \\ev\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" τρόπος καθορισμού αριθμού γραμμής κατά την κλήση του προγράμματος επεξεργασίας κειμένου\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" εναλλακτική τοποθεσία για το αρχείο ιστορικού εντολών\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" όνομα του εξωτερικού προγράμματος σελιδοποίησης\n" + +#: help.c:508 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" εναλλακτική τοποθεσία για το αρχείο .psqlrc του χρήστη\n" + +#: help.c:510 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" shell που χρησιμοποιείται κατά την εντολή \\!\n" + +#: help.c:512 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" κατάλογος για προσωρινά αρχεία\n" + +#: help.c:557 +msgid "Available help:\n" +msgstr "Διαθέσιμη βοήθεια:\n" + +#: help.c:652 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"Εντολή: %s\n" +"Περιγραφή: %s\n" +"Σύνταξη:\n" +"%s\n" +"\n" +"Διεύθυνση URL: %s\n" +"\n" + +#: help.c:675 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"Δεν υπάρχει διαθέσιμη βοήθεια για το \"%s\".\n" +"Δοκιμάστε \\h χωρίς παραμέτρους για να δείτε τη διαθέσιμη βοήθεια.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "δεν ήταν δυνατή η ανάγνωση από αρχείο: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "δεν ήταν δυνατή η αποθήκευση του ιστορικού στο αρχείο “%s”: %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "το ιστορικό δεν υποστηρίζεται από την παρούσα εγκατάσταση" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: δεν είναι συνδεμένο σε μία βάση δεδομένων" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: η τρέχουσα συναλλαγή ματαιώθηκε" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: άγνωστη κατάσταση συναλλαγής" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "Μεγάλα αντικείμενα" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if: με διαφυγή" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "Χρησιμοποιείστε “\\q” για να εξέλθετε %s.\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Η είσοδος είναι μια απόθεση PostgreSQL προσαρμοσμένης μορφής.\n" +"Χρησιμοποιήστε το πρόγραμμα γραμμής εντολών pg_restore για να επαναφέρετε αυτήν την απόθεση σε μια βάση δεδομένων.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Χρησιμοποιείστε \\? για βοήθεια ή πληκτρολογήστε control-C για να αδειάσετε την ενδιάμεση μνήμη εισόδου." + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "Χρησιμοποιείστε \\? για βοήθεια." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "Χρησιμοποιείτε psql, τη διασύνδεση γραμμής εντολών της PostgreSQL." + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Πληκτρολογείστε: \\copyright για τους όρους διανομής\n" +" \\h για βοήθεια σχετικά με τις εντολές SQL\n" +" \\? για βοήθεια σχετικά με τις εντολές psql\n" +" \\g ή ολοκληρώστε με ερωτηματικό για να εκτελέσετε ερώτημα\n" +" \\q για έξοδο\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "Χρησιμοποιείστε “\\q” για να εξέλθετε." + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "Πληκτρολογείστε control-D για να εξέλθετε." + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "Πληκτρολογείστε control-D για να εξέλθετε." + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "το ερώτημα παραβλέφθηκε· χρησιμοποιήστε το \\endif ή το Ctrl-C για να κλείσετε το τρέχον υπό συνθήκη \\if μπλοκ" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "έφτασε στο EOF χωρίς να βρεθούν τελικά \\endif(s)" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "ανολοκλήρωτη συμβολοσειρά με εισαγωγικά" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: έλλειψη μνήμης" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:589 sql_help.c:591 sql_help.c:593 +#: sql_help.c:595 sql_help.c:597 sql_help.c:600 sql_help.c:602 sql_help.c:605 +#: sql_help.c:616 sql_help.c:618 sql_help.c:660 sql_help.c:662 sql_help.c:664 +#: sql_help.c:667 sql_help.c:669 sql_help.c:671 sql_help.c:706 sql_help.c:710 +#: sql_help.c:714 sql_help.c:733 sql_help.c:736 sql_help.c:739 sql_help.c:768 +#: sql_help.c:780 sql_help.c:788 sql_help.c:791 sql_help.c:794 sql_help.c:809 +#: sql_help.c:812 sql_help.c:841 sql_help.c:846 sql_help.c:851 sql_help.c:856 +#: sql_help.c:861 sql_help.c:883 sql_help.c:885 sql_help.c:887 sql_help.c:889 +#: sql_help.c:892 sql_help.c:894 sql_help.c:936 sql_help.c:980 sql_help.c:985 +#: sql_help.c:990 sql_help.c:995 sql_help.c:1000 sql_help.c:1019 +#: sql_help.c:1030 sql_help.c:1032 sql_help.c:1051 sql_help.c:1061 +#: sql_help.c:1063 sql_help.c:1065 sql_help.c:1077 sql_help.c:1081 +#: sql_help.c:1083 sql_help.c:1095 sql_help.c:1097 sql_help.c:1099 +#: sql_help.c:1101 sql_help.c:1119 sql_help.c:1121 sql_help.c:1125 +#: sql_help.c:1129 sql_help.c:1133 sql_help.c:1136 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1141 sql_help.c:1143 sql_help.c:1279 +#: sql_help.c:1281 sql_help.c:1284 sql_help.c:1287 sql_help.c:1289 +#: sql_help.c:1291 sql_help.c:1294 sql_help.c:1297 sql_help.c:1411 +#: sql_help.c:1413 sql_help.c:1415 sql_help.c:1418 sql_help.c:1439 +#: sql_help.c:1442 sql_help.c:1445 sql_help.c:1448 sql_help.c:1452 +#: sql_help.c:1454 sql_help.c:1456 sql_help.c:1458 sql_help.c:1472 +#: sql_help.c:1475 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1491 sql_help.c:1501 sql_help.c:1503 sql_help.c:1513 +#: sql_help.c:1516 sql_help.c:1539 sql_help.c:1541 sql_help.c:1543 +#: sql_help.c:1545 sql_help.c:1548 sql_help.c:1550 sql_help.c:1553 +#: sql_help.c:1556 sql_help.c:1607 sql_help.c:1650 sql_help.c:1653 +#: sql_help.c:1655 sql_help.c:1657 sql_help.c:1660 sql_help.c:1662 +#: sql_help.c:1664 sql_help.c:1667 sql_help.c:1717 sql_help.c:1733 +#: sql_help.c:1964 sql_help.c:2033 sql_help.c:2052 sql_help.c:2065 +#: sql_help.c:2122 sql_help.c:2129 sql_help.c:2139 sql_help.c:2160 +#: sql_help.c:2186 sql_help.c:2204 sql_help.c:2231 sql_help.c:2327 +#: sql_help.c:2373 sql_help.c:2397 sql_help.c:2420 sql_help.c:2424 +#: sql_help.c:2458 sql_help.c:2478 sql_help.c:2500 sql_help.c:2514 +#: sql_help.c:2535 sql_help.c:2559 sql_help.c:2589 sql_help.c:2614 +#: sql_help.c:2661 sql_help.c:2949 sql_help.c:2962 sql_help.c:2979 +#: sql_help.c:2995 sql_help.c:3035 sql_help.c:3089 sql_help.c:3093 +#: sql_help.c:3095 sql_help.c:3102 sql_help.c:3121 sql_help.c:3148 +#: sql_help.c:3183 sql_help.c:3195 sql_help.c:3204 sql_help.c:3248 +#: sql_help.c:3262 sql_help.c:3290 sql_help.c:3298 sql_help.c:3310 +#: sql_help.c:3320 sql_help.c:3328 sql_help.c:3336 sql_help.c:3344 +#: sql_help.c:3352 sql_help.c:3361 sql_help.c:3372 sql_help.c:3380 +#: sql_help.c:3388 sql_help.c:3396 sql_help.c:3404 sql_help.c:3414 +#: sql_help.c:3423 sql_help.c:3432 sql_help.c:3440 sql_help.c:3450 +#: sql_help.c:3461 sql_help.c:3469 sql_help.c:3478 sql_help.c:3489 +#: sql_help.c:3498 sql_help.c:3506 sql_help.c:3514 sql_help.c:3522 +#: sql_help.c:3530 sql_help.c:3538 sql_help.c:3546 sql_help.c:3554 +#: sql_help.c:3562 sql_help.c:3570 sql_help.c:3578 sql_help.c:3595 +#: sql_help.c:3604 sql_help.c:3612 sql_help.c:3629 sql_help.c:3644 +#: sql_help.c:3946 sql_help.c:3997 sql_help.c:4026 sql_help.c:4041 +#: sql_help.c:4526 sql_help.c:4574 sql_help.c:4725 +msgid "name" +msgstr "ονομασία" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1814 +#: sql_help.c:3263 sql_help.c:4302 +msgid "aggregate_signature" +msgstr "aggregate_signature" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:572 +#: sql_help.c:590 sql_help.c:617 sql_help.c:668 sql_help.c:735 sql_help.c:790 +#: sql_help.c:811 sql_help.c:850 sql_help.c:895 sql_help.c:937 sql_help.c:989 +#: sql_help.c:1021 sql_help.c:1031 sql_help.c:1064 sql_help.c:1084 +#: sql_help.c:1098 sql_help.c:1144 sql_help.c:1288 sql_help.c:1412 +#: sql_help.c:1455 sql_help.c:1476 sql_help.c:1490 sql_help.c:1502 +#: sql_help.c:1515 sql_help.c:1542 sql_help.c:1608 sql_help.c:1661 +msgid "new_name" +msgstr "new_name" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:619 +#: sql_help.c:628 sql_help.c:689 sql_help.c:709 sql_help.c:738 sql_help.c:793 +#: sql_help.c:855 sql_help.c:893 sql_help.c:994 sql_help.c:1033 sql_help.c:1062 +#: sql_help.c:1082 sql_help.c:1096 sql_help.c:1142 sql_help.c:1351 +#: sql_help.c:1414 sql_help.c:1457 sql_help.c:1478 sql_help.c:1540 +#: sql_help.c:1656 sql_help.c:2935 +msgid "new_owner" +msgstr "new_owner" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:670 sql_help.c:713 sql_help.c:741 +#: sql_help.c:796 sql_help.c:860 sql_help.c:999 sql_help.c:1066 sql_help.c:1100 +#: sql_help.c:1290 sql_help.c:1459 sql_help.c:1480 sql_help.c:1492 +#: sql_help.c:1504 sql_help.c:1544 sql_help.c:1663 +msgid "new_schema" +msgstr "new_schema" + +#: sql_help.c:44 sql_help.c:1878 sql_help.c:3264 sql_help.c:4331 +msgid "where aggregate_signature is:" +msgstr "όπου aggregate_signature είναι:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:842 +#: sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:862 sql_help.c:981 +#: sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1001 sql_help.c:1832 +#: sql_help.c:1849 sql_help.c:1855 sql_help.c:1879 sql_help.c:1882 +#: sql_help.c:1885 sql_help.c:2034 sql_help.c:2053 sql_help.c:2056 +#: sql_help.c:2328 sql_help.c:2536 sql_help.c:3265 sql_help.c:3268 +#: sql_help.c:3271 sql_help.c:3362 sql_help.c:3451 sql_help.c:3479 +#: sql_help.c:3824 sql_help.c:4204 sql_help.c:4308 sql_help.c:4315 +#: sql_help.c:4321 sql_help.c:4332 sql_help.c:4335 sql_help.c:4338 +msgid "argmode" +msgstr "argmode" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:843 +#: sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:863 sql_help.c:982 +#: sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1002 sql_help.c:1833 +#: sql_help.c:1850 sql_help.c:1856 sql_help.c:1880 sql_help.c:1883 +#: sql_help.c:1886 sql_help.c:2035 sql_help.c:2054 sql_help.c:2057 +#: sql_help.c:2329 sql_help.c:2537 sql_help.c:3266 sql_help.c:3269 +#: sql_help.c:3272 sql_help.c:3363 sql_help.c:3452 sql_help.c:3480 +#: sql_help.c:4309 sql_help.c:4316 sql_help.c:4322 sql_help.c:4333 +#: sql_help.c:4336 sql_help.c:4339 +msgid "argname" +msgstr "argname" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:844 +#: sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:864 sql_help.c:983 +#: sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1003 sql_help.c:1834 +#: sql_help.c:1851 sql_help.c:1857 sql_help.c:1881 sql_help.c:1884 +#: sql_help.c:1887 sql_help.c:2330 sql_help.c:2538 sql_help.c:3267 +#: sql_help.c:3270 sql_help.c:3273 sql_help.c:3364 sql_help.c:3453 +#: sql_help.c:3481 sql_help.c:4310 sql_help.c:4317 sql_help.c:4323 +#: sql_help.c:4334 sql_help.c:4337 sql_help.c:4340 +msgid "argtype" +msgstr "argtype" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:931 +#: sql_help.c:1079 sql_help.c:1473 sql_help.c:1602 sql_help.c:1634 +#: sql_help.c:1686 sql_help.c:1749 sql_help.c:1935 sql_help.c:1942 +#: sql_help.c:2234 sql_help.c:2276 sql_help.c:2283 sql_help.c:2292 +#: sql_help.c:2374 sql_help.c:2590 sql_help.c:2683 sql_help.c:2964 +#: sql_help.c:3149 sql_help.c:3171 sql_help.c:3311 sql_help.c:3666 +#: sql_help.c:3865 sql_help.c:4040 sql_help.c:4788 +msgid "option" +msgstr "επιλογή" + +#: sql_help.c:113 sql_help.c:932 sql_help.c:1603 sql_help.c:2375 +#: sql_help.c:2591 sql_help.c:3150 sql_help.c:3312 +msgid "where option can be:" +msgstr "όπου option μπορεί να είναι:" + +#: sql_help.c:114 sql_help.c:2168 +msgid "allowconn" +msgstr "allowconn" + +#: sql_help.c:115 sql_help.c:933 sql_help.c:1604 sql_help.c:2169 +#: sql_help.c:2376 sql_help.c:2592 sql_help.c:3151 +msgid "connlimit" +msgstr "connlimit" + +#: sql_help.c:116 sql_help.c:2170 +msgid "istemplate" +msgstr "istemplate" + +#: sql_help.c:122 sql_help.c:607 sql_help.c:673 sql_help.c:1293 sql_help.c:1344 +#: sql_help.c:4044 +msgid "new_tablespace" +msgstr "new_tablespace" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:867 sql_help.c:869 sql_help.c:870 sql_help.c:940 +#: sql_help.c:944 sql_help.c:947 sql_help.c:1008 sql_help.c:1010 +#: sql_help.c:1011 sql_help.c:1155 sql_help.c:1158 sql_help.c:1611 +#: sql_help.c:1615 sql_help.c:1618 sql_help.c:2340 sql_help.c:2542 +#: sql_help.c:4062 sql_help.c:4515 +msgid "configuration_parameter" +msgstr "configuration_parameter" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:599 sql_help.c:679 sql_help.c:687 sql_help.c:868 +#: sql_help.c:891 sql_help.c:941 sql_help.c:1009 sql_help.c:1080 +#: sql_help.c:1124 sql_help.c:1128 sql_help.c:1132 sql_help.c:1135 +#: sql_help.c:1140 sql_help.c:1156 sql_help.c:1157 sql_help.c:1324 +#: sql_help.c:1346 sql_help.c:1395 sql_help.c:1417 sql_help.c:1474 +#: sql_help.c:1558 sql_help.c:1612 sql_help.c:1635 sql_help.c:2235 +#: sql_help.c:2277 sql_help.c:2284 sql_help.c:2293 sql_help.c:2341 +#: sql_help.c:2342 sql_help.c:2405 sql_help.c:2408 sql_help.c:2442 +#: sql_help.c:2543 sql_help.c:2544 sql_help.c:2562 sql_help.c:2684 +#: sql_help.c:2723 sql_help.c:2829 sql_help.c:2842 sql_help.c:2856 +#: sql_help.c:2897 sql_help.c:2921 sql_help.c:2938 sql_help.c:2965 +#: sql_help.c:3172 sql_help.c:3866 sql_help.c:4516 sql_help.c:4517 +msgid "value" +msgstr "value" + +#: sql_help.c:197 +msgid "target_role" +msgstr "target_role" + +#: sql_help.c:198 sql_help.c:2219 sql_help.c:2639 sql_help.c:2644 +#: sql_help.c:3799 sql_help.c:3808 sql_help.c:3827 sql_help.c:3836 +#: sql_help.c:4179 sql_help.c:4188 sql_help.c:4207 sql_help.c:4216 +msgid "schema_name" +msgstr "schema_name" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "abbreviated_grant_or_revoke" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "όπου abbreviated_grant_or_revoke είναι ένα από:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:570 sql_help.c:606 sql_help.c:672 sql_help.c:814 sql_help.c:951 +#: sql_help.c:1292 sql_help.c:1622 sql_help.c:2379 sql_help.c:2380 +#: sql_help.c:2381 sql_help.c:2382 sql_help.c:2383 sql_help.c:2516 +#: sql_help.c:2595 sql_help.c:2596 sql_help.c:2597 sql_help.c:2598 +#: sql_help.c:2599 sql_help.c:3154 sql_help.c:3155 sql_help.c:3156 +#: sql_help.c:3157 sql_help.c:3158 sql_help.c:3845 sql_help.c:3849 +#: sql_help.c:4225 sql_help.c:4229 sql_help.c:4536 +msgid "role_name" +msgstr "role_name" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1308 sql_help.c:1310 +#: sql_help.c:1361 sql_help.c:1374 sql_help.c:1399 sql_help.c:1652 +#: sql_help.c:2189 sql_help.c:2193 sql_help.c:2296 sql_help.c:2301 +#: sql_help.c:2401 sql_help.c:2700 sql_help.c:2705 sql_help.c:2707 +#: sql_help.c:2824 sql_help.c:2837 sql_help.c:2851 sql_help.c:2860 +#: sql_help.c:2872 sql_help.c:2901 sql_help.c:3897 sql_help.c:3912 +#: sql_help.c:3914 sql_help.c:4393 sql_help.c:4394 sql_help.c:4403 +#: sql_help.c:4445 sql_help.c:4446 sql_help.c:4447 sql_help.c:4448 +#: sql_help.c:4449 sql_help.c:4450 sql_help.c:4490 sql_help.c:4491 +#: sql_help.c:4496 sql_help.c:4501 sql_help.c:4642 sql_help.c:4643 +#: sql_help.c:4652 sql_help.c:4694 sql_help.c:4695 sql_help.c:4696 +#: sql_help.c:4697 sql_help.c:4698 sql_help.c:4699 sql_help.c:4753 +#: sql_help.c:4755 sql_help.c:4816 sql_help.c:4874 sql_help.c:4875 +#: sql_help.c:4884 sql_help.c:4926 sql_help.c:4927 sql_help.c:4928 +#: sql_help.c:4929 sql_help.c:4930 sql_help.c:4931 +msgid "expression" +msgstr "expression" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "domain_constraint" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1285 sql_help.c:1332 sql_help.c:1333 sql_help.c:1334 +#: sql_help.c:1360 sql_help.c:1373 sql_help.c:1390 sql_help.c:1820 +#: sql_help.c:1822 sql_help.c:2192 sql_help.c:2295 sql_help.c:2300 +#: sql_help.c:2859 sql_help.c:2871 sql_help.c:3909 +msgid "constraint_name" +msgstr "constraint_name" + +#: sql_help.c:244 sql_help.c:1286 +msgid "new_constraint_name" +msgstr "new_constraint_name" + +#: sql_help.c:317 sql_help.c:1078 +msgid "new_version" +msgstr "new_version" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "member_object" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "όπου member_object είναι:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1812 sql_help.c:1817 sql_help.c:1824 +#: sql_help.c:1825 sql_help.c:1826 sql_help.c:1827 sql_help.c:1828 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:1835 sql_help.c:1837 +#: sql_help.c:1841 sql_help.c:1843 sql_help.c:1847 sql_help.c:1852 +#: sql_help.c:1853 sql_help.c:1860 sql_help.c:1861 sql_help.c:1862 +#: sql_help.c:1863 sql_help.c:1864 sql_help.c:1865 sql_help.c:1866 +#: sql_help.c:1867 sql_help.c:1868 sql_help.c:1869 sql_help.c:1870 +#: sql_help.c:1875 sql_help.c:1876 sql_help.c:4298 sql_help.c:4303 +#: sql_help.c:4304 sql_help.c:4305 sql_help.c:4306 sql_help.c:4312 +#: sql_help.c:4313 sql_help.c:4318 sql_help.c:4319 sql_help.c:4324 +#: sql_help.c:4325 sql_help.c:4326 sql_help.c:4327 sql_help.c:4328 +#: sql_help.c:4329 +msgid "object_name" +msgstr "object_name" + +#: sql_help.c:326 sql_help.c:1813 sql_help.c:4301 +msgid "aggregate_name" +msgstr "aggregate_name" + +#: sql_help.c:328 sql_help.c:1815 sql_help.c:2099 sql_help.c:2103 +#: sql_help.c:2105 sql_help.c:3281 +msgid "source_type" +msgstr "source_type" + +#: sql_help.c:329 sql_help.c:1816 sql_help.c:2100 sql_help.c:2104 +#: sql_help.c:2106 sql_help.c:3282 +msgid "target_type" +msgstr "source_type" + +#: sql_help.c:336 sql_help.c:778 sql_help.c:1831 sql_help.c:2101 +#: sql_help.c:2142 sql_help.c:2207 sql_help.c:2459 sql_help.c:2490 +#: sql_help.c:3041 sql_help.c:4203 sql_help.c:4307 sql_help.c:4422 +#: sql_help.c:4426 sql_help.c:4430 sql_help.c:4433 sql_help.c:4671 +#: sql_help.c:4675 sql_help.c:4679 sql_help.c:4682 sql_help.c:4903 +#: sql_help.c:4907 sql_help.c:4911 sql_help.c:4914 +msgid "function_name" +msgstr "function_name" + +#: sql_help.c:341 sql_help.c:771 sql_help.c:1838 sql_help.c:2483 +msgid "operator_name" +msgstr "operator_name" + +#: sql_help.c:342 sql_help.c:707 sql_help.c:711 sql_help.c:715 sql_help.c:1839 +#: sql_help.c:2460 sql_help.c:3405 +msgid "left_type" +msgstr "source_type" + +#: sql_help.c:343 sql_help.c:708 sql_help.c:712 sql_help.c:716 sql_help.c:1840 +#: sql_help.c:2461 sql_help.c:3406 +msgid "right_type" +msgstr "source_type" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:734 sql_help.c:737 sql_help.c:740 +#: sql_help.c:769 sql_help.c:781 sql_help.c:789 sql_help.c:792 sql_help.c:795 +#: sql_help.c:1379 sql_help.c:1842 sql_help.c:1844 sql_help.c:2480 +#: sql_help.c:2501 sql_help.c:2877 sql_help.c:3415 sql_help.c:3424 +msgid "index_method" +msgstr "source_type" + +#: sql_help.c:349 sql_help.c:1848 sql_help.c:4314 +msgid "procedure_name" +msgstr "procedure_name" + +#: sql_help.c:353 sql_help.c:1854 sql_help.c:3823 sql_help.c:4320 +msgid "routine_name" +msgstr "routine_name" + +#: sql_help.c:365 sql_help.c:1350 sql_help.c:1871 sql_help.c:2336 +#: sql_help.c:2541 sql_help.c:2832 sql_help.c:3008 sql_help.c:3586 +#: sql_help.c:3842 sql_help.c:4222 +msgid "type_name" +msgstr "type_name" + +#: sql_help.c:366 sql_help.c:1872 sql_help.c:2335 sql_help.c:2540 +#: sql_help.c:3009 sql_help.c:3239 sql_help.c:3587 sql_help.c:3830 +#: sql_help.c:4210 +msgid "lang_name" +msgstr "lang_name" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "και aggregate_signature είναι:" + +#: sql_help.c:392 sql_help.c:1966 sql_help.c:2232 +msgid "handler_function" +msgstr "handler_function" + +#: sql_help.c:393 sql_help.c:2233 +msgid "validator_function" +msgstr "validator_function" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:661 sql_help.c:845 sql_help.c:984 +#: sql_help.c:1280 sql_help.c:1549 +msgid "action" +msgstr "action" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:665 sql_help.c:675 sql_help.c:677 +#: sql_help.c:680 sql_help.c:682 sql_help.c:683 sql_help.c:1060 sql_help.c:1282 +#: sql_help.c:1300 sql_help.c:1304 sql_help.c:1305 sql_help.c:1309 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1314 +#: sql_help.c:1316 sql_help.c:1319 sql_help.c:1320 sql_help.c:1322 +#: sql_help.c:1325 sql_help.c:1327 sql_help.c:1328 sql_help.c:1375 +#: sql_help.c:1377 sql_help.c:1384 sql_help.c:1393 sql_help.c:1398 +#: sql_help.c:1651 sql_help.c:1654 sql_help.c:1658 sql_help.c:1694 +#: sql_help.c:1819 sql_help.c:1932 sql_help.c:1938 sql_help.c:1951 +#: sql_help.c:1952 sql_help.c:1953 sql_help.c:2274 sql_help.c:2287 +#: sql_help.c:2333 sql_help.c:2400 sql_help.c:2406 sql_help.c:2439 +#: sql_help.c:2669 sql_help.c:2704 sql_help.c:2706 sql_help.c:2814 +#: sql_help.c:2823 sql_help.c:2833 sql_help.c:2836 sql_help.c:2846 +#: sql_help.c:2850 sql_help.c:2873 sql_help.c:2875 sql_help.c:2882 +#: sql_help.c:2895 sql_help.c:2900 sql_help.c:2918 sql_help.c:3044 +#: sql_help.c:3184 sql_help.c:3802 sql_help.c:3803 sql_help.c:3896 +#: sql_help.c:3911 sql_help.c:3913 sql_help.c:3915 sql_help.c:4182 +#: sql_help.c:4183 sql_help.c:4300 sql_help.c:4454 sql_help.c:4460 +#: sql_help.c:4462 sql_help.c:4703 sql_help.c:4709 sql_help.c:4711 +#: sql_help.c:4752 sql_help.c:4754 sql_help.c:4756 sql_help.c:4804 +#: sql_help.c:4935 sql_help.c:4941 sql_help.c:4943 +msgid "column_name" +msgstr "column_name" + +#: sql_help.c:444 sql_help.c:666 sql_help.c:1283 sql_help.c:1659 +msgid "new_column_name" +msgstr "new_column_name" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:674 sql_help.c:866 sql_help.c:1005 +#: sql_help.c:1299 sql_help.c:1559 +msgid "where action is one of:" +msgstr "όπου action είναι ένα από:" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1052 sql_help.c:1301 +#: sql_help.c:1306 sql_help.c:1561 sql_help.c:1565 sql_help.c:2187 +#: sql_help.c:2275 sql_help.c:2479 sql_help.c:2662 sql_help.c:2815 +#: sql_help.c:3091 sql_help.c:3998 +msgid "data_type" +msgstr "data_type" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1302 sql_help.c:1307 +#: sql_help.c:1562 sql_help.c:1566 sql_help.c:2188 sql_help.c:2278 +#: sql_help.c:2402 sql_help.c:2816 sql_help.c:2825 sql_help.c:2838 +#: sql_help.c:2852 sql_help.c:3092 sql_help.c:3098 sql_help.c:3906 +msgid "collation" +msgstr "collation" + +#: sql_help.c:453 sql_help.c:1303 sql_help.c:2279 sql_help.c:2288 +#: sql_help.c:2818 sql_help.c:2834 sql_help.c:2847 +msgid "column_constraint" +msgstr "column_constraint" + +#: sql_help.c:463 sql_help.c:604 sql_help.c:676 sql_help.c:1321 sql_help.c:4801 +msgid "integer" +msgstr "integer" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:678 sql_help.c:681 sql_help.c:1323 +#: sql_help.c:1326 +msgid "attribute_option" +msgstr "attribute_option" + +#: sql_help.c:473 sql_help.c:1330 sql_help.c:2280 sql_help.c:2289 +#: sql_help.c:2819 sql_help.c:2835 sql_help.c:2848 +msgid "table_constraint" +msgstr "table_constraint" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:1337 sql_help.c:1338 sql_help.c:1873 +msgid "trigger_name" +msgstr "trigger_name" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1348 sql_help.c:1349 +#: sql_help.c:2281 sql_help.c:2286 sql_help.c:2822 sql_help.c:2845 +msgid "parent_table" +msgstr "parent_table" + +#: sql_help.c:539 sql_help.c:596 sql_help.c:663 sql_help.c:865 sql_help.c:1004 +#: sql_help.c:1518 sql_help.c:2218 +msgid "extension_name" +msgstr "extension_name" + +#: sql_help.c:541 sql_help.c:1006 sql_help.c:2337 +msgid "execution_cost" +msgstr "execution_cost" + +#: sql_help.c:542 sql_help.c:1007 sql_help.c:2338 +msgid "result_rows" +msgstr "result_rows" + +#: sql_help.c:543 sql_help.c:2339 +msgid "support_function" +msgstr "support_function" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:930 sql_help.c:938 sql_help.c:942 +#: sql_help.c:945 sql_help.c:948 sql_help.c:1601 sql_help.c:1609 +#: sql_help.c:1613 sql_help.c:1616 sql_help.c:1619 sql_help.c:2640 +#: sql_help.c:2642 sql_help.c:2645 sql_help.c:2646 sql_help.c:3800 +#: sql_help.c:3801 sql_help.c:3805 sql_help.c:3806 sql_help.c:3809 +#: sql_help.c:3810 sql_help.c:3812 sql_help.c:3813 sql_help.c:3815 +#: sql_help.c:3816 sql_help.c:3818 sql_help.c:3819 sql_help.c:3821 +#: sql_help.c:3822 sql_help.c:3828 sql_help.c:3829 sql_help.c:3831 +#: sql_help.c:3832 sql_help.c:3834 sql_help.c:3835 sql_help.c:3837 +#: sql_help.c:3838 sql_help.c:3840 sql_help.c:3841 sql_help.c:3843 +#: sql_help.c:3844 sql_help.c:3846 sql_help.c:3847 sql_help.c:4180 +#: sql_help.c:4181 sql_help.c:4185 sql_help.c:4186 sql_help.c:4189 +#: sql_help.c:4190 sql_help.c:4192 sql_help.c:4193 sql_help.c:4195 +#: sql_help.c:4196 sql_help.c:4198 sql_help.c:4199 sql_help.c:4201 +#: sql_help.c:4202 sql_help.c:4208 sql_help.c:4209 sql_help.c:4211 +#: sql_help.c:4212 sql_help.c:4214 sql_help.c:4215 sql_help.c:4217 +#: sql_help.c:4218 sql_help.c:4220 sql_help.c:4221 sql_help.c:4223 +#: sql_help.c:4224 sql_help.c:4226 sql_help.c:4227 +msgid "role_specification" +msgstr "role_specification" + +#: sql_help.c:566 sql_help.c:568 sql_help.c:1632 sql_help.c:2161 +#: sql_help.c:2648 sql_help.c:3169 sql_help.c:3620 sql_help.c:4546 +msgid "user_name" +msgstr "user_name" + +#: sql_help.c:569 sql_help.c:950 sql_help.c:1621 sql_help.c:2647 +#: sql_help.c:3848 sql_help.c:4228 +msgid "where role_specification can be:" +msgstr "όπου role_specification μπορεί να είναι:" + +#: sql_help.c:571 +msgid "group_name" +msgstr "group_name" + +#: sql_help.c:592 sql_help.c:1396 sql_help.c:2167 sql_help.c:2409 +#: sql_help.c:2443 sql_help.c:2830 sql_help.c:2843 sql_help.c:2857 +#: sql_help.c:2898 sql_help.c:2922 sql_help.c:2934 sql_help.c:3839 +#: sql_help.c:4219 +msgid "tablespace_name" +msgstr "group_name" + +#: sql_help.c:594 sql_help.c:685 sql_help.c:1343 sql_help.c:1352 +#: sql_help.c:1391 sql_help.c:1748 sql_help.c:1751 +msgid "index_name" +msgstr "index_name" + +#: sql_help.c:598 sql_help.c:601 sql_help.c:686 sql_help.c:688 sql_help.c:1345 +#: sql_help.c:1347 sql_help.c:1394 sql_help.c:2407 sql_help.c:2441 +#: sql_help.c:2828 sql_help.c:2841 sql_help.c:2855 sql_help.c:2896 +#: sql_help.c:2920 +msgid "storage_parameter" +msgstr "storage_parameter" + +#: sql_help.c:603 +msgid "column_number" +msgstr "column_number" + +#: sql_help.c:627 sql_help.c:1836 sql_help.c:4311 +msgid "large_object_oid" +msgstr "large_object_oid" + +#: sql_help.c:684 sql_help.c:1329 sql_help.c:1367 sql_help.c:2817 +#, fuzzy +#| msgid "sampling_method" +msgid "compression_method" +msgstr "sampling_method" + +#: sql_help.c:717 sql_help.c:2464 +msgid "res_proc" +msgstr "res_proc" + +#: sql_help.c:718 sql_help.c:2465 +msgid "join_proc" +msgstr "join_proc" + +#: sql_help.c:770 sql_help.c:782 sql_help.c:2482 +msgid "strategy_number" +msgstr "strategy_number" + +#: sql_help.c:772 sql_help.c:773 sql_help.c:776 sql_help.c:777 sql_help.c:783 +#: sql_help.c:784 sql_help.c:786 sql_help.c:787 sql_help.c:2484 sql_help.c:2485 +#: sql_help.c:2488 sql_help.c:2489 +msgid "op_type" +msgstr "op_type" + +#: sql_help.c:774 sql_help.c:2486 +msgid "sort_family_name" +msgstr "index_name" + +#: sql_help.c:775 sql_help.c:785 sql_help.c:2487 +msgid "support_number" +msgstr "support_number" + +#: sql_help.c:779 sql_help.c:2102 sql_help.c:2491 sql_help.c:3011 +#: sql_help.c:3013 +msgid "argument_type" +msgstr "argument_type" + +#: sql_help.c:810 sql_help.c:813 sql_help.c:884 sql_help.c:886 sql_help.c:888 +#: sql_help.c:1020 sql_help.c:1059 sql_help.c:1514 sql_help.c:1517 +#: sql_help.c:1693 sql_help.c:1747 sql_help.c:1750 sql_help.c:1821 +#: sql_help.c:1846 sql_help.c:1859 sql_help.c:1874 sql_help.c:1931 +#: sql_help.c:1937 sql_help.c:2273 sql_help.c:2285 sql_help.c:2398 +#: sql_help.c:2438 sql_help.c:2515 sql_help.c:2560 sql_help.c:2616 +#: sql_help.c:2668 sql_help.c:2701 sql_help.c:2708 sql_help.c:2813 +#: sql_help.c:2831 sql_help.c:2844 sql_help.c:2917 sql_help.c:3037 +#: sql_help.c:3218 sql_help.c:3441 sql_help.c:3490 sql_help.c:3596 +#: sql_help.c:3798 sql_help.c:3804 sql_help.c:3862 sql_help.c:3894 +#: sql_help.c:4178 sql_help.c:4184 sql_help.c:4299 sql_help.c:4408 +#: sql_help.c:4410 sql_help.c:4467 sql_help.c:4506 sql_help.c:4657 +#: sql_help.c:4659 sql_help.c:4716 sql_help.c:4750 sql_help.c:4803 +#: sql_help.c:4889 sql_help.c:4891 sql_help.c:4948 +msgid "table_name" +msgstr "table_name" + +#: sql_help.c:815 sql_help.c:2517 +msgid "using_expression" +msgstr "using_expression" + +#: sql_help.c:816 sql_help.c:2518 +msgid "check_expression" +msgstr "check_expression" + +#: sql_help.c:890 sql_help.c:2561 +msgid "publication_parameter" +msgstr "publication_parameter" + +#: sql_help.c:934 sql_help.c:1605 sql_help.c:2377 sql_help.c:2593 +#: sql_help.c:3152 +msgid "password" +msgstr "password" + +#: sql_help.c:935 sql_help.c:1606 sql_help.c:2378 sql_help.c:2594 +#: sql_help.c:3153 +msgid "timestamp" +msgstr "timestamp" + +#: sql_help.c:939 sql_help.c:943 sql_help.c:946 sql_help.c:949 sql_help.c:1610 +#: sql_help.c:1614 sql_help.c:1617 sql_help.c:1620 sql_help.c:3811 +#: sql_help.c:4191 +msgid "database_name" +msgstr "database_name" + +#: sql_help.c:1053 sql_help.c:2663 +msgid "increment" +msgstr "increment" + +#: sql_help.c:1054 sql_help.c:2664 +msgid "minvalue" +msgstr "minvalue" + +#: sql_help.c:1055 sql_help.c:2665 +msgid "maxvalue" +msgstr "maxvalue" + +#: sql_help.c:1056 sql_help.c:2666 sql_help.c:4406 sql_help.c:4504 +#: sql_help.c:4655 sql_help.c:4820 sql_help.c:4887 +msgid "start" +msgstr "start" + +#: sql_help.c:1057 sql_help.c:1318 +msgid "restart" +msgstr "restart" + +#: sql_help.c:1058 sql_help.c:2667 +msgid "cache" +msgstr "cache" + +#: sql_help.c:1102 +msgid "new_target" +msgstr "new_target" + +#: sql_help.c:1120 sql_help.c:2720 +msgid "conninfo" +msgstr "conninfo" + +#: sql_help.c:1122 sql_help.c:1126 sql_help.c:1130 sql_help.c:2721 +msgid "publication_name" +msgstr "publication_name" + +#: sql_help.c:1123 sql_help.c:1127 sql_help.c:1131 +msgid "set_publication_option" +msgstr "set_publication_option" + +#: sql_help.c:1134 +msgid "refresh_option" +msgstr "refresh_option" + +#: sql_help.c:1139 sql_help.c:2722 +msgid "subscription_parameter" +msgstr "subscription_parameter" + +#: sql_help.c:1295 sql_help.c:1298 +msgid "partition_name" +msgstr "partition_name" + +#: sql_help.c:1296 sql_help.c:2290 sql_help.c:2849 +msgid "partition_bound_spec" +msgstr "partition_bound_spec" + +#: sql_help.c:1315 sql_help.c:1364 sql_help.c:2863 +msgid "sequence_options" +msgstr "sequence_options" + +#: sql_help.c:1317 +msgid "sequence_option" +msgstr "sequence_option" + +#: sql_help.c:1331 +msgid "table_constraint_using_index" +msgstr "table_constraint_using_index" + +#: sql_help.c:1339 sql_help.c:1340 sql_help.c:1341 sql_help.c:1342 +msgid "rewrite_rule_name" +msgstr "rewrite_rule_name" + +#: sql_help.c:1353 sql_help.c:2888 +msgid "and partition_bound_spec is:" +msgstr "και partition_bound_spec είναι:" + +#: sql_help.c:1354 sql_help.c:1355 sql_help.c:1356 sql_help.c:2889 +#: sql_help.c:2890 sql_help.c:2891 +msgid "partition_bound_expr" +msgstr "partition_bound_expr" + +#: sql_help.c:1357 sql_help.c:1358 sql_help.c:2892 sql_help.c:2893 +msgid "numeric_literal" +msgstr "numeric_literal" + +#: sql_help.c:1359 +msgid "and column_constraint is:" +msgstr "και column_constraint είναι:" + +#: sql_help.c:1362 sql_help.c:2297 sql_help.c:2331 sql_help.c:2539 +#: sql_help.c:2861 +msgid "default_expr" +msgstr "default_expr" + +#: sql_help.c:1363 sql_help.c:2298 sql_help.c:2862 +msgid "generation_expr" +msgstr "generation_expr" + +#: sql_help.c:1365 sql_help.c:1366 sql_help.c:1376 sql_help.c:1378 +#: sql_help.c:1382 sql_help.c:2864 sql_help.c:2865 sql_help.c:2874 +#: sql_help.c:2876 sql_help.c:2880 +msgid "index_parameters" +msgstr "index_parameters" + +#: sql_help.c:1368 sql_help.c:1385 sql_help.c:2866 sql_help.c:2883 +msgid "reftable" +msgstr "reftable" + +#: sql_help.c:1369 sql_help.c:1386 sql_help.c:2867 sql_help.c:2884 +msgid "refcolumn" +msgstr "refcolumn" + +#: sql_help.c:1370 sql_help.c:1371 sql_help.c:1387 sql_help.c:1388 +#: sql_help.c:2868 sql_help.c:2869 sql_help.c:2885 sql_help.c:2886 +msgid "referential_action" +msgstr "referential_action" + +#: sql_help.c:1372 sql_help.c:2299 sql_help.c:2870 +msgid "and table_constraint is:" +msgstr "και table_constraint είναι:" + +#: sql_help.c:1380 sql_help.c:2878 +msgid "exclude_element" +msgstr "exclude_element" + +#: sql_help.c:1381 sql_help.c:2879 sql_help.c:4404 sql_help.c:4502 +#: sql_help.c:4653 sql_help.c:4818 sql_help.c:4885 +msgid "operator" +msgstr "operator" + +#: sql_help.c:1383 sql_help.c:2410 sql_help.c:2881 +msgid "predicate" +msgstr "predicate" + +#: sql_help.c:1389 +msgid "and table_constraint_using_index is:" +msgstr "και table_constraint_using_index είναι:" + +#: sql_help.c:1392 sql_help.c:2894 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "index_parameters για περιορισμούς UNIQUE, PRIMARY KEY και EXCLUDE είναι:" + +#: sql_help.c:1397 sql_help.c:2899 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "exclude_element σε έναν περιορισμό τύπου EXCLUDE είναι:" + +#: sql_help.c:1400 sql_help.c:2403 sql_help.c:2826 sql_help.c:2839 +#: sql_help.c:2853 sql_help.c:2902 sql_help.c:3907 +msgid "opclass" +msgstr "opclass" + +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:2937 +msgid "tablespace_option" +msgstr "tablespace_option" + +#: sql_help.c:1440 sql_help.c:1443 sql_help.c:1449 sql_help.c:1453 +msgid "token_type" +msgstr "token_type" + +#: sql_help.c:1441 sql_help.c:1444 +msgid "dictionary_name" +msgstr "dictionary_name" + +#: sql_help.c:1446 sql_help.c:1450 +msgid "old_dictionary" +msgstr "old_dictionary" + +#: sql_help.c:1447 sql_help.c:1451 +msgid "new_dictionary" +msgstr "new_dictionary" + +#: sql_help.c:1546 sql_help.c:1560 sql_help.c:1563 sql_help.c:1564 +#: sql_help.c:3090 +msgid "attribute_name" +msgstr "attribute_name" + +#: sql_help.c:1547 +msgid "new_attribute_name" +msgstr "new_attribute_name" + +#: sql_help.c:1551 sql_help.c:1555 +msgid "new_enum_value" +msgstr "new_enum_value" + +#: sql_help.c:1552 +msgid "neighbor_enum_value" +msgstr "neighbor_enum_value" + +#: sql_help.c:1554 +msgid "existing_enum_value" +msgstr "existing_enum_value" + +#: sql_help.c:1557 +msgid "property" +msgstr "property" + +#: sql_help.c:1633 sql_help.c:2282 sql_help.c:2291 sql_help.c:2679 +#: sql_help.c:3170 sql_help.c:3621 sql_help.c:3820 sql_help.c:3863 +#: sql_help.c:4200 +msgid "server_name" +msgstr "server_name" + +#: sql_help.c:1665 sql_help.c:1668 sql_help.c:3185 +msgid "view_option_name" +msgstr "view_option_name" + +#: sql_help.c:1666 sql_help.c:3186 +msgid "view_option_value" +msgstr "view_option_value" + +#: sql_help.c:1687 sql_help.c:1688 sql_help.c:4789 sql_help.c:4790 +msgid "table_and_columns" +msgstr "table_and_columns" + +#: sql_help.c:1689 sql_help.c:1752 sql_help.c:1943 sql_help.c:3669 +#: sql_help.c:4042 sql_help.c:4791 +msgid "where option can be one of:" +msgstr "όπου option μπορεί να είναι ένα από:" + +#: sql_help.c:1690 sql_help.c:1691 sql_help.c:1753 sql_help.c:1945 +#: sql_help.c:1948 sql_help.c:2127 sql_help.c:3670 sql_help.c:3671 +#: sql_help.c:3672 sql_help.c:3673 sql_help.c:3674 sql_help.c:3675 +#: sql_help.c:3676 sql_help.c:3677 sql_help.c:4043 sql_help.c:4045 +#: sql_help.c:4792 sql_help.c:4793 sql_help.c:4794 sql_help.c:4795 +#: sql_help.c:4796 sql_help.c:4797 sql_help.c:4798 sql_help.c:4799 +#: sql_help.c:4800 +msgid "boolean" +msgstr "boolean" + +#: sql_help.c:1692 sql_help.c:4802 +msgid "and table_and_columns is:" +msgstr "και table_and_columns είναι:" + +#: sql_help.c:1708 sql_help.c:4562 sql_help.c:4564 sql_help.c:4588 +msgid "transaction_mode" +msgstr "transaction_mode" + +#: sql_help.c:1709 sql_help.c:4565 sql_help.c:4589 +msgid "where transaction_mode is one of:" +msgstr "όπου transaction_mode είναι ένα από:" + +#: sql_help.c:1718 sql_help.c:4414 sql_help.c:4423 sql_help.c:4427 +#: sql_help.c:4431 sql_help.c:4434 sql_help.c:4663 sql_help.c:4672 +#: sql_help.c:4676 sql_help.c:4680 sql_help.c:4683 sql_help.c:4895 +#: sql_help.c:4904 sql_help.c:4908 sql_help.c:4912 sql_help.c:4915 +msgid "argument" +msgstr "argument" + +#: sql_help.c:1818 +msgid "relation_name" +msgstr "relation_name" + +#: sql_help.c:1823 sql_help.c:3814 sql_help.c:4194 +msgid "domain_name" +msgstr "domain_name" + +#: sql_help.c:1845 +msgid "policy_name" +msgstr "policy_name" + +#: sql_help.c:1858 +msgid "rule_name" +msgstr "rule_name" + +#: sql_help.c:1877 +msgid "text" +msgstr "text" + +#: sql_help.c:1902 sql_help.c:4007 sql_help.c:4244 +msgid "transaction_id" +msgstr "transaction_id" + +#: sql_help.c:1933 sql_help.c:1940 sql_help.c:3933 +msgid "filename" +msgstr "filename" + +#: sql_help.c:1934 sql_help.c:1941 sql_help.c:2618 sql_help.c:2619 +#: sql_help.c:2620 +msgid "command" +msgstr "command" + +#: sql_help.c:1936 sql_help.c:2617 sql_help.c:3040 sql_help.c:3221 +#: sql_help.c:3917 sql_help.c:4397 sql_help.c:4399 sql_help.c:4495 +#: sql_help.c:4497 sql_help.c:4646 sql_help.c:4648 sql_help.c:4759 +#: sql_help.c:4878 sql_help.c:4880 +msgid "condition" +msgstr "condition" + +#: sql_help.c:1939 sql_help.c:2444 sql_help.c:2923 sql_help.c:3187 +#: sql_help.c:3205 sql_help.c:3898 +msgid "query" +msgstr "query" + +#: sql_help.c:1944 +msgid "format_name" +msgstr "format_name" + +#: sql_help.c:1946 +msgid "delimiter_character" +msgstr "delimiter_character" + +#: sql_help.c:1947 +msgid "null_string" +msgstr "null_string" + +#: sql_help.c:1949 +msgid "quote_character" +msgstr "quote_character" + +#: sql_help.c:1950 +msgid "escape_character" +msgstr "escape_character" + +#: sql_help.c:1954 +msgid "encoding_name" +msgstr "encoding_name" + +#: sql_help.c:1965 +msgid "access_method_type" +msgstr "access_method_type" + +#: sql_help.c:2036 sql_help.c:2055 sql_help.c:2058 +msgid "arg_data_type" +msgstr "arg_data_type" + +#: sql_help.c:2037 sql_help.c:2059 sql_help.c:2067 +msgid "sfunc" +msgstr "sfunc" + +#: sql_help.c:2038 sql_help.c:2060 sql_help.c:2068 +msgid "state_data_type" +msgstr "state_data_type" + +#: sql_help.c:2039 sql_help.c:2061 sql_help.c:2069 +msgid "state_data_size" +msgstr "state_data_size" + +#: sql_help.c:2040 sql_help.c:2062 sql_help.c:2070 +msgid "ffunc" +msgstr "ffunc" + +#: sql_help.c:2041 sql_help.c:2071 +msgid "combinefunc" +msgstr "combinefunc" + +#: sql_help.c:2042 sql_help.c:2072 +msgid "serialfunc" +msgstr "serialfunc" + +#: sql_help.c:2043 sql_help.c:2073 +msgid "deserialfunc" +msgstr "deserialfunc" + +#: sql_help.c:2044 sql_help.c:2063 sql_help.c:2074 +msgid "initial_condition" +msgstr "initial_condition" + +#: sql_help.c:2045 sql_help.c:2075 +msgid "msfunc" +msgstr "msfunc" + +#: sql_help.c:2046 sql_help.c:2076 +msgid "minvfunc" +msgstr "minvfunc" + +#: sql_help.c:2047 sql_help.c:2077 +msgid "mstate_data_type" +msgstr "mstate_data_type" + +#: sql_help.c:2048 sql_help.c:2078 +msgid "mstate_data_size" +msgstr "mstate_data_size" + +#: sql_help.c:2049 sql_help.c:2079 +msgid "mffunc" +msgstr "mffunc" + +#: sql_help.c:2050 sql_help.c:2080 +msgid "minitial_condition" +msgstr "minitial_condition" + +#: sql_help.c:2051 sql_help.c:2081 +msgid "sort_operator" +msgstr "sort_operator" + +#: sql_help.c:2064 +msgid "or the old syntax" +msgstr "ή την παλαιά σύνταξη" + +#: sql_help.c:2066 +msgid "base_type" +msgstr "base_type" + +#: sql_help.c:2123 sql_help.c:2164 +msgid "locale" +msgstr "locale" + +#: sql_help.c:2124 sql_help.c:2165 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2125 sql_help.c:2166 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2126 sql_help.c:4297 +msgid "provider" +msgstr "provider" + +#: sql_help.c:2128 sql_help.c:2220 +msgid "version" +msgstr "version" + +#: sql_help.c:2130 +msgid "existing_collation" +msgstr "existing_collation" + +#: sql_help.c:2140 +msgid "source_encoding" +msgstr "source_encoding" + +#: sql_help.c:2141 +msgid "dest_encoding" +msgstr "dest_encoding" + +#: sql_help.c:2162 sql_help.c:2963 +msgid "template" +msgstr "template" + +#: sql_help.c:2163 +msgid "encoding" +msgstr "dest_encoding" + +#: sql_help.c:2190 +msgid "constraint" +msgstr "constraint" + +#: sql_help.c:2191 +msgid "where constraint is:" +msgstr "όπου constraint είναι:" + +#: sql_help.c:2205 sql_help.c:2615 sql_help.c:3036 +msgid "event" +msgstr "event" + +#: sql_help.c:2206 +msgid "filter_variable" +msgstr "filter_variable" + +#: sql_help.c:2294 sql_help.c:2858 +msgid "where column_constraint is:" +msgstr "όπου column_constraint είναι:" + +#: sql_help.c:2332 +msgid "rettype" +msgstr "rettype" + +#: sql_help.c:2334 +msgid "column_type" +msgstr "column_type" + +#: sql_help.c:2343 sql_help.c:2545 +msgid "definition" +msgstr "definition" + +#: sql_help.c:2344 sql_help.c:2546 +msgid "obj_file" +msgstr "obj_file" + +#: sql_help.c:2345 sql_help.c:2547 +msgid "link_symbol" +msgstr "link_symbol" + +#: sql_help.c:2346 sql_help.c:2548 +msgid "sql_body" +msgstr "" + +#: sql_help.c:2384 sql_help.c:2600 sql_help.c:3159 +msgid "uid" +msgstr "uid" + +#: sql_help.c:2399 sql_help.c:2440 sql_help.c:2827 sql_help.c:2840 +#: sql_help.c:2854 sql_help.c:2919 +msgid "method" +msgstr "method" + +#: sql_help.c:2404 +msgid "opclass_parameter" +msgstr "opclass_parameter" + +#: sql_help.c:2421 +msgid "call_handler" +msgstr "call_handler" + +#: sql_help.c:2422 +msgid "inline_handler" +msgstr "inline_handler" + +#: sql_help.c:2423 +msgid "valfunction" +msgstr "valfunction" + +#: sql_help.c:2462 +msgid "com_op" +msgstr "com_op" + +#: sql_help.c:2463 +msgid "neg_op" +msgstr "neg_op" + +#: sql_help.c:2481 +msgid "family_name" +msgstr "family_name" + +#: sql_help.c:2492 +msgid "storage_type" +msgstr "storage_type" + +#: sql_help.c:2621 sql_help.c:3043 +msgid "where event can be one of:" +msgstr "όπου event μπορεί να είναι ένα από:" + +#: sql_help.c:2641 sql_help.c:2643 +msgid "schema_element" +msgstr "schema_element" + +#: sql_help.c:2680 +msgid "server_type" +msgstr "server_type" + +#: sql_help.c:2681 +msgid "server_version" +msgstr "server_version" + +#: sql_help.c:2682 sql_help.c:3817 sql_help.c:4197 +msgid "fdw_name" +msgstr "fdw_name" + +#: sql_help.c:2699 sql_help.c:2702 +msgid "statistics_name" +msgstr "statistics_name" + +#: sql_help.c:2703 +msgid "statistics_kind" +msgstr "statistics_kind" + +#: sql_help.c:2719 +msgid "subscription_name" +msgstr "subscription_name" + +#: sql_help.c:2820 +msgid "source_table" +msgstr "source_table" + +#: sql_help.c:2821 +msgid "like_option" +msgstr "like_option" + +#: sql_help.c:2887 +msgid "and like_option is:" +msgstr "και like_option είναι:" + +#: sql_help.c:2936 +msgid "directory" +msgstr "directory" + +#: sql_help.c:2950 +msgid "parser_name" +msgstr "parser_name" + +#: sql_help.c:2951 +msgid "source_config" +msgstr "source_config" + +#: sql_help.c:2980 +msgid "start_function" +msgstr "start_function" + +#: sql_help.c:2981 +msgid "gettoken_function" +msgstr "gettoken_function" + +#: sql_help.c:2982 +msgid "end_function" +msgstr "end_function" + +#: sql_help.c:2983 +msgid "lextypes_function" +msgstr "lextypes_function" + +#: sql_help.c:2984 +msgid "headline_function" +msgstr "headline_function" + +#: sql_help.c:2996 +msgid "init_function" +msgstr "init_function" + +#: sql_help.c:2997 +msgid "lexize_function" +msgstr "lexize_function" + +#: sql_help.c:3010 +msgid "from_sql_function_name" +msgstr "from_sql_function_name" + +#: sql_help.c:3012 +msgid "to_sql_function_name" +msgstr "to_sql_function_name" + +#: sql_help.c:3038 +msgid "referenced_table_name" +msgstr "referenced_table_name" + +#: sql_help.c:3039 +msgid "transition_relation_name" +msgstr "transition_relation_name" + +#: sql_help.c:3042 +msgid "arguments" +msgstr "arguments" + +#: sql_help.c:3094 sql_help.c:4330 +msgid "label" +msgstr "label" + +#: sql_help.c:3096 +msgid "subtype" +msgstr "subtype" + +#: sql_help.c:3097 +msgid "subtype_operator_class" +msgstr "subtype_operator_class" + +#: sql_help.c:3099 +msgid "canonical_function" +msgstr "canonical_function" + +#: sql_help.c:3100 +msgid "subtype_diff_function" +msgstr "subtype_diff_function" + +#: sql_help.c:3101 +#, fuzzy +#| msgid "storage_type" +msgid "multirange_type_name" +msgstr "storage_type" + +#: sql_help.c:3103 +msgid "input_function" +msgstr "input_function" + +#: sql_help.c:3104 +msgid "output_function" +msgstr "output_function" + +#: sql_help.c:3105 +msgid "receive_function" +msgstr "receive_function" + +#: sql_help.c:3106 +msgid "send_function" +msgstr "send_function" + +#: sql_help.c:3107 +msgid "type_modifier_input_function" +msgstr "type_modifier_input_function" + +#: sql_help.c:3108 +msgid "type_modifier_output_function" +msgstr "type_modifier_output_function" + +#: sql_help.c:3109 +msgid "analyze_function" +msgstr "analyze_function" + +#: sql_help.c:3110 +#, fuzzy +#| msgid "support_function" +msgid "subscript_function" +msgstr "support_function" + +#: sql_help.c:3111 +msgid "internallength" +msgstr "internallength" + +#: sql_help.c:3112 +msgid "alignment" +msgstr "alignment" + +#: sql_help.c:3113 +msgid "storage" +msgstr "storage" + +#: sql_help.c:3114 +msgid "like_type" +msgstr "like_type" + +#: sql_help.c:3115 +msgid "category" +msgstr "category" + +#: sql_help.c:3116 +msgid "preferred" +msgstr "preferred" + +#: sql_help.c:3117 +msgid "default" +msgstr "default" + +#: sql_help.c:3118 +msgid "element" +msgstr "element" + +#: sql_help.c:3119 +msgid "delimiter" +msgstr "delimiter" + +#: sql_help.c:3120 +msgid "collatable" +msgstr "collatable" + +#: sql_help.c:3217 sql_help.c:3893 sql_help.c:4392 sql_help.c:4489 +#: sql_help.c:4641 sql_help.c:4749 sql_help.c:4873 +msgid "with_query" +msgstr "with_query" + +#: sql_help.c:3219 sql_help.c:3895 sql_help.c:4411 sql_help.c:4417 +#: sql_help.c:4420 sql_help.c:4424 sql_help.c:4428 sql_help.c:4436 +#: sql_help.c:4660 sql_help.c:4666 sql_help.c:4669 sql_help.c:4673 +#: sql_help.c:4677 sql_help.c:4685 sql_help.c:4751 sql_help.c:4892 +#: sql_help.c:4898 sql_help.c:4901 sql_help.c:4905 sql_help.c:4909 +#: sql_help.c:4917 +msgid "alias" +msgstr "alias" + +#: sql_help.c:3220 sql_help.c:4396 sql_help.c:4438 sql_help.c:4440 +#: sql_help.c:4494 sql_help.c:4645 sql_help.c:4687 sql_help.c:4689 +#: sql_help.c:4758 sql_help.c:4877 sql_help.c:4919 sql_help.c:4921 +msgid "from_item" +msgstr "from_item" + +#: sql_help.c:3222 sql_help.c:3703 sql_help.c:3974 sql_help.c:4760 +msgid "cursor_name" +msgstr "cursor_name" + +#: sql_help.c:3223 sql_help.c:3901 sql_help.c:4761 +msgid "output_expression" +msgstr "output_expression" + +#: sql_help.c:3224 sql_help.c:3902 sql_help.c:4395 sql_help.c:4492 +#: sql_help.c:4644 sql_help.c:4762 sql_help.c:4876 +msgid "output_name" +msgstr "output_name" + +#: sql_help.c:3240 +msgid "code" +msgstr "code" + +#: sql_help.c:3645 +msgid "parameter" +msgstr "parameter" + +#: sql_help.c:3667 sql_help.c:3668 sql_help.c:3999 +msgid "statement" +msgstr "statement" + +#: sql_help.c:3702 sql_help.c:3973 +msgid "direction" +msgstr "direction" + +#: sql_help.c:3704 sql_help.c:3975 +msgid "where direction can be empty or one of:" +msgstr "όπου direction μπορεί να είναι άδειο ή ένα από:" + +#: sql_help.c:3705 sql_help.c:3706 sql_help.c:3707 sql_help.c:3708 +#: sql_help.c:3709 sql_help.c:3976 sql_help.c:3977 sql_help.c:3978 +#: sql_help.c:3979 sql_help.c:3980 sql_help.c:4405 sql_help.c:4407 +#: sql_help.c:4503 sql_help.c:4505 sql_help.c:4654 sql_help.c:4656 +#: sql_help.c:4819 sql_help.c:4821 sql_help.c:4886 sql_help.c:4888 +msgid "count" +msgstr "count" + +#: sql_help.c:3807 sql_help.c:4187 +msgid "sequence_name" +msgstr "sequence_name" + +#: sql_help.c:3825 sql_help.c:4205 +msgid "arg_name" +msgstr "arg_name" + +#: sql_help.c:3826 sql_help.c:4206 +msgid "arg_type" +msgstr "arg_type" + +#: sql_help.c:3833 sql_help.c:4213 +msgid "loid" +msgstr "loid" + +#: sql_help.c:3861 +msgid "remote_schema" +msgstr "remote_schema" + +#: sql_help.c:3864 +msgid "local_schema" +msgstr "local_schema" + +#: sql_help.c:3899 +msgid "conflict_target" +msgstr "conflict_target" + +#: sql_help.c:3900 +msgid "conflict_action" +msgstr "conflict_action" + +#: sql_help.c:3903 +msgid "where conflict_target can be one of:" +msgstr "όπου conflict_target μπορεί να είναι ένα από:" + +#: sql_help.c:3904 +msgid "index_column_name" +msgstr "index_column_name" + +#: sql_help.c:3905 +msgid "index_expression" +msgstr "index_expression" + +#: sql_help.c:3908 +msgid "index_predicate" +msgstr "index_predicate" + +#: sql_help.c:3910 +msgid "and conflict_action is one of:" +msgstr "και conflict_action είναι ένα από:" + +#: sql_help.c:3916 sql_help.c:4757 +msgid "sub-SELECT" +msgstr "sub-SELECT" + +#: sql_help.c:3925 sql_help.c:3988 sql_help.c:4733 +msgid "channel" +msgstr "channel" + +#: sql_help.c:3947 +msgid "lockmode" +msgstr "lockmode" + +#: sql_help.c:3948 +msgid "where lockmode is one of:" +msgstr "όπου lockmode είναι ένα από:" + +#: sql_help.c:3989 +msgid "payload" +msgstr "payload" + +#: sql_help.c:4016 +msgid "old_role" +msgstr "old_role" + +#: sql_help.c:4017 +msgid "new_role" +msgstr "new_role" + +#: sql_help.c:4053 sql_help.c:4252 sql_help.c:4260 +msgid "savepoint_name" +msgstr "savepoint_name" + +#: sql_help.c:4398 sql_help.c:4451 sql_help.c:4647 sql_help.c:4700 +#: sql_help.c:4879 sql_help.c:4932 +msgid "grouping_element" +msgstr "grouping_element" + +#: sql_help.c:4400 sql_help.c:4498 sql_help.c:4649 sql_help.c:4881 +msgid "window_name" +msgstr "window_name" + +#: sql_help.c:4401 sql_help.c:4499 sql_help.c:4650 sql_help.c:4882 +msgid "window_definition" +msgstr "window_definition" + +#: sql_help.c:4402 sql_help.c:4416 sql_help.c:4455 sql_help.c:4500 +#: sql_help.c:4651 sql_help.c:4665 sql_help.c:4704 sql_help.c:4883 +#: sql_help.c:4897 sql_help.c:4936 +msgid "select" +msgstr "select" + +#: sql_help.c:4409 sql_help.c:4658 sql_help.c:4890 +msgid "where from_item can be one of:" +msgstr "όπου from_item μπορεί να είναι ένα από:" + +#: sql_help.c:4412 sql_help.c:4418 sql_help.c:4421 sql_help.c:4425 +#: sql_help.c:4437 sql_help.c:4661 sql_help.c:4667 sql_help.c:4670 +#: sql_help.c:4674 sql_help.c:4686 sql_help.c:4893 sql_help.c:4899 +#: sql_help.c:4902 sql_help.c:4906 sql_help.c:4918 +msgid "column_alias" +msgstr "column_alias" + +#: sql_help.c:4413 sql_help.c:4662 sql_help.c:4894 +msgid "sampling_method" +msgstr "sampling_method" + +#: sql_help.c:4415 sql_help.c:4664 sql_help.c:4896 +msgid "seed" +msgstr "seed" + +#: sql_help.c:4419 sql_help.c:4453 sql_help.c:4668 sql_help.c:4702 +#: sql_help.c:4900 sql_help.c:4934 +msgid "with_query_name" +msgstr "with_query_name" + +#: sql_help.c:4429 sql_help.c:4432 sql_help.c:4435 sql_help.c:4678 +#: sql_help.c:4681 sql_help.c:4684 sql_help.c:4910 sql_help.c:4913 +#: sql_help.c:4916 +msgid "column_definition" +msgstr "column_definition" + +#: sql_help.c:4439 sql_help.c:4688 sql_help.c:4920 +msgid "join_type" +msgstr "join_type" + +#: sql_help.c:4441 sql_help.c:4690 sql_help.c:4922 +msgid "join_condition" +msgstr "join_condition" + +#: sql_help.c:4442 sql_help.c:4691 sql_help.c:4923 +msgid "join_column" +msgstr "join_column" + +#: sql_help.c:4443 sql_help.c:4692 sql_help.c:4924 +#, fuzzy +#| msgid "column_alias" +msgid "join_using_alias" +msgstr "column_alias" + +#: sql_help.c:4444 sql_help.c:4693 sql_help.c:4925 +msgid "and grouping_element can be one of:" +msgstr "και grouping_element μπορεί να είναι ένα από:" + +#: sql_help.c:4452 sql_help.c:4701 sql_help.c:4933 +msgid "and with_query is:" +msgstr "και with_query είναι:" + +#: sql_help.c:4456 sql_help.c:4705 sql_help.c:4937 +msgid "values" +msgstr "values" + +#: sql_help.c:4457 sql_help.c:4706 sql_help.c:4938 +msgid "insert" +msgstr "insert" + +#: sql_help.c:4458 sql_help.c:4707 sql_help.c:4939 +msgid "update" +msgstr "update" + +#: sql_help.c:4459 sql_help.c:4708 sql_help.c:4940 +msgid "delete" +msgstr "delete" + +#: sql_help.c:4461 sql_help.c:4710 sql_help.c:4942 +#, fuzzy +#| msgid "schema_name" +msgid "search_seq_col_name" +msgstr "schema_name" + +#: sql_help.c:4463 sql_help.c:4712 sql_help.c:4944 +#, fuzzy +#| msgid "schema_name" +msgid "cycle_mark_col_name" +msgstr "schema_name" + +#: sql_help.c:4464 sql_help.c:4713 sql_help.c:4945 +#, fuzzy +#| msgid "new_enum_value" +msgid "cycle_mark_value" +msgstr "new_enum_value" + +#: sql_help.c:4465 sql_help.c:4714 sql_help.c:4946 +msgid "cycle_mark_default" +msgstr "" + +#: sql_help.c:4466 sql_help.c:4715 sql_help.c:4947 +msgid "cycle_path_col_name" +msgstr "" + +#: sql_help.c:4493 +msgid "new_table" +msgstr "new_table" + +#: sql_help.c:4518 +msgid "timezone" +msgstr "timezone" + +#: sql_help.c:4563 +msgid "snapshot_id" +msgstr "snapshot_id" + +#: sql_help.c:4817 +msgid "sort_expression" +msgstr "sort_expression" + +#: sql_help.c:4954 sql_help.c:5932 +msgid "abort the current transaction" +msgstr "ματαιώστε την τρέχουσα συναλλαγή" + +#: sql_help.c:4960 +msgid "change the definition of an aggregate function" +msgstr "αλλάξτε τον ορισμό μιας συνάρτησης συγκεντρωτικών αποτελεσμάτων" + +#: sql_help.c:4966 +msgid "change the definition of a collation" +msgstr "αλλάξτε τον ορισμό συρραφής" + +#: sql_help.c:4972 +msgid "change the definition of a conversion" +msgstr "αλλάξτε τον ορισμό μίας μετατροπής" + +#: sql_help.c:4978 +msgid "change a database" +msgstr "αλλάξτε μία βάση δεδομένων" + +#: sql_help.c:4984 +msgid "define default access privileges" +msgstr "ορίσθε τα προεπιλεγμένα δικαιώματα πρόσβασης" + +#: sql_help.c:4990 +msgid "change the definition of a domain" +msgstr "αλλάξτε τον ορισμό ενός τομέα" + +#: sql_help.c:4996 +msgid "change the definition of an event trigger" +msgstr "αλλάξτε τον ορισμό μιας ενεργοποίησης συμβάντος" + +#: sql_help.c:5002 +msgid "change the definition of an extension" +msgstr "αλλάξτε τον ορισμό μίας προέκτασης" + +#: sql_help.c:5008 +msgid "change the definition of a foreign-data wrapper" +msgstr "αλλάξτε τον ορισιμό μιας περιτύλιξης ξένων δεδομένων" + +#: sql_help.c:5014 +msgid "change the definition of a foreign table" +msgstr "αλλάξτε τον ορισιμό ενός ξενικού πίνακα" + +#: sql_help.c:5020 +msgid "change the definition of a function" +msgstr "αλλάξτε τον ορισμό μιας συνάρτησης" + +#: sql_help.c:5026 +msgid "change role name or membership" +msgstr "αλλάξτε το όνομα ρόλου ή ιδιότητας μέλους" + +#: sql_help.c:5032 +msgid "change the definition of an index" +msgstr "αλλάξτε τον ορισμό ενός ευρετηρίου" + +#: sql_help.c:5038 +msgid "change the definition of a procedural language" +msgstr "αλλάξτε τον ορισμό μιας διαδικαστικής γλώσσας" + +#: sql_help.c:5044 +msgid "change the definition of a large object" +msgstr "αλλάξτε τον ορισιμό ενός μεγάλου αντικειμένου" + +#: sql_help.c:5050 +msgid "change the definition of a materialized view" +msgstr "αλλάξτε τον ορισμό μίας υλοποιημένης όψης" + +#: sql_help.c:5056 +msgid "change the definition of an operator" +msgstr "αλλάξτε τον ορισμό ενός χειριστή" + +#: sql_help.c:5062 +msgid "change the definition of an operator class" +msgstr "αλλάξτε τον ορισμό μίας κλάσης χειριστή" + +#: sql_help.c:5068 +msgid "change the definition of an operator family" +msgstr "αλλάξτε τον ορισμό μίας οικογένειας χειριστή" + +#: sql_help.c:5074 +#, fuzzy +#| msgid "change the definition of a row level security policy" +msgid "change the definition of a row-level security policy" +msgstr "αλλάξτε τον ορισιμό μιας πολιτική ασφάλειας επιπέδου σειράς" + +#: sql_help.c:5080 +msgid "change the definition of a procedure" +msgstr "αλλάξτε τον ορισμό μίας διαδικασίας" + +#: sql_help.c:5086 +msgid "change the definition of a publication" +msgstr "αλλάξτε τον ορισμό μίας δημοσίευσης" + +#: sql_help.c:5092 sql_help.c:5194 +msgid "change a database role" +msgstr "αλλάξτε τον ρόλο μίας βάσης δεδομένων" + +#: sql_help.c:5098 +msgid "change the definition of a routine" +msgstr "αλλάξτε τον ορισμό μιας ρουτίνας" + +#: sql_help.c:5104 +msgid "change the definition of a rule" +msgstr "αλλάξτε τον ορισμό ενός κανόνα" + +#: sql_help.c:5110 +msgid "change the definition of a schema" +msgstr "αλλάξτε τον ορισμό ενός σχήματος" + +#: sql_help.c:5116 +msgid "change the definition of a sequence generator" +msgstr "αλλάξτε τον ορισμό μίας γεννήτριας ακολουθίας" + +#: sql_help.c:5122 +msgid "change the definition of a foreign server" +msgstr "αλλάξτε τον ορισμό ενός ξενικού διακομιστή" + +#: sql_help.c:5128 +msgid "change the definition of an extended statistics object" +msgstr "αλλάξτε τον ορισμό ενός εκτεταμένου αντικειμένου στατιστικών" + +#: sql_help.c:5134 +msgid "change the definition of a subscription" +msgstr "αλλάξτε τον ορισμό μιας συνδρομής" + +#: sql_help.c:5140 +msgid "change a server configuration parameter" +msgstr "αλλάξτε μία παράμετρο διαμόρφωσης διακομιστή" + +#: sql_help.c:5146 +msgid "change the definition of a table" +msgstr "αλλάξτε τον ορισμό ενός πίνακα" + +#: sql_help.c:5152 +msgid "change the definition of a tablespace" +msgstr "αλλάξτε τον ορισμό ενός πινακοχώρου" + +#: sql_help.c:5158 +msgid "change the definition of a text search configuration" +msgstr "αλλάξτε τον ορισμό μίας διαμόρφωσης αναζήτησης κειμένου" + +#: sql_help.c:5164 +msgid "change the definition of a text search dictionary" +msgstr "αλλάξτε τον ορισμό ενός λεξικού αναζήτησης κειμένου" + +#: sql_help.c:5170 +msgid "change the definition of a text search parser" +msgstr "αλλάξτε τον ορισμό ενός αναλυτή αναζήτησης κειμένου" + +#: sql_help.c:5176 +msgid "change the definition of a text search template" +msgstr "αλλάξτε τον ορισμό ενός προτύπου αναζήτησης κειμένου" + +#: sql_help.c:5182 +msgid "change the definition of a trigger" +msgstr "αλλάξτε τον ορισμό μιας ενεργοποίησης" + +#: sql_help.c:5188 +msgid "change the definition of a type" +msgstr "αλλάξτε τον ορισμό ενός τύπου" + +#: sql_help.c:5200 +msgid "change the definition of a user mapping" +msgstr "αλλάξτε τον ορισμό μίας αντιστοίχισης χρήστη" + +#: sql_help.c:5206 +msgid "change the definition of a view" +msgstr "αλλάξτε τον ορισμό μίας όψης" + +#: sql_help.c:5212 +msgid "collect statistics about a database" +msgstr "συλλέξτε στατιστικά σχετικά με μία βάση δεδομένων" + +#: sql_help.c:5218 sql_help.c:6010 +msgid "start a transaction block" +msgstr "εκκινήστε ένα μπλοκ συναλλαγής" + +#: sql_help.c:5224 +msgid "invoke a procedure" +msgstr "κλήση διαδικασίας" + +#: sql_help.c:5230 +msgid "force a write-ahead log checkpoint" +msgstr "επιβάλλετε εισαγωγή ενός σημείου ελέγχου (checkpoint) του write-ahead log" + +#: sql_help.c:5236 +msgid "close a cursor" +msgstr "κλείστε έναν δρομέα" + +#: sql_help.c:5242 +msgid "cluster a table according to an index" +msgstr "δημιουργείστε συστάδα ενός πίνακα σύμφωνα με ένα ευρετήριο" + +#: sql_help.c:5248 +msgid "define or change the comment of an object" +msgstr "ορίσετε ή αλλάξτε το σχόλιο ενός αντικειμένου" + +#: sql_help.c:5254 sql_help.c:5812 +msgid "commit the current transaction" +msgstr "ολοκληρώστε την τρέχουσας συναλλαγής" + +#: sql_help.c:5260 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "ολοκληρώστε μία συναλλαγή που είχε προετοιμαστεί νωρίτερα για ολοκλήρωση σε δύο φάσεις" + +#: sql_help.c:5266 +msgid "copy data between a file and a table" +msgstr "αντιγράψτε δεδομένα μεταξύ ενός αρχείου και ενός πίνακα" + +#: sql_help.c:5272 +msgid "define a new access method" +msgstr "ορίσετε μία νέα μέθοδο πρόσβασης" + +#: sql_help.c:5278 +msgid "define a new aggregate function" +msgstr "ορίσετε μία νέα συνάρτηση συγκεντρωτικών αποτελεσμάτων" + +#: sql_help.c:5284 +msgid "define a new cast" +msgstr "ορίσετε ένα νέο καστ" + +#: sql_help.c:5290 +msgid "define a new collation" +msgstr "ορίσετε μία νέα συρραφή" + +#: sql_help.c:5296 +msgid "define a new encoding conversion" +msgstr "ορίσετε μία νέα μετατροπή κωδικοποίησης" + +#: sql_help.c:5302 +msgid "create a new database" +msgstr "δημιουργήστε μία νέα βάση δεδομένων" + +#: sql_help.c:5308 +msgid "define a new domain" +msgstr "ορίσετε ένα νέο πεδίο" + +#: sql_help.c:5314 +msgid "define a new event trigger" +msgstr "ορίσετε μία νέα ενεργοποίησης συμβάντος" + +#: sql_help.c:5320 +msgid "install an extension" +msgstr "εγκαταστήστε μία νέα προέκταση" + +#: sql_help.c:5326 +msgid "define a new foreign-data wrapper" +msgstr "ορίσετε μία νέα περιτύλιξη ξένων δεδομένων" + +#: sql_help.c:5332 +msgid "define a new foreign table" +msgstr "ορίσετε ένα νέο ξενικό πίνακα" + +#: sql_help.c:5338 +msgid "define a new function" +msgstr "ορίσετε μία νέα συνάρτηση" + +#: sql_help.c:5344 sql_help.c:5404 sql_help.c:5506 +msgid "define a new database role" +msgstr "ορίστε έναν νέο ρόλο βάσης δεδομένων" + +#: sql_help.c:5350 +msgid "define a new index" +msgstr "ορίστε ένα νέο ευρετήριο" + +#: sql_help.c:5356 +msgid "define a new procedural language" +msgstr "ορίστε μία νέα διαδικαστική γλώσσα" + +#: sql_help.c:5362 +msgid "define a new materialized view" +msgstr "Ορίστε μία νέα υλοποιημένη όψη" + +#: sql_help.c:5368 +msgid "define a new operator" +msgstr "ορίστε έναν νέο χειριστή" + +#: sql_help.c:5374 +msgid "define a new operator class" +msgstr "ορίστε μία νέα κλάση χειριστή" + +#: sql_help.c:5380 +msgid "define a new operator family" +msgstr "ορίστε μία νέα οικογένεια χειριστή" + +#: sql_help.c:5386 +#, fuzzy +#| msgid "define a new row level security policy for a table" +msgid "define a new row-level security policy for a table" +msgstr "ορίστε μία νέα πολιτική προστασίας σειράς για έναν πίνακα" + +#: sql_help.c:5392 +msgid "define a new procedure" +msgstr "ορίστε μία νέα διαδικασία" + +#: sql_help.c:5398 +msgid "define a new publication" +msgstr "ορίστε μία νέα κοινοποιήση" + +#: sql_help.c:5410 +msgid "define a new rewrite rule" +msgstr "ορίστε ένα νέο κανόνα επανεγγραφής" + +#: sql_help.c:5416 +msgid "define a new schema" +msgstr "ορίστε ένα νέο σχήμα" + +#: sql_help.c:5422 +msgid "define a new sequence generator" +msgstr "ορίστε ένα νέο παραγωγό ακολουθίων" + +#: sql_help.c:5428 +msgid "define a new foreign server" +msgstr "ορίστε ένα νέο ξενικό διακομιστή" + +#: sql_help.c:5434 +msgid "define extended statistics" +msgstr "ορίστε εκτεταμένα στατιστικά στοιχεία" + +#: sql_help.c:5440 +msgid "define a new subscription" +msgstr "ορίστε μία νέα συνδρομή" + +#: sql_help.c:5446 +msgid "define a new table" +msgstr "ορίσετε ένα νέο πίνακα" + +#: sql_help.c:5452 sql_help.c:5968 +msgid "define a new table from the results of a query" +msgstr "ορίστε ένα νέο πίνακα από τα αποτελέσματα ενός ερωτήματος" + +#: sql_help.c:5458 +msgid "define a new tablespace" +msgstr "ορίστε ένα νέο πινακοχώρο" + +#: sql_help.c:5464 +msgid "define a new text search configuration" +msgstr "ορίστε μία νέα διαμόρφωση αναζήτησης κειμένου" + +#: sql_help.c:5470 +msgid "define a new text search dictionary" +msgstr "ορίστε ένα νέο λεξικό αναζήτησης κειμένου" + +#: sql_help.c:5476 +msgid "define a new text search parser" +msgstr "ορίστε ένα νέο αναλυτή αναζήτησης κειμένου" + +#: sql_help.c:5482 +msgid "define a new text search template" +msgstr "ορίστε ένα νέο πρότυπο αναζήτησης κειμένου" + +#: sql_help.c:5488 +msgid "define a new transform" +msgstr "ορίστε μία νέα μετατροπή" + +#: sql_help.c:5494 +msgid "define a new trigger" +msgstr "ορίσετε μία νέα ενεργοποίηση" + +#: sql_help.c:5500 +msgid "define a new data type" +msgstr "ορίσετε ένα νέο τύπο δεδομένων" + +#: sql_help.c:5512 +msgid "define a new mapping of a user to a foreign server" +msgstr "ορίστε μία νέα αντιστοίχιση ενός χρήστη σε έναν ξένο διακομιστή" + +#: sql_help.c:5518 +msgid "define a new view" +msgstr "ορίστε μία νέα όψη" + +#: sql_help.c:5524 +msgid "deallocate a prepared statement" +msgstr "καταργήστε μία προετοιμασμένη δήλωση" + +#: sql_help.c:5530 +msgid "define a cursor" +msgstr "ορίστε έναν δρομέα" + +#: sql_help.c:5536 +msgid "delete rows of a table" +msgstr "διαγράψτε σειρές ενός πίνακα" + +#: sql_help.c:5542 +msgid "discard session state" +msgstr "καταργήστε την κατάσταση συνεδρίας" + +#: sql_help.c:5548 +msgid "execute an anonymous code block" +msgstr "εκτελέστε ανώνυμο μπλοκ κώδικα" + +#: sql_help.c:5554 +msgid "remove an access method" +msgstr "αφαιρέστε μία μέθοδο πρόσβασης" + +#: sql_help.c:5560 +msgid "remove an aggregate function" +msgstr "αφαιρέστε μία συνάρτηση συγκεντρωτικών αποτελεσμάτων" + +#: sql_help.c:5566 +msgid "remove a cast" +msgstr "αφαιρέστε ένα καστ" + +#: sql_help.c:5572 +msgid "remove a collation" +msgstr "αφαιρέστε μία συρραφή" + +#: sql_help.c:5578 +msgid "remove a conversion" +msgstr "αφαιρέστε μία μετατροπή" + +#: sql_help.c:5584 +msgid "remove a database" +msgstr "αφαιρέστε μία βάση δεδομένων" + +#: sql_help.c:5590 +msgid "remove a domain" +msgstr "αφαιρέστε ένα πεδίο" + +#: sql_help.c:5596 +msgid "remove an event trigger" +msgstr "αφαιρέστε μία ενεργοποίηση συμβάντος" + +#: sql_help.c:5602 +msgid "remove an extension" +msgstr "αφαιρέστε μία προέκταση" + +#: sql_help.c:5608 +msgid "remove a foreign-data wrapper" +msgstr "αφαιρέστε μία περιτύλιξη ξένων δεδομένων" + +#: sql_help.c:5614 +msgid "remove a foreign table" +msgstr "αφαιρέστε έναν ξενικό πίνακα" + +#: sql_help.c:5620 +msgid "remove a function" +msgstr "αφαιρέστε μία συνάρτηση" + +#: sql_help.c:5626 sql_help.c:5692 sql_help.c:5794 +msgid "remove a database role" +msgstr "αφαιρέστε έναν ρόλο μίας βάσης δεδομένων" + +#: sql_help.c:5632 +msgid "remove an index" +msgstr "αφαιρέστε ένα ευρετήριο" + +#: sql_help.c:5638 +msgid "remove a procedural language" +msgstr "αφαιρέστε μία διαδικαστική γλώσσα" + +#: sql_help.c:5644 +msgid "remove a materialized view" +msgstr "αφαιρέστε μία υλοποιημένη όψη" + +#: sql_help.c:5650 +msgid "remove an operator" +msgstr "αφαιρέστε έναν χειριστή" + +#: sql_help.c:5656 +msgid "remove an operator class" +msgstr "αφαιρέστε μία κλάση χειριστή" + +#: sql_help.c:5662 +msgid "remove an operator family" +msgstr "αφαιρέστε μία οικογένεια χειριστή" + +#: sql_help.c:5668 +msgid "remove database objects owned by a database role" +msgstr "αφαιρέστε αντικειμένα βάσης δεδομένων που ανήκουν σε ρόλο βάσης δεδομένων" + +#: sql_help.c:5674 +#, fuzzy +#| msgid "remove a row level security policy from a table" +msgid "remove a row-level security policy from a table" +msgstr "αφαιρέστε μία πολιτική ασφαλείας επιπέδου γραμμής από έναν πίνακα" + +#: sql_help.c:5680 +msgid "remove a procedure" +msgstr "αφαιρέστε μία διαδικασία" + +#: sql_help.c:5686 +msgid "remove a publication" +msgstr "αφαιρέστε μία δημοσίευση" + +#: sql_help.c:5698 +msgid "remove a routine" +msgstr "αφαιρέστε μία ρουτίνα" + +#: sql_help.c:5704 +msgid "remove a rewrite rule" +msgstr "αφαιρέστε έναν κανόνα επανεγγραφής" + +#: sql_help.c:5710 +msgid "remove a schema" +msgstr "αφαιρέστε ένα σχήμα" + +#: sql_help.c:5716 +msgid "remove a sequence" +msgstr "αφαιρέστε μία ακολουθία" + +#: sql_help.c:5722 +msgid "remove a foreign server descriptor" +msgstr "αφαιρέστε έναν περιγραφέα ξενικού διακομιστή" + +#: sql_help.c:5728 +msgid "remove extended statistics" +msgstr "αφαιρέστε εκτεταμένα στατιστικά στοιχεία" + +#: sql_help.c:5734 +msgid "remove a subscription" +msgstr "αφαιρέστε μία συνδρομή" + +#: sql_help.c:5740 +msgid "remove a table" +msgstr "αφαιρέστε έναν πίνακα" + +#: sql_help.c:5746 +msgid "remove a tablespace" +msgstr "αφαιρέστε έναν πινακοχώρο" + +#: sql_help.c:5752 +msgid "remove a text search configuration" +msgstr "αφαιρέστε μία διαμόρφωση αναζήτησης κειμένου" + +#: sql_help.c:5758 +msgid "remove a text search dictionary" +msgstr "αφαιρέστε ένα λεξικό αναζήτησης κειμένου" + +#: sql_help.c:5764 +msgid "remove a text search parser" +msgstr "αφαιρέστε έναν αναλυτή αναζήτησης κειμένου" + +#: sql_help.c:5770 +msgid "remove a text search template" +msgstr "αφαιρέστε ένα πρότυπο αναζήτησης κειμένου" + +#: sql_help.c:5776 +msgid "remove a transform" +msgstr "αφαιρέστε μία μετατροπή" + +#: sql_help.c:5782 +msgid "remove a trigger" +msgstr "αφαιρέστε μία ενεργοποίηση" + +#: sql_help.c:5788 +msgid "remove a data type" +msgstr "αφαιρέστε έναν τύπο δεδομένων" + +#: sql_help.c:5800 +msgid "remove a user mapping for a foreign server" +msgstr "αφαιρέστε μία αντιστοίχιση χρήστη για ξένο διακομιστή" + +#: sql_help.c:5806 +msgid "remove a view" +msgstr "αφαιρέστε μία όψη" + +#: sql_help.c:5818 +msgid "execute a prepared statement" +msgstr "εκτελέστε μία προεπιλεγμένη δήλωση" + +#: sql_help.c:5824 +msgid "show the execution plan of a statement" +msgstr "εμφανίστε το πλάνο εκτέλεσης μίας δήλωσης" + +#: sql_help.c:5830 +msgid "retrieve rows from a query using a cursor" +msgstr "ανακτήστε σειρές από ερώτημα μέσω δρομέα" + +#: sql_help.c:5836 +msgid "define access privileges" +msgstr "ορίσθε δικαιώματα πρόσβασης" + +#: sql_help.c:5842 +msgid "import table definitions from a foreign server" +msgstr "εισαγωγή ορισμών πίνακα από ξένο διακομιστή" + +#: sql_help.c:5848 +msgid "create new rows in a table" +msgstr "δημιουργήστε καινούργιες σειρές σε έναν πίνακα" + +#: sql_help.c:5854 +msgid "listen for a notification" +msgstr "ακούστε για μία κοινοποίηση" + +#: sql_help.c:5860 +msgid "load a shared library file" +msgstr "φορτώστε ένα αρχείο κοινόχρηστης βιβλιοθήκης" + +#: sql_help.c:5866 +msgid "lock a table" +msgstr "κλειδώστε έναν πίνακα" + +#: sql_help.c:5872 +msgid "position a cursor" +msgstr "τοποθετήστε έναν δρομέα" + +#: sql_help.c:5878 +msgid "generate a notification" +msgstr "δημιουργήστε μία κοινοποίηση" + +#: sql_help.c:5884 +msgid "prepare a statement for execution" +msgstr "προετοιμάστε μία δήλωση για εκτέλεση" + +#: sql_help.c:5890 +msgid "prepare the current transaction for two-phase commit" +msgstr "προετοιμάστε την τρέχουσας συναλλαγής για ολοκλήρωση σε δύο φάσεις" + +#: sql_help.c:5896 +msgid "change the ownership of database objects owned by a database role" +msgstr "αλλάξτε την κυριότητα αντικειμένων βάσης δεδομένων που ανήκουν σε ρόλο βάσης δεδομένων" + +#: sql_help.c:5902 +msgid "replace the contents of a materialized view" +msgstr "αντικαθαστήστε τα περιεχόμενα μίας υλοποιημένης όψης" + +#: sql_help.c:5908 +msgid "rebuild indexes" +msgstr "επανακατασκευάστε ευρετήρια" + +#: sql_help.c:5914 +msgid "destroy a previously defined savepoint" +msgstr "καταστρέψτε ένα προηγούμενα ορισμένο σημείο αποθήκευσης" + +#: sql_help.c:5920 +msgid "restore the value of a run-time parameter to the default value" +msgstr "επαναφορά της τιμής μιας παραμέτρου χρόνου εκτέλεσης στην προεπιλεγμένη τιμή" + +#: sql_help.c:5926 +msgid "remove access privileges" +msgstr "αφαιρέστε δικαιώματα πρόσβασης" + +#: sql_help.c:5938 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "Ακύρωση συναλλαγής που είχε προετοιμαστεί προηγουμένως για ολοκλήρωση σε δύο φάσεις" + +#: sql_help.c:5944 +msgid "roll back to a savepoint" +msgstr "επαναφορά σε σημείο αποθήκευσης" + +#: sql_help.c:5950 +msgid "define a new savepoint within the current transaction" +msgstr "ορίστε ένα νέο σημείο αποθήκευσης (savepoint) μέσα στην τρέχουσα συναλλαγή" + +#: sql_help.c:5956 +msgid "define or change a security label applied to an object" +msgstr "ορίστε ή αλλάξτε μία ετικέτα ασφαλείας που εφαρμόζεται σε ένα αντικείμενο" + +#: sql_help.c:5962 sql_help.c:6016 sql_help.c:6052 +msgid "retrieve rows from a table or view" +msgstr "ανακτήστε σειρές από πίνακα ή όψη" + +#: sql_help.c:5974 +msgid "change a run-time parameter" +msgstr "αλλάξτε μία παράμετρο χρόνου εκτέλεσης" + +#: sql_help.c:5980 +msgid "set constraint check timing for the current transaction" +msgstr "ορίστε τον χρονισμό ελέγχου περιορισμού για την τρέχουσα συναλλαγή" + +#: sql_help.c:5986 +msgid "set the current user identifier of the current session" +msgstr "ορίστε το αναγνωριστικό τρέχοντος χρήστη της τρέχουσας συνεδρίας" + +#: sql_help.c:5992 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "ορίστε το αναγνωριστικό χρήστη συνεδρίας και το αναγνωριστικό τρέχοντος χρήστη της τρέχουσας συνεδρίας" + +#: sql_help.c:5998 +msgid "set the characteristics of the current transaction" +msgstr "ορίστε τα χαρακτηριστικά της τρέχουσας συναλλαγής" + +#: sql_help.c:6004 +msgid "show the value of a run-time parameter" +msgstr "εμφάνιση της τιμής μιας παραμέτρου χρόνου εκτέλεσης" + +#: sql_help.c:6022 +msgid "empty a table or set of tables" +msgstr "αδειάστε έναν πίνακα ή ένα σύνολο πινάκων" + +#: sql_help.c:6028 +msgid "stop listening for a notification" +msgstr "σταματήστε να ακούτε μια κοινοποίηση" + +#: sql_help.c:6034 +msgid "update rows of a table" +msgstr "ενημέρωση σειρών πίνακα" + +#: sql_help.c:6040 +msgid "garbage-collect and optionally analyze a database" +msgstr "συλλογή απορριμμάτων και προαιρετική ανάλυση βάσης δεδομένων" + +#: sql_help.c:6046 +msgid "compute a set of rows" +msgstr "υπολογίστε ένα σύνολο σειρών" + +#: startup.c:213 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 μπορεί να χρησιμοποιηθεί μόνο σε μη διαδραστική λειτουργία" + +#: startup.c:326 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου καταγραφής “%s”: %m" + +#: startup.c:438 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Γράψτε “help” για βοήθεια.\n" +"\n" + +#: startup.c:591 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "δεν ήταν δυνατός ο ορισμός παραμέτρου εκτύπωσης “%s”" + +#: startup.c:699 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Δοκιμάστε “%s —help” για περισσότερες πληροφορίες.\n" + +#: startup.c:716 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "παραβλέπεται η πρόσθετη παράμετρος γραμμής εντολών \"%s\"" + +#: startup.c:765 +#, c-format +msgid "could not find own program executable" +msgstr "δεν ήταν δυνατή η εύρεση του ιδίου εκτελέσιμου προγράμματος" + +#: tab-complete.c:4896 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"ολοκλήρωσης καρτέλας ερωτήματος απέτυχε: %s\n" +"Το ερώτημα ήταν:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "μη αναγνωρίσιμη τιμή \"%s\" για \"%s\": αναμένεται Boolean" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "άκυρη τιμή \"%s\" για \"%s\": αναμένεται ακέραιος" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "άκυρη ονομασία παραμέτρου “%s”" + +#: variables.c:419 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"Μη αναγνωρίσιμη τιμή \"%s\" για \"%s\"\n" +"Οι διαθέσιμες τιμές είναι: %s." + +#~ msgid "All connection parameters must be supplied because no database connection exists" +#~ msgstr "Πρέπει να δωθούν όλες οι παρέμετροι γιατί δεν υπάρχει σύνδεση με τη βάση δεδομένων" + +#~ msgid "pclose failed: %m" +#~ msgstr "απέτυχε η εντολή pclose: %m" diff --git a/src/bin/psql/po/es.po b/src/bin/psql/po/es.po new file mode 100644 index 000000000000..80f5c974d48c --- /dev/null +++ b/src/bin/psql/po/es.po @@ -0,0 +1,6473 @@ +# spanish translation of psql. +# +# Copyright (c) 2003-2019, PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# +# Alvaro Herrera, , 2003-2015 +# Diego A. Gil , 2005 +# Martín Marqués , 2013 +# Carlos Chapi , 2021 +# +msgid "" +msgstr "" +"Project-Id-Version: psql (PostgreSQL) 14\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-11 16:45+0000\n" +"PO-Revision-Date: 2021-06-14 20:11-0500\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: BlackCAT 1.1\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "el binario «%s» no es válido" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "no se pudo leer el binario «%s»" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "no se pudo encontrar un «%s» para ejecutar" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "%s() falló: %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: command.c:1315 command.c:3246 command.c:3295 command.c:3412 input.c:227 +#: mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "no se puede duplicar un puntero nulo (error interno)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "no se pudo buscar el ID de usuario efectivo %ld: %s" + +#: ../../common/username.c:45 command.c:565 +msgid "user does not exist" +msgstr "el usuario no existe" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "fallo en la búsqueda de nombre de usuario: código de error %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "la orden no es ejecutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "orden no encontrada" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "el proceso hijo terminó con código de salida %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "el proceso hijo fue terminado por una excepción 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "el proceso hijo terminó con código no reconocido %d" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Petición de cancelación enviada\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "No se pudo enviar la petición de cancelación: %s" + +#: ../../fe_utils/print.c:336 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu fila)" +msgstr[1] "(%lu filas)" + +#: ../../fe_utils/print.c:3039 +#, c-format +msgid "Interrupted\n" +msgstr "Interrumpido\n" + +#: ../../fe_utils/print.c:3103 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "No se puede agregar un encabezado al contenido de la tabla: la cantidad de columnas de %d ha sido excedida.\n" + +#: ../../fe_utils/print.c:3143 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "No se puede agregar una celda al contenido de la tabla: la cantidad de celdas de %d ha sido excedida.\n" + +#: ../../fe_utils/print.c:3401 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "formato de salida no válido (error interno): %d" + +#: ../../fe_utils/psqlscan.l:697 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "saltando expansión recursiva de la variable «%s»" + +#: command.c:230 +#, c-format +msgid "invalid command \\%s" +msgstr "orden \\%s no válida" + +#: command.c:232 +#, c-format +msgid "Try \\? for help." +msgstr "Digite \\? para obtener ayuda." + +#: command.c:250 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: argumento extra «%s» ignorado" + +#: command.c:302 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "orden \\%s ignorada: use \\endif o Ctrl-C para salir del bloque \\if actual" + +#: command.c:563 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "no se pudo obtener directorio home para el usuario de ID %ld: %s" + +#: command.c:581 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: no se pudo cambiar directorio a «%s»: %m" + +#: command.c:606 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "No está conectado a una base de datos.\n" + +#: command.c:616 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Está conectado a la base de datos «%s» como el usuario «%s» en la dirección «%s» port «%s».\n" + +#: command.c:619 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Está conectado a la base de datos «%s» como el usuario «%s» a través del socket en «%s» port «%s».\n" + +#: command.c:625 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» (dirección «%s») port «%s».\n" + +#: command.c:628 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» port «%s».\n" + +#: command.c:1012 command.c:1121 command.c:2602 +#, c-format +msgid "no query buffer" +msgstr "no hay búfer de consulta" + +#: command.c:1045 command.c:5304 +#, c-format +msgid "invalid line number: %s" +msgstr "número de línea no válido: %s" + +#: command.c:1112 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "El servidor (versión %s) no soporta la edición del código fuente de funciones." + +#: command.c:1115 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "El servidor (versión %s) no soporta la edición de vistas." + +#: command.c:1197 +msgid "No changes" +msgstr "Sin cambios" + +#: command.c:1276 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: nombre de codificación no válido o procedimiento de conversión no encontrado" + +#: command.c:1311 command.c:2052 command.c:3242 command.c:3434 command.c:5406 +#: common.c:174 common.c:223 common.c:392 common.c:1248 common.c:1276 +#: common.c:1385 common.c:1492 common.c:1530 copy.c:488 copy.c:709 help.c:62 +#: large_obj.c:157 large_obj.c:192 large_obj.c:254 startup.c:298 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1318 +msgid "There is no previous error." +msgstr "No hay error anterior." + +#: command.c:1431 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: falta el paréntesis derecho" + +#: command.c:1608 command.c:1913 command.c:1927 command.c:1944 command.c:2106 +#: command.c:2342 command.c:2569 command.c:2609 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s: falta argumento requerido" + +#: command.c:1739 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: no puede ocurrir después de \\else" + +#: command.c:1744 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif: no hay un \\if coincidente" + +#: command.c:1808 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else: no puede ocurrir después de \\else" + +#: command.c:1813 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else: no hay un \\if coincidente" + +#: command.c:1853 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif: no hay un \\if coincidente" + +#: command.c:2008 +msgid "Query buffer is empty." +msgstr "El búfer de consulta está vacío." + +#: command.c:2030 +msgid "Enter new password: " +msgstr "Ingrese la nueva contraseña: " + +#: command.c:2031 +msgid "Enter it again: " +msgstr "Ingrésela nuevamente: " + +#: command.c:2035 +#, c-format +msgid "Passwords didn't match." +msgstr "Las constraseñas no coinciden." + +#: command.c:2135 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "%s: no se pudo leer el valor para la variable" + +#: command.c:2238 +msgid "Query buffer reset (cleared)." +msgstr "El búfer de consulta ha sido reiniciado (limpiado)." + +#: command.c:2260 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "Se escribió la historia en el archivo «%s».\n" + +#: command.c:2347 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: el nombre de variable de ambiente no debe contener «=»" + +#: command.c:2399 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "El servidor (versión %s) no soporta el despliegue del código fuente de funciones." + +#: command.c:2402 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "El servidor (versión %s) no soporta el despliegue de definiciones de vistas." + +#: command.c:2409 +#, c-format +msgid "function name is required" +msgstr "el nombre de la función es requerido" + +#: command.c:2411 +#, c-format +msgid "view name is required" +msgstr "el nombre de la vista es requerido" + +#: command.c:2541 +msgid "Timing is on." +msgstr "El despliegue de duración está activado." + +#: command.c:2543 +msgid "Timing is off." +msgstr "El despliegue de duración está desactivado." + +#: command.c:2628 command.c:2656 command.c:3873 command.c:3876 command.c:3879 +#: command.c:3885 command.c:3887 command.c:3913 command.c:3923 command.c:3935 +#: command.c:3949 command.c:3976 command.c:4034 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:3047 startup.c:237 startup.c:287 +msgid "Password: " +msgstr "Contraseña: " + +#: command.c:3052 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "Contraseña para usuario %s: " + +#: command.c:3104 +#, c-format +msgid "Do not give user, host, or port separately when using a connection string" +msgstr "No proporcione usuario, host o puerto de forma separada al usar una cadena de conexión" + +#: command.c:3139 +#, c-format +msgid "No database connection exists to re-use parameters from" +msgstr "No existe una conexión de base de datos para poder reusar sus parámetros" + +#: command.c:3440 +#, c-format +msgid "Previous connection kept" +msgstr "Se ha mantenido la conexión anterior" + +#: command.c:3446 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3502 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» en la dirección «%s» port «%s».\n" + +#: command.c:3505 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» a través del socket en «%s» port «%s».\n" + +#: command.c:3511 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» (dirección «%s») port «%s».\n" + +#: command.c:3514 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» port «%s».\n" + +#: command.c:3519 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Ahora está conectado a la base de datos «%s» con el usuario «%s».\n" + +#: command.c:3559 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, servidor %s)\n" + +#: command.c:3567 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"ADVERTENCIA: %s versión mayor %s, servidor versión mayor %s.\n" +" Algunas características de psql podrían no funcionar.\n" + +#: command.c:3606 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "Conexión SSL (protocolo: %s, cifrado: %s, bits: %s, compresión: %s)\n" + +#: command.c:3607 command.c:3608 command.c:3609 +msgid "unknown" +msgstr "desconocido" + +#: command.c:3610 help.c:45 +msgid "off" +msgstr "desactivado" + +#: command.c:3610 help.c:45 +msgid "on" +msgstr "activado" + +#: command.c:3624 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "Conexión Cifrada GSSAPI\n" + +#: command.c:3644 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"ADVERTENCIA: El código de página de la consola (%u) difiere del código\n" +" de página de Windows (%u).\n" +" Los caracteres de 8 bits pueden funcionar incorrectamente.\n" +" Vea la página de referencia de psql «Notes for Windows users»\n" +" para obtener más detalles.\n" + +#: command.c:3749 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "la variable de ambiente PSQL_EDITOR_LINENUMBER_SWITCH debe estar definida para poder especificar un número de línea" + +#: command.c:3778 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "no se pudo iniciar el editor «%s»" + +#: command.c:3780 +#, c-format +msgid "could not start /bin/sh" +msgstr "no se pudo iniciar /bin/sh" + +#: command.c:3830 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "no se pudo ubicar el directorio temporal: %s" + +#: command.c:3857 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "no se pudo abrir archivo temporal «%s»: %m" + +#: command.c:4193 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: abreviación ambigua «%s» coincide tanto con «%s» como con «%s»" + +#: command.c:4213 +#, c-format +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: formatos permitidos son aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" + +#: command.c:4232 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: estilos de línea permitidos son ascii, old-ascii, unicode" + +#: command.c:4247 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: estilos de línea Unicode de borde permitidos son single, double" + +#: command.c:4262 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: estilos de línea Unicode de columna permitidos son single, double" + +#: command.c:4277 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: estilos de línea Unicode de encabezado permitidos son single, double" + +#: command.c:4320 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep debe ser un carácter de un solo byte" + +#: command.c:4325 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldset ni puede ser una comilla doble, un salto de línea, o un retorno de carro" + +#: command.c:4462 command.c:4650 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset: opción desconocida: %s" + +#: command.c:4482 +#, c-format +msgid "Border style is %d.\n" +msgstr "El estilo de borde es %d.\n" + +#: command.c:4488 +#, c-format +msgid "Target width is unset.\n" +msgstr "El ancho no está definido.\n" + +#: command.c:4490 +#, c-format +msgid "Target width is %d.\n" +msgstr "El ancho es %d.\n" + +#: command.c:4497 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Se ha activado el despliegue expandido.\n" + +#: command.c:4499 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "El despliegue expandido se usa automáticamente.\n" + +#: command.c:4501 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Se ha desactivado el despliegue expandido.\n" + +#: command.c:4507 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "El separador de campos para CSV es «%s».\n" + +#: command.c:4515 command.c:4523 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "El separador de campos es el byte cero.\n" + +#: command.c:4517 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "El separador de campos es «%s».\n" + +#: command.c:4530 +#, c-format +msgid "Default footer is on.\n" +msgstr "El pie por omisión está activo.\n" + +#: command.c:4532 +#, c-format +msgid "Default footer is off.\n" +msgstr "El pie de página por omisión está desactivado.\n" + +#: command.c:4538 +#, c-format +msgid "Output format is %s.\n" +msgstr "El formato de salida es %s.\n" + +#: command.c:4544 +#, c-format +msgid "Line style is %s.\n" +msgstr "El estilo de línea es %s.\n" + +#: command.c:4551 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Despliegue de nulos es «%s».\n" + +#: command.c:4559 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "La salida numérica ajustada localmente está habilitada.\n" + +#: command.c:4561 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "La salida numérica ajustada localmente está deshabilitada.\n" + +#: command.c:4568 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "El paginador se usará para salida larga.\n" + +#: command.c:4570 +#, c-format +msgid "Pager is always used.\n" +msgstr "El paginador se usará siempre.\n" + +#: command.c:4572 +#, c-format +msgid "Pager usage is off.\n" +msgstr "El paginador no se usará.\n" + +#: command.c:4578 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "El paginador no se usará para menos de %d línea.\n" +msgstr[1] "El paginador no se usará para menos de %d líneas.\n" + +#: command.c:4588 command.c:4598 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "El separador de filas es el byte cero.\n" + +#: command.c:4590 +#, c-format +msgid "Record separator is .\n" +msgstr "El separador de filas es .\n" + +#: command.c:4592 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "El separador de filas es «%s».\n" + +#: command.c:4605 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Los atributos de tabla son «%s».\n" + +#: command.c:4608 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Los atributos de tabla han sido indefinidos.\n" + +#: command.c:4615 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "El título es «%s».\n" + +#: command.c:4617 +#, c-format +msgid "Title is unset.\n" +msgstr "El título ha sido indefinido.\n" + +#: command.c:4624 +#, c-format +msgid "Tuples only is on.\n" +msgstr "Mostrar sólo filas está activado.\n" + +#: command.c:4626 +#, c-format +msgid "Tuples only is off.\n" +msgstr "Mostrar sólo filas está desactivado.\n" + +#: command.c:4632 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "El estilo Unicode de borde es «%s».\n" + +#: command.c:4638 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "El estilo de línea Unicode de columna es «%s».\n" + +#: command.c:4644 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "El estilo de línea Unicode de encabezado es «%s».\n" + +#: command.c:4877 +#, c-format +msgid "\\!: failed" +msgstr "\\!: falló" + +#: command.c:4902 common.c:652 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch no puede ser usado con una consulta vacía" + +#: command.c:4943 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (cada %gs)\n" + +#: command.c:4946 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (cada %gs)\n" + +#: command.c:5000 command.c:5007 common.c:552 common.c:559 common.c:1231 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:5199 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "«%s.%s» no es una vista" + +#: command.c:5215 +#, c-format +msgid "could not parse reloptions array" +msgstr "no se pudo interpretar el array reloptions" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "no se puede escapar sin una conexión activa" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "el argumento de la orden de shell contiene un salto de línea o retorno de carro: «%s»" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "se ha perdido la conexión al servidor" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "La conexión al servidor se ha perdido. Intentando reiniciar: " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "Falló.\n" + +#: common.c:330 +#, c-format +msgid "Succeeded.\n" +msgstr "Con éxito.\n" + +#: common.c:382 common.c:949 common.c:1166 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "PQresultStatus no esperado: %d" + +#: common.c:491 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Duración: %.3f ms\n" + +#: common.c:506 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Duración: %.3f ms (%02d:%06.3f)\n" + +#: common.c:515 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Duración: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:522 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Duración: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:546 common.c:604 common.c:1202 +#, c-format +msgid "You are currently not connected to a database." +msgstr "No está conectado a una base de datos." + +#: common.c:659 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "no se puede usar \\watch con COPY" + +#: common.c:664 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "estado de resultado inesperado de \\watch" + +#: common.c:694 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "Notificación asíncrona «%s» con carga «%s» recibida del proceso de servidor con PID %d.\n" + +#: common.c:697 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "Notificación asíncrona «%s» recibida del proceso de servidor con PID %d.\n" + +#: common.c:730 common.c:747 +#, c-format +msgid "could not print result table: %m" +msgstr "no se pudo mostrar la tabla de resultados: %m" + +#: common.c:768 +#, c-format +msgid "no rows returned for \\gset" +msgstr "\\gset no retornó renglón alguno" + +#: common.c:773 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "\\gset retornó más de un renglón" + +#: common.c:791 +#, c-format +msgid "attempt to \\gset into specially treated variable \"%s\" ignored" +msgstr "se ignoró intentó de hacer \\gset a variable con tratamiento especial «%s»" + +#: common.c:1211 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(Modo paso a paso: verifique la orden)****************************************\n" +"%s\n" +"***(presione enter para continuar, o x y enter para cancelar)*******************\n" + +#: common.c:1266 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "El servidor (versión %s) no soporta savepoints para ON_ERROR_ROLLBACK." + +#: common.c:1329 +#, c-format +msgid "STATEMENT: %s" +msgstr "SENTENCIA: %s" + +#: common.c:1373 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "estado de transacción inesperado (%d)" + +#: common.c:1514 describe.c:2179 +msgid "Column" +msgstr "Columna" + +#: common.c:1515 describe.c:178 describe.c:396 describe.c:414 describe.c:459 +#: describe.c:476 describe.c:1128 describe.c:1292 describe.c:1878 +#: describe.c:1902 describe.c:2180 describe.c:4048 describe.c:4271 +#: describe.c:4496 describe.c:5794 +msgid "Type" +msgstr "Tipo" + +#: common.c:1564 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "La orden no tiene resultado, o el resultado no tiene columnas.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy: argumentos requeridos" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: error de procesamiento en «%s»" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: error de procesamiento al final de la línea" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "no se pudo ejecutar la orden «%s»: %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s: no se puede copiar desde/hacia un directorio" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "no se pudo cerrar la tubería a la orden externa: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "no se pudo escribir datos COPY: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "falló la transferencia de datos COPY: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "cancelada por el usuario" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Ingrese los datos a ser copiados seguidos de un fin de línea.\n" +"Termine con un backslash y un punto, o una señal EOF." + +#: copy.c:671 +msgid "aborted because of read failure" +msgstr "se abortó por un error de lectura" + +#: copy.c:705 +msgid "trying to exit copy mode" +msgstr "tratando de salir del modo copy" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: la sentencia no produjo un conjunto de resultados" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: la consulta debe retornar al menos tres columnas" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: los encabezados verticales y horizontales deben ser columnas distintas" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: la columna de datos debe ser especificada cuando la consulta retorna más de tres columnas" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: se superó el número máximo de columnas (%d)" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: el resultado de la consulta contiene múltiples valores para la fila «%s», columna «%s»" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: el número de columna %d está fuera del rango 1..%d" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: nombre de columna «%s» ambiguo" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: nombre de columna «%s» no encontrado" + +#: describe.c:76 describe.c:376 describe.c:728 describe.c:924 describe.c:1120 +#: describe.c:1281 describe.c:1353 describe.c:4036 describe.c:4258 +#: describe.c:4494 describe.c:4585 describe.c:4731 describe.c:4944 +#: describe.c:5104 describe.c:5345 describe.c:5420 describe.c:5431 +#: describe.c:5493 describe.c:5918 describe.c:6001 +msgid "Schema" +msgstr "Esquema" + +#: describe.c:77 describe.c:175 describe.c:243 describe.c:251 describe.c:377 +#: describe.c:729 describe.c:925 describe.c:1038 describe.c:1121 +#: describe.c:1354 describe.c:4037 describe.c:4259 describe.c:4417 +#: describe.c:4495 describe.c:4586 describe.c:4665 describe.c:4732 +#: describe.c:4945 describe.c:5029 describe.c:5105 describe.c:5346 +#: describe.c:5421 describe.c:5432 describe.c:5494 describe.c:5691 +#: describe.c:5775 describe.c:5999 describe.c:6171 describe.c:6411 +msgid "Name" +msgstr "Nombre" + +#: describe.c:78 describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "Result data type" +msgstr "Tipo de dato de salida" + +#: describe.c:86 describe.c:99 describe.c:103 describe.c:390 describe.c:408 +#: describe.c:454 describe.c:471 +msgid "Argument data types" +msgstr "Tipos de datos de argumentos" + +#: describe.c:111 describe.c:118 describe.c:186 describe.c:274 describe.c:523 +#: describe.c:777 describe.c:940 describe.c:1063 describe.c:1356 +#: describe.c:2200 describe.c:3823 describe.c:4108 describe.c:4305 +#: describe.c:4448 describe.c:4522 describe.c:4595 describe.c:4678 +#: describe.c:4853 describe.c:4972 describe.c:5038 describe.c:5106 +#: describe.c:5247 describe.c:5289 describe.c:5362 describe.c:5424 +#: describe.c:5433 describe.c:5495 describe.c:5717 describe.c:5797 +#: describe.c:5932 describe.c:6002 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "Descripción" + +#: describe.c:136 +msgid "List of aggregate functions" +msgstr "Listado de funciones de agregación" + +#: describe.c:161 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "El servidor (versión %s) no soporta métodos de acceso." + +#: describe.c:176 +msgid "Index" +msgstr "Indice" + +#: describe.c:177 describe.c:4056 describe.c:4284 describe.c:5919 +msgid "Table" +msgstr "Tabla" + +#: describe.c:185 describe.c:5696 +msgid "Handler" +msgstr "Manejador" + +#: describe.c:204 +msgid "List of access methods" +msgstr "Lista de métodos de acceso" + +#: describe.c:230 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "El servidor (versión %s) no soporta tablespaces." + +#: describe.c:244 describe.c:252 describe.c:504 describe.c:767 describe.c:1039 +#: describe.c:1280 describe.c:4049 describe.c:4260 describe.c:4421 +#: describe.c:4667 describe.c:5030 describe.c:5692 describe.c:5776 +#: describe.c:6172 describe.c:6309 describe.c:6412 describe.c:6535 +#: describe.c:6613 large_obj.c:289 +msgid "Owner" +msgstr "Dueño" + +#: describe.c:245 describe.c:253 +msgid "Location" +msgstr "Ubicación" + +#: describe.c:264 describe.c:3639 +msgid "Options" +msgstr "Opciones" + +#: describe.c:269 describe.c:740 describe.c:1055 describe.c:4100 +#: describe.c:4104 +msgid "Size" +msgstr "Tamaño" + +#: describe.c:291 +msgid "List of tablespaces" +msgstr "Listado de tablespaces" + +#: describe.c:336 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df sólo acepta las opciones [antpwS+]" + +#: describe.c:344 describe.c:355 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df no acepta la opción «%c» en un servidor versión %s" + +#. translator: "agg" is short for "aggregate" +#: describe.c:392 describe.c:410 describe.c:456 describe.c:473 +msgid "agg" +msgstr "agg" + +#: describe.c:393 describe.c:411 +msgid "window" +msgstr "ventana" + +#: describe.c:394 +msgid "proc" +msgstr "proc" + +#: describe.c:395 describe.c:413 describe.c:458 describe.c:475 +msgid "func" +msgstr "func" + +#: describe.c:412 describe.c:457 describe.c:474 describe.c:1490 +msgid "trigger" +msgstr "disparador" + +#: describe.c:486 +msgid "immutable" +msgstr "inmutable" + +#: describe.c:487 +msgid "stable" +msgstr "estable" + +#: describe.c:488 +msgid "volatile" +msgstr "volátil" + +#: describe.c:489 +msgid "Volatility" +msgstr "Volatilidad" + +#: describe.c:497 +msgid "restricted" +msgstr "restringida" + +#: describe.c:498 +msgid "safe" +msgstr "segura" + +#: describe.c:499 +msgid "unsafe" +msgstr "insegura" + +#: describe.c:500 +msgid "Parallel" +msgstr "Paralelismo" + +#: describe.c:505 +msgid "definer" +msgstr "definidor" + +#: describe.c:506 +msgid "invoker" +msgstr "invocador" + +#: describe.c:507 +msgid "Security" +msgstr "Seguridad" + +#: describe.c:512 +msgid "Language" +msgstr "Lenguaje" + +#: describe.c:516 describe.c:520 +msgid "Source code" +msgstr "Código fuente" + +#: describe.c:691 +msgid "List of functions" +msgstr "Listado de funciones" + +#: describe.c:739 +msgid "Internal name" +msgstr "Nombre interno" + +#: describe.c:761 +msgid "Elements" +msgstr "Elementos" + +#: describe.c:822 +msgid "List of data types" +msgstr "Listado de tipos de dato" + +#: describe.c:926 +msgid "Left arg type" +msgstr "Tipo arg izq" + +#: describe.c:927 +msgid "Right arg type" +msgstr "Tipo arg der" + +#: describe.c:928 +msgid "Result type" +msgstr "Tipo resultado" + +#: describe.c:933 describe.c:4673 describe.c:4830 describe.c:4836 +#: describe.c:5246 describe.c:6784 describe.c:6788 +msgid "Function" +msgstr "Función" + +#: describe.c:1010 +msgid "List of operators" +msgstr "Listado de operadores" + +#: describe.c:1040 +msgid "Encoding" +msgstr "Codificación" + +#: describe.c:1045 describe.c:4946 +msgid "Collate" +msgstr "Collate" + +#: describe.c:1046 describe.c:4947 +msgid "Ctype" +msgstr "Ctype" + +#: describe.c:1059 +msgid "Tablespace" +msgstr "Tablespace" + +#: describe.c:1081 +msgid "List of databases" +msgstr "Listado de base de datos" + +#: describe.c:1122 describe.c:1283 describe.c:4038 +msgid "table" +msgstr "tabla" + +#: describe.c:1123 describe.c:4039 +msgid "view" +msgstr "vista" + +#: describe.c:1124 describe.c:4040 +msgid "materialized view" +msgstr "vistas materializadas" + +#: describe.c:1125 describe.c:1285 describe.c:4042 +msgid "sequence" +msgstr "secuencia" + +#: describe.c:1126 describe.c:4045 +msgid "foreign table" +msgstr "tabla foránea" + +#: describe.c:1127 describe.c:4046 describe.c:4269 +msgid "partitioned table" +msgstr "tabla particionada" + +#: describe.c:1139 +msgid "Column privileges" +msgstr "Privilegios de acceso a columnas" + +#: describe.c:1170 describe.c:1204 +msgid "Policies" +msgstr "Políticas" + +#: describe.c:1236 describe.c:6476 describe.c:6480 +msgid "Access privileges" +msgstr "Privilegios" + +#: describe.c:1267 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "El servidor (versión %s) no soporta la alteración de privilegios por omisión." + +#: describe.c:1287 +msgid "function" +msgstr "función" + +#: describe.c:1289 +msgid "type" +msgstr "tipo" + +#: describe.c:1291 +msgid "schema" +msgstr "esquema" + +#: describe.c:1315 +msgid "Default access privileges" +msgstr "Privilegios de acceso por omisión" + +#: describe.c:1355 +msgid "Object" +msgstr "Objeto" + +#: describe.c:1369 +msgid "table constraint" +msgstr "restricción de tabla" + +#: describe.c:1391 +msgid "domain constraint" +msgstr "restricción de dominio" + +#: describe.c:1419 +msgid "operator class" +msgstr "clase de operadores" + +#: describe.c:1448 +msgid "operator family" +msgstr "familia de operadores" + +#: describe.c:1470 +msgid "rule" +msgstr "regla" + +#: describe.c:1512 +msgid "Object descriptions" +msgstr "Descripciones de objetos" + +#: describe.c:1568 describe.c:4175 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "No se encontró relación llamada «%s»." + +#: describe.c:1571 describe.c:4178 +#, c-format +msgid "Did not find any relations." +msgstr "No se encontró ninguna relación." + +#: describe.c:1827 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "No se encontró relación con OID %s." + +#: describe.c:1879 describe.c:1903 +msgid "Start" +msgstr "Inicio" + +#: describe.c:1880 describe.c:1904 +msgid "Minimum" +msgstr "Mínimo" + +#: describe.c:1881 describe.c:1905 +msgid "Maximum" +msgstr "Máximo" + +#: describe.c:1882 describe.c:1906 +msgid "Increment" +msgstr "Incremento" + +#: describe.c:1883 describe.c:1907 describe.c:2038 describe.c:4589 +#: describe.c:4847 describe.c:4961 describe.c:4966 describe.c:6523 +msgid "yes" +msgstr "sí" + +#: describe.c:1884 describe.c:1908 describe.c:2039 describe.c:4589 +#: describe.c:4844 describe.c:4961 describe.c:6524 +msgid "no" +msgstr "no" + +#: describe.c:1885 describe.c:1909 +msgid "Cycles?" +msgstr "¿Cicla?" + +#: describe.c:1886 describe.c:1910 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1953 +#, c-format +msgid "Owned by: %s" +msgstr "Asociada a: %s" + +#: describe.c:1957 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Secuencia para columna identidad: %s" + +#: describe.c:1964 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Secuencia «%s.%s»" + +#: describe.c:2111 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Tabla unlogged «%s.%s»" + +#: describe.c:2114 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Tabla «%s.%s»" + +#: describe.c:2118 +#, c-format +msgid "View \"%s.%s\"" +msgstr "Vista «%s.%s»" + +#: describe.c:2123 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Vista materializada unlogged «%s.%s»" + +#: describe.c:2126 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Vista materializada \"%s.%s\"" + +#: describe.c:2131 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Índice unlogged «%s.%s»" + +#: describe.c:2134 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "Índice «%s.%s»" + +#: describe.c:2139 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Índice particionado unlogged «%s.%s»" + +#: describe.c:2142 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Índice particionado «%s.%s»" + +#: describe.c:2147 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Relación especial «%s.%s»" + +#: describe.c:2151 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "Tabla TOAST «%s.%s»" + +#: describe.c:2155 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Tipo compuesto «%s.%s»" + +#: describe.c:2159 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "Tabla foránea «%s.%s»" + +#: describe.c:2164 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Tabla unlogged particionada «%s.%s»" + +#: describe.c:2167 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Tabla particionada «%s.%s»" + +#: describe.c:2183 describe.c:4502 +msgid "Collation" +msgstr "Ordenamiento" + +#: describe.c:2184 describe.c:4509 +msgid "Nullable" +msgstr "Nulable" + +#: describe.c:2185 describe.c:4510 +msgid "Default" +msgstr "Por omisión" + +#: describe.c:2188 +msgid "Key?" +msgstr "¿Llave?" + +#: describe.c:2190 describe.c:4739 describe.c:4750 +msgid "Definition" +msgstr "Definición" + +#: describe.c:2192 describe.c:5712 describe.c:5796 describe.c:5867 +#: describe.c:5931 +msgid "FDW options" +msgstr "Opciones de FDW" + +#: describe.c:2194 +msgid "Storage" +msgstr "Almacenamiento" + +#: describe.c:2196 +msgid "Compression" +msgstr "Compresión" + +#: describe.c:2198 +msgid "Stats target" +msgstr "Estadísticas" + +#: describe.c:2334 +#, c-format +msgid "Partition of: %s %s%s" +msgstr "Partición de: %s %s%s" + +#: describe.c:2347 +msgid "No partition constraint" +msgstr "Sin restricción de partición" + +#: describe.c:2349 +#, c-format +msgid "Partition constraint: %s" +msgstr "Restricción de partición: %s" + +#: describe.c:2373 +#, c-format +msgid "Partition key: %s" +msgstr "Llave de partición: %s" + +#: describe.c:2399 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Tabla dueña: «%s.%s»" + +#: describe.c:2470 +msgid "primary key, " +msgstr "llave primaria, " + +#: describe.c:2472 +msgid "unique, " +msgstr "único, " + +#: describe.c:2478 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "de tabla «%s.%s»" + +#: describe.c:2482 +#, c-format +msgid ", predicate (%s)" +msgstr ", predicado (%s)" + +#: describe.c:2485 +msgid ", clustered" +msgstr ", clustered" + +#: describe.c:2488 +msgid ", invalid" +msgstr ", no válido" + +#: describe.c:2491 +msgid ", deferrable" +msgstr ", postergable" + +#: describe.c:2494 +msgid ", initially deferred" +msgstr ", inicialmente postergada" + +#: describe.c:2497 +msgid ", replica identity" +msgstr ", identidad de replicación" + +#: describe.c:2564 +msgid "Indexes:" +msgstr "Índices:" + +#: describe.c:2648 +msgid "Check constraints:" +msgstr "Restricciones CHECK:" + +#: describe.c:2716 +msgid "Foreign-key constraints:" +msgstr "Restricciones de llave foránea:" + +#: describe.c:2779 +msgid "Referenced by:" +msgstr "Referenciada por:" + +#: describe.c:2829 +msgid "Policies:" +msgstr "Políticas:" + +#: describe.c:2832 +msgid "Policies (forced row security enabled):" +msgstr "Políticas (seguridad de registros forzada):" + +#: describe.c:2835 +msgid "Policies (row security enabled): (none)" +msgstr "Políticas (seguridad de filas activa): (ninguna)" + +#: describe.c:2838 +msgid "Policies (forced row security enabled): (none)" +msgstr "Políticas (seguridad de filas forzada): (ninguna)" + +#: describe.c:2841 +msgid "Policies (row security disabled):" +msgstr "Políticas (seguridad de filas inactiva):" + +#: describe.c:2902 describe.c:3006 +msgid "Statistics objects:" +msgstr "Objetos de estadísticas:" + +#: describe.c:3120 describe.c:3224 +msgid "Rules:" +msgstr "Reglas:" + +#: describe.c:3123 +msgid "Disabled rules:" +msgstr "Reglas deshabilitadas:" + +#: describe.c:3126 +msgid "Rules firing always:" +msgstr "Reglas que se activan siempre:" + +#: describe.c:3129 +msgid "Rules firing on replica only:" +msgstr "Reglas que se activan sólo en las réplicas:" + +#: describe.c:3169 +msgid "Publications:" +msgstr "Publicaciones:" + +#: describe.c:3207 +msgid "View definition:" +msgstr "Definición de vista:" + +#: describe.c:3354 +msgid "Triggers:" +msgstr "Triggers:" + +#: describe.c:3358 +msgid "Disabled user triggers:" +msgstr "Disparadores de usuario deshabilitados:" + +#: describe.c:3360 +msgid "Disabled triggers:" +msgstr "Disparadores deshabilitados:" + +#: describe.c:3363 +msgid "Disabled internal triggers:" +msgstr "Disparadores internos deshabilitados:" + +#: describe.c:3366 +msgid "Triggers firing always:" +msgstr "Disparadores que siempre se ejecutan:" + +#: describe.c:3369 +msgid "Triggers firing on replica only:" +msgstr "Disparadores que se ejecutan sólo en las réplicas:" + +#: describe.c:3441 +#, c-format +msgid "Server: %s" +msgstr "Servidor: %s" + +#: describe.c:3449 +#, c-format +msgid "FDW options: (%s)" +msgstr "Opciones de FDW: (%s)" + +#: describe.c:3470 +msgid "Inherits" +msgstr "Hereda" + +#: describe.c:3543 +#, c-format +msgid "Number of partitions: %d" +msgstr "Número de particiones: %d" + +#: describe.c:3552 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Número de particiones: %d (Use \\d+ para listarlas.)" + +#: describe.c:3554 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Número de tablas hijas: %d (Use \\d+ para listarlas.)" + +#: describe.c:3561 +msgid "Child tables" +msgstr "Tablas hijas" + +#: describe.c:3561 +msgid "Partitions" +msgstr "Particiones" + +#: describe.c:3592 +#, c-format +msgid "Typed table of type: %s" +msgstr "Tabla tipada de tipo: %s" + +#: describe.c:3608 +msgid "Replica Identity" +msgstr "Identidad de replicación" + +#: describe.c:3621 +msgid "Has OIDs: yes" +msgstr "Tiene OIDs: sí" + +#: describe.c:3630 +#, c-format +msgid "Access method: %s" +msgstr "Método de acceso: %s" + +#: describe.c:3710 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Tablespace: «%s»" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3722 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", tablespace «%s»" + +#: describe.c:3815 +msgid "List of roles" +msgstr "Lista de roles" + +#: describe.c:3817 +msgid "Role name" +msgstr "Nombre de rol" + +#: describe.c:3818 +msgid "Attributes" +msgstr "Atributos" + +#: describe.c:3820 +msgid "Member of" +msgstr "Miembro de" + +#: describe.c:3831 +msgid "Superuser" +msgstr "Superusuario" + +#: describe.c:3834 +msgid "No inheritance" +msgstr "Sin herencia" + +#: describe.c:3837 +msgid "Create role" +msgstr "Crear rol" + +#: describe.c:3840 +msgid "Create DB" +msgstr "Crear BD" + +#: describe.c:3843 +msgid "Cannot login" +msgstr "No puede conectarse" + +#: describe.c:3847 +msgid "Replication" +msgstr "Replicación" + +#: describe.c:3851 +msgid "Bypass RLS" +msgstr "Ignora RLS" + +#: describe.c:3860 +msgid "No connections" +msgstr "Ninguna conexión" + +#: describe.c:3862 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d conexión" +msgstr[1] "%d conexiones" + +#: describe.c:3872 +msgid "Password valid until " +msgstr "Constraseña válida hasta " + +#: describe.c:3922 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "El servidor (versión %s) no soporta parámetros por base de datos y rol." + +#: describe.c:3935 +msgid "Role" +msgstr "Nombre de rol" + +#: describe.c:3936 +msgid "Database" +msgstr "Base de Datos" + +#: describe.c:3937 +msgid "Settings" +msgstr "Parámetros" + +#: describe.c:3958 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "No se encontró ningún parámetro para el rol «%s» y la base de datos «%s»." + +#: describe.c:3961 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "No se encontró ningún parámetro para el rol «%s»." + +#: describe.c:3964 +#, c-format +msgid "Did not find any settings." +msgstr "No se encontró ningún parámetro." + +#: describe.c:3969 +msgid "List of settings" +msgstr "Listado de parámetros" + +#: describe.c:4041 +msgid "index" +msgstr "índice" + +#: describe.c:4043 +msgid "special" +msgstr "especial" + +#: describe.c:4044 +msgid "TOAST table" +msgstr "Tabla TOAST" + +#: describe.c:4047 describe.c:4270 +msgid "partitioned index" +msgstr "índice particionado" + +#: describe.c:4071 +msgid "permanent" +msgstr "permanente" + +#: describe.c:4072 +msgid "temporary" +msgstr "temporal" + +#: describe.c:4073 +msgid "unlogged" +msgstr "unlogged" + +#: describe.c:4074 +msgid "Persistence" +msgstr "Persistencia" + +#: describe.c:4091 +msgid "Access method" +msgstr "Método de acceso" + +#: describe.c:4183 +msgid "List of relations" +msgstr "Listado de relaciones" + +#: describe.c:4231 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "El servidor (versión %s) no soporta particionamiento declarativo de tablas." + +#: describe.c:4242 +msgid "List of partitioned indexes" +msgstr "Listado de índices particionados" + +#: describe.c:4244 +msgid "List of partitioned tables" +msgstr "Listado de tablas particionadas" + +#: describe.c:4248 +msgid "List of partitioned relations" +msgstr "Listado de relaciones particionadas" + +#: describe.c:4279 +msgid "Parent name" +msgstr "Nombre del padre" + +#: describe.c:4292 +msgid "Leaf partition size" +msgstr "Tamaño de particiones hoja" + +#: describe.c:4295 describe.c:4301 +msgid "Total size" +msgstr "Tamaño total" + +#: describe.c:4425 +msgid "Trusted" +msgstr "Confiable" + +#: describe.c:4433 +msgid "Internal language" +msgstr "Lenguaje interno" + +#: describe.c:4434 +msgid "Call handler" +msgstr "Manejador de llamada" + +#: describe.c:4435 describe.c:5699 +msgid "Validator" +msgstr "Validador" + +#: describe.c:4438 +msgid "Inline handler" +msgstr "Manejador en línea" + +#: describe.c:4466 +msgid "List of languages" +msgstr "Lista de lenguajes" + +#: describe.c:4511 +msgid "Check" +msgstr "Check" + +#: describe.c:4553 +msgid "List of domains" +msgstr "Listado de dominios" + +#: describe.c:4587 +msgid "Source" +msgstr "Fuente" + +#: describe.c:4588 +msgid "Destination" +msgstr "Destino" + +#: describe.c:4590 describe.c:6525 +msgid "Default?" +msgstr "Por omisión?" + +#: describe.c:4627 +msgid "List of conversions" +msgstr "Listado de conversiones" + +#: describe.c:4666 +msgid "Event" +msgstr "Evento" + +#: describe.c:4668 +msgid "enabled" +msgstr "activo" + +#: describe.c:4669 +msgid "replica" +msgstr "réplica" + +#: describe.c:4670 +msgid "always" +msgstr "siempre" + +#: describe.c:4671 +msgid "disabled" +msgstr "inactivo" + +#: describe.c:4672 describe.c:6413 +msgid "Enabled" +msgstr "Activo" + +#: describe.c:4674 +msgid "Tags" +msgstr "Etiquetas" + +#: describe.c:4693 +msgid "List of event triggers" +msgstr "Listado de disparadores por eventos" + +#: describe.c:4720 +#, c-format +msgid "The server (version %s) does not support extended statistics." +msgstr "El servidor (versión %s) no soporta estadísticas extendidas." + +#: describe.c:4757 +msgid "Ndistinct" +msgstr "Ndistinct" + +#: describe.c:4758 +msgid "Dependencies" +msgstr "Dependencias" + +#: describe.c:4768 +msgid "MCV" +msgstr "MCV" + +#: describe.c:4787 +msgid "List of extended statistics" +msgstr "Lista de estadísticas extendidas" + +#: describe.c:4814 +msgid "Source type" +msgstr "Tipo fuente" + +#: describe.c:4815 +msgid "Target type" +msgstr "Tipo destino" + +#: describe.c:4846 +msgid "in assignment" +msgstr "en asignación" + +#: describe.c:4848 +msgid "Implicit?" +msgstr "Implícito?" + +#: describe.c:4903 +msgid "List of casts" +msgstr "Listado de conversiones de tipo (casts)" + +#: describe.c:4931 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "El servidor (versión %s) no soporta «collations»." + +#: describe.c:4952 describe.c:4956 +msgid "Provider" +msgstr "Proveedor" + +#: describe.c:4962 describe.c:4967 +msgid "Deterministic?" +msgstr "¿Determinístico?" + +#: describe.c:5002 +msgid "List of collations" +msgstr "Listado de ordenamientos" + +#: describe.c:5061 +msgid "List of schemas" +msgstr "Listado de esquemas" + +#: describe.c:5086 describe.c:5333 describe.c:5404 describe.c:5475 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "El servidor (versión %s) no soporta búsqueda en texto." + +#: describe.c:5121 +msgid "List of text search parsers" +msgstr "Listado de analizadores de búsqueda en texto" + +#: describe.c:5166 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "No se encontró ningún analizador de búsqueda en texto llamado «%s»." + +#: describe.c:5169 +#, c-format +msgid "Did not find any text search parsers." +msgstr "No se encontró ningún analizador de búsqueda en texto." + +#: describe.c:5244 +msgid "Start parse" +msgstr "Inicio de parse" + +#: describe.c:5245 +msgid "Method" +msgstr "Método" + +#: describe.c:5249 +msgid "Get next token" +msgstr "Obtener siguiente elemento" + +#: describe.c:5251 +msgid "End parse" +msgstr "Fin de parse" + +#: describe.c:5253 +msgid "Get headline" +msgstr "Obtener encabezado" + +#: describe.c:5255 +msgid "Get token types" +msgstr "Obtener tipos de elemento" + +#: describe.c:5266 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Analizador de búsqueda en texto «%s.%s»" + +#: describe.c:5269 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "Analizador de búsqueda en texto «%s»" + +#: describe.c:5288 +msgid "Token name" +msgstr "Nombre de elemento" + +#: describe.c:5299 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "Tipos de elemento para el analizador «%s.%s»" + +#: describe.c:5302 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "Tipos de elemento para el analizador «%s»" + +#: describe.c:5356 +msgid "Template" +msgstr "Plantilla" + +#: describe.c:5357 +msgid "Init options" +msgstr "Opciones de inicialización" + +#: describe.c:5379 +msgid "List of text search dictionaries" +msgstr "Listado de diccionarios de búsqueda en texto" + +#: describe.c:5422 +msgid "Init" +msgstr "Inicializador" + +#: describe.c:5423 +msgid "Lexize" +msgstr "Fn. análisis léx." + +#: describe.c:5450 +msgid "List of text search templates" +msgstr "Listado de plantillas de búsqueda en texto" + +#: describe.c:5510 +msgid "List of text search configurations" +msgstr "Listado de configuraciones de búsqueda en texto" + +#: describe.c:5556 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "No se encontró una configuración de búsqueda en texto llamada «%s»." + +#: describe.c:5559 +#, c-format +msgid "Did not find any text search configurations." +msgstr "No se encontró una configuración de búsqueda en texto." + +#: describe.c:5625 +msgid "Token" +msgstr "Elemento" + +#: describe.c:5626 +msgid "Dictionaries" +msgstr "Diccionarios" + +#: describe.c:5637 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Configuración de búsqueda en texto «%s.%s»" + +#: describe.c:5640 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Configuración de búsqueda en texto «%s»" + +#: describe.c:5644 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Analizador: «%s.%s»" + +#: describe.c:5647 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Analizador: «%s»" + +#: describe.c:5681 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "El servidor (versión %s) no soporta conectores de datos externos." + +#: describe.c:5739 +msgid "List of foreign-data wrappers" +msgstr "Listado de conectores de datos externos" + +#: describe.c:5764 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "El servidor (versión %s) no soporta servidores foráneos." + +#: describe.c:5777 +msgid "Foreign-data wrapper" +msgstr "Conectores de datos externos" + +#: describe.c:5795 describe.c:6000 +msgid "Version" +msgstr "Versión" + +#: describe.c:5821 +msgid "List of foreign servers" +msgstr "Listado de servidores foráneos" + +#: describe.c:5846 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "El servidor (versión %s) no soporta mapeos de usuario." + +#: describe.c:5856 describe.c:5920 +msgid "Server" +msgstr "Servidor" + +#: describe.c:5857 +msgid "User name" +msgstr "Nombre de usuario" + +#: describe.c:5882 +msgid "List of user mappings" +msgstr "Listado de mapeos de usuario" + +#: describe.c:5907 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "El servidor (versión %s) no soporta tablas foráneas." + +#: describe.c:5960 +msgid "List of foreign tables" +msgstr "Listado de tablas foráneas" + +#: describe.c:5985 describe.c:6042 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "El servidor (versión %s) no soporta extensiones." + +#: describe.c:6017 +msgid "List of installed extensions" +msgstr "Listado de extensiones instaladas" + +#: describe.c:6070 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "No se encontró extensión llamada «%s»." + +#: describe.c:6073 +#, c-format +msgid "Did not find any extensions." +msgstr "No se encontró ninguna extensión." + +#: describe.c:6117 +msgid "Object description" +msgstr "Descripción de objeto" + +#: describe.c:6127 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "Objetos en extensión «%s»" + +#: describe.c:6156 describe.c:6232 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "El servidor (versión %s) no soporta publicaciones." + +#: describe.c:6173 describe.c:6310 +msgid "All tables" +msgstr "Todas las tablas" + +#: describe.c:6174 describe.c:6311 +msgid "Inserts" +msgstr "Inserts" + +#: describe.c:6175 describe.c:6312 +msgid "Updates" +msgstr "Updates" + +#: describe.c:6176 describe.c:6313 +msgid "Deletes" +msgstr "Deletes" + +#: describe.c:6180 describe.c:6315 +msgid "Truncates" +msgstr "Truncates" + +#: describe.c:6184 describe.c:6317 +msgid "Via root" +msgstr "Via root" + +#: describe.c:6201 +msgid "List of publications" +msgstr "Listado de publicaciones" + +#: describe.c:6274 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "No se encontró publicación llamada «%s»." + +#: describe.c:6277 +#, c-format +msgid "Did not find any publications." +msgstr "No se encontró ninguna publicación." + +#: describe.c:6306 +#, c-format +msgid "Publication %s" +msgstr "Publicación %s" + +#: describe.c:6354 +msgid "Tables:" +msgstr "Tablas:" + +#: describe.c:6398 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "El servidor (versión %s) no soporta suscripciones." + +#: describe.c:6414 +msgid "Publication" +msgstr "Publicación" + +#: describe.c:6423 +msgid "Binary" +msgstr "Binario" + +#: describe.c:6424 +msgid "Streaming" +msgstr "De flujo" + +#: describe.c:6429 +msgid "Synchronous commit" +msgstr "Commit síncrono" + +#: describe.c:6430 +msgid "Conninfo" +msgstr "Conninfo" + +#: describe.c:6452 +msgid "List of subscriptions" +msgstr "Listado de suscripciones" + +#: describe.c:6519 describe.c:6607 describe.c:6692 describe.c:6775 +msgid "AM" +msgstr "AM" + +#: describe.c:6520 +msgid "Input type" +msgstr "Tipo de entrada" + +#: describe.c:6521 +msgid "Storage type" +msgstr "Tipo de almacenamiento" + +#: describe.c:6522 +msgid "Operator class" +msgstr "Clase de operador" + +#: describe.c:6534 describe.c:6608 describe.c:6693 describe.c:6776 +msgid "Operator family" +msgstr "Familia de operadores" + +#: describe.c:6566 +msgid "List of operator classes" +msgstr "Listado de clases de operador" + +#: describe.c:6609 +msgid "Applicable types" +msgstr "Tipos aplicables" + +#: describe.c:6647 +msgid "List of operator families" +msgstr "Listado de familias de operadores" + +#: describe.c:6694 +msgid "Operator" +msgstr "Operador" + +#: describe.c:6695 +msgid "Strategy" +msgstr "Estrategia" + +#: describe.c:6696 +msgid "ordering" +msgstr "ordenamiento" + +#: describe.c:6697 +msgid "search" +msgstr "búsqueda" + +#: describe.c:6698 +msgid "Purpose" +msgstr "Propósito" + +#: describe.c:6703 +msgid "Sort opfamily" +msgstr "familia de ops de ordenamiento" + +#: describe.c:6734 +msgid "List of operators of operator families" +msgstr "Lista de operadores de familias de operadores" + +#: describe.c:6777 +msgid "Registered left type" +msgstr "Tipo de dato izquierdo registrado" + +#: describe.c:6778 +msgid "Registered right type" +msgstr "Tipo de dato derecho registrado" + +#: describe.c:6779 +msgid "Number" +msgstr "Número" + +#: describe.c:6815 +msgid "List of support functions of operator families" +msgstr "Listado de funciones de la familia de operadores %s" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql es el terminal interactivo de PostgreSQL.\n" +"\n" + +#: help.c:74 help.c:355 help.c:433 help.c:476 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [OPCIONES]... [BASE-DE-DATOS [USUARIO]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Opciones generales:\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr " -c, --command=ORDEN ejecutar sólo una orden (SQL o interna) y salir\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr "" +" -d, --dbname=NOMBRE nombre de base de datos a conectarse\n" +" (por omisión: «%s»)\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=ARCHIVO ejecutar órdenes desde archivo, luego salir\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, --list listar bases de datos, luego salir\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=NOMBRE=VALOR\n" +" definir variable de psql NOMBRE a VALOR\n" +" (p.ej. -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión, luego salir\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc no leer archivo de configuración (~/.psqlrc)\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 («uno»), --single-transaction\n" +" ejecuta órdenes en una única transacción\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=opcs] mostrar esta ayuda, luego salir\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands listar órdenes backslash, luego salir\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables listar variables especiales, luego salir\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Opciones de entrada y salida:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all mostrar las órdenes del script\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors mostrar órdenes fallidas\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, --echo-queries mostrar órdenes enviadas al servidor\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden mostrar consultas generadas por órdenes internas\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, --log-file=ARCH envía el registro de la sesión a un archivo\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, --no-readline deshabilitar edición de línea de órdenes (readline)\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, --output=ARCHIVO enviar resultados de consultas a archivo (u |orden)\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, --quiet modo silencioso (sin mensajes, sólo resultados)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, --single-step modo paso a paso (confirmar cada consulta)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr " -S, --single-line modo de líneas (fin de línea termina la orden SQL)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Opciones de formato de salida:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align modo de salida desalineado\n" + +#: help.c:111 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv modo de salida de tabla CSV (valores separados por comas)\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, --field-separator=CADENA separador de campos para salida desalineada\n" +" (por omisión: «%s»)\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html modo de salida en tablas HTML\n" + +#: help.c:116 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr " -P, --pset=VAR[=ARG] definir opción de impresión VAR en ARG (ver orden \\pset)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, --record-separator=CADENA separador de registros para salida desalineada\n" +" (por omisión: salto de línea)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only sólo muestra registros\n" + +#: help.c:120 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr "" +" -T, --table-attr=TEXTO\n" +" definir atributos de marcas de tabla HTML (ancho, borde)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded activar modo expandido de salida de tablas\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" definir separador de campos para salida desalineada al byte cero\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" definir separador de filas para salida desalineada al byte cero\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Opciones de conexión:\n" + +#: help.c:130 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr "" +" -h, --host=NOMBRE nombre del anfitrión o directorio de socket\n" +" (por omisión: «%s»)\n" + +#: help.c:131 +msgid "local socket" +msgstr "socket local" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, --port=PUERTO puerto del servidor (por omisión: «%s»)\n" + +#: help.c:137 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr "" +" -U, --username=NOMBRE\n" +" nombre de usuario (por omisión: «%s»)\n" + +#: help.c:138 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password nunca pedir contraseña\n" + +#: help.c:139 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr "" +" -W, --password forzar petición de contraseña\n" +" (debería ser automático)\n" + +#: help.c:141 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"Para obtener más ayuda, digite «\\?» (para órdenes internas) o «\\help»\n" +"(para órdenes SQL) dentro de psql, o consulte la sección de psql\n" +"en la documentación de PostgreSQL.\n" +"\n" + +#: help.c:144 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Reporte de errores a <%s>.\n" + +#: help.c:145 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Sitio web de %s: <%s>\n" + +#: help.c:171 +#, c-format +msgid "General\n" +msgstr "General\n" + +#: help.c:172 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright mostrar términos de uso y distribución de PostgreSQL\n" + +#: help.c:173 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [COLUMNAS] ejecutar la consulta y desplegar en «crosstab»\n" + +#: help.c:174 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose mostrar error más reciente en máxima verbosidad\n" + +#: help.c:175 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(OPTIONS)] [FILE] ejecuta la consulta (y envía el resultado a un fichero o |pipe);\n" +" \\g sin argumentos es equivalente a un punto y coma\n" + +#: help.c:177 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc describir resultado de la consulta, sin ejecutarla\n" + +#: help.c:178 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr " \\gexec ejecutar la consulta, luego ejecuta cada valor del resultado\n" + +#: help.c:179 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr "" +" \\gset [PREFIJO] ejecutar la consulta y almacenar los resultados en variables\n" +" de psql\n" + +#: help.c:180 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\ gx [(OPTIONS)] [FILE] como \\g, pero fuerza el modo de salida expandido\n" + +#: help.c:181 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q salir de psql\n" + +#: help.c:182 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SEGS] ejecutar consulta cada SEGS segundos\n" + +#: help.c:185 +#, c-format +msgid "Help\n" +msgstr "Ayuda\n" + +#: help.c:187 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commands] desplegar ayuda sobre las órdenes backslash\n" + +#: help.c:188 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? options desplegar ayuda sobre opciones de línea de órdenes\n" + +#: help.c:189 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables desplegar ayuda sobre variables especiales\n" + +#: help.c:190 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr "" +" \\h [NOMBRE] mostrar ayuda de sintaxis de órdenes SQL;\n" +" use «*» para todas las órdenes\n" + +#: help.c:193 +#, c-format +msgid "Query Buffer\n" +msgstr "Búfer de consulta\n" + +#: help.c:194 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr "" +" \\e [ARCHIVO] [LÍNEA]\n" +" editar el búfer de consulta (o archivo) con editor externo\n" + +#: help.c:195 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr "" +" \\ef [NOMBRE-FUNCIÓN [LÍNEA]]\n" +" editar una función con editor externo\n" + +#: help.c:196 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr "" +" \\ev [NOMBRE-VISTA [LÍNEA]]\n" +" editar definición de una vista con editor externo\n" + +#: help.c:197 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p mostrar el contenido del búfer de consulta\n" + +#: help.c:198 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r reiniciar (limpiar) el búfer de consulta\n" + +#: help.c:200 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [ARCHIVO] mostrar historial de órdenes o guardarlo en archivo\n" + +#: help.c:202 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w ARCHIVO escribir búfer de consulta a archivo\n" + +#: help.c:205 +#, c-format +msgid "Input/Output\n" +msgstr "Entrada/Salida\n" + +#: help.c:206 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr " \\copy ... ejecutar orden SQL COPY con flujo de datos al cliente\n" + +#: help.c:207 +#, c-format +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr " \\echo [-n] [STRING] escribe la cadena en la salida estándar (-n no genera el salto de línea final)\n" + +#: help.c:208 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i ARCHIVO ejecutar órdenes desde archivo\n" + +#: help.c:209 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr " \\ir ARCHIVO como \\i, pero relativo a la ubicación del script actual\n" + +#: help.c:210 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [ARCHIVO] enviar resultados de consultas a archivo u |orden\n" + +#: help.c:211 +#, c-format +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr " \\qecho [-n] [STRING] escribe la cadena hacia flujo de salida \\o (-n no genera el salto de línea final)\n" + +#: help.c:212 +#, c-format +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr " \\warn [-n] [STRING] escribe la cadena a la salida de error estándar (-n no genera el salto de línea final)\n" + +#: help.c:215 +#, c-format +msgid "Conditional\n" +msgstr "Condicional\n" + +#: help.c:216 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPRESIÓN inicia bloque condicional\n" + +#: help.c:217 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR alternativa dentro del bloque condicional actual\n" + +#: help.c:218 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else alternativa final dentro del bloque condicional actual\n" + +#: help.c:219 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif termina el bloque condicional\n" + +#: help.c:222 +#, c-format +msgid "Informational\n" +msgstr "Informativo\n" + +#: help.c:223 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (opciones: S = desplegar objectos de sistema, + = agregar más detalle)\n" + +#: help.c:224 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] listar tablas, vistas y secuencias\n" + +#: help.c:225 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+] NOMBRE describir tabla, índice, secuencia o vista\n" + +#: help.c:226 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [PATRÓN] listar funciones de agregación\n" + +#: help.c:227 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [PATRÓN] listar métodos de acceso\n" + +#: help.c:228 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] listar las clases de operadores\n" + +#: help.c:229 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] listar las familias de operadores\n" + +#: help.c:230 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] listar los operadores de la familia de operadores\n" + +#: help.c:231 +#, c-format +msgid " \\dAp[+] [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp[+] [AMPTRN [OPFPTRN]] enumera las funciones de la familia de operadores\n" + +#: help.c:232 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [PATRÓN] listar tablespaces\n" + +#: help.c:233 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [PATRÓN] listar conversiones\n" + +#: help.c:234 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [PATRÓN] listar conversiones de tipo (casts)\n" + +#: help.c:235 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr " \\dd[S] [PATRÓN] listar comentarios de objetos que no aparecen en otra parte\n" + +#: help.c:236 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [PATRÓN] listar dominios\n" + +#: help.c:237 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [PATRÓN] listar privilegios por omisión\n" + +#: help.c:238 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [PATRÓN] listar tablas foráneas\n" + +#: help.c:239 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [PATRÓN] listar tablas foráneas\n" + +#: help.c:240 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [PATRÓN] listar servidores foráneos\n" + +#: help.c:241 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [PATRÓN] listar mapeos de usuario\n" + +#: help.c:242 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [PATRÓN] listar conectores de datos externos\n" + +#: help.c:243 +#, c-format +msgid "" +" \\df[anptw][S+] [FUNCPTRN [TYPEPTRN ...]]\n" +" list [only agg/normal/procedure/trigger/window] functions\n" +msgstr "" +" \\df[anptw][S+] [FUNCPTRN [TYPEPTRN ...]]\n" +" listar funciones [sólo ag./normal/proc./trigger/ventana]\n" + +#: help.c:245 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [PATRÓN] listar configuraciones de búsqueda en texto\n" + +#: help.c:246 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [PATRÓN] listar diccionarios de búsqueda en texto\n" + +#: help.c:247 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [PATRÓN] listar analizadores (parsers) de búsq. en texto\n" + +#: help.c:248 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [PATRÓN] listar plantillas de búsqueda en texto\n" + +#: help.c:249 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [PATRÓN] listar roles\n" + +#: help.c:250 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [PATRÓN] listar índices\n" + +#: help.c:251 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl listar objetos grandes, lo mismo que \\lo_list\n" + +#: help.c:252 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [PATRÓN] listar lenguajes procedurales\n" + +#: help.c:253 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [PATRÓN] listar vistas materializadas\n" + +#: help.c:254 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [PATRÓN] listar esquemas\n" + +#: help.c:255 +#, c-format +msgid "" +" \\do[S+] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" +" list operators\n" +msgstr "" +" \\do[S+] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" +" listar operadores\n" + +#: help.c:257 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S] [PATRÓN] listar ordenamientos (collations)\n" + +#: help.c:258 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [PATRÓN] listar privilegios de acceso a tablas, vistas y secuencias\n" + +#: help.c:259 +#, c-format +msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" +msgstr " \\dP[tin+] [PATRÓN] listar relaciones particionadas (sólo tablas/índices) [n=anidadas]\n" + +#: help.c:260 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [PAT1 [PAT2]] listar parámetros de rol por base de datos\n" + +#: help.c:261 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [PATRÓN] listar publicaciones de replicación\n" + +#: help.c:262 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [PATRÓN] listar suscripciones de replicación\n" + +#: help.c:263 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [PATRÓN] listar secuencias\n" + +#: help.c:264 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [PATRÓN] listar tablas\n" + +#: help.c:265 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [PATRÓN] listar tipos de dato\n" + +#: help.c:266 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [PATRÓN] listar roles\n" + +#: help.c:267 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [PATRÓN] listar vistas\n" + +#: help.c:268 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [PATRÓN] listar extensiones\n" + +#: help.c:269 +#, c-format +msgid " \\dX [PATTERN] list extended statistics\n" +msgstr " \\dX [PATRÓN] listar estadísticas extendidas\n" + +#: help.c:270 +#, c-format +msgid " \\dy[+] [PATTERN] list event triggers\n" +msgstr " \\dy[+] [PATRÓN] listar disparadores por eventos\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [PATRÓN] listar bases de datos\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] FUNCIÓN mostrar la definición de una función\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] VISTA mostrar la definición de una vista\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [PATRÓN] lo mismo que \\dp\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "Formato\n" + +#: help.c:278 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr " \\a cambiar entre modo de salida alineado y sin alinear\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr " \\C [CADENA] definir título de tabla, o indefinir si es vacío\n" + +#: help.c:280 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr "" +" \\f [CADENA] mostrar o definir separador de campos para\n" +" modo de salida sin alinear\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H cambiar modo de salida HTML (actualmente %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [NOMBRE [VALOR]] define opción de tabla de salida\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|unicode_column_linestyle\n" +" |unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] mostrar sólo filas (actualmente %s)\n" + +#: help.c:292 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr " \\T [CADENA] definir atributos HTML de
, o indefinir si es vacío\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] cambiar modo expandido (actualmente %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "Conexiones\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] [BASE-DE-DATOS|- USUARIO|- ANFITRIÓN|- PUERTO|- | conninfo]\n" +" conectar a una nueva base de datos (actual: «%s»)\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] [BASE-DE-DATOS|- USUARIO|- ANFITRIÓN|- PUERTO|- | conninfo]\n" +" conectar a una nueva base de datos (no hay conexión actual)\n" + +#: help.c:305 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo despliega la información sobre la conexión actual\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr "" +" \\encoding [CODIFICACIÓN]\n" +" mostrar o definir codificación del cliente\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr "" +" \\password [USUARIO]\n" +" cambiar la contraseña para un usuario en forma segura\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "Sistema Operativo\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [DIR] cambiar el directorio de trabajo actual\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr "" +" \\setenv NOMBRE [VALOR]\n" +" definir o indefinir variable de ambiente\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr "" +" \\timing [on|off] mostrar tiempo de ejecución de órdenes\n" +" (actualmente %s)\n" + +#: help.c:315 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr "" +" \\! [ORDEN] ejecutar orden en intérprete de órdenes (shell),\n" +" o iniciar intérprete interactivo\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "Variables\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr " \\prompt [TEXTO] NOMBRE preguntar al usuario el valor de la variable\n" + +#: help.c:320 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr "" +" \\set [NOMBRE [VALOR]] definir variables internas,\n" +" listar todas si no se dan parámetros\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset NOMBRE indefinir (eliminar) variable interna\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "Objetos Grandes\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID ARCHIVO\n" +" \\lo_import ARCHIVO [COMENTARIO]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID operaciones con objetos grandes\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"Lista de variables con tratamiento especial\n" +"\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "variables psql:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=NOMBRE=VALOR\n" +" o \\set NOMBRE VALOR dentro de psql\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT si está definida, órdenes SQL exitosas se comprometen\n" +" automáticamente\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE determina si usar mayúsculas al completar palabras SQL\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr " DBNAME la base de datos actualmente conectada\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO controla qué entrada se escribe a la salida estándar\n" +" [all, errors, none, queries]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN muestra consultas internas usadas por órdenes backslash\n" +" con «noexec» sólo las muestra sin ejecutarlas\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr " ENCODING codificación actual del cliente\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr " ERROR verdadero si la última consulta falló; si no, falso\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT número de filas del resultado que extraer y mostrar cada vez\n" +" (por omisión: 0=sin límite)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" ocultar métodos de acceso de tabla\n" + +#: help.c:379 +#, c-format +msgid "" +" HIDE_TOAST_COMPRESSION\n" +" if set, compression methods are not displayed\n" +msgstr "" +" HIDE_TOAST_COMPRESSION\n" +" ocultar métodos de compresión\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL controla la lista de historia de órdenes\n" +" [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr " HISTFILE nombre de archivo para almacenar historia de órdenes\n" + +#: help.c:385 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr " HISTSIZE número de órdenes a guardar en la historia de órdenes\n" + +#: help.c:387 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr " HOST el servidor actualmente conectado\n" + +#: help.c:389 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF si no está definida, enviar un EOF a sesión interactiva\n" +" termina la aplicación\n" + +#: help.c:391 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr " LASTOID el valor del último OID afectado\n" + +#: help.c:393 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" mensaje y SQLSTATE del último error, o cadena vacía y\n" +" «00000» si no hubo\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK si está definido, un error no aborta la transacción\n" +" (usa «savepoints» implícitos)\n" + +#: help.c:398 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr " ON_ERROR_STOP detiene ejecución por lotes al ocurrir un error\n" + +#: help.c:400 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr " PORT puerto del servidor de la conexión actual\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr " PROMPT1 especifica el prompt estándar de psql\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2 especifica el prompt usado cuando una sentencia continúa\n" +" de una línea anterior\n" + +#: help.c:406 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr " PROMPT3 especifica el prompt usado durante COPY ... FROM STDIN\n" + +#: help.c:408 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr " QUIET ejecuta silenciosamente (igual que -q)\n" + +#: help.c:410 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT número de tuplas retornadas o afectadas por última\n" +" consulta, o 0\n" + +#: help.c:412 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" versión del servidor (cadena corta o numérica)\n" + +#: help.c:415 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT controla el despliegue de campos de contexto de mensaje\n" +" [never, errors, always]\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr " SINGLELINE fin de línea termina modo de órdenes SQL (igual que -S)\n" + +#: help.c:419 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr " SINGLESTEP modo paso a paso (igual que -s)\n" + +#: help.c:421 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr " SQLSTATE SQLSTATE de la última consulta, o «00000» si no hubo error\n" + +#: help.c:423 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr " USER el usuario actualmente conectado\n" + +#: help.c:425 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY controla la verbosidad de errores [default, verbose,\n" +" terse, sqlstate]\n" + +#: help.c:427 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" versión de psql (cadena verbosa, corta o numérica)\n" + +#: help.c:432 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Parámetros de despliegue:\n" + +#: help.c:434 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NOMBRE[=VALOR]\n" +" o \\pset NOMBRE [VALOR] dentro de psql\n" +"\n" + +#: help.c:436 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr " border estilo de borde (número)\n" + +#: help.c:438 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr " columns define el ancho para formato «wrapped»\n" + +#: help.c:440 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr " expanded (o x) salida expandida [on, off, auto]\n" + +#: help.c:442 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep separador de campos para formato «unaligned»\n" +" (por omisión: «%s»)\n" + +#: help.c:445 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr " fieldsep_zero separador de campos en «unaligned» es byte cero\n" + +#: help.c:447 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr " footer activa o desactiva el pie de tabla [on, off]\n" + +#: help.c:449 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr " format define el formato de salida [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:451 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr " linestyle define el estilo de dibujo de líneas [ascii, old-ascii, unicode]\n" + +#: help.c:453 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr " null define la cadena a imprimirse para valores null\n" + +#: help.c:455 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +" numericlocale activa despliegue de carácter específico del lenguaje para\n" +" separar grupos de dígitos\n" + +#: help.c:457 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr " pager controla cuándo se usará un paginador externo [yes, no, always]\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr " recordsep separador de registros (líneas) para formato «unaligned»\n" + +#: help.c:461 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr " recordsep_zero separador de registros en «unaligned» es byte cero\n" + +# XXX WTF does this mean? +#: help.c:463 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (o T) especifica atributos para el tag «table» en formato «html»,\n" +" o ancho proporcional de columnas alineadas a la izquierda\n" +" en formato «latex-longtable»\n" + +#: help.c:466 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr " title define el título de tablas\n" + +#: help.c:468 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr " tuples_only si está definido, sólo los datos de la tabla se muestran\n" + +#: help.c:470 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" define el estilo de líneas Unicode [single, double]\n" + +#: help.c:475 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Variables de ambiente:\n" + +#: help.c:479 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NOMBRE=VALOR [NOMBRE=VALOR] psql ...\n" +" o \\setenv NOMBRE [VALOR] dentro de psql\n" + +#: help.c:481 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NOMBRE=VALOR\n" +" psql ...\n" +" o \\setenv NOMBRE [VALOR] dentro de psql\n" + +#: help.c:484 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr " COLUMNS número de columnas para formato «wrapped»\n" + +#: help.c:486 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr " PGAPPNAME igual que el parámetro de conexión application_name\n" + +#: help.c:488 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr " PGDATABASE igual que el parámetro de conexión dbname\n" + +#: help.c:490 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr " PGHOST igual que el parámetro de conexión host\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr " PGPASSFILE nombre de archivo de contraseñas\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr " PGPASSWORD contraseña de la conexión (no recomendado)\n" + +#: help.c:496 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr " PGPORT igual que el parámetro de conexión port\n" + +#: help.c:498 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr " PGUSER igual que el parámetro de conexión user\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor usado por órdenes \\e, \\ef, y \\ev\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARGS\n" +" cómo especificar número de línea al invocar al editor\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr " PSQL_HISTORY ubicación alternativa del archivo de historia de órdenes\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr " PSQL_PAGER, PAGER nombre de programa paginador externo\n" + +#: help.c:508 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr " PSQLRC ubicación alternativa para el archivo .psqlrc del usuario\n" + +#: help.c:510 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr " SHELL intérprete usado por la orden \\!\n" + +#: help.c:512 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr " TMPDIR directorio para archivos temporales\n" + +#: help.c:557 +msgid "Available help:\n" +msgstr "Ayuda disponible:\n" + +#: help.c:652 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"Orden: %s\n" +"Descripción: %s\n" +"Sintaxis:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" + +#: help.c:675 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"No hay ayuda disponible para «%s».\n" +"Pruebe \\h sin argumentos para mostrar los elementos de ayuda disponibles.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "no se pudo leer el archivo de entrada: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "no se pudo guardar historial a archivo «%s»: %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "el historial de órdenes no está soportado en esta instalación" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: no está conectado a una base de datos" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: transacción en curso está abortada" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: estado de transacción desconocido" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "Objetos grandes" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if: escapado" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "Use «\\q» para salir de %s.\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"La entrada es un dump de PostgreSQL en formato custom.\n" +"Use el programa pg_restore para restaurar este dump a una base de datos.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Use \\? para ayuda o presione control-C para limpiar el búfer de entrada." + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "Digite \\? para obtener ayuda." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "Está usando psql, la interfaz de línea de órdenes de PostgreSQL." + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Digite: \\copyright para ver los términos de distribución\n" +" \\h para ayuda de órdenes SQL\n" +" \\? para ayuda de órdenes psql\n" +" \\g o punto y coma («;») para ejecutar la consulta\n" +" \\q para salir\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "Use \\q para salir." + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "Use control-D para salir." + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "Use control-C para salir." + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "consulta ignorada; use \\endif o Ctrl-C para salir del bloque \\if actual" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "se alcanzó EOF sin encontrar el/los \\endif de cierre" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "una cadena de caracteres entre comillas está inconclusa" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: memoria agotada" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:589 sql_help.c:591 sql_help.c:593 +#: sql_help.c:595 sql_help.c:597 sql_help.c:600 sql_help.c:602 sql_help.c:605 +#: sql_help.c:616 sql_help.c:618 sql_help.c:660 sql_help.c:662 sql_help.c:664 +#: sql_help.c:667 sql_help.c:669 sql_help.c:671 sql_help.c:706 sql_help.c:710 +#: sql_help.c:714 sql_help.c:733 sql_help.c:736 sql_help.c:739 sql_help.c:768 +#: sql_help.c:780 sql_help.c:788 sql_help.c:791 sql_help.c:794 sql_help.c:809 +#: sql_help.c:812 sql_help.c:841 sql_help.c:846 sql_help.c:851 sql_help.c:856 +#: sql_help.c:861 sql_help.c:883 sql_help.c:885 sql_help.c:887 sql_help.c:889 +#: sql_help.c:892 sql_help.c:894 sql_help.c:936 sql_help.c:980 sql_help.c:985 +#: sql_help.c:990 sql_help.c:995 sql_help.c:1000 sql_help.c:1019 +#: sql_help.c:1030 sql_help.c:1032 sql_help.c:1051 sql_help.c:1061 +#: sql_help.c:1063 sql_help.c:1065 sql_help.c:1077 sql_help.c:1081 +#: sql_help.c:1083 sql_help.c:1095 sql_help.c:1097 sql_help.c:1099 +#: sql_help.c:1101 sql_help.c:1119 sql_help.c:1121 sql_help.c:1125 +#: sql_help.c:1129 sql_help.c:1133 sql_help.c:1136 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1141 sql_help.c:1143 sql_help.c:1278 +#: sql_help.c:1280 sql_help.c:1283 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1290 sql_help.c:1293 sql_help.c:1296 sql_help.c:1409 +#: sql_help.c:1411 sql_help.c:1413 sql_help.c:1416 sql_help.c:1437 +#: sql_help.c:1440 sql_help.c:1443 sql_help.c:1446 sql_help.c:1450 +#: sql_help.c:1452 sql_help.c:1454 sql_help.c:1456 sql_help.c:1470 +#: sql_help.c:1473 sql_help.c:1475 sql_help.c:1477 sql_help.c:1487 +#: sql_help.c:1489 sql_help.c:1499 sql_help.c:1501 sql_help.c:1511 +#: sql_help.c:1514 sql_help.c:1537 sql_help.c:1539 sql_help.c:1541 +#: sql_help.c:1543 sql_help.c:1546 sql_help.c:1548 sql_help.c:1551 +#: sql_help.c:1554 sql_help.c:1605 sql_help.c:1648 sql_help.c:1651 +#: sql_help.c:1653 sql_help.c:1655 sql_help.c:1658 sql_help.c:1660 +#: sql_help.c:1662 sql_help.c:1665 sql_help.c:1715 sql_help.c:1731 +#: sql_help.c:1962 sql_help.c:2031 sql_help.c:2050 sql_help.c:2063 +#: sql_help.c:2120 sql_help.c:2127 sql_help.c:2137 sql_help.c:2158 +#: sql_help.c:2184 sql_help.c:2202 sql_help.c:2229 sql_help.c:2325 +#: sql_help.c:2371 sql_help.c:2395 sql_help.c:2418 sql_help.c:2422 +#: sql_help.c:2456 sql_help.c:2476 sql_help.c:2498 sql_help.c:2512 +#: sql_help.c:2533 sql_help.c:2557 sql_help.c:2587 sql_help.c:2612 +#: sql_help.c:2659 sql_help.c:2947 sql_help.c:2960 sql_help.c:2977 +#: sql_help.c:2993 sql_help.c:3033 sql_help.c:3087 sql_help.c:3091 +#: sql_help.c:3093 sql_help.c:3100 sql_help.c:3119 sql_help.c:3146 +#: sql_help.c:3181 sql_help.c:3193 sql_help.c:3202 sql_help.c:3246 +#: sql_help.c:3260 sql_help.c:3288 sql_help.c:3296 sql_help.c:3308 +#: sql_help.c:3318 sql_help.c:3326 sql_help.c:3334 sql_help.c:3342 +#: sql_help.c:3350 sql_help.c:3359 sql_help.c:3370 sql_help.c:3378 +#: sql_help.c:3386 sql_help.c:3394 sql_help.c:3402 sql_help.c:3412 +#: sql_help.c:3421 sql_help.c:3430 sql_help.c:3438 sql_help.c:3448 +#: sql_help.c:3459 sql_help.c:3467 sql_help.c:3476 sql_help.c:3487 +#: sql_help.c:3496 sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3528 sql_help.c:3536 sql_help.c:3544 sql_help.c:3552 +#: sql_help.c:3560 sql_help.c:3568 sql_help.c:3576 sql_help.c:3593 +#: sql_help.c:3602 sql_help.c:3610 sql_help.c:3627 sql_help.c:3642 +#: sql_help.c:3944 sql_help.c:3995 sql_help.c:4024 sql_help.c:4039 +#: sql_help.c:4524 sql_help.c:4572 sql_help.c:4723 +msgid "name" +msgstr "nombre" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1812 +#: sql_help.c:3261 sql_help.c:4300 +msgid "aggregate_signature" +msgstr "signatura_func_agregación" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:572 +#: sql_help.c:590 sql_help.c:617 sql_help.c:668 sql_help.c:735 sql_help.c:790 +#: sql_help.c:811 sql_help.c:850 sql_help.c:895 sql_help.c:937 sql_help.c:989 +#: sql_help.c:1021 sql_help.c:1031 sql_help.c:1064 sql_help.c:1084 +#: sql_help.c:1098 sql_help.c:1144 sql_help.c:1287 sql_help.c:1410 +#: sql_help.c:1453 sql_help.c:1474 sql_help.c:1488 sql_help.c:1500 +#: sql_help.c:1513 sql_help.c:1540 sql_help.c:1606 sql_help.c:1659 +msgid "new_name" +msgstr "nuevo_nombre" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:619 +#: sql_help.c:628 sql_help.c:689 sql_help.c:709 sql_help.c:738 sql_help.c:793 +#: sql_help.c:855 sql_help.c:893 sql_help.c:994 sql_help.c:1033 sql_help.c:1062 +#: sql_help.c:1082 sql_help.c:1096 sql_help.c:1142 sql_help.c:1350 +#: sql_help.c:1412 sql_help.c:1455 sql_help.c:1476 sql_help.c:1538 +#: sql_help.c:1654 sql_help.c:2933 +msgid "new_owner" +msgstr "nuevo_dueño" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:670 sql_help.c:713 sql_help.c:741 +#: sql_help.c:796 sql_help.c:860 sql_help.c:999 sql_help.c:1066 sql_help.c:1100 +#: sql_help.c:1289 sql_help.c:1457 sql_help.c:1478 sql_help.c:1490 +#: sql_help.c:1502 sql_help.c:1542 sql_help.c:1661 +msgid "new_schema" +msgstr "nuevo_esquema" + +#: sql_help.c:44 sql_help.c:1876 sql_help.c:3262 sql_help.c:4329 +msgid "where aggregate_signature is:" +msgstr "donde signatura_func_agregación es:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:842 +#: sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:862 sql_help.c:981 +#: sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1001 sql_help.c:1830 +#: sql_help.c:1847 sql_help.c:1853 sql_help.c:1877 sql_help.c:1880 +#: sql_help.c:1883 sql_help.c:2032 sql_help.c:2051 sql_help.c:2054 +#: sql_help.c:2326 sql_help.c:2534 sql_help.c:3263 sql_help.c:3266 +#: sql_help.c:3269 sql_help.c:3360 sql_help.c:3449 sql_help.c:3477 +#: sql_help.c:3822 sql_help.c:4202 sql_help.c:4306 sql_help.c:4313 +#: sql_help.c:4319 sql_help.c:4330 sql_help.c:4333 sql_help.c:4336 +msgid "argmode" +msgstr "modo_arg" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:843 +#: sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:863 sql_help.c:982 +#: sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1002 sql_help.c:1831 +#: sql_help.c:1848 sql_help.c:1854 sql_help.c:1878 sql_help.c:1881 +#: sql_help.c:1884 sql_help.c:2033 sql_help.c:2052 sql_help.c:2055 +#: sql_help.c:2327 sql_help.c:2535 sql_help.c:3264 sql_help.c:3267 +#: sql_help.c:3270 sql_help.c:3361 sql_help.c:3450 sql_help.c:3478 +#: sql_help.c:4307 sql_help.c:4314 sql_help.c:4320 sql_help.c:4331 +#: sql_help.c:4334 sql_help.c:4337 +msgid "argname" +msgstr "nombre_arg" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:844 +#: sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:864 sql_help.c:983 +#: sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1003 sql_help.c:1832 +#: sql_help.c:1849 sql_help.c:1855 sql_help.c:1879 sql_help.c:1882 +#: sql_help.c:1885 sql_help.c:2328 sql_help.c:2536 sql_help.c:3265 +#: sql_help.c:3268 sql_help.c:3271 sql_help.c:3362 sql_help.c:3451 +#: sql_help.c:3479 sql_help.c:4308 sql_help.c:4315 sql_help.c:4321 +#: sql_help.c:4332 sql_help.c:4335 sql_help.c:4338 +msgid "argtype" +msgstr "tipo_arg" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:931 +#: sql_help.c:1079 sql_help.c:1471 sql_help.c:1600 sql_help.c:1632 +#: sql_help.c:1684 sql_help.c:1747 sql_help.c:1933 sql_help.c:1940 +#: sql_help.c:2232 sql_help.c:2274 sql_help.c:2281 sql_help.c:2290 +#: sql_help.c:2372 sql_help.c:2588 sql_help.c:2681 sql_help.c:2962 +#: sql_help.c:3147 sql_help.c:3169 sql_help.c:3309 sql_help.c:3664 +#: sql_help.c:3863 sql_help.c:4038 sql_help.c:4786 +msgid "option" +msgstr "opción" + +#: sql_help.c:113 sql_help.c:932 sql_help.c:1601 sql_help.c:2373 +#: sql_help.c:2589 sql_help.c:3148 sql_help.c:3310 +msgid "where option can be:" +msgstr "donde opción puede ser:" + +#: sql_help.c:114 sql_help.c:2166 +msgid "allowconn" +msgstr "allowconn" + +#: sql_help.c:115 sql_help.c:933 sql_help.c:1602 sql_help.c:2167 +#: sql_help.c:2374 sql_help.c:2590 sql_help.c:3149 +msgid "connlimit" +msgstr "límite_conexiones" + +#: sql_help.c:116 sql_help.c:2168 +msgid "istemplate" +msgstr "esplantilla" + +#: sql_help.c:122 sql_help.c:607 sql_help.c:673 sql_help.c:1292 sql_help.c:1343 +#: sql_help.c:4042 +msgid "new_tablespace" +msgstr "nuevo_tablespace" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:867 sql_help.c:869 sql_help.c:870 sql_help.c:940 +#: sql_help.c:944 sql_help.c:947 sql_help.c:1008 sql_help.c:1010 +#: sql_help.c:1011 sql_help.c:1155 sql_help.c:1158 sql_help.c:1609 +#: sql_help.c:1613 sql_help.c:1616 sql_help.c:2338 sql_help.c:2540 +#: sql_help.c:4060 sql_help.c:4513 +msgid "configuration_parameter" +msgstr "parámetro_de_configuración" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:599 sql_help.c:679 sql_help.c:687 sql_help.c:868 +#: sql_help.c:891 sql_help.c:941 sql_help.c:1009 sql_help.c:1080 +#: sql_help.c:1124 sql_help.c:1128 sql_help.c:1132 sql_help.c:1135 +#: sql_help.c:1140 sql_help.c:1156 sql_help.c:1157 sql_help.c:1323 +#: sql_help.c:1345 sql_help.c:1393 sql_help.c:1415 sql_help.c:1472 +#: sql_help.c:1556 sql_help.c:1610 sql_help.c:1633 sql_help.c:2233 +#: sql_help.c:2275 sql_help.c:2282 sql_help.c:2291 sql_help.c:2339 +#: sql_help.c:2340 sql_help.c:2403 sql_help.c:2406 sql_help.c:2440 +#: sql_help.c:2541 sql_help.c:2542 sql_help.c:2560 sql_help.c:2682 +#: sql_help.c:2721 sql_help.c:2827 sql_help.c:2840 sql_help.c:2854 +#: sql_help.c:2895 sql_help.c:2919 sql_help.c:2936 sql_help.c:2963 +#: sql_help.c:3170 sql_help.c:3864 sql_help.c:4514 sql_help.c:4515 +msgid "value" +msgstr "valor" + +#: sql_help.c:197 +msgid "target_role" +msgstr "rol_destino" + +#: sql_help.c:198 sql_help.c:2217 sql_help.c:2637 sql_help.c:2642 +#: sql_help.c:3797 sql_help.c:3806 sql_help.c:3825 sql_help.c:3834 +#: sql_help.c:4177 sql_help.c:4186 sql_help.c:4205 sql_help.c:4214 +msgid "schema_name" +msgstr "nombre_de_esquema" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "grant_o_revoke_abreviado" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "donde grant_o_revoke_abreviado es uno de:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:570 sql_help.c:606 sql_help.c:672 sql_help.c:814 sql_help.c:951 +#: sql_help.c:1291 sql_help.c:1620 sql_help.c:2377 sql_help.c:2378 +#: sql_help.c:2379 sql_help.c:2380 sql_help.c:2381 sql_help.c:2514 +#: sql_help.c:2593 sql_help.c:2594 sql_help.c:2595 sql_help.c:2596 +#: sql_help.c:2597 sql_help.c:3152 sql_help.c:3153 sql_help.c:3154 +#: sql_help.c:3155 sql_help.c:3156 sql_help.c:3843 sql_help.c:3847 +#: sql_help.c:4223 sql_help.c:4227 sql_help.c:4534 +msgid "role_name" +msgstr "nombre_de_rol" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1307 sql_help.c:1309 +#: sql_help.c:1360 sql_help.c:1372 sql_help.c:1397 sql_help.c:1650 +#: sql_help.c:2187 sql_help.c:2191 sql_help.c:2294 sql_help.c:2299 +#: sql_help.c:2399 sql_help.c:2698 sql_help.c:2703 sql_help.c:2705 +#: sql_help.c:2822 sql_help.c:2835 sql_help.c:2849 sql_help.c:2858 +#: sql_help.c:2870 sql_help.c:2899 sql_help.c:3895 sql_help.c:3910 +#: sql_help.c:3912 sql_help.c:4391 sql_help.c:4392 sql_help.c:4401 +#: sql_help.c:4443 sql_help.c:4444 sql_help.c:4445 sql_help.c:4446 +#: sql_help.c:4447 sql_help.c:4448 sql_help.c:4488 sql_help.c:4489 +#: sql_help.c:4494 sql_help.c:4499 sql_help.c:4640 sql_help.c:4641 +#: sql_help.c:4650 sql_help.c:4692 sql_help.c:4693 sql_help.c:4694 +#: sql_help.c:4695 sql_help.c:4696 sql_help.c:4697 sql_help.c:4751 +#: sql_help.c:4753 sql_help.c:4814 sql_help.c:4872 sql_help.c:4873 +#: sql_help.c:4882 sql_help.c:4924 sql_help.c:4925 sql_help.c:4926 +#: sql_help.c:4927 sql_help.c:4928 sql_help.c:4929 +msgid "expression" +msgstr "expresión" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "restricción_de_dominio" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1284 sql_help.c:1331 sql_help.c:1332 sql_help.c:1333 +#: sql_help.c:1359 sql_help.c:1371 sql_help.c:1388 sql_help.c:1818 +#: sql_help.c:1820 sql_help.c:2190 sql_help.c:2293 sql_help.c:2298 +#: sql_help.c:2857 sql_help.c:2869 sql_help.c:3907 +msgid "constraint_name" +msgstr "nombre_restricción" + +#: sql_help.c:244 sql_help.c:1285 +msgid "new_constraint_name" +msgstr "nuevo_nombre_restricción" + +#: sql_help.c:317 sql_help.c:1078 +msgid "new_version" +msgstr "nueva_versión" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "objeto_miembro" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "dondo objeto_miembro es:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1810 sql_help.c:1815 sql_help.c:1822 +#: sql_help.c:1823 sql_help.c:1824 sql_help.c:1825 sql_help.c:1826 +#: sql_help.c:1827 sql_help.c:1828 sql_help.c:1833 sql_help.c:1835 +#: sql_help.c:1839 sql_help.c:1841 sql_help.c:1845 sql_help.c:1850 +#: sql_help.c:1851 sql_help.c:1858 sql_help.c:1859 sql_help.c:1860 +#: sql_help.c:1861 sql_help.c:1862 sql_help.c:1863 sql_help.c:1864 +#: sql_help.c:1865 sql_help.c:1866 sql_help.c:1867 sql_help.c:1868 +#: sql_help.c:1873 sql_help.c:1874 sql_help.c:4296 sql_help.c:4301 +#: sql_help.c:4302 sql_help.c:4303 sql_help.c:4304 sql_help.c:4310 +#: sql_help.c:4311 sql_help.c:4316 sql_help.c:4317 sql_help.c:4322 +#: sql_help.c:4323 sql_help.c:4324 sql_help.c:4325 sql_help.c:4326 +#: sql_help.c:4327 +msgid "object_name" +msgstr "nombre_de_objeto" + +#: sql_help.c:326 sql_help.c:1811 sql_help.c:4299 +msgid "aggregate_name" +msgstr "nombre_función_agregación" + +#: sql_help.c:328 sql_help.c:1813 sql_help.c:2097 sql_help.c:2101 +#: sql_help.c:2103 sql_help.c:3279 +msgid "source_type" +msgstr "tipo_fuente" + +#: sql_help.c:329 sql_help.c:1814 sql_help.c:2098 sql_help.c:2102 +#: sql_help.c:2104 sql_help.c:3280 +msgid "target_type" +msgstr "tipo_destino" + +#: sql_help.c:336 sql_help.c:778 sql_help.c:1829 sql_help.c:2099 +#: sql_help.c:2140 sql_help.c:2205 sql_help.c:2457 sql_help.c:2488 +#: sql_help.c:3039 sql_help.c:4201 sql_help.c:4305 sql_help.c:4420 +#: sql_help.c:4424 sql_help.c:4428 sql_help.c:4431 sql_help.c:4669 +#: sql_help.c:4673 sql_help.c:4677 sql_help.c:4680 sql_help.c:4901 +#: sql_help.c:4905 sql_help.c:4909 sql_help.c:4912 +msgid "function_name" +msgstr "nombre_de_función" + +#: sql_help.c:341 sql_help.c:771 sql_help.c:1836 sql_help.c:2481 +msgid "operator_name" +msgstr "nombre_operador" + +#: sql_help.c:342 sql_help.c:707 sql_help.c:711 sql_help.c:715 sql_help.c:1837 +#: sql_help.c:2458 sql_help.c:3403 +msgid "left_type" +msgstr "tipo_izq" + +#: sql_help.c:343 sql_help.c:708 sql_help.c:712 sql_help.c:716 sql_help.c:1838 +#: sql_help.c:2459 sql_help.c:3404 +msgid "right_type" +msgstr "tipo_der" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:734 sql_help.c:737 sql_help.c:740 +#: sql_help.c:769 sql_help.c:781 sql_help.c:789 sql_help.c:792 sql_help.c:795 +#: sql_help.c:1377 sql_help.c:1840 sql_help.c:1842 sql_help.c:2478 +#: sql_help.c:2499 sql_help.c:2875 sql_help.c:3413 sql_help.c:3422 +msgid "index_method" +msgstr "método_de_índice" + +#: sql_help.c:349 sql_help.c:1846 sql_help.c:4312 +msgid "procedure_name" +msgstr "nombre_de_procedimiento" + +#: sql_help.c:353 sql_help.c:1852 sql_help.c:3821 sql_help.c:4318 +msgid "routine_name" +msgstr "nombre_de_rutina" + +#: sql_help.c:365 sql_help.c:1349 sql_help.c:1869 sql_help.c:2334 +#: sql_help.c:2539 sql_help.c:2830 sql_help.c:3006 sql_help.c:3584 +#: sql_help.c:3840 sql_help.c:4220 +msgid "type_name" +msgstr "nombre_de_tipo" + +#: sql_help.c:366 sql_help.c:1870 sql_help.c:2333 sql_help.c:2538 +#: sql_help.c:3007 sql_help.c:3237 sql_help.c:3585 sql_help.c:3828 +#: sql_help.c:4208 +msgid "lang_name" +msgstr "nombre_lenguaje" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "y signatura_func_agregación es:" + +#: sql_help.c:392 sql_help.c:1964 sql_help.c:2230 +msgid "handler_function" +msgstr "función_manejadora" + +#: sql_help.c:393 sql_help.c:2231 +msgid "validator_function" +msgstr "función_validadora" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:661 sql_help.c:845 sql_help.c:984 +#: sql_help.c:1279 sql_help.c:1547 +msgid "action" +msgstr "acción" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:665 sql_help.c:675 sql_help.c:677 +#: sql_help.c:680 sql_help.c:682 sql_help.c:683 sql_help.c:1060 sql_help.c:1281 +#: sql_help.c:1299 sql_help.c:1303 sql_help.c:1304 sql_help.c:1308 +#: sql_help.c:1310 sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 +#: sql_help.c:1315 sql_help.c:1318 sql_help.c:1319 sql_help.c:1321 +#: sql_help.c:1324 sql_help.c:1326 sql_help.c:1327 sql_help.c:1373 +#: sql_help.c:1375 sql_help.c:1382 sql_help.c:1391 sql_help.c:1396 +#: sql_help.c:1649 sql_help.c:1652 sql_help.c:1656 sql_help.c:1692 +#: sql_help.c:1817 sql_help.c:1930 sql_help.c:1936 sql_help.c:1949 +#: sql_help.c:1950 sql_help.c:1951 sql_help.c:2272 sql_help.c:2285 +#: sql_help.c:2331 sql_help.c:2398 sql_help.c:2404 sql_help.c:2437 +#: sql_help.c:2667 sql_help.c:2702 sql_help.c:2704 sql_help.c:2812 +#: sql_help.c:2821 sql_help.c:2831 sql_help.c:2834 sql_help.c:2844 +#: sql_help.c:2848 sql_help.c:2871 sql_help.c:2873 sql_help.c:2880 +#: sql_help.c:2893 sql_help.c:2898 sql_help.c:2916 sql_help.c:3042 +#: sql_help.c:3182 sql_help.c:3800 sql_help.c:3801 sql_help.c:3894 +#: sql_help.c:3909 sql_help.c:3911 sql_help.c:3913 sql_help.c:4180 +#: sql_help.c:4181 sql_help.c:4298 sql_help.c:4452 sql_help.c:4458 +#: sql_help.c:4460 sql_help.c:4701 sql_help.c:4707 sql_help.c:4709 +#: sql_help.c:4750 sql_help.c:4752 sql_help.c:4754 sql_help.c:4802 +#: sql_help.c:4933 sql_help.c:4939 sql_help.c:4941 +msgid "column_name" +msgstr "nombre_de_columna" + +#: sql_help.c:444 sql_help.c:666 sql_help.c:1282 sql_help.c:1657 +msgid "new_column_name" +msgstr "nuevo_nombre_de_columna" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:674 sql_help.c:866 sql_help.c:1005 +#: sql_help.c:1298 sql_help.c:1557 +msgid "where action is one of:" +msgstr "donde acción es una de:" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1052 sql_help.c:1300 +#: sql_help.c:1305 sql_help.c:1559 sql_help.c:1563 sql_help.c:2185 +#: sql_help.c:2273 sql_help.c:2477 sql_help.c:2660 sql_help.c:2813 +#: sql_help.c:3089 sql_help.c:3996 +msgid "data_type" +msgstr "tipo_de_dato" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1301 sql_help.c:1306 +#: sql_help.c:1560 sql_help.c:1564 sql_help.c:2186 sql_help.c:2276 +#: sql_help.c:2400 sql_help.c:2815 sql_help.c:2823 sql_help.c:2836 +#: sql_help.c:2850 sql_help.c:3090 sql_help.c:3096 sql_help.c:3904 +msgid "collation" +msgstr "ordenamiento" + +#: sql_help.c:453 sql_help.c:1302 sql_help.c:2277 sql_help.c:2286 +#: sql_help.c:2816 sql_help.c:2832 sql_help.c:2845 +msgid "column_constraint" +msgstr "restricción_de_columna" + +#: sql_help.c:463 sql_help.c:604 sql_help.c:676 sql_help.c:1320 sql_help.c:4799 +msgid "integer" +msgstr "entero" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:678 sql_help.c:681 sql_help.c:1322 +#: sql_help.c:1325 +msgid "attribute_option" +msgstr "opción_de_atributo" + +#: sql_help.c:473 sql_help.c:1329 sql_help.c:2278 sql_help.c:2287 +#: sql_help.c:2817 sql_help.c:2833 sql_help.c:2846 +msgid "table_constraint" +msgstr "restricción_de_tabla" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1334 +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:1871 +msgid "trigger_name" +msgstr "nombre_disparador" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1347 sql_help.c:1348 +#: sql_help.c:2279 sql_help.c:2284 sql_help.c:2820 sql_help.c:2843 +msgid "parent_table" +msgstr "tabla_padre" + +#: sql_help.c:539 sql_help.c:596 sql_help.c:663 sql_help.c:865 sql_help.c:1004 +#: sql_help.c:1516 sql_help.c:2216 +msgid "extension_name" +msgstr "nombre_de_extensión" + +#: sql_help.c:541 sql_help.c:1006 sql_help.c:2335 +msgid "execution_cost" +msgstr "costo_de_ejecución" + +#: sql_help.c:542 sql_help.c:1007 sql_help.c:2336 +msgid "result_rows" +msgstr "núm_de_filas" + +#: sql_help.c:543 sql_help.c:2337 +msgid "support_function" +msgstr "función_de_soporte" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:930 sql_help.c:938 sql_help.c:942 +#: sql_help.c:945 sql_help.c:948 sql_help.c:1599 sql_help.c:1607 +#: sql_help.c:1611 sql_help.c:1614 sql_help.c:1617 sql_help.c:2638 +#: sql_help.c:2640 sql_help.c:2643 sql_help.c:2644 sql_help.c:3798 +#: sql_help.c:3799 sql_help.c:3803 sql_help.c:3804 sql_help.c:3807 +#: sql_help.c:3808 sql_help.c:3810 sql_help.c:3811 sql_help.c:3813 +#: sql_help.c:3814 sql_help.c:3816 sql_help.c:3817 sql_help.c:3819 +#: sql_help.c:3820 sql_help.c:3826 sql_help.c:3827 sql_help.c:3829 +#: sql_help.c:3830 sql_help.c:3832 sql_help.c:3833 sql_help.c:3835 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:3839 sql_help.c:3841 +#: sql_help.c:3842 sql_help.c:3844 sql_help.c:3845 sql_help.c:4178 +#: sql_help.c:4179 sql_help.c:4183 sql_help.c:4184 sql_help.c:4187 +#: sql_help.c:4188 sql_help.c:4190 sql_help.c:4191 sql_help.c:4193 +#: sql_help.c:4194 sql_help.c:4196 sql_help.c:4197 sql_help.c:4199 +#: sql_help.c:4200 sql_help.c:4206 sql_help.c:4207 sql_help.c:4209 +#: sql_help.c:4210 sql_help.c:4212 sql_help.c:4213 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4218 sql_help.c:4219 sql_help.c:4221 +#: sql_help.c:4222 sql_help.c:4224 sql_help.c:4225 +msgid "role_specification" +msgstr "especificación_de_rol" + +#: sql_help.c:566 sql_help.c:568 sql_help.c:1630 sql_help.c:2159 +#: sql_help.c:2646 sql_help.c:3167 sql_help.c:3618 sql_help.c:4544 +msgid "user_name" +msgstr "nombre_de_usuario" + +#: sql_help.c:569 sql_help.c:950 sql_help.c:1619 sql_help.c:2645 +#: sql_help.c:3846 sql_help.c:4226 +msgid "where role_specification can be:" +msgstr "donde especificación_de_rol puede ser:" + +#: sql_help.c:571 +msgid "group_name" +msgstr "nombre_de_grupo" + +#: sql_help.c:592 sql_help.c:1394 sql_help.c:2165 sql_help.c:2407 +#: sql_help.c:2441 sql_help.c:2828 sql_help.c:2841 sql_help.c:2855 +#: sql_help.c:2896 sql_help.c:2920 sql_help.c:2932 sql_help.c:3837 +#: sql_help.c:4217 +msgid "tablespace_name" +msgstr "nombre_de_tablespace" + +#: sql_help.c:594 sql_help.c:685 sql_help.c:1342 sql_help.c:1351 +#: sql_help.c:1389 sql_help.c:1746 sql_help.c:1749 +msgid "index_name" +msgstr "nombre_índice" + +#: sql_help.c:598 sql_help.c:601 sql_help.c:686 sql_help.c:688 sql_help.c:1344 +#: sql_help.c:1346 sql_help.c:1392 sql_help.c:2405 sql_help.c:2439 +#: sql_help.c:2826 sql_help.c:2839 sql_help.c:2853 sql_help.c:2894 +#: sql_help.c:2918 +msgid "storage_parameter" +msgstr "parámetro_de_almacenamiento" + +#: sql_help.c:603 +msgid "column_number" +msgstr "número_de_columna" + +#: sql_help.c:627 sql_help.c:1834 sql_help.c:4309 +msgid "large_object_oid" +msgstr "oid_de_objeto_grande" + +#: sql_help.c:684 sql_help.c:1328 sql_help.c:2814 +msgid "compression_method" +msgstr "método_de_compresión" + +#: sql_help.c:717 sql_help.c:2462 +msgid "res_proc" +msgstr "proc_res" + +#: sql_help.c:718 sql_help.c:2463 +msgid "join_proc" +msgstr "proc_join" + +#: sql_help.c:770 sql_help.c:782 sql_help.c:2480 +msgid "strategy_number" +msgstr "número_de_estrategia" + +#: sql_help.c:772 sql_help.c:773 sql_help.c:776 sql_help.c:777 sql_help.c:783 +#: sql_help.c:784 sql_help.c:786 sql_help.c:787 sql_help.c:2482 sql_help.c:2483 +#: sql_help.c:2486 sql_help.c:2487 +msgid "op_type" +msgstr "tipo_op" + +#: sql_help.c:774 sql_help.c:2484 +msgid "sort_family_name" +msgstr "nombre_familia_ordenamiento" + +#: sql_help.c:775 sql_help.c:785 sql_help.c:2485 +msgid "support_number" +msgstr "número_de_soporte" + +#: sql_help.c:779 sql_help.c:2100 sql_help.c:2489 sql_help.c:3009 +#: sql_help.c:3011 +msgid "argument_type" +msgstr "tipo_argumento" + +#: sql_help.c:810 sql_help.c:813 sql_help.c:884 sql_help.c:886 sql_help.c:888 +#: sql_help.c:1020 sql_help.c:1059 sql_help.c:1512 sql_help.c:1515 +#: sql_help.c:1691 sql_help.c:1745 sql_help.c:1748 sql_help.c:1819 +#: sql_help.c:1844 sql_help.c:1857 sql_help.c:1872 sql_help.c:1929 +#: sql_help.c:1935 sql_help.c:2271 sql_help.c:2283 sql_help.c:2396 +#: sql_help.c:2436 sql_help.c:2513 sql_help.c:2558 sql_help.c:2614 +#: sql_help.c:2666 sql_help.c:2699 sql_help.c:2706 sql_help.c:2811 +#: sql_help.c:2829 sql_help.c:2842 sql_help.c:2915 sql_help.c:3035 +#: sql_help.c:3216 sql_help.c:3439 sql_help.c:3488 sql_help.c:3594 +#: sql_help.c:3796 sql_help.c:3802 sql_help.c:3860 sql_help.c:3892 +#: sql_help.c:4176 sql_help.c:4182 sql_help.c:4297 sql_help.c:4406 +#: sql_help.c:4408 sql_help.c:4465 sql_help.c:4504 sql_help.c:4655 +#: sql_help.c:4657 sql_help.c:4714 sql_help.c:4748 sql_help.c:4801 +#: sql_help.c:4887 sql_help.c:4889 sql_help.c:4946 +msgid "table_name" +msgstr "nombre_de_tabla" + +#: sql_help.c:815 sql_help.c:2515 +msgid "using_expression" +msgstr "expresión_using" + +#: sql_help.c:816 sql_help.c:2516 +msgid "check_expression" +msgstr "expresión_check" + +#: sql_help.c:890 sql_help.c:2559 +msgid "publication_parameter" +msgstr "parámetro_de_publicación" + +#: sql_help.c:934 sql_help.c:1603 sql_help.c:2375 sql_help.c:2591 +#: sql_help.c:3150 +msgid "password" +msgstr "contraseña" + +#: sql_help.c:935 sql_help.c:1604 sql_help.c:2376 sql_help.c:2592 +#: sql_help.c:3151 +msgid "timestamp" +msgstr "fecha_hora" + +#: sql_help.c:939 sql_help.c:943 sql_help.c:946 sql_help.c:949 sql_help.c:1608 +#: sql_help.c:1612 sql_help.c:1615 sql_help.c:1618 sql_help.c:3809 +#: sql_help.c:4189 +msgid "database_name" +msgstr "nombre_de_base_de_datos" + +#: sql_help.c:1053 sql_help.c:2661 +msgid "increment" +msgstr "incremento" + +#: sql_help.c:1054 sql_help.c:2662 +msgid "minvalue" +msgstr "valormin" + +#: sql_help.c:1055 sql_help.c:2663 +msgid "maxvalue" +msgstr "valormax" + +#: sql_help.c:1056 sql_help.c:2664 sql_help.c:4404 sql_help.c:4502 +#: sql_help.c:4653 sql_help.c:4818 sql_help.c:4885 +msgid "start" +msgstr "inicio" + +#: sql_help.c:1057 sql_help.c:1317 +msgid "restart" +msgstr "reinicio" + +#: sql_help.c:1058 sql_help.c:2665 +msgid "cache" +msgstr "cache" + +#: sql_help.c:1102 +msgid "new_target" +msgstr "nuevo_valor" + +#: sql_help.c:1120 sql_help.c:2718 +msgid "conninfo" +msgstr "conninfo" + +#: sql_help.c:1122 sql_help.c:1126 sql_help.c:1130 sql_help.c:2719 +msgid "publication_name" +msgstr "nombre_de_publicación" + +#: sql_help.c:1123 sql_help.c:1127 sql_help.c:1131 +msgid "set_publication_option" +msgstr "opción_de_conjunto_de_publicación" + +#: sql_help.c:1134 +msgid "refresh_option" +msgstr "opción_refresh" + +#: sql_help.c:1139 sql_help.c:2720 +msgid "subscription_parameter" +msgstr "parámetro_de_suscripción" + +#: sql_help.c:1294 sql_help.c:1297 +msgid "partition_name" +msgstr "nombre_de_partición" + +#: sql_help.c:1295 sql_help.c:2288 sql_help.c:2847 +msgid "partition_bound_spec" +msgstr "borde_de_partición" + +#: sql_help.c:1314 sql_help.c:1363 sql_help.c:2861 +msgid "sequence_options" +msgstr "opciones_de_secuencia" + +#: sql_help.c:1316 +msgid "sequence_option" +msgstr "opción_de_secuencia" + +#: sql_help.c:1330 +msgid "table_constraint_using_index" +msgstr "restricción_de_tabla_con_índice" + +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:1340 sql_help.c:1341 +msgid "rewrite_rule_name" +msgstr "nombre_regla_de_reescritura" + +#: sql_help.c:1352 sql_help.c:2886 +msgid "and partition_bound_spec is:" +msgstr "y borde_de_partición es:" + +#: sql_help.c:1353 sql_help.c:1354 sql_help.c:1355 sql_help.c:2887 +#: sql_help.c:2888 sql_help.c:2889 +msgid "partition_bound_expr" +msgstr "expresión_de_borde_de_partición" + +#: sql_help.c:1356 sql_help.c:1357 sql_help.c:2890 sql_help.c:2891 +msgid "numeric_literal" +msgstr "literal_numérico" + +#: sql_help.c:1358 +msgid "and column_constraint is:" +msgstr "donde restricción_de_columna es:" + +#: sql_help.c:1361 sql_help.c:2295 sql_help.c:2329 sql_help.c:2537 +#: sql_help.c:2859 +msgid "default_expr" +msgstr "expr_por_omisión" + +#: sql_help.c:1362 sql_help.c:2296 sql_help.c:2860 +msgid "generation_expr" +msgstr "expr_de_generación" + +#: sql_help.c:1364 sql_help.c:1365 sql_help.c:1374 sql_help.c:1376 +#: sql_help.c:1380 sql_help.c:2862 sql_help.c:2863 sql_help.c:2872 +#: sql_help.c:2874 sql_help.c:2878 +msgid "index_parameters" +msgstr "parámetros_de_índice" + +#: sql_help.c:1366 sql_help.c:1383 sql_help.c:2864 sql_help.c:2881 +msgid "reftable" +msgstr "tabla_ref" + +#: sql_help.c:1367 sql_help.c:1384 sql_help.c:2865 sql_help.c:2882 +msgid "refcolumn" +msgstr "columna_ref" + +#: sql_help.c:1368 sql_help.c:1369 sql_help.c:1385 sql_help.c:1386 +#: sql_help.c:2866 sql_help.c:2867 sql_help.c:2883 sql_help.c:2884 +msgid "referential_action" +msgstr "acción_referencial" + +#: sql_help.c:1370 sql_help.c:2297 sql_help.c:2868 +msgid "and table_constraint is:" +msgstr "y restricción_de_tabla es:" + +#: sql_help.c:1378 sql_help.c:2876 +msgid "exclude_element" +msgstr "elemento_de_exclusión" + +#: sql_help.c:1379 sql_help.c:2877 sql_help.c:4402 sql_help.c:4500 +#: sql_help.c:4651 sql_help.c:4816 sql_help.c:4883 +msgid "operator" +msgstr "operador" + +#: sql_help.c:1381 sql_help.c:2408 sql_help.c:2879 +msgid "predicate" +msgstr "predicado" + +#: sql_help.c:1387 +msgid "and table_constraint_using_index is:" +msgstr "y restricción_de_tabla_con_índice es:" + +#: sql_help.c:1390 sql_help.c:2892 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "parámetros_de_índice en UNIQUE, PRIMARY KEY y EXCLUDE son:" + +#: sql_help.c:1395 sql_help.c:2897 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "elemento_de_exclusión en una restricción EXCLUDE es:" + +#: sql_help.c:1398 sql_help.c:2401 sql_help.c:2824 sql_help.c:2837 +#: sql_help.c:2851 sql_help.c:2900 sql_help.c:3905 +msgid "opclass" +msgstr "clase_de_ops" + +#: sql_help.c:1414 sql_help.c:1417 sql_help.c:2935 +msgid "tablespace_option" +msgstr "opción_de_tablespace" + +#: sql_help.c:1438 sql_help.c:1441 sql_help.c:1447 sql_help.c:1451 +msgid "token_type" +msgstr "tipo_de_token" + +#: sql_help.c:1439 sql_help.c:1442 +msgid "dictionary_name" +msgstr "nombre_diccionario" + +#: sql_help.c:1444 sql_help.c:1448 +msgid "old_dictionary" +msgstr "diccionario_antiguo" + +#: sql_help.c:1445 sql_help.c:1449 +msgid "new_dictionary" +msgstr "diccionario_nuevo" + +#: sql_help.c:1544 sql_help.c:1558 sql_help.c:1561 sql_help.c:1562 +#: sql_help.c:3088 +msgid "attribute_name" +msgstr "nombre_atributo" + +#: sql_help.c:1545 +msgid "new_attribute_name" +msgstr "nuevo_nombre_atributo" + +#: sql_help.c:1549 sql_help.c:1553 +msgid "new_enum_value" +msgstr "nuevo_valor_enum" + +#: sql_help.c:1550 +msgid "neighbor_enum_value" +msgstr "valor_enum_vecino" + +#: sql_help.c:1552 +msgid "existing_enum_value" +msgstr "valor_enum_existente" + +#: sql_help.c:1555 +msgid "property" +msgstr "propiedad" + +#: sql_help.c:1631 sql_help.c:2280 sql_help.c:2289 sql_help.c:2677 +#: sql_help.c:3168 sql_help.c:3619 sql_help.c:3818 sql_help.c:3861 +#: sql_help.c:4198 +msgid "server_name" +msgstr "nombre_de_servidor" + +#: sql_help.c:1663 sql_help.c:1666 sql_help.c:3183 +msgid "view_option_name" +msgstr "nombre_opción_de_vista" + +#: sql_help.c:1664 sql_help.c:3184 +msgid "view_option_value" +msgstr "valor_opción_de_vista" + +#: sql_help.c:1685 sql_help.c:1686 sql_help.c:4787 sql_help.c:4788 +msgid "table_and_columns" +msgstr "tabla_y_columnas" + +#: sql_help.c:1687 sql_help.c:1750 sql_help.c:1941 sql_help.c:3667 +#: sql_help.c:4040 sql_help.c:4789 +msgid "where option can be one of:" +msgstr "donde opción puede ser una de:" + +#: sql_help.c:1688 sql_help.c:1689 sql_help.c:1751 sql_help.c:1943 +#: sql_help.c:1946 sql_help.c:2125 sql_help.c:3668 sql_help.c:3669 +#: sql_help.c:3670 sql_help.c:3671 sql_help.c:3672 sql_help.c:3673 +#: sql_help.c:3674 sql_help.c:3675 sql_help.c:4041 sql_help.c:4043 +#: sql_help.c:4790 sql_help.c:4791 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +#: sql_help.c:4798 +msgid "boolean" +msgstr "booleano" + +#: sql_help.c:1690 sql_help.c:4800 +msgid "and table_and_columns is:" +msgstr "y tabla_y_columnas es:" + +#: sql_help.c:1706 sql_help.c:4560 sql_help.c:4562 sql_help.c:4586 +msgid "transaction_mode" +msgstr "modo_de_transacción" + +#: sql_help.c:1707 sql_help.c:4563 sql_help.c:4587 +msgid "where transaction_mode is one of:" +msgstr "donde modo_de_transacción es uno de:" + +#: sql_help.c:1716 sql_help.c:4412 sql_help.c:4421 sql_help.c:4425 +#: sql_help.c:4429 sql_help.c:4432 sql_help.c:4661 sql_help.c:4670 +#: sql_help.c:4674 sql_help.c:4678 sql_help.c:4681 sql_help.c:4893 +#: sql_help.c:4902 sql_help.c:4906 sql_help.c:4910 sql_help.c:4913 +msgid "argument" +msgstr "argumento" + +#: sql_help.c:1816 +msgid "relation_name" +msgstr "nombre_relación" + +#: sql_help.c:1821 sql_help.c:3812 sql_help.c:4192 +msgid "domain_name" +msgstr "nombre_de_dominio" + +#: sql_help.c:1843 +msgid "policy_name" +msgstr "nombre_de_política" + +#: sql_help.c:1856 +msgid "rule_name" +msgstr "nombre_regla" + +#: sql_help.c:1875 +msgid "text" +msgstr "texto" + +#: sql_help.c:1900 sql_help.c:4005 sql_help.c:4242 +msgid "transaction_id" +msgstr "id_de_transacción" + +#: sql_help.c:1931 sql_help.c:1938 sql_help.c:3931 +msgid "filename" +msgstr "nombre_de_archivo" + +#: sql_help.c:1932 sql_help.c:1939 sql_help.c:2616 sql_help.c:2617 +#: sql_help.c:2618 +msgid "command" +msgstr "orden" + +#: sql_help.c:1934 sql_help.c:2615 sql_help.c:3038 sql_help.c:3219 +#: sql_help.c:3915 sql_help.c:4395 sql_help.c:4397 sql_help.c:4493 +#: sql_help.c:4495 sql_help.c:4644 sql_help.c:4646 sql_help.c:4757 +#: sql_help.c:4876 sql_help.c:4878 +msgid "condition" +msgstr "condición" + +#: sql_help.c:1937 sql_help.c:2442 sql_help.c:2921 sql_help.c:3185 +#: sql_help.c:3203 sql_help.c:3896 +msgid "query" +msgstr "consulta" + +#: sql_help.c:1942 +msgid "format_name" +msgstr "nombre_de_formato" + +#: sql_help.c:1944 +msgid "delimiter_character" +msgstr "carácter_delimitador" + +#: sql_help.c:1945 +msgid "null_string" +msgstr "cadena_null" + +#: sql_help.c:1947 +msgid "quote_character" +msgstr "carácter_de_comilla" + +#: sql_help.c:1948 +msgid "escape_character" +msgstr "carácter_de_escape" + +#: sql_help.c:1952 +msgid "encoding_name" +msgstr "nombre_codificación" + +#: sql_help.c:1963 +msgid "access_method_type" +msgstr "tipo_de_método_de_acceso" + +#: sql_help.c:2034 sql_help.c:2053 sql_help.c:2056 +msgid "arg_data_type" +msgstr "tipo_de_dato_arg" + +#: sql_help.c:2035 sql_help.c:2057 sql_help.c:2065 +msgid "sfunc" +msgstr "func_transición" + +#: sql_help.c:2036 sql_help.c:2058 sql_help.c:2066 +msgid "state_data_type" +msgstr "tipo_de_dato_de_estado" + +#: sql_help.c:2037 sql_help.c:2059 sql_help.c:2067 +msgid "state_data_size" +msgstr "tamaño_de_dato_de_estado" + +#: sql_help.c:2038 sql_help.c:2060 sql_help.c:2068 +msgid "ffunc" +msgstr "func_final" + +#: sql_help.c:2039 sql_help.c:2069 +msgid "combinefunc" +msgstr "func_combinación" + +#: sql_help.c:2040 sql_help.c:2070 +msgid "serialfunc" +msgstr "func_serial" + +#: sql_help.c:2041 sql_help.c:2071 +msgid "deserialfunc" +msgstr "func_deserial" + +#: sql_help.c:2042 sql_help.c:2061 sql_help.c:2072 +msgid "initial_condition" +msgstr "condición_inicial" + +#: sql_help.c:2043 sql_help.c:2073 +msgid "msfunc" +msgstr "func_transición_m" + +#: sql_help.c:2044 sql_help.c:2074 +msgid "minvfunc" +msgstr "func_inv_m" + +#: sql_help.c:2045 sql_help.c:2075 +msgid "mstate_data_type" +msgstr "tipo_de_dato_de_estado_m" + +#: sql_help.c:2046 sql_help.c:2076 +msgid "mstate_data_size" +msgstr "tamaño_de_dato_de_estado_m" + +#: sql_help.c:2047 sql_help.c:2077 +msgid "mffunc" +msgstr "func_final_m" + +#: sql_help.c:2048 sql_help.c:2078 +msgid "minitial_condition" +msgstr "condición_inicial_m" + +#: sql_help.c:2049 sql_help.c:2079 +msgid "sort_operator" +msgstr "operador_de_ordenamiento" + +#: sql_help.c:2062 +msgid "or the old syntax" +msgstr "o la sintaxis antigua" + +#: sql_help.c:2064 +msgid "base_type" +msgstr "tipo_base" + +#: sql_help.c:2121 sql_help.c:2162 +msgid "locale" +msgstr "configuración regional" + +#: sql_help.c:2122 sql_help.c:2163 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2123 sql_help.c:2164 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2124 sql_help.c:4295 +msgid "provider" +msgstr "proveedor" + +#: sql_help.c:2126 sql_help.c:2218 +msgid "version" +msgstr "versión" + +#: sql_help.c:2128 +msgid "existing_collation" +msgstr "ordenamiento_existente" + +#: sql_help.c:2138 +msgid "source_encoding" +msgstr "codificación_origen" + +#: sql_help.c:2139 +msgid "dest_encoding" +msgstr "codificación_destino" + +#: sql_help.c:2160 sql_help.c:2961 +msgid "template" +msgstr "plantilla" + +#: sql_help.c:2161 +msgid "encoding" +msgstr "codificación" + +#: sql_help.c:2188 +msgid "constraint" +msgstr "restricción" + +#: sql_help.c:2189 +msgid "where constraint is:" +msgstr "donde restricción es:" + +#: sql_help.c:2203 sql_help.c:2613 sql_help.c:3034 +msgid "event" +msgstr "evento" + +#: sql_help.c:2204 +msgid "filter_variable" +msgstr "variable_de_filtrado" + +#: sql_help.c:2292 sql_help.c:2856 +msgid "where column_constraint is:" +msgstr "donde restricción_de_columna es:" + +#: sql_help.c:2330 +msgid "rettype" +msgstr "tipo_ret" + +#: sql_help.c:2332 +msgid "column_type" +msgstr "tipo_columna" + +#: sql_help.c:2341 sql_help.c:2543 +msgid "definition" +msgstr "definición" + +#: sql_help.c:2342 sql_help.c:2544 +msgid "obj_file" +msgstr "archivo_obj" + +#: sql_help.c:2343 sql_help.c:2545 +msgid "link_symbol" +msgstr "símbolo_enlace" + +#: sql_help.c:2344 sql_help.c:2546 +msgid "sql_body" +msgstr "contenido_sql" + +#: sql_help.c:2382 sql_help.c:2598 sql_help.c:3157 +msgid "uid" +msgstr "uid" + +#: sql_help.c:2397 sql_help.c:2438 sql_help.c:2825 sql_help.c:2838 +#: sql_help.c:2852 sql_help.c:2917 +msgid "method" +msgstr "método" + +#: sql_help.c:2402 +msgid "opclass_parameter" +msgstr "parámetro_opclass" + +#: sql_help.c:2419 +msgid "call_handler" +msgstr "manejador_de_llamada" + +#: sql_help.c:2420 +msgid "inline_handler" +msgstr "manejador_en_línea" + +#: sql_help.c:2421 +msgid "valfunction" +msgstr "función_val" + +#: sql_help.c:2460 +msgid "com_op" +msgstr "op_conm" + +#: sql_help.c:2461 +msgid "neg_op" +msgstr "op_neg" + +#: sql_help.c:2479 +msgid "family_name" +msgstr "nombre_familia" + +#: sql_help.c:2490 +msgid "storage_type" +msgstr "tipo_almacenamiento" + +#: sql_help.c:2619 sql_help.c:3041 +msgid "where event can be one of:" +msgstr "donde evento puede ser una de:" + +#: sql_help.c:2639 sql_help.c:2641 +msgid "schema_element" +msgstr "elemento_de_esquema" + +#: sql_help.c:2678 +msgid "server_type" +msgstr "tipo_de_servidor" + +#: sql_help.c:2679 +msgid "server_version" +msgstr "versión_de_servidor" + +#: sql_help.c:2680 sql_help.c:3815 sql_help.c:4195 +msgid "fdw_name" +msgstr "nombre_fdw" + +#: sql_help.c:2697 sql_help.c:2700 +msgid "statistics_name" +msgstr "nombre_de_estadística" + +#: sql_help.c:2701 +msgid "statistics_kind" +msgstr "tipo_de_estadística" + +#: sql_help.c:2717 +msgid "subscription_name" +msgstr "nombre_de_suscripción" + +#: sql_help.c:2818 +msgid "source_table" +msgstr "tabla_origen" + +#: sql_help.c:2819 +msgid "like_option" +msgstr "opción_de_like" + +#: sql_help.c:2885 +msgid "and like_option is:" +msgstr "y opción_de_like es:" + +#: sql_help.c:2934 +msgid "directory" +msgstr "directorio" + +#: sql_help.c:2948 +msgid "parser_name" +msgstr "nombre_de_parser" + +#: sql_help.c:2949 +msgid "source_config" +msgstr "config_origen" + +#: sql_help.c:2978 +msgid "start_function" +msgstr "función_inicio" + +#: sql_help.c:2979 +msgid "gettoken_function" +msgstr "función_gettoken" + +#: sql_help.c:2980 +msgid "end_function" +msgstr "función_fin" + +#: sql_help.c:2981 +msgid "lextypes_function" +msgstr "función_lextypes" + +#: sql_help.c:2982 +msgid "headline_function" +msgstr "función_headline" + +#: sql_help.c:2994 +msgid "init_function" +msgstr "función_init" + +#: sql_help.c:2995 +msgid "lexize_function" +msgstr "función_lexize" + +#: sql_help.c:3008 +msgid "from_sql_function_name" +msgstr "nombre_de_función_from" + +#: sql_help.c:3010 +msgid "to_sql_function_name" +msgstr "nombre_de_función_to" + +#: sql_help.c:3036 +msgid "referenced_table_name" +msgstr "nombre_tabla_referenciada" + +#: sql_help.c:3037 +msgid "transition_relation_name" +msgstr "nombre_de_relación_de_transición" + +#: sql_help.c:3040 +msgid "arguments" +msgstr "argumentos" + +#: sql_help.c:3092 sql_help.c:4328 +msgid "label" +msgstr "etiqueta" + +#: sql_help.c:3094 +msgid "subtype" +msgstr "subtipo" + +#: sql_help.c:3095 +msgid "subtype_operator_class" +msgstr "clase_de_operador_del_subtipo" + +#: sql_help.c:3097 +msgid "canonical_function" +msgstr "función_canónica" + +#: sql_help.c:3098 +msgid "subtype_diff_function" +msgstr "función_diff_del_subtipo" + +#: sql_help.c:3099 +msgid "multirange_type_name" +msgstr "nombre_de_tipo_de_rango_múltiple" + +#: sql_help.c:3101 +msgid "input_function" +msgstr "función_entrada" + +#: sql_help.c:3102 +msgid "output_function" +msgstr "función_salida" + +#: sql_help.c:3103 +msgid "receive_function" +msgstr "función_receive" + +#: sql_help.c:3104 +msgid "send_function" +msgstr "función_send" + +#: sql_help.c:3105 +msgid "type_modifier_input_function" +msgstr "función_entrada_del_modificador_de_tipo" + +#: sql_help.c:3106 +msgid "type_modifier_output_function" +msgstr "función_salida_del_modificador_de_tipo" + +#: sql_help.c:3107 +msgid "analyze_function" +msgstr "función_analyze" + +#: sql_help.c:3108 +msgid "subscript_function" +msgstr "función_de_subíndice" + +#: sql_help.c:3109 +msgid "internallength" +msgstr "largo_interno" + +#: sql_help.c:3110 +msgid "alignment" +msgstr "alineamiento" + +#: sql_help.c:3111 +msgid "storage" +msgstr "almacenamiento" + +#: sql_help.c:3112 +msgid "like_type" +msgstr "como_tipo" + +#: sql_help.c:3113 +msgid "category" +msgstr "categoría" + +#: sql_help.c:3114 +msgid "preferred" +msgstr "preferido" + +#: sql_help.c:3115 +msgid "default" +msgstr "valor_por_omisión" + +#: sql_help.c:3116 +msgid "element" +msgstr "elemento" + +#: sql_help.c:3117 +msgid "delimiter" +msgstr "delimitador" + +#: sql_help.c:3118 +msgid "collatable" +msgstr "ordenable" + +#: sql_help.c:3215 sql_help.c:3891 sql_help.c:4390 sql_help.c:4487 +#: sql_help.c:4639 sql_help.c:4747 sql_help.c:4871 +msgid "with_query" +msgstr "consulta_with" + +#: sql_help.c:3217 sql_help.c:3893 sql_help.c:4409 sql_help.c:4415 +#: sql_help.c:4418 sql_help.c:4422 sql_help.c:4426 sql_help.c:4434 +#: sql_help.c:4658 sql_help.c:4664 sql_help.c:4667 sql_help.c:4671 +#: sql_help.c:4675 sql_help.c:4683 sql_help.c:4749 sql_help.c:4890 +#: sql_help.c:4896 sql_help.c:4899 sql_help.c:4903 sql_help.c:4907 +#: sql_help.c:4915 +msgid "alias" +msgstr "alias" + +#: sql_help.c:3218 sql_help.c:4394 sql_help.c:4436 sql_help.c:4438 +#: sql_help.c:4492 sql_help.c:4643 sql_help.c:4685 sql_help.c:4687 +#: sql_help.c:4756 sql_help.c:4875 sql_help.c:4917 sql_help.c:4919 +msgid "from_item" +msgstr "item_de_from" + +#: sql_help.c:3220 sql_help.c:3701 sql_help.c:3972 sql_help.c:4758 +msgid "cursor_name" +msgstr "nombre_de_cursor" + +#: sql_help.c:3221 sql_help.c:3899 sql_help.c:4759 +msgid "output_expression" +msgstr "expresión_de_salida" + +#: sql_help.c:3222 sql_help.c:3900 sql_help.c:4393 sql_help.c:4490 +#: sql_help.c:4642 sql_help.c:4760 sql_help.c:4874 +msgid "output_name" +msgstr "nombre_de_salida" + +#: sql_help.c:3238 +msgid "code" +msgstr "código" + +#: sql_help.c:3643 +msgid "parameter" +msgstr "parámetro" + +#: sql_help.c:3665 sql_help.c:3666 sql_help.c:3997 +msgid "statement" +msgstr "sentencia" + +#: sql_help.c:3700 sql_help.c:3971 +msgid "direction" +msgstr "dirección" + +#: sql_help.c:3702 sql_help.c:3973 +msgid "where direction can be empty or one of:" +msgstr "donde dirección puede ser vacío o uno de:" + +#: sql_help.c:3703 sql_help.c:3704 sql_help.c:3705 sql_help.c:3706 +#: sql_help.c:3707 sql_help.c:3974 sql_help.c:3975 sql_help.c:3976 +#: sql_help.c:3977 sql_help.c:3978 sql_help.c:4403 sql_help.c:4405 +#: sql_help.c:4501 sql_help.c:4503 sql_help.c:4652 sql_help.c:4654 +#: sql_help.c:4817 sql_help.c:4819 sql_help.c:4884 sql_help.c:4886 +msgid "count" +msgstr "cantidad" + +#: sql_help.c:3805 sql_help.c:4185 +msgid "sequence_name" +msgstr "nombre_secuencia" + +#: sql_help.c:3823 sql_help.c:4203 +msgid "arg_name" +msgstr "nombre_arg" + +#: sql_help.c:3824 sql_help.c:4204 +msgid "arg_type" +msgstr "tipo_arg" + +#: sql_help.c:3831 sql_help.c:4211 +msgid "loid" +msgstr "loid" + +#: sql_help.c:3859 +msgid "remote_schema" +msgstr "schema_remoto" + +#: sql_help.c:3862 +msgid "local_schema" +msgstr "schema_local" + +#: sql_help.c:3897 +msgid "conflict_target" +msgstr "destino_de_conflict" + +#: sql_help.c:3898 +msgid "conflict_action" +msgstr "acción_de_conflict" + +#: sql_help.c:3901 +msgid "where conflict_target can be one of:" +msgstr "donde destino_de_conflict puede ser uno de:" + +#: sql_help.c:3902 +msgid "index_column_name" +msgstr "nombre_de_columna_de_índice" + +#: sql_help.c:3903 +msgid "index_expression" +msgstr "expresión_de_índice" + +#: sql_help.c:3906 +msgid "index_predicate" +msgstr "predicado_de_índice" + +#: sql_help.c:3908 +msgid "and conflict_action is one of:" +msgstr "donde acción_de_conflict es una de:" + +#: sql_help.c:3914 sql_help.c:4755 +msgid "sub-SELECT" +msgstr "sub-SELECT" + +#: sql_help.c:3923 sql_help.c:3986 sql_help.c:4731 +msgid "channel" +msgstr "canal" + +#: sql_help.c:3945 +msgid "lockmode" +msgstr "modo_bloqueo" + +#: sql_help.c:3946 +msgid "where lockmode is one of:" +msgstr "donde modo_bloqueo es uno de:" + +#: sql_help.c:3987 +msgid "payload" +msgstr "carga" + +#: sql_help.c:4014 +msgid "old_role" +msgstr "rol_antiguo" + +#: sql_help.c:4015 +msgid "new_role" +msgstr "rol_nuevo" + +#: sql_help.c:4051 sql_help.c:4250 sql_help.c:4258 +msgid "savepoint_name" +msgstr "nombre_de_savepoint" + +#: sql_help.c:4396 sql_help.c:4449 sql_help.c:4645 sql_help.c:4698 +#: sql_help.c:4877 sql_help.c:4930 +msgid "grouping_element" +msgstr "elemento_agrupante" + +#: sql_help.c:4398 sql_help.c:4496 sql_help.c:4647 sql_help.c:4879 +msgid "window_name" +msgstr "nombre_de_ventana" + +#: sql_help.c:4399 sql_help.c:4497 sql_help.c:4648 sql_help.c:4880 +msgid "window_definition" +msgstr "definición_de_ventana" + +#: sql_help.c:4400 sql_help.c:4414 sql_help.c:4453 sql_help.c:4498 +#: sql_help.c:4649 sql_help.c:4663 sql_help.c:4702 sql_help.c:4881 +#: sql_help.c:4895 sql_help.c:4934 +msgid "select" +msgstr "select" + +#: sql_help.c:4407 sql_help.c:4656 sql_help.c:4888 +msgid "where from_item can be one of:" +msgstr "donde item_de_from puede ser uno de:" + +#: sql_help.c:4410 sql_help.c:4416 sql_help.c:4419 sql_help.c:4423 +#: sql_help.c:4435 sql_help.c:4659 sql_help.c:4665 sql_help.c:4668 +#: sql_help.c:4672 sql_help.c:4684 sql_help.c:4891 sql_help.c:4897 +#: sql_help.c:4900 sql_help.c:4904 sql_help.c:4916 +msgid "column_alias" +msgstr "alias_de_columna" + +#: sql_help.c:4411 sql_help.c:4660 sql_help.c:4892 +msgid "sampling_method" +msgstr "método_de_sampleo" + +#: sql_help.c:4413 sql_help.c:4662 sql_help.c:4894 +msgid "seed" +msgstr "semilla" + +#: sql_help.c:4417 sql_help.c:4451 sql_help.c:4666 sql_help.c:4700 +#: sql_help.c:4898 sql_help.c:4932 +msgid "with_query_name" +msgstr "nombre_consulta_with" + +#: sql_help.c:4427 sql_help.c:4430 sql_help.c:4433 sql_help.c:4676 +#: sql_help.c:4679 sql_help.c:4682 sql_help.c:4908 sql_help.c:4911 +#: sql_help.c:4914 +msgid "column_definition" +msgstr "definición_de_columna" + +#: sql_help.c:4437 sql_help.c:4686 sql_help.c:4918 +msgid "join_type" +msgstr "tipo_de_join" + +#: sql_help.c:4439 sql_help.c:4688 sql_help.c:4920 +msgid "join_condition" +msgstr "condición_de_join" + +#: sql_help.c:4440 sql_help.c:4689 sql_help.c:4921 +msgid "join_column" +msgstr "columna_de_join" + +#: sql_help.c:4441 sql_help.c:4690 sql_help.c:4922 +msgid "join_using_alias" +msgstr "join_con_alias" + +#: sql_help.c:4442 sql_help.c:4691 sql_help.c:4923 +msgid "and grouping_element can be one of:" +msgstr "donde elemento_agrupante puede ser una de:" + +#: sql_help.c:4450 sql_help.c:4699 sql_help.c:4931 +msgid "and with_query is:" +msgstr "y consulta_with es:" + +#: sql_help.c:4454 sql_help.c:4703 sql_help.c:4935 +msgid "values" +msgstr "valores" + +#: sql_help.c:4455 sql_help.c:4704 sql_help.c:4936 +msgid "insert" +msgstr "insert" + +#: sql_help.c:4456 sql_help.c:4705 sql_help.c:4937 +msgid "update" +msgstr "update" + +#: sql_help.c:4457 sql_help.c:4706 sql_help.c:4938 +msgid "delete" +msgstr "delete" + +#: sql_help.c:4459 sql_help.c:4708 sql_help.c:4940 +msgid "search_seq_col_name" +msgstr "nombre_col_para_sec_de_búsqueda" + +#: sql_help.c:4461 sql_help.c:4710 sql_help.c:4942 +msgid "cycle_mark_col_name" +msgstr "nombre_col_para_marca_de_ciclo" + +#: sql_help.c:4462 sql_help.c:4711 sql_help.c:4943 +msgid "cycle_mark_value" +msgstr "valor_marca_de_ciclo" + +#: sql_help.c:4463 sql_help.c:4712 sql_help.c:4944 +msgid "cycle_mark_default" +msgstr "valor_predet_marca_de_ciclo" + +#: sql_help.c:4464 sql_help.c:4713 sql_help.c:4945 +msgid "cycle_path_col_name" +msgstr "nombre_col_para_ruta_de_ciclo" + +#: sql_help.c:4491 +msgid "new_table" +msgstr "nueva_tabla" + +#: sql_help.c:4516 +msgid "timezone" +msgstr "huso_horario" + +#: sql_help.c:4561 +msgid "snapshot_id" +msgstr "id_de_snapshot" + +#: sql_help.c:4815 +msgid "sort_expression" +msgstr "expresión_orden" + +#: sql_help.c:4952 sql_help.c:5930 +msgid "abort the current transaction" +msgstr "aborta la transacción en curso" + +#: sql_help.c:4958 +msgid "change the definition of an aggregate function" +msgstr "cambia la definición de una función de agregación" + +#: sql_help.c:4964 +msgid "change the definition of a collation" +msgstr "cambia la definición de un ordenamiento" + +#: sql_help.c:4970 +msgid "change the definition of a conversion" +msgstr "cambia la definición de una conversión" + +#: sql_help.c:4976 +msgid "change a database" +msgstr "cambia una base de datos" + +#: sql_help.c:4982 +msgid "define default access privileges" +msgstr "define privilegios de acceso por omisión" + +#: sql_help.c:4988 +msgid "change the definition of a domain" +msgstr "cambia la definición de un dominio" + +#: sql_help.c:4994 +msgid "change the definition of an event trigger" +msgstr "cambia la definición de un disparador por evento" + +#: sql_help.c:5000 +msgid "change the definition of an extension" +msgstr "cambia la definición de una extensión" + +#: sql_help.c:5006 +msgid "change the definition of a foreign-data wrapper" +msgstr "cambia la definición de un conector de datos externos" + +#: sql_help.c:5012 +msgid "change the definition of a foreign table" +msgstr "cambia la definición de una tabla foránea" + +#: sql_help.c:5018 +msgid "change the definition of a function" +msgstr "cambia la definición de una función" + +#: sql_help.c:5024 +msgid "change role name or membership" +msgstr "cambiar nombre del rol o membresía" + +#: sql_help.c:5030 +msgid "change the definition of an index" +msgstr "cambia la definición de un índice" + +#: sql_help.c:5036 +msgid "change the definition of a procedural language" +msgstr "cambia la definición de un lenguaje procedural" + +#: sql_help.c:5042 +msgid "change the definition of a large object" +msgstr "cambia la definición de un objeto grande" + +#: sql_help.c:5048 +msgid "change the definition of a materialized view" +msgstr "cambia la definición de una vista materializada" + +#: sql_help.c:5054 +msgid "change the definition of an operator" +msgstr "cambia la definición de un operador" + +#: sql_help.c:5060 +msgid "change the definition of an operator class" +msgstr "cambia la definición de una clase de operadores" + +#: sql_help.c:5066 +msgid "change the definition of an operator family" +msgstr "cambia la definición de una familia de operadores" + +#: sql_help.c:5072 +msgid "change the definition of a row-level security policy" +msgstr "cambia la definición de una política de seguridad a nivel de registros" + +#: sql_help.c:5078 +msgid "change the definition of a procedure" +msgstr "cambia la definición de un procedimiento" + +#: sql_help.c:5084 +msgid "change the definition of a publication" +msgstr "cambia la definición de una publicación" + +#: sql_help.c:5090 sql_help.c:5192 +msgid "change a database role" +msgstr "cambia un rol de la base de datos" + +#: sql_help.c:5096 +msgid "change the definition of a routine" +msgstr "cambia la definición de una rutina" + +#: sql_help.c:5102 +msgid "change the definition of a rule" +msgstr "cambia la definición de una regla" + +#: sql_help.c:5108 +msgid "change the definition of a schema" +msgstr "cambia la definición de un esquema" + +#: sql_help.c:5114 +msgid "change the definition of a sequence generator" +msgstr "cambia la definición de un generador secuencial" + +#: sql_help.c:5120 +msgid "change the definition of a foreign server" +msgstr "cambia la definición de un servidor foráneo" + +#: sql_help.c:5126 +msgid "change the definition of an extended statistics object" +msgstr "cambia la definición de un objeto de estadísticas extendidas" + +#: sql_help.c:5132 +msgid "change the definition of a subscription" +msgstr "cambia la definición de una suscripción" + +#: sql_help.c:5138 +msgid "change a server configuration parameter" +msgstr "cambia un parámetro de configuración del servidor" + +#: sql_help.c:5144 +msgid "change the definition of a table" +msgstr "cambia la definición de una tabla" + +#: sql_help.c:5150 +msgid "change the definition of a tablespace" +msgstr "cambia la definición de un tablespace" + +#: sql_help.c:5156 +msgid "change the definition of a text search configuration" +msgstr "cambia la definición de una configuración de búsqueda en texto" + +#: sql_help.c:5162 +msgid "change the definition of a text search dictionary" +msgstr "cambia la definición de un diccionario de búsqueda en texto" + +#: sql_help.c:5168 +msgid "change the definition of a text search parser" +msgstr "cambia la definición de un analizador de búsqueda en texto" + +#: sql_help.c:5174 +msgid "change the definition of a text search template" +msgstr "cambia la definición de una plantilla de búsqueda en texto" + +#: sql_help.c:5180 +msgid "change the definition of a trigger" +msgstr "cambia la definición de un disparador" + +#: sql_help.c:5186 +msgid "change the definition of a type" +msgstr "cambia la definición de un tipo" + +#: sql_help.c:5198 +msgid "change the definition of a user mapping" +msgstr "cambia la definición de un mapeo de usuario" + +#: sql_help.c:5204 +msgid "change the definition of a view" +msgstr "cambia la definición de una vista" + +#: sql_help.c:5210 +msgid "collect statistics about a database" +msgstr "recolecta estadísticas sobre una base de datos" + +#: sql_help.c:5216 sql_help.c:6008 +msgid "start a transaction block" +msgstr "inicia un bloque de transacción" + +#: sql_help.c:5222 +msgid "invoke a procedure" +msgstr "invocar un procedimiento" + +#: sql_help.c:5228 +msgid "force a write-ahead log checkpoint" +msgstr "fuerza un checkpoint de wal" + +#: sql_help.c:5234 +msgid "close a cursor" +msgstr "cierra un cursor" + +#: sql_help.c:5240 +msgid "cluster a table according to an index" +msgstr "reordena una tabla siguiendo un índice" + +#: sql_help.c:5246 +msgid "define or change the comment of an object" +msgstr "define o cambia un comentario sobre un objeto" + +#: sql_help.c:5252 sql_help.c:5810 +msgid "commit the current transaction" +msgstr "compromete la transacción en curso" + +#: sql_help.c:5258 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "confirma una transacción que fue preparada para two-phase commit" + +#: sql_help.c:5264 +msgid "copy data between a file and a table" +msgstr "copia datos entre un archivo y una tabla" + +#: sql_help.c:5270 +msgid "define a new access method" +msgstr "define un nuevo método de acceso" + +#: sql_help.c:5276 +msgid "define a new aggregate function" +msgstr "define una nueva función de agregación" + +#: sql_help.c:5282 +msgid "define a new cast" +msgstr "define una nueva conversión de tipo" + +#: sql_help.c:5288 +msgid "define a new collation" +msgstr "define un nuevo ordenamiento" + +#: sql_help.c:5294 +msgid "define a new encoding conversion" +msgstr "define una nueva conversión de codificación" + +#: sql_help.c:5300 +msgid "create a new database" +msgstr "crea una nueva base de datos" + +#: sql_help.c:5306 +msgid "define a new domain" +msgstr "define un nuevo dominio" + +#: sql_help.c:5312 +msgid "define a new event trigger" +msgstr "define un nuevo disparador por evento" + +#: sql_help.c:5318 +msgid "install an extension" +msgstr "instala una extensión" + +#: sql_help.c:5324 +msgid "define a new foreign-data wrapper" +msgstr "define un nuevo conector de datos externos" + +#: sql_help.c:5330 +msgid "define a new foreign table" +msgstr "define una nueva tabla foránea" + +#: sql_help.c:5336 +msgid "define a new function" +msgstr "define una nueva función" + +#: sql_help.c:5342 sql_help.c:5402 sql_help.c:5504 +msgid "define a new database role" +msgstr "define un nuevo rol de la base de datos" + +#: sql_help.c:5348 +msgid "define a new index" +msgstr "define un nuevo índice" + +#: sql_help.c:5354 +msgid "define a new procedural language" +msgstr "define un nuevo lenguaje procedural" + +#: sql_help.c:5360 +msgid "define a new materialized view" +msgstr "define una nueva vista materializada" + +#: sql_help.c:5366 +msgid "define a new operator" +msgstr "define un nuevo operador" + +#: sql_help.c:5372 +msgid "define a new operator class" +msgstr "define una nueva clase de operadores" + +#: sql_help.c:5378 +msgid "define a new operator family" +msgstr "define una nueva familia de operadores" + +#: sql_help.c:5384 +msgid "define a new row-level security policy for a table" +msgstr "define una nueva política de seguridad a nivel de registros para una tabla" + +#: sql_help.c:5390 +msgid "define a new procedure" +msgstr "define un nuevo procedimiento" + +#: sql_help.c:5396 +msgid "define a new publication" +msgstr "define una nueva publicación" + +#: sql_help.c:5408 +msgid "define a new rewrite rule" +msgstr "define una nueva regla de reescritura" + +#: sql_help.c:5414 +msgid "define a new schema" +msgstr "define un nuevo schema" + +#: sql_help.c:5420 +msgid "define a new sequence generator" +msgstr "define un nuevo generador secuencial" + +#: sql_help.c:5426 +msgid "define a new foreign server" +msgstr "define un nuevo servidor foráneo" + +#: sql_help.c:5432 +msgid "define extended statistics" +msgstr "define estadísticas extendidas" + +#: sql_help.c:5438 +msgid "define a new subscription" +msgstr "define una nueva suscripción" + +#: sql_help.c:5444 +msgid "define a new table" +msgstr "define una nueva tabla" + +#: sql_help.c:5450 sql_help.c:5966 +msgid "define a new table from the results of a query" +msgstr "crea una nueva tabla usando los resultados de una consulta" + +#: sql_help.c:5456 +msgid "define a new tablespace" +msgstr "define un nuevo tablespace" + +#: sql_help.c:5462 +msgid "define a new text search configuration" +msgstr "define una nueva configuración de búsqueda en texto" + +#: sql_help.c:5468 +msgid "define a new text search dictionary" +msgstr "define un nuevo diccionario de búsqueda en texto" + +#: sql_help.c:5474 +msgid "define a new text search parser" +msgstr "define un nuevo analizador de búsqueda en texto" + +#: sql_help.c:5480 +msgid "define a new text search template" +msgstr "define una nueva plantilla de búsqueda en texto" + +#: sql_help.c:5486 +msgid "define a new transform" +msgstr "define una nueva transformación" + +#: sql_help.c:5492 +msgid "define a new trigger" +msgstr "define un nuevo disparador" + +#: sql_help.c:5498 +msgid "define a new data type" +msgstr "define un nuevo tipo de datos" + +#: sql_help.c:5510 +msgid "define a new mapping of a user to a foreign server" +msgstr "define un nuevo mapa de usuario a servidor foráneo" + +#: sql_help.c:5516 +msgid "define a new view" +msgstr "define una nueva vista" + +#: sql_help.c:5522 +msgid "deallocate a prepared statement" +msgstr "elimina una sentencia preparada" + +#: sql_help.c:5528 +msgid "define a cursor" +msgstr "define un nuevo cursor" + +#: sql_help.c:5534 +msgid "delete rows of a table" +msgstr "elimina filas de una tabla" + +#: sql_help.c:5540 +msgid "discard session state" +msgstr "descartar datos de la sesión" + +#: sql_help.c:5546 +msgid "execute an anonymous code block" +msgstr "ejecutar un bloque anónimo de código" + +#: sql_help.c:5552 +msgid "remove an access method" +msgstr "elimina un método de acceso" + +#: sql_help.c:5558 +msgid "remove an aggregate function" +msgstr "elimina una función de agregación" + +#: sql_help.c:5564 +msgid "remove a cast" +msgstr "elimina una conversión de tipo" + +#: sql_help.c:5570 +msgid "remove a collation" +msgstr "elimina un ordenamiento" + +#: sql_help.c:5576 +msgid "remove a conversion" +msgstr "elimina una conversión de codificación" + +#: sql_help.c:5582 +msgid "remove a database" +msgstr "elimina una base de datos" + +#: sql_help.c:5588 +msgid "remove a domain" +msgstr "elimina un dominio" + +#: sql_help.c:5594 +msgid "remove an event trigger" +msgstr "elimina un disparador por evento" + +#: sql_help.c:5600 +msgid "remove an extension" +msgstr "elimina una extensión" + +#: sql_help.c:5606 +msgid "remove a foreign-data wrapper" +msgstr "elimina un conector de datos externos" + +#: sql_help.c:5612 +msgid "remove a foreign table" +msgstr "elimina una tabla foránea" + +#: sql_help.c:5618 +msgid "remove a function" +msgstr "elimina una función" + +#: sql_help.c:5624 sql_help.c:5690 sql_help.c:5792 +msgid "remove a database role" +msgstr "elimina un rol de base de datos" + +#: sql_help.c:5630 +msgid "remove an index" +msgstr "elimina un índice" + +#: sql_help.c:5636 +msgid "remove a procedural language" +msgstr "elimina un lenguaje procedural" + +#: sql_help.c:5642 +msgid "remove a materialized view" +msgstr "elimina una vista materializada" + +#: sql_help.c:5648 +msgid "remove an operator" +msgstr "elimina un operador" + +#: sql_help.c:5654 +msgid "remove an operator class" +msgstr "elimina una clase de operadores" + +#: sql_help.c:5660 +msgid "remove an operator family" +msgstr "elimina una familia de operadores" + +#: sql_help.c:5666 +msgid "remove database objects owned by a database role" +msgstr "elimina objetos de propiedad de un rol de la base de datos" + +#: sql_help.c:5672 +msgid "remove a row-level security policy from a table" +msgstr "elimina una política de seguridad a nivel de registros de una tabla" + +#: sql_help.c:5678 +msgid "remove a procedure" +msgstr "elimina un procedimiento" + +#: sql_help.c:5684 +msgid "remove a publication" +msgstr "elimina una publicación" + +#: sql_help.c:5696 +msgid "remove a routine" +msgstr "elimina una rutina" + +#: sql_help.c:5702 +msgid "remove a rewrite rule" +msgstr "elimina una regla de reescritura" + +#: sql_help.c:5708 +msgid "remove a schema" +msgstr "elimina un schema" + +#: sql_help.c:5714 +msgid "remove a sequence" +msgstr "elimina un generador secuencial" + +#: sql_help.c:5720 +msgid "remove a foreign server descriptor" +msgstr "elimina un descriptor de servidor foráneo" + +#: sql_help.c:5726 +msgid "remove extended statistics" +msgstr "elimina estadísticas extendidas" + +#: sql_help.c:5732 +msgid "remove a subscription" +msgstr "elimina una suscripción" + +#: sql_help.c:5738 +msgid "remove a table" +msgstr "elimina una tabla" + +#: sql_help.c:5744 +msgid "remove a tablespace" +msgstr "elimina un tablespace" + +#: sql_help.c:5750 +msgid "remove a text search configuration" +msgstr "elimina una configuración de búsqueda en texto" + +#: sql_help.c:5756 +msgid "remove a text search dictionary" +msgstr "elimina un diccionario de búsqueda en texto" + +#: sql_help.c:5762 +msgid "remove a text search parser" +msgstr "elimina un analizador de búsqueda en texto" + +#: sql_help.c:5768 +msgid "remove a text search template" +msgstr "elimina una plantilla de búsqueda en texto" + +#: sql_help.c:5774 +msgid "remove a transform" +msgstr "elimina una transformación" + +#: sql_help.c:5780 +msgid "remove a trigger" +msgstr "elimina un disparador" + +#: sql_help.c:5786 +msgid "remove a data type" +msgstr "elimina un tipo de datos" + +#: sql_help.c:5798 +msgid "remove a user mapping for a foreign server" +msgstr "elimina un mapeo de usuario para un servidor remoto" + +#: sql_help.c:5804 +msgid "remove a view" +msgstr "elimina una vista" + +#: sql_help.c:5816 +msgid "execute a prepared statement" +msgstr "ejecuta una sentencia preparada" + +#: sql_help.c:5822 +msgid "show the execution plan of a statement" +msgstr "muestra el plan de ejecución de una sentencia" + +#: sql_help.c:5828 +msgid "retrieve rows from a query using a cursor" +msgstr "recupera filas de una consulta usando un cursor" + +#: sql_help.c:5834 +msgid "define access privileges" +msgstr "define privilegios de acceso" + +#: sql_help.c:5840 +msgid "import table definitions from a foreign server" +msgstr "importa definiciones de tablas desde un servidor foráneo" + +#: sql_help.c:5846 +msgid "create new rows in a table" +msgstr "crea nuevas filas en una tabla" + +#: sql_help.c:5852 +msgid "listen for a notification" +msgstr "escucha notificaciones" + +#: sql_help.c:5858 +msgid "load a shared library file" +msgstr "carga un archivo de biblioteca compartida" + +#: sql_help.c:5864 +msgid "lock a table" +msgstr "bloquea una tabla" + +#: sql_help.c:5870 +msgid "position a cursor" +msgstr "reposiciona un cursor" + +#: sql_help.c:5876 +msgid "generate a notification" +msgstr "genera una notificación" + +#: sql_help.c:5882 +msgid "prepare a statement for execution" +msgstr "prepara una sentencia para ejecución" + +#: sql_help.c:5888 +msgid "prepare the current transaction for two-phase commit" +msgstr "prepara la transacción actual para two-phase commit" + +#: sql_help.c:5894 +msgid "change the ownership of database objects owned by a database role" +msgstr "cambia de dueño a los objetos de propiedad de un rol de la base de datos" + +#: sql_help.c:5900 +msgid "replace the contents of a materialized view" +msgstr "reemplaza los contenidos de una vista materializada" + +#: sql_help.c:5906 +msgid "rebuild indexes" +msgstr "reconstruye índices" + +#: sql_help.c:5912 +msgid "destroy a previously defined savepoint" +msgstr "destruye un savepoint previamente definido" + +#: sql_help.c:5918 +msgid "restore the value of a run-time parameter to the default value" +msgstr "restaura el valor de un parámetro de configuración al valor inicial" + +#: sql_help.c:5924 +msgid "remove access privileges" +msgstr "revoca privilegios de acceso" + +#: sql_help.c:5936 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "cancela una transacción que fue previamente preparada para two-phase commit" + +#: sql_help.c:5942 +msgid "roll back to a savepoint" +msgstr "descartar hacia un savepoint" + +#: sql_help.c:5948 +msgid "define a new savepoint within the current transaction" +msgstr "define un nuevo savepoint en la transacción en curso" + +#: sql_help.c:5954 +msgid "define or change a security label applied to an object" +msgstr "define o cambia una etiqueta de seguridad sobre un objeto" + +#: sql_help.c:5960 sql_help.c:6014 sql_help.c:6050 +msgid "retrieve rows from a table or view" +msgstr "recupera filas desde una tabla o vista" + +#: sql_help.c:5972 +msgid "change a run-time parameter" +msgstr "cambia un parámetro de configuración" + +#: sql_help.c:5978 +msgid "set constraint check timing for the current transaction" +msgstr "define el modo de verificación de las restricciones de la transacción en curso" + +#: sql_help.c:5984 +msgid "set the current user identifier of the current session" +msgstr "define el identificador de usuario actual de la sesión actual" + +#: sql_help.c:5990 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "" +"define el identificador del usuario de sesión y el identificador\n" +"del usuario actual de la sesión en curso" + +#: sql_help.c:5996 +msgid "set the characteristics of the current transaction" +msgstr "define las características de la transacción en curso" + +#: sql_help.c:6002 +msgid "show the value of a run-time parameter" +msgstr "muestra el valor de un parámetro de configuración" + +#: sql_help.c:6020 +msgid "empty a table or set of tables" +msgstr "vacía una tabla o conjunto de tablas" + +#: sql_help.c:6026 +msgid "stop listening for a notification" +msgstr "deja de escuchar una notificación" + +#: sql_help.c:6032 +msgid "update rows of a table" +msgstr "actualiza filas de una tabla" + +#: sql_help.c:6038 +msgid "garbage-collect and optionally analyze a database" +msgstr "recolecta basura y opcionalmente estadísticas sobre una base de datos" + +#: sql_help.c:6044 +msgid "compute a set of rows" +msgstr "calcula un conjunto de registros" + +#: startup.c:213 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 sólo puede ser usado en modo no interactivo" + +#: startup.c:326 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "no se pudo abrir el archivo de registro «%s»: %m" + +#: startup.c:438 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Digite «help» para obtener ayuda.\n" +"\n" + +#: startup.c:591 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "no se pudo definir parámetro de impresión «%s»" + +#: startup.c:699 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Use «%s --help» para obtener más información.\n" + +#: startup.c:716 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "se ignoró argumento extra «%s» en línea de órdenes" + +#: startup.c:765 +#, c-format +msgid "could not find own program executable" +msgstr "no se pudo encontrar el ejecutable propio" + +#: tab-complete.c:4898 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"la consulta para completación por tabulador falló: %s\n" +"La consulta era:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "valor «%s» no reconocido para «%s»: se esperaba booleano" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "valor «%s» no válido para «%s»: se esperaba número entero" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "nombre de variable no válido: «%s»" + +#: variables.c:419 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"valor «%s» no reconocido para «%s»\n" +"Los valores disponibles son: %s." + +#~ msgid "pclose failed: %m" +#~ msgstr "pclose falló: %m" + +#~ msgid "Could not send cancel request: %s" +#~ msgstr "No se pudo enviar el paquete de cancelación: %s" + +#~ msgid "All connection parameters must be supplied because no database connection exists" +#~ msgstr "Debe proveer todos los parámetros de conexión porque no existe conexión a una base de datos" + +#~ msgid "could not connect to server: %s" +#~ msgstr "no se pudo conectar al servidor: %s" diff --git a/src/bin/psql/po/fr.po b/src/bin/psql/po/fr.po new file mode 100644 index 000000000000..c6260d70ea77 --- /dev/null +++ b/src/bin/psql/po/fr.po @@ -0,0 +1,6986 @@ +# translation of psql.po to fr_fr +# french message translation file for psql +# +# Use these quotes: « %s » +# Peter Eisentraut , 2001. +# Guillaume Lelarge , 2003-2009. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-06-14 06:15+0000\n" +"PO-Revision-Date: 2021-06-14 16:09+0200\n" +"Last-Translator: Guillaume Lelarge \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Poedit 2.4.3\n" + +#: ../../../src/common/logging.c:259 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:266 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:273 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../../common/exec.c:136 ../../common/exec.c:253 ../../common/exec.c:299 +#, c-format +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" + +#: ../../common/exec.c:155 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "binaire « %s » invalide" + +#: ../../common/exec.c:205 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "n'a pas pu lire le binaire « %s »" + +#: ../../common/exec.c:213 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "n'a pas pu trouver un « %s » à exécuter" + +#: ../../common/exec.c:269 ../../common/exec.c:308 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" + +#: ../../common/exec.c:286 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" + +#: ../../common/exec.c:409 +#, c-format +msgid "%s() failed: %m" +msgstr "échec de %s() : %m" + +#: ../../common/exec.c:522 ../../common/exec.c:567 ../../common/exec.c:659 +#: command.c:1315 command.c:3246 command.c:3295 command.c:3412 input.c:227 +#: mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "mémoire épuisée" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "mémoire épuisée\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "n'a pas pu trouver l'identifiant réel %ld de l'utilisateur : %s" + +#: ../../common/username.c:45 command.c:565 +msgid "user does not exist" +msgstr "l'utilisateur n'existe pas" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "échec de la recherche du nom d'utilisateur : code erreur %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "commande non exécutable" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "commande introuvable" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "le processus fils a quitté avec le code de sortie %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "le processus fils a été terminé par l'exception 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "le processus fils a été terminé par le signal %d : %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "le processus fils a quitté avec un statut %d non reconnu" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Requête d'annulation envoyée\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "N'a pas pu envoyer la requête d'annulation : " + +#: ../../fe_utils/print.c:336 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu ligne)" +msgstr[1] "(%lu lignes)" + +#: ../../fe_utils/print.c:3039 +#, c-format +msgid "Interrupted\n" +msgstr "Interrompu\n" + +#: ../../fe_utils/print.c:3103 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "" +"Ne peut pas ajouter l'en-tête au contenu de la table : le nombre de colonnes\n" +"%d est dépassé.\n" + +#: ../../fe_utils/print.c:3143 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "" +"Ne peut pas ajouter une cellule au contenu de la table : le nombre total des\n" +"cellules %d est dépassé.\n" + +#: ../../fe_utils/print.c:3401 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "format de sortie invalide (erreur interne) : %d" + +#: ../../fe_utils/psqlscan.l:697 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "ignore l'expansion récursive de la variable « %s »" + +#: command.c:230 +#, c-format +msgid "invalid command \\%s" +msgstr "commande \\%s invalide" + +#: command.c:232 +#, c-format +msgid "Try \\? for help." +msgstr "Essayez \\? pour l'aide." + +#: command.c:250 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s : argument « %s » supplémentaire ignoré" + +#: command.c:302 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "commande \\%s ignorée ; utilisez \\endif ou Ctrl-C pour quitter le bloc \\if courant" + +#: command.c:563 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "n'a pas pu obtenir le répertoire principal pour l'identifiant d'utilisateur %ld : %s" + +#: command.c:581 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s : n'a pas pu accéder au répertoire « %s » : %m" + +#: command.c:606 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "Vous n'êtes pas connecté à une base de données.\n" + +#: command.c:616 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Vous êtes connecté à la base de données « %s » en tant qu'utilisateur « %s » à l'adresse « %s » via le port « %s ».\n" + +#: command.c:619 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Vous êtes connecté à la base de données « %s » en tant qu'utilisateur « %s » via le socket dans « %s » via le port « %s ».\n" + +#: command.c:625 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Vous êtes connecté à la base de données « %s » en tant qu'utilisateur « %s » sur l'hôte « %s » (adresse « %s ») via le port « %s ».\n" + +#: command.c:628 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Vous êtes connecté à la base de données « %s » en tant qu'utilisateur « %s » sur l'hôte « %s » via le port « %s ».\n" + +#: command.c:1012 command.c:1121 command.c:2602 +#, c-format +msgid "no query buffer" +msgstr "aucun tampon de requête" + +#: command.c:1045 command.c:5304 +#, c-format +msgid "invalid line number: %s" +msgstr "numéro de ligne invalide : %s" + +#: command.c:1112 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "Le serveur (version %s) ne supporte pas l'édition du code de la fonction." + +#: command.c:1115 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "Le serveur (version %s) ne supporte pas l'édition des définitions de vue." + +#: command.c:1197 +msgid "No changes" +msgstr "Aucun changement" + +#: command.c:1276 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s : nom d'encodage invalide ou procédure de conversion introuvable" + +#: command.c:1311 command.c:2052 command.c:3242 command.c:3434 command.c:5406 +#: common.c:174 common.c:223 common.c:392 common.c:1248 common.c:1276 +#: common.c:1385 common.c:1492 common.c:1530 copy.c:488 copy.c:709 help.c:62 +#: large_obj.c:157 large_obj.c:192 large_obj.c:254 startup.c:298 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1318 +msgid "There is no previous error." +msgstr "Il n'y a pas d'erreur précédente." + +#: command.c:1431 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: parenthèse droite manquante" + +#: command.c:1608 command.c:1913 command.c:1927 command.c:1944 command.c:2106 +#: command.c:2342 command.c:2569 command.c:2609 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s : argument requis manquant" + +#: command.c:1739 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif : ne peut pas survenir après \\else" + +#: command.c:1744 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif : pas de \\if correspondant" + +#: command.c:1808 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else : ne peut pas survenir après \\else" + +#: command.c:1813 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else : pas de \\if correspondant" + +#: command.c:1853 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif : pas de \\if correspondant" + +#: command.c:2008 +msgid "Query buffer is empty." +msgstr "Le tampon de requête est vide." + +#: command.c:2030 +msgid "Enter new password: " +msgstr "Saisissez le nouveau mot de passe : " + +#: command.c:2031 +msgid "Enter it again: " +msgstr "Saisissez-le à nouveau : " + +#: command.c:2035 +#, c-format +msgid "Passwords didn't match." +msgstr "Les mots de passe ne sont pas identiques." + +#: command.c:2135 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s : n'a pas pu lire la valeur pour la variable" + +#: command.c:2238 +msgid "Query buffer reset (cleared)." +msgstr "Le tampon de requête a été effacé." + +#: command.c:2260 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "Historique sauvegardé dans le fichier « %s ».\n" + +#: command.c:2347 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s : le nom de la variable d'environnement ne doit pas contenir « = »" + +#: command.c:2399 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "Le serveur (version %s) ne supporte pas l'affichage du code de la fonction." + +#: command.c:2402 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "Le serveur (version %s) ne supporte pas l'affichage des définitions de vues." + +#: command.c:2409 +#, c-format +msgid "function name is required" +msgstr "le nom de la fonction est requis" + +#: command.c:2411 +#, c-format +msgid "view name is required" +msgstr "le nom de la vue est requis" + +#: command.c:2541 +msgid "Timing is on." +msgstr "Chronométrage activé." + +#: command.c:2543 +msgid "Timing is off." +msgstr "Chronométrage désactivé." + +#: command.c:2628 command.c:2656 command.c:3873 command.c:3876 command.c:3879 +#: command.c:3885 command.c:3887 command.c:3913 command.c:3923 command.c:3935 +#: command.c:3949 command.c:3976 command.c:4034 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s : %m" + +#: command.c:3047 startup.c:237 startup.c:287 +msgid "Password: " +msgstr "Mot de passe : " + +#: command.c:3052 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "Mot de passe pour l'utilisateur %s : " + +#: command.c:3104 +#, c-format +msgid "Do not give user, host, or port separately when using a connection string" +msgstr "Ne pas donner utilisateur, hôte ou port lors de l'utilisation d'une chaîne de connexion" + +#: command.c:3139 +#, c-format +msgid "No database connection exists to re-use parameters from" +msgstr "Aucune connexion de base existante pour réutiliser ses paramètres" + +#: command.c:3440 +#, c-format +msgid "Previous connection kept" +msgstr "Connexion précédente conservée" + +#: command.c:3446 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect : %s" + +#: command.c:3502 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s » à l'adresse « %s » via le port « %s ».\n" + +#: command.c:3505 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s » via le socket dans « %s » via le port « %s ».\n" + +#: command.c:3511 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s » sur l'hôte « %s » (adresse « %s » ) via le port « %s ».\n" + +#: command.c:3514 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s » sur l'hôte « %s » via le port « %s ».\n" + +#: command.c:3519 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s ».\n" + +#: command.c:3559 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, serveur %s)\n" + +#: command.c:3567 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"ATTENTION : %s version majeure %s, version majeure du serveur %s.\n" +" Certaines fonctionnalités de psql pourraient ne pas fonctionner.\n" + +#: command.c:3606 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "Connexion SSL (protocole : %s, chiffrement : %s, bits : %s, compression : %s)\n" + +#: command.c:3607 command.c:3608 command.c:3609 +msgid "unknown" +msgstr "inconnu" + +#: command.c:3610 help.c:45 +msgid "off" +msgstr "désactivé" + +#: command.c:3610 help.c:45 +msgid "on" +msgstr "activé" + +#: command.c:3624 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "connexion chiffrée avec GSSAPI\n" + +#: command.c:3644 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"Attention : l'encodage console (%u) diffère de l'encodage Windows (%u).\n" +" Les caractères 8 bits peuvent ne pas fonctionner correctement.\n" +" Voir la section « Notes aux utilisateurs de Windows » de la page\n" +" référence de psql pour les détails.\n" + +#: command.c:3749 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "la variable d'environnement PSQL_EDITOR_LINENUMBER_ARG doit être définie avec un numéro de ligne" + +#: command.c:3778 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "n'a pas pu exécuter l'éditeur « %s »" + +#: command.c:3780 +#, c-format +msgid "could not start /bin/sh" +msgstr "n'a pas pu exécuter /bin/sh" + +#: command.c:3830 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "n'a pas pu localiser le répertoire temporaire : %s" + +#: command.c:3857 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier temporaire « %s » : %m" + +#: command.c:4193 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: abréviation ambigüe : « %s » correspond à « %s » comme à « %s »" + +#: command.c:4213 +#, c-format +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset : les formats autorisés sont aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" + +#: command.c:4232 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: les styles de lignes autorisés sont ascii, old-ascii, unicode" + +#: command.c:4247 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset : les styles autorisés de ligne de bordure Unicode sont single, double" + +#: command.c:4262 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset : les styles autorisés pour la ligne de colonne Unicode sont single, double" + +#: command.c:4277 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset : les styles autorisés pour la ligne d'en-tête Unicode sont single, double" + +#: command.c:4320 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep doit être un unique caractère d'un octet" + +#: command.c:4325 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldsep ne peut pas être un guillemet, un retour à la ligne ou un retour chariot" + +#: command.c:4462 command.c:4650 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset : option inconnue : %s" + +#: command.c:4482 +#, c-format +msgid "Border style is %d.\n" +msgstr "Le style de bordure est %d.\n" + +#: command.c:4488 +#, c-format +msgid "Target width is unset.\n" +msgstr "La largeur cible n'est pas configuré.\n" + +#: command.c:4490 +#, c-format +msgid "Target width is %d.\n" +msgstr "La largeur cible est %d.\n" + +#: command.c:4497 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Affichage étendu activé.\n" + +#: command.c:4499 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "L'affichage étendu est utilisé automatiquement.\n" + +#: command.c:4501 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Affichage étendu désactivé.\n" + +#: command.c:4507 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "Le séparateur de champs pour un CSV est « %s ».\n" + +#: command.c:4515 command.c:4523 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "Le séparateur de champs est l'octet zéro.\n" + +#: command.c:4517 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "Le séparateur de champs est « %s ».\n" + +#: command.c:4530 +#, c-format +msgid "Default footer is on.\n" +msgstr "Le bas de page pas défaut est activé.\n" + +#: command.c:4532 +#, c-format +msgid "Default footer is off.\n" +msgstr "Le bas de page par défaut est désactivé.\n" + +#: command.c:4538 +#, c-format +msgid "Output format is %s.\n" +msgstr "Le format de sortie est %s.\n" + +#: command.c:4544 +#, c-format +msgid "Line style is %s.\n" +msgstr "Le style de ligne est %s.\n" + +#: command.c:4551 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "L'affichage de null est « %s ».\n" + +#: command.c:4559 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "L'affichage de la sortie numérique adaptée à la locale est activé.\n" + +#: command.c:4561 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "L'affichage de la sortie numérique adaptée à la locale est désactivé.\n" + +#: command.c:4568 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Le paginateur est utilisé pour les affichages longs.\n" + +#: command.c:4570 +#, c-format +msgid "Pager is always used.\n" +msgstr "Le paginateur est toujours utilisé.\n" + +#: command.c:4572 +#, c-format +msgid "Pager usage is off.\n" +msgstr "L'utilisation du paginateur est désactivé.\n" + +#: command.c:4578 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "Le paginateur ne sera pas utilisé pour moins que %d ligne.\n" +msgstr[1] "Le paginateur ne sera pas utilisé pour moins que %d lignes.\n" + +#: command.c:4588 command.c:4598 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "Le séparateur d'enregistrements est l'octet zéro.\n" + +#: command.c:4590 +#, c-format +msgid "Record separator is .\n" +msgstr "Le séparateur d'enregistrement est .\n" + +#: command.c:4592 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "Le séparateur d'enregistrements est « %s ».\n" + +#: command.c:4605 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Les attributs de la table sont « %s ».\n" + +#: command.c:4608 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Les attributs de la table ne sont pas définis.\n" + +#: command.c:4615 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "Le titre est « %s ».\n" + +#: command.c:4617 +#, c-format +msgid "Title is unset.\n" +msgstr "Le titre n'est pas défini.\n" + +#: command.c:4624 +#, c-format +msgid "Tuples only is on.\n" +msgstr "L'affichage des tuples seuls est activé.\n" + +#: command.c:4626 +#, c-format +msgid "Tuples only is off.\n" +msgstr "L'affichage des tuples seuls est désactivé.\n" + +#: command.c:4632 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Le style de bordure Unicode est « %s ».\n" + +#: command.c:4638 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Le style de ligne Unicode est « %s ».\n" + +#: command.c:4644 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Le style d'en-tête Unicode est « %s ».\n" + +#: command.c:4877 +#, c-format +msgid "\\!: failed" +msgstr "\\! : échec" + +#: command.c:4902 common.c:652 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch ne peut pas être utilisé avec une requête vide" + +#: command.c:4943 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (chaque %gs)\n" + +#: command.c:4946 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (chaque %gs)\n" + +#: command.c:5000 command.c:5007 common.c:552 common.c:559 common.c:1231 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"******** REQUÊTE *********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:5199 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "« %s.%s » n'est pas une vue" + +#: command.c:5215 +#, c-format +msgid "could not parse reloptions array" +msgstr "n'a pas pu analyser le tableau reloptions" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "ne peut mettre entre guillemets sans connexion active" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "l'argument de la commande shell contient un retour à la ligne ou un retour chariot : « %s »" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "la connexion au serveur a été perdue" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "La connexion au serveur a été perdue. Tentative de réinitialisation : " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "Échec.\n" + +#: common.c:330 +#, c-format +msgid "Succeeded.\n" +msgstr "Succès.\n" + +#: common.c:382 common.c:949 common.c:1166 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "PQresultStatus inattendu : %d" + +#: common.c:491 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Temps : %.3f ms\n" + +#: common.c:506 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Durée : %.3f ms (%02d:%06.3f)\n" + +#: common.c:515 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Durée : %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:522 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Durée : %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:546 common.c:604 common.c:1202 +#, c-format +msgid "You are currently not connected to a database." +msgstr "Vous n'êtes pas connecté à une base de données." + +#: common.c:659 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watch ne peut pas être utilisé avec COPY" + +#: common.c:664 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "statut résultat inattendu pour \\watch" + +#: common.c:694 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "" +"Notification asynchrone « %s » reçue avec le contenu « %s » en provenance du\n" +"processus serveur de PID %d.\n" + +#: common.c:697 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "" +"Notification asynchrone « %s » reçue en provenance du processus serveur de\n" +"PID %d.\n" + +#: common.c:730 common.c:747 +#, c-format +msgid "could not print result table: %m" +msgstr "n'a pas pu imprimer la table résultante : %m" + +#: common.c:768 +#, c-format +msgid "no rows returned for \\gset" +msgstr "aucune ligne retournée pour \\gset" + +#: common.c:773 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "plus d'une ligne retournée pour \\gset" + +#: common.c:791 +#, c-format +msgid "attempt to \\gset into specially treated variable \"%s\" ignored" +msgstr "tentative ignorée d'utilisation de \\gset dans une variable traitée spécialement « %s »" + +#: common.c:1211 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(Mode étape par étape: vérifiez la commande)*********************************\n" +"%s\n" +"***(appuyez sur entrée pour l'exécuter ou tapez x puis entrée pour annuler)***\n" + +#: common.c:1266 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "Le serveur (version %s) ne supporte pas les points de sauvegarde pour ON_ERROR_ROLLBACK." + +#: common.c:1329 +#, c-format +msgid "STATEMENT: %s" +msgstr "INSTRUCTION : %s" + +#: common.c:1373 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "état de la transaction inattendu (%d)" + +#: common.c:1514 describe.c:2179 +msgid "Column" +msgstr "Colonne" + +#: common.c:1515 describe.c:178 describe.c:396 describe.c:414 describe.c:459 +#: describe.c:476 describe.c:1128 describe.c:1292 describe.c:1878 +#: describe.c:1902 describe.c:2180 describe.c:4048 describe.c:4271 +#: describe.c:4496 describe.c:5794 +msgid "Type" +msgstr "Type" + +#: common.c:1564 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "La commande n'a pas de résultats ou le résultat n'a pas de colonnes.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy : arguments requis" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy : erreur d'analyse sur « %s »" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy : erreur d'analyse à la fin de la ligne" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "n'a pas pu exécuter la commande « %s » : %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "n'a pas pu tester le fichier « %s » : %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s : ne peut pas copier depuis/vers un répertoire" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "n'a pas pu fermer le fichier pipe vers la commande externe : %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s : %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "n'a pas pu écrire les données du COPY : %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "Échec du transfert de données COPY : %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "annulé par l'utilisateur" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Saisissez les données à copier suivies d'un saut de ligne.\n" +"Terminez avec un antislash et un point seuls sur une ligne ou un signal EOF." + +#: copy.c:671 +msgid "aborted because of read failure" +msgstr "annulé du fait d'une erreur de lecture" + +#: copy.c:705 +msgid "trying to exit copy mode" +msgstr "tente de sortir du mode copy" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview : la commande n'a pas retourné d'ensemble de résultats" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview : la requête doit renvoyer au moins trois colonnes" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview : les en-têtes horizontales et verticales doivent être des colonnes différentes" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview : la colonne de données doit être spécifiée quand la requête retourne plus de trois colonnes" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview : nombre maximum de colonnes (%d) dépassé" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview : le résultat de la requête contient plusieurs valeurs de données pour la ligne « %s », colonne « %s »" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview : le numéro de colonne %d est en dehors des limites 1..%d" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview : nom de colonne ambigu : « %s »" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview : nom de colonne non trouvé : « %s »" + +#: describe.c:76 describe.c:376 describe.c:728 describe.c:924 describe.c:1120 +#: describe.c:1281 describe.c:1353 describe.c:4036 describe.c:4258 +#: describe.c:4494 describe.c:4585 describe.c:4731 describe.c:4944 +#: describe.c:5104 describe.c:5345 describe.c:5420 describe.c:5431 +#: describe.c:5493 describe.c:5918 describe.c:6001 +msgid "Schema" +msgstr "Schéma" + +#: describe.c:77 describe.c:175 describe.c:243 describe.c:251 describe.c:377 +#: describe.c:729 describe.c:925 describe.c:1038 describe.c:1121 +#: describe.c:1354 describe.c:4037 describe.c:4259 describe.c:4417 +#: describe.c:4495 describe.c:4586 describe.c:4665 describe.c:4732 +#: describe.c:4945 describe.c:5029 describe.c:5105 describe.c:5346 +#: describe.c:5421 describe.c:5432 describe.c:5494 describe.c:5691 +#: describe.c:5775 describe.c:5999 describe.c:6171 describe.c:6411 +msgid "Name" +msgstr "Nom" + +#: describe.c:78 describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "Result data type" +msgstr "Type de données du résultat" + +#: describe.c:86 describe.c:99 describe.c:103 describe.c:390 describe.c:408 +#: describe.c:454 describe.c:471 +msgid "Argument data types" +msgstr "Type de données des paramètres" + +#: describe.c:111 describe.c:118 describe.c:186 describe.c:274 describe.c:523 +#: describe.c:777 describe.c:940 describe.c:1063 describe.c:1356 +#: describe.c:2200 describe.c:3823 describe.c:4108 describe.c:4305 +#: describe.c:4448 describe.c:4522 describe.c:4595 describe.c:4678 +#: describe.c:4853 describe.c:4972 describe.c:5038 describe.c:5106 +#: describe.c:5247 describe.c:5289 describe.c:5362 describe.c:5424 +#: describe.c:5433 describe.c:5495 describe.c:5717 describe.c:5797 +#: describe.c:5932 describe.c:6002 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "Description" + +#: describe.c:136 +msgid "List of aggregate functions" +msgstr "Liste des fonctions d'agrégation" + +#: describe.c:161 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "Le serveur (version %s) ne supporte pas les méthodes d'accès." + +#: describe.c:176 +msgid "Index" +msgstr "Index" + +#: describe.c:177 describe.c:4056 describe.c:4284 describe.c:5919 +msgid "Table" +msgstr "Table" + +#: describe.c:185 describe.c:5696 +msgid "Handler" +msgstr "Gestionnaire" + +#: describe.c:204 +msgid "List of access methods" +msgstr "Liste des méthodes d'accès" + +#: describe.c:230 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "Le serveur (version %s) ne supporte pas les tablespaces." + +#: describe.c:244 describe.c:252 describe.c:504 describe.c:767 describe.c:1039 +#: describe.c:1280 describe.c:4049 describe.c:4260 describe.c:4421 +#: describe.c:4667 describe.c:5030 describe.c:5692 describe.c:5776 +#: describe.c:6172 describe.c:6309 describe.c:6412 describe.c:6535 +#: describe.c:6613 large_obj.c:289 +msgid "Owner" +msgstr "Propriétaire" + +#: describe.c:245 describe.c:253 +msgid "Location" +msgstr "Emplacement" + +#: describe.c:264 describe.c:3639 +msgid "Options" +msgstr "Options" + +#: describe.c:269 describe.c:740 describe.c:1055 describe.c:4100 +#: describe.c:4104 +msgid "Size" +msgstr "Taille" + +#: describe.c:291 +msgid "List of tablespaces" +msgstr "Liste des tablespaces" + +#: describe.c:336 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df ne prend que [anptwS+] comme options" + +#: describe.c:344 describe.c:355 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df ne prend pas d'option « %c » pour un serveur en version %s" + +#. translator: "agg" is short for "aggregate" +#: describe.c:392 describe.c:410 describe.c:456 describe.c:473 +msgid "agg" +msgstr "agg" + +#: describe.c:393 describe.c:411 +msgid "window" +msgstr "window" + +#: describe.c:394 +msgid "proc" +msgstr "proc" + +#: describe.c:395 describe.c:413 describe.c:458 describe.c:475 +msgid "func" +msgstr "func" + +#: describe.c:412 describe.c:457 describe.c:474 describe.c:1490 +msgid "trigger" +msgstr "trigger" + +#: describe.c:486 +msgid "immutable" +msgstr "immutable" + +#: describe.c:487 +msgid "stable" +msgstr "stable" + +#: describe.c:488 +msgid "volatile" +msgstr "volatile" + +#: describe.c:489 +msgid "Volatility" +msgstr "Volatibilité" + +#: describe.c:497 +msgid "restricted" +msgstr "restricted" + +#: describe.c:498 +msgid "safe" +msgstr "safe" + +#: describe.c:499 +msgid "unsafe" +msgstr "unsafe" + +#: describe.c:500 +msgid "Parallel" +msgstr "Parallèle" + +#: describe.c:505 +msgid "definer" +msgstr "definer" + +#: describe.c:506 +msgid "invoker" +msgstr "invoker" + +#: describe.c:507 +msgid "Security" +msgstr "Sécurité" + +#: describe.c:512 +msgid "Language" +msgstr "Langage" + +#: describe.c:516 describe.c:520 +msgid "Source code" +msgstr "Code source" + +#: describe.c:691 +msgid "List of functions" +msgstr "Liste des fonctions" + +#: describe.c:739 +msgid "Internal name" +msgstr "Nom interne" + +#: describe.c:761 +msgid "Elements" +msgstr "Éléments" + +#: describe.c:822 +msgid "List of data types" +msgstr "Liste des types de données" + +#: describe.c:926 +msgid "Left arg type" +msgstr "Type de l'arg. gauche" + +#: describe.c:927 +msgid "Right arg type" +msgstr "Type de l'arg. droit" + +#: describe.c:928 +msgid "Result type" +msgstr "Type du résultat" + +#: describe.c:933 describe.c:4673 describe.c:4830 describe.c:4836 +#: describe.c:5246 describe.c:6784 describe.c:6788 +msgid "Function" +msgstr "Fonction" + +#: describe.c:1010 +msgid "List of operators" +msgstr "Liste des opérateurs" + +#: describe.c:1040 +msgid "Encoding" +msgstr "Encodage" + +#: describe.c:1045 describe.c:4946 +msgid "Collate" +msgstr "Collationnement" + +#: describe.c:1046 describe.c:4947 +msgid "Ctype" +msgstr "Type caract." + +#: describe.c:1059 +msgid "Tablespace" +msgstr "Tablespace" + +#: describe.c:1081 +msgid "List of databases" +msgstr "Liste des bases de données" + +#: describe.c:1122 describe.c:1283 describe.c:4038 +msgid "table" +msgstr "table" + +#: describe.c:1123 describe.c:4039 +msgid "view" +msgstr "vue" + +#: describe.c:1124 describe.c:4040 +msgid "materialized view" +msgstr "vue matérialisée" + +#: describe.c:1125 describe.c:1285 describe.c:4042 +msgid "sequence" +msgstr "séquence" + +#: describe.c:1126 describe.c:4045 +msgid "foreign table" +msgstr "table distante" + +#: describe.c:1127 describe.c:4046 describe.c:4269 +msgid "partitioned table" +msgstr "table partitionnée" + +#: describe.c:1139 +msgid "Column privileges" +msgstr "Droits d'accès à la colonne" + +#: describe.c:1170 describe.c:1204 +msgid "Policies" +msgstr "Politiques" + +#: describe.c:1236 describe.c:6476 describe.c:6480 +msgid "Access privileges" +msgstr "Droits d'accès" + +#: describe.c:1267 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "Le serveur (version %s) ne supporte pas la modification des droits par défaut." + +#: describe.c:1287 +msgid "function" +msgstr "fonction" + +#: describe.c:1289 +msgid "type" +msgstr "type" + +#: describe.c:1291 +msgid "schema" +msgstr "schéma" + +#: describe.c:1315 +msgid "Default access privileges" +msgstr "Droits d'accès par défaut" + +#: describe.c:1355 +msgid "Object" +msgstr "Objet" + +#: describe.c:1369 +msgid "table constraint" +msgstr "contrainte de table" + +#: describe.c:1391 +msgid "domain constraint" +msgstr "contrainte de domaine" + +#: describe.c:1419 +msgid "operator class" +msgstr "classe d'opérateur" + +#: describe.c:1448 +msgid "operator family" +msgstr "famille d'opérateur" + +#: describe.c:1470 +msgid "rule" +msgstr "règle" + +#: describe.c:1512 +msgid "Object descriptions" +msgstr "Descriptions des objets" + +#: describe.c:1568 describe.c:4175 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "Aucune relation nommée « %s » n'a été trouvée." + +#: describe.c:1571 describe.c:4178 +#, c-format +msgid "Did not find any relations." +msgstr "Aucune relation n'a été trouvée." + +#: describe.c:1827 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "Aucune relation avec l'OID « %s » n'a été trouvée." + +#: describe.c:1879 describe.c:1903 +msgid "Start" +msgstr "Début" + +#: describe.c:1880 describe.c:1904 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1881 describe.c:1905 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1882 describe.c:1906 +msgid "Increment" +msgstr "Incrément" + +#: describe.c:1883 describe.c:1907 describe.c:2038 describe.c:4589 +#: describe.c:4847 describe.c:4961 describe.c:4966 describe.c:6523 +msgid "yes" +msgstr "oui" + +#: describe.c:1884 describe.c:1908 describe.c:2039 describe.c:4589 +#: describe.c:4844 describe.c:4961 describe.c:6524 +msgid "no" +msgstr "non" + +#: describe.c:1885 describe.c:1909 +msgid "Cycles?" +msgstr "Cycles ?" + +#: describe.c:1886 describe.c:1910 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1953 +#, c-format +msgid "Owned by: %s" +msgstr "Propriétaire : %s" + +#: describe.c:1957 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Séquence pour la colonne d'identité : %s" + +#: describe.c:1964 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Séquence « %s.%s »" + +#: describe.c:2111 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Table non tracée « %s.%s »" + +#: describe.c:2114 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Table « %s.%s »" + +#: describe.c:2118 +#, c-format +msgid "View \"%s.%s\"" +msgstr "Vue « %s.%s »" + +#: describe.c:2123 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Vue matérialisée non journalisée « %s.%s »" + +#: describe.c:2126 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Vue matérialisée « %s.%s »" + +#: describe.c:2131 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Index non tracé « %s.%s »" + +#: describe.c:2134 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "Index « %s.%s »" + +#: describe.c:2139 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Index partitionné non journalisé « %s.%s »" + +#: describe.c:2142 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Index partitionné « %s.%s »" + +#: describe.c:2147 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Relation spéciale « %s.%s »" + +#: describe.c:2151 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "Table TOAST « %s.%s »" + +#: describe.c:2155 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Type composé « %s.%s »" + +#: describe.c:2159 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "Table distante « %s.%s »" + +#: describe.c:2164 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Table non journalisée « %s.%s »" + +#: describe.c:2167 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Table partitionnée « %s.%s »" + +#: describe.c:2183 describe.c:4502 +msgid "Collation" +msgstr "Collationnement" + +#: describe.c:2184 describe.c:4509 +msgid "Nullable" +msgstr "NULL-able" + +#: describe.c:2185 describe.c:4510 +msgid "Default" +msgstr "Par défaut" + +#: describe.c:2188 +msgid "Key?" +msgstr "Clé ?" + +#: describe.c:2190 describe.c:4739 describe.c:4750 +msgid "Definition" +msgstr "Définition" + +#: describe.c:2192 describe.c:5712 describe.c:5796 describe.c:5867 +#: describe.c:5931 +msgid "FDW options" +msgstr "Options FDW" + +#: describe.c:2194 +msgid "Storage" +msgstr "Stockage" + +#: describe.c:2196 +msgid "Compression" +msgstr "Compression" + +#: describe.c:2198 +msgid "Stats target" +msgstr "Cible de statistiques" + +#: describe.c:2334 +#, c-format +msgid "Partition of: %s %s%s" +msgstr "Partition de : %s %s%s" + +#: describe.c:2347 +msgid "No partition constraint" +msgstr "Aucune contrainte de partition" + +#: describe.c:2349 +#, c-format +msgid "Partition constraint: %s" +msgstr "Contrainte de partition : %s" + +#: describe.c:2373 +#, c-format +msgid "Partition key: %s" +msgstr "Clé de partition : %s" + +#: describe.c:2399 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Table propriétaire : « %s.%s »" + +#: describe.c:2470 +msgid "primary key, " +msgstr "clé primaire, " + +#: describe.c:2472 +msgid "unique, " +msgstr "unique, " + +#: describe.c:2478 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "pour la table « %s.%s »" + +#: describe.c:2482 +#, c-format +msgid ", predicate (%s)" +msgstr ", prédicat (%s)" + +#: describe.c:2485 +msgid ", clustered" +msgstr ", en cluster" + +#: describe.c:2488 +msgid ", invalid" +msgstr ", invalide" + +#: describe.c:2491 +msgid ", deferrable" +msgstr ", déferrable" + +#: describe.c:2494 +msgid ", initially deferred" +msgstr ", initialement déferré" + +#: describe.c:2497 +msgid ", replica identity" +msgstr ", identité réplica" + +#: describe.c:2564 +msgid "Indexes:" +msgstr "Index :" + +#: describe.c:2648 +msgid "Check constraints:" +msgstr "Contraintes de vérification :" + +#: describe.c:2716 +msgid "Foreign-key constraints:" +msgstr "Contraintes de clés étrangères :" + +#: describe.c:2779 +msgid "Referenced by:" +msgstr "Référencé par :" + +#: describe.c:2829 +msgid "Policies:" +msgstr "Politiques :" + +#: describe.c:2832 +msgid "Policies (forced row security enabled):" +msgstr "Politiques (mode sécurité de ligne activé en forcé) :" + +#: describe.c:2835 +msgid "Policies (row security enabled): (none)" +msgstr "Politiques (mode sécurité de ligne activé) : (aucune)" + +#: describe.c:2838 +msgid "Policies (forced row security enabled): (none)" +msgstr "Politiques (mode sécurité de ligne activé en forcé) : (aucune)" + +#: describe.c:2841 +msgid "Policies (row security disabled):" +msgstr "Politiques (mode sécurité de ligne désactivé) :" + +#: describe.c:2902 describe.c:3006 +msgid "Statistics objects:" +msgstr "Objets statistiques :" + +#: describe.c:3120 describe.c:3224 +msgid "Rules:" +msgstr "Règles :" + +#: describe.c:3123 +msgid "Disabled rules:" +msgstr "Règles désactivées :" + +#: describe.c:3126 +msgid "Rules firing always:" +msgstr "Règles toujous activées :" + +#: describe.c:3129 +msgid "Rules firing on replica only:" +msgstr "Règles activées uniquement sur le réplica :" + +#: describe.c:3169 +msgid "Publications:" +msgstr "Publications :" + +#: describe.c:3207 +msgid "View definition:" +msgstr "Définition de la vue :" + +#: describe.c:3354 +msgid "Triggers:" +msgstr "Triggers :" + +#: describe.c:3358 +msgid "Disabled user triggers:" +msgstr "Triggers utilisateurs désactivés :" + +#: describe.c:3360 +msgid "Disabled triggers:" +msgstr "Triggers désactivés :" + +#: describe.c:3363 +msgid "Disabled internal triggers:" +msgstr "Triggers internes désactivés :" + +#: describe.c:3366 +msgid "Triggers firing always:" +msgstr "Triggers toujours activés :" + +#: describe.c:3369 +msgid "Triggers firing on replica only:" +msgstr "Triggers activés uniquement sur le réplica :" + +#: describe.c:3441 +#, c-format +msgid "Server: %s" +msgstr "Serveur : %s" + +#: describe.c:3449 +#, c-format +msgid "FDW options: (%s)" +msgstr "Options FDW : (%s)" + +#: describe.c:3470 +msgid "Inherits" +msgstr "Hérite de" + +#: describe.c:3543 +#, c-format +msgid "Number of partitions: %d" +msgstr "Nombre de partitions : %d" + +#: describe.c:3552 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Nombre de partitions : %d (utilisez \\d+ pour les lister)" + +#: describe.c:3554 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Nombre de tables enfants : %d (utilisez \\d+ pour les lister)" + +#: describe.c:3561 +msgid "Child tables" +msgstr "Tables enfant" + +#: describe.c:3561 +msgid "Partitions" +msgstr "Partitions" + +#: describe.c:3592 +#, c-format +msgid "Typed table of type: %s" +msgstr "Table de type : %s" + +#: describe.c:3608 +msgid "Replica Identity" +msgstr "Identité de réplicat" + +#: describe.c:3621 +msgid "Has OIDs: yes" +msgstr "Contient des OID : oui" + +#: describe.c:3630 +#, c-format +msgid "Access method: %s" +msgstr "Méthode d'accès : %s" + +#: describe.c:3710 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Tablespace : « %s »" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3722 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", tablespace « %s »" + +#: describe.c:3815 +msgid "List of roles" +msgstr "Liste des rôles" + +#: describe.c:3817 +msgid "Role name" +msgstr "Nom du rôle" + +#: describe.c:3818 +msgid "Attributes" +msgstr "Attributs" + +#: describe.c:3820 +msgid "Member of" +msgstr "Membre de" + +#: describe.c:3831 +msgid "Superuser" +msgstr "Superutilisateur" + +#: describe.c:3834 +msgid "No inheritance" +msgstr "Pas d'héritage" + +#: describe.c:3837 +msgid "Create role" +msgstr "Créer un rôle" + +#: describe.c:3840 +msgid "Create DB" +msgstr "Créer une base" + +#: describe.c:3843 +msgid "Cannot login" +msgstr "Ne peut pas se connecter" + +#: describe.c:3847 +msgid "Replication" +msgstr "Réplication" + +#: describe.c:3851 +msgid "Bypass RLS" +msgstr "Contournement RLS" + +#: describe.c:3860 +msgid "No connections" +msgstr "Sans connexions" + +#: describe.c:3862 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d connexion" +msgstr[1] "%d connexions" + +#: describe.c:3872 +msgid "Password valid until " +msgstr "Mot de passe valide jusqu'à " + +#: describe.c:3922 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "Le serveur (version %s) ne supporte pas les paramètres de rôles par bases de données." + +#: describe.c:3935 +msgid "Role" +msgstr "Rôle" + +#: describe.c:3936 +msgid "Database" +msgstr "Base de données" + +#: describe.c:3937 +msgid "Settings" +msgstr "Réglages" + +#: describe.c:3958 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "Aucune configuration pour le rôle « %s » et la base de données « %s » n'a été trouvée." + +#: describe.c:3961 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "Aucune configuration pour le rôle « %s » n'a été trouvée." + +#: describe.c:3964 +#, c-format +msgid "Did not find any settings." +msgstr "Aucune configuration n'a été trouvée." + +#: describe.c:3969 +msgid "List of settings" +msgstr "Liste des paramètres" + +#: describe.c:4041 +msgid "index" +msgstr "index" + +#: describe.c:4043 +msgid "special" +msgstr "spécial" + +#: describe.c:4044 +msgid "TOAST table" +msgstr "Table TOAST" + +#: describe.c:4047 describe.c:4270 +msgid "partitioned index" +msgstr "index partitionné" + +#: describe.c:4071 +msgid "permanent" +msgstr "permanent" + +#: describe.c:4072 +msgid "temporary" +msgstr "temporaire" + +#: describe.c:4073 +msgid "unlogged" +msgstr "non journalisé" + +#: describe.c:4074 +msgid "Persistence" +msgstr "Persistence" + +#: describe.c:4091 +msgid "Access method" +msgstr "Méthode d'accès" + +#: describe.c:4183 +msgid "List of relations" +msgstr "Liste des relations" + +#: describe.c:4231 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "Le serveur (version %s) ne supporte pas le partitionnement déclaratif des tables." + +#: describe.c:4242 +msgid "List of partitioned indexes" +msgstr "Liste des index partitionnés" + +#: describe.c:4244 +msgid "List of partitioned tables" +msgstr "Liste des tables partitionnées" + +#: describe.c:4248 +msgid "List of partitioned relations" +msgstr "Liste des relations partitionnées" + +#: describe.c:4279 +msgid "Parent name" +msgstr "Nom du parent" + +#: describe.c:4292 +msgid "Leaf partition size" +msgstr "Taille de la partition de dernier niveau" + +#: describe.c:4295 describe.c:4301 +msgid "Total size" +msgstr "Taille totale" + +#: describe.c:4425 +msgid "Trusted" +msgstr "De confiance" + +#: describe.c:4433 +msgid "Internal language" +msgstr "Langage interne" + +#: describe.c:4434 +msgid "Call handler" +msgstr "Gestionnaire d'appel" + +#: describe.c:4435 describe.c:5699 +msgid "Validator" +msgstr "Validateur" + +#: describe.c:4438 +msgid "Inline handler" +msgstr "Gestionnaire en ligne" + +#: describe.c:4466 +msgid "List of languages" +msgstr "Liste des langages" + +#: describe.c:4511 +msgid "Check" +msgstr "Vérification" + +#: describe.c:4553 +msgid "List of domains" +msgstr "Liste des domaines" + +#: describe.c:4587 +msgid "Source" +msgstr "Source" + +#: describe.c:4588 +msgid "Destination" +msgstr "Destination" + +#: describe.c:4590 describe.c:6525 +msgid "Default?" +msgstr "Par défaut ?" + +#: describe.c:4627 +msgid "List of conversions" +msgstr "Liste des conversions" + +#: describe.c:4666 +msgid "Event" +msgstr "Événement" + +#: describe.c:4668 +msgid "enabled" +msgstr "activé" + +#: describe.c:4669 +msgid "replica" +msgstr "réplicat" + +#: describe.c:4670 +msgid "always" +msgstr "toujours" + +#: describe.c:4671 +msgid "disabled" +msgstr "désactivé" + +#: describe.c:4672 describe.c:6413 +msgid "Enabled" +msgstr "Activé" + +#: describe.c:4674 +msgid "Tags" +msgstr "Tags" + +#: describe.c:4693 +msgid "List of event triggers" +msgstr "Liste des triggers sur évènement" + +#: describe.c:4720 +#, c-format +msgid "The server (version %s) does not support extended statistics." +msgstr "Le serveur (version %s) ne supporte pas les statistiques étendues." + +#: describe.c:4757 +msgid "Ndistinct" +msgstr "Ndistinct" + +#: describe.c:4758 +msgid "Dependencies" +msgstr "Dépendances" + +#: describe.c:4768 +msgid "MCV" +msgstr "MCV" + +#: describe.c:4787 +msgid "List of extended statistics" +msgstr "Liste des statistiques étendues" + +#: describe.c:4814 +msgid "Source type" +msgstr "Type source" + +#: describe.c:4815 +msgid "Target type" +msgstr "Type cible" + +#: describe.c:4846 +msgid "in assignment" +msgstr "assigné" + +#: describe.c:4848 +msgid "Implicit?" +msgstr "Implicite ?" + +#: describe.c:4903 +msgid "List of casts" +msgstr "Liste des conversions explicites" + +#: describe.c:4931 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "Le serveur (version %s) ne supporte pas les collationnements." + +#: describe.c:4952 describe.c:4956 +msgid "Provider" +msgstr "Fournisseur" + +#: describe.c:4962 describe.c:4967 +msgid "Deterministic?" +msgstr "Déterministe ?" + +#: describe.c:5002 +msgid "List of collations" +msgstr "Liste des collationnements" + +#: describe.c:5061 +msgid "List of schemas" +msgstr "Liste des schémas" + +#: describe.c:5086 describe.c:5333 describe.c:5404 describe.c:5475 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "Le serveur (version %s) ne supporte pas la recherche plein texte." + +#: describe.c:5121 +msgid "List of text search parsers" +msgstr "Liste des analyseurs de la recherche de texte" + +#: describe.c:5166 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "Aucun analyseur de la recherche de texte nommé « %s » n'a été trouvé." + +#: describe.c:5169 +#, c-format +msgid "Did not find any text search parsers." +msgstr "Aucun analyseur de recherche de texte n'a été trouvé." + +#: describe.c:5244 +msgid "Start parse" +msgstr "Début de l'analyse" + +#: describe.c:5245 +msgid "Method" +msgstr "Méthode" + +#: describe.c:5249 +msgid "Get next token" +msgstr "Obtenir le prochain jeton" + +#: describe.c:5251 +msgid "End parse" +msgstr "Fin de l'analyse" + +#: describe.c:5253 +msgid "Get headline" +msgstr "Obtenir l'en-tête" + +#: describe.c:5255 +msgid "Get token types" +msgstr "Obtenir les types de jeton" + +#: describe.c:5266 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Analyseur « %s.%s » de la recherche de texte" + +#: describe.c:5269 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "Analyseur « %s » de la recherche de texte" + +#: describe.c:5288 +msgid "Token name" +msgstr "Nom du jeton" + +#: describe.c:5299 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "Types de jeton pour l'analyseur « %s.%s »" + +#: describe.c:5302 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "Types de jeton pour l'analyseur « %s »" + +#: describe.c:5356 +msgid "Template" +msgstr "Modèle" + +#: describe.c:5357 +msgid "Init options" +msgstr "Options d'initialisation" + +#: describe.c:5379 +msgid "List of text search dictionaries" +msgstr "Liste des dictionnaires de la recherche de texte" + +#: describe.c:5422 +msgid "Init" +msgstr "Initialisation" + +#: describe.c:5423 +msgid "Lexize" +msgstr "Lexize" + +#: describe.c:5450 +msgid "List of text search templates" +msgstr "Liste des modèles de la recherche de texte" + +#: describe.c:5510 +msgid "List of text search configurations" +msgstr "Liste des configurations de la recherche de texte" + +#: describe.c:5556 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "Aucune configuration de la recherche de texte nommée « %s » n'a été trouvée." + +#: describe.c:5559 +#, c-format +msgid "Did not find any text search configurations." +msgstr "Aucune configuration de recherche de texte n'a été trouvée." + +#: describe.c:5625 +msgid "Token" +msgstr "Jeton" + +#: describe.c:5626 +msgid "Dictionaries" +msgstr "Dictionnaires" + +#: describe.c:5637 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Configuration « %s.%s » de la recherche de texte" + +#: describe.c:5640 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Configuration « %s » de la recherche de texte" + +#: describe.c:5644 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Analyseur : « %s.%s »" + +#: describe.c:5647 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Analyseur : « %s »" + +#: describe.c:5681 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "Le serveur (version %s) ne supporte pas les wrappers de données distantes." + +#: describe.c:5739 +msgid "List of foreign-data wrappers" +msgstr "Liste des wrappers de données distantes" + +#: describe.c:5764 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "Le serveur (version %s) ne supporte pas les serveurs distants." + +#: describe.c:5777 +msgid "Foreign-data wrapper" +msgstr "Wrapper des données distantes" + +#: describe.c:5795 describe.c:6000 +msgid "Version" +msgstr "Version" + +#: describe.c:5821 +msgid "List of foreign servers" +msgstr "Liste des serveurs distants" + +#: describe.c:5846 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "Le serveur (version %s) ne supporte pas les correspondances d'utilisateurs." + +#: describe.c:5856 describe.c:5920 +msgid "Server" +msgstr "Serveur" + +#: describe.c:5857 +msgid "User name" +msgstr "Nom de l'utilisateur" + +#: describe.c:5882 +msgid "List of user mappings" +msgstr "Liste des correspondances utilisateurs" + +#: describe.c:5907 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "Le serveur (version %s) ne supporte pas les tables distantes." + +#: describe.c:5960 +msgid "List of foreign tables" +msgstr "Liste des tables distantes" + +#: describe.c:5985 describe.c:6042 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "Le serveur (version %s) ne supporte pas les extensions." + +#: describe.c:6017 +msgid "List of installed extensions" +msgstr "Liste des extensions installées" + +#: describe.c:6070 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "Aucune extension nommée « %s » n'a été trouvée." + +#: describe.c:6073 +#, c-format +msgid "Did not find any extensions." +msgstr "Aucune extension n'a été trouvée." + +#: describe.c:6117 +msgid "Object description" +msgstr "Description d'objet" + +#: describe.c:6127 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "Objets dans l'extension « %s »" + +#: describe.c:6156 describe.c:6232 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "Le serveur (version %s) ne supporte pas les publications." + +#: describe.c:6173 describe.c:6310 +msgid "All tables" +msgstr "Toutes les tables" + +#: describe.c:6174 describe.c:6311 +msgid "Inserts" +msgstr "Insertions" + +#: describe.c:6175 describe.c:6312 +msgid "Updates" +msgstr "Mises à jour" + +#: describe.c:6176 describe.c:6313 +msgid "Deletes" +msgstr "Suppressions" + +#: describe.c:6180 describe.c:6315 +msgid "Truncates" +msgstr "Tronque" + +#: describe.c:6184 describe.c:6317 +msgid "Via root" +msgstr "Via la racine" + +#: describe.c:6201 +msgid "List of publications" +msgstr "Liste des publications" + +#: describe.c:6274 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "Aucune publication nommée « %s » n'a été trouvée." + +#: describe.c:6277 +#, c-format +msgid "Did not find any publications." +msgstr "Aucune publication n'a été trouvée." + +#: describe.c:6306 +#, c-format +msgid "Publication %s" +msgstr "Publication %s" + +#: describe.c:6354 +msgid "Tables:" +msgstr "Tables :" + +#: describe.c:6398 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "Le serveur (version %s) ne supporte pas les souscriptions." + +#: describe.c:6414 +msgid "Publication" +msgstr "Publication" + +#: describe.c:6423 +msgid "Binary" +msgstr "Binaire" + +#: describe.c:6424 +msgid "Streaming" +msgstr "Flux" + +#: describe.c:6429 +msgid "Synchronous commit" +msgstr "Validation synchrone" + +#: describe.c:6430 +msgid "Conninfo" +msgstr "Informations de connexion" + +#: describe.c:6452 +msgid "List of subscriptions" +msgstr "Liste des souscriptions" + +#: describe.c:6519 describe.c:6607 describe.c:6692 describe.c:6775 +msgid "AM" +msgstr "AM" + +#: describe.c:6520 +msgid "Input type" +msgstr "Type en entrée" + +#: describe.c:6521 +msgid "Storage type" +msgstr "Type de stockage" + +#: describe.c:6522 +msgid "Operator class" +msgstr "Classe d'opérateur" + +#: describe.c:6534 describe.c:6608 describe.c:6693 describe.c:6776 +msgid "Operator family" +msgstr "Famille d'opérateur" + +#: describe.c:6566 +msgid "List of operator classes" +msgstr "Liste des classes d'opérateurs" + +#: describe.c:6609 +msgid "Applicable types" +msgstr "Types applicables" + +#: describe.c:6647 +msgid "List of operator families" +msgstr "Liste des familles d'opérateurs" + +#: describe.c:6694 +msgid "Operator" +msgstr "Opérateur" + +#: describe.c:6695 +msgid "Strategy" +msgstr "Stratégie" + +#: describe.c:6696 +msgid "ordering" +msgstr "ordre" + +#: describe.c:6697 +msgid "search" +msgstr "recherche" + +#: describe.c:6698 +msgid "Purpose" +msgstr "But" + +#: describe.c:6703 +msgid "Sort opfamily" +msgstr "Tri famille d'opérateur" + +#: describe.c:6734 +msgid "List of operators of operator families" +msgstr "Liste d'opérateurs des familles d'opérateurs" + +#: describe.c:6777 +msgid "Registered left type" +msgstr "Type de l'arg. gauche enregistré" + +#: describe.c:6778 +msgid "Registered right type" +msgstr "Type de l'arg. droit enregistré" + +#: describe.c:6779 +msgid "Number" +msgstr "Numéro" + +#: describe.c:6815 +msgid "List of support functions of operator families" +msgstr "Liste des fonctions de support des familles d'opérateurs" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql est l'interface interactive de PostgreSQL.\n" +"\n" + +#: help.c:74 help.c:355 help.c:433 help.c:476 +#, c-format +msgid "Usage:\n" +msgstr "Usage :\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [OPTIONS]... [NOM_BASE [NOM_UTILISATEUR]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Options générales :\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr "" +" -c, --command=COMMANDE\n" +" exécute une commande unique (SQL ou interne), puis quitte\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr "" +" -d, --dbname=NOM_BASE\n" +" indique le nom de la base de données à laquelle se\n" +" connecter (par défaut : « %s »)\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr "" +" -f, --file=FICHIER\n" +" exécute les commandes du fichier, puis quitte\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, --list affiche les bases de données disponibles, puis quitte\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=NOM=VALEUR\n" +" configure la variable psql NOM en VALEUR\n" +" (e.g., -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc ne lit pas le fichier de démarrage (~/.psqlrc)\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 (« un »), --single-transaction\n" +" exécute dans une transaction unique (si non intéractif)\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] affiche cette aide et quitte\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commandes liste les méta-commandes, puis quitte\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables liste les variables spéciales, puis quitte\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Options d'entrée/sortie :\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all affiche les lignes du script\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors affiche les commandes échouées\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr "" +" -e, --echo-queries\n" +" affiche les commandes envoyées au serveur\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr "" +" -E, --echo-hidden\n" +" affiche les requêtes engendrées par les commandes internes\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr "" +" -L, --log-file=FICHIER\n" +" envoie les traces dans le fichier\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr "" +" -n, --no-readline\n" +" désactive l'édition avancée de la ligne de commande\n" +" (readline)\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr "" +" -o, --output=FICHIER\n" +" écrit les résultats des requêtes dans un fichier (ou\n" +" |tube)\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr "" +" -q, --quiet s'exécute silencieusement (pas de messages, uniquement le\n" +" résultat des requêtes)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr "" +" -s, --single-step\n" +" active le mode étape par étape (confirmation pour chaque\n" +" requête)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr "" +" -S, --single-line\n" +" active le mode ligne par ligne (EOL termine la commande\n" +" SQL)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Options de formattage de la sortie :\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr "" +" -A, --no-align active le mode d'affichage non aligné des tables (-P\n" +" format=unaligned)\n" + +#: help.c:111 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr "" +" --csv mode d'affichage CSV (valeurs séparées par des virgules)\n" +"\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, --field-separator=CHAINE\n" +" séparateur de champs pour un affichage non aligné\n" +" (par défaut : « %s »)\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html active le mode d'affichage HTML des tables (-P format=html)\n" + +#: help.c:116 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr "" +" -P, --pset=VAR[=ARG]\n" +" initialise l'option d'impression VAR à ARG (voir la\n" +" commande \\pset)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, --record-separator=CHAINE\n" +" séparateur d'enregistrements pour un affichage non aligné\n" +" (par défaut : saut de ligne)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr "" +" -t, --tuples-only\n" +" affiche seulement les lignes (-P tuples_only)\n" + +#: help.c:120 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr "" +" -T, --table-attr=TEXTE\n" +" initialise les attributs des balises HTML de tableau\n" +" (largeur, bordure) (-P tableattr=)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded active l'affichage étendu des tables (-P expanded)\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" initialise le séparateur de champs pour un affichage non\n" +" aligné à l'octet zéro\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" initialise le séparateur d'enregistrements pour un affichage\n" +" non aligné à l'octet zéro\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Options de connexion :\n" + +#: help.c:130 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr "" +" -h, --host=HOTE nom d'hôte du serveur de la base de données ou répertoire\n" +" de la socket (par défaut : %s)\n" + +#: help.c:131 +msgid "local socket" +msgstr "socket locale" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr "" +" -p, --port=PORT port du serveur de la base de données (par défaut :\n" +" « %s »)\n" + +#: help.c:137 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr "" +" -U, --username=NOM\n" +" nom d'utilisateur de la base de données (par défaut :\n" +" « %s »)\n" + +#: help.c:138 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr "" +" -w, --no-password\n" +" ne demande jamais un mot de passe\n" + +#: help.c:139 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr "" +" -W, --password force la demande du mot de passe (devrait survenir\n" +" automatiquement)\n" + +#: help.c:141 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"Pour en savoir davantage, saisissez « \\? » (pour les commandes internes) ou\n" +"« \\help » (pour les commandes SQL) dans psql, ou consultez la section psql\n" +"de la documentation de PostgreSQL.\n" +"\n" + +#: help.c:144 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Rapporter les bogues à <%s>.\n" + +#: help.c:145 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "page d'accueil de %s : <%s>\n" + +#: help.c:171 +#, c-format +msgid "General\n" +msgstr "Général\n" + +#: help.c:172 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr "" +" \\copyright affiche les conditions d'utilisation et de\n" +" distribution de PostgreSQL\n" + +#: help.c:173 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [COLUMNS] exécute la requête et affiche le résultat dans un tableau croisé\n" + +#: help.c:174 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose affiche le message d'erreur le plus récent avec une verbosité maximale\n" + +#: help.c:175 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(OPTIONS)] [FICHIER] exécute la requête (et envoie les résultats à un fichier ou à |pipe);\n" +" \\g sans arguments est équivalent à un point-virgule\n" + +#: help.c:177 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc décrit le résultat de la requête sans l'exécuter\n" + +#: help.c:178 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr " \\gexec exécute la requête et exécute chaque valeur du résultat\n" + +#: help.c:179 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PRÉFIXE] exécute la requête et stocke les résultats dans des variables psql\n" + +#: help.c:180 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [(OPTIONS)] [FICHIER] comme \\g, mais force le mode de sortie étendu\n" + +#: help.c:181 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q quitte psql\n" + +#: help.c:182 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SEC] exécute la requête toutes les SEC secondes\n" + +#: help.c:185 +#, c-format +msgid "Help\n" +msgstr "Aide\n" + +#: help.c:187 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commandes] affiche l'aide sur les métacommandes\n" + +#: help.c:188 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? options affiche l'aide sur les options en ligne de commande de psql\n" + +#: help.c:189 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables affiche l'aide sur les variables spéciales\n" + +#: help.c:190 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr "" +" \\h [NOM] aide-mémoire pour les commandes SQL, * pour toutes\n" +" les commandes\n" + +#: help.c:193 +#, c-format +msgid "Query Buffer\n" +msgstr "Tampon de requête\n" + +#: help.c:194 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr "" +" \\e [FICHIER] [LIGNE] édite le tampon de requête ou le fichier avec un\n" +" éditeur externe\n" + +#: help.c:195 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr "" +" \\ef [FONCTION [LIGNE]] édite la définition de fonction avec un éditeur\n" +" externe\n" + +#: help.c:196 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr "" +" \\ev [VUE [LIGNE]] édite la définition de vue avec un éditeur\n" +" externe\n" + +#: help.c:197 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p affiche le contenu du tampon de requête\n" + +#: help.c:198 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r efface le tampon de requêtes\n" + +#: help.c:200 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr "" +" \\s [FICHIER] affiche l'historique ou le sauvegarde dans un\n" +" fichier\n" + +#: help.c:202 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr "" +" \\w [FICHIER] écrit le contenu du tampon de requêtes dans un\n" +" fichier\n" + +#: help.c:205 +#, c-format +msgid "Input/Output\n" +msgstr "Entrée/Sortie\n" + +#: help.c:206 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr "" +" \\copy ... exécute SQL COPY avec le flux de données dirigé vers\n" +" l'hôte client\n" + +#: help.c:207 +#, c-format +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr " \\echo [-n] [TEXTE] écrit le texte sur la sortie standard (-n pour supprimer le retour à la ligne)\n" + +#: help.c:208 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i FICHIER exécute les commandes du fichier\n" + +#: help.c:209 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr "" +" \\ir FICHIER identique à \\i, mais relatif à l'emplacement du script\n" +" ou un |tube\n" + +#: help.c:210 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr "" +" \\o [FICHIER] envoie les résultats de la requête vers un fichier\n" +" ou un |tube\n" + +#: help.c:211 +#, c-format +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr "" +" \\qecho [-n] [TEXTE] écrit un texte sur la sortie des résultats des\n" +" requêtes (\\o) (-n pour supprimer le retour à la ligne)\n" + +#: help.c:212 +#, c-format +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr " \\warn [-n] [TEXTE] écrit le texte sur la sortie des erreurs (-n pour supprimer le retour à la ligne)\n" + +#: help.c:215 +#, c-format +msgid "Conditional\n" +msgstr "Conditionnel\n" + +#: help.c:216 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR début du bloc conditionnel\n" + +#: help.c:217 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif alternative à l'intérieur du bloc conditionnel courant\n" + +#: help.c:218 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else alternative finale à l'intérieur du bloc conditionnel courant\n" + +#: help.c:219 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif bloc conditionnel de fin\n" + +#: help.c:222 +#, c-format +msgid "Informational\n" +msgstr "Informations\n" + +#: help.c:223 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (options : S = affiche les objets systèmes, + = informations supplémentaires)\n" + +#: help.c:224 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] affiche la liste des tables, vues et séquences\n" + +#: help.c:225 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr "" +" \\d[S+] NOM affiche la description de la table, de la vue,\n" +" de la séquence ou de l'index\n" + +#: help.c:226 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [MODÈLE] affiche les aggrégats\n" + +#: help.c:227 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [MODÈLE] affiche la liste des méthodes d'accès\n" + +#: help.c:228 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] affiche les classes d'opérateurs\n" + +#: help.c:229 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] affiche les familles d'opérateur\n" + +#: help.c:230 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] affiche les opérateurs des familles d'opérateur\n" + +#: help.c:231 +#, c-format +msgid " \\dAp[+] [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp[+] [AMPTRN [OPFPTRN]] liste les fonctions de support des familles d'opérateur\n" + +#: help.c:232 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [MODÈLE] affiche la liste des tablespaces\n" + +#: help.c:233 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [MODÈLE] affiche la liste des conversions\n" + +#: help.c:234 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [MODÈLE] affiche la liste des transtypages\n" + +#: help.c:235 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr "" +" \\dd[S] [MODÈLE] affiche les commentaires des objets dont le commentaire\n" +" n'est affiché nul part ailleurs\n" + +#: help.c:236 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [MODÈLE] affiche la liste des domaines\n" + +#: help.c:237 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [MODÈLE] affiche les droits par défaut\n" + +#: help.c:238 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [MODÈLE] affiche la liste des tables distantes\n" + +#: help.c:239 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [MODÈLE] affiche la liste des tables distantes\n" + +#: help.c:240 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [MODÈLE] affiche la liste des serveurs distants\n" + +#: help.c:241 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [MODÈLE] affiche la liste des correspondances utilisateurs\n" + +#: help.c:242 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [MODÈLE] affiche la liste des wrappers de données distantes\n" + +#: help.c:243 +#, c-format +msgid "" +" \\df[anptw][S+] [FUNCPTRN [TYPEPTRN ...]]\n" +" list [only agg/normal/procedure/trigger/window] functions\n" +msgstr "" +" \\df[anptw][S+] [FUNCPTRN [TYPEPTRN ...]]\n" +" affiche la liste des fonctions [seulement agrégat/normal/procédure/trigger/window]\n" + +#: help.c:245 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr "" +" \\dF[+] [MODÈLE] affiche la liste des configurations de la recherche\n" +" plein texte\n" + +#: help.c:246 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr "" +" \\dFd[+] [MODÈLE] affiche la liste des dictionnaires de la recherche de\n" +" texte\n" + +#: help.c:247 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr "" +" \\dFp[+] [MODÈLE] affiche la liste des analyseurs de la recherche de\n" +" texte\n" + +#: help.c:248 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr "" +" \\dFt[+] [MODÈLE] affiche la liste des modèles de la recherche de\n" +" texte\n" + +#: help.c:249 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [MODÈLE] affiche la liste des rôles (utilisateurs)\n" + +#: help.c:250 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [MODÈLE] affiche la liste des index\n" + +#: help.c:251 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr "" +" \\dl affiche la liste des « Large Objects », identique à\n" +" \\lo_list\n" + +#: help.c:252 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [MODÈLE] affiche la liste des langages procéduraux\n" + +#: help.c:253 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [MODÈLE] affiche la liste des vues matérialisées\n" + +#: help.c:254 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [MODÈLE] affiche la liste des schémas\n" + +#: help.c:255 +#, c-format +msgid "" +" \\do[S+] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" +" list operators\n" +msgstr "" +" \\do[S+] [OPPTRN [TYPEPTRN [TYPEPTRN]]]\n" +" affiche la liste des opérateurs\n" + +#: help.c:257 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [MODÈLE] affiche la liste des collationnements\n" + +#: help.c:258 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr "" +" \\dp [MODÈLE] affiche la liste des droits d'accès aux tables,\n" +" vues, séquences\n" + +#: help.c:259 +#, c-format +msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" +msgstr " \\dP[itn+] [PATTERN] affiche les relations partitionnées [seulement index/table] [n=imbriquées]\n" + +#: help.c:260 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [MODEL1 [MODEL2]] liste la configuration utilisateur par base de données\n" + +#: help.c:261 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[S+] [MODÈLE] affiche la liste des publications de réplication\n" + +#: help.c:262 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [MODÈLE] affiche la liste des souscriptions de réplication\n" + +#: help.c:263 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [MODÈLE] affiche la liste des séquences\n" + +#: help.c:264 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [MODÈLE] affiche la liste des tables\n" + +#: help.c:265 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [MODÈLE] affiche la liste des types de données\n" + +#: help.c:266 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [MODÈLE] affiche la liste des rôles (utilisateurs)\n" + +#: help.c:267 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [MODÈLE] affiche la liste des vues\n" + +#: help.c:268 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [MODÈLE] affiche la liste des extensions\n" + +#: help.c:269 +#, c-format +msgid " \\dX [PATTERN] list extended statistics\n" +msgstr " \\dX [MODÈLE] affiche les statistiques étendues\n" + +#: help.c:270 +#, c-format +msgid " \\dy[+] [PATTERN] list event triggers\n" +msgstr " \\dy[+] [MODÈLE] affiche les triggers sur évènement\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [MODÈLE] affiche la liste des bases de données\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] [FONCTION] édite la définition d'une fonction\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv [FONCTION] édite la définition d'une vue\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [MODÈLE] identique à \\dp\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "Formatage\n" + +#: help.c:278 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr "" +" \\a bascule entre les modes de sortie alignée et non\n" +" alignée\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr "" +" \\C [CHAÎNE] initialise le titre d'une table, ou le désactive en\n" +" l'absence d'argument\n" + +#: help.c:280 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr "" +" \\f [CHAÎNE] affiche ou initialise le séparateur de champ pour\n" +" une sortie non alignée des requêtes\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H bascule le mode de sortie HTML (actuellement %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [NOM [VALEUR]] règle l'affichage de la table\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t affiche uniquement les lignes (actuellement %s)\n" + +#: help.c:292 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr "" +" \\T [CHAÎNE] initialise les attributs HTML de la balise
,\n" +" ou l'annule en l'absence d'argument\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] bascule l'affichage étendu (actuellement %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "Connexions\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[NOM_BASE|- UTILISATEUR|- HOTE|- PORT|-] | conninfo}\n" +" se connecte à une autre base de données\n" +" (actuellement « %s »)\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[NOM_BASE|- UTILISATEUR|- HOTE|- PORT|-] | conninfo}\n" +" se connecte à une nouvelle base de données\n" +" (aucune connexion actuellement)\n" + +#: help.c:305 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo affiche des informations sur la connexion en cours\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [ENCODAGE] affiche ou initialise l'encodage du client\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr "" +" \\password [UTILISATEUR]\n" +" modifie de façon sécurisé le mot de passe d'un\n" +" utilisateur\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "Système d'exploitation\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [RÉPERTOIRE] change de répertoire de travail\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv NOM [VALEUR] (dés)initialise une variable d'environnement\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr "" +" \\timing [on|off] bascule l'activation du chronométrage des commandes\n" +" (actuellement %s)\n" + +#: help.c:315 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr "" +" \\! [COMMANDE] exécute la commande dans un shell ou exécute un\n" +" shell interactif\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "Variables\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr "" +" \\prompt [TEXTE] NOM demande à l'utilisateur de configurer la variable\n" +" interne\n" + +#: help.c:320 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr "" +" \\set [NOM [VALEUR]] initialise une variable interne ou les affiche\n" +" toutes en l'absence de paramètre\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset NOM désactive (supprime) la variable interne\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "« Large objects »\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export OIDLOB FICHIER\n" +" \\lo_import FICHIER [COMMENTAIRE]\n" +" \\lo_list\n" +" \\lo_unlink OIDLOB\n" +" opérations sur les « Large Objects »\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"Liste des variables traitées spécialement\n" +"\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "variables psql :\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=NOM=VALEUR\n" +" ou \\set NOM VALEUR dans psql\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" si activé, les commandes SQL réussies sont automatiquement validées\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" détermine la casse utilisée pour compléter les mots clés SQL\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" le nom de base de données actuel\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" contrôle ce qui est envoyé sur la sortie standard\n" +" [all, errors, none, queries]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" si activé, affiche les requêtes internes exécutées par les méta-commandes ;\n" +" si configuré à « noexec », affiche les requêtes sans les exécuter\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" encodage du jeu de caractères client\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" true si la dernière requête a échoué, sinon false\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" le nombre de lignes résultats à récupérer et à afficher à la fois\n" +" (0 pour illimité)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" si activé, les méthodes d'accès ne sont pas affichées\n" + +#: help.c:379 +#, c-format +msgid "" +" HIDE_TOAST_COMPRESSION\n" +" if set, compression methods are not displayed\n" +msgstr "" +" HIDE_TOAST_COMPRESSION\n" +" si activé, les méthodes de compression methods ne sont pas affichées\n" +"\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" contrôle l'historique des commandes [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" nom du fichier utilisé pour stocker l'historique des commandes\n" + +#: help.c:385 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" nombre maximum de commandes à stocker dans l'historique de commandes\n" + +#: help.c:387 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" l'hôte de la base de données\n" + +#: help.c:389 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" nombre d'EOF nécessaire pour terminer une session interactive\n" + +#: help.c:391 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" valeur du dernier OID affecté\n" + +#: help.c:393 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message et SQLSTATE de la dernière erreur ou une chaîne vide et \"00000\" if si aucune erreur\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" si activé, une erreur n'arrête pas une transaction (utilise des savepoints implicites)\n" + +#: help.c:398 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" arrête l'exécution d'un batch après une erreur\n" + +#: help.c:400 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" port du serveur pour la connexion actuelle\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" spécifie l'invite standard de psql\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" spécifie l'invite utilisé quand une requête continue après la ligne courante\n" + +#: help.c:406 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" spécifie l'invite utilisée lors d'un COPY ... FROM STDIN\n" + +#: help.c:408 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" s'exécute en silence (identique à l'option -q)\n" + +#: help.c:410 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" nombre de lignes renvoyées ou affectées par la dernière requête, ou 0\n" + +#: help.c:412 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" version du serveur (chaîne courte ou format numérique)\n" + +#: help.c:415 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" contrôle l'affichage des champs de contexte du message [never, errors, always]\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" une fin de ligne termine le mode de commande SQL (identique à l'option -S)\n" + +#: help.c:419 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" mode pas à pas (identique à l'option -s)\n" + +#: help.c:421 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE de la dernière requête, ou \"00000\" si aucune erreur\n" + +#: help.c:423 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" l'utilisateur actuellement connecté\n" + +#: help.c:425 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" contrôle la verbosité des rapports d'erreurs [default, verbose, terse, sqlstate]\n" + +#: help.c:427 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" version de psql (chaîne longue, chaîne courte, ou format numérique)\n" + +#: help.c:432 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Paramètres d'affichage :\n" + +#: help.c:434 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NOM[=VALEUR]\n" +" ou \\pset NOM [VALEUR] dans psql\n" +"\n" + +#: help.c:436 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" style de bordure (nombre)\n" + +#: help.c:438 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" largeur cible pour le format encadré\n" + +#: help.c:440 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (ou x)\n" +" sortie étendue [on, off, auto]\n" + +#: help.c:442 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" champ séparateur pour l'affichage non aligné (par défaut « %s »)\n" + +#: help.c:445 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" configure le séparateur de champ pour l'affichage non alignée à l'octet zéro\n" + +#: help.c:447 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" active ou désactive l'affiche du bas de tableau [on, off]\n" + +#: help.c:449 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" active le format de sortie [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:451 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" configure l'affichage des lignes de bordure [ascii, old-ascii, unicode]\n" + +#: help.c:453 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" configure la chaîne à afficher à la place d'une valeur NULL\n" + +#: help.c:455 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +" numericlocale\n" +" active ou désactive l'affichage d'un caractère spécifique à la locale pour séparer\n" +" des groupes de chiffres [on, off]\n" + +#: help.c:457 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" contrôle quand un paginateur externe est utilisé [yes, no, always]\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" enregistre le séparateur de ligne pour les affichages non alignés\n" + +#: help.c:461 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" initialise le séparateur d'enregistrements pour un affichage\n" +" non aligné à l'octet zéro\n" + +#: help.c:463 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (ou T)\n" +" indique les attributs pour la balise de table dans le format html ou les largeurs\n" +" proportionnelles de colonnes pour les types de données alignés à gauche dans le\n" +" format latex-longtable\n" + +#: help.c:466 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" configure le titre de la table pour toute table affichée\n" + +#: help.c:468 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" si activé, seules les données de la table sont affichées\n" + +#: help.c:470 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" configure le style d'affichage de ligne Unicode [single, double]\n" + +#: help.c:475 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Variables d'environnement :\n" + +#: help.c:479 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NOM=VALEUR [NOM=VALEUR] psql ...\n" +" ou \\setenv NOM [VALEUR] dans psql\n" +"\n" + +#: help.c:481 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NOM=VALEUR\n" +" psql ...\n" +" ou \\setenv NOM [VALEUR] dans psql\n" +"\n" + +#: help.c:484 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" nombre de colonnes pour le format encadré\n" + +#: help.c:486 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" identique au paramètre de connexion application_name\n" + +#: help.c:488 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" identique au paramètre de connexion dbname\n" + +#: help.c:490 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" identique au paramètre de connexion host\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" nom du fichier de mot de passe\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" mot de passe de connexion (non recommendé)\n" + +#: help.c:496 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" identique au paramètre de connexion port\n" + +#: help.c:498 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" identique au paramètre de connexion user\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" éditeur utilisé par les commandes \\e, \\ef et \\ev\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" comment spécifier un numéro de ligne lors de l'appel de l'éditeur\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" autre emplacement pour le fichier d'historique des commandes\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" nom du paginateur externe\n" + +#: help.c:508 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" autre emplacement pour le fichier .psqlrc de l'utilisateur\n" + +#: help.c:510 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" shell utilisé par la commande \\!\n" + +#: help.c:512 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" répertoire pour les fichiers temporaires\n" + +#: help.c:557 +msgid "Available help:\n" +msgstr "Aide-mémoire disponible :\n" + +#: help.c:652 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"Commande : %s\n" +"Description : %s\n" +"Syntaxe :\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" + +#: help.c:675 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"Aucun aide-mémoire disponible pour « %s ».\n" +"Essayez \\h sans arguments pour afficher les aide-mémoires disponibles.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "n'a pas pu lire à partir du fichier en entrée : %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "n'a pas pu sauvegarder l'historique dans le fichier « %s » : %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "l'historique n'est pas supportée par cette installation" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s : non connecté à une base de données" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s : la transaction en cours est abandonnée" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s : état de la transaction inconnu" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "« Large objects »" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if : échappé" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "Saisissez « \\q » pour quitter %s.\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Les données en entrée proviennent d'une sauvegarde PostgreSQL au format custom.\n" +"Utilisez l'outil en ligne de commande pg_restore pour restaurer cette sauvegarde dans une base de données.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Utilisez \\? pour l'aide ou appuyez sur control-C pour vider le tampon de saisie." + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "Utilisez \\? pour l'aide." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "Vous utilisez psql, l'interface en ligne de commande de PostgreSQL." + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Saisissez:\n" +" \\copyright pour les termes de distribution\n" +" \\h pour l'aide-mémoire des commandes SQL\n" +" \\? pour l'aide-mémoire des commandes psql\n" +" \\g ou point-virgule en fin d'instruction pour exécuter la requête\n" +" \\q pour quitter\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "Utilisez \\q pour quitter." + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "Utilisez control-D pour quitter." + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "Utilisez control-C pour quitter." + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "requête ignorée ; utilisez \\endif ou Ctrl-C pour quitter le bloc \\if courant" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "a atteint EOF sans trouver le(s) \\endif fermant" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "chaîne entre guillemets non terminée" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s : mémoire épuisée" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:589 sql_help.c:591 sql_help.c:593 +#: sql_help.c:595 sql_help.c:597 sql_help.c:600 sql_help.c:602 sql_help.c:605 +#: sql_help.c:616 sql_help.c:618 sql_help.c:660 sql_help.c:662 sql_help.c:664 +#: sql_help.c:667 sql_help.c:669 sql_help.c:671 sql_help.c:706 sql_help.c:710 +#: sql_help.c:714 sql_help.c:733 sql_help.c:736 sql_help.c:739 sql_help.c:768 +#: sql_help.c:780 sql_help.c:788 sql_help.c:791 sql_help.c:794 sql_help.c:809 +#: sql_help.c:812 sql_help.c:841 sql_help.c:846 sql_help.c:851 sql_help.c:856 +#: sql_help.c:861 sql_help.c:883 sql_help.c:885 sql_help.c:887 sql_help.c:889 +#: sql_help.c:892 sql_help.c:894 sql_help.c:936 sql_help.c:980 sql_help.c:985 +#: sql_help.c:990 sql_help.c:995 sql_help.c:1000 sql_help.c:1019 +#: sql_help.c:1030 sql_help.c:1032 sql_help.c:1051 sql_help.c:1061 +#: sql_help.c:1063 sql_help.c:1065 sql_help.c:1077 sql_help.c:1081 +#: sql_help.c:1083 sql_help.c:1095 sql_help.c:1097 sql_help.c:1099 +#: sql_help.c:1101 sql_help.c:1119 sql_help.c:1121 sql_help.c:1125 +#: sql_help.c:1129 sql_help.c:1133 sql_help.c:1136 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1141 sql_help.c:1143 sql_help.c:1278 +#: sql_help.c:1280 sql_help.c:1283 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1290 sql_help.c:1293 sql_help.c:1296 sql_help.c:1409 +#: sql_help.c:1411 sql_help.c:1413 sql_help.c:1416 sql_help.c:1437 +#: sql_help.c:1440 sql_help.c:1443 sql_help.c:1446 sql_help.c:1450 +#: sql_help.c:1452 sql_help.c:1454 sql_help.c:1456 sql_help.c:1470 +#: sql_help.c:1473 sql_help.c:1475 sql_help.c:1477 sql_help.c:1487 +#: sql_help.c:1489 sql_help.c:1499 sql_help.c:1501 sql_help.c:1511 +#: sql_help.c:1514 sql_help.c:1537 sql_help.c:1539 sql_help.c:1541 +#: sql_help.c:1543 sql_help.c:1546 sql_help.c:1548 sql_help.c:1551 +#: sql_help.c:1554 sql_help.c:1605 sql_help.c:1648 sql_help.c:1651 +#: sql_help.c:1653 sql_help.c:1655 sql_help.c:1658 sql_help.c:1660 +#: sql_help.c:1662 sql_help.c:1665 sql_help.c:1715 sql_help.c:1731 +#: sql_help.c:1962 sql_help.c:2031 sql_help.c:2050 sql_help.c:2063 +#: sql_help.c:2120 sql_help.c:2127 sql_help.c:2137 sql_help.c:2158 +#: sql_help.c:2184 sql_help.c:2202 sql_help.c:2229 sql_help.c:2325 +#: sql_help.c:2371 sql_help.c:2395 sql_help.c:2418 sql_help.c:2422 +#: sql_help.c:2456 sql_help.c:2476 sql_help.c:2498 sql_help.c:2512 +#: sql_help.c:2533 sql_help.c:2557 sql_help.c:2587 sql_help.c:2612 +#: sql_help.c:2659 sql_help.c:2947 sql_help.c:2960 sql_help.c:2977 +#: sql_help.c:2993 sql_help.c:3033 sql_help.c:3087 sql_help.c:3091 +#: sql_help.c:3093 sql_help.c:3100 sql_help.c:3119 sql_help.c:3146 +#: sql_help.c:3181 sql_help.c:3193 sql_help.c:3202 sql_help.c:3246 +#: sql_help.c:3260 sql_help.c:3288 sql_help.c:3296 sql_help.c:3308 +#: sql_help.c:3318 sql_help.c:3326 sql_help.c:3334 sql_help.c:3342 +#: sql_help.c:3350 sql_help.c:3359 sql_help.c:3370 sql_help.c:3378 +#: sql_help.c:3386 sql_help.c:3394 sql_help.c:3402 sql_help.c:3412 +#: sql_help.c:3421 sql_help.c:3430 sql_help.c:3438 sql_help.c:3448 +#: sql_help.c:3459 sql_help.c:3467 sql_help.c:3476 sql_help.c:3487 +#: sql_help.c:3496 sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3528 sql_help.c:3536 sql_help.c:3544 sql_help.c:3552 +#: sql_help.c:3560 sql_help.c:3568 sql_help.c:3576 sql_help.c:3593 +#: sql_help.c:3602 sql_help.c:3610 sql_help.c:3627 sql_help.c:3642 +#: sql_help.c:3944 sql_help.c:3995 sql_help.c:4024 sql_help.c:4039 +#: sql_help.c:4524 sql_help.c:4572 sql_help.c:4723 +msgid "name" +msgstr "nom" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1812 +#: sql_help.c:3261 sql_help.c:4300 +msgid "aggregate_signature" +msgstr "signature_agrégat" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:572 +#: sql_help.c:590 sql_help.c:617 sql_help.c:668 sql_help.c:735 sql_help.c:790 +#: sql_help.c:811 sql_help.c:850 sql_help.c:895 sql_help.c:937 sql_help.c:989 +#: sql_help.c:1021 sql_help.c:1031 sql_help.c:1064 sql_help.c:1084 +#: sql_help.c:1098 sql_help.c:1144 sql_help.c:1287 sql_help.c:1410 +#: sql_help.c:1453 sql_help.c:1474 sql_help.c:1488 sql_help.c:1500 +#: sql_help.c:1513 sql_help.c:1540 sql_help.c:1606 sql_help.c:1659 +msgid "new_name" +msgstr "nouveau_nom" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:619 +#: sql_help.c:628 sql_help.c:689 sql_help.c:709 sql_help.c:738 sql_help.c:793 +#: sql_help.c:855 sql_help.c:893 sql_help.c:994 sql_help.c:1033 sql_help.c:1062 +#: sql_help.c:1082 sql_help.c:1096 sql_help.c:1142 sql_help.c:1350 +#: sql_help.c:1412 sql_help.c:1455 sql_help.c:1476 sql_help.c:1538 +#: sql_help.c:1654 sql_help.c:2933 +msgid "new_owner" +msgstr "nouveau_propriétaire" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:670 sql_help.c:713 sql_help.c:741 +#: sql_help.c:796 sql_help.c:860 sql_help.c:999 sql_help.c:1066 sql_help.c:1100 +#: sql_help.c:1289 sql_help.c:1457 sql_help.c:1478 sql_help.c:1490 +#: sql_help.c:1502 sql_help.c:1542 sql_help.c:1661 +msgid "new_schema" +msgstr "nouveau_schéma" + +#: sql_help.c:44 sql_help.c:1876 sql_help.c:3262 sql_help.c:4329 +msgid "where aggregate_signature is:" +msgstr "où signature_agrégat est :" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:842 +#: sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:862 sql_help.c:981 +#: sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1001 sql_help.c:1830 +#: sql_help.c:1847 sql_help.c:1853 sql_help.c:1877 sql_help.c:1880 +#: sql_help.c:1883 sql_help.c:2032 sql_help.c:2051 sql_help.c:2054 +#: sql_help.c:2326 sql_help.c:2534 sql_help.c:3263 sql_help.c:3266 +#: sql_help.c:3269 sql_help.c:3360 sql_help.c:3449 sql_help.c:3477 +#: sql_help.c:3822 sql_help.c:4202 sql_help.c:4306 sql_help.c:4313 +#: sql_help.c:4319 sql_help.c:4330 sql_help.c:4333 sql_help.c:4336 +msgid "argmode" +msgstr "mode_argument" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:843 +#: sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:863 sql_help.c:982 +#: sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1002 sql_help.c:1831 +#: sql_help.c:1848 sql_help.c:1854 sql_help.c:1878 sql_help.c:1881 +#: sql_help.c:1884 sql_help.c:2033 sql_help.c:2052 sql_help.c:2055 +#: sql_help.c:2327 sql_help.c:2535 sql_help.c:3264 sql_help.c:3267 +#: sql_help.c:3270 sql_help.c:3361 sql_help.c:3450 sql_help.c:3478 +#: sql_help.c:4307 sql_help.c:4314 sql_help.c:4320 sql_help.c:4331 +#: sql_help.c:4334 sql_help.c:4337 +msgid "argname" +msgstr "nom_agrégat" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:844 +#: sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:864 sql_help.c:983 +#: sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1003 sql_help.c:1832 +#: sql_help.c:1849 sql_help.c:1855 sql_help.c:1879 sql_help.c:1882 +#: sql_help.c:1885 sql_help.c:2328 sql_help.c:2536 sql_help.c:3265 +#: sql_help.c:3268 sql_help.c:3271 sql_help.c:3362 sql_help.c:3451 +#: sql_help.c:3479 sql_help.c:4308 sql_help.c:4315 sql_help.c:4321 +#: sql_help.c:4332 sql_help.c:4335 sql_help.c:4338 +msgid "argtype" +msgstr "type_argument" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:931 +#: sql_help.c:1079 sql_help.c:1471 sql_help.c:1600 sql_help.c:1632 +#: sql_help.c:1684 sql_help.c:1747 sql_help.c:1933 sql_help.c:1940 +#: sql_help.c:2232 sql_help.c:2274 sql_help.c:2281 sql_help.c:2290 +#: sql_help.c:2372 sql_help.c:2588 sql_help.c:2681 sql_help.c:2962 +#: sql_help.c:3147 sql_help.c:3169 sql_help.c:3309 sql_help.c:3664 +#: sql_help.c:3863 sql_help.c:4038 sql_help.c:4786 +msgid "option" +msgstr "option" + +#: sql_help.c:113 sql_help.c:932 sql_help.c:1601 sql_help.c:2373 +#: sql_help.c:2589 sql_help.c:3148 sql_help.c:3310 +msgid "where option can be:" +msgstr "où option peut être :" + +#: sql_help.c:114 sql_help.c:2166 +msgid "allowconn" +msgstr "allowconn" + +#: sql_help.c:115 sql_help.c:933 sql_help.c:1602 sql_help.c:2167 +#: sql_help.c:2374 sql_help.c:2590 sql_help.c:3149 +msgid "connlimit" +msgstr "limite_de_connexion" + +#: sql_help.c:116 sql_help.c:2168 +msgid "istemplate" +msgstr "istemplate" + +#: sql_help.c:122 sql_help.c:607 sql_help.c:673 sql_help.c:1292 sql_help.c:1343 +#: sql_help.c:4042 +msgid "new_tablespace" +msgstr "nouveau_tablespace" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:867 sql_help.c:869 sql_help.c:870 sql_help.c:940 +#: sql_help.c:944 sql_help.c:947 sql_help.c:1008 sql_help.c:1010 +#: sql_help.c:1011 sql_help.c:1155 sql_help.c:1158 sql_help.c:1609 +#: sql_help.c:1613 sql_help.c:1616 sql_help.c:2338 sql_help.c:2540 +#: sql_help.c:4060 sql_help.c:4513 +msgid "configuration_parameter" +msgstr "paramètre_configuration" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:599 sql_help.c:679 sql_help.c:687 sql_help.c:868 +#: sql_help.c:891 sql_help.c:941 sql_help.c:1009 sql_help.c:1080 +#: sql_help.c:1124 sql_help.c:1128 sql_help.c:1132 sql_help.c:1135 +#: sql_help.c:1140 sql_help.c:1156 sql_help.c:1157 sql_help.c:1323 +#: sql_help.c:1345 sql_help.c:1393 sql_help.c:1415 sql_help.c:1472 +#: sql_help.c:1556 sql_help.c:1610 sql_help.c:1633 sql_help.c:2233 +#: sql_help.c:2275 sql_help.c:2282 sql_help.c:2291 sql_help.c:2339 +#: sql_help.c:2340 sql_help.c:2403 sql_help.c:2406 sql_help.c:2440 +#: sql_help.c:2541 sql_help.c:2542 sql_help.c:2560 sql_help.c:2682 +#: sql_help.c:2721 sql_help.c:2827 sql_help.c:2840 sql_help.c:2854 +#: sql_help.c:2895 sql_help.c:2919 sql_help.c:2936 sql_help.c:2963 +#: sql_help.c:3170 sql_help.c:3864 sql_help.c:4514 sql_help.c:4515 +msgid "value" +msgstr "valeur" + +#: sql_help.c:197 +msgid "target_role" +msgstr "rôle_cible" + +#: sql_help.c:198 sql_help.c:2217 sql_help.c:2637 sql_help.c:2642 +#: sql_help.c:3797 sql_help.c:3806 sql_help.c:3825 sql_help.c:3834 +#: sql_help.c:4177 sql_help.c:4186 sql_help.c:4205 sql_help.c:4214 +msgid "schema_name" +msgstr "nom_schéma" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "grant_ou_revoke_raccourci" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "où abbreviated_grant_or_revoke fait partie de :" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:570 sql_help.c:606 sql_help.c:672 sql_help.c:814 sql_help.c:951 +#: sql_help.c:1291 sql_help.c:1620 sql_help.c:2377 sql_help.c:2378 +#: sql_help.c:2379 sql_help.c:2380 sql_help.c:2381 sql_help.c:2514 +#: sql_help.c:2593 sql_help.c:2594 sql_help.c:2595 sql_help.c:2596 +#: sql_help.c:2597 sql_help.c:3152 sql_help.c:3153 sql_help.c:3154 +#: sql_help.c:3155 sql_help.c:3156 sql_help.c:3843 sql_help.c:3847 +#: sql_help.c:4223 sql_help.c:4227 sql_help.c:4534 +msgid "role_name" +msgstr "nom_rôle" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1307 sql_help.c:1309 +#: sql_help.c:1360 sql_help.c:1372 sql_help.c:1397 sql_help.c:1650 +#: sql_help.c:2187 sql_help.c:2191 sql_help.c:2294 sql_help.c:2299 +#: sql_help.c:2399 sql_help.c:2698 sql_help.c:2703 sql_help.c:2705 +#: sql_help.c:2822 sql_help.c:2835 sql_help.c:2849 sql_help.c:2858 +#: sql_help.c:2870 sql_help.c:2899 sql_help.c:3895 sql_help.c:3910 +#: sql_help.c:3912 sql_help.c:4391 sql_help.c:4392 sql_help.c:4401 +#: sql_help.c:4443 sql_help.c:4444 sql_help.c:4445 sql_help.c:4446 +#: sql_help.c:4447 sql_help.c:4448 sql_help.c:4488 sql_help.c:4489 +#: sql_help.c:4494 sql_help.c:4499 sql_help.c:4640 sql_help.c:4641 +#: sql_help.c:4650 sql_help.c:4692 sql_help.c:4693 sql_help.c:4694 +#: sql_help.c:4695 sql_help.c:4696 sql_help.c:4697 sql_help.c:4751 +#: sql_help.c:4753 sql_help.c:4814 sql_help.c:4872 sql_help.c:4873 +#: sql_help.c:4882 sql_help.c:4924 sql_help.c:4925 sql_help.c:4926 +#: sql_help.c:4927 sql_help.c:4928 sql_help.c:4929 +msgid "expression" +msgstr "expression" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "contrainte_domaine" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1284 sql_help.c:1331 sql_help.c:1332 sql_help.c:1333 +#: sql_help.c:1359 sql_help.c:1371 sql_help.c:1388 sql_help.c:1818 +#: sql_help.c:1820 sql_help.c:2190 sql_help.c:2293 sql_help.c:2298 +#: sql_help.c:2857 sql_help.c:2869 sql_help.c:3907 +msgid "constraint_name" +msgstr "nom_contrainte" + +#: sql_help.c:244 sql_help.c:1285 +msgid "new_constraint_name" +msgstr "nouvelle_nom_contrainte" + +#: sql_help.c:317 sql_help.c:1078 +msgid "new_version" +msgstr "nouvelle_version" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "objet_membre" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "où objet_membre fait partie de :" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1810 sql_help.c:1815 sql_help.c:1822 +#: sql_help.c:1823 sql_help.c:1824 sql_help.c:1825 sql_help.c:1826 +#: sql_help.c:1827 sql_help.c:1828 sql_help.c:1833 sql_help.c:1835 +#: sql_help.c:1839 sql_help.c:1841 sql_help.c:1845 sql_help.c:1850 +#: sql_help.c:1851 sql_help.c:1858 sql_help.c:1859 sql_help.c:1860 +#: sql_help.c:1861 sql_help.c:1862 sql_help.c:1863 sql_help.c:1864 +#: sql_help.c:1865 sql_help.c:1866 sql_help.c:1867 sql_help.c:1868 +#: sql_help.c:1873 sql_help.c:1874 sql_help.c:4296 sql_help.c:4301 +#: sql_help.c:4302 sql_help.c:4303 sql_help.c:4304 sql_help.c:4310 +#: sql_help.c:4311 sql_help.c:4316 sql_help.c:4317 sql_help.c:4322 +#: sql_help.c:4323 sql_help.c:4324 sql_help.c:4325 sql_help.c:4326 +#: sql_help.c:4327 +msgid "object_name" +msgstr "nom_objet" + +#: sql_help.c:326 sql_help.c:1811 sql_help.c:4299 +msgid "aggregate_name" +msgstr "nom_agrégat" + +#: sql_help.c:328 sql_help.c:1813 sql_help.c:2097 sql_help.c:2101 +#: sql_help.c:2103 sql_help.c:3279 +msgid "source_type" +msgstr "type_source" + +#: sql_help.c:329 sql_help.c:1814 sql_help.c:2098 sql_help.c:2102 +#: sql_help.c:2104 sql_help.c:3280 +msgid "target_type" +msgstr "type_cible" + +#: sql_help.c:336 sql_help.c:778 sql_help.c:1829 sql_help.c:2099 +#: sql_help.c:2140 sql_help.c:2205 sql_help.c:2457 sql_help.c:2488 +#: sql_help.c:3039 sql_help.c:4201 sql_help.c:4305 sql_help.c:4420 +#: sql_help.c:4424 sql_help.c:4428 sql_help.c:4431 sql_help.c:4669 +#: sql_help.c:4673 sql_help.c:4677 sql_help.c:4680 sql_help.c:4901 +#: sql_help.c:4905 sql_help.c:4909 sql_help.c:4912 +msgid "function_name" +msgstr "nom_fonction" + +#: sql_help.c:341 sql_help.c:771 sql_help.c:1836 sql_help.c:2481 +msgid "operator_name" +msgstr "nom_opérateur" + +#: sql_help.c:342 sql_help.c:707 sql_help.c:711 sql_help.c:715 sql_help.c:1837 +#: sql_help.c:2458 sql_help.c:3403 +msgid "left_type" +msgstr "type_argument_gauche" + +#: sql_help.c:343 sql_help.c:708 sql_help.c:712 sql_help.c:716 sql_help.c:1838 +#: sql_help.c:2459 sql_help.c:3404 +msgid "right_type" +msgstr "type_argument_droit" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:734 sql_help.c:737 sql_help.c:740 +#: sql_help.c:769 sql_help.c:781 sql_help.c:789 sql_help.c:792 sql_help.c:795 +#: sql_help.c:1377 sql_help.c:1840 sql_help.c:1842 sql_help.c:2478 +#: sql_help.c:2499 sql_help.c:2875 sql_help.c:3413 sql_help.c:3422 +msgid "index_method" +msgstr "méthode_indexage" + +#: sql_help.c:349 sql_help.c:1846 sql_help.c:4312 +msgid "procedure_name" +msgstr "nom_procédure" + +#: sql_help.c:353 sql_help.c:1852 sql_help.c:3821 sql_help.c:4318 +msgid "routine_name" +msgstr "nom_routine" + +#: sql_help.c:365 sql_help.c:1349 sql_help.c:1869 sql_help.c:2334 +#: sql_help.c:2539 sql_help.c:2830 sql_help.c:3006 sql_help.c:3584 +#: sql_help.c:3840 sql_help.c:4220 +msgid "type_name" +msgstr "nom_type" + +#: sql_help.c:366 sql_help.c:1870 sql_help.c:2333 sql_help.c:2538 +#: sql_help.c:3007 sql_help.c:3237 sql_help.c:3585 sql_help.c:3828 +#: sql_help.c:4208 +msgid "lang_name" +msgstr "nom_langage" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "et signature_agrégat est :" + +#: sql_help.c:392 sql_help.c:1964 sql_help.c:2230 +msgid "handler_function" +msgstr "fonction_gestionnaire" + +#: sql_help.c:393 sql_help.c:2231 +msgid "validator_function" +msgstr "fonction_validateur" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:661 sql_help.c:845 sql_help.c:984 +#: sql_help.c:1279 sql_help.c:1547 +msgid "action" +msgstr "action" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:665 sql_help.c:675 sql_help.c:677 +#: sql_help.c:680 sql_help.c:682 sql_help.c:683 sql_help.c:1060 sql_help.c:1281 +#: sql_help.c:1299 sql_help.c:1303 sql_help.c:1304 sql_help.c:1308 +#: sql_help.c:1310 sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 +#: sql_help.c:1315 sql_help.c:1318 sql_help.c:1319 sql_help.c:1321 +#: sql_help.c:1324 sql_help.c:1326 sql_help.c:1327 sql_help.c:1373 +#: sql_help.c:1375 sql_help.c:1382 sql_help.c:1391 sql_help.c:1396 +#: sql_help.c:1649 sql_help.c:1652 sql_help.c:1656 sql_help.c:1692 +#: sql_help.c:1817 sql_help.c:1930 sql_help.c:1936 sql_help.c:1949 +#: sql_help.c:1950 sql_help.c:1951 sql_help.c:2272 sql_help.c:2285 +#: sql_help.c:2331 sql_help.c:2398 sql_help.c:2404 sql_help.c:2437 +#: sql_help.c:2667 sql_help.c:2702 sql_help.c:2704 sql_help.c:2812 +#: sql_help.c:2821 sql_help.c:2831 sql_help.c:2834 sql_help.c:2844 +#: sql_help.c:2848 sql_help.c:2871 sql_help.c:2873 sql_help.c:2880 +#: sql_help.c:2893 sql_help.c:2898 sql_help.c:2916 sql_help.c:3042 +#: sql_help.c:3182 sql_help.c:3800 sql_help.c:3801 sql_help.c:3894 +#: sql_help.c:3909 sql_help.c:3911 sql_help.c:3913 sql_help.c:4180 +#: sql_help.c:4181 sql_help.c:4298 sql_help.c:4452 sql_help.c:4458 +#: sql_help.c:4460 sql_help.c:4701 sql_help.c:4707 sql_help.c:4709 +#: sql_help.c:4750 sql_help.c:4752 sql_help.c:4754 sql_help.c:4802 +#: sql_help.c:4933 sql_help.c:4939 sql_help.c:4941 +msgid "column_name" +msgstr "nom_colonne" + +#: sql_help.c:444 sql_help.c:666 sql_help.c:1282 sql_help.c:1657 +msgid "new_column_name" +msgstr "nouvelle_nom_colonne" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:674 sql_help.c:866 sql_help.c:1005 +#: sql_help.c:1298 sql_help.c:1557 +msgid "where action is one of:" +msgstr "où action fait partie de :" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1052 sql_help.c:1300 +#: sql_help.c:1305 sql_help.c:1559 sql_help.c:1563 sql_help.c:2185 +#: sql_help.c:2273 sql_help.c:2477 sql_help.c:2660 sql_help.c:2813 +#: sql_help.c:3089 sql_help.c:3996 +msgid "data_type" +msgstr "type_données" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1301 sql_help.c:1306 +#: sql_help.c:1560 sql_help.c:1564 sql_help.c:2186 sql_help.c:2276 +#: sql_help.c:2400 sql_help.c:2815 sql_help.c:2823 sql_help.c:2836 +#: sql_help.c:2850 sql_help.c:3090 sql_help.c:3096 sql_help.c:3904 +msgid "collation" +msgstr "collationnement" + +#: sql_help.c:453 sql_help.c:1302 sql_help.c:2277 sql_help.c:2286 +#: sql_help.c:2816 sql_help.c:2832 sql_help.c:2845 +msgid "column_constraint" +msgstr "contrainte_colonne" + +#: sql_help.c:463 sql_help.c:604 sql_help.c:676 sql_help.c:1320 sql_help.c:4799 +msgid "integer" +msgstr "entier" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:678 sql_help.c:681 sql_help.c:1322 +#: sql_help.c:1325 +msgid "attribute_option" +msgstr "option_attribut" + +#: sql_help.c:473 sql_help.c:1329 sql_help.c:2278 sql_help.c:2287 +#: sql_help.c:2817 sql_help.c:2833 sql_help.c:2846 +msgid "table_constraint" +msgstr "contrainte_table" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1334 +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:1871 +msgid "trigger_name" +msgstr "nom_trigger" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1347 sql_help.c:1348 +#: sql_help.c:2279 sql_help.c:2284 sql_help.c:2820 sql_help.c:2843 +msgid "parent_table" +msgstr "table_parent" + +#: sql_help.c:539 sql_help.c:596 sql_help.c:663 sql_help.c:865 sql_help.c:1004 +#: sql_help.c:1516 sql_help.c:2216 +msgid "extension_name" +msgstr "nom_extension" + +#: sql_help.c:541 sql_help.c:1006 sql_help.c:2335 +msgid "execution_cost" +msgstr "coût_exécution" + +#: sql_help.c:542 sql_help.c:1007 sql_help.c:2336 +msgid "result_rows" +msgstr "lignes_de_résultat" + +#: sql_help.c:543 sql_help.c:2337 +msgid "support_function" +msgstr "fonction_support" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:930 sql_help.c:938 sql_help.c:942 +#: sql_help.c:945 sql_help.c:948 sql_help.c:1599 sql_help.c:1607 +#: sql_help.c:1611 sql_help.c:1614 sql_help.c:1617 sql_help.c:2638 +#: sql_help.c:2640 sql_help.c:2643 sql_help.c:2644 sql_help.c:3798 +#: sql_help.c:3799 sql_help.c:3803 sql_help.c:3804 sql_help.c:3807 +#: sql_help.c:3808 sql_help.c:3810 sql_help.c:3811 sql_help.c:3813 +#: sql_help.c:3814 sql_help.c:3816 sql_help.c:3817 sql_help.c:3819 +#: sql_help.c:3820 sql_help.c:3826 sql_help.c:3827 sql_help.c:3829 +#: sql_help.c:3830 sql_help.c:3832 sql_help.c:3833 sql_help.c:3835 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:3839 sql_help.c:3841 +#: sql_help.c:3842 sql_help.c:3844 sql_help.c:3845 sql_help.c:4178 +#: sql_help.c:4179 sql_help.c:4183 sql_help.c:4184 sql_help.c:4187 +#: sql_help.c:4188 sql_help.c:4190 sql_help.c:4191 sql_help.c:4193 +#: sql_help.c:4194 sql_help.c:4196 sql_help.c:4197 sql_help.c:4199 +#: sql_help.c:4200 sql_help.c:4206 sql_help.c:4207 sql_help.c:4209 +#: sql_help.c:4210 sql_help.c:4212 sql_help.c:4213 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4218 sql_help.c:4219 sql_help.c:4221 +#: sql_help.c:4222 sql_help.c:4224 sql_help.c:4225 +msgid "role_specification" +msgstr "specification_role" + +#: sql_help.c:566 sql_help.c:568 sql_help.c:1630 sql_help.c:2159 +#: sql_help.c:2646 sql_help.c:3167 sql_help.c:3618 sql_help.c:4544 +msgid "user_name" +msgstr "nom_utilisateur" + +#: sql_help.c:569 sql_help.c:950 sql_help.c:1619 sql_help.c:2645 +#: sql_help.c:3846 sql_help.c:4226 +msgid "where role_specification can be:" +msgstr "où specification_role peut être :" + +#: sql_help.c:571 +msgid "group_name" +msgstr "nom_groupe" + +#: sql_help.c:592 sql_help.c:1394 sql_help.c:2165 sql_help.c:2407 +#: sql_help.c:2441 sql_help.c:2828 sql_help.c:2841 sql_help.c:2855 +#: sql_help.c:2896 sql_help.c:2920 sql_help.c:2932 sql_help.c:3837 +#: sql_help.c:4217 +msgid "tablespace_name" +msgstr "nom_tablespace" + +#: sql_help.c:594 sql_help.c:685 sql_help.c:1342 sql_help.c:1351 +#: sql_help.c:1389 sql_help.c:1746 sql_help.c:1749 +msgid "index_name" +msgstr "nom_index" + +#: sql_help.c:598 sql_help.c:601 sql_help.c:686 sql_help.c:688 sql_help.c:1344 +#: sql_help.c:1346 sql_help.c:1392 sql_help.c:2405 sql_help.c:2439 +#: sql_help.c:2826 sql_help.c:2839 sql_help.c:2853 sql_help.c:2894 +#: sql_help.c:2918 +msgid "storage_parameter" +msgstr "paramètre_stockage" + +#: sql_help.c:603 +msgid "column_number" +msgstr "numéro_colonne" + +#: sql_help.c:627 sql_help.c:1834 sql_help.c:4309 +msgid "large_object_oid" +msgstr "oid_large_object" + +#: sql_help.c:684 sql_help.c:1328 sql_help.c:2814 +msgid "compression_method" +msgstr "méthode_compression" + +#: sql_help.c:717 sql_help.c:2462 +msgid "res_proc" +msgstr "res_proc" + +#: sql_help.c:718 sql_help.c:2463 +msgid "join_proc" +msgstr "join_proc" + +#: sql_help.c:770 sql_help.c:782 sql_help.c:2480 +msgid "strategy_number" +msgstr "numéro_de_stratégie" + +#: sql_help.c:772 sql_help.c:773 sql_help.c:776 sql_help.c:777 sql_help.c:783 +#: sql_help.c:784 sql_help.c:786 sql_help.c:787 sql_help.c:2482 sql_help.c:2483 +#: sql_help.c:2486 sql_help.c:2487 +msgid "op_type" +msgstr "type_op" + +#: sql_help.c:774 sql_help.c:2484 +msgid "sort_family_name" +msgstr "nom_famille_tri" + +#: sql_help.c:775 sql_help.c:785 sql_help.c:2485 +msgid "support_number" +msgstr "numéro_de_support" + +#: sql_help.c:779 sql_help.c:2100 sql_help.c:2489 sql_help.c:3009 +#: sql_help.c:3011 +msgid "argument_type" +msgstr "type_argument" + +#: sql_help.c:810 sql_help.c:813 sql_help.c:884 sql_help.c:886 sql_help.c:888 +#: sql_help.c:1020 sql_help.c:1059 sql_help.c:1512 sql_help.c:1515 +#: sql_help.c:1691 sql_help.c:1745 sql_help.c:1748 sql_help.c:1819 +#: sql_help.c:1844 sql_help.c:1857 sql_help.c:1872 sql_help.c:1929 +#: sql_help.c:1935 sql_help.c:2271 sql_help.c:2283 sql_help.c:2396 +#: sql_help.c:2436 sql_help.c:2513 sql_help.c:2558 sql_help.c:2614 +#: sql_help.c:2666 sql_help.c:2699 sql_help.c:2706 sql_help.c:2811 +#: sql_help.c:2829 sql_help.c:2842 sql_help.c:2915 sql_help.c:3035 +#: sql_help.c:3216 sql_help.c:3439 sql_help.c:3488 sql_help.c:3594 +#: sql_help.c:3796 sql_help.c:3802 sql_help.c:3860 sql_help.c:3892 +#: sql_help.c:4176 sql_help.c:4182 sql_help.c:4297 sql_help.c:4406 +#: sql_help.c:4408 sql_help.c:4465 sql_help.c:4504 sql_help.c:4655 +#: sql_help.c:4657 sql_help.c:4714 sql_help.c:4748 sql_help.c:4801 +#: sql_help.c:4887 sql_help.c:4889 sql_help.c:4946 +msgid "table_name" +msgstr "nom_table" + +#: sql_help.c:815 sql_help.c:2515 +msgid "using_expression" +msgstr "expression_using" + +#: sql_help.c:816 sql_help.c:2516 +msgid "check_expression" +msgstr "expression_check" + +#: sql_help.c:890 sql_help.c:2559 +msgid "publication_parameter" +msgstr "paramètre_publication" + +#: sql_help.c:934 sql_help.c:1603 sql_help.c:2375 sql_help.c:2591 +#: sql_help.c:3150 +msgid "password" +msgstr "mot_de_passe" + +#: sql_help.c:935 sql_help.c:1604 sql_help.c:2376 sql_help.c:2592 +#: sql_help.c:3151 +msgid "timestamp" +msgstr "horodatage" + +#: sql_help.c:939 sql_help.c:943 sql_help.c:946 sql_help.c:949 sql_help.c:1608 +#: sql_help.c:1612 sql_help.c:1615 sql_help.c:1618 sql_help.c:3809 +#: sql_help.c:4189 +msgid "database_name" +msgstr "nom_base_de_donnée" + +#: sql_help.c:1053 sql_help.c:2661 +msgid "increment" +msgstr "incrément" + +#: sql_help.c:1054 sql_help.c:2662 +msgid "minvalue" +msgstr "valeur_min" + +#: sql_help.c:1055 sql_help.c:2663 +msgid "maxvalue" +msgstr "valeur_max" + +#: sql_help.c:1056 sql_help.c:2664 sql_help.c:4404 sql_help.c:4502 +#: sql_help.c:4653 sql_help.c:4818 sql_help.c:4885 +msgid "start" +msgstr "début" + +#: sql_help.c:1057 sql_help.c:1317 +msgid "restart" +msgstr "nouveau_début" + +#: sql_help.c:1058 sql_help.c:2665 +msgid "cache" +msgstr "cache" + +#: sql_help.c:1102 +msgid "new_target" +msgstr "nouvelle_cible" + +#: sql_help.c:1120 sql_help.c:2718 +msgid "conninfo" +msgstr "conninfo" + +#: sql_help.c:1122 sql_help.c:1126 sql_help.c:1130 sql_help.c:2719 +msgid "publication_name" +msgstr "nom_publication" + +#: sql_help.c:1123 sql_help.c:1127 sql_help.c:1131 +msgid "set_publication_option" +msgstr "option_ensemble_publication" + +#: sql_help.c:1134 +msgid "refresh_option" +msgstr "option_rafraichissement" + +#: sql_help.c:1139 sql_help.c:2720 +msgid "subscription_parameter" +msgstr "paramètre_souscription" + +#: sql_help.c:1294 sql_help.c:1297 +msgid "partition_name" +msgstr "nom_partition" + +#: sql_help.c:1295 sql_help.c:2288 sql_help.c:2847 +msgid "partition_bound_spec" +msgstr "spec_limite_partition" + +#: sql_help.c:1314 sql_help.c:1363 sql_help.c:2861 +msgid "sequence_options" +msgstr "options_séquence" + +#: sql_help.c:1316 +msgid "sequence_option" +msgstr "option_séquence" + +#: sql_help.c:1330 +msgid "table_constraint_using_index" +msgstr "contrainte_table_utilisant_index" + +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:1340 sql_help.c:1341 +msgid "rewrite_rule_name" +msgstr "nom_règle_réécriture" + +#: sql_help.c:1352 sql_help.c:2886 +msgid "and partition_bound_spec is:" +msgstr "et partition_bound_spec est :" + +#: sql_help.c:1353 sql_help.c:1354 sql_help.c:1355 sql_help.c:2887 +#: sql_help.c:2888 sql_help.c:2889 +msgid "partition_bound_expr" +msgstr "expr_limite_partition" + +#: sql_help.c:1356 sql_help.c:1357 sql_help.c:2890 sql_help.c:2891 +msgid "numeric_literal" +msgstr "numeric_literal" + +#: sql_help.c:1358 +msgid "and column_constraint is:" +msgstr "et contrainte_colonne est :" + +#: sql_help.c:1361 sql_help.c:2295 sql_help.c:2329 sql_help.c:2537 +#: sql_help.c:2859 +msgid "default_expr" +msgstr "expression_par_défaut" + +#: sql_help.c:1362 sql_help.c:2296 sql_help.c:2860 +msgid "generation_expr" +msgstr "expression_génération" + +#: sql_help.c:1364 sql_help.c:1365 sql_help.c:1374 sql_help.c:1376 +#: sql_help.c:1380 sql_help.c:2862 sql_help.c:2863 sql_help.c:2872 +#: sql_help.c:2874 sql_help.c:2878 +msgid "index_parameters" +msgstr "paramètres_index" + +#: sql_help.c:1366 sql_help.c:1383 sql_help.c:2864 sql_help.c:2881 +msgid "reftable" +msgstr "table_référence" + +#: sql_help.c:1367 sql_help.c:1384 sql_help.c:2865 sql_help.c:2882 +msgid "refcolumn" +msgstr "colonne_référence" + +#: sql_help.c:1368 sql_help.c:1369 sql_help.c:1385 sql_help.c:1386 +#: sql_help.c:2866 sql_help.c:2867 sql_help.c:2883 sql_help.c:2884 +msgid "referential_action" +msgstr "action" + +#: sql_help.c:1370 sql_help.c:2297 sql_help.c:2868 +msgid "and table_constraint is:" +msgstr "et contrainte_table est :" + +#: sql_help.c:1378 sql_help.c:2876 +msgid "exclude_element" +msgstr "élément_exclusion" + +#: sql_help.c:1379 sql_help.c:2877 sql_help.c:4402 sql_help.c:4500 +#: sql_help.c:4651 sql_help.c:4816 sql_help.c:4883 +msgid "operator" +msgstr "opérateur" + +#: sql_help.c:1381 sql_help.c:2408 sql_help.c:2879 +msgid "predicate" +msgstr "prédicat" + +#: sql_help.c:1387 +msgid "and table_constraint_using_index is:" +msgstr "et contrainte_table_utilisant_index est :" + +#: sql_help.c:1390 sql_help.c:2892 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "dans les contraintes UNIQUE, PRIMARY KEY et EXCLUDE, les paramètres_index sont :" + +#: sql_help.c:1395 sql_help.c:2897 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "élément_exclusion dans une contrainte EXCLUDE est :" + +#: sql_help.c:1398 sql_help.c:2401 sql_help.c:2824 sql_help.c:2837 +#: sql_help.c:2851 sql_help.c:2900 sql_help.c:3905 +msgid "opclass" +msgstr "classe_d_opérateur" + +#: sql_help.c:1414 sql_help.c:1417 sql_help.c:2935 +msgid "tablespace_option" +msgstr "option_tablespace" + +#: sql_help.c:1438 sql_help.c:1441 sql_help.c:1447 sql_help.c:1451 +msgid "token_type" +msgstr "type_jeton" + +#: sql_help.c:1439 sql_help.c:1442 +msgid "dictionary_name" +msgstr "nom_dictionnaire" + +#: sql_help.c:1444 sql_help.c:1448 +msgid "old_dictionary" +msgstr "ancien_dictionnaire" + +#: sql_help.c:1445 sql_help.c:1449 +msgid "new_dictionary" +msgstr "nouveau_dictionnaire" + +#: sql_help.c:1544 sql_help.c:1558 sql_help.c:1561 sql_help.c:1562 +#: sql_help.c:3088 +msgid "attribute_name" +msgstr "nom_attribut" + +#: sql_help.c:1545 +msgid "new_attribute_name" +msgstr "nouveau_nom_attribut" + +#: sql_help.c:1549 sql_help.c:1553 +msgid "new_enum_value" +msgstr "nouvelle_valeur_enum" + +#: sql_help.c:1550 +msgid "neighbor_enum_value" +msgstr "valeur_enum_voisine" + +#: sql_help.c:1552 +msgid "existing_enum_value" +msgstr "valeur_enum_existante" + +#: sql_help.c:1555 +msgid "property" +msgstr "propriété" + +#: sql_help.c:1631 sql_help.c:2280 sql_help.c:2289 sql_help.c:2677 +#: sql_help.c:3168 sql_help.c:3619 sql_help.c:3818 sql_help.c:3861 +#: sql_help.c:4198 +msgid "server_name" +msgstr "nom_serveur" + +#: sql_help.c:1663 sql_help.c:1666 sql_help.c:3183 +msgid "view_option_name" +msgstr "nom_option_vue" + +#: sql_help.c:1664 sql_help.c:3184 +msgid "view_option_value" +msgstr "valeur_option_vue" + +#: sql_help.c:1685 sql_help.c:1686 sql_help.c:4787 sql_help.c:4788 +msgid "table_and_columns" +msgstr "table_et_colonnes" + +#: sql_help.c:1687 sql_help.c:1750 sql_help.c:1941 sql_help.c:3667 +#: sql_help.c:4040 sql_help.c:4789 +msgid "where option can be one of:" +msgstr "où option fait partie de :" + +#: sql_help.c:1688 sql_help.c:1689 sql_help.c:1751 sql_help.c:1943 +#: sql_help.c:1946 sql_help.c:2125 sql_help.c:3668 sql_help.c:3669 +#: sql_help.c:3670 sql_help.c:3671 sql_help.c:3672 sql_help.c:3673 +#: sql_help.c:3674 sql_help.c:3675 sql_help.c:4041 sql_help.c:4043 +#: sql_help.c:4790 sql_help.c:4791 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +#: sql_help.c:4798 +msgid "boolean" +msgstr "boolean" + +#: sql_help.c:1690 sql_help.c:4800 +msgid "and table_and_columns is:" +msgstr "et table_et_colonnes est :" + +#: sql_help.c:1706 sql_help.c:4560 sql_help.c:4562 sql_help.c:4586 +msgid "transaction_mode" +msgstr "mode_transaction" + +#: sql_help.c:1707 sql_help.c:4563 sql_help.c:4587 +msgid "where transaction_mode is one of:" +msgstr "où mode_transaction fait partie de :" + +#: sql_help.c:1716 sql_help.c:4412 sql_help.c:4421 sql_help.c:4425 +#: sql_help.c:4429 sql_help.c:4432 sql_help.c:4661 sql_help.c:4670 +#: sql_help.c:4674 sql_help.c:4678 sql_help.c:4681 sql_help.c:4893 +#: sql_help.c:4902 sql_help.c:4906 sql_help.c:4910 sql_help.c:4913 +msgid "argument" +msgstr "argument" + +#: sql_help.c:1816 +msgid "relation_name" +msgstr "nom_relation" + +#: sql_help.c:1821 sql_help.c:3812 sql_help.c:4192 +msgid "domain_name" +msgstr "nom_domaine" + +#: sql_help.c:1843 +msgid "policy_name" +msgstr "nom_politique" + +#: sql_help.c:1856 +msgid "rule_name" +msgstr "nom_règle" + +#: sql_help.c:1875 +msgid "text" +msgstr "texte" + +#: sql_help.c:1900 sql_help.c:4005 sql_help.c:4242 +msgid "transaction_id" +msgstr "id_transaction" + +#: sql_help.c:1931 sql_help.c:1938 sql_help.c:3931 +msgid "filename" +msgstr "nom_fichier" + +#: sql_help.c:1932 sql_help.c:1939 sql_help.c:2616 sql_help.c:2617 +#: sql_help.c:2618 +msgid "command" +msgstr "commande" + +#: sql_help.c:1934 sql_help.c:2615 sql_help.c:3038 sql_help.c:3219 +#: sql_help.c:3915 sql_help.c:4395 sql_help.c:4397 sql_help.c:4493 +#: sql_help.c:4495 sql_help.c:4644 sql_help.c:4646 sql_help.c:4757 +#: sql_help.c:4876 sql_help.c:4878 +msgid "condition" +msgstr "condition" + +#: sql_help.c:1937 sql_help.c:2442 sql_help.c:2921 sql_help.c:3185 +#: sql_help.c:3203 sql_help.c:3896 +msgid "query" +msgstr "requête" + +#: sql_help.c:1942 +msgid "format_name" +msgstr "nom_format" + +#: sql_help.c:1944 +msgid "delimiter_character" +msgstr "caractère_délimiteur" + +#: sql_help.c:1945 +msgid "null_string" +msgstr "chaîne_null" + +#: sql_help.c:1947 +msgid "quote_character" +msgstr "caractère_guillemet" + +#: sql_help.c:1948 +msgid "escape_character" +msgstr "chaîne_d_échappement" + +#: sql_help.c:1952 +msgid "encoding_name" +msgstr "nom_encodage" + +#: sql_help.c:1963 +msgid "access_method_type" +msgstr "access_method_type" + +#: sql_help.c:2034 sql_help.c:2053 sql_help.c:2056 +msgid "arg_data_type" +msgstr "type_données_arg" + +#: sql_help.c:2035 sql_help.c:2057 sql_help.c:2065 +msgid "sfunc" +msgstr "sfunc" + +#: sql_help.c:2036 sql_help.c:2058 sql_help.c:2066 +msgid "state_data_type" +msgstr "type_de_données_statut" + +#: sql_help.c:2037 sql_help.c:2059 sql_help.c:2067 +msgid "state_data_size" +msgstr "taille_de_données_statut" + +#: sql_help.c:2038 sql_help.c:2060 sql_help.c:2068 +msgid "ffunc" +msgstr "ffunc" + +#: sql_help.c:2039 sql_help.c:2069 +msgid "combinefunc" +msgstr "combinefunc" + +#: sql_help.c:2040 sql_help.c:2070 +msgid "serialfunc" +msgstr "serialfunc" + +#: sql_help.c:2041 sql_help.c:2071 +msgid "deserialfunc" +msgstr "deserialfunc" + +#: sql_help.c:2042 sql_help.c:2061 sql_help.c:2072 +msgid "initial_condition" +msgstr "condition_initiale" + +#: sql_help.c:2043 sql_help.c:2073 +msgid "msfunc" +msgstr "msfunc" + +#: sql_help.c:2044 sql_help.c:2074 +msgid "minvfunc" +msgstr "minvfunc" + +#: sql_help.c:2045 sql_help.c:2075 +msgid "mstate_data_type" +msgstr "m_type_de_données_statut" + +#: sql_help.c:2046 sql_help.c:2076 +msgid "mstate_data_size" +msgstr "m_taille_de_données_statut" + +#: sql_help.c:2047 sql_help.c:2077 +msgid "mffunc" +msgstr "mffunc" + +#: sql_help.c:2048 sql_help.c:2078 +msgid "minitial_condition" +msgstr "m_condition_initiale" + +#: sql_help.c:2049 sql_help.c:2079 +msgid "sort_operator" +msgstr "opérateur_de_tri" + +#: sql_help.c:2062 +msgid "or the old syntax" +msgstr "ou l'ancienne syntaxe" + +#: sql_help.c:2064 +msgid "base_type" +msgstr "type_base" + +#: sql_help.c:2121 sql_help.c:2162 +msgid "locale" +msgstr "locale" + +#: sql_help.c:2122 sql_help.c:2163 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2123 sql_help.c:2164 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2124 sql_help.c:4295 +msgid "provider" +msgstr "fournisseur" + +#: sql_help.c:2126 sql_help.c:2218 +msgid "version" +msgstr "version" + +#: sql_help.c:2128 +msgid "existing_collation" +msgstr "collationnement_existant" + +#: sql_help.c:2138 +msgid "source_encoding" +msgstr "encodage_source" + +#: sql_help.c:2139 +msgid "dest_encoding" +msgstr "encodage_destination" + +#: sql_help.c:2160 sql_help.c:2961 +msgid "template" +msgstr "modèle" + +#: sql_help.c:2161 +msgid "encoding" +msgstr "encodage" + +#: sql_help.c:2188 +msgid "constraint" +msgstr "contrainte" + +#: sql_help.c:2189 +msgid "where constraint is:" +msgstr "où la contrainte est :" + +#: sql_help.c:2203 sql_help.c:2613 sql_help.c:3034 +msgid "event" +msgstr "événement" + +#: sql_help.c:2204 +msgid "filter_variable" +msgstr "filter_variable" + +#: sql_help.c:2292 sql_help.c:2856 +msgid "where column_constraint is:" +msgstr "où contrainte_colonne est :" + +#: sql_help.c:2330 +msgid "rettype" +msgstr "type_en_retour" + +#: sql_help.c:2332 +msgid "column_type" +msgstr "type_colonne" + +#: sql_help.c:2341 sql_help.c:2543 +msgid "definition" +msgstr "définition" + +#: sql_help.c:2342 sql_help.c:2544 +msgid "obj_file" +msgstr "fichier_objet" + +#: sql_help.c:2343 sql_help.c:2545 +msgid "link_symbol" +msgstr "symbole_link" + +#: sql_help.c:2344 sql_help.c:2546 +msgid "sql_body" +msgstr "corps_sql" + +#: sql_help.c:2382 sql_help.c:2598 sql_help.c:3157 +msgid "uid" +msgstr "uid" + +#: sql_help.c:2397 sql_help.c:2438 sql_help.c:2825 sql_help.c:2838 +#: sql_help.c:2852 sql_help.c:2917 +msgid "method" +msgstr "méthode" + +#: sql_help.c:2402 +msgid "opclass_parameter" +msgstr "paramètre_opclass" + +#: sql_help.c:2419 +msgid "call_handler" +msgstr "gestionnaire_d_appel" + +#: sql_help.c:2420 +msgid "inline_handler" +msgstr "gestionnaire_en_ligne" + +#: sql_help.c:2421 +msgid "valfunction" +msgstr "fonction_val" + +#: sql_help.c:2460 +msgid "com_op" +msgstr "com_op" + +#: sql_help.c:2461 +msgid "neg_op" +msgstr "neg_op" + +#: sql_help.c:2479 +msgid "family_name" +msgstr "nom_famille" + +#: sql_help.c:2490 +msgid "storage_type" +msgstr "type_stockage" + +#: sql_help.c:2619 sql_help.c:3041 +msgid "where event can be one of:" +msgstr "où événement fait partie de :" + +#: sql_help.c:2639 sql_help.c:2641 +msgid "schema_element" +msgstr "élément_schéma" + +#: sql_help.c:2678 +msgid "server_type" +msgstr "type_serveur" + +#: sql_help.c:2679 +msgid "server_version" +msgstr "version_serveur" + +#: sql_help.c:2680 sql_help.c:3815 sql_help.c:4195 +msgid "fdw_name" +msgstr "nom_fdw" + +#: sql_help.c:2697 sql_help.c:2700 +msgid "statistics_name" +msgstr "nom_statistique" + +#: sql_help.c:2701 +msgid "statistics_kind" +msgstr "statistics_kind" + +#: sql_help.c:2717 +msgid "subscription_name" +msgstr "nom_souscription" + +#: sql_help.c:2818 +msgid "source_table" +msgstr "table_source" + +#: sql_help.c:2819 +msgid "like_option" +msgstr "option_like" + +#: sql_help.c:2885 +msgid "and like_option is:" +msgstr "et option_like est :" + +#: sql_help.c:2934 +msgid "directory" +msgstr "répertoire" + +#: sql_help.c:2948 +msgid "parser_name" +msgstr "nom_analyseur" + +#: sql_help.c:2949 +msgid "source_config" +msgstr "configuration_source" + +#: sql_help.c:2978 +msgid "start_function" +msgstr "fonction_start" + +#: sql_help.c:2979 +msgid "gettoken_function" +msgstr "fonction_gettoken" + +#: sql_help.c:2980 +msgid "end_function" +msgstr "fonction_end" + +#: sql_help.c:2981 +msgid "lextypes_function" +msgstr "fonction_lextypes" + +#: sql_help.c:2982 +msgid "headline_function" +msgstr "fonction_headline" + +#: sql_help.c:2994 +msgid "init_function" +msgstr "fonction_init" + +#: sql_help.c:2995 +msgid "lexize_function" +msgstr "fonction_lexize" + +#: sql_help.c:3008 +msgid "from_sql_function_name" +msgstr "nom_fonction_from_sql" + +#: sql_help.c:3010 +msgid "to_sql_function_name" +msgstr "nom_fonction_to_sql" + +#: sql_help.c:3036 +msgid "referenced_table_name" +msgstr "nom_table_référencée" + +#: sql_help.c:3037 +msgid "transition_relation_name" +msgstr "nom_relation_transition" + +#: sql_help.c:3040 +msgid "arguments" +msgstr "arguments" + +#: sql_help.c:3092 sql_help.c:4328 +msgid "label" +msgstr "label" + +#: sql_help.c:3094 +msgid "subtype" +msgstr "sous_type" + +#: sql_help.c:3095 +msgid "subtype_operator_class" +msgstr "classe_opérateur_sous_type" + +#: sql_help.c:3097 +msgid "canonical_function" +msgstr "fonction_canonique" + +#: sql_help.c:3098 +msgid "subtype_diff_function" +msgstr "fonction_diff_sous_type" + +#: sql_help.c:3099 +msgid "multirange_type_name" +msgstr "nom_type_multirange" + +#: sql_help.c:3101 +msgid "input_function" +msgstr "fonction_en_sortie" + +#: sql_help.c:3102 +msgid "output_function" +msgstr "fonction_en_sortie" + +#: sql_help.c:3103 +msgid "receive_function" +msgstr "fonction_receive" + +#: sql_help.c:3104 +msgid "send_function" +msgstr "fonction_send" + +#: sql_help.c:3105 +msgid "type_modifier_input_function" +msgstr "fonction_en_entrée_modificateur_type" + +#: sql_help.c:3106 +msgid "type_modifier_output_function" +msgstr "fonction_en_sortie_modificateur_type" + +#: sql_help.c:3107 +msgid "analyze_function" +msgstr "fonction_analyze" + +#: sql_help.c:3108 +msgid "subscript_function" +msgstr "fonction_indice" + +#: sql_help.c:3109 +msgid "internallength" +msgstr "longueur_interne" + +#: sql_help.c:3110 +msgid "alignment" +msgstr "alignement" + +#: sql_help.c:3111 +msgid "storage" +msgstr "stockage" + +#: sql_help.c:3112 +msgid "like_type" +msgstr "type_like" + +#: sql_help.c:3113 +msgid "category" +msgstr "catégorie" + +#: sql_help.c:3114 +msgid "preferred" +msgstr "préféré" + +#: sql_help.c:3115 +msgid "default" +msgstr "par défaut" + +#: sql_help.c:3116 +msgid "element" +msgstr "élément" + +#: sql_help.c:3117 +msgid "delimiter" +msgstr "délimiteur" + +#: sql_help.c:3118 +msgid "collatable" +msgstr "collationnable" + +#: sql_help.c:3215 sql_help.c:3891 sql_help.c:4390 sql_help.c:4487 +#: sql_help.c:4639 sql_help.c:4747 sql_help.c:4871 +msgid "with_query" +msgstr "requête_with" + +#: sql_help.c:3217 sql_help.c:3893 sql_help.c:4409 sql_help.c:4415 +#: sql_help.c:4418 sql_help.c:4422 sql_help.c:4426 sql_help.c:4434 +#: sql_help.c:4658 sql_help.c:4664 sql_help.c:4667 sql_help.c:4671 +#: sql_help.c:4675 sql_help.c:4683 sql_help.c:4749 sql_help.c:4890 +#: sql_help.c:4896 sql_help.c:4899 sql_help.c:4903 sql_help.c:4907 +#: sql_help.c:4915 +msgid "alias" +msgstr "alias" + +#: sql_help.c:3218 sql_help.c:4394 sql_help.c:4436 sql_help.c:4438 +#: sql_help.c:4492 sql_help.c:4643 sql_help.c:4685 sql_help.c:4687 +#: sql_help.c:4756 sql_help.c:4875 sql_help.c:4917 sql_help.c:4919 +msgid "from_item" +msgstr "élément_from" + +#: sql_help.c:3220 sql_help.c:3701 sql_help.c:3972 sql_help.c:4758 +msgid "cursor_name" +msgstr "nom_curseur" + +#: sql_help.c:3221 sql_help.c:3899 sql_help.c:4759 +msgid "output_expression" +msgstr "expression_en_sortie" + +#: sql_help.c:3222 sql_help.c:3900 sql_help.c:4393 sql_help.c:4490 +#: sql_help.c:4642 sql_help.c:4760 sql_help.c:4874 +msgid "output_name" +msgstr "nom_en_sortie" + +#: sql_help.c:3238 +msgid "code" +msgstr "code" + +#: sql_help.c:3643 +msgid "parameter" +msgstr "paramètre" + +#: sql_help.c:3665 sql_help.c:3666 sql_help.c:3997 +msgid "statement" +msgstr "instruction" + +#: sql_help.c:3700 sql_help.c:3971 +msgid "direction" +msgstr "direction" + +#: sql_help.c:3702 sql_help.c:3973 +msgid "where direction can be empty or one of:" +msgstr "où direction peut être vide ou faire partie de :" + +#: sql_help.c:3703 sql_help.c:3704 sql_help.c:3705 sql_help.c:3706 +#: sql_help.c:3707 sql_help.c:3974 sql_help.c:3975 sql_help.c:3976 +#: sql_help.c:3977 sql_help.c:3978 sql_help.c:4403 sql_help.c:4405 +#: sql_help.c:4501 sql_help.c:4503 sql_help.c:4652 sql_help.c:4654 +#: sql_help.c:4817 sql_help.c:4819 sql_help.c:4884 sql_help.c:4886 +msgid "count" +msgstr "nombre" + +#: sql_help.c:3805 sql_help.c:4185 +msgid "sequence_name" +msgstr "nom_séquence" + +#: sql_help.c:3823 sql_help.c:4203 +msgid "arg_name" +msgstr "nom_argument" + +#: sql_help.c:3824 sql_help.c:4204 +msgid "arg_type" +msgstr "type_arg" + +#: sql_help.c:3831 sql_help.c:4211 +msgid "loid" +msgstr "loid" + +#: sql_help.c:3859 +msgid "remote_schema" +msgstr "schema_distant" + +#: sql_help.c:3862 +msgid "local_schema" +msgstr "schéma_local" + +#: sql_help.c:3897 +msgid "conflict_target" +msgstr "cible_conflit" + +#: sql_help.c:3898 +msgid "conflict_action" +msgstr "action_conflit" + +#: sql_help.c:3901 +msgid "where conflict_target can be one of:" +msgstr "où cible_conflit fait partie de :" + +#: sql_help.c:3902 +msgid "index_column_name" +msgstr "index_nom_colonne" + +#: sql_help.c:3903 +msgid "index_expression" +msgstr "index_expression" + +#: sql_help.c:3906 +msgid "index_predicate" +msgstr "index_prédicat" + +#: sql_help.c:3908 +msgid "and conflict_action is one of:" +msgstr "où action_conflit fait partie de :" + +#: sql_help.c:3914 sql_help.c:4755 +msgid "sub-SELECT" +msgstr "sous-SELECT" + +#: sql_help.c:3923 sql_help.c:3986 sql_help.c:4731 +msgid "channel" +msgstr "canal" + +#: sql_help.c:3945 +msgid "lockmode" +msgstr "mode_de_verrou" + +#: sql_help.c:3946 +msgid "where lockmode is one of:" +msgstr "où mode_de_verrou fait partie de :" + +#: sql_help.c:3987 +msgid "payload" +msgstr "contenu" + +#: sql_help.c:4014 +msgid "old_role" +msgstr "ancien_rôle" + +#: sql_help.c:4015 +msgid "new_role" +msgstr "nouveau_rôle" + +#: sql_help.c:4051 sql_help.c:4250 sql_help.c:4258 +msgid "savepoint_name" +msgstr "nom_savepoint" + +#: sql_help.c:4396 sql_help.c:4449 sql_help.c:4645 sql_help.c:4698 +#: sql_help.c:4877 sql_help.c:4930 +msgid "grouping_element" +msgstr "element_regroupement" + +#: sql_help.c:4398 sql_help.c:4496 sql_help.c:4647 sql_help.c:4879 +msgid "window_name" +msgstr "nom_window" + +#: sql_help.c:4399 sql_help.c:4497 sql_help.c:4648 sql_help.c:4880 +msgid "window_definition" +msgstr "définition_window" + +#: sql_help.c:4400 sql_help.c:4414 sql_help.c:4453 sql_help.c:4498 +#: sql_help.c:4649 sql_help.c:4663 sql_help.c:4702 sql_help.c:4881 +#: sql_help.c:4895 sql_help.c:4934 +msgid "select" +msgstr "sélection" + +#: sql_help.c:4407 sql_help.c:4656 sql_help.c:4888 +msgid "where from_item can be one of:" +msgstr "où élément_from fait partie de :" + +#: sql_help.c:4410 sql_help.c:4416 sql_help.c:4419 sql_help.c:4423 +#: sql_help.c:4435 sql_help.c:4659 sql_help.c:4665 sql_help.c:4668 +#: sql_help.c:4672 sql_help.c:4684 sql_help.c:4891 sql_help.c:4897 +#: sql_help.c:4900 sql_help.c:4904 sql_help.c:4916 +msgid "column_alias" +msgstr "alias_colonne" + +#: sql_help.c:4411 sql_help.c:4660 sql_help.c:4892 +msgid "sampling_method" +msgstr "méthode_echantillonnage" + +#: sql_help.c:4413 sql_help.c:4662 sql_help.c:4894 +msgid "seed" +msgstr "graine" + +#: sql_help.c:4417 sql_help.c:4451 sql_help.c:4666 sql_help.c:4700 +#: sql_help.c:4898 sql_help.c:4932 +msgid "with_query_name" +msgstr "nom_requête_with" + +#: sql_help.c:4427 sql_help.c:4430 sql_help.c:4433 sql_help.c:4676 +#: sql_help.c:4679 sql_help.c:4682 sql_help.c:4908 sql_help.c:4911 +#: sql_help.c:4914 +msgid "column_definition" +msgstr "définition_colonne" + +#: sql_help.c:4437 sql_help.c:4686 sql_help.c:4918 +msgid "join_type" +msgstr "type_de_jointure" + +#: sql_help.c:4439 sql_help.c:4688 sql_help.c:4920 +msgid "join_condition" +msgstr "condition_de_jointure" + +#: sql_help.c:4440 sql_help.c:4689 sql_help.c:4921 +msgid "join_column" +msgstr "colonne_de_jointure" + +#: sql_help.c:4441 sql_help.c:4690 sql_help.c:4922 +msgid "join_using_alias" +msgstr "join_utilisant_alias" + +#: sql_help.c:4442 sql_help.c:4691 sql_help.c:4923 +msgid "and grouping_element can be one of:" +msgstr "où element_regroupement fait partie de :" + +#: sql_help.c:4450 sql_help.c:4699 sql_help.c:4931 +msgid "and with_query is:" +msgstr "et requête_with est :" + +#: sql_help.c:4454 sql_help.c:4703 sql_help.c:4935 +msgid "values" +msgstr "valeurs" + +#: sql_help.c:4455 sql_help.c:4704 sql_help.c:4936 +msgid "insert" +msgstr "insert" + +#: sql_help.c:4456 sql_help.c:4705 sql_help.c:4937 +msgid "update" +msgstr "update" + +#: sql_help.c:4457 sql_help.c:4706 sql_help.c:4938 +msgid "delete" +msgstr "delete" + +#: sql_help.c:4459 sql_help.c:4708 sql_help.c:4940 +msgid "search_seq_col_name" +msgstr "nom_colonne_seq_recherche" + +#: sql_help.c:4461 sql_help.c:4710 sql_help.c:4942 +msgid "cycle_mark_col_name" +msgstr "nom_colonne_marque_cycle" + +#: sql_help.c:4462 sql_help.c:4711 sql_help.c:4943 +msgid "cycle_mark_value" +msgstr "valeur_marque_cycle" + +#: sql_help.c:4463 sql_help.c:4712 sql_help.c:4944 +msgid "cycle_mark_default" +msgstr "défaut_marque_cyle" + +#: sql_help.c:4464 sql_help.c:4713 sql_help.c:4945 +msgid "cycle_path_col_name" +msgstr "nom_colonne_chemin_cycle" + +#: sql_help.c:4491 +msgid "new_table" +msgstr "nouvelle_table" + +#: sql_help.c:4516 +msgid "timezone" +msgstr "fuseau_horaire" + +#: sql_help.c:4561 +msgid "snapshot_id" +msgstr "id_snapshot" + +#: sql_help.c:4815 +msgid "sort_expression" +msgstr "expression_de_tri" + +#: sql_help.c:4952 sql_help.c:5930 +msgid "abort the current transaction" +msgstr "abandonner la transaction en cours" + +#: sql_help.c:4958 +msgid "change the definition of an aggregate function" +msgstr "modifier la définition d'une fonction d'agrégation" + +#: sql_help.c:4964 +msgid "change the definition of a collation" +msgstr "modifier la définition d'un collationnement" + +#: sql_help.c:4970 +msgid "change the definition of a conversion" +msgstr "modifier la définition d'une conversion" + +#: sql_help.c:4976 +msgid "change a database" +msgstr "modifier une base de données" + +#: sql_help.c:4982 +msgid "define default access privileges" +msgstr "définir les droits d'accès par défaut" + +#: sql_help.c:4988 +msgid "change the definition of a domain" +msgstr "modifier la définition d'un domaine" + +#: sql_help.c:4994 +msgid "change the definition of an event trigger" +msgstr "modifier la définition d'un trigger sur évènement" + +#: sql_help.c:5000 +msgid "change the definition of an extension" +msgstr "modifier la définition d'une extension" + +#: sql_help.c:5006 +msgid "change the definition of a foreign-data wrapper" +msgstr "modifier la définition d'un wrapper de données distantes" + +#: sql_help.c:5012 +msgid "change the definition of a foreign table" +msgstr "modifier la définition d'une table distante" + +#: sql_help.c:5018 +msgid "change the definition of a function" +msgstr "modifier la définition d'une fonction" + +#: sql_help.c:5024 +msgid "change role name or membership" +msgstr "modifier le nom d'un groupe ou la liste des ses membres" + +#: sql_help.c:5030 +msgid "change the definition of an index" +msgstr "modifier la définition d'un index" + +#: sql_help.c:5036 +msgid "change the definition of a procedural language" +msgstr "modifier la définition d'un langage procédural" + +#: sql_help.c:5042 +msgid "change the definition of a large object" +msgstr "modifier la définition d'un « Large Object »" + +#: sql_help.c:5048 +msgid "change the definition of a materialized view" +msgstr "modifier la définition d'une vue matérialisée" + +#: sql_help.c:5054 +msgid "change the definition of an operator" +msgstr "modifier la définition d'un opérateur" + +#: sql_help.c:5060 +msgid "change the definition of an operator class" +msgstr "modifier la définition d'une classe d'opérateurs" + +#: sql_help.c:5066 +msgid "change the definition of an operator family" +msgstr "modifier la définition d'une famille d'opérateur" + +#: sql_help.c:5072 +msgid "change the definition of a row-level security policy" +msgstr "modifier la définition d'une politique de sécurité au niveau ligne" + +#: sql_help.c:5078 +msgid "change the definition of a procedure" +msgstr "modifier la définition d'une procédure" + +#: sql_help.c:5084 +msgid "change the definition of a publication" +msgstr "modifier la définition d'une publication" + +#: sql_help.c:5090 sql_help.c:5192 +msgid "change a database role" +msgstr "modifier un rôle" + +#: sql_help.c:5096 +msgid "change the definition of a routine" +msgstr "modifier la définition d'une routine" + +#: sql_help.c:5102 +msgid "change the definition of a rule" +msgstr "modifier la définition d'une règle" + +#: sql_help.c:5108 +msgid "change the definition of a schema" +msgstr "modifier la définition d'un schéma" + +#: sql_help.c:5114 +msgid "change the definition of a sequence generator" +msgstr "modifier la définition d'un générateur de séquence" + +#: sql_help.c:5120 +msgid "change the definition of a foreign server" +msgstr "modifier la définition d'un serveur distant" + +#: sql_help.c:5126 +msgid "change the definition of an extended statistics object" +msgstr "modifier la définition d'un objet de statistiques étendues" + +#: sql_help.c:5132 +msgid "change the definition of a subscription" +msgstr "modifier la définition d'une souscription" + +#: sql_help.c:5138 +msgid "change a server configuration parameter" +msgstr "modifie un paramètre de configuration du serveur" + +#: sql_help.c:5144 +msgid "change the definition of a table" +msgstr "modifier la définition d'une table" + +#: sql_help.c:5150 +msgid "change the definition of a tablespace" +msgstr "modifier la définition d'un tablespace" + +#: sql_help.c:5156 +msgid "change the definition of a text search configuration" +msgstr "modifier la définition d'une configuration de la recherche de texte" + +#: sql_help.c:5162 +msgid "change the definition of a text search dictionary" +msgstr "modifier la définition d'un dictionnaire de la recherche de texte" + +#: sql_help.c:5168 +msgid "change the definition of a text search parser" +msgstr "modifier la définition d'un analyseur de la recherche de texte" + +#: sql_help.c:5174 +msgid "change the definition of a text search template" +msgstr "modifier la définition d'un modèle de la recherche de texte" + +#: sql_help.c:5180 +msgid "change the definition of a trigger" +msgstr "modifier la définition d'un trigger" + +#: sql_help.c:5186 +msgid "change the definition of a type" +msgstr "modifier la définition d'un type" + +#: sql_help.c:5198 +msgid "change the definition of a user mapping" +msgstr "modifier la définition d'une correspondance d'utilisateur" + +#: sql_help.c:5204 +msgid "change the definition of a view" +msgstr "modifier la définition d'une vue" + +#: sql_help.c:5210 +msgid "collect statistics about a database" +msgstr "acquérir des statistiques concernant la base de données" + +#: sql_help.c:5216 sql_help.c:6008 +msgid "start a transaction block" +msgstr "débuter un bloc de transaction" + +#: sql_help.c:5222 +msgid "invoke a procedure" +msgstr "appeler une procédure" + +#: sql_help.c:5228 +msgid "force a write-ahead log checkpoint" +msgstr "forcer un point de vérification des journaux de transactions" + +#: sql_help.c:5234 +msgid "close a cursor" +msgstr "fermer un curseur" + +#: sql_help.c:5240 +msgid "cluster a table according to an index" +msgstr "réorganiser (cluster) une table en fonction d'un index" + +#: sql_help.c:5246 +msgid "define or change the comment of an object" +msgstr "définir ou modifier les commentaires d'un objet" + +#: sql_help.c:5252 sql_help.c:5810 +msgid "commit the current transaction" +msgstr "valider la transaction en cours" + +#: sql_help.c:5258 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "" +"valider une transaction précédemment préparée pour une validation en deux\n" +"phases" + +#: sql_help.c:5264 +msgid "copy data between a file and a table" +msgstr "copier des données entre un fichier et une table" + +#: sql_help.c:5270 +msgid "define a new access method" +msgstr "définir une nouvelle méthode d'accès" + +#: sql_help.c:5276 +msgid "define a new aggregate function" +msgstr "définir une nouvelle fonction d'agrégation" + +#: sql_help.c:5282 +msgid "define a new cast" +msgstr "définir un nouveau transtypage" + +#: sql_help.c:5288 +msgid "define a new collation" +msgstr "définir un nouveau collationnement" + +#: sql_help.c:5294 +msgid "define a new encoding conversion" +msgstr "définir une nouvelle conversion d'encodage" + +#: sql_help.c:5300 +msgid "create a new database" +msgstr "créer une nouvelle base de données" + +#: sql_help.c:5306 +msgid "define a new domain" +msgstr "définir un nouveau domaine" + +#: sql_help.c:5312 +msgid "define a new event trigger" +msgstr "définir un nouveau trigger sur évènement" + +#: sql_help.c:5318 +msgid "install an extension" +msgstr "installer une extension" + +#: sql_help.c:5324 +msgid "define a new foreign-data wrapper" +msgstr "définir un nouveau wrapper de données distantes" + +#: sql_help.c:5330 +msgid "define a new foreign table" +msgstr "définir une nouvelle table distante" + +#: sql_help.c:5336 +msgid "define a new function" +msgstr "définir une nouvelle fonction" + +#: sql_help.c:5342 sql_help.c:5402 sql_help.c:5504 +msgid "define a new database role" +msgstr "définir un nouveau rôle" + +#: sql_help.c:5348 +msgid "define a new index" +msgstr "définir un nouvel index" + +#: sql_help.c:5354 +msgid "define a new procedural language" +msgstr "définir un nouveau langage de procédures" + +#: sql_help.c:5360 +msgid "define a new materialized view" +msgstr "définir une nouvelle vue matérialisée" + +#: sql_help.c:5366 +msgid "define a new operator" +msgstr "définir un nouvel opérateur" + +#: sql_help.c:5372 +msgid "define a new operator class" +msgstr "définir une nouvelle classe d'opérateur" + +#: sql_help.c:5378 +msgid "define a new operator family" +msgstr "définir une nouvelle famille d'opérateur" + +#: sql_help.c:5384 +msgid "define a new row-level security policy for a table" +msgstr "définir une nouvelle politique de sécurité au niveau ligne pour une table" + +#: sql_help.c:5390 +msgid "define a new procedure" +msgstr "définir une nouvelle procédure" + +#: sql_help.c:5396 +msgid "define a new publication" +msgstr "définir une nouvelle publication" + +#: sql_help.c:5408 +msgid "define a new rewrite rule" +msgstr "définir une nouvelle règle de réécriture" + +#: sql_help.c:5414 +msgid "define a new schema" +msgstr "définir un nouveau schéma" + +#: sql_help.c:5420 +msgid "define a new sequence generator" +msgstr "définir un nouveau générateur de séquence" + +#: sql_help.c:5426 +msgid "define a new foreign server" +msgstr "définir un nouveau serveur distant" + +#: sql_help.c:5432 +msgid "define extended statistics" +msgstr "définir des statistiques étendues" + +#: sql_help.c:5438 +msgid "define a new subscription" +msgstr "définir une nouvelle souscription" + +#: sql_help.c:5444 +msgid "define a new table" +msgstr "définir une nouvelle table" + +#: sql_help.c:5450 sql_help.c:5966 +msgid "define a new table from the results of a query" +msgstr "définir une nouvelle table à partir des résultats d'une requête" + +#: sql_help.c:5456 +msgid "define a new tablespace" +msgstr "définir un nouveau tablespace" + +#: sql_help.c:5462 +msgid "define a new text search configuration" +msgstr "définir une nouvelle configuration de la recherche de texte" + +#: sql_help.c:5468 +msgid "define a new text search dictionary" +msgstr "définir un nouveau dictionnaire de la recherche de texte" + +#: sql_help.c:5474 +msgid "define a new text search parser" +msgstr "définir un nouvel analyseur de la recherche de texte" + +#: sql_help.c:5480 +msgid "define a new text search template" +msgstr "définir un nouveau modèle de la recherche de texte" + +#: sql_help.c:5486 +msgid "define a new transform" +msgstr "définir une nouvelle transformation" + +#: sql_help.c:5492 +msgid "define a new trigger" +msgstr "définir un nouveau trigger" + +#: sql_help.c:5498 +msgid "define a new data type" +msgstr "définir un nouveau type de données" + +#: sql_help.c:5510 +msgid "define a new mapping of a user to a foreign server" +msgstr "définit une nouvelle correspondance d'un utilisateur vers un serveur distant" + +#: sql_help.c:5516 +msgid "define a new view" +msgstr "définir une nouvelle vue" + +#: sql_help.c:5522 +msgid "deallocate a prepared statement" +msgstr "désallouer une instruction préparée" + +#: sql_help.c:5528 +msgid "define a cursor" +msgstr "définir un curseur" + +#: sql_help.c:5534 +msgid "delete rows of a table" +msgstr "supprimer des lignes d'une table" + +#: sql_help.c:5540 +msgid "discard session state" +msgstr "annuler l'état de la session" + +#: sql_help.c:5546 +msgid "execute an anonymous code block" +msgstr "exécute un bloc de code anonyme" + +#: sql_help.c:5552 +msgid "remove an access method" +msgstr "supprimer une méthode d'accès" + +#: sql_help.c:5558 +msgid "remove an aggregate function" +msgstr "supprimer une fonction d'agrégation" + +#: sql_help.c:5564 +msgid "remove a cast" +msgstr "supprimer un transtypage" + +#: sql_help.c:5570 +msgid "remove a collation" +msgstr "supprimer un collationnement" + +#: sql_help.c:5576 +msgid "remove a conversion" +msgstr "supprimer une conversion" + +#: sql_help.c:5582 +msgid "remove a database" +msgstr "supprimer une base de données" + +#: sql_help.c:5588 +msgid "remove a domain" +msgstr "supprimer un domaine" + +#: sql_help.c:5594 +msgid "remove an event trigger" +msgstr "supprimer un trigger sur évènement" + +#: sql_help.c:5600 +msgid "remove an extension" +msgstr "supprimer une extension" + +#: sql_help.c:5606 +msgid "remove a foreign-data wrapper" +msgstr "supprimer un wrapper de données distantes" + +#: sql_help.c:5612 +msgid "remove a foreign table" +msgstr "supprimer une table distante" + +#: sql_help.c:5618 +msgid "remove a function" +msgstr "supprimer une fonction" + +#: sql_help.c:5624 sql_help.c:5690 sql_help.c:5792 +msgid "remove a database role" +msgstr "supprimer un rôle de la base de données" + +#: sql_help.c:5630 +msgid "remove an index" +msgstr "supprimer un index" + +#: sql_help.c:5636 +msgid "remove a procedural language" +msgstr "supprimer un langage procédural" + +#: sql_help.c:5642 +msgid "remove a materialized view" +msgstr "supprimer une vue matérialisée" + +#: sql_help.c:5648 +msgid "remove an operator" +msgstr "supprimer un opérateur" + +#: sql_help.c:5654 +msgid "remove an operator class" +msgstr "supprimer une classe d'opérateur" + +#: sql_help.c:5660 +msgid "remove an operator family" +msgstr "supprimer une famille d'opérateur" + +#: sql_help.c:5666 +msgid "remove database objects owned by a database role" +msgstr "supprimer les objets appartenant à un rôle" + +#: sql_help.c:5672 +msgid "remove a row-level security policy from a table" +msgstr "supprimer une politique de sécurité au niveau ligne pour une table" + +#: sql_help.c:5678 +msgid "remove a procedure" +msgstr "supprimer une procédure" + +#: sql_help.c:5684 +msgid "remove a publication" +msgstr "supprimer une publication" + +#: sql_help.c:5696 +msgid "remove a routine" +msgstr "supprimer une routine" + +#: sql_help.c:5702 +msgid "remove a rewrite rule" +msgstr "supprimer une règle de réécriture" + +#: sql_help.c:5708 +msgid "remove a schema" +msgstr "supprimer un schéma" + +#: sql_help.c:5714 +msgid "remove a sequence" +msgstr "supprimer une séquence" + +#: sql_help.c:5720 +msgid "remove a foreign server descriptor" +msgstr "supprimer un descripteur de serveur distant" + +#: sql_help.c:5726 +msgid "remove extended statistics" +msgstr "supprimer des statistiques étendues" + +#: sql_help.c:5732 +msgid "remove a subscription" +msgstr "supprimer une souscription" + +#: sql_help.c:5738 +msgid "remove a table" +msgstr "supprimer une table" + +#: sql_help.c:5744 +msgid "remove a tablespace" +msgstr "supprimer un tablespace" + +#: sql_help.c:5750 +msgid "remove a text search configuration" +msgstr "supprimer une configuration de la recherche de texte" + +#: sql_help.c:5756 +msgid "remove a text search dictionary" +msgstr "supprimer un dictionnaire de la recherche de texte" + +#: sql_help.c:5762 +msgid "remove a text search parser" +msgstr "supprimer un analyseur de la recherche de texte" + +#: sql_help.c:5768 +msgid "remove a text search template" +msgstr "supprimer un modèle de la recherche de texte" + +#: sql_help.c:5774 +msgid "remove a transform" +msgstr "supprimer une transformation" + +#: sql_help.c:5780 +msgid "remove a trigger" +msgstr "supprimer un trigger" + +#: sql_help.c:5786 +msgid "remove a data type" +msgstr "supprimer un type de données" + +#: sql_help.c:5798 +msgid "remove a user mapping for a foreign server" +msgstr "supprime une correspondance utilisateur pour un serveur distant" + +#: sql_help.c:5804 +msgid "remove a view" +msgstr "supprimer une vue" + +#: sql_help.c:5816 +msgid "execute a prepared statement" +msgstr "exécuter une instruction préparée" + +#: sql_help.c:5822 +msgid "show the execution plan of a statement" +msgstr "afficher le plan d'exécution d'une instruction" + +#: sql_help.c:5828 +msgid "retrieve rows from a query using a cursor" +msgstr "extraire certaines lignes d'une requête à l'aide d'un curseur" + +#: sql_help.c:5834 +msgid "define access privileges" +msgstr "définir des privilèges d'accès" + +#: sql_help.c:5840 +msgid "import table definitions from a foreign server" +msgstr "importer la définition d'une table à partir d'un serveur distant" + +#: sql_help.c:5846 +msgid "create new rows in a table" +msgstr "créer de nouvelles lignes dans une table" + +#: sql_help.c:5852 +msgid "listen for a notification" +msgstr "se mettre à l'écoute d'une notification" + +#: sql_help.c:5858 +msgid "load a shared library file" +msgstr "charger un fichier de bibliothèque partagée" + +#: sql_help.c:5864 +msgid "lock a table" +msgstr "verrouiller une table" + +#: sql_help.c:5870 +msgid "position a cursor" +msgstr "positionner un curseur" + +#: sql_help.c:5876 +msgid "generate a notification" +msgstr "engendrer une notification" + +#: sql_help.c:5882 +msgid "prepare a statement for execution" +msgstr "préparer une instruction pour exécution" + +#: sql_help.c:5888 +msgid "prepare the current transaction for two-phase commit" +msgstr "préparer la transaction en cours pour une validation en deux phases" + +#: sql_help.c:5894 +msgid "change the ownership of database objects owned by a database role" +msgstr "changer le propriétaire des objets d'un rôle" + +#: sql_help.c:5900 +msgid "replace the contents of a materialized view" +msgstr "remplacer le contenu d'une vue matérialisée" + +#: sql_help.c:5906 +msgid "rebuild indexes" +msgstr "reconstruire des index" + +#: sql_help.c:5912 +msgid "destroy a previously defined savepoint" +msgstr "détruire un point de retournement précédemment défini" + +#: sql_help.c:5918 +msgid "restore the value of a run-time parameter to the default value" +msgstr "réinitialiser un paramètre d'exécution à sa valeur par défaut" + +#: sql_help.c:5924 +msgid "remove access privileges" +msgstr "supprimer des privilèges d'accès" + +#: sql_help.c:5936 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "" +"annuler une transaction précédemment préparée pour une validation en deux\n" +"phases" + +#: sql_help.c:5942 +msgid "roll back to a savepoint" +msgstr "annuler jusqu'au point de retournement" + +#: sql_help.c:5948 +msgid "define a new savepoint within the current transaction" +msgstr "définir un nouveau point de retournement pour la transaction en cours" + +#: sql_help.c:5954 +msgid "define or change a security label applied to an object" +msgstr "définir ou modifier un label de sécurité à un objet" + +#: sql_help.c:5960 sql_help.c:6014 sql_help.c:6050 +msgid "retrieve rows from a table or view" +msgstr "extraire des lignes d'une table ou d'une vue" + +#: sql_help.c:5972 +msgid "change a run-time parameter" +msgstr "modifier un paramètre d'exécution" + +#: sql_help.c:5978 +msgid "set constraint check timing for the current transaction" +msgstr "définir le moment de la vérification des contraintes pour la transaction en cours" + +#: sql_help.c:5984 +msgid "set the current user identifier of the current session" +msgstr "définir l'identifiant actuel de l'utilisateur de la session courante" + +#: sql_help.c:5990 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "" +"définir l'identifiant de l'utilisateur de session et l'identifiant actuel de\n" +"l'utilisateur de la session courante" + +#: sql_help.c:5996 +msgid "set the characteristics of the current transaction" +msgstr "définir les caractéristiques de la transaction en cours" + +#: sql_help.c:6002 +msgid "show the value of a run-time parameter" +msgstr "afficher la valeur d'un paramètre d'exécution" + +#: sql_help.c:6020 +msgid "empty a table or set of tables" +msgstr "vider une table ou un ensemble de tables" + +#: sql_help.c:6026 +msgid "stop listening for a notification" +msgstr "arrêter l'écoute d'une notification" + +#: sql_help.c:6032 +msgid "update rows of a table" +msgstr "actualiser les lignes d'une table" + +#: sql_help.c:6038 +msgid "garbage-collect and optionally analyze a database" +msgstr "compacter et optionnellement analyser une base de données" + +#: sql_help.c:6044 +msgid "compute a set of rows" +msgstr "calculer un ensemble de lignes" + +#: startup.c:213 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 peut seulement être utilisé dans un mode non interactif" + +#: startup.c:326 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier applicatif « %s » : %m" + +#: startup.c:438 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Saisissez « help » pour l'aide.\n" +"\n" + +#: startup.c:591 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "n'a pas pu configurer le paramètre d'impression « %s »" + +#: startup.c:699 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#: startup.c:716 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "option supplémentaire « %s » ignorée" + +#: startup.c:765 +#, c-format +msgid "could not find own program executable" +msgstr "n'a pas pu trouver son propre exécutable" + +#: tab-complete.c:4898 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"la complétion de la requête a échoué : %s\n" +"La requête était :\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "valeur « %s » non reconnue pour « %s » : booléen attendu" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "valeur « %s » invalide pour « %s » : entier attendu" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "nom de variable « %s » invalide" + +#: variables.c:419 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"valeur « %s » non reconnue pour « %s »\n" +"Les valeurs disponibles sont : %s." + +#~ msgid "pclose failed: %m" +#~ msgstr "échec de pclose : %m" + +#~ msgid "Could not send cancel request: %s" +#~ msgstr "N'a pas pu envoyer la requête d'annulation : %s" + +#~ msgid "lock a named relation (table, etc)" +#~ msgstr "verrouille une relation nommée (table, etc)" + +#~ msgid "could not connect to server: %s" +#~ msgstr "n'a pas pu se connecter au serveur : %s" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapporter les bogues à .\n" + +#~ msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" +#~ msgstr "" +#~ " \\g [FICHIER] ou ; envoie le tampon de requêtes au serveur (et les\n" +#~ " résultats au fichier ou |tube)\n" + +#~ msgid "old_version" +#~ msgstr "ancienne_version" + +#~ msgid "from_list" +#~ msgstr "liste_from" + +#~ msgid "normal" +#~ msgstr "normal" + +#~ msgid "Procedure" +#~ msgstr "Procédure" + +#~ msgid " SERVER_VERSION_NAME server's version (short string)\n" +#~ msgstr " SERVER_VERSION_NAME version du serveur (chaîne courte)\n" + +#~ msgid " VERSION psql's version (verbose string)\n" +#~ msgstr " VERSION version de psql (chaîne verbeuse)\n" + +#~ msgid " VERSION_NAME psql's version (short string)\n" +#~ msgstr " VERSION_NAME version de psql (chaîne courte)\n" + +#~ msgid " VERSION_NUM psql's version (numeric format)\n" +#~ msgstr " VERSION_NUM version de psql (format numérique)\n" + +#~ msgid "attribute" +#~ msgstr "attribut" + +#~ msgid "No per-database role settings support in this server version.\n" +#~ msgstr "Pas de supprot des paramètres rôle par base de données pour la version de ce serveur.\n" + +#~ msgid "No matching settings found.\n" +#~ msgstr "Aucun paramètre correspondant trouvé.\n" + +#~ msgid "No settings found.\n" +#~ msgstr "Aucun paramètre trouvé.\n" + +#~ msgid "No matching relations found.\n" +#~ msgstr "Aucune relation correspondante trouvée.\n" + +#~ msgid "No relations found.\n" +#~ msgstr "Aucune relation trouvée.\n" + +#~ msgid "Password encryption failed.\n" +#~ msgstr "Échec du chiffrement du mot de passe.\n" + +#~ msgid "\\%s: error while setting variable\n" +#~ msgstr "\\%s : erreur lors de l'initialisation de la variable\n" + +#~ msgid "+ opt(%d) = |%s|\n" +#~ msgstr "+ opt(%d) = |%s|\n" + +#~ msgid "could not set variable \"%s\"\n" +#~ msgstr "n'a pas pu initialiser la variable « %s »\n" + +#~ msgid "Modifiers" +#~ msgstr "Modificateurs" + +#~ msgid "collate %s" +#~ msgstr "collationnement %s" + +#~ msgid "not null" +#~ msgstr "non NULL" + +#~ msgid "default %s" +#~ msgstr "Par défaut, %s" + +#~ msgid "Modifier" +#~ msgstr "Modificateur" + +#~ msgid "Object Description" +#~ msgstr "Description d'un objet" + +#~ msgid "%s: could not set variable \"%s\"\n" +#~ msgstr "%s : n'a pas pu initialiser la variable « %s »\n" + +#~ msgid "Watch every %lds\t%s" +#~ msgstr "Vérifier chaque %lds\t%s" + +#~ msgid "Showing locale-adjusted numeric output." +#~ msgstr "Affichage de la sortie numérique adaptée à la locale." + +#~ msgid "Showing only tuples." +#~ msgstr "Affichage des tuples seuls." + +#~ msgid "could not get current user name: %s\n" +#~ msgstr "n'a pas pu obtenir le nom d'utilisateur courant : %s\n" + +#~ msgid "agg_name" +#~ msgstr "nom_d_agrégat" + +#~ msgid "agg_type" +#~ msgstr "type_aggrégat" + +#~ msgid "input_data_type" +#~ msgstr "type_de_données_en_entrée" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" + +#~ msgid "%s: pg_strdup: cannot duplicate null pointer (internal error)\n" +#~ msgstr "%s : pg_strdup : ne peut pas dupliquer le pointeur null (erreur interne)\n" + +#~ msgid " \\l[+] list all databases\n" +#~ msgstr " \\l[+] affiche la liste des bases de données\n" + +#~ msgid "\\%s: error\n" +#~ msgstr "\\%s : erreur\n" + +#~ msgid "\\copy: %s" +#~ msgstr "\\copy : %s" + +#~ msgid "\\copy: unexpected response (%d)\n" +#~ msgstr "\\copy : réponse inattendue (%d)\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide, puis quitte\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version, puis quitte\n" + +#~ msgid "contains support for command-line editing" +#~ msgstr "contient une gestion avancée de la ligne de commande" + +#~ msgid "data type" +#~ msgstr "type de données" + +#~ msgid "column" +#~ msgstr "colonne" + +#~ msgid "new_column" +#~ msgstr "nouvelle_colonne" + +#~ msgid "tablespace" +#~ msgstr "tablespace" + +#~ msgid " on host \"%s\"" +#~ msgstr " sur l'hôte « %s »" + +#~ msgid " at port \"%s\"" +#~ msgstr " sur le port « %s »" + +#~ msgid " as user \"%s\"" +#~ msgstr " comme utilisateur « %s »" + +#~ msgid "define a new constraint trigger" +#~ msgstr "définir une nouvelle contrainte de déclenchement" + +#~ msgid "Exclusion constraints:" +#~ msgstr "Contraintes d'exclusion :" + +#~ msgid "rolename" +#~ msgstr "nom_rôle" + +#~ msgid " \"%s\" IN %s %s" +#~ msgstr " \"%s\" DANS %s %s" + +#~ msgid "(1 row)" +#~ msgid_plural "(%lu rows)" +#~ msgstr[0] "(1 ligne)" +#~ msgstr[1] "(%lu lignes)" + +#~ msgid "" +#~ " \\d{t|i|s|v|S} [PATTERN] (add \"+\" for more detail)\n" +#~ " list tables/indexes/sequences/views/system tables\n" +#~ msgstr "" +#~ " \\d{t|i|s|v|S} [MODÈLE] (ajouter « + » pour plus de détails)\n" +#~ " affiche la liste des\n" +#~ " tables/index/séquences/vues/tables système\n" + +#~ msgid " \\db [PATTERN] list tablespaces (add \"+\" for more detail)\n" +#~ msgstr "" +#~ " \\db [MODÈLE] affiche la liste des tablespaces (ajouter « + » pour\n" +#~ " plus de détails)\n" + +#~ msgid " \\df [PATTERN] list functions (add \"+\" for more detail)\n" +#~ msgstr "" +#~ " \\df [MODÈLE] affiche la liste des fonctions (ajouter « + » pour\n" +#~ " plus de détails)\n" + +#~ msgid " \\dFd [PATTERN] list text search dictionaries (add \"+\" for more detail)\n" +#~ msgstr "" +#~ " \\dFd [MODÈLE] affiche la liste des dictionnaires de la recherche\n" +#~ " de texte (ajouter « + » pour plus de détails)\n" + +#~ msgid " \\dFp [PATTERN] list text search parsers (add \"+\" for more detail)\n" +#~ msgstr "" +#~ " \\dFp [MODÈLE] affiche la liste des analyseurs de la recherche de\n" +#~ " texte (ajouter « + » pour plus de détails)\n" + +#~ msgid " \\dn [PATTERN] list schemas (add \"+\" for more detail)\n" +#~ msgstr "" +#~ " \\dn [MODÈLE] affiche la liste des schémas (ajouter « + » pour\n" +#~ " plus de détails)\n" + +#~ msgid " \\dT [PATTERN] list data types (add \"+\" for more detail)\n" +#~ msgstr "" +#~ " \\dT [MODÈLE] affiche la liste des types de données (ajouter « + »\n" +#~ " pour plus de détails)\n" + +#~ msgid " \\l list all databases (add \"+\" for more detail)\n" +#~ msgstr "" +#~ " \\l affiche la liste des bases de données (ajouter « + »\n" +#~ " pour plus de détails)\n" + +#~ msgid " \\z [PATTERN] list table, view, and sequence access privileges (same as \\dp)\n" +#~ msgstr "" +#~ " \\z [MODÈLE] affiche la liste des privilèges d'accès aux tables,\n" +#~ " vues et séquences (identique à \\dp)\n" + +#~ msgid "Copy, Large Object\n" +#~ msgstr "Copie, « Large Object »\n" + +#~ msgid "" +#~ "Welcome to %s %s (server %s), the PostgreSQL interactive terminal.\n" +#~ "\n" +#~ msgstr "" +#~ "Bienvenue dans %s %s (serveur %s), l'interface interactive de PostgreSQL.\n" +#~ "\n" + +#~ msgid "" +#~ "Welcome to %s %s, the PostgreSQL interactive terminal.\n" +#~ "\n" +#~ msgstr "" +#~ "Bienvenue dans %s %s, l'interface interactive de PostgreSQL.\n" +#~ "\n" + +#~ msgid "" +#~ "WARNING: You are connected to a server with major version %d.%d,\n" +#~ "but your %s client is major version %d.%d. Some backslash commands,\n" +#~ "such as \\d, might not work properly.\n" +#~ "\n" +#~ msgstr "" +#~ "ATTENTION : vous êtes connecté sur un serveur dont la version majeure est\n" +#~ "%d.%d alors que votre client %s est en version majeure %d.%d. Certaines\n" +#~ "commandes avec antislashs, comme \\d, peuvent ne pas fonctionner\n" +#~ "correctement.\n" +#~ "\n" + +#~ msgid "Access privileges for database \"%s\"" +#~ msgstr "Droits d'accès pour la base de données « %s »" + +#~ msgid "?%c? \"%s.%s\"" +#~ msgstr "?%c? « %s.%s »" + +#~ msgid " \"%s\"" +#~ msgstr " « %s »" + +#~ msgid "(No rows)\n" +#~ msgstr "(Aucune ligne)\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help affiche cette aide puis quitte\n" + +#~ msgid "SSL connection (unknown cipher)\n" +#~ msgstr "Connexion SSL (chiffrement inconnu)\n" + +#~ msgid "serialtype" +#~ msgstr "serialtype" + +#~ msgid "statistic_type" +#~ msgstr "type_statistique" + +#~ msgid "Value" +#~ msgstr "Valeur" + +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le journal applicatif « %s » : %s\n" + +#~ msgid "string_literal" +#~ msgstr "littéral_chaîne" + +#~ msgid "unterminated quoted string\n" +#~ msgstr "chaîne entre guillemets non terminée\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapportez les bogues à .\n" + +#~ msgid "%s\n" +#~ msgstr "%s\n" + +#~ msgid "could not close pipe to external command: %s\n" +#~ msgstr "n'a pas pu fermer le fichier pipe vers la commande externe : %s\n" + +#~ msgid "could not stat file \"%s\": %s\n" +#~ msgstr "n'a pas pu tester le fichier « %s » : %s\n" + +#~ msgid "could not execute command \"%s\": %s\n" +#~ msgstr "n'a pas pu exécuter la commande « %s » : %s\n" + +#~ msgid "could not open temporary file \"%s\": %s\n" +#~ msgstr "n'a pas pu ouvrir le fichier temporaire « %s » : %s\n" + +#~ msgid "%s: %s\n" +#~ msgstr "%s : %s\n" + +#~ msgid "Invalid command \\%s. Try \\? for help.\n" +#~ msgstr "Commande \\%s invalide. Essayez \\? pour l'aide-mémoire.\n" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "le processus fils a été terminé par le signal %d" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "pclose failed: %s" +#~ msgstr "échec de pclose : %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu changer le répertoire par « %s » : %s" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "n'a pas pu identifier le répertoire courant : %s" + +#~ msgid "All connection parameters must be supplied because no database connection exists" +#~ msgstr "Tous les paramètres de connexion doivent être fournis car il n'existe pas de connexion à une base de données" + +#~ msgid "collation_name" +#~ msgstr "nom_collation" diff --git a/src/bin/psql/po/ja.po b/src/bin/psql/po/ja.po new file mode 100644 index 000000000000..f33e5e97f416 --- /dev/null +++ b/src/bin/psql/po/ja.po @@ -0,0 +1,6497 @@ +# Japanese message translation file for psql +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# Michihide Hotta , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: psql (PostgreSQL 13)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-21 15:55+0900\n" +"PO-Revision-Date: 2020-09-13 09:00+0200\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: Japan PostgreSQL Users Group \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.13\n" + +#: ../../../src/common/logging.c:241 +#, c-format +msgid "fatal: " +msgstr "致命的エラー: " + +#: ../../../src/common/logging.c:248 +#, c-format +msgid "error: " +msgstr "エラー: " + +#: ../../../src/common/logging.c:255 +#, c-format +msgid "warning: " +msgstr "警告: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "カレントディレクトリを識別できませんでした: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "無効なバイナリ\"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "バイナリ\"%s\"を読み取ることができませんでした" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "実行対象の\"%s\"が見つかりませんでした" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "ディレクトリ\"%s\"に移動できませんでした: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読めませんでした: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pcloseが失敗しました: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: command.c:1255 input.c:227 mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "メモリ不足です" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "メモリ不足です\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ポインターを複製することはできません(内部エラー) \n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "実効ユーザID %ld が見つかりませんでした: %s" + +#: ../../common/username.c:45 command.c:559 +msgid "user does not exist" +msgstr "ユーザが存在しません" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "ユーザ名の検索に失敗: エラー コード %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "コマンドが実行形式ではありません" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "コマンドが見つかりません" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "子プロセスが終了コード %d で終了しました" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "子プロセスが例外 0x%X で強制終了しました" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "子プロセスはシグナル%dにより終了しました: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "子プロセスは認識できないステータス %d で終了しました" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "キャンセル要求を送信しました\n" + +#: ../../fe_utils/cancel.c:165 +msgid "Could not send cancel request: " +msgstr "キャンセル要求を送信できませんでした: " + +#: ../../fe_utils/cancel.c:210 +#, c-format +msgid "Could not send cancel request: %s" +msgstr "キャンセル要求を送信できませんでした: %s" + +#: ../../fe_utils/print.c:336 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu 行)" + +#: ../../fe_utils/print.c:3039 +#, c-format +msgid "Interrupted\n" +msgstr "割り込み\n" + +#: ../../fe_utils/print.c:3103 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "テーブルの内容にヘッダーを追加できません: 列数 %d が制限値を超えています。\n" + +#: ../../fe_utils/print.c:3143 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "テーブルの内容にセルを追加できません: セルの合計数 %d が制限値を超えています。\n" + +#: ../../fe_utils/print.c:3398 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "出力フォーマットが無効(内部エラー):%d" + +#: command.c:224 +#, c-format +msgid "invalid command \\%s" +msgstr "不正なコマンド \\%s " + +#: command.c:226 +#, c-format +msgid "Try \\? for help." +msgstr " \\? でヘルプを表示します。" + +#: command.c:244 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: 余分な引数\"%s\"は無視されました" + +#: command.c:296 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "\\%s コマンドは無視されます; 現在の\\ifブロックを抜けるには\\endifまたはCtrl-Cを使用します" + +#: command.c:557 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "ユーザID %ldのホームディレクトリを取得できませんでした : %s" + +#: command.c:575 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: ディレクトリを\"%s\"に変更できませんでした: %m" + +#: command.c:600 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "現在データベースに接続していません。\n" + +#: command.c:613 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、ホスト\"%s\"上のポート\"%s\"で接続しています。\n" + +#: command.c:616 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、\"%s\"のソケットを介してポート\"%s\"で接続しています。\n" + +#: command.c:622 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、ホスト\"%s\"(アドレス\"%s\")上のポート\"%s\"で接続しています。\n" + +#: command.c:625 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、ホスト\"%s\"上のポート\"%s\"で接続しています。\n" + +#: command.c:965 command.c:1061 command.c:2550 +#, c-format +msgid "no query buffer" +msgstr "問い合わせバッファがありません" + +#: command.c:998 command.c:5061 +#, c-format +msgid "invalid line number: %s" +msgstr "不正な行番号です: %s" + +#: command.c:1052 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "このサーバ(バージョン%s)は関数ソースコードの編集をサポートしていません。" + +#: command.c:1055 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "このサーバ(バージョン%s)はビュー定義の編集をサポートしていません。" + +#: command.c:1137 +msgid "No changes" +msgstr "変更されていません" + +#: command.c:1216 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: エンコーディング名が不正であるか、または変換プロシージャが見つかりません。" + +#: command.c:1251 command.c:1992 command.c:3253 command.c:5163 common.c:174 +#: common.c:223 common.c:388 common.c:1237 common.c:1265 common.c:1373 +#: common.c:1480 common.c:1518 copy.c:488 copy.c:707 help.c:62 large_obj.c:157 +#: large_obj.c:192 large_obj.c:254 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1258 +msgid "There is no previous error." +msgstr "直前のエラーはありません。" + +#: command.c:1371 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: 右括弧がありません" + +#: command.c:1548 command.c:1853 command.c:1867 command.c:1884 command.c:2044 +#: command.c:2281 command.c:2517 command.c:2557 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s: 必要な引数がありません" + +#: command.c:1679 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: \\else の後には置けません" + +#: command.c:1684 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif: 対応する \\if がありません" + +#: command.c:1748 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else: \\else の後には置けません" + +#: command.c:1753 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else: 対応する \\if がありません" + +#: command.c:1793 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif: 対応する \\if がありません" + +#: command.c:1948 +msgid "Query buffer is empty." +msgstr "問い合わせバッファは空です。" + +#: command.c:1970 +msgid "Enter new password: " +msgstr "新しいパスワードを入力してください: " + +#: command.c:1971 +msgid "Enter it again: " +msgstr "もう一度入力してください: " + +#: command.c:1975 +#, c-format +msgid "Passwords didn't match." +msgstr "パスワードが一致しませんでした。" + +#: command.c:2074 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s: 変数の値を読み取ることができませんでした" + +#: command.c:2177 +msgid "Query buffer reset (cleared)." +msgstr "問い合わせバッファがリセット(クリア)されました。" + +#: command.c:2199 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "ファイル\"%s\"にヒストリーを出力しました。\n" + +#: command.c:2286 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: 環境変数名に\"=\"を含めることはできません" + +#: command.c:2347 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "このサーバ(バージョン%s)は関数ソースの表示をサポートしていません。" + +#: command.c:2350 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "このサーバ(バージョン%s)はビュー定義の表示をサポートしていません。" + +#: command.c:2357 +#, c-format +msgid "function name is required" +msgstr "関数名が必要です" + +#: command.c:2359 +#, c-format +msgid "view name is required" +msgstr "ビュー名が必要です" + +#: command.c:2489 +msgid "Timing is on." +msgstr "タイミングは on です。" + +#: command.c:2491 +msgid "Timing is off." +msgstr "タイミングは off です。" + +#: command.c:2576 command.c:2604 command.c:3661 command.c:3664 command.c:3667 +#: command.c:3673 command.c:3675 command.c:3683 command.c:3693 command.c:3702 +#: command.c:3716 command.c:3733 command.c:3791 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:2988 startup.c:236 startup.c:287 +msgid "Password: " +msgstr "パスワード: " + +#: command.c:2993 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "ユーザ %s のパスワード: " + +#: command.c:3064 +#, c-format +msgid "All connection parameters must be supplied because no database connection exists" +msgstr "既存のデータベース接続がないため、すべての接続パラメータを指定しなければなりません" + +#: command.c:3257 +#, c-format +msgid "Previous connection kept" +msgstr "以前の接続は保持されています" + +#: command.c:3261 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3310 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、ホスト\"%s\"のポート\"%s\"で接続しました。\n" + +#: command.c:3313 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、ソケット\"%s\"のポート\"%s\"を介して接続しました。\n" + +#: command.c:3319 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、ホスト\"%s\"(アドレス\"%s\")のポート\"%s\"で接続しました。\n" + +#: command.c:3322 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として、ホスト\"%s\"のポート\"%s\"を介して接続しました。\n" + +#: command.c:3327 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "データベース\"%s\"にユーザ\"%s\"として接続しました。\n" + +#: command.c:3360 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s、サーバ %s)\n" + +#: command.c:3368 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"警告: %s のメジャーバージョンは %s ですが、サーバのメジャーバージョンは %s です。\n" +" psql の機能の中で、動作しないものがあるかもしれません。\n" + +#: command.c:3407 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL 接続 (プロトコル: %s、暗号化方式: %s、ビット長: %s、圧縮: %s)\n" + +#: command.c:3408 command.c:3409 command.c:3410 +msgid "unknown" +msgstr "不明" + +#: command.c:3411 help.c:45 +msgid "off" +msgstr "オフ" + +#: command.c:3411 help.c:45 +msgid "on" +msgstr "オン" + +#: command.c:3425 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "GSSAPI暗号化接続\n" + +#: command.c:3445 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"警告:コンソールのコードページ(%u)がWindowsのコードページ(%u)と異なるため、\n" +" 8ビット文字が正しく表示されない可能性があります。詳細はpsqlリファレンスマニュアルの\n" +" \"Windowsユーザ向けの注意\" (Notes for Windows users)を参照してください。\n" + +#: command.c:3549 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "環境変数PSQL_EDITOR_LINENUMBER_ARGで行番号を指定する必要があります" + +#: command.c:3578 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "エディタ\"%s\"を起動できませんでした" + +#: command.c:3580 +#, c-format +msgid "could not start /bin/sh" +msgstr "/bin/shを起動できませんでした" + +#: command.c:3618 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "一時ディレクトリが見つかりませんでした: %s" + +#: command.c:3645 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "一時ファイル\"%s\"をオープンできませんでした: %m" + +#: command.c:3950 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: 曖昧な短縮形\"%s\"が\"%s\"と\"%s\"のどちらにも合致します" + +#: command.c:3970 +#, c-format +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: 有効なフォーマットはaligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" + +#: command.c:3989 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: 有効な線のスタイルは ascii, old-ascii, unicode" + +#: command.c:4004 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: 有効な Unicode 罫線のスタイルは single, double" + +#: command.c:4019 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: 有効な Unicode 列罫線のスタイルは single, double" + +#: command.c:4034 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: 有効な Unicode ヘッダー罫線のスタイルは single, double" + +#: command.c:4077 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsepは単一の1バイト文字でなければなりません" + +#: command.c:4082 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldsepはダブルクォート、改行(LF)または復帰(CR)にはできません" + +#: command.c:4219 command.c:4407 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset: 未定義のオプション:%s" + +#: command.c:4239 +#, c-format +msgid "Border style is %d.\n" +msgstr "罫線スタイルは %d です。\n" + +#: command.c:4245 +#, c-format +msgid "Target width is unset.\n" +msgstr "ターゲットの幅が設定されていません。\n" + +#: command.c:4247 +#, c-format +msgid "Target width is %d.\n" +msgstr "ターゲットの幅は %d です。\n" + +#: command.c:4254 +#, c-format +msgid "Expanded display is on.\n" +msgstr "拡張表示は on です。\n" + +#: command.c:4256 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "拡張表示が自動的に使われます。\n" + +#: command.c:4258 +#, c-format +msgid "Expanded display is off.\n" +msgstr "拡張表示は off です。\n" + +#: command.c:4264 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "CSVのフィールド区切り文字は\"%s\"です。\n" + +#: command.c:4272 command.c:4280 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "フィールド区切り文字はゼロバイトです。\n" + +#: command.c:4274 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "フィールド区切り文字は\"%s\"です。\n" + +#: command.c:4287 +#, c-format +msgid "Default footer is on.\n" +msgstr "デフォルトフッター(行数の表示)は on です。\n" + +#: command.c:4289 +#, c-format +msgid "Default footer is off.\n" +msgstr "デフォルトフッター(行数の表示)は off です。\n" + +#: command.c:4295 +#, c-format +msgid "Output format is %s.\n" +msgstr "出力形式は %s です。\n" + +#: command.c:4301 +#, c-format +msgid "Line style is %s.\n" +msgstr "線のスタイルは %s です。\n" + +#: command.c:4308 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Null表示は\"%s\"です。\n" + +#: command.c:4316 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "『数値出力時のロケール調整』は on です。\n" + +#: command.c:4318 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "『数値出力時のロケール調整』は off です。\n" + +#: command.c:4325 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "表示が縦に長くなる場合はページャーを使います。\n" + +#: command.c:4327 +#, c-format +msgid "Pager is always used.\n" +msgstr "常にページャーを使います。\n" + +#: command.c:4329 +#, c-format +msgid "Pager usage is off.\n" +msgstr "「ページャーを使う」は off です。\n" + +#: command.c:4335 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "%d 行未満の場合、ページャーは使われません。\n" + +#: command.c:4345 command.c:4355 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "レコードの区切り文字はゼロバイトです\n" + +#: command.c:4347 +#, c-format +msgid "Record separator is .\n" +msgstr "レコード区切り文字はです。\n" + +#: command.c:4349 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "レコード区切り記号は\"%s\"です。\n" + +#: command.c:4362 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "テーブル属性は\"%s\"です。\n" + +#: command.c:4365 +#, c-format +msgid "Table attributes unset.\n" +msgstr "テーブル属性は設定されていません。\n" + +#: command.c:4372 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "タイトルは\"%s\"です。\n" + +#: command.c:4374 +#, c-format +msgid "Title is unset.\n" +msgstr "タイトルは設定されていません。\n" + +#: command.c:4381 +#, c-format +msgid "Tuples only is on.\n" +msgstr "「タプルのみ表示」は on です。\n" + +#: command.c:4383 +#, c-format +msgid "Tuples only is off.\n" +msgstr "「タプルのみ表示」は off です。\n" + +#: command.c:4389 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Unicode の罫線スタイルは\"%s\"です。\n" + +#: command.c:4395 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Unicode 行罫線のスタイルは\"%s\"です。\n" + +#: command.c:4401 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Unicodeヘッダー行のスタイルは\"%s\"です。\n" + +#: command.c:4634 +#, c-format +msgid "\\!: failed" +msgstr "\\!: 失敗" + +#: command.c:4659 common.c:648 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watchは空の問い合わせでは使えません" + +#: command.c:4700 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (%g 秒毎)\n" + +#: command.c:4703 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (%g 秒毎)\n" + +#: command.c:4757 command.c:4764 common.c:548 common.c:555 common.c:1220 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"******** 問い合わせ ******\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:4956 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "\"%s.%s\"はビューではありません" + +#: command.c:4972 +#, c-format +msgid "could not parse reloptions array" +msgstr "reloptions配列をパースできませんでした" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "有効な接続がないのでエスケープできません" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "シェルコマンドの引数に改行(LF)または復帰(CR)が含まれています: \"%s\"" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "サーバへの接続が失われました" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "サーバへの接続が失われました。リセットしています: " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "失敗。\n" + +#: common.c:326 +#, c-format +msgid "Succeeded.\n" +msgstr "成功。\n" + +#: common.c:378 common.c:938 common.c:1155 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "想定外のPQresultStatus: %d" + +#: common.c:487 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "時間: %.3f ミリ秒\n" + +#: common.c:502 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "時間: %.3f ミリ秒(%02d:%06.3f)\n" + +#: common.c:511 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "時間: %.3f ミリ秒 (%02d:%02d:%06.3f)\n" + +#: common.c:518 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "時間: %.3f ミリ秒 (%.0f 日 %02d:%02d:%06.3f)\n" + +#: common.c:542 common.c:600 common.c:1191 +#, c-format +msgid "You are currently not connected to a database." +msgstr "現在データベースに接続していません。" + +#: common.c:655 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watchはCOPYと一緒には使えません" + +#: common.c:660 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "\\watchで想定外の結果ステータス" + +#: common.c:690 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "PID %3$dのサーバプロセスから、ペイロード\"%2$s\"を持つ非同期通知\"%1$s\"を受信しました。\n" + +#: common.c:693 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "PID %2$dのサーバプロセスから非同期通知\"%1$s\"を受信しました。\n" + +#: common.c:726 common.c:743 +#, c-format +msgid "could not print result table: %m" +msgstr "結果テーブルを表示できませんでした: %m" + +#: common.c:764 +#, c-format +msgid "no rows returned for \\gset" +msgstr "\\gset に対して返すべき行がありません" + +#: common.c:769 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "\\gset に対して複数の行が返されました" + +#: common.c:1200 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(シングルステップモード: コマンドを確認してください)********\n" +"%s\n" +"***([Enter] を押して進むか、x [Enter] でキャンセル)**************\n" + +#: common.c:1255 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "このサーバ(バージョン%s)はON_ERROR_ROLLBACKのためのセーブポイントをサポートしていません。" + +#: common.c:1318 +#, c-format +msgid "STATEMENT: %s" +msgstr "ステートメント: %s" + +#: common.c:1361 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "想定外のトランザクション状態(%d)" + +#: common.c:1502 describe.c:2001 +msgid "Column" +msgstr "列" + +#: common.c:1503 describe.c:177 describe.c:393 describe.c:411 describe.c:456 +#: describe.c:473 describe.c:962 describe.c:1126 describe.c:1711 +#: describe.c:1735 describe.c:2002 describe.c:3719 describe.c:3929 +#: describe.c:4162 describe.c:5368 +msgid "Type" +msgstr "タイプ" + +#: common.c:1552 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "このコマンドは結果を返却しないか、結果にカラムが含まれません。\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy: 引数が必要です" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: \"%s\"で構文解析エラー" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: 行の末尾で構文解析エラー" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "コマンド\"%s\"を実行できませんでした: %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "ファイル\"%s\"のstatに失敗しました: %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s: ディレクトリから/へのコピーはできません" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "外部コマンドに対するパイプをクローズできませんでした: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "COPY データを書き込めませんでした: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "COPY データの転送に失敗しました: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "ユーザによってキャンセルされました" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"コピーするデータに続いて改行を入力してください。\n" +"バックスラッシュとピリオドだけの行、もしくは EOF シグナルで終了します。" + +#: copy.c:669 +msgid "aborted because of read failure" +msgstr "読み取りエラーのため中止" + +#: copy.c:703 +msgid "trying to exit copy mode" +msgstr "コピーモードを終了しようとしています。" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: ステートメントは結果セットを返しませんでした" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: 問い合わせは、少なくとも3つの列を返す必要があります" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: 垂直方向と水平方向のヘッダーは異なった列にする必要があります" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: 問い合わせが 4 つ以上の列を返す場合、データ列を指定する必要があります" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "列数が制限値(%d)を超えています" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: 問い合わせ結果の中の\"%s\"行 \"%s\"列に複数のデータ値が含まれています" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: 列番号%dが範囲外です(1..%d)" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: 列名があいまいです: \"%s\"" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: 列名が見つかりませんでした: \"%s\"" + +#: describe.c:75 describe.c:373 describe.c:678 describe.c:810 describe.c:954 +#: describe.c:1115 describe.c:1187 describe.c:3708 describe.c:3916 +#: describe.c:4160 describe.c:4251 describe.c:4518 describe.c:4678 +#: describe.c:4919 describe.c:4994 describe.c:5005 describe.c:5067 +#: describe.c:5492 describe.c:5575 +msgid "Schema" +msgstr "スキーマ" + +#: describe.c:76 describe.c:174 describe.c:242 describe.c:250 describe.c:374 +#: describe.c:679 describe.c:811 describe.c:872 describe.c:955 describe.c:1188 +#: describe.c:3709 describe.c:3917 describe.c:4083 describe.c:4161 +#: describe.c:4252 describe.c:4331 describe.c:4519 describe.c:4603 +#: describe.c:4679 describe.c:4920 describe.c:4995 describe.c:5006 +#: describe.c:5068 describe.c:5265 describe.c:5349 describe.c:5573 +#: describe.c:5745 describe.c:5985 +msgid "Name" +msgstr "名前" + +#: describe.c:77 describe.c:386 describe.c:404 describe.c:450 describe.c:467 +msgid "Result data type" +msgstr "結果のデータ型" + +#: describe.c:85 describe.c:98 describe.c:102 describe.c:387 describe.c:405 +#: describe.c:451 describe.c:468 +msgid "Argument data types" +msgstr "引数のデータ型" + +#: describe.c:110 describe.c:117 describe.c:185 describe.c:273 describe.c:513 +#: describe.c:727 describe.c:826 describe.c:897 describe.c:1190 describe.c:2020 +#: describe.c:3496 describe.c:3769 describe.c:3963 describe.c:4114 +#: describe.c:4188 describe.c:4261 describe.c:4344 describe.c:4427 +#: describe.c:4546 describe.c:4612 describe.c:4680 describe.c:4821 +#: describe.c:4863 describe.c:4936 describe.c:4998 describe.c:5007 +#: describe.c:5069 describe.c:5291 describe.c:5371 describe.c:5506 +#: describe.c:5576 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "説明" + +#: describe.c:135 +msgid "List of aggregate functions" +msgstr "集約関数一覧" + +#: describe.c:160 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "このサーバ(バージョン%s)はアクセスメソッドをサポートしていません。" + +#: describe.c:175 +msgid "Index" +msgstr "インデックス" + +#: describe.c:176 describe.c:3727 describe.c:3942 describe.c:5493 +msgid "Table" +msgstr "テーブル" + +#: describe.c:184 describe.c:5270 +msgid "Handler" +msgstr "ハンドラ" + +#: describe.c:203 +msgid "List of access methods" +msgstr "アクセスメソッド一覧" + +#: describe.c:229 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "このサーバ(バージョン%s) はテーブル空間をサポートしていません。" + +#: describe.c:243 describe.c:251 describe.c:501 describe.c:717 describe.c:873 +#: describe.c:1114 describe.c:3720 describe.c:3918 describe.c:4087 +#: describe.c:4333 describe.c:4604 describe.c:5266 describe.c:5350 +#: describe.c:5746 describe.c:5883 describe.c:5986 describe.c:6107 +#: describe.c:6186 large_obj.c:289 +msgid "Owner" +msgstr "所有者" + +#: describe.c:244 describe.c:252 +msgid "Location" +msgstr "場所" + +#: describe.c:263 describe.c:3313 +msgid "Options" +msgstr "オプション" + +#: describe.c:268 describe.c:690 describe.c:889 describe.c:3761 describe.c:3765 +msgid "Size" +msgstr "サイズ" + +#: describe.c:290 +msgid "List of tablespaces" +msgstr "テーブル空間一覧" + +#: describe.c:333 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\dfで指定できるオプションは [anptwS+] のみです" + +#: describe.c:341 describe.c:352 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\dfはこのサーババージョン%2$sでは\"%1$c\"オプションは指定できません" + +#. translator: "agg" is short for "aggregate" +#: describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "agg" +msgstr "集約" + +#: describe.c:390 describe.c:408 +msgid "window" +msgstr "ウィンドウ" + +#: describe.c:391 +msgid "proc" +msgstr "プロシージャ" + +#: describe.c:392 describe.c:410 describe.c:455 describe.c:472 +msgid "func" +msgstr "関数" + +#: describe.c:409 describe.c:454 describe.c:471 describe.c:1324 +msgid "trigger" +msgstr "トリガー" + +#: describe.c:483 +msgid "immutable" +msgstr "IMMUTABLE" + +#: describe.c:484 +msgid "stable" +msgstr "STABLE" + +#: describe.c:485 +msgid "volatile" +msgstr "VOLATILE" + +#: describe.c:486 +msgid "Volatility" +msgstr "関数の変動性分類" + +#: describe.c:494 +msgid "restricted" +msgstr "制限付き" + +#: describe.c:495 +msgid "safe" +msgstr "安全" + +#: describe.c:496 +msgid "unsafe" +msgstr "危険" + +#: describe.c:497 +msgid "Parallel" +msgstr "並列実行" + +#: describe.c:502 +msgid "definer" +msgstr "定義ロール" + +#: describe.c:503 +msgid "invoker" +msgstr "起動ロール" + +#: describe.c:504 +msgid "Security" +msgstr "セキュリティ" + +#: describe.c:511 +msgid "Language" +msgstr "手続き言語" + +#: describe.c:512 +msgid "Source code" +msgstr "ソースコード" + +#: describe.c:641 +msgid "List of functions" +msgstr "関数一覧" + +#: describe.c:689 +msgid "Internal name" +msgstr "内部名" + +#: describe.c:711 +msgid "Elements" +msgstr "構成要素" + +#: describe.c:768 +msgid "List of data types" +msgstr "データ型一覧" + +#: describe.c:812 +msgid "Left arg type" +msgstr "左辺の型" + +#: describe.c:813 +msgid "Right arg type" +msgstr "右辺の型" + +#: describe.c:814 +msgid "Result type" +msgstr "結果の型" + +#: describe.c:819 describe.c:4339 describe.c:4404 describe.c:4410 +#: describe.c:4820 describe.c:6358 describe.c:6362 +msgid "Function" +msgstr "関数" + +#: describe.c:844 +msgid "List of operators" +msgstr "演算子一覧" + +#: describe.c:874 +msgid "Encoding" +msgstr "エンコーディング" + +#: describe.c:879 describe.c:4520 +msgid "Collate" +msgstr "照合順序" + +#: describe.c:880 describe.c:4521 +msgid "Ctype" +msgstr "Ctype(変換演算子)" + +#: describe.c:893 +msgid "Tablespace" +msgstr "テーブル空間" + +#: describe.c:915 +msgid "List of databases" +msgstr "データベース一覧" + +#: describe.c:956 describe.c:1117 describe.c:3710 +msgid "table" +msgstr "テーブル" + +#: describe.c:957 describe.c:3711 +msgid "view" +msgstr "ビュー" + +#: describe.c:958 describe.c:3712 +msgid "materialized view" +msgstr "マテリアライズドビュー" + +#: describe.c:959 describe.c:1119 describe.c:3714 +msgid "sequence" +msgstr "シーケンス" + +#: describe.c:960 describe.c:3716 +msgid "foreign table" +msgstr "外部テーブル" + +#: describe.c:961 describe.c:3717 describe.c:3927 +msgid "partitioned table" +msgstr "パーティションテーブル" + +#: describe.c:973 +msgid "Column privileges" +msgstr "列の権限" + +#: describe.c:1004 describe.c:1038 +msgid "Policies" +msgstr "ポリシー" + +#: describe.c:1070 describe.c:6048 describe.c:6052 +msgid "Access privileges" +msgstr "アクセス権限" + +#: describe.c:1101 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "このサーバ(バージョン%s)はデフォルト権限の変更をサポートしていません。" + +#: describe.c:1121 +msgid "function" +msgstr "関数" + +#: describe.c:1123 +msgid "type" +msgstr "型" + +#: describe.c:1125 +msgid "schema" +msgstr "スキーマ" + +#: describe.c:1149 +msgid "Default access privileges" +msgstr "デフォルトのアクセス権限" + +#: describe.c:1189 +msgid "Object" +msgstr "オブジェクト" + +#: describe.c:1203 +msgid "table constraint" +msgstr "テーブル制約" + +#: describe.c:1225 +msgid "domain constraint" +msgstr "ドメイン制約" + +#: describe.c:1253 +msgid "operator class" +msgstr "演算子クラス" + +#: describe.c:1282 +msgid "operator family" +msgstr "演算子族" + +#: describe.c:1304 +msgid "rule" +msgstr "ルール" + +#: describe.c:1346 +msgid "Object descriptions" +msgstr "オブジェクトの説明" + +#: describe.c:1402 describe.c:3833 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "\"%s\"という名前のリレーションは見つかりませんでした。" + +#: describe.c:1405 describe.c:3836 +#, c-format +msgid "Did not find any relations." +msgstr "リレーションが見つかりませんでした。" + +#: describe.c:1660 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "OID %sを持つリレーションが見つかりませんでした。" + +#: describe.c:1712 describe.c:1736 +msgid "Start" +msgstr "開始" + +#: describe.c:1713 describe.c:1737 +msgid "Minimum" +msgstr "最小" + +#: describe.c:1714 describe.c:1738 +msgid "Maximum" +msgstr "最大" + +#: describe.c:1715 describe.c:1739 +msgid "Increment" +msgstr "増分" + +#: describe.c:1716 describe.c:1740 describe.c:1871 describe.c:4255 +#: describe.c:4421 describe.c:4535 describe.c:4540 describe.c:6095 +msgid "yes" +msgstr "はい" + +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4255 +#: describe.c:4418 describe.c:4535 describe.c:6096 +msgid "no" +msgstr "いいえ" + +#: describe.c:1718 describe.c:1742 +msgid "Cycles?" +msgstr "循環?" + +#: describe.c:1719 describe.c:1743 +msgid "Cache" +msgstr "キャッシュ" + +#: describe.c:1786 +#, c-format +msgid "Owned by: %s" +msgstr "所有者: %s" + +#: describe.c:1790 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "識別列のシーケンス: %s" + +#: describe.c:1797 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "シーケンス \"%s.%s\"" + +#: describe.c:1933 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "ログを取らないテーブル\"%s.%s\"" + +#: describe.c:1936 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"" + +#: describe.c:1940 +#, c-format +msgid "View \"%s.%s\"" +msgstr "ビュー\"%s.%s\"" + +#: describe.c:1945 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "ログを取らないマテリアライズドビュー\"%s.%s\"" + +#: describe.c:1948 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "マテリアライズドビュー\"%s.%s\"" + +#: describe.c:1953 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "ログを取らないインデックス\"%s.%s\"" + +#: describe.c:1956 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "インデックス\"%s.%s\"" + +#: describe.c:1961 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "ログを取らないパーティションインデックス\"%s.%s\"" + +#: describe.c:1964 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "パーティションインデックス\"%s.%s\"" + +#: describe.c:1969 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "特殊なリレーション\"%s.%s\"" + +#: describe.c:1973 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "TOAST テーブル\"%s.%s\"" + +#: describe.c:1977 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "複合型\"%s.%s\"" + +#: describe.c:1981 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "外部テーブル\"%s.%s\"" + +#: describe.c:1986 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "ログを取らないパーティションテーブル\"%s.%s\"" + +#: describe.c:1989 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "パーティションテーブル\"%s.%s\"" + +#: describe.c:2005 describe.c:4168 +msgid "Collation" +msgstr "照合順序" + +#: describe.c:2006 describe.c:4175 +msgid "Nullable" +msgstr "Null 値を許容" + +#: describe.c:2007 describe.c:4176 +msgid "Default" +msgstr "デフォルト" + +#: describe.c:2010 +msgid "Key?" +msgstr "キー?" + +#: describe.c:2012 +msgid "Definition" +msgstr "定義" + +#: describe.c:2014 describe.c:5286 describe.c:5370 describe.c:5441 +#: describe.c:5505 +msgid "FDW options" +msgstr "FDW オプション" + +#: describe.c:2016 +msgid "Storage" +msgstr "ストレージ" + +#: describe.c:2018 +msgid "Stats target" +msgstr "統計目標" + +#: describe.c:2131 +#, c-format +msgid "Partition of: %s %s" +msgstr "パーティション: %s %s" + +#: describe.c:2143 +msgid "No partition constraint" +msgstr "パーティション制約なし" + +#: describe.c:2145 +#, c-format +msgid "Partition constraint: %s" +msgstr "パーティションの制約: %s" + +#: describe.c:2169 +#, c-format +msgid "Partition key: %s" +msgstr "パーティションキー: %s" + +#: describe.c:2195 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "所属先テーブル\"%s.%s\"" + +#: describe.c:2266 +msgid "primary key, " +msgstr "プライマリキー, " + +#: describe.c:2268 +msgid "unique, " +msgstr "ユニーク," + +#: describe.c:2274 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "テーブル\"%s.%s\"用" + +#: describe.c:2278 +#, c-format +msgid ", predicate (%s)" +msgstr "、述語 (%s)" + +#: describe.c:2281 +msgid ", clustered" +msgstr "、クラスター化" + +#: describe.c:2284 +msgid ", invalid" +msgstr "無効" + +#: describe.c:2287 +msgid ", deferrable" +msgstr "、遅延可能" + +#: describe.c:2290 +msgid ", initially deferred" +msgstr "、最初から遅延中" + +#: describe.c:2293 +msgid ", replica identity" +msgstr "、レプリカの id" + +#: describe.c:2360 +msgid "Indexes:" +msgstr "インデックス:" + +#: describe.c:2444 +msgid "Check constraints:" +msgstr "Check 制約:" + +#: describe.c:2512 +msgid "Foreign-key constraints:" +msgstr "外部キー制約:" + +#: describe.c:2575 +msgid "Referenced by:" +msgstr "参照元:" + +#: describe.c:2625 +msgid "Policies:" +msgstr "ポリシー:" + +#: describe.c:2628 +msgid "Policies (forced row security enabled):" +msgstr "ポリシー(行セキュリティを強制的に有効化):" + +#: describe.c:2631 +msgid "Policies (row security enabled): (none)" +msgstr "ポリシー(行セキュリティ有効化): (なし)" + +#: describe.c:2634 +msgid "Policies (forced row security enabled): (none)" +msgstr "ポリシー(行セキュリティを強制的に有効化): (なし)" + +#: describe.c:2637 +msgid "Policies (row security disabled):" +msgstr "ポリシー(行セキュリティを無効化):" + +#: describe.c:2700 +msgid "Statistics objects:" +msgstr "統計オブジェクト:" + +#: describe.c:2809 describe.c:2913 +msgid "Rules:" +msgstr "ルール:" + +#: describe.c:2812 +msgid "Disabled rules:" +msgstr "無効化されたルール:" + +#: describe.c:2815 +msgid "Rules firing always:" +msgstr "常に適用するルール:" + +#: describe.c:2818 +msgid "Rules firing on replica only:" +msgstr "レプリカ上でのみ適用するルール:" + +#: describe.c:2858 +msgid "Publications:" +msgstr "パブリケーション:" + +#: describe.c:2896 +msgid "View definition:" +msgstr "ビューの定義:" + +#: describe.c:3043 +msgid "Triggers:" +msgstr "トリガー:" + +#: describe.c:3047 +msgid "Disabled user triggers:" +msgstr "無効化されたユーザトリガ:" + +#: describe.c:3049 +msgid "Disabled triggers:" +msgstr "無効化されたトリガー:" + +#: describe.c:3052 +msgid "Disabled internal triggers:" +msgstr "無効化された内部トリガー:" + +#: describe.c:3055 +msgid "Triggers firing always:" +msgstr "常に適用するするトリガー:" + +#: describe.c:3058 +msgid "Triggers firing on replica only:" +msgstr "レプリカ上でのみ適用するトリガー:" + +#: describe.c:3130 +#, c-format +msgid "Server: %s" +msgstr "サーバ: %s" + +#: describe.c:3138 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW オプション: (%s)" + +#: describe.c:3159 +msgid "Inherits" +msgstr "継承元" + +#: describe.c:3219 +#, c-format +msgid "Number of partitions: %d" +msgstr "パーティション数: %d" + +#: describe.c:3228 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "パーティション数: %d (\\d+ で一覧を表示)。" + +#: describe.c:3230 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "子テーブル数: %d (\\d+ で一覧を表示)" + +#: describe.c:3237 +msgid "Child tables" +msgstr "子テーブル" + +#: describe.c:3237 +msgid "Partitions" +msgstr "パーティション" + +#: describe.c:3266 +#, c-format +msgid "Typed table of type: %s" +msgstr "%s 型の型付きテーブル" + +#: describe.c:3282 +msgid "Replica Identity" +msgstr "レプリカ識別" + +#: describe.c:3295 +msgid "Has OIDs: yes" +msgstr "OID あり: はい" + +#: describe.c:3304 +#, c-format +msgid "Access method: %s" +msgstr "アクセスメソッド: %s" + +#: describe.c:3384 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "テーブル空間: \"%s\"" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3396 +#, c-format +msgid ", tablespace \"%s\"" +msgstr "、テーブル空間\"%s\"" + +#: describe.c:3489 +msgid "List of roles" +msgstr "ロール一覧" + +#: describe.c:3491 +msgid "Role name" +msgstr "ロール名" + +#: describe.c:3492 +msgid "Attributes" +msgstr "属性" + +#: describe.c:3493 +msgid "Member of" +msgstr "所属グループ" + +#: describe.c:3504 +msgid "Superuser" +msgstr "スーパユーザ" + +#: describe.c:3507 +msgid "No inheritance" +msgstr "継承なし" + +#: describe.c:3510 +msgid "Create role" +msgstr "ロール作成可" + +#: describe.c:3513 +msgid "Create DB" +msgstr "DB作成可" + +#: describe.c:3516 +msgid "Cannot login" +msgstr "ログインできません" + +#: describe.c:3520 +msgid "Replication" +msgstr "レプリケーション可" + +#: describe.c:3524 +msgid "Bypass RLS" +msgstr "RLS のバイパス" + +#: describe.c:3533 +msgid "No connections" +msgstr "接続なし" + +#: describe.c:3535 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d 個の接続" + +#: describe.c:3545 +msgid "Password valid until " +msgstr "パスワードの有効期限 " + +#: describe.c:3595 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "このサーバ(バージョン%s)はデータベースごとのロール設定をサポートしていません。" + +#: describe.c:3608 +msgid "Role" +msgstr "ロール" + +#: describe.c:3609 +msgid "Database" +msgstr "データベース" + +#: describe.c:3610 +msgid "Settings" +msgstr "設定" + +#: describe.c:3631 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "ロール\"%s\"とデータベース\"%s\"の設定が見つかりませんでした。" + +#: describe.c:3634 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "ロール\"%s\"の設定が見つかりませんでした。" + +#: describe.c:3637 +#, c-format +msgid "Did not find any settings." +msgstr "設定が見つかりませんでした。" + +#: describe.c:3642 +msgid "List of settings" +msgstr "設定一覧" + +#: describe.c:3713 +msgid "index" +msgstr "インデックス" + +#: describe.c:3715 +msgid "special" +msgstr "特殊" + +#: describe.c:3718 describe.c:3928 +msgid "partitioned index" +msgstr "パーティションインデックス" + +#: describe.c:3742 +msgid "permanent" +msgstr "永続" + +#: describe.c:3743 +msgid "temporary" +msgstr "一時" + +#: describe.c:3744 +msgid "unlogged" +msgstr "ログなし" + +#: describe.c:3745 +msgid "Persistence" +msgstr "永続性" + +#: describe.c:3841 +msgid "List of relations" +msgstr "リレーション一覧" + +#: describe.c:3889 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "このサーバ(バージョン%s)は宣言的テーブルパーティショニングをサポートしていません。" + +#: describe.c:3900 +msgid "List of partitioned indexes" +msgstr "パーティションインデックスの一覧" + +#: describe.c:3902 +msgid "List of partitioned tables" +msgstr "パーティションテーブルの一覧" + +#: describe.c:3906 +msgid "List of partitioned relations" +msgstr "パーティションリレーションの一覧" + +#: describe.c:3937 +msgid "Parent name" +msgstr "親の名前" + +#: describe.c:3950 +msgid "Leaf partition size" +msgstr "末端パーティションのサイズ" + +#: describe.c:3953 describe.c:3959 +msgid "Total size" +msgstr "トータルサイズ" + +#: describe.c:4091 +msgid "Trusted" +msgstr "信頼済み" + +#: describe.c:4099 +msgid "Internal language" +msgstr "内部言語" + +#: describe.c:4100 +msgid "Call handler" +msgstr "呼び出しハンドラー" + +#: describe.c:4101 describe.c:5273 +msgid "Validator" +msgstr "バリデーター" + +#: describe.c:4104 +msgid "Inline handler" +msgstr "インラインハンドラー" + +#: describe.c:4132 +msgid "List of languages" +msgstr "手続き言語一覧" + +#: describe.c:4177 +msgid "Check" +msgstr "CHECK制約" + +#: describe.c:4219 +msgid "List of domains" +msgstr "ドメイン一覧" + +#: describe.c:4253 +msgid "Source" +msgstr "変換元" + +#: describe.c:4254 +msgid "Destination" +msgstr "変換先" + +#: describe.c:4256 describe.c:6097 +msgid "Default?" +msgstr "デフォルト?" + +#: describe.c:4293 +msgid "List of conversions" +msgstr "符号化方式一覧" + +#: describe.c:4332 +msgid "Event" +msgstr "イベント" + +#: describe.c:4334 +msgid "enabled" +msgstr "有効" + +#: describe.c:4335 +msgid "replica" +msgstr "レプリカ" + +#: describe.c:4336 +msgid "always" +msgstr "常時" + +#: describe.c:4337 +msgid "disabled" +msgstr "無効" + +#: describe.c:4338 describe.c:5987 +msgid "Enabled" +msgstr "有効状態" + +#: describe.c:4340 +msgid "Tags" +msgstr "タグ" + +#: describe.c:4359 +msgid "List of event triggers" +msgstr "イベントトリガー一覧" + +#: describe.c:4388 +msgid "Source type" +msgstr "変換元の型" + +#: describe.c:4389 +msgid "Target type" +msgstr "変換先の型" + +#: describe.c:4420 +msgid "in assignment" +msgstr "代入時のみ" + +#: describe.c:4422 +msgid "Implicit?" +msgstr "暗黙的に適用 ?" + +#: describe.c:4477 +msgid "List of casts" +msgstr "キャスト一覧" + +#: describe.c:4505 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "このサーバ(バージョン%s)は照合順序をサポートしていません。" + +#: describe.c:4526 describe.c:4530 +msgid "Provider" +msgstr "プロバイダー" + +#: describe.c:4536 describe.c:4541 +msgid "Deterministic?" +msgstr "確定的?" + +#: describe.c:4576 +msgid "List of collations" +msgstr "照合順序一覧" + +#: describe.c:4635 +msgid "List of schemas" +msgstr "スキーマ一覧" + +#: describe.c:4660 describe.c:4907 describe.c:4978 describe.c:5049 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "このサーバ(バージョン%s)は全文検索をサポートしていません。" + +#: describe.c:4695 +msgid "List of text search parsers" +msgstr "テキスト検索用パーサ一覧" + +#: describe.c:4740 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "テキスト検索用パーサ\"%s\"が見つかりませんでした。" + +#: describe.c:4743 +#, c-format +msgid "Did not find any text search parsers." +msgstr "テキスト検索パーサが見つかりませんでした。" + +#: describe.c:4818 +msgid "Start parse" +msgstr "パース開始" + +#: describe.c:4819 +msgid "Method" +msgstr "メソッド" + +#: describe.c:4823 +msgid "Get next token" +msgstr "次のトークンを取得" + +#: describe.c:4825 +msgid "End parse" +msgstr "パース終了" + +#: describe.c:4827 +msgid "Get headline" +msgstr "見出しを取得" + +#: describe.c:4829 +msgid "Get token types" +msgstr "トークンタイプを取得" + +#: describe.c:4840 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "テキスト検索パーサ\"%s.%s\"" + +#: describe.c:4843 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "テキスト検索パーサ\"%s\"" + +#: describe.c:4862 +msgid "Token name" +msgstr "トークン名" + +#: describe.c:4873 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "パーサ\"%s.%s\"のトークンタイプ" + +#: describe.c:4876 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "パーサ\"%s\"のトークンタイプ" + +#: describe.c:4930 +msgid "Template" +msgstr "テンプレート" + +#: describe.c:4931 +msgid "Init options" +msgstr "初期化オプション" + +#: describe.c:4953 +msgid "List of text search dictionaries" +msgstr "テキスト検索用辞書一覧" + +#: describe.c:4996 +msgid "Init" +msgstr "初期化" + +#: describe.c:4997 +msgid "Lexize" +msgstr "Lex 処理" + +#: describe.c:5024 +msgid "List of text search templates" +msgstr "テキスト検索テンプレート一覧" + +#: describe.c:5084 +msgid "List of text search configurations" +msgstr "テキスト検索設定一覧" + +#: describe.c:5130 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "テキスト検索用設定\"%s\"が見つかりませんでした。" + +#: describe.c:5133 +#, c-format +msgid "Did not find any text search configurations." +msgstr "テキスト検索設定が見つかりませんでした。" + +#: describe.c:5199 +msgid "Token" +msgstr "トークン" + +#: describe.c:5200 +msgid "Dictionaries" +msgstr "辞書" + +#: describe.c:5211 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "テキスト検索設定\"%s.%s\"" + +#: describe.c:5214 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "テキスト検索設定\"%s\"" + +#: describe.c:5218 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"パーサ: \"%s.%s\"" + +#: describe.c:5221 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"パーサ: \"%s\"" + +#: describe.c:5255 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "このサーバ(バージョン%s)は外部データラッパをサポートしていません。" + +#: describe.c:5313 +msgid "List of foreign-data wrappers" +msgstr "外部データラッパ一覧" + +#: describe.c:5338 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "このサーバ(バージョン%s)は外部サーバをサポートしていません。" + +#: describe.c:5351 +msgid "Foreign-data wrapper" +msgstr "外部データラッパ" + +#: describe.c:5369 describe.c:5574 +msgid "Version" +msgstr "バージョン" + +#: describe.c:5395 +msgid "List of foreign servers" +msgstr "外部サーバ一覧" + +#: describe.c:5420 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "このサーバ(バージョン%s)はユーザマッピングをサポートしていません。" + +#: describe.c:5430 describe.c:5494 +msgid "Server" +msgstr "サーバ" + +#: describe.c:5431 +msgid "User name" +msgstr "ユーザ名" + +#: describe.c:5456 +msgid "List of user mappings" +msgstr "ユーザマッピング一覧" + +#: describe.c:5481 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "このサーバ(バージョン%s)は外部テーブルをサポートしていません。" + +#: describe.c:5534 +msgid "List of foreign tables" +msgstr "外部テーブル一覧" + +#: describe.c:5559 describe.c:5616 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "このサーバ(バージョン%s)は機能拡張をサポートしていません。" + +#: describe.c:5591 +msgid "List of installed extensions" +msgstr "インストール済みの拡張一覧" + +#: describe.c:5644 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "\"%s\"という名前の機能拡張が見つかりませんでした。" + +#: describe.c:5647 +#, c-format +msgid "Did not find any extensions." +msgstr "機能拡張が見つかりませんでした。" + +#: describe.c:5691 +msgid "Object description" +msgstr "オブジェクトの説明" + +#: describe.c:5701 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "機能拡張\"%s\"内のオブジェクト" + +#: describe.c:5730 describe.c:5806 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "このサーバ(バージョン%s)はパブリケーションをサポートしていません。" + +#: describe.c:5747 describe.c:5884 +msgid "All tables" +msgstr "全テーブル" + +#: describe.c:5748 describe.c:5885 +msgid "Inserts" +msgstr "Insert文" + +#: describe.c:5749 describe.c:5886 +msgid "Updates" +msgstr "Update文" + +#: describe.c:5750 describe.c:5887 +msgid "Deletes" +msgstr "Delete文" + +#: describe.c:5754 describe.c:5889 +msgid "Truncates" +msgstr "Truncate文" + +#: describe.c:5758 describe.c:5891 +msgid "Via root" +msgstr "最上位パーティションテーブル経由" + +#: describe.c:5775 +msgid "List of publications" +msgstr "パブリケーション一覧" + +#: describe.c:5848 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "\"%s\"という名前のパブリケーションが見つかりませんでした。" + +#: describe.c:5851 +#, c-format +msgid "Did not find any publications." +msgstr "パブリケーションが見つかりませんでした。" + +#: describe.c:5880 +#, c-format +msgid "Publication %s" +msgstr "パブリケーション %s" + +#: describe.c:5928 +msgid "Tables:" +msgstr "テーブル:" + +#: describe.c:5972 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "このサーバ(バージョン%s)はサブスクリプションをサポートしていません。" + +#: describe.c:5988 +msgid "Publication" +msgstr "パブリケーション" + +#: describe.c:5996 +msgid "Binary" +msgstr "バイナリ" + +#: describe.c:6001 +msgid "Synchronous commit" +msgstr "同期コミット" + +#: describe.c:6002 +msgid "Conninfo" +msgstr "接続情報" + +#: describe.c:6024 +msgid "List of subscriptions" +msgstr "サブスクリプション一覧" + +#: describe.c:6091 describe.c:6180 describe.c:6266 describe.c:6349 +msgid "AM" +msgstr "AM" + +#: describe.c:6092 +msgid "Input type" +msgstr "入力の型" + +#: describe.c:6093 +msgid "Storage type" +msgstr "ストレージタイプ" + +#: describe.c:6094 +msgid "Operator class" +msgstr "演算子クラス" + +#: describe.c:6106 describe.c:6181 describe.c:6267 describe.c:6350 +msgid "Operator family" +msgstr "演算子族" + +#: describe.c:6139 +msgid "List of operator classes" +msgstr "演算子クラス一覧" + +#: describe.c:6182 +msgid "Applicable types" +msgstr "適用可能型" + +#: describe.c:6221 +msgid "List of operator families" +msgstr "演算子族一覧" + +#: describe.c:6268 +msgid "Operator" +msgstr "演算子" + +#: describe.c:6269 +msgid "Strategy" +msgstr "ストラテジ" + +#: describe.c:6270 +msgid "ordering" +msgstr "順序付け" + +#: describe.c:6271 +msgid "search" +msgstr "検索" + +#: describe.c:6272 +msgid "Purpose" +msgstr "目的" + +#: describe.c:6277 +msgid "Sort opfamily" +msgstr "ソート演算子族" + +#: describe.c:6308 +msgid "List of operators of operator families" +msgstr "演算子族の演算子一覧" + +#: describe.c:6351 +msgid "Registered left type" +msgstr "登録左辺型" + +#: describe.c:6352 +msgid "Registered right type" +msgstr "登録右辺型" + +#: describe.c:6353 +msgid "Number" +msgstr "番号" + +#: describe.c:6389 +msgid "List of support functions of operator families" +msgstr "演算子族のサポート関数一覧" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql は PostgreSQL の対話型ターミナルです。\n" +"\n" + +#: help.c:74 help.c:355 help.c:431 help.c:474 +#, c-format +msgid "Usage:\n" +msgstr "使い方:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [オプション]... [データベース名 [ユーザ名]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "一般的なオプション:\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr " -c, --command=コマンド 単一の(SQLまたは内部)コマンドを一つだけ実行して終了\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr " -d, --dbname=DB名 接続するデータベース名(デフォルト: \"%s\")\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=FILENAME ファイルからコマンドを読み込んで実行後、終了\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l(エル), --list 使用可能なデータベース一覧を表示して終了\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=名前=値\n" +" psql 変数 '名前' に '値' をセット\n" +" (例: -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version バージョン情報を表示して終了\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc 初期化ファイル (~/.psqlrc) を読み込まない\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 (数字の1), --single-transaction\n" +" (対話形式でない場合)単一のトランザクションとして実行\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] このヘルプを表示して終了\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands バックスラッシュコマンドの一覧を表示して終了\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables 特殊変数の一覧を表示して終了\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"入出力オプション:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all スクリプトから読み込んだ入力をすべて表示\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors 失敗したコマンドを表示\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, --echo-queries サーバへ送信したコマンドを表示\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden 内部コマンドが生成した問い合わせを表示\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, --log-file=FILENAME セッションログをファイルに書き込む\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, --no-readline 拡張コマンドライン編集機能(readline)を無効にする\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, --output=FILENAME 問い合わせの結果をファイル (または |パイプ)に送る\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, --quiet 静かに実行 (メッセージなしで、問い合わせの出力のみ)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, --single-step シングルステップモード (各問い合わせごとに確認)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr " -S, --single-line 単一行モード (行末でSQLコマンドを終端)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"出力フォーマットのオプション\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align 桁揃えなしのテーブル出力モード\n" + +#: help.c:111 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv CSV(カンマ区切り)テーブル出力モード\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, --field-separator=文字列\n" +" 桁揃えなし出力時のフィールド区切り文字\n" +" (デフォルト: \"%s\")\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html HTML テーブル出力モード\n" + +#: help.c:116 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr "" +" -P, --pset=変数[=値] 表示オプション '変数' を '値' にセット\n" +" (\\pset コマンドを参照)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, --record-separator=文字列\n" +" 桁揃えなし出力におけるレコード区切り文字\n" +" (デフォルト: 改行)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only 行のみを表示\n" + +#: help.c:120 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr " -T, --table-attr=TEXT HTMLテーブルのタグ属性をセット (width, border等)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded 拡張テーブル出力に切り替える\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" 桁揃えなし出力のフィールド区切りをバイト値の0に設定\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" 桁揃えなし出力のレコード区切りをバイト値の0に設定\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"接続オプション:\n" + +#: help.c:130 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr "" +" -h, --host=HOSTNAME データベースサーバのホストまたはソケットの\n" +" ディレクトリ(デフォルト: \"%s\")\n" + +#: help.c:131 +msgid "local socket" +msgstr "ローカルソケット" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, --port=PORT データベースサーバのポート番号(デフォルト: \"%s\")\n" + +#: help.c:140 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, --username=USERNAME データベースのユーザ名 (デフォルト: \"%s\")\n" + +#: help.c:141 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password パスワード入力を要求しない\n" + +#: help.c:142 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password パスワードプロンプトの強制表示(本来は自動的に表示)\n" + +#: help.c:144 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"詳細はpsqlの中で\"\\?\"(内部コマンドの場合)または\"\\help\"(SQLコマンドの場合)\n" +"をタイプするか、またはPostgreSQLドキュメント中のpsqlのセクションを参照のこと。\n" +"\n" + +#: help.c:147 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "バグは<%s>に報告してください。\n" + +#: help.c:148 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s ホームページ: <%s>\n" + +#: help.c:174 +#, c-format +msgid "General\n" +msgstr "一般\n" + +#: help.c:175 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright PostgreSQL の使い方と配布条件を表示\n" + +#: help.c:176 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [列] 問い合わせを実行し、結果をクロス表形式で出力\n" + +#: help.c:177 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose 最後のエラーメッセージを最大の冗長性で表示\n" + +#: help.c:178 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(OPTIONS)] [FILE] 問い合わせ実行 (と結果のファイルまたは |パイプ への\n" +" 送出);\n" +" \\g に引数を付加しない場合はセミコロンと同義\n" + +#: help.c:180 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc 問い合わせを実行せずに結果の説明を行う\n" + +#: help.c:181 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr " \\gexec 問い合わせを実行し、結果の中の個々の値を実行\n" + +#: help.c:182 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PREFIX] 問い合わせを実行して結果を psql 変数に格納\n" + +#: help.c:183 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [ファイル名] \\g と同じ、ただし拡張出力モードを強制\n" + +#: help.c:184 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q psql を終了する\n" + +#: help.c:185 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [秒数] 指定した秒数ごとに問い合わせを実行\n" + +#: help.c:188 +#, c-format +msgid "Help\n" +msgstr "ヘルプ\n" + +#: help.c:190 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [コマンド] バックスラッシュコマンドのヘルプを表示\n" + +#: help.c:191 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? オプション psql のコマンドライン・オプションのヘルプを表示\n" + +#: help.c:192 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? 変数名 特殊変数のヘルプを表示\n" + +#: help.c:193 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr " \\h [名前] SQLコマンドの文法ヘルプの表示。* で全コマンドを表示\n" + +#: help.c:196 +#, c-format +msgid "Query Buffer\n" +msgstr "問い合わせバッファ\n" + +#: help.c:197 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr "" +" \\e [ファイル] [行番号] 現在の問い合わせバッファ(やファイル)を外部エディタで\n" +" 編集\n" + +#: help.c:198 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [関数名 [行番号]] 関数定義を外部エディタで編集\n" + +#: help.c:199 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr " \\ev [ビュー名 [行番号]] ビュー定義を外部エディタで編集\n" + +#: help.c:200 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p 問い合わせバッファの内容を表示\n" + +#: help.c:201 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r 問い合わせバッファをリセット(クリア)\n" + +#: help.c:203 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [ファイル] ヒストリを表示またはファイルに保存\n" + +#: help.c:205 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w ファイル 問い合わせバッファの内容をファイルに保存\n" + +#: help.c:208 +#, c-format +msgid "Input/Output\n" +msgstr "入出力\n" + +#: help.c:209 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr "" +" \\copy ... クライアントホストに対し、データストリームを使って\n" +" SQL COPYを実行\n" + +#: help.c:210 +#, c-format +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr " \\echo [-n] [文字列] 文字列を標準出力に書き込む (-n で改行しない)\n" + +#: help.c:211 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i ファイル ファイルからコマンドを読み込んで実行\n" + +#: help.c:212 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr "" +" \\ir ファイル \\i と同じ。ただし現在のスクリプトの場所からの相対パス\n" +" で指定\n" + +#: help.c:213 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [ファイル] 問い合わせ結果をすべてファイルまたは |パイプ へ送出\n" + +#: help.c:214 +#, c-format +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr "" +" \\qecho [-n] [文字列] 文字列を\\oで指定した出力ストリームに書き込む(-n で改行\n" +" しない)\n" + +#: help.c:215 +#, c-format +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr " \\warn [-n] [文字列] 文字列を標準エラー出力に書き込む (-n で改行しない)\n" + +#: help.c:218 +#, c-format +msgid "Conditional\n" +msgstr "条件分岐\n" + +#: help.c:219 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR 条件分岐ブロックの開始\n" + +#: help.c:220 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR 現在の条件分岐ブロック内の選択肢\n" + +#: help.c:221 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else 現在の条件分岐ブロックにおける最後の選択肢\n" + +#: help.c:222 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif 条件分岐ブロックの終了\n" + +#: help.c:225 +#, c-format +msgid "Informational\n" +msgstr "情報表示\n" + +#: help.c:226 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (オプション:S = システムオブジェクトを表示, + = 詳細表示)\n" + +#: help.c:227 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] テーブル、ビュー、およびシーケンスの一覧を表示\n" + +#: help.c:228 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+] 名前 テーブル、ビュー、シーケンス、またはインデックスの説明を表示\n" + +#: help.c:229 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [パターン] 集約関数の一覧を表示\n" + +#: help.c:230 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [パターン] アクセスメソッドの一覧を表示\n" + +#: help.c:231 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] 演算子クラスの一覧を表示\n" + +#: help.c:232 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] 演算子族の一覧を表示\n" + +#: help.c:233 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] 演算子族の演算子の一覧を表示\n" + +#: help.c:234 +#, c-format +msgid " \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp [AMPTRN [OPFPTRN]] 演算子族のサポート関数の一覧を表示\n" + +#: help.c:235 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [パターン] テーブル空間の一覧を表示\n" + +#: help.c:236 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [パターン] 符号化方式間の変換の一覧を表示\n" + +#: help.c:237 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [パターン] キャストの一覧を表示します。\n" + +#: help.c:238 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr " \\dd[S] [パターン] 他では表示されないオブジェクトの説明を表示\n" + +#: help.c:239 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [パターン] ドメインの一覧を表示\n" + +#: help.c:240 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [パターン] デフォルト権限の一覧を表示\n" + +#: help.c:241 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [パターン] 外部テーブルの一覧を表示\n" + +#: help.c:242 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [パターン] 外部テーブルの一覧を表示\n" + +#: help.c:243 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [パターン] 外部サーバの一覧を表示\n" + +#: help.c:244 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [パターン] ユーザマッピングの一覧を表示\n" + +#: help.c:245 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [パターン] 外部データラッパの一覧を表示\n" + +#: help.c:246 +#, c-format +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr "" +" \\df[antw][S+] [パターン] 関数(集約/通常/プロシージャ/トリガー/ウィンドウ\n" +" 関数のみ)の一覧を表示\n" + +#: help.c:247 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [パターン] テキスト検索設定の一覧を表示\n" + +#: help.c:248 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [パターン] テキスト検索辞書の一覧を表示\n" + +#: help.c:249 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [パターン] テキスト検索パーサの一覧を表示\n" + +#: help.c:250 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [パターン] テキスト検索テンプレートの一覧を表示\n" + +#: help.c:251 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [パターン] ロールの一覧を表示\n" + +#: help.c:252 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [パターン] インデックスの一覧を表示\n" + +#: help.c:253 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl ラージオブジェクトの一覧を表示、\\lo_list と同じ\n" + +#: help.c:254 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [パターン] 手続き言語の一覧を表示\n" + +#: help.c:255 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [パターン] 実体化ビューの一覧を表示\n" + +#: help.c:256 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [パターン] スキーマの一覧を表示\n" + +#: help.c:257 +#, c-format +msgid " \\do[S] [PATTERN] list operators\n" +msgstr " \\do[S] [名前] 演算子の一覧を表示\n" + +#: help.c:258 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [パターン] 照合順序の一覧を表示\n" + +#: help.c:259 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [パターン] テーブル、ビュー、シーケンスのアクセス権の一覧を表示\n" + +#: help.c:260 +#, c-format +msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" +msgstr "" +" \\dP[itn+] [パターン] パーティションリレーション[テーブル/インデックスのみ]\n" +" の一覧を表示 [n=入れ子]\n" + +#: help.c:261 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [パターン1 [パターン2]] データベース毎のロール設定の一覧を表示\n" + +#: help.c:262 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [パターン] レプリケーションのパブリケーションの一覧を表示\n" + +#: help.c:263 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [パターン] レプリケーションのサブスクリプションの一覧を表示\n" + +#: help.c:264 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [パターン] シーケンスの一覧を表示\n" + +#: help.c:265 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [パターン] テーブルの一覧を表示\n" + +#: help.c:266 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [パターン] データ型の一覧を表示\n" + +#: help.c:267 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [パターン] ロールの一覧を表示\n" + +#: help.c:268 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [パターン] ビューの一覧を表示\n" + +#: help.c:269 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [パターン] 機能拡張の一覧を表示\n" + +#: help.c:270 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [パターン] イベントトリガーの一覧を表示\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [パターン] データベースの一覧を表示\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] 関数名 関数の定義を表示\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] ビュー名 ビューの定義を表示\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [パターン] \\dp と同じ\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "書式設定\n" + +#: help.c:278 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr " \\a 非整列と整列間の出力モードの切り替え\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr " \\C [文字列] テーブルのタイトルを設定、値がなければ削除\n" + +#: help.c:280 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr "" +" \\f [文字列] 問い合わせ結果の非整列出力時のフィールド区切り文字を\n" +" 表示または設定\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H HTML出力モードの切り替え (現在値: %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [名前 [値]] テーブル出力のオプション設定\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] 結果行のみ表示 (現在値: %s)\n" + +#: help.c:292 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr " \\T [文字列] HTMLの
タグ属性の設定、値がなければ解除\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] 拡張出力の切り替え (現在値: %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "接続\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[DB名|- ユーザ名|- ホスト名|- ポート番号|-] | 接続文字列}\n" +" 新しいデータベースに接続 (現在: \"%s\")\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[DB名|- ユーザ名|- ホスト名|- ポート番号|-] | 接続文字列}\n" +" 新しいデータベースに接続 (現在: 未接続)\n" + +#: help.c:305 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo 現在の接続に関する情報を表示\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [エンコーディング] クライアントのエンコーディングを表示または設定\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr " \\password [ユーザ名] ユーザのパスワードを安全に変更\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "オペレーティングシステム\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [DIR] カレントディレクトリを変更\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv 名前 [値] 環境変数を設定または解除\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] コマンドの実行時間表示の切り替え (現在値: %s)\n" + +#: help.c:315 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr "" +" \\! [コマンド] シェルでコマンドを実行するか、もしくは対話型シェルを\n" +" 起動します。\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "変数\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr " \\prompt [テキスト] 変数名 ユーザに対して内部変数の設定を要求します\n" + +#: help.c:320 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr " \\set [変数名 [値]] 内部変数の値を設定、パラメータがなければ一覧を表示\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset 変数名 内部変数を削除\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "ラージ・オブジェクト\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID ファイル名\n" +" \\lo_import ファイル名 [コメント]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID ラージオブジェクトの操作\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"特別に扱われる変数の一覧\n" +"\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "psql変数:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=名前=値\n" +" またはpsql内で \\set 名前 値\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" セットされている場合、SQLコマンドが成功した際に自動的にコミット\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" SQLキーワードの補完に使う文字ケースを指定\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" 現在接続中のデータベース名\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" どの入力を標準出力への出力対象とするかを設定\n" +" [all, errors, none, queries]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" セットされていれば、バックスラッシュコマンドで実行される内部問い合わせを\n" +" 表示; \"noexec\"を設定した場合は実行せずに表示のみ\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" 現在のクライアント側の文字セットのエンコーディング\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" 最後の問い合わせが失敗であれば真、そうでなければ偽\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" 一度に取得および表示する結果の行数 (0 = 無制限)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" 設定すると、テーブルアクセスメソッドは表示されない\n" +"\n" + +#: help.c:379 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" コマンド履歴の制御 [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" コマンド履歴を保存するファイルの名前\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" コマンド履歴で保存するコマンド数の上限\n" + +#: help.c:385 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" 現在接続中のデータベースサーバホスト\n" + +#: help.c:387 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" 対話形セッションを終わらせるのに必要なEOFの数\n" + +#: help.c:389 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" 最後の変更の影響を受けたOID\n" + +#: help.c:391 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" 最後のエラーのメッセージおよび SQLSTATE、\n" +" なにもなければ空の文字列および\"00000\"\n" + +#: help.c:394 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" セットされている場合、エラーでトランザクションを停止しない (暗黙のセーブ\n" +" ポイントを使用)\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" エラー発生後にバッチ実行を停止\n" + +#: help.c:398 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" 現在の接続のサーバポート\n" + +#: help.c:400 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" psql の標準のプロンプトを指定\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" ステートメントが前行から継続する場合のプロンプトを指定\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" COPY ... FROM STDIN の最中に使われるプロンプトを指定\n" + +#: help.c:406 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" メッセージを表示しない (-q オプションと同じ)\n" + +#: help.c:408 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" 最後の問い合わせで返却した、または影響を与えた行の数、または0\n" + +#: help.c:410 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" サーバのバージョン(短い文字列または数値)\n" + +#: help.c:413 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" メッセージコンテキストフィールドの表示を制御 [never, errors, always]\n" + +#: help.c:415 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" セットした場合、改行はSQLコマンドを終端する (-S オプションと同じ)\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" シングルステップモード (-s オプションと同じ)\n" + +#: help.c:419 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" 最後の問い合わせの SQLSTATE、またはエラーでなければ\"00000\"\n" + +#: help.c:421 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" 現在接続中のデータベースユーザ\n" + +#: help.c:423 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" エラー報告の詳細度を制御 [default, verbose, terse, sqlstate]\n" + +#: help.c:425 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql のバージョン(長い文字列、短い文字列または数値)\n" + +#: help.c:430 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"表示設定:\n" + +#: help.c:432 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=名前[=値]\n" +" またはpsql内で \\pset 名前 [値]\n" +"\n" + +#: help.c:434 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" 境界線のスタイル (番号)\n" + +#: help.c:436 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" 折り返し形式で目標とする横幅\n" + +#: help.c:438 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (or x)\n" +" 拡張出力 [on, off, auto]\n" + +#: help.c:440 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" 非整列出力でのフィールド区切り文字(デフォルトは \"%s\")\n" + +#: help.c:443 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" 非整列出力でのフィールド区切り文字をバイト値の0に設定\n" + +#: help.c:445 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" テーブルフッター出力の要否を設定 [on, off]\n" + +#: help.c:447 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" 出力フォーマットを設定 [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:449 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" 境界線の描画スタイルを設定 [ascii, old-ascii, unicode]\n" + +#: help.c:451 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" null 値の代わりに表示する文字列を設定\n" + +#: help.c:453 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +" numericlocale\n" +" ロケール固有文字での桁区切りを表示するかどうかを指定\n" + +#: help.c:455 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" いつ外部ページャーを使うかを制御 [yes, no, always]\n" + +#: help.c:457 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" 非整列出力でのレコード(行)区切り\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" 非整列出力でレコード区切りにバイト値の0に設定\n" + +#: help.c:461 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (or T)\n" +" HTMLフォーマット時のtableタグの属性、もしくは latex-longtable\n" +" フォーマット時に左寄せするデータ型の相対カラム幅を指定\n" + +#: help.c:464 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" 以降に表示される表のタイトルを設定\n" + +#: help.c:466 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" セットされた場合、実際のテーブルデータのみを表示\n" + +#: help.c:468 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" Unicode による線描画時のスタイルを設定 [single, double]\n" + +#: help.c:473 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"環境変数:\n" + +#: help.c:477 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" 名前=値 [名前=値] psql ...\n" +" またはpsql内で \\setenv 名前 [値]\n" +"\n" + +#: help.c:479 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set 名前=値\n" +" psql ...\n" +" またはpsq内で \\setenv 名前 [値]\n" +"\n" + +#: help.c:482 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" 折り返し書式におけるカラム数\n" + +#: help.c:484 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" application_name 接続パラメータと同じ\n" + +#: help.c:486 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" dbname 接続パラメータと同じ\n" + +#: help.c:488 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" host 接続パラメータと同じ\n" + +#: help.c:490 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" 接続用パスワード (推奨されません)\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" パスワードファイル名\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" port 接続パラメータと同じ\n" + +#: help.c:496 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" user 接続パラメータと同じ\n" + +#: help.c:498 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" \\e, \\ef, \\ev コマンドで使われるエディタ\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" エディタの起動時に行番号を指定する方法\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" コマンドライン履歴ファイルの代替の場所\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" 外部ページャープログラムの名前\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" ユーザの .psqlrc ファイルの代替の場所\n" + +#: help.c:508 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" \\! コマンドで使われるシェル\n" + +#: help.c:510 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" テンポラリファイル用ディレクトリ\n" + +#: help.c:554 +msgid "Available help:\n" +msgstr "利用可能なヘルプ:\n" + +#: help.c:642 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"コマンド: %s\n" +"説明: %s\n" +"書式:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" + +#: help.c:661 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"\"%s\"のヘルプがありません。\n" +"引数なしで \\h とタイプすると、ヘルプの一覧が表示されます。\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "入力ファイルから読み込めませんでした: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "ファイル\"%s\"にヒストリーを保存できませんでした: %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "この環境ではヒストリー機能がサポートされていません" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: データベースに接続していません" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: 現在のトランザクションは中断されました" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: 未知のトランザクション状態" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "ラージ オブジェクト" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if: 脱出しました" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "\"\\q\"で%sを抜けます。\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"この入力データは PostgreSQL のカスタムフォーマットのダンプです。\n" +"このダンプをデータベースにリストアするには pg_restore コマンドを使ってください。\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "\\? でヘルプの表示、control-C で入力バッファをクリアします。" + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr " \\? でヘルプを表示します。" + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "PostgreSQL へのコマンド ライン インターフェイス、psql を使用しています。" + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"ヒント: \\copyright とタイプすると、配布条件を表示します。\n" +" \\h とタイプすると、SQLコマンドのヘルプを表示します。\n" +" \\? とタイプすると、psqlコマンドのヘルプを表示します。\n" +" \\g と打つかセミコロンで閉じると、問い合わせを実行します。\n" +" \\q で終了します。\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "\\q で終了します。" + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "control-D で終了します。" + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "control-C で終了します。" + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "問い合わせは無視されました; \\endifかCtrl-Cで現在の\\ifブロックを抜けてください" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "ブロックを閉じる\\endifを検出中に、ファイルの終端(EOF)に達しました" + +#: psqlscan.l:693 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "変数\"%s\"の再帰展開をスキップしています" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "文字列の引用符が閉じていません" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: メモリ不足です" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1090 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 +#: sql_help.c:1112 sql_help.c:1114 sql_help.c:1118 sql_help.c:1121 +#: sql_help.c:1122 sql_help.c:1123 sql_help.c:1126 sql_help.c:1128 +#: sql_help.c:1262 sql_help.c:1264 sql_help.c:1267 sql_help.c:1270 +#: sql_help.c:1272 sql_help.c:1274 sql_help.c:1277 sql_help.c:1280 +#: sql_help.c:1391 sql_help.c:1393 sql_help.c:1395 sql_help.c:1398 +#: sql_help.c:1419 sql_help.c:1422 sql_help.c:1425 sql_help.c:1428 +#: sql_help.c:1432 sql_help.c:1434 sql_help.c:1436 sql_help.c:1438 +#: sql_help.c:1452 sql_help.c:1455 sql_help.c:1457 sql_help.c:1459 +#: sql_help.c:1469 sql_help.c:1471 sql_help.c:1481 sql_help.c:1483 +#: sql_help.c:1493 sql_help.c:1496 sql_help.c:1519 sql_help.c:1521 +#: sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 sql_help.c:1530 +#: sql_help.c:1533 sql_help.c:1536 sql_help.c:1586 sql_help.c:1629 +#: sql_help.c:1632 sql_help.c:1634 sql_help.c:1636 sql_help.c:1639 +#: sql_help.c:1641 sql_help.c:1643 sql_help.c:1646 sql_help.c:1696 +#: sql_help.c:1712 sql_help.c:1933 sql_help.c:2002 sql_help.c:2021 +#: sql_help.c:2034 sql_help.c:2091 sql_help.c:2098 sql_help.c:2108 +#: sql_help.c:2129 sql_help.c:2155 sql_help.c:2173 sql_help.c:2200 +#: sql_help.c:2295 sql_help.c:2340 sql_help.c:2364 sql_help.c:2387 +#: sql_help.c:2391 sql_help.c:2425 sql_help.c:2445 sql_help.c:2467 +#: sql_help.c:2481 sql_help.c:2501 sql_help.c:2524 sql_help.c:2554 +#: sql_help.c:2579 sql_help.c:2625 sql_help.c:2903 sql_help.c:2916 +#: sql_help.c:2933 sql_help.c:2949 sql_help.c:2989 sql_help.c:3041 +#: sql_help.c:3045 sql_help.c:3047 sql_help.c:3053 sql_help.c:3071 +#: sql_help.c:3098 sql_help.c:3133 sql_help.c:3145 sql_help.c:3154 +#: sql_help.c:3198 sql_help.c:3212 sql_help.c:3240 sql_help.c:3248 +#: sql_help.c:3260 sql_help.c:3270 sql_help.c:3278 sql_help.c:3286 +#: sql_help.c:3294 sql_help.c:3302 sql_help.c:3311 sql_help.c:3322 +#: sql_help.c:3330 sql_help.c:3338 sql_help.c:3346 sql_help.c:3354 +#: sql_help.c:3364 sql_help.c:3373 sql_help.c:3382 sql_help.c:3390 +#: sql_help.c:3400 sql_help.c:3411 sql_help.c:3419 sql_help.c:3428 +#: sql_help.c:3439 sql_help.c:3448 sql_help.c:3456 sql_help.c:3464 +#: sql_help.c:3472 sql_help.c:3480 sql_help.c:3488 sql_help.c:3496 +#: sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 sql_help.c:3528 +#: sql_help.c:3545 sql_help.c:3554 sql_help.c:3562 sql_help.c:3579 +#: sql_help.c:3594 sql_help.c:3869 sql_help.c:3920 sql_help.c:3949 +#: sql_help.c:3962 sql_help.c:4407 sql_help.c:4455 sql_help.c:4596 +msgid "name" +msgstr "名前" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1783 +#: sql_help.c:3213 sql_help.c:4193 +msgid "aggregate_signature" +msgstr "集約関数のシグニチャー" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1093 sql_help.c:1129 sql_help.c:1271 sql_help.c:1392 +#: sql_help.c:1435 sql_help.c:1456 sql_help.c:1470 sql_help.c:1482 +#: sql_help.c:1495 sql_help.c:1522 sql_help.c:1587 sql_help.c:1640 +msgid "new_name" +msgstr "新しい名前" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1091 sql_help.c:1127 sql_help.c:1332 +#: sql_help.c:1394 sql_help.c:1437 sql_help.c:1458 sql_help.c:1520 +#: sql_help.c:1635 sql_help.c:2889 +msgid "new_owner" +msgstr "新しい所有者" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1095 +#: sql_help.c:1273 sql_help.c:1439 sql_help.c:1460 sql_help.c:1472 +#: sql_help.c:1484 sql_help.c:1524 sql_help.c:1642 +msgid "new_schema" +msgstr "新しいスキーマ" + +#: sql_help.c:44 sql_help.c:1847 sql_help.c:3214 sql_help.c:4222 +msgid "where aggregate_signature is:" +msgstr "集約関数のシグニチャーには以下のものがあります:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1801 +#: sql_help.c:1818 sql_help.c:1824 sql_help.c:1848 sql_help.c:1851 +#: sql_help.c:1854 sql_help.c:2003 sql_help.c:2022 sql_help.c:2025 +#: sql_help.c:2296 sql_help.c:2502 sql_help.c:3215 sql_help.c:3218 +#: sql_help.c:3221 sql_help.c:3312 sql_help.c:3401 sql_help.c:3429 +#: sql_help.c:3753 sql_help.c:4101 sql_help.c:4199 sql_help.c:4206 +#: sql_help.c:4212 sql_help.c:4223 sql_help.c:4226 sql_help.c:4229 +msgid "argmode" +msgstr "引数のモード" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1802 +#: sql_help.c:1819 sql_help.c:1825 sql_help.c:1849 sql_help.c:1852 +#: sql_help.c:1855 sql_help.c:2004 sql_help.c:2023 sql_help.c:2026 +#: sql_help.c:2297 sql_help.c:2503 sql_help.c:3216 sql_help.c:3219 +#: sql_help.c:3222 sql_help.c:3313 sql_help.c:3402 sql_help.c:3430 +#: sql_help.c:4200 sql_help.c:4207 sql_help.c:4213 sql_help.c:4224 +#: sql_help.c:4227 sql_help.c:4230 +msgid "argname" +msgstr "引数の名前" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1803 +#: sql_help.c:1820 sql_help.c:1826 sql_help.c:1850 sql_help.c:1853 +#: sql_help.c:1856 sql_help.c:2298 sql_help.c:2504 sql_help.c:3217 +#: sql_help.c:3220 sql_help.c:3223 sql_help.c:3314 sql_help.c:3403 +#: sql_help.c:3431 sql_help.c:4201 sql_help.c:4208 sql_help.c:4214 +#: sql_help.c:4225 sql_help.c:4228 sql_help.c:4231 +msgid "argtype" +msgstr "引数の型" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1453 sql_help.c:1581 sql_help.c:1613 +#: sql_help.c:1665 sql_help.c:1904 sql_help.c:1911 sql_help.c:2203 +#: sql_help.c:2245 sql_help.c:2252 sql_help.c:2261 sql_help.c:2341 +#: sql_help.c:2555 sql_help.c:2647 sql_help.c:2918 sql_help.c:3099 +#: sql_help.c:3121 sql_help.c:3261 sql_help.c:3616 sql_help.c:3788 +#: sql_help.c:3961 sql_help.c:4658 +msgid "option" +msgstr "オプション" + +#: sql_help.c:113 sql_help.c:927 sql_help.c:1582 sql_help.c:2342 +#: sql_help.c:2556 sql_help.c:3100 sql_help.c:3262 +msgid "where option can be:" +msgstr "オプションには以下のものがあります:" + +#: sql_help.c:114 sql_help.c:2137 +msgid "allowconn" +msgstr "接続の可否(真偽値)" + +#: sql_help.c:115 sql_help.c:928 sql_help.c:1583 sql_help.c:2138 +#: sql_help.c:2343 sql_help.c:2557 sql_help.c:3101 +msgid "connlimit" +msgstr "最大同時接続数" + +#: sql_help.c:116 sql_help.c:2139 +msgid "istemplate" +msgstr "テンプレートかどうか(真偽値)" + +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1276 sql_help.c:1325 +msgid "new_tablespace" +msgstr "新しいテーブル空間名" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1140 sql_help.c:1143 sql_help.c:1590 +#: sql_help.c:1594 sql_help.c:1597 sql_help.c:2308 sql_help.c:2508 +#: sql_help.c:3980 sql_help.c:4396 +msgid "configuration_parameter" +msgstr "設定パラメータ" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1117 sql_help.c:1120 sql_help.c:1125 sql_help.c:1141 +#: sql_help.c:1142 sql_help.c:1307 sql_help.c:1327 sql_help.c:1375 +#: sql_help.c:1397 sql_help.c:1454 sql_help.c:1538 sql_help.c:1591 +#: sql_help.c:1614 sql_help.c:2204 sql_help.c:2246 sql_help.c:2253 +#: sql_help.c:2262 sql_help.c:2309 sql_help.c:2310 sql_help.c:2372 +#: sql_help.c:2375 sql_help.c:2409 sql_help.c:2509 sql_help.c:2510 +#: sql_help.c:2527 sql_help.c:2648 sql_help.c:2678 sql_help.c:2783 +#: sql_help.c:2796 sql_help.c:2810 sql_help.c:2851 sql_help.c:2875 +#: sql_help.c:2892 sql_help.c:2919 sql_help.c:3122 sql_help.c:3789 +#: sql_help.c:4397 sql_help.c:4398 +msgid "value" +msgstr "値" + +#: sql_help.c:197 +msgid "target_role" +msgstr "対象のロール" + +#: sql_help.c:198 sql_help.c:2188 sql_help.c:2603 sql_help.c:2608 +#: sql_help.c:3735 sql_help.c:3742 sql_help.c:3756 sql_help.c:3762 +#: sql_help.c:4083 sql_help.c:4090 sql_help.c:4104 sql_help.c:4110 +msgid "schema_name" +msgstr "スキーマ名" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "GRANT/REVOKEの省略形" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "GRANT/REVOKEの省略形は以下のいずれかです:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1275 sql_help.c:1601 sql_help.c:2346 sql_help.c:2347 +#: sql_help.c:2348 sql_help.c:2349 sql_help.c:2350 sql_help.c:2483 +#: sql_help.c:2560 sql_help.c:2561 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 sql_help.c:3104 sql_help.c:3105 sql_help.c:3106 +#: sql_help.c:3107 sql_help.c:3108 sql_help.c:3768 sql_help.c:3772 +#: sql_help.c:4116 sql_help.c:4120 sql_help.c:4417 +msgid "role_name" +msgstr "ロール名" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1342 sql_help.c:1354 sql_help.c:1379 sql_help.c:1631 +#: sql_help.c:2158 sql_help.c:2162 sql_help.c:2265 sql_help.c:2270 +#: sql_help.c:2368 sql_help.c:2778 sql_help.c:2791 sql_help.c:2805 +#: sql_help.c:2814 sql_help.c:2826 sql_help.c:2855 sql_help.c:3820 +#: sql_help.c:3835 sql_help.c:3837 sql_help.c:4282 sql_help.c:4283 +#: sql_help.c:4292 sql_help.c:4333 sql_help.c:4334 sql_help.c:4335 +#: sql_help.c:4336 sql_help.c:4337 sql_help.c:4338 sql_help.c:4371 +#: sql_help.c:4372 sql_help.c:4377 sql_help.c:4382 sql_help.c:4521 +#: sql_help.c:4522 sql_help.c:4531 sql_help.c:4572 sql_help.c:4573 +#: sql_help.c:4574 sql_help.c:4575 sql_help.c:4576 sql_help.c:4577 +#: sql_help.c:4624 sql_help.c:4626 sql_help.c:4685 sql_help.c:4741 +#: sql_help.c:4742 sql_help.c:4751 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +msgid "expression" +msgstr "評価式" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "ドメイン制約" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1268 sql_help.c:1313 sql_help.c:1314 sql_help.c:1315 +#: sql_help.c:1341 sql_help.c:1353 sql_help.c:1370 sql_help.c:1789 +#: sql_help.c:1791 sql_help.c:2161 sql_help.c:2264 sql_help.c:2269 +#: sql_help.c:2813 sql_help.c:2825 sql_help.c:3832 +msgid "constraint_name" +msgstr "制約名" + +#: sql_help.c:244 sql_help.c:1269 +msgid "new_constraint_name" +msgstr "新しい制約名" + +#: sql_help.c:317 sql_help.c:1073 +msgid "new_version" +msgstr "新しいバージョン" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "メンバーオブジェクト" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "メンバーオブジェクトは以下の通りです:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1781 sql_help.c:1786 sql_help.c:1793 +#: sql_help.c:1794 sql_help.c:1795 sql_help.c:1796 sql_help.c:1797 +#: sql_help.c:1798 sql_help.c:1799 sql_help.c:1804 sql_help.c:1806 +#: sql_help.c:1810 sql_help.c:1812 sql_help.c:1816 sql_help.c:1821 +#: sql_help.c:1822 sql_help.c:1829 sql_help.c:1830 sql_help.c:1831 +#: sql_help.c:1832 sql_help.c:1833 sql_help.c:1834 sql_help.c:1835 +#: sql_help.c:1836 sql_help.c:1837 sql_help.c:1838 sql_help.c:1839 +#: sql_help.c:1844 sql_help.c:1845 sql_help.c:4189 sql_help.c:4194 +#: sql_help.c:4195 sql_help.c:4196 sql_help.c:4197 sql_help.c:4203 +#: sql_help.c:4204 sql_help.c:4209 sql_help.c:4210 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4217 sql_help.c:4218 sql_help.c:4219 +#: sql_help.c:4220 +msgid "object_name" +msgstr "オブジェクト名" + +#: sql_help.c:326 sql_help.c:1782 sql_help.c:4192 +msgid "aggregate_name" +msgstr "集約関数名" + +#: sql_help.c:328 sql_help.c:1784 sql_help.c:2068 sql_help.c:2072 +#: sql_help.c:2074 sql_help.c:3231 +msgid "source_type" +msgstr "変換前の型" + +#: sql_help.c:329 sql_help.c:1785 sql_help.c:2069 sql_help.c:2073 +#: sql_help.c:2075 sql_help.c:3232 +msgid "target_type" +msgstr "変換後の型" + +#: sql_help.c:336 sql_help.c:774 sql_help.c:1800 sql_help.c:2070 +#: sql_help.c:2111 sql_help.c:2176 sql_help.c:2426 sql_help.c:2457 +#: sql_help.c:2995 sql_help.c:4100 sql_help.c:4198 sql_help.c:4311 +#: sql_help.c:4315 sql_help.c:4319 sql_help.c:4322 sql_help.c:4550 +#: sql_help.c:4554 sql_help.c:4558 sql_help.c:4561 sql_help.c:4770 +#: sql_help.c:4774 sql_help.c:4778 sql_help.c:4781 +msgid "function_name" +msgstr "関数名" + +#: sql_help.c:341 sql_help.c:767 sql_help.c:1807 sql_help.c:2450 +msgid "operator_name" +msgstr "演算子名" + +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1808 +#: sql_help.c:2427 sql_help.c:3355 +msgid "left_type" +msgstr "左辺の型" + +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1809 +#: sql_help.c:2428 sql_help.c:3356 +msgid "right_type" +msgstr "右辺の型" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1359 sql_help.c:1811 sql_help.c:1813 sql_help.c:2447 +#: sql_help.c:2468 sql_help.c:2831 sql_help.c:3365 sql_help.c:3374 +msgid "index_method" +msgstr "インデックスメソッド" + +#: sql_help.c:349 sql_help.c:1817 sql_help.c:4205 +msgid "procedure_name" +msgstr "プロシージャ名" + +#: sql_help.c:353 sql_help.c:1823 sql_help.c:3752 sql_help.c:4211 +msgid "routine_name" +msgstr "ルーチン名" + +#: sql_help.c:365 sql_help.c:1331 sql_help.c:1840 sql_help.c:2304 +#: sql_help.c:2507 sql_help.c:2786 sql_help.c:2962 sql_help.c:3536 +#: sql_help.c:3766 sql_help.c:4114 +msgid "type_name" +msgstr "型名" + +#: sql_help.c:366 sql_help.c:1841 sql_help.c:2303 sql_help.c:2506 +#: sql_help.c:2963 sql_help.c:3189 sql_help.c:3537 sql_help.c:3758 +#: sql_help.c:4106 +msgid "lang_name" +msgstr "言語名" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "集約関数のシグニチャーは以下の通りです:" + +#: sql_help.c:392 sql_help.c:1935 sql_help.c:2201 +msgid "handler_function" +msgstr "ハンドラー関数" + +#: sql_help.c:393 sql_help.c:2202 +msgid "validator_function" +msgstr "バリデーター関数" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1263 sql_help.c:1529 +msgid "action" +msgstr "アクション" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1265 +#: sql_help.c:1283 sql_help.c:1287 sql_help.c:1288 sql_help.c:1292 +#: sql_help.c:1294 sql_help.c:1295 sql_help.c:1296 sql_help.c:1297 +#: sql_help.c:1299 sql_help.c:1302 sql_help.c:1303 sql_help.c:1305 +#: sql_help.c:1308 sql_help.c:1310 sql_help.c:1355 sql_help.c:1357 +#: sql_help.c:1364 sql_help.c:1373 sql_help.c:1378 sql_help.c:1630 +#: sql_help.c:1633 sql_help.c:1637 sql_help.c:1673 sql_help.c:1788 +#: sql_help.c:1901 sql_help.c:1907 sql_help.c:1920 sql_help.c:1921 +#: sql_help.c:1922 sql_help.c:2243 sql_help.c:2256 sql_help.c:2301 +#: sql_help.c:2367 sql_help.c:2373 sql_help.c:2406 sql_help.c:2633 +#: sql_help.c:2661 sql_help.c:2662 sql_help.c:2769 sql_help.c:2777 +#: sql_help.c:2787 sql_help.c:2790 sql_help.c:2800 sql_help.c:2804 +#: sql_help.c:2827 sql_help.c:2829 sql_help.c:2836 sql_help.c:2849 +#: sql_help.c:2854 sql_help.c:2872 sql_help.c:2998 sql_help.c:3134 +#: sql_help.c:3737 sql_help.c:3738 sql_help.c:3819 sql_help.c:3834 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:4085 sql_help.c:4086 +#: sql_help.c:4191 sql_help.c:4342 sql_help.c:4581 sql_help.c:4623 +#: sql_help.c:4625 sql_help.c:4627 sql_help.c:4673 sql_help.c:4801 +msgid "column_name" +msgstr "列名" + +#: sql_help.c:444 sql_help.c:664 sql_help.c:1266 sql_help.c:1638 +msgid "new_column_name" +msgstr "新しい列名" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1282 sql_help.c:1539 +msgid "where action is one of:" +msgstr "アクションは以下のいずれかです:" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1284 +#: sql_help.c:1289 sql_help.c:1541 sql_help.c:1545 sql_help.c:2156 +#: sql_help.c:2244 sql_help.c:2446 sql_help.c:2626 sql_help.c:2770 +#: sql_help.c:3043 sql_help.c:3921 +msgid "data_type" +msgstr "データ型" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1285 sql_help.c:1290 +#: sql_help.c:1542 sql_help.c:1546 sql_help.c:2157 sql_help.c:2247 +#: sql_help.c:2369 sql_help.c:2771 sql_help.c:2779 sql_help.c:2792 +#: sql_help.c:2806 sql_help.c:3044 sql_help.c:3050 sql_help.c:3829 +msgid "collation" +msgstr "照合順序" + +#: sql_help.c:453 sql_help.c:1286 sql_help.c:2248 sql_help.c:2257 +#: sql_help.c:2772 sql_help.c:2788 sql_help.c:2801 +msgid "column_constraint" +msgstr "カラム制約" + +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1304 sql_help.c:4670 +msgid "integer" +msgstr "整数" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1306 +#: sql_help.c:1309 +msgid "attribute_option" +msgstr "属性オプション" + +#: sql_help.c:473 sql_help.c:1311 sql_help.c:2249 sql_help.c:2258 +#: sql_help.c:2773 sql_help.c:2789 sql_help.c:2802 +msgid "table_constraint" +msgstr "テーブル制約" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1316 +#: sql_help.c:1317 sql_help.c:1318 sql_help.c:1319 sql_help.c:1842 +msgid "trigger_name" +msgstr "トリガー名" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1329 sql_help.c:1330 +#: sql_help.c:2250 sql_help.c:2255 sql_help.c:2776 sql_help.c:2799 +msgid "parent_table" +msgstr "親テーブル" + +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1498 sql_help.c:2187 +msgid "extension_name" +msgstr "拡張名" + +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2305 +msgid "execution_cost" +msgstr "実行コスト" + +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2306 +msgid "result_rows" +msgstr "結果の行数" + +#: sql_help.c:543 sql_help.c:2307 +msgid "support_function" +msgstr "サポート関数" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1580 sql_help.c:1588 +#: sql_help.c:1592 sql_help.c:1595 sql_help.c:1598 sql_help.c:2604 +#: sql_help.c:2606 sql_help.c:2609 sql_help.c:2610 sql_help.c:3736 +#: sql_help.c:3740 sql_help.c:3743 sql_help.c:3745 sql_help.c:3747 +#: sql_help.c:3749 sql_help.c:3751 sql_help.c:3757 sql_help.c:3759 +#: sql_help.c:3761 sql_help.c:3763 sql_help.c:3765 sql_help.c:3767 +#: sql_help.c:3769 sql_help.c:3770 sql_help.c:4084 sql_help.c:4088 +#: sql_help.c:4091 sql_help.c:4093 sql_help.c:4095 sql_help.c:4097 +#: sql_help.c:4099 sql_help.c:4105 sql_help.c:4107 sql_help.c:4109 +#: sql_help.c:4111 sql_help.c:4113 sql_help.c:4115 sql_help.c:4117 +#: sql_help.c:4118 +msgid "role_specification" +msgstr "ロールの指定" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:1611 sql_help.c:2130 +#: sql_help.c:2612 sql_help.c:3119 sql_help.c:3570 sql_help.c:4427 +msgid "user_name" +msgstr "ユーザ名" + +#: sql_help.c:568 sql_help.c:945 sql_help.c:1600 sql_help.c:2611 +#: sql_help.c:3771 sql_help.c:4119 +msgid "where role_specification can be:" +msgstr "ロール指定は以下の通りです:" + +#: sql_help.c:570 +msgid "group_name" +msgstr "グループ名" + +#: sql_help.c:591 sql_help.c:1376 sql_help.c:2136 sql_help.c:2376 +#: sql_help.c:2410 sql_help.c:2784 sql_help.c:2797 sql_help.c:2811 +#: sql_help.c:2852 sql_help.c:2876 sql_help.c:2888 sql_help.c:3764 +#: sql_help.c:4112 +msgid "tablespace_name" +msgstr "テーブル空間名" + +#: sql_help.c:593 sql_help.c:681 sql_help.c:1324 sql_help.c:1333 +#: sql_help.c:1371 sql_help.c:1722 +msgid "index_name" +msgstr "インデックス名" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1326 +#: sql_help.c:1328 sql_help.c:1374 sql_help.c:2374 sql_help.c:2408 +#: sql_help.c:2782 sql_help.c:2795 sql_help.c:2809 sql_help.c:2850 +#: sql_help.c:2874 +msgid "storage_parameter" +msgstr "ストレージパラメータ" + +#: sql_help.c:602 +msgid "column_number" +msgstr "列番号" + +#: sql_help.c:626 sql_help.c:1805 sql_help.c:4202 +msgid "large_object_oid" +msgstr "ラージオブジェクトのOID" + +#: sql_help.c:713 sql_help.c:2431 +msgid "res_proc" +msgstr "制約選択評価関数" + +#: sql_help.c:714 sql_help.c:2432 +msgid "join_proc" +msgstr "結合選択評価関数" + +#: sql_help.c:766 sql_help.c:778 sql_help.c:2449 +msgid "strategy_number" +msgstr "戦略番号" + +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2451 sql_help.c:2452 +#: sql_help.c:2455 sql_help.c:2456 +msgid "op_type" +msgstr "演算子の型" + +#: sql_help.c:770 sql_help.c:2453 +msgid "sort_family_name" +msgstr "ソートファミリー名" + +#: sql_help.c:771 sql_help.c:781 sql_help.c:2454 +msgid "support_number" +msgstr "サポート番号" + +#: sql_help.c:775 sql_help.c:2071 sql_help.c:2458 sql_help.c:2965 +#: sql_help.c:2967 +msgid "argument_type" +msgstr "引数の型" + +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1494 sql_help.c:1497 +#: sql_help.c:1672 sql_help.c:1721 sql_help.c:1790 sql_help.c:1815 +#: sql_help.c:1828 sql_help.c:1843 sql_help.c:1900 sql_help.c:1906 +#: sql_help.c:2242 sql_help.c:2254 sql_help.c:2365 sql_help.c:2405 +#: sql_help.c:2482 sql_help.c:2525 sql_help.c:2581 sql_help.c:2632 +#: sql_help.c:2663 sql_help.c:2768 sql_help.c:2785 sql_help.c:2798 +#: sql_help.c:2871 sql_help.c:2991 sql_help.c:3168 sql_help.c:3391 +#: sql_help.c:3440 sql_help.c:3546 sql_help.c:3734 sql_help.c:3739 +#: sql_help.c:3785 sql_help.c:3817 sql_help.c:4082 sql_help.c:4087 +#: sql_help.c:4190 sql_help.c:4297 sql_help.c:4299 sql_help.c:4348 +#: sql_help.c:4387 sql_help.c:4536 sql_help.c:4538 sql_help.c:4587 +#: sql_help.c:4621 sql_help.c:4672 sql_help.c:4756 sql_help.c:4758 +#: sql_help.c:4807 +msgid "table_name" +msgstr "テーブル名" + +#: sql_help.c:811 sql_help.c:2484 +msgid "using_expression" +msgstr "USING表現" + +#: sql_help.c:812 sql_help.c:2485 +msgid "check_expression" +msgstr "CHECK表現" + +#: sql_help.c:886 sql_help.c:2526 +msgid "publication_parameter" +msgstr "パブリケーションパラメータ" + +#: sql_help.c:929 sql_help.c:1584 sql_help.c:2344 sql_help.c:2558 +#: sql_help.c:3102 +msgid "password" +msgstr "パスワード" + +#: sql_help.c:930 sql_help.c:1585 sql_help.c:2345 sql_help.c:2559 +#: sql_help.c:3103 +msgid "timestamp" +msgstr "タイムスタンプ" + +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1589 +#: sql_help.c:1593 sql_help.c:1596 sql_help.c:1599 sql_help.c:3744 +#: sql_help.c:4092 +msgid "database_name" +msgstr "データベース名" + +#: sql_help.c:1048 sql_help.c:2627 +msgid "increment" +msgstr "増分値" + +#: sql_help.c:1049 sql_help.c:2628 +msgid "minvalue" +msgstr "最小値" + +#: sql_help.c:1050 sql_help.c:2629 +msgid "maxvalue" +msgstr "最大値" + +#: sql_help.c:1051 sql_help.c:2630 sql_help.c:4295 sql_help.c:4385 +#: sql_help.c:4534 sql_help.c:4689 sql_help.c:4754 +msgid "start" +msgstr "開始番号" + +#: sql_help.c:1052 sql_help.c:1301 +msgid "restart" +msgstr "再開始番号" + +#: sql_help.c:1053 sql_help.c:2631 +msgid "cache" +msgstr "キャッシュ割り当て数" + +#: sql_help.c:1097 +msgid "new_target" +msgstr "新しいターゲット" + +#: sql_help.c:1113 sql_help.c:2675 +msgid "conninfo" +msgstr "接続文字列" + +#: sql_help.c:1115 sql_help.c:2676 +msgid "publication_name" +msgstr "パブリケーション名" + +#: sql_help.c:1116 +msgid "set_publication_option" +msgstr "{SET PUBLICATION の追加オプション}" + +#: sql_help.c:1119 +msgid "refresh_option" +msgstr "{REFRESH PUBLICATION の追加オプション}" + +#: sql_help.c:1124 sql_help.c:2677 +msgid "subscription_parameter" +msgstr "{SUBSCRIPTION パラメータ名}" + +#: sql_help.c:1278 sql_help.c:1281 +msgid "partition_name" +msgstr "パーティション名" + +#: sql_help.c:1279 sql_help.c:2259 sql_help.c:2803 +msgid "partition_bound_spec" +msgstr "パーティション境界の仕様" + +#: sql_help.c:1298 sql_help.c:1345 sql_help.c:2817 +msgid "sequence_options" +msgstr "シーケンスオプション" + +#: sql_help.c:1300 +msgid "sequence_option" +msgstr "シーケンスオプション" + +#: sql_help.c:1312 +msgid "table_constraint_using_index" +msgstr "インデックスを使うテーブルの制約" + +#: sql_help.c:1320 sql_help.c:1321 sql_help.c:1322 sql_help.c:1323 +msgid "rewrite_rule_name" +msgstr "書き換えルール名" + +#: sql_help.c:1334 sql_help.c:2842 +msgid "and partition_bound_spec is:" +msgstr "パーティション境界の仕様は以下の通りです:" + +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:2843 +#: sql_help.c:2844 sql_help.c:2845 +msgid "partition_bound_expr" +msgstr "パーティション境界式" + +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:2846 sql_help.c:2847 +msgid "numeric_literal" +msgstr "数値定数" + +#: sql_help.c:1340 +msgid "and column_constraint is:" +msgstr "そしてカラム制約は以下の通りです:" + +#: sql_help.c:1343 sql_help.c:2266 sql_help.c:2299 sql_help.c:2505 +#: sql_help.c:2815 +msgid "default_expr" +msgstr "デフォルト表現" + +#: sql_help.c:1344 sql_help.c:2267 sql_help.c:2816 +msgid "generation_expr" +msgstr "生成式" + +#: sql_help.c:1346 sql_help.c:1347 sql_help.c:1356 sql_help.c:1358 +#: sql_help.c:1362 sql_help.c:2818 sql_help.c:2819 sql_help.c:2828 +#: sql_help.c:2830 sql_help.c:2834 +msgid "index_parameters" +msgstr "インデックスパラメータ" + +#: sql_help.c:1348 sql_help.c:1365 sql_help.c:2820 sql_help.c:2837 +msgid "reftable" +msgstr "参照テーブル" + +#: sql_help.c:1349 sql_help.c:1366 sql_help.c:2821 sql_help.c:2838 +msgid "refcolumn" +msgstr "参照列" + +#: sql_help.c:1350 sql_help.c:1351 sql_help.c:1367 sql_help.c:1368 +#: sql_help.c:2822 sql_help.c:2823 sql_help.c:2839 sql_help.c:2840 +msgid "referential_action" +msgstr "参照動作" + +#: sql_help.c:1352 sql_help.c:2268 sql_help.c:2824 +msgid "and table_constraint is:" +msgstr "テーブル制約は以下の通りです:" + +#: sql_help.c:1360 sql_help.c:2832 +msgid "exclude_element" +msgstr "除外対象要素" + +#: sql_help.c:1361 sql_help.c:2833 sql_help.c:4293 sql_help.c:4383 +#: sql_help.c:4532 sql_help.c:4687 sql_help.c:4752 +msgid "operator" +msgstr "演算子" + +#: sql_help.c:1363 sql_help.c:2377 sql_help.c:2835 +msgid "predicate" +msgstr "インデックスの述語" + +#: sql_help.c:1369 +msgid "and table_constraint_using_index is:" +msgstr "テーブル制約は以下の通りです:" + +#: sql_help.c:1372 sql_help.c:2848 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "UNIQUE, PRIMARY KEY, EXCLUDE 制約のインデックスパラメータは以下の通りです:" + +#: sql_help.c:1377 sql_help.c:2853 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "EXCLUDE 制約の除外対象要素は以下の通りです:" + +#: sql_help.c:1380 sql_help.c:2370 sql_help.c:2780 sql_help.c:2793 +#: sql_help.c:2807 sql_help.c:2856 sql_help.c:3830 +msgid "opclass" +msgstr "演算子クラス" + +#: sql_help.c:1396 sql_help.c:1399 sql_help.c:2891 +msgid "tablespace_option" +msgstr "テーブル空間のオプション" + +#: sql_help.c:1420 sql_help.c:1423 sql_help.c:1429 sql_help.c:1433 +msgid "token_type" +msgstr "トークンの型" + +#: sql_help.c:1421 sql_help.c:1424 +msgid "dictionary_name" +msgstr "辞書名" + +#: sql_help.c:1426 sql_help.c:1430 +msgid "old_dictionary" +msgstr "元の辞書" + +#: sql_help.c:1427 sql_help.c:1431 +msgid "new_dictionary" +msgstr "新しい辞書" + +#: sql_help.c:1526 sql_help.c:1540 sql_help.c:1543 sql_help.c:1544 +#: sql_help.c:3042 +msgid "attribute_name" +msgstr "属性名" + +#: sql_help.c:1527 +msgid "new_attribute_name" +msgstr "新しい属性名" + +#: sql_help.c:1531 sql_help.c:1535 +msgid "new_enum_value" +msgstr "新しい列挙値" + +#: sql_help.c:1532 +msgid "neighbor_enum_value" +msgstr "隣接した列挙値" + +#: sql_help.c:1534 +msgid "existing_enum_value" +msgstr "既存の列挙値" + +#: sql_help.c:1537 +msgid "property" +msgstr "プロパティ" + +#: sql_help.c:1612 sql_help.c:2251 sql_help.c:2260 sql_help.c:2643 +#: sql_help.c:3120 sql_help.c:3571 sql_help.c:3750 sql_help.c:3786 +#: sql_help.c:4098 +msgid "server_name" +msgstr "サーバ名" + +#: sql_help.c:1644 sql_help.c:1647 sql_help.c:3135 +msgid "view_option_name" +msgstr "ビューのオプション名" + +#: sql_help.c:1645 sql_help.c:3136 +msgid "view_option_value" +msgstr "ビューオプションの値" + +#: sql_help.c:1666 sql_help.c:1667 sql_help.c:4659 sql_help.c:4660 +msgid "table_and_columns" +msgstr "テーブルおよび列" + +#: sql_help.c:1668 sql_help.c:1912 sql_help.c:3619 sql_help.c:3963 +#: sql_help.c:4661 +msgid "where option can be one of:" +msgstr "オプションには以下のうちのいずれかを指定します:" + +#: sql_help.c:1669 sql_help.c:1670 sql_help.c:1914 sql_help.c:1917 +#: sql_help.c:2096 sql_help.c:3620 sql_help.c:3621 sql_help.c:3622 +#: sql_help.c:3623 sql_help.c:3624 sql_help.c:3625 sql_help.c:3626 +#: sql_help.c:3627 sql_help.c:4662 sql_help.c:4663 sql_help.c:4664 +#: sql_help.c:4665 sql_help.c:4666 sql_help.c:4667 sql_help.c:4668 +#: sql_help.c:4669 +msgid "boolean" +msgstr "真偽値" + +#: sql_help.c:1671 sql_help.c:4671 +msgid "and table_and_columns is:" +msgstr "そしてテーブルと列の指定は以下の通りです:" + +#: sql_help.c:1687 sql_help.c:4443 sql_help.c:4445 sql_help.c:4469 +msgid "transaction_mode" +msgstr "トランザクションのモード" + +#: sql_help.c:1688 sql_help.c:4446 sql_help.c:4470 +msgid "where transaction_mode is one of:" +msgstr "トランザクションのモードは以下の通りです:" + +#: sql_help.c:1697 sql_help.c:4303 sql_help.c:4312 sql_help.c:4316 +#: sql_help.c:4320 sql_help.c:4323 sql_help.c:4542 sql_help.c:4551 +#: sql_help.c:4555 sql_help.c:4559 sql_help.c:4562 sql_help.c:4762 +#: sql_help.c:4771 sql_help.c:4775 sql_help.c:4779 sql_help.c:4782 +msgid "argument" +msgstr "引数" + +#: sql_help.c:1787 +msgid "relation_name" +msgstr "リレーション名" + +#: sql_help.c:1792 sql_help.c:3746 sql_help.c:4094 +msgid "domain_name" +msgstr "ドメイン名" + +#: sql_help.c:1814 +msgid "policy_name" +msgstr "ポリシー名" + +#: sql_help.c:1827 +msgid "rule_name" +msgstr "ルール名" + +#: sql_help.c:1846 +msgid "text" +msgstr "コメント文字列" + +#: sql_help.c:1871 sql_help.c:3930 sql_help.c:4135 +msgid "transaction_id" +msgstr "トランザクションID" + +#: sql_help.c:1902 sql_help.c:1909 sql_help.c:3856 +msgid "filename" +msgstr "ファイル名" + +#: sql_help.c:1903 sql_help.c:1910 sql_help.c:2583 sql_help.c:2584 +#: sql_help.c:2585 +msgid "command" +msgstr "コマンド" + +#: sql_help.c:1905 sql_help.c:2582 sql_help.c:2994 sql_help.c:3171 +#: sql_help.c:3840 sql_help.c:4286 sql_help.c:4288 sql_help.c:4376 +#: sql_help.c:4378 sql_help.c:4525 sql_help.c:4527 sql_help.c:4630 +#: sql_help.c:4745 sql_help.c:4747 +msgid "condition" +msgstr "条件" + +#: sql_help.c:1908 sql_help.c:2411 sql_help.c:2877 sql_help.c:3137 +#: sql_help.c:3155 sql_help.c:3821 +msgid "query" +msgstr "問い合わせ" + +#: sql_help.c:1913 +msgid "format_name" +msgstr "フォーマット名" + +#: sql_help.c:1915 +msgid "delimiter_character" +msgstr "区切り文字" + +#: sql_help.c:1916 +msgid "null_string" +msgstr "NULL文字列" + +#: sql_help.c:1918 +msgid "quote_character" +msgstr "引用符文字" + +#: sql_help.c:1919 +msgid "escape_character" +msgstr "エスケープ文字" + +#: sql_help.c:1923 +msgid "encoding_name" +msgstr "エンコーディング名" + +#: sql_help.c:1934 +msgid "access_method_type" +msgstr "アクセスメソッドの型" + +#: sql_help.c:2005 sql_help.c:2024 sql_help.c:2027 +msgid "arg_data_type" +msgstr "入力データ型" + +#: sql_help.c:2006 sql_help.c:2028 sql_help.c:2036 +msgid "sfunc" +msgstr "状態遷移関数" + +#: sql_help.c:2007 sql_help.c:2029 sql_help.c:2037 +msgid "state_data_type" +msgstr "状態データの型" + +#: sql_help.c:2008 sql_help.c:2030 sql_help.c:2038 +msgid "state_data_size" +msgstr "状態データのサイズ" + +#: sql_help.c:2009 sql_help.c:2031 sql_help.c:2039 +msgid "ffunc" +msgstr "終了関数" + +#: sql_help.c:2010 sql_help.c:2040 +msgid "combinefunc" +msgstr "結合関数" + +#: sql_help.c:2011 sql_help.c:2041 +msgid "serialfunc" +msgstr "シリアライズ関数" + +#: sql_help.c:2012 sql_help.c:2042 +msgid "deserialfunc" +msgstr "デシリアライズ関数" + +#: sql_help.c:2013 sql_help.c:2032 sql_help.c:2043 +msgid "initial_condition" +msgstr "初期条件" + +#: sql_help.c:2014 sql_help.c:2044 +msgid "msfunc" +msgstr "前方状態遷移関数" + +#: sql_help.c:2015 sql_help.c:2045 +msgid "minvfunc" +msgstr "逆状態遷移関数" + +#: sql_help.c:2016 sql_help.c:2046 +msgid "mstate_data_type" +msgstr "移動集約モード時の状態値のデータ型" + +#: sql_help.c:2017 sql_help.c:2047 +msgid "mstate_data_size" +msgstr "移動集約モード時の状態値のデータサイズ" + +#: sql_help.c:2018 sql_help.c:2048 +msgid "mffunc" +msgstr "移動集約モード時の終了関数" + +#: sql_help.c:2019 sql_help.c:2049 +msgid "minitial_condition" +msgstr "移動集約モード時の初期条件" + +#: sql_help.c:2020 sql_help.c:2050 +msgid "sort_operator" +msgstr "ソート演算子" + +#: sql_help.c:2033 +msgid "or the old syntax" +msgstr "または古い構文" + +#: sql_help.c:2035 +msgid "base_type" +msgstr "基本の型" + +#: sql_help.c:2092 sql_help.c:2133 +msgid "locale" +msgstr "ロケール" + +#: sql_help.c:2093 sql_help.c:2134 +msgid "lc_collate" +msgstr "照合順序" + +#: sql_help.c:2094 sql_help.c:2135 +msgid "lc_ctype" +msgstr "Ctype(変換演算子)" + +#: sql_help.c:2095 sql_help.c:4188 +msgid "provider" +msgstr "プロバイダ" + +#: sql_help.c:2097 sql_help.c:2189 +msgid "version" +msgstr "バージョン" + +#: sql_help.c:2099 +msgid "existing_collation" +msgstr "既存の照合順序" + +#: sql_help.c:2109 +msgid "source_encoding" +msgstr "変換元のエンコーディング" + +#: sql_help.c:2110 +msgid "dest_encoding" +msgstr "変換先のエンコーディング" + +#: sql_help.c:2131 sql_help.c:2917 +msgid "template" +msgstr "テンプレート" + +#: sql_help.c:2132 +msgid "encoding" +msgstr "エンコード" + +#: sql_help.c:2159 +msgid "constraint" +msgstr "制約条件" + +#: sql_help.c:2160 +msgid "where constraint is:" +msgstr "制約条件は以下の通りです:" + +#: sql_help.c:2174 sql_help.c:2580 sql_help.c:2990 +msgid "event" +msgstr "イベント" + +#: sql_help.c:2175 +msgid "filter_variable" +msgstr "フィルター変数" + +#: sql_help.c:2263 sql_help.c:2812 +msgid "where column_constraint is:" +msgstr "カラム制約は以下の通りです:" + +#: sql_help.c:2300 +msgid "rettype" +msgstr "戻り値の型" + +#: sql_help.c:2302 +msgid "column_type" +msgstr "列の型" + +#: sql_help.c:2311 sql_help.c:2511 +msgid "definition" +msgstr "定義" + +#: sql_help.c:2312 sql_help.c:2512 +msgid "obj_file" +msgstr "オブジェクトファイル名" + +#: sql_help.c:2313 sql_help.c:2513 +msgid "link_symbol" +msgstr "リンクシンボル" + +#: sql_help.c:2351 sql_help.c:2565 sql_help.c:3109 +msgid "uid" +msgstr "UID" + +#: sql_help.c:2366 sql_help.c:2407 sql_help.c:2781 sql_help.c:2794 +#: sql_help.c:2808 sql_help.c:2873 +msgid "method" +msgstr "インデックスメソッド" + +#: sql_help.c:2371 +msgid "opclass_parameter" +msgstr "演算子クラスパラメータ" + +#: sql_help.c:2388 +msgid "call_handler" +msgstr "呼び出しハンドラー" + +#: sql_help.c:2389 +msgid "inline_handler" +msgstr "インラインハンドラー" + +#: sql_help.c:2390 +msgid "valfunction" +msgstr "バリデーション関数" + +#: sql_help.c:2429 +msgid "com_op" +msgstr "交代演算子" + +#: sql_help.c:2430 +msgid "neg_op" +msgstr "否定演算子" + +#: sql_help.c:2448 +msgid "family_name" +msgstr "演算子族の名前" + +#: sql_help.c:2459 +msgid "storage_type" +msgstr "ストレージタイプ" + +#: sql_help.c:2586 sql_help.c:2997 +msgid "where event can be one of:" +msgstr "イベントは以下のいずれかです:" + +#: sql_help.c:2605 sql_help.c:2607 +msgid "schema_element" +msgstr "スキーマ要素" + +#: sql_help.c:2644 +msgid "server_type" +msgstr "サーバのタイプ" + +#: sql_help.c:2645 +msgid "server_version" +msgstr "サーバのバージョン" + +#: sql_help.c:2646 sql_help.c:3748 sql_help.c:4096 +msgid "fdw_name" +msgstr "外部データラッパ名" + +#: sql_help.c:2659 +msgid "statistics_name" +msgstr "統計オブジェクト名" + +#: sql_help.c:2660 +msgid "statistics_kind" +msgstr "統計種別" + +#: sql_help.c:2674 +msgid "subscription_name" +msgstr "サブスクリプション名" + +#: sql_help.c:2774 +msgid "source_table" +msgstr "コピー元のテーブル" + +#: sql_help.c:2775 +msgid "like_option" +msgstr "LIKEオプション" + +#: sql_help.c:2841 +msgid "and like_option is:" +msgstr "LIKE オプションは以下の通りです:" + +#: sql_help.c:2890 +msgid "directory" +msgstr "ディレクトリ" + +#: sql_help.c:2904 +msgid "parser_name" +msgstr "パーサ名" + +#: sql_help.c:2905 +msgid "source_config" +msgstr "複製元の設定" + +#: sql_help.c:2934 +msgid "start_function" +msgstr "開始関数" + +#: sql_help.c:2935 +msgid "gettoken_function" +msgstr "トークン取得関数" + +#: sql_help.c:2936 +msgid "end_function" +msgstr "終了関数" + +#: sql_help.c:2937 +msgid "lextypes_function" +msgstr "LEXTYPE関数" + +#: sql_help.c:2938 +msgid "headline_function" +msgstr "見出し関数" + +#: sql_help.c:2950 +msgid "init_function" +msgstr "初期処理関数" + +#: sql_help.c:2951 +msgid "lexize_function" +msgstr "LEXIZE関数" + +#: sql_help.c:2964 +msgid "from_sql_function_name" +msgstr "{FROM SQL 関数名}" + +#: sql_help.c:2966 +msgid "to_sql_function_name" +msgstr "{TO SQL 関数名}" + +#: sql_help.c:2992 +msgid "referenced_table_name" +msgstr "被参照テーブル名" + +#: sql_help.c:2993 +msgid "transition_relation_name" +msgstr "移行用リレーション名" + +#: sql_help.c:2996 +msgid "arguments" +msgstr "引数" + +#: sql_help.c:3046 sql_help.c:4221 +msgid "label" +msgstr "ラベル" + +#: sql_help.c:3048 +msgid "subtype" +msgstr "当該範囲のデータ型" + +#: sql_help.c:3049 +msgid "subtype_operator_class" +msgstr "当該範囲のデータ型の演算子クラス" + +#: sql_help.c:3051 +msgid "canonical_function" +msgstr "正規化関数" + +#: sql_help.c:3052 +msgid "subtype_diff_function" +msgstr "当該範囲のデータ型の差分抽出関数" + +#: sql_help.c:3054 +msgid "input_function" +msgstr "入力関数" + +#: sql_help.c:3055 +msgid "output_function" +msgstr "出力関数" + +#: sql_help.c:3056 +msgid "receive_function" +msgstr "受信関数" + +#: sql_help.c:3057 +msgid "send_function" +msgstr "送信関数" + +#: sql_help.c:3058 +msgid "type_modifier_input_function" +msgstr "型修飾子の入力関数" + +#: sql_help.c:3059 +msgid "type_modifier_output_function" +msgstr "型修飾子の出力関数" + +#: sql_help.c:3060 +msgid "analyze_function" +msgstr "分析関数" + +#: sql_help.c:3061 +msgid "internallength" +msgstr "内部長" + +#: sql_help.c:3062 +msgid "alignment" +msgstr "バイト境界" + +#: sql_help.c:3063 +msgid "storage" +msgstr "ストレージ" + +#: sql_help.c:3064 +msgid "like_type" +msgstr "LIKEの型" + +#: sql_help.c:3065 +msgid "category" +msgstr "カテゴリー" + +#: sql_help.c:3066 +msgid "preferred" +msgstr "優先データ型かどうか(真偽値)" + +#: sql_help.c:3067 +msgid "default" +msgstr "デフォルト" + +#: sql_help.c:3068 +msgid "element" +msgstr "要素のデータ型" + +#: sql_help.c:3069 +msgid "delimiter" +msgstr "区切り記号" + +#: sql_help.c:3070 +msgid "collatable" +msgstr "照合可能" + +#: sql_help.c:3167 sql_help.c:3816 sql_help.c:4281 sql_help.c:4370 +#: sql_help.c:4520 sql_help.c:4620 sql_help.c:4740 +msgid "with_query" +msgstr "WITH問い合わせ" + +#: sql_help.c:3169 sql_help.c:3818 sql_help.c:4300 sql_help.c:4306 +#: sql_help.c:4309 sql_help.c:4313 sql_help.c:4317 sql_help.c:4325 +#: sql_help.c:4539 sql_help.c:4545 sql_help.c:4548 sql_help.c:4552 +#: sql_help.c:4556 sql_help.c:4564 sql_help.c:4622 sql_help.c:4759 +#: sql_help.c:4765 sql_help.c:4768 sql_help.c:4772 sql_help.c:4776 +#: sql_help.c:4784 +msgid "alias" +msgstr "エイリアス" + +#: sql_help.c:3170 sql_help.c:4285 sql_help.c:4327 sql_help.c:4329 +#: sql_help.c:4375 sql_help.c:4524 sql_help.c:4566 sql_help.c:4568 +#: sql_help.c:4629 sql_help.c:4744 sql_help.c:4786 sql_help.c:4788 +msgid "from_item" +msgstr "FROM項目" + +#: sql_help.c:3172 sql_help.c:3653 sql_help.c:3897 sql_help.c:4631 +msgid "cursor_name" +msgstr "カーソル名" + +#: sql_help.c:3173 sql_help.c:3824 sql_help.c:4632 +msgid "output_expression" +msgstr "出力表現" + +#: sql_help.c:3174 sql_help.c:3825 sql_help.c:4284 sql_help.c:4373 +#: sql_help.c:4523 sql_help.c:4633 sql_help.c:4743 +msgid "output_name" +msgstr "出力名" + +#: sql_help.c:3190 +msgid "code" +msgstr "コードブロック" + +#: sql_help.c:3595 +msgid "parameter" +msgstr "パラメータ" + +#: sql_help.c:3617 sql_help.c:3618 sql_help.c:3922 +msgid "statement" +msgstr "ステートメント" + +#: sql_help.c:3652 sql_help.c:3896 +msgid "direction" +msgstr "取り出す方向と行数" + +#: sql_help.c:3654 sql_help.c:3898 +msgid "where direction can be empty or one of:" +msgstr "取り出す方向と行数は無指定もしくは以下のいずれかです:" + +#: sql_help.c:3655 sql_help.c:3656 sql_help.c:3657 sql_help.c:3658 +#: sql_help.c:3659 sql_help.c:3899 sql_help.c:3900 sql_help.c:3901 +#: sql_help.c:3902 sql_help.c:3903 sql_help.c:4294 sql_help.c:4296 +#: sql_help.c:4384 sql_help.c:4386 sql_help.c:4533 sql_help.c:4535 +#: sql_help.c:4688 sql_help.c:4690 sql_help.c:4753 sql_help.c:4755 +msgid "count" +msgstr "取り出す位置や行数" + +#: sql_help.c:3741 sql_help.c:4089 +msgid "sequence_name" +msgstr "シーケンス名" + +#: sql_help.c:3754 sql_help.c:4102 +msgid "arg_name" +msgstr "引数名" + +#: sql_help.c:3755 sql_help.c:4103 +msgid "arg_type" +msgstr "引数の型" + +#: sql_help.c:3760 sql_help.c:4108 +msgid "loid" +msgstr "ラージオブジェクトid" + +#: sql_help.c:3784 +msgid "remote_schema" +msgstr "リモートスキーマ" + +#: sql_help.c:3787 +msgid "local_schema" +msgstr "ローカルスキーマ" + +#: sql_help.c:3822 +msgid "conflict_target" +msgstr "競合ターゲット" + +#: sql_help.c:3823 +msgid "conflict_action" +msgstr "競合時アクション" + +#: sql_help.c:3826 +msgid "where conflict_target can be one of:" +msgstr "競合ターゲットは以下のいずれかです:" + +#: sql_help.c:3827 +msgid "index_column_name" +msgstr "インデックスのカラム名" + +#: sql_help.c:3828 +msgid "index_expression" +msgstr "インデックス表現" + +#: sql_help.c:3831 +msgid "index_predicate" +msgstr "インデックスの述語" + +#: sql_help.c:3833 +msgid "and conflict_action is one of:" +msgstr "競合時アクションは以下のいずれかです:" + +#: sql_help.c:3839 sql_help.c:4628 +msgid "sub-SELECT" +msgstr "副問い合わせ句" + +#: sql_help.c:3848 sql_help.c:3911 sql_help.c:4604 +msgid "channel" +msgstr "チャネル" + +#: sql_help.c:3870 +msgid "lockmode" +msgstr "ロックモード" + +#: sql_help.c:3871 +msgid "where lockmode is one of:" +msgstr "ロックモードは以下のいずれかです:" + +#: sql_help.c:3912 +msgid "payload" +msgstr "ペイロード" + +#: sql_help.c:3939 +msgid "old_role" +msgstr "元のロール" + +#: sql_help.c:3940 +msgid "new_role" +msgstr "新しいロール" + +#: sql_help.c:3971 sql_help.c:4143 sql_help.c:4151 +msgid "savepoint_name" +msgstr "セーブポイント名" + +#: sql_help.c:4287 sql_help.c:4339 sql_help.c:4526 sql_help.c:4578 +#: sql_help.c:4746 sql_help.c:4798 +msgid "grouping_element" +msgstr "グルーピング要素" + +#: sql_help.c:4289 sql_help.c:4379 sql_help.c:4528 sql_help.c:4748 +msgid "window_name" +msgstr "ウィンドウ名" + +#: sql_help.c:4290 sql_help.c:4380 sql_help.c:4529 sql_help.c:4749 +msgid "window_definition" +msgstr "ウィンドウ定義" + +#: sql_help.c:4291 sql_help.c:4305 sql_help.c:4343 sql_help.c:4381 +#: sql_help.c:4530 sql_help.c:4544 sql_help.c:4582 sql_help.c:4750 +#: sql_help.c:4764 sql_help.c:4802 +msgid "select" +msgstr "SELECT句" + +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4757 +msgid "where from_item can be one of:" +msgstr "FROM項目は以下のいずれかです:" + +#: sql_help.c:4301 sql_help.c:4307 sql_help.c:4310 sql_help.c:4314 +#: sql_help.c:4326 sql_help.c:4540 sql_help.c:4546 sql_help.c:4549 +#: sql_help.c:4553 sql_help.c:4565 sql_help.c:4760 sql_help.c:4766 +#: sql_help.c:4769 sql_help.c:4773 sql_help.c:4785 +msgid "column_alias" +msgstr "行エイリアス" + +#: sql_help.c:4302 sql_help.c:4541 sql_help.c:4761 +msgid "sampling_method" +msgstr "サンプリングメソッド" + +#: sql_help.c:4304 sql_help.c:4543 sql_help.c:4763 +msgid "seed" +msgstr "乱数シード" + +#: sql_help.c:4308 sql_help.c:4341 sql_help.c:4547 sql_help.c:4580 +#: sql_help.c:4767 sql_help.c:4800 +msgid "with_query_name" +msgstr "WITH問い合わせ名" + +#: sql_help.c:4318 sql_help.c:4321 sql_help.c:4324 sql_help.c:4557 +#: sql_help.c:4560 sql_help.c:4563 sql_help.c:4777 sql_help.c:4780 +#: sql_help.c:4783 +msgid "column_definition" +msgstr "カラム定義" + +#: sql_help.c:4328 sql_help.c:4567 sql_help.c:4787 +msgid "join_type" +msgstr "JOINタイプ" + +#: sql_help.c:4330 sql_help.c:4569 sql_help.c:4789 +msgid "join_condition" +msgstr "JOIN条件" + +#: sql_help.c:4331 sql_help.c:4570 sql_help.c:4790 +msgid "join_column" +msgstr "JOINカラム" + +#: sql_help.c:4332 sql_help.c:4571 sql_help.c:4791 +msgid "and grouping_element can be one of:" +msgstr "グルーピング要素は以下のいずれかです:" + +#: sql_help.c:4340 sql_help.c:4579 sql_help.c:4799 +msgid "and with_query is:" +msgstr "WITH問い合わせは以下のいずれかです:" + +#: sql_help.c:4344 sql_help.c:4583 sql_help.c:4803 +msgid "values" +msgstr "VALUES句" + +#: sql_help.c:4345 sql_help.c:4584 sql_help.c:4804 +msgid "insert" +msgstr "INSERT句" + +#: sql_help.c:4346 sql_help.c:4585 sql_help.c:4805 +msgid "update" +msgstr "UPDATE句" + +#: sql_help.c:4347 sql_help.c:4586 sql_help.c:4806 +msgid "delete" +msgstr "DELETE句" + +#: sql_help.c:4374 +msgid "new_table" +msgstr "新しいテーブル" + +#: sql_help.c:4399 +msgid "timezone" +msgstr "タイムゾーン" + +#: sql_help.c:4444 +msgid "snapshot_id" +msgstr "スナップショットID" + +#: sql_help.c:4686 +msgid "sort_expression" +msgstr "ソート表現" + +#: sql_help.c:4813 sql_help.c:5791 +msgid "abort the current transaction" +msgstr "現在のトランザクションを中止します" + +#: sql_help.c:4819 +msgid "change the definition of an aggregate function" +msgstr "集約関数の定義を変更します。" + +#: sql_help.c:4825 +msgid "change the definition of a collation" +msgstr "照合順序の定義を変更します。" + +#: sql_help.c:4831 +msgid "change the definition of a conversion" +msgstr "エンコーディング変換ルールの定義を変更します。" + +#: sql_help.c:4837 +msgid "change a database" +msgstr "データベースを変更します。" + +#: sql_help.c:4843 +msgid "define default access privileges" +msgstr "デフォルトのアクセス権限を定義します。" + +#: sql_help.c:4849 +msgid "change the definition of a domain" +msgstr "ドメインの定義を変更します。" + +#: sql_help.c:4855 +msgid "change the definition of an event trigger" +msgstr "イベントトリガーの定義を変更します。" + +#: sql_help.c:4861 +msgid "change the definition of an extension" +msgstr "拡張の定義を変更します。" + +#: sql_help.c:4867 +msgid "change the definition of a foreign-data wrapper" +msgstr "外部データラッパの定義を変更します。" + +#: sql_help.c:4873 +msgid "change the definition of a foreign table" +msgstr "外部テーブルの定義を変更します。" + +#: sql_help.c:4879 +msgid "change the definition of a function" +msgstr "関数の定義を変更します。" + +#: sql_help.c:4885 +msgid "change role name or membership" +msgstr "ロール名またはメンバーシップを変更します。" + +#: sql_help.c:4891 +msgid "change the definition of an index" +msgstr "インデックスの定義を変更します。" + +#: sql_help.c:4897 +msgid "change the definition of a procedural language" +msgstr "手続き言語の定義を変更します。" + +#: sql_help.c:4903 +msgid "change the definition of a large object" +msgstr "ラージオブジェクトの定義を変更します。" + +#: sql_help.c:4909 +msgid "change the definition of a materialized view" +msgstr "マテリアライズドビューの定義を変更します。" + +#: sql_help.c:4915 +msgid "change the definition of an operator" +msgstr "演算子の定義を変更します。" + +#: sql_help.c:4921 +msgid "change the definition of an operator class" +msgstr "演算子クラスの定義を変更します。" + +#: sql_help.c:4927 +msgid "change the definition of an operator family" +msgstr "演算子族の定義を変更します。" + +#: sql_help.c:4933 +msgid "change the definition of a row level security policy" +msgstr "行レベルのセキュリティ ポリシーの定義を変更します。" + +#: sql_help.c:4939 +msgid "change the definition of a procedure" +msgstr "プロシージャの定義を変更します" + +#: sql_help.c:4945 +msgid "change the definition of a publication" +msgstr "パブリケーションの定義を変更します。" + +#: sql_help.c:4951 sql_help.c:5053 +msgid "change a database role" +msgstr "データベースロールを変更します。" + +#: sql_help.c:4957 +msgid "change the definition of a routine" +msgstr "ルーチンの定義を変更します。" + +#: sql_help.c:4963 +msgid "change the definition of a rule" +msgstr "ルールの定義を変更します。" + +#: sql_help.c:4969 +msgid "change the definition of a schema" +msgstr "スキーマの定義を変更します。" + +#: sql_help.c:4975 +msgid "change the definition of a sequence generator" +msgstr "シーケンスジェネレーターの定義を変更します。" + +#: sql_help.c:4981 +msgid "change the definition of a foreign server" +msgstr "外部サーバの定義を変更します。" + +#: sql_help.c:4987 +msgid "change the definition of an extended statistics object" +msgstr "拡張統計情報オブジェクトの定義を変更します。" + +#: sql_help.c:4993 +msgid "change the definition of a subscription" +msgstr "サブスクリプションの定義を変更します。" + +#: sql_help.c:4999 +msgid "change a server configuration parameter" +msgstr "サーバの構成パラメータを変更します。" + +#: sql_help.c:5005 +msgid "change the definition of a table" +msgstr "テーブルの定義を変更します。" + +#: sql_help.c:5011 +msgid "change the definition of a tablespace" +msgstr "テーブル空間の定義を変更します。" + +#: sql_help.c:5017 +msgid "change the definition of a text search configuration" +msgstr "テキスト検索設定の定義を変更します。" + +#: sql_help.c:5023 +msgid "change the definition of a text search dictionary" +msgstr "テキスト検索辞書の定義を変更します。" + +#: sql_help.c:5029 +msgid "change the definition of a text search parser" +msgstr "テキスト検索パーサの定義を変更します。" + +#: sql_help.c:5035 +msgid "change the definition of a text search template" +msgstr "テキスト検索テンプレートの定義を変更します。" + +#: sql_help.c:5041 +msgid "change the definition of a trigger" +msgstr "トリガーの定義を変更します。" + +#: sql_help.c:5047 +msgid "change the definition of a type" +msgstr "型の定義を変更します。" + +#: sql_help.c:5059 +msgid "change the definition of a user mapping" +msgstr "ユーザマッピングの定義を変更します。" + +#: sql_help.c:5065 +msgid "change the definition of a view" +msgstr "ビューの定義を変更します。" + +#: sql_help.c:5071 +msgid "collect statistics about a database" +msgstr "データベースの統計情報を収集します。" + +#: sql_help.c:5077 sql_help.c:5869 +msgid "start a transaction block" +msgstr "トランザクションブロックを開始します。" + +#: sql_help.c:5083 +msgid "invoke a procedure" +msgstr "プロシージャを実行します" + +#: sql_help.c:5089 +msgid "force a write-ahead log checkpoint" +msgstr "先行書き込みログのチェックポイントを強制的に実行します。" + +#: sql_help.c:5095 +msgid "close a cursor" +msgstr "カーソルを閉じます。" + +#: sql_help.c:5101 +msgid "cluster a table according to an index" +msgstr "インデックスに従ってテーブルをクラスタ化します。" + +#: sql_help.c:5107 +msgid "define or change the comment of an object" +msgstr "オブジェクトのコメントを定義または変更します。" + +#: sql_help.c:5113 sql_help.c:5671 +msgid "commit the current transaction" +msgstr "現在のトランザクションをコミットします。" + +#: sql_help.c:5119 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "二相コミットのために事前に準備されたトランザクションをコミットします。" + +#: sql_help.c:5125 +msgid "copy data between a file and a table" +msgstr "ファイルとテーブル間でデータをコピーします。" + +#: sql_help.c:5131 +msgid "define a new access method" +msgstr "新しいアクセスメソッドを定義します。" + +#: sql_help.c:5137 +msgid "define a new aggregate function" +msgstr "新しい集約関数を定義します。" + +#: sql_help.c:5143 +msgid "define a new cast" +msgstr "新しいキャストを定義します。" + +#: sql_help.c:5149 +msgid "define a new collation" +msgstr "新しい照合順序を定義します。" + +#: sql_help.c:5155 +msgid "define a new encoding conversion" +msgstr "新しいエンコーディングの変換ルールを定義します。" + +#: sql_help.c:5161 +msgid "create a new database" +msgstr "新しいデータベースを作成します。" + +#: sql_help.c:5167 +msgid "define a new domain" +msgstr "新しいドメインを定義します。" + +#: sql_help.c:5173 +msgid "define a new event trigger" +msgstr "新しいイベントトリガーを定義します。" + +#: sql_help.c:5179 +msgid "install an extension" +msgstr "拡張をインストールします。" + +#: sql_help.c:5185 +msgid "define a new foreign-data wrapper" +msgstr "新しい外部データラッパを定義します。" + +#: sql_help.c:5191 +msgid "define a new foreign table" +msgstr "新しい外部テーブルを定義します。" + +#: sql_help.c:5197 +msgid "define a new function" +msgstr "新しい関数を定義します。" + +#: sql_help.c:5203 sql_help.c:5263 sql_help.c:5365 +msgid "define a new database role" +msgstr "新しいデータベースロールを定義します。" + +#: sql_help.c:5209 +msgid "define a new index" +msgstr "新しいインデックスを定義します。" + +#: sql_help.c:5215 +msgid "define a new procedural language" +msgstr "新しい手続き言語を定義します。" + +#: sql_help.c:5221 +msgid "define a new materialized view" +msgstr "新しいマテリアライズドビューを定義します。" + +#: sql_help.c:5227 +msgid "define a new operator" +msgstr "新しい演算子を定義します。" + +#: sql_help.c:5233 +msgid "define a new operator class" +msgstr "新しい演算子クラスを定義します。" + +#: sql_help.c:5239 +msgid "define a new operator family" +msgstr "新しい演算子族を定義します。" + +#: sql_help.c:5245 +msgid "define a new row level security policy for a table" +msgstr "テーブルに対して新しい行レベルのセキュリティポリシーを定義します。" + +#: sql_help.c:5251 +msgid "define a new procedure" +msgstr "新しいプロシージャを定義します" + +#: sql_help.c:5257 +msgid "define a new publication" +msgstr "新しいパブリケーションを定義します。" + +#: sql_help.c:5269 +msgid "define a new rewrite rule" +msgstr "新しい書き換えルールを定義します。" + +#: sql_help.c:5275 +msgid "define a new schema" +msgstr "新しいスキーマを定義します。" + +#: sql_help.c:5281 +msgid "define a new sequence generator" +msgstr "新しいシーケンスジェネレーターを定義します。" + +#: sql_help.c:5287 +msgid "define a new foreign server" +msgstr "新しい外部サーバを定義します。" + +#: sql_help.c:5293 +msgid "define extended statistics" +msgstr "拡張統計情報を定義します。" + +#: sql_help.c:5299 +msgid "define a new subscription" +msgstr "新しいサブスクリプションを定義します。" + +#: sql_help.c:5305 +msgid "define a new table" +msgstr "新しいテーブルを定義します。" + +#: sql_help.c:5311 sql_help.c:5827 +msgid "define a new table from the results of a query" +msgstr "問い合わせの結果から新しいテーブルを定義します。" + +#: sql_help.c:5317 +msgid "define a new tablespace" +msgstr "新しいテーブル空間を定義します。" + +#: sql_help.c:5323 +msgid "define a new text search configuration" +msgstr "新しいテキスト検索設定を定義します。" + +#: sql_help.c:5329 +msgid "define a new text search dictionary" +msgstr "新しいテキスト検索辞書を定義します。" + +#: sql_help.c:5335 +msgid "define a new text search parser" +msgstr "新しいテキスト検索パーサを定義します。" + +#: sql_help.c:5341 +msgid "define a new text search template" +msgstr "新しいテキスト検索テンプレートを定義します。" + +#: sql_help.c:5347 +msgid "define a new transform" +msgstr "新しい変換を定義します。" + +#: sql_help.c:5353 +msgid "define a new trigger" +msgstr "新しいトリガーを定義します。" + +#: sql_help.c:5359 +msgid "define a new data type" +msgstr "新しいデータ型を定義します。" + +#: sql_help.c:5371 +msgid "define a new mapping of a user to a foreign server" +msgstr "外部サーバに対するユーザの新しいマッピングを定義します。" + +#: sql_help.c:5377 +msgid "define a new view" +msgstr "新しいビューを定義します。" + +#: sql_help.c:5383 +msgid "deallocate a prepared statement" +msgstr "プリペアドステートメントを開放します。" + +#: sql_help.c:5389 +msgid "define a cursor" +msgstr "カーソルを定義します。" + +#: sql_help.c:5395 +msgid "delete rows of a table" +msgstr "テーブルの行を削除します。" + +#: sql_help.c:5401 +msgid "discard session state" +msgstr "セッション状態を破棄します。" + +#: sql_help.c:5407 +msgid "execute an anonymous code block" +msgstr "無名コードブロックを実行します。" + +#: sql_help.c:5413 +msgid "remove an access method" +msgstr "アクセスメソッドを削除します。" + +#: sql_help.c:5419 +msgid "remove an aggregate function" +msgstr "集約関数を削除します。" + +#: sql_help.c:5425 +msgid "remove a cast" +msgstr "キャストを削除します。" + +#: sql_help.c:5431 +msgid "remove a collation" +msgstr "照合順序を削除します。" + +#: sql_help.c:5437 +msgid "remove a conversion" +msgstr "符号化方式変換を削除します。" + +#: sql_help.c:5443 +msgid "remove a database" +msgstr "データベースを削除します。" + +#: sql_help.c:5449 +msgid "remove a domain" +msgstr "ドメインを削除します。" + +#: sql_help.c:5455 +msgid "remove an event trigger" +msgstr "イベントトリガーを削除します。" + +#: sql_help.c:5461 +msgid "remove an extension" +msgstr "拡張を削除します。" + +#: sql_help.c:5467 +msgid "remove a foreign-data wrapper" +msgstr "外部データラッパを削除します。" + +#: sql_help.c:5473 +msgid "remove a foreign table" +msgstr "外部テーブルを削除します。" + +#: sql_help.c:5479 +msgid "remove a function" +msgstr "関数を削除します。" + +#: sql_help.c:5485 sql_help.c:5551 sql_help.c:5653 +msgid "remove a database role" +msgstr "データベースロールを削除します。" + +#: sql_help.c:5491 +msgid "remove an index" +msgstr "インデックスを削除します。" + +#: sql_help.c:5497 +msgid "remove a procedural language" +msgstr "手続き言語を削除します。" + +#: sql_help.c:5503 +msgid "remove a materialized view" +msgstr "マテリアライズドビューを削除します。" + +#: sql_help.c:5509 +msgid "remove an operator" +msgstr "演算子を削除します。" + +#: sql_help.c:5515 +msgid "remove an operator class" +msgstr "演算子クラスを削除します。" + +#: sql_help.c:5521 +msgid "remove an operator family" +msgstr "演算子族を削除します。" + +#: sql_help.c:5527 +msgid "remove database objects owned by a database role" +msgstr "データベースロールが所有するデータベースオブジェクトを削除します。" + +#: sql_help.c:5533 +msgid "remove a row level security policy from a table" +msgstr "テーブルから行レベルのセキュリティポリシーを削除します。" + +#: sql_help.c:5539 +msgid "remove a procedure" +msgstr "プロシージャを削除します。" + +#: sql_help.c:5545 +msgid "remove a publication" +msgstr "パブリケーションを削除します。" + +#: sql_help.c:5557 +msgid "remove a routine" +msgstr "ルーチンを削除します。" + +#: sql_help.c:5563 +msgid "remove a rewrite rule" +msgstr "書き換えルールを削除します。" + +#: sql_help.c:5569 +msgid "remove a schema" +msgstr "スキーマを削除します。" + +#: sql_help.c:5575 +msgid "remove a sequence" +msgstr "シーケンスを削除します。" + +#: sql_help.c:5581 +msgid "remove a foreign server descriptor" +msgstr "外部サーバ記述子を削除します。" + +#: sql_help.c:5587 +msgid "remove extended statistics" +msgstr "拡張統計情報を削除します。" + +#: sql_help.c:5593 +msgid "remove a subscription" +msgstr "サブスクリプションを削除します。" + +#: sql_help.c:5599 +msgid "remove a table" +msgstr "テーブルを削除します。" + +#: sql_help.c:5605 +msgid "remove a tablespace" +msgstr "テーブル空間を削除します。" + +#: sql_help.c:5611 +msgid "remove a text search configuration" +msgstr "テキスト検索設定を削除します。" + +#: sql_help.c:5617 +msgid "remove a text search dictionary" +msgstr "テキスト検索辞書を削除します。" + +#: sql_help.c:5623 +msgid "remove a text search parser" +msgstr "テキスト検索パーサを削除します。" + +#: sql_help.c:5629 +msgid "remove a text search template" +msgstr "テキスト検索テンプレートを削除します。" + +#: sql_help.c:5635 +msgid "remove a transform" +msgstr "自動変換ルールを削除します。" + +#: sql_help.c:5641 +msgid "remove a trigger" +msgstr "トリガーを削除します。" + +#: sql_help.c:5647 +msgid "remove a data type" +msgstr "データ型を削除します。" + +#: sql_help.c:5659 +msgid "remove a user mapping for a foreign server" +msgstr "外部サーバのユーザマッピングを削除します。" + +#: sql_help.c:5665 +msgid "remove a view" +msgstr "ビューを削除します。" + +#: sql_help.c:5677 +msgid "execute a prepared statement" +msgstr "プリペアドステートメントを実行します。" + +#: sql_help.c:5683 +msgid "show the execution plan of a statement" +msgstr "ステートメントの実行計画を表示します。" + +#: sql_help.c:5689 +msgid "retrieve rows from a query using a cursor" +msgstr "カーソルを使って問い合わせから行を取り出します。" + +#: sql_help.c:5695 +msgid "define access privileges" +msgstr "アクセス権限を定義します。" + +#: sql_help.c:5701 +msgid "import table definitions from a foreign server" +msgstr "外部サーバからテーブル定義をインポートします。" + +#: sql_help.c:5707 +msgid "create new rows in a table" +msgstr "テーブルに新しい行を作成します。" + +#: sql_help.c:5713 +msgid "listen for a notification" +msgstr "通知メッセージを監視します。" + +#: sql_help.c:5719 +msgid "load a shared library file" +msgstr "共有ライブラリファイルをロードします。" + +#: sql_help.c:5725 +msgid "lock a table" +msgstr "テーブルをロックします。" + +#: sql_help.c:5731 +msgid "position a cursor" +msgstr "カーソルを位置づけます。" + +#: sql_help.c:5737 +msgid "generate a notification" +msgstr "通知を生成します。" + +#: sql_help.c:5743 +msgid "prepare a statement for execution" +msgstr "実行に備えてステートメントを準備します。" + +#: sql_help.c:5749 +msgid "prepare the current transaction for two-phase commit" +msgstr "二相コミットに備えて現在のトランザクションを準備します。" + +#: sql_help.c:5755 +msgid "change the ownership of database objects owned by a database role" +msgstr "データベースロールが所有するデータベースオブジェクトの所有権を変更します。" + +#: sql_help.c:5761 +msgid "replace the contents of a materialized view" +msgstr "マテリアライズドビューの内容を置き換えます。" + +#: sql_help.c:5767 +msgid "rebuild indexes" +msgstr "インデックスを再構築します。" + +#: sql_help.c:5773 +msgid "destroy a previously defined savepoint" +msgstr "以前に定義されたセーブポイントを破棄します。" + +#: sql_help.c:5779 +msgid "restore the value of a run-time parameter to the default value" +msgstr "実行時パラメータの値をデフォルト値に戻します。" + +#: sql_help.c:5785 +msgid "remove access privileges" +msgstr "アクセス特権を削除します。" + +#: sql_help.c:5797 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "二相コミットのために事前に準備されたトランザクションをキャンセルします。" + +#: sql_help.c:5803 +msgid "roll back to a savepoint" +msgstr "セーブポイントまでロールバックします。" + +#: sql_help.c:5809 +msgid "define a new savepoint within the current transaction" +msgstr "現在のトランザクション内で新しいセーブポイントを定義します。" + +#: sql_help.c:5815 +msgid "define or change a security label applied to an object" +msgstr "オブジェクトに適用されるセキュリティラベルを定義または変更します。" + +#: sql_help.c:5821 sql_help.c:5875 sql_help.c:5911 +msgid "retrieve rows from a table or view" +msgstr "テーブルまたはビューから行を取得します。" + +#: sql_help.c:5833 +msgid "change a run-time parameter" +msgstr "実行時のパラメータを変更します。" + +#: sql_help.c:5839 +msgid "set constraint check timing for the current transaction" +msgstr "現在のトランザクションについて、制約チェックのタイミングを設定します。" + +#: sql_help.c:5845 +msgid "set the current user identifier of the current session" +msgstr "現在のセッションの現在のユーザ識別子を設定します。" + +#: sql_help.c:5851 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "セッションのユーザ識別子および現在のセッションの現在のユーザ識別子を設定します。" + +#: sql_help.c:5857 +msgid "set the characteristics of the current transaction" +msgstr "現在のトランザクションの特性を設定します。" + +#: sql_help.c:5863 +msgid "show the value of a run-time parameter" +msgstr "実行時パラメータの値を表示します。" + +#: sql_help.c:5881 +msgid "empty a table or set of tables" +msgstr "テーブルもしくはテーブルセットを0件に切り詰めます。" + +#: sql_help.c:5887 +msgid "stop listening for a notification" +msgstr "通知メッセージの監視を中止します。" + +#: sql_help.c:5893 +msgid "update rows of a table" +msgstr "テーブルの行を更新します。" + +#: sql_help.c:5899 +msgid "garbage-collect and optionally analyze a database" +msgstr "ガーベッジコレクションを行い、また必要に応じてデータベースを分析します。" + +#: sql_help.c:5905 +msgid "compute a set of rows" +msgstr "行セットを計算します。" + +#: startup.c:212 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 は非対話モード時でのみ使用可能です" + +#: startup.c:299 +#, c-format +msgid "could not connect to server: %s" +msgstr "サーバに接続できませんでした: %s" + +#: startup.c:327 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "ロックファイル\"%s\"をオープンできませんでした: %m" + +#: startup.c:439 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"\"help\"でヘルプを表示します。\n" +"\n" + +#: startup.c:589 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "表示パラメータ\"%s\"を設定できませんでした" + +#: startup.c:697 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細は\"%s --help\"をごらんください。\n" + +#: startup.c:714 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "余分なコマンドライン引数\"%s\"は無視されました" + +#: startup.c:763 +#, c-format +msgid "could not find own program executable" +msgstr "実行可能ファイルが見つかりませんでした" + +#: tab-complete.c:4672 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"タブ補完の問い合わせに失敗しました: %s\n" +"問い合わせ:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "\"%2$s\"の値\"%1$s\"が認識できません: 真偽値を指定してください" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "\"%2$s\"の値\"%1$s\"が不正です: 整数を指定してください" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "変数名が不正です: \"%s\"" + +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"\"%2$s\"の値\"%1$s\"が認識できません。\n" +"有効な値は %3$s。" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "カレントディレクトリを特定できませんでした: %s" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "ディレクトリ\"%s\"に移動できませんでした: %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "シンボリックリンク\"%s\"を読み取ることができませんでした" + +#~ msgid "pclose failed: %s" +#~ msgstr "pcloseが失敗しました: %s" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "子プロセスがシグナル %s で強制終了しました" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "子プロセスがシグナル %d で強制終了しました" + +#~ msgid "Invalid command \\%s. Try \\? for help.\n" +#~ msgstr "\\%s は無効なコマンドです。\\? でヘルプを参照してください。\n" + +#~ msgid "%s: %s\n" +#~ msgstr "%s: %s\n" + +#~ msgid "could not open temporary file \"%s\": %s\n" +#~ msgstr "一時ファイル\"%s\"を開けませんでした: %s\n" + +#~ msgid "could not execute command \"%s\": %s\n" +#~ msgstr "コマンド\"%s\"を実行できませんでした: %s\n" + +#~ msgid "could not stat file \"%s\": %s\n" +#~ msgstr "ファイル\"%s\"をstatできませんでした: %s\n" + +#~ msgid "could not close pipe to external command: %s\n" +#~ msgstr "外部コマンドへのパイプを閉じることができませんでした: %s\n" + +#~ msgid "%s\n" +#~ msgstr "%s\n" + +#~ msgid "unterminated quoted string\n" +#~ msgstr "文字列の引用符が閉じていません。\n" + +#~ msgid "string_literal" +#~ msgstr "文字列定数" + +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s: ログファイル\"%s\"を開くことができませんでした: %s\n" + +#~ msgid "attribute" +#~ msgstr "属性" + +#~ msgid " VERSION_NUM psql's version (numeric format)\n" +#~ msgstr " VERSION_NUM psql のバージョン (数値フォーマット)\n" + +#~ msgid " VERSION_NAME psql's version (short string)\n" +#~ msgstr " VERSION_NAME psql のバージョン (短い文字列)\n" + +#~ msgid " VERSION psql's version (verbose string)\n" +#~ msgstr " VERSION psql のバージョン (詳細な文字列)\n" + +#~ msgid " SERVER_VERSION_NAME server's version (short string)\n" +#~ msgstr " SERVER_VERSION_NAME サーバのバージョン名 (短い文字列)\n" + +#~ msgid "normal" +#~ msgstr "通常" + +#~ msgid "Procedure" +#~ msgstr "プロシージャー名" + +#~ msgid "from_list" +#~ msgstr "FROMリスト" + +#~ msgid "using_list" +#~ msgstr "USINGリスト" + +#~ msgid "old_version" +#~ msgstr "旧バージョン" + +#~ msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" +#~ msgstr " \\g [ファイル] または ; 問い合わせを実行(し、結果をファイルまたは |パイプ へ出力)します。\n" diff --git a/src/bin/psql/po/ko.po b/src/bin/psql/po/ko.po new file mode 100644 index 000000000000..3d3da974b68c --- /dev/null +++ b/src/bin/psql/po/ko.po @@ -0,0 +1,6545 @@ +# Korean message translation file for psql +# Ioseph Kim. , 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: psql (PostgreSQL) 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-10-12 22:13+0000\n" +"PO-Revision-Date: 2020-10-27 14:28+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "심각: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "오류: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "경고: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "현재 디렉터리가 무엇인지 모르겠음: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "잘못된 바이너리 파일: \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" 바이너리 파일을 읽을 수 없음" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "실행할 \"%s\" 파일 찾을 수 없음" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" 이름의 디렉터리로 이동할 수 없습니다: %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "\"%s\" 심볼릭 링크 파일을 읽을 수 없음: %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose 실패: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: command.c:1255 input.c:227 mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "메모리 부족" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null 포인터를 복제할 수 없음(내부 오류)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "UID %ld 해당하는 사용자를 찾을 수 없음: %s" + +#: ../../common/username.c:45 command.c:559 +msgid "user does not exist" +msgstr "사용자 없음" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "사용자 이름 찾기 실패: 오류번호 %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "명령을 실행할 수 없음" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "명령어를 찾을 수 없음" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "하위 프로세스가 %d 코드로 종료했음" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "0x%X 예외처리에 의해 하위 프로세스가 종료되었음" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "하위 프로세스가 %d 신호를 받고 종료되었음: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "하위 프로세스가 알 수 없는 상태(%d)로 종료되었음" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "취소 요청 보냄\n" + +#: ../../fe_utils/cancel.c:165 +msgid "Could not send cancel request: " +msgstr "취소 요청 보내기 실패: " + +#: ../../fe_utils/cancel.c:210 +#, c-format +msgid "Could not send cancel request: %s" +msgstr "취소 요청 보내기 실패: %s" + +#: ../../fe_utils/print.c:350 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu개 행)" + +#: ../../fe_utils/print.c:3055 +#, c-format +msgid "Interrupted\n" +msgstr "인트럽트발생\n" + +#: ../../fe_utils/print.c:3119 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "테이블 내용에 헤더를 추가할 수 없음: 열 수가 %d개를 초과했습니다.\n" + +#: ../../fe_utils/print.c:3159 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "테이블 내용에 셀을 추가할 수 없음: 총 셀 수가 %d개를 초과했습니다.\n" + +#: ../../fe_utils/print.c:3414 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "잘못된 출력 형식 (내부 오류): %d" + +#: ../../fe_utils/psqlscan.l:694 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "\"%s\" 변수의 재귀적 확장을 건너뛰는 중" + +#: command.c:224 +#, c-format +msgid "invalid command \\%s" +msgstr "잘못된 명령: \\%s" + +#: command.c:226 +#, c-format +msgid "Try \\? for help." +msgstr "도움말을 보려면 \\?를 입력하십시오." + +#: command.c:244 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: \"%s\" 추가 인자가 무시되었음" + +#: command.c:296 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "" +"\\%s 명령은 무시함; 현재 \\if 블록을 중지하려면, \\endif 명령이나 Ctrl-C 키" +"를 사용하세요." + +#: command.c:557 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "UID %ld 사용자의 홈 디렉터리를 찾을 수 없음: %s" + +#: command.c:575 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: \"%s\" 디렉터리로 이동할 수 없음: %m" + +#: command.c:600 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "현재 데이터베이스에 연결되어있지 않습니다.\n" + +#: command.c:613 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" on address \"%s\" at " +"port \"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 주소=\"%s\", 포트=\"%s\".\n" + +#: command.c:616 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at " +"port \"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 소켓=\"%s\", 포트=\"%s\".\n" + +#: command.c:622 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address " +"\"%s\") at port \"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 호스트=\"%s\" (주소=\"%s\"), 포" +"트=\"%s\".\n" + +#: command.c:625 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port " +"\"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 호스트=\"%s\", 포트=\"%s\".\n" + +#: command.c:965 command.c:1061 command.c:2550 +#, c-format +msgid "no query buffer" +msgstr "쿼리 버퍼가 없음" + +#: command.c:998 command.c:5061 +#, c-format +msgid "invalid line number: %s" +msgstr "잘못된 줄 번호: %s" + +#: command.c:1052 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "이 서버(%s 버전)는 함수 소스 편집 기능을 제공하지 않습니다." + +#: command.c:1055 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "이 서버(%s 버전)는 뷰 정의 편집 기능을 제공하지 않습니다." + +#: command.c:1137 +msgid "No changes" +msgstr "변경 내용 없음" + +#: command.c:1216 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: 잘못된 인코딩 이름 또는 문자셋 변환 프로시저 없음" + +#: command.c:1251 command.c:1992 command.c:3253 command.c:5163 common.c:174 +#: common.c:223 common.c:388 common.c:1237 common.c:1265 common.c:1373 +#: common.c:1480 common.c:1518 copy.c:488 copy.c:707 help.c:62 large_obj.c:157 +#: large_obj.c:192 large_obj.c:254 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1258 +msgid "There is no previous error." +msgstr "이전 오류가 없습니다." + +#: command.c:1371 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: 오른쪽 괄호 빠졌음" + +#: command.c:1548 command.c:1853 command.c:1867 command.c:1884 command.c:2044 +#: command.c:2281 command.c:2517 command.c:2557 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s: 필요한 인자가 빠졌음" + +#: command.c:1679 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: \\else 구문 뒤에 올 수 없음" + +#: command.c:1684 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif: \\if 명령과 짝이 안맞음" + +#: command.c:1748 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else: \\else 명령 뒤에 올 수 없음" + +#: command.c:1753 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else: \\if 명령과 짝이 안맞음" + +#: command.c:1793 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif: \\if 명령과 짝이 안맞음" + +#: command.c:1948 +msgid "Query buffer is empty." +msgstr "쿼리 버퍼가 비었음." + +#: command.c:1970 +msgid "Enter new password: " +msgstr "새 암호를 입력하세요:" + +#: command.c:1971 +msgid "Enter it again: " +msgstr "다시 입력해 주세요:" + +#: command.c:1975 +#, c-format +msgid "Passwords didn't match." +msgstr "암호가 서로 틀립니다." + +#: command.c:2074 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s: 변수 값을 읽을 수 없음" + +#: command.c:2177 +msgid "Query buffer reset (cleared)." +msgstr "쿼리 버퍼 초기화 (비웠음)." + +#: command.c:2199 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "명령내역(history)을 \"%s\" 파일에 기록했습니다.\n" + +#: command.c:2286 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: OS 환경 변수 이름에는 \"=\" 문자가 없어야 함" + +#: command.c:2347 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "이 서버(%s 버전)는 함수 소스 보기 기능을 제공하지 않습니다." + +#: command.c:2350 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "이 서버(%s 버전)는 뷰 정의 보기 기능을 제공하지 않습니다." + +#: command.c:2357 +#, c-format +msgid "function name is required" +msgstr "함수 이름이 필요함" + +#: command.c:2359 +#, c-format +msgid "view name is required" +msgstr "뷰 이름이 필요함" + +#: command.c:2489 +msgid "Timing is on." +msgstr "작업수행시간 보임" + +#: command.c:2491 +msgid "Timing is off." +msgstr "작업수행시간 숨김" + +#: command.c:2576 command.c:2604 command.c:3661 command.c:3664 command.c:3667 +#: command.c:3673 command.c:3675 command.c:3683 command.c:3693 command.c:3702 +#: command.c:3716 command.c:3733 command.c:3791 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:2988 startup.c:236 startup.c:287 +msgid "Password: " +msgstr "암호: " + +#: command.c:2993 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "%s 사용자의 암호: " + +#: command.c:3064 +#, c-format +msgid "" +"All connection parameters must be supplied because no database connection " +"exists" +msgstr "현재 접속 정보가 없습니다. 접속을 위한 연결 관련 매개변수를 지정하세요" + +#: command.c:3257 +#, c-format +msgid "Previous connection kept" +msgstr "이전 연결이 유지되었음" + +#: command.c:3261 +#, c-format +msgid "\\connect: %s" +msgstr "\\연결: %s" + +#: command.c:3310 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at " +"port \"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 주소=\"%s\", 포트=\"%s\".\n" + +#: command.c:3313 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " +"at port \"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 소켓=\"%s\", 포트=\"%s\".\n" + +#: command.c:3319 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" on host \"%s" +"\" (address \"%s\") at port \"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 호스트=\"%s\" (주소 \"%s\"), 포" +"트=\"%s\".\n" + +#: command.c:3322 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at " +"port \"%s\".\n" +msgstr "" +"접속정보: 데이터베이스=\"%s\", 사용자=\"%s\", 호스트=\"%s\", 포트=\"%s\".\n" + +#: command.c:3327 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "접속정보: 데이터베이스=\"%s\", 사용자=\"%s\".\n" + +#: command.c:3360 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s(%s, %s 서버)\n" + +#: command.c:3368 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"경고: %s 메이저 버전 %s, 서버 메이저 버전 %s.\n" +" 일부 psql 기능이 작동하지 않을 수도 있습니다.\n" + +#: command.c:3407 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL 연결정보 (프로토콜: %s, 암호화기법: %s, 비트: %s, 압축: %s)\n" + +#: command.c:3408 command.c:3409 command.c:3410 +msgid "unknown" +msgstr "알수없음" + +#: command.c:3411 help.c:45 +msgid "off" +msgstr "off" + +#: command.c:3411 help.c:45 +msgid "on" +msgstr "on" + +#: command.c:3425 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "암호화된 GSSAPI 연결\n" + +#: command.c:3445 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"경고: 콘솔 코드 페이지(%u)가 Windows 코드 페이지(%u)와 달라서\n" +" 8비트 문자가 올바르게 표시되지 않을 수 있습니다. 자세한 내용은 psql " +"참조\n" +" 페이지 \"Notes for Windows users\"를 참조하십시오.\n" + +#: command.c:3549 +#, c-format +msgid "" +"environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a " +"line number" +msgstr "" +"지정한 줄번호를 사용하기 위해서는 PSQL_EDITOR_LINENUMBER_ARG 이름의 OS 환경변" +"수가 설정되어 있어야 합니다." + +#: command.c:3578 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "\"%s\" 문서 편집기를 실행시킬 수 없음" + +#: command.c:3580 +#, c-format +msgid "could not start /bin/sh" +msgstr "/bin/sh 명령을 실행할 수 없음" + +#: command.c:3618 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "임시 디렉터리 경로를 알 수 없음: %s" + +#: command.c:3645 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "\"%s\" 임시 파일을 열 수 없음: %m" + +#: command.c:3950 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: \"%s\" 생략형이 \"%s\" 또는 \"%s\" 값 모두 선택가능해서 모호함" + +#: command.c:3970 +#, c-format +msgid "" +"\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-" +"longtable, troff-ms, unaligned, wrapped" +msgstr "" +"\\pset: 허용되는 출력 형식: aligned, asciidoc, csv, html, latex, latex-" +"longtable, troff-ms, unaligned, wrapped" + +#: command.c:3989 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: 사용할 수 있는 선 모양은 ascii, old-ascii, unicode" + +#: command.c:4004 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: 사용할 수 있는 유니코드 테두리 모양은 single, double" + +#: command.c:4019 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: 사용할 수 있는 유니코드 칼럼 선 모양은 single, double" + +#: command.c:4034 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: 사용할 수 있는 유니코드 헤더 선 모양은 single, double" + +#: command.c:4077 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep 문자는 1바이트의 단일 문자여야 함" + +#: command.c:4082 +#, c-format +msgid "" +"\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage " +"return" +msgstr "" +"\\pset: csv_fieldsep 문자로 따옴표, 줄바꿈(\\n, \\r) 문자는 사용할 수 없음" + +#: command.c:4219 command.c:4407 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset: 알 수 없는 옵션: %s" + +#: command.c:4239 +#, c-format +msgid "Border style is %d.\n" +msgstr "html 테이블의 테두리를 %d로 지정했습니다.\n" + +#: command.c:4245 +#, c-format +msgid "Target width is unset.\n" +msgstr "대상 너비 미지정.\n" + +#: command.c:4247 +#, c-format +msgid "Target width is %d.\n" +msgstr "대상 너비는 %d입니다.\n" + +#: command.c:4254 +#, c-format +msgid "Expanded display is on.\n" +msgstr "칼럼 단위 보기 기능 켬.\n" + +#: command.c:4256 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "칼럼 단위 보기 기능을 자동으로 지정 함.\n" + +#: command.c:4258 +#, c-format +msgid "Expanded display is off.\n" +msgstr "칼럼 단위 보기 기능 끔.\n" + +#: command.c:4264 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "CSV용 필드 구분자: \"%s\".\n" + +#: command.c:4272 command.c:4280 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "필드 구분자가 0 바이트입니다.\n" + +#: command.c:4274 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "필드 구분자 \"%s\".\n" + +#: command.c:4287 +#, c-format +msgid "Default footer is on.\n" +msgstr "기본 꼬릿말 보기 기능 켬.\n" + +#: command.c:4289 +#, c-format +msgid "Default footer is off.\n" +msgstr "기본 꼬릿말 보기 기능 끔.\n" + +#: command.c:4295 +#, c-format +msgid "Output format is %s.\n" +msgstr "현재 출력 형식: %s.\n" + +#: command.c:4301 +#, c-format +msgid "Line style is %s.\n" +msgstr "선 모양: %s.\n" + +#: command.c:4308 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Null 값은 \"%s\" 문자로 보여짐.\n" + +#: command.c:4316 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "로케일 맞춤 숫자 표기 기능 켬.\n" + +#: command.c:4318 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "로케일 맞춤 숫자 표기 기능 끔.\n" + +#: command.c:4325 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "긴 출력을 위해 페이저가 사용됨.\n" + +#: command.c:4327 +#, c-format +msgid "Pager is always used.\n" +msgstr "항상 페이저가 사용됨.\n" + +#: command.c:4329 +#, c-format +msgid "Pager usage is off.\n" +msgstr "화면단위 보기 기능 끔(전체 자료 모두 보여줌).\n" + +#: command.c:4335 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "%d 줄보다 적은 경우는 페이지 단위 보기가 사용되지 않음\n" + +#: command.c:4345 command.c:4355 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "레코드 구분자가 0 바이트임.\n" + +#: command.c:4347 +#, c-format +msgid "Record separator is .\n" +msgstr "레코드 구분자는 줄바꿈 문자입니다.\n" + +#: command.c:4349 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "레코드 구분자 \"%s\".\n" + +#: command.c:4362 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "테이블 속성: \"%s\".\n" + +#: command.c:4365 +#, c-format +msgid "Table attributes unset.\n" +msgstr "테이블 속성 모두 지움.\n" + +#: command.c:4372 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "출력 테이블의 제목: \"%s\"\n" + +#: command.c:4374 +#, c-format +msgid "Title is unset.\n" +msgstr "출력 테이블의 제목을 지정하지 않았습니다.\n" + +#: command.c:4381 +#, c-format +msgid "Tuples only is on.\n" +msgstr "자료만 보기 기능 켬.\n" + +#: command.c:4383 +#, c-format +msgid "Tuples only is off.\n" +msgstr "자료만 보기 기능 끔.\n" + +#: command.c:4389 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "유니코드 테두리 선문자: \"%s\".\n" + +#: command.c:4395 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "유니코드 칼럼 선문자: \"%s\".\n" + +#: command.c:4401 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "유니코드 헤더 선문자: \"%s\".\n" + +#: command.c:4634 +#, c-format +msgid "\\!: failed" +msgstr "\\!: 실패" + +#: command.c:4659 common.c:648 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch 명령으로 수행할 쿼리가 없습니다." + +#: command.c:4700 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (%g초 간격)\n" + +#: command.c:4703 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (%g초 간격)\n" + +#: command.c:4757 command.c:4764 common.c:548 common.c:555 common.c:1220 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********** 쿼리 **********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:4956 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "\"%s.%s\" 뷰(view)가 아님" + +#: command.c:4972 +#, c-format +msgid "could not parse reloptions array" +msgstr "reloptions 배열을 분석할 수 없음" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "현재 접속한 연결 없이는 특수문자처리를 할 수 없음" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "쉘 명령의 인자에 줄바꿈 문자가 있음: \"%s\"" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "서버 접속 끊김" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "서버로부터 연결이 끊어졌습니다. 다시 연결을 시도합니다: " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "실패.\n" + +#: common.c:326 +#, c-format +msgid "Succeeded.\n" +msgstr "성공.\n" + +#: common.c:378 common.c:938 common.c:1155 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "PQresultStatus 반환값이 잘못됨: %d" + +#: common.c:487 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "작업시간: %.3f ms\n" + +#: common.c:502 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "작업시간: %.3f ms (%02d:%06.3f)\n" + +#: common.c:511 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "작업시간: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:518 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "작업시간: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:542 common.c:600 common.c:1191 +#, c-format +msgid "You are currently not connected to a database." +msgstr "현재 데이터베이스에 연결되어있지 않습니다." + +#: common.c:655 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watch 작업으로 COPY 명령은 사용할 수 없음" + +#: common.c:660 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "\\watch 쿼리 결과가 비정상적입니다." + +#: common.c:690 +#, c-format +msgid "" +"Asynchronous notification \"%s\" with payload \"%s\" received from server " +"process with PID %d.\n" +msgstr "\"%s\" 비동기 통지를 받음, 부가정보: \"%s\", 보낸 프로세스: %d.\n" + +#: common.c:693 +#, c-format +msgid "" +"Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "동기화 신호 \"%s\" 받음, 해당 서버 프로세스 PID %d.\n" + +#: common.c:726 common.c:743 +#, c-format +msgid "could not print result table: %m" +msgstr "결과 테이블을 출력할 수 없음: %m" + +#: common.c:764 +#, c-format +msgid "no rows returned for \\gset" +msgstr "\\gset 해당 자료 없음" + +#: common.c:769 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "\\gset 실행 결과가 단일 자료가 아님" + +#: common.c:1200 +#, c-format +msgid "" +"***(Single step mode: verify " +"command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to " +"cancel)********************\n" +msgstr "" +"***(단독 순차 모드: 쿼리 확인)*********************************************\n" +"%s\n" +"***(Enter: 계속 진행, x Enter: 중지)********************\n" + +#: common.c:1255 +#, c-format +msgid "" +"The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "" +"서버(%s 버전)에서 ON_ERROR_ROLLBACK에 사용할 savepoint를 지원하지 않습니다." + +#: common.c:1318 +#, c-format +msgid "STATEMENT: %s" +msgstr "명령구문: %s" + +#: common.c:1361 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "알 수 없는 트랜잭션 상태 (%d)" + +#: common.c:1502 describe.c:2001 +msgid "Column" +msgstr "필드명" + +#: common.c:1503 describe.c:177 describe.c:393 describe.c:411 describe.c:456 +#: describe.c:473 describe.c:962 describe.c:1126 describe.c:1711 +#: describe.c:1735 describe.c:2002 describe.c:3729 describe.c:3939 +#: describe.c:4172 describe.c:5378 +msgid "Type" +msgstr "종류" + +#: common.c:1552 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "해당 명령 결과가 없거나, 그 결과에는 칼럼이 없습니다.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy: 인자가 필요함" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: 구문 오류: \"%s\"" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: 줄 끝에 구문 오류" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "\"%s\" 명령을 실행할 수 없음: %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" 파일의 상태값을 알 수 없음: %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s: 디렉터리부터 또는 디렉터리로 복사할 수 없음" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "외부 명령으로 파이프를 닫을 수 없음: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "COPY 자료를 기록할 수 없음: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "COPY 자료 변환 실패: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "사용자에 의해서 취소됨" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"한 줄에 한 레코드씩 데이터를 입력하고\n" +"자료입력이 끝나면 backslash 점 (\\.) 마지막 줄 처음에 입력하는 EOF 시그널을 " +"보내세요." + +#: copy.c:669 +msgid "aborted because of read failure" +msgstr "읽기 실패로 중지됨" + +#: copy.c:703 +msgid "trying to exit copy mode" +msgstr "복사 모드를 종료하는 중" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: 구문 결과가 집합을 반환하지 않았음" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: 쿼리 결과는 적어도 세 개의 칼럼은 반환 해야 함" + +#: crosstabview.c:156 +#, c-format +msgid "" +"\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: 행과 열의 칼럼이 각각 다른 칼럼이어야 함" + +#: crosstabview.c:172 +#, c-format +msgid "" +"\\crosstabview: data column must be specified when query returns more than " +"three columns" +msgstr "" +"\\crosstabview: 처리할 칼럼이 세개보다 많을 때는 자료로 사용할 칼럼을 지정해" +"야 함" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: 최대 칼럼 수 (%d) 초과" + +#: crosstabview.c:397 +#, c-format +msgid "" +"\\crosstabview: query result contains multiple data values for row \"%s\", " +"column \"%s\"" +msgstr "" +"\\crosstabview: \"%s\" 로우, \"%s\" 칼럼에 대해 쿼리 결과는 다중값이어야 함" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: %d 번째 열은 1..%d 범위를 벗어났음" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: 칼럼 이름이 모호함: \"%s\"" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: 칼럼 이름 없음: \"%s\"" + +#: describe.c:75 describe.c:373 describe.c:678 describe.c:810 describe.c:954 +#: describe.c:1115 describe.c:1187 describe.c:3718 describe.c:3926 +#: describe.c:4170 describe.c:4261 describe.c:4528 describe.c:4688 +#: describe.c:4929 describe.c:5004 describe.c:5015 describe.c:5077 +#: describe.c:5502 describe.c:5585 +msgid "Schema" +msgstr "스키마" + +#: describe.c:76 describe.c:174 describe.c:242 describe.c:250 describe.c:374 +#: describe.c:679 describe.c:811 describe.c:872 describe.c:955 describe.c:1188 +#: describe.c:3719 describe.c:3927 describe.c:4093 describe.c:4171 +#: describe.c:4262 describe.c:4341 describe.c:4529 describe.c:4613 +#: describe.c:4689 describe.c:4930 describe.c:5005 describe.c:5016 +#: describe.c:5078 describe.c:5275 describe.c:5359 describe.c:5583 +#: describe.c:5755 describe.c:5995 +msgid "Name" +msgstr "이름" + +#: describe.c:77 describe.c:386 describe.c:404 describe.c:450 describe.c:467 +msgid "Result data type" +msgstr "반환 자료형" + +#: describe.c:85 describe.c:98 describe.c:102 describe.c:387 describe.c:405 +#: describe.c:451 describe.c:468 +msgid "Argument data types" +msgstr "인자 자료형" + +#: describe.c:110 describe.c:117 describe.c:185 describe.c:273 describe.c:513 +#: describe.c:727 describe.c:826 describe.c:897 describe.c:1190 describe.c:2020 +#: describe.c:3506 describe.c:3779 describe.c:3973 describe.c:4124 +#: describe.c:4198 describe.c:4271 describe.c:4354 describe.c:4437 +#: describe.c:4556 describe.c:4622 describe.c:4690 describe.c:4831 +#: describe.c:4873 describe.c:4946 describe.c:5008 describe.c:5017 +#: describe.c:5079 describe.c:5301 describe.c:5381 describe.c:5516 +#: describe.c:5586 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "설명" + +#: describe.c:135 +msgid "List of aggregate functions" +msgstr "통계 함수 목록" + +#: describe.c:160 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "서버(%s 버전)에서 접근 방법을 지원하지 않습니다." + +#: describe.c:175 +msgid "Index" +msgstr "인덱스" + +#: describe.c:176 describe.c:3737 describe.c:3952 describe.c:5503 +msgid "Table" +msgstr "테이블" + +#: describe.c:184 describe.c:5280 +msgid "Handler" +msgstr "핸들러" + +#: describe.c:203 +msgid "List of access methods" +msgstr "접근 방법 목록" + +#: describe.c:229 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "서버(%s 버전)에서 테이블스페이스를 지원하지 않습니다." + +#: describe.c:243 describe.c:251 describe.c:501 describe.c:717 describe.c:873 +#: describe.c:1114 describe.c:3730 describe.c:3928 describe.c:4097 +#: describe.c:4343 describe.c:4614 describe.c:5276 describe.c:5360 +#: describe.c:5756 describe.c:5893 describe.c:5996 describe.c:6111 +#: describe.c:6190 large_obj.c:289 +msgid "Owner" +msgstr "소유주" + +#: describe.c:244 describe.c:252 +msgid "Location" +msgstr "위치" + +#: describe.c:263 describe.c:3323 +msgid "Options" +msgstr "옵션" + +#: describe.c:268 describe.c:690 describe.c:889 describe.c:3771 describe.c:3775 +msgid "Size" +msgstr "크기" + +#: describe.c:290 +msgid "List of tablespaces" +msgstr "테이블스페이스 목록" + +#: describe.c:333 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df 명령은 [anptwS+]만 추가로 사용함" + +#: describe.c:341 describe.c:352 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df 명령은 \"%c\" 옵션을 %s 버전 서버에서는 사용할 수 없음" + +#. translator: "agg" is short for "aggregate" +#: describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "agg" +msgstr "집계" + +#: describe.c:390 describe.c:408 +msgid "window" +msgstr "창" + +#: describe.c:391 +msgid "proc" +msgstr "" + +#: describe.c:392 describe.c:410 describe.c:455 describe.c:472 +msgid "func" +msgstr "함수" + +#: describe.c:409 describe.c:454 describe.c:471 describe.c:1324 +msgid "trigger" +msgstr "트리거" + +#: describe.c:483 +msgid "immutable" +msgstr "immutable" + +#: describe.c:484 +msgid "stable" +msgstr "stable" + +#: describe.c:485 +msgid "volatile" +msgstr "volatile" + +#: describe.c:486 +msgid "Volatility" +msgstr "휘발성" + +#: describe.c:494 +msgid "restricted" +msgstr "엄격함" + +#: describe.c:495 +msgid "safe" +msgstr "safe" + +#: describe.c:496 +msgid "unsafe" +msgstr "unsafe" + +#: describe.c:497 +msgid "Parallel" +msgstr "병렬처리" + +#: describe.c:502 +msgid "definer" +msgstr "definer" + +#: describe.c:503 +msgid "invoker" +msgstr "invoker" + +#: describe.c:504 +msgid "Security" +msgstr "보안" + +#: describe.c:511 +msgid "Language" +msgstr "언어" + +#: describe.c:512 +msgid "Source code" +msgstr "소스 코드" + +#: describe.c:641 +msgid "List of functions" +msgstr "함수 목록" + +#: describe.c:689 +msgid "Internal name" +msgstr "내부 이름" + +#: describe.c:711 +msgid "Elements" +msgstr "요소" + +#: describe.c:768 +msgid "List of data types" +msgstr "자료형 목록" + +#: describe.c:812 +msgid "Left arg type" +msgstr "왼쪽 인수 자료형" + +#: describe.c:813 +msgid "Right arg type" +msgstr "오른쪽 인수 자료형" + +#: describe.c:814 +msgid "Result type" +msgstr "반환 자료형" + +#: describe.c:819 describe.c:4349 describe.c:4414 describe.c:4420 +#: describe.c:4830 describe.c:6362 describe.c:6366 +msgid "Function" +msgstr "함수" + +#: describe.c:844 +msgid "List of operators" +msgstr "연산자 목록" + +#: describe.c:874 +msgid "Encoding" +msgstr "인코딩" + +#: describe.c:879 describe.c:4530 +msgid "Collate" +msgstr "Collate" + +#: describe.c:880 describe.c:4531 +msgid "Ctype" +msgstr "Ctype" + +#: describe.c:893 +msgid "Tablespace" +msgstr "테이블스페이스" + +#: describe.c:915 +msgid "List of databases" +msgstr "데이터베이스 목록" + +#: describe.c:956 describe.c:1117 describe.c:3720 +msgid "table" +msgstr "테이블" + +#: describe.c:957 describe.c:3721 +msgid "view" +msgstr "뷰(view)" + +#: describe.c:958 describe.c:3722 +msgid "materialized view" +msgstr "구체화된 뷰" + +#: describe.c:959 describe.c:1119 describe.c:3724 +msgid "sequence" +msgstr "시퀀스" + +#: describe.c:960 describe.c:3726 +msgid "foreign table" +msgstr "외부 테이블" + +#: describe.c:961 describe.c:3727 describe.c:3937 +msgid "partitioned table" +msgstr "파티션 테이블" + +#: describe.c:973 +msgid "Column privileges" +msgstr "칼럼 접근권한" + +#: describe.c:1004 describe.c:1038 +msgid "Policies" +msgstr "정책" + +#: describe.c:1070 describe.c:6052 describe.c:6056 +msgid "Access privileges" +msgstr "액세스 권한" + +#: describe.c:1101 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "이 서버(%s 버전)는 ALTER DEFAULT PRIVILEGES 기능을 지원하지 않습니다." + +#: describe.c:1121 +msgid "function" +msgstr "함수" + +#: describe.c:1123 +msgid "type" +msgstr "type" + +#: describe.c:1125 +msgid "schema" +msgstr "스키마" + +#: describe.c:1149 +msgid "Default access privileges" +msgstr "기본 접근권한" + +#: describe.c:1189 +msgid "Object" +msgstr "개체" + +#: describe.c:1203 +msgid "table constraint" +msgstr "테이블 제약 조건" + +#: describe.c:1225 +msgid "domain constraint" +msgstr "도메인 제약조건" + +#: describe.c:1253 +msgid "operator class" +msgstr "연산자 클래스" + +#: describe.c:1282 +msgid "operator family" +msgstr "연산자 부류" + +#: describe.c:1304 +msgid "rule" +msgstr "룰(rule)" + +#: describe.c:1346 +msgid "Object descriptions" +msgstr "개체 설명" + +#: describe.c:1402 describe.c:3843 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "\"%s\" 이름을 릴레이션(relation) 없음." + +#: describe.c:1405 describe.c:3846 +#, c-format +msgid "Did not find any relations." +msgstr "관련 릴레이션 찾을 수 없음." + +#: describe.c:1660 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "%s oid의 어떤 릴레이션(relation)도 찾을 수 없음." + +#: describe.c:1712 describe.c:1736 +msgid "Start" +msgstr "시작" + +#: describe.c:1713 describe.c:1737 +msgid "Minimum" +msgstr "최소값" + +#: describe.c:1714 describe.c:1738 +msgid "Maximum" +msgstr "최대값" + +#: describe.c:1715 describe.c:1739 +msgid "Increment" +msgstr "증가값" + +#: describe.c:1716 describe.c:1740 describe.c:1871 describe.c:4265 +#: describe.c:4431 describe.c:4545 describe.c:4550 describe.c:6099 +msgid "yes" +msgstr "예" + +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4265 +#: describe.c:4428 describe.c:4545 describe.c:6100 +msgid "no" +msgstr "아니오" + +#: describe.c:1718 describe.c:1742 +msgid "Cycles?" +msgstr "순환?" + +#: describe.c:1719 describe.c:1743 +msgid "Cache" +msgstr "캐쉬" + +#: describe.c:1786 +#, c-format +msgid "Owned by: %s" +msgstr "소유주: %s" + +#: describe.c:1790 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "식별 칼럼용 시퀀스: %s" + +#: describe.c:1797 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "\"%s.%s\" 시퀀스" + +#: describe.c:1933 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "로그 미사용 테이블 \"%s.%s\"" + +#: describe.c:1936 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "\"%s.%s\" 테이블" + +#: describe.c:1940 +#, c-format +msgid "View \"%s.%s\"" +msgstr "\"%s.%s\" 뷰(view)" + +#: describe.c:1945 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "트랜잭션 로그를 남기지 않은 구체화된 뷰 \"%s.%s\"" + +#: describe.c:1948 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Materialized 뷰 \"%s.%s\"" + +#: describe.c:1953 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "\"%s.%s\" 로그 미사용 인덱스" + +#: describe.c:1956 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "\"%s.%s\" 인덱스" + +#: describe.c:1961 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "\"%s.%s\" 로그 미사용 파티션 인덱스" + +#: describe.c:1964 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "\"%s.%s\" 파티션 인덱스" + +#: describe.c:1969 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "\"%s.%s\" 특수 릴레이션(relation)" + +#: describe.c:1973 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "\"%s.%s\" TOAST 테이블" + +#: describe.c:1977 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "\"%s.%s\" 복합자료형" + +#: describe.c:1981 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "\"%s.%s\" 외부 테이블" + +#: describe.c:1986 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "로그 미사용 파티션 테이블 \"%s.%s\"" + +#: describe.c:1989 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "\"%s.%s\" 파티션 테이블" + +#: describe.c:2005 describe.c:4178 +msgid "Collation" +msgstr "Collation" + +#: describe.c:2006 describe.c:4185 +msgid "Nullable" +msgstr "NULL허용" + +#: describe.c:2007 describe.c:4186 +msgid "Default" +msgstr "초기값" + +#: describe.c:2010 +msgid "Key?" +msgstr "" + +#: describe.c:2012 +msgid "Definition" +msgstr "정의" + +#: describe.c:2014 describe.c:5296 describe.c:5380 describe.c:5451 +#: describe.c:5515 +msgid "FDW options" +msgstr "FDW 옵션" + +#: describe.c:2016 +msgid "Storage" +msgstr "스토리지" + +#: describe.c:2018 +msgid "Stats target" +msgstr "통계수집량" + +#: describe.c:2131 +#, c-format +msgid "Partition of: %s %s" +msgstr "소속 파티션: %s %s" + +#: describe.c:2143 +msgid "No partition constraint" +msgstr "파티션 제약 조건 없음" + +#: describe.c:2145 +#, c-format +msgid "Partition constraint: %s" +msgstr "파티션 제약조건: %s" + +#: describe.c:2169 +#, c-format +msgid "Partition key: %s" +msgstr "파티션 키: %s" + +#: describe.c:2195 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "소속 테이블: \"%s.%s\"" + +#: describe.c:2266 +msgid "primary key, " +msgstr "기본키, " + +#: describe.c:2268 +msgid "unique, " +msgstr "고유, " + +#: describe.c:2274 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "적용테이블: \"%s.%s\"" + +#: describe.c:2278 +#, c-format +msgid ", predicate (%s)" +msgstr ", predicate (%s)" + +#: describe.c:2281 +msgid ", clustered" +msgstr ", 클러스됨" + +#: describe.c:2284 +msgid ", invalid" +msgstr ", 잘못됨" + +#: describe.c:2287 +msgid ", deferrable" +msgstr ", 지연가능" + +#: describe.c:2290 +msgid ", initially deferred" +msgstr ", 트랜잭션단위지연" + +#: describe.c:2293 +msgid ", replica identity" +msgstr ", 복제 식별자" + +#: describe.c:2360 +msgid "Indexes:" +msgstr "인덱스들:" + +#: describe.c:2444 +msgid "Check constraints:" +msgstr "체크 제약 조건:" + +#: describe.c:2512 +msgid "Foreign-key constraints:" +msgstr "참조키 제약 조건:" + +#: describe.c:2575 +msgid "Referenced by:" +msgstr "다음에서 참조됨:" + +#: describe.c:2625 +msgid "Policies:" +msgstr "정책:" + +#: describe.c:2628 +msgid "Policies (forced row security enabled):" +msgstr "정책 (로우단위 보안정책 강제 활성화):" + +#: describe.c:2631 +msgid "Policies (row security enabled): (none)" +msgstr "정책 (로우단위 보안정책 활성화): (없음)" + +#: describe.c:2634 +msgid "Policies (forced row security enabled): (none)" +msgstr "정책 (로우단위 보안정책 강제 활성화): (없음)" + +#: describe.c:2637 +msgid "Policies (row security disabled):" +msgstr "정책 (로우단위 보안정책 비활성화):" + +#: describe.c:2705 +msgid "Statistics objects:" +msgstr "통계정보 객체:" + +#: describe.c:2819 describe.c:2923 +msgid "Rules:" +msgstr "룰(rule)들:" + +#: describe.c:2822 +msgid "Disabled rules:" +msgstr "사용중지된 규칙:" + +#: describe.c:2825 +msgid "Rules firing always:" +msgstr "항상 발생하는 규칙:" + +#: describe.c:2828 +msgid "Rules firing on replica only:" +msgstr "복제본에서만 발생하는 규칙:" + +#: describe.c:2868 +msgid "Publications:" +msgstr "발행자:" + +#: describe.c:2906 +msgid "View definition:" +msgstr "뷰 정의:" + +#: describe.c:3053 +msgid "Triggers:" +msgstr "트리거들:" + +#: describe.c:3057 +msgid "Disabled user triggers:" +msgstr "사용중지된 사용자 트리거:" + +#: describe.c:3059 +msgid "Disabled triggers:" +msgstr "사용중지된 트리거:" + +#: describe.c:3062 +msgid "Disabled internal triggers:" +msgstr "사용중지된 내부 트리거:" + +#: describe.c:3065 +msgid "Triggers firing always:" +msgstr "항상 발생하는 트리거:" + +#: describe.c:3068 +msgid "Triggers firing on replica only:" +msgstr "복제본에서만 발생하는 트리거:" + +#: describe.c:3140 +#, c-format +msgid "Server: %s" +msgstr "서버: %s" + +#: describe.c:3148 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW 옵션들: (%s)" + +#: describe.c:3169 +msgid "Inherits" +msgstr "상속" + +#: describe.c:3229 +#, c-format +msgid "Number of partitions: %d" +msgstr "파티션 테이블 수: %d" + +#: describe.c:3238 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "파티션 테이블 수: %d (\\d+ 명령으로 볼 수 있음)" + +#: describe.c:3240 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "하위 테이블 수: %d (\\d+ 명령으로 볼 수 있음)" + +#: describe.c:3247 +msgid "Child tables" +msgstr "하위 테이블" + +#: describe.c:3247 +msgid "Partitions" +msgstr "파티션들" + +#: describe.c:3276 +#, c-format +msgid "Typed table of type: %s" +msgstr "자료형의 typed 테이블: %s" + +#: describe.c:3292 +msgid "Replica Identity" +msgstr "복제 식별자" + +#: describe.c:3305 +msgid "Has OIDs: yes" +msgstr "OID 사용: yes" + +#: describe.c:3314 +#, c-format +msgid "Access method: %s" +msgstr "접근 방법: %s" + +#: describe.c:3394 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "테이블스페이스: \"%s\"" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3406 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", \"%s\" 테이블스페이스" + +#: describe.c:3499 +msgid "List of roles" +msgstr "롤 목록" + +#: describe.c:3501 +msgid "Role name" +msgstr "롤 이름" + +#: describe.c:3502 +msgid "Attributes" +msgstr "속성" + +#: describe.c:3503 +msgid "Member of" +msgstr "소속 그룹:" + +#: describe.c:3514 +msgid "Superuser" +msgstr "슈퍼유저" + +#: describe.c:3517 +msgid "No inheritance" +msgstr "상속 없음" + +#: describe.c:3520 +msgid "Create role" +msgstr "롤 만들기" + +#: describe.c:3523 +msgid "Create DB" +msgstr "DB 만들기" + +#: describe.c:3526 +msgid "Cannot login" +msgstr "로그인할 수 없음" + +#: describe.c:3530 +msgid "Replication" +msgstr "복제" + +#: describe.c:3534 +msgid "Bypass RLS" +msgstr "RLS 통과" + +#: describe.c:3543 +msgid "No connections" +msgstr "연결 없음" + +#: describe.c:3545 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d개 연결" + +#: describe.c:3555 +msgid "Password valid until " +msgstr "비밀번호 만료기한: " + +#: describe.c:3605 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "이 서버(%s 버전)는 데이터베이스 개별 롤 설정을 지원하지 않습니다." + +#: describe.c:3618 +msgid "Role" +msgstr "롤" + +#: describe.c:3619 +msgid "Database" +msgstr "데이터베이스" + +#: describe.c:3620 +msgid "Settings" +msgstr "설정" + +#: describe.c:3641 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "\"%s\" 롤과 \"%s\" 데이터베이스에 대한 특정 설정이 없습니다." + +#: describe.c:3644 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "\"%s\" 롤용 특정 설정이 없음." + +#: describe.c:3647 +#, c-format +msgid "Did not find any settings." +msgstr "추가 설정 없음." + +#: describe.c:3652 +msgid "List of settings" +msgstr "설정 목록" + +#: describe.c:3723 +msgid "index" +msgstr "인덱스" + +#: describe.c:3725 +msgid "special" +msgstr "특수" + +#: describe.c:3728 describe.c:3938 +msgid "partitioned index" +msgstr "파티션_인덱스" + +#: describe.c:3752 +msgid "permanent" +msgstr "" + +#: describe.c:3753 +msgid "temporary" +msgstr "" + +#: describe.c:3754 +msgid "unlogged" +msgstr "" + +#: describe.c:3755 +msgid "Persistence" +msgstr "" + +#: describe.c:3851 +msgid "List of relations" +msgstr "릴레이션(relation) 목록" + +#: describe.c:3899 +#, c-format +msgid "" +"The server (version %s) does not support declarative table partitioning." +msgstr "이 서버(%s 버전)는 파티션 테이블 기능을 지원하지 않습니다." + +#: describe.c:3910 +msgid "List of partitioned indexes" +msgstr "파티션 인덱스 목록" + +#: describe.c:3912 +msgid "List of partitioned tables" +msgstr "파티션 테이블 목록" + +#: describe.c:3916 +msgid "List of partitioned relations" +msgstr "파티션 릴레이션(relation) 목록" + +#: describe.c:3947 +msgid "Parent name" +msgstr "상위 이름" + +#: describe.c:3960 +msgid "Leaf partition size" +msgstr "하위 파티션 크기" + +#: describe.c:3963 describe.c:3969 +msgid "Total size" +msgstr "전체 크기" + +#: describe.c:4101 +msgid "Trusted" +msgstr "신뢰됨" + +#: describe.c:4109 +msgid "Internal language" +msgstr "내부 언어" + +#: describe.c:4110 +msgid "Call handler" +msgstr "호출 핸들러" + +#: describe.c:4111 describe.c:5283 +msgid "Validator" +msgstr "유효성 검사기" + +#: describe.c:4114 +msgid "Inline handler" +msgstr "인라인 핸들러" + +#: describe.c:4142 +msgid "List of languages" +msgstr "언어 목록" + +#: describe.c:4187 +msgid "Check" +msgstr "체크" + +#: describe.c:4229 +msgid "List of domains" +msgstr "도메인(domain) 목록" + +#: describe.c:4263 +msgid "Source" +msgstr "소스" + +#: describe.c:4264 +msgid "Destination" +msgstr "설명" + +#: describe.c:4266 describe.c:6101 +msgid "Default?" +msgstr "초기값?" + +#: describe.c:4303 +msgid "List of conversions" +msgstr "문자코드변환규칙(conversion) 목록" + +#: describe.c:4342 +msgid "Event" +msgstr "이벤트" + +#: describe.c:4344 +msgid "enabled" +msgstr "활성화" + +#: describe.c:4345 +msgid "replica" +msgstr "replica" + +#: describe.c:4346 +msgid "always" +msgstr "항상" + +#: describe.c:4347 +msgid "disabled" +msgstr "비활성화" + +#: describe.c:4348 describe.c:5997 +msgid "Enabled" +msgstr "활성화" + +#: describe.c:4350 +msgid "Tags" +msgstr "태그" + +#: describe.c:4369 +msgid "List of event triggers" +msgstr "이벤트 트리거 목록" + +#: describe.c:4398 +msgid "Source type" +msgstr "Source 자료형" + +#: describe.c:4399 +msgid "Target type" +msgstr "Target 자료형" + +#: describe.c:4430 +msgid "in assignment" +msgstr "in assignment" + +#: describe.c:4432 +msgid "Implicit?" +msgstr "Implicit?" + +#: describe.c:4487 +msgid "List of casts" +msgstr "형변환자 목록" + +#: describe.c:4515 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "이 서버(%s 버전)는 문자 정렬(collation) 기능을 지원하지 않습니다." + +#: describe.c:4536 describe.c:4540 +msgid "Provider" +msgstr "제공자" + +#: describe.c:4546 describe.c:4551 +msgid "Deterministic?" +msgstr "" + +#: describe.c:4586 +msgid "List of collations" +msgstr "문자 정렬 목록" + +#: describe.c:4645 +msgid "List of schemas" +msgstr "스키마(schema) 목록" + +#: describe.c:4670 describe.c:4917 describe.c:4988 describe.c:5059 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "이 서버(%s 버전)에서 전문 검색을 지원하지 않습니다." + +#: describe.c:4705 +msgid "List of text search parsers" +msgstr "텍스트 검색 파서 목록" + +#: describe.c:4750 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "\"%s\"(이)라는 전문 검색 분석기를 찾지 못했습니다." + +#: describe.c:4753 +#, c-format +msgid "Did not find any text search parsers." +msgstr "특정 전문 검색 분석기를 찾지 못했습니다." + +#: describe.c:4828 +msgid "Start parse" +msgstr "구문 분석 시작" + +#: describe.c:4829 +msgid "Method" +msgstr "방법" + +#: describe.c:4833 +msgid "Get next token" +msgstr "다음 토큰 가져오기" + +#: describe.c:4835 +msgid "End parse" +msgstr "구문 분석 종료" + +#: describe.c:4837 +msgid "Get headline" +msgstr "헤드라인 가져오기" + +#: describe.c:4839 +msgid "Get token types" +msgstr "토큰 형식 가져오기" + +#: describe.c:4850 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "\"%s.%s\" 텍스트 검색 파서" + +#: describe.c:4853 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "\"%s\" 텍스트 검색 파서" + +#: describe.c:4872 +msgid "Token name" +msgstr "토큰 이름" + +#: describe.c:4883 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "\"%s.%s\" 파서의 토큰 형식" + +#: describe.c:4886 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "\"%s\" 파서의 토큰 형식" + +#: describe.c:4940 +msgid "Template" +msgstr "템플릿" + +#: describe.c:4941 +msgid "Init options" +msgstr "초기화 옵션" + +#: describe.c:4963 +msgid "List of text search dictionaries" +msgstr "텍스트 검색 사전 목록" + +#: describe.c:5006 +msgid "Init" +msgstr "초기화" + +#: describe.c:5007 +msgid "Lexize" +msgstr "Lexize" + +#: describe.c:5034 +msgid "List of text search templates" +msgstr "텍스트 검색 템플릿 목록" + +#: describe.c:5094 +msgid "List of text search configurations" +msgstr "텍스트 검색 구성 목록" + +#: describe.c:5140 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "\"%s\"(이)라는 텍스트 검색 구성을 찾지 못했습니다." + +#: describe.c:5143 +#, c-format +msgid "Did not find any text search configurations." +msgstr "특정 텍스트 검색 구성을 찾지 못했습니다." + +#: describe.c:5209 +msgid "Token" +msgstr "토큰" + +#: describe.c:5210 +msgid "Dictionaries" +msgstr "사전" + +#: describe.c:5221 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "텍스트 검색 구성 \"%s.%s\"" + +#: describe.c:5224 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "텍스트 검색 구성 \"%s\"" + +#: describe.c:5228 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"파서: \"%s.%s\"" + +#: describe.c:5231 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"파서: \"%s\"" + +#: describe.c:5265 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "이 서버(%s 버전)에서 외부 데이터 래퍼를 지원하지 않습니다." + +#: describe.c:5323 +msgid "List of foreign-data wrappers" +msgstr "외부 데이터 래퍼 목록" + +#: describe.c:5348 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "이 서버(%s 버전)에서 외부 서버를 지원하지 않습니다." + +#: describe.c:5361 +msgid "Foreign-data wrapper" +msgstr "외부 데이터 래퍼" + +#: describe.c:5379 describe.c:5584 +msgid "Version" +msgstr "버전" + +#: describe.c:5405 +msgid "List of foreign servers" +msgstr "외부 서버 목록" + +#: describe.c:5430 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "이 서버(%s 버전)에서 사용자 매핑을 지원하지 않습니다." + +#: describe.c:5440 describe.c:5504 +msgid "Server" +msgstr "서버" + +#: describe.c:5441 +msgid "User name" +msgstr "사용자 이름" + +#: describe.c:5466 +msgid "List of user mappings" +msgstr "사용자 매핑 목록" + +#: describe.c:5491 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "이 서버(%s 버전)에서 외부 테이블을 지원하지 않습니다." + +#: describe.c:5544 +msgid "List of foreign tables" +msgstr "외부 테이블 목록" + +#: describe.c:5569 describe.c:5626 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "이 서버(%s 버전)에서 확장기능을 지원하지 않습니다." + +#: describe.c:5601 +msgid "List of installed extensions" +msgstr "설치된 확장기능 목록" + +#: describe.c:5654 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "\"%s\" 이름의 확장 기능 모듈을 찾을 수 없습니다." + +#: describe.c:5657 +#, c-format +msgid "Did not find any extensions." +msgstr "추가할 확장 기능 모듈이 없음." + +#: describe.c:5701 +msgid "Object description" +msgstr "개체 설명" + +#: describe.c:5711 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "\"%s\" 확장 기능 안에 포함된 객체들" + +#: describe.c:5740 describe.c:5816 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "이 서버(%s 버전)는 논리 복제 발행 기능을 지원하지 않습니다." + +#: describe.c:5757 describe.c:5894 +msgid "All tables" +msgstr "모든 테이블" + +#: describe.c:5758 describe.c:5895 +msgid "Inserts" +msgstr "Inserts" + +#: describe.c:5759 describe.c:5896 +msgid "Updates" +msgstr "Updates" + +#: describe.c:5760 describe.c:5897 +msgid "Deletes" +msgstr "Deletes" + +#: describe.c:5764 describe.c:5899 +msgid "Truncates" +msgstr "" + +#: describe.c:5768 describe.c:5901 +msgid "Via root" +msgstr "" + +#: describe.c:5785 +msgid "List of publications" +msgstr "발행 목록" + +#: describe.c:5858 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "\"%s\" 이름의 발행 없음." + +#: describe.c:5861 +#, c-format +msgid "Did not find any publications." +msgstr "발행 없음." + +#: describe.c:5890 +#, c-format +msgid "Publication %s" +msgstr "%s 발행" + +#: describe.c:5938 +msgid "Tables:" +msgstr "테이블" + +#: describe.c:5982 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "이 서버(%s 버전)는 구독 기능을 지원하지 않습니다." + +#: describe.c:5998 +msgid "Publication" +msgstr "발행" + +#: describe.c:6005 +msgid "Synchronous commit" +msgstr "동기식 커밋" + +#: describe.c:6006 +msgid "Conninfo" +msgstr "연결정보" + +#: describe.c:6028 +msgid "List of subscriptions" +msgstr "구독 목록" + +#: describe.c:6095 describe.c:6184 describe.c:6270 describe.c:6353 +msgid "AM" +msgstr "" + +#: describe.c:6096 +msgid "Input type" +msgstr "입력 자료형" + +#: describe.c:6097 +msgid "Storage type" +msgstr "스토리지 유형" + +#: describe.c:6098 +msgid "Operator class" +msgstr "연산자 클래스" + +#: describe.c:6110 describe.c:6185 describe.c:6271 describe.c:6354 +msgid "Operator family" +msgstr "연산자 부류" + +#: describe.c:6143 +msgid "List of operator classes" +msgstr "연산자 클래스 목록" + +#: describe.c:6186 +msgid "Applicable types" +msgstr "" + +#: describe.c:6225 +msgid "List of operator families" +msgstr "연산자 부류 목록" + +#: describe.c:6272 +msgid "Operator" +msgstr "연산자" + +#: describe.c:6273 +msgid "Strategy" +msgstr "전략번호" + +#: describe.c:6274 +msgid "ordering" +msgstr "" + +#: describe.c:6275 +msgid "search" +msgstr "" + +#: describe.c:6276 +msgid "Purpose" +msgstr "" + +#: describe.c:6281 +msgid "Sort opfamily" +msgstr "정렬 연산자 부류" + +#: describe.c:6312 +msgid "List of operators of operator families" +msgstr "연산자 부류 소속 연산자 목록" + +#: describe.c:6355 +msgid "Registered left type" +msgstr "등록된 왼쪽 자료형" + +#: describe.c:6356 +msgid "Registered right type" +msgstr "등록된 오른쪽 자료형" + +#: describe.c:6357 +msgid "Number" +msgstr "" + +#: describe.c:6393 +msgid "List of support functions of operator families" +msgstr "연산자 부류 소속 지원 함수 목록" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql은 PostgreSQL 대화식 터미널입니다.\n" +"\n" + +#: help.c:74 help.c:355 help.c:431 help.c:474 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "일반 옵션:\n" + +#: help.c:82 +#, c-format +msgid "" +" -c, --command=COMMAND run only single command (SQL or internal) and " +"exit\n" +msgstr "" +" -c, --command=COMMAND 하나의 명령(SQL 또는 내부 명령)만 실행하고 끝냄\n" + +#: help.c:83 +#, c-format +msgid "" +" -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr " -d, --dbname=DBNAME 연결할 데이터베이스 이름(기본 값: \"%s\")\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=FILENAME 파일 안에 지정한 명령을 실행하고 끝냄\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr "" +" -l, --list 사용 가능한 데이터베이스 목록을 표시하고 끝냄\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=NAME=VALUE\n" +" psql 변수 NAME을 VALUE로 설정\n" +" (예, -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc 시작 파일(~/.psqlrc)을 읽지 않음\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-" +"interactive)\n" +msgstr "" +" -1 (\"one\"), --single-transaction\n" +" 명령 파일을 하나의 트랜잭션으로 실행\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] 이 도움말을 표시하고 종료\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr "" +" --help=commands psql 내장명령어(\\문자로 시작하는)를 표시하고 종" +"료\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables 특별 변수들 보여주고, 종료\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"입출력 옵션:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all 스크립트의 모든 입력 표시\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors 실패한 명령들 출력\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, --echo-queries 서버로 보낸 명령 표시\n" + +#: help.c:101 +#, c-format +msgid "" +" -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden 내부 명령이 생성하는 쿼리 표시\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, --log-file=FILENAME 세션 로그를 파일로 보냄\n" + +#: help.c:103 +#, c-format +msgid "" +" -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr "" +" -n, --no-readline 확장된 명령행 편집 기능을 사용중지함(readline)\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, --output=FILENAME 쿼리 결과를 파일(또는 |파이프)로 보냄\n" + +#: help.c:105 +#, c-format +msgid "" +" -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, --quiet 자동 실행(메시지 없이 쿼리 결과만 표시)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, --single-step 단독 순차 모드(각 쿼리 확인)\n" + +#: help.c:107 +#, c-format +msgid "" +" -S, --single-line single-line mode (end of line terminates SQL " +"command)\n" +msgstr " -S, --single-line 한 줄 모드(줄 끝에서 SQL 명령이 종료됨)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"출력 형식 옵션:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align 정렬되지 않은 표 형태의 출력 모드\n" + +#: help.c:111 +#, c-format +msgid "" +" --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv CSV (쉼표-분리 자료) 테이블 출력 모드\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: " +"\"%s\")\n" +msgstr "" +" -F, --field-separator=STRING\n" +" unaligned 출력용 필드 구분자 설정(기본 값: \"%s" +"\")\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html HTML 표 형태 출력 모드\n" + +#: help.c:116 +#, c-format +msgid "" +" -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset " +"command)\n" +msgstr "" +" -P, --pset=VAR[=ARG] 인쇄 옵션 VAR을 ARG로 설정(\\pset 명령 참조)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: " +"newline)\n" +msgstr "" +" -R, --record-separator=STRING\n" +" unaligned 출력용 레코드 구분자 설정\n" +" (기본 값: 줄바꿈 문자)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only 행만 인쇄\n" + +#: help.c:120 +#, c-format +msgid "" +" -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, " +"border)\n" +msgstr "" +" -T, --table-attr=TEXT HTML table 태그 속성 설정(예: width, border)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded 확장된 표 형태로 출력\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero " +"byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" unaligned 출력용 필드 구분자를 0 바이트로 지정\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero " +"byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" unaligned 출력용 레코드 구분자를 0 바이트로 지정\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"연결 옵션들:\n" + +#: help.c:130 +#, c-format +msgid "" +" -h, --host=HOSTNAME database server host or socket directory " +"(default: \"%s\")\n" +msgstr "" +" -h, --host=HOSTNAME 데이터베이스 서버 호스트 또는 소켓 디렉터리\n" +" (기본값: \"%s\")\n" + +#: help.c:131 +msgid "local socket" +msgstr "로컬 소켓" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, --port=PORT 데이터베이스 서버 포트(기본 값: \"%s\")\n" + +#: help.c:140 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, --username=USERNAME 데이터베이스 사용자 이름(기본 값: \"%s\")\n" + +#: help.c:141 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password 암호 프롬프트 표시 안 함\n" + +#: help.c:142 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr " -W, --password 암호 입력 프롬프트 보임(자동으로 처리함)\n" + +#: help.c:144 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help" +"\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"자세한 내용을 보려면 psql 내에서 \"\\?\"(내부 명령) 또는 \"\\help\"(SQL\n" +"명령)를 입력하거나 PostgreSQL\n" +"설명서에서 psql 섹션을 참조하십시오.\n" +"\n" + +#: help.c:147 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "문제점 보고 주소: <%s>\n" + +#: help.c:148 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "%s 홈페이지: <%s>\n" + +#: help.c:174 +#, c-format +msgid "General\n" +msgstr "일반\n" + +#: help.c:175 +#, c-format +msgid "" +" \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright PostgreSQL 사용법 및 저작권 정보 표시\n" + +#: help.c:176 +#, c-format +msgid "" +" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr "" +" \\crosstabview [칼럼들] 쿼리를 실행하고, 피봇 테이블 형태로 자료를 보여줌\n" + +#: help.c:177 +#, c-format +msgid "" +" \\errverbose show most recent error message at maximum " +"verbosity\n" +msgstr "" +" \\errverbose 최대 자세히 보기 상태에서 최근 오류를 다 보여줌\n" + +#: help.c:178 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |" +"pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(OPTIONS)] [FILE] 쿼리 실행 (결과는 지정한 파일로, 또는 | 파이프로);\n" +" \\g 명령에서 인자가 없으면 세미콜론과 같음\n" + +#: help.c:180 +#, c-format +msgid "" +" \\gdesc describe result of query, without executing it\n" +msgstr "" +" \\gdesc 쿼리를 실행하지 않고 그 결과 칼럼과 자료형을 출력\n" + +#: help.c:181 +#, c-format +msgid "" +" \\gexec execute query, then execute each value in its " +"result\n" +msgstr " \\gexec 쿼리를 실행하고, 그 결과를 각각 실행 함\n" + +#: help.c:182 +#, c-format +msgid "" +" \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PREFIX] 쿼리 실행 뒤 그 결과를 psql 변수로 저장\n" + +#: help.c:183 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [(OPTIONS)] [FILE] \\g 명령과 같으나, 출력을 확장 모드로 강제함\n" + +#: help.c:184 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q psql 종료\n" + +#: help.c:185 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SEC] 매 초마다 쿼리 실행\n" + +#: help.c:188 +#, c-format +msgid "Help\n" +msgstr "도움말\n" + +#: help.c:190 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commands] psql 역슬래시 명령어 설명\n" + +#: help.c:191 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? options psql 명령행 옵션 도움말 보기\n" + +#: help.c:192 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables psql 환경 설정 변수들에 설명 보기\n" + +#: help.c:193 +#, c-format +msgid "" +" \\h [NAME] help on syntax of SQL commands, * for all " +"commands\n" +msgstr "" +" \\h [NAME] SQL 명령 구문 도움말, 모든 명령을 표시하려면 * 입" +"력\n" + +#: help.c:196 +#, c-format +msgid "Query Buffer\n" +msgstr "쿼리 버퍼\n" + +#: help.c:197 +#, c-format +msgid "" +" \\e [FILE] [LINE] edit the query buffer (or file) with external " +"editor\n" +msgstr " \\e [FILE] [LINE] 외부 편집기로 쿼리 버퍼(또는 파일) 편집\n" + +#: help.c:198 +#, c-format +msgid "" +" \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [FUNCNAME [LINE]] 외부 편집기로 해당 함수 내용 편집\n" + +#: help.c:199 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr " \\ev [VIEWNAME [LINE]] 외부 편집기로 해당 뷰 정의 편집\n" + +#: help.c:200 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p 쿼리 버퍼의 내용 표시\n" + +#: help.c:201 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r 쿼리 버퍼 초기화(모두 지움)\n" + +#: help.c:203 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [FILE] 기록 표시 또는 파일에 저장\n" + +#: help.c:205 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w FILE 쿼리 버퍼를 파일에 기록\n" + +#: help.c:208 +#, c-format +msgid "Input/Output\n" +msgstr "입력/출력\n" + +#: help.c:209 +#, c-format +msgid "" +" \\copy ... perform SQL COPY with data stream to the client " +"host\n" +msgstr "" +" \\copy ... 클라이언트 호스트에 있는 자료를 SQL COPY 명령 실" +"행\n" + +#: help.c:210 +#, c-format +msgid "" +" \\echo [-n] [STRING] write string to standard output (-n for no " +"newline)\n" +msgstr " \\echo [-n] [STRING] 문자열을 표준 출력에 기록 (-n 줄바꿈 없음)\n" + +#: help.c:211 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i FILE 파일에서 명령 실행\n" + +#: help.c:212 +#, c-format +msgid "" +" \\ir FILE as \\i, but relative to location of current " +"script\n" +msgstr "" +" \\ir FILE \\i 명령과 같으나, 경로가 현재 위치 기준 상대적\n" + +#: help.c:213 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [FILE] 모든 쿼리 결과를 파일 또는 |파이프로 보냄\n" + +#: help.c:214 +#, c-format +msgid "" +" \\qecho [-n] [STRING] write string to \\o output stream (-n for no " +"newline)\n" +msgstr " \\qecho [-n] [STRING] 문자열을 \\o 출력 스트림에 기록 (-n 줄바꿈 없음)\n" + +#: help.c:215 +#, c-format +msgid "" +" \\warn [-n] [STRING] write string to standard error (-n for no " +"newline)\n" +msgstr " \\warn [-n] [STRING] 문자열을 stderr에 기록 (-n 줄바꿈 없음)\n" + +#: help.c:218 +#, c-format +msgid "Conditional\n" +msgstr "조건문\n" + +#: help.c:219 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR 조건문 시작\n" + +#: help.c:220 +#, c-format +msgid "" +" \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR else if 구문 시작\n" + +#: help.c:221 +#, c-format +msgid "" +" \\else final alternative within current conditional " +"block\n" +msgstr " \\else 조건문의 그 외 조건\n" + +#: help.c:222 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif 조건문 끝\n" + +#: help.c:225 +#, c-format +msgid "Informational\n" +msgstr "정보보기\n" + +#: help.c:226 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (옵션: S = 시스템 개체 표시, + = 추가 상세 정보)\n" + +#: help.c:227 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] 테이블, 뷰 및 시퀀스 목록\n" + +#: help.c:228 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+] NAME 테이블, 뷰, 시퀀스 또는 인덱스 설명\n" + +#: help.c:229 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [PATTERN] 집계 함수 목록\n" + +#: help.c:230 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [PATTERN] 접근 방법 목록\n" + +#: help.c:231 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] 연산자 클래스 목록\n" + +#: help.c:232 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] 연산자 부류 목록\n" + +#: help.c:233 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] 연산자 부류 소속 연산자 목록\n" + +#: help.c:234 +#, c-format +msgid "" +" \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr "" +" \\dAp [AMPTRN [OPFPTRN]] 연산자 가족에 포함된 지원 함수 목록\n" + +#: help.c:235 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [PATTERN] 테이블스페이스 목록\n" + +#: help.c:236 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [PATTERN] 문자셋 변환자 목록\n" + +#: help.c:237 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [PATTERN] 자료형 변환자 목록\n" + +#: help.c:238 +#, c-format +msgid "" +" \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr "" +" \\dd[S] [PATTERN] 다른 곳에서는 볼 수 없는 객체 설명을 보여줌\n" + +#: help.c:239 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [PATTERN] 도메인 목록\n" + +#: help.c:240 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [PATTERN] 기본 접근권한 목록\n" + +#: help.c:241 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [PATTERN] 외부 테이블 목록\n" + +#: help.c:242 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [PATTERN] 외부 테이블 목록\n" + +#: help.c:243 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [PATTERN] 외부 서버 목록\n" + +#: help.c:244 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [PATTERN] 사용자 매핑 목록\n" + +#: help.c:245 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [PATTERN] 외부 데이터 래퍼 목록\n" + +#: help.c:246 +#, c-format +msgid "" +" \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] " +"functions\n" +msgstr "" +" \\df[anptw][S+] [PATRN] [agg/normal/procedures/trigger/window] 함수 목록\n" + +#: help.c:247 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [PATTERN] 텍스트 검색 구성 목록\n" + +#: help.c:248 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [PATTERN] 텍스트 검색 사전 목록\n" + +#: help.c:249 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [PATTERN] 텍스트 검색 파서 목록\n" + +#: help.c:250 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [PATTERN] 텍스트 검색 템플릿 목록\n" + +#: help.c:251 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [PATTERN] 롤 목록\n" + +#: help.c:252 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [PATTERN] 인덱스 목록\n" + +#: help.c:253 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl 큰 개체 목록, \\lo_list 명령과 같음\n" + +#: help.c:254 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [PATTERN] 프로시져 언어 목록\n" + +#: help.c:255 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [PATTERN] materialized 뷰 목록\n" + +#: help.c:256 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [PATTERN] 스키마 목록\n" + +#: help.c:257 +#, c-format +msgid " \\do[S] [PATTERN] list operators\n" +msgstr " \\do[S] [PATTERN] 연산자 목록\n" + +#: help.c:258 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [PATTERN] collation 목록\n" + +#: help.c:259 +#, c-format +msgid "" +" \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [PATTERN] 테이블, 뷰 및 시퀀스 액세스 권한 목록\n" + +#: help.c:260 +#, c-format +msgid "" +" \\dP[itn+] [PATTERN] list [only index/table] partitioned relations " +"[n=nested]\n" +msgstr "" +" \\dP[itn+] [PATTERN] 파티션 릴레이션 목록 [인덱스/테이블만] [n=nested]\n" + +#: help.c:261 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [PATRN1 [PATRN2]] 데이터베이스별 롤 설정 목록\n" + +#: help.c:262 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [PATTERN] 복제 발행 목록\n" + +#: help.c:263 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [PATTERN] 복제 구독 목록\n" + +#: help.c:264 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [PATTERN] 시퀀스 목록\n" + +#: help.c:265 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [PATTERN] 테이블 목록\n" + +#: help.c:266 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [PATTERN] 데이터 형식 목록\n" + +#: help.c:267 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [PATTERN] 롤 목록\n" + +#: help.c:268 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [PATTERN] 뷰 목록\n" + +#: help.c:269 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [PATTERN] 확장 모듈 목록\n" + +#: help.c:270 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [PATTERN] 이벤트 트리거 목록\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [PATTERN] 데이터베이스 목록\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] 함수이름 함수 정의 보기\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] 뷰이름 뷰 정의 보기\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [PATTERN] \\dp와 같음\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "출력 형식\n" + +#: help.c:278 +#, c-format +msgid "" +" \\a toggle between unaligned and aligned output mode\n" +msgstr "" +" \\a 정렬되지 않은 출력 모드와 정렬된 출력 모드 전환\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr "" +" \\C [STRING] 테이블 제목 설정 또는 값이 없는 경우 설정 안 함\n" + +#: help.c:280 +#, c-format +msgid "" +" \\f [STRING] show or set field separator for unaligned query " +"output\n" +msgstr "" +" \\f [STRING] unaligned 출력에 대해 필드 구분자 표시 또는 설정\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H HTML 출력 모드 전환(현재 %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [이름 [값]] 테이블 출력 옵션 설정\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] 행만 표시(현재 %s)\n" + +#: help.c:292 +#, c-format +msgid "" +" \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr "" +" \\T [STRING] HTML
태그 속성 설정 또는 비었는 경우 설정 " +"안 함\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] 확장된 출력 전환 (현재 %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "연결\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" 새 데이터베이스에 접속 (현재 \"%s\")\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" 새 데이터베이스에 접속 (현재 접속해 있지 않음)\n" + +#: help.c:305 +#, c-format +msgid "" +" \\conninfo display information about current connection\n" +msgstr " \\conninfo 현재 데이터베이스 접속 정보 보기\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [ENCODING] 클라이언트 인코딩 표시 또는 설정\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr " \\password [USERNAME] 사용자 암호를 안전하게 변경\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "운영 체제\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [DIR] 현재 작업 디렉터리 변경\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv NAME [VALUE] 환경 변수 지정 및 해제\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] 명령 실행 시간 전환(현재 %s)\n" + +#: help.c:315 +#, c-format +msgid "" +" \\! [COMMAND] execute command in shell or start interactive " +"shell\n" +msgstr " \\! [COMMAND] 셸 명령 실행 또는 대화식 셸 시작\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "변수\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr "" +" \\prompt [TEXT] NAME 사용자에게 내부 변수를 설정하라는 메시지 표시\n" + +#: help.c:320 +#, c-format +msgid "" +" \\set [NAME [VALUE]] set internal variable, or list all if no " +"parameters\n" +msgstr "" +" \\set [NAME [VALUE]] 내부 변수 설정 또는 미지정 경우 모든 변수 목록 표" +"시\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset NAME 내부 변수 설정 해제(삭제)\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "큰 개체\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID 큰 개체 작업\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "특별한 기능 설정 변수 목록\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "psql 변수들:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=NAME=VALUE\n" +" 또는 psql 명령 모드에서는 \\set NAME VALUE\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" 설정 되면, SQL 명령이 정상 실행 되면 자동 커밋 함\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" SQL 키워드 자동완성에서 대소문자 처리\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" 현재 접속한 데이터베이스 이름\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" 입력을 표준 출력으로 보낼 종류\n" +" [all, errors, none, queries]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" 지정 되면 psql 내장 명령어의 내부 쿼리를 출력함;\n" +" \"noexec\" 값으로 설정하면, 실행되지 않고 쿼리만 보여줌\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" 현재 클라이언트 인코딩 지정\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" 마지막 쿼리가 실패했으면 true, 아니면 false\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = " +"unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" 쿼리 결과에 대해서 출력할 최대 로우 개수 (0=제한없음)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" 지정하면 테이블 접근 방법을 보여주지 않음\n" + +#: help.c:379 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" 명령 내역 처리 방법 [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" 명령 내역을 저장할 파일 이름\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" 명령 내역 최대 보관 개수\n" + +#: help.c:385 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" 현재 접속한 데이터베이스 서버 호스트\n" + +#: help.c:387 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" 대화형 세션 종료를 위한 EOF 개수\n" + +#: help.c:389 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" 마지막 영향 받은 OID 값\n" + +#: help.c:391 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if " +"none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" 마지막 오류 메시지와 SQLSTATE, 정상이면, 빈 문자열과 \"00000\"\n" + +#: help.c:394 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" 설정하면 오류 발생시에도 트랜잭션 중지 안함 (savepoint 암묵적 사용)\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" 배치 작업 시 오류가 발생하면 중지함\n" + +#: help.c:398 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" 현재 접속한 서버 포트\n" + +#: help.c:400 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" 기본 psql 프롬프트 정의\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous " +"line\n" +msgstr "" +" PROMPT2\n" +" 아직 구문이 덜 끝난 명령행의 프롬프트\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" COPY ... FROM STDIN 작업시 보일 프롬프트\n" + +#: help.c:406 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" 조용히 실행 (-q 옵션과 같음)\n" + +#: help.c:408 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" 마지막 쿼리 작업 대상 로우 수, 또는 0\n" + +#: help.c:410 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" 문자열 버전 정보나, 숫자 형식 버전 정보\n" + +#: help.c:413 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" 상황별 자세한 메시지 내용 출력 제어 [never, errors, always]\n" + +#: help.c:415 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" 한 줄에 하나의 SQL 명령 실행 (-S 옵션과 같음)\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" 각 명령을 확인하며 실행 (-s 옵션과 같음)\n" + +#: help.c:419 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" 마지막 쿼리의 SQLSTATE 값, 오류가 없으면 \"00000\"\n" + +#: help.c:421 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" 현재 접속한 데이터베이스 사용자\n" + +#: help.c:423 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" 오류 출력시 자세히 볼 내용 범위 [default, verbose, terse, sqlstate]\n" + +#: help.c:425 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql 버전 (자세한 버전, 단순한 버전, 숫자형 버전)\n" + +#: help.c:430 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"출력 설정들:\n" + +#: help.c:432 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NAME[=VALUE]\n" +" 또는 psql 명령 모드에서는 \\pset NAME [VALUE]\n" +"\n" + +#: help.c:434 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" 테두리 모양 (숫자)\n" + +#: help.c:436 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" 줄바꿈을 위한 너비 지정\n" + +#: help.c:438 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (또는 x)\n" +" 확장된 출력 전환 [on, off, auto]\n" + +#: help.c:440 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" unaligned 출력용 필드 구분자 (초기값 \"%s\"')\n" + +#: help.c:443 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" unaligned 출력용 필드 구분자를 0 바이트로 지정\n" + +#: help.c:445 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" 테이블 꼬리말 보이기 전환 [on, off]\n" + +#: help.c:447 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" 출력 양식 지정 [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:449 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" 테두리 선 모양 지정 [ascii, old-ascii, unicode]\n" + +#: help.c:451 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" null 값 출력 방법\n" + +#: help.c:453 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of " +"digits\n" +msgstr "" +" numericlocale\n" +" 숫자 출력에서 로케일 기반 천자리 분리 문자 활성화 [on, off]\n" + +#: help.c:455 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" 외부 페이지 단위 보기 도구 사용 여부 [yes, no, always]\n" + +#: help.c:457 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" unaligned 출력용 레코드(줄) 구분자\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" unaligned 출력용 레코드 구분자를 0 바이트로 지정\n" + +#: help.c:461 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (또는 T)\n" +" html 테이블 태그에 대한 속성이나,\n" +" latex-longtable 양식에서 왼쪽 정렬 자료용 칼럼 넓이 지정\n" + +#: help.c:464 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" 테이블 제목 지정\n" + +#: help.c:466 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" 지정되면, 자료만 보임\n" + +#: help.c:468 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" 유니코드 선 종류 [single, double]\n" + +#: help.c:473 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"OS 환경 변수들:\n" + +#: help.c:477 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" 또는 psql 명령 모드에서는 \\setenv NAME [VALUE]\n" +"\n" + +#: help.c:479 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NAME=VALUE\n" +" psql ...\n" +" 또는 psql 명령 모드에서는 \\setenv NAME [VALUE]\n" +"\n" + +#: help.c:482 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" 다음 줄로 넘어갈 칼럼 수\n" + +#: help.c:484 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" application_name 변수값으로 사용됨\n" + +#: help.c:486 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" 접속할 데이터베이스 이름\n" + +#: help.c:488 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" 서버 접속용 호스트 이름\n" + +#: help.c:490 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" 서버 접속 비밀번호 (보안에 취약함)\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" 서버 접속용 비밀번호가 저장된 파일 이름\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" 서버 접속용 포트\n" + +#: help.c:496 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" 서버 접속용 데이터베이스 사용자 이름\n" + +#: help.c:498 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" \\e, \\ef, \\ev 명령에서 사용할 외부 편집기 경로\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" 외부 편집기 호출 시 사용할 줄번호 선택 옵션\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" 사용자 .psql_history 파일 임의 지정\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PAGER\n" +" 페이지 단위 보기에서 사용할 프로그램\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" 사용자 .psqlrc 파일의 임의 지정\n" + +#: help.c:508 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" \\! 명령에서 사용할 쉘\n" + +#: help.c:510 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" 임시 파일을 사용할 디렉터리\n" + +#: help.c:554 +msgid "Available help:\n" +msgstr "사용 가능한 도움말:\n" + +#: help.c:642 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"명령: %s\n" +"설명: %s\n" +"문법:\n" +"%s\n" +"URL: %s\n" +"\n" + +#: help.c:661 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"\"%s\" 명령에 대한 도움말 없음.\n" +"\\h 명령을 인자 없이 호출 하면 사용 가능한 모든 명령 보여줌.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "입력 파일을 읽을 수 없음: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "history를 \"%s\" 파일로 저장할 수 없음: %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "히스토리 기능은 이 설치본에서는 지원하지 않음" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: 데이터베이스에 연되어있지 않음" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: 현재 트랜잭션 중지됨" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: 알 수 없는 트랜잭션 상태" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "대형 객체들" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if: escaped" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "마치려면 \"\\q\"를 입력하세요: %s\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"이 입력은 PostgreSQL 사용자양식 덤프 내용입니다.\n" +"이 덤프 내용을 데이터베이스에 반영하려면,\n" +"pg_restore 명령행 클라이언트를 사용하세요.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "\\? 도움말, Ctrl-C 입력 버퍼 비우기" + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "도움말을 보려면 \\?를 입력하십시오." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "PostgreSQL에 대한 명령행 인터페이스인 psql을 사용하고 있습니다." + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"사용법: \\copyright 저작권 정보\n" +" \\h SQL 명령 도움말\n" +" \\? psql 명령 도움말\n" +" \\g 또는 명령 끝에 세미콜론(;) 쿼리 실행\n" +" \\q 마침\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "\\q 마침" + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "마침은 Ctrl-D" + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "마침은 Ctrl-C" + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "" +"쿼리 무시됨; 현재 \\if 블록을 끝내려면 \\endif 또는 Ctrl-C 키를 사용하세요." + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "\\endif 없이 EOF 도달" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "마무리 안된 따옴표 안의 문자열" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: 메모리 부족" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1090 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 +#: sql_help.c:1112 sql_help.c:1114 sql_help.c:1118 sql_help.c:1121 +#: sql_help.c:1122 sql_help.c:1123 sql_help.c:1126 sql_help.c:1128 +#: sql_help.c:1262 sql_help.c:1264 sql_help.c:1267 sql_help.c:1270 +#: sql_help.c:1272 sql_help.c:1274 sql_help.c:1277 sql_help.c:1280 +#: sql_help.c:1391 sql_help.c:1393 sql_help.c:1395 sql_help.c:1398 +#: sql_help.c:1419 sql_help.c:1422 sql_help.c:1425 sql_help.c:1428 +#: sql_help.c:1432 sql_help.c:1434 sql_help.c:1436 sql_help.c:1438 +#: sql_help.c:1452 sql_help.c:1455 sql_help.c:1457 sql_help.c:1459 +#: sql_help.c:1469 sql_help.c:1471 sql_help.c:1481 sql_help.c:1483 +#: sql_help.c:1493 sql_help.c:1496 sql_help.c:1519 sql_help.c:1521 +#: sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 sql_help.c:1530 +#: sql_help.c:1533 sql_help.c:1536 sql_help.c:1586 sql_help.c:1629 +#: sql_help.c:1632 sql_help.c:1634 sql_help.c:1636 sql_help.c:1639 +#: sql_help.c:1641 sql_help.c:1643 sql_help.c:1646 sql_help.c:1696 +#: sql_help.c:1712 sql_help.c:1933 sql_help.c:2002 sql_help.c:2021 +#: sql_help.c:2034 sql_help.c:2091 sql_help.c:2098 sql_help.c:2108 +#: sql_help.c:2129 sql_help.c:2155 sql_help.c:2173 sql_help.c:2200 +#: sql_help.c:2295 sql_help.c:2340 sql_help.c:2364 sql_help.c:2387 +#: sql_help.c:2391 sql_help.c:2425 sql_help.c:2445 sql_help.c:2467 +#: sql_help.c:2481 sql_help.c:2501 sql_help.c:2524 sql_help.c:2554 +#: sql_help.c:2579 sql_help.c:2625 sql_help.c:2903 sql_help.c:2916 +#: sql_help.c:2933 sql_help.c:2949 sql_help.c:2989 sql_help.c:3041 +#: sql_help.c:3045 sql_help.c:3047 sql_help.c:3053 sql_help.c:3071 +#: sql_help.c:3098 sql_help.c:3133 sql_help.c:3145 sql_help.c:3154 +#: sql_help.c:3198 sql_help.c:3212 sql_help.c:3240 sql_help.c:3248 +#: sql_help.c:3260 sql_help.c:3270 sql_help.c:3278 sql_help.c:3286 +#: sql_help.c:3294 sql_help.c:3302 sql_help.c:3311 sql_help.c:3322 +#: sql_help.c:3330 sql_help.c:3338 sql_help.c:3346 sql_help.c:3354 +#: sql_help.c:3364 sql_help.c:3373 sql_help.c:3382 sql_help.c:3390 +#: sql_help.c:3400 sql_help.c:3411 sql_help.c:3419 sql_help.c:3428 +#: sql_help.c:3439 sql_help.c:3448 sql_help.c:3456 sql_help.c:3464 +#: sql_help.c:3472 sql_help.c:3480 sql_help.c:3488 sql_help.c:3496 +#: sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 sql_help.c:3528 +#: sql_help.c:3545 sql_help.c:3554 sql_help.c:3562 sql_help.c:3579 +#: sql_help.c:3594 sql_help.c:3869 sql_help.c:3920 sql_help.c:3949 +#: sql_help.c:3962 sql_help.c:4407 sql_help.c:4455 sql_help.c:4596 +msgid "name" +msgstr "이름" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1783 +#: sql_help.c:3213 sql_help.c:4193 +msgid "aggregate_signature" +msgstr "집계함수_식별구문" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1093 sql_help.c:1129 sql_help.c:1271 sql_help.c:1392 +#: sql_help.c:1435 sql_help.c:1456 sql_help.c:1470 sql_help.c:1482 +#: sql_help.c:1495 sql_help.c:1522 sql_help.c:1587 sql_help.c:1640 +msgid "new_name" +msgstr "새이름" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1091 sql_help.c:1127 sql_help.c:1332 +#: sql_help.c:1394 sql_help.c:1437 sql_help.c:1458 sql_help.c:1520 +#: sql_help.c:1635 sql_help.c:2889 +msgid "new_owner" +msgstr "새사용자" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1095 +#: sql_help.c:1273 sql_help.c:1439 sql_help.c:1460 sql_help.c:1472 +#: sql_help.c:1484 sql_help.c:1524 sql_help.c:1642 +msgid "new_schema" +msgstr "새스키마" + +#: sql_help.c:44 sql_help.c:1847 sql_help.c:3214 sql_help.c:4222 +msgid "where aggregate_signature is:" +msgstr "집계함수_식별구문 사용법:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1801 +#: sql_help.c:1818 sql_help.c:1824 sql_help.c:1848 sql_help.c:1851 +#: sql_help.c:1854 sql_help.c:2003 sql_help.c:2022 sql_help.c:2025 +#: sql_help.c:2296 sql_help.c:2502 sql_help.c:3215 sql_help.c:3218 +#: sql_help.c:3221 sql_help.c:3312 sql_help.c:3401 sql_help.c:3429 +#: sql_help.c:3753 sql_help.c:4101 sql_help.c:4199 sql_help.c:4206 +#: sql_help.c:4212 sql_help.c:4223 sql_help.c:4226 sql_help.c:4229 +msgid "argmode" +msgstr "인자모드" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1802 +#: sql_help.c:1819 sql_help.c:1825 sql_help.c:1849 sql_help.c:1852 +#: sql_help.c:1855 sql_help.c:2004 sql_help.c:2023 sql_help.c:2026 +#: sql_help.c:2297 sql_help.c:2503 sql_help.c:3216 sql_help.c:3219 +#: sql_help.c:3222 sql_help.c:3313 sql_help.c:3402 sql_help.c:3430 +#: sql_help.c:4200 sql_help.c:4207 sql_help.c:4213 sql_help.c:4224 +#: sql_help.c:4227 sql_help.c:4230 +msgid "argname" +msgstr "인자이름" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1803 +#: sql_help.c:1820 sql_help.c:1826 sql_help.c:1850 sql_help.c:1853 +#: sql_help.c:1856 sql_help.c:2298 sql_help.c:2504 sql_help.c:3217 +#: sql_help.c:3220 sql_help.c:3223 sql_help.c:3314 sql_help.c:3403 +#: sql_help.c:3431 sql_help.c:4201 sql_help.c:4208 sql_help.c:4214 +#: sql_help.c:4225 sql_help.c:4228 sql_help.c:4231 +msgid "argtype" +msgstr "인자자료형" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1453 sql_help.c:1581 sql_help.c:1613 +#: sql_help.c:1665 sql_help.c:1904 sql_help.c:1911 sql_help.c:2203 +#: sql_help.c:2245 sql_help.c:2252 sql_help.c:2261 sql_help.c:2341 +#: sql_help.c:2555 sql_help.c:2647 sql_help.c:2918 sql_help.c:3099 +#: sql_help.c:3121 sql_help.c:3261 sql_help.c:3616 sql_help.c:3788 +#: sql_help.c:3961 sql_help.c:4658 +msgid "option" +msgstr "옵션" + +#: sql_help.c:113 sql_help.c:927 sql_help.c:1582 sql_help.c:2342 +#: sql_help.c:2556 sql_help.c:3100 sql_help.c:3262 +msgid "where option can be:" +msgstr "옵션 사용법:" + +#: sql_help.c:114 sql_help.c:2137 +msgid "allowconn" +msgstr "접속허용" + +#: sql_help.c:115 sql_help.c:928 sql_help.c:1583 sql_help.c:2138 +#: sql_help.c:2343 sql_help.c:2557 sql_help.c:3101 +msgid "connlimit" +msgstr "접속제한" + +#: sql_help.c:116 sql_help.c:2139 +msgid "istemplate" +msgstr "템플릿?" + +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1276 sql_help.c:1325 +msgid "new_tablespace" +msgstr "새테이블스페이스" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1140 sql_help.c:1143 sql_help.c:1590 +#: sql_help.c:1594 sql_help.c:1597 sql_help.c:2308 sql_help.c:2508 +#: sql_help.c:3980 sql_help.c:4396 +msgid "configuration_parameter" +msgstr "환경설정_매개변수" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1117 sql_help.c:1120 sql_help.c:1125 sql_help.c:1141 +#: sql_help.c:1142 sql_help.c:1307 sql_help.c:1327 sql_help.c:1375 +#: sql_help.c:1397 sql_help.c:1454 sql_help.c:1538 sql_help.c:1591 +#: sql_help.c:1614 sql_help.c:2204 sql_help.c:2246 sql_help.c:2253 +#: sql_help.c:2262 sql_help.c:2309 sql_help.c:2310 sql_help.c:2372 +#: sql_help.c:2375 sql_help.c:2409 sql_help.c:2509 sql_help.c:2510 +#: sql_help.c:2527 sql_help.c:2648 sql_help.c:2678 sql_help.c:2783 +#: sql_help.c:2796 sql_help.c:2810 sql_help.c:2851 sql_help.c:2875 +#: sql_help.c:2892 sql_help.c:2919 sql_help.c:3122 sql_help.c:3789 +#: sql_help.c:4397 sql_help.c:4398 +msgid "value" +msgstr "값" + +#: sql_help.c:197 +msgid "target_role" +msgstr "대상롤" + +#: sql_help.c:198 sql_help.c:2188 sql_help.c:2603 sql_help.c:2608 +#: sql_help.c:3735 sql_help.c:3742 sql_help.c:3756 sql_help.c:3762 +#: sql_help.c:4083 sql_help.c:4090 sql_help.c:4104 sql_help.c:4110 +msgid "schema_name" +msgstr "스키마이름" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "grant_또는_revoke_내용" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "grant_또는_revoke_내용에 사용되는 구문:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1275 sql_help.c:1601 sql_help.c:2346 sql_help.c:2347 +#: sql_help.c:2348 sql_help.c:2349 sql_help.c:2350 sql_help.c:2483 +#: sql_help.c:2560 sql_help.c:2561 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 sql_help.c:3104 sql_help.c:3105 sql_help.c:3106 +#: sql_help.c:3107 sql_help.c:3108 sql_help.c:3768 sql_help.c:3772 +#: sql_help.c:4116 sql_help.c:4120 sql_help.c:4417 +msgid "role_name" +msgstr "롤이름" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1342 sql_help.c:1354 sql_help.c:1379 sql_help.c:1631 +#: sql_help.c:2158 sql_help.c:2162 sql_help.c:2265 sql_help.c:2270 +#: sql_help.c:2368 sql_help.c:2778 sql_help.c:2791 sql_help.c:2805 +#: sql_help.c:2814 sql_help.c:2826 sql_help.c:2855 sql_help.c:3820 +#: sql_help.c:3835 sql_help.c:3837 sql_help.c:4282 sql_help.c:4283 +#: sql_help.c:4292 sql_help.c:4333 sql_help.c:4334 sql_help.c:4335 +#: sql_help.c:4336 sql_help.c:4337 sql_help.c:4338 sql_help.c:4371 +#: sql_help.c:4372 sql_help.c:4377 sql_help.c:4382 sql_help.c:4521 +#: sql_help.c:4522 sql_help.c:4531 sql_help.c:4572 sql_help.c:4573 +#: sql_help.c:4574 sql_help.c:4575 sql_help.c:4576 sql_help.c:4577 +#: sql_help.c:4624 sql_help.c:4626 sql_help.c:4685 sql_help.c:4741 +#: sql_help.c:4742 sql_help.c:4751 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +msgid "expression" +msgstr "표현식" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "도메인_제약조건" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1268 sql_help.c:1313 sql_help.c:1314 sql_help.c:1315 +#: sql_help.c:1341 sql_help.c:1353 sql_help.c:1370 sql_help.c:1789 +#: sql_help.c:1791 sql_help.c:2161 sql_help.c:2264 sql_help.c:2269 +#: sql_help.c:2813 sql_help.c:2825 sql_help.c:3832 +msgid "constraint_name" +msgstr "제약조건_이름" + +#: sql_help.c:244 sql_help.c:1269 +msgid "new_constraint_name" +msgstr "새제약조건_이름" + +#: sql_help.c:317 sql_help.c:1073 +msgid "new_version" +msgstr "새버전" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "맴버_객체" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "맴버_객체 사용법:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1781 sql_help.c:1786 sql_help.c:1793 +#: sql_help.c:1794 sql_help.c:1795 sql_help.c:1796 sql_help.c:1797 +#: sql_help.c:1798 sql_help.c:1799 sql_help.c:1804 sql_help.c:1806 +#: sql_help.c:1810 sql_help.c:1812 sql_help.c:1816 sql_help.c:1821 +#: sql_help.c:1822 sql_help.c:1829 sql_help.c:1830 sql_help.c:1831 +#: sql_help.c:1832 sql_help.c:1833 sql_help.c:1834 sql_help.c:1835 +#: sql_help.c:1836 sql_help.c:1837 sql_help.c:1838 sql_help.c:1839 +#: sql_help.c:1844 sql_help.c:1845 sql_help.c:4189 sql_help.c:4194 +#: sql_help.c:4195 sql_help.c:4196 sql_help.c:4197 sql_help.c:4203 +#: sql_help.c:4204 sql_help.c:4209 sql_help.c:4210 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4217 sql_help.c:4218 sql_help.c:4219 +#: sql_help.c:4220 +msgid "object_name" +msgstr "객체이름" + +#: sql_help.c:326 sql_help.c:1782 sql_help.c:4192 +msgid "aggregate_name" +msgstr "집계함수이름" + +#: sql_help.c:328 sql_help.c:1784 sql_help.c:2068 sql_help.c:2072 +#: sql_help.c:2074 sql_help.c:3231 +msgid "source_type" +msgstr "기존자료형" + +#: sql_help.c:329 sql_help.c:1785 sql_help.c:2069 sql_help.c:2073 +#: sql_help.c:2075 sql_help.c:3232 +msgid "target_type" +msgstr "대상자료형" + +#: sql_help.c:336 sql_help.c:774 sql_help.c:1800 sql_help.c:2070 +#: sql_help.c:2111 sql_help.c:2176 sql_help.c:2426 sql_help.c:2457 +#: sql_help.c:2995 sql_help.c:4100 sql_help.c:4198 sql_help.c:4311 +#: sql_help.c:4315 sql_help.c:4319 sql_help.c:4322 sql_help.c:4550 +#: sql_help.c:4554 sql_help.c:4558 sql_help.c:4561 sql_help.c:4770 +#: sql_help.c:4774 sql_help.c:4778 sql_help.c:4781 +msgid "function_name" +msgstr "함수이름" + +#: sql_help.c:341 sql_help.c:767 sql_help.c:1807 sql_help.c:2450 +msgid "operator_name" +msgstr "연산자이름" + +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1808 +#: sql_help.c:2427 sql_help.c:3355 +msgid "left_type" +msgstr "왼쪽인자_자료형" + +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1809 +#: sql_help.c:2428 sql_help.c:3356 +msgid "right_type" +msgstr "오른쪽인자_자료형" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1359 sql_help.c:1811 sql_help.c:1813 sql_help.c:2447 +#: sql_help.c:2468 sql_help.c:2831 sql_help.c:3365 sql_help.c:3374 +msgid "index_method" +msgstr "색인방법" + +#: sql_help.c:349 sql_help.c:1817 sql_help.c:4205 +msgid "procedure_name" +msgstr "프로시져_이름" + +#: sql_help.c:353 sql_help.c:1823 sql_help.c:3752 sql_help.c:4211 +msgid "routine_name" +msgstr "루틴_이름" + +#: sql_help.c:365 sql_help.c:1331 sql_help.c:1840 sql_help.c:2304 +#: sql_help.c:2507 sql_help.c:2786 sql_help.c:2962 sql_help.c:3536 +#: sql_help.c:3766 sql_help.c:4114 +msgid "type_name" +msgstr "자료형이름" + +#: sql_help.c:366 sql_help.c:1841 sql_help.c:2303 sql_help.c:2506 +#: sql_help.c:2963 sql_help.c:3189 sql_help.c:3537 sql_help.c:3758 +#: sql_help.c:4106 +msgid "lang_name" +msgstr "언어_이름" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "집계함수_식별구문 사용법:" + +#: sql_help.c:392 sql_help.c:1935 sql_help.c:2201 +msgid "handler_function" +msgstr "핸들러_함수" + +#: sql_help.c:393 sql_help.c:2202 +msgid "validator_function" +msgstr "유효성검사_함수" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1263 sql_help.c:1529 +msgid "action" +msgstr "동작" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1265 +#: sql_help.c:1283 sql_help.c:1287 sql_help.c:1288 sql_help.c:1292 +#: sql_help.c:1294 sql_help.c:1295 sql_help.c:1296 sql_help.c:1297 +#: sql_help.c:1299 sql_help.c:1302 sql_help.c:1303 sql_help.c:1305 +#: sql_help.c:1308 sql_help.c:1310 sql_help.c:1355 sql_help.c:1357 +#: sql_help.c:1364 sql_help.c:1373 sql_help.c:1378 sql_help.c:1630 +#: sql_help.c:1633 sql_help.c:1637 sql_help.c:1673 sql_help.c:1788 +#: sql_help.c:1901 sql_help.c:1907 sql_help.c:1920 sql_help.c:1921 +#: sql_help.c:1922 sql_help.c:2243 sql_help.c:2256 sql_help.c:2301 +#: sql_help.c:2367 sql_help.c:2373 sql_help.c:2406 sql_help.c:2633 +#: sql_help.c:2661 sql_help.c:2662 sql_help.c:2769 sql_help.c:2777 +#: sql_help.c:2787 sql_help.c:2790 sql_help.c:2800 sql_help.c:2804 +#: sql_help.c:2827 sql_help.c:2829 sql_help.c:2836 sql_help.c:2849 +#: sql_help.c:2854 sql_help.c:2872 sql_help.c:2998 sql_help.c:3134 +#: sql_help.c:3737 sql_help.c:3738 sql_help.c:3819 sql_help.c:3834 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:4085 sql_help.c:4086 +#: sql_help.c:4191 sql_help.c:4342 sql_help.c:4581 sql_help.c:4623 +#: sql_help.c:4625 sql_help.c:4627 sql_help.c:4673 sql_help.c:4801 +msgid "column_name" +msgstr "칼럼이름" + +#: sql_help.c:444 sql_help.c:664 sql_help.c:1266 sql_help.c:1638 +msgid "new_column_name" +msgstr "새칼럼이름" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1282 sql_help.c:1539 +msgid "where action is one of:" +msgstr "동작 사용법:" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1284 +#: sql_help.c:1289 sql_help.c:1541 sql_help.c:1545 sql_help.c:2156 +#: sql_help.c:2244 sql_help.c:2446 sql_help.c:2626 sql_help.c:2770 +#: sql_help.c:3043 sql_help.c:3921 +msgid "data_type" +msgstr "자료형" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1285 sql_help.c:1290 +#: sql_help.c:1542 sql_help.c:1546 sql_help.c:2157 sql_help.c:2247 +#: sql_help.c:2369 sql_help.c:2771 sql_help.c:2779 sql_help.c:2792 +#: sql_help.c:2806 sql_help.c:3044 sql_help.c:3050 sql_help.c:3829 +msgid "collation" +msgstr "collation" + +#: sql_help.c:453 sql_help.c:1286 sql_help.c:2248 sql_help.c:2257 +#: sql_help.c:2772 sql_help.c:2788 sql_help.c:2801 +msgid "column_constraint" +msgstr "칼럼_제약조건" + +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1304 sql_help.c:4670 +msgid "integer" +msgstr "정수" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1306 +#: sql_help.c:1309 +msgid "attribute_option" +msgstr "속성_옵션" + +#: sql_help.c:473 sql_help.c:1311 sql_help.c:2249 sql_help.c:2258 +#: sql_help.c:2773 sql_help.c:2789 sql_help.c:2802 +msgid "table_constraint" +msgstr "테이블_제약조건" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1316 +#: sql_help.c:1317 sql_help.c:1318 sql_help.c:1319 sql_help.c:1842 +msgid "trigger_name" +msgstr "트리거이름" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1329 sql_help.c:1330 +#: sql_help.c:2250 sql_help.c:2255 sql_help.c:2776 sql_help.c:2799 +msgid "parent_table" +msgstr "상위_테이블" + +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1498 sql_help.c:2187 +msgid "extension_name" +msgstr "확장모듈이름" + +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2305 +msgid "execution_cost" +msgstr "실행비용" + +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2306 +msgid "result_rows" +msgstr "반환자료수" + +#: sql_help.c:543 sql_help.c:2307 +msgid "support_function" +msgstr "지원_함수" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1580 sql_help.c:1588 +#: sql_help.c:1592 sql_help.c:1595 sql_help.c:1598 sql_help.c:2604 +#: sql_help.c:2606 sql_help.c:2609 sql_help.c:2610 sql_help.c:3736 +#: sql_help.c:3740 sql_help.c:3743 sql_help.c:3745 sql_help.c:3747 +#: sql_help.c:3749 sql_help.c:3751 sql_help.c:3757 sql_help.c:3759 +#: sql_help.c:3761 sql_help.c:3763 sql_help.c:3765 sql_help.c:3767 +#: sql_help.c:3769 sql_help.c:3770 sql_help.c:4084 sql_help.c:4088 +#: sql_help.c:4091 sql_help.c:4093 sql_help.c:4095 sql_help.c:4097 +#: sql_help.c:4099 sql_help.c:4105 sql_help.c:4107 sql_help.c:4109 +#: sql_help.c:4111 sql_help.c:4113 sql_help.c:4115 sql_help.c:4117 +#: sql_help.c:4118 +msgid "role_specification" +msgstr "롤_명세" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:1611 sql_help.c:2130 +#: sql_help.c:2612 sql_help.c:3119 sql_help.c:3570 sql_help.c:4427 +msgid "user_name" +msgstr "사용자이름" + +#: sql_help.c:568 sql_help.c:945 sql_help.c:1600 sql_help.c:2611 +#: sql_help.c:3771 sql_help.c:4119 +msgid "where role_specification can be:" +msgstr "롤_명세 사용법:" + +#: sql_help.c:570 +msgid "group_name" +msgstr "그룹이름" + +#: sql_help.c:591 sql_help.c:1376 sql_help.c:2136 sql_help.c:2376 +#: sql_help.c:2410 sql_help.c:2784 sql_help.c:2797 sql_help.c:2811 +#: sql_help.c:2852 sql_help.c:2876 sql_help.c:2888 sql_help.c:3764 +#: sql_help.c:4112 +msgid "tablespace_name" +msgstr "테이블스페이스이름" + +#: sql_help.c:593 sql_help.c:681 sql_help.c:1324 sql_help.c:1333 +#: sql_help.c:1371 sql_help.c:1722 +msgid "index_name" +msgstr "인덱스이름" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1326 +#: sql_help.c:1328 sql_help.c:1374 sql_help.c:2374 sql_help.c:2408 +#: sql_help.c:2782 sql_help.c:2795 sql_help.c:2809 sql_help.c:2850 +#: sql_help.c:2874 +msgid "storage_parameter" +msgstr "스토리지_매개변수" + +#: sql_help.c:602 +msgid "column_number" +msgstr "칼럼번호" + +#: sql_help.c:626 sql_help.c:1805 sql_help.c:4202 +msgid "large_object_oid" +msgstr "대형_객체_oid" + +#: sql_help.c:713 sql_help.c:2431 +msgid "res_proc" +msgstr "" + +#: sql_help.c:714 sql_help.c:2432 +msgid "join_proc" +msgstr "" + +#: sql_help.c:766 sql_help.c:778 sql_help.c:2449 +msgid "strategy_number" +msgstr "전략_번호" + +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2451 sql_help.c:2452 +#: sql_help.c:2455 sql_help.c:2456 +msgid "op_type" +msgstr "연산자자료형" + +#: sql_help.c:770 sql_help.c:2453 +msgid "sort_family_name" +msgstr "" + +#: sql_help.c:771 sql_help.c:781 sql_help.c:2454 +msgid "support_number" +msgstr "" + +#: sql_help.c:775 sql_help.c:2071 sql_help.c:2458 sql_help.c:2965 +#: sql_help.c:2967 +msgid "argument_type" +msgstr "인자자료형" + +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1494 sql_help.c:1497 +#: sql_help.c:1672 sql_help.c:1721 sql_help.c:1790 sql_help.c:1815 +#: sql_help.c:1828 sql_help.c:1843 sql_help.c:1900 sql_help.c:1906 +#: sql_help.c:2242 sql_help.c:2254 sql_help.c:2365 sql_help.c:2405 +#: sql_help.c:2482 sql_help.c:2525 sql_help.c:2581 sql_help.c:2632 +#: sql_help.c:2663 sql_help.c:2768 sql_help.c:2785 sql_help.c:2798 +#: sql_help.c:2871 sql_help.c:2991 sql_help.c:3168 sql_help.c:3391 +#: sql_help.c:3440 sql_help.c:3546 sql_help.c:3734 sql_help.c:3739 +#: sql_help.c:3785 sql_help.c:3817 sql_help.c:4082 sql_help.c:4087 +#: sql_help.c:4190 sql_help.c:4297 sql_help.c:4299 sql_help.c:4348 +#: sql_help.c:4387 sql_help.c:4536 sql_help.c:4538 sql_help.c:4587 +#: sql_help.c:4621 sql_help.c:4672 sql_help.c:4756 sql_help.c:4758 +#: sql_help.c:4807 +msgid "table_name" +msgstr "테이블이름" + +#: sql_help.c:811 sql_help.c:2484 +msgid "using_expression" +msgstr "" + +#: sql_help.c:812 sql_help.c:2485 +msgid "check_expression" +msgstr "체크_표현식" + +#: sql_help.c:886 sql_help.c:2526 +msgid "publication_parameter" +msgstr "발행_매개변수" + +#: sql_help.c:929 sql_help.c:1584 sql_help.c:2344 sql_help.c:2558 +#: sql_help.c:3102 +msgid "password" +msgstr "암호" + +#: sql_help.c:930 sql_help.c:1585 sql_help.c:2345 sql_help.c:2559 +#: sql_help.c:3103 +msgid "timestamp" +msgstr "" + +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1589 +#: sql_help.c:1593 sql_help.c:1596 sql_help.c:1599 sql_help.c:3744 +#: sql_help.c:4092 +msgid "database_name" +msgstr "데이터베이스이름" + +#: sql_help.c:1048 sql_help.c:2627 +msgid "increment" +msgstr "" + +#: sql_help.c:1049 sql_help.c:2628 +msgid "minvalue" +msgstr "최소값" + +#: sql_help.c:1050 sql_help.c:2629 +msgid "maxvalue" +msgstr "최대값" + +#: sql_help.c:1051 sql_help.c:2630 sql_help.c:4295 sql_help.c:4385 +#: sql_help.c:4534 sql_help.c:4689 sql_help.c:4754 +msgid "start" +msgstr "시작" + +#: sql_help.c:1052 sql_help.c:1301 +msgid "restart" +msgstr "재시작" + +#: sql_help.c:1053 sql_help.c:2631 +msgid "cache" +msgstr "캐쉬" + +#: sql_help.c:1097 +msgid "new_target" +msgstr "새대상" + +#: sql_help.c:1113 sql_help.c:2675 +msgid "conninfo" +msgstr "접속정보" + +#: sql_help.c:1115 sql_help.c:2676 +msgid "publication_name" +msgstr "발행_이름" + +#: sql_help.c:1116 +msgid "set_publication_option" +msgstr "발행_옵션_설정" + +#: sql_help.c:1119 +msgid "refresh_option" +msgstr "새로고침_옵션" + +#: sql_help.c:1124 sql_help.c:2677 +msgid "subscription_parameter" +msgstr "구독_매개변수" + +#: sql_help.c:1278 sql_help.c:1281 +msgid "partition_name" +msgstr "파티션_이름" + +#: sql_help.c:1279 sql_help.c:2259 sql_help.c:2803 +msgid "partition_bound_spec" +msgstr "파티션_범위_정의" + +#: sql_help.c:1298 sql_help.c:1345 sql_help.c:2817 +msgid "sequence_options" +msgstr "시퀀스_옵션" + +#: sql_help.c:1300 +msgid "sequence_option" +msgstr "시퀀스_옵션" + +#: sql_help.c:1312 +msgid "table_constraint_using_index" +msgstr "" + +#: sql_help.c:1320 sql_help.c:1321 sql_help.c:1322 sql_help.c:1323 +msgid "rewrite_rule_name" +msgstr "" + +#: sql_help.c:1334 sql_help.c:2842 +msgid "and partition_bound_spec is:" +msgstr "" + +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:2843 +#: sql_help.c:2844 sql_help.c:2845 +msgid "partition_bound_expr" +msgstr "파티션_범위_정의" + +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:2846 sql_help.c:2847 +msgid "numeric_literal" +msgstr "" + +#: sql_help.c:1340 +msgid "and column_constraint is:" +msgstr "칼럼_제약조건 사용법:" + +#: sql_help.c:1343 sql_help.c:2266 sql_help.c:2299 sql_help.c:2505 +#: sql_help.c:2815 +msgid "default_expr" +msgstr "초기값_표현식" + +#: sql_help.c:1344 sql_help.c:2267 sql_help.c:2816 +msgid "generation_expr" +msgstr "" + +#: sql_help.c:1346 sql_help.c:1347 sql_help.c:1356 sql_help.c:1358 +#: sql_help.c:1362 sql_help.c:2818 sql_help.c:2819 sql_help.c:2828 +#: sql_help.c:2830 sql_help.c:2834 +msgid "index_parameters" +msgstr "색인매개변수" + +#: sql_help.c:1348 sql_help.c:1365 sql_help.c:2820 sql_help.c:2837 +msgid "reftable" +msgstr "참조테이블" + +#: sql_help.c:1349 sql_help.c:1366 sql_help.c:2821 sql_help.c:2838 +msgid "refcolumn" +msgstr "참조칼럼" + +#: sql_help.c:1350 sql_help.c:1351 sql_help.c:1367 sql_help.c:1368 +#: sql_help.c:2822 sql_help.c:2823 sql_help.c:2839 sql_help.c:2840 +msgid "referential_action" +msgstr "참조_방식" + +#: sql_help.c:1352 sql_help.c:2268 sql_help.c:2824 +msgid "and table_constraint is:" +msgstr "테이블_제약조건 사용법:" + +#: sql_help.c:1360 sql_help.c:2832 +msgid "exclude_element" +msgstr "" + +#: sql_help.c:1361 sql_help.c:2833 sql_help.c:4293 sql_help.c:4383 +#: sql_help.c:4532 sql_help.c:4687 sql_help.c:4752 +msgid "operator" +msgstr "연산자" + +#: sql_help.c:1363 sql_help.c:2377 sql_help.c:2835 +msgid "predicate" +msgstr "범위한정구문" + +#: sql_help.c:1369 +msgid "and table_constraint_using_index is:" +msgstr "" + +#: sql_help.c:1372 sql_help.c:2848 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "" + +#: sql_help.c:1377 sql_help.c:2853 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "" + +#: sql_help.c:1380 sql_help.c:2370 sql_help.c:2780 sql_help.c:2793 +#: sql_help.c:2807 sql_help.c:2856 sql_help.c:3830 +msgid "opclass" +msgstr "연산자클래스" + +#: sql_help.c:1396 sql_help.c:1399 sql_help.c:2891 +msgid "tablespace_option" +msgstr "테이블스페이스_옵션" + +#: sql_help.c:1420 sql_help.c:1423 sql_help.c:1429 sql_help.c:1433 +msgid "token_type" +msgstr "토큰_종류" + +#: sql_help.c:1421 sql_help.c:1424 +msgid "dictionary_name" +msgstr "사전이름" + +#: sql_help.c:1426 sql_help.c:1430 +msgid "old_dictionary" +msgstr "옛사전" + +#: sql_help.c:1427 sql_help.c:1431 +msgid "new_dictionary" +msgstr "새사전" + +#: sql_help.c:1526 sql_help.c:1540 sql_help.c:1543 sql_help.c:1544 +#: sql_help.c:3042 +msgid "attribute_name" +msgstr "속성이름" + +#: sql_help.c:1527 +msgid "new_attribute_name" +msgstr "새속성이름" + +#: sql_help.c:1531 sql_help.c:1535 +msgid "new_enum_value" +msgstr "" + +#: sql_help.c:1532 +msgid "neighbor_enum_value" +msgstr "" + +#: sql_help.c:1534 +msgid "existing_enum_value" +msgstr "" + +#: sql_help.c:1537 +msgid "property" +msgstr "속성" + +#: sql_help.c:1612 sql_help.c:2251 sql_help.c:2260 sql_help.c:2643 +#: sql_help.c:3120 sql_help.c:3571 sql_help.c:3750 sql_help.c:3786 +#: sql_help.c:4098 +msgid "server_name" +msgstr "서버이름" + +#: sql_help.c:1644 sql_help.c:1647 sql_help.c:3135 +msgid "view_option_name" +msgstr "뷰_옵션이름" + +#: sql_help.c:1645 sql_help.c:3136 +msgid "view_option_value" +msgstr "" + +#: sql_help.c:1666 sql_help.c:1667 sql_help.c:4659 sql_help.c:4660 +msgid "table_and_columns" +msgstr "테이블과_칼럼" + +#: sql_help.c:1668 sql_help.c:1912 sql_help.c:3619 sql_help.c:3963 +#: sql_help.c:4661 +msgid "where option can be one of:" +msgstr "옵션 사용법:" + +#: sql_help.c:1669 sql_help.c:1670 sql_help.c:1914 sql_help.c:1917 +#: sql_help.c:2096 sql_help.c:3620 sql_help.c:3621 sql_help.c:3622 +#: sql_help.c:3623 sql_help.c:3624 sql_help.c:3625 sql_help.c:3626 +#: sql_help.c:3627 sql_help.c:4662 sql_help.c:4663 sql_help.c:4664 +#: sql_help.c:4665 sql_help.c:4666 sql_help.c:4667 sql_help.c:4668 +#: sql_help.c:4669 +msgid "boolean" +msgstr "" + +#: sql_help.c:1671 sql_help.c:4671 +msgid "and table_and_columns is:" +msgstr "테이블과_칼럼 사용법:" + +#: sql_help.c:1687 sql_help.c:4443 sql_help.c:4445 sql_help.c:4469 +msgid "transaction_mode" +msgstr "트랜잭션모드" + +#: sql_help.c:1688 sql_help.c:4446 sql_help.c:4470 +msgid "where transaction_mode is one of:" +msgstr "트랜잭션모드 사용법:" + +#: sql_help.c:1697 sql_help.c:4303 sql_help.c:4312 sql_help.c:4316 +#: sql_help.c:4320 sql_help.c:4323 sql_help.c:4542 sql_help.c:4551 +#: sql_help.c:4555 sql_help.c:4559 sql_help.c:4562 sql_help.c:4762 +#: sql_help.c:4771 sql_help.c:4775 sql_help.c:4779 sql_help.c:4782 +msgid "argument" +msgstr "인자" + +#: sql_help.c:1787 +msgid "relation_name" +msgstr "릴레이션이름" + +#: sql_help.c:1792 sql_help.c:3746 sql_help.c:4094 +msgid "domain_name" +msgstr "도메인이름" + +#: sql_help.c:1814 +msgid "policy_name" +msgstr "정책이름" + +#: sql_help.c:1827 +msgid "rule_name" +msgstr "룰이름" + +#: sql_help.c:1846 +msgid "text" +msgstr "" + +#: sql_help.c:1871 sql_help.c:3930 sql_help.c:4135 +msgid "transaction_id" +msgstr "트랜잭션_id" + +#: sql_help.c:1902 sql_help.c:1909 sql_help.c:3856 +msgid "filename" +msgstr "파일이름" + +#: sql_help.c:1903 sql_help.c:1910 sql_help.c:2583 sql_help.c:2584 +#: sql_help.c:2585 +msgid "command" +msgstr "명령어" + +#: sql_help.c:1905 sql_help.c:2582 sql_help.c:2994 sql_help.c:3171 +#: sql_help.c:3840 sql_help.c:4286 sql_help.c:4288 sql_help.c:4376 +#: sql_help.c:4378 sql_help.c:4525 sql_help.c:4527 sql_help.c:4630 +#: sql_help.c:4745 sql_help.c:4747 +msgid "condition" +msgstr "조건" + +#: sql_help.c:1908 sql_help.c:2411 sql_help.c:2877 sql_help.c:3137 +#: sql_help.c:3155 sql_help.c:3821 +msgid "query" +msgstr "쿼리문" + +#: sql_help.c:1913 +msgid "format_name" +msgstr "입출력양식이름" + +#: sql_help.c:1915 +msgid "delimiter_character" +msgstr "구분문자" + +#: sql_help.c:1916 +msgid "null_string" +msgstr "널문자열" + +#: sql_help.c:1918 +msgid "quote_character" +msgstr "인용부호" + +#: sql_help.c:1919 +msgid "escape_character" +msgstr "이스케이프 문자" + +#: sql_help.c:1923 +msgid "encoding_name" +msgstr "인코딩이름" + +#: sql_help.c:1934 +msgid "access_method_type" +msgstr "" + +#: sql_help.c:2005 sql_help.c:2024 sql_help.c:2027 +msgid "arg_data_type" +msgstr "인자자료형" + +#: sql_help.c:2006 sql_help.c:2028 sql_help.c:2036 +msgid "sfunc" +msgstr "" + +#: sql_help.c:2007 sql_help.c:2029 sql_help.c:2037 +msgid "state_data_type" +msgstr "" + +#: sql_help.c:2008 sql_help.c:2030 sql_help.c:2038 +msgid "state_data_size" +msgstr "" + +#: sql_help.c:2009 sql_help.c:2031 sql_help.c:2039 +msgid "ffunc" +msgstr "" + +#: sql_help.c:2010 sql_help.c:2040 +msgid "combinefunc" +msgstr "" + +#: sql_help.c:2011 sql_help.c:2041 +msgid "serialfunc" +msgstr "" + +#: sql_help.c:2012 sql_help.c:2042 +msgid "deserialfunc" +msgstr "" + +#: sql_help.c:2013 sql_help.c:2032 sql_help.c:2043 +msgid "initial_condition" +msgstr "" + +#: sql_help.c:2014 sql_help.c:2044 +msgid "msfunc" +msgstr "" + +#: sql_help.c:2015 sql_help.c:2045 +msgid "minvfunc" +msgstr "" + +#: sql_help.c:2016 sql_help.c:2046 +msgid "mstate_data_type" +msgstr "" + +#: sql_help.c:2017 sql_help.c:2047 +msgid "mstate_data_size" +msgstr "" + +#: sql_help.c:2018 sql_help.c:2048 +msgid "mffunc" +msgstr "" + +#: sql_help.c:2019 sql_help.c:2049 +msgid "minitial_condition" +msgstr "" + +#: sql_help.c:2020 sql_help.c:2050 +msgid "sort_operator" +msgstr "정렬연산자" + +#: sql_help.c:2033 +msgid "or the old syntax" +msgstr "또는 옛날 구문" + +#: sql_help.c:2035 +msgid "base_type" +msgstr "기본자료형" + +#: sql_help.c:2092 sql_help.c:2133 +msgid "locale" +msgstr "로케일" + +#: sql_help.c:2093 sql_help.c:2134 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2094 sql_help.c:2135 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2095 sql_help.c:4188 +msgid "provider" +msgstr "제공자" + +#: sql_help.c:2097 sql_help.c:2189 +msgid "version" +msgstr "버전" + +#: sql_help.c:2099 +msgid "existing_collation" +msgstr "" + +#: sql_help.c:2109 +msgid "source_encoding" +msgstr "원래인코딩" + +#: sql_help.c:2110 +msgid "dest_encoding" +msgstr "대상인코딩" + +#: sql_help.c:2131 sql_help.c:2917 +msgid "template" +msgstr "템플릿" + +#: sql_help.c:2132 +msgid "encoding" +msgstr "인코딩" + +#: sql_help.c:2159 +msgid "constraint" +msgstr "제약조건" + +#: sql_help.c:2160 +msgid "where constraint is:" +msgstr "제약조건 사용법:" + +#: sql_help.c:2174 sql_help.c:2580 sql_help.c:2990 +msgid "event" +msgstr "이벤트" + +#: sql_help.c:2175 +msgid "filter_variable" +msgstr "" + +#: sql_help.c:2263 sql_help.c:2812 +msgid "where column_constraint is:" +msgstr "칼럼_제약조건 사용법:" + +#: sql_help.c:2300 +msgid "rettype" +msgstr "" + +#: sql_help.c:2302 +msgid "column_type" +msgstr "" + +#: sql_help.c:2311 sql_help.c:2511 +msgid "definition" +msgstr "함수정의" + +#: sql_help.c:2312 sql_help.c:2512 +msgid "obj_file" +msgstr "오브젝트파일" + +#: sql_help.c:2313 sql_help.c:2513 +msgid "link_symbol" +msgstr "연결할_함수명" + +#: sql_help.c:2351 sql_help.c:2565 sql_help.c:3109 +msgid "uid" +msgstr "" + +#: sql_help.c:2366 sql_help.c:2407 sql_help.c:2781 sql_help.c:2794 +#: sql_help.c:2808 sql_help.c:2873 +msgid "method" +msgstr "색인방법" + +#: sql_help.c:2371 +msgid "opclass_parameter" +msgstr "opclass_매개변수" + +#: sql_help.c:2388 +msgid "call_handler" +msgstr "" + +#: sql_help.c:2389 +msgid "inline_handler" +msgstr "" + +#: sql_help.c:2390 +msgid "valfunction" +msgstr "구문검사함수" + +#: sql_help.c:2429 +msgid "com_op" +msgstr "" + +#: sql_help.c:2430 +msgid "neg_op" +msgstr "" + +#: sql_help.c:2448 +msgid "family_name" +msgstr "" + +#: sql_help.c:2459 +msgid "storage_type" +msgstr "스토리지_유형" + +#: sql_help.c:2586 sql_help.c:2997 +msgid "where event can be one of:" +msgstr "이벤트 사용법:" + +#: sql_help.c:2605 sql_help.c:2607 +msgid "schema_element" +msgstr "" + +#: sql_help.c:2644 +msgid "server_type" +msgstr "서버_종류" + +#: sql_help.c:2645 +msgid "server_version" +msgstr "서버_버전" + +#: sql_help.c:2646 sql_help.c:3748 sql_help.c:4096 +msgid "fdw_name" +msgstr "fdw_이름" + +#: sql_help.c:2659 +msgid "statistics_name" +msgstr "통계정보_이름" + +#: sql_help.c:2660 +msgid "statistics_kind" +msgstr "통계정보_종류" + +#: sql_help.c:2674 +msgid "subscription_name" +msgstr "구독_이름" + +#: sql_help.c:2774 +msgid "source_table" +msgstr "원본테이블" + +#: sql_help.c:2775 +msgid "like_option" +msgstr "LIKE구문옵션" + +#: sql_help.c:2841 +msgid "and like_option is:" +msgstr "" + +#: sql_help.c:2890 +msgid "directory" +msgstr "디렉터리" + +#: sql_help.c:2904 +msgid "parser_name" +msgstr "구문분석기_이름" + +#: sql_help.c:2905 +msgid "source_config" +msgstr "원본_설정" + +#: sql_help.c:2934 +msgid "start_function" +msgstr "시작_함수" + +#: sql_help.c:2935 +msgid "gettoken_function" +msgstr "gettoken함수" + +#: sql_help.c:2936 +msgid "end_function" +msgstr "종료_함수" + +#: sql_help.c:2937 +msgid "lextypes_function" +msgstr "lextypes함수" + +#: sql_help.c:2938 +msgid "headline_function" +msgstr "headline함수" + +#: sql_help.c:2950 +msgid "init_function" +msgstr "init함수" + +#: sql_help.c:2951 +msgid "lexize_function" +msgstr "lexize함수" + +#: sql_help.c:2964 +msgid "from_sql_function_name" +msgstr "" + +#: sql_help.c:2966 +msgid "to_sql_function_name" +msgstr "" + +#: sql_help.c:2992 +msgid "referenced_table_name" +msgstr "" + +#: sql_help.c:2993 +msgid "transition_relation_name" +msgstr "전달_릴레이션이름" + +#: sql_help.c:2996 +msgid "arguments" +msgstr "인자들" + +#: sql_help.c:3046 sql_help.c:4221 +msgid "label" +msgstr "" + +#: sql_help.c:3048 +msgid "subtype" +msgstr "" + +#: sql_help.c:3049 +msgid "subtype_operator_class" +msgstr "" + +#: sql_help.c:3051 +msgid "canonical_function" +msgstr "" + +#: sql_help.c:3052 +msgid "subtype_diff_function" +msgstr "" + +#: sql_help.c:3054 +msgid "input_function" +msgstr "입력함수" + +#: sql_help.c:3055 +msgid "output_function" +msgstr "출력함수" + +#: sql_help.c:3056 +msgid "receive_function" +msgstr "받는함수" + +#: sql_help.c:3057 +msgid "send_function" +msgstr "주는함수" + +#: sql_help.c:3058 +msgid "type_modifier_input_function" +msgstr "" + +#: sql_help.c:3059 +msgid "type_modifier_output_function" +msgstr "" + +#: sql_help.c:3060 +msgid "analyze_function" +msgstr "분석함수" + +#: sql_help.c:3061 +msgid "internallength" +msgstr "" + +#: sql_help.c:3062 +msgid "alignment" +msgstr "정렬" + +#: sql_help.c:3063 +msgid "storage" +msgstr "스토리지" + +#: sql_help.c:3064 +msgid "like_type" +msgstr "" + +#: sql_help.c:3065 +msgid "category" +msgstr "" + +#: sql_help.c:3066 +msgid "preferred" +msgstr "" + +#: sql_help.c:3067 +msgid "default" +msgstr "기본값" + +#: sql_help.c:3068 +msgid "element" +msgstr "요소" + +#: sql_help.c:3069 +msgid "delimiter" +msgstr "구분자" + +#: sql_help.c:3070 +msgid "collatable" +msgstr "" + +#: sql_help.c:3167 sql_help.c:3816 sql_help.c:4281 sql_help.c:4370 +#: sql_help.c:4520 sql_help.c:4620 sql_help.c:4740 +msgid "with_query" +msgstr "" + +#: sql_help.c:3169 sql_help.c:3818 sql_help.c:4300 sql_help.c:4306 +#: sql_help.c:4309 sql_help.c:4313 sql_help.c:4317 sql_help.c:4325 +#: sql_help.c:4539 sql_help.c:4545 sql_help.c:4548 sql_help.c:4552 +#: sql_help.c:4556 sql_help.c:4564 sql_help.c:4622 sql_help.c:4759 +#: sql_help.c:4765 sql_help.c:4768 sql_help.c:4772 sql_help.c:4776 +#: sql_help.c:4784 +msgid "alias" +msgstr "별칭" + +#: sql_help.c:3170 sql_help.c:4285 sql_help.c:4327 sql_help.c:4329 +#: sql_help.c:4375 sql_help.c:4524 sql_help.c:4566 sql_help.c:4568 +#: sql_help.c:4629 sql_help.c:4744 sql_help.c:4786 sql_help.c:4788 +msgid "from_item" +msgstr "" + +#: sql_help.c:3172 sql_help.c:3653 sql_help.c:3897 sql_help.c:4631 +msgid "cursor_name" +msgstr "커서이름" + +#: sql_help.c:3173 sql_help.c:3824 sql_help.c:4632 +msgid "output_expression" +msgstr "출력표현식" + +#: sql_help.c:3174 sql_help.c:3825 sql_help.c:4284 sql_help.c:4373 +#: sql_help.c:4523 sql_help.c:4633 sql_help.c:4743 +msgid "output_name" +msgstr "" + +#: sql_help.c:3190 +msgid "code" +msgstr "" + +#: sql_help.c:3595 +msgid "parameter" +msgstr "매개변수" + +#: sql_help.c:3617 sql_help.c:3618 sql_help.c:3922 +msgid "statement" +msgstr "명령구문" + +#: sql_help.c:3652 sql_help.c:3896 +msgid "direction" +msgstr "방향" + +#: sql_help.c:3654 sql_help.c:3898 +msgid "where direction can be empty or one of:" +msgstr "방향 자리는 비워두거나 다음 중 하나:" + +#: sql_help.c:3655 sql_help.c:3656 sql_help.c:3657 sql_help.c:3658 +#: sql_help.c:3659 sql_help.c:3899 sql_help.c:3900 sql_help.c:3901 +#: sql_help.c:3902 sql_help.c:3903 sql_help.c:4294 sql_help.c:4296 +#: sql_help.c:4384 sql_help.c:4386 sql_help.c:4533 sql_help.c:4535 +#: sql_help.c:4688 sql_help.c:4690 sql_help.c:4753 sql_help.c:4755 +msgid "count" +msgstr "출력개수" + +#: sql_help.c:3741 sql_help.c:4089 +msgid "sequence_name" +msgstr "시퀀스이름" + +#: sql_help.c:3754 sql_help.c:4102 +msgid "arg_name" +msgstr "인자이름" + +#: sql_help.c:3755 sql_help.c:4103 +msgid "arg_type" +msgstr "인자자료형" + +#: sql_help.c:3760 sql_help.c:4108 +msgid "loid" +msgstr "" + +#: sql_help.c:3784 +msgid "remote_schema" +msgstr "원격_스키마" + +#: sql_help.c:3787 +msgid "local_schema" +msgstr "로컬_스키마" + +#: sql_help.c:3822 +msgid "conflict_target" +msgstr "" + +#: sql_help.c:3823 +msgid "conflict_action" +msgstr "" + +#: sql_help.c:3826 +msgid "where conflict_target can be one of:" +msgstr "conflict_target 사용법:" + +#: sql_help.c:3827 +msgid "index_column_name" +msgstr "인덱스칼럼이름" + +#: sql_help.c:3828 +msgid "index_expression" +msgstr "인덱스표현식" + +#: sql_help.c:3831 +msgid "index_predicate" +msgstr "" + +#: sql_help.c:3833 +msgid "and conflict_action is one of:" +msgstr "conflict_action 사용법:" + +#: sql_help.c:3839 sql_help.c:4628 +msgid "sub-SELECT" +msgstr "" + +#: sql_help.c:3848 sql_help.c:3911 sql_help.c:4604 +msgid "channel" +msgstr "" + +#: sql_help.c:3870 +msgid "lockmode" +msgstr "" + +#: sql_help.c:3871 +msgid "where lockmode is one of:" +msgstr "lockmode 사용법:" + +#: sql_help.c:3912 +msgid "payload" +msgstr "" + +#: sql_help.c:3939 +msgid "old_role" +msgstr "기존롤" + +#: sql_help.c:3940 +msgid "new_role" +msgstr "새롤" + +#: sql_help.c:3971 sql_help.c:4143 sql_help.c:4151 +msgid "savepoint_name" +msgstr "savepoint_name" + +#: sql_help.c:4287 sql_help.c:4339 sql_help.c:4526 sql_help.c:4578 +#: sql_help.c:4746 sql_help.c:4798 +msgid "grouping_element" +msgstr "" + +#: sql_help.c:4289 sql_help.c:4379 sql_help.c:4528 sql_help.c:4748 +msgid "window_name" +msgstr "윈도우이름" + +#: sql_help.c:4290 sql_help.c:4380 sql_help.c:4529 sql_help.c:4749 +msgid "window_definition" +msgstr "원도우정의" + +#: sql_help.c:4291 sql_help.c:4305 sql_help.c:4343 sql_help.c:4381 +#: sql_help.c:4530 sql_help.c:4544 sql_help.c:4582 sql_help.c:4750 +#: sql_help.c:4764 sql_help.c:4802 +msgid "select" +msgstr "" + +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4757 +msgid "where from_item can be one of:" +msgstr "" + +#: sql_help.c:4301 sql_help.c:4307 sql_help.c:4310 sql_help.c:4314 +#: sql_help.c:4326 sql_help.c:4540 sql_help.c:4546 sql_help.c:4549 +#: sql_help.c:4553 sql_help.c:4565 sql_help.c:4760 sql_help.c:4766 +#: sql_help.c:4769 sql_help.c:4773 sql_help.c:4785 +msgid "column_alias" +msgstr "칼럼별칭" + +#: sql_help.c:4302 sql_help.c:4541 sql_help.c:4761 +msgid "sampling_method" +msgstr "표본추출방법" + +#: sql_help.c:4304 sql_help.c:4543 sql_help.c:4763 +msgid "seed" +msgstr "" + +#: sql_help.c:4308 sql_help.c:4341 sql_help.c:4547 sql_help.c:4580 +#: sql_help.c:4767 sql_help.c:4800 +msgid "with_query_name" +msgstr "" + +#: sql_help.c:4318 sql_help.c:4321 sql_help.c:4324 sql_help.c:4557 +#: sql_help.c:4560 sql_help.c:4563 sql_help.c:4777 sql_help.c:4780 +#: sql_help.c:4783 +msgid "column_definition" +msgstr "칼럼정의" + +#: sql_help.c:4328 sql_help.c:4567 sql_help.c:4787 +msgid "join_type" +msgstr "" + +#: sql_help.c:4330 sql_help.c:4569 sql_help.c:4789 +msgid "join_condition" +msgstr "" + +#: sql_help.c:4331 sql_help.c:4570 sql_help.c:4790 +msgid "join_column" +msgstr "" + +#: sql_help.c:4332 sql_help.c:4571 sql_help.c:4791 +msgid "and grouping_element can be one of:" +msgstr "" + +#: sql_help.c:4340 sql_help.c:4579 sql_help.c:4799 +msgid "and with_query is:" +msgstr "" + +#: sql_help.c:4344 sql_help.c:4583 sql_help.c:4803 +msgid "values" +msgstr "값" + +#: sql_help.c:4345 sql_help.c:4584 sql_help.c:4804 +msgid "insert" +msgstr "" + +#: sql_help.c:4346 sql_help.c:4585 sql_help.c:4805 +msgid "update" +msgstr "" + +#: sql_help.c:4347 sql_help.c:4586 sql_help.c:4806 +msgid "delete" +msgstr "" + +#: sql_help.c:4374 +msgid "new_table" +msgstr "새테이블" + +#: sql_help.c:4399 +msgid "timezone" +msgstr "" + +#: sql_help.c:4444 +msgid "snapshot_id" +msgstr "" + +#: sql_help.c:4686 +msgid "sort_expression" +msgstr "" + +#: sql_help.c:4813 sql_help.c:5791 +msgid "abort the current transaction" +msgstr "현재 트랜잭션 중지함" + +#: sql_help.c:4819 +msgid "change the definition of an aggregate function" +msgstr "집계함수 정보 바꾸기" + +#: sql_help.c:4825 +msgid "change the definition of a collation" +msgstr "collation 정의 바꾸기" + +#: sql_help.c:4831 +msgid "change the definition of a conversion" +msgstr "문자코드 변환규칙(conversion) 정보 바꾸기" + +#: sql_help.c:4837 +msgid "change a database" +msgstr "데이터베이스 변경" + +#: sql_help.c:4843 +msgid "define default access privileges" +msgstr "기본 접근 권한 정의" + +#: sql_help.c:4849 +msgid "change the definition of a domain" +msgstr "도메인 정보 바꾸기" + +#: sql_help.c:4855 +msgid "change the definition of an event trigger" +msgstr "트리거 정보 바꾸기" + +#: sql_help.c:4861 +msgid "change the definition of an extension" +msgstr "확장모듈 정의 바꾸기" + +#: sql_help.c:4867 +msgid "change the definition of a foreign-data wrapper" +msgstr "외부 데이터 래퍼 정의 바꾸기" + +#: sql_help.c:4873 +msgid "change the definition of a foreign table" +msgstr "외부 테이블 정의 바꾸기" + +#: sql_help.c:4879 +msgid "change the definition of a function" +msgstr "함수 정보 바꾸기" + +#: sql_help.c:4885 +msgid "change role name or membership" +msgstr "롤 이름이나 맴버쉽 바꾸기" + +#: sql_help.c:4891 +msgid "change the definition of an index" +msgstr "인덱스 정의 바꾸기" + +#: sql_help.c:4897 +msgid "change the definition of a procedural language" +msgstr "procedural language 정보 바꾸기" + +#: sql_help.c:4903 +msgid "change the definition of a large object" +msgstr "대형 객체 정의 바꾸기" + +#: sql_help.c:4909 +msgid "change the definition of a materialized view" +msgstr "materialized 뷰 정의 바꾸기" + +#: sql_help.c:4915 +msgid "change the definition of an operator" +msgstr "연산자 정의 바꾸기" + +#: sql_help.c:4921 +msgid "change the definition of an operator class" +msgstr "연산자 클래스 정보 바꾸기" + +#: sql_help.c:4927 +msgid "change the definition of an operator family" +msgstr "연산자 부류의 정의 바꾸기" + +#: sql_help.c:4933 +msgid "change the definition of a row level security policy" +msgstr "로우 단위 보안 정책의 정의 바꾸기" + +#: sql_help.c:4939 +msgid "change the definition of a procedure" +msgstr "프로시져 정의 바꾸기" + +#: sql_help.c:4945 +msgid "change the definition of a publication" +msgstr "발행 정보 바꾸기" + +#: sql_help.c:4951 sql_help.c:5053 +msgid "change a database role" +msgstr "데이터베이스 롤 변경" + +#: sql_help.c:4957 +msgid "change the definition of a routine" +msgstr "루틴 정의 바꾸기" + +#: sql_help.c:4963 +msgid "change the definition of a rule" +msgstr "룰 정의 바꾸기" + +#: sql_help.c:4969 +msgid "change the definition of a schema" +msgstr "스키마 이름 바꾸기" + +#: sql_help.c:4975 +msgid "change the definition of a sequence generator" +msgstr "시퀀스 정보 바꾸기" + +#: sql_help.c:4981 +msgid "change the definition of a foreign server" +msgstr "외부 서버 정의 바꾸기" + +#: sql_help.c:4987 +msgid "change the definition of an extended statistics object" +msgstr "확장 통계정보 객체 정의 바꾸기" + +#: sql_help.c:4993 +msgid "change the definition of a subscription" +msgstr "구독 정보 바꾸기" + +#: sql_help.c:4999 +msgid "change a server configuration parameter" +msgstr "서버 환경 설정 매개 변수 바꾸기" + +#: sql_help.c:5005 +msgid "change the definition of a table" +msgstr "테이블 정보 바꾸기" + +#: sql_help.c:5011 +msgid "change the definition of a tablespace" +msgstr "테이블스페이스 정의 바꾸기" + +#: sql_help.c:5017 +msgid "change the definition of a text search configuration" +msgstr "텍스트 검색 구성 정의 바꾸기" + +#: sql_help.c:5023 +msgid "change the definition of a text search dictionary" +msgstr "텍스트 검색 사전 정의 바꾸기" + +#: sql_help.c:5029 +msgid "change the definition of a text search parser" +msgstr "텍스트 검색 파서 정의 바꾸기" + +#: sql_help.c:5035 +msgid "change the definition of a text search template" +msgstr "텍스트 검색 템플릿 정의 바꾸기" + +#: sql_help.c:5041 +msgid "change the definition of a trigger" +msgstr "트리거 정보 바꾸기" + +#: sql_help.c:5047 +msgid "change the definition of a type" +msgstr "자료형 정의 바꾸기" + +#: sql_help.c:5059 +msgid "change the definition of a user mapping" +msgstr "사용자 매핑 정의 바꾸기" + +#: sql_help.c:5065 +msgid "change the definition of a view" +msgstr "뷰 정의 바꾸기" + +#: sql_help.c:5071 +msgid "collect statistics about a database" +msgstr "데이터베이스 사용 통계 정보를 갱신함" + +#: sql_help.c:5077 sql_help.c:5869 +msgid "start a transaction block" +msgstr "트랜잭션 블럭을 시작함" + +#: sql_help.c:5083 +msgid "invoke a procedure" +msgstr "프로시져 호출" + +#: sql_help.c:5089 +msgid "force a write-ahead log checkpoint" +msgstr "트랜잭션 로그를 강제로 체크포인트 함" + +#: sql_help.c:5095 +msgid "close a cursor" +msgstr "커서 닫기" + +#: sql_help.c:5101 +msgid "cluster a table according to an index" +msgstr "지정한 인덱스 기준으로 테이블 자료를 다시 저장함" + +#: sql_help.c:5107 +msgid "define or change the comment of an object" +msgstr "해당 개체의 코멘트를 지정하거나 수정함" + +#: sql_help.c:5113 sql_help.c:5671 +msgid "commit the current transaction" +msgstr "현재 트랜잭션 commit" + +#: sql_help.c:5119 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "two-phase 커밋을 위해 먼저 준비된 트랜잭션을 커밋하세요." + +#: sql_help.c:5125 +msgid "copy data between a file and a table" +msgstr "테이블과 파일 사이 자료를 복사함" + +#: sql_help.c:5131 +msgid "define a new access method" +msgstr "새 접속 방법 정의" + +#: sql_help.c:5137 +msgid "define a new aggregate function" +msgstr "새 집계합수 만들기" + +#: sql_help.c:5143 +msgid "define a new cast" +msgstr "새 형변환자 만들기" + +#: sql_help.c:5149 +msgid "define a new collation" +msgstr "새 collation 만들기" + +#: sql_help.c:5155 +msgid "define a new encoding conversion" +msgstr "새 문자코드변환규칙(conversion) 만들기" + +#: sql_help.c:5161 +msgid "create a new database" +msgstr "데이터베이스 생성" + +#: sql_help.c:5167 +msgid "define a new domain" +msgstr "새 도메인 만들기" + +#: sql_help.c:5173 +msgid "define a new event trigger" +msgstr "새 이벤트 트리거 만들기" + +#: sql_help.c:5179 +msgid "install an extension" +msgstr "확장 모듈 설치" + +#: sql_help.c:5185 +msgid "define a new foreign-data wrapper" +msgstr "새 외부 데이터 래퍼 정의" + +#: sql_help.c:5191 +msgid "define a new foreign table" +msgstr "새 외부 테이블 정의" + +#: sql_help.c:5197 +msgid "define a new function" +msgstr "새 함수 만들기" + +#: sql_help.c:5203 sql_help.c:5263 sql_help.c:5365 +msgid "define a new database role" +msgstr "새 데이터베이스 롤 만들기" + +#: sql_help.c:5209 +msgid "define a new index" +msgstr "새 인덱스 만들기" + +#: sql_help.c:5215 +msgid "define a new procedural language" +msgstr "새 프로시주얼 언어 만들기" + +#: sql_help.c:5221 +msgid "define a new materialized view" +msgstr "새 materialized 뷰 만들기" + +#: sql_help.c:5227 +msgid "define a new operator" +msgstr "새 연산자 만들기" + +#: sql_help.c:5233 +msgid "define a new operator class" +msgstr "새 연잔자 클래스 만들기" + +#: sql_help.c:5239 +msgid "define a new operator family" +msgstr "새 연산자 부류 만들기" + +#: sql_help.c:5245 +msgid "define a new row level security policy for a table" +msgstr "특정 테이블에 로우 단위 보안 정책 정의" + +#: sql_help.c:5251 +msgid "define a new procedure" +msgstr "새 프로시져 만들기" + +#: sql_help.c:5257 +msgid "define a new publication" +msgstr "새 발행 만들기" + +#: sql_help.c:5269 +msgid "define a new rewrite rule" +msgstr "새 룰(rule) 만들기" + +#: sql_help.c:5275 +msgid "define a new schema" +msgstr "새 스키마(schema) 만들기" + +#: sql_help.c:5281 +msgid "define a new sequence generator" +msgstr "새 시퀀스 만들기" + +#: sql_help.c:5287 +msgid "define a new foreign server" +msgstr "새 외부 서버 정의" + +#: sql_help.c:5293 +msgid "define extended statistics" +msgstr "새 확장 통계정보 만들기" + +#: sql_help.c:5299 +msgid "define a new subscription" +msgstr "새 구독 만들기" + +#: sql_help.c:5305 +msgid "define a new table" +msgstr "새 테이블 만들기" + +#: sql_help.c:5311 sql_help.c:5827 +msgid "define a new table from the results of a query" +msgstr "쿼리 결과를 새 테이블로 만들기" + +#: sql_help.c:5317 +msgid "define a new tablespace" +msgstr "새 테이블스페이스 만들기" + +#: sql_help.c:5323 +msgid "define a new text search configuration" +msgstr "새 텍스트 검색 구성 정의" + +#: sql_help.c:5329 +msgid "define a new text search dictionary" +msgstr "새 텍스트 검색 사전 정의" + +#: sql_help.c:5335 +msgid "define a new text search parser" +msgstr "새 텍스트 검색 파서 정의" + +#: sql_help.c:5341 +msgid "define a new text search template" +msgstr "새 텍스트 검색 템플릿 정의" + +#: sql_help.c:5347 +msgid "define a new transform" +msgstr "새 transform 만들기" + +#: sql_help.c:5353 +msgid "define a new trigger" +msgstr "새 트리거 만들기" + +#: sql_help.c:5359 +msgid "define a new data type" +msgstr "새 자료형 만들기" + +#: sql_help.c:5371 +msgid "define a new mapping of a user to a foreign server" +msgstr "사용자와 외부 서버 간의 새 매핑 정의" + +#: sql_help.c:5377 +msgid "define a new view" +msgstr "새 view 만들기" + +#: sql_help.c:5383 +msgid "deallocate a prepared statement" +msgstr "준비된 구문(prepared statement) 지우기" + +#: sql_help.c:5389 +msgid "define a cursor" +msgstr "커서 지정" + +#: sql_help.c:5395 +msgid "delete rows of a table" +msgstr "테이블의 자료 삭제" + +#: sql_help.c:5401 +msgid "discard session state" +msgstr "세션 상태 삭제" + +#: sql_help.c:5407 +msgid "execute an anonymous code block" +msgstr "임의 코드 블록 실행" + +#: sql_help.c:5413 +msgid "remove an access method" +msgstr "접근 방법 삭제" + +#: sql_help.c:5419 +msgid "remove an aggregate function" +msgstr "집계 함수 삭제" + +#: sql_help.c:5425 +msgid "remove a cast" +msgstr "형변환자 삭제" + +#: sql_help.c:5431 +msgid "remove a collation" +msgstr "collation 삭제" + +#: sql_help.c:5437 +msgid "remove a conversion" +msgstr "문자코드 변환규칙(conversion) 삭제" + +#: sql_help.c:5443 +msgid "remove a database" +msgstr "데이터베이스 삭제" + +#: sql_help.c:5449 +msgid "remove a domain" +msgstr "도메인 삭제" + +#: sql_help.c:5455 +msgid "remove an event trigger" +msgstr "이벤트 트리거 삭제" + +#: sql_help.c:5461 +msgid "remove an extension" +msgstr "확장 모듈 삭제" + +#: sql_help.c:5467 +msgid "remove a foreign-data wrapper" +msgstr "외부 데이터 래퍼 제거" + +#: sql_help.c:5473 +msgid "remove a foreign table" +msgstr "외부 테이블 삭제" + +#: sql_help.c:5479 +msgid "remove a function" +msgstr "함수 삭제" + +#: sql_help.c:5485 sql_help.c:5551 sql_help.c:5653 +msgid "remove a database role" +msgstr "데이터베이스 롤 삭제" + +#: sql_help.c:5491 +msgid "remove an index" +msgstr "인덱스 삭제" + +#: sql_help.c:5497 +msgid "remove a procedural language" +msgstr "프로시주얼 언어 삭제" + +#: sql_help.c:5503 +msgid "remove a materialized view" +msgstr "materialized 뷰 삭제" + +#: sql_help.c:5509 +msgid "remove an operator" +msgstr "연산자 삭제" + +#: sql_help.c:5515 +msgid "remove an operator class" +msgstr "연산자 클래스 삭제" + +#: sql_help.c:5521 +msgid "remove an operator family" +msgstr "연산자 부류 삭제" + +#: sql_help.c:5527 +msgid "remove database objects owned by a database role" +msgstr "데이터베이스 롤로 권한이 부여된 데이터베이스 개체들을 삭제하세요" + +#: sql_help.c:5533 +msgid "remove a row level security policy from a table" +msgstr "특정 테이블에 정의된 로우 단위 보안 정책 삭제" + +#: sql_help.c:5539 +msgid "remove a procedure" +msgstr "프로시져 삭제" + +#: sql_help.c:5545 +msgid "remove a publication" +msgstr "발행 삭제" + +#: sql_help.c:5557 +msgid "remove a routine" +msgstr "루틴 삭제" + +#: sql_help.c:5563 +msgid "remove a rewrite rule" +msgstr "룰(rule) 삭제" + +#: sql_help.c:5569 +msgid "remove a schema" +msgstr "스키마(schema) 삭제" + +#: sql_help.c:5575 +msgid "remove a sequence" +msgstr "시퀀스 삭제" + +#: sql_help.c:5581 +msgid "remove a foreign server descriptor" +msgstr "외부 서버 설명자 제거" + +#: sql_help.c:5587 +msgid "remove extended statistics" +msgstr "확장 통계정보 삭제" + +#: sql_help.c:5593 +msgid "remove a subscription" +msgstr "구독 삭제" + +#: sql_help.c:5599 +msgid "remove a table" +msgstr "테이블 삭제" + +#: sql_help.c:5605 +msgid "remove a tablespace" +msgstr "테이블스페이스 삭제" + +#: sql_help.c:5611 +msgid "remove a text search configuration" +msgstr "텍스트 검색 구성 제거" + +#: sql_help.c:5617 +msgid "remove a text search dictionary" +msgstr "텍스트 검색 사전 제거" + +#: sql_help.c:5623 +msgid "remove a text search parser" +msgstr "텍스트 검색 파서 제거" + +#: sql_help.c:5629 +msgid "remove a text search template" +msgstr "텍스트 검색 템플릿 제거" + +#: sql_help.c:5635 +msgid "remove a transform" +msgstr "transform 삭제" + +#: sql_help.c:5641 +msgid "remove a trigger" +msgstr "트리거 삭제" + +#: sql_help.c:5647 +msgid "remove a data type" +msgstr "자료형 삭제" + +#: sql_help.c:5659 +msgid "remove a user mapping for a foreign server" +msgstr "외부 서버에 대한 사용자 매핑 제거" + +#: sql_help.c:5665 +msgid "remove a view" +msgstr "뷰(view) 삭제" + +#: sql_help.c:5677 +msgid "execute a prepared statement" +msgstr "준비된 구문(prepared statement) 실행" + +#: sql_help.c:5683 +msgid "show the execution plan of a statement" +msgstr "쿼리 실행계획 보기" + +#: sql_help.c:5689 +msgid "retrieve rows from a query using a cursor" +msgstr "해당 커서에서 자료 뽑기" + +#: sql_help.c:5695 +msgid "define access privileges" +msgstr "액세스 권한 지정하기" + +#: sql_help.c:5701 +msgid "import table definitions from a foreign server" +msgstr "외부 서버로부터 테이블 정의 가져오기" + +#: sql_help.c:5707 +msgid "create new rows in a table" +msgstr "테이블 자료 삽입" + +#: sql_help.c:5713 +msgid "listen for a notification" +msgstr "특정 서버 메시지 수신함" + +#: sql_help.c:5719 +msgid "load a shared library file" +msgstr "공유 라이브러리 파일 로드" + +#: sql_help.c:5725 +msgid "lock a table" +msgstr "테이블 잠금" + +#: sql_help.c:5731 +msgid "position a cursor" +msgstr "커서 위치 옮기기" + +#: sql_help.c:5737 +msgid "generate a notification" +msgstr "특정 서버 메시지 발생" + +#: sql_help.c:5743 +msgid "prepare a statement for execution" +msgstr "준비된 구문(prepared statement) 만들기" + +#: sql_help.c:5749 +msgid "prepare the current transaction for two-phase commit" +msgstr "two-phase 커밋을 위해 현재 트랜잭션을 준비함" + +#: sql_help.c:5755 +msgid "change the ownership of database objects owned by a database role" +msgstr "데이터베이스 롤로 권한이 부여된 데이터베이스 개체들의 소유주 바꾸기" + +#: sql_help.c:5761 +msgid "replace the contents of a materialized view" +msgstr "구체화된 뷰의 내용 수정" + +#: sql_help.c:5767 +msgid "rebuild indexes" +msgstr "인덱스 다시 만들기" + +#: sql_help.c:5773 +msgid "destroy a previously defined savepoint" +msgstr "이전 정의된 savepoint를 파기함" + +#: sql_help.c:5779 +msgid "restore the value of a run-time parameter to the default value" +msgstr "실시간 환경 변수값을 초기값으로 다시 지정" + +#: sql_help.c:5785 +msgid "remove access privileges" +msgstr "액세스 권한 해제하기" + +#: sql_help.c:5797 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "two-phase 커밋을 위해 먼저 준비되었던 트랜잭션 실행취소하기" + +#: sql_help.c:5803 +msgid "roll back to a savepoint" +msgstr "savepoint 파기하기" + +#: sql_help.c:5809 +msgid "define a new savepoint within the current transaction" +msgstr "현재 트랜잭션에서 새로운 savepoint 만들기" + +#: sql_help.c:5815 +msgid "define or change a security label applied to an object" +msgstr "해당 개체에 보안 라벨을 정의하거나 변경" + +#: sql_help.c:5821 sql_help.c:5875 sql_help.c:5911 +msgid "retrieve rows from a table or view" +msgstr "테이블이나 뷰의 자료를 출력" + +#: sql_help.c:5833 +msgid "change a run-time parameter" +msgstr "실시간 환경 변수값 바꾸기" + +#: sql_help.c:5839 +msgid "set constraint check timing for the current transaction" +msgstr "현재 트랜잭션에서 제약조건 설정" + +#: sql_help.c:5845 +msgid "set the current user identifier of the current session" +msgstr "현재 세션의 현재 사용자 식별자를 지정" + +#: sql_help.c:5851 +msgid "" +"set the session user identifier and the current user identifier of the " +"current session" +msgstr "현재 세션의 사용자 인증을 지정함 - 사용자 지정" + +#: sql_help.c:5857 +msgid "set the characteristics of the current transaction" +msgstr "현재 트랜잭션의 성질을 지정함" + +#: sql_help.c:5863 +msgid "show the value of a run-time parameter" +msgstr "실시간 환경 변수값들을 보여줌" + +#: sql_help.c:5881 +msgid "empty a table or set of tables" +msgstr "하나 또는 지정한 여러개의 테이블에서 모든 자료 지움" + +#: sql_help.c:5887 +msgid "stop listening for a notification" +msgstr "특정 서버 메시지 수신 기능 끔" + +#: sql_help.c:5893 +msgid "update rows of a table" +msgstr "테이블 자료 갱신" + +#: sql_help.c:5899 +msgid "garbage-collect and optionally analyze a database" +msgstr "물리적인 자료 정리 작업 - 쓰레기값 청소" + +#: sql_help.c:5905 +msgid "compute a set of rows" +msgstr "compute a set of rows" + +#: startup.c:212 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 옵션은 비대화형 모드에서만 사용할 수 있음" + +#: startup.c:299 +#, c-format +msgid "could not connect to server: %s" +msgstr "서버 접속 실패: %s" + +#: startup.c:327 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "\"%s\" 잠금파일을 열 수 없음: %m" + +#: startup.c:439 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"도움말을 보려면 \"help\"를 입력하십시오.\n" +"\n" + +#: startup.c:589 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "출력 매개 변수 \"%s\" 지정할 수 없음" + +#: startup.c:697 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "자세한 도움말은 \"%s --help\"\n" + +#: startup.c:714 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "추가 명령행 인자 \"%s\" 무시됨" + +#: startup.c:763 +#, c-format +msgid "could not find own program executable" +msgstr "실행 가능한 프로그램을 찾을 수 없음" + +#: tab-complete.c:4640 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"탭 자동완성용 쿼리 실패: %s\n" +"사용한 쿼리:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "잘못된 \"%s\" 값을 \"%s\" 변수값으로 사용함: 불린형이어야 함" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "\"%s\" 값은 \"%s\" 변수값으로 사용할 수 없음; 정수형이어야 함" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "잘못된 변수 이름: \"%s\"" + +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"\"%s\" 값은 \"%s\" 변수값으로 사용할 수 없음\n" +"사용할 수 있는 변수값: %s" diff --git a/src/bin/psql/po/ru.po b/src/bin/psql/po/ru.po new file mode 100644 index 000000000000..5e6303c6555c --- /dev/null +++ b/src/bin/psql/po/ru.po @@ -0,0 +1,6933 @@ +# Russian message translation file for psql +# Copyright (C) 2001-2016 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Serguei A. Mokhov , 2001-2005. +# Oleg Bartunov , 2004-2005. +# Sergey Burladyan , 2012. +# Alexander Lakhin , 2012-2017, 2018, 2019, 2020. +msgid "" +msgstr "" +"Project-Id-Version: psql (PostgreSQL current)\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2021-02-08 07:28+0300\n" +"PO-Revision-Date: 2020-11-20 15:23+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "важно: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "ошибка: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "предупреждение: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "не удалось определить текущий каталог: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "неверный исполняемый файл \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "не удалось прочитать исполняемый файл \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "не удалось найти запускаемый файл \"%s\"" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "не удалось перейти в каталог \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "не удалось прочитать символическую ссылку \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "ошибка pclose: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: command.c:1255 command.c:3173 command.c:3222 command.c:3339 input.c:227 +#: mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "нехватка памяти" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "нехватка памяти\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "выяснить эффективный идентификатор пользователя (%ld) не удалось: %s" + +#: ../../common/username.c:45 command.c:559 +msgid "user does not exist" +msgstr "пользователь не существует" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "распознать имя пользователя не удалось (код ошибки: %lu)" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "неисполняемая команда" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "команда не найдена" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "дочерний процесс завершился с кодом возврата %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "дочерний процесс прерван исключением 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "дочерний процесс завершён по сигналу %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "дочерний процесс завершился с нераспознанным состоянием %d" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Сигнал отмены отправлен\n" + +#: ../../fe_utils/cancel.c:165 ../../fe_utils/cancel.c:210 +msgid "Could not send cancel request: " +msgstr "Отправить сигнал отмены не удалось: " + +#: ../../fe_utils/print.c:350 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu строка)" +msgstr[1] "(%lu строки)" +msgstr[2] "(%lu строк)" + +#: ../../fe_utils/print.c:3055 +#, c-format +msgid "Interrupted\n" +msgstr "Прервано\n" + +#: ../../fe_utils/print.c:3119 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "" +"Ошибка добавления заголовка таблицы: превышен предел числа столбцов (%d).\n" + +#: ../../fe_utils/print.c:3159 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "" +"Ошибка добавления ячейки в таблицу: превышен предел числа ячеек (%d).\n" + +#: ../../fe_utils/print.c:3414 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "неверный формат вывода (внутренняя ошибка): %d" + +#: ../../fe_utils/psqlscan.l:694 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "рекурсивное расширение переменной \"%s\" пропускается" + +#: command.c:224 +#, c-format +msgid "invalid command \\%s" +msgstr "неверная команда \\%s" + +#: command.c:226 +#, c-format +msgid "Try \\? for help." +msgstr "Введите \\? для получения справки." + +#: command.c:244 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: лишний аргумент \"%s\" пропущен" + +#: command.c:296 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "" +"команда \\%s игнорируется; добавьте \\endif или нажмите Ctrl-C для " +"завершения текущего блока \\if" + +#: command.c:557 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "не удалось получить домашний каталог пользователя c ид. %ld: %s" + +#: command.c:575 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: не удалось перейти в каталог \"%s\": %m" + +#: command.c:600 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "В данный момент вы не подключены к базе данных.\n" + +#: command.c:613 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" on address \"%s\" at " +"port \"%s\".\n" +msgstr "" +"Вы подключены к базе данных \"%s\" как пользователь \"%s\" (адрес сервера " +"\"%s\", порт \"%s\").\n" + +#: command.c:616 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at " +"port \"%s\".\n" +msgstr "" +"Вы подключены к базе данных \"%s\" как пользователь \"%s\" через сокет в \"%s" +"\", порт \"%s\".\n" + +#: command.c:622 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address " +"\"%s\") at port \"%s\".\n" +msgstr "" +"Вы подключены к базе данных \"%s\" как пользователь \"%s\" (сервер \"%s\": " +"адрес \"%s\", порт \"%s\").\n" + +#: command.c:625 +#, c-format +msgid "" +"You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port " +"\"%s\".\n" +msgstr "" +"Вы подключены к базе данных \"%s\" как пользователь \"%s\" (сервер \"%s\", " +"порт \"%s\").\n" + +#: command.c:965 command.c:1061 command.c:2550 +#, c-format +msgid "no query buffer" +msgstr "нет буфера запросов" + +#: command.c:998 command.c:5171 +#, c-format +msgid "invalid line number: %s" +msgstr "неверный номер строки: %s" + +#: command.c:1052 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "" +"Сервер (версия %s) не поддерживает редактирование исходного кода функции." + +#: command.c:1055 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "" +"Сервер (версия %s) не поддерживает редактирование определения представления." + +#: command.c:1137 +msgid "No changes" +msgstr "Изменений нет" + +#: command.c:1216 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "" +"%s: неверное название кодировки символов или не найдена процедура " +"перекодировки" + +#: command.c:1251 command.c:1992 command.c:3169 command.c:3361 command.c:5273 +#: common.c:174 common.c:223 common.c:388 common.c:1244 common.c:1272 +#: common.c:1380 common.c:1487 common.c:1525 copy.c:488 copy.c:707 help.c:62 +#: large_obj.c:157 large_obj.c:192 large_obj.c:254 startup.c:299 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1258 +msgid "There is no previous error." +msgstr "Ошибки не было." + +#: command.c:1371 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: отсутствует правая скобка" + +#: command.c:1548 command.c:1853 command.c:1867 command.c:1884 command.c:2044 +#: command.c:2281 command.c:2517 command.c:2557 +#, c-format +msgid "\\%s: missing required argument" +msgstr "отсутствует необходимый аргумент \\%s" + +#: command.c:1679 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif не может находиться после \\else" + +#: command.c:1684 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif без соответствующего \\if" + +#: command.c:1748 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else не может находиться после \\else" + +#: command.c:1753 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else без соответствующего \\if" + +#: command.c:1793 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif без соответствующего \\if" + +#: command.c:1948 +msgid "Query buffer is empty." +msgstr "Буфер запроса пуст." + +#: command.c:1970 +msgid "Enter new password: " +msgstr "Введите новый пароль: " + +#: command.c:1971 +msgid "Enter it again: " +msgstr "Повторите его: " + +#: command.c:1975 +#, c-format +msgid "Passwords didn't match." +msgstr "Пароли не совпадают." + +#: command.c:2074 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s: не удалось прочитать значение переменной" + +#: command.c:2177 +msgid "Query buffer reset (cleared)." +msgstr "Буфер запроса сброшен (очищен)." + +#: command.c:2199 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "История записана в файл \"%s\".\n" + +#: command.c:2286 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: имя переменной окружения не может содержать знак \"=\"" + +#: command.c:2347 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "Сервер (версия %s) не поддерживает вывод исходного кода функции." + +#: command.c:2350 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "Сервер (версия %s) не поддерживает вывод определения представлений." + +#: command.c:2357 +#, c-format +msgid "function name is required" +msgstr "требуется имя функции" + +#: command.c:2359 +#, c-format +msgid "view name is required" +msgstr "требуется имя представления" + +#: command.c:2489 +msgid "Timing is on." +msgstr "Секундомер включён." + +#: command.c:2491 +msgid "Timing is off." +msgstr "Секундомер выключен." + +#: command.c:2576 command.c:2604 command.c:3771 command.c:3774 command.c:3777 +#: command.c:3783 command.c:3785 command.c:3793 command.c:3803 command.c:3812 +#: command.c:3826 command.c:3843 command.c:3901 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:2988 startup.c:236 startup.c:287 +msgid "Password: " +msgstr "Пароль: " + +#: command.c:2993 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "Пароль пользователя %s: " + +#: command.c:3047 +#, c-format +msgid "" +"All connection parameters must be supplied because no database connection " +"exists" +msgstr "" +"Без подключения к базе данных необходимо указывать все параметры подключения" + +#: command.c:3367 +#, c-format +msgid "Previous connection kept" +msgstr "Сохранено предыдущее подключение" + +#: command.c:3373 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3420 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at " +"port \"%s\".\n" +msgstr "" +"Сейчас вы подключены к базе данных \"%s\" как пользователь \"%s\" (адрес " +"сервера \"%s\", порт \"%s\").\n" + +#: command.c:3423 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " +"at port \"%s\".\n" +msgstr "" +"Вы подключены к базе данных \"%s\" как пользователь \"%s\" через сокет в \"%s" +"\", порт \"%s\".\n" + +#: command.c:3429 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" on host \"%s" +"\" (address \"%s\") at port \"%s\".\n" +msgstr "" +"Сейчас вы подключены к базе данных \"%s\" как пользователь \"%s\" (сервер " +"\"%s\": адрес \"%s\", порт \"%s\").\n" + +#: command.c:3432 +#, c-format +msgid "" +"You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at " +"port \"%s\".\n" +msgstr "" +"Вы подключены к базе данных \"%s\" как пользователь \"%s\" (сервер \"%s\", " +"порт \"%s\").\n" + +#: command.c:3437 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Вы подключены к базе данных \"%s\" как пользователь \"%s\".\n" + +#: command.c:3470 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, сервер %s)\n" + +#: command.c:3478 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"ПРЕДУПРЕЖДЕНИЕ: %s имеет базовую версию %s, а сервер - %s.\n" +" Часть функций psql может не работать.\n" + +#: command.c:3517 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL-соединение (протокол: %s, шифр: %s, бит: %s, сжатие: %s)\n" + +#: command.c:3518 command.c:3519 command.c:3520 +msgid "unknown" +msgstr "неизвестно" + +#: command.c:3521 help.c:45 +msgid "off" +msgstr "выкл." + +#: command.c:3521 help.c:45 +msgid "on" +msgstr "вкл." + +#: command.c:3535 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "Соединение зашифровано GSSAPI\n" + +#: command.c:3555 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"ПРЕДУПРЕЖДЕНИЕ: Кодовая страница консоли (%u) отличается от основной\n" +" страницы Windows (%u).\n" +" 8-битовые (русские) символы могут отображаться некорректно.\n" +" Подробнее об этом смотрите документацию psql, раздел\n" +" \"Notes for Windows users\".\n" + +#: command.c:3659 +#, c-format +msgid "" +"environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a " +"line number" +msgstr "" +"в переменной окружения PSQL_EDITOR_LINENUMBER_ARG должен быть указан номер " +"строки" + +#: command.c:3688 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "не удалось запустить редактор \"%s\"" + +#: command.c:3690 +#, c-format +msgid "could not start /bin/sh" +msgstr "не удалось запустить /bin/sh" + +#: command.c:3728 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "не удалось найти временный каталог: %s" + +#: command.c:3755 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "не удалось открыть временный файл \"%s\": %m" + +#: command.c:4060 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "" +"\\pset: неоднозначному сокращению \"%s\" соответствует и \"%s\", и \"%s\"" + +#: command.c:4080 +#, c-format +msgid "" +"\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-" +"longtable, troff-ms, unaligned, wrapped" +msgstr "" +"\\pset: допустимые форматы: aligned, asciidoc, csv, html, latex, latex-" +"longtable, troff-ms, unaligned, wrapped" + +#: command.c:4099 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: допустимые стили линий: ascii, old-ascii, unicode" + +#: command.c:4114 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: допустимые стили Unicode-линий границ: single, double" + +#: command.c:4129 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: допустимые стили Unicode-линий столбцов: single, double" + +#: command.c:4144 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: допустимые стили Unicode-линий заголовков: single, double" + +#: command.c:4187 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: символ csv_fieldsep должен быть однобайтовым" + +#: command.c:4192 +#, c-format +msgid "" +"\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage " +"return" +msgstr "" +"\\pset: в качестве csv_fieldsep нельзя выбрать символ кавычек, новой строки " +"или возврата каретки" + +#: command.c:4329 command.c:4517 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "неизвестный параметр \\pset: %s" + +#: command.c:4349 +#, c-format +msgid "Border style is %d.\n" +msgstr "Стиль границ: %d.\n" + +#: command.c:4355 +#, c-format +msgid "Target width is unset.\n" +msgstr "Ширина вывода сброшена.\n" + +#: command.c:4357 +#, c-format +msgid "Target width is %d.\n" +msgstr "Ширина вывода: %d.\n" + +#: command.c:4364 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Расширенный вывод включён.\n" + +#: command.c:4366 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "Расширенный вывод применяется автоматически.\n" + +#: command.c:4368 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Расширенный вывод выключен.\n" + +#: command.c:4374 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "Разделитель полей для CSV: \"%s\".\n" + +#: command.c:4382 command.c:4390 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "Разделитель полей - нулевой байт.\n" + +#: command.c:4384 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "Разделитель полей: \"%s\".\n" + +#: command.c:4397 +#, c-format +msgid "Default footer is on.\n" +msgstr "Строка итогов включена.\n" + +#: command.c:4399 +#, c-format +msgid "Default footer is off.\n" +msgstr "Строка итогов выключена.\n" + +#: command.c:4405 +#, c-format +msgid "Output format is %s.\n" +msgstr "Формат вывода: %s.\n" + +#: command.c:4411 +#, c-format +msgid "Line style is %s.\n" +msgstr "Установлен стиль линий: %s.\n" + +#: command.c:4418 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Null выводится как: \"%s\".\n" + +#: command.c:4426 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "Локализованный вывод чисел включён.\n" + +#: command.c:4428 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "Локализованный вывод чисел выключен.\n" + +#: command.c:4435 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Постраничник используется для вывода длинного текста.\n" + +#: command.c:4437 +#, c-format +msgid "Pager is always used.\n" +msgstr "Постраничник используется всегда.\n" + +#: command.c:4439 +#, c-format +msgid "Pager usage is off.\n" +msgstr "Постраничник выключен.\n" + +#: command.c:4445 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "Постраничник не будет использоваться, если строк меньше %d\n" +msgstr[1] "Постраничник не будет использоваться, если строк меньше %d\n" +msgstr[2] "Постраничник не будет использоваться, если строк меньше %d\n" + +#: command.c:4455 command.c:4465 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "Разделитель записей - нулевой байт.\n" + +#: command.c:4457 +#, c-format +msgid "Record separator is .\n" +msgstr "Разделитель записей: <новая строка>.\n" + +#: command.c:4459 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "Разделитель записей: \"%s\".\n" + +#: command.c:4472 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Атрибуты HTML-таблицы: \"%s\".\n" + +#: command.c:4475 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Атрибуты HTML-таблицы не заданы.\n" + +#: command.c:4482 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "Заголовок: \"%s\".\n" + +#: command.c:4484 +#, c-format +msgid "Title is unset.\n" +msgstr "Заголовок не задан.\n" + +#: command.c:4491 +#, c-format +msgid "Tuples only is on.\n" +msgstr "Режим вывода только кортежей включён.\n" + +#: command.c:4493 +#, c-format +msgid "Tuples only is off.\n" +msgstr "Режим вывода только кортежей выключен.\n" + +#: command.c:4499 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Стиль Unicode-линий границ: \"%s\".\n" + +#: command.c:4505 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Стиль Unicode-линий столбцов: \"%s\".\n" + +#: command.c:4511 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Стиль Unicode-линий границ: \"%s\".\n" + +#: command.c:4744 +#, c-format +msgid "\\!: failed" +msgstr "\\!: ошибка" + +#: command.c:4769 common.c:648 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch нельзя использовать с пустым запросом" + +#: command.c:4810 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (обновление: %g с)\n" + +#: command.c:4813 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (обновление: %g с)\n" + +#: command.c:4867 command.c:4874 common.c:548 common.c:555 common.c:1227 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********* ЗАПРОС *********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:5066 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "\"%s.%s\" — не представление" + +#: command.c:5082 +#, c-format +msgid "could not parse reloptions array" +msgstr "не удалось разобрать массив reloptions" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "экранирование строк не работает без подключения к БД" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "" +"аргумент команды оболочки содержит символ новой строки или перевода каретки: " +"\"%s\"" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "подключение к серверу было потеряно" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "Подключение к серверу потеряно. Попытка восстановления " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "неудачна.\n" + +#: common.c:326 +#, c-format +msgid "Succeeded.\n" +msgstr "удачна.\n" + +#: common.c:378 common.c:945 common.c:1162 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "неожиданное значение PQresultStatus: %d" + +#: common.c:487 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Время: %.3f мс\n" + +#: common.c:502 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Время: %.3f мс (%02d:%06.3f)\n" + +#: common.c:511 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Время: %.3f мс (%02d:%02d:%06.3f)\n" + +#: common.c:518 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Время: %.3f мс (%.0f д. %02d:%02d:%06.3f)\n" + +#: common.c:542 common.c:600 common.c:1198 +#, c-format +msgid "You are currently not connected to a database." +msgstr "В данный момент вы не подключены к базе данных." + +#: common.c:655 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watch нельзя использовать с COPY" + +#: common.c:660 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "неожиданное состояние результата для \\watch" + +#: common.c:690 +#, c-format +msgid "" +"Asynchronous notification \"%s\" with payload \"%s\" received from server " +"process with PID %d.\n" +msgstr "" +"Получено асинхронное уведомление \"%s\" с сообщением-нагрузкой \"%s\" от " +"серверного процесса с PID %d.\n" + +#: common.c:693 +#, c-format +msgid "" +"Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "" +"Получено асинхронное уведомление \"%s\" от серверного процесса с PID %d.\n" + +#: common.c:726 common.c:743 +#, c-format +msgid "could not print result table: %m" +msgstr "не удалось вывести таблицу результатов: %m" + +#: common.c:764 +#, c-format +msgid "no rows returned for \\gset" +msgstr "сервер не возвратил строк для \\gset" + +#: common.c:769 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "сервер возвратил больше одной строки для \\gset" + +#: common.c:787 +#, c-format +msgid "attempt to \\gset into specially treated variable \"%s\" ignored" +msgstr "попытка выполнить \\gset со специальной переменной \"%s\" игнорируется" + +#: common.c:1207 +#, c-format +msgid "" +"***(Single step mode: verify " +"command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to " +"cancel)********************\n" +msgstr "" +"***(Пошаговый режим: проверка " +"команды)******************************************\n" +"%s\n" +"***(Enter - выполнение; x и Enter - отмена)**************\n" + +#: common.c:1262 +#, c-format +msgid "" +"The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "" +"Сервер (версия %s) не поддерживает точки сохранения для ON_ERROR_ROLLBACK." + +#: common.c:1325 +#, c-format +msgid "STATEMENT: %s" +msgstr "ОПЕРАТОР: %s" + +#: common.c:1368 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "неожиданное состояние транзакции (%d)" + +#: common.c:1509 describe.c:2001 +msgid "Column" +msgstr "Столбец" + +#: common.c:1510 describe.c:177 describe.c:393 describe.c:411 describe.c:456 +#: describe.c:473 describe.c:962 describe.c:1126 describe.c:1711 +#: describe.c:1735 describe.c:2002 describe.c:3733 describe.c:3943 +#: describe.c:4176 describe.c:5382 +msgid "Type" +msgstr "Тип" + +#: common.c:1559 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Команда не выдала результат, либо в результате нет столбцов.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "укажите аргументы \\copy" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: ошибка разбора аргумента \"%s\"" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: ошибка разбора в конце строки" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "не удалось выполнить команду \"%s\": %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "не удалось получить информацию о файле \"%s\": %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "COPY FROM/TO не может работать с каталогом (%s)" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "не удалось закрыть канал сообщений с внешней командой: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "не удалось записать данные COPY: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "ошибка передачи данных COPY: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "отменено пользователем" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Вводите данные для копирования, разделяя строки переводом строки.\n" +"Закончите ввод строкой '\\.' или сигналом EOF." + +#: copy.c:669 +msgid "aborted because of read failure" +msgstr "прерывание из-за ошибки чтения" + +#: copy.c:703 +msgid "trying to exit copy mode" +msgstr "попытка выйти из режима копирования" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: оператор не возвратил результирующий набор" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: запрос должен возвращать минимум три столбца" + +#: crosstabview.c:156 +#, c-format +msgid "" +"\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "" +"\\crosstabview: для вертикальных и горизонтальных заголовков должны " +"задаваться разные столбцы" + +#: crosstabview.c:172 +#, c-format +msgid "" +"\\crosstabview: data column must be specified when query returns more than " +"three columns" +msgstr "" +"\\crosstabview: когда запрос возвращает больше трёх столбцов, необходимо " +"указать столбец данных" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: превышен максимум числа столбцов (%d)" + +#: crosstabview.c:397 +#, c-format +msgid "" +"\\crosstabview: query result contains multiple data values for row \"%s\", " +"column \"%s\"" +msgstr "" +"\\crosstabview: в результатах запроса содержится несколько значений данных " +"для строки \"%s\", столбца \"%s\"" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: номер столбца %d выходит за рамки диапазона 1..%d" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: неоднозначное имя столбца: \"%s\"" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: имя столбца не найдено: \"%s\"" + +#: describe.c:75 describe.c:373 describe.c:678 describe.c:810 describe.c:954 +#: describe.c:1115 describe.c:1187 describe.c:3722 describe.c:3930 +#: describe.c:4174 describe.c:4265 describe.c:4532 describe.c:4692 +#: describe.c:4933 describe.c:5008 describe.c:5019 describe.c:5081 +#: describe.c:5506 describe.c:5589 +msgid "Schema" +msgstr "Схема" + +#: describe.c:76 describe.c:174 describe.c:242 describe.c:250 describe.c:374 +#: describe.c:679 describe.c:811 describe.c:872 describe.c:955 describe.c:1188 +#: describe.c:3723 describe.c:3931 describe.c:4097 describe.c:4175 +#: describe.c:4266 describe.c:4345 describe.c:4533 describe.c:4617 +#: describe.c:4693 describe.c:4934 describe.c:5009 describe.c:5020 +#: describe.c:5082 describe.c:5279 describe.c:5363 describe.c:5587 +#: describe.c:5759 describe.c:5999 +msgid "Name" +msgstr "Имя" + +#: describe.c:77 describe.c:386 describe.c:404 describe.c:450 describe.c:467 +msgid "Result data type" +msgstr "Тип данных результата" + +#: describe.c:85 describe.c:98 describe.c:102 describe.c:387 describe.c:405 +#: describe.c:451 describe.c:468 +msgid "Argument data types" +msgstr "Типы данных аргументов" + +#: describe.c:110 describe.c:117 describe.c:185 describe.c:273 describe.c:513 +#: describe.c:727 describe.c:826 describe.c:897 describe.c:1190 describe.c:2020 +#: describe.c:3510 describe.c:3783 describe.c:3977 describe.c:4128 +#: describe.c:4202 describe.c:4275 describe.c:4358 describe.c:4441 +#: describe.c:4560 describe.c:4626 describe.c:4694 describe.c:4835 +#: describe.c:4877 describe.c:4950 describe.c:5012 describe.c:5021 +#: describe.c:5083 describe.c:5305 describe.c:5385 describe.c:5520 +#: describe.c:5590 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "Описание" + +#: describe.c:135 +msgid "List of aggregate functions" +msgstr "Список агрегатных функций" + +#: describe.c:160 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "Сервер (версия %s) не поддерживает методы доступа." + +#: describe.c:175 +msgid "Index" +msgstr "Индекс" + +#: describe.c:176 describe.c:3741 describe.c:3956 describe.c:5507 +msgid "Table" +msgstr "Таблица" + +#: describe.c:184 describe.c:5284 +msgid "Handler" +msgstr "Обработчик" + +#: describe.c:203 +msgid "List of access methods" +msgstr "Список методов доступа" + +#: describe.c:229 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "Сервер (версия %s) не поддерживает табличные пространства." + +#: describe.c:243 describe.c:251 describe.c:501 describe.c:717 describe.c:873 +#: describe.c:1114 describe.c:3734 describe.c:3932 describe.c:4101 +#: describe.c:4347 describe.c:4618 describe.c:5280 describe.c:5364 +#: describe.c:5760 describe.c:5897 describe.c:6000 describe.c:6115 +#: describe.c:6194 large_obj.c:289 +msgid "Owner" +msgstr "Владелец" + +#: describe.c:244 describe.c:252 +msgid "Location" +msgstr "Расположение" + +#: describe.c:263 describe.c:3327 +msgid "Options" +msgstr "Параметры" + +#: describe.c:268 describe.c:690 describe.c:889 describe.c:3775 describe.c:3779 +msgid "Size" +msgstr "Размер" + +#: describe.c:290 +msgid "List of tablespaces" +msgstr "Список табличных пространств" + +#: describe.c:333 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df принимает в качестве параметров только [anptwS+]" + +#: describe.c:341 describe.c:352 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df не поддерживает параметр \"%c\" с сервером версии %s" + +# well-spelled: агр +#. translator: "agg" is short for "aggregate" +#: describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "agg" +msgstr "агр." + +#: describe.c:390 describe.c:408 +msgid "window" +msgstr "оконная" + +#: describe.c:391 +msgid "proc" +msgstr "проц." + +# well-spelled: функ +#: describe.c:392 describe.c:410 describe.c:455 describe.c:472 +msgid "func" +msgstr "функ." + +#: describe.c:409 describe.c:454 describe.c:471 describe.c:1324 +msgid "trigger" +msgstr "триггерная" + +#: describe.c:483 +msgid "immutable" +msgstr "постоянная" + +#: describe.c:484 +msgid "stable" +msgstr "стабильная" + +#: describe.c:485 +msgid "volatile" +msgstr "изменчивая" + +#: describe.c:486 +msgid "Volatility" +msgstr "Изменчивость" + +#: describe.c:494 +msgid "restricted" +msgstr "ограниченная" + +#: describe.c:495 +msgid "safe" +msgstr "безопасная" + +#: describe.c:496 +msgid "unsafe" +msgstr "небезопасная" + +#: describe.c:497 +msgid "Parallel" +msgstr "Параллельность" + +#: describe.c:502 +msgid "definer" +msgstr "определившего" + +#: describe.c:503 +msgid "invoker" +msgstr "вызывающего" + +#: describe.c:504 +msgid "Security" +msgstr "Безопасность" + +#: describe.c:511 +msgid "Language" +msgstr "Язык" + +#: describe.c:512 +msgid "Source code" +msgstr "Исходный код" + +#: describe.c:641 +msgid "List of functions" +msgstr "Список функций" + +#: describe.c:689 +msgid "Internal name" +msgstr "Внутреннее имя" + +#: describe.c:711 +msgid "Elements" +msgstr "Элементы" + +#: describe.c:768 +msgid "List of data types" +msgstr "Список типов данных" + +#: describe.c:812 +msgid "Left arg type" +msgstr "Тип левого аргумента" + +#: describe.c:813 +msgid "Right arg type" +msgstr "Тип правого аргумента" + +#: describe.c:814 +msgid "Result type" +msgstr "Результирующий тип" + +#: describe.c:819 describe.c:4353 describe.c:4418 describe.c:4424 +#: describe.c:4834 describe.c:6366 describe.c:6370 +msgid "Function" +msgstr "Функция" + +#: describe.c:844 +msgid "List of operators" +msgstr "Список операторов" + +#: describe.c:874 +msgid "Encoding" +msgstr "Кодировка" + +#: describe.c:879 describe.c:4534 +msgid "Collate" +msgstr "LC_COLLATE" + +#: describe.c:880 describe.c:4535 +msgid "Ctype" +msgstr "LC_CTYPE" + +#: describe.c:893 +msgid "Tablespace" +msgstr "Табл. пространство" + +#: describe.c:915 +msgid "List of databases" +msgstr "Список баз данных" + +#: describe.c:956 describe.c:1117 describe.c:3724 +msgid "table" +msgstr "таблица" + +#: describe.c:957 describe.c:3725 +msgid "view" +msgstr "представление" + +#: describe.c:958 describe.c:3726 +msgid "materialized view" +msgstr "материализованное представление" + +#: describe.c:959 describe.c:1119 describe.c:3728 +msgid "sequence" +msgstr "последовательность" + +#: describe.c:960 describe.c:3730 +msgid "foreign table" +msgstr "сторонняя таблица" + +#: describe.c:961 describe.c:3731 describe.c:3941 +msgid "partitioned table" +msgstr "секционированная таблица" + +#: describe.c:973 +msgid "Column privileges" +msgstr "Права для столбцов" + +#: describe.c:1004 describe.c:1038 +msgid "Policies" +msgstr "Политики" + +#: describe.c:1070 describe.c:6056 describe.c:6060 +msgid "Access privileges" +msgstr "Права доступа" + +#: describe.c:1101 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "Сервер (версия %s) не поддерживает изменение прав по умолчанию." + +#: describe.c:1121 +msgid "function" +msgstr "функция" + +#: describe.c:1123 +msgid "type" +msgstr "тип" + +#: describe.c:1125 +msgid "schema" +msgstr "схема" + +#: describe.c:1149 +msgid "Default access privileges" +msgstr "Права доступа по умолчанию" + +#: describe.c:1189 +msgid "Object" +msgstr "Объект" + +#: describe.c:1203 +msgid "table constraint" +msgstr "ограничение таблицы" + +#: describe.c:1225 +msgid "domain constraint" +msgstr "ограничение домена" + +#: describe.c:1253 +msgid "operator class" +msgstr "класс операторов" + +#: describe.c:1282 +msgid "operator family" +msgstr "семейство операторов" + +#: describe.c:1304 +msgid "rule" +msgstr "правило" + +#: describe.c:1346 +msgid "Object descriptions" +msgstr "Описание объекта" + +#: describe.c:1402 describe.c:3847 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "Отношение \"%s\" не найдено." + +#: describe.c:1405 describe.c:3850 +#, c-format +msgid "Did not find any relations." +msgstr "Отношения не найдены." + +#: describe.c:1660 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "Отношение с OID %s не найдено." + +#: describe.c:1712 describe.c:1736 +msgid "Start" +msgstr "Начальное_значение" + +#: describe.c:1713 describe.c:1737 +msgid "Minimum" +msgstr "Минимум" + +#: describe.c:1714 describe.c:1738 +msgid "Maximum" +msgstr "Максимум" + +#: describe.c:1715 describe.c:1739 +msgid "Increment" +msgstr "Шаг" + +#: describe.c:1716 describe.c:1740 describe.c:1871 describe.c:4269 +#: describe.c:4435 describe.c:4549 describe.c:4554 describe.c:6103 +msgid "yes" +msgstr "да" + +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4269 +#: describe.c:4432 describe.c:4549 describe.c:6104 +msgid "no" +msgstr "нет" + +#: describe.c:1718 describe.c:1742 +msgid "Cycles?" +msgstr "Зацикливается?" + +#: describe.c:1719 describe.c:1743 +msgid "Cache" +msgstr "Кешируется" + +#: describe.c:1786 +#, c-format +msgid "Owned by: %s" +msgstr "Владелец: %s" + +#: describe.c:1790 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Последовательность для столбца идентификации: %s" + +#: describe.c:1797 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Последовательность \"%s.%s\"" + +#: describe.c:1933 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Нежурналируемая таблица \"%s.%s\"" + +#: describe.c:1936 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Таблица \"%s.%s\"" + +#: describe.c:1940 +#, c-format +msgid "View \"%s.%s\"" +msgstr "Представление \"%s.%s\"" + +#: describe.c:1945 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Нежурналируемое материализованное представление \"%s.%s\"" + +#: describe.c:1948 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Материализованное представление \"%s.%s\"" + +#: describe.c:1953 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Нежурналируемый индекс \"%s.%s\"" + +#: describe.c:1956 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "Индекс \"%s.%s\"" + +#: describe.c:1961 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Нежурналируемый секционированный индекс \"%s.%s\"" + +#: describe.c:1964 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Секционированный индекс \"%s.%s\"" + +#: describe.c:1969 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Специальное отношение \"%s.%s\"" + +#: describe.c:1973 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "TOAST-таблица \"%s.%s\"" + +#: describe.c:1977 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Составной тип \"%s.%s\"" + +#: describe.c:1981 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "Сторонняя таблица \"%s.%s\"" + +#: describe.c:1986 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Нежурналируемая секционированная таблица \"%s.%s\"" + +#: describe.c:1989 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Секционированная таблица \"%s.%s\"" + +#: describe.c:2005 describe.c:4182 +msgid "Collation" +msgstr "Правило сортировки" + +#: describe.c:2006 describe.c:4189 +msgid "Nullable" +msgstr "Допустимость NULL" + +#: describe.c:2007 describe.c:4190 +msgid "Default" +msgstr "По умолчанию" + +#: describe.c:2010 +msgid "Key?" +msgstr "Ключевой?" + +#: describe.c:2012 +msgid "Definition" +msgstr "Определение" + +# well-spelled: ОСД +#: describe.c:2014 describe.c:5300 describe.c:5384 describe.c:5455 +#: describe.c:5519 +msgid "FDW options" +msgstr "Параметры ОСД" + +#: describe.c:2016 +msgid "Storage" +msgstr "Хранилище" + +#: describe.c:2018 +msgid "Stats target" +msgstr "Цель для статистики" + +#: describe.c:2135 +#, c-format +msgid "Partition of: %s %s" +msgstr "Секция из: %s %s" + +#: describe.c:2147 +msgid "No partition constraint" +msgstr "Нет ограничения секции" + +#: describe.c:2149 +#, c-format +msgid "Partition constraint: %s" +msgstr "Ограничение секции: %s" + +#: describe.c:2173 +#, c-format +msgid "Partition key: %s" +msgstr "Ключ разбиения: %s" + +#: describe.c:2199 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Принадлежит таблице: \"%s.%s\"" + +#: describe.c:2270 +msgid "primary key, " +msgstr "первичный ключ, " + +#: describe.c:2272 +msgid "unique, " +msgstr "уникальный, " + +#: describe.c:2278 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "для таблицы \"%s.%s\"" + +#: describe.c:2282 +#, c-format +msgid ", predicate (%s)" +msgstr ", предикат (%s)" + +#: describe.c:2285 +msgid ", clustered" +msgstr ", кластеризованный" + +#: describe.c:2288 +msgid ", invalid" +msgstr ", нерабочий" + +#: describe.c:2291 +msgid ", deferrable" +msgstr ", откладываемый" + +#: describe.c:2294 +msgid ", initially deferred" +msgstr ", изначально отложенный" + +#: describe.c:2297 +msgid ", replica identity" +msgstr ", репликационный" + +#: describe.c:2364 +msgid "Indexes:" +msgstr "Индексы:" + +#: describe.c:2448 +msgid "Check constraints:" +msgstr "Ограничения-проверки:" + +# TO REWVIEW +#: describe.c:2516 +msgid "Foreign-key constraints:" +msgstr "Ограничения внешнего ключа:" + +#: describe.c:2579 +msgid "Referenced by:" +msgstr "Ссылки извне:" + +#: describe.c:2629 +msgid "Policies:" +msgstr "Политики:" + +#: describe.c:2632 +msgid "Policies (forced row security enabled):" +msgstr "Политики (усиленная защита строк включена):" + +#: describe.c:2635 +msgid "Policies (row security enabled): (none)" +msgstr "Политики (защита строк включена): (Нет)" + +#: describe.c:2638 +msgid "Policies (forced row security enabled): (none)" +msgstr "Политики (усиленная защита строк включена): (Нет)" + +#: describe.c:2641 +msgid "Policies (row security disabled):" +msgstr "Политики (защита строк выключена):" + +#: describe.c:2709 +msgid "Statistics objects:" +msgstr "Объекты статистики:" + +#: describe.c:2823 describe.c:2927 +msgid "Rules:" +msgstr "Правила:" + +#: describe.c:2826 +msgid "Disabled rules:" +msgstr "Отключённые правила:" + +#: describe.c:2829 +msgid "Rules firing always:" +msgstr "Правила, срабатывающие всегда:" + +#: describe.c:2832 +msgid "Rules firing on replica only:" +msgstr "Правила, срабатывающие только в реплике:" + +#: describe.c:2872 +msgid "Publications:" +msgstr "Публикации:" + +#: describe.c:2910 +msgid "View definition:" +msgstr "Определение представления:" + +#: describe.c:3057 +msgid "Triggers:" +msgstr "Триггеры:" + +#: describe.c:3061 +msgid "Disabled user triggers:" +msgstr "Отключённые пользовательские триггеры:" + +#: describe.c:3063 +msgid "Disabled triggers:" +msgstr "Отключённые триггеры:" + +#: describe.c:3066 +msgid "Disabled internal triggers:" +msgstr "Отключённые внутренние триггеры:" + +#: describe.c:3069 +msgid "Triggers firing always:" +msgstr "Триггеры, срабатывающие всегда:" + +#: describe.c:3072 +msgid "Triggers firing on replica only:" +msgstr "Триггеры, срабатывающие только в реплике:" + +#: describe.c:3144 +#, c-format +msgid "Server: %s" +msgstr "Сервер: %s" + +# well-spelled: ОСД +#: describe.c:3152 +#, c-format +msgid "FDW options: (%s)" +msgstr "Параметр ОСД: (%s)" + +#: describe.c:3173 +msgid "Inherits" +msgstr "Наследует" + +#: describe.c:3233 +#, c-format +msgid "Number of partitions: %d" +msgstr "Число секций: %d" + +#: describe.c:3242 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Число секций: %d (чтобы просмотреть их, введите \\d+)" + +#: describe.c:3244 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Дочерних таблиц: %d (чтобы просмотреть и их, воспользуйтесь \\d+)" + +#: describe.c:3251 +msgid "Child tables" +msgstr "Дочерние таблицы" + +#: describe.c:3251 +msgid "Partitions" +msgstr "Секции" + +#: describe.c:3280 +#, c-format +msgid "Typed table of type: %s" +msgstr "Типизированная таблица типа: %s" + +#: describe.c:3296 +msgid "Replica Identity" +msgstr "Идентификация реплики" + +#: describe.c:3309 +msgid "Has OIDs: yes" +msgstr "Содержит OID: да" + +#: describe.c:3318 +#, c-format +msgid "Access method: %s" +msgstr "Метод доступа: %s" + +#: describe.c:3398 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Табличное пространство: \"%s\"" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3410 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", табл. пространство \"%s\"" + +#: describe.c:3503 +msgid "List of roles" +msgstr "Список ролей" + +#: describe.c:3505 +msgid "Role name" +msgstr "Имя роли" + +#: describe.c:3506 +msgid "Attributes" +msgstr "Атрибуты" + +#: describe.c:3507 +msgid "Member of" +msgstr "Член ролей" + +#: describe.c:3518 +msgid "Superuser" +msgstr "Суперпользователь" + +#: describe.c:3521 +msgid "No inheritance" +msgstr "Не наследуется" + +#: describe.c:3524 +msgid "Create role" +msgstr "Создаёт роли" + +#: describe.c:3527 +msgid "Create DB" +msgstr "Создаёт БД" + +#: describe.c:3530 +msgid "Cannot login" +msgstr "Вход запрещён" + +#: describe.c:3534 +msgid "Replication" +msgstr "Репликация" + +#: describe.c:3538 +msgid "Bypass RLS" +msgstr "Пропускать RLS" + +#: describe.c:3547 +msgid "No connections" +msgstr "Нет подключений" + +#: describe.c:3549 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d подключение" +msgstr[1] "%d подключения" +msgstr[2] "%d подключений" + +#: describe.c:3559 +msgid "Password valid until " +msgstr "Пароль действует до " + +#: describe.c:3609 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "" +"Сервер (версия %s) не поддерживает назначение параметров ролей для баз " +"данных." + +#: describe.c:3622 +msgid "Role" +msgstr "Роль" + +#: describe.c:3623 +msgid "Database" +msgstr "БД" + +#: describe.c:3624 +msgid "Settings" +msgstr "Параметры" + +#: describe.c:3645 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "Параметры для роли \"%s\" и базы данных \"%s\" не найдены." + +#: describe.c:3648 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "Параметры для роли \"%s\" не найдены." + +#: describe.c:3651 +#, c-format +msgid "Did not find any settings." +msgstr "Никакие параметры не найдены." + +#: describe.c:3656 +msgid "List of settings" +msgstr "Список параметров" + +#: describe.c:3727 +msgid "index" +msgstr "индекс" + +# skip-rule: capital-letter-first +#: describe.c:3729 +msgid "special" +msgstr "спец. отношение" + +#: describe.c:3732 describe.c:3942 +msgid "partitioned index" +msgstr "секционированный индекс" + +#: describe.c:3756 +msgid "permanent" +msgstr "постоянное" + +#: describe.c:3757 +msgid "temporary" +msgstr "временное" + +#: describe.c:3758 +msgid "unlogged" +msgstr "нежурналируемое" + +#: describe.c:3759 +msgid "Persistence" +msgstr "Хранение" + +#: describe.c:3855 +msgid "List of relations" +msgstr "Список отношений" + +#: describe.c:3903 +#, c-format +msgid "" +"The server (version %s) does not support declarative table partitioning." +msgstr "" +"Сервер (версия %s) не поддерживает декларативное секционирование таблиц." + +#: describe.c:3914 +msgid "List of partitioned indexes" +msgstr "Список секционированных индексов" + +#: describe.c:3916 +msgid "List of partitioned tables" +msgstr "Список секционированных таблиц" + +#: describe.c:3920 +msgid "List of partitioned relations" +msgstr "Список секционированных отношений" + +#: describe.c:3951 +msgid "Parent name" +msgstr "Имя родителя" + +#: describe.c:3964 +msgid "Leaf partition size" +msgstr "Размер конечной секции" + +#: describe.c:3967 describe.c:3973 +msgid "Total size" +msgstr "Общий размер" + +#: describe.c:4105 +msgid "Trusted" +msgstr "Доверенный" + +#: describe.c:4113 +msgid "Internal language" +msgstr "Внутренний язык" + +#: describe.c:4114 +msgid "Call handler" +msgstr "Обработчик вызова" + +#: describe.c:4115 describe.c:5287 +msgid "Validator" +msgstr "Функция проверки" + +#: describe.c:4118 +msgid "Inline handler" +msgstr "Обработчик внедрённого кода" + +#: describe.c:4146 +msgid "List of languages" +msgstr "Список языков" + +#: describe.c:4191 +msgid "Check" +msgstr "Проверка" + +#: describe.c:4233 +msgid "List of domains" +msgstr "Список доменов" + +#: describe.c:4267 +msgid "Source" +msgstr "Источник" + +#: describe.c:4268 +msgid "Destination" +msgstr "Назначение" + +#: describe.c:4270 describe.c:6105 +msgid "Default?" +msgstr "По умолчанию?" + +#: describe.c:4307 +msgid "List of conversions" +msgstr "Список преобразований" + +#: describe.c:4346 +msgid "Event" +msgstr "Событие" + +#: describe.c:4348 +msgid "enabled" +msgstr "включён" + +#: describe.c:4349 +msgid "replica" +msgstr "реплика" + +#: describe.c:4350 +msgid "always" +msgstr "всегда" + +#: describe.c:4351 +msgid "disabled" +msgstr "отключён" + +#: describe.c:4352 describe.c:6001 +msgid "Enabled" +msgstr "Включён" + +#: describe.c:4354 +msgid "Tags" +msgstr "Теги" + +#: describe.c:4373 +msgid "List of event triggers" +msgstr "Список событийных триггеров" + +#: describe.c:4402 +msgid "Source type" +msgstr "Исходный тип" + +#: describe.c:4403 +msgid "Target type" +msgstr "Целевой тип" + +#: describe.c:4434 +msgid "in assignment" +msgstr "в присваивании" + +#: describe.c:4436 +msgid "Implicit?" +msgstr "Неявное?" + +#: describe.c:4491 +msgid "List of casts" +msgstr "Список приведений типов" + +#: describe.c:4519 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "Сервер (версия %s) не поддерживает правила сравнения." + +#: describe.c:4540 describe.c:4544 +msgid "Provider" +msgstr "Поставщик" + +#: describe.c:4550 describe.c:4555 +msgid "Deterministic?" +msgstr "Детерминированное?" + +#: describe.c:4590 +msgid "List of collations" +msgstr "Список правил сортировки" + +#: describe.c:4649 +msgid "List of schemas" +msgstr "Список схем" + +#: describe.c:4674 describe.c:4921 describe.c:4992 describe.c:5063 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "Сервер (версия %s) не поддерживает полнотекстовый поиск." + +#: describe.c:4709 +msgid "List of text search parsers" +msgstr "Список анализаторов текстового поиска" + +#: describe.c:4754 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "Анализатор текстового поиска \"%s\" не найден." + +#: describe.c:4757 +#, c-format +msgid "Did not find any text search parsers." +msgstr "Никакие анализаторы текстового поиска не найдены." + +#: describe.c:4832 +msgid "Start parse" +msgstr "Начало разбора" + +#: describe.c:4833 +msgid "Method" +msgstr "Метод" + +#: describe.c:4837 +msgid "Get next token" +msgstr "Получение следующего фрагмента" + +#: describe.c:4839 +msgid "End parse" +msgstr "Окончание разбора" + +#: describe.c:4841 +msgid "Get headline" +msgstr "Получение выдержки" + +#: describe.c:4843 +msgid "Get token types" +msgstr "Получение типов фрагментов" + +#: describe.c:4854 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Анализатор текстового поиска \"%s.%s\"" + +#: describe.c:4857 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "Анализатор текстового поиска \"%s\"" + +#: describe.c:4876 +msgid "Token name" +msgstr "Имя фрагмента" + +#: describe.c:4887 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "Типы фрагментов для анализатора \"%s.%s\"" + +#: describe.c:4890 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "Типы фрагментов для анализатора \"%s\"" + +#: describe.c:4944 +msgid "Template" +msgstr "Шаблон" + +#: describe.c:4945 +msgid "Init options" +msgstr "Параметры инициализации" + +#: describe.c:4967 +msgid "List of text search dictionaries" +msgstr "Список словарей текстового поиска" + +#: describe.c:5010 +msgid "Init" +msgstr "Инициализация" + +#: describe.c:5011 +msgid "Lexize" +msgstr "Выделение лексем" + +#: describe.c:5038 +msgid "List of text search templates" +msgstr "Список шаблонов текстового поиска" + +#: describe.c:5098 +msgid "List of text search configurations" +msgstr "Список конфигураций текстового поиска" + +#: describe.c:5144 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "Конфигурация текстового поиска \"%s\" не найдена." + +#: describe.c:5147 +#, c-format +msgid "Did not find any text search configurations." +msgstr "Никакие конфигурации текстового поиска не найдены." + +#: describe.c:5213 +msgid "Token" +msgstr "Фрагмент" + +#: describe.c:5214 +msgid "Dictionaries" +msgstr "Словари" + +#: describe.c:5225 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Конфигурация текстового поиска \"%s.%s\"" + +#: describe.c:5228 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Конфигурация текстового поиска \"%s\"" + +#: describe.c:5232 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Анализатор: \"%s.%s\"" + +#: describe.c:5235 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Анализатор: \"%s\"" + +#: describe.c:5269 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "Сервер (версия %s) не поддерживает обёртки сторонних данных." + +#: describe.c:5327 +msgid "List of foreign-data wrappers" +msgstr "Список обёрток сторонних данных" + +#: describe.c:5352 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "Сервер (версия %s) не поддерживает сторонние серверы." + +#: describe.c:5365 +msgid "Foreign-data wrapper" +msgstr "Обёртка сторонних данных" + +#: describe.c:5383 describe.c:5588 +msgid "Version" +msgstr "Версия" + +#: describe.c:5409 +msgid "List of foreign servers" +msgstr "Список сторонних серверов" + +#: describe.c:5434 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "Сервер (версия %s) не поддерживает сопоставления пользователей." + +#: describe.c:5444 describe.c:5508 +msgid "Server" +msgstr "Сервер" + +#: describe.c:5445 +msgid "User name" +msgstr "Имя пользователя" + +#: describe.c:5470 +msgid "List of user mappings" +msgstr "Список сопоставлений пользователей" + +#: describe.c:5495 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "Сервер (версия %s) не поддерживает сторонние таблицы." + +#: describe.c:5548 +msgid "List of foreign tables" +msgstr "Список сторонних таблиц" + +#: describe.c:5573 describe.c:5630 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "Сервер (версия %s) не поддерживает расширения." + +#: describe.c:5605 +msgid "List of installed extensions" +msgstr "Список установленных расширений" + +#: describe.c:5658 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "Расширение \"%s\" не найдено." + +#: describe.c:5661 +#, c-format +msgid "Did not find any extensions." +msgstr "Никакие расширения не найдены." + +#: describe.c:5705 +msgid "Object description" +msgstr "Описание объекта" + +#: describe.c:5715 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "Объекты в расширении \"%s\"" + +#: describe.c:5744 describe.c:5820 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "Сервер (версия %s) не поддерживает публикации." + +#: describe.c:5761 describe.c:5898 +msgid "All tables" +msgstr "Все таблицы" + +#: describe.c:5762 describe.c:5899 +msgid "Inserts" +msgstr "Добавления" + +#: describe.c:5763 describe.c:5900 +msgid "Updates" +msgstr "Изменения" + +#: describe.c:5764 describe.c:5901 +msgid "Deletes" +msgstr "Удаления" + +#: describe.c:5768 describe.c:5903 +msgid "Truncates" +msgstr "Опустошения" + +#: describe.c:5772 describe.c:5905 +msgid "Via root" +msgstr "Через корень" + +#: describe.c:5789 +msgid "List of publications" +msgstr "Список публикаций" + +#: describe.c:5862 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "Публикация \"%s\" не найдена." + +#: describe.c:5865 +#, c-format +msgid "Did not find any publications." +msgstr "Никакие публикации не найдены." + +#: describe.c:5894 +#, c-format +msgid "Publication %s" +msgstr "Публикация %s" + +#: describe.c:5942 +msgid "Tables:" +msgstr "Таблицы:" + +#: describe.c:5986 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "Сервер (версия %s) не поддерживает подписки." + +#: describe.c:6002 +msgid "Publication" +msgstr "Публикация" + +#: describe.c:6009 +msgid "Synchronous commit" +msgstr "Синхронная фиксация" + +#: describe.c:6010 +msgid "Conninfo" +msgstr "Строка подключения" + +#: describe.c:6032 +msgid "List of subscriptions" +msgstr "Список подписок" + +#: describe.c:6099 describe.c:6188 describe.c:6274 describe.c:6357 +msgid "AM" +msgstr "МД" + +#: describe.c:6100 +msgid "Input type" +msgstr "Входной тип" + +#: describe.c:6101 +msgid "Storage type" +msgstr "Тип хранения" + +#: describe.c:6102 +msgid "Operator class" +msgstr "Класс операторов" + +#: describe.c:6114 describe.c:6189 describe.c:6275 describe.c:6358 +msgid "Operator family" +msgstr "Семейство операторов" + +#: describe.c:6147 +msgid "List of operator classes" +msgstr "Список классов операторов" + +#: describe.c:6190 +msgid "Applicable types" +msgstr "Применимые типы" + +#: describe.c:6229 +msgid "List of operator families" +msgstr "Список семейств операторов" + +#: describe.c:6276 +msgid "Operator" +msgstr "Оператор" + +#: describe.c:6277 +msgid "Strategy" +msgstr "Стратегия" + +#: describe.c:6278 +msgid "ordering" +msgstr "сортировка" + +#: describe.c:6279 +msgid "search" +msgstr "поиск" + +#: describe.c:6280 +msgid "Purpose" +msgstr "Назначение" + +#: describe.c:6285 +msgid "Sort opfamily" +msgstr "Семейство для сортировки" + +#: describe.c:6316 +msgid "List of operators of operator families" +msgstr "Список операторов из семейств операторов" + +#: describe.c:6359 +msgid "Registered left type" +msgstr "Зарегистрированный левый тип" + +#: describe.c:6360 +msgid "Registered right type" +msgstr "Зарегистрированный правый тип" + +#: describe.c:6361 +msgid "Number" +msgstr "Номер" + +#: describe.c:6397 +msgid "List of support functions of operator families" +msgstr "Список опорных функций из семейств операторов" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql - это интерактивный терминал PostgreSQL.\n" +"\n" + +#: help.c:74 help.c:355 help.c:431 help.c:474 +#, c-format +msgid "Usage:\n" +msgstr "Использование:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [ПАРАМЕТР]... [БД [ПОЛЬЗОВАТЕЛЬ]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Общие параметры:\n" + +#: help.c:82 +#, c-format +msgid "" +" -c, --command=COMMAND run only single command (SQL or internal) and " +"exit\n" +msgstr "" +" -c, --command=КОМАНДА выполнить одну команду (SQL или внутреннюю) и " +"выйти\n" + +#: help.c:83 +#, c-format +msgid "" +" -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr "" +" -d, --dbname=БД имя подключаемой базы данных (по умолчанию \"%s" +"\")\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=ИМЯ_ФАЙЛА выполнить команды из файла и выйти\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, --list вывести список баз данных и выйти\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=ИМЯ=ЗНАЧЕНИЕ\n" +" присвоить переменной psql ИМЯ заданное ЗНАЧЕНИЕ\n" +" (например: -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать версию и выйти\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr "" +" -X, --no-psqlrc игнорировать файл параметров запуска (~/.psqlrc)\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-" +"interactive)\n" +msgstr "" +" -1 (\"один\"), --single-transaction\n" +" выполнить как одну транзакцию\n" +" (в неинтерактивном режиме)\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] показать эту справку и выйти\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands перечислить команды с \\ и выйти\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr "" +" --help=variables перечислить специальные переменные и выйти\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Параметры ввода/вывода:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all отображать все команды из скрипта\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors отображать команды с ошибками\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, --echo-queries отображать команды, отправляемые серверу\n" + +#: help.c:101 +#, c-format +msgid "" +" -E, --echo-hidden display queries that internal commands generate\n" +msgstr "" +" -E, --echo-hidden выводить запросы, порождённые внутренними " +"командами\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, --log-file=ИМЯ_ФАЙЛА сохранять протокол работы в файл\n" + +#: help.c:103 +#, c-format +msgid "" +" -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr "" +" -n, --no-readline отключить редактор командной строки readline\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr "" +" -o, --output=ИМЯ_ФАЙЛА направить результаты запроса в файл (или канал " +"|)\n" + +#: help.c:105 +#, c-format +msgid "" +" -q, --quiet run quietly (no messages, only query output)\n" +msgstr "" +" -q, --quiet показывать только результаты запросов, без " +"сообщений\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr "" +" -s, --single-step пошаговый режим (подтверждение каждого запроса)\n" + +#: help.c:107 +#, c-format +msgid "" +" -S, --single-line single-line mode (end of line terminates SQL " +"command)\n" +msgstr "" +" -S, --single-line однострочный режим (конец строки завершает " +"команду)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Параметры вывода:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align режим вывода невыровненной таблицы\n" + +#: help.c:111 +#, c-format +msgid "" +" --csv CSV (Comma-Separated Values) table output mode\n" +msgstr "" +" --csv режим вывода в формате CSV (значения, " +"разделённые\n" +" запятыми)\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: " +"\"%s\")\n" +msgstr "" +" -F, --field-separator=СТРОКА\n" +" разделителей полей при невыровненном выводе\n" +" (по умолчанию: \"%s\")\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html вывод таблицы в формате HTML\n" + +#: help.c:116 +#, c-format +msgid "" +" -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset " +"command)\n" +msgstr "" +" -P, --pset=ПАР[=ЗНАЧ] определить параметр печати ПАР (с заданным " +"ЗНАЧЕНИЕМ)\n" +" (см. описание \\pset)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: " +"newline)\n" +msgstr "" +" -R, --record-separator=СТРОКА\n" +" разделитель записей при невыровненном выводе\n" +" (по умолчанию: новая строка)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only выводить только кортежи\n" + +#: help.c:120 +#, c-format +msgid "" +" -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, " +"border)\n" +msgstr "" +" -T, --table-attr=ТЕКСТ установить атрибуты HTML-таблицы (width, border)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded включить развёрнутый вывод таблицы\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero " +"byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" сделать разделителем полей при невыровненном\n" +" выводе нулевой байт\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero " +"byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" сделать разделителем записей при невыровненном\n" +" нулевой байт\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Параметры подключения:\n" + +#: help.c:130 +#, c-format +msgid "" +" -h, --host=HOSTNAME database server host or socket directory " +"(default: \"%s\")\n" +msgstr "" +" -h, --host=ИМЯ имя сервера баз данных или каталог сокетов\n" +" (по умолчанию: \"%s\")\n" + +#: help.c:131 +msgid "local socket" +msgstr "локальный сокет" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr "" +" -p, --port=ПОРТ порт сервера баз данных (по умолчанию: \"%s\")\n" + +#: help.c:140 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, --username=ИМЯ имя пользователя (по умолчанию: \"%s\")\n" + +#: help.c:141 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password не запрашивать пароль\n" + +#: help.c:142 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr "" +" -W, --password запрашивать пароль всегда (обычно не требуется)\n" + +#: help.c:144 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help" +"\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"Чтобы узнать больше, введите \"\\?\" (список внутренних команд) или \"\\help" +"\"\n" +"(справка по операторам SQL) в psql, либо обратитесь к разделу psql в\n" +"документации PostgreSQL.\n" +"\n" + +#: help.c:147 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Об ошибках сообщайте по адресу <%s>.\n" + +#: help.c:148 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "Домашняя страница %s: <%s>\n" + +#: help.c:174 +#, c-format +msgid "General\n" +msgstr "Общие\n" + +# skip-rule: copyright +#: help.c:175 +#, c-format +msgid "" +" \\copyright show PostgreSQL usage and distribution terms\n" +msgstr "" +" \\copyright условия использования и распространения " +"PostgreSQL\n" + +#: help.c:176 +#, c-format +msgid "" +" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr "" +" \\crosstabview [СТОЛБЦЫ] выполнить запрос и вывести результат в " +"перекрёстном виде\n" + +#: help.c:177 +#, c-format +msgid "" +" \\errverbose show most recent error message at maximum " +"verbosity\n" +msgstr "" +" \\errverbose вывести максимально подробное сообщение о " +"последней ошибке\n" + +#: help.c:178 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |" +"pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(ПАРАМЕТРЫ)] [ФАЙЛ] выполнить запрос (и направить результаты в файл\n" +"\n" +" или канал |); \\g без аргументов равнозначно \";" +"\"\n" + +#: help.c:180 +#, c-format +msgid "" +" \\gdesc describe result of query, without executing it\n" +msgstr "" +" \\gdesc описать результат запроса, но не выполнять его\n" + +#: help.c:181 +#, c-format +msgid "" +" \\gexec execute query, then execute each value in its " +"result\n" +msgstr "" +" \\gexec выполнить запрос, а затем выполнить каждую строку " +"в результате\n" + +#: help.c:182 +#, c-format +msgid "" +" \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr "" +" \\gset [ПРЕФИКС] выполнить запрос и сохранить результаты в " +"переменных\n" +" psql\n" + +#: help.c:183 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr "" +" \\gx [(ПАРАМЕТРЫ)] [ФАЙЛ] то же, что \\g, но в режиме развёрнутого вывода\n" + +#: help.c:184 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q выйти из psql\n" + +#: help.c:185 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr "" +" \\watch [СЕК] повторять запрос в цикле через заданное число " +"секунд\n" + +#: help.c:188 +#, c-format +msgid "Help\n" +msgstr "Справка\n" + +#: help.c:190 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commands] справка по командам psql c \\\n" + +#: help.c:191 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr "" +" \\? options справка по параметрам командной строки psql\n" + +#: help.c:192 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables справка по специальным переменным\n" + +#: help.c:193 +#, c-format +msgid "" +" \\h [NAME] help on syntax of SQL commands, * for all " +"commands\n" +msgstr "" +" \\h [ИМЯ] справка по заданному SQL-оператору; * - по всем\n" + +#: help.c:196 +#, c-format +msgid "Query Buffer\n" +msgstr "Буфер запроса\n" + +#: help.c:197 +#, c-format +msgid "" +" \\e [FILE] [LINE] edit the query buffer (or file) with external " +"editor\n" +msgstr "" +" \\e [ФАЙЛ] [СТРОКА] править буфер запроса (или файл) во внешнем " +"редакторе\n" + +#: help.c:198 +#, c-format +msgid "" +" \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr "" +" \\ef [ФУНКЦИЯ [СТРОКА]] править определение функции во внешнем редакторе\n" + +#: help.c:199 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr "" +" \\ev [VIEWNAME [LINE]] править определение представления во внешнем " +"редакторе\n" + +#: help.c:200 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p вывести содержимое буфера запросов\n" + +#: help.c:201 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r очистить буфер запроса\n" + +#: help.c:203 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [ФАЙЛ] вывести историю или сохранить её в файл\n" + +#: help.c:205 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w ФАЙЛ записать буфер запроса в файл\n" + +#: help.c:208 +#, c-format +msgid "Input/Output\n" +msgstr "Ввод/Вывод\n" + +#: help.c:209 +#, c-format +msgid "" +" \\copy ... perform SQL COPY with data stream to the client " +"host\n" +msgstr " \\copy ... выполнить SQL COPY на стороне клиента\n" + +#: help.c:210 +#, c-format +msgid "" +" \\echo [-n] [STRING] write string to standard output (-n for no " +"newline)\n" +msgstr "" +" \\echo [-n] [СТРОКА] записать строку в поток стандартного вывода\n" +" (-n отключает перевод строки)\n" + +#: help.c:211 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i ФАЙЛ выполнить команды из файла\n" + +#: help.c:212 +#, c-format +msgid "" +" \\ir FILE as \\i, but relative to location of current " +"script\n" +msgstr "" +" \\ir ФАЙЛ подобно \\i, но путь задаётся относительно\n" +" текущего скрипта\n" + +#: help.c:213 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr "" +" \\o [ФАЙЛ] выводить все результаты запросов в файл или канал " +"|\n" + +#: help.c:214 +#, c-format +msgid "" +" \\qecho [-n] [STRING] write string to \\o output stream (-n for no " +"newline)\n" +msgstr "" +" \\qecho [-n] [СТРОКА] записать строку в выходной поток \\o\n" +" (-n отключает перевод строки)\n" + +#: help.c:215 +#, c-format +msgid "" +" \\warn [-n] [STRING] write string to standard error (-n for no " +"newline)\n" +msgstr "" +" \\warn [-n] [СТРОКА] записать строку в поток вывода ошибок\n" +" (-n отключает перевод строки)\n" + +#: help.c:218 +#, c-format +msgid "Conditional\n" +msgstr "Условия\n" + +#: help.c:219 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if ВЫРАЖЕНИЕ начало блока условия\n" + +#: help.c:220 +#, c-format +msgid "" +" \\elif EXPR alternative within current conditional block\n" +msgstr "" +" \\elif ВЫРАЖЕНИЕ альтернативная ветвь в текущем блоке условия\n" + +#: help.c:221 +#, c-format +msgid "" +" \\else final alternative within current conditional " +"block\n" +msgstr "" +" \\else окончательная ветвь в текущем блоке условия\n" + +#: help.c:222 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif конец блока условия\n" + +#: help.c:225 +#, c-format +msgid "Informational\n" +msgstr "Информационные\n" + +#: help.c:226 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr "" +" (дополнения: S = показывать системные объекты, + = дополнительные " +"подробности)\n" + +#: help.c:227 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr "" +" \\d[S+] список таблиц, представлений и " +"последовательностей\n" + +#: help.c:228 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr "" +" \\d[S+] ИМЯ описание таблицы, представления, " +"последовательности\n" +" или индекса\n" + +#: help.c:229 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [МАСКА] список агрегатных функций\n" + +#: help.c:230 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [МАСКА] список методов доступа\n" + +# well-spelled: МСК +#: help.c:231 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [МСК_МД [МСК_ТИПА]] список классов операторов\n" + +# well-spelled: МСК +#: help.c:232 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [МСК_МД [МСК_ТИПА]] список семейств операторов\n" + +# well-spelled: МСК +#: help.c:233 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr "" +" \\dAo[+] [МСК_МД [МСК_СОП]] список операторов из семейств операторов\n" + +# well-spelled: МСК +#: help.c:234 +#, c-format +msgid "" +" \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr "" +" \\dAp [МСК_МД [МСК_СОП]] список опорных функций из семейств " +"операторов\n" + +#: help.c:235 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [МАСКА] список табличных пространств\n" + +#: help.c:236 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [МАСКА] список преобразований\n" + +#: help.c:237 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [МАСКА] список приведений типов\n" + +#: help.c:238 +#, c-format +msgid "" +" \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr "" +" \\dd[S] [МАСКА] описания объектов, не выводимые в других режимах\n" + +#: help.c:239 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [МАСКА] список доменов\n" + +#: help.c:240 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [МАСКА] список прав по умолчанию\n" + +#: help.c:241 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [МАСКА] список сторонних таблиц\n" + +#: help.c:242 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [МАСКА] список сторонних таблиц\n" + +#: help.c:243 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [МАСКА] список сторонних серверов\n" + +#: help.c:244 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [МАСКА] список сопоставлений пользователей\n" + +#: help.c:245 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [МАСКА] список обёрток сторонних данных\n" + +#: help.c:246 +#, c-format +msgid "" +" \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] " +"functions\n" +msgstr "" +" \\df[anptw][S+] [МАСКА] список [только агрегатных/обычных/(процедур)/\n" +" триггерных/оконных] функций\n" + +#: help.c:247 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [МАСКА] список конфигураций текстового поиска\n" + +#: help.c:248 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [МАСКА] список словарей текстового поиска\n" + +#: help.c:249 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [МАСКА] список анализаторов текстового поиска\n" + +#: help.c:250 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [МАСКА] список шаблонов текстового поиска\n" + +#: help.c:251 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [МАСКА] список ролей\n" + +#: help.c:252 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [МАСКА] список индексов\n" + +#: help.c:253 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr "" +" \\dl список больших объектов (то же, что и \\lo_list)\n" + +#: help.c:254 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [МАСКА] список языков процедур\n" + +#: help.c:255 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [МАСКА] список материализованных представлений\n" + +#: help.c:256 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [МАСКА] список схем\n" + +#: help.c:257 +#, c-format +msgid " \\do[S] [PATTERN] list operators\n" +msgstr " \\do[S] [МАСКА] список операторов\n" + +#: help.c:258 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [МАСКА] список правил сортировки\n" + +#: help.c:259 +#, c-format +msgid "" +" \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr "" +" \\dp [МАСКА] список прав доступа к таблицам, представлениям и\n" +" последовательностям\n" + +#: help.c:260 +#, c-format +msgid "" +" \\dP[itn+] [PATTERN] list [only index/table] partitioned relations " +"[n=nested]\n" +msgstr "" +" \\dP[itn+] [МАСКА] список секционированных отношений\n" +" [только индексов (i)/таблиц (t)], с вложенностью " +"(n)\n" + +# well-spelled: МАСК +#: help.c:261 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [МАСК1 [МАСК2]] список параметров роли на уровне БД\n" + +#: help.c:262 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [МАСКА] список публикаций для репликации\n" + +#: help.c:263 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [МАСКА] список подписок на репликацию\n" + +#: help.c:264 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [МАСКА] список последовательностей\n" + +#: help.c:265 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [МАСКА] список таблиц\n" + +#: help.c:266 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [МАСКА] список типов данных\n" + +#: help.c:267 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [МАСКА] список ролей\n" + +#: help.c:268 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [МАСКА] список представлений\n" + +#: help.c:269 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [МАСКА] список расширений\n" + +#: help.c:270 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [МАСКА] список событийных триггеров\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [МАСКА] список баз данных\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] ИМЯ_ФУНКЦИИ показать определение функции\n" + +# well-spelled: ПРЕДСТ +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] ИМЯ_ПРЕДСТ показать определение представления\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [МАСКА] то же, что и \\dp\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "Форматирование\n" + +#: help.c:278 +#, c-format +msgid "" +" \\a toggle between unaligned and aligned output mode\n" +msgstr "" +" \\a переключение режимов вывода:\n" +" неформатированный/выровненный\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr "" +" \\C [СТРОКА] задать заголовок таблицы или убрать, если не " +"задан\n" + +#: help.c:280 +#, c-format +msgid "" +" \\f [STRING] show or set field separator for unaligned query " +"output\n" +msgstr "" +" \\f [СТРОКА] показать или установить разделитель полей для\n" +" неформатированного вывода\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr "" +" \\H переключить режим вывода в HTML (текущий: %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [ИМЯ [ЗНАЧЕНИЕ]] установить параметр вывода таблицы\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] режим вывода только строк (сейчас: %s)\n" + +#: help.c:292 +#, c-format +msgid "" +" \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr "" +" \\T [СТРОКА] задать атрибуты для
или убрать, если не " +"заданы\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr "" +" \\x [on|off|auto] переключить режим расширенного вывода (сейчас: " +"%s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "Соединение\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[БД|- ПОЛЬЗОВАТЕЛЬ|- СЕРВЕР|- ПОРТ|-] | conninfo}\n" +" подключиться к другой базе данных\n" +" (текущая: \"%s\")\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[БД|- ПОЛЬЗОВАТЕЛЬ|- СЕРВЕР|- ПОРТ|-] | conninfo}\n" +" подключиться к другой базе данных\n" +" (сейчас подключения нет)\n" + +#: help.c:305 +#, c-format +msgid "" +" \\conninfo display information about current connection\n" +msgstr " \\conninfo информация о текущем соединении\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [КОДИРОВКА] показать/установить клиентскую кодировку\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr " \\password [ИМЯ] безопасно сменить пароль пользователя\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "Операционная система\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [ПУТЬ] сменить текущий каталог\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr "" +" \\setenv ИМЯ [ЗНАЧЕНИЕ] установить или сбросить переменную окружения\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] включить/выключить секундомер (сейчас: %s)\n" + +#: help.c:315 +#, c-format +msgid "" +" \\! [COMMAND] execute command in shell or start interactive " +"shell\n" +msgstr "" +" \\! [КОМАНДА] выполнить команду в командной оболочке\n" +" или запустить интерактивную оболочку\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "Переменные\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr "" +" \\prompt [ТЕКСТ] ИМЯ предложить пользователю задать внутреннюю " +"переменную\n" + +#: help.c:320 +#, c-format +msgid "" +" \\set [NAME [VALUE]] set internal variable, or list all if no " +"parameters\n" +msgstr "" +" \\set [ИМЯ [ЗНАЧЕНИЕ]] установить внутреннюю переменную или вывести все,\n" +" если имя не задано\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset ИМЯ сбросить (удалить) внутреннюю переменную\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "Большие объекты\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID ФАЙЛ\n" +" \\lo_import ФАЙЛ [КОММЕНТАРИЙ]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID операции с большими объектами\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"Список специальных переменных\n" +"\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "Переменные psql:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=ИМЯ=ЗНАЧЕНИЕ\n" +" или \\set ИМЯ ЗНАЧЕНИЕ в приглашении psql\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" если установлен, успешные SQL-команды фиксируются автоматически\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" определяет регистр для автодополнения ключевых слов SQL\n" +" [lower (нижний), upper (верхний),\n" +" preserve-lower (сохранять нижний),\n" +" preserve-upper (сохранять верхний)]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" имя текущей подключённой базы данных\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" определяет, что выдаётся на стандартный вывод\n" +" [all (всё), errors (ошибки), none (ничего),\n" +" queries (запросы)]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" если включено, выводит внутренние запросы, порождаемые командами с \\;\n" +" если установлено значение \"noexec\", они выводятся, но не выполняются\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" текущая кодировка клиентского набора символов\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" true в случае ошибки в последнем запросе, иначе — false\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = " +"unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" число результирующих строк, извлекаемых и отображаемых за раз\n" +" (0 = без ограничений)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" если установлено, табличные методы доступа не выводятся\n" + +#: help.c:379 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" управляет историей команд [ignorespace (игнорировать пробелы),\n" +" ignoredups (игнорировать дубли), ignoreboth (и то, и другое)]\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" имя файла, в котором будет сохраняться история команд\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" максимальное число команд, сохраняемых в истории\n" + +#: help.c:385 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" сервер баз данных, к которому установлено подключение\n" + +#: help.c:387 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" количество EOF для завершения интерактивного сеанса\n" + +#: help.c:389 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" значение последнего задействованного OID\n" + +#: help.c:391 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if " +"none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" сообщение и код SQLSTATE последней ошибки, либо пустая строка и " +"\"00000\",\n" +" если ошибки не было\n" + +#: help.c:394 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" если установлено, транзакция не прекращается при ошибке\n" +" (используются неявные точки сохранения)\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" останавливать выполнение пакета команд после ошибки\n" + +#: help.c:398 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" порт сервера для текущего соединения\n" + +#: help.c:400 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" устанавливает стандартное приглашение psql\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous " +"line\n" +msgstr "" +" PROMPT2\n" +" устанавливает приглашение, которое выводится при переносе оператора\n" +" на новую строку\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" устанавливает приглашение для выполнения COPY ... FROM STDIN\n" + +#: help.c:406 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" выводить минимум сообщений (как и с параметром -q)\n" + +#: help.c:408 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" число строк, возвращённых или обработанных последним SQL-запросом, либо " +"0\n" + +#: help.c:410 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" версия сервера (в коротком текстовом и числовом формате)\n" + +#: help.c:413 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" управляет отображением полей контекста сообщений\n" +" [never (не отображать никогда), errors (ошибки), always (всегда]\n" + +#: help.c:415 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" если установлено, конец строки завершает режим ввода SQL-команды\n" +" (как и с параметром -S)\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" пошаговый режим (как и с параметром -s)\n" + +#: help.c:419 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE последнего запроса или \"00000\", если он выполнился без " +"ошибок\n" + +#: help.c:421 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" текущий пользователь, подключённый к БД\n" + +#: help.c:423 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" управляет детализацией отчётов об ошибках [default (по умолчанию),\n" +" verbose (подробно), terse (кратко), sqlstate (код состояния)]\n" + +#: help.c:425 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" версия psql (в развёрнутом, в коротком текстовом и в числовом формате)\n" + +#: help.c:430 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Параметры отображения:\n" + +#: help.c:432 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=ИМЯ[=ЗНАЧЕНИЕ]\n" +" или \\pset ИМЯ [ЗНАЧЕНИЕ] в приглашении psql\n" +"\n" + +#: help.c:434 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" стиль границы (число)\n" + +#: help.c:436 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" целевая ширина для формата с переносом\n" + +#: help.c:438 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (или x)\n" +" расширенный вывод [on (вкл.), off (выкл.), auto (авто)]\n" + +#: help.c:440 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" разделитель полей для неформатированного вывода (по умолчанию \"%s\")\n" + +#: help.c:443 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" устанавливает ноль разделителем полей при неформатированном выводе\n" + +#: help.c:445 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" включает или выключает вывод подписей таблицы [on (вкл.), off (выкл.)]\n" + +#: help.c:447 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" устанавливает формат вывода [unaligned (неформатированный),\n" +"\n" +" aligned (выровненный), wrapped (с переносом), html, asciidoc, ...]\n" + +#: help.c:449 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" задаёт стиль рисования линий границы [ascii, old-ascii, unicode]\n" + +#: help.c:451 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" устанавливает строку, выводимую вместо значения NULL\n" + +#: help.c:453 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of " +"digits\n" +msgstr "" +" numericlocale\n" +" отключает вывод заданного локалью разделителя группы цифр\n" + +#: help.c:455 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" определяет, используется ли внешний постраничник\n" +" [yes (да), no (нет), always (всегда)]\n" + +#: help.c:457 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" разделитель записей (строк) при неформатированном выводе\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" устанавливает ноль разделителем записей при неформатированном выводе\n" + +#: help.c:461 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (или T)\n" +" задаёт атрибуты для тега table в формате html или пропорциональные\n" +" ширины столбцов для выровненных влево данных, в формате latex-longtable\n" + +#: help.c:464 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" задаёт заголовок таблицы для последовательно печатаемых таблиц\n" + +#: help.c:466 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" если установлено, выводятся только непосредственно табличные данные\n" + +#: help.c:468 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" задаёт стиль рисуемых линий Unicode [single (одинарные), double " +"(двойные)]\n" + +#: help.c:473 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Переменные окружения:\n" + +#: help.c:477 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" ИМЯ=ЗНАЧЕНИЕ [ИМЯ=ЗНАЧЕНИЕ] psql ...\n" +" или \\setenv ИМЯ [ЗНАЧЕНИЕ] в приглашении psql\n" +"\n" + +#: help.c:479 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set ИМЯ=ЗНАЧЕНИЕ\n" +" psql ...\n" +" или \\setenv ИМЯ ЗНАЧЕНИЕ в приглашении psql\n" +"\n" + +#: help.c:482 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" число столбцов для форматирования с переносом\n" + +#: help.c:484 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" синоним параметра подключения application_name\n" + +#: help.c:486 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" синоним параметра подключения dbname\n" + +#: help.c:488 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" синоним параметра подключения host\n" + +#: help.c:490 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" пароль для подключения (использовать не рекомендуется)\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" имя файла с паролем\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" синоним параметра подключения port\n" + +#: help.c:496 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" синоним параметра подключения user\n" + +#: help.c:498 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" редактор, вызываемый командами \\e, \\ef и \\ev\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" определяет способ передачи номера строки при вызове редактора\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" альтернативное размещение файла с историей команд\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" имя программы внешнего постраничника\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" альтернативное размещение пользовательского файла .psqlrc\n" + +#: help.c:508 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" оболочка, вызываемая командой \\!\n" + +#: help.c:510 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" каталог для временных файлов\n" + +#: help.c:555 +msgid "Available help:\n" +msgstr "Имеющаяся справка:\n" + +#: help.c:650 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"Команда: %s\n" +"Описание: %s\n" +"Синтаксис:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" + +#: help.c:673 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"Нет справки по команде \"%s\".\n" +"Попробуйте \\h без аргументов и посмотрите, что есть.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "не удалось прочитать входной файл: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "не удалось сохранить историю в файле \"%s\": %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "в данной среде история не поддерживается" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: нет соединения с базой данных" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: текущая транзакция прервана" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: неизвестное состояние транзакции" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "Большие объекты" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "выход из блока \\if" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "Чтобы выйти из %s, введите \"\\q\".\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Результат выдаётся в специальном формате выгрузки PostgreSQL.\n" +"Чтобы восстановить базу данных из этого формата, воспользуйтесь программой " +"командной строки pg_restore.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "" +"Введите \\? для получения справки или нажмите Control-C для очистки буфера " +"ввода." + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "Введите \\? для получения справки." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "Вы используете psql - интерфейс командной строки к PostgreSQL." + +# skip-rule: copyright +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Азы: \\copyright - условия распространения\n" +" \\h - справка по операторам SQL\n" +" \\? - справка по командам psql\n" +" \\g или ; в конце строки - выполнение запроса\n" +" \\q - выход\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "Введите \\q для выхода." + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "Нажмите Control-D для выхода." + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "Нажмите Control-C для выхода." + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "" +"запрос игнорируется; добавьте \\endif или нажмите Ctrl-C для завершения " +"текущего блока \\if" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "в закончившемся потоке команд не хватает \\endif" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "незавершённая строка в кавычках" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: нехватка памяти" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1090 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 +#: sql_help.c:1112 sql_help.c:1114 sql_help.c:1118 sql_help.c:1121 +#: sql_help.c:1122 sql_help.c:1123 sql_help.c:1126 sql_help.c:1128 +#: sql_help.c:1262 sql_help.c:1264 sql_help.c:1267 sql_help.c:1270 +#: sql_help.c:1272 sql_help.c:1274 sql_help.c:1277 sql_help.c:1280 +#: sql_help.c:1391 sql_help.c:1393 sql_help.c:1395 sql_help.c:1398 +#: sql_help.c:1419 sql_help.c:1422 sql_help.c:1425 sql_help.c:1428 +#: sql_help.c:1432 sql_help.c:1434 sql_help.c:1436 sql_help.c:1438 +#: sql_help.c:1452 sql_help.c:1455 sql_help.c:1457 sql_help.c:1459 +#: sql_help.c:1469 sql_help.c:1471 sql_help.c:1481 sql_help.c:1483 +#: sql_help.c:1493 sql_help.c:1496 sql_help.c:1519 sql_help.c:1521 +#: sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 sql_help.c:1530 +#: sql_help.c:1533 sql_help.c:1536 sql_help.c:1586 sql_help.c:1629 +#: sql_help.c:1632 sql_help.c:1634 sql_help.c:1636 sql_help.c:1639 +#: sql_help.c:1641 sql_help.c:1643 sql_help.c:1646 sql_help.c:1696 +#: sql_help.c:1712 sql_help.c:1933 sql_help.c:2002 sql_help.c:2021 +#: sql_help.c:2034 sql_help.c:2091 sql_help.c:2098 sql_help.c:2108 +#: sql_help.c:2129 sql_help.c:2155 sql_help.c:2173 sql_help.c:2200 +#: sql_help.c:2295 sql_help.c:2340 sql_help.c:2364 sql_help.c:2387 +#: sql_help.c:2391 sql_help.c:2425 sql_help.c:2445 sql_help.c:2467 +#: sql_help.c:2481 sql_help.c:2501 sql_help.c:2524 sql_help.c:2554 +#: sql_help.c:2579 sql_help.c:2625 sql_help.c:2903 sql_help.c:2916 +#: sql_help.c:2933 sql_help.c:2949 sql_help.c:2989 sql_help.c:3041 +#: sql_help.c:3045 sql_help.c:3047 sql_help.c:3053 sql_help.c:3071 +#: sql_help.c:3098 sql_help.c:3133 sql_help.c:3145 sql_help.c:3154 +#: sql_help.c:3198 sql_help.c:3212 sql_help.c:3240 sql_help.c:3248 +#: sql_help.c:3260 sql_help.c:3270 sql_help.c:3278 sql_help.c:3286 +#: sql_help.c:3294 sql_help.c:3302 sql_help.c:3311 sql_help.c:3322 +#: sql_help.c:3330 sql_help.c:3338 sql_help.c:3346 sql_help.c:3354 +#: sql_help.c:3364 sql_help.c:3373 sql_help.c:3382 sql_help.c:3390 +#: sql_help.c:3400 sql_help.c:3411 sql_help.c:3419 sql_help.c:3428 +#: sql_help.c:3439 sql_help.c:3448 sql_help.c:3456 sql_help.c:3464 +#: sql_help.c:3472 sql_help.c:3480 sql_help.c:3488 sql_help.c:3496 +#: sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 sql_help.c:3528 +#: sql_help.c:3545 sql_help.c:3554 sql_help.c:3562 sql_help.c:3579 +#: sql_help.c:3594 sql_help.c:3869 sql_help.c:3920 sql_help.c:3949 +#: sql_help.c:3962 sql_help.c:4407 sql_help.c:4455 sql_help.c:4596 +msgid "name" +msgstr "имя" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1783 +#: sql_help.c:3213 sql_help.c:4193 +msgid "aggregate_signature" +msgstr "сигнатура_агр_функции" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1093 sql_help.c:1129 sql_help.c:1271 sql_help.c:1392 +#: sql_help.c:1435 sql_help.c:1456 sql_help.c:1470 sql_help.c:1482 +#: sql_help.c:1495 sql_help.c:1522 sql_help.c:1587 sql_help.c:1640 +msgid "new_name" +msgstr "новое_имя" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1091 sql_help.c:1127 sql_help.c:1332 +#: sql_help.c:1394 sql_help.c:1437 sql_help.c:1458 sql_help.c:1520 +#: sql_help.c:1635 sql_help.c:2889 +msgid "new_owner" +msgstr "новый_владелец" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1095 +#: sql_help.c:1273 sql_help.c:1439 sql_help.c:1460 sql_help.c:1472 +#: sql_help.c:1484 sql_help.c:1524 sql_help.c:1642 +msgid "new_schema" +msgstr "новая_схема" + +#: sql_help.c:44 sql_help.c:1847 sql_help.c:3214 sql_help.c:4222 +msgid "where aggregate_signature is:" +msgstr "где сигнатура_агр_функции:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1801 +#: sql_help.c:1818 sql_help.c:1824 sql_help.c:1848 sql_help.c:1851 +#: sql_help.c:1854 sql_help.c:2003 sql_help.c:2022 sql_help.c:2025 +#: sql_help.c:2296 sql_help.c:2502 sql_help.c:3215 sql_help.c:3218 +#: sql_help.c:3221 sql_help.c:3312 sql_help.c:3401 sql_help.c:3429 +#: sql_help.c:3753 sql_help.c:4101 sql_help.c:4199 sql_help.c:4206 +#: sql_help.c:4212 sql_help.c:4223 sql_help.c:4226 sql_help.c:4229 +msgid "argmode" +msgstr "режим_аргумента" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1802 +#: sql_help.c:1819 sql_help.c:1825 sql_help.c:1849 sql_help.c:1852 +#: sql_help.c:1855 sql_help.c:2004 sql_help.c:2023 sql_help.c:2026 +#: sql_help.c:2297 sql_help.c:2503 sql_help.c:3216 sql_help.c:3219 +#: sql_help.c:3222 sql_help.c:3313 sql_help.c:3402 sql_help.c:3430 +#: sql_help.c:4200 sql_help.c:4207 sql_help.c:4213 sql_help.c:4224 +#: sql_help.c:4227 sql_help.c:4230 +msgid "argname" +msgstr "имя_аргумента" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1803 +#: sql_help.c:1820 sql_help.c:1826 sql_help.c:1850 sql_help.c:1853 +#: sql_help.c:1856 sql_help.c:2298 sql_help.c:2504 sql_help.c:3217 +#: sql_help.c:3220 sql_help.c:3223 sql_help.c:3314 sql_help.c:3403 +#: sql_help.c:3431 sql_help.c:4201 sql_help.c:4208 sql_help.c:4214 +#: sql_help.c:4225 sql_help.c:4228 sql_help.c:4231 +msgid "argtype" +msgstr "тип_аргумента" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1453 sql_help.c:1581 sql_help.c:1613 +#: sql_help.c:1665 sql_help.c:1904 sql_help.c:1911 sql_help.c:2203 +#: sql_help.c:2245 sql_help.c:2252 sql_help.c:2261 sql_help.c:2341 +#: sql_help.c:2555 sql_help.c:2647 sql_help.c:2918 sql_help.c:3099 +#: sql_help.c:3121 sql_help.c:3261 sql_help.c:3616 sql_help.c:3788 +#: sql_help.c:3961 sql_help.c:4658 +msgid "option" +msgstr "параметр" + +#: sql_help.c:113 sql_help.c:927 sql_help.c:1582 sql_help.c:2342 +#: sql_help.c:2556 sql_help.c:3100 sql_help.c:3262 +msgid "where option can be:" +msgstr "где допустимые параметры:" + +#: sql_help.c:114 sql_help.c:2137 +msgid "allowconn" +msgstr "разр_подключения" + +#: sql_help.c:115 sql_help.c:928 sql_help.c:1583 sql_help.c:2138 +#: sql_help.c:2343 sql_help.c:2557 sql_help.c:3101 +msgid "connlimit" +msgstr "предел_подключений" + +#: sql_help.c:116 sql_help.c:2139 +msgid "istemplate" +msgstr "это_шаблон" + +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1276 sql_help.c:1325 +msgid "new_tablespace" +msgstr "новое_табл_пространство" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1140 sql_help.c:1143 sql_help.c:1590 +#: sql_help.c:1594 sql_help.c:1597 sql_help.c:2308 sql_help.c:2508 +#: sql_help.c:3980 sql_help.c:4396 +msgid "configuration_parameter" +msgstr "параметр_конфигурации" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1117 sql_help.c:1120 sql_help.c:1125 sql_help.c:1141 +#: sql_help.c:1142 sql_help.c:1307 sql_help.c:1327 sql_help.c:1375 +#: sql_help.c:1397 sql_help.c:1454 sql_help.c:1538 sql_help.c:1591 +#: sql_help.c:1614 sql_help.c:2204 sql_help.c:2246 sql_help.c:2253 +#: sql_help.c:2262 sql_help.c:2309 sql_help.c:2310 sql_help.c:2372 +#: sql_help.c:2375 sql_help.c:2409 sql_help.c:2509 sql_help.c:2510 +#: sql_help.c:2527 sql_help.c:2648 sql_help.c:2678 sql_help.c:2783 +#: sql_help.c:2796 sql_help.c:2810 sql_help.c:2851 sql_help.c:2875 +#: sql_help.c:2892 sql_help.c:2919 sql_help.c:3122 sql_help.c:3789 +#: sql_help.c:4397 sql_help.c:4398 +msgid "value" +msgstr "значение" + +#: sql_help.c:197 +msgid "target_role" +msgstr "целевая_роль" + +#: sql_help.c:198 sql_help.c:2188 sql_help.c:2603 sql_help.c:2608 +#: sql_help.c:3735 sql_help.c:3742 sql_help.c:3756 sql_help.c:3762 +#: sql_help.c:4083 sql_help.c:4090 sql_help.c:4104 sql_help.c:4110 +msgid "schema_name" +msgstr "имя_схемы" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "предложение_GRANT_или_REVOKE" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "где допустимое предложение_GRANT_или_REVOKE:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1275 sql_help.c:1601 sql_help.c:2346 sql_help.c:2347 +#: sql_help.c:2348 sql_help.c:2349 sql_help.c:2350 sql_help.c:2483 +#: sql_help.c:2560 sql_help.c:2561 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 sql_help.c:3104 sql_help.c:3105 sql_help.c:3106 +#: sql_help.c:3107 sql_help.c:3108 sql_help.c:3768 sql_help.c:3772 +#: sql_help.c:4116 sql_help.c:4120 sql_help.c:4417 +msgid "role_name" +msgstr "имя_роли" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1342 sql_help.c:1354 sql_help.c:1379 sql_help.c:1631 +#: sql_help.c:2158 sql_help.c:2162 sql_help.c:2265 sql_help.c:2270 +#: sql_help.c:2368 sql_help.c:2778 sql_help.c:2791 sql_help.c:2805 +#: sql_help.c:2814 sql_help.c:2826 sql_help.c:2855 sql_help.c:3820 +#: sql_help.c:3835 sql_help.c:3837 sql_help.c:4282 sql_help.c:4283 +#: sql_help.c:4292 sql_help.c:4333 sql_help.c:4334 sql_help.c:4335 +#: sql_help.c:4336 sql_help.c:4337 sql_help.c:4338 sql_help.c:4371 +#: sql_help.c:4372 sql_help.c:4377 sql_help.c:4382 sql_help.c:4521 +#: sql_help.c:4522 sql_help.c:4531 sql_help.c:4572 sql_help.c:4573 +#: sql_help.c:4574 sql_help.c:4575 sql_help.c:4576 sql_help.c:4577 +#: sql_help.c:4624 sql_help.c:4626 sql_help.c:4685 sql_help.c:4741 +#: sql_help.c:4742 sql_help.c:4751 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +msgid "expression" +msgstr "выражение" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "ограничение_домена" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1268 sql_help.c:1313 sql_help.c:1314 sql_help.c:1315 +#: sql_help.c:1341 sql_help.c:1353 sql_help.c:1370 sql_help.c:1789 +#: sql_help.c:1791 sql_help.c:2161 sql_help.c:2264 sql_help.c:2269 +#: sql_help.c:2813 sql_help.c:2825 sql_help.c:3832 +msgid "constraint_name" +msgstr "имя_ограничения" + +#: sql_help.c:244 sql_help.c:1269 +msgid "new_constraint_name" +msgstr "имя_нового_ограничения" + +#: sql_help.c:317 sql_help.c:1073 +msgid "new_version" +msgstr "новая_версия" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "элемент_объект" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "где элемент_объект:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1781 sql_help.c:1786 sql_help.c:1793 +#: sql_help.c:1794 sql_help.c:1795 sql_help.c:1796 sql_help.c:1797 +#: sql_help.c:1798 sql_help.c:1799 sql_help.c:1804 sql_help.c:1806 +#: sql_help.c:1810 sql_help.c:1812 sql_help.c:1816 sql_help.c:1821 +#: sql_help.c:1822 sql_help.c:1829 sql_help.c:1830 sql_help.c:1831 +#: sql_help.c:1832 sql_help.c:1833 sql_help.c:1834 sql_help.c:1835 +#: sql_help.c:1836 sql_help.c:1837 sql_help.c:1838 sql_help.c:1839 +#: sql_help.c:1844 sql_help.c:1845 sql_help.c:4189 sql_help.c:4194 +#: sql_help.c:4195 sql_help.c:4196 sql_help.c:4197 sql_help.c:4203 +#: sql_help.c:4204 sql_help.c:4209 sql_help.c:4210 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4217 sql_help.c:4218 sql_help.c:4219 +#: sql_help.c:4220 +msgid "object_name" +msgstr "имя_объекта" + +# well-spelled: агр +#: sql_help.c:326 sql_help.c:1782 sql_help.c:4192 +msgid "aggregate_name" +msgstr "имя_агр_функции" + +#: sql_help.c:328 sql_help.c:1784 sql_help.c:2068 sql_help.c:2072 +#: sql_help.c:2074 sql_help.c:3231 +msgid "source_type" +msgstr "исходный_тип" + +#: sql_help.c:329 sql_help.c:1785 sql_help.c:2069 sql_help.c:2073 +#: sql_help.c:2075 sql_help.c:3232 +msgid "target_type" +msgstr "целевой_тип" + +#: sql_help.c:336 sql_help.c:774 sql_help.c:1800 sql_help.c:2070 +#: sql_help.c:2111 sql_help.c:2176 sql_help.c:2426 sql_help.c:2457 +#: sql_help.c:2995 sql_help.c:4100 sql_help.c:4198 sql_help.c:4311 +#: sql_help.c:4315 sql_help.c:4319 sql_help.c:4322 sql_help.c:4550 +#: sql_help.c:4554 sql_help.c:4558 sql_help.c:4561 sql_help.c:4770 +#: sql_help.c:4774 sql_help.c:4778 sql_help.c:4781 +msgid "function_name" +msgstr "имя_функции" + +#: sql_help.c:341 sql_help.c:767 sql_help.c:1807 sql_help.c:2450 +msgid "operator_name" +msgstr "имя_оператора" + +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1808 +#: sql_help.c:2427 sql_help.c:3355 +msgid "left_type" +msgstr "тип_слева" + +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1809 +#: sql_help.c:2428 sql_help.c:3356 +msgid "right_type" +msgstr "тип_справа" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1359 sql_help.c:1811 sql_help.c:1813 sql_help.c:2447 +#: sql_help.c:2468 sql_help.c:2831 sql_help.c:3365 sql_help.c:3374 +msgid "index_method" +msgstr "метод_индекса" + +#: sql_help.c:349 sql_help.c:1817 sql_help.c:4205 +msgid "procedure_name" +msgstr "имя_процедуры" + +#: sql_help.c:353 sql_help.c:1823 sql_help.c:3752 sql_help.c:4211 +msgid "routine_name" +msgstr "имя_подпрограммы" + +#: sql_help.c:365 sql_help.c:1331 sql_help.c:1840 sql_help.c:2304 +#: sql_help.c:2507 sql_help.c:2786 sql_help.c:2962 sql_help.c:3536 +#: sql_help.c:3766 sql_help.c:4114 +msgid "type_name" +msgstr "имя_типа" + +#: sql_help.c:366 sql_help.c:1841 sql_help.c:2303 sql_help.c:2506 +#: sql_help.c:2963 sql_help.c:3189 sql_help.c:3537 sql_help.c:3758 +#: sql_help.c:4106 +msgid "lang_name" +msgstr "имя_языка" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "и сигнатура_агр_функции:" + +#: sql_help.c:392 sql_help.c:1935 sql_help.c:2201 +msgid "handler_function" +msgstr "функция_обработчик" + +#: sql_help.c:393 sql_help.c:2202 +msgid "validator_function" +msgstr "функция_проверки" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1263 sql_help.c:1529 +msgid "action" +msgstr "действие" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1265 +#: sql_help.c:1283 sql_help.c:1287 sql_help.c:1288 sql_help.c:1292 +#: sql_help.c:1294 sql_help.c:1295 sql_help.c:1296 sql_help.c:1297 +#: sql_help.c:1299 sql_help.c:1302 sql_help.c:1303 sql_help.c:1305 +#: sql_help.c:1308 sql_help.c:1310 sql_help.c:1355 sql_help.c:1357 +#: sql_help.c:1364 sql_help.c:1373 sql_help.c:1378 sql_help.c:1630 +#: sql_help.c:1633 sql_help.c:1637 sql_help.c:1673 sql_help.c:1788 +#: sql_help.c:1901 sql_help.c:1907 sql_help.c:1920 sql_help.c:1921 +#: sql_help.c:1922 sql_help.c:2243 sql_help.c:2256 sql_help.c:2301 +#: sql_help.c:2367 sql_help.c:2373 sql_help.c:2406 sql_help.c:2633 +#: sql_help.c:2661 sql_help.c:2662 sql_help.c:2769 sql_help.c:2777 +#: sql_help.c:2787 sql_help.c:2790 sql_help.c:2800 sql_help.c:2804 +#: sql_help.c:2827 sql_help.c:2829 sql_help.c:2836 sql_help.c:2849 +#: sql_help.c:2854 sql_help.c:2872 sql_help.c:2998 sql_help.c:3134 +#: sql_help.c:3737 sql_help.c:3738 sql_help.c:3819 sql_help.c:3834 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:4085 sql_help.c:4086 +#: sql_help.c:4191 sql_help.c:4342 sql_help.c:4581 sql_help.c:4623 +#: sql_help.c:4625 sql_help.c:4627 sql_help.c:4673 sql_help.c:4801 +msgid "column_name" +msgstr "имя_столбца" + +#: sql_help.c:444 sql_help.c:664 sql_help.c:1266 sql_help.c:1638 +msgid "new_column_name" +msgstr "новое_имя_столбца" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1282 sql_help.c:1539 +msgid "where action is one of:" +msgstr "где допустимое действие:" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1284 +#: sql_help.c:1289 sql_help.c:1541 sql_help.c:1545 sql_help.c:2156 +#: sql_help.c:2244 sql_help.c:2446 sql_help.c:2626 sql_help.c:2770 +#: sql_help.c:3043 sql_help.c:3921 +msgid "data_type" +msgstr "тип_данных" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1285 sql_help.c:1290 +#: sql_help.c:1542 sql_help.c:1546 sql_help.c:2157 sql_help.c:2247 +#: sql_help.c:2369 sql_help.c:2771 sql_help.c:2779 sql_help.c:2792 +#: sql_help.c:2806 sql_help.c:3044 sql_help.c:3050 sql_help.c:3829 +msgid "collation" +msgstr "правило_сортировки" + +#: sql_help.c:453 sql_help.c:1286 sql_help.c:2248 sql_help.c:2257 +#: sql_help.c:2772 sql_help.c:2788 sql_help.c:2801 +msgid "column_constraint" +msgstr "ограничение_столбца" + +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1304 sql_help.c:4670 +msgid "integer" +msgstr "целое" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1306 +#: sql_help.c:1309 +msgid "attribute_option" +msgstr "атрибут" + +#: sql_help.c:473 sql_help.c:1311 sql_help.c:2249 sql_help.c:2258 +#: sql_help.c:2773 sql_help.c:2789 sql_help.c:2802 +msgid "table_constraint" +msgstr "ограничение_таблицы" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1316 +#: sql_help.c:1317 sql_help.c:1318 sql_help.c:1319 sql_help.c:1842 +msgid "trigger_name" +msgstr "имя_триггера" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1329 sql_help.c:1330 +#: sql_help.c:2250 sql_help.c:2255 sql_help.c:2776 sql_help.c:2799 +msgid "parent_table" +msgstr "таблица_родитель" + +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1498 sql_help.c:2187 +msgid "extension_name" +msgstr "имя_расширения" + +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2305 +msgid "execution_cost" +msgstr "стоимость_выполнения" + +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2306 +msgid "result_rows" +msgstr "строк_в_результате" + +#: sql_help.c:543 sql_help.c:2307 +msgid "support_function" +msgstr "вспомогательная_функция" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1580 sql_help.c:1588 +#: sql_help.c:1592 sql_help.c:1595 sql_help.c:1598 sql_help.c:2604 +#: sql_help.c:2606 sql_help.c:2609 sql_help.c:2610 sql_help.c:3736 +#: sql_help.c:3740 sql_help.c:3743 sql_help.c:3745 sql_help.c:3747 +#: sql_help.c:3749 sql_help.c:3751 sql_help.c:3757 sql_help.c:3759 +#: sql_help.c:3761 sql_help.c:3763 sql_help.c:3765 sql_help.c:3767 +#: sql_help.c:3769 sql_help.c:3770 sql_help.c:4084 sql_help.c:4088 +#: sql_help.c:4091 sql_help.c:4093 sql_help.c:4095 sql_help.c:4097 +#: sql_help.c:4099 sql_help.c:4105 sql_help.c:4107 sql_help.c:4109 +#: sql_help.c:4111 sql_help.c:4113 sql_help.c:4115 sql_help.c:4117 +#: sql_help.c:4118 +msgid "role_specification" +msgstr "указание_роли" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:1611 sql_help.c:2130 +#: sql_help.c:2612 sql_help.c:3119 sql_help.c:3570 sql_help.c:4427 +msgid "user_name" +msgstr "имя_пользователя" + +#: sql_help.c:568 sql_help.c:945 sql_help.c:1600 sql_help.c:2611 +#: sql_help.c:3771 sql_help.c:4119 +msgid "where role_specification can be:" +msgstr "где допустимое указание_роли:" + +#: sql_help.c:570 +msgid "group_name" +msgstr "имя_группы" + +#: sql_help.c:591 sql_help.c:1376 sql_help.c:2136 sql_help.c:2376 +#: sql_help.c:2410 sql_help.c:2784 sql_help.c:2797 sql_help.c:2811 +#: sql_help.c:2852 sql_help.c:2876 sql_help.c:2888 sql_help.c:3764 +#: sql_help.c:4112 +msgid "tablespace_name" +msgstr "табл_пространство" + +#: sql_help.c:593 sql_help.c:681 sql_help.c:1324 sql_help.c:1333 +#: sql_help.c:1371 sql_help.c:1722 +msgid "index_name" +msgstr "имя_индекса" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1326 +#: sql_help.c:1328 sql_help.c:1374 sql_help.c:2374 sql_help.c:2408 +#: sql_help.c:2782 sql_help.c:2795 sql_help.c:2809 sql_help.c:2850 +#: sql_help.c:2874 +msgid "storage_parameter" +msgstr "параметр_хранения" + +#: sql_help.c:602 +msgid "column_number" +msgstr "номер_столбца" + +#: sql_help.c:626 sql_help.c:1805 sql_help.c:4202 +msgid "large_object_oid" +msgstr "oid_большого_объекта" + +#: sql_help.c:713 sql_help.c:2431 +msgid "res_proc" +msgstr "процедура_ограничения" + +#: sql_help.c:714 sql_help.c:2432 +msgid "join_proc" +msgstr "процедура_соединения" + +#: sql_help.c:766 sql_help.c:778 sql_help.c:2449 +msgid "strategy_number" +msgstr "номер_стратегии" + +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2451 sql_help.c:2452 +#: sql_help.c:2455 sql_help.c:2456 +msgid "op_type" +msgstr "тип_операции" + +#: sql_help.c:770 sql_help.c:2453 +msgid "sort_family_name" +msgstr "семейство_сортировки" + +#: sql_help.c:771 sql_help.c:781 sql_help.c:2454 +msgid "support_number" +msgstr "номер_опорной_процедуры" + +#: sql_help.c:775 sql_help.c:2071 sql_help.c:2458 sql_help.c:2965 +#: sql_help.c:2967 +msgid "argument_type" +msgstr "тип_аргумента" + +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1494 sql_help.c:1497 +#: sql_help.c:1672 sql_help.c:1721 sql_help.c:1790 sql_help.c:1815 +#: sql_help.c:1828 sql_help.c:1843 sql_help.c:1900 sql_help.c:1906 +#: sql_help.c:2242 sql_help.c:2254 sql_help.c:2365 sql_help.c:2405 +#: sql_help.c:2482 sql_help.c:2525 sql_help.c:2581 sql_help.c:2632 +#: sql_help.c:2663 sql_help.c:2768 sql_help.c:2785 sql_help.c:2798 +#: sql_help.c:2871 sql_help.c:2991 sql_help.c:3168 sql_help.c:3391 +#: sql_help.c:3440 sql_help.c:3546 sql_help.c:3734 sql_help.c:3739 +#: sql_help.c:3785 sql_help.c:3817 sql_help.c:4082 sql_help.c:4087 +#: sql_help.c:4190 sql_help.c:4297 sql_help.c:4299 sql_help.c:4348 +#: sql_help.c:4387 sql_help.c:4536 sql_help.c:4538 sql_help.c:4587 +#: sql_help.c:4621 sql_help.c:4672 sql_help.c:4756 sql_help.c:4758 +#: sql_help.c:4807 +msgid "table_name" +msgstr "имя_таблицы" + +#: sql_help.c:811 sql_help.c:2484 +msgid "using_expression" +msgstr "выражение_использования" + +#: sql_help.c:812 sql_help.c:2485 +msgid "check_expression" +msgstr "выражение_проверки" + +#: sql_help.c:886 sql_help.c:2526 +msgid "publication_parameter" +msgstr "параметр_публикации" + +#: sql_help.c:929 sql_help.c:1584 sql_help.c:2344 sql_help.c:2558 +#: sql_help.c:3102 +msgid "password" +msgstr "пароль" + +#: sql_help.c:930 sql_help.c:1585 sql_help.c:2345 sql_help.c:2559 +#: sql_help.c:3103 +msgid "timestamp" +msgstr "timestamp" + +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1589 +#: sql_help.c:1593 sql_help.c:1596 sql_help.c:1599 sql_help.c:3744 +#: sql_help.c:4092 +msgid "database_name" +msgstr "имя_БД" + +#: sql_help.c:1048 sql_help.c:2627 +msgid "increment" +msgstr "шаг" + +#: sql_help.c:1049 sql_help.c:2628 +msgid "minvalue" +msgstr "мин_значение" + +#: sql_help.c:1050 sql_help.c:2629 +msgid "maxvalue" +msgstr "макс_значение" + +#: sql_help.c:1051 sql_help.c:2630 sql_help.c:4295 sql_help.c:4385 +#: sql_help.c:4534 sql_help.c:4689 sql_help.c:4754 +msgid "start" +msgstr "начальное_значение" + +#: sql_help.c:1052 sql_help.c:1301 +msgid "restart" +msgstr "значение_перезапуска" + +#: sql_help.c:1053 sql_help.c:2631 +msgid "cache" +msgstr "кеш" + +#: sql_help.c:1097 +msgid "new_target" +msgstr "новое_имя" + +#: sql_help.c:1113 sql_help.c:2675 +msgid "conninfo" +msgstr "строка_подключения" + +#: sql_help.c:1115 sql_help.c:2676 +msgid "publication_name" +msgstr "имя_публикации" + +#: sql_help.c:1116 +msgid "set_publication_option" +msgstr "параметр_set_publication" + +#: sql_help.c:1119 +msgid "refresh_option" +msgstr "параметр_обновления" + +#: sql_help.c:1124 sql_help.c:2677 +msgid "subscription_parameter" +msgstr "параметр_подписки" + +#: sql_help.c:1278 sql_help.c:1281 +msgid "partition_name" +msgstr "имя_секции" + +#: sql_help.c:1279 sql_help.c:2259 sql_help.c:2803 +msgid "partition_bound_spec" +msgstr "указание_границ_секции" + +#: sql_help.c:1298 sql_help.c:1345 sql_help.c:2817 +msgid "sequence_options" +msgstr "параметры_последовательности" + +#: sql_help.c:1300 +msgid "sequence_option" +msgstr "параметр_последовательности" + +#: sql_help.c:1312 +msgid "table_constraint_using_index" +msgstr "ограничение_таблицы_с_индексом" + +#: sql_help.c:1320 sql_help.c:1321 sql_help.c:1322 sql_help.c:1323 +msgid "rewrite_rule_name" +msgstr "имя_правила_перезаписи" + +#: sql_help.c:1334 sql_help.c:2842 +msgid "and partition_bound_spec is:" +msgstr "и указание_границ_секции:" + +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:2843 +#: sql_help.c:2844 sql_help.c:2845 +msgid "partition_bound_expr" +msgstr "выражение_границ_секции" + +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:2846 sql_help.c:2847 +msgid "numeric_literal" +msgstr "числовая_константа" + +#: sql_help.c:1340 +msgid "and column_constraint is:" +msgstr "и ограничение_столбца:" + +#: sql_help.c:1343 sql_help.c:2266 sql_help.c:2299 sql_help.c:2505 +#: sql_help.c:2815 +msgid "default_expr" +msgstr "выражение_по_умолчанию" + +#: sql_help.c:1344 sql_help.c:2267 sql_help.c:2816 +msgid "generation_expr" +msgstr "генерирующее_выражение" + +#: sql_help.c:1346 sql_help.c:1347 sql_help.c:1356 sql_help.c:1358 +#: sql_help.c:1362 sql_help.c:2818 sql_help.c:2819 sql_help.c:2828 +#: sql_help.c:2830 sql_help.c:2834 +msgid "index_parameters" +msgstr "параметры_индекса" + +#: sql_help.c:1348 sql_help.c:1365 sql_help.c:2820 sql_help.c:2837 +msgid "reftable" +msgstr "целевая_таблица" + +#: sql_help.c:1349 sql_help.c:1366 sql_help.c:2821 sql_help.c:2838 +msgid "refcolumn" +msgstr "целевой_столбец" + +#: sql_help.c:1350 sql_help.c:1351 sql_help.c:1367 sql_help.c:1368 +#: sql_help.c:2822 sql_help.c:2823 sql_help.c:2839 sql_help.c:2840 +msgid "referential_action" +msgstr "ссылочное_действие" + +#: sql_help.c:1352 sql_help.c:2268 sql_help.c:2824 +msgid "and table_constraint is:" +msgstr "и ограничение_таблицы:" + +#: sql_help.c:1360 sql_help.c:2832 +msgid "exclude_element" +msgstr "объект_исключения" + +#: sql_help.c:1361 sql_help.c:2833 sql_help.c:4293 sql_help.c:4383 +#: sql_help.c:4532 sql_help.c:4687 sql_help.c:4752 +msgid "operator" +msgstr "оператор" + +#: sql_help.c:1363 sql_help.c:2377 sql_help.c:2835 +msgid "predicate" +msgstr "предикат" + +#: sql_help.c:1369 +msgid "and table_constraint_using_index is:" +msgstr "и ограничение_таблицы_с_индексом:" + +#: sql_help.c:1372 sql_help.c:2848 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "параметры_индекса в ограничениях UNIQUE, PRIMARY KEY и EXCLUDE:" + +#: sql_help.c:1377 sql_help.c:2853 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "объект_исключения в ограничении EXCLUDE:" + +#: sql_help.c:1380 sql_help.c:2370 sql_help.c:2780 sql_help.c:2793 +#: sql_help.c:2807 sql_help.c:2856 sql_help.c:3830 +msgid "opclass" +msgstr "класс_оператора" + +#: sql_help.c:1396 sql_help.c:1399 sql_help.c:2891 +msgid "tablespace_option" +msgstr "параметр_табл_пространства" + +#: sql_help.c:1420 sql_help.c:1423 sql_help.c:1429 sql_help.c:1433 +msgid "token_type" +msgstr "тип_фрагмента" + +#: sql_help.c:1421 sql_help.c:1424 +msgid "dictionary_name" +msgstr "имя_словаря" + +#: sql_help.c:1426 sql_help.c:1430 +msgid "old_dictionary" +msgstr "старый_словарь" + +#: sql_help.c:1427 sql_help.c:1431 +msgid "new_dictionary" +msgstr "новый_словарь" + +#: sql_help.c:1526 sql_help.c:1540 sql_help.c:1543 sql_help.c:1544 +#: sql_help.c:3042 +msgid "attribute_name" +msgstr "имя_атрибута" + +#: sql_help.c:1527 +msgid "new_attribute_name" +msgstr "новое_имя_атрибута" + +#: sql_help.c:1531 sql_help.c:1535 +msgid "new_enum_value" +msgstr "новое_значение_перечисления" + +#: sql_help.c:1532 +msgid "neighbor_enum_value" +msgstr "соседнее_значение_перечисления" + +#: sql_help.c:1534 +msgid "existing_enum_value" +msgstr "существующее_значение_перечисления" + +#: sql_help.c:1537 +msgid "property" +msgstr "свойство" + +#: sql_help.c:1612 sql_help.c:2251 sql_help.c:2260 sql_help.c:2643 +#: sql_help.c:3120 sql_help.c:3571 sql_help.c:3750 sql_help.c:3786 +#: sql_help.c:4098 +msgid "server_name" +msgstr "имя_сервера" + +#: sql_help.c:1644 sql_help.c:1647 sql_help.c:3135 +msgid "view_option_name" +msgstr "имя_параметра_представления" + +#: sql_help.c:1645 sql_help.c:3136 +msgid "view_option_value" +msgstr "значение_параметра_представления" + +#: sql_help.c:1666 sql_help.c:1667 sql_help.c:4659 sql_help.c:4660 +msgid "table_and_columns" +msgstr "таблица_и_столбцы" + +#: sql_help.c:1668 sql_help.c:1912 sql_help.c:3619 sql_help.c:3963 +#: sql_help.c:4661 +msgid "where option can be one of:" +msgstr "где допустимый параметр:" + +#: sql_help.c:1669 sql_help.c:1670 sql_help.c:1914 sql_help.c:1917 +#: sql_help.c:2096 sql_help.c:3620 sql_help.c:3621 sql_help.c:3622 +#: sql_help.c:3623 sql_help.c:3624 sql_help.c:3625 sql_help.c:3626 +#: sql_help.c:3627 sql_help.c:4662 sql_help.c:4663 sql_help.c:4664 +#: sql_help.c:4665 sql_help.c:4666 sql_help.c:4667 sql_help.c:4668 +#: sql_help.c:4669 +msgid "boolean" +msgstr "логическое_значение" + +#: sql_help.c:1671 sql_help.c:4671 +msgid "and table_and_columns is:" +msgstr "и таблица_и_столбцы:" + +#: sql_help.c:1687 sql_help.c:4443 sql_help.c:4445 sql_help.c:4469 +msgid "transaction_mode" +msgstr "режим_транзакции" + +#: sql_help.c:1688 sql_help.c:4446 sql_help.c:4470 +msgid "where transaction_mode is one of:" +msgstr "где допустимый режим_транзакции:" + +#: sql_help.c:1697 sql_help.c:4303 sql_help.c:4312 sql_help.c:4316 +#: sql_help.c:4320 sql_help.c:4323 sql_help.c:4542 sql_help.c:4551 +#: sql_help.c:4555 sql_help.c:4559 sql_help.c:4562 sql_help.c:4762 +#: sql_help.c:4771 sql_help.c:4775 sql_help.c:4779 sql_help.c:4782 +msgid "argument" +msgstr "аргумент" + +#: sql_help.c:1787 +msgid "relation_name" +msgstr "имя_отношения" + +#: sql_help.c:1792 sql_help.c:3746 sql_help.c:4094 +msgid "domain_name" +msgstr "имя_домена" + +#: sql_help.c:1814 +msgid "policy_name" +msgstr "имя_политики" + +#: sql_help.c:1827 +msgid "rule_name" +msgstr "имя_правила" + +#: sql_help.c:1846 +msgid "text" +msgstr "текст" + +#: sql_help.c:1871 sql_help.c:3930 sql_help.c:4135 +msgid "transaction_id" +msgstr "код_транзакции" + +#: sql_help.c:1902 sql_help.c:1909 sql_help.c:3856 +msgid "filename" +msgstr "имя_файла" + +#: sql_help.c:1903 sql_help.c:1910 sql_help.c:2583 sql_help.c:2584 +#: sql_help.c:2585 +msgid "command" +msgstr "команда" + +#: sql_help.c:1905 sql_help.c:2582 sql_help.c:2994 sql_help.c:3171 +#: sql_help.c:3840 sql_help.c:4286 sql_help.c:4288 sql_help.c:4376 +#: sql_help.c:4378 sql_help.c:4525 sql_help.c:4527 sql_help.c:4630 +#: sql_help.c:4745 sql_help.c:4747 +msgid "condition" +msgstr "условие" + +#: sql_help.c:1908 sql_help.c:2411 sql_help.c:2877 sql_help.c:3137 +#: sql_help.c:3155 sql_help.c:3821 +msgid "query" +msgstr "запрос" + +#: sql_help.c:1913 +msgid "format_name" +msgstr "имя_формата" + +#: sql_help.c:1915 +msgid "delimiter_character" +msgstr "символ_разделитель" + +#: sql_help.c:1916 +msgid "null_string" +msgstr "представление_NULL" + +#: sql_help.c:1918 +msgid "quote_character" +msgstr "символ_кавычек" + +#: sql_help.c:1919 +msgid "escape_character" +msgstr "спецсимвол" + +#: sql_help.c:1923 +msgid "encoding_name" +msgstr "имя_кодировки" + +#: sql_help.c:1934 +msgid "access_method_type" +msgstr "тип_метода_доступа" + +#: sql_help.c:2005 sql_help.c:2024 sql_help.c:2027 +msgid "arg_data_type" +msgstr "тип_данных_аргумента" + +#: sql_help.c:2006 sql_help.c:2028 sql_help.c:2036 +msgid "sfunc" +msgstr "функция_состояния" + +#: sql_help.c:2007 sql_help.c:2029 sql_help.c:2037 +msgid "state_data_type" +msgstr "тип_данных_состояния" + +#: sql_help.c:2008 sql_help.c:2030 sql_help.c:2038 +msgid "state_data_size" +msgstr "размер_данных_состояния" + +#: sql_help.c:2009 sql_help.c:2031 sql_help.c:2039 +msgid "ffunc" +msgstr "функция_завершения" + +#: sql_help.c:2010 sql_help.c:2040 +msgid "combinefunc" +msgstr "комбинирующая_функция" + +#: sql_help.c:2011 sql_help.c:2041 +msgid "serialfunc" +msgstr "функция_сериализации" + +#: sql_help.c:2012 sql_help.c:2042 +msgid "deserialfunc" +msgstr "функция_десериализации" + +#: sql_help.c:2013 sql_help.c:2032 sql_help.c:2043 +msgid "initial_condition" +msgstr "начальное_условие" + +#: sql_help.c:2014 sql_help.c:2044 +msgid "msfunc" +msgstr "функция_состояния_движ" + +#: sql_help.c:2015 sql_help.c:2045 +msgid "minvfunc" +msgstr "обратная_функция_движ" + +#: sql_help.c:2016 sql_help.c:2046 +msgid "mstate_data_type" +msgstr "тип_данных_состояния_движ" + +#: sql_help.c:2017 sql_help.c:2047 +msgid "mstate_data_size" +msgstr "размер_данных_состояния_движ" + +#: sql_help.c:2018 sql_help.c:2048 +msgid "mffunc" +msgstr "функция_завершения_движ" + +#: sql_help.c:2019 sql_help.c:2049 +msgid "minitial_condition" +msgstr "начальное_условие_движ" + +#: sql_help.c:2020 sql_help.c:2050 +msgid "sort_operator" +msgstr "оператор_сортировки" + +#: sql_help.c:2033 +msgid "or the old syntax" +msgstr "или старый синтаксис" + +#: sql_help.c:2035 +msgid "base_type" +msgstr "базовый_тип" + +#: sql_help.c:2092 sql_help.c:2133 +msgid "locale" +msgstr "код_локали" + +#: sql_help.c:2093 sql_help.c:2134 +msgid "lc_collate" +msgstr "код_правила_сортировки" + +#: sql_help.c:2094 sql_help.c:2135 +msgid "lc_ctype" +msgstr "код_классификации_символов" + +#: sql_help.c:2095 sql_help.c:4188 +msgid "provider" +msgstr "поставщик" + +#: sql_help.c:2097 sql_help.c:2189 +msgid "version" +msgstr "версия" + +#: sql_help.c:2099 +msgid "existing_collation" +msgstr "существующее_правило_сортировки" + +#: sql_help.c:2109 +msgid "source_encoding" +msgstr "исходная_кодировка" + +#: sql_help.c:2110 +msgid "dest_encoding" +msgstr "целевая_кодировка" + +#: sql_help.c:2131 sql_help.c:2917 +msgid "template" +msgstr "шаблон" + +#: sql_help.c:2132 +msgid "encoding" +msgstr "кодировка" + +#: sql_help.c:2159 +msgid "constraint" +msgstr "ограничение" + +#: sql_help.c:2160 +msgid "where constraint is:" +msgstr "где ограничение:" + +#: sql_help.c:2174 sql_help.c:2580 sql_help.c:2990 +msgid "event" +msgstr "событие" + +#: sql_help.c:2175 +msgid "filter_variable" +msgstr "переменная_фильтра" + +#: sql_help.c:2263 sql_help.c:2812 +msgid "where column_constraint is:" +msgstr "где ограничение_столбца:" + +#: sql_help.c:2300 +msgid "rettype" +msgstr "тип_возврата" + +#: sql_help.c:2302 +msgid "column_type" +msgstr "тип_столбца" + +#: sql_help.c:2311 sql_help.c:2511 +msgid "definition" +msgstr "определение" + +#: sql_help.c:2312 sql_help.c:2512 +msgid "obj_file" +msgstr "объектный_файл" + +#: sql_help.c:2313 sql_help.c:2513 +msgid "link_symbol" +msgstr "символ_в_экспорте" + +#: sql_help.c:2351 sql_help.c:2565 sql_help.c:3109 +msgid "uid" +msgstr "uid" + +#: sql_help.c:2366 sql_help.c:2407 sql_help.c:2781 sql_help.c:2794 +#: sql_help.c:2808 sql_help.c:2873 +msgid "method" +msgstr "метод" + +#: sql_help.c:2371 +msgid "opclass_parameter" +msgstr "параметр_класса_оп" + +#: sql_help.c:2388 +msgid "call_handler" +msgstr "обработчик_вызова" + +#: sql_help.c:2389 +msgid "inline_handler" +msgstr "обработчик_внедрённого_кода" + +#: sql_help.c:2390 +msgid "valfunction" +msgstr "функция_проверки" + +#: sql_help.c:2429 +msgid "com_op" +msgstr "коммут_оператор" + +#: sql_help.c:2430 +msgid "neg_op" +msgstr "обратный_оператор" + +#: sql_help.c:2448 +msgid "family_name" +msgstr "имя_семейства" + +#: sql_help.c:2459 +msgid "storage_type" +msgstr "тип_хранения" + +#: sql_help.c:2586 sql_help.c:2997 +msgid "where event can be one of:" +msgstr "где допустимое событие:" + +#: sql_help.c:2605 sql_help.c:2607 +msgid "schema_element" +msgstr "элемент_схемы" + +#: sql_help.c:2644 +msgid "server_type" +msgstr "тип_сервера" + +#: sql_help.c:2645 +msgid "server_version" +msgstr "версия_сервера" + +#: sql_help.c:2646 sql_help.c:3748 sql_help.c:4096 +msgid "fdw_name" +msgstr "имя_обёртки_сторонних_данных" + +#: sql_help.c:2659 +msgid "statistics_name" +msgstr "имя_статистики" + +#: sql_help.c:2660 +msgid "statistics_kind" +msgstr "вид_статистики" + +#: sql_help.c:2674 +msgid "subscription_name" +msgstr "имя_подписки" + +#: sql_help.c:2774 +msgid "source_table" +msgstr "исходная_таблица" + +#: sql_help.c:2775 +msgid "like_option" +msgstr "параметр_порождения" + +#: sql_help.c:2841 +msgid "and like_option is:" +msgstr "и параметр_порождения:" + +#: sql_help.c:2890 +msgid "directory" +msgstr "каталог" + +#: sql_help.c:2904 +msgid "parser_name" +msgstr "имя_анализатора" + +#: sql_help.c:2905 +msgid "source_config" +msgstr "исходная_конфигурация" + +#: sql_help.c:2934 +msgid "start_function" +msgstr "функция_начала" + +#: sql_help.c:2935 +msgid "gettoken_function" +msgstr "функция_выдачи_фрагмента" + +#: sql_help.c:2936 +msgid "end_function" +msgstr "функция_окончания" + +#: sql_help.c:2937 +msgid "lextypes_function" +msgstr "функция_лекс_типов" + +#: sql_help.c:2938 +msgid "headline_function" +msgstr "функция_создания_выдержек" + +#: sql_help.c:2950 +msgid "init_function" +msgstr "функция_инициализации" + +#: sql_help.c:2951 +msgid "lexize_function" +msgstr "функция_выделения_лексем" + +#: sql_help.c:2964 +msgid "from_sql_function_name" +msgstr "имя_функции_из_sql" + +#: sql_help.c:2966 +msgid "to_sql_function_name" +msgstr "имя_функции_в_sql" + +#: sql_help.c:2992 +msgid "referenced_table_name" +msgstr "ссылающаяся_таблица" + +#: sql_help.c:2993 +msgid "transition_relation_name" +msgstr "имя_переходного_отношения" + +#: sql_help.c:2996 +msgid "arguments" +msgstr "аргументы" + +#: sql_help.c:3046 sql_help.c:4221 +msgid "label" +msgstr "метка" + +#: sql_help.c:3048 +msgid "subtype" +msgstr "подтип" + +#: sql_help.c:3049 +msgid "subtype_operator_class" +msgstr "класс_оператора_подтипа" + +#: sql_help.c:3051 +msgid "canonical_function" +msgstr "каноническая_функция" + +#: sql_help.c:3052 +msgid "subtype_diff_function" +msgstr "функция_различий_подтипа" + +#: sql_help.c:3054 +msgid "input_function" +msgstr "функция_ввода" + +#: sql_help.c:3055 +msgid "output_function" +msgstr "функция_вывода" + +#: sql_help.c:3056 +msgid "receive_function" +msgstr "функция_получения" + +#: sql_help.c:3057 +msgid "send_function" +msgstr "функция_отправки" + +#: sql_help.c:3058 +msgid "type_modifier_input_function" +msgstr "функция_ввода_модификатора_типа" + +#: sql_help.c:3059 +msgid "type_modifier_output_function" +msgstr "функция_вывода_модификатора_типа" + +#: sql_help.c:3060 +msgid "analyze_function" +msgstr "функция_анализа" + +#: sql_help.c:3061 +msgid "internallength" +msgstr "внутр_длина" + +#: sql_help.c:3062 +msgid "alignment" +msgstr "выравнивание" + +#: sql_help.c:3063 +msgid "storage" +msgstr "хранение" + +#: sql_help.c:3064 +msgid "like_type" +msgstr "тип_образец" + +#: sql_help.c:3065 +msgid "category" +msgstr "категория" + +#: sql_help.c:3066 +msgid "preferred" +msgstr "предпочитаемый" + +#: sql_help.c:3067 +msgid "default" +msgstr "по_умолчанию" + +#: sql_help.c:3068 +msgid "element" +msgstr "элемент" + +#: sql_help.c:3069 +msgid "delimiter" +msgstr "разделитель" + +#: sql_help.c:3070 +msgid "collatable" +msgstr "сортируемый" + +#: sql_help.c:3167 sql_help.c:3816 sql_help.c:4281 sql_help.c:4370 +#: sql_help.c:4520 sql_help.c:4620 sql_help.c:4740 +msgid "with_query" +msgstr "запрос_WITH" + +#: sql_help.c:3169 sql_help.c:3818 sql_help.c:4300 sql_help.c:4306 +#: sql_help.c:4309 sql_help.c:4313 sql_help.c:4317 sql_help.c:4325 +#: sql_help.c:4539 sql_help.c:4545 sql_help.c:4548 sql_help.c:4552 +#: sql_help.c:4556 sql_help.c:4564 sql_help.c:4622 sql_help.c:4759 +#: sql_help.c:4765 sql_help.c:4768 sql_help.c:4772 sql_help.c:4776 +#: sql_help.c:4784 +msgid "alias" +msgstr "псевдоним" + +#: sql_help.c:3170 sql_help.c:4285 sql_help.c:4327 sql_help.c:4329 +#: sql_help.c:4375 sql_help.c:4524 sql_help.c:4566 sql_help.c:4568 +#: sql_help.c:4629 sql_help.c:4744 sql_help.c:4786 sql_help.c:4788 +msgid "from_item" +msgstr "источник_данных" + +#: sql_help.c:3172 sql_help.c:3653 sql_help.c:3897 sql_help.c:4631 +msgid "cursor_name" +msgstr "имя_курсора" + +#: sql_help.c:3173 sql_help.c:3824 sql_help.c:4632 +msgid "output_expression" +msgstr "выражение_результата" + +#: sql_help.c:3174 sql_help.c:3825 sql_help.c:4284 sql_help.c:4373 +#: sql_help.c:4523 sql_help.c:4633 sql_help.c:4743 +msgid "output_name" +msgstr "имя_результата" + +#: sql_help.c:3190 +msgid "code" +msgstr "внедрённый_код" + +#: sql_help.c:3595 +msgid "parameter" +msgstr "параметр" + +#: sql_help.c:3617 sql_help.c:3618 sql_help.c:3922 +msgid "statement" +msgstr "оператор" + +#: sql_help.c:3652 sql_help.c:3896 +msgid "direction" +msgstr "направление" + +#: sql_help.c:3654 sql_help.c:3898 +msgid "where direction can be empty or one of:" +msgstr "где допустимое направление пустое или:" + +#: sql_help.c:3655 sql_help.c:3656 sql_help.c:3657 sql_help.c:3658 +#: sql_help.c:3659 sql_help.c:3899 sql_help.c:3900 sql_help.c:3901 +#: sql_help.c:3902 sql_help.c:3903 sql_help.c:4294 sql_help.c:4296 +#: sql_help.c:4384 sql_help.c:4386 sql_help.c:4533 sql_help.c:4535 +#: sql_help.c:4688 sql_help.c:4690 sql_help.c:4753 sql_help.c:4755 +msgid "count" +msgstr "число" + +#: sql_help.c:3741 sql_help.c:4089 +msgid "sequence_name" +msgstr "имя_последовательности" + +#: sql_help.c:3754 sql_help.c:4102 +msgid "arg_name" +msgstr "имя_аргумента" + +#: sql_help.c:3755 sql_help.c:4103 +msgid "arg_type" +msgstr "тип_аргумента" + +#: sql_help.c:3760 sql_help.c:4108 +msgid "loid" +msgstr "код_БО" + +#: sql_help.c:3784 +msgid "remote_schema" +msgstr "удалённая_схема" + +#: sql_help.c:3787 +msgid "local_schema" +msgstr "локальная_схема" + +#: sql_help.c:3822 +msgid "conflict_target" +msgstr "объект_конфликта" + +#: sql_help.c:3823 +msgid "conflict_action" +msgstr "действие_при_конфликте" + +#: sql_help.c:3826 +msgid "where conflict_target can be one of:" +msgstr "где допустимый объект_конфликта:" + +#: sql_help.c:3827 +msgid "index_column_name" +msgstr "имя_столбца_индекса" + +#: sql_help.c:3828 +msgid "index_expression" +msgstr "выражение_индекса" + +#: sql_help.c:3831 +msgid "index_predicate" +msgstr "предикат_индекса" + +#: sql_help.c:3833 +msgid "and conflict_action is one of:" +msgstr "а допустимое действие_при_конфликте:" + +#: sql_help.c:3839 sql_help.c:4628 +msgid "sub-SELECT" +msgstr "вложенный_SELECT" + +#: sql_help.c:3848 sql_help.c:3911 sql_help.c:4604 +msgid "channel" +msgstr "канал" + +#: sql_help.c:3870 +msgid "lockmode" +msgstr "режим_блокировки" + +#: sql_help.c:3871 +msgid "where lockmode is one of:" +msgstr "где допустимый режим_блокировки:" + +#: sql_help.c:3912 +msgid "payload" +msgstr "сообщение_нагрузка" + +#: sql_help.c:3939 +msgid "old_role" +msgstr "старая_роль" + +#: sql_help.c:3940 +msgid "new_role" +msgstr "новая_роль" + +#: sql_help.c:3971 sql_help.c:4143 sql_help.c:4151 +msgid "savepoint_name" +msgstr "имя_точки_сохранения" + +#: sql_help.c:4287 sql_help.c:4339 sql_help.c:4526 sql_help.c:4578 +#: sql_help.c:4746 sql_help.c:4798 +msgid "grouping_element" +msgstr "элемент_группирования" + +#: sql_help.c:4289 sql_help.c:4379 sql_help.c:4528 sql_help.c:4748 +msgid "window_name" +msgstr "имя_окна" + +#: sql_help.c:4290 sql_help.c:4380 sql_help.c:4529 sql_help.c:4749 +msgid "window_definition" +msgstr "определение_окна" + +#: sql_help.c:4291 sql_help.c:4305 sql_help.c:4343 sql_help.c:4381 +#: sql_help.c:4530 sql_help.c:4544 sql_help.c:4582 sql_help.c:4750 +#: sql_help.c:4764 sql_help.c:4802 +msgid "select" +msgstr "select" + +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4757 +msgid "where from_item can be one of:" +msgstr "где допустимый источник_данных:" + +#: sql_help.c:4301 sql_help.c:4307 sql_help.c:4310 sql_help.c:4314 +#: sql_help.c:4326 sql_help.c:4540 sql_help.c:4546 sql_help.c:4549 +#: sql_help.c:4553 sql_help.c:4565 sql_help.c:4760 sql_help.c:4766 +#: sql_help.c:4769 sql_help.c:4773 sql_help.c:4785 +msgid "column_alias" +msgstr "псевдоним_столбца" + +#: sql_help.c:4302 sql_help.c:4541 sql_help.c:4761 +msgid "sampling_method" +msgstr "метод_выборки" + +#: sql_help.c:4304 sql_help.c:4543 sql_help.c:4763 +msgid "seed" +msgstr "начальное_число" + +#: sql_help.c:4308 sql_help.c:4341 sql_help.c:4547 sql_help.c:4580 +#: sql_help.c:4767 sql_help.c:4800 +msgid "with_query_name" +msgstr "имя_запроса_WITH" + +#: sql_help.c:4318 sql_help.c:4321 sql_help.c:4324 sql_help.c:4557 +#: sql_help.c:4560 sql_help.c:4563 sql_help.c:4777 sql_help.c:4780 +#: sql_help.c:4783 +msgid "column_definition" +msgstr "определение_столбца" + +#: sql_help.c:4328 sql_help.c:4567 sql_help.c:4787 +msgid "join_type" +msgstr "тип_соединения" + +#: sql_help.c:4330 sql_help.c:4569 sql_help.c:4789 +msgid "join_condition" +msgstr "условие_соединения" + +#: sql_help.c:4331 sql_help.c:4570 sql_help.c:4790 +msgid "join_column" +msgstr "столбец_соединения" + +#: sql_help.c:4332 sql_help.c:4571 sql_help.c:4791 +msgid "and grouping_element can be one of:" +msgstr "где допустимый элемент_группирования:" + +#: sql_help.c:4340 sql_help.c:4579 sql_help.c:4799 +msgid "and with_query is:" +msgstr "и запрос_WITH:" + +#: sql_help.c:4344 sql_help.c:4583 sql_help.c:4803 +msgid "values" +msgstr "значения" + +#: sql_help.c:4345 sql_help.c:4584 sql_help.c:4804 +msgid "insert" +msgstr "insert" + +#: sql_help.c:4346 sql_help.c:4585 sql_help.c:4805 +msgid "update" +msgstr "update" + +#: sql_help.c:4347 sql_help.c:4586 sql_help.c:4806 +msgid "delete" +msgstr "delete" + +#: sql_help.c:4374 +msgid "new_table" +msgstr "новая_таблица" + +#: sql_help.c:4399 +msgid "timezone" +msgstr "часовой_пояс" + +#: sql_help.c:4444 +msgid "snapshot_id" +msgstr "код_снимка" + +#: sql_help.c:4686 +msgid "sort_expression" +msgstr "выражение_сортировки" + +#: sql_help.c:4813 sql_help.c:5791 +msgid "abort the current transaction" +msgstr "прервать текущую транзакцию" + +#: sql_help.c:4819 +msgid "change the definition of an aggregate function" +msgstr "изменить определение агрегатной функции" + +#: sql_help.c:4825 +msgid "change the definition of a collation" +msgstr "изменить определение правила сортировки" + +#: sql_help.c:4831 +msgid "change the definition of a conversion" +msgstr "изменить определение преобразования" + +#: sql_help.c:4837 +msgid "change a database" +msgstr "изменить атрибуты базы данных" + +#: sql_help.c:4843 +msgid "define default access privileges" +msgstr "определить права доступа по умолчанию" + +#: sql_help.c:4849 +msgid "change the definition of a domain" +msgstr "изменить определение домена" + +#: sql_help.c:4855 +msgid "change the definition of an event trigger" +msgstr "изменить определение событийного триггера" + +#: sql_help.c:4861 +msgid "change the definition of an extension" +msgstr "изменить определение расширения" + +#: sql_help.c:4867 +msgid "change the definition of a foreign-data wrapper" +msgstr "изменить определение обёртки сторонних данных" + +#: sql_help.c:4873 +msgid "change the definition of a foreign table" +msgstr "изменить определение сторонней таблицы" + +#: sql_help.c:4879 +msgid "change the definition of a function" +msgstr "изменить определение функции" + +#: sql_help.c:4885 +msgid "change role name or membership" +msgstr "изменить имя роли или членство" + +#: sql_help.c:4891 +msgid "change the definition of an index" +msgstr "изменить определение индекса" + +#: sql_help.c:4897 +msgid "change the definition of a procedural language" +msgstr "изменить определение процедурного языка" + +#: sql_help.c:4903 +msgid "change the definition of a large object" +msgstr "изменить определение большого объекта" + +#: sql_help.c:4909 +msgid "change the definition of a materialized view" +msgstr "изменить определение материализованного представления" + +#: sql_help.c:4915 +msgid "change the definition of an operator" +msgstr "изменить определение оператора" + +#: sql_help.c:4921 +msgid "change the definition of an operator class" +msgstr "изменить определение класса операторов" + +#: sql_help.c:4927 +msgid "change the definition of an operator family" +msgstr "изменить определение семейства операторов" + +#: sql_help.c:4933 +msgid "change the definition of a row level security policy" +msgstr "изменить определение политики безопасности на уровне строк" + +#: sql_help.c:4939 +msgid "change the definition of a procedure" +msgstr "изменить определение процедуры" + +#: sql_help.c:4945 +msgid "change the definition of a publication" +msgstr "изменить определение публикации" + +#: sql_help.c:4951 sql_help.c:5053 +msgid "change a database role" +msgstr "изменить роль пользователя БД" + +#: sql_help.c:4957 +msgid "change the definition of a routine" +msgstr "изменить определение подпрограммы" + +#: sql_help.c:4963 +msgid "change the definition of a rule" +msgstr "изменить определение правила" + +#: sql_help.c:4969 +msgid "change the definition of a schema" +msgstr "изменить определение схемы" + +#: sql_help.c:4975 +msgid "change the definition of a sequence generator" +msgstr "изменить определение генератора последовательности" + +#: sql_help.c:4981 +msgid "change the definition of a foreign server" +msgstr "изменить определение стороннего сервера" + +#: sql_help.c:4987 +msgid "change the definition of an extended statistics object" +msgstr "изменить определение объекта расширенной статистики" + +#: sql_help.c:4993 +msgid "change the definition of a subscription" +msgstr "изменить определение подписки" + +#: sql_help.c:4999 +msgid "change a server configuration parameter" +msgstr "изменить параметр конфигурации сервера" + +#: sql_help.c:5005 +msgid "change the definition of a table" +msgstr "изменить определение таблицы" + +#: sql_help.c:5011 +msgid "change the definition of a tablespace" +msgstr "изменить определение табличного пространства" + +#: sql_help.c:5017 +msgid "change the definition of a text search configuration" +msgstr "изменить определение конфигурации текстового поиска" + +#: sql_help.c:5023 +msgid "change the definition of a text search dictionary" +msgstr "изменить определение словаря текстового поиска" + +#: sql_help.c:5029 +msgid "change the definition of a text search parser" +msgstr "изменить определение анализатора текстового поиска" + +#: sql_help.c:5035 +msgid "change the definition of a text search template" +msgstr "изменить определение шаблона текстового поиска" + +#: sql_help.c:5041 +msgid "change the definition of a trigger" +msgstr "изменить определение триггера" + +#: sql_help.c:5047 +msgid "change the definition of a type" +msgstr "изменить определение типа" + +#: sql_help.c:5059 +msgid "change the definition of a user mapping" +msgstr "изменить сопоставление пользователей" + +#: sql_help.c:5065 +msgid "change the definition of a view" +msgstr "изменить определение представления" + +#: sql_help.c:5071 +msgid "collect statistics about a database" +msgstr "собрать статистику о базе данных" + +#: sql_help.c:5077 sql_help.c:5869 +msgid "start a transaction block" +msgstr "начать транзакцию" + +#: sql_help.c:5083 +msgid "invoke a procedure" +msgstr "вызвать процедуру" + +#: sql_help.c:5089 +msgid "force a write-ahead log checkpoint" +msgstr "произвести контрольную точку в журнале предзаписи" + +#: sql_help.c:5095 +msgid "close a cursor" +msgstr "закрыть курсор" + +#: sql_help.c:5101 +msgid "cluster a table according to an index" +msgstr "перегруппировать таблицу по индексу" + +#: sql_help.c:5107 +msgid "define or change the comment of an object" +msgstr "задать или изменить комментарий объекта" + +#: sql_help.c:5113 sql_help.c:5671 +msgid "commit the current transaction" +msgstr "зафиксировать текущую транзакцию" + +#: sql_help.c:5119 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "зафиксировать транзакцию, ранее подготовленную для двухфазной фиксации" + +#: sql_help.c:5125 +msgid "copy data between a file and a table" +msgstr "импорт/экспорт данных в файл" + +#: sql_help.c:5131 +msgid "define a new access method" +msgstr "создать новый метод доступа" + +#: sql_help.c:5137 +msgid "define a new aggregate function" +msgstr "создать агрегатную функцию" + +#: sql_help.c:5143 +msgid "define a new cast" +msgstr "создать приведение типов" + +#: sql_help.c:5149 +msgid "define a new collation" +msgstr "создать правило сортировки" + +#: sql_help.c:5155 +msgid "define a new encoding conversion" +msgstr "создать преобразование кодировки" + +#: sql_help.c:5161 +msgid "create a new database" +msgstr "создать базу данных" + +#: sql_help.c:5167 +msgid "define a new domain" +msgstr "создать домен" + +#: sql_help.c:5173 +msgid "define a new event trigger" +msgstr "создать событийный триггер" + +#: sql_help.c:5179 +msgid "install an extension" +msgstr "установить расширение" + +#: sql_help.c:5185 +msgid "define a new foreign-data wrapper" +msgstr "создать обёртку сторонних данных" + +#: sql_help.c:5191 +msgid "define a new foreign table" +msgstr "создать стороннюю таблицу" + +#: sql_help.c:5197 +msgid "define a new function" +msgstr "создать функцию" + +#: sql_help.c:5203 sql_help.c:5263 sql_help.c:5365 +msgid "define a new database role" +msgstr "создать роль пользователя БД" + +#: sql_help.c:5209 +msgid "define a new index" +msgstr "создать индекс" + +#: sql_help.c:5215 +msgid "define a new procedural language" +msgstr "создать процедурный язык" + +#: sql_help.c:5221 +msgid "define a new materialized view" +msgstr "создать материализованное представление" + +#: sql_help.c:5227 +msgid "define a new operator" +msgstr "создать оператор" + +#: sql_help.c:5233 +msgid "define a new operator class" +msgstr "создать класс операторов" + +#: sql_help.c:5239 +msgid "define a new operator family" +msgstr "создать семейство операторов" + +#: sql_help.c:5245 +msgid "define a new row level security policy for a table" +msgstr "создать новую политику безопасности на уровне строк для таблицы" + +#: sql_help.c:5251 +msgid "define a new procedure" +msgstr "создать процедуру" + +#: sql_help.c:5257 +msgid "define a new publication" +msgstr "создать публикацию" + +#: sql_help.c:5269 +msgid "define a new rewrite rule" +msgstr "создать правило перезаписи" + +#: sql_help.c:5275 +msgid "define a new schema" +msgstr "создать схему" + +#: sql_help.c:5281 +msgid "define a new sequence generator" +msgstr "создать генератор последовательностей" + +#: sql_help.c:5287 +msgid "define a new foreign server" +msgstr "создать сторонний сервер" + +#: sql_help.c:5293 +msgid "define extended statistics" +msgstr "создать расширенную статистику" + +#: sql_help.c:5299 +msgid "define a new subscription" +msgstr "создать подписку" + +#: sql_help.c:5305 +msgid "define a new table" +msgstr "создать таблицу" + +#: sql_help.c:5311 sql_help.c:5827 +msgid "define a new table from the results of a query" +msgstr "создать таблицу из результатов запроса" + +#: sql_help.c:5317 +msgid "define a new tablespace" +msgstr "создать табличное пространство" + +#: sql_help.c:5323 +msgid "define a new text search configuration" +msgstr "создать конфигурацию текстового поиска" + +#: sql_help.c:5329 +msgid "define a new text search dictionary" +msgstr "создать словарь текстового поиска" + +#: sql_help.c:5335 +msgid "define a new text search parser" +msgstr "создать анализатор текстового поиска" + +#: sql_help.c:5341 +msgid "define a new text search template" +msgstr "создать шаблон текстового поиска" + +#: sql_help.c:5347 +msgid "define a new transform" +msgstr "создать преобразование" + +#: sql_help.c:5353 +msgid "define a new trigger" +msgstr "создать триггер" + +#: sql_help.c:5359 +msgid "define a new data type" +msgstr "создать тип данных" + +#: sql_help.c:5371 +msgid "define a new mapping of a user to a foreign server" +msgstr "создать сопоставление пользователя для стороннего сервера" + +#: sql_help.c:5377 +msgid "define a new view" +msgstr "создать представление" + +#: sql_help.c:5383 +msgid "deallocate a prepared statement" +msgstr "освободить подготовленный оператор" + +#: sql_help.c:5389 +msgid "define a cursor" +msgstr "создать курсор" + +#: sql_help.c:5395 +msgid "delete rows of a table" +msgstr "удалить записи таблицы" + +#: sql_help.c:5401 +msgid "discard session state" +msgstr "очистить состояние сеанса" + +#: sql_help.c:5407 +msgid "execute an anonymous code block" +msgstr "выполнить анонимный блок кода" + +#: sql_help.c:5413 +msgid "remove an access method" +msgstr "удалить метод доступа" + +#: sql_help.c:5419 +msgid "remove an aggregate function" +msgstr "удалить агрегатную функцию" + +#: sql_help.c:5425 +msgid "remove a cast" +msgstr "удалить приведение типа" + +#: sql_help.c:5431 +msgid "remove a collation" +msgstr "удалить правило сортировки" + +#: sql_help.c:5437 +msgid "remove a conversion" +msgstr "удалить преобразование" + +#: sql_help.c:5443 +msgid "remove a database" +msgstr "удалить базу данных" + +#: sql_help.c:5449 +msgid "remove a domain" +msgstr "удалить домен" + +#: sql_help.c:5455 +msgid "remove an event trigger" +msgstr "удалить событийный триггер" + +#: sql_help.c:5461 +msgid "remove an extension" +msgstr "удалить расширение" + +#: sql_help.c:5467 +msgid "remove a foreign-data wrapper" +msgstr "удалить обёртку сторонних данных" + +#: sql_help.c:5473 +msgid "remove a foreign table" +msgstr "удалить стороннюю таблицу" + +#: sql_help.c:5479 +msgid "remove a function" +msgstr "удалить функцию" + +#: sql_help.c:5485 sql_help.c:5551 sql_help.c:5653 +msgid "remove a database role" +msgstr "удалить роль пользователя БД" + +#: sql_help.c:5491 +msgid "remove an index" +msgstr "удалить индекс" + +#: sql_help.c:5497 +msgid "remove a procedural language" +msgstr "удалить процедурный язык" + +#: sql_help.c:5503 +msgid "remove a materialized view" +msgstr "удалить материализованное представление" + +#: sql_help.c:5509 +msgid "remove an operator" +msgstr "удалить оператор" + +#: sql_help.c:5515 +msgid "remove an operator class" +msgstr "удалить класс операторов" + +#: sql_help.c:5521 +msgid "remove an operator family" +msgstr "удалить семейство операторов" + +#: sql_help.c:5527 +msgid "remove database objects owned by a database role" +msgstr "удалить объекты базы данных, принадлежащие роли" + +#: sql_help.c:5533 +msgid "remove a row level security policy from a table" +msgstr "удалить политику безопасности на уровне строк из таблицы" + +#: sql_help.c:5539 +msgid "remove a procedure" +msgstr "удалить процедуру" + +#: sql_help.c:5545 +msgid "remove a publication" +msgstr "удалить публикацию" + +#: sql_help.c:5557 +msgid "remove a routine" +msgstr "удалить подпрограмму" + +#: sql_help.c:5563 +msgid "remove a rewrite rule" +msgstr "удалить правило перезаписи" + +#: sql_help.c:5569 +msgid "remove a schema" +msgstr "удалить схему" + +#: sql_help.c:5575 +msgid "remove a sequence" +msgstr "удалить последовательность" + +#: sql_help.c:5581 +msgid "remove a foreign server descriptor" +msgstr "удалить описание стороннего сервера" + +#: sql_help.c:5587 +msgid "remove extended statistics" +msgstr "удалить расширенную статистику" + +#: sql_help.c:5593 +msgid "remove a subscription" +msgstr "удалить подписку" + +#: sql_help.c:5599 +msgid "remove a table" +msgstr "удалить таблицу" + +#: sql_help.c:5605 +msgid "remove a tablespace" +msgstr "удалить табличное пространство" + +#: sql_help.c:5611 +msgid "remove a text search configuration" +msgstr "удалить конфигурацию текстового поиска" + +#: sql_help.c:5617 +msgid "remove a text search dictionary" +msgstr "удалить словарь текстового поиска" + +#: sql_help.c:5623 +msgid "remove a text search parser" +msgstr "удалить анализатор текстового поиска" + +#: sql_help.c:5629 +msgid "remove a text search template" +msgstr "удалить шаблон текстового поиска" + +#: sql_help.c:5635 +msgid "remove a transform" +msgstr "удалить преобразование" + +#: sql_help.c:5641 +msgid "remove a trigger" +msgstr "удалить триггер" + +#: sql_help.c:5647 +msgid "remove a data type" +msgstr "удалить тип данных" + +#: sql_help.c:5659 +msgid "remove a user mapping for a foreign server" +msgstr "удалить сопоставление пользователя для стороннего сервера" + +#: sql_help.c:5665 +msgid "remove a view" +msgstr "удалить представление" + +#: sql_help.c:5677 +msgid "execute a prepared statement" +msgstr "выполнить подготовленный оператор" + +#: sql_help.c:5683 +msgid "show the execution plan of a statement" +msgstr "показать план выполнения оператора" + +#: sql_help.c:5689 +msgid "retrieve rows from a query using a cursor" +msgstr "получить результат запроса через курсор" + +#: sql_help.c:5695 +msgid "define access privileges" +msgstr "определить права доступа" + +#: sql_help.c:5701 +msgid "import table definitions from a foreign server" +msgstr "импортировать определения таблиц со стороннего сервера" + +#: sql_help.c:5707 +msgid "create new rows in a table" +msgstr "добавить строки в таблицу" + +#: sql_help.c:5713 +msgid "listen for a notification" +msgstr "ожидать уведомления" + +#: sql_help.c:5719 +msgid "load a shared library file" +msgstr "загрузить файл разделяемой библиотеки" + +#: sql_help.c:5725 +msgid "lock a table" +msgstr "заблокировать таблицу" + +#: sql_help.c:5731 +msgid "position a cursor" +msgstr "установить курсор" + +#: sql_help.c:5737 +msgid "generate a notification" +msgstr "сгенерировать уведомление" + +#: sql_help.c:5743 +msgid "prepare a statement for execution" +msgstr "подготовить оператор для выполнения" + +#: sql_help.c:5749 +msgid "prepare the current transaction for two-phase commit" +msgstr "подготовить текущую транзакцию для двухфазной фиксации" + +#: sql_help.c:5755 +msgid "change the ownership of database objects owned by a database role" +msgstr "изменить владельца объектов БД, принадлежащих заданной роли" + +#: sql_help.c:5761 +msgid "replace the contents of a materialized view" +msgstr "заменить содержимое материализованного представления" + +#: sql_help.c:5767 +msgid "rebuild indexes" +msgstr "перестроить индексы" + +#: sql_help.c:5773 +msgid "destroy a previously defined savepoint" +msgstr "удалить ранее определённую точку сохранения" + +#: sql_help.c:5779 +msgid "restore the value of a run-time parameter to the default value" +msgstr "восстановить исходное значение параметра выполнения" + +#: sql_help.c:5785 +msgid "remove access privileges" +msgstr "удалить права доступа" + +#: sql_help.c:5797 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "отменить транзакцию, подготовленную ранее для двухфазной фиксации" + +#: sql_help.c:5803 +msgid "roll back to a savepoint" +msgstr "откатиться к точке сохранения" + +#: sql_help.c:5809 +msgid "define a new savepoint within the current transaction" +msgstr "определить новую точку сохранения в текущей транзакции" + +#: sql_help.c:5815 +msgid "define or change a security label applied to an object" +msgstr "задать или изменить метку безопасности, применённую к объекту" + +#: sql_help.c:5821 sql_help.c:5875 sql_help.c:5911 +msgid "retrieve rows from a table or view" +msgstr "выбрать строки из таблицы или представления" + +#: sql_help.c:5833 +msgid "change a run-time parameter" +msgstr "изменить параметр выполнения" + +#: sql_help.c:5839 +msgid "set constraint check timing for the current transaction" +msgstr "установить время проверки ограничений для текущей транзакции" + +#: sql_help.c:5845 +msgid "set the current user identifier of the current session" +msgstr "задать идентификатор текущего пользователя в текущем сеансе" + +#: sql_help.c:5851 +msgid "" +"set the session user identifier and the current user identifier of the " +"current session" +msgstr "" +"задать идентификатор пользователя сеанса и идентификатор текущего " +"пользователя в текущем сеансе" + +#: sql_help.c:5857 +msgid "set the characteristics of the current transaction" +msgstr "задать свойства текущей транзакции" + +#: sql_help.c:5863 +msgid "show the value of a run-time parameter" +msgstr "показать значение параметра выполнения" + +#: sql_help.c:5881 +msgid "empty a table or set of tables" +msgstr "опустошить таблицу или набор таблиц" + +#: sql_help.c:5887 +msgid "stop listening for a notification" +msgstr "прекратить ожидание уведомлений" + +#: sql_help.c:5893 +msgid "update rows of a table" +msgstr "изменить строки таблицы" + +#: sql_help.c:5899 +msgid "garbage-collect and optionally analyze a database" +msgstr "произвести сборку мусора и проанализировать базу данных" + +#: sql_help.c:5905 +msgid "compute a set of rows" +msgstr "получить набор строк" + +#: startup.c:212 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 можно использовать только в неинтерактивном режиме" + +#: startup.c:327 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "не удалось открыть файл протокола \"%s\": %m" + +#: startup.c:439 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Введите \"help\", чтобы получить справку.\n" +"\n" + +#: startup.c:589 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "не удалось установить параметр печати \"%s\"" + +#: startup.c:697 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Для дополнительной информации попробуйте \"%s --help\".\n" + +#: startup.c:714 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "лишний аргумент \"%s\" проигнорирован" + +#: startup.c:763 +#, c-format +msgid "could not find own program executable" +msgstr "не удалось найти собственный исполняемый файл" + +#: tab-complete.c:4640 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"ошибка запроса Tab-дополнения: %s\n" +"Запрос:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "" +"нераспознанное значение \"%s\" для \"%s\": ожидалось булевское значение" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "неправильное значение \"%s\" для \"%s\": ожидалось целое" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "неправильное имя переменной: \"%s\"" + +#: variables.c:419 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"нераспознанное значение \"%s\" для \"%s\"\n" +"Допустимые значения: %s." + +#~ msgid "Could not send cancel request: %s" +#~ msgstr "Отправить сигнал отмены не удалось: %s" + +#~ msgid "could not connect to server: %s" +#~ msgstr "не удалось подключиться к серверу: %s" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Об ошибках сообщайте по адресу .\n" + +#~ msgid "" +#~ " \\g [FILE] or ; execute query (and send results to file or |" +#~ "pipe)\n" +#~ msgstr "" +#~ " \\g [ФАЙЛ] или ; выполнить запрос\n" +#~ " (и направить результаты в файл или канал |)\n" + +#~ msgid "old_version" +#~ msgstr "старая_версия" + +#~ msgid "using_list" +#~ msgstr "список_USING" + +#~ msgid "from_list" +#~ msgstr "список_FROM" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "дочерний процесс завершён по сигналу %s" + +#~ msgid "Invalid command \\%s. Try \\? for help.\n" +#~ msgstr "Неверная команда \\%s. Справка по командам: \\?\n" + +#~ msgid "%s\n" +#~ msgstr "%s\n" + +#~ msgid "string_literal" +#~ msgstr "строковая_константа" + +#~ msgid "normal" +#~ msgstr "обычная" + +#~ msgid "Procedure" +#~ msgstr "Процедура" + +#~ msgid " SERVER_VERSION_NAME server's version (short string)\n" +#~ msgstr " SERVER_VERSION_NAME версия сервера (короткая строка)\n" + +#~ msgid " VERSION psql's version (verbose string)\n" +#~ msgstr " VERSION версия psql (развёрнутая строка)\n" + +#~ msgid " VERSION_NAME psql's version (short string)\n" +#~ msgstr " VERSION_NAME версия psql (короткая строка)\n" + +#~ msgid " VERSION_NUM psql's version (numeric format)\n" +#~ msgstr " VERSION_NUM версия psql (в числовом формате)\n" + +#~ msgid "attribute" +#~ msgstr "атрибут" + +#~ msgid "Value" +#~ msgstr "Значение" + +#~ msgid "statistic_type" +#~ msgstr "тип_статистики" + +#~ msgid "No per-database role settings support in this server version.\n" +#~ msgstr "" +#~ "Это версия сервера не поддерживает параметры ролей на уровне базы " +#~ "данных.\n" + +#~ msgid "No matching settings found.\n" +#~ msgstr "Соответствующие параметры не найдены.\n" + +#~ msgid "No settings found.\n" +#~ msgstr "Параметры не найдены.\n" + +#~ msgid "No matching relations found.\n" +#~ msgstr "Соответствующие отношения не найдены.\n" + +#~ msgid "No relations found.\n" +#~ msgstr "Отношения не найдены.\n" + +#~ msgid "Object Description" +#~ msgstr "Описание объекта" + +#~ msgid "Password encryption failed.\n" +#~ msgstr "Ошибка при шифровании пароля.\n" + +#~ msgid "suboption" +#~ msgstr "подпараметр" + +#~ msgid "where suboption can be:" +#~ msgstr "где допустимые подпараметры:" + +#~ msgid "slot_name" +#~ msgstr "имя_слота" + +#~ msgid "puboption" +#~ msgstr "параметр_публикации" + +#~ msgid "where puboption can be:" +#~ msgstr "где допустимый параметр_публикации:" + +#~ msgid "+ opt(%d) = |%s|\n" +#~ msgstr "+ opt(%d) = |%s|\n" + +#~ msgid "\\%s: error while setting variable\n" +#~ msgstr "\\%s: не удалось установить переменную\n" + +#~ msgid "could not set variable \"%s\"\n" +#~ msgstr "не удалось установить переменную \"%s\"\n" + +#~ msgid "Modifiers" +#~ msgstr "Модификаторы" + +#~ msgid "collate %s" +#~ msgstr "правило сортировки %s" + +#~ msgid "not null" +#~ msgstr "NOT NULL" + +#~ msgid "default %s" +#~ msgstr "DEFAULT %s" + +#~ msgid "Modifier" +#~ msgstr "Модификатор" + +#~ msgid "%s: could not set variable \"%s\"\n" +#~ msgstr "%s: не удалось установить переменную \"%s\"\n" + +#~ msgid "\\crosstabview: query must return results to be shown in crosstab\n" +#~ msgstr "" +#~ "\\crosstabview: запрос должен возвращать результаты для вывода в " +#~ "перекрёстном виде\n" + +#~ msgid "\\crosstabview: invalid column number: \"%s\"\n" +#~ msgstr "\\crosstabview: неверный номер столбца: \"%s\"\n" + +#~ msgid "serialtype" +#~ msgstr "сериализованный_тип" + +#~ msgid "Watch every %lds\t%s" +#~ msgstr "Повтор запрос через %ld сек.\t%s" + +#~ msgid "" +#~ "\n" +#~ "Display influencing variables:\n" +#~ msgstr "" +#~ "\n" +#~ "Рабочие параметры:\n" + +#~ msgid " unicode_border_linestyle\n" +#~ msgstr " unicode_border_linestyle\n" + +#~ msgid " unicode_column_linestyle\n" +#~ msgstr " unicode_column_linestyle\n" + +#~ msgid "column_name_index" +#~ msgstr "индекс_по_имени_столбца" + +#~ msgid "expression_index" +#~ msgstr "индекс_по_выражению" + +#~ msgid "SSL connection (unknown cipher)\n" +#~ msgstr "SSL-соединение (шифр неизвестен)\n" + +#~ msgid "(No rows)\n" +#~ msgstr "(Нет записей)\n" + +#~ msgid "where view_option_name can be one of:" +#~ msgstr "где допустимое имя_параметра_представления:" + +#~ msgid "local" +#~ msgstr "local" + +#~ msgid "cascaded" +#~ msgstr "cascaded" + +#~ msgid "Border style (%s) unset.\n" +#~ msgstr "Стиль границ (%s) сброшен.\n" + +#~ msgid "Output format (%s) is aligned.\n" +#~ msgstr "Формат вывода (%s): выровненный.\n" + +#~ msgid "invfunc" +#~ msgstr "обр_функция" + +#~ msgid "" +#~ "change the definition of a tablespace or affect objects of a tablespace" +#~ msgstr "изменить определение или содержимое табличного пространства" + +#~ msgid "Showing locale-adjusted numeric output." +#~ msgstr "Числа выводятся в локализованном формате." + +#~ msgid "Showing only tuples." +#~ msgstr "Выводятся только кортежи." + +#~ msgid "could not get current user name: %s\n" +#~ msgstr "не удалось узнать имя текущего пользователя: %s\n" + +#~ msgid "agg_name" +#~ msgstr "агр_функция" + +#~ msgid "agg_type" +#~ msgstr "агр_тип" + +#~ msgid "input_data_type" +#~ msgstr "тип_входных_данных" + +#~ msgid "%s: -1 is incompatible with -c and -l\n" +#~ msgstr "%s: -1 несовместимо с -c и -l\n" + +#~ msgid " \\l[+] list all databases\n" +#~ msgstr " \\l[+] список всех баз данных\n" + +#~ msgid "column" +#~ msgstr "столбец" + +#~ msgid "new_column" +#~ msgstr "новая_столбец" + +#~ msgid "tablespace" +#~ msgstr "табл_пространство" + +#~ msgid "\\%s: error\n" +#~ msgstr "ошибка \\%s\n" + +#~ msgid "\\copy: %s" +#~ msgstr "\\copy: %s" + +#~ msgid "contains support for command-line editing" +#~ msgstr "включает поддержку редактирования командной строки" + +#~ msgid "data type" +#~ msgstr "тип данных" diff --git a/src/bin/psql/po/sv.po b/src/bin/psql/po/sv.po new file mode 100644 index 000000000000..3d783d72fd4b --- /dev/null +++ b/src/bin/psql/po/sv.po @@ -0,0 +1,6402 @@ +# Swedish message translation file for psql +# Peter Eisentraut , 2001, 2009, 2010. +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019, 2020. +# +# Use these quotes: "%s" +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 13\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2020-08-27 21:44+0000\n" +"PO-Revision-Date: 2020-08-30 10:09+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/common/logging.c:236 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../../../src/common/logging.c:243 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/common/logging.c:250 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 +#, c-format +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" + +#: ../../common/exec.c:156 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ogiltig binär \"%s\"" + +#: ../../common/exec.c:206 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "kunde inte läsa binär \"%s\"" + +#: ../../common/exec.c:214 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "kunde inte hitta en \"%s\" att köra" + +#: ../../common/exec.c:270 ../../common/exec.c:309 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" + +#: ../../common/exec.c:287 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" + +#: ../../common/exec.c:410 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: command.c:1255 input.c:227 mainloop.c:81 mainloop.c:402 +#, c-format +msgid "out of memory" +msgstr "slut på minne" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 +#, c-format +msgid "out of memory\n" +msgstr "slut på minne\n" + +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kan inte duplicera null-pekare (internt fel)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "kunde inte slå upp effektivt användar-id %ld: %s" + +#: ../../common/username.c:45 command.c:559 +msgid "user does not exist" +msgstr "användaren finns inte" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "misslyckad sökning efter användarnamn: felkod %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "kommandot är inte körbart" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "kommandot kan ej hittas" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "barnprocess avslutade med kod %d" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "barnprocess terminerades med avbrott 0x%X" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "barnprocess avslutade med okänd statuskod %d" + +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Förfrågan om avbrytning skickad\n" + +#: ../../fe_utils/cancel.c:165 +msgid "Could not send cancel request: " +msgstr "Kunde inte skicka förfrågan om avbrytning: " + +#: ../../fe_utils/cancel.c:210 +#, c-format +msgid "Could not send cancel request: %s" +msgstr "Kunde inte skicka förfrågan om avbrytning: %s" + +#: ../../fe_utils/print.c:350 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu rad)" +msgstr[1] "(%lu rader)" + +#: ../../fe_utils/print.c:3055 +#, c-format +msgid "Interrupted\n" +msgstr "Avbruten\n" + +#: ../../fe_utils/print.c:3119 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "Kan inte lägga till rubrik till tabellinnehåll: antal kolumner (%d) överskridet.\n" + +#: ../../fe_utils/print.c:3159 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "Kan inte lägga till cell till tabellinnehåll: totala cellantalet (%d) överskridet.\n" + +#: ../../fe_utils/print.c:3414 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "ogiltigt utdataformat (internt fel): %d" + +#: ../../fe_utils/psqlscan.l:694 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "hoppar över rekursiv expandering av variabeln \"%s\"" + +#: command.c:224 +#, c-format +msgid "invalid command \\%s" +msgstr "ogiltigt kommando \\%s" + +#: command.c:226 +#, c-format +msgid "Try \\? for help." +msgstr "Försök med \\? för hjälp." + +#: command.c:244 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: extra argument \"%s\" ignorerat" + +#: command.c:296 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "kommandot \\%s ignorerat; använd \\endif eller Ctrl-C för att avsluta nuvarande \\if-block" + +#: command.c:557 +#, c-format +msgid "could not get home directory for user ID %ld: %s" +msgstr "kunde inte hämta hemkatalog för användar-ID %ld: %s" + +#: command.c:575 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: kunde inte byta katalog till \"%s\": %m" + +#: command.c:600 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "Du är för närvarande inte uppkopplad mot en databas.\n" + +#: command.c:613 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Du är uppkopplad upp mot databas \"%s\" som användare \"%s\" på adress \"%s\" på port \"%s\".\n" + +#: command.c:616 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Du är uppkopplad mot databas \"%s\" som användare \"%s\" via uttag i \"%s\" på port \"%s\".\n" + +#: command.c:622 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Du är uppkopplad upp mot databas \"%s\" som användare \"%s\" på värd \"%s\" (adress \"%s\") på port \"%s\".\n" + +#: command.c:625 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Du är uppkopplad upp mot databas \"%s\" som användare \"%s\" på värd \"%s\" på port \"%s\".\n" + +#: command.c:965 command.c:1061 command.c:2550 +#, c-format +msgid "no query buffer" +msgstr "ingen frågebuffert" + +#: command.c:998 command.c:5061 +#, c-format +msgid "invalid line number: %s" +msgstr "ogiltigt radnummer: %s" + +#: command.c:1052 +#, c-format +msgid "The server (version %s) does not support editing function source." +msgstr "Servern (version %s) stöder inte redigering av funktionskällkod." + +#: command.c:1055 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "Servern (version %s) stöder inte redigering av vydefinitioner." + +#: command.c:1137 +msgid "No changes" +msgstr "Inga ändringar" + +#: command.c:1216 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: ogiltigt kodningsnamn eller konverteringsprocedur hittades inte" + +#: command.c:1251 command.c:1992 command.c:3253 command.c:5163 common.c:174 +#: common.c:223 common.c:388 common.c:1237 common.c:1265 common.c:1373 +#: common.c:1480 common.c:1518 copy.c:488 copy.c:707 help.c:62 large_obj.c:157 +#: large_obj.c:192 large_obj.c:254 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1258 +msgid "There is no previous error." +msgstr "Det finns inget tidigare fel." + +#: command.c:1371 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: saknar höger parentes" + +#: command.c:1548 command.c:1853 command.c:1867 command.c:1884 command.c:2044 +#: command.c:2281 command.c:2517 command.c:2557 +#, c-format +msgid "\\%s: missing required argument" +msgstr "\\%s: obligatoriskt argument saknas" + +#: command.c:1679 +#, c-format +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: kan inte komma efter \\else" + +#: command.c:1684 +#, c-format +msgid "\\elif: no matching \\if" +msgstr "\\elif: ingen matchande \\if" + +#: command.c:1748 +#, c-format +msgid "\\else: cannot occur after \\else" +msgstr "\\else: kan inte komma efter \\else" + +#: command.c:1753 +#, c-format +msgid "\\else: no matching \\if" +msgstr "\\else: ingen matchande \\if" + +#: command.c:1793 +#, c-format +msgid "\\endif: no matching \\if" +msgstr "\\endif: ingen matchande \\if" + +#: command.c:1948 +msgid "Query buffer is empty." +msgstr "Frågebufferten är tom." + +#: command.c:1970 +msgid "Enter new password: " +msgstr "Mata in nytt lösenord: " + +#: command.c:1971 +msgid "Enter it again: " +msgstr "Mata in det igen: " + +#: command.c:1975 +#, c-format +msgid "Passwords didn't match." +msgstr "Lösenorden stämde inte överens." + +#: command.c:2074 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "\\%s: kunde inte läsa värde på varibeln" + +#: command.c:2177 +msgid "Query buffer reset (cleared)." +msgstr "Frågebufferten har blivit borttagen." + +#: command.c:2199 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "Skrev historiken till fil \"%s\".\n" + +#: command.c:2286 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: omgivningsvariabelnamn får ej innehålla \"=\"" + +#: command.c:2347 +#, c-format +msgid "The server (version %s) does not support showing function source." +msgstr "Servern (version %s) stöder inte visning av funktionskällkod." + +#: command.c:2350 +#, c-format +msgid "The server (version %s) does not support showing view definitions." +msgstr "Servern (version %s) stöder inte visning av vydefinitioner." + +#: command.c:2357 +#, c-format +msgid "function name is required" +msgstr "funktionsnamn krävs" + +#: command.c:2359 +#, c-format +msgid "view name is required" +msgstr "vynamn krävs" + +#: command.c:2489 +msgid "Timing is on." +msgstr "Tidtagning är på." + +#: command.c:2491 +msgid "Timing is off." +msgstr "Tidtagning är av." + +#: command.c:2576 command.c:2604 command.c:3661 command.c:3664 command.c:3667 +#: command.c:3673 command.c:3675 command.c:3683 command.c:3693 command.c:3702 +#: command.c:3716 command.c:3733 command.c:3791 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, c-format +msgid "%s: %m" +msgstr "%s: %m" + +#: command.c:2988 startup.c:236 startup.c:287 +msgid "Password: " +msgstr "Lösenord: " + +#: command.c:2993 startup.c:284 +#, c-format +msgid "Password for user %s: " +msgstr "Lösenord för användare %s: " + +#: command.c:3064 +#, c-format +msgid "All connection parameters must be supplied because no database connection exists" +msgstr "Alla anslutningsparametrar måste anges då ingen databasuppkoppling är gjord" + +#: command.c:3257 +#, c-format +msgid "Previous connection kept" +msgstr "Föregående förbindelse bevarad" + +#: command.c:3261 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3310 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" på adress \"%s\" på port \"%s\".\n" + +#: command.c:3313 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" via uttag i \"%s\" på port \"%s\".\n" + +#: command.c:3319 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" på värd \"%s\" (adress \"%s\") på port \"%s\".\n" + +#: command.c:3322 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" på värd \"%s\" på port \"%s\".\n" + +#: command.c:3327 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\".\n" + +#: command.c:3360 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, server %s)\n" + +#: command.c:3368 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"VARNING: %s huvudversion %s, server huvudversion %s.\n" +" En del psql-finesser kommer kanske inte fungera.\n" + +#: command.c:3407 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL-förbindelse (protokoll: %s, krypto: %s, bitar: %s, komprimering: %s)\n" + +#: command.c:3408 command.c:3409 command.c:3410 +msgid "unknown" +msgstr "okänd" + +#: command.c:3411 help.c:45 +msgid "off" +msgstr "av" + +#: command.c:3411 help.c:45 +msgid "on" +msgstr "på" + +#: command.c:3425 +#, c-format +msgid "GSSAPI-encrypted connection\n" +msgstr "GSSAPI-krypterad anslutning\n" + +#: command.c:3445 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"VARNING: Konsollens \"code page\" (%u) skiljer sig fån Windows \"code page\" (%u)\n" +" 8-bitars tecken kommer troligen inte fungera korrekt. Se psql:s\n" +" referensmanual i sektionen \"Notes for Windows users\" för mer detaljer.\n" + +#: command.c:3549 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "omgivningsvariabeln PSQL_EDITOR_LINENUMBER_ARG måste ange ett radnummer" + +#: command.c:3578 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "kunde inte starta editorn \"%s\"" + +#: command.c:3580 +#, c-format +msgid "could not start /bin/sh" +msgstr "kunde inte starta /bin/sh" + +#: command.c:3618 +#, c-format +msgid "could not locate temporary directory: %s" +msgstr "kunde inte hitta temp-katalog: %s" + +#: command.c:3645 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "kunde inte öppna temporär fil \"%s\": %m" + +#: command.c:3950 +#, c-format +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: tvetydig förkortning \"%s\" matchar både \"%s\" och \"%s\"" + +#: command.c:3970 +#, c-format +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: tillåtna format är aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" + +#: command.c:3989 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: tillåtna linjestilar är ascii, old-ascii, unicode" + +#: command.c:4004 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: tillåtna Unicode-ramstilar är single, double" + +#: command.c:4019 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: tillåtna Unicode-kolumnlinjestilar ärsingle, double" + +#: command.c:4034 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: tillåtna Unicode-rubriklinjestilar är single, double" + +#: command.c:4077 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep måste vara ett ensamt en-byte-tecken" + +#: command.c:4082 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldset kan inte vara dubbelcitat, nyrad eller vagnretur" + +#: command.c:4219 command.c:4407 +#, c-format +msgid "\\pset: unknown option: %s" +msgstr "\\pset: okänd parameter: %s" + +#: command.c:4239 +#, c-format +msgid "Border style is %d.\n" +msgstr "Ramstil är %d.\n" + +#: command.c:4245 +#, c-format +msgid "Target width is unset.\n" +msgstr "Målvidd är inte satt.\n" + +#: command.c:4247 +#, c-format +msgid "Target width is %d.\n" +msgstr "Målvidd är %d.\n" + +#: command.c:4254 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Utökad visning är på.\n" + +#: command.c:4256 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "Utökad visning används automatiskt.\n" + +#: command.c:4258 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Utökad visning är av.\n" + +#: command.c:4264 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "Fältseparatorn för CSV är \"%s\".\n" + +#: command.c:4272 command.c:4280 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "Fältseparatorn är noll-byte.\n" + +#: command.c:4274 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "Fältseparatorn är \"%s\".\n" + +#: command.c:4287 +#, c-format +msgid "Default footer is on.\n" +msgstr "Standard sidfot är på.\n" + +#: command.c:4289 +#, c-format +msgid "Default footer is off.\n" +msgstr "Standard sidfot är av.\n" + +#: command.c:4295 +#, c-format +msgid "Output format is %s.\n" +msgstr "Utdataformatet är \"%s\".\n" + +#: command.c:4301 +#, c-format +msgid "Line style is %s.\n" +msgstr "Linjestil är %s.\n" + +#: command.c:4308 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Null-visare är \"%s\".\n" + +#: command.c:4316 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "Lokal-anpassad numerisk utdata är på.\n" + +#: command.c:4318 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "Lokal-anpassad numerisk utdata är av.\n" + +#: command.c:4325 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Siduppdelare är på för lång utdata.\n" + +#: command.c:4327 +#, c-format +msgid "Pager is always used.\n" +msgstr "Siduppdelare används alltid.\n" + +#: command.c:4329 +#, c-format +msgid "Pager usage is off.\n" +msgstr "Siduppdelare är av.\n" + +#: command.c:4335 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "Siduppdelare kommer inte användas för färre än %d linje.\n" +msgstr[1] "Siduppdelare kommer inte användas för färre än %d linjer.\n" + +#: command.c:4345 command.c:4355 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "Postseparatorn är noll-byte.\n" + +#: command.c:4347 +#, c-format +msgid "Record separator is .\n" +msgstr "Postseparatorn är .\n" + +#: command.c:4349 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "Postseparatorn är \"%s\".\n" + +#: command.c:4362 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Tabellattributen är \"%s\".\n" + +#: command.c:4365 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Tabellattributen är ej satta.\n" + +#: command.c:4372 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "Titeln är \"%s\".\n" + +#: command.c:4374 +#, c-format +msgid "Title is unset.\n" +msgstr "Titeln är inte satt.\n" + +#: command.c:4381 +#, c-format +msgid "Tuples only is on.\n" +msgstr "Visa bara tupler är på.\n" + +#: command.c:4383 +#, c-format +msgid "Tuples only is off.\n" +msgstr "Visa bara tupler är av.\n" + +#: command.c:4389 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Unicode-ramstil är \"%s\".\n" + +#: command.c:4395 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Unicode-kolumnLinjestil är \"%s\".\n" + +#: command.c:4401 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Unicode-rubriklinjestil är \"%s\".\n" + +#: command.c:4634 +#, c-format +msgid "\\!: failed" +msgstr "\\!: misslyckades" + +#: command.c:4659 common.c:648 +#, c-format +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch kan inte användas på en tom fråga" + +#: command.c:4700 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (varje %gs)\n" + +#: command.c:4703 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (varje %gs)\n" + +#: command.c:4757 command.c:4764 common.c:548 common.c:555 common.c:1220 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********* FRÅGA **********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:4956 +#, c-format +msgid "\"%s.%s\" is not a view" +msgstr "\"%s.%s\" är inte en vy" + +#: command.c:4972 +#, c-format +msgid "could not parse reloptions array" +msgstr "kunde inte parsa arrayen reloptions" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection" +msgstr "kan inte escape:a utan en aktiv uppkoppling" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "shell-kommandots argument innehåller nyrad eller vagnretur: \"%s\"" + +#: common.c:304 +#, c-format +msgid "connection to server was lost" +msgstr "förbindelsen till servern har brutits" + +#: common.c:308 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "Förbindelsen till servern har brutits. Försöker starta om: " + +#: common.c:313 +#, c-format +msgid "Failed.\n" +msgstr "Misslyckades.\n" + +#: common.c:326 +#, c-format +msgid "Succeeded.\n" +msgstr "Lyckades.\n" + +#: common.c:378 common.c:938 common.c:1155 +#, c-format +msgid "unexpected PQresultStatus: %d" +msgstr "oväntad PQresultStatus: %d" + +#: common.c:487 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Tid: %.3f ms\n" + +#: common.c:502 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Tid: %.3f ms (%02d:%06.3f)\n" + +#: common.c:511 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Tid: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:518 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Tid: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:542 common.c:600 common.c:1191 +#, c-format +msgid "You are currently not connected to a database." +msgstr "Du är för närvarande inte uppkopplad mot en databas." + +#: common.c:655 +#, c-format +msgid "\\watch cannot be used with COPY" +msgstr "\\watch kan inte användas med COPY" + +#: common.c:660 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "oväntat resultatstatus för \\watch" + +#: common.c:690 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "Asynkron notificering \"%s\" mottagen med innehåll \"%s\" från serverprocess med PID %d.\n" + +#: common.c:693 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "Asynkron notificering \"%s\" mottagen från serverprocess med PID %d.\n" + +#: common.c:726 common.c:743 +#, c-format +msgid "could not print result table: %m" +msgstr "kunde inte visa resultatabell: %m" + +#: common.c:764 +#, c-format +msgid "no rows returned for \\gset" +msgstr "inga rader returnerades för \\gset" + +#: common.c:769 +#, c-format +msgid "more than one row returned for \\gset" +msgstr "mer än en rad returnerades för \\gset" + +#: common.c:1200 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(Stegningsläge: Verifiera kommando)*******************************************\n" +"%s\n" +"***(tryck return för att fortsätta eller skriv x och return för att avbryta)*****\n" + +#: common.c:1255 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "Servern (version %s) stöder inte sparpunkter för ON_ERROR_ROLLBACK." + +#: common.c:1318 +#, c-format +msgid "STATEMENT: %s" +msgstr "SATS: %s" + +#: common.c:1361 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "oväntad transaktionsstatus (%d)" + +#: common.c:1502 describe.c:2001 +msgid "Column" +msgstr "Kolumn" + +#: common.c:1503 describe.c:177 describe.c:393 describe.c:411 describe.c:456 +#: describe.c:473 describe.c:962 describe.c:1126 describe.c:1711 +#: describe.c:1735 describe.c:2002 describe.c:3719 describe.c:3929 +#: describe.c:4162 describe.c:5368 +msgid "Type" +msgstr "Typ" + +#: common.c:1552 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Kommandot hade inget resultat eller så hade resultatet inga kolumner.\n" + +#: copy.c:98 +#, c-format +msgid "\\copy: arguments required" +msgstr "\\copy: argument krävs" + +#: copy.c:253 +#, c-format +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: parsfel vid \"%s\"" + +#: copy.c:255 +#, c-format +msgid "\\copy: parse error at end of line" +msgstr "\\copy: parsfel vid radslutet" + +#: copy.c:328 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "kunde inte köra kommandot \"%s\": %m" + +#: copy.c:344 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() på fil \"%s\": %m" + +#: copy.c:348 +#, c-format +msgid "%s: cannot copy from/to a directory" +msgstr "%s: kan inte kopiera från/till en katalog" + +#: copy.c:385 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "kunde inte stänga rör till externt komamndo: %m" + +#: copy.c:390 +#, c-format +msgid "%s: %s" +msgstr "%s: %s" + +#: copy.c:453 copy.c:463 +#, c-format +msgid "could not write COPY data: %m" +msgstr "kunde inte skriva COPY-data: %m" + +#: copy.c:469 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "COPY-överföring av data misslyckades: %s" + +#: copy.c:530 +msgid "canceled by user" +msgstr "avbruten av användaren" + +#: copy.c:541 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Mata in data som skall kopieras följt av en nyrad.\n" +"Avsluta med bakstreck och en punkt ensamma på en rad eller av en EOF." + +#: copy.c:669 +msgid "aborted because of read failure" +msgstr "avbruten på grund av läsfel" + +#: copy.c:703 +msgid "trying to exit copy mode" +msgstr "försöker avsluta kopieringsläge" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: satsen returnerade ingen resultatmängd" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: frågan måste returnera minst tre kolumner" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: vertikala och horisontala rubriker måste vara olika kolumner" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: datakolumn måste anges när frågan returnerar mer än tre kolumner" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: maximalt antal kolumner (%d) överskridet" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: frågeresultatet innehåller multipla värden för rad \"%s\", kolumn \"%s\"" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: kolumnnummer %d är utanför giltigt intervall 1..%d" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: tvetydigt kolumnnamn: \"%s\"" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: hittar ej kolumnnamn: \"%s\"" + +#: describe.c:75 describe.c:373 describe.c:678 describe.c:810 describe.c:954 +#: describe.c:1115 describe.c:1187 describe.c:3708 describe.c:3916 +#: describe.c:4160 describe.c:4251 describe.c:4518 describe.c:4678 +#: describe.c:4919 describe.c:4994 describe.c:5005 describe.c:5067 +#: describe.c:5492 describe.c:5575 +msgid "Schema" +msgstr "Schema" + +#: describe.c:76 describe.c:174 describe.c:242 describe.c:250 describe.c:374 +#: describe.c:679 describe.c:811 describe.c:872 describe.c:955 describe.c:1188 +#: describe.c:3709 describe.c:3917 describe.c:4083 describe.c:4161 +#: describe.c:4252 describe.c:4331 describe.c:4519 describe.c:4603 +#: describe.c:4679 describe.c:4920 describe.c:4995 describe.c:5006 +#: describe.c:5068 describe.c:5265 describe.c:5349 describe.c:5573 +#: describe.c:5745 describe.c:5985 +msgid "Name" +msgstr "Namn" + +#: describe.c:77 describe.c:386 describe.c:404 describe.c:450 describe.c:467 +msgid "Result data type" +msgstr "Resultatdatatyp" + +#: describe.c:85 describe.c:98 describe.c:102 describe.c:387 describe.c:405 +#: describe.c:451 describe.c:468 +msgid "Argument data types" +msgstr "Argumentdatatyp" + +#: describe.c:110 describe.c:117 describe.c:185 describe.c:273 describe.c:513 +#: describe.c:727 describe.c:826 describe.c:897 describe.c:1190 describe.c:2020 +#: describe.c:3496 describe.c:3769 describe.c:3963 describe.c:4114 +#: describe.c:4188 describe.c:4261 describe.c:4344 describe.c:4427 +#: describe.c:4546 describe.c:4612 describe.c:4680 describe.c:4821 +#: describe.c:4863 describe.c:4936 describe.c:4998 describe.c:5007 +#: describe.c:5069 describe.c:5291 describe.c:5371 describe.c:5506 +#: describe.c:5576 large_obj.c:290 large_obj.c:300 +msgid "Description" +msgstr "Beskrivning" + +#: describe.c:135 +msgid "List of aggregate functions" +msgstr "Lista med aggregatfunktioner" + +#: describe.c:160 +#, c-format +msgid "The server (version %s) does not support access methods." +msgstr "Servern (version %s) stöder inte accessmetoder." + +#: describe.c:175 +msgid "Index" +msgstr "Index" + +#: describe.c:176 describe.c:3727 describe.c:3942 describe.c:5493 +msgid "Table" +msgstr "Tabell" + +#: describe.c:184 describe.c:5270 +msgid "Handler" +msgstr "Hanterare" + +#: describe.c:203 +msgid "List of access methods" +msgstr "Lista med accessmetoder" + +#: describe.c:229 +#, c-format +msgid "The server (version %s) does not support tablespaces." +msgstr "Servern (version %s) stöder inte tabellutrymmen." + +#: describe.c:243 describe.c:251 describe.c:501 describe.c:717 describe.c:873 +#: describe.c:1114 describe.c:3720 describe.c:3918 describe.c:4087 +#: describe.c:4333 describe.c:4604 describe.c:5266 describe.c:5350 +#: describe.c:5746 describe.c:5883 describe.c:5986 describe.c:6101 +#: describe.c:6180 large_obj.c:289 +msgid "Owner" +msgstr "Ägare" + +#: describe.c:244 describe.c:252 +msgid "Location" +msgstr "Plats" + +#: describe.c:263 describe.c:3313 +msgid "Options" +msgstr "Alternativ" + +#: describe.c:268 describe.c:690 describe.c:889 describe.c:3761 describe.c:3765 +msgid "Size" +msgstr "Storlek" + +#: describe.c:290 +msgid "List of tablespaces" +msgstr "Lista med tabellutrymmen" + +#: describe.c:333 +#, c-format +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df tar bara [anptwS+] som flaggor" + +#: describe.c:341 describe.c:352 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df tar inte en \"%c\"-flagga med serverversion %s" + +#. translator: "agg" is short for "aggregate" +#: describe.c:389 describe.c:407 describe.c:453 describe.c:470 +msgid "agg" +msgstr "agg" + +#: describe.c:390 describe.c:408 +msgid "window" +msgstr "fönster" + +#: describe.c:391 +msgid "proc" +msgstr "proc" + +#: describe.c:392 describe.c:410 describe.c:455 describe.c:472 +msgid "func" +msgstr "funk" + +#: describe.c:409 describe.c:454 describe.c:471 describe.c:1324 +msgid "trigger" +msgstr "utlösare" + +#: describe.c:483 +msgid "immutable" +msgstr "oföränderlig" + +#: describe.c:484 +msgid "stable" +msgstr "stabil" + +#: describe.c:485 +msgid "volatile" +msgstr "instabil" + +#: describe.c:486 +msgid "Volatility" +msgstr "Instabilitet" + +#: describe.c:494 +msgid "restricted" +msgstr "begränsad" + +#: describe.c:495 +msgid "safe" +msgstr "säker" + +#: describe.c:496 +msgid "unsafe" +msgstr "osäker" + +#: describe.c:497 +msgid "Parallel" +msgstr "Parallell" + +#: describe.c:502 +msgid "definer" +msgstr "definierare" + +#: describe.c:503 +msgid "invoker" +msgstr "anropare" + +#: describe.c:504 +msgid "Security" +msgstr "Säkerhet" + +#: describe.c:511 +msgid "Language" +msgstr "Språk" + +#: describe.c:512 +msgid "Source code" +msgstr "Källkod" + +#: describe.c:641 +msgid "List of functions" +msgstr "Lista med funktioner" + +#: describe.c:689 +msgid "Internal name" +msgstr "Internt namn" + +#: describe.c:711 +msgid "Elements" +msgstr "Element" + +#: describe.c:768 +msgid "List of data types" +msgstr "Lista med datatyper" + +#: describe.c:812 +msgid "Left arg type" +msgstr "Vänster argumenttyp" + +#: describe.c:813 +msgid "Right arg type" +msgstr "Höger argumenttyp" + +#: describe.c:814 +msgid "Result type" +msgstr "Resultattyp" + +#: describe.c:819 describe.c:4339 describe.c:4404 describe.c:4410 +#: describe.c:4820 describe.c:6352 describe.c:6356 +msgid "Function" +msgstr "Funktion" + +#: describe.c:844 +msgid "List of operators" +msgstr "Lista med operatorer" + +#: describe.c:874 +msgid "Encoding" +msgstr "Kodning" + +#: describe.c:879 describe.c:4520 +msgid "Collate" +msgstr "Jämförelse" + +#: describe.c:880 describe.c:4521 +msgid "Ctype" +msgstr "Ctype" + +#: describe.c:893 +msgid "Tablespace" +msgstr "Tabellutrymme" + +#: describe.c:915 +msgid "List of databases" +msgstr "Lista med databaser" + +#: describe.c:956 describe.c:1117 describe.c:3710 +msgid "table" +msgstr "tabell" + +#: describe.c:957 describe.c:3711 +msgid "view" +msgstr "vy" + +#: describe.c:958 describe.c:3712 +msgid "materialized view" +msgstr "materialiserad vy" + +#: describe.c:959 describe.c:1119 describe.c:3714 +msgid "sequence" +msgstr "sekvens" + +#: describe.c:960 describe.c:3716 +msgid "foreign table" +msgstr "främmande tabell" + +#: describe.c:961 describe.c:3717 describe.c:3927 +msgid "partitioned table" +msgstr "partitionerad tabell" + +#: describe.c:973 +msgid "Column privileges" +msgstr "Kolumnrättigheter" + +#: describe.c:1004 describe.c:1038 +msgid "Policies" +msgstr "Policys" + +#: describe.c:1070 describe.c:6042 describe.c:6046 +msgid "Access privileges" +msgstr "Åtkomsträttigheter" + +#: describe.c:1101 +#, c-format +msgid "The server (version %s) does not support altering default privileges." +msgstr "Servern (version %s) stöder inte ändring av standardrättigheter." + +#: describe.c:1121 +msgid "function" +msgstr "funktion" + +#: describe.c:1123 +msgid "type" +msgstr "typ" + +#: describe.c:1125 +msgid "schema" +msgstr "schema" + +#: describe.c:1149 +msgid "Default access privileges" +msgstr "Standard accessrättigheter" + +#: describe.c:1189 +msgid "Object" +msgstr "Objekt" + +#: describe.c:1203 +msgid "table constraint" +msgstr "tabellvillkor" + +#: describe.c:1225 +msgid "domain constraint" +msgstr "domänvillkor" + +#: describe.c:1253 +msgid "operator class" +msgstr "operatorklass" + +#: describe.c:1282 +msgid "operator family" +msgstr "operatorfamilj" + +#: describe.c:1304 +msgid "rule" +msgstr "rule" + +#: describe.c:1346 +msgid "Object descriptions" +msgstr "Objektbeskrivningar" + +#: describe.c:1402 describe.c:3833 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "Kunde inte hitta en relation med namn \"%s\"." + +#: describe.c:1405 describe.c:3836 +#, c-format +msgid "Did not find any relations." +msgstr "Kunde inte hitta några relationer." + +#: describe.c:1660 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "Kunde inte hitta en relation med OID %s." + +#: describe.c:1712 describe.c:1736 +msgid "Start" +msgstr "Start" + +#: describe.c:1713 describe.c:1737 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1714 describe.c:1738 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1715 describe.c:1739 +msgid "Increment" +msgstr "Ökning" + +#: describe.c:1716 describe.c:1740 describe.c:1871 describe.c:4255 +#: describe.c:4421 describe.c:4535 describe.c:4540 describe.c:6089 +msgid "yes" +msgstr "ja" + +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4255 +#: describe.c:4418 describe.c:4535 describe.c:6090 +msgid "no" +msgstr "nej" + +#: describe.c:1718 describe.c:1742 +msgid "Cycles?" +msgstr "Cyklisk?" + +#: describe.c:1719 describe.c:1743 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1786 +#, c-format +msgid "Owned by: %s" +msgstr "Ägd av: %s" + +#: describe.c:1790 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Sekvens för identitetskolumn: %s" + +#: describe.c:1797 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Sekvens \"%s.%s\"" + +#: describe.c:1933 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Ologgad tabell \"%s.%s\"" + +#: describe.c:1936 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Tabell \"%s.%s\"" + +#: describe.c:1940 +#, c-format +msgid "View \"%s.%s\"" +msgstr "Vy \"%s.%s\"" + +#: describe.c:1945 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Ologgad materialiserad vy \"%s.%s\"" + +#: describe.c:1948 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "Materialiserad vy \"%s.%s\"" + +#: describe.c:1953 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Ologgat index \"%s.%s\"" + +#: describe.c:1956 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "Index \"%s.%s\"" + +#: describe.c:1961 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Ologgat partitionerat index \"%s.%s\"" + +#: describe.c:1964 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Partitionerat index \"%s.%s\"" + +#: describe.c:1969 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Särskild relation \"%s.%s\"" + +#: describe.c:1973 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "TOAST-tabell \"%s.%s\"" + +#: describe.c:1977 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Sammansatt typ \"%s.%s\"" + +#: describe.c:1981 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "Främmande tabell \"%s.%s\"" + +#: describe.c:1986 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Ologgad partitionerad tabell \"%s.%s\"" + +#: describe.c:1989 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Partitionerad tabell \"%s.%s\"" + +#: describe.c:2005 describe.c:4168 +msgid "Collation" +msgstr "Jämförelse" + +#: describe.c:2006 describe.c:4175 +msgid "Nullable" +msgstr "Nullbar" + +#: describe.c:2007 describe.c:4176 +msgid "Default" +msgstr "Standard" + +#: describe.c:2010 +msgid "Key?" +msgstr "Nyckel?" + +#: describe.c:2012 +msgid "Definition" +msgstr "Definition" + +#: describe.c:2014 describe.c:5286 describe.c:5370 describe.c:5441 +#: describe.c:5505 +msgid "FDW options" +msgstr "FDW-alternativ" + +#: describe.c:2016 +msgid "Storage" +msgstr "Lagring" + +#: describe.c:2018 +msgid "Stats target" +msgstr "Statistikmål" + +#: describe.c:2131 +#, c-format +msgid "Partition of: %s %s" +msgstr "Partition av: %s %s" + +#: describe.c:2143 +msgid "No partition constraint" +msgstr "Inget partitioneringsvillkor" + +#: describe.c:2145 +#, c-format +msgid "Partition constraint: %s" +msgstr "Partitioneringsvillkor: %s" + +#: describe.c:2169 +#, c-format +msgid "Partition key: %s" +msgstr "Partitioneringsnyckel: %s" + +#: describe.c:2195 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Ägande tabell \"%s.%s\"" + +#: describe.c:2266 +msgid "primary key, " +msgstr "primärnyckel, " + +#: describe.c:2268 +msgid "unique, " +msgstr "unik, " + +#: describe.c:2274 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "för tabell \"%s.%s\"" + +#: describe.c:2278 +#, c-format +msgid ", predicate (%s)" +msgstr ", predikat (%s)" + +#: describe.c:2281 +msgid ", clustered" +msgstr ", klustrad" + +#: describe.c:2284 +msgid ", invalid" +msgstr ", ogiltig" + +#: describe.c:2287 +msgid ", deferrable" +msgstr ", uppskjutbar" + +#: describe.c:2290 +msgid ", initially deferred" +msgstr ", initialt uppskjuten" + +#: describe.c:2293 +msgid ", replica identity" +msgstr ", replikaidentitet" + +#: describe.c:2360 +msgid "Indexes:" +msgstr "Index:" + +#: describe.c:2444 +msgid "Check constraints:" +msgstr "Kontrollvillkor:" + +#: describe.c:2512 +msgid "Foreign-key constraints:" +msgstr "Främmande nyckel-villkor:" + +#: describe.c:2575 +msgid "Referenced by:" +msgstr "Refererad av:" + +#: describe.c:2625 +msgid "Policies:" +msgstr "Policys:" + +#: describe.c:2628 +msgid "Policies (forced row security enabled):" +msgstr "Policys (tvingad radsäkerhet påslagen):" + +#: describe.c:2631 +msgid "Policies (row security enabled): (none)" +msgstr "Policys (radsäkerhet påslagna): (ingen)" + +#: describe.c:2634 +msgid "Policies (forced row security enabled): (none)" +msgstr "Policys (tvingad radsäkerhet påslagen): (ingen)" + +#: describe.c:2637 +msgid "Policies (row security disabled):" +msgstr "Policys (radsäkerhet avstängd):" + +#: describe.c:2700 +msgid "Statistics objects:" +msgstr "Statistikobjekt:" + +#: describe.c:2809 describe.c:2913 +msgid "Rules:" +msgstr "Regler:" + +#: describe.c:2812 +msgid "Disabled rules:" +msgstr "Avstängda regler:" + +#: describe.c:2815 +msgid "Rules firing always:" +msgstr "Regler som alltid utförs:" + +#: describe.c:2818 +msgid "Rules firing on replica only:" +msgstr "Regler som utförs enbart på replika:" + +#: describe.c:2858 +msgid "Publications:" +msgstr "Publiceringar:" + +#: describe.c:2896 +msgid "View definition:" +msgstr "Vydefinition:" + +#: describe.c:3043 +msgid "Triggers:" +msgstr "Utlösare:" + +#: describe.c:3047 +msgid "Disabled user triggers:" +msgstr "Avstängda användarutlösare:" + +#: describe.c:3049 +msgid "Disabled triggers:" +msgstr "Avstängda utlösare:" + +#: describe.c:3052 +msgid "Disabled internal triggers:" +msgstr "Avstängda interna utlösare:" + +#: describe.c:3055 +msgid "Triggers firing always:" +msgstr "Utlösare som alltid aktiveras:" + +#: describe.c:3058 +msgid "Triggers firing on replica only:" +msgstr "Utlösare som aktiveras enbart på replika:" + +#: describe.c:3130 +#, c-format +msgid "Server: %s" +msgstr "Server: %s" + +#: describe.c:3138 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW-alternativ: (%s)" + +#: describe.c:3159 +msgid "Inherits" +msgstr "Ärver" + +#: describe.c:3219 +#, c-format +msgid "Number of partitions: %d" +msgstr "Antal partitioner: %d" + +#: describe.c:3228 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Antal partitioner: %d (Använd \\d+ för att lista dem.)" + +#: describe.c:3230 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Antal barntabeller: %d (Använd \\d+ för att lista dem.)" + +#: describe.c:3237 +msgid "Child tables" +msgstr "Barntabeller" + +#: describe.c:3237 +msgid "Partitions" +msgstr "Partitioner" + +#: describe.c:3266 +#, c-format +msgid "Typed table of type: %s" +msgstr "Typad tabell av typ: %s" + +#: describe.c:3282 +msgid "Replica Identity" +msgstr "Replikaidentitet" + +#: describe.c:3295 +msgid "Has OIDs: yes" +msgstr "Har OID:er: ja" + +#: describe.c:3304 +#, c-format +msgid "Access method: %s" +msgstr "Accessmetod: %s" + +#: describe.c:3384 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Tabellutrymme: \"%s\"" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3396 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", tabellutrymme: \"%s\"" + +#: describe.c:3489 +msgid "List of roles" +msgstr "Lista med roller" + +#: describe.c:3491 +msgid "Role name" +msgstr "Rollnamn" + +#: describe.c:3492 +msgid "Attributes" +msgstr "Attribut" + +#: describe.c:3493 +msgid "Member of" +msgstr "Medlem av" + +#: describe.c:3504 +msgid "Superuser" +msgstr "Superanvändare" + +#: describe.c:3507 +msgid "No inheritance" +msgstr "Inget arv" + +#: describe.c:3510 +msgid "Create role" +msgstr "Skapa roll" + +#: describe.c:3513 +msgid "Create DB" +msgstr "Skapa DB" + +#: describe.c:3516 +msgid "Cannot login" +msgstr "Kan inte logga in" + +#: describe.c:3520 +msgid "Replication" +msgstr "Replikering" + +#: describe.c:3524 +msgid "Bypass RLS" +msgstr "Hopp över RLS" + +#: describe.c:3533 +msgid "No connections" +msgstr "Inga uppkopplingar" + +#: describe.c:3535 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d uppkoppling" +msgstr[1] "%d uppkopplingar" + +#: describe.c:3545 +msgid "Password valid until " +msgstr "Lösenord giltigt till " + +#: describe.c:3595 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "Servern (version %s) stöder inte rollinställningar per databas." + +#: describe.c:3608 +msgid "Role" +msgstr "Roll" + +#: describe.c:3609 +msgid "Database" +msgstr "Databas" + +#: describe.c:3610 +msgid "Settings" +msgstr "Inställningar" + +#: describe.c:3631 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "Kunde inte hitta några inställningar för roll \"%s\" och databas \"%s\"." + +#: describe.c:3634 +#, c-format +msgid "Did not find any settings for role \"%s\"." +msgstr "Kunde inte hitta några inställningar för roll \"%s\"." + +#: describe.c:3637 +#, c-format +msgid "Did not find any settings." +msgstr "Kunde inte hitta några inställningar." + +#: describe.c:3642 +msgid "List of settings" +msgstr "Lista med inställningar" + +#: describe.c:3713 +msgid "index" +msgstr "index" + +#: describe.c:3715 +msgid "special" +msgstr "särskild" + +#: describe.c:3718 describe.c:3928 +msgid "partitioned index" +msgstr "partitionerat index" + +#: describe.c:3742 +msgid "permanent" +msgstr "permanent" + +#: describe.c:3743 +msgid "temporary" +msgstr "temporär" + +#: describe.c:3744 +msgid "unlogged" +msgstr "ologgad" + +#: describe.c:3745 +msgid "Persistence" +msgstr "Persistens" + +#: describe.c:3841 +msgid "List of relations" +msgstr "Lista med relationer" + +#: describe.c:3889 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "Servern (version %s) stöder inte deklarativ tabellpartitionering." + +#: describe.c:3900 +msgid "List of partitioned indexes" +msgstr "Lista med partitionerade index" + +#: describe.c:3902 +msgid "List of partitioned tables" +msgstr "Lista med partitionerade tabeller" + +#: describe.c:3906 +msgid "List of partitioned relations" +msgstr "Lista med partitionerade relationer" + +#: describe.c:3937 +msgid "Parent name" +msgstr "Föräldranamn" + +#: describe.c:3950 +msgid "Leaf partition size" +msgstr "Partitionsstorlek av löv" + +#: describe.c:3953 describe.c:3959 +msgid "Total size" +msgstr "Total storlek" + +#: describe.c:4091 +msgid "Trusted" +msgstr "Tillförlitlig" + +#: describe.c:4099 +msgid "Internal language" +msgstr "Internt språk" + +#: describe.c:4100 +msgid "Call handler" +msgstr "Anropshanterare" + +#: describe.c:4101 describe.c:5273 +msgid "Validator" +msgstr "Validerare" + +#: describe.c:4104 +msgid "Inline handler" +msgstr "Inline-hanterare" + +#: describe.c:4132 +msgid "List of languages" +msgstr "Lista med språk" + +#: describe.c:4177 +msgid "Check" +msgstr "Check" + +#: describe.c:4219 +msgid "List of domains" +msgstr "Lista med domäner" + +#: describe.c:4253 +msgid "Source" +msgstr "Källa" + +#: describe.c:4254 +msgid "Destination" +msgstr "Mål" + +#: describe.c:4256 describe.c:6091 +msgid "Default?" +msgstr "Standard?" + +#: describe.c:4293 +msgid "List of conversions" +msgstr "Lista med konverteringar" + +#: describe.c:4332 +msgid "Event" +msgstr "Händelse" + +#: describe.c:4334 +msgid "enabled" +msgstr "påslagen" + +#: describe.c:4335 +msgid "replica" +msgstr "replika" + +#: describe.c:4336 +msgid "always" +msgstr "alltid" + +#: describe.c:4337 +msgid "disabled" +msgstr "avstängd" + +#: describe.c:4338 describe.c:5987 +msgid "Enabled" +msgstr "Påslagen" + +#: describe.c:4340 +msgid "Tags" +msgstr "Etiketter" + +#: describe.c:4359 +msgid "List of event triggers" +msgstr "Lista med händelseutlösare" + +#: describe.c:4388 +msgid "Source type" +msgstr "Källtyp" + +#: describe.c:4389 +msgid "Target type" +msgstr "Måltyp" + +#: describe.c:4420 +msgid "in assignment" +msgstr "i tilldelning" + +#: describe.c:4422 +msgid "Implicit?" +msgstr "Implicit?" + +#: describe.c:4477 +msgid "List of casts" +msgstr "Lista med typomvandlingar" + +#: describe.c:4505 +#, c-format +msgid "The server (version %s) does not support collations." +msgstr "Servern (version %s) stöder inte jämförelser (collations)." + +#: describe.c:4526 describe.c:4530 +msgid "Provider" +msgstr "Leverantör" + +#: describe.c:4536 describe.c:4541 +msgid "Deterministic?" +msgstr "Deterministisk?" + +#: describe.c:4576 +msgid "List of collations" +msgstr "Lista med jämförelser (collations)" + +#: describe.c:4635 +msgid "List of schemas" +msgstr "Lista med scheman" + +#: describe.c:4660 describe.c:4907 describe.c:4978 describe.c:5049 +#, c-format +msgid "The server (version %s) does not support full text search." +msgstr "Servern (version %s) stöder inte fulltextsökning." + +#: describe.c:4695 +msgid "List of text search parsers" +msgstr "Lista med textsökparsrar" + +#: describe.c:4740 +#, c-format +msgid "Did not find any text search parser named \"%s\"." +msgstr "Kunde inte hitta en textsökparser med namn \"%s\"." + +#: describe.c:4743 +#, c-format +msgid "Did not find any text search parsers." +msgstr "Kunde inte hitta några textsökparsrar." + +#: describe.c:4818 +msgid "Start parse" +msgstr "Starta parsning" + +#: describe.c:4819 +msgid "Method" +msgstr "Metod" + +#: describe.c:4823 +msgid "Get next token" +msgstr "Hämta nästa symbol" + +#: describe.c:4825 +msgid "End parse" +msgstr "Avsluta parsning" + +#: describe.c:4827 +msgid "Get headline" +msgstr "Hämta rubrik" + +#: describe.c:4829 +msgid "Get token types" +msgstr "Hämta symboltyper" + +#: describe.c:4840 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Textsökparser \"%s.%s\"" + +#: describe.c:4843 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "Textsökparser \"%s\"" + +#: describe.c:4862 +msgid "Token name" +msgstr "Symbolnamn" + +#: describe.c:4873 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "Symboltyper för parser \"%s.%s\"" + +#: describe.c:4876 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "Symboltyper för parser \"%s\"" + +#: describe.c:4930 +msgid "Template" +msgstr "Mall" + +#: describe.c:4931 +msgid "Init options" +msgstr "Initieringsalternativ" + +#: describe.c:4953 +msgid "List of text search dictionaries" +msgstr "Lista med textsökordlistor" + +#: describe.c:4996 +msgid "Init" +msgstr "Init" + +#: describe.c:4997 +msgid "Lexize" +msgstr "Symboluppdelning" + +#: describe.c:5024 +msgid "List of text search templates" +msgstr "Lista med textsökmallar" + +#: describe.c:5084 +msgid "List of text search configurations" +msgstr "Lista med textsökkonfigurationer" + +#: describe.c:5130 +#, c-format +msgid "Did not find any text search configuration named \"%s\"." +msgstr "Kunde inte hitta en textsökkonfiguration med namn \"%s\"." + +#: describe.c:5133 +#, c-format +msgid "Did not find any text search configurations." +msgstr "Kunde inte hitta några textsökkonfigurationer." + +#: describe.c:5199 +msgid "Token" +msgstr "Symbol" + +#: describe.c:5200 +msgid "Dictionaries" +msgstr "Ordlistor" + +#: describe.c:5211 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Textsökkonfiguration \"%s.%s\"" + +#: describe.c:5214 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Textsökkonfiguration \"%s\"" + +#: describe.c:5218 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Parser: \"%s.%s\"" + +#: describe.c:5221 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Parser: \"%s\"" + +#: describe.c:5255 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "Servern (version %s) stöder inte främmande data-omvandlare." + +#: describe.c:5313 +msgid "List of foreign-data wrappers" +msgstr "Lista med främmande data-omvandlare" + +#: describe.c:5338 +#, c-format +msgid "The server (version %s) does not support foreign servers." +msgstr "Servern (version %s) stöder inte främmande servrar." + +#: describe.c:5351 +msgid "Foreign-data wrapper" +msgstr "Främmande data-omvandlare" + +#: describe.c:5369 describe.c:5574 +msgid "Version" +msgstr "Version" + +#: describe.c:5395 +msgid "List of foreign servers" +msgstr "Lista med främmande servrar" + +#: describe.c:5420 +#, c-format +msgid "The server (version %s) does not support user mappings." +msgstr "Servern (version %s) stöder inte användarmappningar." + +#: describe.c:5430 describe.c:5494 +msgid "Server" +msgstr "Server" + +#: describe.c:5431 +msgid "User name" +msgstr "Användarnamn" + +#: describe.c:5456 +msgid "List of user mappings" +msgstr "Lista av användarmappningar" + +#: describe.c:5481 +#, c-format +msgid "The server (version %s) does not support foreign tables." +msgstr "Servern (version %s) stöder inte främmande tabeller." + +#: describe.c:5534 +msgid "List of foreign tables" +msgstr "Lista med främmande tabeller" + +#: describe.c:5559 describe.c:5616 +#, c-format +msgid "The server (version %s) does not support extensions." +msgstr "Servern (version %s) stöder inte utökningar." + +#: describe.c:5591 +msgid "List of installed extensions" +msgstr "Lista med installerade utökningar" + +#: describe.c:5644 +#, c-format +msgid "Did not find any extension named \"%s\"." +msgstr "Kunde inte hitta en utökning med namn \"%s\"." + +#: describe.c:5647 +#, c-format +msgid "Did not find any extensions." +msgstr "Kunde inte hitta några utökningar." + +#: describe.c:5691 +msgid "Object description" +msgstr "Objektbeskrivning" + +#: describe.c:5701 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "Objekt i utökning \"%s\"" + +#: describe.c:5730 describe.c:5806 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "Servern (version %s) stöder inte publiceringar." + +#: describe.c:5747 describe.c:5884 +msgid "All tables" +msgstr "Alla tabeller" + +#: describe.c:5748 describe.c:5885 +msgid "Inserts" +msgstr "Insättningar" + +#: describe.c:5749 describe.c:5886 +msgid "Updates" +msgstr "Uppdateringar" + +#: describe.c:5750 describe.c:5887 +msgid "Deletes" +msgstr "Borttagningar" + +#: describe.c:5754 describe.c:5889 +msgid "Truncates" +msgstr "Trunkerar" + +#: describe.c:5758 describe.c:5891 +msgid "Via root" +msgstr "Via root" + +#: describe.c:5775 +msgid "List of publications" +msgstr "Lista med publiceringar" + +#: describe.c:5848 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "Kunde inte hitta någon publicering med namn \"%s\"." + +#: describe.c:5851 +#, c-format +msgid "Did not find any publications." +msgstr "Kunde inte hitta några publiceringar." + +#: describe.c:5880 +#, c-format +msgid "Publication %s" +msgstr "Publicering %s" + +#: describe.c:5928 +msgid "Tables:" +msgstr "Tabeller:" + +#: describe.c:5972 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "Denna server (version %s) stöder inte prenumerationer." + +#: describe.c:5988 +msgid "Publication" +msgstr "Publicering" + +#: describe.c:5995 +msgid "Synchronous commit" +msgstr "Synkron commit" + +#: describe.c:5996 +msgid "Conninfo" +msgstr "Förbindelseinfo" + +#: describe.c:6018 +msgid "List of subscriptions" +msgstr "Lista med prenumerationer" + +#: describe.c:6085 describe.c:6174 describe.c:6260 describe.c:6343 +msgid "AM" +msgstr "AM" + +#: describe.c:6086 +msgid "Input type" +msgstr "Indatatyp" + +#: describe.c:6087 +msgid "Storage type" +msgstr "Lagringstyp" + +#: describe.c:6088 +msgid "Operator class" +msgstr "Operatorklass" + +#: describe.c:6100 describe.c:6175 describe.c:6261 describe.c:6344 +msgid "Operator family" +msgstr "Operatorfamilj" + +#: describe.c:6133 +msgid "List of operator classes" +msgstr "Lista med operatorklasser" + +#: describe.c:6176 +msgid "Applicable types" +msgstr "Applicerbara typer" + +#: describe.c:6215 +msgid "List of operator families" +msgstr "Lista med operatorfamiljer" + +#: describe.c:6262 +msgid "Operator" +msgstr "Operator" + +#: describe.c:6263 +msgid "Strategy" +msgstr "Strategi" + +#: describe.c:6264 +msgid "ordering" +msgstr "ordning" + +#: describe.c:6265 +msgid "search" +msgstr "sök" + +#: describe.c:6266 +msgid "Purpose" +msgstr "Ändamål" + +#: describe.c:6271 +msgid "Sort opfamily" +msgstr "Sortering-opfamilj" + +#: describe.c:6302 +msgid "List of operators of operator families" +msgstr "Lista med operatorer i operatorfamiljer" + +#: describe.c:6345 +msgid "Registered left type" +msgstr "Registrerad vänstertyp" + +#: describe.c:6346 +msgid "Registered right type" +msgstr "Registrerad högertyp" + +#: describe.c:6347 +msgid "Number" +msgstr "Nummer" + +#: describe.c:6383 +msgid "List of support functions of operator families" +msgstr "Lista med supportfunktioner i operatorfamiljer" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql är den interaktiva PostgreSQL-terminalen.\n" +"\n" + +#: help.c:74 help.c:355 help.c:431 help.c:474 +#, c-format +msgid "Usage:\n" +msgstr "Användning:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [FLAGGA]... [DBNAMN [ANVÄNDARNAMN]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Allmänna flaggor:\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr " -c, --command=KOMMANDO kör ett kommando (SQL eller internt) och avsluta sedan\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr " -d, --dbname=DBNAMN databasnamn att koppla upp mot (standard: \"%s\")\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=FILNAMN kör kommandon från fil och avsluta sedan\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, --list lista befintliga databaser och avsluta sedan\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variale=NAMN=VÄRDE\n" +" sätt psql-variabel NAMN till VÄRDE\n" +" (t.ex. -v ON_ERROR_STOP=1)\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X, --no-psqlrc läs inte startfilen (~/.psqlrc)\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 (\"ett\"), --single-transaction\n" +" kör kommandofilen som en transaktion (om icke-interaktiv)\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=alternativ] visa denna hjälp, avsluta sedan\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands lista bakstreck-kommandon, avsluta sedan\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variabler lista speciella variabler, avsluta sedan\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Flaggor för in-/utmatning:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all visa all indata från skript\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors visa misslyckade kommandon\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, --echo-queries visa kommandon som skickas till servern\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden visa frågor som interna kommandon skapar\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, --log-file=FILENAME skicka sessions-logg till fil\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, --no-readline slå av förbättrad kommandoradsredigering (readline)\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, --output=FILNAMN skriv frågeresultat till fil (eller |rör)\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, --quiet kör tyst (inga meddelanden, endast frågeutdata)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, --single-step stegningsläge (bekräfta varje fråga)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr " -S, --single-line enradsläge (slutet på raden avslutar SQL-kommando)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Flaggor för utdataformat:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align ojusterad utskrift av tabeller\n" + +#: help.c:111 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv CSV-utmarningsläge (kommaseparerade värden)\n" + +#: help.c:112 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, --field-separator=STRÄNG\n" +" fältseparator för icke justerad utdata (standard: \"%s\")\n" + +#: help.c:115 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html HTML-utskrift av tabeller\n" + +#: help.c:116 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr " -P, --pset=VAR[=ARG] sätt utskriftsvariabel VAR till ARG (se kommando \\pset)\n" + +#: help.c:117 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, --record-separator=STRÄNG\n" +" sätt postseparator för icke justerad utdata (standard: newline)\n" + +#: help.c:119 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only visa endast rader\n" + +#: help.c:120 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr " -T, --table-attr=TEXT sätt HTML-tabellers flaggor (t.ex. width, border)\n" + +#: help.c:121 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded slå på utökad utsrift av tabeller\n" + +#: help.c:122 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" sätt fältseparator för icke justerad utdata till noll-byte\n" + +#: help.c:124 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, --record-separator=zero\n" +" sätt postseparator för icke justerad utdata till noll-byte\n" + +#: help.c:127 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Flaggor för anslutning:\n" + +#: help.c:130 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr "" +" -h, --host=VÄRDNAMN databasens värdnamn eller uttagkatalog (socket)\n" +" (standard: \"%s\")\n" + +#: help.c:131 +msgid "local socket" +msgstr "lokalt uttag (socket)" + +#: help.c:134 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, --port=PORT databasens serverport (standard: \"%s\")\n" + +#: help.c:140 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, --username=ANVNAMN användarnamn för databasen (standard: \"%s\")\n" + +#: help.c:141 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password fråga aldrig efter lösenord\n" + +#: help.c:142 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password fråga om lösenord (borde ske automatiskt)\n" + +#: help.c:144 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"För mer information, skriv \"\\?\" (för interna kommandon) eller\n" +"\"\\help\" (för SQL-kommandon) i psql, eller läs avsnittet om psql\n" +"i PostgreSQL-dokumentationen.\n" +"\n" + +#: help.c:147 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Rapportera fel till <%s>.\n" + +#: help.c:148 +#, c-format +msgid "%s home page: <%s>\n" +msgstr "hemsida för %s: <%s>\n" + +#: help.c:174 +#, c-format +msgid "General\n" +msgstr "Allmänna\n" + +#: help.c:175 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright visa PostgreSQL-upphovsrättsinformation\n" + +#: help.c:176 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [KOLUMNER] kör fråga och visa resultatet i en korstabell\n" + +#: help.c:177 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose visa senste felmeddelande vid maximal verbositet\n" + +#: help.c:178 +#, c-format +msgid "" +" \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr "" +" \\g [(FLAGGOR)] [FIL] kör frågan (och skicka resultatet till fil eller |rör);\n" +" \\g utan argument är samma som ett semikolon\n" + +#: help.c:180 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc beskriv resultatet av fråga utan att köra den\n" + +#: help.c:181 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr " \\gexec kör fråga, kör sen varje värde i resultatet\n" + +#: help.c:182 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PREFIX] kör frågan och spara resultatet i psql-variabler\n" + +#: help.c:183 +#, c-format +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [(FLAGGOR)] [FIL] som \\g, men tvinga expanderat utmatningsläge\n" + +#: help.c:184 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q avsluta psql\n" + +#: help.c:185 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SEK] kör fråga var SEK sekund\n" + +#: help.c:188 +#, c-format +msgid "Help\n" +msgstr "Hjälp\n" + +#: help.c:190 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [kommandon] visa hjälp om backstreckkommandon\n" + +#: help.c:191 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr " \\? options visa hjälp för psqls kommandoradflaggor\n" + +#: help.c:192 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables visa hjälp om speciella variabler\n" + +#: help.c:193 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr " \\h [NAMN] hjälp med syntaxen för SQL-kommandon, * för alla kommandon\n" + +#: help.c:196 +#, c-format +msgid "Query Buffer\n" +msgstr "Frågebuffert\n" + +#: help.c:197 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr " \\e [FIL] [RAD] redigera frågebufferten (eller filen) med extern redigerare\n" + +#: help.c:198 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [FUNKNAMN [RAD]] redigera funktionsdefinition med extern redigerare\n" + +#: help.c:199 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr " \\ev [FUNKNAMN [RAD]] redigera vydefinition med extern redigerare\n" + +#: help.c:200 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p visa innehållet i frågebufferten\n" + +#: help.c:201 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r nollställ (radera) frågebufferten\n" + +#: help.c:203 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [FILNAMN] visa kommandohistorien eller spara den i fil\n" + +#: help.c:205 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w FILNAMN skriv frågebuffert till fil\n" + +#: help.c:208 +#, c-format +msgid "Input/Output\n" +msgstr "In-/Utmatning\n" + +#: help.c:209 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr " \\copy ... utför SQL COPY med dataström till klientvärden\n" + +#: help.c:210 +#, c-format +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr " \\echo [-n] [TEXT] skriv text till standard ut (-n för ingen nyrad)\n" + +#: help.c:211 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i FILNAMN kör kommandon från fil\n" + +#: help.c:212 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr " \\ir FIL som \\i, men relativt platsen för aktuellt script\n" + +#: help.c:213 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [FIL] skicka frågeresultat till fil eller |rör\n" + +#: help.c:214 +#, c-format +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr " \\qecho [-n] [TEXT] skriv text till \\o-utdataströmmen (-n för ingen nyrad)\n" + +#: help.c:215 +#, c-format +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr " \\warn [-n] [TEXT] skriv text till standard error (-n för ingen nyrad)\n" + +#: help.c:218 +#, c-format +msgid "Conditional\n" +msgstr "Villkor\n" + +#: help.c:219 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR starta villkorsblock\n" + +#: help.c:220 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR alternativ inom aktuellt villkorsblock\n" + +#: help.c:221 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else avslutningsalternativ inom aktuellt villkorsblock\n" + +#: help.c:222 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif avsluta villkorsblock\n" + +#: help.c:225 +#, c-format +msgid "Informational\n" +msgstr "Informationer\n" + +#: help.c:226 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (flaggor: S = lista systemobjekt, + = mer detaljer)\n" + +#: help.c:227 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] lista tabeller, vyer och sekvenser\n" + +#: help.c:228 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+] NAMN beskriv tabell, vy, sekvens eller index\n" + +#: help.c:229 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [MALL] lista aggregatfunktioner\n" + +#: help.c:230 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [MALL] lista accessmetoder\n" + +#: help.c:231 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] lista operatorklasser\n" + +#: help.c:232 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] lista operatorfamiljer\n" + +#: help.c:233 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] lista operatorer i operatorfamiljer\n" + +#: help.c:234 +#, c-format +msgid " \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp [AMPTRN [OPFPTRN]] lista supportfunktioner i operatorfamiljer\n" + +#: help.c:235 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [MALL] lista tabellutrymmen\n" + +#: help.c:236 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [MALL] lista konverteringar\n" + +#: help.c:237 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [MALL] lista typomvandlingar\n" + +#: help.c:238 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr " \\dd[S] [MALL] visa objektbeskrivning som inte visas på andra ställen\n" + +#: help.c:239 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [MALL] lista domäner\n" + +#: help.c:240 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [MALL] lista standardrättigheter\n" + +#: help.c:241 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [MALL] lista främmande tabeller\n" + +#: help.c:242 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [MALL] lista främmande tabeller\n" + +#: help.c:243 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [MALL] lista främmande servrar\n" + +#: help.c:244 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [MALL] lista användarmappning\n" + +#: help.c:245 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [MALL] lista främmande data-omvandlare\n" + +#: help.c:246 +#, c-format +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [MALL] lista [endast agg/normala/procedur/utlösar/window] funktioner\n" + +#: help.c:247 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [MALL] lista textsökkonfigurationer\n" + +#: help.c:248 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [MALL] lista textsökordlistor\n" + +#: help.c:249 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [MALL] lista textsökparsrar\n" + +#: help.c:250 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [MALL] lista textsökmallar\n" + +#: help.c:251 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [MALL] lista roller\n" + +#: help.c:252 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [MALL] lista index\n" + +#: help.c:253 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl lista stora objekt, samma som \\lo_list\n" + +#: help.c:254 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [MALL] lista procedurspråk\n" + +#: help.c:255 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [MALL] lista materialiserade vyer\n" + +#: help.c:256 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [MALL] lista scheman\n" + +#: help.c:257 +#, c-format +msgid " \\do[S] [PATTERN] list operators\n" +msgstr " \\do[S] [MALL] lista operatorer\n" + +#: help.c:258 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [MALL] lista jämförelser (collation)\n" + +#: help.c:259 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [MALL] lista åtkomsträttigheter för tabeller, vyer och sekvenser\n" + +#: help.c:260 +#, c-format +msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" +msgstr " \\dP[tin+] [MALL] lista [bara tabell/index] partitionerade relationer [n=nästlad]\n" + +#: help.c:261 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [MALL1 [MALL2]] lista rollinställningar per databas\n" + +#: help.c:262 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [MALL] lista replikeringspubliceringar\n" + +#: help.c:263 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [MALL] lista replikeringsprenumerationer\n" + +#: help.c:264 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [MALL] lista sekvenser\n" + +#: help.c:265 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [MALL] lista tabeller\n" + +#: help.c:266 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [MALL] lista datatyper\n" + +#: help.c:267 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [MALL] lista roller\n" + +#: help.c:268 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [MALL] lista vyer\n" + +#: help.c:269 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [MALL] lista utökningar\n" + +#: help.c:270 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [MALL] lista händelseutlösare\n" + +#: help.c:271 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [MALL] lista databaser\n" + +#: help.c:272 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] FUNKNAMN visa en funktions definition\n" + +#: help.c:273 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] VYNAMN visa en vys definition\n" + +#: help.c:274 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [MALL] samma som \\dp\n" + +#: help.c:277 +#, c-format +msgid "Formatting\n" +msgstr "Formatering\n" + +#: help.c:278 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr " \\a byt mellan ojusterat och justerat utdataformat\n" + +#: help.c:279 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr " \\C [TEXT] sätt tabelltitel, eller nollställ\n" + +#: help.c:280 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr " \\f [TEXT] visa eller sätt fältseparatorn för ojusterad utmatning\n" + +#: help.c:281 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H slå på/av HTML-utskriftsläge (för närvarande: %s)\n" + +#: help.c:283 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" +msgstr "" +" \\pset [NAMN [VÄRDE]] sätt utmatningsalternativ för tabeller\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" + +#: help.c:290 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] visa endast rader (för närvarande: %s)\n" + +#: help.c:292 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr " \\T [TEXT] sätt HTML-tabellens
-attribut, eller nollställ\n" + +#: help.c:293 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] slå på/av utökad utskrift (för närvarande: %s)\n" + +#: help.c:297 +#, c-format +msgid "Connection\n" +msgstr "Förbindelse\n" + +#: help.c:299 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[DBNAMN|- ANVÄNDARE|- VÄRD|- PORT|-] | conninfo}\n" +" koppla upp mot ny databas (för närvarande \"%s\")\n" + +#: help.c:303 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[DBNAMN|- ANVÄNDARE|- VÄRD|- PORT|-] | conninfo}\n" +" koppla upp mot ny databas (för närvarande ingen uppkoppling)\n" + +#: help.c:305 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo visa information om aktuell uppkoppling\n" + +#: help.c:306 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [KODNING] visa eller sätt klientens teckenkodning\n" + +#: help.c:307 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr " \\password [ANVÄNDARNAMN] byt användares lösenord på ett säkert sätt\n" + +#: help.c:310 +#, c-format +msgid "Operating System\n" +msgstr "Operativsystem\n" + +#: help.c:311 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [KATALOG] byt den aktuella katalogen\n" + +#: help.c:312 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv NAMN [VÄRDE] sätt eller nollställ omgivningsvariabel\n" + +#: help.c:313 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] slå på/av tidstagning av kommandon (för närvarande: %s)\n" + +#: help.c:315 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr " \\! [KOMMANDO] kör kommando i skal eller starta interaktivt skal\n" + +#: help.c:318 +#, c-format +msgid "Variables\n" +msgstr "Variabler\n" + +#: help.c:319 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr " \\prompt [TEXT] NAMN be användaren att sätta en intern variabel\n" + +#: help.c:320 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr " \\set [NAMN [VÄRDE]] sätt intern variabel, eller lista alla om ingen param\n" + +#: help.c:321 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset NAME ta bort intern variabel\n" + +#: help.c:324 +#, c-format +msgid "Large Objects\n" +msgstr "Stora objekt\n" + +#: help.c:325 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID FIL\n" +" \\lo_import FIL [KOMMENTAR]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID operationer på stora objekt\n" + +#: help.c:352 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "Lista av variabler som hanteras speciellt\n" + +#: help.c:354 +#, c-format +msgid "psql variables:\n" +msgstr "psql-variabler:\n" + +#: help.c:356 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=NAMN=VÄRDE\n" +" eller \\set NAMN VÄRDE inne i psql\n" +"\n" + +#: help.c:358 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" om satt så kommer efterföljande SQL-kommandon commit:as automatiskt\n" + +#: help.c:360 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" bestämmer skiftläge för att komplettera SQL-nyckelord\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:363 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" den uppkopplade databasens namn\n" + +#: help.c:365 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" bestämmer vilken indata som skrivs till standard ut\n" +" [all, errors, none, queries]\n" + +#: help.c:368 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" om satt, visa interna frågor som körs av backåtstreckkommandon:\n" +" om satt till \"noexec\", bara visa dem utan att köra\n" + +#: help.c:371 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" aktuell teckenkodning för klient\n" + +#: help.c:373 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" sant om sista frågan misslyckades, falskt annars\n" + +#: help.c:375 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" antal resultatrader som hämtas och visas åt gången (0=obegränsat)\n" + +#: help.c:377 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" om satt så visas inte accessmetoder\n" + +#: help.c:379 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" styr kommandohistoriken [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:381 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" filnamn för att spara kommandohistoriken i\n" + +#: help.c:383 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" maximalt antal kommandon som sparas i kommandohistoriken\n" + +#: help.c:385 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" den uppkopplade databasens värd\n" + +#: help.c:387 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" antal EOF som behövs för att avsluta en interaktiv session\n" + +#: help.c:389 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" värdet av den senast påverkade OID:en\n" + +#: help.c:391 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" meddelande och SQLSTATE för sista felet eller en tom sträng och \"00000\" om det inte varit fel\n" + +#: help.c:394 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" om satt, ett fel stoppar inte en transaktion (använder implicita sparpunkter)\n" + +#: help.c:396 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" avsluta batchkörning vid fel\n" + +#: help.c:398 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" värdport för den aktuella uppkopplingen\n" + +#: help.c:400 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" anger standardprompten för psql\n" + +#: help.c:402 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" anger den prompt som används om en sats forsätter på efterföljande rad\n" + +#: help.c:404 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" anger den prompt som används för COPY ... FROM STDIN\n" + +#: help.c:406 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" kör tyst (samma som flaggan -q)\n" + +#: help.c:408 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" antal rader som returnerades eller påverkades av senaste frågan alternativt 0\n" + +#: help.c:410 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NUM\n" +" SERVER_VERSION_NAME\n" +" serverns version (i kort sträng eller numeriskt format)\n" + +#: help.c:413 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" styr visning av meddelandekontextfält [never, errors, always]\n" + +#: help.c:415 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" om satt, slut på raden avslutar SQL-kommandon (samma som flaggan -S )\n" + +#: help.c:417 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" stegningsläge (samma som flaggan -s)\n" + +#: help.c:419 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE för sista frågan eller \"00000\" om det inte varit fel\n" + +#: help.c:421 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" den uppkopplade databasanvändaren\n" + +#: help.c:423 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" styr verbositet för felrapporter [default, verbose, terse, sqlstate]\n" + +#: help.c:425 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql:s version (i lång sträng, kort sträng eller numeriskt format)\n" + +#: help.c:430 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Visningsinställningar:\n" + +#: help.c:432 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NAMN[=VÄRDE]\n" +" eller \\pset NAMN [VÄRDE] inne i psql\n" +"\n" + +#: help.c:434 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" ramstil (nummer)\n" + +#: help.c:436 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" målvidd för wrappade format\n" + +#: help.c:438 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (eller x)\n" +" expanderad utdata [on, off, auto]\n" + +#: help.c:440 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" fältseparator för ej justerad utdata (standard \"%s\")\n" + +#: help.c:443 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" sätt fältseparator för ej justerad utdata till noll-byte\n" + +#: help.c:445 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" slå på/av visning av tabellfot [on, off]\n" + +#: help.c:447 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" sätt utdataformat [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:449 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" sätt ramlinjestil [ascii, old-ascii, unicode]\n" + +#: help.c:451 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" sätt sträng som visas istället för null-värden\n" + +#: help.c:453 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +" numericlocale\n" +" slå på visning av lokalspecifika tecken för gruppering av siffror\n" + +#: help.c:455 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" styr när en extern pagenerare används [yes, no, always]\n" + +#: help.c:457 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" post (rad) separator för ej justerad utdata\n" + +#: help.c:459 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" sätt postseparator för ej justerad utdata till noll-byte\n" + +#: help.c:461 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (el. T)\n" +" ange attribut för tabelltaggen i html-format eller proportionella\n" +" kolumnvidder för vänsterjusterade datatypet i latex-longtable-format\n" + +#: help.c:464 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" sätt tabelltitel för efterkommande tabellutskrifter\n" + +#: help.c:466 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" om satt, bara tabelldatan visas\n" + +#: help.c:468 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" sätter stilen på Unicode-linjer [single, double]\n" + +#: help.c:473 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Omgivningsvariabler:\n" + +#: help.c:477 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NAMN=VÄRDE [NAMN=VÄRDE] psql ...\n" +" eller \\setenv NAMN [VÄRDE] inne psql\n" +"\n" + +#: help.c:479 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NAMN=VÄRDE\n" +" psql ...\n" +" eller \\setenv NAMN [VÄRDE] inne i psql\n" +"\n" + +#: help.c:482 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" antal kolumner i wrappade format\n" + +#: help.c:484 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" samma som anslutningsparametern \"application_name\"\n" + +#: help.c:486 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" samma som anslutningsparametern \"dbname\"\n" + +#: help.c:488 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" samma som anslutningsparametern \"host\"\n" + +#: help.c:490 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" uppkoppingens lösenord (rekommenderas inte)\n" + +#: help.c:492 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" lösenordsfilnamn\n" + +#: help.c:494 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" samma som anslutingsparametern \"port\"\n" + +#: help.c:496 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" samma som anslutningsparametern \"user\"\n" + +#: help.c:498 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" redigerare som används av kommanona \\e, \\ef och \\ev\n" + +#: help.c:500 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" hur radnummer anges när redigerare startas\n" + +#: help.c:502 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" alternativ plats för kommandohistorikfilen\n" + +#: help.c:504 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PAGER\n" +" namnet på den externa pageneraren\n" + +#: help.c:506 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" alternativ plats för användarens \".psqlrc\"-fil\n" + +#: help.c:508 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" skalet som används av kommandot \\!\n" + +#: help.c:510 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" katalog för temporärfiler\n" + +#: help.c:554 +msgid "Available help:\n" +msgstr "Tillgänglig hjälp:\n" + +#: help.c:642 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" +msgstr "" +"Kommando: %s\n" +"Beskrivning: %s\n" +"Syntax:\n" +"%s\n" +"\n" +"URL: %s\n" +"\n" + +#: help.c:661 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"Ingen hjälp tillgänglig för \"%s\".\n" +"Försök med \\h utan argument för att se den tillgängliga hjälpen.\n" + +#: input.c:217 +#, c-format +msgid "could not read from input file: %m" +msgstr "kunde inte läsa från infilen: %m" + +#: input.c:471 input.c:509 +#, c-format +msgid "could not save history to file \"%s\": %m" +msgstr "kunde inte skriva kommandohistorien till \"%s\": %m" + +#: input.c:528 +#, c-format +msgid "history is not supported by this installation" +msgstr "historia stöds inte av denna installationen" + +#: large_obj.c:65 +#, c-format +msgid "%s: not connected to a database" +msgstr "%s: ej uppkopplad mot en databas" + +#: large_obj.c:84 +#, c-format +msgid "%s: current transaction is aborted" +msgstr "%s: aktuell transaktion är avbruten" + +#: large_obj.c:87 +#, c-format +msgid "%s: unknown transaction status" +msgstr "%s: okänd transaktionsstatus" + +#: large_obj.c:288 large_obj.c:299 +msgid "ID" +msgstr "ID" + +#: large_obj.c:309 +msgid "Large objects" +msgstr "Stora objekt" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped" +msgstr "\\if: escape:ad" + +#: mainloop.c:195 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "Använd \"\\q\" för att lämna %s.\n" + +#: mainloop.c:217 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Indatan är en PostgreSQL-specifik dump.\n" +"Använd kommandoradsprogrammet pg_restore för att läsa in denna dump till databasen.\n" + +#: mainloop.c:298 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Använd \\? för hjälp eller tryck control-C för att nollställa inmatningsbufferten." + +#: mainloop.c:300 +msgid "Use \\? for help." +msgstr "Använd \\? för hjälp." + +#: mainloop.c:304 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "Du använder psql, den interaktiva PostgreSQL-terminalen." + +#: mainloop.c:305 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Skriv: \\copyright för upphovsrättsinformation\n" +" \\h för hjälp om SQL-kommandon\n" +" \\? för hjälp om psql-kommandon\n" +" \\g eller avsluta med semikolon för att köra en fråga\n" +" \\q för att avsluta\n" + +#: mainloop.c:329 +msgid "Use \\q to quit." +msgstr "Använd \\q för att avsluta." + +#: mainloop.c:332 mainloop.c:356 +msgid "Use control-D to quit." +msgstr "Använd control-D för att avsluta." + +#: mainloop.c:334 mainloop.c:358 +msgid "Use control-C to quit." +msgstr "Använd control-C för att avsluta." + +#: mainloop.c:465 mainloop.c:613 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "fråga ignorerat; använd \\endif eller Ctrl-C för att avsluta aktuellt \\if-block" + +#: mainloop.c:631 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "kom till EOF utan att hitta avslutande \\endif" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "icketerminerad citerad sträng" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: slut på minne" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1090 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 +#: sql_help.c:1112 sql_help.c:1114 sql_help.c:1118 sql_help.c:1121 +#: sql_help.c:1122 sql_help.c:1123 sql_help.c:1126 sql_help.c:1128 +#: sql_help.c:1262 sql_help.c:1264 sql_help.c:1267 sql_help.c:1270 +#: sql_help.c:1272 sql_help.c:1274 sql_help.c:1277 sql_help.c:1280 +#: sql_help.c:1391 sql_help.c:1393 sql_help.c:1395 sql_help.c:1398 +#: sql_help.c:1419 sql_help.c:1422 sql_help.c:1425 sql_help.c:1428 +#: sql_help.c:1432 sql_help.c:1434 sql_help.c:1436 sql_help.c:1438 +#: sql_help.c:1452 sql_help.c:1455 sql_help.c:1457 sql_help.c:1459 +#: sql_help.c:1469 sql_help.c:1471 sql_help.c:1481 sql_help.c:1483 +#: sql_help.c:1493 sql_help.c:1496 sql_help.c:1519 sql_help.c:1521 +#: sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 sql_help.c:1530 +#: sql_help.c:1533 sql_help.c:1536 sql_help.c:1586 sql_help.c:1629 +#: sql_help.c:1632 sql_help.c:1634 sql_help.c:1636 sql_help.c:1639 +#: sql_help.c:1641 sql_help.c:1643 sql_help.c:1646 sql_help.c:1696 +#: sql_help.c:1712 sql_help.c:1933 sql_help.c:2002 sql_help.c:2021 +#: sql_help.c:2034 sql_help.c:2091 sql_help.c:2098 sql_help.c:2108 +#: sql_help.c:2129 sql_help.c:2155 sql_help.c:2173 sql_help.c:2200 +#: sql_help.c:2295 sql_help.c:2340 sql_help.c:2364 sql_help.c:2387 +#: sql_help.c:2391 sql_help.c:2425 sql_help.c:2445 sql_help.c:2467 +#: sql_help.c:2481 sql_help.c:2501 sql_help.c:2524 sql_help.c:2554 +#: sql_help.c:2579 sql_help.c:2625 sql_help.c:2903 sql_help.c:2916 +#: sql_help.c:2933 sql_help.c:2949 sql_help.c:2989 sql_help.c:3041 +#: sql_help.c:3045 sql_help.c:3047 sql_help.c:3053 sql_help.c:3071 +#: sql_help.c:3098 sql_help.c:3133 sql_help.c:3145 sql_help.c:3154 +#: sql_help.c:3198 sql_help.c:3212 sql_help.c:3240 sql_help.c:3248 +#: sql_help.c:3260 sql_help.c:3270 sql_help.c:3278 sql_help.c:3286 +#: sql_help.c:3294 sql_help.c:3302 sql_help.c:3311 sql_help.c:3322 +#: sql_help.c:3330 sql_help.c:3338 sql_help.c:3346 sql_help.c:3354 +#: sql_help.c:3364 sql_help.c:3373 sql_help.c:3382 sql_help.c:3390 +#: sql_help.c:3400 sql_help.c:3411 sql_help.c:3419 sql_help.c:3428 +#: sql_help.c:3439 sql_help.c:3448 sql_help.c:3456 sql_help.c:3464 +#: sql_help.c:3472 sql_help.c:3480 sql_help.c:3488 sql_help.c:3496 +#: sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 sql_help.c:3528 +#: sql_help.c:3545 sql_help.c:3554 sql_help.c:3562 sql_help.c:3579 +#: sql_help.c:3594 sql_help.c:3869 sql_help.c:3920 sql_help.c:3949 +#: sql_help.c:3962 sql_help.c:4407 sql_help.c:4455 sql_help.c:4596 +msgid "name" +msgstr "namn" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1783 +#: sql_help.c:3213 sql_help.c:4193 +msgid "aggregate_signature" +msgstr "aggregatsignatur" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1093 sql_help.c:1129 sql_help.c:1271 sql_help.c:1392 +#: sql_help.c:1435 sql_help.c:1456 sql_help.c:1470 sql_help.c:1482 +#: sql_help.c:1495 sql_help.c:1522 sql_help.c:1587 sql_help.c:1640 +msgid "new_name" +msgstr "nytt_namn" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1091 sql_help.c:1127 sql_help.c:1332 +#: sql_help.c:1394 sql_help.c:1437 sql_help.c:1458 sql_help.c:1520 +#: sql_help.c:1635 sql_help.c:2889 +msgid "new_owner" +msgstr "ny_ägare" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1095 +#: sql_help.c:1273 sql_help.c:1439 sql_help.c:1460 sql_help.c:1472 +#: sql_help.c:1484 sql_help.c:1524 sql_help.c:1642 +msgid "new_schema" +msgstr "nytt_schema" + +#: sql_help.c:44 sql_help.c:1847 sql_help.c:3214 sql_help.c:4222 +msgid "where aggregate_signature is:" +msgstr "där aggregatsignatur är:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1801 +#: sql_help.c:1818 sql_help.c:1824 sql_help.c:1848 sql_help.c:1851 +#: sql_help.c:1854 sql_help.c:2003 sql_help.c:2022 sql_help.c:2025 +#: sql_help.c:2296 sql_help.c:2502 sql_help.c:3215 sql_help.c:3218 +#: sql_help.c:3221 sql_help.c:3312 sql_help.c:3401 sql_help.c:3429 +#: sql_help.c:3753 sql_help.c:4101 sql_help.c:4199 sql_help.c:4206 +#: sql_help.c:4212 sql_help.c:4223 sql_help.c:4226 sql_help.c:4229 +msgid "argmode" +msgstr "arg_läge" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1802 +#: sql_help.c:1819 sql_help.c:1825 sql_help.c:1849 sql_help.c:1852 +#: sql_help.c:1855 sql_help.c:2004 sql_help.c:2023 sql_help.c:2026 +#: sql_help.c:2297 sql_help.c:2503 sql_help.c:3216 sql_help.c:3219 +#: sql_help.c:3222 sql_help.c:3313 sql_help.c:3402 sql_help.c:3430 +#: sql_help.c:4200 sql_help.c:4207 sql_help.c:4213 sql_help.c:4224 +#: sql_help.c:4227 sql_help.c:4230 +msgid "argname" +msgstr "arg_namn" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1803 +#: sql_help.c:1820 sql_help.c:1826 sql_help.c:1850 sql_help.c:1853 +#: sql_help.c:1856 sql_help.c:2298 sql_help.c:2504 sql_help.c:3217 +#: sql_help.c:3220 sql_help.c:3223 sql_help.c:3314 sql_help.c:3403 +#: sql_help.c:3431 sql_help.c:4201 sql_help.c:4208 sql_help.c:4214 +#: sql_help.c:4225 sql_help.c:4228 sql_help.c:4231 +msgid "argtype" +msgstr "arg_typ" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1453 sql_help.c:1581 sql_help.c:1613 +#: sql_help.c:1665 sql_help.c:1904 sql_help.c:1911 sql_help.c:2203 +#: sql_help.c:2245 sql_help.c:2252 sql_help.c:2261 sql_help.c:2341 +#: sql_help.c:2555 sql_help.c:2647 sql_help.c:2918 sql_help.c:3099 +#: sql_help.c:3121 sql_help.c:3261 sql_help.c:3616 sql_help.c:3788 +#: sql_help.c:3961 sql_help.c:4658 +msgid "option" +msgstr "flaggor" + +#: sql_help.c:113 sql_help.c:927 sql_help.c:1582 sql_help.c:2342 +#: sql_help.c:2556 sql_help.c:3100 sql_help.c:3262 +msgid "where option can be:" +msgstr "där flaggor kan vara:" + +#: sql_help.c:114 sql_help.c:2137 +msgid "allowconn" +msgstr "tillåtansl" + +#: sql_help.c:115 sql_help.c:928 sql_help.c:1583 sql_help.c:2138 +#: sql_help.c:2343 sql_help.c:2557 sql_help.c:3101 +msgid "connlimit" +msgstr "anslutningstak" + +#: sql_help.c:116 sql_help.c:2139 +msgid "istemplate" +msgstr "ärmall" + +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1276 sql_help.c:1325 +msgid "new_tablespace" +msgstr "nytt_tabellutrymme" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1140 sql_help.c:1143 sql_help.c:1590 +#: sql_help.c:1594 sql_help.c:1597 sql_help.c:2308 sql_help.c:2508 +#: sql_help.c:3980 sql_help.c:4396 +msgid "configuration_parameter" +msgstr "konfigurationsparameter" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1117 sql_help.c:1120 sql_help.c:1125 sql_help.c:1141 +#: sql_help.c:1142 sql_help.c:1307 sql_help.c:1327 sql_help.c:1375 +#: sql_help.c:1397 sql_help.c:1454 sql_help.c:1538 sql_help.c:1591 +#: sql_help.c:1614 sql_help.c:2204 sql_help.c:2246 sql_help.c:2253 +#: sql_help.c:2262 sql_help.c:2309 sql_help.c:2310 sql_help.c:2372 +#: sql_help.c:2375 sql_help.c:2409 sql_help.c:2509 sql_help.c:2510 +#: sql_help.c:2527 sql_help.c:2648 sql_help.c:2678 sql_help.c:2783 +#: sql_help.c:2796 sql_help.c:2810 sql_help.c:2851 sql_help.c:2875 +#: sql_help.c:2892 sql_help.c:2919 sql_help.c:3122 sql_help.c:3789 +#: sql_help.c:4397 sql_help.c:4398 +msgid "value" +msgstr "värde" + +#: sql_help.c:197 +msgid "target_role" +msgstr "målroll" + +#: sql_help.c:198 sql_help.c:2188 sql_help.c:2603 sql_help.c:2608 +#: sql_help.c:3735 sql_help.c:3742 sql_help.c:3756 sql_help.c:3762 +#: sql_help.c:4083 sql_help.c:4090 sql_help.c:4104 sql_help.c:4110 +msgid "schema_name" +msgstr "schemanamn" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "förkortad_grant_eller_revoke" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "där förkortad_grant_eller_revok är en av:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1275 sql_help.c:1601 sql_help.c:2346 sql_help.c:2347 +#: sql_help.c:2348 sql_help.c:2349 sql_help.c:2350 sql_help.c:2483 +#: sql_help.c:2560 sql_help.c:2561 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 sql_help.c:3104 sql_help.c:3105 sql_help.c:3106 +#: sql_help.c:3107 sql_help.c:3108 sql_help.c:3768 sql_help.c:3772 +#: sql_help.c:4116 sql_help.c:4120 sql_help.c:4417 +msgid "role_name" +msgstr "rollnamn" + +#: sql_help.c:236 sql_help.c:459 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1342 sql_help.c:1354 sql_help.c:1379 sql_help.c:1631 +#: sql_help.c:2158 sql_help.c:2162 sql_help.c:2265 sql_help.c:2270 +#: sql_help.c:2368 sql_help.c:2778 sql_help.c:2791 sql_help.c:2805 +#: sql_help.c:2814 sql_help.c:2826 sql_help.c:2855 sql_help.c:3820 +#: sql_help.c:3835 sql_help.c:3837 sql_help.c:4282 sql_help.c:4283 +#: sql_help.c:4292 sql_help.c:4333 sql_help.c:4334 sql_help.c:4335 +#: sql_help.c:4336 sql_help.c:4337 sql_help.c:4338 sql_help.c:4371 +#: sql_help.c:4372 sql_help.c:4377 sql_help.c:4382 sql_help.c:4521 +#: sql_help.c:4522 sql_help.c:4531 sql_help.c:4572 sql_help.c:4573 +#: sql_help.c:4574 sql_help.c:4575 sql_help.c:4576 sql_help.c:4577 +#: sql_help.c:4624 sql_help.c:4626 sql_help.c:4685 sql_help.c:4741 +#: sql_help.c:4742 sql_help.c:4751 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 +msgid "expression" +msgstr "uttryck" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "domain_villkor" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1268 sql_help.c:1313 sql_help.c:1314 sql_help.c:1315 +#: sql_help.c:1341 sql_help.c:1353 sql_help.c:1370 sql_help.c:1789 +#: sql_help.c:1791 sql_help.c:2161 sql_help.c:2264 sql_help.c:2269 +#: sql_help.c:2813 sql_help.c:2825 sql_help.c:3832 +msgid "constraint_name" +msgstr "villkorsnamn" + +#: sql_help.c:244 sql_help.c:1269 +msgid "new_constraint_name" +msgstr "nyy_villkorsnamn" + +#: sql_help.c:317 sql_help.c:1073 +msgid "new_version" +msgstr "ny_version" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "medlemsobjekt" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "där medlemsobjekt är:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1781 sql_help.c:1786 sql_help.c:1793 +#: sql_help.c:1794 sql_help.c:1795 sql_help.c:1796 sql_help.c:1797 +#: sql_help.c:1798 sql_help.c:1799 sql_help.c:1804 sql_help.c:1806 +#: sql_help.c:1810 sql_help.c:1812 sql_help.c:1816 sql_help.c:1821 +#: sql_help.c:1822 sql_help.c:1829 sql_help.c:1830 sql_help.c:1831 +#: sql_help.c:1832 sql_help.c:1833 sql_help.c:1834 sql_help.c:1835 +#: sql_help.c:1836 sql_help.c:1837 sql_help.c:1838 sql_help.c:1839 +#: sql_help.c:1844 sql_help.c:1845 sql_help.c:4189 sql_help.c:4194 +#: sql_help.c:4195 sql_help.c:4196 sql_help.c:4197 sql_help.c:4203 +#: sql_help.c:4204 sql_help.c:4209 sql_help.c:4210 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4217 sql_help.c:4218 sql_help.c:4219 +#: sql_help.c:4220 +msgid "object_name" +msgstr "objektnamn" + +#: sql_help.c:326 sql_help.c:1782 sql_help.c:4192 +msgid "aggregate_name" +msgstr "aggregatnamn" + +#: sql_help.c:328 sql_help.c:1784 sql_help.c:2068 sql_help.c:2072 +#: sql_help.c:2074 sql_help.c:3231 +msgid "source_type" +msgstr "källtyp" + +#: sql_help.c:329 sql_help.c:1785 sql_help.c:2069 sql_help.c:2073 +#: sql_help.c:2075 sql_help.c:3232 +msgid "target_type" +msgstr "måltyp" + +#: sql_help.c:336 sql_help.c:774 sql_help.c:1800 sql_help.c:2070 +#: sql_help.c:2111 sql_help.c:2176 sql_help.c:2426 sql_help.c:2457 +#: sql_help.c:2995 sql_help.c:4100 sql_help.c:4198 sql_help.c:4311 +#: sql_help.c:4315 sql_help.c:4319 sql_help.c:4322 sql_help.c:4550 +#: sql_help.c:4554 sql_help.c:4558 sql_help.c:4561 sql_help.c:4770 +#: sql_help.c:4774 sql_help.c:4778 sql_help.c:4781 +msgid "function_name" +msgstr "funktionsnamn" + +#: sql_help.c:341 sql_help.c:767 sql_help.c:1807 sql_help.c:2450 +msgid "operator_name" +msgstr "operatornamn" + +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1808 +#: sql_help.c:2427 sql_help.c:3355 +msgid "left_type" +msgstr "vänster_typ" + +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1809 +#: sql_help.c:2428 sql_help.c:3356 +msgid "right_type" +msgstr "höger_typ" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1359 sql_help.c:1811 sql_help.c:1813 sql_help.c:2447 +#: sql_help.c:2468 sql_help.c:2831 sql_help.c:3365 sql_help.c:3374 +msgid "index_method" +msgstr "indexmetod" + +#: sql_help.c:349 sql_help.c:1817 sql_help.c:4205 +msgid "procedure_name" +msgstr "procedurnamn" + +#: sql_help.c:353 sql_help.c:1823 sql_help.c:3752 sql_help.c:4211 +msgid "routine_name" +msgstr "rutinnamn" + +#: sql_help.c:365 sql_help.c:1331 sql_help.c:1840 sql_help.c:2304 +#: sql_help.c:2507 sql_help.c:2786 sql_help.c:2962 sql_help.c:3536 +#: sql_help.c:3766 sql_help.c:4114 +msgid "type_name" +msgstr "typnamn" + +#: sql_help.c:366 sql_help.c:1841 sql_help.c:2303 sql_help.c:2506 +#: sql_help.c:2963 sql_help.c:3189 sql_help.c:3537 sql_help.c:3758 +#: sql_help.c:4106 +msgid "lang_name" +msgstr "språknamn" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "och aggregatsignatur är:" + +#: sql_help.c:392 sql_help.c:1935 sql_help.c:2201 +msgid "handler_function" +msgstr "hanterarfunktion" + +#: sql_help.c:393 sql_help.c:2202 +msgid "validator_function" +msgstr "valideringsfunktion" + +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1263 sql_help.c:1529 +msgid "action" +msgstr "aktion" + +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1265 +#: sql_help.c:1283 sql_help.c:1287 sql_help.c:1288 sql_help.c:1292 +#: sql_help.c:1294 sql_help.c:1295 sql_help.c:1296 sql_help.c:1297 +#: sql_help.c:1299 sql_help.c:1302 sql_help.c:1303 sql_help.c:1305 +#: sql_help.c:1308 sql_help.c:1310 sql_help.c:1355 sql_help.c:1357 +#: sql_help.c:1364 sql_help.c:1373 sql_help.c:1378 sql_help.c:1630 +#: sql_help.c:1633 sql_help.c:1637 sql_help.c:1673 sql_help.c:1788 +#: sql_help.c:1901 sql_help.c:1907 sql_help.c:1920 sql_help.c:1921 +#: sql_help.c:1922 sql_help.c:2243 sql_help.c:2256 sql_help.c:2301 +#: sql_help.c:2367 sql_help.c:2373 sql_help.c:2406 sql_help.c:2633 +#: sql_help.c:2661 sql_help.c:2662 sql_help.c:2769 sql_help.c:2777 +#: sql_help.c:2787 sql_help.c:2790 sql_help.c:2800 sql_help.c:2804 +#: sql_help.c:2827 sql_help.c:2829 sql_help.c:2836 sql_help.c:2849 +#: sql_help.c:2854 sql_help.c:2872 sql_help.c:2998 sql_help.c:3134 +#: sql_help.c:3737 sql_help.c:3738 sql_help.c:3819 sql_help.c:3834 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:4085 sql_help.c:4086 +#: sql_help.c:4191 sql_help.c:4342 sql_help.c:4581 sql_help.c:4623 +#: sql_help.c:4625 sql_help.c:4627 sql_help.c:4673 sql_help.c:4801 +msgid "column_name" +msgstr "kolumnnamn" + +#: sql_help.c:444 sql_help.c:664 sql_help.c:1266 sql_help.c:1638 +msgid "new_column_name" +msgstr "nytt_kolumnnamn" + +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1282 sql_help.c:1539 +msgid "where action is one of:" +msgstr "där aktion är en av:" + +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1284 +#: sql_help.c:1289 sql_help.c:1541 sql_help.c:1545 sql_help.c:2156 +#: sql_help.c:2244 sql_help.c:2446 sql_help.c:2626 sql_help.c:2770 +#: sql_help.c:3043 sql_help.c:3921 +msgid "data_type" +msgstr "datatyp" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1285 sql_help.c:1290 +#: sql_help.c:1542 sql_help.c:1546 sql_help.c:2157 sql_help.c:2247 +#: sql_help.c:2369 sql_help.c:2771 sql_help.c:2779 sql_help.c:2792 +#: sql_help.c:2806 sql_help.c:3044 sql_help.c:3050 sql_help.c:3829 +msgid "collation" +msgstr "jämförelse" + +#: sql_help.c:453 sql_help.c:1286 sql_help.c:2248 sql_help.c:2257 +#: sql_help.c:2772 sql_help.c:2788 sql_help.c:2801 +msgid "column_constraint" +msgstr "kolumnvillkor" + +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1304 sql_help.c:4670 +msgid "integer" +msgstr "heltal" + +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1306 +#: sql_help.c:1309 +msgid "attribute_option" +msgstr "attributalternativ" + +#: sql_help.c:473 sql_help.c:1311 sql_help.c:2249 sql_help.c:2258 +#: sql_help.c:2773 sql_help.c:2789 sql_help.c:2802 +msgid "table_constraint" +msgstr "tabellvillkor" + +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1316 +#: sql_help.c:1317 sql_help.c:1318 sql_help.c:1319 sql_help.c:1842 +msgid "trigger_name" +msgstr "utlösarnamn" + +#: sql_help.c:480 sql_help.c:481 sql_help.c:1329 sql_help.c:1330 +#: sql_help.c:2250 sql_help.c:2255 sql_help.c:2776 sql_help.c:2799 +msgid "parent_table" +msgstr "föräldertabell" + +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1498 sql_help.c:2187 +msgid "extension_name" +msgstr "utökningsnamn" + +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2305 +msgid "execution_cost" +msgstr "körkostnad" + +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2306 +msgid "result_rows" +msgstr "resultatrader" + +#: sql_help.c:543 sql_help.c:2307 +msgid "support_function" +msgstr "supportfunktion" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1580 sql_help.c:1588 +#: sql_help.c:1592 sql_help.c:1595 sql_help.c:1598 sql_help.c:2604 +#: sql_help.c:2606 sql_help.c:2609 sql_help.c:2610 sql_help.c:3736 +#: sql_help.c:3740 sql_help.c:3743 sql_help.c:3745 sql_help.c:3747 +#: sql_help.c:3749 sql_help.c:3751 sql_help.c:3757 sql_help.c:3759 +#: sql_help.c:3761 sql_help.c:3763 sql_help.c:3765 sql_help.c:3767 +#: sql_help.c:3769 sql_help.c:3770 sql_help.c:4084 sql_help.c:4088 +#: sql_help.c:4091 sql_help.c:4093 sql_help.c:4095 sql_help.c:4097 +#: sql_help.c:4099 sql_help.c:4105 sql_help.c:4107 sql_help.c:4109 +#: sql_help.c:4111 sql_help.c:4113 sql_help.c:4115 sql_help.c:4117 +#: sql_help.c:4118 +msgid "role_specification" +msgstr "rollspecifikation" + +#: sql_help.c:565 sql_help.c:567 sql_help.c:1611 sql_help.c:2130 +#: sql_help.c:2612 sql_help.c:3119 sql_help.c:3570 sql_help.c:4427 +msgid "user_name" +msgstr "användarnamn" + +#: sql_help.c:568 sql_help.c:945 sql_help.c:1600 sql_help.c:2611 +#: sql_help.c:3771 sql_help.c:4119 +msgid "where role_specification can be:" +msgstr "där rollspecifikation kan vara:" + +#: sql_help.c:570 +msgid "group_name" +msgstr "gruppnamn" + +#: sql_help.c:591 sql_help.c:1376 sql_help.c:2136 sql_help.c:2376 +#: sql_help.c:2410 sql_help.c:2784 sql_help.c:2797 sql_help.c:2811 +#: sql_help.c:2852 sql_help.c:2876 sql_help.c:2888 sql_help.c:3764 +#: sql_help.c:4112 +msgid "tablespace_name" +msgstr "tabellutrymmesnamn" + +#: sql_help.c:593 sql_help.c:681 sql_help.c:1324 sql_help.c:1333 +#: sql_help.c:1371 sql_help.c:1722 +msgid "index_name" +msgstr "indexnamn" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1326 +#: sql_help.c:1328 sql_help.c:1374 sql_help.c:2374 sql_help.c:2408 +#: sql_help.c:2782 sql_help.c:2795 sql_help.c:2809 sql_help.c:2850 +#: sql_help.c:2874 +msgid "storage_parameter" +msgstr "lagringsparameter" + +#: sql_help.c:602 +msgid "column_number" +msgstr "kolumnnummer" + +#: sql_help.c:626 sql_help.c:1805 sql_help.c:4202 +msgid "large_object_oid" +msgstr "stort_objekt_oid" + +#: sql_help.c:713 sql_help.c:2431 +msgid "res_proc" +msgstr "res_proc" + +#: sql_help.c:714 sql_help.c:2432 +msgid "join_proc" +msgstr "join_proc" + +#: sql_help.c:766 sql_help.c:778 sql_help.c:2449 +msgid "strategy_number" +msgstr "strateginummer" + +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2451 sql_help.c:2452 +#: sql_help.c:2455 sql_help.c:2456 +msgid "op_type" +msgstr "op_typ" + +#: sql_help.c:770 sql_help.c:2453 +msgid "sort_family_name" +msgstr "sorteringsfamiljnamn" + +#: sql_help.c:771 sql_help.c:781 sql_help.c:2454 +msgid "support_number" +msgstr "supportnummer" + +#: sql_help.c:775 sql_help.c:2071 sql_help.c:2458 sql_help.c:2965 +#: sql_help.c:2967 +msgid "argument_type" +msgstr "argumenttyp" + +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1494 sql_help.c:1497 +#: sql_help.c:1672 sql_help.c:1721 sql_help.c:1790 sql_help.c:1815 +#: sql_help.c:1828 sql_help.c:1843 sql_help.c:1900 sql_help.c:1906 +#: sql_help.c:2242 sql_help.c:2254 sql_help.c:2365 sql_help.c:2405 +#: sql_help.c:2482 sql_help.c:2525 sql_help.c:2581 sql_help.c:2632 +#: sql_help.c:2663 sql_help.c:2768 sql_help.c:2785 sql_help.c:2798 +#: sql_help.c:2871 sql_help.c:2991 sql_help.c:3168 sql_help.c:3391 +#: sql_help.c:3440 sql_help.c:3546 sql_help.c:3734 sql_help.c:3739 +#: sql_help.c:3785 sql_help.c:3817 sql_help.c:4082 sql_help.c:4087 +#: sql_help.c:4190 sql_help.c:4297 sql_help.c:4299 sql_help.c:4348 +#: sql_help.c:4387 sql_help.c:4536 sql_help.c:4538 sql_help.c:4587 +#: sql_help.c:4621 sql_help.c:4672 sql_help.c:4756 sql_help.c:4758 +#: sql_help.c:4807 +msgid "table_name" +msgstr "tabellnamn" + +#: sql_help.c:811 sql_help.c:2484 +msgid "using_expression" +msgstr "using-uttryck" + +#: sql_help.c:812 sql_help.c:2485 +msgid "check_expression" +msgstr "check-uttryck" + +#: sql_help.c:886 sql_help.c:2526 +msgid "publication_parameter" +msgstr "publiceringsparameter" + +#: sql_help.c:929 sql_help.c:1584 sql_help.c:2344 sql_help.c:2558 +#: sql_help.c:3102 +msgid "password" +msgstr "lösenord" + +#: sql_help.c:930 sql_help.c:1585 sql_help.c:2345 sql_help.c:2559 +#: sql_help.c:3103 +msgid "timestamp" +msgstr "tidsstämpel" + +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1589 +#: sql_help.c:1593 sql_help.c:1596 sql_help.c:1599 sql_help.c:3744 +#: sql_help.c:4092 +msgid "database_name" +msgstr "databasnamn" + +#: sql_help.c:1048 sql_help.c:2627 +msgid "increment" +msgstr "ökningsvärde" + +#: sql_help.c:1049 sql_help.c:2628 +msgid "minvalue" +msgstr "minvärde" + +#: sql_help.c:1050 sql_help.c:2629 +msgid "maxvalue" +msgstr "maxvärde" + +#: sql_help.c:1051 sql_help.c:2630 sql_help.c:4295 sql_help.c:4385 +#: sql_help.c:4534 sql_help.c:4689 sql_help.c:4754 +msgid "start" +msgstr "start" + +#: sql_help.c:1052 sql_help.c:1301 +msgid "restart" +msgstr "starta om" + +#: sql_help.c:1053 sql_help.c:2631 +msgid "cache" +msgstr "cache" + +#: sql_help.c:1097 +msgid "new_target" +msgstr "nytt_mål" + +#: sql_help.c:1113 sql_help.c:2675 +msgid "conninfo" +msgstr "anslinfo" + +#: sql_help.c:1115 sql_help.c:2676 +msgid "publication_name" +msgstr "publiceringsnamn" + +#: sql_help.c:1116 +msgid "set_publication_option" +msgstr "sätt_publicerings_alternativ" + +#: sql_help.c:1119 +msgid "refresh_option" +msgstr "refresh_alternativ" + +#: sql_help.c:1124 sql_help.c:2677 +msgid "subscription_parameter" +msgstr "prenumerationsparameter" + +#: sql_help.c:1278 sql_help.c:1281 +msgid "partition_name" +msgstr "partitionsnamn" + +#: sql_help.c:1279 sql_help.c:2259 sql_help.c:2803 +msgid "partition_bound_spec" +msgstr "partitionsgränsspec" + +#: sql_help.c:1298 sql_help.c:1345 sql_help.c:2817 +msgid "sequence_options" +msgstr "sekvensalternativ" + +#: sql_help.c:1300 +msgid "sequence_option" +msgstr "sekvensalternativ" + +#: sql_help.c:1312 +msgid "table_constraint_using_index" +msgstr "tabellvillkor_för_index" + +#: sql_help.c:1320 sql_help.c:1321 sql_help.c:1322 sql_help.c:1323 +msgid "rewrite_rule_name" +msgstr "omskrivningsregelnamn" + +#: sql_help.c:1334 sql_help.c:2842 +msgid "and partition_bound_spec is:" +msgstr "och partitionsgränsspec är:" + +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:2843 +#: sql_help.c:2844 sql_help.c:2845 +msgid "partition_bound_expr" +msgstr "partitionsgränsuttryck" + +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:2846 sql_help.c:2847 +msgid "numeric_literal" +msgstr "numerisk_literal" + +#: sql_help.c:1340 +msgid "and column_constraint is:" +msgstr "och kolumnvillkor är:" + +#: sql_help.c:1343 sql_help.c:2266 sql_help.c:2299 sql_help.c:2505 +#: sql_help.c:2815 +msgid "default_expr" +msgstr "default_uttryck" + +#: sql_help.c:1344 sql_help.c:2267 sql_help.c:2816 +msgid "generation_expr" +msgstr "generatoruttryck" + +#: sql_help.c:1346 sql_help.c:1347 sql_help.c:1356 sql_help.c:1358 +#: sql_help.c:1362 sql_help.c:2818 sql_help.c:2819 sql_help.c:2828 +#: sql_help.c:2830 sql_help.c:2834 +msgid "index_parameters" +msgstr "indexparametrar" + +#: sql_help.c:1348 sql_help.c:1365 sql_help.c:2820 sql_help.c:2837 +msgid "reftable" +msgstr "reftabell" + +#: sql_help.c:1349 sql_help.c:1366 sql_help.c:2821 sql_help.c:2838 +msgid "refcolumn" +msgstr "refkolumn" + +#: sql_help.c:1350 sql_help.c:1351 sql_help.c:1367 sql_help.c:1368 +#: sql_help.c:2822 sql_help.c:2823 sql_help.c:2839 sql_help.c:2840 +msgid "referential_action" +msgstr "referentiell_aktion" + +#: sql_help.c:1352 sql_help.c:2268 sql_help.c:2824 +msgid "and table_constraint is:" +msgstr "och tabellvillkor är:" + +#: sql_help.c:1360 sql_help.c:2832 +msgid "exclude_element" +msgstr "uteslutelement" + +#: sql_help.c:1361 sql_help.c:2833 sql_help.c:4293 sql_help.c:4383 +#: sql_help.c:4532 sql_help.c:4687 sql_help.c:4752 +msgid "operator" +msgstr "operator" + +#: sql_help.c:1363 sql_help.c:2377 sql_help.c:2835 +msgid "predicate" +msgstr "predikat" + +#: sql_help.c:1369 +msgid "and table_constraint_using_index is:" +msgstr "och tabellvillkor_för_index är:" + +#: sql_help.c:1372 sql_help.c:2848 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "indexparametrar i UNIQUE-, PRIMARY KEY- och EXCLUDE-villkor är:" + +#: sql_help.c:1377 sql_help.c:2853 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "uteslutelement i ett EXCLUDE-villkort är:" + +#: sql_help.c:1380 sql_help.c:2370 sql_help.c:2780 sql_help.c:2793 +#: sql_help.c:2807 sql_help.c:2856 sql_help.c:3830 +msgid "opclass" +msgstr "op-klass" + +#: sql_help.c:1396 sql_help.c:1399 sql_help.c:2891 +msgid "tablespace_option" +msgstr "tabellutrymmesalternativ" + +#: sql_help.c:1420 sql_help.c:1423 sql_help.c:1429 sql_help.c:1433 +msgid "token_type" +msgstr "symboltyp" + +#: sql_help.c:1421 sql_help.c:1424 +msgid "dictionary_name" +msgstr "ordlistnamn" + +#: sql_help.c:1426 sql_help.c:1430 +msgid "old_dictionary" +msgstr "gammal_ordlista" + +#: sql_help.c:1427 sql_help.c:1431 +msgid "new_dictionary" +msgstr "ny_ordlista" + +#: sql_help.c:1526 sql_help.c:1540 sql_help.c:1543 sql_help.c:1544 +#: sql_help.c:3042 +msgid "attribute_name" +msgstr "attributnamn" + +#: sql_help.c:1527 +msgid "new_attribute_name" +msgstr "nytt_attributnamn" + +#: sql_help.c:1531 sql_help.c:1535 +msgid "new_enum_value" +msgstr "nytt_enumvärde" + +#: sql_help.c:1532 +msgid "neighbor_enum_value" +msgstr "närliggande_enumvärde" + +#: sql_help.c:1534 +msgid "existing_enum_value" +msgstr "existerande_enumvärde" + +#: sql_help.c:1537 +msgid "property" +msgstr "egenskap" + +#: sql_help.c:1612 sql_help.c:2251 sql_help.c:2260 sql_help.c:2643 +#: sql_help.c:3120 sql_help.c:3571 sql_help.c:3750 sql_help.c:3786 +#: sql_help.c:4098 +msgid "server_name" +msgstr "servernamn" + +#: sql_help.c:1644 sql_help.c:1647 sql_help.c:3135 +msgid "view_option_name" +msgstr "visningsalternativnamn" + +#: sql_help.c:1645 sql_help.c:3136 +msgid "view_option_value" +msgstr "visningsalternativvärde" + +#: sql_help.c:1666 sql_help.c:1667 sql_help.c:4659 sql_help.c:4660 +msgid "table_and_columns" +msgstr "tabell_och_kolumner" + +#: sql_help.c:1668 sql_help.c:1912 sql_help.c:3619 sql_help.c:3963 +#: sql_help.c:4661 +msgid "where option can be one of:" +msgstr "där flaggor kan vara en av:" + +#: sql_help.c:1669 sql_help.c:1670 sql_help.c:1914 sql_help.c:1917 +#: sql_help.c:2096 sql_help.c:3620 sql_help.c:3621 sql_help.c:3622 +#: sql_help.c:3623 sql_help.c:3624 sql_help.c:3625 sql_help.c:3626 +#: sql_help.c:3627 sql_help.c:4662 sql_help.c:4663 sql_help.c:4664 +#: sql_help.c:4665 sql_help.c:4666 sql_help.c:4667 sql_help.c:4668 +#: sql_help.c:4669 +msgid "boolean" +msgstr "boolean" + +#: sql_help.c:1671 sql_help.c:4671 +msgid "and table_and_columns is:" +msgstr "och tabell_och_kolumner är:" + +#: sql_help.c:1687 sql_help.c:4443 sql_help.c:4445 sql_help.c:4469 +msgid "transaction_mode" +msgstr "transaktionsläge" + +#: sql_help.c:1688 sql_help.c:4446 sql_help.c:4470 +msgid "where transaction_mode is one of:" +msgstr "där transaktionsläge är en av:" + +#: sql_help.c:1697 sql_help.c:4303 sql_help.c:4312 sql_help.c:4316 +#: sql_help.c:4320 sql_help.c:4323 sql_help.c:4542 sql_help.c:4551 +#: sql_help.c:4555 sql_help.c:4559 sql_help.c:4562 sql_help.c:4762 +#: sql_help.c:4771 sql_help.c:4775 sql_help.c:4779 sql_help.c:4782 +msgid "argument" +msgstr "argument" + +#: sql_help.c:1787 +msgid "relation_name" +msgstr "relationsnamn" + +#: sql_help.c:1792 sql_help.c:3746 sql_help.c:4094 +msgid "domain_name" +msgstr "domännamn" + +#: sql_help.c:1814 +msgid "policy_name" +msgstr "policynamn" + +#: sql_help.c:1827 +msgid "rule_name" +msgstr "regelnamn" + +#: sql_help.c:1846 +msgid "text" +msgstr "text" + +#: sql_help.c:1871 sql_help.c:3930 sql_help.c:4135 +msgid "transaction_id" +msgstr "transaktions-id" + +#: sql_help.c:1902 sql_help.c:1909 sql_help.c:3856 +msgid "filename" +msgstr "filnamn" + +#: sql_help.c:1903 sql_help.c:1910 sql_help.c:2583 sql_help.c:2584 +#: sql_help.c:2585 +msgid "command" +msgstr "kommando" + +#: sql_help.c:1905 sql_help.c:2582 sql_help.c:2994 sql_help.c:3171 +#: sql_help.c:3840 sql_help.c:4286 sql_help.c:4288 sql_help.c:4376 +#: sql_help.c:4378 sql_help.c:4525 sql_help.c:4527 sql_help.c:4630 +#: sql_help.c:4745 sql_help.c:4747 +msgid "condition" +msgstr "villkor" + +#: sql_help.c:1908 sql_help.c:2411 sql_help.c:2877 sql_help.c:3137 +#: sql_help.c:3155 sql_help.c:3821 +msgid "query" +msgstr "fråga" + +#: sql_help.c:1913 +msgid "format_name" +msgstr "formatnamn" + +#: sql_help.c:1915 +msgid "delimiter_character" +msgstr "avdelartecken" + +#: sql_help.c:1916 +msgid "null_string" +msgstr "null-sträng" + +#: sql_help.c:1918 +msgid "quote_character" +msgstr "citattecken" + +#: sql_help.c:1919 +msgid "escape_character" +msgstr "escape-tecken" + +#: sql_help.c:1923 +msgid "encoding_name" +msgstr "kodningsnamn" + +#: sql_help.c:1934 +msgid "access_method_type" +msgstr "accessmetodtyp" + +#: sql_help.c:2005 sql_help.c:2024 sql_help.c:2027 +msgid "arg_data_type" +msgstr "arg_datatyp" + +#: sql_help.c:2006 sql_help.c:2028 sql_help.c:2036 +msgid "sfunc" +msgstr "sfunc" + +#: sql_help.c:2007 sql_help.c:2029 sql_help.c:2037 +msgid "state_data_type" +msgstr "tillståndsdatatyp" + +#: sql_help.c:2008 sql_help.c:2030 sql_help.c:2038 +msgid "state_data_size" +msgstr "tillståndsdatastorlek" + +#: sql_help.c:2009 sql_help.c:2031 sql_help.c:2039 +msgid "ffunc" +msgstr "ffunc" + +#: sql_help.c:2010 sql_help.c:2040 +msgid "combinefunc" +msgstr "kombinerafunk" + +#: sql_help.c:2011 sql_help.c:2041 +msgid "serialfunc" +msgstr "serialiseringsfunk" + +#: sql_help.c:2012 sql_help.c:2042 +msgid "deserialfunc" +msgstr "deserialiseringsfunk" + +#: sql_help.c:2013 sql_help.c:2032 sql_help.c:2043 +msgid "initial_condition" +msgstr "startvärde" + +#: sql_help.c:2014 sql_help.c:2044 +msgid "msfunc" +msgstr "msfunk" + +#: sql_help.c:2015 sql_help.c:2045 +msgid "minvfunc" +msgstr "minvfunk" + +#: sql_help.c:2016 sql_help.c:2046 +msgid "mstate_data_type" +msgstr "mtillståndsdatatyp" + +#: sql_help.c:2017 sql_help.c:2047 +msgid "mstate_data_size" +msgstr "ntillståndsstorlek" + +#: sql_help.c:2018 sql_help.c:2048 +msgid "mffunc" +msgstr "mffunk" + +#: sql_help.c:2019 sql_help.c:2049 +msgid "minitial_condition" +msgstr "mstartvärde" + +#: sql_help.c:2020 sql_help.c:2050 +msgid "sort_operator" +msgstr "sorteringsoperator" + +#: sql_help.c:2033 +msgid "or the old syntax" +msgstr "eller gamla syntaxen" + +#: sql_help.c:2035 +msgid "base_type" +msgstr "bastyp" + +#: sql_help.c:2092 sql_help.c:2133 +msgid "locale" +msgstr "lokal" + +#: sql_help.c:2093 sql_help.c:2134 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2094 sql_help.c:2135 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2095 sql_help.c:4188 +msgid "provider" +msgstr "leverantör" + +#: sql_help.c:2097 sql_help.c:2189 +msgid "version" +msgstr "version" + +#: sql_help.c:2099 +msgid "existing_collation" +msgstr "existerande_jämförelse" + +#: sql_help.c:2109 +msgid "source_encoding" +msgstr "källkodning" + +#: sql_help.c:2110 +msgid "dest_encoding" +msgstr "målkodning" + +#: sql_help.c:2131 sql_help.c:2917 +msgid "template" +msgstr "mall" + +#: sql_help.c:2132 +msgid "encoding" +msgstr "kodning" + +#: sql_help.c:2159 +msgid "constraint" +msgstr "villkor" + +#: sql_help.c:2160 +msgid "where constraint is:" +msgstr "där villkor är:" + +#: sql_help.c:2174 sql_help.c:2580 sql_help.c:2990 +msgid "event" +msgstr "händelse" + +#: sql_help.c:2175 +msgid "filter_variable" +msgstr "filtervariabel" + +#: sql_help.c:2263 sql_help.c:2812 +msgid "where column_constraint is:" +msgstr "där kolumnvillkor är:" + +#: sql_help.c:2300 +msgid "rettype" +msgstr "rettyp" + +#: sql_help.c:2302 +msgid "column_type" +msgstr "kolumntyp" + +#: sql_help.c:2311 sql_help.c:2511 +msgid "definition" +msgstr "definition" + +#: sql_help.c:2312 sql_help.c:2512 +msgid "obj_file" +msgstr "obj-fil" + +#: sql_help.c:2313 sql_help.c:2513 +msgid "link_symbol" +msgstr "linksymbol" + +#: sql_help.c:2351 sql_help.c:2565 sql_help.c:3109 +msgid "uid" +msgstr "uid" + +#: sql_help.c:2366 sql_help.c:2407 sql_help.c:2781 sql_help.c:2794 +#: sql_help.c:2808 sql_help.c:2873 +msgid "method" +msgstr "metod" + +#: sql_help.c:2371 +msgid "opclass_parameter" +msgstr "opclass_parameter" + +#: sql_help.c:2388 +msgid "call_handler" +msgstr "anropshanterare" + +#: sql_help.c:2389 +msgid "inline_handler" +msgstr "inline-hanterare" + +#: sql_help.c:2390 +msgid "valfunction" +msgstr "val-funktion" + +#: sql_help.c:2429 +msgid "com_op" +msgstr "com_op" + +#: sql_help.c:2430 +msgid "neg_op" +msgstr "neg_op" + +#: sql_help.c:2448 +msgid "family_name" +msgstr "familjenamn" + +#: sql_help.c:2459 +msgid "storage_type" +msgstr "lagringstyp" + +#: sql_help.c:2586 sql_help.c:2997 +msgid "where event can be one of:" +msgstr "där händelse kan vara en av:" + +#: sql_help.c:2605 sql_help.c:2607 +msgid "schema_element" +msgstr "schema-element" + +#: sql_help.c:2644 +msgid "server_type" +msgstr "servertyp" + +#: sql_help.c:2645 +msgid "server_version" +msgstr "serverversion" + +#: sql_help.c:2646 sql_help.c:3748 sql_help.c:4096 +msgid "fdw_name" +msgstr "fdw-namn" + +#: sql_help.c:2659 +msgid "statistics_name" +msgstr "statistiknamn" + +#: sql_help.c:2660 +msgid "statistics_kind" +msgstr "statistiksort" + +#: sql_help.c:2674 +msgid "subscription_name" +msgstr "prenumerationsnamn" + +#: sql_help.c:2774 +msgid "source_table" +msgstr "källtabell" + +#: sql_help.c:2775 +msgid "like_option" +msgstr "like_alternativ" + +#: sql_help.c:2841 +msgid "and like_option is:" +msgstr "och likealternativ är:" + +#: sql_help.c:2890 +msgid "directory" +msgstr "katalog" + +#: sql_help.c:2904 +msgid "parser_name" +msgstr "parsernamn" + +#: sql_help.c:2905 +msgid "source_config" +msgstr "källkonfig" + +#: sql_help.c:2934 +msgid "start_function" +msgstr "startfunktion" + +#: sql_help.c:2935 +msgid "gettoken_function" +msgstr "gettoken_funktion" + +#: sql_help.c:2936 +msgid "end_function" +msgstr "slutfunktion" + +#: sql_help.c:2937 +msgid "lextypes_function" +msgstr "symboltypfunktion" + +#: sql_help.c:2938 +msgid "headline_function" +msgstr "rubrikfunktion" + +#: sql_help.c:2950 +msgid "init_function" +msgstr "init_funktion" + +#: sql_help.c:2951 +msgid "lexize_function" +msgstr "symboluppdelningsfunktion" + +#: sql_help.c:2964 +msgid "from_sql_function_name" +msgstr "från_sql_funktionsnamn" + +#: sql_help.c:2966 +msgid "to_sql_function_name" +msgstr "till_sql_funktionsnamn" + +#: sql_help.c:2992 +msgid "referenced_table_name" +msgstr "refererat_tabellnamn" + +#: sql_help.c:2993 +msgid "transition_relation_name" +msgstr "övergångsrelationsnamn" + +#: sql_help.c:2996 +msgid "arguments" +msgstr "argument" + +#: sql_help.c:3046 sql_help.c:4221 +msgid "label" +msgstr "etikett" + +#: sql_help.c:3048 +msgid "subtype" +msgstr "subtyp" + +#: sql_help.c:3049 +msgid "subtype_operator_class" +msgstr "subtypoperatorklass" + +#: sql_help.c:3051 +msgid "canonical_function" +msgstr "kanonisk_funktion" + +#: sql_help.c:3052 +msgid "subtype_diff_function" +msgstr "subtyp_diff_funktion" + +#: sql_help.c:3054 +msgid "input_function" +msgstr "inmatningsfunktion" + +#: sql_help.c:3055 +msgid "output_function" +msgstr "utmatningsfunktion" + +#: sql_help.c:3056 +msgid "receive_function" +msgstr "mottagarfunktion" + +#: sql_help.c:3057 +msgid "send_function" +msgstr "sändfunktion" + +#: sql_help.c:3058 +msgid "type_modifier_input_function" +msgstr "typmodifiering_indatafunktion" + +#: sql_help.c:3059 +msgid "type_modifier_output_function" +msgstr "typmodifiering_utdatafunktion" + +#: sql_help.c:3060 +msgid "analyze_function" +msgstr "analysfunktion" + +#: sql_help.c:3061 +msgid "internallength" +msgstr "internlängd" + +#: sql_help.c:3062 +msgid "alignment" +msgstr "justering" + +#: sql_help.c:3063 +msgid "storage" +msgstr "lagring" + +#: sql_help.c:3064 +msgid "like_type" +msgstr "liketyp" + +#: sql_help.c:3065 +msgid "category" +msgstr "kategori" + +#: sql_help.c:3066 +msgid "preferred" +msgstr "föredragen" + +#: sql_help.c:3067 +msgid "default" +msgstr "standard" + +#: sql_help.c:3068 +msgid "element" +msgstr "element" + +#: sql_help.c:3069 +msgid "delimiter" +msgstr "avskiljare" + +#: sql_help.c:3070 +msgid "collatable" +msgstr "sorterbar" + +#: sql_help.c:3167 sql_help.c:3816 sql_help.c:4281 sql_help.c:4370 +#: sql_help.c:4520 sql_help.c:4620 sql_help.c:4740 +msgid "with_query" +msgstr "with_fråga" + +#: sql_help.c:3169 sql_help.c:3818 sql_help.c:4300 sql_help.c:4306 +#: sql_help.c:4309 sql_help.c:4313 sql_help.c:4317 sql_help.c:4325 +#: sql_help.c:4539 sql_help.c:4545 sql_help.c:4548 sql_help.c:4552 +#: sql_help.c:4556 sql_help.c:4564 sql_help.c:4622 sql_help.c:4759 +#: sql_help.c:4765 sql_help.c:4768 sql_help.c:4772 sql_help.c:4776 +#: sql_help.c:4784 +msgid "alias" +msgstr "alias" + +#: sql_help.c:3170 sql_help.c:4285 sql_help.c:4327 sql_help.c:4329 +#: sql_help.c:4375 sql_help.c:4524 sql_help.c:4566 sql_help.c:4568 +#: sql_help.c:4629 sql_help.c:4744 sql_help.c:4786 sql_help.c:4788 +msgid "from_item" +msgstr "frånval" + +#: sql_help.c:3172 sql_help.c:3653 sql_help.c:3897 sql_help.c:4631 +msgid "cursor_name" +msgstr "markörnamn" + +#: sql_help.c:3173 sql_help.c:3824 sql_help.c:4632 +msgid "output_expression" +msgstr "utdatauttryck" + +#: sql_help.c:3174 sql_help.c:3825 sql_help.c:4284 sql_help.c:4373 +#: sql_help.c:4523 sql_help.c:4633 sql_help.c:4743 +msgid "output_name" +msgstr "utdatanamn" + +#: sql_help.c:3190 +msgid "code" +msgstr "kod" + +#: sql_help.c:3595 +msgid "parameter" +msgstr "parameter" + +#: sql_help.c:3617 sql_help.c:3618 sql_help.c:3922 +msgid "statement" +msgstr "sats" + +#: sql_help.c:3652 sql_help.c:3896 +msgid "direction" +msgstr "riktning" + +#: sql_help.c:3654 sql_help.c:3898 +msgid "where direction can be empty or one of:" +msgstr "där riktning kan vara tom eller en av:" + +#: sql_help.c:3655 sql_help.c:3656 sql_help.c:3657 sql_help.c:3658 +#: sql_help.c:3659 sql_help.c:3899 sql_help.c:3900 sql_help.c:3901 +#: sql_help.c:3902 sql_help.c:3903 sql_help.c:4294 sql_help.c:4296 +#: sql_help.c:4384 sql_help.c:4386 sql_help.c:4533 sql_help.c:4535 +#: sql_help.c:4688 sql_help.c:4690 sql_help.c:4753 sql_help.c:4755 +msgid "count" +msgstr "antal" + +#: sql_help.c:3741 sql_help.c:4089 +msgid "sequence_name" +msgstr "sekvensnamn" + +#: sql_help.c:3754 sql_help.c:4102 +msgid "arg_name" +msgstr "arg_namn" + +#: sql_help.c:3755 sql_help.c:4103 +msgid "arg_type" +msgstr "arg_typ" + +#: sql_help.c:3760 sql_help.c:4108 +msgid "loid" +msgstr "loid" + +#: sql_help.c:3784 +msgid "remote_schema" +msgstr "externt_schema" + +#: sql_help.c:3787 +msgid "local_schema" +msgstr "lokalt_schema" + +#: sql_help.c:3822 +msgid "conflict_target" +msgstr "konfliktmål" + +#: sql_help.c:3823 +msgid "conflict_action" +msgstr "konfliktaktion" + +#: sql_help.c:3826 +msgid "where conflict_target can be one of:" +msgstr "där konfliktmål kan vara en av:" + +#: sql_help.c:3827 +msgid "index_column_name" +msgstr "indexkolumnnamn" + +#: sql_help.c:3828 +msgid "index_expression" +msgstr "indexuttryck" + +#: sql_help.c:3831 +msgid "index_predicate" +msgstr "indexpredikat" + +#: sql_help.c:3833 +msgid "and conflict_action is one of:" +msgstr "och konfliktaktion är en av:" + +#: sql_help.c:3839 sql_help.c:4628 +msgid "sub-SELECT" +msgstr "sub-SELECT" + +#: sql_help.c:3848 sql_help.c:3911 sql_help.c:4604 +msgid "channel" +msgstr "kanal" + +#: sql_help.c:3870 +msgid "lockmode" +msgstr "låsläge" + +#: sql_help.c:3871 +msgid "where lockmode is one of:" +msgstr "där låsläge är en av:" + +#: sql_help.c:3912 +msgid "payload" +msgstr "innehåll" + +#: sql_help.c:3939 +msgid "old_role" +msgstr "gammal_roll" + +#: sql_help.c:3940 +msgid "new_role" +msgstr "ny_roll" + +#: sql_help.c:3971 sql_help.c:4143 sql_help.c:4151 +msgid "savepoint_name" +msgstr "sparpunktnamn" + +#: sql_help.c:4287 sql_help.c:4339 sql_help.c:4526 sql_help.c:4578 +#: sql_help.c:4746 sql_help.c:4798 +msgid "grouping_element" +msgstr "gruperingselement" + +#: sql_help.c:4289 sql_help.c:4379 sql_help.c:4528 sql_help.c:4748 +msgid "window_name" +msgstr "fönsternamn" + +#: sql_help.c:4290 sql_help.c:4380 sql_help.c:4529 sql_help.c:4749 +msgid "window_definition" +msgstr "fönsterdefinition" + +#: sql_help.c:4291 sql_help.c:4305 sql_help.c:4343 sql_help.c:4381 +#: sql_help.c:4530 sql_help.c:4544 sql_help.c:4582 sql_help.c:4750 +#: sql_help.c:4764 sql_help.c:4802 +msgid "select" +msgstr "select" + +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4757 +msgid "where from_item can be one of:" +msgstr "där frånval kan vara en av:" + +#: sql_help.c:4301 sql_help.c:4307 sql_help.c:4310 sql_help.c:4314 +#: sql_help.c:4326 sql_help.c:4540 sql_help.c:4546 sql_help.c:4549 +#: sql_help.c:4553 sql_help.c:4565 sql_help.c:4760 sql_help.c:4766 +#: sql_help.c:4769 sql_help.c:4773 sql_help.c:4785 +msgid "column_alias" +msgstr "kolumnalias" + +#: sql_help.c:4302 sql_help.c:4541 sql_help.c:4761 +msgid "sampling_method" +msgstr "samplingsmetod" + +#: sql_help.c:4304 sql_help.c:4543 sql_help.c:4763 +msgid "seed" +msgstr "frö" + +#: sql_help.c:4308 sql_help.c:4341 sql_help.c:4547 sql_help.c:4580 +#: sql_help.c:4767 sql_help.c:4800 +msgid "with_query_name" +msgstr "with_frågenamn" + +#: sql_help.c:4318 sql_help.c:4321 sql_help.c:4324 sql_help.c:4557 +#: sql_help.c:4560 sql_help.c:4563 sql_help.c:4777 sql_help.c:4780 +#: sql_help.c:4783 +msgid "column_definition" +msgstr "kolumndefinition" + +#: sql_help.c:4328 sql_help.c:4567 sql_help.c:4787 +msgid "join_type" +msgstr "join-typ" + +#: sql_help.c:4330 sql_help.c:4569 sql_help.c:4789 +msgid "join_condition" +msgstr "join-villkor" + +#: sql_help.c:4331 sql_help.c:4570 sql_help.c:4790 +msgid "join_column" +msgstr "join-kolumn" + +#: sql_help.c:4332 sql_help.c:4571 sql_help.c:4791 +msgid "and grouping_element can be one of:" +msgstr "och grupperingselement kan vara en av:" + +#: sql_help.c:4340 sql_help.c:4579 sql_help.c:4799 +msgid "and with_query is:" +msgstr "och with_fråga är:" + +#: sql_help.c:4344 sql_help.c:4583 sql_help.c:4803 +msgid "values" +msgstr "värden" + +#: sql_help.c:4345 sql_help.c:4584 sql_help.c:4804 +msgid "insert" +msgstr "insert" + +#: sql_help.c:4346 sql_help.c:4585 sql_help.c:4805 +msgid "update" +msgstr "update" + +#: sql_help.c:4347 sql_help.c:4586 sql_help.c:4806 +msgid "delete" +msgstr "delete" + +#: sql_help.c:4374 +msgid "new_table" +msgstr "ny_tabell" + +#: sql_help.c:4399 +msgid "timezone" +msgstr "tidszon" + +#: sql_help.c:4444 +msgid "snapshot_id" +msgstr "snapshot_id" + +#: sql_help.c:4686 +msgid "sort_expression" +msgstr "sorteringsuttryck" + +#: sql_help.c:4813 sql_help.c:5791 +msgid "abort the current transaction" +msgstr "avbryt aktuell transaktion" + +#: sql_help.c:4819 +msgid "change the definition of an aggregate function" +msgstr "ändra definitionen av en aggregatfunktion" + +#: sql_help.c:4825 +msgid "change the definition of a collation" +msgstr "ändra definitionen av en jämförelse" + +#: sql_help.c:4831 +msgid "change the definition of a conversion" +msgstr "ändra definitionen av en konvertering" + +#: sql_help.c:4837 +msgid "change a database" +msgstr "ändra en databas" + +#: sql_help.c:4843 +msgid "define default access privileges" +msgstr "definiera standardaccessrättigheter" + +#: sql_help.c:4849 +msgid "change the definition of a domain" +msgstr "ändra definitionen av en domän" + +#: sql_help.c:4855 +msgid "change the definition of an event trigger" +msgstr "ändra definitionen av en händelseutlösare" + +#: sql_help.c:4861 +msgid "change the definition of an extension" +msgstr "ändra definitionen av en utökning" + +#: sql_help.c:4867 +msgid "change the definition of a foreign-data wrapper" +msgstr "ändra definitionen av en främmande data-omvandlare" + +#: sql_help.c:4873 +msgid "change the definition of a foreign table" +msgstr "ändra definitionen av en främmande tabell" + +#: sql_help.c:4879 +msgid "change the definition of a function" +msgstr "ändra definitionen av en funktion" + +#: sql_help.c:4885 +msgid "change role name or membership" +msgstr "ändra rollnamn eller medlemskap" + +#: sql_help.c:4891 +msgid "change the definition of an index" +msgstr "ändra definitionen av ett index" + +#: sql_help.c:4897 +msgid "change the definition of a procedural language" +msgstr "ändra definitionen av ett procedur-språk" + +#: sql_help.c:4903 +msgid "change the definition of a large object" +msgstr "ändra definitionen av ett stort objekt" + +#: sql_help.c:4909 +msgid "change the definition of a materialized view" +msgstr "ändra definitionen av en materialiserad vy" + +#: sql_help.c:4915 +msgid "change the definition of an operator" +msgstr "ändra definitionen av en operator" + +#: sql_help.c:4921 +msgid "change the definition of an operator class" +msgstr "ändra definitionen av en operatorklass" + +#: sql_help.c:4927 +msgid "change the definition of an operator family" +msgstr "ändra definitionen av en operatorfamilj" + +#: sql_help.c:4933 +msgid "change the definition of a row level security policy" +msgstr "ändra definitionen av en säkerhetspolicy på radnivå" + +#: sql_help.c:4939 +msgid "change the definition of a procedure" +msgstr "ändra definitionen av en procedur" + +#: sql_help.c:4945 +msgid "change the definition of a publication" +msgstr "ändra definitionen av en publicering" + +#: sql_help.c:4951 sql_help.c:5053 +msgid "change a database role" +msgstr "ändra databasroll" + +#: sql_help.c:4957 +msgid "change the definition of a routine" +msgstr "ändra definitionen av en rutin" + +#: sql_help.c:4963 +msgid "change the definition of a rule" +msgstr "ändra definitionen av en regel" + +#: sql_help.c:4969 +msgid "change the definition of a schema" +msgstr "ändra definitionen av ett schema" + +#: sql_help.c:4975 +msgid "change the definition of a sequence generator" +msgstr "ändra definitionen av en sekvensgenerator" + +#: sql_help.c:4981 +msgid "change the definition of a foreign server" +msgstr "ändra definitionen av en främmande server" + +#: sql_help.c:4987 +msgid "change the definition of an extended statistics object" +msgstr "ändra definitionen av ett utökat statistikobjekt" + +#: sql_help.c:4993 +msgid "change the definition of a subscription" +msgstr "ändra definitionen av en prenumerering" + +#: sql_help.c:4999 +msgid "change a server configuration parameter" +msgstr "ändra en servers konfigurationsparameter" + +#: sql_help.c:5005 +msgid "change the definition of a table" +msgstr "ändra definitionen av en tabell" + +#: sql_help.c:5011 +msgid "change the definition of a tablespace" +msgstr "ändra definitionen av ett tabellutrymme" + +#: sql_help.c:5017 +msgid "change the definition of a text search configuration" +msgstr "ändra definitionen av en textsökkonfiguration" + +#: sql_help.c:5023 +msgid "change the definition of a text search dictionary" +msgstr "ändra definitionen av en textsökordlista" + +#: sql_help.c:5029 +msgid "change the definition of a text search parser" +msgstr "ändra definitionen av en textsökparser" + +#: sql_help.c:5035 +msgid "change the definition of a text search template" +msgstr "ändra definitionen av en textsökmall" + +#: sql_help.c:5041 +msgid "change the definition of a trigger" +msgstr "ändra definitionen av en utlösare" + +#: sql_help.c:5047 +msgid "change the definition of a type" +msgstr "ändra definitionen av en typ" + +#: sql_help.c:5059 +msgid "change the definition of a user mapping" +msgstr "ändra definitionen av en användarmappning" + +#: sql_help.c:5065 +msgid "change the definition of a view" +msgstr "ändra definitionen av en vy" + +#: sql_help.c:5071 +msgid "collect statistics about a database" +msgstr "samla in statistik om en databas" + +#: sql_help.c:5077 sql_help.c:5869 +msgid "start a transaction block" +msgstr "starta ett transaktionsblock" + +#: sql_help.c:5083 +msgid "invoke a procedure" +msgstr "anropa en procedur" + +#: sql_help.c:5089 +msgid "force a write-ahead log checkpoint" +msgstr "tvinga checkpoint i transaktionsloggen" + +#: sql_help.c:5095 +msgid "close a cursor" +msgstr "stäng en markör" + +#: sql_help.c:5101 +msgid "cluster a table according to an index" +msgstr "klustra en tabell efter ett index" + +#: sql_help.c:5107 +msgid "define or change the comment of an object" +msgstr "definiera eller ändra en kommentar på ett objekt" + +#: sql_help.c:5113 sql_help.c:5671 +msgid "commit the current transaction" +msgstr "utför den aktuella transaktionen" + +#: sql_help.c:5119 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "utför commit på en transaktion som tidigare förberetts för två-fas-commit" + +#: sql_help.c:5125 +msgid "copy data between a file and a table" +msgstr "kopiera data mellan en fil och en tabell" + +#: sql_help.c:5131 +msgid "define a new access method" +msgstr "definiera en ny accessmetod" + +#: sql_help.c:5137 +msgid "define a new aggregate function" +msgstr "definiera en ny aggregatfunktion" + +#: sql_help.c:5143 +msgid "define a new cast" +msgstr "definiera en ny typomvandling" + +#: sql_help.c:5149 +msgid "define a new collation" +msgstr "definiera en ny jämförelse" + +#: sql_help.c:5155 +msgid "define a new encoding conversion" +msgstr "definiera en ny teckenkodningskonvertering" + +#: sql_help.c:5161 +msgid "create a new database" +msgstr "skapa en ny databas" + +#: sql_help.c:5167 +msgid "define a new domain" +msgstr "definiera en ny domän" + +#: sql_help.c:5173 +msgid "define a new event trigger" +msgstr "definiera en ny händelseutlösare" + +#: sql_help.c:5179 +msgid "install an extension" +msgstr "installera en utökning" + +#: sql_help.c:5185 +msgid "define a new foreign-data wrapper" +msgstr "definiera en ny främmande data-omvandlare" + +#: sql_help.c:5191 +msgid "define a new foreign table" +msgstr "definiera en ny främmande tabell" + +#: sql_help.c:5197 +msgid "define a new function" +msgstr "definiera en ny funktion" + +#: sql_help.c:5203 sql_help.c:5263 sql_help.c:5365 +msgid "define a new database role" +msgstr "definiera en ny databasroll" + +#: sql_help.c:5209 +msgid "define a new index" +msgstr "skapa ett nytt index" + +#: sql_help.c:5215 +msgid "define a new procedural language" +msgstr "definiera ett nytt procedur-språk" + +#: sql_help.c:5221 +msgid "define a new materialized view" +msgstr "definiera en ny materialiserad vy" + +#: sql_help.c:5227 +msgid "define a new operator" +msgstr "definiera en ny operator" + +#: sql_help.c:5233 +msgid "define a new operator class" +msgstr "definiera en ny operatorklass" + +#: sql_help.c:5239 +msgid "define a new operator family" +msgstr "definiera en ny operatorfamilj" + +#: sql_help.c:5245 +msgid "define a new row level security policy for a table" +msgstr "definiera en ny säkerhetspolicy på radnivå för en tabell" + +#: sql_help.c:5251 +msgid "define a new procedure" +msgstr "definiera ett ny procedur" + +#: sql_help.c:5257 +msgid "define a new publication" +msgstr "definiera en ny publicering" + +#: sql_help.c:5269 +msgid "define a new rewrite rule" +msgstr "definiera en ny omskrivningsregel" + +#: sql_help.c:5275 +msgid "define a new schema" +msgstr "definiera ett nytt schema" + +#: sql_help.c:5281 +msgid "define a new sequence generator" +msgstr "definiera en ny sekvensgenerator" + +#: sql_help.c:5287 +msgid "define a new foreign server" +msgstr "definiera en ny främmande server" + +#: sql_help.c:5293 +msgid "define extended statistics" +msgstr "definiera utökad statistik" + +#: sql_help.c:5299 +msgid "define a new subscription" +msgstr "definiera en ny prenumeration" + +#: sql_help.c:5305 +msgid "define a new table" +msgstr "definiera en ny tabell" + +#: sql_help.c:5311 sql_help.c:5827 +msgid "define a new table from the results of a query" +msgstr "definiera en ny tabell utifrån resultatet av en fråga" + +#: sql_help.c:5317 +msgid "define a new tablespace" +msgstr "definiera ett nytt tabellutrymme" + +#: sql_help.c:5323 +msgid "define a new text search configuration" +msgstr "definiera en ny textsökkonfiguration" + +#: sql_help.c:5329 +msgid "define a new text search dictionary" +msgstr "definiera en ny textsökordlista" + +#: sql_help.c:5335 +msgid "define a new text search parser" +msgstr "definiera en ny textsökparser" + +#: sql_help.c:5341 +msgid "define a new text search template" +msgstr "definiera en ny textsökmall" + +#: sql_help.c:5347 +msgid "define a new transform" +msgstr "definiera en ny transform" + +#: sql_help.c:5353 +msgid "define a new trigger" +msgstr "definiera en ny utlösare" + +#: sql_help.c:5359 +msgid "define a new data type" +msgstr "definiera en ny datatyp" + +#: sql_help.c:5371 +msgid "define a new mapping of a user to a foreign server" +msgstr "definiera en ny mappning av en användare till en främmande server" + +#: sql_help.c:5377 +msgid "define a new view" +msgstr "definiera en ny vy" + +#: sql_help.c:5383 +msgid "deallocate a prepared statement" +msgstr "deallokera en förberedd sats" + +#: sql_help.c:5389 +msgid "define a cursor" +msgstr "definiera en markör" + +#: sql_help.c:5395 +msgid "delete rows of a table" +msgstr "radera rader i en tabell" + +#: sql_help.c:5401 +msgid "discard session state" +msgstr "släng sessionstillstånd" + +#: sql_help.c:5407 +msgid "execute an anonymous code block" +msgstr "kör ett annonymt kodblock" + +#: sql_help.c:5413 +msgid "remove an access method" +msgstr "ta bort en accessmetod" + +#: sql_help.c:5419 +msgid "remove an aggregate function" +msgstr "ta bort en aggregatfunktioner" + +#: sql_help.c:5425 +msgid "remove a cast" +msgstr "ta bort en typomvandling" + +#: sql_help.c:5431 +msgid "remove a collation" +msgstr "ta bort en jämförelse" + +#: sql_help.c:5437 +msgid "remove a conversion" +msgstr "ta bort en konvertering" + +#: sql_help.c:5443 +msgid "remove a database" +msgstr "ta bort en databas" + +#: sql_help.c:5449 +msgid "remove a domain" +msgstr "ta bort en domän" + +#: sql_help.c:5455 +msgid "remove an event trigger" +msgstr "ta bort en händelseutlösare" + +#: sql_help.c:5461 +msgid "remove an extension" +msgstr "ta bort en utökning" + +#: sql_help.c:5467 +msgid "remove a foreign-data wrapper" +msgstr "ta bort en frammande data-omvandlare" + +#: sql_help.c:5473 +msgid "remove a foreign table" +msgstr "ta bort en främmande tabell" + +#: sql_help.c:5479 +msgid "remove a function" +msgstr "ta bort en funktion" + +#: sql_help.c:5485 sql_help.c:5551 sql_help.c:5653 +msgid "remove a database role" +msgstr "ta bort en databasroll" + +#: sql_help.c:5491 +msgid "remove an index" +msgstr "ta bort ett index" + +#: sql_help.c:5497 +msgid "remove a procedural language" +msgstr "ta bort ett procedur-språk" + +#: sql_help.c:5503 +msgid "remove a materialized view" +msgstr "ta bort en materialiserad vy" + +#: sql_help.c:5509 +msgid "remove an operator" +msgstr "ta bort en operator" + +#: sql_help.c:5515 +msgid "remove an operator class" +msgstr "ta bort en operatorklass" + +#: sql_help.c:5521 +msgid "remove an operator family" +msgstr "ta bort en operatorfamilj" + +#: sql_help.c:5527 +msgid "remove database objects owned by a database role" +msgstr "ta bort databasobjekt som ägs av databasroll" + +#: sql_help.c:5533 +msgid "remove a row level security policy from a table" +msgstr "ta bort en säkerhetspolicy på radnivå från en tabell" + +#: sql_help.c:5539 +msgid "remove a procedure" +msgstr "ta bort en procedur" + +#: sql_help.c:5545 +msgid "remove a publication" +msgstr "ta bort en publicering" + +#: sql_help.c:5557 +msgid "remove a routine" +msgstr "ta bort en rutin" + +#: sql_help.c:5563 +msgid "remove a rewrite rule" +msgstr "ta bort en omskrivningsregel" + +#: sql_help.c:5569 +msgid "remove a schema" +msgstr "ta bort ett schema" + +#: sql_help.c:5575 +msgid "remove a sequence" +msgstr "ta bort en sekvens" + +#: sql_help.c:5581 +msgid "remove a foreign server descriptor" +msgstr "ta bort en främmande server-deskriptor" + +#: sql_help.c:5587 +msgid "remove extended statistics" +msgstr "ta bort utökad statistik" + +#: sql_help.c:5593 +msgid "remove a subscription" +msgstr "ta bort en prenumeration" + +#: sql_help.c:5599 +msgid "remove a table" +msgstr "ta bort en tabell" + +#: sql_help.c:5605 +msgid "remove a tablespace" +msgstr "ta bort ett tabellutrymme" + +#: sql_help.c:5611 +msgid "remove a text search configuration" +msgstr "ta bort en textsökkonfiguration" + +#: sql_help.c:5617 +msgid "remove a text search dictionary" +msgstr "ta bort en textsökordlista" + +#: sql_help.c:5623 +msgid "remove a text search parser" +msgstr "ta bort en textsökparser" + +#: sql_help.c:5629 +msgid "remove a text search template" +msgstr "ta bort en textsökmall" + +#: sql_help.c:5635 +msgid "remove a transform" +msgstr "ta bort en transform" + +#: sql_help.c:5641 +msgid "remove a trigger" +msgstr "ta bort en utlösare" + +#: sql_help.c:5647 +msgid "remove a data type" +msgstr "ta bort en datatyp" + +#: sql_help.c:5659 +msgid "remove a user mapping for a foreign server" +msgstr "ta bort en användarmappning för en främmande server" + +#: sql_help.c:5665 +msgid "remove a view" +msgstr "ta bort en vy" + +#: sql_help.c:5677 +msgid "execute a prepared statement" +msgstr "utför en förberedd sats" + +#: sql_help.c:5683 +msgid "show the execution plan of a statement" +msgstr "visa körningsplanen för en sats" + +#: sql_help.c:5689 +msgid "retrieve rows from a query using a cursor" +msgstr "hämta rader från en fråga med hjälp av en markör" + +#: sql_help.c:5695 +msgid "define access privileges" +msgstr "definera åtkomsträttigheter" + +#: sql_help.c:5701 +msgid "import table definitions from a foreign server" +msgstr "importera tabelldefinitioner från en främmande server" + +#: sql_help.c:5707 +msgid "create new rows in a table" +msgstr "skapa nya rader i en tabell" + +#: sql_help.c:5713 +msgid "listen for a notification" +msgstr "lyssna efter notifiering" + +#: sql_help.c:5719 +msgid "load a shared library file" +msgstr "ladda en delad biblioteksfil (shared library)" + +#: sql_help.c:5725 +msgid "lock a table" +msgstr "lås en tabell" + +#: sql_help.c:5731 +msgid "position a cursor" +msgstr "flytta en markör" + +#: sql_help.c:5737 +msgid "generate a notification" +msgstr "generera en notifiering" + +#: sql_help.c:5743 +msgid "prepare a statement for execution" +msgstr "förbered en sats för körning" + +#: sql_help.c:5749 +msgid "prepare the current transaction for two-phase commit" +msgstr "avbryt aktuell transaktion för två-fas-commit" + +#: sql_help.c:5755 +msgid "change the ownership of database objects owned by a database role" +msgstr "byt ägare på databasobjekt som ägs av en databasroll" + +#: sql_help.c:5761 +msgid "replace the contents of a materialized view" +msgstr "ersätt innehållet av en materialiserad vy" + +#: sql_help.c:5767 +msgid "rebuild indexes" +msgstr "återskapa index" + +#: sql_help.c:5773 +msgid "destroy a previously defined savepoint" +msgstr "ta bort en tidigare definierad sparpunkt" + +#: sql_help.c:5779 +msgid "restore the value of a run-time parameter to the default value" +msgstr "återställ värde av körningsparameter till standardvärdet" + +#: sql_help.c:5785 +msgid "remove access privileges" +msgstr "ta bort åtkomsträttigheter" + +#: sql_help.c:5797 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "avbryt en transaktion som tidigare förberetts för två-fas-commit" + +#: sql_help.c:5803 +msgid "roll back to a savepoint" +msgstr "rulla tillbaka till sparpunkt" + +#: sql_help.c:5809 +msgid "define a new savepoint within the current transaction" +msgstr "definera en ny sparpunkt i den aktuella transaktionen" + +#: sql_help.c:5815 +msgid "define or change a security label applied to an object" +msgstr "definiera eller ändra en säkerhetsetikett på ett objekt" + +#: sql_help.c:5821 sql_help.c:5875 sql_help.c:5911 +msgid "retrieve rows from a table or view" +msgstr "hämta rader från en tabell eller vy" + +#: sql_help.c:5833 +msgid "change a run-time parameter" +msgstr "ändra en körningsparameter" + +#: sql_help.c:5839 +msgid "set constraint check timing for the current transaction" +msgstr "sätt integritetsvillkorstiming för nuvarande transaktion" + +#: sql_help.c:5845 +msgid "set the current user identifier of the current session" +msgstr "sätt användare för den aktiva sessionen" + +#: sql_help.c:5851 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "sätt sessionsanvändaridentifierare och nuvarande användaridentifierare för den aktiva sessionen" + +#: sql_help.c:5857 +msgid "set the characteristics of the current transaction" +msgstr "sätt inställningar för nuvarande transaktionen" + +#: sql_help.c:5863 +msgid "show the value of a run-time parameter" +msgstr "visa värde på en körningsparameter" + +#: sql_help.c:5881 +msgid "empty a table or set of tables" +msgstr "töm en eller flera tabeller" + +#: sql_help.c:5887 +msgid "stop listening for a notification" +msgstr "sluta att lyssna efter notifiering" + +#: sql_help.c:5893 +msgid "update rows of a table" +msgstr "uppdatera rader i en tabell" + +#: sql_help.c:5899 +msgid "garbage-collect and optionally analyze a database" +msgstr "skräpsamla och eventuellt analysera en databas" + +#: sql_help.c:5905 +msgid "compute a set of rows" +msgstr "beräkna en mängd rader" + +#: startup.c:212 +#, c-format +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 kan bara användas i icke-interaktivt läge" + +#: startup.c:299 +#, c-format +msgid "could not connect to server: %s" +msgstr "kunde inte ansluta till server: %s" + +#: startup.c:327 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "kunde inte öppna loggfil \"%s\": %m" + +#: startup.c:439 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Skriv \"help\" för hjälp.\n" +"\n" + +#: startup.c:589 +#, c-format +msgid "could not set printing parameter \"%s\"" +msgstr "kunde inte sätta utskriftsparameter \"%s\"" + +#: startup.c:697 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: startup.c:714 +#, c-format +msgid "extra command-line argument \"%s\" ignored" +msgstr "extra kommandoradsargument \"%s\" ignorerad" + +#: startup.c:763 +#, c-format +msgid "could not find own program executable" +msgstr "kunde inte hitta det egna programmets körbara fil" + +#: tab-complete.c:4640 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s" +msgstr "" +"tab-kompletteringsfråga misslyckades: %s\n" +"Frågan var:\n" +"%s" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "okänt värde \"%s\" för \"%s\": förväntade sig en Boolean" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "ogiltigt värde \"%s\" för \"%s\": förväntade sig ett heltal" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "ogiltigt variabelnamn: \"%s\"" + +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"okänt värde \"%s\" för \"%s\"\n" +"Tillgängliga värden är: %s." + +#~ msgid "Opfamily Name" +#~ msgstr "Opfamiljenamn" + +#~ msgid "Proc name" +#~ msgstr "Proc-namn" + +#~ msgid "List of procedures of operator families" +#~ msgstr "Lista med procedurer i operatorfamilj" + +#~ msgid " \\g with no arguments is equivalent to a semicolon\n" +#~ msgstr " \\g utan argument är ekvivalent med ett semikolon\n" diff --git a/src/bin/psql/po/uk.po b/src/bin/psql/po/uk.po index f273f2e7ed25..5037f3a24573 100644 --- a/src/bin/psql/po/uk.po +++ b/src/bin/psql/po/uk.po @@ -2,9 +2,9 @@ msgid "" msgstr "" "Project-Id-Version: postgresql\n" "Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" -"POT-Creation-Date: 2019-09-27 15:12+0000\n" -"PO-Revision-Date: 2019-12-20 20:17\n" -"Last-Translator: pasha_golub\n" +"POT-Creation-Date: 2020-09-21 21:14+0000\n" +"PO-Revision-Date: 2020-09-22 13:43\n" +"Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" "MIME-Version: 1.0\n" @@ -12,72 +12,74 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" "X-Crowdin-Project: postgresql\n" +"X-Crowdin-Project-ID: 324573\n" "X-Crowdin-Language: uk\n" -"X-Crowdin-File: /REL_12_STABLE/psql.pot\n" +"X-Crowdin-File: /DEV_13/psql.pot\n" +"X-Crowdin-File-ID: 526\n" -#: ../../../src/common/logging.c:188 +#: ../../../src/common/logging.c:236 #, c-format msgid "fatal: " msgstr "збій: " -#: ../../../src/common/logging.c:195 +#: ../../../src/common/logging.c:243 #, c-format msgid "error: " msgstr "помилка: " -#: ../../../src/common/logging.c:202 +#: ../../../src/common/logging.c:250 #, c-format msgid "warning: " msgstr "попередження: " -#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#: ../../common/exec.c:137 ../../common/exec.c:254 ../../common/exec.c:300 #, c-format msgid "could not identify current directory: %m" msgstr "не вдалося визначити поточний каталог: %m" -#: ../../common/exec.c:157 +#: ../../common/exec.c:156 #, c-format msgid "invalid binary \"%s\"" msgstr "невірний бінарний файл \"%s\"" -#: ../../common/exec.c:207 +#: ../../common/exec.c:206 #, c-format msgid "could not read binary \"%s\"" msgstr "неможливо прочитати бінарний файл \"%s\"" -#: ../../common/exec.c:215 +#: ../../common/exec.c:214 #, c-format msgid "could not find a \"%s\" to execute" msgstr "неможливо знайти \"%s\" для виконання" -#: ../../common/exec.c:271 ../../common/exec.c:310 +#: ../../common/exec.c:270 ../../common/exec.c:309 #, c-format msgid "could not change directory to \"%s\": %m" -msgstr "не вдалося змінити каталог в \"%s\": %m" +msgstr "не вдалося змінити каталог на \"%s\": %m" -#: ../../common/exec.c:288 +#: ../../common/exec.c:287 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "не можливо прочитати символічне послання \"%s\": %m" -#: ../../common/exec.c:541 +#: ../../common/exec.c:410 #, c-format msgid "pclose failed: %m" msgstr "помилка pclose: %m" -#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 -#: command.c:1218 input.c:228 mainloop.c:82 mainloop.c:386 +#: ../../common/exec.c:539 ../../common/exec.c:584 ../../common/exec.c:676 +#: command.c:1255 input.c:227 mainloop.c:81 mainloop.c:402 #, c-format msgid "out of memory" msgstr "недостатньо пам'яті" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 +#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162 #, c-format msgid "out of memory\n" msgstr "недостатньо пам'яті\n" -#: ../../common/fe_memutils.c:92 +#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154 #, c-format msgid "cannot duplicate null pointer (internal error)\n" msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n" @@ -87,7 +89,7 @@ msgstr "неможливо дублювати нульовий покажчик msgid "could not look up effective user ID %ld: %s" msgstr "не можу знайти користувача з ефективним ID %ld: %s" -#: ../../common/username.c:45 command.c:555 +#: ../../common/username.c:45 command.c:559 msgid "user does not exist" msgstr "користувача не існує" @@ -126,7 +128,20 @@ msgstr "дочірній процес перервано через сигнал msgid "child process exited with unrecognized status %d" msgstr "дочірній процес завершився з невизнаним статусом %d" -#: ../../fe_utils/print.c:353 +#: ../../fe_utils/cancel.c:161 ../../fe_utils/cancel.c:206 +msgid "Cancel request sent\n" +msgstr "Запит на скасування відправлений\n" + +#: ../../fe_utils/cancel.c:165 +msgid "Could not send cancel request: " +msgstr "не вдалося надіслати запит на скасування: " + +#: ../../fe_utils/cancel.c:210 +#, c-format +msgid "Could not send cancel request: %s" +msgstr "Не вдалося надіслати скасування запиту: %s" + +#: ../../fe_utils/print.c:350 #, c-format msgid "(%lu row)" msgid_plural "(%lu rows)" @@ -135,314 +150,319 @@ msgstr[1] "(%lu рядки)" msgstr[2] "(%lu рядків)" msgstr[3] "(%lu рядка)" -#: ../../fe_utils/print.c:3058 +#: ../../fe_utils/print.c:3055 #, c-format msgid "Interrupted\n" msgstr "Перервано\n" -#: ../../fe_utils/print.c:3122 +#: ../../fe_utils/print.c:3119 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Неможливо додати заголовок до вмісту таблиці: кількість колонок %d перевищено.\n" -#: ../../fe_utils/print.c:3162 +#: ../../fe_utils/print.c:3159 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "Неможливо додати комірку до вмісту таблиці: перевищено загальну кількість комірок %d.\n" -#: ../../fe_utils/print.c:3417 +#: ../../fe_utils/print.c:3414 #, c-format msgid "invalid output format (internal error): %d" msgstr "невірний формат виводу (внутрішня помилка): %d" -#: ../../fe_utils/psqlscan.l:729 +#: ../../fe_utils/psqlscan.l:694 #, c-format msgid "skipping recursive expansion of variable \"%s\"" msgstr "пропуск рекурсивного розгортання змінної \"%s\"" -#: command.c:221 +#: command.c:224 #, c-format msgid "invalid command \\%s" msgstr "Невірна команда \\%s" -#: command.c:223 +#: command.c:226 #, c-format msgid "Try \\? for help." msgstr "Спробуйте \\? для отримання довідки." -#: command.c:241 +#: command.c:244 #, c-format msgid "\\%s: extra argument \"%s\" ignored" msgstr "\\%s: зайвий аргумент \"%s\" проігноровано" -#: command.c:293 +#: command.c:296 #, c-format msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" msgstr "\\%s команду проігноровано; скористайтесь \\endif або Ctrl-C, щоб вийти з поточного блоку \\if" -#: command.c:553 +#: command.c:557 #, c-format msgid "could not get home directory for user ID %ld: %s" msgstr "неможливо отримати домашню директорію для користувача ID %ld: %s" -#: command.c:571 +#: command.c:575 #, c-format msgid "\\%s: could not change directory to \"%s\": %m" msgstr "\\%s: неможливо змінити директорію на \"%s\": %m" -#: command.c:596 +#: command.c:600 #, c-format msgid "You are currently not connected to a database.\n" msgstr "На даний момент ви від'єднанні від бази даних.\n" -#: command.c:609 +#: command.c:613 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" msgstr "Ви під'єднані до бази даних \"%s\" як користувач \"%s\" за аресою \"%s\" на порту \"%s\".\n" -#: command.c:612 +#: command.c:616 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Ви під'єднані до бази даних \"%s\" як користувач \"%s\" через сокет в \"%s\" на порту \"%s\".\n" -#: command.c:618 +#: command.c:622 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" msgstr "Ви під'єднані до бази даних \"%s\" як користувач \"%s\" на хості \"%s\" (за аресою \"%s\") на порту \"%s\".\n" -#: command.c:621 +#: command.c:625 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Ви під'єднані до бази даних \"%s\" як користувач \"%s\" на хості \"%s\" на порту \"%s\".\n" -#: command.c:930 command.c:1026 command.c:2411 +#: command.c:965 command.c:1061 command.c:2550 #, c-format msgid "no query buffer" msgstr "немає буферу запитів" -#: command.c:963 command.c:4832 +#: command.c:998 command.c:5061 #, c-format msgid "invalid line number: %s" msgstr "невірний номер рядка: %s" -#: command.c:1017 +#: command.c:1052 #, c-format msgid "The server (version %s) does not support editing function source." msgstr "Сервер (версія %s) не пітдримує редагування вихідного коду функцій." -#: command.c:1020 +#: command.c:1055 #, c-format msgid "The server (version %s) does not support editing view definitions." msgstr "Сервер (версія %s) не підтримує редагування визначення подання." -#: command.c:1102 +#: command.c:1137 msgid "No changes" msgstr "Без змін" -#: command.c:1179 +#: command.c:1216 #, c-format msgid "%s: invalid encoding name or conversion procedure not found" msgstr "%s: невірне ім'я кодування або не знайдено процедуру конверсії" -#: command.c:1214 command.c:1853 command.c:3109 command.c:4934 common.c:175 -#: common.c:224 common.c:535 common.c:1376 common.c:1404 common.c:1512 -#: common.c:1615 common.c:1653 copy.c:490 copy.c:709 help.c:63 large_obj.c:157 +#: command.c:1251 command.c:1992 command.c:3253 command.c:5163 common.c:174 +#: common.c:223 common.c:388 common.c:1237 common.c:1265 common.c:1373 +#: common.c:1480 common.c:1518 copy.c:488 copy.c:707 help.c:62 large_obj.c:157 #: large_obj.c:192 large_obj.c:254 #, c-format msgid "%s" msgstr "%s" -#: command.c:1221 +#: command.c:1258 msgid "There is no previous error." msgstr "Попередня помилка відсутня." -#: command.c:1409 command.c:1714 command.c:1728 command.c:1745 command.c:1905 -#: command.c:2142 command.c:2378 command.c:2418 +#: command.c:1371 +#, c-format +msgid "\\%s: missing right parenthesis" +msgstr "\\%s: відсутня права дужка" + +#: command.c:1548 command.c:1853 command.c:1867 command.c:1884 command.c:2044 +#: command.c:2281 command.c:2517 command.c:2557 #, c-format msgid "\\%s: missing required argument" msgstr "\\%s: не вистачає обов'язкового аргументу" -#: command.c:1540 +#: command.c:1679 #, c-format msgid "\\elif: cannot occur after \\else" msgstr "\\elif: не може йти після \\else" -#: command.c:1545 +#: command.c:1684 #, c-format msgid "\\elif: no matching \\if" msgstr "\\elif: немає відповідного \\if" -#: command.c:1609 +#: command.c:1748 #, c-format msgid "\\else: cannot occur after \\else" msgstr "\\else: не може йти після \\else" -#: command.c:1614 +#: command.c:1753 #, c-format msgid "\\else: no matching \\if" msgstr "\\else: немає відповідного \\if" -#: command.c:1654 +#: command.c:1793 #, c-format msgid "\\endif: no matching \\if" msgstr "\\endif: немає відповідного \\if" -#: command.c:1809 +#: command.c:1948 msgid "Query buffer is empty." msgstr "Буфер запиту порожній." -#: command.c:1831 +#: command.c:1970 msgid "Enter new password: " msgstr "Введіть новий пароль:" -#: command.c:1832 +#: command.c:1971 msgid "Enter it again: " msgstr "Введіть знову: " -#: command.c:1836 +#: command.c:1975 #, c-format msgid "Passwords didn't match." msgstr "Паролі не співпадають." -#: command.c:1935 +#: command.c:2074 #, c-format msgid "\\%s: could not read value for variable" msgstr "\\%s: не вдалося прочитати значення змінної" -#: command.c:2038 +#: command.c:2177 msgid "Query buffer reset (cleared)." msgstr "Буфер запитів скинуто (очищено)." -#: command.c:2060 +#: command.c:2199 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "Історію записано до файлу \"%s\".\n" -#: command.c:2147 +#: command.c:2286 #, c-format msgid "\\%s: environment variable name must not contain \"=\"" msgstr "\\%s: змінна середовища не повинна містити \"=\"" -#: command.c:2208 +#: command.c:2347 #, c-format msgid "The server (version %s) does not support showing function source." msgstr "Сервер (версія %s) не пітдримує відображнення вихідного коду функцій." -#: command.c:2211 +#: command.c:2350 #, c-format msgid "The server (version %s) does not support showing view definitions." msgstr "Сервер (версія %s) не підтримує відображення визначення подання." -#: command.c:2218 +#: command.c:2357 #, c-format msgid "function name is required" msgstr "необхідне ім'я функції" -#: command.c:2220 +#: command.c:2359 #, c-format msgid "view name is required" msgstr "необхідне ім'я подання" -#: command.c:2350 +#: command.c:2489 msgid "Timing is on." msgstr "Таймер увімкнено." -#: command.c:2352 +#: command.c:2491 msgid "Timing is off." msgstr "Таймер вимкнено." -#: command.c:2437 command.c:2465 command.c:3516 command.c:3519 command.c:3522 -#: command.c:3528 command.c:3530 command.c:3538 command.c:3548 command.c:3557 -#: command.c:3571 command.c:3588 command.c:3646 common.c:71 copy.c:333 -#: copy.c:405 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#: command.c:2576 command.c:2604 command.c:3661 command.c:3664 command.c:3667 +#: command.c:3673 command.c:3675 command.c:3683 command.c:3693 command.c:3702 +#: command.c:3716 command.c:3733 command.c:3791 common.c:70 copy.c:331 +#: copy.c:403 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 #, c-format msgid "%s: %m" msgstr "%s: %m" -#: command.c:2849 startup.c:240 startup.c:291 +#: command.c:2988 startup.c:236 startup.c:287 msgid "Password: " msgstr "Пароль: " -#: command.c:2854 startup.c:288 +#: command.c:2993 startup.c:284 #, c-format msgid "Password for user %s: " msgstr "Пароль користувача %s:" -#: command.c:2925 +#: command.c:3064 #, c-format msgid "All connection parameters must be supplied because no database connection exists" msgstr "Мають бути введені усі параметри з'єднання, оскільки відсутнє підключення до бази даних" -#: command.c:3113 +#: command.c:3257 #, c-format msgid "Previous connection kept" msgstr "Попереднє підключення триває" -#: command.c:3117 +#: command.c:3261 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:3166 +#: command.c:3310 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" msgstr "Ви під'єднані до бази даних \"%s\" як користувач \"%s\" за адресою \"%s\" на порту \"%s\".\n" -#: command.c:3169 +#: command.c:3313 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Ви тепер під'єднані до бази даних \"%s\" як користувач \"%s\" через сокет в \"%s\" на порту \"%s\".\n" -#: command.c:3175 +#: command.c:3319 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" msgstr "Ви під'єднані до бази даних \"%s\" як користувач \"%s\" на хості \"%s\" (за адресою \"%s\") на порту \"%s\".\n" -#: command.c:3178 +#: command.c:3322 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Ви тепер під'єднані до бази даних \"%s\" як користувач \"%s\" на хості \"%s\" на порту \"%s\".\n" -#: command.c:3183 +#: command.c:3327 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Ви тепер під'єднані до бази даних \"%s\" як користувач \"%s\".\n" -#: command.c:3216 +#: command.c:3360 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, сервер %s)\n" -#: command.c:3224 +#: command.c:3368 #, c-format msgid "WARNING: %s major version %s, server major version %s.\n" " Some psql features might not work.\n" msgstr "УВАГА: мажорна версія %s %s, мажорна версія сервера %s.\n" " Деякі функції psql можуть не працювати.\n" -#: command.c:3263 +#: command.c:3407 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "З'єднання SSL (протокол: %s, шифр: %s, біти: %s, компресія: %s)\n" -#: command.c:3264 command.c:3265 command.c:3266 +#: command.c:3408 command.c:3409 command.c:3410 msgid "unknown" msgstr "невідомо" -#: command.c:3267 help.c:46 +#: command.c:3411 help.c:45 msgid "off" msgstr "вимк" -#: command.c:3267 help.c:46 +#: command.c:3411 help.c:45 msgid "on" msgstr "увімк" -#: command.c:3281 +#: command.c:3425 #, c-format msgid "GSSAPI-encrypted connection\n" msgstr "З'єднання зашифровано GSSAPI\n" -#: command.c:3301 +#: command.c:3445 #, c-format msgid "WARNING: Console code page (%u) differs from Windows code page (%u)\n" " 8-bit characters might not work correctly. See psql reference\n" @@ -451,172 +471,172 @@ msgstr "УВАГА: Кодова сторінка консолі (%u) відрі " 8-бітові символи можуть працювати неправильно. Детальніше у розділі \n" " \"Нотатки для користувачів Windows\" у документації psql.\n" -#: command.c:3405 +#: command.c:3549 #, c-format msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" msgstr "змінна середовища PSQL_EDITOR_LINENUMBER_ARG має бути встановлена, щоб вказувати номер рядка" -#: command.c:3434 +#: command.c:3578 #, c-format msgid "could not start editor \"%s\"" msgstr "неможливо запустити редактор \"%s\"" -#: command.c:3436 +#: command.c:3580 #, c-format msgid "could not start /bin/sh" msgstr "неможливо запустити /bin/sh" -#: command.c:3474 +#: command.c:3618 #, c-format msgid "could not locate temporary directory: %s" msgstr "неможливо знайти тимчасову директорію: %s" -#: command.c:3501 +#: command.c:3645 #, c-format msgid "could not open temporary file \"%s\": %m" msgstr "неможливо відкрити тимчасовий файл \"%s\": %m" -#: command.c:3794 +#: command.c:3950 #, c-format msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" msgstr "\\pset: неоднозначна абревіатура \"%s\" відповідає обом \"%s\" і \"%s" -#: command.c:3814 +#: command.c:3970 #, c-format msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" msgstr "\\pset: дозволені формати: aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" -#: command.c:3833 +#: command.c:3989 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" msgstr "\\pset: дозволені стилі ліній: ascii, old-ascii, unicode" -#: command.c:3848 +#: command.c:4004 #, c-format msgid "\\pset: allowed Unicode border line styles are single, double" msgstr "\\pset: дозволені стилі ліній рамок Unicode: single, double" -#: command.c:3863 +#: command.c:4019 #, c-format msgid "\\pset: allowed Unicode column line styles are single, double" msgstr "\\pset: дозволені стилі ліній стовпців для Unicode: single, double" -#: command.c:3878 +#: command.c:4034 #, c-format msgid "\\pset: allowed Unicode header line styles are single, double" msgstr "\\pset: дозволені стилі ліній заголовків для Unicode: single, double" -#: command.c:3921 +#: command.c:4077 #, c-format msgid "\\pset: csv_fieldsep must be a single one-byte character" msgstr "\\pset: csv_fieldsep повинен бути однобайтовим символом" -#: command.c:3926 +#: command.c:4082 #, c-format msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" msgstr "\\pset: csv_fieldsep не може бути подвійною лапкою, новим рядком або поверненням каретки" -#: command.c:4063 command.c:4249 +#: command.c:4219 command.c:4407 #, c-format msgid "\\pset: unknown option: %s" msgstr "\\pset: невідомий параметр: %s" -#: command.c:4081 +#: command.c:4239 #, c-format msgid "Border style is %d.\n" msgstr "Стиль рамки %d.\n" -#: command.c:4087 +#: command.c:4245 #, c-format msgid "Target width is unset.\n" msgstr "Цільова ширина не встановлена.\n" -#: command.c:4089 +#: command.c:4247 #, c-format msgid "Target width is %d.\n" msgstr "Цільова ширина %d.\n" -#: command.c:4096 +#: command.c:4254 #, c-format msgid "Expanded display is on.\n" msgstr "Розширене відображення увімкнуто.\n" -#: command.c:4098 +#: command.c:4256 #, c-format msgid "Expanded display is used automatically.\n" msgstr "Розширене відображення використовується автоматично.\n" -#: command.c:4100 +#: command.c:4258 #, c-format msgid "Expanded display is off.\n" msgstr "Розширене відображення вимкнуто.\n" -#: command.c:4106 +#: command.c:4264 #, c-format msgid "Field separator for CSV is \"%s\".\n" msgstr "Розділювач полів CSV: \"%s\".\n" -#: command.c:4114 command.c:4122 +#: command.c:4272 command.c:4280 #, c-format msgid "Field separator is zero byte.\n" msgstr "Розділювач полів - нульовий байт.\n" -#: command.c:4116 +#: command.c:4274 #, c-format msgid "Field separator is \"%s\".\n" msgstr "Розділювач полів \"%s\".\n" -#: command.c:4129 +#: command.c:4287 #, c-format msgid "Default footer is on.\n" msgstr "Нинжній колонтитул увімкнуто за замовчуванням.\n" -#: command.c:4131 +#: command.c:4289 #, c-format msgid "Default footer is off.\n" msgstr "Нинжній колонтитул вимкнуто за замовчуванням.\n" -#: command.c:4137 +#: command.c:4295 #, c-format msgid "Output format is %s.\n" msgstr "Формат виводу %s.\n" -#: command.c:4143 +#: command.c:4301 #, c-format msgid "Line style is %s.\n" msgstr "Стиль лінії %s.\n" -#: command.c:4150 +#: command.c:4308 #, c-format msgid "Null display is \"%s\".\n" msgstr "Null відображається як \"%s\".\n" -#: command.c:4158 +#: command.c:4316 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "Локалізоване виведення чисел ввімкнено.\n" -#: command.c:4160 +#: command.c:4318 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "Локалізоване виведення чисел вимкнено.\n" -#: command.c:4167 +#: command.c:4325 #, c-format msgid "Pager is used for long output.\n" msgstr "Пейджер використовується для виведення довгого тексту.\n" -#: command.c:4169 +#: command.c:4327 #, c-format msgid "Pager is always used.\n" msgstr "Завжди використовується пейджер.\n" -#: command.c:4171 +#: command.c:4329 #, c-format msgid "Pager usage is off.\n" msgstr "Пейджер не використовується.\n" -#: command.c:4177 +#: command.c:4335 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" @@ -625,87 +645,87 @@ msgstr[1] "Пейджер не буде використовуватися дл msgstr[2] "Пейджер не буде використовуватися для менш ніж %d рядків.\n" msgstr[3] "Пейджер не буде використовуватися для менш ніж %d рядка.\n" -#: command.c:4187 command.c:4197 +#: command.c:4345 command.c:4355 #, c-format msgid "Record separator is zero byte.\n" msgstr "Розділювач записів - нульовий байт.\n" -#: command.c:4189 +#: command.c:4347 #, c-format msgid "Record separator is .\n" msgstr "Розділювач записів: .\n" -#: command.c:4191 +#: command.c:4349 #, c-format msgid "Record separator is \"%s\".\n" msgstr "Розділювач записів: \"%s\".\n" -#: command.c:4204 +#: command.c:4362 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "Табличні атрибути \"%s\".\n" -#: command.c:4207 +#: command.c:4365 #, c-format msgid "Table attributes unset.\n" msgstr "Атрибути таблиць не задані.\n" -#: command.c:4214 +#: command.c:4372 #, c-format msgid "Title is \"%s\".\n" msgstr "Заголовок: \"%s\".\n" -#: command.c:4216 +#: command.c:4374 #, c-format msgid "Title is unset.\n" msgstr "Заголовок не встановлено.\n" -#: command.c:4223 +#: command.c:4381 #, c-format msgid "Tuples only is on.\n" msgstr "Увімкнуто тільки кортежі.\n" -#: command.c:4225 +#: command.c:4383 #, c-format msgid "Tuples only is off.\n" msgstr "Вимкнуто тільки кортежі.\n" -#: command.c:4231 +#: command.c:4389 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "Стиль ліній рамки для Unicode: \"%s\".\n" -#: command.c:4237 +#: command.c:4395 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "Стиль ліній стовпців для Unicode: \"%s\".\n" -#: command.c:4243 +#: command.c:4401 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "Стиль ліній заголовків для Unicode: \"%s\".\n" -#: command.c:4405 +#: command.c:4634 #, c-format msgid "\\!: failed" msgstr "\\!: помилка" -#: command.c:4430 common.c:795 +#: command.c:4659 common.c:648 #, c-format msgid "\\watch cannot be used with an empty query" msgstr "\\watch не може бути використано із пустим запитом" -#: command.c:4471 +#: command.c:4700 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (кожні %g сек)\n" -#: command.c:4474 +#: command.c:4703 #, c-format msgid "%s (every %gs)\n" msgstr "%s (кожні %g сек)\n" -#: command.c:4528 command.c:4535 common.c:695 common.c:702 common.c:1359 +#: command.c:4757 command.c:4764 common.c:548 common.c:555 common.c:1220 #, c-format msgid "********* QUERY **********\n" "%s\n" @@ -714,107 +734,112 @@ msgstr "********* ЗАПИТ **********\n" "%s\n" "**************************\n\n" -#: command.c:4727 +#: command.c:4956 #, c-format msgid "\"%s.%s\" is not a view" msgstr "\"%s.%s\" не є поданням" -#: command.c:4743 +#: command.c:4972 #, c-format msgid "could not parse reloptions array" msgstr "неможливо розібрати масив reloptions" -#: common.c:160 +#: common.c:159 #, c-format msgid "cannot escape without active connection" msgstr "не можна вийти без активного з'єднання" -#: common.c:201 +#: common.c:200 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"" msgstr "аргумент командної оболонки містить символ нового рядка або повернення каретки: \"%s\"" -#: common.c:395 +#: common.c:304 #, c-format msgid "connection to server was lost" msgstr "з'єднання із сервером втрачено" -#: common.c:399 +#: common.c:308 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "З'єднання із сервером втрачено. Спроба перевстановити:" -#: common.c:404 +#: common.c:313 #, c-format msgid "Failed.\n" msgstr "Помилка.\n" -#: common.c:417 +#: common.c:326 #, c-format msgid "Succeeded.\n" msgstr "Вдало.\n" -#: common.c:525 common.c:1077 common.c:1294 +#: common.c:378 common.c:938 common.c:1155 #, c-format msgid "unexpected PQresultStatus: %d" msgstr "неочікуваний PQresultStatus: %d" -#: common.c:634 +#: common.c:487 #, c-format msgid "Time: %.3f ms\n" msgstr "Час: %.3f мс\n" -#: common.c:649 +#: common.c:502 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "Час: %.3f мс (%02d:%06.3f)\n" -#: common.c:658 +#: common.c:511 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "Час: %.3f мс (%02d:%02d:%06.3f)\n" -#: common.c:665 +#: common.c:518 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Час: %.3f мс (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:689 common.c:747 common.c:1330 +#: common.c:542 common.c:600 common.c:1191 #, c-format msgid "You are currently not connected to a database." msgstr "На даний момент ви від'єднанні від бази даних." -#: common.c:802 +#: common.c:655 #, c-format msgid "\\watch cannot be used with COPY" msgstr "\\watch не може бути використано з COPY" -#: common.c:807 +#: common.c:660 #, c-format msgid "unexpected result status for \\watch" msgstr "неочікуваний результат статусу для \\watch" -#: common.c:837 +#: common.c:690 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "Асинхронне сповіщення \"%s\" з навантаженням \"%s\" отримане від серверного процесу з PID %d.\n" -#: common.c:840 +#: common.c:693 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "Асинхронне сповіщення \"%s\" отримане від серверного процесу з PID %d.\n" -#: common.c:903 +#: common.c:726 common.c:743 +#, c-format +msgid "could not print result table: %m" +msgstr "не вдалося надрукувати таблицю результатів: %m" + +#: common.c:764 #, c-format msgid "no rows returned for \\gset" msgstr "немає рядків повернутих для \\gset" -#: common.c:908 +#: common.c:769 #, c-format msgid "more than one row returned for \\gset" msgstr "більш, ніж один рядок повернуто для \\gset" -#: common.c:1339 +#: common.c:1200 #, c-format msgid "***(Single step mode: verify command)*******************************************\n" "%s\n" @@ -823,899 +848,905 @@ msgstr "***(Покроковий режим: перевірка команди)* "%s\n" "***(Enter - виповнити; х і Enter - відмінити)********************\n" -#: common.c:1394 +#: common.c:1255 #, c-format msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." msgstr "Сервер (версія %s) не підтримує точки збереження для ON_ERROR_ROLLBACK." -#: common.c:1457 +#: common.c:1318 #, c-format msgid "STATEMENT: %s" msgstr "ІНСТРУКЦІЯ: %s" -#: common.c:1500 +#: common.c:1361 #, c-format msgid "unexpected transaction status (%d)" msgstr "неочікуваний стан транзакції (%d)" -#: common.c:1637 describe.c:2002 +#: common.c:1502 describe.c:2001 msgid "Column" msgstr "Стовпець" -#: common.c:1638 describe.c:179 describe.c:394 describe.c:412 describe.c:457 -#: describe.c:474 describe.c:963 describe.c:1127 describe.c:1712 -#: describe.c:1736 describe.c:2003 describe.c:3674 describe.c:3859 -#: describe.c:4092 describe.c:5298 +#: common.c:1503 describe.c:177 describe.c:393 describe.c:411 describe.c:456 +#: describe.c:473 describe.c:962 describe.c:1126 describe.c:1711 +#: describe.c:1735 describe.c:2002 describe.c:3729 describe.c:3939 +#: describe.c:4172 describe.c:5378 msgid "Type" msgstr "Тип" -#: common.c:1687 +#: common.c:1552 #, c-format msgid "The command has no result, or the result has no columns.\n" msgstr "Команда не має результату або результат не має стовпців.\n" -#: copy.c:100 +#: copy.c:98 #, c-format msgid "\\copy: arguments required" msgstr "\\copy: необхідні аргументи" -#: copy.c:255 +#: copy.c:253 #, c-format msgid "\\copy: parse error at \"%s\"" msgstr "\\copy: помилка розбору аргументу біля \"%s\"" -#: copy.c:257 +#: copy.c:255 #, c-format msgid "\\copy: parse error at end of line" msgstr "\\copy: помилка розбору в кінці рядка" -#: copy.c:330 +#: copy.c:328 #, c-format msgid "could not execute command \"%s\": %m" msgstr "не вдалося виконати команду \"%s\": %m" -#: copy.c:346 +#: copy.c:344 #, c-format msgid "could not stat file \"%s\": %m" msgstr "не вдалося отримати інформацію від файлу \"%s\": %m" -#: copy.c:350 +#: copy.c:348 #, c-format msgid "%s: cannot copy from/to a directory" msgstr "%s: не можна копіювати з/до каталогу" -#: copy.c:387 +#: copy.c:385 #, c-format msgid "could not close pipe to external command: %m" msgstr "не вдалося закрити канал за допомогою зовнішньої команди: %m" -#: copy.c:392 +#: copy.c:390 #, c-format msgid "%s: %s" msgstr "%s: %s" -#: copy.c:455 copy.c:465 +#: copy.c:453 copy.c:463 #, c-format msgid "could not write COPY data: %m" msgstr "неможливо записати дані COPY: %m" -#: copy.c:471 +#: copy.c:469 #, c-format msgid "COPY data transfer failed: %s" msgstr "Помилка передачі даних COPY: %s" -#: copy.c:532 +#: copy.c:530 msgid "canceled by user" msgstr "скасовано користувачем" -#: copy.c:543 +#: copy.c:541 msgid "Enter data to be copied followed by a newline.\n" "End with a backslash and a period on a line by itself, or an EOF signal." msgstr "Введіть дані для копювання, розділяючи переносом рядка.\n" "Завершіть введення за допомогою \"\\.\" або за допомогою сигналу EOF." -#: copy.c:671 +#: copy.c:669 msgid "aborted because of read failure" msgstr "перервано через помилку читання" -#: copy.c:705 +#: copy.c:703 msgid "trying to exit copy mode" msgstr "спроба вийти з режиму копіювання" -#: crosstabview.c:124 +#: crosstabview.c:123 #, c-format msgid "\\crosstabview: statement did not return a result set" msgstr "\\crosstabview: команда не повернула набір з результатами" -#: crosstabview.c:130 +#: crosstabview.c:129 #, c-format msgid "\\crosstabview: query must return at least three columns" msgstr "\\crosstabview: запит має повернути принаймні три стовпці" -#: crosstabview.c:157 +#: crosstabview.c:156 #, c-format msgid "\\crosstabview: vertical and horizontal headers must be different columns" msgstr "\\crosstabview: вертикальні і горизонтальні заголовки повинні бути різними стовпцями" -#: crosstabview.c:173 +#: crosstabview.c:172 #, c-format msgid "\\crosstabview: data column must be specified when query returns more than three columns" msgstr "\\crosstabview: необхідно вказати стовпець даних, коли запит повертає більше трьох стовпців" -#: crosstabview.c:229 +#: crosstabview.c:228 #, c-format msgid "\\crosstabview: maximum number of columns (%d) exceeded" msgstr "\\crosstabview: Максимальна кількість стовпців (%d) перевищена" -#: crosstabview.c:398 +#: crosstabview.c:397 #, c-format msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" msgstr "\\crosstabview: результат запиту містить кілька значень даних для рядка «%s», стовпця «%s»" -#: crosstabview.c:646 +#: crosstabview.c:645 #, c-format msgid "\\crosstabview: column number %d is out of range 1..%d" msgstr "\\crosstabview: номер стовпця %d поза межами 1..%d" -#: crosstabview.c:671 +#: crosstabview.c:670 #, c-format msgid "\\crosstabview: ambiguous column name: \"%s\"" msgstr "\\crosstabview: неоднозначна назва стовпця: \"%s\"" -#: crosstabview.c:679 +#: crosstabview.c:678 #, c-format msgid "\\crosstabview: column name not found: \"%s\"" msgstr "\\crosstabview: ім'я стовпця не знайдено: \"%s\"" -#: describe.c:77 describe.c:374 describe.c:679 describe.c:811 describe.c:955 -#: describe.c:1116 describe.c:1188 describe.c:3663 describe.c:3846 -#: describe.c:4090 describe.c:4181 describe.c:4448 describe.c:4608 -#: describe.c:4849 describe.c:4924 describe.c:4935 describe.c:4997 -#: describe.c:5422 describe.c:5505 +#: describe.c:75 describe.c:373 describe.c:678 describe.c:810 describe.c:954 +#: describe.c:1115 describe.c:1187 describe.c:3718 describe.c:3926 +#: describe.c:4170 describe.c:4261 describe.c:4528 describe.c:4688 +#: describe.c:4929 describe.c:5004 describe.c:5015 describe.c:5077 +#: describe.c:5502 describe.c:5585 msgid "Schema" msgstr "Схема" -#: describe.c:78 describe.c:176 describe.c:244 describe.c:252 describe.c:375 -#: describe.c:680 describe.c:812 describe.c:873 describe.c:956 describe.c:1189 -#: describe.c:3664 describe.c:3847 describe.c:4013 describe.c:4091 -#: describe.c:4182 describe.c:4261 describe.c:4449 describe.c:4533 -#: describe.c:4609 describe.c:4850 describe.c:4925 describe.c:4936 -#: describe.c:4998 describe.c:5195 describe.c:5279 describe.c:5503 -#: describe.c:5675 describe.c:5900 +#: describe.c:76 describe.c:174 describe.c:242 describe.c:250 describe.c:374 +#: describe.c:679 describe.c:811 describe.c:872 describe.c:955 describe.c:1188 +#: describe.c:3719 describe.c:3927 describe.c:4093 describe.c:4171 +#: describe.c:4262 describe.c:4341 describe.c:4529 describe.c:4613 +#: describe.c:4689 describe.c:4930 describe.c:5005 describe.c:5016 +#: describe.c:5078 describe.c:5275 describe.c:5359 describe.c:5583 +#: describe.c:5755 describe.c:5995 msgid "Name" msgstr "Назва" -#: describe.c:79 describe.c:387 describe.c:405 describe.c:451 describe.c:468 +#: describe.c:77 describe.c:386 describe.c:404 describe.c:450 describe.c:467 msgid "Result data type" msgstr "Тип даних результату" -#: describe.c:87 describe.c:100 describe.c:104 describe.c:388 describe.c:406 -#: describe.c:452 describe.c:469 +#: describe.c:85 describe.c:98 describe.c:102 describe.c:387 describe.c:405 +#: describe.c:451 describe.c:468 msgid "Argument data types" msgstr "Типи даних аргументів" -#: describe.c:112 describe.c:119 describe.c:187 describe.c:275 describe.c:514 -#: describe.c:728 describe.c:827 describe.c:898 describe.c:1191 describe.c:2021 -#: describe.c:3452 describe.c:3699 describe.c:3893 describe.c:4044 -#: describe.c:4118 describe.c:4191 describe.c:4274 describe.c:4357 -#: describe.c:4476 describe.c:4542 describe.c:4610 describe.c:4751 -#: describe.c:4793 describe.c:4866 describe.c:4928 describe.c:4937 -#: describe.c:4999 describe.c:5221 describe.c:5301 describe.c:5436 -#: describe.c:5506 large_obj.c:290 large_obj.c:300 +#: describe.c:110 describe.c:117 describe.c:185 describe.c:273 describe.c:513 +#: describe.c:727 describe.c:826 describe.c:897 describe.c:1190 describe.c:2020 +#: describe.c:3506 describe.c:3779 describe.c:3973 describe.c:4124 +#: describe.c:4198 describe.c:4271 describe.c:4354 describe.c:4437 +#: describe.c:4556 describe.c:4622 describe.c:4690 describe.c:4831 +#: describe.c:4873 describe.c:4946 describe.c:5008 describe.c:5017 +#: describe.c:5079 describe.c:5301 describe.c:5381 describe.c:5516 +#: describe.c:5586 large_obj.c:290 large_obj.c:300 msgid "Description" msgstr "Опис" -#: describe.c:137 +#: describe.c:135 msgid "List of aggregate functions" msgstr "Перелік агрегатних функцій" -#: describe.c:162 +#: describe.c:160 #, c-format msgid "The server (version %s) does not support access methods." msgstr "Сервер (версія %s) не підтримує методи доступу." -#: describe.c:177 +#: describe.c:175 msgid "Index" msgstr "Індекс" -#: describe.c:178 describe.c:3680 describe.c:3872 describe.c:5423 +#: describe.c:176 describe.c:3737 describe.c:3952 describe.c:5503 msgid "Table" msgstr "Таблиця" -#: describe.c:186 describe.c:5200 +#: describe.c:184 describe.c:5280 msgid "Handler" msgstr "Обробник" -#: describe.c:205 +#: describe.c:203 msgid "List of access methods" msgstr "Список методів доступу" -#: describe.c:231 +#: describe.c:229 #, c-format msgid "The server (version %s) does not support tablespaces." msgstr "Сервер (версія %s) не підтримує табличні простори." -#: describe.c:245 describe.c:253 describe.c:502 describe.c:718 describe.c:874 -#: describe.c:1115 describe.c:3675 describe.c:3848 describe.c:4017 -#: describe.c:4263 describe.c:4534 describe.c:5196 describe.c:5280 -#: describe.c:5676 describe.c:5802 describe.c:5901 large_obj.c:289 +#: describe.c:243 describe.c:251 describe.c:501 describe.c:717 describe.c:873 +#: describe.c:1114 describe.c:3730 describe.c:3928 describe.c:4097 +#: describe.c:4343 describe.c:4614 describe.c:5276 describe.c:5360 +#: describe.c:5756 describe.c:5893 describe.c:5996 describe.c:6111 +#: describe.c:6190 large_obj.c:289 msgid "Owner" msgstr "Власник" -#: describe.c:246 describe.c:254 +#: describe.c:244 describe.c:252 msgid "Location" msgstr "Розташування" -#: describe.c:265 describe.c:3270 +#: describe.c:263 describe.c:3323 msgid "Options" msgstr "Параметри" -#: describe.c:270 describe.c:691 describe.c:890 describe.c:3691 describe.c:3695 +#: describe.c:268 describe.c:690 describe.c:889 describe.c:3771 describe.c:3775 msgid "Size" msgstr "Розмір" -#: describe.c:292 +#: describe.c:290 msgid "List of tablespaces" msgstr "Список табличних просторів" -#: describe.c:334 +#: describe.c:333 #, c-format msgid "\\df only takes [anptwS+] as options" msgstr "\\df приймає в якості параметрів тільки [anptwS+]" -#: describe.c:342 describe.c:353 +#: describe.c:341 describe.c:352 #, c-format msgid "\\df does not take a \"%c\" option with server version %s" msgstr "\\df не приймає параметр \"%c\" із сервером версії %s" #. translator: "agg" is short for "aggregate" -#: describe.c:390 describe.c:408 describe.c:454 describe.c:471 +#: describe.c:389 describe.c:407 describe.c:453 describe.c:470 msgid "agg" msgstr "агр." -#: describe.c:391 describe.c:409 +#: describe.c:390 describe.c:408 msgid "window" msgstr "вікно" -#: describe.c:392 +#: describe.c:391 msgid "proc" msgstr "проц" -#: describe.c:393 describe.c:411 describe.c:456 describe.c:473 +#: describe.c:392 describe.c:410 describe.c:455 describe.c:472 msgid "func" msgstr "функ" -#: describe.c:410 describe.c:455 describe.c:472 describe.c:1325 +#: describe.c:409 describe.c:454 describe.c:471 describe.c:1324 msgid "trigger" msgstr "тригер" -#: describe.c:484 +#: describe.c:483 msgid "immutable" msgstr "постійна" -#: describe.c:485 +#: describe.c:484 msgid "stable" msgstr "стабільна" -#: describe.c:486 +#: describe.c:485 msgid "volatile" msgstr "мінлива" -#: describe.c:487 +#: describe.c:486 msgid "Volatility" msgstr "Мінливість" -#: describe.c:495 +#: describe.c:494 msgid "restricted" msgstr "обмежений" -#: describe.c:496 +#: describe.c:495 msgid "safe" msgstr "безпечний" -#: describe.c:497 +#: describe.c:496 msgid "unsafe" msgstr "небезпечний" -#: describe.c:498 +#: describe.c:497 msgid "Parallel" msgstr "Паралельність" -#: describe.c:503 +#: describe.c:502 msgid "definer" msgstr "визначник" -#: describe.c:504 +#: describe.c:503 msgid "invoker" msgstr "викликач" -#: describe.c:505 +#: describe.c:504 msgid "Security" msgstr "Безпека" -#: describe.c:512 +#: describe.c:511 msgid "Language" msgstr "Мова" -#: describe.c:513 +#: describe.c:512 msgid "Source code" msgstr "Вихідний код" -#: describe.c:642 +#: describe.c:641 msgid "List of functions" msgstr "Список функцій" -#: describe.c:690 +#: describe.c:689 msgid "Internal name" msgstr "Внутрішнє назва" -#: describe.c:712 +#: describe.c:711 msgid "Elements" msgstr "Елементи" -#: describe.c:769 +#: describe.c:768 msgid "List of data types" msgstr "Список типів даних" -#: describe.c:813 +#: describe.c:812 msgid "Left arg type" msgstr "Тип лівого аргумента" -#: describe.c:814 +#: describe.c:813 msgid "Right arg type" msgstr "Тип правого аргумента" -#: describe.c:815 +#: describe.c:814 msgid "Result type" msgstr "Результуючий тип" -#: describe.c:820 describe.c:4269 describe.c:4334 describe.c:4340 -#: describe.c:4750 +#: describe.c:819 describe.c:4349 describe.c:4414 describe.c:4420 +#: describe.c:4830 describe.c:6362 describe.c:6366 msgid "Function" msgstr "Функція" -#: describe.c:845 +#: describe.c:844 msgid "List of operators" msgstr "Список операторів" -#: describe.c:875 +#: describe.c:874 msgid "Encoding" msgstr "Кодування" -#: describe.c:880 describe.c:4450 +#: describe.c:879 describe.c:4530 msgid "Collate" msgstr "Порядок сортування" -#: describe.c:881 describe.c:4451 +#: describe.c:880 describe.c:4531 msgid "Ctype" msgstr "Ctype" -#: describe.c:894 +#: describe.c:893 msgid "Tablespace" msgstr "Табличний простір" -#: describe.c:916 +#: describe.c:915 msgid "List of databases" msgstr "Список баз даних" -#: describe.c:957 describe.c:1118 describe.c:3665 +#: describe.c:956 describe.c:1117 describe.c:3720 msgid "table" msgstr "таблиця" -#: describe.c:958 describe.c:3666 +#: describe.c:957 describe.c:3721 msgid "view" msgstr "подання" -#: describe.c:959 describe.c:3667 +#: describe.c:958 describe.c:3722 msgid "materialized view" msgstr "матеріалізоване подання" -#: describe.c:960 describe.c:1120 describe.c:3669 +#: describe.c:959 describe.c:1119 describe.c:3724 msgid "sequence" msgstr "послідовність" -#: describe.c:961 describe.c:3671 +#: describe.c:960 describe.c:3726 msgid "foreign table" msgstr "зовнішня таблиця" -#: describe.c:962 describe.c:3672 describe.c:3857 +#: describe.c:961 describe.c:3727 describe.c:3937 msgid "partitioned table" msgstr "секційна таблиця" -#: describe.c:974 +#: describe.c:973 msgid "Column privileges" msgstr "Права для стовпців" -#: describe.c:1005 describe.c:1039 +#: describe.c:1004 describe.c:1038 msgid "Policies" msgstr "Політики" -#: describe.c:1071 describe.c:5957 describe.c:5961 +#: describe.c:1070 describe.c:6052 describe.c:6056 msgid "Access privileges" msgstr "Права доступу" -#: describe.c:1102 +#: describe.c:1101 #, c-format msgid "The server (version %s) does not support altering default privileges." msgstr "Сервер (версія %s) не підтримує зміну прав за замовчуванням." -#: describe.c:1122 +#: describe.c:1121 msgid "function" msgstr "функція" -#: describe.c:1124 +#: describe.c:1123 msgid "type" msgstr "тип" -#: describe.c:1126 +#: describe.c:1125 msgid "schema" msgstr "схема" -#: describe.c:1150 +#: describe.c:1149 msgid "Default access privileges" msgstr "Права доступу за замовчуванням" -#: describe.c:1190 +#: describe.c:1189 msgid "Object" msgstr "Об'єкт" -#: describe.c:1204 +#: describe.c:1203 msgid "table constraint" msgstr "обмеження таблиці" -#: describe.c:1226 +#: describe.c:1225 msgid "domain constraint" msgstr "обмеження домену" -#: describe.c:1254 +#: describe.c:1253 msgid "operator class" msgstr "клас операторів" -#: describe.c:1283 +#: describe.c:1282 msgid "operator family" msgstr "сімейство операторів" -#: describe.c:1305 +#: describe.c:1304 msgid "rule" msgstr "правило" -#: describe.c:1347 +#: describe.c:1346 msgid "Object descriptions" msgstr "Опис об'єкту" -#: describe.c:1403 describe.c:3763 +#: describe.c:1402 describe.c:3843 #, c-format msgid "Did not find any relation named \"%s\"." msgstr "Не знайдено жодного відношення під назвою \"%s\"." -#: describe.c:1406 describe.c:3766 +#: describe.c:1405 describe.c:3846 #, c-format msgid "Did not find any relations." msgstr "Не знайдено жодного відношення." -#: describe.c:1661 +#: describe.c:1660 #, c-format msgid "Did not find any relation with OID %s." msgstr "Не знайдено жодного відношення з OID %s." -#: describe.c:1713 describe.c:1737 +#: describe.c:1712 describe.c:1736 msgid "Start" msgstr "Початок" -#: describe.c:1714 describe.c:1738 +#: describe.c:1713 describe.c:1737 msgid "Minimum" msgstr "Мінімум" -#: describe.c:1715 describe.c:1739 +#: describe.c:1714 describe.c:1738 msgid "Maximum" msgstr "Максимум" -#: describe.c:1716 describe.c:1740 +#: describe.c:1715 describe.c:1739 msgid "Increment" msgstr "Приріст" -#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4185 -#: describe.c:4351 describe.c:4465 describe.c:4470 +#: describe.c:1716 describe.c:1740 describe.c:1871 describe.c:4265 +#: describe.c:4431 describe.c:4545 describe.c:4550 describe.c:6099 msgid "yes" msgstr "так" -#: describe.c:1718 describe.c:1742 describe.c:1873 describe.c:4185 -#: describe.c:4348 describe.c:4465 +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4265 +#: describe.c:4428 describe.c:4545 describe.c:6100 msgid "no" msgstr "ні" -#: describe.c:1719 describe.c:1743 +#: describe.c:1718 describe.c:1742 msgid "Cycles?" msgstr "Цикли?" -#: describe.c:1720 describe.c:1744 +#: describe.c:1719 describe.c:1743 msgid "Cache" msgstr "Кеш" -#: describe.c:1787 +#: describe.c:1786 #, c-format msgid "Owned by: %s" msgstr "Власник: %s" -#: describe.c:1791 +#: describe.c:1790 #, c-format msgid "Sequence for identity column: %s" msgstr "Послідовність для стовпця identity: %s" -#: describe.c:1798 +#: describe.c:1797 #, c-format msgid "Sequence \"%s.%s\"" msgstr "Послідовність \"%s.%s\"" -#: describe.c:1934 +#: describe.c:1933 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Таблиця без журналювання \"%s.%s\"" -#: describe.c:1937 +#: describe.c:1936 #, c-format msgid "Table \"%s.%s\"" msgstr "Таблиця \"%s.%s\"" -#: describe.c:1941 +#: describe.c:1940 #, c-format msgid "View \"%s.%s\"" msgstr "Подання \"%s.%s\"" -#: describe.c:1946 +#: describe.c:1945 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Матеріалізоване подання без журналювання \"%s.%s\"" -#: describe.c:1949 +#: describe.c:1948 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Матеріалізоване подання \"%s.%s\"" -#: describe.c:1954 +#: describe.c:1953 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Індекс без журналювання \"%s.%s\"" -#: describe.c:1957 +#: describe.c:1956 #, c-format msgid "Index \"%s.%s\"" msgstr "Індекс \"%s.%s\"" -#: describe.c:1962 +#: describe.c:1961 #, c-format msgid "Unlogged partitioned index \"%s.%s\"" msgstr "Секційний індекс без журналювання \"%s.%s\"" -#: describe.c:1965 +#: describe.c:1964 #, c-format msgid "Partitioned index \"%s.%s\"" msgstr "Секційний індекс \"%s.%s\"" -#: describe.c:1970 +#: describe.c:1969 #, c-format msgid "Special relation \"%s.%s\"" msgstr "Спеціальне відношення \"%s.%s\"" -#: describe.c:1974 +#: describe.c:1973 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "Таблиця TOAST \"%s.%s\"" -#: describe.c:1978 +#: describe.c:1977 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Композитний тип \"%s.%s\"" -#: describe.c:1982 +#: describe.c:1981 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Зовнішня таблиця \"%s.%s\"" -#: describe.c:1987 +#: describe.c:1986 #, c-format msgid "Unlogged partitioned table \"%s.%s\"" msgstr "Секційна таблиця без журналювання \"%s.%s\"" -#: describe.c:1990 +#: describe.c:1989 #, c-format msgid "Partitioned table \"%s.%s\"" msgstr "Секційна таблиця \"%s.%s\"" -#: describe.c:2006 describe.c:4098 +#: describe.c:2005 describe.c:4178 msgid "Collation" msgstr "Сортування" -#: describe.c:2007 describe.c:4105 +#: describe.c:2006 describe.c:4185 msgid "Nullable" msgstr "Обнуляється" -#: describe.c:2008 describe.c:4106 +#: describe.c:2007 describe.c:4186 msgid "Default" msgstr "За замовчуванням" -#: describe.c:2011 +#: describe.c:2010 msgid "Key?" msgstr "Ключ?" -#: describe.c:2013 +#: describe.c:2012 msgid "Definition" msgstr "Визначення" -#: describe.c:2015 describe.c:5216 describe.c:5300 describe.c:5371 -#: describe.c:5435 +#: describe.c:2014 describe.c:5296 describe.c:5380 describe.c:5451 +#: describe.c:5515 msgid "FDW options" msgstr "Налаштування FDW" -#: describe.c:2017 +#: describe.c:2016 msgid "Storage" msgstr "Сховище" -#: describe.c:2019 +#: describe.c:2018 msgid "Stats target" msgstr "Статистична ціль" -#: describe.c:2132 +#: describe.c:2131 #, c-format msgid "Partition of: %s %s" msgstr "Розділ: %s %s" -#: describe.c:2144 +#: describe.c:2143 msgid "No partition constraint" msgstr "Відсутнє розділове обмеження" -#: describe.c:2146 +#: describe.c:2145 #, c-format msgid "Partition constraint: %s" msgstr "Обмеження секції: %s" -#: describe.c:2170 +#: describe.c:2169 #, c-format msgid "Partition key: %s" msgstr "Ключ розділу: %s" -#: describe.c:2240 +#: describe.c:2195 +#, c-format +msgid "Owning table: \"%s.%s\"" +msgstr "Таблиця, що володіє: \"%s.%s\"" + +#: describe.c:2266 msgid "primary key, " msgstr "первинний ключ," -#: describe.c:2242 +#: describe.c:2268 msgid "unique, " msgstr "унікальний," -#: describe.c:2248 +#: describe.c:2274 #, c-format msgid "for table \"%s.%s\"" msgstr "для таблиці \"%s.%s\"" -#: describe.c:2252 +#: describe.c:2278 #, c-format msgid ", predicate (%s)" msgstr ", предикат (%s)" -#: describe.c:2255 +#: describe.c:2281 msgid ", clustered" msgstr ", кластеризовано" -#: describe.c:2258 +#: describe.c:2284 msgid ", invalid" msgstr ", недійсний" -#: describe.c:2261 +#: describe.c:2287 msgid ", deferrable" msgstr ", відтермінований" -#: describe.c:2264 +#: describe.c:2290 msgid ", initially deferred" msgstr ", від початку відтермінований" -#: describe.c:2267 +#: describe.c:2293 msgid ", replica identity" msgstr ", ідентичність репліки" -#: describe.c:2326 +#: describe.c:2360 msgid "Indexes:" msgstr "Індекси:" -#: describe.c:2410 +#: describe.c:2444 msgid "Check constraints:" msgstr "Обмеження перевірки:" -#: describe.c:2478 +#: describe.c:2512 msgid "Foreign-key constraints:" msgstr "Обмеження зовнішнього ключа:" -#: describe.c:2541 +#: describe.c:2575 msgid "Referenced by:" msgstr "Посилання ззовні:" -#: describe.c:2591 +#: describe.c:2625 msgid "Policies:" msgstr "Політики:" -#: describe.c:2594 +#: describe.c:2628 msgid "Policies (forced row security enabled):" msgstr "Політики (посилений захист рядків активовано):" -#: describe.c:2597 +#: describe.c:2631 msgid "Policies (row security enabled): (none)" msgstr "Політики (захист рядків ввімкнуто): (ні)" -#: describe.c:2600 +#: describe.c:2634 msgid "Policies (forced row security enabled): (none)" msgstr "Політики (посилений захист рядків ввімкнуто): (ні)" -#: describe.c:2603 +#: describe.c:2637 msgid "Policies (row security disabled):" msgstr "Політики (захист рядків вимкнуто):" -#: describe.c:2666 +#: describe.c:2705 msgid "Statistics objects:" msgstr "Об'єкти статистики:" -#: describe.c:2775 describe.c:2879 +#: describe.c:2819 describe.c:2923 msgid "Rules:" msgstr "Правила:" -#: describe.c:2778 +#: describe.c:2822 msgid "Disabled rules:" msgstr "Вимкнені правила:" -#: describe.c:2781 +#: describe.c:2825 msgid "Rules firing always:" msgstr "Правила, що завжди працюють:" -#: describe.c:2784 +#: describe.c:2828 msgid "Rules firing on replica only:" msgstr "Правила, що працюють тільки на репліці:" -#: describe.c:2824 +#: describe.c:2868 msgid "Publications:" msgstr "Публікації:" -#: describe.c:2862 +#: describe.c:2906 msgid "View definition:" msgstr "Визначення подання:" -#: describe.c:3001 +#: describe.c:3053 msgid "Triggers:" msgstr "Тригери:" -#: describe.c:3005 +#: describe.c:3057 msgid "Disabled user triggers:" msgstr "Вимкнені користувацькі тригери:" -#: describe.c:3007 +#: describe.c:3059 msgid "Disabled triggers:" msgstr "Вимкнені тригери:" -#: describe.c:3010 +#: describe.c:3062 msgid "Disabled internal triggers:" msgstr "Вимкнені внутрішні тригери:" -#: describe.c:3013 +#: describe.c:3065 msgid "Triggers firing always:" msgstr "Тригери, що завжди працюють:" -#: describe.c:3016 +#: describe.c:3068 msgid "Triggers firing on replica only:" msgstr "Тригери, що працюють тільки на репліці:" -#: describe.c:3075 +#: describe.c:3140 #, c-format msgid "Server: %s" msgstr "Сервер: %s" -#: describe.c:3083 +#: describe.c:3148 #, c-format msgid "FDW options: (%s)" msgstr "Налаштування FDW: (%s)" -#: describe.c:3102 +#: describe.c:3169 msgid "Inherits" msgstr "Успадковує" -#: describe.c:3161 +#: describe.c:3229 #, c-format msgid "Number of partitions: %d" msgstr "Число секцій: %d" -#: describe.c:3170 -#, c-format -msgid "Number of child tables: %d (Use \\d+ to list them.)" -msgstr "Кількість дочірніх таблиць: %d (\\d+ для списку)" - -#: describe.c:3172 +#: describe.c:3238 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "Кількість розділів: %d (\\d+ для списку)" -#: describe.c:3180 +#: describe.c:3240 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "Кількість дочірніх таблиць: %d (\\d+ для списку)" + +#: describe.c:3247 msgid "Child tables" msgstr "Дочірні таблиці" -#: describe.c:3180 +#: describe.c:3247 msgid "Partitions" msgstr "Розділи" -#: describe.c:3223 +#: describe.c:3276 #, c-format msgid "Typed table of type: %s" msgstr "Типізована таблиця типу: %s" -#: describe.c:3239 +#: describe.c:3292 msgid "Replica Identity" msgstr "Ідентичність репліки" -#: describe.c:3252 +#: describe.c:3305 msgid "Has OIDs: yes" msgstr "Має OIDs: так" -#: describe.c:3261 +#: describe.c:3314 #, c-format msgid "Access method: %s" msgstr "Метод доступу: %s" -#: describe.c:3340 +#: describe.c:3394 #, c-format msgid "Tablespace: \"%s\"" msgstr "Табличний простір: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3352 +#: describe.c:3406 #, c-format msgid ", tablespace \"%s\"" msgstr ", табличний простір \"%s\"" -#: describe.c:3445 +#: describe.c:3499 msgid "List of roles" msgstr "Список ролей" -#: describe.c:3447 +#: describe.c:3501 msgid "Role name" msgstr "Ім'я ролі" -#: describe.c:3448 +#: describe.c:3502 msgid "Attributes" msgstr "Атрибути" -#: describe.c:3449 +#: describe.c:3503 msgid "Member of" msgstr "Член" -#: describe.c:3460 +#: describe.c:3514 msgid "Superuser" msgstr "Суперкористувач" -#: describe.c:3463 +#: describe.c:3517 msgid "No inheritance" msgstr "Без успадкування" -#: describe.c:3466 +#: describe.c:3520 msgid "Create role" msgstr "Створити роль" -#: describe.c:3469 +#: describe.c:3523 msgid "Create DB" msgstr "Створити базу даних" -#: describe.c:3472 +#: describe.c:3526 msgid "Cannot login" msgstr "Не може увійти" -#: describe.c:3476 +#: describe.c:3530 msgid "Replication" msgstr "Реплікація" -#: describe.c:3480 +#: describe.c:3534 msgid "Bypass RLS" msgstr "Обхід RLC" -#: describe.c:3489 +#: describe.c:3543 msgid "No connections" msgstr "Без підключень" -#: describe.c:3491 +#: describe.c:3545 #, c-format msgid "%d connection" msgid_plural "%d connections" @@ -1724,539 +1755,635 @@ msgstr[1] "%d підключення" msgstr[2] "%d підключень" msgstr[3] "%d підключення" -#: describe.c:3501 +#: describe.c:3555 msgid "Password valid until " msgstr "Пароль дійнсий до" -#: describe.c:3551 +#: describe.c:3605 #, c-format msgid "The server (version %s) does not support per-database role settings." msgstr "Сервер (версія %s) не підтримує рольові налаштування побазово." -#: describe.c:3564 +#: describe.c:3618 msgid "Role" msgstr "Роль" -#: describe.c:3565 +#: describe.c:3619 msgid "Database" msgstr "База даних" -#: describe.c:3566 +#: describe.c:3620 msgid "Settings" msgstr "Параметри" -#: describe.c:3587 +#: describe.c:3641 #, c-format msgid "Did not find any settings for role \"%s\" and database \"%s\"." msgstr "Не знайдено жодного параметра для ролі \"%s\" і бази даних \"%s\"." -#: describe.c:3590 +#: describe.c:3644 #, c-format msgid "Did not find any settings for role \"%s\"." msgstr "Не знайдено жодного параметру для ролі \"%s\"." -#: describe.c:3593 +#: describe.c:3647 #, c-format msgid "Did not find any settings." msgstr "Не знайдено жодного параметру." -#: describe.c:3598 +#: describe.c:3652 msgid "List of settings" msgstr "Список параметрів" -#: describe.c:3668 +#: describe.c:3723 msgid "index" msgstr "індекс" -#: describe.c:3670 +#: describe.c:3725 msgid "special" msgstr "спеціальний" -#: describe.c:3673 describe.c:3858 +#: describe.c:3728 describe.c:3938 msgid "partitioned index" msgstr "секційний індекс" -#: describe.c:3771 +#: describe.c:3752 +msgid "permanent" +msgstr "постійна" + +#: describe.c:3753 +msgid "temporary" +msgstr "тимчасова" + +#: describe.c:3754 +msgid "unlogged" +msgstr "нежурнальована" + +#: describe.c:3755 +msgid "Persistence" +msgstr "Стійкість" + +#: describe.c:3851 msgid "List of relations" msgstr "Список відношень" -#: describe.c:3819 +#: describe.c:3899 #, c-format msgid "The server (version %s) does not support declarative table partitioning." msgstr "Сервер (версія %s) не підтримує декларативне секціонування таблиць." -#: describe.c:3830 +#: describe.c:3910 msgid "List of partitioned indexes" msgstr "Список секційних індексів" -#: describe.c:3832 +#: describe.c:3912 msgid "List of partitioned tables" msgstr "Список секційних таблиць" -#: describe.c:3836 +#: describe.c:3916 msgid "List of partitioned relations" msgstr "Список секційних відношень" -#: describe.c:3867 +#: describe.c:3947 msgid "Parent name" msgstr "Батьківська назва" -#: describe.c:3880 +#: describe.c:3960 msgid "Leaf partition size" msgstr "Розмір дочірньої секції" -#: describe.c:3883 describe.c:3889 +#: describe.c:3963 describe.c:3969 msgid "Total size" msgstr "Загальний розмір" -#: describe.c:4021 +#: describe.c:4101 msgid "Trusted" msgstr "Надійний" -#: describe.c:4029 +#: describe.c:4109 msgid "Internal language" msgstr "Внутрішня мова" -#: describe.c:4030 +#: describe.c:4110 msgid "Call handler" msgstr "Обробник виклику" -#: describe.c:4031 describe.c:5203 +#: describe.c:4111 describe.c:5283 msgid "Validator" msgstr "Функція перевірки" -#: describe.c:4034 +#: describe.c:4114 msgid "Inline handler" msgstr "Оброблювач впровадженого коду" -#: describe.c:4062 +#: describe.c:4142 msgid "List of languages" msgstr "Список мов" -#: describe.c:4107 +#: describe.c:4187 msgid "Check" msgstr "Перевірка" -#: describe.c:4149 +#: describe.c:4229 msgid "List of domains" msgstr "Список доменів" -#: describe.c:4183 +#: describe.c:4263 msgid "Source" msgstr "Джерело" -#: describe.c:4184 +#: describe.c:4264 msgid "Destination" msgstr "Призначення" -#: describe.c:4186 +#: describe.c:4266 describe.c:6101 msgid "Default?" msgstr "За замовчуванням?" -#: describe.c:4223 +#: describe.c:4303 msgid "List of conversions" msgstr "Список перетворень" -#: describe.c:4262 +#: describe.c:4342 msgid "Event" msgstr "Подія" -#: describe.c:4264 +#: describe.c:4344 msgid "enabled" msgstr "увімкнено" -#: describe.c:4265 +#: describe.c:4345 msgid "replica" msgstr "репліка" -#: describe.c:4266 +#: describe.c:4346 msgid "always" msgstr "завжди" -#: describe.c:4267 +#: describe.c:4347 msgid "disabled" msgstr "вимкнено" -#: describe.c:4268 describe.c:5902 +#: describe.c:4348 describe.c:5997 msgid "Enabled" msgstr "Увімкнено" -#: describe.c:4270 +#: describe.c:4350 msgid "Tags" msgstr "Теги" -#: describe.c:4289 +#: describe.c:4369 msgid "List of event triggers" msgstr "Список тригерів подій" -#: describe.c:4318 +#: describe.c:4398 msgid "Source type" msgstr "Початковий тип" -#: describe.c:4319 +#: describe.c:4399 msgid "Target type" msgstr "Тип цілі" -#: describe.c:4350 +#: describe.c:4430 msgid "in assignment" msgstr "у призначенні" -#: describe.c:4352 +#: describe.c:4432 msgid "Implicit?" msgstr "Приховане?" -#: describe.c:4407 +#: describe.c:4487 msgid "List of casts" msgstr "Список приведення типів" -#: describe.c:4435 +#: describe.c:4515 #, c-format msgid "The server (version %s) does not support collations." msgstr "Сервер (версія %s) не підтримує співставлення." -#: describe.c:4456 describe.c:4460 +#: describe.c:4536 describe.c:4540 msgid "Provider" msgstr "Постачальник" -#: describe.c:4466 describe.c:4471 +#: describe.c:4546 describe.c:4551 msgid "Deterministic?" msgstr "Детермінований?" -#: describe.c:4506 +#: describe.c:4586 msgid "List of collations" msgstr "Список правил сортування" -#: describe.c:4565 +#: describe.c:4645 msgid "List of schemas" msgstr "Список схем" -#: describe.c:4590 describe.c:4837 describe.c:4908 describe.c:4979 +#: describe.c:4670 describe.c:4917 describe.c:4988 describe.c:5059 #, c-format msgid "The server (version %s) does not support full text search." msgstr "Сервер (версія %s) не підтримує повнотекстовий пошук." -#: describe.c:4625 +#: describe.c:4705 msgid "List of text search parsers" msgstr "Список парсерів текстового пошуку" -#: describe.c:4670 +#: describe.c:4750 #, c-format msgid "Did not find any text search parser named \"%s\"." msgstr "Не знайдено жодного парсера текстового пошуку \"%s\"." -#: describe.c:4673 +#: describe.c:4753 #, c-format msgid "Did not find any text search parsers." msgstr "Не знайдено жодного парсера текстового пошуку." -#: describe.c:4748 +#: describe.c:4828 msgid "Start parse" msgstr "Почати розбір" -#: describe.c:4749 +#: describe.c:4829 msgid "Method" msgstr "Метод" -#: describe.c:4753 +#: describe.c:4833 msgid "Get next token" msgstr "Отримати наступний токен" -#: describe.c:4755 +#: describe.c:4835 msgid "End parse" msgstr "Закінчити розбір" -#: describe.c:4757 +#: describe.c:4837 msgid "Get headline" msgstr "Отримати заголовок" -#: describe.c:4759 +#: describe.c:4839 msgid "Get token types" msgstr "Отримати типи токенів" -#: describe.c:4770 +#: describe.c:4850 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Парсер текстового пошуку \"%s.%s\"" -#: describe.c:4773 +#: describe.c:4853 #, c-format msgid "Text search parser \"%s\"" msgstr "Парсер текстового пошуку \"%s\"" -#: describe.c:4792 +#: describe.c:4872 msgid "Token name" msgstr "Ім'я токену" -#: describe.c:4803 +#: describe.c:4883 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Типи токенів для парсера \"%s.%s\"" -#: describe.c:4806 +#: describe.c:4886 #, c-format msgid "Token types for parser \"%s\"" msgstr "Типи токенів для парсера \"%s\"" -#: describe.c:4860 +#: describe.c:4940 msgid "Template" msgstr "Шаблон" -#: describe.c:4861 +#: describe.c:4941 msgid "Init options" msgstr "Параметри ініціалізації" -#: describe.c:4883 +#: describe.c:4963 msgid "List of text search dictionaries" msgstr "Список словників текстового пошуку" -#: describe.c:4926 +#: describe.c:5006 msgid "Init" msgstr "Ініціалізація" -#: describe.c:4927 +#: describe.c:5007 msgid "Lexize" msgstr "Виділення лексем" -#: describe.c:4954 +#: describe.c:5034 msgid "List of text search templates" msgstr "Список шаблонів текстового пошуку" -#: describe.c:5014 +#: describe.c:5094 msgid "List of text search configurations" msgstr "Список конфігурацій текстового пошуку" -#: describe.c:5060 +#: describe.c:5140 #, c-format msgid "Did not find any text search configuration named \"%s\"." msgstr "Не знайдено жодної конфігурації текстового пошуку під назвою \"%s\"." -#: describe.c:5063 +#: describe.c:5143 #, c-format msgid "Did not find any text search configurations." msgstr "Не знайдено жодної конфігурації текствого пошуку." -#: describe.c:5129 +#: describe.c:5209 msgid "Token" msgstr "Токен" -#: describe.c:5130 +#: describe.c:5210 msgid "Dictionaries" msgstr "Словники" -#: describe.c:5141 +#: describe.c:5221 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Конфігурація пошуку тексту \"%s.%s\"" -#: describe.c:5144 +#: describe.c:5224 #, c-format msgid "Text search configuration \"%s\"" msgstr "Конфігурація пошуку тексту \"%s\"" -#: describe.c:5148 +#: describe.c:5228 #, c-format msgid "\n" "Parser: \"%s.%s\"" msgstr "\n" "Парсер: \"%s.%s\"" -#: describe.c:5151 +#: describe.c:5231 #, c-format msgid "\n" "Parser: \"%s\"" msgstr "\n" "Парсер: \"%s\"" -#: describe.c:5185 +#: describe.c:5265 #, c-format msgid "The server (version %s) does not support foreign-data wrappers." msgstr "Сервер (версія %s) не підтримує джерела сторонніх даних." -#: describe.c:5243 +#: describe.c:5323 msgid "List of foreign-data wrappers" msgstr "Список джерел сторонніх даних" -#: describe.c:5268 +#: describe.c:5348 #, c-format msgid "The server (version %s) does not support foreign servers." msgstr "Сервер (версія %s) не підтримує сторонні сервери." -#: describe.c:5281 +#: describe.c:5361 msgid "Foreign-data wrapper" msgstr "Джерело сторонніх даних" -#: describe.c:5299 describe.c:5504 +#: describe.c:5379 describe.c:5584 msgid "Version" msgstr "Версія" -#: describe.c:5325 +#: describe.c:5405 msgid "List of foreign servers" msgstr "Список сторонніх серверів" -#: describe.c:5350 +#: describe.c:5430 #, c-format msgid "The server (version %s) does not support user mappings." msgstr "Сервер (версія %s) не підтримує зіставлення користувачів." -#: describe.c:5360 describe.c:5424 +#: describe.c:5440 describe.c:5504 msgid "Server" msgstr "Сервер" -#: describe.c:5361 +#: describe.c:5441 msgid "User name" msgstr "Ім'я користувача" -#: describe.c:5386 +#: describe.c:5466 msgid "List of user mappings" msgstr "Список зіставлень користувачів" -#: describe.c:5411 +#: describe.c:5491 #, c-format msgid "The server (version %s) does not support foreign tables." msgstr "Сервер (версія %s) не підтримує сторонні таблиці." -#: describe.c:5464 +#: describe.c:5544 msgid "List of foreign tables" msgstr "Список сторонніх таблиць" -#: describe.c:5489 describe.c:5546 +#: describe.c:5569 describe.c:5626 #, c-format msgid "The server (version %s) does not support extensions." msgstr "Сервер (версія %s) не підтримує розширення." -#: describe.c:5521 +#: describe.c:5601 msgid "List of installed extensions" msgstr "Список встановлених розширень" -#: describe.c:5574 +#: describe.c:5654 #, c-format msgid "Did not find any extension named \"%s\"." msgstr "Не знайдено жодного розширення під назвою \"%s\"." -#: describe.c:5577 +#: describe.c:5657 #, c-format msgid "Did not find any extensions." msgstr "Не знайдено жодного розширення." -#: describe.c:5621 +#: describe.c:5701 msgid "Object description" msgstr "Опис об'єкту" -#: describe.c:5631 +#: describe.c:5711 #, c-format msgid "Objects in extension \"%s\"" msgstr "Об'єкти в розширенні \"%s\"" -#: describe.c:5660 describe.c:5731 +#: describe.c:5740 describe.c:5816 #, c-format msgid "The server (version %s) does not support publications." msgstr "Сервер (версія %s) не підтримує публікації." -#: describe.c:5677 describe.c:5803 +#: describe.c:5757 describe.c:5894 msgid "All tables" msgstr "Усі таблиці" -#: describe.c:5678 describe.c:5804 +#: describe.c:5758 describe.c:5895 msgid "Inserts" msgstr "Вставки" -#: describe.c:5679 describe.c:5805 +#: describe.c:5759 describe.c:5896 msgid "Updates" msgstr "Оновлення" -#: describe.c:5680 describe.c:5806 +#: describe.c:5760 describe.c:5897 msgid "Deletes" msgstr "Видалення" -#: describe.c:5684 describe.c:5808 +#: describe.c:5764 describe.c:5899 msgid "Truncates" msgstr "Очищення" -#: describe.c:5701 +#: describe.c:5768 describe.c:5901 +msgid "Via root" +msgstr "Через root" + +#: describe.c:5785 msgid "List of publications" msgstr "Список публікацій" -#: describe.c:5769 +#: describe.c:5858 #, c-format msgid "Did not find any publication named \"%s\"." msgstr "Не знайдено жодної публікації під назвою \"%s\"." -#: describe.c:5772 +#: describe.c:5861 #, c-format msgid "Did not find any publications." msgstr "Не знайдено жодної публікації." -#: describe.c:5799 +#: describe.c:5890 #, c-format msgid "Publication %s" msgstr "Публікація %s" -#: describe.c:5843 +#: describe.c:5938 msgid "Tables:" msgstr "Таблиці:" -#: describe.c:5887 +#: describe.c:5982 #, c-format msgid "The server (version %s) does not support subscriptions." msgstr "Сервер (версія %s) не підтримує підписки." -#: describe.c:5903 +#: describe.c:5998 msgid "Publication" msgstr "Публікація" -#: describe.c:5910 +#: describe.c:6005 msgid "Synchronous commit" msgstr "Синхронні затвердження" -#: describe.c:5911 +#: describe.c:6006 msgid "Conninfo" msgstr "Conninfo" -#: describe.c:5933 +#: describe.c:6028 msgid "List of subscriptions" msgstr "Список підписок" -#: help.c:74 +#: describe.c:6095 describe.c:6184 describe.c:6270 describe.c:6353 +msgid "AM" +msgstr "АМ" + +#: describe.c:6096 +msgid "Input type" +msgstr "Тип вводу" + +#: describe.c:6097 +msgid "Storage type" +msgstr "Тип сховища" + +#: describe.c:6098 +msgid "Operator class" +msgstr "Клас операторів" + +#: describe.c:6110 describe.c:6185 describe.c:6271 describe.c:6354 +msgid "Operator family" +msgstr "Сімейство операторів" + +#: describe.c:6143 +msgid "List of operator classes" +msgstr "Список класів операторів" + +#: describe.c:6186 +msgid "Applicable types" +msgstr "Типи для застосування" + +#: describe.c:6225 +msgid "List of operator families" +msgstr "Список сімейств операторів" + +#: describe.c:6272 +msgid "Operator" +msgstr "Оператор" + +#: describe.c:6273 +msgid "Strategy" +msgstr "Стратегія" + +#: describe.c:6274 +msgid "ordering" +msgstr "упорядкування" + +#: describe.c:6275 +msgid "search" +msgstr "пошук" + +#: describe.c:6276 +msgid "Purpose" +msgstr "Ціль" + +#: describe.c:6281 +msgid "Sort opfamily" +msgstr "Сімейство операторів сортування" + +#: describe.c:6312 +msgid "List of operators of operator families" +msgstr "Список операторів сімейств операторів" + +#: describe.c:6355 +msgid "Registered left type" +msgstr "Зареєстрований лівий тип" + +#: describe.c:6356 +msgid "Registered right type" +msgstr "Зареєстрований правий тип" + +#: describe.c:6357 +msgid "Number" +msgstr "Число" + +#: describe.c:6393 +msgid "List of support functions of operator families" +msgstr "Список функцій підтримки сімейств операторів" + +#: help.c:73 #, c-format msgid "psql is the PostgreSQL interactive terminal.\n\n" msgstr "psql - це інтерактивний термінал PostgreSQL.\n\n" -#: help.c:75 help.c:349 help.c:425 help.c:468 +#: help.c:74 help.c:355 help.c:431 help.c:474 #, c-format msgid "Usage:\n" msgstr "Використання:\n" -#: help.c:76 +#: help.c:75 #, c-format msgid " psql [OPTION]... [DBNAME [USERNAME]]\n\n" msgstr " psql [ОПЦІЯ]... [БД [КОРИСТУВАЧ]]\n\n" -#: help.c:78 +#: help.c:77 #, c-format msgid "General options:\n" msgstr "Основні налаштування:\n" -#: help.c:83 +#: help.c:82 #, c-format msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" msgstr " -c, --command=КОМАНДА виконати лише одну команду (SQL або внутрішню) і вийти\n" -#: help.c:84 +#: help.c:83 #, c-format msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" msgstr " -d, --dbname=DBNAME ім'я бази даних для підключення (за замовчання: \"%s\") \n" -#: help.c:85 +#: help.c:84 #, c-format msgid " -f, --file=FILENAME execute commands from file, then exit\n" msgstr " -f, --file=FILENAME виконує команди з файлу, потім виходить\n" -#: help.c:86 +#: help.c:85 #, c-format msgid " -l, --list list available databases, then exit\n" msgstr " -l, --list виводить список доступних баз даних, потім виходить\n" -#: help.c:87 +#: help.c:86 #, c-format msgid " -v, --set=, --variable=NAME=VALUE\n" " set psql variable NAME to VALUE\n" @@ -2265,113 +2392,113 @@ msgstr " -v, --set=, --variable=NAME=VALUE\n" " присвоїти змінній psql NAME значення VALUE\n" " (наприклад, -v ON_ERROR_STOP=1)\n" -#: help.c:90 +#: help.c:89 #, c-format msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version вивести інофрмацію про версію, потім вийти\n" +msgstr " -V, --version вивести інформацію про версію, потім вийти\n" -#: help.c:91 +#: help.c:90 #, c-format msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" msgstr " -X, --no-psqlrc ігнорувати файл параметрів запуска (~/.psqlrc)\n" -#: help.c:92 +#: help.c:91 #, c-format msgid " -1 (\"one\"), --single-transaction\n" " execute as a single transaction (if non-interactive)\n" msgstr " -1 (\"один\"), --single-transaction\n" " виконує як одну транзакцію (якщо не інтерактивна)\n" -#: help.c:94 +#: help.c:93 #, c-format msgid " -?, --help[=options] show this help, then exit\n" msgstr " -?, --help [=options] показати цю довідку, потім вийти\n" -#: help.c:95 +#: help.c:94 #, c-format msgid " --help=commands list backslash commands, then exit\n" msgstr " --help=commands перерахувати команди, потім вийти\n" -#: help.c:96 +#: help.c:95 #, c-format msgid " --help=variables list special variables, then exit\n" msgstr " --help=variables перерахувати спеціальні змінні, потім вийти\n" -#: help.c:98 +#: help.c:97 #, c-format msgid "\n" "Input and output options:\n" msgstr "\n" "Параметри вводу і виводу:\n" -#: help.c:99 +#: help.c:98 #, c-format msgid " -a, --echo-all echo all input from script\n" msgstr " -a, --echo-all відобразити всі вхідні дані з скрипта\n" -#: help.c:100 +#: help.c:99 #, c-format msgid " -b, --echo-errors echo failed commands\n" msgstr " -b, --echo-errors відобразити команди з помилками\n" -#: help.c:101 +#: help.c:100 #, c-format msgid " -e, --echo-queries echo commands sent to server\n" msgstr " -e, --echo-queries відобразити команди, відправлені на сервер\n" -#: help.c:102 +#: help.c:101 #, c-format msgid " -E, --echo-hidden display queries that internal commands generate\n" msgstr " -E, --echo-hidden відобразити запити, згенеровані внутрішніми командами\n" -#: help.c:103 +#: help.c:102 #, c-format msgid " -L, --log-file=FILENAME send session log to file\n" msgstr " -L, --log-file=FILENAME зберегти протокол роботи у файл\n" -#: help.c:104 +#: help.c:103 #, c-format msgid " -n, --no-readline disable enhanced command line editing (readline)\n" msgstr " -n, --no-readline вимкнути розширене редагування командного рядка (readline)\n" -#: help.c:105 +#: help.c:104 #, c-format msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" msgstr " -o, --output=FILENAME надсилати результати запиту до файлу (або до каналу |)\n" -#: help.c:106 +#: help.c:105 #, c-format msgid " -q, --quiet run quietly (no messages, only query output)\n" msgstr " -q, --quiet тихий запуск (ніяких повідомлень, лише результат запитів)\n" -#: help.c:107 +#: help.c:106 #, c-format msgid " -s, --single-step single-step mode (confirm each query)\n" msgstr " -s, --single-step покроковий режим (підтвердження кожного запиту)\n" -#: help.c:108 +#: help.c:107 #, c-format msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" msgstr " -S, --single-line однорядковий режим (кінець рядка завершує команду)\n" -#: help.c:110 +#: help.c:109 #, c-format msgid "\n" "Output format options:\n" msgstr "\n" "Параметри формату виводу:\n" -#: help.c:111 +#: help.c:110 #, c-format msgid " -A, --no-align unaligned table output mode\n" msgstr " -A, --no-align режим виводу не вирівняної таблиці\n" -#: help.c:112 +#: help.c:111 #, c-format msgid " --csv CSV (Comma-Separated Values) table output mode\n" msgstr " --csv режим виводу таблиць CSV (Comma-Separated Values)\n" -#: help.c:113 +#: help.c:112 #, c-format msgid " -F, --field-separator=STRING\n" " field separator for unaligned output (default: \"%s\")\n" @@ -2379,17 +2506,17 @@ msgstr " -F, --field-separator=СТРОКА\n" " розділювач полів при не вирівняному виводі\n" " (за замовчуванням: \"%s\")\n" -#: help.c:116 +#: help.c:115 #, c-format msgid " -H, --html HTML table output mode\n" msgstr " -H, --html вивід таблиці у форматі HTML\n" -#: help.c:117 +#: help.c:116 #, c-format msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" msgstr " -P, --pset=VAR[=ARG] встановити параметр виводу змінної VAR значенню ARG (див. команду \"\\pset\")\n" -#: help.c:118 +#: help.c:117 #, c-format msgid " -R, --record-separator=STRING\n" " record separator for unaligned output (default: newline)\n" @@ -2397,72 +2524,72 @@ msgstr " -R, --record-separator=СТРОКА\n" " розділювач записів при не вирівняному виводі\n" " (за замовчуванням: новий рядок)\n" -#: help.c:120 +#: help.c:119 #, c-format msgid " -t, --tuples-only print rows only\n" msgstr " -t, --tuples-only виводити лише рядки\n" -#: help.c:121 +#: help.c:120 #, c-format msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" msgstr " -T, --table-attr=ТЕКСТ встановити атрибути HTML-таблиці (width, border)\n" -#: help.c:122 +#: help.c:121 #, c-format msgid " -x, --expanded turn on expanded table output\n" msgstr " -x, --expanded ввімкнути розширене виведення таблиці\n" -#: help.c:123 +#: help.c:122 #, c-format msgid " -z, --field-separator-zero\n" " set field separator for unaligned output to zero byte\n" msgstr " -z, --field-separator-zero\n" " встановити розділювач полів для не вирівняного виводу в нульовий байт\n" -#: help.c:125 +#: help.c:124 #, c-format msgid " -0, --record-separator-zero\n" " set record separator for unaligned output to zero byte\n" msgstr " -0, --record-separator-zero\n" " встановити розділювач записів для не вирівняного виводу в нульовий байт\n" -#: help.c:128 +#: help.c:127 #, c-format msgid "\n" "Connection options:\n" msgstr "\n" "Налаштування з'єднання:\n" -#: help.c:131 +#: help.c:130 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" msgstr " -h, --host=HOSTNAME хост сервера бази даних або каталог сокетів (за замовчуванням: \"%s)\n" -#: help.c:132 +#: help.c:131 msgid "local socket" msgstr "локальний сокет" -#: help.c:135 +#: help.c:134 #, c-format msgid " -p, --port=PORT database server port (default: \"%s\")\n" msgstr " -p, --port=PORT порт сервера бази даних (за замовчуванням: \"%s\")\n" -#: help.c:141 +#: help.c:140 #, c-format msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" msgstr " -U, --username=USERNAME ім'я користувача бази даних (за змовчуванням: \"%s\")\n" -#: help.c:142 +#: help.c:141 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password ніколи не запитувати пароль\n" -#: help.c:143 +#: help.c:142 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password запитувати пароль завжди (повинно траплятись автоматично)\n" -#: help.c:145 +#: help.c:144 #, c-format msgid "\n" "For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" @@ -2471,10 +2598,15 @@ msgid "\n" msgstr "\n" "Щоб дізнатися більше, введіть \"\\?\" (для внутрішніх команд) або \"\\help\"(для команд SQL) в psql, або звіртеся з розділом psql документації PostgreSQL. \n\n" +#: help.c:147 +#, c-format +msgid "Report bugs to <%s>.\n" +msgstr "Повідомляти про помилки на <%s>.\n" + #: help.c:148 #, c-format -msgid "Report bugs to .\n" -msgstr "Про помилки повідомляйте на .\n" +msgid "%s home page: <%s>\n" +msgstr "Домашня сторінка %s: <%s>\n" #: help.c:174 #, c-format @@ -2498,420 +2630,447 @@ msgstr " \\errverbose вивести максимально докл #: help.c:178 #, c-format -msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" -msgstr " \\g [FILE] or ; виконати запит (та надіслати результати до файлу або до каналу |)\n" +msgid " \\g [(OPTIONS)] [FILE] execute query (and send results to file or |pipe);\n" +" \\g with no arguments is equivalent to a semicolon\n" +msgstr " \\g [(OPTIONS)] [FILE] виконати запит (і надіслати результати до файлу або |каналу);\n" +" \\g без аргументів рівнозначно крапці з комою\n" -#: help.c:179 +#: help.c:180 #, c-format msgid " \\gdesc describe result of query, without executing it\n" msgstr " \\gdesc описати результат запиту без виконання\n" -#: help.c:180 +#: help.c:181 #, c-format msgid " \\gexec execute query, then execute each value in its result\n" msgstr " \\gexec виконати запит, потім виконати кожне значення в його результаті\n" -#: help.c:181 +#: help.c:182 #, c-format msgid " \\gset [PREFIX] execute query and store results in psql variables\n" msgstr " \\gset [PREFIX] виконати запит та зберегти результати в змінних psql \n" -#: help.c:182 +#: help.c:183 #, c-format -msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" -msgstr " \\gx [FILE] те саме, що й \"\\g\", але в режимі розширеного виводу\n" +msgid " \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [(OPTIONS)] [FILE] як \\g, але вмикає розширений режим виводу\n" -#: help.c:183 +#: help.c:184 #, c-format msgid " \\q quit psql\n" msgstr " \\q вийти з psql\n" -#: help.c:184 +#: help.c:185 #, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEC] виконувати запит кожні SEC секунд\n" -#: help.c:187 +#: help.c:188 #, c-format msgid "Help\n" msgstr "Довідка\n" -#: help.c:189 +#: help.c:190 #, c-format msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [commands] показати довідку по командах з \\\n" -#: help.c:190 +#: help.c:191 #, c-format msgid " \\? options show help on psql command-line options\n" msgstr " \\? options показати довідку по параметрах командного рядку psql\n" -#: help.c:191 +#: help.c:192 #, c-format msgid " \\? variables show help on special variables\n" msgstr " \\? variables показати довідку по спеціальних змінних\n" -#: help.c:192 +#: help.c:193 #, c-format msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" msgstr " \\h [NAME] довідка з синтаксису команд SQL, * для всіх команд\n" -#: help.c:195 +#: help.c:196 #, c-format msgid "Query Buffer\n" msgstr "Буфер запитів\n" -#: help.c:196 +#: help.c:197 #, c-format msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" msgstr " \\e [FILE] [LINE] редагувати буфер запитів (або файл) зовнішнім редактором\n" -#: help.c:197 +#: help.c:198 #, c-format msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr " \\ef [FUNCNAME [LINE]] редагувати визначення функції зовнішнім редактором\n" -#: help.c:198 +#: help.c:199 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr " \\ev [VIEWNAME [LINE]] редагувати визначення подання зовнішнім редактором\n" -#: help.c:199 +#: help.c:200 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p показати вміст буфера запитів\n" -#: help.c:200 +#: help.c:201 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r скинути (очистити) буфер запитів\n" -#: help.c:202 +#: help.c:203 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr " \\s [FILE] відобразити історію або зберегти її до файлу\n" -#: help.c:204 +#: help.c:205 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr " \\w FILE писати буфер запитів до файлу\n" -#: help.c:207 +#: help.c:208 #, c-format msgid "Input/Output\n" msgstr "Ввід/Вивід\n" -#: help.c:208 +#: help.c:209 #, c-format msgid " \\copy ... perform SQL COPY with data stream to the client host\n" msgstr " \\copy ... виконати команду SQL COPY з потоком даних на клієнтський хост\n" -#: help.c:209 +#: help.c:210 #, c-format -msgid " \\echo [STRING] write string to standard output\n" -msgstr " \\echo [STRING] вивести рядок на стандартний вивід\n" +msgid " \\echo [-n] [STRING] write string to standard output (-n for no newline)\n" +msgstr " \\echo [-n] [STRING] записати рядок до стандартного виводу (-n для пропуску нового рядка)\n" -#: help.c:210 +#: help.c:211 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i FILE виконати команди з файлу\n" -#: help.c:211 +#: help.c:212 #, c-format msgid " \\ir FILE as \\i, but relative to location of current script\n" msgstr " \\ir ФАЙЛ те саме, що \\i, але відносно розташування поточного сценарію\n" -#: help.c:212 +#: help.c:213 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr " \\o [FILE] надсилати всі результати запитів до файлу або до каналу |\n" -#: help.c:213 +#: help.c:214 #, c-format -msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" -msgstr " \\qecho [STRING] вивести рядок до потоку виводу запитів (див. \\o)\n" +msgid " \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n" +msgstr " \\qecho [-n] [STRING] записати рядок до вихідного потоку \\o (-n для пропуску нового рядка)\n" -#: help.c:216 +#: help.c:215 +#, c-format +msgid " \\warn [-n] [STRING] write string to standard error (-n for no newline)\n" +msgstr " \\warn [-n] [STRING] записати рядок до стандартної помилки (-n для пропуску нового рядка)\n" + +#: help.c:218 #, c-format msgid "Conditional\n" msgstr "Умовний\n" -#: help.c:217 +#: help.c:219 #, c-format msgid " \\if EXPR begin conditional block\n" msgstr " \\if EXPR початок умовного блоку\n" -#: help.c:218 +#: help.c:220 #, c-format msgid " \\elif EXPR alternative within current conditional block\n" msgstr " \\elif EXPR альтернатива в рамках поточного блоку\n" -#: help.c:219 +#: help.c:221 #, c-format msgid " \\else final alternative within current conditional block\n" msgstr " \\else остаточна альтернатива в рамках поточного умовного блоку\n" -#: help.c:220 +#: help.c:222 #, c-format msgid " \\endif end conditional block\n" msgstr " \\endif кінець умовного блоку\n" -#: help.c:223 +#: help.c:225 #, c-format msgid "Informational\n" msgstr "Інформаційний\n" -#: help.c:224 +#: help.c:226 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (параметри: S = показати системні об'єкти, + = додаткові деталі)\n" -#: help.c:225 +#: help.c:227 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] вивести таблиці, подання і послідовності\n" -#: help.c:226 +#: help.c:228 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr " \\d[S+] NAME описати таблицю, подання, послідовність або індекс\n" -#: help.c:227 +#: help.c:229 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [PATTERN] вивести агрегати\n" -#: help.c:228 +#: help.c:230 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [PATTERN] вивести методи доступу\n" -#: help.c:229 +#: help.c:231 +#, c-format +msgid " \\dAc[+] [AMPTRN [TYPEPTRN]] list operator classes\n" +msgstr " \\dAc[+] [AMPTRN [TYPEPTRN]] список класів операторів\n" + +#: help.c:232 +#, c-format +msgid " \\dAf[+] [AMPTRN [TYPEPTRN]] list operator families\n" +msgstr " \\dAf[+] [AMPTRN [TYPEPTRN]] список сімейств операторів\n" + +#: help.c:233 +#, c-format +msgid " \\dAo[+] [AMPTRN [OPFPTRN]] list operators of operator families\n" +msgstr " \\dAo[+] [AMPTRN [OPFPTRN]] список операторів сімейств операторів\n" + +#: help.c:234 +#, c-format +msgid " \\dAp [AMPTRN [OPFPTRN]] list support functions of operator families\n" +msgstr " \\dAp [AMPTRN [OPFPTRN]] список функцій підтримки сімейств операторів\n" + +#: help.c:235 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [PATTERN] вивести табличні простори\n" -#: help.c:230 +#: help.c:236 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [PATTERN] вивести перетворення\n" -#: help.c:231 +#: help.c:237 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [PATTERN] вивести приведення типів\n" -#: help.c:232 +#: help.c:238 #, c-format msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr " \\dd[S] [PATTERN] показати опис об'єкта, що не відображається в іншому місці\n" -#: help.c:233 +#: help.c:239 #, c-format msgid " \\dD[S+] [PATTERN] list domains\n" msgstr " \\dD[S+] [PATTERN] вивести домени\n" -#: help.c:234 +#: help.c:240 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" msgstr " \\ddp [PATTERN] вивести привілеї за замовчуванням\n" -#: help.c:235 +#: help.c:241 #, c-format msgid " \\dE[S+] [PATTERN] list foreign tables\n" msgstr " \\dE[S+] [PATTERN] вивести зовнішні таблиці\n" -#: help.c:236 +#: help.c:242 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\dE[S+] [PATTERN] вивести зовнішні таблиці\n" -#: help.c:237 +#: help.c:243 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [PATTERN] вивести зовнішні сервери\n" -#: help.c:238 +#: help.c:244 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [PATTERN] вивести користувацькі зіставлення\n" -#: help.c:239 +#: help.c:245 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [PATTERN] список джерел сторонніх даних\n" -#: help.c:240 +#: help.c:246 #, c-format msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" msgstr " \\df[anptw][S+] [PATRN] вивести [тільки аггрегатні/нормальні/процедурні/тригерні/віконні] функції\n" -#: help.c:241 +#: help.c:247 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr " \\dF[+] [PATTERN] вивести конфігурації текстового пошуку\n" -#: help.c:242 +#: help.c:248 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [PATTERN] вивести словники текстового пошуку\n" -#: help.c:243 +#: help.c:249 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [PATTERN] вивести парсери текстового пошуку\n" -#: help.c:244 +#: help.c:250 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [PATTERN] вивести шаблони текстового пошуку\n" -#: help.c:245 +#: help.c:251 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [PATTERN] вивести ролі\n" -#: help.c:246 +#: help.c:252 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [PATTERN] вивести індекси\n" -#: help.c:247 +#: help.c:253 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr " \\dl вивести великі об'єкти, те саме, що \\lo_list\n" -#: help.c:248 +#: help.c:254 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [PATTERN] вивести процедурні мови\n" -#: help.c:249 +#: help.c:255 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [PATTERN] вивести матеріалізовані подання\n" -#: help.c:250 +#: help.c:256 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [PATTERN] вивести схеми\n" -#: help.c:251 +#: help.c:257 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [PATTERN] вивести оператори\n" -#: help.c:252 +#: help.c:258 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S+] [PATTERN] вивести правила сортування\n" -#: help.c:253 +#: help.c:259 #, c-format msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" msgstr " \\dp [PATTERN] вивести привілеї доступу до таблиць, подань або послідновностей \n" -#: help.c:254 +#: help.c:260 #, c-format msgid " \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n" msgstr " \\dP[itn+] [PATTERN] вивести [тільки індекс/таблицю] секційні відношення [n=вкладені]\n" -#: help.c:255 +#: help.c:261 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [PATRN1 [PATRN2]] вивести налаштування ролей побазово\n" -#: help.c:256 +#: help.c:262 #, c-format msgid " \\dRp[+] [PATTERN] list replication publications\n" msgstr " \\dRp[+] [PATTERN] вивести реплікаційні публікації\n" -#: help.c:257 +#: help.c:263 #, c-format msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" msgstr " \\dRs[+] [PATTERN] вивести реплікаційні підписки\n" -#: help.c:258 +#: help.c:264 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [PATTERN] вивести послідовності\n" -#: help.c:259 +#: help.c:265 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [PATTERN] вивести таблиці\n" -#: help.c:260 +#: help.c:266 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [PATTERN] вивести типи даних\n" -#: help.c:261 +#: help.c:267 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [PATTERN] вивести ролі\n" -#: help.c:262 +#: help.c:268 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [PATTERN] вивести подання\n" -#: help.c:263 +#: help.c:269 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [PATTERN] вивести розширення\n" -#: help.c:264 +#: help.c:270 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [PATTERN] вивести тригери подій\n" -#: help.c:265 +#: help.c:271 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [PATTERN] вивести бази даних\n" -#: help.c:266 +#: help.c:272 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] FUNCNAME відобразити визначення функції\n" -#: help.c:267 +#: help.c:273 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] VIEWNAME відобразити визначення подання\n" -#: help.c:268 +#: help.c:274 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [PATTERN] те саме, що \\dp\n" -#: help.c:271 +#: help.c:277 #, c-format msgid "Formatting\n" msgstr "Форматування\n" -#: help.c:272 +#: help.c:278 #, c-format msgid " \\a toggle between unaligned and aligned output mode\n" msgstr " \\a перемикання між режимами виводу: unaligned, aligned\n" -#: help.c:273 +#: help.c:279 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr " \\C [STRING] встановити заголовок таблиці або прибрати, якщо не задано\n" -#: help.c:274 +#: help.c:280 #, c-format msgid " \\f [STRING] show or set field separator for unaligned query output\n" msgstr " \\f [STRING] показати або встановити розділювач полів для не вирівняного виводу запиту\n" -#: help.c:275 +#: help.c:281 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H переключити режим виводу HTML (поточний: %s)\n" -#: help.c:277 +#: help.c:283 #, c-format msgid " \\pset [NAME [VALUE]] set table output option\n" " (border|columns|csv_fieldsep|expanded|fieldsep|\n" @@ -2928,104 +3087,104 @@ msgstr " \\pset [NAME [VALUE]] встановити параметр виво " unicode_border_linestyle|unicode_column_linestyle|\n" " unicode_header_linestyle)\n" -#: help.c:284 +#: help.c:290 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] показувати лише рядки (поточно %s)\n" -#: help.c:286 +#: help.c:292 #, c-format msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" msgstr " \\T [STRING] встановити атрибути для HTML
або прибрати, якщо не задані\n" -#: help.c:287 +#: help.c:293 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] переключити розширений вивід (поточний: %s)\n" -#: help.c:291 +#: help.c:297 #, c-format msgid "Connection\n" msgstr "Підключення\n" -#: help.c:293 +#: help.c:299 #, c-format msgid " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connect to new database (currently \"%s\")\n" msgstr " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo} під'єднатися до нової бази даних (поточно \"%s\")\n" -#: help.c:297 +#: help.c:303 #, c-format msgid " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connect to new database (currently no connection)\n" msgstr " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo} під'єднатися до нової бази даних (зараз з'єднання відсутнє)\n" -#: help.c:299 +#: help.c:305 #, c-format msgid " \\conninfo display information about current connection\n" msgstr " \\conninfo показати інформацію про поточне з'єднання\n" -#: help.c:300 +#: help.c:306 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [ENCODING] показати або встановити кодування клієнта\n" -#: help.c:301 +#: help.c:307 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr " \\password [USERNAME] безпечно змінити пароль користувача \n" -#: help.c:304 +#: help.c:310 #, c-format msgid "Operating System\n" msgstr "Операційна система\n" -#: help.c:305 +#: help.c:311 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [DIR] змінити поточний робочий каталог\n" -#: help.c:306 +#: help.c:312 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NAME [VALUE] встановити або скинути змінну середовища\n" -#: help.c:307 +#: help.c:313 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr " \\timing [on|off] переключити таймер команд (поточний: %s)\n" -#: help.c:309 +#: help.c:315 #, c-format msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" msgstr " \\! [COMMAND] виконати команду в оболонці або запустити інтерактивну оболонку\n" -#: help.c:312 +#: help.c:318 #, c-format msgid "Variables\n" msgstr "Змінні\n" -#: help.c:313 +#: help.c:319 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr " \\prompt [TEXT] NAME запитати користувача значення внутрішньої змінної\n" -#: help.c:314 +#: help.c:320 #, c-format msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" msgstr " \\set [NAME [VALUE]] встановити внутрішню змінну або вивести всі, якщо не задані параметри\n" -#: help.c:315 +#: help.c:321 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset NAME скинути (видалити) значення внутрішньої змінної\n" -#: help.c:318 +#: help.c:324 #, c-format msgid "Large Objects\n" msgstr "Великі об'єкти\n" -#: help.c:319 +#: help.c:325 #, c-format msgid " \\lo_export LOBOID FILE\n" " \\lo_import FILE [COMMENT]\n" @@ -3036,31 +3195,31 @@ msgstr " \\lo_export LOBOID FILE\n" " \\lo_list\n" " \\lo_unlink LOBOID операції з великими об'єктами\n" -#: help.c:346 +#: help.c:352 #, c-format msgid "List of specially treated variables\n\n" msgstr "Список спеціальних змінних\n\n" -#: help.c:348 +#: help.c:354 #, c-format msgid "psql variables:\n" msgstr "змінні psql:\n" -#: help.c:350 +#: help.c:356 #, c-format msgid " psql --set=NAME=VALUE\n" " or \\set NAME VALUE inside psql\n\n" msgstr " psql --set=ІМ'Я=ЗНАЧЕННЯ\n" " або \\set ІМ'Я ЗНАЧЕННЯ усередині psql\n\n" -#: help.c:352 +#: help.c:358 #, c-format msgid " AUTOCOMMIT\n" " if set, successful SQL commands are automatically committed\n" msgstr " AUTOCOMMIT\n" " якщо встановлений, успішні SQL-команди підтверджуються автоматично\n" -#: help.c:354 +#: help.c:360 #, c-format msgid " COMP_KEYWORD_CASE\n" " determines the case used to complete SQL key words\n" @@ -3069,20 +3228,20 @@ msgstr " COMP_KEYWORD_CASE\n" " визначає регістр для автодоповнення ключових слів SQL\n" " [lower, upper, preserve-lower, preserve-upper]\n" -#: help.c:357 +#: help.c:363 #, c-format msgid " DBNAME\n" " the currently connected database name\n" msgstr " DBNAME назва під'єднаної бази даних\n" -#: help.c:359 +#: help.c:365 #, c-format msgid " ECHO\n" " controls what input is written to standard output\n" " [all, errors, none, queries]\n" msgstr " ECHO контролює ввід, що виводиться на стандартний вивід [all, errors, none, queries]\n" -#: help.c:362 +#: help.c:368 #, c-format msgid " ECHO_HIDDEN\n" " if set, display internal queries executed by backslash commands;\n" @@ -3091,71 +3250,71 @@ msgstr " ECHO_HIDDEN\n" " якщо ввімкнено, виводить внутрішні запити, виконані за допомогою \"\\\";\n" " якщо встановлено значення \"noexec\", тільки виводяться, але не виконуються\n" -#: help.c:365 +#: help.c:371 #, c-format msgid " ENCODING\n" " current client character set encoding\n" msgstr " ENCODING\n" " поточне кодування набору символів клієнта\n" -#: help.c:367 +#: help.c:373 #, c-format msgid " ERROR\n" " true if last query failed, else false\n" msgstr " ERROR\n" " істина, якщо в останньому запиті є помилка, в іншому разі - хибність\n" -#: help.c:369 +#: help.c:375 #, c-format msgid " FETCH_COUNT\n" " the number of result rows to fetch and display at a time (0 = unlimited)\n" msgstr " FETCH_COUNT\n" " число рядків з результатами для передачі та відображення за один раз (0 = необмежено)\n" -#: help.c:371 +#: help.c:377 #, c-format msgid " HIDE_TABLEAM\n" " if set, table access methods are not displayed\n" msgstr " HIDE_TABLEAM\n" " якщо вказано, методи доступу до таблиць не відображаються\n" -#: help.c:373 +#: help.c:379 #, c-format msgid " HISTCONTROL\n" " controls command history [ignorespace, ignoredups, ignoreboth]\n" msgstr " HISTCONTROL контролює історію команд [ignorespace, ignoredups, ignoreboth]\n" -#: help.c:375 +#: help.c:381 #, c-format msgid " HISTFILE\n" " file name used to store the command history\n" msgstr " HISTFILE ім'я файлу для зберігання історії команд\n" -#: help.c:377 +#: help.c:383 #, c-format msgid " HISTSIZE\n" " maximum number of commands to store in the command history\n" msgstr " HISTSIZE максимальна кількість команд для зберігання в історії команд\n" -#: help.c:379 +#: help.c:385 #, c-format msgid " HOST\n" " the currently connected database server host\n" msgstr " HOST поточний підключений хост сервера бази даних\n" -#: help.c:381 +#: help.c:387 #, c-format msgid " IGNOREEOF\n" " number of EOFs needed to terminate an interactive session\n" msgstr " IGNOREEOF кількість EOF для завершення інтерактивної сесії\n" -#: help.c:383 +#: help.c:389 #, c-format msgid " LASTOID\n" " value of the last affected OID\n" msgstr " LASTOID значення останнього залученого OID\n" -#: help.c:385 +#: help.c:391 #, c-format msgid " LAST_ERROR_MESSAGE\n" " LAST_ERROR_SQLSTATE\n" @@ -3164,63 +3323,63 @@ msgstr " LAST_ERROR_MESSAGE\n" " LAST_ERROR_SQLSTATE\n" " повідомлення та код SQLSTATE останньої помилки, або пустий рядок та \"00000\", якщо помилки не було\n" -#: help.c:388 +#: help.c:394 #, c-format msgid " ON_ERROR_ROLLBACK\n" " if set, an error doesn't stop a transaction (uses implicit savepoints)\n" msgstr " ON_ERROR_ROLLBACK\n" " якщо встановлено, транзакція не припиняється у разі помилки (використовуються неявні точки збереження)\n" -#: help.c:390 +#: help.c:396 #, c-format msgid " ON_ERROR_STOP\n" " stop batch execution after error\n" msgstr " ON_ERROR_STOP\n" " зупиняти виконання пакету команд після помилки\n" -#: help.c:392 +#: help.c:398 #, c-format msgid " PORT\n" " server port of the current connection\n" msgstr " PORT\n" " порт сервера для поточного з'єднання\n" -#: help.c:394 +#: help.c:400 #, c-format msgid " PROMPT1\n" " specifies the standard psql prompt\n" msgstr " PROMPT1\n" " визначає стандратне запрошення psql \n" -#: help.c:396 +#: help.c:402 #, c-format msgid " PROMPT2\n" " specifies the prompt used when a statement continues from a previous line\n" msgstr " PROMPT2\n" " визначає запрошення, яке використовується при продовженні команди з попереднього рядка\n" -#: help.c:398 +#: help.c:404 #, c-format msgid " PROMPT3\n" " specifies the prompt used during COPY ... FROM STDIN\n" msgstr " PROMPT3\n" " визначає запрошення, яке виконується під час COPY ... FROM STDIN\n" -#: help.c:400 +#: help.c:406 #, c-format msgid " QUIET\n" " run quietly (same as -q option)\n" msgstr " QUIET\n" " тихий запуск ( як із параметром -q)\n" -#: help.c:402 +#: help.c:408 #, c-format msgid " ROW_COUNT\n" " number of rows returned or affected by last query, or 0\n" msgstr " ROW_COUNT\n" " число повернених або оброблених рядків останнім запитом, або 0\n" -#: help.c:404 +#: help.c:410 #, c-format msgid " SERVER_VERSION_NAME\n" " SERVER_VERSION_NUM\n" @@ -3229,49 +3388,49 @@ msgstr " SERVER_VERSION_NAME\n" " SERVER_VERSION_NUM\n" " версія серевера (у короткому текстовому або числовому форматі)\n" -#: help.c:407 +#: help.c:413 #, c-format msgid " SHOW_CONTEXT\n" " controls display of message context fields [never, errors, always]\n" msgstr " SHOW_CONTEXT\n" " керує відображенням полів контексту повідомлень [never, errors, always]\n" -#: help.c:409 +#: help.c:415 #, c-format msgid " SINGLELINE\n" " if set, end of line terminates SQL commands (same as -S option)\n" msgstr " SINGLELINE\n" " якщо встановлено, кінець рядка завершує режим вводу SQL-команди (як з параметром -S)\n" -#: help.c:411 +#: help.c:417 #, c-format msgid " SINGLESTEP\n" " single-step mode (same as -s option)\n" msgstr " SINGLESTEP\n" " покроковий режим (як з параметром -s)\n" -#: help.c:413 +#: help.c:419 #, c-format msgid " SQLSTATE\n" " SQLSTATE of last query, or \"00000\" if no error\n" msgstr " SQLSTATE\n" " SQLSTATE останнього запиту, або \"00000\" якщо немає помилок\n" -#: help.c:415 +#: help.c:421 #, c-format msgid " USER\n" " the currently connected database user\n" msgstr " USER\n" " поточний користувач, підключений до бази даних\n" -#: help.c:417 +#: help.c:423 #, c-format msgid " VERBOSITY\n" " controls verbosity of error reports [default, verbose, terse, sqlstate]\n" msgstr " VERBOSITY\n" " контролює докладність звітів про помилку [default, verbose, terse, sqlstate]\n" -#: help.c:419 +#: help.c:425 #, c-format msgid " VERSION\n" " VERSION_NAME\n" @@ -3282,112 +3441,112 @@ msgstr " VERSION\n" " VERSION_NUM\n" " psql версія (в розгорнутому, в короткому текстовому або числовому форматі)\n" -#: help.c:424 +#: help.c:430 #, c-format msgid "\n" "Display settings:\n" msgstr "\n" "Налаштування відобреження:\n" -#: help.c:426 +#: help.c:432 #, c-format msgid " psql --pset=NAME[=VALUE]\n" " or \\pset NAME [VALUE] inside psql\n\n" msgstr " psql --pset=NAME[=VALUE]\n" " або \\pset ІМ'Я [VALUE] всередині psql\n\n" -#: help.c:428 +#: help.c:434 #, c-format msgid " border\n" " border style (number)\n" msgstr " border\n" " стиль рамки (число)\n" -#: help.c:430 +#: help.c:436 #, c-format msgid " columns\n" " target width for the wrapped format\n" msgstr " columns\n" " цільова ширина для формату з переносом\n" -#: help.c:432 +#: help.c:438 #, c-format msgid " expanded (or x)\n" " expanded output [on, off, auto]\n" msgstr " expanded (or x)\n" " розширений вивід [on, off, auto]\n" -#: help.c:434 +#: help.c:440 #, c-format msgid " fieldsep\n" " field separator for unaligned output (default \"%s\")\n" msgstr " fieldsep\n" " розділювач полів для не вирівняного виводу (за замовчуванням \"%s\")\n" -#: help.c:437 +#: help.c:443 #, c-format msgid " fieldsep_zero\n" " set field separator for unaligned output to a zero byte\n" msgstr " fieldsep_zero\n" " встановити розділювач полів для невирівняного виводу на нульовий байт\n" -#: help.c:439 +#: help.c:445 #, c-format msgid " footer\n" " enable or disable display of the table footer [on, off]\n" msgstr " footer\n" " вмикає або вимикає вивід підписів таблиці [on, off]\n" -#: help.c:441 +#: help.c:447 #, c-format msgid " format\n" " set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" msgstr " format\n" " встановити формат виводу [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -#: help.c:443 +#: help.c:449 #, c-format msgid " linestyle\n" " set the border line drawing style [ascii, old-ascii, unicode]\n" msgstr " linestyle\n" " встановлює стиль малювання ліній рамки [ascii, old-ascii, unicode]\n" -#: help.c:445 +#: help.c:451 #, c-format msgid " null\n" " set the string to be printed in place of a null value\n" msgstr " null\n" " встановлює рядок, який буде виведено замість значення (null)\n" -#: help.c:447 +#: help.c:453 #, c-format msgid " numericlocale\n" " enable display of a locale-specific character to separate groups of digits\n" msgstr " numericlocale\n" " вмикає виведення заданого локалью роздільника групи цифр\n" -#: help.c:449 +#: help.c:455 #, c-format msgid " pager\n" " control when an external pager is used [yes, no, always]\n" msgstr " pager\n" " контролює використання зовнішнього пейджера [yes, no, always]\n" -#: help.c:451 +#: help.c:457 #, c-format msgid " recordsep\n" " record (line) separator for unaligned output\n" msgstr " recordsep\n" " розділювач записів (рядків) для не вирівняного виводу\n" -#: help.c:453 +#: help.c:459 #, c-format msgid " recordsep_zero\n" " set record separator for unaligned output to a zero byte\n" msgstr " recordsep_zero\n" " встановлює розділювач записів для невирівняного виводу на нульовий байт\n" -#: help.c:455 +#: help.c:461 #, c-format msgid " tableattr (or T)\n" " specify attributes for table tag in html format, or proportional\n" @@ -3396,21 +3555,21 @@ msgstr " tableattr (або T)\n" " вказує атрибути для тегу table у html форматі або пропорційні \n" " ширини стовпців для вирівняних вліво даних, у latex-longtable форматі\n" -#: help.c:458 +#: help.c:464 #, c-format msgid " title\n" " set the table title for subsequently printed tables\n" msgstr " title\n" " задає заголовок таблиці для послідовно друкованих таблиць\n" -#: help.c:460 +#: help.c:466 #, c-format msgid " tuples_only\n" " if set, only actual table data is shown\n" msgstr " tuples_only\n" " якщо встановлено, виводяться лише фактичні табличні дані\n" -#: help.c:462 +#: help.c:468 #, c-format msgid " unicode_border_linestyle\n" " unicode_column_linestyle\n" @@ -3421,21 +3580,21 @@ msgstr " unicode_border_linestyle\n" " unicode_header_linestyle\n" " задає стиль мальювання ліній (Unicode) [single, double]\n" -#: help.c:467 +#: help.c:473 #, c-format msgid "\n" "Environment variables:\n" msgstr "\n" "Змінні оточення:\n" -#: help.c:471 +#: help.c:477 #, c-format msgid " NAME=VALUE [NAME=VALUE] psql ...\n" " or \\setenv NAME [VALUE] inside psql\n\n" msgstr " ІМ'Я=ЗНАЧЕННЯ [ІМ'Я=ЗНАЧЕННЯ] psql ...\n" " або \\setenv ІМ'Я [VALUE] всередині psql\n\n" -#: help.c:473 +#: help.c:479 #, c-format msgid " set NAME=VALUE\n" " psql ...\n" @@ -3444,116 +3603,116 @@ msgstr " встановлює ІМ'Я=ЗНАЧЕННЯ\n" " psql ...\n" " або \\setenv ІМ'Я [VALUE] всередині psql\n\n" -#: help.c:476 +#: help.c:482 #, c-format msgid " COLUMNS\n" " number of columns for wrapped format\n" msgstr " COLUMNS\n" " число стовпців для форматування з переносом\n" -#: help.c:478 +#: help.c:484 #, c-format msgid " PGAPPNAME\n" " same as the application_name connection parameter\n" msgstr " PGAPPNAME\n" " те саме, що параметр підключення application_name\n" -#: help.c:480 +#: help.c:486 #, c-format msgid " PGDATABASE\n" " same as the dbname connection parameter\n" msgstr " PGDATABASE\n" " те саме, що параметр підключення dbname\n" -#: help.c:482 +#: help.c:488 #, c-format msgid " PGHOST\n" " same as the host connection parameter\n" msgstr " PGHOST\n" " те саме, що параметр підключення host\n" -#: help.c:484 +#: help.c:490 #, c-format msgid " PGPASSWORD\n" " connection password (not recommended)\n" msgstr " PGPASSWORD\n" " пароль для підключення (не рекомендується)\n" -#: help.c:486 +#: help.c:492 #, c-format msgid " PGPASSFILE\n" " password file name\n" msgstr " PGPASSFILE\n" " назва файлу з паролем\n" -#: help.c:488 +#: help.c:494 #, c-format msgid " PGPORT\n" " same as the port connection parameter\n" msgstr " PGPORT\n" " те саме, що параметр підключення port\n" -#: help.c:490 +#: help.c:496 #, c-format msgid " PGUSER\n" " same as the user connection parameter\n" msgstr " PGUSER\n" " те саме, що параметр підключення user\n" -#: help.c:492 +#: help.c:498 #, c-format msgid " PSQL_EDITOR, EDITOR, VISUAL\n" " editor used by the \\e, \\ef, and \\ev commands\n" msgstr " PSQL_EDITOR, EDITOR, VISUAL\n" " редактор для команд \\e, \\ef і \\ev\n" -#: help.c:494 +#: help.c:500 #, c-format msgid " PSQL_EDITOR_LINENUMBER_ARG\n" " how to specify a line number when invoking the editor\n" msgstr " PSQL_EDITOR_LINENUMBER_ARG\n" " як вказати номер рядка при виклику редактора\n" -#: help.c:496 +#: help.c:502 #, c-format msgid " PSQL_HISTORY\n" " alternative location for the command history file\n" msgstr " PSQL_HISTORY\n" " альтернативне розміщення файлу з історією команд\n" -#: help.c:498 +#: help.c:504 #, c-format msgid " PSQL_PAGER, PAGER\n" " name of external pager program\n" msgstr " PSQL_PAGER, PAGER\n" " ім'я програми зовнішнього пейджеру\n" -#: help.c:500 +#: help.c:506 #, c-format msgid " PSQLRC\n" " alternative location for the user's .psqlrc file\n" msgstr " PSQLRC\n" " альтернативне розміщення користувацького файла .psqlrc\n" -#: help.c:502 +#: help.c:508 #, c-format msgid " SHELL\n" " shell used by the \\! command\n" msgstr " SHELL\n" " оболонка, що використовується командою \\!\n" -#: help.c:504 +#: help.c:510 #, c-format msgid " TMPDIR\n" " directory for temporary files\n" msgstr " TMPDIR\n" " каталог для тимчасових файлів\n" -#: help.c:548 +#: help.c:554 msgid "Available help:\n" msgstr "Доступна довідка:\n" -#: help.c:636 +#: help.c:642 #, c-format msgid "Command: %s\n" "Description: %s\n" @@ -3566,24 +3725,24 @@ msgstr "Команда: %s\n" "%s\n\n" "URL: %s\n\n" -#: help.c:655 +#: help.c:661 #, c-format msgid "No help available for \"%s\".\n" "Try \\h with no arguments to see available help.\n" msgstr "Немає доступної довідки по команді \"%s\".\n" "Спробуйте \\h без аргументів, щоб подивитись доступну довідку.\n" -#: input.c:218 +#: input.c:217 #, c-format msgid "could not read from input file: %m" msgstr "не вдалося прочитати з вхідного файлу: %m" -#: input.c:472 input.c:510 +#: input.c:471 input.c:509 #, c-format msgid "could not save history to file \"%s\": %m" msgstr "не можливо зберегти історію в файлі \"%s\": %m" -#: input.c:529 +#: input.c:528 #, c-format msgid "history is not supported by this installation" msgstr "ця установка не підтримує історію" @@ -3616,30 +3775,30 @@ msgstr "Великі об'єкти" msgid "\\if: escaped" msgstr "\\if: вихід" -#: mainloop.c:183 +#: mainloop.c:195 #, c-format msgid "Use \"\\q\" to leave %s.\n" msgstr "Введіть \"\\q\", щоб вийти з %s.\n" -#: mainloop.c:205 +#: mainloop.c:217 msgid "The input is a PostgreSQL custom-format dump.\n" "Use the pg_restore command-line client to restore this dump to a database.\n" msgstr "Ввід являє собою спеціальний формат дампу PostgreSQL.\n" "Щоб відновити базу даних з цього дампу, скористайтеся командою pg_restore.\n" -#: mainloop.c:282 +#: mainloop.c:298 msgid "Use \\? for help or press control-C to clear the input buffer." msgstr "Для отримання довідки введіть \\? або натисніть сontrol-C для очищення буферу вводу." -#: mainloop.c:284 +#: mainloop.c:300 msgid "Use \\? for help." msgstr "Введіть \\? для отримання довідки." -#: mainloop.c:288 +#: mainloop.c:304 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Ви використовуєте psql — інтерфейс командного рядка до PostgreSQL." -#: mainloop.c:289 +#: mainloop.c:305 #, c-format msgid "Type: \\copyright for distribution terms\n" " \\h for help with SQL commands\n" @@ -3652,24 +3811,24 @@ msgstr "Введіть: \\copyright для умов розповсюдженн " \\g або крапку з комою в кінці рядка для виконання запиту\n" " \\q для виходу\n" -#: mainloop.c:313 +#: mainloop.c:329 msgid "Use \\q to quit." msgstr "Введіть \\q, щоб вийти." -#: mainloop.c:316 mainloop.c:340 +#: mainloop.c:332 mainloop.c:356 msgid "Use control-D to quit." msgstr "Натисніть control-D, щоб вийти." -#: mainloop.c:318 mainloop.c:342 +#: mainloop.c:334 mainloop.c:358 msgid "Use control-C to quit." msgstr "Натисніть control-C, щоб вийти." -#: mainloop.c:449 mainloop.c:591 +#: mainloop.c:465 mainloop.c:613 #, c-format msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" msgstr "запит ігнорується; введіть \\endif або натисніть Ctrl-C для завершення поточного \\if блоку" -#: mainloop.c:609 +#: mainloop.c:631 #, c-format msgid "reached EOF without finding closing \\endif(s)" msgstr "досягнуто кінця файлу без завершального \\endif" @@ -3705,48 +3864,48 @@ msgstr "%s: бракує пам'яті" #: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 #: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 #: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 -#: sql_help.c:1089 sql_help.c:1091 sql_help.c:1093 sql_help.c:1109 -#: sql_help.c:1111 sql_help.c:1115 sql_help.c:1118 sql_help.c:1119 -#: sql_help.c:1120 sql_help.c:1123 sql_help.c:1125 sql_help.c:1258 -#: sql_help.c:1260 sql_help.c:1263 sql_help.c:1266 sql_help.c:1268 -#: sql_help.c:1270 sql_help.c:1273 sql_help.c:1276 sql_help.c:1386 -#: sql_help.c:1388 sql_help.c:1390 sql_help.c:1393 sql_help.c:1414 -#: sql_help.c:1417 sql_help.c:1420 sql_help.c:1423 sql_help.c:1427 -#: sql_help.c:1429 sql_help.c:1431 sql_help.c:1433 sql_help.c:1447 -#: sql_help.c:1450 sql_help.c:1452 sql_help.c:1454 sql_help.c:1464 -#: sql_help.c:1466 sql_help.c:1476 sql_help.c:1478 sql_help.c:1488 -#: sql_help.c:1491 sql_help.c:1513 sql_help.c:1515 sql_help.c:1517 -#: sql_help.c:1520 sql_help.c:1522 sql_help.c:1524 sql_help.c:1527 -#: sql_help.c:1577 sql_help.c:1619 sql_help.c:1622 sql_help.c:1624 -#: sql_help.c:1626 sql_help.c:1628 sql_help.c:1630 sql_help.c:1633 -#: sql_help.c:1683 sql_help.c:1699 sql_help.c:1920 sql_help.c:1989 -#: sql_help.c:2008 sql_help.c:2021 sql_help.c:2078 sql_help.c:2085 -#: sql_help.c:2095 sql_help.c:2115 sql_help.c:2140 sql_help.c:2158 -#: sql_help.c:2187 sql_help.c:2282 sql_help.c:2324 sql_help.c:2347 -#: sql_help.c:2368 sql_help.c:2369 sql_help.c:2406 sql_help.c:2426 -#: sql_help.c:2448 sql_help.c:2462 sql_help.c:2482 sql_help.c:2505 -#: sql_help.c:2535 sql_help.c:2560 sql_help.c:2606 sql_help.c:2884 -#: sql_help.c:2897 sql_help.c:2914 sql_help.c:2930 sql_help.c:2970 -#: sql_help.c:3022 sql_help.c:3026 sql_help.c:3028 sql_help.c:3034 -#: sql_help.c:3052 sql_help.c:3079 sql_help.c:3114 sql_help.c:3126 -#: sql_help.c:3135 sql_help.c:3179 sql_help.c:3193 sql_help.c:3221 -#: sql_help.c:3229 sql_help.c:3237 sql_help.c:3245 sql_help.c:3253 -#: sql_help.c:3261 sql_help.c:3269 sql_help.c:3277 sql_help.c:3286 -#: sql_help.c:3297 sql_help.c:3305 sql_help.c:3313 sql_help.c:3321 -#: sql_help.c:3329 sql_help.c:3339 sql_help.c:3348 sql_help.c:3357 -#: sql_help.c:3365 sql_help.c:3375 sql_help.c:3386 sql_help.c:3394 -#: sql_help.c:3403 sql_help.c:3414 sql_help.c:3423 sql_help.c:3431 -#: sql_help.c:3439 sql_help.c:3447 sql_help.c:3455 sql_help.c:3463 -#: sql_help.c:3471 sql_help.c:3479 sql_help.c:3487 sql_help.c:3495 -#: sql_help.c:3503 sql_help.c:3520 sql_help.c:3529 sql_help.c:3537 -#: sql_help.c:3554 sql_help.c:3569 sql_help.c:3839 sql_help.c:3890 -#: sql_help.c:3919 sql_help.c:3927 sql_help.c:4360 sql_help.c:4408 -#: sql_help.c:4549 +#: sql_help.c:1090 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 +#: sql_help.c:1112 sql_help.c:1114 sql_help.c:1118 sql_help.c:1121 +#: sql_help.c:1122 sql_help.c:1123 sql_help.c:1126 sql_help.c:1128 +#: sql_help.c:1262 sql_help.c:1264 sql_help.c:1267 sql_help.c:1270 +#: sql_help.c:1272 sql_help.c:1274 sql_help.c:1277 sql_help.c:1280 +#: sql_help.c:1391 sql_help.c:1393 sql_help.c:1395 sql_help.c:1398 +#: sql_help.c:1419 sql_help.c:1422 sql_help.c:1425 sql_help.c:1428 +#: sql_help.c:1432 sql_help.c:1434 sql_help.c:1436 sql_help.c:1438 +#: sql_help.c:1452 sql_help.c:1455 sql_help.c:1457 sql_help.c:1459 +#: sql_help.c:1469 sql_help.c:1471 sql_help.c:1481 sql_help.c:1483 +#: sql_help.c:1493 sql_help.c:1496 sql_help.c:1519 sql_help.c:1521 +#: sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 sql_help.c:1530 +#: sql_help.c:1533 sql_help.c:1536 sql_help.c:1586 sql_help.c:1629 +#: sql_help.c:1632 sql_help.c:1634 sql_help.c:1636 sql_help.c:1639 +#: sql_help.c:1641 sql_help.c:1643 sql_help.c:1646 sql_help.c:1696 +#: sql_help.c:1712 sql_help.c:1933 sql_help.c:2002 sql_help.c:2021 +#: sql_help.c:2034 sql_help.c:2091 sql_help.c:2098 sql_help.c:2108 +#: sql_help.c:2129 sql_help.c:2155 sql_help.c:2173 sql_help.c:2200 +#: sql_help.c:2295 sql_help.c:2340 sql_help.c:2364 sql_help.c:2387 +#: sql_help.c:2391 sql_help.c:2425 sql_help.c:2445 sql_help.c:2467 +#: sql_help.c:2481 sql_help.c:2501 sql_help.c:2524 sql_help.c:2554 +#: sql_help.c:2579 sql_help.c:2625 sql_help.c:2903 sql_help.c:2916 +#: sql_help.c:2933 sql_help.c:2949 sql_help.c:2989 sql_help.c:3041 +#: sql_help.c:3045 sql_help.c:3047 sql_help.c:3053 sql_help.c:3071 +#: sql_help.c:3098 sql_help.c:3133 sql_help.c:3145 sql_help.c:3154 +#: sql_help.c:3198 sql_help.c:3212 sql_help.c:3240 sql_help.c:3248 +#: sql_help.c:3260 sql_help.c:3270 sql_help.c:3278 sql_help.c:3286 +#: sql_help.c:3294 sql_help.c:3302 sql_help.c:3311 sql_help.c:3322 +#: sql_help.c:3330 sql_help.c:3338 sql_help.c:3346 sql_help.c:3354 +#: sql_help.c:3364 sql_help.c:3373 sql_help.c:3382 sql_help.c:3390 +#: sql_help.c:3400 sql_help.c:3411 sql_help.c:3419 sql_help.c:3428 +#: sql_help.c:3439 sql_help.c:3448 sql_help.c:3456 sql_help.c:3464 +#: sql_help.c:3472 sql_help.c:3480 sql_help.c:3488 sql_help.c:3496 +#: sql_help.c:3504 sql_help.c:3512 sql_help.c:3520 sql_help.c:3528 +#: sql_help.c:3545 sql_help.c:3554 sql_help.c:3562 sql_help.c:3579 +#: sql_help.c:3594 sql_help.c:3869 sql_help.c:3920 sql_help.c:3949 +#: sql_help.c:3962 sql_help.c:4407 sql_help.c:4455 sql_help.c:4596 msgid "name" msgstr "назва" -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1770 -#: sql_help.c:3194 sql_help.c:4146 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1783 +#: sql_help.c:3213 sql_help.c:4193 msgid "aggregate_signature" msgstr "сигнатура_агр_функції" @@ -3755,9 +3914,9 @@ msgstr "сигнатура_агр_функції" #: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 #: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 #: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 -#: sql_help.c:1092 sql_help.c:1126 sql_help.c:1267 sql_help.c:1387 -#: sql_help.c:1430 sql_help.c:1451 sql_help.c:1465 sql_help.c:1477 -#: sql_help.c:1490 sql_help.c:1521 sql_help.c:1578 sql_help.c:1627 +#: sql_help.c:1093 sql_help.c:1129 sql_help.c:1271 sql_help.c:1392 +#: sql_help.c:1435 sql_help.c:1456 sql_help.c:1470 sql_help.c:1482 +#: sql_help.c:1495 sql_help.c:1522 sql_help.c:1587 sql_help.c:1640 msgid "new_name" msgstr "нова_назва" @@ -3765,21 +3924,21 @@ msgstr "нова_назва" #: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 #: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 #: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 -#: sql_help.c:1077 sql_help.c:1090 sql_help.c:1124 sql_help.c:1327 -#: sql_help.c:1389 sql_help.c:1432 sql_help.c:1453 sql_help.c:1516 -#: sql_help.c:1625 sql_help.c:2870 +#: sql_help.c:1077 sql_help.c:1091 sql_help.c:1127 sql_help.c:1332 +#: sql_help.c:1394 sql_help.c:1437 sql_help.c:1458 sql_help.c:1520 +#: sql_help.c:1635 sql_help.c:2889 msgid "new_owner" msgstr "новий_власник" #: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 #: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 -#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1094 -#: sql_help.c:1269 sql_help.c:1434 sql_help.c:1455 sql_help.c:1467 -#: sql_help.c:1479 sql_help.c:1523 sql_help.c:1629 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1095 +#: sql_help.c:1273 sql_help.c:1439 sql_help.c:1460 sql_help.c:1472 +#: sql_help.c:1484 sql_help.c:1524 sql_help.c:1642 msgid "new_schema" msgstr "нова_схема" -#: sql_help.c:44 sql_help.c:1834 sql_help.c:3195 sql_help.c:4175 +#: sql_help.c:44 sql_help.c:1847 sql_help.c:3214 sql_help.c:4222 msgid "where aggregate_signature is:" msgstr "де сигнатура_агр_функції:" @@ -3787,13 +3946,13 @@ msgstr "де сигнатура_агр_функції:" #: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 #: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 #: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 -#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1788 -#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 -#: sql_help.c:1841 sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 -#: sql_help.c:2283 sql_help.c:2483 sql_help.c:3196 sql_help.c:3199 -#: sql_help.c:3202 sql_help.c:3287 sql_help.c:3376 sql_help.c:3404 -#: sql_help.c:3724 sql_help.c:4057 sql_help.c:4152 sql_help.c:4159 -#: sql_help.c:4165 sql_help.c:4176 sql_help.c:4179 sql_help.c:4182 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1801 +#: sql_help.c:1818 sql_help.c:1824 sql_help.c:1848 sql_help.c:1851 +#: sql_help.c:1854 sql_help.c:2003 sql_help.c:2022 sql_help.c:2025 +#: sql_help.c:2296 sql_help.c:2502 sql_help.c:3215 sql_help.c:3218 +#: sql_help.c:3221 sql_help.c:3312 sql_help.c:3401 sql_help.c:3429 +#: sql_help.c:3753 sql_help.c:4101 sql_help.c:4199 sql_help.c:4206 +#: sql_help.c:4212 sql_help.c:4223 sql_help.c:4226 sql_help.c:4229 msgid "argmode" msgstr "режим_аргументу" @@ -3801,13 +3960,13 @@ msgstr "режим_аргументу" #: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 #: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 #: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 -#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1789 -#: sql_help.c:1806 sql_help.c:1812 sql_help.c:1836 sql_help.c:1839 -#: sql_help.c:1842 sql_help.c:1991 sql_help.c:2010 sql_help.c:2013 -#: sql_help.c:2284 sql_help.c:2484 sql_help.c:3197 sql_help.c:3200 -#: sql_help.c:3203 sql_help.c:3288 sql_help.c:3377 sql_help.c:3405 -#: sql_help.c:4153 sql_help.c:4160 sql_help.c:4166 sql_help.c:4177 -#: sql_help.c:4180 sql_help.c:4183 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1802 +#: sql_help.c:1819 sql_help.c:1825 sql_help.c:1849 sql_help.c:1852 +#: sql_help.c:1855 sql_help.c:2004 sql_help.c:2023 sql_help.c:2026 +#: sql_help.c:2297 sql_help.c:2503 sql_help.c:3216 sql_help.c:3219 +#: sql_help.c:3222 sql_help.c:3313 sql_help.c:3402 sql_help.c:3430 +#: sql_help.c:4200 sql_help.c:4207 sql_help.c:4213 sql_help.c:4224 +#: sql_help.c:4227 sql_help.c:4230 msgid "argname" msgstr "ім'я_аргументу" @@ -3815,67 +3974,69 @@ msgstr "ім'я_аргументу" #: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 #: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 #: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 -#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1790 -#: sql_help.c:1807 sql_help.c:1813 sql_help.c:1837 sql_help.c:1840 -#: sql_help.c:1843 sql_help.c:2285 sql_help.c:2485 sql_help.c:3198 -#: sql_help.c:3201 sql_help.c:3204 sql_help.c:3289 sql_help.c:3378 -#: sql_help.c:3406 sql_help.c:4154 sql_help.c:4161 sql_help.c:4167 -#: sql_help.c:4178 sql_help.c:4181 sql_help.c:4184 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1803 +#: sql_help.c:1820 sql_help.c:1826 sql_help.c:1850 sql_help.c:1853 +#: sql_help.c:1856 sql_help.c:2298 sql_help.c:2504 sql_help.c:3217 +#: sql_help.c:3220 sql_help.c:3223 sql_help.c:3314 sql_help.c:3403 +#: sql_help.c:3431 sql_help.c:4201 sql_help.c:4208 sql_help.c:4214 +#: sql_help.c:4225 sql_help.c:4228 sql_help.c:4231 msgid "argtype" msgstr "тип_аргументу" #: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 -#: sql_help.c:1074 sql_help.c:1448 sql_help.c:1572 sql_help.c:1604 -#: sql_help.c:1652 sql_help.c:1891 sql_help.c:1898 sql_help.c:2190 -#: sql_help.c:2232 sql_help.c:2239 sql_help.c:2248 sql_help.c:2325 -#: sql_help.c:2536 sql_help.c:2628 sql_help.c:2899 sql_help.c:3080 -#: sql_help.c:3102 sql_help.c:3590 sql_help.c:3758 sql_help.c:4610 +#: sql_help.c:1074 sql_help.c:1453 sql_help.c:1581 sql_help.c:1613 +#: sql_help.c:1665 sql_help.c:1904 sql_help.c:1911 sql_help.c:2203 +#: sql_help.c:2245 sql_help.c:2252 sql_help.c:2261 sql_help.c:2341 +#: sql_help.c:2555 sql_help.c:2647 sql_help.c:2918 sql_help.c:3099 +#: sql_help.c:3121 sql_help.c:3261 sql_help.c:3616 sql_help.c:3788 +#: sql_help.c:3961 sql_help.c:4658 msgid "option" msgstr "параметр" -#: sql_help.c:113 sql_help.c:927 sql_help.c:1573 sql_help.c:2326 -#: sql_help.c:2537 sql_help.c:3081 +#: sql_help.c:113 sql_help.c:927 sql_help.c:1582 sql_help.c:2342 +#: sql_help.c:2556 sql_help.c:3100 sql_help.c:3262 msgid "where option can be:" msgstr "де параметр може бути:" -#: sql_help.c:114 sql_help.c:2122 +#: sql_help.c:114 sql_help.c:2137 msgid "allowconn" msgstr "дозвол_підкл" -#: sql_help.c:115 sql_help.c:928 sql_help.c:1574 sql_help.c:2123 -#: sql_help.c:2538 sql_help.c:3082 +#: sql_help.c:115 sql_help.c:928 sql_help.c:1583 sql_help.c:2138 +#: sql_help.c:2343 sql_help.c:2557 sql_help.c:3101 msgid "connlimit" msgstr "ліміт_підключень" -#: sql_help.c:116 sql_help.c:2124 +#: sql_help.c:116 sql_help.c:2139 msgid "istemplate" msgstr "чи_шаблон" -#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1272 sql_help.c:1320 +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1276 sql_help.c:1325 msgid "new_tablespace" msgstr "новий_табл_простір" #: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 #: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 #: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 -#: sql_help.c:1006 sql_help.c:1137 sql_help.c:1140 sql_help.c:1581 -#: sql_help.c:1585 sql_help.c:1588 sql_help.c:2295 sql_help.c:2489 -#: sql_help.c:3944 sql_help.c:4349 +#: sql_help.c:1006 sql_help.c:1140 sql_help.c:1143 sql_help.c:1590 +#: sql_help.c:1594 sql_help.c:1597 sql_help.c:2308 sql_help.c:2508 +#: sql_help.c:3980 sql_help.c:4396 msgid "configuration_parameter" msgstr "параметр_конфігурації" #: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 #: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 #: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 -#: sql_help.c:1114 sql_help.c:1117 sql_help.c:1122 sql_help.c:1138 -#: sql_help.c:1139 sql_help.c:1302 sql_help.c:1322 sql_help.c:1370 -#: sql_help.c:1392 sql_help.c:1449 sql_help.c:1582 sql_help.c:1605 -#: sql_help.c:2191 sql_help.c:2233 sql_help.c:2240 sql_help.c:2249 -#: sql_help.c:2296 sql_help.c:2297 sql_help.c:2356 sql_help.c:2390 -#: sql_help.c:2490 sql_help.c:2491 sql_help.c:2508 sql_help.c:2629 -#: sql_help.c:2659 sql_help.c:2764 sql_help.c:2777 sql_help.c:2791 -#: sql_help.c:2832 sql_help.c:2856 sql_help.c:2873 sql_help.c:2900 -#: sql_help.c:3103 sql_help.c:3759 sql_help.c:4350 sql_help.c:4351 +#: sql_help.c:1117 sql_help.c:1120 sql_help.c:1125 sql_help.c:1141 +#: sql_help.c:1142 sql_help.c:1307 sql_help.c:1327 sql_help.c:1375 +#: sql_help.c:1397 sql_help.c:1454 sql_help.c:1538 sql_help.c:1591 +#: sql_help.c:1614 sql_help.c:2204 sql_help.c:2246 sql_help.c:2253 +#: sql_help.c:2262 sql_help.c:2309 sql_help.c:2310 sql_help.c:2372 +#: sql_help.c:2375 sql_help.c:2409 sql_help.c:2509 sql_help.c:2510 +#: sql_help.c:2527 sql_help.c:2648 sql_help.c:2678 sql_help.c:2783 +#: sql_help.c:2796 sql_help.c:2810 sql_help.c:2851 sql_help.c:2875 +#: sql_help.c:2892 sql_help.c:2919 sql_help.c:3122 sql_help.c:3789 +#: sql_help.c:4397 sql_help.c:4398 msgid "value" msgstr "значення" @@ -3883,9 +4044,9 @@ msgstr "значення" msgid "target_role" msgstr "цільова_роль" -#: sql_help.c:198 sql_help.c:2174 sql_help.c:2584 sql_help.c:2589 -#: sql_help.c:3706 sql_help.c:3713 sql_help.c:3727 sql_help.c:3733 -#: sql_help.c:4039 sql_help.c:4046 sql_help.c:4060 sql_help.c:4066 +#: sql_help.c:198 sql_help.c:2188 sql_help.c:2603 sql_help.c:2608 +#: sql_help.c:3735 sql_help.c:3742 sql_help.c:3756 sql_help.c:3762 +#: sql_help.c:4083 sql_help.c:4090 sql_help.c:4104 sql_help.c:4110 msgid "schema_name" msgstr "ім'я_схеми" @@ -3900,33 +4061,29 @@ msgstr "де скорочено_GRANT_або_REVOKE є одним з:" #: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 #: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 #: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 -#: sql_help.c:1271 sql_help.c:1592 sql_help.c:2329 sql_help.c:2330 -#: sql_help.c:2331 sql_help.c:2332 sql_help.c:2333 sql_help.c:2464 -#: sql_help.c:2541 sql_help.c:2542 sql_help.c:2543 sql_help.c:2544 -#: sql_help.c:2545 sql_help.c:3085 sql_help.c:3086 sql_help.c:3087 -#: sql_help.c:3088 sql_help.c:3089 sql_help.c:3740 sql_help.c:3741 -#: sql_help.c:3742 sql_help.c:4040 sql_help.c:4044 sql_help.c:4047 -#: sql_help.c:4049 sql_help.c:4051 sql_help.c:4053 sql_help.c:4055 -#: sql_help.c:4061 sql_help.c:4063 sql_help.c:4065 sql_help.c:4067 -#: sql_help.c:4069 sql_help.c:4071 sql_help.c:4072 sql_help.c:4073 -#: sql_help.c:4370 +#: sql_help.c:1275 sql_help.c:1601 sql_help.c:2346 sql_help.c:2347 +#: sql_help.c:2348 sql_help.c:2349 sql_help.c:2350 sql_help.c:2483 +#: sql_help.c:2560 sql_help.c:2561 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 sql_help.c:3104 sql_help.c:3105 sql_help.c:3106 +#: sql_help.c:3107 sql_help.c:3108 sql_help.c:3768 sql_help.c:3772 +#: sql_help.c:4116 sql_help.c:4120 sql_help.c:4417 msgid "role_name" msgstr "ім'я_ролі" -#: sql_help.c:236 sql_help.c:459 sql_help.c:1287 sql_help.c:1289 -#: sql_help.c:1337 sql_help.c:1349 sql_help.c:1374 sql_help.c:1621 -#: sql_help.c:2143 sql_help.c:2147 sql_help.c:2252 sql_help.c:2257 -#: sql_help.c:2351 sql_help.c:2759 sql_help.c:2772 sql_help.c:2786 -#: sql_help.c:2795 sql_help.c:2807 sql_help.c:2836 sql_help.c:3790 -#: sql_help.c:3805 sql_help.c:3807 sql_help.c:4235 sql_help.c:4236 -#: sql_help.c:4245 sql_help.c:4286 sql_help.c:4287 sql_help.c:4288 -#: sql_help.c:4289 sql_help.c:4290 sql_help.c:4291 sql_help.c:4324 -#: sql_help.c:4325 sql_help.c:4330 sql_help.c:4335 sql_help.c:4474 -#: sql_help.c:4475 sql_help.c:4484 sql_help.c:4525 sql_help.c:4526 -#: sql_help.c:4527 sql_help.c:4528 sql_help.c:4529 sql_help.c:4530 -#: sql_help.c:4577 sql_help.c:4579 sql_help.c:4636 sql_help.c:4692 -#: sql_help.c:4693 sql_help.c:4702 sql_help.c:4743 sql_help.c:4744 -#: sql_help.c:4745 sql_help.c:4746 sql_help.c:4747 sql_help.c:4748 +#: sql_help.c:236 sql_help.c:459 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1342 sql_help.c:1354 sql_help.c:1379 sql_help.c:1631 +#: sql_help.c:2158 sql_help.c:2162 sql_help.c:2265 sql_help.c:2270 +#: sql_help.c:2368 sql_help.c:2778 sql_help.c:2791 sql_help.c:2805 +#: sql_help.c:2814 sql_help.c:2826 sql_help.c:2855 sql_help.c:3820 +#: sql_help.c:3835 sql_help.c:3837 sql_help.c:4282 sql_help.c:4283 +#: sql_help.c:4292 sql_help.c:4333 sql_help.c:4334 sql_help.c:4335 +#: sql_help.c:4336 sql_help.c:4337 sql_help.c:4338 sql_help.c:4371 +#: sql_help.c:4372 sql_help.c:4377 sql_help.c:4382 sql_help.c:4521 +#: sql_help.c:4522 sql_help.c:4531 sql_help.c:4572 sql_help.c:4573 +#: sql_help.c:4574 sql_help.c:4575 sql_help.c:4576 sql_help.c:4577 +#: sql_help.c:4624 sql_help.c:4626 sql_help.c:4685 sql_help.c:4741 +#: sql_help.c:4742 sql_help.c:4751 sql_help.c:4792 sql_help.c:4793 +#: sql_help.c:4794 sql_help.c:4795 sql_help.c:4796 sql_help.c:4797 msgid "expression" msgstr "вираз" @@ -3935,14 +4092,14 @@ msgid "domain_constraint" msgstr "обмеження_домену" #: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 -#: sql_help.c:1264 sql_help.c:1308 sql_help.c:1309 sql_help.c:1310 -#: sql_help.c:1336 sql_help.c:1348 sql_help.c:1365 sql_help.c:1776 -#: sql_help.c:1778 sql_help.c:2146 sql_help.c:2251 sql_help.c:2256 -#: sql_help.c:2794 sql_help.c:2806 sql_help.c:3802 +#: sql_help.c:1268 sql_help.c:1313 sql_help.c:1314 sql_help.c:1315 +#: sql_help.c:1341 sql_help.c:1353 sql_help.c:1370 sql_help.c:1789 +#: sql_help.c:1791 sql_help.c:2161 sql_help.c:2264 sql_help.c:2269 +#: sql_help.c:2813 sql_help.c:2825 sql_help.c:3832 msgid "constraint_name" msgstr "ім'я_обмеження" -#: sql_help.c:244 sql_help.c:1265 +#: sql_help.c:244 sql_help.c:1269 msgid "new_constraint_name" msgstr "ім'я_нового_обмеження" @@ -3962,82 +4119,82 @@ msgstr "де елемент_об'єкт є:" #: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 #: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 #: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 -#: sql_help.c:368 sql_help.c:1768 sql_help.c:1773 sql_help.c:1780 -#: sql_help.c:1781 sql_help.c:1782 sql_help.c:1783 sql_help.c:1784 -#: sql_help.c:1785 sql_help.c:1786 sql_help.c:1791 sql_help.c:1793 -#: sql_help.c:1797 sql_help.c:1799 sql_help.c:1803 sql_help.c:1808 -#: sql_help.c:1809 sql_help.c:1816 sql_help.c:1817 sql_help.c:1818 -#: sql_help.c:1819 sql_help.c:1820 sql_help.c:1821 sql_help.c:1822 -#: sql_help.c:1823 sql_help.c:1824 sql_help.c:1825 sql_help.c:1826 -#: sql_help.c:1831 sql_help.c:1832 sql_help.c:4142 sql_help.c:4147 -#: sql_help.c:4148 sql_help.c:4149 sql_help.c:4150 sql_help.c:4156 -#: sql_help.c:4157 sql_help.c:4162 sql_help.c:4163 sql_help.c:4168 -#: sql_help.c:4169 sql_help.c:4170 sql_help.c:4171 sql_help.c:4172 -#: sql_help.c:4173 +#: sql_help.c:368 sql_help.c:1781 sql_help.c:1786 sql_help.c:1793 +#: sql_help.c:1794 sql_help.c:1795 sql_help.c:1796 sql_help.c:1797 +#: sql_help.c:1798 sql_help.c:1799 sql_help.c:1804 sql_help.c:1806 +#: sql_help.c:1810 sql_help.c:1812 sql_help.c:1816 sql_help.c:1821 +#: sql_help.c:1822 sql_help.c:1829 sql_help.c:1830 sql_help.c:1831 +#: sql_help.c:1832 sql_help.c:1833 sql_help.c:1834 sql_help.c:1835 +#: sql_help.c:1836 sql_help.c:1837 sql_help.c:1838 sql_help.c:1839 +#: sql_help.c:1844 sql_help.c:1845 sql_help.c:4189 sql_help.c:4194 +#: sql_help.c:4195 sql_help.c:4196 sql_help.c:4197 sql_help.c:4203 +#: sql_help.c:4204 sql_help.c:4209 sql_help.c:4210 sql_help.c:4215 +#: sql_help.c:4216 sql_help.c:4217 sql_help.c:4218 sql_help.c:4219 +#: sql_help.c:4220 msgid "object_name" msgstr "ім'я_об'єкту" -#: sql_help.c:326 sql_help.c:1769 sql_help.c:4145 +#: sql_help.c:326 sql_help.c:1782 sql_help.c:4192 msgid "aggregate_name" msgstr "ім'я_агр_функції" -#: sql_help.c:328 sql_help.c:1771 sql_help.c:2055 sql_help.c:2059 -#: sql_help.c:2061 sql_help.c:3212 +#: sql_help.c:328 sql_help.c:1784 sql_help.c:2068 sql_help.c:2072 +#: sql_help.c:2074 sql_help.c:3231 msgid "source_type" msgstr "початковий_тип" -#: sql_help.c:329 sql_help.c:1772 sql_help.c:2056 sql_help.c:2060 -#: sql_help.c:2062 sql_help.c:3213 +#: sql_help.c:329 sql_help.c:1785 sql_help.c:2069 sql_help.c:2073 +#: sql_help.c:2075 sql_help.c:3232 msgid "target_type" msgstr "тип_цілі" -#: sql_help.c:336 sql_help.c:774 sql_help.c:1787 sql_help.c:2057 -#: sql_help.c:2098 sql_help.c:2161 sql_help.c:2407 sql_help.c:2438 -#: sql_help.c:2976 sql_help.c:4056 sql_help.c:4151 sql_help.c:4264 -#: sql_help.c:4268 sql_help.c:4272 sql_help.c:4275 sql_help.c:4503 -#: sql_help.c:4507 sql_help.c:4511 sql_help.c:4514 sql_help.c:4721 -#: sql_help.c:4725 sql_help.c:4729 sql_help.c:4732 +#: sql_help.c:336 sql_help.c:774 sql_help.c:1800 sql_help.c:2070 +#: sql_help.c:2111 sql_help.c:2176 sql_help.c:2426 sql_help.c:2457 +#: sql_help.c:2995 sql_help.c:4100 sql_help.c:4198 sql_help.c:4311 +#: sql_help.c:4315 sql_help.c:4319 sql_help.c:4322 sql_help.c:4550 +#: sql_help.c:4554 sql_help.c:4558 sql_help.c:4561 sql_help.c:4770 +#: sql_help.c:4774 sql_help.c:4778 sql_help.c:4781 msgid "function_name" msgstr "ім'я_функції" -#: sql_help.c:341 sql_help.c:767 sql_help.c:1794 sql_help.c:2431 +#: sql_help.c:341 sql_help.c:767 sql_help.c:1807 sql_help.c:2450 msgid "operator_name" msgstr "ім'я_оператора" -#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1795 -#: sql_help.c:2408 sql_help.c:3330 +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1808 +#: sql_help.c:2427 sql_help.c:3355 msgid "left_type" msgstr "тип_ліворуч" -#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1796 -#: sql_help.c:2409 sql_help.c:3331 +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1809 +#: sql_help.c:2428 sql_help.c:3356 msgid "right_type" msgstr "тип_праворуч" #: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 #: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 -#: sql_help.c:1354 sql_help.c:1798 sql_help.c:1800 sql_help.c:2428 -#: sql_help.c:2449 sql_help.c:2812 sql_help.c:3340 sql_help.c:3349 +#: sql_help.c:1359 sql_help.c:1811 sql_help.c:1813 sql_help.c:2447 +#: sql_help.c:2468 sql_help.c:2831 sql_help.c:3365 sql_help.c:3374 msgid "index_method" msgstr "метод_індексу" -#: sql_help.c:349 sql_help.c:1804 sql_help.c:4158 +#: sql_help.c:349 sql_help.c:1817 sql_help.c:4205 msgid "procedure_name" msgstr "назва_процедури" -#: sql_help.c:353 sql_help.c:1810 sql_help.c:3723 sql_help.c:4164 +#: sql_help.c:353 sql_help.c:1823 sql_help.c:3752 sql_help.c:4211 msgid "routine_name" msgstr "ім'я_підпрограми" -#: sql_help.c:365 sql_help.c:1326 sql_help.c:1827 sql_help.c:2291 -#: sql_help.c:2488 sql_help.c:2767 sql_help.c:2943 sql_help.c:3511 -#: sql_help.c:3737 sql_help.c:4070 +#: sql_help.c:365 sql_help.c:1331 sql_help.c:1840 sql_help.c:2304 +#: sql_help.c:2507 sql_help.c:2786 sql_help.c:2962 sql_help.c:3536 +#: sql_help.c:3766 sql_help.c:4114 msgid "type_name" msgstr "назва_типу" -#: sql_help.c:366 sql_help.c:1828 sql_help.c:2290 sql_help.c:2487 -#: sql_help.c:2944 sql_help.c:3170 sql_help.c:3512 sql_help.c:3729 -#: sql_help.c:4062 +#: sql_help.c:366 sql_help.c:1841 sql_help.c:2303 sql_help.c:2506 +#: sql_help.c:2963 sql_help.c:3189 sql_help.c:3537 sql_help.c:3758 +#: sql_help.c:4106 msgid "lang_name" msgstr "назва_мови" @@ -4045,129 +4202,134 @@ msgstr "назва_мови" msgid "and aggregate_signature is:" msgstr "і сигнатура_агр_функції:" -#: sql_help.c:392 sql_help.c:1922 sql_help.c:2188 +#: sql_help.c:392 sql_help.c:1935 sql_help.c:2201 msgid "handler_function" msgstr "функція_обробник" -#: sql_help.c:393 sql_help.c:2189 +#: sql_help.c:393 sql_help.c:2202 msgid "validator_function" msgstr "функція_перевірки" #: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 -#: sql_help.c:1259 sql_help.c:1514 +#: sql_help.c:1263 sql_help.c:1529 msgid "action" msgstr "дія" #: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 #: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 #: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 -#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1261 -#: sql_help.c:1279 sql_help.c:1283 sql_help.c:1284 sql_help.c:1288 -#: sql_help.c:1290 sql_help.c:1291 sql_help.c:1292 sql_help.c:1294 -#: sql_help.c:1297 sql_help.c:1298 sql_help.c:1300 sql_help.c:1303 -#: sql_help.c:1305 sql_help.c:1350 sql_help.c:1352 sql_help.c:1359 -#: sql_help.c:1368 sql_help.c:1373 sql_help.c:1620 sql_help.c:1623 -#: sql_help.c:1660 sql_help.c:1775 sql_help.c:1888 sql_help.c:1894 -#: sql_help.c:1907 sql_help.c:1908 sql_help.c:1909 sql_help.c:2230 -#: sql_help.c:2243 sql_help.c:2288 sql_help.c:2350 sql_help.c:2354 -#: sql_help.c:2387 sql_help.c:2614 sql_help.c:2642 sql_help.c:2643 -#: sql_help.c:2750 sql_help.c:2758 sql_help.c:2768 sql_help.c:2771 -#: sql_help.c:2781 sql_help.c:2785 sql_help.c:2808 sql_help.c:2810 -#: sql_help.c:2817 sql_help.c:2830 sql_help.c:2835 sql_help.c:2853 -#: sql_help.c:2979 sql_help.c:3115 sql_help.c:3708 sql_help.c:3709 -#: sql_help.c:3789 sql_help.c:3804 sql_help.c:3806 sql_help.c:3808 -#: sql_help.c:4041 sql_help.c:4042 sql_help.c:4144 sql_help.c:4295 -#: sql_help.c:4534 sql_help.c:4576 sql_help.c:4578 sql_help.c:4580 -#: sql_help.c:4624 sql_help.c:4752 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1265 +#: sql_help.c:1283 sql_help.c:1287 sql_help.c:1288 sql_help.c:1292 +#: sql_help.c:1294 sql_help.c:1295 sql_help.c:1296 sql_help.c:1297 +#: sql_help.c:1299 sql_help.c:1302 sql_help.c:1303 sql_help.c:1305 +#: sql_help.c:1308 sql_help.c:1310 sql_help.c:1355 sql_help.c:1357 +#: sql_help.c:1364 sql_help.c:1373 sql_help.c:1378 sql_help.c:1630 +#: sql_help.c:1633 sql_help.c:1637 sql_help.c:1673 sql_help.c:1788 +#: sql_help.c:1901 sql_help.c:1907 sql_help.c:1920 sql_help.c:1921 +#: sql_help.c:1922 sql_help.c:2243 sql_help.c:2256 sql_help.c:2301 +#: sql_help.c:2367 sql_help.c:2373 sql_help.c:2406 sql_help.c:2633 +#: sql_help.c:2661 sql_help.c:2662 sql_help.c:2769 sql_help.c:2777 +#: sql_help.c:2787 sql_help.c:2790 sql_help.c:2800 sql_help.c:2804 +#: sql_help.c:2827 sql_help.c:2829 sql_help.c:2836 sql_help.c:2849 +#: sql_help.c:2854 sql_help.c:2872 sql_help.c:2998 sql_help.c:3134 +#: sql_help.c:3737 sql_help.c:3738 sql_help.c:3819 sql_help.c:3834 +#: sql_help.c:3836 sql_help.c:3838 sql_help.c:4085 sql_help.c:4086 +#: sql_help.c:4191 sql_help.c:4342 sql_help.c:4581 sql_help.c:4623 +#: sql_help.c:4625 sql_help.c:4627 sql_help.c:4673 sql_help.c:4801 msgid "column_name" msgstr "назва_стовпця" -#: sql_help.c:444 sql_help.c:664 sql_help.c:1262 +#: sql_help.c:444 sql_help.c:664 sql_help.c:1266 sql_help.c:1638 msgid "new_column_name" msgstr "нова_назва_стовпця" #: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 -#: sql_help.c:1278 sql_help.c:1530 +#: sql_help.c:1282 sql_help.c:1539 msgid "where action is one of:" msgstr "де допустима дія:" -#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1280 -#: sql_help.c:1285 sql_help.c:1532 sql_help.c:1536 sql_help.c:2141 -#: sql_help.c:2231 sql_help.c:2427 sql_help.c:2607 sql_help.c:2751 -#: sql_help.c:3024 sql_help.c:3891 +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1284 +#: sql_help.c:1289 sql_help.c:1541 sql_help.c:1545 sql_help.c:2156 +#: sql_help.c:2244 sql_help.c:2446 sql_help.c:2626 sql_help.c:2770 +#: sql_help.c:3043 sql_help.c:3921 msgid "data_type" msgstr "тип_даних" -#: sql_help.c:452 sql_help.c:457 sql_help.c:1281 sql_help.c:1286 -#: sql_help.c:1533 sql_help.c:1537 sql_help.c:2142 sql_help.c:2234 -#: sql_help.c:2352 sql_help.c:2752 sql_help.c:2760 sql_help.c:2773 -#: sql_help.c:2787 sql_help.c:3025 sql_help.c:3031 sql_help.c:3799 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1285 sql_help.c:1290 +#: sql_help.c:1542 sql_help.c:1546 sql_help.c:2157 sql_help.c:2247 +#: sql_help.c:2369 sql_help.c:2771 sql_help.c:2779 sql_help.c:2792 +#: sql_help.c:2806 sql_help.c:3044 sql_help.c:3050 sql_help.c:3829 msgid "collation" msgstr "правила_сортування" -#: sql_help.c:453 sql_help.c:1282 sql_help.c:2235 sql_help.c:2244 -#: sql_help.c:2753 sql_help.c:2769 sql_help.c:2782 +#: sql_help.c:453 sql_help.c:1286 sql_help.c:2248 sql_help.c:2257 +#: sql_help.c:2772 sql_help.c:2788 sql_help.c:2801 msgid "column_constraint" msgstr "обмеження_стовпця" -#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1299 +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1304 sql_help.c:4670 msgid "integer" msgstr "ціле" -#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1301 -#: sql_help.c:1304 +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1306 +#: sql_help.c:1309 msgid "attribute_option" msgstr "параметр_атрибуту" -#: sql_help.c:473 sql_help.c:1306 sql_help.c:2236 sql_help.c:2245 -#: sql_help.c:2754 sql_help.c:2770 sql_help.c:2783 +#: sql_help.c:473 sql_help.c:1311 sql_help.c:2249 sql_help.c:2258 +#: sql_help.c:2773 sql_help.c:2789 sql_help.c:2802 msgid "table_constraint" msgstr "обмеження_таблиці" -#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1311 -#: sql_help.c:1312 sql_help.c:1313 sql_help.c:1314 sql_help.c:1829 +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1316 +#: sql_help.c:1317 sql_help.c:1318 sql_help.c:1319 sql_help.c:1842 msgid "trigger_name" msgstr "ім'я_тригеру" -#: sql_help.c:480 sql_help.c:481 sql_help.c:1324 sql_help.c:1325 -#: sql_help.c:2237 sql_help.c:2242 sql_help.c:2757 sql_help.c:2780 +#: sql_help.c:480 sql_help.c:481 sql_help.c:1329 sql_help.c:1330 +#: sql_help.c:2250 sql_help.c:2255 sql_help.c:2776 sql_help.c:2799 msgid "parent_table" msgstr "батьківська_таблиця" #: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 -#: sql_help.c:1493 sql_help.c:2173 +#: sql_help.c:1498 sql_help.c:2187 msgid "extension_name" msgstr "ім'я_розширення" -#: sql_help.c:541 sql_help.c:1001 sql_help.c:2292 +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2305 msgid "execution_cost" msgstr "вартість_виконання" -#: sql_help.c:542 sql_help.c:1002 sql_help.c:2293 +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2306 msgid "result_rows" msgstr "рядки_результату" -#: sql_help.c:543 sql_help.c:2294 +#: sql_help.c:543 sql_help.c:2307 msgid "support_function" msgstr "функція_підтримки" #: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 -#: sql_help.c:940 sql_help.c:943 sql_help.c:1571 sql_help.c:1579 -#: sql_help.c:1583 sql_help.c:1586 sql_help.c:1589 sql_help.c:2585 -#: sql_help.c:2587 sql_help.c:2590 sql_help.c:2591 sql_help.c:3707 -#: sql_help.c:3711 sql_help.c:3714 sql_help.c:3716 sql_help.c:3718 -#: sql_help.c:3720 sql_help.c:3722 sql_help.c:3728 sql_help.c:3730 -#: sql_help.c:3732 sql_help.c:3734 sql_help.c:3736 sql_help.c:3738 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1580 sql_help.c:1588 +#: sql_help.c:1592 sql_help.c:1595 sql_help.c:1598 sql_help.c:2604 +#: sql_help.c:2606 sql_help.c:2609 sql_help.c:2610 sql_help.c:3736 +#: sql_help.c:3740 sql_help.c:3743 sql_help.c:3745 sql_help.c:3747 +#: sql_help.c:3749 sql_help.c:3751 sql_help.c:3757 sql_help.c:3759 +#: sql_help.c:3761 sql_help.c:3763 sql_help.c:3765 sql_help.c:3767 +#: sql_help.c:3769 sql_help.c:3770 sql_help.c:4084 sql_help.c:4088 +#: sql_help.c:4091 sql_help.c:4093 sql_help.c:4095 sql_help.c:4097 +#: sql_help.c:4099 sql_help.c:4105 sql_help.c:4107 sql_help.c:4109 +#: sql_help.c:4111 sql_help.c:4113 sql_help.c:4115 sql_help.c:4117 +#: sql_help.c:4118 msgid "role_specification" msgstr "вказання_ролі" -#: sql_help.c:565 sql_help.c:567 sql_help.c:1602 sql_help.c:2116 -#: sql_help.c:2593 sql_help.c:3100 sql_help.c:3545 sql_help.c:4380 +#: sql_help.c:565 sql_help.c:567 sql_help.c:1611 sql_help.c:2130 +#: sql_help.c:2612 sql_help.c:3119 sql_help.c:3570 sql_help.c:4427 msgid "user_name" msgstr "ім'я_користувача" -#: sql_help.c:568 sql_help.c:945 sql_help.c:1591 sql_help.c:2592 -#: sql_help.c:3739 +#: sql_help.c:568 sql_help.c:945 sql_help.c:1600 sql_help.c:2611 +#: sql_help.c:3771 sql_help.c:4119 msgid "where role_specification can be:" msgstr "де вказання_ролі може бути:" @@ -4175,22 +4337,22 @@ msgstr "де вказання_ролі може бути:" msgid "group_name" msgstr "ім'я_групи" -#: sql_help.c:591 sql_help.c:1371 sql_help.c:2121 sql_help.c:2357 -#: sql_help.c:2391 sql_help.c:2765 sql_help.c:2778 sql_help.c:2792 -#: sql_help.c:2833 sql_help.c:2857 sql_help.c:2869 sql_help.c:3735 -#: sql_help.c:4068 +#: sql_help.c:591 sql_help.c:1376 sql_help.c:2136 sql_help.c:2376 +#: sql_help.c:2410 sql_help.c:2784 sql_help.c:2797 sql_help.c:2811 +#: sql_help.c:2852 sql_help.c:2876 sql_help.c:2888 sql_help.c:3764 +#: sql_help.c:4112 msgid "tablespace_name" msgstr "ім'я_табличного_простору" -#: sql_help.c:593 sql_help.c:681 sql_help.c:1319 sql_help.c:1328 -#: sql_help.c:1366 sql_help.c:1709 +#: sql_help.c:593 sql_help.c:681 sql_help.c:1324 sql_help.c:1333 +#: sql_help.c:1371 sql_help.c:1722 msgid "index_name" msgstr "назва_індексу" -#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1321 -#: sql_help.c:1323 sql_help.c:1369 sql_help.c:2355 sql_help.c:2389 -#: sql_help.c:2763 sql_help.c:2776 sql_help.c:2790 sql_help.c:2831 -#: sql_help.c:2855 +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1326 +#: sql_help.c:1328 sql_help.c:1374 sql_help.c:2374 sql_help.c:2408 +#: sql_help.c:2782 sql_help.c:2795 sql_help.c:2809 sql_help.c:2850 +#: sql_help.c:2874 msgid "storage_parameter" msgstr "параметр_зберігання" @@ -4198,1769 +4360,1771 @@ msgstr "параметр_зберігання" msgid "column_number" msgstr "номер_стовпця" -#: sql_help.c:626 sql_help.c:1792 sql_help.c:4155 +#: sql_help.c:626 sql_help.c:1805 sql_help.c:4202 msgid "large_object_oid" msgstr "oid_великого_об'єкта" -#: sql_help.c:713 sql_help.c:2412 +#: sql_help.c:713 sql_help.c:2431 msgid "res_proc" msgstr "res_процедура" -#: sql_help.c:714 sql_help.c:2413 +#: sql_help.c:714 sql_help.c:2432 msgid "join_proc" msgstr "процедура_приєднання" -#: sql_help.c:766 sql_help.c:778 sql_help.c:2430 +#: sql_help.c:766 sql_help.c:778 sql_help.c:2449 msgid "strategy_number" msgstr "номер_стратегії" #: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 -#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2432 sql_help.c:2433 -#: sql_help.c:2436 sql_help.c:2437 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2451 sql_help.c:2452 +#: sql_help.c:2455 sql_help.c:2456 msgid "op_type" msgstr "тип_операції" -#: sql_help.c:770 sql_help.c:2434 +#: sql_help.c:770 sql_help.c:2453 msgid "sort_family_name" msgstr "ім'я_родини_сортування" -#: sql_help.c:771 sql_help.c:781 sql_help.c:2435 +#: sql_help.c:771 sql_help.c:781 sql_help.c:2454 msgid "support_number" msgstr "номер_підтримки" -#: sql_help.c:775 sql_help.c:2058 sql_help.c:2439 sql_help.c:2946 -#: sql_help.c:2948 +#: sql_help.c:775 sql_help.c:2071 sql_help.c:2458 sql_help.c:2965 +#: sql_help.c:2967 msgid "argument_type" msgstr "тип_аргументу" #: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 -#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1489 sql_help.c:1492 -#: sql_help.c:1659 sql_help.c:1708 sql_help.c:1777 sql_help.c:1802 -#: sql_help.c:1815 sql_help.c:1830 sql_help.c:1887 sql_help.c:1893 -#: sql_help.c:2229 sql_help.c:2241 sql_help.c:2348 sql_help.c:2386 -#: sql_help.c:2463 sql_help.c:2506 sql_help.c:2562 sql_help.c:2613 -#: sql_help.c:2644 sql_help.c:2749 sql_help.c:2766 sql_help.c:2779 -#: sql_help.c:2852 sql_help.c:2972 sql_help.c:3149 sql_help.c:3366 -#: sql_help.c:3415 sql_help.c:3521 sql_help.c:3705 sql_help.c:3710 -#: sql_help.c:3755 sql_help.c:3787 sql_help.c:4038 sql_help.c:4043 -#: sql_help.c:4143 sql_help.c:4250 sql_help.c:4252 sql_help.c:4301 -#: sql_help.c:4340 sql_help.c:4489 sql_help.c:4491 sql_help.c:4540 -#: sql_help.c:4574 sql_help.c:4623 sql_help.c:4707 sql_help.c:4709 -#: sql_help.c:4758 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1494 sql_help.c:1497 +#: sql_help.c:1672 sql_help.c:1721 sql_help.c:1790 sql_help.c:1815 +#: sql_help.c:1828 sql_help.c:1843 sql_help.c:1900 sql_help.c:1906 +#: sql_help.c:2242 sql_help.c:2254 sql_help.c:2365 sql_help.c:2405 +#: sql_help.c:2482 sql_help.c:2525 sql_help.c:2581 sql_help.c:2632 +#: sql_help.c:2663 sql_help.c:2768 sql_help.c:2785 sql_help.c:2798 +#: sql_help.c:2871 sql_help.c:2991 sql_help.c:3168 sql_help.c:3391 +#: sql_help.c:3440 sql_help.c:3546 sql_help.c:3734 sql_help.c:3739 +#: sql_help.c:3785 sql_help.c:3817 sql_help.c:4082 sql_help.c:4087 +#: sql_help.c:4190 sql_help.c:4297 sql_help.c:4299 sql_help.c:4348 +#: sql_help.c:4387 sql_help.c:4536 sql_help.c:4538 sql_help.c:4587 +#: sql_help.c:4621 sql_help.c:4672 sql_help.c:4756 sql_help.c:4758 +#: sql_help.c:4807 msgid "table_name" msgstr "ім'я_таблиці" -#: sql_help.c:811 sql_help.c:2465 +#: sql_help.c:811 sql_help.c:2484 msgid "using_expression" msgstr "вираз_використання" -#: sql_help.c:812 sql_help.c:2466 +#: sql_help.c:812 sql_help.c:2485 msgid "check_expression" msgstr "вираз_перевірки" -#: sql_help.c:886 sql_help.c:2507 +#: sql_help.c:886 sql_help.c:2526 msgid "publication_parameter" msgstr "параметр_публікації" -#: sql_help.c:929 sql_help.c:1575 sql_help.c:2327 sql_help.c:2539 -#: sql_help.c:3083 +#: sql_help.c:929 sql_help.c:1584 sql_help.c:2344 sql_help.c:2558 +#: sql_help.c:3102 msgid "password" msgstr "пароль" -#: sql_help.c:930 sql_help.c:1576 sql_help.c:2328 sql_help.c:2540 -#: sql_help.c:3084 +#: sql_help.c:930 sql_help.c:1585 sql_help.c:2345 sql_help.c:2559 +#: sql_help.c:3103 msgid "timestamp" msgstr "мітка часу" -#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1580 -#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:3715 -#: sql_help.c:4048 +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1589 +#: sql_help.c:1593 sql_help.c:1596 sql_help.c:1599 sql_help.c:3744 +#: sql_help.c:4092 msgid "database_name" msgstr "назва_бази_даних" -#: sql_help.c:1048 sql_help.c:2608 +#: sql_help.c:1048 sql_help.c:2627 msgid "increment" msgstr "інкремент" -#: sql_help.c:1049 sql_help.c:2609 +#: sql_help.c:1049 sql_help.c:2628 msgid "minvalue" msgstr "мін_значення" -#: sql_help.c:1050 sql_help.c:2610 +#: sql_help.c:1050 sql_help.c:2629 msgid "maxvalue" msgstr "макс_значення" -#: sql_help.c:1051 sql_help.c:2611 sql_help.c:4248 sql_help.c:4338 -#: sql_help.c:4487 sql_help.c:4640 sql_help.c:4705 +#: sql_help.c:1051 sql_help.c:2630 sql_help.c:4295 sql_help.c:4385 +#: sql_help.c:4534 sql_help.c:4689 sql_help.c:4754 msgid "start" msgstr "початок" -#: sql_help.c:1052 sql_help.c:1296 +#: sql_help.c:1052 sql_help.c:1301 msgid "restart" msgstr "перезапуск" -#: sql_help.c:1053 sql_help.c:2612 +#: sql_help.c:1053 sql_help.c:2631 msgid "cache" msgstr "кеш" -#: sql_help.c:1110 sql_help.c:2656 +#: sql_help.c:1097 +msgid "new_target" +msgstr "нова_ціль" + +#: sql_help.c:1113 sql_help.c:2675 msgid "conninfo" msgstr "інформація_підключення" -#: sql_help.c:1112 sql_help.c:2657 +#: sql_help.c:1115 sql_help.c:2676 msgid "publication_name" msgstr "назва_публікації" -#: sql_help.c:1113 +#: sql_help.c:1116 msgid "set_publication_option" msgstr "опція_set_publication" -#: sql_help.c:1116 +#: sql_help.c:1119 msgid "refresh_option" msgstr "опція_оновлення" -#: sql_help.c:1121 sql_help.c:2658 +#: sql_help.c:1124 sql_help.c:2677 msgid "subscription_parameter" msgstr "параметр_підписки" -#: sql_help.c:1274 sql_help.c:1277 +#: sql_help.c:1278 sql_help.c:1281 msgid "partition_name" msgstr "ім'я_розділу" -#: sql_help.c:1275 sql_help.c:2246 sql_help.c:2784 +#: sql_help.c:1279 sql_help.c:2259 sql_help.c:2803 msgid "partition_bound_spec" msgstr "специфікація_рамок_розділу" -#: sql_help.c:1293 sql_help.c:1340 sql_help.c:2798 +#: sql_help.c:1298 sql_help.c:1345 sql_help.c:2817 msgid "sequence_options" msgstr "опції_послідовності" -#: sql_help.c:1295 +#: sql_help.c:1300 msgid "sequence_option" msgstr "опція_послідовності" -#: sql_help.c:1307 +#: sql_help.c:1312 msgid "table_constraint_using_index" msgstr "індекс_обмеження_таблиці" -#: sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 sql_help.c:1318 +#: sql_help.c:1320 sql_help.c:1321 sql_help.c:1322 sql_help.c:1323 msgid "rewrite_rule_name" msgstr "ім'я_правила_перезапису" -#: sql_help.c:1329 sql_help.c:2823 +#: sql_help.c:1334 sql_help.c:2842 msgid "and partition_bound_spec is:" msgstr "і специфікація_рамок_розділу:" -#: sql_help.c:1330 sql_help.c:1331 sql_help.c:1332 sql_help.c:2824 -#: sql_help.c:2825 sql_help.c:2826 +#: sql_help.c:1335 sql_help.c:1336 sql_help.c:1337 sql_help.c:2843 +#: sql_help.c:2844 sql_help.c:2845 msgid "partition_bound_expr" msgstr "код_секції" -#: sql_help.c:1333 sql_help.c:1334 sql_help.c:2827 sql_help.c:2828 +#: sql_help.c:1338 sql_help.c:1339 sql_help.c:2846 sql_help.c:2847 msgid "numeric_literal" msgstr "числовий_літерал" -#: sql_help.c:1335 +#: sql_help.c:1340 msgid "and column_constraint is:" msgstr "і обмеження_стовпця:" -#: sql_help.c:1338 sql_help.c:2253 sql_help.c:2286 sql_help.c:2486 -#: sql_help.c:2796 +#: sql_help.c:1343 sql_help.c:2266 sql_help.c:2299 sql_help.c:2505 +#: sql_help.c:2815 msgid "default_expr" msgstr "вираз_за_замовчуванням" -#: sql_help.c:1339 sql_help.c:2254 sql_help.c:2797 +#: sql_help.c:1344 sql_help.c:2267 sql_help.c:2816 msgid "generation_expr" msgstr "код_генерації" -#: sql_help.c:1341 sql_help.c:1342 sql_help.c:1351 sql_help.c:1353 -#: sql_help.c:1357 sql_help.c:2799 sql_help.c:2800 sql_help.c:2809 -#: sql_help.c:2811 sql_help.c:2815 +#: sql_help.c:1346 sql_help.c:1347 sql_help.c:1356 sql_help.c:1358 +#: sql_help.c:1362 sql_help.c:2818 sql_help.c:2819 sql_help.c:2828 +#: sql_help.c:2830 sql_help.c:2834 msgid "index_parameters" msgstr "параметри_індексу" -#: sql_help.c:1343 sql_help.c:1360 sql_help.c:2801 sql_help.c:2818 +#: sql_help.c:1348 sql_help.c:1365 sql_help.c:2820 sql_help.c:2837 msgid "reftable" msgstr "залежна_таблиця" -#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2802 sql_help.c:2819 +#: sql_help.c:1349 sql_help.c:1366 sql_help.c:2821 sql_help.c:2838 msgid "refcolumn" msgstr "залежний_стовпець" -#: sql_help.c:1345 sql_help.c:1346 sql_help.c:1362 sql_help.c:1363 -#: sql_help.c:2803 sql_help.c:2804 sql_help.c:2820 sql_help.c:2821 +#: sql_help.c:1350 sql_help.c:1351 sql_help.c:1367 sql_help.c:1368 +#: sql_help.c:2822 sql_help.c:2823 sql_help.c:2839 sql_help.c:2840 msgid "referential_action" msgstr "дія_посилання" -#: sql_help.c:1347 sql_help.c:2255 sql_help.c:2805 +#: sql_help.c:1352 sql_help.c:2268 sql_help.c:2824 msgid "and table_constraint is:" msgstr "і обмеження_таблиці:" -#: sql_help.c:1355 sql_help.c:2813 +#: sql_help.c:1360 sql_help.c:2832 msgid "exclude_element" msgstr "об'єкт_виключення" -#: sql_help.c:1356 sql_help.c:2814 sql_help.c:4246 sql_help.c:4336 -#: sql_help.c:4485 sql_help.c:4638 sql_help.c:4703 +#: sql_help.c:1361 sql_help.c:2833 sql_help.c:4293 sql_help.c:4383 +#: sql_help.c:4532 sql_help.c:4687 sql_help.c:4752 msgid "operator" msgstr "оператор" -#: sql_help.c:1358 sql_help.c:2358 sql_help.c:2816 +#: sql_help.c:1363 sql_help.c:2377 sql_help.c:2835 msgid "predicate" msgstr "предикат" -#: sql_help.c:1364 +#: sql_help.c:1369 msgid "and table_constraint_using_index is:" msgstr "і індекс_обмеження_таблиці:" -#: sql_help.c:1367 sql_help.c:2829 +#: sql_help.c:1372 sql_help.c:2848 msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" msgstr "параметри_індексу в обмеженнях UNIQUE, PRIMARY KEY, EXCLUDE:" -#: sql_help.c:1372 sql_help.c:2834 +#: sql_help.c:1377 sql_help.c:2853 msgid "exclude_element in an EXCLUDE constraint is:" msgstr "елемент_виключення в обмеженні EXCLUDE:" -#: sql_help.c:1375 sql_help.c:2353 sql_help.c:2761 sql_help.c:2774 -#: sql_help.c:2788 sql_help.c:2837 sql_help.c:3800 +#: sql_help.c:1380 sql_help.c:2370 sql_help.c:2780 sql_help.c:2793 +#: sql_help.c:2807 sql_help.c:2856 sql_help.c:3830 msgid "opclass" msgstr "клас_оператора" -#: sql_help.c:1391 sql_help.c:1394 sql_help.c:2872 +#: sql_help.c:1396 sql_help.c:1399 sql_help.c:2891 msgid "tablespace_option" msgstr "опція_табличного_простору" -#: sql_help.c:1415 sql_help.c:1418 sql_help.c:1424 sql_help.c:1428 +#: sql_help.c:1420 sql_help.c:1423 sql_help.c:1429 sql_help.c:1433 msgid "token_type" msgstr "тип_токену" -#: sql_help.c:1416 sql_help.c:1419 +#: sql_help.c:1421 sql_help.c:1424 msgid "dictionary_name" msgstr "ім'я_словника" -#: sql_help.c:1421 sql_help.c:1425 +#: sql_help.c:1426 sql_help.c:1430 msgid "old_dictionary" msgstr "старий_словник" -#: sql_help.c:1422 sql_help.c:1426 +#: sql_help.c:1427 sql_help.c:1431 msgid "new_dictionary" msgstr "новий_словник" -#: sql_help.c:1518 sql_help.c:1531 sql_help.c:1534 sql_help.c:1535 -#: sql_help.c:3023 +#: sql_help.c:1526 sql_help.c:1540 sql_help.c:1543 sql_help.c:1544 +#: sql_help.c:3042 msgid "attribute_name" msgstr "ім'я_атрибута" -#: sql_help.c:1519 +#: sql_help.c:1527 msgid "new_attribute_name" msgstr "нове_ім'я_атрибута" -#: sql_help.c:1525 sql_help.c:1529 +#: sql_help.c:1531 sql_help.c:1535 msgid "new_enum_value" msgstr "нове_значення_перерахування" -#: sql_help.c:1526 +#: sql_help.c:1532 msgid "neighbor_enum_value" msgstr "сусіднє_значення_перерахування" -#: sql_help.c:1528 +#: sql_help.c:1534 msgid "existing_enum_value" msgstr "існуюче_значення_перерахування" -#: sql_help.c:1603 sql_help.c:2238 sql_help.c:2247 sql_help.c:2624 -#: sql_help.c:3101 sql_help.c:3546 sql_help.c:3721 sql_help.c:3756 -#: sql_help.c:4054 +#: sql_help.c:1537 +msgid "property" +msgstr "властивість" + +#: sql_help.c:1612 sql_help.c:2251 sql_help.c:2260 sql_help.c:2643 +#: sql_help.c:3120 sql_help.c:3571 sql_help.c:3750 sql_help.c:3786 +#: sql_help.c:4098 msgid "server_name" msgstr "назва_серверу" -#: sql_help.c:1631 sql_help.c:1634 sql_help.c:3116 +#: sql_help.c:1644 sql_help.c:1647 sql_help.c:3135 msgid "view_option_name" msgstr "ім'я_параметра_представлення" -#: sql_help.c:1632 sql_help.c:3117 +#: sql_help.c:1645 sql_help.c:3136 msgid "view_option_value" msgstr "значення_параметра_представлення" -#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4611 sql_help.c:4612 +#: sql_help.c:1666 sql_help.c:1667 sql_help.c:4659 sql_help.c:4660 msgid "table_and_columns" msgstr "таблиця_і_стовпці" -#: sql_help.c:1655 sql_help.c:1899 sql_help.c:3593 sql_help.c:4613 +#: sql_help.c:1668 sql_help.c:1912 sql_help.c:3619 sql_help.c:3963 +#: sql_help.c:4661 msgid "where option can be one of:" msgstr "де параметр може бути одним із:" -#: sql_help.c:1656 sql_help.c:1657 sql_help.c:1901 sql_help.c:1904 -#: sql_help.c:2083 sql_help.c:3594 sql_help.c:3595 sql_help.c:3596 -#: sql_help.c:3597 sql_help.c:3598 sql_help.c:3599 sql_help.c:3600 -#: sql_help.c:4614 sql_help.c:4615 sql_help.c:4616 sql_help.c:4617 -#: sql_help.c:4618 sql_help.c:4619 sql_help.c:4620 sql_help.c:4621 +#: sql_help.c:1669 sql_help.c:1670 sql_help.c:1914 sql_help.c:1917 +#: sql_help.c:2096 sql_help.c:3620 sql_help.c:3621 sql_help.c:3622 +#: sql_help.c:3623 sql_help.c:3624 sql_help.c:3625 sql_help.c:3626 +#: sql_help.c:3627 sql_help.c:4662 sql_help.c:4663 sql_help.c:4664 +#: sql_help.c:4665 sql_help.c:4666 sql_help.c:4667 sql_help.c:4668 +#: sql_help.c:4669 msgid "boolean" msgstr "логічний" -#: sql_help.c:1658 sql_help.c:4622 +#: sql_help.c:1671 sql_help.c:4671 msgid "and table_and_columns is:" msgstr "і таблиця_і_стовпці:" -#: sql_help.c:1674 sql_help.c:4396 sql_help.c:4398 sql_help.c:4422 +#: sql_help.c:1687 sql_help.c:4443 sql_help.c:4445 sql_help.c:4469 msgid "transaction_mode" msgstr "режим_транзакції" -#: sql_help.c:1675 sql_help.c:4399 sql_help.c:4423 +#: sql_help.c:1688 sql_help.c:4446 sql_help.c:4470 msgid "where transaction_mode is one of:" msgstr "де режим_транзакції один з:" -#: sql_help.c:1684 sql_help.c:4256 sql_help.c:4265 sql_help.c:4269 -#: sql_help.c:4273 sql_help.c:4276 sql_help.c:4495 sql_help.c:4504 -#: sql_help.c:4508 sql_help.c:4512 sql_help.c:4515 sql_help.c:4713 -#: sql_help.c:4722 sql_help.c:4726 sql_help.c:4730 sql_help.c:4733 +#: sql_help.c:1697 sql_help.c:4303 sql_help.c:4312 sql_help.c:4316 +#: sql_help.c:4320 sql_help.c:4323 sql_help.c:4542 sql_help.c:4551 +#: sql_help.c:4555 sql_help.c:4559 sql_help.c:4562 sql_help.c:4762 +#: sql_help.c:4771 sql_help.c:4775 sql_help.c:4779 sql_help.c:4782 msgid "argument" msgstr "аргумент" -#: sql_help.c:1774 +#: sql_help.c:1787 msgid "relation_name" msgstr "назва_відношення" -#: sql_help.c:1779 sql_help.c:3717 sql_help.c:4050 +#: sql_help.c:1792 sql_help.c:3746 sql_help.c:4094 msgid "domain_name" msgstr "назва_домену" -#: sql_help.c:1801 +#: sql_help.c:1814 msgid "policy_name" msgstr "назва_політики" -#: sql_help.c:1814 +#: sql_help.c:1827 msgid "rule_name" msgstr "назва_правила" -#: sql_help.c:1833 +#: sql_help.c:1846 msgid "text" msgstr "текст" -#: sql_help.c:1858 sql_help.c:3900 sql_help.c:4088 +#: sql_help.c:1871 sql_help.c:3930 sql_help.c:4135 msgid "transaction_id" msgstr "ідентифікатор_транзакції" -#: sql_help.c:1889 sql_help.c:1896 sql_help.c:3826 +#: sql_help.c:1902 sql_help.c:1909 sql_help.c:3856 msgid "filename" msgstr "ім'я файлу" -#: sql_help.c:1890 sql_help.c:1897 sql_help.c:2564 sql_help.c:2565 -#: sql_help.c:2566 +#: sql_help.c:1903 sql_help.c:1910 sql_help.c:2583 sql_help.c:2584 +#: sql_help.c:2585 msgid "command" msgstr "команда" -#: sql_help.c:1892 sql_help.c:2563 sql_help.c:2975 sql_help.c:3152 -#: sql_help.c:3810 sql_help.c:4239 sql_help.c:4241 sql_help.c:4329 -#: sql_help.c:4331 sql_help.c:4478 sql_help.c:4480 sql_help.c:4583 -#: sql_help.c:4696 sql_help.c:4698 +#: sql_help.c:1905 sql_help.c:2582 sql_help.c:2994 sql_help.c:3171 +#: sql_help.c:3840 sql_help.c:4286 sql_help.c:4288 sql_help.c:4376 +#: sql_help.c:4378 sql_help.c:4525 sql_help.c:4527 sql_help.c:4630 +#: sql_help.c:4745 sql_help.c:4747 msgid "condition" msgstr "умова" -#: sql_help.c:1895 sql_help.c:2392 sql_help.c:2858 sql_help.c:3118 -#: sql_help.c:3136 sql_help.c:3791 +#: sql_help.c:1908 sql_help.c:2411 sql_help.c:2877 sql_help.c:3137 +#: sql_help.c:3155 sql_help.c:3821 msgid "query" msgstr "запит" -#: sql_help.c:1900 +#: sql_help.c:1913 msgid "format_name" msgstr "назва_формату" -#: sql_help.c:1902 +#: sql_help.c:1915 msgid "delimiter_character" msgstr "символ_роздільник" -#: sql_help.c:1903 +#: sql_help.c:1916 msgid "null_string" msgstr "представлення_NULL" -#: sql_help.c:1905 +#: sql_help.c:1918 msgid "quote_character" msgstr "символ_лапок" -#: sql_help.c:1906 +#: sql_help.c:1919 msgid "escape_character" msgstr "символ_екранування" -#: sql_help.c:1910 +#: sql_help.c:1923 msgid "encoding_name" msgstr "ім'я_кодування" -#: sql_help.c:1921 +#: sql_help.c:1934 msgid "access_method_type" msgstr "тип_метода_доступа" -#: sql_help.c:1992 sql_help.c:2011 sql_help.c:2014 +#: sql_help.c:2005 sql_help.c:2024 sql_help.c:2027 msgid "arg_data_type" msgstr "тип_даних_аргумента" -#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 +#: sql_help.c:2006 sql_help.c:2028 sql_help.c:2036 msgid "sfunc" msgstr "функція_стану" -#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 +#: sql_help.c:2007 sql_help.c:2029 sql_help.c:2037 msgid "state_data_type" msgstr "тип_даних_стану" -#: sql_help.c:1995 sql_help.c:2017 sql_help.c:2025 +#: sql_help.c:2008 sql_help.c:2030 sql_help.c:2038 msgid "state_data_size" msgstr "розмір_даних_стану" -#: sql_help.c:1996 sql_help.c:2018 sql_help.c:2026 +#: sql_help.c:2009 sql_help.c:2031 sql_help.c:2039 msgid "ffunc" msgstr "функція_завершення" -#: sql_help.c:1997 sql_help.c:2027 +#: sql_help.c:2010 sql_help.c:2040 msgid "combinefunc" msgstr "комбінуюча_функція" -#: sql_help.c:1998 sql_help.c:2028 +#: sql_help.c:2011 sql_help.c:2041 msgid "serialfunc" msgstr "функція_серіалізації" -#: sql_help.c:1999 sql_help.c:2029 +#: sql_help.c:2012 sql_help.c:2042 msgid "deserialfunc" msgstr "функція_десеріалізації" -#: sql_help.c:2000 sql_help.c:2019 sql_help.c:2030 +#: sql_help.c:2013 sql_help.c:2032 sql_help.c:2043 msgid "initial_condition" msgstr "початкова_умова" -#: sql_help.c:2001 sql_help.c:2031 +#: sql_help.c:2014 sql_help.c:2044 msgid "msfunc" msgstr "функція_стану_рух" -#: sql_help.c:2002 sql_help.c:2032 +#: sql_help.c:2015 sql_help.c:2045 msgid "minvfunc" msgstr "зворотна_функція_рух" -#: sql_help.c:2003 sql_help.c:2033 +#: sql_help.c:2016 sql_help.c:2046 msgid "mstate_data_type" msgstr "тип_даних_стану_рух" -#: sql_help.c:2004 sql_help.c:2034 +#: sql_help.c:2017 sql_help.c:2047 msgid "mstate_data_size" msgstr "розмір_даних_стану_рух" -#: sql_help.c:2005 sql_help.c:2035 +#: sql_help.c:2018 sql_help.c:2048 msgid "mffunc" msgstr "функція_завершення_рух" -#: sql_help.c:2006 sql_help.c:2036 +#: sql_help.c:2019 sql_help.c:2049 msgid "minitial_condition" msgstr "початкова_умова_рух" -#: sql_help.c:2007 sql_help.c:2037 +#: sql_help.c:2020 sql_help.c:2050 msgid "sort_operator" msgstr "оператор_сортування" -#: sql_help.c:2020 +#: sql_help.c:2033 msgid "or the old syntax" msgstr "або старий синтаксис" -#: sql_help.c:2022 +#: sql_help.c:2035 msgid "base_type" msgstr "базовий_тип" -#: sql_help.c:2079 +#: sql_help.c:2092 sql_help.c:2133 msgid "locale" msgstr "локаль" -#: sql_help.c:2080 sql_help.c:2119 +#: sql_help.c:2093 sql_help.c:2134 msgid "lc_collate" msgstr "код_правила_сортування" -#: sql_help.c:2081 sql_help.c:2120 +#: sql_help.c:2094 sql_help.c:2135 msgid "lc_ctype" msgstr "код_класифікації_символів" -#: sql_help.c:2082 sql_help.c:4141 +#: sql_help.c:2095 sql_help.c:4188 msgid "provider" msgstr "постачальник" -#: sql_help.c:2084 sql_help.c:2175 +#: sql_help.c:2097 sql_help.c:2189 msgid "version" msgstr "версія" -#: sql_help.c:2086 +#: sql_help.c:2099 msgid "existing_collation" msgstr "існуюче_правило_сортування" -#: sql_help.c:2096 +#: sql_help.c:2109 msgid "source_encoding" msgstr "початкове_кодування" -#: sql_help.c:2097 +#: sql_help.c:2110 msgid "dest_encoding" msgstr "цільве_кодування" -#: sql_help.c:2117 sql_help.c:2898 +#: sql_help.c:2131 sql_help.c:2917 msgid "template" msgstr "шаблон" -#: sql_help.c:2118 +#: sql_help.c:2132 msgid "encoding" msgstr "кодування" -#: sql_help.c:2144 +#: sql_help.c:2159 msgid "constraint" msgstr "обмеження" -#: sql_help.c:2145 +#: sql_help.c:2160 msgid "where constraint is:" msgstr "де обмеження:" -#: sql_help.c:2159 sql_help.c:2561 sql_help.c:2971 +#: sql_help.c:2174 sql_help.c:2580 sql_help.c:2990 msgid "event" msgstr "подія" -#: sql_help.c:2160 +#: sql_help.c:2175 msgid "filter_variable" msgstr "змінна_фільтру" -#: sql_help.c:2176 -msgid "old_version" -msgstr "стара_версія" - -#: sql_help.c:2250 sql_help.c:2793 +#: sql_help.c:2263 sql_help.c:2812 msgid "where column_constraint is:" msgstr "де обмеження_стовпців:" -#: sql_help.c:2287 +#: sql_help.c:2300 msgid "rettype" msgstr "тип_результату" -#: sql_help.c:2289 +#: sql_help.c:2302 msgid "column_type" msgstr "тип_стовпця" -#: sql_help.c:2298 sql_help.c:2492 +#: sql_help.c:2311 sql_help.c:2511 msgid "definition" msgstr "визначення" -#: sql_help.c:2299 sql_help.c:2493 +#: sql_help.c:2312 sql_help.c:2512 msgid "obj_file" msgstr "об'єктний_файл" -#: sql_help.c:2300 sql_help.c:2494 +#: sql_help.c:2313 sql_help.c:2513 msgid "link_symbol" msgstr "символ_експорту" -#: sql_help.c:2334 sql_help.c:2546 sql_help.c:3090 +#: sql_help.c:2351 sql_help.c:2565 sql_help.c:3109 msgid "uid" msgstr "uid" -#: sql_help.c:2349 sql_help.c:2388 sql_help.c:2762 sql_help.c:2775 -#: sql_help.c:2789 sql_help.c:2854 +#: sql_help.c:2366 sql_help.c:2407 sql_help.c:2781 sql_help.c:2794 +#: sql_help.c:2808 sql_help.c:2873 msgid "method" msgstr "метод" -#: sql_help.c:2370 +#: sql_help.c:2371 +msgid "opclass_parameter" +msgstr "opclass_parameter" + +#: sql_help.c:2388 msgid "call_handler" msgstr "обробник_виклику" -#: sql_help.c:2371 +#: sql_help.c:2389 msgid "inline_handler" msgstr "обробник_впровадженого_коду" -#: sql_help.c:2372 +#: sql_help.c:2390 msgid "valfunction" msgstr "функція_перевірки" -#: sql_help.c:2410 +#: sql_help.c:2429 msgid "com_op" msgstr "комут_оператор" -#: sql_help.c:2411 +#: sql_help.c:2430 msgid "neg_op" msgstr "зворотній_оператор" -#: sql_help.c:2429 +#: sql_help.c:2448 msgid "family_name" msgstr "назва_сімейства" -#: sql_help.c:2440 +#: sql_help.c:2459 msgid "storage_type" msgstr "тип_зберігання" -#: sql_help.c:2567 sql_help.c:2978 +#: sql_help.c:2586 sql_help.c:2997 msgid "where event can be one of:" msgstr "де подія може бути однією з:" -#: sql_help.c:2586 sql_help.c:2588 +#: sql_help.c:2605 sql_help.c:2607 msgid "schema_element" msgstr "елемент_схеми" -#: sql_help.c:2625 +#: sql_help.c:2644 msgid "server_type" msgstr "тип_серверу" -#: sql_help.c:2626 +#: sql_help.c:2645 msgid "server_version" msgstr "версія_серверу" -#: sql_help.c:2627 sql_help.c:3719 sql_help.c:4052 +#: sql_help.c:2646 sql_help.c:3748 sql_help.c:4096 msgid "fdw_name" msgstr "назва_fdw" -#: sql_help.c:2640 +#: sql_help.c:2659 msgid "statistics_name" msgstr "назва_статистики" -#: sql_help.c:2641 +#: sql_help.c:2660 msgid "statistics_kind" msgstr "вид_статистики" -#: sql_help.c:2655 +#: sql_help.c:2674 msgid "subscription_name" msgstr "назва_підписки" -#: sql_help.c:2755 +#: sql_help.c:2774 msgid "source_table" msgstr "вихідна_таблиця" -#: sql_help.c:2756 +#: sql_help.c:2775 msgid "like_option" msgstr "параметр_породження" -#: sql_help.c:2822 +#: sql_help.c:2841 msgid "and like_option is:" msgstr "і параметр_породження:" -#: sql_help.c:2871 +#: sql_help.c:2890 msgid "directory" msgstr "каталог" -#: sql_help.c:2885 +#: sql_help.c:2904 msgid "parser_name" msgstr "назва_парсера" -#: sql_help.c:2886 +#: sql_help.c:2905 msgid "source_config" msgstr "початкова_конфігурація" -#: sql_help.c:2915 +#: sql_help.c:2934 msgid "start_function" msgstr "функція_початку" -#: sql_help.c:2916 +#: sql_help.c:2935 msgid "gettoken_function" msgstr "функція_видачі_токену" -#: sql_help.c:2917 +#: sql_help.c:2936 msgid "end_function" msgstr "функція_завершення" -#: sql_help.c:2918 +#: sql_help.c:2937 msgid "lextypes_function" msgstr "функція_лекс_типів" -#: sql_help.c:2919 +#: sql_help.c:2938 msgid "headline_function" msgstr "функція_створення_заголовків" -#: sql_help.c:2931 +#: sql_help.c:2950 msgid "init_function" msgstr "функція_ініціалізації" -#: sql_help.c:2932 +#: sql_help.c:2951 msgid "lexize_function" msgstr "функція_виділення_лексем" -#: sql_help.c:2945 +#: sql_help.c:2964 msgid "from_sql_function_name" msgstr "ім'я_функції_з_sql" -#: sql_help.c:2947 +#: sql_help.c:2966 msgid "to_sql_function_name" msgstr "ім'я_функції_в_sql" -#: sql_help.c:2973 +#: sql_help.c:2992 msgid "referenced_table_name" msgstr "ім'я_залежної_таблиці" -#: sql_help.c:2974 +#: sql_help.c:2993 msgid "transition_relation_name" msgstr "ім'я_перехідного_відношення" -#: sql_help.c:2977 +#: sql_help.c:2996 msgid "arguments" msgstr "аргументи" -#: sql_help.c:3027 sql_help.c:4174 +#: sql_help.c:3046 sql_help.c:4221 msgid "label" msgstr "мітка" -#: sql_help.c:3029 +#: sql_help.c:3048 msgid "subtype" msgstr "підтип" -#: sql_help.c:3030 +#: sql_help.c:3049 msgid "subtype_operator_class" msgstr "клас_оператора_підтипу" -#: sql_help.c:3032 +#: sql_help.c:3051 msgid "canonical_function" msgstr "канонічна_функція" -#: sql_help.c:3033 +#: sql_help.c:3052 msgid "subtype_diff_function" msgstr "функція_розбіжностей_підтипу" -#: sql_help.c:3035 +#: sql_help.c:3054 msgid "input_function" msgstr "функція_вводу" -#: sql_help.c:3036 +#: sql_help.c:3055 msgid "output_function" msgstr "функція_виводу" -#: sql_help.c:3037 +#: sql_help.c:3056 msgid "receive_function" msgstr "функція_отримання" -#: sql_help.c:3038 +#: sql_help.c:3057 msgid "send_function" msgstr "функція_відправки" -#: sql_help.c:3039 +#: sql_help.c:3058 msgid "type_modifier_input_function" msgstr "функція_введення_модифікатора_типу" -#: sql_help.c:3040 +#: sql_help.c:3059 msgid "type_modifier_output_function" msgstr "функція_виводу_модифікатора_типу" -#: sql_help.c:3041 +#: sql_help.c:3060 msgid "analyze_function" msgstr "функція_аналізу" -#: sql_help.c:3042 +#: sql_help.c:3061 msgid "internallength" msgstr "внутр_довжина" -#: sql_help.c:3043 +#: sql_help.c:3062 msgid "alignment" msgstr "вирівнювання" -#: sql_help.c:3044 +#: sql_help.c:3063 msgid "storage" msgstr "зберігання" -#: sql_help.c:3045 +#: sql_help.c:3064 msgid "like_type" msgstr "тип_зразок" -#: sql_help.c:3046 +#: sql_help.c:3065 msgid "category" msgstr "категорія" -#: sql_help.c:3047 +#: sql_help.c:3066 msgid "preferred" msgstr "привілейований" -#: sql_help.c:3048 +#: sql_help.c:3067 msgid "default" msgstr "за_замовчуванням" -#: sql_help.c:3049 +#: sql_help.c:3068 msgid "element" msgstr "елемент" -#: sql_help.c:3050 +#: sql_help.c:3069 msgid "delimiter" msgstr "роздільник" -#: sql_help.c:3051 +#: sql_help.c:3070 msgid "collatable" msgstr "сортувальний" -#: sql_help.c:3148 sql_help.c:3786 sql_help.c:4234 sql_help.c:4323 -#: sql_help.c:4473 sql_help.c:4573 sql_help.c:4691 +#: sql_help.c:3167 sql_help.c:3816 sql_help.c:4281 sql_help.c:4370 +#: sql_help.c:4520 sql_help.c:4620 sql_help.c:4740 msgid "with_query" msgstr "with_запит" -#: sql_help.c:3150 sql_help.c:3788 sql_help.c:4253 sql_help.c:4259 -#: sql_help.c:4262 sql_help.c:4266 sql_help.c:4270 sql_help.c:4278 -#: sql_help.c:4492 sql_help.c:4498 sql_help.c:4501 sql_help.c:4505 -#: sql_help.c:4509 sql_help.c:4517 sql_help.c:4575 sql_help.c:4710 -#: sql_help.c:4716 sql_help.c:4719 sql_help.c:4723 sql_help.c:4727 -#: sql_help.c:4735 +#: sql_help.c:3169 sql_help.c:3818 sql_help.c:4300 sql_help.c:4306 +#: sql_help.c:4309 sql_help.c:4313 sql_help.c:4317 sql_help.c:4325 +#: sql_help.c:4539 sql_help.c:4545 sql_help.c:4548 sql_help.c:4552 +#: sql_help.c:4556 sql_help.c:4564 sql_help.c:4622 sql_help.c:4759 +#: sql_help.c:4765 sql_help.c:4768 sql_help.c:4772 sql_help.c:4776 +#: sql_help.c:4784 msgid "alias" msgstr "псевдонім" -#: sql_help.c:3151 -msgid "using_list" -msgstr "список_using" +#: sql_help.c:3170 sql_help.c:4285 sql_help.c:4327 sql_help.c:4329 +#: sql_help.c:4375 sql_help.c:4524 sql_help.c:4566 sql_help.c:4568 +#: sql_help.c:4629 sql_help.c:4744 sql_help.c:4786 sql_help.c:4788 +msgid "from_item" +msgstr "джерело_даних" -#: sql_help.c:3153 sql_help.c:3626 sql_help.c:3867 sql_help.c:4584 +#: sql_help.c:3172 sql_help.c:3653 sql_help.c:3897 sql_help.c:4631 msgid "cursor_name" msgstr "ім'я_курсору" -#: sql_help.c:3154 sql_help.c:3794 sql_help.c:4585 +#: sql_help.c:3173 sql_help.c:3824 sql_help.c:4632 msgid "output_expression" msgstr "вираз_результату" -#: sql_help.c:3155 sql_help.c:3795 sql_help.c:4237 sql_help.c:4326 -#: sql_help.c:4476 sql_help.c:4586 sql_help.c:4694 +#: sql_help.c:3174 sql_help.c:3825 sql_help.c:4284 sql_help.c:4373 +#: sql_help.c:4523 sql_help.c:4633 sql_help.c:4743 msgid "output_name" msgstr "ім'я_результату" -#: sql_help.c:3171 +#: sql_help.c:3190 msgid "code" msgstr "код" -#: sql_help.c:3570 +#: sql_help.c:3595 msgid "parameter" msgstr "параметр" -#: sql_help.c:3591 sql_help.c:3592 sql_help.c:3892 +#: sql_help.c:3617 sql_help.c:3618 sql_help.c:3922 msgid "statement" msgstr "оператор" -#: sql_help.c:3625 sql_help.c:3866 +#: sql_help.c:3652 sql_help.c:3896 msgid "direction" msgstr "напрямок" -#: sql_help.c:3627 sql_help.c:3868 +#: sql_help.c:3654 sql_help.c:3898 msgid "where direction can be empty or one of:" msgstr "де напрямок може бути пустим або одним із:" -#: sql_help.c:3628 sql_help.c:3629 sql_help.c:3630 sql_help.c:3631 -#: sql_help.c:3632 sql_help.c:3869 sql_help.c:3870 sql_help.c:3871 -#: sql_help.c:3872 sql_help.c:3873 sql_help.c:4247 sql_help.c:4249 -#: sql_help.c:4337 sql_help.c:4339 sql_help.c:4486 sql_help.c:4488 -#: sql_help.c:4639 sql_help.c:4641 sql_help.c:4704 sql_help.c:4706 +#: sql_help.c:3655 sql_help.c:3656 sql_help.c:3657 sql_help.c:3658 +#: sql_help.c:3659 sql_help.c:3899 sql_help.c:3900 sql_help.c:3901 +#: sql_help.c:3902 sql_help.c:3903 sql_help.c:4294 sql_help.c:4296 +#: sql_help.c:4384 sql_help.c:4386 sql_help.c:4533 sql_help.c:4535 +#: sql_help.c:4688 sql_help.c:4690 sql_help.c:4753 sql_help.c:4755 msgid "count" msgstr "кількість" -#: sql_help.c:3712 sql_help.c:4045 +#: sql_help.c:3741 sql_help.c:4089 msgid "sequence_name" msgstr "ім'я_послідовності" -#: sql_help.c:3725 sql_help.c:4058 +#: sql_help.c:3754 sql_help.c:4102 msgid "arg_name" msgstr "ім'я_аргументу" -#: sql_help.c:3726 sql_help.c:4059 +#: sql_help.c:3755 sql_help.c:4103 msgid "arg_type" msgstr "тип_аргументу" -#: sql_help.c:3731 sql_help.c:4064 +#: sql_help.c:3760 sql_help.c:4108 msgid "loid" msgstr "код_вел_об'єкту" -#: sql_help.c:3754 +#: sql_help.c:3784 msgid "remote_schema" msgstr "віддалена_схема" -#: sql_help.c:3757 +#: sql_help.c:3787 msgid "local_schema" msgstr "локальна_схема" -#: sql_help.c:3792 +#: sql_help.c:3822 msgid "conflict_target" msgstr "ціль_конфлікту" -#: sql_help.c:3793 +#: sql_help.c:3823 msgid "conflict_action" msgstr "дія_при_конфлікті" -#: sql_help.c:3796 +#: sql_help.c:3826 msgid "where conflict_target can be one of:" msgstr "де ціль_конфлікту може бути одним з:" -#: sql_help.c:3797 +#: sql_help.c:3827 msgid "index_column_name" msgstr "ім'я_стовпця_індексу" -#: sql_help.c:3798 +#: sql_help.c:3828 msgid "index_expression" msgstr "вираз_індексу" -#: sql_help.c:3801 +#: sql_help.c:3831 msgid "index_predicate" msgstr "предикат_індексу" -#: sql_help.c:3803 +#: sql_help.c:3833 msgid "and conflict_action is one of:" msgstr "і дія_при_конфлікті одна з:" -#: sql_help.c:3809 sql_help.c:4581 +#: sql_help.c:3839 sql_help.c:4628 msgid "sub-SELECT" msgstr "вкладений-SELECT" -#: sql_help.c:3818 sql_help.c:3881 sql_help.c:4557 +#: sql_help.c:3848 sql_help.c:3911 sql_help.c:4604 msgid "channel" msgstr "канал" -#: sql_help.c:3840 +#: sql_help.c:3870 msgid "lockmode" msgstr "режим_блокування" -#: sql_help.c:3841 +#: sql_help.c:3871 msgid "where lockmode is one of:" msgstr "де режим_блокування один з:" -#: sql_help.c:3882 +#: sql_help.c:3912 msgid "payload" msgstr "зміст" -#: sql_help.c:3909 +#: sql_help.c:3939 msgid "old_role" msgstr "стара_роль" -#: sql_help.c:3910 +#: sql_help.c:3940 msgid "new_role" msgstr "нова_роль" -#: sql_help.c:3935 sql_help.c:4096 sql_help.c:4104 +#: sql_help.c:3971 sql_help.c:4143 sql_help.c:4151 msgid "savepoint_name" msgstr "ім'я_точки_збереження" -#: sql_help.c:4238 sql_help.c:4280 sql_help.c:4282 sql_help.c:4328 -#: sql_help.c:4477 sql_help.c:4519 sql_help.c:4521 sql_help.c:4695 -#: sql_help.c:4737 sql_help.c:4739 -msgid "from_item" -msgstr "джерело_даних" - -#: sql_help.c:4240 sql_help.c:4292 sql_help.c:4479 sql_help.c:4531 -#: sql_help.c:4697 sql_help.c:4749 +#: sql_help.c:4287 sql_help.c:4339 sql_help.c:4526 sql_help.c:4578 +#: sql_help.c:4746 sql_help.c:4798 msgid "grouping_element" msgstr "елемент_групування" -#: sql_help.c:4242 sql_help.c:4332 sql_help.c:4481 sql_help.c:4699 +#: sql_help.c:4289 sql_help.c:4379 sql_help.c:4528 sql_help.c:4748 msgid "window_name" msgstr "назва_вікна" -#: sql_help.c:4243 sql_help.c:4333 sql_help.c:4482 sql_help.c:4700 +#: sql_help.c:4290 sql_help.c:4380 sql_help.c:4529 sql_help.c:4749 msgid "window_definition" msgstr "визначення_вікна" -#: sql_help.c:4244 sql_help.c:4258 sql_help.c:4296 sql_help.c:4334 -#: sql_help.c:4483 sql_help.c:4497 sql_help.c:4535 sql_help.c:4701 -#: sql_help.c:4715 sql_help.c:4753 +#: sql_help.c:4291 sql_help.c:4305 sql_help.c:4343 sql_help.c:4381 +#: sql_help.c:4530 sql_help.c:4544 sql_help.c:4582 sql_help.c:4750 +#: sql_help.c:4764 sql_help.c:4802 msgid "select" msgstr "виберіть" -#: sql_help.c:4251 sql_help.c:4490 sql_help.c:4708 +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4757 msgid "where from_item can be one of:" msgstr "де джерело_даних може бути одним з:" -#: sql_help.c:4254 sql_help.c:4260 sql_help.c:4263 sql_help.c:4267 -#: sql_help.c:4279 sql_help.c:4493 sql_help.c:4499 sql_help.c:4502 -#: sql_help.c:4506 sql_help.c:4518 sql_help.c:4711 sql_help.c:4717 -#: sql_help.c:4720 sql_help.c:4724 sql_help.c:4736 +#: sql_help.c:4301 sql_help.c:4307 sql_help.c:4310 sql_help.c:4314 +#: sql_help.c:4326 sql_help.c:4540 sql_help.c:4546 sql_help.c:4549 +#: sql_help.c:4553 sql_help.c:4565 sql_help.c:4760 sql_help.c:4766 +#: sql_help.c:4769 sql_help.c:4773 sql_help.c:4785 msgid "column_alias" msgstr "псевдонім_стовпця" -#: sql_help.c:4255 sql_help.c:4494 sql_help.c:4712 +#: sql_help.c:4302 sql_help.c:4541 sql_help.c:4761 msgid "sampling_method" msgstr "метод_вибірки" -#: sql_help.c:4257 sql_help.c:4496 sql_help.c:4714 +#: sql_help.c:4304 sql_help.c:4543 sql_help.c:4763 msgid "seed" msgstr "початкове_число" -#: sql_help.c:4261 sql_help.c:4294 sql_help.c:4500 sql_help.c:4533 -#: sql_help.c:4718 sql_help.c:4751 +#: sql_help.c:4308 sql_help.c:4341 sql_help.c:4547 sql_help.c:4580 +#: sql_help.c:4767 sql_help.c:4800 msgid "with_query_name" msgstr "ім'я_запиту_WITH" -#: sql_help.c:4271 sql_help.c:4274 sql_help.c:4277 sql_help.c:4510 -#: sql_help.c:4513 sql_help.c:4516 sql_help.c:4728 sql_help.c:4731 -#: sql_help.c:4734 +#: sql_help.c:4318 sql_help.c:4321 sql_help.c:4324 sql_help.c:4557 +#: sql_help.c:4560 sql_help.c:4563 sql_help.c:4777 sql_help.c:4780 +#: sql_help.c:4783 msgid "column_definition" msgstr "визначення_стовпця" -#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4738 +#: sql_help.c:4328 sql_help.c:4567 sql_help.c:4787 msgid "join_type" msgstr "тип_поєднання" -#: sql_help.c:4283 sql_help.c:4522 sql_help.c:4740 +#: sql_help.c:4330 sql_help.c:4569 sql_help.c:4789 msgid "join_condition" msgstr "умова_поєднання" -#: sql_help.c:4284 sql_help.c:4523 sql_help.c:4741 +#: sql_help.c:4331 sql_help.c:4570 sql_help.c:4790 msgid "join_column" msgstr "стовпець_поєднання" -#: sql_help.c:4285 sql_help.c:4524 sql_help.c:4742 +#: sql_help.c:4332 sql_help.c:4571 sql_help.c:4791 msgid "and grouping_element can be one of:" msgstr "і елемент_групування може бути одним з:" -#: sql_help.c:4293 sql_help.c:4532 sql_help.c:4750 +#: sql_help.c:4340 sql_help.c:4579 sql_help.c:4799 msgid "and with_query is:" msgstr "і запит_WITH:" -#: sql_help.c:4297 sql_help.c:4536 sql_help.c:4754 +#: sql_help.c:4344 sql_help.c:4583 sql_help.c:4803 msgid "values" msgstr "значення" -#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4755 +#: sql_help.c:4345 sql_help.c:4584 sql_help.c:4804 msgid "insert" msgstr "вставка" -#: sql_help.c:4299 sql_help.c:4538 sql_help.c:4756 +#: sql_help.c:4346 sql_help.c:4585 sql_help.c:4805 msgid "update" msgstr "оновлення" -#: sql_help.c:4300 sql_help.c:4539 sql_help.c:4757 +#: sql_help.c:4347 sql_help.c:4586 sql_help.c:4806 msgid "delete" msgstr "видалення" -#: sql_help.c:4327 +#: sql_help.c:4374 msgid "new_table" msgstr "нова_таблиця" -#: sql_help.c:4352 +#: sql_help.c:4399 msgid "timezone" msgstr "часовий пояс" -#: sql_help.c:4397 +#: sql_help.c:4444 msgid "snapshot_id" msgstr "код_знімку" -#: sql_help.c:4582 -msgid "from_list" -msgstr "список_FROM" - -#: sql_help.c:4637 +#: sql_help.c:4686 msgid "sort_expression" msgstr "вираз_сортування" -#: sql_help.c:4764 sql_help.c:5742 +#: sql_help.c:4813 sql_help.c:5791 msgid "abort the current transaction" msgstr "перервати поточну транзакцію" -#: sql_help.c:4770 +#: sql_help.c:4819 msgid "change the definition of an aggregate function" msgstr "змінити визначення агрегатної функції" -#: sql_help.c:4776 +#: sql_help.c:4825 msgid "change the definition of a collation" msgstr "змінити визначення правила сортування" -#: sql_help.c:4782 +#: sql_help.c:4831 msgid "change the definition of a conversion" msgstr "змінити визначення перетворення" -#: sql_help.c:4788 +#: sql_help.c:4837 msgid "change a database" msgstr "змінити базу даних" -#: sql_help.c:4794 +#: sql_help.c:4843 msgid "define default access privileges" msgstr "визначити права доступу за замовчуванням" -#: sql_help.c:4800 +#: sql_help.c:4849 msgid "change the definition of a domain" msgstr "змінити визначення домену" -#: sql_help.c:4806 +#: sql_help.c:4855 msgid "change the definition of an event trigger" msgstr "змінити визначення тригеру події" -#: sql_help.c:4812 +#: sql_help.c:4861 msgid "change the definition of an extension" msgstr "змінити визначення розширення" -#: sql_help.c:4818 +#: sql_help.c:4867 msgid "change the definition of a foreign-data wrapper" msgstr "змінити визначення джерела сторонніх даних" -#: sql_help.c:4824 +#: sql_help.c:4873 msgid "change the definition of a foreign table" msgstr "змінити визначення сторонньої таблиці" -#: sql_help.c:4830 +#: sql_help.c:4879 msgid "change the definition of a function" msgstr "змінити визначення функції" -#: sql_help.c:4836 +#: sql_help.c:4885 msgid "change role name or membership" msgstr "змінити назву ролі або членства" -#: sql_help.c:4842 +#: sql_help.c:4891 msgid "change the definition of an index" msgstr "змінити визначення індексу" -#: sql_help.c:4848 +#: sql_help.c:4897 msgid "change the definition of a procedural language" msgstr "змінити визначення процедурної мови" -#: sql_help.c:4854 +#: sql_help.c:4903 msgid "change the definition of a large object" msgstr "змінити визначення великого об'єкту" -#: sql_help.c:4860 +#: sql_help.c:4909 msgid "change the definition of a materialized view" msgstr "змінити визначення матеріалізованого подання" -#: sql_help.c:4866 +#: sql_help.c:4915 msgid "change the definition of an operator" msgstr "змінити визначення оператора" -#: sql_help.c:4872 +#: sql_help.c:4921 msgid "change the definition of an operator class" msgstr "змінити визначення класа операторів" -#: sql_help.c:4878 +#: sql_help.c:4927 msgid "change the definition of an operator family" msgstr "змінити визначення сімейства операторів" -#: sql_help.c:4884 +#: sql_help.c:4933 msgid "change the definition of a row level security policy" msgstr "змінити визначення політики безпеки на рівні рядків" -#: sql_help.c:4890 +#: sql_help.c:4939 msgid "change the definition of a procedure" msgstr "змінити визначення процедури" -#: sql_help.c:4896 +#: sql_help.c:4945 msgid "change the definition of a publication" msgstr "змінити визначення публікації" -#: sql_help.c:4902 sql_help.c:5004 +#: sql_help.c:4951 sql_help.c:5053 msgid "change a database role" msgstr "змінити роль бази даних" -#: sql_help.c:4908 +#: sql_help.c:4957 msgid "change the definition of a routine" msgstr "змінити визначення підпрограми" -#: sql_help.c:4914 +#: sql_help.c:4963 msgid "change the definition of a rule" msgstr "змінити визначення правила" -#: sql_help.c:4920 +#: sql_help.c:4969 msgid "change the definition of a schema" msgstr "змінити визначення схеми" -#: sql_help.c:4926 +#: sql_help.c:4975 msgid "change the definition of a sequence generator" msgstr "змінити визначення генератору послідовності" -#: sql_help.c:4932 +#: sql_help.c:4981 msgid "change the definition of a foreign server" msgstr "змінити визначення стороннього серверу" -#: sql_help.c:4938 +#: sql_help.c:4987 msgid "change the definition of an extended statistics object" msgstr "змінити визначення об'єкту розширеної статистики" -#: sql_help.c:4944 +#: sql_help.c:4993 msgid "change the definition of a subscription" msgstr "змінити визначення підписки" -#: sql_help.c:4950 +#: sql_help.c:4999 msgid "change a server configuration parameter" msgstr "змінити параметр конфігурації сервера" -#: sql_help.c:4956 +#: sql_help.c:5005 msgid "change the definition of a table" msgstr "змінити визначення таблиці" -#: sql_help.c:4962 +#: sql_help.c:5011 msgid "change the definition of a tablespace" msgstr "змінити визначення табличного простору" -#: sql_help.c:4968 +#: sql_help.c:5017 msgid "change the definition of a text search configuration" msgstr "змінити визначення конфігурації текстового пошуку" -#: sql_help.c:4974 +#: sql_help.c:5023 msgid "change the definition of a text search dictionary" msgstr "змінити визначення словника текстового пошуку" -#: sql_help.c:4980 +#: sql_help.c:5029 msgid "change the definition of a text search parser" msgstr "змінити визначення парсера текстового пошуку" -#: sql_help.c:4986 +#: sql_help.c:5035 msgid "change the definition of a text search template" msgstr "змінити визначення шаблона текстового пошуку" -#: sql_help.c:4992 +#: sql_help.c:5041 msgid "change the definition of a trigger" msgstr "змінити визначення тригеру" -#: sql_help.c:4998 +#: sql_help.c:5047 msgid "change the definition of a type" msgstr "змінити визначення типу" -#: sql_help.c:5010 +#: sql_help.c:5059 msgid "change the definition of a user mapping" msgstr "змінити визначення зіставлень користувачів" -#: sql_help.c:5016 +#: sql_help.c:5065 msgid "change the definition of a view" msgstr "змінити визначення подання" -#: sql_help.c:5022 +#: sql_help.c:5071 msgid "collect statistics about a database" msgstr "зібрати статистику про базу даних" -#: sql_help.c:5028 sql_help.c:5820 +#: sql_help.c:5077 sql_help.c:5869 msgid "start a transaction block" msgstr "розпочати транзакцію" -#: sql_help.c:5034 +#: sql_help.c:5083 msgid "invoke a procedure" msgstr "викликати процедуру" -#: sql_help.c:5040 +#: sql_help.c:5089 msgid "force a write-ahead log checkpoint" msgstr "провести контрольну точку в журналі попереднього запису" -#: sql_help.c:5046 +#: sql_help.c:5095 msgid "close a cursor" msgstr "закрити курсор" -#: sql_help.c:5052 +#: sql_help.c:5101 msgid "cluster a table according to an index" msgstr "перегрупувати таблицю за індексом" -#: sql_help.c:5058 +#: sql_help.c:5107 msgid "define or change the comment of an object" msgstr "задати або змінити коментар об'єкта" -#: sql_help.c:5064 sql_help.c:5622 +#: sql_help.c:5113 sql_help.c:5671 msgid "commit the current transaction" msgstr "затвердити поточну транзакцію" -#: sql_help.c:5070 +#: sql_help.c:5119 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "затвердити транзакцію, раніше підготовлену до двохфазного затвердження" -#: sql_help.c:5076 +#: sql_help.c:5125 msgid "copy data between a file and a table" msgstr "копіювати дані між файлом та таблицею" -#: sql_help.c:5082 +#: sql_help.c:5131 msgid "define a new access method" msgstr "визначити новий метод доступу" -#: sql_help.c:5088 +#: sql_help.c:5137 msgid "define a new aggregate function" msgstr "визначити нову агрегатну функцію" -#: sql_help.c:5094 +#: sql_help.c:5143 msgid "define a new cast" msgstr "визначити приведення типів" -#: sql_help.c:5100 +#: sql_help.c:5149 msgid "define a new collation" msgstr "визначити нове правило сортування" -#: sql_help.c:5106 +#: sql_help.c:5155 msgid "define a new encoding conversion" msgstr "визначити нове перетворення кодування" -#: sql_help.c:5112 +#: sql_help.c:5161 msgid "create a new database" msgstr "створити нову базу даних" -#: sql_help.c:5118 +#: sql_help.c:5167 msgid "define a new domain" msgstr "визначити новий домен" -#: sql_help.c:5124 +#: sql_help.c:5173 msgid "define a new event trigger" msgstr "визначити новий тригер події" -#: sql_help.c:5130 +#: sql_help.c:5179 msgid "install an extension" msgstr "встановити розширення" -#: sql_help.c:5136 +#: sql_help.c:5185 msgid "define a new foreign-data wrapper" msgstr "визначити нове джерело сторонніх даних" -#: sql_help.c:5142 +#: sql_help.c:5191 msgid "define a new foreign table" msgstr "визначити нову сторонню таблицю" -#: sql_help.c:5148 +#: sql_help.c:5197 msgid "define a new function" msgstr "визначити нову функцію" -#: sql_help.c:5154 sql_help.c:5214 sql_help.c:5316 +#: sql_help.c:5203 sql_help.c:5263 sql_help.c:5365 msgid "define a new database role" msgstr "визначити нову роль бази даних" -#: sql_help.c:5160 +#: sql_help.c:5209 msgid "define a new index" msgstr "визначити новий індекс" -#: sql_help.c:5166 +#: sql_help.c:5215 msgid "define a new procedural language" msgstr "визначити нову процедурну мову" -#: sql_help.c:5172 +#: sql_help.c:5221 msgid "define a new materialized view" msgstr "визначити нове матеріалізоване подання" -#: sql_help.c:5178 +#: sql_help.c:5227 msgid "define a new operator" msgstr "визначити новий оператор" -#: sql_help.c:5184 +#: sql_help.c:5233 msgid "define a new operator class" msgstr "визначити новий клас оператора" -#: sql_help.c:5190 +#: sql_help.c:5239 msgid "define a new operator family" msgstr "визначити нове сімейство операторів" -#: sql_help.c:5196 +#: sql_help.c:5245 msgid "define a new row level security policy for a table" msgstr "визначити нову політику безпеки на рівні рядків для таблиці" -#: sql_help.c:5202 +#: sql_help.c:5251 msgid "define a new procedure" msgstr "визначити нову процедуру" -#: sql_help.c:5208 +#: sql_help.c:5257 msgid "define a new publication" msgstr "визначити нову публікацію" -#: sql_help.c:5220 +#: sql_help.c:5269 msgid "define a new rewrite rule" msgstr "визначити нове правило перезапису" -#: sql_help.c:5226 +#: sql_help.c:5275 msgid "define a new schema" msgstr "визначити нову схему" -#: sql_help.c:5232 +#: sql_help.c:5281 msgid "define a new sequence generator" msgstr "визначити новий генератор послідовностей" -#: sql_help.c:5238 +#: sql_help.c:5287 msgid "define a new foreign server" msgstr "визначити новий сторонній сервер" -#: sql_help.c:5244 +#: sql_help.c:5293 msgid "define extended statistics" msgstr "визначити розширену статистику" -#: sql_help.c:5250 +#: sql_help.c:5299 msgid "define a new subscription" msgstr "визначити нову підписку" -#: sql_help.c:5256 +#: sql_help.c:5305 msgid "define a new table" msgstr "визначити нову таблицю" -#: sql_help.c:5262 sql_help.c:5778 +#: sql_help.c:5311 sql_help.c:5827 msgid "define a new table from the results of a query" msgstr "визначити нову таблицю з результатів запиту" -#: sql_help.c:5268 +#: sql_help.c:5317 msgid "define a new tablespace" msgstr "визначити новий табличний простір" -#: sql_help.c:5274 +#: sql_help.c:5323 msgid "define a new text search configuration" msgstr "визначити нову конфігурацію текстового пошуку" -#: sql_help.c:5280 +#: sql_help.c:5329 msgid "define a new text search dictionary" msgstr "визначити новий словник текстового пошуку" -#: sql_help.c:5286 +#: sql_help.c:5335 msgid "define a new text search parser" msgstr "визначити новий аналізатор текстового пошуку" -#: sql_help.c:5292 +#: sql_help.c:5341 msgid "define a new text search template" msgstr "визначити новий шаблон текстового пошуку" -#: sql_help.c:5298 +#: sql_help.c:5347 msgid "define a new transform" msgstr "визначити нове перетворення" -#: sql_help.c:5304 +#: sql_help.c:5353 msgid "define a new trigger" msgstr "визначити новий тригер" -#: sql_help.c:5310 +#: sql_help.c:5359 msgid "define a new data type" msgstr "визначити новий тип даних" -#: sql_help.c:5322 +#: sql_help.c:5371 msgid "define a new mapping of a user to a foreign server" msgstr "визначити нове зіставлення користувача для стороннього сервера" -#: sql_help.c:5328 +#: sql_help.c:5377 msgid "define a new view" msgstr "визначити нове подання" -#: sql_help.c:5334 +#: sql_help.c:5383 msgid "deallocate a prepared statement" msgstr "звільнити підготовлену команду" -#: sql_help.c:5340 +#: sql_help.c:5389 msgid "define a cursor" msgstr "визначити курсор" -#: sql_help.c:5346 +#: sql_help.c:5395 msgid "delete rows of a table" msgstr "видалити рядки таблиці" -#: sql_help.c:5352 +#: sql_help.c:5401 msgid "discard session state" msgstr "очистити стан сесії" -#: sql_help.c:5358 +#: sql_help.c:5407 msgid "execute an anonymous code block" msgstr "виконати анонімний блок коду" -#: sql_help.c:5364 +#: sql_help.c:5413 msgid "remove an access method" msgstr "видалити метод доступу" -#: sql_help.c:5370 +#: sql_help.c:5419 msgid "remove an aggregate function" msgstr "видалити агрегатну функцію" -#: sql_help.c:5376 +#: sql_help.c:5425 msgid "remove a cast" msgstr "видалити приведення типів" -#: sql_help.c:5382 +#: sql_help.c:5431 msgid "remove a collation" msgstr "видалити правило сортування" -#: sql_help.c:5388 +#: sql_help.c:5437 msgid "remove a conversion" msgstr "видалити перетворення" -#: sql_help.c:5394 +#: sql_help.c:5443 msgid "remove a database" msgstr "видалити базу даних" -#: sql_help.c:5400 +#: sql_help.c:5449 msgid "remove a domain" msgstr "видалити домен" -#: sql_help.c:5406 +#: sql_help.c:5455 msgid "remove an event trigger" msgstr "видалити тригер події" -#: sql_help.c:5412 +#: sql_help.c:5461 msgid "remove an extension" msgstr "видалити розширення" -#: sql_help.c:5418 +#: sql_help.c:5467 msgid "remove a foreign-data wrapper" msgstr "видалити джерело сторонніх даних" -#: sql_help.c:5424 +#: sql_help.c:5473 msgid "remove a foreign table" msgstr "видалити сторонню таблицю" -#: sql_help.c:5430 +#: sql_help.c:5479 msgid "remove a function" msgstr "видалити функцію" -#: sql_help.c:5436 sql_help.c:5502 sql_help.c:5604 +#: sql_help.c:5485 sql_help.c:5551 sql_help.c:5653 msgid "remove a database role" msgstr "видалити роль бази даних" -#: sql_help.c:5442 +#: sql_help.c:5491 msgid "remove an index" msgstr "видалити індекс" -#: sql_help.c:5448 +#: sql_help.c:5497 msgid "remove a procedural language" msgstr "видалити процедурну мову" -#: sql_help.c:5454 +#: sql_help.c:5503 msgid "remove a materialized view" msgstr "видалити матеріалізоване подання" -#: sql_help.c:5460 +#: sql_help.c:5509 msgid "remove an operator" msgstr "видалити оператор" -#: sql_help.c:5466 +#: sql_help.c:5515 msgid "remove an operator class" msgstr "видалити клас операторів" -#: sql_help.c:5472 +#: sql_help.c:5521 msgid "remove an operator family" msgstr "видалити сімейство операторів" -#: sql_help.c:5478 +#: sql_help.c:5527 msgid "remove database objects owned by a database role" msgstr "видалити об'єкти бази даних, що належать ролі" -#: sql_help.c:5484 +#: sql_help.c:5533 msgid "remove a row level security policy from a table" msgstr "видалити політику безпеки на рівні рядків з таблиці" -#: sql_help.c:5490 +#: sql_help.c:5539 msgid "remove a procedure" msgstr "видалити процедуру" -#: sql_help.c:5496 +#: sql_help.c:5545 msgid "remove a publication" msgstr "видалити публікацію" -#: sql_help.c:5508 +#: sql_help.c:5557 msgid "remove a routine" msgstr "видалити підпрограму" -#: sql_help.c:5514 +#: sql_help.c:5563 msgid "remove a rewrite rule" msgstr "видалити правило перезапису" -#: sql_help.c:5520 +#: sql_help.c:5569 msgid "remove a schema" msgstr "видалити схему" -#: sql_help.c:5526 +#: sql_help.c:5575 msgid "remove a sequence" msgstr "видалити послідовність" -#: sql_help.c:5532 +#: sql_help.c:5581 msgid "remove a foreign server descriptor" msgstr "видалити опис стороннього серверу" -#: sql_help.c:5538 +#: sql_help.c:5587 msgid "remove extended statistics" msgstr "видалити розширену статистику" -#: sql_help.c:5544 +#: sql_help.c:5593 msgid "remove a subscription" msgstr "видалити підписку" -#: sql_help.c:5550 +#: sql_help.c:5599 msgid "remove a table" msgstr "видалити таблицю" -#: sql_help.c:5556 +#: sql_help.c:5605 msgid "remove a tablespace" msgstr "видалити табличний простір" -#: sql_help.c:5562 +#: sql_help.c:5611 msgid "remove a text search configuration" msgstr "видалити конфігурацію тектового пошуку" -#: sql_help.c:5568 +#: sql_help.c:5617 msgid "remove a text search dictionary" msgstr "видалити словник тектового пошуку" -#: sql_help.c:5574 +#: sql_help.c:5623 msgid "remove a text search parser" msgstr "видалити парсер тектового пошуку" -#: sql_help.c:5580 +#: sql_help.c:5629 msgid "remove a text search template" msgstr "видалити шаблон тектового пошуку" -#: sql_help.c:5586 +#: sql_help.c:5635 msgid "remove a transform" msgstr "видалити перетворення" -#: sql_help.c:5592 +#: sql_help.c:5641 msgid "remove a trigger" msgstr "видалити тригер" -#: sql_help.c:5598 +#: sql_help.c:5647 msgid "remove a data type" msgstr "видалити тип даних" -#: sql_help.c:5610 +#: sql_help.c:5659 msgid "remove a user mapping for a foreign server" msgstr "видалити зіставлення користувача для стороннього серверу" -#: sql_help.c:5616 +#: sql_help.c:5665 msgid "remove a view" msgstr "видалити подання" -#: sql_help.c:5628 +#: sql_help.c:5677 msgid "execute a prepared statement" msgstr "виконати підготовлену команду" -#: sql_help.c:5634 +#: sql_help.c:5683 msgid "show the execution plan of a statement" msgstr "показати план виконання команди" -#: sql_help.c:5640 +#: sql_help.c:5689 msgid "retrieve rows from a query using a cursor" msgstr "отримати рядки запиту з курсору" -#: sql_help.c:5646 +#: sql_help.c:5695 msgid "define access privileges" msgstr "визначити права доступу" -#: sql_help.c:5652 +#: sql_help.c:5701 msgid "import table definitions from a foreign server" msgstr "імпортувати визначення таблиць зі стороннього серверу" -#: sql_help.c:5658 +#: sql_help.c:5707 msgid "create new rows in a table" msgstr "створити нові рядки в таблиці" -#: sql_help.c:5664 +#: sql_help.c:5713 msgid "listen for a notification" msgstr "очікувати на повідомлення" -#: sql_help.c:5670 +#: sql_help.c:5719 msgid "load a shared library file" msgstr "завантажити файл спільної бібліотеки" -#: sql_help.c:5676 +#: sql_help.c:5725 msgid "lock a table" msgstr "заблокувати таблицю" -#: sql_help.c:5682 +#: sql_help.c:5731 msgid "position a cursor" msgstr "розташувати курсор" -#: sql_help.c:5688 +#: sql_help.c:5737 msgid "generate a notification" msgstr "згенерувати повідомлення" -#: sql_help.c:5694 +#: sql_help.c:5743 msgid "prepare a statement for execution" msgstr "підготувати команду для виконання" -#: sql_help.c:5700 +#: sql_help.c:5749 msgid "prepare the current transaction for two-phase commit" msgstr "підготувати поточну транзакцію для двохфазного затвердження" -#: sql_help.c:5706 +#: sql_help.c:5755 msgid "change the ownership of database objects owned by a database role" msgstr "змінити власника об'єктів БД, що належать заданій ролі" -#: sql_help.c:5712 +#: sql_help.c:5761 msgid "replace the contents of a materialized view" msgstr "замінити вміст матеріалізованого подання" -#: sql_help.c:5718 +#: sql_help.c:5767 msgid "rebuild indexes" msgstr "перебудувати індекси" -#: sql_help.c:5724 +#: sql_help.c:5773 msgid "destroy a previously defined savepoint" msgstr "видалити раніше визначену точку збереження" -#: sql_help.c:5730 +#: sql_help.c:5779 msgid "restore the value of a run-time parameter to the default value" msgstr "відновити початкове значення параметру виконання" -#: sql_help.c:5736 +#: sql_help.c:5785 msgid "remove access privileges" msgstr "видалити права доступу" -#: sql_help.c:5748 +#: sql_help.c:5797 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "скасувати транзакцію, раніше підготовлену до двохфазного затвердження" -#: sql_help.c:5754 +#: sql_help.c:5803 msgid "roll back to a savepoint" msgstr "відкотитися до точки збереження" -#: sql_help.c:5760 +#: sql_help.c:5809 msgid "define a new savepoint within the current transaction" msgstr "визначити нову точку збереження в рамках поточної транзакції" -#: sql_help.c:5766 +#: sql_help.c:5815 msgid "define or change a security label applied to an object" msgstr "визначити або змінити мітку безпеки, застосовану до об'єкта" -#: sql_help.c:5772 sql_help.c:5826 sql_help.c:5862 +#: sql_help.c:5821 sql_help.c:5875 sql_help.c:5911 msgid "retrieve rows from a table or view" msgstr "отримати рядки з таблиці або подання" -#: sql_help.c:5784 +#: sql_help.c:5833 msgid "change a run-time parameter" msgstr "змінити параметр виконання" -#: sql_help.c:5790 +#: sql_help.c:5839 msgid "set constraint check timing for the current transaction" msgstr "встановити час перевірки обмеження для поточної транзакції" -#: sql_help.c:5796 +#: sql_help.c:5845 msgid "set the current user identifier of the current session" msgstr "встановити ідентифікатор поточного користувача в поточній сесії" -#: sql_help.c:5802 +#: sql_help.c:5851 msgid "set the session user identifier and the current user identifier of the current session" msgstr "встановити ідентифікатор користувача сесії й ідентифікатор поточного користувача в поточній сесії" -#: sql_help.c:5808 +#: sql_help.c:5857 msgid "set the characteristics of the current transaction" msgstr "встановити характеристики поточної транзакції" -#: sql_help.c:5814 +#: sql_help.c:5863 msgid "show the value of a run-time parameter" msgstr "показати значення параметра виконання" -#: sql_help.c:5832 +#: sql_help.c:5881 msgid "empty a table or set of tables" msgstr "очистити таблицю або декілька таблиць" -#: sql_help.c:5838 +#: sql_help.c:5887 msgid "stop listening for a notification" msgstr "припинити очікування повідомлень" -#: sql_help.c:5844 +#: sql_help.c:5893 msgid "update rows of a table" msgstr "змінити рядки таблиці" -#: sql_help.c:5850 +#: sql_help.c:5899 msgid "garbage-collect and optionally analyze a database" msgstr "виконати збір сміття і проаналізувати базу даних" -#: sql_help.c:5856 +#: sql_help.c:5905 msgid "compute a set of rows" msgstr "отримати набір рядків" -#: startup.c:216 +#: startup.c:212 #, c-format msgid "-1 can only be used in non-interactive mode" msgstr "-1 можна використовувати лише в неінтерактивному режимі" -#: startup.c:303 +#: startup.c:299 #, c-format msgid "could not connect to server: %s" msgstr "не вдалося підключитися до сервера: %s" -#: startup.c:331 +#: startup.c:327 #, c-format msgid "could not open log file \"%s\": %m" msgstr "не вдалося відкрити файл протоколу \"%s\": %m" -#: startup.c:443 +#: startup.c:439 #, c-format msgid "Type \"help\" for help.\n\n" msgstr "Введіть \"help\", щоб отримати допомогу.\n\n" -#: startup.c:593 +#: startup.c:589 #, c-format msgid "could not set printing parameter \"%s\"" msgstr "не вдалося встановити параметр друку \"%s\"" -#: startup.c:701 +#: startup.c:697 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n" +msgstr "Спробуйте \"%s --help\" для отримання додаткової інформації.\n" -#: startup.c:718 +#: startup.c:714 #, c-format msgid "extra command-line argument \"%s\" ignored" msgstr "зайвий аргумент \"%s\" проігнорований" -#: startup.c:767 +#: startup.c:763 #, c-format msgid "could not find own program executable" msgstr "не вдалося знайти ехе файл власної програми" -#: tab-complete.c:4408 +#: tab-complete.c:4640 #, c-format msgid "tab completion query failed: %s\n" "Query was:\n" @@ -5969,22 +6133,22 @@ msgstr "помилка запиту Tab-доповнення: %s\n" "Запит:\n" "%s" -#: variables.c:141 +#: variables.c:139 #, c-format msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" msgstr "нерозпізнане значення \"%s\" для \"%s\": очікувалося логічне значення" -#: variables.c:178 +#: variables.c:176 #, c-format msgid "invalid value \"%s\" for \"%s\": integer expected" msgstr "неправильне значення \"%s\" для \"%s\": очікувалося ціле число" -#: variables.c:226 +#: variables.c:224 #, c-format msgid "invalid variable name: \"%s\"" msgstr "неправильне ім'я змінної: \"%s\"" -#: variables.c:395 +#: variables.c:393 #, c-format msgid "unrecognized value \"%s\" for \"%s\"\n" "Available values are: %s." diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index ef503ec41bb4..9f236049f000 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/prompt.c */ @@ -15,6 +15,7 @@ #include "common.h" #include "common/string.h" #include "input.h" +#include "libpq/pqcomm.h" #include "prompt.h" #include "settings.h" @@ -136,7 +137,7 @@ get_prompt(promptStatus_t status, ConditionalStack cstack) const char *host = PQhost(pset.db); /* INET socket */ - if (host && host[0] && !is_absolute_path(host)) + if (host && host[0] && !is_unixsock_path(host)) { strlcpy(buf, host, sizeof(buf)); if (*p == 'm') diff --git a/src/bin/psql/prompt.h b/src/bin/psql/prompt.h index 3c8666918cdc..ad6646d99b68 100644 --- a/src/bin/psql/prompt.h +++ b/src/bin/psql/prompt.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/prompt.h */ diff --git a/src/bin/psql/psqlscanslash.h b/src/bin/psql/psqlscanslash.h index 7210e4924079..074e961e18c4 100644 --- a/src/bin/psql/psqlscanslash.h +++ b/src/bin/psql/psqlscanslash.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/psqlscanslash.h */ diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l index d6bcd95d1821..063f181345d0 100644 --- a/src/bin/psql/psqlscanslash.l +++ b/src/bin/psql/psqlscanslash.l @@ -8,7 +8,7 @@ * * See fe_utils/psqlscan_int.h for additional commentary. * - * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -759,7 +759,7 @@ dequote_downcase_identifier(char *str, bool downcase, int encoding) { if (downcase && !inquotes) *cp = pg_tolower((unsigned char) *cp); - cp += PQmblen(cp, encoding); + cp += PQmblenBounded(cp, encoding); } } } @@ -783,7 +783,7 @@ evaluate_backtick(PsqlScanState state) initPQExpBuffer(&cmd_output); - fd = popen(cmd, PG_BINARY_R); + fd = popen(cmd, "r"); if (!fd) { pg_log_error("%s: %m", cmd); @@ -824,7 +824,7 @@ evaluate_backtick(PsqlScanState state) /* If no error, transfer result to output_buf */ if (!error) { - /* strip any trailing newline */ + /* strip any trailing newline (but only one) */ if (cmd_output.len > 0 && cmd_output.data[cmd_output.len - 1] == '\n') cmd_output.len--; diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index 97941aa10c67..83f2e6f254ed 100644 --- a/src/bin/psql/settings.h +++ b/src/bin/psql/settings.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/settings.h */ @@ -117,6 +117,13 @@ typedef struct _psqlSettings VariableSpace vars; /* "shell variable" repository */ + /* + * If we get a connection failure, the now-unusable PGconn is stashed here + * until we can successfully reconnect. Never attempt to do anything with + * this PGconn except extract parameters for a \connect attempt. + */ + PGconn *dead_conn; /* previous connection to backend */ + /* * The remaining fields are set by assign hooks associated with entries in * "vars". They should not be set directly except by those hook @@ -127,6 +134,7 @@ typedef struct _psqlSettings bool quiet; bool singleline; bool singlestep; + bool hide_compression; bool hide_tableam; int fetch_count; int histsize; diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index 392b96eb862d..110906a4e959 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/startup.c */ @@ -17,6 +17,7 @@ #include "command.h" #include "common.h" #include "common/logging.h" +#include "common/string.h" #include "describe.h" #include "fe_utils/print.h" #include "getopt_long.h" @@ -119,8 +120,7 @@ main(int argc, char *argv[]) { struct adhoc_opts options; int successResult; - bool have_password = false; - char password[100]; + char *password = NULL; bool new_pass; pg_logging_init(argv[0]); @@ -145,6 +145,7 @@ main(int argc, char *argv[]) pset.progname = get_progname(argv[0]); pset.db = NULL; + pset.dead_conn = NULL; setDecimalLocale(); pset.encoding = PQenv2encoding(); pset.queryFout = stdout; @@ -233,8 +234,7 @@ main(int argc, char *argv[]) * offer a potentially wrong one. Typical uses of this option are * noninteractive anyway. */ - simple_prompt("Password: ", password, sizeof(password), false); - have_password = true; + password = simple_prompt("Password: ", false); } /* loop until we have a password if requested by backend */ @@ -251,7 +251,7 @@ main(int argc, char *argv[]) keywords[2] = "user"; values[2] = options.username; keywords[3] = "password"; - values[3] = have_password ? password : NULL; + values[3] = password; keywords[4] = "dbname"; /* see do_connect() */ values[4] = (options.list_dbs && options.dbname == NULL) ? "postgres" : options.dbname; @@ -269,7 +269,7 @@ main(int argc, char *argv[]) if (PQstatus(pset.db) == CONNECTION_BAD && PQconnectionNeedsPassword(pset.db) && - !have_password && + !password && pset.getPassword != TRI_NO) { /* @@ -287,9 +287,8 @@ main(int argc, char *argv[]) password_prompt = pg_strdup(_("Password: ")); PQfinish(pset.db); - simple_prompt(password_prompt, password, sizeof(password), false); + password = simple_prompt(password_prompt, false); free(password_prompt); - have_password = true; new_pass = true; } } while (new_pass); @@ -444,7 +443,10 @@ main(int argc, char *argv[]) /* clean up */ if (pset.logfile) fclose(pset.logfile); - PQfinish(pset.db); + if (pset.db) + PQfinish(pset.db); + if (pset.dead_conn) + PQfinish(pset.dead_conn); setQFout(NULL); return successResult; @@ -1157,6 +1159,13 @@ show_context_hook(const char *newval) return true; } +static bool +hide_compression_hook(const char *newval) +{ + return ParseVariableBool(newval, "HIDE_TOAST_COMPRESSION", + &pset.hide_compression); +} + static bool hide_tableam_hook(const char *newval) { @@ -1225,6 +1234,9 @@ EstablishVariableSpace(void) SetVariableHooks(pset.vars, "SHOW_CONTEXT", show_context_substitute_hook, show_context_hook); + SetVariableHooks(pset.vars, "HIDE_TOAST_COMPRESSION", + bool_substitute_hook, + hide_compression_hook); SetVariableHooks(pset.vars, "HIDE_TABLEAM", bool_substitute_hook, hide_tableam_hook); diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c index c521749661c3..3a141cdc2b39 100644 --- a/src/bin/psql/stringutils.c +++ b/src/bin/psql/stringutils.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/stringutils.c */ @@ -143,7 +143,7 @@ strtokx(const char *s, /* okay, we have a quoted token, now scan for the closer */ char thisquote = *p++; - for (; *p; p += PQmblen(p, encoding)) + for (; *p; p += PQmblenBounded(p, encoding)) { if (*p == escape && p[1] != '\0') p++; /* process escaped anything */ @@ -262,7 +262,7 @@ strip_quotes(char *source, char quote, char escape, int encoding) else if (c == escape && src[1] != '\0') src++; /* process escaped character */ - i = PQmblen(src, encoding); + i = PQmblenBounded(src, encoding); while (i--) *dst++ = *src++; } @@ -324,7 +324,7 @@ quote_if_needed(const char *source, const char *entails_quote, else if (strchr(entails_quote, c)) need_quotes = true; - i = PQmblen(src, encoding); + i = PQmblenBounded(src, encoding); while (i--) *dst++ = *src++; } diff --git a/src/bin/psql/stringutils.h b/src/bin/psql/stringutils.h index 4be172e031f9..b47425e8644c 100644 --- a/src/bin/psql/stringutils.h +++ b/src/bin/psql/stringutils.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2020, PostgreSQL Global Development Group + * Copyright (c) 2000-2021, PostgreSQL Global Development Group * * src/bin/psql/stringutils.h */ diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab_completion.pl index c27f216d3927..3c58d50118a7 100644 --- a/src/bin/psql/t/010_tab_completion.pl +++ b/src/bin/psql/t/010_tab_completion.pl @@ -1,3 +1,6 @@ + +# Copyright (c) 2021, PostgreSQL Global Development Group + use strict; use warnings; diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 53b50fdf8c99..667f125bc27b 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -550,6 +550,18 @@ static const SchemaQuery Query_for_list_of_selectables = { .result = "pg_catalog.quote_ident(c.relname)", }; +/* Relations supporting TRUNCATE */ +static const SchemaQuery Query_for_list_of_truncatables = { + .catname = "pg_catalog.pg_class c", + .selcondition = + "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_FOREIGN_TABLE) ", " + CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", +}; + /* Relations supporting GRANT are currently same as those supporting SELECT */ #define Query_for_list_of_grantables Query_for_list_of_selectables @@ -610,6 +622,14 @@ static const SchemaQuery Query_for_list_of_statistics = { .result = "pg_catalog.quote_ident(s.stxname)", }; +static const SchemaQuery Query_for_list_of_collations = { + .catname = "pg_catalog.pg_collation c", + .selcondition = "c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))", + .viscondition = "pg_catalog.pg_collation_is_visible(c.oid)", + .namespace = "c.collnamespace", + .result = "pg_catalog.quote_ident(c.collname)", +}; + /* * Queries to get lists of names of various kinds of things, possibly @@ -750,6 +770,7 @@ static const SchemaQuery Query_for_list_of_statistics = { " FROM pg_catalog.pg_roles "\ " WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\ " UNION ALL SELECT 'PUBLIC'"\ +" UNION ALL SELECT 'CURRENT_ROLE'"\ " UNION ALL SELECT 'CURRENT_USER'"\ " UNION ALL SELECT 'SESSION_USER'" @@ -968,6 +989,11 @@ static const SchemaQuery Query_for_list_of_statistics = { " and pg_catalog.pg_table_is_visible(c2.oid)"\ " and c2.relispartition = 'true'" +#define Query_for_list_of_cursors \ +" SELECT pg_catalog.quote_ident(name) "\ +" FROM pg_catalog.pg_cursors "\ +" WHERE substring(pg_catalog.quote_ident(name),1,%d)='%s'" + /* * These object types were introduced later than our support cutoff of * server version 7.4. We use the VersionedQuery infrastructure so that @@ -1018,7 +1044,7 @@ static const pgsql_thing_t words_after_create[] = { {"AGGREGATE", NULL, NULL, Query_for_list_of_aggregates}, {"CAST", NULL, NULL, NULL}, /* Casts have complex structures for names, so * skip it */ - {"COLLATION", "SELECT pg_catalog.quote_ident(collname) FROM pg_catalog.pg_collation WHERE collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding())) AND substring(pg_catalog.quote_ident(collname),1,%d)='%s'"}, + {"COLLATION", NULL, NULL, &Query_for_list_of_collations}, /* * CREATE CONSTRAINT TRIGGER is not supported here because it is designed @@ -1474,7 +1500,7 @@ psql_completion(const char *text, int start, int end) "ABORT", "ALTER", "ANALYZE", "BEGIN", "CALL", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN", - "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK", + "FETCH", "GRANT", "IMPORT FOREIGN SCHEMA", "INSERT INTO", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", "PREPARE", "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK", @@ -1494,7 +1520,7 @@ psql_completion(const char *text, int start, int end) "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL", "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt", "\\drds", "\\dRs", "\\dRp", "\\ds", "\\dS", - "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy", + "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dX", "\\dy", "\\e", "\\echo", "\\ef", "\\elif", "\\else", "\\encoding", "\\endif", "\\errverbose", "\\ev", "\\f", @@ -1574,7 +1600,7 @@ psql_completion(const char *text, int start, int end) /* complete with something you can create or replace */ else if (TailMatches("CREATE", "OR", "REPLACE")) COMPLETE_WITH("FUNCTION", "PROCEDURE", "LANGUAGE", "RULE", "VIEW", - "AGGREGATE", "TRANSFORM"); + "AGGREGATE", "TRANSFORM", "TRIGGER"); /* DROP, but not DROP embedded in other commands */ /* complete with something you can drop */ @@ -1603,14 +1629,24 @@ psql_completion(const char *text, int start, int end) /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE */ else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) COMPLETE_WITH("("); - /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE (...) */ - else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny)) + /* ALTER AGGREGATE (...) */ + else if (Matches("ALTER", "AGGREGATE", MatchAny, MatchAny)) { if (ends_with(prev_wd, ')')) COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); else COMPLETE_WITH_FUNCTION_ARG(prev2_wd); } + /* ALTER FUNCTION,PROCEDURE,ROUTINE (...) */ + else if (Matches("ALTER", "FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny)) + { + if (ends_with(prev_wd, ')')) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA", + "DEPENDS ON EXTENSION", "NO DEPENDS ON EXTENSION"); + else + COMPLETE_WITH_FUNCTION_ARG(prev2_wd); + } + /* ALTER PUBLICATION */ else if (Matches("ALTER", "PUBLICATION", MatchAny)) COMPLETE_WITH("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET"); @@ -1619,11 +1655,12 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH("(", "TABLE"); /* ALTER PUBLICATION SET ( */ else if (HeadMatches("ALTER", "PUBLICATION", MatchAny) && TailMatches("SET", "(")) - COMPLETE_WITH("publish"); + COMPLETE_WITH("publish", "publish_via_partition_root"); /* ALTER SUBSCRIPTION */ else if (Matches("ALTER", "SUBSCRIPTION", MatchAny)) COMPLETE_WITH("CONNECTION", "ENABLE", "DISABLE", "OWNER TO", - "RENAME TO", "REFRESH PUBLICATION", "SET"); + "RENAME TO", "REFRESH PUBLICATION", "SET", + "ADD PUBLICATION", "DROP PUBLICATION"); /* ALTER SUBSCRIPTION REFRESH PUBLICATION */ else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("REFRESH", "PUBLICATION")) @@ -1637,20 +1674,25 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH("(", "PUBLICATION"); /* ALTER SUBSCRIPTION SET ( */ else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "(")) - COMPLETE_WITH("slot_name", "synchronous_commit"); + COMPLETE_WITH("binary", "slot_name", "streaming", "synchronous_commit"); /* ALTER SUBSCRIPTION SET PUBLICATION */ else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "PUBLICATION")) { /* complete with nothing here as this refers to remote publications */ } - /* ALTER SUBSCRIPTION SET PUBLICATION */ + /* ALTER SUBSCRIPTION ADD|DROP|SET PUBLICATION */ else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches("SET", "PUBLICATION", MatchAny)) + TailMatches("ADD|DROP|SET", "PUBLICATION", MatchAny)) COMPLETE_WITH("WITH ("); - /* ALTER SUBSCRIPTION SET PUBLICATION WITH ( */ + /* ALTER SUBSCRIPTION ADD|SET PUBLICATION WITH ( */ else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches("SET", "PUBLICATION", MatchAny, "WITH", "(")) + TailMatches("ADD|SET", "PUBLICATION", MatchAny, "WITH", "(")) COMPLETE_WITH("copy_data", "refresh"); + /* ALTER SUBSCRIPTION DROP PUBLICATION WITH ( */ + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("DROP", "PUBLICATION", MatchAny, "WITH", "(")) + COMPLETE_WITH("refresh"); + /* ALTER SCHEMA */ else if (Matches("ALTER", "SCHEMA", MatchAny)) COMPLETE_WITH("OWNER TO", "RENAME TO"); @@ -1724,7 +1766,8 @@ psql_completion(const char *text, int start, int end) /* ALTER INDEX */ else if (Matches("ALTER", "INDEX", MatchAny)) COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET", - "RESET", "ATTACH PARTITION", "DEPENDS", "NO DEPENDS"); + "RESET", "ATTACH PARTITION", + "DEPENDS ON EXTENSION", "NO DEPENDS ON EXTENSION"); else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH")) COMPLETE_WITH("PARTITION"); else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION")) @@ -1758,14 +1801,14 @@ psql_completion(const char *text, int start, int end) /* ALTER INDEX SET|RESET ( */ else if (Matches("ALTER", "INDEX", MatchAny, "RESET", "(")) COMPLETE_WITH("fillfactor", - "vacuum_cleanup_index_scale_factor", "deduplicate_items", /* BTREE */ + "deduplicate_items", /* BTREE */ "fastupdate", "gin_pending_list_limit", /* GIN */ "buffering", /* GiST */ "pages_per_range", "autosummarize" /* BRIN */ ); else if (Matches("ALTER", "INDEX", MatchAny, "SET", "(")) COMPLETE_WITH("fillfactor =", - "vacuum_cleanup_index_scale_factor =", "deduplicate_items =", /* BTREE */ + "deduplicate_items =", /* BTREE */ "fastupdate =", "gin_pending_list_limit =", /* GIN */ "buffering =", /* GiST */ "pages_per_range =", "autosummarize =" /* BRIN */ @@ -1899,7 +1942,8 @@ psql_completion(const char *text, int start, int end) /* ALTER MATERIALIZED VIEW */ else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny)) COMPLETE_WITH("ALTER COLUMN", "CLUSTER ON", "DEPENDS ON EXTENSION", - "OWNER TO", "RENAME", "RESET (", "SET"); + "NO DEPENDS ON EXTENSION", "OWNER TO", "RENAME", + "RESET (", "SET"); /* ALTER MATERIALIZED VIEW xxx RENAME */ else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny, "RENAME")) COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'TO'"); @@ -1976,17 +2020,18 @@ psql_completion(const char *text, int start, int end) /* ALTER TRIGGER ON */ else if (Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny)) - COMPLETE_WITH("RENAME TO"); + COMPLETE_WITH("RENAME TO", "DEPENDS ON EXTENSION", + "NO DEPENDS ON EXTENSION"); /* * If we detect ALTER TABLE , suggest sub commands */ else if (Matches("ALTER", "TABLE", MatchAny)) COMPLETE_WITH("ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", - "ENABLE", "INHERIT", "NO INHERIT", "RENAME", "RESET", + "ENABLE", "INHERIT", "NO", "RENAME", "RESET", "OWNER TO", "SET", "VALIDATE CONSTRAINT", "REPLICA IDENTITY", "ATTACH PARTITION", - "DETACH PARTITION"); + "DETACH PARTITION", "FORCE ROW LEVEL SECURITY"); /* ALTER TABLE xxx ENABLE */ else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE")) COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE", @@ -2016,6 +2061,9 @@ psql_completion(const char *text, int start, int end) /* ALTER TABLE xxx INHERIT */ else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); + /* ALTER TABLE xxx NO */ + else if (Matches("ALTER", "TABLE", MatchAny, "NO")) + COMPLETE_WITH("FORCE ROW LEVEL SECURITY", "INHERIT"); /* ALTER TABLE xxx NO INHERIT */ else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); @@ -2074,7 +2122,7 @@ psql_completion(const char *text, int start, int end) /* ALTER TABLE ALTER [COLUMN] SET */ else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") || Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET")) - COMPLETE_WITH("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE"); + COMPLETE_WITH("(", "COMPRESSION", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE"); /* ALTER TABLE ALTER [COLUMN] SET ( */ else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") || Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "(")) @@ -2160,6 +2208,8 @@ psql_completion(const char *text, int start, int end) completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_partition_of_table); } + else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION", MatchAny)) + COMPLETE_WITH("CONCURRENTLY", "FINALIZE"); /* ALTER TABLESPACE with RENAME TO, OWNER TO, SET, RESET */ else if (Matches("ALTER", "TABLESPACE", MatchAny)) @@ -2272,24 +2322,40 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL); else if (Matches("CALL", MatchAny)) COMPLETE_WITH("("); +/* CLOSE */ + else if (Matches("CLOSE")) + COMPLETE_WITH_QUERY(Query_for_list_of_cursors + " UNION SELECT 'ALL'"); /* CLUSTER */ else if (Matches("CLUSTER")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'"); - else if (Matches("CLUSTER", "VERBOSE")) + else if (Matches("CLUSTER", "VERBOSE") || + Matches("CLUSTER", "(*)")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL); /* If we have CLUSTER , then add "USING" */ - else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON"))) + else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON|(|(*)"))) COMPLETE_WITH("USING"); /* If we have CLUSTER VERBOSE , then add "USING" */ - else if (Matches("CLUSTER", "VERBOSE", MatchAny)) + else if (Matches("CLUSTER", "VERBOSE|(*)", MatchAny)) COMPLETE_WITH("USING"); /* If we have CLUSTER USING, then add the index as well */ else if (Matches("CLUSTER", MatchAny, "USING") || - Matches("CLUSTER", "VERBOSE", MatchAny, "USING")) + Matches("CLUSTER", "VERBOSE|(*)", MatchAny, "USING")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } + else if (HeadMatches("CLUSTER", "(*") && + !HeadMatches("CLUSTER", "(*)")) + { + /* + * This fires if we're in an unfinished parenthesized option list. + * get_previous_words treats a completed parenthesized option list as + * one word, so the above test is correct. + */ + if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) + COMPLETE_WITH("VERBOSE"); + } /* COMMENT */ else if (Matches("COMMENT")) @@ -2340,7 +2406,7 @@ psql_completion(const char *text, int start, int end) " UNION ALL SELECT '('"); /* Complete COPY ( with legal query commands */ else if (Matches("COPY|\\copy", "(")) - COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH"); + COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT INTO", "UPDATE", "DELETE FROM", "WITH"); /* Complete COPY */ else if (Matches("COPY|\\copy", MatchAny)) COMPLETE_WITH("FROM", "TO"); @@ -2391,12 +2457,28 @@ psql_completion(const char *text, int start, int end) else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny)) COMPLETE_WITH("HANDLER"); + /* CREATE COLLATION */ + else if (Matches("CREATE", "COLLATION", MatchAny)) + COMPLETE_WITH("(", "FROM"); + else if (Matches("CREATE", "COLLATION", MatchAny, "FROM")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_collations, NULL); + else if (HeadMatches("CREATE", "COLLATION", MatchAny, "(*")) + { + if (TailMatches("(|*,")) + COMPLETE_WITH("LOCALE =", "LC_COLLATE =", "LC_CTYPE =", + "PROVIDER =", "DETERMINISTIC ="); + else if (TailMatches("PROVIDER", "=")) + COMPLETE_WITH("libc", "icu"); + else if (TailMatches("DETERMINISTIC", "=")) + COMPLETE_WITH("true", "false"); + } + /* CREATE DATABASE */ else if (Matches("CREATE", "DATABASE", MatchAny)) COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", "IS_TEMPLATE", "ALLOW_CONNECTIONS", "CONNECTION LIMIT", - "LC_COLLATE", "LC_CTYPE"); + "LC_COLLATE", "LC_CTYPE", "LOCALE"); else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE")) COMPLETE_WITH_QUERY(Query_for_list_of_template_databases); @@ -2576,7 +2658,7 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* Complete "CREATE PUBLICATION [...] WITH" */ else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "(")) - COMPLETE_WITH("publish"); + COMPLETE_WITH("publish", "publish_via_partition_root"); /* CREATE RULE */ /* Complete "CREATE [ OR REPLACE ] RULE " with "AS ON" */ @@ -2696,35 +2778,61 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH("WITH ("); /* Complete "CREATE SUBSCRIPTION ... WITH ( " */ else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("WITH", "(")) - COMPLETE_WITH("copy_data", "connect", "create_slot", "enabled", - "slot_name", "synchronous_commit"); + COMPLETE_WITH("binary", "connect", "copy_data", "create_slot", + "enabled", "slot_name", "streaming", + "synchronous_commit"); /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */ - /* complete CREATE TRIGGER with BEFORE,AFTER,INSTEAD OF */ - else if (TailMatches("CREATE", "TRIGGER", MatchAny)) + + /* + * Complete CREATE [ OR REPLACE ] TRIGGER with BEFORE|AFTER|INSTEAD + * OF. + */ + else if (TailMatches("CREATE", "TRIGGER", MatchAny) || + TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny)) COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF"); - /* complete CREATE TRIGGER BEFORE,AFTER with an event */ - else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER")) + + /* + * Complete CREATE [ OR REPLACE ] TRIGGER BEFORE,AFTER with an + * event. + */ + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER") || + TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER")) COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE"); - /* complete CREATE TRIGGER INSTEAD OF with an event */ - else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF")) + /* Complete CREATE [ OR REPLACE ] TRIGGER INSTEAD OF with an event */ + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF") || + TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF")) COMPLETE_WITH("INSERT", "DELETE", "UPDATE"); - /* complete CREATE TRIGGER BEFORE,AFTER sth with OR,ON */ + + /* + * Complete CREATE [ OR REPLACE ] TRIGGER BEFORE,AFTER sth with + * OR|ON. + */ else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) || - TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny)) + TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) || + TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny) || + TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny)) COMPLETE_WITH("ON", "OR"); /* - * complete CREATE TRIGGER BEFORE,AFTER event ON with a list of - * tables. EXECUTE FUNCTION is the recommended grammar instead of EXECUTE - * PROCEDURE in version 11 and upwards. + * Complete CREATE [ OR REPLACE ] TRIGGER BEFORE,AFTER event ON + * with a list of tables. EXECUTE FUNCTION is the recommended grammar + * instead of EXECUTE PROCEDURE in version 11 and upwards. */ - else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON")) + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON") || + TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */ - else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON")) + + /* + * Complete CREATE [ OR REPLACE ] TRIGGER ... INSTEAD OF event ON with a + * list of views. + */ + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON") || + TailMatches("CREATE", "OR", "REPLACE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("ON", MatchAny)) + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && + TailMatches("ON", MatchAny)) { if (pset.sversion >= 110000) COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY", @@ -2733,7 +2841,8 @@ psql_completion(const char *text, int start, int end) COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY", "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); } - else if (HeadMatches("CREATE", "TRIGGER") && + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && (TailMatches("DEFERRABLE") || TailMatches("INITIALLY", "IMMEDIATE|DEFERRED"))) { if (pset.sversion >= 110000) @@ -2741,11 +2850,16 @@ psql_completion(const char *text, int start, int end) else COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); } - else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("REFERENCING")) + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && + TailMatches("REFERENCING")) COMPLETE_WITH("OLD TABLE", "NEW TABLE"); - else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("OLD|NEW", "TABLE")) + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && + TailMatches("OLD|NEW", "TABLE")) COMPLETE_WITH("AS"); - else if (HeadMatches("CREATE", "TRIGGER") && + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && (TailMatches("REFERENCING", "OLD", "TABLE", "AS", MatchAny) || TailMatches("REFERENCING", "OLD", "TABLE", MatchAny))) { @@ -2754,7 +2868,8 @@ psql_completion(const char *text, int start, int end) else COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); } - else if (HeadMatches("CREATE", "TRIGGER") && + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && (TailMatches("REFERENCING", "NEW", "TABLE", "AS", MatchAny) || TailMatches("REFERENCING", "NEW", "TABLE", MatchAny))) { @@ -2763,7 +2878,8 @@ psql_completion(const char *text, int start, int end) else COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); } - else if (HeadMatches("CREATE", "TRIGGER") && + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && (TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) || @@ -2774,11 +2890,16 @@ psql_completion(const char *text, int start, int end) else COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE"); } - else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR")) + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && + TailMatches("FOR")) COMPLETE_WITH("EACH", "ROW", "STATEMENT"); - else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR", "EACH")) + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && + TailMatches("FOR", "EACH")) COMPLETE_WITH("ROW", "STATEMENT"); - else if (HeadMatches("CREATE", "TRIGGER") && + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && (TailMatches("FOR", "EACH", "ROW|STATEMENT") || TailMatches("FOR", "ROW|STATEMENT"))) { @@ -2787,22 +2908,31 @@ psql_completion(const char *text, int start, int end) else COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE"); } - else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("WHEN", "(*)")) + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && + TailMatches("WHEN", "(*)")) { if (pset.sversion >= 110000) COMPLETE_WITH("EXECUTE FUNCTION"); else COMPLETE_WITH("EXECUTE PROCEDURE"); } - /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE|FUNCTION */ - else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("EXECUTE")) + + /* + * Complete CREATE [ OR REPLACE ] TRIGGER ... EXECUTE with + * PROCEDURE|FUNCTION. + */ + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && + TailMatches("EXECUTE")) { if (pset.sversion >= 110000) COMPLETE_WITH("FUNCTION"); else COMPLETE_WITH("PROCEDURE"); } - else if (HeadMatches("CREATE", "TRIGGER") && + else if ((HeadMatches("CREATE", "TRIGGER") || + HeadMatches("CREATE", "OR", "REPLACE", "TRIGGER")) && TailMatches("EXECUTE", "FUNCTION|PROCEDURE")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); @@ -2872,7 +3002,7 @@ psql_completion(const char *text, int start, int end) { if (TailMatches("(|*,")) COMPLETE_WITH("INPUT", "OUTPUT", "RECEIVE", "SEND", - "TYPMOD_IN", "TYPMOD_OUT", "ANALYZE", + "TYPMOD_IN", "TYPMOD_OUT", "ANALYZE", "SUBSCRIPT", "INTERNALLENGTH", "PASSEDBYVALUE", "ALIGNMENT", "STORAGE", "LIKE", "CATEGORY", "PREFERRED", "DEFAULT", "ELEMENT", "DELIMITER", @@ -2886,7 +3016,8 @@ psql_completion(const char *text, int start, int end) { if (TailMatches("(|*,")) COMPLETE_WITH("SUBTYPE", "SUBTYPE_OPCLASS", "COLLATION", - "CANONICAL", "SUBTYPE_DIFF"); + "CANONICAL", "SUBTYPE_DIFF", + "MULTIRANGE_TYPE_NAME"); else if (TailMatches("(*|*,", MatchAnyExcept("*="))) COMPLETE_WITH("="); else if (TailMatches("=", MatchAnyExcept("*)"))) @@ -2949,17 +3080,51 @@ psql_completion(const char *text, int start, int end) /* DEALLOCATE */ else if (Matches("DEALLOCATE")) - COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements); + COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements + " UNION SELECT 'ALL'"); /* DECLARE */ + + /* + * Complete DECLARE with one of BINARY, INSENSITIVE, SCROLL, NO + * SCROLL, and CURSOR. + */ else if (Matches("DECLARE", MatchAny)) - COMPLETE_WITH("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", + COMPLETE_WITH("BINARY", "ASENSITIVE", "INSENSITIVE", "SCROLL", "NO SCROLL", "CURSOR"); + + /* + * Complete DECLARE ...